; 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. ; ; > $.Source.PMF.osinit ; ***************************************************************************** ExecuteInit ROUT Push R14 ; Point to OsbyteVars ; and initialise them BYTEWS WsPtr LDRB R4, LastBREAK ; 1 => power-on, 2 => hard CMP R4, #PowerOnReset ADREQ R2, PowerOnResetVars ADRNE R2, HardResetVars MOV R3, #0 STR R3, TimerAlpha +0 ; zero both copies of TIME STR R3, TimerAlpha +4 STR R3, TimerBeta +0 STR R3, TimerBeta +4 MOV R1, #32 ; default FX11 and FX12 STRB R1, KeyRepDelay MOV R1, #8 STRB R1, KeyRepRate MOV R1, WsPtr ; start at the beginning ADR R11, ByteVarInitTable ByteVarInitLoop LDRB R0, [R11], #1 ; copy a byte from table STRB R0, [R1], #1 ; to vars TEQ R1, R2 ; at end ? BNE ByteVarInitLoop ; [no, then loop] STRB R3, NoIgnore ; zero NoIgnore STRB R4, LastBREAK ; put LastBREAK back ; Initialise buffer pointers LDR R0, =ZeroPage+4*(NBuffers-1) ; index to pointer MOV R1, #0 ; value to store MOV R2, #NBuffers-1 BuffPtrInitLoop STR R1, [R0, #BuffInPtrs] STR R1, [R0, #BuffOutPtrs] SUB R0, R0, #4 SUBS R2, R2, #1 BPL BuffPtrInitLoop ; mark printer as dormant STR R1, PrinterActive ; (R1=0) ; initialise SpriteSize to zero (fixes bug MED-00811) LDR R2, =ZeroPage STR R1, [R2, #SpriteSize] ; Initialise event semaphores ADR R0, EventSemaphores ADD R2, R0, #32 10 STR R1, [R0], #4 ; clear all 32 event semaphores TEQ R0, R2 BNE %BT10 STRB R1, FlashState STRB R1, SerialInHandle ; zero serial handles STRB R1, SerialOutHandle ; Initialise LatchB and soft copy ; MOV R1, #0 ; AND with 0 (was omitted on earlier MOS) ; R1 already zero MOV R0, #0 ; EOR with 0 BL UpdateLatchB LDR R1, =ZeroPage MOV R0, #4_3330 ; Assume VGA during osinit STRB R0, [R1, #MonitorLeadType] BL ReadUniqueID Push "r9,r12" AddressHAL MOV R0, #0 CallHAL HAL_TimerDevice MOV R4, R0 CallHAL HAL_IRQClear ; clear timer 0 IRQ MOV R0, R4 CallHAL HAL_IRQEnable ; enable timer 0 IRQ Pull "r9,r12" ; The RTC driver is later on in the module chain, or missing, for now default the ; system time to UNIX epoch + 1 day (so time() doesn't return -1) secs0070 * (86400*(365*70+18)) ; from time() in risc_oslib.c.armsys LDR R7, =(secs0070 * 100) ; centiseconds LSW MOV R8, #&33 ; centiseconds MSW BL Store5ByteInRealTime ; insert soft key 10 MOV R2, #&CA BL RDCHS Pull PC LTORG ; ***************************************************************************** ; ; InitHostedDAs - Set up the dynamic areas that we kindly host on ; behalf of other parts of the OS (SpriteUtils, RamFS, Font Manager) InitHostedDAs Push "r0-r12, lr" ; SpriteArea MOV r0, #SpriteSizeCMOS ; find out how much spritesize configured BL GetConfiguredSize ; in: r0 = CMOS address, out: r2 = size MOV r1, #ChangeDyn_SpriteArea ; Area number MOV r3, #-1 ; Base address dynamic MOV r4, #AreaFlags_Sprites ; Area flags MOV r5, #16*1024*1024 ; Maximum size (changed from -1, address space preservation) ADRL r6, DynAreaHandler_Sprites ; Pointer to handler MOV r7, #-1 ; Use base address as workspace ptr ADRL r8, AreaName_SpriteArea ; 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! ; RAMDisc MOV r1, #ChangeDyn_RamFS ; Area number MOV r3, #-1 ; Base address dynamic ARM_read_ID r4 AND r4, r4, #&F000 CMP r4, #&A000 MOVEQ r4, #AreaFlags_RAMDisc_SA ; Area flags, if StrongARM (introduced for Ursula) MOVNE r4, #AreaFlags_RAMDisc ; Area flags [ PMPRAMFS MOV r5, #PMPRAMFS_Size*4096 ORR r4, r4, #DynAreaFlags_PMP MOV r2, #0 ORR r4, r4, #DynAreaFlags_NeedsSpecificPages MOV r9, #0 | MOV r0, #RAMDiscCMOS ; find out how much RAM disc configured BL GetConfiguredSize ; in: r0 = CMOS address, out: r2 = size MOV r5, #128*1024*1024 ; A trade off between nice big disc and complete waste of address space ] ADRL r6, DynAreaHandler_RAMDisc ; Pointer to handler MOV r7, #-1 ; Use base address as workspace ptr ADRL r8, AreaName_RAMDisc ; 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! [ PMPRAMFS ; Currently, physical memory pools must be created with 0 size, then resized afterwards MOV r0, #RAMDiscCMOS ; find out how much RAM disc configured BL GetConfiguredSize ; in: r0 = CMOS address, out: r2 = size MOVS r1, r2 MOV r0, #ChangeDyn_RamFS SWINE XOS_ChangeDynamicArea ] ; FontArea MOV r0, #FontCMOS ; find out how much font cache configured BL GetConfiguredSize ; in: r0 = CMOS address, out: r2 = size MOV r1, #ChangeDyn_FontArea ; Area number MOV r3, #-1 ; Base address dynamic MOV r4, #AreaFlags_FontArea ; Area flags MOV r5, #32*1024*1024 ; Maximum size changed from -1 for Ursula (limit address ; space usage on large memory machines) ADRL r6, DynAreaHandler_FontArea ; Pointer to handler MOV r7, #-1 ; Use base address as workspace ptr ADRL r8, AreaName_FontArea ; 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, pc" ; ***************************************************************************** ; ; ReadHardCMOSDefaults - Read CMOS values for a hard/power-on reset ; On entry WsPtr -> BYTEWS ReadHardCMOSDefaults Push R14 MOV R0, #PigCMOS BL Read STRB R0, PrinterIgnore MOV R0, #PSITCMOS BL Read TST R0, #2 ; NoIgnore bit MOVEQ R1, #0 MOVNE R1, #&80 STRB R1, NoIgnore MOV R1, R0, LSR #5 ; printer type now in bits 0..2 STRB R1, PrinterDrivType MOV R0, #MODETVCMOS BL Read MOV R2, R0, LSR #4 ; bit0:=interlace, bits 1-3 := vertical AND R1, R2, #1 STRB R1, TVInterlace MOV R2, R2, LSL #31-3 ; bits 29-31 := vertical MOV R2, R2, ASR #29 ; sign extend STRB R2, TVVertical MOV R0, #DBTBCMOS BL Read LDRB R1, StartOptions TST R0, #&10 ; bit 4 = boot bit ORREQ R1, R1, #8 ; noboot => set bit 3 BICNE R1, R1, #8 ; boot => clear bit 3 STRB R1, StartOptions LDR R2, =ZeroPage+VduDriverWorkSpace+CursorFlags ANDS R1, R0, #8 ; noscroll bit - put 0 or 1 MOVNE R1, #1 ; in bottom byte of CursorFlags STRB R1, [R2] ; leave other bytes alone MOV R0, #CountryCMOS ; read country CMOS and store in var BL Read ; but don't bind 'Default' to a fixed STRB R0, Country ; country at this stage BL SetUpPrinterBuffer Pull PC ; ***************************************************************************** ; ; ReadCMOSDefaults - Read CMOS values for any reset ; On entry WsPtr -> BYTEWS ReadCMOSDefaults Push R14 MOV R0, #DBTBCMOS BL Read TST R0, #2 ; NZ => loud MOVEQ R1, #&D0 ; (quiet) MOVNE R1, #&90 ; (LOUD) STRB R1, BELLinfo MOV R0, #StartCMOS BL Read MOVS R1, R0, LSL #(32-5) ; bit 5 -> carry, bit 4 -> N bit MOVPL R1, #KBStat_NoShiftLock + KBStat_ShiftEnable ; SHCAPS MOVMI R1, #KBStat_NoShiftLock + KBStat_NoCapsLock ; NOCAPS MOVCS R1, #KBStat_NoShiftLock ; CAPS TST R0, #1:SHL:7 ; [NO]NUM ORRNE R1, R1, #KBStat_NoNumLock BICEQ R1, R1, #KBStat_NoNumLock STRB R1, KeyBdStatus LDR R11, =ZeroPage+KeyWorkSpace BL UpdateLEDs MOV R0, #SystemSpeedCMOS BL Read TST R0, #&20 ; Cache off when b5 set LDR R2, =:NOT: (MMUC_I + MMUC_C + MMUC_W) LDRNE R1, =0 LDREQ R1, =MMUC_I + MMUC_C + MMUC_W MOV R0, #MMUCReason_ModifyControl BL MMUControlSub BL Read_Configd_MonitorType LDR r1, =ZeroPage+VduDriverWorkSpace+CurrentMonitorType ; set current to default STR r0, [r1] Pull R14 ; and drop thru to ... ReadKeyDefaults Push R14 MOV R0, #KeyDelCMOS ; Read the default out of CMOS RAM BL Read ; comes back in R0 STRB R0, KeyRepDelay MOV R0, #KeyRepCMOS ; Read the default out of CMOS RAM BL Read ; comes back in R0 STRB R0, KeyRepRate Pull PC ; ***************************************************************************** ; ; PostInit - Called by Sam after modules have been initialised ; PostInit ROUT Push R14 BYTEWS WsPtr SWI XPortable_ReadFeatures BVC %FT01 MOV R0, #0 MOV R1, #0 SWI XPortable_Speed ; attempt to make the portable go fast! MOVVC R1, #PortableFeature_Speed MOVVS R1, #0 01 AND R1, R1, #(PortableFeature_Speed :OR: PortableFeature_Idle :OR: PortableFeature_Stop) LDR R0, =ZeroPage STRB R1, [R0, #PortableFlags] Pull PC ; ***************************************************************************** ; ; SetUpPrinterBuffer - create the printer buffer SetUpPrinterBuffer Entry "r1-r3" MOV r0, #PrinterBufferCMOS BL Read LDR r2, =ZeroPage LDR r2, [r2, #Page_Size] MULS r3, r2, r0 BEQ %FT10 ; if zero, then use default area & size BL ClaimSysHeapNode ; else claim space from system heap BVC %FT20 ; if no error then OK, else use default 10 LDR r2, =PrintBuff ; use default buffer MOV r3, #PrintBuffSize 20 LDR r0, =ZeroPage STR r2, [r0, #PrinterBufferAddr] STR r3, [r0, #PrinterBufferSize] EXIT ; ***************************************************************************** ; ; UpdateLatchB - update latch B and soft copy ; ; LATCHB := (LATCHB AND R1) EOR R0 ; UpdateLatchB Push "R2, R3, R14" PHPSEI ; disable IRQ LDR R2, =ZeroPage LDRB R3, [R2, #LatchBSoftCopy] AND R3, R3, R1 EOR R3, R3, R0 STRB R3, [R2, #LatchBSoftCopy] PLP Pull "R2, R3, PC" ; The initial values for all of the osbyte variables ; as decreed by arthur. ByteVarInitTable ; The main osbyte variables, accessed ; via calls &A6 to &FF DCW OsbyteVars-&A6 ; VarStart # 2 ; &A6,&A7. Note that OS_Byte &A6/&A7 now returns hardcoded values instead of referring to this value held in workspace; potentially we could remove/reuse this entire 10 byte block in the future. = 0,0 ; ROMPtr # 2 ; &A8,&A9 = 0,0 ; ROMInfo # 2 ; &AA,&AB = 0,0 ; KBTran # 2 ; &AC,&AD = 0,0 ; VDUvars # 2 ; &AE,&AF ; = 0 ; CFStime # 1 ; &B0 = 0 ; InputStream # 1 ; &B1 = &FF ; KeyBdSema # 1 ; &B2 ; = &00 ; ROMPollSema # 1 ; &B3 = &80 ; OSHWM # 1 ; &B4 (hi-byte of &8000) ; = 1 ; RS423mode # 1 ; &B5 = 0 ; NoIgnore # 1 ; &B6 = &00 ; CFSRFS # 1 ; &B7 = &00,&00 ; VULAcopy # 2 ; &B8,&B9 ; = &00 ; ROMatBRK # 1 ; &BA = &FF ; BASICROM # 1 ; &BB ; = &04 ; ADCchanel # 1 ; &BC = &04 ; ADCmaxchn # 1 ; &BD = &00 ; ADCconv # 1 ; &BE ; = &FF ; RS432use # 1 ; &BF = &42 ; RS432conflag # 1 ; &C0 ; = &19 ; FlashCount # 1 ; &C1 = &19 ; SpacPeriod # 1 ; &C2 = &19 ; MarkPeriod # 1 ; &C3 ; = &32 ; KeyRepDelay # 1 ; &C4 = &08 ; KeyRepRate # 1 ; &C5 ; = &00 ; ExecFileH # 1 ; &C6 = &00 ; SpoolFileH # 1 ; &C7 ; = &00 ; ESCBREAK # 1 ; &C8 (200) ; = &00 ; KeyBdDisable # 1 ; &C9 = &34 ; KeyBdStatus # 1 ; &CA ; = &11 ; RS423HandShake # 1 ; &CB = &00 ; RS423InputSupr # 1 ; &CC = &00 ; RS423CFSFlag # 1 ; &CD ; = &00 ; EconetOScall # 1 ; &CE = &00 ; EconetOSrdch # 1 ; &CF = &00 ; EconetOSwrch # 1 ; &D0 ; = &00 ; SpeechSupr # 1 ; &D1 = &00 ; SoundSupr # 1 ; &D2 ; = &01 ; BELLchannel # 1 ; &D3 = &90 ; BELLinfo # 1 ; &D4 = &64 ; BELLfreq # 1 ; &D5 = &06 ; BELLdur # 1 ; &D6 ; = &81 ; StartMessSupr # 1 ; &D7 ; = &00 ; SoftKeyLen # 1 ; &D8 ; = &00 ; PageModeLineCount # 1 ; &D9 ; = &00 ; VDUqueueItems # 1 ; &DA ; = &09 ; TABch # 1 ; &DB = &1B ; ESCch # 1 ; &DC ; = &01,&D0,&E0,&F0 ; IPbufferCh # 4 ; &DD,&DE,&DF,&E0 = &01,&80,&90,&00 ; RedKeyCh # 4 ; &E1,&E2,&E3,&E4 ; = &00 ; ESCaction # 1 ; &E5 = &00 ; ESCeffect # 1 ; &E6 ; = &00 ; u6522IRQ # 1 ; &E7 = &00 ; s6850IRQ # 1 ; &E8 = &00 ; s6522IRQ # 1 ; &E9 ; = &00 ; TubeFlag # 1 ; &EA ; = &00 ; SpeechFlag # 1 ; &EB ; = &00 ; WrchDest # 1 ; &EC = &00 ; CurEdit # 1 ; &ED ; = &30 ; KeyBase ; &EE = &01 ; Shadow ; &EF = &00 ; Country ; &F0 ; = &00 ; UserFlag # 1 ; &F1 ; = &64 ; SerULAreg # 1 ; &F2 ; = &05 ; TimerState # 1 ; &F3 ; = &FF ; SoftKeyConsist # 1 ; &F4 ; = &01 ; PrinterDrivType # 1 ; &F5 = &0A ; PrinterIgnore # 1 ; &F6 ; = &01,&00,&00 ; BREAKvector # 3 ; &F7,&F8,&F9 ; = &00 ; DRIVER ; &FA = &00 ; DISPLAY ; &FB ; = &FF ; LangROM # 1 ; &FC ; = &01 ; LastBREAK # 1 ; &FD ; = &0F ; KeyOpt # 1 ; &FE ; = &08 ; StartOptions # 1 ; &FF ; ; ByteVarInitTableEnd ByteVarInitTableSize * ByteVarInitTableEnd - ByteVarInitTable ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ LTORG oldirqowner & IRQ ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; TranslateMonitorLeadType - Determine monitor type and default mode + sync from monitor lead type ; ; in: Monitor lead type in variable MonitorLeadType (surprisingly!) ; ; out: r3 = default mode to use ; r4 = default monitortype to use ; r5 = default sync to use ; TranslateMonitorLeadType Entry "r0-r2" [ ZeroPage = 0 MOV r1, #Service_MonitorLeadTranslation LDRB r2, [r1, #MonitorLeadType-Service_MonitorLeadTranslation] | LDR r2, =ZeroPage MOV r1, #Service_MonitorLeadTranslation LDRB r2, [r2, #MonitorLeadType] ] SWI XOS_ServiceCall TEQ r1, #0 ; if service claimed, then exit with these numbers EXIT EQ ADR r0, MonitorLeadList 10 LDR r14, [r0], #4 EOR r1, r2, r14, LSR #24 ; differences EOR r14, r14, #&FF000000 ; make don't cares into zero TST r14, #&C0000000 BICEQ r1, r1, #&C0 ; knock out difference pairs if don't care TST r14, #&30000000 BICEQ r1, r1, #&30 TST r14, #&0C000000 BICEQ r1, r1, #&0C TST r14, #&03000000 BICEQ r1, r1, #&03 TEQ r1, #0 ; if still have differences, then loop BNE %BT10 MOV r0, #&FF AND r3, r0, r14 ; mode in bits 0..7 AND r4, r0, r14, LSR #8 ; monitortype in bits 8..15 AND r5, r0, r14, LSR #16 ; sync in bits 16..23 ; Give the current GraphicsV driver a chance to specify a better mode ; than whatever we've picked here Push "r4" MOV r0, r3 VDWS r4 LDR r4, [r4, #CurrentGraphicsVDriver] MOV r4, r4, LSL #24 ORR r4, r4, #GraphicsV_StartupMode BL CallGraphicsV Pull "r4" MOV r3, r0 EXIT MACRO MonitorLeadItem $lead, $mode, $monitortype, $sync ASSERT $lead < 256 ASSERT $mode < 256 ASSERT $monitortype < 256 ASSERT $sync < 256 DCD (($lead):SHL:24):OR:(($sync):SHL:16):OR:(($monitortype):SHL:8):OR:($mode) MEND MonitorLeadList ; KJB - changed default modes to 256 colours MonitorLeadItem 4_3330, 28, 3, 0 ; VGA-capable monitors MonitorLeadItem 4_3111, 28, 5, 0 ; Nothing - try LCD (fudge fudge) MonitorLeadItem 4_3333, 15, 0, 1 ; Others - assume TV standard ; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; ; ReadUniqueID - Read unique machine ID ; ReadUniqueID Entry "r0-r3,r9,r12" AddressHAL ; Check for extended ID first MOV r0, #0 CallHAL HAL_ExtMachineID CMP r0, #0 BEQ %FT10 MOV r2, sp SUB r0, r2, r0 BIC r0, r0, #3 MOV sp, r0 Push "r0,r2" ; Remember old SP, buffer pointer CallHAL HAL_ExtMachineID Pull "r1" MOV r2, #0 MOV r3, #0 05 ; Construct the 7 byte machine ID using this simple algorithm: ; EOR each extended ID byte with the low byte of the 7 byte ID, ; then rotate left 7 bits LDRB r12, [r1], #1 EOR r2, r2, r12 AND r12, r3, #&fe0000 MOV r3, r3, LSL #7 ORR r3, r3, r2, LSR #25 MOV r2, r2, LSL #7 ORR r2, r2, r12, LSR #17 SUBS r0, r0, #1 BNE %BT05 LDR sp, [sp] ; Restore SP [ ZeroPage <> 0 LDR r0, =ZeroPage ] STR r2, [r0, #RawMachineID+0] STR r3, [r0, #RawMachineID+4] ; Abuse CheckCRC to calculate CRC byte BL CheckCRC LDR r0, =ZeroPage STRB r2, [r0, #RawMachineID+7] EXIT 10 CallHAL HAL_MachineID LDR r3, =ZeroPage STR r0, [r3, #RawMachineID+0] STR r1, [r3, #RawMachineID+4] BL CheckCRC BVS IDError EXIT IDError DebugTX "Machine ID duff,zero substituted" MOV r0, #0 [ ZeroPage = 0 STR r0, [r0, #RawMachineID+0] ; indicate no ID by putting zero here STR r0, [r0, #RawMachineID+4] | LDR lr, =ZeroPage STR r0, [lr, #RawMachineID+0] ; indicate no ID by putting zero here STR r0, [lr, #RawMachineID+4] ] EXIT CheckCRC ROUT ; Note: artificial ID generator relies on the required CRC being returned in R2! LDR r1, =ZeroPage+RawMachineID ; pointer to current byte MOV r2, #0 MOV r3, #7 ; number of bytes to do 10 LDRB r4, [r1], #1 EOR r2, r2, r4 MOV r4, #8 ; number of bits to do 20 MOVS r2, r2, LSR #1 ; shift bit out into carry EORCS r2, r2, #&8C ; feedback carry into other bits SUBS r4, r4, #1 ; one less bit to do BNE %BT20 ; loop until done whole byte SUBS r3, r3, #1 ; one less byte to do BNE %BT10 ; loop until done all 7 bytes LDRB r4, [r1], #1 ; read CRC CMP r4, r2 ; if correct MOVEQ pc, lr ; exit (V clear) RETURNVS ; else exit indicating error LTORG END