From 00d0c4c3e1fe8bd02589981a7e8eee6e031c4783 Mon Sep 17 00:00:00 2001
From: Neil Turton <nturton@gitlab.riscosopen.org>
Date: Tue, 21 Jan 1997 16:30:14 +0000
Subject: [PATCH] Version Spin_merge taken

---
 hdr/DeviceFS |   5 +-
 s/DeviceFS   |  58 +++++++++++++++-----
 s/FSystem    | 146 +++++++++++++++++++++++++++++++++++++++++++++++----
 3 files changed, 183 insertions(+), 26 deletions(-)

diff --git a/hdr/DeviceFS b/hdr/DeviceFS
index 6a36e48..fee9aae 100644
--- a/hdr/DeviceFS
+++ b/hdr/DeviceFS
@@ -29,6 +29,8 @@ OldOpt  SETA    {OPT}
 ; 16-Apr-91 DDV Added StreamCreated reason code.
 ; 04-Jan-93 JSR Added PrinterDestination_SCSIPrinter
 ; 17-May-94 AMcC Changed to using the preferred SWI base and name symbols
+; 30-Apr-96 RWB	Added DeviceCall_IOCtl
+; 28-May-96 RWB Added ParentFlag_DeviceUpcalls
 
 SWIClass        SETS    DeviceFSSWI_Name
 
@@ -50,6 +52,7 @@ ParentFlag_BlockDevice          * 1:SHL:0       ; bit 0  set => block device
 ParentFlag_FullDuplex           * 1:SHL:1       ; bit 1  set => device is full duplex
 ParentFlag_MonitorTransfers     * 1:SHL:2       ; bit 2  set => MonitorTX/RX available
 ParentFlag_MonitorEOF           * 1:SHL:3       ; bit 3  set => Monitor EOF on reading
+ParentFlag_DeviceUpcalls	* 1:SHL:4	; bit 4  set => Issue device upcalls
 
 DeviceFlag_BufferedDevice       * 1:SHL:0       ; bit 0  set => device should be buffered
 DeviceFlag_DefinePathVariable   * 1:SHL:1       ; bit 1  set => setup a <device>$Path variable for this object
@@ -71,7 +74,7 @@ DeviceCall_EndOfData            * 10            ; has end of data been reached
 DeviceCall_StreamCreated        * 11            ; stream has now been created reason code.
 DeviceCall_MonitorTX            * 12            ; is TX going OK?
 DeviceCall_MonitorRX            * 13            ; is RX going OK?
-
+DeviceCall_IOCtl		* 14		; perform IOCtl
 DeviceCall_ExternalBase         * &80000000     ; all reasons with bit 31 set are for device dependant use
 
 
diff --git a/s/DeviceFS b/s/DeviceFS
index 74a0939..9f9b30e 100644
--- a/s/DeviceFS
+++ b/s/DeviceFS
@@ -127,7 +127,16 @@
 ; 07-Sep-93 0.28 SMC Escape now returns error number 17.
 ;                    Fixed bug in fs_put where Escape was ignored.
 ; 04-Feb-94 0.29 TMD Move GET hdr:Territory below GET hdr:NewErrors
-;
+; 26-Apr-96 0.30 RWB Implemented OS_Args 2 (Read open file extent) to return
+;		     number of bytes in buffer.
+; 30-Apr-96 0.31 RWB Implemented OS_Args 9 (IOCtl) to dispatch IOCtl reason call
+;                    to underlying device driver.
+; 14-May-96 0.32 RWB Overload OS_Args 2 to return free space in buffer if a tx
+;		     stream.
+; 22-May-96 0.33 RWB Issue an upcall when buffer becomes non-dormant.
+;		     Issue upcalls with stream handle when thresholds are passed
+; 14-Jun-96 0.34 RWB Pass file switch handle through to device driver during
+;		     device initialisation.
 
                 GET     hdr:ListOpts
                 GET     hdr:Macros
@@ -280,7 +289,12 @@ pf_BlockDevice          * 1:SHL:0       ; bit 0 set => Block device (ie. floppy
 pf_FullDuplex           * 1:SHL:1       ; bit 1 set => Device supports full duplex operation
 pf_MonitorTransfers     * 1:SHL:2       ; bit 2 set => monitor transfers
 pf_MonitorEOF           * 1:SHL:3       ; bit 3 set => monitor EOF during read
+ [ issue_device_upcalls
+pf_DeviceUpcalls	* 1:SHL:4	; bit 4 set => issue stream upcalls on buffer thresholding
+pf_AllowedBits          * pf_BlockDevice+ pf_FullDuplex+ pf_MonitorTransfers+ pf_MonitorEOF+ pf_DeviceUpcalls
+ |
 pf_AllowedBits          * pf_BlockDevice+ pf_FullDuplex+ pf_MonitorTransfers+ pf_MonitorEOF
+ ]
 
 ff_FileInputOutput      * 1:SHL:0
 ff_FileForTX            * 1:SHL:0       ; bit 0  set => TX
@@ -1523,32 +1537,48 @@ UpCall          ROUT
 
                 TEQ     r0, #UpCall_BufferFilling
                 TEQNE   r0, #UpCall_BufferEmptying
-                MOVNES  pc, lr                                  ; quick check to see if mine
+                MOVNES  pc, lr                    ; quick check to see if mine
 
-                Push    "r0-r4"
+                Push    "r0-r4,pr"
 
-                LDR     r3, FilesAt                             ; -> start of the file list
+                LDR     r3, FilesAt               ; -> start of the file list
 00
-                TEQ     r3, #0                                  ; end of the files list?
-                Pull    "r0-r4", EQ
-                MOVEQS  pc, lr                                  ; yes, so unstack and then exit
+                TEQ     r3, #0                    ; end of the files list?
+                Pull    "r0-r4,pr", EQ
+                MOVEQS  pc, lr                    ; yes, so unstack and then exit
 
                 LDR     lr, [r3, #file_BufferHandle]
-                TEQ     lr, r1                                  ; is it our buffer?
+                TEQ     lr, r1                    ; is it our buffer?
                 LDRNE   r3, [r3, #file_Next]
-                BNE     %00                                     ; loop until all checked
+                BNE     %00                       ; loop until all checked
 
                 TEQ     r0, #UpCall_BufferFilling
                 MOVEQ   r0, #DeviceCall_Halt
-                MOVNE   r0, #DeviceCall_Resume                  ; convert to an understandable device call
+                MOVNE   r0, #DeviceCall_Resume    ; convert to an understandable device call
 
                 LDR     r1, [r3, #file_Parent]
                 LDR     r2, [r3, #file_InternalHandle]
                 BL      CallDevice
-                STRVS   r0, [sp]                                ; write the error address to frame
-
-                Pull    "r0-r4, lr"                             ; balance stack (pull extra one to claim vector)
-                BICVCS  pc, lr, #V_bit                          ; only errors are external
+                STRVS   r0, [sp]                  ; write the error address to frame
+
+ [ issue_device_upcalls
+; check to see if device driver wants these upcalls forwarding
+		BVS	%10
+		LDR	pr, [r3, #file_Parent]
+		LDR	r1, [pr, #parent_Flags]
+		TST	r1, #pf_DeviceUpcalls
+		BEQ	%10
+; now issue upcalls based on stream handle
+                TEQ     r0, #DeviceCall_Halt
+                MOVEQ   r0, #UpCall_DeviceThresAbove
+                MOVNE   r0, #UpCall_DeviceThresBelow
+                LDR     r1, [r3, #file_FSwitchHandle]
+		SWI	XOS_UpCall
+                STRVS   r0, [sp]
+10
+ ]
+                Pull    "r0-r4,pr, lr"            ; balance stack (pull extra one to claim vector)
+                BICVCS  pc, lr, #V_bit            ; only errors are external
                 ORRS    pc, lr, #V_bit
 
 ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
diff --git a/s/FSystem b/s/FSystem
index 2552576..2383927 100644
--- a/s/FSystem
+++ b/s/FSystem
@@ -85,9 +85,10 @@ fs_control      & fs_name -module_start                         ; -> fs name, eg
                 & fs_args -module_start                         ; -> fs args
                 & fs_close -module_start                        ; -> fs close
                 & fs_file -module_start                         ; -> fs file
-fs_infoword     & fsinfo_special+ fsinfo_flushnotify+ fsinfo_dontusesave+ fsnumber_DeviceFS
+fs_infoword     & fsinfo_special+ fsinfo_flushnotify+ fsinfo_dontusesave+ fsinfo_extrainfo+ fsnumber_DeviceFS
                 & fs_func -module_start                         ; -> fs func
                 & fs_gbpb -module_start                         ; -> gbpb routine
+		& fsextra_IOCtl
 
 fs_badop
                 ADR     r0, ErrorBlock_DeviceFS_BadOp
@@ -322,6 +323,7 @@ open_input
 
                 LDR     r6, [fr, #file_UserSpecialData]         ; -> decoded special field string
                 MOV     r2, fr                                  ;  = internal handle
+		LDR	r4, [fr, #file_FSwitchHandle]
                 MOV     r1, pr
                 MOV     r0, #DeviceCall_Initialise
                 BL      CallDevice                              ; attempt to call the device
@@ -382,6 +384,7 @@ open_output
                 Debug   open, "file flags", r3
 
                 LDR     r6, [fr, #file_UserSpecialData]         ; -> decoded special field string
+		LDR	r4, [fr, #file_FSwitchHandle]
                 MOV     r2, fr
                 MOV     r1, pr
                 MOV     r0, #DeviceCall_Initialise
@@ -485,8 +488,14 @@ make_buffer     ROUT
                 STR     r0, [fr, #file_BufferHandle]
 
                 LDR     r1, [fr, #file_Flags]
+ [ wakeup_data_present
+		TST	r1, #ff_FileForTX
+		ADRNE	r1, wakeup			; normal tx wakeup
+		ADREQ	r1, wakeup_rx			; special rx wakeup
+ |
                 ANDS    r1, r1, #ff_FileForTX                   ; if an output device (r1<>0)
                 ADRNE   r1, wakeup                              ; then use real wake up code else use none
+ ]
                 ADR     r2, detach                              ; try to close stream if someone tries to detach
                 MOV     r3, fr
                 MOV     r4, wp                                  ; workspace + private word
@@ -532,6 +541,26 @@ wakeup          ENTRY   "r0-r3"
                 SWI     XBuffer_ModifyFlags
                 EXITS
 
+ [ wakeup_data_present
+; wake up code, this is called when some data is inserted into a dormant RX buffer.
+wakeup_rx	ENTRY	"r0-r2"
+
+		MOV	r2, pc
+		ORR	r0, r2, #SVC_mode
+		TEQP	r0, #0
+		NOP
+
+		Push	"lr"
+		MOV	r0, #UpCall_DeviceRxDataPresent
+                LDR     r1, [r8, #file_FSwitchHandle]
+		SWI	XOS_UpCall
+		Pull	"lr"
+
+		TEQP	r2, #0
+		NOP
+
+		EXITS
+ ]
 ; detach code, this is called when someone tries to deregister the buffer, or link it some other device
 
 detach          ENTRY   "r0-r2"
@@ -807,7 +836,14 @@ fs_put          ENTRY   "r0-r2, fr, r9"
 ;
 
 fs_args         ROUT
-
+		CMP	r3, #3
+		BNE	%1
+		Push	"r0-r1"
+		MOV	r0, #&3500000
+		LDR	r1, =&40ff0000
+		STR	r1, [r0]
+		Pull	"r0-r1"
+1
                 Debug   args, "fs_args called with reason code", r0
 
                 TEQ     r0, #fsargs_SetEXT                      ; ignore SetEXT
@@ -816,29 +852,117 @@ fs_args         ROUT
                 TEQ     r0, #fsargs_SetPTR
                 TEQNE   r0, #fsargs_EnsureSize
                 TEQNE   r0, #fsargs_WriteZeroes
-                BEQ     fs_badop                                ; these ones give nice clean and tidy errors
+                BEQ     fs_badop                ; these ones give nice errors
 
                 TEQ     r0, #fsargs_ReadPTR
-                TEQNE   r0, #fsargs_ReadEXT
                 TEQNE   r0, #fsargs_ReadSize
-                MOVEQ   r2, #0                                  ; these ones return size pointer
+                MOVEQ   r2, #0			; return 0
                 MOVEQS  pc, lr
 
+                TEQ	r0, #fsargs_ReadEXT
+		BEQ	args_ext
+
+		TEQ	r0, #fsargs_IOCtl
+		BEQ	args_ioctl
+
                 TEQ     r0, #fsargs_ReadLoadExec
                 BEQ     args_loadexec
 
-                TEQ     r0, #fsargs_Flush                       ; is it a flush?
+                TEQ     r0, #fsargs_Flush               ; is it a flush?
                 BEQ     args_flush
 
-                TEQ     r0, #fsargs_EOFCheck                    ; is it a eof read?
-                BEQ     args_eof                                ; then do it
+                TEQ     r0, #fsargs_EOFCheck            ; is it a eof read?
+                BEQ     args_eof                        ; then do it
 
                 B       fs_badop
 
+; handle ioctl's
+
+args_ioctl	ENTRY	"r0-r3, fr,pr"
+
+                MOV     fr, r1                     	; -> file record
+		LDR	pr, [fr, #file_Parent]
+
+                MOV     r0, #DeviceCall_IOCtl
+                MOV     r1, pr
+		MOV	r3, r2				; shift r2 up a reg
+		MOV	r2, fr
+                BL      CallDevice
+
+                STRVS   r0, [sp]
+                PullEnv VS
+                ORRVSS  pc, lr, #V_bit
+
+		EXIT
+
+; handle checking of the file extent
+
+args_ext	ENTRY	"r0-r1,r3-r6, fr"
+
+                MOV     fr, r1                     	; -> file record
+
+                LDR     r0, [fr, #file_BufferHandle]
+                CMP     r0, #-1                         ; is the object buffered
+                BEQ     %FT10				; look at rx/tx word
+
+; is this a tx stream
+		LDR	r0, [fr, #file_Flags]
+		TST	r0, #ff_FileForTX
+		BNE	%5
+
+ [ FastBufferMan
+                MOV     r0, #BufferReason_UsedSpace
+                LDR     r1, [fr, #file_BufferPrivId]
+                CallBuffMan
+ |
+                SWI     XBuffer_GetInfo
+ ]
+                STRVS   r0, [sp]
+                PullEnv VS
+                ORRVSS  pc, lr, #V_bit
+
+ [ :LNOT: FastBufferMan
+                MOV	r6, r2
+ ]
+		EXIT
+5
+; deal with tx stream
+ [ FastBufferMan
+                MOV     r0, #BufferReason_FreeSpace
+                LDR     r1, [fr, #file_BufferPrivId]
+                CallBuffMan
+ |
+                SWI     XBuffer_GetInfo
+ ]
+                STRVS   r0, [sp]
+                PullEnv VS
+                ORRVSS  pc, lr, #V_bit
+
+ [ :LNOT: FastBufferMan
+                MOV	r6, r2
+ ]
+		EXIT
 
-; handle checking the EOF flag within the system.  Could return errors, assumes that r1
-; on entry contains the internal handle passed to and from fileswitch to the filing
-; system.
+10
+; handle the case where none-buffered, just a word
+                LDR     r0, [fr, #file_RXTXWord]
+                CMP     r0, #-1                    	; RX/TX word full
+		MOVEQ	r2, #0				; no
+		MOVNE	r2, #1				; yes
+; is this a tx stream
+		LDR	r0, [fr, #file_Flags]
+		TST	r0, #ff_FileForTX
+		EXIT	EQ
+
+		CMP	r2, #0
+		MOVEQ	r2, #1
+		MOVNE	r2, #0
+
+		EXIT
+
+; handle checking the EOF flag within the system.  Could return errors, assumes
+; that r1 on entry contains the internal handle passed to and from fileswitch to
+; the filing system.
 
 checkeof        ENTRY   "r2"                                    ; internal routine,
                 BL      args_eof
-- 
GitLab