10 REM > TUBE/src v1.10
   20 REM Source for *TUBE (ON|OFF|<num>) by J.G.Harston
   30 REM v1.00 28-Jun-1992 Initial version
   40 REM v1.10 12-Jun-2016 added <num> parameter
   50 :
   60 OSARGS=&FFDA:OSBYTE=&FFF4
   70 DIM mcode% &200:load%=&FFFF0900:ver$="v1.10"
   80 :
   90 host=&A8:num=&A9:lptr=&AA:tube=&27A:lang=&28C
  100 FOR P=0 TO 1
  110   P%=load%:O%=mcode%
  120   [OPT P*3+4
  130   .go%
  140   LDA #0:LDX #1:JSR OSBYTE     :\ Find MOS
  150   STX host:TXA:BNE TubeNotElectron
  160   LDA #&FC
  170   STA TUBEIO0+2:STA TUBEIO2+2  :\ Adjust address of Tube registers
  180   STA TUBEIO3+2:STA TUBEIO6+2
  190   .TubeNotElectron
  200   LDA #1:LDX #lptr:JSR OSARGS        :\ Get command line, Y=0 from above
  210   LDA (lptr),Y:CMP #13:BEQ TubeExit  :\ No parameters, just exit
  220   LDX host                           :\ Prepare X=host for later
  230   AND #&DF:CMP #ASC"@":BCC TubeNum   :\ *TUBE <num>
  240   :
  250   CMP #ASC"O":BNE TubeExit     :\ Not *TUBE O
  260   INY:LDA (lptr),Y:DEY:AND #&DF
  270   LDY tube                     :\ Get Y=Tube enabled for later
  280   CMP #ASC"N":BEQ TubeOn       :\ *TUBE ON
  290   CMP #ASC"F":BEQ TubeOff      :\ *TUBE OFF
  300   BNE TubeExit                 :\ Not ON or OFF, just exit
  310   :
  320   .TubeNum
  330   JSR ScanDecimal:TAY          :\ Y=CPU to select
  340   PHP:CPX #3:BCC TubeBBCElk    :\ Not Master, only a single Tube port
  350   SEI:LDA &FE34                :\ Disable IRQs, get current Tube
  360   EOR #&10:STA &FE34:STY &FEE6 :\ Swap Tube, select Tube CPU
  370   EOR #&10:STA &FE34           :\ Swap Tube back
  380   .TubeBBCElk
  390   .TUBEIO6
  400   STY &FEE6:PLP                :\ Select Tube CPU, restore IRQs
  410   .TubeExit
  420   RTS
  430   :
  440   .TubeOff
  450   TYA:BPL TubeExit             :\ Tube already disabled
  460   LDA lang
  470   CMP #&FF:BEQ errNoLang:PHA   :\ Check current language ROM
  480   LDA #0:STA tube              :\ Clear Tube presence flag
  490   LDA &FFB7:STA lptr+0         :\ Point to default vectors
  500   LDA &FFB8:STA lptr+1
  510   LDY #&20
  520   .TubeOffEvent
  530   LDA (lptr),Y:STA &200,Y      :\ Reset EVENTV
  540   INY:CPY #&22:BNE TubeOffEvent
  550   JSR ServiceInit              :\ Initialise ROMs
  560   JSR ReselectFS               :\ Reselect current filing system
  570   PLA:TAX                      :\ Get current language ROM back
  580   LDA #142:JMP OSBYTE          :\ Re-enter current language
  590   :
  600   .TubeOn
  610   TYA:BMI TubeExit             :\ Tube already enabled
  620   .TUBEIO0
  630   LDA &FEE0:BMI errNoTube      :\ No Tube hardware present
  640   LDA #&FF:STA tube            :\ Set Tube enabled flag
  650   JSR ServiceInit              :\ Initialise ROMs
  660   LDY #0:LDX #&FF:JSR Service  :\ Tube Pre-Init
  670   LDX #&FE:JSR Service         :\ Tube Post-Init
  680   .TubeOnWait
  690   .TUBEIO2
  700   BIT &FEE2:BVC TubeOnWait     :\ Wait for Reply Port ready
  710   LDA #&7F                     :\ Ack OSCLI from Tube
  720   .TUBEIO3
  730   STA &FEE3
  740   JMP &32                      :\ Jump to Tube poll loop
  750   :
  760   .errNoLang
  770   BRK:EQUB 249:EQUS "No language in host"
  780   .errNoTube
  790   BRK:EQUB 144:EQUS "No Tube present":BRK
  800   :
  810   .ReselectFS
  820   LDA #0:TAY:JSR OSARGS   :\ Get current filing system
  830   TAY:LDX #18:BNE Service :\ Reselect filing system
  840   .ServiceInit
  850   LDX #&37
  860   .Service
  870   LDA #143:JMP OSBYTE     :\ Issue service call
  880   :
  890   .ScanDecimal
  900   JSR CheckDigit:BCC errBadNumber
  910   .ScanDecimalLp
  920   STA num
  930   JSR CheckDigit:BCC ScanDecimalDone
  940   PHA:LDA num
  950   CMP #26:BCS errBadNumber  :\ num*10>=260
  960   ASL A:ASL A:ADC num:ASL A :\ num=num*10
  970   STA num:PLA
  980   ADC num:BCC ScanDecimalLp :\ num=num*10+digit
  990   .errBadNumber
 1000   BRK:EQUB 252:EQUS "Bad number":BRK
 1010   .ScanDecimalDone
 1020   LDA num:RTS
 1030   :
 1040   .CheckDigit
 1050   LDA (lptr),Y
 1060   CMP #ASC"9"+1:BCS ChkDigitBad :\ >'9'
 1070   CMP #ASC"0":BCC ChkDigitBad   :\ <'0'
 1080   INY:AND #15:RTS
 1090   .ChkDigitBad
 1100   CLC:RTS
 1110   :
 1120   EQUS ver$
 1130 ]:NEXT
 1140 PRINT"*SAVE TUBE "+STR$~mcode%+" "+STR$~O%+" "+STR$~(go%OR&FFFF0000)+" "+STR$~(load%OR&FFFF0000)