; >s.ArthurAsm 

; SWI values for ProtoArfur 0.012

WriteC        * &00
WriteS        * &01
Write0        * &02
NewLine       * &03
ReadC         * &04
CLI           * &05
Byte          * &06
Word          * &07
File          * &08
Args          * &09
BGet          * &0A

BPut          * &0B
Multiple      * &0C
Open          * &0D
ReadLine      * &0E
Control       * &0F
GetEnv        * &10
Exit          * &11
SetEnv        * &12
IntOn         * &13
IntOff        * &14
CallBack      * &15
EnterOS       * &16
BreakPt       * &17
BreakCtrl     * &18
UnusedSWI     * &19
UpdateMEMC    * &1A
SetCallBack   * &1B
Mouse         * &1C

Heap          * &1D     ; Our new ones start here
Module        * &1E
Claim         * &1F     ; PMF's vector handling
Release       * &20     ; routines
ReadUnsigned  * &21     ; Read an unsigned number
GenerateEvent * &22
ReadVarVal    * &23     ; read variable value & type
SetVarVal     * &24     ; set  variable value & type
GSInit        * &25
GSRead        * &26
GSTrans       * &27
BinaryToDecimal * &28
FSControl     * &29
ChangeDynamicArea * &2A
GenerateError * &2B
ReadEscapeState * &2C

WriteI        * &100

UserSWI       * &200


Initialise          *    &000400c0
CreateWindow        *    &000400c1
CreateIcon          *    &000400c2
DeleteWindow        *    &000400c3
DeleteIcon          *    &000400c4
OpenWindow          *    &000400c5
CloseWindow         *    &000400c6
Poll                *    &000400c7
RedrawWindow        *    &000400c8
UpdateWindow        *    &000400c9
GetRectangle        *    &000400ca
GetWindowState      *    &000400cb
GetWindowInfo       *    &000400cc
SetIconState        *    &000400cd
GetIconState        *    &000400ce
GetPointerInfo      *    &000400cf
DragBox             *    &000400d0
ForceRedraw         *    &000400d1
SetCaretPosition    *    &000400d2
GetCaretPosition    *    &000400d3
CreateMenu          *    &000400d4
DecodeMenu          *    &000400d5
WhichIcon           *    &000400d6
SetExtent           *    &000400d7
SetPointerShape     *    &000400d8



SWI_OP        * &ef000000 ; SWIAL  op-code
XOS_MASK      * &00020000 ; mask to make a swi an Arthur v-error swi

; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; Register names

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
r15 RN 15

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
R15 RN 15
PC RN 15

a1 RN 0
a2 RN 1
a3 RN 2
a4 RN 3
v1 RN 4
v2 RN 5
v3 RN 6
v4 RN 7
v5 RN 8
v6 RN 9
fp RN 10
ip RN 11
sp RN 12
sl RN 13
lk RN 14
pc RN 15


; in s.ArthurAsm ...
;  get()
;  vdu()
;  vduw()
;  mouse()
;  swi()
;  swix()

        IMPORT |x$stack_overflow|

        EXPORT |get|
        EXPORT |vdu|
        EXPORT |vduw|
        EXPORT |mouseX|
        EXPORT |mouseY|
        EXPORT |mouseB|
        EXPORT |swi|
        EXPORT |swix|


 AREA |C$$code|, CODE, READONLY

|v$codesegment|

get     SWI     ReadC
        MOVS    PC,R14

vduw
        SWI     WriteC
        MOV     R0,R0,LSR #8
vdu     SWI     WriteC
        MOVS    PC,R14

mouseX
        SWI     Mouse
        MOVS    PC,R14

mouseY
        SWI     Mouse
        MOV     R0,R1
        MOVS    PC,r14

mouseB
        SWI     Mouse
        MOV     R0,R2
        MOVS    PC,R14

; In : a1 contains pointer to return structure, a2 contains swi number, a3
; points to arm register structure

swi
        MOV     ip, sp
        STMFD   sp!, {v1-v6,fp,ip,lk,pc}
        SUB     fp, ip, #4
        CMP     sp, sl
        BLCC    |x$stack_overflow|

        BIC     a2, a2, #&ff000000      ; just in case swi number stupid!
        ORR     a2, a2, #SWI_OP         ; make into swi operation
        LDR     a4, return_inst         ; get a return instruction
        STMDB   sp!, {a2,a4}            ; then put both on the stack

        MOV     ip, a1                  ; save return pointer out of way
        LDMIA   a3, {a1-v6}             ; get user's input registers

        ADR     r14, return_hre         ; come back here
        MOV     pc, sp                  ; after executing stacked instr.
return_hre
        ADD     sp, sp, #2*4            ; tidy stack

        STMIA   ip, {a1-v6}             ; then return r0-r8 to user
        MOV     a1, ip                  ; returning it's pointer

        LDMEA   fp, {v1-v6,fp,sp,pc}^

return_inst

        MOV     pc, lk                  ; data really - for stack execution

; In : a1 contains swi number, a2
; points to arm register structure

swix
        MOV     ip, sp
        STMFD   sp!, {v1-v6,fp,ip,lk,pc}
        SUB     fp, ip, #4
        CMP     sp, sl
        BLCC    |x$stack_overflow|

        BIC     a1, a1, #&ff000000      ; just in case swi number stupid!
        ORR     a1, a1, #SWI_OP         ; make into swi operation
        ORR     a1, a1, #XOS_MASK       ; make a swi of V-error type
        LDR     a3, return_inst         ; get a return instruction
        STMDB   sp!, {a1,a3}            ; then put both on the stack

        MOV     ip, a2                  ; save return pointer out of way
        LDMIA   a2, {a1-v6}             ; get user's input registers

        ADR     r14, return_here        ; come back here
        MOV     pc, sp                  ; after executing stacked instr.
return_here
        ADD     sp, sp, #2*4            ; tidy stack

        STMIA   ip, {a1-v6}             ; then return r0-r8 to user
        MOVVC   a1, #0                  ; returning 0 if no error,
                                        ; pointer to error block if error

        LDMEA   fp, {v1-v6,fp,sp,pc}^


        END
