160 lines
6.0 KiB
Python
160 lines
6.0 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 iff 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
|
|
bne(pc()+3) #41
|
|
bra(pc()+3) #42
|
|
ld(0xfc); C('Unsafe')#43 Clear low channelMask bits so it becomes safe
|
|
ld(0xff); C('Safe')#43(!) No change to channelMask because already safe
|
|
anda([channelMask]) #44
|
|
st([channelMask]) #45
|
|
ld([sysArgs+4]) #46
|
|
bne('.sysPi#49') #47
|
|
# Execute code (don't care about checksum anymore)
|
|
ld([sysArgs+5]); C('Execute')#48 Low run address
|
|
st([vLR]) #49 https://forum.gigatron.io/viewtopic.php?p=29#p29
|
|
suba(2) #50
|
|
st([vPC]) #51
|
|
ld([sysArgs+6]) #52 High run address
|
|
st([vPC+1]) #53
|
|
st([vLR+1]) #54
|
|
ld(hi('REENTER'),Y) #55
|
|
jmp(Y,'REENTER') #56
|
|
ld(-60/2) #57
|
|
# 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#49')
|
|
ld([sysArgs+0]); C('Loading data')#49 Continue checksum
|
|
suba(1,X) #50 Point at last byte
|
|
ld([Y,X]) #51
|
|
st([sysArgs+2]) #52
|
|
ld(hi('REENTER'),Y) #53
|
|
jmp(Y,'REENTER') #54
|
|
ld(-58/2) #55
|
|
|
|
#-----------------------------------------------------------------------
|
|
# 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
|
|
|
|
#-----------------------------------------------------------------------
|
|
#
|
|
#-----------------------------------------------------------------------
|
|
|