Commit 2cc5ebc7 authored by Jeffrey Lee's avatar Jeffrey Lee

Merge latest changes from main branch

Version 5.89, 4.129.2.6. Tagged as 'Kernel-5_89-4_129_2_6'
parents e6c4e3c2 ac1ea0f5
......@@ -11,13 +11,13 @@
GBLS Module_HelpVersion
GBLS Module_ComponentName
GBLS Module_ComponentPath
Module_MajorVersion SETS "5.88"
Module_Version SETA 588
Module_MinorVersion SETS "4.129.2.5"
Module_Date SETS "03 Sep 2017"
Module_ApplicationDate SETS "03-Sep-17"
Module_MajorVersion SETS "5.89"
Module_Version SETA 589
Module_MinorVersion SETS "4.129.2.6"
Module_Date SETS "10 Sep 2017"
Module_ApplicationDate SETS "10-Sep-17"
Module_ComponentName SETS "Kernel"
Module_ComponentPath SETS "castle/RiscOS/Sources/Kernel"
Module_FullVersion SETS "5.88 (4.129.2.5)"
Module_HelpVersion SETS "5.88 (03 Sep 2017) 4.129.2.5"
Module_FullVersion SETS "5.89 (4.129.2.6)"
Module_HelpVersion SETS "5.89 (10 Sep 2017) 4.129.2.6"
END
/* (5.88)
/* (5.89)
*
* This file is automatically maintained by srccommit, do not edit manually.
* Last processed by srccommit version: 1.1.
*
*/
#define Module_MajorVersion_CMHG 5.88
#define Module_MinorVersion_CMHG 4.129.2.5
#define Module_Date_CMHG 03 Sep 2017
#define Module_MajorVersion_CMHG 5.89
#define Module_MinorVersion_CMHG 4.129.2.6
#define Module_Date_CMHG 10 Sep 2017
#define Module_MajorVersion "5.88"
#define Module_Version 588
#define Module_MinorVersion "4.129.2.5"
#define Module_Date "03 Sep 2017"
#define Module_MajorVersion "5.89"
#define Module_Version 589
#define Module_MinorVersion "4.129.2.6"
#define Module_Date "10 Sep 2017"
#define Module_ApplicationDate "03-Sep-17"
#define Module_ApplicationDate "10-Sep-17"
#define Module_ComponentName "Kernel"
#define Module_ComponentPath "castle/RiscOS/Sources/Kernel"
#define Module_FullVersion "5.88 (4.129.2.5)"
#define Module_HelpVersion "5.88 (03 Sep 2017) 4.129.2.5"
#define Module_LibraryVersionInfo "5:88"
#define Module_FullVersion "5.89 (4.129.2.6)"
#define Module_HelpVersion "5.89 (10 Sep 2017) 4.129.2.6"
#define Module_LibraryVersionInfo "5:89"
......@@ -123,8 +123,8 @@ EntryNo_HAL_UARTBreak # 1 ; 80
EntryNo_HAL_UARTModemControl # 1 ; 81
EntryNo_HAL_UARTModemStatus # 1 ; 82
EntryNo_HAL_UARTDevice # 1 ; 83
EntryNo_HAL_UARTDefault # 1 ; 84
EntryNo_HAL_Reset # 1 ; 84
EntryNo_HAL_DebugRX # 1 ; 85
EntryNo_HAL_DebugTX # 1 ; 86
......@@ -145,24 +145,22 @@ EntryNo_HAL_PlatformName # 1 ; 97, ReadSysInfo 9 subreason 7 (was H
EntryNo_HAL_InitDevices # 1 ; 100
EntryNo_HAL_KbdScanSetup # 1 ; 101
EntryNo_HAL_KbdScan # 1 ; 102
EntryNo_HAL_KbdScanFinish # 1 ; 103
EntryNo_HAL_KbdScanInterrupt # 1 ; 104
EntryNo_HAL_KbdScanDependencies # 1 ; 101
# 1 ; 102 (was HAL_KbdScan)
# 1 ; 103 (was HAL_KbdScanFinish)
# 1 ; 104 (was HAL_KbdScanInterrupt)
EntryNo_HAL_PhysInfo # 1 ; 105
EntryNo_HAL_USBControllerInfo # 1 ; 106
EntryNo_HAL_Reset # 1 ; 106
EntryNo_HAL_IRQMax # 1 ; 107 (was HAL_MonitorLeadID)
EntryNo_HAL_VideoRender # 1 ; 108
EntryNo_HAL_USBControllerInfo # 1 ; 108
EntryNo_HAL_USBPortPower # 1 ; 109
EntryNo_HAL_USBPortIRQStatus # 1 ; 110
EntryNo_HAL_USBPortIRQClear # 1 ; 111
EntryNo_HAL_VideoIICOp # 1 ; 112
EntryNo_HAL_USBPortDevice # 1 ; 112
EntryNo_HAL_TimerIRQClear # 1 ; 113
EntryNo_HAL_TimerIRQStatus # 1 ; 114
......@@ -170,13 +168,10 @@ EntryNo_HAL_TimerIRQStatus # 1 ; 114
EntryNo_HAL_ExtMachineID # 1 ; 115, ReadSysInfo 10
EntryNo_HAL_VideoFramestoreAddress # 1 ; 116
EntryNo_HAL_UARTDefault # 1 ; 117
EntryNo_HAL_VideoRender # 1 ; 117
EntryNo_HAL_VideoStartupMode # 1 ; 118
EntryNo_HAL_VideoPixelFormatList # 1 ; 119
EntryNo_HAL_USBPortDevice # 1 ; 120
EntryNo_HAL_VideoIICOp # 1 ; 120
EntryNo_HAL_Watchdog # 1 ; 121
......@@ -231,17 +226,6 @@ IICStatus_Busy # 1
IICStatus_Slave # 1
IICStatus_Error # 1
; 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
; USB
^ 0
......
......@@ -996,18 +996,19 @@ IICBus_Size # 0
; *****************************************************************************
; Real workspace definition
; locations used during reset only. Not cleared by ClearPhysRAM, but
; locations used during reset only. Not cleared by ClearWkspRAM, but
; cleared later (just before DEFHAN).
; Note that these are all relative to ZeroPage!
^ &80 ; steer clear of FIQ code
InitWsStart # 0
InitIRQHandler # 4 ; pointer to IRQ handler (LDR PC'ed from IRQ HW vector)
InitIRQWs # 16 ; workspace for IRQ handler
InitUsedStart # 4 ; start of used pages (L2PT etc) not to be cleared
InitUsedEnd # 4 ; end of used pages
InitUsedBlock # 4 ; current block in PhysRamTable
InitClearRamWs # 10*4
InitClearRamWs # 10*4 ; preserve registers during ClearPhysRAM
InitDMABlock # 8 ; block of DMAable memory extracted from PhysRamTable
InitDMAOffset # 4 ; offset+8 into PhysRamTable where memory was taken
InitDMAEnd # 4 ; current DMA alloc pos
......
......@@ -64,6 +64,7 @@
GET Hdr:OsBytes
GET Hdr:Internatio
GET Hdr:Territory
GET Hdr:Countries
GET Hdr:Portable
GET Hdr:MsgTrans
GET Hdr:PaletteV
......
......@@ -762,8 +762,7 @@ RISCOS_Start
LDR a2, [sp, #0]
STR a2, [a1, #HAL_StartFlags]
; Set up a reset IRQ handler (used during RAM clear for keyboard
; scan, and later for IIC CMOS access)
; Set up a reset IRQ handler (for IIC CMOS access)
MSR CPSR_c, #IRQ32_mode + I32_bit + F32_bit
LDR sp_irq, =ScratchSpace + 1024 ; 1K is plenty since Reset_IRQ_Handler now runs in SVC mode
MSR CPSR_c, #SVC32_mode + I32_bit + F32_bit
......@@ -1041,16 +1040,6 @@ MMUon_nol1ptoverlap
BL IICInit
LDR a1, =ZeroPage+InitIRQWs
MOV a2, #1
STRB a2, [a1, #KbdScanActive]
DebugTX "HAL_KbdScanSetup"
CallHAL HAL_KbdScanSetup
MSR CPSR_c, #F32_bit+SVC32_mode ; enable IRQs for scan
; Remember some stuff that's about to get zapped
LDR ip, =ZeroPage
LDR v4, [ip, #ROMPhysAddr]
......@@ -1060,7 +1049,7 @@ MMUon_nol1ptoverlap
LDR a1, [ip, #HAL_StartFlags]
TST a1, #OSStartFlag_RAMCleared
BLEQ ClearPhysRAM ; Only clear the memory if the HAL didn't
BLEQ ClearWkspRAM ; Only clear the memory if the HAL didn't
; Put it back
LDR ip, =ZeroPage
......@@ -1069,7 +1058,7 @@ MMUon_nol1ptoverlap
STR v7, [ip, #MaxCamEntry]
STR v8, [ip, #IRQMax]
; Calculate CPU feature flags (if moving this to before ClearPhysRAM, ensure the workspace also gets moved into the skipped region)
; Calculate CPU feature flags
BL ReadCPUFeatures
MOV v8, ip
......@@ -1259,7 +1248,7 @@ ROMDecompWSAddr * 4<<20
LDR a1, =SysHeapAddress
LDR a2, =AreaFlags_SysHeap
LDR a3, =32*1024
BL Init_MapInRAM
BL Init_MapInRAM_Clear
; Allocate the cursor/system/sound block - first the cached bit
LDR a1, =CursorChunkAddress
......@@ -1275,14 +1264,14 @@ ROMDecompWSAddr * 4<<20
LDR a1, =KbuffsBaseAddress
LDR a2, =AreaFlags_Kbuffs
LDR a3, =(KbuffsSize + &FFF) :AND: &FFFFF000 ;(round to 4k)
BL Init_MapInRAM
BL Init_MapInRAM_Clear
[ HiProcVecs
; Map in DebuggerSpace
LDR a1, =DebuggerSpace
LDR a2, =AreaFlags_DebuggerSpace
LDR a3, =(DebuggerSpace_Size + &FFF) :AND: &FFFFF000
BL Init_MapInRAM
BL Init_MapInRAM_Clear
]
[ MinorL2PThack
......@@ -1348,14 +1337,6 @@ ROMDecompWSAddr * 4<<20
BL CountPageTablePages
[ {FALSE}
MOV a1, #InitIRQWs
MOV a2, #0
MOV a3, #0
STMIA a1!, {a2,a3}
STMIA a1!, {a2,a3}
]
B Continue_after_HALInit
LTORG
......@@ -1607,6 +1588,16 @@ Init_MapInRAM ROUT
MOV a1, v8
Pull "v4-v8,pc"
Init_MapInRAM_Clear ROUT ; same as Init_MapInRAM but also
Push "a1,a3,v5,lr" ; clears the mapped in result
BL Init_MapInRAM
MOV v5, a1
Pull "a1,a3"
MOV a2, #0
BL memset
MOV a1, v5
Pull "v5,pc"
; Allocate and map a physically contigous chunk of some DMAable RAM.
;
; On entry:
......@@ -1636,7 +1627,7 @@ Init_MapInRAM_DMA ROUT
MOV a2, a1
MOV a1, v5
BL Init_MapIn ; map it in
; DMA regions won't get cleared by ClearPhysRam, so do it manually
; DMA regions won't get cleared by ClearWkspRam, so do it manually
; Could potentially skip this if the HAL says RAM is already clear, but
; for now do it anyway (especially since startup flags haven't been set
; when we're first called)
......@@ -1925,28 +1916,22 @@ Init_PageTablesChanged
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
; ClearPhysRAM - Routine to clear "all" memory
;
; While this routine is running, keyboard IRQs may happen. For this reason
; it avoids the base of logical RAM (hardware IRQ vector and workspace).
; ClearWkspRAM - Routine to clear "all" workspace
;
; We also have to avoid anything between InitUsedStart and InitUsedEnd - i.e.
; We have to avoid anything between InitUsedStart and InitUsedEnd - i.e.
; the page tables, HAL workspace, etc.
;
; Note that zero page workspace isn't included in InitUsedStart/InitUsedEnd.
; Sensitive areas of it (e.g. PhysRamTable, IRQ vector) are skipped via the
; help of RamSkipTable
; We don't have to worry about trampling on the ROM image as it's already been
; excluded from PhysRamTable. We also don't have to worry about skipping the
; special DMA block, because at this point in time that won't be listed in
; PhysRamTable either.
;
; The bulk of RAM is cleared during the keyboard scan (ClearFreePoolSection).
;
; out: r4-r11, r13 preserved
;
ClearPhysRAM ROUT
ClearWkspRAM ROUT
MSR CPSR_c, #F32_bit+FIQ32_mode ; get some extra registers
MOV r8, #0
MOV r9, #0
......@@ -1957,11 +1942,10 @@ ClearPhysRAM ROUT
MOV r14, #0
MSR CPSR_c, #F32_bit+SVC32_mode
;now let us do the clear
LDR r0,=ZeroPage+InitClearRamWs ;we can preserve r4-r11,lr in one of the skipped regions
STMIA r0,{r4-r11,lr}
DebugTX "ClearPhysRAM"
DebugTX "ClearWkspRAM"
; Start off by clearing zero page + scratch space, as these:
; (a) are already mapped in and
......@@ -1991,112 +1975,16 @@ ClearPhysRAM ROUT
STMNEIA r0!, {r8-r11}
BNE %BT30
; Now walk PhysRamTable and clear everything else, except for the stuff
; between InitUsedStart and InitUsedEnd.
;
; To skip these areas properly, we convert their addresses to physical
; page numbers. This is because PhysRamTable isn't guaranteed to be in
; ascending address order.
MSR CPSR_c, #F32_bit+SVC32_mode
LDR r9, =ZeroPage
LDR r5, [r9, #InitUsedStart]
SUB r0, r5, #DRAMOffset_L1PT ; Scratch space + zero page are already cleared, so add them to InitUsedStart..InitUsedEnd
BL PhysAddrToPageNo
; If the DMA region was taken from the first RAM block, we won't be able to look up the page number
; Instead, let's use the first DRAM page for InitUsedStart - as this will correspond to the first page that isn't hidden inside the DMA region
CMP r0, #-1
LDREQ r0, [r9, #DRAMPhysAddrA]
BLEQ PhysAddrToPageNo
MOV r5, r0
LDR r0, [r9, #InitUsedEnd]
BL PhysAddrToPageNo
SUB r6, r0, #1
ADD r9, r9, #PhysRamTable
MOV r4, #0 ; current page no
LDMIA r9!, {r10, r11}
MOV r11, r11, LSR #12 ; get rid of flags
50
; Map in this area, cacheable + bufferable to ensure burst writes are
; performed. We're careful to not partially overwrite any pages which
; are being used, so this shouldn't cause any issues due to being
; cachable + potentially doubly mapped.
MOV r0, #0
MOV r1, r10
MOV r2, #0
BL RISCOS_AccessPhysicalAddressUnchecked
; Inner loop will process one page at a time to keep things simple
MOV r3, r11
MSR CPSR_c, #F32_bit+FIQ32_mode ; switch to our bank o'zeros
MOV r2, #0
60
CMP r4, r5
CMPHS r6, r4
ADD r1, r0, #4096
BHS %FT80
; Clear this page
70
STMIA r0!, {r2,r8-r14}
STMIA r0!, {r2,r8-r14}
TEQ r0, r1
BNE %BT70
80
MOV r0, r1 ; increment log addr
ADD r4, r4, #1 ; increment page no
SUBS r3, r3, #1 ; decrement length
MOVNES r1, r0, LSL #12 ; check for MB limit
BNE %BT60
MSR CPSR_c, #F32_bit+SVC32_mode
; Make page uncacheable so the following is safe
Push "r0-r3"
MOV r0, #L1_B
MOV r1, r10
MOV r2, #0
BL RISCOS_AccessPhysicalAddress
Pull "r0-r3"
; Clean & invalidate the cache before the 1MB window closes
[ CacheCleanerHack
; StrongARM requires special clean code, because we haven't mapped in
; DCacheCleanAddress yet. Cheat and only perform a clean, not full
; clean + invalidate (should be safe as we've only been writing)
ARM_read_ID r2
AND r2, r2, #&F000
CMP r2, #&A000
BNE %FT90
85
SUB r0, r0, #32 ; rewind 1 cache line
ARMA_clean_DCentry r0
MOVS r1, r0, LSL #12 ; start of the MB?
BNE %BT85
B %FT91
90
]
ARMop Cache_CleanInvalidateAll
91
ADD r10, r10, r11, LSL #12 ; r10+(r11-r3) = next MB
MOVS r11, r3 ; next block needed? also resets r11 ready for next pass
SUBNE r10, r10, r3, LSL #12
LDMEQIA r9!, {r10, r11} ; grab next block if necessary
MOVEQS r11, r11, LSR #12 ; anything left to do?
BNE %BT50
MOV a1, #L1_Fault
BL RISCOS_ReleasePhysicalAddress ; reset to default
LDR r0, =ZeroPage+InitClearRamWs
LDMIA r0, {r4-r11,r14} ;restore
CPR_skipped
[ {FALSE} ; NewReset sets this later
LDR r0, =ZeroPage+OsbyteVars + :INDEX: LastBREAK
MOV r1, #&80
STRB r1, [r0] ; flag the fact that RAM cleared
]
MSR CPSR_c, #F32_bit + UND32_mode ; retrieve the MMU control register
LDR r0, =ZeroPage ; soft copy
......@@ -2120,12 +2008,169 @@ CPR_skipped
& -1
MEND
RamSkipTable
MakeSkipTable ZeroPage, InitWsEnd
MakeSkipTable ZeroPage+SkippedTables, SkippedTablesEnd-SkippedTables
EndSkipTables
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
; ClearFreePoolSection - Routine to clear a section of the free pool
;
; During keyboard scanning we soak up slack time clearing the bulk of RAM
; by picking a section of the free pool, mapping it in, clearing & flushing.
;
; In: r0 = CAM entry to continue from
; Out: r0 = updated
;
ClearFreePoolSection ROUT
Push "r1-r3, lr"
LDR r1, =ZeroPage
LDR r1, [r1, #MaxCamEntry]
LDR r2, =ZeroPage+FreePoolDANode
CMP r0, r1
BHI %FT30
LDR r3, =CAM
ADD r1, r3, r1, LSL #CAM_EntrySizeLog2 ; top entry (inc)
ADD r3, r3, r0, LSL #CAM_EntrySizeLog2 ; starting entry
10
LDR r14, [r3, #CAM_PageFlags]
TST r14, #DynAreaFlags_PMP
BEQ %FT20
LDR r14, [r3, #CAM_PMP]
TEQ r14, r2
BEQ %FT40
20
ADD r3, r3, #CAM_EntrySize ; next
CMP r3, r1
BLS %BT10
30
MOV r0, #-1
Pull "r1-r3, pc"
40
Push "r0-r12"
; This is a PMP entry in the free pool
LDR r14, [r3, #CAM_PMPIndex] ; list index
LDR r9, [r2, #DANode_PMP] ; PMP list base
LDR r3, [r9, r14, LSL #2] ; ppn
BL ppn_to_physical ; => r5 = PA
[ MEMM_Type = "ARM600"
; Map in this section, cacheable + bufferable to ensure burst writes
; are performed (StrongARM will only perform burst writes to CB areas)
MOV a1, #OSAP_None
|
; Map in this section with default NCB cache policy. Making it cacheable
; is liable to slow things down significantly on some platforms (e.g.
; PL310 L2 cache)
LDR a1, =OSAP_None + DynAreaFlags_NotCacheable
]
MOV a2, r5
MOV a3, #0
BL RISCOS_AccessPhysicalAddressUnchecked
MOV r4, #0 ; clear to this value
MOV r6, r4
MOV r7, r4
MOV r8, r4
MOV r12, r4
45
MOV r9, r4
MOV r10, r4
MOV r11, r4
; Fill that page
ADD r2, r0, #4096
50
STMIA r0!, {r4,r6-r12}
STMIA r0!, {r4,r6-r12}
TEQ r0, r2
BNE %BT50
; Step the CAM until there are no more pages in that section
LDR r1, [sp, #1*4]
LDR r2, [sp, #2*4]
LDR r11, [sp, #3*4]
B %FT65
60
LDR r14, [r11, #CAM_PageFlags]
TST r14, #DynAreaFlags_PMP
BEQ %FT65
LDR r14, [r11, #CAM_PMP]
TEQ r14, r2
BEQ %FT70
65
ADD r11, r11, #CAM_EntrySize ; next
CMP r11, r1
BLS %BT60
MOV r14, #-1 ; CAM top, no more
B %FT80
70
MOV r10, r5 ; previous PA
; Next PMP entry in the free pool
LDR r14, [r11, #CAM_PMPIndex] ; list index
LDR r9, [r2, #DANode_PMP] ; PMP list base
LDR r3, [r9, r14, LSL #2] ; ppn
BL ppn_to_physical ; => r5 = PA
MOV r14, r10, LSR #20
TEQ r14, r5, LSR #20 ; same MB as previous?
LDRNE r14, =CAM
SUBNE r14, r11, r14
MOVNE r14, r14, LSR #CAM_EntrySizeLog2 ; no, so compute continuation point
LDREQ r0, =PhysicalAccess
MOVEQ r14, r5, LSL #12
ORREQ r0, r0, r14, LSR #12
STREQ r11, [sp, #3*4]
BEQ %BT45 ; yes, so clear it
80
STR r14, [sp, #0*4] ; return value for continuation
[ MEMM_Type = "ARM600" ; VMSAv6 maps as non-cacheable, so no flush required
; Make page uncacheable so the following is safe
MOV r4, r0
MOV r0, #L1_B
MOV r1, r10
MOV r2, #0
BL RISCOS_AccessPhysicalAddress
MOV r0, r4
; Clean & invalidate the cache before the 1MB window closes
[ CacheCleanerHack
; StrongARM requires special clean code, because we haven't mapped in
; DCacheCleanAddress yet. Cheat and only perform a clean, not full
; clean + invalidate (should be safe as we've only been writing)
ARM_read_ID r2
AND r2, r2, #&F000
CMP r2, #&A000
BNE %FT90
85
SUB r0, r0, #32 ; rewind 1 cache line
ARMA_clean_DCentry r0
MOVS r1, r0, LSL #12 ; start of the MB?
BNE %BT85
B %FT91
90
]
ARMop Cache_CleanInvalidateAll
]
91
MOV a1, #L1_Fault
BL RISCOS_ReleasePhysicalAddress ; reset to default
Pull "r0-r12"
Pull "r1-r3, pc"
InitProcVecs
BKPT &C000 ; Reset
......@@ -2659,7 +2704,8 @@ Reset_IRQ_Handler
ORR a3, a2, #SVC32_mode
MSR CPSR_c, a3
Push "a1-a2,lr"
; If it's not an IIC interrupt, pass it on to the keyboard scan code
; If it's not an IIC interrupt, mute it
LDR v2, =ZeroPage
AddressHAL v2
CallHAL HAL_IRQSource
......@@ -2678,14 +2724,9 @@ Reset_IRQ_Handler
ADD v1, v1, #IICBus_Size
CMP ip, #IICBus_Count
BNE %BT10
LDRB a2, [v2, #InitIRQWs+KbdScanActive]
TEQ a2, #0
CallHAL HAL_KbdScanInterrupt,NE
; Keyboard scan code will have return -1 if it handled the IRQ
; If it didn't handle it, or keyboard scanning is inactive, something
; bad has happened
CMP a1, #-1
CallHAL HAL_IRQDisable,NE ; Stop the rogue device from killing us completely
CallHAL HAL_IRQDisable ; Stop the rogue device from killing us completely
Reset_IRQ_Exit
MyCLREX a1, a2
Pull "a1-a2,lr"
......@@ -2750,6 +2791,7 @@ hextab DCB "0123456789abcdef"
;HALDebugHexTX2
; stmfd r13!, {r0-r3,sb,ip,lr}
; AddressHAL
; mov r0,r0,lsl #16
; b jbdt2
;HALDebugHexTX4
; stmfd r13!, {r0-r3,sb,ip,lr}
......
......@@ -94,29 +94,134 @@ UnplugCMOSTableEnd ; used for backwards indexing
ALIGN
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
; ModuleInitForKbdScan - Start subset of ROM modules for keyboard scan
;
; in: r0 -> comma seperated list of ROM module names
;
; out: All registers preserved
;
ModuleInit Entry "r0-r12" ; call here on system startup
ModuleInitForKbdScan Entry "r0-r12"
MOV r0, #HeapReason_Init ; first initialise the heap
MOV r1, #RMAAddress
LDR r3, [r1, #:INDEX: hpdend] ; saved for us during init.
SWI XOS_Heap
; first initialise the podule manager - this must be the second module (ie the 1st after UtilityModule)
ASSERT ROMModule_Link = 0
ADRL r6, SysModules_Info+4
LDR r9, =ZeroPage+ROMModuleChain ; pointer to 'previous' node
MOV r8, #0 ; initial head ptr is zero
STR r8, [r9] ; set up null list
LDR r0, [sp, #0*4]
CMP r0, #-1 ; no list?
BNE %FT10
; just init the podule manager - this must be the second module (ie the 1st after UtilityModule)
LDR r1, [r6, #-4]
ADD r1, r6, r1
LDR r14, [r1, #-4]
TEQ r14, #0
MOVNE r0, #ModHandReason_AddArea
SWINE XOS_Module
EXIT
; now for each module in the main ROM needed for KbdScan, create a node for it
10
MOV r3, #-1 ; podule -1 is main ROM
MOV r10, #0 ; chunk number 0 to start
20
LDR r7, [r6, #-4] ; get size of this module
TEQ r7, #0 ; if zero
BEQ %FT50 ; then no more main rom modules
LDR r4, [r6, #Module_TitleStr] ; r4 = offset to module name
ADD r4, r6, r4 ; r4 -> module name
LDR r5, [r6, #Module_HelpStr] ; r5 = help offset
TEQ r5, #0 ; if no help string
ADDEQ r5, r6, #Module_HelpStr ; then use help offset as string (null string)
ADDNE r5, r6, r5 ; otherwise point to help string
CMP r10, #FirstUnpluggableModule
BCC %FT30 ; unconditional since not unpluggable anyway
LDR r11, [sp, #0*4]
BL CompareTitleWithCSV
BNE %FT40 ; if your name's not on the list you can't come in
30
ADR r11, UnplugCMOSTable
SUBS r14, r10, #FirstUnpluggableModule ; subtract number of first module that has an unplug bit
MOVCS r1, r14, LSR #3 ; get byte number
ANDCS r14, r14, #7 ; get bit number
ADDCS r14, r14, #16 ; bit mask stored in bits 16 onwards
RSBCSS r1, r1, #(UnplugCMOSTableEnd-UnplugCMOSTable) ; invert table offset, and check in range
LDRCSB r11, [r11, r1] ; load table value if in range
MOVCS r12, #1
ORRCS r11, r11, r12, LSL r14 ; merge with bit mask
MOVCC r11, #0 ; otherwise zero
BL AddROMModuleNode
BVS %FT50 ; if failed then can't add any more ROMs!
40
MOV r9, r2 ; this node is now previous one
ADD r6, r6, r7 ; go on to next module
ADD r10, r10, #1 ; chunk number +=1
B %BT20
; now start them
50
LDR r12, =ZeroPage+ROMModuleChain
LDR r12, [r12]
60
TEQ r12, #0 ; if no more modules
BEQ %FT90 ; then skip
MOV r11, r12 ; start with current one
BL InitialiseROMModuleAtInit
LDR r12, [r12, #ROMModule_Link]
B %BT60
90
[ DebugROMInit
SWI XOS_WriteS
= "mod init (kbdscan) done",0
SWI XOS_NewLine
]
MOV r1, #RMASizeCMOS