zellyn / a2audit

Apple II audit routines: for testing your Apple II or emulator
MIT License
29 stars 6 forks source link

Memory bank question #10

Closed cbeust closed 4 years ago

cbeust commented 4 years ago

I am receiving the following error for my emulator:

image

However, if I read the switches correctly:

    lda $c080 ; read ram 2, no write
    lda $c081 ; read rom, write rom, ram 2

In other words, after these two switches, read of $D17B should be taking place in rom, so it can't be #$22.

Am I missing something?

cbeust commented 4 years ago

Sorry, I initially misphrased. I corrected the text of the issue now.

zellyn commented 4 years ago

Oh dear. It appears my URLs are broken. Until I get a chance to fix them, you can look here: https://github.com/zellyn/a2audit/blob/master/v0/index.md

It's been long enough that I'm pulling up Sather myself to figure this one out. Until then, I can say that my real Apple IIe passed all these tests, so I'm certain they are correct :-)

zellyn commented 4 years ago

Oh. I get it now. The test is telling you that after running, $D17B in RAM bank 2 was $54, not $22. A single read to $C081 should not be enough to write-enable, so incrementing $D17B (which as you pointed out, contains value $53 because it's currently displaying ROM) should have no effect on the RAM. If you did two LDAs on $C081, you'd write-enable bank 2, so incrementing $53 would yield $54, and write back to bank2.

These things are tricky, which is exactly why I wrote the tests :-) You're going to become all-too-familiar with https://archive.org/details/Understanding_the_Apple_IIe/page/n129/mode/2up :-)

cbeust commented 4 years ago

Ooh I see! It's been hard for me to find specific explanations of the difference between one and two LDA in a row. I read a lot of material but hadn't come up across that book yet, will take a look. And yes, I'm pretty sure all your tests are correct 👍

I have a suggestion, though: it would be useful to have a version that's completely headless (no disk, no text display) and it would just crash whenever a test fails, e.g. with a BRK:

   (test1)
   beq @next
   brk

@next:
   (test2)
   beq @next
   brk

@next:

This way I could incorporate your tests directly into the functional suite for my emulator.

Also, how can I generate a .lst of your code? I haven't been able to rebuild them so far...

Thanks again, this is going to be super useful for me!

zellyn commented 4 years ago

I'm not sure what exactly you mean by a .lst … the code is all here: https://github.com/zellyn/a2audit/blob/master/audit/auxmem.asm

Building should be easy, as long as you have acme installed (https://sourceforge.net/projects/acme-crossass/) I build it using this script: https://github.com/zellyn/a2audit/blob/master/audit/build

(For side projects like this, if I didn't save how to build it in a file, I'd never remember 🙂)

As for BRK-type tests, feel free to send a PR to add a #define to do that if you like. While a2audit is indeed intended as an Apple II-specific follow-on to Klaus Dormann's amazing 6502 tests, I've never really considered them as targeting the same kind of headless running… you'll see as you get further, that the video tests in particular actually show you things, and ask you to eyeball them to see whether they look right :-) But it seems 100% useful to be able to #ifdef out the interactive portions.

zellyn commented 4 years ago

ps. always nice to see anyone building an Apple II emulator :-) Your unfamiliarity with UtAIIe is not going to last long 😂

You should also join #emulators on the Apple2Infinitum slack: http://apple2.gs:3000/ — it's where all the emulator writers hang out :-)

cbeust commented 4 years ago

A .lst is generated at assembly time with all the exact memory addresses, here is Klaus' for example.

It's very convenient to be able to place breakpoints judiciously as I go through your tests. I'm using cc65 right now but I will take a look at acme.

I know there are tons of Apple 2 emulators out there but on top of the challenge, I have very specific goals in mind for mine: make it a developer oriented emulator, with a lot of inside view on the code that's running, cycle exact, running protected disks (woz support is in), buffer views with nibble/syncs, being able to easily load assembled programs from the outside (file watchers), etc...

As for headless, yes, I've seen what a2audit does later in the tests, that part is certainly not headless :) Maybe I'll see if I can extract some of the headless parts into my own functional suites.

Thanks again for your help, you'll probably hear from me again as I make my way through the Apple 2 arcana.

zellyn commented 4 years ago

fwiw, I like the idea of a developer-focused emulator. I have found having my own emulator that can run in text mode in a terminal very useful: for instance, while writing md5sum 6502 code, I had a file watcher that compiled my assembly, loaded it into my emulator, and dumped the output to the screen, then printed the desired results right below, so I could eyeball them.

There is some prior art here that you should know about. A kansasfest attendee a few years ago proposed a common API for emulators, so you could eg. run them in a cloud and control them remotely. (I think it was Dagen Brock. See this slack discussion) MicroM8 has most of the features you're describing, plus also has a very capable web-based debugger that should probably inform any creation of a standard.

I think collaborating to create a standard remote operation/debugging API would be super useful. I could see lots of emulators implementing it.

cbeust commented 4 years ago

Interesting to see you came across that need for a file watcher too :)

It's odd to me even AppleWin, which is excellent, only has this hacky CiderPress integration if you want to do something like that.

This was one of the first features I implemented in my emulator (as soon as I had a monitor prompt that is): instruct it to watch a directory with specific files and loading addresses, and whenever a change is detected (which means I just assembled a new version), it gets automatically loaded in my emulator at the specified address.

Being able to turn on runtime disassembly for given conditions (PC within a certain range, or cycles within a certain range, or certain memory access) is also super useful (see below for an example). I certainly wish I had that when I embarked on some old school Apple 2 game cracking.

Having some reusable stuff would certainly be useful. I'm developing my emulator in Kotlin and I have made my 6502 pretty reusable (it offers a bunch of listeners that you implement if you want to read or write the memory or act on certain register changes, etc...) but it's a bit sad to see the amount of wheel reinventing that takes place (and I'm contributing to it myself :-) ).

C65E : BD 8C C0   LDA  $C08C,X     A=FF X=60 Y=FF S=FE P=B0 PC=$C661 P=$B0 {N--- ----} SP={$FE stack:[$1FF:$30 ]} 0
C661 : 10 FB      BPL  $C65E       A=FF X=60 Y=FF S=FE P=B0 PC=$C663 P=$B0 {N--- ----} SP={$FE stack:[$1FF:$30 ]} 0
C663 : 49 D5      EOR  #$D5        A=2A X=60 Y=FF S=FE P=30 PC=$C665 P=$30 {---- ----} SP={$FE stack:[$1FF:$30 ]} 0
C665 : D0 F7      BNE  $C65E       A=2A X=60 Y=FF S=FE P=30 PC=$C65E P=$30 {---- ----} SP={$FE stack:[$1FF:$30 ]} 0
C65E : BD 8C C0   LDA  $C08C,X     A=FF X=60 Y=FF S=FE P=B0 PC=$C661 P=$B0 {N--- ----} SP={$FE stack:[$1FF:$30 ]} 0
C661 : 10 FB      BPL  $C65E       A=FF X=60 Y=FF S=FE P=B0 PC=$C663 P=$B0 {N--- ----} SP={$FE stack:[$1FF:$30 ]} 0
C663 : 49 D5      EOR  #$D5        A=2A X=60 Y=FF S=FE P=30 PC=$C665 P=$30 {---- ----} SP={$FE stack:[$1FF:$30 ]} 0
C665 : D0 F7      BNE  $C65E       A=2A X=60 Y=FF S=FE P=30 PC=$C65E P=$30 {---- ----} SP={$FE stack:[$1FF:$30 ]} 0
C65E : BD 8C C0   LDA  $C08C,X     A=D5 X=60 Y=FF S=FE P=B0 PC=$C661 P=$B0 {N--- ----} SP={$FE stack:[$1FF:$30 ]} 0
C661 : 10 FB      BPL  $C65E       A=D5 X=60 Y=FF S=FE P=B0 PC=$C663 P=$B0 {N--- ----} SP={$FE stack:[$1FF:$30 ]} 0
C663 : 49 D5      EOR  #$D5        A=00 X=60 Y=FF S=FE P=32 PC=$C665 P=$32 {---- --Z-} SP={$FE stack:[$1FF:$30 ]} 0
C665 : D0 F7      BNE  $C65E       A=00 X=60 Y=FF S=FE P=32 PC=$C667 P=$32 {---- --Z-} SP={$FE stack:[$1FF:$30 ]} 0
xotmatrix commented 4 years ago

ACME can generate a compiler listing using the -r report flag.

acme -r mycode.lst mycode.asm
cbeust commented 4 years ago

Indeed. I switched to ACME, I prefer its local label handling over cc65's.

Closing this issue, I've resolved all my problems with @zellyn's guidance.