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