;    (c) D.R.McAuley 1987
r0      RN 0
r1      RN 1
r2      RN 2
r3      RN 3
r4      RN 4
r5      RN 5
r6      RN 6
r7      RN 7
r8      RN 8
r9      RN 9
r10     RN 10
r11     RN 11
r12     RN 12
r13     RN 13
r14     RN 14
pc      RN 15

ON        * 1
OFF       * 0
OutputToo * OFF        ; ON means buffer output also OFF means ...


C_bit   * &20000000
V_bit   * &10000000


; Useful SWI numbers
OS_IntOn   * 19
OS_IntOff  * 20
OS_Claim   * 31
OS_Release * 32

; Useful Vector numbers
ErrorV     * &01
IrqV       * &02
WrchV      * &03
Rdch       * &04
CliV       * &05
ByteV      * &06
WordV      * &07
FileV      * &08
ArgsV      * &09
BGetV      * &0A
BputV      * &0B
GBPBV      * &0C
OpenV      * &0D
ReadlineV  * &0E
FSCV       * &0F
EventV     * &10
INSV       * &14
REMV       * &15
CNPV       * &16
UKVDU23V   * &17
UKSWIV     * &18
UKPLOTV    * &19
MouveV     * &1A
VDUXV      * &1B
TickerV    * &1C
UpcallV    * &1D

; Buffer numbers

Keyboard    * 0
RS423_In    * 1
RS243_Out   * 2



 IMPORT  |_rsinsertinn|
 IMPORT  |_rsremoveinn|
 IMPORT  |_rscountnpinn|
 IMPORT  |_rsinsertout|
 IMPORT  |_rsremoveout|
 IMPORT  |_rscountnpout|
 IMPORT  |_kbinsertinn|
 IMPORT  |_kbremoveinn|
 IMPORT  |_kbcountnpinn|

 AREA |C$$code|, CODE, READONLY


|v$codeseg|


; intercept the appropriate system vectors
; r2 is a dummy work space pointer
rsintercept
        SWI     OS_IntOff       ; Disable Interrupts

        MOV     r2, #0 

        MOV     r0, #INSV
        ADR     r1, vecinsert
        SWI     OS_Claim        ; Claim vector

        MOV     r0, #REMV
        ADR     r1, vecremove
        SWI     OS_Claim        ; Claim vector

        MOV     r0, #CNPV
        ADR     r1, veccountnp
        SWI     OS_Claim        ; Claim vector

        SWI     OS_IntOn        ; Enable Interrupts
        MOV     pc, r14

; release the claims we have on system interrupts
; r2 is a dummy work space pointer
rsrelease
        SWI     OS_IntOff       ; Disable Interrupts

        MOV     r2,#0

        MOV     r0, #INSV
        ADR     r1, vecinsert
        SWI     OS_Release      ; Release vector

        MOV     r0, #REMV
        ADR     r1, vecremove
        SWI     OS_Release      ; Release vector

        MOV     r0, #CNPV
        ADR     r1, veccountnp
        SWI     OS_Release      ; Release vector

        SWI     OS_IntOn        ; Enable Interrupts
        MOV     pc, r14




; intercept the appropriate system vectors
; r2 is a dummy work space pointer
kbintercept
        SWI     OS_IntOff       ; Disable Interrupts

        MOV     r2, #0 

        MOV     r0, #INSV
        ADR     r1, kbvecinsert
        SWI     OS_Claim        ; Claim vector

        MOV     r0, #REMV
        ADR     r1, kbvecremove
        SWI     OS_Claim        ; Claim vector

        MOV     r0, #CNPV
        ADR     r1, kbveccountnp
        SWI     OS_Claim        ; Claim vector

        SWI     OS_IntOn        ; Enable Interrupts
        MOV     pc, r14

; release the claims we have on system interrupts
; r2 is a dummy work space pointer
kbrelease
        SWI     OS_IntOff       ; Disable Interrupts

        MOV     r2,#0

        MOV     r0, #INSV
        ADR     r1, kbvecinsert
        SWI     OS_Release      ; Release vector

        MOV     r0, #REMV
        ADR     r1, kbvecremove
        SWI     OS_Release      ; Release vector

        MOV     r0, #CNPV
        ADR     r1, kbveccountnp
        SWI     OS_Release      ; Release vector

        SWI     OS_IntOn        ; Enable Interrupts
        MOV     pc, r14


; insert a charater into a buffer either a character from the receiver
; or a character to be transmitted
vecinsert
        CMP     r1, #RS423_In
        [       OutputToo = ON                
        CMPNE   r1, #RS423_Out
        ]
        MOVNE   pc, r14
        STMFD   r13!,{r0-r12}  
        [       OutputToo = ON
        CMP     r1, #RS423_In
        BLEQ    |_rsinsertinn|
        BLNE    |_rsinsertout|
        |
        BL      |_rsinsertinn|
        ]
        CMP     r0, #1
        LDMFD   r13!, {r0-r12,r14}
        BIC     r14, r14, #C_bit
        ORREQ   r14, r14, #C_bit
        MOVS    pc, r14


; remove a character from a buffer, either fetch a receoved character
; or transmit the next character
vecremove
        CMP     r1, #RS423_In
        [       OutputToo = ON
        CMPNE   r1, #RS423_Out
        ]
        MOVNE   pc, r14
        STMFD   r13!,{r1,r3-r12}
        AND     r0, r14, #V_bit
        [       OutputToo = ON
        CMP     r1, #RS423_In
        BLEQ    |_rsremoveinn|
        BLNE    |_rsremoveout|
        |
        BL      |_rsremoveinn|
        ]
        LDMFD   r13!, {r1,r3-r12,r14}
        BIC     r14, r14, #C_bit
        CMP     r0, #256
        ORRGE   r14, r14, #C_bit
        MOV     r2, r0
        MOVS    pc, r14

; either examine the buffers or purge there contents
veccountnp
        BVS     veccountp
        CMP     r1, #RS423_In
        [       OutputToo = ON
        CMPNE   r1, #RS423_Out
        ]
        MOVNE   pc, r14
        [       OutputToo = ON
        CMP     r1, #RS423_In
        ]
        STMFD   r13!,{r3-r12}
        AND     r0, r14, #V_bit
        AND     r1, r14, #C_bit
        [       OutputToo = ON
        BLEQ    |_rscountnpinn|
        BLNE    |_rscountnpout|
        |
        BL      |_rscountnpinn|
        ]
        LDMFD   r13!, {r3-r12,pc}

veccountp
        CMP     r1, #RS423_In
        [       OutputToo = ON
        CMPNE   r1, #RS423_Out
        ]
        MOVNE   pc, r14
        [       OutputToo = ON
        CMP     r1, #RS423_In
        ]
        STMFD   r13!,{r1-r12}
        AND     r0, r14, #V_bit
        AND     r1, r14, #C_bit
        [       OutputToo = ON
        BLEQ    |_rscountnpinn|
        BLNE    |_rscountnpout|
        |
        BL      |_rscountnpinn|
        ]
        LDMFD   r13!, {r1-r12,pc}



kbvecinsert
        CMP     r1, #Keyboard
        MOVNE   pc, r14
        STMFD   r13!, {r0-r12}
        BL      |_kbinsertinn|
        CMP     r0, #1
        LDMFD   r13!, {r0-r12,r14}
        BIC     r14, r14, #C_bit
        ORREQ   r14, r14, #C_bit
        MOVS    pc, r14

kbvecremove
        CMP     r1, #Keyboard
        MOVNE   pc, r14
        STMFD   r13!,{r1,r3-r12}
        AND     r0, r14, #V_bit
        BL      |_kbremoveinn|
        LDMFD   r13!, {r1,r3-r12,r14}
        BIC     r14, r14, #C_bit
        CMP     r0, #256
        ORRGE   r14, r14, #C_bit
        MOV     r2, r0
        MOVS    pc, r14

kbveccountnp
        BVS     kbveccountp
        CMP     r1, #Keyboard
        MOVNE   pc, r14
        STMFD   r13!,{r3-r12}
        AND     r0, r14, #V_bit
        AND     r1, r14, #C_bit
        BL      |_kbcountnpinn|
        LDMFD   r13!, {r3-r12,pc}

kbveccountp
        CMP     r1, #Keyboard
        MOVNE   pc, r14
        STMFD   r13!,{r1-r12}
        AND     r0, r14, #V_bit
        AND     r1, r14, #C_bit
        BL      |_kbcountnpinn|
        LDMFD   r13!, {r1-r12,pc}



; Need at least 64 bytes of Data to stop objasm hanging!!!!
 AREA |C$$data|
|v$dataseg|
 DCD &0
 ALIGN 64


 EXPORT  |rsintercept|
 EXPORT  |rsrelease|

 EXPORT  |kbintercept|
 EXPORT  |kbrelease|

 END
