6502 command stream player, part 7

NES ROM - untested. probably will not work
This commit is contained in:
tildearrow 2025-04-18 13:57:25 -05:00
parent 3a04b5b18d
commit 05059e3e26
5 changed files with 196 additions and 27 deletions

View file

@ -1,23 +1,51 @@
; this is a definition file for a NES ROM. ; this is a definition file for a NES ROM.
; addresses
PPUCTRL=$2000
PPUMASK=$2001
PPUSTATUS=$2002
OAMADDR=$2003
OAMDATA=$2004
PPUSCROLL=$2005
PPUADDR=$2006
PPUDATA=$2007
APUBASE=$4000
OAMDMA=$4014
; memory map
.MEMORYMAP .MEMORYMAP
DEFAULTSLOT 1 DEFAULTSLOT 1
; 2KB RAM ; 2KB RAM
SLOT 0 START $0000 SIZE $800 SLOT 0 START $0000 SIZE $800
; 32KB ROM ; 32KB ROM
SLOT 1 START $8000 SIZE $8000 SLOT 1 START $8000 SIZE $8000
; 8KB character ROM
SLOT 2 START $10000 SIZE $2000
SLOT 3 START $12000 SIZE $10
.ENDME .ENDME
.ROMBANKMAP .ROMBANKMAP
BANKSTOTAL 2 BANKSTOTAL 3
; iNES header ; iNES header
BANKSIZE $10 BANKSIZE $10
BANKS 1
; program ROM data ; program ROM data
BANKSIZE $8000 BANKSIZE $8000
BANKS 1 BANKS 1
; character ROM data ; character ROM data
BANKSIZE $2000
BANKS 1
.ENDRO .ENDRO
.BANK 1 SLOT 1 ; iNES header goes here
.ORGA $8000 .BANK 0 SLOT 3
.db "NES"
.db $1a
; program size
.db $02
; character size
.db $01
; flags/padding
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00

View file

@ -0,0 +1,2 @@
[objects]
test.o

View file

@ -3,4 +3,123 @@
.include "nes.i" .include "nes.i"
pendingTick=$400
; program ROM
.BANK 1 SLOT 1
.ORGA $8000
main: main:
; initialize processor
sei
cld
ldx #$ff
txs
; clear all memory
ldx #$07
stx $01
lda #$00
sta $00
tay
- sta ($00),y
dey
bne -
dex
bne -
; clear zero page
ldx #$00
- sta $00,x
dex
bne -
initPlayer:
; initialize command stream player
jsr fcsInit
initPPU:
; wait for PPU to be ready
bit PPUSTATUS
; wait two frames
- bit PPUSTATUS
bpl -
- bit PPUSTATUS
bpl -
startPlayer:
; draw some text
lda #$21
sta PPUADDR
lda #$02
sta PPUADDR
ldx #$00
- lda helloWorld.w,x
beq +
sta PPUDATA
inx
bne -
; set up PPU
+ lda #$07
sta PPUMASK
; reset scroll position
bit PPUSTATUS
lda #$00
sta PPUSCROLL
sta PPUSCROLL
; set up VBlank interrupt
lda #$80
sta PPUCTRL
loop:
lda pendingTick
beq loop
jsr fcsTick
lda #0
sta pendingTick
jmp loop
; interrupt handlers
nmi:
lda #1
sta pendingTick
rti
irq:
rti
; command stream player definition
FCS_MAX_CHAN=4
FCS_MAX_STACK=16
fcsAddrBase=$20
fcsZeroPage=$10
fcsGlobalStack=$200
fcsPtr=cmdStream
fcsVolMax=volMaxArray
; command call table
fcsCmdTableLow=fcsCmdTableExample
fcsCmdTableHigh=fcsCmdTableExample
.include "../stream.s"
; data
helloWorld:
.db "Hello, World!"
.db 0
volMaxArray:
.dw $40, $40, $40, $40
cmdStream:
.incbin "../seq.bin"
; vectors
.ORGA $FFFA
.dw nmi
.dw main
.dw irq
; character ROM
.BANK 2 SLOT 2
.ORGA $10000
.incbin "chr.bin"

View file

@ -2,6 +2,17 @@
; written by tildearrow ; written by tildearrow
; usage: ; usage:
; define the following constants:
; - FCS_MAX_CHAN: the number of channels in your stream
; - FCS_MAX_STACK: the maximum stack size
; - fcsAddrBase: player state address base
; - fcsZeroPage: player state address base for zero-page-mandatory variables
; - fcsGlobalStack: player stack (best placed in a page)
; - fcsPtr: pointer to command stream
; - fcsVolMax: pointer to max channel volume array
; - fcsCmdTableLow: low address of command table
; - fcsCmdTableHigh: high address of command table
; - see stream_example.i for an example
; call fcsInit - this sets A to 0 on success or 1 on failure ; call fcsInit - this sets A to 0 on success or 1 on failure
; call fcsTick on every frame/tick/whatever ; call fcsTick on every frame/tick/whatever
; - call your dispatch implementation's tick function afterwards ; - call your dispatch implementation's tick function afterwards
@ -10,33 +21,12 @@
; - short pointers only ; - short pointers only
; - little-endian only! ; - little-endian only!
.include "6502base.i"
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; constants
FCS_MAX_CHAN=8 ; maximum number of channels (up to 127, but see below!)
FCS_MAX_STACK=16 ; stack depth per channel (FCS_MAX_STACK*FCS_MAX_CHAN<256)
; player constants - change if necessary
fcsAddrBase=$20 ; player state address base
fcsZeroPage=$10 ; player state address base for zero-page-mandatory variables
fcsGlobalStack=$200 ; player stack (best placed in a page)
fcsPtr=$8000 ; pointer to command stream
fcsVolMax=fcsVolMaxExample ; pointer to max channel volume array
; calculated from player constants ; calculated from player constants
fcsDelays=fcsPtr+8 fcsDelays=fcsPtr+8
fcsSpeedDial=fcsPtr+24 fcsSpeedDial=fcsPtr+24
; command call table
; - see src/engine/dispatch.h for a list of commands to be potentially handled
; - do not implement HINT commands - the player will never send these
; - no need to implement commands not pertaining to the target system
; - a zero pointer means "don't handle"
fcsCmdTableLow=fcsCmdTableExample
fcsCmdTableHigh=fcsCmdTableExample
; variables ; variables
; these may be read by your command handling routines ; these may be read by your command handling routines
fcsArg0=fcsAddrBase ; int fcsArg0=fcsAddrBase ; int
@ -495,10 +485,13 @@ fcsInit:
; set channel program counters ; set channel program counters
ldx #(FCS_MAX_CHAN*2) ldx #(FCS_MAX_CHAN*2)
- dex - dex
lda fcsPtr+40,x lda fcsPtr+40.w,x
sta chanPC,x sta chanPC,x
bne - bne -
; set volumes
; TODO
; success ; success
lda #0 lda #0
rts rts
@ -572,7 +565,14 @@ fcsDummyFunc:
rts rts
fcsVolMaxExample: fcsVolMaxExample:
.db 127, 127, 127, 127, 127, 127, 127, 127 .dw $7f00
.dw $7f00
.dw $7f00
.dw $7f00
.dw $7f00
.dw $7f00
.dw $7f00
.dw $7f00
; first 64 commands ; first 64 commands
fcsCmdTableExample: fcsCmdTableExample:

View file

@ -0,0 +1,20 @@
; this is an example file.
; constants
FCS_MAX_CHAN=8 ; maximum number of channels (up to 127, but see below!)
FCS_MAX_STACK=16 ; stack depth per channel (FCS_MAX_STACK*FCS_MAX_CHAN<256)
; player constants - change if necessary
fcsAddrBase=$20 ; player state address base
fcsZeroPage=$10 ; player state address base for zero-page-mandatory variables
fcsGlobalStack=$200 ; player stack (best placed in a page)
fcsPtr=$8000 ; pointer to command stream
fcsVolMax=fcsVolMaxExample ; pointer to max channel volume array
; command call table
; - see src/engine/dispatch.h for a list of commands to be potentially handled
; - do not implement HINT commands - the player will never send these
; - no need to implement commands not pertaining to the target system
; - a zero pointer means "don't handle"
fcsCmdTableLow=fcsCmdTableExample
fcsCmdTableHigh=fcsCmdTableExample