From: bcockburn@acorn.co.uk (Bruce Cockburn)
Newsgroups: comp.sys.acorn.tech
Subject: Re: Unknown swi question
Date: 7 Oct 92 14:17:45 GMT
Organization: Acorn Computers Ltd, Cambridge, England

David (and all module writers),

  The current technology at Acorn is to use code like this;

SWIEntry        ROUT
        LDR     wp, [ r12 ]
        CMP     r11, #( EndOfJumpTable - JumpTable ) / 4
        ADRCS   r0, ErrorOutOfRange
        ADDCC   pc, pc, r11, LSL #2
        ;       Only one instruction after the ADD pc, pc
        [       UseMsgTrans
        B       MakeErrorWithModuleName
        |
        ORRS    pc, lr, #VFlag
        ]       ; UseMsgTrans
JumpTable                               ; Then the jump table
        B       Version                 ; &40000, 0
        B       MyFirstSWI              ; &40001, 1
        B       ReadOperation           ; &40002, 2
        B       WriteOperation          ; &40003, 3
EndOfJumpTable

        LTORG

ErrorOutOfRange
        DCD     ErrorNumber_OutOfRange  ; &000001E8
        [       UseMsgTrans
        DCB     "BadSWI"
        |
        DCB     "SWI value out of range for this Module"
        ]
        DCB     0
        ALIGN

        [       UseMsgTrans
MakeError       ROUT
        Push    "r4, r5, lr"
        MOV     r4, #0
DoMakeError1
        MOV     r5, #0
        BL      MessageTransErrorLookup2
        Pull    "r4, r5, pc"

MakeErrorWithModuleName
        Push    "r4, r5, lr"
        ADR     r4, ModuleTitle
        B       DoMakeError1

MessageTransErrorLookup2
        Push    "r1-r3, r6, r7, lr"
        LD      r1, MessageBlockAddress
        CMP     r1, #0                  ; Clears V
        BNE     DoErrorLookup
        MOV     r7, r0
        ADR     r0, MessageBlock
        ADR     r1, MessageFileName
        MOV     r2, #0                  ; Use the file where she lies
        SWI     XMessageTrans_OpenFile
        ADRVC   r1, MessageBlock
        STRVC   r1, MessageBlockAddress
        MOV     r0, r7                  ; Preserve R0 even in the error case
DoErrorLookup
        MOV     r2, #0
        MOV     r3, #0
        MOV     r6, #0
        MOV     r7, #0
        SWIVC   XMessageTrans_ErrorLookup
        Pull    "r1-r3, r6, r7, pc"

MessageFileName
        DCB     "Resources:$.Resources.ModuleName.Messages", 0
        ALIGN

MessageTransGSLookup0
        Push    "r4, r5, lr"
        MOV     r4, #0
        MOV     r5, #0
        BL      MessageTransGSLookup2
        Pull    "r4, r5, pc"

MessageTransGSLookup1
        Push    "r5, lr"
        MOV     r5, #0
        BL      MessageTransGSLookup2
        Pull    "r5, pc"

MessageTransGSLookup2
        Push    "r6, r7, lr"
        LD      r0, MessageBlockAddress
        CMP     r0, #0                  ; Clears V
        BNE     DoGSLookup
        Push    "r1, r2"
        ADR     r0, MessageBlock
        ADR     r1, MessageFileName
        MOV     r2, #0                  ; Use the file where she lies
        SWI     XMessageTrans_OpenFile
        ADRVC   r0, MessageBlock
        STRVC   r0, MessageBlockAddress
        Pull    "r1, r2"
DoGSLookup
        MOV     r6, #0
        MOV     r7, #0
        SWIVC   XMessageTrans_GSLookup
        Pull    "r6, r7, pc"

        ]       ; UseMsgTrans

  I hope this is clear.

  Cheers, Bruce.