; > TubeIO
; Minimal interface to Tube system
; --------------------------------

; 08-Feb-2008: RDCH/WRCH use direct TRAP calls
; 09-Feb-2008: CLI checks for *Quit, seperate ostty and mytty settings
; 10-Feb-2008: Vectors explicity set on startup, calls chain through to
;              BBC calls if BBC environment available.
; 22-Aug-2008 ?? Set up unix handlers
; 25-Feb-2009: Working on SIGINT handler and cooked/raw tty settings

; Should be able to set up EMT handler, then do everything through EMTs
; Try setting ESCFLG on SIGINT


; Initialise Host I/O system
; ==========================
; On entry, r5=&0BBC for BBC environment or <>&0BBC otherwise
;           r6=>top of memory-2, bottom of stack, startup parameters
;               stacked parameters end with -1 or 0 (documented as 0, actually -1)
; On exit,  r0=bottom of memory
;           r1=top of memory
; Could combine this with IO_CommandLine and recover space used by parameters.
; Keeping parameters means still have startup command available.
;
.IO_Init
;; adr IO_UNIX,r0		; Default to UNIX TRAP calls
;; mov 6(sp),r4			; Address of first parameter
;; beq IO_Init2			; =0, no parameters, use UNIX I/O calls
;; inc r4			; Test for -1
;; beq IO_Init2			; =-1, no parameters, use UNIX I/O calls
;; dec r4			; Restore r4
;; movb (r4)+,r1		; Get first char of first param
;; cmp r1,#ASC"-"		; Is it a switch?
;; bne IO_Init2			; No, use UNIX I/O calls
;; movb (r4),r1			; Get first char of first param
;; bis #&20,r1			; Ensure lower case
;; cmp r1,#ASC"b"		; Is it "-b"?
;; bne IO_Init2			; No, use UNIX I/O calls
;; adr IO_BBC,r0		; Force use of BBC I/O calls
;; .IO_Init2
;; adr IO_BBC,r2		; Use BBC I/O fall-through calls
;; cmp r1,#ASC"u"			; Is it "-unix"?
;; beq IO_Init25			; Yes, jump to use only UNIX I/Ocalls
;; cmp r5,#&0BBC		; Is BBC environment available?
;; beq IO_Init3			; Yes, use BBC calls
;; .IO_Init25
;; mov #0,r5			; Prevent BBC I/O calls
;; adr IO_NUL,r2		; Fall-through to nulls
;; .IO_Init3
;; adr QUITV,r1			; Point to vectors
;; adr BBCQUITV,r3
;; mov #16,r4			; 16 entries to fill in
;; .IO_InitLp1
;; mov (r0)+,(r1)+		; Copy to vector tables
;; mov (r2)+,(r3)+
;; dec  r4
;; bne  IO_InitLp1		; Loop for 16 entries
;
; Set BBC handlers
; ----------------
;; cmp  r5,#&0BBC			; Is BBC environment available?
;; bne  IO_InitSignals		; No, jump to set up signals
mov #&FFFE,r0			; -2 = Escape handler
clr r1				; Keep default handler routine
adr SV_ESCFLG,r2		; Set handler buffer address
emt 14				; Set Escape flag
mov #&FFFD,r0			; -3 = Error handler
adr ErrorHandler,r1		; Set handler routine
clr r2				; Keep default buffer address
emt 14				; Set Error handler
;
; Catch system signals
; --------------------
;; .IO_InitSignals
;; jsr pc,SetupSIGINT		; Catch user interupts (Escape)
;; jsr pc,SetupSIGEMT		; Catch EMTs
;; jsr pc,SetupSIGSYS		; Catch bad SYS (TRAP) calls

;; ; Set I/O environment
;; ; -------------------
;; trap 54				; ioctrl(), nb - not available on v6
;; equw 0				; stdin
;; equb 18,"t"			; TIOCGETP
;; equw SV_OSIOCTL			; Read settings on stdin
;; ;
;; mov  #27,SV_OSIOCTL+0		; Change SIGINT to CHR$27, SIGQUIT to CHR$0
;; trap 54				; ioctrl()
;; equw 0				; stdin
;; equb 17,"t"			; TIOCSETP
;; equw SV_OSIOCTL			; Write settings on stdin
;; 
;; ; On Unix v6, trap 54 returns to next instruction
;; ; On Unix v7, trap 54 skips three words on return
;; ; 'RTI' is opcode 2, 2=STDERR
;; 
;; ; Set up tty and keep copy to restore and to use on I/O calls
;; ; -----------------------------------------------------------
;; clr  r0				; 0=STDIN
;; trap 32				; gtty()
;; equw SV_OSTTY			; Read host TTY setting
;; mov  SV_OSTTY+0,SV_MYTTY+0	; Copy to mytty settings
;; mov  SV_OSTTY+2,SV_MYTTY+2
;; jsr  pc,tty_mine		; Set up my TTY settings
;
; Return memory limits
; --------------------
adr  BasicEnd,r0		; r0=bottom of memory
mov  sp,r1
add  #2,r1			; r1=top of memory
rts pc

;; ; Set TTY settings for outside or inside operation
;; ; ------------------------------------------------
;; .tty_mine
;; mov  SV_OSTTY+4,r0		; Get host tty_flags
;; bic  #32+8+2,r0			; Echo off, Raw+CBreak off
;; bis  #2,r0			; CBREAK on -- raw, but with INT and QUIT working
;; mov  r0,SV_MYTTY+4		; Store my tty_flags
;; clr  r0				; 0=STDIN
;; trap 31				; stty()
;; equw SV_MYTTY			; Set my TTY setting
;; rts  pc
;; 
;; .tty_raw
;; mov  SV_OSTTY+4,r0		; Get host tty_flags
;; bic  #32+8+2,r0			; Echo off, Raw+CBreak off
;; bis  #32,r0			; Raw on -- allow SIGINT and SIGQUIT through
;; mov  r0,SV_MYTTY+4		; Store my tty_flags
;; clr  r0				; 0=STDIN
;; trap 31				; stty()
;; equw SV_MYTTY			; Set my TTY setting
;; rts  pc
;; 
;; .tty_host
;; clr  r0				; 0=stdin
;; trap 31				; stty()
;; equw SV_OSTTY			; Set host TTY setting
;; rts  pc
;; 
;; 
;; ; Signal handlers
;; ; ===============
;; .SetupSIGINT
;; trap 48				; signal()
;; equw 2				; SIGINT - User interupt (Escape)
;; equw CatchSIGINT
;; rts  pc
;; .CatchSIGINT
;; jsr  pc,SetupSIGINT		; Reconnect handler
;; movb #&FF,SV_ESCFLG		; Set local Escape flag
;; rti
;; 
;; .SetupSIGEMT
;; trap 48				; signal()
;; equw 7				; SIGEMT - EMT call
;; equw CatchSIGEMT
;; rts  pc
;; .CatchSIGEMT
;; jsr  pc,SetupSIGEMT		; Reconnect handler
;; rti
;; 
;; .SetupSIGSYS
;; trap 48				; signal()
;; equw 12				; SIGSYS - unknown SYS (TRAP) call
;; equw CatchSIGSYS
;; rts  pc
;; .CatchSIGSYS
;; jsr  pc,SetupSIGSYS		; Reconnect handler
;; rti
 

; Copy any command line to string buffer
; ======================================
; sp=>retaddr, argn, arg[0], arg[1], ... 0
;
.IO_CommandLine
mov sp,r3			; Point to stack frame
add #6,r3			; Point to first parameter
adr SV_STRING,r1		; Point to string buffer
.IO_CmdSkip
mov (r3)+,r2			; Get address of parameter
beq IO_CmdEnd			; =0 - end of parameters
inc r2
beq IO_CmdEnd			; =-1 - end of parameters
dec r2
movb (r2),r0			; Check this parameter
cmpb r0,#ASC"-"			; Is it an option to BASIC
beq IO_CmdSkip			; Skip BASIC options
sub #2,r3			; Adjust for following increment
.IO_CmdNext
mov (r3)+,r2			; Get address of parameter
beq IO_CmdEnd			; End of parameters
.IO_CmdCopy
movb (r2)+,(r1)+		; Copy bytes from parameter to string buffer
bne IO_CmdCopy			; Loop until zero byte
movb #32,&FFFF(r1)		; Replace zero byte with space
br  IO_CmdNext			; Jump back for next parameter
.IO_CmdEnd
movb #13,(r1)			; Store terminating <cr>
adr SV_STRING,r4		; r4=>command line
movb (r4),r0			; Get first byte from string
cmp r0,#13			; Is it null string - no parameters?
rts pc				; Return EQ=no command line, NE=command line found


;; ; IO jump block entries for Unix environment
;; ; ------------------------------------------
;; .IO_UNIX
;; equw UNIX_QUIT
;; equw UNIX_CLI
;; equw UNIX_BYTE
;; equw UNIX_WORD
;; equw UNIX_WRCH
;; equw UNIX_NEWL
;; equw UNIX_RDCH
;; equw UNIX_FILE
;; equw UNIX_ARGS
;; equw UNIX_BGET
;; equw UNIX_BPUT
;; equw UNIX_GBPB
;; equw UNIX_FIND
;; equw UNIX_SYS1
;; equw UNIX_SYS2
;; equw UNIX_ERROR

;; ; IO jump block entries for BBC environment
;; ; -----------------------------------------
;; .IO_BBC
;; equw BBC_QUIT
;; equw BBC_CLI
;; equw BBC_BYTE
;; equw BBC_WORD
;; equw BBC_WRCH
;; equw BBC_NEWL
;; equw BBC_RDCH
;; equw BBC_FILE
;; equw BBC_ARGS
;; equw BBC_BGET
;; equw BBC_BPUT
;; equw BBC_GBPB
;; equw BBC_FIND
;; equw BBC_SYS1
;; equw BBC_SYS2
;; equw BBC_ERROR

;; ; IO jump block entries for null returns
;; ; --------------------------------------
;; .IO_NUL
;; equw NUL_QUIT
;; equw NUL_CLI
;; equw NUL_BYTE
;; equw NUL_WORD
;; equw NUL_WRCH
;; equw NUL_NEWL
;; equw NUL_RDCH
;; equw NUL_FILE
;; equw NUL_ARGS
;; equw NUL_BGET
;; equw NUL_BPUT
;; equw NUL_GBPB
;; equw NUL_FIND
;; equw NUL_SYS1
;; equw NUL_SYS2
;; equw NUL_ERROR


;; ; IO entry points
;; ; ===============
;; .IO_QUIT0	MOV #0,R0	; Quit with status=0
;; .IO_QUIT	JSR PC,@QUITV	; Quit
;; 		BVS IO_Error
;; 		RTS PC
;; .IO_CLI	JSR PC,@CLIV	; Execute command
;; 		BVS IO_Error
;; 		RTS PC
;; .IO_BYTE	JSR PC,@BYTEV	; Byte operation
;; 		BVS IO_Error
;; 		RTS PC
;; .IO_WORD	JSR PC,@WORDV	; Control block operation
;; 		BVS IO_Error
;; 		RTS PC
;; .IO_WRCR	MOV #13,R0	; Print CHR$13
;; 		BR  IO_WRCH
;; .IO_ASCI	CMP R0,#13	; Print ASCII character
;; 		BEQ IO_NEWL
;; .IO_WRCH	JSR PC,@WRCHV	; Send char to output stream
;; 		BVS IO_Error
;; 		RTS PC
;; .IO_NEWL	JSR PC,@NEWLV	; Send NEWLINE to output stream
;; 		BVS IO_Error
;; 		RTS PC
;; .IO_RDCH	JSR PC,@RDCHV	; Read char from input stream
;; 		BVS IO_Error
;; 		RTS PC
;; .IO_FILE	JSR PC,@FILEV	; Whole file operations
;; 		BVS IO_Error
;; 		RTS PC
;; .IO_ARGS	JSR PC,@ARGSV	; Information on open files
;; 		BVS IO_Error
;; 		RTS PC
;; .IO_BGET	JSR PC,@BGETV	; Get byte from channel
;; 		BVS IO_Error
;; 		RTS PC
;; .IO_BPUT	JSR PC,@BPUTV	; Put byte to channel
;; 		BVS IO_Error
;; 		RTS PC
;; .IO_GBPB	JSR PC,@GBPBV	; Block read/write
;; 		BVS IO_Error
;; 		RTS PC
;; .IO_FIND	JSR PC,@FINDV	; Open or close file
;; 		BVS IO_Error
;; 		RTS PC
;; .IO_SYS1	JSR PC,@sys1V
;; 		BVS IO_Error
;; 		RTS PC
;; .IO_SYS2	JSR PC,@sys2V
;; 		BVS IO_Error
;; 		RTS PC
;; .IO_ERROR	JSR PC,@ERRV	; Generate an error
;; 		BVS IO_Error
;; 		RTS PC
;; 
.IO_Error			; R0=>error block byte,string,zero byte
clv
mov r0,-(sp)
jmp Error


;; ; NUL returns
;; ; ===========
;; .NUL_QUIT
;; .NUL_CLI
;; .NUL_BYTE
;; .NUL_WORD
;; .NUL_WRCH
;; .NUL_NEWL
;; .NUL_RDCH
;; .NUL_FILE
;; .NUL_ARGS
;; .NUL_BGET
;; .NUL_BPUT
;; .NUL_GBPB
;; .NUL_FIND
;; .NUL_SYS1
;; .NUL_SYS2
;; .NUL_ERROR
;; 		clv
;; 		rts pc


; Direct calls to BBC MOS I/O calls
; =================================
.IO_QUIT
.BBC_QUIT	mov r0,-(sp)	; Save return value
		mov #2,r0
		emt 13		; Set default handlers
		mov (sp)+,r0	; Get return value back
		emt 0		; Won't actually get back!
		BVS IO_Error
		rts pc
.IO_CLI
.BBC_CLI	emt 1		; r0=>command string
		BVS IO_Error
		rts pc
.IO_BYTE
.BBC_BYTE	emt 2		; Osbyte r0,r1,r2
		BVS IO_Error
		rts pc
.IO_WORD
.BBC_WORD	emt 3		; Osword r0,r1=>block
		BVS IO_Error
		rts pc
.IO_WRCR	mov #13,r0
		br  IO_WRCH
.IO_ASCI	cmp r0,#13
		beq IO_NEWL
.IO_WRCH
.BBC_WRCH	emt 4		; Oswrch r0=char
		BVS IO_Error
		rts pc
.IO_NEWL
.BBC_NEWL	emt 5		; Print NEWLINE
		BVS IO_Error
		rts pc
.IO_RDCH
.BBC_RDCH	emt 6		; Osrdch r0=char
		BVS IO_Error
		rts pc
.IO_FILE
.BBC_FILE	emt 7		; Osfile r0=action, r1=>block
		BVS IO_Error
		rts pc
.IO_ARGS
.BBC_ARGS	emt 8		; Osargs r0=action, r1=>block, r2=handle
		BVS IO_Error
		rts pc
.IO_BGET
.BBC_BGET	emt 9		; Osbget r1=handle
		BVS IO_Error
		rts pc
.IO_BPUT
.BBC_BPUT	emt 10		; Osbput r0=byte, r1=handle
		BVS IO_Error
		rts pc
.IO_GBPB
.BBC_GBPB	emt 11		; Osgbpb r0=action, r1=>block
		BVS IO_Error
		rts pc
.IO_FIND
.BBC_FIND	emt 12		; Osfind r0=action, r1=>filename or handle
		BVS IO_Error
		rts pc
.IO_SYS1
.BBC_SYS1	emt 13
		BVS IO_Error
		rts pc
.IO_SYS2
.BBC_SYS2	emt 14
		BVS IO_Error
		rts pc
.IO_ERROR
.BBC_ERROR	emt 15		; Generate inline error
		BVS IO_Error
		rts pc


; Calls translated to UNIX TRAPs
; ==============================

;; ; OSNEWL - Output newline to output stream
;; ; ========================================
.UNIX_NEWL			; Print NEWLINE
;; mov  #10,r0
;; jsr  pc,IO_WRCH
.UNIX_WRCR			; Print CR
;; mov  #13,r0

;; ; OSWRCH - Output character to output stream
;; ; ==========================================
;; ; On entry, R0=character
;; ; On exit,  all registers preserved
;; ;
.UNIX_WRCH
;; mov  r0,MOS_BUF			; Store char in buffer
;; mov  #1,r0			; STDOUT=1
;; trap 4				; write()
;; equw MOS_BUF			; address=buffer
;; equw 1				; count=1
;; mov  MOS_BUF,r0			; Restore r0
;; clv				; Clear error state
;; rts  pc


;; ; OSRDCH - Wait for character from input stream
;; ; =============================================
;; ; On exit,  R0=character
;; ;           CC=not escape, CS=escape
;; ;
.UNIX_RDCH
;; jsr  pc,tty_raw			; Select raw TTY settings
;; clr  r0				; STDIN=0
;; trap 3				; read()
;; equw MOS_BUF			; address=buffer
;; equw 1				; count=1
;; jsr  pc,tty_mine		; Return to my TTY settings
;; movb MOS_BUF,r0			; Fetch char from buffer
;; cmp  r0,#27			; Escape character?
;; beq  UNIX_RDCH_ESC
;; clc				; Not Escape
;; clv				; No error
;; rts  pc
;; .UNIX_RDCH_ESC
;; sec				; Escape character
;; clv				; No error
;; rts  pc


;; ; OSQUIT - Quit execution
;; ; =======================
;; ; On entry, R0=exit status
;; ;
.UNIX_QUIT
;; mov  r0,-(sp)			; Save exit status
;; jsr  pc,tty_host		; Return to host TTY settings
;; trap 48				; signal(SIGSYS,0)
;; equw 12
;; equw 0
;; trap 48				; signal(SIGEMT,0)
;; equw 7
;; equw 0
;; trap 48				; signal(SIGINT,0)
;; equw 2
;; equw 0
;; mov  (sp)+,r0			; Get exit status back
;; trap 1				; exit(r0)
;; clv				; Clear error state
;; rts  pc				; Just in case we get back!


;; ; OSWORD - Host calls with parameters in control block
;; ; ====================================================
;; ; On entry, R0=action
;; ;           R1=>control block
;; ; On exit,  All registers undefined
;; ;
.UNIX_WORD
; 0 - Read line
; 1 - Read TIME
; 2 - Write TIME
; 3 - Read SYSTIME
; 4 - Write SYSTIME
; 5 - Read from memory
; 6 - Write to memory
; 7 - SOUND
; 8 - ENVELOPE
; 9 - POINT
; 10 - Character definition
; 11 - Read palette
; 12 - Write palette
; 13 - Read graphics positions
; 14 - Read TIME$
; 15 - Write TIME$
;; tst r0
;; beq UNIX_WORD0			; Jump for OSWORD 0, Read Line
;; cmp r0,#1
;; beq UNIX_WORD1			; OSWORD 1 - Read TIME
;; jmp @BBCWORDV			; Fall through to BBC call
;; 
;; ; Read line of text
;; ; -----------------
;; ; On entry, R1=>address of memory to read string to
;; ; On exit,  R2=length of string
;; ;           CC=ok, CS=Escape pressed
;; ;
;; .UNIX_WORD0
;; mov  r1,-(sp)			; Save pointer to control block
;; mov  r3,-(sp)			; Save R3
;; mov  (r1),r1			; Get pointer to buffer
;; clr  r2				; Zero number of characters read
;; .RdLnLoop
;; jsr  pc,IO_RDCH			; Get a character
;; bcs  RdLnEsc			; Escape state
;; cmp  r0,#13
;; beq  RdLnCR			; <CR> - End of line
;; cmp  r0,#10
;; beq  RdLnCR			; <LF> - End of line
;; cmp  r0,#21
;; beq  RdLnU			; Ctrl-U - delete line
;; cmp  r0,#127
;; beq  RdLnDel			; <DEL> - del a character
;; cmp  r0,#8
;; beq  RdLnDel			; <BS> - del a character
;; cmp  r0,#ASC" "
;; bcs  RdLnLoop			; Ignore other control characters
;; cmp  r2,#240
;; bcc  RdLnLoop			; No more room for characters
;; movb r0,(r1)+			; Put character into memory
;; add  #1,r2			; Inc. number of characters
;; jsr  pc,IO_WRCH			; Output the character
;; br   RdLnLoop			; Go back for another
;; ;
;; .RdLnU
;; mov  r2,r3			; We want to delete all characters
;; br   RdLnDelete
;; .RdLnDel
;; mov  #1,r3			; We only want to delete one char
;; .RdLnDelete
;; tst  r2				; Check line length
;; beq  RdLnLoop			; Length=0, jump back to main loop
;; mov  #8,r0			; Output <DEL> by backspacing
;; jsr  pc,IO_WRCH
;; mov  #32,r0
;; jsr  pc,IO_WRCH
;; mov  #8,r0
;; jsr  pc,IO_WRCH
;; dec  r1				; Back address pointer
;; dec  r2				; Dec character counter
;; ;sob  r3,RdLnDelete		; Loop for each to delete
;; dec  r3
;; bne  RdLnDelete			; Loop for each to delete
;; br   RdLnLoop			; Go back into ReadLine loop
;; ;
;; .RdLnEsc
;; jsr  pc,IO_NEWL			; Print newline
;; clr  r2				; Length = 0
;; mov  (sp)+,r3			; Restore R3
;; mov  (sp)+,r1			; Get buffer address back
;; movb r0,(r1)			; Put <CR> terminator in
;; sec				; Set carry - escape
;; rts  pc
;; ;
;; .RdLnCR
;; mov  #13,r0			; Convert <LF> to <CR>
;; movb r0,(r1)+			; Put <CR> terminator in
;; jsr  pc,IO_NEWL			; Returns with r0=<cr>
;; clc				; Clear carry - ok
;; .RdLnEnd
;; mov  (sp)+,r3			; Restore R3
;; mov  (sp)+,r1			; Get buffer address back
;; clr  r0				; Restore R0
;; rts  pc				; r0=0, r1=buffer, r2=length

;; ; Read TIME
;; ; ---------
;; .UNIX_WORD1
;; ; On entry, R1=>block to read time to
;; ; On exit,  R0,R1=corrupted
;; ;
;; mov  r2,-(sp)			; Save R2 for later
;; mov  r1,-(sp)			; Save buffer pointer
;; TRAP 13				; Read time to r0:r1
;; mov  (sp)+,r2			; Get buffer pointer back
;; movb r0,(r2)+			; Store returned time
;; swab r0				; nb - should be in centiseconds
;; movb r0,(r2)+
;; movb r1,(r2)+
;; swab r1
;; movb r1,(r2)
;; mov  (sp)+,r2
;; rts  pc				; r0,r1 corrupted


;; ; OSCLI - Execute command
;; ; =======================
;; ; Initially, just checks for *Quit
.UNIX_CLI			; r0=>command string
;; mov r1,-(sp)
;; mov r0,-(sp)
;; mov r0,r1
;; .CLI_lp1
;; movb (r1)+,r0
;; cmp r0,#ASC"*"
;; beq CLI_lp1			; Skip spaces
;; cmp r0,#ASC" "
;; beq CLI_lp1
;; mov r1,-(sp)			; Save address after '*'s and ' 's
;; bic #32,r0
;; cmp r0,#ASC"Q"
;; bne CLI_not
;; movb (r1)+,r0
;; bic #32,r0
;; cmp r0,#ASC"U"
;; bne CLI_not
;; movb (r1)+,r0
;; bic #32,r0
;; cmp r0,#ASC"I"
;; bne CLI_not
;; movb (r1)+,r0
;; bic #32,r0
;; cmp r0,#ASC"T"
;; bne CLI_not
;; movb (r1),r0
;; cmp r0,#ASC"!"
;; bcc CLI_not
;; jmp IO_QUIT0
;; .CLI_not
;; mov (sp)+,r1			; Get command line address back
;; ;
;; 				; (pc+0)=>name
;; 				; (pc+2)=argv
;; ;
;; mov (sp)+,r0			; Restore registers
;; mov (sp)+,r1
;; jmp @BBCCLIV			; Fall through to BBC call


;; ; OSBYTE - Host calls with byte parameters
;; ; ========================================
.UNIX_BYTE
;; tst  r0
;; beq  UNIX_BYTE0
;; jmp  @BBCBYTEV			; Osbyte r0,r1,r2

;; ; Read host system type
;; ; ---------------------
;; .UNIX_BYTE0
;; mov  #8,r1			; r1=8 for Unix
;; rts  pc


;; ; Fall through to BBC calls
;; ; =========================
.UNIX_FILE	;; jmp @BBCFILEV	; Osfile r0=action, r1=>block
.UNIX_ARGS	;; jmp @BBCARGSV	; Osargs r0=action, r1=>block, r2=handle
.UNIX_BGET	;; jmp @BBCBGETV	; Osbget r1=handle
.UNIX_BPUT	;; jmp @BBCBPUTV	; Osbput r0=byte, r1=handle
.UNIX_GBPB	;; jmp @BBCGBPBV	; Osgbpb r0=action, r1=>block
.UNIX_FIND	;; jmp @BBCFINDV	; Osfind r0=action, r1=>filename or handle
.UNIX_SYS1	;; jmp @BBCSYS1V
.UNIX_SYS2	;; jmp @BBCSYS2V
.UNIX_ERROR	;; jmp @BBCERRV	; Generate error

