From 8dd1fe60371acb4a120ab7e18159d6a67f80f0a6 Mon Sep 17 00:00:00 2001 From: FyloZ Date: Mon, 6 May 2024 20:23:53 -0400 Subject: [PATCH] Removed ROMS --- test_roms/cpu_exec_space/readme.txt | 158 ------ .../cpu_exec_space/source/common/ascii_1.chr | Bin 1536 -> 0 bytes .../cpu_exec_space/source/common/ascii_2.chr | Bin 1536 -> 0 bytes .../cpu_exec_space/source/common/ascii_3.chr | Bin 1536 -> 0 bytes .../cpu_exec_space/source/common/build_rom.s | 96 ---- .../cpu_exec_space/source/common/colors.inc | 59 -- .../cpu_exec_space/source/common/console.s | 282 ---------- test_roms/cpu_exec_space/source/common/crc.s | 118 ---- .../cpu_exec_space/source/common/delay.s | 190 ------- .../cpu_exec_space/source/common/devcart.bin | Bin 256 -> 0 bytes .../cpu_exec_space/source/common/macros.inc | 169 ------ .../cpu_exec_space/source/common/neshw.inc | 37 -- test_roms/cpu_exec_space/source/common/ppu.s | 142 ----- .../cpu_exec_space/source/common/print.s | 380 ------------- .../cpu_exec_space/source/common/shell.inc | 32 -- .../cpu_exec_space/source/common/shell.s | 331 ----------- .../cpu_exec_space/source/common/testing.s | 106 ---- .../cpu_exec_space/source/common/text_out.s | 61 -- test_roms/cpu_exec_space/source/readme.txt | 105 ---- .../source/test_cpu_exec_space_apu.s | 243 -------- .../source/test_cpu_exec_space_ppuio.s | 524 ------------------ .../test_cpu_exec_space_apu.nes | Bin 40976 -> 0 bytes .../test_cpu_exec_space_ppuio.nes | Bin 40976 -> 0 bytes test_roms/nestest.fdb | 4 - test_roms/nestest.nes | Bin 24592 -> 0 bytes test_roms/smb.fdb | 1 - test_roms/smb.nes | Bin 40976 -> 0 bytes 27 files changed, 3038 deletions(-) delete mode 100644 test_roms/cpu_exec_space/readme.txt delete mode 100644 test_roms/cpu_exec_space/source/common/ascii_1.chr delete mode 100644 test_roms/cpu_exec_space/source/common/ascii_2.chr delete mode 100644 test_roms/cpu_exec_space/source/common/ascii_3.chr delete mode 100644 test_roms/cpu_exec_space/source/common/build_rom.s delete mode 100644 test_roms/cpu_exec_space/source/common/colors.inc delete mode 100644 test_roms/cpu_exec_space/source/common/console.s delete mode 100644 test_roms/cpu_exec_space/source/common/crc.s delete mode 100644 test_roms/cpu_exec_space/source/common/delay.s delete mode 100644 test_roms/cpu_exec_space/source/common/devcart.bin delete mode 100644 test_roms/cpu_exec_space/source/common/macros.inc delete mode 100644 test_roms/cpu_exec_space/source/common/neshw.inc delete mode 100644 test_roms/cpu_exec_space/source/common/ppu.s delete mode 100644 test_roms/cpu_exec_space/source/common/print.s delete mode 100644 test_roms/cpu_exec_space/source/common/shell.inc delete mode 100644 test_roms/cpu_exec_space/source/common/shell.s delete mode 100644 test_roms/cpu_exec_space/source/common/testing.s delete mode 100644 test_roms/cpu_exec_space/source/common/text_out.s delete mode 100644 test_roms/cpu_exec_space/source/readme.txt delete mode 100644 test_roms/cpu_exec_space/source/test_cpu_exec_space_apu.s delete mode 100644 test_roms/cpu_exec_space/source/test_cpu_exec_space_ppuio.s delete mode 100644 test_roms/cpu_exec_space/test_cpu_exec_space_apu.nes delete mode 100644 test_roms/cpu_exec_space/test_cpu_exec_space_ppuio.nes delete mode 100644 test_roms/nestest.fdb delete mode 100644 test_roms/nestest.nes delete mode 100644 test_roms/smb.fdb delete mode 100644 test_roms/smb.nes diff --git a/test_roms/cpu_exec_space/readme.txt b/test_roms/cpu_exec_space/readme.txt deleted file mode 100644 index 4eaf8ae..0000000 --- a/test_roms/cpu_exec_space/readme.txt +++ /dev/null @@ -1,158 +0,0 @@ -NES Memory Execution Tests ----------------------------------- -These tests verify that the CPU can execute code from any possible -memory location, even if that is mapped as I/O space. - -In addition, two obscure side effects are tested: - -1. The PPU open bus. Any write to PPU will update the open bus. - Reading from 2002 updates the low 5 bits. Reading from 2007 - updates 8 bits. The open bus is shown in any addresss/bit - that the PPU does not write to. Read from 2000, you get open bus. - Read from 2006, ditto. Read from 2002, you get that in high 3 bits. - Additionally, the open bus decays automatically to zero in about one - second if not refreshed. - This test requires that a value written to $2003 can be read back - from $2001 within a time window of one or two frames. - -2. One-byte opcodes must issue a dummy read to the byte immediately - following that opcode. The CPU always does a fetch of the second - byte, before it has even begun executing the opcode in the first - place. - -Additionally, the following PPU features must be working properly: - -1. PPU memory writes and reads through $2006/$2007 -2. The address high/low toggle reset at $2002 -3. A single write through $2006 must not affect the address used by $2007 -4. NMI should fire sometimes to salvage a broken program, if the JSR/JMP - never reaches its intended destination. (Only required in the - test IF the CPU and/or open bus are not working properly.) - -The test is done FIVE times: Once with JSR $2001, again with JMP $2001, -and then with RTS (with target address of $2001), and then with a JMP -that expects to return with an RTI opcode. Finally, with a regular -JSR, but the return from the code is done through a BRK instruction. - -Tests and results: - - #2: PPU memory access through $2007 does not work properly. (Use other tests to determine the exact problem.) - #3: PPU open bus implementation is missing or incomplete: A write to $2003, followed by a read from $2001 should return the same value as was written. - #4: The RTS at $2001 was never executed. (If NMI has not been implemented in the emulator, the symptom of this failure is that the program crashes and does not output either "Fail" nor "Passed"). - #5: An RTS opcode should still do a dummy fetch of the next opcode. (The same goes for all one-byte opcodes, really.) - #6: I have no idea what happened, but the test did not work as supposed to. In any case, the problem is in the PPU. - #7: A jump to $2001 should never execute code from $8001 / $9001 / $A001 / $B001 / $C001 / $D001 / $E001. - #8: Okay, the test passed when JSR was used, but NOT when the opcode was JMP. I definitely did not think any emulator would trigger this result. - #9: Your PPU is broken in mind-defyingly random ways. - #10: RTS to $2001 never returned. This message never gets displayed. - #11: The test passed when JSR was used, and when JMP was used, but NOT when RTS was used. Caught ya! Paranoia wins. - #12: Your PPU gave up reason at the last moment. - #13: JMP to $2001 never returned. Again, this message never gets displayed. - #14: An RTI opcode should still do a dummy fetch of the next opcode. (The same goes for all one-byte opcodes, really.) - #15: An RTI opcode should not destroy the PPU. Somehow that still appears to be the case here. - #16: IRQ occurred uncalled - #17: JSR to $2001 never returned. (Never displayed) - #18: The BRK instruction should issue an automatic fetch of the byte that follows right after the BRK. (The same goes for all one-byte opcodes, but with BRK it should be a bit more obvious than with others.) - #19: A BRK opcode should not destroy the PPU. Somehow that still appears to be the case here. - - -Expected output: - TEST:test_cpu_exec_space_ppuio - This program verifies that the - CPU can execute code from any - possible location that it can - address, including I/O space. - - In addition, it will be tested - that an RTS instruction does a - dummy read of the byte that - immediately follows the - instructions. - - JSR+RTS TEST OK - JMP+RTS TEST OK - RTS+RTS TEST OK - JMP+RTI TEST OK - JMP+BRK TEST OK - - Passed - -Expected output in the other test: - - TEST: test_cpu_exec_space_apu - This program verifies that the - CPU can execute code from any - possible location that it can - address, including I/O space. - - In this test, it is also - verified that not only all - write-only APU I/O ports - return the open bus, but - also the unallocated I/O - space in $4018..$40FF. - - 40FF 40 - Passed - - - -Flashes, clicks, other glitches -------------------------------- -If a test prints "passed", it passed, even if there were some flashes or -odd sounds. Only a test which prints "done" at the end requires that you -watch/listen while it runs in order to determine whether it passed. Such -tests involve things which the CPU cannot directly test. - - -Alternate output ----------------- -Tests generally print information on screen, but also report the final -result audibly, and output text to memory, in case the PPU doesn't work -or there isn't one, as in an NSF or a NES emulator early in development. - -After the tests are done, the final result is reported as a series of -beeps (see below). For NSF builds, any important diagnostic bytes are -also reported as beeps, before the final result. - - -Output at $6000 ---------------- -All text output is written starting at $6004, with a zero-byte -terminator at the end. As more text is written, the terminator is moved -forward, so an emulator can print the current text at any time. - -The text output may include ANSI color codes, which take the form of -an esc character ($1B), an opening bracket ('['), and a sequence of -numbers and semicolon characters, terminated by a non-digit character ('m'). - -The test status is written to $6000. $80 means the test is running, $81 -means the test needs the reset button pressed, but delayed by at least -100 msec from now. $00-$7F means the test has completed and given that -result code. - -To allow an emulator to know when one of these tests is running and the -data at $6000+ is valid, as opposed to some other NES program, $DE $B0 -$G1 is written to $6001-$6003. - - -Audible output --------------- -A byte is reported as a series of tones. The code is in binary, with a -low tone for 0 and a high tone for 1, and with leading zeroes skipped. -The first tone is always a zero. A final code of 0 means passed, 1 means -failure, and 2 or higher indicates a specific reason. See the source -code of the test for more information about the meaning of a test code. -They are found after the set_test macro. For example, the cause of test -code 3 would be found in a line containing set_test 3. Examples: - - Tones Binary Decimal Meaning - - - - - - - - - - - - - - - - - - - - - - low 0 0 passed - low high 01 1 failed - low high low 010 2 error 2 - - --- -Shay Green -Joel Yliluoma diff --git a/test_roms/cpu_exec_space/source/common/ascii_1.chr b/test_roms/cpu_exec_space/source/common/ascii_1.chr deleted file mode 100644 index 3366c2599e4cdcd7105fbd689ab42171e8bb911c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1536 zcmY*Zy^0$#5EfT#CCrs77C(ckun=LcN_7t*LQs(`hpV7MxV*=>XHgNR5-yE7LP!y= zGA5)5E*2%DHJ+IjHt5qgnxAiGrPOknwv?g6aU5wsZ^k;}kIu}-yDqW)$DoZ3ABgYY z^~0C&p0L)M_HEN?jHf#~^A@r7gjI0=Twth-*;c*Xd zp9aEa!1#t;Bv`rlvl744#&wVg_iijz)HLO(lf3hJ0%2bP<6BGjWes z4k0uN$iA-nVJqfuJ?pb3{sFtMyF0=TKQOIXzk6&bk+k9dWY4p3rK3)w{+utRi2f=S zOD>T-X|yhd^=$lfvx8 zUa8{=6BO7ri3P^`E@A+#`H4sBc#`vh_2sB}-jz)lz8C&5+V^pZqtqC)6Yr-|CE6(S nYjUzaN=^8MPvmcfucI+5!t*$YdD-G?D&$iB&x@#quF>W{7IqB7 diff --git a/test_roms/cpu_exec_space/source/common/ascii_2.chr b/test_roms/cpu_exec_space/source/common/ascii_2.chr deleted file mode 100644 index 8a8f74f2b29b35c2c1a9137d42fd32788fcd540c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1536 zcmZuxy^0$#5FW1BN|-BEEPe)6VIjg?mFgZsgrFi>4p%{iaCwiBXHgMU375tkA*2Xb z852?j7mJe78qdr^gbn)ijppZ@Spoci>9#-3?j*jjypm7g`hsS+> z{V)*L1IE|vBIcD1KPvG%rEQlZ;ogp=ikhZ0b&|I(O&(@nE$tvD|R;sSdCfefw^<~cvoS?WDPNQy#bDI{nN)Mw;_XJ%(>=F7?W>5!q%sh zyd``oIp=aATvM7-V!f_75x;S1pFPLJ+Zc}H*(Sec|LYFr6#C_I{B#85NV*b{%K5OD1u=}dJBW&>lQ;PMw$A%I~8}3hXJPTJks3_`B=~9a5 zFF+`%1oEWNx)j#4@l#^HHzr7Z0MI`2fM5L=@`t0j&=a4cR`K>`kkUK=H#i$F{h#XL za3CJwc)|n)woPJzvA&BKfNOr@kvg8_d|-VkD4usP5ySVwA4dB&E^&|=V|L>G1Sr7- nnO~EW^#Pdh3!li}3SUR9SA^$r5c9Id*Hp*_?)Mi_3tfYMuvZMj diff --git a/test_roms/cpu_exec_space/source/common/ascii_3.chr b/test_roms/cpu_exec_space/source/common/ascii_3.chr deleted file mode 100644 index 2c5b26bdb43aac9cd7899428c45f832832c056c7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1536 zcmZA1F>Bl~6bJA}22bM1sKMN4&{PZ+N2X5w5TXtj#5g8 zk|~7Jq1<59{-30Gxm3CEvn*NCd$L9JvS==ZzveVerGrRQp70}4@0{&C`ZwQ=N}KTw ziT$g7_&B~MQ7Ki%6FY^8R7avSs2fKjjrOk{@rbDPf&~&5Smn_S9(Z;s*F++btIg~c zCNl2k?C|zJKD-}D)B^{;km%#a&Ob7Vi_*4>p2XfxDI+Fv4Qt2kqIF@7sEavbeq%_S zzxvkj# zQ;a!A60vyxk!Z&d!f4UIdP*_IbRsc_u!fN7rJ>aW?OeEzGlyPoUKaU3~x67!}X_IUrqZOO})#2f6s z>aIw%_^^~h{+id=Nd6u~z9z~Q7@R5BBGIfo;uk|WrG)(zaX*DLb9+&tcS@c_zQ2ar z&i2O4oF9=0{XJgrW*s-R@e{sfe9h>8wjM?Mb|mdXC>xLdRql*Z9%6|e^Wku~@c4)Y zqApraE$SlTJ7MGT23O1aa7c;AM}9B(`RW{Ibwa&qJf`ij-X>wTZxh-toOxZS7qL1% zKS{*hnb&u=qL>E843YoQ_&=NGz`d-WPF?(^Ts{iSGAj#DXKR$=8?VAHdBS Ag#Z8m diff --git a/test_roms/cpu_exec_space/source/common/build_rom.s b/test_roms/cpu_exec_space/source/common/build_rom.s deleted file mode 100644 index e852ef5..0000000 --- a/test_roms/cpu_exec_space/source/common/build_rom.s +++ /dev/null @@ -1,96 +0,0 @@ -; Builds program as iNES ROM - -; Default is 16K PRG and 8K CHR ROM, NROM (0) - -.if 0 ; Options to set before .include "shell.inc": -CHR_RAM=1 ; Use CHR-RAM instead of CHR-ROM -CART_WRAM=1 ; Use mapper that supports 8K WRAM in cart -CUSTOM_MAPPER=n ; Specify mapper number -.endif - -.ifndef CUSTOM_MAPPER - .ifdef CART_WRAM - CUSTOM_MAPPER = 2 ; UNROM - .else - CUSTOM_MAPPER = 0 ; NROM - .endif -.endif - -;;;; iNES header -.ifndef CUSTOM_HEADER - .segment "HEADER" - .byte $4E,$45,$53,26 ; "NES" EOF - - .ifdef CHR_RAM - .byte 2,0 ; 32K PRG, CHR RAM - .else - .byte 2,1 ; 32K PRG, 8K CHR - .endif - - .byte CUSTOM_MAPPER*$10+$01 ; vertical mirroring -.endif - -.ifndef CUSTOM_VECTORS - .segment "VECTORS" - .word -1&$FFFF,-1&$FFFF,-1&$FFFF, nmi, reset, irq -.endif - -;;;; CHR-RAM/ROM -.ifdef CHR_RAM - .define CHARS "CHARS_PRG" - .segment CHARS - ascii_chr: - - .segment "CHARS_PRG_ASCII" - .align $200 - .incbin "ascii.chr" - ascii_chr_end: -.else - .define CHARS "CHARS" - .segment "CHARS_ASCII" - ;.align $200 - .incbin "ascii_3.chr" - ;.align $200 - .incbin "ascii_2.chr" - ;.align $200 - .incbin "ascii_1.chr" - .res $E00 -.endif - -;.segment CHARS - ;.res $10,0 - -;;;; Shell -.ifndef NEED_CONSOLE - NEED_CONSOLE=1 -.endif - -; Move code to $C000 -;.segment "DMC" -; .res $4000 - -.include "shell.s" - -std_reset: - lda #0 - sta PPUCTRL - sta PPUMASK - jmp run_shell - -init_runtime: - .ifdef CHR_RAM - load_ascii_chr - .endif - rts - -post_exit: - jsr set_final_result - jmp forever - -; This helps devcart recover after running test. -; It is never executed by test ROM. -.segment "LOADER" - .incbin "devcart.bin" - -.code -.align 256 diff --git a/test_roms/cpu_exec_space/source/common/colors.inc b/test_roms/cpu_exec_space/source/common/colors.inc deleted file mode 100644 index 3e019c1..0000000 --- a/test_roms/cpu_exec_space/source/common/colors.inc +++ /dev/null @@ -1,59 +0,0 @@ -.define color2 $A0 -.define color1 $40 -.define color3 $E0 - -zp_res color_ptr,2 - -.pushseg -.segment "RODATA" -Color1Esc: .byte 27, "[0;33m", 0 -Color2Esc: .byte 27, "[1;34m", 0 -Color3Esc: .byte 27, "[0;37m", 0 -.segment "LIB" - -TextColor1: - pha - setw color_ptr, Color1Esc - lda #color1 - bne ColorPrint_Sub -TextColor2: - pha - setw color_ptr, Color2Esc - lda #color2 - bne ColorPrint_Sub -TextColor3: - pha - setw color_ptr, Color3Esc - lda #color3 -ColorPrint_Sub: - sta text_color - tya - pha - ldy #0 -@loop: - lda (color_ptr),y - beq :+ - jsr write_text_out - incw color_ptr - bne @loop -: pla - tay - pla - rts - - - -.popseg - - - -.macro text_color1 - jsr TextColor1 -.endmacro -.macro text_color2 - jsr TextColor2 -.endmacro -.macro text_white - jsr TextColor3 -.endmacro - diff --git a/test_roms/cpu_exec_space/source/common/console.s b/test_roms/cpu_exec_space/source/common/console.s deleted file mode 100644 index 9a257d5..0000000 --- a/test_roms/cpu_exec_space/source/common/console.s +++ /dev/null @@ -1,282 +0,0 @@ -; Scrolling text console with line wrapping, 30x29 characters. -; Buffers lines for speed. Will work even if PPU doesn't -; support scrolling (until text reaches bottom). Keeps border -; along bottom in case TV cuts it off. -; -; Defers most initialization until first newline, at which -; point it clears nametable and makes palette non-black. -; -; ** ASCII font must already be in CHR, and mirroring -; must be vertical or single-screen. - -; Number of characters of margin on left and right, to avoid -; text getting cut off by common TVs -console_margin = 1 - -console_buf_size = 32 -console_width = console_buf_size - (console_margin*2) - -zp_byte console_pos -zp_byte console_scroll -zp_byte console_temp -zp_byte text_color - -bss_res console_buf,console_buf_size - - -; Initializes console -console_init: - ; Flag that console hasn't been initialized - setb console_scroll,-1&$FF - lda #0 - sta text_color - jmp console_clear_line_ - - -; Hides console by blacking palette and disabling PPU. -; Preserved: A, X, Y -console_hide: - pha - txa - pha - tay - pha - - jsr console_wait_vbl_ - setb PPUMASK,0 - lda #$0F - tax - tay - jsr console_load_palette_ - pla - tay - pla - tax - pla - rts - - -console_wait_vbl_: - lda console_scroll - cmp #-1&$FF - jne wait_vbl_optional - - ; Deferred initialization of PPU until first use of console - - ; In case PPU doesn't support scrolling, start a - ; couple of lines down - setb console_scroll,16 - - jsr console_hide - txa - pha - - ; Fill nametable with spaces - setb PPUADDR,$20 - setb PPUADDR,$00 - ldx #240 - ;lda #$E0 - ;sta text_color - lda #0 -: sta PPUDATA - sta PPUDATA - sta PPUDATA - sta PPUDATA - dex - bne :- - - ; Clear attributes - lda #0 - ldx #$40 -: sta PPUDATA - dex - bne :- - - pla - tax - jmp console_show - - -; Shows console display -; Preserved: X, Y -console_show: - pha - - txa - pha - tay - pha - - jsr console_wait_vbl_ - setb PPUMASK,PPUMASK_BG0 - - lda #$22 ; red - ldx #$27 ; green - ldy #$30 ; white - jsr console_load_palette_ - - pla - tay - pla - tax - - jmp console_apply_scroll_ - - -; Shows console display -; Preserved: X, Y -console_show_nowait: - pha - - txa - pha - tay - pha - - setb PPUMASK,PPUMASK_BG0 - - lda #$22 ; red - ldx #$27 ; green - ldy #$30 ; white - jsr console_load_palette_ - - pla - tay - pla - tax - - jmp console_apply_scroll_ - - -console_load_palette_: - pha - setb PPUADDR,$3F - setb PPUADDR,$00 - setb PPUDATA,$0F ; black - pla - sta PPUDATA - stx PPUDATA - sty PPUDATA - rts - - -; Prints char A to console. Will not appear until -; a newline or flush occurs. -; Preserved: A, X, Y -console_print: - cmp #10 - beq console_newline - - stx console_temp - - ; Newline if buf full and next char isn't space - ldx console_pos - bpl :+ - cmp #' ' - beq @ignore_space - ldx console_temp - jsr console_newline - stx console_temp - ldx console_pos -: - ; Write to buffer - clc - adc text_color - sta console_buf+console_margin,x - dex - stx console_pos - -@ignore_space: - ldx console_temp - rts - - - - -; Displays current line and starts new one -; Preserved: A, X, Y -console_newline: - pha - jsr console_wait_vbl_ - jsr console_flush_ - jsr console_clear_line_ - - ; Scroll up 8 pixels and clear one line AHEAD - lda console_scroll - jsr console_add_8_to_scroll_ - sta console_scroll - jsr console_add_8_to_scroll_ - jsr console_flush_a - jmp console_apply_scroll_ - - -; A = (A + 8) % 240 -console_add_8_to_scroll_: - cmp #240-8 - bcc :+ - adc #16-1;+1 for set carry -: adc #8 - rts - - -console_clear_line_: - stx console_temp - - ; Start new clear line - lda #0 - ldx #console_buf_size-1 -: sta console_buf,x - dex - bpl :- - ldx #console_width-1 - stx console_pos - - ldx console_temp - rts - - -; Displays current line's contents without scrolling. -; Preserved: A, X, Y -console_flush: - pha - jsr console_wait_vbl_ - jsr console_flush_ -console_apply_scroll_: - lda #0 - sta PPUADDR - sta PPUADDR - - sta PPUSCROLL - lda console_scroll - jsr console_add_8_to_scroll_ - jsr console_add_8_to_scroll_ - sta PPUSCROLL - - pla - rts - -console_flush_: - lda console_scroll -console_flush_a: - ; Address line in nametable - sta console_temp - lda #$08 - asl console_temp - rol a - asl console_temp - rol a - sta PPUADDR - lda console_temp - sta PPUADDR - - ; Copy line - stx console_temp - ldx #console_buf_size-1 -: lda console_buf,x - sta PPUDATA - dex - bpl :- - ldx console_temp - - rts - diff --git a/test_roms/cpu_exec_space/source/common/crc.s b/test_roms/cpu_exec_space/source/common/crc.s deleted file mode 100644 index de96c2a..0000000 --- a/test_roms/cpu_exec_space/source/common/crc.s +++ /dev/null @@ -1,118 +0,0 @@ -; CRC-32 checksum calculation - -zp_res checksum,4 -zp_byte checksum_temp -zp_byte checksum_off_ - -; Turns CRC updating on/off. Allows nesting. -; Preserved: A, X, Y -crc_off: - dec checksum_off_ - rts - -crc_on: inc checksum_off_ - beq :+ - jpl internal_error ; catch unbalanced crc calls -: rts - - -; Initializes checksum module. Might initialize tables -; in the future. -init_crc: - jmp reset_crc - - -; Clears checksum and turns it on -; Preserved: X, Y -reset_crc: - lda #0 - sta checksum_off_ - lda #$FF - sta checksum - sta checksum + 1 - sta checksum + 2 - sta checksum + 3 - rts - - -; Updates checksum with byte in A (unless disabled via crc_off) -; Preserved: A, X, Y -; Time: 357 clocks average -update_crc: - bit checksum_off_ - bmi update_crc_off -update_crc_: - pha - stx checksum_temp - eor checksum - ldx #8 -@bit: lsr checksum+3 - ror checksum+2 - ror checksum+1 - ror a - bcc :+ - sta checksum - lda checksum+3 - eor #$ED - sta checksum+3 - lda checksum+2 - eor #$B8 - sta checksum+2 - lda checksum+1 - eor #$83 - sta checksum+1 - lda checksum - eor #$20 -: dex - bne @bit - sta checksum - ldx checksum_temp - pla -update_crc_off: - rts - - -; Prints checksum as 8-character hex value -print_crc: - jsr crc_off - - ; Print complement - ldx #3 -: lda checksum,x - eor #$FF - jsr print_hex - dex - bpl :- - - jmp crc_on - - -; EQ if checksum matches CRC -; Out: A=0 and EQ if match, A>0 and NE if different -; Preserved: X, Y -.macro is_crc crc - jsr_with_addr is_crc_,{.dword crc} -.endmacro - -is_crc_: - tya - pha - - ; Compare with complemented checksum - ldy #3 -: lda (ptr),y - sec - adc checksum,y - bne @wrong - dey - bpl :- - pla - tay - lda #0 - rts - -@wrong: - pla - tay - lda #1 - rts diff --git a/test_roms/cpu_exec_space/source/common/delay.s b/test_roms/cpu_exec_space/source/common/delay.s deleted file mode 100644 index 5645a34..0000000 --- a/test_roms/cpu_exec_space/source/common/delay.s +++ /dev/null @@ -1,190 +0,0 @@ -; Delays in CPU clocks, milliseconds, etc. All routines are re-entrant -; (no global data). No routines touch X or Y during execution. -; Code generated by macros is relocatable; it contains no JMPs to itself. - -zp_byte delay_temp_ ; only written to - -; Delays n clocks, from 2 to 16777215 -; Preserved: A, X, Y, flags -.macro delay n - .if (n) < 0 .or (n) = 1 .or (n) > 16777215 - .error "Delay out of range" - .endif - delay_ (n) -.endmacro - - -; Delays n milliseconds (1/1000 second) -; n can range from 0 to 1100. -; Preserved: A, X, Y, flags -.macro delay_msec n - .if (n) < 0 .or (n) > 1100 - .error "time out of range" - .endif - delay ((n)*CLOCK_RATE+500)/1000 -.endmacro - - -; Delays n microseconds (1/1000000 second). -; n can range from 0 to 100000. -; Preserved: A, X, Y, flags -.macro delay_usec n - .if (n) < 0 .or (n) > 100000 - .error "time out of range" - .endif - delay ((n)*((CLOCK_RATE+50)/100)+5000)/10000 -.endmacro - -.align 64 - -; Delays A clocks + overhead -; Preserved: X, Y -; Time: A+25 clocks (including JSR) -: sbc #7 ; carry set by CMP -delay_a_25_clocks: - cmp #7 - bcs :- ; do multiples of 7 - lsr a ; bit 0 - bcs :+ -: ; A=clocks/2, either 0,1,2,3 - beq @zero ; 0: 5 - lsr a - beq :+ ; 1: 7 - bcc :+ ; 2: 9 -@zero: bne :+ ; 3: 11 -: rts ; (thanks to dclxvi for the algorithm) - - -; Delays A*256 clocks + overhead -; Preserved: X, Y -; Time: A*256+16 clocks (including JSR) -delay_256a_16_clocks: - cmp #0 - bne :+ - rts -delay_256a_11_clocks_: -: pha - lda #256-19-22 - jsr delay_a_25_clocks - pla - clc - adc #-1&$FF - bne :- - rts - - -; Delays A*65536 clocks + overhead -; Preserved: X, Y -; Time: A*65536+16 clocks (including JSR) -delay_65536a_16_clocks: - cmp #0 - bne :+ - rts -delay_65536a_11_clocks_: -: pha - lda #256-19-22-13 - jsr delay_a_25_clocks - lda #255 - jsr delay_256a_11_clocks_ - pla - clc - adc #-1&$FF - bne :- - rts - -max_short_delay = 41 - - ; delay_short_ macro jumps into these - .res (max_short_delay-12)/2,$EA ; NOP -delay_unrolled_: - rts - -.macro delay_short_ n - .if n < 0 .or n = 1 .or n > max_short_delay - .error "Internal delay error" - .endif - .if n = 0 - ; nothing - .elseif n = 2 - nop - .elseif n = 3 - sta 65536+17 - lda #^(n - 15) - jsr delay_65536a_11_clocks_ - ; +2 ensures remaining clocks is never 1 - delay_nosave_ (((n - 15) & $FFFF) + 2) - .elseif n > 255+27 - lda #>(n - 15) - jsr delay_256a_11_clocks_ - ; +2 ensures remaining clocks is never 1 - delay_nosave_ (<(n - 15) + 2) - .elseif n >= 27 - lda #<(n - 27) - jsr delay_a_25_clocks - .else - delay_short_ n - .endif -.endmacro - -.macro delay_ n - .if n > max_short_delay - php - pha - delay_nosave_ (n - 14) - pla - plp - .else - delay_short_ n - .endif -.endmacro - diff --git a/test_roms/cpu_exec_space/source/common/devcart.bin b/test_roms/cpu_exec_space/source/common/devcart.bin deleted file mode 100644 index e8958c60cee839eb37da1072177122577e9b3155..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 256 zcmWH^NL5J7&&kOz&&*3#NX}15Rmdz>C@oG+QAny(NJ%YAPAn?XQ}8SS3FoDjr4}iq zR-`7EmOvDgq!yPb1o`{wF|6e1{r|t0VFA~KUn`w^MI9FXn9E`R;=(V5s(&Z@SlFb^WXpf00NG! A0ssI2 diff --git a/test_roms/cpu_exec_space/source/common/macros.inc b/test_roms/cpu_exec_space/source/common/macros.inc deleted file mode 100644 index 52982a6..0000000 --- a/test_roms/cpu_exec_space/source/common/macros.inc +++ /dev/null @@ -1,169 +0,0 @@ -; jxx equivalents to bxx -.macpack longbranch - -; blt, bge equivalents to bcc, bcs -.define blt bcc -.define bge bcs -.define jge jcs -.define jlt jcc - -; Puts data in another segment -.macro seg_data seg,data - .pushseg - .segment seg - data - .popseg -.endmacro - -; Reserves size bytes in zeropage/bss for name. -; If size is omitted, reserves one byte. -.macro zp_res name,size - .ifblank size - zp_res name,1 - .else - seg_data "ZEROPAGE",{name: .res size} - .endif -.endmacro - -.macro bss_res name,size - .ifblank size - bss_res name,1 - .else - seg_data "BSS",{name: .res size} - .endif -.endmacro - -.macro nv_res name,size - .ifblank size - nv_res name,1 - .else - seg_data "NVRAM",{name: .res size} - .endif -.endmacro - -; Reserves one byte in zeropage for name (very common) -.macro zp_byte name - seg_data "ZEROPAGE",{name: .res 1} -.endmacro - -; Passes constant data to routine in addr -; Preserved: A, X, Y -.macro jsr_with_addr routine,data - .local Addr - pha - lda #Addr - sta addr+1 - pla - jsr routine - seg_data "RODATA",{Addr: data} -.endmacro - -; Calls routine multiple times, with A having the -; value 'start' the first time, 'start+step' the -; second time, up to 'end' for the last time. -.macro for_loop routine,start,end,step - lda #start -: pha - jsr routine - pla - clc - adc #step - cmp #<((end)+(step)) - bne :- -.endmacro - -; Calls routine n times. The value of A in the routine -; counts from 0 to n-1. -.macro loop_n_times routine,n - for_loop routine,0,n-1,+1 -.endmacro - -; Same as for_loop, except uses 16-bit value in YX. -; -256 <= step <= 255 -.macro for_loop16 routine,start,end,step -.if (step) < -256 || (step) > 255 - .error "Step must be within -256 to 255" -.endif - ldy #>(start) - lda #<(start) -: tax - pha - tya - pha - jsr routine - pla - tay - pla - clc - adc #step -.if (step) > 0 - bcc :+ - iny -.else - bcs :+ - dey -.endif -: cmp #<((end)+(step)) - bne :-- - cpy #>((end)+(step)) - bne :-- -.endmacro - -; Copies byte from in to out -; Preserved: X, Y -.macro mov out, in - lda in - sta out -.endmacro - -; Stores byte at addr -; Preserved: X, Y -.macro setb addr, byte - lda #byte - sta addr -.endmacro - -; Stores word at addr -; Preserved: X, Y -.macro setw addr, word - lda #<(word) - sta addr - lda #>(word) - sta addr+1 -.endmacro - -; Loads XY with 16-bit immediate or value at address -.macro ldxy Arg - .if .match( .left( 1, {Arg} ), # ) - ldy #<(.right( .tcount( {Arg} )-1, {Arg} )) - ldx #>(.right( .tcount( {Arg} )-1, {Arg} )) - .else - ldy (Arg) - ldx (Arg)+1 - .endif -.endmacro - -; Increments word at Addr and sets Z flag appropriately -; Preserved: A, X, Y -.macro incw Addr - .local @incw_skip ; doesn't work, so HOW THE HELL DO YOU MAKE A LOCAL LABEL IN A MACRO THAT DOESN"T DISTURB INVOKING CODE< HUH?????? POS - inc Addr - bne @incw_skip - inc Addr+1 -@incw_skip: -.endmacro - -; Increments XY as 16-bit register, in CONSTANT time. -; Z flag set based on entire result. -; Preserved: A -; Time: 7 clocks -.macro incxy7 - iny ; 2 - beq *+4 ; 3 - ; -1 - bne *+3 ; 3 - ; -1 - inx ; 2 -.endmacro diff --git a/test_roms/cpu_exec_space/source/common/neshw.inc b/test_roms/cpu_exec_space/source/common/neshw.inc deleted file mode 100644 index bdd4136..0000000 --- a/test_roms/cpu_exec_space/source/common/neshw.inc +++ /dev/null @@ -1,37 +0,0 @@ -; NES I/O locations and masks - -; Clocks per second -.ifndef CLOCK_RATE - CLOCK_RATE = 1789773 ; NTSC -; CLOCK_RATE = 1662607 ; PAL -.endif - -.ifndef BUILD_NSF - -; PPU -PPUCTRL = $2000 -PPUMASK = $2001 -PPUSTATUS = $2002 -SPRADDR = $2003 -SPRDATA = $2004 -PPUSCROLL = $2005 -PPUADDR = $2006 -PPUDATA = $2007 -SPRDMA = $4014 - -PPUCTRL_NMI = $80 -PPUMASK_BG0 = $0A -PPUCTRL_8X8 = $00 -PPUCTRL_8X16 = $20 -PPUMASK_SPR = $14 -PPUMASK_BG0CLIP = $08 - -.endif - -; APU -SNDCHN = $4015 -JOY1 = $4016 -JOY2 = $4017 -SNDMODE = $4017 - -SNDMODE_NOIRQ = $40 diff --git a/test_roms/cpu_exec_space/source/common/ppu.s b/test_roms/cpu_exec_space/source/common/ppu.s deleted file mode 100644 index 21cad12..0000000 --- a/test_roms/cpu_exec_space/source/common/ppu.s +++ /dev/null @@ -1,142 +0,0 @@ -; PPU utilities - -bss_res ppu_not_present - -; Sets PPUADDR to w -; Preserved: X, Y -.macro set_ppuaddr w - bit PPUSTATUS - setb PPUADDR,>w - setb PPUADDR, 1789773 - .error "Currently only supports NTSC" - .endif - delay ((n)*341)/3 -.endmacro - - -; Waits for VBL then disables PPU rendering. -; Preserved: A, X, Y -disable_rendering: - pha - jsr wait_vbl_optional - setb PPUMASK,0 - pla - rts - - -; Fills first nametable with $00 -; Preserved: Y -clear_nametable: - ldx #$20 - bne clear_nametable_ - -clear_nametable2: - ldx #$24 -clear_nametable_: - lda #0 - jsr fill_screen_ - - ; Clear pattern table - ldx #64 -: sta PPUDATA - dex - bne :- - rts - - -; Fills screen with tile A -; Preserved: A, Y -fill_screen: - ldx #$20 - bne fill_screen_ - -; Same as fill_screen, but fills other nametable -fill_screen2: - ldx #$24 -fill_screen_: - stx PPUADDR - ldx #$00 - stx PPUADDR - ldx #240 -: sta PPUDATA - sta PPUDATA - sta PPUDATA - sta PPUDATA - dex - bne :- - rts - - -; Fills palette with $0F -; Preserved: Y -clear_palette: - set_ppuaddr $3F00 - ldx #$20 - lda #$0F -: sta PPUDATA - dex - bne :- - - -; Fills OAM with $FF -; Preserved: Y -clear_oam: - lda #$FF - -; Fills OAM with A -; Preserved: A, Y -fill_oam: - ldx #0 - stx SPRADDR -: sta SPRDATA - dex - bne :- - rts - - -; Initializes wait_vbl_optional. Must be called before -; using it. -.align 32 -init_wait_vbl: - ; Wait for VBL flag to be set, or ~60000 - ; clocks (2 frames) to pass - ldy #24 - ldx #1 - bit PPUSTATUS -: bit PPUSTATUS - bmi @set - dex - bne :- - dey - bpl :- -@set: - ; Be sure flag didn't stay set (in case - ; PPUSTATUS always has high bit set) - tya - ora PPUSTATUS - sta ppu_not_present - rts - - -; Same as wait_vbl, but returns immediately if PPU -; isn't working or doesn't support VBL flag -; Preserved: A, X, Y -.align 16 -wait_vbl_optional: - bit ppu_not_present - bmi :++ - ; FALL THROUGH - -; Clears VBL flag then waits for it to be set. -; Preserved: A, X, Y -wait_vbl: - bit PPUSTATUS -: bit PPUSTATUS - bpl :- -: rts diff --git a/test_roms/cpu_exec_space/source/common/print.s b/test_roms/cpu_exec_space/source/common/print.s deleted file mode 100644 index aba22a7..0000000 --- a/test_roms/cpu_exec_space/source/common/print.s +++ /dev/null @@ -1,380 +0,0 @@ -; Prints values in various ways to output, -; including numbers and strings. - -newline = 10 - -zp_byte print_temp_ - -; Prints indicated register to console as two hex -; chars and space -; Preserved: A, X, Y, flags -print_a: - php - pha -print_reg_: - jsr print_hex - lda #' ' - jsr print_char_ - pla - plp - rts - -print_x: - php - pha - txa - jmp print_reg_ - -print_y: - php - pha - tya - jmp print_reg_ - -print_p: - php - pha - php - pla - jmp print_reg_ - -print_s: - php - pha - txa - tsx - inx - inx - inx - inx - jsr print_x - tax - pla - plp - rts - - -; Prints A as two hex characters, NO space after -; Preserved: A, X, Y -print_hex: - jsr update_crc - - pha - lsr a - lsr a - lsr a - lsr a - jsr print_hex_nibble - pla - - pha - and #$0F - jsr print_hex_nibble - pla - rts - -print_hex_nibble: - cmp #10 - blt @digit - adc #6;+1 since carry is set -@digit: adc #'0' - jmp print_char_ - - -; Prints character and updates checksum UNLESS -; it's a newline. -; Preserved: A, X, Y -print_char: - cmp #newline - beq :+ - jsr update_crc -: pha - jsr print_char_ - pla - rts - - -; Prints space. Does NOT update checksum. -; Preserved: A, X, Y -print_space: - pha - lda #' ' - jsr print_char_ - pla - rts - - -; Advances to next line. Does NOT update checksum. -; Preserved: A, X, Y -print_newline: - pha - lda #newline - jsr print_char_ - pla - rts - - -; Prints string -; Preserved: A, X, Y -.macro print_str str,str2,str3,str4,str5,str6,str7,str8,str9,str10,str11,str12,str13,str14,str15 - jsr print_str_ - .byte str - .ifnblank str2 - .byte str2 - .endif - .ifnblank str3 - .byte str3 - .endif - .ifnblank str4 - .byte str4 - .endif - .ifnblank str5 - .byte str5 - .endif - .ifnblank str6 - .byte str6 - .endif - .ifnblank str7 - .byte str7 - .endif - .ifnblank str8 - .byte str8 - .endif - .ifnblank str9 - .byte str9 - .endif - .ifnblank str10 - .byte str10 - .endif - .ifnblank str11 - .byte str11 - .endif - .ifnblank str12 - .byte str12 - .endif - .ifnblank str13 - .byte str13 - .endif - .ifnblank str14 - .byte str14 - .endif - .ifnblank str15 - .byte str15 - .endif - .byte 0 -.endmacro - - -print_str_: - sta print_temp_ - - pla - sta addr - pla - sta addr+1 - - jsr inc_addr - jsr print_str_addr - - lda print_temp_ - jmp (addr) - - -; Prints string at addr and leaves addr pointing to -; byte AFTER zero terminator. -; Preserved: A, X, Y -print_str_addr: - pha - tya - pha - - ldy #0 - beq :+ ; always taken -@loop: jsr print_char - jsr inc_addr -: lda (addr),y - bne @loop - - pla - tay - pla - ; FALL THROUGH - -; Increments 16-bit value in addr. -; Preserved: A, X, Y -inc_addr: - inc addr - beq :+ - rts -: inc addr+1 - rts - - - -.pushseg -.segment "RODATA" - ; >= 60000 ? (EA60) - ; >= 50000 ? (C350) - ; >= 40000 ? (9C40) - ; >= 30000 ? (7530) - ; >= 20000 ? (4E20) - ; >= 10000 ? (2710) -digit10000_hi: .byte $00,$27,$4E,$75,$9C,$C3,$EA -digit10000_lo: .byte $00,$10,$20,$30,$40,$50,$60 - ; >= 9000 ? (2328 (hex)) - ; >= 8000 ? (1F40 (hex)) - ; >= 7000 ? (1B58 (hex)) - ; >= 6000 ? (1770 (hex)) - ; >= 5000 ? (1388 (hex)) - ; >= 4000 ? (FA0 (hex)) - ; >= 3000 ? (BB8 (hex)) - ; >= 2000 ? (7D0 (hex)) - ; >= 1000 ? (3E8 (hex)) -digit1000_hi: .byte $00,$03,$07,$0B,$0F,$13,$17,$1B,$1F,$23 -digit1000_lo: .byte $00,$E8,$D0,$B8,$A0,$88,$70,$58,$40,$28 -; >= 900 ? (384 (hex)) -; >= 800 ? (320 (hex)) -; >= 700 ? (2BC (hex)) -; >= 600 ? (258 (hex)) -; >= 500 ? (1F4 (hex)) -; >= 400 ? (190 (hex)) -; >= 300 ? (12C (hex)) -; >= 200 ? (C8 (hex)) -; >= 100 ? (64 (hex)) -digit100_hi: .byte $00,$00,$00,$01,$01,$01,$02,$02,$03,$03 -digit100_lo: .byte $00,$64,$C8,$2C,$90,$F4,$58,$BC,$20,$84 -.popseg - -.macro dec16_comparew table_hi, table_lo - .local @lt - cmp table_hi,y - bcc @lt - bne @lt ; only test the lo-part if hi-part is equal - pha - txa - cmp table_lo,y - pla -@lt: -.endmacro -.macro do_digit table_hi, table_lo - pha - ; print Y as digit; put X in A and do SEC for subtraction - jsr @print_dec16_helper - sbc table_lo,y - tax - pla - sbc table_hi,y -.endmacro - -; Prints A:X as 2-5 digit decimal value, NO space after. -; A = high 8 bits, X = low 8 bits. -print_dec16: - ora #0 - beq @less_than_256 - - ldy #6 - sty print_temp_ - - ; TODO: Use binary search? -: dec16_comparew digit10000_hi,digit10000_lo - bcs @got10000 - dey - bne :- - ;cpy print_temp_ - ;beq @got10000 -@cont_1000: - ldy #9 -: dec16_comparew digit1000_hi,digit1000_lo - bcs @got1000 - dey - bne :- ; Y = 0. - cpy print_temp_ ; zero print_temp_ = print zero-digits - beq @got1000 -@cont_100: - ldy #9 -: dec16_comparew digit100_hi,digit100_lo - bcs @got100 - dey - bne :- - cpy print_temp_ - beq @got100 -@got10000: - do_digit digit10000_hi,digit10000_lo - ; value is now 0000..9999 - ldy #0 - sty print_temp_ - beq @cont_1000 -@got1000: - do_digit digit1000_hi,digit1000_lo - ; value is now 000..999 - ldy #0 - sty print_temp_ - beq @cont_100 -@got100: - do_digit digit100_hi,digit100_lo - ; value is now 00..99 - txa - jmp print_dec_00_99 -@less_than_256: - txa - jmp print_dec -@print_dec16_helper: - tya - jsr print_digit - txa - sec - rts -; Prints A as 2-3 digit decimal value, NO space after. -; Preserved: Y -print_dec: - ; Hundreds - cmp #10 - blt print_digit - cmp #100 - blt print_dec_00_99 - ldx #'0'-1 -: inx - sbc #100 - bge :- - adc #100 - jsr print_char_x - - ; Tens -print_dec_00_99: - sec - ldx #'0'-1 -: inx - sbc #10 - bge :- - adc #10 - jsr print_char_x - ; Ones -print_digit: - ora #'0' - jmp print_char - ; Print a single digit -print_char_x: - pha - txa - jsr print_char - pla - rts - - -; Prints one of two characters based on condition. -; SEC; print_cc bcs,'C','-' prints 'C'. -; Preserved: A, X, Y, flags -.macro print_cc cond,yes,no - ; Avoids labels since they're not local - ; to macros in ca65. - php - pha - cond *+6 - lda #no - bne *+4 - lda #yes - jsr print_char - pla - plp -.endmacro - diff --git a/test_roms/cpu_exec_space/source/common/shell.inc b/test_roms/cpu_exec_space/source/common/shell.inc deleted file mode 100644 index 0f2557c..0000000 --- a/test_roms/cpu_exec_space/source/common/shell.inc +++ /dev/null @@ -1,32 +0,0 @@ -; Included at beginning of program - -.ifdef CUSTOM_PREFIX - .include "custom_prefix.s" -.endif - -; Sub-test in a multi-test ROM -.ifdef BUILD_MULTI - .include "build_multi.s" -.else - -; NSF music file -.ifdef BUILD_NSF - .include "build_nsf.s" -.endif - -; Devcart -.ifdef BUILD_DEVCART - .include "build_devcart.s" -.endif - -; NES internal RAM -.ifdef BUILD_NOCART - .include "build_nocart.s" -.endif - -; NES ROM (default) -.ifndef SHELL_INCLUDED - .include "build_rom.s" -.endif - -.endif ; .ifdef BUILD_MULTI diff --git a/test_roms/cpu_exec_space/source/common/shell.s b/test_roms/cpu_exec_space/source/common/shell.s deleted file mode 100644 index 76cbe22..0000000 --- a/test_roms/cpu_exec_space/source/common/shell.s +++ /dev/null @@ -1,331 +0,0 @@ -; Common routines and runtime - -; Detect inclusion loops (otherwise ca65 goes crazy) -.ifdef SHELL_INCLUDED - .error "shell.s included twice" - .end -.endif -SHELL_INCLUDED = 1 - -;**** Special globals **** - -; Temporary variables that ANY routine might modify, so -; only use them between routine calls. -temp = <$A -temp2 = <$B -temp3 = <$C -addr = <$E -ptr = addr - -.segment "NVRAM" - ; Beginning of variables not cleared at startup - nvram_begin: - -;**** Code segment setup **** - -.segment "RODATA" - ; Any user code which runs off end might end up here, - ; so catch that mistake. - nop ; in case there was three-byte opcode before this - nop - jmp internal_error - -; Move code to $E200 ($200 bytes for text output) -;.segment "DMC" -; .res $2200 - -; Devcart corrupts byte at $E000 when powering off -.segment "CODE" - nop - -;**** Common routines **** - -.include "macros.inc" -.include "neshw.inc" -.include "print.s" -.include "delay.s" -.include "crc.s" -.include "testing.s" - -.ifdef NEED_CONSOLE - .include "console.s" -.else - ; Stubs so code doesn't have to care whether - ; console exists - console_init: - console_show: - console_hide: - console_print: - console_flush: - rts -.endif - -.ifndef CUSTOM_PRINT - .include "text_out.s" - - print_char_: - jsr write_text_out - jmp console_print - - stop_capture: - rts - -.endif - -;**** Shell core **** - -.ifndef CUSTOM_RESET - reset: - sei - jmp std_reset -.endif - - -; Sets up hardware then runs main -run_shell: - sei - cld ; unnecessary on NES, but might help on clone - ldx #$FF - txs - jsr init_shell - set_test $FF - jmp run_main - - -; Initializes shell -init_shell: - jsr clear_ram - jsr init_wait_vbl ; waits for VBL once here, - jsr wait_vbl_optional ; so only need to wait once more - jsr init_text_out - jsr init_testing - jsr init_runtime - jsr console_init - rts - - -; Runs main in consistent PPU/APU environment, then exits -; with code 0 -run_main: - jsr pre_main - jsr main - lda #0 - jmp exit - - -; Sets up environment for main to run in -pre_main: - -.ifndef BUILD_NSF - jsr disable_rendering - setb PPUCTRL,0 - jsr clear_palette - jsr clear_nametable - jsr clear_nametable2 - jsr clear_oam -.endif - - lda #$34 - pha - lda #0 - tax - tay - jsr wait_vbl_optional - plp - sta SNDMODE - rts - - -.ifndef CUSTOM_EXIT - exit: -.endif - -; Reports result and ends program -std_exit: - sei - cld - ldx #$FF - txs - pha - - setb SNDCHN,0 - .ifndef BUILD_NSF - setb PPUCTRL,0 - .endif - - pla - pha - jsr report_result - ;jsr clear_nvram ; TODO: was this needed for anything? - pla - jmp post_exit - - -; Reports final result code in A -report_result: - jsr :+ - jmp play_byte - -: jsr print_newline - jsr console_show - - ; 0: "" - cmp #1 - bge :+ - rts -: - ; 1: "Failed" - bne :+ - print_str {"Failed",newline} - rts - - ; n: "Failed #n" -: print_str "Failed #" - jsr print_dec - jsr print_newline - rts - -;**** Other routines **** - -; Reports internal error and exits program -internal_error: - print_str newline,"Internal error" - lda #255 - jmp exit - - -.import __NVRAM_LOAD__, __NVRAM_SIZE__ - -; Clears $0-($100+S) and nv_ram_end-$7FF -clear_ram: - lda #0 - - ; Main pages - tax -: sta 0,x - sta $300,x - sta $400,x - sta $500,x - sta $600,x - sta $700,x - inx - bne :- - - ; Stack except that above stack pointer - tsx - inx -: dex - sta $100,x - bne :- - - ; BSS except nvram - ldx #<__NVRAM_SIZE__ -: sta __NVRAM_LOAD__,x - inx - bne :- - - rts - - -; Clears nvram -clear_nvram: - ldx #<__NVRAM_SIZE__ - beq @empty - lda #0 -: dex - sta __NVRAM_LOAD__,x - bne :- -@empty: - rts - - -; Prints filename and newline, if available, otherwise nothing. -; Preserved: A, X, Y -print_filename: - .ifdef FILENAME_KNOWN - pha - jsr print_newline - setw addr,filename - jsr print_str_addr - jsr print_newline - pla - .endif - rts - -.pushseg -.segment "RODATA" - ; Filename terminated with zero byte. - filename: - .ifdef FILENAME_KNOWN - .incbin "ram:nes_temp" - .endif - .byte 0 -.popseg - - -;**** ROM-specific **** -.ifndef BUILD_NSF - -.include "ppu.s" - -avoid_silent_nsf: -play_byte: - rts - -; Loads ASCII font into CHR RAM -.macro load_ascii_chr - bit PPUSTATUS - setb PPUADDR,$00 - setb PPUADDR,$00 - setb addr,ascii_chr - ldy #0 -@page: - stx addr+1 -: lda (addr),y - sta PPUDATA - iny - bne :- - inx - cpx #>ascii_chr_end - bne @page -.endmacro - -; Disables interrupts and loops forever -.ifndef CUSTOM_FOREVER -forever: - sei - lda #0 - sta PPUCTRL -: beq :- - .res $10,$EA ; room for code to run loader -.endif - - -; Default NMI -.ifndef CUSTOM_NMI - zp_byte nmi_count - - nmi: - inc nmi_count - rti - - ; Waits for NMI. Must be using NMI handler that increments - ; nmi_count, with NMI enabled. - ; Preserved: X, Y - wait_nmi: - lda nmi_count - : cmp nmi_count - beq :- - rts -.endif - - -; Default IRQ -.ifndef CUSTOM_IRQ - irq: - bit SNDCHN ; clear APU IRQ flag - rti -.endif - -.endif diff --git a/test_roms/cpu_exec_space/source/common/testing.s b/test_roms/cpu_exec_space/source/common/testing.s deleted file mode 100644 index ba41f03..0000000 --- a/test_roms/cpu_exec_space/source/common/testing.s +++ /dev/null @@ -1,106 +0,0 @@ -; Utilities for writing test ROMs - -; In NVRAM so these can be used before initializing runtime, -; then runtime initialized without clearing them -nv_res test_code ; code of current test -nv_res test_name,2 ; address of name of current test, or 0 of none - - -; Sets current test code and optional name. Also resets -; checksum. -; Preserved: A, X, Y -.macro set_test code,name - pha - lda #code - jsr set_test_ - .ifblank name - setb test_name+1,0 - .else - .local Addr - setw test_name,Addr - seg_data "RODATA",{Addr: .byte name,0} - .endif - pla -.endmacro - -set_test_: - sta test_code - jmp reset_crc - - -; Initializes testing module -init_testing: - jmp init_crc - - -; Reports that all tests passed -tests_passed: - jsr print_filename - print_str newline,"Passed" - lda #0 - jmp exit - - -; Reports "Done" if set_test has never been used, -; "Passed" if set_test 0 was last used, or -; failure if set_test n was last used. -tests_done: - ldx test_code - jeq tests_passed - inx - bne test_failed - jsr print_filename - print_str newline,"Done" - lda #0 - jmp exit - - -; Reports that the current test failed. Prints code and -; name last set with set_test, or just "Failed" if none -; have been set yet. -test_failed: - ldx test_code - - ; Treat $FF as 1, in case it wasn't ever set - inx - bne :+ - inx - stx test_code -: - ; If code >= 2, print name - cpx #2-1 ; -1 due to inx above - blt :+ - lda test_name+1 - beq :+ - jsr print_newline - sta addr+1 - lda test_name - sta addr - jsr print_str_addr - jsr print_newline -: - jsr print_filename - - ; End program - lda test_code - jmp exit - - -; If checksum doesn't match expected, reports failed test. -; Clears checksum afterwards. -; Preserved: A, X, Y -.macro check_crc expected - jsr_with_addr check_crc_,{.dword expected} -.endmacro - -check_crc_: - pha - jsr is_crc_ - bne :+ - jsr reset_crc - pla - rts - -: jsr print_newline - jsr print_crc - jmp test_failed diff --git a/test_roms/cpu_exec_space/source/common/text_out.s b/test_roms/cpu_exec_space/source/common/text_out.s deleted file mode 100644 index 3a4137f..0000000 --- a/test_roms/cpu_exec_space/source/common/text_out.s +++ /dev/null @@ -1,61 +0,0 @@ -; Text output as expanding zero-terminated string at text_out_base - -; The final exit result byte is written here -final_result = $6000 - -; Text output is written here as an expanding -; zero-terminated string -text_out_base = $6004 - -bss_res text_out_temp -zp_res text_out_addr,2 - -init_text_out: - ldx #0 - - ; Put valid data first - setb text_out_base,0 - - lda #$80 - jsr set_final_result - - ; Now fill in signature that tells emulator there's - ; useful data there - setb text_out_base-3,$DE - setb text_out_base-2,$B0 - setb text_out_base-1,$61 - - ldx #>text_out_base - stx text_out_addr+1 - setb text_out_addr,". - -Several routines are available to print values and text to the console. -Most update a running CRC-32 checksum which can be checked with -check_crc, allowing ALL the output to be checked very easily. If the -checksum doesn't match, it is printed, so you can run the code on a NES -and paste the correct checksum into your code. - -The default is to build an iNES ROM, with other build types that I -haven't documented (devcart, sub-test of a multi-test ROM, NSF music -file). My nes.cfg file puts the code at $E000 since my devcart requires -it, and I don't want the normal ROM to differ in any way from what I've -tested. - -Library routines are organized by function into several files, each with -short documentation. Each routine may also optionally list registers -which are preserved, rather than those which are modified (trashed) as -is more commonly done. This is because it's best for the caller to -assume that ALL registers are NOT preserved unless noted. - -Some macros are used to make common operations more convenient. The left -is equivalent to the right: - - Macro Equivalent - ------------------------------------- - blt bcc - - bge bcs - - jne label beq skip - jmp label - skip: - etc. - - zp_byte name .zeropage - name: .res 1 - .code - - zp_res name,n .zeropage - name: .res n - .code - - bss_res name,n .bss - name: .res n - .code - - for_loop r,b,e,s calls a routine with A set to successive values - --- -Shay Green - -Some tests might turn the screen off and on, since that affects the -behavior being tested. This does not indicate failure, and should be -ignored. Only the test result reported at the end is important. - -The error code at the end is also reported audibly with a series of -tones, in case the picture isn't visible for some reason. The code is in -binary, with a low tone indicating 0 and a high tone 1. The first tone -is always a zero, so you can tell the difference. A code of 0 means -passed, 1 means failure, and 2 or higher indicates a specific reason as -listed in the source code by the corresponding set_code line. Examples: - -low = 0 = passed -low high = 1 = failed -low high low = 2 = error 2 -low high high = 3 = error 3 - -See the source code for more information about a particular test and why -it might be failing. Each test has comments and correct output at top. --- -Shay Green diff --git a/test_roms/cpu_exec_space/source/test_cpu_exec_space_apu.s b/test_roms/cpu_exec_space/source/test_cpu_exec_space_apu.s deleted file mode 100644 index 482a5a9..0000000 --- a/test_roms/cpu_exec_space/source/test_cpu_exec_space_apu.s +++ /dev/null @@ -1,243 +0,0 @@ -; Expected output, and explanation: -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; TEST: test_cpu_exec_space_apu -; This program verifies that the -; CPU can execute code from any -; possible location that it can -; address, including I/O space. -; -; In this test, it is also -; verified that not only all -; write-only APU I/O ports -; return the open bus, but -; also the unallocated I/O -; space in $4018..$40FF. -; -; 40FF 40 -; Passed -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; -; Written by Joel Yliluoma - http://iki.fi/bisqwit/ - -.segment "LIB" -.include "shell.inc" -.include "colors.inc" -.segment "CODE" - -zp_res nmi_count -zp_res maybe_crashed - -zp_res temp_code,8 -zp_res console_save,2 - -bss_res empty,$500 - -.macro print_str_and_ret s,s2,s3,s4,s5,s6,s7,s8,s9,s10,s11,s12,s13,s14,s15 - print_str s,s2,s3,s4,s5,s6,s7,s8,s9,s10,s11,s12,s13,s14,s15 - rts -.endmacro -.macro my_print_str s,s2,s3,s4,s5,s6,s7,s8,s9,s10,s11,s12,s13,s14,s15 - .local Addr - jsr Addr - seg_data "RODATA",{Addr: print_str_and_ret s,s2,s3,s4,s5,s6,s7,s8,s9,s10,s11,s12,s13,s14,s15} -.endmacro - -set_vram_pos: - ldy PPUSTATUS - sta PPUADDR ; poke high 6 bits - stx PPUADDR ; poke low 8 bits - rts - -test_failed_finish: - jsr crash_proof_end - ; Re-enable screen - jsr console_show - text_white - jmp test_failed - -open_bus_pathological_fail: - jmp test_failed_finish - -main: - jsr intro - - ; Disable all APU channels and frame IRQ (ensure that $4015 reads back as $00) - lda #$00 - sta $4015 - lda #$40 - sta $4017 - - ldx #>empty - ldy #temp_code - jsr print_hex - lda #(:+ ) - pha - lda #<(:+ ) - pha - php - ; - lda #$4C ; jmp abs - sta temp_code+0 - stx temp_code+1 - sty temp_code+2 - jmp temp_code -: inx - bne @loop - - text_white - jsr console_show - jsr wait_vbl - jmp tests_passed - - - - - .pushseg - .segment "RODATA" -intro: text_white - print_str "TEST: test_cpu_exec_space_apu",newline - text_color1 - jsr print_str_ - ; 0123456789ABCDEF0123456789ABCD - .byte "This program verifies that the",newline - .byte "CPU can execute code from any",newline - .byte "possible location that it can",newline - .byte "address, including I/O space.",newline - .byte newline - .byte "In this test, it is also",newline - .byte "verified that not only all",newline - .byte "write-only APU I/O ports",newline - .byte "return the open bus, but",newline - .byte "also the unallocated I/O",newline - .byte "space in $4018..$40FF.",newline - .byte newline,0 - text_white - rts - .popseg - - - - - -nmi: - pha - lda maybe_crashed - beq :+ - inc nmi_count - lda nmi_count - cmp #4 - bcc :+ - jmp test_failed_finish -: - pla - rti - -crash_proof_begin: - lda #$FF - sta nmi_count - sta maybe_crashed - - ; Enable NMI - lda #$80 - sta $2000 - rts - -crash_proof_end: - ; Disable NMI - lda #0 - sta $2000 - sta maybe_crashed - rts - -irq: - ; Presume we got here through a BRK opcode. - ; Presumably, that opcode was placed in $8000..$E000 to trap wrong access. - plp -wrong_code_executed_somewhere: - text_white - print_str "ERROR",newline - text_color1 - ; 0123456789ABCDEF0123456789ABC| - print_str "Mysteriously Landed at $" - pla - tax - pla - jsr print_hex - txa - jsr print_hex - text_white - jsr print_str_ - .byte newline - ; 0123456789ABCDEF0123456789ABCD - .byte "Program flow did not follow",newline - .byte "the planned path, for a number",newline - .byte "of different possible reasons.",newline - .byte 0 - ; 0123456789ABCDEF0123456789ABC|0123456789ABCDEF0123456789ABC|0123456789ABCDEF0123456789ABC|0123456789ABCDEF0123456789ABC| - set_test 2,"Failure To Obey Predetermined Execution Path" - jmp test_failed_finish - -.pushseg -.segment "WRONG_CODE_8000" - .repeat $6200 - brk - .endrepeat - ; zero-fill -.popseg diff --git a/test_roms/cpu_exec_space/source/test_cpu_exec_space_ppuio.s b/test_roms/cpu_exec_space/source/test_cpu_exec_space_ppuio.s deleted file mode 100644 index 3b75cd5..0000000 --- a/test_roms/cpu_exec_space/source/test_cpu_exec_space_ppuio.s +++ /dev/null @@ -1,524 +0,0 @@ -; Expected output, and explanation: -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; TEST: test_cpu_exec_space -; This program verifies that the -; CPU can execute code from any -; possible location that it can -; address, including I/O space. -; -; In addition, it will be tested -; that an RTS instruction does a -; dummy read of the byte that -; immediately follows the -; instructions. -; -; JSR+RTS TEST OK -; JMP+RTS TEST OK -; RTS+RTS TEST OK -; JMP+RTI TEST OK -; JMP+BRK TEST OK -; -; Passed -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; -; Written by Joel Yliluoma - http://iki.fi/bisqwit/ - -.segment "LIB" -.include "shell.inc" -.include "colors.inc" -.segment "CODE" - -zp_res nmi_count -zp_res brk_issued -zp_res maybe_crashed - -.macro print_str_and_ret s,s2,s3,s4,s5,s6,s7,s8,s9,s10,s11,s12,s13,s14,s15 - print_str s,s2,s3,s4,s5,s6,s7,s8,s9,s10,s11,s12,s13,s14,s15 - rts -.endmacro -.macro my_print_str s,s2,s3,s4,s5,s6,s7,s8,s9,s10,s11,s12,s13,s14,s15 - .local Addr - jsr Addr - seg_data "RODATA",{Addr: print_str_and_ret s,s2,s3,s4,s5,s6,s7,s8,s9,s10,s11,s12,s13,s14,s15} -.endmacro - -set_vram_pos: - ldy PPUSTATUS - sta PPUADDR ; poke high 6 bits - stx PPUADDR ; poke low 8 bits - rts - -test_failed_finish: - jsr crash_proof_end - ; Re-enable screen - jsr console_show - text_white - jmp test_failed - -open_bus_pathological_fail: - jmp test_failed_finish - -main: - lda #0 - sta brk_issued - - ; Operations we will be doing are: - ; - jsr intro - - text_color2 - - ; 0123456789ABCDEF0123456789ABC|0123456789ABCDEF0123456789ABC|0123456789ABCDEF0123456789ABC|0123456789ABCDEF0123456789ABC| - set_test 2,"PPU memory access through $2007 does not work properly. (Use other tests to determine the exact problem.)" - jsr console_hide - jsr crash_proof_begin - - ; Put byte $55 at $2400 and byte $AA at $2411. - lda #$24 - ldx #$00 - jsr set_vram_pos - ldy #$55 - sty PPUDATA - ldx #$11 - jsr set_vram_pos - ldy #$AA - sty PPUDATA - ; Read from $2400 and $2411. - lda #$24 - ldx #$00 - jsr set_vram_pos - ldy PPUDATA ; Discard the buffered byte; load $55 into buffer. - ldx #$11 - jsr set_vram_pos - lda PPUDATA ; Load buffer ($55); place $AA in buffer. - cmp #$55 - bne test_failed_finish - lda PPUDATA ; Load buffer ($AA); place unknown in buffer. - cmp #$AA - bne test_failed_finish - - jsr crash_proof_end - jsr console_show - - ; 0123456789ABCDEF0123456789ABC|0123456789ABCDEF0123456789ABC|0123456789ABCDEF0123456789ABC|0123456789ABCDEF0123456789ABC|0123456789ABCDEF0123456789ABC| - set_test 3,"PPU open bus implementation is missing or incomplete: A write to $2003, followed by a read from $2001 should return the same value as was written." - jsr wait_vbl - lda #$B2 ; sufficiently random byte. - sta $2003 ; OAM index, but also populates open bus - eor $2001 - bne open_bus_pathological_fail - - ; Set VRAM address ($2411). This is the address we will be reading from, if the test worked properly. - jsr console_hide - jsr crash_proof_begin - - lda #$24 - ldx #$00 - jsr set_vram_pos - - ; Now, set HALF of the other address ($2400). If the test did NOT work properly, this address will be read from. - lda #$24 - sta PPUADDR - - ; Poke the open bus again; it was wasted earlier. - lda #$60 ; rts - sta $2003 ; OAM index, but also populates open bus - - set_test 4,"The RTS at $2001 was never executed." - - jsr $2001 ; should fetch opcode from $2001, and do a dummy read at $2002 - - ; 0123456789ABCDEF0123456789ABC|0123456789ABCDEF0123456789ABC|0123456789ABCDEF0123456789ABC|0123456789ABCDEF0123456789ABC| - set_test 5,"An RTS opcode should still do a dummy fetch of the next opcode. (The same goes for all one-byte opcodes, really.)" - - ; Poke the OTHER HALF of the address ($2411). If the RTS did a dummy read at $2002, as it should, - ; this ends up being a first HALF of a dummy address. - lda #$11 - sta PPUADDR - - ; Read from PPU. - lda PPUDATA ; Discard the buffered byte; load something into buffer - lda PPUDATA ; eject buffer. We should have $2400 contents ($55). - pha - jsr crash_proof_end - jsr console_show - pla - cmp #$55 - beq passed_1 - cmp #$AA ; $AA is the expected result if the dummy read was not implemented properly. - beq :+ - ; - ; If we got neither $55 nor $AA, there is something else wrong. - ; - jsr print_hex - ; 0123456789ABCDEF0123456789ABC|0123456789ABCDEF0123456789ABC|0123456789ABCDEF0123456789ABC|0123456789ABCDEF0123456789ABC| - set_test 6,"I have no idea what happened, but the test did not work as supposed to. In any case, the problem is in the PPU." -: jmp test_failed_finish - -passed_1: - ; ********* Do the test again, this time using JMP instead of JSR - print_str "JSR+RTS TEST OK",newline - - jsr console_hide - ; Set VRAM address ($2411). This is the address we will be reading from, if the test worked properly. - jsr crash_proof_begin - - lda #$24 - ldx #$00 - jsr set_vram_pos - - ; Now, set HALF of the other address ($2400). If the test did NOT work properly, this address will be read from. - lda #$24 - sta PPUADDR - - ; Poke the open bus again; it was wasted earlier. - lda #$60 ; rts - sta $2003 ; OAM index, but also populates open bus - - jsr do_jmp_test - ; should return here! - - ; 0123456789ABCDEF0123456789ABC|0123456789ABCDEF0123456789ABC|0123456789ABCDEF0123456789ABC|0123456789ABCDEF0123456789ABC|0123456789ABCDEF0123456789ABC|0123456789ABCDEF0123456789ABC|0123456789ABCDEF0123456789ABC|0123456789ABCDEF0123456789ABC| - set_test 8,"Okay, the test passed when JSR was used, but NOT when the opcode was JMP. How can an emulator possibly get this result? You may congratulate yourself now, for finding something that is even more unconventional than this test." - - ; Poke the OTHER HALF of the address ($2411). If the RTS did a dummy read at $2002, as it should, - ; this ends up being a first HALF of a dummy address. - lda #$11 - sta PPUADDR - - ; Read from PPU. - lda PPUDATA ; Discard the buffered byte; load something into buffer - lda PPUDATA ; eject buffer. We should have $2400 contents ($55). - pha - jsr crash_proof_end - jsr console_show - pla - cmp #$55 - beq passed_2 - cmp #$AA ; $AA is the expected result if the dummy read was not implemented properly. - beq :+ - ; 0123456789ABCDEF0123456789ABC|0123456789ABCDEF0123456789ABC|0123456789ABCDEF0123456789ABC|0123456789ABCDEF0123456789ABC| - ; - ; If we got neither $55 nor $AA, there is something else wrong. - ; - jsr print_hex - set_test 9,"Your PPU is broken in mind-defyingly random ways." -: jmp test_failed_finish - - -do_jmp_test: - ; 0123456789ABCDEF0123456789ABC|0123456789ABCDEF0123456789ABC|0123456789ABCDEF0123456789ABC|0123456789ABCDEF0123456789ABC| - set_test 4,"The RTS at $2001 was never executed." - jmp $2001 ; should fetch opcode from $2001, and do a dummy read at $2002 - -passed_2: - print_str "JMP+RTS TEST OK",newline - ; ********* Do the test once more, this time using RTS instead of JSR - - jsr console_hide - ; Set VRAM address ($2411). This is the address we will be reading from, if the test worked properly. - jsr crash_proof_begin - - lda #$24 - ldx #$00 - jsr set_vram_pos - - ; Now, set HALF of the other address ($2400). If the test did NOT work properly, this address will be read from. - lda #$24 - sta PPUADDR - - ; Poke the open bus again; it was wasted earlier. - lda #$60 ; rts - sta $2003 ; OAM index, but also populates open bus - - jsr do_rts_test - ; should return here! - - ; 0123456789ABCDEF0123456789ABC|0123456789ABCDEF0123456789ABC|0123456789ABCDEF0123456789ABC|0123456789ABCDEF0123456789ABC|0123456789ABCDEF0123456789ABC|0123456789ABCDEF0123456789ABC|0123456789ABCDEF0123456789ABC|0123456789ABCDEF0123456789ABC| - set_test 11,"The test passed when JSR was used, and when JMP was used, but NOT when RTS was used. Caught ya! Paranoia wins." - - ; Poke the OTHER HALF of the address ($2411). If the RTS did a dummy read at $2002, as it should, - ; this ends up being a first HALF of a dummy address. - lda #$11 - sta PPUADDR - - ; Read from PPU. - lda PPUDATA ; Discard the buffered byte; load something into buffer - lda PPUDATA ; eject buffer. We should have $2400 contents ($55). - pha - jsr crash_proof_end - jsr console_show - pla - cmp #$55 - beq passed_3 - cmp #$AA ; $AA is the expected result if the dummy read was not implemented properly. - beq :+ - ; 0123456789ABCDEF0123456789ABC|0123456789ABCDEF0123456789ABC|0123456789ABCDEF0123456789ABC|0123456789ABCDEF0123456789ABC| - ; - ; If we got neither $55 nor $AA, there is something else wrong. - ; - jsr print_hex - set_test 12,"Your PPU gave up reason at the last moment." -: jmp test_failed_finish - - -do_rts_test: - set_test 10,"RTS to $2001 never returned." ; This message never gets displayed. - lda #$20 - pha - lda #$00 - pha - rts - -passed_3: - print_str "RTS+RTS TEST OK",newline - ; Do the second test (JMP) once more. This time, use RTI rather than RTI. - - ; Set VRAM address ($2411). This is the address we will be reading from, if the test worked properly. - jsr console_hide - jsr crash_proof_begin - - lda #$24 - ldx #$00 - jsr set_vram_pos - - ; Now, set HALF of the other address ($2400). If the test did NOT work properly, this address will be read from. - lda #$24 - sta PPUADDR - - ; Poke the open bus again; it was wasted earlier. - lda #$40 ; rti - sta $2003 ; OAM index, but also populates open bus - - set_test 13,"JMP to $2001 never returned." ; This message never gets displayed, either. - - lda #>(:+ ) - pha - lda #<(:+ ) - pha - php - jmp $2001 ; should fetch opcode from $2001, and do a dummy read at $2002 -: - - ; 0123456789ABCDEF0123456789ABC|0123456789ABCDEF0123456789ABC|0123456789ABCDEF0123456789ABC|0123456789ABCDEF0123456789ABC| - set_test 14,"An RTI opcode should still do a dummy fetch of the next opcode. (The same goes for all one-byte opcodes, really.)" - - ; Poke the OTHER HALF of the address ($2411). If the RTI did a dummy read at $2002, as it should, - ; this ends up being a first HALF of a dummy address. - lda #$11 - sta PPUADDR - - ; Read from PPU. - lda PPUDATA ; Discard the buffered byte; load something into buffer - lda PPUDATA ; eject buffer. We should have $2400 contents ($55). - pha - jsr crash_proof_end - jsr console_show - pla - cmp #$55 - beq passed_4 - cmp #$AA ; $AA is the expected result if the dummy read was not implemented properly. - beq :+ - ; 0123456789ABCDEF0123456789ABC|0123456789ABCDEF0123456789ABC|0123456789ABCDEF0123456789ABC|0123456789ABCDEF0123456789ABC| - ; - ; If we got neither $55 nor $AA, there is something else wrong. - ; - jsr print_hex - set_test 15,"An RTI opcode should not destroy the PPU. Somehow that still appears to be the case here." -: jmp test_failed_finish - -passed_4: - print_str "JMP+RTI TEST OK",newline - ; ********* Do the test again, this time using BRK instead of RTS/RTI - - jsr console_hide - jsr crash_proof_begin - - ; Set VRAM address ($2411). This is the address we will be reading from, if the test worked properly. - lda #$24 - ldx #$00 - jsr set_vram_pos - - ; Now, set HALF of the other address ($2400). If the test did NOT work properly, this address will be read from. - lda #$24 - sta PPUADDR - - ; Poke the open bus again; it was wasted earlier. - lda #$00 ; brk - sta $2003 ; OAM index, but also populates open bus - - lda #1 - sta brk_issued - - set_test 17,"JSR to $2001 never returned." ; This message never gets displayed, either. - jmp $2001 - nop - nop - nop - nop -returned_from_brk: - nop - nop - nop - nop - - ; should return here! - ; 0123456789ABCDEF0123456789ABC|0123456789ABCDEF0123456789ABC|0123456789ABCDEF0123456789ABC|0123456789ABCDEF0123456789ABC|0123456789ABCDEF0123456789ABC|0123456789ABCDEF0123456789ABC|0123456789ABCDEF0123456789ABC|0123456789ABCDEF0123456789ABC| - set_test 18,"The BRK instruction should issue an automatic fetch of the byte that follows right after the BRK. (The same goes for all one-byte opcodes, but with BRK it should be a bit more obvious than with others.)" - - ; Poke the OTHER HALF of the address ($2411). If the BRK did a dummy read at $2002, as it should, - ; this ends up being a first HALF of a dummy address. - lda #$11 - sta PPUADDR - - ; Read from PPU. - lda PPUDATA ; Discard the buffered byte; load something into buffer - lda PPUDATA ; eject buffer. We should have $2400 contents ($55). - pha - jsr crash_proof_end - jsr console_show - pla - cmp #$55 - beq passed_5 - cmp #$AA ; $AA is the expected result if the dummy read was not implemented properly. - beq :+ - ; 0123456789ABCDEF0123456789ABC|0123456789ABCDEF0123456789ABC|0123456789ABCDEF0123456789ABC|0123456789ABCDEF0123456789ABC| - ; - ; If we got neither $55 nor $AA, there is something else wrong. - ; - jsr print_hex - set_test 19,"A BRK opcode should not destroy the PPU. Somehow that still appears to be the case here." -: jmp test_failed_finish - - -passed_5: - print_str "JMP+BRK TEST OK",newline - text_white - jsr console_show - jsr wait_vbl - jmp tests_passed - - - - - .pushseg - .segment "RODATA" -intro: text_white - print_str "TEST:test_cpu_exec_space_ppuio",newline - text_color1 - jsr print_str_ - ; 0123456789ABCDEF0123456789ABCD - .byte "This program verifies that the",newline - .byte "CPU can execute code from any",newline - .byte "possible location that it can",newline - .byte "address, including I/O space.",newline - .byte newline - .byte "In addition, it will be tested",newline - .byte "that an RTS instruction does a",newline - .byte "dummy read of the byte that",newline - .byte "immediately follows the",newline - .byte "instructions.",newline - .byte newline,0 - text_white - rts - .popseg - - - ; Prospects (bleak) of improving this test: - ; - ; $2000 is write only (writing updates open_bus, reading returns open_bus) - ; $2001 is write only (writing updates open_bus, reading returns open_bus) - ; $2002 is read only (writing updates open_bus, reading UPDATES open_bus (but only for low 5 bits)) - ; $2003 is write only (writing updates open_bus, reading returns open_bus) - ; $2004 is read-write (writing updates open_bus, however for %4==2, bitmask=11100011. Reading is UNRELIABLE.) - ; $2005 is write only (writing updates open_bus, reading returns open_bus) - ; $2006 is write only (writing updates open_bus, reading returns open_bus) - ; $2007 is read-write (writing updates open_bus, reading UPDATES open_bus) - - -irq: - ; Presume we got here through a BRK opcode. - lda brk_issued - beq spurious_irq - cmp #1 - beq brk_successful - ; If we got a spurious IRQ, and already warned of it once, do a regular RTI - rti -spurious_irq: - lda #2 - sta brk_issued - set_test 16,"IRQ occurred uncalled" - jmp test_failed_finish -brk_successful: - jmp returned_from_brk - - - -nmi: - pha - lda maybe_crashed - beq :+ - inc nmi_count - lda nmi_count - cmp #4 - bcc :+ - jmp test_failed_finish -: - pla - rti - -crash_proof_begin: - lda #$FF - sta nmi_count - sta maybe_crashed - - ; Enable NMI - lda #$80 - sta $2000 - rts - -crash_proof_end: - ; Disable NMI - lda #0 - sta $2000 - sta maybe_crashed - rts - -wrong_code_executed_somewhere: - pha - txa - pha - - text_white - print_str "ERROR",newline - - text_color1 - print_str "Mysteriously Landed at $" - pla - jsr print_hex - pla - jsr print_hex - jsr print_newline - text_color1 - ; 0123456789ABCDEF0123456789ABC| - print_str "CPU thinks we are at: $" - pla - tax - pla - jsr print_hex - txa - jsr print_hex - ; 0123456789ABCDEF0123456789ABC|0123456789ABCDEF0123456789ABC|0123456789ABCDEF0123456789ABC|0123456789ABCDEF0123456789ABC| - set_test 7,"A jump to $2001 should never execute code from anywhere else than $2001" - jmp test_failed_finish - -.pushseg -.segment "WRONG_CODE_8000" - .repeat $6200/8, I - .byt $EA - lda #<( $8001+ 8*I) - ldx #>( $8001+ 8*I) - jsr wrong_code_executed_somewhere - .endrepeat - ; CODE BEGINS AT E200 -.popseg diff --git a/test_roms/cpu_exec_space/test_cpu_exec_space_apu.nes b/test_roms/cpu_exec_space/test_cpu_exec_space_apu.nes deleted file mode 100644 index db7559f47dea8a5f7b5d6a873ea3243d9e31a90d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 40976 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 diff --git a/test_roms/nestest.fdb b/test_roms/nestest.fdb deleted file mode 100644 index a972c53..0000000 --- a/test_roms/nestest.fdb +++ /dev/null @@ -1,4 +0,0 @@ -BreakPoint: startAddr=00000014 endAddr=00000000 flags=ER--X- condition="" desc="" -BreakPoint: startAddr=00000023 endAddr=00000000 flags=ER--X- condition="" desc="" -BreakPoint: startAddr=00000000 endAddr=00000000 flags=EC--X- condition="" desc="" -Bookmark: addr=C10F desc="" diff --git a/test_roms/nestest.nes b/test_roms/nestest.nes deleted file mode 100644 index fc2a88c36db9c5c2de9cca33be0e446e12007f17..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24592 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 O2L?Sb=z;&AJn-*m;2p96 diff --git a/test_roms/smb.fdb b/test_roms/smb.fdb deleted file mode 100644 index 4168ad2..0000000 --- a/test_roms/smb.fdb +++ /dev/null @@ -1 +0,0 @@ -BreakPoint: startAddr=00000022 endAddr=00000000 flags=ER--X- condition="" desc="" diff --git a/test_roms/smb.nes b/test_roms/smb.nes deleted file mode 100644 index 4342b2eec67ed2497bd5b4392d4c40279921a48b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 40976 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≷Woja?()9P3JgKzg5j00M?0 z!Md=7Ed68_euMk-jaFu$l^ci! zF-@DjzeZZ$!6R%~cc|$F-BVA~!#Xpbdw!-l@IqUo7i+<796LofZ1pd^{(+c&z}ks^ zq;wUE-w)jA@L$V$dsQN;MbFi37u<(&unEzV;^P!`;*@n(D0g zP1_K|HA+%FTH<)a^rmCAX^rC?T|_U?Y@H*{`+TA@s}AJqx2?>ZBG%F+8&BM}?pv(h z&)gJu-xR0)Qn2fQHz~{N{pNz5GhJ|;b9)PnqP;iD{Zr`6pB?8Am?$lzGc%W+1OQKQFb8p$|cq<{B9+nQS$Kkjeg8FF8u`8B>X4em-ZKUx1|)!B>=grBt>3 z-R4KYixREvp!qSJBLx$hMeX{7h^Ja|(9E`BekiB1m|?C``{hCNdnll^avq7fw-u+` z+C&>hsS{-M05(fi9OvePRFGkzr8CTC?FwtNN}Ccv%6@1HFjF05HP& z@jRqEK7;=l2|#L5hyc~b9j;F!+uPk;Fp0ws(by03V(v^9-aYC9!(=i_#adju?n zF~($IfYiT4tsSm=Ok&(&th3oV+eyLWXRGAhEP{rq4ur9aFCW%vBage#80C$e(=Wit z2h@liqwV)KOd;AC-MFAgfU(^Tds_EoftaCD^sookLFe=79M$LfN=Pt8GyO(2dk-fx z-#nbrJP&uTH^1Ke*WuFRUmnkCeymyFY(DNiY(C!o-HUtg;pdKYf1f!*pXm3y

m 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%0DEkguRi*P9DR( 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