diff --git a/demos/smb/Sim.s b/demos/smb/Sim.s new file mode 100644 index 0000000..225fecc --- /dev/null +++ b/demos/smb/Sim.s @@ -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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/demos/smb/apu_sim.s b/demos/smb/apu_sim.s new file mode 100644 index 0000000..15098c0 --- /dev/null +++ b/demos/smb/apu_sim.s @@ -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 diff --git a/demos/smb/build-image.bat b/demos/smb/build-image.bat index e71d339..571016a 100644 --- a/demos/smb/build-image.bat +++ b/demos/smb/build-image.bat @@ -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 diff --git a/demos/smb/package.json b/demos/smb/package.json index 491597b..3e369af 100644 --- a/demos/smb/package.json +++ b/demos/smb/package.json @@ -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" },