; 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. ; SUBT => NewReset ; Reset types SoftReset * 0 PowerOnReset * 1 ControlReset * 2 ; CMOS RAM resetting stuff: CMOSLimit * &F0 ; Keyboard scan KbdFlag_Ctrl * 1:SHL:0 KbdFlag_Shift * 1:SHL:1 KbdFlag_R * 1:SHL:4 KbdFlag_T * 1:SHL:5 KbdFlag_Delete * 1:SHL:6 KbdFlag_Copy * 1:SHL:7 KbdFlag_Present * 1:SHL:30 KbdFlag_Done * 1:SHL:31 ; GetConfiguredSize - convert CMOS address into amount of memory ; in: r0 = CMOS address ; out: r0 corrupted ; r2 = amount in bytes ; NB this routine doesn't do screen size mangling (yet!) GetConfiguredSize Entry "r1" LDR r1, =ZeroPage LDR r1, [r1, #Page_Size] ADRL lr, PageShifts-1 LDRB r1, [lr, r1, LSR #12] ; r1 = log2 pagesize MOV r2, #127 ; mask of value TEQ r0, #FontCMOS ; if fontsize MOVEQ r1, #12 ; then in units of 4K, not pagesize MOVEQ r2, #255 ; and use full byte BL Read ; read CMOS ram AND r2, r0, r2 ; value anded with mask MOV r2, r2, LSL r1 ; and shifted up accordingly EXIT ; MassageScreenSize - called from screen DA creation and ReadSysInfo MassageScreenSize ROUT Push lr LDR lr, =ZeroPage LDR lr, [lr, #VideoSizeFlags] TST lr, #OSAddRAM_VRAMNotForGeneralUse MOVNE r0, lr, LSR #12 MOVNE r0, r0, LSL #12 Pull pc, NE CMP r0, #0 BNE CmosScreenWillDo [ ZeroPage <> 0 LDR r0, =ZeroPage ] LDR r0, [r0, #RAMLIMIT] CMP r0, #(512*1024):SHR:12 MOVEQ r0, #80*1024 MOVNE r0, #160*1024 CmosScreenWillDo CMP r0, #20*1024 ; ensure mode 0 gettable ADDCC r0, r0, r10 ; if not, then add another page BCC CmosScreenWillDo CMP r0, #ScreenMaxSize MOVHI r0, #ScreenMaxSize Pull pc LTORG CONT_Break AddressHAL MOV a1, #1 [ LongDesc :LAND: ShortDesc PTWhich a2 LDRNE a2, =LL1PT LDREQ a2, =L1PT ELIF LongDesc LDR a2, =LL1PT ; Probably not very useful (L2PT would be better) | LDR a2, =L1PT ] CallHAL HAL_Reset ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; Entry point from HALInit Continue_after_HALInit ; Initialise the RW data segment IMPORT |Image$$RW$$Base| IMPORT |Image$$RO$$Limit| IMPORT |Image$$ZI$$Base| LDR R0, =|Image$$RW$$Base| LDR R1, =|Image$$RO$$Limit| LDR R2, =|Image$$ZI$$Base| 31 CMP R0, R2 LDRNE R3, [R1], #4 STRNE R3, [R0], #4 BNE %BT31 [ USE_SYNCLIB ; Initialise synclib IMPORT synclib_init BL synclib_init ] ; AbortTrap DebugTX "aborttrap_init" IMPORT aborttrap_init BL aborttrap_init ; OK, there is quite a bit of code poking below, to various addresses. We'll ; defer IMB consideration till the poking's done, then do a full IMB (full ; data cache clean). This avoids various little IMB's and removes chance of leaving ; some unnoticed poked code in data cache. The deferral should be safe, because none ; of the poked code will be used yet awhile (given that current IRQ hardware vector is ; not actually changed below). ; Copy default processor vector table and default preveneers. ; Code relies on preveneers being immediately after processor vector table ; but could easily be changed into 2 copy loops. ASSERT ProcVecPreVeneers = ProcVec_End ASSERT DefaultPreVeneers = DefaultProcVecs+ProcVec_End-ProcVec_Start ADRL R0, DefaultProcVecs LDR R1, =ZeroPage+ProcVec_Start MOV R2, #ProcVec_End-ProcVec_Start+ProcVecPreVeneersSize 39 LDR R3, [R0], #4 STR R3, [R1], #4 SUBS R2, R2, #4 BNE %BT39 ; copy handler addresses ADRL R1, MOSROMVecs+4 ; don't copy to 0: key stuff is using ; it as workspace! LDR R0, =ZeroPage+4 LDR R3, =ZeroPage+EndMOSROMVecs-MOSROMVecs 40 LDR R2, [R1], #4 ; N.B. IRQ handler better be same as the one in there STR R2, [R0], #4 TEQ R0, R3 BNE %BT40 ChangedProcVecs r0 ; Now copy the initialised data LDR R0, =ZeroPage+IRQ1V ADRL r1, StartData LDR R3, =ZeroPage+(EndData-StartData+IRQ1V) DatCopy LDR R2, [R1], #4 STR R2, [R0], #4 TEQ R0, R3 BNE DatCopy ADR r2, CONT_Break LDR r0, =ZeroPage STR r2, [r0, #ResetIndirection] MOV r3, #0 ; zero-initialise key bits of workspace [ CompatibilityPage STRB r3, [r0, #CompatibilityPageEnabled] ] ; Now the SWI despatch + low part of SWI table ADRL R3, DirtyBranch LDR R0, =SWIDespatch SVCTabCopy ; so copy the table LDR R2, [R1], #4 STR R2, [R0], #4 TEQ R1, R3 BNE SVCTabCopy ; pad to 1K table here, rather than use ROM space ADRL R2, NoSuchSWI LDR R4, =1024+SvcTable ; end of table PadSVCTable CMP R0, R4 STRNE R2, [R0], #4 BNE PadSVCTable ; now the dirty branch LDR R1, [R1] STR R1, [R0] ; conversion SWIs all go through same despatch point LDR R0, =SvcTable ADRL R1, despatchConvert STR R1, [R0, #OS_ConvertStandardDateAndTime * 4] STR R1, [R0, #OS_ConvertDateAndTime * 4] MOV R2, #OS_ConvertHex1 conversionSWIfill STR R1, [R0, R2, LSL #2] ADD R2, R2, #1 CMP R2, #OS_ConvertVariform BLS conversionSWIfill ; OK, that completes the poking around, some of which is code. Now let's ; do a full IMB type thing, to be safe ; LDR r0, =ZeroPage ARMop IMB_Full,,,r0 DebugTX "IMB_Full done" [ CacheablePageTables ; If we want cacheable page tables, now is a good time to enable them ; (can't easily enable them earlier on due to the page tables being temporarily ; doubly-mapped during MMU init) PTOp MakePageTablesCacheable ] [ CacheCMOSRAM DebugTX "InitCMOSCache entry" BL InitCMOSCache ; initialise cache of CMOS RAM TEQ R0, #0 ; returns zero on failure [ ZeroPage <> 0 LDREQ R0, =ZeroPage ] LDREQ R1, [R0, #HAL_StartFlags] ORREQ R1, R1, #OSStartFlag_NoCMOS STREQ R1, [R0, #HAL_StartFlags] BEQ %FT41 DebugTX "InitCMOSCache done" B %FT42 41 DebugTX "InitCMOSCache failed" 42 ] ; Initialise CAO ptr to none. LDR R0, =ZeroPage LDR R1, =DuffEntry ; nothing will be here!! STR R1, [R0, #Curr_Active_Object] ; Get creating the essential areas DebugTX "InitDynamicAreas" BL InitDynamicAreas ; RMA Push "r0-r12" MOV r1, #ChangeDyn_RMA ; Area number MOV r2, #4096 ; Initial size MOV r3, #RMAAddress ; Base address MOV r4, #AreaFlags_RMA ; Area flags MOV r5, #RMAMaxSize ; Maximum size ADRL r6, DynAreaHandler_RMA ; Pointer to handler MOV r7, r3 ; Workspace ptr points at area itself ADRL r8, AreaName_RMA ; Title string - node will have to be reallocated ; after module init, to internationalise it BL DynArea_Create ; ignore any error, we're stuffed if we get one! Pull "r0-r12" ; Screen Push "r0-r12" MOV r0, #ScreenSizeCMOS BL Read LDR r5, =ZeroPage LDR r10, [r5, #Page_Size] ; needed by MassageScreenSize MUL r0, r10, r0 ; convert to bytes LDR r5, [r5, #VideoSizeFlags] ; maximum size MOV r5, r5, LSR #12 MOV r5, r5, LSL #12 BL MassageScreenSize ; Clamps the initial size regardless of the ; contents of the ScreenSizeCMOS MOV r1, #ChangeDyn_Screen ; area number MOV r2, r0 ; initial size MOV r3, #-1 ; Base address dynamic LDR r4, =AreaFlags_Screen ; area flags ADRL r6, DynAreaHandler_Screen ; handler VDWS r7 ; workspace pointer MOV r8, #0 STR r8, [r7, #CursorFlags] ; put zero in CursorFlags as an indication that VDU not yet inited STR r2, [r7, #TotalScreenSize] ADRL r8, AreaName_Screen ; area name BL DynArea_Create STR r3, [r7, #ScreenEndAddr] Pull "r0-r12" MOV R0, #ChangeDyn_FreePool ; 512k of RAM in AplSpace should be plenty for ROM init. MOV R1, #512*1024 ; Theoretically we don't need any at all, but having some there RSB R1, R1, #0 ; should make it easier to debug any ROM init failures. SWI XOS_ChangeDynamicArea LDR R1, =ZeroPage LDR R2, [R1, #AplWorkSize] STR R2, [R1, #MemLimit] MOV R0, #AppSpaceStart MOV R1, #0 SUB R2, R2, R0 BL memset ; Clear AplSpace DebugTX "InitVectors" BL InitVectors ; ready for OsByte to read mode LDR R1, =ZeroPage+ModuleSWI_HashTab MOV R2, #ModuleSHT_Entries MOV R0, #0 clearmswis SUBS R2, R2, #1 STR R0, [R1, R2, LSL #2] BGT clearmswis [ International [ ZeroPage <> 0 LDR R2, =ZeroPage ] MOV R1, #-1 ; We don't have a message file yet ! STRB R1, [R2, #ErrorSemaphore] ; Don't translate errors. STR R0, [R2, #KernelMessagesBlock] ; No message file open. [ CacheCommonErrors STR R0, [R2, #CachedErrorBlocks] ; No cached errors ] ] ; Make the choice between PowerOn and Hard reset based purely on ; the state of the POR bit and NOT on whether memory was cleared. LDR R0, =ZeroPage+HAL_StartFlags LDR R1, [R0] TST R1, #OSStartFlag_POR MOVNE R0, #PowerOnReset MOVEQ R0, #ControlReset LDR R1, =ZeroPage+OsbyteVars + :INDEX: LastBREAK STRB R0, [R1] DebugTX "InitIRQ1" BL InitialiseIRQ1Vtable LDR R3, =ZeroPage ADRL R1, Default_PIRQHandler_Node STR R1, [R3, #PIRQ_Chain] STR R1, [R3, #PFIQasIRQ_Chain] ASSERT Default_PFIQasIRQHandler_Node = Default_PIRQHandler_Node MOV R0, #0 ; put in IRQ handler, word at 0 STRB r0, [r3, #FIQclaim_interlock] STRB r0, [r3, #CallBack_Flag] STR r0, [r3, #CallBack_Vector] STR r0, [r3, #TickNodeChain] ; Create the Branch Through 0 Trampoline in the system heap MOV R3, #Branch0_Trampoline_Size BL ClaimSysHeapNode ADRVCL R0, Branch0_Trampoline ASSERT Branch0_Trampoline_Init = 20 LDMVCIA R0, {R1,R3,R4,R5,R14} STMVCIA R2, {R1,R3,R4,R5,R14} LDRVC R0, =ZeroPage STRVC R2, [R0, #ProcVec_Branch0] LDR R1, BranchThroughZeroInstruction2 STR R1, [R0] ; put branch through 0 code at 0 LDR R1, RealIRQHandler STR R1, [R0, #&18] DebugTX "IMB_Full" ; we need to do an IMB type thing for modifying code in vector area, ; and for copying irq handler code ARMop IMB_Full,,,r0 ChangedProcVecs r0 LDR r0,=ZeroPage MOV R1, #&100 STR R1, [R0, #RCLimit] MOV R1, #0 STR R1, [R0, #ReturnCode] ; now put in error handler and escape handler BL DEFHAN BL DEFHN2 MOV R0, #ExceptionDumpArea LDR R1, =ZeroPage+DUMPER SWI XOS_ChangeEnvironment VDWS WsPtr ; main MOS initialisation DebugTX "VduInit" BL VduInit DebugTX "ExecuteInit" BL ExecuteInit DebugTX "KeyInit" BL KeyInit DebugTX "OscliInit" BL OscliInit ; before initialising modules DebugTX "Enabling IRQs" WritePSRc SVC_mode, R14 ; enable IRQs DebugTX "IRQs on" [ DebugTerminal MOV R0, #RdchV ADRL R1, DebugTerminal_Rdch LDR R2, =ZeroPage LDR R2, [R2, #HAL_Workspace] SWI XOS_Claim MOV R0, #WrchV ADRL R1, DebugTerminal_Wrch SWI XOS_Claim DebugTX "Debug terminal on" ] BL InitialiseMode ; select correct screen mode, in case any ; module prints anything in initialisation DebugTX "HAL_InitDevices" AddressHAL MOV R0, #0 [ ZeroPage = 0 STR R0, [R0, #DeviceCount] STR R0, [R0, #DeviceTable] | LDR R1, =ZeroPage STR R0, [R1, #DeviceCount] STR R0, [R1, #DeviceTable] ] CallHAL HAL_InitDevices ; get HAL to register any devices it has BL LookForHALCacheController DebugTX "InitVariables" BL InitVariables DebugTX "AMBControl_Init" BL AMBControl_Init ; initialise AMBControl section AddressHAL CallHAL HAL_KbdScanDependencies MOV r5, r0 DebugTX "ModuleInitForKbdScan" BL ModuleInitForKbdScan ; minimal post module setup for keyboard scan BL KeyPostInit ; scan keyboard for interesting keypresses R/T/Delete/End + Ctrl/Shift or timeout LDR r3, =ZeroPage LDR r6, [r3, #HAL_StartFlags] TST r6, #OSStartFlag_RAMCleared MOVEQ r6, #0 ; RAM clear from start of free pool MOVNE r6, #-1 ; RAM clear not needed LDR r3, [r3, #MetroGnome] ADD r3, r3, #300 ; timeout (cs) 02 CMP r5, #-1 ; HAL gave no KbdScan details BEQ %FT04 TST r4, #KbdFlag_Present BNE %FT03 LDR r0, =ZeroPage+KeyWorkSpace LDRB r0, [r0, #:INDEX:KbId] ; check if anyone registered with KeyV CMP r0, #&20 ; same limit as GetCountry BCS %FT04 ORR r4, r4, #KbdFlag_Present DebugTX "KbdFlag_Present" 03 MOV r0, #OsByte_INKEY MOV r1, #0 :EOR: &7F ; scan from shift upwards MOV r2, #255 SWI XOS_Byte TEQ r1, #0 ORREQ r4, r4, #KbdFlag_Shift TEQ r1, #1 ORREQ r4, r4, #KbdFlag_Ctrl TEQ r1, #51 ORREQ r4, r4, #KbdFlag_R TEQ r1, #35 ORREQ r4, r4, #KbdFlag_T TEQ r1, #89 ORREQ r4, r4, #KbdFlag_Delete TEQ r1, #105 ORREQ r4, r4, #KbdFlag_Copy 04 SWI XOS_LeaveOS SWI XOS_EnterOS ; callbacks ; Prior to getting here, ClearWkspRAM cleared low OS workspace & ScratchSpace, and ; Init_MapInRAM_Clear has selectively cleared other early allocations. That leaves ; everything from InitDynamicAreas ; RMA => not cleared, it's in use ; Screen => not cleared, the next CLS will do that ; and ; AplSpace (first 512k) => cleared unconditionally ; Free pool => clear now if HAL didn't ; left to do. MOV r0, r6 BL ClearFreePoolSection MOV r6, r0 CMP r6, #-1 BNE %BT02 ; the show's not over until the RAM clear is done CMP r5, #-1 BEQ %FT05 ; HAL gave no KbdScan details TST r4, #KbdFlag_Shift :OR: KbdFlag_Ctrl :OR: KbdFlag_R :OR: KbdFlag_T :OR: KbdFlag_Delete BNE %FT05 ; exciting key press beats a timeout LDR r0, =ZeroPage LDR r0, [r0, #MetroGnome] CMP r0, r3 ; timed out? BCC %BT02 05 ORR r4, r4, #KbdFlag_Done Push "r4" ; save until after MOSInit ; Clear temp ws skipped earlier LDR R0, =ZeroPage+InitWsStart MOV R1, #0 MOV R2, #InitWsEnd - InitWsStart BL memset cmos_checks MOV R3, #-1 ; do all CMOS if we do any [ ValidateCMOS ; Do a POR if some super-critical values are shagged or if checksum is invalid. BL ValChecksum ; Always check the checksum BNE cmos_reset ] ; IF power-on bit set AND R/T/Del/Copy pressed THEN reset CMOS RAM LDR R0, =ZeroPage+HAL_StartFlags LDR R1, [R0] TST R1, #OSStartFlag_NoCMOS ; If no CMOS, reset for sensible cache BNE cmos_reset TST R1, #OSStartFlag_POR BEQ no_cmos_reset ; not a power on reset DebugTX "POR detected" TST R1, #OSStartFlag_NoCMOSReset BNE no_cmos_reset TST R1, #OSStartFlag_CMOSReset BNE cmos_reset TST R4, #KbdFlag_R:OR:KbdFlag_T:OR:KbdFlag_Delete:OR:KbdFlag_Copy LDRNE R3, =ZeroPage MOVNE R14, #1 STRNEB R14, [R3, #MentionCMOSReset] BEQ no_cmos_reset ; power on bit checked again there ; CMOS reset detectified. ; Wipe it, then squirt in the MOS's table of default values TST R4, #KbdFlag_Copy:OR:KbdFlag_Delete MOVNE R3, #-1 ; Del or Copy does all RAM MOVEQ R3, #UserCMOS ; R or T just system [ ChecksumCMOS BL ValChecksum ; unless the CMOS ram's corrupt .. MOVNE R3, #-1 ; .. then blast it anyway. ] cmos_reset DebugTX "Reset CMOS" MOV R4, #0 cmrlp CMP R3, #-1 BEQ cmrall ; ignore system-only wipe checks CMP R4, #UserCMOS MOVEQ R4, #&50 ; skip User (30-45) & 3rd party (46-59) & high podules (60-79) BEQ cmrall CMP R4, #PoduleCMOS MOVEQ R4, #&80 ; skip low podules (112-127) BEQ cmrall TEQ R4, #NewADFSCMOS ; documented in 'Troubleshooting' in TEQNE R4, #CountryCMOS ; the RISC OS 3.7 user guide as preserved BEQ cmrskip cmrall MOV R1, R4 BL NVMemory_ResetValue ; get the reset value MOVS R1, R2 ; when -ve, leave alone MOVPL R0, R4 BLPL Write ; CMOS(R0) := R1 cmrskip ADD R4, R4, #1 CMP R4, #CMOSLimit BCC cmrlp ; IF R or Delete pressed THEN set sync 0 ELSE set sync Auto LDR R4, [SP] TST R4, #KbdFlag_R:OR:KbdFlag_Delete MOV R0, #VduCMOS MOVNE R1, #MonitorTypeAuto :OR: Sync_Auto ; if R or Del MOVEQ R1, #MonitorTypeAuto :OR: Sync_Separate ; if T or Copy BL Write [ ChecksumCMOS BL MakeChecksum ; create a valid checksum ] B init_other_modules no_cmos_reset MOV r0, #SystemSpeedCMOS BL Read BIC r1, r0, #CMOSResetBit ; clear bit indicating CMOS reset MOV r0, #SystemSpeedCMOS BL Write init_other_modules ; init that's deferrable until the CMOS is sanitised DebugTX "ReadDefaults" BYTEWS WsPtr BL ReadHardCMOSDefaults BL ReadCMOSDefaults DebugTX "InitHostedDAs" BL InitHostedDAs DebugTX "MouseInit" BL MouseInit ; now go back and load the other modules, scan podules, accounting for frugal bits DebugTX "ModuleInit" BL ModuleInit MOV R0, #0 ; shrink sysheap as far as will go. SUB R1, R0, #4*1024*1024 SWI XOS_ChangeDynamicArea MOV R0, #ReadCMOS MOV R1, #SysHeapCMOS SWI XOS_Byte AND R2, R2, #2_111111 ; mask to same size as status LDR R0, =ZeroPage LDR R0, [R0, #Page_Size] MUL R3, R0, R2 ; size spare wanted BL ClaimSysHeapNode MOV R0, #HeapReason_Free SWI XOS_Heap MOV R0, #ReadCMOS MOV R1, #FileLangCMOS SWI XOS_Byte MOV R1, R2 MOV R0, #FSControl_SelectFS ; set configured filing system SWI XOS_FSControl ; Update territory in case it changed after ModuleInitForKbdScan MOV R0, #ReadCMOS MOV R1, #TerritoryCMOS SWI XOS_Byte EOR R0, R2, #1 ; encoded so that 0 => TerritoryNum_UK SWI XTerritory_Select ; Update RTC now all the modules are running SWI XOS_ResyncTime [ DebugROMInit SWI XOS_WriteS = "Service_PostInit",0 SWI XOS_NewLine ] MOV r1, #Service_PostInit ; issue post-initialisation service BL Issue_Service [ DebugROMInit SWI XOS_WriteS = "callbacks",0 SWI XOS_NewLine ] SWI XOS_LeaveOS SWI XOS_EnterOS ; switch back to SVC mode (IRQs, FIQs enabled) [ International ; Open the kernel messages file. LDR r0, =ZeroPage+KernelMessagesBlock+4 ADRL r1, MessageFileName MOV r2, #0 ; Use file directly. SWI XMessageTrans_OpenFile MOVVC r0, #-1 LDRVC lr, =ZeroPage STRVC r0, [lr, #KernelMessagesBlock] ; Message file is now open. ASSERT (ZeroPage :AND: 255) = 0 ; if we've managed to open message file STRVCB lr, [lr, #ErrorSemaphore] ; then allow errors to be translated ] ; OS_ReadSysInfo 9,2 now relies on the Territory module, which may ; enable IRQs. But the PRMs say OS_ReadSysInfo shouldn't alter the IRQ ; state. So call it once here just to initialise the string which it ; uses the Territory module to generate. ; This won't account for any modules using it during ModuleInit, but ; that should be pretty rare (or at least rare from within IRQ-sensitive ; code) ; ; Must also be after Service_PostInit to give TerritoryManager opportunity ; to load disc based territories. MOV R0, #9 MOV R1, #2 SWI XOS_ReadSysInfo [ UseNewFX0Error ; Also, *FX 0 BL InitNewFX0Error ] [ CompatibilityPage ; Enable low zero page compatibility page MOV R0, #OSMemReason_Compatibility MOV R1, #1 SWI XOS_Memory ] BL InitialiseMode LDR R0, =ZeroPage LDRB R14, [R0, #MentionCMOSReset] TEQ R14, #0 BEQ %FT12 [ International SWI XOS_WriteI+10 BVS %FT09 BL WriteS_Translated = "CmosRst:CMOS RAM reset, press ESCAPE to continue",0 ALIGN 09 | SWI XOS_WriteS = 10,"CMOS RAM reset, press ESCAPE to continue",0 ALIGN ] 10 SWI XOS_ReadEscapeState BCC %BT10 MOV R0, #OsByte_ClearEscape SWI XOS_Byte ; Clear the condition SWI XOS_WriteI+12 ; Clear the screen 12 SWI XOS_WriteS = 10, "$SystemName ", 0 ; now RISC OS (no +) again ALIGN MOV R0, #8 ORR R0, R0, #&500 SWI XOS_Memory ; returns amount of soft ROM (pages) in r1 MOVVS R1, #0 LDR R0, =ZeroPage LDR R0, [R0, #RAMLIMIT] ADD R0, R0, R1 MOV R0, R0, LSR #20-Log2PageSize ; down to megabytes LDR R1, =GeneralMOSBuffer MOV R2, #?GeneralMOSBuffer SWI XOS_ConvertInteger4 SWI XOS_Write0 SWI XOS_WriteS = "MB", 10,13, 10, 0 ; title complete ALIGN BL ARM_PrintProcessorType MOV r0, #0 ; Set DomainId to 0 every reset [ ZeroPage = 0 STR r0, [r0, #DomainId] ; before calling anyone | LDR r1, =ZeroPage STR r0, [r1, #DomainId] ; before calling anyone ] ; issue reset service call MOV R1, #Service_Reset SWI XOS_ServiceCall ; now set up the default FIQ owner MOV R1, #Service_ClaimFIQ SWI XOS_ServiceCall MOV R1, #Service_ReleaseFIQ SWI XOS_ServiceCall BL PostInit SWI XOS_WriteI+7 ; go beep! Yaay! ; Now that ROM modules have mostly finished allocating memory, move a large ; chunk of the free memory from the free pool into application space so that ; the boot sequence and configured language have something to play around with ; (particularly if booting into BASIC!) ; However be careful not to move everything, otherwise anything which locks ; application space during boot could cripple important background processes ; like USB LDR r0, =ZeroPage LDR r1, [r0, #AplWorkSize] LDR r0, [r0, #FreePoolDANode+DANode_PMPSize] CMP r0, #DynArea_PMP_BigPageCount MOVLO r0, r0, LSL #12 LDRHS r0, =DynArea_PMP_BigByteCount SUB r1, r1, #32*1024 SUB r1, r1, r0 MOV r1, r1, ASR #1 ; 50% each sounds fair MOV r0, #ChangeDyn_FreePool SWI XOS_ChangeDynamicArea MOV r0, #OsByte_RW_LastResetType MOV r1, #0 MOV r2, #&FF SWI XOS_Byte CMP r1, #PowerOnReset BNE %FT70 LDR r1, =ZeroPage+HAL_StartFlags LDR r1, [r1] TST r1, #OSStartFlag_NoCMOSReset BNE %FT70 ; if any keypad-numeric key pressed, reconfigure monitor type MOV r0, #OsByte_ScanKeyboard ; scan keyboard MOV r1, #&FF ; starting at (&FF + 1) AND &FF 60 ADD r1, r1, #1 AND r1, r1, #&FF SWI XOS_Byte TEQ r1, #&FF ; if no key down BEQ %FT70 ; then give up ADR r2, MonitorKeypadTable 62 LDRB r14, [r2], #2 ; search for key in table TEQ r14, #&FF BEQ %FT70 ; give up, key not in table TEQ r1, r14 BNE %BT62 LDRB r3, [r2, #-1] ; get corresponding CMOS bits MOV r0, #ReadCMOS MOV r1, #VduCMOS SWI XOS_Byte BIC r2, r2, #MonitorTypeBits ORR r2, r2, r3 MOV r0, #WriteCMOS SWI XOS_Byte TEQ r3, #MonitorTypeAuto ; if we're setting monitortype auto BNE %FT64 ADRL r0, ModeCMOSTable +8 ; then configure mode auto LDR r2, [r0, #-8] ; (load auto value) BL WriteMultiField ADRL r0, SyncCMOSTable +8 ; and configure sync auto LDR r2, [r0, #-8] ; (load auto value) BL WriteMultiField 64 BL InitialiseMode [ International SWI XOS_WriteI+10 BVS %FT65 BL WriteS_Translated = "MonType:Monitor type reconfigured",10,13,10,0 ALIGN 65 | SWI XOS_WriteS = 10,"Monitor type reconfigured",10,13,10,0 ALIGN ] B %FT70 RealIRQHandler LDR PC, .-&18+ProcVec_IRQ BranchThroughZeroInstruction2 LDR PC, .+ProcVec_Branch0 LTORG MonitorKeypadTable ; internal key number, CMOS bits = 106, MonitorType0 = 107, MonitorType1 = 124, MonitorType2 = 108, MonitorType3 = 122, MonitorType4 = 123, MonitorType5 = 26, MonitorType6 = 27, MonitorType7 = 42, MonitorType8 = 43, MonitorType9 = 76, MonitorTypeAuto ; keypad dot = &FF ALIGN 32 [ International MessageFileName DCB "Resources:$.Resources.Kernel.Messages",0 ALIGN ] 70 ; Deal with SHIFT pressed/SHIFT-BREAK configured: ; do appropriate FSControl if wanted Pull "R4" ; recover KbdFlag bits TST R4, #KbdFlag_Present ; first check kbd there BNE shifty_boot [ International BL WriteS_Translated = "NoKbd:No keyboard present - autobooting", 10,13,0 ALIGN | SWI XOS_WriteS = 7, "No keyboard present - autobooting", 10,13,0 ALIGN ] B Hortoculture_Kicking shifty_boot MOV R0, #OsByte_RW_StartupOptions MOV R1, #0 MOV R2, #&FF ; read shifty state SWI XOS_Byte TST R4, #KbdFlag_Shift EORNE R1, R1, #8 ; invert sense TST R1, #8 BNE %FT80 ; no boot when set Hortoculture_Kicking MOV R0, #FSControl_BootupFS SWI XOS_FSControl BVC %FT80 Push "r3,r4" ADD r1, r0, #4 ; Set Boot$Error if it failed (Desktop will report it). ADR r0, str_booterror MOV r2, #1024 ; Big enough that terminator will be reached. MOV r3, #0 MOV r4, #VarType_String SWI XOS_SetVarVal SUBVS r0, r1, #4 ; If setting Boot$Error failed then report original error as before. BLVS PrintError SWIVS XOS_NewLine Pull "r3,r4" 80 ; if keypad-* pressed, drop into * prompt MOV r0, #OsByte_INKEY MOV r1, #KeyScan_NumPadStar :AND: &FF MOV r2, #&FF SWI XOS_Byte TEQ r1, #&FF TEQEQ r2, #&FF BEQ DoStartSuper ; EQ -> start up supervisor ; Start configured language module if keypad-* wasn't pressed MOV R0, #ReadCMOS MOV R1, #LanguageCMOS SWI XOS_Byte MOV R0, #ModHandReason_GetNames SUB R1, R2, #1 MOV R2, #0 ; preferred incarnation SWI XOS_Module ADRVSL R3, UtilityMod LDR R2, [R3, #Module_TitleStr] CMP R2, #0 ADDNE R1, R3, R2 DoStartSuper ADREQL R1, UtilModTitle ; ALWAYS enter via SWI: sets CAO etc. MOV R0, #ModHandReason_Enter ADRL R2, crstring ; no environment SWI XOS_Module CMP r0, r0 ; set EQ if failed to enter config.lang B DoStartSuper ; -> force Super entry str_booterror DCB "Boot$$Error",0 ALIGN END