6502 command stream player, part 3

does not compile
This commit is contained in:
tildearrow 2025-04-16 20:39:07 -05:00
parent f18faa4655
commit 17a14f292f
5 changed files with 98 additions and 121 deletions

2
.gitignore vendored
View file

@ -37,3 +37,5 @@ res/docpdf/.venv
res/docpdf/htmldoc/ res/docpdf/htmldoc/
res/fonts/compressed/ res/fonts/compressed/
res/furnace.appdata.xml res/furnace.appdata.xml
src/asm/6502/*.o
src/asm/6502/*.bin

20
src/asm/6502/6502base.i Normal file
View file

@ -0,0 +1,20 @@
; this defines a base 6502 machine with 64K RAM across the entire address space.
; use for testing!
.MEMORYMAP
DEFAULTSLOT 0
SLOT 0 START $0000 SIZE $2000
SLOT 1 START $2000 SIZE $2000
SLOT 2 START $4000 SIZE $2000
.ENDME
.ROMBANKMAP
BANKSTOTAL 3
BANKSIZE $2000
BANKS 2
BANKSIZE $C000
BANKS 1
.ENDRO
.BANK 1 SLOT 1
.ORGA $2000

View file

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

View file

@ -1,73 +0,0 @@
patPos=$90
tempByte=$80
nextNote=$a0
nextIns=$a1
nextVolume=$b0
nextRow=$b1
nextEffect1=$c0
nextEffect2=$d0
nextEffect3=$e0
nextEffect4=$f0
.macro nextByte
lda (patPos,x)
inc patPos,x
bcc :+
inc patPos+1,x
: clc
.endmacro
; read next row.
; load X with channel<<1
readNext:
lda #$ff
sta nextNote,x ; clear last values
sta nextIns,x
sta nextVolume,x
sta nextEffect1,x
sta nextEffect2,x
sta nextEffect3,x
sta nextEffect4,x
nextByte
sta tempByte ; temporary store
beq endOfPat
lda #$20 ; start pattern check
bit tempByte ; NVI..EEE
bpl :+
php ; read note
nextByte
sta nextNote,x
plp
: bvc :+
php ; read volume
nextByte
sta nextVolume,x
plp
: bne :+
nextByte ; read instrument
sta nextIns,x
: lda tempByte
and #7
tay
txa
pha
clv
readEffectLoop:
dey ; check if we're done
beq readLength
nextByte ; effect
sta nextEffect1,x
nextByte ; effect val
sta nextEffect1+1,x
txa ; add 16 to offset
adc #$10
tax
bvc readEffectLoop
readLength:
pla
tax
nextByte
sta nextRow,x
endOfPat:
rts

View file

@ -10,10 +10,12 @@
; - short pointers only ; - short pointers only
; - little-endian only! ; - little-endian only!
.include "6502base.i"
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; constants ; constants
FCS_MAX_CHANS=8 ; maximum number of channels (up to 127, but see below!) 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) FCS_MAX_STACK=16 ; stack depth per channel (FCS_MAX_STACK*FCS_MAX_CHAN<256)
; player constants - change if necessary ; player constants - change if necessary
@ -55,8 +57,8 @@ chanVibratoPos=fcsAddrBase+24+(FCS_MAX_CHAN*4) ; char
; may be used for driver detection ; may be used for driver detection
fcsDriverInfo: fcsDriverInfo:
.byte "Furnace" .db "Furnace"
.byte 0 .db 0
; note on null ; note on null
fcsNoteOnNull: fcsNoteOnNull:
@ -80,6 +82,9 @@ fcsOneByteDispatch:
jsr fcsDispatchCmd jsr fcsDispatchCmd
rts rts
fcsNoOp:
rts
; x: channel*2 ; x: channel*2
; y: command ; y: command
fcsDispatchCmd: fcsDispatchCmd:
@ -91,24 +96,33 @@ fcsDispatchCmd:
; check for zero ; check for zero
lda fcsTempPtr lda fcsTempPtr
ora fcsTempPtr ora fcsTempPtr
beq :+ ; get out beq + ; get out
; handle command in dispatch code ; handle command in dispatch code
jmp (fcsTempPtr) jmp (fcsTempPtr)
; only if pointer is zero ; only if pointer is zero
: rts + rts
; x: channel*2 ; x: channel*2
; a is set to next byte ; a is set to next byte
fcsReadNext: fcsReadNext:
; a=chanPC[x]+fcsPtr
clc
lda chanPC,x
adc #>fcsPtr
sta fcsTempPtr
lda chanPC+1,x lda chanPC+1,x
adc #<fcsPtr
sta fcsTempPtr+1 sta fcsTempPtr+1
ldy chanPC,x ; increase PC
lda (fcsTempPtr),y inc chanPC,x
iny bne +
bne :+
inc chanPC+1,x inc chanPC+1,x
: sty chanPC,x
; read byte and put it into a
; this is at the end to ensure flags are set properly
+ ldy #0
lda (fcsTempPtr),y
rts rts
; x: channel*2 (for speed... char variables are interleaved) ; x: channel*2 (for speed... char variables are interleaved)
@ -120,8 +134,8 @@ fcsChannelCmd:
; process and read arguments ; process and read arguments
; if (a<0xb3) ; if (a<0xb3)
bmi fcsNote ; handle $00-$7f bmi fcsNote ; handle $00-$7f
cmp #$b3 cmp #$b4
bpl fcsOther bpl fcsCheckOther
; this is a note ; this is a note
fcsNote: fcsNote:
@ -134,15 +148,29 @@ fcsChannelCmd:
jsr fcsDispatchCmd jsr fcsDispatchCmd
rts rts
; check other instructions
fcsCheckOther:
; check for preset delays
cmp #$f0
bmi fcsOther
; handler for preset delays
fcsPresetDelay:
; load preset delay and store it
tay
lda fcsPtr+8-240,y
sta chanTicks,x
lda #0
sta chanTicks+1,x
rts
; other instructions ; other instructions
fcsOther: fcsOther:
; call respective handler ; call respective handler
sec
sbc #$b4
tay tay
lda fcsInsTableLow,y lda fcsInsTableLow-180,y
sta fcsTempPtr sta fcsTempPtr
lda fcsInsTableHigh,y lda fcsInsTableHigh-180,y
sta fcsTempPtr+1 sta fcsTempPtr+1
jmp (fcsTempPtr) jmp (fcsTempPtr)
@ -170,15 +198,15 @@ fcsDoChannel:
; check whether this channel is halted (PC = 0) ; check whether this channel is halted (PC = 0)
lda chanPC,x lda chanPC,x
ora chanPC+1,x ora chanPC+1,x
beq :+ beq +
rts rts
; channel not halted... begin processing ; channel not halted... begin processing
; chanTicks-- ; chanTicks--
: lda chanTicks,x + lda chanTicks,x
sec sec
sbc #1 sbc #1
sta chanTicks,x sta chanTicks,x
bne :+ ; skip if our counter isn't zero bne + ; skip if our counter isn't zero
; ticks lower is zero; check upper byte ; ticks lower is zero; check upper byte
ldy chanTicks+1,x ldy chanTicks+1,x
@ -194,51 +222,49 @@ fcsDoChannel:
fcsDoChannelLoop: fcsDoChannelLoop:
lda chanTicks,x lda chanTicks,x
ora chanTicks+1,x ora chanTicks+1,x
bne :+ ; get out if chanTicks is no longer zero bne + ; get out if chanTicks is no longer zero
jsr fcsChannelCmd ; read next command jsr fcsChannelCmd ; read next command
jmp fcsDoChannelLoop jmp fcsDoChannelLoop
: jsr fcsChannelPost + jsr fcsChannelPost
; end ; end
rts rts
fcsTick: fcsTick:
; update channel state ; update channel state
; for (x=0; x<FCS_MAX_CHANS; x++) ; for (x=0; x<FCS_MAX_CHAN; x++)
ldx #0 ldx #0
: jsr fcsDoChannel - jsr fcsDoChannel
inx inx
inx inx
cpx #FCS_MAX_CHANS*2 cpx #FCS_MAX_CHAN*2
bne :- bne -
; increase tick counter ; increase tick counter
inc fcsTicks inc fcsTicks
bne :+ bne +
inc fcsTicks+1 inc fcsTicks+1
; end ; end
: rts + rts
fcsInit: fcsInit:
; set all tick counters to 1 ; set all tick counters to 1
lda #1 lda #1
ldy #0 ldy #0
ldx #(FCS_MAX_CHANS*2) ldx #(FCS_MAX_CHAN*2)
: dex - dex
sty chanTicks,x sty chanTicks,x
dex dex
sta chanTicks,x sta chanTicks,x
bne :- bne -
; set channel program counters ; set channel program counters
ldx #(FCS_MAX_CHANS*2) ldx #(FCS_MAX_CHAN*2)
: dex - dex
lda fcsPtr+40,x lda fcsPtr+40,x
sta chanPC,x sta chanPC,x
bne :- bne -
; TODO: relocate and more...
; success ; success
lda #0 lda #0
@ -246,10 +272,10 @@ fcsInit:
; floor(127*sin((x/64)*(2*pi))) ; floor(127*sin((x/64)*(2*pi)))
fcsVibTable: fcsVibTable:
.byte 0, 12, 24, 36, 48, 59, 70, 80, 89, 98, 105, 112, 117, 121, 124, 126 .db 0, 12, 24, 36, 48, 59, 70, 80, 89, 98, 105, 112, 117, 121, 124, 126
.byte 127, 126, 124, 121, 117, 112, 105, 98, 89, 80, 70, 59, 48, 36, 24, 12 .db 127, 126, 124, 121, 117, 112, 105, 98, 89, 80, 70, 59, 48, 36, 24, 12
.byte 0, -12, -24, -36, -48, -59, -70, -80, -89, -98, -105, -112, -117, -121, -124, -126 .db 0, -12, -24, -36, -48, -59, -70, -80, -89, -98, -105, -112, -117, -121, -124, -126
.byte -126, -126, -124, -121, -117, -112, -105, -98, -89, -80, -70, -59, -48, -36, -24, -12 .db -126, -126, -124, -121, -117, -112, -105, -98, -89, -80, -70, -59, -48, -36, -24, -12
; "dummy" implementation - example only! ; "dummy" implementation - example only!
@ -257,15 +283,15 @@ fcsDummyFunc:
rts rts
fcsVolMaxExample: fcsVolMaxExample:
.byte 127, 127, 127, 127, 127, 127, 127, 127 .db 127, 127, 127, 127, 127, 127, 127, 127
; first 64 commands ; first 64 commands
fcsCmdTableExample: fcsCmdTableExample:
.word 0, 0, 0, 0, 0, 0, 0, 0 .db 0, 0, 0, 0, 0, 0, 0, 0
.word 0, 0, 0, 0, 0, 0, 0, 0 .db 0, 0, 0, 0, 0, 0, 0, 0
.word 0, 0, 0, 0, 0, 0, 0, 0 .db 0, 0, 0, 0, 0, 0, 0, 0
.word 0, 0, 0, 0, 0, 0, 0, 0 .db 0, 0, 0, 0, 0, 0, 0, 0
.word 0, 0, 0, 0, 0, 0, 0, 0 .db 0, 0, 0, 0, 0, 0, 0, 0
.word 0, 0, 0, 0, 0, 0, 0, 0 .db 0, 0, 0, 0, 0, 0, 0, 0
.word 0, 0, 0, 0, 0, 0, 0, 0 .db 0, 0, 0, 0, 0, 0, 0, 0
.word 0, 0, 0, 0, 0, 0, 0, 0 .db 0, 0, 0, 0, 0, 0, 0, 0