	GET	h.asmregs

	AREA    |C$$code|, CODE, READONLY

SWIReturnInst   LDR     pc, [sp, #0*4]

        EXPORT  swix
swix    ROUT
        ORR     r0, r0, #&20000

        EXPORT  swi
swi     ROUT

; Construct a stack frame that looks something like this:
;       returnval
;       LDMIA   r12!, {r0..rn}
;       SWI     xxxxxx
;       LDR     pc, [sp]
;       saved r4-r11,lr
;       saved r1
;       saved input values (r2...rn)

        STMFD   sp!, {r1-r3}            ; Save r1 and put 1st two variadic args on stack
        BIC     r2, r0, #&ff000000
        ORR     r2, r2, #&ef000000      ; Construct SWI instruction
        ADR     r0, SWIReturn
        TST     r1, #&200000            ; bit for write flags
        ADRNE   r0, SWIReturnFlags
        BIC     r1, r1, #&ff000000      ; Construct LDMIA R12!, {regs} instruction, if
        BICS    r1, r1, #&00ff0000      ; {regs} = {} (IE no input regs) we must not
        ORRNE   r1, r1, #&e8000000      ; use an LDMIA R12!, {} instruction as this is an
        ORRNE   r1, r1, #&00bC0000      ; invalid instruction, we use a suitable NOP instead
        MOVEQ   r1, #0                  ; 0 = opcode for ANDEQ r0, r0, r0 (a suitable NOP)
        LDR     r3, SWIReturnInst
        STMFD   sp!, {r0-r9,r11,lr}     ; Save regs and set up SWI call routine (in R0-R3)
	MOV	r0, #0
	SWI 	&2006e
        ADD     r12, sp, #(12+1)*4      ; Point R12 at input regs on stack.
        ADD     pc, sp, #4              ; Call routine on stack
SWIReturnFlags
        LDR     r11, [r12], #4
        STR     pc, [r11]               ; write flags
SWIReturn
        LDR     lr, [sp, #(12+0)*4]     ; Fetch reg mask again
        MOVS    lr, lr, ASL #1          ; Shift out setting C if R0 to be written, N
        LDRCS   r11, [r12], #4          ; if R1 to be written.
        STRCS   r0, [r11]
        LDRMI   r11, [r12], #4
        STRMI   r1, [r11]
        MOVS    lr, lr, ASL #2          ; Shift 2 bits each time for the next 2 regs
        LDRCS   r11, [r12], #4
        STRCS   r2, [r11]
        LDRMI   r11, [r12], #4
        STRMI   r3, [r11]
        MOVS    lr, lr, ASL #2
        LDRCS   r11, [r12], #4
        STRCS   r4, [r11]
        LDRMI   r11, [r12], #4
        STRMI   r5, [r11]
        MOVS    lr, lr, ASL #2
        LDRCS   r11, [r12], #4
        STRCS   r6, [r11]
        LDRMI   r11, [r12], #4
        STRMI   r7, [r11]
        MOVS    lr, lr, ASL #2
        LDRCS   r11, [r12], #4
        STRCS   r8, [r11]
        LDRMI   r11, [r12], #4
        STRMI   r9, [r11]
        LDR     r1, [sp, #2*4]
        TST     r1, #&20000             ; X-bit clear
        CMPEQ   pc, #&80000000          ; SET V flag if so, so R0 not cleared
        MOVVC   r0, #0                  ; Clear R0 if no error (or X-bit clear)
        ADD     sp, sp, #4*4            ; Drop SWI call routine
        LDMIA   sp!, {r4-r9,r11,lr}
        ADD     sp, sp, #3*4            ; Drop saved R1 and 1st two variadic args.
        MOVS    pc, lr

        END
