Code: Select all
STA AYBase
Code: Select all
STA AYBase+1
Code: Select all
STA AYBase
Code: Select all
STA AYBase+1
Code: Select all
commands
sty tempy
; adjust the command pointer to get command table offset
and #%01111111 ; mask off top bit
rol ; bit shift = multiply by 2 (addresses are 2 bytes in size)
; get command address from command pointer table (self modifying code)
tay
lda (commandtable),y
sta ijmp+1
lda (commandtable),y
sta ijmp+2
ijmp jmp commandtable ; self modifying code, playsong end replaced with current command address
Yup.Twilighte wrote:JamesD, you wrote..
Code: Select all
commands sty tempy ; adjust the command pointer to get command table offset and #%01111111 ; mask off top bit rol ; bit shift = multiply by 2 (addresses are 2 bytes in size) ; get command address from command pointer table (self modifying code) tay lda (commandtable),y sta ijmp+1 lda (commandtable),y sta ijmp+2 ijmp jmp commandtable ; self modifying code, playsong end replaced with current command address
I think you meant to put an INY between the two lda(commandtable),y?
Code: Select all
docomnd
; beq playsongend
sty temp ; save Y
; self modifying code
; register A contains the command number + 128
; adjust the command pointer to get command table offset
; and #%01111111 ; mask off top bit. Not required due to ROL
clc ; CLC for the ROL
; ROL moves top bit to carry and previous carry goes to bottom bit
rol ; bit shift = multiply by 2 (addresses are 2 bytes in size)
; get command address from command pointer table (self modifying code)
tay ; move the command table offset to Y
lda (cmds),y ; load the 1st byte of the command pointer into A
sta ijmp+1 ; modify the 1st byte of the address in the jmp
iny ; adjust offset for next byte
lda (cmds),y ; load the 2nd byte of the command pointer into A
sta ijmp+2 ; modify the 2nd byte of the address in the jmp
ldy temp ; restore Y
ijmp jmp playsongend ; playsong end replaced with current command address
commandtable
.word playsongend ; 00 end of song
; additional command pointers go here
Code: Select all
;**************************************************************
;* our interrupt handler
;**************************************************************
_VBLIrq
; save registers
pha
bit VIA_T1C
; wait for interrupt, _WaitCount times
lda _WaitCount
dec ; decrement the counter
sta _WaitCount
bne exit_int
#ifdef USE_C02
phx ;65c02
phy ;65c02
#else
txa
pha
tya
pha
#endif
ldy #1 ; offset from song pointer, Y must be used for this addressing mode
lda (song),y ; get number of registers to modify
; bmi docomnd ; negative numbers are commands
beq playsongend ; check for end of song
tax ; put it in X
iny ; next byte in song
_reglop
lda (song),y ; get the register number to modify
;6502 ORIC AY Control using the VIA 6522 makes this slower than memory mapped AY chip
#ifdef ORICAY
sta VIAIORA ; set the AY data register number
lda #$FF ; $FF = VIAIORA holds a register number
sta VIA_PCR ; Set the VIA 6522 control line Register(PCR)
lda #$DD ; $DD = VIAIORA is inactive
sta VIA_PCR ; Set the VIA 6522 control line Register(PCR)
#else
sta AYBase+1 ; set the AY data register number
#endif
iny ; point to next byte in song
lda (song),y ; get the Value for the AY register
#ifdef ORICAY
sta VIAIORA ; load the data register value
lda #$FD ; $FD = VIAIORA holds data for a preset register
sta VIA_PCR ; Set the VIA 6522 control line Register(PCR)
lda #$DD ; $DD = VIAIORA is inactive
sta VIA_PCR ; Set the VIA 6522 control line Register(PCR)
#else
sta AYBase ; load the data register value
#endif
iny ; point to next byte in song
dex ; decrement the register count
bne _reglop ; keep looping if not done setting registers
; iny ; point to next byte in song
lda (song),y ; get the new wait counter
sta _WaitCount ; save it
; update the pointer (16 bit song pointer + 8 bit index)
; (songLSB + y, songMSB + carry)
; clc ; clear the carry for out 16 bit addition
tya ; put pointer offset in A
adc song ; add low byte (LSB)
sta song ; update low byte
lda #0 ; clear A
adc song+1 ; add carry to high byte (MSB)
sta song+1 ; update the song pointer
; restore registers we saved
#ifdef USE_C02
ply ; 65c02
plx ; 65c02
#else
pla
tay
pla
tax
#endif
exit_int
pla
rti
;======================
docomnd
; beq playsongend
sty temp ; save Y
; self modifying code
; register A contains the command number + 128
; adjust the command pointer to get command table offset
; and #%01111111 ; mask off top bit. Not required due to ROL
clc ; CLC for the ROL
; ROL moves top bit to carry and previous carry goes to bottom bit
rol ; bit shift = multiply by 2 (addresses are 2 bytes in size)
; get command address from command pointer table (self modifying code)
tay ; move the command table offset to Y
lda (cmds),y ; load the 1st byte of the command pointer into A
sta ijmp+1 ; modify the 1st byte of the address in the jmp
iny ; adjust offset for next byte
lda (cmds),y ; load the 2nd byte of the command pointer into A
sta ijmp+2 ; modify the 2nd byte of the address in the jmp
ldy temp ; restore Y
ijmp jmp playsongend ; playsong end replaced with current command address
;===============================
commandtable
.word playsongend ; 0 end of song
.word playsongend ; other commands would go here
;
Code: Select all
extern unsigned char MyAssemblerByte;
void MyAssemblerFunction();
void main()
{
MyAssemblerByte=23:
MyAssemblerFunction();
}
Code: Select all
_MyAssemblerByte dc.b 0
_ MyAssemblerFunction
rts
Code: Select all
ldy #0
lda (sp),y
sta ...
iny
lda (sp),y
sta ...