10 REM > REMOTE/S
   20 REM Source for SJ Research REMOTE command
   30 REM This version assumes it was run from NFS and NFS is the current filing
   40 REM system as it directly access vaious bits of NFS workspace.
   50 :
   60 OS_CLI=&FFF7:OSBYTE=&FFF4:OSWORD=&FFF1:OSWRCH=&FFEE
   70 OSWRCR=&FFEC:OSNEWL=&FFE7:OSASCI=&FFE3:OSRDCH=&FFE0
   80 :
   90 load%=&FFFF0E10:REM Load in low NFS workspace
  100 :
  110 DIM mcode% &200
  120 FOR P=0 TO 1
  130   P%=load%:O%=mcode%
  140   [OPT P*3+4
  150   .exec%
  160   LDX #&07:LDY #&FF:JSR L0FCA  :\ Scan command line, X=offset for FSOp lookup later
  170   BCC L0E51                    :\ Jump if station number given
  180   .L0E19
  190   LDA (&BE),Y:INY:BCS L0E22    :\ Get character from command line
  200   :                            :\ Skip past NFS workspace
  210   EQUD &00000F2A
  220   :
  230   .L0E22
  240   STA L0FA2,X:INX              :\ Store user name in FSOp workspace
  250   EOR #&0D:BNE L0E19           :\ Loop until CR found
  260   STA L0FA2                    :\ Store &00 to do Net_FSOp
  270   LDA #&18:STA L0FA2+3         :\ NetFS_Op=&18 - User Lookup
  280   STX L0FA2+1                  :\ Length=offset to end of username
  290   LDX #L0FA2 AND 255           :\ Point to control block
  300   LDY #L0FA2 DIV 256
  310   LDA #&14:JSR OSWORD          :\ Call Net_FSOp
  320   LDA L0FA2+3:BEQ L0E4B        :\ Ok, use returned data
  330   LDA #&00:STA L0FA2+17        :\ Put terminating zero on error message
  340   JMP L0FA2+2                  :\ Jump to generate error
  350   :
  360   \ TxRx block in NFS private workspace pointed to by &BE/F
  370   \ 0C=ctrl, b7=remote request arrived
  380   \ 0D=port        &93
  390   \ 0E=dest stn
  400   \ 0F=dest net
  410   \ 10=start       FFFFwsD9
  420   \ 14=end         FFFFwsE9
  430   \ 18=param
  440   :
  450   .L0E4B
  460   LDA L0FA2+5:LDX L0FA2+6      :\ X=net, A=stn
  470   :
  480   \ Manually construct a Rx control block
  490   .L0E51
  500   LDY #&0E:STA (&9E),Y         :\ Store stn in NFS workspace
  510   INY:TXA:STA (&9E),Y          :\ Store net in NFS workspace
  520   JSR L0F5B                    :\ Copy RxCB to NFS workspace
  530   JSR L0F3B                    :\ Initialise TxCB
  540   LDX #&01:STX L0FC1           :\ Set OSPROC=1 for 'Start REMOTE'
  550   .L0E64
  560   LDA &0220,X:STA &C4,X        :\ Save EVENTV in filing system workspace
  570   LDA L0F0D,X:STA &0220,X      :\ Claim EVENTV
  580   DEX:BPL L0E64                :\ Loop to set both bytes
  590   :
  600   .L0E72
  610   LDY #L0FB5 DIV 256           :\ Point to OSPROC TxCB
  620   LDX #L0FB5 AND 255:JSR L0F78 :\ Transmit OSPROC
  630   STA &0E0D                    :\ Clear event type
  640   ASL L0FFC:BCC L0E8D          :\ Skip if events already enabled
  650   LDX #&02:LDA #&0E:JSR OSBYTE :\ Enable BufIns events
  660   LDX #&06:JSR OSBYTE          :\ Enable Escape events
  670   :
  680   \ Main loop
  690   .L0E8D
  700   LDA #&0C:STA &A0
  710   LDA &9F:STA &A1:LDX #&00     :\ Point to byte &0C in NFS workspace
  720   LDA (&A0,X):BMI L0EAD        :\ Jump if remote request arrived
  730   LDA &0E0D:BEQ L0E8D          :\ No events, loop back
  740   CMP #&02:BEQ L0EA8           :\ BufIns, jump to send character
  750   LDA #&1B:STA &C0             :\ Escape, CHR$27 in output buffer
  760   .L0EA8
  770   JSR L0F3B:BNE L0E72          :\ Initialise TxCB, loop back to send
  780   :
  790   \ &D9=request type 00=WRCH  01=WORD  02=BYTE   03=BYTE  0A=FINISH
  800   \                                    no reply with reply
  810   \ &DA=parameters     char       A        A       A
  820   \ &DB                        control     X       X
  830   \ &DC                         block      Y       Y
  840   :
  850   .L0EAD
  860   LDY #&D9:LDA (&9E),Y         :\ Get byte &D9 from NFS workspace
  870   BEQ L0EFA                    :\ 00=OSWRCH request
  880   CMP #&0A:BEQ L0F0F           :\ 0A=REMOTE finish
  890   CMP #&01:BEQ L0EEE           :\ 01=OSWORD request
  900   :
  910   \ OSBYTE request
  920   PHA:INY                      :\ Point to received register values
  930   .L0EBD
  940   LDA (&9E),Y:PHA              :\ Stack received register values
  950   INY:CPY #&DD:BNE L0EBD
  960   PLA:TAY:PLA:TAX:PLA          :\ Pop values into registers
  970   JSR OSBYTE                   :\ Perform the requested OSBYTE
  980   PHP:PHA:TXA:PHA:TYA:PHA      :\ Stack register values to send back
  990   LDY #&DA                     :\ Point to register value to send
 1000   .L0ED5
 1010   PLA:STA (&9E),Y              :\ Unstack registers into transmit area
 1020   INY:CPY #&DE:BNE L0ED5
 1030   PLA:CMP #&02:BEQ L0EE9       :\ If call &02, don't reply
 1040   LDY &9F:LDX #&0C:JSR L0F78   :\ Transmit back from workspace
 1050   .L0EE9
 1060   JSR L0F5B:BNE L0E8D          :\ Re-open Rx block and loop back
 1070   :
 1080   \ OSWORD REQUEST
 1090   .L0EEE
 1100   INY:LDA (&9E),Y              :\ Get OSWORD number
 1110   LDX #&DB:LDY &9F             :\ Point to received control block
 1120   JSR OSWORD:BNE L0EE9         :\ Perform requested OSWORD and loop back
 1130   :
 1140   PRINT CHARACTER
 1150   .L0EFA
 1160   INY:LDA (&9E),Y              :\ Get received character
 1170   JSR OSWRCH:JMP L0EE9         :\ Perform requested OSWRCH and loop back
 1180   
 1190   BRK              :\ 0F03: 00          .
 1200   BRK              :\ 0F04: 00          .
 1210   BRK              :\ 0F05: 00          .
 1220   BRK              :\ 0F06: 00          .
 1230   BRK              :\ 0F07: 00          .
 1240   BRK              :\ 0F08: 00          .
 1250   EQUD &FFFF0E10
 1260   .L0F0D
 1270   EQUW &0F2A       :\ Event handler address
 1280   :
 1290   \ TERMINATE REMOTE
 1300   .L0F0F
 1310   LDA #&02:LDA #&0D:JSR OSBYTE :\ Disable BufIns events
 1320   LDX #&06:JSR OSBYTE          :\ Disable Escape events
 1330   LDX #&02
 1340   .L0F1D
 1350   LDA &C3,X:STA &021F,X        :\ Restore EVENTV
 1360   DEX:BNE L0F1D                :\ Loop for both bytes
 1370   LDA #&0F:JMP OSBYTE          :\ Clear buffers and exit
 1380   :
 1390   \ Event handler
 1400   .L0F2A
 1410   CMP #&02:BEQ L0F32           :\ Character entering buffer
 1420   CMP #&06:BNE L0F38           :\ Escape event
 1430   .L0F32
 1440   STA &0E0D:STY &C0:RTS        :\ Store event type and parameter
 1450   
 1460   .L0F38
 1470   JMP (&00C4)                  :\ Daisychain with unclaimed events
 1480   
 1490   .L0F3B
 1500   LDA #&91:LDX #&00:JSR OSBYTE :\ Get character from KBD buffer
 1510   LDX #&0D
 1520   .L0F44
 1530   LDA L0FE6,X:STA L0FB5,X      :\ Initialise TxCB
 1540   DEX:BPL L0F44
 1550   LDY #&0F:LDX #&01            :\ Point to net.stn in NFS workspace
 1560   .L0F51
 1570   LDA (&9E),Y:STA L0FB7,X      :\ Copy net.stn to TxCB
 1580   DEY:DEX:BPL L0F51:RTS        :\ Copy both bytes, return MI+NE
 1590   
 1600   .L0F5B                       :\ Set up RECEIVE block
 1610   LDY #&17                     :\ RxCB is at ws08 to ws17
 1620   LDX #&07                     :\ 8 bytes to copy
 1630   .L0F5F
 1640   LDA L0FF4,X                  :\ Get byte from RxCB
 1650   BNE L0F66:LDA &9F            :\ If &00 replace with ws address
 1660   .L0F66
 1670   STA (&9E),Y                  :\ Store in NFS workspace
 1680   DEY:DEX:BPL L0F5F            :\ Copy bytes
 1690   DEY
 1700   LDA #&93:DEY:STA (&9E),Y     :\ Set port=&93
 1710   LDA #&7F:DEY:STA (&9E),Y:RTS :\ Set flag=&7F
 1720   
 1730   .L0F78                       :\ TRANSMIT from XY
 1740   STX &C1:STY &C2              :\ Save control block address
 1750   .L0F7C                       :\ TRANSMIT from &C1/2
 1760   LDX &C1:LDY &C2              :\ Point to control block
 1770   LDA #&10:JSR OSWORD          :\ Call TRANSMIT
 1780   LDA #&7E                     :\ Prepare to Ack any Escapes
 1790   BIT &FF:BPL L0F97            :\ No Escape, poll Tx
 1800   JSR OSBYTE                   :\ Ack. Escape
 1810   BRK:EQUB 17:EQUS "Escape":BRK
 1820   .L0F97
 1830   LDA #&32:JSR OSBYTE          :\ Poll Tx
 1840   TXA:BMI L0F97                :\ Loop until Tx started
 1850   BNE L0F7C:RTS                :\ Retry until Tx sucessful
 1860   :
 1870   \ Scan for decimal number
 1880   \ This is later used as workspace for user name lookup
 1890   .L0FA2
 1900   TAX                          :\ Copy current net value to X
 1910   .L0FA3
 1920   LDA #&00                     :\ Clear current value
 1930   .L0FA5
 1940   STA &B2                      :\ Store current value
 1950   .L0FA7
 1960   LDA (&BE),Y                  :\ Get character from command line
 1970   CMP #&40:BCS L0FC6           :\ Return with CC with letter
 1980   CMP #&2E:BEQ L0FC7           :\ Return with CS with '.'
 1990   BMI L0FC6                    :\ Return with CC with <'.'
 2000   :
 2010   \ Scan decimal number
 2020   \ TxCB later copied here
 2030   .L0FB3
 2040   AND #&0F                     :\ Convert digit to binary
 2050   .L0FB5
 2060   STA &B3                      :\ Store digit in &B3 as temp
 2070   .L0FB7
 2080   ASL &B2:LDA &B2:ASL A:ASL A  :\ A=num*8
 2090   ADC &B2:ADC &B3              :\ A=num*10+digit
 2100   .L0FC1
 2110   STA &B2:INY:BNE L0FA7        :\ Store update num, step to next
 2120   .L0FC6
 2130   CLC                          :\ Return num with CC=no '.' found
 2140   .L0FC7
 2150   LDA &B2                      :\ Return num
 2160   .L0FC9
 2170   RTS
 2180   :
 2190   \ Scan command line, using NFS's private line pointer
 2200   \ Will return CC for X=net, A=stn, CS for username
 2210   .L0FCA
 2220   INY:LDA (&BE),Y              :\ Get character from command line
 2230   CMP #ASC" ":BNE L0FCA        :\ Skip until space found, stepping past filename
 2240   .L0FD1
 2250   INY:LDA (&BE),Y              :\ Get character from command line
 2260   CMP #ASC" ":BEQ L0FD1        :\ Skip past spaces, stepping to parameters
 2270   CMP #ASC"A":BCS L0FC9        :\ If letter, return with CS with letter
 2280   LDA #&00:JSR L0FA2           :\ Scan number, A=0 for net=0
 2290   BCC L0FC9                    :\ Return if no '.' found
 2300   INY:BCS L0FA2                :\ Step past '.', loop back to get another num
 2310   :
 2320   .L0FE6
 2330   EQUB &85         :\ 0FB5 -> Control byte=OSPROC
 2340   EQUB &00         :\ 0FB6 -> Port=Immediate
 2350   EQUW &0000       :\ 0FB7 -> Station
 2360   EQUD &FFFF00C0   :\ 0FB9 -> Argument block start address
 2370   EQUD &FFFF00C1   :\ 0FBD -> Argument block end address
 2380   EQUW &0004       :\ 0FC1 -> Procedure=4
 2390   .L0FF4
 2400   CMP &FF00,Y      :\ 0FF4: D9 00 FF    Y..
 2410   BBS7,&E9,&0FF9   :\ 0FF7: FF E9 00    .i.
 2420   BBS7,&FF,&0F7C   :\ 0FFA: FF FF 80    ...
 2430   JSR &2806        :\ 0FFD: 20 06 28     .(
 2440 ]NEXT
 2450 PRINT "*SAVE REMOTE ";~mcode%;" ";~O%;" ";~exec%;" ";~load%