162 lines
6.1 KiB
Python
162 lines
6.1 KiB
Python
|
|
#-----------------------------------------------------------------------
|
|
#
|
|
# Loader-specific SYS extensions
|
|
#
|
|
#-----------------------------------------------------------------------
|
|
|
|
from asm import *
|
|
|
|
# Peek into the ROM's symbol table
|
|
videoY = symbol('videoY')
|
|
sysArgs = symbol('sysArgs0')
|
|
vPC = symbol('vPC')
|
|
vLR = symbol('vLR')
|
|
vTmp = symbol('vTmp')
|
|
channelMask = symbol('channelMask_v4')
|
|
|
|
#-----------------------------------------------------------------------
|
|
# Extension SYS_LoaderNextByteIn_32
|
|
#-----------------------------------------------------------------------
|
|
|
|
# sysArgs[0:1] Current address
|
|
# sysArgs[2] Checksum
|
|
# sysArgs[3] Wait value (videoY)
|
|
|
|
label('SYS_LoaderNextByteIn_32')
|
|
ld([videoY]) #15
|
|
xora([sysArgs+3]) #16
|
|
bne('.sysNbi#19') #17
|
|
ld([sysArgs+0],X) #18
|
|
ld([sysArgs+1],Y) #19
|
|
ld(IN) #20
|
|
st([Y,X]) #21
|
|
adda([sysArgs+2]) #22
|
|
st([sysArgs+2]) #23
|
|
ld([sysArgs+0]) #24
|
|
adda(1) #25
|
|
st([sysArgs+0]) #26
|
|
ld(hi('REENTER'),Y) #27
|
|
jmp(Y,'REENTER') #28
|
|
ld(-32/2) #29
|
|
# Restart the instruction in the next timeslice
|
|
label('.sysNbi#19')
|
|
ld([vPC]) #19
|
|
suba(2) #20
|
|
st([vPC]) #21
|
|
ld(hi('NEXTY'),Y) #22
|
|
jmp(Y,'NEXTY') #23
|
|
ld(-26/2) #24
|
|
|
|
#-----------------------------------------------------------------------
|
|
# Extension SYS_LoaderProcessInput_64
|
|
#-----------------------------------------------------------------------
|
|
|
|
# sysArgs[0:1] Source address
|
|
# sysArgs[2] Checksum
|
|
# sysArgs[4] Copy count
|
|
# sysArgs[5:6] Destination address
|
|
|
|
label('SYS_LoaderProcessInput_64')
|
|
ld([sysArgs+1],Y) #15
|
|
ld([sysArgs+2]) #16
|
|
bne('.sysPi#19') #17
|
|
ld([sysArgs+0]) #18
|
|
suba(65,X) #19 Point at first byte of buffer
|
|
ld([Y,X]) #20 Command byte
|
|
st([Y,Xpp]); C('Just X++')#21
|
|
xora(ord('L')) #22 This loader lumps everything under 'L'
|
|
bne('.sysPi#25') #23
|
|
ld([Y,X]); C('Valid command')#24 Length byte
|
|
st([Y,Xpp]); C('Just X++')#25
|
|
anda(63) #26 Bit 6:7 are garbage
|
|
st([sysArgs+4]) #27 Copy count 0..60
|
|
adda([Y,X]) #28 One location past (+1) the last byte of fragment
|
|
adda(1) #29 254+1 = $ff becomes 0, 255+1 = $00 becomes 1
|
|
anda(0xfe) #30 Will be zero only when writing in top 2 bytes of page
|
|
st([vTmp]) #31 Remember as first condition
|
|
ld([Y,X]) #32 Low copy address
|
|
st([Y,Xpp]); C('Just X++')#33
|
|
st([sysArgs+5]) #34
|
|
ld([Y,X]) #35 High copy address
|
|
st([Y,Xpp]); C('Just X++')#36
|
|
st([sysArgs+6]) #37
|
|
suba(1) #38 Check if writing into sound channel page (1..4)
|
|
anda(0xfc) #39
|
|
ora([vTmp]) #40 Combine second condition with first
|
|
st([vTmp]) #41 Zero when overwriting one of oscL[1..4] or oscH[1..4]
|
|
ld([sysArgs+4]) #42 Check copy count
|
|
bne('.sysPi#45') #43
|
|
# Execute code (don't care about checksum anymore)
|
|
ld([sysArgs+5]); C('Execute')#44 Low run address
|
|
st([vLR]) #45 https://forum.gigatron.io/viewtopic.php?p=29#p29
|
|
suba(2) #46
|
|
st([vPC]) #47
|
|
ld([sysArgs+6]) #48 High run address
|
|
st([vPC+1]) #49
|
|
st([vLR+1]) #50
|
|
ld(hi('REENTER'),Y) #51
|
|
jmp(Y,'REENTER') #52
|
|
ld(-56/2) #53
|
|
# Invalid checksum
|
|
label('.sysPi#19')
|
|
wait(25-19); C('Invalid checksum')#19 Reset checksum
|
|
# Unknown command
|
|
label('.sysPi#25')
|
|
ld(ord('g')); C('Unknown command')#25 Reset checksum
|
|
st([sysArgs+2]) #26
|
|
ld(hi('REENTER'),Y) #27
|
|
jmp(Y,'REENTER') #28
|
|
ld(-32/2) #29
|
|
# Loading data
|
|
label('.sysPi#45')
|
|
ld([vTmp]); C('Loading data')#45
|
|
bne(pc()+3) #46
|
|
bra(pc()+3) #47
|
|
ld(0xfc); C('Unsafe')#48 Clear low channelMask bits so it becomes safe
|
|
ld(0xff); C('Safe')#48(!) No change to channelMask because already safe
|
|
anda([channelMask]) #49
|
|
st([channelMask]) #50
|
|
ld([sysArgs+0]) #51 Continue checksum
|
|
suba(1,X) #52 Point at last byte
|
|
ld([Y,X]) #53
|
|
st([sysArgs+2]) #54
|
|
ld(hi('REENTER'),Y) #55
|
|
jmp(Y,'REENTER') #56
|
|
ld(-60/2) #57
|
|
|
|
#-----------------------------------------------------------------------
|
|
# Extension SYS_LoaderPayloadCopy_34
|
|
#-----------------------------------------------------------------------
|
|
|
|
# sysArgs[0:1] Source address
|
|
# sysArgs[4] Copy count
|
|
# sysArgs[5:6] Destination address
|
|
|
|
label('SYS_LoaderPayloadCopy_34')
|
|
ld([sysArgs+4]) #15 Copy count
|
|
beq('.sysCc#18') #16
|
|
suba(1) #17
|
|
st([sysArgs+4]) #18
|
|
ld([sysArgs+0],X) #19 Current pointer
|
|
ld([sysArgs+1],Y) #20
|
|
ld([Y,X]) #21
|
|
ld([sysArgs+5],X) #22 Target pointer
|
|
ld([sysArgs+6],Y) #23
|
|
st([Y,X]) #24
|
|
ld([sysArgs+5]) #25 Increment target
|
|
adda(1) #26
|
|
st([sysArgs+5]) #27
|
|
bra('.sysCc#30') #28
|
|
label('.sysCc#18')
|
|
ld(hi('REENTER'),Y) #18,29
|
|
wait(30-19) #19
|
|
label('.sysCc#30')
|
|
jmp(Y,'REENTER') #30
|
|
ld(-34/2) #31
|
|
|
|
#-----------------------------------------------------------------------
|
|
#
|
|
#-----------------------------------------------------------------------
|
|
|