home *** CD-ROM | disk | FTP | other *** search
- ; Alternative SWI functions. These were posted to Usenet by Edward Nevill
- ; of Acorn. I have included the start of his posting below (the rest was
- ; the code, and a test routine).
-
- ; As usual with code I've nicked and included here, any credit (and my
- ; thanks) goes to Edward, for the code and for publicly distributing it.
- ; I hope I've not introduced any bugs while including it with this library...
-
- ; "How to use" documentation is in the C header file, "Swi.h".
-
- ; Path: cix!slxsys!uknet!ukc!acorn!enevill
- ; From: enevill@acorn.co.uk (Edward Nevill)
- ; Newsgroups: comp.sys.acorn
- ; Subject: New SWI veneers
- ; Message-ID: <10187@acorn.co.uk>
- ; Date: 4 Oct 91 17:11:01 GMT
- ; Sender: enevill@acorn.co.uk
- ; Distribution: comp
- ; Organization: Acorn Computers Ltd, Cambridge, England
- ; Lines: 212
- ;
- ; Here is an optimised SWI veneer which can be used instead of _kernel_swi.
- ; It is significantly faster than _kernel_swi and is much easier to use
- ; (IMHO).
- ;
- ; Enjoy,
- ; Edward.
-
- 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
- sp RN 13
- lr RN 14
- pc RN 15
-
-
- 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
- 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)
- ADD r12, sp, #(12+1)*4 ; Point R12 at input regs on stack.
- ADD pc, sp, #4 ; Call routine on stack
- 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
-