Giter Site home page Giter Site logo

dirkwhoffmann / vamiga Goto Github PK

View Code? Open in Web Editor NEW
284.0 22.0 23.0 231.38 MB

vAmiga is a user-friendly Amiga 500, 1000, 2000 emulator for macOS

Home Page: https://dirkwhoffmann.github.io/vAmiga

License: Other

Swift 22.01% C++ 68.23% C 4.26% Objective-C 3.00% Objective-C++ 1.60% Metal 0.64% Rich Text Format 0.03% CMake 0.25%
amiga amiga-emulator retrocomputing emulator

vamiga's Introduction

vamiga's People

Contributors

dirkwhoffmann avatar gshipley avatar maddthesane avatar makigumo avatar prb28 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

vamiga's Issues

DMA slot allocation

Based on what we've discussed in #1, I think a design decision has emerged. Instead of doing all the DMA stuff at an HSYNC event with intermediate updates (as it seems to be done in UAE / SAE), the DMA controller (Agnus) will be run whenever the CPU has processed an instruction. Hence, we have instruction accuracy. We cannot have real cycle accuracy (like, e.g., all decent C64 emulators have), because the CPU core computes a single instruction in one chunk (it would be too slow anyway).

So my first code draft looks as follows:

void
DMAController::executeUntil(Cycle targetClock)
{
    // Determine number of master clock cycles to execute
    Cycle missingCycles = targetClock - clock;

    // Convert to DMA cycles
    DMACycle missingDMACycles = AS_DMA_CYCLES(missingCycles);

    // Execute missing cycles
    for (DMACycle i = 0; i < missingDMACycles; i++) {
        
        switch (vhpos) {
            case 0x07:
            case 0x09:
            case 0x0B:
                // Do disk DMA
                break;
                
            case 0x0D:
            case 0x0F:
            case 0x11:
            case 0x13:
                // Do Audio DMA
                break;
                
            // AND SO ON ...
                
            default:
                break;
                
        }
        
        // Check if the rasterline end has been reached
        if (vhpos < 227) vhpos++; else hsyncAction();
    }
    
    // Note the completed cycles
    clock += DMA_CYCLES(missingDMACycles);
}

The core is a big switch statement wich basically implements a state machine with the vhsync counter as the state. I expect a switch statement to be superior to a manually managed function table, because modern compilers translate big switch constructs to jump tables anyway (at least if compiled with optimizations switched on).

The hsync and vsync look as follows:

void
DMAController::hsyncAction()
{
    vhpos = 0;
    
    // CIA B counts HSYNCs
    amiga->ciaB.incrementTOD();
    
    // Check if the frame end has been reached
    if (vpos < 312) vpos++; else vsyncAction();
}

void
DMAController::vsyncAction()
{
    vpos = 0;
    
    // CIA A counts VSYNCs
    amiga->ciaA.incrementTOD();
}

Bitplane DMA bug

Symptom:

Screenshot 2019-05-20 at 12 15 13

Cyan area: Bitplane DMA is enabled
Black line: Line 255

Copper list (for reference):

Screenshot 2019-05-20 at 12 14 43

Debug output (for reference):

[14934] (252,  2)  FC0F58: PCBD 602C 1040: Denise: pokeBPLCON0(A302)
[14934] (256,  2)  FC0F58: PCBD 602C 1040: Denise: pokeBPLCON0(302)
[14935] (251, 86)  FC0F58: PCBD 602C 1040: Denise: pokeBPLCON0(302)
[14935] (252,  2)  FC0F58: PCBD 602C 1040: Denise: pokeBPLCON0(A302)
[14935] (256,  2)  FC0F58: PCBD 602C 1040: Denise: pokeBPLCON0(302)
[14936] (251, 86)  FC0F58: PCBD 602C 1040: Denise: pokeBPLCON0(302)
[14936] (252,  2)  FC0F58: PCBD 602C 1040: Denise: pokeBPLCON0(A302)
[14936] (256,  2)  FC0F58: PCBD 602C 1040: Denise: pokeBPLCON0(302)
[14937] (251, 86)  FC0F58: PCBD 602C 1040: Denise: pokeBPLCON0(302)
[14937] (252,  2)  FC0F58: PCBD 602C 1040: Denise: pokeBPLCON0(A302)
[14937] (256,  2)  FC0F58: PCBD 602C 1040: Denise: pokeBPLCON0(302)
[14938] (251, 86)  FC0F58: PCBD 602C 1040: Denise: pokeBPLCON0(302)

Alpine9000 test #10 fails

Test 10 is a great test for measuring the Blitter speed. However, it needs to be compiled manually 😟:

The `NUM_COLORS` variable in the [Makefile](Makefile) sets the number of colors. 
This automatically creates the correct bitplane and palette data as well as  
reconfiguring the example code. So now we can see what impact the number of 
bitplanes has on blit speed:

Border pixels sometimes wrong in HAM mode

"HAM Pics 1 (1991 David Hill)" shows wrong colours in the left border of most HAM images.

Screenshot 2019-05-18 at 15 15 18

Variable 'hamRGB' is correctly initialised with the background color at the beginning of each rasterline, so the cause my be something different (?!).

DiagROM results

Screenshot 2019-06-10 at 14 09 28

Quick analysis:

BFE001 is PRA of CIAA ( /FIR1 /FIR0 /RDY /TK0 /WPRO /CHNG /LED OVL )

DFF018 is SERDATR

Faery Tale Music

Goodmorning everyone,
I tried the game Faery Tale, the one posted by Alessandro in the "Logbook for version 0.2" discussion with the new version 0.23 of the vAmiga.
Faery Tale was my first Amiga500 game, it seems to me that the soundtrack during the game is very different from the one played on a real Amiga, possibly I remember badly or the sound is slowed down and incomplete.

https://github.com/dirkwhoffmann/vAmiga/files/3238784/Faery.Tale.Adventure.The.1986.MicroIllusions.cr.adf.zip

Faery Tale Adventure graphics error

Reported by Alessandro:

Before this screen:
Schermata 2019-06-07 alle 22 38 13

There is this graph error that cannot be seen in the original:
Schermata 2019-06-07 alle 22 38 03

None picture are to be shown, that should be a clean screen.

Bad pixels in bottom line

Ham pics (Dave Hill):

Screenshot 2019-05-20 at 14 50 14

Bad pixels occur in last line.

Conjecture: A change in DMA state or display state does not get into effect immediately. It is postponed until the next line is reached (?!)

Test programs

I've found a couple of example programs that could help to debug the emulator:

https://github.com/alpine9000/amiga_examples

However, I did not manage to compile the examples down to an ADF. Maybe it has to be compiled under Windows (don't know).

Could somebody try to compile this? The result will be one or more ADFs.

Is it worth to implement an enhanced HAM mode?

As you know, HAM mode always synthesizes two pixels, by either

a) reading directly from a color register or
b) by replacing a color component from the previous pixel.

Therefore it is easy to implement a slightly enhanced HAM mode which interpolates the first of the two pixels in case b).

In this picture, the difference gets visible to some extend:

interpolatedHAM

However, for most pictures I tested, the result is hardly visible with the human eye, so it might not worth to offer it as an option. It's easy to implement though (just a few lines of code) ...

Add option to silence disk change drive clicks

Here's the thing: For each drive with no disk inserted, track disk device polls for an inserted disk periodically by moving the drive head up and down. That's OK if only df0 is connected, because there will be a disk inserted most of the time. However, if external drives are present, there is most likely some drive without a disk and the clicking sounds becomes annoying (at first I though the emulator has a bug until I realised that I had df1 connected as well).

My proposed solution is to add an option

[X] Silence disk polling clicks

here:

Screenshot 2019-04-12 at 19 21 59

Maybe with a better name though πŸ€”

Differences C64 CIAs and Amiga CIAs

I've encountered an interesting "feature" in the Amiga CIA implementation of SAE / UAE:

When writing the hi byte of counter B, the following happens:

case 7:
		CIA_update();
		ciaalb = (ciaalb & 0xff) | (val << 8);
		if ((ciaacrb & 1) == 0)
			ciaatb = ciaalb;
		if (ciaacrb & 8) {
			ciaatb = ciaalb;
			ciaacrb |= 1;
			ciaastartb = CIASTARTCYCLESHI;
		} 

The "feature" is the last if. If timer B is configured to run in one shot mode (bit at mask position 8 in crb is 1), the counter is automatically started.

I'm pretty sure that the original CIAs (MOS 6526 as used in the C64) are not doing that. Does anybody know if this a feature of the newer MOS 8520 used in the Amiga?

Sword of Sodan graphics errors

vAmiga hangs as soon as this disc is inserted, but the disk works with other emulators.
I tried with or without sloram etc. but the incompatibility starts as soon as this disc is inserted.
It looks like nothing is loaded, either it's a format problem or something in the bootblock.
Insert in DF0: do not load from WB.

Report:
report.txt

Adf:

Simple text_test.adf.zip

"Marble Madness" madness

Experiments with SAE:

  1. Slow memory disabled => Runs just fine
  2. Slow memory enabled => doesn't start
  3. Drive head position reset to 0 when a read begins => doesn't start

Logbook for version 0.1

I am going to use this thread as a logbook in the near future to document the progress towards version 0.1. V0.1 should have about the same functionality as UAE 0.1. We'll then have a (completely useless) emulator that can do nothing but show the Workbench initial screen. To speak with a picture:

goal0 1

This is the current situation:

We have

  • a CPU (Musashi core),
  • memory,
  • two (yet unconnected) CIAs.

So let’s see how far we can get with this. These are the first lines of Kickstart 1.2 which I want to step through:

FC00D2  lea       040000,SP         Set stack pointer to top of first 128K.
FC00D8  move.l    #$020000,D0
FC00DE  subq.l    #1,D0             Delay loop.
FC00E0  bgt.s     FC00DE

        ; If the ROM is also visible at F00000, or if there is another
        ; ROM there, jump there.

FC00E2  lea       FC0000(PC),A0     Load base address of ROM we're in.
FC00E6  lea       F00000,A1         Load (absolute address) F00000.
FC00EC  cmp.l     A1,A0             Are we at F00000?
FC00EE  beq.s     FC00FE            If so, don't execute the following.
FC00F0  lea       FC00FE(PC),A5     This is relative, i.e. always points
                                    12 bytes down from where we are.
FC00F4  cmp.w     #$1111,(A1)       If "1111" not found at F00000, then
FC00F8  bne.s     FC00FE            continue running below, else start
FC00FA  jmp       2(A1)             running at F00002.

        ; Set up port A on the first CIA (8520-A).

FC00FE  move.b    #3,BFE201         Set low two bits for output.
FC0106  move.b    #2,BFE001         Set boot ROM off, power light dim.

Before we can get started, we need to install the Kickstart Rom. This is done in the hardware preferences. By default, the Aros replacement Rom is installed.

screenshot 2019-02-12 at 18 41 29

It can be replaced by an original Rom via drag & drop, so why stick to the clone if we can have the real stuff 😎:

screenshot 2019-02-12 at 18 41 45

The Kickstart Rom is usually located in the upper memory area. On startup, the Amiga mirrors it in the lower memory banks to enable the CPU to find the correct start vector. The memory inspector shows the details:

screenshot 2019-02-12 at 18 44 25

When powering on the Amiga, the CPU loads the start vector from the mirrored Kickstart Rom and jumps to address FC00D2. For testing purposes I let the emulator stop at FC00DE at a predefined breakpoint which can be watched in the CPU panel:

screenshot 2019-02-12 at 18 45 35

Let’s set another breakpoint at FC00FE by double clicking the corresponding line in the program window:

screenshot 2019-02-12 at 18 49 47

By pressing the Run button the CPU starts and stops at FC00FE.

screenshot 2019-02-12 at 19 15 12

Pretty nice so far πŸ₯³, but at this point the Kickstart Rom writes into the CIA registers πŸ™. Two CIAs are already present in the current implementation, but they are not yet connected to memory. Therefore I have to stop here. I'll continue this thread once the CIAs are connected. Stay tuned ...

Issue with releasing and retaining the mouse

If I press alt+cmd to exit vAmiga window but in the vAmiga an icon is selected (see in the photo the Shell icon) when I re-enter the emulator the pointer works but the icon remains selected and I cannot open anything else but the shell (which remains selected).
Schermata 2019-05-11 alle 09 07 38

Logbook for version 0.2

Now that vAmiga can display the startup screen, it's time to set up a new milestone. The next objective will be to load the workbench. However, based on my experience with V0.1, I am going to adjust my software development approach a little bit.

Originally, I started the project by reading the HRM and inspecting the existing UAE / SAE code. Now, here is the thing:

comprehensibility

For all emulators I have seen so far, there is a strict reciprocal relationship between comprehensibility and compatibility. For this reason, I have abandoned the idea of looking up most details in UAE / SAE at this early development stage. In general, you can imagine UAE as a big bunch of millions of if statements (that are not always so cleverly named). Since my head is small, this big pile just doesn't fit in.

Therefore, I will take a different approach for V0.2. First, I am going to make my emulator functionally compatible to Omega and try to improve compatibility afterwards (by peeking into the source code of WinFellow and SAE). I already did this with the Blitter and it saved me a lot of development time (with the drawback that the Blitter is far from being timing-accurate yet).

In preparation for V0.2, I already did some groundwork. E.g., the event handler got a disk controller slot where periodic events are scheduled for rotating the disk. These events are not really utilised yet (because Omega doesn’t emulate it that way). Later, they will be used to fill a FIFO buffer in order to decouple the DMA stuff (which happens inside Paula) from the drive head logic (which is part of the drive of course). The FIFO buffer is already there, but hasn't yet been activated.

White stripe while booting

Ham pics (Dave Hill):

A white stripe shows up while booting:

Screenshot 2019-05-27 at 11 47 59

Todo: Check background color register changes. Because the stripe is also displayed in areas where bitplane DMA is off, it must (theoretically) be caused by a background color change.

Might also be due to horizontal scrolling, so it might be best to implement horizontal scrolling first.

Barbarian hacker intro bug

Findings: When the disk is dragged in after the disk & hand logo has shown up, the intro is scrambled:

Screenshot 2019-06-09 at 14 18 54

DMA debugger view:

Screenshot 2019-06-09 at 16 46 22

When the disk is inserted right from the start, it looks like this (red stripes are debug markers) :

Screenshot 2019-06-09 at 17 38 32

Don't know what's going on here. Obviously, it must have something to do with the display window. Up to now, I thought the display window can only be modified by writing into DIWSTRT and DIWSTOP... πŸ€”

after speaking bravely he crashes

image

debug output

Current configuration:

   AmigaModel: Amiga 500
realTimeClock: no
          df0: yes Drive 3.5" DD
          df1: no Drive 3.5" DD
          df2: no Drive 3.5" DD
          df3: no Drive 3.5" DD

         warp: 0 (82763776) (77992)
Assertion failed: (IS_EVEN(addr)), function peek16, 
file .../vAmiga/Amiga/Computer/Memory.cpp, line 395.

points to here ... addr is not even ... ends with 1.

uint16_t
Memory::peek16(uint32_t addr)
{
    if (!IS_EVEN(addr)) {
        debug("PC: %X peek16(%X) memSrc = %d\n", _cpu->getPC(), addr, memSrc[(addr & 0xFFFFFF) >> 16]);
        _amiga->dump();
    }
    
    assert(IS_EVEN(addr));

image

I wanted to look at the root cause but I have no good idea. I traveled the stacktrace but this strategy does not really help here. Maybe it is some DMA scheduling problems ? Because when it crashes the mouse pointer sprite gets scrambled too?

Amiga screen geometry

I'm back in the conceptual phase. This is how I understand the Amiga screen geometry at the moment:

screen

The numbers in square brackets (intervals) refer to the DMA cycle number (horizontally) and the vpos value, respectively.

Before I can continue to implement, I need to clarify the following:

  • Is it true that the HSYNC does not start at DMA cycle 0? If my image is correct, then graphics data that is produced during the first few DMA cycles (e.g., by the sprite sequencer) still belongs to the previous line.

The graphics also contains a design proposal for the displaying events. If a line belongs to the display window (as specified by register DIWSTRT and DIWSTOP), I plan to schedule the following events:

  • HBLANK: Fills the rest of the previous line with the background color
  • DIWSTRT: Fills the beginning of the line with the background color
  • DRAW: Draws a chunk of 16 pixels in hires mode or 32 pixels in lores mode (will be scheduled every fourth DMA cycle in hires mode and every eights DMA cycle in lores mode).
  • DIWSTOP: basically the same as DRAW
  • HSYNC: Triggers the CIA counter, checks for VSYNC etc.

Please let my know if this makes sense to you or if it doesn't? πŸ€”

Alpine9000 test case summary

For reference:

000.trackdisk: Pass
001.simple_image: Pass
002.sprite_display: Pass
003.music: Pass
004.copper_bars: Pass
005.copper_vert: Pass
006.simple_blit: Pass
007.masked_blit: Pass
008.shift_blit: Pass
009.amin_blit: Pass
010.blit_speed: FAIL (REQUIRES CYCLE-ACCURATE BLITTER) πŸ₯΄
011.ehb_mode: Pass
012.ham_mode: Pass
013.dithered_ham: Pass
014.lace_ham: Pass
015.sliced_ham: Pass
016.copper_fun: Pass
017.dual_playfield: Pass
018.vert_scroll: Pass
019.hori_scroll: Pass
020.shrinkler: Pass
021.calling_c: Pass
022.photons_boot_loader: Pass
023.slideshow: Pass
024.simple_text: Pass
025.scroll_text: Pass
026.tile_hscroll: Pass
027.parallax: Pass

tools and strategies for compatibility fine tuning

Just wanted to bring this new and very cool project to your attention. In my opinion it is an incredible cool tool. And a good starting point of comparing vAmigas behaviour in detail with the latest generations of high compatible UAE Emulators .

In short, you can develop amiga code in VisualCode on your mac with full code completion, explanation for custom registers, assembler syntax hilighting and so on. Then you can switch to debug and run or debug your code with the integrated fsuae, inspect registers memory and so on. You can also let it generate an ADF file. This works really fast and fluenty. I just had several debug sessions with the copper bar program from its example workspace. You start programming run stop edit change something start again see results and so on... make several trial and error cycles in only 15 seconds or so.

The idea: it can be used to write short mini test programs for vAmiga, to teach vAmiga compatibility of current versions of UAE.
Strategy: We let it build ADFs with certain short test code mini programs, see the results in fsuae, inspect registers in VisualCode with integrated FSUAE debugger and then we can feed that same ADF into vAmiga and compare that same code in vAmigas debugger. Side by side comparison and debugging of fsuae and vAmiga.

you find the well documented visual studio extension of Amiga-Assembly here:
https://github.com/prb28/vscode-amiga-assembly

You install the following extension inside visual studios extension finder.
https://marketplace.visualstudio.com/items?itemName=prb28.amiga-assembly

Once installed you can download an example workspace with a small copper mini program example:
https://github.com/prb28/vscode-amiga-wks-example

To debug and run the small copper mini program example, you still have to get the latest precompiled external binaries of FSUAE, ADF Tools for the mac with which Amiga-Assembly works together from the osx.zip file here
https://github.com/prb28/vscode-amiga-assembly/releases

copy them into the bin folder of the example workspace. Now you will be able to build run debug and build short Amiga programs and export ADFs without leaving VisualStudioCode.πŸ˜ƒ

Dirk, if you have questions about setting up and how to run it, just ask me here. The developer is also very sympathic and currently still activly developing it.

Booting AROS fails

When booting with the Aros Rom installed, vAmiga gets stuck in an infinite loop:

Screenshot 2019-05-06 at 14 21 36

Bugs in Paccer

All bugs that have been spotted so far are related to sprites:

  • Upper right sprite shouldn't be visible on startup (outside visible range)
  • Sprite colors are wrong (all ghosts are drawn with the same color, Pacman should be yellow)
  • From time to time, there are graphics glitches (Sprites do not get switched off after they were drawn. They are drawn in vertical stripes until the vblank area is reached).

Screenshot 2019-05-19 at 09 52 06

User interface questions

I am unsure about the following:

  1. Retaining and releasing the mouse pointer

    What is the best way to share the mouse pointer between the Mac and vAmiga? Right now, Cmd-i does the trick, but this causes issues. Firstly, this combination is unusual. Secondly, there is no way to get the mouse back if the Command keys are used in direct mapping mode.

  2. ADF files and 5.25" drives

    How should vAmiga react if the user tries to insert an ADF file into a 5.25" drive? One possibility would be to show an alert box:

    "The capacity of df1 is too low. Only the first 40 cylinders will be converted." [OK, Cancel]

    Or:

    "df1 is a single-density drive. Only the first 40 cylinders will be converted." [OK, Cancel]

Does anybody know whether there is a special ADF format for 5.25" drives or 3.5" HD drives? Up to now, I've only seen standard ADF files representing 3.5" DD disks.

And finally, a really stupid question: Does anybody know how to type ":" in SAE or FsUAE on a German keyboard? I want to type "dir df1:" in a CLI window with df1: set to a 5.25" drive. The problem: In SAE, multiple keys result in "ΓΌ ΓΆ Γ€" and stuff, but I can't get ':' 🀨. In FsUAE I cannot even select 5.25" drives (at least I didn't find where πŸ˜–).

No CIA A interrupt during startup

By comparing Omega's bootstrap output with vAmiga's, I notices that Omega is triggering a CIA A interrupt at some point:

intreq 20
intreq 8008
*** IRQ *** 8

This interrupt does not occur in vAmiga, because vAmiga is yet programmed to crash on the first CIA A interrupt. This is most likely the reason why the hand & disk picture is not drawn.

Serial interface (UART)

I've added UART emulation to vAmiga in order to make DiagROM boot. To test the UART implementation, I need to emulate a device that is connected to the serial port.

Does anyone remember a simple device that got attached to the Amiga's serial port? A modem would be far too complicated.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.