10 REM > GO/src v1.10
   20 REM Source for *GO by J.G.Harston
   30 REM v1.00 28-Jun-1992
   40 REM v1.10 12-Feb-2017 Allows (addr) and [addr]
   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)