; Copyright 1996 Acorn Computers Ltd ; ; Licensed under the Apache License, Version 2.0 (the "License"); ; you may not use this file except in compliance with the License. ; You may obtain a copy of the License at ; ; http://www.apache.org/licenses/LICENSE-2.0 ; ; Unless required by applicable law or agreed to in writing, software ; distributed under the License is distributed on an "AS IS" BASIS, ; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ; See the License for the specific language governing permissions and ; limitations under the License. ; TTL => Middle ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; VecRdLine - Read line from input stream (OSWORD 0 equivalent) ;mjs June 2001, API redefined to support full 32-bit addresses ; In r0 -> buffer for characters ; r1 = max length of line (excluding carriage return), and flags in top 3 bits ; bit 31 *must* be set to indicate new API supporting 32-bit addresses ; bit 30 set means don't reflect characters that don't go in the buffer ; bit 29 set means reflect with the character in R4 ; r2 = lowest character put into buffer ; r3 = highest character put into buffer ; r4 = character to echo if r1 bit 29 is set ; wp -> OsbyteVars ; Out r0, r2, r3 corrupted ; r1 = length of line (excluding carriage return) ; C=0 => line terminated by return (CR or LF) ; C=1 => line terminated by ESCAPE ; For backward compatibility, supports old API, assuming address in r0 is ; safe (has top 2 bits clear). The old API uses bits 31,30 of r0 to ; specify flags as in bits 30,29 of r1 above. ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ VecRdLine ROUT Push "R4-R7" TST R1, #&80000000 ; check for old API ANDEQ R7, R0, #&C0000000 ORREQ R1, R1, R7, LSR #1 ORREQ R1, R1, #&80000000 BICEQ R0, R0, #&C0000000 ; if so, munge into new API AND R7, R1, #&E0000000 ; extract flags AND R4, R4, #&FF ORR R7, R7, R4 ; got flags, potential echo byte in R7 BIC R1, R1, #&E0000000 ; zap flags MOV R4, R0 ; R4 -> buffer MOV R6, #0 ; R6 = index into buffer STRB R6, PageModeLineCount ; reset page lines B %FT10 LTORG 05 SWI XOS_WriteC BVS ReadLine_Vset 10 SWI XOS_ReadC BVS ReadLine_Vset BCS %FT70 ; ESCAPE LDRB R5, WrchDest ; does output include VDU ? TST R5, #2 BNE %FT30 ; no, then still buffer LDRB R5, VDUqueueItems ; is VDU queueing ? TEQ R5, #0 BNE %BT05 ; yes, then just print 30 TEQ R0, #127 ; is it DELETE ? TEQNE R0, #8 ; or backspace? BNE %FT40 ; no, then skip TEQ R6, #0 ; yes, then have we any chars ? BEQ %BT10 ; no, then loop SUB R6, R6, #1 ; go back 1 char MOV R0, #127 B %BT05 ; print DEL and loop 40 TEQ R0, #21 ; is it CTRL-U ? BNE %FT50 ; no, then skip TEQ R6, #0 ; yes, then have we any chars ? BEQ %BT10 ; no, then loop 45 SWI XOS_WriteI+127 ; print DELs to start of line BVS ReadLine_Vset SUBS R6, R6, #1 BNE %BT45 B %BT10 ; then loop 50 TEQ R0, #13 ; is it CR ? TEQNE R0, #10 ; or LF ? MOVEQ r0, #13 ; always store CR if so STRB R0, [R4, R6] ; store byte in buffer BEQ %FT60 ; Exit if either CMP R6, R1 ; is buffer full ? MOVCS R0, #7 ; if so, beep and loop BCS %BT05 CMP R0, R2 ; is char >= min ? CMPCS R3, R0 ; and char <= max ? ADDCS R6, R6, #1 ; if so, then inc pointer BCS %FT80 TST R7, #&40000000 ; no reflection BNE %BT10 ; of non-entered chars 80 TST R7, #&20000000 ANDNE R0, R7, #&FF ; echo char -> R0 B %BT05 ; echo character 60 SWI XOS_NewLine BVS ReadLine_Vset ; insert code here to call NetVec with R0 = &0D 70 CLRV EndReadLine MOVVC R0, R4 ; restore R0 MOV R5, #0 LDRB R5, [R5, #ESC_Status] MOVS R5, R5, LSL #(32-6) ; shift esc bit into carry MOV R1, R6 ; R1 := length [ No26bitCode Pull "R4-R7, pc" ; Always claiming vector | Pull "R4-R7, lr" ; Always claiming vector BIC lr, lr, #V_bit :OR: C_bit MOV r12, pc AND r12, r12, #V_bit :OR: C_bit ORRS pc, lr, r12 ; back with C, V affected. ] ReadLine_Vset SETV B EndReadLine ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; SWI OS_Control (deprecated): set handlers SCTRL Push "R0-R3, lr" WritePSRc SVC_mode+I_bit, R0 ; need IRQs off to get consistent state MOV R0, #EventHandler MOV R1, R3 BL CallCESWI STR R1, [stack, #3*4] MOV R0, #EscapeHandler LDR R1, [stack, #2*4] BL CallCESWI STR R1, [stack, #2*4] MOV R0, #ErrorHandler Pull "R1, R3" BL CallCESWI MOV R0, R1 MOV R1, R3 Pull "R2, R3, lr" ExitSWIHandler CallCESWI Push lr MOV r2, #0 ; readonly SWI XOS_ChangeEnvironment Pull pc ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; SWI OS_SetEnv (deprecated): Environment setting SSTENV Push "R0, R1, lr" WritePSRc SVC_mode+I_bit, R0 ; no irqs - want consistent set. MOV R0, #AddressExceptionHandler MOV R1, R7 SWI XOS_ChangeEnvironment MOV R7, R1 MOV R0, #DataAbortHandler MOV R1, R6 SWI XOS_ChangeEnvironment MOV R6, R1 MOV R0, #PrefetchAbortHandler MOV R1, R5 SWI XOS_ChangeEnvironment MOV R5, R1 MOV R0, #UndefinedHandler MOV R1, R4 SWI XOS_ChangeEnvironment MOV R4, R1 MOV R0, #MemoryLimit LDR R1, [stack, #4] SWI XOS_ChangeEnvironment STR R1, [stack, #4] MOV R0, #ExitHandler Pull "R1" BL CallCESWI Push "R1" MOV R12, #0 LDR R2, [R12, #RAMLIMIT] ; this is read-only MOV R3, #0 ; never any Brazil-type buffering ; m2 tools will complain if there is! Pull "R0, R1, lr" ExitSWIHandler ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; Change user state SWIs ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ SINTON BIC lr, lr, #I32_bit ExitSWIHandler SINTOFF ORR lr, lr, #I32_bit ExitSWIHandler SENTERSWI TST lr, #2_11100 ORREQ lr, lr, #SVC26_mode ; 26-bit modes -> SVC26 BICNE lr, lr, #2_11111 ORRNE lr, lr, #SVC32_mode ; others -> SVC32 ExitSWIHandler SLEAVESWI BIC lr, lr, #2_01111 ExitSWIHandler ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; SWI OS_BreakPt: user breakpoint - unsuitable for debugging SVC mode code! SBRKPT ROUT ADD sp, sp, #4 ; discard stacked SWI number MOV r10, #0 LDR r10, [r10, #BrkBf] [ No26bitCode STR r12, [r10, #16*4] ; original PSR (with V) Pull r14 TST r12, #T32_bit SUBEQ r14, r14, #4 SUBNE r14, r14, #2 ; r14 = PC of the SWI TST r12, #2_01111 | FakeLR r11,,r12 ; r12+[sp] -> lr (r11 temp reg) SUB r14, r14, #4 ; r14 = PC of the SWI TST r14, #SVC_mode ] STR r14, [r10, #15*4] ; PC of the SWI put in. BNE %FT01 ; NE if not in user mode STMIA r10!, {r0} MOV r0, r10 LDMFD sp, {r10-r12} [ SASTMhatbroken STMIA r0!,{r1-r12} STMIA r0, {r13_usr,r14_usr}^ ; user mode case done. SUB r0, r0, #12*4 | STMIA r0, {r1-r12, r13_usr, r14_usr}^ ; user mode case done. NOP ] 10 LDR stack, =SVCSTK MOV r12, #BrkAd_ws LDMIA r12, {r12, pc} ; call breakpoint handler ; Non-user mode case 01 AND r11, r12, #2_01111 ; SVC26/SVC32 mode? TEQ r11, #SVC_mode BEQ %FT02 ; [yes] ; Non-user, non-supervisor - must be IRQ, ABT, UND or SYS (no SWIs from FIQ) STMIA r10!, {r0} MOV r0, r10 BIC r14, r12, #T32_bit ; don't go into Thumb mode LDMFD sp, {r10-r12} ; Not banked MSR CPSR_c, R14 ; get at registers r13 and r14 STMIA r0, {r1-r14} WritePSRc SVC_mode, r12 B %BT10 ; Supervisor mode case 02 MOV r14, r12 ; supervisor mode. R14 in buffer dead LDMFD sp!, {r10-r12} STMIA r14, {r0-r13} LDR r12, =&DEADDEAD STR r12, [r14, #14*4] ; mark R14 as dead B %BT10 ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; SWI OS_UnusedSWI (deprecated): Set the unused SWI handler SUNUSED Push "R1, lr" MOV R1, R0 MOV R0, #UnusedSWIHandler SWI XOS_ChangeEnvironment MOV R0, R1 Pull "R1, lr" ExitSWIHandler ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; SWI OS_SetCallBack: Set callback flag SSETCALL ROUT MSR CPSR_c, #I32_bit + SVC32_mode MOV r10, #0 LDRB r11, [r10, #CallBack_Flag] ORR r11, r11, #CBack_OldStyle STRB r11, [r10, #CallBack_Flag] ADD sp, sp, #4 ; Skip saved R11 B back_to_user_irqs_already_off ; Do NOT exit via normal mechanism ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; SWI read mouse information ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ VecMouse WritePSRc SVC_mode+I_bit, R10 MOV R10, #MouseV Push "lr" BL CallVector Pull "lr" ExitSWIHandler ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; SWI OS_SerialOp when not in kernel ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ SerialOp ROUT MOV r10, #SerialV Push lr BL CallVector Pull lr BICCC lr, lr, #C_bit ORRCS lr, lr, #C_bit B SLVK_TestV ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; Supervisor routines to set default handlers ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; Reset Error and Escape handlers DEFHAN LDR R1, =GeneralMOSBuffer ; decent length error buffer ADR R0, ERRORH ADR R2, ESCAPH MOV R3, #0 MOV R4, R14 SWI XOS_Control MOV r0, #UpCallHandler ADR r1, DefUpcallHandler MOV r2, #0 SWI XOS_ChangeEnvironment MOV PC, R4 ; Reset Exception, Event, BreakPoint, UnusedSWI, Exit and CallBack handlers DEFHN2 MOV R12, R14 MOV R0, #0 MOV R1, #0 MOV R2, #0 ADR R3, EVENTH SWI XOS_Control LDR R0, =DUMPER ADR R1, NOCALL SWI XOS_CallBack ADRL R0, CLIEXIT MOV R1, #0 MOV R2, #0 ADR R4, UNDEF ADRL R5, ABORTP ADRL R6, ABORTD ADRL R7, ADDREX SWI XOS_SetEnv LDR R0, =DUMPER ADR R1, DEFBRK SWI XOS_BreakCtrl ADRL R0, NoHighSWIHandler SWI XOS_UnusedSWI MOV PC, R12 ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; system handlers ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ DefUpcallHandler ESCAPH EVENTH MOV pc, lr NOCALL MOV r0, #0 ; default callback routine LDR r14, [r0, #CallBf] [ No26bitCode LDR r0, [r14, #4*16] MSR SPSR_cxsf, r0 ] LDMIA r14, {r0-r12, r13_usr, r14_usr}^ ; load user's regs NOP LDR r14, [r14, #4*15] MOVS pc, r14 ERRORH ROUT [ International ADR R0,KernelMessagesBlock+4 ADR R1,ErrorToken MOV R2,#0 SWI XMessageTrans_Lookup MOVVC R12,R2 ADRVS R12,ErrorText 01 LDRB R0,[R12],#1 CMP R0,#32 BLT %FT99 CMP R0,#"%" SWINE XOS_WriteC BVS %FT99 BNE %BT01 LDRB R0,[R12],#1 ; Found a % CMP R0,#32 BLT %FT99 CMP R0,#"0" LDREQ R0,=GeneralMOSBuffer+8 BEQ %FT10 CMP R0,#"1" BNE %BT01 LDR R3,=GeneralMOSBuffer+4 LDR R0,[R3] LDR R1,=MOSConvertBuffer MOV R2,#12 SWI XOS_ConvertHex8 02 LDRB R1, [R0], #1 CMP R1, #"0" BEQ %BT02 CMP R1, #0 SUBEQ R0, R0, #1 SUB R0, R0, #1 10 SWI XOS_Write0 BVC %BT01 99 SWI XOS_NewLine MOV R0, #0 STRB R0, [R0, #ErrorSemaphore] ; Enable error translation, in case we got here in the ; middle of looking up an error B GOSUPV ErrorToken = "Error:" ErrorText = "Error: %0 (Error Number &%1)",0 ALIGN | SWI OS_WriteS = 10,13,"Error:",10,13, 0 ALIGN LDR r0, =GeneralMOSBuffer+4 BL PrintError B GOSUPV ] DEFBRK [ International WritePSRc 0, lr MOV r0, r0 MOV r13, #0 LDR r13, [r13, #BrkBf] LDR r0, [r13, #15*4] LDR r1, =GeneralMOSBuffer MOV r2, #?GeneralMOSBuffer SWI OS_ConvertHex8 ; r0 -> address MOV R4,R0 ADR R0,KernelMessagesBlock+4 ADR R1,BreakToken LDR R2,=GeneralMOSBuffer+16 MOV R3,#256-16 SWI XMessageTrans_Lookup MOVVC R0,R2 ADRVS R0,BreakText SWI OS_Write0 SWI OS_NewLine | SWI OS_WriteS = "Stopped at break point at &", 0 ALIGN WritePSRc 0, lr MOV r0, r0 MOV r13, #0 LDR r13, [r13, #BrkBf] LDR r0, [r13, #15*4] LDR r1, =GeneralMOSBuffer MOV r2, #?GeneralMOSBuffer SWI OS_ConvertHex8 SWI OS_Write0 SWI OS_NewLine ] Quit_Code SWI OS_Exit [ International BreakToken = "BreakPt:" BreakText = "Stopped at break point at &%0",0 ALIGN ] PrintError MOV R12, R14 LDR R10, [R0], #4 SWI XOS_Write0 BVS %FT02 [ :LNOT: International SWI XOS_WriteS = " (Error number &", 0 BVS %FT02 ] LDR R1,=GeneralMOSBuffer MOV R2, #&E0 MOV R0, R10 SWI XOS_ConvertHex8 ; can't fail! 01 LDRB R1, [R0], #1 CMP R1, #"0" BEQ %BT01 CMP R1, #0 SUBEQ R0, R0, #1 [ International ; We might not have any stack so .. SUB R11,R0, #1 ; R11 -> Error number ADR R0, KernelMessagesBlock+4 ADR R1, PrintErrorString MOV R2,#0 ; Don't copy message SWI XMessageTrans_Lookup ADRVS R2,PrintErrorString+4 ; If no MessageTrans point at english text. 11 LDRB R0,[R2],#1 CMP R0,#32 BLT %FT13 CMP R0,#"%" SWINE XOS_WriteC BVS %FT13 BNE %BT11 LDRB R0,[R2],#1 CMP R0,#32 BLT %FT13 ; Just in case the % is the last character ! CMP R0,#"0" ; We only know about %0 BNE %BT11 12 LDRB R0,[R11],#1 ; Print error number. CMP R0,#32 BLT %BT11 SWI XOS_WriteC BVC %BT12 13 | SUB R0, R0, #1 SWI XOS_Write0 SWIVC XOS_WriteI+")" ] SWIVC XOS_NewLine 02 MOV PC, R12 [ International PrintErrorString = "Err: (Error number &%0)", 0 ALIGN ] LTORG ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; Exception handling DumpyTheRegisters ROUT [ No26bitCode ; In ABT32 or UND32, PC, PSR already stored, PSR in R1 MOV R4, R14 ; put error address into unbanked register TST R1, #&0F | ; In SVC26, fake 26-bit PC at 0 LDR R1, [R0, -R0] ; PC when exception happened STR R1, [R0, #(15-8)*4] ; In the right slot now ... TST R1, #SVC_mode ] [ SASTMhatbroken STMEQIA R0!,{R8-R12} STMEQIA R0, {R13,R14}^ ; user mode case done. SUBEQ R0, R0, #5*4 | STMEQIA R0, {R8-R14}^ ; user mode case done. ] BEQ UNDEF2 [ No26bitCode ORR R2, R1, #I32_bit :OR: F32_bit BIC R2, R2, #T32_bit MSR CPSR_c, R2 ; change into original mode STMIA R0, {R8-R14} ; save the banked registers AND R2, R1, #&0F EORS R2, R2, #FIQ_mode ; Was we in FIQ ? Zero if so MOVEQ R3, #IOC STREQB R2, [R3, #IOCFIQMSK] ; Blow away all FIQ sources UNDEF2 MSR CPSR_c, #I32_bit+F32_bit+SVC32_mode ; into SVC mode MOV R14, R4 ; corrupt R14_SVC (but already saved if we were in SVC) ; ... and fall into UNDEF1 | TST R1, #1 ; SWI mode? TSTNE R1, #2 BNE %FT02 ORR R1, R1, #I_bit :OR: F_bit ; keep interrupts off until handlers restored TEQP R1, #0 ; get at registers NOP STMIA R0, {R8-R14} TEQP PC, #SVC_mode :OR: I_bit :OR: F_bit AND R1, R1, #SVC_mode EORS R2, R1, #FIQ_mode ; Was we in FIQ ? Zero if so MOVEQ R3, #IOC STREQB R2, [R3, #IOCFIQMSK] ; Blow away all FIQ sources B UNDEF1 02 STMIA R0, {R8-R14} ; ... and fall into UNDEF2 UNDEF1 ] LDR sp, =SVCSTK ; Flatten superstack MOV R0, #0 LDR R0, [R0, #ExceptionDump] ADD R1, R0, #10*4 ; point at dumped R10 LDMIA R1, {R10-R12} ; try and put back user registers Push "R10-R12" ; for error handler to find on stack LDR R1, [R0, #15*4] Push R1 LDR R0, BranchThroughZeroInstruction ; load the B RESET1 instr. STR R0, [R1, -R1] ; and store it at zero again [ :LNOT:No26bitCode BIC R14, R14, #ARM_CC_Mask ] LDR R0, =GeneralMOSBuffer+128 ; so can do deviant sharing ! [ International MOV r10, #0 LDRB r10, [r10, #ErrorSemaphore] TEQ r10, #0 ; if ok to translate error MOVEQ r10, r14 BEQ %FT10 ] LDR r11, [r14], #4 ; Copy error number STR r11, [r0], #4 01 LDRB r11, [r14], #1 ; Copy error string STRB r11, [r0], #1 CMP r11, #"%" ; Test for "%" near end of string BNE %BT01 10 SUB r1, r0, #1 ; point, ready for conversion LDR R2, =GeneralMOSBuffer+?GeneralMOSBuffer SUB r2, r2, r1 ; amount left in buffer MOV R0, #0 LDR R0, [R0, #ExceptionDump] LDR R0, [R0, #15*4] ; saved PC [ :LNOT: No26bitCode BIC R0, R0, #ARM_CC_Mask ] SWI XOS_ConvertHex8 [ International MOV r4, #0 LDRB r4, [r4, #ErrorSemaphore] TEQ r4, #0 LDRNE R0, =GeneralMOSBuffer+128 MOVEQ R4, R0 MOVEQ R0, R10 BLEQ TranslateError_UseR4 | LDR R0, =GeneralMOSBuffer+128 ] [ No26bitCode ; Flatten UND and ABT stacks, jic MRS R2, CPSR BIC R2, R2, #F32_bit + &1F ORR R3, R2, #ABT32_mode MSR CPSR_c, R3 ; FIQs back on LDR r13_abort, =ABTSTK ORR R3, R2, #UND32_mode MSR CPSR_c, R3 LDR r13_undef, =UNDSTK ORR R3, R2, #IRQ32_mode MSR CPSR_c, R3 | TEQP PC, #IRQ_mode+I_bit ] MOV R1, #0 STR R1, [R1, #IRQsema] LDR SPIRQ, =IRQSTK SWI OS_GenerateError LTORG UNDEF ROUT [ No26bitCode ; In UND32 mode, with a stack Push R14 SETPSR F_bit :OR: I_bit, R14 | TEQP pc, #F_bit :OR: I_bit :OR: SVC_mode ; FIQ off too STR R14, [R0, -R0] ] MOV R14, #0 LDR R14, [R14, #ExceptionDump] STMIA R14!, {R0-R7} [ No26bitCode MRS R1, SPSR STR R1, [R14, #(16-8)*4] ; save PSR Pull R0 STR R0, [R14, #(15-8)*4] ; save PC ] MOV R0, R14 BL DumpyTheRegisters MakeErrorBlock UndefinedInstruction ABORTP ROUT [ No26bitCode ; In ABT32 mode, with a stack Push R14 SETPSR F_bit :OR: I_bit, R14 | TEQP pc, #F_bit :OR: I_bit :OR: SVC_mode ; FIQ off too STR R14, [R0, -R0] ] MOV R14, #0 LDR R14, [R14, #ExceptionDump] STMIA R14!, {R0-R7} [ No26bitCode MRS R1, SPSR STR R1, [R14, #(16-8)*4] ; save PSR Pull R0 STR R0, [R14, #(15-8)*4] ; save PC ] MOV R0, R14 BL DumpyTheRegisters MakeErrorBlock InstructionAbort ABORTD ROUT [ No26bitCode ; In ABT32 mode, with a stack Push R14 SETPSR F_bit :OR: I_bit, R14 | TEQP pc, #F_bit :OR: I_bit :OR: SVC_mode ; FIQ off too STR R14, [R0, -R0] ] MOV R14, #0 LDR R14, [R14, #ExceptionDump] STMIA R14!, {R0-R7} [ No26bitCode MRS R1, SPSR STR R1, [R14, #(16-8)*4] ; save PSR Pull R0 STR R0, [R14, #(15-8)*4] ; save PC ] MOV R0, R14 BL DumpyTheRegisters MakeErrorBlock DataAbort ADDREX ROUT ; This really can't happen. Honest [ No26bitCode MSR CPSR_c, #F32_bit :OR: I32_bit :OR: SVC32_mode ; FIQ off too STR R14, [R0, -R0] | TEQP pc, #F_bit :OR: I_bit :OR: SVC_mode ; FIQ off too STR R14, [R0, -R0] ] MOV R14, #0 LDR R14, [R14, #ExceptionDump] STMIA R14!, {R0-R7} MOV R0, R14 [ No26bitCode MRS R1, SPSR STR R1, [R14, #(16-8)*4] ; save PSR LDR R14, [R0, -R0] STR R14, [R14, #(15-8)*4] ] BL DumpyTheRegisters MakeErrorBlock AddressException ; Can branch through zero in any mode RESET1 ROUT STR R1, [R0, -R0] MOV R1, #0 LDR R1, [R1, #ExceptionDump] STMIA R1, {R0-R14} [ No26bitCode MOV R0, #0 STR R0, [R1, #15*4] MRS R0, CPSR STR R0, [R1, #16*4] | MRS R0, CPSR ; Fake up a combined PC+PSR (PC=0) AND R1, R0, #I32_bit :OR: F32_bit AND R0, R0, #&F0000003 ORR R0, R0, R1, LSL #IF32_26Shift MOV R1, #0 LDR R1, [R1, #ExceptionDump] STR R0, [R1, #15*4] ] LDR R0, [R0, -R0] STR R0, [R1, #1*4] SWI XOS_EnterOS BL UNDEF1 MakeErrorBlock BranchThrough0 BranchThroughZeroInstruction [ ProcessorVectors LDR PC, .+ProcVec_Branch0 | B .+(RESET1-0) ] ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; SWI to call the UpCall vector ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ DoAnUpCall ROUT Push lr ; better have one of these to pull later ! [ No26bitCode MRS r12, CPSR BIC r12, r12, #&F0000000 BIC r12, r12, #I32_bit:OR:F32_bit AND r10, lr, #&F0000000 ; copy user flags (I bit clear) ORR r10, r10, r12 MSR CPSR_cf, r10 ; ints on, stay in SVC mode, flags in psr | AND r10, lr, #&F0000000 ; copy user flags (I_bit clear) TEQP r10, #SVC_mode ; ints on, stay in SVC mode, flags in psr ] MOV r10, #UpCallV BL CallVector Pull lr BIC lr, lr, #&F0000000 [ No26bitCode MRS R10, CPSR MOV R10, R10, LSR #(32-4) | MOV R10, PC, LSR #(32-4) ] ORR lr, lr, R10, LSL #(32-4) ExitSWIHandler ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; SWI OS_ChangeEnvironment: Call the environment change vector ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ChangeEnvironment ROUT Push lr MOV R10, #ChangeEnvironmentV BL CallVector Pull lr B SLVK_TestV ; ..... and the default handler ..... AdjustOurSet WritePSRc SVC_mode+I_bit, R14 CMP R0, #MaxEnvNumber BHI AOS_Silly [ False CMP r0, #CallBackHandler BLEQ testcallbackpending ] ADR R10, AOS_Table ADD R11, R0, R0, LSL #1 ; number * 3 ADD R10, R10, R11, LSL #2 ; point at entry MOV R12, R1 LDR R11, [R10] CMP R11, #0 LDRNE R1, [R11] CMPNE R12, #0 STRNE R12, [R11] MOV R12, R2 LDR R11, [R10, #4] CMP R11, #0 LDRNE R2, [R11] CMPNE R12, #0 STRNE R12, [R11] MOV R12, R3 LDR R11, [R10, #8] CMP R11, #0 LDRNE R3, [R11] CMPNE R12, #0 STRNE R12, [R11] [ No26bitCode Pull pc | Pull pc,,^ ] AOS_Silly ADR r0, ErrorBlock_BadEnvNumber [ International BL TranslateError ] exit_AOS [ No26bitCode SETV Pull "pc" | Pull "lr" ORRS pc, lr, #V_bit ] MakeErrorBlock BadEnvNumber [ False testcallbackpending CMP r1, #0 ; OK if only reading CMPEQ r2, #0 CMPEQ r3, #0 LDRNEB r10, [r0, #CallBack_Flag-CallBackHandler] TSTNE r10, #CBack_OldStyle MOVEQ pc, r14 SetBorder r0, r14, 15, 0, 0 ADR r0, ErrorBlock_CallbackPending B exit_AOS MakeErrorBlock CallbackPending ] AOS_Table & MemLimit ; MemoryLimit & 0 & 0 & UndHan ; UndefinedHandler & 0 & 0 & PAbHan ; PrefetchAbortHandler & 0 & 0 & DAbHan ; DatabortHandler & 0 & 0 & AdXHan ; AddressExceptionHandler & 0 & 0 & 0 ; OtherExceptionHandler & 0 & 0 & ErrHan ; ErrorHandler & ErrHan_ws & ErrBuf & CallAd ; CallBackHandler & CallAd_ws & CallBf & BrkAd ; BreakPointHandler & BrkAd_ws & BrkBf & EscHan ; EscapeHandler & EscHan_ws & 0 & EvtHan ; EventHandler & EvtHan_ws & 0 & SExitA ; ExitHandler & SExitA_ws & 0 & HiServ ; UnusedSWIHandler & HiServ_ws & 0 & ExceptionDump ; ExceptionDumpArea & 0 & 0 & AplWorkSize ; application space size & 0 & 0 & Curr_Active_Object & 0 & 0 & UpCallHan & UpCallHan_ws & 0 assert (.-AOS_Table)/12 = MaxEnvNumber ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; SWI OS_ReadDefaultHandler ; In r0 = environment number ReadDefaultHandler ROUT CMP r0, #(dhte-defhantab)/12 MOVHS r0, #0 ; return wally value ADD r10, r0, r0, LSL #1 ; *3 ADD r10, pc, r10, LSL #2 ; *4 (pc = defhantab-4) LDMIB r10, {r1-r3} ; gives additional +4 ExitSWIHandler defhantab & 0 ; wally entry & 0 & 0 & UNDEF ; UndefinedHandler & 0 & 0 & ABORTP ; PrefetchAbortHandler & 0 & 0 & ABORTD ; DataAbortHandler & 0 & 0 & ADDREX ; AddressExceptionHandler & 0 & 0 & 0 ; OtherExceptionHandler & 0 & 0 & ERRORH ; ErrorHandler & 0 & GeneralMOSBuffer & NOCALL ; CallBackHandler & 0 & DUMPER & DEFBRK ; BreakPointHandler & 0 & DUMPER & ESCAPH ; EscapeHandler & 0 & GeneralMOSBuffer & EVENTH ; EventHandler & 0 & 0 & CLIEXIT ; ExitHandler & 0 & 0 & NoHighSWIHandler ; UnusedSWIHandler & 0 & 0 & 0 ; exception dump & 0 & 0 & 0 ; app space size & 0 & 0 & 0 ; cao pointer & 0 & 0 & DefUpcallHandler ; upcall handler & 0 & 0 dhte ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; In r0 = sysinfo handle ; Out r0 = sysinfo for r0in ReadSysInfo_Code ROUT CMP r0, #1 BCC %FT00 ; r0 = 0 BEQ %FT10 ; r0 = 1 CMP r0, #3 BCC %FT20 ; r0 = 2 BEQ %FT30 ; R0 = 3 CMP r0, #5 BCC %FT40 ; R0 = 4 BEQ %FT50 ; R0 = 5 CMP r0, #7 BCC %FT60 ; R0 = 6 BEQ %FT70 ; R0 = 7 CMP r0, #9 BCC %FT80 ; R0 = 8 ; R0 = 9 not allocated yet (BEQ %FT90) ; R0 > 8, so illegal value ADR r0, ErrorBlock_BadReadSysInfo [ International Push "lr" BL TranslateError Pull "lr" ] ORR lr, lr, #V_bit ExitSWIHandler MakeErrorBlock BadReadSysInfo ; ReadSysInfo(0) - return configured screensize in r0 00 Push "r1, r2, lr" MOV r0, #ReadCMOS MOV r1, #ScreenSizeCMOS SWI XOS_Byte AND r0, r2, #&7F ; top bit is reserved MOV r10, #0 LDR r10, [r10, #Page_Size] MUL r0, r10, r0 BL MassageScreenSize ; adjust for min and max or default values Pull "r1, r2, lr" ExitSWIHandler ; ReadSysInfo(1) - returns configured mode/wimpmode in r0 ; configured monitortype in r1 ; configured sync in r2 ; (all de-autofied) 10 Push "r3-r5, lr" BL Read_Configd_Sync MOV r2, r0 [ ModeSelectors LDR r1, =VduDriverWorkSpace+CurrentMonitorType ; read current monitortype LDR r1, [r1] | BL Read_Configd_MonitorType MOV r1, r0 ] BL Read_Configd_Mode CMP r0, #-1 ; if none of the three are auto, don't bother with translation CMPNE r1, #-1 CMPNE r2, #-1 BNE %FT15 BL TranslateMonitorLeadType ; issue service or work it out ourselves CMP r0, #-1 ; if mode auto MOVEQ r0, r3 ; then replace with default CMP r1, #-1 ; if monitortype auto MOVEQ r1, r4 ; then replace with default CMP r2, #-1 ; if sync auto MOVEQ r2, r5 ; then replace with default 15 Pull "r3-r5, lr" ExitSWIHandler ; ReadSysInfo(2) ; ; in: r0 = 2 ; ; out: r0 = hardware configuration word 0 ; bits 0-7 = special functions chip type ; 0 => none ; 1 => IOEB ; bits 8-15 = I/O control chip type ; 0 => IOC ; 1 => IOMD ; bits 16-23 = memory control chip type ; 0 => MEMC1/MEMC1a ; 1 => IOMD ; bits 24-31 = video control chip type ; 0 => VIDC1a ; 1 => VIDC20 ; r1 = hardware configuration word 1 ; bits 0-7 = I/O chip type ; 0 => absent ; 1 => 82C710/711 or SMC'665 or similar ; bits 8-31 reserved (set to 0) ; r2 = hardware configuration word 2 ; bits 0-7 = LCD controller type ; 0 => absent ; 1 => present (type 1) eg A4 portable ; 2 => present (type 2) eg Stork portable ; bits 8-15 = IOMD variant ; 0 => IOMD ; 1 => IOMDL ie ARM7500 (Morris) ; bits 16-23 = VIDC20 variant ; 0 => VIDC20 ; 1 => VIDC2L ie ARM7500 (Morris) ; bits 24-31 = miscellaneous flags ; bit 24 0 => IIC bus slow (100kHz) ; 1 => IIC bus fast (400kHz) ; bit 25 0 => keep I/O clocks running during idle ; 1 => stop I/O clocks during idle ; bits 26-31 reserved (set to 0) ; r3 = word 0 of unique machine ID, or 0 if unavailable ; r4 = word 1 of unique machine ID, or 0 if unavailable ; Bits in IOSystemType IOST_COMBOMASK * 7 IOST_82C710 * 1 IOST_82C711 * 2 IOST_37C665 * 3 IOST_37C669 * 4 IOST_UMC669 * 5 IOST_IOEB * 8 ; On IOMD systems this really means IOMD. IOST_LC * 16 [ MorrisSupport IOST_7500 * 32 ;Running on ARM7500 (Morris) so actually IOMDL and VIDC2L IOST_BATMAN * 64 ;Stork keyboard/battery controller seems to be present ] [ HAL 20 Push "r9,r14" AddressHAL SUB sp, sp, #12 ADD a1, sp, #0 ADD a2, sp, #4 ADD a3, sp, #8 CallHAL HAL_HardwareInfo MOV r12, #0 LDR r3, [r12, #RawMachineID+0] LDR r4, [r12, #RawMachineID+4] Pull "r0-r2,r9,r14" ExitSWIHandler | 20 MOV r0, #0 LDR r3, [r0, #RawMachineID+0] LDR r4, [r0, #RawMachineID+4] MOV r3, r3, LSR #8 ; lose first 8 bits ORR r3, r3, r4, LSL #24 ; and put bits 0..7 of r3 into bits 24..31 of r2 MOV r4, r4, LSL #8 ; lose CRC bits MOV r4, r4, LSR #16 ; and move the rest down to the bottom LDRB r0, [r0, #IOSystemType] ANDS r2, r0, #IOST_LC MOVNE r2, #1 ; make r2 0 or 1 [ MorrisSupport TST r0, #IOST_BATMAN MOVNE r2, #2 ;NE, its a Stork portable TST r0, #IOST_7500 ORRNE r2, r2, #&00000100 ;NE, Morris based machine with IOMDL ORRNE r2, r2, #&00010000 ;NE, and VIDC2L ] MOV r1, #0 LDRB r1, [r1, #NVRamSpeed] SUB r1, r1, #1 ; catch zero = slow (just in case) CMP r1, #3-1 ; speed is 3 for 400kHz, 10 for 100kHz. ORRLS r2, r2, #&01000000 ; indicate fast speed [ StopClocksDuringIdle ORR r2, r2, #&02000000 ] ANDS r1, r0, #IOST_COMBOMASK MOVNE r1, #1 ; make r1 0 or 1 LDR r0, =&01010100 ExitSWIHandler ] ; ReadSysInfo(3) ; ; in: r0 = 3 ; ; out: r0 = I/O chip base features mask 710 711 665 669 UMC669 ; Bits 0..3 Base IDE type 1 1 1 1 1 ; Bits 4..7 Base FDC type 1 1 1 1 1 ; Bits 8..11 Base parallel type 1 1 1 1 1 ; Bits 12..15 Base 1st serial type 1 1 1 1 1 ; Bits 16..19 Base 2nd serial type 0 1 1 1 1 ; Bits 20..23 Base Config type 1 2 3 4 5 ; Bits 24..31 Reserved 0 0 0 0 0 ; ; r1 = I/O chip extra features mask 710 711 665 669 UMC669 ; Bits 0..3 IDE extra features 0 0 0 0 0 ; Bits 4..7 FDC extra features 0 0 0 0 0 ; Bits 8..11 parallel extra features 0 0 1 1 1 ; Bits 12..15 1st serial extra features 0 0 1 1 1 ; Bits 16..19 2nd serial extra features 0 0 1 1 1 ; Bits 20..23 config extra features 0 0 0 0 0 ; Bits 24..31 Reserved 0 0 0 0 0 ; ; r2-r4 undefined (reserved for future expansion) ; 30 [ HAL Push "r9,r14" AddressHAL SUB sp, sp, #8 ADD a1, sp, #0 ADD a2, sp, #4 CallHAL HAL_SuperIOInfo Pull "a1,a2,r9,r14" ExitSWIHandler | MOV r0, #0 ; used as index and as default value LDRB r1, [r0, #IOSystemType] ANDS r1, r1, #IOST_COMBOMASK TEQ r1, #IOST_82C710 LDREQ r0, =&00101111 MOVEQ r1, #0 TEQ r1, #IOST_82C711 LDREQ r0, =&00211111 MOVEQ r1, #0 CMP r1, #IOST_37C665 [ ReassignedIOMDInterrupts ; If the device numbers have been reassigned, we can't really call the devices compatible. ; Also, we've lost the floppy and hard disc interrupts, so mark as not present. LDRHS r0, =&00022200 | LDRHS r0, =&00011111 ] ORRHS r0, r0, r1, LSL #20 LDRHS r1, =&00011100 MOV r2, #0 MOV r3, #0 MOV r4, #0 ExitSWIHandler ] ; OS_ReadSysInfo 4 (SWI &58) ; ; On entry: r0 = 4 (reason code) ; ; On exit: r0 = LSW of Ethernet Network Address (or 0) ; r1 = MSW of Ethernet Network Address (or 0) ; ; Use: Code loaded from the dedicated Network Expansion Card or ; from a normal Expansion Card should use the value returned ; by this call in preference to a locally provided value. 40 MOV r0, #0 LDRB r1, [ r0, #RawMachineID ] ; The family byte TEQ r1, #&81 ; Is this a custom part? BNE ExitNoEthernetAddress LDR r1, [ r0, #RawMachineID+4 ] ; Acorn's ID and part# [ True BIC r1, r1, #&FF000000 ; Remove the CRC LDR r0, =&0050A4 ; Acorn's ID is &005 | ; Version for no checking of Manufacture's ID MOV r1, r1, LSL #20 MOV r1, r1, LSR #20 ; Remove CRC and ID LDR r0, =&0A4 ] TEQ r1, r0 ; Is this one of our chips? BNE ExitNoEthernetAddress MOV r0, #0 LDR r0, [ r0, #RawMachineID ] MOV r0, r0, LSR #8 ; Lose family byte LDR r1, =&0000A4100000 ; Base Ethernet address ADD r0, r1, r0 ; Add Dallas part to base [ STB TST r0, #1:SHL:23 ; Check not overflowed into secondary range BNE ExitNoEthernetAddress MOV r1, r0, LSR #24 ; Check not overflowed out of Acorn's range TEQ r1, #&A4 BNE ExitNoEthernetAddress ] MOV r1, #0 ; Top 16 bits are zero ExitSWIHandler ExitNoEthernetAddress [ :LNOT: STB MOV r0, #0 MOV r1, #0 ExitSWIHandler | Push "r2,lr" MOV r1, #Service_MachineAddress ; See if anyone else can provide it BL Issue_Service TEQ r1, #0 MOVEQ r1, r2 BLNE GetMachineAddressCMOS Pull "r2,lr" ExitSWIHandler ] [ STB NVRAM_TAG_MACAddress = "MACAddress", 0 NVRAM_TAG_MACAddressChecksum = "MACAddressChecksum", 0 NVRAM_TAG_MACAddress2nd = "MACAddress2nd", 0 NVRAM_TAG_MACAddressChecksum2nd = "MACAddressChecksum2nd", 0 ALIGN GetMachineAddressCMOS ; Out: r0 = lower 4 bytes (or 0) ; r1 = upper 2 bytes (or 0) ; EQ => valid, NE => invalid ; Entry "r2-r5", 8 ; Preserve these + get 8 bytes workspace ADR r0,NVRAM_TAG_MACAddress ADR r3,NVRAM_TAG_MACAddressChecksum BL CheckOneCopyOfMachineAddressCMOS ; Get 1st copy of MAC in r0=low 4 bytes, ; r1=upper 2 bytes of MAC in bytes 0,1 stored checksum in byte 2, calculated checksum in byte 3 [ MACNVRAM2copies MOV r4,r0 MOV r5,r1 ADR r0,NVRAM_TAG_MACAddress2nd ADR r3,NVRAM_TAG_MACAddressChecksum2nd BL CheckOneCopyOfMachineAddressCMOS ; Get 2nd copy of MAC CMP r0,r4 CMPEQ r1,r5 BNE %FT41 ; Have different values - i.e one (possibly both) is wrong/broken ] ;two copies of MAC MOV r2,r1,LSR#16 ; move checksum values into low bytes AND r3,r2,#&ff ; r3=stored checksum MOV r2,r2,LSR#8 ; r2=calculated checksum CMP r2,r3 ; do the checksums match BNE %FT43 ; if not then we have unrecoverable fault, both values identical but checksums broken ; this would be the case for an unprogrammed CMOS MOV r2,#&ff ORR r2,r2,r2,LSL#8 ; mask for removing checksums AND r1,r1,r2 ; #&0000ffff remove checksums from r1 EXIT ; return with valid MAC in r0,r1 and flags set to EQ by branch just above [ MACNVRAM2copies ;two copies differ 41 MOV r2,r5,LSR#16 ; move checksum for 1st copy into low bytes AND r3,r2,#&ff ; r3=stored checksum MOV r2,r2,LSR#8 ; r2=calculated checksum CMP r2,r3 ; do the checksums match BEQ %FT45 ; okay need to repair second set MOV r2,r1,LSR#16 ; move checksum for 2nd copy into low bytes AND r3,r2,#&ff ; r3=stored checksum MOV r2,r2,LSR#8 ; r2=calculated checksum CMP r2,r3 ; do the checksums match BEQ %FT46 ; okay need to repair first set ] ;we arrive here if we have a situation from which no sensible MAC can be derived ;i) both values are broken 43 MOV r0,#0 MOV r1,#0 EXIT ;return with r0,r1 both zero to indicate no valid address, two possible paths here both have NE flags [ MACNVRAM2copies ;checksum is valid for first set so repair second set 45 ADR r3,NVRAM_TAG_MACAddress2nd ADR r0,NVRAM_TAG_MACAddressChecksum2nd B %FT47 ;checksum is valid for second set so repair first set 46 MOV r4,r0 ;get values of 2nd set into write registers MOV r5,r1 ADR r3,NVRAM_TAG_MACAddress ADR r0,NVRAM_TAG_MACAddressChecksum ;store MAC (+ check sum) in r4,r5, and checksum in r2 to NVRAM tags given by r0 and r3 47 [ 1=2 ; forgot that NVRAM_Write will fail ; on locked locations such as .. the MAC addresses... ; this will be modified shortly to call a new SWI provided ; by the NVRAM module to turn a tag into an address and ; then perform the write using routines in the i2cutils ; section of the kernel. MOV r1, sp ;some workspace STRB r2, [r1,#0] ;store the checksum MOV r2, #1 SWI XNVRAM_Write ;TST r0, #&80000000 ; Check for errors ;BNE %FT48 ; Oh dear BIC r5,r5,#&ffff0000 ;get rid of checksum - we already have a value in r2 extracted earlier MOV r0,r3 ;NVRAM_TAG_MACAddress MOV r1,sp ;workspace MOV r3,r5 STRB r3,[r1,#1] MOV r3,r3,LSR#8 STRB r3,[r1,#0] MOV r3,r4 STRB r3,[r1,#5] MOV r3,r3,LSR#8 STRB r3,[r1,#4] MOV r3,r3,LSR#8 STRB r3,[r1,#3] MOV r3,r3,LSR#8 STRB r3,[r1,#2] MOV r2,#6 SWI XNVRAM_Write ;TST r0, #&80000000 ; Check for errors ;BNE %FT48 ; Oh dear ] ;return with the values from r4,r5 in r0,r1 and flags eq ;48 MOV r0,r4 MOV r1,r5 CMP r1,r1 ;make flags equal - is this required? EXIT ] ; MACNVRAM2copies ;On entry r0 points to MAC address Tag name ; r3 points to Checksum Tag name CheckOneCopyOfMachineAddressCMOS Entry ,8 MOV r1, sp MOV r2, #6 SWI XNVRAM_Read MOVVS r0, #&ffffffff TST r0, #&80000000 ; Check for errors BNE MachineAddressNVRAMError MOV r0, r3 ADD r1, sp, #6 MOV r2, #1 SWI XNVRAM_Read MOVVS r0, #&ffffffff TST r0, #&80000000 ; Check for errors BNE MachineAddressNVRAMError MOV r0, #0 MOV r1, #0 LDRB r3, [sp, #0] ; Get the first byte into checksum MOV r1, r3, ASL #8 ; Store into result LDRB r2, [sp, #1] ; Get the next byte ADD r3, r3, r2 ; Add to the checksum ORR r1, r1, r2, ASL #0 ; Store into the result LDRB r2, [sp, #2] ; Get the next byte ADD r3, r3, r2 ; Add to the checksum MOV r0, r2, ASL #24 ; Store into the result LDRB r2, [sp, #3] ; Get the next byte ADD r3, r3, r2 ; Add to the checksum ORR r0, r0, r2, ASL #16 ; Store into the result LDRB r2, [sp, #4] ; Get the next byte ADD r3, r3, r2 ; Add to the checksum ORR r0, r0, r2, ASL #8 ; Store into the result LDRB r2, [sp, #5] ; Get the next byte ADD r3, r3, r2 ; Add to the checksum ORR r0, r0, r2, ASL #0 ; Store into the result LDRB r2, [sp, #6] ; Get the checksum AND r3, r3, #&FF EOR r3, r3, #&FF ORR r1,r1,r2,LSL#16 ;put stored checksum in byte 2 ORR r1,r1,r3,LSL#24 ;put calculated checksum in byte 3 49 EXIT MachineAddressNVRAMError MOV r0,#0 MOV r1,#0 EXIT ] ; OS_ReadSysInfo 5 ; ; On entry: r0 = 5 (reason code) ; ; On exit: r0 = LSW of Raw data from Dallas Chip ; r1 = MSW of Raw data from Dallas Chip 50 MOV r0, #0 LDR r1, [r0, #RawMachineID+4] LDR r0, [r0, #RawMachineID+0] ExitSWIHandler ; OS_ReadSysInfo 6 - read kernel values (Acorn use only; eg. SoftLoad, ROMPatch) ; ; On entry: r0 = 6 (reason code) ; r1 -> input block, 1 word per entry, giving number of value required, terminated by -1 ; OR: r1 = 0 if just 1 value is required, and this is to beturned in r2 ; r2 -> output block, 1 word per entry, will be filled in on output ; OR: r2 = number of single value required, if r1 = 0 ; ; On exit: ; if r1 entry != 0: ; r0,r1,r2 preserved ; output block filled in, filled in value(s) set to 0 if unrecognised/no longer meaningful value(s) ; if r1 entry = 0: ; r0,r1 preserved ; r2 = single value required, or set to 0 if if unrecognised/no longer meaningful value ; ; valid value numbers available - see table below ; 60 Push "r0-r3" ADR r3,osri6_table CMP r1,#0 BEQ %FT64 62 LDR r0,[r1],#4 CMP r0,#-1 BEQ %FT66 CMP r0,#osri6_maxvalue MOVHI r0,#0 LDRLS r0,[r3,r0,LSL #2] STR r0,[r2],#4 B %BT62 64 CMP r2,#osri6_maxvalue MOVHI r2,#0 LDRLS r2,[r3,r2,LSL #2] STR r2,[sp,#2*4] 66 Pull "r0-r3" ExitSWIHandler osri6_table DCD CamEntriesPointer ;0 DCD MaxCamEntry ;1 DCD PageFlags_Unavailable ;2 DCD PhysRamTable ;3 DCD 0 ;4 (was ARMA_Cleaner_flipflop, no longer exists in HALised kernel) DCD TickNodeChain ;5 DCD ROMModuleChain ;6 DCD DAList ;7 DCD AppSpaceDANode ;8 DCD Module_List ;9 DCD ModuleSHT_Entries ;10 DCD ModuleSWI_HashTab ;11 DCD IOSystemType ;12 DCD L1PT ;13 DCD L2PT ;14 DCD UNDSTK ;15 DCD SVCSTK ;16 DCD SysHeapStart ;17 osri6_maxvalue * 17 ; OS_ReadSysInfo 7 - read 32-bit Abort information for last unexpected abort ; (prefetch or data) ; ; On entry: r0 = 6 (reason code) ; ; On exit: r1 = 32-bit PC for last abort ; r2 = 32-bit PSR for last abort ; r3 = fault address for last abort (same as PC for prefetch abort) ; 70 Push "r0" LDR r0, =Abort32_dumparea LDR r1, [r0,#2*4] LDR r2, [r0] LDR r3, [r0,#4] Pull "r0" ExitSWIHandler ; OS_ReadSysInfo 8 - Returns summary information on host platform. ; ; On entry: ; r0 = 8 (reason code 8) ; ; On exit: ; r0 = platform class ; currently defined classes are: ; 0 = unspecified platform (r1,r2 will be 0) ; 1 = Medusa (currently returned for Risc PC only) ; 2 = Morris (currently returned for A7000 only) ; 3 = Morris+ (currently returned for A7000+ only) ; 4 = Phoebe (currently returned for Risc PC 2 only) ; all other values currently reserved ; r1 = 32 additional platform specifier flags (if defined) ; bits 0..31 = value of flags 0..31 if defined, 0 if undefined ; r2 = defined status of the 32 flags in r1 ; bits 0..31 = status of flags 0..31 ; 0 = flag is undefined in this OS version ; 1 = flag is defined in this OS version ; ; The current flag definitions for r1 (1=supported, 0=unsupported) are : ; ; 0 = Podule expansion card(s) ; 1 = PCI expansion card(s) ; 2 = additional processor(s) ; 3 = auto power off ; 4..31 reserved (currently undefined) ; 80 [ HAL MOV r0, #5 MOV r1, #0 MOV r2, #0 ExitSWIHandler | Push "r3-r5" ADR r3, %86 MOV r4, #IOMD_Base LDRB r4, [r4, #IOMD_ID0] 82 LDR r5, [r3], #4 TEQ r5, #&80000000 ;terminator TEQNE r5, r4 LDMEQIA r3, {r0-r2} BEQ %FT84 ADD r3, r3, #3*4 B %BT82 84 Pull "r3-r5" ExitSWIHandler 86 DCD IOMD_Original :AND: &FF, 1, &00000001, &0000000F DCD IOMD_7500 :AND: &FF, 2, &00000001, &0000000F DCD IOMD_7500FE :AND: &FF, 3, &00000001, &0000000F DCD IOMD_IOMD2 :AND: &FF, 4, &0000000F, &0000000F DCD &80000000, 0, 0, 0 ;terminator ] LTORG END