diff --git a/src/asm/6502/nes/nes.i b/src/asm/6502/nes/nes.i index cf161934a..c15bf64ea 100644 --- a/src/asm/6502/nes/nes.i +++ b/src/asm/6502/nes/nes.i @@ -1,23 +1,51 @@ ; 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 DEFAULTSLOT 1 ; 2KB RAM SLOT 0 START $0000 SIZE $800 ; 32KB ROM SLOT 1 START $8000 SIZE $8000 +; 8KB character ROM +SLOT 2 START $10000 SIZE $2000 +SLOT 3 START $12000 SIZE $10 .ENDME .ROMBANKMAP -BANKSTOTAL 2 +BANKSTOTAL 3 ; iNES header BANKSIZE $10 +BANKS 1 ; program ROM data BANKSIZE $8000 BANKS 1 ; character ROM data - +BANKSIZE $2000 +BANKS 1 .ENDRO -.BANK 1 SLOT 1 -.ORGA $8000 +; iNES header goes here +.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 diff --git a/src/asm/6502/nes/test.ini b/src/asm/6502/nes/test.ini new file mode 100644 index 000000000..02a5a2eaa --- /dev/null +++ b/src/asm/6502/nes/test.ini @@ -0,0 +1,2 @@ +[objects] +test.o diff --git a/src/asm/6502/nes/test.s b/src/asm/6502/nes/test.s index c7f2433d9..848ec05d9 100644 --- a/src/asm/6502/nes/test.s +++ b/src/asm/6502/nes/test.s @@ -3,4 +3,123 @@ .include "nes.i" +pendingTick=$400 + +; program ROM +.BANK 1 SLOT 1 +.ORGA $8000 + 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" diff --git a/src/asm/6502/stream.s b/src/asm/6502/stream.s index 1dadeb1b0..775ae11c8 100644 --- a/src/asm/6502/stream.s +++ b/src/asm/6502/stream.s @@ -2,6 +2,17 @@ ; written by tildearrow ; 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 fcsTick on every frame/tick/whatever ; - call your dispatch implementation's tick function afterwards @@ -10,33 +21,12 @@ ; - short pointers 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 fcsDelays=fcsPtr+8 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 ; these may be read by your command handling routines fcsArg0=fcsAddrBase ; int @@ -495,10 +485,13 @@ fcsInit: ; set channel program counters ldx #(FCS_MAX_CHAN*2) - dex - lda fcsPtr+40,x + lda fcsPtr+40.w,x sta chanPC,x bne - + ; set volumes + ; TODO + ; success lda #0 rts @@ -572,7 +565,14 @@ fcsDummyFunc: rts 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 fcsCmdTableExample: diff --git a/src/asm/6502/stream_example.i b/src/asm/6502/stream_example.i new file mode 100644 index 000000000..950fd71eb --- /dev/null +++ b/src/asm/6502/stream_example.i @@ -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