10
20
30
40
50 :
60 OSARGS=&FFDA
70 DIM mcode% &200:load%=&FFFF0900:ver$="v1.10"
80 :
90 addr=&A8:lptr=&AC:tmp=&AE:off=&AF:tube=&27A
100 FOR P=0 TO 1
110 P%=load%:O%=mcode%
120 [OPT P*3+4
130 .errSyntax
140 BRK:EQUB 220:EQUS "Syntax: GO [(<addr>)]":BRK
150 :
160 .go%
170 LDA #1:LDY #0:LDX #lptr:JSR OSARGS
180 LDA (lptr),Y:CMP #13:BEQ errSyntax
190 STA off:INY
200 CMP #ASC"(":BEQ ScanHex :\ *GO (addr)
210 CMP #ASC"[":BEQ ScanHex :\ *GO [addr]
220 DEY:STY off :\ *GO addr
230 :
240 .ScanHex
250 LDX #addr:LDA #0 :\ Prepare to scan hex
260 STA 0,X:STA 1,X :\ Clear hex accumulator
270 STA 2,X:STA 3,X
280 .GetHexNext
290 LDA (lptr),Y
300 CMP #ASC"!":BCC GetHexDone :\ End of hex number
310 CMP #ASC")":BEQ GetHexDone
320 CMP #ASC"]":BEQ GetHexDone
330 CMP #ASC"0":BCC errSyntax :\ Bad digit
340 CMP #ASC"9"+1:BCC GetHexDigit :\ Decimal digit
350 SBC #7:BCC errSyntax :\ Bad digit
360 CMP #ASC"@":BCS errSyntax :\ Bad digit
370 .GetHexDigit
380 ASL A:ASL A:ASL A:ASL A :\ Move digit to top nybble
390 STY tmp:LDY #4 :\ Four bits to move
400 .GetHexMultiply
410 ASL A :\ Rotate current digit into
420 ROL 0,X:ROL 1,X :\ accumulated hex number
430 ROL 2,X:ROL 3,X
440 DEY:BNE GetHexMultiply :\ Loop to move in four bits
450 LDY tmp:INY:BNE GetHexNext :\ Loop to read next digit
460 .GetHexDone
470 :
480 LDA tube:BPL EnterIO :\ No Tube, enter I/O memory
490 LDX addr+3:INX:BEQ EnterIO :\ &FFxxxxxx, enter I/O memory
500 .TubeClaim
510 LDA #&C0+&10:JSR &406 :\ Claim Tube
520 BCC TubeClaim
530 LDA off:BEQ TubeEnter :\ *GO addr
540 ASL A:PHA :\ b7=0 (addr), b7=1 [addr]
550 LDA #0:JSR TubeStart:LDY #0 :\ Read bytes from CoPro
560 .TubeGetWord
570 LDX #9
580 .TubeWait:DEX:BNE TubeWait :\ Delay between each byte
590 LDA addr+0,Y:STA addr+4,Y
600 LDA &FEE5:STA addr+0,Y
610 INY:CPY #4:BNE TubeGetWord :\ Fetch four bytes
620 TAX:PLA:BPL TubeEnter :\ *GO (addr)
630 TXA:PHA:LDY #&FC:CLC :\ X=&00 if offset, X<>&00 if direct
640 .TubeOffset
650 LDX addr+8,Y
660 PLA:PHA:BNE TubeAddr :\ addr?3<>0, jump to addr
670 TXA:ADC addr+4,Y:TAX :\ addr?3=0, jump to addr+!addr
680 .TubeAddr
690 STX addr+4,Y
700 INY:BNE TubeOffset:PLA
710 .TubeEnter
720 LDA #4 :\ Execute code and release Tube
730 .TubeStart
740 LDX #addr:LDY #0:JMP &406
750 :
760 .EnterIO
770 LDA off:BEQ EnterIOgo:ASL off :\ b7=0 (addr), b7=1 [addr]
780 LDY #1:LDA (addr),Y:TAX
790 DEY:LDA (addr),Y:CLC
800 BIT off:BPL IOAddr :\ (addr), store new address
810 ADC addr+0:PHA:TXA :\ [addr], add to address
820 ADC addr+1:TAX:PLA
830 .IOAddr
840 STA addr+0:STX addr+1
850 .EnterIOgo
860 LDA #1:JMP (addr) :\ Enter code in I/O memory
870 :
880 EQUS ver$
890 ]:NEXT
900 PRINT"*SAVE GO "+STR$~mcode%+" "+STR$~O%+" "+STR$~(go%OR&FFFF0000)+" "+STR$~(load%OR&FFFF0000)