Create APU simulator for debugging

This commit is contained in:
Lucas Scharenbroich 2023-06-16 01:05:31 -05:00
parent 361c7dae56
commit 60d566e78c
4 changed files with 517 additions and 1 deletions

59
demos/smb/Sim.s Normal file
View File

@ -0,0 +1,59 @@
; IIgs Game Engine
TYP $B3 ; S16 file
DSK APUSim
XPL
; Segment #1 -- Main execution block
ASM apu_sim.s
KND #$1100
SNA MAIN

454
demos/smb/apu_sim.s Normal file
View File

@ -0,0 +1,454 @@
; APU Sim
;
; Interactive driver for the APU emulation. Inspired by the liveNES ROM (https://github.com/plgDavid/livenes)
REL
use EDS.GSOS.Macs
; Keycodes
LEFT_ARROW equ $08
RIGHT_ARROW equ $15
UP_ARROW equ $0B
DOWN_ARROW equ $0A
KBD_REG equ $E0C000
KBD_STROBE_REG equ $E0C010
VBL_STATE_REG equ $E0C019
MOD_REG equ $E0C025
COMMAND_KEY_REG equ $E0C061
OPTION_KEY_REG equ $E0C062
; ReadControl return value bits
PAD_BUTTON_B equ $0100
PAD_BUTTON_A equ $0200
PAD_KEY_DOWN equ $0400
; Direct page space
MyUserId equ 0
LastKey equ 2
CursorRow equ 4
CursorCol equ 6
Tmp0 equ 128
Tmp1 equ 130
mx %00
phk
plb
sta MyUserId
stz CursorCol
stz CursorRow
jsr InitGraphics
jsr APUStartUp
sep #$30
lda #1
jsl APU_STATUS_WRITE ; turn on the first pulse channel by default
rep #$30
:update
jsr DrawUI
:evtloop
jsr DrawDynUI ; Always update to see changing internal APU values
jsr _ReadControl
bit #PAD_KEY_DOWN ; Only response to actual key presses
beq :evtloop
and #$007F
cmp #'q'
beq :done
cmp #UP_ARROW
bne *+8
jsr MoveUp
brl :update
cmp #DOWN_ARROW
bne *+8
jsr MoveDown
brl :update
cmp #LEFT_ARROW
bne *+8
jsr MoveLeft
brl :update
cmp #RIGHT_ARROW
bne *+8
jsr MoveRight
brl :update
cmp #' '
bne :next
jsr Toggle
brl :update
:next
brl :evtloop
:done
jsr APUShutDown
Quit
_QuitGS qtRec
qtRec adrl $0000
da $00
; Toggle an APU bit
Toggle
mx %11
sep #$30
lda CursorRow
asl
tax
jmp (:toggle1,x)
:toggle1 da Toggle4000,Toggle4001,Toggle4002,Toggle4003,Toggle4015
Toggle4000
lda APU_PULSE1_REG1
ldx CursorCol
eor ToggleTable,x
jsl APU_PULSE1_REG1_WRITE
bra ToggleExit
Toggle4001
lda APU_PULSE1_REG2
ldx CursorCol
eor ToggleTable,x
jsl APU_PULSE1_REG2_WRITE
bra ToggleExit
Toggle4002
lda APU_PULSE1_REG3
ldx CursorCol
eor ToggleTable,x
jsl APU_PULSE1_REG3_WRITE
bra ToggleExit
Toggle4003
lda APU_PULSE1_REG4
ldx CursorCol
eor ToggleTable,x
jsl APU_PULSE1_REG4_WRITE
bra ToggleExit
Toggle4015
lda APU_STATUS
ldx CursorCol
eor ToggleTable,x
jsl APU_STATUS_WRITE
bra ToggleExit
TogglePulse2
ToggleExit
rep #$30
rts
ToggleTable dfb $80,$40,$20,$10,$08,$04,$02,$01
; Cursor navigation
mx %00
MoveUp
lda CursorRow
dec
bpl *+5
lda #4
sta CursorRow
rts
MoveDown
lda CursorRow
inc
cmp #5
bcc *+5
lda #0
sta CursorRow
rts
MoveLeft
lda CursorCol
dec
bpl *+5
lda #7
sta CursorCol
rts
MoveRight
lda CursorCol
inc
cmp #8
bcc *+5
lda #0
sta CursorCol
rts
; Read the keyboard and paddle controls and return in a game-controller-like format
mx %00
_ReadControl pea $0000 ; low byte = key code, high byte = %------AB
sep #$20
ldal OPTION_KEY_REG ; 'B' button
and #$80
beq :BNotDown
lda #>PAD_BUTTON_B
ora 2,s
sta 2,s
:BNotDown
ldal COMMAND_KEY_REG
and #$80
beq :ANotDown
lda #>PAD_BUTTON_A
ora 2,s
sta 2,s
:ANotDown
ldal KBD_STROBE_REG ; read the keyboard
bit #$80
beq :KbdNotDwn ; check the key-down status
and #$7f
ora 1,s
sta 1,s
cmp LastKey
beq :KbdDown
sta LastKey
lda #>PAD_KEY_DOWN ; set the keydown flag
ora 2,s
sta 2,s
bra :KbdDown
:KbdNotDwn
stz LastKey
:KbdDown
rep #$20
pla
rts
mx %00
InitGraphics
lda #0
ldx #0
:scbloop stal $E12000,x
inx
inx
cpx #$7E00
bcc :scbloop
ldx #0
:palloop lda DefaultPalette,x
stal $E19E00,x
inx
inx
cpx #$20
bcc :palloop
sep #$20
lda #$C1
stal $E0C029
rep #$20
rts
DefaultPalette ENT
dw $0000,$0777,$0841,$072C
dw $000F,$0080,$0F70,$0D00
dw $0FA9,$0FF0,$00E0,$04DF
dw $0DAF,$078F,$0CCC,$0FFF
; UI string templates
PULSE1_TITLE str 'PULSE1'
PULSE_REG1_STR str 'DDLCVVVV'
PULSE_REG2_STR str 'EPPPNSSS'
PULSE_REG3_STR str 'TTTTTTTT'
PULSE_REG4_STR str 'LLLLLTTT'
APU_STATUS_STR str '---DNT21'
ROW_SPAN equ {8*160}
DrawDynUI
ldx #{18*4}+{ROW_SPAN*5}
ldy #$3333
lda APU_PULSE1_LENGTH_COUNTER
jsr DrawByte
ldx #{18*4}+{ROW_SPAN*6}
ldy #$3333
lda APU_PULSE1_MUTE
jsr DrawByte
ldx #{18*4}+{ROW_SPAN*7}
ldy #$3333
lda APU_PULSE1_ENVELOPE
jsr DrawByte
ldx #{18*4}+{ROW_SPAN*8}
ldy #$3333
lda APU_PULSE1_CURRENT_PERIOD
jsr DrawWord
DrawUI
ldx #{1*4}+{ROW_SPAN*5}
ldy #$4444
lda #$4000
jsr DrawWord
ldy #PULSE_REG1_STR
lda APU_PULSE1_REG1
ldx #{6*4}+{ROW_SPAN*5}
jsr DrawBitsHL
ldx #{15*4}+{ROW_SPAN*5}
ldy #$5555
lda APU_PULSE1_REG1
jsr DrawByte
ldx #{1*4}+{ROW_SPAN*6}
ldy #$4444
lda #$4001
jsr DrawWord
ldy #PULSE_REG2_STR
lda APU_PULSE1_REG2
ldx #{6*4}+{ROW_SPAN*6}
jsr DrawBitsHL
ldx #{15*4}+{ROW_SPAN*6}
ldy #$5555
lda APU_PULSE1_REG2
jsr DrawByte
ldx #{1*4}+{ROW_SPAN*7}
ldy #$4444
lda #$4002
jsr DrawWord
ldy #PULSE_REG3_STR
lda APU_PULSE1_REG3
ldx #{6*4}+{ROW_SPAN*7}
jsr DrawBitsHL
ldx #{15*4}+{ROW_SPAN*7}
ldy #$5555
lda APU_PULSE1_REG3
jsr DrawByte
ldx #{1*4}+{ROW_SPAN*8}
ldy #$4444
lda #$4003
jsr DrawWord
ldy #PULSE_REG4_STR
lda APU_PULSE1_REG4
ldx #{6*4}+{ROW_SPAN*8}
jsr DrawBitsHL
ldx #{15*4}+{ROW_SPAN*8}
ldy #$5555
lda APU_PULSE1_REG4
jsr DrawByte
; Draw the APU Status byte
ldx #{1*4}+{ROW_SPAN*10}
ldy #$4444
lda #$4015
jsr DrawWord
ldy #APU_STATUS_STR
lda APU_STATUS
ldx #{6*4}+{ROW_SPAN*10}
jsr DrawBitsHL
ldx #{15*4}+{ROW_SPAN*10}
ldy #$5555
lda APU_STATUS
jsr DrawByte
lda CursorRow
asl
tax
lda row2screen,x ; Get the physical position of each logical row
asl
asl
asl
asl
asl
pha
asl
asl
clc
adc 1,s
asl
asl
asl
sta 1,s
lda CursorCol
clc
adc #6
asl
asl
clc
adc 1,s
tax
pla
lda #'_'
ldy #$FFFF
jsr DrawBottom
rts
row2screen dw 5,6,7,8,10
; Draw a byte as a series of bits using the template strings and
; the bit values to set the color
;
; x = screen coordinates
; y = string template
; a = byte value
DrawBitsHL
and #$00FF
xba
sta Tmp0
iny ; advance past string length byte
sty Tmp1
ldy #0
:loop
phy
lda (Tmp1),y
and #$00FF
ldy #$1111 ; dk. grey
asl Tmp0
bcc *+5
ldy #$FFFF ; white
jsr DrawChar
txa
clc
adc #4
tax
ply
iny
cpy #8
bcc :loop
rts
put App.Msg.s
put font.s
put apu.s

View File

@ -14,4 +14,5 @@ REM Cadius does not overwrite files, so clear the root folder first
REM Now copy files and folders as needed
%CADIUS% ADDFILE %IMAGE% %FOLDER% .\SuperMarioGS
%CADIUS% ADDFILE %IMAGE% %FOLDER% .\APUSim
%CADIUS% ADDFILE %IMAGE% %FOLDER% ..\..\src\Tool160

View File

@ -15,10 +15,12 @@
"gsport": "%npm_package_config_gsport%",
"build:rom": "%npm_package_config_merlin32% -V %npm_package_config_macros% RomOnly.s",
"build:sys16": "%npm_package_config_merlin32% -V %npm_package_config_macros% App.s",
"build:sim": "%npm_package_config_merlin32% -V %npm_package_config_macros% Sim.s",
"build": "npm run build:tool && npm run build:sys16",
"build:tool": "%npm_package_config_merlin32% -V %npm_package_config_macros% ../../src/Master.s",
"build:image": "build-image.bat %npm_package_config_cadius%",
"build:swizzle": "",
"build:swizzle": "./mkswizzetbl.sh > pal_w11.s",
"run:sim": "npm run build:sim && npm run build:image && npm run gsport",
"debug": "\"%npm_package_config_crossrunner%\" SuperMarioGS -Source SuperMarioGS_S02__Output.txt -Source SuperMarioGS_S03__Output.txt -Debug -CompatibilityLayer"
},