gigatron/rom/Apps/Loader/SYS_Loader_v4.py
2025-01-28 19:17:01 +03:00

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
#-----------------------------------------------------------------------
#
#-----------------------------------------------------------------------