From 3e9f9f3a898a368839d53f952029b9e5cb79df47 Mon Sep 17 00:00:00 2001 From: ROOL <code@riscosopen.org> Date: Tue, 15 Apr 2003 20:18:38 +0000 Subject: [PATCH] This commit was manufactured by cvs2git to create tag 'Kernel- 5_35-4_79_2_60'. Sprout from HAL 2003-04-15 20:18:37 UTC Kevin Bracey <kbracey@gitlab.riscosopen.org> 'Version increased to dizzy 5.03' Delete: Docs/HAL/ADisNote Docs/HAL/ARMop_API Docs/HAL/Entries Docs/HAL/HAL_API Docs/HAL/Init Docs/HAL/MoreEnts Docs/HAL/NewAPI Docs/HAL/NewCDV Docs/HAL/Notes Docs/HAL/OS_Hardware Docs/HAL/OpenBusAdapter Docs/HAL/Serial Docs/MemMaps/+Access,ffd Docs/MemMaps/+SrcIndex Docs/MemMaps/+SrcIndexO Docs/MemMaps/130 Docs/MemMaps/258 Docs/PrivDoc/+Access,ffd Docs/PrivDoc/+SrcIndex Docs/PrivDoc/+SrcIndexO Docs/PrivDoc/5thColumn/+Access,ffd Docs/PrivDoc/5thColumn/+SrcIndex Docs/PrivDoc/5thColumn/+SrcIndexO Docs/PrivDoc/5thColumn/Concept Docs/PrivDoc/MMPM Docs/PrivDoc/ScreenMode NewModes/Make,feb NewModes/NEWF2 NewModes/NEWFORMAT NewModes/OldFormat NewModes/OldPSSrc NewModes/OldToNew,ffb NewModes/PSSrc Resources/UK/CmdHelp Resources/UK/Messages Resources/UK/Morris4/Messages Resources/UK/Omega/Messages Resources/UK/Ursula/Messages TestSrc/A600tlb TestSrc/Arm3 TestSrc/Begin TestSrc/Cmos TestSrc/ErrorCount,ffb TestSrc/ExtCmd TestSrc/ExtIO TestSrc/InitModule TestSrc/Ioc TestSrc/LEDDelay TestSrc/MEMC1 TestSrc/Mem1IOMD TestSrc/Mem1MEMC1 TestSrc/Mem2 TestSrc/Mem3 TestSrc/Mem4 TestSrc/Mem5 TestSrc/ROMCard TestSrc/ShowIOMDRs TestSrc/TestMain TestSrc/ToggleLED TestSrc/Vidc h/HALDevice hdr/ARMops hdr/Copro15ops hdr/EnvNumbers hdr/ExportVals/!HowTo hdr/ExportVals/Makefile hdr/ExportVals/Mk,fd7 hdr/ExportVals/s/GetVals hdr/ExportVals/values hdr/HALDevice hdr/HALEntries hdr/KernelWS hdr/KeyWS hdr/ModHand hdr/OSEntries hdr/Old/Arthur/PublicWS hdr/Old/Arthur/Space200 hdr/Old/NewSpace hdr/Old/VickySpace hdr/Options hdr/PublicWS hdr/RISCOS hdr/Variables hdr/VduExt s/AMBControl/AMB s/AMBControl/Memory s/AMBControl/Options s/AMBControl/Workspace s/AMBControl/allocate s/AMBControl/deallocate s/AMBControl/growp s/AMBControl/growshrink s/AMBControl/main s/AMBControl/mapslot s/AMBControl/mapsome s/AMBControl/memmap s/AMBControl/readinfo s/AMBControl/service s/AMBControl/shrinkp s/ARM600 s/ARMops s/Arthur2 s/Arthur3 s/ArthurSWIs s/ChangeDyn s/Convrsions s/End s/ExtraSWIs s/FlashROM s/GetAll s/HAL s/HeapMan s/HeapSort s/KbdResA1 s/KbdResPC s/KbdResRCMM s/Kernel s/LibKern s/MEMC1 s/MEMC2 s/MOSDict s/MemInfo s/Middle s/ModHand s/MoreComms s/MoreSWIs s/Morris s/MsgCode s/NewIRQs s/NewReset s/Oscli s/PMF/Buffer s/PMF/Def s/PMF/IIC s/PMF/Internat s/PMF/KbdDrA1 s/PMF/convdate s/PMF/i2cutils s/PMF/key s/PMF/mouse s/PMF/osbyte s/PMF/oseven s/PMF/osinit s/PMF/osword s/PMF/oswrch s/PMF/realtime s/SWINaming s/Super1 s/SysComms s/TickEvents s/UnSqueeze s/Utility s/vdu/vdu23 s/vdu/vdu5 s/vdu/vducursoft s/vdu/vdudecl s/vdu/vdudriver s/vdu/vdufont s/vdu/vdufontl1 s/vdu/vdugrafa s/vdu/vdugrafb s/vdu/vdugrafc s/vdu/vdugrafd s/vdu/vdugrafdec s/vdu/vdugrafe s/vdu/vdugraff s/vdu/vdugrafg s/vdu/vdugrafh s/vdu/vdugrafi s/vdu/vdugrafj s/vdu/vdugrafk s/vdu/vdugrafl s/vdu/vdugrafv s/vdu/vduhint s/vdu/vdumodes s/vdu/vdupal10 s/vdu/vdupal20 s/vdu/vdupalette s/vdu/vdupalxx s/vdu/vduplot s/vdu/vdupointer s/vdu/vduswis s/vdu/vduttx s/vdu/vduwrch --- .gitattributes | 4 - Docs/HAL/ADisNote | 48 - Docs/HAL/ARMop_API | 441 --- Docs/HAL/Entries | 343 -- Docs/HAL/HAL_API | 1078 ------- Docs/HAL/Init | 116 - Docs/HAL/MoreEnts | 500 --- Docs/HAL/NewAPI | 235 -- Docs/HAL/NewCDV | 23 - Docs/HAL/Notes | 109 - Docs/HAL/OS_Hardware | 47 - Docs/HAL/OpenBusAdapter | 43 - Docs/HAL/Serial | 133 - Docs/MemMaps/+Access,ffd | Bin 1 -> 0 bytes Docs/MemMaps/+SrcIndex | 3 - Docs/MemMaps/+SrcIndexO | 3 - Docs/MemMaps/130 | 38 - Docs/MemMaps/258 | 24 - Docs/PrivDoc/+Access,ffd | Bin 1 -> 0 bytes Docs/PrivDoc/+SrcIndex | 4 - Docs/PrivDoc/+SrcIndexO | 4 - Docs/PrivDoc/5thColumn/+Access,ffd | Bin 1 -> 0 bytes Docs/PrivDoc/5thColumn/+SrcIndex | 2 - Docs/PrivDoc/5thColumn/+SrcIndexO | 2 - Docs/PrivDoc/5thColumn/Concept | 59 - Docs/PrivDoc/MMPM | 54 - Docs/PrivDoc/ScreenMode | 92 - NewModes/Make,feb | 17 - NewModes/NEWF2 | 144 - NewModes/NEWFORMAT | 89 - NewModes/OldFormat | 453 --- NewModes/OldPSSrc | 1002 ------ NewModes/OldToNew,ffb | Bin 2713 -> 0 bytes NewModes/PSSrc | 791 ----- Resources/UK/CmdHelp | Bin 10566 -> 0 bytes Resources/UK/Messages | 179 -- Resources/UK/Morris4/Messages | 172 - Resources/UK/Omega/Messages | 172 - Resources/UK/Ursula/Messages | 172 - TestSrc/A600tlb | 61 - TestSrc/Arm3 | 71 - TestSrc/Begin | 2163 ------------- TestSrc/Cmos | 320 -- TestSrc/ErrorCount,ffb | Bin 2403 -> 0 bytes TestSrc/ExtCmd | 1019 ------ TestSrc/ExtIO | 1107 ------- TestSrc/InitModule | 114 - TestSrc/Ioc | 110 - TestSrc/LEDDelay | 35 - TestSrc/MEMC1 | 552 ---- TestSrc/Mem1IOMD | 708 ----- TestSrc/Mem1MEMC1 | 390 --- TestSrc/Mem2 | 312 -- TestSrc/Mem3 | 127 - TestSrc/Mem4 | 630 ---- TestSrc/Mem5 | 316 -- TestSrc/ROMCard | 222 -- TestSrc/ShowIOMDRs | 214 -- TestSrc/TestMain | 78 - TestSrc/ToggleLED | 48 - TestSrc/Vidc | 535 ---- h/HALDevice | 39 - hdr/ARMops | 93 - hdr/Copro15ops | 549 ---- hdr/EnvNumbers | 61 - hdr/ExportVals/!HowTo | 7 - hdr/ExportVals/Makefile | 38 - hdr/ExportVals/Mk,fd7 | 16 - hdr/ExportVals/s/GetVals | 88 - hdr/ExportVals/values | 70 - hdr/HALDevice | 110 - hdr/HALEntries | 176 - hdr/KernelWS | 1948 ------------ hdr/KeyWS | 125 - hdr/ModHand | 110 - hdr/OSEntries | 44 - hdr/Old/Arthur/PublicWS | 90 - hdr/Old/Arthur/Space200 | 1017 ------ hdr/Old/NewSpace | 1172 ------- hdr/Old/VickySpace | 1296 -------- hdr/Options | 494 --- hdr/PublicWS | 94 - hdr/RISCOS | 395 --- hdr/Variables | 27 - hdr/VduExt | 126 - s/AMBControl/AMB | 41 - s/AMBControl/Memory | 60 - s/AMBControl/Options | 80 - s/AMBControl/Workspace | 87 - s/AMBControl/allocate | 122 - s/AMBControl/deallocate | 103 - s/AMBControl/growp | 146 - s/AMBControl/growshrink | 170 - s/AMBControl/main | 253 -- s/AMBControl/mapslot | 150 - s/AMBControl/mapsome | 86 - s/AMBControl/memmap | 768 ----- s/AMBControl/readinfo | 68 - s/AMBControl/service | 246 -- s/AMBControl/shrinkp | 102 - s/ARM600 | 3569 --------------------- s/ARMops | 1732 ---------- s/Arthur2 | 2345 -------------- s/Arthur3 | 2478 --------------- s/ArthurSWIs | 1281 -------- s/ChangeDyn | 4773 ---------------------------- s/Convrsions | 387 --- s/End | 22 - s/ExtraSWIs | 81 - s/FlashROM | 671 ---- s/GetAll | 205 -- s/HAL | 2154 ------------- s/HeapMan | 1637 ---------- s/HeapSort | 411 --- s/KbdResA1 | 326 -- s/KbdResPC | 190 -- s/KbdResRCMM | 280 -- s/Kernel | 1619 ---------- s/LibKern | 120 - s/MEMC1 | 571 ---- s/MEMC2 | 713 ----- s/MOSDict | 69 - s/MemInfo | 1220 ------- s/Middle | 1957 ------------ s/ModHand | 3794 ---------------------- s/MoreComms | 574 ---- s/MoreSWIs | 1198 ------- s/Morris | 81 - s/MsgCode | 632 ---- s/NewIRQs | 1537 --------- s/NewReset | 2337 -------------- s/Oscli | 1500 --------- s/PMF/Buffer | 319 -- s/PMF/Def | 148 - s/PMF/IIC | 948 ------ s/PMF/Internat | 250 -- s/PMF/KbdDrA1 | 611 ---- s/PMF/convdate | 109 - s/PMF/i2cutils | 1871 ----------- s/PMF/key | 1478 --------- s/PMF/mouse | 474 --- s/PMF/osbyte | 1267 -------- s/PMF/oseven | 230 -- s/PMF/osinit | 1409 -------- s/PMF/osword | 776 ----- s/PMF/oswrch | 182 -- s/PMF/realtime | 177 -- s/SWINaming | 675 ---- s/Super1 | 101 - s/SysComms | 1875 ----------- s/TickEvents | 250 -- s/UnSqueeze | 353 -- s/Utility | 1112 ------- s/vdu/vdu23 | 1700 ---------- s/vdu/vdu5 | 656 ---- s/vdu/vducursoft | 712 ----- s/vdu/vdudecl | 423 --- s/vdu/vdudriver | 2450 -------------- s/vdu/vdufont | 243 -- s/vdu/vdufontl1 | 247 -- s/vdu/vdugrafa | 396 --- s/vdu/vdugrafb | 1120 ------- s/vdu/vdugrafc | 441 --- s/vdu/vdugrafd | 592 ---- s/vdu/vdugrafdec | 308 -- s/vdu/vdugrafe | 995 ------ s/vdu/vdugraff | 906 ------ s/vdu/vdugrafg | 2678 ---------------- s/vdu/vdugrafh | 1191 ------- s/vdu/vdugrafi | 339 -- s/vdu/vdugrafj | 1331 -------- s/vdu/vdugrafk | 458 --- s/vdu/vdugrafl | 700 ---- s/vdu/vdugrafv | 172 - s/vdu/vduhint | 1398 -------- s/vdu/vdumodes | 1111 ------- s/vdu/vdupal10 | 603 ---- s/vdu/vdupal20 | 1167 ------- s/vdu/vdupalette | 226 -- s/vdu/vdupalxx | 1129 ------- s/vdu/vduplot | 1611 ---------- s/vdu/vdupointer | 554 ---- s/vdu/vduswis | 2102 ------------ s/vdu/vduttx | 1834 ----------- s/vdu/vduwrch | 3340 ------------------- 185 files changed, 114607 deletions(-) delete mode 100644 Docs/HAL/ADisNote delete mode 100644 Docs/HAL/ARMop_API delete mode 100644 Docs/HAL/Entries delete mode 100644 Docs/HAL/HAL_API delete mode 100644 Docs/HAL/Init delete mode 100644 Docs/HAL/MoreEnts delete mode 100644 Docs/HAL/NewAPI delete mode 100644 Docs/HAL/NewCDV delete mode 100644 Docs/HAL/Notes delete mode 100644 Docs/HAL/OS_Hardware delete mode 100644 Docs/HAL/OpenBusAdapter delete mode 100644 Docs/HAL/Serial delete mode 100644 Docs/MemMaps/+Access,ffd delete mode 100644 Docs/MemMaps/+SrcIndex delete mode 100644 Docs/MemMaps/+SrcIndexO delete mode 100644 Docs/MemMaps/130 delete mode 100644 Docs/MemMaps/258 delete mode 100644 Docs/PrivDoc/+Access,ffd delete mode 100644 Docs/PrivDoc/+SrcIndex delete mode 100644 Docs/PrivDoc/+SrcIndexO delete mode 100644 Docs/PrivDoc/5thColumn/+Access,ffd delete mode 100644 Docs/PrivDoc/5thColumn/+SrcIndex delete mode 100644 Docs/PrivDoc/5thColumn/+SrcIndexO delete mode 100644 Docs/PrivDoc/5thColumn/Concept delete mode 100644 Docs/PrivDoc/MMPM delete mode 100644 Docs/PrivDoc/ScreenMode delete mode 100644 NewModes/Make,feb delete mode 100644 NewModes/NEWF2 delete mode 100644 NewModes/NEWFORMAT delete mode 100644 NewModes/OldFormat delete mode 100644 NewModes/OldPSSrc delete mode 100644 NewModes/OldToNew,ffb delete mode 100644 NewModes/PSSrc delete mode 100644 Resources/UK/CmdHelp delete mode 100644 Resources/UK/Messages delete mode 100644 Resources/UK/Morris4/Messages delete mode 100644 Resources/UK/Omega/Messages delete mode 100644 Resources/UK/Ursula/Messages delete mode 100644 TestSrc/A600tlb delete mode 100644 TestSrc/Arm3 delete mode 100644 TestSrc/Begin delete mode 100644 TestSrc/Cmos delete mode 100644 TestSrc/ErrorCount,ffb delete mode 100644 TestSrc/ExtCmd delete mode 100644 TestSrc/ExtIO delete mode 100644 TestSrc/InitModule delete mode 100644 TestSrc/Ioc delete mode 100644 TestSrc/LEDDelay delete mode 100644 TestSrc/MEMC1 delete mode 100644 TestSrc/Mem1IOMD delete mode 100644 TestSrc/Mem1MEMC1 delete mode 100644 TestSrc/Mem2 delete mode 100644 TestSrc/Mem3 delete mode 100644 TestSrc/Mem4 delete mode 100644 TestSrc/Mem5 delete mode 100644 TestSrc/ROMCard delete mode 100644 TestSrc/ShowIOMDRs delete mode 100644 TestSrc/TestMain delete mode 100644 TestSrc/ToggleLED delete mode 100644 TestSrc/Vidc delete mode 100644 h/HALDevice delete mode 100644 hdr/ARMops delete mode 100644 hdr/Copro15ops delete mode 100644 hdr/EnvNumbers delete mode 100644 hdr/ExportVals/!HowTo delete mode 100644 hdr/ExportVals/Makefile delete mode 100644 hdr/ExportVals/Mk,fd7 delete mode 100644 hdr/ExportVals/s/GetVals delete mode 100644 hdr/ExportVals/values delete mode 100644 hdr/HALDevice delete mode 100644 hdr/HALEntries delete mode 100644 hdr/KernelWS delete mode 100644 hdr/KeyWS delete mode 100644 hdr/ModHand delete mode 100644 hdr/OSEntries delete mode 100644 hdr/Old/Arthur/PublicWS delete mode 100644 hdr/Old/Arthur/Space200 delete mode 100644 hdr/Old/NewSpace delete mode 100644 hdr/Old/VickySpace delete mode 100644 hdr/Options delete mode 100644 hdr/PublicWS delete mode 100644 hdr/RISCOS delete mode 100644 hdr/Variables delete mode 100644 hdr/VduExt delete mode 100644 s/AMBControl/AMB delete mode 100644 s/AMBControl/Memory delete mode 100644 s/AMBControl/Options delete mode 100644 s/AMBControl/Workspace delete mode 100644 s/AMBControl/allocate delete mode 100644 s/AMBControl/deallocate delete mode 100644 s/AMBControl/growp delete mode 100644 s/AMBControl/growshrink delete mode 100644 s/AMBControl/main delete mode 100644 s/AMBControl/mapslot delete mode 100644 s/AMBControl/mapsome delete mode 100644 s/AMBControl/memmap delete mode 100644 s/AMBControl/readinfo delete mode 100644 s/AMBControl/service delete mode 100644 s/AMBControl/shrinkp delete mode 100644 s/ARM600 delete mode 100644 s/ARMops delete mode 100644 s/Arthur2 delete mode 100644 s/Arthur3 delete mode 100644 s/ArthurSWIs delete mode 100644 s/ChangeDyn delete mode 100644 s/Convrsions delete mode 100644 s/End delete mode 100644 s/ExtraSWIs delete mode 100644 s/FlashROM delete mode 100644 s/GetAll delete mode 100644 s/HAL delete mode 100644 s/HeapMan delete mode 100644 s/HeapSort delete mode 100644 s/KbdResA1 delete mode 100644 s/KbdResPC delete mode 100644 s/KbdResRCMM delete mode 100644 s/Kernel delete mode 100644 s/LibKern delete mode 100644 s/MEMC1 delete mode 100644 s/MEMC2 delete mode 100644 s/MOSDict delete mode 100644 s/MemInfo delete mode 100644 s/Middle delete mode 100644 s/ModHand delete mode 100644 s/MoreComms delete mode 100644 s/MoreSWIs delete mode 100644 s/Morris delete mode 100644 s/MsgCode delete mode 100644 s/NewIRQs delete mode 100644 s/NewReset delete mode 100644 s/Oscli delete mode 100644 s/PMF/Buffer delete mode 100644 s/PMF/Def delete mode 100644 s/PMF/IIC delete mode 100644 s/PMF/Internat delete mode 100644 s/PMF/KbdDrA1 delete mode 100644 s/PMF/convdate delete mode 100644 s/PMF/i2cutils delete mode 100644 s/PMF/key delete mode 100644 s/PMF/mouse delete mode 100644 s/PMF/osbyte delete mode 100644 s/PMF/oseven delete mode 100644 s/PMF/osinit delete mode 100644 s/PMF/osword delete mode 100644 s/PMF/oswrch delete mode 100644 s/PMF/realtime delete mode 100644 s/SWINaming delete mode 100644 s/Super1 delete mode 100644 s/SysComms delete mode 100644 s/TickEvents delete mode 100644 s/UnSqueeze delete mode 100644 s/Utility delete mode 100644 s/vdu/vdu23 delete mode 100644 s/vdu/vdu5 delete mode 100644 s/vdu/vducursoft delete mode 100644 s/vdu/vdudecl delete mode 100644 s/vdu/vdudriver delete mode 100644 s/vdu/vdufont delete mode 100644 s/vdu/vdufontl1 delete mode 100644 s/vdu/vdugrafa delete mode 100644 s/vdu/vdugrafb delete mode 100644 s/vdu/vdugrafc delete mode 100644 s/vdu/vdugrafd delete mode 100644 s/vdu/vdugrafdec delete mode 100644 s/vdu/vdugrafe delete mode 100644 s/vdu/vdugraff delete mode 100644 s/vdu/vdugrafg delete mode 100644 s/vdu/vdugrafh delete mode 100644 s/vdu/vdugrafi delete mode 100644 s/vdu/vdugrafj delete mode 100644 s/vdu/vdugrafk delete mode 100644 s/vdu/vdugrafl delete mode 100644 s/vdu/vdugrafv delete mode 100644 s/vdu/vduhint delete mode 100644 s/vdu/vdumodes delete mode 100644 s/vdu/vdupal10 delete mode 100644 s/vdu/vdupal20 delete mode 100644 s/vdu/vdupalette delete mode 100644 s/vdu/vdupalxx delete mode 100644 s/vdu/vduplot delete mode 100644 s/vdu/vdupointer delete mode 100644 s/vdu/vduswis delete mode 100644 s/vdu/vduttx delete mode 100644 s/vdu/vduwrch diff --git a/.gitattributes b/.gitattributes index f3d97fc5..d0460a77 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,5 +1 @@ -hdr/** gitlab-language=armasm linguist-language=armasm linguist-detectable=true -s/** gitlab-language=armasm linguist-language=armasm linguist-detectable=true **/s/** gitlab-language=armasm linguist-language=armasm linguist-detectable=true -*,ffb gitlab-language=bbcbasic linguist-language=bbcbasic linguist-detectable=true -h/** gitlab-language=c linguist-language=c linguist-detectable=true diff --git a/Docs/HAL/ADisNote b/Docs/HAL/ADisNote deleted file mode 100644 index c3cb1bc6..00000000 --- a/Docs/HAL/ADisNote +++ /dev/null @@ -1,48 +0,0 @@ -0 STATE (X) 0->X (8) -1 nWAIT 1->9 -2 BRST 2->X (2) -3 nFIQ 3->X (13) -4 nIRQ 4->X (12) -5 nc (MAS[0]) 5->6 -6 nMREQ 1 6->1 -7 SEQ (X) 7->0 -8 nRW 8->3 -9 nBW (MAS[1]) 9->7 -10 LOCK 10->X (10) -11 nTRANS (X) 11->5 -12 nOPC (X) 12->4 -13 nc 13->11 (DMA low) -14 ABE -15 DBE - - - -Master clock: (MCLK down) -0 SEQ 0->7 -1 nMREQ 1->6 -2 nEXEC - -Slave clock: (MCLK up) -3 nRW 16->8 -4 nOPC 17->12 -5 nTRANS 18->11 -6 MAS[0] 19->5 -7 MAS[1] 20->9 -8 DBGACK -9 nWAIT 22->1 -10 ABORT -11 DMA -12 BIGEND -13 CS0 -14 CS1 -15 CS2 -16 CS3 -17 CS4 -18 CS5 -19 CS6 -20 CS7 - - -0 - -0->X \ No newline at end of file diff --git a/Docs/HAL/ARMop_API b/Docs/HAL/ARMop_API deleted file mode 100644 index 0321389e..00000000 --- a/Docs/HAL/ARMop_API +++ /dev/null @@ -1,441 +0,0 @@ -12345678901234567890123456789012345678901234567890123456789012345678901234567890 - -mjs 12 Jan 2001 Early Draft -mjs 14 Feb 2001 XScale survey revised, ARMop reentrancy defined - - -RISC OS Kernel ARM core support -=============================== - -This document is concerned with the design of open ended support for -multiple ARM cores within the RISC OS kernel, as part of the work loosely -termed hardware abstraction. Note that the ARM core support is part of the -OS kernel, and so is not part of the hardware abstraction layer (HAL) -itself. - -Background ----------- - -ARM core support (including caches and MMU) has historically been coded in a -tailored way for one or two specific variants. Since version 3.7 this has -meant just two variants; ARM 6/7 and StrongARM SA110. A more generic -approach is required for the next generation. This aims both to support -several cores in a more structured way, and to cover minor variants (eg. -cache size) with the same support code. The natural approach is to set up -run-time vectors to a set of ARM support routines. - -Note that it is currently assumed that the ARM MMU architecture will not -change radically in future ARM cores. Hence, the kernel memory management -algorithms remain largely unchanged. This is believed to be a reasonable -assumption, since the last major memory management change was with Risc PC -and ARM 610 (when the on-chip MMU was introduced). - -Note that all ARM support code must be 32-bit clean, as part of the 32-bit -clean kernel. - -Survey of ARM core requirements -------------------------------- - -At present, five broad ARM core types can be considered to be of interest; -ARM7 (and ARM6), ARM9, ARM10, StrongARM (SA1) and XScale. These divide -primarily in terms of cache types, and cache and TLB maintenance -requirements. They also span a range of defined ARM architecture variants, -which introduced variants for system operations (primarily coprocessor 15 -instructions). - -The current ARM architecture is version 5. This (and version 4) has some -open ended definitions to allow code to determine cache size and types from -CP15 registers. Hence, the design of the support code can hope to be at -least tolerant of near future variations that are introduced. - -ARM7 ----- - -ARM7 cores may be architecture 3 or 4. They differ in required coprocessor -15 operations for the same cache and TLB control. ARM6 cores are much the -same as architecture 3 ARM7. The general character of all these cores is of -unified write-through caches that can only be invalidated on a global basis. -The TLBs are also unified, and can be invalidated per entry or globally. - -ARM9 ----- - -ARM9 cores are architecture 4. We ignore ARM9 variants without an MMU. The -kernel can read cache size and features. The ARM 920 or 922 have harvard -caches, with writeback and writethrough capable data caches (on a page or -section granularity). Data and instruction caches can be invalidated by -individual lines or globally. The data cache can be cleaned by virtual -address or cache segment/index, allowing for efficient cache maintenance. -Data and instruction TLBs can be invalidated by entry or globally. - -ARM10 ------ - -ARM 10 is architecture 5. Few details available at present. Likely to be -similar to ARM9 in terms of cache features and available operations. - -StrongARM ---------- - -StrongARM is architecture 4. StrongARMs have harvard caches, the data cache -being writeback only (no writethrough option). The data cache can only be -globally cleaned in an indirect manner, by reading from otherwise unused -address space. This is inefficient because it requires external (to the -core) reads on the bus. In particular, the minimum cost of a clean, for a -nearly clean cache, is high. The data cache supports clean and invalidate by -individual virtual lines, so this is reasonably efficient for small ranges -of address. The data TLB can be invalidated by entry or globally. - -The instruction cache can only be invalidated globally. This is inefficient -for cases such as IMBs over a small range (dynamic code). The instruction -TLB can only be invalidated globally. - -Some StrongARM variants have a mini data cache. This is selected over the -main cache on a section or page by using the cachable/bufferable bits set to -C=1,B=0 in the MMU (this is not standard ARM architecture). The mini data -cache is writeback and must be cleaned in the same manner as the main data -cache. - -XScale ------- - -XScale is architecture 5. It implements harvard caches, the data cache being -writeback or writethrough (on a page or section granularity). Data and -instruction caches can be invalidated by individual lines or globally. The -data cache can be fully cleaned by allocating lines from otherwise unused -address space. Unlike StrongARM, no external reads are needed for the clean -operation, so that cache maintenance is efficient. - -XScale has a mini data cache. This is only available by using extension bits -in the MMU. This extension is not documented in the current manual for -architecture 5, but will presumably be properly recognised by ARM. It should -be a reasonably straightforward extension for RISC OS. The mini data cache -can only be cleaned by inefficient indirect reads as on StrongARM. - -For XScale, the whole mini data cache can be configured as writethrough. The -most likely use for RISC OS is to map screen memory as mini cacheable, so -writethrough caching will be selected to prevent problems with delayed -screen update (and hence intricate screen/cache management code as in Ursula -for StrongARM). With writethrough configured, most operations can ignore the -mini cache, because invalidation by virtual address will invalidate mini or -main cache entries as appropriate. - -Unfortunately, for global cache invalidatation, things are very awkward. -RISC OS cannot use the global cache invalidate operation (which globally -invalidates both data caches), unless it is very careful to 100% clean the -main cache with all interrupts (IRQs and FIQs) disabled. This is to avoid -fatal loss of uncleaned lines from the writeback main cache. Disabling -interrupts for the duration of a main cache clean is an unacceptable -latency. Therefore, reluctantly, RISC OS must do the equivalent of cleaning -the mini cache (slow physical reads) in order to globally invalidate it as a -side effect. - -The instruction and data TLBs can each be invalidated by entry or globally. - - -Kernel ARM operations ---------------------- - -This section lists the definitions and API of the set of ARM operations -(ARMops) required by the kernel for each major ARM type that is to be -supported. Some operations may be very simple on some ARMs. Others may need -support from the kernel environment - for example, readable parameters that -have been determined at boot, or address space available for cache clean -operations. - -The general rules for register usage and preservation in calling these -ARMops iare: - - - any parameters are passed in r0,r1 etc. as required - - r0 may be used as a scratch register - - the routines see a valid stack via sp, at least 16 words are available - - lr is the return link as required - - on exit, all registers except r0 and lr must be preserved - -Note that where register values are given as logical addresses, these are -RISC OS logical addresses. The equivalent ARM terminology is virtual address -(VA), or modified virtual address (MVA) for architectures with the fast -context switch extension. - -Note also that where cache invalidation is required, it is implicit that any -associated operations for a particular ARM should be performed also. The -most obvious example is for an ARM with branch prediction, where it may be -necessary to invalidate a branch cache anywhere where instruction cache -invalidation is to be performed. - -Any operation that is a null operation on the given ARM should be -implemented as a single return instruction: - - MOV pc, lr - - -ARMop reentrancy ----------------- - -In general, the operations will be called from SVC mode with interrupts -enabled. However, some use of some operations from interrupt mode is -expected. Notably, it is desirable for the IMB operations to be -available from interrupt mode. Therefore, it is intended that all -implementations of all ARMops be reentrant. Most will be so with no -difficulty. For ARMs with writeback data caches, the cleaning algorithm -may have to be constructed carefully to handle reentrancy (and to avoid -turning off interrupts for the duration of a clean). - - -Cache ARMops ------------- - --- Cache_CleanInvalidateAll - -The cache or caches are to be globally invalidated, with cleaning of any -writeback data being properly performed. - - entry: - - exit: - - -Note that any write buffer draining should also be performed by this -operation, so that memory is fully updated with respect to any writeaback -data. - -The OS only expects the invalidation to be with respect to instructions/data -that are not involved in any currently active interrupts. In other words, it -is expected and desirable that interrupts remain enabled during any extended -clean operation, in order to avoid impact on interrupt latency. - --- Cache_CleanAll - -The unified cache or data cache are to be globally cleaned (any writeback data -updated to memory). Invalidation is not required. - - entry: - - exit: - - -Note that any write buffer draining should also be performed by this -operation, so that memory is fully updated with respect to any writeaback -data. - -The OS only expects the cleaning to be with respect to data that are not -involved in any currently active interrupts. In other words, it is expected -and desirable that interrupts remain enabled during any extended clean -operation, in order to avoid impact on interrupt latency. - --- Cache_InvalidateAll - -The cache or caches are to be globally invalidated. Cleaning of any writeback -data is not to be performed. - - entry: - - exit: - - -This call is only required for special restart use, since it implies that -any writeback data are either irrelevant or not valid. It should be a very -simple operation on all ARMs. - --- Cache_RangeThreshold - -Return a threshold value for an address range, above which it is advisable -to globally clean and/or invalidate caches, for performance reasons. For a -range less than or equal to the threshold, a ranged cache operation is -recommended. - - entry: - - exit: r0 = threshold value (bytes) - -This call returns a value that the kernel may use to select between strategies -in some cache operations. This threshold may also be of use to some of the -ARM operations themselves (although they should typically be able to read -the parameter more directly). - -The exact value is unlikely to be critical, but a sensible value may depend -on both the ARM and external factors such as memory bus speed. - - --- WriteBuffer_Drain - -Any writebuffers are to be drained so that any pending writes are guaranteed -completed to memory. - - entry: - - exit: - - - -TLB ARMops ----------- - --- TLB_InvalidateAll - -The TLB or TLBs are to be globally invalidated. - - entry: - - exit: - - - --- TLB_InvalidateEntry - -The TLB or TLBs are to be invalidated for the entry at the given logical -address. - - entry: r0 = logical address of entry to invalidate (page aligned) - exit: - - -The address will always be page aligned (4k). - - -IMB ARMops ----------- - --- IMB_Full - -A global instruction memory barrier (IMB) is to be performed. - - entry: - - exit: - - -An IMB is an operation that should be performed after new instructions have -been stored and before they are executed. It guarantees correct operation -for code modification (eg. something as simple as loading code to be -executed). - -On some ARMs, this operation may be null. On ARMs with harvard architecture -this typically consists of: - - 1) clean data cache - 2) drain write buffer - 3) invalidate instruction cache - -There may be other considerations such as invalidating branch prediction -caches. - - --- IMB_Range - -An instruction memory barrier (IMB) is to be performed over a logical -address range. - - entry: r0 = logical address of start of range - r1 = logical address of end of range (exclusive) - Note that r0 and r1 are aligned on cache line boundaries - exit: - - -An IMB is an operation that should be performed after new instructions have -been stored and before they are executed. It guarantees correct operation -for code modification (eg. something as simple as loading code to be -executed). - -On some ARMs, this operation may be null. On ARMs with harvard architecture -this typically consists of: - - 1) clean data cache over the range - 2) drain write buffer - 3) invalidate instruction cache over the range - -There may be other considerations such as invalidating branch prediction -caches. - -Note that the range may be very large. The implementation of this call is -typically expected to use a threshold (related to Cache_RangeThreshold) to -decide when to perform IMB_Full instead, being faster for large ranges. - - -MMU mapping ARMops ------------------- - --- MMU_Changing - -The global MMU mapping is about to be changed. - - entry: - - exit: - - -The operation must typically perform the following: - - 1) globally clean and invalidate all caches - 2) drain write buffer - 3) globally invalidate TLB or TLBs - -Note that it should not be necessary to disable IRQs. The OS ensures that -remappings do not affect currently active interrupts. - --- MMU_ChangingEntry - -The MMU mapping is about to be changed for a single page entry (4k). - - entry: r0 = logical address of entry (page aligned) - exit: - - -The operation must typically perform the following: - - 1) clean and invalidate all caches over the 4k range of the page - 2) drain write buffer - 3) invalidate TLB or TLBs for the entry - -Note that it should not be necessary to disable IRQs. The OS ensures that -remappings do not affect currently active interrupts. - --- MMU_ChangingUncached - -The MMU mapping is about to be changed in a way that globally affects -uncacheable space. - - entry: - - exit: - - -The operation must typically globally invalidate the TLB or TLBs. The OS -guarantees that cacheable space is not affected, so cache operations are not -required. However, there may still be considerations such as fill buffers -that operate in uncacheable space on some ARMs. - --- MMU_ChangingUncachedEntry - -The MMU mapping is about to be changed for a single uncacheable page entry -(4k). - - entry: r0 = logical address of entry (page aligned) - exit: - - -The operation must typically invalidate the TLB or TLBs for the entry. The -OS guarantees that cacheable space is not affected, so cache operations are -not required. However, there may still be considerations such as fill -buffers that operate in uncacheable space on some ARMs. - - --- MMU_ChangingEntries - -The MMU mapping is about to be changed for a contiguous range of page -entries (multiple of 4k). - - entry: r0 = logical address of first page entry (page aligned) - r1 = number of page entries ( >= 1) - exit: - - -The operation must typically perform the following: - - 1) clean and invalidate all caches over the range of the pages - 2) drain write buffer - 3) invalidate TLB or TLBs over the range of the entries - -Note that it should not be necessary to disable IRQs. The OS ensures that -remappings do not affect currently active interrupts. - -Note that the number of entries may be large. The operation is typically -expected to use a reasonable threshold, above which it performs a global -operation instead for speed reasons. - --- MMU_ChangingUncachedEntries - -The MMU mapping is about to be changed for a contiguous range of uncacheable -page entries (multiple of 4k). - - entry: r0 = logical address of first page entry (page aligned) - r1 = number of page entries ( >= 1) - exit: - - -The operation must typically invalidate the TLB or TLBs over the range of -the entries. The OS guarantees that cacheable space is not affected, so -cache operations are not required. However, there may still be -considerations such as fill buffers that operate in uncacheable space on -some ARMs. - -Note that the number of entries may be large. The operation is typically -expected to use a reasonable threshold, above which it performs a global -operation instead for speed reasons. diff --git a/Docs/HAL/Entries b/Docs/HAL/Entries deleted file mode 100644 index 3c43b939..00000000 --- a/Docs/HAL/Entries +++ /dev/null @@ -1,343 +0,0 @@ -RISC OS and the "HAL" -===================== - -RISC OS currently is tied to the IOMD20 and VIDC20 peripheral set, -descendents of the original IOC, MEMC and VIDC devices designed in parallel -with the original ARM. These devices provide a close fit with RISC OS, and -their functionality is well suited to general purpose and embedded systems, -but the continuing drive to reduce cost requires us to support other -peripheral sets on off-the-shelf ARM system on chips. - -First targets for support are L7205/L7210 for Customer L and CL92xx (the new -ARM920T based devices) for Customer A. Enclosed are a summary of their -advantages and disadvantages over the ARM7500FE for our Information -Appliance designs. - - L7205 CL92xx - + Faster (50% or so) + Faster (400%+) - + SDRAM support + SDRAM support - + USB + USB - + EIDE interface - + Lots of GPIO - - No hardware cursor - - No floating point - Incompatible floating point - - No video DACs - No video DACs - - No PS/2 - No PS/2 - - Bizarre MS-Windows video system - - -To support these devices, and others in the future, a simple HAL is to be -inserted underneath RISC OS. This will provide two functions. Firstly, it -will be responsible for initial system bootstrap, much like a PC BIOS, and -secondly it will provide simple APIs to allow hardware access. - -The HAL APIs are a thin veneer on top of the hardware. They are designed to -act as replacements for all the hardware knowledge and manipulation performed -by the RISC OS Kernel, together with some APIs that will allow RISC OS driver -modules to become more hardware independent. No attempt will be made (at this -stage) to perform such tasks as separating the video drivers from the Kernel, -for example. - -One tricky design decision is the amount of abstraction to aim for. Too -little, and the system is not flexible enough; too much and HAL design is -needlessly complicated for simple hardware. The present design tries to -err on the side of too little abstraction. Extra, more abstract APIs can -always be added later. So, initially, for example, the serial device API -will just provide discovery, some capability flags and the base address -of the UART register set. This will be sufficient for the vast majority -of devices. If new hardware comes along later that isn't UART compatible, -a new API can be defined. Simple hardware can continue to just report -UART base addresses. - -The bulk of device driver implementation remains in RISC OS modules - the -difference is that the HAL will allow many device drivers to no longer -directly access hardware. For example, PS2Driver can now use HAL calls to -send and receive bytes through the PS/2 ports, and thus is no longer tied to -IOMD's PS/2 hardware. Similarly, interrupt masking and unmasking, as -performed by any device vector claimant, is now a HAL call. Note that HAL -calls are normally performed via a Kernel SWI - alternatively the Kernel -can return the address of specific Kernel routines. There is nothing to stop -specific drivers talking to hardware directly, as long as they accept that -this will tie them to specific devices. - -This dividing line between the HAL and RISC OS driver modules is crucial. If -the HAL does everything, then we have achieved nothing - we have just as much -hardware dependent code - it's just in a different place. It is important to -place the dividing line as close to the hardware as possible, to make it easy -to design a HAL and to prevent large amounts of code duplication between -HALs for different platforms. - -The Kernel remains responsible for the ARM's MMU and all other aspects of the -CPU core. The HAL requires no knowledge of details of ARM implementations, -and thus any HAL implementation should work on any processor from the ARM610 -to the ARM940T or XScale. - - -OS independence -=============== - -Notionally, the HAL implementation is OS independent. It makes no assumptions -about the virtual memory map of the OS, and only uses the defined HAL->OS -entries. The HAL should not call RISC OS SWIs. - -In practice, however, the HALs are unlikely to be used on anything other -than RISC OS, and many HALs are likely to be written. This makes it sensible -to place as much intelligence as possible within RISC OS itself, to prevent -duplicated effort. - - - -Calling standards -================= - -RISC OS and the HAL are two separate entities, potentially linked separately. -Thus some simple dynamic linking is required. This occurs via a hybrid of the -RISC OS module header and Shared C Library stubs. Each RISC OS/HAL entry is -given a unique (arbitrary) number, starting at 0. The offset to each entry is -given in an entry table. Calls can be made manually through this table, or -stubs could be created at run-time to allow high-level language calls. - -Every entry (up to the declared maximum) must exist. If not implemented, a -failure response must be returned, or the call ignored, as appropriate. - -To permit high-level language use in the future, the procedure call standard -in both directions is ATPCS, with no use of floating point, no stack limit -checking, no frame pointers, and no Thumb interworking. HAL code is expected -to be ROPI and RWPI (hence it is called with its static workspace base in -sb). The OS kernel is neither ROPI nor RWPI (except for the pre-MMU calls, -which are ROPI). - -The HAL will always be called in a privileged mode - if called in an -interrupt mode, the corresponding interrupts will be disabled. The HAL should -not change mode. HAL code should work in both 26-bit and 32-bit modes (but -should assume 32-bit configuration). - - -Header formats -============== - -The OS is linked to run at a particular base address. At present, the address -will be at <n>MB + 64KB. This allows a HAL of up to 64K to be placed at the -bottom of a ROM below the OS, and the whole thing to be section-mapped. -However, if a different arrangement is used, the system will still work -(albeit slightly less efficiently). - -The OS starts with a magic word - this aids probing and location of images. -Following that is a defined header format: - -Word 0: Magic word ("OSIm" - &6D49534F) -Word 1: Flags (0) -Word 2: Image size -Word 3: Offset from base to entry table -Word 4: Number of entries available - -The HAL itself may have whatever header is required to start the system. For -example on ARM7500 16->32 bit switch code is required, and on the 9500 parts -a special ROM header and checksum must be present. Instead of a header, -a pointer to the HAL descriptor is passed to the OS in the OS_Start call: - -Word 0: Flags - bit 0 => uncachable workspace (32K) required - bits 1-31 reserved -Word 1: Offset from descriptor to start of HAL (will be <= 0) -Word 2: HAL size -Word 3: Offset from descriptor to entry table -Word 4: Number of entries available -Word 5: Static workspace required - -Each of the HAL and the OS must be contiguous within physical memory. - - - - - - -RISC OS entry points from HAL init -================================== - - -Entry 0: -void RISCOS_InitARM(unsigned int flags) - - flags: reserved - sbz - -On entry: - SVC mode - MMU and caches off - IRQs and FIQs disabled - No RAM or stack used - -On exit: - Instruction cache may be on - -Usage: - This routine must be called once very early on in the HAL start-up, to accelerate the - CPU for the rest of HAL initialisation. Typically, it will just enable the instruction - cache (if possible on the ARM in use), and ensure that the processor is in 32-bit - configuration and mode. - - Some architecture 4 (and later) ARMs have bits in the control register that affect - the hardware layer - eg the iA and nF bits in the ARM920T. These are the HAL's - responsibility - the OS will not touch them. Conversely, the HAL should not touch the - cache, MMU and core configuration bits (currently bits 0-14). - - On architecture 3, the control register is write only - the OS will set bits 11-31 to - zero. - - Likewise, such things as the StrongARM 110's register 15 (Test, Clock and Idle Control) - are the HAL's responsibility. The OS does not know about the configuration of the - system, so cannot program such registers. - - This entry may not be called after RISCOS_Start. - - - -Entry 1: -void *RISCOS_AddRAM(unsigned int flags, void *start, void *end, uintptr_t sigbits, void *ref) - flags - bit 0: video memory (only first contiguous range will be used) - bits 8-11: speed indicator (arbitrary, higher => faster) - other bits reserved (SBZ) - start - start address of RAM (inclusive) (no alignment requirements) - end - end address of RAM (exclusive) (no alignment requirements, but must be >= start) - sigbits - significant address bit mask (1 => this bit of addr decoded, 0 => this bit ignored) - ref - reference handle (NULL for first call) - -Returns ref for next call - -On entry: - SVC32 mode - MMU and data cache off - IRQs and FIQs disabled - -Other notes: - This entry point must be the first call from the HAL to RISC OS following a hardware - reset. It may be called as many times as necessary to give all enumerate RAM that - is available for general purpose use. It should only be called to declare video - memory if the video memory may be used as normal RAM when in small video modes. - - To permit software resets: - The HAL must be non-destructive of any declared RAM outside the first 4K of the first - block. - The stack pointer should be initialised 4K into the first block, or in some non- - declared RAM. - Must present memory in a fixed order on any given system. - - Current limitations: - The first block must be at least 256K and 16K aligned. (Yuck) - Block coalescing only works well if RAM banks are added in ascending address order. - - RISC OS will use RAM at the start of the first block as initial workspace. Max usage - is 16 bytes per block + 32 (currently 8 per block + 4). This limits the number of - discontiguous blocks (although RISC OS will concatanate contiguous blocks where - possible). - - This call must not be made after RISCOS_Start. - - -Entry 2: -void RISCOS_Start(unsigned int flags, int *riscos_header, int *hal_entry_table, void *ref) - - flags - bit 0: power on reset - bit 1: CMOS reset inhibited (eg protection link on Risc PC) - bit 2: perform a CMOS reset (if bit 1 clear and bit 0 set - eg front panel - button held down on an NC) - -On entry: - SVC32 mode - MMU and data cache off - IRQs and FIQs disabled - -Usage: - This routine must be called after all calls to RISCOS_AddRAM have been completed. - It does not return. Future calls back to the HAL are via the HAL entry table, after - the MMU has been enabled. - - -Entry 3: -void *RISCOS_MapInIO(unsigned int flags, void *phys, unsigned int size) - - flags: bit 2 => make memory bufferable - phys: physical address to map in - size: number of bytes of memory to map in - -Usage: - This routine is used to map in IO memory for the HAL's usage. Normally it would - only be called during HAL_Init(). Once mapped in the IO space cannot be released. - - It returns the resultant virtual address corresponding to phys, or 0 for failure. - Failure can only occur if no RAM is available for page tables, or if the virtual - address space is exhausted. - - - -void *RISCOS_AccessPhysicalAddress(unsigned int flags, void *phys, void **oldp) - - flags: bit 2 => make memory bufferable - other bits must be zero - phys: physical address to access - oldp: pointer to location to store old state (or NULL) - -On entry: - Privileged mode - MMU on - FIQs on - Re-entrant - -On exit: - Returns logical address corresponding to phys - -Usage: - Arranges for the physical address phys to be mapped in to logical memory. - In fact, the whole megabyte containing "phys" is mapped in (ie if phys = - &12345678, then &12300000 to &123FFFFF become available). The memory is - supervisor access only, non-cacheable, non-bufferable by default, and will - remain available until the next call to RISCOS_Release/AccessPhysicalAddress - (although interrupt routines or subroutines may temporarily map in something - else). - - When finished, the user should call RISCOS_ReleasePhysicalAddress. - - - - -void RISCOS_ReleasePhysicalAddress(void *old) - - old: state returned from a previous call to RISCOS_AccessPhysicalAddress - -On entry: - MMU on - FIQs on - Re-entrant - -Usage: - Call with the a value output from a previous RISCOS_ReleasePhysicalAddress. - -Example: - - void *old; - unsigned int *addr = (unsigned int *) 0x80005000; - unsigned int *addr2 = (unsigned int *) 0x90005000; - - addr = (unsigned int *) RISCOS_AccessPhysicalAddress(addr, &old); - addr[0] = 3; addr[1] = 5; - - addr2 = (unsigned int *) RISCOS_AccessPhysicalAddress(addr2, NULL); - *addr2 = 7; - - RISCOS_ReleasePhysicalAddress(old); - - - - - -HAL entries -=========== - - -void HAL_Start(int *riscos_header) diff --git a/Docs/HAL/HAL_API b/Docs/HAL/HAL_API deleted file mode 100644 index 77b577a9..00000000 --- a/Docs/HAL/HAL_API +++ /dev/null @@ -1,1078 +0,0 @@ -12345678901234567890123456789012345678901234567890123456789012345678901234567890 - -2001 - a HAL API ----------------- - -mjs 12 Jan 2001 Early Draft (mjs,kjb) - - -RISC OS Hardware Abstraction -============================ - -Background ----------- - -This document is concerned with low level developments of RISC OS in order -to support future ARM based platforms. Loosely, this has been considered as -creating a hardware abstraction layer, or HAL. This term is a useful -shorthand, but with the following caveats. Firstly, the HAL work is only -envisaged to provide a modest level of low level abstraction (at least for -the next OS generation). Secondly, significant non-HAL work, at all levels, -is required to make a useful next generation RISC OS. - -Note that most of the hardware dependence of the OS is already confined to -low level code (essentially, the kernel and device drivers). Here we assume -that the OS is only expected to run on an ARM processor, and with somewhat -restricted choices of I/O hardware (eg. friendly video pixel formats). - -Up to now (version 4), RISC OS has evolved while closely coupled to an ARM -processor core and to an Acorn proprietary chip set (video, memory, I/O). It -has remained highly hardware specific. For the purposes of further -investment in RISC OS, three key areas of hardware dependence must be -addressed; 32-bit clean operation, support for new ARM cores, support for -various video, memory and I/O configurations. Without all of these, the OS -is essentially useless on forseeable future hardware. - - -32-bit clean code ------------------ - -All RISC OS code must run 32-bit clean on future releases. This is because -all ARM cores from ARM9 onwards (and also some ARM7 variants) have entirely -removed support for RISC OS's native 26-bit modes. Note that 32-bit clean -code is not precluded from working on the older ARM cores (back to ARM 610). - -With more care, 32/26-bit agnostic code can be written to work back to ARM -2. This may be of interest to module and application code, but note that the -OS kernel itself is only expected to work back to ARM 610, since an MMU is -required. - -Much of the work required is routine and has been done for the OS itself -(though long term weeding of consequent bugs is required). A 32-bit -compatible shared C library has been released in order to encourage -conversion of application code by third parties. This work is not part of -hardware abstraction and is not considered further in this document. - -Support for newer ARM cores ---------------------------- - -ARM core support (including caches and MMU) has historically been coded in a -tailored way for one or two specific variants. Since version 3.7 this has -meant just two variants; ARM 6/7 and StrongARM SA110. A more generic -approach is required for the next generation. This aims both to support -several cores in a more structured way, and to cover minor variants (eg. -cache size) with the same support code. The natural approach is to set up -run-time vectors to a set of ARM support routines. - -Note that it is currently assumed that the ARM MMU architecture will not -change radically in future ARM cores. Hence, the kernel memory management -algorithms remain largely unchanged. This is believed to be a reasonable -assumption, since the last major memory management change was with Risc PC -and ARM 610 (when the on-chip MMU was introduced). - -ARM core support is confined almost entirely to the kernel, and is therefore -not strictly part of the HAL. The HAL will only be concerned with any -external factors such as clock selection. Only HAL aspects are considered -further in this document. - -Hardware abstraction layer --------------------------- - -A simple HAL is to be inserted underneath RISC OS. This will provide two -functions. Firstly, it will be responsible for initial system bootstrap, -much like a PC BIOS, and secondly it will provide simple APIs to allow -hardware access. - -The HAL APIs are a thin veneer on top of the hardware. They are designed to -act as replacements for all the hardware knowledge and manipulation -performed by the RISC OS Kernel, together with some APIs that will allow -RISC OS driver modules to become more hardware independent. No attempt will -be made (at this stage) to perform such tasks as separating the video -drivers from the Kernel, for example. - -One tricky design decision is the amount of abstraction to aim for. Too -little, and the system is not flexible enough; too much and HAL design is -needlessly complicated for simple hardware. The present design tries to err -on the side of too little abstraction. Extra, more abstract APIs can always -be added later. So, initially, for example, the serial device API will just -provide discovery, some capability flags and the base address of the UART -register set. This will be sufficient for the vast majority of devices. If -new hardware comes along later that isn't UART compatible, a new API can be -defined. Simple hardware can continue to just report UART base addresses. - -The bulk of device driver implementation remains in RISC OS modules - the -difference is that the HAL will allow many device drivers to avoid direct -access to hardware. For example, PS2Driver can now use HAL calls to send and -receive bytes through the PS/2 ports, and thus is no longer tied to IOMD's -PS/2 hardware. Similarly, interrupt masking and unmasking, as performed by -any device vector claimant, is now a HAL call. Note that HAL calls are -normally performed via a Kernel SWI - alternatively the Kernel can return -the address of specific HAL routines. There is nothing to stop specific -drivers talking to hardware directly, as long as they accept that this will -tie them to specific devices. - -This dividing line between the HAL and RISC OS driver modules is crucial. If -the HAL does everything, then we have achieved nothing - we have just as -much hardware dependent code - it's just in a different place. It is -important to place the dividing line as close to the hardware as possible, -to make it easy to design a HAL and to prevent large amounts of code -duplication between HALs for different platforms. - -The Kernel remains responsible for the ARM's MMU and all other aspects of -the CPU core. The HAL requires no knowledge of details of ARM -implementations, and thus any HAL implementation should work on any -processor from the ARM610 onwards. - - -HAL/OS layout and headers -------------------------- - -The OS is linked to run at a particular base address. Pre-HAL OS's were -linked to run at <n>MB, that is on a MB alignment to allow efficient MMU -section mapping. For simplicity, the HAL/OS layout can allow a fixed maximum -size for the HAL, currently set at 64k. Then the OS base address will be -<n>MB+64k. This allows a HAL of up to 64K to be placed at the bottom of a -ROM below the OS, and the HAL/OS combination to still be section-mapped. A -ROM should be portable to hardware variants merely by replacing the 64k HAL -block. - -A more flexible system would only sacrifice MMU mapping efficiency. The HAL -and OS could be placed in any desired way, provided that each is contiguous -in physical memory. - -The OS starts with a header including a magic word - this aids probing and -location of images. The OS header format is defined as: - -Word 0: Magic word ("OSIm" - &6D49534F) -Word 1: Flags (currently should be 0) -Word 2: Image size (bytes) -Word 3: Offset (bytes) from OS base to table of OS routine entry points -Word 4: Number of entries in table - -The HAL itself should have whatever header is required to start the system. -For example on ARM7500 16->32 bit switch code is required, and on the -9500 parts a special ROM header and checksum must be present. A HAL -descriptor block, instead of a header, can be placed somewhere in the HAL. A -pointer to this block is passed by the HAL to the OS in the OS_Start call: - -Word 0: Flags - bit 0 => uncachable workspace (32K) required - bits 1-31 reserved -Word 1: Offset (bytes) from descriptor to start of HAL (will be <= 0) -Word 2: HAL size (bytes) -Word 3: Offset (bytes) from descriptor to table of HAL routine entry points -Word 4: Number of entries in table -Word 5: Size of HAL static workspace required (bytes) - -Calling standards ------------------ - -RISC OS and the HAL are two separate entities, potentially linked -separately. The OS and the HAL are each defined with a set of callable -routines for the OS/HAL interface. Each HAL entry or each OS entry is given -a unique (arbitrary) number, starting at 0. The offset to each entry is -given in an entry table. Calls can be made manually through this table, or -stubs could be created at run-time to allow high-level language calls. - -Every entry (up to the declared maximum) must exist. If not implemented, a -failure response must be returned, or the call ignored, as appropriate. Note -that the OS interface for the HAL should not be confused with standard OS -calls (SWIs) already defined for use in the OS itself. - -To permit high-level language use in the future, the procedure call standard -in both directions is the ARM-Thumb Procedure Call Standard (ATPCS) as -defined by ARM, with no use of floating point, no stack limit checking, no -frame pointers, and no Thumb interworking. HAL code is expected to be ROPI -and RWPI (ie. all its read-only segments and read-write segments are -position-independent). Hence the HAL is called with its static workspace -base (sb) in r9. The OS kernel is neither ROPI nor RWPI (except for the -pre-MMU calls, which are ROPI). OS calls from the HAL do not use r9 as a -static base. - -The HAL will always be called in a privileged mode - if called in an -interrupt mode, the corresponding interrupts will be disabled. The HAL -should not change mode. HAL code should work in both 26-bit and 32-bit modes -(but should assume 32-bit configuration). - -Routines can be conveniently specified in C language syntax. Typically they -will be written in assembler. In detail, the ATPCS register usage for HAL -calls is as follows: - - ATPCS ARM use at exit - a1 r0 argument 1/return value undefined or return value - a2 r1 argument 2/return value undefined or return value - a3 r2 argument 3/return value undefined or return value - a4 r3 argument 4/return value undefined or return value - v1 r4 var 1 preserved - v2 r5 var 2 preserved - v3 r6 var 3 preserved - v4 r7 var 4 preserved - v5 r8 var 5 preserved - sb r9 static workspace base preserved - v7 r10 var 7 preserved - v8 r11 var 8 preserved - ip r12 scratch undefined - sp r13 stack pointer preserved - lr r14 return link undefined - -The static workspace base points to the HAL workspace. - -Note that HAL calls must be assumed to corrupt all of r0-r3,r12,r14. A -function return value may be in r0, or (less commonly) multiple return -words in two or more of r0-r3. - -If there are more than 4 arguments to a HAL call, arguments 5 onwards must -be pushed onto the stack before the call, and discarded after return. (The -order of arguments is with argument 5 at top of stack, ie. first to be -pulled.) - -The register usage for the OS entry points is the same, except that r9 is -not used as a static base (it is preserved). - -When using assembler, the register usage may seem somewhat restricted, and -cumbersome for more than 4 arguments. However, it is typically a reasonable -balance for function calls (as a PCS would aim to be), and does not preclude -implementation in C for example. Old kernel code may require register -preserving overhead to insert HAL calls easily, but for most calls this is -insignificant, compared to hardware access costs. - -Initialisation sequence ------------------------ - -After system reset, bootstrap code in the HAL will do minimal hardware -set-up ... blah blah - -HAL entry points ----------------- - -These routines are expected to be called from the OS (Kernel). See the -'Calling standards' section for general information on register usage and so -forth. - -Interrupts ----------- - -The HAL must provide the ability to identify, prioritise and mask IRQs, and the ability -to mask FIQs. RISC OS supplies the ARM's processor vectors, and on an IRQ calls the HAL -to request the identity of the highest priority interrupt. - -IRQ and FIQ device numbers are arbitrary, varying from system to system. They should be -arranged to allow quick mappings to and from hardware registers, and should ideally -be packed, starting at 0. - -Timers ------- - -The HAL must supply at least one timer capable of generating periodic -interrupts. Each timer should generate a separate logical interrupt, and the -interrupt must be latched. The timers must either be variable rate (period is -a multiple of a basic granularity), or be fixed rate (period = 1*granularity). -Optionally, the timer should be capable of reporting the time until the -next interrupt, in units of the granularity. - -Counter -------- - -The HAL must supply a counter that varies rapidly, appropriate for use for -sub-millisecond timing. On many systems, this counter will form part of -timer 0 - as such it is not required to operate when timer 0 is not running. -On other systems, the periodic timers may have no readable latch, and a -separate unit will be required. - -The counter should count down from (period-1) to 0 continuously. - -Non-volatile memory -------------------- - -The HAL should provide at least 240 bytes of non-volatile memory. If no -non-volatile memory is available, the HAL may provide fake NVRAM contents -suitable for RISC OS - however, it is preferable that the HAL just state -that NVRAM is not available, and RISC OS will act as though a CMOS reset has -been performed every reset. - -NVRAM is typically implemented as an IIC device, so the calls are permitted -to be slow, and to enable interrupts. The HAL is not expected to cache -contents. - -If the HAL has no particular knowledge of NVMemory, then it may just say -that "NVMemory is on IIC", and the OS will probe for CMOS/EEPROM devices on -the IIC bus. - -IIC bus -------- - -Many hardware designs have an IIC bus. Often, it is used only to support -non-volatile memory, but in other systems TV tuners, TV modulators, -microcontrollers, and arbitrary expansion cards may be fitted. - -Low-level and high level APIs are defined. An arbitrary number of buses is -supported, and each can be controlled by either the low or high level API. -The OS should normally only use one fixed API on each bus - mixing APIs is -unpredictable. - -The low-level API requires the OS to control the two lines of the bus -directly. The high-level API currently covers version 2.1 of the IIC -protocol, and allows high-level transactions to be performed. - -It is expected that a HAL will always provide the low-level API on each bus, -where possible in hardware. Using this, the OS can provide Fast mode single -or multi-master operation. The HAL may wish to provide the high-level API -where a dedicated IIC port with hardware assistance is available; this will -further permit High-speed and slave operation. - -As it is possible that some HAL APIs (eg NVMemory), although abstracted at -this API layer, are still actually an IIC device, a matching set of -high-level IIC calls are provided in the OS. These give the HAL access to -the OS IIC engine, which will make low-level HAL calls. This saves the HAL -from implementing the full IIC protocol. To illustrate this diagramatically: - - +----------+ NVMem_Read +------------+ NVMemoryRead +------------+ - | | ---------> | | ------------> | | - | App | | OS | IICTransmit | HAL | - | | | | <------------ | | - | | | | IICSetLines | | - | | | | ------------> | | - +----------+ +------------+ +------------+ - -The low-level calls should be fast. Interrupt status may not be altered. - -The following structure is used: - - typedef struct { int SDA, SCL } IICLines; - -High level API to be defined ... - -Video ------ - -The HAL only attempts to abstract the hardware controller aspects of the OS -video. It does not (yet) consider pixel formats, framestore layout, hardware -graphics acceleration. All these would affect a great deal of RISC OS -graphics code that forms much of the value of the OS. This means that the -envisaged HAL/RISC OS combination makes some specific assumptions about -graphics framestore layout as follows: - - - memory mapped framestore - - expected to be contiguous physical memory, can be specific memory (eg. VRAM) - - mapped as contiguous logical memory - - progressive raster scan in logical memory from top left pixel to bottom right - - start of each raster row must be word aligned - - number of pixels in a row should be such that row is a whole number of words - - spacing between start of each row is a constant number of words, possibly - greater than row length (via mode variable, LineLength) - - 1,2,4,8,16 or 32 bits per pixel (bpp) - - little endian pixel packing for 1,2,4 bpp (least significant bits are - leftmost pixels) - - presence of palette assumed for 1,2,4,8 bpp (8-bits per r,g,b component in - each entry) - - 16 bpp format: - bits 0-4 Red - 5-9 Green - 10-14 Blue - 15 Supremacy (0=solid, 1=transparent) - - 32 bpp format: - bits 0-7 Red - 8-15 Green - 16-23 Blue - 24-31 Supremacy (0=solid, 255=transparent) - - palette words are 32 bits: - bits 0-7 Reserved (0), or Supremacy (0=solid, 255=transparent) - 8-15 Red - 16-23 Green - 24-31 Blue - - pointer/cursor is assumed supported in hardware, 32x32 pixels, - each pixel either transparent or one of 3 paletted colours - - support for physically interlaced, logically progressive framestore via - MMU tricks and use of LineLength mode variable, currently not fully - integrated into kernel - -Note that it is possible to support hardware where only some pixel depths -are available, or only some fit the RISC OS assumptions. Also some hardware -has some configurability for 'arbitrary' choices like RGB versus BGR -ordering. Hence, the restrictions are typically much less severe than might -first be thought. - -Supporting a software only pointer/cursor is feasible (much less work than -new pixel formats) but not yet considered. - -Aside: RISC OS video interlace trick ------------------------------------- - -Has been used in NC/STB variants. Makes a physically interlaced framestore -(two distinct field stores) appear as logically progressive framestore, -using MMU to map many logical copies, and using freedom to choose a constant -logical increment between rows in RO mode definition. For 576 rows say, uses -576M of logical space. Each 1M (section mapped) supports a row and allows -logical address to increment monotonically, as physical address alternates -between (increasing rows of) physical field stores. Currently not integrated -into kernel, so fudges address space allocation and poking of video -variables. Also has drawback of thrashing data TLBs (one entry per row). - -The trick requires the physical field stores to be separated by 1M plus half -a row. The logical spacing between rows is also set to 1M plus half a row. -The 1M logical sections are set to map alternately to the even and odd -physical fields (the second field being offset by half a row relative to 1M -alignment). Then the logical incrementing of rows maps alternately between -fields, incrementing physically by 1 row between visits to the same field. -Note that the multiple logical mapping implies uncached screen to avoid -coherency worries, but RO uses uncached screen anyway (with exception of -Ursula/Phoebe, now defunct). - - -Routines in detail ------------------- - -[Note, plonking all routines here possibly only temporarily. May want -routines listed in relevant sections with overview. eg. video routines -with video section, etc.] - --- HAL_Init(unsigned int *riscos_header, void *uncacheable_ws) - -The OS will call HAL_Init after enabling the MMU, and initialising the HAL -workspace (filled with 0). At this point any initialisation for the main HAL -routines (rather than the early bootstrap code in the HAL) can be done. - --- HAL_IRQEnable - -???? - --- HAL_IRQDisable - -???? - --- HAL_IRQClear - -???? - --- HAL_IRQSource - -???? - --- HAL_Reset - -This resets the board depending on the value in a1 - a1 = 0 hard reset and turn the power off (ie.just turn the power off) - a1 = 1 hard reset and leave the power on - a1 > 1 reserved -Asking HAL_PlatformInfo will tell you if the hardware allows the power to be turned off by software,if it doesn't then behaviour is per a1 = 1 - --- int HAL_Timers(void) - -Returns number of timers. Timers are numbered from 0 upwards. Timer 0 must -exist. - --- int HAL_TimerDevice(int timer) - -Returns device number of timer n. A device number refers to the IRQ device -number for interrupt calls. - --- unsigned int HAL_TimerGranularity(int timer) - -Returns basic granularity of timer n in ticks per second. - --- unsigned int HAL_TimerMaxPeriod(int timer) - -Returns maximum period of the timer, in units of Granularity. Will be 1 for -a fixed rate timer. - --- void HAL_TimerSetPeriod(int timer, unsigned int period) - -Sets period of timer n. If period > 0, the timer will generate interrupts -every (period / granularity) seconds. If period = 0, the timer may be -stopped. This may not be possible on some hardware, so the corresponding -interrupt should be masked in addition to calling this function with period -0. If period > maxperiod, behaviour is undefined. - --- unsigned int HAL_TimerPeriod(int timer) - -Reads period of timer n. This should be the actual period in use by the -hardware, so if for example period 0 was requested and impossible, the -actual current period should be reported. - --- unsigned int HAL_TimerReadCountdown(int timer) - -Returns the time until the next interrupt in units of granularity, rounded -down. If not available, 0 is returned. - --- unsigned int HAL_CounterRate(void) - -Returns the rate of the counter in ticks per second. Typically will equal -HAL_TimerGranularity(0). - --- unsigned int HAL_CounterPeriod(void) - -Returns the period of the counter, in ticks. Typically will equal -HAL_TimerPeriod(0). - --- unsigned int HAL_CounterRead(void) - -Reads the current counter value. Typically will equal -HAL_TimerReadCountdown(0). - --- unsigned void HAL_CounterDelay(unsigned int microseconds) - -Delay for at least the specified number of microseconds. - --- unsigned int HAL_NVMemoryType(void) - -Returns a flags word describing the NVMemory - bits 0-7: 0 => no NVMemory available - 1 => NVMemory may be available on the IIC bus - 2 => NVMemory is available on the IIC bus, and the - device characteristics are known - 3 => the HAL provides NVMemory access calls. - bit 8: NVMemory has a protected region at the end - bit 9: Protected region is software deprotectable - bit 10: Memory locations 0-15 are readable - bit 11: Memory locations 0-15 are writeable - -If bits 0-7 are 0 or 1 no other NVMemory calls need be available, and bits -8-31 should be zero. - -If bits 0-7 are 2, Size, ProtectedSize, Protection and IICAddress calls must -be available. - -If bits 0-7 are 3, all calls except IICAddress must be available. - --- unsigned int HAL_NVMemorySize(void) - -Returns the number of bytes of non-volatile memory available. Bytes 0-15 -should be included in the count, so for example a Philips PCF8583 CMOS/RTC -device (as used in the Archimedes and Risc PC) would be described as a -256-byte device, with locations 0-15 not readable. More complex arrangements -would have to be abstracted out by the HAL providing its own NVMemory access -calls. - -This is to suit the current RISC OS Kernel, which does not use bytes 0-15. - --- unsigned int HAL_NVMemoryProtectedSize(void) - -Returns the number of bytes of NVMemory that are protected. These should be -at the top of the address space. The OS will not attempt to write to those -locations without first requesting deprotection (if available). Returns 0 if -bit 8 of the flags is clear. - --- void HAL_NVMemoryProtection(bool) - -Enables (if true) or disables if (false) the protection of the software -protectable region. Does nothing if bits 8 and 9 not both set. - --- unsigned int HAL_NVMemoryIICAddress(void) - -Returns a word describing the addressing scheme of the NVRAM. - bits 0-7: IIC address - -This will always be on bus zero. - --- int HAL_NVMemoryRead(unsigned int addr, void *buffer, unsigned int n) - -Reads n bytes of memory from address addr onwards into the buffer supplied. -Returns the number of bytes successfully read. Under all normal -circumstances the return value will be n - if it is not, a hardware failure -is implied. Behaviour is undefined if the address range specified is outside -the NVMemory, or inside bytes 0-15, if declared unavailable. - --- int HAL_NVMemoryWrite(unsigned int addr, void *buffer, unsigned int n) - -Write n bytes of memory into address addr onwards from the buffer supplied. -Returns the number of bytes successfully written. Under all normal -circumstances the return value will be n - if it is not, a hardware failure -is implied. Behaviour is undefined if the address range specified is outside -the NVMemory. Writes inside the a protected region should be ignored. - --- int HAL_IICBuses(void) - -Returns the number of IIC buses on the system. - --- unsigned int HAL_IICType(int bus) - -Returns a flag word describing the specified IIC bus. - bit 0: Bus supplies the low-level API - bit 1: Bus supplies the high-level API - bit 2: High-level API supports multi-master operation - bit 3: High-level API supports slave operation - bit 16: Bus supports Fast (400kbps) operation - bit 17: Bus supports High-speed (3.4Mbps) operation - bits 20-31: Version number of IIC supported by high-level API, * 100. - - --- __value_in_regs IICLines HAL_IICSetLines(int bus, IICLines lines) - -Sets the SDA and SCL lines on the specified bus. A 0 value represents logic -LOW, 1 logic HIGH. The function then reads back and returns the values -present on the bus, to permit arbitration. - -Note the "__value_in_regs" keyword, which signifies that the binary ABI -expects SDA and SCL to be returned in registers a1 and a2. - --- __value_in_regs IICLines HAL_IICReadLines(int bus) - -Reads the state of the IIC lines on the specified bus, without changing -their state. - -Note the "__value_in_regs" keyword, which signifies that the binary ABI -expects SDA and SCL to be returned in registers a1 and a2. - --- int HAL_VideoFlybackDevice(void) - -Returns the device number of the video flyback interrupt. [Note: HAL -interrupt API possibly subject to change, may affect this call.] - --- void HAL_Video_SetMode(const void *VIDCList3) - -Programs the video controller to initialise a display mode. RISC OS passes a -standard VIDC List Type 3 as specified in PRM 5a-125. Note that this is a -generic video controller list, and so VIDC in this context does not refer to -any specific devices such as Acorn VIDC20. - -The HAL is expected to set the video controller timings on this call. Any -palette, pixel DMA and hardware cursor settings are controlled via other -calls. - --- void HAL_Video_WritePaletteEntry(uint type, uint pcolour, uint index) - -Writes a single palette entry to the video controller. - - type = 0 for normal palette entry - 1 for border colour - 2 for pointer colour - >= 3 reserved - - pcolour = palette entry colour in BBGGRRSS format (Blue,Green,Red,Supremacy) - - index = index of entry - -Indices are in the range 0..255 for normal, 0 for border, 0..3 for pointer -colours. Note that RISC OS only makes calls using 1..3 for the pointer, and -pointer colour 0 is assumed to be transparent. - --- void HAL_Video_WritePaletteEntries(uint type, const uint *pcolours, - uint index, uint Nentries) - -Writes a block of palette entries to the video controller. - - type = 0 for normal palette entry - 1 for border colour - 2 for pointer colour - >= 3 reserved - - pcolours = pointer to block of palette entry colours in BBGGRRSS format - (Blue,Green,Red,Supremacy) - - index = start index in palette (for first entry in block) - - Nentries = number of entries in block (must be >= 1) - -Indices are in the range 0..255 for normal, 0 for border, 0..3 for pointer -colours. Note that RISC OS only makes calls using 1..3 for the pointer, and -pointer colour 0 is assumed to be transparent. - --- uint HAL_Video_ReadPaletteEntry(uint type, uint pcolour, uint index) - -Returns the effective palette entry after taking into account any hardware -restrictions in the video controller, assuming it was originally programmed -with the value pcolour. - - type = 0 for normal palette entry - 1 for border colour - 2 for pointer colour - >= 3 reserved - - pcolour = palette entry colour in BBGGRRSS format (Blue,Green,Red,Supremacy) - - index = index of entry - - returns : effective BBGGRRSS - -Indices are in the range 0..255 for normal, 0 for border, 0..3 for pointer -colours. Note that RISC OS only makes calls using 1..3 for the pointer, and -pointer colour 0 is assumed to be transparent. - -Depending on harwdware capabilities, HALs may have to remember current -settings (eg. bits per pixel) or keep soft copies of entries. Because this -call supplies the original pcolour, this need is minimised (some HALs can -just return pcolour or a directly modified pcolour). - --- void HAL_Video_SetInterlace(uint interlace) - -Sets the video interlaced sync. - - interlace = 0 or 1 for interlace off or on - (all other values reserved) - --- void HAL_Video_SetBlank(uint blank, uint DPMS) - - blank = 0 or 1 for unblank or blank - (all other values reserved) - - DMPS = 0..3 as specified by monitor DPMSState (from mode file) - 0 for no DPMS power saving - -The HAL is expected to attempt to turn syncs off according to DPMS, and to -turn video DMA off for blank (and therefore on for unblank) if possible. The -HAL is not expected to do anything else, eg. blank all palette entries. Such -things are the responsibility of the OS, and also this call is expected to -be fast. May be called with interrupts off. - --- void HAL_Video_SetPowerSave(uint powersave) - - powersave = 0 or 1 for power save off or on - (all other values reserved) - -The HAL is expected to perform any reasonable measures on the video -controller to save power (eg. turn off DACs), when the display is assumed -not to be required. Blanking is handled by a separate call. - -[What does this really mean. What is acceptable and safe for displays? ] - --- void HAL_Video_UpdatePointer(uint flags, int x, int y, const shape_t *shape) - -Update the displayed position of the current pointer shape (or turn shape -off). This call is made by the OS at a time to allow smoothly displayed -changes (on a VSync). - - flags: - bit 0 = pointer display enable (0=off, 1=on) - bit 1 = pointer shape update (0=no change, 1=updated) - bits 2..31 reserved (0) - - xpos = x position of top left of pointer (xpos = 0 for left of display) - - ypos = y position of top left of pointer (ypos = 0 for top of display) - - shape points to shape_t descriptor block: - typedef struct shape_t - { - uint8 width; /* unpadded width in bytes (see notes) */ - uint8 height; /* in pixels */ - uint8 padding[2]; /* 2 bytes of padding for field alignment */ - void *buffLA; /* logical address of buffer holding pixel data */ - void *buffPA; /* corresponding physical address of buffer */ - } - -Notes: -1) if flags bit 0 is 0 (pointer off), x, y, shape are undefined -2) the shape data from RISC OS is always padded with transparent pixels - on the rhs, to a width of 32 pixels (8 bytes) -3) pointer clipping is the responsibility of the HAL (eg. may be able to - allow display of pointer in border region on some h/w) -4) buffer for pixel data is aligned to a multiple of 256 bytes or better - -The HAL may need to take note of the shape updated flag, and make its own -new copies if true. This is to handle cases like dual scan LCD pointer, -which typically needs two or more shape buffers for the hardware, or -possibly to handle clipping properly. This work should only be done when the -updated flag is true. - -A simple HAL, where hardware permits, can use the shape data in the buffer -directly, ignoring the updated flag. The OS guarantees that the buffer data -is valid for the whole time it is to be displayed. - --- void HAL_Video_SetDAG(uint DAG, uint paddr) - -Set the video DMA address generator value to the given physical address. - - DAG = 0 set start address of current video display - 1 set start address of total video buffer - 2 set end address (exclusive) of total video buffer - all other values reserved - - paddr = physical address for given DAG - -The OS has a video buffer which is >= total display size, and may be using -bank switching (several display buffers) or hardware scroll within the total -video buffer. - - DAG=1 will be start address of current total video buffer - DAG=2 will be end address (exclusive) of current total video buffer - DAG=0 will be start address in buffer for current display - -HALs should respond differently depending on whether hardware scroll is -supported or not. (The OS will already know this from HAL_Video_Features). - -No hardware scroll: -Only DAG=0 is significant, and the end address of the current display is -implied by the size of the current mode. Calls with DAG=1,2 should be -ignored. - -Hardware scroll: -DAG=0 again defines display start. DAG=2 defines the last address -(exclusive) that should be displayed before wrapping back (if reached within -display size), and DAG=1 defines the address to which accesses should wrap -back. - --- int HAL_Video_VetMode(const void *VIDClist, const void *workspace) - -Allows HAL to vet a proposed mode. - -[What does this really do, and what can HAL do. Are we going to allow -changes to VIDCList by HAL, ie. not const. Is mode workspace really ok to -pass to HAL ???] - - VIDClist -> generic video controller list (VIDC list type 3) - - workspace -> mode workspace (if mode number), or 0 - - returns 0 if OK (may be minor adjusts to VIDClist and/or workspace values) - non-zero if not OK - - --- uint HAL_Video_Features(void) - -Determine key features supported by the video hardware. - - returns a flags word: - bit 0 hardware scroll is supported - bit 1 hardware pointer/cursor is supported - bit 2 interlace is supported with progressive framestore - other bits reserved (returned as 0) - -Bits are set for true. If bit 2 is true, then the OS assumes that a simple -progressive framestore layout is sufficient for an interlaced display (ie. -that the hardware implements the interlaced scan). - --- uint HAL_Video_PixelFormats(void) - -Determine the pixel formats that are supported by the hardware. - - returns flags word: - bit 0 1 bpp is supported - bit 1 2 bpp is supported - bit 2 4 bpp is supported - bit 3 8 bpp is supported - bit 4 16 bpp is supported - bit 5 32 bpp is supported - other bits reserved (returned as 0) - -Bits are set for true. Bits 0-5 refer to support with standard RISC OS pixel -layout. (such as little endian packing for 1,2,4 bpp, 5-5-5 RGB for 16 bpp, -etc). See the section discussing Video for more information. Other formats -may be introduced when/if RO supports them. - --- uint HAL_Video_BufferAlignment(void) - -Determine the framestore buffer alignment required by the hardware. - - returns an unsigned integer: - the required alignment for the framestore buffer, in bytes - (expected to be a power of 2) - - --- HAL_MatrixColumns - -??? - --- HAL_MatrixScan - -??? - --- HAL_TouchscreenType - -??? - --- HAL_TouchscreenRead - -??? - --- unsigned int64 HAL_MachineID(void) - -Returns a 64-bit unique machine identifier,this may later be used to -form the ethernet MAC address but otherwise has no great significance on non -networked machines. - -The top 8 bits are a CRC,based on the same algorithm the original DS2401 -used - if the CRC fails zero will be substituted - --- void *HAL_ControllerAddress(unsigned controller) - -Asks the HAL where various controllers might or might not be. -Podule manager uses this information to determine at run time whether or not -to bother doing anything. - -Returns r0=logical address of the chosen controller,or zero - - 0 = EASI card access speed control - 1 = EASI space(s) - 2 = VIDC1 - 3 = VIDC20 - 4 = S space base (IOMD,podules,NICs,blah blah) - 5 = Extension ROM(s) - --- HALEntry HAL_HardwareInfo - -See OS_ReadSysInfo reason code 2 - --- HALEntry HAL_SuperIOInfo - -See OS_ReadSysInfo reason code 3 - -RISC OS entry points from HAL init ----------------------------------- - -These are entry points into the OS, called from the HAL. - --- void RISCOS_InitARM(unsigned int flags) - - flags: reserved - sbz - -On entry: - SVC mode - MMU and caches off - IRQs and FIQs disabled - No RAM or stack used - -On exit: - Instruction cache may be on - -This routine must be called once very early on in the HAL start-up, to -accelerate the CPU for the rest of HAL initialisation. Typically, it will -just enable the instruction cache (if possible on the ARM in use), and -ensure that the processor is in 32-bit configuration and mode. - -Some architecture 4 (and later) ARMs have bits in the control register that -affect the hardware layer - eg the iA and nF bits in the ARM920T. These are -the HAL's responsibility - the OS will not touch them. Conversely, the HAL -should not touch the cache, MMU and core configuration bits (currently bits -0-14). - -On architecture 3, the control register is write only - the OS will set bits -11-31 to zero. - -Likewise, such things as the StrongARM 110's register 15 (Test, Clock and -Idle Control) are the HAL's responsibility. The OS does not know about the -configuration of the system, so cannot program such registers. - -This entry must not be called after RISCOS_Start. - --- void *RISCOS_AddRAM(unsigned int flags, void *start, void *end, - uintptr_t sigbits, void *ref) - flags - bit 0: video memory (only first contiguous range will be used) - bit 1: video memory is not suitable for general use - bits 8-11: speed indicator (arbitrary, higher => faster) - other bits reserved (SBZ) - start - start address of RAM (inclusive) (no alignment requirements) - end - end address of RAM (exclusive) (no alignment requirements, but must be >= start) - sigbits - significant address bit mask (1 => this bit of addr decoded, 0 => this bit ignored) - ref - reference handle (NULL for first call) - -Returns ref for next call - -On entry: - SVC32 mode - MMU and data cache off - IRQs and FIQs disabled - -This entry point must be the first call from the HAL to RISC OS following a hardware -reset. It may be called as many times as necessary to give all enumerate RAM that -is available for general purpose use. It should only be called to declare video -memory if the video memory may be used as normal RAM when in small video modes. - -To permit software resets: - The HAL must be non-destructive of any declared RAM outside the first 4K of the first - block. - The stack pointer should be initialised 4K into the first block, or in some non- - declared RAM. - Must present memory in a fixed order on any given system. - -The first block must be at least 256K and 16K aligned. -Block coalescing only works well if RAM banks are added in ascending address order. - -RISC OS will use RAM at the start of the first block as initial workspace. -Max usage is 16 bytes per block + 32 (currently 8 per block + 4). This -limits the number of discontiguous blocks (although RISC OS will concatanate -contiguous blocks where possible). - -This call must not be made after RISCOS_Start. - - --- void RISCOS_Start(unsigned int flags, int *riscos_header, - int *hal_entry_table, void *ref) - - flags - bit 0: power on reset - bit 1: CMOS reset inhibited (eg protection link on Risc PC) - bit 2: perform a CMOS reset (if bit 1 clear and bit 0 set - eg front panel - button held down on an NC) - bit 3: there is no CMOS (the Kernel must use a RAM cache) - bit 4: the RAM has already been cleared to zero - -On entry: - SVC32 mode - MMU and data cache off - IRQs and FIQs disabled - -This routine must be called after all calls to RISCOS_AddRAM have been -completed. It does not return. Future calls back to the HAL are via the HAL -entry table, after the MMU has been enabled. - - --- void *RISCOS_MapInIO(unsigned int flags, void *phys, unsigned int size) - - flags: bit 2 => make memory bufferable - phys: physical address to map in - size: number of bytes of memory to map in - -This routine is used to map in IO memory for the HAL's usage. Normally it -would only be called during HAL_Init(). Once mapped in the IO space cannot -be released. - -It returns the resultant virtual address corresponding to phys, or 0 for -failure. Failure can only occur if no RAM is available for page tables, or -if the virtual address space is exhausted. - --- void *RISCOS_AccessPhysicalAddress(unsigned int flags, void *phys, void **oldp) - - flags: bit 2 => make memory bufferable - other bits must be zero - phys: physical address to access - oldp: pointer to location to store old state (or NULL) - -On entry: - Privileged mode - MMU on - FIQs on - Re-entrant - -On exit: - Returns logical address corresponding to phys - -Arranges for the physical address phys to be mapped in to logical memory. In -fact, the whole megabyte containing "phys" is mapped in (ie if phys = -&12345678, then &12300000 to &123FFFFF become available). The memory is -supervisor access only, non-cacheable, non-bufferable by default, and will -remain available until the next call to RISCOS_Release/AccessPhysicalAddress -(although interrupt routines or subroutines may temporarily map in something -else). - -When finished, the user should call RISCOS_ReleasePhysicalAddress. - --- void RISCOS_ReleasePhysicalAddress(void *old) - - old: state returned from a previous call to RISCOS_AccessPhysicalAddress - -On entry: - MMU on - FIQs on - Re-entrant - -Usage: - Call with the a value output from a previous RISCOS_ReleasePhysicalAddress. - -Example: - - void *old; - unsigned int *addr = (unsigned int *) 0x80005000; - unsigned int *addr2 = (unsigned int *) 0x90005000; - - addr = (unsigned int *) RISCOS_AccessPhysicalAddress(addr, &old); - addr[0] = 3; addr[1] = 5; - - addr2 = (unsigned int *) RISCOS_AccessPhysicalAddress(addr2, NULL); - *addr2 = 7; - - RISCOS_ReleasePhysicalAddress(old); diff --git a/Docs/HAL/Init b/Docs/HAL/Init deleted file mode 100644 index def56cad..00000000 --- a/Docs/HAL/Init +++ /dev/null @@ -1,116 +0,0 @@ -Arrange correct ROM image -POST -Initialise memory system - ROM timings, width -Reset screen -Disable interrupts -Start timers -Size memory - Set up table describing memory layout - Set up video DMA -Time CPU - - - - - - - -CONT / CONT_Break - - InitMEMC (in: r1 = 0 -> Reset, 1 -> Break) - Check for 7500 vs IOMD - Program CPU, MEM and IO clocks - Set ROM timings - Set ROM width - Set up VRAM refresh - Set up peripheral timings - Set up sound format - Ensure MMU off and caches - - Set up VIDC - - Disable interrupts in IOC - - Start timer 0 - - MemSize (out: r0 = page size, r1 = memory size, r2 = MEMC CR) - Set up RAM width - Find memory - create a table of (addr,len) pairs (in first memory found) - Find VRAM - if none take from first block - Start filling in page zero (in first block) - Set up video DMA registers - Allocate L1PT, and some L2PT, and soft CAM - Turn on MMU and caches - - TimeCPU (out: r0 = peak RAM speed in kHz) - - Put in extra pages: cursor, system heap - - Start keyboard scanning - - If POR or FX 200 - Clear memory - - Check processor type - - Fill in processor vectors - - Read CMOS - - Fill in SWI dispatch table - - Wait for keyboard (up to two seconds) - - If (POR AND R/T/Del/Copy) - Reset CMOS - Goto Hard Reset - - IF (POR or CannotReset or SysHeapCorrupt or CAM map nonsense or Ctrl pressed) - Clear the CAM - - Set it up - - InitDynamicAreas - - Create system dynamic areas - - InitVectors - - Clear SWI hash table - - Clear POR bit - Else - Do the soft reset stuff - - Re-initialise kernel - - If (hard reset) - Init variables - Initialise modules - PostInit - - Set mode - - Print "RISC OS" - - Service_Reset - - Shut all files - - Beep if hard reset - - If numpad key down - reconfigure monitor, change mode - print "monitor type reconfigured" - - Check shift - - Do boot - - Else check * - - Else enter language - - - \ No newline at end of file diff --git a/Docs/HAL/MoreEnts b/Docs/HAL/MoreEnts deleted file mode 100644 index 6205b728..00000000 --- a/Docs/HAL/MoreEnts +++ /dev/null @@ -1,500 +0,0 @@ -Initialisation -============== - -HAL_Init(unsigned int *riscos_header) - - Will be called after the MMU is turned on, before any other entries points. - The HAL workspace will be filled with zeroes. - - -Interrupts -========== - -The HAL must provide the ability to identify, prioritise and mask IRQs, and the ability -to mask FIQs. RISC OS supplies the ARM's processor vectors, and on an IRQ calls the HAL -to request the identity of the highest priority interrupt. - -IRQ and FIQ device numbers are arbitrary, varying from system to system. They should be -arranged to allow quick mappings to and from hardware registers, and should ideally -be packed, starting at 0. - -HAL_IRQEnable -HAL_IRQDisable -HAL_IRQClear -HAL_IRQSource (get highest priority asserted IRQ) -HAL_IRQDisableAll - -HAL_FIQEnable -HAL_FIQDisable -HAL_FIQClear -HAL_FIQDisableAll - -Interrupt specifications are generally described by a 3-word structure. -The 3 words correspond directly to the contents of registers R0,R3 and R4 -on entry to OS_ClaimDeviceVector. - -typedef struct irq_descriptor -{ - int device; - union { - struct { - unsigned char *addr; - int maskandpolarity; - } bit; - struct { - int (*forme)(void *handle); - void *handle; - } func; - } sub; -} irq_descriptor; - -OS_ClaimDeviceVector changes: - -R3 and R4 must always be supplied. Set R3=R4=0 to claim "all" of an interrupt. -Bit 31 of the device number indicates that a routine is being supplied instead -of an address and a mask. - -When supplying a bit mask, your handler is called if - - ([addr] AND maskandpolarity) EOR (maskandpolarity >> 8) - -is nonzero. This is a RISC OS 3.8+ backwards-compatible extension to the original -check: - - [addr] AND maskandpolarity - -When supplying a routine, your handler is called if - - forme(handle) - -returns nonzero. - -if - - -Timers -====== - -The HAL must supply at least one timer capable of generating periodic -interrupts. Each timer should generate a separate logical interrupt, and the -interrupt must be latched. The timers must either be variable rate (period is -a multiple of a basic granularity), or be fixed rate (period = 1*granularity). -Optionally, the timer should be capable of reporting the time until the -next interrupt, in units of the granularity. - -int HAL_Timers(void) - - Returns number of timers. Timers are numbered from 0 upwards. Timer 0 - must exist. - -int HAL_TimerDevice(int timer) - - Returns device number of timer n - -unsigned int HAL_TimerGranularity(int timer) - - Returns basic granularity of timer n in ticks per second. - -unsigned int HAL_TimerMaxPeriod(int timer) - - Returns maximum period of the timer, in units of Granularity. Will be 1 - for a fixed rate timer. - -void HAL_TimerSetPeriod(int timer, unsigned int period) - - Sets period of timer n. If period > 0, the timer will generate interrupts every - (period / granularity) seconds. If period = 0, the timer may be stopped. - This may not be possible on some hardware, so the corresponding interrupt - should be masked in addition to calling this function with period 0. - If period > maxperiod, behaviour is undefined. - -unsigned int HAL_TimerPeriod(int timer) - - Reads period of timer n. This should be the actual period in use by the - hardware, so if for example period 0 was requested and impossible, the - actual current period should be reported. - -unsigned int HAL_TimerReadCountdown(int timer) - - Returns the time until the next interrupt in units of granularity, rounded down. - If not available, 0 is returned. - -Counter -======= - -The HAL must supply a counter that varies rapidly, appropriate for use for -sub-millisecond timing. On many systems, this counter will form part of -timer 0 - as such it is not required to operate when timer 0 is not running. -On other systems, the periodic timers may have no readable latch, and a -separate unit will be required. - -The counter should count down from (period-1) to 0 continuously. - -unsigned int HAL_CounterRate(void) - - Returns the rate of the counter in ticks per second. Typically will - equal HAL_TimerGranularity(0). - -unsigned int HAL_CounterPeriod(void) - - Returns the period of the counter, in ticks. Typically will equal - HAL_TimerPeriod(0). - -unsigned int HAL_CounterRead(void) - - Reads the current counter value. Typically will equal - HAL_TimerReadCountdown(0). - -unsigned void HAL_CounterDelay(unsigned int microseconds) - - Delay for at least the specified number of microseconds. - - -Non-volatile memory -=================== - -The HAL should provide at least 240 bytes of non-volatile memory. If no -non-volatile memory is available, the HAL may provide fake NVRAM contents -suitable for RISC OS - however, it is preferable that the HAL just state that -NVRAM is not available, and RISC OS will act as though a CMOS reset has been -performed every reset. - -NVRAM is typically implemented as an IIC device, so the calls are permitted -to be slow, and to enable interrupts. The HAL is not expected to cache -contents. - -If the HAL has no particular knowledge of NVMemory, then it may -just say that "NVMemory is on IIC", and the OS will probe for CMOS/EEPROM -devices on the IIC bus. - -unsigned int HAL_NVMemoryType(void) - - Returns a flags word describing the NVMemory - bits 0-7: 0 => no NVMemory available - 1 => NVMemory may be available on the IIC bus - 2 => NVMemory is available on the IIC bus, and the - device characteristics are known - 3 => the HAL provides NVMemory access calls. - bit 8: NVMemory has a protected region at the end - bit 9: Protected region is software deprotectable - bit 10: Memory locations 0-15 are readable - bit 11: Memory locations 0-15 are writeable - - If bits 0-7 are 0 or 1 no other NVMemory calls need be available, - and bits 8-31 should be zero. - - If bits 0-7 are 2, Size, ProtectedSize, Protection and IICAddress calls must - be available. - - If bits 0-7 are 3, all calls except IICAddress must be available. - -unsigned int HAL_NVMemorySize(void) - - Returns the number of bytes of non-volatile memory available. Bytes 0-15 - should be included in the count, so for example a Philips PCF8583 - CMOS/RTC device (as used in the Archimedes and Risc PC) would be described - as a 256-byte device, with locations 0-15 not readable. More complex - arrangements would have to be abstracted out by the HAL providing its own - NVMemory access calls. - - This is to suit the current RISC OS Kernel, which does not use bytes 0-15. - -unsigned int HAL_NVMemoryProtectedSize(void) - - Returns the number of bytes of NVMemory that are protected. These should - be at the top of the address space. The OS will not attempt to write - to those locations without first requesting deprotection (if available). - Returns 0 if bit 8 of the flags is clear. - -void HAL_NVMemoryProtection(bool) - - Enables (if true) or disables if (false) the protection of the software - protectable region. Does nothing if bits 8 and 9 not both set. - -unsigned int HAL_NVMemoryIICAddress(void) - - Returns a word describing the addressing scheme of the NVRAM. - bits 0-7: IIC address - - This will always be on bus zero. - -int HAL_NVMemoryRead(unsigned int addr, void *buffer, unsigned int n) - - Reads n bytes of memory from address addr onwards into the buffer supplied. - Returns the number of bytes successfully read. Under all normal circumstances - the return value will be n - if it is not, a hardware failure is implied. - Behaviour is undefined if the address range specified is outside the NVMemory, - or inside bytes 0-15, if declared unavailable. - -int HAL_NVMemoryWrite(unsigned int addr, void *buffer, unsigned int n) - - Write n bytes of memory into address addr onwards from the buffer supplied. - Returns the number of bytes successfully written. Under all normal circumstances - the return value will be n - if it is not, a hardware failure is implied. - Behaviour is undefined if the address range specified is outside the NVMemory. - Writes inside the a protected region should be ignored. - -I²C bus -======= - -Many hardware designs have an I²C bus. Often, it is used only to place non- -volatile memory on, but in other systems TV tuners, TV modulators, -microcontrollers, and arbitrary expansion cards may be fitted. - -Low-level and high level APIs are defined. An arbitrary number of buses are -supported, and each can be controlled by either the low or high level API. -The OS should normally only use one fixed API on each bus - mixing APIs may -not have good results. - -The low-level API requires the OS to control the two lines of the bus -directly. The high-level API currently covers version 2.1 of the I²C -protocol, and allows high-level transactions to be performed. - -It is expected that a HAL will always provide the low-level API on each -bus, where possible in hardware. Using this, the OS can provide Fast mode -single or multi-master operation. The HAL may wish to provide the high-level API -where a dedicated I²C port with hardware assistance is available; this will -further permit High-speed and slave operation. - -As it is possible that some HAL APIs (eg NVMemory), although abstracted at -this API layer, are still actually an I²C device, a matching set of high-level -I²C calls are provided in the OS. These give the HAL access to the OS I²C engine, -which will make low-level HAL calls. This saves the HAL from implementing the -full I²C protocol. To illustrate this diagramatically: - - +----------+ NVMem_Read +------------+ NVMemoryRead +------------+ - | | ---------> | | ------------> | | - | App | | OS | IICTransmit | HAL | - | | | | <------------ | | - | | | | IICSetLines | | - | | | | ------------> | | - +----------+ +------------+ +------------+ - -int HAL_IICBuses(void) - - Returns the number of IIC buses on the system. - -unsigned int HAL_IICType(int bus) - - Returns a flag word describing the specified IIC bus. - bit 0: Bus supplies the low-level API - bit 1: Bus supplies the high-level API - bit 2: High-level API supports multi-master operation - bit 3: High-level API supports slave operation - bit 4: High-level API supports background operation - bit 16: Bus supports Fast (400kbps) operation - bit 17: Bus supports High-speed (3.4Mbps) operation - bits 20-31: Version number of I²C supported by high-level API, * 100. - -Low level API -------------- - -The low-level calls should be instantaneous. Interrupt status may not be altered. - -The following structure is used: - - typedef struct { int SDA, SCL } IICLines; - -Note the "__value_in_regs" keyword, which signifies that the binary ABI expects -SDA and SCL to be returned in registers a1 and a2. - -__value_in_regs IICLines HAL_IICSetLines(int bus, IICLines lines) - - Sets the SDA and SCL lines on the specified bus. A 0 value represents - logic LOW, 1 logic HIGH. The function then reads back and returns - the values present on the bus, to permit arbitration. - -__value_in_regs IICLines HAL_IICReadLines(int bus); - - Reads the state of the IIC lines on the specified bus, without changing - their state. - -High level API --------------- - -The high-level interface process a single transfer at a time (from the -initial START to the STOP). It is designed to support background operations. - -irq_descriptor HAL_IICDevice(int bus); - - Returns the interrupt specification for the bus. This is not meaningful - if bit 4 of the flags word above is not set. The OS will claim the interrupt - and call HAL_IICMonitorTransfer() each time it occurs. - - -#define IICSTATUS_COMPLETED 0 -#define IICSTATUS_INPROGRESS 1 /* transfer proceeding in background */ -#define IICSTATUS_NOACK 2 /* slave failed to acknowledge */ -#define IICSTATUS_BUSY 3 /* IIC system busy (call back later) */ -#define IICSTATUS_SLAVE 4 /* reserved for slave operations */ -#define IICSTATUS_ERROR 5 /* other error prevented completion */ - -typedef struct iic_transfer -{ - unsigned addr:8; - unsigned :22; - unsigned checksumonly:1; - unsigned nostart:1; - union - { unsigned checksum; - void *data; - } d; - unsigned len; -} iic_transfer; - -int HAL_IICTransfer(int bus, unsigned n, iic_transfer transfer[static n]); - - Initiates an IIC transfer. The transfer shall progress in the background - if bit 4 is set, in which case the normal return should be IICSTATUS_INPROGRESS. - The OS will call HAL_IICMonitorTransfer each time an interrupt occurs - this - will allow the HAL to progress through the transfer if it's not totally automatic. - If the transfer happens in the foreground, return values are as for - IICMonitorTransfer (see below). - - If an IIC transfer is currently in progress, the call may return BUSY and the - caller should retry later - although if background transfers are supported it may - queue the transfer and return INPROGRESS. If another master is driving the bus, - it should silently wait until the bus is free (in the background or foreground as - appropriate). If we lose arbitration, the transfer should be retried when the bus - becomes free. - - transfer[] is an array of n transfer descriptors. Each descriptor describes part - of the transfer. The direction of the subtransfer is determined by the least - significant bit of addr. If nostart is 0, a START is first transmitted followed - by addr, otherwise the data flow continues where the previous subtransfer - left off. nostart must be 0 for the first subtransfer. - - For writes, len bytes of data are read from "data" and transmitted. For reads, - len bytes are received and written to "data", unless "checksumonly" is 1, in which - case the len received bytes are summed and the (32-bit) sum stored in checksum. - - If background transfers are in use, the transfer[] array and the data blocks must - remain available in unpaged memory for the duration of the transfer. - - IICTransfer is re-entrant, but may return BUSY if re-entered (see above). - - -int HAL_IICMonitorTransfer(int bus); - - Will be called on every interrupt, and should return the status of the transfer - currently in progress. If no transfer is in progress, the call should return - COMPLETED. - - If the transfer is still in progress, INPROGRESS is returned. - - If the slave failed to acknowledge (either the address or any later transmitted - byte), NOACK is returned. - - If we have been addressed as a slave, the call returns SLAVE. More details to - be confirmed. - - BUSY is not a valid response. - - This will only be called in response to an IIC interrupt, with interrupts disabled. - The interrupt shall be cleared by this call. - - Unknown return codes will be ignored. - - -Machine ID -========== - -unsigned int64 HAL_MachineID(void) - - Returns a 64-bit unique machine identifier,this may later be used to - form the ethernet MAC address but otherwise has no great significance on non - networked machines. - - The top 8 bits are a CRC,based on the same algorithm the original DS2401 - used - if the CRC fails zero will be substituted - -ControllerAddress -================= - -void *HAL_ControllerAddress(unsigned controller) - - Asks the HAL where various controllers might or might not be. - Podule manager uses this information to determine at run time whether or not - to bother doing anything. - - Returns r0=logical address of the chosen controller,or zero - - 0 = EASI card access speed control - 1 = EASI space(s) - 2 = VIDC1 - 3 = VIDC20 - 4 = S space base (IOMD,podules,NICs,blah blah) - 5 = Extension ROM(s) - -Matrix Keyboard -=============== - -Many devices provide a matrix keyboard interface. The following calls -provide access to it. Interrupt driven operation, or high-level calls will be -defined later. - -int HAL_MatrixColumns(void) - - Returns the number of columns available via the matrix interface. - Columns are numbered from 0 to <num columns>-1. - -unsigned int HAL_MatrixScan(int column). - - Returns a bitfield describing which rows are active on the specified column. - Any timing issues, or the driving of the matrix between calls are left to - the HAL. - -Touchscreen -=========== - -PDA-type devices usually have a touchscreen as their primary pointing device. -This API provides a simple interface to a touchscreen. The calls are described -in terms of a resistive touchscreen, but other technologies should be mappable -onto it. Interrupt operation is yet to be defined. - - -unsigned int HAL_TouchscreenType(void) - - Returns a flags word indicating the type of touchscreen. - bits 0-7: Touchscreen type 0=>none, 1=>resistive - bit 8: Interrupt operation supported - bit 9: Calibration not required - bits 10-15: Reserved - bits 16-21: Bits of precision available - bits 22-31: Reserved - - "Calibration not required" indicates that the raw values returned map linearly - onto the screen display area to a usable accuracy as follows: - - X,Y (00000000,00000000) = bottom left of display area - X,Y (FFFFFFFF,FFFFFFFF) = top right of display area - Pres 00000000-1FFFFFFF = no touch - Pres 20000000-3FFFFFFF = light touch - Pres 3FFFFFFF-7FFFFFFF = touch - Pres 80000000-FFFFFFFF = firm touch - -unsigned int HAL_TouchscreenMeasure(int meas) - Performs a touchscreen measurement. Measurements are: - 0 = X position - 1 = Y position - 2 = pressure - 3 = X resistance - 4 = Y resistance - - "X" and "Y" need not actually be X and Y - rotation can be dealt with by - calibration. - - All values are returned as unsigned 32-bit values in the range &00000000-&FFFFFFFF. - If using, for example, a 10-bit DAC, the 10-bit value read should be placed at the - top of the returned word. Ideally, the 10 bits should be replicated in lower bits - (ABCDEFGH IJABCDEF GHIJABCD EFGHIJAB) to ensure the returned values fully span - the 32-bit range. - - Resistance measurements can be used to compensate for large pressed areas causing - shorts - subtract the instantaneous resistance from the instantaneous precision. - (I think). - -Serial ports -============ - -The RS232 serial UART is a fundamental peripheral on most current hardware. All diff --git a/Docs/HAL/NewAPI b/Docs/HAL/NewAPI deleted file mode 100644 index 7dfc6839..00000000 --- a/Docs/HAL/NewAPI +++ /dev/null @@ -1,235 +0,0 @@ -Overview -======== - -The HAL introduces the new concept of a "device". A device is a logical -representation of a component of hardware. Each active devices is uniquely -identified by a constant pointer to a device descriptor. The descriptor is -a structure which contains information about the device and a series of entry -points to perform usually simple operations on the device. Devices can be -provided by the Bootloader, or by RISC OS modules. - -Devices provided outside the Bootloader are, in principle, hot swappable, -although it is up to device drivers using it whether they can support this. - -Throughout this document, device descriptors are described in terms of C, -although the scheme maps naturally to assembler or C++. All device calls use -the base ATPCS calling standard (R0-R3 arguments/return values, R4-R11 -preserved, R12 corrupted), to permit straightforward use from C or assembler. - -From C: - XXXDevice->Activate(XXXDevice); - -A simple call to a activate a device from assembler might look like: - - LDR R0, XXXDevice - MOV LR, PC - LDR PC, [R0, #DevEntry_Activate] ; R0-R3,R12 corrupted - -If an assembler device driver module is using a lot of device calls, it -might be preferable to move the workspace pointer from the traditional R12 -to R11. - - -The device descriptor -===================== - -The device descriptor starts with a fixed format header, as described -below. Following this header are more function pointers providing device-specific -calls. - -struct device -{ - uint16_t type; - uint16_t id; - uint32_t location; - uint32_t version; - const char *description; - void *address; - uint32_t reserved[3]; - bool (*Activate)(struct device *); - void (*Deactivate)(struct device *); - void (*Reset)(struct device *); - int32_t (*Sleep)(struct device *, int32_t state); - int32_t devicenumber; - bool (*TestIRQ)(struct device *); - uint32_t reserved[2]; - -}; - - -struct serial -{ - struct device dev; - uint8_t (*ReadByte)(struct serial *); - void (*WriteByte)(struct serial *, uint8_t c); - - // private data -} - -Hence, the first device specific function pointer is offset 32 bytes from the -device pointer. - -Type ----- -The type word describes what the device is. - - Bits 15-8: Top level type (eg video, sound, system peripheral, comms port) - Defined values are: 1 = video - 2 = sound - 3 = system peripheral - 4 = comms port - Bits 7-0: Second level type (eg VDU display, 16-bit PCM sound output, - interrupt controller, UART). Allocated independently within each top - level type. - -This half-word, together with the version number, indicate which device specific calls -are available. - -ID --- -16-bit product code - a unique identifier for this particular device. - -Location --------- -The location describes the location of the device in terms of the bus architecture -of the computer. Again, it is grouped by bytes. - - Bits 31-28: Bus type - 0 => processor (0 = core, 1 = coprocessor) - 1 => main system bus (0 = AHB, 1 = ASB, 2 = PXBus) - 2 => peripheral bus (0 = APB) - 3 => expansion bus (0 = Acorn Expansion Card, 1 = ISA, 2 = PCI) - 4 => serial bus (0 = AC-Link) - Bits 27-24: Bus sub-type (see above) - Bits 23-16: Bus number - Bits 15-8: Card number (PCI, expansion card etc) / chip select number - Bits 7-0: Unit number - -Version -------- -The version describes the version of the device API implemented. It consists of a -major version number (bits 31-16) and a minor version number (bits 15-0). A change in -major version number indicates an incompatible change of API. An increase in the -minor version number indicates backwards-compatible extensions to the API (eg -extra functions). - -Description ------------ -A textual description of the device. This should be English, human-readable and -Basic Latin (characters &20-&7E). Descriptors along the lines of those output by -*Podules are expected. For example: - - National Semiconductor 16C550 UART - Philips ISP1160 USB host controller - Acorn IOMD21 PS/2 keyboard - Acorn VIDC20 - Intel SA-1110 DMA controller - -Address -------- -This field may either be 0, or may be a pointer to the base address of the -memory-mapped registers of the device in question. Drivers should not -normally use this field to directly poke the device. If they do, they must be -absolutely certain that there is no other way to achieve the effect, and that -the device type word is known to them. What exactly the address points to -depends on the exact device in question. - -Activate --------- -A device driver must call the Activate entry point before using a device. A -success/failure indication is returned: 1 indicates successful activation, 0 indicates -unsuccessful. Devices may ignore activate/deactivate calls, count them, or -may alternatively provide full locking to allow only one activation. Typically this -would be called by in a driver's module initialisation routine. Alternatively, it might -be called just before a DeviceFS device is opened for access. - -Deactivate ----------- -A device driver must call the Deactivate entry point when it has finished -using a device. - -Reset ------ -The Kernel will call the Reset entry point of every device on the system -before performing a software reset (eg OS_Reset or Ctrl-Break), after it has -issued Service_PreReset. All devices must enter a quiescent state. - -Sleep ------ -This call reads or sets a device's power-down state. If the second parameter is -1, -then the current state is returned; otherwise the second parameter must be a value in -the range 0-255 giving sleepiness (0 = full power, 255 = off) and the old sleepiness -is returned. Note that the value returned does not have to match the last value -programmed: for example, if a device cannot power down, it will always return 0. - -DeviceNumber ------------- -If this is -1, then the device has no associated interrupt. Otherwise, bits 0-30 give -the device number and bit 31 flags that the device vector is shared, ie this is the R0 -that should be passed to OS_ClaimDeviceVector. If bit 31 is set then the TestIRQ -routine must be used to determine whether the vector should be claimed or passed on. - -TestIRQ -------- -Returns 0 if the device is not interrupting, or 1 if the device is interrupting. -When DeviceNumber is -1, this must be a null pointer. - - - -Creation and removal of devices -=============================== - -Devices are declared by calling the HAL->OS call OS_AddDevice or SWI OS_Hardware 2. - -SWI OS_Hardware 2 (SWI &7A) ---------------------------- -On entry: R0 -> device descriptor - R8 = 2 -On exit: All registers preserved - -void OS_AddDevice(uint32_t flags, struct device *d); - -void HAL_InitDevices(uint32_t flags); - -Declare a new device to the system. OS_AddDevice must not be called until -HAL_InitDevices is called. - - -Devices are removed by calling OS_Hardware 3. There is no HAL->OS equivalent. - -SWI OS_Hardware 3 (SWI &7A) ---------------------------- -On entry: R0 -> device descriptor - R8 = 3 -On exit: All registers preserved - - -The Kernel tracks all present devices, issuing service calls as devices come and go, and -providing a call to enumerate devices of a particular type. - -SWI OS_Hardware 4 (SWI &7A) ---------------------------- -On entry: R0 bits 0-15 = type to match - bits 16-31 = maximum major version number to match - R1 = 0 to start an enumeration, else preserved from last call - R8 = 4 -On exit: R1 = -1 if there are no (more) devices of this type - R2 -> device descriptor (undefined if R1 = -1) - Other registers preserved - - -Service_Hardware (Service Call &D9) ------------------------------------- -On entry: R0 bits 0-7 = sub-reason code, bits 8-31 flags (undefined, ignore) - R1 = reason code (&D9) - R2 -> device -On exit: Depends on sub-reason code - - Sub-reason code 0: Device added -On exit: All registers must be preserved - - Sub-reason code 1: Device being removed -On exit: R1 = 0 => we object to device being removed - R0 -> error block - other registers must be preserved - else all registers must be preserved diff --git a/Docs/HAL/NewCDV b/Docs/HAL/NewCDV deleted file mode 100644 index 4cf878e6..00000000 --- a/Docs/HAL/NewCDV +++ /dev/null @@ -1,23 +0,0 @@ -New ClaimDeviceVector behaviour - -R3 and R4 are meaningless, except for podule IRQ and FIQ-as-IRQ, which -keep the same behaviour as previously. (This is currently done in the Kernel, -but should be deferred to the Podule Manager). - -For other claimants, if bit 31 of the R0 is set in the OS_ClaimDeviceVector -call, the interrupt will be passed on to earlier claimants unless your -routine claims the vector. This behaviour is then the same as IrqV claimants. -It is up to you to determine whether your device has interrupted. If it has, -you should service it, and claim the vector (by pulling the return address -off the stack). If not, pass the vector along. If no handlers claim the -vector, then the OS knows that there is no device driver able to handle the -interrupt being asserted, so it will mask off that line. - -If you do not claim the vector, you must preserve R0 and R3. R1,R2,R12 may -be corrupted. - -It is critical that your claiming or not is purely on the basis of whether -your card is interrupting, and is accurate. Not claiming when your card is -interrupting, or claiming when it isn't can both cause incorrect system -behaviour. - diff --git a/Docs/HAL/Notes b/Docs/HAL/Notes deleted file mode 100644 index afb54290..00000000 --- a/Docs/HAL/Notes +++ /dev/null @@ -1,109 +0,0 @@ -Entry into RISC OS: - -POST check (if any) complete - -CPU & memory systems at full speed -MMU off, SVC32 mode, IRQs+FIQs disabled -All interrupts masked -I/O timings set up -DRAM refresh running -Video system stabilised (off?) - - -Information passed: -Table of (addr,len) pairs of RAM -Address + amount of VRAM -Memory speed? -CPU speed? -Entry point to HAL - - - - - - -Questions: - -How to clear RAM without logical copy? Do we NEED a logical copy? -Yes we do - but logical copy will NOT be contiguous. - -Physical Size Logical - offset -F0000000 01000000 80000000 70000000 -F1000000 01000000 81000000 70000000 -60000000 00001000 82000000 22000000 - fast SRAM - how to signal? - -02000000 00200000 80000000 7FE00000 -10000000 01700000 80200000 70200000 -11B00000 02500000 81900000 6FE00000 -14000000 04000000 83E00000 6FE00000 - -02000000 00200000 82000000 80000000 -10000000 01700000 90000000 80000000 -11B00000 02500000 91B00000 80000000 -14000000 04000000 94000000 80000000 - - - - -Memory Map - - -00000000 16K Kernel workspace -00004000 16K Scratch space -00008000 Mem-32K Application memory -0xxxxxxx 3840M-Mem Dynamic areas -F0000000 160M I/O space (growing downwards if necessary) -FA000000 1M HAL workspace -FA100000 8K IRQ stack -FA200000 32K SVC stack -FA300000 8K ABT stack -FA400000 8K UND stack -FAE00000 1M Reserved for physical memory accesses -FAF00000 256k reserved for DCache cleaner address space (eg. StrongARM) -FAF40000 64k kernel buffers (for long command lines, size defined by KbuffsMaxSize) -FAFE8000 32K HAL workspace -FAFF0000 32K "Cursor/System/Sound" block (probably becoming just "System") -FAFF8000 32K "Nowhere" -FB000000 4M L2PT -FB400000 16K L1PT -FB404000 4M-16K System heap -FB800000 8M Soft CAM -FC000000 64M ROM - - -26-bit system: - -00000000 16K Kernel workspace -00004000 16K Scratch space -00008000 28M-32K Application memory -01C00000 32K SVC stack -01C08000 2M-32K System heap -01F00000 32K Cursor/System/Sound -01F08000 32K "Nowhere" -02100000 15M Module area -03000000 8M I/O space -03800000 8M ROM -04000000 2G-64M Dynamic areas -80000000 512M Logical copy of physical space -A0000000 1280M Dynamic areas -F0000000 224M I/O space (growing downwards if necessary) -FE000000 1M HAL workspace -FE100000 8K ABT stack -FE200000 8K UND stack -FF000000 4M L2PT + embedded L1PT -FF800000 8M Soft CAM - - -"Soft" resets - -Entry through HAL - full HAL initialisation. -HAL must not destroy (much) memory. -RISC OS detects intact memory and makes the reset "soft". -RAM page tables reconstructed from CAM. -Other page tables reconstructed through HAL. - - -"Break" - -RISC OS calls HAL to shut down, then shuts off MMU, and calls HAL_Reset code. -HAL then re-enters RISC OS in the usual fashion. diff --git a/Docs/HAL/OS_Hardware b/Docs/HAL/OS_Hardware deleted file mode 100644 index 1eeace5c..00000000 --- a/Docs/HAL/OS_Hardware +++ /dev/null @@ -1,47 +0,0 @@ -SWI OS_Hardware (SWI &7A) -------------------------- - -On entry: R0-R7 parameters - R8 = reason code (bits 0-7) and flags (bits 8-31) - R9 = hardware call number -On exit: depends on flags - -This SWI provides access to the hardware layer. Conceptually, it is -similar to accessing the hardware registers directly in earlier versions -of RISC OS - whereever possible OS routines should be used in preference. -This call is primarily designed for the use of device drivers - for example -the PS2Driver module makes PS2 hardware calls using this interface. - -Making hardware calls to devices normally managed by the Kernel is liable to -cause the same problems as poking the hardware. However, making hardware -calls is of course preferable to actually accessing the hardware directly. -Use this interface with caution. - -SWI OS_Hardware 0 (SWI &7A) ---------------------------- -On entry: R0-R7 parameters for hardware routine - R8 = 0 - R9 = hardware call number -On exit: R0-R3 updated by call - R4-R9 preserved. - -This SWI calls a HAL routine. HAL routines internally are ATPCS, so R0-R3 are -passed in as a1-a4, and R4-R7 are pushed on to the stack. The a1-a4 on exit -from the routine are passed back in R0-R3. - -If the HAL routine is not available, an error is returned. Actual HAL -routines do not return RISC OS errors - any possible failure will be -indicated in a call-specific manner. - -SWI OS_Hardware 1 (SWI &7A) ---------------------------- -On entry: R8 = 1 - R9 = hardware call number -On exit: R0 = routine address - R1 = static base value for routine - -This call looks up the address of a HAL routine. If it does not exist, an -error is returned. Otherwise, the address of the routine is returned in R0. -Calls made to the routine should be in a privileged mode, with R9 (sb) set to -the static base value returned by this SWI. Refer to the HAL documentation -for more details of calling conditions. diff --git a/Docs/HAL/OpenBusAdapter b/Docs/HAL/OpenBusAdapter deleted file mode 100644 index f6a30716..00000000 --- a/Docs/HAL/OpenBusAdapter +++ /dev/null @@ -1,43 +0,0 @@ - G F D B 9 7 5 3 1 Gnd? - G J E C A 8 6 4 2 0 - - -Aux - - X - X - - - G 1 3 5 7 9 B D F x - 0 2 4 6 8 A C E J x - -FIQ -aux -14 pfiq -12 preq -15 pirq -13 rclk - -Cont -3 Fiq -14 abe -9 nbw -15 dBE -1 wait -4 irq -8 nrw - - -2 brst -10 lock -clk mclk -0 state? (lk1) -7 seq? lk2 -12 nopc? lk3 -11 ntrans lk4 -6 mreq - -5 n/c -13 n/c - -CLK to AUX link connects MCLK to AUX clock diff --git a/Docs/HAL/Serial b/Docs/HAL/Serial deleted file mode 100644 index 7ff334a3..00000000 --- a/Docs/HAL/Serial +++ /dev/null @@ -1,133 +0,0 @@ -Features - - Bit 0: FIFOs available - -int ReceiveByte(int port, int *status) - - Returns the next byte from the FIFO (if enabled) or the holding register. - If status is non-NULL, the line status associated with the byte is - read (see LineStatus). The return value is only meaningful if a - received byte is available (bit 0 of *status will be set). - -void TransmitByte(int port, int byte) - -int LineStatus(int port) - - Bit 0: Receiver Data Ready - Bit 1: Overrun Error - Bit 2: Parity Error - Bit 3: Framing Error - Bit 4: Break Error - Bit 5: Transmitter Holding Register Empty - Bit 6: Transmitter Empty (including FIFO) - Bit 7: FIFO contains a Parity, Framing or Break error - - Parity, Framing and Break errors are associated with each byte received. - Whether the values reported here are associated with the last byte - read using ReceiveByte or with the next byte to be read is undefined. - You should request the status using ReceiveByte to ensure accurate - identification of bytes with errors. - - Error bits are cleared whenever status is read, using either LineStatus - or ReceiveByte with status non-NULL. - -int InterruptEnable(int port, int eor, int mask) - - Enables interrupts. Bits are: - - Bit 0: Received Data Available (and Character Timeout) - Bit 1: Transmitter Holding Register Empty - Bit 2: Received Line Status - Bit 3: Modem Status - - Returns previous state. - -int Rate(int port, int baud16) - - Sets the rate, in units of 1/16 of a baud. Returns the previous rate. - Use -1 to read. - -int Format(int port, int format) - - Bits 0-1: Bits per word 0=>5, 1=>6, 2=>7, 3=>8 - Bit 2: Stop length 0=>1, 1=>2 (1.5 if 5 bits) - Bit 3: Parity enabled - Bits 4-5: Parity: 0 => Odd (or disabled) - 1 => Even - 2 => Mark (parity bit = 1) - 3 => Space (parity bit = 0) - - Returns previous format. -1 to read. - -void FIFOSize(int *rx, int *tx) - - Returns the size of the RX and TX FIFOs. Either parameter may be NULL. - Note that the size of the TX FIFO is the total amount of data that can - be sent immediately when the Transmitter Holding Register Empty - status holds. (So an unusual UART that had a transmit threshold - should return total FIFO size minus threshold). - -void FIFOClear(int port, int flags) - - Clears the input FIFO (if bit 0 set) and the output FIFO (if bit 1 set). - -int FIFOEnable(int port, int enable) - - Enables or disables the RX and TX FIFOs: 0 => disable, 1 => enable - -1 => read status. Returns previous status. - -int FIFOThreshold(int port, int threshold) - - Sets the receive threshold level for the FIFO RX interrupt. Normally - available values are 1,4,8 and 14 bytes. Returns previous value. - -1 to read. - -int InterruptID(int port) - - Returns the highest priority interrupt currently asserted. In order - of priority: - - 3 => Receiver Line Status (Cleared by ReceiveByte/LineStatus) - 2 => Received Data Available (Cleared by reading enough data) - 6 => Character Timeout (received data waiting) - 1 => Transmitter Holding Register Empty (Cleared by this call) - 0 => Modem Status (Cleared by ModemStatus) - -1 => No Interrupt - - The Modem Status interrupt occurs when the CTS, DSR or DCD inputs - change, or when RI goes from high to low (ie bits 0 to 3 of ModemStatus - are set). - -int Break(int port, int enable) - - Activates (1) or deactivates (0) a break condition. -1 to read, - returns previous state. - -int ModemControl(int port, int eor, int mask) - - Modifies the modem control outputs. - - Bit 0: DTR - Bit 1: RTS - - Note that these are logical outputs, although the physical pins may be inverted. - So 1 indicates a request to send. - -int ModemStatus(int port) - - Reads the modem status inputs. - - Bit 0: CTS changed since last call - Bit 1: DSR changed since last call - Bit 2: RI changed from high to low since last call - Bit 3: DCD changed since last call - Bit 4: CTS - Bit 5: DSR - Bit 6: RI - Bit 7: DCD - - Note that these are logical inputs, although the physical pins may be inverted. - So 1 indicates a Clear To Send condition. - -int Device(int port) - diff --git a/Docs/MemMaps/+Access,ffd b/Docs/MemMaps/+Access,ffd deleted file mode 100644 index f76dd238ade08917e6712764a16a22005a50573d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1 IcmZPo000310RR91 diff --git a/Docs/MemMaps/+SrcIndex b/Docs/MemMaps/+SrcIndex deleted file mode 100644 index 6953e19f..00000000 --- a/Docs/MemMaps/+SrcIndex +++ /dev/null @@ -1,3 +0,0 @@ -directory -130 fff 0 Mike_Stephens 2bf39672 31060a66 0 -258 fff 0 Mike_Stephens 2bf395c1 31060a66 0 diff --git a/Docs/MemMaps/+SrcIndexO b/Docs/MemMaps/+SrcIndexO deleted file mode 100644 index a77883a4..00000000 --- a/Docs/MemMaps/+SrcIndexO +++ /dev/null @@ -1,3 +0,0 @@ -directory -130 fff 1 Mike_Stephens 2bf39672 31060a66 0 -258 fff 1 Mike_Stephens 2bf395c1 31060a66 0 diff --git a/Docs/MemMaps/130 b/Docs/MemMaps/130 deleted file mode 100644 index 8d44fc29..00000000 --- a/Docs/MemMaps/130 +++ /dev/null @@ -1,38 +0,0 @@ - 000 App space - 01C System heap/svc stack - 01E Soft CAM copy/und stack - 01F Sound/pointer/random - 020 RMA - 02C L2PT and L1PT - 030 I/O - 038 ROM - 040 Screen - 060 Free pool - 0E2 Sprites - 164 Font cache - 1E6 RAM disc - 268 Another area 1 - 2EA Another area 2 - 36C Another area 3 - 3EE Another area 4 - 470 Another area 5 - 4F2 Another area 6 - 574 Another area 7 - 5F6 Another area 8 - 678 Another area 9 - 6FA Another area 10 - 77C Another area 11 - 7FE Nothing - 800 Phys space copy - A00 Another area 12 - A82 Another area 13 - B04 Another area 14 - B86 Another area 15 - C08 Another area 16 - C8A Another area 17 - D0C Another area 18 - D8E Another area 19 - E10 Another area 20 - E92 Another area 21 - F14 Another area 22 - F96 Nothing diff --git a/Docs/MemMaps/258 b/Docs/MemMaps/258 deleted file mode 100644 index 86cfa15e..00000000 --- a/Docs/MemMaps/258 +++ /dev/null @@ -1,24 +0,0 @@ - 000 App space - 01C System heap/svc stack - 01E Soft CAM copy/und stack - 01F Sound/pointer/random - 020 RMA - 02C L2PT and L1PT - 030 I/O - 038 ROM - 040 Screen - 060 Free pool - 162 Sprites - 264 Font cache - 366 RAM disc - 468 Another area 1 - 56A Another area 2 - 66C Another area 3 - 76E Nothing - 800 Phys space copy - A00 Another area 4 - B02 Another area 5 - C03 Another area 6 - D04 Another area 7 - E05 Another area 8 - F06 Nothing diff --git a/Docs/PrivDoc/+Access,ffd b/Docs/PrivDoc/+Access,ffd deleted file mode 100644 index f76dd238ade08917e6712764a16a22005a50573d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1 IcmZPo000310RR91 diff --git a/Docs/PrivDoc/+SrcIndex b/Docs/PrivDoc/+SrcIndex deleted file mode 100644 index cd3053e6..00000000 --- a/Docs/PrivDoc/+SrcIndex +++ /dev/null @@ -1,4 +0,0 @@ -directory -5thColumn 1000 0 Mike_Stephens 2e05be22 30fd2d55 0 -MMPM fff 0 Mike_Stephens 2c53f7f8 31060a6b 0 -ScreenMode fff 0 Mike_Stephens 2c4d19fc 31060a6b 0 diff --git a/Docs/PrivDoc/+SrcIndexO b/Docs/PrivDoc/+SrcIndexO deleted file mode 100644 index b5095ee0..00000000 --- a/Docs/PrivDoc/+SrcIndexO +++ /dev/null @@ -1,4 +0,0 @@ -directory -5thColumn 1000 0 Mike_Stephens 2e05be22 30fd2d55 0 -MMPM fff 1 Mike_Stephens 2c53f7f8 31060a6b 0 -ScreenMode fff 1 Mike_Stephens 2c4d19fc 31060a6b 0 diff --git a/Docs/PrivDoc/5thColumn/+Access,ffd b/Docs/PrivDoc/5thColumn/+Access,ffd deleted file mode 100644 index f76dd238ade08917e6712764a16a22005a50573d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1 IcmZPo000310RR91 diff --git a/Docs/PrivDoc/5thColumn/+SrcIndex b/Docs/PrivDoc/5thColumn/+SrcIndex deleted file mode 100644 index 9e67ef52..00000000 --- a/Docs/PrivDoc/5thColumn/+SrcIndex +++ /dev/null @@ -1,2 +0,0 @@ -directory -Concept fff 0 Mike_Stephens 27ad92e9 31060a69 0 diff --git a/Docs/PrivDoc/5thColumn/+SrcIndexO b/Docs/PrivDoc/5thColumn/+SrcIndexO deleted file mode 100644 index 763bdbcc..00000000 --- a/Docs/PrivDoc/5thColumn/+SrcIndexO +++ /dev/null @@ -1,2 +0,0 @@ -directory -Concept fff 1 Mike_Stephens 27ad92e9 31060a69 0 diff --git a/Docs/PrivDoc/5thColumn/Concept b/Docs/PrivDoc/5thColumn/Concept deleted file mode 100644 index 50565e9e..00000000 --- a/Docs/PrivDoc/5thColumn/Concept +++ /dev/null @@ -1,59 +0,0 @@ -; > 5thColumn.Concept - - RISC OS Support for extension ROMs - ================================== - - Author: Tim Dobson - Status: Draft - Issue: 0.02 - History: - - Date Revision Changes - - 11-Oct-90 0.00 Started - 16-Oct-90 0.01 Completed first draft - 04-Feb-91 0.02 Updated to reflect reality - -This document describes the purpose of the extension ROM system and -discusses various design issues. For the full technical documentation, refer -to the document "5thColumn.Manual". - -The extension ROM system allows the development of hardware platforms fitted -with a normal 32 bit wide RISC OS ROM set plus one or more 8, 16 or 32 bit -ROMs or EPROMs containing software modules which add to or replace modules -in the main ROM set. This allows the same main ROM set to be used in a wider -variety of hardware platforms, removing the extra cost and lead times of -re-romming, and possibly reducing costs by allowing bulk purchase of the -main ROM set. - -The extension ROM(s) appear in the memory map in unused parts of the low -(&03400000 to &037FFFFF) or high (&03800000 to &03FFFFFF) ROM areas. A 32 -bit wide extension ROM set is directly executable in place, saving on user -RAM. 8 or 16 bit wide sets have to be copied into RAM to execute. By using -the low ROM area (whose access time is programmable independently from the -high area containing the main ROM set) slow EPROMs can be used. - -A particularly attractive configuration might be to have 8 ROM sockets on -the board, 4 for the main ROM set, and the other 4 capable of taking either -one 32 bit wide set (eg a large set of applications eg Internet) or up to 4 -individual 8 bit wide ROMs containing smaller applications or utilities. - -The scheme also allows a machine to have limited protection against -unauthorised access, if the extension ROM contains a module which requires a -password to be entered before continuing. - -In order to allow different sizes of EPROMs to be used without having to -have links on the board, the software will look for extension ROMs at higher -addresses first, and work backwards. This means that the high order address -lines (which should be tied to +5v on smaller sizes of EPROM) will be pulled -high initially, although they will be pulled low later on when looking for -further extension ROMs. - -The way in which the kernel initialises modules has been changed. If there -is more than one version of the same module present in the ROM (which -includes the main ROM, expansion card ROMs and extension ROMs) then only the -newest version of the module is initialised. If an extension ROM contains a -newer version of a module in the main ROM, then the newer version will be -initialised at the point in the initialisation sequence where the main ROM -version would have been initialised. This allows main ROM modules to be -replaced without the problems associated with initialisation order. diff --git a/Docs/PrivDoc/MMPM b/Docs/PrivDoc/MMPM deleted file mode 100644 index 57ea4e00..00000000 --- a/Docs/PrivDoc/MMPM +++ /dev/null @@ -1,54 +0,0 @@ -; > PrivDoc.MMPM - -Still to do on memory management, as of 26-May-93: - -; Must be TMD - - + Make SoftCAMMap variable size - + Finish routine to allocate backing L2 for an area - + Write routine to allocate logical addresses for areas - + Write routine to check for overlapping areas - + Complete Create dynamic area routine - (done apart from final OS_ChangeDynamicArea to get required size) - + Write Remove dynamic area routine - (done apart from initial OS_ChangeDynamicArea to shrink to zero size) - + Write Return info on dynamic area routine - + Write Enumerate dynamic areas routine - + Write Renumber dynamic areas routine - + Change OS_ReadDynamicArea to use new list - + Change OS_ValidateAddress to use new list - + Put in new error messages properly - * If CreateArea fails to grow area to required size, it should kill area and return error - * Change ChangeDynamicArea code to use lists: - + Check enough is working for Wimp_ClaimFreeMemory to use OS_DynamicArea(create) - * Check PreShrink and PostShrink work completely OK - * Check PreGrow and PostGrow work (apart from passing in page blocks) - * Migrate existing areas to new world: - * Update InitDynamicAreas initially to fake up a node for the RMA, and check it works - * Use DynamicArea_Create to create RMA from scratch (if feasible) - * Update InitDynamicAreas to fake up a node for the system heap + check it (no way of using create routine) - * Change OS_ReadRAMFsLimits to use OS_ReadDynamicArea - * Write RAMFS area handlers - * Create RAMFS dynamic area using DynamicArea_Create, + check it works - * Do similar for font cache, sprite area - - * Put in code to split grow block into chunks, and create page blocks (without checking for updates from PreGrow) - * Put in checks for PreGrow requesting particular pages, and call alternative code: - * Do the double shuffle - * Issue Service_PagesUnsafe/Safe - * Stop it getting the static pages (esp. cursor/sound page, L1 and maybe L2) - * Put in extra code to cope with doubly-mapped areas - * Write area handlers for screen, and move it to new world - * Change size of application space to 24M (check all refs to 16M in whole image) - * Put in indirections for hardware vector poking - * Change FPE to use indirections (KWelton) - * Move RMA to &02100000, and change size of app space to 28M - * Conversion to do late aborts - -; Could be done by ANOther - - * OS_Memory: - a) conversion bits - b) read phys.memory arrangement - c) read amounts of various sorts of memory - d) read controller addresses \ No newline at end of file diff --git a/Docs/PrivDoc/ScreenMode b/Docs/PrivDoc/ScreenMode deleted file mode 100644 index 410e776a..00000000 --- a/Docs/PrivDoc/ScreenMode +++ /dev/null @@ -1,92 +0,0 @@ -; > PrivDoc.ScreenMode - -Still to do on screen mode selection, as of 21-Jul-93: - -Key: + Done and tested - - Done but not tested - * Still to do - x Not done for a good reason - - + Make OS_ReadModeVariable work with mode selectors - + OS_ScreenMode(ReturnMode) - + OS_ScreenMode(EnumerateModes) - + Create variable holding video bandwidth - + Add this reason code to just load up video bandwidth, VideoSize and issue service - + Service_ModeExtension additions - + Load up r4 and r5 with video bandwidth, VideoSize respectively - + Change vdugrafg:SetUpSprModeData:04 to check for mode selector, and goto 10 if so - + Check other occurrences of BranchIfKnownMode to look for similar bits - + Put code to handle new sprite mode word into PushModeInfo (any monitor only?) - + Remove new sprite mode word fudging in vdugrafg:SetupSprModeData and - vdugrafl:SwitchOutputToSprite - + Make SwitchOutputToSprite(new format) set up ECFIndex (it doesn't at the moment!) - + Make sure tests for equal mode numbers don't assume equal ptrs to mode selectors are equivalent - + Modify NewModes module to respond to Service_EnumerateScreenModes, to test enumeration. - + OS_ScreenMode(SetMonitorType) - + Allocate soft copy for monitortype - + Write routine to update soft copy from CMOS - + Call this routine in initialisation - + Make *Configure MonitorType update soft copy - + Change ReadMonitorType to read from soft copy - + Add this reason code to either store given value or update from CMOS - + Make sprites which have mode selectors as their mode word illegal - + Move conversion of mode selectors to new format sprite mode words - into PreCreateHeader, rather than PostCreateHeader, so that it - doesn't call SetupSprModeData with a (now illegal) mode selector - -> MT ScreenModes module - - -> AG Make switch output to sprite for a new format sprite make mode selector for current mode? - - -> AG *ScreenSave in mode 50 seems to produce a sprite with a palette. - - -> NK Trying to set a WimpMode with XEigFactor=27 caused data abort. - Investigate and/or range-limit values. - - -> AG Put in support for returning errors from PushModeInfo (for bad mode - selectors and new format sprite mode words): - + Make mode change routine check for error from PushModeInfo and FindOKMode - + Make FindSubstitute check errors from PushModeInfo - + Make FindOKMode check errors from FindSubstitute - + Make CheckModeValid check errors from FindOKMode - + Make SetupSprModeData capable of returning errors: - + Ditto SpriteV handler (already OK) - + Ditto PreCreateHeader - + Ditto CreateHeader - + Ditto GetSprite - -> AG Make SwitchOutputToSprite/Mask check errors from PushModeInfo - - - Design and code algorithm for working out FIFO reload position for VIDC20 - (Still need explanation from ARM of why 7 quad-words doesn't always work) - - * OS_ScreenMode(SelectMode) - + Make normal mode selection routine into a subroutine - + Write veneers to put round call to this in OS_ScreenMode(SelectMode) - * Change actual mode change code to cope with mode selectors - + Prevent main routine looking at shadow bit in mode selector - + Modify FindOKMode to cope with mode selector - + Modify OS_CheckModeValid to cope with mode selector - + Make all pushed mode variables into words (not bytes) - + Modify PushModeInfo to cope with mode selector - + Make YEigFactor default to 2 if yres < xres/2 (and change spec. to reflect that) - + Make numbered modes work after loading mode file - + Allocate space for OS copy of mode selector - x Make OS mode selector part of saved VDU context - (not needed since sprites can't have mode selectors as their mode) - x Sort out internal mode variables PalIndex, ECFIndex wrt - converting existing mode numbers into mode selectors (no need, still use old workspace-getting code) - x Make mode selector blocks for all existing numbered modes - (no need, constructed on fly since only needed during svc call) - * Check that copying mode selector has no adverse effects - * Sort out why issuing a mode change with invalid mode selector doesn't give error - * Modify FindOKMode to cope with 16 and 32 bpp modes somehow - - * Prevent pointer position from going into the sync pulse (causes screen picture disruption) - - * Adjust borders on all modes, to cope with VIDC20 problem - (Needs algorithm from ARM that works!) - - * Mode change happily passes round any old rubbish to Service_ModeExtension - it should:- - * First check that value is word-aligned - if not it may be a new sprite mode word - * Do a Validate_Address on fixed bit of block? - - * What should *ScreenLoad do with a new format sprite? diff --git a/NewModes/Make,feb b/NewModes/Make,feb deleted file mode 100644 index 50fa3365..00000000 --- a/NewModes/Make,feb +++ /dev/null @@ -1,17 +0,0 @@ -| 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. -| -| > NewModes.Make -WimpSlot -min 1024k -max 1024k -AASM <Obey$Dir>.PSSrc <Obey$Dir>.PSModule -module -quit diff --git a/NewModes/NEWF2 b/NewModes/NEWF2 deleted file mode 100644 index cf992a1d..00000000 --- a/NewModes/NEWF2 +++ /dev/null @@ -1,144 +0,0 @@ -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; general purpose mode macros - -ClockShift * 9 -SyncShift * 11 - -; pixel rate specifiers - -CRPix_24000 * 3 :OR: (0 :SHL: ClockShift) -CRPix_16000 * 2 :OR: (0 :SHL: ClockShift) -CRPix_12000 * 1 :OR: (0 :SHL: ClockShift) -CRPix_8000 * 0 :OR: (0 :SHL: ClockShift) -CRPix_25175 * 3 :OR: (1 :SHL: ClockShift) -CRPix_36000 * 3 :OR: (2 :SHL: ClockShift) - - MACRO - VIDC_List $lbpp,$hsync,$hbpch,$hlbdr,$hdisp,$hrbdr,$hfpch, $vsync,$vbpch,$vlbdr,$vdisp,$vrbdr,$vfpch,$pixrate,$sp - LCLA sub - LCLA syncpol - [ $lbpp = 3 -sub SETA 5 - ] - [ $lbpp = 2 -sub SETA 7 - ] - [ $lbpp = 1 -sub SETA 11 - ] - [ $lbpp = 0 -sub SETA 19 - ] - [ "$sp"="" -syncpol SETA 0 :SHL: SyncShift ; normal sync polarity - | - ASSERT $sp<=3 -syncpol SETA $sp :SHL: SyncShift - ] - ASSERT ($hsync :AND: 1)=0 - ASSERT ($hbpch :AND: 1)=1 - ASSERT ($hlbdr :AND: 1)=0 - ASSERT ($hdisp :AND: 1)=0 - ASSERT ($hrbdr :AND: 1)=0 - ASSERT ($hfpch :AND: 1)=1 - [ (($hsync+$hbpch+$hlbdr+$hdisp+$hrbdr+$hfpch) :AND: 3)<>0 - ! 0, "Warning: mode unsuitable for interlaced use" - ] -; Horizontal - & (&80:SHL:24) :OR: ((($hsync+$hbpch+$hlbdr+$hdisp+$hrbdr+$hfpch -2 )/2) :SHL: 14) ; HCR - & (&84:SHL:24) :OR: ((($hsync -2 )/2) :SHL: 14) ; HSWR - & (&88:SHL:24) :OR: ((($hsync+$hbpch -1 )/2) :SHL: 14) ; HBSR - & (&8C:SHL:24) :OR: ((($hsync+$hbpch+$hlbdr -sub)/2) :SHL: 14) ; HDSR - & (&90:SHL:24) :OR: ((($hsync+$hbpch+$hlbdr+$hdisp -sub)/2) :SHL: 14) ; HDER - & (&94:SHL:24) :OR: ((($hsync+$hbpch+$hlbdr+$hdisp+$hrbdr -1 )/2) :SHL: 14) ; HBER - & (&9C:SHL:24) :OR: (((($hsync+$hbpch+$hlbdr+$hdisp+$hrbdr+$hfpch-2)/2+1)/2):SHL:14); HIR -; Vertical - & (&A0:SHL:24) :OR: (($vsync+$vbpch+$vlbdr+$vdisp+$vrbdr+$vfpch -1) :SHL: 14) ; VCR - & (&A4:SHL:24) :OR: (($vsync -1) :SHL: 14) ; VSWR - & (&A8:SHL:24) :OR: (($vsync+$vbpch -1) :SHL: 14) ; VBSR - & (&AC:SHL:24) :OR: (($vsync+$vbpch+$vlbdr -1) :SHL: 14) ; VDSR - & (&B0:SHL:24) :OR: (($vsync+$vbpch+$vlbdr+$vdisp -1) :SHL: 14) ; VDER - & (&B4:SHL:24) :OR: (($vsync+$vbpch+$vlbdr+$vdisp+$vrbdr -1) :SHL: 14) ; VBER -; Control Register - & (&E0:SHL:24) :OR: (CRPix_$pixrate) :OR: ($lbpp :SHL: 2) :OR: syncpol - & -1 - MEND - - MACRO - VIDC_WS $bpp,$hpix,$vpix,$multx,$multy, $dht - - & VduExt_XWindLimit, $hpix-1 - & VduExt_ScrRCol, ($hpix/8)-1 - & VduExt_LineLength, $hpix*$bpp/8 - [ "$dht" <> "" - & VduExt_ModeFlags, Flag_DoubleVertical - & VduExt_ScrBRow, ($vpix/16)-1 - | - & VduExt_ScrBRow, ($vpix/8)-1 - ] - & VduExt_YWindLimit, $vpix-1 - & VduExt_ScreenSize, $hpix*$vpix*$bpp/8 - - & VduExt_XEigFactor, $multx - & VduExt_YEigFactor, $multy - MEND - - - - -VLN_0 VIDC_List 0, 72,145, 48, 640, 48, 71, 3,18,18,256,17, 0,16000,0 ; MODE 0 -VLN_1 VIDC_List 1, 36, 73, 24, 320, 24, 35, 3,18,18,256,17, 0, 8000,0 ; MODE 1 -VLN_2 VIDC_List 2, 36, 73, 24, 320, 24, 35, 3,18,18,256,17, 0, 8000,0 ; MODE 2 -VLN_3 VIDC_List 1, 72,145, 48, 640, 48, 71, 3,18,22,250,19, 0,16000,0 ; MODE 3 -VLN_4 VIDC_List 0, 72,145, 48, 640, 48, 71, 3,18,18,256,17, 0,16000,0 ; MODE 4 -VLN_5 VIDC_List 1, 36, 73, 24, 320, 24, 35, 3,18,18,256,17, 0, 8000,0 ; MODE 5 -VLN_6 VIDC_List 1, 36, 73, 24, 320, 24, 35, 3,18,22,250,19, 0, 8000,0 ; MODE 6 -VLN_7 VIDC_List 2, 36, 73, 24, 320, 24, 35, 3,18,22,250,19, 0, 8000,0 ; MODE 7 -VLN_8 VIDC_List 1, 72,145, 48, 640, 48, 71, 3,18,18,256,17, 0,16000,0 ; MODE 8 -VLN_9 VIDC_List 2, 36, 73, 24, 320, 24, 35, 3,18,18,256,17, 0, 8000,0 ; MODE 9 -VLN_10 VIDC_List 3, 36, 73, 24, 320, 24, 35, 3,18,18,256,17, 0, 8000,0 ; MODE 10 -VLN_11 VIDC_List 1, 72,145, 48, 640, 48, 71, 3,18,22,250,19, 0,16000,0 ; MODE 11 -VLN_12 VIDC_List 2, 72,145, 48, 640, 48, 71, 3,18,18,256,17, 0,16000,0 ; MODE 12 -VLN_13 VIDC_List 3, 36, 73, 24, 320, 24, 35, 3,18,18,256,17, 0, 8000,0 ; MODE 13 -VLN_14 VIDC_List 2, 72,145, 48, 640, 48, 71, 3,18,22,250,19, 0,16000,0 ; MODE 14 -VLN_15 VIDC_List 3, 72,145, 48, 640, 48, 71, 3,18,18,256,17, 0,16000,0 ; MODE 15 -VLN_16 VIDC_List 2, 72,215, 46,1056, 46,101, 3,18,18,256,17, 0,24000,0 ; MODE 16 -VLN_17 VIDC_List 2, 72,215, 46,1056, 46,101, 3,18,22,250,19, 0,24000,0 ; MODE 17 -;VLN_18 VIDC_List 0, 56,183, 2, 640, 2, 13, 3,17, 1,512, 1, 0,24000,0 ; MODE 18 -;VLN_19 VIDC_List 1, 56,183, 2, 640, 2, 13, 3,17, 1,512, 1, 0,24000,0 ; MODE 19 -;VLN_20 VIDC_List 2, 56,183, 2, 640, 2, 13, 3,17, 1,512, 1, 0,24000,0 ; MODE 20 -;VLN_21 VIDC_List 3, 56,183, 2, 640, 2, 13, 3,17, 1,512, 1, 0,24000,0 ; MODE 21 -VLN_24 VIDC_List 3, 72,215, 46,1056, 46,101, 3,18,18,256,17, 0,24000,0 ; MODE 24 -VLN_33 VIDC_List 3, 74,127, 0, 768, 0, 55, 3,18, 0,288, 0, 3,16000,0 ; MODE 33 -VLN_34 VIDC_List 3, 74, 87, 0, 832, 0, 31, 3,18, 0,288, 0, 3,16000,0 ; MODE 34 - -VLM_0 VIDC_List 0, 72, 63, 88, 640, 88, 73, 3,16,17,256,17, 3,16000,0 ; MODE 0 -VLM_1 VIDC_List 1, 36, 33, 44, 320, 44, 35, 3,16,17,256,17, 3, 8000,0 ; MODE 1 -VLM_2 VIDC_List 2, 36, 33, 44, 320, 44, 35, 3,16,17,256,17, 3, 8000,0 ; MODE 2 -VLM_3 VIDC_List 1, 72, 63, 88, 640, 88, 73, 3,16,20,250,20, 3,16000,0 ; MODE 3 -VLM_4 VIDC_List 0, 72, 63, 88, 640, 88, 73, 3,16,17,256,17, 3,16000,0 ; MODE 4 -VLM_5 VIDC_List 1, 36, 51, 24, 320, 24, 57, 3,16,17,256,17, 3, 8000,0 ; MODE 5 -VLM_6 VIDC_List 1, 36, 33, 44, 320, 44, 35, 3,16,20,250,20, 3, 8000,0 ; MODE 6 -VLM_7 VIDC_List 2, 36, 31, 44, 320, 44, 37, 3,18,22,250,16, 3, 8000,0 ; MODE 7 -VLM_8 VIDC_List 1, 72, 63, 88, 640, 88, 73, 3,16,17,256,17, 3,16000,0 ; MODE 8 -VLM_9 VIDC_List 2, 36, 33, 44, 320, 44, 35, 3,16,17,256,17, 3, 8000,0 ; MODE 9 -VLM_10 VIDC_List 3, 36, 33, 44, 320, 44, 35, 3,16,17,256,17, 3, 8000,0 ; MODE 10 -VLM_11 VIDC_List 1, 72, 63, 88, 640, 88, 73, 3,16,20,250,20, 3,16000,0 ; MODE 11 -VLM_12 VIDC_List 2, 72, 63, 88, 640, 88, 73, 3,16,17,256,17, 3,16000,0 ; MODE 12 -VLM_13 VIDC_List 3, 36, 33, 44, 320, 44, 35, 3,16,17,256,17, 3, 8000,0 ; MODE 13 -VLM_14 VIDC_List 2, 72, 63, 88, 640, 88, 73, 3,16,20,250,20, 3,16000,0 ; MODE 14 -VLM_15 VIDC_List 3, 72, 63, 88, 640, 88, 73, 3,16,17,256,17, 3,16000,0 ; MODE 15 -VLM_16 VIDC_List 2,112, 47,132,1056,132, 57, 3,16,17,256,17, 3,24000,0 ; MODE 16 -VLM_17 VIDC_List 2,112, 47,132,1056,132, 57, 3,16,20,250,20, 3,24000,0 ; MODE 17 -VLM_18 VIDC_List 0, 56,111, 2, 640, 2, 85, 3,17, 1,512, 1, 0,24000,0 ; MODE 18 -VLM_19 VIDC_List 1, 56,111, 2, 640, 2, 85, 3,17, 1,512, 1, 0,24000,0 ; MODE 19 -VLM_20 VIDC_List 2, 56,111, 2, 640, 2, 85, 3,17, 1,512, 1, 0,24000,0 ; MODE 20 -VLM_21 VIDC_List 3, 56,111, 2, 640, 2, 85, 3,17, 1,512, 1, 0,24000,0 ; MODE 21 -VLM_24 VIDC_List 3,112, 47,132,1056,132, 57, 3,16,17,256,17, 3,24000,0 ; MODE 24 -VLM_25 VIDC_List 0, 96, 47, 0, 640, 0, 15, 2,32, 0,480, 0,11,25175,3 ; MODE 25 -VLM_26 VIDC_List 1, 96, 47, 0, 640, 0, 15, 2,32, 0,480, 0,11,25175,3 ; MODE 26 -VLM_27 VIDC_List 2, 96, 47, 0, 640, 0, 15, 2,32, 0,480, 0,11,25175,3 ; MODE 27 -VLM_28 VIDC_List 3, 96, 47, 0, 640, 0, 15, 2,32, 0,480, 0,11,25175,3 ; MODE 28 -VLM_31 VIDC_List 2, 72,129, 0, 800, 0, 23, 2,22, 0,600, 0, 1,36000,0 ; MODE 31 - -VLH_23 VIDC_List 2, 52, 47, 2, 288, 2, 1, 3,43, 4,896, 4, 0,24000,0 ; MODE 23 diff --git a/NewModes/NEWFORMAT b/NewModes/NEWFORMAT deleted file mode 100644 index d0734fed..00000000 --- a/NewModes/NEWFORMAT +++ /dev/null @@ -1,89 +0,0 @@ - [ {FALSE} ; This mode not supported by VIDC, so not used -V32tab1 - VIDC_List 0,36,73,24,320,24,35, 3,18,18,256,17,0,8000,0 - ] - -V32tab2 ; MODES 1,5 - VIDC_List 1,36,73,24,320,24,35, 3,18,18,256,17,0,8000,0 - -V32tab2T ; MODE 6 - VIDC_List 1,36,73,24,320,24,35, 3,18,22,250,19,0,8000,0 - -V32tab4 ; MODES 2,9 - VIDC_List 2,36,73,24,320,24,35, 3,18,18,256,17,0,8000,0 - -V32tab4T ; MODE 7 - VIDC_List 2,36,73,24,320,24,35, 3,18,22,250,19,0,8000,0 - -V32tab8 ; MODES 10,13 - VIDC_List 3,36,73,24,320,24,35, 3,18,18,256,17,0,8000,0 - - -V64tab1 ; MODES 0,4 - VIDC_List 0,72,145,48,640,48,71, 3,18,18,256,17,0,16000,0 - -V64tab2 ; MODE 8 - VIDC_List 1,72,145,48,640,48,71, 3,18,18,256,17,0,16000,0 - -V64tab2T ; MODES 3,11 - VIDC_List 1,72,145,48,640,48,71, 3,18,22,250,19,0,16000,0 - -V64tab4 ; MODE 12 - VIDC_List 2,72,145,48,640,48,71, 3,18,18,256,17,0,16000,0 - -V64tab4T ; MODE 14 - VIDC_List 2,72,145,48,640,48,71, 3,18,22,250,19,0,16000,0 - -V64tab8 ; MODE 15 - VIDC_List 3,72,145,48,640,48,71, 3,18,18,256,17,0,16000,0 - -V132tab4 ; MODE 16 - VIDC_List 2,72,215,46,1056,46,101, 3,18,18,256,17,0,24000,0 - -V132tab4T ; MODE 17 - VIDC_List 2,72,215,46,1056,46,101, 3,18,22,250,19,0,24000,0 - - [ {TRUE} -V64tab1D ; MODE 18 - VIDC_List 0,56,183,2,640,2,13, 3,17,1,512,1,0,24000,0 - -V64tab2D ; MODE 19 - VIDC_List 1,56,183,2,640,2,13, 3,17,1,512,1,0,24000,0 - -V64tab4D ; MODE 20 - VIDC_List 2,56,183,2,640,2,13, 3,17,1,512,1,0,24000,0 - -V64tab8D ; MODE 21 (NEW) - VIDC_List 3,56,183,2,640,2,13, 3,17,1,512,1,0,24000,0 - - [ {FALSE} ; not used any more -V128tab1 ; MODE 22 - VIDC_List 2,54,39,2,320,2,7, 2,44,1,976,1,0,24000,0 - ] - -V115tab1 ; MODE 23 new Unoid monitor style, 1152x896 - ; changed again 29-Jul-88 to give 64.4Hz - VIDC_List 2,52,47,2,288,2,1, 3,43,4,896,4,0,24000,0 - - | - -V64tab1D ; MODE 18 (old) - VIDC_List 0,56,199,2,640,2,1, 3,17,1,512,1,0,24000,0 - -V64tab2D ; MODE 19 (old) - VIDC_List 1,56,199,2,640,2,1, 3,17,1,512,1,0,24000,0 - -V64tab4D ; MODE 20 (old) - VIDC_List 2,56,199,2,640,2,1, 3,17,1,512,1,0,24000,0 - -V128tab1 ; MODE 22 (old) - VIDC_List 2,60,41,0,320,0,3, 2,44,1,976,1,0,24000,0 - -V115tab1 ; MODE 23 - VIDC_List 2,60,41,16,288,16,3, 2,44,57,864,57,0,24000,0 - - ] - -V132tab8 ; MODE 24 (NEW) - VIDC_List 3,72,215,46,1056,46,101, 3,18,18,256,17,0,24000,0 - diff --git a/NewModes/OldFormat b/NewModes/OldFormat deleted file mode 100644 index 278a8a6c..00000000 --- a/NewModes/OldFormat +++ /dev/null @@ -1,453 +0,0 @@ - [ {FALSE} ; This mode not supported by VIDC, so not used -V32tab1 - & &803FC000 - & &84044000 - & &880D8000 - & &8C0E4000 - & &90364000 - & &943B8000 - & &9C200000 - & &A04DC000 - & &A4008000 - & &A8050000 - & &AC098000 - & &B0498000 - & &B44DC000 - & &E0000030 - & -1 - ] - -V32tab2 ; MODES 1,5 - & &803FC000 - & &84044000 - & &880D8000 - & &8C0F4000 - & &90374000 - & &943B8000 - & &9C200000 - & &A04DC000 - & &A4008000 - & &A8050000 - & &AC098000 - & &B0498000 - & &B44DC000 - & &E0000034 - & -1 - -V32tab2T ; MODE 6 - & &803FC000 - & &84044000 - & &880D8000 - & &8C0F4000 - & &90374000 - & &943B8000 - & &9C200000 - & &A04DC000 - & &A4008000 - & &A8050000 - & &AC0A8000 ; start 4 pixels down - & &B0490000 ; end 2 pixels up - & &B44DC000 - & &E0000034 - & -1 - -V32tab4 ; MODES 2,9 - & &803FC000 - & &84044000 - & &880D8000 - & &8C0FC000 - & &9037C000 - & &943B8000 - & &9C200000 - & &A04DC000 - & &A4008000 - & &A8050000 - & &AC098000 - & &B0498000 - & &B44DC000 - & &E0000038 - & -1 - -V32tab4T ; MODE 7 - & &803FC000 - & &84044000 - & &880D8000 - & &8C0FC000 - & &9037C000 - & &943B8000 - & &9C200000 - & &A04DC000 - & &A4008000 - & &A8050000 - & &AC0A8000 ; start 4 pixels down - & &B0490000 ; end 2 pixels up - & &B44DC000 - & &E0000038 - & -1 - -V32tab8 ; MODES 10,13 - & &803FC000 - & &84044000 - & &880D8000 - & &8C100000 - & &90380000 - & &943B8000 - & &9C200000 - & &A04DC000 - & &A4008000 - & &A8050000 - & &AC098000 - & &B0498000 - & &B44DC000 - & &E000002C - & -1 - - -V64tab1 ; MODES 0,4 - & &807FC000 - & &8408C000 - & &881B0000 - & &8C1EC000 - & &906EC000 - & &94770000 - & &9C400000 - & &A04DC000 - & &A4008000 - & &A8050000 - & &AC098000 - & &B0498000 - & &B44DC000 - & &E0000032 - & -1 - -V64tab2 ; MODE 8 - & &807FC000 - & &8408C000 - & &881B0000 - & &8C1FC000 - & &906FC000 - & &94770000 - & &9C400000 - & &A04DC000 - & &A4008000 - & &A8050000 - & &AC098000 - & &B0498000 - & &B44DC000 - & &E0000036 - & -1 - -V64tab2T ; MODES 3,11 - & &807FC000 - & &8408C000 - & &881B0000 - & &8C1FC000 - & &906FC000 - & &94770000 - & &9C400000 - & &A04DC000 - & &A4008000 - & &A8050000 - & &AC0A8000 ; Start 4 pixels down - & &B0490000 ; End 2 pixels up - & &B44DC000 - & &E0000036 - & -1 - -V64tab4 ; MODE 12 - & &807FC000 - & &8408C000 - & &881B0000 - & &8C204000 - & &90704000 - & &94770000 - & &9C400000 - & &A04DC000 - & &A4008000 - & &A8050000 - & &AC098000 - & &B0498000 - & &B44DC000 - & &E000002A - & -1 - -V64tab4T ; MODE 14 - & &807FC000 - & &8408C000 - & &881B0000 - & &8C204000 - & &90704000 - & &94770000 - & &9C400000 - & &A04DC000 - & &A4008000 - & &A8050000 - & &AC0A8000 ; Start 4 pixels down - & &B0490000 ; End 2 pixels up - & &B44DC000 - & &E000002A - & -1 - -V64tab8 ; MODE 15 - & &807FC000 - & &8408C000 - & &881B0000 - & &8C208000 - & &90708000 - & &94770000 - & &9C400000 - & &A04DC000 - & &A4008000 - & &A8050000 - & &AC098000 - & &B0498000 - & &B44DC000 - & &E000001E - & -1 - -V132tab4 ; MODE 16 - & &80BFC000 - & &8408C000 - & &8823C000 ; 1B0000 - & &8C28C000 - & &90ACC000 - & &94B34000 ; B20000 - & &9C600000 - & &A04DC000 - & &A4008000 - & &A8050000 - & &AC098000 - & &B0498000 - & &B44DC000 - & &E000002B - & -1 - -V132tab4T ; MODE 17 - & &80BFC000 - & &8408C000 - & &8823C000 ; 1B0000 - & &8C28C000 - & &90ACC000 - & &94B34000 ; B34000 - & &9C600000 - & &A04DC000 - & &A4008000 - & &A8050000 - & &AC0A8000 ; start 4 pixels down - & &B0490000 ; end 2 pixels up - & &B44DC000 - & &E000002B - & -1 - - [ {TRUE} -V64tab1D ; MODE 18 - & &806FC000 - & &8406C000 - & &881DC000 - & &8C1BC000 - & &906BC000 - & &946E4000 - & &9C380000 - & &A0854000 - & &A4008000 - & &A804C000 - & &AC050000 - & &B0850000 - & &B4854000 - & &E0000033 - & -1 - -V64tab2D ; MODE 19 - & &806FC000 - & &8406C000 - & &881DC000 - & &8C1CC000 - & &906CC000 - & &946E4000 - & &9C380000 - & &A0854000 - & &A4008000 - & &A804C000 - & &AC050000 - & &B0850000 - & &B4854000 - & &E0000037 - & -1 - -V64tab4D ; MODE 20 - & &806FC000 - & &8406C000 - & &881DC000 - & &8C1D4000 - & &906D4000 - & &946E4000 - & &9C380000 - & &A0854000 - & &A4008000 - & &A804C000 - & &AC050000 - & &B0850000 - & &B4854000 - & &E000002B - & -1 - -V64tab8D ; MODE 21 (NEW) - & &806FC000 - & &8406C000 - & &881DC000 - & &8C1D8000 - & &906D8000 - & &946E4000 - & &9C380000 - & &A0854000 - & &A4008000 - & &A804C000 - & &AC050000 - & &B0850000 - & &B4854000 - & &E000000F - & -1 - - [ {FALSE} ; not used any more -V128tab1 ; MODE 22 - & &8034C000 - & &84068000 - & &880B8000 - & &8C0B0000 - & &90330000 - & &94340000 - & &9C1A8000 - & &A0FFC000 - & &A4004000 - & &A80B4000 - & &AC0B8000 - & &B0FF8000 - & &B4FFC000 - & &E000002B - & -1 - ] - -V115tab1 ; MODE 23 new Unoid monitor style, 1152x896 - ; changed again 29-Jul-88 to give 64.4Hz - & &8030C000 - & &84064000 - & &880C4000 - & &8C0BC000 - & &902FC000 - & &9430C000 - & &9C188000 ; changed 16-Aug-88, was 1A8 - & &A0ED4000 - & &A4008000 - & &A80B4000 - & &AC0C4000 - & &B0EC4000 - & &B4ED4000 - & &E000002B - & -1 - - | - -V64tab1D ; MODE 18 (old) - & &80704000 - & &8406C000 - & &881FC000 - & &8C1DC000 - & &906DC000 - & &94704000 - & &9C384000 - & &A0854000 - & &A4008000 - & &A804C000 - & &AC050000 - & &B0850000 - & &B4854000 - & &E0000033 - & -1 - -V64tab2D ; MODE 19 (old) - & &80704000 - & &8406C000 - & &881FC000 - & &8C1EC000 - & &906EC000 - & &94704000 - & &9C384000 - & &A0854000 - & &A4008000 - & &A804C000 - & &AC050000 - & &B0850000 - & &B4854000 - & &E0000037 - & -1 - -V64tab4D ; MODE 20 (old) - & &80704000 - & &8406C000 - & &881FC000 - & &8C1F4000 - & &906F4000 - & &94704000 - & &9C384000 - & &A0854000 - & &A4008000 - & &A804C000 - & &AC050000 - & &B0850000 - & &B4854000 - & &E000002B - & -1 - -V128tab1 ; MODE 22 (old) - & &8034C000 - & &84074000 - & &880C8000 - & &8C0BC000 - & &9033C000 - & &94348000 - & &9C1A8000 ; was wrong - & &A0FFC000 - & &A4004000 - & &A80B4000 - & &AC0B8000 - & &B0FF8000 - & &B4FFC000 - & &E000002B - & -1 - -V115tab1 ; MODE 23 - & &8034C000 - & &84074000 - & &880C8000 - & &8C0DC000 - & &9031C000 - & &94348000 - & &9C1A8000 ; was wrong - & &A0FFC000 - & &A4004000 - & &A80B4000 - & &AC198000 - & &B0F18000 - & &B4FFC000 - & &E000002B - & -1 - - ] - -V132tab8 ; MODE 24 (NEW) - & &80BFC000 - & &8408C000 - & &8823C000 - & &8C290000 - & &90AD0000 - & &94B34000 - & &9C600000 - & &A04DC000 - & &A4008000 - & &A8050000 - & &AC098000 - & &B0498000 - & &B44DC000 - & &E000000F - & -1 - diff --git a/NewModes/OldPSSrc b/NewModes/OldPSSrc deleted file mode 100644 index c8ebe682..00000000 --- a/NewModes/OldPSSrc +++ /dev/null @@ -1,1002 +0,0 @@ -; > NewModes.PSSrc -; 08-Nov-89 - - GET &.Hdr.ListOpts - GET &.Hdr.Macros - GET &.Hdr.System - GET &.Hdr.NewSpace - GET &.Hdr.ModHand - GET &.Hdr.Services - GET &.Hdr.Proc - GET &.Hdr.File - GET &.Hdr.NewErrors - GET &.Hdr.VduExt - GET &.Hdr.Debug - GET &.Hdr.CMOS - - LEADR Module_LoadAddr - - GBLL Debug -Debug SETL {FALSE} - - GBLL Module -Module SETL {TRUE} ; Really ! - -TAB * 9 -LF * 10 -FF * 12 -CR * 13 - -MonitorType_Normal * 0 -MonitorType_MultiSync * 1 -MonitorType_HiResMono * 2 -MonitorType_VGA * 3 -MonitorType_DontCare * -1 - -Normal * 1 :SHL: MonitorType_Normal -MultiSync * 1 :SHL: MonitorType_MultiSync -HiResMono * 1 :SHL: MonitorType_HiResMono -VGA * 1 :SHL: MonitorType_VGA - -ScreenEndAdr * &02000000 -Vinit * &03600000 -Interlace * &40 - - MACRO - NewMode $modeno, $monitors, $vidclist, $wslist - & $modeno - & $monitors -99 - & ($vidclist)-%BT99 - & ($wslist)-%BT99 - MEND - -; Module workspace allocation - - ^ 0, R12 - -ModeExt_WorkspaceSize * :INDEX: @ - -; **************** Module code starts here ********************** - -Module_BaseAddr - - DCD 0 - DCD ModeExt_Init -Module_BaseAddr - DCD ModeExt_Die -Module_BaseAddr - DCD ModeExt_Service -Module_BaseAddr - DCD ModeExt_Title -Module_BaseAddr - DCD ModeExt_HelpStr -Module_BaseAddr - DCD ModeExt_HC_Table-Module_BaseAddr - -ModeExt_Title - = "NewModes", 0 - -ModeExt_HelpStr - = "NewModes" - = TAB - = "1.3 (08 Nov 1989) test Multisync Modes", 0 - ALIGN - -; ***************************************************************************** - -ModeExt_HC_Table * Module_BaseAddr - -; ***************************************************************************** -; -; ModeExt_Init - Initialisation entry point -; - -ModeExt_Init ENTRY - - MOV R0, #EventV - ADRL R1, EventRoutine - MOV R2, R12 - SWI XOS_Claim - MOVVC R0, #14 - MOVVC R1, #Event_VSync - SWIVC XOS_Byte - EXIT - -; ***************************************************************************** -; -; ModeExt_Die - Die entry -; - -ModeExt_Die ENTRY - - MOV R0, #13 - MOV R1, #Event_VSync - SWI XOS_Byte - MOV R0, #EventV - ADRL R1, EventRoutine - MOV R2, R12 - SWI XOS_Release - EXITS - -; ***************************************************************************** -; -; ModeExt_Service - Main entry point for services -; -; in: R1 = service reason code -; - -ModeExt_Service ENTRY - TEQ R1, #Service_ModeExtension - TEQNE R1, #Service_PreModeChange - TEQNE R1, #Service_ModeChange - TEQNE R1, #Service_Reset - TEQNE R1, #Service_ModeTranslation - EXIT NE - - TEQ R1, #Service_PreModeChange - MOVEQ R14, #0 ; zero the word - STREQ R14, [R12] - EXIT EQ - - TEQ R1, #Service_ModeChange - BEQ ModeChangeService - - TEQ R1, #Service_Reset - BEQ ResetCode - - TEQ R1, #Service_ModeTranslation - BEQ ModeTranslation - - [ Debug - DREG R2, "Mode = " - DREG R3, "Monitor type = " - ] - - Push "R5-R8" - - ADR R5, NewModesList-8 - MOV R8, #1 -10 - ADD R5, R5, #8 ; skip VidC, WS - LDMIA R5!, {R6, R7} ; R6 = mode, R7 = OK monitor types - CMP R6, #-1 - Pull "R5-R8, PC", EQ ; mode not in list, exit - TEQ R2, R6 ; if not this mode - BNE %BT10 ; then loop - CMP R3, #MonitorType_DontCare ; if any monitor type - BEQ %FT20 ; then found one - TST R7, R8, LSL R3 ; else if not appropriate monitor - BEQ %BT10 ; then loop -20 - LDMIA R5, {R3, R4} ; load offsets to VidCList, WSList - ADD R3, R3, R5 ; convert to addresses - ADD R4, R4, R5 ; convert to addresses - MOV R1, #0 ; claim service - Pull "R5-R8, PC" - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -NewModesList - - NewMode 0, MultiSync, Multi100VIDCList, Multi100WSList ; rshifted Mode 0 - NewMode 1, MultiSync, Multi101VIDCList, Multi101WSList ; rshifted Mode 1 - NewMode 2, MultiSync, Multi102VIDCList, Multi102WSList ; rshifted Mode 2 - NewMode 3, MultiSync, Multi103VIDCList, Multi103WSList ; rshifted Mode 3 - NewMode 4, MultiSync, Multi104VIDCList, Multi104WSList ; rshifted Mode 4 - NewMode 5, MultiSync, Multi105VIDCList, Multi105WSList ; rshifted Mode 5 - NewMode 6, MultiSync, Multi106VIDCList, Multi106WSList ; rshifted Mode 6 - NewMode 7, MultiSync, Multi107VIDCList, Multi107WSList ; rshifted Mode 7 - NewMode 8, MultiSync, Multi108VIDCList, Multi108WSList ; rshifted Mode 8 - NewMode 9, MultiSync, Multi109VIDCList, Multi109WSList ; rshifted Mode 9 - NewMode 10, MultiSync, Multi110VIDCList, Multi110WSList ; rshifted Mode 10 - NewMode 11, MultiSync, Multi111VIDCList, Multi111WSList ; rshifted Mode 11 - NewMode 12, MultiSync, Multi112VIDCList, Multi112WSList ; rshifted Mode 12 - NewMode 13, MultiSync, Multi113VIDCList, Multi113WSList ; rshifted Mode 13 - NewMode 14, MultiSync, Multi114VIDCList, Multi114WSList ; rshifted Mode 14 - NewMode 15, MultiSync, Multi115VIDCList, Multi115WSList ; rshifted Mode 15 - NewMode 16, MultiSync, Multi116VIDCList, Multi116WSList ; rshifted Mode 16 - NewMode 17, MultiSync, Multi117VIDCList, Multi117WSList ; rshifted Mode 17 - NewMode 18, MultiSync, Multi118VIDCList, Multi118WSList ; rshifted Mode 18 - NewMode 19, MultiSync, Multi119VIDCList, Multi119WSList ; rshifted Mode 19 - NewMode 20, MultiSync, Multi120VIDCList, Multi120WSList ; rshifted Mode 20 - NewMode 21, MultiSync, Multi121VIDCList, Multi121WSList ; rshifted Mode 21 - - NewMode 24, MultiSync, Multi124VIDCList, Multi124WSList ; rshifted Mode 24 - - NewMode 25, VGA :OR: MultiSync, VGA1VIDCList, VGA1WSList2 ; VGA 1bp 640x480 - NewMode 26, VGA :OR: MultiSync, VGA2VIDCList, VGA2WSList2 ; VGA 2bp 640x480 - NewMode 27, VGA :OR: MultiSync, VGA4VIDCList, VGA4WSList2 ; VGA 4bp 640x480 - NewMode 28, VGA :OR: MultiSync, VGA8VIDCList, VGA8WSList2 ; VGA 8bp 640x480 - - NewMode 31, MultiSync, sVGA4_VIDCList, sVGA4_WSList ; super VGA 4bp 800x600 - NewMode 32, MultiSync, sVGA8_VIDCList, sVGA8_WSList ; super VGA 8bp 800x600 - - NewMode 33, Normal :OR: MultiSync, Mode33VIDCList, Mode33WSList ; overscan 768x288 - NewMode 34, Normal :OR: MultiSync, Mode34VIDCList, Mode34WSList ; overscan 832x288 - -; NewMode 45, VGA :OR: MultiSync, VGA11VIDCList, VGA11WSList2 ; VGA 1bp 640x350 -; NewMode 46, VGA :OR: MultiSync, VGA12VIDCList, VGA12WSList2 ; VGA 2bp 640x350 -; NewMode 47, VGA :OR: MultiSync, VGA14VIDCList, VGA14WSList2 ; VGA 4bp 640x350 -; NewMode 48, VGA :OR: MultiSync, VGA18VIDCList, VGA18WSList2 ; VGA 8bp 640x350 - -; NewMode 55, VGA :OR: MultiSync, VGA21VIDCList, VGA21WSList2 ; VGA 1bp 720x400 -; NewMode 56, VGA :OR: MultiSync, VGA22VIDCList, VGA22WSList2 ; VGA 2bp 720x400 -; NewMode 57, VGA :OR: MultiSync, VGA24VIDCList, VGA24WSList2 ; VGA 4bp 720x400 -; NewMode 58, VGA :OR: MultiSync, VGA28VIDCList, VGA28WSList2 ; VGA 8bp 720x400 - -; NewMode 60, MultiSync, Multi350VIDCList, Multi350WSList ; MDA 640x350 -; NewMode 61, MultiSync, Multi200VIDCList, Multi200WSList ; CGA 640x200 -; NewMode 62, MultiSync, Multi351VIDCList, Multi351WSList ; EGA 640x350 - -; NewMode 66, MultiSync, Multi66VIDCList, Multi66WSList ; DTP 960x384 4bpp -; NewMode 67, MultiSync, Multi67VIDCList, Multi67WSList ; DTP 960x384 8bpp - -; NewMode 76, MultiSync, Multi76VIDCList, Multi76WSList ; DTP 1280x384 4bpp -; NewMode 77, MultiSync, Multi77VIDCList, Multi77WSList ; DTP 1280x384 8bpp - - & -1, 0 - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; general purpose mode macros - -ClockShift * 9 -SyncShift * 11 - -; pixel rate specifiers - -CRPix_24000 * 3 :OR: (0 :SHL: ClockShift) -CRPix_16000 * 2 :OR: (0 :SHL: ClockShift) -CRPix_12000 * 1 :OR: (0 :SHL: ClockShift) -CRPix_8000 * 0 :OR: (0 :SHL: ClockShift) -CRPix_25175 * 3 :OR: (1 :SHL: ClockShift) -CRPix_36000 * 3 :OR: (2 :SHL: ClockShift) - - MACRO - VIDC_List $bpp,$hsync,$hbpch,$hlbdr,$hdisp,$hrbdr,$hfpch, $vsync,$vbpch,$vlbdr,$vdisp,$vrbdr,$vfpch,$pixrate,$sp - LCLA sub - LCLA lbpp - LCLA syncpol - [ $bpp = 8 -sub SETA 5 -lbpp SETA 3 - ] - [ $bpp = 4 -sub SETA 7 -lbpp SETA 2 - ] - [ $bpp = 2 -sub SETA 11 -lbpp SETA 1 - ] - [ $bpp = 1 -sub SETA 19 -lbpp SETA 0 - ] - [ "$sp"="" :LOR: "$sp"="0" -syncpol SETA 0 :SHL: SyncShift ; normal sync polarity - | - [ "$sp"="1" -syncpol SETA 3 :SHL: SyncShift ; inverted H and V sync - | - ! 1,"Sync polarity must be null string or 0 (for normal syncs) or 1 (for inverted H and V syncs)" - ] - ] - ASSERT ($hsync :AND: 1)=0 - ASSERT ($hbpch :AND: 1)=1 - ASSERT ($hlbdr :AND: 1)=0 - ASSERT ($hdisp :AND: 1)=0 - ASSERT ($hrbdr :AND: 1)=0 - ASSERT ($hfpch :AND: 1)=1 -; Horizontal - & (&80:SHL:24) :OR: ((($hsync+$hbpch+$hlbdr+$hdisp+$hrbdr+$hfpch -2 )/2) :SHL: 14) ; HCR - & (&84:SHL:24) :OR: ((($hsync -2 )/2) :SHL: 14) ; HSWR - & (&88:SHL:24) :OR: ((($hsync+$hbpch -1 )/2) :SHL: 14) ; HBSR - & (&8C:SHL:24) :OR: ((($hsync+$hbpch+$hlbdr -sub)/2) :SHL: 14) ; HDSR - & (&90:SHL:24) :OR: ((($hsync+$hbpch+$hlbdr+$hdisp -sub)/2) :SHL: 14) ; HDER - & (&94:SHL:24) :OR: ((($hsync+$hbpch+$hlbdr+$hdisp+$hrbdr -1 )/2) :SHL: 14) ; HBER -; Vertical - & (&A0:SHL:24) :OR: (($vsync+$vbpch+$vlbdr+$vdisp+$vrbdr+$vfpch -1) :SHL: 14) ; VCR - & (&A4:SHL:24) :OR: (($vsync -1) :SHL: 14) ; VSWR - & (&A8:SHL:24) :OR: (($vsync+$vbpch -1) :SHL: 14) ; VBSR - & (&AC:SHL:24) :OR: (($vsync+$vbpch+$vlbdr -1) :SHL: 14) ; VDSR - & (&B0:SHL:24) :OR: (($vsync+$vbpch+$vlbdr+$vdisp -1) :SHL: 14) ; VDER - & (&B4:SHL:24) :OR: (($vsync+$vbpch+$vlbdr+$vdisp+$vrbdr -1) :SHL: 14) ; VBER -; Control Register - & (&E0:SHL:24) :OR: (CRPix_$pixrate) :OR: (lbpp :SHL: 2) :OR: syncpol - MEND - - MACRO - VIDC_WS $bpp,$hpix,$vpix,$multx,$multy, $dht - - & VduExt_XWindLimit, $hpix-1 - & VduExt_ScrRCol, ($hpix/8)-1 - & VduExt_LineLength, $hpix*$bpp/8 - [ "$dht" <> "" - & VduExt_ModeFlags, Flag_DoubleVertical - & VduExt_ScrBRow, ($vpix/16)-1 - | - & VduExt_ScrBRow, ($vpix/8)-1 - ] - & VduExt_YWindLimit, $vpix-1 - & VduExt_ScreenSize, $hpix*$vpix*$bpp/8 - - & VduExt_XEigFactor, $multx - & VduExt_YEigFactor, $multy - MEND - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -; Start of multi sync archy modes - -; Mode 0, multiscan mode 0 -Multi100VIDCList - & 0 - & 0 - VIDC_List 1,72,63,88,640,88,73, 3,16,17,256,17,3,16000 - & -1 -Multi100WSList - & 0 - & 0 - & -1 - -; Mode 1, multiscan mode 1 -Multi101VIDCList - & 0 - & 1 - VIDC_List 2,36,33,44,320,44,35, 3,16,17,256,17,3,8000 - & -1 -Multi101WSList - & 0 - & 1 - & -1 - -; Mode 2, multiscan mode 2 -Multi102VIDCList - & 0 - & 2 - VIDC_List 4,36,33,44,320,44,35, 3,16,17,256,17,3,8000 - & -1 -Multi102WSList - & 0 - & 2 - & -1 - -; Mode 3, multiscan mode 3 -Multi103VIDCList - & 0 - & 3 - VIDC_List 2,72,63,88,640,88,73, 3,16,20,250,20,3,16000 - & -1 -Multi103WSList - & 0 - & 3 - & -1 - -; Mode 4, multiscan mode 4 -Multi104VIDCList - & 0 - & 4 - VIDC_List 1,72,63,88,640,88,73, 3,16,17,256,17,3,16000 - & -1 -Multi104WSList - & 0 - & 4 - & -1 - -; Mode 5, multiscan mode 5 -Multi105VIDCList - & 0 - & 5 - VIDC_List 2,36,51,24,320,24,57, 3,16,17,256,17,3,8000 - & -1 -Multi105WSList - & 0 - & 5 - & -1 - -; Mode 6, multiscan mode 6 -Multi106VIDCList - & 0 - & 6 - VIDC_List 2,36,33,44,320,44,35, 3,16,20,250,20,3,8000 - & -1 -Multi106WSList - & 0 - & 6 - & -1 - -; Mode 7, multiscan mode 7 -Multi107VIDCList - & 0 - & 7 - VIDC_List 4,36,31,44,320,44,37, 3,18,22,250,16,3,8000 - & -1 -Multi107WSList - & 0 - & 7 - & -1 - -; Mode 8, multiscan mode 8 -Multi108VIDCList - & 0 - & 8 - VIDC_List 2,72,63,88,640,88,73, 3,16,17,256,17,3,16000 - & -1 -Multi108WSList - & 0 - & 8 - & -1 - -; Mode 9, multiscan mode 9 -Multi109VIDCList - & 0 - & 9 - VIDC_List 4,36,33,44,320,44,35, 3,16,17,256,17,3,8000 - & -1 -Multi109WSList - & 0 - & 9 - & -1 - -; Mode 10, multiscan mode 10 -Multi110VIDCList - & 0 - & 10 - VIDC_List 8,36,33,44,320,44,35, 3,16,17,256,17,3,8000 - & -1 -Multi110WSList - & 0 - & 10 - & -1 - -; Mode 11, multiscan mode 11 -Multi111VIDCList - & 0 - & 11 - VIDC_List 2,72,63,88,640,88,73, 3,16,20,250,20,3,16000 - & -1 -Multi111WSList - & 0 - & 11 - & -1 - -; Mode 12, multiscan mode 12 -Multi112VIDCList - & 0 - & 12 - VIDC_List 4,72,63,88,640,88,73, 3,16,17,256,17,3,16000 - & -1 -Multi112WSList - & 0 - & 12 - & -1 - -; Mode 13, multiscan mode 13 -Multi113VIDCList - & 0 - & 13 - VIDC_List 8,36,33,44,320,44,35, 3,16,17,256,17,3,8000 - & -1 -Multi113WSList - & 0 - & 13 - & -1 - -; Mode 14, multiscan mode 14 -Multi114VIDCList - & 0 - & 14 - VIDC_List 4,72,63,88,640,88,73, 3,16,20,250,20,3,16000 - & -1 -Multi114WSList - & 0 - & 14 - & -1 - -; Mode 15, multiscan mode 15 -Multi115VIDCList - & 0 - & 15 - VIDC_List 8,72,63,88,640,88,73, 3,16,17,256,17,3,16000 - & -1 -Multi115WSList - & 0 - & 15 - & -1 - -; Mode 16, multiscan mode 16 -Multi116VIDCList - & 0 - & 16 - VIDC_List 4,112,47,132,1056,132,57, 3,16,17,256,17,3,24000 -; -; tv blanking! 112,139, 76,1056,114, 39, ,3,18,16,256,16,3 -; 4u67,5u79,3u2,44u,4u7,1u62, 21r 3r -; should be =10u4 =1u65 22r 3r(2r5) -;philips needs bprch > 57 or goes dark (sync at 112) -; can inc sync to 10u0, more and screen starts to wobble - & -1 -Multi116WSList - & 0 - & 16 - & -1 - -; Mode 17, multiscan mode 17 -Multi117VIDCList - & 0 - & 17 - VIDC_List 4,112,47,132,1056,132,57, 3,16,20,250,20,3,24000 - & -1 -Multi117WSList - & 0 - & 17 - & -1 - -; Mode 18, multiscan mode 18 -Multi118VIDCList - & 0 - & 18 - VIDC_List 1,56,111,2,640,2,85, 3,17,1,512,1,0,24000 - & -1 -Multi118WSList - & 0 - & 18 - & -1 - -; Mode 19, multiscan mode 19 -Multi119VIDCList - & 0 - & 19 - VIDC_List 2,56,111,2,640,2,85, 3,17,1,512,1,0,24000 - & -1 -Multi119WSList - & 0 - & 19 - & -1 - -; Mode 20, multiscan mode 20 -Multi120VIDCList - & 0 - & 20 - VIDC_List 4,56,111,2,640,2,85, 3,17,1,512,1,0,24000 - & -1 -Multi120WSList - & 0 - & 20 - & -1 - -; Mode 21, multiscan mode 21 -Multi121VIDCList - & 0 - & 21 - VIDC_List 8,56,111,2,640,2,85, 3,17,1,512,1,0,24000 - & -1 -Multi121WSList - & 0 - & 21 - & -1 - -; Mode 24, multiscan mode 24 -Multi124VIDCList - & 0 - & 24 - VIDC_List 8,112,47,132,1056,132,57, 3,16,17,256,17,3,24000 - & -1 -Multi124WSList - & 0 - & 24 - & -1 - - -; MODE 25 (VGA or multisync monitors, 640x480) -VGA1VIDCList - & 0 - & 18 - VIDC_List 1,96,47,0,640,0,15, 2,32,0,480,0,11,25175,1 - & -1 -VGA1WSList2 - & 0 - & 18 - & -1 - -; MODE 26 (VGA or multisync monitors, 640x480) -VGA2VIDCList - & 0 - & 19 - VIDC_List 2,96,47,0,640,0,15, 2,32,0,480,0,11,25175,1 - & -1 -VGA2WSList2 - & 0 - & 19 - & -1 - -; MODE 27 (VGA or multisync monitors, 640x480) -VGA4VIDCList - & 0 - & 20 - VIDC_List 4,96,47,0,640,0,15, 2,32,0,480,0,11,25175,1 - & -1 -VGA4WSList2 - & 0 - & 20 - & -1 - -; MODE 28 (VGA or multisync monitors, 640x480) -VGA8VIDCList - & 0 - & 21 - VIDC_List 8,96,47,0,640,0,15, 2,32,0,480,0,11,25175,1 - & -1 -VGA8WSList2 - & 0 - & 21 - & -1 - -; MODE 31 (800x600 by 4 bits per pixel) -sVGA4_VIDCList - & 0 - & 20 - VIDC_List 4,72,129,0,800,0,23, 2,22,0,600,0,1,36000 - & &E000042B - & -1 -sVGA4_WSList - & 0 - & 20 - VIDC_WS 4,800,600,1,1 - & -1 - -; MODE 32 (800x600 by 8 bits per pixel) -sVGA8_VIDCList - & 0 - & 24 - VIDC_List 8,72,129,0,800,0,23, 2,22,0,600,0,1,36000 - & &E000040F - & -1 -sVGA8_WSList - & 0 - & 24 - VIDC_WS 8,800,600,1,1 - & -1 - -; MODE 33 (768x288 by 8 bits per pixel) -Mode33VIDCList - - & 0 - & 15 - VIDC_List 8,74,127,0,768,0,55, 3,18,0,288,0,3,16000 - & -1 -Mode33WSList - & 0 - & 15 - VIDC_WS 8,768,288,1,2 - & -1 - -; MODE 34 (832x288 by 8 bits per pixel) -Mode34VIDCList - & 0 - & 15 - VIDC_List 8,74,87,0,832,0,31, 3,18,0,288,0,3,16000 - & -1 -Mode34WSList - & 0 - & 15 - VIDC_WS 8,832,288,1,2 - & -1 - -;; MODE 45 (VGA or multisync monitors, 640x350) -;VGA11VIDCList -; & 0 -; & 18 -; VIDC_List 1,96,47,0,640,0,15, 2,59,0,350,0,38 -; & -1 -;VGA11WSList2 -; & 0 -; & 18 -; VIDC_WS 1,640,350,1,2 -; & -1 - -;; MODE 46 (VGA or multisync monitors, 640x350) -;VGA12VIDCList -; & 0 -; & 19 -; VIDC_List 2,96,47,0,640,0,15, 2,59,0,350,0,38 -; & -1 -;VGA12WSList2 -; & 0 -; & 19 -; VIDC_WS 2,640,350,1,2 -; & -1 - -;; MODE 47 (VGA or multisync monitors, 640x350) -;VGA14VIDCList -; & 0 -; & 20 -; VIDC_List 4,96,47,0,640,0,15, 2,59,0,350,0,38 -; & -1 -;VGA14WSList2 -; & 0 -; & 20 -; VIDC_WS 4,640,350,1,2 -; & -1 - -;; MODE 48 (VGA or multisync monitors, 640x350) -;VGA18VIDCList -; & 0 -; & 21 -; VIDC_List 8,96,47,0,640,0,15, 2,59,0,350,0,38 -; & &E000020F -; & -1 -;VGA18WSList2 -; & 0 -; & 21 -; VIDC_WS 8,640,350,1,2 -; & -1 - -;; MODE 55 (VGA or multisync monitors, 720x400) -;VGA21VIDCList -; & 0 -; & 18 -; VIDC_List 1,108,55,0,720,0,17, 2,34,0,400,0,13 -; & -1 -;VGA21WSList2 -; & 0 -; & 18 -; VIDC_WS 1,720,400,1,2 -; & -1 - -;; MODE 56 (VGA or multisync monitors, 720x400) -;VGA22VIDCList -; & 0 -; & 19 -; VIDC_List 2,108,55,0,720,0,17, 2,34,0,400,0,13 -; & -1 -;VGA22WSList2 -; & 0 -; & 19 -; VIDC_WS 2,720,400,1,2 -; & -1 - -;; MODE 57 (VGA or multisync monitors, 720x400) -;VGA24VIDCList -; & 0 -; & 20 -; VIDC_List 4,108,55,0,720,0,17, 2,34,0,400,0,13 -; & -1 -;VGA24WSList2 -; & 0 -; & 20 -; VIDC_WS 4,720,400,1,2 -; & -1 - -;; MODE 58 (VGA or multisync monitors, 720x400) -;VGA28VIDCList -; & 0 -; & 21 -; VIDC_List 8,108,55,0,720,0,17, 2,34,0,400,0,13 -; & &E000020F -; & -1 -;VGA28WSList2 -; & 0 -; & 21 -; VIDC_WS 8,720,400,1,2 -; & -1 - -;; IBM standard form modes - -;; Mode 60 MDA, multiscan -;Multi350VIDCList -; & 0 -; & 12 -; VIDC_List 4,132,17,2,704,2,9, 17,4,0,350,0,0 -; & -1 -;Multi350WSList -; & 0 -; & 12 -; VIDC_WS 4,704,350,1,2 -; & -1 - -;; Mode 61 CGA, multiscan -;Multi200VIDCList -; & 0 -; & 12 -; VIDC_List 4,68,115,0,720,0,105, 3,34,0,200,0,25 -; & -1 -;Multi200WSList -; & 0 -; & 12 -; VIDC_WS 4,720,200,1,2 -; & -1 - -;; Mode 62 EGA, multiscan -;Multi351VIDCList -; & 0 -; & 12 -; VIDC_List 4,78,25,0,624,0,1, 13,2,0,350,0,1 -; & -1 -;Multi351WSList -; & 0 -; & 12 -; VIDC_WS 4,624,350,1,2 -; & -1 - - -;; Mode 66 , DTP multiscan 960x384 4bpp -;Multi66VIDCList -; & 0 -; & 20 -; VIDC_List 4,72,101,0,960,0,39, 3,18,0,384,0,2 -; & -1 -;Multi66WSList -; & 0 -; & 20 -; VIDC_WS 4,960,384,1,2 -; & -1 - -;; Mode 67 , DTP multiscan 960x384 8bpp -;Multi67VIDCList -; & 0 -; & 21 -; VIDC_List 8,72,101,0,960,0,39, 3,18,0,384,0,2 -; & -1 -;Multi67WSList -; & 0 -; & 21 -; VIDC_WS 8,960,384,1,2 -; & -1 - -;; Mode 76 , DTP multiscan 1280x296 4bpp -;Multi76VIDCList -; & 0 -; & 16 -; VIDC_List 4,48,111,0,1280,0,53, 3,14,0,296,0,4 -; & -1 -;Multi76WSList -; & 0 -; & 16 -; VIDC_WS 4,1280,296,1,2 -; & -1 - -;; Mode 77 , DTP multiscan 1280x296 8bpp -;Multi77VIDCList -; & 0 -; & 24 -; VIDC_List 8,48,111,0,1280,0,53, 3,14,0,296,0,4 -; & -1 -;Multi77WSList -; & 0 -; & 24 -; VIDC_WS 8,1280,296,1,2 -; & -1 - - [ Debug - InsertDebugRoutines - ] - -; ***************************************************************************** -; -; Code to execute on reset -; -; in: R14 already stacked -; - -ResetCode ROUT - Push "R0-R6" - BL ModeExt_Init - Pull "R0-R6,PC" - -; ***************************************************************************** -; -; EventRoutine - Routine called on Vsync -; - -EventRoutine ROUT - TEQ R0, #Event_VSync - MOVNE PC, R14 - ENTRY "R0-R6" - LDR R1, [R12] ; load state flag, 0 => disabled - RSBS R1, R1, #0 ; change sign - EXIT EQ ; if zero then do nowt - - STR R1, [R12] ; store back - VDWS WsPtr - LDR R2, [WsPtr, #TotalScreenSize] ; needed later as well - ADDMI R1, R1, R2 ; if -ve then add TotalScreenSize - - STR R1, [WsPtr, #TeletextOffset] - -; now set VInit to this - - LDR R0, [WsPtr, #DisplayStart] - SUB R0, R0, #ScreenEndAdr - ADD R0, R0, R2 ; make start of screen 0 - ADD R0, R0, R1 ; add on teletext bank offset - CMP R0, R2 ; if out of range - SUBCS R0, R0, R2 ; then subtract total size -SetVinitPhys - MOV R1, #Vinit - STR R0, [WsPtr, #VinitCopy] - MOV R0, R0, LSR #4 ; bottom 4 bits not valid - ORR R0, R1, R0, LSL #2 ; OR in at correct place - STR R0, [R0] ; any old data will do - - LDR R0, [WsPtr, #VIDCControlCopy] - ORR R0, R0, #Interlace ; turn interlace on - STR R0, [WsPtr, #VIDCControlCopy] - MOV R1, #VIDC - STR R0, [R1] - - EXIT - -; ***************************************************************************** - -ModeChangeService - Push "R0-R6" - MOV R5, R12 ; our workspace pointer - VDWS WsPtr - MOV R6, #0 - LDR R0, [WsPtr, #DisplayModeNo] - TEQ R0, #18 - TEQNE R0, #19 - TEQNE R0, #20 - TEQNE R0, #21 - TEQNE R0, #26 - TEQNE R0, #27 - BNE %FT10 - MOV R0, #&A1 - MOV R1, #VduCMOS - SWI XOS_Byte - ANDS R2, R2, #MonitorTypeBits - BNE %FT10 - - MOV R0, #255 - STR R0, [WsPtr, #DisplayYWindLimit] - LDR R0, [WsPtr, #YEigFactor] - ADD R0, R0, #1 - STR R0, [WsPtr, #DisplayYEigFactor] - LDR R0, =541-6 - STR R0, [WsPtr, #CursorFudgeFactor] - - LDR R6, [WsPtr, #LineLength] - MOV R6, R6, LSR #1 - RSB R6, R6, #0 -10 - STR R6, [R5] - Pull "R0-R6, PC" - -; ***************************************************************************** -; -; ModeTranslation - Code to perform VGA mode number translation -; -; in: R1 = Service_ModeTranslation -; R2 = mode number -; R3 = monitor type -; return address stacked -; -; out: R1 = 0 if claimed -; R2 = substitute -; R3 preserved - -ModeTranslation ROUT - TEQ R3, #MonitorType_VGA - Pull PC, NE - BIC R1, R2, #&80 ; get rid of shadow bit - CMP R1, #32 ; if in range 32..39 - RSBCSS R1, R1, #39 - BCS %FT10 ; then don't modify - - [ {TRUE} - MOV R2, #0 - | - Push R0 - MOV R0, R2 - MOV R1, #9 ; log2bpp - SWI XOS_ReadModeVariable - Pull R0 - MOVVS R2, #0 ; if error or invalid then use mode 32 - MOVCS R2, #0 - CMP R2, #4 - MOVCS R2, #3 - ADD R2, R2, #32 - ] -10 - MOV R1, #0 ; claim service - Pull PC - - END - diff --git a/NewModes/OldToNew,ffb b/NewModes/OldToNew,ffb deleted file mode 100644 index 982d10c2346510cefd9691867c6d7f539f57082e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2713 zcmah~PiQ0O6`zrIH```E$FWMuCQW$EjvP%qk~Na-wOx<tSeDm{6*;xM+TBpP9Z4f= z8hK_iGm`Ak!%~tS$`X2LOX;C3?Lz+$aww&=P(qWCl0y<gAcd49q)-yrLuiT)rH8if zefpb2sSGpz-v8h4z3&YZghU_mu6N?whpiB_)zxJ%>aOpg@W|_gmLEVVY%oDM-N#3v z4<);9If2!Hj?=Jw2wN5yo>|A&P@_T>y=>QkOezftGLVKUN%=Ac+3v%M+kqqV1ROVn zPGDgaJAkI$w!k{BTV4pZ19dE*ZJSQrf}S0=c&1^T6h=w*;o2~YTMJEeFww<30k=7A z3T8MeKGz5OwZhO_TU_k*dMT3^o^t)e#r6PJuvjYQ3*|~7iN%i`i+#B4w5=cj-+HQJ z`v|^v0;Y%M)y*0f-8OsR`d}XV7V1Km%J2DhXgh~01a33znZAY5F7=^d2cd7*klASl zhqwS)m^MHTO$Q{S0>z31n?|KrQ87%p4_Ar@JA0Q8;EJ)oZ<G&;g$nHLLw>KkRXix} zmGQI<M)?}-7Ry^ISjZpt$~yLZLV=~)#I4mJA`xB1q85xh2u-x0bKqHZyJ^=EpmW$U z4=p%!yO!@DF7Pb>$PTE_0TxLUBKM(fAK9T9a^Yk?rn*K`^!dd;Y=GHl25W1%)Go%e z+Np}$@#|KqZ1o;<8&;6oYc~#DJTc)5@&`~YZsp^N%+ivg2Ax_WtEirR?3<w#B(x=k z2@l0ctmxXRs%h#)b%_ay>tho|UrDFas+Qr;WqM|E^n{h{s)q8Vm5Zvjd~qeKW|p*z zODYUax!b@r%iSQY@;@eI9?ZAh`jeHG-3;~BwaST8AN;RrOjzIRntr`y`m!z=oB6H6 z_NATTqr0WY%6pH0b-!|Oxq9X5wI|G4y<s&ETlP1fY#%wU_mm%moo?^=<mt4Q$>x@@ zpw;W&keIN&*sv+ofHK2xcKnq5KZrx~#~-vEx=XT7ZVM7|x$XK#W{Aos9&$V3XS7K2 zSlgH_mi6awe7OY^oH-ma{RJ5LFyWZlPDn$q|BMOWX0QDKo`+X26w6GwISYoY-@asp zCELMi|KTirjFGr8++@P7hXDnDG-NfatZzs#4-(vjXF*e?O%rbo1;qk?buU0QuHS-} z&@zX;{mnh(hoYoLVP2fYJNyqUh&wRhH9Ak#^!8l<uQTC23B`l4sm3=pHZnOyuf}i8 zr_<Z~$Apj2@C_#X{S2A^>-?y=Wksjj=2y~K9urSZhyOhjXRy3sTm>s);(c=@m?~J5 z{$FZQ<u!`Shz#DjfE25S%*3zog2YG9U|Hh9={K49^|S91wPNdY?~)Z0{nH;Z@mr^u z_?>g_!|iI~YFuIB_ZE>JenIfaSwdDbs&pCGbjUT}nZ9{s;Wn3;_~RLUY|X^m80>`^ z3^wYU_`9=ru#rrB`EG3Ii#-49XFuhlKi{R3=0o(kGxPqW31WXHzprCG^My1P^zT@^ z=6QM|zfZ&~H?k~p_Wm8TNRY`&T0yavQy$4IWLRYGft|{gkt+8Y)t4UF*{qCID-)H* zBJ&q^w#KUbL`7?Wk}E8dMw7zOdvz-3l*t+<7@JJx#spjU?-WPQlla*1NLl+BP`AF3 zKuF1qvY5d!{uCsXLDy_|ES$zVZbe-5mV;L=a`nFI2)i+=V*vxz&R56CjZt<|w9i+^ zxQ!8RQgqK($Eb}_RiwCqiV={_=^Wq1P-De(j_=R30^C_Tk<TJOiM488y`>Z1$${t> zu~xg*@O9!jNpcqXb*zP7Cl5sh6rr3&{t#>V+zPXxsDPqB&9$057P3S1vdCLAU7m~J zvdCXzU7m|DCI_Ow#kxEfp-YmSMLvmjc`m}0Bsq)xGuGv~2oZ`fax^m6<++ex^drf+ zOT)FVkJo<!2N7;SBD=mm+1U!tOk#4xJ}S=)?6Qi&qF;O%aZdck>z&-j2Ns2A=@KO9 z!t)<ptm`H0JjgVKs?15o7a_(Mp~M#<!xy2!7a>qV<{YUqCkI~xQ%(Y&2BsXWDi4vV za^Oi=>m#TC%A&bbEV{w?olF=qN_XzP1Dmp%kE^?JwG?O3{d;g({~VX9B$L<IW??t3 zPtMJAP>SojaU7?pHxFbx`iQBtic4`-QxxQ}6kpeWiEAMG^xc4m1sxrpIRkI9=yOT> u0?>xvjVCo_;gwtDNFmWXIgkxPVg4WCf{XriuvntcpBt~i=x-6ufBp;QQ4IkA diff --git a/NewModes/PSSrc b/NewModes/PSSrc deleted file mode 100644 index a9b05b5f..00000000 --- a/NewModes/PSSrc +++ /dev/null @@ -1,791 +0,0 @@ -; > NewModes.PSSrc -; 08-Nov-89 - - GET &.Hdr.ListOpts - GET &.Hdr.Macros - GET &.Hdr.System - GET &.Hdr.NewSpace - GET &.Hdr.ModHand - GET &.Hdr.Services - GET &.Hdr.Proc - GET &.Hdr.File - GET &.Hdr.NewErrors - GET &.Hdr.VduExt - GET &.Hdr.Debug - GET &.Hdr.CMOS - - LEADR Module_LoadAddr - - GBLL Debug -Debug SETL {FALSE} - - GBLL Module -Module SETL {TRUE} ; Really ! - -TAB * 9 -LF * 10 -FF * 12 -CR * 13 - -MonitorType_Normal * 0 -MonitorType_MultiSync * 1 -MonitorType_HiResMono * 2 -MonitorType_VGA * 3 -MonitorType_DontCare * -1 - -Normal * 1 :SHL: MonitorType_Normal -MultiSync * 1 :SHL: MonitorType_MultiSync -HiResMono * 1 :SHL: MonitorType_HiResMono -VGA * 1 :SHL: MonitorType_VGA - -ScreenEndAdr * &02000000 -Vinit * &03600000 -Interlace * &40 - - MACRO - NewMode $modeno, $monitors, $vidclist, $wslist - & $modeno - & $monitors -99 - & ($vidclist)-%BT99 - & ($wslist)-%BT99 - MEND - -; Module workspace allocation - - ^ 0, R12 - -ModeExt_WorkspaceSize * :INDEX: @ - -; **************** Module code starts here ********************** - -Module_BaseAddr - - DCD 0 - DCD ModeExt_Init -Module_BaseAddr - DCD ModeExt_Die -Module_BaseAddr - DCD ModeExt_Service -Module_BaseAddr - DCD ModeExt_Title -Module_BaseAddr - DCD ModeExt_HelpStr -Module_BaseAddr - DCD ModeExt_HC_Table-Module_BaseAddr - -ModeExt_Title - = "NewModes", 0 - -ModeExt_HelpStr - = "NewModes" - = TAB - = "1.3 (08 Nov 1989) test Multisync Modes", 0 - ALIGN - -; ***************************************************************************** - -ModeExt_HC_Table * Module_BaseAddr - -; ***************************************************************************** -; -; ModeExt_Init - Initialisation entry point -; - -ModeExt_Init ENTRY - - MOV R0, #EventV - ADRL R1, EventRoutine - MOV R2, R12 - SWI XOS_Claim - MOVVC R0, #14 - MOVVC R1, #Event_VSync - SWIVC XOS_Byte - EXIT - -; ***************************************************************************** -; -; ModeExt_Die - Die entry -; - -ModeExt_Die ENTRY - - MOV R0, #13 - MOV R1, #Event_VSync - SWI XOS_Byte - MOV R0, #EventV - ADRL R1, EventRoutine - MOV R2, R12 - SWI XOS_Release - EXITS - -; ***************************************************************************** -; -; ModeExt_Service - Main entry point for services -; -; in: R1 = service reason code -; - -ModeExt_Service ENTRY - TEQ R1, #Service_ModeExtension - TEQNE R1, #Service_PreModeChange - TEQNE R1, #Service_ModeChange - TEQNE R1, #Service_Reset - TEQNE R1, #Service_ModeTranslation - EXIT NE - - TEQ R1, #Service_PreModeChange - MOVEQ R14, #0 ; zero the word - STREQ R14, [R12] - EXIT EQ - - TEQ R1, #Service_ModeChange - BEQ ModeChangeService - - TEQ R1, #Service_Reset - BEQ ResetCode - - TEQ R1, #Service_ModeTranslation - BEQ ModeTranslation - - [ Debug - DREG R2, "Mode = " - DREG R3, "Monitor type = " - ] - - Push "R5-R8" - - ADR R5, NewModesList-8 - MOV R8, #1 -10 - ADD R5, R5, #8 ; skip VidC, WS - LDMIA R5!, {R6, R7} ; R6 = mode, R7 = OK monitor types - CMP R6, #-1 - Pull "R5-R8, PC", EQ ; mode not in list, exit - TEQ R2, R6 ; if not this mode - BNE %BT10 ; then loop - CMP R3, #MonitorType_DontCare ; if any monitor type - BEQ %FT20 ; then found one - TST R7, R8, LSL R3 ; else if not appropriate monitor - BEQ %BT10 ; then loop -20 - LDMIA R5, {R3, R4} ; load offsets to VidCList, WSList - ADD R3, R3, R5 ; convert to addresses - ADD R4, R4, R5 ; convert to addresses - MOV R1, #0 ; claim service - Pull "R5-R8, PC" - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -NewModesList - - NewMode 0, MultiSync, Multi100VIDCList, Multi100WSList ; rshifted Mode 0 - NewMode 1, MultiSync, Multi101VIDCList, Multi101WSList ; rshifted Mode 1 - NewMode 2, MultiSync, Multi102VIDCList, Multi102WSList ; rshifted Mode 2 - NewMode 3, MultiSync, Multi103VIDCList, Multi103WSList ; rshifted Mode 3 - NewMode 4, MultiSync, Multi104VIDCList, Multi104WSList ; rshifted Mode 4 - NewMode 5, MultiSync, Multi105VIDCList, Multi105WSList ; rshifted Mode 5 - NewMode 6, MultiSync, Multi106VIDCList, Multi106WSList ; rshifted Mode 6 - NewMode 7, MultiSync, Multi107VIDCList, Multi107WSList ; rshifted Mode 7 - NewMode 8, MultiSync, Multi108VIDCList, Multi108WSList ; rshifted Mode 8 - NewMode 9, MultiSync, Multi109VIDCList, Multi109WSList ; rshifted Mode 9 - NewMode 10, MultiSync, Multi110VIDCList, Multi110WSList ; rshifted Mode 10 - NewMode 11, MultiSync, Multi111VIDCList, Multi111WSList ; rshifted Mode 11 - NewMode 12, MultiSync, Multi112VIDCList, Multi112WSList ; rshifted Mode 12 - NewMode 13, MultiSync, Multi113VIDCList, Multi113WSList ; rshifted Mode 13 - NewMode 14, MultiSync, Multi114VIDCList, Multi114WSList ; rshifted Mode 14 - NewMode 15, MultiSync, Multi115VIDCList, Multi115WSList ; rshifted Mode 15 - NewMode 16, MultiSync, Multi116VIDCList, Multi116WSList ; rshifted Mode 16 - NewMode 17, MultiSync, Multi117VIDCList, Multi117WSList ; rshifted Mode 17 - NewMode 18, MultiSync, Multi118VIDCList, Multi118WSList ; rshifted Mode 18 - NewMode 19, MultiSync, Multi119VIDCList, Multi119WSList ; rshifted Mode 19 - NewMode 20, MultiSync, Multi120VIDCList, Multi120WSList ; rshifted Mode 20 - NewMode 21, MultiSync, Multi121VIDCList, Multi121WSList ; rshifted Mode 21 - - NewMode 24, MultiSync, Multi124VIDCList, Multi124WSList ; rshifted Mode 24 - - NewMode 25, VGA :OR: MultiSync, VGA1VIDCList, VGA1WSList2 ; VGA 1bp 640x480 - NewMode 26, VGA :OR: MultiSync, VGA2VIDCList, VGA2WSList2 ; VGA 2bp 640x480 - NewMode 27, VGA :OR: MultiSync, VGA4VIDCList, VGA4WSList2 ; VGA 4bp 640x480 - NewMode 28, VGA :OR: MultiSync, VGA8VIDCList, VGA8WSList2 ; VGA 8bp 640x480 - - NewMode 31, MultiSync, sVGA4_VIDCList, sVGA4_WSList ; super VGA 4bp 800x600 - NewMode 32, MultiSync, sVGA8_VIDCList, sVGA8_WSList ; super VGA 8bp 800x600 - - NewMode 33, Normal :OR: MultiSync, Mode33VIDCList, Mode33WSList ; overscan 768x288 - NewMode 34, Normal :OR: MultiSync, Mode34VIDCList, Mode34WSList ; overscan 832x288 - - & -1, 0 - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; general purpose mode macros - -ClockShift * 9 -SyncShift * 11 - -; pixel rate specifiers - -CRPix_24000 * 3 :OR: (0 :SHL: ClockShift) -CRPix_16000 * 2 :OR: (0 :SHL: ClockShift) -CRPix_12000 * 1 :OR: (0 :SHL: ClockShift) -CRPix_8000 * 0 :OR: (0 :SHL: ClockShift) -CRPix_25175 * 3 :OR: (1 :SHL: ClockShift) -CRPix_36000 * 3 :OR: (2 :SHL: ClockShift) - - MACRO - VIDC_List $lbpp,$hsync,$hbpch,$hlbdr,$hdisp,$hrbdr,$hfpch, $vsync,$vbpch,$vlbdr,$vdisp,$vrbdr,$vfpch,$pixrate,$sp - LCLA sub - LCLA syncpol - [ $lbpp = 3 -sub SETA 5 - ] - [ $lbpp = 2 -sub SETA 7 - ] - [ $lbpp = 1 -sub SETA 11 - ] - [ $lbpp = 0 -sub SETA 19 - ] - [ "$sp"="" -syncpol SETA 0 :SHL: SyncShift ; normal sync polarity - | - ASSERT $sp<=3 -syncpol SETA $sp :SHL: SyncShift - ] - ASSERT ($hsync :AND: 1)=0 - ASSERT ($hbpch :AND: 1)=1 - ASSERT ($hlbdr :AND: 1)=0 - ASSERT ($hdisp :AND: 1)=0 - ASSERT ($hrbdr :AND: 1)=0 - ASSERT ($hfpch :AND: 1)=1 - [ (($hsync+$hbpch+$hlbdr+$hdisp+$hrbdr+$hfpch) :AND: 3)<>0 - ! 0, "Warning: mode unsuitable for interlaced use" - ] -; Horizontal - & (&80:SHL:24) :OR: ((($hsync+$hbpch+$hlbdr+$hdisp+$hrbdr+$hfpch -2 )/2) :SHL: 14) ; HCR - & (&84:SHL:24) :OR: ((($hsync -2 )/2) :SHL: 14) ; HSWR - & (&88:SHL:24) :OR: ((($hsync+$hbpch -1 )/2) :SHL: 14) ; HBSR - & (&8C:SHL:24) :OR: ((($hsync+$hbpch+$hlbdr -sub)/2) :SHL: 14) ; HDSR - & (&90:SHL:24) :OR: ((($hsync+$hbpch+$hlbdr+$hdisp -sub)/2) :SHL: 14) ; HDER - & (&94:SHL:24) :OR: ((($hsync+$hbpch+$hlbdr+$hdisp+$hrbdr -1 )/2) :SHL: 14) ; HBER - & (&9C:SHL:24) :OR: (((($hsync+$hbpch+$hlbdr+$hdisp+$hrbdr+$hfpch-2)/2+1)/2):SHL:14); HIR -; Vertical - & (&A0:SHL:24) :OR: (($vsync+$vbpch+$vlbdr+$vdisp+$vrbdr+$vfpch -1) :SHL: 14) ; VCR - & (&A4:SHL:24) :OR: (($vsync -1) :SHL: 14) ; VSWR - & (&A8:SHL:24) :OR: (($vsync+$vbpch -1) :SHL: 14) ; VBSR - & (&AC:SHL:24) :OR: (($vsync+$vbpch+$vlbdr -1) :SHL: 14) ; VDSR - & (&B0:SHL:24) :OR: (($vsync+$vbpch+$vlbdr+$vdisp -1) :SHL: 14) ; VDER - & (&B4:SHL:24) :OR: (($vsync+$vbpch+$vlbdr+$vdisp+$vrbdr -1) :SHL: 14) ; VBER -; Control Register - & (&E0:SHL:24) :OR: (CRPix_$pixrate) :OR: ($lbpp :SHL: 2) :OR: syncpol - MEND - - MACRO - VIDC_WS $bpp,$hpix,$vpix,$multx,$multy, $dht - - & VduExt_XWindLimit, $hpix-1 - & VduExt_ScrRCol, ($hpix/8)-1 - & VduExt_LineLength, $hpix*$bpp/8 - [ "$dht" <> "" - & VduExt_ModeFlags, Flag_DoubleVertical - & VduExt_ScrBRow, ($vpix/16)-1 - | - & VduExt_ScrBRow, ($vpix/8)-1 - ] - & VduExt_YWindLimit, $vpix-1 - & VduExt_ScreenSize, $hpix*$vpix*$bpp/8 - - & VduExt_XEigFactor, $multx - & VduExt_YEigFactor, $multy - MEND - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -; Start of multi sync archy modes - -; Mode 0, multiscan mode 0 -Multi100VIDCList - & 0 - & 0 - VIDC_List 0,72,63,88,640,88,73, 3,16,17,256,17,3,16000,0 - & -1 -Multi100WSList - & 0 - & 0 - & -1 - -; Mode 1, multiscan mode 1 -Multi101VIDCList - & 0 - & 1 - VIDC_List 1,36,33,44,320,44,35, 3,16,17,256,17,3,8000,0 - & -1 -Multi101WSList - & 0 - & 1 - & -1 - -; Mode 2, multiscan mode 2 -Multi102VIDCList - & 0 - & 2 - VIDC_List 2,36,33,44,320,44,35, 3,16,17,256,17,3,8000,0 - & -1 -Multi102WSList - & 0 - & 2 - & -1 - -; Mode 3, multiscan mode 3 -Multi103VIDCList - & 0 - & 3 - VIDC_List 1,72,63,88,640,88,73, 3,16,20,250,20,3,16000,0 - & -1 -Multi103WSList - & 0 - & 3 - & -1 - -; Mode 4, multiscan mode 4 -Multi104VIDCList - & 0 - & 4 - VIDC_List 0,72,63,88,640,88,73, 3,16,17,256,17,3,16000,0 - & -1 -Multi104WSList - & 0 - & 4 - & -1 - -; Mode 5, multiscan mode 5 -Multi105VIDCList - & 0 - & 5 - VIDC_List 1,36,51,24,320,24,57, 3,16,17,256,17,3,8000,0 - & -1 -Multi105WSList - & 0 - & 5 - & -1 - -; Mode 6, multiscan mode 6 -Multi106VIDCList - & 0 - & 6 - VIDC_List 1,36,33,44,320,44,35, 3,16,20,250,20,3,8000,0 - & -1 -Multi106WSList - & 0 - & 6 - & -1 - -; Mode 7, multiscan mode 7 -Multi107VIDCList - & 0 - & 7 - VIDC_List 2,36,31,44,320,44,37, 3,18,22,250,16,3,8000,0 - & -1 -Multi107WSList - & 0 - & 7 - & -1 - -; Mode 8, multiscan mode 8 -Multi108VIDCList - & 0 - & 8 - VIDC_List 1,72,63,88,640,88,73, 3,16,17,256,17,3,16000,0 - & -1 -Multi108WSList - & 0 - & 8 - & -1 - -; Mode 9, multiscan mode 9 -Multi109VIDCList - & 0 - & 9 - VIDC_List 2,36,33,44,320,44,35, 3,16,17,256,17,3,8000,0 - & -1 -Multi109WSList - & 0 - & 9 - & -1 - -; Mode 10, multiscan mode 10 -Multi110VIDCList - & 0 - & 10 - VIDC_List 3,36,33,44,320,44,35, 3,16,17,256,17,3,8000,0 - & -1 -Multi110WSList - & 0 - & 10 - & -1 - -; Mode 11, multiscan mode 11 -Multi111VIDCList - & 0 - & 11 - VIDC_List 1,72,63,88,640,88,73, 3,16,20,250,20,3,16000,0 - & -1 -Multi111WSList - & 0 - & 11 - & -1 - -; Mode 12, multiscan mode 12 -Multi112VIDCList - & 0 - & 12 - VIDC_List 2,72,63,88,640,88,73, 3,16,17,256,17,3,16000,0 - & -1 -Multi112WSList - & 0 - & 12 - & -1 - -; Mode 13, multiscan mode 13 -Multi113VIDCList - & 0 - & 13 - VIDC_List 3,36,33,44,320,44,35, 3,16,17,256,17,3,8000,0 - & -1 -Multi113WSList - & 0 - & 13 - & -1 - -; Mode 14, multiscan mode 14 -Multi114VIDCList - & 0 - & 14 - VIDC_List 2,72,63,88,640,88,73, 3,16,20,250,20,3,16000,0 - & -1 -Multi114WSList - & 0 - & 14 - & -1 - -; Mode 15, multiscan mode 15 -Multi115VIDCList - & 0 - & 15 - VIDC_List 3,72,63,88,640,88,73, 3,16,17,256,17,3,16000,0 - & -1 -Multi115WSList - & 0 - & 15 - & -1 - -; Mode 16, multiscan mode 16 -Multi116VIDCList - & 0 - & 16 - VIDC_List 2,112,47,132,1056,132,57, 3,16,17,256,17,3,24000,0 -; -; tv blanking! 112,139, 76,1056,114, 39, ,3,18,16,256,16,3 -; 4u67,5u79,3u2,44u,4u7,1u62, 21r 3r -; should be =10u4 =1u65 22r 3r(2r5) -;philips needs bprch > 57 or goes dark (sync at 112) -; can inc sync to 10u0, more and screen starts to wobble - & -1 -Multi116WSList - & 0 - & 16 - & -1 - -; Mode 17, multiscan mode 17 -Multi117VIDCList - & 0 - & 17 - VIDC_List 2,112,47,132,1056,132,57, 3,16,20,250,20,3,24000,0 - & -1 -Multi117WSList - & 0 - & 17 - & -1 - -; Mode 18, multiscan mode 18 -Multi118VIDCList - & 0 - & 18 - VIDC_List 0,56,111,2,640,2,85, 3,17,1,512,1,0,24000,0 - & -1 -Multi118WSList - & 0 - & 18 - & -1 - -; Mode 19, multiscan mode 19 -Multi119VIDCList - & 0 - & 19 - VIDC_List 1,56,111,2,640,2,85, 3,17,1,512,1,0,24000,0 - & -1 -Multi119WSList - & 0 - & 19 - & -1 - -; Mode 20, multiscan mode 20 -Multi120VIDCList - & 0 - & 20 - VIDC_List 2,56,111,2,640,2,85, 3,17,1,512,1,0,24000,0 - & -1 -Multi120WSList - & 0 - & 20 - & -1 - -; Mode 21, multiscan mode 21 -Multi121VIDCList - & 0 - & 21 - VIDC_List 3,56,111,2,640,2,85, 3,17,1,512,1,0,24000,0 - & -1 -Multi121WSList - & 0 - & 21 - & -1 - -; Mode 24, multiscan mode 24 -Multi124VIDCList - & 0 - & 24 - VIDC_List 3,112,47,132,1056,132,57, 3,16,17,256,17,3,24000,0 - & -1 -Multi124WSList - & 0 - & 24 - & -1 - - -; MODE 25 (VGA or multisync monitors, 640x480) -VGA1VIDCList - & 0 - & 18 - VIDC_List 0,96,47,0,640,0,15, 2,32,0,480,0,11,25175,3 - & -1 -VGA1WSList2 - & 0 - & 18 - & -1 - -; MODE 26 (VGA or multisync monitors, 640x480) -VGA2VIDCList - & 0 - & 19 - VIDC_List 1,96,47,0,640,0,15, 2,32,0,480,0,11,25175,3 - & -1 -VGA2WSList2 - & 0 - & 19 - & -1 - -; MODE 27 (VGA or multisync monitors, 640x480) -VGA4VIDCList - & 0 - & 20 - VIDC_List 2,96,47,0,640,0,15, 2,32,0,480,0,11,25175,3 - & -1 -VGA4WSList2 - & 0 - & 20 - & -1 - -; MODE 28 (VGA or multisync monitors, 640x480) -VGA8VIDCList - & 0 - & 21 - VIDC_List 3,96,47,0,640,0,15, 2,32,0,480,0,11,25175,3 - & -1 -VGA8WSList2 - & 0 - & 21 - & -1 - -; MODE 31 (800x600 by 4 bits per pixel) -sVGA4_VIDCList - & 0 - & 20 - VIDC_List 2,72,129,0,800,0,23, 2,22,0,600,0,1,36000,0 - & -1 -sVGA4_WSList - & 0 - & 20 - VIDC_WS 4,800,600,1,1 - & -1 - -; MODE 32 (800x600 by 8 bits per pixel) -sVGA8_VIDCList - & 0 - & 24 - VIDC_List 3,72,129,0,800,0,23, 2,22,0,600,0,1,36000,0 - & -1 -sVGA8_WSList - & 0 - & 24 - VIDC_WS 8,800,600,1,1 - & -1 - -; MODE 33 (768x288 by 8 bits per pixel) -Mode33VIDCList - - & 0 - & 15 - VIDC_List 3,74,127,0,768,0,55, 3,18,0,288,0,3,16000,0 - & -1 -Mode33WSList - & 0 - & 15 - VIDC_WS 8,768,288,1,2 - & -1 - -; MODE 34 (832x288 by 8 bits per pixel) -Mode34VIDCList - & 0 - & 15 - VIDC_List 3,74,87,0,832,0,31, 3,18,0,288,0,3,16000,0 - & -1 -Mode34WSList - & 0 - & 15 - VIDC_WS 8,832,288,1,2 - & -1 - - [ Debug - InsertDebugRoutines - ] - -; ***************************************************************************** -; -; Code to execute on reset -; -; in: R14 already stacked -; - -ResetCode ROUT - Push "R0-R6" - BL ModeExt_Init - Pull "R0-R6,PC" - -; ***************************************************************************** -; -; EventRoutine - Routine called on Vsync -; - -EventRoutine ROUT - TEQ R0, #Event_VSync - MOVNE PC, R14 - ENTRY "R0-R6" - LDR R1, [R12] ; load state flag, 0 => disabled - RSBS R1, R1, #0 ; change sign - EXIT EQ ; if zero then do nowt - - STR R1, [R12] ; store back - VDWS WsPtr - LDR R2, [WsPtr, #TotalScreenSize] ; needed later as well - ADDMI R1, R1, R2 ; if -ve then add TotalScreenSize - - STR R1, [WsPtr, #TeletextOffset] - -; now set VInit to this - - LDR R0, [WsPtr, #DisplayStart] - SUB R0, R0, #ScreenEndAdr - ADD R0, R0, R2 ; make start of screen 0 - ADD R0, R0, R1 ; add on teletext bank offset - CMP R0, R2 ; if out of range - SUBCS R0, R0, R2 ; then subtract total size -SetVinitPhys - MOV R1, #Vinit - STR R0, [WsPtr, #VinitCopy] - MOV R0, R0, LSR #4 ; bottom 4 bits not valid - ORR R0, R1, R0, LSL #2 ; OR in at correct place - STR R0, [R0] ; any old data will do - - LDR R0, [WsPtr, #VIDCControlCopy] - ORR R0, R0, #Interlace ; turn interlace on - STR R0, [WsPtr, #VIDCControlCopy] - MOV R1, #VIDC - STR R0, [R1] - - EXIT - -; ***************************************************************************** - -ModeChangeService - Push "R0-R6" - MOV R5, R12 ; our workspace pointer - VDWS WsPtr - MOV R6, #0 - LDR R0, [WsPtr, #DisplayModeNo] - TEQ R0, #18 - TEQNE R0, #19 - TEQNE R0, #20 - TEQNE R0, #21 - TEQNE R0, #26 - TEQNE R0, #27 - BNE %FT10 - MOV R0, #&A1 - MOV R1, #VduCMOS - SWI XOS_Byte - ANDS R2, R2, #MonitorTypeBits - BNE %FT10 - - MOV R0, #255 - STR R0, [WsPtr, #DisplayYWindLimit] - LDR R0, [WsPtr, #YEigFactor] - ADD R0, R0, #1 - STR R0, [WsPtr, #DisplayYEigFactor] - LDR R0, =541-6 - STR R0, [WsPtr, #CursorFudgeFactor] - - LDR R6, [WsPtr, #LineLength] - MOV R6, R6, LSR #1 - RSB R6, R6, #0 -10 - STR R6, [R5] - Pull "R0-R6, PC" - -; ***************************************************************************** -; -; ModeTranslation - Code to perform VGA mode number translation -; -; in: R1 = Service_ModeTranslation -; R2 = mode number -; R3 = monitor type -; return address stacked -; -; out: R1 = 0 if claimed -; R2 = substitute -; R3 preserved - -ModeTranslation ROUT - TEQ R3, #MonitorType_VGA - Pull PC, NE - BIC R1, R2, #&80 ; get rid of shadow bit - CMP R1, #32 ; if in range 32..39 - RSBCSS R1, R1, #39 - BCS %FT10 ; then don't modify - - [ {TRUE} - MOV R2, #0 - | - Push R0 - MOV R0, R2 - MOV R1, #9 ; log2bpp - SWI XOS_ReadModeVariable - Pull R0 - MOVVS R2, #0 ; if error or invalid then use mode 32 - MOVCS R2, #0 - CMP R2, #4 - MOVCS R2, #3 - ADD R2, R2, #32 - ] -10 - MOV R1, #0 ; claim service - Pull PC - - END - diff --git a/Resources/UK/CmdHelp b/Resources/UK/CmdHelp deleted file mode 100644 index dbd61b6e5ce445463e08756c9869e3f694014f66..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10566 zcmds7-*X$c5sn_|e?bq$I5UmSP>PfEp=B7&P!uU~B#H`;a_rG)I;SH@U39!-?}sEd z&i~$TcL5wIQ;FU5shy7E!{M-t#kafPF8JchUytIboMv}AEq;4(aycFK#^>#3FH7g~ zqRO@E#HC&ysH@H@%)_NFb$)QI3SAbeyw$2V8V7399jR<p##vhI@9s2%GAye?&EjH} zglm}>Re7${(wjEKvW1G5t3)sHM$c57s%18-5?!b;*X=J@o6-2F-5i<WBrc3xJJGD0 ztW}bQGd*jmMSLHp3sx?LzA8*-DxA%7T@)&t^SFH6l2=KQ@t`*+hLDFWzbjT@q_Lww zV;P#)oQy|C7YsYCSTgIpyR*9^diTbo_GK9-ak*Aewp>DuqHSLef?j)ochECf7cj)f zQ$|N^SzpD4F-33G?wOU;D$nj??AKe;u2?*?V(%26%c+KRR_ac#u}e>_lhgLFRJUQF zZgsL!S<0)w`0`hV$D1Dya~<9ZNDe2b?J3TmhiE0GW8fiIz{fI9!xD#BhQ(dcQdzEE zJ>aG4O($pc6r2nP)7L7DVCE#g(`^2U2By?aRhC%_+x~p3Qzc_@f!*Tt=x_;g^DIfS z2eKW+Le=n|4q55>Tt_7|=H*osRs{hmRbf?TH(6GyS5*pZ73z>4uxey6K6?#`SZo!} z_L}xf5>-?yo!`d=lrA%Mqg7s|Di39&w^*Ad)yt?POczzS*u=~U+43TL(D^vs|Dv{L z4+|{x(Hba?qb^Kq-0!Fh_j~#d_`{~fmx}n`+Cq7r!KtD!y45XZ4!&6Ba9M(5*kad& zBStObT0G3aFQQz-#!J1-^0nC>9YM8%k^#j5C=#sGGJI^SEec)j4In!pT{`K()#-=P zhvVyOb+s3;{4Fmg;c^gc8y|JIj0UXV(-)ro`q6DBChPZ3+D&>yT!NdaP!(m)K|oyl z?a?KieGX`<G7r;Yp5;q%ft$5D4kkLBk(b-O@=6_9;=mV}=UHwfP9~5@&uXDl4M+&q zG!HS_2^xq+FmYNfZy=fiQK=tGW8OZNs73O3R~?y(0NbIN8^Z6y#K?Yo2HAL28h<J) zIz|j#KnzqeyVsBGH*j_AZVGkk0VoqD>jKls+ey{ht1@6dEVG=#)z^(i1A#H-cu}tm z$VZS1H^<_;J9{nFY^iTr3c<S3aEkCcloWP%er%~uOC8`Z{&hf42MwboR<&OsP9n*` z-LU2XP419*p!pVgCyrEc8_!FX$BWyNt(oX~Niz>HEy)&f1e<tsaHP{oOTF!$H5$<P zUgrgcy&GLV5b{Mng$PPLY&>Y%JwIxxF+S_lpY!pw@#-cnAL2s4Mv4&`&O*C8li~5n zw587agK48tR5#A_09qv0IqRR3emY$s1|kDlbW*N3#H>5Yr4a=xN-+pB2wXD@5}b7n z5<2rveTY6hj>mzZ1OI3@@kdck%}u~?VQgPr7Fsobs^XGdUO&bbj`W?Aga;4z!+|V4 z9JHIm0mVB31VR$R{-cg6L4O7u<u;S4nO?ye$qQj~LKuOS;}!+$8k!Ppu(p#98U8NS z^rU~TIwpyNiS*Bce*JvyYr06YTpMkVL1TtIP}3EJCNhhPWjwkCr-?9N%ss?6wHh*~ zc1ll>N&UZZpd^aozA|sTxhC|BRu|)++nn3TB1^>WIMtMk3d9Tq@fnQuX<2UK=P3as z*;;bIS4B<COyZ*SiZF20KkHBX_FJ4FAB|Du`Ol{8CB5;*drBaxh?j8^a#Eb|8(FqR z`J0T*i)O1;R!}DL5@fMXBWUr4!1oUe49UC-IUZlW`lTw$*SvuD-7-sKgd|n2S9)Ka za;jD{q;Y&A7~hyY<7}8ltegKW$?bv<K!=*tae@}EL9w98&rECp3rBu<f*j(cAIKrf zNB^$`Wisj|Iy4y%5ACKIfo~@$1Q0rbpIj#yl0kTr0MLe~&+}}_M>rXEjcd{O&PmKV zzI8|av_QFG3_R+SFd0(ti|CF{IYijEJjNKEY6=eEf&xjnCekzYqz`~tXr}WNhy#44 za6J=E$n{JFLlU6s00a1c3TTmsMq#1d2KxR6jBXv-av7J2K2RN-V@w`L)zq|c%a2o& z(I5ovccw*PwL{SKo-Awk$)-fvLC8g&<&^Q_rTcV4nGNF(Q{?*68h1$IWC+JcIzu9D zS2#2!spe(6N~(o;^en@BGD)su_+cEP4ina1taKF5W5g{|QEcH<9QyV$;x<&IqLL9~ zDAK{EjZWjlP@c)?lvJhxb%#Hav>gh!V9+UX>MOwuY^bndr85+A)<)o1lMxMYVQE={ z-8>!8$G~?&y`*gx>C9s=0Mw&?(w>YadI*DBnc$RmXv5UorL{1J@rJNZhbMf)J3In( zxI(3ftOvH{wDWkU6ZgDPCRJ+mn;@a$11f>4bh}Pg2Bvz>PM<tufN4Bi+wD(jc^V+^ zMColJJ7NgCxDP%^x2a1)jukwb`hsaO|AbxjZbYI+_ey#cqqe>9@!5i+Necs<2aO8A z9VJDQ!S<Hz$3(oT^Rba!Mw|LUVr>|wj;CXw4IF|#?13j076s@E+1rpyAySA37?E24 z9weCp@V*)Y36dtc+aXhlT!L51Lhx1AnAYYhf^!}oMq!j^#*QT1=}Ag-AcEmb{{oNm zVQdx>n+8*aZoBkGfl_lmK2EzWVWNL}E4(HNmTm0ryp%jnTYQOxg>pB(v0=`!PZ*F2 zT)S)N?(dq-<L$iO!ISN?OuK(z%Bta=9Vk|w84movI6AjqQqt+~q08yuZQ$dhyUiYq z-X~+|jYs1JPmooBtb(9&QH@wbP>||Yk}RC@qYn^$(oAL|qq<D7uihH8O4S2k766#T zBx*^h&ZggrOz2sk5$StH8)W#CjEx*3ok)8y=&P94WP$G_;}u{sC;(<PU$%`*sg!!Q zM@0FT^rT2@r%34%Ouasd5pdO!Ih)!r){HjqDMBu9GUPI<_b8?a77bRVor)5?a{$xl zcM#6?B-G|25&0zH&ss|FFZR9oilt^Kg}DPKl*#5E6vtVW%qSM1v$aYnZzEh#yXxv% zq=?#7M;mc?_rY5+1RKlZ2>hC*zU+QDe2E?snkwpLmwFF}F9AkJny2y7P`c?5enF3$ zec_Tu=$vPDhN7wNi0Kn=L7^pL!^`uFw&5uVjoHelfHfV#ZV9zDaiLz1{ftoul!p1D zqAs+T0xBjz3z(>0t1ym6lAVU45@5JN1wW!TKDW699W!D6@*MR#Ki91KsV_OHUWqQB zIN$!_MQ!x%iYjlhQTGBik^#ULJ$@LQ%KoAxqYyCI`qa75|Ek0SDZ(TuAj-0vEX)a- zE0lFq_km4dWtapQjLVjJBL)VYmBugdwO0M0*S+W)#YqWgE~Cs=K5$sYiBbIU5-gRU zt==lt51*~^EY8KhKTl(l?lcxHwkq69vcdqocZLAU&nlu(p(tcwSkrWh%_Rs1>ssB| zh(31`c^MD&J@j%*D`$cPD+3^ap!HNP@J$7Jcu4&wI?vcth|U~HxK(3rMv!pnu7uBB zY9H!~nd=W-?5p#PyfLIYNZO_7YRZ|@;<TfEbtdgB@?7^NLj-Z`RzKn@CW@CXG4-Hx zy*b{DAF!@E;Kt~V(Jd2c#7okH=!wglgX?SGe~!5R6ojMo&~C~A)Qw>b9JQ1N9~mRp zWtFF7d-4MAxpL7byFx<&UsIjK4q^_5)_1xaIa{%CR4rFVr4gKt9yenhS`_G+g4LR9 zDDgfbcCZ*9M>psVhiZl|rAp-)*?dlkhfEEAnd4vPHj6xRtGSOLzgC&_s1=4)y;aG` z8;iow9`5=$4B1lu9Z*M){!-#x5_X@qpy(9J5SKgiDrZhAQN(oyq*7-vAsq9{HW<?& z6AW{QL#Sg|u;N%3`HNl5bxEO|+b=IAn`FZ3?`QB%b~AX_ZVuj|x~Ecd9Q^Ze?aCv( za!X-K{zhG0wXRkEt@-bF8wNTa%Yw)7{o^r=Y0d^6{Hq_(g1wLPETzP9t@hLc7D1{p zr}xTplh-XEb{<wqss8%+H*enH^wIt|R~BFW@D;Zy>cvbU0D!tgOFb)5<>U<D;}%v2 zQT-Q0zv4iJB`z6PR8VD1+lX__s|4_=??OzFa*PNWHI5Jt0;=)B2#^o>x)2{lNj1~p zCOvZ<**HT&aV1%JAEG-*{h;c}1?cY10B5`XD;#be6!#2WjBKL@oq1D9HAEPJLK3dx z<_jjsxiuR7N8CHZF=$G`oC^%4C~z-F5fVJsvm088Vz$%%`*ssgMDhgD^D1S=#n+4` z7|<*S51QS9RqAGs@M|A&WEc@}7NDMEJ8fQ!Zwm@Wd9SA_w^T;|ebq<j7+ghq$GGK* zG-YLWpiss|sf|+ff|}nPN19XWqY8Z`z1)^qKiur$lyC<{{w77=)!sC`fn5=VHg@M4 zCTDa_&+QWH#g6bh#8WgE)6$}npnyy;353Ll)MO=bk9{?yn-Z4*=-zh2W5^|(2rv<< zAW(%MG#EOK{u-|J%pUy?J!|Rj%}+BPG{!4)a^nk}9G-y1w9JXIQ^AqpCk`8!H4PXl z|7r5KbS<g^Q!;GMv~Wz&z)93A%G;#XHv#UlzmeSj8t&D2(?BlX`YGVv__i^yky7q8 zW*Gd=4Ys@hW6uEjjq-@3TU@KtZ3un!ef<>?aijz!jcqe&XMg*ho$*C`#+<`#fXD1@ z7_=6g@F@1CS?MPAi2R}N8<G^<n4Bb?g+nVTbJcl75~C2^S#KsUhP(LQ#ROzh;Qy@i zh0JV-yV4~xg(6K(c7xQwxeUPs_sAO#B~cId^!<rsISoZ-4K@#6bO$He{X|rkujJ5f zCpJfc%l=>nlslnn4jj#ZnWj4d^qIHl1h@J3wu#=S?iLUH0Wsphk%8m?H~eS<F-{#L zZtI2#+_K@I`xd1*{ca;djxie+LO{P-AbwQ;EP;$s$BWNpo+Qd?$0BRplt+EgyT_@s zoBS>d-QD>M{SOW+8+dNDuhpk;TJPk7+i+I*VyIQY1E|XHU?8tPL(+rY`1c{)I$*TO z)vNhQ$4!{t8LR{+es6+T^kuHH%yig;3$W;bp8c?ID#p#q%dj#}CHRE`e5gtkcJ{RD zGDO7sk;Qg%{;0kuQcF!!7?j1^{6V3C&fVTsayI7~^u`F<pn<f9`mA~CGdz$bjZI%W zxS-A#O&|MhYFl=0E0;gP1W!xl&oBYh_%lZE>PWk*XUs5tEB-izJ5Jvsl;S!8zq0_> z<C|NA92;8s);z(l;SgeLhGb{ig2u#FTkZ-R4H6;4oegBAT7wJlJ@9wR{j!kyD~{3< kM=|=n2c@OQPpGH<h&uTfzjgfPIBhkBv|3e?`iF$*Kg@Ceg#Z8m diff --git a/Resources/UK/Messages b/Resources/UK/Messages deleted file mode 100644 index 4b3c6cc5..00000000 --- a/Resources/UK/Messages +++ /dev/null @@ -1,179 +0,0 @@ -BadNumb:Number not recognised -NoSuchSWI1:SWI &%0 not known -VarCantFind:System variable '%0' not found -BuffOverflow:Buffer overflow -Escape:Escape -Syntax:Syntax -OptErr:Syntax: *Opt [<x> [[,] <y>]] -NoHelp:No help found. -HelpFound:==> Help on keyword %0 -Address:Address : -ASCII:ASCII data -Unp:Unplugged modules are: -NoUnp:No modules are unplugged -Podule:(Podule %0) -Extn:(Extn ROM %0) -Modules:No. Position Workspace Name -Number:(Number) -Macro:(Macro) -Result:Result is %0, value : -Integer:an integer -String:a string -ROMMTitle:No. Position|IModule Name|I|IVersion|IStatus|M|J -SYSROM:System ROM -EXTROM:Extn ROM -PODROM:Podule -Active:Active -Dormant:Dormant -Unplugged:Unplugged -Running:Running -Untitled:<Untitled> -Supervisor:Supervisor -ErrSub:E -YesNo:yn -Config:Configuration -Options:options: -Status:status: -Err: (Error number &%0) -Error:Error: %0 (Error number &%1) -UndefinedInstruction:Internal error: undefined instruction at &%0 -InstructionAbort:Internal error: abort on instruction fetch at &%0 -DataAbort:Internal error: abort on data transfer at &%0 -AddressException:Internal error: address exception at &%0 -BranchThrough0:Internal error: branch through zero -SDoesntExist:Sprite doesn't exist -ModuleTooOld:Module %0 too old -NaffRelease:Bad vector release -RMNotFound:Module %0 not found -NaffDevNo:Bad device number -BadDevVecRel:Bad device release -RedirectFail:Redirection fails -StackFull:Not enough memory on system stack -OscliLongLine:Too long -NoOscliSpecials:Special field not allowed in filing system prefix to OS_CLI -OscliTooHard:Expansion too complex -BadCommand:Command not recognised -BadParmString:Parameter expansion contains unrecognised characters -TooManyParms:Too many parameters -BadKey:Key number must be in the range 0-15 -BadAddress:Address not recognised -OutsideFile:Outside file -NotABlock:Not a heap block -BadDesc:Bad heap descriptor -HeapBadReason:Bad reason code -HeapFailInit:Can't initialise heap -BadLink:Heap overwritten -HeapFailAlloc:Not enough memory (in heap) -BadExtend:Not enough memory (to extend heap) -ExcessiveShrink:Can't shrink heap any further -BadModuleReason:Unknown OS_Module call -CantKill:Module is currently active -MHNoRoom:The area of memory reserved for relocatable modules is full -NoMoreModules:No more modules -NoMoreIncarnations:No more incarnations of that module -PostfixNeeded:Postfix not specified -IncarnationExists:Incarnation already exists -ChunkNotRM:Podule chunk is not a relocatable module -ModulePostfix:'%%' in module title -NotMod:This is not a relocatable module -BadRMHeaderField:Illegal header field in module -RMNot32bit:Module '%0' is not 32-bit compatible -IncarnationNotFound:Incarnation not found -RMNotFoundInROM:Module is not in ROM -NumbTooBig:Number too big -BadBase:Base not recognised -BadClaimNum:Bad vector number -SysHeapFull:The area of memory reserved for the system heap is full -NotAllMoved:Memory cannot be moved -ChDynamCAO:Can't change memory area (application running) -AplWSpaceInUse:Application memory area in use -RAMFsUnchangeable:The size of the RAM filing system can only be changed when it is empty -BadDynamicArea:Unknown dynamic area -AreaAlreadyExists:Dynamic area already exists -AreaNotOnPageBdy:Base address not on page boundary -OverlappingAreas:Overlapping areas -CantAllocateArea:Unable to allocate logical address space -CantAllocateLevel2:Unable to allocate page tables for area -UnknownAreaHandler:Unknown dynamic area handler call -RCExc:Return code limit exceeded -RCNegative:Negative return code -BadString:String not recognised -BadVarType:Bad variable type -VarNoRoom:The area of memory reserved for the system variables is full. Use the Task Manager to make more space in the system heap/stack area. -BadMacVal:Bad macro value -BadVarNam:Variable name not recognised -VarTooLong:Variable value too long -BadParameters:Parameters not recognised -ArgRepeated:Argument repeated -BadBra:Mismatched brackets -StkOFlo:Expression stack overflow -MissOpn:Missing operand -MissOpr:Missing operator -BadInt:String is not convertible to integer -StrOFlo:String too long -NaffItm:Unknown operand -DivZero:Division by zero -NotNumeric:Numeric parameter needed -NoThen:There is no THEN -IsString:Expression is a string -ConParmTooBig:Configure parameter too big -BadConOpt:Configure option not recognised -BadStat:Status option not recognised -Config2manyparms:Too many parameters -NoSuchSWI2:SWI name not known -BadTime:Invalid time interval -BadEnvNumber:Bad Environment number -BadReadSysInfo:Unknown OS_ReadSysInfo call -BadMODE:Not enough memory to change to this screen mode -SNoWorkSpace:No memory is reserved for the system sprite area. Use the Task Manager to make some space for the system sprites. -SNoRoom:Not enough memory to create sprite -NoSprites:No sprites -NotGraphics:Not a graphics mode -SCantOpenFile:Can't open file -SNotEnoughRoom:Not enough memory in sprite area -SBadSpriteFile:Bad sprite file -SNoRoomToMerge:Not enough memory to add sprite -SBad2ndPtr:Bad 2nd ptr -InvalidRowOrCol:Invalid row or column -InvalidHeight:Invalid height -InvalidWidth:Invalid width -NoRoomToInsert:Not enough memory to insert row or column -SpriteAlreadyExists:Sprite already exists -InvalidSpriteMode:Invalid sprite mode -SBadReasonCode:Bad sprite reason code -CantInTeletext:Can't switch output in teletext mode -SInvalidSaveArea:Invalid save area -SpriteIsCurrentDest:Sprite is current destination -BadDPI:Illegal XDPI or YDPI in sprite -ModeNotAvailable:Screen mode not available -BadPixelDepth:Bad pixel depth -BadMSFlags:Illegal flags in mode selector -CDATStackOverflow:System stack overflow -NoSuchSWI:SWI not known -BadSav:Incorrect number of parameters for *Save -MonType:Monitor type reconfigured. -NoKbd:No keyboard present - autobooting -BreakPt:Stopped at break point at &%0 -STail:|J|MUse *Configure to set the options.|J|M -CTail1:|J|MWhere:|J|MD is a decimal number, a hexadecimal number preceded by &,|J|Mor the base followed by underscore, followed|J|M -CTail2:by digits in the given base.|J|MItems within [ ] are optional.|J|MUse *Status to display the current settings.|J|M -Zonk:Unknown OS_ScreenMode reason code -SNoMask:Mask or Palette operations not supported in this display depth -BadVIDCDiv:Bad VIDC divider value -BadPlatReas:Unknown OS_PlatformFeatures reason code - -600:ARM 600 Processor -610:ARM 610 Processor -700:ARM 700 Processor -710:ARM 710 Processor -710a:ARM 710a Processor -SA110:SA-110 Processor -7500:ARM 7500 Processor -7500FE:ARM 7500FE Processor -SA1100:SA-1100 Processor -SA1110:SA-1110 Processor -720T:ARM 720T Processor -920T:ARM 920T Processor -922T:ARM 922T Processor -X80200:80200 Processor -X80321:80321 Processor diff --git a/Resources/UK/Morris4/Messages b/Resources/UK/Morris4/Messages deleted file mode 100644 index c1c9f430..00000000 --- a/Resources/UK/Morris4/Messages +++ /dev/null @@ -1,172 +0,0 @@ -BadNumb:Number not recognised -NoSuchSWI1:SWI &%0 not known -VarCantFind:System variable '%0' not found -BuffOverflow:Buffer overflow -Escape:Escape -Syntax:Syntax -OptErr:Syntax: *Opt [<x> [[,] <y>]] -NoHelp:No help found. -HelpFound:==> Help on keyword %0 -Address:Address : -ASCII:ASCII data -Unp:Unplugged modules are: -NoUnp:No modules are unplugged -Podule:(Podule %0) -Extn:(Extn ROM %0) -Modules:No. Position Workspace Name -Number:(Number) -Macro:(Macro) -Result:Result is %0, value : -Integer:an integer -String:a string -ROMMTitle:No. Position|IModule Name|I|IVersion|IStatus|M|J -SYSROM:System ROM -EXTROM:Extn ROM -PODROM:Podule -Active:Active -Dormant:Dormant -Unplugged:Unplugged -Running:Running -Untitled:<Untitled> -Supervisor:Supervisor -ErrSub:E -YesNo:yn -Config:Configuration -Options:options: -Status:status: -Err: (Error number &%0) -Error:Error: %0 (Error number &%1) -UndefinedInstruction:Internal error: undefined instruction at &%0 -InstructionAbort:Internal error: abort on instruction fetch at &%0 -DataAbort:Internal error: abort on data transfer at &%0 -AddressException:Internal error: address exception at &%0 -BranchThrough0:Internal error: branch through zero -SDoesntExist:Sprite doesn't exist -ModuleTooOld:Module %0 too old -NaffRelease:Bad vector release -RMNotFound:Module %0 not found -NaffDevNo:Bad device number -BadDevVecRel:Bad device release -RedirectFail:Redirection fails -StackFull:Not enough memory on system stack -OscliLongLine:Too long -NoOscliSpecials:Special field not allowed in filing system prefix to OS_CLI -OscliTooHard:Expansion too complex -BadCommand:Command not recognised -BadParmString:Parameter expansion contains unrecognised characters -TooManyParms:Too many parameters -BadKey:Key number must be in the range 0-15 -BadAddress:Address not recognised -OutsideFile:Outside file -NotABlock:Not a heap block -BadDesc:Bad heap descriptor -HeapBadReason:Bad reason code -HeapFailInit:Can't initialise heap -BadLink:Heap overwritten -HeapFailAlloc:Not enough memory (in heap) -BadExtend:Not enough memory (to extend heap) -ExcessiveShrink:Can't shrink heap any further -BadModuleReason:Unknown OS_Module call -CantKill:Module is currently active -MHNoRoom:The area of memory reserved for relocatable modules is full. Quit any unwanted applications or see the RISC OS User Guide for ways to maximise memory. -NoMoreModules:No more modules -NoMoreIncarnations:No more incarnations of that module -PostfixNeeded:Postfix not specified -IncarnationExists:Incarnation already exists -ChunkNotRM:Podule chunk is not a relocatable module -ModulePostfix:'%%' in module title -NotMod:This is not a relocatable module -BadRMHeaderField:Illegal header field in module -RMNot32bit:Module '%0' is not 32-bit compatible -IncarnationNotFound:Incarnation not found -RMNotFoundInROM:Module is not in ROM -NumbTooBig:Number too big -BadBase:Base not recognised -BadClaimNum:Bad vector number -SysHeapFull:The area of memory reserved for the system heap is full. Quit any unwanted applications or see the RISC OS User Guide for ways to maximise memory. -NotAllMoved:There is not enough memory to perform this operation. Quit any unwanted applications or see the RISC OS User Guide for ways to maximise memory. (Memory cannot be moved) -ChDynamCAO:Can't change memory area (application running) -AplWSpaceInUse:Application memory area in use -RAMFsUnchangeable:The size of the RAM filing system can only be changed when it is empty -BadDynamicArea:Unknown dynamic area -AreaAlreadyExists:Dynamic area already exists -AreaNotOnPageBdy:Base address not on page boundary -OverlappingAreas:Overlapping areas -CantAllocateArea:Unable to allocate logical address space -CantAllocateLevel2:Unable to allocate page tables for area -UnknownAreaHandler:Unknown dynamic area handler call -RCExc:Return code limit exceeded -RCNegative:Negative return code -BadString:String not recognised -BadVarType:Bad variable type -VarNoRoom:The area of memory reserved for the system variables is full. Use the Task Manager to make more space in the system heap/stack area. -BadMacVal:Bad macro value -BadVarNam:Variable name not recognised -VarTooLong:Variable value too long -BadParameters:Parameters not recognised -ArgRepeated:Argument repeated -BadBra:Mismatched brackets -StkOFlo:Expression stack overflow -MissOpn:Missing operand -MissOpr:Missing operator -BadInt:String is not convertible to integer -StrOFlo:String too long -NaffItm:Unknown operand -DivZero:Division by zero -NotNumeric:Numeric parameter needed -NoThen:There is no THEN -IsString:Expression is a string -ConParmTooBig:Configure parameter too big -BadConOpt:Configure option not recognised -BadStat:Status option not recognised -Config2manyparms:Too many parameters -NoSuchSWI2:SWI name not known -BadTime:Invalid time interval -BadEnvNumber:Bad Environment number -BadReadSysInfo:Unknown OS_ReadSysInfo call -BadMODE:Not enough memory to change to this screen mode -SNoWorkSpace:No memory is reserved for the system sprite area. Use the Task Manager to make some space for the system sprites. -SNoRoom:Not enough memory to create sprite -NoSprites:No sprites -NotGraphics:Not a graphics mode -SCantOpenFile:Can't open file -SNotEnoughRoom:Not enough memory in sprite area -SBadSpriteFile:Bad sprite file -SNoRoomToMerge:Not enough memory to add sprite -SBad2ndPtr:Bad 2nd ptr -InvalidRowOrCol:Invalid row or column -InvalidHeight:Invalid height -InvalidWidth:Invalid width -NoRoomToInsert:Not enough memory to insert row or column -SpriteAlreadyExists:Sprite already exists -InvalidSpriteMode:Invalid sprite mode -SBadReasonCode:Bad sprite reason code -CantInTeletext:Can't switch output in teletext mode -SInvalidSaveArea:Invalid save area -SpriteIsCurrentDest:Sprite is current destination -BadDPI:Illegal XDPI or YDPI in sprite -ModeNotAvailable:Screen mode not available -BadPixelDepth:Bad pixel depth -BadMSFlags:Illegal flags in mode selector -CDATStackOverflow:System stack overflow -NoSuchSWI:SWI not known -BadSav:Incorrect number of parameters for *Save -MonType:Monitor type reconfigured. -NoKbd:No keyboard present - autobooting -BreakPt:Stopped at break point at &%0 -STail:|J|MUse *Configure to set the options.|J|M -CTail1:|J|MWhere:|J|MD is a decimal number, a hexadecimal number preceded by &,|J|Mor the base followed by underscore, followed|J|M -CTail2:by digits in the given base.|J|MItems within [ ] are optional.|J|MUse *Status to display the current settings.|J|M -Zonk:Unknown OS_ScreenMode reason code -SNoMask:Mask or Palette operations not supported in this display depth -BadVIDCDiv:Bad VIDC divider value -BadPlatReas:Unknown OS_PlatformFeatures reason code - -600:ARM 600 Processor -610:ARM 610 Processor -700:ARM 700 Processor -710:ARM 710 Processor -7500:ARM 7500 Processor -7500FE:ARM 7500FE Processor -810:ARM 810 Processor -SA110:StrongARM Processor diff --git a/Resources/UK/Omega/Messages b/Resources/UK/Omega/Messages deleted file mode 100644 index ee631fc0..00000000 --- a/Resources/UK/Omega/Messages +++ /dev/null @@ -1,172 +0,0 @@ -Escape:Escape -Syntax:Syntax -OptErr:Syntax: *Opt [<x> [[,] <y>]] -NoHelp:No help found. -HelpFound:==> Help on keyword %0 -Address:Address : -ASCII:ASCII data -Unp:Unplugged modules are: -NoUnp:No modules are unplugged -Podule:(Podule %0) -Extn:(Extn ROM %0) -Modules:No. Position Workspace Name -Number:(Number) -Macro:(Macro) -Result:Result is %0, value : -Integer:an integer -String:a string -ROMMTitle:No. Position|IModule Name|I|IVersion|IStatus|M|J -SYSROM:System ROM -EXTROM:Extn ROM -PODROM:Podule -Active:Active -Dormant:Dormant -Unplugged:Unplugged -Running:Running -Untitled:<Untitled> -Supervisor:Supervisor -ErrSub:E -YesNo:yn -Config:Configuration -Options:options: -Status:status: -Err: (Error number &%0) -Error:Error: %0 (Error number &%1) -UndefinedInstruction:The Network Computer has experienced a technical difficulty and needs to be rebooted (100:%0). Contact your service provider. -InstructionAbort:The Network Computer has experienced a technical difficulty and needs to be rebooted (101:%0). Contact your service provider. -DataAbort:The Network Computer has experienced a technical difficulty and needs to be rebooted (102:%0). Contact your service provider. -AddressException:The Network Computer has experienced a technical difficulty and needs to be rebooted (103:%0). Contact your service provider. -BranchThrough0:The Network Computer has experienced a technical difficulty and needs to be rebooted (105:%0). Contact your service provider. -NoSuchSWI1:The Network Computer has experienced a technical difficulty (1E8:%0). Please select Continue. -SDoesntExist:Sprite doesn't exist -VarCantFind:System variable '%0' not found -BuffOverflow:Buffer overflow -BadNumb:Number not recognised -ModuleTooOld:Module %0 too old -NaffRelease:Bad vector release -RMNotFound:Module %0 not found -NaffDevNo:Bad device number -BadDevVecRel:Bad device release -RedirectFail:Redirection fails -StackFull:Not enough memory on system stack -OscliLongLine:Too long -NoOscliSpecials:Special field not allowed in filing system prefix to OS_CLI -OscliTooHard:Expansion too complex -BadCommand:Command not recognised -BadParmString:Parameter expansion contains unrecognised characters -TooManyParms:Too many parameters -BadKey:Key number must be in the range 0-15 -BadAddress:Address not recognised -OutsideFile:Outside file -NotABlock:Not a heap block -BadDesc:Bad heap descriptor -HeapBadReason:Bad reason code -HeapFailInit:Can't initialise heap -BadLink:Heap overwritten -HeapFailAlloc:Not enough memory (in heap) -BadExtend:Not enough memory (to extend heap) -ExcessiveShrink:Can't shrink heap any further -BadModuleReason:Unknown OS_Module call -CantKill:Module is currently active -MHNoRoom:The Network Computer has experienced a technical difficulty (101). Please select Continue. -NoMoreModules:No more modules -NoMoreIncarnations:No more incarnations of that module -PostfixNeeded:Postfix not specified -IncarnationExists:Incarnation already exists -ChunkNotRM:Podule chunk is not a relocatable module -ModulePostfix:'%%' in module title -NotMod:This is not a relocatable module -BadRMHeaderField:Illegal header field in module -RMNot32bit:Module '%0' is not 32-bit compatible -IncarnationNotFound:Incarnation not found -RMNotFoundInROM:Module is not in ROM -NumbTooBig:Number too big -BadBase:Base not recognised -BadClaimNum:Bad vector number -SysHeapFull:The Network Computer has experienced a technical difficulty (1E4). Please select Continue. -NotAllMoved:The Network Computer has experienced a technical difficulty (1C1). Please select Continue. -ChDynamCAO:Can't change memory area (application running) -AplWSpaceInUse:Application memory area in use -RAMFsUnchangeable:The size of the RAM filing system can only be changed when it is empty -BadDynamicArea:Unknown dynamic area -AreaAlreadyExists:Dynamic area already exists -AreaNotOnPageBdy:Base address not on page boundary -OverlappingAreas:Overlapping areas -CantAllocateArea:Unable to allocate logical address space -CantAllocateLevel2:Unable to allocate page tables for area -UnknownAreaHandler:Unknown dynamic area handler call -RCExc:Return code limit exceeded -RCNegative:Negative return code -BadString:String not recognised -BadVarType:Bad variable type -VarNoRoom:The area of memory reserved for the system variables is full. Use the Task Manager to make more space in the system heap/stack area. -BadMacVal:Bad macro value -BadVarNam:Variable name not recognised -VarTooLong:Variable value too long -BadParameters:Parameters not recognised -ArgRepeated:Argument repeated -BadBra:Mismatched brackets -StkOFlo:Expression stack overflow -MissOpn:Missing operand -MissOpr:Missing operator -BadInt:String is not convertible to integer -StrOFlo:String too long -NaffItm:Unknown operand -DivZero:Division by zero -NotNumeric:Numeric parameter needed -NoThen:There is no THEN -IsString:Expression is a string -ConParmTooBig:Configure parameter too big -BadConOpt:Configure option not recognised -BadStat:Status option not recognised -Config2manyparms:Too many parameters -NoSuchSWI2:SWI name not known -BadTime:Invalid time interval -BadEnvNumber:Bad Environment number -BadReadSysInfo:Unknown OS_ReadSysInfo call -BadMODE:Not enough memory to change to this screen mode -SNoWorkSpace:No memory is reserved for the system sprite area. Use the Task Manager to make some space for the system sprites. -SNoRoom:Not enough memory to create sprite -NoSprites:No sprites -NotGraphics:Not a graphics mode -SCantOpenFile:Can't open file -SNotEnoughRoom:Not enough memory in sprite area -SBadSpriteFile:Bad sprite file -SNoRoomToMerge:Not enough memory to add sprite -SBad2ndPtr:Bad 2nd ptr -InvalidRowOrCol:Invalid row or column -InvalidHeight:Invalid height -InvalidWidth:Invalid width -NoRoomToInsert:Not enough memory to insert row or column -SpriteAlreadyExists:Sprite already exists -InvalidSpriteMode:Invalid sprite mode -SBadReasonCode:Bad sprite reason code -CantInTeletext:Can't switch output in teletext mode -SInvalidSaveArea:Invalid save area -SpriteIsCurrentDest:Sprite is current destination -BadDPI:Illegal XDPI or YDPI in sprite -ModeNotAvailable:Screen mode not available -BadPixelDepth:Bad pixel depth -BadMSFlags:Illegal flags in mode selector -CDATStackOverflow:System stack overflow -NoSuchSWI:SWI not known -BadSav:Incorrect number of parameters for *Save -MonType:Monitor type reconfigured. -NoKbd:No keyboard present - autobooting -BreakPt:Stopped at break point at &%0 -STail:|J|MUse *Configure to set the options.|J|M -CTail1:|J|MWhere:|J|MD is a decimal number, a hexadecimal number preceded by &,|J|Mor the base followed by underscore, followed|J|M -CTail2:by digits in the given base.|J|MItems within [ ] are optional.|J|MUse *Status to display the current settings.|J|M -Zonk:Unknown OS_ScreenMode reason code -SNoMask:Mask or Palette operations not supported in this display depth -BadVIDCDiv:Bad VIDC divider value -BadPlatReas:Unknown OS_PlatformFeatures reason code - -600:ARM 600 Processor -610:ARM 610 Processor -700:ARM 700 Processor -710:ARM 710 Processor -7500:ARM 7500 Processor -7500FE:ARM 7500FE Processor -810:ARM 810 Processor -SA110:StrongARM Processor diff --git a/Resources/UK/Ursula/Messages b/Resources/UK/Ursula/Messages deleted file mode 100644 index c1c9f430..00000000 --- a/Resources/UK/Ursula/Messages +++ /dev/null @@ -1,172 +0,0 @@ -BadNumb:Number not recognised -NoSuchSWI1:SWI &%0 not known -VarCantFind:System variable '%0' not found -BuffOverflow:Buffer overflow -Escape:Escape -Syntax:Syntax -OptErr:Syntax: *Opt [<x> [[,] <y>]] -NoHelp:No help found. -HelpFound:==> Help on keyword %0 -Address:Address : -ASCII:ASCII data -Unp:Unplugged modules are: -NoUnp:No modules are unplugged -Podule:(Podule %0) -Extn:(Extn ROM %0) -Modules:No. Position Workspace Name -Number:(Number) -Macro:(Macro) -Result:Result is %0, value : -Integer:an integer -String:a string -ROMMTitle:No. Position|IModule Name|I|IVersion|IStatus|M|J -SYSROM:System ROM -EXTROM:Extn ROM -PODROM:Podule -Active:Active -Dormant:Dormant -Unplugged:Unplugged -Running:Running -Untitled:<Untitled> -Supervisor:Supervisor -ErrSub:E -YesNo:yn -Config:Configuration -Options:options: -Status:status: -Err: (Error number &%0) -Error:Error: %0 (Error number &%1) -UndefinedInstruction:Internal error: undefined instruction at &%0 -InstructionAbort:Internal error: abort on instruction fetch at &%0 -DataAbort:Internal error: abort on data transfer at &%0 -AddressException:Internal error: address exception at &%0 -BranchThrough0:Internal error: branch through zero -SDoesntExist:Sprite doesn't exist -ModuleTooOld:Module %0 too old -NaffRelease:Bad vector release -RMNotFound:Module %0 not found -NaffDevNo:Bad device number -BadDevVecRel:Bad device release -RedirectFail:Redirection fails -StackFull:Not enough memory on system stack -OscliLongLine:Too long -NoOscliSpecials:Special field not allowed in filing system prefix to OS_CLI -OscliTooHard:Expansion too complex -BadCommand:Command not recognised -BadParmString:Parameter expansion contains unrecognised characters -TooManyParms:Too many parameters -BadKey:Key number must be in the range 0-15 -BadAddress:Address not recognised -OutsideFile:Outside file -NotABlock:Not a heap block -BadDesc:Bad heap descriptor -HeapBadReason:Bad reason code -HeapFailInit:Can't initialise heap -BadLink:Heap overwritten -HeapFailAlloc:Not enough memory (in heap) -BadExtend:Not enough memory (to extend heap) -ExcessiveShrink:Can't shrink heap any further -BadModuleReason:Unknown OS_Module call -CantKill:Module is currently active -MHNoRoom:The area of memory reserved for relocatable modules is full. Quit any unwanted applications or see the RISC OS User Guide for ways to maximise memory. -NoMoreModules:No more modules -NoMoreIncarnations:No more incarnations of that module -PostfixNeeded:Postfix not specified -IncarnationExists:Incarnation already exists -ChunkNotRM:Podule chunk is not a relocatable module -ModulePostfix:'%%' in module title -NotMod:This is not a relocatable module -BadRMHeaderField:Illegal header field in module -RMNot32bit:Module '%0' is not 32-bit compatible -IncarnationNotFound:Incarnation not found -RMNotFoundInROM:Module is not in ROM -NumbTooBig:Number too big -BadBase:Base not recognised -BadClaimNum:Bad vector number -SysHeapFull:The area of memory reserved for the system heap is full. Quit any unwanted applications or see the RISC OS User Guide for ways to maximise memory. -NotAllMoved:There is not enough memory to perform this operation. Quit any unwanted applications or see the RISC OS User Guide for ways to maximise memory. (Memory cannot be moved) -ChDynamCAO:Can't change memory area (application running) -AplWSpaceInUse:Application memory area in use -RAMFsUnchangeable:The size of the RAM filing system can only be changed when it is empty -BadDynamicArea:Unknown dynamic area -AreaAlreadyExists:Dynamic area already exists -AreaNotOnPageBdy:Base address not on page boundary -OverlappingAreas:Overlapping areas -CantAllocateArea:Unable to allocate logical address space -CantAllocateLevel2:Unable to allocate page tables for area -UnknownAreaHandler:Unknown dynamic area handler call -RCExc:Return code limit exceeded -RCNegative:Negative return code -BadString:String not recognised -BadVarType:Bad variable type -VarNoRoom:The area of memory reserved for the system variables is full. Use the Task Manager to make more space in the system heap/stack area. -BadMacVal:Bad macro value -BadVarNam:Variable name not recognised -VarTooLong:Variable value too long -BadParameters:Parameters not recognised -ArgRepeated:Argument repeated -BadBra:Mismatched brackets -StkOFlo:Expression stack overflow -MissOpn:Missing operand -MissOpr:Missing operator -BadInt:String is not convertible to integer -StrOFlo:String too long -NaffItm:Unknown operand -DivZero:Division by zero -NotNumeric:Numeric parameter needed -NoThen:There is no THEN -IsString:Expression is a string -ConParmTooBig:Configure parameter too big -BadConOpt:Configure option not recognised -BadStat:Status option not recognised -Config2manyparms:Too many parameters -NoSuchSWI2:SWI name not known -BadTime:Invalid time interval -BadEnvNumber:Bad Environment number -BadReadSysInfo:Unknown OS_ReadSysInfo call -BadMODE:Not enough memory to change to this screen mode -SNoWorkSpace:No memory is reserved for the system sprite area. Use the Task Manager to make some space for the system sprites. -SNoRoom:Not enough memory to create sprite -NoSprites:No sprites -NotGraphics:Not a graphics mode -SCantOpenFile:Can't open file -SNotEnoughRoom:Not enough memory in sprite area -SBadSpriteFile:Bad sprite file -SNoRoomToMerge:Not enough memory to add sprite -SBad2ndPtr:Bad 2nd ptr -InvalidRowOrCol:Invalid row or column -InvalidHeight:Invalid height -InvalidWidth:Invalid width -NoRoomToInsert:Not enough memory to insert row or column -SpriteAlreadyExists:Sprite already exists -InvalidSpriteMode:Invalid sprite mode -SBadReasonCode:Bad sprite reason code -CantInTeletext:Can't switch output in teletext mode -SInvalidSaveArea:Invalid save area -SpriteIsCurrentDest:Sprite is current destination -BadDPI:Illegal XDPI or YDPI in sprite -ModeNotAvailable:Screen mode not available -BadPixelDepth:Bad pixel depth -BadMSFlags:Illegal flags in mode selector -CDATStackOverflow:System stack overflow -NoSuchSWI:SWI not known -BadSav:Incorrect number of parameters for *Save -MonType:Monitor type reconfigured. -NoKbd:No keyboard present - autobooting -BreakPt:Stopped at break point at &%0 -STail:|J|MUse *Configure to set the options.|J|M -CTail1:|J|MWhere:|J|MD is a decimal number, a hexadecimal number preceded by &,|J|Mor the base followed by underscore, followed|J|M -CTail2:by digits in the given base.|J|MItems within [ ] are optional.|J|MUse *Status to display the current settings.|J|M -Zonk:Unknown OS_ScreenMode reason code -SNoMask:Mask or Palette operations not supported in this display depth -BadVIDCDiv:Bad VIDC divider value -BadPlatReas:Unknown OS_PlatformFeatures reason code - -600:ARM 600 Processor -610:ARM 610 Processor -700:ARM 700 Processor -710:ARM 710 Processor -7500:ARM 7500 Processor -7500FE:ARM 7500FE Processor -810:ARM 810 Processor -SA110:StrongARM Processor diff --git a/TestSrc/A600tlb b/TestSrc/A600tlb deleted file mode 100644 index 6481c8b3..00000000 --- a/TestSrc/A600tlb +++ /dev/null @@ -1,61 +0,0 @@ -; -; A600tlb -; -; POST procedure for checking the TLB in A600 MMU. -; -; for each of level 1, level 2 small-page, level 2 large-page -; construct page table -; flush cache -; start timer -; for 32 addresses (with different mappings) -; check address mapping -; save timer -; for same 32 addresses -; check address mapping -; compare test times (did 2nd test require table walk ?) - - - - - -Use a list of addresses that cover a good mixture of virtual addresses -Build a page table that maps these to physical RAM addresses in various ways -Access the addresses in such an order that the cache rotates, scrapping -one entry each time through the list, and loading another. So each cache -entry gets used 31 times, then is lost. -Choice of physical mapping should ensure that the cache entries contain -lots of different values of page and section base addresses. -Choice of virtual test address should ensure that cache tag varies as -widely as posible, too. PRBS ? -Very widely varying values of cache tag require that a large number -of mappings exist .. if these are 2-level mappings, that requires -a lot of RAM. Page tables should be multiply-mapped. -RISC OS puts lots of stuff below the 4M mark. Limits App space to 16M -for backwards compatibility. Probably worth testing outside these -limits to ensure Gold doesn't fall over, but failure rates would be -very low. - - - - -; -; POST procedure for checking access faults (was PPL test) -; -; for each of level 1, level 2 small-page, level 2 large-page -; construct page table -; for user, supervisor mode -; check address alignment fault -; check section translation fault -; check -; check page translation fault -; for 3 domain types -; for 16 domains -; check access permissions -; - - - -; -; POST procedure for checking IDC -; -; diff --git a/TestSrc/Arm3 b/TestSrc/Arm3 deleted file mode 100644 index a385f75f..00000000 --- a/TestSrc/Arm3 +++ /dev/null @@ -1,71 +0,0 @@ -; > TestSrc.ARM3 - - TTL RISC OS 2+ POST ARM version determination -; -; Reads ARM3 version register, returns 0 if ARM 2 fitted. -; -;------------------------------------------------------------------------ -; History -; -; Date Name Comment -; ---- ---- ------- -; 20-Apr-89 ArtG Initial version -; -; -;------------------------------------------------------------------------ - -A3Cid CN 0 -A3Cfls CN 1 -A3Cmod CN 2 -A3Ccac CN 3 -A3Cupd CN 4 -A3Cdis CN 5 - -A3CON CP 15 - - - -ts_ARM_type - MOV r13,lr -; -; First, set up an undefined instruction vector to catch an ARM 2 -; (or a faulty ARM 3 ??) when the copro instruction is run. -; Only applies on systems where ROM isn't mapped at zero. - - [ CPU_Type = "ARM2" :LOR: CPU_Type = "ARM3" - MOV r0,#0 ; set a page at logical 0 - MOV r1,r0 - BL ts_set_cam - ADR r0,ts_ARM_undefined - LDMIA r0,{r2,r3} - MOV r1,#4 - STMIA r1,{r2,r3} ; set the undefined instruction trap - ] -; -; Read ARM3C0 version I.D. -; - MOV r0, #(-1) ; should always be altered - MRC A3CON,0,r0,A3Cid,A3Cid ; Read control register 0 - MOV r12, r0 - [ CPU_Type = "ARM2" :LOR: CPU_Type = "ARM3" - MOV r1,#0 - BL ts_set_cam_idle ; remove the vector page again - ] - MOVS r0, r12 ; return the ID (0 for ARM 2) - MOV pc,r13 - -; -; Trap to be taken when ARM 2 is fitted -; - -ts_ARM_undefined - MOV r0,#0 - MOVS pc,r14_svc -10 - ASSERT ((%10 - ts_ARM_undefined) / 4 = 2) - - - - - END - diff --git a/TestSrc/Begin b/TestSrc/Begin deleted file mode 100644 index bc2993bb..00000000 --- a/TestSrc/Begin +++ /dev/null @@ -1,2163 +0,0 @@ -; > TestSrc.Begin - - TTL RISC OS 2+ Power-On Self-Test -; -; Startup code for RISC OS ROM Self-Test. -; -; Performs ROM test patterns, determines test strategy and enters -; external or internal test code. -; -; A minimal set of opcodes should be used (ideally, only B, LDR and ADDS) -; so that a processor test may be validly included in the internal test -; sequence. -; -;------------------------------------------------------------------------ -; History -; -; Date Name Rel Comment -; ---- ---- --- ------- -; 23-Feb-93 ArtG 2.00 Experimental ARM 600 / Jordan mods -; 20-Oct-93 ARTG 2.02 Changed to new conditional assembly scheme -; 18-Nov-94 RCM 2.05 Morris changes -; 15-May-96 BAR 2.06 Update for ARM7500FE variant, new IOMD ID -; Code. Used initially in the NC product; -; needs different prescalers and ROM speed -; settings, switched on IOMD ID code. -; 30-May-96 BAR 2.07 Add code to flash NC's led's. Ignore morse -; code and just use the simplified flash -; sequence. -; 14-Jun-96 BAR 2.08 Add get call for initmodule file. -; 17-Jun-96 BAR 2.09 Change speed settings for the second bank of -; ROM space. -; 24-Jun-96 BAR 2.10 Updated second check on IOMD ID, instead of -; checking for ARM7500 IOMD ID code to skip -; the Virq test, now checks for the original -; (RiscPC) IOMD ID code and skips Virq test if -; not equal. Thus ARM7500 and ARM7500FE -; devices don't execute the test. -; Updated version number. -; Added call to sir_IOMD_Regs -show iomd registers -; 08-Jul-96 BAR 2.11 Ensure r0 is cleared before checking IOMD vsn no. -; Change ROM Burst speed from93.75nS to 125nS. -; 09-Jul-96 Make IOMD ID code more efficent. Change -; variables used for ROMCR Values and remove -; 'NormalSpeed' ROMs compiler switching code - -; no longer supporting PSwindell. -; Change non-7500FE ROM Burst speed from 3 ticks -; to 4 ticks -; 25-Jul-96 BAR 2.12 Add code to handle EEPROM as well as CMOS -; RAM. Code supplied by J.Harris. -; 29-Jul-96 BAR 2.13 Update LED stuff to wait properly. -; 29-Jul-96 BAR 2.14 Update exit codes IOMD et all. -; More work on the LED code. -; 30-Jul-96 BAR 2.15 Humm, get the LED's to work ! -; 16-Aug-96 JRH 2.16 Add check for OS image in 2nd ROM bank. -; Don't program the 2nd ROM bank speed (ROMCR1), -; unless CanLiveInROMCard is True, in which case -; check whether we're running from the 2nd bank. -; Made display of IOMD regs conditional on new -; ShowIOMDRegs flag, which is set to TRUE -; 05-Sep-96 BAR 2.17 Updated to NOT show the progress colours on -; the screen unless a POST box is added when -; they will be shown. This is in accordance -; with fault report ANC-00159. The final red -; fail screen will be maintained as this -; enfoces the fact the the POSt has failed and -; that the ser needs to attend to the unit. -; The compile switch DontShowProgressColours -; can be set to FALSE, then the progress -; colours will always be shown. -; 07-Oct-96 JRH 2.18 Changed ExtIO to fix support for speaking to -; the test box when running from the 2nd ROM bank, -; conditioned on CanLiveOnROMCard. -; 22-Oct-96 JRH 2.19 Added an Align64 at the end of the file because -; OS_Find was sometimes failing. Don't know why. -; Fixed bug introduced in 2.18 which turned burst -; off on ROMCR0. -; 08 Nov 96 BAR 2.20 Add kluge to skip ram (long) test -; altogether, 'cos it appears to be crashing. -; amg: Renaissance merge. 7500FE unconditional, other changes now conditioned -; on STB being {TRUE}. Extra declarations left unconditional. -; 10 Mar 97 BAR 2.21 Add code to check 1K of NVRAM - if reqd. -; 13 Mar 97 BAR 2.22 Change conditional assemble flags for -; including new LED flashing routines. Now -; checks for Left & Right LED flags. -; Always use the VGA VIDC Definition Table if -; the flag ChrontelSupport is TRUE. -; 18 Mar 97 BAR 2.23 Added C_DEFAULT (Black) Change use of -; C_WARMSTART to C_DEFAULT. -; 12 Jun 97 BAR 2.24 Ensure LED is set to RED before flashing -; them - gets the sequence right. If flashed -; ensure that BOTH are turned back on. -; 19 Jun 97 BAR 2.25 Remove un-necessary mov r13,r14's -; When completed flashing LED's restore the -; faultcode flag from fiq_regs. -; 04 Apr 00 KJB 2.30 Converted to run in 32-bit mode always. -; ShowIOMDRegs set to FALSE (request from -; Tom Clay) -; -;------------------------------------------------------------------------ -; -; TS_STATUS should be one of : -; -; 'R' RISC OS POST -; 'S' Standalone version (with a2 memory test instead of RISCOS) -; 'T' Test build - development only -; - -TS_STATUS * "R" ; Medusa POST version 2.0x -; -TS_RELEASE * 23 -TS_CHANGES * 0 - - - GBLL POSTenabled -POSTenabled SETL {TRUE} ; don't permit POST for ordinary startup - - GBLL AlwaysShortPOST -AlwaysShortPOST SETL {TRUE} :LAND: STB ; always do a short POST - - GBLL ShowIOMDRegs -ShowIOMDRegs SETL (IO_Type = "IOMD") :LAND: {FALSE} :LAND: STB ; show IOMD regs - - GBLL DontShowProgressColours -DontShowProgressColours SETL {TRUE} :LAND: STB ; Do not show the progress colour screens. - ; Progress Colours will always be shown when using POST Box. - ; Set to true for NC - Fault Report ANC-00159. - - GBLL DontDoCMOSTest -DontDoCMOSTest SETL {TRUE} :LAND: STB - - - -ts_Rom_bits * 21 ; Widest ROM address -ts_Rom_length * 1 :SHL: ts_Rom_bits ; Longest ROM -ts_highaddr_bit * 1 :SHL: 25 ; ARM address width -ts_Alias_bits * (1 :SHL: 23) ; I/F output bits -ts_recover_time * (1 :SHL: 8) ; inter-twiddle delay -ts_pause_time * 200 ; Display pause time -ts_S5_base * &3350000 ; IO register base address -ts_IOEB_ID * (ts_S5_base + &50) ; IOE_B ASIC identification -ts_IOEB_ident * &5 ; the value found there -ts_PCaddress * &3010000 ; PC IO world base address -ts_ReadyByte_00 * &90 ; signal 'Here I am' to ExtIO -ts_BBRAM * &A0 ; IIC address of clock/ram chip - [ STB -ts_BBE2 * &A8 ; IIC address of E2ROM chip -ts_BB2KE2 * &E0 ; IIC address of 2K E2ROM chip - ] -ts_RamChunk * &2000 ; gap between data line tests -ts_MaxRamTest * 4*1024*1024 ; Max. DRAM tested on normal reset -ts_VIDCPhys * &3400000 ; Real location of VIDC - -; -; Border colours used for self-test indicators -; - [ VIDC_Type = "VIDC1a" -C_ARMOK * &40000000+&70C ; testing ROM -C_RAMTEST * &40000000+&C70 ; testing RAM -C_FAULT * &40000000+&00F ; failed tests -C_PASSED * &40000000+&7C0 ; all passed -C_WARMSTART * &40000000+&777 ; not tested -C_DEFAULT * &40000000+&000 ; default (Black) - ] - - [ VIDC_Type = "VIDC20" -C_2NDBANK * &40000000+&C00070 ; jumping to image in 2nd ROM bank (Dark blue) -C_ARMOK * &40000000+&7000C0 ; testing ROM (Magenta) -C_RAMTEST * &40000000+&C07000 ; testing RAM (Blue) -C_FAULT * &40000000+&0000F0 ; failed tests(Red) -C_PASSED * &40000000+&70C000 ; all passed (Green) -C_WARMSTART * &40000000+&707070 ; not tested (Mid grey) -C_DEFAULT * &40000000+&000000 ; default (Black) - ] -; -; -; Responses to external commands -; -; -ErrorCmd * &00FF -; -; Control bitmasks used to indicate results of test to RISCOS -; - -R_SOFT * 0 ; not a power-on reset -R_HARD * 1 ; Self-test run due to POR -R_EXTERN * 2 ; external tests performed -R_TESTED * 4 ; Self-test run due to test link -R_MEMORY * 8 ; Memory has been tested -R_ARM3 * &10 ; ARM 3 fitted -R_MEMSKIP * &20 ; long memory test disabled -R_IOEB * &40 ; PC-style IO controller (A5000) -R_IOMD * &40 ; PC-style IO controller (RiscPC, ARM7500) -R_VRAM * &80 ; VRAM present - -R_STATUS * &1ff ; bits that aren't a fault - -R_CHKFAILBIT * &100 ; CMOS contents failed checksum -R_ROMFAILBIT * &200 ; ROM failed checksum -R_CAMFAILBIT * &400 ; CAM failed -R_PROFAILBIT * &800 ; MEMC protection failed -R_IOCFAILBIT * &1000 ; IOC register test failed -R_INTFAILBIT * &2000 ; Cannot clear interrupts -R_VIDFAILBIT * &4000 ; VIDC flyback failure -R_SNDFAILBIT * &8000 ; Sound DMA failure -R_CMSFAILBIT * &10000 ; CMOS unreadable -R_LINFAILBIT * &20000 ; Page zero RAM failure -R_MEMFAILBIT * &40000 ; Main RAM test failure -R_CACFAILBIT * &80000 ; ARM 3 Cache test failure -; - [ MorrisSupport -Kludge * 96 - | -Kludge * 0 - ] - SUBT Exception vectors -; -; These vectors are available for use while the Rom is mapped into -; low memory addresses. The Reset vector will be copied to low RAM -; as part of a software reset sequence : therefore it must perform -; a fixed operation to ensure compatibility with future versions -; of RISC-OS. -; - -Reset -ts_start - $DoMorrisROMHeader - - [ :LNOT: MorrisSupport - [ ResetIndirected - LDR pc,.+ResetIndirection ; load pc from vector at &118 - | - B ts_RomPatt + PhysROM ; Jump to normal ROM space - ] - ] -01 - & ts_Rom_length ; gets patched by ROM builder -02 - & (ts_ROM_cvectors - ROM) ; pointer to code vector table -03 - & (ts_ROM_dvectors - ROM) ; pointer to data vector table -04 - & (ts_ROM_bvectors - ROM) ; pointer to branch table - B Reset ; not currently used - B Reset - B Reset - - -ts_ROMSIZE * %BT01 - ts_start -ts_CVECTORS * %BT02 - ts_start -ts_DVECTORS * %BT03 - ts_start -ts_BVECTORS * %BT04 - ts_start - - ! 0, "ts_Rom_length held at ":CC::STR:(%BT01 - ROM) - - -; -; Selftest version ID -; - -00 - ASSERT %B00 <= (ts_start + &2c + Kludge) - % ((ts_start + &2c + Kludge) - %B00) - -ts_ID & ((TS_STATUS :SHL: 24) + (TS_RELEASE :SHL: 16) + TS_CHANGES) - -ts_ID_text -ts_himsg - = "SELFTEST" ; **DISPLAY_TEXT** - = &89 ; Cursor position - = TS_STATUS - = ("0" + (TS_RELEASE / 10)) - = "." - = ("0" + (TS_RELEASE :MOD: 10)) - = ("0" + (TS_CHANGES :MOD: 10)) - = 0 - - ALIGN - -; -; These vector tables permit access by the external (or downloaded) test -; software to data and code in the POST modules. -; Find the start of these tables through the 2nd and 3rd vectors at -; the start of the ROM. -; - -ts_ROM_dvectors -01 - & ts_ID ; Selftest identification number -02 - & (ts_ID_text - ROM) ; Selftest identification text - - -ts_ROM_cvectors - & ts_RomPatt - & ts_User_startup - & ts_Self_test_startup - & ts_Dealer_startup - & ts_Forced_startup - & ts_GetCommand - & ts_Softstart - & ts_Hardstart - - -; -; ROM branch vectors - intended primarily so downloaded programs -; may use standard subroutines. This table should be in a fixed place. -; - -00 - ASSERT %B00 <= (ts_start + 128 + Kludge) - % ((ts_start + 128 + Kludge) - %B00) - -ts_ROM_bvectors - B ts_RomPatt - B ts_GetCommand - B ts_SendByte - B ts_SendWord - B ts_GetByte - B ts_GetWord - B ts_SendText - B ts_MoreText - B ts_SendLCDCmd - - -; -; Pad out until the location of the ResetIndirection vector -; - - ASSERT .-ROM <= ResetIndirection - % ResetIndirection-(.-ROM) - & ts_RomPatt-ROM+PhysROM - -; -; ROM test code -; -; Note : the register order in ADDS ...pc.. is often critical. -; If we want to adjust pc, use ADDS pc,rn,pc so that the PSR is -; rewritten with it's original value. -; If we want to do some pc-relative arithmetic, use ADDS rn,pc,rn -; so that the bits from PSR are NOT used in the address calculation. -; - - SUBT Macros - - MACRO - MODE $mode_bits - MSR CPSR_c,#I32_bit :OR: F32_bit :OR: $mode_bits - MEND - - MACRO - MOV_fiq $dest,$src - MODE FIQ32_mode - MOV $dest,$src - MODE SVC32_mode - MEND - - MACRO - FAULT $code - MODE FIQ32_mode - ORR r12_fiq,r12_fiq,$code - MODE SVC32_mode - MEND - - -; -; Define an area of storage with the required set of data bus patterns -; These are used both for testing the complete width of the data bus -; during ROM pattern testing, and will provide a tidy set of patterns -; if the reset is held, while the ARM increments addresses. -; - - SUBT ROM Address and Data Patterns - -DataPatterns - - GBLA dmask -dmask SETA &80000000 - - DCD &FFFFFFFF ; first two : all set - DCD &0 ; all clear - - GBLA OldOpt ; don't list all the walking -OldOpt SETA {OPT} ; patterns - OPT OptNoList - - WHILE dmask > 0 ; then for each bit - DCD &$dmask ; set it - DCD :NOT: &$dmask ; and clear it -dmask SETA dmask :SHR: 1 - WEND - OPT OldOpt -DEnd - - - OPT OptList -; -; -; Read the ROM at a series of addresses -; such that : a) all the address lines are exercised individually -; b) all the data lines are exercised individually -; -; Data and address lines are exercised as walking-0 and walking-1. -; The test is performed as a series of LDR operations to avoid using -; a larger instruction set. -; - -ts_RomPatt ROUT - - ; Patterns which will exercise most of the data bus. - ; All are arbitrary instructions with NV execution - - DCD &F0000000 ; walking 1 - -OldOpt SETA {OPT} ; patterns - OPT OptNoList - -dmask SETA &08000000 - WHILE dmask > 0 - DCD dmask :OR: &F0000000 -dmask SETA dmask :SHR: 1 - WEND - - DCD &FFFFFFFF ; walking 0 - -dmask SETA &08000000 - WHILE dmask > 0 - DCD (:NOT: dmask) :OR: &F0000000 -dmask SETA dmask :SHR: 1 - WEND - - OPT OldOpt - - ; Now some proper code : - ; Initialise address pointer and make MemC safe - - LDR r0,%01 - ADD pc,r0,pc -01 - & 0 ; useful constant - - [ IO_Type = "IOC-A1" ;;!! unsafe if we execute ROM at zero - LDR r1,%02 - ADD pc,r0,pc -02 ;;!! This remaps MEMC's ROM - & &E000C :OR: MEMCADR ;;!! addressing if it hasn't - STR r1,[r1] ;;!! already happened. - ] - - LDR r5,%03 ; Load r5 with a constant which - ADD pc,r0,pc ; may be added to ROM plus a -03 ; walking-zero bitmask to create - & ts_Rom_length - 3 ; a valid word address in ROM. - LDR r2,%04 ; Offset from ROM start to here - ADD pc,r0,pc -04 - & ROM - pcfromstart - - ADD r2,pc,r2 ; pointer to start of ROM - ADD r3,r2,r0 ; pointer to start of ROM -pcfromstart - ADD r4,r2,r0 ; pointer to start of ROM - - ; assembly-time loop - only 32 iterations required - -OldOpt SETA {OPT} - - GBLA doffset -doffset SETA DataPatterns - WHILE doffset < DEnd - - LDR r0,doffset ; walking 1 data pattern - LDR r1,doffset+4 ; walking 0 data pattern - LDR r6,[r2] ; walking 1 address pattern - LDR r6,[r3] ; walking 0 address pattern - - [ (doffset - DataPatterns) > ((32 - ts_Rom_bits) * 8) - [ (doffset - DataPatterns) < (31 * 8) - ADD r2,r4,r0 ; r2 = ROM + walking 1 pattern - ADD r3,r4,r1 ; r3 = ROM + walking 0 pattern - ADD r3,r3,r5 ; adjust to a valid address - ] - ] - - OPT OptNoList - -doffset SETA doffset + 8 - WEND - - ASSERT (. - doffset < 4095) ; in range without barrel shift ? - - OPT OldOpt - - [ EmulatorSupport - ARM_on_emulator r0 ; we skip the rest of POST if - BEQ CONT ; on the emulator - ] - -; -; External interface drivers - -; provides entry points to send byte- and word- and string-sized objects -; and to receive byte- and word-sized objects -; -; Continue into GetCommand, which determines adapter type (or no adapter) -; and jumps to an ExtCmd handler, ts_User_startup, ts_Forced_startup or -; ts_Dealer_startup as appropriate. -; - B ts_GetCommand ; (This instruction redundant 'cos ts_GetCommand - ; is the first thing defined in TestSrc.ExtIO) - GET TestSrc.ExtIO - -; -; External command handlers - respond to commands given through the -; external test interface. -; - - GET TestSrc.ExtCmd - - - SUBT Selftest -; -; There is no attached test interface. Is this a power-on reset ? -; Addressing IOC will make MEMC1a remap the ROM to high memory if -; it hasn't already done it, so be careful to ensure that the -; ARM is addressing normally-addressed ROM when this code runs. -; - -ts_User_startup ROUT - LDR r0,%01 - ADD pc,r0,pc -01 - & 0 -; -; IOMD will only access the ROM until a write to IOMD has been made - -; make this write also switch on refresh so the DRAM has a chance to -; get running before the memory test starts. -; - [ MEMC_Type = "IOMD" - LDR r1,%02 - ADD pc,r0,pc -02 - & (IOMD_Base+IOMD_VREFCR) - LDR r2,%03 - ADD pc,r0,pc -03 - & IOMD_VREFCR_REF_16 - STR r2, [r1,#0] - ] - - [ POSTenabled - LDR r1,%12 ; load address of IOC IRQ register - ADD pc,r0,pc -12 - & IOC+IOCIRQSTAA - - LDR r1, [r1,#0] ; Get IRQSTAA register (hence POR bit) - LDR r2, %13 - ADD pc,r0,pc ; Constant to shift por to bit 31 -13 - & por_bit :SHL: 1 -14 ADD r1,r1,r1 - ADDS r2,r2,r2 - BCC %14 ; loop until por_bit is at bit 31 - ADDS r1,r1,r1 ; then shift it into carry - BCC ts_Self_test_end ; POR bit clear - do soft reset. - -; it's a power-on reset, so assume we can't be in 32-bit mode for ARM 6/7 - - MOV_fiq r12_fiq, #R_HARD - B ts_Self_test_startup - | - B CONT ; if user POST disabled - ] -; -; Perform self - tests -; -; Any distinction between test operation for Power-up, Display-only -; and Forced tests needs to be made between these three entry points. -; - - -; This is where tests start if a dumb test link is fitted -; (a diode from A21 to *ROMCS, disabling the ROMs when A21 is high) - -ts_Forced_startup ROUT - - MOV_fiq r12_fiq, #R_TESTED - B ts_Self_test_startup - -; This is where the tests start if an external display adapter is fitted - -ts_Dealer_startup ROUT - - MOV_fiq r12_fiq, #R_EXTERN - - LDR r4,%FT02 ; make a pointer to signon string -01 ADD r4,pc,r4 - ADD pc,r0,pc -02 - & (ts_himsg - %BT01 - 8) - - ADD r14,pc,r0 ; make a return address for this 'call' - ASSERT (.+4 = ts_Self_test_startup) ; PC must point there already ! - B ts_SendText - -ts_Self_test_startup ROUT - -; This is where the power-on test starts (every user gets this) - - -; -; Processor test would go here .... if there was one. -; - - [ MorrisSupport -; -; On startup Morris defaults to dividing all its clocks by two and -; accessing ROM at the slowest possible access speed. So check for -; Morris and set to sensible values. -; -; check for te veriosn of IOMD, only need to determin between variants in -; the ARM7500 and ARM7500FE - condional code assembly excludes non-ARM7500 -; devices. - - MOV r2, #IOMD_Base ; r2 points to the IOMD base address defiend in HDR:IO.IOMDL - LDRB r1,[r2,#IOMD_ID1] ; load r1 with IOMD ID high byte - LDRB r0,[r2,#IOMD_ID0] ; load r0 with IOMD ID low byte - ORR r0,r0,r1,LSL#8 ; Or r0 and r1, shifted left 8, put in r0 - LDR r1,=ts_IOMD_ID2 ; get Ref IOMD ID code #2 - CMPS r0,r1 ; check for IOMD ID Code #2 - BEQ %FT05 ; If equal, got to 05 - - LDRNE r1,=ts_IOMD_ID3 ; If not ID1, get ID code #3 - CMPNES r0,r1 ; If not ID1, check for IOMD ID Code #3 - BNE %FT10 ; Not equal; not an ARM7500 or an ARM7500FE - skip - - [ RO371Timings -05 - MOV r0, #0 ;Calling from POST - BL TimeCPU ;just sets things according to assumed bus speeds for each IOMD id, in this case - - | ; else if not RO371Timings - -; Here because its an ARM7500 'FE' variant -; Program the CPU, Memory and IO clock prescalers -; Set the prescalers to :- -; CPUCLK divide by 2 unless FECPUSpeedNormal set -; MEMCLK divide by 1 -; IOCLK divide by 1 -; - [ FECPUSpeedNormal - MOV r0, #IOMD_CLKCTL_CpuclkNormal + IOMD_CLKCTL_MemclkNormal + IOMD_CLKCTL_IOclkNormal - | - MOV r0, #IOMD_CLKCTL_CpuclkHalf + IOMD_CLKCTL_MemclkNormal + IOMD_CLKCTL_IOclkNormal - ] - STRB r0, [r2, #IOMD_CLKCTL] ; initialise all the prescalers. -; -; Set ROM speed, take care to preserve 16-bit mode bit... -; -; According to BSiddle on the 15-May-96, Omega will use burst mode roms: use 93nS burst, 156nS initial. -; According to TDbson on the 09-Jul-96, Omega will handle ROMS up to 120nS and 70nS. -; Thus the ROM speed should be initilised to :- -; Half Speed or H bit, clear, which is ON ! : Half the delays, thus DOUBLE all clock ticks. -; Non-Sequental delay : 10 Ticks : Half speed on, so select 5 ticks (5*2) -; Burst delay : 8 Ticks : Half speed on, so select 4 ticks (4*2) -; Remember the Memory clock on Omega is faster than on previous porducts. -; The fast flash devices used for Omega testing should be able to cope even -; though they aren't burst devices. - LDRB r0, [r2, #IOMD_ROMCR0] ; Get contents of ROMCR0 in to r0 - AND r0, r0, #&40 ; clear all but the 16-bit mode flag - [ ROMSpeedNormal - ORR r0, r0, #IOMD_ROMCR_Normal :OR: IOMD_ROMCR_NSTicks_$ROMSpeedNSTicks :OR: IOMD_ROMCR_BTicks_$ROMSpeedBurstTicks - | - ORR r0, r0, #IOMD_ROMCR_HalfSpeed :OR: IOMD_ROMCR_NSTicks_$ROMSpeedNSTicks :OR: IOMD_ROMCR_BTicks_$ROMSpeedBurstTicks - ] - STRB r0, [r2, #IOMD_ROMCR0] ; Prog. the reg.s - [ CanLiveOnROMCard - TST pc, #ts_RC_2ndbank ; Not running out of 2nd ROM bank? - ; Don't know what's in the 2nd bank -> program it to a slow default - [ ExtROMis16bit - [ ROMSpeedNormal - MOVEQ r0, #IOMD_ROMCR_Normal :OR: IOMD_ROMCR_16bit :OR: IOMD_ROMCR_NSTicks_7 :OR: IOMD_ROMCR_BurstOff - | - MOVEQ r0, #IOMD_ROMCR_HalfSpeed :OR: IOMD_ROMCR_16bit :OR: IOMD_ROMCR_NSTicks_7 :OR: IOMD_ROMCR_BurstOff - ] - | - [ ROMSpeedNormal - MOVEQ r0, #IOMD_ROMCR_Normal :OR: IOMD_ROMCR_32bit :OR: IOMD_ROMCR_NSTicks_7 :OR: IOMD_ROMCR_BurstOff - | - MOVEQ r0, #IOMD_ROMCR_HalfSpeed :OR: IOMD_ROMCR_32bit :OR: IOMD_ROMCR_NSTicks_7 :OR: IOMD_ROMCR_BurstOff - ] - ] - STRB r0, [r2, #IOMD_ROMCR1] ; Otherwise program it the same - ] - B %FT10 -; - -05 -; Here because its an ARM7500 variant - NON 'FE' device. -; Program the CPU, Memory and IO clock prescalers -; Set the prescalers to :- -; CPUCLK divide by 1 -; MEMCLK divide by 1 -; IOCLK divide by 1 -; - MOV r0, #IOMD_CLKCTL_CpuclkNormal + IOMD_CLKCTL_MemclkNormal + IOMD_CLKCTL_IOclkNormal - STRB r0, [r2, #IOMD_CLKCTL] ; initialise all prescalers to div1 -; -; Set ROM speed, take care to preserve 16-bit mode bit... -; -; According to RJKing on 6/5/94, Kryten will use burst mode roms: use 93nS burst, 156nS initial. -; According to BSiddle on 09-Jul-96 - Omega will need to set the burst speed to 4 ticks from 3 ticks. -; Thus the ROM speed should be initilised to :- -; Half Speed or H bit, Set, which is OFF ! : Don't half the delays. -; Non-Sequental delay : 5 Ticks : Half speed off, so select 5 ticks -; Burst delay : 4 Ticks : Half speed off, so select 4 ticks -; The fast EPROMS used for Kryten testing should be able to cope even though -; they aren't burst devices - - LDRB r0, [r2, #IOMD_ROMCR0] ; Get contents of ROMCR0 in to r0 - AND r0, r0, #&40 ; clear all but the 16-bit mode flag - [ ROMSpeedNormal - ORR r0, r0, #IOMD_ROMCR_Normal :OR: IOMD_ROMCR_NSTicks_$ROMSpeedNSTicks :OR: IOMD_ROMCR_BTicks_$ROMSpeedBurstTicks - | - ORR r0, r0, #IOMD_ROMCR_HalfSpeed :OR: IOMD_ROMCR_NSTicks_$ROMSpeedNSTicks :OR: IOMD_ROMCR_BTicks_$ROMSpeedBurstTicks - ] - STRB r0, [r2, #IOMD_ROMCR0] ; Prog. the reg.s - [ CanLiveOnROMCard - TST pc, #ts_RC_2ndbank ; Not running out of 2nd ROM bank? - ; Don't know what's in the 2nd bank -> program it to a slow default - [ ExtROMis16bit - [ ROMSpeedNormal - MOVEQ r0, #IOMD_ROMCR_Normal :OR: IOMD_ROMCR_16bit :OR: IOMD_ROMCR_NSTicks_7 :OR: IOMD_ROMCR_BurstOff - | - MOVEQ r0, #IOMD_ROMCR_HalfSpeed :OR: IOMD_ROMCR_16bit :OR: IOMD_ROMCR_NSTicks_7 :OR: IOMD_ROMCR_BurstOff - ] - | - [ ROMSpeedNormal - MOVEQ r0, #IOMD_ROMCR_Normal :OR: IOMD_ROMCR_32bit :OR: IOMD_ROMCR_NSTicks_7 :OR: IOMD_ROMCR_BurstOff - | - MOVEQ r0, #IOMD_ROMCR_HalfSpeed :OR: IOMD_ROMCR_32bit :OR: IOMD_ROMCR_NSTicks_7 :OR: IOMD_ROMCR_BurstOff - ] - ] - STRB r0, [r2, #IOMD_ROMCR1] ; Otherwise program it the same - ] - - ] ;RO371Timings conditional - -; -10 - ] -; -; From this point on we assume we can safely use all the processor -; -; Initialise VIDC -; - -ts_InitVIDC - [ IO_Type = "IOMD" ; If POSTbox fitted, ROM may still be mapped everywhere - ; Using IOMD - MOV r2,#IOMD_Base - MOV r0, #IOMD_VREFCR_REF_16 ; switch on DRAM refresh - STR r0, [r2, #IOMD_VREFCR] - MOV r1,#ts_VIDCPhys - - [ ChrontelSupport - ; We have a Chrontel chip ... thus always set for VGA. - ADRL r2,TestVVIDCTAB - | ; NOT ChrontelSupport - ; We don't have a Chrontel chip - ; ... thus check MonitorType and select table as reqd. - ADRL r2,TestVIDCTAB - LDR r0,=IOMD_MonitorType - LDR r0,[r0] - ANDS r0,r0,#IOMD_MonitorIDMask - ADDEQ r2,r2,#(TestVVIDCTAB-TestVIDCTAB) - ] ; Endif - ChrontelSupport - | ; not IOMD - MOV r1,#ts_VIDCPhys - ADRL r2,TestVIDCTAB - ] ; Endif - IO_Type = "IOMD" - -10 LDR r0, [r2],#4 - CMP r0, #-1 - STRNE r0, [r1] - BNE %BT10 - -; -; Test for presence of OS image in 2nd ROM bank and jump to it -; - GBLS DoROMCardThings - [ ROMCardSupport :LOR: CanLiveOnROMCard -DoROMCardThings SETS "GET TestSrc.ROMCard" - | -DoROMCardThings SETS "" - ] - $DoROMCardThings - - -; -; Set purple screen -; - - [ DontShowProgressColours - MOV_fiq r0,r12_fiq ; restore the faultcode bits - ANDS r0,r0,#(R_EXTERN :OR: R_TESTED) ; If test adapter present, - ; NE : Adaptor fitted, show progress. - ; EQ : No Adaptor fitted, don't show progress - BEQ ts_RomTest ; EQ : Don't show colours - ] - MOV r1, #ts_VIDCPhys - - [ :LNOT: StrongARM_POST - ;skip POST for StrongARM or ARM8 - ARM_read_ID r0 - AND r0,r0,#&F000 - CMP r0,#&A000 ;if we are a StrongARM... - CMPNE r0,#&8000 ;or an ARM8... - LDREQ r0,=C_WARMSTART ;the colour that indicates no POST performed - STREQ r0,[r1] - BEQ ts_Hardstart ;RISC OS - right now! - ] - - [ ARM810support :LAND: (:LNOT: ARM810_POST) - ;just too horrible to fix POST for ARM 8 at the moment - ARM_read_ID r0 - AND r0,r0,#&F000 - CMP r0,#&8000 ;if we are an ARM 8 - LDREQ r0,=C_WARMSTART ;the colour that indicates no POST performed - STREQ r0,[r1] - BEQ ts_Hardstart ;RISC OS - right now! - ] - - LDR r0, =C_ARMOK ; set initial screen colour - STR r0, [r1] - - B ts_RomTest - - LTORG - ROUT - -; -; Calculate ROM checksum : display status and calculated checksum. -; - -1 - = "ROM :",0 -2 - = "ROM bad",&88,&ff,&ff,&ff,&ff,&ff,&ff,&ff,&ff,0 -3 - = "ROM size",&8A,&ff,&ff,&ff,&ff,&ff,&ff,0 - ALIGN - -ts_RomTest - ADR r4,%BT1 - BL ts_SendText - - BL ts_ROM_checksum - BEQ %20 - ADR r4,%BT2 ; Failed message - FAULT #R_ROMFAILBIT ; set ROM bit in r12_fiq - MOV r8,r0 ; calculated checksum - BL ts_SendText - - BL ts_ROM_alias ; Checksum failed :- - ADR r4,%BT3 ; hunt for first alias - MOV r8,r0, LSL #8 - BL ts_SendText ; and report it. -20 - - [ IO_Type = "IOC-A1" ; Don't use RISC OS MemSize - ; until much later - it sets up - ; the ARM600 MMU as well. - B ts_MEMCset - -; -; Do MEMC setup and memory size determination (the first time). -; - LTORG - ROUT - -1 - = "M Size :",0 -2 - = "M Size",&89,&ff,&ff,&ff,&ff,".",&ff,&ff,0 - ALIGN - -ts_MEMCset - MOV r12,#0 - ADR r4,%BT1 - BL ts_SendText - LDR r1,=(&E000C :OR: MEMCADR) ; MemSize expects 32k page - STR r1,[r1] - BL MemSize - -; -; MemSize returns with r0 = page size (now in bytes, *NOT* in MEMC control patterns), -; r1 = memory size (in bytes) -; r2 = MEMC control value -; -; Translate these into a number that looks like : -; -; mmmm.pp -; -; where mmmm is memory size in hex Kbytes, pp is page size in hex Kbytes. -; - MODE FIQ32_mode ; Save memory size and - MOV r11_fiq,r2 ; MEMC setup value for - MOV r10_fiq,r1 ; later use - MODE SVC32_mode - - MOV r8, r0, LSR #2 ; MemSize now returns actual page size in r0 - ADD r8,r8,r1,LSL #6 - ADR r4,%BT2 - BL ts_SendText - - ] - -; -; Test data, address and byte strobe lines. -; On MEMC systems, this calls MemSize and tests the memory that finds. -; On IOMD systems, memory sizing is performed along with the data line -; tests, and that result is used for address line testing. -; - - B ts_LineTest - - GBLS tsGetMem1 -tsGetMem1 SETS "GET TestSrc.Mem1" :CC: MEMC_Type - $tsGetMem1 - -; -; Test IOC. -; This shuld require vector space to work (for testing interrupts), -; but the current version just reports the status register contents. -; -; Display is ccaabbff -; -; where cc is the control register -; aa is IRQ status register A -; bb is IRQ status register B -; ff is FIQ status register -; - - B ts_IOCTest - - LTORG - ROUT - - [ IO_Type = "IOMD" -1 - = "IOMD :",0 -2 - = "IOMD-F",&88,&ff,&ff,&ff,&ff,&ff,&ff,&ff,&ff,0 -3 - = "IOMD-V" -4 - = &88,&ff,&ff,&ff,&ff," V.",&ff,0 - | -1 - = "IOC :",0 -2 - = "IOC-F",&88,&ff,&ff,&ff,&ff,&ff,&ff,&ff,&ff,0 -3 - = "IOC" -4 - = &88,&ff,&ff,&ff,&ff,&ff,&ff,&ff,&ff,0 - ] - ALIGN - -ts_IOCTest - ADR r4,%BT1 - BL ts_SendText - BL ts_IOCreg ; check register integrity - BEQ %FT8 - ADR r4,%BT2 - BL ts_SendText ; report if failure - - FAULT #R_IOCFAILBIT -8 - ADR r4,%BT1 - BL ts_SendText - BL ts_IOCstat ; IOCstat, get IOC/IOMD Vsn number. - ; Note : func leaves falgs un altered, thus - ; result of last comparison is passed back - ; as the result. - ; r8 has the id&vsn number : &IIIIVV00 - BEQ %FT10 ; fail message only printed if - ADR r4,%BT3 ; ID code unrecognised - BL ts_SendText - FAULT #R_IOCFAILBIT ; .. and set error bit if IOMD code is wrong - B %FT11 -10 - ADR r4,%BT4 ; print the status value - BL ts_MoreText - FAULT #R_IOMD ; set that bit in the result word - ; to indicate an IOMD was found. - -11 - - [ IO_Type = "IOMD" - ; IO world is IOMD : Show IOMD Regs, skip IOEB test - [ ShowIOMDRegs - BL sir_ShowIOMDRegs - ] - B ts_CMOStest - | - ; IO world is IOEB: Do the IOEB test, skip Show IOMD Regs. - B ts_IOEBtest - ] - - LTORG - ROUT - -; -; Check for presence of IOEB ASIC -; - - [ IO_Type = "IOEB" - -1 - = "IOEB :",0 -2 - = "IOEB",&88,"exists",0 - - - ALIGN - -ts_IOEBtest - ADR r4,%BT1 - BL ts_SendText - - LDR r0,=ts_IOEB_ID ; read an ID register in the IOEB ASIC - LDRB r0, [r0] - AND r0, r0, #&f - CMPS r0, #ts_IOEB_ident ; if it looks right ( == 5) .. - BNE %10 - - FAULT #R_IOEB ; set that bit in the result word - ADR r4, %BT2 - BL ts_SendText -10 B ts_CMOStest - ] ; IOEB IO world - ROUT - -; -; Read CMOS -; Check the checksum, read the memory test flag. -; - - -ts_CMOStest - [ DontDoCMOSTest - B ts_IOinit - | - ADR r4,%FT1 - BL ts_SendText - - [ ChecksumCMOS :LAND: STB - LDR r0,=(ts_BBRAM + &4000) - MOV r1,#&C0 ; Get first RAM area - MOV r2,#CMOSxseed - BL ts_CMOSread - BNE %FT10 - MOV r2, r0 - LDR r0,=(ts_BBRAM + &1000) ; Accumulate the second RAM area - MOV r1,#&2F - BL ts_CMOSread - BNE %FT10 - RSB r2, r0, #0 ; Subtract from the checksum byte - LDR r0,=(ts_BBRAM + &3F00) - MOV r1,#1 - BL ts_CMOSread - BNE %FT10 - MOV r8, r0, LSL #24 - ANDS r0, r0, #&FF ; A zero result ? - MOV r1, #R_CHKFAILBIT - ADR r4,%FT3 ; Report checksum failure - BNE %FT21 ; failed .. report error - ] ; end ChecksumCMOS - - [ :LNOT: AlwaysShortPOST ; Always do a short post on STBs - LDR r0,=(ts_BBRAM + &FC00) ; Read Misc1CMOS byte - MOV r1,#1 - MOV r2,#0 - BL ts_CMOSread - BNE %FT10 - ANDS r0,r0,#&80 ; Test the memory-test-disable bit - BEQ %FT25 - ] - FAULT #R_MEMSKIP ; If set, skip the memory test - B %FT25 - -10 -; CMOS failed -> try E2 - [ E2ROMSupport :LAND: STB - [ ChecksumCMOS - - ; Accumulate the first RAM area - LDR r0,=(ts_BBE2 + &4000) ; r0 = base addr + start location - MOV r1,#&C0 ; r1 = length of data to read - MOV r2,#CMOSxseed ; r2 = checksum seed or previous value - BL ts_CMOSread ; read the cmos r0 = new checksum. NE = failure; EQ = ok. - BNE %FT20 ; branch if NE - failed to ready at all. - - ; Accumulate the second RAM area - MOV r2, r0 ; r2 = r0 = new checksum value. - LDR r0,=(ts_BBE2 + &1000) ; r0 = base addr + start location - MOV r1,#&2F ; r1 = length of data to read - BL ts_CMOSread ; read the cmos r0 = new checksum. NE = failure; EQ = ok. - BNE %FT22 ; branch if NE - failed to ready at all. - RSB r2, r0, #0 ; Subtract from the checksum byte - - ; Check to see if we need to Accumulate the THIRD area. - MOV r1,#?CMOSRAMCache ; r1 = size of the CMOS RAM - TEQ r1,#240 ; Is r1 = 240 bytes ? - BEQ %FT15 ; It is equal, go to checksum checking code - - ; Accumulate the third RAM area - MOV r2,r0 ; r2 = r0 = new checksum value. - LDR r0,=(ts_BBE2 + &10000) ; r0 = base addr + start location - MOV r1,#&300 ; r1 = length of data to read - BL ts_CMOSread ; read the cmos r0 = new checksum. NE = failure; EQ = ok. - BNE %FT22 ; branch if NE - failed to ready at all. - - ; read and check the shecksum value. -15 RSB r2, r0, #0 ; Subtract from the checksum byte - LDR r0,=(ts_BBE2 + &3F00) ; r0 = base addr + start location - MOV r1,#1 ; r1 = length of data to read - BL ts_CMOSread ; read the cmos r0 = new checksum. NE = failure; EQ = ok. - BNE %FT22 ; branch if NE - failed to ready at all. - - ; Check the checksum is correct - MOV r8, r0, LSL #24 ; r8 = r0 << 24 : put the checksum value in r8 for displaying. - ANDS r0, r0, #&FF ; r0 = r0 + &FF : If alls ok s/be a zero result ... - MOV r1, #R_CHKFAILBIT ; r1 = checksum fail flag - ADR r4,%FT3 ; Report checksum failure - BNE %FT21 ; failed .. report error - ] ; end ChecksumCMOS - - [ STB :LAND: :LNOT: AlwaysShortPOST ; Always do a short post on STBs - LDR r0,=(ts_BBE2 + &FC00) ; Read Misc1CMOS byte - MOV r1,#1 - MOV r2,#0 - BL ts_CMOSread - BNE %FT22 - ANDS r0,r0,#&80 ; Test the memory-test-disable bit - BEQ %FT25 - ] - FAULT #R_MEMSKIP ; If set, skip the memory test - B %FT25 - ] - -1 - = "SRAM :",0 -2 - = "SRAM-F",0 -3 - = "SRAM-C",&8e,&ff,&ff,0 - ALIGN - -20 -; CMOS failed -> try 2K E2 - [ E2ROMSupport - [ ChecksumCMOS - - ; Accumulate the first RAM area - LDR r0,=(ts_BB2KE2 + &4000) ; r0 = base addr + start location - MOV r1,#&C0 ; r1 = length of data to read - MOV r2,#CMOSxseed ; r2 = checksum seed or previous value - BL ts_CMOSread ; read the cmos r0 = new checksum. NE = failure; EQ = ok. - BNE %FT22 ; branch if NE - failed to ready at all. - - ; Accumulate the second RAM area - MOV r2, r0 ; r2 = r0 = new checksum value. - LDR r0,=(ts_BB2KE2 + &1000) ; r0 = base addr + start location - MOV r1,#&2F ; r1 = length of data to read - BL ts_CMOSread ; read the cmos r0 = new checksum. NE = failure; EQ = ok. - BNE %FT22 ; branch if NE - failed to ready at all. - RSB r2, r0, #0 ; Subtract from the checksum byte - - ; Check to see if we need to Accumulate the THIRD area. - MOV r1,#?CMOSRAMCache ; r1 = size of the CMOS RAM - TEQ r1,#240 ; Is r1 = 240 bytes ? - BEQ %FT15 ; It is equal, go to checksum checking code - - ; Accumulate the third RAM area - MOV r2,r0 ; r2 = r0 = new checksum value. - LDR r0,=(ts_BB2KE2 + &10000); r0 = base addr + start location - MOV r1,#&300 ; r1 = length of data to read - BL ts_CMOSread ; read the cmos r0 = new checksum. NE = failure; EQ = ok. - BNE %FT22 ; branch if NE - failed to ready at all. - - ; read and check the shecksum value. -15 RSB r2, r0, #0 ; Subtract from the checksum byte - LDR r0,=(ts_BB2KE2 + &3F00) ; r0 = base addr + start location - MOV r1,#1 ; r1 = length of data to read - BL ts_CMOSread ; read the cmos r0 = new checksum. NE = failure; EQ = ok. - BNE %FT22 ; branch if NE - failed to ready at all. - - ; Check the checksum is correct - MOV r8, r0, LSL #24 ; r8 = r0 << 24 : put the checksum value in r8 for displaying. - ANDS r0, r0, #&FF ; r0 = r0 + &FF : If alls ok s/be a zero result ... - MOV r1, #R_CHKFAILBIT ; r1 = checksum fail flag - ADR r4,%BT3 ; Report checksum failure - BNE %FT21 ; failed .. report error - ] ; end ChecksumCMOS - - [ :LNOT: AlwaysShortPOST ; Always do a short post on STBs - LDR r0,=(ts_BB2KE2 + &FC00) ; Read Misc1CMOS byte - MOV r1,#1 - MOV r2,#0 - BL ts_CMOSread - BNE %FT22 - ANDS r0,r0,#&80 ; Test the memory-test-disable bit - BEQ %FT25 - ] - FAULT #R_MEMSKIP ; If set, skip the memory test - B %FT25 - ] -22 - MOV r1,#R_CMSFAILBIT ; Real fault - set the fault bit - ADR r4,%BT2 ; Report fault accessing IIC - ; (Bitmap & POST display) -21 - FAULT r1 - BL ts_SendText ; Report one fault or another -25 - B ts_IOinit - - ] ; DontDoCMOSTest - - LTORG - ROUT -; -; Initialize various machine registers - e.g, turn off the floppy -; drive, etc, etc. -; - -1 - = "IOinit:",0 - ALIGN - -ts_IOinit - ADR r4,%BT1 - BL ts_SendText - ADRL r2,ts_IOinitab -10 - LDR r0,[r2],#4 ; Get address - LDR r1,[r2],#4 ; Get initialization data - CMPS r0,#(-1) - STRNE r1,[r0] ; write to IO port - BNE %10 - B Speedset -; -; Use the RISC OS MEMC setup code to guess the proper processor / memory -; configuration. The memory speed can then be set up correctly for -; fastest possible working, and the memory array tested in the -; configuration RISC OS expects. -; -; Display the results of the TimeCPU test as : -; -; ssss.m.r -; -; where ssss is the processor speed in hex kHz, -; m is 0 for MEMC, 1 for MEMC1a -; r is the MEMC rom speed switch setting. -; - ROUT - -1 - = "Speed :",0 -2 - = "Speed",&88,&ff,&ff,&ff,&ff,".",&ff,".",&ff,0 - - ALIGN - -Speedset - ADR r4,%BT1 - BL ts_SendText - - [ MEMC_Type = "IOMD" - MOV r9,#0 - | - MOV_fiq r0, r11_fiq ; get MEMC setup - MOV r9,r0 ; compare IOC and CPU clocks - ] - - BL TimeCPU - MOV r0,r9 - MOV_fiq r11_fiq,r0 - - MOV r8,r7,LSL #16 - TST r7, #1 :SHL: 16 ; test bit 16 of r7 : - ADDNE r8,r8,#&1000 ; MEMC1 / MEMC1a detected - AND r9,r9,#&C0 ; get High ROM access bits - ADD r8,r8,r9, LSL #2 - ADR r4,%BT2 - BL ts_SendText - B RAMtest - -; -; Long RAM test, ideally exercising all memory. -; In order to keep boot time short, the following scheme is used : -; -; Normal power-on boot - test VRAM and up to 4M of first DRAM entry -; CMOS disable set - test nothing -; Test hardware fitted - test entire memory -; - - ROUT - - -1 - = "RAM :",0 -2 - = "RAM bad",&88,&ff,&ff,&ff,&ff,&ff,&ff,&ff,&ff,0 -3 - = &89,"skipped",0 -4 - = "RAM :",&88,&ff,&ff,&ff,&ff,&ff,&ff,&ff,&ff,0 - - - ALIGN - -RAMtest - [ {TRUE} - B ts_VIDCtest ; skip memory test altogether - | - ADR r4,%BT1 - ] - BL ts_SendText -; -; if (R_MEMSKIP && R_HARD) -; skip all the remaining tests -; if (!R_LINFAILBIT) -; perform the long memory test -; - MOV_fiq r0,r12_fiq ; skip this test if data line fault - AND r1,r0,#(R_MEMSKIP :OR: R_HARD) ; or the user didn't want it - TEQS r1,#(R_MEMSKIP :OR: R_HARD) - ANDNE r1,r1,#R_LINFAILBIT - TEQNE r1,#R_LINFAILBIT - BNE %12 - ADR r4,%BT3 ; skipping memory test .... - BL ts_MoreText - B ts_Report -12 - [ STB :LAND: DontShowProgressColours - MOV_fiq r0,r12_fiq ; restore the faultcode bits - ANDS r0,r0,#(R_EXTERN :OR: R_TESTED) ; If test adapter present, - ; NE : Adaptor fitted, show progress. - ; EQ : No Adaptor fitted, don't show progress - BEQ %FT13 ; EQ : Don't show colours - ] - LDR r1,=C_RAMTEST ; doing at least part of the long memory test - LDR r0,=ts_VIDCPhys ; write the border colour - STR r1,[r0] -13 - BL MemSize ; Set MMU up, mapping (some) RAM at logical address 0 - ; Note that this returns with the MMU enabled, - ; the ROM remapped to it's ORGed address, - ; and r4 the offset from physical to ORGed ROM addresses - ; r4 = ROM - Phys[Ext]ROM - RSB r4, r4, #PhysSpace ; r4 = PhysSpace - ROM + Phys[Ext]ROM, pc = ROM + offset - MODE SVC32_mode ; Must do this, as PhysSpace is outside 26 bit addressing - ADD pc, pc, r4 ; pc = PhysSpace + Phys[Ext]ROM + offset - NOP ; this instruction skipped by pc adjustment - -; -; Modify the PhysRamTable so only VRAM and the first ts_MaxRamTest of DRAM gets tested -; - MOV_fiq r0,r12 ; get the test condition flags - - ANDS r0,r0,#(R_EXTERN :OR: R_TESTED) - BNE %FT16 ; do full test if test adapter is present - MOV r9,#PhysRamTable - ADD r10,r9,#(PhysRamTableEnd-PhysRamTable) -14 - LDR r1,[r9, #4] - ADD r0,r0,r1 ; r0 = running sum of memory sizes - SUBS r2,r0,#ts_MaxRamTest ; r2 = excess over ts_MaxRamTest - SUBHI r1,r1,r2 ; r1 = current size truncated - STRHI r1,[r9, #4] - MOVHI r0,#ts_MaxRamTest ; truncate running sum to MaxRamTest - - ADD r9,r9,#(DRAMPhysAddrB-DRAMPhysAddrA) - CMPS r9,r10 - BNE %BT14 -16 - FAULT #R_MEMORY ; memory tests were attempted - - MOV r9,#VideoPhysAddr - LDR r8,[r9] ; report the test address - ADRL r4,%BT4 - BL ts_SendText - LDR r0,[r9] ; get VRAM start address and size - LDR r1,[r9,#4] - ADD r0,r0,#PhysSpace - BL ts_RamTest - BNE %FT20 ; failed - abort ram testing - -; -; VRAM (or 1st MB of DRAM, if no VRAM fitted) looks OK - move the translation -; table there so memory tests can proceed without smashing it. -; - MOV r9,#PhysRamTable - LDR r0,[r9,#VideoPhysAddr-PhysRamTable] ; get address of video RAM - LDR r1,[r9,#DRAMPhysAddrA-PhysRamTable] ; get address of 1st DRAM bank - LDR r3, =DRAMOffset_L2PT - ADD r1, r1, r3 ; make r1 -> L2PT - ADD r0, r0, r3 ; make r0 -> temporary L2PT - BL ts_remap_ttab ; copy ttab at r1 to r0 and change table base - -; -; Now run the RAM test at each DRAMPhysAddr until the end of the table or a zero entry -; is reached. Mark tested entries by setting the PhysSpace address, so a pointer to the -; next entry need not be kept. -; -18 - MOV r9,#DRAMPhysAddrA - ADD r10,r9,#(PhysRamTableEnd-DRAMPhysAddrA) -19 - CMPS r9,r10 ; reached end of table ? - LDRNE r0,[r9] - TSTNE r0,r0 ; reached unused entries ? - LDRNE r1,[r9,#4] ; or blanked-out entries ? - TSTNE r1,r1 - BEQ %FT21 ; .. all passed OK - TSTS r0,#PhysSpace - ADDNE r9,r9,#(DRAMPhysAddrB-DRAMPhysAddrA) - BNE %BT19 ; this entry done .. find the next - - MOV r8,r0 ; report address of this block - ADRL r4,%BT4 - BL ts_SendText - - LDR r0,[r9] ; start testing it - ADD r0,r0,#PhysSpace - LDR r1,[r9, #4] - STR r0,[r9] ; mark block so it isn't retested - MOV r2,#PhysRamTable - LDMIA r2,{r3-r14} ; save the PhysRamTable - STMIA r0,{r3-r14} - BL ts_RamTest - LDMIA r13,{r1-r11,r14} ; restore the PhysRamTable - MOV r13,#PhysRamTable - STMIA r13,{r1-r11,r14} - BEQ %BT18 ; if it passed, go look for another block - -20 - FAULT #R_MEMFAILBIT ; failed - report fault address - ADRL r4,%BT2 - MOV r11,r1 ; Save failed data - MOV r8,r0 ; first failing address - BL ts_SendText - MOV r4,r12 ; get fault message - MOV r8,r11 ; and fault data - BL ts_SendText -21 - - [ MEMM_Type = "MEMC1" - -; -; Test the CAMs - for each fitted MEMC, go through all the CAM entries -; remapping logical memory and testing against physical correspondence. -; Then try out the protection bits in each CAM entry and various -; processor modes. -; These tests return pointers to their own fault report strings. -; - B ts_CAMtest - ROUT -1 - = "CAMs :",0 -2 - = "PPLs :",0 -3 - = &89,"skipped",0 - ALIGN - -ts_CAMtest - LDR r4,=%BT1 - BL ts_SendText - - MOV_fiq r0,r12_fiq ; skip this test if memory fault - MOV r1,#(R_LINFAILBIT :OR: R_MEMFAILBIT) - ANDS r0,r0,r1 - BEQ %08 - LDR r4,=%BT3 - BL ts_MoreText - B %20 - -08 - BL ts_CAM - BEQ %10 - BL ts_SendText - FAULT #R_CAMFAILBIT -10 - LDR r4,=%BT2 - BL ts_SendText - - MOV_fiq r0,r12_fiq ; skip this test if memory fault - MOV r1,#(R_LINFAILBIT :OR: R_MEMFAILBIT) - ANDS r0,r0,r1 - BEQ %18 - LDR r4,=%BT3 - BL ts_MoreText - B %20 -18 - BL ts_memc_prot - BEQ %20 - BL ts_SendText - FAULT #R_PROFAILBIT -20 - - ] - -; -; After testing memory and translation, turn MMU off again before running remainder -; of tests. This simplifies finishing up (where system must be put back into 26-bit -; mode before initialising RISCOS) if memory tests were deselected. -; Take care to poke the real translation table - it's been relocated to video -; RAM during the memory tests. -; - -ts_restore_physical - - [ StrongARM_POST - ;make sure ARM810 cache or StrongARM data cache is cleaned/flushed, because we are going to remap - ARM_read_ID r5 - AND r5,r5,#&F000 - CMP r5,#&8000 - BNE %FT22 -;ARM810 -;;; ARM8_cleanflush_IDC r5 ;not implemented yet - B %FT24 -22 - CMP r5,#&A000 - BNE %FT24 -;StrongARM -;tricky...we'll read 16k of data in current ROM space, to act as clean and flush of current data - MOV r3,pc - BIC r3,r3,#31 ;32 byte aligned - ARMA_clean_DC r3,r5,r7 -24 - ] ;StrongARM_POST - - MOV r5, pc ; obtain current address - SUB r5, r5,#PhysSpace ; adjust to point to unmapped version - MOV r5, r5, LSR #20 ; divide by 1MB - MOV r7, r5, LSL #20 ; r7 = physical address of base of section - ORR r7, r7, #(AP_None * L1_APMult) - ORR r7, r7, #L1_Section - MOV r3, #VideoPhysAddr ; find the copied translation table - LDR r3, [r3] - ADD r3, r3, #PhysSpace - ADD r3, r3, #DRAMOffset_L1PT - STR r7, [r3, r5, LSL #2] ; store replacement entry in L1 (not U,C or B) - - [ StrongARM_POST - ;flush cache if ARM 6/7 (ARM 8,StrongARM already sorted, above) - ;flush TLB(s) - ARM_read_ID r4 - AND r4,r4,#&F000 - CMP r4,#&8000 ;ARM 8? - CMPNE r4,#&A000 ;or StrongARM? - MCRNE ARM_config_cp,0,R0,ARM67_cacheflush_reg,C0,0 ;flush 6/7 cache - MCRNE ARM_config_cp,0,R0,ARM67_TLBflush_reg,C0,0 ;flush 6/7 TLB - MCREQ ARM_config_cp,0,R0,ARM8A_TLB_reg,C7,0 ;flush 8/StrongARM TLB(s) - | - SetCop r7, CR_IDCFlush ; flush cache + TLB just in case - SetCop r7, CR_TLBFlush ; (data written is irrelevant) - ] - -; The ROM should now be mapped at the present address less PhysSpace, which is where it -; would be if the MMU were turned off. - - MOV r4,#PhysSpace - SUB pc,pc,r4 - NOP ; this instruction is skipped - -; now turn the MMU off, also ensures 26 bit mode, if ARM 6/7 (since P bit zero) - MOV r7, #MMUC_D - SetCop r7, CR_Control - - B ts_VIDCtest - -; -; The VIDC tests check vertical blanking frequency in a fixed video -; mode and measure the time taken for sound DMA. -; - - ROUT - -1 - = "VIDC :",0 -2 - = "Virq bad",&88,' ',&ff,'.',&ff,&ff,&ff,&ff,&ff,0 -3 - = "Sirq bad",&8B,&ff,&ff,&ff,&ff,&ff,0 -4 - = &8A,"Mid0 ",&ff,0 - - ALIGN - -ts_VIDCtest - ADR r4,%BT1 - BL ts_SendText - [ IO_Type = "IOMD" - LDR r0,=IOMD_MonitorType ; Indicate monitor ID bit's value - LDR r0,[r0] - AND r0,r0,#IOMD_MonitorIDMask - MOV r8,r0,LSL #28 - ADR r4,%BT4 - BL ts_MoreText - ] - - [ MorrisSupport - MOV r3, #IOMD_Base - LDRB r1,[r3,#IOMD_ID1] ; load r1 with IOMD ID high byte - LDRB r0,[r3,#IOMD_ID0] ; load r1 with IOMD ID low byte - ORR r0,r0,r1,LSL#8 ; Or r0 and r1, shifted left 8, put in r0 - LDR r1,=ts_IOMD_ID1 ; get Ref IOMD ID code #1 (Original) - CMPS r0,r1 ; check for IOMD ID Code #1 - BNE %FT10 ; If not equal, got to 10 - ; thus skip Virq test on ARM7500 and ARM7500FE (Morris) - ] - - BL ts_VIDC_period - BEQ %10 - ADR r4,%B2 - MOV r8, r0, LSL #8 - BL ts_SendText ; Display Virq fail msg - FAULT #R_VIDFAILBIT -10 - [ IO_Type = "IOMD" - ; RCM thinks this is no longer needed - all IOMD's are issue two - ; besides, the test takes no account of Morris reusing the number space! - ; MOV r3,#IOMD_Base ; skip Sirq test on version 1 IOMD - ; LDRB r0,[r3,#IOMD_VERSION] - ; CMPS r0,#1 - ; BEQ %FT20 - ] - BL ts_SIRQ_period - BEQ %20 - ADR r4,%B3 - MOV r8, r0, LSL #12 - BL ts_SendText ; Display Sirq fail msg - FAULT #R_SNDFAILBIT -20 - MOV r1,#ts_VIDCPhys ; Restore full-screen - ADRL r2,TestVIDCTAB ; border colour. - [ IO_Type = "IOMD" - LDR r0,=IOMD_MonitorType - LDR r0,[r0] - ANDS r0,r0,#IOMD_MonitorIDMask - ADDEQ r2,r2,#(TestVVIDCTAB-TestVIDCTAB) - ] -30 LDR r0, [r2],#4 - CMP r0, #-1 - STRNE r0, [r1] - BNE %BT30 - - [ STB :LAND: DontShowProgressColours - MOV_fiq r0,r12_fiq ; restore the faultcode bits - ANDS r0,r0,#(R_EXTERN :OR: R_TESTED) ; If test adapter present, - ; NE : Adaptor fitted, show progress. - ; EQ : No Adaptor fitted, don't show progress - BEQ ts_ARMtype_test ; EQ : Don't show colours - ] - LDR r0,=C_ARMOK ; set initial screen colour - STR r0, [r1] - - B ts_ARMtype_test - -; -; Read the ARM3 identification register. -; If memory tests failed, this won't be performed since the vector -; page must exist for error recovery on ARM2 systems. -; - - ROUT -1 - = "ARM ID:",0 -2 - = "ARM ID",&88,&ff,&ff,&ff,&ff,&ff,&ff,&ff,&ff,0 -3 - = &89,"skipped",0 - - ALIGN - -ts_ARMtype_test - - ADR r4,%BT1 - BL ts_SendText - - MOV_fiq r0,r12_fiq ; skip this test if memory fault - LDR r1,=((R_LINFAILBIT :OR: R_MEMFAILBIT) :OR: (R_CAMFAILBIT :OR: R_PROFAILBIT)) - ANDS r0,r0,r1 - BEQ %05 - ADR r4,%BT3 - BL ts_MoreText - B %08 ; and quit - -05 - BL ts_ARM_type - MOVS r8, r0 ; ready to display ID code - ADR r4,%BT2 - - BEQ %FT07 ; ARM 2 : skip cache test - FAULT #R_ARM3 ; not really a fault, just status -07 - BL ts_SendText - -08 - B ts_Report - - - -; -; Report the test results to the user -; -; If this was a forced test (test adapter fitted) then pause even when -; test passed : otherwise, pause only on error. -; - -ts_passmsg - = "PASS :",&88,&ff,&ff,&ff,&ff,&ff,&ff,&ff,&ff,0 -ts_failmsg - = "FAIL :",&88,&ff,&ff,&ff,&ff,&ff,&ff,&ff,&ff,0 - -ts_R00 & 00 - - - [ STB :LAND: POSTFlashesFrontPanelLEDs - ; Define Long, Equal and short flash delays -ts_Long_Flash * &03 ; Number of 1/4 Sec delays for a long flash -ts_Short_Flash * &01 ; Number of 1/4 Sec delays for a short flash -ts_Equal_Flash * &02 ; Number of 1/4 Sec delays for a equal flash -ts_Fail_Flash_Delay * &14 ; Number of Flash Cycles for a Fail, with adaptor -ts_Pass_Flash_Delay * &0A ; Number of Flash Cycles for a Pass, with adaptor - -IOMD_LED_GREENLED * IOMD_C_FrontPanelRightLED ; The right LED should be the GREEN LED -IOMD_LED_REDLED * IOMD_C_FrontPanelLeftLED ; The left LED should be the RED LED -IOMD_LED_BOTH * IOMD_LED_REDLED :OR: IOMD_LED_GREENLED ; - - ] ; Endif (POSTFlashesFrontPanelLEDs) - -ts_Report ROUT - MOV_fiq r7,r12_fiq ; check for fault bits set - LDR r0,=R_STATUS - BICS r0,r7,r0 - - ADREQ r4, ts_passmsg ; tests passed - LDREQ r9,=C_PASSED - - ADRNE r4, ts_failmsg ; tests failed - LDRNE r9,=C_FAULT - - LDR r0,=ts_VIDCPhys ; write the border colour - STR r9,[r0] - - MOV r8,r7 - BL ts_SendText ; write the message and fault code - - ; if the test adapter is present, leave green screen awhile - ; otherwise, wait only if there's a fault. - - LDR r3,=ts_recover_time -00 ADDS r3,r3,r3 ; 16-loop delay - BCC %B00 ; - let the adapter recover - ; from previous bus activity - ADR r2,ts_R00 - ORR r2,r2,#ts_Alias_bits - LDR r3,[r2] - MOV r2,#-1 - ADDS r3,r3,r2 - BCS ts_Report_wait - - ; Here is r3 = 0, which ment a DUMP adaptor was present. - ; - ; Continue to the OS - ; - MOV_fiq r0,r12_fiq - LDR r2,=R_STATUS - BICS r0,r0,r2 - BEQ ts_Hardstart - -ts_Report_wait ROUT - ; - ; Here if a Display or other type of adaptor found. - ; - [ STB :LAND: POSTFlashesFrontPanelLEDs - ; - ; Check to see if we are a PASS or FAIL - ; - MOV_fiq r7,r12_fiq ; check for fault bits set - LDR r0,=R_STATUS - BICS r0,r7,r0 - - BEQ ts_flash_leds_pass ; flash the leds to show a pass - ; flash the leds to show a failure - ; Fall through ! - -ts_flash_leds_fail - ; - ; Get here if the POST fails ! - ; - ; Set it so the RED LED is on. - BL ts_led_redon_only ; Ensure that the RED LED only is on, - ; Check for display adpator, if fitted, flash LED's for 20 times - ; else flash LEDs forever. - ; - MOV_fiq r0,r12_fiq ; restore the faultcode bits - ANDS r0,r0,#(R_EXTERN :OR: R_TESTED) ; If test adapter present, - BNE %FT19 ; Adaptor : Goto 20 Flash loops Code - ; No Adaptor : Goto Infinite flash loop Code - ; Fall through ! -14 - ; Infinite Flash loop - ; Register usage .... - ; r0, used by toggle leds & delay routines - ; r1, used by toggle leds routine - ; -15 BL ts_led_fail ; Call code to flash the leds - B %BT15 ; Repeat forever. - -19 - ; Loop for specified time - ; Register usage .... - ; r0, used by toggle leds & delay routines - ; r1, used by toggle leds routine - ; - ; r3, Loop counter - ; r4, Pass delay time to delay code. - ; - MOV r3,#ts_Fail_Flash_Delay ; Set the loop counter. -20 BL ts_led_fail ; Call code to flash the leds - SUBS r3,r3,#1 ; Decrment loop counter - BNE %BT20 ; Repeat until r3 = 0 - BEQ %FT50 ; r3=0, were all done - ; Goto start the OS - -ts_flash_leds_pass - ; Here if POST passed. - ; If adaptor fitted, flash the LEDs for a 10 secs - MOV_fiq r0,r12_fiq ; restore the faultcode bits - ANDS r0,r0,#(R_EXTERN :OR: R_TESTED) ; If test adapter present, - BEQ %FT55 ; No Adaptor : Goto start the OS - ; Adaptor : Goto 10 Flash loops Code - ; Fall through ! - - ; Set it so the RED LED is on. - BL ts_led_redon_only ; Ensure that the RED LED only is on, - ; Loop for specified time - ; Register usage .... - ; r0, used by toggle leds & delay routines - ; r1, used by toggle leds routine - ; - ; r3, Loop counter - ; r4, Pass delay time to delay code. - ; - MOV r3,#ts_Pass_Flash_Delay ; Set the loop counter. -30 BL ts_led_pass ; Call code to flash the leds - SUBS r3,r3,#1 ; Decrment loop counter - BNE %BT30 ; Repeat until r3 = 0 - BEQ %FT50 ; r3=0, were all done - ; Goto start the OS - -ts_led_fail - ; Code to flash the LED's through one flash cycle (on-off) - ; This will take 1 Second to complete. - ; - ;|------>|--1/4 Sec--|--1/4 Sec--|--1/4 Sec--|--1/4 Sec--| - ;|--Red--|---Green---|----Red----|----Red----|----Red----|\ - ; \_______________________________________________/ - ; - ; Red Green - MOV r13,r14 ; make a note of where we On Off - ; came from. - BL tl_Toggle_LEDs ; Toggle the LEDs Off On - MOV r4,#ts_Short_Flash ; Load r4 with Short flash Off On - BL ld_LED_Delay ; call delay routine Off On - BL tl_Toggle_LEDs ; Toggle the LEDs On Off - MOV r4,#ts_Long_Flash ; load r4 with long flash On Off - BL ld_LED_Delay ; call delay routine On Off - - MOV pc,r13 ; move r13 (r14) back to - ; where we came from. - -ts_led_pass - ; Code to flash the LED's through one flash cycle (on-off) - ; This will take 1 Second to complete. - ; - ;|------>|--1/4 Sec--|--1/4 Sec--|--1/4 Sec--|--1/4 Sec--| - ;|--Red--|---Green---|---Green---|---Green---|----RED----|\ - ; \_______________________________________________/ - ; - ; Red Green - MOV r13,r14 ; make a note of where we On Off - ; came from. - BL tl_Toggle_LEDs ; Toggle the LEDs Off On - MOV r4,#ts_Long_Flash ; Load r4 with long flash Off On - BL ld_LED_Delay ; call delay routine Off On - BL tl_Toggle_LEDs ; Toggle the LEDs On Off - MOV r4,#ts_Short_Flash ; load r4 with short flash On Off - BL ld_LED_Delay ; call delay routine On Off - - MOV pc,r13 ; move r13 (r14) back to - ; where we came from. - -ts_led_redon_only - LDR r1, =IOMD_IOLINES ; r1 = addr of IOMD_IOLINES - LDRB r0,[r1] ; load r0 with the byte pointed to by r1 -; DREG r0,"contents of loc->r1" - BIC r0,r0,#IOMD_LED_GREENLED ; Clear GREEN LED bit - ORR r0,r0,#IOMD_LED_REDLED ; Set RED LED bit - ORR r0,r0,#IOMD_C_ReadMask ; OR with the default I/O settings - STRB r0,[r1] ; store a byte of r0 in to loc pointed to by r1 - MOV pc, r14 ; Return to caller - -ts_led_greenon_only - LDR r1, =IOMD_IOLINES ; r1 = addr of IOMD_IOLINES - LDRB r0,[r1] ; load r0 with the byte pointed to by r1 -; DREG r0,"contents of loc->r1" - BIC r0,r0,#IOMD_LED_REDLED ; clear RED LED bit - ORR r0,r0,#IOMD_LED_GREENLED ; Set GREEN LED bit - ORR r0,r0,#IOMD_C_ReadMask ; OR with the default I/O settings - STRB r0,[r1] ; store a byte of r0 in to loc pointed to by r1 - MOV pc, r14 ; Return to caller - -ts_led_bothon - LDR r1, =IOMD_IOLINES ; r1 = addr of IOMD_IOLINES - LDRB r0,[r1] ; load r0 with the byte pointed to by r1 -; DREG r0,"contents of loc->r1" - ORR r0,r0,#IOMD_LED_BOTH ; Set Both Green & RED LED bits - ORR r0,r0,#IOMD_C_ReadMask ; OR with the default I/O settings - STRB r0,[r1] ; store a byte of r0 in to loc pointed to by r1 - MOV pc, r14 ; Return to caller - -ts_led_bothoff - LDR r1, =IOMD_IOLINES ; r1 = addr of IOMD_IOLINES - LDRB r0,[r1] ; load r0 with the byte pointed to by r1 -; DREG r0,"contents of loc->r1" - BIC r0,r0,#IOMD_LED_BOTH ; Clear Both Green & RED LED bits - ORR r0,r0,#IOMD_C_ReadMask ; OR with the default I/O settings - STRB r0,[r1] ; store a byte of r0 in to loc pointed to by r1 - MOV pc, r14 ; Return to caller - - - -50 - ; come here if we've finished showing pass/fail by flashing the LEDs - ; thus a test link or display aaptor was fitted - ; so turn on the LED's - BL ts_led_bothon - -55 - ; come here because we passed, but no display adaptor ot test link, thus LEDs weren't flashed - ; so ........ - ; Continue on our way - ; - | ; else - ; - ; :LNOT: POSTFlashesFrontPanelLEDs - ; Thus we use the old way of flashing the LED etc .... - ; - ; Indicate fault found : Set the border to fault colour and flash - ; the disk LED, using the fault bitmap in r12_fiq to modulate the flashing. - ; - -ts_oldLED_on * &be0000 ; assert SEL0 and INUSE -ts_oldLED_off * &ff0000 ; on machines with 1772 controller -ts_oldLEDaddr * (ts_S5_base :OR: &40) - -ts_710LED_on * &100000 ; assert SEL0 and MotorEN0 -ts_710LED_off * &110000 ; on machines with 82C710 controller -ts_710LEDaddr * (ts_PCaddress :OR: (&3f2 :SHL: 2)) - -ts_665LED_on * &10 ; assert SEL0 and MotorEN0 -ts_665LED_off * &11 ; on machines with 37665 controller - ; and Medusa low-byte I/O world -ts_665LEDaddr * (ts_PCaddress :OR: (&3f2 :SHL: 2)) - -01 - MOV_fiq r6,r12_fiq - LDR r2,=&11111111 - [ :LNOT: STB - LDR r7,=(35000 * 8) ; 1/4 second pause loop count - ] - - [ IO_Type = "IOMD" - LDRNE r1,=ts_665LEDaddr ; set up for Medusa disc address - MOVNE r8,#ts_665LED_on - MOVNE r9,#ts_665LED_off - | - TST r6, #R_IOEB ; determine original / 710 disc controller - LDREQ r1,=ts_oldLEDaddr ; set up for Archimedes disc address - MOVEQ r8,#ts_oldLED_on - MOVEQ r9,#ts_oldLED_off - LDRNE r1,=ts_710LEDaddr ; set up for Brisbane disc address - MOVNE r8,#ts_710LED_on - MOVNE r9,#ts_710LED_off - ] - -02 - [ STB - BL ld_LED_Delay ; call delay routine - - MOV r0,r8 ; turn the LED on - STR r0,[r1] - - BL ld_LED_Delay ; call delay routine - - ADDS r6,r6,r6 ; if a '1' is to be written, - BCC %06 - BL ld_LED_Delay ; call delay routine } - BL ld_LED_Delay ; call delay routine } Half A Second - | - MOV r0,r7 -03 SUBS r0,r0,#1 ; pause for a 1/4 second - BNE %03 - - MOV r0,r8 ; turn the LED on - STR r0,[r1] - - MOV r0,r7 -04 SUBS r0,r0,#1 ; pause for a 1/4 second - BNE %04 - ADDS r6,r6,r6 ; if a '1' is to be written, - BCC %06 - MOV r0,r7,LSL #1 ; then pause another 1/2 second -05 SUBS r0,r0,#1 - BNE %05 - ] -06 - MOV r0, r9 ; turn the LED off - STR r0,[r1] - -; -; Count down 32 bits. Every 4 bits, insert an extra pause to simplify -; reading the flashes. -; - ADDS r2,r2,r2 - BCC %08 - [ STB - BL ld_LED_Delay ; call delay routine } - BL ld_LED_Delay ; call delay routine } One Seconds Worth - BL ld_LED_Delay ; call delay routine } - BL ld_LED_Delay ; call delay routine } - | - MOV r0,r7,LSL #2 ; then pause another second -05 SUBS r0,r0,#1 - BNE %05 - ] -08 - ANDS r2,r2,r2 ; all the bits displayed now ? - BNE %02 - MOV_fiq r0,r12_fiq ; restore the faultcode bits - ] ; Endif (POSTFlashesFrontPanelLEDs) -; - MOV_fiq r0,r12_fiq ; restore the faultcode bits -; Uncomment the following line if the POST code is to loop when the POST -; display adaptor (post box) is fitted. -; -; ANDS r0,r0,#(R_EXTERN :OR: R_TESTED) ; If the display adapter & test link are present, -; -; Comment this line out if POST Code is to loop when the POST display -; adaptor (post box) is fitted. -; - ANDS r0,r0,# R_TESTED ; If the test link is present, - BNE Reset ; repeat the test forever - - B CONT ; otherwise, run RISC OS - -ts_Hardstart - MOVS r0,#R_HARD ; and report a hard start - B CONT ; to RISC OS - -; -; Tests skipped : fall into RISC-OS -; - -ts_Self_test_end - - [ STB :LAND: DontShowProgressColours - MOV_fiq r0,r12_fiq ; restore the faultcode bits - ANDS r0,r0,#(R_EXTERN :OR: R_TESTED) ; If test adapter present, - ; NE : Adaptor fitted, show progress. - ; EQ : No Adaptor fitted, don't show progress - BEQ ts_Softstart ; EQ : Don't show colours - ] - LDR r1,=C_DEFAULT - LDR r0,=ts_VIDCPhys ; write the border colour - STR r1,[r0] - -ts_Softstart - MOVS r0,#R_SOFT ; soft reset indicator - B CONT - -; -; -; - ROUT -; -; This table consists of a series of address/data pairs for IO -; initialization. -; Note that these addresses are likely to be in the IO world, -; and hence the data written is that from the MOST significant -; 16 bits of the data bus. -; An 'address' of -1 terminates the table. -; - -ts_IOinitab - [ IO_Type = "IOMD" - | - & ts_S5_base :OR: &10, &000000 ; Printer port data - & ts_S5_base :OR: &18, &000000 ; FDC control & printer strobes - & ts_S5_base :OR: &40, &ff0000 ; FDD select lines - & ts_S5_base :OR: &48, &000000 ; VIDC clock control - ] - & (-1) - - -; -; -;--------------------------------------------------------------------------- - - LTORG - - -; Include test modules executed by call, rather than inline - - GET TestSrc.Mem2 - GET TestSrc.Mem3 - GET TestSrc.Mem4 - GET TestSrc.Mem5 - GET TestSrc.Vidc - GET TestSrc.Ioc - GET TestSrc.Cmos - GET TestSrc.Arm3 - - ; amg: 7/12/96 Renaissance. Once again I wish AASM could understand conditionals - ; around GETs - - GBLS get_toggleled - GBLS get_leddelay - GBLS get_showiomdrs - [ STB -get_toggleled SETS "GET TestSrc.ToggleLED" -get_leddelay SETS "GET TestSrc.LEDDelay" -get_showiomdrs SETS "GET TestSrc.ShowIOMDRs" - | -get_toggleled SETS "" -get_leddelay SETS "" -get_showiomdrs SETS "" - ] - $get_toggleled - $get_leddelay - $get_showiomdrs - - ALIGN 64 ; JRH: Kernel seems happier if we do this! - - END diff --git a/TestSrc/Cmos b/TestSrc/Cmos deleted file mode 100644 index f95d28e2..00000000 --- a/TestSrc/Cmos +++ /dev/null @@ -1,320 +0,0 @@ -; > TestSrc.Cmos - - TTL RISC OS 2+ POST battery-backed RAM access -; -; A function to read bytes from CMOS, for use in verifying the checksum -; and reading memory test flag & video modes. -;------------------------------------------------------------------------ -; History -; -; Date Name Comment -; ---- ---- ------- -; 05-Apr-91 ArtG Initial version, based on IICMod. -; -; -;------------------------------------------------------------------------ -; -; in: -; R0 = device address (bit 8 - 15 register address ) -; R1 = length of block to read -; R2 = initial sum value -; -; out: R0 = sum of all bytes in block -; R1 - R13 trashed -; - -ts_CMOSread ROUT - - MOV R13,R14 - MOV R8,R2 ; initialise accumulator - MOV R7,R1 ; initialise byte counter - MOV R6,R0 ; stash register address - MOV R2, #IOC - MOV R0, #-1 ; ensure timer is ticking - STRB R0, [R2, #Timer0LL] ; (nonzero in input latch) - STRB R0, [R2, #Timer0LH] - STRB R0, [R2, #Timer0GO] ; load the count registers - BL ts_Start - BEQ %FT30 ; check clock line toggles OK - AND R0, R6, #&FE - BL ts_TXCheckAck ; transmit device address (write) - BVS %FT30 - MOV R0, R6, LSR #8 - BL ts_TXCheckAck ; write register address - BVS %FT30 - BL ts_Start ; Extra START bit to switch modes - AND R0, R6, #&FE - ORR R0, R0, #1 - BL ts_TXCheckAck ; transmit device address (read) - BVS %FT30 -20 - BL ts_RXByte ; read byte from bus - ADD R8, R8, R0 ; accumulate total - SUBS R7, R7, #1 ; is it last byte ? - MOVNE R0, #0 ; no, then acknowledge with 0 bit - MOVEQ R0, #1 ; yes, then don't acknowledge - BL ts_ClockData ; but always send ack clock pulse - TEQ R7, #0 ; loop, until last byte - BNE %BT20 -30 - MOVVS R7, #-1 ; pass error indicator to caller - BL ts_Stop - MOV R0, R8 - TEQ R7, #0 ; return zero flag if read OK - MOV PC,R13 - -; ***************************************************************************** -; -; TXCheckACK - transmit a byte and wait for slave to ACK -; -; out: Trashes r0,r1,r2,r3,r4,r5,r9,r10,r11,r12 -; V bit set on error. -; - -ts_TXCheckAck ROUT - MOV R12,R14 - BL ts_TXByte - BL ts_Acknowledge - MOV PC, R12 - -; ***************************************************************************** -; -; SetC1C0 - Set clock and data lines to values in R1 and R0 respectively -; -; out: Trashes r0,r1,r2,r11 -; - -ts_SetC1C0 ROUT - MOVS R11, R14 ; NE: indicate not checking clock -ts_SetOrCheck - MRS R14, CPSR - ORR R14, R14, #I32_bit ; disable interrupts - MSR CPSR_c, R14 - - ADD R0, R0, R1, LSL #1 ; R0 := C0 + C1*2 - - ORR R0, R0, #&C0 ; make sure two test bits are - ; always set to 1 ! - MOV R2, #IOC - STRB R0, [R2, #IOCControl] -10 - LDREQB R1, [R2, #IOCControl] ; wait for clock - TSTEQ R1, #i2c_clock_bit ; to read high - BEQ %BT10 - - MOV R0, #10 ; delay for >= 10/2 microsecs -; -; in-line do-micro-delay to save a stack level -; - STRB R0, [R2, #Timer0LR] ; copy counter into output latch - LDRB R1, [R2, #Timer0CL] ; R1 := low output latch -20 - STRB R0, [R2, #Timer0LR] ; copy counter into output latch - LDRB R14, [R2, #Timer0CL] ; R14 := low output latch - TEQ R14, R1 ; unchanged ? - MOVNE R1, R14 ; copy anyway - BEQ %BT20 ; then loop - SUBS R0, R0, #1 ; decrement count - BNE %BT20 ; loop if not finished -; -; end do-micro-delay -; - MOV PC, R11 - -; Set clock and data lines to R1 and R0 and then wait for clock to be high - -ts_SetC1C0CheckClock ROUT - MOV R11, R14 - CMP R0, R0 ; EQ: indicate checking clock - B ts_SetOrCheck - - -; ***************************************************************************** -; -; ClockData - Clock a bit of data down the IIC bus -; -; in: R0 = data bit -; -; out: Trashes r0,r1,r2,r3,r10,r11 -; - -ts_ClockData ROUT - MOV R10,R14 - - MOV R3, R0 ; save data - MOV R1, #0 ; clock LO - BL ts_SetC1C0 - - MOV R1, #1 ; clock HI - MOV R0, R3 - BL ts_SetC1C0CheckClock - -; Delay here must be >= 4.0 microsecs - - MOV R1, #0 ; clock LO - MOV R0, R3 - BL ts_SetC1C0 - - MOV PC,R10 - -; ***************************************************************************** -; -; Start - Send the Start signal -; -; out: Trashes r0,r1,r2,r9,r11 -; R0 (and Z flag) indicates state of clock .. should be NZ. -; - -ts_Start ROUT - MOV R9,R14 - - MOV R0, #1 ; clock HI, data HI - MOV R1, #1 - BL ts_SetC1C0 - -; Delay here must be >= 4.0 microsecs - - MOV R0, #0 ; clock HI, data LO - MOV R1, #1 - BL ts_SetC1C0 - -; Make sure clock really is high (and not shorted to gnd) - - LDRB R3, [R2, #IOCControl] - -; Delay here must be >= 4.7 microsecs - - MOV R0, #0 ; clock LO, data LO - MOV R1, #0 - BL ts_SetC1C0 - - ANDS R0, R3, #i2c_clock_bit - MOV PC,R9 - -; ***************************************************************************** -; -; Acknowledge - Check acknowledge after transmitting a byte -; -; out: Trashes r0,r1,r2,r3,r9,r11 -; V=0 => acknowledge received -; V=1 => no acknowledge received -; - -ts_Acknowledge ROUT - MOV R9,R14 - - MOV R0, #1 ; clock LO, data HI - MOV R1, #0 - BL ts_SetC1C0 - - MOV R0, #1 ; clock HI, data HI - MOV R1, #1 - BL ts_SetC1C0CheckClock - -; Delay here must be >= 4.0 microsecs - - MOV R2, #IOC - LDRB R3, [R2, #IOCControl] ; get the data from IOC - - MOV R0, #1 ; clock LO, data HI - MOV R1, #0 - BL ts_SetC1C0 - - TST R3, #1 ; should be LO for correct acknowledge - MRS R3, CPSR - BICEQ R3, R3, #V_bit ; clear V if correct acknowledge - ORRNE R3, R3, #V_bit ; set V if no acknowledge - MSR CPSR_f, R3 - - MOV PC,R9 - -; ***************************************************************************** -; -; Stop - Send the Stop signal -; -; out: Trashes r0,r1,r2,r9,r11 -; - -ts_Stop ROUT - MOV R9,R14 - - MOV R0, #0 ; clock HI, data LO - MOV R1, #1 - BL ts_SetC1C0 - -; Delay here must be >= 4.0 microsecs - - MOV R0, #1 ; clock HI, data HI - MOV R1, #1 - BL ts_SetC1C0 - - MOV PC,R9 - -; ***************************************************************************** -; -; TXByte - Transmit a byte -; -; in: R0 = byte to be transmitted -; -; out: Trashes r0,r1,r2,r3,r4,r5,r9,r10,r11 -; - -ts_TXByte ROUT - MOV R9, R14 - MOV R4, R0 ; byte goes into R4 - MOV R5, #&80 ; 2^7 the bit mask -10 - ANDS R0, R4, R5 ; zero if bit is zero - MOVNE R0, #1 - BL ts_ClockData ; send the bit - MOVS R5, R5, LSR #1 - BNE %BT10 - MOV PC, R9 - -; ***************************************************************************** -; -; RXByte - Receive a byte -; -; out: R0 = byte received -; Trashes r1,r2,r3,r4,r9,r11 -; - -ts_RXByte ROUT - MOV R9, R14 - MOV R3, #0 ; byte:=0 - MOV R2, #IOC - MOV R4, #7 - - MOV R0, #1 ; clock LO, data HI - MOV R1, #0 - BL ts_SetC1C0 -10 - MOV R0, #1 ; pulse clock HI - MOV R1, #1 - BL ts_SetC1C0CheckClock - - LDRB R1, [R2, #IOCControl] ; get the data from IOC - AND R1, R1, #1 - ADD R3, R1, R3, LSL #1 ; byte:=byte*2+(IOC?0)AND1 - - MOV R0, #1 ; return clock LO - MOV R1, #0 - BL ts_SetC1C0 - - SUBS R4, R4, #1 - BCS %BT10 - - MOV R0, R3 ; return the result in R0 - MOV PC, R9 - - LTORG - - END - - - - - - - - diff --git a/TestSrc/ErrorCount,ffb b/TestSrc/ErrorCount,ffb deleted file mode 100644 index 67416ed54affe43f7d6da26f59bbaeac2176b027..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2403 zcmaJ?O^j1j6n<@nXfzk)N00>d@SHccOsCTs2O=FhG7N(jp@TC;#D(Oxy=`B3eYd{* zN~fsA7<Hj6T%ZdV#sv#?;lj9Jp~ko{EYKJiE{qTiMiLT@kS>f1^*gU+sKGdknRm}Q z_dDnNzVqG)%Sv}?PB%M&TdRjOnaO16pe!po;FbeTMOCi*+S9cTHNCR1tW{n7n(xwn zx2$}lD%A2TDxk2gXtpWK_|wm%=qVK#SNk-X&QO92?0(8lP6K3bmpZyd4cQ@Ihtx6( zD6XNZ>nT#pWz`JH^{K2IP0y7+MrylZJ?hlQNdsl9OGo-Bx)e%Wkhs$9kgg7vk_>MQ zKh-7vsfS@RJ3iiSx6?8jJgtM;xYwg)#`ovv<_k;nV;KI%#eA0z`JOU{0`*+W4M4us zA=$)uWm&?|o@|p2NY(;{T&Q{ccHoAtUrUkE)vzrC1+>SyRB=rhxTRM3F9rL&2r3K~ zKtt)1J-bBtC7X87F6Ea}fGKq8aK8BX!l5D^o?Tp=Efn+fOSG^^a|?w%`C@*dfYV-@ zEgYdI@`XJqQqT`xspV$CEHJ9e+Nuf*33f}0Em(1os;J<zX{xeYb;}^=*IKfssHTsr zzy~jCs-WQ-_Ss;_3V?>Y<hczulwlOSxgP_r@fO{&rb{#PL7;;<-ST12`XOQ6zpqP0 z-hx)>dT!XEGMH=M>rhGYid1?_a17m*XE2=%sV<Kzq?J#lmh1H@gq48GCVjxv=5z%V zRLC}9HPEVIYAwSwVA1o%#Y6Kirit<)NzZ6_3q>G~&(wuAIRiSn9FgIjlGN0$A3{c$ z>*+Q%R6_?HvgdgDD-oaFxNywaP<7{hw}c(a(a7FCj|gio_#S++%biVKx0#J1ztt!K zoVV9)U=9UXQmhh{7?#^|T~7gUH$Cc2X`qg<o&g|eaY-?dzVT$JqM;H;4;i&Mm83vJ zTOZJoz5N<k#VZ={K9;qAT=}l@L$4#O$^vxM(W`2r{ea?(?#ZC0Oo&OVia!CEqeE4R z^$!&7mX!jC@J7(?R<*i-b*VxvVfi4veE;>MZ5<p-+$v5|STC=-B&<^?dwcB#>K8&} z2dVcE{cv@uRdsS(I3%o3Ca=JCoHO()Wm04pG?|X6E7|O;1`#8#%j}OWtk3V}n>oI; zWo$}V=aSdRUUE+;*1RvVp%HufB-c&bpcN{Ei{EXGmdD8@I59Sr9G~2dZ^Mr}u27<v z*@{4tcFyolpny*GXNu7I8wX_#UVJDEyk8zdV^*nW_khPHOZIdRQdqx(^Pgg6W)U0O zRFXzHIS!59XuNH^h^-zHv3pYh#U~iX9Mp!tb921$_=_cYkk1Etde|anqds-_Me?2g z{7DhpzTqOKj}#le8Qrz^BC9!2w-1q~HUp6&(4M{LG8Ng2v%MG18JiHX`Wot$7M*0S z=!jUbiMS^pBPLt$xOEE6U)W5&Hk@L5QD$=6cH~}rfaps9+DwLCSt-Qfl!(1K%G_2a zXMi&&RG=fTM!5mQjB=NEZX-G`VrMqqa>IrwA0hj-h@D;atB8FGO6S*I=hvdI#n=P@ zzDM}de=)uK|1););*PtV+{lj14iWnc)kN1;v`O_e!Nw)*X%WADpn6Kg*Cu<_sgscr zAUJI&DK~>n8DuTun<E185fF%HhD1EO>L(H3gNMQzyiO69hFr$m6o2~8tF-K-I*y2! z)?LP9WE>}9Tin|~beTF%ZrK@~fT0{0@#7;rMr1_C!LG9-00VGaHt_^BAisne(EfFv z;WYPu7yaMo*ZE&%AK!cKbdNqDQqej^*FRm4cn_FGiDF-EL2QL7*WWxv1>bH$L8MKT zjGm&z4?Mun7~r?*3v>qmb`#P`X0OWOtQ^kScJ|y`^r&=Z9-iQ{93K5Ffnzc&ozdJx u_M0q1BL2rtT#fc=;O+|6l@H|b%(hH6_k|ozZObG_?Q}YAXWxkK{{0Ukq3LA+ diff --git a/TestSrc/ExtCmd b/TestSrc/ExtCmd deleted file mode 100644 index c465802b..00000000 --- a/TestSrc/ExtCmd +++ /dev/null @@ -1,1019 +0,0 @@ -; > TestSrc.ExtCmd - - TTL RISC OS 2+ POST external commands -; -; External test commands for RISC OS ROM. -; -; Provides functions to read data, write data and execute code using -; parameters from an external controlling host. -; -; A minimal set of opcodes should be used (ideally, only B, LDR and ADDS) -; so that a processor test may be validly included in the internal test -; sequence. -; -;------------------------------------------------------------------------ -; History -; -; Date Name Comment -; ---- ---- ------- -; 27-Nov-89 ArtG Initial version -; 06-Dec-89 ArtG Release 0.2 for integration -; 30-Mar-90 ArtG Added NOPs (ADDS r0,r0,r0) after ADDS pc,.. -; 19-Apr-90 ArtG Speedups for read/write commands. -; 15-May-90 ArtG Fixed multiple %13 label in ts_W_FIW -; 22-May-90 ArtG Fixed bugs in ts_B_MWW, ts_W_RIB -; 18-Jun-93 ArtG Added Arm600 control instructions -; 1-Jul-93 ArtG Replaced ADDS pc.. instructions with ADD pc.. -; for compatibility with SVC32_mode. -; -;------------------------------------------------------------------------ - - - -; -; All these routines use registers as follows : -; -; r0 - always zero -; r1 -; r2 -; r3 - undisturbed : used as constant by I/O routine -; r4 - return value from I/O routine, parameter to I/O routines -; r5 -; r6 -; r7 - saved value of command byte on entry -; r8 - operation counter -; r9 - pointer to data transfer operation -; r10 - increment value (0, 1 or 4) to add to pointer in r9 -; r11 - decrement constant (-1) to add to counter in r8 -; r12 - checksum accumulator -; r13 - pointer to operation code -; r14 - return address for calls to I/O routines -; - - SUBT External command handlers -; -; Called by vectoring through command_table. -; R4 contains command byte (including 3 option bits) -; Get operation count -; Get address -; If single-word data -; Get data -; Get checksum -; Reply with command byte or FF -; Do operation -; Else -; For each word -; Get data -; Do operation -; Get checksum -; Reply with command byte or FF -; Return by branching to GetCommand. - -ts_write_memory ROUT - - ADDS r13,r0,r4 ; save the control byte - ADDS r7,r0,r4 - ADDS r14, r0, pc ; setup return address for .. - B ts_GetWord ; .. get operation count word - ADDS r8, r0, r4 ; r8 is operation count - ADDS r12,r0,r4 ; initialise checksum - ADDS r14, r0, pc - B ts_GetWord ; r9 is initial target address - ADDS r9, r0, r4 - ADDS r12,r12,r4 ; accumulate checksum - ADDS r10,r0,r0 ; set initial constants - LDR r11,%01 - ADD pc,pc,r0 -01 - DCD (0 - 1) - -; -; Check for operations which don't involve reading a block of data. -; These are acknowledged BEFORE performing the operation. -; - ADDS r0,r0,r0 - ADDS r13,r13,r13 ; convert operation code to vector - ADDS r13,r13,r13 - LDR r4, %02 - ADD pc,pc,r0 -02 - & (ts_write_cmd_table - %03) - ADDS r4,pc,r4 - ADDS r13,r4,r13 -03 - LDR r13,[r13] ; fetch pointer to code - LDR r4,%04 - ADD pc,pc,r0 -04 - & (ts_write_cmd_table - ts_W_fetch_operations) - ADDS r0,r0,r0 - ADDS r4,r4,r13 - BCS ts_Write_getdata ; defer acknowledgement till later - - ; check the above test was valid, given code layout - ; Note - this is also required by code near ts_Write_cmd_done - - ASSERT (ts_W_RSW < ts_W_fetch_operations) - ASSERT (ts_W_RSB < ts_W_fetch_operations) - ASSERT (ts_W_RIW < ts_W_fetch_operations) - ASSERT (ts_W_RIB < ts_W_fetch_operations) - ASSERT (ts_W_FSW >= ts_W_fetch_operations) - ASSERT (ts_W_FSB >= ts_W_fetch_operations) - ASSERT (ts_W_FIW >= ts_W_fetch_operations) - ASSERT (ts_W_FIB >= ts_W_fetch_operations) - -; -; Fetch the first data word and checksum, and acknowledge -; - - ADDS r14,r0,pc ;get next data word - B ts_GetWord - ADDS r12,r12,r4 ;accumulate checksum - ADDS r10,r0,r4 - ADDS r14,r0,pc - B ts_GetWord ;read transmitted checksum - ADDS r4,r4,r12 ;tx + total should be zero - LDR r5,%05 - ADD pc,pc,r0 -05 - & (0 - 1) - ADDS r5,r5,r4 ;carry set on checksum failure - BCS ts_cmd_error - -; -; Checksum looks OK. Send the command and the checksum back. -; - LDR r4,%06 - ADD pc,pc,r0 -06 - & ts_WriteCmdByte - ADDS r4,r4,r7 ;restore the original - - ADDS r14,r0,pc - B ts_SendByte - ADDS r4,r0,r12 ;then send the calculated checksum - ADDS r14,r0,pc - B ts_SendWord - - ADDS r4,r0,r10 ;restore the data word - ADDS r10,r0,r0 ;and the zero in r10 - B ts_Write_usedata ;dive off to do the work - -; -; Enter the main loop, repeating the operation labelled in r13. -; - -ts_Write_getdata - ADDS r9,r9,r10 ;perform increment operation - ADDS r8,r8,r11 ;countdown repeat counter - BCC ts_Write_cmd_ack - ADDS r14,r0,pc ;get next data word - B ts_GetWord - ADDS r12,r12,r4 ;accumulate checksum - B %07 - -ts_Write_usedata - ADDS r9,r9,r10 ;perform increment operation -ts_Write_count - ADDS r8,r8,r11 ;countdown repeat counter - BCC ts_Write_cmd_done -07 - ADD pc,pc,r13 ;jump back to operations - & 0 - -; -; In this table, the operation after any word fetch is vectored by -; the 3 least significant bits of the command byte to perform some -; combination of writing with : -; -; bit 2 -> 0 R : repeat with same data -; 1 F : fetch more data for next operation -; -; bit 1 -> 0 S : leave address static -; 1 I : increment address after operation -; -; bit 0 -> 0 W : word operation -; 1 B : byte operation -; - - ASSERT ((ts_write_cmd_table - %07) = 8) - -ts_write_cmd_table - - DCD (ts_W_RSW - ts_write_cmd_table) - DCD (ts_W_RSB - ts_write_cmd_table) - DCD (ts_W_RIW - ts_write_cmd_table) - DCD (ts_W_RIB - ts_write_cmd_table) - DCD (ts_W_FSW - ts_write_cmd_table) - DCD (ts_W_FSB - ts_write_cmd_table) - DCD (ts_W_FIW - ts_write_cmd_table) - DCD (ts_W_FIB - ts_write_cmd_table) - -; -; And here are the trailers that perform these operations. -; Each is started with the data in r4, address in r9 and completes -; by returning to Write_getdata (to read another word) or Write_usedata -; (to repeat with the same data) with r10 = increment value (initially 0) -; - -ts_W_RSW - STR r4,[r9] ;store word, repeat address - ADDS r8,r8,r11 ;countdown repeat counter - BCS ts_W_RSW - B ts_Write_cmd_done - -ts_W_RSB - STRB r4,[r9] ;store byte, repeat address - ADDS r8,r8,r11 - BCS ts_W_RSB - B ts_Write_cmd_done - -ts_W_RIW - LDR r10,%11 - ADD pc,pc,r0 -11 - DCD 4 -12 - STR r4,[r9] ;store word, increment word address - ADDS r9,r9,r10 ;perform increment operation - ADDS r8,r8,r11 ;countdown repeat counter - BCS %B12 - B ts_Write_cmd_done - - -ts_W_RIB - LDR r10,%13 - ADD pc,pc,r0 -13 - DCD 1 -14 - STRB r4,[r9] ;store byte, increment byte address - ADDS r9,r9,r10 - ADDS r8,r8,r11 - BCS %B14 - B ts_Write_cmd_done - - - -ts_W_fetch_operations ;all past here fetch new data - ;on each loop - -ts_W_FSW - STR r4,[r9] ;store word, repeat address - B ts_Write_getdata - -ts_W_FSB - STRB r4,[r9] ;store byte, repeat address - B ts_Write_getdata - -ts_W_FIW - STR r4,[r9] ;store word, increment word address - LDR r10,%15 - B ts_Write_getdata -15 - DCD 4 - -ts_W_FIB - STRB r4,[r9] ;store byte, increment byte address - LDR r10,%16 - B ts_Write_getdata -16 - DCD 1 - - -; -; Operations completed. Operations that read multiple data words from -; the host must now checksum and acknowledge the block (even though -; it's a bit late to do anything about it) -; - -ts_Write_cmd_ack -; -; Operation involved multiple fetches - only now ready to ACK. -; - ADDS r14,r0,pc - B ts_GetWord ;read transmitted checksum - ADDS r4,r4,r12 ;tx + total should be zero - LDR r5,%25 - ADD pc,pc,r0 -25 - & (0 - 1) - ADDS r5,r5,r4 ;carry set on checksum failure - BCS ts_cmd_error - -; -; Checksum looks OK. Send the command and the checksum back. -; - LDR r4,%26 - ADD pc,pc,r0 -26 - & ts_WriteCmdByte - ADDS r4,r4,r7 ;restore the original - ADDS r14,r0,pc - B ts_SendByte - ADDS r4,r0,r12 ;then send the calculated checksum - ADDS r14,r0,pc - B ts_SendWord - -ts_Write_cmd_done - B ts_GetCommand - - - -; Called by vectoring through command_table. -; R4 contains command byte (including 3 option bits) -; Get operation count -; Get address -; Reply with command byte or FF -; Reply with checksum -; For each word -; Read data -; If Verbose option -; Send data -; If Quiet option -; Send result of read operation -; Send checksum of result packet -; Return by branching to GetCommand. - -ts_read_memory ROUT - - ADDS r13,r0,r4 ; save the control byte - ADDS r7,r0,r4 - - ADDS r14, r0, pc ; setup return address for .. - B ts_GetWord ; .. get operation count word - ADDS r8, r0, r4 ; r8 is operation count - ADDS r12,r0,r4 ; initialise checksum - - ADDS r14, r0, pc - B ts_GetWord ; r9 is initial target address - ADDS r9, r0, r4 - ADDS r12,r12,r4 ; accumulate checksum - ADDS r10,r0,r0 ; set initial constants - LDR r11,%01 - ADD pc,pc,r0 -01 - DCD (0 - 1) -; -; Convert the operation options into a code pointer -; - ADDS r0,r0,r0 - ADDS r13,r13,r13 ; convert operation code to vector - ADDS r13,r13,r13 - LDR r4, %02 - ADD pc,pc,r0 -02 - & (ts_read_cmd_table - %03) - ADDS r4,pc,r4 - ADDS r13,r4,r13 -03 - LDR r13,[r13] ; fetch pointer to code - -; -; Fetch the checksum, and acknowledge -; - - ADDS r14,r0,pc - B ts_GetWord ;read transmitted checksum - ADDS r4,r4,r12 ;tx + total should be zero - LDR r5,%05 - ADD pc,pc,r0 -05 - & (0 - 1) - ADDS r5,r5,r4 ;carry set on checksum failure - BCS ts_cmd_error - -; -; Checksum looks OK. Send the command and the checksum back. -; - LDR r4,%06 - ADD pc,pc,r0 -06 - & ts_ReadCmdByte - ADDS r4,r4,r7 ;restore the original - ADDS r14,r0,pc - B ts_SendByte - ADDS r4,r0,r12 ;then send the calculated checksum - ADDS r14,r0,pc - B ts_SendWord - - ADDS r12,r0,r0 ;initialise the upload checksum - B ts_Read_count ;enter the loop - -; -; Enter the main loop, repeating the operation labelled in r13. -; This loop is for operations that finish with all data sent - -ts_Read_Txdata ;send data to host - ADDS r12,r12,r4 ;accumulate the checksum - ADDS r14,r0,pc - B ts_SendWord ;send this word - ADDS r9,r9,r10 ;perform increment operation - ADDS r8,r8,r11 ;countdown repeat counter - BCC ts_Read_cmd_done - B %07 ;go off to the jump handler - -ts_Read_count - ADDS r8,r8,r11 ;countdown repeat counter - BCC ts_Read_cmd_read ;send data at finish -07 - ADD pc,pc,r13 ;jump back to operations - & 0 - -; -; In this table, the operation after any word fetch is vectored by -; the 2 least significant bits of the command byte to perform some -; combination of reading with : -; -; bit 2 -> 0 Q : read data without reporting it -; 1 V : Transmit the result of every read operation -; -; bit 1 -> 0 S : leave address static -; 1 I : increment address after operation -; -; bit 0 -> 0 W : word operation -; 1 B : byte operation -; - - ASSERT ((ts_read_cmd_table - %07) = 8) - -ts_read_cmd_table - - DCD (ts_R_QSW - ts_read_cmd_table) - DCD (ts_R_QSB - ts_read_cmd_table) - DCD (ts_R_QIW - ts_read_cmd_table) - DCD (ts_R_QIB - ts_read_cmd_table) - DCD (ts_R_VSW - ts_read_cmd_table) - DCD (ts_R_VSB - ts_read_cmd_table) - DCD (ts_R_VIW - ts_read_cmd_table) - DCD (ts_R_VIB - ts_read_cmd_table) - -; -; And here are the trailers that perform these operations. -; Each is started with the data in r4, address in r9 and completes -; by returning to Write_getdata (to read another word) or Write_usedata -; (to repeat with the same data) with r10 = increment value (initially 0) -; - -ts_R_QSW - LDR r4,[r9] ;read word, repeat address - ADDS r8,r8,r11 ;countdown repeat counter - BCS ts_R_QSW - B ts_Read_cmd_read ;send data at finish - - -ts_R_QSB - LDRB r4,[r9] ;read byte, repeat address - ADDS r8,r8,r11 - BCS ts_R_QSB - B ts_Read_cmd_read - -ts_R_QIW - LDR r10,%11 - ADD pc,pc,r0 -11 - DCD 4 -12 - LDR r4,[r9] ;read word, increment word address - ADDS r9,r9,r10 ;perform increment operation - ADDS r8,r8,r11 ;countdown repeat counter - BCS %B12 - B ts_Read_cmd_read ;send data at finish - - -ts_R_QIB - LDR r10,%13 - ADD pc,pc,r0 -13 - DCD 1 -14 - LDRB r4,[r9] ;read byte, increment byte address - ADDS r9,r9,r10 ;perform increment operation - ADDS r8,r8,r11 ;countdown repeat counter - BCS %B14 - B ts_Read_cmd_read ;send data at finish - - -ts_R_VSW - LDR r4,[r9] ;read and tx word, repeat address - B ts_Read_Txdata - -ts_R_VSB - LDRB r4,[r9] ;read and tx byte, repeat address - B ts_Read_Txdata - -ts_R_VIW - LDR r4,[r9] ;read and tx word, next word address - LDR r10,%15 - B ts_Read_Txdata -15 - DCD 4 - -ts_R_VIB - ADDS r0,r0,r0 - LDRB r4,[r9] ;read and tx byte, next byte address - LDR r10,%16 - B ts_Read_Txdata -16 - DCD 1 - - -; -; Operations completed. Report final result and checksum back to host. -; Quiet option only transmits read data here (this is pretty useless -; except where only one value was read) -; - -ts_Read_cmd_read - ADDS r12,r12,r4 - ADDS r14,r0,pc ;send result of 'quiet' read - B ts_SendWord -ts_Read_cmd_done - SUBS r4,r0,r12 ;get overall checksum - can't think - ADDS r14,r0,pc ;how to do this using only ADDS ! - B ts_SendWord - - B ts_GetCommand - - -; Called by vectoring through command table. -; if option 1 set, read processor mode -; Read address -; Read and check checksum -; Reply with command byte or FF -; Reply with checksum -; if option 1 set, load SPSR -; Jump to code - - -ts_execute ROUT - ADDS r12,r0,r0 ; initialise checksum adder - LDR r8,%00 ; initialise msr-jumper - ADD pc,pc,r0 -00 - & 4 - ADDS r7,r4,r4 ; get operation type - ADDS r7,r7,r7 - ADD pc,pc,r7 ; jump to pc + (r4 * 4) - & 0 - - B %FT10 - B %FT08 - B %FT10 - B %FT10 - B %FT10 - B %FT10 - B %FT10 - B %FT10 - - -08 ADDS r14,r0,pc ; get new processor mode - B ts_GetWord - ADDS r12,r0,r4 - ADDS r8,r0,r0 ; kill msr-jumper -10 - ADDS r14,r0,pc - B ts_GetWord ; get jump address - ADDS r9,r12,r4 - ADDS r14,r0,pc - B ts_GetWord ; get checksum - ADDS r4,r4,r9 - LDR r5,%11 - ADD pc,pc,r0 -11 - & (0 - 1) - ADDS r4,r5,r4 ; compare total chex with zero - BCS ts_cmd_error ; carry set on error - - LDR r4,%12 - ADD pc,pc,r0 -12 - & ts_ExecuteCmdByte - ADDS r0,r0,r0 - ADDS r14,r0,pc ; echo command byte - B ts_SendByte - ADDS r4,r0,r9 ;return checksum (actually, the - ADDS r14,r0,pc ; entire message ..) - B ts_SendWord - - -; Now jump to the location given in the message, using the given status bits - - ADD pc,pc,r8 ; jump over the msr instruction - NOP - MSR SPSR_cf,R12 - - ADDS r14,pc,r0 ; Load the address of %13 into r14 - ; to provide a return address - ADD pc,r0,r9 ; Do the jump -13 - B ts_GetCommand - - - -; Called by vectoring through command table -; Read operation count -; Read target addresses -; Read data -; Send command byte or FF -; Send checksum -; For all operation count -; write data -; if read-back option -; read data -; Return by branching to GetCommand - - -ts_bus_exercise ROUT - ADDS r7,r0,r4 ; save the control byte - - ADDS r14, r0, pc ; setup return address for .. - B ts_GetWord ; .. get operation count word - ADDS r8, r0, r4 ; r8 is operation count - ADDS r12,r0,r4 ; initialise checksum - - ADDS r14, r0, pc - B ts_GetWord ; r9 is first target address - ADDS r9, r0, r4 - ADDS r12,r12,r4 ; accumulate checksum - ADDS r14, r0, pc - B ts_GetWord ; r10 is second target address - ADDS r10, r0, r4 - ADDS r12,r12,r4 ; accumulate checksum - - ADDS r14, r0, pc - B ts_GetWord ; r11 is first data word - ADDS r11, r0, r4 - ADDS r12,r12,r4 ; accumulate checksum - ADDS r14, r0, pc - B ts_GetWord ; r13 is second data word - ADDS r13, r0, r4 - ADDS r12,r12,r4 ; accumulate checksum - -; -; Fetch the checksum, and acknowledge -; - - ADDS r14,r0,pc - B ts_GetWord ;read transmitted checksum - ADDS r4,r4,r12 ;tx + total should be zero - LDR r5,%05 - ADD pc,pc,r0 -05 - & (0 - 1) - ADDS r5,r5,r4 ;carry set on checksum failure - BCS ts_cmd_error - -; -; Checksum looks OK. Send the command and the checksum back. -; - LDR r4,%06 - ADD pc,pc,r0 -06 - & ts_BusExCmdByte - ADDS r4,r4,r7 ;restore the original - ADDS r14,r0,pc - B ts_SendByte - ADDS r4,r0,r12 ;then send the calculated checksum - ADDS r14,r0,pc - B ts_SendWord - - ADDS r12,r0,r13 ; Now addresses are in r9, r10 - ; and data in r11, r12. -; -; Convert the operation options into a code pointer -; - ADDS r13,r7,r7 ; convert operation code to vector - ADDS r13,r13,r13 - LDR r4, %02 - ADD pc,pc,r0 -02 - & (ts_busex_cmd_table - %03) - ADDS r4,pc,r4 - ADDS r13,r4,r13 -03 - LDR r13,[r13] ; fetch pointer to code - LDR r7, %04 ; set up decrementer in r8 - ADD pc,pc,r0 -04 - DCD (0 - 1) -07 - ADD pc,pc,r13 ; jump to operation - & 0 - -; -; In this table, the operation after any word fetch is vectored by -; the 3 least significant bits of the command byte to perform some -; combination of writing with : -; -; bit 2 -> 0 S : Perform separate data write ops -; 1 M : Use STM / LDM instructions -; -; bit 1 -> 0 R : Perform only read operations -; 1 W : Write before reading -; -; bit 0 -> 0 W : word operation -; 1 B : byte operation -; -; Note that byte and multiple operations are mutually -; exclusive. -; - - ASSERT ((ts_busex_cmd_table - %07) = 8) - -ts_busex_cmd_table - - DCD (ts_B_SRW - ts_busex_cmd_table) - DCD (ts_B_SRB - ts_busex_cmd_table) - DCD (ts_B_SWW - ts_busex_cmd_table) - DCD (ts_B_SWB - ts_busex_cmd_table) - DCD (ts_B_MRW - ts_busex_cmd_table) - DCD (ts_B_MRB - ts_busex_cmd_table) - DCD (ts_B_MWW - ts_busex_cmd_table) - DCD (ts_B_MWB - ts_busex_cmd_table) - -ts_B_SRW - LDR r11,[r9] ; read-only separate words - LDR r12,[r10] - ADDS r8, r8, r7 - BCS ts_B_SRW - B ts_B_done - -ts_B_SRB - LDRB r11,[r9] ; read-only separate bytes - LDRB r12,[r10] - ADDS r8, r8, r7 - BCS ts_B_SRB - B ts_B_done - -ts_B_SWW - STR r11,[r9] ; write and read separate words - STR r12,[r10] - LDR r1,[r9] - LDR r2,[r10] - ADDS r8, r8, r7 - BCS ts_B_SWW - B ts_B_done - -ts_B_SWB - STRB r11,[r9] ; write and read separate bytes - STRB r12,[r10] - LDRB r1,[r9] - LDRB r2,[r10] - ADDS r8, r8, r7 - BCS ts_B_SWB - B ts_B_done - - -ts_B_MRW - LDMIA r9,{r1,r2} ; read-only multiple words - LDMIA r10,{r1,r2} - ADDS r8, r8, r7 - BCS ts_B_MRW - B ts_B_done - -ts_B_MWW - STMIA r9,{r11,r12} ; write and read multiple words - LDMIA r9,{r1,r2} - STMIA r10,{r11,r12} - LDMIA r10,{r1,r2} - ADDS r8, r8, r7 - BCS ts_B_MWW - B ts_B_done - -; -; Orthogonally, these should be multiple byte operations - we can't do that, -; so they actually do a single/multiple mixture. -; The first address argument is used for word-aligned operations and the -; second for byte-aligned operations - so set only the second address -; to a non-word-aligned address. - -ts_B_MRB - LDMIA r9,{r1,r2} ; read-only multiple words - LDRB r1,[r10] ; then single bytes - LDR r1,[r9] ; and single words - ADDS r8, r8, r7 - BCS ts_B_MRB - B ts_B_done - -ts_B_MWB - STMIA r9,{r11,r12} ; store multiple words - STRB r11,[r10] ; write byte - STR r12,[r9] ; write words - LDMIA r9,{r1,r2} - LDRB r1,[r10] - LDR r1,[r9] ; read single and multiple words - ADDS r8, r8, r7 - BCS ts_B_MWB -; B ts_B_done - -ts_B_done - B ts_GetCommand - - - -; -; All commands fall through here to respond with FF if the received -; message block checksums fail. -; - -ts_cmd_error ROUT ; error in command - LDR r4, %01 ; return error response - ADD pc,pc,r0 -01 - DCD ErrorCmd - ADDS r0,r0,r0 - ADDS r14, r0, pc ; send response byte to host - B ts_SendByte - - B ts_GetCommand - - -; generic coprocessor register names - -cpr0 CN 0 -cpr1 CN 1 -cpr2 CN 2 -cpr3 CN 3 -cpr4 CN 4 -cpr5 CN 5 -cpr6 CN 6 -cpr7 CN 7 -cpr8 CN 8 -cpr9 CN 9 -cpr10 CN 10 -cpr11 CN 11 -cpr12 CN 12 -cpr13 CN 13 -cpr14 CN 14 -cpr15 CN 15 - - -; Called by vectoring through command table. -; Read transfer value -; Read and check checksum -; Extract copro register number -; Index suitable MRC instruction -; Perform copro write -; Reply with command byte or FF -; Reply with checksum - -ts_write_cpr15h ROUT - ADDS r4,r4,#8 ; adjust opcode for high registers -ts_write_cpr15l - ADDS r7,r0,r4 ; save opcode to r7 - ADDS r14,r0,pc - B ts_GetWord ; get value for copro - ADDS r9,r0,r4 - ADDS r14,r0,pc - B ts_GetWord ; get checksum - ADDS r4,r4,r9 - LDR r5,%01 - ADD pc,pc,r0 -01 - & (0 - 1) - ADDS r4,r5,r4 ; compare total chex with zero - BCS ts_cmd_error ; carry set on error - - ADDS r13,r7,r7 ; point into instruction table - ADDS r13,r13,r13 - ADDS r13,r13,r13 - ADD pc,pc,r13 ; jump to pc + (r7 * 8) - & 0 - - SetCop r9,cpr0 ; transfer instructions - B %02 - SetCop r9,cpr1 - B %02 - SetCop r9,cpr2 - B %02 - SetCop r9,cpr3 - B %02 - SetCop r9,cpr4 - B %02 - SetCop r9,cpr5 - B %02 - SetCop r9,cpr6 - B %02 - SetCop r9,cpr7 - B %02 - SetCop r9,cpr8 - B %02 - SetCop r9,cpr9 - B %02 - SetCop r9,cpr10 - B %02 - SetCop r9,cpr11 - B %02 - SetCop r9,cpr12 - B %02 - SetCop r9,cpr13 - B %02 - SetCop r9,cpr14 - B %02 - SetCop r9,cpr15 - -02 - LDR r4,%03 - ADD pc,pc,r0 -03 - & ts_CPWCmdByte ; build command byte + option - ADDS r4,r4,r7 - ADDS r14,r0,pc ; echo command byte - B ts_SendByte - ADDS r4,r0,r9 ; return checksum - ADDS r14,r0,pc ; - B ts_SendWord - - B ts_GetCommand - - - - -; Called by vectoring through command table. -; Read and check checksum -; Extract copro register number -; Index suitable MCR instruction -; Perform copro read -; Reply with command byte or FF -; Reply with checksum -; Send transfer results -; Send checksum - -ts_read_cpr15h ROUT - ADDS r4,r4,#8 ; adjust opcode for high registers -ts_read_cpr15l - ADDS r7,r0,r4 ; save opcode in r7 - ADDS r14,r0,pc - B ts_GetWord ; get checksum to r4 - ADDS r9,r0,r4 ; copy to r9 - LDR r5,%01 - ADD pc,pc,r0 -01 - & (0 - 1) - ADDS r4,r5,r4 ; compare total chex with zero - BCS ts_cmd_error ; carry set on error - - LDR r4,%02 - ADD pc,pc,r0 -02 - & ts_CPRCmdByte ; build command byte + option - ADDS r4,r4,r7 - ADDS r14,r0,pc ; echo command byte - B ts_SendByte - ADDS r4,r0,r9 ; return checksum - ADDS r14,r0,pc - B ts_SendWord - - ADDS r13,r7,r7 ; point into instruction table - ADDS r13,r13,r13 - ADDS r13,r13,r13 - ADD pc,pc,r13 ; jump to pc + (r7 * 8) - & 0 - - ReadCop r12,cpr0 ; transfer instructions - B %03 - ReadCop r12,cpr1 - B %03 - ReadCop r12,cpr2 - B %03 - ReadCop r12,cpr3 - B %03 - ReadCop r12,cpr4 - B %03 - ReadCop r12,cpr5 - B %03 - ReadCop r12,cpr6 - B %03 - ReadCop r12,cpr7 - B %03 - ReadCop r12,cpr8 - B %03 - ReadCop r12,cpr9 - B %03 - ReadCop r12,cpr10 - B %03 - ReadCop r12,cpr11 - B %03 - ReadCop r12,cpr12 - B %03 - ReadCop r12,cpr13 - B %03 - ReadCop r12,cpr14 - B %03 - ReadCop r12,cpr15 - -03 - ADDS r4,r0,r12 ; return result - ADDS r14,r0,pc - B ts_SendWord - SUBS r4,r0,r12 ; return checksum - ADDS r14,r0,pc - B ts_SendWord - - B ts_GetCommand - - - END - - diff --git a/TestSrc/ExtIO b/TestSrc/ExtIO deleted file mode 100644 index 76c2db31..00000000 --- a/TestSrc/ExtIO +++ /dev/null @@ -1,1107 +0,0 @@ -; > TestSrc.ExtIO - - TTL RISC OS 2+ POST external commands -; -; External interface for RISC OS ROM. -; provides entry points to send byte- and word- and string-sized objects -; and to receive byte- and word-sized objects -; -; A minimal set of opcodes should be used (ideally, only B, LDR and ADDS) -; so that a processor test may be validly included in the internal test -; sequence. -; -;------------------------------------------------------------------------ -; History -; -; Date Name Comment -; ---- ---- ------- -; 06-Dec-89 ArtG Initial version - split from `Begin` -; Release 0.2 for integration -; 31-Mar-90 ArtG Added ts_MoreText, cursor position, hex. -; 19-Apr-90 ArtG Added bus exercise commands -; 09-May-90 ArtG Changed LCD strobe to 12 pulses -; 15-May-90 ArtG Added ReadyByte : improves synchronization -; when ExtCmd execution toggles A21/A22. -; 18-Jun-90 ArtG Added CPR15 read/write functions -; 04-Oct-96 JRH Updated comments to refer to test box on A23. -; Added support for speaking to the test box when -; running from the 2nd ROM bank, conditioned on -; CanLiveOnROMCard. Needed because 2nd ROM bank -; isn't ghosted on the A23 line like the 1st bank. -; 04-May-99 KJB Modified to cope with >8M ROMs. -;------------------------------------------------------------------------ - - - SUBT Test adapter interface - -; -; The test adapter senses an access to the ROM with address line A23 high. -; -; 8M addressing space ROMs only use address lines A2 to A22, -; so if A23 is asserted it will be ignored (the ROMS are aliased -; into 16M of space). With no test adapter, the aliased ROM location will -; be read and may be recognised. The test adapter may selectively disable -; ROMs when A23 is high, causing arbitrary data to be read. This data -; should be dependent on the previous ROM read operation, and will -; therefore be predictably not equal to the data read when the ROMs are -; aliased. -; -; On a system with >8M of ROM, A23 is now meaningful, and there is no -; aliasing of the ROM image. In this case, we read a fixed location at the -; end of the ROM that always contains zero - if it reads as non-zero, the -; test adapter is signalling. -; - - - MACRO - TestAdapterLocation $reg -; -; Load up the registers for the test interface communication. -; On exit: R0 = 0 -; R1 corrupted -; $reg -> zero word in 8-16MB space we can read to communicate with -; test box - -; If the ROM is >8M, we will use the fixed zero word in the ROM trailer. -; If not, we use the old scheme (in case someone is using an old ROM joiner -; that doesn't write the correct trailer.) Because the ROM is >8M, the -; trailer will be at an address with A23 set, as desired. -; -; KJB - note I haven't kept the purity of the minimal instruction set - -; I feel that it is unlikely that there ever will be a processor test, -; and if there is, then this won't be the only place where the purity -; has been broken... - - ASSERT ts_Alias_bits = 8*1024*1024 - - MOV r0,#0 - LDR r1,[r0, #ts_ROMSIZE] ; size of ROM in bank 0 - CMP r1,#8*1024*1024 - SUBHI $reg,r1,#20 ; zero word is at end-20 - BHI %FT05 - -; Point r2 at a word which contains 0 in 0-8MB physical space. -; Note that this code doesn't cope with the case where it can't find a zero -; word anywhere in the whole ROM. I don't think that this is a problem. - - MOV r0, #0 ; expected below - MOV $reg, #0 ; start of physical space -01 - LDR r1, [$reg, #4]! - TEQ r1, r0 ; is it zero? - BNE %BT01 - - ADD $reg, $reg, #ts_Alias_bits ; point to zero word in ghost -05 - MEND - - - -; -; This section determines whether the test interface adapter exists, and -; what variety is fitted (dumb, display or external) -; 3 read operations are performed (a WS operation): if all of these -; find a ROM alias then no adapter is fitted. -; -; If an adapter responds, then a RD operation is performed - 4 strobes then -; clocking 8 bits into r4. These bits may be all zeros (a dumb adapter) -; or all ones (a display adapter) or some other value (an external -; adapter) -; - -ts_GetCommand ROUT - - LDR r0,%01 - ADD pc,pc,r0 -01 - & 0 - - ; delay to make a gap before reading - - LDR r3,%02 - ADD pc,pc,r0 -02 - & ts_recover_time -03 - ADDS r3,r3,r3 ; 16-loop delay - BCC %03 - - ROUT - - TestAdapterLocation r2 ; r0 = 0, r1 corrupted - - MOV r1, #-1 ; expected below -04 - ; do an RD operation (four strobes) to ensure interface cleared - - LDR r3,[r2] - ADDS r3,r3,r1 - LDR r3,[r2] - ADDS r3,r3,r1 - LDR r3,[r2] - ADDS r3,r3,r1 - LDR r3,[r2] - ADDS r3,r3,r1 - - ; write a byte (initially, &90) to indicate readiness - - LDR r4,%20 - ADD pc,pc,r0 -20 - & ts_ReadyByte_00 - ADDS r14,r0,pc - B ts_SendByte - - ; delay to make a gap between WRS and RD operations - - LDR r3,%05 - ADD pc,pc,r0 -05 - & ts_recover_time -06 - ADDS r3,r3,r3 ; 16-loop delay - BCC %06 - - LDR r5,%07 ; counter for first 5 bits - ADD pc,pc,r0 -07 - & 1 :SHL: (32 - 5) - LDR r6,%08 ; counter for last 3 bits - ADD pc,pc,r0 -08 - & 1 :SHL: (32 - 3) - ADDS r4,r0,r0 ; input accumulator initialisation - -; put the test interface into input mode - - LDR r3,[r2] ; 3 bit lead-in - ADDS r3,r3,r1 ; (adapter detects WS operation) - BCC ts_User_startup ; abort if no adapter present - - LDR r3,[r2] ; two more strobes, then waitloop - ADDS r3,r3,r1 - LDR r3,[r2] - ADDS r3,r3,r1 - -; started input operation : wait for interface to be ready - -09 - LDR r3,[r2] ; read start bit repeatedly - ADDS r3,r3,r1 ; (adapter detects RD operation) - BCC %09 ; loop until interface is ready - -; read the first 5 bits into r5 and the second 3 bits into r4 - -10 LDR r3,[r2] ; read a bit of the byte - ADDS r3,r3,r1 ; .. if the test adapter is present, carry bit set - ADCS r4,r4,r4 ; .. shift left and add in carry - - ADDS r5,r5,r5 ; loop until 5 bits are read - BCC %10 - - ADDS r5,r4,r4 ; copy bits 7..3 to r5, bits 5..1 - - ADDS r4,r0,r0 ; and read the last 3 bits to r4 -11 LDR r3,[r2] ; read a bit of the byte - ADDS r3,r3,r1 - ADCS r4,r4,r4 - - ADDS r6,r6,r6 ; loop until last 3 bits are read - BCC %11 - -; -; Command byte read in (split between r4 and r5) -; Pass the option bits (r4) to the function identified by r5. -; - - ADDS r5,r5,r5 ; index * 2 -> index * 4 - LDR r3,%12 ; pc-relative ptr to command_table - ADD pc,pc,r0 -12 - & ts_command_table - %13 - ADDS r3,pc,r3 ; absolute pointer to command table - ADDS r3,r3,r5 - -13 LDR r3,[r3] ; get table entry -14 ADD pc,pc,r3 ; (offset from command_table) - - & 0 ; necessary padding : pc must point - ; to command table when r3 is added. - -; -; This is the table of offsets to all the built-in functions. -; The top 5 bits of the command are used to index, so there are -; 32 possible entries, mostly illegal. -; Decoding of the function modifier bits is performed by multiple -; entries in this table. -; - -; pc must point here when ADDS pc,r3,pc is executed - - ASSERT ((ts_command_table - %14) = 8) - -ts_command_table - - DCD (ts_Dealer_startup - ts_command_table) ; display interface -ts_Windex - DCD (ts_write_memory - ts_command_table) ; external tests -ts_Rindex - DCD (ts_read_memory - ts_command_table) -ts_Eindex - DCD (ts_execute - ts_command_table) -ts_Bindex - DCD (ts_bus_exercise - ts_command_table) - - DCD (ts_GetCommand - ts_command_table) ; dummy entry aligns CPR instructions - ; to allow 4-bit option field -ts_CWindex - DCD (ts_write_cpr15l - ts_command_table) - DCD (ts_write_cpr15h - ts_command_table) -ts_CRindex - DCD (ts_read_cpr15l - ts_command_table) - DCD (ts_read_cpr15h - ts_command_table) - - ; pad the table out to 31 entries - ; (leave space for display vector) - -OldOpt SETA {OPT} - OPT OptNoList -doffset SETA . - WHILE doffset < (ts_command_table + (31 * 4)) ; illegal entries - DCD (ts_GetCommand - ts_command_table) -doffset SETA doffset + 4 - WEND - OPT OldOpt - - DCD (ts_Forced_startup - ts_command_table) ; dumb interface - -; -; The indexes into the above table are needed in ExtCmd ... -; -ts_WriteCmdByte * ((ts_Windex - ts_command_table) :SHL: 1) -ts_ReadCmdByte * ((ts_Rindex - ts_command_table) :SHL: 1) -ts_ExecuteCmdByte * ((ts_Eindex - ts_command_table) :SHL: 1) -ts_BusExCmdByte * ((ts_Bindex - ts_command_table) :SHL: 1) -ts_CPWCmdByte * ((ts_CWindex - ts_command_table) :SHL: 1) -ts_CPRCmdByte * ((ts_CRindex - ts_command_table) :SHL: 1) - - -; -; Primitives for reading data from the external interface -; -; - Get a byte from the interface (into r4) -; - Get a (4 byte) word from the interface (into r4) -; -; Required register setup is presumed done by a recent ts_GetCommand. -; r0, r1 and r2 have critical values -; r14 is the link address -; - -ts_GetWord ROUT - - LDR r6,%01 ; counter for 4 bytes per word - ADD pc,pc,r0 ; (bit set 4 left shifts from Carry) -01 - & 1 :SHL: (32 - 4) - B ts_Getdata - -ts_GetByte ROUT - LDR r6,%01 ; counter for single byte - ADD pc,pc,r0 -01 - & 1 :SHL: (32 - 1) - -ts_Getdata ROUT - ADDS r4,r0,r0 ; input accumulator initialisation - - LDR r3,[r2] ; 3 bit lead-in - ADDS r3,r3,r1 ; (adapter detects RD operation) - LDR r3,[r2] - ADDS r3,r3,r1 - LDR r3,[r2] - ADDS r3,r3,r1 - -; started input operation : now loop until r6 shifts into Carry - -02 - LDR r5,%03 ; counter for 8 bits per byte - ADD pc,pc,r0 -03 - & 2_00000001000000010000000100000001 -04 - LDR r3,[r2] ; read start bit repeatedly - ADDS r3,r3,r1 - BCC %04 ; loop until interface is ready -05 - LDR r3,[r2] ; read a bit of the byte - ADDS r3,r3,r1 - ADCS r4,r4,r4 ; SHL r4, add carry bit. - - ADDS r5,r5,r5 ; loop until byte is read - BCC %05 - - ADDS r6,r6,r6 ; loop until word is read - BCC %04 - - ADD pc,r0,r14 ; back to the caller - - -; -; Primitives for sending data to the interface -; -; - Send a byte to the interface (from r4 lsb) -; - Send a (4 byte) word to the interface (from r4) -; -; Required register setup is presumed done by a recent ts_GetCommand. -; r0, r1 and r2 have critical values -; r14 is the link address -; - -ts_SendWord ROUT - LDR r6,%01 ; counter for 4 bytes per word - ADD pc,pc,r0 ; (bit set 4 left shifts from Carry) -01 - & 1 :SHL: (32 - 4) - B ts_Putdata - -ts_SendByte ROUT - LDR r6,%01 ; counter for single byte - ADD pc,pc,r0 -01 - & (3 :SHL: 7) -02 ADDS r4,r4,r4 ;shift byte into highest 8 bits - ADDS r6,r6,r6 - BCC %02 ;stop when byte shifted, - ;leaving bit 31 set in r6 - -ts_Putdata ROUT - -; Wait - gap between successive WS attempts or successive bytes - -01 LDR r3,%02 - ADD pc,pc,r0 -02 - & ts_recover_time -03 ADDS r3,r3,r3 ; 16-loop delay - BCC %03 - - LDR r3,[r2] ; Test for adapter ready for data - ADDS r3,r3,r1 ; (adapter detects WS operation) - LDR r3,[r2] - ADDS r3,r3,r1 - BCC %10 ; skip out if adapter not present - LDR r3,[r2] - ADDS r3,r3,r1 - BCC %01 ; loop back until adapter is ready - -; Adapter ready - loop around all the bits in the byte - - LDR r5,%04 ; load bits-per-byte counter - ADD pc,pc,r0 -04 - & (1 :SHL: (32-8)) - -05 LDR r3,%06 ; delay before sending bit - ADD pc,pc,r0 -06 - & ts_recover_time -07 ADDS r3,r3,r3 ; 16-loop delay - BCC %07 - - ; Send a single bit : 1 pulse for 1, 2 pulses for 0 - - LDR r3,[r2] - ADDS r4,r4,r4 ; shift current bit into Carry - LDRCC r3,[r2] ; second pulse if bit is 0 - - ; repeat until 8 bits are sent - - ADDS r5,r5,r5 - BCC %05 - -; Repeat for all the bytes to be sent (1 or 4) - - ADDS r6,r6,r6 - BCC %01 - -; Go to TXRDY to ensure the host sees the transmit request - - LDR r3,%08 ; delay before sending pattern - ADD pc,pc,r0 -08 - & ts_recover_time -09 ADDS r3,r3,r3 ; 16-loop delay - BCC %09 - - LDR r3,[r2] - ADDS r3,r3,r1 ; dummy - space between pulses - LDR r3,[r2] - ADDS r3,r3,r1 - LDR r3,[r2] - -; All sent - r14 holds the caller's return address -10 - ADD pc,r0,r14 - - - -; -; Reporting primitive -; -; - Send the text (nul-terminated, at r4) to the display -; -; Interface registers need to be set up : this function is called from test -; code rather than external interface code. -; -; The display is assumed to be a standard 16 character LCD module using -; the Hitachi HD44780 display controller. -; The 16-digit module uses a single 44780. This is an abnormal use of the -; controller, and requires it to be set to two-line mode, with the first -; 8 displayed characters on the first 'line', and the second 8 on the -; second 'line'. Characters sent to the second line must be written at -; character position 40 +. In order to permit different modules to be -; fitted to later adapters, it is suggested that the first 7 characters -; be treated as a 'title' line, and the second 8 as a 'comment' line. -; A space should always be placed at the end of the title line to -; split the display fields, unless there is no 'comment' line. -; Do not display characters across the two areas as though they adjoined -; (even though they do :-) ). -; -; The controller is operated in its 4-bit mode, which allows the interface -; to drive 4 bits of alpha information and 4 bits of control information. -; The bits in a transmitted byte are assigned as : -; -; bit 0 - D4 } 4-bit mode data bus -; 1 - D5 } -; 2 - D6 } -; 3 - D7 } -; -; 4 - RS Register Select : 0 for control, 1 for data -; -; 5 - } Unassigned -; 6 - } -; -; 7 - CPEN Interface control : 0 for enable, -; 1 for disable -; -; For each message sent, the display is first initialised, using the -; following sequence (each byte is sent as 2 bytes, high nibble first, -; with RS clear in bit 4 of each byte) -; After each byte, an RD operation is performed : this is used by the -; interface hardware to strobe the data into the display. -; -; -; The message addressed by r4 is then sent (data mode : RS set in each byte) -; until a 0 byte is encountered. -; - -; -; This is the command sequence sent to initialise the display -; - -ts_initialise - = &30,&30,&30,&20 ; power-up initialisation - = &20,&80 ; 4 bit mode, two line, Font 0 - = &00,&C0 ; Display on, no cursor visible - = &00,&60 ; Incrementing display position, no shift - = &80,&00 ; Set DD RAM address 0 - = &00,&20 ; Cursor home - = &00,&10 ; Display clear -ts_initialise_end - - ASSERT ((ts_initialise_end - ts_initialise) / 2) < 32 - - -; -; This is the command sequence sent when continuation text is sent -; - -ts_extend - = &00,&C0 ; Display on, cursor invisible - = &00,&60 ; Incrementing display position, no shift -ts_extend_end - - ASSERT ((ts_extend_end - ts_extend) / 2) < 32 - -; -; One of these commands are sent when offset text is required -; - -ts_offset_table - = &80,&00 ; Set DD RAM address 0 -ts_offset_table_1 - = &80,&10 ; Set DD RAM address 1 - = &80,&20 ; Set DD RAM address 2 - = &80,&30 ; Set DD RAM address 3 - = &80,&40 ; Set DD RAM address 4 - = &80,&50 ; Set DD RAM address 5 - = &80,&60 ; Set DD RAM address 6 - = &80,&70 ; Set DD RAM address 7 - = &C0,&00 ; Set DD RAM address 40 - = &C0,&10 ; Set DD RAM address 41 - = &C0,&20 ; Set DD RAM address 42 - = &C0,&30 ; Set DD RAM address 43 - = &C0,&40 ; Set DD RAM address 44 - = &C0,&50 ; Set DD RAM address 45 - = &C0,&60 ; Set DD RAM address 46 - = &C0,&70 ; Set DD RAM address 47 - - -; This assertion is forced by the code : each sequence assumed 2 bytes. - - ASSERT ((ts_offset_table_1 - ts_offset_table) = 2) - - - - ALIGN - -; -; Here starts the code ... -; - -ts_SendQuit ROUT ; put this code BEFORE %16 - ADD pc,r0,r14 ; - - - -; -; Entry point for initialising the display and sending r4 text. -; - - -ts_SendText ROUT - -; -; Point to the command sequence to setup and clear the display -; - - LDR r0,%10 ; set zero in r0 - ADD pc,pc,r0 -10 - & 0 - LDR r7,%11 ; pointer to init sequence - ADDS r7,pc,r7 - ADD pc,pc,r0 -11 - & (ts_initialise - .) - LDR r6,%12 ; length of init sequence - ADD pc,pc,r0 -12 - & (1 :SHL: (32 - (ts_initialise_end - ts_initialise))) - B ts_SendLCDCmd - - -; -; Entry point for adding text to current cursor position -; - -ts_MoreText ROUT - - LDR r0,%10 ; set zero in r0 - ADD pc,pc,r0 -10 - & 0 - LDR r7,%11 ; pointer to command sequence - ADDS r7,pc,r7 - ADD pc,pc,r0 -11 - & (ts_extend - .) - LDR r6,%12 ; length of command sequence - ADD pc,pc,r0 -12 - & (1 :SHL: (32 - (ts_extend_end - ts_extend))) - B ts_SendLCDCmd - - -ts_PosText ROUT - -; -; Entry point for adding text at a specific cursor position -; Used iteratively by SendText, etc if cursor position command found. -; Offset into display is given in r6. -; - - LDR r0,%10 ; set zero in r0 - ADD pc,pc,r0 -10 - & 0 - LDR r7,%11 ; pointer to command sequence - ADDS r7,pc,r7 - ADD pc,pc,r0 -11 - & (ts_offset_table - .) ; offset * 2 into table of - ADDS r6,r6,r6 ; offset command sequences - ADDS r7,r7,r6 - - LDR r6,%12 ; length of command sequence - ADD pc,pc,r0 -12 - & (1 :SHL: (32 - 2)) - - -; -; Entry point for writing arbitrary command strings. -; Set r7 to point to command string, r6 length (as tables above), -; Set r4 to point to following Data string (null-terminated). -; - -ts_SendLCDCmd - TestAdapterLocation r2 ; r0 = 0, r1 corrupted -04 - -; Wait - gap between successive WS attempts or successive bytes - -ts_send_command_byte ROUT - - LDR r3,%14 - ADD pc,pc,r0 -14 - & ts_recover_time -15 ADDS r3,r3,r3 ; 16-loop delay - BCC %15 - LDR r1,%16 ; reload test register - ADD pc,pc,r0 -16 - & (-1) - - LDR r3,[r2] ; Test for adapter ready for data - ADDS r3,r3,r1 ; (adapter detects WS operation) - BCC ts_SendQuit ; skip output : adapter not present - ; (backward jump helps ensure LDR r3,[r2] - ; only reads zero when adapter absent - LDR r3,[r2] ; since previous bus data is nonzero) - ADDS r3,r3,r1 - LDR r3,[r2] - ADDS r3,r3,r1 - BCC ts_send_command_byte ; loop back until adapter is ready - -; Adapter ready - loop around all the bits in the byte - - - LDR r5,%21 ; load byte-shift counter ... - ADD pc,pc,r0 ; ... and bits-per-byte counter -21 - & (1 :SHL: 8) + 1 ; 24 shifts + 8 shifts - LDRB r1,[r7] -22 ADDS r1,r1,r1 ; shift byte up into m.s.d. - ADDS r5,r5,r5 - BCC %22 - - ; Send a single bit : 1 pulse for 1, 2 pulses for 0 - -23 LDR r3,[r2] - ADDS r1,r1,r1 ; shift current bit into Carry - LDRCC r3,[r2] ; second pulse if bit is 0 - - ; and wait for the inter-bit time - - LDR r3,%24 - ADD pc,pc,r0 -24 - & ts_recover_time -25 ADDS r3,r3,r3 ; 16-loop delay - BCC %25 - - ; repeat until 8 bits are sent - - ADDS r5,r5,r5 - BCC %23 - - ; do a RD operation to strobe the data out - - LDR r5,%26 - ADD pc,pc,r0 -26 - & (1 :SHL: (32 - 12)) -27 - LDR r3,[r2] - ADDS r5,r5,r5 - BCC %27 - -; Repeat for all the bytes to be sent (ts_initialise_end - ts_initialise) - - LDR r3,%33 - ADD pc,pc,r0 -33 - & 1 - ADDS r7,r7,r3 ; bump the pointer - ADDS r6,r6,r6 ; bump the counter (shift left) - BCC ts_send_command_byte - - -; -; Then send all the display bytes (in 4-bit mode) until a nul-terminator -; is reached. -; - -; -; Send a single character (as two separate 4-bit fields) -; First, look to see if it's one of : -; -; NUL - end of text string -; 0x80 - 0xfe - cursor positioning -; 0xff - introduce a hex digit -; - -ts_send_text_byte ROUT - - LDR r1,%40 ; reload test register - ADD pc,pc,r0 -40 - & (-1) - - LDRB r7,[r4] - ADDS r3,r7,r1 ; test for nul terminator - BCC ts_SendEnd - -; -; Byte isn't null. Check for >= 0x80. -; - - LDR r6,%42 ; test for cursor control - ADD pc,pc,r0 -42 - & (-&80) ; &8x means column x. - ADDS r6,r7,r6 - BCC ts_printable_char ; < &80 : write a character - -; -; Carry set : r6 now holds (value - 0x80). Check for numeric escape (&ff). -; - LDR r3,%43 - ADD pc,pc,r0 -43 - & (-&7f) - ADDS r3,r6,r3 - BCC %47 - -; -; Carry set : fetch a nybble from the top of r8 and display that. -; - - ADDS r8,r8,r8 - ADCS r6,r0,r0 - ADDS r8,r8,r8 - ADCS r6,r6,r6 - ADDS r8,r8,r8 - ADCS r6,r6,r6 - ADDS r8,r8,r8 - ADCS r6,r6,r6 - - LDRB r7,[pc,r6] - B ts_printable_char -45 - = "0123456789ABCDEF" - -; -; Not &ff : r6 holds cursor positioning offset (< &80). Skip over -; the cursor control byte and iterate thro' PosText to move -; typing position. -; - -47 - LDR r3, %48 - ADD pc,pc,r0 -48 - & 1 - ADDS r4,r3,r4 - B ts_PosText - -; -; Character is normal text : write it to the LCD. -; The shift loop is used to generate the inter-byte delay normally -; provided by ts_recover_time. Always make sure this is long enough. -; - -ts_printable_char - - ADDS r6,r0,r7 ; take a copy of character - LDR r5,%51 ; load byte-shift counter ... - ADD pc,pc,r0 ; ... and bits-per-byte counter -51 ; as a bitmask of the shift pattern - & (1:SHL:8)+(1:SHL:4)+1 ; 24 shifts + 4 shifts + 4 shifts -52 ADDS r6,r6,r6 ; shift byte up into m.s.d. - ADDS r0,r0,r0 ; slow this loop down - ensure it's - ADDS r0,r0,r0 ; always slower than ts_recover_time - ADDS r5,r5,r5 - BCC %52 - - LDR r3,[r2] ; Test for adapter ready for data - ADDS r3,r3,r1 ; (adapter detects WS operation) - LDR r3,[r2] - ADDS r3,r3,r1 - LDR r3,[r2] - ADDS r3,r3,r1 - BCC ts_printable_char ; loop back until adapter is ready - -; Adapter ready - loop around all the bits in the byte - -ts_send_tbit_upper - - ; wait for the inter-bit time - - LDR r3,%55 - ADD pc,pc,r0 -55 - & ts_recover_time -56 ADDS r3,r3,r3 ; 16-loop delay - BCC %56 - - ; Send a single bit : 1 pulse for 1, 2 pulses for 0 - - LDR r3,[r2] - ADDS r6,r6,r6 ; shift current bit into Carry - LDRCC r3,[r2] ; second pulse if bit is 0 - - ; repeat until upper 4 bits are sent - - ADDS r5,r5,r5 - BCC ts_send_tbit_upper - - ; then send the interface control bits - - LDR r1,%57 - ADD pc,pc,r0 -57 - & (8 :SHL: 28) ; assert RS control pin - -ts_send_cbit_upper - - ; wait for the inter-bit time - - LDR r3,%58 - ADD pc,pc,r0 -58 - & ts_recover_time -59 ADDS r3,r3,r3 ; 16-loop delay - BCC %59 - - ; Send a single bit : 1 pulse for 1, 2 pulses for 0 - - LDR r3,[r2] - ADDS r1,r1,r1 ; shift current bit into Carry - LDRCC r3,[r2] ; second pulse if bit is 0 - ADDS r5,r5,r5 - BCC ts_send_cbit_upper - -; -; do a RD operation to strobe the data out -; - - LDR r3,%61 - ADD pc,pc,r0 -61 - & ts_recover_time -62 ADDS r3,r3,r3 ; 16-loop delay - BCC %62 - - LDR r5,%63 - ADD pc,pc,r0 -63 - & (1 :SHL: (32 - 12)) -64 - LDR r3,[r2] - ADDS r5,r5,r5 - BCC %64 - - ; prepare to send the lower 4 bits out - - LDR r5,%70 ; bitcount mask for 4 data bits - ADD pc,pc,r0 ; and 4 interface control bits -70 - & (((1 :SHL: 4) + 1) :SHL: 24) - -ts_send_text_lower - LDR r3,%71 - ADD pc,pc,r0 -71 - & ts_recover_time -72 ADDS r3,r3,r3 ; 16-loop delay - BCC %72 - - LDR r1,%73 - ADD pc,pc,r0 -73 - & (-1) - - LDR r3,[r2] ; Test for adapter ready for data - ADDS r3,r3,r1 ; (adapter detects WS operation) - LDR r3,[r2] - ADDS r3,r3,r1 - LDR r3,[r2] - ADDS r3,r3,r1 - BCC ts_send_text_lower ; loop back until adapter is ready - -ts_send_tbit_lower - - ; wait for the inter-bit time - - LDR r3,%76 - ADD pc,pc,r0 -76 - & ts_recover_time -77 ADDS r3,r3,r3 ; 16-loop delay - BCC %77 - - ; Send a single bit : 1 pulse for 1, 2 pulses for 0 - - LDR r3,[r2] - ADDS r6,r6,r6 ; shift current bit into Carry - LDRCC r3,[r2] ; second pulse if bit is 0 - - ; repeat until lower 4 bits are sent - - ADDS r5,r5,r5 - BCC ts_send_tbit_lower - - - ; then send the interface control bits - - LDR r1,%78 - ADD pc,pc,r0 -78 - & (8 :SHL: 28) ; assert RS control pin - -ts_send_cbit_lower - - ; wait for the inter-bit time - - LDR r3,%80 - ADD pc,pc,r0 -80 - & ts_recover_time -81 ADDS r3,r3,r3 ; 16-loop delay - BCC %81 - - ; Send a single bit : 1 pulse for 1, 2 pulses for 0 - - LDR r3,[r2] - ADDS r1,r1,r1 ; shift current bit into Carry - LDRCC r3,[r2] ; second pulse if bit is 0 - - ADDS r5,r5,r5 - BCC ts_send_cbit_lower - -; -; do a RD operation to strobe the data out -; - - ; wait for the inter-bit time - - LDR r3,%82 - ADD pc,pc,r0 -82 - & ts_recover_time -83 ADDS r3,r3,r3 ; 16-loop delay - BCC %83 - - LDR r5,%84 - ADD pc,pc,r0 -84 - & 1 :SHL: (32 - 12) -85 - LDR r3,[r2] - ADDS r5,r5,r5 - BCC %85 - -; Repeat for all the bytes to be sent (until nul terminator is found) - - LDR r3,%86 - ADD pc,pc,r0 -86 - & 1 - ADDS r4,r3,r4 ; bump text pointer - B ts_send_text_byte - -; -; Wait for about 1 seconds worth of LCD operation delays to -; permit the operator to read the text. -; Use of the interface's monitor allows this delay to be increased -; or decreased externally. -; - -ts_SendEnd ROUT - - LDR r7, %01 - ADD pc,pc,r0 -01 - & (ts_pause_time + 1) ; must be an odd number - ; to ensure pairs of zeros - ASSERT ((ts_pause_time :AND: 1) = 0) - -02 - LDR r3,%03 - ADD pc,pc,r0 -03 - & ts_recover_time -04 ADDS r3,r3,r3 ; 16-loop delay - BCC %04 - LDR r1,%05 ; reload test register - ADD pc,pc,r0 -05 - & (-1) - - LDR r3,[r2] ; Test for adapter ready for data - ADDS r3,r3,r1 ; (adapter detects WS operation) - BCC ts_SendQuit ; skip output : adapter not present - LDR r3,[r2] - ADDS r3,r3,r1 - LDR r3,[r2] - ADDS r3,r3,r1 - BCC %02 ; loop back until adapter is ready - -; Adapter ready - loop around all the bits in the byte -; Note that each byte is actually 4 bits to the LCD module, -; so a even number must be sent or the display will get out -; of sync until the next display reset sequence. - - LDR r5,%10 ; bits-per-byte counter - ADD pc,pc,r0 -10 - & (1 :SHL: 24) - LDR r3,%11 - ADD pc,pc,r0 -11 - & ts_recover_time ; wait before sending data bits -12 ADDS r3,r3,r3 ; for byte timing. - BCC %12 - - ; Send a single bit : always 2 pulses for 0 - -13 LDR r3,[r2] - LDR r3,[r2] - - ; and wait for the inter-bit time - - LDR r3,%14 - ADD pc,pc,r0 -14 - & ts_recover_time -15 ADDS r3,r3,r3 ; 16-loop delay - BCC %15 - - ; repeat until 8 bits are sent - - ADDS r5,r5,r5 - BCC %13 - - ; do a RD operation to strobe the data out - - LDR r5,%16 - ADD pc,pc,r0 -16 - & 1 :SHL: (32 - 12) -17 - LDR r3,[r2] - ADDS r5,r5,r5 - BCC %17 - - ; repeat until a sufficient number of nuls are done - - ADDS r7,r7,r1 ; count down loop counter - BCS %02 - - ADD pc,r0,r14 ; back to caller - - - END diff --git a/TestSrc/InitModule b/TestSrc/InitModule deleted file mode 100644 index 3b3a9412..00000000 --- a/TestSrc/InitModule +++ /dev/null @@ -1,114 +0,0 @@ -; > InitModule -; Source for Pre_InitModule, PostInitModule im_InitModules & im_Pre_InitPodMod functions -; -; *********************************** -; *** C h a n g e L i s t *** -; *********************************** -; -; Date Who Version Description -; ---- --- ------- ----------- -; 13-Jun-96 BAR 0.01 Started -; 27-Jun-96 BAR 0.02 Added code to check the type of reset we -; just had. If power-on then we can display -; messages, else exit back. -; -; -; Provides functions to display messages for when we initiliseing the -; modules. Messages are only sent to the display adapator, if the Reset Type -; is Power On Reset. The code uses the constant ResetType, defined in -; kernel.hdr.KernelWS. This is the address of a memory location, where the -; type of reset is stored. ResetType is a sigle bit flag, in bit 0 of the -; memory location. The constant PowerOnReset is used, which is defined in -; Kernel.s.newReset. This defines the value that a power-on reset should be. -; The value of PowerOnReset should always be 1. (This corresponds to the -; value of the bit 4 of IOMD's IRQA Status register, where the Power-on -; reset status is initially stored.) The value of ResetType can vary between -; different versions of the operating system. -; -; -; im_Pre_InitModule is called before a module is started -; im_Post_InitModule is called after a module is started, only if there was -; an error -; im_InitModules is called at the start of initiliseing the modules. -; im_Pre_InitPodMod is called when we start the podule manager. -; -; All the functions will push registers r0-r12 to the stack, check the -; poweron reset status, if power on reset, then send a message to the -; display adaptor and then pull them off at the end. -; -; -im_Pre_InitModule ROUT - Push "r0-r12" ; Put r0->r12 on to stack -; Get the type of reset we had, if power-on - can use display adaptor - LDR r1,=ResetType ; Load r1 with address of ResetType - LDR r0,[r1] ; Get contents of ResetType = what type of reset - CMPS r0,#PowerOnReset ; Compare with PowerOnReset (1) -;if equel send message - LDREQ r4,[r11,#ROMModule_Name] ; Put ptr to mod name in r4 - BLEQ ts_SendText ; Send the txt to disp adaptor -;restore the reg's. - Pull "r0-r12" ; Get r0->r12 from the stack - - MOV pc,r14 ; Return to caller - -im_Post_InitModule ROUT - -1 - = "Module Bad",0 - - Push "r0-r12" ; Put r0->r12 on to stack -; Get the type of reset we had, if power-on - can use display adaptor - LDR r1,=ResetType ; Load r1 with address of ResetType - LDR r0,[r1] ; Get contents of ResetType = what type of reset - CMPS r0,#PowerOnReset ; Compare with PowerOnReset (1) - BNE %FT2 ; IF not equal jump to 2 AKA don't send msg. - - Push "r0" ; Put r0 in stack again - ADR r4, %BT1 ; r4 = bad module msg - BL ts_SendText ; Send the txt to disp adaptor - Pull "r0" ; Get r0 from the stack - ADDVC r4,r0,#4 ; If V Clr add 4 to r0 - point to err txt - BLVC ts_SendText ; Send the txt to disp adaptor -2 - Pull "r0-r12" ; Get r0->r12 from the stack - - MOV pc,r14 ; Return to caller - -im_InitModules ROUT - -1 - = "Init Modules :",0 - - Push "r0-r12" ; Put r0->r12 on to stack -; Get the type of reset we had, if power-on - can use display adaptor - LDR r1,=ResetType ; Load r1 with address of ResetType - LDR r0,[r1] ; Get contents of ResetType = what type of reset - CMPS r0,#PowerOnReset ; Compare with PowerOnReset (1) -;if equel send message - ADREQ r4, %BT1 ; r4 = init msg - BLEQ ts_SendText ; Send the txt to disp adaptor -;restore the reg's. - Pull "r0-r12" ; Get r0->r12 from the stack - - MOV pc,r14 ; Return to caller - -im_Pre_InitPodMod ROUT - -1 - = "Podule",0 - - Push "r0-r12" ; Put r0->r12 on to stack -; Get the type of reset we had, if power-on - can use display adaptor - LDR r1,=ResetType ; Load r1 with address of ResetType - LDR r0,[r1] ; Get contents of ResetType = what type of reset - CMPS r0,#PowerOnReset ; Compare with PowerOnReset (1) -;if equel send message - ADREQ r4, %BT1 ; r4 = init msg - BLEQ ts_SendText ; Send the txt to disp adaptor -;restore the reg's. - Pull "r0-r12" ; Get r0->r12 from the stack - - MOV pc,r14 ; Return to caller - - - END diff --git a/TestSrc/Ioc b/TestSrc/Ioc deleted file mode 100644 index d4429894..00000000 --- a/TestSrc/Ioc +++ /dev/null @@ -1,110 +0,0 @@ -; > TestSrc.IOC - - TTL RISC OS 2+ POST IO controller -; -; This initial IOC test simply reports the content of the IRQ and FIRQ -; registers, to show any unexpected pending IRQs. -; Certain of these should really be cleared, and the effect of an -; interrupt tested. -; -;------------------------------------------------------------------------ -; History -; -; Date Name Comment -; ---- ---- ------- -; 18-Dec-89 ArtG Initial version -; 29-Nov-91 ArtG Added IOC bus test using mask registers -; 20-Jun-93 ArtG Modified for 29-bit IOMD test -; 18-Nov-94 RCM Morris changes -; 15-May-96 BAR Changes for 7500FE - new IOMD ID code. -; Now list 3 ID codes. -; 17-Jun-96 BAR Change ts_IOMD_IDn definitions to point to -; definitions in IOMDL -; 09-Jul-96 BAR Improve IOMD ID code. -; -; -;------------------------------------------------------------------------ - - [ IO_Type = "IOMD" -ts_IObase * IOMD_Base -ts_IOmask * &00fffff0 ;&1fffffff -ts_IOreg1 * IOMD_VIDEND ;IOMD_VIDCUR -ts_IOreg2 * IOMD_VIDSTART -ts_IObswap * 32 -ts_IOMD_ID1 * IOMD_Original -ts_IOMD_ID2 * IOMD_7500 -ts_IOMD_ID3 * IOMD_7500FE - | -ts_IObase * IOC -ts_IOmask * &ff0000 -ts_IOreg1 * IOCIRQMSKA -ts_IOreg2 * IOCIRQMSKB -ts_IObswap * 16 - ] - -ts_IOCreg - MOV r0,#0 ; zero error accumulator - LDR r3, =ts_IObase - MOV r1,#(1 :SHL: 31) ; initialise bit-set test mask -0 - MVN r2,r1 ; make bit-clear test mask - LDR r4, =ts_IOmask - ANDS r4,r1,r4 - BEQ %FT1 ; skip if this bit isn't tested - STR r1,[r3,#ts_IOreg1] - STR r2,[r3,#ts_IOreg2] - LDR r4,[r3,#ts_IOreg1] -; EOR r4, r4, r1, LSR #ts_IObswap ; check bit-set test was OK - EOR r4, r4, r1 ; check bit-set test was OK - ORR r0, r0, r4 ; accumulate errors in r0 - LDR r4,[r3,#ts_IOreg2] -; EOR r4, r4, r2, LSR #ts_IObswap ; check bit-clear test was OK - EOR r4, r4, r2 ; check bit-clear test was OK - ORR r0, r0, r4 ; accumulate errors in r0 -1 - MOV r1, r1, LSR #1 ; shift mask downwards - TEQ r1,#0 - BNE %BT0 ; and loop until all bits tested - - LDR r8, =ts_IOmask - ANDS r8, r0, r8 - MOV pc,r14 ; return error if any bit failed - -ts_IOCstat - LDR r3, =ts_IObase ; r3 points to IO Chip base address - MOV r0,#0 ; clear r0 - [ IO_Type = "IOMD" - ; Check IOMD chip variants - LDRB r1,[r3,#IOMD_ID1] ; load r1 with IOMD ID high byte - LDRB r0,[r3,#IOMD_ID0] ; load r1 with IOMD ID low byte - ORR r0,r0,r1, LSL #8 ; Or r0 and r1 - shifted left 8, put in r0 - LDR r1,=ts_IOMD_ID1 ; get Ref IOMD ID code #1 - CMPS r0,r1 ; check =to IOMD ID Code #1 - - LDRNE r1,=ts_IOMD_ID2 ; If not ID1, get Ref IOMD ID code #2 - CMPNES r0,r1 ; If not ID1, check =to IOMD ID Code #2 - - LDRNE r1,=ts_IOMD_ID3 ; if not ID1 and ID2, get Ref IOMD ID code #3 - CMPNES r0,r1 ; If not ID1 and ID2, check =to IOMD ID Code #3 - - MOV r0,r0,LSL #16 ; Move ID code in to top 16 bits - LDRB r1,[r3,#IOMD_VERSION] ; Load r with IOMD Version number - ORR r8,r0,r1, LSL #12 ; Or r0 and r1 - shifted left 12, put in r8 - MOV pc,r14 ; extit to whence came from. - | - ; Check IOC chip variants - LDRB r1,[r3,#IOCControl] - ORR r0,r0,r1, LSL #(32 - 8) - LDRB r1,[r3,#IOCIRQSTAA] - ORR r0,r0,r1, LSL #(32 - 16) - LDRB r1,[r3,#IOCIRQSTAB] - ORR r0,r0,r1, LSL #(32 - 24) - LDRB r1,[r3,#IOCFIQSTA] - ORR r8,r0,r1 - ANDS r1,r1,#0 ; return zero flag (OK) - - MOV pc,r14 - ] - - END - diff --git a/TestSrc/LEDDelay b/TestSrc/LEDDelay deleted file mode 100644 index 3418b646..00000000 --- a/TestSrc/LEDDelay +++ /dev/null @@ -1,35 +0,0 @@ -; > LEDDelay -; Source for LEDDelay function -; -; *********************************** -; *** C h a n g e L i s t *** -; *********************************** -; -; Date Who Version Description -; ---- --- ------- ----------- -; 30-May-96 BAR 0.01 Started -; 12 Jun 97 BAR 0.02 Change value of 1/4 delay time. -; -; Will provide a 1/4 second delay for flashing the LED's - - - -;ld_quarter_sec * (35000*8) ; 1/4 Second delay ! -ld_quarter_sec * (100000*6) ; 1/4 Second delay ! For Boca Units - -ld_LED_Delay ROUT -; Generate the required delay between changing the LED status -; On entry .... -; r4 = required delay time -; Register usage .... -; r0, general scratch pad -; -01 LDR r0,=ld_quarter_sec ; Load r0 with 1/4 seconds delay -02 SUBS r0,r0,#1 ; subtract one - BNE %02 ; back we go .... pause for a 1/4 second - SUBS r4,r4,#1 ; subtract one - BNE %01 ; repeat the pause for the flash duration - - MOV pc,r14 ; Return to caller - - END diff --git a/TestSrc/MEMC1 b/TestSrc/MEMC1 deleted file mode 100644 index 847df368..00000000 --- a/TestSrc/MEMC1 +++ /dev/null @@ -1,552 +0,0 @@ -; > MEMC1 - -; MEMC interface file - MEMC1 version - -; Created by TMD 10-Aug-90 - -VInit * &03600000 -VStart * &03620000 -VEnd * &03640000 -CInit * &03660000 -; SStart * &03680000 -; SEnd * &036A0000 -; SPtr * &036C0000 - -; ***************************************************************************** -; -; SetDAG - Program DMA address generator R1 with physical address R0 -; -; in: r0 = physical address -; r1 = index of DMA address generator to program, as defined in vdudecl -; -; out: All registers preserved, operation ignored if illegal -; - - [ {FALSE} -SetDAG ENTRY "r0" - CMP r1, #MEMCDAG_MaxReason - EXIT HI - ADR r14, DAGAddressTable - LDR r14, [r14, r1, LSL #2] ; load base address in MEMC1 - MOV r0, r0, LSR #4 ; bottom 4 bits irrelevant - CMP r0, #(1 :SHL: 15) ; ensure in range - ORRCC r14, r14, r0, LSL #2 - STRCC r14, [r14] ; any old data will do - EXIT - - GBLA DAGIndex -DAGIndex SETA 0 - - MACRO - DAGTab $reason, $address - ASSERT ($reason)=DAGIndex - & $address -DAGIndex SETA DAGIndex + 1 - MEND - -DAGAddressTable - DAGTab MEMCDAG_VInit, VInit - DAGTab MEMCDAG_VStart, VStart - DAGTab MEMCDAG_VEnd, VEnd - DAGTab MEMCDAG_CInit, CInit - ] -;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; CAM manipulation utility routines - -BangCamUpdate ROUT - -; R2 = CAM entry no -; R3 = logaddr -; R9 = current MEMC value -; R11 = PPL -; set and update tables - - MOV R4, #0 - LDR R4, [R4, #CamEntriesPointer] - ORR r0, r3, r11, LSL #28 ; top nibble is PPL - STR r0, [R4, R2, LSL #2] - -BangCam - -; r0 corrupted -; r1 corrupted -; R2 = CAM entry no -; R3 = logaddr -; r4 corrupted -; r5 spare! -; r6 corrupted -; r7, r8 spare -; R9 = current MEMC value -; r10 spare -; R11 = PPL -; r12 spare - - AND R4, R9, #&C ; pagesize - ADR R0, PageMangleTable - LDR R0, [R0, R4] ; load data table pointer - MOV R4, #0 -01 LDR R1, [R0], #4 - CMP R1, #-1 - BEQ %FT02 - AND R6, R2, R1 - LDR R1, [R0], #4 - CMP R1, #0 - RSBMI R1, R1, #0 - ORRPL R4, R4, R6, LSL R1 - ORRMI R4, R4, R6, LSR R1 - B %BT01 - -02 LDR R1, [R0], #4 - CMP R1, #-1 - BEQ %FT03 - AND R6, R3, R1 - LDR R1, [R0], #4 - CMP R1, #0 - RSBMI R1, R1, #0 - ORRPL R4, R4, R6, LSL R1 - ORRMI R4, R4, R6, LSR R1 - B %BT02 - -03 ORR R4, R4, #CAM - ORR R4, R4, R11, LSL #8 ; stuff in PPL - STR R4, [R4] ; and write it - MOV PC, LR - -; Data to drive CAM setting - -PageMangleTable - & PageMangle4K - & PageMangle8K - & PageMangle16K - & PageMangle32K - -; For each page size, pairs of masks and shift factors to put the bits in the -; right place. Two sets: operations on Physical Page Number, operations on -; Logical Page Number. - -; Shifts are Shift Left values (<<). Each section terminated by -1 - -PageMangle4K -; PPN: - & 2_011111111 - & 0 ; bits in right place - & -1 -; LPN: - & 2_1100000000000:SHL:12 - & (11-12)-12 ; LPN[12:11] -> A[11:10] - & 2_0011111111111:SHL:12 - & (22-10)-12 ; LPN[10:0 ] -> A[22:12] - & -1 - -PageMangle8K -; PPN: - & 2_010000000 - & 7-7 ; PPN[7] -> A[7] - & 2_001000000 - & 0-6 ; PPN[6] -> A[0] - & 2_000111111 - & 6-5 ; PPN[5:0] -> A[6:1] - & -1 -; LPN: - & 2_110000000000:SHL:13 - & (11-11)-13 ; LPN[11:10] -> A[11:10] - & 2_001111111111:SHL:13 - & (22-9)-13 ; LPN[9:0] -> A[22:13] - & -1 - -PageMangle16K -; PPN: - & 2_010000000 - & 7-7 ; PPN[7] -> A[7] - & 2_001100000 - & 1-6 ; PPN[6:5] -> A[1:0] - & 2_000011111 - & 6-4 ; PPN[4:0] -> A[6:2] - & -1 -; LPN: - & 2_11000000000:SHL:14 - & (11-10)-14 ; LPN[10:9] -> A[11:10] - & 2_00111111111:SHL:14 - & (22-8)-14 ; LPN[8:0] -> A[22:14] - & -1 - -PageMangle32K -; PPN: - & 2_100000000 - & 12-8 ; PPN[8] -> A[12] - & 2_010000000 - & 7-7 ; PPN[7] -> A[7] - & 2_001000000 - & 1-6 ; PPN[6] -> A[1] - & 2_000100000 - & 2-5 ; PPN[5] -> A[2] - & 2_000010000 - & 0-4 ; PPN[4] -> A[0] - & 2_000001111 - & 6-3 ; PPN[3:0] -> A[6:3] - & -1 -; LPN: - & 2_1100000000:SHL:15 - & (11-9)-15 ; LPN[9:8] -> A[11:10] - & 2_0011111111:SHL:15 - & (22-7)-15 ; LPN[7:0] -> A[22:15] - & -1 - -PageSizes - & 4*1024 ; 0 is 4K - & 8*1024 ; 4 is 8K - & 16*1024 ; 8 is 16 - & 32*1024 ; C is 32 - -PageShifts - = 12, 13, 0, 14 ; 1 2 3 4 - = 0, 0, 0, 15 ; 5 6 7 8 - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; SWI OS_UpdateMEMC: Read/write MEMC1 control register - -SSETMEMC ROUT - - AND r10, r0, r1 - MOV r12, #0 - TEQP pc, #SVC_mode+I_bit+F_bit - LDR r0, [r12, #MEMC_CR_SoftCopy] ; return old value - BIC r11, r0, r1 - ORR r11, r11, R10 - BIC r11, r11, #&FF000000 - BIC r11, r11, #&00F00000 - ORR r11, r11, #MEMCADR - STR r11, [r12, #MEMC_CR_SoftCopy] - STR r11, [r11] - TEQP pc, #SVC_mode+I_bit - ExitSWIHandler - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; -; ClearPhysRAM - Routine to clear "all" memory -; -; While this routine is running, keyboard IRQs may happen. For this reason -; it avoids LogRAM 0..31 (where hardware IRQ vector is) and PhysRAM -; 0..31 where the IRQ workspace is. -; - -ClearPhysRAM ROUT - MOV R0, #0 - MOV R1, #0 - MOV R2, #0 - MOV R3, #0 - MOV R4, #0 - MOV R5, #0 - MOV R6, #0 - MOV R11, #0 - MOV R8, #PhysRam - CMP R13, #512*1024 - ADDEQ R10, R8, #(512-64)*1024 ; get address that's logram 0 - ADDNE R10, R8, #512*1024 - ADD R13, R13, #PhysRam ; end of memory - ADD R8, R8, #4*8 ; skip minimal startup workspace -10 CMP R8, R10 - ADDEQ R8, R8, #4*8 ; skip physram that's logram 0 - STMNEIA R8!, {R0-R6, r11} - CMP R8, R13 - BNE %BT10 - SUB R13, R13, #PhysRam - - LDR R0, =OsbyteVars + :INDEX: LastBREAK - MOV R1, #&80 - STRB R1, [R0] ; flag the fact that RAM cleared - MOV pc, lr - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; -; InitMEMC - Initialise memory controller -; - -InitMEMC ROUT - LDR R0, ResetMemC_Value - STR R0, [R0] ; set ROM access times, refresh on flyback, no DMA - MOV pc, lr - -; -> MemSize - -; (non-destructive) algorithm to determine MEMC RAM configuration -; -; Dave Flynn and Alasdair Thomas -; 17-March-87 -; -; Spooling checkered by NRaine and SSwales ! -; 8MByte check bodged in by APT -; -; NOTE: Routines MemSize and TimeCPU are called by the power-on test software, -; so their specifications MUST not change. -; -; Set MEMC for 32-k page then analyse signature of possible -; external RAM configurations... -; The configurations are: -; -; Ram Size Page Size Configuration (Phys RAM) Signature -;-------------------------------------------------------------------- -; 16MByte 32k 4*32*1Mx1 A13,A20,A21,A22,A23,A23.5 distinct -; 16MByte 32k 16*8*256kx4 A13,A20,A21,A22,A23,A23.5 distinct -; -; 12MByte 32k 3*32*1Mx1 A13,A20,A21,A22,A23 OK, A23.5 fail -; 12MByte 32k 12*8*256kx4 A13,A20,A21,A22,A23 OK, A23.5 fail -; -; 8MByte 32k 2*32*1Mx1 A13,A20,A21,A22 distinct, A23 fail -; 8MByte 32k 8*8*256kx4 A13,A20,A21,A22 distinct, A23 fail -; -; 4Mbyte 32k 32*1Mx1 A13,A21,A20 distinct, A22,A23 fail -; 4Mbyte 32k 4*8*256kx4 A13,A21,A20 distinct, A22,A23 fail -; -; 2Mbyte 32k expandable 2*8*256kx4 A13,A20 distinct, A21 fails -; 2Mbyte ??? 16k fixed 2*8*256kx4 A13,A21 distinct, A20 fails -; -; 1Mbyte 8k 32*256kx1 A13,A20 fail, A19,A18,A12 distinct -; 1Mbyte 8k 8*256kx1 A13,A20 fail, A19,A18,A12 distinct -; 1Mbyte 8k 4*8*64kx4 A13,A20 fail, A19,A18,A12 distinct -; -; 512Kbyte 8k expandable 2*8*64kx4 A13,A20,A19 fail, A12,A18 distinct -; 512Kbyte 4k fixed 2*8*64kx4 A13,A20,A12 fail, A19,A18 distinct -; -; 256Kbyte 4K 8*64kx4 A13,A20,A12,A18 fail, A21,A19 ok -; 256Kbyte 4K 32*64kx1 A13,A20,A12,A18 fail, A21,A19 ok -; - -Z_Flag * &40000000 - -; MemSize routine... enter with 32K pagesize set -; R0 returns page size -; R1 returns memory size -; R2 returns value set in MEMC -; uses R3-R7 - -MemSize ROUT - MOV r7, lr - MOV r0, #PhysRam - ADD r1, r0, #A13 - BL DistinctAddresses - BNE %10 - ADD r1, r0, #A21 - BL DistinctAddresses - MOVNE r0, #Page32K - MOVNE r1, #2048*1024 - BNE MemSizeDone - - MOV r0, #PhysRam - ADD r1, r0, #4*1024*1024 - BL DistinctAddresses - MOVNE r0, #Page32K - MOVNE r1, #4*1024*1024 - BNE MemSizeDone - - MOV r0, #PhysRam - ADD r1, r0, #8*1024*1024 - BL DistinctAddresses - MOVNE r0, #Page32K - MOVNE r1, #8*1024*1024 - BNE MemSizeDone - - MOV r0, #PhysRam - ADD r1, r0, #12*1024*1024 - BL DistinctAddresses - MOV r0, #Page32K - MOVNE r1, #12*1024*1024 - MOVEQ r1, #16*1024*1024 - B MemSizeDone - -10 ADD r1, r0, #A20 - BL DistinctAddresses - BNE %20 - MOV r0, #Page16K - MOV r1, #2048*1024 - B MemSizeDone - -20 ADD r1, r0, #A19 - BL DistinctAddresses - BEQ %30 - MOV r0, #Page8K - MOV r1, #512*1024 - B MemSizeDone - -30 ADD r1, r0, #A18 - BL DistinctAddresses - BEQ %40 - MOV r0, #Page4K - MOV r1, #256*1024 - B MemSizeDone - -40 ADD r1, r0, #A12 - BL DistinctAddresses - BEQ %50 - MOV r0, #Page4K - MOV r1, #512*1024 - B MemSizeDone - -50 MOV r0, #Page8K - MOV r1, #1024*1024 - -MemSizeDone - LDR r2, ResetMemC_Value - BIC r2, r2, #&C - ORR r2, r2, r0 - STR r2, [r2] ; set MEMC to right state - MOV pc, r7 - - -; DistinctAddresses routine... -; r0,r1 are the addresses to check -; uses r2-5 -; writes interleaved patterns (to prevent dynamic storage...) -; checks writing every bit low and high... -; return Z-flag set if distinct - -DistinctAddresses ROUT - LDR r2, [r0] ; preserve - LDR r3, [r1] - LDR r4, Pattern - STR r4, [r0] ; mark first - MOV r5, r4, ROR #16 - STR r5, [r1] ; mark second - LDR r5, [r0] - CMP r5, r4 ; check first - BNE %10 ; exit with Z clear - LDR r5, [r1] ; check second - CMP r5, r4, ROR #16 ; clear Z if not same - BNE %10 -; now check inverse bit writes - STR r4, [r1] ; mark second - MOV r5, r4, ROR #16 - STR r5, [r0] ; mark first - LDR r5, [r1] - CMP r5, r4 ; check second - BNE %10 ; exit with Z clear - LDR r5, [r0] ; check first - CMP r5, r4, ROR #16 ; clear Z if not same -10 STR r3, [r1] ; restore - STR r2, [r0] - ORREQ lr, lr, #Z_Flag - BICNE lr, lr, #Z_Flag - MOVS pc, lr - -Pattern - & &AAFF5500 ; shiftable bit check pattern - -; init state with masked out page size - -ResetMemC_Value - & &E010C :OR: MEMCADR ; slugged ROMs + flyback refresh only + 32K page - -; Constants -; -A21 * 1:SHL:21 -A20 * 1:SHL:20 -A19 * 1:SHL:19 -A18 * 1:SHL:18 -A13 * 1:SHL:13 -A12 * 1:SHL:12 - -Page32K * &C ; in MEMC control reg patterns... -Page16K * &8 -Page8K * &4 -Page4K * &0 - - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; In r0-r6 trashable -; r9 = Current MEMC CR - -; Out r9 MEMC value with slowest ROM speed, correct pagesize -; r7 processor speed in kHz, tbs -> MEMC1a - -ncpuloops * 1024 ; don't go longer than 4ms without refresh ! -nmulloops * 128 - -TimeCPU ROUT - - BIC r9, r9, #3 :SHL: 8 - STR r9, [r9] ; turn off refresh for a bit - -; Time CPU/Memory speed - - LDR r1, =&7FFE ; 32K @ 2MHz = ~16ms limit - MOV r3, #IOC - - MOV r0, r1, LSR #8 - STRB r1, [r3, #Timer1LL] - STRB r0, [r3, #Timer1LH] - LDR r0, =ncpuloops - STRB r0, [r3, #Timer1GO] ; start the timer NOW - B %FT10 ; Looks superfluous, but is required - ; to get ncpuloops pipeline breaks - -10 SUBS r0, r0, #1 ; 1S - BNE %BT10 ; 1N + 2S - - STRB r0, [r3, #Timer1LR] ; latch count NOW - LDRB r2, [r3, #Timer1CL] - LDRB r0, [r3, #Timer1CH] - ADD r2, r2, r0, LSL #8 ; count after looping is ... - - SUB r2, r1, r2 ; decrements ! - MOV r2, r2, LSR #1 ; IOC clock decrements at 2MHz - -; Time CPU/MEMC Multiply time - - MOV r4, #-1 ; Gives worst case MUL - - MOV r0, r1, LSR #8 - STRB r1, [r3, #Timer1LL] - STRB r0, [r3, #Timer1LH] - LDR r0, =nmulloops - STRB r0, [r3, #Timer1GO] ; start the timer NOW - B %FT20 ; Looks superfluous, but is required - ; to get nmulloops pipeline breaks - -20 MUL r5, r4, r4 ; 1S + 16I - MUL r5, r4, r4 ; 1S + 16I - SUBS r0, r0, #1 ; 1S - BNE %BT20 ; 1N + 2S - - STRB r0, [r3, #Timer1LR] ; latch count NOW - LDRB r4, [r3, #Timer1CL] - LDRB r0, [r3, #Timer1CH] - ADD r4, r4, r0, LSL #8 ; count after looping is ... - - SUB r4, r1, r4 ; decrements ! - MOV r4, r4, LSR #1 ; IOC clock decrements at 2MHz - - ORR r9, r9, #1 :SHL: 8 ; set refresh on flyback - STR r9, [r9] ; restore MEMC state a.s.a.p. - -; In ROM - each cpu loop took 4R cycles @ 8/f*500ns/cycle - - LDR r0, =4*(8*500/1000)*ncpuloops*1000 - DivRem r7, r0, r2, r1 ; r2 preserved - MOV r0, #&80 ; At 8 MHz and below, run fast ROMs - LDR r1, =8050 ; Over 8 MHz, need medium ROMs - CMP r7, r1 - MOVHI r0, #&40 - LDR r1, =13000 ; Over 13 MHz, need slowest ROMs - CMP r7, r1 - MOVHI r0, #&00 - ORR r9, r9, r0 - STR r9, [r9] ; Set ROM speed appropriately - - ASSERT ncpuloops = 8*nmulloops ; for given ratio cutoff <------------ - - MOV r4, r4, LSL #10 ; *1024 to get resolution on divide - DivRem r0, r4, r2, r1 - LDR r1, =1100 ; Cutoff point; MEMC1 longer than this - CMP r0, r1 - ORRLO r7, r7, #1 :SHL: 16 ; Note MEMC1a prescence - - MOV pc, lr - -; Typical figures give (in ROM at 8MHz): - -; MEMC1 2048 CPU, 2432 MEMC -> MUL ratio 1216 -; MEMC1a 2048 864 432 - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - END diff --git a/TestSrc/Mem1IOMD b/TestSrc/Mem1IOMD deleted file mode 100644 index 4a8354f5..00000000 --- a/TestSrc/Mem1IOMD +++ /dev/null @@ -1,708 +0,0 @@ -; > TestSrc.Mem1IOMD - - TTL RISC OS 2+ POST memory linetest -; -; This test code is used to perform basic integrity tests on DRAM. -; It doesn't test all locations - just walks patterns through data -; and address lines. -; -;------------------------------------------------------------------------ -; History -; -; Date Name Comment -; ---- ---- ------- -; 1-Jun-93 ArtG Derived from Mem1 for use on Medusa -; 18-Nov-94 RCM Morris changes -; 24-Jun-96 BAR Change the IOMD ID code checking code, -; instead of checking for ARM7500 and skipping -; ARM7500 specifi code if not equal, not -; checks for original (RriscPC) IOM ID code -; and skip if equal, thus ARM7500 and -; ARM7500FE parts still do correct test. -; 08-Jul-96 BAR Ensure r0 is cleared before checking IOMD vsn no. -; -;------------------------------------------------------------------------ - -; -; Test the data and address and byte strobe lines for uniqueness. -; - - LTORG - ROUT - -1 - = "VRAM :",0 -2 - = "VRAM-F",&88,&ff,&ff,&ff,&ff,&ff,&ff,&ff,&ff,0 -3 - = "DRAM ",&ff,":",0 -4 - = "Data :",0 -5 - = &88,&ff,&ff," MByte",0 - - ALIGN - -ts_LineTest - [ MorrisSupport - MOV r12, #IOMD_Base - MOV r0,#0 ; Clear out r0 - LDRB r1,[r12,#IOMD_ID1] ; load r1 with IOMD ID high byte - ORR r0,r0,r1, LSL #8 ; Or r0 and r1 - shifted left 8, put in r0 - LDRB r1,[r12,#IOMD_ID0] ; load r1 with IOMD ID low byte - ORR r0,r0,r1 ; Or r0 and r1, put in r0 - LDR r1,=ts_IOMD_ID1 ; get Ref IOMD ID code #1 (Original) - CMPS r0,r1 ; check for IOMD ID Code #1 - BEQ ts_LineTestIOMD ; Original IOMD, not 7500 or 7500FE, assume RiscPC hardware -; -; Here bceause its an ARM7500 or ARM7500 'FE' variant : Morris H/W -; - MOV r11, #IOMD_DRAMWID_DRAM_32bit * &0F ;set all 4 banks to be 32bit initially - LDR r1, =ts_IOMD_ID3 - TEQ r0, r1 ; are we on FE part? - ORREQ r11, r11, #IOMD_DRAMWID_EDO_Enable :OR: IOMD_DRAMWID_RASCAS_3 :OR: IOMD_DRAMWID_RASPre_4 - ; if so, then enable EDO and slower RASCAS and RASPre times - -; ts_LineTest for Morris -; - MOV r14, #IOMD_Base - STRB r11, [r14, #IOMD_DRAMWID] - -; enable 32-bit addressing of data, also forces 26 bit mode, if ARM 6/7 (since P bit zero) - MOV r0,#MMUC_D - SetCop r0,CR_Control - - MOV r0,#0 - MOV_fiq r9,r0 ; r9-fiq records low DRAM address for use elsewhere - - MOV r10, #0 ;indicate no RAM found yet - MOV r9, #IOMD_DRAMWID_DRAM_16bit ;bit to OR into DRAMWID to set 16bit - MOV r12, #DRAM0PhysRam -; -; r12 DRAM address -; r9 IOMD_DRAMWID_DRAM_16bit for current DRAM bank -; r11 current IOMD_DRAMWID register contents -; -;ExamineDRAMBank ;examine first/next DRAM bank -2005 -; - MOV r8,r12,LSL #2 ; indicate bank under test - AND r8,r8,#(3 :SHL: 28) - ADR r4,%BT3 - BL ts_SendText -; - MOV r8,#0 ; r8 indicates RAM found in this bank - - LDMIA r12, {r1, r2} ;Preserve the two locations that we widdle on - - ADRL r3, funnypatterns ;We write different values to two locations - LDMIA r3, {r3, r4} ; incase bus capacitance holds our value - STMIA r12, {r3, r4} - LDMIA r12, {r5, r6} ;Reread test locations - EORS r5, r5, r3 ;Both locations should read correctly - EOR r6, r6, r4 ; if memory is 32bits wide - ;TEQ r5, #0 - TEQEQ r6, #0 - BEQ %FT2010 ;32bit wide memory - - TST r5, #&00FF ;If the bottom 16bits of each location - TSTEQ r5, #&FF00 ; are correct, the memory is 16bits wide - TSTEQ r6, #&00FF - TSTEQ r6, #&FF00 - BNE %FT2050 ;No memory in this bank - - ORR r11, r11, r9 ;Bank is 16bits wide -2010 - STMIA r12, {r1, r2} ;Restore the two locations we widdled on - ;Must do BEFORE poking the DRAMWID register - MOV r14, #IOMD_Base ; - STRB r11, [r14, #IOMD_DRAMWID] ; -; -; minimum ram test -; - MOV r0, r12 - ADD r1, r12, #A18 - BL DistinctAddresses - BNE %FT2050 ;Less than 512KBytes, so ignore this bank - - MOV_fiq r2,r9 ; if this is the first bank of DRAM or VRAM, - TEQS r2,#0 ; put it's address in r9_fiq - BNE %FT2012 - MOV_fiq r9,r0 -2012 - - - MOV r6, #0 ;Fragment address - MOV r7, #0 ;Fragment address - MOV r8, #A19 ; now go through address lines A19-A25 -2015 - MOV r0, r12 - ADD r1, r12, r8 ; see if this address line is unique - BL DistinctAddresses - BNE %FT2020 ; if we've failed then r8 is true size, so exit - MOV r8, r8, LSL #1 ; else shift up to next - TEQ r8, #A26 ; only test up to A25 - BNE %BT2015 - BEQ %FT2035 ;Bank fully occupied, DON'T test for higher fragments -2020 -; -; Found some DRAM, at address r0, size r8. -; There may be one or two higher address lines connected, so scan upto A25 looking for -; extra DRAM chunks. -; - MOV r1, r8 -2025 - TEQ r1, #A25 - BEQ %FT2035 ;No higher active address lines found ie one lump of DRAM - ADD r1, r0, r1,LSL #1 - BL DistinctAddresses - SUB r1, r1, r0 ;Recover bit value - BNE %BT2025 -; -; Got a 2nd fragment, at address r1 (also of size r8) -; - MOV r6, r1 -2030 - TEQ r1, #A25 - BEQ %FT2035 ;No higher active address lines found ie two lumps of DRAM - ADD r1, r0, r1,LSL #1 - BL DistinctAddresses - SUB r1, r1, r0 ;Recover bit value - BNE %BT2030 -; -; Got another active address line (ie total four fragments) -; - MOV r7, r1 -; -2035 -; -; Found 1, 2 or 4 lumps of DRAM -; -;NoRamInBank -2050 - MOV r13, r8 - TEQ r6, #0 - MOVNE r13, r13, LSL #1 - TEQNE r7, #0 - MOVNE r13, r13, LSL #1 ; remember size of this bank in bytes - MOV r8,r13,LSL #(24 - 20) ; and display it in 2 digits, in MBytes. - ADR r4,%BT5 - BL ts_MoreText - - - ADRL r4,%FT73 ; announce data line test - BL ts_SendText - MOV r1,r12 ; do walking bit test - BL ts_Dataline - BEQ %FT2055 ; looks OK, carry on to next bank - - ADRL r4,%FT74 ; bit test failed, so report it - MOV r8,r0 - BL ts_SendText ; and bit fault mask - - CMPS r13,#0 ; was any RAM thought to be here ? - BEQ %FT2055 - FAULT #R_LINFAILBIT ; if so, it's faulty. - MOV r13,#0 ; so ignore it -2055 -2055 -; -; If there was some RAM found here, and it passed the dataline test, -; do the address and bytestrobe tests on it too. -; - CMPS r13,#0 - BEQ %FT2060 - - ADRL r4,%FT75 ; announce start of address line test - BL ts_SendText - MOV r1,r12 ; test address lines in this block - MOV r0,r13, LSR #2 ; bank may be in 4 fragments - BL ts_Addrline - BEQ %FT2056 - ADRL r4,%FT76 ; failed - report error mask - MOV r8,r0 - BL ts_SendText - FAULT #R_LINFAILBIT ; and record failure - MOV r13,#0 ; then forget this memory block - -2056 - ADR r4,%FT77 ; announce start of byte test - BL ts_SendText - MOV r1,r12 - BL ts_Byteword - BEQ %FT2060 - ADR r4,%FT78 ; failed - report error mask - MOV r8,r0,LSL #16 - BL ts_SendText - FAULT #R_LINFAILBIT ; and record failure - MOV r13,#0 ; then forget this memory block -2060 - - -; If the RAM found still seems OK, add it's size into the r10 accumulator -; Working or not, carry on to check the next bank. - - ADD r10,r10,r13 ; accumulate DRAM if any found - ADD r12, r12, #DRAM1PhysRam-DRAM0PhysRam ; move onto next bank - MOV r9, r9, LSL #1 ; shunt up position in DRAMWID - CMP r9, #&0010 ; if more banks to do - BLT %BT2005 ; then loop - - ADR r4,%FT70 - BL ts_SendText ; None found .. print message - - MOVS r8,r10,LSL #(24 - 20) ; all finished .. - ADREQL r4,%FT71 ; did we find any DRAM? - ADRNEL r4,%FT72 - BNE %FT2065 - FAULT #R_LINFAILBIT ; fault if we didn't -2065 - BL ts_MoreText - B ts_endline - - - ] - -ts_LineTestIOMD - ADR r4,%BT1 - BL ts_SendText ; Start data line tests on VRAM - - MOV r0,#0 - MOV_fiq r9,r0 ; r9-fiq records VRAM or low DRAM address - - MOV r12, #IOMD_Base - MOV r2, #IOMD_VREFCR_VRAM_256Kx64 :OR: IOMD_VREFCR_REF_16 ; assume 2 banks of VRAM by default - STRB r2, [r12, #IOMD_VREFCR] - -; Find the size, using MemSize's method - - MOV r0, #VideoPhysRam ; point at VRAM - ADD r1, r0, #A2 ; test A2 - BL DistinctAddresses - MOVEQ r9, #2 ; we've got 2M of VRAM - BEQ %FT21 - - MOV r2, #IOMD_VREFCR_VRAM_256Kx32 :OR: IOMD_VREFCR_REF_16 - STRB r2, [r12, #IOMD_VREFCR] - ADD r1, r0, #A2 ; check for any VRAM at all - BL DistinctAddresses - MOVEQ r9, #1 ; we've got 1M of VRAM - MOVNE r9, #0 ; no VRAM -21 - BNE %FT22 - MOV_fiq r9,r0 ; record VRAM address - FAULT #R_VRAM ; indicate VRAM present - -; Report size .. if this is non-zero and the data line test fails, -; RISC OS will have problems. - -22 - ADR r4,%BT5 ; Add size (in hex Mbyte) - MOV r8,r9, LSL #24 ; to "VRam : " message - BL ts_MoreText - -; Worked out what size VRAM is, and set up IOMD register. -; Do a data line test on the resulting array, repeated at oddword address to -; ensure both banks get tested with walking 0 and walking 1 - - ADR r4,%BT4 - BL ts_SendText - MOV r1, #VideoPhysRam - BL ts_Dataline - ADDEQ r1,r1,#4 - BLEQ ts_Dataline - BEQ %FT25 ; looks OK - carry on with VRAM test -; -; Data line test failed. Report the bitmap that failed, then carry on. -; - ADR r4,%BT2 - MOV r8,r0 ; report data fault mask - BL ts_SendText - B %FT30 - -; -; If there was some VRAM found here, and it passed the dataline test, -; do the address and bytestrobe tests on it too. -; - -25 - ADRL r4,%FT75 ; announce start of address line test - BL ts_SendText - MOV r1,#VideoPhysRam - MOV r0,r9,LSL #20 ; size in MB determined before dataline test - BL ts_Addrline - BEQ %FT26 - ADRL r4,%FT76 ; failed - report error mask - MOV r8,r0 - BL ts_SendText - FAULT #R_LINFAILBIT ; and record failure - B %FT30 -26 - ADRL r4,%FT77 ; announce start of byte test - BL ts_SendText - MOV r1,#VideoPhysRam - BL ts_Byteword - ADDEQ r1,r1,#4 ; retest at an oddword boundary - BLEQ ts_Byteword - BEQ %FT27 - ADRL r4,%FT78 ; failed - report error mask - MOV r8,r0,LSL #16 - BL ts_SendText - FAULT #R_LINFAILBIT ; and record failure -27 - - -; Similarly, test each DRAM bank in turn, reporting failures or sizes for each - -30 - MOV r11, #IOMD_DRAMCR_DRAM_Large * &55 ; set all banks to be large initially - MOV r14, #IOMD_Base - STRB r11, [r14, #IOMD_DRAMCR] - -; enable 32-bit addressing of data, also forces 26 bit mode, if ARM 6/7 (since P bit zero) - MOV r0,#MMUC_D - SetCop r0,CR_Control - - MOV r10, #0 ; indicate no RAM found yet - MOV r9, #IOMD_DRAMCR_DRAM_Small ; bit to OR into DRAMCR - MOV r12, #DRAM0PhysRam -35 - MOV r8,r12,LSL #2 ; indicate bank under test - AND r8,r8,#(3 :SHL: 28) - ADRL r4,%BT3 - BL ts_SendText - - MOV r8,#0 ; r8 indicates RAM found in this bank - MOV r0, r12 - ADD r1, r12, #A10 ; this should be OK for both configurations - BL DistinctAddresses - BNE %FT50 ; [no RAM in this bank at all] - - MOV_fiq r2,r9 ; if this is the first bank of DRAM or VRAM, - TEQS r2,#0 ; put it's address in r9_fiq - BNE %FT36 - MOV_fiq r9,r0 - -36 ADD r1, r12, #A11 ; test for 256K DRAM - BL DistinctAddresses - ORRNE r11, r11, r9 ; it is, so select small multiplexing - MOVNE r14, #IOMD_Base - STRNEB r11, [r14, #IOMD_DRAMCR] ; store new value of DRAMCR, so we can use memory immediately - MOVNE r8, #1024*1024 ; must be 1Mbyte at this address - BNE %FT50 - -; it's bigger than 256K words, so test address lines A21-A25 in sequence -; we assume that the size of each bank is a power of 2 - - MOV r8, #A21 ; now go through address lines A21-A25 -40 - ADD r1, r12, r8 ; see if this address line is unique - BL DistinctAddresses - BNE %FT50 ; if we've failed then r8 is true size, so exit - MOV r8, r8, LSL #1 ; else shift up to next - TEQ r8, #A26 ; only test up to A25 - BNE %BT40 - -50 - MOV r13,r8 ; remember size of this bank in bytes - MOV r8,r13,LSL #(24 - 20) ; and display it in 2 digits, in MBytes. - ADRL r4,%BT5 - BL ts_MoreText - - ADRL r4,%FT73 ; announce data line test - BL ts_SendText - MOV r1,r12 ; do walking bit test - BL ts_Dataline - BEQ %FT55 ; looks OK, carry on to next bank - - ADRL r4,%FT74 ; bit test failed, so report it - MOV r8,r0 - BL ts_SendText ; and bit fault mask - - CMPS r13,#0 ; was any RAM thought to be here ? - BEQ %FT55 - FAULT #R_LINFAILBIT ; if so, it's faulty. - MOV r13,#0 ; so ignore it -55 - -; -; If there was some RAM found here, and it passed the dataline test, -; do the address and bytestrobe tests on it too. -; - CMPS r13,#0 - BEQ %FT60 - - ADR r4,%FT75 ; announce start of address line test - BL ts_SendText - MOV r1,r12 ; test address lines in this block - MOV r0,r13 - BL ts_Addrline - BEQ %FT56 - ADR r4,%FT76 ; failed - report error mask - MOV r8,r0 - BL ts_SendText - FAULT #R_LINFAILBIT ; and record failure - MOV r13,#0 ; then forget this memory block - -56 - ADR r4,%FT77 ; announce start of byte test - BL ts_SendText - MOV r1,r12 - BL ts_Byteword - BEQ %FT60 - ADR r4,%FT78 ; failed - report error mask - MOV r8,r0,LSL #16 - BL ts_SendText - FAULT #R_LINFAILBIT ; and record failure - MOV r13,#0 ; then forget this memory block -60 - - -; If the RAM found still seems OK, add it's size into the r10 accumulator -; Working or not, carry on to check the next bank. - - ADD r10,r10,r13 ; accumulate DRAM if any found - ADD r12, r12, #DRAM1PhysRam-DRAM0PhysRam ; move onto next bank - MOV r9, r9, LSL #2 ; shunt up position in DRAMCR - CMP r9, #&100 ; if more banks to do - BCC %BT35 ; then loop - - ADR r4,%FT70 - BL ts_SendText ; None found .. print message - - MOVS r8,r10,LSL #(24 - 20) ; all finished .. - ADREQ r4,%FT71 ; did we find any DRAM? - ADRNE r4,%FT72 - BNE %FT65 - FAULT #R_LINFAILBIT ; fault if we didn't -65 - BL ts_MoreText - B ts_endline - - -70 - = "DRAM",0 -71 - = &88,"Failed",0 -72 - = &88,&ff,&ff," MByte",0 -73 - = "Data :",0 -74 - = "Data-F",&88,&ff,&ff,&ff,&ff,&ff,&ff,&ff,&ff,0 -75 - = "Addrs :",0 -76 - = "Addrs-F",&88,&ff,&ff,&ff,&ff,&ff,&ff,&ff,&ff,0 -77 - = "Byte :",0 -78 - = "Byte-F",&88,&ff,&ff,&ff,&ff,0 - - -; -; Data line test. -; -; In : r1 - start address for test -; -; Out : r0 - failing data pattern -; r1 - address of failure -; -; -; This exercises data lines in attempt to find shorts/opens. -; It goes something like : -; -; for (ptr = address, pattern = 1; pattern != 0; pattern <<= 1) -; *ptr++ = pattern; -; *ptr++ = ~pattern; -; for (ptr = address, pattern = 1; pattern != 0; pattern <<= 1) -; result |= pattern ^ *ptr++; -; result |= ~pattern ^ *ptr++; -; return result and address -; - -ts_Dataline ROUT - -; -; Write all walking-zero, walking-one patterns -; -10 MOV r6,r1 ; set pointer for a write loop - MOV r5,#1 ; set initial test pattern - MVN r4,r5 ; and it's inverse -11 - STMIA r6!,{r4-r5} ; write the patterns - - ADDS r5,r5,r5 ; shift the pattern (into Carry) - MVN r4,r5 - BCC %BT11 ; repeat until all bits done -; -; Read back and accumulate in r0 any incorrect bits -; - MOV r6,r1 ; set pointer for a read loop - MOV r5,#1 ; set initial test pattern - MVN r4,r5 ; and it's inverse - MOV r0,#0 ; accumulate result -21 - LDMIA r6!,{r2-r3} ; read the patterns - EOR r2,r2,r4 - ORR r0,r0,r2 ; OR any failed bits into r0 - EOR r3,r3,r5 - ORR r0,r0,r2 - - ADDS r5,r5,r5 ; shift the pattern (into Carry) - MVN r4,r5 - BCC %BT21 ; repeat until all bits done -; -; After all checks at this address group, report back errors -; - MOVS r0,r0 ; check for any result bits set - MOV pc,r14 ; return r0 with error map (or 0) - - - -; -; Address line test -; -; In : r0 - size of memory block -; r1 - start address of memory block -; -; Out : r0 - failing address bit mask -; -; This exercises address lines in an attempt to find any which don't -; work (i.e., don't select unique addresses). -; -; It works something like : -; -; MaxRam = PhysRam | (Memory size - 4); -; for (pattern = 4; pattern < memsize; pattern <<= 1 ) -; *(PhysRam ^ pattern) = pattern; -; *(MaxRam ^ pattern) = ~pattern; -; for (pattern = 4; pattern < memsize; pattern <<= 1 ) -; if (*PhysRam == *(PhysRam ^ pattern)) -; result |= pattern; -; if (*MaxRam == *(MaxRam + pattern)) -; result |= pattern; -; return result -; - - -ts_Addrline ROUT - - MOVS r7,r0 ; Save memory size - SUB r6,r0,#4 ; Calculate MaxRam - ADD r6,r6,r1 ; (all-bits-set memory address) -; -; Mark (walking one, walking 0) addresses with unique patterns -; - LDR r5,=&5A5AA5A5 ; initialize end markers - STR r5,[r6] - MVN r4,r5 - MOV r3,r1 - STR r4,[r3] - - MOV r5,#4 ; initialize pattern -02 - MVN r4,r5 - EOR r3,r5,r1 ; point to (start ^ pattern) - STR r4,[r3] - EOR r3,r5,r6 ; point to (end ^ pattern) - STR r5,[r3] - - MOV r5,r5,LSL #1 ; shift test pattern up - CMPS r5,r7 ; test bit still inside memory ? - BCC %02 ; reached top bit - end this loop -; -; Check (walking one, walking 0) addresses for effectivity -; - MOV r5,#4 ; initialize pattern - MOV r3,r1 - MOV r0,#0 -04 - MVN r4,r5 - EOR r2,r5,r3 ; point to (start ^ pattern) - LDR r2,[r2] - LDR r1,[r3] - CMPS r1,r2 ; do contents differ ? - ORREQ r0,r0,r5 ; no - record ineffective bit - - EOR r2,r5,r6 ; point to (end ^ pattern) - LDR r2,[r2] - LDR r1,[r6] - CMPS r1,r2 ; do contents differ ? - ORREQ r0,r0,r5 ; no - record ineffective bit - - MOV r5,r5,LSL #1 ; shift test pattern up - CMPS r5,r7 ; test bit still inside memory ? - BCC %04 ; reached top bit - end this loop - - MOVS r0,r0 ; any result bits set - return error - MOV pc,r14 - - -; -; Byte / word test -; -; In : r1 - memory start -; -; Out : r0 - Failure indication -; -; This test ensures that individual bytes may be written to each part of a word -; without affecting the other bytes in the word. -; -; for (byte = 0; byte < 4; byte ++) -; address[0] = word_signature -; address[1] = ~word_signature -; address + byte = byte_signature -; if (address[0] != -; (word_signature & (~ff << byte * 8)) -; | (byte_signature << byte * 8) ) -; result |= (1 << byte) -; if (result != 0 -; result |= address; /* fail at address, byte(s) */ -; return result; /* pass */ -; - -ts_Byteword ROUT - - LDR r3,=&AABBCCDD ; word signature - MOV r0,#0 - MOV r2,r0 -; -; byte test loop ( for bytes 0 to 4 ...) -; -02 - MVN r4,r3 - STMIA r1,{r3,r4} ; write word signature - STRB r2,[r1,r2] ; write byte (0, 1, 2 or 3) - - MOV r4,r2,LSL #3 ; calculate expected result - MOV r5,#&ff - MVN r5,r5,LSL r4 - AND r5,r5,r3 ; word signature, byte removed - ORR r5,r5,r2,LSL r4 ; byte signature inserted - - LDR r4,[r1,#4] ; read (probable) inverse data to precharge bus - LDR r4,[r1] ; read modified word - CMPS r4,r5 - MOV r5,#1 - MOV r4,r2,LSL #2 - ORRNE r0,r0,r5,LSL r4 ; fault : set bit in result mask -; -; Loop for next byte -; - ADD r2,r2,#1 ; Bump byte counter - CMPS r2,#4 ; ... until 4 byte strobes tested - BLO %BT02 -; -; byte strobes all tested : check for errors -; - CMPS r0,#0 - MOV pc,r14 ; Result : return address and fault mask. - -; -; End of RAM line tests -; - -ts_endline - - END diff --git a/TestSrc/Mem1MEMC1 b/TestSrc/Mem1MEMC1 deleted file mode 100644 index 632c9bf2..00000000 --- a/TestSrc/Mem1MEMC1 +++ /dev/null @@ -1,390 +0,0 @@ -; > TestSrc.Mem1 - - TTL RISC OS 2+ POST memory linetest -; -; This test code is used to perform basic integrity tests on DRAM. -; It doesn't test all locations - just walks patterns through data -; and address lines. -; -;------------------------------------------------------------------------ -; History -; -; Date Name Comment -; ---- ---- ------- -; 18-Dec-89 ArtG Initial version -; 1-Jun-93 ArtG Reorganised to allow separate module for Medusa -; -; -;------------------------------------------------------------------------ - -; -; Test the data and address and byte strobe lines for uniqueness. -; - - LTORG - ROUT - -1 - = "Data :",0 -2 - = "Data @",&89,&ff,&ff,&ff,&ff,&ff,&ff,&ff,0 -3 - = "Data-F",&88,&ff,&ff,&ff,&ff,&ff,&ff,&ff,&ff,0 -4 - = "Data-P",&88,&ff,&ff,&ff,&ff,&ff,&ff,&ff,&ff,0 - - - - ALIGN - -ts_LineTest - - ADR r4,%BT1 - BL ts_SendText ; Start data line tests - - MOV_fiq r0,r10_fiq - MOV r1, #PhysRam - BL ts_Dataline - BEQ ts_address ; OK : continue to next test -; -; Data line test failed. This probably also means that RISCOS got the -; configuration wrong, so set it to 32K pages and repeat - otherwise -; the data line test result may be garbage. -; - ADR r4,%BT2 - MOV r11,r0 ; save data & report fault address - MOV r8,r1,LSL #4 - BL ts_SendText - - MOV r8,r11 - ADR r4,%BT3 ; report data fault mask - BL ts_SendText - - LDR r0,=(&E000C :OR: MEMCADR) ; set 32K page size - STR r0,[r0] - MOV_fiq r11_fiq,r0 - - MOV r0,#ts_RamChunk ; limit test to 1 block - MOV r1,#PhysRam - BL ts_Dataline - - MOV r8,r0 - ADR r4,%BT4 ; ready to report data fault mask - B ts_linefault - -; -; Start the address line tests -; - ROUT - -4 - = "Addrs :",0 -5 - = "Addrs",&89,&ff,&ff,&ff,&ff,&ff,&ff,&ff,0 -6 - = "Byte :",0 -7 - = "Byte",&89,&ff,&ff,&ff,&ff,&ff,&ff,&ff,0 - - - -ts_address - ADR r4,%BT4 - BL ts_SendText ; Start address line tests - - MOV_fiq r0,r10_fiq - BL ts_Addrline - - ADR r4,%BT5 - MOV r8,r0,LSL #4 - BEQ %30 ; Failed : report address fault - -ts_linefault - FAULT #R_LINFAILBIT - B %31 - -30 ADR r4,%BT6 ; Start Byte/Word test - BL ts_SendText - - MOV_fiq r0,r10_fiq ; get memory size - BL ts_Byteword - - MOV r8,r0,LSL #4 ; Get result to top of r8 - BEQ %40 - FAULT #R_LINFAILBIT - - ADR r4,%BT7 - -31 BL ts_SendText - B %42 -; -; Line tests passed. Do a short test on memory that isn't there, -; in case it's supposed to be and we want to know why it's not .. - -40 - MOV_fiq r0, r10_fiq ; if there's less than 16Mbytes .. - CMP r0, #(16 * 1024 * 1024) - BCS %F42 - ADR r4, %FT44 ; briefly test the next bit of ram - BL ts_SendText ; in case it's a duff expansion - - MOV_fiq r1,r10_fiq - ADD r1,r1,#PhysRam - MOV r0,#ts_RamChunk - BL ts_Dataline - ADR r4, %FT45 - MOV r11, r0 ; report the result even if OK - MOV r8,r1,LSL #4 - BL ts_SendText ; report address - - MOV r8,r11 - ADR r4,%FT46 ; report data fault mask - BL ts_SendText -; -; End of line tests -; - -42 - B ts_IOCTest - -44 - = "Exp? :",0 -45 - = "Exp? @",&89,&ff,&ff,&ff,&ff,&ff,&ff,&ff,0 -46 - = "Exp?",&88,&ff,&ff,&ff,&ff,&ff,&ff,&ff,&ff,0 - - - -; -; Data line test. -; -; In : r0 - size of memory -; r1 - start address for test -; -; Out : r0 - failing data pattern -; r1 - address of failure -; -; -; This exercises data lines in attempt to find shorts/opens. -; It goes something like : -; -; for (address = start; address < end of ram; address += ts_RamChunk) -; for (ptr = address, pattern = 1; pattern != 0; pattern <<= 1) -; *ptr++ = pattern; -; *ptr++ = ~pattern; -; for (ptr = address, pattern = 1; pattern != 0; pattern <<= 1) -; result |= pattern ^ *ptr++; -; result |= ~pattern ^ *ptr++; -; if (result |= 0) -; return result and address -; - -ts_Dataline ROUT - - ADD r7,r1,r0 ; end address -; -; Write all walking-zero, walking-one patterns -; -10 MOV r6,r1 ; set pointer for a write loop - MOV r5,#1 ; set initial test pattern - MVN r4,r5 ; and it's inverse -11 - STMIA r6!,{r4-r5} ; write the patterns - - ADDS r5,r5,r5 ; shift the pattern (into Carry) - MVN r4,r5 - BCC %BT11 ; repeat until all bits done -; -; Read back and accumulate in r0 any incorrect bits -; - MOV r6,r1 ; set pointer for a read loop - MOV r5,#1 ; set initial test pattern - MVN r4,r5 ; and it's inverse - MOV r0,#0 ; accumulate result -21 - LDMIA r6!,{r2-r3} ; read the patterns - EOR r2,r2,r4 - ORR r0,r0,r2 ; OR any failed bits into r0 - EOR r3,r3,r5 - ORR r0,r0,r2 - - ADDS r5,r5,r5 ; shift the pattern (into Carry) - MVN r4,r5 - BCC %BT21 ; repeat until all bits done -; -; After all checks at this address group, report back errors -; - MOVS r0,r0 ; check for any result bits set - MOVNE pc,r14 ; return on error -; -; Bump to another address group -; - ADD r1,r1,#ts_RamChunk - CMPS r1,r7 ; test for loop end - BLO %10 - - SUBS r1,r1,#ts_RamChunk ; no fault - last tested address - MOVS r0,r0 - MOV pc,r14 ; test complete - no failures. - - -; -; Address line test -; -; In : r0 - size of memeory -; -; Out : r0 - failing address bit mask -; -; This exercises address lines in an attempt to find any which don't -; work (i.e., don't select unique addresses). -; -; It works something like : -; -; MaxRam = PhysRam | (Memory size - 4); -; for (pattern = 4; pattern < memsize; pattern <<= 1 ) -; *(PhysRam ^ pattern) = pattern; -; *(MaxRam ^ pattern) = ~pattern; -; for (pattern = 4; pattern < memsize; pattern <<= 1 ) -; if (*PhysRam == *(PhysRam ^ pattern)) -; result |= pattern; -; if (*MaxRam == *(MaxRam + pattern)) -; result |= pattern; -; return result -; - - -ts_Addrline ROUT - - MOVS r7,r0 ; Save memory size - SUB r6,r0,#4 ; Calculate MaxRam - ADD r6,r6,#PhysRam ; (all-bits-set memory address) -; -; Mark (walking one, walking 0) addresses with unique patterns -; - LDR r5,=&5A5AA5A5 ; initialize end markers - STR r5,[r6] - MVN r4,r5 - MOV r3,#PhysRam - STR r4,[r3] - - MOV r5,#4 ; initialize pattern -02 - MVN r4,r5 - EOR r3,r5,#PhysRam ; point to (start ^ pattern) - STR r4,[r3] - EOR r3,r5,r6 ; point to (end ^ pattern) - STR r5,[r3] - - MOV r5,r5,LSL #1 ; shift test pattern up - CMPS r5,r7 ; test bit still inside memory ? - BCC %02 ; reached top bit - end this loop -; -; Check (walking one, walking 0) addresses for effectivity -; - MOV r5,#4 ; initialize pattern - MOV r3,#PhysRam - MOV r0,#0 -04 - MVN r4,r5 - EOR r2,r5,r3 ; point to (start ^ pattern) - LDR r2,[r2] - LDR r1,[r3] - CMPS r1,r2 ; do contents differ ? - ORREQ r0,r0,r5 ; no - record ineffective bit - - EOR r2,r5,r6 ; point to (end ^ pattern) - LDR r2,[r2] - LDR r1,[r6] - CMPS r1,r2 ; do contents differ ? - ORREQ r0,r0,r5 ; no - record ineffective bit - - MOV r5,r5,LSL #1 ; shift test pattern up - CMPS r5,r7 ; test bit still inside memory ? - BCC %04 ; reached top bit - end this loop - - MOVS r0,r0 ; any result bits set - return error - MOV pc,r14 - - -; -; Byte / word test -; -; In : r0 - memory size -; -; Out : r0 - address of physical ram where failure occured -; -; This test ensures (for each of four possible MEMCs fitted) -; that individual bytes may be written to each part of a word -; without affecting the other bytes in the word. -; -; for (address = PhysRam; address < PhysRam + Memsize; address += 4Mbyte) -; for (byte = 0; byte < 4; byte ++) -; address[0] = word_signature -; address[1] = ~word_signature -; address + byte = byte_signature -; if (address[0] != -; (word_signature & (~ff << byte * 8)) -; | (byte_signature << byte * 8) ) -; result |= (1 << byte) -; if (result != 0 -; result |= address; /* fail at address, byte(s) */ -; return result; -; return result; /* pass */ -; - -ts_Byteword ROUT - - ADD r7,r0,#PhysRam ; Set test limit address - MOV r1,#PhysRam ; Initial test address - LDR r3,=&AABBCCDD ; word signature -; -; MEMC test loop (for addresses 4M, 8M, ...) -; -01 - MOV r0,#0 ; clear result register - MOV r2,#0 ; clear byte count -; -; byte test loop ( for bytes 0 to 4 ...) -; -02 - MVN r4,r3 - STMIA r1,{r3,r4} ; write word signature - STRB r2,[r1,r2] ; write byte - - MOV r4,r2,LSL #3 ; calculate expected result - MOV r5,#&ff - MVN r5,r5,LSL r4 - AND r5,r5,r3 ; word signature, byte removed - ORR r5,r5,r2,LSL r4 ; byte signature inserted - - LDR r4,[r1,#4] - LDR r4,[r1] ; read modified word - CMPS r4,r5 - MOV r5,#1 - ORRNE r0,r0,r5,LSL r2 ; fault : set bit in result mask -; -; Loop for next byte -; - ADD r2,r2,#1 ; Bump byte counter - CMPS r2,#4 ; ... until 4 byte strobes tested - BLO %BT02 -; -; byte strobes all tested : check for errors -; - CMPS r0,#0 - ORRNE r0,r0,r1 - MOVNE pc,r14 ; Error : return address and fault. -; -; Loop for next MEMC -; - ADD r1,r1,#&400000 ; Bump to next MEMC - CMPS r1,r7 - BLO %01 - - MOVS r0,#0 ; Passed - return OK - MOV pc,r14 - - - END - \ No newline at end of file diff --git a/TestSrc/Mem2 b/TestSrc/Mem2 deleted file mode 100644 index 09e9b97a..00000000 --- a/TestSrc/Mem2 +++ /dev/null @@ -1,312 +0,0 @@ -;> MEM2C -; -; RISC OS 2+ BOOT TEST SOFTWARE -; MEMORY TEST 2 VERSION A. -; BRIAN RICE 30-10-89 -; 06-Apr-90 ArtG 0.1 Test variable memory size -; -; This file will perform a simple test on all DRAM. -; The test code for this test was taken from thhe A680 Quick memory -; test software. The software was copied straight but the number of times -; the test looped arround was cut down to two loops, because of time -; constraints when testing the memory. - -Test_wks_msize * &40 ; Space for test block size -Test_wks_return1 * &44 ; Space for return addresses -Test_wks_return2 * &48 -Test_code_off * &4C ; Where testing starts - -test_size * 13 * 4 ; Size of test group -test_mem_rsvd * Test_code_off+test_mem_template_end-test_mem_template - -; -; Quick test the RAM (pre boot style) -; - -ts_RamTest ROUT - MOV r13,r0 - STR r14,[r13,#Test_wks_return1] - STR r1,[r13,#Test_wks_msize] - - LDR r0, test_quick_pattern - BL test_mem_code - ORRS r0,r0,r0 - BNE test_mem_quit -; - LDR r0, test_quick_pattern - MVN r0, r0 ; inverse pattern - BL test_mem_code - ORRS r0,r0,r0 - -test_mem_quit - ADR r12,%22 - BEQ %10 - -; If fault detected, exit with zero flag clear, r0 pointing to failing -; location, r1 containing faulty data and r2 pointing a suitable error -; message indicating whether all-0 or all-1 data was expected. - - LDR r2,[r14] ; fetch failing instructiom - ANDS r2,r2,#1 ; calculate expected data - ADREQ r12,%20 ; and load suitable message - ADRNE r12,%21 - MOVS r0,r0 ; with zero flag set for PASS. -10 - LDR pc,[r13,#Test_wks_return1] - -; Fail messages indicate incorrect data read after WRote 0 or Wrote 1 -; to all bits at that location. - -20 - = "WR-0 RD",&88,&ff,&ff,&ff,&ff,&ff,&ff,&ff,&ff,0 -21 - = "WR-1 RD",&88,&ff,&ff,&ff,&ff,&ff,&ff,&ff,&ff,0 -22 - = "??",0 - - ALIGN - -test_quick_pattern & &0f76 - -; Large Memory test. Generates the write + test routines in memory -; then calls them. The routine tests patterns as defined by the bottom -; 13 bits of r0. -; -; N.B. The test start address must be calculated to ensure that -; the loops finish exactly with r0 equal to End_memory -; -; The routine returns with eq true if the memory is OK. - - -test_mem_code - ROUT - - STR r14, [r13, #Test_wks_return2] -; -; Copy the ram test code into low ram, modifying MOV instructions -; to MVN in accordance with the test pattern. -; - ADR r1, test_mem_template - ADD r2, r13, #Test_code_off - LDMIA r1!, {r3-r4} ; copy initial 2 instrucions - STMIA r2!, {r3-r4} - MOV r4, #1 -0 MOVS r0, r0, ROR #1 - LDR r3, [r1], #4 - ORRCS r3, r3, #&00400000 ; Convert MOV => MVN - STR r3, [r2], #4 - ADD r4, r4, #1 - CMP r4, #13 - BLE %B0 -; -; Copy the load loop control and verify start instructions -; - LDMIA r1!, {r5-r9} - STMIA r2!, {r5-r9} -; -; Copy and modify the CMP instructions -; - MOV r0, r0, ROR #32-13 - MOV r4, #1 -1 MOVS r0, r0, ROR #1 - LDR r3, [r1], #4 - ORRCS r3, r3, #&00200000 ; Convert CMP => cmn - ORRCS r3, r3, #&00000001 ; Convert #0 => #1 - STR r3, [r2], #4 - ADD r4, r4, #1 - CMP r4, #13 - BLE %B1 -; -; Copy the verify loop control and finishing-up instructions -; - LDMIA r1!, {r5-r12} - STMIA r2!, {r5-r12} - LDMIA r1!, {r5-r12} - STMIA r2!, {r5-r12} - LDMIA r1!, {r5-r12} - STMIA r2!, {r5-r12} - -; check we've copied enough - ASSERT ((test_mem_stadd - test_mem_chk) = (24 * 4)) -; -; Calculate the test start and end addresses -; - LDR r0, [r13, #Test_wks_msize] ; size of test area - ADD r14, r13, r0 ; end of test area - SUB r1, r0, #test_mem_rsvd ; testable size - - MOV r2, #test_size ; adjust r1 to (r1 / 13*4) * (13*4) - DivRem r3, r1, r2, r4 - MUL r1, r3, r2 - SUB r0, r14, r1 ; rounded test start address - -; Do it. - MOV r1, #Test_code_off - ADD r1, r1, r13 ; pointer to copied code - MOV pc, r1 - -; -; The following code is copied (and modified) into RAM for execution -; - -test_mem_template - ROUT - STR r0, test_mem_stadd ; save initial RAM address - STR r13, test_mem_base ; save test area base address - MOV r1, #0 ; Converted to MVN if bit = 1 - MOV r2, #0 ; Converted to MVN if bit = 1 - MOV r3, #0 ; Converted to MVN if bit = 1 - MOV r4, #0 ; Converted to MVN if bit = 1 - MOV r5, #0 ; Converted to MVN if bit = 1 - MOV r6, #0 ; Converted to MVN if bit = 1 - MOV r7, #0 ; Converted to MVN if bit = 1 - MOV r8, #0 ; Converted to MVN if bit = 1 - MOV r9, #0 ; Converted to MVN if bit = 1 - MOV r10, #0 ; Converted to MVN if bit = 1 - MOV r11, #0 ; Converted to MVN if bit = 1 - MOV r12, #0 ; Converted to MVN if bit = 1 - MOV r13, #0 ; Converted to MVN if bit = 1 -0 - STMIA r0!, {r1-r13} - CMP r0, r14 - BLO %B0 - - LDR r0, test_mem_stadd -1 - LDMIA r0!, {r1-r13} -2 - CMP r1, #0 ; Converted to cmn if bit = 1 - CMPEQ r2, #0 ; Converted to cmneq if bit = 1 - CMPEQ r3, #0 ; Converted to cmneq if bit = 1 - CMPEQ r4, #0 ; Converted to cmneq if bit = 1 - CMPEQ r5, #0 ; Converted to cmneq if bit = 1 - CMPEQ r6, #0 ; Converted to cmneq if bit = 1 - CMPEQ r7, #0 ; Converted to cmneq if bit = 1 - CMPEQ r8, #0 ; Converted to cmneq if bit = 1 - CMPEQ r9, #0 ; Converted to cmneq if bit = 1 - CMPEQ r10, #0 ; Converted to cmneq if bit = 1 - CMPEQ r11, #0 ; Converted to cmneq if bit = 1 - CMPEQ r12, #0 ; Converted to cmneq if bit = 1 - CMPEQ r13, #0 ; Converted to cmneq if bit = 1 -test_mem_chk - BNE %F5 ; go report fault data - CMP r0, r14 - BLO %B1 ; else loop for next batch - MOVS r0, #0 ; All OK : return with NULL r0 -4 - LDR r13,test_mem_base - LDR pc, [r13, #Test_wks_return2] - -; Failed : repeat the last batch of tests one at a time, to determine -; the first failing address and data. -; Note that the test instructions are copied to %8 to permit individual -; execution, and %7 is overwritten with an instruction used to copy -; the failing data into r1. Change this code very carefully ! - -5 - LDR r14,%2 ; Obtain first test in the set - STR r14,%8 ; and re-execute it - SUB r0,r0,#(13*4) ; adjust pointer to bad data - ADR r14,%2 ; point to first test. -7 - B %8 ; make sure %8 is refetched -8 - & 0 ; redo the test here : - BNE %4 ; if it failed, exit with - ; r0 = ptr to memory - ; r1 = wrongly read data - ; r14 => failing instruction - - LDR r1,[r14,#4]! ;fetch next instruction - AND r1,r1,#&f0000 ;make an instruction - MOV r1,r1,LSR #16 ;to copy the next register - ORR r1,r1,#&E1000000 ;down to r1 - ORR r1,r1,#&00A00000 ;e.g. CMPEQ r10,#0 - ORR r1,r1,#&00001000 - STR r1,%7 ;and put it at %7 - LDR r1,[r14] ;then copy the next test - STR r1,%8 ;to %8 - ADD r0,r0,#4 ;bump the fault pointer - B %7 ;and execute %7 and %8. - -test_mem_stadd ; address of first test location - & 0 -test_mem_base - & 0 ; address of test block - -test_mem_template_end - -; -; Copy the L2 page table from r1 to r0, then remap the translation table's -; base address in the MMU to point to an L1 page table within it. -; - ROUT - -ts_remap_ttab - - [ StrongARM_POST - ;make sure ARM810 cache or StrongARM data cache is cleaned/flushed, because we are going to remap - ARM_read_ID r3 - AND r3,r3,#&F000 - CMP r3,#&8000 - BNE %FT22 -;ARM810 -;;; ARM8_cleanflush_IDC r3 ;not implemented yet - B %FT24 -22 - CMP r3,#&A000 - BNE %FT24 -;StrongARM -;tricky...we'll read 16k of data in current ROM space, to act as clean and flush of current data - MOV r3,pc - BIC r3,r3,#31 ;32 byte aligned - ARMA_clean_DC r3,r4,r5 -24 - ] ;StrongARM_POST - - MOV r2,#FixedAreasL2Size - ADD r0,r0,r2 ; point to locations in PhysSpace - ADD r0,r0,#PhysSpace - ADD r1,r1,r2 - ADD r1,r1,#PhysSpace -10 - ASSERT ((FixedAreasL2Size :AND: ((8*4)-1)) = 0) - LDMDB r1!,{r3-r10} ; copy the page & section tables - STMDB r0!,{r3-r10} - SUBS r2,r2,#(8*4) - BNE %BT10 - - SUB r9,r1,r0 ; r9 = offset from original to copy - ADD r0, r0, #DRAMOffset_L1PT-DRAMOffset_L2PT ; r0 -> copy of L1Phys - SUB r10, r0, #PhysSpace ; keep real address of L1PT for MMU - ADD r2,r0,#((1 :SHL: (32-20))*4) ; size of L1PT - 1 word per meg of memory -11 LDR r3,[r0],#4 ; check each L1 table entry - ANDS r4,r3,#3 - CMPS r4,#L1_Page ; if it's page mapped .. - SUBEQ r3,r3,r9 ; adjust the page table base address - STREQ r3,[r0,#-4] - CMPS r0,r2 ; repeat for all the level 1 table - BNE %BT11 - - SetCop r10, CR_TTabBase ; set up MMU pointer to L1 - - [ StrongARM_POST - ;flush cache if ARM 6/7 (ARM 8,StrongARM already sorted, above) - ;flush TLB(s) - ARM_read_ID r4 - AND r4,r4,#&F000 - CMP r4,#&8000 ;ARM 8? - CMPNE r4,#&A000 ;or StrongARM? - MCRNE ARM_config_cp,0,R0,ARM67_cacheflush_reg,C0,0 ;flush 6/7 cache - MCRNE ARM_config_cp,0,R0,ARM67_TLBflush_reg,C0,0 ;flush 6/7 TLB - MCREQ ARM_config_cp,0,R0,ARM8A_TLB_reg,C7,0 ;flush 8/StrongARM TLB(s) - | - SetCop r0, CR_IDCFlush ; flush cache + TLB just in case - SetCop r0, CR_TLBFlush ; (data written is irrelevant) - ] - - MOV pc,r14 - - - END - diff --git a/TestSrc/Mem3 b/TestSrc/Mem3 deleted file mode 100644 index 5b22aa2a..00000000 --- a/TestSrc/Mem3 +++ /dev/null @@ -1,127 +0,0 @@ - ;> RomCheck -; -; RISC OS 2+ BOOT TEST SOFTWARE -; MEMORY TEST 3 VERSION A. -; BRIAN RICE 01-11-89 -; 24.04.90 0.10 ArtG Added ROM size test -; 15.05.90 1.00 ArtG Changed to put checksum at (end - 2 words) -; 17.05.90 1.01 ArtG Changed to get ROM length from vectot table -; 16-Aug-96 1.02 JRH Gets ROM start using PC-relative addressing, -; to support OSimages in 1st or 2nd ROM bank -; -; -; This file will perform quick checksum test on the OS ROMS. -; -; -; The test code for this test is a simple additive checksum routine. -; The software will read eight words from ROM then add the contents from ROM -; to a register. When the test is complete the contents of the checksum -; register is checked by adding the final word in ROM - this should give -; zero. -; The program will be run from ROM, at slowest speed. -; -; All except the last two words are checksummed : these hold the numbers -; that cause each individual ROM to CRC to zero, so they can't simultaneously -; be included in an all-zero additive checksum. - -ts_CRCsize * (2 * 4) - -; -; -;r0 IS A POINTER TO THE LOCATIONS IN MEMORY. -;r1 HAS THE CALCULATED CHECKSUM. -;r2 HOLDS A COUNTER INDICATION HOW MANY WORDS ARE LEFT TO GET -;r3 is a temporary variable -;r4 TO r11 ARE USED TO LOAD THE CONTENTS OF 8 LOCATIONS FROM THE ROM. -; - ROUT - -ts_ROM_checksum - -;StrongARM_POST issue: -;ARM810 - this will probably go bang! because ARM810 aborts if the processor -; vectors (00 - 1C) are read in 26-bit mode - - MOV r1, #&00 ; initialise accumulator - ADRL r0, ROM ; initialise pointer using PC-relative - ; addressing (could be 1st or 2nd bank) - LDR r2, [r0, #ts_ROMSIZE] ; initialise endstop - ADD r2, r2, r0 ; - must be at least 8 words - SUB r2, r2, #(10 * 4) ; below the real endpoint - -loop1 LDMIA r0!, {r4 - r11} ;LOAD r4 TO r11 WITH THE CONTENTS - ;OF LOCATIONS POINTED TO BY r0 - ;WHICH IS INCREMEMTED AUTOMATICALLY - ;TO POINT TO THE NEXT LOCATION -01 - ADD r1, r1, r4 ;ADD r4 TO CHECKSUM - ADD r1, r1, r5 ;ADD r5 TO CHECKSUM - ADD r1, r1, r6 ;ADD r6 TO CHECKSUM - ADD r1, r1, r7 ;ADD r7 TO CHECKSUM - ADD r1, r1, r8 ;ADD r8 TO CHECKSUM - ADD r1, r1, r9 ;ADD r9 TO CHECKSUM - ADD r1, r1, r10 ;ADD r10 TO CHECKSUM - ADD r1, r1, r11 ;ADD r11 TO CHECKSUM -02 - ASSERT ((%02 - %01) = 32) ; else r2 won't count down correctly - - CMPS r0, r2 - BCC loop1 ;loop until pointer reaches endstop - - LDMIA r0!, {r4 - r9} ; get last 6 words (miss last 2 in ROM) -03 - ADD r1, r1, r4 ;ADD r4 TO CHECKSUM - ADD r1, r1, r5 ;ADD r5 TO CHECKSUM - ADD r1, r1, r6 ;ADD r6 TO CHECKSUM - ADD r1, r1, r7 ;ADD r7 TO CHECKSUM - ADD r1, r1, r8 ;ADD r8 TO CHECKSUM - ADD r1, r1, r9 ;ADD r9 TO CHECKSUM -04 - ASSERT (((%04 - %03) + (2*4)) = 32) ; Change this if you like - - ; but be careful to count nearly - ; to the top in eights, then add - ; add in the last few words. - - MOVS r0,r1 ; should be zero if all OK - - MOV pc,r14 ;return with zero flag set on OK - ;and the calculated sum in r0. - - -; -; ROM alias check. -; This test looks for an aliased copy of the vector table at varying -; distances from the start of ROM space. -; 16K is fairly arbitrary but corresponds approximately with the size of -; the POST. If there's an alias below that, we've probably already crashed ! -; -; This test is only called if the checksum fails, in order to indicate a -; possible high ROM address line failure. - -ts_ROM_alias ROUT - - ADRL r0, ROM ; initialise pointer using PC-relative - ; addressing (could be 1st or 2nd bank) - LDR r3,[r0, #ts_ROMSIZE] ; get the ROM length word - LDMIA r0,{r4,r5,r6,r7} - MOV r1,#(16 * 1024) - -01 ADD r2,r0,r1 ; get some words from possible alias - LDMIA r2,{r8,r9,r10,r11} - CMPS r4,r8 - CMPNE r5,r9 - CMPNE r6,r10 - CMPNE r7,r11 - BEQ %10 ; aliased : found MS ROM address bit - - MOVS r1, r1, LSL #1 ; test the next (more significant) bit - CMPS r1, r3 ; reached the limit yet ? - BLT %01 ; no - try again. - -10 MOV r0,r1 ; reached the end, or an alias. - MOV pc,lr - - - LTORG - - END diff --git a/TestSrc/Mem4 b/TestSrc/Mem4 deleted file mode 100644 index 5d712673..00000000 --- a/TestSrc/Mem4 +++ /dev/null @@ -1,630 +0,0 @@ -;> MEM4H_SCR -; -; RISC OS 2+ BOOT TEST SOFTWARE. -; MEMORY TEST 4 VERSION H. BRIAN RICE 12-01-90. -; 04-Apr-90 ArtG 0.1 Added ts_count_cams, improved reporting -; 11-Apr-90 ArtG 0.2 Use RISC OS routine BangCams for -; alternate MEMC configurations. -; 17-Apr-90 ArtG 0.3 rationalise page-counting code -; -; This file will be called by MEM6x_SCR for the purposes of assembly. -; This file will perform quick walking bit test on the CAM Entry points. -; The test code for this test was taken from the A680 test code. -; -; The module requires the running of the memory sizing routine used by -; the OS to set up the page size for this module. -; -; This test module was designed to operate on all current and future -; machines. The module is designed to handle up to 512 physical pages -; which is the maximum number of pages in a 16 MByte FOX. -; -; A 16 MB FOX has 4 MEMCs in use, each MEMC is addressed by Bits 7 and -; 12 of the logical to physical address translator. The use of bit 12 -; does have a problem in that on machines with 0.5MB of memory this is -; used to define the logical page number. Machine with 1MB or greater bit -; 12 is not used, therefore this test may hit problems on A305's. The -; intention is that A305 owners will upgrade to A310's when upgrading to -; RISC OS 2+. -; -; Because FOX can have up to 4 MEMCs fitted the following addressing is -; used to determine the MEMC accessed, bit 12, bit 7 -; 0 0 = Master MEMC = MEMC 0 -; 0 1 = Slave MEMC 1 = MEMC 1 -; 1 0 = Slave MEMC 2 = MEMC 2 -; 1 1 = Slave MEMC 3 = MEMC 3 -; -; -; This test will initialise the CAM entries for up to 512 physical pages. -; The physical pages will be mapped to logical page 5. Each page will have -; a copy of test routine vectors and a page marker. The page marker consists -; of the page number and a code to indicate which MEMC was used. The code for -; the MEMC used is as follows :- MEMC 0 0001 1110 = &1E -; MEMC 1 0010 1101 = &2D -; MEMC 2 0100 1011 = &4B -; MEMC 3 1000 0111 = &87 -; -; The page marker is arranged as follows &mm5Apppp -; | | -; | \-- Page Number &0000 ‰ &01FF. -; \--------MEMC Code as above. -; -; The patterns are chosen so that if two or more MEMCs are accessed -; together and both RAM outputs get enabled onto the data bus simultaneously, -; then there is a reasonable chance that the data returned will show the -; presence of a fault. -; -; When the CAM entries have been initialised the module will then check that -; all the pages are mapped correctly. A simple walking one pattern is used -; to check that the page is not present anywhere else in the memory area. -; This isn't really sufficient, but keeps the test time low. -; -; The tests are performed with the memory protection level set to 0. -; -; This version uses the "my abort" routine in MEM5x_SCR instead of the -; ts_dab_exp0 .. 5 method as taken from the A680 code. -; - -ts_rst_msg = "RST",0 -ts_uni_msg = "UDF",0 -ts_swi_msg = "SWI",0 -ts_pab_msg = "PAB",0 -ts_dab_msg = "DAB",0 -ts_aex_msg = "ADX",0 -ts_irq_msg = "IRQ",0 -ts_fiq_msg = "FIQ",0 -ts_bxc_msg = &85,"@",&88,&ff,&ff,&ff,&ff,&ff,&ff,&ff,&ff,0 - ALIGN - - -ts_rst ; Unused exception vectors - ADR r4, ts_rst_msg - B ts_bad_exception -ts_uni - ADR r4, ts_uni_msg - B ts_bad_exception -ts_swi - ADR r4, ts_swi_msg - B ts_bad_exception -ts_pab - ADR r4, ts_pab_msg - B ts_bad_exception -ts_dab_unexp - ADR r4, ts_dab_msg - B ts_bad_exception -ts_aex - ADR r4, ts_aex_msg - B ts_bad_exception -ts_irq - ADR r4, ts_irq_msg - B ts_bad_exception -ts_fiq - ADR r4, ts_fiq_msg - B ts_bad_exception - - -ts_bad_exception - SUBS r8, r14, #8 ; remember aborted instruction - BL ts_SendText - ADR r4, ts_bxc_msg ; display aborted address - BL ts_MoreText - B Reset - - -; -ts_rom_base * ROM ; Base address of the OS ROMS. -ts_phys_mem * (32*1024*1024) ; Physical Memory area. -ts_pagemark * &005A0000 ; + phys page number + MEMC code. -ts_pmark_pos * 32 ; Position of page mark (avoiding vectors). -ts_cam_base * &3800000 ; Base address of the CAM table in MEMC. -ts_vrest * &5 ; Unused page which all pages are mapped to. -ts_MAX_CAMS * 512 ; Most CAMs ever expected -ts_memc_codes = &1E, &2D, &4B, &87 ; List of the memc_codes to be used. -; -ts_logpages ; List of Logical pages. - & &0001 - & &0002 - & &0004 - & &0008 - & &0010 - & &0020 - & &0040 - & &0080 - & &0100 - & &0200 - & &03FF - & &03FE - & &03FD - & &03FB - & &03F7 - & &03EF - & &03DF - & &03BF - & &037F - & &02FF - & &01FF - & &0000 ; Terminator for the list. -ts_logpagesend ; End of the list. -; -; -; Exception vectors : copied to start of each page to ensure that they will always -; exist on page zero when arbitrary pages are mapped there. -; -ts_vectors - B (ts_vectors-ts_start)+ts_rom_base+ts_rst - B (ts_vectors-ts_start)+ts_rom_base+ts_uni - B (ts_vectors-ts_start)+ts_rom_base+ts_swi - B (ts_vectors-ts_start)+ts_rom_base+ts_pab -ts_dab_vector - B (ts_vectors-ts_start)+ts_rom_base+ts_dab - B (ts_vectors-ts_start)+ts_rom_base+ts_aex - B (ts_vectors-ts_start)+ts_rom_base+ts_irq - B (ts_vectors-ts_start)+ts_rom_base+ts_fiq - - -; *************************************************************************** -; -ts_CAM -; -; CAM test (full or partial) -; Start of the CAM test, all physical pages have a copy of the vectors -; so they may be mapped as page 0. Then each page is mapped at a series -; of (walking 1, walking 0) logical pages and tested to be correctly -; mapped. Other pages are set to an unused logical page by set_cam_idle -; to prevent any CAM clashes. -; -; Copy the test vectors and page marker into all the pages. -; - ROUT ; Local Branches. - MOV r13, lr ; Preserve link register in r13. - BL ts_count_CAMs ; get log2 pagesize - MOV r0, #ts_MAX_CAMS ; r0 = last page to test - SUB r0, r0, #1 -0 BL ts_copy_vectors ; Gosub ts_vectors. - SUBS r0, r0, #&01 ; bump down to next page - BGE %B0 ; repeatuntil all pages set. -; -; 'C' pseudocode for the test routine. -; -; for (i = &1ff; i >= 0; i--) -; set_cam_idle(i); -; -; find maximum page number. -; if (max_page != ts_count_CAMS) -; report CAM number error -; -; for (phys = &max_page; phys >= 0; phys--) { -; for (logp = &logpages[0]; logp < &logpages[sizof(logpages)]; logp++) { -; if (*logp == 0) { -; set_cam(*logp, phys); -; check_mapped(*logp, phys); -; } else { -; int zphys = (phys + 1) % num_pages; -; set_cam(0, zphys); -; set_cam(*logp, phys); -; check_mapped(*logp, phys); -; set_cam_idle(zphys); -; } -; } -; set_cam_idle(phys); -; } -; -; Idle the pages. -; - ROUT ; Local Branches. - MOV r12, #ts_MAX_CAMS ; always clear all 512 - just in case 4 MEMCs. - SUB r12, r12, #&01 ; Subtract 1 to make max page #. -0 MOV r1, r12 ; r1 = page number. - BL ts_set_cam_idle - SUBS r12, r12, #&01 ; bump to next page downwards - BGE %B0 ; repeatuntil page 0 done -; -; We need to find out what the maximum number of pages is, after running the above routine -; all the pages will have the pagemark programed in to each page. As stated in the intro -; programing the pages from the top down will ensure that, irrespective of the number of -; MEMCs available, that the bottom pages are programed correctly. Therefore if we start -; at the top, read in a page, check it's page number & memc code are correct, if so then -; that is possibly the maximum page number. If not then subtract 1 from the page number and -; try again until a possible good page is found. -; - ROUT ; Local Branches. - - BL ts_count_CAMs ; get log2 pagesize to r1 - MOV r8, #ts_MAX_CAMS ; r8= max. number of physical pages. -0 SUBS r8, r8, #&01 ; Subtract 1 to make it r8 - 1 Pages. - BEQ ts_bad_CAM_count ; no pages ? - shouldn't hit this! -; -; Calculate the expected page marker, in r4, for the current page, in r8. -; - ADR r4, ts_memc_codes ; r4 = address of table with the memc codes. - LDRB r4, [r4, r8, LSR#7] ; r4 = Loc pointed to by r4 + (r1 >> 7). - ORR r4, r8, r4, LSL #24 ; r4 = page number OR (MEMC code << 24). - ORR r4, r4, #ts_pagemark ; r4 = page id OR magic number -; -; The calculated page marker is now in r4, ref_p_mark. -; Current page in r8 - convert to physical address in r9. -; the pagesize power-of-2 is in r1 (from ts_count_CAMs) -; - MOV r9, r8, LSL r1 ; convert PPN to phys offset - ORR r9, r9, #ts_phys_mem ; add offset to start of phys mem -; -; r9 now has the address of the current page - read the page marker for that page. -; - LDR r9, [r9, #ts_pmark_pos] ; r9 = contents of loc pointed to by - ; r9 + ts_pmark_pos. -; -; Check that read_p_mark is valid. -; -; Either the value read is the expected pagemark, junk (no memory) or an -; aliased pagemark - if it's aliased, then either the memory or the MEMC -; isn't decoded that far. -; Bump down and try a bit lower, until it's OK. -; - CMP r4, r9 ; Is page-mark expected value ? - BNE %B0 - -; -; Found a pagemarker in the proper place. Check that the number of pages that -; appear to be present are the same as the number found by ts_count_CAMs -; (i.e. the memory size / page size). -; - SUB r0, r0, #1 ; convert count -> max page number - CMPS r0, r8 - BNE ts_bad_CAM_count -; -; If all is well, we should have the maximum usable page number in r8. -; -; Need to reset page 0 in the CAM entries, currently all pages are mapped to page 5. -; We need to have logical page 0 mapped to physical page 0. -; - MOV r0, #&00 ; r0 = &00, the page to map. - MOV r1, #&00 ; r1 = &00, the page to map to. - MOV r2, #&00 ; r2 = &00, set the protection level. - BL ts_set_camp -; -; Check we can still see the data abort vector at physical page zero -; - no good continuing if we can't. -; - MOV r0, #ts_phys_mem - LDR r0, [r0, #(ts_dab_vector - ts_vectors)] - LDR r1, ts_dab_vector - CMPS r0, r1 - BNE ts_bad_dab_vector - -; -; Now lets get on with the testing. -; - -2 ADRL r10, ts_logpages ; logp = &logpages[0] - -3 LDR r0, [r10] ; r0 = page to test - CMP r0, #&00 ; last entry ? - BNE %F4 - MOV r1, r8 ; r1 = r8, page under test - BL ts_set_cam ; Gosub ts_set_cam. - LDR r0, [r10] ; r0 current logical test page - MOV r1, r8 ; r1 = current test page - BL ts_check_mapped ; Gosub ts_check_mapped. - B %F5 - -4 ADD r12, r8, #&01 - BL ts_count_CAMs ; get total number of pages - SUB r0,r0,#1 ; make a mask for useable page - AND r0,r0,#&7f ; numbers - min(128, num_pages) - AND r12, r12, r0 ; r12 -> (r12 + 1) masked - MOV r0, #&00 ; to useable page numbers. - MOV r1, r12 - BL ts_set_cam ; Setup a page for vectors - LDR r0, [r10] ; r0 = current logical test page. - MOV r1, r8 ; r1 = current physical test page. - BL ts_set_cam ; Setup a page to test - - LDR r0, [r10] ; look up logical page again. - MOV r1, r8 ; recall physical page. - BL ts_check_mapped ; check the ts_set_cam worked. - MOV r1, r12 ; unmap the vector page - BL ts_set_cam_idle - -5 ADD r10, r10, #&04 ; next entry in test list. - ADRL r0, ts_logpagesend ; r0 = ts_logpagesend. - CMP r10, r0 ; repeat until list of logical - BLO %B3 ; pages all done. - - MOV r1, r8 ; unmap the page we just tested - BL ts_set_cam_idle - - SUBS r8, r8, #1 ; bump phys page counter down. - ANDS r8,r8,r8 - BGE %B2 ; If r8 >= 0 Then branch back to 2. - - ANDS r0,r0,#0 - MOV pc,r13 ; all done and passed - -; -; **************************************************************************** -; -ts_copy_vectors -; -; Copies the vectors to the physical page in r0 (preserved) also copies -; pagemark + phypage. -; Expects r1 (preserved) to hold log2 of pagesize -; - ROUT ; Local Branches. - - ADR r2, ts_vectors ; r2 = source address - LDMIA r2, {r4-r11} ; r4 - r11 = loc pointed to by r2, post inc. - - MOV r3, r0, LSL r1 ; r3 = r0 * 2**r1 . - ORR r3, r3, #ts_phys_mem ; r3 = r3 OR ts_phys_mem. - STMIA r3, {r4-r11} ; loc pointed to by r3, post inc = r4 to r11. -; -; find out which memc is handling the page (r0), then assign the appropiate memc_code. -; Add in the page number and pagemark, then store into the required position in the -; page in question. -; - ADR r2, ts_memc_codes ; r2 = address of table with the memc codes. - LDRB r2, [r2, r0, LSR#7] ; r2 = memc code for this phys page. - ORR r2, r0, r2, LSL #24 ; OR in phys page number. - ORR r2, r2, #ts_pagemark ; OR in pagemark. - STR r2, [r3, #ts_pmark_pos] ; loc pointed to by r1 + ts_pmark_pos = pagemark. - MOV pc, lr ; Return to caller. -; -; **************************************************************************** -; -ts_set_cam_idle -; -; This module will program the physical page (r1) to the logical page 5, ts_vrest and -; continue onto the next section ts_set_cam. -; - ROUT ; Local Branches. - MOV r0, #ts_vrest ; r0 = ts_vrest, = unused logical page. -; -; **************************************************************************** -; -ts_set_cam -; -; This module will program the physical page (r1) to the logical page (r0) at -; protection mode 0 and continue onto the next section ts_set_camp. -; - MOV r2, #&00 ; r2 = &00, memory prot level 0. -; -; **************************************************************************** -; -ts_set_camp -; -; This module will map a range the physical pages (r1) to the logical page (r0) and -; set the protection mode (r2). This module will return to the location from where -; either itself or ts_set_cam or ts_set_cam_idle were called from. -; -; Corrupts r0,r1,r2,r3,r4,r6,r9,r11 -; -; Calls the RISC OS routine BangCam to do the PPNO, LPNO bit switching. -; First, jumble the registers to suit BangCam .. -; -; r2 = CAM entry (PPNO) -; r3 = logical address -; r9 = current MEMC setting (for pagesize) -; r11 = PPL -; - MOV r3,r0 ; logical page number - MOV r11,r2 ; protection level - MOV r2,r1 ; physical page number - MOV_fiq r0, r11_fiq ; MEMC configuration - MOV r9, r0 ; keep a copy in r9 - MOV r1, r9, LSR #2 - AND r1, r1, #3 ; calculate pagesize shift - ADD r1, r1, #12 - MOV r3, r3, LSL r1 ; convert LPN to logaddr - B BangCam ; return thro' BangCam - -; -; **************************************************************************** -; -ts_check_mapped -; -; This routine will check that the CAM has been programed correctly and that the required -; page is responding when asked. A quick test is made to check that other pages are not -; responding as well. -; -; logical page in r0, -; physical page in r1, -; test that they are the same. -; -; No return value : reports faults directly and returns thro' r13 -; -; Uses (corrupts) r0,r1,r2,r3,r4,r5,r6,r7 -; -; Find out which memc is handling the page (r1), then assign the appropiate memc_code. -; Add in the page number and pagemark, then compare that pagemark with those found -; in memory at the expected logical and physical addresses. -; -; This code assumes that any system with multiple MEMCs will always have 32K pages. -; - ROUT ; Local Branches. - - MOV r3, r0 ; save the current logical pagenumber. - MOV r5, lr ; Preserve link register in case of Abort. - ADR r2, ts_memc_codes ; r2 = address of table with the memc codes. - LDRB r2, [r2, r1, LSR#7] ; fetch the memc code for this page. - ORR r2, r1, r2, LSL #24 ; build the page number into the pagemark - ORR r2, r2, #ts_pagemark ; build in the pagemark magic number -; -; r2 should now have the page_mark for the current page (r1). -; calculate the shift to convert page number to memory offset. -; - MODE FIQ_mode - MOV r4, r11_fiq, LSR #2 ; pagesize / 4K - MODE SVC_mode - AND r4, r4, #3 - ADD r4, r4, #12 -; -; if the mapping failed completely, the test might abort -; - MOV r6, #&00 ; r6 = &00, clear expected abort flag. - MOV r7, #&94 ; r7 = &94, set abort expected flag. -; -; make the pointers and test the contents -; - MOV r0, r0, LSL r4 ; r0 = LPN * pagesize. - LDR r0, [r0, #ts_pmark_pos] ; r0 = contents of loc in r0 + ts_pmark_pos. - CMP r6, #94 ; did that fetch abort ? - ADREQ r4, %F14 ; mapping totally failed - BEQ ts_CAM_fail - MOV r1, r1, LSL r4 ; r1 = PPN * pagesize. - ORR r1, r1, #ts_phys_mem ; r1 = r1 ORed with ts_phys_mem. - LDR r1, [r1, #ts_pmark_pos] ; r1 = contents of loc in r1 + ts_pmark_pos. - CMP r0, r1 ; Are the read pagemarks equal ?? - ADRNE r4, %F10 - BNE ts_CAM_fail ; Failed : mapping not equal. - CMP r0, r2 ; - ADRNE r4, %F11 - BNE ts_CAM_fail ; Failed : map equal, but corrupt -; -; test that the page doesn't exist anywhere else -; - MOV r2, #1 -0 EOR r0, r2, r3 ; Flip a (walking) bit in the LPN. - CMP r0, #ts_vrest ; Is r0 = ts_vrest ?? Where all the pages are - ; mapped to. - BEQ %F1 ; If r0 = ts_vrest then branch forward to 1. -; -; The following instruction should abort. -; - MOV r0, r0, LSL r4 ; r0 = LPN * pagesize. - MOV r6, #&00 ; r6 = &00, clear abort handled flag. - MOV r7, #&94 ; r7 = &94, set abort expected flag. - LDR r0, [r0, #ts_pmark_pos] ; get a possible pagemark from this page. - CMP r6, #&94 ; Did we go thro' the abort handler ? - BEQ %F1 ; If equal then an abort happened, good ! -; -; Not aborted - is it page zero, where the vectors live ? -; - TEQS r2, r3 - BEQ %F1 ; yes - that SHOULDN'T abort -; -; Fault - is the page mapped there the same as our test page ? -; - CMP r0, r1 - ADREQ r4, %F12 ; Failed : phys page also mapped here - ADRNE r4, %F13 ; Failed : page not unmapped - EOR r3, r2, r3 ; remake the duff LPN for the error display - B ts_CAM_fail - ; If equal then no abort happened, not good !! - -1 MOV r2, r2, LSL#1 ; bump to next-bit-set page number - CMP r2, #(ts_MAX_CAMS :SHL: 1) ; Hit number of logical pages ? - BLT %B0 ; If r2 < maximum number then loop again. - - MOV r7, #0 ; no longer expecting aborts - MOV pc, r5 ; Return to caller. - -; -; Indicate that CAM mapping test failed (PPN is not at LPN) -; Display r8, the physical page number and r3, the logical page. -; -; ***This error exit returns to the CALLER of check_mapped, thro' r13*** -; - -10 - = "CAM map",&88,&ff,&ff,&ff,".",&ff,&ff,&ff,&ff,0 -11 - = "CAM pmk",&88,&ff,&ff,&ff,".",&ff,&ff,&ff,&ff,0 -12 - = "CAM als",&88,&ff,&ff,&ff,".",&ff,&ff,&ff,&ff,0 -13 - = "CAM unm",&88,&ff,&ff,&ff,".",&ff,&ff,&ff,&ff,0 -14 - = "CAM abo",&88,&ff,&ff,&ff,".",&ff,&ff,&ff,&ff,0 - - ALIGN - - -ts_CAM_fail - MOV r0, r8, LSL #16 ; physical page # - LDR r1, =&ffff - AND r1, r1, r3 - ORR r0, r0, r1 ; add logical page # - MOV r8, r0, LSL #4 - MOV r6, #0 ; no longer expecting aborts - ORRS r0, r0, #1 - MOV pc, r13 - -; -; ************************************************************************** -; - -; Routine to return expected number of physical pages in r0. -; Uses memory size determination from r10_fiq and page mode from r11_fiq. -; Returns pagesize as power-of-two in r1, for pagenumber->address calcs. - -ts_count_CAMs - - MODE FIQ_mode - MOV r0,r10_fiq,LSR #12 ; get values determined - MOV r1,r11_fiq,LSR #2 ; by MemSize - MODE SVC_mode - - AND r1,r1,#3 ; memory / pagesize - MOV r0,r0,LSR r1 - ADD r1,r1,#12 ; page bit-shift value - - MOV pc,lr - - -; -; ************************************************************************** -; - ROUT - -; Indicate that an unexpected number of CAM pages were found. -; -; Display as "CAM ## eee.fff" -; -; where eee is the expected maximum page number (r0), fff is the number -; of of the highest page actually found (r8). - -0 - = "CAM ##",&89,&ff,&ff,&ff,".",&ff,&ff,&ff,0 - ALIGN - -ts_bad_CAM_count - ADD r8, r8, r0, LSL #12 - MOV r8, r8, LSL #8 - ADR r4, %B0 - ORRS r0, r0 ,#1 - MOV pc, r13 -; -; ************************************************************************** -; - -; Indicate that the DAB vector wasn't visible in physmem - -0 - = "CAM vec",&88,&ff,&ff,&ff,&ff,&ff,&ff,&ff,&ff,0 - ALIGN - -ts_bad_dab_vector - ADR r4, %B0 - EOR r8,r0,r1 ; indicate which bits are lost - ORRS r0, r0, #1 - MOV pc, r13 -; -; ************************************************************************** - -; Routine to indicate that an unexpected abort was found. - -0 - = "DAB @",&88,&ff,&ff,&ff,&ff,&ff,&ff,&ff,&ff, 0 - ALIGN - -ts_unxvect - ADR r4, %B0 - SUBS r8, r14_svc, #8 ; indicate the aborting instruction - BL ts_SendText - ORRS r0, r0, #1 - MOV pc, r13 - - - - LTORG - - END diff --git a/TestSrc/Mem5 b/TestSrc/Mem5 deleted file mode 100644 index 607a8b8e..00000000 --- a/TestSrc/Mem5 +++ /dev/null @@ -1,316 +0,0 @@ -;>MEM5D_SCR -; -; RISC OS 2+ BOOT TEST SOFTWARE. -; MEMORY TEST 5 VERSION D. BRIAN RICE 10-01-90. -; 04-Apr-90 ArtG 0.1 Use memory size to determine page count -; 11-Apr-90 ArtG 0.2 Changes to permit use of BangCam -; -; This file will be called by MEM6x_SCR for the purposes of assembly. -; This file requires the assembly of MEM4x_SCR to be perfromed at the -; same time. The program will call the cam setting routines in the cam -; test program. -; -; This file will test MEMCs ability to assert its protection over -; logical pages. -; The test code for this test was taken from the A680 test code. -; The Arm CPU has three mode of operation, Supervisor, Operating System. -; and User. Most of the time the machine will operate in user mode, in this. -; mode the designers do not want the user to have full access to the memory. -; map, therefore the MEMC(s) will check that the CPU has the appropiate -; level of authorisation to access specific area of memory. -; User mode is the lowest mode, allowing limited R/W access to the ram. -; Operating System is next up the list and is allowed some more access to -; to the ram than user mode. -; Supervisor mode this is the highest and the CPU has unlimited access to -; the entire memory map. -; -; This version has the "my abort" routine in it not the ts_dab_exp0..5 routine as -; coded from the A680 code. -; -; Set up some variables. -; -ts_wks_word * 36 ; Offset of word for workspace. -; -; **************************************************************************** -; -ts_memc_prot -; -; This module will map and assign protection mode 0 to all the pages. The -; module will then perfrom a read and write operations in supervisor and -; user modes. This is repeated for the three (four) protection modes. -; The module will check after every protection mode level that the required -; responses have been returned. -; -; Set up the memory, map and assign protection mode 0. -; - ROUT ; Local Branches. - MOV r13, lr ; Preserve the link register. - MOV r12, #&00 ; r12 = The physical page to test. - -0 ADD r8, r12, #&01 ; Get a page to use as vectors, - BL ts_count_CAMs ; get total number of pages - SUB r0,r0,#1 ; make a mask for useable page - AND r0,r0,#&7f ; numbers - min(128, num_pages) - AND r8, r8, r0 - - MOV r1, r8 ; r1 = r8, r1 = physical page 0. - MOV r0, #&00 ; r0 = &00, r0 = logical page 0. - BL ts_set_cam ; Gosub ts_set_cam, set the CAM up. -; -; Set protection mode 0 and test that page. -; - MOV r2, #&00 ; r2 = &00, r2 = protection mode 0. - BL ts_mem_prot ; Gosub ts_mem_prot. - CMP r3,#&0F ; Is r3 = &0F ? r3 = Super Read/Write ok. - ; O/S Read/Write ok. - ; User Read/Write ok. - MOV r2, #0 - BNE ts_prot_fail ; If r3 <> &0F Then branch to fail routine. -; -; Set protection mode 1 and test that page. -; - MOV r2, #&01 ; r2 = &01, r2 = protection mode 1. - BL ts_mem_prot ; Gosub ts_mem_prot. - [ CPU_Type = "ARM600" - CMP r3,#&0f ; no ABORT line to ARM600 - | - CMP r3,#&0B ; Is r3 = &0B ? r3 = Super Read/Write ok. - ] ; O/S Read/Write ok. - ; User Read only ok. - - MOV r2,#1 - BNE ts_prot_fail ; If r3 <> &0B Then branch to fail routine. -; -; Set protection mode 2 and test that page. -; - MOV r2, #&02 ; r2 = &02, r2 = protection mode 2. - BL ts_mem_prot ; Gosub ts_mem_prot. - [ CPU_Type = "ARM600" - CMP r3,#&0f ; no ABORT line to ARM600 - | - CMP r3,#&03 ; Is r3 = &03 ? r3 = Super Read/Write ok. - ] ; O/S Read only ok. - ; User No Access ok. - MOV r2,#2 - BNE ts_prot_fail ; If r3 <> &03 Then branch to fail routine. -; -; Set protection mode 3 and test that page. -; - MOV r2, #&03 ; r2 = &03, r2 = protection mode 3. - BL ts_mem_prot ; Gosub ts_mem_prot. - [ CPU_Type = "ARM600" - CMP r3,#&0f ; no ABORT line to ARM600 - | - CMP r3, #&03 ; Is r3 = &03 ? r3 = Super Read/Write ok. - ] ; O/S Read only ok. - ; User No Access ok. - MOV r2,#3 - BNE ts_prot_fail ; If r3 <> &03 Then branch to - ; fail routine. -; -; Reset the page used to idle. -; - MOV r0, r12 ; r0 = r12, idle the pages - ; being used. - BL ts_set_cam_idle ; Gosub ts_set_cam_idle. - MOV r0, r8 ; r0 = r8, idle the pages - ; being used. - BL ts_set_cam_idle ; Gosub ts_set_cam_idle. -; -; Increment the physical page counter and check that all the pages are -; done, else finish. -; - BL ts_count_CAMs - ADD r12, r12, #&01 ; do the next physical page. - CMP r12, r0 ; Done all pages ? - BLT %B0 ; If r12 <= cam_entries, - ; branch back to 0. - - ANDS r0, r0, #0 ; set zero flag : test passed - MOV pc, r13 ; Return to caller. -; -; ************************************************************************** -; -; Branch here when ts_memc_prot fails to get the proper result from -; ts_mem_prot. -; -; At this point, -; -; r3 is a map of permitted ops (user read, user write, sys read, sys write) -; r2 is the memc protection mode -; r12 is the physical page number. -; -; This is displayed as : -; -; PPL bad l.a.pppp -; -; where l is the PPL set on that page (0, 1, 2 or 3) -; a is a bitmap of the actual operations permitted (ur.uw.or.ow) -; p is the physical page number tested -; - -0 - = "PPL bad",&88,&ff,".",&ff,".",&ff,&ff,&ff,&ff,0 - ALIGN - -ts_prot_fail - AND r2, r2, #&0f - MOV r0, r2, LSL #20 ; mode bits - AND r3, r3, #&0f - ORR r0, r0, r3, LSL #16 ; permitted ops bits - BIC r12, r12, #&ff000000 - BIC r12, r12, #&ff0000 - ORR r0, r0, r12 ; current page number - - - ADR r4, %B0 ; get fail message - MOV r8, r0, LSL #8 ; shift number to suit ts_SendText - ORRS r0, r0, #1 ; fail flag - MOV pc, r13 - - -; -; -; This section will test that the physical page referenced in r12 at the set -; protection mode. During the operation of this module, aborts are expected to happen. -; The aborts are handled by the routine ts_dab. -; -; The system is running in supervisor mode and thus to check the user mode read / writes -; the address translator flag is used. The CPU has a signal called -TRANS which when used -; with MEMC forces the an address translation to be performed, this is not done whilst -; in supervisor mode because it has unlimited access to the memory map. The address -; translator falg (T) is used with STR and LDR instructions only, the effective result of -; adding the (T) to the opcode is to force the instruction to be executed as if the CPU -; was in user mode, thus unauthorised accesses will cause an abort to occur. -; -; IN: -; r12 - physical page. -; r2 - protection mode. -; OUT: -; r3 - access pattern. -; r3 = &0F, Super Read/Write ok, O/S Read/Write ok, User Read/Write ok. -; r3 = &0B, Super Read/Write ok, O/S Read/Write ok, User Read only ok. -; r3 = &03, Super Read/Write ok, O/S Read only ok, User No Access ok. -; -ts_mem_prot -; -; Set up data to write and read from memory. -; - MOV r10, lr ; Preserve link register. - MOV r1, r12 ; r1 = physical page. - MOV r0, #&01 ; r0 = logical page 1. - BL ts_set_camp - - MOV r3, #&00 ; Initialise access pattern. - MOV_fiq r5, r11_fiq ; get MEMC control - AND r5, r5, #&C - ADR r9, ts_ppl_tptrs - LDR r9, [r9, r5] ; get test address for this pagesize -; -; Test 1 system mode - write. -; - MOV r6, #&00 ; r6 = &00, clear expected abort flag. - MOV r7, #&94 ; r7 = &94, set abort expected flag. -; -; The following instruction may abort. -; - STR r1, [r9] ; Store r1 at loc pointed to by r9. - CMP r6, #&00 ; Is r6 = &00 ? If not then abort happened. - ORREQ r3, r3, #&01 ; If r6 = &00, Then update r3, access pattern. -; -; Test 2 system mode - read. -; - MOV r6, #&00 ; r6 = &00, clear expected abort flag. - MOV r7, #&94 ; r7 = &94, set abort expected flag. -; -; The following instruction may abort. -; - LDR r1, [r9] ; Load r1 from loc pointed to by r9. - CMP r6, #&00 ; Is r6 = &00 ? If not then abort happened. - ORREQ r3, r3, #&02 ; If r6 = &00 Then update r3, access pattern. -; -; Test 3 user mode - write. -; - MOV r6, #&00 ; r6 = &00, clear expected abort flag. - MOV r7, #&94 ; r7 = &94, set abort expected flag. -; -; The following instruction may abort. -; - STRT r1, [r9] ; Store r1 at loc pointed to by r9. - CMP r6, #&00 ; Is r6 = &00 ? If not then abort happened. - ORREQ r3, r3, #&04 ; If r6 = &00 Then update r3, access pattern. -; -; Test 4 user mode - read. -; - MOV r6, #&00 ; r6 = &00, clear expected abort flag. - MOV r7, #&94 ; r7 = &94, set expected expected flag. -; -; The following instruction may abort. -; - LDRT r1, [r9] ; Load r1 from loc pointed to by r9. - CMP r6, #&00 ; Is r6 = &00 ? If not then abort happened. - ORREQ r3, r3, #&08 ; If r6 = &00 Then update r3, access pattern. - MOV pc, r10 ; Return to caller. - -; -; addresses (a short way up page 1) to test PPL aborts -; - -ts_ppl_tptrs - & ( 4 * 1024) + ts_wks_word - & ( 8 * 1024) + ts_wks_word - & (16 * 1024) + ts_wks_word - & (32 * 1024) + ts_wks_word -; -; -ts_dab -; -; This routine provides the handling when a DATA ABORT occurs. -; The routine will if the abort was DATA cause the program to skip over the instruction -; that caused the abort first place. -; Data aborts could come from a variety of sources, in this module we are only concerned -; about a select group of aborts. This abort routine is called instead of the "usuall" -; abort routine. All that is required from this abort routine is to set a flag to -; indicate that an abort occured. Therefore this routine needs to be told that the -; abort that caused the routine to be called is either one of mine or not, (expected -; or unexpected). To achive this &94 is placed in r7. The abort routine will check -; for the presence of &94 in r7, if present then the abort is an expected abort. -; The abort routine will then copy r7 into r6, which is used as a flag to indicate -; that an abort occured and that it was an expected abort. Then the routine will -; return control to the program at the location after the instruction that caused to -; abort to occur. -; The return address is stored by the CPU into the link regester lr (r14), sort off. -; It must be remembered that the PC is always 2 instructions ahead. E.G. if the -; instruction that causes the abort is at &2000, then the lr will have &2008 in it, -; but we want to return to the location after the abort instruction, &2004. Therefore to -; return to the correct location &04 is removed from the lr and this is put into the pc. -; If the abort was not expected then the routine will jump to the end and another -; routine will show that an unexpected abort was generated. -; -; IN: -; r6 - Equals &00, cleared just before the instruction that could cause an abort. -; r7 - Equals &94, set just before the instruction that could cause an abort. -; -; OUT: -; r6 - Equals &94, set if an abort happened and was expected. -; r7 - Equals &94, preserved. -; - ROUT ; Local Branches. -; -; Check that it is an expected abort and not an unexpected abort. -; - CMP r7, #&94 ; Is r7 = &94, abort expected value. - BNE ts_dab_unexp ; If <> &94, Then branch to unexpected - ; abort handler. -; -; It is an expected abort, so handle it. -; - MOV r6, r7 ; r6 = r7, indicates that an abort happened. - SUB pc, lr, #&04 ; pc = link reg - &04. - ; Skip over aborting instruction. - ; By reloading the pc we return to the area - ; of code where the abort occured but 4 - ; locations further on. - - - END diff --git a/TestSrc/ROMCard b/TestSrc/ROMCard deleted file mode 100644 index bf15a619..00000000 --- a/TestSrc/ROMCard +++ /dev/null @@ -1,222 +0,0 @@ -; > TestSrc.ROMCard - - TTL NCOS Support for ROM Cards -; -; Tests for presence of a 2,4 or 8MB OS image in 2nd ROM bank and jumps to it. -; -; This doesn't really belong in the POST sources, but lives here because it -; needs to happen soon after boot. This file is included inline by Begin before -; it starts calculating the ROM checksum -; -; Relies on width of the 2nd ROM bank already being set to 32bit. -; If 16bit extension ROM support is required then s.ARM600 must set ROMCR1 back -; to 16bit-wide. -; -; No registers are preserved and, unlike some other parts of the POST code, it -; assumes it is running on a fully-functional ARM & IOMD. -; - - -;------------------------------------------------------------------------ -; History -; -; Date Name Comment -; ---- ---- ------- -; 16-Aug-96 JRH First release -; 05-Sep-96 BAR Add code to switch out the progress colour screens. -; See begin (2.17 for details). -; 05-Aug-98 NCE Changes for Customer F maintainance OS. -; Front panel button skips lookng for ROM banks. -; Support for 3rd Rom bank. - - -; Can't have CanLiveOnROMCard TRUE without ROMCardSupport - ASSERT ROMCardSupport - - GBLL DebugROMCard -DebugROMCard SETL {FALSE} - -ts_RC_1meg * (1*1024*1024) -ts_RC_MinOSsize * (2*1024*1024) -ts_RC_MaxOSsize * (8*1024*1024) -ts_RC_2ndbank * (16*1024*1024) -ts_RC_3rdbank * (24*1024*1024) -ts_RC_idoffset * -16 ; offset from end of image - - -ROMCardTest ROUT - -; DEBUG: set up VIDC for VGA, assuming 32M clock - [ DebugROMCard - MOV r1, #ts_VIDCPhys - LDR r0, =&40ffffff ; White - STR r0, [r1] - ] - - [ CanLiveOnROMCard - CMP pc, #ts_RC_2ndbank ;skip this stuff if already - BGT %FT99 ;running in 2nd bank of higher - ] - - [ IOMD_C_FrontPanelButton <> 0 - [ :LNOT: FrontPanelButtClearsCMOS - MOV r0, #IOMD_Base ; if front panel button pressed then skip this - LDRB r0, [r0, #IOMD_CLINES] ; stuff and run the maintainance OS - TST r0, #IOMD_C_FrontPanelButton - BEQ %FT99 - ] - ] - - [ DebugROMCard - LDR r0, =&4000ffff ; Yellow - STR r0, [r1] - ] - - - MOV r3,#ts_RC_3rdbank ;lr contains the address of the ROM were looking for - -40 - MOV r12, r3 ; try to pull ROM size out of the image - LDR r12, [r12, #ROMSizeOffset] ; if this fails then we will start at r3 and work up - CMP r12, #ts_RC_MaxOSsize - BHI %FT90 - -ts_RC_idword = "NCOS" ; id string -ts_RC_LDRPCInst & &E59FF - -00 - ADD r2, r12, r3 ; end of image - LDR r1, ts_RC_idword ; id word to look for - LDR r0, [r2, #ts_RC_idoffset] - CMP r0, r1 - BNE %FT90 ; try next size if no match - -; Found the id string, now see if it checksums to 0. -; Following code ripped off from Mem3. -; -; r0 IS A POINTER TO THE LOCATIONS IN MEMORY. -; r1 HAS THE CALCULATED CHECKSUM. -; r2 HOLDS A COUNTER INDICATION HOW MANY WORDS ARE LEFT TO GET -; r3 is a temporary variable (no it isn't) -; r4 TO r11 ARE USED TO LOAD THE CONTENTS OF 8 LOCATIONS FROM THE ROM. -; - [ DebugROMCard - MOV r1,#ts_VIDCPhys - LDR r0, =&407f7fff ; Fetching Pink - STR r0, [r1] - ] - MOV r1, #&00 ; initialise accumulator - MOV r0, r3 ; initialise pointer - ADD r2, r0, r12 ; initialise endstop, >= 8 words - SUB r2, r2, #(8 * 4) ; below the real endpoint - -RC_loop1 - LDMIA r0!, {r4 - r11} ; get 8 words & post-inc -01 - ADD r1, r1, r4 - ADD r1, r1, r5 - ADD r1, r1, r6 - ADD r1, r1, r7 - ADD r1, r1, r8 - ADD r1, r1, r9 - ADD r1, r1, r10 - ADD r1, r1, r11 -02 - ASSERT ((%02 - %01) = 32) ; else r2 won't count down correctly - - CMP r0, r2 - BNE RC_loop1 ; loop until pointer reaches endstop - - LDMIA r0, {r4 - r9} ; get last 6 words (miss last 2 in ROM) -03 - ADD r1, r1, r4 - ADD r1, r1, r5 - ADD r1, r1, r6 - ADD r1, r1, r7 - ADD r1, r1, r8 - ADDS r1, r1, r9 ; NOTE: Z set => checksum OK -04 - ASSERT (((%04 - %03) + (2*4)) = 32) - - BNE %FT90 ; Skip if checksum not zero - -; We have a valid image. Now work out where to jump to in it. -; Can't just jump to the start because 1st instruction is an LDR PC. -; Code ripped off from Tim's Softloader (thanks Tim) - - [ DontShowProgressColours - ; Display "Jumping to 2nd ROM bank" colour - - MOV_fiq r0,r12_fiq ; restore the faultcode bits - ANDS r0,r0,#(R_EXTERN :OR: R_TESTED) ; If test adapter present, - ; NE : Adaptor fitted, show progress. - ; EQ : No Adaptor fitted, don't show progress - BEQ %FT10 ; EQ : Don't show colours - ] - MOV r1, #ts_VIDCPhys - LDR r0, =C_2NDBANK - STR r0, [r1] -10 - - [ DebugROMCard -; Delay - MOV r0, #0 - MOV r1, #(2*1024*1024) -15 - LDMIA r0!, {r2} - CMP r0, r1 - BNE %BT15 - ] - MOV r0, r3 ; start of 2nd ROM image - LDR r6, [r0] ; load 1st instruction of ROM image - AND r2, r6, #&FF000000 - TEQ r2, #&EA000000 ; is it a branch - BNE %FT20 ; [no, so try something else] - - MOV r6, r6, LSL #(32-21) ; extract offset within ROM - ADD r0, r0, r6, LSR #(32-21-2) ; convert to byte offset - ADD pc, r0, #8 ; allow for pre-fetch - -; check for LDR PC, [PC, +/-#x] -20 MOV r4, r6, LSR #12 - LDR r5, ts_RC_LDRPCInst - ORR r4, r4, #1 << (23-12) - TEQ r4, r5 -30 ; endlessloop - BNE %BT30 ; not either, so stuck - - EOR r6, r6, r4, LSL #12 ; extract offset, and up/down bit - TST r6, #1 << 23 ; NE => bit was 0, so -ve - RSBNE r6, r6, #1 << 23 ; get rid of bit 23 and negate - ADD r6, r6, #8 ; offset in ROM we're reading - LDR r6, [r0, r6] ; address to jump to - ADD pc, r0, r6 ; jump to it - -; Try the other ROM bank -90 - CMP r3, #ts_RC_2ndbank - BEQ %FT91 - MOV r3,#ts_RC_2ndbank - B %BT40 - -91 - [ DebugROMCard - MOV r1, #ts_VIDCPhys - LDR r0, =&407fff7f ; Pale Green - STR r0, [r1] -; Delay - MOV r0, #0 - MOV r1, #(2*1024*1024) -95 - LDMIA r0!, {r2} - CMP r0, r1 - BNE %BT95 - - B %FT99 ; No image found - - LTORG - ] - -; Fall through to POST code -99 - END diff --git a/TestSrc/ShowIOMDRs b/TestSrc/ShowIOMDRs deleted file mode 100644 index 88ef07ff..00000000 --- a/TestSrc/ShowIOMDRs +++ /dev/null @@ -1,214 +0,0 @@ -; > ShowIOMDRs -; Source for ShowIOMDRegisters functions -; -; *********************************** -; *** C h a n g e L i s t *** -; *********************************** -; -; Date Who Version Description -; ---- --- ------- ----------- -; 24-Jun-96 BAR 0.01 Started. -; 05-Jul-96 BAR 0.02 Fix all sorts of bugs ... ! -; 08-Jul-96 BAR 0.03 Fixed some more bugs ... hopfully ! -; 25-Jul-96 BAR 0.04 Fixed some more bugs ... hopfuly ! -; 29-Jul-96 BAR 0.05 Changed not to show skipped. -; Basically working now. -; -; Will show the contents of selected IOMD registers via the display adaptor. -; -; Show contents of IOMD Regs via display adaptor -; Note : Contents of the registers are not checked, therefore this code will -; not thus won't cause a failure. Contents can't be relied upon, -; because of changes to H/W OS etc.. -; -ALIGN -sir_IgnoreTable & &88888888 ;+00C,+008,+004,+000 - & &88888888 ;+01C,+018,+014,+010 - & &88888888 ;+02C,+028,+024,+020 - & &88888888 ;+03C,+038,+034,+030 - & &88888888 ;+04C,+048,+044,+040 - & &88888888 ;+05C,+058,+054,+050 - & &88888888 ;+06C,+068,+064,+060 - & &00888888 ;+07C,+078,+074,+070 - & &88008888 ;+08C,+088,+084,+080 - & &88888800 ;+09C,+098,+094,+090 - & &88880000 ;+0AC,+0A8,+0A4,+0A0 - & &00000000 ;+0BC,+0B8,+0B4,+0B0 - & &88888800 ;+0CC,+0C8,+0C4,+0C0 - & &00008888 ;+0DC,+0D8,+0D4,+0D0 - & &90888888 ;+0EC,+0E8,+0E4,+0E0 - & &00909090 ;+0FC,+0F8,+0F4,+0F0 - & &00000000 ;+10C,+108,+104,+100 - & &00000000 ;+11C,+118,+114,+110 - & &00000000 ;+12C,+128,+124,+120 - & &00000000 ;+13C,+138,+134,+130 - & &00000000 ;+14C,+148,+144,+140 - & &00000000 ;+15C,+158,+154,+150 - & &00000000 ;+16C,+168,+164,+160 - & &00000000 ;+17C,+178,+174,+170 - & &A0A0A0A0 ;+18C,+188,+184,+180 - & &00008888 ;+19C,+198,+194,+190 - & &00000000 ;+1AC,+1A8,+1A4,+1A0 - & &00000000 ;+1BC,+1B8,+1B4,+1B0 - & &00A0A0A0 ;+1CC,+1C8,+1C4,+1C0 - & &A0A0A0A0 ;+1DC,+1D8,+1D4,+1D0 - & &00A00088 ;+1EC,+1E8,+1E4,+1E0 - & &00888888 ;+1FC,+1F8,+1F4,+1F0 -; -; The above is the Show Register Ignore table. It defines if a register is ; -; to be shown and if it is what size the register is. Registers are ; -; expressed as an offset from the base address of IOMD. The registers are ; -; word aligned. To reduce size this table uses one byte per register. The -; table is arranged so that each word repesents 4 registers. The size of the -; register is either 8, 16 or 32 bits, which can be repesented in hex as -; &08, &10 and &20. Threrefore the maximum bit in any byte needed for size -; is bit 5. Therefore bit 8 is used as the flag to indicate if the register -; is to be used, whilst the remaining 7 bits are used for the size. A size -; of 0 is not allowed, therfore the following values for each byte can be -; expected :- -; <= &80 Register will be skipped -; = &88 Show the register and its 8 bits wide -; = &90 Show the register and its 16 bits wide -; = &A0 Show the register and its 32 bits wide -; Any other value is liable to cause havoc ! - -sir_ShowIOMDRegs ROUT -; -; Read the IOMD Register. -; -; Display Adaptor has a 16 char display. -; 32bit no. is 8 chars long -; Display Columns &80+ : 0123456789012345 -; Start message : IOMD Regs: -; Each location read : +01FC 12345678 -; Each location skipped : +01FC Skipped -; -; Define the messages -;"0123456789ABCDEF" - ALIGN -1 - = "IOMD Regs:",0 - ALIGN -2 - = "+",&FF,&FF,&FF,&8B,&FF,&FF,&FF,&FF,&FF,0 -;"+123 12345" - ALIGN -3 - = "+",&FF,&FF,&FF,&89,"Skipped",0 -;"+123 Skipped" - ALIGN -4 - = "+",&FF,&FF,&FF,0 -;"+123" - ALIGN -5 - = &88,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF,0 -;" 12345678" - ALIGN -; -; Define some constants -; -sir_mask8 * &FF ; 8 bit register mask -sir_mask16 * &FFFF ; 16 bit register mask -sir_mask32 * &FFFFFFFF ; 32 bit register mask -sir_MaxOffset * &1FC ; Maximum register offset. -; -; ts_showtext I/f is :- -; r4 = text string to leave -; r8 = number to subsitute -; r0 - r3, r5 - r7 corrupted -; -; r9 = table loop counter +1 -; r10 = iomd offset loop counter +4 -; r11 = iomd base -; tempory copy of r1, contents of IOMD - 32bit data -; r12 = table address -; - MOV r13,r14 ; Put r14 in r13 for later use. - MOV r0,#0 ; data read from the Ignore table - MOV r1,#0 ; data read from iomd - MOV r4,#0 ; Pointer to string for display adaptor - MOV r8,#0 ; Number to subsitue in display adaptor - MOV r9,#0 ; Ignore table counter (+1) - MOV r10,#0 ; IOMD Offset counter (+4) - MOV r11,#0 ; IOMD's base address. - ; Tempory copy of r1. - ADR r12,sir_IgnoreTable ; Get IOMD Ignore table address. -; -sir_loop -; ok, lets do some work here guys - LDRB r0,[r12,r9] ; Get data from Ignore Table - CMPS r0,#&80 ; Check top bit set -; BLE sir_DisplaySkip ; Jump to display skip msg if skipped - ; Don't show skipped - makes post too long, - ; Remove comment to re-instate and comment line below - BLE sir_LoopControl ; Jump to loop control. - - AND r0,r0,#&7F ; Mask off top bit to get reg size - - CMPS r0,#&08 ; Is reg size = 8 - LDREQ r0,=sir_mask8 ; If yes : mask = &FF - BEQ sir_cont ; Jump on to continue - - CMPS r0,#&10 ; Is reg size = 16 - LDREQ r0,=sir_mask16 ; If yes : mask = &FFFF - BEQ sir_cont ; Jump on to continue - - CMPS r0,#&20 ; Is reg size = 32 - LDREQ r0,=sir_mask32 ; If yes : mask = &FFFFFFFF - -sir_cont -; Ok, we've got the mask in r0, lets get the data from IOMD - LDR r11,=IOMD_Base ; Get IOMD's base address. - ; Need to 'cos r11 is also used as tmp store for r1 - LDR r1,[r11,r10] ; Get data from IOMD (base [r11] + offsert [r10]) - AND r1,r1,r0 ; Mask off the reqd. data - MOV r8,r10,LSL #20 ; Put offset that was read into r8 and - ; shifted left 20 to fill top 3 nibles - MOV r2,#&10 ; Put CMP data in r2, this will be shift left 12 - CMPS r0,r2,LSL #12 ; Is mask < &10000 ? (&10<<12) - - BHI sir_TwoLine ; Mask > &10000 : jump to code to show - ; offset & data on two lines -; The mask is less then &10000 - ADD r8,r8,r1 ; Add to r8 the masked data - ADR r4,%BT2 ; r4 -> result message #2 - - BL ts_SendText ; Anyway : Display the message :- - ; Mask < &10000 : +XXX XXXXX - B sir_LoopControl ; Go to loop control - -sir_TwoLine -; Code to disply the offset and data on two lines, because the data is 32 -; bits wide. -; The mask is greater then &1000 -; r1 has the data read from IOMD in it. - ADR r4,%BT4 ; r4 -> result message #4 - MOV r11,r1 ; Need to make a tempory copy of R1 - BL ts_SendText ; Anyway : Display the message :- - ; Mask > &10000 : +XXX - MOV r8,r11 ; r8 = the masked data - ; r11 is the tempory copy of r1 - ADR r4,%BT5 ; r4 -> result message #5 - BL ts_MoreText ; Add the data to the line. - B sir_LoopControl ; Go to loop control - -sir_DisplaySkip -; Ok, we don't want to display this register - MOV r8,r10,LSL #20 ; Mask < &10000 : r8 = offset that was read - ; shifted left 20 to fill top 3 nibles - ; r8 = offset that was skipped - ADR r4,%BT3 ; R4 -> skipping message - BL ts_SendText ; Display the message - -sir_LoopControl -; ok lets see if we need to do some more - ADD r9,r9,#1 ; Increment table counter - ADD r10,r10,#4 ; Increment IOMD offset counter - CMP r10,#sir_MaxOffset ; Have we reached the end ? - BLE sir_loop ; If <= end then loop back - -; Nop, that's it all done ! - MOV pc,r13 ; Return to caller, r13 help retn addr. - - END diff --git a/TestSrc/TestMain b/TestSrc/TestMain deleted file mode 100644 index 22fcf0d1..00000000 --- a/TestSrc/TestMain +++ /dev/null @@ -1,78 +0,0 @@ -; > TestMain - - -; Main assembly file for isolated assembly of machine test software - -MEMCADR * &3600000 -ROM * &3800000 - - [ MEMC_Type = "IOMD" -VideoPhysRam * &02000000 ; Amazing - it's in the same place! -DRAM0PhysRam * &10000000 ; 4 DRAM banks -DRAM1PhysRam * &14000000 -DRAM2PhysRam * &18000000 -DRAM3PhysRam * &1C000000 -DRAMBaseAddressMask * &1C000000 ; used to mask off bits after stealing video RAM -PhysSpaceSize * &20000000 ; IOMD physical map is 512M big -PhysROM * &00000000 ; and real ROM starts at 0 -SAMLength * 512*4 ; SAM length in bytes for 1 bank of VRAM -EASISpacePhys * &08000000 -EASISpace * PhysSpace + EASISpacePhys - | -VideoPhysRam * &02000000 -PhysSpaceSize * &04000000 ; MEMC1 physical map is 64M big -PhysROM * &03800000 -PhysRamPhys * &02000000 ; physical space starts here - ] - - ORG ROM - - GET TestSrc/Begin -CONT - ADRL r2,TestVIDCTAB - LDR r0,=IOMD_MonitorType - LDR r0,[r0] - ANDS r0,r0,#IOMD_MonitorIDMask - ADDEQ r2,r2,#(TestVVIDCTAB-TestVIDCTAB) - MOV r0,#ts_VIDCPhys -08 LDR r1, [r2],#4 - CMP r1, #-1 - STRNE r1, [r0] - BNE %BT08 - - MOV r9,#0 -10 - ORR r9,r9,#&40000000 - STR r9,[r0] ; write the border colour - ADD r9,r9,#&00000005 - ADD r9,r9,#&00000300 - ADD r9,r9,#&00010000 - AND r9,r9,#&00ffffff - - MOV r1,#&10000 -12 ADDS r1,r1,#(-1) - BNE %BT12 - - B %BT10 - -; -; The RISC-OS MEMC setup code is re-used to ensure similar -; detection of memory configuration. The MEMC1 code is modified only -; to remove an unnecessary function. - - GBLL Module -Module SETL {FALSE} - GBLL AssembleSAtest -AssembleSAtest SETL {FALSE} - -DynAreaFlags_DoublyMapped * 1 :SHL: 6 -DynAreaFlags_NotCacheable * 1 :SHL: 5 -DynAreaFlags_NotBufferable * 1 :SHL: 4 -DynAreaFlags_APBits * 15 :SHL: 0 ; currently onl - - - END - - - - diff --git a/TestSrc/ToggleLED b/TestSrc/ToggleLED deleted file mode 100644 index db6cdb6a..00000000 --- a/TestSrc/ToggleLED +++ /dev/null @@ -1,48 +0,0 @@ -; > ToggleLED -; Source for ToggleLED function -; -; *********************************** -; *** C h a n g e L i s t *** -; *********************************** -; -; Date Who Version Description -; ---- --- ------- ----------- -; 29-May-96 BAR 0.01 Started -; 07 Mar 97 BAR 0.02 Changed to optionally use seperate control -; lines for the LED's. -; 11 Jun 97 BAR 0.03 Make sure the IOMD_Base is used. -; 12 Jun 97 BAR 0.04 Don't use entry & exit. -; -; This file will provide support to flash the front pannel LED's -; -IOMD_IOLINES * (IOMD_Base+&0C) ; IOMD_CLINES -; IOMD_IOLINES_INPUTS * &7B ; IOMD_C_ReadMask -; IOMD_STANDBY_LED_BIT * 1<<7 ; - -; Define IOMD_LED_BITS by oring together the known lables for the LED bits. -; One or more of the following can be 0, -IOMD_LED_BITS * IOMD_C_FrontPanelRightLED :OR: IOMD_C_FrontPanelLeftLED :OR: IOMD_C_FrontPanelLED - -tl_Toggle_LEDs ROUT -; Toggle the standby/on LEDs -; On entry .... -; Nothing. -; Register usage .... -; r0, general scratch pad -; r1, addr of IOMD_CLINES -; -; DLINE "toggle leds" - LDR r1, =IOMD_IOLINES ; r1 = addr of IOMD_IOLINES -; LDR r1, =IOMD_CLINES ; r1 = addr of IOMD_CLINES -; DLINE "led -1111111" - LDRB r0,[r1] ; load r0 with the byte pointed to by r1 -; DLINE "led -2222222" - EOR r0,r0,#IOMD_LED_BITS ; Toggle the LED bit(s); ExOR -; DLINE "led -3333333" - ORR r0,r0,#IOMD_C_ReadMask ; OR with the default I/O settings -; DLINE "led -4444444" - STRB r0,[r1] ; store a byte of r0 in to loc pointed to by r1 -; DLINE "led -5555555" - MOV pc, r14 ; Return to caller - - END diff --git a/TestSrc/Vidc b/TestSrc/Vidc deleted file mode 100644 index 2828689d..00000000 --- a/TestSrc/Vidc +++ /dev/null @@ -1,535 +0,0 @@ -; > TestSrc.VIDC - - TTL RISC OS 2+ POST video controller -; -; The video outputs cannot be tested directly, and VIDC permits only -; write operations on its registers. -; This module performs two tests to verify VIDC's operation -; -; - measure mode 0 FLBK period against IOC timer -; - check that sound DMA occurs (MEMC reports DMA complete) -; -; This code contains timing loops affected by gross changes in processor -; speed, and will re-initialise MEMC with 4K pages and continous refresh. -; -;------------------------------------------------------------------------ -; History -; -; Date Name Comment -; ---- ---- ------- -; 18-Dec-89 ArtG Initial version -; 04-Apr-90 ArtG Use saved MEMC control register setting -; 20-Jun-93 ArtG Medusa VIDC20 / IOMD changes -; 18-Nov-94 RCM Morris changes -; 25 Feb 97 ??? ?? -; 18 Mar 97 BAR Change border colour from grey to black for -; IDC20 std. and vga definition tables. -; -; -;------------------------------------------------------------------------ - - -VIDC_CLOCK_CONTROL * ts_S5_base :OR: &0048 ; Fox VIDC clock control -VIDC_CLOCK_NORMAL * &0 - -VIDC_VFLYWAIT * 72000 ; 200mS timeout loop -VIDC_SOUNDWAIT * 40000 ; 100mS timeout loop - -MEMC_Sstart * MEMCADR :OR: &80000 -MEMC_SendN * MEMCADR :OR: &A0000 -MEMC_Sptr * MEMCADR :OR: &C0000 -MEMC_Son * &00800 - -ts_Soundbuf * &200 ; relative to PhysRam -ts_Soundbuf_length * &400 - - [ VIDC_Type = "VIDC20" -VIDSTIM0 * &A0000000 ; base VIDC20 register values -VIDSTIM1 * &A1000000 -VIDSFR * &B0000000 -VIDSCR * &B1000005 -VIDDMAoff * &94000024 -VIDVCOWAIT * &5 -VIDVCOFREQ * &D0000404 - | -VIDSTIM0 * &60000000 ; base VIDC register values -VIDSTIM1 * &64000000 -VIDSFR * &C0000100 - ] - - SUBT FLBK period test -; -; This test attempts to validate the video timing system by checking for -; the proper period from the vertical flyback pulse. To make life easier, -; the test is performed only in mode 0 - i.e a 20mS period. -; -; This test contains a processor-clock timed loop as an outer limit : -; it assumes that the processor will never run more than a factor of ten -; faster than an 8Mhz ARM2. -; This is valid provided that this code isn't run with an ARM3 cache enabled. -; - -; Initialise video clock control (for FOX) -; Initialise VIDC -; Clear IR interrupt request in IOC -; Poll IOC until IR appears (if ever) -; Set IOC timer 0 to 32 mS -; Clear IR interrupt request in IOC -; Poll IOC until IR appears (if ever) -; Check timer 0 has counted down 20 mS (19.8 - 20.2 mS) -; Return zero flag set on OK, clear on test failure. - - -ts_VIDC_period ROUT - - ; Initialise VIDC clock and VIDC - - [ VIDC_Type = "VIDC1a" - LDR r3, =VIDC_CLOCK_CONTROL ; - MOV r1, #VIDC_CLOCK_NORMAL - STRB r1, [r3] - ] - - MOV r7, #0 - MOV r1, #ts_VIDCPhys - ADRL r6, TestVIDCTAB -00 LDR r0, [r6],#4 ; setup using main table - CMP r0, #-1 - STRNE r0, [r1] - BNE %BT00 -01 LDR r0, [r6],#4 ; enable DMA using 2nd table - CMP r0, #-1 - STRNE r0, [r1] - BNE %BT01 - - ; Wait for the start of a flyback period - -04 - LDR r3, =IOC - [ MEMC_Type = "IOMD" - LDR r1, [r6] ; get FSIZE value from end of TestVIDCTAB - STR r1, [r3, #IOMD_FSIZE] - ] - MOV r1, #vsync_bit - STRB r1, [r3, #IOCIRQCLRA] - LDR r2, =VIDC_VFLYWAIT ; long timeout loop - C 200mS - -05 LDRB r1, [r3, #IOCIRQSTAA] - ANDS r1, r1, #vsync_bit - BNE %06 - SUBS r2, r2,#1 - BNE %05 - - LDR r0,=&fffff - ORRS r0, r0,r7, LSL #20 ; Failed : clear 0 flag - MOV pc, r14 ; ... and quit - - ; Set up IOC timer 0 -06 - LDR r1, =(32 * 1000 * 2) ; 32mS upper limit - STRB r1, [r3, #Timer0LL] - MOV r0, r1, LSR #8 - STRB r0, [r3, #Timer0LH] - MOV r0, #0 - STRB r0, [r3, #Timer0GO] ; start the timer - - ; clear the IR and T0 bits - - MOV r0, #(vsync_bit :OR: timer0_bit) - STRB r0, [r3,#IOCIRQCLRA] - - ; wait for what should be a complete vflyback period - -10 LDR r2, =VIDC_VFLYWAIT ; timeout loop - C 200 msec -11 LDRB r0, [r3,#IOCIRQSTAA] - TSTS r0, #vsync_bit - BNE %14 ; wait for end of vsync - - TSTS r0, #timer0_bit ; or timer underflow - BNE %13 - -12 SUBS r2, r2, #1 ; or last-ditch timeout - BNE %11 - -13 ORRS r0, r0,#1 ; Failed : clear 0 flag - MOV r0, #0 ; but return a zero - MOV pc, r14 ; ... and quit - - ; finished in reasonable time : check against margins. - -14 STRB r0, [r3, #Timer0LR] ; latch the current count - LDRB r2, [r3, #Timer0CL] - LDRB r0, [r3, #Timer0CH] - ADD r2, r2, r0, LSL #8 - - SUB r2, r1, r2 - MOV r0, r2, LSR #1 ; Vertical flyback time in uS - - LDR r1, =19800 ; inside limits ? - SUBS r2, r0, r1 - BLE %F20 - - LDR r1, =400 ; 19.8 -> 20.2 mS - CMPS r2, r1 - BGE %F20 - MOV r1,#0 ; OK - 0 indicates pass - - ; After success using the 24MHz reference clock, select the - ; VCO clock (also at 24MHz) and ensure the test is passed after - ; a few cycles to allow the VCO to settle. - -20 - [ VIDC_Type = "VIDC20" - - TEQ r7,#0 ; if this is the first loop .. - BNE %FT21 - TEQ r1,#0 ; and it passed OK .. - BNE %FT25 - MOV r2,#ts_VIDCPhys - LDR r3,=VIDVCOFREQ ; set the vco to 24MHz - LDR r4,=&E0000400 ; and use the vco clock - STMIA r2,{r3,r4} - MOV r7,#VIDVCOWAIT ; set the vco test loop count - B %BT04 ; and run around again - -21 ORR r0,r0,r7,LSL #20 - SUBS r7,r7,#1 ; if all attempts now made - BEQ %FT25 ; return final result - TEQ r1,#0 ; else repeat until passed - BNE %BT04 - ] - - ; return with zero flag set if timers were OK - ; measured time (in uS) in r0 if flyback was wrong, - ; bits 20+ show fail loop - 0 for refclk, 1 for vcoclk. - -25 - ORRS r1,r1,r1 - MOV pc, r14 - - - SUBT Sound DMA test -; -; This test runs the sound DMA system to prove the operation of VIDC and -; MEMC's sound DMA control and the operation of the SIRQ sound DMA complete -; interrupt. -; To avoid making a noise, set the sound muting bit on. -; -; Initialise MEMC sound DMA -; Initialise VIDC sound channel -; Initialise timer 0 and timer 1 to guard-band 10mS sound duration -; Poll IOC until IL1 (SIRQ interrupt) becomes active -; Check timer 0 has completed and timer 1 has not -; - -ts_SIRQ_period ROUT - - ; set up MEMC to point to a buffer near the start of physical RAM, - ; labelled in r9_fiq by the early memory size tests (not MemSize) - ; Registers are set as (address / 16) - ; Register bits are (register * 4) in VIDC address mask - ; Hence values written to MEMC + register offset + (pointer / 4) - - - [ MEMC_Type = "IOMD" - MOV r3,#IOMD_Base - MOV r0,#(IOMD_DMA_C_Bit :OR: IOMD_DMA_E_Bit :OR: 16) - STR r0,[r3,#IOMD_SD0CR] - MOV_fiq r0,r9 ; zero the DMA buffer - ADD r1,r0,#ts_Soundbuf_length - MOV r2,#0 -02 STR r2,[r0],#4 - CMPS r0,r1 - BNE %BT02 - | - MOV_fiq r0,r11_fiq - BIC r0, r0, #MEMC_Son ; ensure sound DMA disabled - - STR r0, [r0] - LDR r1, =(MEMC_SendN :OR: ((ts_Soundbuf + ts_Soundbuf_length) / 4)) - STR r1, [r1] - LDR r2, =(MEMC_Sstart :OR: (ts_Soundbuf / 4)) - STR r2, [r2] - LDR r0, =MEMC_Sptr ; initialise Sptr and set up again .. - STR r0, [r0] - STR r1, [r1] - STR r2, [r2] - ] - - ; Set up VIDC for 8 channels, 10uS (/8) per sample - - LDR r0, =ts_VIDCPhys - [ VIDC_Type = "VIDC20" - LDR r1, =VIDSCR ; VIDC10 mode, 24Mhz clock - STR r1, [r0] - LDR r1, =VIDDMAoff - STR r1, [r0] - ] - LDR r1, =(VIDSTIM0 + 1) ; channel 0 at 100% left - LDR r2, =((VIDSTIM1 - VIDSTIM0) + 1) - MOV r3, #7 -05 STR r1, [r0] ; .. up to 6 at 100% right - ADD r1, r1, r2 - SUBS r3, r3, #1 - BNE %05 - SUB r1, r1, #4 ; finally ch7 at centre again - STR r1, [r0] - - LDR r1, =(VIDSFR + 8) ; 10uS/byte - STR r1, [r0] - - ; Set up the timer to limit at 20 us (10uS/sample, 1024-16 bytes => 10.08 mS) - - LDR r3, =IOC - LDR r1, =(20 * 1000 * 2) ; 20 mS upper limit - STRB r1, [r3, #Timer1LL] - MOV r0, r1, LSR #8 - STRB r0, [r3, #Timer1LH] - - MOV r0, #-1 - STRB r0, [r3, #IOCControl] ; mute sound (on IOC system) - STRB r0, [r3, #Timer1GO] ; start the timer - - [ MEMC_Type = "IOMD" - MOV r0, #(IOMD_DMA_E_Bit :OR: 16) ; enable the IOMD DMA - STR r0, [r3,#IOMD_SD0CR] - MOV_fiq r0,r9 ; set the buffer pointers - MOV r4,#((ts_Soundbuf_length/2) - 16) - STR r0,[r3,#IOMD_SD0CURA] - STR r4,[r3,#IOMD_SD0ENDA] - LDR r2,[r3,#IOMD_SD0ST] - ORR r4,r4,#IOMD_DMA_S_Bit - STR r0,[r3,#IOMD_SD0CURB] - STR r4,[r3,#IOMD_SD0ENDB] - | - MOV_fiq r0, r11_fiq - ORR r0, r0, #MEMC_Son - STR r0, [r0] ; enable the MEMC1a DMA - ] - - ; set long timeout, clear the IL1, T0 and T1 bits - - LDR r2, =VIDC_SOUNDWAIT ; lastditch timeout loop - LDR r0, =(timer0_bit :OR: timer1_bit) - STRB r0, [r3,#IOCIRQCLRA] - - - ; Wait until sound DMA completes (or up to about 100 mS), - ; then check timers. - -10 - [ MEMC_Type = "IOMD" - LDRB r0,[r3, #IOMD_SD0ST] - AND r0, r0, #(IOMD_DMA_O_Bit :OR: IOMD_DMA_I_Bit) - CMPS r0, #(IOMD_DMA_O_Bit :OR: IOMD_DMA_I_Bit) - BEQ %12 - | - LDRB r0, [r3,#IOCIRQSTAB] - ANDS r0, r0, #sound_IRQ_bit - BNE %12 - ] - LDR r0, [r3, #IOCIRQSTAA] - ANDS r0, r0,#timer1_bit ; timeout if timer 1 expires - BNE %11 - - SUBS r2, r2, #1 ; or counter reaches zero - BNE %10 - -11 ORRS r0, r0, #1 ; Failed : clear 0 flag - MOV r2, #0 ; return a timeout value of 0 - B %15 ; ... and quit - - ; finished in reasonable time : check time remaining in t1 - ; Time for DMA should be 10.24ms (1024 bytes at 10us/byte) - ; less up to the time to use the final 16-byte transfer, 160us. - -12 STRB r0, [r3, #Timer1LR] ; latch the current count - LDRB r2, [r3, #Timer1CL] - LDRB r0, [r3, #Timer1CH] - ADD r2, r2, r0, LSL #8 - - SUB r2, r1, r2 - MOV r2, r2, LSR #1 ; Sound DMA time in uS - - LDR r1, =10030 ; inside limits ? - SUBS r0, r2, r1 - BLE %F13 - - LDR r1, =260 ; 10.03 -> 10.29 mS - CMPS r0, r1 - MOVLT r1,#0 ; inside limits : set Z flag - -13 ORRS r1,r1,r1 - - ; return with zero flag set if time (in r2) was within limits - -15 - [ MEMC_Type = "IOMD" - MOV r0, #IOMD_DMA_C_Bit - STR r0, [r3,#IOMD_SD0CR] - | - BIC r0, r0, #MEMC_Son - STR r0, [r0] - ] - MOV r0, r2 ; return the long time value - MOV pc, r14 - -;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; -; Data tables: VIDC := mode 0, all palette black - -TestVIDCTAB - - [ VIDC_Type = "VIDC1a" - - & &00000000 - & &04000000 - & &08000000 - & &0C000000 - & &10000000 - & &14000000 - & &18000000 - & &1C000000 - & &20000000 - & &24000000 - & &28000000 - & &2C000000 - & &30000000 - & &34000000 - & &38000000 - & &3C000000 - & &40000000 ; Border -> black - & &44000000 ; Cursor -> black - & &48000000 - & &4C000000 ; Palette programmed (avoid messy screen on reset) -; -; standard mode 0 setup (except display area disabled) -; - - & &807FC000 - & &8408C000 - & &881B0000 - & &8C1EC000 ; HDSR - & &906EC000 ; HDER - & &94770000 - & &9C400000 - & &A04DC000 - & &A4008000 - & &A8050000 ; VBSR - & &AC098000 ; VDSR - & &B0000000 ; VDER < VDSR to disable screen DMA B0000000 - & &B44DC000 ; VBER - & &E00000B2 -; -; Additional setup : cursor blanked, sound frequency test bit set -; - & &C0000100 ; SFR NB. TEST BIT! - also DFlynn requested value - & &98258000 ; HCSR - & &B8004000 ; VCSR - & &BC400000 ; VCER -; don't mess with the stereo image registers: sound code will set them. - & &FFFFFFFF ; That's the lot - -; -; Further registers to turn screen DMA on again (border all over) -; Must have a video start register before video end register to get -; a vertical flyback interrupt. -; - & &B0494000 ; VDER > VDSR to enable screen DMA - & &FFFFFFFF - ] - - [ VIDC_Type = "VIDC20" - -; This differs from the default RISC OS VIDCTAB in running from -; the 24MHZ video ref clock. H register contents are increased by 50%. - -; Program Control Register first, to clear power-down bit - - & &E0000402 ; CR: FIFO load 16 words, 1 bpp, ck/1, rclk - & &E0000402 ; - & &B1000001 ; SCR: sound disabled (+use 24MHz clock) - -; Don't bother programming all 256 palette entries, we'll be here all night -; Since we're setting up a 1 bit-per-pixel mode, just do colours 0 and 1 - - & &10000000 ; Palette address register = 0 - & &00000000 ; Colour 0 = black - & &00000000 ; Colour 1 = black - & &40000000 ; Border colour = black(was grey &7F7F7F) - & &50000000 ; Pointer colour 1 = black - & &60000000 ; Pointer colour 2 = black - & &70000000 ; Pointer colour 3 = black - -; Get a stable display up so we get stable signals - - & &800005F8 ; HCR = 114 + 132 + 144 + 960 + 144 + 42 - & &8100006A ; HSWR = 114 - & &820000EA ; HBSR = 114 + 132 - & &83000174 ; HDSR = 114 + 132 + 144 - & &84000534 ; HDER = 114 + 132 + 144 + 960 - & &850005CA ; HBER = 114 + 132 + 144 + 960 + 144 - & &860000F3 ; HCSR = HDSR - - & &90000137 ; VCR = 3 + 19 + 16 + 256 + 16 + 2 - & &91000002 ; VSWR = 3 - & &92000015 ; VBSR = 3 + 19 - & &93000025 ; VDSR = 3 + 19 + 16 - & &94000024 ; VDER = VDSR -1 to disable sceeen DMA - & &95000135 ; VBER = 3 + 19 + 16 + 256 + 16 - & &96000025 ; VCSR = VDSR - & &97000025 ; VCER = VDSR - - & &C00F1003 ; EREG = comp sync, DACs on, ereg output ext lut - & &D000C385 ; FSYNREG, clk = (3+1)/(5+1) * 24MHz = 16MHz - & &F0013000 ; DCR: bus D[31:0], Hdisc - & &FFFFFFFF - - & &94000125 ; VDER > VDSR to enable screen DMA - & &FFFFFFFF - ; FSIZE is one less than number of rasters in Vflyback - & &00000037 ; (3 + 19 + 16 + 0 + 16 + 2) - 1 - - ; Alternate settings for VGA monitor - -TestVVIDCTAB - & &E0000402 ; CR: FIFO load 16 words, 1 bpp, ck/1, rclk - & &E0000402 ; - & &B1000001 ; SCR: sound disabled (+use 24MHz clock) - - & &10000000 ; Palette address register = 0 - & &00000000 ; Colour 0 = black - & &00000000 ; Colour 1 = black - & &40000000 ; Border colour = black(was grey &7F7F7F) - & &50000000 ; Pointer colour 1 = black - & &60000000 ; Pointer colour 2 = black - & &70000000 ; Pointer colour 3 = black - - & &80000310 ; HCR = 92 + 45 + 0 + 640 + 0 + 16 - & &81000054 ; HSWR = 92 - & &82000080 ; HBSR = 92 + 45 - & &83000080 ; HDSR = 92 + 45 + 0 - & &84000300 ; HDER = 92 + 45 + 0 + 640 - & &85000300 ; HBER = 92 + 45 + 0 + 640 + 0 - & &86000080 ; HCSR = HDSR - - & &9000020B ; VCR = 2 + 32 + 0 + 480 + 0 + 11 - & &91000001 ; VSWR = 2 - & &92000021 ; VBSR = 2 + 32 - & &93000021 ; VDSR = 2 + 32 + 0 - & &94000020 ; VDER = VDSR -1 to disable sceeen DMA - & &95000201 ; VBER = 2 + 32 + 0 + 480 + 0 - & &96000021 ; VCSR = VDSR - & &97000021 ; VCER = VDSR - - & &C0051003 ; EREG = sep/inv sync, DACs on, ereg output ext lut - & &D000C385 ; FSYNREG, clk = (3+1)/(5+1) * 24MHz = 16MHz - & &F0013000 ; DCR: bus D[31:0], Hdisc - & &FFFFFFFF - - ] - - END - - - diff --git a/h/HALDevice b/h/HALDevice deleted file mode 100644 index 3a979b68..00000000 --- a/h/HALDevice +++ /dev/null @@ -1,39 +0,0 @@ -/* Copyright 2003 Tematic 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. - */ -#ifndef GLOBAL_HALDEVICE_H - -#include <stdbool.h> -#include <stdint.h> - -struct device -{ - uint16_t type; - uint16_t id; - uint32_t location; - uint32_t version; - const char *description; - void *address; - uint32_t reserved1[3]; - bool (*Activate)(struct device *); - void (*Deactivate)(struct device *); - void (*Reset)(struct device *); - int32_t (*Sleep)(struct device *, int32_t state); - int32_t devicenumber; - bool (*TestIRQ)(struct device *); - uint32_t reserved2[2]; -}; - -#endif -/* In the exported copy of this file, the Hdr2H translation of hdr.HALDevice will follow. */ diff --git a/hdr/ARMops b/hdr/ARMops deleted file mode 100644 index 2efdc141..00000000 --- a/hdr/ARMops +++ /dev/null @@ -1,93 +0,0 @@ -; Copyright 2000 Pace Micro Technology plc -; -; 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. -; - -ARMv3 * 0 -ARMv4 * 1 -ARMv4T * 2 -ARMv5 * 3 -ARMv5T * 4 -ARMv5TE * 5 - - ^ 0 -ARM600 # 1 -ARM610 # 1 -ARM700 # 1 -ARM710 # 1 -ARM710a # 1 -SA110_preRevT # 1 -SA110 # 1 -ARM7500 # 1 -ARM7500FE # 1 -SA1100 # 1 -SA1110 # 1 -ARM720T # 1 -ARM920T # 1 -ARM922T # 1 -X80200 # 1 -X80321 # 1 -ARMunk * 255 - -; These flags are stored in ProcessorFlags and returned by OS_PlatformFeatures 0 (Read code features) - -CPUFlag_SynchroniseCodeAreas * 1:SHL:0 ; Calls to OS_SynchroniseCodeAreas required -CPUFlag_InterruptDelay * 1:SHL:1 ; Clearing then setting I bit immediately doesn't trigger IRQs -CPUFlag_VectorReadException * 1:SHL:2 ; 26-bit reads of hardware vectors abort -CPUFlag_StorePCplus8 * 1:SHL:3 ; Stores of R15 store PC+8 rather than PC+12 -CPUFlag_BaseRestored * 1:SHL:4 ; Base Restored abort model rather than Base Updated -CPUFlag_SplitCache * 1:SHL:5 ; CPU has separate I and D caches -CPUFlag_32bitOS * 1:SHL:6 ; OS is 32-bit -CPUFlag_No26bitMode * 1:SHL:7 ; CPU does not support 26-bit modes -CPUFlag_LongMul * 1:SHL:8 ; Has M extensions (UMULL etc) -CPUFlag_Thumb * 1:SHL:9 ; Supports Thumb -CPUFlag_DSP * 1:SHL:10 ; Has E extensions (QADD etc) -CPUFlag_ExtendedPages * 1:SHL:15 ; Supports extended small page L2 descriptors -CPUFlag_NoWBDrain * 1:SHL:16 ; CPU does not support Drain Write Buffer instruction -CPUFlag_AbortRestartBroken * 1:SHL:17 ; Aborts do not correctly follow documented abort model -CPUFlag_XScale * 1:SHL:18 ; it's an XScale, so weird debug etc -CPUFlag_XScaleJTAGconnected * 1:SHL:19 ; JTAG has been connected - -; The macro to do an ARM operation. All ARM operations are expected -; to corrupt a1 only -; This macro corrupts ip unless $zero reg is supplied - - MACRO - ARMop $op, $cond, $tailcall, $zero - [ "$zero" = "" - MOV$cond ip, #ZeroPage - ] - [ "$tailcall" = "" - MOV$cond lr, pc - ] - [ "$zero" = "" - LDR$cond pc, [ip, #Proc_$op] - | - LDR$cond pc, [$zero, #Proc_$op] - ] - MEND - - MACRO - ChangedProcVecs $tmp - [ XScaleJTAGDebug - MOV $tmp, #0 - LDR $tmp, [$tmp, #ProcessorFlags] - TST $tmp, #CPUFlag_XScaleJTAGconnected - BEQ %FT01 - BKPT &2000 -01 - ] - MEND - - - END diff --git a/hdr/Copro15ops b/hdr/Copro15ops deleted file mode 100644 index d6c23652..00000000 --- a/hdr/Copro15ops +++ /dev/null @@ -1,549 +0,0 @@ -; Copyright 2000 Pace Micro Technology plc -; -; 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. -; -; > Copro15ops - -;macros for Coprocessor #15 operations (configuration), which run-time detect -;and cater for ARM 6,7,8,A (A=StrongARM). -;Routines detect which ARM directly by reading ARM ID register (avoids memory reads). - -; 24-01-96 MJS Created -; 07-10-96 MJS Updated for proper ARM 810 support (not needed for RO 3.70) -; 10-03-97 MJS A few additions for chocolate flavour screen handling (possible -; Domain and FSR register use) in Phoebe OS - -ARM_config_cp CP 15 ;coprocessor number for configuration control - -ARM_ID_reg CN 0 ;processor ID -ARM_control_reg CN 1 ;control -ARM_tbase_reg CN 2 ;translation base (MMU) -ARM_domain_reg CN 3 ;domain access control (MMU) -ARM_FSR_reg CN 5 ;Fault status reg (MMU, read only on ARM 6/7) -ARM_FAR_reg CN 6 ;Fault address reg (MMU, read only on ARM 6/7) - -ARM67_TLBflush_reg CN 5 ;TLB flush, ARMs 6 or 7 -ARM67_TLBpurge_reg CN 6 ;TLB purge entry, ARMs 6 or 7 -ARM67_cacheflush_reg CN 7 ;cache flush, ARMs 6 or 7 -ARMv3_TLBflush_reg CN 5 ;TLB flush, ARMs 6 or 7 -ARMv3_TLBpurge_reg CN 6 ;TLB purge entry, ARMs 6 or 7 -ARMv3_cacheflush_reg CN 7 ;cache flush, ARMs 6 or 7 - -ARM8A_cache_reg CN 7 ;cache operations, ARMs 8 or StrongARM -ARM8A_TLB_reg CN 8 ;TLB operations, ARMs 8 or StrongARM -ARMv4_cache_reg CN 7 ;cache operations, ARMs 8 or StrongARM -ARMv4_TLB_reg CN 8 ;TLB operations, ARMs 8 or StrongARM - -ARM8_cacheLD_reg CN 9 ;cache lock-down, ARM 8 -ARM8_TLBLD_reg CN 10 ;TLB lock-down, ARM 8 - -ARM8_CTC_reg CN 15 ;Clock and test configuration - -ARMA_TCI_reg CN 15 ;Test,Clock and Idle control - -;so that AASM will accept the general value for MCR CRm field -C0 CN 0 -C1 CN 1 -C2 CN 2 -C3 CN 3 -C4 CN 4 -C5 CN 5 -C6 CN 6 -C7 CN 7 -C8 CN 8 -C9 CN 9 -C10 CN 10 -C11 CN 11 -C12 CN 12 -C13 CN 13 -C14 CN 14 -C15 CN 15 - - -; -; ----------------- all ARMs --------------------------------------------- -; - -;set MMU translation base - MACRO - ARM_MMU_transbase $reg,$cond - MCR$cond ARM_config_cp,0,$reg,ARM_tbase_reg,C0,0 - MEND - -;set MMU domain access register - MACRO - ARM_MMU_domain $reg,$cond - MCR$cond ARM_config_cp,0,$reg,ARM_domain_reg,C0,0 - MEND - -;read control register - MACRO - ARM_read_control $reg,$cond - MRC$cond ARM_config_cp,0,$reg,ARM_control_reg,C0,0 - MEND - -;set control register - MACRO - ARM_write_control $reg,$cond - MCR$cond ARM_config_cp,0,$reg,ARM_control_reg,C0,0 - MEND - -;read MMU/external fault status - MACRO - ARM_read_FSR $reg,$cond - MRC$cond ARM_config_cp,0,$reg,ARM_FSR_reg,C0,0 - MEND - -;set MMU/external fault status - MACRO - ARM_write_FSR $reg,$cond - MCR$cond ARM_config_cp,0,$reg,ARM_FSR_reg,C0,0 - MEND - -;read MMU/external fault address - MACRO - ARM_read_FAR $reg,$cond - MRC$cond ARM_config_cp,0,$reg,ARM_FAR_reg,C0,0 - MEND - -; set MMU/external fault address - MACRO - ARM_write_FAR $reg,$cond - MCR$cond ARM_config_cp,0,$reg,ARM_FAR_reg,C0,0 - MEND - -;read ID register to register $id -;bits 15:12 of returned ID will be 0,7,8,10 for ARM 6,7,8,A - MACRO - ARM_read_ID $id,$cond - MRC$cond ARM_config_cp,0,$id,ARM_ID_reg,C0,0 - MEND - -;read cache type register to register $type - MACRO - ARM_read_cachetype $type,$cond - MRC$cond ARM_config_cp,0,$type,ARM_ID_reg,C0,1 - MEND - -;read ARM 'number' (6,7,8,&A currently) into $num - MACRO - ARM_number $num - ARM_read_ID $num - ANDS $num,$num,#&F000 - MOVEQ $num,#&6000 ;catch and correct daft ARM 6 ID layout - MOV $num,$num,LSR #12 - MEND - -; check if we're on an ARM 6 - EQ if so - MACRO - ARM_6 $tmp, $cond - ARM_read_ID $tmp, $cond - TST$cond $tmp, #&F000 - MEND - -;check whether running on emulator - this is subject to change. ARMs before -;ARM 920 ignore op2, and will definitely return something other than "1". -;ARM 920 onwards use op2 0 and 1 - behaviour with other op2 values is as yet -;unknown... - MACRO - ARM_on_emulator $tmp,$cond - MRC$cond ARM_config_cp,0,$tmp,ARM_ID_reg,C0,7 - TEQ$cond $tmp,#1 - MEND - -;flush whole TLB (both data and instruction for StrongARM) -;trashes $temp - MACRO - ARM_flush_TLB $temp - ARM_read_ID $temp - AND $temp,$temp,#&F000 - CMP $temp,#&8000 ;ARM 8? - CMPNE $temp,#&A000 ;or StrongARM? - MCRNE ARM_config_cp,0,R0,ARM67_TLBflush_reg,C0,0 - MCREQ ARM_config_cp,0,R0,ARM8A_TLB_reg,C7,0 - MEND - -;flush whole cache (both data and instruction for StrongARM), -;without worrying about any cache cleaning -;trashes $temp - MACRO - ARM_flush_cache $temp - ARM_read_ID $temp - AND $temp,$temp,#&F000 - CMP $temp,#&8000 ;ARM 8? - CMPNE $temp,#&A000 ;or StrongARM? - MCRNE ARM_config_cp,0,R0,ARM67_cacheflush_reg,C0,0 - MCREQ ARM_config_cp,0,R0,ARM8A_cache_reg,C7,0 - MEND - -;flush whole TLB and cache (both data and instruction for StrongARM), -;without worrying about any cache cleaning -;trashes $temp - MACRO - ARM_flush_cacheandTLB $temp - ARM_read_ID $temp - AND $temp,$temp,#&F000 - CMP $temp,#&8000 ;ARM 8? - CMPNE $temp,#&A000 ;or StrongARM? - MCRNE ARM_config_cp,0,R0,ARM67_cacheflush_reg,C0,0 - MCRNE ARM_config_cp,0,R0,ARM67_TLBflush_reg,C0,0 - MCREQ ARM_config_cp,0,R0,ARM8A_cache_reg,C7,0 - MCREQ ARM_config_cp,0,R0,ARM8A_TLB_reg,C7,0 - MEND - -; -; -------------- ARM 6,7 only -------------------------------------------- -; - -;flush cache - MACRO - ARM67_flush_cache $cond - MCR$cond ARM_config_cp,0,R0,ARM67_cacheflush_reg,C0,0 - MEND - -;flush TLB - MACRO - ARM67_flush_TLB $cond - MCR$cond ARM_config_cp,0,R0,ARM67_TLBflush_reg,C0,0 - MEND - -;flush TLB entry, virtual address in $reg - MACRO - ARM67_flush_TLBentry $reg,$cond - MCR$cond ARM_config_cp,0,$reg,ARM67_TLBpurge_reg,C0,0 - MEND - -; -; -------------- ARM 810 only ---------------------------------------------- -; - - [ {FALSE} - -;turn off branch prediction -; - the forced mispredicted branch ensures that the predictor is trapped in -; this code segment when turned off -; - corrupts $temp and status flags -; - MACRO - ARM8_branchpredict_off $temp -01 - ARM_read_control $temp - BIC $temp,$temp,#&800 ;z bit (branch prediction) - ARM_write_control $temp - SEC ;set carry flag - BCC %BT01 - MEND - -;turn on branch prediction - MACRO - ARM8_branchpredict_on $temp - ARM_read_control $temp - ORR $temp,$temp,#&800 ;z bit (branch prediction) - ARM_write_control $temp - MEND - -;flush branch prediction, which is sufficient for an IMB (instruction memory -;barrier) on ARM 810, BUT... -; - intended for in line use only, where efficiency matters, or SWI call is -; awkward -; - general code should use SWI OS_SynchroniseCodeAreas to implement -; an IMB (instruction memory barrier) in future proof, ARM independent way -; - kernel code may use this without regard to which ARM running - ie. assumed -; harmless on other ARMs -; - MACRO - ARM8_branchpredict_flush - SUB PC,PC,#4 ;flush, because PC is written by data op - MEND - -;clean cache entry -; - segment,index spec in $reg -; - bits 4..6 = segment (0..7) -; - bits 26..31 = index (0..63) -; - all other bits zero - MACRO - ARM8_clean_IDCentry $reg,$cond - MCR$cond ARM_config_cp,0,$reg,ARM8A_cache_reg,C11,1 - MEND - -;flush cache entry - segment,index spec in $reg, as for ARM8_clean_IDCentry - MACRO - ARM8_flush_IDCentry $reg,$cond - MCR$cond ARM_config_cp,0,$reg,ARM8A_cache_reg,C7,1 - MEND - -;clean and flush cache entry - segment,index spec in $reg, as for ARM8_clean_IDCentry -; -;if ARM810cleanflushbroken is TRUE, interrupts *must* be currently diabled (see below) -; - MACRO - ARM8_cleanflush_IDCentry $reg,$cond - [ ARM810cleanflushbroken - ARM8_clean_IDCentry $reg,$cond - ARM8_flush_IDCentry $reg,$cond - | - MCR$cond ARM_config_cp,0,$reg,ARM8A_cache_reg,C15,1 - ] - MEND - -;fully clean and flush cache (assumes no locked-down entries to preserve) -; -;if ARM810cleanflushbroken is TRUE, then we have to make sure interrupts are disabled during -;the sequence of 2 MCRs that make up ARM8_cleanflush_IDCentry, to avoid an interrupt hole. -;The hole occurs if an interrupt fills and dirties the particular cache entry after the clean -;but before the flush. We don't have this problem with StrongARM, because the entry is -;specified by virtual address, and RISC OS only cleans/flushes address space not currently -;involved in interrupts. -; - [ ARM810cleanflushbroken - - MACRO - ARM8_cleanflush_IDC $temp,$temp2 - ;for simplicity, disable interrupts during entire operation - mrs ,$temp2,CPSR - ORR $temp,$temp2,#I32_bit - msr ,CPSR_c,$temp ;disable I - MOV $temp,#0 ;initial segment and index -01 - ARM8_cleanflush_IDCentry $temp - ADD $temp,$temp,#1 :SHL: 26 ;next index - CMP $temp,#1 :SHL: 26 ;last index done if index field wrapped to 0 - BHS %BT01 - ADD $temp,$temp,#1 :SHL: 4 ;next segment - CMP $temp,#8 :SHL: 4 ;8 segments done? - BLO %BT01 - msr ,CPSR_c,$temp2 ;restore I - MEND - - | - - MACRO - ARM8_cleanflush_IDC $temp - MOV $temp,#0 ;initial segment and index -01 - ARM8_cleanflush_IDCentry $temp - ADD $temp,$temp,#1 :SHL: 26 ;next index - CMP $temp,#1 :SHL: 26 ;last index done if index field wrapped to 0 - BHS %BT01 - ADD $temp,$temp,#1 :SHL: 4 ;next segment - CMP $temp,#8 :SHL: 4 ;8 segments done? - BLO %BT01 - MEND - - ] - -;flush whole TLB (actually, same as ARMA_flush_TLBs) - MACRO - ARM8_flush_TLB $cond - MCR$cond ARM_config_cp,0,R0,ARM8A_TLB_reg,C7,0 - MEND - -;flush TLB entry, virtual address in $reg - MACRO - ARM8_flush_TLBentry $reg,$cond - MCR$cond ARM_config_cp,0,$reg,ARM8A_TLB_reg,C7,1 - MEND - -;select external Refclk pin as fast clock (dynamic switching, asynchronous) - MACRO - ARM8_refclk_fclk $temp - MRC ARM_config_cp,0,$temp,ARM8_CTC_reg,C0,0 - BIC $temp, $temp,#&1 ;turn off dynamic bus switching (bit0) - MCR ARM_config_cp,0,$temp,ARM8_CTC_reg,C0,0 - BIC $temp,$temp,#&2 ;select asynchronous mode (default) (bit1) - ORR $temp,$temp,#&4 ;select REFCLK as the FCLK source (bits3:2) - BIC $temp,$temp,#&10 ;ensure L=0 when writing (PLL locked) (bit4) - MCR ARM_config_cp,0,$temp,ARM8_CTC_reg,C0,0 - NOP - NOP - NOP - NOP - ORR $temp,$temp,#&1 ;select dynamic clock switching (bit0) - MCR ARM_config_cp,0,$temp,ARM8_CTC_reg,C0,0 - MEND - -;select PLL output as fast clock (dynamic switching, asynchronous) - MACRO - ARM8_pll_fclk $temp - MRC ARM_config_cp,0,$temp,ARM8_CTC_reg,C0,0 - BIC $temp,$temp,#&1 ;turn off dynamic bus switching (bit0) - MCR ARM_config_cp,0,$temp,ARM8_CTC_reg,C0,0 - BIC $temp,$temp,#&2 ;select asynchronous mode (default) (bit1) - ORR $temp,$temp,#&C ;select PLLClkOut as the FCLK source (bits3:2) - BIC $temp,$temp,#&10 ;ensure L=0 when writing (PLL locked) (bit4) - MCR ARM_config_cp,0,$temp,ARM8_CTC_reg,C0,0 - NOP - NOP - NOP - NOP - ORR $temp,$temp,#&1 ;select dynamic clock switching (bit0) - MCR ARM_config_cp,0,$temp,ARM8_CTC_reg,C0,0 - MEND - - ] ;ARM810support - -; -; -------------- StrongARM only ------------------------------------------ -; - -;clean whole data cache, using 16k private cleaner area at address in -;$cleanaddr -;trashes $cleanaddr,$temp1,$temp2 -; -;method: -;clean whole (16k) data cache by reading 16k private cleaner area in 8-word -;(one cache line) steps -; -;note: this routine should NOT be used as is without care - remember -; 1) interrupts should be off (to guarantee this clean is effective) -; 2) DC should be flushed afterwards (to guarantee next clean using -; private area is effective, ie. all private area flushed out now) -; see ARMA_fullycleanflush_DC for 'packaged routine' -; - MACRO - ARMA_clean_DC $cleanaddr,$temp1,$temp2 - ADD $temp1,$cleanaddr,#16*1024 -10 - LDR $temp2,[$cleanaddr],#32 - TEQ $temp1,$cleanaddr - BNE %BT10 - MEND - -;flush whole data cache - MACRO - ARMA_flush_DC $cond - MCR$cond ARM_config_cp,0,R0,ARM8A_cache_reg,C6,0 - MEND - -;clean data cache entry, virtual addr in $reg - MACRO - ARMA_clean_DCentry $reg,$cond - MCR$cond ARM_config_cp,0,$reg,ARM8A_cache_reg,C10,1 - MEND - -;flush data cache entry, virtual addr in $reg - MACRO - ARMA_flush_DCentry $reg,$cond - MCR$cond ARM_config_cp,0,$reg,ARM8A_cache_reg,C6,1 - MEND - -;clean and flush data cache entry, virtual addr in $reg - MACRO - ARMA_cleanflush_DCentry $reg,$cond - MCR$cond ARM_config_cp,0,$reg,ARM8A_cache_reg,C14,1 - MEND - -;clean data cache for virtual address range from $lo (inclusive) to $hi (exclusive) -;corrupts $lo,$hi - MACRO - ARMA_clean_DCrange $lo,$hi - BIC $lo,$lo,#31 ;align down to 8-word (1 cache line) boundary - ADD $hi,$hi,#31 - BIC $hi,$hi,#31 ;align up to 8-word boundary -01 - ARMA_clean_DCentry $lo ;clean entry for virtual address $lo - ADD $lo,$lo,#32 ;next line - ARMA_clean_DCentry $lo - ADD $lo,$lo,#32 - ARMA_clean_DCentry $lo - ADD $lo,$lo,#32 - ARMA_clean_DCentry $lo - ADD $lo,$lo,#32 - CMP $lo,$hi - BLO %BT01 - MEND - -;drain write buffer - MACRO - ARMA_drain_WB $cond - MCR$cond ARM_config_cp,0,R0,ARM8A_cache_reg,C10,4 - MEND - - MACRO - ARM_drain_WB $cond - MCR$cond ARM_config_cp,0,R0,ARM8A_cache_reg,C10,4 - MEND - -;flush whole instruction cache - MACRO - ARMA_flush_IC $WithoutNOPs,$cond - MCR$cond ARM_config_cp,0,R0,ARM8A_cache_reg,C5,0 - [ "$WithoutNOPs" = "" - MOV R0,R0 ; 4 NOPS - up to 4 further instructions may come from IC before flush - MOV R0,R0 - MOV R0,R0 - MOV R0,R0 - ] - MEND - -;flush whole instruction cache and whole data cache - MACRO - ARMA_flush_ICandDC $WithoutNOPs,$cond - MCR$cond ARM_config_cp,0,R0,ARM8A_cache_reg,C7,0 - [ "$WithoutNOPs" = "" - MOV R0,R0 ; 4 NOPS - up to 4 further instructions may come from IC before flush - MOV R0,R0 - MOV R0,R0 - MOV R0,R0 - ] - MEND - -;flush whole instruction TLB - MACRO - ARMA_flush_ITLB $cond - MCR$cond ARM_config_cp,0,R0,ARM8A_TLB_reg,C5,0 - MEND - -;flush whole data TLB - MACRO - ARMA_flush_DTLB $cond - MCR$cond ARM_config_cp,0,R0,ARM8A_TLB_reg,C6,0 - MEND - -;flush whole instruction and data TLBs - MACRO - ARMA_flush_TLBs $cond - MCR$cond ARM_config_cp,0,R0,ARM8A_TLB_reg,C7,0 - MEND - -;flush data TLB entry, virtual address in $reg - MACRO - ARMA_flush_DTLBentry $reg,$cond - MCR$cond ARM_config_cp,0,$reg,ARM8A_TLB_reg,C6,1 - MEND - -;fully clean and flush DC - see ARMA_clean_DC for more info - MACRO - ARMA_fullycleanflush_DC $cleanaddr,$temp1,$temp2,$temp3 - mrs ,$temp3,CPSR - ORR $temp1,$temp3,#I32_bit - msr ,CPSR_c,$temp1 ;disable IRQs - ARMA_clean_DC $cleanaddr,$temp1,$temp2 - ARMA_flush_DC - msr ,CPSR_c,$temp3 ;restore IRQ state - MEND - -;enable core clock switching (fast core clock allowed) - MACRO - ARMA_fastcoreclock $cond - MCR$cond ARM_config_cp,0,R0,ARMA_TCI_reg,C1,2 - MEND - -;disable core clock switching (core clock is memory clock) - MACRO - ARMA_slowcoreclock $cond - MCR$cond ARM_config_cp,0,R0,ARMA_TCI_reg,C2,2 - MEND - - - END diff --git a/hdr/EnvNumbers b/hdr/EnvNumbers deleted file mode 100644 index 68023aef..00000000 --- a/hdr/EnvNumbers +++ /dev/null @@ -1,61 +0,0 @@ -; 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 => &.Hdr.EnvNumbers - -OldOpt SETA {OPT} - OPT OptNoList+OptNoP1List - -; *********************************** -; *** C h a n g e L i s t *** -; *********************************** - -; Date Name Description -; ---- ---- ----------- -; 15-Aug-88 SKS Added numbers in comments -; 09-Jun-94 AMcC Added comment associating this header with -; OS_ChangeEnvironment -; -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; Codes in R0 for OS_ChangeEnvironment -; ==================================== - ^ 0 -MemoryLimit # 1 ; 0 R2 ignored - -UndefinedHandler # 1 ; 1 " " -PrefetchAbortHandler # 1 ; 2 " " -DataAbortHandler # 1 ; 3 " " -AddressExceptionHandler # 1 ; 4 " " -OtherExceptionHandler # 1 ; 5 for FPU exception etc. expansion - -ErrorHandler # 1 ; 6 R3 is error buffer pointer -CallBackHandler # 1 ; 7 R3 is register buffer ptr -BreakPointHandler # 1 ; 8 R3 is register buffer ptr - -EscapeHandler # 1 ; 9 -EventHandler # 1 ; 10 -ExitHandler # 1 ; 11 -UnusedSWIHandler # 1 ; 12 - -ExceptionDumpArea # 1 ; 13 - -ApplicationSpaceSize # 1 ; 14 -CAOPointer # 1 ; 15 - -UpCallHandler # 1 ; 16 - -MaxEnvNumber # 1 - - OPT OldOpt - END diff --git a/hdr/ExportVals/!HowTo b/hdr/ExportVals/!HowTo deleted file mode 100644 index ef144d4e..00000000 --- a/hdr/ExportVals/!HowTo +++ /dev/null @@ -1,7 +0,0 @@ -To add a Kernel workspace variable name to PublicWS: - -1) Add a LabelValue line for the variable to s.GetVals -2) Run Mk -3) See what value was generated for the variable in 'values' -3) 'Export' the variable in hdr.KernelWS (see any other exported variable) -4) Add the variable and its value to hdr.PublicWS diff --git a/hdr/ExportVals/Makefile b/hdr/ExportVals/Makefile deleted file mode 100644 index c2937e9d..00000000 --- a/hdr/ExportVals/Makefile +++ /dev/null @@ -1,38 +0,0 @@ -# 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. -# -# Makefile for ExportVals -# - -# -# Generic options: -# -MKDIR = cdir -AS = aasm -CP = copy -RM = remove -CCFLAGS = -c -depend !Depend -IC: -ASFLAGS = -Stamp -quit -CPFLAGS = ~cfr~v - - -# -# Generic rules: -# -all: - ${AS} ${ASFLAGS} -To null: -From s.GetVals { > values } - settype values text - @echo ok - -# Dynamic dependencies: diff --git a/hdr/ExportVals/Mk,fd7 b/hdr/ExportVals/Mk,fd7 deleted file mode 100644 index d645a7f6..00000000 --- a/hdr/ExportVals/Mk,fd7 +++ /dev/null @@ -1,16 +0,0 @@ -| 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. -| -Dir <Obey$Dir> -amu_machine diff --git a/hdr/ExportVals/s/GetVals b/hdr/ExportVals/s/GetVals deleted file mode 100644 index dccedbc5..00000000 --- a/hdr/ExportVals/s/GetVals +++ /dev/null @@ -1,88 +0,0 @@ -; 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. -; - GET Hdr:ListOpts - GET Hdr:Macros - GET Hdr:System - GET Hdr:Machine.<Machine> - -; Hack! - GBLL med_00001_debug -med_00001_debug SETL {FALSE} - -; and another... - GBLL StrongARM -StrongARM SETL {TRUE} - -; yet more.. - GBLL ChocolateSysHeap -ChocolateSysHeap SETL {TRUE} - - GBLL mjsSysHeapNodesTrace -mjsSysHeapNodesTrace SETL {TRUE} - - - GET ^.PublicWS - GET ^.KernelWS - - - MACRO - LabelValue $LabelName - LCLS String -String SETS "Label " :CC: "$LabelName" :CC: " has the value &" -String SETS "$String" :CC: :STR: $LabelName - ! 0, "$String" - MEND - - MACRO - RegisterLabelValue $LabelName - LCLS String - LCLA Register -String SETS "Label " :CC: "$LabelName" :CC: " has the value &" -String SETS "$String" :CC: :STR: ( :INDEX: $LabelName) -Register SETA :BASE: $LabelName - [ Register >= 10 -String SETS "$String" :CC: ", R" :CC: ((:STR: (Register+6)) :RIGHT: 2) - | -String SETS "$String" :CC: ", R" :CC: ((:STR: Register) :RIGHT: 1) - ] - ! 0, "$String" - MEND - - - LabelValue Export_BgEcfOraEor - LabelValue Export_FgEcfOraEor - LabelValue Export_BranchToSWIExit - LabelValue Export_DomainId - LabelValue Export_ESC_Status - LabelValue Export_IRQsema - LabelValue Export_LatchBSoftCopy - LabelValue Export_MEMC_CR_SoftCopy - LabelValue Export_DebuggerSpace - LabelValue Export_RedirectInHandle - LabelValue Export_RedirectOutHandle - LabelValue Export_ScratchSpace - LabelValue ScratchSpaceSize - LabelValue Export_SoundDMABuffers - LabelValue Export_SoundDMABufferSize - LabelValue Export_SoundWorkSpace - LabelValue Export_SVCSTK - LabelValue Export_SvcTable - LabelValue Export_SysHeapStart - LabelValue Export_VduDriverWorkSpace - LabelValue VDWSSize - LabelValue ScreenBlankFlag - LabelValue ScreenBlankDPMSState - - END diff --git a/hdr/ExportVals/values b/hdr/ExportVals/values deleted file mode 100644 index e946a675..00000000 --- a/hdr/ExportVals/values +++ /dev/null @@ -1,70 +0,0 @@ -; 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. -; -ARM stand alone Macro Assembler Version 2.00 -AMBControl_ws at 00000180 -ARMA_Cleaner_flipflop at 00000184 -SyncCodeA_sema (byte) at 00000188 -Oscli_CmdHashSum at 0000018C -Oscli_CmdHashLists at 00000190 -Serv_SysChains at 00000194 -Serv_UsrChains at 00000198 -Serv_AwkwardChain at 0000019C -VideoPhysAddr held at 000001A0 -LCD_Active flag byte held at 00000259 -ProcessorType at 0000025B -ProcessorFlags at 0000025C -Free space after ProcVec = 00000020 -Free space after EnvString = 000000E0 -Free space after CamMap debug block = 00000024 -KeyWorkSpace at 00000590 -ChocolateCBBlocks at 00000790 -ChocolateSVBlocks at 00000794 -ChocolateTKBlocks at 00000798 -ChocolateMRBlocks at 0000079C -ChocolateMABlocks at 000007A0 -ChocolateMSBlocks at 000007A4 -Module_List at 000007D0 -ModuleSWI_HashTab at 00000C40 -SysVars_StickyPtrs at 00000E40 -Abort32_dumparea at 00000E6C -Help_guard at 00000E84 -PCI_status at 00000E98 -IOMD_NoInterrupt at 00000E9C - -**WARNING** compiling in code to trace some SysHeap node statistics (mjsSysHeapNodesTrace TRUE) - -mjsSHNodesTrace_ws at 00000EAC -Label Export_BgEcfOraEor has the value &000004C0 -Label Export_FgEcfOraEor has the value &00000480 -Label Export_BranchToSWIExit has the value &01F037FC -Label Export_DomainId has the value &00000FF8 -Label Export_ESC_Status has the value &00000104 -Label Export_IRQsema has the value &00000108 -Label Export_LatchBSoftCopy has the value &00000105 -Label Export_MEMC_CR_SoftCopy has the value &00000114 -Label Export_RedirectInHandle has the value &00000AE1 -Label Export_RedirectOutHandle has the value &00000AE2 -Label Export_ScratchSpace has the value &00004000 -Label ScratchSpaceSize has the value &00004000 -Label Export_SoundDMABuffers has the value &01F06000 -Label Export_SoundDMABufferSize has the value &00001000 -Label Export_SoundWorkSpace has the value &01F04000 -Label Export_SVCSTK has the value &01C02000 -Label Export_SvcTable has the value &01F033FC -Label Export_SysHeapStart has the value &01C02000 -Label Export_VduDriverWorkSpace has the value &00001000 -Label VDWSSize has the value &00003000 -Label ScreenBlankFlag has the value &0000047C -Label ScreenBlankDPMSState has the value &0000047D diff --git a/hdr/HALDevice b/hdr/HALDevice deleted file mode 100644 index c84d994b..00000000 --- a/hdr/HALDevice +++ /dev/null @@ -1,110 +0,0 @@ -; Copyright 2002 Tematic 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. -; - -; Structure of generic HAL devices, as described in Kernel.Docs.HAL.NewAPI - -OldOpt SETA {OPT} - OPT OptNoList+OptNoP1List - - [ :LNOT: :DEF: Included_Hdr_HALDevice - GBLL Included_Hdr_HALDevice -Included_Hdr_HALDevice SETL {TRUE} - - - ^ 0 -HALDevice_Type # 2 -HALDevice_ID # 2 -HALDevice_Location # 4 -HALDevice_Version # 4 -HALDevice_Description # 4 -HALDevice_Address # 4 -HALDevice_Reserved1 # 12 -HALDevice_Activate # 4 -HALDevice_Deactivate # 4 -HALDevice_Reset # 4 -HALDevice_Sleep # 4 -HALDevice_Device # 4 -HALDevice_TestIRQ # 4 -HALDevice_Reserved2 # 8 -HALDeviceSize * :INDEX: @ - - -HALDeviceType_Video * 1 :SHL: 8 - ^ 1 -HALDeviceVideo_VDU # 1 ; VDU display - -HALDeviceType_Audio * 2 :SHL: 8 - ^ 1 -HALDeviceAudio_AudC # 1 ; 16-bit sound input/output controller -HALDeviceAudio_Mixer # 1 ; Sound I/O mixer - -HALDeviceType_SysPeri * 3 :SHL: 8 - ^ 1 -HALDeviceSysPeri_IntC # 1 ; Interrupt controller -HALDeviceSysPeri_DMAC # 1 ; DMA controller -HALDeviceSysPeri_DMAB # 1 ; DMA channel - buffer type -HALDeviceSysPeri_DMAL # 1 ; DMA channel - list type - -HALDeviceType_Comms * 4 :SHL: 8 - ^ 1 -HALDeviceComms_UART # 1 ; UART - - -HALDeviceBus_Pro * 0 :SHL: 28 - -HALDeviceProBus_Core * 0 :SHL: 24 -HALDeviceProBus_CoPro * 1 :SHL: 24 - -HALDeviceBus_Sys * 1 :SHL: 28 - -HALDeviceSysBus_AHB * 0 :SHL: 24 -HALDeviceSysBus_ASB * 1 :SHL: 24 -HALDeviceSysBus_PXBus * 2 :SHL: 24 - -HALDeviceBus_Peri * 2 :SHL: 28 - -HALDevicePeriBus_APB * 0 :SHL: 24 - -HALDeviceBus_Exp * 3 :SHL: 28 - -HALDeviceExpBus_Acorn * 0 :SHL: 24 -HALDeviceExpBus_ISA * 1 :SHL: 24 -HALDeviceExpBus_PCI * 2 :SHL: 24 - -HALDeviceBus_Ser * 4 :SHL: 28 - -HALDeviceSerBus_ACLink * 0 :SHL: 24 - - - ^ 0 -HALDeviceID_AudC_M5451 # 1 - - ^ 0 -HALDeviceID_Mixer_STAC9750 # 1 - - ^ 0 -HALDeviceID_DMAC_M1535 # 1 -HALDeviceID_DMAC_M5229 # 1 - - ^ 0 -HALDeviceID_DMAB_M1535 # 1 - - ^ 0 -HALDeviceID_DMAL_M5229 # 1 - - ] - - OPT OldOpt - END diff --git a/hdr/HALEntries b/hdr/HALEntries deleted file mode 100644 index 010b2903..00000000 --- a/hdr/HALEntries +++ /dev/null @@ -1,176 +0,0 @@ -; Copyright 2000 Pace Micro Technology plc -; -; 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. -; -; The layout of the HAL descriptor - - ^ 0 -HALDesc_Flags # 4 -HALDesc_Start # 4 -HALDesc_Size # 4 -HALDesc_Entries # 4 -HALDesc_NumEntries # 4 -HALDesc_Workspace # 4 -HALDesc_size # 4 - -HALFlag_NCNBWorkspace * 1:SHL:0 - -; Entries to the HAL from the OS - - ^ 0 -EntryNo_HAL_Init # 1 - -EntryNo_HAL_IRQEnable # 1 -EntryNo_HAL_IRQDisable # 1 -EntryNo_HAL_IRQClear # 1 -EntryNo_HAL_IRQSource # 1 -EntryNo_HAL_IRQStatus # 1 -EntryNo_HAL_FIQEnable # 1 -EntryNo_HAL_FIQDisable # 1 -EntryNo_HAL_FIQDisableAll # 1 -EntryNo_HAL_FIQClear # 1 -EntryNo_HAL_FIQSource # 1 -EntryNo_HAL_FIQStatus # 1 - -EntryNo_HAL_Timers # 1 -EntryNo_HAL_TimerDevice # 1 -EntryNo_HAL_TimerGranularity # 1 -EntryNo_HAL_TimerMaxPeriod # 1 -EntryNo_HAL_TimerSetPeriod # 1 -EntryNo_HAL_TimerPeriod # 1 -EntryNo_HAL_TimerReadCountdown # 1 - -EntryNo_HAL_CounterRate # 1 -EntryNo_HAL_CounterPeriod # 1 -EntryNo_HAL_CounterRead # 1 -EntryNo_HAL_CounterDelay # 1 - -EntryNo_HAL_NVMemoryType # 1 -EntryNo_HAL_NVMemorySize # 1 -EntryNo_HAL_NVMemoryPageSize # 1 -EntryNo_HAL_NVMemoryProtectedSize # 1 -EntryNo_HAL_NVMemoryProtection # 1 -EntryNo_HAL_NVMemoryIICAddress # 1 -EntryNo_HAL_NVMemoryRead # 1 -EntryNo_HAL_NVMemoryWrite # 1 - -EntryNo_HAL_IICBuses # 1 -EntryNo_HAL_IICType # 1 -EntryNo_HAL_IICSetLines # 1 -EntryNo_HAL_IICReadLines # 1 -EntryNo_HAL_IICDevice # 1 -EntryNo_HAL_IICTransfer # 1 -EntryNo_HAL_IICMonitorTransfer # 1 - -EntryNo_HAL_VideoFlybackDevice # 1 -EntryNo_HAL_Video_SetMode # 1 -EntryNo_HAL_Video_WritePaletteEntry # 1 -EntryNo_HAL_Video_WritePaletteEntries # 1 -EntryNo_HAL_Video_ReadPaletteEntry # 1 -EntryNo_HAL_Video_SetInterlace # 1 -EntryNo_HAL_Video_SetBlank # 1 -EntryNo_HAL_Video_SetPowerSave # 1 -EntryNo_HAL_Video_UpdatePointer # 1 -EntryNo_HAL_Video_SetDAG # 1 -EntryNo_HAL_Video_VetMode # 1 -EntryNo_HAL_Video_PixelFormats # 1 -EntryNo_HAL_Video_Features # 1 -EntryNo_HAL_Video_BufferAlignment # 1 -EntryNo_HAL_Video_OutputFormat # 1 - -EntryNo_HAL_MatrixColumns # 1 -EntryNo_HAL_MatrixScan # 1 - -EntryNo_HAL_TouchscreenType # 1 -EntryNo_HAL_TouchscreenRead # 1 -EntryNo_HAL_TouchscreenMode # 1 -EntryNo_HAL_TouchscreenMeasure # 1 - -EntryNo_HAL_MachineID # 1 ; ReadSysInfo 2 -EntryNo_HAL_ControllerAddress # 1 ; Memory 9 -EntryNo_HAL_HardwareInfo # 1 ; ReadSysInfo 2 -EntryNo_HAL_SuperIOInfo # 1 ; ReadSysInfo 3 -EntryNo_HAL_PlatformInfo # 1 ; ReadSysInfo 8 -EntryNo_HAL_CleanerSpace # 1 - -EntryNo_HAL_UARTPorts # 1 -EntryNo_HAL_UARTStartUp # 1 -EntryNo_HAL_UARTShutdown # 1 -EntryNo_HAL_UARTFeatures # 1 -EntryNo_HAL_UARTReceiveByte # 1 -EntryNo_HAL_UARTTransmitByte # 1 -EntryNo_HAL_UARTLineStatus # 1 -EntryNo_HAL_UARTInterruptEnable # 1 -EntryNo_HAL_UARTRate # 1 -EntryNo_HAL_UARTFormat # 1 -EntryNo_HAL_UARTFIFOSize # 1 -EntryNo_HAL_UARTFIFOClear # 1 -EntryNo_HAL_UARTFIFOEnable # 1 -EntryNo_HAL_UARTFIFOThreshold # 1 -EntryNo_HAL_UARTInterruptID # 1 -EntryNo_HAL_UARTBreak # 1 -EntryNo_HAL_UARTModemControl # 1 -EntryNo_HAL_UARTModemStatus # 1 -EntryNo_HAL_UARTDevice # 1 - -EntryNo_HAL_Reset # 1 -EntryNo_HAL_DebugRX # 1 -EntryNo_HAL_DebugTX # 1 - -EntryNo_HAL_PCIFeatures # 1 -EntryNo_HAL_PCIReadConfigByte # 1 -EntryNo_HAL_PCIReadConfigHalfword # 1 -EntryNo_HAL_PCIReadConfigWord # 1 -EntryNo_HAL_PCIWriteConfigByte # 1 -EntryNo_HAL_PCIWriteConfigHalfword # 1 -EntryNo_HAL_PCIWriteConfigWord # 1 -EntryNo_HAL_PCISpecialCycle # 1 -EntryNo_HAL_PCISlotTable # 1 -EntryNo_HAL_PCIAddresses # 1 - -EntryNo_HAL_ATAControllerInfo # 1 -EntryNo_HAL_ATASetModes # 1 -EntryNo_HAL_ATACableID # 1 - -EntryNo_HAL_InitDevices # 1 - -EntryNo_HAL_KbdScanSetup # 1 -EntryNo_HAL_KbdScan # 1 -EntryNo_HAL_KbdScanFinish # 1 -EntryNo_HAL_KbdScanInterrupt # 1 - -EntryNo_HAL_PhysInfo # 1 - -; Various flags and constants - -; NVMemory - -NVMemoryFlag_None * 0 -NVMemoryFlag_MaybeIIC * 1 -NVMemoryFlag_IIC * 2 -NVMemoryFlag_HAL * 3 -NVMemoryFlag_Provision * 7 ; mask for provision -NVMemoryFlag_ProtectAtEnd * 1:SHL:8 ; Protected region at end -NVMemoryFlag_Deprotectable * 1:SHL:9 -NVMemoryFlag_LowRead * 1:SHL:10 ; locations 0-15 are readable -NVMemoryFlag_LowWrite * 1:SHL:11 ; locations 0-15 are writeable - -; IIC - -IICFlag_LowLevel * 1:SHL:0 -IICFlag_HighLevel * 1:SHL:1 -IICFlag_Background * 1:SHL:4 -IICFlag_Fast * 1:SHL:16 -IICFlag_HighSpeed * 1:SHL:17 - - END diff --git a/hdr/KernelWS b/hdr/KernelWS deleted file mode 100644 index 7ee9b60f..00000000 --- a/hdr/KernelWS +++ /dev/null @@ -1,1948 +0,0 @@ -; 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 > Kernel WorkSpace - -OldOpt SETA {OPT} - OPT OptNoList+OptNoP1List - -; *********************************** -; *** C h a n g e L i s t *** -; *********************************** - -; Date Name Description -; ---- ---- ----------- -; 02-Nov-87 APT Added module SWI hash table -; 03-Nov-87 APT Modo-fied module SWI hash table info, removed BRKLST -; 09-Nov-87 APT Removed ESCCNT and ESFLG -; 12-Nov-87 APT Added IRQsema -; 13-Nov-87 APT Added DefaultIRQ1V codespace -; 16-Nov-87 APT PIRQ chain heads -; 18-Nov-87 APT Reordered EvtHan, EvtHan_ws -; 19-Nov-87 APT Moved IRQsema -; 01-Dec-87 APT Added interruptible heap manager workspace -; 08-Dec-87 TMD Added ECFShift, ECFYOffset -; 14-Dec-87 TMD Added DisplayNColour, DisplayModeFlags -; 15-Dec-87 TMD Added KeyAlphabet -; 22-Dec-87 NDR Using ScratchSpace -; 13-Jan-88 APT General scratchspace bash, low workspace reordering. -; Removed spurious 32 bytes of osbyte wspace -; 14-Jan-88 APT *type buffer in scratchspace. -; MOShasFIQ byte added -; 20-Jan-88 APT Workspace juggling for speed & space; also discarded -; Level0 stuff. -; 28-Jan-88 APT MetroGnome moved to "public" location for ADFS -; 02-Feb-88 APT FIQclaim_interlock added -; 05-Feb-88 APT CallBack_Vector -; 09-Feb-88 APT RAM for SWI despatch -; 17-Feb-88 TMD Added VduSaveArea, VduSaveAreaPtr, DisplayModeNo -; 26-Feb-88 APT NoOfCamEntries manifest -; 03-Mar-88 APT Shrank SVC despatch -; 03-Mar-88 APT NoOfCamEntries manifest doubled -; 07-Mar-88 TMD Added DisplayScreenStart, VduOutputCurrentState, -; SpriteMaskSelect, reordered mode variables -; 07-Mar-88 APT Made CamEntries always at &164 -; 07-Mar-88 TMD Added GCharSizes, GCharSizeX, GCharSizeY -; 08-Mar-88 TMD Added GCharSpacing, GCharSpaceX, GCharSpaceY -; 08-Mar-88 TMD Moved GCharSizes..GCharSpaceY into first 1K of workspace -; 15-Mar-88 TMD Added HLineAddr -; 18-Mar-88 TMD Added DisplayXWindLimit, DisplayYWindLimit, -; DisplayXEigFactor, DisplayYEigFactor, PointerXEigFactor -; 18-Mar-88 APT Setting variables scratchspace use revised. -; 21-Mar-88 TMD Removed CursorIndex -; 22-Mar-88 TMD Added TCharSizeX,TCharSizeY,TCharSpaceX,TCharSpaceY -; 29-Mar-88 TMD Added GcolOraEorAddr -; 31-Mar-88 TMD Removed WsFontPtr -; 07-Apr-88 SKS Added HeapSort use of ScratchSpace -; 14-Apr-88 TMD Added SerialFlags -; 28-Apr-88 TMD Added XONXOFFChar -; 5-May-88 APT Added MemorySpeed -; 18-May-88 APT Added CannotReset sema at &107, removed pre-1.20 changes. -; 24-May-88 TMD Added ClipBoxEnable, ClipBoxLCol..ClipBoxTRow, moved in -; ScrLoaSpriteCB, ScrLoaBuffer, SrcSavCommon -; 24-May-88 TMD Flood fill uses ScratchSpace -; 01-Jun-88 TMD Added AlignSpace for ClipBoxCoords -; 03-Jun-88 BCSKS Make Keyboard buffer into a useful part of the system -; Also PrinterBufferSize -; 09-Jun-88 DJS Draw uses ScratchSpace -; 09-Jun-88 BC Gave Econet some private debungling space -; 11-Jun-88 SKS Align IRQ stack to make STMFD not cross two MEMC bdy's -; Made info condit'l on AsmArf; someone had commented it out! -; 15-Jun-88 SKS Added two more instructions in SWIDespatch area -; Moved SLVK definition into kernel; it's not public -; 16-Jun-88 SKS Added 3 more instructions in SWIDespatch area + nailed -; SvcTable address for compatibility -; 22-Jun-88 SKS Moved MEMC_CR_SoftCopy into pubic ws -; 19-Jul-88 APT Added UpCall handler stuff -; 20-Jul-88 SKS Added above entry -; Amended comment about overlaid workspace in vdu -; 15-Aug-88 SKS Inserted DomainId at FF8 (set by Wimp on task swap, used by -; FileSwitch to tag resources) -; 27-Sep-89 JSR Added ColourTrans to users of scratch space -; 24-Oct-89 TMD Added CamEntriesForBigMachines, CamEntriesPointer -; 26-Oct-89 TMD Added MaxCamEntry, removed NoOfCamEntries symbol -; 27-Oct-89 TMD Added VIDCClockSpeed -; 09-Nov-89 TMD Added ResetIndirection -; 15-Jan-91 TMD Added ROMModuleChain -; 04-Feb-91 DDV Added DeviceFS as user of ScratchSpace. -; 04-Feb-91 DDV Added ColourTrans use of ScratchSpace to build diff tables. -; 06-Mar-91 TMD Added IOSystemType -; 07-Mar-91 LVR ADFS uses scratch space for floppy formatting -; 07-Mar-91 TMD Added MonitorLeadType -; 08-Mar-91 TMD Added PrinterBufferAddr, PrinterBufferSize -; 11-Apr-91 TMD Added SerialInHandle, SerialOutHandle -; 24-Apr-91 TMD Added UniqueMachineID -; 09-Jun-91 RM Added KernelMessagesBlock,ErrorSemaphore and MOSConvertBuffer -; 26-Jul-91 JSR Extend GeneralMOSBuffer by 4 bytes to make it a valid -; length for the default error handler's error buffer -; 19-Aug-91 JSR Added *If to list of GeneralMOSBuffer users -; 22-Aug-91 TMD Reduced ErrorSemaphore to a byte, added PortableFlag -; 25-Aug-91 DDV Updated to indicate correct usage of scratch space by ColourTrans -; 09-Jan-92 DDV Added FgPattern, BgPattern and indicate use of ScratchSpace by OS_SetColour -; 20-Jan-92 TMD OS_SetColour no longer uses ScratchSpace -; 17-Feb-92 ECN Added CLibWord and RISCOSLibWord -; 02-Apr-92 TMD Added ScreenBlankFlag -; 27-Jul-92 TMD Create Victoria specific version -; 28-Jul-92 TMD Moved RAMDiscAddress -; 29-Jul-92 TMD Moved SpriteSpaceAddress -; 30-Jul-92 TMD Moved FontCacheAddress -; 31-Jul-92 TMD Moved ScreenEndAdr from source.vdudecl, and moved actual address! -; 03-Aug-92 TMD Added PhysRam (moved from hdr:System) -; 24-Aug-92 TMD Added AbortIndirection -; 26-Aug-92 TMD Added PreVeneerRegDump -; 02-Sep-92 TMD Added FirPalAddr, SecPalAddr -; 10-Sep-92 DDV Added new Vdu Variables for new text expansion buffer -; 17-Sep-92 DDV Moved NColour into the word initialised VDU workspace -; 17-Sep-92 DDV Two new colour words added for text foreground and background. -; 27-Jan-93 TMD Moved RMA to new position -; 29-Jan-93 TMD Put RMA back to old position (you can't branch to above 32M!) -; 01-Feb-93 TMD Added PhysRamTable -; 02-Feb-93 TMD Added VInitSoftCopy and VEndSoftCopy -; 03-Feb-93 TMD Added PhysRamTableEnd -; 04-Feb-93 TMD Added extra slot in PhysRamTable (in case soft-loaded OS splits a bank) -; 08-Feb-93 TMD Added VRAMWidth variable, and extra symbols for skipped bits -; 24-Feb-93 TMD Changed VRAMPhysAddr to VideoPhysAddr, and split off VideoSize from VRAMSize, to allow for -; DRAM-only systems -; 05-Mar-93 TMD Added CMOSRAMCache -; 19-Apr-93 TMD Added DAList, AppSpaceDANode and DANode offset symbols -; 26-Apr-93 TMD Added FreePoolAddress, FreePoolMaxSize, FreePoolSize -; 29-Apr-93 TMD Changed FontCacheAddress, SpriteSpaceAddress, RAMDiscAddress and FreePoolAddress -; in order to make way for L2PT, which is moving above 64M -; 10-May-93 TMD Added SoftCamMapSize -; 11-May-93 TMD Moved SoftCamMapSize into area that's not zapped in clearing all memory routine -; 12-May-93 TMD Added FreePoolDANode, removed FreePoolSize -; 20-May-93 TMD Moved AplWorkSize into AppSpaceDANode -; 27-May-93 TMD Added VideoBandwidth -; 04-Jun-93 TMD Added CurrentMonitorType -; 09-Jun-93 TMD Added CamMapCorruptDebugBlock -; 07-Jul-93 TMD Increased FreePoolMaxSize to 64M (had to reduce RAMDiscMaxSize to 48M and -; move FreePoolAddress down to do this) -; 15-Jul-93 TMD Added KernelModeSelector -; 26-Jul-93 SMC Moved DefaultIRQ1V (had to accommodate IRQs for IOMD DMA) -; 04-Aug-93 TMD Added L2PTSize, removed FreePoolMaxSize -; 14-Aug-93 TMD Removed SpriteSpaceAddress, shuffled things down -; 16-Aug-93 TMD Removed RAMDiscAddress, shuffled things down -; 17-Aug-93 TMD Removed FontCacheAddress, shuffled things down -; Corrected maximum size of system heap to 2M-8K. -; Added node (in bottom 32K) for system heap. -; 25-Aug-93 SMC Added processor vector table at ProcVec_Start -; Added ProcVecPreVeneers -; 02-Sep-93 SMC Moved RMA to &02100000 and changed application space size to 28M. -; 03-Sep-93 TMD Moved InitKbdWs into SkippedTables (was at start of screen originally) -; 07-Oct-93 TMD Put in OldMemoryMap option so I can still use it -; 07-Oct-93 TMD Added ScreenBlankDPMSState, HSWRSoftCopy, VSWRSoftCopy -; 10-Dec-93 BC Added RawMachineID -; 13-Dec-93 BC Removed UniqueMachineID -; 14-Jan-94 TMD Added CDASemaphore -; 18-Jan-94 TMD Added MMUControlSoftCopy -; 15-Jun-94 AMcC Renamed file (was VickySpace) -; The following values are 'exported' to PublicWS: -; Name: Used by: -; ---------------------------------- -; BgEcfOraEor SprExtend -; FgEcfOraEor SprExtend -; BranchToSWIExit TaskWindow -; CannotReset FileCore -; DomainId FileSwitch -; ESC_Status ADFS, DeviceFS -; IRQsema Draw, MsgTrans -; LatchBSoftCopy ADFS, Parallel -; MEMC_CR_SoftCopy ADFS -; RedirectInHandle TaskWindow -; RedirectOutHandle TaskWindow -; ScratchSpace ADFS, Colours, Draw, FileCore -; FileSwitch, FontManager, NetFiler -; SoundDMABufferSize Sound0 -; SoundDMABuffers Sound0 -; SoundWorkSpace Portable, Sound1, Sound2, Voices -; SVCSTK FileSwitch -; SvcTable TaskWindow, Wimp -; SysHeapStart FileSwitch -; VduDriverWorkSpace SprExtend -; -; 31-Oct-94 AMcC/RM/WT Added CLine_Softcopy for Morris monitor id -; 03-Nov-94 AMcC Export ScreenBlankFlag and ScreenBlankDPMSState -; (for DPMSUtils: part of RISC OS releases 3.50 and 3.60) -; 28-Mar-95 JRH Added NVRamSize and RTCFitted, conditioned on E2ROMSupport -; 06-Feb-95 SMC Increased SVC stack size to 12K. -; 18-Jan-96 JRH Removed CLine_Softcopy cos not needed -; 06-Feb-96 SMC Increased DefIRQ1Vspace for IRQC registers -; amg 6/12/96 Renaissance. Merge in changes below from 3.70 version. Make changes conditional. -; 07-Feb-95 WT Added LCD_Active for LCD/CRT dynamic switching support -; 07-Feb-95 WT Added VStartSoftCopy for dual-panel LCD support -; 18-May-95 WT Added LCD_Inverted for LCD inversion (well, surprise surprise!) -; 05-Dec-95 WT Added ProcessorType and ProcessorFlags (1 byte each) -; amg 07/12/96 Renaissance. Shifted ResetType (which is a public export) so it'll -; stay in the same place. -; 21-Jul-98 NDT Added PixelRate. Moved KernelModeSelector to make space. -; 19-Oct-99 KJB Moved IOSystemType into SkippedTables. -; -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; Memory map: - -; Dynamic area node format - - ^ 0 -DANode_Link # 4 ; points to next node -DANode_Number # 4 ; number of this area -DANode_Base # 4 ; base address of area (points in middle of doubly-mapped areas) -DANode_Flags # 4 ; various flags -DANode_Size # 4 ; current size of area (not counting holes, if Sparse area) -DANode_MaxSize # 4 ; maximum size of area -DANode_Workspace # 4 ; workspace pointer when calling handlers -DANode_Handler # 4 ; pointer to handler routine for area -DANode_Title # 4 ; pointer to area title -DANode_SubLink # 4 ; next node in any disjoint sublist (currently used for Shrinkables only) -DANode_SparseHWM # 4 ; high water mark, if Sparse area (highest base+size claimed for area) -DANode_SortLink # 4 ; next node in alphabetically sorted list -DANode_NodeSize # 0 - - -; The addresses below are only temporary; eventually most of them will be allocated at run time (we hope!) - -ZeroPage * &00000000 - - [ HAL -; Sort out 26/32 bit versions -SVCStackSize * 32*1024 -IRQStackSize * 8*1024 -ABTStackSize * 8*1024 -UNDStackSize * 8*1024 -KbuffsMaxSize * 64*1024 -DCacheCleanSize * 256*1024 ;should be multiple of 64k - -AplWorkMaxSize * &20000000 ; 512M - temporary (need to decide this at boot time) -;ScreenEndAdr * &24000000 ; temporary - run time allocate - -RMAAddress * AplWorkMaxSize ; temporary - run time allocate? -ScreenMaxSize * 480*1024 - -RMAMaxSize * &10000000 ; 256M - -FreePoolAddress * RMAAddress + RMAMaxSize -IOLimit * &BA000000 ; initial lower limit on room for IO space (DA creation may move limit up) -IO * &FA000000 ; works downwards -HALWorkspace * &FA000000 -HALWorkspaceSpace * &00100000 -IRQStackAddress * &FA100000 - [ {TRUE} -SVCStackAddress * &FA200000 - | -SVCStackAddress * &01C00000 - ] -ABTStackAddress * &FA300000 -UNDStackAddress * &FA400000 -PhysicalAccess * &FAE00000 -DCacheCleanAddress * &FAF00000 ; eg. for StrongARM, 256k of space, up to FAF40000 -KbuffsBaseAddress * &FAF40000 ; kernel buffers for long command lines, size KbuffsMaxSize -HALWorkspaceNCNB * &FAFE8000 ; 32K of uncacheable HAL workspace (if requested) - [ {TRUE} -CursorChunkAddress * &FAFF0000 - | -CursorChunkAddress * &01F00000 - ] -L2PT * &FB000000 -L1PT * &FB400000 - [ {TRUE} -SysHeapChunkAddress * &FB404000 -SysHeapAddress * SysHeapChunkAddress -SysHeapMaxSize * &FB800000 - SysHeapAddress - | -SysHeapChunkAddress * &01C08000 -SysHeapAddress * SysHeapChunkAddress -SysHeapMaxSize * &001F8000 - ] -CAM * &FB800000 -CAMspace * 8*1024*1024 ; enough for 4GB of RAM - -IRQSTK * IRQStackAddress + IRQStackSize -ABTSTK * ABTStackAddress + ABTStackSize -UNDSTK * UNDStackAddress + UNDStackSize - | -AplWorkMaxSize * &01C00000 ; 28M -RMAAddress * &02100000 -RMAMaxSize * &00B00000 ; 11M - -SVCStackSize * 8*1024 - -SysHeapChunkAddress * &01C00000 -SVCStackAddress * SysHeapChunkAddress -SysHeapAddress * SysHeapChunkAddress+SVCStackSize -SysHeapMaxSize * &00200000-SVCStackSize - -CursorChunkAddress * &01F00000 ; Fixed size 32K - -ScreenEndAdr * &05000000 ; was &02000000 -ScreenMaxSize * 480*1024 - -; FontCacheAddress * &06000000 ; was &01E00000 ; now dynamic -; FontCacheMaxSize * &01000000 ; 16M - -; SpriteSpaceAddress * &08000000 ; was &01400000 ; now dynamic -; SpriteSpaceMaxSize * &01000000 ; 16M - -; RAMDiscAddress * &07000000 ; was &01000000 ; now dynamic -; RAMDiscMaxSize * &03000000 ; 48M - -FreePoolAddress * &06000000 ; may still go lower! - -PhysRam * &05000000 -;following dynamic area only used if LongCommandLines is {TRUE} -KbuffsBaseAddress * &2078000 ;just above reserved area for fake 480k screen -KbuffsMaxSize * &0088000 ;544k (takes us up to start of RMA) - ] - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; system variables - - ^ 0,R12 - -OSBYTEFirstVar # 0 - -ByteVars # 0 ; The main osbyte variables, accessed - ; via calls &A6 to &FF - -VarStart # 2 ; &A6,&A7 -ROMPtr # 2 ; &A8,&A9 -ROMInfo # 2 ; &AA,&AB -KBTran # 2 ; &AC,&AD -VDUvars # 2 ; &AE,&AF - -CFStime # 1 ; &B0 -InputStream # 1 ; &B1 -KeyBdSema # 1 ; &B2 - -ROMPollSema # 1 ; &B3 -OSHWM # 1 ; &B4 - -RS423mode # 1 ; &B5 -NoIgnore # 1 ; &B6 -CFSRFS # 1 ; &B7 -VULAcopy # 2 ; &B8,&B9 - -ROMatBRK # 1 ; &BA -BASICROM # 1 ; &BB - -ADCchanel # 1 ; &BC -ADCmaxchn # 1 ; &BD -ADCconv # 1 ; &BE - -RS423use # 1 ; &BF -RS423conflag # 1 ; &C0 - -FlashCount # 1 ; &C1 -SpacPeriod # 1 ; &C2 -MarkPeriod # 1 ; &C3 - -KeyRepDelay # 1 ; &C4 -KeyRepRate # 1 ; &C5 - -ExecFileH # 1 ; &C6 -SpoolFileH # 1 ; &C7 - -ESCBREAK # 1 ; &C8 (200) - -KeyBdDisable # 1 ; &C9 -KeyBdStatus # 1 ; &CA - -RS423HandShake # 1 ; &CB -RS423InputSupr # 1 ; &CC -RS423CFSFlag # 1 ; &CD - -EconetOScall # 1 ; &CE -EconetOSrdch # 1 ; &CF -EconetOSwrch # 1 ; &D0 - -SpeechSupr # 1 ; &D1 -SoundSupr # 1 ; &D2 - -BELLchannel # 1 ; &D3 -BELLinfo # 1 ; &D4 -BELLfreq # 1 ; &D5 -BELLdur # 1 ; &D6 - -StartMessSupr # 1 ; &D7 - -SoftKeyLen # 1 ; &D8 - -PageModeLineCount # 1 ; &D9 - -VDUqueueItems # 1 ; &DA - -TABch # 1 ; &DB -ESCch # 1 ; &DC - -IPbufferCh # 4 ; &DD,&DE,&DF,&E0 -RedKeyCh # 4 ; &E1,&E2,&E3,&E4 - -ESCaction # 1 ; &E5 -ESCeffect # 1 ; &E6 - -u6522IRQ # 1 ; &E7 -s6850IRQ # 1 ; &E8 -s6522IRQ # 1 ; &E9 - -TubeFlag # 1 ; &EA - -SpeechFlag # 1 ; &EB - -WrchDest # 1 ; &EC -CurEdit # 1 ; &ED - -SoftResetVars # 0 ; Reset to here on soft reset - -KeyBase # 1 ; &EE -Shadow # 1 ; &EF -Country # 1 ; &F0 - -UserFlag # 1 ; &F1 - -SerULAreg # 1 ; &F2 - -TimerState # 1 ; &F3 - -SoftKeyConsist # 1 ; &F4 - -PrinterDrivType # 1 ; &F5 -PrinterIgnore # 1 ; &F6 - -BREAKvector # 3 ; &F7,&F8,&F9 - -MemDriver # 1 ; &FA - where the VDU drivers write to -MemDisplay # 1 ; &FB - where we display from - -LangROM # 1 ; &FC - -LastBREAK # 1 ; &FD - -KeyOpt # 1 ; &FE - -StartOptions # 1 ; &FF - -HardResetVars # 0 ; Reset to here on hard reset -PowerOnResetVars # 0 ; Reset to here on power-on reset - -; These two can dovetail in here to use up 2 bytes before the AlignSpace! - -SerialInHandle # 1 ; Handle for serial input stream (0 if not open currently) -SerialOutHandle # 1 ; Handle for serial output stream (-----------""----------) - - AlignSpace - -EventSemaphores # 32 ; One byte for each of 32 events - -TimerAlpha # 8 ; As used by time (bottom 5 bytes) -TimerBeta # 8 ; ................................ -; both aligned to word boundaries - -RealTime # 8 ; 5-byte fast real-time - -PrinterActive # 4 ; Handle/active flag for printer (word aligned) - -IntervalTimer # 5 ; Up Counter synchronous with TIME. -; Event generated when Zero is reached -; bottom byte aligned to word boundary - -SecondsTime # 1 ; the soft copy (centi-)seconds of the RTC -CentiTime # 1 ; """""""""""""""""""""""""""""""""""""""" - -FlashState # 1 ; which flash colours are we using - -SecondsDirty # 1 ; the dirty flag for start up! - -MinTick # 1 ; the minutes odd/even state - -DCDDSRCopy # 1 ; copy of ACIA bits to check for change - -TVVertical # 1 ; *TV first parameter - -TVInterlace # 1 ; *TV second parameter - -CentiCounter # 1 ; Counter for VDU CTRL timing - -Alphabet # 1 ; Current alphabet number - -Keyboard # 1 ; Current keyboard number - -KeyAlphabet # 1 ; Alphabet associated with current keyboard - - GBLS PrinterPrefix -PrinterPrefix SETS "PrinterType$" - -PrinterTypeName # 6 + :LEN: (PrinterPrefix) - - AlignSpace - -SerialFlags # 4 ; New serial flags - -XONXOFFChar # 1 ; Character to send before rest (0 if none) - - AlignSpace - -OSBYTEVarSize * @-OSBYTEFirstVar - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -; End of variables' space - -; *** layout of a descriptor block for a display pointer shape *** - - ^ 0 -PointerBlkHAL # 0 ; fields up to private part passed to HAL -PointerWidth # 1 ; actual (unpadded) shape width in bytes (from OS_Word 21) -PointerHeight # 1 ; shape height in pixels - # 2 ; alignment padding -PointerBuffLA # 4 ; logical address of shape buffer (up to 8 * 32 bytes) -PointerBuffPA # 4 ; physical address of shape buffer -PointerBlkPrivate # 0 ; fields below here not used by HAL -PointerActiveX # 1 ; active x in pixels from left -PointerActiveY # 1 ; active y in pixels from top - # 2 ; alignment padding -PointerBlkSize # 0 - - -; *********************************** -; *** Main Vdu Driver Workspace *** -; *********************************** - - ^ 0 - -FgEcf # 4 * 8 ; Foreground Ecf, set by GCOL(a,0-127) -BgEcf # 4 * 8 ; Background Ecf, set by GCOL(a,128-255) -GPLFMD # 4 ; Foreground action, set by GCOL(a,0-127) -GPLBMD # 4 ; Background action, set by GCOL(a,128-255) -GFCOL # 4 ; Foreground colour, set by GCOL(a,0-127) -GBCOL # 4 ; Background colour, set by GCOL(a,128-255) - -GWLCol # 4 ; Graphics window left column -- -GWBRow # 4 ; Graphics window bottom row | -GWRCol # 4 ; Graphics window right column | -GWTRow # 4 ; Graphics window top row -- - -qqqPad # 3 -QQ # 17 ;Queue - QQ+1 is on a word boundary -QOffset # 4 ;Value to add to VDUqueueItems to point to next queue posn. -JVec # 4 ;Jump vector to internal routines - -; Start of MODE table workspace - -ScreenSize # 4 ; number of bytes needed for this mode (assumed 1st in list) - -XWindLimit # 4 ; Maximum value of GWRCol (internal representation) - -; LineLength must be immediately after YWindLimit - -YWindLimit # 4 ; Maximum value of GWTRow (internal representation) - -LineLength # 4 ; Length of one pixel row in bytes - -NColour # 4 ; Number of colours minus 1 - -; End of word mode variables - -YShftFactor # 4 ; Number of places to shift YCoord in address generation after - ; multiplying by 5, holds - ; 7,6,5 or 4 for 8,4,2 or 1 bits per pixel (640x256 mode) or - ; 6,5,4 or 3 for 8,4,2 or 1 bits per pixel (320x256 mode). - -ModeFlags # 4 ; Bit 0 => non-graphic, Bit 1 => teletext, Bit 2 => gap mode - -XEigFactor # 4 ; Number of places to shift XCoord in external to internal - ; coordinate conversion, holds - ; 1 for 640x256 mode - ; 2 for 320x256 mode - ; 3 for 160x256 (BBC micro mode 2) - -YEigFactor # 4 ; number of shifts to convert between internal/external Y - -Log2BPC # 4 ; Log to base 2 of BytesPerChar ie (0,1,2,3,4) - -Log2BPP # 4 ; Log to base 2 of BitsPerPix ie (0,1,2,3) - -ECFIndex # 4 ; Index into default ECF tables - -ScrRCol # 4 ; Maximum column number in this screen mode -ScrBRow # 4 ; Maximum row number in this screen mode - -PalIndex # 4 ; Index into palette tables (0,1,2,3) - -; End of table-initialised workspace - -; Next 3 must be together in this order ! - -XShftFactor # 4 ; Number of places to shift XCoord in address generation, - ; holds 2,3,4 or 5 for 8,4,2,1 bits per pixel respectivly -GColAdr # 4 ; Address of Ecf to plot - either FgEcf or BgEcf - -ScreenStart # 4 ; Start address of screen (for VDU drivers) - -NPix # 4 ; Number of pixels per word minus 1, holds - ; holds 3,7,15 or 31 for 8,4,2,1 bits per pixel modes - -AspectRatio # 4 ; Pixel shape : 0 square, 1 horz rect, 2 vert rect - -BitsPerPix # 4 ; Bits per pixel (1,2,4,8) - -BytesPerChar # 4 ; Bytes per 8 pixels of character - ; (same as BitsPerPix except in double pixel modes) - - # 4 ; SPARE (avoiding changes of exported addresses for now) - -RowMult # 4 ; Row multiplier for text manipulation - -RowLength # 4 ; Bytes per text row in this mode (eg 640,1280,5120) - -; The following (up to and including NewPtY) must be together in this order -; (relied upon by DefaultWindows) - -TWLCol # 4 ; Text window left column -- -TWBRow # 4 ; Text window bottom row | -TWRCol # 4 ; Text window right column | -TWTRow # 4 ; Text window top row -- - -OrgX # 4 ; Screen origin (external representation) -OrgY # 4 - -GCsX # 4 ; Graphics cursor (external representation) -GCsY # 4 - -OlderCsX # 4 ; Very old X coordinate (internal) -OlderCsY # 4 ; Very old Y coordinate (internal) - -OldCsX # 4 ; Old graphics cursor (internal representation) -- -OldCsY # 4 ; | - ; | -GCsIX # 4 ; Graphics cursor (internal representation) | -GCsIY # 4 ; | - ; | -NewPtX # 4 ; Newest point (internal representation) | -NewPtY # 4 ; -- - -; End of together block - -TForeCol # 4 ; Text foreground colour -TBackCol # 4 ; Text background colour - -CursorX # 4 ; Text cursor X position ; these 3 must be in same order as ... -CursorY # 4 ; Text cursor Y position -CursorAddr # 4 ; Screen address of (output) cursor - -InputCursorX # 4 ; Input cursor X position ; ... these 3 -InputCursorY # 4 ; Input cursor Y position -InputCursorAddr # 4 ; Screen address of input cursor - -EORtoggle # 4 ; Toggle between gap and non-gap -RowsToDo # 4 ; in the CLS - -VduStatus # 4 ; Vdu2, Window, Shadow bits (others in CursorFlags) - -CBWS # 8 ; Clear block (VDU 23,8..) workspace -CBStart # 2 -CBEnd # 2 - -CursorDesiredState # 4 -CursorStartOffset # 4 -CursorEndOffset # 4 -CursorCounter # 4 -CursorSpeed # 4 -Reg10Copy # 4 - -CursorFill # 4 ; Word to EOR cursor ; MUST be immediately before CursorNbit - -CursorNbit # 4 ; Pointer to cursor code for current mode - -DisplayStart # 4 ; Start address of screen (for display) -DriverBankAddr # 4 ; Default start address for VDU drivers -DisplayBankAddr # 4 ; Default start address for display -DisplayNColour # 4 ; No. of colours -1 for displayed mode -DisplayModeFlags # 4 ; ModeFlags for displayed mode -DisplayModeNo # 4 ; ModeNo for displayed mode -DisplayScreenStart # 4 ; Where VDU outputs to when outputting to screen - -DisplayXWindLimit # 4 ; Used for pointer programming -DisplayYWindLimit # 4 -DisplayXEigFactor # 4 -DisplayYEigFactor # 4 -PointerXEigFactor # 4 - -Ecf1 # 8 ; The Ecf patterns -Ecf2 # 8 -Ecf3 # 8 -Ecf4 # 8 - -DotLineStyle # 8 ; Dot dash line pattern - -ModeNo # 4 ; Current mode number - -TFTint # 4 ; Text foreground tint (in bits 6,7) -TBTint # 4 ; Text background tint -GFTint # 4 ; Graphics foreground tint -GBTint # 4 ; Graphics background tint - -TotalScreenSize # 4 ; Amount configured for screen (in bytes) - -MaxMode # 4 ; Maximum mode number allowed (20 for now) - -ScreenEndAddr # 4 ; Logical address of screen (start of 2nd copy) - -CursorFlags # 4 ; Silly Master cursor movement flags - -CursorStack # 4 ; Bit stack of nested cursor states (0 => on, 1 => off) - ; (bit 31 = TOS) - -ECFShift # 4 ; number of bits to rotate right ECF OR and EOR masks by -ECFYOffset # 4 ; vertical offset to ECF index - -WsVdu5 # 0 ; Vdu 5 workspace -WsScr # 4 -WsEcfPtr # 4 -; WsFontPtr # 4 ; not needed any more, kept in register -EndVerti # 4 -StartMask # 4 -EndMask # 4 -FontOffset # 4 -TempPlain # 16 ; only used for MODE 10 - -VIDCClockSpeed # 4 ; current VIDC clock speed in kHz (now always zero) - -CurrentMonitorType # 4 ; initialised from configured one - -PixelRate # 4 ; Pixel Rate in kHz - -GraphicWs # 300 ; All graphics workspace is overlaid here -EndGraphicWs # 0 - - [ AssemblingArthur :LAND: :DEF: ShowWS - ! 0,"16 ":CC::STR:@ - ] - AlignSpace 16 - -GCharSizes # 0 -GCharSizeX # 4 ; width of VDU 5 chars in pixels -GCharSizeY # 4 ; height of VDU 5 chars in pixels - -GCharSpacing # 0 -GCharSpaceX # 4 ; horizontal spacing between VDU 5 chars in pixels -GCharSpaceY # 4 ; vertical ------------------""----------------- - -TCharSizes # 0 -TCharSizeX # 4 ; width of VDU 4 chars in pixels -TCharSizeY # 4 ; height of VDU 4 chars in pixels - -TCharSpacing # 0 -TCharSpaceX # 4 ; horizontal spacing between VDU 4 chars in pixels -TCharSpaceY # 4 ; vertical ------------------""----------------- - -HLineAddr # 4 ; address of exported HLine -GcolOraEorAddr # 4 ; address of FgEcfOraEor etc - -BlankPalAddr # 4 ; address of block for blank palette -FirPalAddr # 4 ; address of block for first flash state palette -SecPalAddr # 4 ; address of block for second flash state palette - -PointerShapes # 0 -PointerShape1 # 4 ; pointers to defined shapes 1 to 4 -PointerShape2 # 4 -PointerShape3 # 4 -PointerShape4 # 4 -PointerShapesH # 0 -PointerShapeH1 # 4 ; pointers to holding shapes 1 and 2 (so updates never hit shape given to HAL) -PointerShapeH2 # 4 - -PointerShapeBlocks # 6*PointerBlkSize ; room for the 6 shape descriptors themselves - -PointerShapeLA # 4 ; logical address of current shape buffer (owned by HAL) -PointerShapeNumber # 1 ; includes bit 7 linkage flag - # 3 ; alignment padding -PointerX # 4 ; co-ordinates of pointer (not always = mouse) -PointerY # 4 - - [ :DEF: ShowWS - ! 0, "PointerShapes @ ":CC::STR:(PointerShapes) - ] - - [ :LNOT: UseGraphicsV -HWPixelFormats # 4 ; pixel formats word from HAL -HWVideoFeatures # 4 ; features word from HAL -HWBufferAlign # 4 ; buffer alignment word from HAL - # 40*4 - 6*PointerBlkSize ; SPARE (avoiding changes of exported addresses for now) - | - # 43*4 - 6*PointerBlkSize ; SPARE (avoiding changes of exported addresses for now) - ] - -TextFgColour # 4 ; Fg/Bg colour stored as a colour number, computed on VDU 18 and re-poked! -TextBgColour # 4 ; - -; In this brave new world there is a pointer to the text expansion -; buffer used for VDU 4 / 5 text plotting. - -; This now lives in the system heap. - -TextExpandArea # 4 ; Pointer to Text expand area (in system heap) -TextExpandArea_Size * (8*1024) - - # 2*4 ; SPARE (avoiding changes of exported addresses for now) - -;ScreenBlankFlag # 1 ; 0 => unblanked, 1 => blanked - -Export_ScreenBlankFlag # 1 - ASSERT Export_ScreenBlankFlag = ScreenBlankFlag - ASSERT ?Export_ScreenBlankFlag = ?ScreenBlankFlag - -;ScreenBlankDPMSState # 1 ; 0 => just blank video - ; 1 => blank to stand-by (hsync off) - ; 2 => blank to suspend (vsync off) - ; 3 => blank to off (H+V off) - -Export_ScreenBlankDPMSState # 1 - ASSERT Export_ScreenBlankDPMSState = ScreenBlankDPMSState - ASSERT ?Export_ScreenBlankDPMSState = ?ScreenBlankDPMSState - - - [ AssemblingArthur :LAND: :DEF: ShowWS - ! 0,"64 ":CC::STR:@ - ] - AlignSpace 64 - -Export_FgEcfOraEor # 4*16 ; Interleaved zgora & zgeor - ASSERT Export_FgEcfOraEor = FgEcfOraEor - ASSERT ?Export_FgEcfOraEor = ?FgEcfOraEor - -Export_BgEcfOraEor # 4*16 ; Interleaved zgora & zgeor - ASSERT Export_BgEcfOraEor = BgEcfOraEor - ASSERT ?Export_BgEcfOraEor = ?BgEcfOraEor - -BgEcfStore # 4*16 ; Interleaved zgora & zgeor to store background - -;Current state of pattern -LineDotCnt # 4 ; Count down to restarting pattern -LineDotPatLSW # 4 ; Current state of pattern LSWord -LineDotPatMSW # 4 ; " " " " MSWord - -DotLineLength # 4 ; Dot Pattern repeat length as given in *FX163,242,n - -BBCcompatibleECFs # 4 ; 0 => BBC compatible, 1 => native - -SpAreaStart # 4 ; Start of sprite area -SpChooseName # 16 ; No comment says Richard -SpChoosePtr # 4 - - # 8*4 ; SPARE (avoiding changes of exported addresses for now) - -TeletextOffset # 4 ; Offset to current teletext flash bank - -TeletextCount # 4 ; Number of vsyncs till next teletext flash - -WrchNbit # 4 ; Pointer to char code for current mode - - [ HiResTTX -CharWidth # 4 ; Width of a character in bytes (same as BytesPerChar except - ; in MODE 7, where characters are 16 pixels wide) - ] -TTXFlags # 4 ; VDU 23,18 flags -TTXFlag_Suspend * 1:SHL:0 -TTXFlag_Conceal * 1:SHL:1 -TTXFlag_BlackEnable * 1:SHL:2 -TTXFlag_TransModeShift * 3 -TTXFlag_TransModeMask * 3:SHL:TTXFlag_TransModeShift - ; bits 9-11 must be zero -TTXFlag_FgTransEOR * 1:SHL:12 - ; bits 13-15 must be zero -TTXFlag_BgTransEOR * 1:SHL:16 - ; bits 17-19 must be zero -TTXFlag_FgTransBIC * 1:SHL:20 - ; bits 21-23 must be zero -TTXFlag_BgTransBIC * 1:SHL:24 - -BeepBlock # 8 ; OSWORD block for VDU 7 - -ScreenMemoryClaimed # 1 ; NZ => memory has been claimed or is unusable -ExternalFramestore # 1 ; NZ => using external framestore rather than screen memory DA - - [ AssemblingArthur :LAND: :DEF: ShowWS - ! 0,"16 ":CC::STR:@ - ] - AlignSpace 16 ; Align workspace to 16 bytes - -TTXDoubleCounts # 25 ; Number of double height chars on each line - - [ AssemblingArthur :LAND: :DEF: ShowWS - ! 0,"16 ":CC::STR:@ - ] - AlignSpace 16 ; Align workspace to 16 bytes - -RAMMaskTb # 32*4 ; Copy of MaskTb for this mode (up to 32 words) - - [ AssemblingArthur :LAND: :DEF: ShowWS - ! 0,"16 ":CC::STR:@ - ] - AlignSpace 16 ; Align workspace to 16 bytes - -VduOutputCurrentState # 0 ; values of R0-R3 to return from SwitchOutputToSprite - ; or Mask; next 4 must be in this order -SpriteMaskSelect # 4 ; value of R0 to be given to SWI OS_SpriteOp to set up - ; current state -VduSpriteArea # 4 ; Pointer to sprite area containing VDU output sprite - ; (0 if output is to screen) -VduSprite # 4 ; Pointer to VDU output sprite (0 if output to screen) - -VduSaveAreaPtr # 4 ; Pointer to save area for VDU variables - - - [ AssemblingArthur :LAND: :DEF: ShowWS - ! 0,"16,12 ":CC::STR:@ - ] - AlignSpace 16, 12 ; Make ClipBoxCoords a valid immediate, - ; with ClipBoxEnable immediately before it -ClipBoxInfo # 0 -ClipBoxEnable # 4 ; 0 => clip box disabled, 1 => enabled - -ClipBoxCoords # 0 ; Internal coords of modified area of screen -ClipBoxLCol # 4 -ClipBoxBRow # 4 -ClipBoxRCol # 4 -ClipBoxTRow # 4 - -FgPattern # 4*8 ; foreground pattern as defined by OS_SetColour -BgPattern # 4*8 ; background pattern as defined by OS_SetColour - - # 3*4 ; SPARE (avoiding changes of exported addresses for now) - -KernelModeSelector # 4 ; pointer to block in system heap where - ; current mode selector is copied - - [ AssemblingArthur :LAND: :DEF: ShowWS - ! 0,"16 ":CC::STR:@ - ] - AlignSpace 16 ; Align workspace to 16 bytes - -TextExpand # 4*1024 ; Tim's massive text expansion table for whizzy WRCH -; TextPlain is now always hard against the end of TextExpand for this mode - -TTXSoftFonts * TextExpand + 2*1024 ; Soft fonts in teletext mode - - [ AssemblingArthur :LAND: :DEF: ShowWS - ! 0,"64 ":CC::STR:@ - ] - AlignSpace 64 ; Align workspace to 64 bytes - -; Teletext map and copy/move buffer are overlaid - -TTXMapSize * 41*25*4 ; (&1004 bytes) -LargeCommon # TTXMapSize ; the largest area -TTXMap * LargeCommon - -ScrLoaSpriteCB * LargeCommon ; (size = SpriteCBsize + MaxSpritePaletteSize) -ScrLoaBuffer * LargeCommon ; (size = one pixel row) -ScrSavCommon * LargeCommon ; (size = SpriteAreaCBsize + SpriteCBsize - ; + MaxSpritePaletteSize) - -FldQueueSize * ScratchSpaceSize -FldQueueStart * ScratchSpace - - [ AssemblingArthur :LAND: :DEF: ShowWS - ! 0,"64 ":CC::STR:@ - ] - AlignSpace 64 ; Align workspace to 64 bytes - -Font # &700 ; 7 pages of (soft) font - -SaveAreaSize * 12*1024-@ - -VduSaveArea # SaveAreaSize ; save area for switching output to sprites - -VDWSSize # 0 - - ASSERT VDWSSize <= 12 * 1024 - -; ***************************************************************************** -; Space in the first 32K is allocated below -; ***************************************************************************** -; Real workspace definition - -; locations used during reset only. Not cleared by ClearPhysRAM, but -; cleared later (just before DEFHAN). - - ^ ZeroPage+&80 ; steer clear of FIQ code -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 ; can't remember -InitClearRamWs # 10*4 - AlignSpace 32 ; because we clear 32 at a time -InitWsEnd # 0 - -; Basic kernel space - defined locations for external modules - - ^ ZeroPage+&100 -IRQ1V # 4 ; &100 - -Export_ESC_Status # 1 ; &104 - ASSERT Export_ESC_Status = ESC_Status - ASSERT ?Export_ESC_Status = ?ESC_Status - -Export_LatchBSoftCopy # 1 ; &105 - ASSERT Export_LatchBSoftCopy = LatchBSoftCopy - ASSERT ?Export_LatchBSoftCopy = ?LatchBSoftCopy - -IOCControlSoftCopy # 1 ; &106 - -Export_CannotReset # 1 ; &107 - ASSERT Export_CannotReset = CannotReset - ASSERT ?Export_CannotReset = ?CannotReset - -Export_IRQsema # 4 ; &108 - ASSERT Export_IRQsema = IRQsema - ASSERT ?Export_IRQsema = ?IRQsema - -MetroGnome # 4 ; &10C -MemorySpeed # 4 ; &110 - -Export_MEMC_CR_SoftCopy # 4 ; &114 - ASSERT Export_MEMC_CR_SoftCopy = MEMC_CR_SoftCopy - ASSERT ?Export_MEMC_CR_SoftCopy = ?MEMC_CR_SoftCopy - -ResetIndirection # 4 ; &118 - -; Now all internal definitions - -; Up to here is initialized on reset - -; Next come handler variables - -MemLimit # 4 -UndHan # 4 -PAbHan # 4 -DAbHan # 4 -AdXHan # 4 - -ErrHan # 4 -ErrBuf # 4 -ErrHan_ws # 4 - -CallAd_ws # 4 ; smart Rs ordering: -CallAd # 4 ; can do LDMIA of r12, pc -CallBf # 4 - -BrkAd_ws # 4 -BrkAd # 4 -BrkBf # 4 - -EscHan_ws # 4 -EscHan # 4 - -EvtHan_ws # 4 -EvtHan # 4 - -; The next lot of workspace is in the space vacated by the small soft CAM map area -; (256 words) which is no longer adequate, so we can reuse it - -JordanWS # 0 - # 3*4 ; SPARE -DAList # 4 ; Pointer to first node on dynamic area list - - - AlignSpace 16 -AMBControl_ws # 4 ; workspace anchor word for AMBControl -DynArea_ws # 4 ; workspace anchor word for data structures to accelerate OS SWIs for dynamic areas - [ StrongARM -SyncCodeA_sema # 1 ; re-entrancy semaphore for SynchroniseCodeAreas (full address space version) - [ :DEF: ShowWS - ! 0, "AMBControl_ws at ":CC::STR:(AMBControl_ws) - ! 0, "DynArea_ws at ":CC::STR:(DynArea_ws) - ! 0, "SyncCodeA_sema (byte) at ":CC::STR:(SyncCodeA_sema) - ] - ] -; [ this was used on Phoebe as described below, now only used for Wimp free pool lock ] -; word controlling rescue of VRAM that is not used by screen (and sorting into bottom of free pool) - VRAM is slower than SDRAM for Phoebe. -; word organised as 3 fields - control field (byte) is not written by interrupt routine, so can be safely manipulated by foreground with IRQs enabled -VRAMRescue_control # 1 ; control bits manipulated by foreground, read by interrupt driven rescuer - ; Bit fields of VRAMRescue_control (VRRc_...) defined as follows: - ; -VRRc_disable * &01 ; control bit 0 slow page rescue from Free Pool disabled completely, if set (disabled for no VRAM) -VRRc_suspend * &02 ; control bit 1 slow page rescue suspended by outside agent, if set -VRRc_wimp_lock * &04 ; control bit 2 slow page rescue suspended because Wimp_ClaimFreeMemory has claimed free pool, if set - ; control bits 3..7 reserved (should be 0) - - AlignSpace 4 -Oscli_CmdHashSum # 4 ;for hashed command lookup -Oscli_CmdHashLists # 4 ;anchor for hashed command lists structure - [ :DEF: ShowWS - ! 0, "Oscli_CmdHashSum at ":CC::STR:(Oscli_CmdHashSum) - ! 0, "Oscli_CmdHashLists at ":CC::STR:(Oscli_CmdHashLists) - ] - -Serv_SysChains # 4 ;anchor for block handling 'system' service numbers, in range 1 to 255 -Serv_UsrChains # 4 ;anchor for block handling 'user' service numbers, > 255 -Serv_AwkwardChain # 4 ;anchor for chain handling non-compliant modules (no service table) - [ :DEF: ShowWS - ! 0, "Serv_SysChains at ":CC::STR:(Serv_SysChains) - ! 0, "Serv_UsrChains at ":CC::STR:(Serv_UsrChains) - ! 0, "Serv_AwkwardChain at ":CC::STR:(Serv_AwkwardChain) - ] - - - AlignSpace 32 ; skipped bit must start on 32-byte boundary (due to speedup) - -SkippedTables # 0 -PhysRamTable # 0 ; 6 pairs of words (physaddr, size) indicating - ; RAM present in machine (NB normally you would need at most 5 - ; on IOMD machines, but the extra one is if a soft-loaded ROM image - ; causes a bank to split -VideoPhysAddr # 4 ; Address of video RAM (in the case of DRAM-only machines, -VideoSize # 4 ; this is actually a chunk out of DRAM) -DRAMPhysAddrA # 4 ; Next the DRAM - note that any banks with no memory -DRAMSizeA # 4 ; in them will be omitted from this table, so that -DRAMPhysAddrB # 4 ; eg DRAMPhysAddrA corresponds to the first bank with -DRAMSizeB # 4 ; DRAM in it, not necessarily bank 0 -DRAMPhysAddrC # 4 ; If not all the slots are occupied, then -DRAMSizeC # 4 ; the remaining entries in this table have size fields -DRAMPhysAddrD # 4 ; of zero (and probably addresses of zero too) -DRAMSizeD # 4 -DRAMPhysAddrE # 4 -DRAMSizeE # 4 - [ MorrisSupport -DRAMPhysAddrExtra # 8 * 12 ; The DRAM used with MORRIS can fragment into four - ; blocks so allocate 3 extra word pairs per bank - ] -PhysRamTableEnd # 0 -DRAMPhysTableSize * (PhysRamTableEnd-DRAMPhysAddrA) / 8 - - [ :DEF: ShowWS - ! 0, "VideoPhysAddr held at ":CC::STR:(VideoPhysAddr) - ] - - [ HAL -VRAMFlags # 4 ; Flags of VRAM block (from HAL's AddRAM call) -L2PTUsed # 4 ; Amount of memory used for L2PT - | -VRAMSize # 4 ; Amount of VRAM (in bytes) (may be more than 2M) (at &200 last time I checked) -VideoBandwidth # 4 ; video bandwidth in bytes/sec -L2PTSize # 4 ; Amount of memory (in bytes) used for static L2PT - ; - this consists of fixed size first bit, plus variable size - ; bit for the free pool L2, which follows directly after it - ] -SoftCamMapSize # 4 ; Amount of memory (in bytes) used for soft CAM map - ; (whole number of pages) - [ {FALSE} -InitKbdHandler # 4 ; Address of interrupt routine -InitKbdWs # 16 ; Workspace for reset keyboard IRQ code (was 12 changed for Morris) - ] - [ :LNOT: HAL -CLine_Softcopy # 1 ; Added for Morris - Monitor id - -VRAMWidth # 1 ; 0 => no VRAM, 1 => 32-bits wide, 2 => 64-bits wide - - [ {FALSE} ;;; mjsHAL no LCD support -LCD_Active # 1 ; Added to support LCD/CRT switching. bm 6 bits 0=>External CRT in use, 1=>Mono, 2=>Passive colour, 3=>Active colour - ; bit 7 unset=>single panel, set=>dual panel -LCD_Inverted # 1 ; Added to support LCD palette inversion. 0=normal, 1=inverted. Note that the inversion is invisible to apps. - [ :DEF: ShowWS - ! 0, "LCD_Active flag byte held at ":CC::STR:(LCD_Active) - ] - | - # 2 ; SPARE - ] - ] - - [ HAL - AlignSpace -HAL_StartFlags # 4 -HAL_Descriptor # 4 -HAL_Workspace # 4 -HAL_WsSize # 4 - -ICache_Info # 0 -ICache_NSets # 4 -ICache_Size # 4 -ICache_LineLen # 1 -ICache_Associativity # 1 - -Cache_Type # 1 -Cache_Flags # 1 - -DCache_Info # 0 -DCache_NSets # 4 -DCache_Size # 4 -DCache_LineLen # 1 -DCache_Associativity # 1 - # 2 - -DCache_CleanBaseAddress # 0 ; word used either for IndexBit or CleanBaseAddress -DCache_IndexBit # 4 -DCache_CleanNextAddress # 0 ; word used either for IndexSegStart or CleanNextAddress -DCache_IndexSegStart # 4 -DCache_RangeThreshold # 4 - -ProcessorArch # 1 - ] -IOSystemType # 1 ; 0 => old I/O subsystem, 1 => IOEB+82C710 system, 2..255 => ? -ProcessorType # 1 ; Processor type (handles 600 series onwards) - AlignSpace -ProcessorFlags # 4 ; Processor flags (IMB, Arch4 etc) - [ :DEF: ShowWS - ! 0, "ProcessorType at ":CC::STR:(ProcessorType) - ! 0, "ProcessorFlags at ":CC::STR:(ProcessorFlags) - ] - [ HAL - - AlignSpace - -MMU_PCBTrans # 4 - -Proc_Cache_CleanInvalidateAll # 4 -Proc_Cache_CleanAll # 4 -Proc_Cache_InvalidateAll # 4 -Proc_Cache_RangeThreshold # 4 -Proc_TLB_InvalidateAll # 4 -Proc_TLB_InvalidateEntry # 4 -Proc_WriteBuffer_Drain # 4 -Proc_IMB_Full # 4 -Proc_IMB_Range # 4 -Proc_MMU_Changing # 4 -Proc_MMU_ChangingEntry # 4 -Proc_MMU_ChangingUncached # 4 -Proc_MMU_ChangingUncachedEntry # 4 -Proc_MMU_ChangingEntries # 4 -Proc_MMU_ChangingUncachedEntries # 4 - - ] - - -IOAllocPtr # 4 ; current lowpoint of mapped I/O space (also upper limit on DAs) -IOAllocLimit # 4 ; current lowest allowed I/O space (DA creation may move this up) - - AlignSpace 32 ; skipped bit must end on 32-byte boundary (due to speedup) -SkippedTablesEnd # 0 - - - -ProcVec_Start # 0 ; Start of processor vector table -ProcVec_Branch0 # 4 ; Branch through zero -ProcVec_UndInst # 4 ; Undefined instruction vector -ProcVec_SWI # 4 ; SWI vector -ProcVec_PrefAb # 4 ; Prefetch abort vector -ProcVec_DataAb # 4 ; Data abort vector -ProcVec_AddrEx # 4 ; not used (was Address exception vector on 26-bit-only ARMs) -ProcVec_IRQ # 4 ; IRQ vector -ProcVec_End # 0 - -ProcVecPreVeneersSize * 4*4 ; Space for preveneers for loading handler addresses from 0 page. -ProcVecPreVeneers # ProcVecPreVeneersSize - - [ :DEF: ShowWS - ! 0, "Free space before DebuggerSpace = ":CC::STR:(&300-@) - ] - - ASSERT @ <= &300 - # (&300-@) -Export_DebuggerSpace # 16*8 ; Debugger module needs some zero page - -; NVRAM support - -NVRamSize # 1 ; Size of NVRam (E2ROM & CMOS) fitted in 256byte units -RTCFitted # 1 ; flag non zero if RTC is fitted -NVRamBase # 1 ; Base of NVRam -NVRamSpeed # 1 ; Clock hold time in 0.5µs units -NVRamPageSize # 1 ; Page size for writing (log2) -NVRamWriteSize # 1 ; Size of writable region (256byte units) - - AlignSpace - -IICType # 4 -IICStatus # 4 - -AppSpaceDANode # DANode_NodeSize ; Dummy area node for application space (not on list) -FreePoolDANode # DANode_NodeSize ; Area node for free pool -SysHeapDANode # DANode_NodeSize ; Area node for system heap -CDASemaphore # 4 ; Semaphore for OS_ChangeDynamicArea - non-zero => routine threaded -MMUControlSoftCopy # 4 ; Soft copy of ARM control register - [ HAL -DeviceCount # 4 ; size of our table of devices in the system heap -DeviceTable # 4 ; pointer to table - ] - -AplWorkSize * AppSpaceDANode + DANode_Size - - [ :LNOT: LongCommandLines -EnvString # 256 - ] - - [ :DEF: ShowWS - ! 0, "Free space after EnvString = ":CC::STR:(&500-@) - ] - - ASSERT @ <= &500 ; a convenient address to remember - # (&500-@) - -CamMapCorruptDebugBlock # &40 ; somewhere to dump registers in case of emergency - - [ :DEF: ShowWS - ! 0, "Free space after CamMap debug block = ":CC::STR:((JordanWS+256*4)-@) - ] - - ASSERT @ <= JordanWS+256*4 - # (JordanWS+256*4-@) ; pad out to original size - -CamEntriesPointer # 4 ; points to where CAM soft copy is - ; (CamEntries for machines up to 8MBytes, - ; CamEntriesForBigMachines for larger machines) - -MaxCamEntry # 4 ; maximum index into the cam map, ie - ; 511 for 16MByte machines, 383 for 12MBytes - ; 255 for 8MBytes, otherwise 127 - -RAMLIMIT # 4 - -ROMPhysAddr # 4 - -HiServ_ws # 4 -HiServ # 4 -SExitA # 4 -SExitA_ws # 4 -UpCallHan_ws # 4 -UpCallHan # 4 - -ROMModuleChain # 4 ; pointer to head of ROM module chain - -; now a section that it's handy to have in simply loadable places - - [ AssemblingArthur :LAND: :DEF: ShowWS - ! 0,"16 ":CC::STR:@ - ] - AlignSpace 16 - -KeyWorkSpaceSize * &200 -KeyWorkSpace # KeyWorkSpaceSize - [ :DEF: ShowWS - ! 0, "KeyWorkSpace at ":CC::STR:(KeyWorkSpace) - ] - -; The following were reordered on 26-Jul-91. Old ordering was: -; GeneralMOSBuffer -; ModuleSWI_HashTab -; Module_List -; Curr_Active_Object -; VecPtrTab -; ExceptionDump - -; SWI hash table moved to OldIRQ1Vspace on 12-Nov-97, for Ursula (wider hashing) -; -; !!!! Free Space -; - [ ChocolateSysHeap -ChocolateBlockArrays # 0 -ChocolateCBBlocks # 4 ; -> array of quick access blocks for Callback -ChocolateSVBlocks # 4 ; -> array of quick access blocks for software vectors -ChocolateTKBlocks # 4 ; -> array of quick access blocks for tickers -ChocolateMRBlocks # 4 ; -> array of blocks for ROM module nodes (reduces no. of individual blocks in heap) -ChocolateMABlocks # 4 ; -> array of blocks for active module nodes (reduces no. of individual blocks in heap) -ChocolateMSBlocks # 4 ; -> array of blocks for module SWI hash nodes (reduces no. of individual blocks in heap) - [ :DEF: ShowWS - ! 0, "ChocolateCBBlocks at ":CC::STR:(ChocolateCBBlocks) - ! 0, "ChocolateSVBlocks at ":CC::STR:(ChocolateSVBlocks) - ! 0, "ChocolateTKBlocks at ":CC::STR:(ChocolateTKBlocks) - ! 0, "ChocolateMRBlocks at ":CC::STR:(ChocolateMRBlocks) - ! 0, "ChocolateMABlocks at ":CC::STR:(ChocolateMABlocks) - ! 0, "ChocolateMSBlocks at ":CC::STR:(ChocolateMSBlocks) - ] - - [ :LNOT: HAL -mjs_tempHALworkspace # 4 ; required only temporarily for semi-HALised code still in RO kernel - [ :DEF: ShowWS - ! 0, "*** mjs_tempHALworkspace should be removed when kernel/HAL split permits" - ] -; !!!! Free Space (36 bytes) -OldSWIHashspace # 9*4 - | -; !!!! Free Space (40 bytes) -OldSWIHashspace # 10*4 - ] - - | -; !!!! Free Space (64 bytes) -OldSWIHashspace # 16*4 - ] - -; -;was: -;ModuleSHT_Entries * 16 -;ModuleSWI_HashTab # 4*ModuleSHT_Entries - -Module_List # 4 - [ :DEF: ShowWS - ! 0, "Module_List at ":CC::STR:(Module_List) - ] - -Curr_Active_Object # 4 - -; Vector Claim & Release tables etc - -VecPtrTab # NVECTORS * 4 - -ExceptionDump # 4 - -; GeneralMOSBuffer: re-use with caution! -; Here's just some of the users: -; user use(s) -; default error handler error buffer (must be 246+4 bytes big) -; *If expression to be evaluated to control the *If -; Command line to be submited on the expression -; evaluating to non-zero (the THEN clause). - [ LongCommandLines -OldGeneralMOSBuffer # 256+4 ;spare - | -GeneralMOSBuffer # 256+4 - ] - - [ AssemblingArthur :LAND: :DEF: ShowWS - ! 0,"16 ":CC::STR:@ - ] - AlignSpace 16 ; Ensures we can MOV rn, #OsbyteVars if <=&1000 - -OsbyteVars # OSBYTEVarSize - ASSERT OsbyteVars < &10000 ; Must keep in first 64K so address can be read by - ; (and stored in) OS_Bytes &A6,&A7. SKS - -; These must be in first 4K -NBuffers * 10 -BuffInPtrs # 4 * NBuffers -BuffOutPtrs # 4 * NBuffers - -VariableList # 4 - -; Oscli stuff -OscliCBtopUID # 4 -OscliCBbotUID # 4 -OscliCBcurrend # 4 - -ReturnCode # 4 -RCLimit # 4 - -SpriteSize # 4 ; saved on startup for Sprite code - -TickNodeChain # 4 - -PIRQ_Chain # 4 -PFIQasIRQ_Chain # 4 - -; Workspace - -EnvTime # 5 - -Export_RedirectInHandle # 1 - ASSERT Export_RedirectInHandle = RedirectInHandle - ASSERT ?Export_RedirectInHandle = ?RedirectInHandle - -Export_RedirectOutHandle # 1 - ASSERT Export_RedirectOutHandle = RedirectOutHandle - ASSERT ?Export_RedirectOutHandle = ?RedirectOutHandle - -MOShasFIQ # 1 -FIQclaim_interlock # 1 -CallBack_Flag # 1 -IRQ_CallBack_Flag * CallBack_Flag -MonitorLeadType # 1 ; some function of the monitor lead inputs, as yet undetermined - - AlignSpace - -DUMPER # 17 * 4 ; now 17 words for 32-bit - - # 4 ; PxxxIRQ_Chain used to be here -Page_Size # 4 -CMOSRAMCache # 256 - -; Was Free space (752 bytes) left by old IRQ despatch (new IRQ despatch moved as it required more space). -; Re-used for various purposes on 12-Nov-97, for Ursula -; - ASSERT @ = &C34 ;if fails, may need to rearrange padding to sort hash table alignment -; -ModuleSHT_Entries * 128 -ModuleSHT_Padding0 # 12 ;spare, so that SWI hashtable is aligned for easy immediate address load -ModuleSWI_HashTab # 4*ModuleSHT_Entries - [ :DEF: ShowWS - ! 0, "ModuleSWI_HashTab at ":CC::STR:(ModuleSWI_HashTab) - ] -; -SysVars_StickyPointers # (10+1)*4 ;used if ChocolateSysVars is TRUE (1 dummy pointer for 0 size) - [ :DEF: ShowWS - ! 0, "SysVars_StickyPtrs at ":CC::STR:(SysVars_StickyPointers) - ] -; -Abort32_dumparea # 6*4 ;info for OS_ReadSysInfo 7 - 32-bit PSR, fault address, 32-bit PC (room for two copies) - [ :DEF: ShowWS - ! 0, "Abort32_dumparea at ":CC::STR:(Abort32_dumparea) - ] -; -Help_guard # 4 ;for *help, guard against foreground re-entrancy (multiple taskwindows) -Help_msgdescr # 4*4 ;for *help, 4 words MessageTrans descriptor - [ :DEF: ShowWS - ! 0, "Help_guard at ":CC::STR:(Help_guard) - ] -; -PCI_status # 4 ;bit 0 = 1 if PCI exists or 0 if PCI does not exist, bits 1..31 reserved (0) - [ :DEF: ShowWS - ! 0, "PCI_status at ":CC::STR:(PCI_status) - ] -IOMD_NoInterrupt # 4 ;no. of irq devices for extant IOMD -IOMD_DefaultIRQ1Vcode # 4 ;default irq code start address (ROM) for extant IOMD -IOMD_DefaultIRQ1Vcode_end # 4 ;default irq code end address (ROM) -IOMD_Devices # 4 ;default irq devices table address (ROM) - [ :DEF: ShowWS - ! 0, "IOMD_NoInterrupt at ":CC::STR:(IOMD_NoInterrupt) - ] -; - [ mjsSysHeapNodesTrace -mjsSHNodesTrace_ws # 0 -mjsSHNT_hcl_total # 4 ;total calls to ClaimSysHeapNode -mjsSHNT_hfr_total # 4 ;total calls to FreeSysHeapNode -mjsSHNT_hop_total # 4 ;total calls to DoSysHeapOpWithExpansion -mjsSHNT_ohc_total # 4 ;total calls to OS_Heap for SysHeap claim -mjsSHNT_ohf_total # 4 ;total calls to OS_Heap for SysHeap free -mjsSHNT_ohx_total # 4 ;total calls to OS_Heap for SysHeap expand or shrink -mjsSHNT_vcs_total # 4 ;total SysVar ClaimVNode calls that picked up a sticky node -mjsSHNT_vch_total # 4 ;total SysVar ClaimVNode calls that went to the heap for a node -mjsSHNT_vxs_total # 4 ;total SysVar ExpandOrShrinkVNode calls that tried to do sticky change -mjsSHNT_vxh_total # 4 ;total SysVar ExpandOrShrinkVNode calls that went to the heap -mjsSHNT_vfs_total # 4 ;total SysVar FreeVNode calls that stuck -mjsSHNT_vfh_total # 4 ;total SysVar FreeVNode calls that dropped a node to the heap - [ :DEF: ShowWS - ! 0, "" - ! 0, "**WARNING** compiling in code to trace some SysHeap node statistics (mjsSysHeapNodesTrace TRUE)" - ! 0, "" - ! 0, "mjsSHNodesTrace_ws at ":CC::STR:(mjsSHNodesTrace_ws) - ] -ModuleSHT_Padding1 # 752-12-4*ModuleSHT_Entries-11*4-6*4-5*4-4-4*4-12*4 ;spare - | -ModuleSHT_Padding1 # 752-12-4*ModuleSHT_Entries-11*4-6*4-5*4-4-4*4 ;spare - ] -; - ASSERT @ = &C34 + 752 -; -;was: -;OldIRQ1Vspace # 752 - - -CallBack_Vector # 4 - -; interruptible heap manager workspace - -HeapSavedReg_R0 # 4 -HeapSavedReg_R1 # 4 -HeapSavedReg_R2 # 4 -HeapSavedReg_R3 # 4 -HeapSavedReg_R4 # 4 -HeapSavedReg_R13 # 4 -HeapReturnedReg_R0 # 4 -HeapReturnedReg_R1 # 4 -HeapReturnedReg_R2 # 4 -HeapReturnedReg_R3 # 4 -HeapReturnedReg_R4 # 4 -HeapReturnedReg_R13 # 4 -HeapReturnedReg_PSR # 4 ; also acts as interlock - -PrinterBufferAddr # 4 ; holds address of printer buffer -PrinterBufferSize # 4 ; size of printer buffer - not to be confused with PrintBuffSize - ; which is the (constant) default size for the MOS's smallish buffer -RawMachineID # 8 ; 64 bits for unique machine ID -KernelMessagesBlock # 20 ; 5 Words for messagetrans message block. -ErrorSemaphore # 1 ; Error semaphore to avoid looping on error translation. - [ StorkPowerSave -PortableFlags # 1 ; -PowerSave * &80 - | -PortableFlag # 1 ; Non-zero => got an error from Portable_Speed, so don't try it again - ] - - AlignSpace - -MOSConvertBuffer # 12 ; Enough romm for 8 hex digits. -AbortIndirection # 4 ; Pointer to list of addresses and trap routines -PreVeneerRegDump # 17*4 ; room for r0-r15, spsr - - [ CacheCommonErrors -CachedErrorBlocks # 4 ; pointer to sysheap node holding the error block cache - ] - - [ AssemblingArthur :LAND: :DEF: ShowWS - ! 0, "low space free ":CC::STR:(&FE8-@) - ] - ASSERT @ < &FE8 - -; Words for old tools of assorted varieties -; Don't move the following as their positions are assumed by other modules - - ^ &FE8 -CLibCounter # 1 ; Counter for Shared C Library tmpnam function - - AlignSpace - -; ECN 17-Feb-92 -; Added RISCOSLibWord and CLibWord. The ROM RISCOSLib and CLib must continue -; to work even when they are killed since ROM apps are hard linked to the -; ROM libraries. They cannot use the private word since the block pointed -; to by this will be freed. -RISCOSLibWord # 4 -CLibWord # 4 -FPEAnchor # 4 - -Export_DomainId # 4 ; SKS added for domain identification - ASSERT Export_DomainId = DomainId - ASSERT ?Export_DomainId = ?DomainId - -Modula2_Private # 4 ; MICK has FFC and uses it it in USR mode - -Export_VduDriverWorkSpace # VDWSSize - ASSERT Export_VduDriverWorkSpace = VduDriverWorkSpace - ASSERT ?Export_VduDriverWorkSpace = ?VduDriverWorkSpace - - ASSERT (VduDriverWorkSpace :AND: 63) = 0 ; For Tim (VDU5) - - - [ AssemblingArthur :LAND: :DEF: ShowWS - ! 0, "high space free ":CC::STR:(&4000-@) - ] - - ^ &4000 -ScratchSpaceSize * &4000 - -Export_ScratchSpace # ScratchSpaceSize - ASSERT Export_ScratchSpace = ScratchSpace - ASSERT ?Export_ScratchSpace = ?ScratchSpace - - ASSERT @ <= &8000 ; Start of apl - -; ***************************************************************************** -; Users of ScratchSpace declare yourself here: - -; NRaine: Filling a polygon uses ScratchSpace to flatten the path - -; DSeal: Draw module uses ScratchSpace on fill operations (this supercedes -; NRaine's declaration above). - -; SKS: HeapSort with (r1 & 0x80000000) & ~(r1 & 0x20000000) & (r5 <= 16K) -; uses ScratchSpace as a temp slot for data shuffling after sorting - -; TMD: Flood fill uses ScratchSpace for the flood queue. - -; Tidying the RMA uses ScratchSpace while all modules are dead - - [ GSWorkspaceInKernelBuffers -; the GSTrans workspace has now moved to the kernel buffers area -; GSInit and GSRead may now safely be called from USR mode wahey... - | -; GSTRANS workspace: GSINIT puts state into the workspacem and GSREAD uses it. -; DO NOT do any operations between GSINIT/GSREAD SWIS. -; SWIs called: OSWord in time var code -; BinaryToDecimal, ReadUnsigned - ] - -; LVR: ADFS uses scratch space to format floppies on 1772 based machines - -; DDV: ColourTrans uses scratch space to build palette tables when in -; ColourTrans_SelecTable/RetrunColourNumber and also whilst generating -; stipple pattterns. - - [ GSWorkspaceInKernelBuffers -; GSVarWSpace is now in kernel buffers - | -GSVarWSpace * ScratchSpace - ] - - ^ 0 -GSNameBuff # &100 -GS_Stack # &200 -GS_StackPtr_Lim * &200 / 4 ; Number of words in stack. -GS_StackPtr # 4 - [ GSWorkspaceInKernelBuffers -GSVarWSpace_Size # 0 - ] - - ^ @ + ScratchSpace - -; Pointers for SubstituteArgs: no external calls. -; Ensure these don't overlap FileSwitch's buffers below! - -MacExStartPtrs # 44 -MacExEndPtrs # 44 - -; OS_CLI has a buffer for alias expansion: ReadVarVal and SubstituteArgs -; are called while the buffer is held. Also used for module prefixes: -; Module called twice in this case. - - [ LongCommandLines -OldAliasExpansionBuffer # 100 ;spare, mjs: shouldn't this have been &100 ??!?? - | -AliasExpansionBuffer # 100 ;mjs: shouldn't this be &100 ??!?? -; *list/*type need an argument expansion buffer: ReadArgs called with it. -ArgumentBuffer * AliasExpansionBuffer - ] - - -; EvaluateExpression space. Calls ReadUnsigned, BinaryToDecimal and ReadVarVal. - -ExprWSpace * @ - - ^ 0, R12 - [ LongCommandLines - ;ExprBuff moved to Kernel buffers area - | -ExprBuff # &100 - ] -exprBracDif # 2 ; keep exprSTRACC aligned -tos_op # 2 ; 1 byte for use as STRACC-1 -ExprSVCstack # 4 - - [ LongCommandLines - ;exprSTRACC moved to Kernel buffers area -ExprStackLimit * @ - exprBracDif + ExprWSpace + &100 ;keep 256 buffer zone for stack overflow -ExprStackStart * ScratchSpace + ScratchSpaceSize - | -exprSTRACC * @ - ExprBuff + ExprWSpace -ExprStackLimit * exprSTRACC + &100 -ExprStackStart * ScratchSpace + ScratchSpaceSize - ] - - -; Tutu needs some for argument substitution + expansion for run/load types -; Only OS call during xform is XOS_SubstituteArgs and XOS_Heap(Claim,SysHeap) - - ^ 0 ; Offset from ScratchSpace -rav_substituted # 256 -rav_arglist # 256 - -TopOfPageZero # 0 - - ^ &8000 ; The actual top of Page Zero -EconetDebugSpace |#| &20 * 4 ; Thirty two words (&7F80) - - ASSERT @ > TopOfPageZero ; Make sure we don't clash - -; ***************************************************************************** -; *** Cursor, Sound DMA, SWI, and OSCLI workspace. *** -; *** Sits in the 32K above 31M, ie. &01F000000..&01F07FFF *** -; *** Has the physical address &02078000, ie. 32M + 512K - 32K *** -; ***************************************************************************** - -TopOfDMAPhysRAM * &80000 ; OFFSET in physram -TopOfDMAWorkSpace * CursorChunkAddress + 32*1024 -OffsetLogicalToPhysical * TopOfDMAPhysRAM - TopOfDMAWorkSpace - - ^ TopOfDMAWorkSpace ; Note we will be going down - -; Sound - -SoundWorkSpaceSize * &1000 - -Export_SoundDMABufferSize * &1000 - ASSERT Export_SoundDMABufferSize = SoundDMABufferSize - -SoundEvtSize * &1000 - -Export_SoundDMABuffers |#| SoundDMABufferSize * 2 - ASSERT Export_SoundDMABuffers = SoundDMABuffers - ASSERT ?Export_SoundDMABuffers = ?SoundDMABuffers - -Export_SoundWorkSpace |#| SoundWorkSpaceSize + SoundEvtSize - ASSERT Export_SoundWorkSpace = SoundWorkSpace - ASSERT ?Export_SoundWorkSpace = ?SoundWorkSpace - -; Cursor -; mjs Sep 2000, Kernel/HAL split -; Note that cursor data memory is expected to be uncacheable, since HAL may use it -; directly for h/w DMA. This may not be true since RO 3.7, but should be sorted -; eventually for next generation RO - -CursorDataSize * &600 ; four defined shapes, plus 2 holding shapes -CursorData |#| CursorDataSize -CursorSoundRAM * CursorData -CursorSoundPhysRAM * CursorSoundRAM + OffsetLogicalToPhysical - -SPARE_oldCursorSpace |#| &200 ; padding to avoid changing exported addresses for now - -; SWI despatcher - -BranchToSWIExit |#| 4 - -SvcTable |#| &400 - - [ :LNOT: HAL32 - ASSERT SvcTable = &01F033FC ; Required for SVC table pokers, 1.20 compatible - ] - [ No26bitCode -SWIDespatch_Size * 32*4 - | -SWIDespatch_Size * 30*4 ; can save 2 instructions if 26-bit (no Thumb) - ] -SWIDespatch |#| SWIDespatch_Size - - -; Buffers - -KeyBuffSize * &100 -RS423InBuffSize * &100 -RS423OutBuffSize * &C0 -PrintBuffSize * &400 -Sound0BuffSize * 4 -Sound1BuffSize * 4 -Sound2BuffSize * 4 -Sound3BuffSize * 4 -SpeechBuffSize * 4 -MouseBuffSize * &40 -KeyBuff |#| KeyBuffSize -RS423InBuff |#| RS423InBuffSize -RS423OutBuff |#| RS423OutBuffSize -PrintBuff |#| PrintBuffSize -Sound0Buff |#| Sound0BuffSize -Sound1Buff |#| Sound1BuffSize -Sound2Buff |#| Sound2BuffSize -Sound3Buff |#| Sound3BuffSize -SpeechBuff |#| SpeechBuffSize -MouseBuff |#| MouseBuffSize - -; Oscli buffering - - [ LongCommandLines -OldOscliBuffs |#| (16+1)*&100 ;spare - | -OscliBuffSize * &100 -OscliNoBuffs * 16 -OscliCircBuffLimit |#| 0 -OscliCircBuffStart |#| OscliBuffSize * OscliNoBuffs -RedirectBuff |#| OscliBuffSize - ] - -; Default IRQ despatch moved here as a result of IOMD having an extra -; 6 interrupts for I/O and sound DMA (this is really IOMD specific, not -; ARM600/700 specific but for the moment it is assumed that they are -; used on the same machines). - [ MorrisSupport -DefIRQ1Vspace * 12*4+12*23+2*256+64 + 7*4+12*16+32+256 ;Morris adds 2 more IRQ registers - | -DefIRQ1Vspace * 12*4+12*23+2*256+64 ; for size checking in MOS - ] -DefaultIRQ1V |#| DefIRQ1Vspace - - [ AssemblingArthur :LAND: :DEF: ShowWS - ! 0, "Aligning IRQ stack from ":CC::STR:@ - ] - [ @-7*4 :AND: 15 <> 0 - |#| (@-7*4):AND:15 - ] - [ :LNOT: HAL32 -IRQSTK # 0 ; Overflow will give abort - [ AssemblingArthur :LAND: :DEF: ShowWS - ! 0, "IRQ stack size ":CC::STR:(IRQSTK-CursorChunkAddress) - ] - ] - - ASSERT @ > ( CursorChunkAddress + &1000 ) ; Check minimum stack - -; ***************************************************************************** -; High system workspace -; ***************************************************************************** - - [ HAL32 - ^ SVCStackAddress - | - ^ SysHeapChunkAddress - ] - - # SVCStackSize ; svcstk size. Overflow will give abort -SVCSTK # 0 - - [ HAL32 -SysHeapStart * SysHeapAddress - | -SysHeapStart # 0 - ] - - -; ***************************************************************************** - - [ LongCommandLines - - ASSERT LongCLISize >= 256+4 ;minimum size of GeneralMOSBuffer - -;Kernel buffers area - - ^ KbuffsBaseAddress - -GeneralMOSBuffer # LongCLISize - -EnvString # LongCLISize - -AliasExpansionBuffer # LongCLISize -ArgumentBuffer * AliasExpansionBuffer - -ExprBuff # LongCLISize -exprSTRACC # LongCLISize - -OscliBuffSize * LongCLISize -OscliNoBuffs * 16 -RedirectBuff # OscliBuffSize -OscliCircBuffStart # OscliBuffSize * OscliNoBuffs -OscliCircBuffLimit # 0 - - [ GSWorkspaceInKernelBuffers -GSVarWSpace # GSVarWSpace_Size - -SysVarWorkSpace # 40 ; used by the sys$* variables for reading the current time into - ] - -KbuffsEnd # 0 -KbuffsSize * KbuffsEnd - KbuffsBaseAddress ;size of Kernel buffers area - - ASSERT ((KbuffsSize + &FFF) :AND: &FFFFF000) <= KbuffsMaxSize - - ! 0, "Kbuffs at ":CC::STR:(KbuffsBaseAddress) - ! 0, "Kbuffs Size is ":CC::STR:(KbuffsSize) - - [ {FALSE} - ! 0, "GeneralMOSBuffer at ":CC::STR:(GeneralMOSBuffer) - ! 0, "EnvString at ":CC::STR:(EnvString) - ! 0, "AliasExpansionBuffer at ":CC::STR:(AliasExpansionBuffer) - ! 0, "ArgumentBuffer at ":CC::STR:(ArgumentBuffer) - ! 0, "ExprBuff at ":CC::STR:(ExprBuff) - ! 0, "exprSTRACC at ":CC::STR:(exprSTRACC) - ! 0, "RedirectBuff at ":CC::STR:(RedirectBuff) - ! 0, "OscliCircBuffStart at ":CC::STR:(OscliCircBuffStart) - ] - - ] ;LongCommandLines - - - OPT OldOpt - END diff --git a/hdr/KeyWS b/hdr/KeyWS deleted file mode 100644 index 3e9e60b7..00000000 --- a/hdr/KeyWS +++ /dev/null @@ -1,125 +0,0 @@ -; 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. -; -; > $.Hdr.KeyWS - -; *********************************** -; *** C h a n g e L i s t *** -; *********************************** - -; Date Name Description -; ---- ---- ----------- -; 06-Feb-91 TMD Added LastLED -; 09-Mar-92 TMD Added JustGotKbID -; 24-Feb-93 SMC Reorganised for new keyboard/mouse interfaces -; 19-Jul-93 JSR Changed conditional from A1Keyboard to Keyboard_Type = "A1A500" - -; Keyboard variables - - GBLS keyprefix -keyprefix SETS "Key$" - - ^ 0, R11 - -CurrKey # 1 ; current key in two key rollover -OldKey # 1 ; old key in two key rollover -KbId # 1 -LastKbId # 1 -AutoRepeatCount # 1 -Debouncing # 1 ; NZ => do delay next, Z => do repeat -MouseButtons # 1 ; bit0=R, bit1=C, bit2=L -PendingAltType # 1 ; 1 => A, 2 => SA, 3 => CA, 4 => CSA -ModulesOK # 1 ; bit0=1 => modules are initialised - ; bit1=1 => we have offered service -LastLED # 1 ; last request for LED change, so we don't send repeated ones -MouseType # 1 ; current pointer device type -MousePresent # 1 ; mouse detected -MouseReporting # 1 ; mouse is sending reports itself - - - # 3 :AND: (- :INDEX: @) - -InkeyCounter # 4 -MouseX # 4 -MouseY # 4 -SoftKeyPtr # 4 -MouseXMult # 4 -MouseYMult # 4 -KeyVec # 4 - - -MouseBounds # 16 -MouseBoundLCol * MouseBounds+0 -MouseBoundBRow * MouseBounds+4 -MouseBoundRCol * MouseBounds+8 -MouseBoundTRow * MouseBounds+12 - -KeysDown # 20 ; bitmap of all down keys - -SoftKeyName # 3 + :LEN:(keyprefix) ; up to 2 digits + terminator - -SoftKeyExpand # 255 ; current key expansion - - ASSERT (:INDEX: @) < KeyWorkSpaceSize -UserKeyWorkSpaceSize * KeyWorkSpaceSize-(:INDEX: @) -UserKeyWorkSpace # UserKeyWorkSpaceSize - - -; PMF -> VDU communication stuff put in here because both VDU and PMF -; 'GET' this file - -; GBLA ExtEntries -;ExtEntries SETA 0 -; -; MACRO -; AddExtEntry $EntryName -;Index_$EntryName * ExtEntries -;Value_$ExtEntries * $EntryName -;ExtEntries SETA ExtEntries +1 -; MEND -; -; MACRO -;$Table OutputExternals -;$Table -; LCLA count -;count SETA 0 -; WHILE count < ExtEntries -; & Value_$count - $Table -4 -;count SETA count + 1 -; WEND -; MEND - - MACRO - ByteToNosbod $EntryName - VDWS WsPtr - BL $EntryName - MEND - -; AddExtEntry DoReadPOSVPOSI -; AddExtEntry DoReadPOSVPOSO -; AddExtEntry DoOSBYTE87 -; AddExtEntry DoResetFont -; AddExtEntry DoReadFont -; AddExtEntry DoReadVDUStatus -; AddExtEntry DoReadVDUVariable -; AddExtEntry DoReadPalette -; AddExtEntry DoSetPalette -; AddExtEntry DoPointerStuff -; AddExtEntry DoSetScreenStart -; AddExtEntry DoSetDriverBank -; AddExtEntry DoSetDisplayBank -; AddExtEntry DoOsbyte163_242 -; AddExtEntry DoOsWord13 - - END diff --git a/hdr/ModHand b/hdr/ModHand deleted file mode 100644 index ca84761d..00000000 --- a/hdr/ModHand +++ /dev/null @@ -1,110 +0,0 @@ -; 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 Module handler reason codes etc. => &.Hdr.ModHand - -OldOpt SETA {OPT} - OPT OptNoList+OptNoP1List - -; *********************************** -; *** C h a n g e L i s t *** -; *********************************** - -; Date Name Description -; ---- ---- ----------- -; 27-Nov-86 BC Added Module_Ticker -; 15-Jan-87 SKS Added SWI base addresses -; 21-Jan-87 APT New Module_LoadAddr added. -; 26-Jan-87 BC Removed Module_Ticker -; 5-Feb-87 APT Added flag manifests -; 9-Feb-87 APT Added more reason codes -; 17-Feb-87 BC Added Module name server entries -; 25-Feb-87 APT Help-is-code flag added -; 2-Apr-87 APT ExtendBlock reason code added -; 23-Apr-87 APT Help-is-code flag moved into high byte -; 17-Jun-87 APT NewIncarnation, AddPoduleModule reason codes -; 24-Jun-87 APT RenameIncarnation r.c. -; 15-Jul-87 APT MakePreferred -; 29-Jul-87 APT LookupName -; 17-Aug-87 APT EnumerateROM_Modules -; 23-Jan-91 TMD EnumerateROM_ModulesWithInfo -; 07-May-99 KJB FindEndOfROM_ModuleChain - -ModHandReason_Run * 0 -ModHandReason_Load * 1 -ModHandReason_Enter * 2 -ModHandReason_ReInit * 3 -ModHandReason_Delete * 4 -ModHandReason_RMADesc * 5 -ModHandReason_Claim * 6 -ModHandReason_Free * 7 -ModHandReason_Tidy * 8 -ModHandReason_Clear * 9 -ModHandReason_AddArea * 10 -ModHandReason_CopyArea * 11 -ModHandReason_GetNames * 12 -ModHandReason_ExtendBlock * 13 -ModHandReason_NewIncarnation * 14 -ModHandReason_RenameIncarnation * 15 -ModHandReason_MakePreferred * 16 -ModHandReason_AddPoduleModule * 17 -ModHandReason_LookupName * 18 -ModHandReason_EnumerateROM_Modules * 19 -ModHandReason_EnumerateROM_ModulesWithInfo * 20 -ModHandReason_FindEndOfROM_ModuleChain * 21 - -; Real module offsets - - ^ 0 -Module_Start # 4 -Module_Init # 4 -Module_Die # 4 -Module_Service # 4 -Module_Title # 4 -Module_HelpStr # 4 -Module_HC_Table # 4 ; help and command table. - -; optional SWI handler offsets -Module_SWIChunk # 4 -Module_SWIEntry # 4 -Module_NameTable # 4 -Module_NameCode # 4 - -; optional Message filename offset -Module_MsgFile # 4 - -; optional flags table offset -Module_FlagTable # 4 - -; flags for the first word of the flags table -ModuleFlag_32bit * 1 :SHL: 0 - -; Magic number for RM load addr - -Module_LoadAddr * &FFFFFA00 ; magic number from Stu/Bruce standard : - ; the two zeroes are ignored. - ; &FFFFFE00 on Proto-Arfur < .032 - -Module_SWIChunkSize * 2_1000000 - -; flags for the information word : - -FS_Command_Flag * 1 :SHL: 31 -Status_Keyword_Flag * 1 :SHL: 30 -Help_Is_Code_Flag * 1 :SHL: 29 -International_Help * 1 :SHL: 28 - - OPT OldOpt - - END diff --git a/hdr/OSEntries b/hdr/OSEntries deleted file mode 100644 index d05fd5d2..00000000 --- a/hdr/OSEntries +++ /dev/null @@ -1,44 +0,0 @@ -; Copyright 2000 Pace Micro Technology plc -; -; 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. -; -; Entries to the OS from the HAL - - ^ 0 -OS_InitARM # 1 -OS_AddRAM # 1 -OS_Start # 1 -OS_MapInIO # 1 -OS_AddDevice # 1 -OS_LogToPhys # 1 - -HighestOSEntry * :INDEX: @ - 1 - -; The layout of the OS header - ^ 0 -OSHdr_Magic # 4 -OSHdr_Flags # 4 -OSHdr_ImageSize # 4 -OSHdr_Entries # 4 -OSHdr_NumEntries # 4 -OSHdr_size # 0 - -; Parameters/flag for various calls - -OSStartFlag_POR * 1:SHL:0 ; Power-On Reset -OSStartFlag_NoCMOSReset * 1:SHL:1 ; CMOS reset inhibited (protection link etc) -OSStartFlag_CMOSReset * 1:SHL:2 ; CMOS reset (if POR and not inhibited) -OSStartFlag_NoCMOS * 1:SHL:3 ; There's no real NVRAM, only cache -OSStartFlag_RAMCleared * 1:SHL:4 ; RAM has been cleared to zero - - END diff --git a/hdr/Old/Arthur/PublicWS b/hdr/Old/Arthur/PublicWS deleted file mode 100644 index c2aa021e..00000000 --- a/hdr/Old/Arthur/PublicWS +++ /dev/null @@ -1,90 +0,0 @@ -; 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 > Public Work Space - -OldOpt SETA {OPT} - OPT OptNoList+OptNoP1List - -; *********************************** -; *** C h a n g e L i s t *** -; *********************************** - -; Date Name Description -; ---- ---- ----------- -; 15-Jun-94 AMcC Created - holds values 'exported' from Kernel WorkSpace -; Corresponds to Values set in Space200 -; - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; Memory map values: - - ^ &00000104 -ESC_Status # 1 - - ^ &00000105 -LatchBSoftCopy # 1 - - ^ &00000107 -CannotReset # 1 - - ^ &00000108 -IRQsema # 4 - - ^ &00000114 -MEMC_CR_SoftCopy # 4 - - ^ &00000480 -FgEcfOraEor # 4*16 ; Interleaved zgora & zgeor (from Vdu Driver Workspace) - - ^ &000004C0 -BgEcfOraEor # 4*16 ; Interleaved zgora & zgeor (from Vdu Driver Workspace) - - ^ &00000AD1 ; RedirectInHandle -RedirectInHandle # 1 - - ^ &00000AD2 ; RedirectOutHandle -RedirectOutHandle # 1 - - ^ &00000FF8 -DomainId # 4 ; domain identification - - ^ &00001000 -VduDriverWorkSpace # &3000 - - ^ &00004000 -ScratchSpace # &4000 - - ^ &01C02000 -SVCSTK # 0 - - ^ &01C02000 -SysHeapStart # 0 - - ^ &01F033FC -SvcTable # &400 - - ^ &01F037FC -BranchToSWIExit # 4 ; from SWI despatcher - - ^ &01F04000 -SoundWorkSpace # &2000 - -SoundDMABufferSize * &1000 - - ^ &01F06000 -SoundDMABuffers # SoundDMABufferSize * 2 - - OPT OldOpt - END diff --git a/hdr/Old/Arthur/Space200 b/hdr/Old/Arthur/Space200 deleted file mode 100644 index 8a126a1a..00000000 --- a/hdr/Old/Arthur/Space200 +++ /dev/null @@ -1,1017 +0,0 @@ -; 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 > &.Hdr.NewSpace - -OldOpt SETA {OPT} - OPT OptNoList+OptNoP1List - -; *********************************** -; *** C h a n g e L i s t *** -; *********************************** - -; Date Name Description -; ---- ---- ----------- -; 02-Nov-87 APT Added module SWI hash table -; 03-Nov-87 APT Modo-fied module SWI hash table info, removed BRKLST -; 09-Nov-87 APT Removed ESCCNT and ESFLG -; 12-Nov-87 APT Added IRQsema -; 13-Nov-87 APT Added DefaultIRQ1V codespace -; 16-Nov-87 APT PIRQ chain heads -; 18-Nov-87 APT Reordered EvtHan, EvtHan_ws -; 19-Nov-87 APT Moved IRQsema -; 01-Dec-87 APT Added interruptible heap manager workspace -; 08-Dec-87 TMD Added ECFShift, ECFYOffset -; 14-Dec-87 TMD Added DisplayNColour, DisplayModeFlags -; 15-Dec-87 TMD Added KeyAlphabet -; 22-Dec-87 NDR Using ScratchSpace -; 13-Jan-88 APT General scratchspace bash, low workspace reordering. -; Removed spurious 32 bytes of osbyte wspace -; 14-Jan-88 APT *type buffer in scratchspace. -; MOShasFIQ byte added -; 20-Jan-88 APT Workspace juggling for speed & space; also discarded -; Level0 stuff. -; 28-Jan-88 APT MetroGnome moved to "public" location for ADFS -; 02-Feb-88 APT FIQclaim_interlock added -; 05-Feb-88 APT CallBack_Vector -; 09-Feb-88 APT RAM for SWI despatch -; 17-Feb-88 TMD Added VduSaveArea, VduSaveAreaPtr, DisplayModeNo -; 26-Feb-88 APT NoOfCamEntries manifest -; 03-Mar-88 APT Shrank SVC despatch -; 03-Mar-88 APT NoOfCamEntries manifest doubled -; 07-Mar-88 TMD Added DisplayScreenStart, VduOutputCurrentState, -; SpriteMaskSelect, reordered mode variables -; 07-Mar-88 APT Made CamEntries always at &164 -; 07-Mar-88 TMD Added GCharSizes, GCharSizeX, GCharSizeY -; 08-Mar-88 TMD Added GCharSpacing, GCharSpaceX, GCharSpaceY -; 08-Mar-88 TMD Moved GCharSizes..GCharSpaceY into first 1K of workspace -; 15-Mar-88 TMD Added HLineAddr -; 18-Mar-88 TMD Added DisplayXWindLimit, DisplayYWindLimit, -; DisplayXEigFactor, DisplayYEigFactor, PointerXEigFactor -; 18-Mar-88 APT Setting variables scratchspace use revised. -; 21-Mar-88 TMD Removed CursorIndex -; 22-Mar-88 TMD Added TCharSizeX,TCharSizeY,TCharSpaceX,TCharSpaceY -; 29-Mar-88 TMD Added GcolOraEorAddr -; 31-Mar-88 TMD Removed WsFontPtr -; 07-Apr-88 SKS Added HeapSort use of ScratchSpace -; 14-Apr-88 TMD Added SerialFlags -; 28-Apr-88 TMD Added XONXOFFChar -; 5-May-88 APT Added MemorySpeed -; 18-May-88 APT Added CannotReset sema at &107, removed pre-1.20 changes. -; 24-May-88 TMD Added ClipBoxEnable, ClipBoxLCol..ClipBoxTRow, moved in -; ScrLoaSpriteCB, ScrLoaBuffer, SrcSavCommon -; 24-May-88 TMD Flood fill uses ScratchSpace -; 01-Jun-88 TMD Added AlignSpace for ClipBoxCoords -; 03-Jun-88 BCSKS Make Keyboard buffer into a useful part of the system -; Also PrinterBufferSize -; 09-Jun-88 DJS Draw uses ScratchSpace -; 09-Jun-88 BC Gave Econet some private debungling space -; 11-Jun-88 SKS Align IRQ stack to make STMFD not cross two MEMC bdy's -; Made info condit'l on AsmArf; someone had commented it out! -; 15-Jun-88 SKS Added two more instructions in SWIDespatch area -; Moved SLVK definition into kernel; it's not public -; 16-Jun-88 SKS Added 3 more instructions in SWIDespatch area + nailed -; SvcTable address for compatibility -; 22-Jun-88 SKS Moved MEMC_CR_SoftCopy into pubic ws -; 19-Jul-88 APT Added UpCall handler stuff -; 20-Jul-88 SKS Added above entry -; Amended comment about overlaid workspace in vdu -; 15-Aug-88 SKS Inserted DomainId at FF8 (set by Wimp on task swap, used by -; FileSwitch to tag resources) - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; Memory map: - -CursorChunkAddress * 31*1024*1024 -FontCacheAddress * 30*1024*1024 -SysHeapChunkAddress * 28*1024*1024 -RMAAddress * 24*1024*1024 -SpriteSpaceAddress * 20*1024*1024 -RAMDiscAddress * 16*1024*1024 - -; **********+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; system variables - - ^ 0,R12 - -OSBYTEFirstVar # 0 - -ByteVars # 0 ; The main osbyte variables, accessed - ; via calls &A6 to &FF - -VarStart # 2 ; &A6,&A7 -ROMPtr # 2 ; &A8,&A9 -ROMInfo # 2 ; &AA,&AB -KBTran # 2 ; &AC,&AD -VDUvars # 2 ; &AE,&AF - -CFStime # 1 ; &B0 -InputStream # 1 ; &B1 -KeyBdSema # 1 ; &B2 - -ROMPollSema # 1 ; &B3 -OSHWM # 1 ; &B4 - -RS423mode # 1 ; &B5 -NoIgnore # 1 ; &B6 -CFSRFS # 1 ; &B7 -VULAcopy # 2 ; &B8,&B9 - -ROMatBRK # 1 ; &BA -BASICROM # 1 ; &BB - -ADCchanel # 1 ; &BC -ADCmaxchn # 1 ; &BD -ADCconv # 1 ; &BE - -RS423use # 1 ; &BF -RS423conflag # 1 ; &C0 - -FlashCount # 1 ; &C1 -SpacPeriod # 1 ; &C2 -MarkPeriod # 1 ; &C3 - -KeyRepDelay # 1 ; &C4 -KeyRepRate # 1 ; &C5 - -ExecFileH # 1 ; &C6 -SpoolFileH # 1 ; &C7 - -ESCBREAK # 1 ; &C8 (200) - -KeyBdDisable # 1 ; &C9 -KeyBdStatus # 1 ; &CA - -RS423HandShake # 1 ; &CB -RS423InputSupr # 1 ; &CC -RS423CFSFlag # 1 ; &CD - -EconetOScall # 1 ; &CE -EconetOSrdch # 1 ; &CF -EconetOSwrch # 1 ; &D0 - -SpeechSupr # 1 ; &D1 -SoundSupr # 1 ; &D2 - -BELLchannel # 1 ; &D3 -BELLinfo # 1 ; &D4 -BELLfreq # 1 ; &D5 -BELLdur # 1 ; &D6 - -StartMessSupr # 1 ; &D7 - -SoftKeyLen # 1 ; &D8 - -PageModeLineCount # 1 ; &D9 - -VDUqueueItems # 1 ; &DA - -TABch # 1 ; &DB -ESCch # 1 ; &DC - -IPbufferCh # 4 ; &DD,&DE,&DF,&E0 -RedKeyCh # 4 ; &E1,&E2,&E3,&E4 - -ESCaction # 1 ; &E5 -ESCeffect # 1 ; &E6 - -u6522IRQ # 1 ; &E7 -s6850IRQ # 1 ; &E8 -s6522IRQ # 1 ; &E9 - -TubeFlag # 1 ; &EA - -SpeechFlag # 1 ; &EB - -WrchDest # 1 ; &EC -CurEdit # 1 ; &ED - -SoftResetVars # 0 ; Reset to here on soft reset - -KeyBase # 1 ; &EE -Shadow # 1 ; &EF -Country # 1 ; &F0 - -UserFlag # 1 ; &F1 - -SerULAreg # 1 ; &F2 - -TimerState # 1 ; &F3 - -SoftKeyConsist # 1 ; &F4 - -PrinterDrivType # 1 ; &F5 -PrinterIgnore # 1 ; &F6 - -HardResetVars # 0 ; Reset to here on hard reset - -BREAKvector # 3 ; &F7,&F8,&F9 - -MemDriver # 1 ; &FA - where the VDU drivers write to -MemDisplay # 1 ; &FB - where we display from - -LangROM # 1 ; &FC - -LastBREAK # 1 ; &FD - -KeyOpt # 1 ; &FE - -StartOptions # 1 ; &FF - -PowerOnResetVars # 0 ; Reset to here on power-on reset - - AlignSpace - -EventSemaphores # 32 ; One byte for each of 32 events - -TimerAlpha # 8 ; As used by time (bottom 5 bytes) -TimerBeta # 8 ; ................................ -; both aligned to word boundaries - -RealTime # 8 ; 5-byte fast real-time - -PrinterActive # 4 ; Handle/active flag for printer (word aligned) - -IntervalTimer # 5 ; Up Counter synchronous with TIME. -; Event generated when Zero is reached -; bottom byte aligned to word boundary - -SecondsTime # 1 ; the soft copy (centi-)seconds of the RTC -CentiTime # 1 ; """""""""""""""""""""""""""""""""""""""" - -FlashState # 1 ; which flash colours are we using - -SecondsDirty # 1 ; the dirty flag for start up! - -MinTick # 1 ; the minutes odd/even state - -DCDDSRCopy # 1 ; copy of ACIA bits to check for change - -TVVertical # 1 ; *TV first parameter - -TVInterlace # 1 ; *TV second parameter - -CentiCounter # 1 ; Counter for VDU CTRL timing - -Alphabet # 1 ; Current alphabet number - -Keyboard # 1 ; Current keyboard number - -KeyAlphabet # 1 ; Alphabet associated with current keyboard - - GBLS PrinterPrefix -PrinterPrefix SETS "PrinterType$" - -PrinterTypeName # 6 + :LEN: (PrinterPrefix) - - AlignSpace - -SerialFlags # 4 ; New serial flags - -XONXOFFChar # 1 ; Character to send before rest (0 if none) - - AlignSpace - -OSBYTEVarSize * @-OSBYTEFirstVar - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -; End of variables' space - - -; *********************************** -; *** Main Vdu Driver Workspace *** -; *********************************** - - ^ 0 - -FgEcf # 4 * 8 ; Foreground Ecf, set by GCOL(a,0-127) -BgEcf # 4 * 8 ; Background Ecf, set by GCOL(a,128-255) -GPLFMD # 4 ; Foreground action, set by GCOL(a,0-127) -GPLBMD # 4 ; Background action, set by GCOL(a,128-255) -GFCOL # 4 ; Foreground colour, set by GCOL(a,0-127) -GBCOL # 4 ; Background colour, set by GCOL(a,128-255) - -GWLCol # 4 ; Graphics window left column -- -GWBRow # 4 ; Graphics window bottom row | -GWRCol # 4 ; Graphics window right column | -GWTRow # 4 ; Graphics window top row -- - -qqqPad # 3 -QQ # 17 ;Queue - QQ+1 is on a word boundary -QOffset # 4 ;Value to add to VDUqueueItems to point to next queue posn. -JVec # 4 ;Jump vector to internal routines - -; Start of MODE table workspace - -ScreenSize # 4 ; number of bytes needed for this mode (assumed 1st in list) - -XWindLimit # 4 ; Maximum value of GWRCol (internal representation) - -; LineLength must be immediately after YWindLimit - -YWindLimit # 4 ; Maximum value of GWTRow (internal representation) - -LineLength # 4 ; Length of one pixel row in bytes - -; End of word mode variables - -YShftFactor # 4 ; Number of places to shift YCoord in address generation after - ; multiplying by 5, holds - ; 7,6,5 or 4 for 8,4,2 or 1 bits per pixel (640x256 mode) or - ; 6,5,4 or 3 for 8,4,2 or 1 bits per pixel (320x256 mode). - -ModeFlags # 4 ; Bit 0 => non-graphic, Bit 1 => teletext, Bit 2 => gap mode - -XEigFactor # 4 ; Number of places to shift XCoord in external to internal - ; coordinate conversion, holds - ; 1 for 640x256 mode - ; 2 for 320x256 mode - ; 3 for 160x256 (BBC micro mode 2) - -YEigFactor # 4 ; number of shifts to convert between internal/external Y - -NColour # 4 ; Number of colours minus 1 - -Log2BPC # 4 ; Log to base 2 of BytesPerChar ie (0,1,2,3,4) - -Log2BPP # 4 ; Log to base 2 of BitsPerPix ie (0,1,2,3) - -ECFIndex # 4 ; Index into default ECF tables - -ScrRCol # 4 ; Maximum column number in this screen mode -ScrBRow # 4 ; Maximum row number in this screen mode - -PalIndex # 4 ; Index into palette tables (0,1,2,3) - -; End of table-initialised workspace - -; Next 3 must be together in this order ! - -XShftFactor # 4 ; Number of places to shift XCoord in address generation, - ; holds 2,3,4 or 5 for 8,4,2,1 bits per pixel respectivly -GColAdr # 4 ; Address of Ecf to plot - either FgEcf or BgEcf - -ScreenStart # 4 ; Start address of screen (for VDU drivers) - -NPix # 4 ; Number of pixels per word minus 1, holds - ; holds 3,7,15 or 31 for 8,4,2,1 bits per pixel modes - -AspectRatio # 4 ; Pixel shape : 0 square, 1 horz rect, 2 vert rect - -BitsPerPix # 4 ; Bits per pixel (1,2,4,8) - -BytesPerChar # 4 ; Bytes per one line of character - ; (same as BitsPerPix except in double pixel modes) - -CursorFudgeFactor # 4 ; Factor for horizontal cursor positioning - -RowMult # 4 ; Row multiplier for text manipulation - -RowLength # 4 ; Bytes per text row in this mode (eg 640,1280,5120) - -; The following (up to and including NewPtY) must be together in this order -; (relied upon by DefaultWindows) - -TWLCol # 4 ; Text window left column -- -TWBRow # 4 ; Text window bottom row | -TWRCol # 4 ; Text window right column | -TWTRow # 4 ; Text window top row -- - -OrgX # 4 ; Screen origin (external representation) -OrgY # 4 - -GCsX # 4 ; Graphics cursor (external representation) -GCsY # 4 - -OlderCsX # 4 ; Very old X coordinate (internal) -OlderCsY # 4 ; Very old Y coordinate (internal) - -OldCsX # 4 ; Old graphics cursor (internal representation) -- -OldCsY # 4 ; | - ; | -GCsIX # 4 ; Graphics cursor (internal representation) | -GCsIY # 4 ; | - ; | -NewPtX # 4 ; Newest point (internal representation) | -NewPtY # 4 ; -- - -; End of together block - -TForeCol # 4 ; Text foreground colour -TBackCol # 4 ; Text background colour - -CursorX # 4 ; Text cursor X position ; these 3 must be in same order as ... -CursorY # 4 ; Text cursor Y position -CursorAddr # 4 ; Screen address of (output) cursor - -InputCursorX # 4 ; Input cursor X position ; ... these 3 -InputCursorY # 4 ; Input cursor Y position -InputCursorAddr # 4 ; Screen address of input cursor - -EORtoggle # 4 ; Toggle between gap and non-gap -RowsToDo # 4 ; in the CLS - -VduStatus # 4 ; Vdu2, Window, Shadow bits (others in CursorFlags) - -CBWS # 8 ; Clear block (VDU 23,8..) workspace -CBStart # 2 -CBEnd # 2 - -CursorDesiredState # 4 -CursorStartOffset # 4 -CursorEndOffset # 4 -CursorCounter # 4 -CursorSpeed # 4 -Reg10Copy # 4 - -CursorFill # 4 ; Word to EOR cursor ; MUST be immediately before CursorNbit - -CursorNbit # 4 ; Pointer to cursor code for current mode - -DisplayStart # 4 ; Start address of screen (for display) -DriverBankAddr # 4 ; Default start address for VDU drivers -DisplayBankAddr # 4 ; Default start address for display -DisplayNColour # 4 ; No. of colours -1 for displayed mode -DisplayModeFlags # 4 ; ModeFlags for displayed mode -DisplayModeNo # 4 ; ModeNo for displayed mode -DisplayScreenStart # 4 ; Where VDU outputs to when outputting to screen - -DisplayXWindLimit # 4 ; Used for pointer programming -DisplayYWindLimit # 4 -DisplayXEigFactor # 4 -DisplayYEigFactor # 4 -PointerXEigFactor # 4 - -Ecf1 # 8 ; The Ecf patterns -Ecf2 # 8 -Ecf3 # 8 -Ecf4 # 8 - -DotLineStyle # 8 ; Dot dash line pattern - -ModeNo # 4 ; Current mode number - -TFTint # 4 ; Text foreground tint (in bits 6,7) -TBTint # 4 ; Text background tint -GFTint # 4 ; Graphics foreground tint -GBTint # 4 ; Graphics background tint - -TotalScreenSize # 4 ; Amount configured for screen (in bytes) - -MaxMode # 4 ; Maximum mode number allowed (20 for now) - -VinitCopy # 4 ; Copy of Vinit for VDU 23;12 or 13 - -CursorFlags # 4 ; Silly Master cursor movement flags - -CursorStack # 4 ; Bit stack of nested cursor states (0 => on, 1 => off) - ; (bit 31 = TOS) - -ECFShift # 4 ; number of bits to rotate right ECF OR and EOR masks by -ECFYOffset # 4 ; vertical offset to ECF index - -WsVdu5 # 0 ; Vdu 5 workspace -WsScr # 4 -WsEcfPtr # 4 -; WsFontPtr # 4 ; not needed any more, kept in register -EndVerti # 4 -StartMask # 4 -EndMask # 4 -FontOffset # 4 -TempPlain # 16 ; only used for MODE 10 - -GraphicWs # 300 ; All graphics workspace is overlaid here -EndGraphicWs # 0 - - [ AssemblingArthur - ! 0,"16 ":CC::STR:@ - ] - AlignSpace 16 - -GCharSizes # 0 -GCharSizeX # 4 ; width of VDU 5 chars in pixels -GCharSizeY # 4 ; height of VDU 5 chars in pixels - -GCharSpacing # 0 -GCharSpaceX # 4 ; horizontal spacing between VDU 5 chars in pixels -GCharSpaceY # 4 ; vertical ------------------""----------------- - -TCharSizes # 0 -TCharSizeX # 4 ; width of VDU 4 chars in pixels -TCharSizeY # 4 ; height of VDU 4 chars in pixels - -TCharSpacing # 0 -TCharSpaceX # 4 ; horizontal spacing between VDU 4 chars in pixels -TCharSpaceY # 4 ; vertical ------------------""----------------- - -HLineAddr # 4 ; address of exported HLine -GcolOraEorAddr # 4 ; address of FgEcfOraEor etc - -FirPalSetting # 4*28 ; First palette settings -SecPalSetting # 4*28 ; Second palette settings - - [ AssemblingArthur - ! 0,"64 ":CC::STR:@ - ] - AlignSpace 64 - -FgEcfOraEor # 4*16 ; Interleaved zgora & zgeor -BgEcfOraEor # 4*16 ; Interleaved zgora & zgeor -BgEcfStore # 4*16 ; Interleaved zgora & zgeor to store background - -;Current state of pattern -LineDotCnt # 4 ; Count down to restarting pattern -LineDotPatLSW # 4 ; Current state of pattern LSWord -LineDotPatMSW # 4 ; " " " " MSWord - -DotLineLength # 4 ; Dot Pattern repeat length as given in *FX163,242,n - -BBCcompatibleECFs # 4 ; 0 => BBC compatible, 1 => native - -SpAreaStart # 4 ; Start of sprite area -SpChooseName # 16 ; No comment says Richard -SpChoosePtr # 4 - -PointerHeights # 4 ; 4 x 1 byte -PointerActiveXs # 4 ; 4 x 1 byte -PointerActiveYs # 4 ; 4 x 1 byte -PointerShapeNumber # 4 ; only bottom byte used -PointerX # 4 ; co-ordinates of pointer (not always = mouse) -PointerY # 4 - -VIDCControlCopy # 4 ; Soft copy of VIDC control register -VertAdjust # 4 ; offset to add to vertical VIDC registers - -TeletextOffset # 4 ; Offset to current teletext flash bank - -TeletextCount # 4 ; Number of vsyncs till next teletext flash - -WrchNbit # 4 ; Pointer to char code for current mode - -BeepBlock # 8 ; OSWORD block for VDU 7 - -ScreenMemoryClaimed # 1 ; NZ => memory has been claimed or is unusable - - [ AssemblingArthur - ! 0,"16 ":CC::STR:@ - ] - AlignSpace 16 ; Align workspace to 16 bytes - -TTXDoubleCounts # 25 ; Number of double height chars on each line - - [ AssemblingArthur - ! 0,"16 ":CC::STR:@ - ] - AlignSpace 16 ; Align workspace to 16 bytes - -RAMMaskTb # 32*4 ; Copy of MaskTb for this mode (up to 32 words) - - [ AssemblingArthur - ! 0,"16 ":CC::STR:@ - ] - AlignSpace 16 ; Align workspace to 16 bytes - -VduOutputCurrentState # 0 ; values of R0-R3 to return from SwitchOutputToSprite - ; or Mask; next 4 must be in this order -SpriteMaskSelect # 4 ; value of R0 to be given to SWI OS_SpriteOp to set up - ; current state -VduSpriteArea # 4 ; Pointer to sprite area containing VDU output sprite - ; (0 if output is to screen) -VduSprite # 4 ; Pointer to VDU output sprite (0 if output to screen) - -VduSaveAreaPtr # 4 ; Pointer to save area for VDU variables - - - [ AssemblingArthur - ! 0,"16,12 ":CC::STR:@ - ] - AlignSpace 16, 12 ; Make ClipBoxCoords a valid immediate, - ; with ClipBoxEnable immediately before it -ClipBoxInfo # 0 -ClipBoxEnable # 4 ; 0 => clip box disabled, 1 => enabled - -ClipBoxCoords # 0 ; Internal coords of modified area of screen -ClipBoxLCol # 4 -ClipBoxBRow # 4 -ClipBoxRCol # 4 -ClipBoxTRow # 4 - - [ AssemblingArthur - ! 0,"16 ":CC::STR:@ - ] - AlignSpace 16 ; Align workspace to 16 bytes - -TextExpand # 4*1024 ; Tim's massive text expansion table for whizzy WRCH -; TextPlain is now always hard against the end of TextExpand for this mode - -TTXSoftFonts * TextExpand + 2*1024 ; Soft fonts in teletext mode - - [ AssemblingArthur - ! 0,"64 ":CC::STR:@ - ] - AlignSpace 64 ; Align workspace to 64 bytes - -; Teletext map and copy/move buffer are overlaid - -TTXMapSize * 41*25*4 ; (&1004 bytes) -LargeCommon # TTXMapSize ; the largest area -TTXMap * LargeCommon - -ScrLoaSpriteCB * LargeCommon ; (size = SpriteCBsize + MaxSpritePaletteSize) -ScrLoaBuffer * LargeCommon ; (size = one pixel row) -ScrSavCommon * LargeCommon ; (size = SpriteAreaCBsize + SpriteCBsize - ; + MaxSpritePaletteSize) - -FldQueueSize * ScratchSpaceSize -FldQueueStart * ScratchSpace - - [ AssemblingArthur - ! 0,"64 ":CC::STR:@ - ] - AlignSpace 64 ; Align workspace to 64 bytes - -Font # &700 ; 7 pages of (soft) font - -SaveAreaSize * 12*1024-@ - -VduSaveArea # SaveAreaSize ; save area for switching output to sprites - -VDWSSize # 0 - - ASSERT VDWSSize <= 12 * 1024 - -; ***************************************************************************** -; Space in the first 32K is allocated below -; ***************************************************************************** -; Real workspace definition - -; Basic kernel space - defined locations for external modules - - ^ &100 -IRQ1V # 4 ; &100 - -ESC_Status # 1 ; &104 -LatchBSoftCopy # 1 ; &105 -IOCControlSoftCopy # 1 ; &106 -CannotReset # 1 ; &107 - -IRQsema # 4 ; &108 -MetroGnome # 4 ; &10C -MemorySpeed # 4 ; &110 - -MEMC_CR_SoftCopy # 4 ; &114 - - -; Now all internal definitions - -; Up to here is initialized on reset - -; Next come handler variables - -MemLimit # 4 -UndHan # 4 -PAbHan # 4 -DAbHan # 4 -AdXHan # 4 - -ErrHan # 4 -ErrBuf # 4 -ErrHan_ws # 4 - -CallAd_ws # 4 ; smart Rs ordering: -CallAd # 4 ; can do LDMIA of r12, pc -CallBf # 4 - -BrkAd_ws # 4 -BrkAd # 4 -BrkBf # 4 - -EscHan_ws # 4 -EscHan # 4 - -EvtHan_ws # 4 -EvtHan # 4 - -RAMLIMIT # 4 - -NoOfCamEntries * 255 ; we have entries 0-n.o.c.e. -CamEntries # 4 * (NoOfCamEntries+1) ; keep CAM entries + PPL in here - ASSERT CamEntries = &164 ; Fixed for PCEmulator - -AplWorkSize # 4 - -HiServ_ws # 4 -HiServ # 4 -SExitA # 4 -SExitA_ws # 4 -UpCallHan_ws # 4 -UpCallHan # 4 - - -; now a section that it's handy to have in simply loadable places - - [ AssemblingArthur - ! 0,"16 ":CC::STR:@ - ] - AlignSpace 16 - -KeyWorkSpaceSize * &200 -KeyWorkSpace # KeyWorkSpaceSize - -; general MOS buffer: re-use with caution! - -GeneralMOSBuffer # 256 - -ModuleSHT_Entries * 16 -ModuleSWI_HashTab # 4*ModuleSHT_Entries - -Module_List # 4 -Curr_Active_Object # 4 - -; Vector Claim & Release tables etc - -VecPtrTab # NVECTORS * 4 - -ExceptionDump # 4 - - - [ AssemblingArthur - ! 0,"16 ":CC::STR:@ - ] - AlignSpace 16 ; Ensures we can MOV rn, #OsbyteVars if <=&1000 - -OsbyteVars # OSBYTEVarSize - ASSERT OsbyteVars < &10000 ; Must keep in first 64K so address can be read by - ; (and stored in) OS_Bytes &A6,&A7. SKS - -; These must be in first 4K -NBuffers * 10 -BuffInPtrs # 4 * NBuffers -BuffOutPtrs # 4 * NBuffers - -VariableList # 4 - -; Oscli stuff -OscliCBtopUID # 4 -OscliCBbotUID # 4 -OscliCBcurrend # 4 - -ReturnCode # 4 -RCLimit # 4 - -SpriteSize # 4 ; saved on startup for Sprite code and RAMFS -RAMDiscSize # 4 -FontCacheSize # 4 ; and font manager - -TickNodeChain # 4 - -; Workspace - -EnvTime # 5 -RedirectInHandle # 1 -RedirectOutHandle # 1 -MOShasFIQ # 1 -FIQclaim_interlock # 1 -CallBack_Flag # 1 -IRQ_CallBack_Flag * CallBack_Flag - - AlignSpace - -EnvString # 256 - - -DUMPER # 16 * 4 - -; more system workspace -Page_Size # 4 -PIRQ_Chain # 4 -PFIQasIRQ_Chain # 4 - -; IRQ despatch -DefIRQ1Vspace * 9*4+12*17+2*256 ; for size checking in MOS -DefaultIRQ1V # DefIRQ1Vspace ; assembly - - -CallBack_Vector # 4 - -; interruptible heap manager workspace - -HeapSavedReg_R0 # 4 -HeapSavedReg_R1 # 4 -HeapSavedReg_R2 # 4 -HeapSavedReg_R3 # 4 -HeapSavedReg_R4 # 4 -HeapSavedReg_R13 # 4 -HeapReturnedReg_R0 # 4 -HeapReturnedReg_R1 # 4 -HeapReturnedReg_R2 # 4 -HeapReturnedReg_R3 # 4 -HeapReturnedReg_R4 # 4 -HeapReturnedReg_R13 # 4 -HeapReturnedReg_PC # 4 ; also acts as interlock - - [ AssemblingArthur - ! 0, "low space free ":CC::STR:(&FF4-@) - ] - ASSERT @ < &FF4 - -; Words for old tools of assorted varieties - ^ &FF4 -FPEAnchor # 4 -DomainId # 4 ; SKS added for domain identification -Modula2_Private # 4 ; MICK has FFC and uses it it in USR mode - -VduDriverWorkSpace # VDWSSize - ASSERT (VduDriverWorkSpace :AND: 63) = 0 ; For Tim (VDU5) - - - [ AssemblingArthur - ! 0, "high space free ":CC::STR:(&4000-@) - ] - - ^ &4000 -ScratchSpaceSize * &4000 -ScratchSpace # ScratchSpaceSize - - ASSERT @ <= &8000 ; Start of apl - -; ***************************************************************************** -; Users of ScratchSpace declare yourself here: - -; NRaine: Filling a polygon uses ScratchSpace to flatten the path - -; DSeal: Draw module uses ScratchSpace on fill operations (this supercedes -; NRaine's declaration above). - -; SKS: HeapSort with (r1 & 0x80000000) & ~(r1 & 0x20000000) & (r5 <= 16K) -; uses ScratchSpace as a temp slot for data shuffling after sorting - -; TMD: Flood fill uses ScratchSpace for the flood queue. - -; Tidying the RMA uses ScratchSpace while all modules are dead - -; GSTRANS workspace: GSINIT puts state into the workspacem and GSREAD uses it. -; DO NOT do any operations between GSINIT/GSREAD SWIS. -; SWIs called: OSWord in time var code -; BinaryToDecimal, ReadUnsigned - -GSVarWSpace * ScratchSpace - - ^ 0 -GSNameBuff # &100 -GS_Stack # &200 -GS_StackPtr_Lim * &200 / 4 ; Number of words in stack. -GS_StackPtr # 4 - - ^ @ + ScratchSpace - -; Pointers for SubstituteArgs: no external calls. -; Ensure these don't overlap FileSwitch's buffers below! - -MacExStartPtrs # 44 -MacExEndPtrs # 44 - -; OS_CLI has a buffer for alias expansion: ReadVarVal and SubstituteArgs -; are called while the buffer is held. Also used for module prefixes: -; Module called twice in this case. - -AliasExpansionBuffer # 100 - -; *list/*type need an argument expansion buffer: ReadArgs called with it. - -ArgumentBuffer * AliasExpansionBuffer - -; EvaluateExpression space. Calls ReadUnsigned, BinaryToDecimal and ReadVarVal. - -ExprWSpace * @ - - ^ 0, R12 -ExprBuff # &100 -exprBracDif # 2 ; keep exprSTRACC aligned -tos_op # 2 ; 1 byte for use as STRACC-1 -ExprSVCstack # 4 -exprSTRACC * @ - ExprBuff + ExprWSpace - -ExprStackLimit * exprSTRACC + &100 -ExprStackStart * ScratchSpace + ScratchSpaceSize - - -; Tutu needs some for argument substitution + expansion for run/load types -; Only OS call during xform is XOS_SubstituteArgs and XOS_Heap(Claim,SysHeap) - - ^ 0 ; Offset from ScratchSpace -rav_substituted # 256 -rav_arglist # 256 - -TopOfPageZero # 0 - - ^ &8000 ; The actual top of Page Zero -EconetDebugSpace |#| &20 * 4 ; Thirty two words (&7F80) - - ASSERT @ > TopOfPageZero ; Make sure we don't clash - -; ***************************************************************************** -; *** Cursor, Sound DMA, SWI, and OSCLI workspace. *** -; *** Sits in the 32K above 31M, ie. &01F000000..&01F07FFF *** -; *** Has the physical address &02078000, ie. 32M + 512K - 32K *** -; ***************************************************************************** - -TopOfDMAPhysRAM * &80000 ; OFFSET in physram -TopOfDMAWorkSpace * CursorChunkAddress + 32*1024 -OffsetLogicalToPhysical * TopOfDMAPhysRAM - TopOfDMAWorkSpace - - ^ TopOfDMAWorkSpace ; Note we will be going down - -; Sound - -SoundWorkSpaceSize * &1000 -SoundDMABufferSize * &1000 -SoundEvtSize * &1000 -SoundDMABuffers |#| SoundDMABufferSize * 2 -SoundWorkSpace |#| SoundWorkSpaceSize + SoundEvtSize - -; Cursor - -CursorDataSize * &800 -CursorData |#| CursorDataSize -CursorSoundRAM * CursorData -CursorSoundPhysRAM * CursorSoundRAM + OffsetLogicalToPhysical - -; SWI despatcher - -BranchToSWIExit |#| 4 -SvcTable |#| &400 - ASSERT SvcTable = &01F033FC ; Required for SVC table pokers, 1.20 compatible -SWIDespatch_Size * 29*4 -SWIDespatch |#| SWIDespatch_Size - - -; Buffers - -KeyBuffSize * &100 -RS423InBuffSize * &100 -RS423OutBuffSize * &C0 -PrintBuffSize * &400 -Sound0BuffSize * 4 -Sound1BuffSize * 4 -Sound2BuffSize * 4 -Sound3BuffSize * 4 -SpeechBuffSize * 4 -MouseBuffSize * &40 -KeyBuff |#| KeyBuffSize -RS423InBuff |#| RS423InBuffSize -RS423OutBuff |#| RS423OutBuffSize -PrintBuff |#| PrintBuffSize -Sound0Buff |#| Sound0BuffSize -Sound1Buff |#| Sound1BuffSize -Sound2Buff |#| Sound2BuffSize -Sound3Buff |#| Sound3BuffSize -SpeechBuff |#| SpeechBuffSize -MouseBuff |#| MouseBuffSize - -; Oscli buffering - -OscliBuffSize * &100 -OscliNoBuffs * 16 -OscliCircBuffLimit |#| 0 -OscliCircBuffStart |#| OscliBuffSize * OscliNoBuffs -RedirectBuff |#| OscliBuffSize - - [ AssemblingArthur - ! 0, "Aligning IRQ stack from ":CC::STR:@ - ] - [ @-7*4 :AND: 15 <> 0 - |#| (@-7*4):AND:15 - ] -IRQSTK # 0 ; Overflow will give abort - [ AssemblingArthur - ! 0, "IRQ stack size ":CC::STR:(IRQSTK-CursorChunkAddress) - ] - - ASSERT @ > ( CursorChunkAddress + &1000 ) ; Check minimum stack - -; ***************************************************************************** -; High system workspace -; ***************************************************************************** - - ^ SysHeapChunkAddress - - # 8*1024 ; svcstk size. Overflow will give abort -SVCSTK # 0 -SysHeapStart # 0 - - - OPT OldOpt - END diff --git a/hdr/Old/NewSpace b/hdr/Old/NewSpace deleted file mode 100644 index 50f32335..00000000 --- a/hdr/Old/NewSpace +++ /dev/null @@ -1,1172 +0,0 @@ -; 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 > &.Hdr.NewSpace - -OldOpt SETA {OPT} - OPT OptNoList+OptNoP1List - -; *********************************** -; *** C h a n g e L i s t *** -; *********************************** - -; Date Name Description -; ---- ---- ----------- -; 02-Nov-87 APT Added module SWI hash table -; 03-Nov-87 APT Modo-fied module SWI hash table info, removed BRKLST -; 09-Nov-87 APT Removed ESCCNT and ESFLG -; 12-Nov-87 APT Added IRQsema -; 13-Nov-87 APT Added DefaultIRQ1V codespace -; 16-Nov-87 APT PIRQ chain heads -; 18-Nov-87 APT Reordered EvtHan, EvtHan_ws -; 19-Nov-87 APT Moved IRQsema -; 01-Dec-87 APT Added interruptible heap manager workspace -; 08-Dec-87 TMD Added ECFShift, ECFYOffset -; 14-Dec-87 TMD Added DisplayNColour, DisplayModeFlags -; 15-Dec-87 TMD Added KeyAlphabet -; 22-Dec-87 NDR Using ScratchSpace -; 13-Jan-88 APT General scratchspace bash, low workspace reordering. -; Removed spurious 32 bytes of osbyte wspace -; 14-Jan-88 APT *type buffer in scratchspace. -; MOShasFIQ byte added -; 20-Jan-88 APT Workspace juggling for speed & space; also discarded -; Level0 stuff. -; 28-Jan-88 APT MetroGnome moved to "public" location for ADFS -; 02-Feb-88 APT FIQclaim_interlock added -; 05-Feb-88 APT CallBack_Vector -; 09-Feb-88 APT RAM for SWI despatch -; 17-Feb-88 TMD Added VduSaveArea, VduSaveAreaPtr, DisplayModeNo -; 26-Feb-88 APT NoOfCamEntries manifest -; 03-Mar-88 APT Shrank SVC despatch -; 03-Mar-88 APT NoOfCamEntries manifest doubled -; 07-Mar-88 TMD Added DisplayScreenStart, VduOutputCurrentState, -; SpriteMaskSelect, reordered mode variables -; 07-Mar-88 APT Made CamEntries always at &164 -; 07-Mar-88 TMD Added GCharSizes, GCharSizeX, GCharSizeY -; 08-Mar-88 TMD Added GCharSpacing, GCharSpaceX, GCharSpaceY -; 08-Mar-88 TMD Moved GCharSizes..GCharSpaceY into first 1K of workspace -; 15-Mar-88 TMD Added HLineAddr -; 18-Mar-88 TMD Added DisplayXWindLimit, DisplayYWindLimit, -; DisplayXEigFactor, DisplayYEigFactor, PointerXEigFactor -; 18-Mar-88 APT Setting variables scratchspace use revised. -; 21-Mar-88 TMD Removed CursorIndex -; 22-Mar-88 TMD Added TCharSizeX,TCharSizeY,TCharSpaceX,TCharSpaceY -; 29-Mar-88 TMD Added GcolOraEorAddr -; 31-Mar-88 TMD Removed WsFontPtr -; 07-Apr-88 SKS Added HeapSort use of ScratchSpace -; 14-Apr-88 TMD Added SerialFlags -; 28-Apr-88 TMD Added XONXOFFChar -; 5-May-88 APT Added MemorySpeed -; 18-May-88 APT Added CannotReset sema at &107, removed pre-1.20 changes. -; 24-May-88 TMD Added ClipBoxEnable, ClipBoxLCol..ClipBoxTRow, moved in -; ScrLoaSpriteCB, ScrLoaBuffer, SrcSavCommon -; 24-May-88 TMD Flood fill uses ScratchSpace -; 01-Jun-88 TMD Added AlignSpace for ClipBoxCoords -; 03-Jun-88 BCSKS Make Keyboard buffer into a useful part of the system -; Also PrinterBufferSize -; 09-Jun-88 DJS Draw uses ScratchSpace -; 09-Jun-88 BC Gave Econet some private debungling space -; 11-Jun-88 SKS Align IRQ stack to make STMFD not cross two MEMC bdy's -; Made info condit'l on AsmArf; someone had commented it out! -; 15-Jun-88 SKS Added two more instructions in SWIDespatch area -; Moved SLVK definition into kernel; it's not public -; 16-Jun-88 SKS Added 3 more instructions in SWIDespatch area + nailed -; SvcTable address for compatibility -; 22-Jun-88 SKS Moved MEMC_CR_SoftCopy into pubic ws -; 19-Jul-88 APT Added UpCall handler stuff -; 20-Jul-88 SKS Added above entry -; Amended comment about overlaid workspace in vdu -; 15-Aug-88 SKS Inserted DomainId at FF8 (set by Wimp on task swap, used by -; FileSwitch to tag resources) -; 27-Sep-89 JSR Added ColourTrans to users of scratch space -; 24-Oct-89 TMD Added CamEntriesForBigMachines, CamEntriesPointer -; 26-Oct-89 TMD Added MaxCamEntry, removed NoOfCamEntries symbol -; 27-Oct-89 TMD Added VIDCClockSpeed -; 09-Nov-89 TMD Added ResetIndirection -; 15-Jan-91 TMD Added ROMModuleChain -; 04-Feb-91 DDV Added DeviceFS as user of ScratchSpace. -; 04-Feb-91 DDV Added ColourTrans use of ScratchSpace to build diff tables. -; 06-Mar-91 TMD Added IOSystemType -; 07-Mar-91 LVR ADFS uses scratch space for floppy formatting -; 07-Mar-91 TMD Added MonitorLeadType -; 08-Mar-91 TMD Added PrinterBufferAddr, PrinterBufferSize -; 11-Apr-91 TMD Added SerialInHandle, SerialOutHandle -; 24-Apr-91 TMD Added UniqueMachineID -; 09-Jun-91 RM Added KernelMessagesBlock,ErrorSemaphore and MOSConvertBuffer -; 26-Jul-91 JSR Extend GeneralMOSBuffer by 4 bytes to make it a valid -; length for the default error handler's error buffer -; 19-Aug-91 JSR Added *If to list of GeneralMOSBuffer users -; 22-Aug-91 TMD Reduced ErrorSemaphore to a byte, added PortableFlag -; 25-Aug-91 DDV Updated to indicate correct usage of scratch space by ColourTrans -; 09-Jan-92 DDV Added FgPattern, BgPattern and indicate use of ScratchSpace by OS_SetColour -; 20-Jan-92 TMD OS_SetColour no longer uses ScratchSpace -; 17-Feb-92 ECN Added CLibWord and RISCOSLibWord -; 02-Apr-92 TMD Added ScreenBlankFlag -; 03-Aug-92 TMD Kept in step with hdr:VickySpace, added PhysRam (from hdr:System) -; 09-Sep-92 TMD Added FirPalAddr, SecPalAddr -; 10-Sep-92 DDV Added pointer to the System heap copy of the Whizzy text expansion buffer -; 07-Oct-92 TMD Brought in line with VickySpace with respect to new VIDC stuff -; 04-Jun-93 TMD Added CurrentMonitorType -; 15-Jul-93 TMD Added KernelModeSelector -; 25-Aug-93 SMC Added processor vector table at ProcVec_Start -; Added ProcVecPreVeneers -; 07-Oct-93 TMD Added ScreenBlankDPMSState, HSWRSoftCopy, VSWRSoftCopy -; -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; Memory map: - -AplWorkMaxSize * &01000000 ; 16M - -RMAAddress * &01800000 -RMAMaxSize * &00400000 ; 4M - -SysHeapChunkAddress * &01C00000 -SysHeapMaxSize * &00200000 ; 2M - -CursorChunkAddress * &01F00000 ; Fixed size 32K - -ScreenEndAdr * &02000000 -ScreenMaxSize * 480*1024 - -FontCacheAddress * &01E00000 -FontCacheMaxSize * &00100000 ; 1M - -SpriteSpaceAddress * &01400000 -SpriteSpaceMaxSize * &00400000 ; 4M - -RAMDiscAddress * &01000000 -RAMDiscMaxSize * &00400000 ; 4M - -PhysRam * &02000000 - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; system variables - - ^ 0,R12 - -OSBYTEFirstVar # 0 - -ByteVars # 0 ; The main osbyte variables, accessed - ; via calls &A6 to &FF - -VarStart # 2 ; &A6,&A7 -ROMPtr # 2 ; &A8,&A9 -ROMInfo # 2 ; &AA,&AB -KBTran # 2 ; &AC,&AD -VDUvars # 2 ; &AE,&AF - -CFStime # 1 ; &B0 -InputStream # 1 ; &B1 -KeyBdSema # 1 ; &B2 - -ROMPollSema # 1 ; &B3 -OSHWM # 1 ; &B4 - -RS423mode # 1 ; &B5 -NoIgnore # 1 ; &B6 -CFSRFS # 1 ; &B7 -VULAcopy # 2 ; &B8,&B9 - -ROMatBRK # 1 ; &BA -BASICROM # 1 ; &BB - -ADCchanel # 1 ; &BC -ADCmaxchn # 1 ; &BD -ADCconv # 1 ; &BE - -RS423use # 1 ; &BF -RS423conflag # 1 ; &C0 - -FlashCount # 1 ; &C1 -SpacPeriod # 1 ; &C2 -MarkPeriod # 1 ; &C3 - -KeyRepDelay # 1 ; &C4 -KeyRepRate # 1 ; &C5 - -ExecFileH # 1 ; &C6 -SpoolFileH # 1 ; &C7 - -ESCBREAK # 1 ; &C8 (200) - -KeyBdDisable # 1 ; &C9 -KeyBdStatus # 1 ; &CA - -RS423HandShake # 1 ; &CB -RS423InputSupr # 1 ; &CC -RS423CFSFlag # 1 ; &CD - -EconetOScall # 1 ; &CE -EconetOSrdch # 1 ; &CF -EconetOSwrch # 1 ; &D0 - -SpeechSupr # 1 ; &D1 -SoundSupr # 1 ; &D2 - -BELLchannel # 1 ; &D3 -BELLinfo # 1 ; &D4 -BELLfreq # 1 ; &D5 -BELLdur # 1 ; &D6 - -StartMessSupr # 1 ; &D7 - -SoftKeyLen # 1 ; &D8 - -PageModeLineCount # 1 ; &D9 - -VDUqueueItems # 1 ; &DA - -TABch # 1 ; &DB -ESCch # 1 ; &DC - -IPbufferCh # 4 ; &DD,&DE,&DF,&E0 -RedKeyCh # 4 ; &E1,&E2,&E3,&E4 - -ESCaction # 1 ; &E5 -ESCeffect # 1 ; &E6 - -u6522IRQ # 1 ; &E7 -s6850IRQ # 1 ; &E8 -s6522IRQ # 1 ; &E9 - -TubeFlag # 1 ; &EA - -SpeechFlag # 1 ; &EB - -WrchDest # 1 ; &EC -CurEdit # 1 ; &ED - -SoftResetVars # 0 ; Reset to here on soft reset - -KeyBase # 1 ; &EE -Shadow # 1 ; &EF -Country # 1 ; &F0 - -UserFlag # 1 ; &F1 - -SerULAreg # 1 ; &F2 - -TimerState # 1 ; &F3 - -SoftKeyConsist # 1 ; &F4 - -PrinterDrivType # 1 ; &F5 -PrinterIgnore # 1 ; &F6 - -HardResetVars # 0 ; Reset to here on hard reset - -BREAKvector # 3 ; &F7,&F8,&F9 - -MemDriver # 1 ; &FA - where the VDU drivers write to -MemDisplay # 1 ; &FB - where we display from - -LangROM # 1 ; &FC - -LastBREAK # 1 ; &FD - -KeyOpt # 1 ; &FE - -StartOptions # 1 ; &FF - -PowerOnResetVars # 0 ; Reset to here on power-on reset - -; These two can dovetail in here to use up 2 bytes before the AlignSpace! - -SerialInHandle # 1 ; Handle for serial input stream (0 if not open currently) -SerialOutHandle # 1 ; Handle for serial output stream (-----------""----------) - - AlignSpace - -EventSemaphores # 32 ; One byte for each of 32 events - -TimerAlpha # 8 ; As used by time (bottom 5 bytes) -TimerBeta # 8 ; ................................ -; both aligned to word boundaries - -RealTime # 8 ; 5-byte fast real-time - -PrinterActive # 4 ; Handle/active flag for printer (word aligned) - -IntervalTimer # 5 ; Up Counter synchronous with TIME. -; Event generated when Zero is reached -; bottom byte aligned to word boundary - -SecondsTime # 1 ; the soft copy (centi-)seconds of the RTC -CentiTime # 1 ; """""""""""""""""""""""""""""""""""""""" - -FlashState # 1 ; which flash colours are we using - -SecondsDirty # 1 ; the dirty flag for start up! - -MinTick # 1 ; the minutes odd/even state - -DCDDSRCopy # 1 ; copy of ACIA bits to check for change - -TVVertical # 1 ; *TV first parameter - -TVInterlace # 1 ; *TV second parameter - -CentiCounter # 1 ; Counter for VDU CTRL timing - -Alphabet # 1 ; Current alphabet number - -Keyboard # 1 ; Current keyboard number - -KeyAlphabet # 1 ; Alphabet associated with current keyboard - - GBLS PrinterPrefix -PrinterPrefix SETS "PrinterType$" - -PrinterTypeName # 6 + :LEN: (PrinterPrefix) - - AlignSpace - -SerialFlags # 4 ; New serial flags - -XONXOFFChar # 1 ; Character to send before rest (0 if none) - - AlignSpace - -OSBYTEVarSize * @-OSBYTEFirstVar - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -; End of variables' space - - -; *********************************** -; *** Main Vdu Driver Workspace *** -; *********************************** - - ^ 0 - -FgEcf # 4 * 8 ; Foreground Ecf, set by GCOL(a,0-127) -BgEcf # 4 * 8 ; Background Ecf, set by GCOL(a,128-255) -GPLFMD # 4 ; Foreground action, set by GCOL(a,0-127) -GPLBMD # 4 ; Background action, set by GCOL(a,128-255) -GFCOL # 4 ; Foreground colour, set by GCOL(a,0-127) -GBCOL # 4 ; Background colour, set by GCOL(a,128-255) - -GWLCol # 4 ; Graphics window left column -- -GWBRow # 4 ; Graphics window bottom row | -GWRCol # 4 ; Graphics window right column | -GWTRow # 4 ; Graphics window top row -- - -qqqPad # 3 -QQ # 17 ;Queue - QQ+1 is on a word boundary -QOffset # 4 ;Value to add to VDUqueueItems to point to next queue posn. -JVec # 4 ;Jump vector to internal routines - -; Start of MODE table workspace - -ScreenSize # 4 ; number of bytes needed for this mode (assumed 1st in list) - -XWindLimit # 4 ; Maximum value of GWRCol (internal representation) - -; LineLength must be immediately after YWindLimit - -YWindLimit # 4 ; Maximum value of GWTRow (internal representation) - -LineLength # 4 ; Length of one pixel row in bytes - -NColour # 4 ; Number of colours minus 1 - -; End of word mode variables - -YShftFactor # 4 ; Number of places to shift YCoord in address generation after - ; multiplying by 5, holds - ; 7,6,5 or 4 for 8,4,2 or 1 bits per pixel (640x256 mode) or - ; 6,5,4 or 3 for 8,4,2 or 1 bits per pixel (320x256 mode). - -ModeFlags # 4 ; Bit 0 => non-graphic, Bit 1 => teletext, Bit 2 => gap mode - -XEigFactor # 4 ; Number of places to shift XCoord in external to internal - ; coordinate conversion, holds - ; 1 for 640x256 mode - ; 2 for 320x256 mode - ; 3 for 160x256 (BBC micro mode 2) - -YEigFactor # 4 ; number of shifts to convert between internal/external Y - -Log2BPC # 4 ; Log to base 2 of BytesPerChar ie (0,1,2,3,4) - -Log2BPP # 4 ; Log to base 2 of BitsPerPix ie (0,1,2,3) - -ECFIndex # 4 ; Index into default ECF tables - -ScrRCol # 4 ; Maximum column number in this screen mode -ScrBRow # 4 ; Maximum row number in this screen mode - -PalIndex # 4 ; Index into palette tables (0,1,2,3) - -; End of table-initialised workspace - -; Next 3 must be together in this order ! - -XShftFactor # 4 ; Number of places to shift XCoord in address generation, - ; holds 2,3,4 or 5 for 8,4,2,1 bits per pixel respectivly -GColAdr # 4 ; Address of Ecf to plot - either FgEcf or BgEcf - -ScreenStart # 4 ; Start address of screen (for VDU drivers) - -NPix # 4 ; Number of pixels per word minus 1, holds - ; holds 3,7,15 or 31 for 8,4,2,1 bits per pixel modes - -AspectRatio # 4 ; Pixel shape : 0 square, 1 horz rect, 2 vert rect - -BitsPerPix # 4 ; Bits per pixel (1,2,4,8) - -BytesPerChar # 4 ; Bytes per one line of character - ; (same as BitsPerPix except in double pixel modes) - -CursorFudgeFactor # 4 ; Factor for horizontal cursor positioning - -RowMult # 4 ; Row multiplier for text manipulation - -RowLength # 4 ; Bytes per text row in this mode (eg 640,1280,5120) - -; The following (up to and including NewPtY) must be together in this order -; (relied upon by DefaultWindows) - -TWLCol # 4 ; Text window left column -- -TWBRow # 4 ; Text window bottom row | -TWRCol # 4 ; Text window right column | -TWTRow # 4 ; Text window top row -- - -OrgX # 4 ; Screen origin (external representation) -OrgY # 4 - -GCsX # 4 ; Graphics cursor (external representation) -GCsY # 4 - -OlderCsX # 4 ; Very old X coordinate (internal) -OlderCsY # 4 ; Very old Y coordinate (internal) - -OldCsX # 4 ; Old graphics cursor (internal representation) -- -OldCsY # 4 ; | - ; | -GCsIX # 4 ; Graphics cursor (internal representation) | -GCsIY # 4 ; | - ; | -NewPtX # 4 ; Newest point (internal representation) | -NewPtY # 4 ; -- - -; End of together block - -TForeCol # 4 ; Text foreground colour -TBackCol # 4 ; Text background colour - -CursorX # 4 ; Text cursor X position ; these 3 must be in same order as ... -CursorY # 4 ; Text cursor Y position -CursorAddr # 4 ; Screen address of (output) cursor - -InputCursorX # 4 ; Input cursor X position ; ... these 3 -InputCursorY # 4 ; Input cursor Y position -InputCursorAddr # 4 ; Screen address of input cursor - -EORtoggle # 4 ; Toggle between gap and non-gap -RowsToDo # 4 ; in the CLS - -VduStatus # 4 ; Vdu2, Window, Shadow bits (others in CursorFlags) - -CBWS # 8 ; Clear block (VDU 23,8..) workspace -CBStart # 2 -CBEnd # 2 - -CursorDesiredState # 4 -CursorStartOffset # 4 -CursorEndOffset # 4 -CursorCounter # 4 -CursorSpeed # 4 -Reg10Copy # 4 - -CursorFill # 4 ; Word to EOR cursor ; MUST be immediately before CursorNbit - -CursorNbit # 4 ; Pointer to cursor code for current mode - -DisplayStart # 4 ; Start address of screen (for display) -DriverBankAddr # 4 ; Default start address for VDU drivers -DisplayBankAddr # 4 ; Default start address for display -DisplayNColour # 4 ; No. of colours -1 for displayed mode -DisplayModeFlags # 4 ; ModeFlags for displayed mode -DisplayModeNo # 4 ; ModeNo for displayed mode -DisplayScreenStart # 4 ; Where VDU outputs to when outputting to screen - -DisplayXWindLimit # 4 ; Used for pointer programming -DisplayYWindLimit # 4 -DisplayXEigFactor # 4 -DisplayYEigFactor # 4 -PointerXEigFactor # 4 - -Ecf1 # 8 ; The Ecf patterns -Ecf2 # 8 -Ecf3 # 8 -Ecf4 # 8 - -DotLineStyle # 8 ; Dot dash line pattern - -ModeNo # 4 ; Current mode number - -TFTint # 4 ; Text foreground tint (in bits 6,7) -TBTint # 4 ; Text background tint -GFTint # 4 ; Graphics foreground tint -GBTint # 4 ; Graphics background tint - -TotalScreenSize # 4 ; Amount configured for screen (in bytes) - -MaxMode # 4 ; Maximum mode number allowed (20 for now) - -VinitCopy # 4 ; Copy of Vinit for VDU 23;12 or 13 - -CursorFlags # 4 ; Silly Master cursor movement flags - -CursorStack # 4 ; Bit stack of nested cursor states (0 => on, 1 => off) - ; (bit 31 = TOS) - -ECFShift # 4 ; number of bits to rotate right ECF OR and EOR masks by -ECFYOffset # 4 ; vertical offset to ECF index - -WsVdu5 # 0 ; Vdu 5 workspace -WsScr # 4 -WsEcfPtr # 4 -; WsFontPtr # 4 ; not needed any more, kept in register -EndVerti # 4 -StartMask # 4 -EndMask # 4 -FontOffset # 4 -TempPlain # 16 ; only used for MODE 10 - -VIDCClockSpeed # 4 ; current VIDC clock speed in kHz - -CurrentMonitorType # 4 ; initialised from configured one - -KernelModeSelector # 4 ; pointer to block in system heap where - ; current mode selector is copied - -GraphicWs # 300 ; All graphics workspace is overlaid here -EndGraphicWs # 0 - - [ AssemblingArthur - ! 0,"16 ":CC::STR:@ - ] - AlignSpace 16 - -GCharSizes # 0 -GCharSizeX # 4 ; width of VDU 5 chars in pixels -GCharSizeY # 4 ; height of VDU 5 chars in pixels - -GCharSpacing # 0 -GCharSpaceX # 4 ; horizontal spacing between VDU 5 chars in pixels -GCharSpaceY # 4 ; vertical ------------------""----------------- - -TCharSizes # 0 -TCharSizeX # 4 ; width of VDU 4 chars in pixels -TCharSizeY # 4 ; height of VDU 4 chars in pixels - -TCharSpacing # 0 -TCharSpaceX # 4 ; horizontal spacing between VDU 4 chars in pixels -TCharSpaceY # 4 ; vertical ------------------""----------------- - -HLineAddr # 4 ; address of exported HLine -GcolOraEorAddr # 4 ; address of FgEcfOraEor etc - -FirPalSetting # 4*28 ; First palette settings (not used on VIDC20) -FirPalAddr * FirPalSetting ; Address of block for first palette setting (only used on VIDC20) -SecPalSetting # 4*28 ; Second palette settings (not used on VIDC20) -SecPalAddr * SecPalSetting ; Address of block for second palette setting (only used on VIDC20) - -TextFgColour # 4 ; Fg/Bg colour stored as a colour number, computed on VDU 18 and re-poked! -TextBgColour # 4 ; - -; In this brave new world there is a pointer to the text expansion -; buffer used for VDU 4 / 5 text plotting. - -; This now lives in the system heap. - -TextExpandArea # 4 ; Pointer to Text expand area (in system heap) -TextExpandArea_Size * (8*1024) - -HSWRSoftCopy # 4 ; soft copy of h.sync width register (for DPMS) -VSWRSoftCopy # 4 ; soft copy of v.sync width register (for DPMS) - -ScreenBlankFlag # 1 ; 0 => unblanked, 1 => blanked -ScreenBlankDPMSState # 1 ; 0 => just blank video - ; 1 => blank to stand-by (hsync off) - ; 2 => blank to suspend (vsync off) - ; 3 => blank to off (H+V off) - - [ AssemblingArthur - ! 0,"64 ":CC::STR:@ - ] - AlignSpace 64 - -FgEcfOraEor # 4*16 ; Interleaved zgora & zgeor -BgEcfOraEor # 4*16 ; Interleaved zgora & zgeor -BgEcfStore # 4*16 ; Interleaved zgora & zgeor to store background - -;Current state of pattern -LineDotCnt # 4 ; Count down to restarting pattern -LineDotPatLSW # 4 ; Current state of pattern LSWord -LineDotPatMSW # 4 ; " " " " MSWord - -DotLineLength # 4 ; Dot Pattern repeat length as given in *FX163,242,n - -BBCcompatibleECFs # 4 ; 0 => BBC compatible, 1 => native - -SpAreaStart # 4 ; Start of sprite area -SpChooseName # 16 ; No comment says Richard -SpChoosePtr # 4 - -PointerHeights # 4 ; 4 x 1 byte -PointerActiveXs # 4 ; 4 x 1 byte -PointerActiveYs # 4 ; 4 x 1 byte -PointerShapeNumber # 4 ; only bottom byte used -PointerX # 4 ; co-ordinates of pointer (not always = mouse) -PointerY # 4 - -VIDCControlCopy # 4 ; Soft copy of VIDC control register -VertAdjust # 4 ; offset to add to vertical VIDC registers - -TeletextOffset # 4 ; Offset to current teletext flash bank - -TeletextCount # 4 ; Number of vsyncs till next teletext flash - -WrchNbit # 4 ; Pointer to char code for current mode - -BeepBlock # 8 ; OSWORD block for VDU 7 - -ScreenMemoryClaimed # 1 ; NZ => memory has been claimed or is unusable - - [ AssemblingArthur - ! 0,"16 ":CC::STR:@ - ] - AlignSpace 16 ; Align workspace to 16 bytes - -TTXDoubleCounts # 25 ; Number of double height chars on each line - - [ AssemblingArthur - ! 0,"16 ":CC::STR:@ - ] - AlignSpace 16 ; Align workspace to 16 bytes - -RAMMaskTb # 32*4 ; Copy of MaskTb for this mode (up to 32 words) - - [ AssemblingArthur - ! 0,"16 ":CC::STR:@ - ] - AlignSpace 16 ; Align workspace to 16 bytes - -VduOutputCurrentState # 0 ; values of R0-R3 to return from SwitchOutputToSprite - ; or Mask; next 4 must be in this order -SpriteMaskSelect # 4 ; value of R0 to be given to SWI OS_SpriteOp to set up - ; current state -VduSpriteArea # 4 ; Pointer to sprite area containing VDU output sprite - ; (0 if output is to screen) -VduSprite # 4 ; Pointer to VDU output sprite (0 if output to screen) - -VduSaveAreaPtr # 4 ; Pointer to save area for VDU variables - - - [ AssemblingArthur - ! 0,"16,12 ":CC::STR:@ - ] - AlignSpace 16, 12 ; Make ClipBoxCoords a valid immediate, - ; with ClipBoxEnable immediately before it -ClipBoxInfo # 0 -ClipBoxEnable # 4 ; 0 => clip box disabled, 1 => enabled - -ClipBoxCoords # 0 ; Internal coords of modified area of screen -ClipBoxLCol # 4 -ClipBoxBRow # 4 -ClipBoxRCol # 4 -ClipBoxTRow # 4 - -FgPattern # 4*8 ; foreground pattern as defined by OS_SetColour -BgPattern # 4*8 ; background pattern as defined by OS_SetColour - - [ AssemblingArthur - ! 0,"16 ":CC::STR:@ - ] - - AlignSpace 16 ; Align workspace to 16 bytes - -TextExpand # 4*1024 ; Tim's massive text expansion table for whizzy WRCH -; TextPlain is now always hard against the end of TextExpand for this mode - -TTXSoftFonts * TextExpand + 2*1024 ; Soft fonts in teletext mode - - [ AssemblingArthur - ! 0,"64 ":CC::STR:@ - ] - AlignSpace 64 ; Align workspace to 64 bytes - -; Teletext map and copy/move buffer are overlaid - -TTXMapSize * 41*25*4 ; (&1004 bytes) -LargeCommon # TTXMapSize ; the largest area -TTXMap * LargeCommon - -ScrLoaSpriteCB * LargeCommon ; (size = SpriteCBsize + MaxSpritePaletteSize) -ScrLoaBuffer * LargeCommon ; (size = one pixel row) -ScrSavCommon * LargeCommon ; (size = SpriteAreaCBsize + SpriteCBsize - ; + MaxSpritePaletteSize) - -FldQueueSize * ScratchSpaceSize -FldQueueStart * ScratchSpace - - [ AssemblingArthur - ! 0,"64 ":CC::STR:@ - ] - AlignSpace 64 ; Align workspace to 64 bytes - -Font # &700 ; 7 pages of (soft) font - -SaveAreaSize * 12*1024-@ - -VduSaveArea # SaveAreaSize ; save area for switching output to sprites - -VDWSSize # 0 - - ASSERT VDWSSize <= 12 * 1024 - -; ***************************************************************************** -; Space in the first 32K is allocated below -; ***************************************************************************** -; Real workspace definition - -; Basic kernel space - defined locations for external modules - - ^ &100 -IRQ1V # 4 ; &100 - -ESC_Status # 1 ; &104 -LatchBSoftCopy # 1 ; &105 -IOCControlSoftCopy # 1 ; &106 -CannotReset # 1 ; &107 - -IRQsema # 4 ; &108 -MetroGnome # 4 ; &10C -MemorySpeed # 4 ; &110 - -MEMC_CR_SoftCopy # 4 ; &114 -ResetIndirection # 4 ; &118 - -; Now all internal definitions - -; Up to here is initialized on reset - -; Next come handler variables - -MemLimit # 4 -UndHan # 4 -PAbHan # 4 -DAbHan # 4 -AdXHan # 4 - -ErrHan # 4 -ErrBuf # 4 -ErrHan_ws # 4 - -CallAd_ws # 4 ; smart Rs ordering: -CallAd # 4 ; can do LDMIA of r12, pc -CallBf # 4 - -BrkAd_ws # 4 -BrkAd # 4 -BrkBf # 4 - -EscHan_ws # 4 -EscHan # 4 - -EvtHan_ws # 4 -EvtHan # 4 - -CamEntries # 4 * 256 ; CAM entries + PPL in here for machines up to - ; 8 MBytes - for larger machines they're stored - ; in CamEntriesForBigMachines - the location - ; CamEntriesPointer points to whichever is used - ASSERT CamEntries = &164 ; Fixed for PCEmulator (doesn't work with >= 8MBytes) - -CamEntriesPointer # 4 ; points to where CAM soft copy is - ; (CamEntries for machines up to 8MBytes, - ; CamEntriesForBigMachines for larger machines) - -MaxCamEntry # 4 ; maximum index into the cam map, ie - ; 511 for 16MByte machines, 383 for 12MBytes - ; 255 for 8MBytes, otherwise 127 - -RAMLIMIT # 4 - -AplWorkSize # 4 - -HiServ_ws # 4 -HiServ # 4 -SExitA # 4 -SExitA_ws # 4 -UpCallHan_ws # 4 -UpCallHan # 4 - -ROMModuleChain # 4 ; pointer to head of ROM module chain - -; now a section that it's handy to have in simply loadable places - - [ AssemblingArthur - ! 0,"16 ":CC::STR:@ - ] - AlignSpace 16 - -KeyWorkSpaceSize * &200 -KeyWorkSpace # KeyWorkSpaceSize - -; The following were reordered on 26-Jul-91. Old ordering was: -; GeneralMOSBuffer -; ModuleSWI_HashTab -; Module_List -; Curr_Active_Object -; VecPtrTab -; ExceptionDump - -ModuleSHT_Entries * 16 -ModuleSWI_HashTab # 4*ModuleSHT_Entries - -Module_List # 4 -Curr_Active_Object # 4 - -; Vector Claim & Release tables etc - -VecPtrTab # NVECTORS * 4 - -ExceptionDump # 4 - -; GeneralMOSBuffer: re-use with caution! -; Here's just some of the users: -; user use(s) -; default error handler error buffer (must be 246+4 bytes big) -; *If expression to be evaluated to control the *If -; Command line to be submited on the expression -; evaluating to non-zero (the THEN clause). -GeneralMOSBuffer # 256+4 - - [ AssemblingArthur - ! 0,"16 ":CC::STR:@ - ] - AlignSpace 16 ; Ensures we can MOV rn, #OsbyteVars if <=&1000 - -OsbyteVars # OSBYTEVarSize - ASSERT OsbyteVars < &10000 ; Must keep in first 64K so address can be read by - ; (and stored in) OS_Bytes &A6,&A7. SKS - -; These must be in first 4K -NBuffers * 10 -BuffInPtrs # 4 * NBuffers -BuffOutPtrs # 4 * NBuffers - -VariableList # 4 - -; Oscli stuff -OscliCBtopUID # 4 -OscliCBbotUID # 4 -OscliCBcurrend # 4 - -ReturnCode # 4 -RCLimit # 4 - -SpriteSize # 4 ; saved on startup for Sprite code and RAMFS -RAMDiscSize # 4 -FontCacheSize # 4 ; and font manager - -TickNodeChain # 4 - -; Workspace - -EnvTime # 5 -RedirectInHandle # 1 -RedirectOutHandle # 1 -MOShasFIQ # 1 -FIQclaim_interlock # 1 -CallBack_Flag # 1 -IRQ_CallBack_Flag * CallBack_Flag -IOSystemType # 1 ; 0 => old I/O subsystem, 1 => IOEB+82C710 system, 2..255 => ? -MonitorLeadType # 1 ; some function of the monitor lead inputs, as yet undetermined - - AlignSpace - -EnvString # 256 - - -DUMPER # 16 * 4 - -; more system workspace -Page_Size # 4 -PIRQ_Chain # 4 -PFIQasIRQ_Chain # 4 - -; IRQ despatch -DefIRQ1Vspace * 9*4+12*17+2*256 ; for size checking in MOS -DefaultIRQ1V # DefIRQ1Vspace ; assembly - - -CallBack_Vector # 4 - -; interruptible heap manager workspace - -HeapSavedReg_R0 # 4 -HeapSavedReg_R1 # 4 -HeapSavedReg_R2 # 4 -HeapSavedReg_R3 # 4 -HeapSavedReg_R4 # 4 -HeapSavedReg_R13 # 4 -HeapReturnedReg_R0 # 4 -HeapReturnedReg_R1 # 4 -HeapReturnedReg_R2 # 4 -HeapReturnedReg_R3 # 4 -HeapReturnedReg_R4 # 4 -HeapReturnedReg_R13 # 4 -HeapReturnedReg_PC # 4 ; also acts as interlock - -PrinterBufferAddr # 4 ; holds address of printer buffer -PrinterBufferSize # 4 ; size of printer buffer - not to be confused with PrintBuffSize - ; which is the (constant) default size for the MOS's smallish buffer -UniqueMachineID # 8 ; 64 bits for unique machine ID -KernelMessagesBlock # 20 ; 5 Words for messagetrans message block. -ErrorSemaphore # 1 ; Error semaphore to avoid looping on error translation. -PortableFlag # 1 ; Non-zero => got an error from Portable_Speed, so don't try it again - - AlignSpace - -MOSConvertBuffer # 12 ; Enough romm for 8 hex digits. - -ProcVec_Start # 0 ; Start of processor vector table -ProcVec_Branch0 # 4 ; Branch through zero -ProcVec_UndInst # 4 ; Undefined instruction vector -ProcVec_SWI # 4 ; SWI vector -ProcVec_PrefAb # 4 ; Prefetch abort vector -ProcVec_DataAb # 4 ; Data abort vector -ProcVec_AddrEx # 4 ; Address exception vector (not useful on ARM600/700) -ProcVec_IRQ # 4 ; IRQ vector -ProcVec_End # 0 - -ProcVecPreVeneersSize * 4*4 ; Space for preveneers for loading handler addresses from 0 page. -ProcVecPreVeneers # ProcVecPreVeneersSize - - [ AssemblingArthur - ! 0, "low space free ":CC::STR:(&FEC-@) - ] - ASSERT @ < &FEC - -; Words for old tools of assorted varieties - ^ &FEC -; ECN 17-Feb-92 -; Added RISCOSLibWord and CLibWord. The ROM RISCOSLib and CLib must continue -; to work even when they are killed since ROM apps are hard linked to the -; ROM libraries. They cannot use the private word since the block pointed -; to by this will be freed. -RISCOSLibWord # 4 -CLibWord # 4 -FPEAnchor # 4 -DomainId # 4 ; SKS added for domain identification -Modula2_Private # 4 ; MICK has FFC and uses it it in USR mode - -VduDriverWorkSpace # VDWSSize - ASSERT (VduDriverWorkSpace :AND: 63) = 0 ; For Tim (VDU5) - - - [ AssemblingArthur - ! 0, "high space free ":CC::STR:(&4000-@) - ] - - ^ &4000 -ScratchSpaceSize * &4000 -ScratchSpace # ScratchSpaceSize - - ASSERT @ <= &8000 ; Start of apl - -; ***************************************************************************** -; Users of ScratchSpace declare yourself here: - -; NRaine: Filling a polygon uses ScratchSpace to flatten the path - -; DSeal: Draw module uses ScratchSpace on fill operations (this supercedes -; NRaine's declaration above). - -; SKS: HeapSort with (r1 & 0x80000000) & ~(r1 & 0x20000000) & (r5 <= 16K) -; uses ScratchSpace as a temp slot for data shuffling after sorting - -; TMD: Flood fill uses ScratchSpace for the flood queue. - -; Tidying the RMA uses ScratchSpace while all modules are dead - -; GSTRANS workspace: GSINIT puts state into the workspacem and GSREAD uses it. -; DO NOT do any operations between GSINIT/GSREAD SWIS. -; SWIs called: OSWord in time var code -; BinaryToDecimal, ReadUnsigned - -; LVR: ADFS uses scratch space to format floppies on 1772 based machines - -; DDV: ColourTrans uses scratch space to build palette tables when in -; ColourTrans_SelecTable/RetrunColourNumber and also whilst generating -; stipple pattterns. - -GSVarWSpace * ScratchSpace - - ^ 0 -GSNameBuff # &100 -GS_Stack # &200 -GS_StackPtr_Lim * &200 / 4 ; Number of words in stack. -GS_StackPtr # 4 - - ^ @ + ScratchSpace - -; Pointers for SubstituteArgs: no external calls. -; Ensure these don't overlap FileSwitch's buffers below! - -MacExStartPtrs # 44 -MacExEndPtrs # 44 - -; OS_CLI has a buffer for alias expansion: ReadVarVal and SubstituteArgs -; are called while the buffer is held. Also used for module prefixes: -; Module called twice in this case. - -AliasExpansionBuffer # 100 - -; *list/*type need an argument expansion buffer: ReadArgs called with it. - -ArgumentBuffer * AliasExpansionBuffer - -; EvaluateExpression space. Calls ReadUnsigned, BinaryToDecimal and ReadVarVal. - -ExprWSpace * @ - - ^ 0, R12 -ExprBuff # &100 -exprBracDif # 2 ; keep exprSTRACC aligned -tos_op # 2 ; 1 byte for use as STRACC-1 -ExprSVCstack # 4 -exprSTRACC * @ - ExprBuff + ExprWSpace - -ExprStackLimit * exprSTRACC + &100 -ExprStackStart * ScratchSpace + ScratchSpaceSize - - -; Tutu needs some for argument substitution + expansion for run/load types -; Only OS call during xform is XOS_SubstituteArgs and XOS_Heap(Claim,SysHeap) - - ^ 0 ; Offset from ScratchSpace -rav_substituted # 256 -rav_arglist # 256 - -TopOfPageZero # 0 - - ^ &8000 ; The actual top of Page Zero -EconetDebugSpace |#| &20 * 4 ; Thirty two words (&7F80) - - ASSERT @ > TopOfPageZero ; Make sure we don't clash - -; ***************************************************************************** -; *** Cursor, Sound DMA, SWI, and OSCLI workspace. *** -; *** Sits in the 32K above 31M, ie. &01F000000..&01F07FFF *** -; *** Has the physical address &02078000, ie. 32M + 512K - 32K *** -; ***************************************************************************** - -TopOfDMAPhysRAM * &80000 ; OFFSET in physram -TopOfDMAWorkSpace * CursorChunkAddress + 32*1024 -OffsetLogicalToPhysical * TopOfDMAPhysRAM - TopOfDMAWorkSpace - - ^ TopOfDMAWorkSpace ; Note we will be going down - -; Sound - -SoundWorkSpaceSize * &1000 -SoundDMABufferSize * &1000 -SoundEvtSize * &1000 -SoundDMABuffers |#| SoundDMABufferSize * 2 -SoundWorkSpace |#| SoundWorkSpaceSize + SoundEvtSize - -; Cursor - -CursorDataSize * &800 -CursorData |#| CursorDataSize -CursorSoundRAM * CursorData -CursorSoundPhysRAM * CursorSoundRAM + OffsetLogicalToPhysical - -; SWI despatcher - -BranchToSWIExit |#| 4 -SvcTable |#| &400 - ASSERT SvcTable = &01F033FC ; Required for SVC table pokers, 1.20 compatible -SWIDespatch_Size * 29*4 -SWIDespatch |#| SWIDespatch_Size - - -; Buffers - -KeyBuffSize * &100 -RS423InBuffSize * &100 -RS423OutBuffSize * &C0 -PrintBuffSize * &400 -Sound0BuffSize * 4 -Sound1BuffSize * 4 -Sound2BuffSize * 4 -Sound3BuffSize * 4 -SpeechBuffSize * 4 -MouseBuffSize * &40 -KeyBuff |#| KeyBuffSize -RS423InBuff |#| RS423InBuffSize -RS423OutBuff |#| RS423OutBuffSize -PrintBuff |#| PrintBuffSize -Sound0Buff |#| Sound0BuffSize -Sound1Buff |#| Sound1BuffSize -Sound2Buff |#| Sound2BuffSize -Sound3Buff |#| Sound3BuffSize -SpeechBuff |#| SpeechBuffSize -MouseBuff |#| MouseBuffSize - -; Oscli buffering - -OscliBuffSize * &100 -OscliNoBuffs * 16 -OscliCircBuffLimit |#| 0 -OscliCircBuffStart |#| OscliBuffSize * OscliNoBuffs -RedirectBuff |#| OscliBuffSize - -; New soft CAM address for 12MByte or 16MByte machines - -CamEntriesForBigMachines |#| 512*4 ; 512 entries, each is a word - - [ AssemblingArthur - ! 0, "Aligning IRQ stack from ":CC::STR:@ - ] - [ @-7*4 :AND: 15 <> 0 - |#| (@-7*4):AND:15 - ] -IRQSTK # 0 ; Overflow will give abort - [ AssemblingArthur - ! 0, "IRQ stack size ":CC::STR:(IRQSTK-CursorChunkAddress) - ] - - ASSERT @ > ( CursorChunkAddress + &1000 ) ; Check minimum stack - -; ***************************************************************************** -; High system workspace -; ***************************************************************************** - - ^ SysHeapChunkAddress - - # 8*1024 ; svcstk size. Overflow will give abort -SVCSTK # 0 -SysHeapStart # 0 - - - OPT OldOpt - END diff --git a/hdr/Old/VickySpace b/hdr/Old/VickySpace deleted file mode 100644 index c060e361..00000000 --- a/hdr/Old/VickySpace +++ /dev/null @@ -1,1296 +0,0 @@ -; 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 > &.Hdr.VickySpace - -OldOpt SETA {OPT} - OPT OptNoList+OptNoP1List - -; *********************************** -; *** C h a n g e L i s t *** -; *********************************** - -; Date Name Description -; ---- ---- ----------- -; 02-Nov-87 APT Added module SWI hash table -; 03-Nov-87 APT Modo-fied module SWI hash table info, removed BRKLST -; 09-Nov-87 APT Removed ESCCNT and ESFLG -; 12-Nov-87 APT Added IRQsema -; 13-Nov-87 APT Added DefaultIRQ1V codespace -; 16-Nov-87 APT PIRQ chain heads -; 18-Nov-87 APT Reordered EvtHan, EvtHan_ws -; 19-Nov-87 APT Moved IRQsema -; 01-Dec-87 APT Added interruptible heap manager workspace -; 08-Dec-87 TMD Added ECFShift, ECFYOffset -; 14-Dec-87 TMD Added DisplayNColour, DisplayModeFlags -; 15-Dec-87 TMD Added KeyAlphabet -; 22-Dec-87 NDR Using ScratchSpace -; 13-Jan-88 APT General scratchspace bash, low workspace reordering. -; Removed spurious 32 bytes of osbyte wspace -; 14-Jan-88 APT *type buffer in scratchspace. -; MOShasFIQ byte added -; 20-Jan-88 APT Workspace juggling for speed & space; also discarded -; Level0 stuff. -; 28-Jan-88 APT MetroGnome moved to "public" location for ADFS -; 02-Feb-88 APT FIQclaim_interlock added -; 05-Feb-88 APT CallBack_Vector -; 09-Feb-88 APT RAM for SWI despatch -; 17-Feb-88 TMD Added VduSaveArea, VduSaveAreaPtr, DisplayModeNo -; 26-Feb-88 APT NoOfCamEntries manifest -; 03-Mar-88 APT Shrank SVC despatch -; 03-Mar-88 APT NoOfCamEntries manifest doubled -; 07-Mar-88 TMD Added DisplayScreenStart, VduOutputCurrentState, -; SpriteMaskSelect, reordered mode variables -; 07-Mar-88 APT Made CamEntries always at &164 -; 07-Mar-88 TMD Added GCharSizes, GCharSizeX, GCharSizeY -; 08-Mar-88 TMD Added GCharSpacing, GCharSpaceX, GCharSpaceY -; 08-Mar-88 TMD Moved GCharSizes..GCharSpaceY into first 1K of workspace -; 15-Mar-88 TMD Added HLineAddr -; 18-Mar-88 TMD Added DisplayXWindLimit, DisplayYWindLimit, -; DisplayXEigFactor, DisplayYEigFactor, PointerXEigFactor -; 18-Mar-88 APT Setting variables scratchspace use revised. -; 21-Mar-88 TMD Removed CursorIndex -; 22-Mar-88 TMD Added TCharSizeX,TCharSizeY,TCharSpaceX,TCharSpaceY -; 29-Mar-88 TMD Added GcolOraEorAddr -; 31-Mar-88 TMD Removed WsFontPtr -; 07-Apr-88 SKS Added HeapSort use of ScratchSpace -; 14-Apr-88 TMD Added SerialFlags -; 28-Apr-88 TMD Added XONXOFFChar -; 5-May-88 APT Added MemorySpeed -; 18-May-88 APT Added CannotReset sema at &107, removed pre-1.20 changes. -; 24-May-88 TMD Added ClipBoxEnable, ClipBoxLCol..ClipBoxTRow, moved in -; ScrLoaSpriteCB, ScrLoaBuffer, SrcSavCommon -; 24-May-88 TMD Flood fill uses ScratchSpace -; 01-Jun-88 TMD Added AlignSpace for ClipBoxCoords -; 03-Jun-88 BCSKS Make Keyboard buffer into a useful part of the system -; Also PrinterBufferSize -; 09-Jun-88 DJS Draw uses ScratchSpace -; 09-Jun-88 BC Gave Econet some private debungling space -; 11-Jun-88 SKS Align IRQ stack to make STMFD not cross two MEMC bdy's -; Made info condit'l on AsmArf; someone had commented it out! -; 15-Jun-88 SKS Added two more instructions in SWIDespatch area -; Moved SLVK definition into kernel; it's not public -; 16-Jun-88 SKS Added 3 more instructions in SWIDespatch area + nailed -; SvcTable address for compatibility -; 22-Jun-88 SKS Moved MEMC_CR_SoftCopy into pubic ws -; 19-Jul-88 APT Added UpCall handler stuff -; 20-Jul-88 SKS Added above entry -; Amended comment about overlaid workspace in vdu -; 15-Aug-88 SKS Inserted DomainId at FF8 (set by Wimp on task swap, used by -; FileSwitch to tag resources) -; 27-Sep-89 JSR Added ColourTrans to users of scratch space -; 24-Oct-89 TMD Added CamEntriesForBigMachines, CamEntriesPointer -; 26-Oct-89 TMD Added MaxCamEntry, removed NoOfCamEntries symbol -; 27-Oct-89 TMD Added VIDCClockSpeed -; 09-Nov-89 TMD Added ResetIndirection -; 15-Jan-91 TMD Added ROMModuleChain -; 04-Feb-91 DDV Added DeviceFS as user of ScratchSpace. -; 04-Feb-91 DDV Added ColourTrans use of ScratchSpace to build diff tables. -; 06-Mar-91 TMD Added IOSystemType -; 07-Mar-91 LVR ADFS uses scratch space for floppy formatting -; 07-Mar-91 TMD Added MonitorLeadType -; 08-Mar-91 TMD Added PrinterBufferAddr, PrinterBufferSize -; 11-Apr-91 TMD Added SerialInHandle, SerialOutHandle -; 24-Apr-91 TMD Added UniqueMachineID -; 09-Jun-91 RM Added KernelMessagesBlock,ErrorSemaphore and MOSConvertBuffer -; 26-Jul-91 JSR Extend GeneralMOSBuffer by 4 bytes to make it a valid -; length for the default error handler's error buffer -; 19-Aug-91 JSR Added *If to list of GeneralMOSBuffer users -; 22-Aug-91 TMD Reduced ErrorSemaphore to a byte, added PortableFlag -; 25-Aug-91 DDV Updated to indicate correct usage of scratch space by ColourTrans -; 09-Jan-92 DDV Added FgPattern, BgPattern and indicate use of ScratchSpace by OS_SetColour -; 20-Jan-92 TMD OS_SetColour no longer uses ScratchSpace -; 17-Feb-92 ECN Added CLibWord and RISCOSLibWord -; 02-Apr-92 TMD Added ScreenBlankFlag -; 27-Jul-92 TMD Create Victoria specific version -; 28-Jul-92 TMD Moved RAMDiscAddress -; 29-Jul-92 TMD Moved SpriteSpaceAddress -; 30-Jul-92 TMD Moved FontCacheAddress -; 31-Jul-92 TMD Moved ScreenEndAdr from source.vdudecl, and moved actual address! -; 03-Aug-92 TMD Added PhysRam (moved from hdr:System) -; 24-Aug-92 TMD Added AbortIndirection -; 26-Aug-92 TMD Added PreVeneerRegDump -; 02-Sep-92 TMD Added FirPalAddr, SecPalAddr -; 10-Sep-92 DDV Added new Vdu Variables for new text expansion buffer -; 17-Sep-92 DDV Moved NColour into the word initialised VDU workspace -; 17-Sep-92 DDV Two new colour words added for text foreground and background. -; 27-Jan-93 TMD Moved RMA to new position -; 29-Jan-93 TMD Put RMA back to old position (you can't branch to above 32M!) -; 01-Feb-93 TMD Added PhysRamTable -; 02-Feb-93 TMD Added VInitSoftCopy and VEndSoftCopy -; 03-Feb-93 TMD Added PhysRamTableEnd -; 04-Feb-93 TMD Added extra slot in PhysRamTable (in case soft-loaded OS splits a bank) -; 08-Feb-93 TMD Added VRAMWidth variable, and extra symbols for skipped bits -; 24-Feb-93 TMD Changed VRAMPhysAddr to VideoPhysAddr, and split off VideoSize from VRAMSize, to allow for -; DRAM-only systems -; 05-Mar-93 TMD Added CMOSRAMCache -; 19-Apr-93 TMD Added DAList, AppSpaceDANode and DANode offset symbols -; 26-Apr-93 TMD Added FreePoolAddress, FreePoolMaxSize, FreePoolSize -; 29-Apr-93 TMD Changed FontCacheAddress, SpriteSpaceAddress, RAMDiscAddress and FreePoolAddress -; in order to make way for L2PT, which is moving above 64M -; 10-May-93 TMD Added SoftCamMapSize -; 11-May-93 TMD Moved SoftCamMapSize into area that's not zapped in clearing all memory routine -; 12-May-93 TMD Added FreePoolDANode, removed FreePoolSize -; 20-May-93 TMD Moved AplWorkSize into AppSpaceDANode -; 27-May-93 TMD Added VideoBandwidth -; 04-Jun-93 TMD Added CurrentMonitorType -; 09-Jun-93 TMD Added CamMapCorruptDebugBlock -; 07-Jul-93 TMD Increased FreePoolMaxSize to 64M (had to reduce RAMDiscMaxSize to 48M and -; move FreePoolAddress down to do this) -; 15-Jul-93 TMD Added KernelModeSelector -; 26-Jul-93 SMC Moved DefaultIRQ1V (had to accommodate IRQs for IOMD DMA) -; 04-Aug-93 TMD Added L2PTSize, removed FreePoolMaxSize -; 14-Aug-93 TMD Removed SpriteSpaceAddress, shuffled things down -; 16-Aug-93 TMD Removed RAMDiscAddress, shuffled things down -; 17-Aug-93 TMD Removed FontCacheAddress, shuffled things down -; Corrected maximum size of system heap to 2M-8K. -; Added node (in bottom 32K) for system heap. -; 25-Aug-93 SMC Added processor vector table at ProcVec_Start -; Added ProcVecPreVeneers -; 02-Sep-93 SMC Moved RMA to &02100000 and changed application space size to 28M. -; 03-Sep-93 TMD Moved InitKbdWs into SkippedTables (was at start of screen originally) -; 07-Oct-93 TMD Put in OldMemoryMap option so I can still use it -; 07-Oct-93 TMD Added ScreenBlankDPMSState, HSWRSoftCopy, VSWRSoftCopy -; 10-Dec-93 BC Added RawMachineID -; 13-Dec-93 BC Removed UniqueMachineID -; 14-Jan-94 TMD Added CDASemaphore -; 18-Jan-94 TMD Added MMUControlSoftCopy -; -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; Memory map: - -; Dynamic area node format - - ^ 0 - -DANode_Link # 4 ; points to next node -DANode_Number # 4 ; number of this area -DANode_Base # 4 ; base address of area (points in middle of doubly-mapped areas) -DANode_Flags # 4 ; various flags -DANode_Size # 4 ; current size of area -DANode_MaxSize # 4 ; maximum size of area -DANode_Workspace # 4 ; workspace pointer when calling handlers -DANode_Handler # 4 ; pointer to handler routine for area -DANode_Title # 4 ; pointer to area title (variable length) -DANode_NodeSize # 0 - -; The addresses below are only temporary; eventually most of them will be allocated at run time (we hope!) - - [ :DEF: OldMemoryMap -AplWorkMaxSize * &01000000 ; 16M -RMAAddress * &01800000 -RMAMaxSize * &00400000 ; 4M - | -AplWorkMaxSize * &01C00000 ; 28M -RMAAddress * &02100000 -RMAMaxSize * &00B00000 ; 11M - ] - -SysHeapChunkAddress * &01C00000 -SysHeapMaxSize * &00200000-8*1024 ; 2M - 8K - -CursorChunkAddress * &01F00000 ; Fixed size 32K - -ScreenEndAdr * &05000000 ; was &02000000 -ScreenMaxSize * 480*1024 - -; FontCacheAddress * &06000000 ; was &01E00000 ; now dynamic -; FontCacheMaxSize * &01000000 ; 16M - -; SpriteSpaceAddress * &08000000 ; was &01400000 ; now dynamic -; SpriteSpaceMaxSize * &01000000 ; 16M - -; RAMDiscAddress * &07000000 ; was &01000000 ; now dynamic -; RAMDiscMaxSize * &03000000 ; 48M - -FreePoolAddress * &06000000 ; may still go lower! - -PhysRam * &05000000 - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; system variables - - ^ 0,R12 - -OSBYTEFirstVar # 0 - -ByteVars # 0 ; The main osbyte variables, accessed - ; via calls &A6 to &FF - -VarStart # 2 ; &A6,&A7 -ROMPtr # 2 ; &A8,&A9 -ROMInfo # 2 ; &AA,&AB -KBTran # 2 ; &AC,&AD -VDUvars # 2 ; &AE,&AF - -CFStime # 1 ; &B0 -InputStream # 1 ; &B1 -KeyBdSema # 1 ; &B2 - -ROMPollSema # 1 ; &B3 -OSHWM # 1 ; &B4 - -RS423mode # 1 ; &B5 -NoIgnore # 1 ; &B6 -CFSRFS # 1 ; &B7 -VULAcopy # 2 ; &B8,&B9 - -ROMatBRK # 1 ; &BA -BASICROM # 1 ; &BB - -ADCchanel # 1 ; &BC -ADCmaxchn # 1 ; &BD -ADCconv # 1 ; &BE - -RS423use # 1 ; &BF -RS423conflag # 1 ; &C0 - -FlashCount # 1 ; &C1 -SpacPeriod # 1 ; &C2 -MarkPeriod # 1 ; &C3 - -KeyRepDelay # 1 ; &C4 -KeyRepRate # 1 ; &C5 - -ExecFileH # 1 ; &C6 -SpoolFileH # 1 ; &C7 - -ESCBREAK # 1 ; &C8 (200) - -KeyBdDisable # 1 ; &C9 -KeyBdStatus # 1 ; &CA - -RS423HandShake # 1 ; &CB -RS423InputSupr # 1 ; &CC -RS423CFSFlag # 1 ; &CD - -EconetOScall # 1 ; &CE -EconetOSrdch # 1 ; &CF -EconetOSwrch # 1 ; &D0 - -SpeechSupr # 1 ; &D1 -SoundSupr # 1 ; &D2 - -BELLchannel # 1 ; &D3 -BELLinfo # 1 ; &D4 -BELLfreq # 1 ; &D5 -BELLdur # 1 ; &D6 - -StartMessSupr # 1 ; &D7 - -SoftKeyLen # 1 ; &D8 - -PageModeLineCount # 1 ; &D9 - -VDUqueueItems # 1 ; &DA - -TABch # 1 ; &DB -ESCch # 1 ; &DC - -IPbufferCh # 4 ; &DD,&DE,&DF,&E0 -RedKeyCh # 4 ; &E1,&E2,&E3,&E4 - -ESCaction # 1 ; &E5 -ESCeffect # 1 ; &E6 - -u6522IRQ # 1 ; &E7 -s6850IRQ # 1 ; &E8 -s6522IRQ # 1 ; &E9 - -TubeFlag # 1 ; &EA - -SpeechFlag # 1 ; &EB - -WrchDest # 1 ; &EC -CurEdit # 1 ; &ED - -SoftResetVars # 0 ; Reset to here on soft reset - -KeyBase # 1 ; &EE -Shadow # 1 ; &EF -Country # 1 ; &F0 - -UserFlag # 1 ; &F1 - -SerULAreg # 1 ; &F2 - -TimerState # 1 ; &F3 - -SoftKeyConsist # 1 ; &F4 - -PrinterDrivType # 1 ; &F5 -PrinterIgnore # 1 ; &F6 - -HardResetVars # 0 ; Reset to here on hard reset - -BREAKvector # 3 ; &F7,&F8,&F9 - -MemDriver # 1 ; &FA - where the VDU drivers write to -MemDisplay # 1 ; &FB - where we display from - -LangROM # 1 ; &FC - -LastBREAK # 1 ; &FD - -KeyOpt # 1 ; &FE - -StartOptions # 1 ; &FF - -PowerOnResetVars # 0 ; Reset to here on power-on reset - -; These two can dovetail in here to use up 2 bytes before the AlignSpace! - -SerialInHandle # 1 ; Handle for serial input stream (0 if not open currently) -SerialOutHandle # 1 ; Handle for serial output stream (-----------""----------) - - AlignSpace - -EventSemaphores # 32 ; One byte for each of 32 events - -TimerAlpha # 8 ; As used by time (bottom 5 bytes) -TimerBeta # 8 ; ................................ -; both aligned to word boundaries - -RealTime # 8 ; 5-byte fast real-time - -PrinterActive # 4 ; Handle/active flag for printer (word aligned) - -IntervalTimer # 5 ; Up Counter synchronous with TIME. -; Event generated when Zero is reached -; bottom byte aligned to word boundary - -SecondsTime # 1 ; the soft copy (centi-)seconds of the RTC -CentiTime # 1 ; """""""""""""""""""""""""""""""""""""""" - -FlashState # 1 ; which flash colours are we using - -SecondsDirty # 1 ; the dirty flag for start up! - -MinTick # 1 ; the minutes odd/even state - -DCDDSRCopy # 1 ; copy of ACIA bits to check for change - -TVVertical # 1 ; *TV first parameter - -TVInterlace # 1 ; *TV second parameter - -CentiCounter # 1 ; Counter for VDU CTRL timing - -Alphabet # 1 ; Current alphabet number - -Keyboard # 1 ; Current keyboard number - -KeyAlphabet # 1 ; Alphabet associated with current keyboard - - GBLS PrinterPrefix -PrinterPrefix SETS "PrinterType$" - -PrinterTypeName # 6 + :LEN: (PrinterPrefix) - - AlignSpace - -SerialFlags # 4 ; New serial flags - -XONXOFFChar # 1 ; Character to send before rest (0 if none) - - AlignSpace - -OSBYTEVarSize * @-OSBYTEFirstVar - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -; End of variables' space - - -; *********************************** -; *** Main Vdu Driver Workspace *** -; *********************************** - - ^ 0 - -FgEcf # 4 * 8 ; Foreground Ecf, set by GCOL(a,0-127) -BgEcf # 4 * 8 ; Background Ecf, set by GCOL(a,128-255) -GPLFMD # 4 ; Foreground action, set by GCOL(a,0-127) -GPLBMD # 4 ; Background action, set by GCOL(a,128-255) -GFCOL # 4 ; Foreground colour, set by GCOL(a,0-127) -GBCOL # 4 ; Background colour, set by GCOL(a,128-255) - -GWLCol # 4 ; Graphics window left column -- -GWBRow # 4 ; Graphics window bottom row | -GWRCol # 4 ; Graphics window right column | -GWTRow # 4 ; Graphics window top row -- - -qqqPad # 3 -QQ # 17 ;Queue - QQ+1 is on a word boundary -QOffset # 4 ;Value to add to VDUqueueItems to point to next queue posn. -JVec # 4 ;Jump vector to internal routines - -; Start of MODE table workspace - -ScreenSize # 4 ; number of bytes needed for this mode (assumed 1st in list) - -XWindLimit # 4 ; Maximum value of GWRCol (internal representation) - -; LineLength must be immediately after YWindLimit - -YWindLimit # 4 ; Maximum value of GWTRow (internal representation) - -LineLength # 4 ; Length of one pixel row in bytes - -NColour # 4 ; Number of colours minus 1 - -; End of word mode variables - -YShftFactor # 4 ; Number of places to shift YCoord in address generation after - ; multiplying by 5, holds - ; 7,6,5 or 4 for 8,4,2 or 1 bits per pixel (640x256 mode) or - ; 6,5,4 or 3 for 8,4,2 or 1 bits per pixel (320x256 mode). - -ModeFlags # 4 ; Bit 0 => non-graphic, Bit 1 => teletext, Bit 2 => gap mode - -XEigFactor # 4 ; Number of places to shift XCoord in external to internal - ; coordinate conversion, holds - ; 1 for 640x256 mode - ; 2 for 320x256 mode - ; 3 for 160x256 (BBC micro mode 2) - -YEigFactor # 4 ; number of shifts to convert between internal/external Y - -Log2BPC # 4 ; Log to base 2 of BytesPerChar ie (0,1,2,3,4) - -Log2BPP # 4 ; Log to base 2 of BitsPerPix ie (0,1,2,3) - -ECFIndex # 4 ; Index into default ECF tables - -ScrRCol # 4 ; Maximum column number in this screen mode -ScrBRow # 4 ; Maximum row number in this screen mode - -PalIndex # 4 ; Index into palette tables (0,1,2,3) - -; End of table-initialised workspace - -; Next 3 must be together in this order ! - -XShftFactor # 4 ; Number of places to shift XCoord in address generation, - ; holds 2,3,4 or 5 for 8,4,2,1 bits per pixel respectivly -GColAdr # 4 ; Address of Ecf to plot - either FgEcf or BgEcf - -ScreenStart # 4 ; Start address of screen (for VDU drivers) - -NPix # 4 ; Number of pixels per word minus 1, holds - ; holds 3,7,15 or 31 for 8,4,2,1 bits per pixel modes - -AspectRatio # 4 ; Pixel shape : 0 square, 1 horz rect, 2 vert rect - -BitsPerPix # 4 ; Bits per pixel (1,2,4,8) - -BytesPerChar # 4 ; Bytes per one line of character - ; (same as BitsPerPix except in double pixel modes) - -CursorFudgeFactor # 4 ; Factor for horizontal cursor positioning - -RowMult # 4 ; Row multiplier for text manipulation - -RowLength # 4 ; Bytes per text row in this mode (eg 640,1280,5120) - -; The following (up to and including NewPtY) must be together in this order -; (relied upon by DefaultWindows) - -TWLCol # 4 ; Text window left column -- -TWBRow # 4 ; Text window bottom row | -TWRCol # 4 ; Text window right column | -TWTRow # 4 ; Text window top row -- - -OrgX # 4 ; Screen origin (external representation) -OrgY # 4 - -GCsX # 4 ; Graphics cursor (external representation) -GCsY # 4 - -OlderCsX # 4 ; Very old X coordinate (internal) -OlderCsY # 4 ; Very old Y coordinate (internal) - -OldCsX # 4 ; Old graphics cursor (internal representation) -- -OldCsY # 4 ; | - ; | -GCsIX # 4 ; Graphics cursor (internal representation) | -GCsIY # 4 ; | - ; | -NewPtX # 4 ; Newest point (internal representation) | -NewPtY # 4 ; -- - -; End of together block - -TForeCol # 4 ; Text foreground colour -TBackCol # 4 ; Text background colour - -CursorX # 4 ; Text cursor X position ; these 3 must be in same order as ... -CursorY # 4 ; Text cursor Y position -CursorAddr # 4 ; Screen address of (output) cursor - -InputCursorX # 4 ; Input cursor X position ; ... these 3 -InputCursorY # 4 ; Input cursor Y position -InputCursorAddr # 4 ; Screen address of input cursor - -EORtoggle # 4 ; Toggle between gap and non-gap -RowsToDo # 4 ; in the CLS - -VduStatus # 4 ; Vdu2, Window, Shadow bits (others in CursorFlags) - -CBWS # 8 ; Clear block (VDU 23,8..) workspace -CBStart # 2 -CBEnd # 2 - -CursorDesiredState # 4 -CursorStartOffset # 4 -CursorEndOffset # 4 -CursorCounter # 4 -CursorSpeed # 4 -Reg10Copy # 4 - -CursorFill # 4 ; Word to EOR cursor ; MUST be immediately before CursorNbit - -CursorNbit # 4 ; Pointer to cursor code for current mode - -DisplayStart # 4 ; Start address of screen (for display) -DriverBankAddr # 4 ; Default start address for VDU drivers -DisplayBankAddr # 4 ; Default start address for display -DisplayNColour # 4 ; No. of colours -1 for displayed mode -DisplayModeFlags # 4 ; ModeFlags for displayed mode -DisplayModeNo # 4 ; ModeNo for displayed mode -DisplayScreenStart # 4 ; Where VDU outputs to when outputting to screen - -DisplayXWindLimit # 4 ; Used for pointer programming -DisplayYWindLimit # 4 -DisplayXEigFactor # 4 -DisplayYEigFactor # 4 -PointerXEigFactor # 4 - -Ecf1 # 8 ; The Ecf patterns -Ecf2 # 8 -Ecf3 # 8 -Ecf4 # 8 - -DotLineStyle # 8 ; Dot dash line pattern - -ModeNo # 4 ; Current mode number - -TFTint # 4 ; Text foreground tint (in bits 6,7) -TBTint # 4 ; Text background tint -GFTint # 4 ; Graphics foreground tint -GBTint # 4 ; Graphics background tint - -TotalScreenSize # 4 ; Amount configured for screen (in bytes) - -MaxMode # 4 ; Maximum mode number allowed (20 for now) - -VinitCopy # 4 ; Copy of Vinit for VDU 23;12 or 13 - -CursorFlags # 4 ; Silly Master cursor movement flags - -CursorStack # 4 ; Bit stack of nested cursor states (0 => on, 1 => off) - ; (bit 31 = TOS) - -ECFShift # 4 ; number of bits to rotate right ECF OR and EOR masks by -ECFYOffset # 4 ; vertical offset to ECF index - -WsVdu5 # 0 ; Vdu 5 workspace -WsScr # 4 -WsEcfPtr # 4 -; WsFontPtr # 4 ; not needed any more, kept in register -EndVerti # 4 -StartMask # 4 -EndMask # 4 -FontOffset # 4 -TempPlain # 16 ; only used for MODE 10 - -VIDCClockSpeed # 4 ; current VIDC clock speed in kHz - -CurrentMonitorType # 4 ; initialised from configured one - -KernelModeSelector # 4 ; pointer to block in system heap where - ; current mode selector is copied - -GraphicWs # 300 ; All graphics workspace is overlaid here -EndGraphicWs # 0 - - [ AssemblingArthur - ! 0,"16 ":CC::STR:@ - ] - AlignSpace 16 - -GCharSizes # 0 -GCharSizeX # 4 ; width of VDU 5 chars in pixels -GCharSizeY # 4 ; height of VDU 5 chars in pixels - -GCharSpacing # 0 -GCharSpaceX # 4 ; horizontal spacing between VDU 5 chars in pixels -GCharSpaceY # 4 ; vertical ------------------""----------------- - -TCharSizes # 0 -TCharSizeX # 4 ; width of VDU 4 chars in pixels -TCharSizeY # 4 ; height of VDU 4 chars in pixels - -TCharSpacing # 0 -TCharSpaceX # 4 ; horizontal spacing between VDU 4 chars in pixels -TCharSpaceY # 4 ; vertical ------------------""----------------- - -HLineAddr # 4 ; address of exported HLine -GcolOraEorAddr # 4 ; address of FgEcfOraEor etc - -FirPalSetting # 4*28 ; First palette settings (not used on VIDC20) -FirPalAddr * FirPalSetting ; Address of block for first palette setting (only used on VIDC20) -SecPalSetting # 4*28 ; Second palette settings (not used on VIDC20) -SecPalAddr * SecPalSetting ; Address of block for second palette setting (only used on VIDC20) - -TextFgColour # 4 ; Fg/Bg colour stored as a colour number, computed on VDU 18 and re-poked! -TextBgColour # 4 ; - -; In this brave new world there is a pointer to the text expansion -; buffer used for VDU 4 / 5 text plotting. - -; This now lives in the system heap. - -TextExpandArea # 4 ; Pointer to Text expand area (in system heap) -TextExpandArea_Size * (8*1024) - -HSWRSoftCopy # 4 ; soft copy of h.sync width register (for DPMS) -VSWRSoftCopy # 4 ; soft copy of v.sync width register (for DPMS) - -ScreenBlankFlag # 1 ; 0 => unblanked, 1 => blanked -ScreenBlankDPMSState # 1 ; 0 => just blank video - ; 1 => blank to stand-by (hsync off) - ; 2 => blank to suspend (vsync off) - ; 3 => blank to off (H+V off) - [ AssemblingArthur - ! 0,"64 ":CC::STR:@ - ] - AlignSpace 64 - -FgEcfOraEor # 4*16 ; Interleaved zgora & zgeor -BgEcfOraEor # 4*16 ; Interleaved zgora & zgeor -BgEcfStore # 4*16 ; Interleaved zgora & zgeor to store background - -;Current state of pattern -LineDotCnt # 4 ; Count down to restarting pattern -LineDotPatLSW # 4 ; Current state of pattern LSWord -LineDotPatMSW # 4 ; " " " " MSWord - -DotLineLength # 4 ; Dot Pattern repeat length as given in *FX163,242,n - -BBCcompatibleECFs # 4 ; 0 => BBC compatible, 1 => native - -SpAreaStart # 4 ; Start of sprite area -SpChooseName # 16 ; No comment says Richard -SpChoosePtr # 4 - -PointerHeights # 4 ; 4 x 1 byte -PointerActiveXs # 4 ; 4 x 1 byte -PointerActiveYs # 4 ; 4 x 1 byte -PointerShapeNumber # 4 ; only bottom byte used -PointerX # 4 ; co-ordinates of pointer (not always = mouse) -PointerY # 4 - -VIDCControlCopy # 4 ; Soft copy of VIDC control register -VertAdjust # 4 ; offset to add to vertical VIDC registers - -TeletextOffset # 4 ; Offset to current teletext flash bank - -TeletextCount # 4 ; Number of vsyncs till next teletext flash - -WrchNbit # 4 ; Pointer to char code for current mode - -BeepBlock # 8 ; OSWORD block for VDU 7 - -ScreenMemoryClaimed # 1 ; NZ => memory has been claimed or is unusable - - [ AssemblingArthur - ! 0,"16 ":CC::STR:@ - ] - AlignSpace 16 ; Align workspace to 16 bytes - -TTXDoubleCounts # 25 ; Number of double height chars on each line - - [ AssemblingArthur - ! 0,"16 ":CC::STR:@ - ] - AlignSpace 16 ; Align workspace to 16 bytes - -RAMMaskTb # 32*4 ; Copy of MaskTb for this mode (up to 32 words) - - [ AssemblingArthur - ! 0,"16 ":CC::STR:@ - ] - AlignSpace 16 ; Align workspace to 16 bytes - -VduOutputCurrentState # 0 ; values of R0-R3 to return from SwitchOutputToSprite - ; or Mask; next 4 must be in this order -SpriteMaskSelect # 4 ; value of R0 to be given to SWI OS_SpriteOp to set up - ; current state -VduSpriteArea # 4 ; Pointer to sprite area containing VDU output sprite - ; (0 if output is to screen) -VduSprite # 4 ; Pointer to VDU output sprite (0 if output to screen) - -VduSaveAreaPtr # 4 ; Pointer to save area for VDU variables - - - [ AssemblingArthur - ! 0,"16,12 ":CC::STR:@ - ] - AlignSpace 16, 12 ; Make ClipBoxCoords a valid immediate, - ; with ClipBoxEnable immediately before it -ClipBoxInfo # 0 -ClipBoxEnable # 4 ; 0 => clip box disabled, 1 => enabled - -ClipBoxCoords # 0 ; Internal coords of modified area of screen -ClipBoxLCol # 4 -ClipBoxBRow # 4 -ClipBoxRCol # 4 -ClipBoxTRow # 4 - -FgPattern # 4*8 ; foreground pattern as defined by OS_SetColour -BgPattern # 4*8 ; background pattern as defined by OS_SetColour - - [ AssemblingArthur - ! 0,"16 ":CC::STR:@ - ] - AlignSpace 16 ; Align workspace to 16 bytes - -TextExpand # 4*1024 ; Tim's massive text expansion table for whizzy WRCH -; TextPlain is now always hard against the end of TextExpand for this mode - -TTXSoftFonts * TextExpand + 2*1024 ; Soft fonts in teletext mode - - [ AssemblingArthur - ! 0,"64 ":CC::STR:@ - ] - AlignSpace 64 ; Align workspace to 64 bytes - -; Teletext map and copy/move buffer are overlaid - -TTXMapSize * 41*25*4 ; (&1004 bytes) -LargeCommon # TTXMapSize ; the largest area -TTXMap * LargeCommon - -ScrLoaSpriteCB * LargeCommon ; (size = SpriteCBsize + MaxSpritePaletteSize) -ScrLoaBuffer * LargeCommon ; (size = one pixel row) -ScrSavCommon * LargeCommon ; (size = SpriteAreaCBsize + SpriteCBsize - ; + MaxSpritePaletteSize) - -FldQueueSize * ScratchSpaceSize -FldQueueStart * ScratchSpace - - [ AssemblingArthur - ! 0,"64 ":CC::STR:@ - ] - AlignSpace 64 ; Align workspace to 64 bytes - -Font # &700 ; 7 pages of (soft) font - -SaveAreaSize * 12*1024-@ - -VduSaveArea # SaveAreaSize ; save area for switching output to sprites - -VDWSSize # 0 - - ASSERT VDWSSize <= 12 * 1024 - -; ***************************************************************************** -; Space in the first 32K is allocated below -; ***************************************************************************** -; Real workspace definition - -; Basic kernel space - defined locations for external modules - - ^ &100 -IRQ1V # 4 ; &100 - -ESC_Status # 1 ; &104 -LatchBSoftCopy # 1 ; &105 -IOCControlSoftCopy # 1 ; &106 -CannotReset # 1 ; &107 - -IRQsema # 4 ; &108 -MetroGnome # 4 ; &10C -MemorySpeed # 4 ; &110 - -MEMC_CR_SoftCopy # 4 ; &114 -ResetIndirection # 4 ; &118 - -; Now all internal definitions - -; Up to here is initialized on reset - -; Next come handler variables - -MemLimit # 4 -UndHan # 4 -PAbHan # 4 -DAbHan # 4 -AdXHan # 4 - -ErrHan # 4 -ErrBuf # 4 -ErrHan_ws # 4 - -CallAd_ws # 4 ; smart Rs ordering: -CallAd # 4 ; can do LDMIA of r12, pc -CallBf # 4 - -BrkAd_ws # 4 -BrkAd # 4 -BrkBf # 4 - -EscHan_ws # 4 -EscHan # 4 - -EvtHan_ws # 4 -EvtHan # 4 - -; The next lot of workspace is in the space vacated by the small soft CAM map area -; (256 words) which is no longer adequate, so we can reuse it - -JordanWS # 0 -VInitSoftCopy # 4 ; soft copy of VInit so we can set L bit correctly -VEndSoftCopy # 4 ; soft copy of VEnd ------------""--------------- -DAList # 4 ; Pointer to first node on dynamic area list - - AlignSpace 16 ; skipped bit must start on 16-byte boundary - -SkippedTables # 0 -PhysRamTable # 0 ; 6 pairs of words (physaddr, size) indicating - ; RAM present in machine (NB normally you would need at most 5 - ; on IOMD machines, but the extra one is if a soft-loaded ROM image - ; causes a bank to split -VideoPhysAddr # 4 ; Address of video RAM (in the case of DRAM-only machines, -VideoSize # 4 ; this is actually a chunk out of DRAM) -DRAMPhysAddrA # 4 ; Next the DRAM - note that any banks with no memory -DRAMSizeA # 4 ; in them will be omitted from this table, so that -DRAMPhysAddrB # 4 ; eg DRAMPhysAddrA corresponds to the first bank with -DRAMSizeB # 4 ; DRAM in it, not necessarily bank 0 -DRAMPhysAddrC # 4 ; If not all the slots are occupied, then -DRAMSizeC # 4 ; the remaining entries in this table have size fields -DRAMPhysAddrD # 4 ; of zero (and probably addresses of zero too) -DRAMSizeD # 4 -DRAMPhysAddrE # 4 -DRAMSizeE # 4 -PhysRamTableEnd # 0 - -VRAMSize # 4 ; Amount of VRAM (in bytes) (may be more than 2M) -VRAMWidth # 4 ; 0 => no VRAM, 1 => 32-bits wide, 2 => 64-bits wide -VideoBandwidth # 4 ; video bandwidth in bytes/sec -L2PTSize # 4 ; Amount of memory (in bytes) used for static L2PT - ; - this consists of fixed size first bit, plus variable size - ; bit for the free pool L2, which follows directly after it -SoftCamMapSize # 4 ; Amount of memory (in bytes) used for soft CAM map - ; (whole number of pages) -InitKbdWs # 12 ; Workspace for reset keyboard IRQ code - - AlignSpace 16 ; skipped bit must end on 16-byte boundary -SkippedTablesEnd # 0 - -CMOSRAMCache # 240 ; Cache for CMOS RAM -AppSpaceDANode # DANode_NodeSize ; Dummy area node for application space (not on list) -FreePoolDANode # DANode_NodeSize ; Area node for free pool -SysHeapDANode # DANode_NodeSize ; Area node for system heap -CDASemaphore # 4 ; Semaphore for OS_ChangeDynamicArea - non-zero => routine threaded -MMUControlSoftCopy # 4 ; Soft copy of ARM600/700 control register - -AplWorkSize * AppSpaceDANode + DANode_Size - -ProcVec_Start # 0 ; Start of processor vector table -ProcVec_Branch0 # 4 ; Branch through zero -ProcVec_UndInst # 4 ; Undefined instruction vector -ProcVec_SWI # 4 ; SWI vector -ProcVec_PrefAb # 4 ; Prefetch abort vector -ProcVec_DataAb # 4 ; Data abort vector -ProcVec_AddrEx # 4 ; Address exception vector (not useful on ARM600/700) -ProcVec_IRQ # 4 ; IRQ vector -ProcVec_End # 0 - -ProcVecPreVeneersSize * 4*4 ; Space for preveneers for loading handler addresses from 0 page. -ProcVecPreVeneers # ProcVecPreVeneersSize - - ASSERT @ <= &500 ; a convenient address to remember - # (&500-@) - -CamMapCorruptDebugBlock # &40 ; somewhere to dump registers in case of emergency - - ASSERT @ <= JordanWS+256*4 - # (JordanWS+256*4-@) ; pad out to original size - -CamEntriesPointer # 4 ; points to where CAM soft copy is - ; (CamEntries for machines up to 8MBytes, - ; CamEntriesForBigMachines for larger machines) - -MaxCamEntry # 4 ; maximum index into the cam map, ie - ; 511 for 16MByte machines, 383 for 12MBytes - ; 255 for 8MBytes, otherwise 127 - -RAMLIMIT # 4 - - # 4 ; dummy slot where AplWorkSize used to be - -HiServ_ws # 4 -HiServ # 4 -SExitA # 4 -SExitA_ws # 4 -UpCallHan_ws # 4 -UpCallHan # 4 - -ROMModuleChain # 4 ; pointer to head of ROM module chain - -; now a section that it's handy to have in simply loadable places - - [ AssemblingArthur - ! 0,"16 ":CC::STR:@ - ] - AlignSpace 16 - -KeyWorkSpaceSize * &200 -KeyWorkSpace # KeyWorkSpaceSize - -; The following were reordered on 26-Jul-91. Old ordering was: -; GeneralMOSBuffer -; ModuleSWI_HashTab -; Module_List -; Curr_Active_Object -; VecPtrTab -; ExceptionDump - -ModuleSHT_Entries * 16 -ModuleSWI_HashTab # 4*ModuleSHT_Entries - -Module_List # 4 -Curr_Active_Object # 4 - -; Vector Claim & Release tables etc - -VecPtrTab # NVECTORS * 4 - -ExceptionDump # 4 - -; GeneralMOSBuffer: re-use with caution! -; Here's just some of the users: -; user use(s) -; default error handler error buffer (must be 246+4 bytes big) -; *If expression to be evaluated to control the *If -; Command line to be submited on the expression -; evaluating to non-zero (the THEN clause). -GeneralMOSBuffer # 256+4 - - [ AssemblingArthur - ! 0,"16 ":CC::STR:@ - ] - AlignSpace 16 ; Ensures we can MOV rn, #OsbyteVars if <=&1000 - -OsbyteVars # OSBYTEVarSize - ASSERT OsbyteVars < &10000 ; Must keep in first 64K so address can be read by - ; (and stored in) OS_Bytes &A6,&A7. SKS - -; These must be in first 4K -NBuffers * 10 -BuffInPtrs # 4 * NBuffers -BuffOutPtrs # 4 * NBuffers - -VariableList # 4 - -; Oscli stuff -OscliCBtopUID # 4 -OscliCBbotUID # 4 -OscliCBcurrend # 4 - -ReturnCode # 4 -RCLimit # 4 - -SpriteSize # 4 ; saved on startup for Sprite code and RAMFS -RAMDiscSize # 4 -FontCacheSize # 4 ; and font manager - -TickNodeChain # 4 - -; Workspace - -EnvTime # 5 -RedirectInHandle # 1 -RedirectOutHandle # 1 -MOShasFIQ # 1 -FIQclaim_interlock # 1 -CallBack_Flag # 1 -IRQ_CallBack_Flag * CallBack_Flag -IOSystemType # 1 ; 0 => old I/O subsystem, 1 => IOEB+82C710 system, 2..255 => ? -MonitorLeadType # 1 ; some function of the monitor lead inputs, as yet undetermined - - AlignSpace - -EnvString # 256 - - -DUMPER # 16 * 4 - -; more system workspace -Page_Size # 4 -PIRQ_Chain # 4 -PFIQasIRQ_Chain # 4 - -; !!!! Free space (752 bytes) left by old IRQ despatch (new IRQ despatch -; !!!! moved as it required more space). -OldIRQ1Vspace # 752 - - -CallBack_Vector # 4 - -; interruptible heap manager workspace - -HeapSavedReg_R0 # 4 -HeapSavedReg_R1 # 4 -HeapSavedReg_R2 # 4 -HeapSavedReg_R3 # 4 -HeapSavedReg_R4 # 4 -HeapSavedReg_R13 # 4 -HeapReturnedReg_R0 # 4 -HeapReturnedReg_R1 # 4 -HeapReturnedReg_R2 # 4 -HeapReturnedReg_R3 # 4 -HeapReturnedReg_R4 # 4 -HeapReturnedReg_R13 # 4 -HeapReturnedReg_PC # 4 ; also acts as interlock - -PrinterBufferAddr # 4 ; holds address of printer buffer -PrinterBufferSize # 4 ; size of printer buffer - not to be confused with PrintBuffSize - ; which is the (constant) default size for the MOS's smallish buffer -RawMachineID # 8 ; 64 bits for unique machine ID -KernelMessagesBlock # 20 ; 5 Words for messagetrans message block. -ErrorSemaphore # 1 ; Error semaphore to avoid looping on error translation. -PortableFlag # 1 ; Non-zero => got an error from Portable_Speed, so don't try it again - - AlignSpace - -MOSConvertBuffer # 12 ; Enough romm for 8 hex digits. -AbortIndirection # 4 ; Pointer to list of addresses and trap routines -PreVeneerRegDump # 17*4 ; room for r0-r15, spsr - - [ AssemblingArthur - ! 0, "low space free ":CC::STR:(&FEC-@) - ] - ASSERT @ < &FEC - -; Words for old tools of assorted varieties - ^ &FEC -; ECN 17-Feb-92 -; Added RISCOSLibWord and CLibWord. The ROM RISCOSLib and CLib must continue -; to work even when they are killed since ROM apps are hard linked to the -; ROM libraries. They cannot use the private word since the block pointed -; to by this will be freed. -RISCOSLibWord # 4 -CLibWord # 4 -FPEAnchor # 4 -DomainId # 4 ; SKS added for domain identification -Modula2_Private # 4 ; MICK has FFC and uses it it in USR mode - -VduDriverWorkSpace # VDWSSize - ASSERT (VduDriverWorkSpace :AND: 63) = 0 ; For Tim (VDU5) - - - [ AssemblingArthur - ! 0, "high space free ":CC::STR:(&4000-@) - ] - - ^ &4000 -ScratchSpaceSize * &4000 -ScratchSpace # ScratchSpaceSize - - ASSERT @ <= &8000 ; Start of apl - -; ***************************************************************************** -; Users of ScratchSpace declare yourself here: - -; NRaine: Filling a polygon uses ScratchSpace to flatten the path - -; DSeal: Draw module uses ScratchSpace on fill operations (this supercedes -; NRaine's declaration above). - -; SKS: HeapSort with (r1 & 0x80000000) & ~(r1 & 0x20000000) & (r5 <= 16K) -; uses ScratchSpace as a temp slot for data shuffling after sorting - -; TMD: Flood fill uses ScratchSpace for the flood queue. - -; Tidying the RMA uses ScratchSpace while all modules are dead - -; GSTRANS workspace: GSINIT puts state into the workspacem and GSREAD uses it. -; DO NOT do any operations between GSINIT/GSREAD SWIS. -; SWIs called: OSWord in time var code -; BinaryToDecimal, ReadUnsigned - -; LVR: ADFS uses scratch space to format floppies on 1772 based machines - -; DDV: ColourTrans uses scratch space to build palette tables when in -; ColourTrans_SelecTable/RetrunColourNumber and also whilst generating -; stipple pattterns. - -GSVarWSpace * ScratchSpace - - ^ 0 -GSNameBuff # &100 -GS_Stack # &200 -GS_StackPtr_Lim * &200 / 4 ; Number of words in stack. -GS_StackPtr # 4 - - ^ @ + ScratchSpace - -; Pointers for SubstituteArgs: no external calls. -; Ensure these don't overlap FileSwitch's buffers below! - -MacExStartPtrs # 44 -MacExEndPtrs # 44 - -; OS_CLI has a buffer for alias expansion: ReadVarVal and SubstituteArgs -; are called while the buffer is held. Also used for module prefixes: -; Module called twice in this case. - -AliasExpansionBuffer # 100 - -; *list/*type need an argument expansion buffer: ReadArgs called with it. - -ArgumentBuffer * AliasExpansionBuffer - -; EvaluateExpression space. Calls ReadUnsigned, BinaryToDecimal and ReadVarVal. - -ExprWSpace * @ - - ^ 0, R12 -ExprBuff # &100 -exprBracDif # 2 ; keep exprSTRACC aligned -tos_op # 2 ; 1 byte for use as STRACC-1 -ExprSVCstack # 4 -exprSTRACC * @ - ExprBuff + ExprWSpace - -ExprStackLimit * exprSTRACC + &100 -ExprStackStart * ScratchSpace + ScratchSpaceSize - - -; Tutu needs some for argument substitution + expansion for run/load types -; Only OS call during xform is XOS_SubstituteArgs and XOS_Heap(Claim,SysHeap) - - ^ 0 ; Offset from ScratchSpace -rav_substituted # 256 -rav_arglist # 256 - -TopOfPageZero # 0 - - ^ &8000 ; The actual top of Page Zero -EconetDebugSpace |#| &20 * 4 ; Thirty two words (&7F80) - - ASSERT @ > TopOfPageZero ; Make sure we don't clash - -; ***************************************************************************** -; *** Cursor, Sound DMA, SWI, and OSCLI workspace. *** -; *** Sits in the 32K above 31M, ie. &01F000000..&01F07FFF *** -; *** Has the physical address &02078000, ie. 32M + 512K - 32K *** -; ***************************************************************************** - -TopOfDMAPhysRAM * &80000 ; OFFSET in physram -TopOfDMAWorkSpace * CursorChunkAddress + 32*1024 -OffsetLogicalToPhysical * TopOfDMAPhysRAM - TopOfDMAWorkSpace - - ^ TopOfDMAWorkSpace ; Note we will be going down - -; Sound - -SoundWorkSpaceSize * &1000 -SoundDMABufferSize * &1000 -SoundEvtSize * &1000 -SoundDMABuffers |#| SoundDMABufferSize * 2 -SoundWorkSpace |#| SoundWorkSpaceSize + SoundEvtSize - -; Cursor - -CursorDataSize * &800 -CursorData |#| CursorDataSize -CursorSoundRAM * CursorData -CursorSoundPhysRAM * CursorSoundRAM + OffsetLogicalToPhysical - -; SWI despatcher - -BranchToSWIExit |#| 4 -SvcTable |#| &400 - ASSERT SvcTable = &01F033FC ; Required for SVC table pokers, 1.20 compatible -SWIDespatch_Size * 29*4 -SWIDespatch |#| SWIDespatch_Size - - -; Buffers - -KeyBuffSize * &100 -RS423InBuffSize * &100 -RS423OutBuffSize * &C0 -PrintBuffSize * &400 -Sound0BuffSize * 4 -Sound1BuffSize * 4 -Sound2BuffSize * 4 -Sound3BuffSize * 4 -SpeechBuffSize * 4 -MouseBuffSize * &40 -KeyBuff |#| KeyBuffSize -RS423InBuff |#| RS423InBuffSize -RS423OutBuff |#| RS423OutBuffSize -PrintBuff |#| PrintBuffSize -Sound0Buff |#| Sound0BuffSize -Sound1Buff |#| Sound1BuffSize -Sound2Buff |#| Sound2BuffSize -Sound3Buff |#| Sound3BuffSize -SpeechBuff |#| SpeechBuffSize -MouseBuff |#| MouseBuffSize - -; Oscli buffering - -OscliBuffSize * &100 -OscliNoBuffs * 16 -OscliCircBuffLimit |#| 0 -OscliCircBuffStart |#| OscliBuffSize * OscliNoBuffs -RedirectBuff |#| OscliBuffSize - -; Default IRQ despatch moved here as a result of IOMD having an extra -; 6 interrupts for I/O and sound DMA (this is really IOMD specific, not -; ARM600/700 specific but for the moment it is assumed that they are -; used on the same machines). -DefIRQ1Vspace * 12*4+12*23+2*256+64 ; for size checking in MOS -DefaultIRQ1V |#| DefIRQ1Vspace - - [ AssemblingArthur - ! 0, "Aligning IRQ stack from ":CC::STR:@ - ] - [ @-7*4 :AND: 15 <> 0 - |#| (@-7*4):AND:15 - ] -IRQSTK # 0 ; Overflow will give abort - [ AssemblingArthur - ! 0, "IRQ stack size ":CC::STR:(IRQSTK-CursorChunkAddress) - ] - - ASSERT @ > ( CursorChunkAddress + &1000 ) ; Check minimum stack - -; ***************************************************************************** -; High system workspace -; ***************************************************************************** - - ^ SysHeapChunkAddress - - # 8*1024 ; svcstk size. Overflow will give abort -SVCSTK # 0 -SysHeapStart # 0 - - - OPT OldOpt - END diff --git a/hdr/Options b/hdr/Options deleted file mode 100644 index 2f286153..00000000 --- a/hdr/Options +++ /dev/null @@ -1,494 +0,0 @@ -; Copyright 2000 Pace Micro Technology plc -; -; 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. -; -; amg 7/12/96 Renaissance -; Forcibly ensure that options only intended for one class of platform -; stay there. Generally this involves combining switches with the STB -; switch. The exception is processor architectural stuff. 7500FE is -; included always, and StrongARM has an independed switch. -; -; When you want to migrate features from one platform to another you'll -; find that every occurence of feature switches has been qualified with -; the appropriate sense of the STB switch. This is to remind you to think -; about what you're about to do! Check whether the code actually will work -; at all on something that is or is not a STB class product. -; -; Using the STB switch this aggressively also help ensure that there's -; no unexpected code crossover in the initial merge. - -; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; now the conditional flags for the version we want -; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - GBLL CacheOff -CacheOff SETL {FALSE} - -; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; essential global variables -; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - GET Version - GBLS VersionNo - [ Module_MinorVersion = "" :LOR: :LNOT: STB -VersionNo SETS "$VString ($Date)" - | -VersionNo SETS "$VString ($Date) $Module_MinorVersion" - ] - -; SystemName moved to Machine.* header files. - - GBLS MosTitle -MosTitle SETS "$SystemName $VersionNo" - - GBLL AddTubeBashers -AddTubeBashers SETL {FALSE} - -Tube_Normal * 1 -Tube_Simulator * 2 - - GBLA TubeType -TubeType SETA Tube_Simulator - -UserMemStart * &8000 - - GBLL ExceptionsAreErrors -ExceptionsAreErrors SETL 1=1 - -AssemblingArthur SETL {TRUE} -; defined in hdr.system to allow conditionals in macros - - GBLL DoingVdu -DoingVdu SETL {FALSE} ; so can get KeyWS! - GBLL Module -Module SETL {FALSE} - - GBLL IncludeTestSrc ; whether test code is included -IncludeTestSrc SETL :LNOT: HAL - -;RISC OS 3.71 onwards assumed bus timings - if true, then ROM speeds atc are assumed according to IOMD ID regs. as follows: -; if IOMD (Risc PC) ROM ticks 5-3 (assumed bus 32 MHz) -; if 7500 (A7000) ROM ticks 5-3 (assumed bus 32 MHz), all clocks divide-by-1 -; if 7500FE (A7000+) ROM ticks 5-3,half speed (asssumed bus 64 MHz), EDO memory, divide-by-2 I/O, divide-by-1 CPU and memory -; - GBLL RO371Timings -RO371Timings SETL :LNOT: STB - -; For development on Customer M hardware only - GBLL ParallelFlashUpgrade -ParallelFlashUpgrade SETL {FALSE} - -;whether we support running on the (Risc PC) emulator - GBLL EmulatorSupport -EmulatorSupport SETL {TRUE} - - [ :LNOT: RO371Timings - - GBLL NormalSpeedROMS - [ STB -NormalSpeedROMS SETL {TRUE} ;use FALSE for slow EPROMS - | -NormalSpeedROMS SETL {FALSE} ;use FALSE for slow EPROMS - ] - - GBLL AutoSpeedROMS -AutoSpeedROMS SETL {TRUE} :LAND: :LNOT: STB - - GBLL RISCPCBurstMode -RISCPCBurstMode SETL {FALSE} -;>>>RCM says if the FRM approves the use of burst mode ROMS for -;>>>RISC PC (no reason why it shouldn't) all references to RISCPCBurstMode -;>>>could be replaced by NormalSpeedROMS - - ] ; :LNOT:RO371Timings - - GBLL DoInitialiseMode -DoInitialiseMode SETL {TRUE} :LAND: STB - - [ STB - GBLL Select16BitSound ; STBs and pre-IOMD systems don't have this link -Select16BitSound SETL {FALSE} - | - GBLL Select16BitSound -Select16BitSound SETL {TRUE} - ] - GBLL Japanese16BitSound -Japanese16BitSound SETL {TRUE} :LAND: STB - - GBLL ChopOffTheGoolies -ChopOffTheGoolies SETL {FALSE} - - GBLL ChecksumCMOS -ChecksumCMOS SETL {TRUE} - - GBLL SqueezeMods ; whether squeezed modules are allowed -SqueezeMods SETL {TRUE} - - GBLL International ; whether text and error messages come from messages file. -International SETL {TRUE} - - GBLL CacheCommonErrors ; whether common internationalised errors are cached in sysheap -CacheCommonErrors SETL International :LAND: {TRUE} - - GBLL MouseBufferManager ; Whether mouse uses buffer manager -MouseBufferManager SETL {TRUE} - - GBLL IrqsInClaimRelease ; Whether OS_Claim/Release restore IRQ's before releasing heap node -IrqsInClaimRelease SETL {TRUE} - - GBLL TickIrqReenter ; Whether TickEventChain processing re-enables IRQ's -TickIrqReenter SETL {TRUE} - - GBLL SoftResets ; If false, always force a hard reset -SoftResets SETL {FALSE} - - GBLL AlwaysClearRAM ; If true, clear RAM on every break/reset -AlwaysClearRAM SETL {TRUE} - - GBLL CacheCMOSRAM ; Whether to keep a RAM copy of CMOS RAM for faster access -CacheCMOSRAM SETL {TRUE} - - GBLL LCDInvert -LCDInvert SETL {TRUE} :LAND: :LNOT: STB - - GBLL ModeSelectors ; whether mode selectors are understood -ModeSelectors SETL {TRUE} - - GBLL MakeModeSelectorsForModeNumbers -MakeModeSelectorsForModeNumbers SETL ModeSelectors :LAND: {FALSE} ; not actually needed after all - - GBLL IgnoreVRAM ; if true, don't add VRAM to the RAM list (+ don't use for screen) -IgnoreVRAM SETL {FALSE} - - GBLL UseGraphicsV ; if true, use GraphicsV, rather than going straight -UseGraphicsV SETL {TRUE} ; to the hardware (or HAL) - - GBLL LateAborts ; if true, use late abort mode on ARM600 (compulsory on ARM700) -LateAborts SETL {TRUE} - - GBLL ShrinkableDAs ; if true, support Shrinkable Dynamic Areas (eg. CacheFS) -ShrinkableDAs SETL {TRUE} - - GBLL ShadowROM ; if true, the ROM is mirrored above -ShadowROM SETL {FALSE} ; &FF800000 - - GBLL Interruptible32bitModes -Interruptible32bitModes SETL {TRUE} ;if true, limited 32-bit mode code support (interrupt handler does not assume - ; 26-bit foreground), also allows faster, 32-bit APCS version of FPEmulator - - GBLL GSWorkspaceInKernelBuffers ; Move gstrans workspace into the kernel buffers area to fix redirection -GSWorkspaceInKernelBuffers SETL {TRUE} ; and everything else that suffers from the dodgy use of scratch space. - - - GBLL EarlierReentrancyInDAShrink -EarlierReentrancyInDAShrink SETL {TRUE} ; fix for RAMFS and new FileCore (causes reentrant DA shrink/remove) - - GBLL OnlyKernelCanAccessHardwareVectors -OnlyKernelCanAccessHardwareVectors SETL {TRUE} ; if true, only the Kernel is permitted to write to the hardware vectors - ; while in 26-bit mode. If false, the whole ROM can (including BASIC - ; and the Shared C Library - eg any memcpy!) - - GBLL LongCommandLines ; first introduced for Ursula, merged into HAL kernel -LongCommandLines SETL {TRUE} - [ LongCommandLines -LongCLISize * 1024 ; buffer size for long commands - ] - - GBLL StrongARM - GBLL SAcleanflushbroken ;whether StrongARM single MCR for DC clean+flush broken (is always for SA110) - GBLL SASTMhatbroken ;whether ROM must support SA110's with broken STM^ (revision 3 should fix this) - GBLL StrongARM_POST ;whether to run POST for StrongARM (and possibly ARM8) - - GBLL ARM6support - GBLL XScaleMiniCache ;is the XScale mini data-cache used (at all) - GBLL XScaleJTAGDebug - GBLL ECC ;use ECC on XScale. May compromise other ARM compatibility - -StrongARM SETL {TRUE} -SAcleanflushbroken SETL {TRUE} :LAND: StrongARM -SASTMhatbroken SETL {TRUE} :LAND: StrongARM -StrongARM_POST SETL {TRUE} :LAND: StrongARM - -ARM6support SETL {TRUE} - -XScaleMiniCache SETL {FALSE} - -XScaleJTAGDebug SETL {TRUE} - -ECC SETL {FALSE} - - - ;mjs - ;concept of sparsely mapped dynamic areas introduced for Ursula - GBLL DA_Batman ;Holey dynamic areas Batman! - - ;mjs - ;Chocolate flavours implemented for Ursula, but they are generally useful performance enhancements - ;(not all Ursula performance improvements are flagged with Chocolate - eg. simple changes such as slicker SWI - ;despatch and wider SWI hashing) - ; - ;any ARM - ; - GBLL ChocolateSysHeap ;whether to save cost of SysHeap block claim/release for common cases (eg. callback blocks) - ;also reduces SysHeap stress by using fewer blocks in total - GBLL ChocolateOSMod ;whether to reduce SysHeap stress in module handling - GBLL ChocolateSysVars ;whether to do performance improvements in system variable handling - GBLL ChocolateOscli ;whether to do performance improvements in Oscli command stuff - GBLL ChocolateService ;whether to implement fast module service call distribution (uses table introduced - ;into module format by Ursula API) - - ;possibly enabled at run time for some ARMs only - ; - GBLL ChocolateAMB ;whether to compile support for Lazy task swapping - -DA_Batman SETL {TRUE} - -ChocolateSysHeap SETL {TRUE} -ChocolateOSMod SETL {TRUE} -ChocolateSysVars SETL {TRUE} -ChocolateOscli SETL {TRUE} -ChocolateService SETL {TRUE} -ChocolateAMB SETL {TRUE} :LAND: No26bitCode ; not implemented for 26bit kernel at present - [ ChocolateSysHeap - GBLA MaxChocolateCBBlocks ;max quick CallBack blocks available at any one time (else ordinary heap nodes used) - GBLA MaxChocolateSVBlocks ;max quick Software Vector blocks available at any one time (else ordinary heap nodes used) - GBLA MaxChocolateTKBlocks ;max quick Ticker blocks available at any one time (else ordinary heap nodes used) - GBLA MaxChocolateMRBlocks ;max module ROM blocks before ordinary heap nodes are used (reduces total no. nodes in SysHeap) - GBLA MaxChocolateMABlocks ;max module Active blocks before ordinary heap nodes are used - GBLA MaxChocolateMSBlocks ;max module SWI Hash blocks before ordinary heap nodes are used -MaxChocolateCBBlocks SETA 32 -MaxChocolateSVBlocks SETA 128 -MaxChocolateTKBlocks SETA 32 -MaxChocolateMRBlocks SETA 150 -MaxChocolateMABlocks SETA 150 -MaxChocolateMSBlocks SETA 150 - ] - - GBLL Oscli_QuickAliases - GBLL Oscli_HashedCommands -Oscli_QuickAliases SETL {TRUE} :LAND: ChocolateOscli ;try to do a better job of checking for aliases -Oscli_HashedCommands SETL {TRUE} :LAND: ChocolateOscli ;try to do a better job of finding commands - - - GBLL VCOstartfix ;code in early kernel to fix VCO start problem on A7000 (esp. 7500FE) -VCOstartfix SETL {TRUE} - - - GBLL mjsServiceTrace ;for statistics gathering on service calls only -mjsServiceTrace SETL {FALSE} - GBLL mjsSysHeapNodesTrace ;for statistics gathering on some SysHeap nodes only -mjsSysHeapNodesTrace SETL {FALSE} - - GBLL NoSPSRcorruption ;set to true if IRQ dispatcher -NoSPSRcorruption SETL {FALSE} ;preserves SPSR_SVC - - GBLL CheckProtectionLink ; if true, disallow CMOS RAM changes if link in protected position -CheckProtectionLink SETL {TRUE} ; NB affects Delete/Copy/R/T and 0-9/. - - GBLL RMTidyDoesNowt ; if true, RMTidy does nothing -RMTidyDoesNowt SETL {TRUE} ; should really be "machine has FSLock in ROM" - - GBLL RogerEXEY ; if true, use Roger's new algorithm for XEigFactor, YEigFactor -RogerEXEY SETL {FALSE} ; Marketing don't like it! - - GBLL DebugROMInit -DebugROMInit SETL {FALSE} - - GBLL DebugROMPostInit ; Displays when the PostInit service call is sent to each ROM module (currently works on vanilla service call handling only) -DebugROMPostInit SETL (:LNOT: ChocolateService) :LAND: {FALSE} - - GBLL DebugROMErrors -DebugROMErrors SETL {FALSE} - - GBLL DebugTerminal ; default WRCH and RDCH through HAL -DebugTerminal SETL {FALSE} - - GBLL DebugHALTX -DebugHALTX SETL {FALSE} - - GBLL DebugHeaps ; initialise claimed and freed blocks -DebugHeaps SETL {FALSE} ; (may slow things down unacceptably) - [ DebugHeaps - ! 0, "*** WARNING *** Heap debugging assembled in" - ] - -; ChangeDynamicArea and related options - - GBLL DebugCDA -DebugCDA SETL {FALSE} - - GBLL DebugCDA2 -DebugCDA2 SETL {FALSE} - - GBLL StorkPowerSave ;True => power saving for Stork AND A4 -StorkPowerSave SETL MorrisSupport ;False=> older A4 code only - - GBLL LCDSupport ;Whether LCD Support is assembled in or not -LCDSupport SETL {TRUE} :LAND: :LNOT: STB - ;(First intro'd for Stork) - - GBLL FixR9CorruptionInExtensionSWI ; whether R9 corruption by ExtensionSWI handler is fixed -FixR9CorruptionInExtensionSWI SETL No26bitCode ; currently FALSE as CC's !SpellMod (possibly others) rely on it being broken - - GBLL FixCallBacks ; see Docs.CallbackChange -FixCallBacks SETL {TRUE} ; also addresses some atomicity problems - - GBLL InterlacedPointer -InterlacedPointer SETL {TRUE} :LAND: STB ; enable code to do proper interlaced pointer - - GBLL ValidateCMOS ; Apply special CMOS-corruption detection code, -ValidateCMOS SETL {TRUE} ; and do minimal default settings. - - GBLS GetMessages - [ International -GetMessages SETS "GET s.MsgCode" - | -GetMessages SETS "" - ] - - GBLL DebugForcedReset ; debug forced hard resets -DebugForcedReset SETL {FALSE} - - GBLA ConfiguredLang -ConfiguredLang SETA 11 ; default configured language - - GBLA FirstUnpluggableModule -FirstUnpluggableModule SETA 8 ; Podule, FileSwitch, ResourceFS, Messages, MessageTrans, - ; TerritoryManager, UKTerritory - - [ DebugForcedReset -Reset_CannotResetFlag * 1 -Reset_SysHeapCorrupt * 2 -Reset_WrongCamMapAddress * 3 -Reset_WrongNumberOfPages * 4 -Reset_CamMapCorrupt * 5 -Reset_VectorChainCorrupt * 6 -Reset_TickNodesCorrupt * 7 -Reset_DeviceVectorCorrupt * 8 -Reset_PoduleOrCallBackCorrupt * 9 - ] - -; Flags for RISC OS Blue changes -; - GBLL AssembleKEYV -AssembleKEYV SETL {TRUE} ; Use KEYV. - GBLL AssemblePointerV -AssemblePointerV SETL {TRUE} ; Use PointerV. - GBLL PollMouse -PollMouse SETL {FALSE} ; Poll mouse. - - GBLL ProcessorVectors -ProcessorVectors SETL {TRUE} ; Processor vectors indirected through 0 page. - - GBLS GetUnsqueeze - [ SqueezeMods -GetUnsqueeze SETS "GET s.Unsqueeze" - | -GetUnsqueeze SETS "" - ] - GBLS GetFlashROM - [ ParallelFlashUpgrade -GetFlashROM SETS "GET s.FlashROM" - | -GetFlashROM SETS "" - ] - GBLS GetKernelMEMC - GBLS GetPalette - GBLS GetMemInfo - GBLS GetHAL -GetKernelMEMC SETS "GET s.ARM600" -GetMemInfo SETS "GET s.MemInfo" - -GetPalette SETS "GET s.vdu.vdupalxx" - [ HAL -GetHAL SETS "GET s.HAL" - | -GetHAL SETS "" - ] - - - GBLS GetKbdDrA1 - [ Keyboard_Type = "A1A500" -GetKbdDrA1 SETS "GET s.PMF.KbdDrA1" - | -GetKbdDrA1 SETS "" - ] - - GBLS GetKbdRes - [ :LNOT: HAL - [ Keyboard_Type = "A1A500" -GetKbdRes SETS "GET s.KbdResA1" - | -GetKbdRes SETS "GET s.KbdRes" :CC: Keyboard_Type - ] - ] - -; control switches for med_00001 (the flood fill routines 1024 line limit). -; Switches have the following effects: -; -; _userma Will use rma if >48K is free, up to a maximum of 128K. It will -; try to acheive the latter by growing the rma if possible. -; _twowords Use two word entries in the queue. This overcomes the limitation -; of the original packed word format. -; _debug Store the queue start, end and 'amount to change the rma dynamic -; area by' in the first three words of OldIRQ1VSpace - - GBLL med_00001_userma - GBLL med_00001_twowords - GBLL med_00001_debug - -med_00001_userma SETL {TRUE} -med_00001_twowords SETL {TRUE} -;med_00001_debug SETL {TRUE} - -;med_00001_userma SETL {FALSE} -;med_00001_twowords SETL {FALSE} -med_00001_debug SETL {FALSE} - - [ med_00001_userma -smallest_rma_size * (48*1024) ; define the low threshold for rma use -largest_rma_size * (128*1024) ; and the ceiling for rma use - ] - - [ med_00001_debug - ! 0,"" - ! 0,",-----------------------------------------------------------------," - ! 0,"| **** WARNING **** |" - ! 0,"| |" - ! 0,"| Audit trail debugging for MED-00001 is enabled. This reuses the |" - ! 0,"| first three words of OldIRQ1Vspace. This should be turned off |" - ! 0,"| once MED-00001 has been tested and marked 'fixed'. |" - ! 0,"| |" - ! 0,"| Usage: |" - ! 0,"| +0 start of area used by flood fill |" - ! 0,"| +4 end+1 of area used by flood fill |" - ! 0,"| +8 amount the rma was grown by |" - ! 0,"'-----------------------------------------------------------------'" - ! 0,"" - ] - -; Ickle macros. We want to be able to turn IRQs on and off fast in the -; code in various places. To do this easily, have a name for the -; SVC26/32 mode we run in. - - [ No26bitCode -USR2632 * USR32_mode -SVC2632 * SVC32_mode - | -USR2632 * USR26_mode -SVC2632 * SVC26_mode - ] - -MaxSwi * OS_HeapSort32+1 - - END diff --git a/hdr/PublicWS b/hdr/PublicWS deleted file mode 100644 index 5d9c772e..00000000 --- a/hdr/PublicWS +++ /dev/null @@ -1,94 +0,0 @@ -; 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 > Public Work Space - -OldOpt SETA {OPT} - OPT OptNoList+OptNoP1List - -; *********************************** -; *** C h a n g e L i s t *** -; *********************************** - -; Date Name Description -; ---- ---- ----------- -; 15-Jun-94 AMcC Created - holds values 'exported' from KernelWS -; Corresponds to Values previously set in VickySpace / NewSpace -; 03-Nov-94 AMcC Added ScreenBlankFlag and ScreenBlankDPMSState -; 12-Jul-95 JRH Added RestType -; -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; Memory map values: (in address order) - - ^ &00000104 -ESC_Status # 1 - - ^ &00000105 -LatchBSoftCopy # 1 - - ^ &00000107 -CannotReset # 1 - - ^ &00000108 -IRQsema # 4 - - ^ &00000114 -MEMC_CR_SoftCopy # 4 - - ^ &00000300 -DebuggerSpace # 8*16 - - ^ &0000047C -ScreenBlankFlag # 1 ; 0 => unblanked, 1 => blanked - - ^ &0000047D -ScreenBlankDPMSState # 1 ; 0 => just blank video - ; 1 => blank to stand-by (hsync off) - ; 2 => blank to suspend (vsync off) - ; 3 => blank to off (H+V off) - ^ &00000480 -FgEcfOraEor # 4*16 ; Interleaved zgora & zgeor (from Vdu Driver Workspace) - - ^ &000004C0 -BgEcfOraEor # 4*16 ; Interleaved zgora & zgeor (from Vdu Driver Workspace) - - ^ &00000AE1 ; RedirectInHandle -RedirectInHandle # 1 - - ^ &00000AE2 ; RedirectOutHandle -RedirectOutHandle # 1 - - ^ &00000FF8 -DomainId # 4 ; domain identification - - ^ &00001000 -VduDriverWorkSpace # &3000 - - ^ &00004000 -ScratchSpace # &4000 - - [ {FALSE} - ^ &01F04000 - | - ^ &FAFF4000 - ] -SoundWorkSpace # &2000 - -SoundDMABufferSize * &1000 - -SoundDMABuffers # SoundDMABufferSize * 2 - - - OPT OldOpt - END diff --git a/hdr/RISCOS b/hdr/RISCOS deleted file mode 100644 index b6c834e6..00000000 --- a/hdr/RISCOS +++ /dev/null @@ -1,395 +0,0 @@ -; Copyright 2008 Castle Technology 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. -; -; This header file is autogenerated from the files maintained by the -; RISC OS allocations manager and should not be edited by anyone else. - - SUBT Definitions relating to the basic RISCOS kernel ==> Hdr:RISCOS - -OldOpt SETA {OPT} - OPT OptNoList+OptNoP1List - -; SWI names are exported in two forms : -; 1) with OS_ 'OS_DoThingToOtherThing' as N -; 2) with XOS_ 'XOS_DoThingToOtherThing' as N + Auto_Error_SWI_bit - -Auto_Error_SWI_bit_number * 17 -Auto_Error_SWI_bit * 1 :SHL: Auto_Error_SWI_bit_number - -SWIClass SETS RISCOS_Kernel_0SWI_Name - - ^ RISCOS_Kernel_0SWI_Base - AddSWI WriteC ; &00 - AddSWI WriteS ; &01 - AddSWI Write0 ; &02 - AddSWI NewLine ; &03 - AddSWI ReadC ; &04 - AddSWI CLI ; &05 - AddSWI Byte ; &06 - AddSWI Word ; &07 - AddSWI File ; &08 - AddSWI Args ; &09 - AddSWI BGet ; &0A - AddSWI BPut ; &0B - AddSWI GBPB ; &0C - AddSWI Find ; &0D - AddSWI ReadLine ; &0E - AddSWI Control ; &0F - AddSWI GetEnv ; &10 - AddSWI Exit ; &11 - AddSWI SetEnv ; &12 - AddSWI IntOn ; &13 - AddSWI IntOff ; &14 - AddSWI CallBack ; &15 - AddSWI EnterOS ; &16 - AddSWI BreakPt ; &17 - AddSWI BreakCtrl ; &18 - AddSWI UnusedSWI ; &19 - AddSWI UpdateMEMC ; &1A - AddSWI SetCallBack ; &1B - AddSWI Mouse ; &1C - AddSWI Heap ; &1D ; Our new ones start here - AddSWI Module ; &1E - AddSWI Claim ; &1F ; PMF's vector handling - AddSWI Release ; &20 ; routines - AddSWI ReadUnsigned ; &21 ; Read an unsigned number - AddSWI GenerateEvent ; &22 - AddSWI ReadVarVal ; &23 ; read variable value & type - AddSWI SetVarVal ; &24 ; set variable value & type - AddSWI GSInit ; &25 - AddSWI GSRead ; &26 - AddSWI GSTrans ; &27 - AddSWI BinaryToDecimal ; &28 - AddSWI FSControl ; &29 - AddSWI ChangeDynamicArea ; &2A - AddSWI GenerateError ; &2B - AddSWI ReadEscapeState ; &2C - AddSWI EvaluateExpression ; &2D - AddSWI SpriteOp ; &2E - AddSWI ReadPalette ; &2F ; (was FontManager) - AddSWI ServiceCall ; &30 ; was Claim_Release_FIQ - AddSWI ReadVduVariables ; &31 - AddSWI ReadPoint ; &32 - AddSWI UpCall ; &33 - AddSWI CallAVector ; &34 ; was ReadCurrentError - AddSWI ReadModeVariable ; &35 - AddSWI RemoveCursors ; &36 - AddSWI RestoreCursors ; &37 - AddSWI SWINumberToString ; &38 - AddSWI SWINumberFromString ; &39 - AddSWI ValidateAddress ; &3A - AddSWI CallAfter ; &3B - AddSWI CallEvery ; &3C - AddSWI RemoveTickerEvent ; &3D - AddSWI InstallKeyHandler ; &3E - AddSWI CheckModeValid ; &3F - -SWIClass SETS RISCOS_Kernel_1SWI_Name - - ^ RISCOS_Kernel_1SWI_Base - AddSWI ChangeEnvironment ; &40 - AddSWI ClaimScreenMemory ; &41 - AddSWI ReadMonotonicTime ; &42 - AddSWI SubstituteArgs ; &43 - AddSWI PrettyPrint ; &44 - AddSWI Plot ; &45 - AddSWI WriteN ; &46 - AddSWI AddToVector ; &47 - AddSWI WriteEnv ; &48 - AddSWI ReadArgs ; &49 - AddSWI ReadRAMFsLimits ; &4A - AddSWI ClaimDeviceVector ; &4B - AddSWI ReleaseDeviceVector ; &4C - AddSWI DelinkApplication ; &4D - AddSWI RelinkApplication ; &4E - AddSWI HeapSort ; &4F - AddSWI ExitAndDie ; &50 - AddSWI ReadMemMapInfo ; &51 - AddSWI ReadMemMapEntries ; &52 - AddSWI SetMemMapEntries ; &53 - AddSWI AddCallBack ; &54 - AddSWI ReadDefaultHandler ; &55 - AddSWI SetECFOrigin ; &56 - AddSWI SerialOp ; &57 - AddSWI ReadSysInfo ; &58 - AddSWI Confirm ; &59 - AddSWI ChangedBox ; &5A - AddSWI CRC ; &5B - AddSWI ReadDynamicArea ; &5C - AddSWI PrintChar ; &5D - AddSWI ChangeRedirection ; &5E - AddSWI RemoveCallBack ; &5F - AddSWI FindMemMapEntries ; &60 - AddSWI SetColour ; &61 - AddSWI ClaimSWI ; &62 ; In ToolkitSpt - Must be implemented - AddSWI ReleaseSWI ; &63 ; OS > 3.10. - AddSWI Pointer ; &64 - AddSWI ScreenMode ; &65 - AddSWI DynamicArea ; &66 - AddSWI AbortTrap ; &67 - AddSWI Memory ; &68 - AddSWI ClaimProcessorVector ; &69 - AddSWI Reset ; &6A - AddSWI MMUControl ; &6B - AddSWI ResyncTime ; &6C - AddSWI PlatformFeatures ; &6D - AddSWI SynchroniseCodeAreas ; &6E - AddSWI CallASWI ; &6F - AddSWI AMBControl ; &70 ### Clashes with OS_SpecialControl on PPlus ### - AddSWI CallASWIR12 ; &71 - AddSWI SpecialControl ; &72 ### this was &70 in original PPlus sources ### - AddSWI EnterUSR32 ; &73 first used in Ursula - AddSWI EnterUSR26 ; &74 first used in Ursula - AddSWI VIDCDivider ; &75 - AddSWI NVMemory ; &76 - ^ OS_NVMemory + 4 - AddSWI Hardware ; &7A - AddSWI IICOp ; &7B - AddSWI LeaveOS ; &7C - AddSWI ReadLine32 ; &7D - AddSWI SubstituteArgs32 ; &7E - AddSWI HeapSort32 ; &7F - - ASSERT @ <= &C0 - -SWIClass SETS RISCOS_StringConversionSWI_Name - - ^ RISCOS_StringConversionSWI_Base - AddSWI ConvertStandardDateAndTime ; &C0 - AddSWI ConvertDateAndTime ; &C1 - - ^ RISCOS_StringConversionSWI_Base + &10 - AddSWI ConvertHex1 ; &D0 - AddSWI ConvertHex2 ; &D1 - AddSWI ConvertHex4 ; &D2 - AddSWI ConvertHex6 ; &D3 - AddSWI ConvertHex8 ; &D4 - AddSWI ConvertCardinal1 ; &D5 - AddSWI ConvertCardinal2 ; &D6 - AddSWI ConvertCardinal3 ; &D7 - AddSWI ConvertCardinal4 ; &D8 - AddSWI ConvertInteger1 ; &D9 - AddSWI ConvertInteger2 ; &DA - AddSWI ConvertInteger3 ; &DB - AddSWI ConvertInteger4 ; &DC - AddSWI ConvertBinary1 ; &DD - AddSWI ConvertBinary2 ; &DE - AddSWI ConvertBinary3 ; &DF - AddSWI ConvertBinary4 ; &E0 - AddSWI ConvertSpacedCardinal1 ; &E1 - AddSWI ConvertSpacedCardinal2 ; &E2 - AddSWI ConvertSpacedCardinal3 ; &E3 - AddSWI ConvertSpacedCardinal4 ; &E4 - AddSWI ConvertSpacedInteger1 ; &E5 - AddSWI ConvertSpacedInteger2 ; &E6 - AddSWI ConvertSpacedInteger3 ; &E7 - AddSWI ConvertSpacedInteger4 ; &E8 - AddSWI ConvertFixedNetStation ; &E9 - AddSWI ConvertNetStation ; &EA - AddSWI ConvertFixedFileSize ; &EB - AddSWI ConvertFileSize ; &EC - AddSWI ConvertHex16 ; &ED - AddSWI ConvertCardinal8 ; &EE - AddSWI ConvertInteger8 ; &EF - AddSWI ConvertBinary8 ; &F0 - AddSWI ConvertSpacedCardinal8 ; &F1 - AddSWI ConvertSpacedInteger8 ; &F2 - AddSWI ConvertFixedFileSize64 ; &F3 - AddSWI ConvertFileSize64 ; &F4 - - ASSERT @ <= &100 - -SWIClass SETS RISCOS_WriteCharacter_0SWI_Name - - ^ RISCOS_WriteCharacter_0SWI_Base - AddSWI WriteI ; &100-&1FF - - ; RISC OS Specific register synonyms - -Error RN r0 ; Error return pointer - -wp RN r12 ; Workspace Pointer -WP RN r12 -WsPtr RN r12 - -sp RN r13 ; Stack Pointer -SP RN r13 -sp_irq RN r13_irq ; Note there is no definition -sp_svc RN r13_svc ; for sp_usr or sp_fiq. -stack RN r13 -Stack RN r13 -STACK RN r13 - - - ; Vector numbers - -UserV * &00 -ErrorV * &01 -IrqV * &02 -WrchV * &03 -RdchV * &04 ; --, -CliV * &05 ; | -ByteV * &06 ; | -WordV * &07 ; | -FileV * &08 ; | -ArgsV * &09 ; } These numbers correspond -BGetV * &0A ; } to the SWI numbers -BPutV * &0B ; | -GBPBV * &0C ; | -FindV * &0D ; | -ReadLineV * &0E ; --' -FSCV * &0F -EventV * &10 -UPTV * &11 -NETV * &12 -KEYV * &13 -INSV * &14 -REMV * &15 -CNPV * &16 ; Count/Purge Buffer V -UKVDU23V * &17 ; VDU23 (decimal) -UKSWIV * &18 ; Unknown SWI numbers -UKPLOTV * &19 ; VDU25 (decimal) -MouseV * &1A ; The mouse SWI vectors along here -VDUXV * &1B ; The kernel calls this vector instead of - ; the VDU if bit 5 of wrch destination set -TickerV * &1C ; 100Hz pacemaker -UpCallV * &1D ; The 'can you deal with this before I go bang' vector. -ChangeEnvironmentV * &1E ; vectors along here when changing any handlers, - ; so debuggers etc. can stop it getting through. -SpriteV * &1F ; called by SWI SpriteOp -DrawV * &20 ; polygon fill vector for printers -EconetV * &21 ; Vector for NetFS/Econet progress reporting -ColourV * &22 ; for the ColourTrans module -PaletteV * &23 ; palette changed indication -SerialV * &24 ; indirection of SerialOps from kernel to Serial device drivers. -FontV * &25 ; indirection of Font Manager calls prior - ; to processing by Font Manager. -PointerV * &26 ; for mouse drivers -TimeShareV * &27 ; SkyNet TimeShare -GraphicsV * &2A ; indirection of graphics system from Kernel -UnthreadV * &2B ; high-priority callbacks - -SpareVector4 * &2C -SpareVector3 * &2D -SpareVector2 * &2E -SpareVector1 * &2F - -; LowPriorityEventV -; R0 - flags -; R1 - event class -; R2 - event type -; Event Classes -; 0 - System -; 1 - Window - -NVECTORS * &30 ; There are this many vectors, 0..NVECTORS-1 - - ; Buffer indices - -Buff_Key * 0 -Buff_RS423In * 1 -Buff_RS423Out * 2 -Buff_Print * 3 -Buff_Sound0 * 4 -Buff_Sound1 * 5 -Buff_Sound2 * 6 -Buff_Sound3 * 7 -Buff_Speech * 8 -Buff_Mouse * 9 - - ; Event numbers. 0..31 available - -Event_OutputEmpty * 0 -Event_InputFull * 1 -Event_CharInput * 2 -Event_ADCConvert * 3 -Event_VSync * 4 -Event_IntervalTimer * 5 -Event_Escape * 6 -Event_RS423Error * 7 -Event_Econet_UserRPC * 8 -Event_User * 9 -Event_Mouse * 10 -Event_Keyboard * 11 -Event_Sound * 12 -Event_Econet_Rx * 14 -Event_Econet_Tx * 15 -Event_Econet_OSProc * 16 ; This is where Notify, View etc. happen -Event_MIDI * 17 ; to notify of MIDI data being received -Event_Internet * 19 -Event_Expansion * 21 ; was SJ. Now earmarked for use with subreason codes -Event_DeviceOverRun * 22 ; DeviceFS to inform the world that a device has overrun -Event_PortableBMU * 28 ; Downgrade of BMU interrupt. -; #### WARNING #### There are TWO event numbers left. Do not allocate any more -; without a really good reason. amg -Event_PRISM * 32 ; State change events from the PRISM subsystem - -; Subreason codes for Event_Expansion - to be passed in R1 on the event call - ^ 0 -Event_Expansion_SmartCard # 0 ; ANC Rich Buckley -Event_Expansion_SCInterface # 1 ; 1 more useful alias for above -Event_Expansion_SCTransport # 1 ; 2 - -; Keyboard status bits - -KBStat_PendingAlt * &01 -KBStat_ScrollLock * &02 -KBStat_NoNumLock * &04 -KBStat_ShiftEngaged * &08 -KBStat_NoCapsLock * &10 -KBStat_NoShiftLock * &20 -KBStat_CtrlEngaged * &40 -KBStat_ShiftEnable * &80 - -KBStat_NoCapsLockBitNo * 4 - -MainVars * &A6 - - -MosVer * 6 ; nice non-zero value - - GBLS MosTitle -MosTitle SETS "Tim's Arthur Operating System 0.00" -; If assembling arthur, there are better strings to use!! - -NIL * &80000000 ; An interesting value - - -MaxLengthDateLo * &33EA0000 ; Wednesday, 28th September 1988 -MaxLengthDateHi * &00000041 ; 11:34:36.80 am - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; And a handy variable or three - - GBLL True -True SETL {TRUE} - - GBLL False -False SETL {FALSE} - - GBLL AssemblingArthur -AssemblingArthur SETL False - -; This needs to be defined for some builds of the Wimp to correctly -; select delegation of application memory management code to the kernel. - GBLL AMBKernel -AMBKernel SETL True - -; Tells Switcher it's being built on a system with OS_DynamicArea 6 and 7 -; available - activated by Kernel's internal DynArea_QuickHandles switch. - GBLL OSD6and7Kernel -OSD6and7Kernel SETL True - - OPT OldOpt - END diff --git a/hdr/Variables b/hdr/Variables deleted file mode 100644 index 697ce82b..00000000 --- a/hdr/Variables +++ /dev/null @@ -1,27 +0,0 @@ -; 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. -; -; > $.Hdr.Variables -; define variable types, as got by SWI ReadVarVal, etc. - -VarType_String * 0 -VarType_Number * 1 -VarType_Macro * 2 -VarType_Expanded * 3 ; given to Read, this always returns a string - ; given to Set, this means evaluate an expression -VarType_LiteralString * 4 ; Only valid for Set - sets the string as is (no - ; GSTrans) -VarType_Code * 16 - - END diff --git a/hdr/VduExt b/hdr/VduExt deleted file mode 100644 index 6b53865f..00000000 --- a/hdr/VduExt +++ /dev/null @@ -1,126 +0,0 @@ -; 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 VDU variable numbers => &.Hdr.VduExt - -OldOpt SETA {OPT} - OPT OptNoList+OptNoP1List - -; ************************************************************ -; *** C h a n g e L i s t (better late than never!) *** -; ************************************************************ - -; Date Name Description -; ---- ---- ----------- -; 27-Oct-89 TMD Added VIDCClockSpeed -; 05-Aug-91 DDV Added Flag_FullPalette -; 15-Jul-93 TMD Added NumModeVars -; 21-Jul-98 NDT Added PixelRate - -; Sets up external symbols of the form VduExt_<var name> -; for use with SWI OS_ReadVDUVariables - - MACRO - NotRVVTBarWobblyBits $var, $base - [ "$base"<>"" -NotRVVTBarWobblyBitscounter SETA $base - ] -VduExt_$var * NotRVVTBarWobblyBitscounter -NotRVVTBarWobblyBitscounter SETA NotRVVTBarWobblyBitscounter +1 - MEND - - GBLA NotRVVTBarWobblyBitscounter -NotRVVTBarWobblyBitscounter SETA 0 - - NotRVVTBarWobblyBits ModeFlags, 0 - NotRVVTBarWobblyBits ScrRCol - NotRVVTBarWobblyBits ScrBRow - NotRVVTBarWobblyBits NColour - NotRVVTBarWobblyBits XEigFactor - NotRVVTBarWobblyBits YEigFactor - NotRVVTBarWobblyBits LineLength - NotRVVTBarWobblyBits ScreenSize - NotRVVTBarWobblyBits YShftFactor - NotRVVTBarWobblyBits Log2BPP - NotRVVTBarWobblyBits Log2BPC - NotRVVTBarWobblyBits XWindLimit - NotRVVTBarWobblyBits YWindLimit - -NumModeVars * NotRVVTBarWobblyBitscounter - - NotRVVTBarWobblyBits GWLCol, &80 - NotRVVTBarWobblyBits GWBRow - NotRVVTBarWobblyBits GWRCol - NotRVVTBarWobblyBits GWTRow - NotRVVTBarWobblyBits TWLCol - NotRVVTBarWobblyBits TWBRow - NotRVVTBarWobblyBits TWRCol - NotRVVTBarWobblyBits TWTRow - NotRVVTBarWobblyBits OrgX - NotRVVTBarWobblyBits OrgY - NotRVVTBarWobblyBits GCsX - NotRVVTBarWobblyBits GCsY - NotRVVTBarWobblyBits OlderCsX - NotRVVTBarWobblyBits OlderCsY - NotRVVTBarWobblyBits OldCsX - NotRVVTBarWobblyBits OldCsY - NotRVVTBarWobblyBits GCsIX - NotRVVTBarWobblyBits GCsIY - NotRVVTBarWobblyBits NewPtX - NotRVVTBarWobblyBits NewPtY - NotRVVTBarWobblyBits ScreenStart - NotRVVTBarWobblyBits DisplayStart - NotRVVTBarWobblyBits TotalScreenSize - NotRVVTBarWobblyBits GPLFMD - NotRVVTBarWobblyBits GPLBMD - NotRVVTBarWobblyBits GFCOL - NotRVVTBarWobblyBits GBCOL - NotRVVTBarWobblyBits TForeCol - NotRVVTBarWobblyBits TBackCol - NotRVVTBarWobblyBits GFTint - NotRVVTBarWobblyBits GBTint - NotRVVTBarWobblyBits TFTint - NotRVVTBarWobblyBits TBTint - NotRVVTBarWobblyBits MaxMode - NotRVVTBarWobblyBits GCharSizeX - NotRVVTBarWobblyBits GCharSizeY - NotRVVTBarWobblyBits GCharSpaceX - NotRVVTBarWobblyBits GCharSpaceY - NotRVVTBarWobblyBits HLineAddr - NotRVVTBarWobblyBits TCharSizeX - NotRVVTBarWobblyBits TCharSizeY - NotRVVTBarWobblyBits TCharSpaceX - NotRVVTBarWobblyBits TCharSpaceY - NotRVVTBarWobblyBits GcolOraEorAddr - NotRVVTBarWobblyBits VIDCClockSpeed - NotRVVTBarWobblyBits PixelRate - - NotRVVTBarWobblyBits WindowWidth, &100 - NotRVVTBarWobblyBits WindowHeight - -; Bits in ModeFlags - -Flag_NonGraphic * 1 -Flag_Teletext * 2 -Flag_GapMode * 4 -Flag_BBCGapMode * 8 -Flag_HiResMono * 16 -Flag_DoubleVertical * 32 -Flag_HardScrollDisabled * 64 ; set when outputting to a sprite -Flag_FullPalette * 128 ; set when palette is not brain damaged -Flag_InterlacedMode * 256 ; set when full interlaced mode - - OPT OldOpt - - END diff --git a/s/AMBControl/AMB b/s/AMBControl/AMB deleted file mode 100644 index c0088427..00000000 --- a/s/AMBControl/AMB +++ /dev/null @@ -1,41 +0,0 @@ -; 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. -; - -; Implements OS_AMBControl (takes care of application memory management for Wimp) -; -; Nov 1995 mjs development version originated as Module -; Jul 1996 mjs fully implemented in kernel for RISC OS 3.70 -; Mar 1997 mjs performance enhancements for Ursula OS -; Oct 2000 mjs Ursula code resurrected for 32-bit HALised kernel, hoorah! - - GET s.AMBControl.Options - GET s.AMBControl.Workspace - GET s.AMBControl.main - GET s.AMBControl.allocate - GET s.AMBControl.deallocate - GET s.AMBControl.growshrink - GET s.AMBControl.mapslot - GET s.AMBControl.mapsome - GET s.AMBControl.readinfo - - GET s.AMBControl.growp - GET s.AMBControl.shrinkp - GET s.AMBControl.service - - GET s.AMBControl.Memory - - GET s.AMBControl.memmap - - END diff --git a/s/AMBControl/Memory b/s/AMBControl/Memory deleted file mode 100644 index 8fc2f47e..00000000 --- a/s/AMBControl/Memory +++ /dev/null @@ -1,60 +0,0 @@ -; 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. -; -; > s.Memory - -; Small veneer between AMBControl's memory block requirements and OS_Heap, -; using system heap. This is changed since Ursula - old code called OS_Module -; and claimed blocks from RMA, which is an anachronism since code is in -; the kernel. - -; quantise sizes to reduce heap stress -; -AMBblockQ * 64 - - -;in: r3=size -;out: r2 -> block, r0 corrupted -; -AMB_BlockClaim ROUT - Push "r1,r3,lr" - ADD r3,r3,#AMBblockQ - 1 - BIC r3,r3,#AMBblockQ - 1 - BL ClaimSysHeapNode - Pull "r1,r3,pc" - -;in: r2 -> block -;out: r0 corrupted -; -AMB_BlockFree ROUT - Push "r1,lr" - BL FreeSysHeapNode - Pull "r1,pc" - -;in: r2 -> block, r3 = new size -;out: r2 -> new block, r0 corrupted -; -AMB_BlockResize ROUT - Push "r1,r3,lr" - ADD r3,r3,#AMBblockQ - 1 - BIC r3,r3,#AMBblockQ - 1 - LDR r1,[r2,#-4] ;pick up OS_Heap's size word (naughty!) - SUB r1,r1,#8 ;heap size will be 8 more than quantised size - SUBS r3,r3,r1 ;required size change - MOVNE r0, #HeapReason_ExtendBlock - BLNE DoSysHeapOpWithExtension - Pull "r1,r3,pc" - - - END diff --git a/s/AMBControl/Options b/s/AMBControl/Options deleted file mode 100644 index 107f97fb..00000000 --- a/s/AMBControl/Options +++ /dev/null @@ -1,80 +0,0 @@ -; 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. -; - -; > s.Options - -AMBMagicNodeID * &4E424D41 ;"AMBN" - -AMBInitialMaxNodes * 256 -AMBGrowMaxNodes * 64 ;not used now AMBControl is in kernel - - -;Bin pages by physical address, for quick mapping from page number to -;physical address. Bin entry holds physical address of first page in bin. -;Bin size must be no bigger than minimum physical RAM fragment to be found -;in machine. eg. 512k size gives 128 pages in a bin, so shift of 7 and -;mask of &7F. Max practical bin size is 1M (mask must be immediate constant). -; -AMBPhysBinShift * 7 -AMBPhysBinMask * &7F - - -ApplicationStart * (32*1024) - -AbsMaxAppSize * AplWorkMaxSize ;application space limit for RISC OS -AbsMaxAppPages * (AbsMaxAppSize:SHR:Log2PageSize) ;and same limit expressed in Pages - - [ ChocolateAMB -AMBMIRegWords * (AbsMaxAppPages+31) :SHR: 5 ;no. of words for AMBMappedInRegister - ;convenient to set this at fixed max size - ;(only 896 bytes for 28Mb AppSpace) - ] - -;whether to check handles given to AMBControl - not very useful when in kernel -; - GBLL ValidateAMBHandles -ValidateAMBHandles SETL {FALSE} - - -;performance enhancements originally introduced for Ursula OS -; -; ChocolateAMB - if {FALSE}, disables all AMBControl crazy chocolate flavour enhancements -; -; AMB_LazyMapIn - if {TRUE}, individual pages of a swapped-in task are only mapped in when -; necessary (happens via abort mechanism). This typically makes the swapping -; cost much lower and much less sensitive to large slot size. The worst case -; swapping cost is still good (abort mechanism cost is very small). -; Probably only worth supporting this on ARMs with simple instruction restart -; after abort (originally StrongARM revT or later for Ursula) -; -; AMB_LimpidFreePool - if {TRUE}, the cache(s) can be assumed to be clear with respect to the FreePool -; when AMBControl fetches pages from it. This allows AMBControl to avoid any -; cache clean/flush for moving pages out of the FreePool. This assumption is -; valid if either: FreePool pages are uncacheable; or FreePool pages are -; never used in situ; or FreePool pages are flushed after use in situ. -; -; AMB_ChocTrace - if {TRUE}, keep trace info for some enhanced code calls and data (probably development only) - - GBLL AMB_LazyMapIn - GBLL AMB_LimpidFreePool - GBLL AMB_ChocTrace - -AMB_LazyMapIn SETL {TRUE} :LAND: ChocolateAMB -AMB_LimpidFreePool SETL {TRUE} :LAND: ChocolateAMB ;allowed because FreePool is currently marked uncacheable - ;current implementation assumes uncacheability as criterion - -AMB_ChocTrace SETL {FALSE} :LAND: ChocolateAMB ;development only - - END diff --git a/s/AMBControl/Workspace b/s/AMBControl/Workspace deleted file mode 100644 index 79e2d3d6..00000000 --- a/s/AMBControl/Workspace +++ /dev/null @@ -1,87 +0,0 @@ -; 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. -; -; > s.Workspace - - -; -;task node format -; - ^ 0 -AMBNode_HdrStart # 0 -AMBNode_id # 4 ;magic identifier -AMBNode_handle # 4 ;handle for external reference -AMBNode_prev # 4 ;ptr to previous node -AMBNode_next # 4 ;ptr to next node -AMBNode_pagetable # 0 ;data comprising page table from here on -AMBNode_Npages # 4 ;no. of pages in page list -AMBNode_startaddr # 4 ;logical address of first page (-1 means nowhere) -AMBNode_PPL # 4 ;PPL ('page protection level') for pages -AMBNode_pages # 0 ;list of page numbers from here on (1 word per page) -AMBNode_HdrEnd # 0 -; -AMBNode_HdrSize * AMBNode_HdrEnd - AMBNode_HdrStart - - -; -;main workspace -; - ^ 0,R12 -AMBNhandles # 4 ;total handles available -AMBNtasks # 4 ;no. of tasks currently allocated -AMBMappedInNode # 4 ;node ptr of mapped-in task, or 0 for none -AMBNodeHandles # 4 ;ptr to node handle array (1 word per entry) -AMBPhysBin # 4 ;ptr to physical page bin array -AMBPhysBinEntries # 4 ;no. of entries in physical page bin array -AMBAnchorNode # AMBNode_HdrSize ;dummy node - see note (1) below -; - [ ChocolateAMB -AMBFlags # 4 ;bits defined as below -AMBNContextSwitches # 4 ;monotonic count of total no. of task map-in's (eg. for performance tracing) - [ AMB_ChocTrace -AMBNmakeunsparse # 4 ;count of no. of calls to AMB_MakeUnsparse -AMBNmemmoveshrink # 4 ;count of no. of Service_MemoryMoved shrink fixups -AMBNmemmovegrow # 4 ;count of no. of Service_MemoryMoved grow fixups - ] -AMBMappedInNpages # 4 ;no. of pages of MappedInNode really mapped in -AMBMappedInRegister # AMBMIRegWords*4 ;1 bit per page - see note (2) below - ] -; -AMBmaxwork * :INDEX:@ ;size of main workspace (assumed to be multiple of 4 bytes) - - - [ ChocolateAMB -; -;definition of bits in AMBFlags -; -AMBFlag_LazyMapIn_disable * &80000000 ;bit 31 LazyMapIn permanent disable (eg. not running on StrongARM) -AMBFlag_LazyMapIn_suspend * &40000000 ;bit 30 LazyMapIn suspend (controlled via AMB SWI) - ;bits 29..0 reserved (0) -; - ] - -;Notes: -; -; (1) AMBAnchorNode is a dummy node with 0 page entries that forms the anchor of a -; circular node list. This averts the need for any special case for adding or -; removing nodes. -; -; (2) AMBMappedInRegister is a 'bitmap' of the current page mapping status of the -; MappedInNode. This supports AMB_LazyMapIn. Bit n corresponds to the n'th page -; of the MappedInNode; if it is set, then that page is currently mapped in. The -; bits are packed 'little endian', so bit 0 is the LSB of word 0, bit 31 is -; the MSB of word 0, bit 32 is the LSB of word 1 and so on. - - - END diff --git a/s/AMBControl/allocate b/s/AMBControl/allocate deleted file mode 100644 index 432bab77..00000000 --- a/s/AMBControl/allocate +++ /dev/null @@ -1,122 +0,0 @@ -; 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. -; -; > s.allocate - -; handle allocate reason code - -; entry: -; R0 = 0 (reason code 0) -; R1 = number of pages -; -; exit: -; R1 = no. of pages actually allocated -; R2 = handle for allocation - -allocate - Push "R0,R3,R4,LR" - -; Debug AMB,"allocate ",r0,r1 - - MOV R3,#AbsMaxAppSize - SUB R3,R3,#ApplicationStart - MOV R3,R3,LSR #Log2PageSize ;R3 = absolute max app pages - - CMP R1,R3 - MOVGT R1,R3 - -;get handle for node - LDR R0,AMBNodeHandles - LDR R4,[R0] - CMP R4,#0 ;any handles available? - BNE %FT01 - - ; give up - Pull "R0,R3,R4,LR" - ADR R0,err_nomorehandles - B SLVK_SetV - -01 -;get memory for node - from RMA - MOV R3,#(AMBNode_pages - AMBNode_id) ;size excluding page list - ADD R3,R3,R1,LSL #2 ;plus one word per page - BL AMB_BlockClaim - BVS alloc_done - -;remember handle in node - STR R4,[R2,#AMBNode_handle] - -;init fields of new node - LDR R4,=AMBMagicNodeID - STR R4,[R2,#AMBNode_id] ;magic id - MOV R4,#0 - STR R4,[R2,#AMBNode_Npages] ;number of pages = 0 (so far) - MOV R4,#ApplicationStart - STR R4,[R2,#AMBNode_startaddr] - LDR R4,=AppSpaceDANode - LDR R4,[R4,#DANode_Flags] - AND R4,R4,#&7F - STR R4,[R2,#AMBNode_PPL] ;PPL from bottom 8 bits of DA flags - -;do the actual MMU page allocation (grow from 0), for R1 pages, using node R2 - BL growpages - BVS alloc_done - - CMP R1,#0 ;EQ status if we were asked for 0 pages - LDR R1,[R2,#AMBNode_Npages] ;actual no. of pages we achieved - BEQ alloc_ok ;if asked for 0, regard as ok - - CMP R1,#0 - BEQ alloc_zeropages ;achieving 0 pages is not ok - -;ok, so remove handle from free list -alloc_ok - LDR R0,AMBNodeHandles - LDR R4,[R2,#AMBNode_handle] - LDR R3,[R0,R4,LSL #2] ;next free handle - STR R3,[R0] ;store as new first free handle - STR R2,[R0,R4,LSL #2] ;and remember node address in handle array - -;R2 -> new node - put it on front of list - ADR R3,AMBAnchorNode ; R3 -> ank_node - LDR R4,[R3,#AMBNode_next] ; R4 -> old_node (old front) - STR R4,[R2,#AMBNode_next] ; new_next := old_node - STR R2,[R3,#AMBNode_next] ; ank_next := new_node - STR R3,[R2,#AMBNode_prev] ; new_prev := ank_node - STR R2,[R4,#AMBNode_prev] ; old_prev := new_node - - LDR R4,AMBNtasks - ADD R4,R4,#1 - STR R4,AMBNtasks - - STR R2,AMBMappedInNode ;allocated node is also mapped in - LDR R2,[R2,#AMBNode_handle] ;change address to handle - CLRV - -alloc_done -; Debug AMB,"<alloc ",r1,r2 - STRVS R0,[SP] - Pull "R0,R3,R4,LR" - B SLVK_TestV - -;free page table space and return 0 handle -alloc_zeropages - BL AMB_BlockFree - MOV R1,#0 - MOV R2,#0 - B alloc_done - - LTORG - - END diff --git a/s/AMBControl/deallocate b/s/AMBControl/deallocate deleted file mode 100644 index 2e9b47c6..00000000 --- a/s/AMBControl/deallocate +++ /dev/null @@ -1,103 +0,0 @@ -; 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. -; -; > s.deallocate - - -; handle deallocate reason code - -; entry: -; R0 = 1 (reason code 1) -; R2 = handle -; -; exit - - - -deallocate - Push "R0-R3,LR" - -; Debug AMB,"deallocate ",r0,r2 - - [ ValidateAMBHandles - ;validate handle - LDR R0,AMBNhandles - CMP R2,R0 - BGT badhandle_dealloc - CMP R2,#1 - BLT badhandle_dealloc - ] - - LDR R0,AMBNodeHandles ; R0 -> handle array - LDR R1,[R0,R2,LSL #2] ; R1 -> node - - [ ValidateAMBHandles - ;check we have a proper id for node handle - LDR R3,=AMBMagicNodeID - LDR LR,[R1,#AMBNode_id] - CMP LR,R3 - BNE badhandle_dealloc - ] - - Push "R1-R2" - MOV R2,R1 ;node ptr - MOV R1,#0 ;shrink to 0 pages - BL shrinkpages ;do actual MMU page deallocate - Pull "R1-R2" - BVS dealloc_done - -;put handle on free list - LDR R3,[R0] ;current first free handle - STR R3,[R0,R2,LSL #2] ;attach - STR R2,[R0] ;new first free handle - -;remove node from list - MOV R2,R1 ; R2 -> node - LDR R0,[R2,#AMBNode_prev] ; R0 -> prev_node - LDR R1,[R2,#AMBNode_next] ; R1 -> next_node - STR R1,[R0,#AMBNode_next] ; prev_next := next_node - STR R0,[R1,#AMBNode_prev] ; next_prev := prev_node - LDR R0,AMBNtasks - SUB R0,R0,#1 - STR R0,AMBNtasks - -;if this is the mapped-in node, then nothing is now mapped in - LDR R0,AMBMappedInNode - CMP R0,R2 - MOVEQ R0,#0 - STREQ R0,AMBMappedInNode - -;free node (at R2) - BL AMB_BlockFree - -dealloc_done - STRVS R0,[SP] - Pull "R0-R3,LR" - B SLVK_TestV - - LTORG - - [ ValidateAMBHandles -badhandle_dealloc - Pull "R0-R3,LR" -badhandle - ADR R0,err_badhandle - B SLVK_SetV -err_badhandle - DCD 0 - DCB "AMBControl bad handle",0 - ALIGN - ] - - - END diff --git a/s/AMBControl/growp b/s/AMBControl/growp deleted file mode 100644 index e3d47757..00000000 --- a/s/AMBControl/growp +++ /dev/null @@ -1,146 +0,0 @@ -; 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. -; -; > s.growp - - -;grow slot by taking pages from FreePool; add them to AppSpace - - -; entry: -; R1 = new number of pages for slot (more than current value) -; R2 -> AMB node (page table already allocated/grown to size) -; -; exit: - - -growpages ROUT - Push "R0-R7,LR" - - MOV R6,R1 ;save entry R1 - LDR R5,[R2,#AMBNode_Npages] - CMP R5,R6 - Pull "R0-R7,PC",EQ ;done if no. of pages unchanged - - MOV R0,R2 ;R0 -> AMB node - - LDR R1,=FreePoolDANode ;R1 := source for pages - LDR R2,=AppSpaceDANode ;R2 := dest for pages - - LDR R7,[R0,#AMBNode_Npages] ;R7 := current no. of pages - SUB R3,R6,R7 ;no. of pages required from FreePool - LDR R4,[R1,#DANode_Size] - MOV R4,R4,LSR #Log2PageSize ;no. of pages in FreePool - CMP R3,R4 - [ ShrinkableDAs - BLGT growp_TryToShrinkShrinkables - ] - MOVGT R3,R4 ;R3 := no. of pages we will move - CMP R3,#0 - BEQ %FT02 ;done if can't move any pages - ADD R4,R3,R7 - STR R4,[R0,#AMBNode_Npages] ;new no. of pages - - ADD R4,R0,#AMBNode_pages - ADD R4,R4,R7,LSL #2 ;R4 -> 1st page table entry for grow - LDR R5,[R1,#DANode_Base] - LDR LR,[R1,#DANode_Size] - ADD R5,R5,LR ;current end of FreePool - SUB R5,R5,R3,LSL #Log2PageSize ;R5 := first required page address - - ;entry: R3 = no. of pages, R4 -> buffer for page entries, - ; R5 := start logical address - BL AMB_FindMemMapEntries ;find page nos. - - [ AMB_LazyMapIn - LDR R5,AMBFlags - TST R5,#AMBFlag_LazyMapIn_disable :OR: AMBFlag_LazyMapIn_suspend - ; - MOVEQ R5,#-1 ;map the pages to Nowhere initially - MOVEQ R6,#AP_Duff - LDRNE R5,[R0,#AMBNode_startaddr] - ADDNE R5,R5,R7,LSL #Log2PageSize ;R5 := first new page new address - LDRNE R6,[R0,#AMBNode_PPL] ;R6 := dest PPL flags - | - LDR R5,[R0,#AMBNode_startaddr] - ADD R5,R5,R7,LSL #Log2PageSize ;R5 := first new page new address - LDR R6,[R0,#AMBNode_PPL] ;R6 := dest PPL flags - ] - ; - ;entry: R3 = no. of pages, R4 -> list of page entries, - ; R5 = start logical address, R6 = PPL - BL AMB_SetMemMapEntries ;remap - - LDR R5,[R1,#DANode_Size] - SUB R5,R5,R3,LSL #Log2PageSize - STR R5,[R1,#DANode_Size] ;new FreePool size - - LDR R5,[R2,#DANode_Size] - ADD R5,R5,R3,LSL #Log2PageSize - STR R5,[R2,#DANode_Size] ;new AppSpace size - MOV R6,#0 - STR R5,[R6,#MemLimit] ;update MemLimit - -02 -;;; STRVS R0,[SP] - CLRV - Pull "R0-R7,PC" - - [ ShrinkableDAs -; -; growp_TryToShrinkShrinkables - try to shrink shrinkable DAs, to grow free pool -; -; entry: -; R1 -> FreePool DANode -; R3 = no. of pages required in FreePool -; R4 = no. of pages in FreePool (must be less than R3) -; -; exit: -; R4 = new no. of pages in FreePool -; condition code GT is true if still less than required (ie. R3 > R4 on exit) -; -growp_TryToShrinkShrinkables ROUT - Push "R0-R2,R11,R12,LR" - - MOV R11,R1 ; -> FreePool DANode - MOV R1,R3,LSL #Log2PageSize ;amount we need in FreePool - MOV R2,R4,LSL #Log2PageSize ;amount we have in FreePool - MOV R10,#DAList - ASSERT DANode_Link = 0 ;because DAList has only link -10 - LDR R10,[R10,#DANode_Link] ;and load next - CMP R10,#1 ;any more nodes? - BCC %FT99 - LDR LR,[R10,#DANode_Flags] ;check area is shrinkable - TST LR,#DynAreaFlags_Shrinkable - BEQ %BT10 ;if not, try next area - - SUBS R1,R1,R2 ;amount we still need - LDR LR,[R10,#DANode_Size] ;available size of this area - CMP LR,R1 - MOVCC R1,LR ;min(amount we need, size of this area) - RSB R1,R1,#0 ;make negative - it's a shrink - LDR R0,[R10,#DANode_Number] - SWI XOS_ChangeDynamicArea ;should not be currently threaded during AMBControl - MOV R1,R3,LSL #Log2PageSize ;original amount we need again - LDR R2,[R11,#DANode_Size] ;get new size of FreePool - CMP R2,R1 - BCC %BT10 ;if still too small, loop -99 - MOV R4,R2,LSR #Log2PageSize ;no. of pages now in FreePool - CMP R3,R4 - Pull "R0-R2,R11,R12,PC" - - ] ;ShrinkableDAs - - END diff --git a/s/AMBControl/growshrink b/s/AMBControl/growshrink deleted file mode 100644 index 29ea8634..00000000 --- a/s/AMBControl/growshrink +++ /dev/null @@ -1,170 +0,0 @@ -; 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. -; -; s.growshrink - -; heap block can move when resized, so make sure pointers fixed-up - -; change number of pages in slot (grow/shrink) - -; entry: -; R0 = 2 (reason code 2) -; R1 = new number of pages required -; R2 = handle -; -; exit: -; R1 = new number of pages actually achieved -; R3 = old number of pages - -growshrink - - Push "R0,R2,R4,R5,LR" - -; Debug AMB,"growshrink ",r0,r1,r2 - - MOV R5,#AbsMaxAppSize - SUB R5,R5,#ApplicationStart - MOV R5,R5,LSR #Log2PageSize ;R5 = absolute max app pages - CMP R1,R5 - MOVGT R1,R5 - - [ ValidateAMBHandles - ;validate handle - LDR R0,AMBNhandles - CMP R2,R0 - BGT badsghandle - CMP R2,#1 - BLT badsghandle - ] - - LDR R0,AMBNodeHandles ; R0 -> handles array - LDR R2,[R0,R2,LSL #2] ; R2 -> node - - [ ValidateAMBHandles - ;check we have a proper id for node - LDR R3,=AMBMagicNodeID - LDR LR,[R2,#AMBNode_id] - CMP LR,R3 - BNE badsghandle - ] - - LDR R3,[R2,#AMBNode_Npages] - CMP R1,R3 - Pull "R0,R2,R4,R5,LR",EQ ; done if no change - BEQ SLVK - - MOV R5,R3 ; R5 := old no. pages - BLT gs_shrink - -;grow - BL grwshr_node ; grow node itself first - BVS gs_done ; failed node grow is not error - means grow by 0 - BL growpages ; grow the slot (MMU mapping) - STRVS R0,[SP] - Pull "R0,R2,R4,R5,LR",VS - BVS SLVK_SetV - B gs_done -gs_shrink - BL shrinkpages ; shrink the slot (MMU mapping) first - BLVC grwshr_node ; shrink node itself - STRVS R0,[SP] - Pull "R0,R2,R4,R5,LR",VS - BVS SLVK_SetV -gs_done - MOV R3,R5 ;old no. of pages - CMP R2,#0 ;also clears V - MOVEQ R1,#0 - LDRNE R1,[R2,#AMBNode_Npages] - - CMP R2,#0 ;0 for freed node - STREQ R2,[SP,#4] ;poke freed handle to saved R2 - - Pull "R0,R2,R4,R5,LR" - B SLVK - - -;handle grow/shrink of node itself -;entry: -; R1 = new no. of pages -; R2 -> node -; R5 = old no. of pages -;exit: -; R2 -> node (may be moved) -grwshr_node - Push "R0,R3,R4,LR" - CMP R1,#0 - BEQ grwshrn_free ;shrunk to nothing - MOV R3,#(AMBNode_pages - AMBNode_id) ;new size excluding page list - ADD R3,R3,R1,LSL #2 ;new size - MOV R4,R2 ;so we can check for moved block - BL AMB_BlockResize - MOVVS R2,R4 ;in case block ptr not preserved on error - BVS grwshrn_done -;fix-up links if block has moved - CMP R4,R2 - BEQ grwshrn_done - - LDR R3,[R2,#AMBNode_prev] - STR R2,[R3,#AMBNode_next] ;fix prev_next - LDR R3,[R2,#AMBNode_next] - STR R2,[R3,#AMBNode_prev] ;fix next_prev - LDR R3,AMBMappedInNode - CMP R3,R4 - STREQ R2,AMBMappedInNode ;fix MappedInNode if it matches - LDR R3,[R2,#AMBNode_handle] - LDR R4,AMBNodeHandles - STR R2,[R4,R3,LSL #2] ;fix node address in handle array - -grwshrn_done - STRVS R0,[SP] - Pull "R0,R3,R4,PC" - -grwshrn_free - LDR R0,AMBNodeHandles - LDR R4,[R2,#AMBNode_handle] -;put handle on free list - LDR R3,[R0] ;current first free handle - STR R3,[R0,R4,LSL #2] ;attach - STR R4,[R0] ;new first free handle - -;remove node from list - LDR R0,[R2,#AMBNode_prev] ; R0 -> prev_node - LDR R3,[R2,#AMBNode_next] ; R3 -> next_node - STR R3,[R0,#AMBNode_next] ; prev_next := next_node - STR R0,[R3,#AMBNode_prev] ; next_prev := prev_node - LDR R0,AMBNtasks - SUB R0,R0,#1 - STR R0,AMBNtasks - -;if this is the mapped-in node, then nothing is now mapped in - LDR R0,AMBMappedInNode - CMP R0,R2 - MOVEQ R0,#0 - STREQ R0,AMBMappedInNode - - BL AMB_BlockFree - MOVVC R2,#0 - B grwshrn_done - - LTORG - - - [ ValidateAMBHandles -badsghandle - Pull "R0,R2,R4,R5,LR" - B badhandle - ] - - - END diff --git a/s/AMBControl/main b/s/AMBControl/main deleted file mode 100644 index 4a321db1..00000000 --- a/s/AMBControl/main +++ /dev/null @@ -1,253 +0,0 @@ -; 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. -; - -; > s.main - -;;; Initialisation -; -AMBControl_Init - Push "R0-R4,R12,LR" - -;claim main workspace - LDR R3,=AMBmaxwork - BL ClaimSysHeapNode -;;; BVS err_cantclaim - this should not happen - -;don't store ws pointer till end of initialise - service routines must -;know when initialise is not yet complete -; - MOV R12,R2 - -;zero-init workspace - MOV R1,#0 - LDR R3,=AMBmaxwork - ADD R3,R3,R2 -00 - STR R1,[R2],#4 - CMP R2,R3 - BLO %BT00 - -;claim block for handle array - MOV R3,#(AMBInitialMaxNodes:SHL:2) - BL ClaimSysHeapNode -;;; BVS err_cantclaim - STR R2,AMBNodeHandles - -;put all handles on free list (entry 0 is used as hdr of free list) - MOV R0,#1 - MOV R1,#AMBInitialMaxNodes - STR R1,AMBNhandles -01 - STR R0,[R2],#4 - ADD R0,R0,#1 - CMP R0,R1 - BNE %BT01 - MOV R0,#0 ; = end of list - STR R0,[R2] - -;claim block for PhysBin array - LDR R3,=MaxCamEntry - LDR R3,[R3] - ADD R3,R3,#1 ;no. of RAM pages extant - MOV R3,R3,LSR #AMBPhysBinShift ;no. of bin entries reqd. - STR R3,AMBPhysBinEntries - MOV R3,R3,LSL #2 ;1 word per entry - BL ClaimSysHeapNode -;;; BVS err_cantclaim - STR R2,AMBPhysBin - -;init PhysBin - MOV R0,#PhysRamTable - LDR R3,AMBPhysBin - LDR R4,AMBPhysBinEntries - LDMIA R0!,{R1,R2} ;address,size of first physical fragment - MOV R2,R2,LSR #Log2PageSize ;no. pages in fragment - B %FT04 -03 - ADD R1,R1,#(1:SHL:(Log2PageSize+AMBPhysBinShift)) ;next bin address - SUBS R2,R2,#(1:SHL:AMBPhysBinShift) ;no. pages binned - LDMLEIA R0!,{R1,R2} ;address,size of next physical fragment - MOVLE R2,R2,LSR #Log2PageSize ;no. pages in fragment -04 - STR R1,[R3],#4 - SUBS R4,R4,#1 - BNE %BT03 - -;init any other workspace that shouldn't init as 0 - ADR R1,AMBAnchorNode - STR R1,[R1,#AMBNode_prev] ;anchor prev initially -> anchor (empty list) - STR R1,[R1,#AMBNode_next] ;anchor next initially -> anchor (empty list) - [ AMB_LazyMapIn - MOV R0,#0 - LDR R0,[R0,#ProcessorFlags] - TST R0,#CPUFlag_BaseRestored - MOVEQ R1,#AMBFlag_LazyMapIn_disable ;laziness not supported if we can't trivially restart after abort (because we're lazy!) - MOVNE R1,#0 ;yipee, laziness enabled (and not suspended) - TST R0,#CPUFlag_AbortRestartBroken ;but wait! can't use for bugged chips (eg. pre rev T StrongARM) - MOVNE R1,#AMBFlag_LazyMapIn_disable - STR R1,AMBFlags - ] - MOV R0,#AMBControl_ws - STR R12,[R0] ;now initialisation is complete - - Pull "R0-R4,R12,PC" - - -; OS_AMBControl SWI handler -; entry: -; R0 = reason code (bits 0..7) and flags (bits 8..31), flags depend on reason -; other regs. depend on reason code -; exit: -; R0 preserved -; other regs. depend on reason code - -AMBControlSWI - MOV R12,#AMBControl_ws - LDR R12,[R12] - - AND R11,R0,#&FF - CMP R11,#(reasons0-reasons1)/4 - ADDCC PC,PC,R11,LSL #2 ;Despatch if within a suitable range - B reasons1 -reasons0 - B allocate ;0 - B deallocate ;1 - B growshrink ;2 - B mapslot ;3 - B readinfo ;4 - [ AMB_LazyMapIn - B laziness ;5 - | - B reserved ;5 - ] - B reserved ;6 - B reserved ;7 - B mjs_info ;8 - system reason code, dumps info to buffer -reasons1 - ADR R0,err_badreason - B SLVK_SetV - - - [ AMB_LazyMapIn -; -;entry: R0=5 (reason),R1=1 for lazy on, 0 for lazy off, -1 to read lazy only -;exit: R1=new lazy value, after any restrictions of platform applied -; -;action: if reading only, if lazy disabled, or if new state = current, do nothing -; if state is changing, map out any current node, change state, map in any current node -; -laziness ROUT - Push "R2-R3,LR" - CMP R1,#-1 - BEQ %FT20 - LDR R2,AMBFlags ;R2 := current flags - TST R2,#AMBFlag_LazyMapIn_disable ;disable is permanent - BNE %FT20 - CMP R1,#0 - MOV R1,R2 - ORREQ R1,R1,#AMBFlag_LazyMapIn_suspend - BICNE R1,R1,#AMBFlag_LazyMapIn_suspend ;R1 := new flags - EOR R3,R1,R2 - TST R3,#AMBFlag_LazyMapIn_suspend ;is suspend status changing? - BEQ %FT20 - LDR R3,AMBMappedInNode - CMP R3,#0 - BEQ %FT10 - Push "R0-R3" - MOV R0,#3 - MOV R1,#-1 - LDR R2,[R3,#AMBNode_handle] - SWI XOS_AMBControl ;map out current node - Pull "R0-R3" -10 - STR R1,AMBFlags - CMP R3,#0 - BEQ %FT20 - Push "R0-R3" - MOV R0,#3 - MOV R1,#0 - LDR R2,[R3,#AMBNode_handle] - SWI XOS_AMBControl ;map in current node - Pull "R0-R3" -20 - LDR R1,AMBFlags - TST R1,#AMBFlag_LazyMapIn_disable :OR: AMBFlag_LazyMapIn_suspend - MOVEQ R1,#1 - MOVNE R1,#0 - Pull "R2-R3,LR" - B SLVK -; - ] ;AMB_LazyMapIn - - -;entry: R0=8 (reason),R1 -> buffer (say 4k for up to 255 tasks) -;exit: buffer filled: -; 0 Ntasks -; 4 Handle of mapped in task (or 0) -; 8 Handle 1 -; 12 Npages 1 -; 16 Logical address 1 -; 20 PPL 1 -; 24 Handle 2 -; 28 Npages 2 -; 32 Logical address 2 -; 36 PPL 2 -; ... -mjs_info - Push "R1-R7,LR" - LDR R2,AMBNtasks - STR R2,[R1],#4 - LDR R2,AMBMappedInNode - CMP R2,#0 - LDRNE R2,[R2,#AMBNode_handle] - STR R2,[R1],#4 - ADR R2,AMBAnchorNode - MOV R7,R2 -01 - LDR R2,[R2,#AMBNode_next] - CMP R2,R7 - BEQ %FT02 - LDR R3,[R2,#AMBNode_handle] - LDR R4,[R2,#AMBNode_Npages] - LDR R5,[R2,#AMBNode_startaddr] - LDR R6,[R2,#AMBNode_PPL] - STMIA R1!,{R3-R6} - B %BT01 -02 - Pull "R1-R7,LR" - B SLVK - -reserved - ADR R0,err_reserved - B SLVK_SetV - -;;; errors (sod internationalisation) - -err_badreason - DCD 0 - DCB "bad AMBControl reason code",0 - ALIGN - -err_reserved - DCD 0 - DCB "reserved AMBControl reason code",0 - ALIGN - -err_nomorehandles - DCD 0 - DCB "AMBControl handles exhausted",0 - ALIGN - - END diff --git a/s/AMBControl/mapslot b/s/AMBControl/mapslot deleted file mode 100644 index 509b6743..00000000 --- a/s/AMBControl/mapslot +++ /dev/null @@ -1,150 +0,0 @@ -; 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. -; -; > s.mapslot - -; handle mapping of entire slot in or out (bit 8 of R0 clear) -; or mapping of some of slot (bit 8 of R0 set) - -; entry: -; R0 = bits 0..7 = 3 (reason code 3); bit 8 set for mapsome -; R1 = start (logical) address; 0 means application start; -1 means map out -; R2 = handle -; R3,R4 used if bit 8 set - see mapsome -; -; Note that if bit 8 is clear, the use is restricted to mapping in or out of -; whole slots only. Hence if bit 8 is clear, behaviour is undefined unless -; R1 is one of: 0, &8000 or -1. -; -mapslot - -; Debug AMB,"mapslot",r0,r1,r2,r3,r4 - - TST R0,#&100 ;if bit 8 set, then mapsome - BNE mapsome - - Push "R0-R6,LR" - - MOVS R5,R1 ;save entry R1 - MOVEQ R5,#ApplicationStart ;0 means application start - - [ ValidateAMBHandles - ;validate handle - LDR R0,AMBNhandles - CMP R2,R0 - BGT badmapslot - CMP R2,#1 - BLT badmapslot - ] - - LDR R0,AMBNodeHandles ; R0 -> handle array - LDR R1,[R0,R2,LSL #2] ; R1 -> node - - [ ValidateAMBHandles - ;check we have a proper id for node handle - LDR R3,=AMBMagicNodeID - LDR LR,[R1,#AMBNode_id] - CMP LR,R3 - BNE badmapslot - ] - - LDR R3,[R1,#AMBNode_Npages] - ADD R4,R1,#AMBNode_pages - -;;;actually, we can have 0 page slots (eg. sometimes from pinboard) -;;; CMP R3,#0 -;;; BEQ ms_done ;should not happen - - - LDR R2,AMBMappedInNode - CMP R1,R2 - CMPEQ R5,#-1 - BEQ ms_domap ;do map if already mapped in, and asked to map out - - CMP R1,R2 - CMPNE R5,#-1 - BEQ ms_done ;else do map only if not already mapped in, and asked to map in - -ms_domap - CMP R5,#-1 ;EQ if it is a map out - LDREQ R6,=DuffEntry - MOVNE R6,#ApplicationStart - STR R6,[R1,#AMBNode_startaddr] - MOVEQ R6,#AP_Duff - MOVNE R6,#0 - STR R6,[R1,#AMBNode_PPL] - - [ AMB_LazyMapIn - LDRNE R2,AMBNContextSwitches - ADDNE R2,R2,#1 - STRNE R2,AMBNContextSwitches - LDR R2,AMBFlags - TST R2,#AMBFlag_LazyMapIn_disable :OR: AMBFlag_LazyMapIn_suspend - BNE ms_cantbelazy - ; - ; - if map out, do sparse map out of whole page list then zero AMBMappedInNpages - ; - if map in, just zero AMBMappedInNpages (last map out will have cleared AMBMappedInRegister) - ; - MOV R2,R5 - CMP R2,#-1 - LDREQ R3,AMBMappedInNpages - ADREQ R5,AMBMappedInRegister - LDREQ R6,[R1,#AMBNode_Npages] - ;entry: R3 = no. pages mapped in, R4 -> list of page entries, - ; R5 -> bitmap of pages mapped in, R6=total no. of pages in page list - BLEQ AMB_SetMemMapEntries_SparseMapOut - MOV R3,#0 - STR R3,AMBMappedInNpages - MOV R5,R2 - B ms_mapdone -ms_cantbelazy - ;entry: R3 = no. of pages, R4 -> list of page entries, - ; R5 := start logical address, R6 = PPL - BL AMB_SetMemMapEntries -ms_mapdone - | - ;entry: R3 = no. of pages, R4 -> list of page entries, - ; R5 := start logical address, R6 = PPL - BL AMB_SetMemMapEntries - ] - -;update AppSpace kernel stuff - LDR R2,[R1,#AMBNode_Npages] - LDR R3,=AppSpaceDANode - MOV R0,#ApplicationStart - CMP R5,#-1 - ADDNE R0,R0,R2,LSL #Log2PageSize - STR R0,[R3,#DANode_Size] - MOV R3,#0 - STR R0,[R3,#MemLimit] - CMP R5,#-1 - MOVEQ R3,#0 - MOVNE R3,R1 - STR R3,AMBMappedInNode - -ms_done -;;; STRVS R0,[SP] - CLRV - Pull "R0-R6,LR" - B SLVK_TestV - - LTORG - - [ ValidateAMBHandles -badmapslot - Pull "R0-R6,LR" - B badhandle - ] - - END diff --git a/s/AMBControl/mapsome b/s/AMBControl/mapsome deleted file mode 100644 index f5444d6e..00000000 --- a/s/AMBControl/mapsome +++ /dev/null @@ -1,86 +0,0 @@ -; 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. -; -; > s.mapsome - -; handle mapping in of some of slot -; (used to implement 'mapenoughslot' for Wimp_TransferBlock) - -; entry: -; R0 = &103 (reason code 3, bit 8 set for mapsome) -; R1 = start (logical address) -; R2 = handle -; R3 = offset to start of mapping (pages into slot) -; R4 = no. of pages to map - -mapsome - Push "R0-R7,LR" - - CMP R1,#0 - MOVEQ R1,#ApplicationStart - - [ ValidateAMBHandles - ;validate handle - LDR R0,AMBNhandles - CMP R2,R0 - BGT badmapsome - CMP R2,#1 - BLT badmapsome - ] - - LDR R0,AMBNodeHandles ; R0 -> handle array - LDR R0,[R0,R2,LSL #2] ; R0 -> node - - [ ValidateAMBHandles - ;check we have a proper id for node handle - LDR R6,=AMBMagicNodeID - LDR LR,[R0,#AMBNode_id] - CMP LR,R6 - BNE badmapsome - ] - - LDR R6,[R0,#AMBNode_Npages] - ADD LR,R3,R4 - CMP LR,R6 - BGT badmssize - - MOV R7,R3 - MOV R3,R4 - ADD R4,R0,#AMBNode_pages - ADD R4,R4,R7,LSL #2 - MOV R5,R1 - CMP R5,#-1 - MOVEQ R6,#AP_Duff - MOVNE R6,#0 - ;entry: R3 = no. of pages, R4 -> list of page entries, - ; R5 := start logical address, R6 = PPL - BL AMB_SetMemMapEntries - - Pull "R0-R7,LR" - B SLVK - - LTORG - -badmssize -;return with V set but no error block (Wimp handles that) - Pull "R0-R7,LR" - B SLVK_SetV - - [ ValidateAMBHandles -badmapsome - Pull "R0-R7,LR" - B badhandle - ] - - END diff --git a/s/AMBControl/memmap b/s/AMBControl/memmap deleted file mode 100644 index 92b609ae..00000000 --- a/s/AMBControl/memmap +++ /dev/null @@ -1,768 +0,0 @@ -; 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. -; -; > s.memmap - -; low level memory mapping -; -; ---------------------------------------------------------------------------------- -; -;convert page number in $pnum to L2PT entry (physical address+protection bits), -;using PhysBin table for speed -; -;entry: $ptable -> PhysBin table, $pbits = protection bits -;exit: $temp corrupted -; - MACRO - PageNumToL2PT $pnum,$ptable,$pbits,$temp - BIC $temp,$pnum,#(3:SHL:(AMBPhysBinShift-2)) ;word alignment for PhysBin lookup - LDR $temp,[$ptable,$temp,LSR #(AMBPhysBinShift-2)] ;start physical address of bin - AND $pnum,$pnum,#AMBPhysBinMask ;no. pages into bin - ADD $pnum,$temp,$pnum,LSL #Log2PageSize ;physical address of page - ORR $pnum,$pnum,$pbits ;munge in protection bits - MEND - - - [ AMB_LazyMapIn - -; ---------------------------------------------------------------------------------- -; -;AMB_LazyFixUp -; -; *Only* for ARMs where the abort handler can restart instructions -; -; Routine to be used in abort handlers (in abort32 mode), that checks to see if abort -; is expected, and fixes things up if so, ready to restart instruction. -; -; Fix up consists of mapping in affected page, and updating AMBMappedInRegister. This -; may seem like a lot of work, but remember that the L2PT and CAM updates for each page are -; needed anyway in non-lazy scheme, so there is really only a housekeeping overhead. -; -; There is no cache clean/flush consideration here, since the map is a map in from Nowhere. -; TLB flush consideration is left to main abort handler code - in fact there may not -; be a TLB flush consideration at all, if ARM TLB can be assumed not to cache an -; entry which is a translation fault, as seems rational. -; -; entry: r0 = aborting address (data address for data abort, instruction address -; for prefetch abort), r1-r7 trashable, no stack -; r2 = 1 for prefetch abort, 0 for data abort -; FSR valid for data aborts, unpredictable for prefetch aborts -; exit: r0 = non-zero (NE status) if abort was expected and fixed up, zero (EQ status) if not -; FAR,FSR,SPSR_abt,lr_abt preserved -; -AMB_LazyFixUp ROUT - MOV r7,r12 - MOV r12,#AMBControl_ws - LDR r12,[r12] - CMP r12,#0 - BEQ %FT90 ;not initialised! - LDR r1,AMBFlags - TST r1,#AMBFlag_LazyMapIn_disable :OR: AMBFlag_LazyMapIn_suspend - BNE %FT90 ;not active - LDR r1,AMBMappedInNode - CMP r1,#0 - BEQ %FT90 ;no current node - ARM_read_FSR r6 ;hang onto FSR in case we have to preserve it - TEQ r2,#1 ;if data abort - ANDNE r3,r6,#&F - TEQNE r3,#7 ; and not a page translation fault - BNE %FT20 ; then not a lazy abort (and FAR may be invalid anyway) - LDR r2,[r1,#AMBNode_Npages] - SUBS r0,r0,#ApplicationStart - BLO %FT20 ;abort not in current app space - MOV r0,r0,LSR #Log2PageSize ;address now in terms of pages from ApplicationStart - CMP r0,r2 - BHS %FT20 ;abort not in current app space -; -; check/update the MappedIn bitmap -; - ADR r2,AMBMappedInRegister - MOV r5,#1 - ADD r2,r2,r0,LSR #5-2 - BIC r2,r2,#3 ;r2 -> bitmap word affected - AND r3,r0,#31 - MOV r5,r5,LSL r3 ;mask for bit affected in bitmap word - LDR r3,[r2] - LDR r4,AMBMappedInNpages ;count it - TST r3,r5 ;if page already mapped in, not a lazy abort - BNE %FT20 - ORR r3,r3,r5 ;ok, mark that we are going to map this page in - STR r3,[r2] - ADD r4,r4,#1 - STR r4,AMBMappedInNpages -; -; now map in the the page that went pop -; - ADD r1,r1,#AMBNode_pages - ADD r1,r1,r0,LSL #2 ;r1 -> page involved, in node page list - LDR r2,AMBPhysBin - MOV r3,#&FF0 - ORR r3,r3,#&E ;&FFE = L2PT protection bits for ordinary page - LDR r4,[r1] - MOV r6,r4 - PageNumToL2PT r4,r2,r3,r5 -; -;here, r6 = page number of page involved, r4 = new L2PT entry value to map in page -; - ADD r0,r0,#ApplicationStart:SHR:Log2PageSize ;address now in terms of pages from 0 - MOV r5,#L2PT - STR r4,[r5,r0,LSL #2] ;update L2PT -; - MOV r5,#0 - LDR r5,[r5,#CamEntriesPointer] - ADD r5,r5,r6,LSL #3 ;r5 -> CAM entry affected - MOVS r0,r0,LSL #Log2PageSize ;address is now ordinary again, and must be non-zero - MOV r1,#0 ;0 = AP for ordinary page - STMIA r5,{r0,r1} ;update CAM entry - MOV r12,r7 - MOV pc,lr ;r0 is non-zero, NE status -; -; not our abort, but is possible that client abort handler is in app space, so force all -; app space pages in now (so that client abort handler does not cause lazy abort, scribbling over original abort details) -; - ASSERT No26bitCode ;assumes we have an abort stack! (recursive lazy fixup aborts may occur) -20 - MOV r1,#ApplicationStart ;good old page walk to provoke lazy fixups - LDR r2,AMBMappedInNode - LDR r2,[r2,#AMBNode_Npages] - CMP r2,#0 - BEQ %FT90 - MRS r0,SPSR ;preserve SPSR_abort for original abort details - MOV r4,lr ;preserve lr_abort so we can return properly (!) - ARM_read_FAR r5 ;preserve FAR in case client abort handler wants to read it - ;preserve FSR (already in r6) similarly -30 - LDR r3,[r1] ;bring that page in by the magic of aborts - SUBS r2,r2,#1 - ADD r1,r1,#PageSize - BNE %BT30 - MSR SPSR_cxsf,r0 ;SPSR for original abort - MOV lr,r4 ;restore return address - ARM_write_FAR r5 ;restore FAR - ARM_write_FSR r6 ;restore FSR -; -90 - MOVS r0,#0 - MOV r12,r7 - MOV pc,lr ;r0 is zero, EQ status - - ] ;AMB_LazyMapIn - -; ---------------------------------------------------------------------------------- - - [ AMB_LazyMapIn - -; -; If page of given logical address (r0) is in current app space, make sure page is -; 'honest' ie. properly mapped in. This is for things like FindMemMapEntries -; that must return sensible info (and presumably their client needs a consistent -; view of app space mapping, so that laziness is transparent) -; -AMB_MakeHonestLA ROUT - CMP r0,#AbsMaxAppSize ;quick dismiss if definitely not app address - MOVHS pc,lr - Push "r1,r12,lr" - MOV r12,#AMBControl_ws - LDR r12,[r12] - CMP r12,#0 - BEQ %FT90 ;we're dormant! - SUBS r14,r0,#ApplicationStart - BMI %FT90 ;below app space - MOV r14,r14,LSR #Log2PageSize ;pages from ApplicationStart - LDR r1,AMBMappedInNode - CMP r1,#0 - BEQ %FT90 ;no node mapped in - LDR r1,[r1,#AMBNode_Npages] - CMP r1,r14 ;HI if log addr is in current app space - LDRHI r1, [r0,#0] ;make honest if necessary (magic of abort fixups!) -90 - Pull "r1,r12,pc" - - -; similar to AMB_MakeHonestLA, but for page of given page number (r0) -; -AMB_MakeHonestPN ROUT - Push "r1-r3,r12,lr" - MOV r12,#AMBControl_ws - LDR r12,[r12] - CMP r12,#0 - BEQ %FT90 ;we're dormant! - MOV r14,#0 - LDR r1,[r14,#MaxCamEntry] - CMP r0,r1 - BHI %FT90 ;invalid page number - LDR r1,[r14,#CamEntriesPointer] - LDR r1,[r1,r0,LSL #3] ;logical address from CAM - LDR r14,=Nowhere - TEQ r1,r14 - BNE %FT90 ;only a page at Nowhere might be dishonest - LDR r1,AMBMappedInNode ;let's check the current node - CMP r1,#0 - BEQ %FT90 ;no node mapped in - LDR r14,[r1,#AMBNode_Npages] - MOV r14,r14,LSL #Log2PageSize - ADD r14,r14,#ApplicationStart ;top of current app space - ADD r1,r1,#AMBNode_pages ;[r1] is page number - MOV r2,#ApplicationStart ;r2 is logical address for page -10 - CMP r2,r14 - BHS %FT90 - LDR r3,[r1],#4 ;next page number in node - TEQ r3,r0 ;see if its the one that wants to be honest - ADDNE r2,r2,#PageSize ;next logical address - BNE %BT10 - LDR r1,[r2,#0] ;make honest if necessary (magic of abort fixups!) -90 - Pull "r1-r3,r12,pc" - - ] ;AMB_LazyMapIn - -; ---------------------------------------------------------------------------------- -; -;AMB_movepagesin_L2PT -; -;updates L2PT for new logical page positions, does not update CAM -; -; entry: -; r3 = new logical address of 1st page -; r8 = number of pages -; r10 -> page list -; r11 = protection/control bits for L2PT -; -AMB_movepagesin_L2PT ROUT - Push "r0-r10,r12,lr" - - LDR lr,AMBPhysBin ;lr -> PhysBin - LDR r9,=L2PT - ADD r9,r9,r3,LSR #(Log2PageSize-2) ;r9 -> L2PT for 1st new logical page - - CMP r8,#8 - BLT %FT20 -10 - LDMIA r10!,{r0-r7} ;next 8 page numbers - PageNumToL2PT r0,lr,r11,r12 - PageNumToL2PT r1,lr,r11,r12 - PageNumToL2PT r2,lr,r11,r12 - PageNumToL2PT r3,lr,r11,r12 - PageNumToL2PT r4,lr,r11,r12 - PageNumToL2PT r5,lr,r11,r12 - PageNumToL2PT r6,lr,r11,r12 - PageNumToL2PT r7,lr,r11,r12 - STMIA r9!,{r0-r7} ;write 8 L2PT entries - SUB r8,r8,#8 - CMP r8,#8 - BGE %BT10 -20 - CMP r8,#0 - BEQ %FT35 -30 - LDR r0,[r10],#4 - PageNumToL2PT r0,lr,r11,r12 - STR r0,[r9],#4 - SUBS r8,r8,#1 - BNE %BT30 -35 - Pull "r0-r10,r12,pc" - -; ---------------------------------------------------------------------------------- -; -;update CAM entry for page number in $reg -; -;entry: r11 -> CAM, r9 = logical addr of page, lr = PPL of page -;exit: $reg = addr of CAM entry -; - MACRO - UpdateCAM $reg - ADD $reg,r11,$reg,LSL #3 ;r0 -> CAM entry for 1st page - STMIA $reg,{r9,lr} ;store logical addr,PPL - MEND - -; ---------------------------------------------------------------------------------- -; -;AMB_movepagesin_CAM -; -;updates CAM, does not update L2PT -; -; entry: -; r3 = new logical address of 1st page -; r8 = number of pages -; r9 = PPL for CAM -; r10 -> page list -; -AMB_movepagesin_CAM ROUT - Push "r0-r11,lr" - - - MOV lr,r9 - MOV r9,r3 - MOV r11,#0 - LDR r11,[r11,#CamEntriesPointer] ;r11 -> CAM - - CMP r8,#8 - BLT %FT20 -10 - LDMIA r10!,{r0-r7} ;next 8 page numbers - UpdateCAM r0 - ADD r9,r9,#PageSize ;next logical addr - UpdateCAM r1 - ADD r9,r9,#PageSize - UpdateCAM r2 - ADD r9,r9,#PageSize - UpdateCAM r3 - ADD r9,r9,#PageSize - UpdateCAM r4 - ADD r9,r9,#PageSize - UpdateCAM r5 - ADD r9,r9,#PageSize - UpdateCAM r6 - ADD r9,r9,#PageSize - UpdateCAM r7 - ADD r9,r9,#PageSize - SUB r8,r8,#8 - CMP r8,#8 - BGE %BT10 -20 - CMP r8,#0 - Pull "r0-r11,pc",EQ -30 - LDR r0,[r10],#4 - UpdateCAM r0 - ADD r9,r9,#PageSize - SUBS r8,r8,#1 - BNE %BT30 - Pull "r0-r11,pc" - -; ---------------------------------------------------------------------------------- -; -;AMB_movepagesout_CAM -; -;updates CAM, does not update L2PT -; -; entry: -; r8 = number of pages -; r9 = PPL for CAM -; r10 -> page list -; -AMB_movepagesout_CAM ROUT - Push "r0-r11,lr" - - MOV lr,r9 - LDR r9,=DuffEntry - MOV r11,#0 - LDR r11,[r11,#CamEntriesPointer] ;r11 -> CAM - - CMP r8,#8 - BLT %FT20 -10 - LDMIA r10!,{r0-r7} ;next 8 page numbers - UpdateCAM r0 - UpdateCAM r1 - UpdateCAM r2 - UpdateCAM r3 - UpdateCAM r4 - UpdateCAM r5 - UpdateCAM r6 - UpdateCAM r7 - SUB r8,r8,#8 - CMP r8,#8 - BGE %BT10 -20 - CMP r8,#0 - Pull "r0-r11,pc",EQ -30 - LDR r0,[r10],#4 - UpdateCAM r0 - SUBS r8,r8,#1 - BNE %BT30 - Pull "r0-r11,pc" - -; ---------------------------------------------------------------------------------- -; -;AMB_movepagesout_L2PT -; -;updates L2PT for old logical page positions, does not update CAM -; -; entry: -; r4 = old logical address of 1st page -; r8 = number of pages -; -AMB_movepagesout_L2PT ROUT - Push "r0-r8,lr" - - LDR lr,=L2PT - ADD lr,lr,r4,LSR #(Log2PageSize-2) ;lr -> L2PT 1st entry - - MOV r0,#0 ;0 means translation fault - MOV r1,#0 - MOV r2,#0 - MOV r3,#0 - MOV r4,#0 - MOV r5,#0 - MOV r6,#0 - MOV r7,#0 - - CMP r8,#8 - BLT %FT20 -10 - STMIA lr!,{r0-r7} ;blam! (8 entries) - SUB r8,r8,#8 - CMP r8,#8 - BGE %BT10 -20 - CMP r8,#0 - BEQ %FT35 -30 - STR r0,[lr],#4 - SUBS r8,r8,#1 - BNE %BT30 -35 - Pull "r0-r8,pc" - -; ---------------------------------------------------------------------------------- -; -; AMB_SetMemMapEntries: -; -; entry: -; R3 = no. of pages -; R4 -> list of page entries (1 word per entry, giving page no.) -; R5 = start logical address of mapping (-1 means 'out of the way') -; R6 = PPL ('page protection level') for mapping -; -AMB_SetMemMapEntries ROUT - - Push "r0-r4,r7-r11,lr" - - MOVS r8,r3 - BEQ AMB_smme_exit - - CMP r5,#-1 - MOVEQ r9,#AP_Duff ;PPL for mapped out pages - MOVNE r9,r6 ;PPL for mapped in pages - -;get L2PT protection etc. bits, appropriate to PPL in R9, into R11 - ADRL r1,PPLTrans - AND lr,r9,#3 - LDR r11,[r1,lr,LSL #2] - TST r9,#DynAreaFlags_NotCacheable - TSTEQ r9,#PageFlags_TempUncacheableBits - ORREQ r11,r11,#L2_C ;if cacheable (area bit CLEAR + temp count zero), then OR in C bit - TST r9,#DynAreaFlags_NotBufferable - ORREQ r11,r11,#L2_B ;if bufferable (area bit CLEAR), then OR in B bit - - MOV r10,r4 ;ptr to next page number - - LDR r2,[r10] ;page number of 1st page - MOV r7,#0 - LDR r7,[r7,#CamEntriesPointer] ;r7 -> CAM - ADD r1,r7,r2,LSL #3 ;r1 -> CAM entry for 1st page - [ AMB_LimpidFreePool - LDR r4,[r1] ;fetch old logical addr. of 1st page from CAM - LDR r3,[r1,#4] ;fetch old PPL of 1st page from CAM - | - LDR r4,[r1] ;fetch old logical addr. of 1st page from CAM - ] - - CMP r5,#-1 - BEQ AMB_smme_mapout -;map or mapin - LDR r1,=DuffEntry - CMP r4,r1 - BEQ AMB_smme_mapin - -;map from somewhere to somewhere (should be App Space <-> Free Pool) -; - [ AMB_LimpidFreePool - ;can avoid cache clean/flush for moving pages out from FreePool, since FreePool pages are uncacheable - ; - TST r3, #DynAreaFlags_NotCacheable ;test PPL of 1st page for not cacheable bit set - BEQ AMB_smme_mapnotlimpid ;if clear, must do full map somewhere with cache clean/flush - ; - ;this should be map FreePool -> App Space then - ; - MOV r0,r4 ;address of 1st page - MOV r1,r8 ;number of pages - MOV r3,#0 - ARMop MMU_ChangingUncachedEntries,,,r3 ;no cache worries, hoorah - MOV r3,r5 - BL AMB_movepagesout_L2PT ;unmap 'em from where they are - BL AMB_movepagesin_L2PT ;map 'em to where they now be - BL AMB_movepagesin_CAM ;keep the bloomin' soft CAM up to date - Pull "r0-r4,r7-r11, pc" -AMB_smme_mapnotlimpid - ] -; - MOV r0,r4 ;address of 1st page - MOV r1,r8 ;number of pages - MOV r3,#0 - ARMop MMU_ChangingEntries,,,r3 ; - MOV r3,r5 - BL AMB_movepagesout_L2PT - BL AMB_movepagesin_L2PT - BL AMB_movepagesin_CAM - Pull "r0-r4,r7-r11, pc" - -;all pages sourced from same old logical page Nowhere, ie. pages currently mapped out, no cache worries -; -AMB_smme_mapin - MOV r0,r4 ;address of 1st page - MOV r1,r8 ;number of pages - MOV r3,#0 - ARMop MMU_ChangingUncachedEntries,,,r3 ;TLB coherency, possibly not needed (TLBs shouldn't cache 0 entries) - MOV r3,r5 - BL AMB_movepagesin_L2PT - BL AMB_movepagesin_CAM - Pull "r0-r4,r7-r11, pc" - -;all pages destined for same new logical page Nowhere, ie. mapping them out -; -AMB_smme_mapout - MOV r0,r4 ;address of 1st page - MOV r1,r8 ;number of pages - MOV r3,#0 - ARMop MMU_ChangingEntries,,,r3 ; - LDR r3,=DuffEntry - BL AMB_movepagesout_L2PT - BL AMB_movepagesout_CAM - -AMB_smme_exit - Pull "r0-r4,r7-r11, pc" - - - - [ AMB_LazyMapIn - -; ---------------------------------------------------------------------------------- -; -; AMB_SetMemMapEntries_SparseMapOut: -; -; -; entry: -; R3 = no. of pages currently mapped in (0=none) -; R4 -> list of page entries (1 word per entry, giving page no.) -; R5 -> bitmap of pages mapped in (1 bit per page in whole page list) -; R6 = total no. of pages in slot -; -AMB_SetMemMapEntries_SparseMapOut ROUT - - CMP r3,#0 - MOVEQ pc,lr - Push "r0-r11,lr" - - MOV r10,r4 ;ptr to page list - MOV r7,#0 - LDR r7,[r7,#CamEntriesPointer] ;r7 -> CAM - MOV r9,#AP_Duff ;permissions for DuffEntry - LDR r1,=DuffEntry ;means Nowhere, in CAM - MOV r4,#ApplicationStart ;log. address of first page - MOV r2,#0 ;r2 is zero during sparse map out - - ;if the number of pages mapped in is small enough, we'll do cache/TLB coherency on - ;just those pages, else global (performance decision, threshold probably not critical) - - ARMop Cache_RangeThreshold,,,r2 ;returns threshold (bytes) in r0 - CMP r3,r0,LSR #Log2PageSize - MOVLO r6,#0 ;r6 := 0 if we are to do coherency as we go - BLO %FT10 ;let's do it - - ARMop MMU_Changing,,,r2 ;global coherency - B %FT10 - -;skip next 32 pages then continue -06 - ADD r10,r10,#32*4 - ADD r4,r4,#32*PageSize - -;find the sparsely mapped pages, map them out, doing coherency as we go if enabled -10 - MOV r8,#1 ;initial bitmap mask for new bitmap word - LDR r11,[r5],#4 ;next word of bitmap - CMP r11,#0 ;if next 32 bits of bitmap clear, skip - BEQ %BT06 ;skip loop must terminate if r3 > 0 -12 - TST r11,r8 ;page is currently mapped in if bit set - BEQ %FT16 - TEQ r6, #0 - BNE %FT14 ;check for coherency as we go - MOV r0,r4 ;address of page - ARMop MMU_ChangingEntry,,,r2 -14 - LDR r0,[r10] ;page no. - ADD r0,r7,r0,LSL #3 ;r0 -> CAM entry for page - STMIA r0,{r1,r9} ;CAM entry for page set to DuffEntry,AP_Duff - LDR lr,=L2PT ;lr -> L2PT - STR r2,[lr,r4,LSR #(Log2PageSize-2)] ;L2PT entry for page set to 0 (means translation fault) - SUBS r3,r3,#1 - STREQ r2,[r5,#-4] ;make sure we clear last word of bitmap, and... - BEQ %FT20 ;done -16 - ADD r10,r10,#4 ;next page no. - ADD r4,r4,#PageSize ;next logical address - MOVS r8,r8,LSL #1 ;if 32 bits processed... - BNE %BT12 - STR r2,[r5,#-4] ;zero word of bitmap we've just traversed (r2 is 0) - B %BT10 - -20 - Pull "r0-r11,pc" - - - -; ---------------------------------------------------------------------------------- -; -; AMB_MakeUnsparse -; -; entry: r0 = size of area (at top of current slot) to ensure is not sparsely mapped -; -; action: walk over space involved, to force abort handler fix up to map in any -; pages not already there -; -AMB_MakeUnsparse ROUT - Push "r0-r2,r12,lr" -; Debug AMB,"AMB_MakeUnsparse r0",r0 - ADD r0,r0,#PageSize - SUB r0,r0,#1 - MOVS r0,r0,LSR #Log2PageSize - BEQ %FT20 - MOV r12,#AMBControl_ws - LDR r12,[r12] - CMP r12,#0 - BEQ %FT20 - LDR r1,AMBMappedInNode - CMP r1,#0 - BEQ %FT20 - LDR r2,AMBFlags - TST r2,#AMBFlag_LazyMapIn_disable :OR: AMBFlag_LazyMapIn_suspend - BNE %FT20 - [ AMB_ChocTrace - LDR r2,AMBNmakeunsparse - ADD r2,r2,#1 - STR r2,AMBNmakeunsparse - ] - LDR r2,[r1,#AMBNode_Npages] -; Debug AMB,"AMB_MakeUnsparse pages Npages ",r0,r2 - CMP r0,r2 - MOVHI r0,r2 - SUB lr,r2,r0 - MOV lr,lr,LSL #Log2PageSize - ADD lr,lr,#ApplicationStart -; Debug AMB,"AMB_MakeUnsparse MappedInNode addr pages ",r1,lr,r0 -10 - LDR r2,[lr] ;tends to wash data cache a bit, but this should be called rarely - ADD lr,lr,#PageSize - SUBS r0,r0,#1 - BNE %BT10 -20 - Pull "r0-r2,r12,pc" - - - ] ;AMB_LazyMapIn - -; ---------------------------------------------------------------------------------- -; -; AMB_FindMemMapEntries -; -; finds page numbers for pages currently at given logical start address, -; and fills in buffer; pages must exist -; -; (does not have any page number guesses) -; -; entry: -; R3 = no. of pages -; R4 -> buffer for page entries -; R5 = logical address of 1st page -; exit: -; buffer at R4 filled in with page numbers -; -AMB_FindMemMapEntries ROUT - - Push "r0-r11,lr" - -;initialise r0,r1,r2 as physical RAM chunk cache for AMB_r11topagenum routine - MOV r9,#PhysRamTable - LDMIA r9,{r0,r1} ;r0,r1 := phys addr,size of chunk - ADD r1,r1,r0 ;r0,r1 := lowest addr,highest addr + 1 of chunk - MOV r2,#0 ;r2 := first page number of chunk - - LDR r10,=L2PT - ADD r10,r10,r5,LSR #(Log2PageSize-2) ;r10 -> L2 entry for 1st page - CMP r3,#4 ;handle pages in chunks of 4 - BLT %FT20 -10 - LDMIA r10!,{r5-r8} ;next 4 L2PT entries - MOV r11,r5,LSR #Log2PageSize ;r11 := phys_addr/page_size - BL AMB_r11topagenum - MOV r5,r11 - MOV r11,r6,LSR #Log2PageSize - BL AMB_r11topagenum - MOV r6,r11 - MOV r11,r7,LSR #Log2PageSize - BL AMB_r11topagenum - MOV r7,r11 - MOV r11,r8,LSR #Log2PageSize - BL AMB_r11topagenum - STMIA r4!,{r5-r7,r11} ;fill in next 4 page numbers - SUB r3,r3,#4 - CMP r3,#4 - BGE %BT10 -20 - CMP r3,#0 - Pull "r0-r11,pc",EQ -30 - LDR r11,[r10],#4 - MOV r11,r11,LSR #Log2PageSize - BL AMB_r11topagenum - STR r11,[r4],#4 - SUBS r3,r3,#1 - BNE %BT30 - Pull "r0-r11,pc" - -; ---------------------------------------------------------------------------------- -; -;AMB_r11topagenum -;entry: -; r0,r1,r2 = lowest addr,highest addr +1,first page no. -; (cached physical RAM chunk) -; r11 = physical_addr/page_size for page -; -;exit: -; r11 = page number of page -; r0,r1,r2 cache updated if necessary -; r9 corrupted -; -AMB_r11topagenum ROUT - CMP r11,r0,LSR #Log2PageSize - BLO %FT10 - CMP r11,r1,LSR #Log2PageSize - BHS %FT10 -;cache hit (phys address in range of cached chunk) - SUB r11,r11,r0,LSR #Log2PageSize ;pages into chunk - ADD r11,r11,r2 ;page number - MOV pc,lr -10 - MOV r9,#PhysRamTable - MOV r2,#0 ;start at page number 0 -20 - LDMIA r9!,{r0,r1} ;r0,r1 := phys addr,size of chunk - SUB r11,r11,r0,LSR #Log2PageSize - CMP r11,r1,LSR #Log2PageSize - ADDHS r11,r11,r0,LSR #Log2PageSize - ADDHS r2,r2,r1,LSR #Log2PageSize - BHS %BT20 - ADD r1,r1,r0 - ADD r11,r11,r2 - MOV pc,lr - - LTORG - - END diff --git a/s/AMBControl/readinfo b/s/AMBControl/readinfo deleted file mode 100644 index 977297da..00000000 --- a/s/AMBControl/readinfo +++ /dev/null @@ -1,68 +0,0 @@ -; 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. -; -; > s.readinfo - -; handle read info. reason code - -;entry: -; R0 = reason code and flags -; bits 0-7 4 (reason code) -; bits 8-31 reserved (must be 0) -; R2 = handle - -;exit: -; R1 = current mapping start address; -1 means mapped out -; R3 = currently allocated number of pages - -readinfo - Push "R0,LR" - - [ ValidateAMBHandles - ;validate handle - LDR R0,AMBNhandles - CMP R2,R0 - BGT badhandle_rinfo - CMP R2,#1 - BLT badhandle_rinfo - ] - - LDR R0,AMBNodeHandles ; R0 -> handle array - LDR R1,[R0,R2,LSL #2] ; R1 -> node - - [ ValidateAMBHandles - ;check we have a proper id for node handle - LDR R3,=AMBMagicNodeID - LDR LR,[R1,#AMBNode_id] - CMP LR,R3 - BNE badhandle_rinfo - ] - - LDR R3,[R1,#AMBNode_Npages] - LDR R1,[R1,#AMBNode_startaddr] - LDR LR,=DuffEntry - CMP R1,LR - MOVEQ R1,#-1 - Pull "R0,LR" - B SLVK - - LTORG - - [ ValidateAMBHandles -badhandle_rinfo - Pull "R0,LR" - B badhandle - ] - - END diff --git a/s/AMBControl/service b/s/AMBControl/service deleted file mode 100644 index a6328647..00000000 --- a/s/AMBControl/service +++ /dev/null @@ -1,246 +0,0 @@ -; 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. -; -; > s.service - -; routines hanging on (kernel direct equiv. of) memory service calls - - -;Service_MemoryMoved -; -; if there is a mapped-in node then recheck which and how many pages it owns -; -; it is only necessary to: -; 1) reset node's idea of Npages to agree with no. of pages in app space -; 2) if Npages has increased, find the page numbers for new pages [and update -; the mapped in list, if LazyMapIn] -; ie. page numbers of existing pages are not messed with -; -AMBsrv_memorymoved ROUT - Push "R3-R6,R12,LR" - - MOV R12,#AMBControl_ws - LDR R12,[R12] - CMP R12,#0 - Pull "R3-R6,R12,PC",EQ ;AMBControl not initialised yet! - - LDR R4,AMBMappedInNode - CMP R4,#0 - Pull "R3-R6,R12,PC",EQ ;done if nothing mapped in - - LDR R3,[R4,#AMBNode_Npages] - - LDR R6,=AppSpaceDANode - LDR R6,[R6,#DANode_Size] - SUB R6,R6,#ApplicationStart - MOV R6,R6,LSR #Log2PageSize - - CMP R6,R3 - STRNE R6,[R4,#AMBNode_Npages] ;update Npages - [ AMB_LazyMapIn - Pull "R3-R6,R12,PC",EQ ;done if Npages same - BLT %FT22 ;shrink - | - Pull "R3-R6,R12,PC",LE ;done if Npages same, or shrink - ] - - MOV R5,#ApplicationStart - ADD R5,R5,R3,LSL #Log2PageSize ;first logical address to find - ADD R4,R4,#AMBNode_pages - ADD R4,R4,R3,LSL #2 ;first page number word to use - SUB R3,R6,R3 ;no. of pages to find (grow number) - BL AMB_FindMemMapEntries - - [ AMB_LazyMapIn - ;if Npages has grown, update AMBMappedInNpages and set bits in bitmap for - ;new pages, since these will be mapped in. - ; -; Debug AMB,"AMBsrv +Npages ",R3 - [ AMB_ChocTrace - LDR R5,AMBNmemmovegrow - ADD R5,R5,#1 - STR R5,AMBNmemmovegrow - ] - LDR R5,AMBFlags - TST R5,#AMBFlag_LazyMapIn_disable :OR: AMBFlag_LazyMapIn_suspend - BNE %FT21 - LDR R5,AMBMappedInNpages - ADD R5,R5,R3 - STR R5,AMBMappedInNpages - LDR R4,AMBMappedInNode - LDR R5,[R4,#AMBNode_Npages] - SUB R5,R5,R3 - ADR R6,AMBMappedInRegister - ADD R6,R6,R5,LSR #5-2 ;first word of bitmap affected - BIC R6,R6,#3 - AND R5,R5,#31 ;first bit of word - MOV R4,#1 - MOV R5,R4,LSL R5 ;bitmap mask - LDR R4,[R6],#4 -10 - ORR R4,R4,R5 - SUBS R3,R3,#1 - STREQ R4,[R6,#-4] - BEQ %FT20 - MOVS R5,R5,LSL #1 - BNE %BT10 - STR R4,[R6,#-4] - MOV R4,#-1 -12 - CMP R3,#32 - BLT %FT14 - STR R4,[R6],#4 - SUBS R3,R3,#32 - BEQ %FT20 - B %BT12 -14 - MOV R5,#1 - LDR R4,[R6],#4 - B %BT10 -20 -21 - Pull "R3-R6,R12,PC" - -22 - SUB R3,R3,R6 ;no. of pages removed from app space (known unsparse before removal) -; Debug AMB,"AMBsrv -Npages ",R3 - [ AMB_ChocTrace - LDR R5,AMBNmemmoveshrink - ADD R5,R5,#1 - STR R5,AMBNmemmoveshrink - ] - LDR R5,AMBFlags - TST R5,#AMBFlag_LazyMapIn_disable :OR AMBFlag_LazyMapIn_suspend - BNE %FT41 - LDR R5,AMBMappedInNpages - SUB R5,R5,R3 - STR R5,AMBMappedInNpages - LDR R4,AMBMappedInNode - LDR R5,[R4,#AMBNode_Npages] - ADR R6,AMBMappedInRegister - ADD R6,R6,R5,LSR #5-2 ;first word of bitmap affected - BIC R6,R6,#3 - AND R5,R5,#31 ;first bit of word - MOV R4,#1 - MOV R5,R4,LSL R5 ;bitmap mask - LDR R4,[R6],#4 -30 - BIC R4,R4,R5 - SUBS R3,R3,#1 - STREQ R4,[R6,#-4] - BEQ %FT40 - MOVS R5,R5,LSL #1 - BNE %BT30 - STR R4,[R6,#-4] - MOV R4,#0 -32 - CMP R3,#32 - BLT %FT34 - STR R4,[R6],#4 - SUBS R3,R3,#32 - BEQ %FT40 - B %BT32 -34 - MOV R5,#1 - LDR R4,[R6],#4 - B %BT30 -40 -41 - ] ;AMB_LazyMapIn - - Pull "R3-R6,R12,PC" - - -;Service_PagesSafe -; entry: R2 = no. pages involved, -; R3 -> page block describing state before -; R4 -> page block describing state after -; -; action: fix-up page numbers in page lists of nodes as necessary -; -AMBsrv_pagessafe ROUT - Push "R0-R1,R5-R10,R12,LR" - - MOV R12,#AMBControl_ws - LDR R12,[R12] - CMP R12,#0 - Pull "R0-R1,R5-R10,R12,PC",EQ ;AMBControl not initialised yet! - - LDR R0,AMBNtasks - CMP R0,#0 - Pull "R0-R1,R5-R10,R12,PC",EQ ;no nodes to check - -;speed-up - list of pages tends to span a narrow range of page numbers, so -; use min,max limits to skip search - MOV R9,#&7FFFFFFF - MOV R10,#0 - MOV R0,R3 - MOV R1,R2 -00 - LDR R5,[R0],#12 - CMP R9,R5 - MOVGT R9,R5 ;remember minimum 'before' page no. in R9 - CMP R10,R5 - MOVLT R10,R5 ;remember maximum 'before' page no. in R10 - SUBS R1,R1,#1 - BNE %BT00 - - ADR R0,AMBAnchorNode - MOV R1,R0 - Push "R0,R1" - B %FT03 -01 -;check pages for this node - LDR R5,[R0,#AMBNode_Npages] - CMP R5,#0 - BEQ %FT04 ;skip if node has zero pages - ADD R6,R0,#AMBNode_pages - Push "R0,R1" -02 -;for each page in node - LDR R7,[R6] ;page no. from node - CMP R7,R9 - BLT %FT13 ;not in list ( < 'before' min) - CMP R7,R10 - BGT %FT13 ;not in list ( > 'before' max) -;oh dear! search of before,after lists required - MOV LR,R2 - MOV R0,R3 - MOV R1,R4 -11 - LDR R8,[R0],#12 ;next page from before list - CMP R8,R7 ;matches node page? - BEQ %FT12 - ADD R1,R1,#12 ;step the after list - SUBS LR,LR,#1 - BNE %BT11 - B %FT13 ;done pages in node,not matched -12 - LDR R8,[R1] ;fetch new page number from after list - STR R8,[R6] ;store it for node -13 - ADD R6,R6,#4 ;next page in node - SUBS R5,R5,#1 - BNE %BT02 -03 - Pull "R0,R1" -04 -;next node - LDR R0,[R0,#AMBNode_next] - CMP R0,R1 ;done if back at anchor node - BNE %BT01 - Pull "R0-R1,R5-R10,R12,PC" - - END - diff --git a/s/AMBControl/shrinkp b/s/AMBControl/shrinkp deleted file mode 100644 index 2c965c75..00000000 --- a/s/AMBControl/shrinkp +++ /dev/null @@ -1,102 +0,0 @@ -; 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. -; -; > s.shrinkp - - -;shrink slot by taking pages (from AppSpace); add them to FreePool - - -; entry: -; R1 = new number of pages for slot (less than current value) -; R2 -> AMB Node - -shrinkpages - Push "R0-R7,LR" - - MOV R6,R1 ;save entry R1 - LDR R5,[R2,#AMBNode_Npages] - CMP R5,R6 - Pull "R0-R7,PC",EQ ;done if no. of pages unchanged - - MOV R0,R2 ;R0 -> AMB node - -;set R3 to 1 if deallocate is from mapped-in slot (so AppSpace needs update) - LDR R5,AMBMappedInNode - CMP R5,R0 - MOVEQ R3,#1 ;flag this is the mapped-in node - MOVNE R3,#0 ;flag is not - - [ AMB_LazyMapIn - ;first make sure the current mapping of mapped in node is simple, - ;so that main mapping can cope - easiest thing is to do a sparse map out - ; - BNE %FT02 - Push "R3,R6" - LDR R3,AMBFlags - TST R3,#AMBFlag_LazyMapIn_disable :OR: AMBFlag_LazyMapIn_suspend - BNE %FT01 - LDR R3,AMBMappedInNpages - ADD R4,R5,#AMBNode_pages - LDR R6,[R5,#AMBNode_Npages] - ADR R5,AMBMappedInRegister - BL AMB_SetMemMapEntries_SparseMapOut - MOV R3,#0 - STR R3,AMBMappedInNpages -01 - Pull "R3,R6" -02 - ] - - TST R3,#1 ;check flag - MOVEQ R1,#0 ;source is not App space - LDRNE R1,=AppSpaceDANode ;source is App space - LDR R2,=FreePoolDANode ;dest - - LDR R7,[R0,#AMBNode_Npages] ;R7 := current number of pages - SUBS R3,R7,R6 ;R3 := no. of pages to move - BEQ %FT02 ;done if no pages to move - STR R6,[R0,#AMBNode_Npages] ;new no. of pages - - ADD R4,R0,#AMBNode_pages - ADD R4,R4,R6,LSL #2 ;R4 -> 1st page table entry for shrink - LDR R5,[R2,#DANode_Base] - LDR R6,[R2,#DANode_Size] - ADD R5,R5,R6 ;R5 -> current end of FreePool - LDR R6,[R2,#DANode_Flags] - AND R6,R6,#&7F ;R6 = dest PPL flags - - ;entry: R3 = no. of pages, R4 -> list of page entries, - ; R5 = start logical address, R6 = PPL - BL AMB_SetMemMapEntries ;remap - - LDR R0,[R2,#DANode_Size] - ADD R0,R0,R3,LSL #Log2PageSize - STR R0,[R2,#DANode_Size] - -;update Application Space kernel values, if required - CMP R1,#0 - LDRNE R0,[R1,#DANode_Size] - SUBNE R0,R0,R3,LSL #Log2PageSize - STRNE R0,[R1,#DANode_Size] - MOVNE R5,#0 - STRNE R0,[R5,#MemLimit] ;update MemLimit - -02 -;;; STRVS R0,[SP] - CLRV - Pull "R0-R7,PC" - - - END diff --git a/s/ARM600 b/s/ARM600 deleted file mode 100644 index 413f69da..00000000 --- a/s/ARM600 +++ /dev/null @@ -1,3569 +0,0 @@ -; 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. -; -; > ARM600 - - GBLL DebugAborts -DebugAborts SETL {FALSE} - - -; MMU interface file - ARM600 version - -; Created by TMD 15-Jul-92 -; Comments updated by TMD 04-Aug-93 - -;24-01-96 MJS now effectively codes for ARM 6 onwards (6,7,8,A, where A = StrongARM) -; but ARM8 not properly supported (not needed for RO 3.70) -;07-10-96 MJS proper support for ARM810 added - - -; Workspace needed for ARM600 work is as follows: -; -; * Level 2 page tables for a contiguous logical area starting at zero -; This consists of: -; a) a fixed size bit covering 0 to 192M (currently) -; b) a variable size bit covering the free pool - 192M to 192M + (memsize rounded up to 4M) -; Note that the 192M value is sufficient to cover all the fixed size areas at present. -; As more areas switch to new world, this limit will come down and down, but free pool must always -; start at the end of the fixed areas. -; (Level 2 for areas outside this region are allocated dynamically afterwards) -; -; * Level 1 page table (16K, stored in the middle of L2PT, where the I/O + ROM would be if it wasn't section mapped) -; -; * Undefined32 mode stack (8K) -; -; * Abort32 mode stack (8K) -; -; * Soft CAM map (variable size = memsize/4K*8, rounded up to 4K) -; -; In order to make the memory models for MEMC1 and IOMD harmonious, the MEMC1 system is considered as a section of -; video RAM starting at &02000000 size 480K, and an area of "non-video RAM" starting at &02078000, size (totalRAM-480K) -; IOMD has 1 area of video RAM and up to 4 areas of non-video RAM. -; -; (Note: when OS is soft-loaded, a 2 Mbyte chunk of DRAM is removed from the RAM map, therefore the model allows for -; 1 area of video RAM and up to 5 areas of non-video RAM) -; -; The fixed system pages (which include those described above) start at the base of the first bank of non-video RAM -; (on IOMD we allow this to be in any of the 4 RAM sites, ie you don't have to have RAM in any particular SIMM site) -; Consequently the base of the fixed system pages is not known at assembly time, so has to be passed in a register -; to the generic code. -; -; amg 7/12/96 Renaissance, import changes below from Spinner tree, but this is fundamentally the -; 3.70 file. - -; 17-Jun-96 BAR Change speed settings for the second bank of ROM space. -; 09-Jul-96 BAR Improve IOMD ID vsn code - two places. -; Change ROM Speed settings for 7500FE and non-7500FE parts. -; 25-Jul-96 BAR Correct bug in video bandwidth code, wrong label used. -; 16-Aug-96 JRH Programming of 2nd ROM bank (IOMD ROMCR1 register): -; reinstated ExtROMSupport code, added CanLiveOnROMCard code -; MemInitTable: -; If ExtROMSupport: added assertion that ImageSize <= 4096 -; and maps 4MB of each ROM bank. -; Otherwise: always maps 8MB of ROM space independant of ImageSize - - - -; Fixed page allocation is as follows - - ^ 0 - [ :LNOT: HAL -DRAMOffset_CursorChunk # 32*1024 ; ie on MEMC1 this is the last 32K of DAG-addressable memory -DRAMOffset_PageZero # 32*1024 ; 32K at location zero -DRAMOffset_SystemHeap # 32*1024 ; system heap/svc stack - [ No26bitCode -DRAMOffset_AbortStack # 8*1024 - ] - AlignSpace 16*1024 ; L1PT (and hence L2PT) must be 16K-aligned -DRAMOffset_L2PT # 0 ; static L2PT (variable size, with embedded L1PT) -DRAMOffset_L1PT * DRAMOffset_L2PT + 48*1024 - ] - -; Undefined stack memory (size 8K) starts immediately after end of L2PT (which is variable size) -; Soft CAM map (variable size) starts immediately after end of UndStack - -StaticPagesSize * @ - -; Logical addresses are as follows - - [ :LNOT: HAL -L2PT * &02C00000 ; size 256K -L1PT * &02C0C000 ; in the middle of L2PT, where the mapping for 03000000 to 03FFFFFF would be - ] - -FixedAreasL2Size * 96*1024 ; amount of L2 to cover fixed areas, excluding free pool - -UndStackSoftCamChunk * &01E00000 -UndStackSize * 8*1024 -CamEntriesForVicky * UndStackSoftCamChunk + UndStackSize - [ :LNOT: HAL -UNDSTK * CamEntriesForVicky ; points to end of stack -CAMspace * &02000000-CamEntriesForVicky - [ No26bitCode -AbtStack * &02000000 -AbtStackSize * 8*1024 -ABTSTK * AbtStack + AbtStackSize - ] -PhysSpace * &80000000 ; Map of MEMC/IOMD physical space (64M/512M in size) - ] - - -; - address for virtual area for StrongARM data cache cleaning (32k, for two 16k areas) -; - the two areas are used in strict rotation for each full clean, so that we can do a full -; clean (and not flush) with interrupts on -; - the address must be aligned such that EOR with 16*1024 flipflops between the two addresses -ARMA_Cleaners_address * &01F10000 - - - [ :LNOT: HAL -;note that we use the R bit if supported (not 610), so that we can write protect ROM space -;fully (user and supervisor) -; - [ :LNOT: CacheOff -ARM_default_MMU_CR_table -; -;ARM 6 SBLDPWCAM - DCD 2_0000001111101 -; -;ARM 7 FRSB1DPWCAM - DCD 2_0011001111101 -; -;ARM 8 Z0RSB111WCAM - DCD 2_0101001111101 -; -;ARM 9 ?? - DCD 0 -; -;StrongARM I00RSB111WCAM - DCD 2_1001001111101 -; - | -ARM_default_MMU_CR_table ; if CacheOff true, same as cacheoff table - ] -; -ARM_cacheoff_MMU_CR_table -; -;ARM 6 SBLDPWCAM - DCD 2_0000001110001 -; -;ARM 7 FRSB1DPWCAM - DCD 2_0011001110001 -; -;ARM 8 Z0RSB111WCAM - DCD 2_0001001110001 -; -;ARM 9 ?? - DCD 0 -; -;StrongARM I00RSB111WCAM - DCD 2_0001001110001 -; - - ] ; HAL - -OneMByte EQU (1024*1024) -SixteenMByte EQU (1024*1024 * 16) - - KEEP - -; ***************************************************************************** - -; mjs Oct 2000 kernel/HAL split -; SetDAG stuff is no more, routines like SetVinit now call equivalent HAL -; routine - -; **************** CAM manipulation utility routines *********************************** - -; ************************************************************************************** -; -; BangCamUpdate - Update CAM, MMU for page move, coping with page currently mapped in -; -; mjs Oct 2000 -; reworked to use generic ARM ops (vectored to appropriate routines during boot) -; -; First look in the CamEntries table to find the logical address L this physical page is -; currently allocated to. Then check in the Level 2 page tables to see if page L is currently -; at page R2. If it is, then map page L to be inaccessible, otherwise leave page L alone. -; Then map logical page R3 to physical page R2. -; -; in: r2 = physical page number -; r3 = logical address (2nd copy if doubly mapped area) -; r9 = offset from 1st to 2nd copy of doubly mapped area (either source or dest, but not both) -; r11 = PPL + CB bits -; -; out: r0, r1, r4, r6 corrupted -; r2, r3, r5, r7-r12 preserved -; -; NB Use of stack is allowed in this routine - -BangCamUpdate ROUT - TST r11, #DynAreaFlags_DoublyMapped ; if moving page to doubly mapped area - SUBNE r3, r3, r9 ; then CAM soft copy holds ptr to 1st copy - - MOV r1, #0 - LDR r1, [r1, #CamEntriesPointer] - ADD r1, r1, r2, LSL #3 ; point at cam entry (logaddr, PPL) - LDMIA r1, {r0, r6} ; r0 = current logaddress, r6 = current PPL - STMIA r1, {r3, r11} ; store new address, PPL - Push "r0, r6" ; save old logical address, PPL - MOV r1, #PhysRamTable ; go through phys RAM table - MOV r6, r2 ; make copy of r2 (since that must be preserved) -10 - LDMIA r1!, {r0, r4} ; load next address, size - SUBS r6, r6, r4, LSR #12 ; subtract off that many pages - BCS %BT10 ; if more than that, go onto next bank - - ADD r6, r6, r4, LSR #12 ; put back the ones which were too many - ADD r0, r0, r6, LSL #12 ; move on address by the number of pages left - LDMFD r13, {r6} ; reload old logical address - -; now we have r6 = old logical address, r2 = physical page number, r0 = physical address - - TEQ r6, r3 ; TMD 19-Jan-94: if old logaddr = new logaddr, then - BEQ %FT20 ; don't remove page from where it is, to avoid window - ; where page is nowhere. - LDR r1, =L2PT - ADD r6, r1, r6, LSR #10 ; r6 -> L2PT entry for old log.addr - MOV r4, r6, LSR #12 ; r4 = word offset into L2 for address r6 - LDR r4, [r1, r4, LSL #2] ; r4 = L2PT entry for L2PT entry for old log.addr - TST r4, #3 ; if page not there - BEQ %FT20 ; then no point in trying to remove it - - LDR r4, [r6] ; r4 = L2PT entry for old log.addr - MOV r4, r4, LSR #12 ; r4 = physical address for old log.addr - TEQ r4, r0, LSR #12 ; if equal to physical address of page being moved - BNE %FT20 ; if not there, then just put in new page - - Push "r0, r3, r11, r14" ; save phys.addr, new log.addr, new PPL, lr - ADD r3, sp, #4*4 - LDMIA r3, {r3, r11} ; reload old logical address, old PPL - MOV r0, #0 ; cause translation fault - BL BangL2PT ; map page out - Pull "r0, r3, r11, r14" -20 - ADD sp, sp, #8 ; junk old logical address, PPL - B BangCamAltEntry ; and branch into BangCam code - -; ************************************************************************************** -; -; BangCam - Update CAM, MMU for page move, assuming page currently mapped out -; -; This routine maps a physical page to a given logical address -; It is assumed that the physical page is currently not mapped anywhere else -; -; in: r2 = physical page number -; r3 = logical address (2nd copy if doubly mapped) -; r9 = offset from 1st to 2nd copy of doubly mapped area (either source or dest, but not both) -; r11 = PPL -; -; out: r0, r1, r4, r6 corrupted -; r2, r3, r5, r7-r12 preserved -; -; NB Can't use stack - there might not be one! -; -; NB Also - the physical page number MUST be in range. - -; This routine must work in 32-bit mode - -BangCam ROUT - TST r11, #DynAreaFlags_DoublyMapped ; if area doubly mapped - SUBNE r3, r3, r9 ; then move ptr to 1st copy - - MOV r1, #PhysRamTable ; go through phys RAM table - MOV r6, r2 ; make copy of r2 (since that must be preserved) -10 - LDMIA r1!, {r0, r4} ; load next address, size - SUBS r6, r6, r4, LSR #12 ; subtract off that many pages - BCS %BT10 ; if more than that, go onto next bank - - ADD r6, r6, r4, LSR #12 ; put back the ones which were too many - ADD r0, r0, r6, LSL #12 ; move on address by the number of pages left -BangCamAltEntry - LDR r4, =DuffEntry ; check for requests to map a page to nowhere - ADR r1, PPLTrans - TEQ r4, r3 ; don't actually map anything to nowhere - MOVEQ pc, lr - AND r4, r11, #3 ; first use PPL bits - LDR r1, [r1, r4, LSL #2] ; get PPL bits and SmallPage indicator - - [ {FALSE} - TST r11, #DynAreaFlags_NotCacheable - TSTEQ r11, #PageFlags_TempUncacheableBits - ORREQ r1, r1, #L2_C ; if cacheable (area bit CLEAR + temp count zero), then OR in C bit - TST r11, #DynAreaFlags_NotBufferable - ORREQ r1, r1, #L2_B ; if bufferable (area bit CLEAR), then OR in B bit - - ORR r0, r0, r1 - | - ASSERT DynAreaFlags_CPBits = 7 :SHL: 12 - ASSERT DynAreaFlags_NotCacheable = 1 :SHL: 5 - ASSERT DynAreaFlags_NotBufferable = 1 :SHL: 4 - - ORR r0, r0, r1 - - MOV r6, #ZeroPage - LDR r6, [r6, #MMU_PCBTrans] - AND r4, r11, #DynAreaFlags_CPBits - AND r1, r11, #DynAreaFlags_NotCacheable + DynAreaFlags_NotBufferable - TST r11, #PageFlags_TempUncacheableBits - ORRNE r1, r1, #DynAreaFlags_NotCacheable ; if temp uncache, set NC bit, ignore P - ORREQ r1, r1, r4, LSR #6 ; else use NC, NB and P bits - LDRB r1, [r6, r1, LSR #4] ; convert to X, C and B bits for this CPU - ORR r0, r0, r1 - ] - - LDR r1, =L2PT ; point to level 2 page tables - - ;fall through to BangL2PT - -;internal entry point for updating L2PT entry -; -; entry: r0 = new L2PT value, r1 -> L2PT, r3 = logical address (4k aligned), r11 = PPL -; -; exit: r0,r1,r4,r6 corrupted -; -BangL2PT ; internal entry point used only by BangCamUpdate - Push "lr" - MOV r6, r0 - - TST r11, #DynAreaFlags_DoublyMapped - BNE BangL2PT_sledgehammer ;if doubly mapped, don't try to be clever - - ;we sort out cache coherency _before_ remapping, because some ARMs might insist on - ;that order (write back cache doing write backs to logical addresses) - ;we need to worry about cache only if mapping out a cacheable page - ; - TEQ r6, #0 ;EQ if mapping out - TSTEQ r11, #DynAreaFlags_NotCacheable ;EQ if also cacheable (overcautious for temp uncache+illegal PCB combos) - MOV r0, r3 ;MMU page entry address - ADR lr, %FT20 - MOV r4, #0 - ARMop MMU_ChangingEntry, EQ, tailcall, r4 - ARMop MMU_ChangingUncachedEntry, NE, tailcall, r4 - -20 STR r6, [r1, r3, LSR #10] ;update L2PT entry - - Pull "pc" - -BangL2PT_sledgehammer - - ;sledgehammer is super cautious and does cache/TLB coherency on a global basis - ;should only be used for awkward cases - ; - TEQ r6, #0 ;EQ if mapping out - TSTEQ r11, #DynAreaFlags_NotCacheable ;EQ if also cacheable (overcautious for temp uncache+illegal PCB combos) - ADR lr, %FT30 - MOV r4, #0 - ARMop MMU_Changing, EQ, tailcall, r4 - ARMop MMU_ChangingUncached, NE, tailcall, r4 - -30 STR r6, [r1, r3, LSR #10]! ; update level 2 page table (and update pointer so we can use bank-to-bank offset - TST r11, #DynAreaFlags_DoublyMapped ; if area doubly mapped - STRNE r6, [r1, r9, LSR #10] ; then store entry for 2nd copy as well - ADDNE r3, r3, r9 ; and point logical address back at 2nd copy - - Pull "pc" - - -PPLTransL1 - & (AP_Full * L1_APMult) + L1_Section ; R any W any - & (AP_Read * L1_APMult) + L1_Section ; R any W sup - & (AP_None * L1_APMult) + L1_Section ; R sup W sup - & (AP_ROM * L1_APMult) + L1_Section ; R any W none - -PPLTrans - & (AP_Full * L2_APMult) + L2_SmallPage ; R any W any - & (AP_Read * L2_APMult) + L2_SmallPage ; R any W sup - & (AP_None * L2_APMult) + L2_SmallPage ; R sup W sup - & (AP_ROM * L2_APMult) + L2_SmallPage ; R any W none - -PPLTransX - & (AP_Full * L2X_APMult) + L2_ExtPage ; R any W any - & (AP_Read * L2X_APMult) + L2_ExtPage ; R any W sup - & (AP_None * L2X_APMult) + L2_ExtPage ; R sup W sup - & (AP_ROM * L2X_APMult) + L2_ExtPage ; R any W none - -PageSizes - & 4*1024 ; 0 is 4K - & 8*1024 ; 4 is 8K - & 16*1024 ; 8 is 16 - & 32*1024 ; C is 32 - -PageShifts - = 12, 13, 0, 14 ; 1 2 3 4 - = 0, 0, 0, 15 ; 5 6 7 8 - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; SWI OS_UpdateMEMC: Read/write MEMC1 control register - -SSETMEMC ROUT - - AND r10, r0, r1 - MOV r12, #0 - WritePSRc SVC_mode+I_bit+F_bit, r0 - LDR r0, [r12, #MEMC_CR_SoftCopy] ; return old value - BIC r11, r0, r1 - ORR r11, r11, R10 - BIC r11, r11, #&FF000000 - BIC r11, r11, #&00F00000 - ORR r11, r11, #MEMCADR - STR r11, [r12, #MEMC_CR_SoftCopy] - -; mjs Oct 2000 kernel/HAL split -; -; The kernel itself should now never call this SWI, but grudgingly has -; to maintain at least bit 10 of soft copy -; -; Here, we only mimic action of bit 10 to control video/cursor DMA (eg. for ADFS) -; The whole OS_UpdateMEMC thing would ideally be withdrawn as archaic, but -; unfortunately has not even been deprecated up to now - -; for reference, the bits of the MEMC1 control register are: -; -; bits 0,1 => unused -; bits 2,3 => page size, irrelevant since always 4K -; bits 4,5 => low ROM access time (mostly irrelevant but set it up anyway) -; bits 6,7 => hi ROM access time (definitely irrelevant but set it up anyway) -; bits 8,9 => DRAM refresh control -; bit 10 => Video/cursor DMA enable -; bit 11 => Sound DMA enable -; bit 12 => OS mode - - [ UseGraphicsV - Push "r0,r1,r4, r14" - TST r11, #(1 :SHL: 10) - MOVEQ r0, #1 ; blank (video DMA disable) - MOVNE r0, #0 ; unblank (video DMA enable) - MOV r1, #0 ; no funny business with DPMS - MOV r4, #GraphicsV_SetBlank - BL CallGraphicsV - Pull "r0,r1,r4, r14" - | - Push "r0-r3, r9, r14" ; can corrupt r12 - TST r11, #(1 :SHL: 10) - MOVEQ r0, #1 ; blank (video DMA disable) - MOVNE r0, #0 ; unblank (video DMA enable) - MOV r1, #0 ; no funny business with DPMS - MOV r0, #0 - MOV r1 - mjsAddressHAL - mjsCallHAL HAL_Video_SetBlank - Pull "r0-r3, r9, r14" - ] - - WritePSRc SVC_mode+I_bit, r11 - ExitSWIHandler - - [ :LNOT: HAL -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; -; ClearPhysRAM - Routine to clear "all" memory -; -; While this routine is running, keyboard IRQs may happen. For this reason -; it avoids LogRAM 0..31 (where hardware IRQ vector is) and PhysRAM -; 0..31 where the IRQ workspace is. -; -; We also have to avoid the L2PT (inc L1PT) and the PhysRamTable. -; The latter is also used to tell us which areas of memory we should clear. - -; We don't have to worry about trampling on the ROM image as it's -; already been excluded from PhysRamTable. - -; This routine must work in 32-bit mode. - -; in: r7 = memory speed -; r8 = page size -; r9 = MEMC control register -; r13 = total RAM size -; -; None of the above are actually used by this routine -; -; out: r7-r9, r13 preserved -; - - GBLL ClearPhysRAMspeedup -ClearPhysRAMspeedup SETL {TRUE} - -ClearPhysRAM ROUT - - [ EmulatorSupport - ARM_on_emulator r0 - BEQ CPR_skipped - ] - -;StrongARM - We will make the logical representation of physical space for RAM temporarily bufferable -; (on any ARM). This is small boost for ARM 6,7,8 but a big speed benefit for StrongARM (which -; won't burst write in non bufferable areas). - - LDR r0, =L1PT - LDR r12, =PhysRamTable - ADD r4, r12, #PhysRamTableEnd-PhysRamTable ; r4 -> end of table -02 - LDMIA r12!, {r10, r11} ; load next address, size - SUB r11,r11,#&100000 ; 1 Mb will be done on first L1PT update - ORR r10, r10, #PhysSpace ; point to logical representation of physical space - ADD r1,r0,r10,LSR #(20-2) ; L1PT address for same -;MJS bug fix (since 3.70) for memory fragments not necessarily 1Mb aligned (eg 2 Mb Kryten) - BIC r1,r1,#3 -; -04 - LDR r2,[r1] - ORR r2,r2,#4 ; bufferable bit - STR r2,[r1],#4 - SUBS r11,r11,#&100000 ; another 1 Mb done - BPL %BT04 - TEQ r12, r4 ; have we done all areas? - BNE %BT02 - -;now let us do the clear - [ ClearPhysRAMspeedup - MOV r0,#ZeroPage+InitClearRamWs ;we can preserve r7-r9,r13 at logical address 52..67 - STMIA r0,{r7-r9,r13} - MOV r7, #0 - MOV r8, #0 - MOV r9, #0 - MOV r13, #0 - ] - MOV r0, #0 - MOV r1, #0 - MOV r2, #0 - MOV r3, #0 - LDR r12, =PhysRamTable ; point to 5 lots of (physaddr,size) - ADR r6, RamSkipTable - ADD r4, r12, #PhysRamTableEnd-PhysRamTable ; r4 -> end of table -10 - LDR r5, [r6], #4 ; load first skip offset - - LDMIA r12!, {r10, r11} ; load next address, size - - ORR r10, r10, #PhysSpace ; point to logical representation of physical space - ADD r11, r11, r10 ; r11 -> end address of this area -15 - ADD r5, r5, r10 ; r5 -> skip address if any -20 - TEQ r10, r11 ; test for end of this area? - BEQ %FT30 - TEQ r10, r5 ; test for the start of a skipped region - [ ClearPhysRAMspeedup - STMNEIA r10!, {r0-r3,r7-r9,r13} - | - STMNEIA r10!, {r0-r3} - ] - BNE %BT20 - - LDR r5, [r6], #4 ; load skip amount - CMP r5, #0 ; if negative, then it's an offset from start of skipped bit - LDRLT r5, [r10, r5] ; to address of word holding skip amount - ADD r10, r10, r5 ; and skip it - LDR r5, [r6], #4 ; load next skip offset (NB relative to end of last skip) - B %BT15 - -30 - TEQ r12, r4 ; have we done all areas? - BNE %BT10 - - [ ClearPhysRAMspeedup - MOV r0, #ZeroPage+InitClearRamWs - LDMIA r0, {r7-r9,r13} ;restore - - MOV r0, #ZeroPage+InitUsedStart ;clear our speed up workspace - ASSERT InitUsedStart < InitUsedEnd - ASSERT InitUsedEnd < InitClearRamWs - GBLA finalclear -finalclear SETA InitUsedStart - WHILE finalclear < InitWsEnd - STMIA r0!,{r1-r3} -finalclear SETA finalclear + 12 - WEND - ] - -;StrongARM - now let us remove bufferable status of logical representation of physical space (perhaps we could -; leave it? not sure at the mo.) - - LDR r0, =L1PT - LDR r12, =PhysRamTable - ADD r4, r12, #PhysRamTableEnd-PhysRamTable ; r4 -> end of table -32 - LDMIA r12!, {r10, r11} ; load next address, size - SUB r11,r11,#&100000 ; 1 Mb will be done on first L1PT update - ORR r10, r10, #PhysSpace ; point to logical representation of physical space - ADD r1,r0,r10,LSR #(20-2) ; L1PT address for same -;MJS bug fix (since 3.70) for memory fragments not necessarily 1Mb aligned (eg 2 Mb Kryten) - BIC r1,r1,#3 -; -34 - LDR r2,[r1] - BIC r2,r2,#4 ; bufferable bit - STR r2,[r1],#4 - SUBS r11,r11,#&100000 ; another 1 Mb done - BPL %BT34 - TEQ r12, r4 ; have we done all areas? - BNE %BT32 - -CPR_skipped - - LDR r0, =OsbyteVars + :INDEX: LastBREAK - - MOV r1, #&80 - STRB r1, [r0] ; flag the fact that RAM cleared - - ARM_number r0 - SUB r0,r0,#6 - ADRL r1,ARM_default_MMU_CR_table - LDR r1,[r1,r0,LSL #2] - MOV r0, #0 - STR r1, [r0, #MMUControlSoftCopy] ; set up MMU soft copy - - MOV pc, lr - - LTORG - - GBLA lastaddr -lastaddr SETA 0 - GBLA lastregion -lastregion SETA 0 - - MACRO - MakeSkipTable $region, $addr, $size - [ ($region)<>lastregion - & -1 -lastaddr SETA 0 - ] - & ($addr)-lastaddr, $size -lastaddr SETA ($addr)+($size) -lastregion SETA $region - MEND - - MACRO - EndSkipTables - WHILE lastregion < (PhysRamTableEnd-PhysRamTable)/8 - & -1 -lastregion SETA lastregion +1 - WEND - MEND - -; Note (TMD 04-Aug-93): Special bodge put in here to allow variable size skip for L2PT. -; If skip size field is negative, then it's an offset from the start of this skipped bit to a word holding -; the size of the skip. This relies on the L2PTSize being in page zero, which is at a lower physical address than -; the L2 itself. Also assumes that there are no more skips in the 1st DRAM chunk after the L2PT, since the offset -; to the next skip is relative to the end of the previous one, which isn't known at assembly time! - -; Tim says "Yuk, yuk, yuk!!" - -RamSkipTable - MakeSkipTable 1, DRAMOffset_PageZero + 0, InitWsEnd - ZeroPage ; skip 1st n bytes of LogRAM, so IRQs work! - MakeSkipTable 1, DRAMOffset_PageZero + SkippedTables, SkippedTablesEnd-SkippedTables - MakeSkipTable 1, DRAMOffset_L2PT, DRAMOffset_PageZero + L2PTSize - DRAMOffset_L2PT - EndSkipTables - - ASSERT DRAMOffset_PageZero + L2PTSize < DRAMOffset_L2PT - - ] ; :LNOT: HAL - - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; -; InitMEMC - Initialise memory controller -; -; in: r1 = 0 if reset, 1 if break - -InitMEMC ROUT - -; Note: On IOMD, all accesses go to ROM until the first write cycle. - - MOV r12, #IOMD_Base - -; amg: drop in FE-aware routine, leave old one here for reference - - [ MorrisSupport -; Perform a dummy write to IOMD (some harmless register) to get it out of ROM force mode. -; Reads from IOMD will return garbage before this has happened. If we're actually running out -; of 32-bit wide ROMs on MORRIS, a write will already have happened, to get ROMCR0 from -; 16 to 32-bit wide mode, but we can't yet determine for sure (by reading it back), so do it -; anyway. - - STRB r12, [r12, #IOMD_DMAREQ] ; writes to DMAREQ are ignored - - LDRB r2,[r12,#IOMD_ID1] ; load r2 with IOMD ID high byte - LDRB r0,[r12,#IOMD_ID0] ; load r0 with IOMD ID low byte - ORR r0,r0,r2, LSL #8 ; Or r0 and r2 - shifted left 8, put in r0 - LDR r2,=IOMD_7500 ; get Ref IOMD ID code for IOMD in a 7500 - CMPS r0,r2 ; check for IOMD ID Code for IOMD in a 7500 - BEQ init7500cpu ; If equal, got to init7500cpu - - LDRNE r2,=IOMD_7500FE ; If not, get ID code for IOMD in a 7500FE - CMPNES r0,r2 ; If not, check for IOMD ID Code for IOMD in a 7500FE - BNE MedusaInit ; NOT MORRIS assume Medusa hardware - - -init7500FEcpu -; Here bceause its an ARM7500 'FE' variant -; Program the CPU, Memory and IO clock prescalers -; Set the prescalers to :- - - [ RO371Timings -; CPUCLK divide by 1 -; MEMCLK divide by 2 -; IOCLK divide by 2 -; - MOV r0, #IOMD_CLKCTL_CpuclkNormal + IOMD_CLKCTL_MemclkHalf + IOMD_CLKCTL_IOclkHalf - | -; CPUCLK divide by 2 unless FECPUSpeedNormal set -; MEMCLK divide by 1 -; IOCLK divide by 1 -; - [ FECPUSpeedNormal - [ FEIOSpeedHalf - MOV r0, #IOMD_CLKCTL_CpuclkNormal + IOMD_CLKCTL_MemclkNormal + IOMD_CLKCTL_IOclkHalf - | - MOV r0, #IOMD_CLKCTL_CpuclkNormal + IOMD_CLKCTL_MemclkNormal + IOMD_CLKCTL_IOclkNormal - ] - | - [ FEIOSpeedHalf - MOV r0, #IOMD_CLKCTL_CpuclkHalf + IOMD_CLKCTL_MemclkNormal + IOMD_CLKCTL_IOclkHalf - | - MOV r0, #IOMD_CLKCTL_CpuclkHalf + IOMD_CLKCTL_MemclkNormal + IOMD_CLKCTL_IOclkNormal - ] - ] - ] - STRB r0, [r12, #IOMD_CLKCTL] ; initialise all the prescalers. -; -; Set ROM speed, take care to preserve 16-bit mode bit... -; -; According to BSiddle on the 15-May-96, Omega will use burst mode roms: use 93nS burst, 156nS initial. -; According to TDobson on the 09-Jul-96, Omega will handle ROMS up to 120nS and 70nS. -; Thus the ROM speed should be initilised to :- -; Half Speed or H bit, clear, which is ON ! : Half the delays, thus DOUBLE all clock ticks. -; Non-Sequental delay : 10 Ticks : Half speed on, so select 5 ticks (5*2) -; Burst delay : 8 Ticks : Half speed on, so select 4 ticks (4*2) -; Remember the Memory clock on Omega is faster than on previous products. -; The fast flash devices used for Omega testing should be able to cope even -; though they aren't burst devices. - LDRB r0, [r12, #IOMD_ROMCR0] ; Get contents of ROMCR0 in to r0 - AND r0, r0, #&40 ; clear all but the 16-bit mode flag - [ RO371Timings - ORR r0, r0, #IOMD_ROMCR_HalfSpeed + IOMD_ROMCR_NSTicks_5 + IOMD_ROMCR_BTicks_3 - | - [ ROMSpeedNormal - ORR r0, r0, #IOMD_ROMCR_Normal :OR: IOMD_ROMCR_NSTicks_$ROMSpeedNSTicks :OR: IOMD_ROMCR_BTicks_$ROMSpeedBurstTicks - | - ORR r0, r0, #IOMD_ROMCR_HalfSpeed :OR: IOMD_ROMCR_NSTicks_$ROMSpeedNSTicks :OR: IOMD_ROMCR_BTicks_$ROMSpeedBurstTicks - ] - ] - STRB r0, [r12, #IOMD_ROMCR0] ; Prog. the reg.s - -; Program the 2nd ROM bank - [ ExtROMSupport - -; Unless we're actually running from the 2nd ROM bank (CanLiveOnROMCard), we don't know how fast -; the extension ROM in the 2nd bank goes, so program it for a slow default speed - [ CanLiveOnROMCard - TST pc, #PhysExtROM ; are we running out of the 2nd ROM bank? Program the 2nd bank the same as the 1st if so - STRNE r0, [r12, #IOMD_ROMCR1] - ] - [ ExtROMis16bit - [ ROMSpeedNormal - MOV r0, #IOMD_ROMCR_Normal :OR: IOMD_ROMCR_16bit :OR: IOMD_ROMCR_NSTicks_7 :OR: IOMD_ROMCR_BurstOff - | - MOV r0, #IOMD_ROMCR_HalfSpeed :OR: IOMD_ROMCR_16bit :OR: IOMD_ROMCR_NSTicks_7 :OR: IOMD_ROMCR_BurstOff - ] - | - [ ROMSpeedNormal - MOV r0, #IOMD_ROMCR_Normal :OR: IOMD_ROMCR_32bit :OR: IOMD_ROMCR_NSTicks_7 :OR: IOMD_ROMCR_BurstOff - | - MOV r0, #IOMD_ROMCR_HalfSpeed :OR: IOMD_ROMCR_32bit :OR: IOMD_ROMCR_NSTicks_7 :OR: IOMD_ROMCR_BurstOff - ] - ] - [ CanLiveOnROMCard - STREQB r0, [r12, #IOMD_ROMCR1] - | - STRB r0, [r12, #IOMD_ROMCR1] - ] - - |;ExtROMSupport - - [ CanLiveOnROMCard - STRB r0, [r12, #IOMD_ROMCR1] ; Program the 2nd bank the same as the 1st - | - STRB r0, [r12, #IOMD_ROMCR1] ; 2nd bank unused: program it the same anyway - ] - - ];ExtROMSupport - -; Now program ASTCR to add wait states, since MEMCLK is fast relative to IOCLK - - MOV r0, #IOMD_ASTCR_WaitStates - STRB r0, [r12, #IOMD_ASTCR] - - B init7500cpu_common ; branch to common init code. -; - -init7500cpu -; Here because its an ARM7500 variant - NON 'FE' device. -; Program the CPU, Memory and IO clock prescalers -; Set the prescalers to :- -; CPUCLK divide by 1 -; MEMCLK divide by 1 -; IOCLK divide by 1 -; - MOV r0, #IOMD_CLKCTL_CpuclkNormal + IOMD_CLKCTL_MemclkNormal + IOMD_CLKCTL_IOclkNormal - STRB r0, [r12, #IOMD_CLKCTL] ; initialise all prescalers to div1 -; -; Set ROM speed, take care to preserve 16-bit mode bit... -; -; According to RJKing on 6/5/94, Kryten will use burst mode roms: use 93nS burst, 156nS initial. -; According to BSiddle on 09-Jul-96 - Omenga will need to set the burst speed to 4 ticks from 3 ticks. -; Thus the ROM speed should be initilised to :- -; Half Speed or H bit, Set, which is OFF ! : Don't half the delays. -; Non-Sequental delay : 5 Ticks : Half speed off, so select 5 ticks -; Burst delay : 4 Ticks : Half speed off, so select 4 ticks -; The fast EPROMS used for Kryten testing should be able to cope even though -; they aren't burst devices - - LDRB r0, [r12, #IOMD_ROMCR0] ; Get contents of ROMCR0 in to r0 - AND r0, r0, #&40 ; clear all but the 16-bit mode flag - [ RO371Timings - ORR r0, r0, #IOMD_ROMCR_Normal + IOMD_ROMCR_NSTicks_5 + IOMD_ROMCR_BTicks_3 - | - [ ROMSpeedNormal - ORR r0, r0, #IOMD_ROMCR_Normal :OR: IOMD_ROMCR_NSTicks_$ROMSpeedNSTicks :OR: IOMD_ROMCR_BTicks_$ROMSpeedBurstTicks - | - ORR r0, r0, #IOMD_ROMCR_HalfSpeed :OR: IOMD_ROMCR_NSTicks_$ROMSpeedNSTicks :OR: IOMD_ROMCR_BTicks_$ROMSpeedBurstTicks - ] - ] - STRB r0, [r12, #IOMD_ROMCR0] ; Prog. the reg.s - -; Program the 2nd ROM bank - [ ExtROMSupport - -; Unless we're actually running from the 2nd ROM bank (CanLiveOnROMCard), we don't know how fast -; the extension ROM in the 2nd bank goes, so program it for a slow default speed - [ CanLiveOnROMCard - TST pc, #PhysExtROM ; are we running out of the 2nd ROM bank? Program the 2nd bank the same as the 1st if so - STRNE r0, [r12, #IOMD_ROMCR1] - ] - [ ExtROMis16bit - [ ROMSpeedNormal - MOV r0, #IOMD_ROMCR_Normal :OR: IOMD_ROMCR_16bit :OR: IOMD_ROMCR_NSTicks_7 :OR: IOMD_ROMCR_BurstOff - | - MOV r0, #IOMD_ROMCR_HalfSpeed :OR: IOMD_ROMCR_16bit :OR: IOMD_ROMCR_NSTicks_7 :OR: IOMD_ROMCR_BurstOff - ] - | - [ ROMSpeedNormal - MOV r0, #IOMD_ROMCR_Normal :OR: IOMD_ROMCR_32bit :OR: IOMD_ROMCR_NSTicks_7 :OR: IOMD_ROMCR_BurstOff - | - MOV r0, #IOMD_ROMCR_HalfSpeed :OR: IOMD_ROMCR_32bit :OR: IOMD_ROMCR_NSTicks_7 :OR: IOMD_ROMCR_BurstOff - ] - ] - [ CanLiveOnROMCard - STREQB r0, [r12, #IOMD_ROMCR1] - | - STRB r0, [r12, #IOMD_ROMCR1] - ] - - |;ExtROMSupport - - [ CanLiveOnROMCard - STRB r0, [r12, #IOMD_ROMCR1] ; Program the 2nd bank the same as the 1st - | - STRB r0, [r12, #IOMD_ROMCR1] ; 2nd bank unused: program it the same anyway - ] - - ];ExtROMSupport - -; Now program ASTCR to *NOT* add wait states, since MEMCLK is slow relative to IOCLK - - MOV r0, #IOMD_ASTCR_Minimal - STRB r0, [r12, #IOMD_ASTCR] - -; -; -init7500cpu_common -; Common setup requirments for BOTH 7500 and 7500FE. -; -; MORRIS doesn't support VRAM. Kryten has same DRAM speed as Medusa -; - MOV r0, #IOMD_VREFCR_REF_16 ; select 16µs refresh - STRB r0, [r12, #IOMD_VREFCR] - - MOV r0, #IOMD_IOTCR_Network_TypeA :OR: IOMD_IOTCR_Combo_TypeB :OR: IOMD_IOTCR_Sound_TypeB :OR: IOMD_IOTCR_Sound_Word - STRB r0, [r12, #IOMD_IOTCR] - - ; MOV r0, #0 ; Podule manager will set ECTCR to TypeA cycles - ; STRB r0, [r12, #IOMD_ECTCR] - - [ Japanese16BitSound :LAND: STB - MOV r0, #2_10 - STRB r0, [r12, #IOMD_VIDMUX] - ] - B CommonInit - -MedusaInit - ] ; MorrisSupport - -; amg renaissance -> [ MorrisSupport -; amg renaissance -> ; Perform a dummy write to IOMD (some harmless register) to get it out of ROM force mode. -; amg renaissance -> ; Reads from IOMD will return garbage before this has happened. If we're actually running out -; amg renaissance -> ; of 32-bit wide ROMs on MORRIS, a write will already have happened, to get ROMCR0 from -; amg renaissance -> ; 16 to 32-bit wide mode, but we can't yet determine for sure (by reading it back), so do it -; amg renaissance -> ; anyway. -; amg renaissance -> -; amg renaissance -> STRB r12, [r12, #IOMD_DMAREQ] ; writes to DMAREQ are ignored -; amg renaissance -> -; amg renaissance -> LDRB r0, [r12, #IOMD_ID0] -; amg renaissance -> CMP r0, #&98 -; amg renaissance -> LDRB r0, [r12, #IOMD_ID1] -; amg renaissance -> CMPEQ r0, #&5B -; amg renaissance -> ;MOVEQ r3, #xxxx -; amg renaissance -> BNE MedusaInit ; NOT MORRIS assume Medusa hardware -; amg renaissance -> ; -; amg renaissance -> ; MORRIS contains IOMD equivalant circuitry. Due to lack of VRAM, presence of 16/32 bit support -; amg renaissance -> ; and a different ROM speed register, we program it slightly differently. -; amg renaissance -> ; -; amg renaissance -> -; amg renaissance -> ; -; amg renaissance -> ; PSwindell wants all prescalers set to divide by 1 -; amg renaissance -> ; -; amg renaissance -> MOV r0, #IOMD_CLKCTL_CpuclkNormal + IOMD_CLKCTL_MemclkNormal + IOMD_CLKCTL_IOclkNormal -; amg renaissance -> STRB r0, [r12, #IOMD_CLKCTL] ; initialise all prescalers to div1 -; amg renaissance -> -; amg renaissance -> ; -; amg renaissance -> ; Set ROM speed, take care to preserve 16-bit mode bit... -; amg renaissance -> ; -; amg renaissance -> ; According to RJKing on 6/5/94, Kryten will use burst mode roms: use 93nS burst, 156nS initial. -; amg renaissance -> ; -; amg renaissance -> ; We assume that the extension ROMs are the same access time and width as the main OS ROMS. -; amg renaissance -> ; -; amg renaissance -> LDRB r0, [r12, #IOMD_ROMCR0] -; amg renaissance -> AND r0, r0, #&40 ; clear all but 16-bit mode bit, giving us the slowest ROMs possible -; amg renaissance -> [ :LNOT: AutoSpeedROMS -; amg renaissance -> [ NormalSpeedROMS -; amg renaissance -> ;Normal code -; amg renaissance -> ORR r0, r0, #IOMD_ROMCR_Normal + IOMD_ROMCR_156 + IOMD_ROMCR_Burst93 -; amg renaissance -> ; initialise ROM speed to 156.25nS, 93.75nS burst -; amg renaissance -> ; the fast EPROMS used for Kryten testing should be able to cope even though they aren't -; amg renaissance -> ; burst devices -; amg renaissance -> | -; amg renaissance -> ;Slow ROM access for PSwindells test EPROMS. Paul requested 156nS (or slower), burst off. -; amg renaissance -> ORR r0, r0, #IOMD_ROMCR_Normal + IOMD_ROMCR_187 + IOMD_ROMCR_BurstOff -; amg renaissance -> -; amg renaissance -> ! 0, "*** WARNING *** Slow ROM version ment for PSwindell" -; amg renaissance -> ] -; amg renaissance -> ] -; amg renaissance -> STRB r0, [r12, #IOMD_ROMCR0] -; amg renaissance -> STRB r0, [r12, #IOMD_ROMCR1] ; and do the same for extension ROMs (just in case) -; amg renaissance -> ; -; amg renaissance -> ; MORRIS doesn't support VRAM. Kryten has same DRAM speed as Medusa -; amg renaissance -> ; -; amg renaissance -> MOV r0, #IOMD_VREFCR_REF_16 ; select 16µs refresh -; amg renaissance -> STRB r0, [r12, #IOMD_VREFCR] -; amg renaissance -> -; amg renaissance -> MOV r0, #IOMD_IOTCR_Network_TypeA :OR: IOMD_IOTCR_Combo_TypeB :OR: IOMD_IOTCR_Sound_TypeB :OR: IOMD_IOTCR_Sound_Word -; amg renaissance -> STRB r0, [r12, #IOMD_IOTCR] -; amg renaissance -> -; amg renaissance -> MOV r0, #0 ; Podule manager wants TypeA setting by default for all podules -; amg renaissance -> STRB r0, [r12, #IOMD_ECTCR] -; amg renaissance -> -; amg renaissance -> [ Select16BitSound -; amg renaissance -> ; All MORRIS based machines have 16bit 'Japanese' format sound DAC's -; amg renaissance -> MOV r0, #2_10 -; amg renaissance -> STRB r0, [r12, #IOMD_VIDMUX] -; amg renaissance -> ] -; amg renaissance -> B CommonInit -; amg renaissance -> -; amg renaissance -> MedusaInit -; amg renaissance -> ] - - - [ RO371Timings - MOV r0, #&12 ; 5-3 cycle ROM access - | - - [ RISCPCBurstMode - [ 1 = 1 - ReadCop r0, CR_ID - BIC r0, r0, #&F ;ignore 4 bit revision field - LDR r2, =&41007100 ;Test for early 710's - CMP r0, r2 ; - MOVEQ r0, #IOMD_ROMCR_156 + IOMD_ROMCR_BurstOff ;cos they can't work in burst mode! - MOVNE r0, #IOMD_ROMCR_156 + IOMD_ROMCR_Burst93 ;610's 710A's and beyond can - ! 0, "*** WARNING *** Burst mode enabled on RISC PC iff processor can cope" - | - MOV r0, #IOMD_ROMCR_156 + IOMD_ROMCR_Burst93 - ! 0, "*** WARNING *** Burst mode enabled on RISC PC" - ] - | - MOV r0, #IOMD_ROMCR_156 + IOMD_ROMCR_BurstOff ; initialise ROM speed to 156.25ns (changed from 187ns 21-Jan-94) - ] - - ] ;RO371Timings conditional - - STRB r0, [r12, #IOMD_ROMCR0] - [ STB - [ :LNOT: ExtROMis16bit - STRB r0, [r12, #IOMD_ROMCR1] ; and do the same for extension ROMs (just in case) - | - MOV r0, #IOMD_ROMCR_16bit + IOMD_ROMCR_Normal + IOMD_ROMCR_156 + IOMD_ROMCR_BurstOff - STRB r0, [r12, #IOMD_ROMCR1] ; 16bit 156.25nS noburst (Lowest common denominator) - ] - | - STRB r0, [r12, #IOMD_ROMCR1] ; and do the same for extension ROMs (just in case) - ] - MOV r0, #IOMD_VREFCR_VRAM_256Kx64 :OR: IOMD_VREFCR_REF_16 ; select 16µs refresh, assume 2 banks of VRAM - STRB r0, [r12, #IOMD_VREFCR] - - MOV r0, #IOMD_IOTCR_Network_TypeA :OR: IOMD_IOTCR_Combo_TypeB :OR: IOMD_IOTCR_Sound_TypeB :OR: IOMD_IOTCR_Sound_Word - STRB r0, [r12, #IOMD_IOTCR] - - ; MOV r0, #0 ; Podule manager will set ECTCR to TypeA cycles - ; STRB r0, [r12, #IOMD_ECTCR] - -CommonInit -; On breaks (ie software resets) we have to turn the MMU off. -; This is slightly tricky if we've been soft-loaded! - - TEQ r1, #0 ; r1 = 0 if reset, 1 if break - BEQ %FT03 ; [it's a reset] - - SetMode SVC32_mode, r0 ; select 32-bit mode (we know we're in 32-bit config) - B %FT05 -03 - -; It's a reset, so select 32-bit config, MMU off - - [ LateAborts - MOV r2, #MMUC_P :OR: MMUC_D :OR: MMUC_L ; select 32-bit config, MMU off, late aborts - | - MOV r2, #MMUC_P :OR: MMUC_D ; select 32-bit config, MMU off - ] - SetCop r2, CR_Control - SetMode SVC32_mode, r1, r0 ; and re-select 32-bit mode (this time it'll work) - AND r0, r0, #&1F ; check original mode - TEQ r0, #SVC26_mode ; if we were in a 26-bit mode, - BICEQ lr, lr, #&FC000003 ; then knock off 26-bit style PSR bits from link register - ; don't knock them off otherwise, since we may be soft-loaded above 64M - MOV pc, lr ; and exit - -; It's a Break - -; The MMU is on and we want it off: whether we're executing out of ROM or RAM, we -; have to jump to the physical location of our image, which means paging it in at its -; own physical address. - -; On MEMC1 systems it's possible that the L1/L2 logical address is the same as the image's physical -; address, which causes a headache, so we'd best use the physical mapping of the page tables (this -; can't clash as IOMD only goes up to 2000 0000 and our physical mapping is above that). - -05 - [ HAL - ! 0, "Sort out Break" - | - MOV r0, #0 - LDR r0, [r0, #DRAMPhysAddrA] ; get address of 1st DRAM bank - LDR r1, =PhysSpace + DRAMOffset_L1PT ; offset to start of L1 - ADD r0, r0, r1 ; r0 -> L1 in physical mapped logical space - - LDR r1, [r0, #ROM :SHR: (20-2)] ; load L1 entry for 1st Mbyte of ROM - MOV r1, r1, LSR #20 ; knock off other bits - LDR r2, =(AP_None * L1_APMult) + L1_Section - ; (svc-only access) + ~ucb + section mapped - ORR r2, r2, r1, LSL #20 ; merge in address - STR r2, [r0, r1, LSL #2]! ; store in L1PT for 1st Mbyte - ADD r2, r2, #1 :SHL: 20 ; move on to 2nd Mbyte - STR r2, [r0, #4] ; and store in next entry - - ARM_flush_cacheandTLB r0 - - MOV r0, r1, LSL #20 - SUB r0, r0, #ROM ; form RAM-ROM offset - ADD pc, pc, r0 ; jump to RAM code (when we get onto IOMD, we'll have to be in 32-bit mode) - NOP ; this instruction will be skipped - - ] ; HAL - -; we're now in RAM, so it's safe to turn the MMU off, but leave us in 32-bit config (and 32-bit mode) - - [ :LNOT:No26bitCode - BIC lr, lr, #&FC000003 ; knock out PSR bits from return address - ; (we know we were in 32-bit config, 26-bit mode on entry) - ] - ADD lr, lr, r0 ; and add on offset - NB this may now be above 64MB (on IOMD) - -;mjs - the MMU off values are ok for all ARMs; some will ignore P,D,L bits - [ LateAborts - MOV r0, #MMUC_P :OR: MMUC_D :OR: MMUC_L ; turn MMU off, but leave us in 32-bit config, late aborts - | - MOV r0, #MMUC_P :OR: MMUC_D ; turn MMU off, but leave us in 32-bit config - ] - ARM_write_control r0 - - MOV pc, lr ; return to caller, but in physical address space - - LTORG -; -> MemSize - -; (non-destructive) algorithm to determine MEMC RAM configuration -; -; Dave Flynn and Alasdair Thomas -; 17-March-87 -; -; Spooling checkered by NRaine and SSwales ! -; 8MByte check bodged in by APT -; -; NOTE: Routines MemSize and TimeCPU are called by the power-on test software, -; so their specifications MUST not change. -; -; Set MEMC for 32-k page then analyse signature of possible -; external RAM configurations... -; The configurations are: -; -; Ram Size Page Size Configuration (Phys RAM) Signature -;-------------------------------------------------------------------- -; 16MByte 32k 4*32*1Mx1 A13,A20,A21,A22,A23,A23.5 distinct -; 16MByte 32k 16*8*256kx4 A13,A20,A21,A22,A23,A23.5 distinct -; -; 12MByte 32k 3*32*1Mx1 A13,A20,A21,A22,A23 OK, A23.5 fail -; 12MByte 32k 12*8*256kx4 A13,A20,A21,A22,A23 OK, A23.5 fail -; -; 8MByte 32k 2*32*1Mx1 A13,A20,A21,A22 distinct, A23 fail -; 8MByte 32k 8*8*256kx4 A13,A20,A21,A22 distinct, A23 fail -; -; 4Mbyte 32k 32*1Mx1 A13,A21,A20 distinct, A22,A23 fail -; 4Mbyte 32k 4*8*256kx4 A13,A21,A20 distinct, A22,A23 fail -; -; 2Mbyte 32k expandable 2*8*256kx4 A13,A20 distinct, A21 fails -; 2Mbyte ??? 16k fixed 2*8*256kx4 A13,A21 distinct, A20 fails -; -; 1Mbyte 8k 32*256kx1 A13,A20 fail, A19,A18,A12 distinct -; 1Mbyte 8k 8*256kx1 A13,A20 fail, A19,A18,A12 distinct -; 1Mbyte 8k 4*8*64kx4 A13,A20 fail, A19,A18,A12 distinct -; -; 512Kbyte 8k expandable 2*8*64kx4 A13,A20,A19 fail, A12,A18 distinct -; 512Kbyte 4k fixed 2*8*64kx4 A13,A20,A12 fail, A19,A18 distinct -; -; 256Kbyte 4K 8*64kx4 A13,A20,A12,A18 fail, A21,A19 ok -; 256Kbyte 4K 32*64kx1 A13,A20,A12,A18 fail, A21,A19 ok -; - -; MemSize routine... enter with 32K pagesize set -; R0 returns page size -; R1 returns memory size -; R2 returns value set in MEMC -; Can corrupt R3-R14 - -; Note that on a soft-loaded system, the 1st word of the image may be -; temporarily overwritten, but this is just the reset branch so it's OK. - -; MMU is always off at this point, so we must use the physical address of PhysRAM -; Also we are entered in 32-bit config, 32-bit mode, -; but we exit in 32-bit config, 26-bit mode - - [ MorrisSupport -funnypatterns - & &66CC9933 ; 0110 1100 1001 0011 - & &CC993366 ; 1100 1001 0011 0110 - ] - -MemSize ROUT - MOV r13, lr ;save in a register, cos we've got no stack - - MOV r12, #IOMD_Base - - [ MorrisSupport -; - LDRB r0, [r12, #IOMD_ID0] ; load r1 with IOMD ID high byte - LDRB r1, [r12, #IOMD_ID1] ; load r0 with IOMD ID low byte - ORR r0,r0,r1,LSL#8 ; Or r0 and r1, shifted left 8, put in r0 - LDR r1,=IOMD_Original ; get Ref IOMD ID code - original - CMP r0,r1 ; check for IOMD ID Code - original - BEQ MemSizeIOMD ; Not ID Code - original, - ; therefore jump to Medusa hardware code - ; else fall through to Morris code. -; -; MemSize for Morris -; - [ RO371Timings - MOV r11, #&70 ;all 4 banks assumed 32 bit - EDO and timing bits set in case 7500FE (don't care bits otherwise) - | - MOV r11, #IOMD_DRAMWID_DRAM_32bit * &0F ;set all 4 banks to be 32bit initially - LDR r1, =IOMD_7500FE - TEQ r0, r1 ; are we on FE part? - ORREQ r11, r11, #IOMD_DRAMWID_EDO_Enable :OR: IOMD_DRAMWID_RASCAS_3 :OR: IOMD_DRAMWID_RASPre_3 - ; if so, then enable EDO and slower RASCAS and RASPre times - ! 0,"7500FE support expects EDO memory in s.ARM600" - ] - MOV r14, #IOMD_Base - STRB r11, [r14, #IOMD_DRAMWID] - MOV r10, #0 ;indicate no RAM found yet - MOV r9, #IOMD_DRAMWID_DRAM_16bit ;bit to OR into DRAMWID to set 16bit - MOV r0, #DRAM0PhysRam -; -; r0 DRAM address -; r9 IOMD_DRAMWID_DRAM_16bit for current DRAM bank -; r11 current IOMD_DRAMWID register contents -; -ExamineDRAMBank ;examine first/next DRAM bank -; - LDMIA r0, {r1, r2} ;Preserve the two locations that we widdle on - - ADR r3, funnypatterns ;We write different values to two locations - LDMIA r3, {r3, r4} ; incase bus capacitance holds our value - STMIA r0, {r3, r4} - LDMIA r0, {r5, r6} ;Reread test locations - EORS r5, r5, r3 ;Both locations should read correctly - EOR r6, r6, r4 ; if memory is 32bits wide - ;TEQ r5, #0 - TEQEQ r6, #0 - BEQ %FT05 ;32bit wide memory - - TST r5, #&00FF ;If the bottom 16bits of each location - TSTEQ r5, #&FF00 ; are correct, the memory is 16bits wide - TSTEQ r6, #&00FF - TSTEQ r6, #&FF00 - ADDNE r0, r0, #DRAM1PhysRam-DRAM0PhysRam ; move onto next bank - BNE NoRamInBank ;No memory in this bank - - ORR r11, r11, r9 ;Bank is 16bits wide -05 - STMIA r0, {r1, r2} ;Restore the two locations we widdled on - ;Must do BEFORE poking the DRAMWID register - MOV r14, #IOMD_Base ; - STRB r11, [r14, #IOMD_DRAMWID] ; - - BL Add_DRAM_bank - -NoRamInBank - MOV r9, r9, LSL #1 ; shunt up position in DRAMWID - CMP r9, #&0010 ; if more banks to do - BLT ExamineDRAMBank ; then loop - - MOV r6, #0 ; No VRAM - MOV r0, #0 - MOV r14, #IOMD_Base - - LDRB r4, [r14, #IOMD_ID0] - LDRB r7, [r14, #IOMD_ID1] - ORR r4, r4, r7, LSL #8 - LDR r7, =IOMD_7500FE ; if FE part, then assume EDO DRAM - TEQ r4, r7 - LDREQ r2, =80000000 ; so allow 80E6 bytes/s - [ STB - LDRNE r2, =44000000 ; else only allow 44E6 bytes/s - | - LDRNE r2, =46500000 ; if no VRAM, then 46.5E6 bytes/sec bandwidth - ] - MOV r1, #IOMD_VIDCR_DRAMMode :OR: &10 ; if no VRAM, then turn on DRAM mode, and set increment to &10 - - B Allocate_DRAM - -MemSizeIOMD - ] - -; Right, let's find out where our memory is - - -MemSizeIOMD_notSA - - MOV r11, #IOMD_DRAMCR_DRAM_Large * &55 ; set all banks to be large initially - MOV r14, #IOMD_Base - STRB r11, [r14, #IOMD_DRAMCR] - - MOV r10, #0 ; indicate no RAM found yet - MOV r9, #IOMD_DRAMCR_DRAM_Small ; bit to OR into DRAMCR - MOV r0, #DRAM0PhysRam -10 - ADD r1, r0, #A10 ; this should be OK for both configurations - BL DistinctAddresses - ADDNE r0, r0, #DRAM1PhysRam-DRAM0PhysRam ; move onto next bank - BNE %FT15 ; [no RAM in this bank at all] - - ADD r1, r0, #A11 ; test for 256K DRAM - BL DistinctAddresses - ORRNE r11, r11, r9 ; it is, so select small multiplexing - MOVNE r14, #IOMD_Base - STRNEB r11, [r14, #IOMD_DRAMCR] ; store new value of DRAMCR, so we can use memory immediately - - BL Add_DRAM_bank - -; Now, we have to find a bank of DRAM, so we've got somewhere to store our results! -15 - MOV r9, r9, LSL #2 ; shunt up position in DRAMCR - CMP r9, #&100 ; if more banks to do - BCC %BT10 ; then loop - -; Now, we check out the VRAM. -; Don't bother checking for more than 2M of VRAM, because we don't know what the 1/2 SAM length is for larger sizes - - MOV r2, #IOMD_VREFCR_VRAM_256Kx64 :OR: IOMD_VREFCR_REF_16 ; assume 2 banks of VRAM by default - STRB r2, [r12, #IOMD_VREFCR] - - MOV r0, #VideoPhysRam ; point at VRAM - ADD r1, r0, #A2 ; test A2 - BL DistinctAddresses - MOVEQ r6, #2 ; we've got 2M of VRAM - BEQ %FT20 - - MOV r2, #IOMD_VREFCR_VRAM_256Kx32 :OR: IOMD_VREFCR_REF_16 - STRB r2, [r12, #IOMD_VREFCR] - ADD r1, r0, #A2 ; check for any VRAM at all - BL DistinctAddresses - MOVEQ r6, #1 ; we've got 1M of VRAM - MOVNE r6, #0 ; no VRAM -20 - [ IgnoreVRAM - MOV r6, #0 ; pretend there's no VRAM - ] - CMP r6, #1 - MOVCC r1, #IOMD_VIDCR_DRAMMode :OR: &10 ; if no VRAM, then turn on DRAM mode, and set increment to &10 - MOVEQ r1, #SAMLength/2/256 ; if 1M VRAM, then use VRAM mode, and set increment for 1/2 SAM - MOVHI r1, #SAMLength/2/256*2 ; if 2M VRAM, then use VRAM mode, and set increment for 2*1/2 SAM - LDRCC r2, =46500000 ; if no VRAM, then 46.5E6 bytes/sec bandwidth - LDREQ r2, =80000000 ; if 1M VRAM, then 80E6 ---------""-------- - LDRHI r2, =160000000 ; if 2M VRAM, then 160E6 ---------""-------- - MOVCC r0, #0 ; Clear VRAM base if there is no VRAM - -; Allocate_DRAM -; r0 = Video base if r6!=0 -; r1 = Value for IOMD VIDCR -; r2 = Bandwidth limit -; r6 = VRAM size in Mb -; r10 = End of DRAM list -Allocate_DRAM - -NoDRAMPanic - TST r10, r10 - BEQ NoDRAMPanic ; Stop here if there is no DRAM (we could use VRAM I suppose...) - - MOV r7, r6, LSL #20 ; r7 = size of video memory - LDR r8, [r10] ; r8 = the number of DRAM blocks. - SUB r11, r10, r8, LSL #3 ; Jump back to the start of the list - - LDMIA r11!, {r4, r5} ; Get a block from the list. (r4,r5) = (base,size) - CMP r6, #0 ; Did we find any VRAM? - BNE %FT30 ; Skip this bit if we did. - MOV r0, r4 ; Allocate this block as video memory - MOV r7, r5 - CMP r10, r11 ; Was this the only block? If so, leave 1M - SUBEQS r7, r7, #1024*1024 - MOVCC r7, r5, ASR #1 ; If that overflowed, take half the bank. - CMP r7, #8*1024*1024 - MOVCS r7, #8*1024*1024 ; Limit allocation to 8M - the size of the logical space - - ADD r4, r4, r7 ; Adjust the DRAM block base... - SUBS r5, r5, r7 ; ... and the size. - LDMEQIA r11!, {r4, r5} ; Fetch the next block if we claimed it all. - -30 ADD r12, r4, #DRAMOffset_PageZero ; Use the first block for kernel workspace. - ADD r3, r12, #DRAMPhysAddrA ; Set the table address as well - - CMP r8, #5 - ADDCS r10, r11, #3:SHL:3 ; Limit to 4 blocks of DRAM (3 + this one) - -35 STMIA r3!, {r4, r5} ; Put the DRAM block into the table - TEQ r10, r11 - LDMNEIA r11!, {r4, r5} ; Get the next block if there is one. - BNE %BT35 - -; Now go back and put the VRAM information in, and also program VIDCR and VIDCUR - - [ :LNOT:HAL - STRB r6, [r12, #VRAMWidth] ; store width of VRAM (0,1 or 2) - MOV r14, #IOMD_Base - STRB r1, [r14, #IOMD_VIDCR] - STR r0, [r14, #IOMD_VIDCUR] ; set up VIDCUR to start of video RAM - STR r0, [r14, #IOMD_VIDSTART] ; do same for VIDSTART - STR r0, [r14, #IOMD_VIDINIT] ; and for VIDINIT - ; so we don't get a mess when we turn video DMA on later - STR r2, [r12, #VideoBandwidth] ; store video bandwidth - - ADD r4, r0, #1024*1024-4096 ; add on a bit to form VIDEND (will be on mult. of SAM) - STR r4, [r14, #IOMD_VIDEND] ; yes I know it's a bit of a bodge - - MOV r4, r6, LSL #20 ; convert amount of VRAM to bytes - STR r4, [r12, #VRAMSize] ; and store - ] - - ADD r2, r12, #VideoPhysAddr ; r2 -> Start of PhysRamTable - STMIA r2, {r0, r7} ; store video memory block -MemSizeTotalRAM -; Now we have to work out the total RAM size - - MOV r1, #0 - MOV r7, r2 -40 - LDMIA r7!, {r4, r5} ; get address, size - ADD r1, r1, r5 ; add on size - TEQ r7, r3 - BNE %BT40 - - MOV r0, #Page4K ; something to put in MEMC CR soft copy - ; (it's probably irrelevant) - ADRL r4, ROM - -; r0 = Page size -; r1 = Total memory size (bytes) -; r2 = PhysRamTable -; r3 = After last used entry in PhysRamTable -; r4 = Address of ROM - -; now store zeros to fill out table - -55 - ADD r5, r2, #PhysRamTableEnd-PhysRamTable - MOV r6, #0 - MOV r7, #0 -57 - CMP r3, r5 - STMCCIA r3!, {r6, r7} - BCC %BT57 - - [ :LNOT: HAL -; Now set up L1 + L2 -; - first work out how big static L2 needs to be -; - then zero L1 + L2 (L1 is actually inside L2) - - MOV r3, r1, LSR #22 ; r3 = memsize / 4M - TEQ r1, r3, LSL #22 ; if any remainder - ADDNE r3, r3, #1 ; then round up (r3 is now how many pages of L2 needed for free pool) - MOV r3, r3, LSL #12 ; convert to bytes - ADD r3, r3, #FixedAreasL2Size ; add on size of L2 for other fixed areas - STR r3, [r2, #L2PTSize-PhysRamTable] ; save away for future reference - - LDR r2, [r2, #DRAMPhysAddrA-PhysRamTable] ; get address of 1st DRAM bank - LDR r5, =DRAMOffset_L2PT - ADD r2, r2, r5 ; make r2 -> L2PT - MOV r5, #0 ; value to initialise L1 and L2 to (translation faults) - MOV r6, r5 - MOV r7, r5 - MOV r8, r5 - MOV r9, r5 - MOV r10, r5 - MOV r11, r5 - MOV r12, r5 - ADD r2, r2, r3 ; start at end and work back -60 - STMDB r2!, {r5-r12} - SUBS r3, r3, #8*4 - BNE %BT60 - -; r2 ends up pointing at L2 - - ADD r3, r2, #DRAMOffset_L1PT-DRAMOffset_L2PT ; r3 -> L1Phys - -; now initialise all the L1 for the area covered by the static L2, as if it were all page mapped -; - the section mapped stuff will be overwritten when we go thru MemInitTable shortly - - ORR r5, r2, #L1_Page + L1_U ; take phys base of L2, and or in other bits to form an L1 entry - LDR r6, =L2PTSize+DRAMOffset_PageZero-DRAMOffset_L2PT - LDR r10, [r2, r6] ; r10 = size of L2 (used after this loop, too) - ADD r6, r5, r10 ; r6 = value in r5 when we've finished - MOV r7, r3 ; r7 -> where we're storing L1 entries -61 - STR r5, [r7], #4 ; store L1 entry - ADD r5, r5, #1024 ; advance L2 pointer - TEQ r5, r6 - BNE %BT61 - -; now go through memory initialisation table, setting up entries - - ADR r5, MemInitTable -65 - LDMIA r5!, {r6-r8} ; load size, logaddr, indicator - TEQ r6, #0 ; if size field is zero - BEQ %FT90 ; then we've finished going through table - - TST r8, #1 ; if bit 0 of indicator is set, then it's page mapped - BNE %FT75 - - TST r8, #2 ; is it abort? - BNE %FT68 ; [no] - -; it's a section abort (r8=0) - -66 - STR r8, [r3, r7, LSR #20-2] ; store zero in L1 table - ADD r7, r7, #&00100000 ; increment logical address by 1M - SUBS r6, r6, #&00100000 ; and decrement size by 1M - BNE %BT66 ; loop until done - B %BT65 - - -68 -; it's section mapped - - TST r8, #ROMbit ; is it a ROM image offset - ADDNE r8, r8, r4 ; if so, then add in image offset - BICNE r8, r8, #ROMbit ; and knock out the dodgy bit - - TST r8, #Vidbit ; is it a video memory offset - LDRNE r9, =VideoPhysAddr+DRAMOffset_PageZero-DRAMOffset_L2PT - LDRNE r9, [r2, r9] ; get physical address of video RAM - ADDNE r8, r8, r9 ; add on offset - BICNE r8, r8, #Vidbit ; and knock out the dodgy bit -70 - STR r8, [r3, r7, LSR #20-2] ; store entry in L1 table (assumes bits 18, 19 are clear!) - ADD r7, r7, #&00100000 ; increment logical address by 1M - ADD r8, r8, #&00100000 ; and physical address by 1M - SUBS r6, r6, #&00100000 ; and decrement size by 1M - BNE %BT70 ; if we've not finished then loop - B %BT65 ; else go back to main loop - -; explicit L2 setup - -75 - CMP r6, #-1 ; if size <> -1 - BNE %FT80 ; then normal - -; size = -1 => this is the chunk with the soft CAM map in it, -; so we must work out a suitable size (and store it in SoftCamMapSize) -; we also have to work out the correct offset in the DRAM bank, since this is -; after variable size L2PT - - MOV r6, r1, LSR #24-3 ; number of pages for cam map - CMP r1, r6, LSL #24-3 ; if bits dropped off - ADDNE r6, r6, #1 ; then need one more page - MOV r6, r6, LSL #12 - LDR r9, =DRAMOffset_PageZero-DRAMOffset_L2PT+SoftCamMapSize - STR r6, [r2, r9] ; store size used - ADD r6, r6, #UndStackSize ; chunk also includes undstack - ADD r9, r10, #DRAMOffset_L2PT ; undstack/cammap starts at offset L2PT + L2PTSize - ORR r8, r8, r9 ; OR in other misc bits from table -80 - LDR r9, =DRAMOffset_PageZero-DRAMOffset_L2PT+DRAMPhysAddrA - ; offset from L2 to word containing physical address of 1st DRAM bank - LDR r9, [r2, r9] ; r9 = address of 1st DRAM bank - ADD r8, r8, r9 ; convert offset to address - EOR r8, r8, #L2_SmallPage :EOR: 1 ; make bottom 2 bits correct for L2 - ADD r9, r2, r7, LSR #10 ; r9 -> L2 for this page -85 - STR r8, [r9], #4 ; store entry in L2 - ADD r8, r8, #4*1024 ; advance physical page address - SUBS r6, r6, #4*1024 ; one less page to do - BNE %BT85 - B %BT65 - -; L1 is now set up correctly, and L2 has the correct CB bits, but no accessible pages -; Put in the L2 entries for the logical area we are going to access the L2 (and L1) at -; r10 still holds L2PT size - -90 - ADD r5, r2, #(L2PT :SHR: 10) ; r5 -> start of L2PT for L2 logical address - LDR r6, =(AP_None * L2_APMult) + L2_SmallPage ; r6 = other gubbins to put in L2 entries (not C or B) - ORR r6, r6, r2 ; OR in physical address of L2 - MOV r7, r10 ; amount to put in (L2PTSize) -95 - STR r6, [r5], #4 ; store entry - ADD r6, r6, #4096 ; move onto next page - SUBS r7, r7, #4096 ; one less page to do - BNE %BT95 ; loop until done - -; But before we turn on, we have to temporarily make the addresses we are currently executing out of -; into a section mapped area straight through, so we don't crash before we can jump up into ROM area - - ASSERT ((CritStart :EOR: CritEnd) :AND: &FFF00000)=0 ; make sure start and end are in the same MB chunk - - ADR r5, CritStart ; point at critical region start - MOV r5, r5, LSR #20 ; divide by 1MB - LDR r6, [r3, r5, LSL #2] ; get current L1 entry to put back later - MOV r7, r5, LSL #20 ; r7 = physical address of base of section - ORR r7, r7, #(AP_None * L1_APMult) - ORR r7, r7, #L1_Section - STR r7, [r3, r5, LSL #2] ; store replacement entry in L1 (not U,C or B) - - ARM_MMU_transbase r3 ; set up MMU pointer to L1 - ADD r3, r3, #PhysSpace ; when we put L1 entry back later, we need to use the copy in PhysSpace area - - MOV r7, #1 - ARM_MMU_domain r7 ; only use domain 0 - - ARM_flush_cacheandTLB r7 ; flush cache + TLB just in case - - ARM_number r2 ;should be 6,7,8 or &A - SUB r2,r2,#6 ; r2 := 0..4 for ARM 6,7,8,(9),&A - ADRL r7,ARM_default_MMU_CR_table - LDR r7,[r7,r2,LSL #2] ;get appropriate default value for MMU control reg - -CritStart - ARM_write_control r7 - -; now we can jump into the ROM space (if we're not already there) - - RSB r4, r4, #ROM ; make offset from current address to ROM - ADD pc, pc, r4 ; jump up into ROM area - NOP ; this instruction will be skipped - -; now put back the L1 entry we messed up - - STR r6, [r3, r5, LSL #2] -CritEnd ; 2 words after we go up into ROM - ARM_flush_TLB r2 ; flush TLB (no need to flush cache, as there's nothing in it) - - SetMode UND32_mode, r7 - LDR r13_undef, =UNDSTK ; set up undefined mode stack pointer - - [ No26bitCode - SetMode ABT32_mode, r7 - LDR r13_abort, =ABTSTK ; set up abort mode stack pointer - - SetMode SVC32_mode, r7 ; RISC OS is 32 bit now. yay! - | - SetMode SVC26_mode, r7 ; switch into 26-bit mode - ] - ADD r13, r13, r4 ; adjust return address - - LDR r2, ResetMemC_Value - BIC r2, r2, #&C - ORR r2, r2, r0 - MOV r0, #4*1024 ; r0 = true page size (now split off - ; from MEMC control register) - MOV pc, r13 - - ] ; :LNOT: HAL - -; add_dram_bank -; Entry: r10 -> workspace (initially 0) -; r0 = bank address -; Exit: r10 -> workspace (allocated if 0 on entry) -; r0 = next bank address -; r9, r11, r13 preserved -; Probe a DRAM bank, and add any DRAM found to the workspace -Add_DRAM_bank - ROUT - MOV r12, lr ; r12 = return address - EOR r1, r0, #A16 ; Check there is some RAM in the bank - BL DistinctAddresses - ADDNE r0, r0, #DRAM1PhysRam-DRAM0PhysRam - MOVNE pc, r12 ; Return if no RAM in the bank - - ; Only some address lines are decoded by the SIMM. For example, a 4M SIMM may be split - ; into 2 banks, with A2-A20 decoded on each, or A2-A19,A21 decoded. First we need to - ; find out which address lines are decoded, and which are ignored. - MOV r6, #DRAM1PhysRam-DRAM0PhysRam - MOV r7, #A17 - SUB r6, r6, #1 ; Get address lines which select address within bank. - - ; Loop through the address lines, finding out which are decoded. We clear the bits in r6 - ; which correspond to non-decoded address lines. - ; r6 = address line mask - ; r7 = current address line -10 EOR r1, r0, r7 ; Toggle the address line - BL DistinctAddresses ; Check if address line has any effect. - BICNE r6, r6, r7 ; Clear the bit if the address line fails. - MOV r7, r7, LSL #1 ; Move onto the next address line. - TST r6, r7 ; Have we reached the limit? - BNE %BT10 ; Repeat if not. - - ; r6 = decoded address lines in bank. (ie in A0-A25) - ; r7 = The size of the DRAM bank - ; Since the DRAM bank may not be contiguous, we now split the bank up into contiguous - ; blocks. We make these as large as possible to save work. Here we set r8 to the - ; size of the smallest contiguous block(s) of RAM. (There will also be some contiguous - ; blocks which are twice this size in some cases.) - ADD r8, r6, #A17 - BIC r8, r8, r6 ; r8 = First clear bit in r6 from A17 up. - - RSB r4, r8, #0 ; r4 = All bits at or above r8 set since r8 is a power of 2. - - RSB r7, r7, #0 ; r7 = address bits which select the bank since r7 was a - ; power of 2. - ORR r3, r7, r6 ; r3 = All decoded address lines. - AND r7, r4, r3 ; r7 = All decoded bits at or above r8. - -; Make sure that the dram bank may not be contained within the image. The code below fails -; to work correctly if a dram bank is contained within an OS image. Currently this would -; require an image larger than 64M. - ASSERT OSROM_ImageSize*1024 <= DRAM1PhysRam-DRAM0PhysRam - -15 MOV r1, r0 ; r1 = Address of start of block (inclusive). - ADD r2, r1, r8 ; r2 = End of the block (exclusive). - - ; Move the end of the block if the OS image begins in this block. - ADRL r4, ROM ; r4 = Start of the OS image (which may be in RAM). - EOR r5, r4, r1 ; r5 = Difference between image and memory block. - TST r5, r7 ; Check if the image begins in this block of RAM. - ANDEQ r2, r4, r3 ; Set end of block to start of image. - - ; Move the start of the block if the OS image ends in this block. - ADD r4, r4, #OSROM_ImageSize*1024 - SUB r4, r4, #1 ; r4 = Last byte of the OS image. - EOR r5, r4, r1 ; r5 = Difference between end of image and block. - TST r5, r7 ; Check if the image ends in this block of RAM. - ANDEQ r5, r4, r3 ; r5 = Address of last byte of the image within this block. - ADDEQ r1, r5, #1 ; Set start of block to the byte after the image. - - ; If the image is contained in the block, we will have swapped the start and end - ; addresses. This means that the block is split into two parts. The bit below - ; the image and the bit above the image. - CMP r1, r2 - BLS %FT20 ; If start <= end, then block is not fragmented. - CMP r2, r0 ; Check the size of the fragment before the image. - MOV r0, r1 ; Store old start address - AND r1, r1, r7 ; Get the start of the block - BLNE Allocate_DRAM_fragment ; Allocate it if it's non-zero. - MOV r1, r0 ; Restore the old start of fragment - AND r0, r0, r7 ; Get the start of the block again. - ADD r2, r0, r8 ; End of next fragment is the end of the block. - - CMP r1, r2 ; Compare start and (modified) end. -20 BLNE Allocate_DRAM_fragment - - ; Now move onto the next block. We add the non-decoded address lines to cause the - ; carry to be propagated across them. Then we mask them out. - MVN r4, r7 ; Add the non-connected address lines to ... - ADD r4, r4, r0 ; ... the block address ... - ADD r4, r4, r8 ; ... and the block size. -; EOR r5, r0, r4 ; Compare with old address - AND r0, r4, r7 ; Leave only the decoded lines set. -; BIC r5, r5, r6 ; Clear decoded lines within the bank. -; TST r5, r7 ; Check only the bank lines. -; BEQ %BT15 ; Repeat for next block. - - TST r0, r6 - BNE %BT15 - - MOV pc, r12 ; Done for this bank. - -; Allocate_DRAM_block -; Entry: -; r1 = block start (inclusive) -; r2 = block end (exclusive) -; r3 = All decoded address lines -; r7 = All decoded bits at or above r8 -; r8 = Size of largest contiguous block -; block length is assumed to be at least the size of the static data - ie. 160k -; The maximum block list size is then 4k, which fits easily into the cursor chunk -; Exit: -; r10 updated -; r0, r3, r6-r9, r11-r13 preserved -; r10 points to a word containing the number of blocks stored. -; The pairs of words before -Allocate_DRAM_fragment - ROUT - CMP r10, #0 - BEQ %FT20 - - ; We are not dealing with the first block since r10 != 0. Make an attempt to merge this block - ; with the previous block. - LDMDB r10, {r4, r5} ; Get details of the previous block - ADD r5, r4, r5 ; Get the end address - EOR r5, r5, r1 ; Compare with the current block start address... - TST r5, r3 ; ... but only check the decoded bits. - EOR r5, r5, r1 ; Restore the previous block end address. - BNE %FT10 ; We can't merge it after the previous block - - ; r4 = previous start - ; r5 = previous end - ; The block is just after the previous block. That means the start address is unchanged, but - ; the length is increased. - SUB r5, r5, r4 ; Calculate the previous block length. - SUB r2, r2, r1 ; Find the length of the new block. - ; r2 = length of block - ADD r5, r5, r2 ; Add it to the previous length. - STR r5, [r10, #-4] ; Update the block size in memory. - MOV pc, lr - - ; The block is not just after the previous block, but it may be just before. This may be the - ; case if we are softloaded. -10 SUB r4, r4, #1 ; Compare the address before the previous block start ... - SUB r2, r2, #1 ; ... with the address of the last byte in this block ... - EOR r4, r4, r2 - TST r4, r3 ; ... but check only the decoded bits. - ADD r2, r2, #1 ; Restore the end address. - BNE %FT20 ; Skip if we cannot merge the block. - - ; The block is just before the previous block. The start address and length both change. - LDR r4, [r10, #-8] ; Get the previous block start again. - - SUB r2, r2, r1 ; Calculate the current block size. - SUB r4, r4, r2 ; Subtract from the previous block start address. - SUB r5, r5, r4 ; Calculate the new length=end-start - STMDB r10, {r4, r5} ; Update the block info in memory. - MOV pc, lr - - ; We now have a region which does not merge with a previous region. We move it up to the - ; highest address we can in the hope that this block will merge with the next block. -20 SUB r2, r2, r1 ; Calculate the block size - MVN r4, r3 ; Get the non-decoded address lines. - ORR r1, r4, r1 ; Set the non-decoded address bit in the start address. - -30 CMP r10, #0 ; If the workspace has not been allocated... - MOVEQ r10, r1 ; ... use this block. - MOVEQ r4, #0 ; Initialise the counter. - - ; The block/fragment to be added is between r1 and r1+r2. - LDRNE r4, [r10] ; Get the old counter if there was one. - STMIA r10!, {r1, r2} ; Store address and size. - ADD r4, r4, #1 ; Increment the counter. - STR r4, [r10] ; Store the counter. - - MOV pc, lr ; We've done with this block now. - - - -; Memory map initialisation table -; Consists of word triplets (size,logaddr,type) -; where size is size in bytes of area (size=0 terminates list) -; logaddr is the base logical address of area -; type is one of 5 formats: -; a) a standard section-mapped L1 entry (physical address gets incremented for each MB in size) -; b) like a section-mapped L1 entry, but with bit 12 set (address field holds base offset from "ROM" image) -; c) like a section-mapped L1 entry, but with bit 13 set (address field holds base offset from start of video RAM) -; d) like a page-mapped L1 entry, which indicates a page-mapped area to fill in -; the L2 for. In this case the other bits are as follows:- -; Bits 3,2 - CB respectively -; Bits (11,10),(9,8),(7,6),(5,4) - access privileges -; Bits 31-12 - offset in 1st DRAM bank to start of these pages (in units of pages) -; If the size field contains -1, then it is the SoftCAMMap, and the appropriate size should be worked out, -; and stored in SoftCamMapSize. Also, since the size of the L2 is variable the offset into the DRAM bank -; of the SoftCamMap is unknown at assembly time, so the offset bits in table are zero. -; e) zero - indicating that this area should abort (only necessary for section mapped bits in 48M-64M, cause they -; have no level 2, therefore section must abort) - used for VIDC1 emulation area. -; Note in case d), the L1 is not actually touched (it should have already been set up to point to the right L2) -; - -ROMbit * 1 :SHL: 12 -Vidbit * 1 :SHL: 13 -PSS * PhysSpaceSize :SHR: 20 ; Number of megabytes in physical space (used in table generation) - - MACRO - MemInitSection $size, $U, $C, $B, $logaddr, $ap, $physaddr - & ($size)*&00100000 - & $logaddr - & (($U)*L1_U):OR:(($C)*L1_C):OR:(($B)*L1_B):OR:(($ap)*L1_APMult):OR:$physaddr:OR:L1_Section - MEND - - MACRO - MemInitROMs $size, $U, $C, $B, $logaddr, $ap - & ($size)*&00100000 - & $logaddr - & (($U)*L1_U):OR:(($C)*L1_C):OR:(($B)*L1_B):OR:(($ap)*L1_APMult):OR:ROMbit:OR:L1_Section - MEND - - MACRO - MemInitVideo $size, $U, $C, $B, $logaddr, $ap - & ($size)*&00100000 - & $logaddr - & (($U)*L1_U):OR:(($C)*L1_C):OR:(($B)*L1_B):OR:(($ap)*L1_APMult):OR:Vidbit:OR:L1_Section - MEND - - MACRO - MemInitAbort $size, $logaddr - & ($size)*&00100000 - & $logaddr - & 0 - MEND - - MACRO - MemInitPagesL2 $size, $C, $B, $logaddr, $ap, $dramoffset - & ($size) - & $logaddr - & (($C)*L1_C):OR:(($B)*L1_B):OR:(($ap)*L2_APMult):OR:$dramoffset:OR:L1_Page - MEND - -MemInitTable ; sz, U, C, B, logaddr, (ap, (physaddr)) - MemInitSection 4, 1, 0, 0, &03000000, AP_None, &03000000 ; I/O - - MemInitAbort 1, &03400000 ; VIDC1 emulation zone - MemInitSection 1, 1, 0, 0, &03500000, AP_None, &03400000 ; VIDC20 space - MemInitSection 2, 1, 0, 0, &03600000, AP_None, &03600000 ; LAGs - - [ OSROM_ImageSize >= 8192 - ; We will map in the whole ROM, but only the first 8M will fall in the 26-bit - ; address space, and be available for modules. - MemInitROMs (OSROM_ImageSize / 1024), 1, 1, 1, &03800000, AP_Read - | - [ STB - [ ExtROMSupport ; System build option - ASSERT (OSROM_ImageSize <= 4096) ; No room for extension ROMs with an 8MB OS image - MemInitROMs 4, 1, 1, 1, &03800000, AP_Read ; ROM - MemInitSection 4, 1, 1, 1, &03C00000, AP_Read, &01000000 ; Extension ROM - | - MemInitROMs 8, 1, 1, 1, &03800000, AP_Read ; ROM (1st or 2nd bank) - ] - | - [ OSROM_ImageSize = 4096 - MemInitROMs 4, 1, 1, 1, &03800000, AP_Read ; ROM - MemInitROMs 4, 1, 1, 1, &03C00000, AP_Read ; ROM - | - MemInitROMs 2, 1, 1, 1, &03800000, AP_Read ; ROM - MemInitROMs 2, 1, 1, 1, &03A00000, AP_Read ; ROM - MemInitROMs 2, 1, 1, 1, &03C00000, AP_Read ; ROM - MemInitROMs 2, 1, 1, 1, &03E00000, AP_Read ; ROM - ] - ] - ] - - [ :LNOT: HAL - MemInitSection PSS, 1, 0, 0, PhysSpace, AP_None, &00000000 ; map of physical space - ] - - [ ShadowROM - MemInitROMs 2, 1, 1, 1, &FF800000, AP_Read ; ROM - MemInitROMs 2, 1, 1, 1, &FFA00000, AP_Read ; ROM - MemInitROMs 2, 1, 1, 1, &FFC00000, AP_Read ; ROM - MemInitROMs 2, 1, 1, 1, &FFE00000, AP_Read ; ROM - ] - -; Now explicit initialisation of L2 for static pages - - [ :LNOT: HAL - MemInitPagesL2 &8000, 0, 0, CursorChunkAddress, AP_Read, DRAMOffset_CursorChunk ;but see L1L2PTenhancements - MemInitPagesL2 &8000, 1, 1, &00000000, AP_Full, DRAMOffset_PageZero - MemInitPagesL2 &8000, 1, 1, SysHeapChunkAddress, AP_Full, DRAMOffset_SystemHeap - - [ StrongARM -;StrongARM requires 2*16k of private logical space (used for absolutely nothing else), which is -;readable and cacheable, for data cache cleaning purposes. We want to map the space to -;start of ROM bank 1 (physical target), so that IOMD timings can be poked for maximum read speed -;(only requirement of physical space is that it is readable without h/w abort). Here, though, -;we have to conform to format for MemInitPagesL2, so we just point to some convenient RAM, -;and fix things up later (see L1L2PTenhancements) -; - MemInitPagesL2 &8000, 1, 1, ARMA_Cleaners_address, AP_Read, DRAMOffset_PageZero - ] - [ No26bitCode - MemInitPagesL2 AbtStackSize, 1, 1, AbtStack, AP_Read, DRAMOffset_AbortStack - ] - - MemInitPagesL2 -1, 1, 1, UndStackSoftCamChunk, AP_Full, 0 ; variable offset and size - - ] ; :LNOT HAL - - & 0, 0, 0 ; terminate table - - LTORG - -; DistinctAddresses routine... -; r0,r1 are the addresses to check -; uses r2-5 -; writes interleaved patterns (to prevent dynamic storage...) -; checks writing every bit low and high... -; return Z-flag set if distinct - -; This routine must work in 32-bit mode - -DistinctAddresses ROUT - LDR r2, [r0] ; preserve - LDR r3, [r1] - LDR r4, Pattern - STR r4, [r0] ; mark first - MOV r5, r4, ROR #16 - STR r5, [r1] ; mark second - LDR r5, [r0] - CMP r5, r4 ; check first - BNE %10 ; exit with Z clear - LDR r5, [r1] ; check second - CMP r5, r4, ROR #16 ; clear Z if not same - BNE %10 -; now check inverse bit writes - STR r4, [r1] ; mark second - MOV r5, r4, ROR #16 - STR r5, [r0] ; mark first - LDR r5, [r1] - CMP r5, r4 ; check second - BNE %10 ; exit with Z clear - LDR r5, [r0] ; check first - CMP r5, r4, ROR #16 ; clear Z if not same -10 STR r3, [r1] ; restore - STR r2, [r0] - MOV pc, lr ; Z flag is already set up, and other flags don't matter - -Pattern - & &AAFF5500 ; shiftable bit check pattern - -; init state with masked out page size - -ResetMemC_Value - & &E010C :OR: MEMCADR ; slugged ROMs + flyback refresh only + 32K page - -; Constants -; -A0 * 1 :SHL: 00 -A1 * 1 :SHL: 01 -A2 * 1 :SHL: 02 -A3 * 1 :SHL: 03 -A4 * 1 :SHL: 04 -A5 * 1 :SHL: 05 -A6 * 1 :SHL: 06 -A7 * 1 :SHL: 07 -A8 * 1 :SHL: 08 -A9 * 1 :SHL: 09 -A10 * 1 :SHL: 10 -A11 * 1 :SHL: 11 -A12 * 1 :SHL: 12 -A13 * 1 :SHL: 13 -A14 * 1 :SHL: 14 -A15 * 1 :SHL: 15 -A16 * 1 :SHL: 16 -A17 * 1 :SHL: 17 -A18 * 1 :SHL: 18 -A19 * 1 :SHL: 19 -A20 * 1 :SHL: 20 -A21 * 1 :SHL: 21 -A22 * 1 :SHL: 22 -A23 * 1 :SHL: 23 -A24 * 1 :SHL: 24 -A25 * 1 :SHL: 25 -A26 * 1 :SHL: 26 -A27 * 1 :SHL: 27 -A28 * 1 :SHL: 28 -A29 * 1 :SHL: 29 -A30 * 1 :SHL: 30 -A31 * 1 :SHL: 31 - -Page32K * &C ; in MEMC control reg patterns... -Page16K * &8 -Page8K * &4 -Page4K * &0 - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; In r0=0 -> Coming from the Test routine - no fancy business! -; r1-r6 trashable -; [[[ r9 = Current MEMC CR (true MEMC value, not fudged to look like 4K page size) ]]] - -; Out [[[ r9 MEMC value with slowest ROM speed, correct pagesize ]]] -; r7 processor speed in kHz, bit 16 => can do STM to I/O (ie MEMC1a, MEMC2), bit 17 => MEMC2 - -; This routine must work in 32-bit mode, and should not use any memory!!!! - - [ RO371Timings - -TimeCPU ROUT ;does not actually measure anything - assumes timings (and EDO for 7500FE) according to IOMD id - - MOV r2, #IOC ; Address of the IO controller (IOMD) - - LDRB r7, [r2, #IOMD_ID0] ; Is - CMP r7, #&E7 ; It - LDRB r7, [r2, #IOMD_ID1] ; A - CMPEQ r7, #&D4 ; Risc PC ? - BEQ timecpuriscpc - CMP r7, #&AA ; assume 7500 or 7500FE - BEQ timecpu7500FE -;7500 then - MOV r7, #&32 ; 5-3 cycle ROM access - STRB r7, [r2, #IOMD_ROMCR0] - STRB r7, [r2, #IOMD_ROMCR1] - MOV r7, #&07 ; clock dividers: /1 for I/O, /1 for CPU, /1 for memory - STRB r7, [r2, #IOMD_CLKCTL] - LDR r7, =(1 :SHL: 16) :OR: 16000 ; assumed 16MHz RAM (32 MHz bus) - MOV pc, lr - -timecpu7500FE -;set memory to 32MHz for early boot (avoid probs with POST and with power-on key detection) - MOV r7, #&12 ; 5-3 cycle ROM access, half speed (ie. 10-6) - STRB r7, [r2, #IOMD_ROMCR0] - STRB r7, [r2, #IOMD_ROMCR1] - MOV r7, #&70 ; EDO RAM, 32 bit wide, conservative RAS and CAS timing - STRB r7, [r2, #IOMD_DRAMWID] ; DRAM control reg. (more than just width on FE) - MOV r7, #&04 ; clock dividers: /1 for CPU, /2 for memory, /2 for I/O - STRB r7, [r2, #IOMD_CLKCTL] - LDR r7, =(1 :SHL: 16) :OR: 32000 ; assumed 32MHz RAM (64 MHz bus), even though /2 at the moment - MOV pc, lr - -timecpuriscpc - MOV r7, #&12 ; 5-3 cycle ROM access - STR r7, [r2, #IOMD_ROMCR0] - STR r7, [r2, #IOMD_ROMCR1] - LDR r7, =(1 :SHL: 16) :OR: 16000 ; assumed 16MHz RAM (32 MHz bus) - MOV pc, lr - - [ :LNOT: HAL -;used by NewReset, after main kernel boot -;sets full 64MHz memory if on 7500FE -;preserves registers _and_ flags -; -finalmemoryspeed ROUT - EntryS r0 - MOV lr, #IOC - LDRB r0, [lr, #IOMD_ID0] ; Is - CMP r0, #&E7 ; It - LDRB r0, [lr, #IOMD_ID1] ; A - CMPEQ r0, #&D4 ; Risc PC ? - BEQ fmspeed_done - CMP r0, #&AA ; EQ if 7500FE - MOVEQ r0, #&80 - STREQB r0, [lr, #&CC] ; ASTCR register: set i/o asynchronous timing for fast memory clock - MOVEQ r0, #&06 ; clock dividers: /1 for CPU, /1 for memory, /2 for I/O - STREQB r0, [lr, #IOMD_CLKCTL] -fmspeed_done - EXITS ; ***KJB - flag preservation necessary? - ] - - | ; else if not RO371Timings - -ncpuloops * 1024 ; don't go longer than 4ms without refresh ! -nmulloops * 128 - -TimeCPU ROUT ;ONLY WORKS FOR IOMD(L) machines - this shouldn't be a problem though - [ :LNOT: AutoSpeedROMS - LDR r7, =(1 :SHL: 16) :OR: 16000 ; indicate 16MHz RAM - | - - [ {TRUE} -;don't do timing for Risc PC -; -;MJS bug fix (since 3.70) - setup r3 properly, and don't corrupt r0 you fool -; - MOV r3, #IOC ; Address of the IO controller - LDRB r7, [r3, #IOMD_ID0] ; Is - CMP r7, #&E7 ; It - LDRB r7, [r3, #IOMD_ID1] ; A - CMPEQ r7, #&D4 ; Medusa? - MOVEQ r7,#&3e00 ;for non-Morris force 16MHz timing, assumed Risc PC - ORREQ r7,r7,#&80 - ORREQ r7,r7,#&10000 ;and note we're on IOMD - MOVEQ pc,lr - ] - -; Time CPU/Memory speed - LDR r1, =&7FFE ; 32K @ 2MHz = ~16ms limit - MOV r3, #IOC ; Address of the IO controller - - CMP r0, #0 - LDREQ r7, =(1 :SHL: 16) :OR: 16000 ; indicate 16MHz RAM - a little lie :-) - MOVEQ pc, lr ; Quick, leg it while they're not looking! - - ;Turn off the CPU cache - - ; note that this old style code wont compile properly if HAL (no table) - ARM_number r4 - SUB r4,r4,#6 - ADRL r2,ARM_cacheoff_MMU_CR_table - LDR r2,[r2,r4,LSL #2] ;get appropriate cache-off value for MMU control reg - ARM_write_control r2 - - ;And don't forget to flush afterwards :-) - ;SetCop r0, CR_IDCFlush - ;SetCop r0, CR_TLBFlush - - ;Turn off DMA/refreshes, but keep the reg contents for future restoration - LDRB r4, [r3, #IOMD_VREFCR] ;Refresh - LDRB r5, [r3, #IOMD_SD0CR] ;Sound - LDRB r6, [r3, #IOMD_VIDCR] ;Video - MOV r2, #0 - STRB r2, [r3, #IOMD_VREFCR] ;Refresh off - STRB r2, [r3, #IOMD_SD0CR] ;Sound off - STRB r2, [r3, #IOMD_VIDCR] ;Video off - - MOV r2, r1, LSR #8 - STRB r1, [r3, #Timer1LL] - STRB r2, [r3, #Timer1LH] - LDR r2, =ncpuloops - STRB r2, [r3, #Timer1GO] ; start the timer NOW - B %FT10 ; Looks superfluous, but is required - ; to get ncpuloops pipeline breaks -10 - SUBS r2, r2, #1 ; 1S - BNE %BT10 ; 1N + 2S - - STRB r2, [r3, #Timer1LR] ; latch count NOW - LDRB r2, [r3, #Timer1CL] - LDRB r7, [r3, #Timer1CH] - ADD r2, r2, r7, LSL #8 ; count after looping is ... - - SUB r2, r1, r2 ; decrements ! - MOV r7, r2, LSR #1 ; IOC clock decrements at 2MHz, so we now have ticks in 1MHz - - ;Put DMA/refreshes back to what they were - STRB r4, [r3, #IOMD_VREFCR] ;Refresh back - STRB r5, [r3, #IOMD_SD0CR] ;Sound back - STRB r6, [r3, #IOMD_VIDCR] ;Video back - - ;And don't forget to flush first - ;SetCop r0, CR_IDCFlush - ;SetCop r0, CR_TLBFlush - - ;Turn on the CPU cache - - ;note that this old style code wont compile properly if HAL (no table) - ARM_number r4 - SUB r4,r4,#6 - ADRL r2,ARM_default_MMU_CR_table - LDR r2,[r2,r4,LSL #2] ;get appropriate default value for MMU control reg - ARM_write_control r2 - - MOV r2, r7 -; In ROM - each cpu loop took 4R cycles @ [MEMCLK cycles+1]/f*500ns/cycle - - [ MorrisSupport - LDRB r0, [r3, #IOMD_ID0] ; Is - CMP r0, #&E7 ; It - LDRB r0, [r3, #IOMD_ID1] ; A - CMPEQ r0, #&D4 ; Medusa? - LDRNE r0, =(4*15*500*ncpuloops) ;Morris timing values [reordered to prevent miscalculation - ;due to Aasm integering mid-calculation] (30720000) - LDREQ r0, =(4*(8*500/1000)*ncpuloops*1000) ;RiscPC/IOMD timing values (16384000) - DivRem r7, r0, r2, r1 ; r2 preserved, R7=memory speed in kHz (MEMCLK/2) - | - LDR r0, =(4*(8*500/1000)*ncpuloops*1000) ;RiscPC/IOMD timing values (16384000) - DivRem r7, r0, r2, r1 ; r2 preserved, R7=memory speed in kHz (MEMCLK/2) - ] - - ;Set the ROM speeds appropriately here, including Burst/NoBurst - MOV r4, #SystemROMspeed ; - MUL r0, r7, r4 ; r0 = number of cycles/ROM access *500000 - LDR r1, =500000 - DivRem r2, r0, r1, r4 ; r2 = divisor, r0 = remainder, r4 is trashed - CMP r0, #0 - ADDGT r2, r2, #1 ; Always round _UPWARDS_ - CMP r2, #14 - MOVGT r2, #14 ; Top out at 14 cycles - - MOV r5, #BurstROMspeed ; - MUL r0, r7, r5 ; r0 = number of cycles/ROM burst access *500000 - DivRem r3, r0, r1, r4 ; r3 = divisor, r0 = remainder, r4 is trashed - CMP r0, #0 - ADDGT r3, r3, #1 ; Always round _upwards_ - CMP r3, #4 - MOVGT r3, #4 ; Top out at 4 cycles - - [ :LNOT: NormalSpeedROMS - ;limit speeds to 4 cycles minimum (125 ns) - eg. for StrongARM with EPROM - CMP r2,#4 - MOVLT r2,#4 - CMP r3,#4 - MOVLT r3,#4 - ! 0, "*** WARNING Autospeed ROM speed limited to 4 cycles (125 ns) minimum ***" - ] - ;So we have R2=cycles for normal access, R3=cycles for burst access - ;Load the iomd reg into R1, clear the bits we're messing with - MOV r4, #IOC - LDRB r1, [r4, #IOMD_ROMCR0] ; Read ROMCR0 - AND r1, r1, #2_11000000 ; Only preserve bits 6 & 7 - - ADR r0, MemClkTable - LDRB r5, [r0, r2] ; Grab the relevant byte - ORR r1, r1, r5 - - ADR r0, BurstTable - LDRB r5, [r0, r3] ; Grab the relevant info - ORR r1, r1, r5 - - STRB r1, [r4, #IOMD_ROMCR0] ; Write ROMCR0 - STRB r1, [r4, #IOMD_ROMCR1] ; Write ROMCR1 - - ORR r7, r7, #1 :SHL: 16 ; Note MEMC1a presence (we're on IOMD) - ] -timecpu_sodthefancytimingstuff - MOV pc, lr - - ] ;RO371Timings conditional - - LTORG - -MemClkTable - DCB 2_100101 ; 0 cycles (set to min which is 2) - DCB 2_100101 ; 1 cycle (set to min. which is 2) - DCB 2_100101 ; 2 cycles - DCB 2_100100 ; 3 cycles - DCB 2_100011 ; 4 cycles - DCB 2_100010 ; 5 cycles - DCB 2_100001 ; 6 cycles - DCB 2_100000 ; 7 cycles - DCB 2_000011 ; 8 cycles (2x4) - DCB 2_000010 ; 9 cycles (same as 10) - DCB 2_000010 ; 10 cycles (2x5) - DCB 2_000001 ; 11 cycles (same as 12) - DCB 2_000001 ; 12 cycles (2x6) - DCB 2_000000 ; 13 cycles (same as 14) - DCB 2_000000 ; 14 cycles (2x7) - - ALIGN -BurstTable - DCB 2_000000 ; 0 cycles (no burst) - DCB 2_011000 ; 1 cycle - DCB 2_011000 ; 2 cycles - DCB 2_010000 ; 3 cycles - DCB 2_001000 ; 4 cycles - - ALIGN - - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; -; SWI OS_MMUControl -; -; in: r0 = 0 (reason code 0, for modify control register) -; r1 = EOR mask -; r2 = AND mask -; -; new control = ((old control AND r2) EOR r1) -; -; out: r1 = old value -; r2 = new value -; -; in: r0 bits 1 to 28 = 0, bit 0 = 1 (reason code 1, for flush request) -; r0 bit 31 set if cache(s) to be flushed -; r0 bit 30 set if TLB(s) to be flushed -; r0 bit 29 set if flush of entry only (else whole flush) -; r0 bit 28 set if write buffer to be flushed (implied by bit 31) -; r1 = entry specifier, if r0 bit 29 set -; (currently, flushing by entry is ignored, and just does full flush) -; - - ^ 0 -MMUCReason_ModifyControl # 1 ; reason code 0 -MMUCReason_Flush # 1 ; reason code 1 -MMUCReason_Unknown # 0 - -MMUControlSWI Entry - BL MMUControlSub - PullEnv - ORRVS lr, lr, #V_bit - ExitSWIHandler - -MMUControlSub - Push lr - AND lr,r0,#&FF - CMP lr, #MMUCReason_Unknown - ADDCC pc, pc, lr, LSL #2 - B MMUControl_Unknown - B MMUControl_ModifyControl - B MMUControl_Flush - -MMUControl_Unknown - ADRL r0, ErrorBlock_HeapBadReason - [ International - BL TranslateError - ] - Pull lr - SETV - MOV pc, lr - - -MMUControl_ModifyControl ROUT - Push "r3,r4,r5" - CMP r1,#0 - CMPEQ r2,#&FFFFFFFF - BEQ MMUC_modcon_readonly - MOV r3,#0 - LDRB r5,[r3, #ProcessorArch] - PHPSEI r4 ; disable IRQs while we modify soft copy (and possibly switch caches off/on) - - LDR lr, [r3, #MMUControlSoftCopy] - CMP r5,#ARMv4 - ARM_read_control lr,HS -; MOVHS lr,lr,LSL #19 -; MOVHS lr,lr,LSR #19 ; if ARMv4 or later, we can read control reg. - trust this more than soft copy - AND r2, r2, lr - EOR r2, r2, r1 - MOV r1, lr - LDR r5, [r3, #ProcessorFlags] - TST r5, #CPUFlag_SplitCache - BEQ %FT05 - TST r2,#&4 ; if split caches, then I bit mirrors C bit - ORRNE r2,r2,#&1000 - BICEQ r2,r2,#&1000 -05 - STR r2, [r3, #MMUControlSoftCopy] - BIC lr, r2, r1 ; lr = bits going from 0->1 - TST lr, #MMUC_C ; if cache turning on then flush cache before we do it - BEQ %FT10 - - Push "r0" - MOV r0, #0 - ARMop Cache_InvalidateAll,,,r0 - Pull "r0" -10 - BIC lr, r1, r2 ; lr = bits going from 1->0 - TST lr, #MMUC_C ; if cache turning off then clean data cache first - BEQ %FT15 - Push "r0" - MOV r0, #0 - ARMop Cache_CleanAll,,,r0 - Pull "r0" -15 - ARM_write_control r2 - BIC lr, r1, r2 ; lr = bits going from 1->0 - TST lr, #MMUC_C ; if cache turning off then flush cache afterwards - BEQ %FT20 - Push "r0" - MOV r0, #0 - ARMop Cache_InvalidateAll,,,r0 - Pull "r0" -20 - PLP r4 ; restore IRQ state - Pull "r3,r4,r5,pc" - -MMUC_modcon_readonly - MOV r3, #0 - LDRB r5, [r3, #ProcessorArch] - LDR lr, [r3, #MMUControlSoftCopy] - CMP r5, #ARMv4 - ARM_read_control lr,HS -; MOVHS lr,lr,LSL #19 -; MOVHS lr,lr,LSR #19 ; if ARMv4 or later, we can read control reg. - trust this more than soft copy - STRHS lr, [r3, #MMUControlSoftCopy] - MOV r1, lr - MOV r2, lr - Pull "r3,r4,r5,pc" - -MMUControl_Flush - MOVS r10, r0 - MOV r12, #0 - ARMop Cache_CleanInvalidateAll,MI,,r12 - TST r10,#&40000000 - ARMop TLB_InvalidateAll,NE,,r12 - TST r10,#&10000000 - ARMop WriteBuffer_Drain,NE,,r12 - ADDS r0,r10,#0 - Pull "pc" - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; -; Exception veneers - - [ :LNOT:No26bitCode -; Undefined instruction trap pre-veneer -; in: r13_undef -> a FD stack -; r14_undef -> undefined instruction +4 -; psr_undef = PSR at time of undef'd instruction - -UndPreVeneer ROUT - - Push "r0-r7,r14" ; push r0-r7 on undef stack, and make room for return address - MOV r0, r13_undef - -; for the time being just merge lr and psr - - MRS r1, SPSR ; r1 = saved PSR - AND r2, r1, #&F0000003 ; get saved NZCV and 26 bit modes - ORR lr_undef, lr_undef, r2 - AND r2, r1, #I32_bit + F32_bit ; extract I and F from new place - ORR r1, lr_undef, r2, LSL #IF32_26Shift ; r1 = combined lr and psr - - MRS r2, CPSR ; now switch into SVC26 - BIC r3, r2, #&1F - ORR r3, r3, #SVC26_mode - MSR SPSR_cxsf, r3 ; set SPSR_undef to be CPSR but with SVC26 - MSR CPSR_c, r3 ; and select this mode now - - MOV lr_svc, r1 ; lr_svc = PC + PSR from exception - - MSR CPSR_c, r2 ; go back into undef mode - - LDR r1, =UndHan ; work out address of undefined instruction handler - LDR r1, [r1] - STR r1, [r0, #8*4] ; and store it as return address - Pull "r0-r7, pc",,^ ; exit to handler, restoring sp_undef and entering SVC26 mode - ] - - [ No26bitCode :LAND: ChocolateAMB -; Instruction fetch abort pre-veneer, just to field possible lazy AMB aborts -; -PAbPreVeneer ROUT - Push "r0-r7, lr" ; wahey, we have an abort stack - SUB r0, lr_abort, #4 ; aborting address - MOV r2, #1 - BL AMB_LazyFixUp ; can trash r0-r7, returns NE status if claimed and fixed up - Pull "r0-r7, lr", NE ; restore regs and - SUBNES pc, lr_abort, #4 ; restart aborting instruction if fixed up - LDR lr, [sp, #8*4] ; (not a lazy abort) restore lr - LDR r0, =PAbHan ; we want to jump to PAb handler, in abort mode - LDR r0, [r0] - STR r0, [sp, #8*4] - Pull "r0-r7, pc" - ] - - [ :LNOT:No26bitCode -; Instruction fetch abort pre-veneer - -PAbPreVeneer ROUT - - LDR r13_abort, =PreVeneerRegDump - STMIA r13_abort, {r0-r7} - MOV r0, r13_abort - -; for the time being just merge lr and psr - - MRS r1, SPSR ; r1 = saved PSR - - LDR r2, =Abort32_dumparea - STMIA r2, {r1,lr_abort} ;dump 32-bit PSR, fault address (PC) - STR lr_abort,[r2,#2*4] ;dump 32-bit PC - - AND r2, r1, #&F0000003 ; get saved NZCV and 26 bit modes - ORR lr_abort, lr_abort, r2 - AND r2, r1, #I32_bit + F32_bit ; extract I and F from new place - ORR r1, lr_abort, r2, LSL #IF32_26Shift ; r1 = combined lr and psr - - MRS r2, CPSR ; now switch into SVC26 - BIC r2, r2, #&1F - ORR r2, r2, #SVC26_mode - MSR CPSR_c, r2 - - MOV lr_svc, r1 ; lr_svc = PC + PSR from exception - LDR r1, =PAbHan - LDR r1, [r1] - STR r1, [r0, #8*4] - LDMIA r0, {r0-r7, pc} ; jump to prefetch abort handler - ] - -; Preliminary layout of abort indirection nodes - - ^ 0 -AI_Link # 4 -AI_Low # 4 -AI_High # 4 -AI_WS # 4 -AI_Addr # 4 - - EXPORT DAbPreVeneer - -DAbPreVeneer ROUT - - [ No26bitCode - SUB r13_abort, r13_abort, #17*4 ; we use stacks, dontcherknow - | - LDR r13_abort, =PreVeneerRegDump - ] - STMIA r13_abort, {r0-r7} ; save unbanked registers anyway - STR lr_abort, [r13_abort, #15*4] ; save old PC, ie instruction address - - [ ChocolateAMB - ARM_read_FAR r0 ; aborting address - MOV r2, #0 - BL AMB_LazyFixUp ; can trash r0-r7, returns NE status if claimed and fixed up - LDR lr_abort, [r13_abort, #15*4] ; restore lr_abort - LDMIA r13_abort, {r0-r7} ; restore regs - ADDNE r13_abort, r13_abort, #17*4 ; if fixed up, restore r13_abort - SUBNES pc, lr_abort, #8 ; and restart aborting instruction - ] - - MRS r0, SPSR ; r0 = PSR when we aborted - MRS r1, CPSR ; r1 = CPSR - ADD r2, r13_abort, #8*4 ; r2 -> saved register bank for r8 onwards - - LDR r4, =Abort32_dumparea+3*4 ;use temp area (avoid overwriting main area for expected aborts) - ARM_read_FAR r3 - STMIA r4, {r0,r3,lr_abort} ; dump 32-bit PSR, fault address, 32-bit PC - - MOV r4, lr_abort ; move address of aborting instruction into an unbanked register - BIC r1, r1, #&1F ; knock out current mode bits - ANDS r3, r0, #&1F ; extract old mode bits (and test for USR26_mode (=0)) - TEQNE r3, #USR32_mode ; if usr26 or usr32 then use ^ to store registers - [ SASTMhatbroken - STMEQIA r2!,{r8-r12} - STMEQIA r2 ,{r13,r14}^ - SUBEQ r2, r2, #5*4 - | - STMEQIA r2, {r8-r14}^ - ] - BEQ %FT05 - - ORR r3, r3, r1 ; and put in user's - MSR CPSR_c, r3 ; switch to user's mode - - STMIA r2, {r8-r14} ; save the banked registers - - MRS r5, SPSR ; get the SPSR for the aborter's mode - STR r5, [r2, #8*4] ; and store away in the spare slot on the end - ; (this is needed for LDM with PC and ^) - [ No26bitCode - ORR r1, r1, #ABT32_mode - MSR CPSR_c, r1 ; back to abort mode for the rest of this -05 - Push "r0" ; save SPSR_abort - | -05 - ORR r1, r1, #SVC26_mode ; then switch to SVC for the rest of this - MSR CPSR_c, r1 - Push "r0, lr_svc" ; save SPSR_abort and lr_svc - ] - - [ SASTMhatbroken - SUB sp, sp, #3*4 - STMIA sp, {r13,r14}^ ; save USR bank in case STM ^, and also so we can corrupt them - NOP - STMDB sp!, {r8-r12} - | - SUB sp, sp, #8*4 ; make room for r8_usr to r14_usr and PC - STMIA sp, {r8-r15}^ ; save USR bank in case STM ^, and also so we can corrupt them - ] - - SUB r11, r2, #8*4 ; r11 -> register bank - STR r4, [sp, #7*4] ; store aborter's PC in user register bank - - TST r0, #T32_bit ; were they in Thumb mode? if so, give up now - BNE %FT90 - -;ARM 810 or StrongARM allow signed byte load or half-word load/stores - not supported at present -;***KJB - need to think about LDRH family - LDR r10, [r4, #-8]! ; r10 = actual instruction that aborted, and r4 points to it - AND r9, r10, #&0E000000 - TEQ r9, #&08000000 ; test for LDM/STM - BNE %FT50 ; if not LDM/STM, then it's an "easy" LDR/STR - -; Write "It's an LDM/STM" - - [ DebugAborts - DLINE "It's an LDM/STM" - ] - -; First count the number of transferred registers, and undo any writeback - - MOV r9, #0 ; r9 = no. of registers in list - MOVS r8, r10, LSL #16 - BEQ %FT20 -10 - MOVS r8, r8, LSL #1 - ADDCS r9, r9, #1 - BNE %BT10 -20 - MOV r8, r10, LSR #16 - AND r8, r8, #&0F ; base register number - LDR r7, [r11, r8, LSL #2] ; ------""----- value - - TST r10, #1 :SHL: 23 ; test up/down - MOVNE r1, r9 ; if up, r1 = +ve no. of regs - RSBEQ r1, r9, #0 ; if down, r1 = -ve no. of regs - -;initially assume writeback -;we want r6 = base reg value before assumed writeback (r7 is base reg value after abort) -;writeback will have been performed for ARMs with CPUFlag_BaseRestored clear -; - MOV r6, #0 - LDR r6, [r6, #ProcessorFlags] - TST r6, #CPUFlag_BaseRestored - MOVNE r6, r7 - SUBEQ r6, r7, r1, ASL #2 - -;now we want r6 to be the base register value before the abort, so we will discard -;our adjusted value and take r7, if the instruction in fact had no writeback -; - TST r10, #1 :SHL: 21 ; test if write-back bit set - TEQNE r8, #15 ; (if base is PC then write-back not allowed) - MOVEQ r6, r7 ; if not wb, reg after abort is correct - - MOV r1, sp ; r1 -> end of stack frame, and start of user-mode register bank - SUB sp, sp, r9, LSL #2 ; make stack frame for registers - TST r10, #1 :SHL: 20 ; if its an STM, we have to load up the stack frame - BNE %FT30 ; but if it's an LDM, we call trap routine first - - STR r6, [r11, r8, LSL #2] ; store original base in register list, to be overwritten after 1st transfer - -; now go through registers, storing them into frame - - MOV r5, sp ; pointer to position in stack frame - MOV lr, r10, LSL #16 ; extract bottom 16 bits - MOVS lr, lr, LSR #16 ; ie bitmask of which registers r0-r15 stored - BEQ %FT30 ; this shouldn't happen (it's illegal) - - MOV r3, r11 ; current pointer into register bank -21 - TST r10, #1 :SHL: 22 ; is it STM with ^ - ANDNE lr, lr, #&FF ; if so then extract bottom 8 bits (r0-r7 on 1st pass, r8-r15 on 2nd) -22 - MOVS lr, lr, LSR #1 ; shift bit into carry - LDRCS r2, [r3], #4 ; if set bit then transfer word from register bank - STRCS r2, [r5], #4 ; into stack frame - STRCS r7, [r11, r8, LSL #2] ; and after 1st transfer, store updated base into register bank - ADDCC r3, r3, #4 ; else just increment register bank pointer - BNE %BT22 ; if more bits to do, then loop - - TEQ r5, r1 ; have we done all registers? - MOVNE lr, r10, LSR #8 ; no, then must have been doing STM with ^, and have some user-bank regs to store - MOVNE r3, r1 ; so point r3 at user-mode register bank - BNE %BT21 ; and go back into loop - -30 - -; now work out address of 1st transfer - - ANDS r5, r10, #(3 :SHL: 23) ; bit 24 set => pre, bit 23 set => inc - SUBEQ r2, r6, r9, LSL #2 ; if post-dec, then 1st address = initial-nregs*4+4 - ADDEQ r2, r2, #4 - BEQ %FT32 - - CMP r5, #2 :SHL: 23 - MOVCC r2, r6 ; CC => post-inc, so 1st address = initial - SUBEQ r2, r6, r9, LSL #2 ; EQ => pre-dec, so 1st address = initial-nregs*4 - ADDHI r2, r6, #4 ; HI => pre-inc, so 1st address = initial+4 -32 - ANDS r0, r10, #1 :SHL: 20 ; r0 = 0 => STM - MOVNE r0, #1 ; = 1 => LDM - LDR r1, [r1, #8*4] ; get SPSR_abort - TST r1, #&F ; test if transfer took place in USR mode - ORRNE r0, r0, #2 ; if not then set bit 1 of flags word in r0 - MOV r1, sp ; block to transfer from/into - BIC r2, r2, #3 ; LDM/STM always present word-aligned address - MOV r3, r9, LSL #2 ; length of transfer in bytes, and r4 still points to aborting instruction - BL ProcessTransfer - ADDVS sp, sp, r9, LSL #2 ; if invalid transfer then junk stack frame - BVS %FT90 ; and generate an exception - -; we transferred successfully, so now check if LDM and load up register bank from block - - TST r10, #1 :SHL: 20 - ADDEQ sp, sp, r9, LSL #2 ; it's an STM, so junk stack frame and tidy up - BEQ %FT70 - -; now go through registers, loading them from frame - - ADD r1, sp, r9, LSL #2 ; r1 -> end of stack frame, and start of user-mode bank registers - MOV r5, sp ; pointer to position in stack frame - MOV r4, r10, LSL #16 ; extract bottom 16 bits - MOVS r4, r4, LSR #16 ; ie bitmask of which registers r0-r15 stored - BEQ %FT40 ; this shouldn't happen (it's illegal) - - SUB r3, r1, #8*4 ; r3 -> notional start of user bank, if it began at r0 (it actually starts at r8) - MOV r0, #0 ; assume no user registers by default - TST r10, #1 :SHL: 15 ; is PC in list - BNE %FT34 ; then can't be LDM of user bank - TST r10, #1 :SHL: 22 ; is it LDM with ^ - BEQ %FT34 ; no, then use main bank for all registers - LDR r2, [r1, #8*4] ; get SPSR - ANDS r2, r2, #15 ; get bottom 4 bits of mode (EQ => USR26 or USR32) - BEQ %FT34 ; if USR mode then use main bank for all - TEQ r2, #FIQ26_mode ; if FIQ mode then put r8-r14 in user bank - LDREQ lr, =&7F00 ; then put r8-r14 in user bank - LDRNE lr, =&6000 ; else put r13,r14 in user bank - AND r0, r4, lr ; r0 = mask of registers to put into user bank - BIC r4, r4, lr ; r4 = mask of registers to put into main bank - MOV lr, #0 -34 - MOVS r4, r4, LSR #1 ; shift bit into carry - LDRCS r2, [r5], #4 ; if set bit then transfer word from stack frame - STRCS r2, [r11, lr, LSL #2] ; into main register bank - MOVS r0, r0, LSR #1 ; shift bit into carry - LDRCS r2, [r5], #4 ; if set bit then transfer word from stack frame - STRCS r2, [r3, lr, LSL #2] ; into user register bank - ADD lr, lr, #1 - ORRS r6, r0, r4 ; have we finished both banks? - BNE %BT34 ; no, then loop - -; If LDM with PC in list, then add 4 to it, so the exit procedure is the same as if PC not loaded -; Also, if it was an LDM with PC and ^, then we have to update the stacked SPSR - -40 - MOV sp, r1 ; junk frame - - TST r10, #1 :SHL: 15 ; check PC in list - ADDNE r2, r2, #4 ; since PC is last, r2 will still hold the value loaded - STRNE r2, [r11, #15*4] ; store back into main register bank - TSTNE r10, #1 :SHL: 22 ; now check LDM ^ - BEQ %FT70 ; [not LDM with PC in list] - - LDR r9, [sp, #8*4] ; get SPSR_abort - AND r8, r9, #&1F ; r8 = aborter's mode - TEQ r8, #USR32_mode ; if in USR32 - BEQ %FT70 ; then the ^ has no effect (actually uses CPSR) - TST r8, #&1C ; if 32-bit mode - LDRNE r7, [r11, #16*4] ; then use SPSR for the aborter's mode else use updated r15 in r2 (26-bit format) - ANDEQ r7, r2, #&F0000003 ; flag and mode bits in same place - ANDEQ r2, r2, #&0C000000 ; but I and F have to move to bits 7 and 6 - ORREQ r7, r7, r2, LSR #(26-6) - -; r7 is now desired PSR (in 32-bit format) to update to -; now check which bits can actually be updated - - TEQ r8, #USR26_mode - BICEQ r9, r9, #&F0000000 ; if USR26 then we can only update NZCV - ANDEQ r7, r7, #&F0000000 - ORREQ r9, r9, r7 - MOVNE r9, r7 ; else can update all bits - STR r9, [sp, #8*4] ; store back updated SPSR_abort (to become CPSR) - B %FT70 ; now tidy up - -50 - -; it's an LDR/STR - first work out offset - - [ DebugAborts - DLINE "It's an LDR/STR" - ] - - TST r10, #1 :SHL: 25 ; if immediate - MOVEQ r9, r10, LSL #(31-11) ; then extract bottom 12 bits - MOVEQ r9, r9, LSR #(31-11) - BEQ %FT60 - - AND r8, r10, #&0F ; register to shift - LDR r9, [r11, r8, LSL #2] ; get actual value of register - - MOV r8, r10, LSR #7 ; extract shift amount - ANDS r8, r8, #&1F ; (bits 7..11) - MOVEQ r8, #32 ; if zero then make 32 - - ANDS r7, r10, #&60 - ANDEQ r8, r8, #&1F ; LSL 0 is really zero - MOVEQ r9, r9, LSL r8 - TEQ r7, #&20 - MOVEQ r9, r9, LSR r8 - TEQ r7, #&40 - MOVEQ r9, r9, ASR r8 - TEQ r7, #&60 - MOVEQ r9, r9, ROR r8 ; if 32 then we haven't spoilt it! - TEQEQ r8, #32 ; if ROR #32 then really RRX - BNE %FT60 - LDR r7, [sp, #8*4] ; get SPSR - AND r7, r7, #C_bit - CMP r7, #1 ; set carry from original user - MOV r9, r9, RRX -60 - TST r10, #1 :SHL: 23 ; test for up/down - RSBEQ r9, r9, #0 ; if down then negate - -;;;assume ARM 6 configured for LateAbort - others cannot be configured -;;;so, at run time, ARM 6 or 7 means late, ARM 8 or StrongARM means early -;;; -;;; [ LateAborts -;;; TST r10, #1 :SHL: 21 ; if write-back -;;; MOVNE r8, #0 ; then no post-inc -;;; RSBEQ r8, r9, #0 ; else post-inc = - pre-inc -;;; ADD r0, r8, r9 ; amount to subtract off base register for correction - -;;; TST r10, #1 :SHL: 24 ; however, if we're doing post-increment -;;; MOVEQ r8, r9 ; then post-inc = what was pre-inc -;;; MOVEQ r0, r9 ; and adjustment is what was added on -;;; RSB r9, r8, #0 ; and pre-inc = -post-inc -;;; | -;;; TST r10, #1 :SHL: 21 ; if write-back -;;; MOVNE r8, #0 ; then no post-inc -;;; RSBEQ r8, r9, #0 ; else post-inc = - pre-inc - -;;; TST r10, #1 :SHL: 24 ; however, if we're doing post-increment -;;; MOVEQ r8, r9 ; then post-inc = what was pre-inc -;;; MOVEQ r9, #0 ; and pre-inc = 0 -;;; ] - - MOV r8, #0 - LDR r8, [r8, #ProcessorFlags] - TST r8, #CPUFlag_BaseRestored - BNE %FT62 -;not base restored - TST r10, #1 :SHL: 21 ; if write-back - MOVNE r8, #0 ; then no post-inc - RSBEQ r8, r9, #0 ; else post-inc = - pre-inc - ADD r0, r8, r9 ; amount to subtract off base register for correction - - TST r10, #1 :SHL: 24 ; however, if we're doing post-increment - MOVEQ r8, r9 ; then post-inc = what was pre-inc - MOVEQ r0, r9 ; and adjustment is what was added on - RSB r9, r8, #0 ; and pre-inc = -post-inc - B %FT63 -62 -;base restored - TST r10, #1 :SHL: 21 ; if write-back - MOVNE r8, #0 ; then no post-inc - RSBEQ r8, r9, #0 ; else post-inc = - pre-inc - - TST r10, #1 :SHL: 24 ; however, if we're doing post-increment - MOVEQ r8, r9 ; then post-inc = what was pre-inc - MOVEQ r9, #0 ; and pre-inc = 0 - -63 - MOV r7, r10, LSL #31-19 - MOV r7, r7, LSR #28 ; r7 = base register number - LDR r6, [r11, r7, LSL #2] ; r6 = base register value - -;;; [ LateAborts -;;; SUB r0, r6, r0 ; compute adjusted base register -;;; STR r0, [r11, r7, LSL #2] ; and store back in case we decide to abort after all -;;; ] - - MOV r1, #0 - LDR r1, [r1, #ProcessorFlags] - TST r1, #CPUFlag_BaseRestored - SUBEQ r0, r6, r0 ; compute adjusted base register (if not base restored) - STREQ r0, [r11, r7, LSL #2] ; and store back in case we decide to abort after all - -; no need to clear PSR bits out of R15, because PSR is separate - - ADD r9, r9, r6 ; r2 = offset+base = illegal address - - [ DebugAborts - DREG r9, "Aborting address = " - DREG r8, "Post-increment = " - DREG r4, "Instruction where abort happened = " - ] - - ANDS r0, r10, #1 :SHL: 20 ; if an LDR then bit 20 set - MOVNE r0, #1 ; so make 1 - SUBNE sp, sp, #4 ; then just create 1 word stack frame - BNE %FT65 - - MOV r5, r10, LSR #12 ; else it's an STR (r0 = 0) - AND r5, r5, #&0F ; r5 = source register number - LDR r5, [r11, r5, LSL #2] ; r5 = value of source register - [ DebugAborts - DREG r5, "Data value to store = " - ] - Push "r5" ; create stack frame with this value in it -65 - LDR r1, [sp, #(1+8)*4] ; get SPSR_abort - TST r1, #&F ; test if transfer took place in USR mode - ORRNE r0, r0, #2 ; if not then set bit 1 of flags word in r0 - - MOV r1, sp ; r1 -> data block - TST r10, #1 :SHL: 22 ; if byte transfer - MOVNE r3, #1 ; then length of transfer = 1 - MOVNE r2, r9 ; and use unmolested address - MOVEQ r3, #4 ; else length = 4 - BICEQ r2, r9, #3 ; and mask out bottom 2 bits of address - - BL ProcessTransfer - ADDVS sp, sp, #4 ; if illegal transfer, junk stack frame - BVS %FT90 ; and cause exception - - ADD r6, r9, r8 ; update base register with offset - STR r6, [r11, r7, LSL #2] ; and store back (NB if LDR and dest=base, the load overwrites the updated base) - - TST r10, #1 :SHL: 20 ; if it's STR (not LDR) - ADDEQ sp, sp, #4 ; then junk stack frame - BEQ %FT70 ; and tidy up - - Pull "r6" ; LDR/LDRB, so get value to load into register - TST r10, #1 :SHL: 22 ; if LDRB - ANDNE r6, r6, #&FF ; then put zero in top 3 bytes of word - ANDEQ r9, r9, #3 ; else rotate word to correct position - r9 = bottom 2 bits of address - MOVEQ r9, r9, LSL #3 ; multiply by 8 to get rotation factor - MOVEQ r6, r6, ROR r9 ; rotate to correct position in register - - MOV r5, r10, LSR #12 ; test for LDR PC - AND r5, r5, #&0F ; r5 = dest register number - TEQ r5, #15 ; if PC - ADDEQ r6, r6, #4 ; then adjust for abort exit - STR r6, [r11, r5, LSL #2] ; store into register bank - -70 - -; Tidy up routine, common to LDR/STR and LDM/STM - - ADD r2, r11, #8*4 ; point r2 at 2nd half of main register bank - LDMIA sp, {r8-r14}^ ; reload user bank registers - NOP ; don't access banked registers after LDM^ - ADD sp, sp, #8*4 ; junk user bank stack frame - - [ No26bitCode - Pull "r0" ; r0 = (possibly updated) SPSR_abort - MRS r1, CPSR - | - Pull "r0, lr" ; r0 = (possibly updated) SPSR_abort, restore lr_svc - - SetMode ABT32_mode, r1 ; leaves r1 = current PSR - ] - - MRS r6, SPSR ; get original SPSR, with aborter's original mode - AND r7, r6, #&0F - TEQ r7, #USR26_mode ; also matches USR32 - LDMEQIA r2, {r8-r14}^ ; if user mode then just use ^ to reload registers - NOP - BEQ %FT80 - - ORR r6, r6, #I32_bit ; use aborter's flags and mode but set I - BIC r6, r6, #T32_bit ; and don't set Thumb bit - MSR CPSR_c, r6 ; switch to aborter's mode - LDMIA r2, {r8-r14} ; reload banked registers - MSR CPSR_c, r1 ; switch back to ABT32 - -80 - LDR lr_abort, [r13_abort, #15*4] ; get PC to return to - MSR SPSR_cxsf, r0 ; set up new SPSR (may have changed for LDM {PC}^) - - LDMIA r13_abort, {r0-r7} ; reload r0-r7 - [ No26bitCode - ADD r13_abort, r13_abort, #17*4 ; we use stacks, dontcherknow - ] - SUBS pc, lr_abort, #4 ; go back 8 to adjust for PC being 2 words out, - ; then forward 4 to skip instruction we've just executed - -; Call normal exception handler - -90 - -; copy temp area to real area (we believe this is an unexpected data abort now) - - LDR r0, =Abort32_dumparea - LDR r1, [r0,#3*4] - STR r1, [r0] - LDR r1, [r0,#4*4] - STR r1, [r0,#4] - LDR r1, [r0,#5*4] - STR r1, [r0,#2*4] - - [ No26bitCode - MOV r0, #0 ; we're going to call abort handler - STR r0, [r0, #CDASemaphore] ; so allow recovery if we were in CDA - - LDR r0, =DAbHan - LDR r0, [r0] ; get address of data abort handler - [ DebugAborts - DREG r0, "Handler address = " - ] - - ADD r2, r11, #8*4 ; point r2 at 2nd half of main register bank - LDMIA sp, {r8-r14}^ ; reload user bank registers - NOP ; don't access banked registers after LDM^ - ADD sp, sp, #9*4 ; junk user bank stack frame + saved SPSR - - MRS r1, CPSR - - MRS r6, SPSR ; get original SPSR, with aborter's original mode - AND r7, r6, #&0F - TEQ r7, #USR26_mode ; also matches USR32 - LDMEQIA r2, {r8-r14}^ ; if user mode then just use ^ to reload registers - NOP - BEQ %FT80 - - ORR r6, r6, #I32_bit ; use aborter's flags and mode but set I - BIC r6, r6, #T32_bit ; and don't set Thumb - MSR CPSR_c, r6 ; switch to aborter's mode - LDMIA r2, {r8-r14} ; reload banked registers - MSR CPSR_c, r1 ; switch back to ABT32 - -80 - STR r0, [r13_abort, #16*4] ; save handler address at top of stack - LDR lr_abort, [r13_abort, #15*4] ; get abort address back in R14 - - LDMIA r13_abort, {r0-r7} ; reload r0-r7 - ADD r13_abort, r13_abort, #16*4 ; we use stacks, dontcherknow - - Pull pc - - | -; for the time being just merge lr and psr - - LDR r0, [sp, #8*4] ; r0 = original SPSR (can't have been modified) - - LDR lr, [r11, #15*4] ; get PC of aborter - AND r1, r0, #&F0000000 ; get saved NZCV - ORR lr, lr, r1 - AND r1, r0, #I32_bit + F32_bit ; extract I and F from new place - ORR lr, lr, r1, LSL #IF32_26Shift ; and merge - AND r1, r0, #3 ; get old mode bits (have to assume a 26-bit mode!) - ORR lr, lr, r1 ; lr = combined lr and psr - STR lr, [sp, #9*4] ; overwrite stacked lr_svc - TEQ r1, #SVC26_mode ; if aborter was in SVC mode - STREQ lr, [r11, #14*4] ; then also overwrite r14 in aborter's register bank - - BIC r0, r0, #&1F ; clear mode bits in SPSR - ORR r0, r0, #SVC26_mode :OR: I32_bit ; and force SVC26 with I set - [ DebugAborts - DLINE "Going to call data abort handler" - DREG lr, "lr_svc will be " - DREG r0, "PSR going to exit with = " - ] - STR r0, [sp, #8*4] ; overwrite stacked SPSR - ] - - MOV r0, #0 ; we're going to call abort handler - STR r0, [r0, #CDASemaphore] ; so allow recovery if we were in CDA - - LDR r0, =DAbHan - LDR r0, [r0] ; get address of data abort handler - [ DebugAborts - DREG r0, "Handler address = " - ] - ADD r0, r0, #4 ; add on 4 to adjust for abort exit - STR r0, [r11, #15*4] ; and store in pc in register bank - B %BT70 ; then junk to normal tidy-up routine - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; -; ProcessTransfer - Process an abort transfer -; -; in: r0 = flags -; bit 0 = 0 => Store to memory -; 1 => Load from memory -; bit 1 = 0 => Transfer executed in user mode -; 1 => Transfer executed in non-user mode -; r1 = block of data to transfer from/into -; r2 = illegal address -; r3 = length of transfer in bytes -; r4 -> instruction which aborted -; SVC26/32 mode -; -; out: V=0 => transfer accomplished -; V=1 => transfer not accomplished -; All registers preserved -; - -SectionSizeShift * 20 -SectionSize * 1 :SHL: SectionSizeShift - -LargePageSizeShift * 16 -LargePageSize * 1 :SHL: LargePageSizeShift - -SmallPageSizeShift * 12 -SmallPageSize * 1 :SHL: SmallPageSizeShift - -ProcessTransfer Entry "r1-r7,r12" - - [ DebugAborts - DLINE "ProcessTransfer entered" - DREG r2, "Illegal address = " - DREG r3, "Length of transfer = " - DREG r4, "Abort happened at address " - DREG r0, "Flags = " - DLINE "Data = ",cc - - MOV r5, r3 - MOV r6, r1 -01 - LDR r7, [r6], #4 - DREG r7," ",cc - SUBS r5, r5, #4 - BHI %BT01 - DLINE "" - ] - - -; First identify if start address should have aborted - -10 - LDR r7, =L1PT - MOV lr, r2, LSR #SectionSizeShift ; r2 as a multiple of 1Mb - EOR r5, r2, lr, LSL #SectionSizeShift ; r5 = offset within section - SUB r5, r2, r5 ; r5 -> start of section containing r2 - ADD r5, r5, #SectionSize ; r5 -> start of section after r2 - - LDR lr, [r7, lr, LSL #2] ; get L1PT entry - ANDS r7, lr, #3 ; 00 => trans.fault, 01 => page, 10 => section, 11 => reserved (fault) - TEQNE r7, #3 - BEQ Fault - TEQ r7, #1 - BEQ CheckPage - -; it's section mapped - check section access privileges - -15 - ANDS r7, lr, #3 :SHL: 10 ; extract ap - BEQ Fault ; 00 => no access for anyone (at the moment) - TST r0, #2 ; test for non-usr access - BNE %FT20 ; if non-usr then OK to access here - CMP r7, #2 :SHL: 10 - BCC Fault ; 01 => no usr access - BHI %FT20 ; 11 => full user access, so OK - TST r0, #1 - BEQ Fault ; 10 => usr read-only, so stores not allowed - -; access OK, so copy up to end of section/sub-page - -20 -;ARM 8 and StrongARM will abort for vector reads (as well as writes) in 26bit mode, so we must -;handle vector reads properly as well now -;In fact, StrongARM does not abort (optional in architecture 4), but ARM 8 does - MJS 08-10-96 - [ {FALSE} - TST r0, #1 ; if load from memory - BNE %FT60 ; then skip - ] - -; it's a store to memory (may be a vector write), or a read from memory (may be a vector read) -; do it in words if >= 4 bytes, so word writes to VIDC work for example - -25 - CMP r2, #&1C ; if in abort area (but allow any access to &1C) - [ OnlyKernelCanAccessHardwareVectors - BHS %FT22 - CMP r4, #ROM ; and executing outside the kernel - BLO %FT23 - ADRL lr, EndOfKernel - CMP r4, lr - BLO %FT22 -23 - MOV r5, #&20 ; then set end-of-section = 32 - B Fault ; and check user list -22 - | - CMPCC r4, #ROM ; and executing out of RAM - MOVCC r5, #&20 ; then set end-of-section = 32 - BCC Fault ; and check user list - ] - - [ :LNOT:No26bitCode - SetMode SVC32_mode, lr ; go into SVC32 so we can poke or peek vector area - ] - - TST r0, #1 ; test for peek/poke - BEQ %FT30 -26 -;peeking - TEQ r2, r5 ; have we gone onto a new block? - BEQ %FT50 ; if so then exit if finished else go back to outer loop - SUBS r3, r3, #4 ; have we got at least a word to do? - LDRCS lr, [r2], #4 ; if so then copy word - STRCS lr, [r1], #4 - BHI %BT26 ; and if not all done then loop - BEQ %FT50 ; if all done then switch back to SVC26 and exit - - ADDS r3, r3, #4 -27 - LDRB lr, [r2], #1 ; read byte from register bank - STRB lr, [r1], #1 ; and store to memory - SUBS r3, r3, #1 ; decrement byte count - BEQ %FT50 ; if finished then switch back to SVC26 and exit - TEQ r2, r5 ; have we gone onto a new block? - BNE %BT27 ; no, then loop - B %FT50 - -30 -;poking - TEQ r2, r5 ; have we gone onto a new block? - BEQ %FT50 ; if so then exit if finished else go back to outer loop - SUBS r3, r3, #4 ; have we got at least a word to do? - LDRCS lr, [r1], #4 ; if so then copy word - STRCS lr, [r2], #4 - BHI %BT30 ; and if not all done then loop - BEQ %FT50 ; if all done then switch back to SVC26 and exit - - ADDS r3, r3, #4 -40 - LDRB lr, [r1], #1 ; read byte from register bank - STRB lr, [r2], #1 ; and store to memory - SUBS r3, r3, #1 ; decrement byte count - BEQ %FT50 ; if finished then switch back to SVC26 and exit - TEQ r2, r5 ; have we gone onto a new block? - BNE %BT40 ; no, then loop - -50 - [ :LNOT:No26bitCode - SetMode SVC26_mode, lr - ] - CMP r3, #0 - BNE %BT10 - EXIT ; exit (VC from CMP) - - [ {FALSE} -; it's a load from memory -60 - LDRB lr, [r2], #1 ; read byte from memory - STRB lr, [r1], #1 ; and store to memory bank - SUBS r3, r3, #1 ; decrement byte count - EXIT EQ ; if finished then exit (VC from SUBS) - TEQ r2, r5 ; have we gone onto a new block? - BNE %BT60 ; no, then loop - B %BT10 ; yes, then go back to start - ] - -; it's page mapped, so check L2PT -; lr = L1 table entry -; We use the logical copy of physical space here, in order to access the entry pointed to by the L1 entry - -CheckPage - MOV r5, r2, LSR #SmallPageSizeShift ; r2 as a multiple of 4K - MOV r5, r5, LSL #SmallPageSizeShift - ADD r5, r5, #SmallPageSize ; if translation fault, then it applies to small page - - MOV lr, lr, LSR #10 ; remove domain and U bits - MOV lr, lr, LSL #10 - [ HAL - SUB sp, sp, #4 - Push "r0-r3,r12" - MOV r0, #0 - MOV r1, lr - ADD r2, sp, #5*4 - BL RISCOS_AccessPhysicalAddress - MOV lr, r0 - Pull "r0-r3,r12" - | - ORR lr, lr, #PhysSpace ; now physical address is converted to a logical one (in physspace) - ] - AND r7, r2, #&000FF000 ; extract bits which are to form L2 offset - - LDR lr, [lr, r7, LSR #10] ; lr = L2PT entry - [ HAL - Push "r0-r3,r12,lr" - LDR r0, [sp, #6*4] - BL RISCOS_ReleasePhysicalAddress - Pull "r0-r3,r12,lr" - ADD sp, sp, #4 - ] - ANDS r7, lr, #3 ; 00 => trans.fault, 01 => large page - ; 10 => small page, 11 => reserved (fault) - TEQNE r7, #3 - BEQ Fault - TEQ r7, #2 ; if small page - MOVEQ r7, #SmallPageSizeShift-2 ; then sub-page size = 1<<10 - MOVNE r7, #LargePageSizeShift-2 ; else sub-page size = 1<<14 - - MOV r5, r2, LSR r7 ; round down to start of sub-page - MOV r5, r5, LSL r7 - MOV r6, #1 - ADD r5, r5, r6, LSL r7 ; then move on to start of next sub-page - - MOV r7, r2, LSR r7 ; put sub-page number in bits 1,2 - AND r7, r7, #3 ; and junk other bits - RSB r7, r7, #3 ; invert sub-page ordering - MOV r7, r7, LSL #1 ; and double it - MOV lr, lr, LSL r7 ; then shift up access privileges so that correct ones appear in bits 10,11 - B %BT15 ; re-use code to check access privileges - -Fault - SUB r5, r5, r2 ; r5 = number of bytes we can do in this section/page/sub-page - Push "r3" ; save number of bytes to do - CMP r3, r5 ; if more bytes than there are in this block - MOVHI r3, r5 - -; Now scan list of user abort addresses - - MOV r6, #0 - LDR r6, [r6, #AbortIndirection] - TEQ r6, #0 - BEQ %FT85 ; address not in any abort node -75 - LDR r5, [r6, #AI_Low] - CMP r2, r5 - BCC %FT80 - LDR r5, [r6, #AI_High] - CMP r2, r5 - BCS %FT80 - - Push "r3" ; save number of bytes we can do in this section/page/sub-page - SUB r5, r5, r2 ; number of bytes we can do for this node - CMP r3, r5 ; if bigger than the size of this node - MOVHI r3, r5 ; then restrict number of bytes - - ADD r5, r6, #AI_WS - MOV lr, pc - LDMIA r5, {r12, pc} - -; returns to here - - ADDVS sp, sp, #8 ; if user abort failed, then junk both pushed r3's - EXIT VS ; and exit - - ADD r1, r1, r3 ; advance register block - ADD r2, r2, r3 ; and illegal address pointer - - LDR r5, [sp, #4] ; subtract amount done from stacked total amount to do - SUBS r5, r5, r3 - STR r5, [sp, #4] ; and store back - - Pull "r5" - SUBS r3, r5, r3 ; is there more to do in this section/page/sub-page? - BEQ %FT90 ; no then skip -80 - LDR r6, [r6, #AI_Link] ; else try next node - TEQ r6, #0 - BNE %BT75 -85 - ADD sp, sp, #4 ; junk pushed r3 - SETV ; indicate access invalid - EXIT ; and exit - -90 - Pull "r3" ; restore total amount left to do - TEQ r3, #0 - BNE %BT10 ; yes, then loop - EXIT ; no, then exit (V=0 from SUBS) - - -;some tricks to improve performance, looking at MMU level 1 and level 2 page tables -L1L2PTenhancements ROUT - Push "r0-r5,lr" - - ;mjs change for Ursula: - ;improved kernel workspace protection - ; - user access to bottom 3k restricted to read only (things like Clib tmpnam counter prevent - ; going further) - ; - Java VM will probably require bottom 1k restricted to no user access (so that VM can avoid - ; all run-time checks for null pointers), but this currently makes various things like ShareFS - ; go pop-bang, so not done yet (see TRUE/FALSE choice below) - ; - MOV r0,#L2PT ;L2PT address for page at 0 - LDR r1,[r0] - BIC r1,r1,#&FF0 ;clear current AP bits for all four 1k sub-pages (S0 to S3) - [ {FALSE} ;this would be good for Java VM: - ORR r1,r1,#&E90 ;S0=user none, S1=user read, S2=user read, S3=user read/write - | ;this makes less current things go pop-bang: - ORR r1,r1,#&EA0 ;S0=user read, S1=user read, S2=user read, S3=user read/write - ] - STR r1,[r0] - -;if the MMU control reg (soft copy) has R bit set (bit 9), then adjust the L1 entries for ROM -;space to give full write protection (user and supervisor) - MOV r0,#0 - LDR r1,[r0,#MMUControlSoftCopy] - TST r1,#&200 - BEQ L1L2PTe_WPROMdone ;ARM 610 has no R bit, for example - LDR r0,=L1PT - ADD r0,r0,#ROM :SHR: (20-2) ;address of first L1PT entry for ROM space - [ OSROM_ImageSize > 8192 - MOV r1,#OSROM_ImageSize / 1024 - | - MOV r1,#8 ;8 entries (8 Mbytes) - ] -L1L2PTe_WPROMloop - LDR r2,[r0] - BIC r2,r2,#&C00 ;set AP (access permission) bits to 00 - STR r2,[r0],#4 - SUBS r1,r1,#1 - BNE L1L2PTe_WPROMloop -L1L2PTe_WPROMdone - - [ :LNOT: (CanLiveOnROMCard :LOR: ROMCardSupport :LOR: ExtROMSupport) - -;go for best available memory speed for data cache cleaner area (StrongARM) - LDR r0,=L2PT :OR: (ARMA_Cleaners_address :SHR: 10) ;address of 1st L2PT word for cleaner area - LDR r1,[r0] - MOV r1,r1,LSL #20 - MOV r1,r1,LSR #20 ;zap physical address field - ORR r1,r1,#&01000000 ; = physical address of start of ROM bank 1 - MOV r2,#8 ;8 L2PT entries to fiddle -00 - STR r1,[r0],#4 - SUBS r2,r2,#1 - BNE %BT00 - MOV r0,#IOC - MOV r1,#5 - STRB r1,[r0, #IOMD_ROMCR1] ;ROM bank 1 speed = fastest (62.5 ns) - ] - -;make first 5 pages of cursor chunk cacheable and bufferable - this is rather handy, 'coz things -;like the SWI dispatcher, IRQ dispatcher are here. May be a slight worry over cursor data -;being write-back cached (StrongARM) - should strictly clean,drain write buffer or whatever for shape change. - LDR r0,=L2PT :OR: (CursorChunkAddress :SHR: 10) ;address of 1st L2PT word for CursorChunk - MOV R2,#5 ;5 entries to adjust -01 - LDR r1,[r0] - ORR r1,r1,#&C ;make page cacheable and bufferable - STR r1,[r0],#4 - SUBS r2,r2,#1 - BNE %BT01 - -;make other 3 pages of chunk bufferable - MOV R2,#3 -02 - LDR r1,[r0] - ORR r1,r1,#&4 ;make page bufferable - STR r1,[r0],#4 - SUBS r2,r2,#1 - BNE %BT02 - -;try to rescue some pages from the L2PT itself, in the AppSpace region - ie. AppSpace max size can really -;be total RAM size, if that is less than 28 Mb, and for every 4Mb less that is we can rescue a 4k page -;and return it to the free pool - handy on a 2Mb Kryten for instance! - - LDR r0,=MaxCamEntry - LDR r0,[r0] - ADD r0,r0,#1+255+768 ; = no. of 4k RAM pages in machine + 255 + 3*256 - MOV r0,r0,LSR #8 ; = no. of Mbytes in machine rounded up + 3 - BIC r0,r0,#3 ; round up to next 4 Mb - CMP r0,#28 ; if 28Mb or more, no pages to be rescued from L2PT AppSpace - BHS %FT09 - LDR r1,=AppSpaceDANode - MOV r2,r0,LSL #20 - STR r2,[r1,#DANode_MaxSize] ; update AppSpace max size - MOV r0,r0,LSR #2 ; no. of L2PT AppSpace pages which cannot be rescued - MOV r1,#L2PT - ADD r4, r1, #L1PT-L2PT - ADD r4, r4, r0, LSL #4 ;the L1PT entry to blank out (4 L1 entries per L2 entry) - ADD r1,r1,#(L2PT :SHR: (12-2)) ;the L2PT of the L2PT (and first 7 entries are for App Space) - ADD r1,r1,r0,LSL #2 ;first entry for rescue - LDR r3,=FreePoolDANode - LDR r2,[r3,#DANode_Base] - LDR r5,[r3,#DANode_Size] ; FreePool size so far - ADD r2,r2,r5 ; r2 -> next logical address for a rescued page - - SUB sp,sp,#16 ; room for 1 page block entry + terminator - MOV r3,sp -05 - Push "r0" - LDR r0,[r1],#4 ; pick up the L2PT entry - BIC r0,r0,#&0FF - BIC r0,r0,#&F00 ; mask to leave physical address only - STR r0,[r3,#8] ; store physical address in word 2 of page block entry - - Push "r1-r2" - MOV r0,#&0C00 - MOV r1,r3 - MOV r2,#1 - SWI XOS_Memory ; fill in page number, given physical address - - MOV r0,#2 ; means inaccessible in user mode (destined for FreePool) - STR r0,[r3,#8] - MOV r0,#-1 - STR r0,[r3,#12] ; terminator - Pull "r1-r2" - - STR r2,[r3,#4] ; new logical address for page - MOV r0,r3 - SWI XOS_SetMemMapEntries - - MOV r0, #0 ; Blank out the L1PT entries for the page table we just removed - STR r0, [r4], #4 - STR r0, [r4], #4 - STR r0, [r4], #4 - STR r0, [r4], #4 - - Pull "r0" - ADD r2,r2,#4096 - ADD r5,r5,#4096 ; next page - ADD r0,r0,#1 - CMP r0,#7 ;7 entries in total for full 28Mb AppSpace - BNE %BT05 - ADD sp,sp,#16 ;drop the workspace - - LDR r0,=FreePoolDANode - STR r5,[r0,#DANode_Size] ;update FreePoolSize - -09 - Pull "r0-r5,pc" - - -; -; ---------------- XOS_SynchroniseCodeAreas implementation --------------- -; - -;this SWI effectively implements IMB and IMBrange (Instruction Memory Barrier) -;for newer ARMs - -;entry: -; R0 = flags -; bit 0 set -> R1,R2 specify virtual address range to synchronise -; R1 = start address (word aligned, inclusive) -; R2 = end address (word aligned, inclusive) -; bit 0 clear synchronise entire virtual space -; bits 1..31 reserved -; -;exit: -; R0-R2 preserved -; -SyncCodeAreasSWI ROUT - Push "lr" - BL SyncCodeAreas - Pull "lr" ; no error return possible - B SLVK - -SyncCodeAreas - TST R0,#1 ; range variant of SWI? - BEQ SyncCodeAreasFull - -SyncCodeAreasRange - Push "r0-r2, lr" - MOV r0, r1 - ADD r1, r2, #4 ;exclusive end address - MOV r2, #0 - LDRB lr, [r2, #DCache_LineLen] - SUB lr, lr, #1 - ADD r1, r1, lr ;rounding up end address - MVN lr, lr - AND r0, r0, lr ;cache line aligned - AND r1, r1, lr ;cache line aligned - ARMop IMB_Range,,,r2 - Pull "r0-r2, pc" - -SyncCodeAreasFull - Push "r0, lr" - MOV r0, #0 - ARMop IMB_Full,,,r0 - Pull "r0, pc" - - LTORG - - [ DebugAborts - InsertDebugRoutines - ] - END diff --git a/s/ARMops b/s/ARMops deleted file mode 100644 index e8e27f73..00000000 --- a/s/ARMops +++ /dev/null @@ -1,1732 +0,0 @@ -; Copyright 2000 Pace Micro Technology plc -; -; 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. -; - ; GET Hdr:ListOpts - ; GET Hdr:Macros - ; GET Hdr:System - ; $GetCPU - ; $GetMEMM - - ; GET hdr.Options - - ; GET Hdr:PublicWS - ; GET Hdr:KernelWS - - ; GET hdr.Copro15ops - ; GET hdr.ARMops - -v7 RN 10 - - ; EXPORT Init_ARMarch - ; EXPORT ARM_Analyse - ; EXPORT ARM_PrintProcessorType - - ; AREA KernelCode,CODE,READONLY - -; ARM keep changing their mind about ID field layout. -; Here's a summary, courtesy of the ARM ARM (v5): -; -; pre-ARM 7: xxxx0xxx -; ARM 7: xxxx7xxx where bit 23 indicates v4T/~v3 -; post-ARM 7: xxxanxxx where n<>0 or 7 and a = architecture (1=4,2=4T,3=5,4=5T) -; - -; int Init_ARMarch(void) -; Returns architecture, as above in a1. Also EQ if ARMv3, NE if ARMv4 or later. -; Corrupts only ip, no RAM usage. -Init_ARMarch - ARM_read_ID ip - ANDS a1, ip, #&0000F000 - MOVEQ pc, lr ; ARM 3 or ARM 6 - TEQ a1, #&00007000 - BNE %FT20 - TST ip, #&00800000 ; ARM 7 - check for Thumb - MOVNE a1, #ARMv4T - MOVEQ a1, #ARMv3 - MOV pc, lr -20 ANDS a1, ip, #&000F0000 ; post-ARM 7 - MOV a1, a1, LSR #16 - MOV pc, lr - - - -ARM_Analyse - Push "v1,v2,v5,v6,v7,lr" - ARM_read_ID v1 - ARM_read_cachetype v2 - MOV v6, #ZeroPage - - ADRL v7, KnownCPUTable -FindARMloop - LDMIA v7!, {a1, a2} ; See if it's a known ARM - CMP a1, #-1 - BEQ %FT20 - AND a2, v1, a2 - TEQ a1, a2 - ADDNE v7, v7, #8 - BNE FindARMloop - TEQ v2, v1 ; If we don't have cache attributes, read from table - LDREQ v2, [v7] - -20 TEQ v2, v1 - BEQ %BT20 ; Cache unknown: panic - - CMP a1, #-1 - LDRNEB a2, [v7, #4] - MOVEQ a2, #ARMunk - STRB a2, [v6, #ProcessorType] - - ASSERT CT_Isize_pos = 0 - MOV a1, v2 - ADD a2, v6, #ICache_Info - BL EvaluateCache - MOV a1, v2, LSR #CT_Dsize_pos - ADD a2, v6, #DCache_Info - BL EvaluateCache - - AND a1, v2, #CT_ctype_mask - MOV a1, a1, LSR #CT_ctype_pos - STRB a1, [v6, #Cache_Type] - - [ No26bitCode - MOV v5, #CPUFlag_32bitOS - | - MOV v5, #0 - ] - - TST v2, #CT_S - ORRNE v5, v5, #CPUFlag_SplitCache+CPUFlag_SynchroniseCodeAreas - - [ CacheOff - ORR v5, v5, #CPUFlag_SynchroniseCodeAreas - | - ARM_read_control a1 ; if Z bit set then we have branch prediction, - TST a1, #MMUC_Z ; so we need OS_SynchroniseCodeAreas even if not - ORRNE v5, v5, #CPUFlag_SynchroniseCodeAreas ; split caches - ] - - ; Test abort timing (base restored or base updated) - MOV a1, #&8000 - LDR a2, [a1], #4 ; Will abort - DAb handler will continue execution - TEQ a1, #&8000 - ORREQ v5, v5, #CPUFlag_BaseRestored - - ; Check store of PC -30 STR pc, [sp, #-4]! - ADR a2, %BT30 + 8 - LDR a1, [sp], #4 - TEQ a1, a2 - ORREQ v5, v5, #CPUFlag_StorePCplus8 - - [ 0=1 - ; Check whether 26-bit mode is available - MSR CPSR_c, #F32_bit+I32_bit+SVC26_mode - MRS a1, CPSR - AND a1, a1, #M32_bits - TEQ a1, #SVC26_mode - ORRNE v5, v5, #CPUFlag_No26bitMode - MSREQ CPSR_c, #F32_bit+I32_bit+SVC32_mode - BNE %FT35 - - ; Do we get vector exceptions on read? - MOV a1, #0 - LDR a1, [a1] ; If this aborts a1 will be left unchanged - TEQ a1, #0 - ORREQ v5, v5, #CPUFlag_VectorReadException - ] -35 - - BL Init_ARMarch - STRB a1, [v6, #ProcessorArch] - - TEQ a1, #ARMv3 ; assume long multiply available - ORRNE v5, v5, #CPUFlag_LongMul ; if v4 or later - TEQNE a1, #ARMv4 ; assume 26-bit available - ORRNE v5, v5, #CPUFlag_No26bitMode ; iff v3 or v4 (not T) - TEQNE a1, #ARMv5 ; assume Thumb available - ORRNE v5, v5, #CPUFlag_Thumb ; iff not v3,v4,v5 - - MSR CPSR_f, #Q32_bit - MRS lr, CPSR - TST lr, #Q32_bit - ORRNE v5, v5, #CPUFlag_DSP - - LDRB v4, [v6, #ProcessorType] - - TEQ v4, #ARMunk ; Modify deduced flags - ADRNEL lr, KnownCPUFlags - ADDNE lr, lr, v4, LSL #3 - LDMNEIA lr, {a2, a3} - ORRNE v5, v5, a2 - BICNE v5, v5, a3 - - [ XScaleJTAGDebug - TST v5, #CPUFlag_XScale - BEQ %FT40 - - MRC p14, 0, a2, c10, c0 ; Read debug control register - TST a2, #&80000000 - ORRNE v5, v5, #CPUFlag_XScaleJTAGconnected - MOVEQ a2, #&C000001C ; enable hot debug - MCREQ p14, 0, a2, c10, c0 - BNE %FT40 -40 - ] - - STR v5, [v6, #ProcessorFlags] - - ; Now, a1 = processor architecture (ARMv3, ARMv4 ...) - ; v4 = processor type (ARM600, ARM610, ...) - ; v5 = processor flags - - CMP a1, #ARMv4 - BLO Analyse_ARMv3 ; eg. ARM710 - - LDRB a2, [v6, #Cache_Type] - TEQ a2, #CT_ctype_WT - TSTEQ v5, #CPUFlag_SplitCache - BEQ Analyse_WriteThroughUnified ; eg. ARM7TDMI derivative - - TEQ a2, #CT_ctype_WB_CR7_LDa - BEQ Analyse_WB_CR7_LDa ; eg. ARM9 - - TEQ a2, #CT_ctype_WB_Crd - BEQ Analyse_WB_Crd ; eg. StrongARM - - TEQ a2, #CT_ctype_WB_Cal_LD - BEQ Analyse_WB_Cal_LD ; assume XScale - - ; others ... - -WeirdARMPanic - B WeirdARMPanic ; stiff :) - -Analyse_ARMv3 - ADRL a1, NullOp - ADRL a2, Cache_Invalidate_ARMv3 - ADRL a3, WriteBuffer_Drain_ARMv3 - ADRL a4, TLB_Invalidate_ARMv3 - ADRL ip, TLB_InvalidateEntry_ARMv3 - - STR a1, [v6, #Proc_Cache_CleanAll] - STR a2, [v6, #Proc_Cache_CleanInvalidateAll] - STR a2, [v6, #Proc_Cache_InvalidateAll] - STR a3, [v6, #Proc_WriteBuffer_Drain] - STR a4, [v6, #Proc_TLB_InvalidateAll] - STR ip, [v6, #Proc_TLB_InvalidateEntry] - STR a1, [v6, #Proc_IMB_Full] - STR a1, [v6, #Proc_IMB_Range] - - ADRL a1, MMU_Changing_ARMv3 - ADRL a2, MMU_ChangingEntry_ARMv3 - ADRL a3, MMU_ChangingUncached_ARMv3 - ADRL a4, MMU_ChangingUncachedEntry_ARMv3 - STR a1, [v6, #Proc_MMU_Changing] - STR a2, [v6, #Proc_MMU_ChangingEntry] - STR a3, [v6, #Proc_MMU_ChangingUncached] - STR a4, [v6, #Proc_MMU_ChangingUncachedEntry] - - ADRL a1, MMU_ChangingEntries_ARMv3 - ADRL a2, MMU_ChangingUncachedEntries_ARMv3 - ADRL a3, Cache_RangeThreshold_ARMv3 - STR a1, [v6, #Proc_MMU_ChangingEntries] - STR a2, [v6, #Proc_MMU_ChangingUncachedEntries] - STR a3, [v6, #Proc_Cache_RangeThreshold] - - ADRL a1, XCBTableWT - STR a1, [v6, #MMU_PCBTrans] - B %FT90 - -Analyse_WriteThroughUnified - ADRL a1, NullOp - ADRL a2, Cache_InvalidateUnified - TST v5, #CPUFlag_NoWBDrain - ADRNEL a3, WriteBuffer_Drain_OffOn - ADREQL a3, WriteBuffer_Drain - ADRL a4, TLB_Invalidate_Unified - ADRL ip, TLB_InvalidateEntry_Unified - - STR a1, [v6, #Proc_Cache_CleanAll] - STR a2, [v6, #Proc_Cache_CleanInvalidateAll] - STR a2, [v6, #Proc_Cache_InvalidateAll] - STR a3, [v6, #Proc_WriteBuffer_Drain] - STR a4, [v6, #Proc_TLB_InvalidateAll] - STR ip, [v6, #Proc_TLB_InvalidateEntry] - STR a1, [v6, #Proc_IMB_Full] - STR a1, [v6, #Proc_IMB_Range] - - ADRL a1, MMU_Changing_Writethrough - ADRL a2, MMU_ChangingEntry_Writethrough - ADRL a3, MMU_ChangingUncached - ADRL a4, MMU_ChangingUncachedEntry - STR a1, [v6, #Proc_MMU_Changing] - STR a2, [v6, #Proc_MMU_ChangingEntry] - STR a3, [v6, #Proc_MMU_ChangingUncached] - STR a4, [v6, #Proc_MMU_ChangingUncachedEntry] - - ADRL a1, MMU_ChangingEntries_Writethrough - ADRL a2, MMU_ChangingUncachedEntries - ADRL a3, Cache_RangeThreshold_Writethrough - STR a1, [v6, #Proc_MMU_ChangingEntries] - STR a2, [v6, #Proc_MMU_ChangingUncachedEntries] - STR a3, [v6, #Proc_Cache_RangeThreshold] - - ADRL a1, XCBTableWT - STR a1, [v6, #MMU_PCBTrans] - B %FT90 - -Analyse_WB_CR7_LDa - TST v5, #CPUFlag_SplitCache - BEQ WeirdARMPanic ; currently, only support harvard caches here (eg. ARM920) - - ADRL a1, Cache_CleanInvalidateAll_WB_CR7_LDa - STR a1, [v6, #Proc_Cache_CleanInvalidateAll] - - ADRL a1, Cache_CleanAll_WB_CR7_LDa - STR a1, [v6, #Proc_Cache_CleanAll] - - ADRL a1, Cache_InvalidateAll_WB_CR7_LDa - STR a1, [v6, #Proc_Cache_InvalidateAll] - - ADRL a1, Cache_RangeThreshold_WB_CR7_LDa - STR a1, [v6, #Proc_Cache_RangeThreshold] - - ADRL a1, TLB_InvalidateAll_WB_CR7_LDa - STR a1, [v6, #Proc_TLB_InvalidateAll] - - ADRL a1, TLB_InvalidateEntry_WB_CR7_LDa - STR a1, [v6, #Proc_TLB_InvalidateEntry] - - ADRL a1, WriteBuffer_Drain_WB_CR7_LDa - STR a1, [v6, #Proc_WriteBuffer_Drain] - - ADRL a1, IMB_Full_WB_CR7_LDa - STR a1, [v6, #Proc_IMB_Full] - - ADRL a1, IMB_Range_WB_CR7_LDa - STR a1, [v6, #Proc_IMB_Range] - - ADRL a1, MMU_Changing_WB_CR7_LDa - STR a1, [v6, #Proc_MMU_Changing] - - ADRL a1, MMU_ChangingEntry_WB_CR7_LDa - STR a1, [v6, #Proc_MMU_ChangingEntry] - - ADRL a1, MMU_ChangingUncached_WB_CR7_LDa - STR a1, [v6, #Proc_MMU_ChangingUncached] - - ADRL a1, MMU_ChangingUncachedEntry_WB_CR7_LDa - STR a1, [v6, #Proc_MMU_ChangingUncachedEntry] - - ADRL a1, MMU_ChangingEntries_WB_CR7_LDa - STR a1, [v6, #Proc_MMU_ChangingEntries] - - ADRL a1, MMU_ChangingUncachedEntries_WB_CR7_LDa - STR a1, [v6, #Proc_MMU_ChangingUncachedEntries] - - MOV a1, #0 - LDRB a2, [a1, #DCache_Associativity] - - MOV a3, #256 - MOV a4, #8 ; to find log2(ASSOC), rounded up -Analyse_WB_CR7_LDa_L1 - MOV a3, a3, LSR #1 - SUB a4, a4, #1 - CMP a2, a3 - BLO Analyse_WB_CR7_LDa_L1 - ADDHI a4, a4, #1 - - RSB a2, a4, #32 - MOV a3, #1 - MOV a3, a3, LSL a2 - STR a3, [a1, #DCache_IndexBit] - LDR a4, [a1, #DCache_NSets] - LDRB a2, [a1, #DCache_LineLen] - SUB a4, a4, #1 - MUL a4, a2, a4 - STR a4, [a1, #DCache_IndexSegStart] - - MOV a2, #64*1024 ; arbitrary-ish - STR a2, [a1, #DCache_RangeThreshold] - - ADRL a1, XCBTableWBR ; assume read-allocate WB/WT cache - STR a1, [v6, #MMU_PCBTrans] - - B %FT90 - -Analyse_WB_Crd - TST v5, #CPUFlag_SplitCache - BEQ WeirdARMPanic ; currently, only support harvard - - ADRL a1, Cache_CleanInvalidateAll_WB_Crd - STR a1, [v6, #Proc_Cache_CleanInvalidateAll] - - ADRL a1, Cache_CleanAll_WB_Crd - STR a1, [v6, #Proc_Cache_CleanAll] - - ADRL a1, Cache_InvalidateAll_WB_Crd - STR a1, [v6, #Proc_Cache_InvalidateAll] - - ADRL a1, Cache_RangeThreshold_WB_Crd - STR a1, [v6, #Proc_Cache_RangeThreshold] - - ADRL a1, TLB_InvalidateAll_WB_Crd - STR a1, [v6, #Proc_TLB_InvalidateAll] - - ADRL a1, TLB_InvalidateEntry_WB_Crd - STR a1, [v6, #Proc_TLB_InvalidateEntry] - - ADRL a1, WriteBuffer_Drain_WB_Crd - STR a1, [v6, #Proc_WriteBuffer_Drain] - - ADRL a1, IMB_Full_WB_Crd - STR a1, [v6, #Proc_IMB_Full] - - ADRL a1, IMB_Range_WB_Crd - STR a1, [v6, #Proc_IMB_Range] - - ADRL a1, MMU_Changing_WB_Crd - STR a1, [v6, #Proc_MMU_Changing] - - ADRL a1, MMU_ChangingEntry_WB_Crd - STR a1, [v6, #Proc_MMU_ChangingEntry] - - ADRL a1, MMU_ChangingUncached_WB_Crd - STR a1, [v6, #Proc_MMU_ChangingUncached] - - ADRL a1, MMU_ChangingUncachedEntry_WB_Crd - STR a1, [v6, #Proc_MMU_ChangingUncachedEntry] - - ADRL a1, MMU_ChangingEntries_WB_Crd - STR a1, [v6, #Proc_MMU_ChangingEntries] - - ADRL a1, MMU_ChangingUncachedEntries_WB_Crd - STR a1, [v6, #Proc_MMU_ChangingUncachedEntries] - - MOV a1, #0 - LDR a2, =DCacheCleanAddress - STR a2, [a1, #DCache_CleanBaseAddress] - STR a2, [a1, #DCache_CleanNextAddress] - MOV a2, #64*1024 ;arbitrary-ish threshold - STR a2, [a1, #DCache_RangeThreshold] - - LDRB a2, [a1, #ProcessorType] - TEQ a2, #SA110 - ADREQL a2, XCBTableSA110 - BEQ Analyse_WB_Crd_finish - TEQ a2, #SA1100 - TEQNE a2, #SA1110 - ADREQL a2, XCBTableSA1110 - ADRNEL a2, XCBTableWBR -Analyse_WB_Crd_finish - STR a2, [a1, #MMU_PCBTrans] - B %FT90 - -Analyse_WB_Cal_LD - TST v5, #CPUFlag_SplitCache - BEQ WeirdARMPanic ; currently, only support harvard - - ADRL a1, Cache_CleanInvalidateAll_WB_Cal_LD - STR a1, [v6, #Proc_Cache_CleanInvalidateAll] - - ADRL a1, Cache_CleanAll_WB_Cal_LD - STR a1, [v6, #Proc_Cache_CleanAll] - - ADRL a1, Cache_InvalidateAll_WB_Cal_LD - STR a1, [v6, #Proc_Cache_InvalidateAll] - - ADRL a1, Cache_RangeThreshold_WB_Cal_LD - STR a1, [v6, #Proc_Cache_RangeThreshold] - - ADRL a1, TLB_InvalidateAll_WB_Cal_LD - STR a1, [v6, #Proc_TLB_InvalidateAll] - - ADRL a1, TLB_InvalidateEntry_WB_Cal_LD - STR a1, [v6, #Proc_TLB_InvalidateEntry] - - ADRL a1, WriteBuffer_Drain_WB_Cal_LD - STR a1, [v6, #Proc_WriteBuffer_Drain] - - ADRL a1, IMB_Full_WB_Cal_LD - STR a1, [v6, #Proc_IMB_Full] - - ADRL a1, IMB_Range_WB_Cal_LD - STR a1, [v6, #Proc_IMB_Range] - - ADRL a1, MMU_Changing_WB_Cal_LD - STR a1, [v6, #Proc_MMU_Changing] - - ADRL a1, MMU_ChangingEntry_WB_Cal_LD - STR a1, [v6, #Proc_MMU_ChangingEntry] - - ADRL a1, MMU_ChangingUncached_WB_Cal_LD - STR a1, [v6, #Proc_MMU_ChangingUncached] - - ADRL a1, MMU_ChangingUncachedEntry_WB_Cal_LD - STR a1, [v6, #Proc_MMU_ChangingUncachedEntry] - - ADRL a1, MMU_ChangingEntries_WB_Cal_LD - STR a1, [v6, #Proc_MMU_ChangingEntries] - - ADRL a1, MMU_ChangingUncachedEntries_WB_Cal_LD - STR a1, [v6, #Proc_MMU_ChangingUncachedEntries] - - MOV a1, #0 - LDR a2, =DCacheCleanAddress - STR a2, [a1, #DCache_CleanBaseAddress] - STR a2, [a1, #DCache_CleanNextAddress] - - [ XScaleMiniCache - ! 1, "You need to arrange for XScale mini-cache clean area to be mini-cacheable" - LDR a2, =DCacheCleanAddress + 4 * 32*1024 - STR a2, [a1, #MCache_CleanBaseAddress] - STR a2, [a1, #MCache_CleanNextAddress] - ] - - - ; arbitrary-ish values, mini cache makes global op significantly more expensive - [ XScaleMiniCache - MOV a2, #128*1024 - | - MOV a2, #32*1024 - ] - STR a2, [a1, #DCache_RangeThreshold] - - ; enable full coprocessor access - LDR a2, =&3FFF - MCR p15, 0, a2, c15, c1 - - ADRL a2, XCBTableXScaleWA ; choose between RA and WA here - STR a2, [a1, #MMU_PCBTrans] - - B %FT90 - -90 - Pull "v1,v2,v5,v6,v7,pc" - - -; This routine works out the values LINELEN, ASSOCIATIVITY, NSETS and CACHE_SIZE defined in section -; B2.3.3 of the ARMv5 ARM. -EvaluateCache - AND a3, a1, #CT_assoc_mask+CT_M - TEQ a3, #(CT_assoc_0:SHL:CT_assoc_pos)+CT_M - BEQ %FT80 - MOV ip, #1 - ASSERT CT_len_pos = 0 - AND a4, a1, #CT_len_mask - ADD a4, a4, #3 - MOV a4, ip, LSL a4 ; LineLen = 1 << (len+3) - STRB a4, [a2, #ICache_LineLen-ICache_Info] - MOV a3, #2 - TST a1, #CT_M - ADDNE a3, a3, #1 ; Multiplier = 2 + M - AND a4, a1, #CT_assoc_mask - RSB a4, ip, a4, LSR #CT_assoc_pos - MOV a4, a3, LSL a4 ; Associativity = Multiplier << (assoc-1) - STRB a4, [a2, #ICache_Associativity-ICache_Info] - AND a4, a1, #CT_size_mask - MOV a4, a4, LSR #CT_size_pos - MOV a3, a3, LSL a4 - MOV a3, a3, LSL #8 ; Size = Multiplier << (size+8) - STR a3, [a2, #ICache_Size-ICache_Info] - ADD a4, a4, #6 - AND a3, a1, #CT_assoc_mask - SUB a4, a4, a3, LSR #CT_assoc_pos - AND a3, a1, #CT_len_mask - ASSERT CT_len_pos = 0 - SUB a4, a4, a3 - MOV a4, ip, LSL a4 ; NSets = 1 << (size + 6 - assoc - len) - STR a4, [a2, #ICache_NSets-ICache_Info] - MOV pc, lr - - -80 MOV a1, #0 - STR a1, [a2, #ICache_NSets-ICache_Info] - STR a1, [a2, #ICache_Size-ICache_Info] - STRB a1, [a2, #ICache_LineLen-ICache_Info] - STRB a1, [a2, #ICache_Associativity-ICache_Info] - MOV pc, lr - - -; Create a list of CPUs, 16 bytes per entry: -; ID bits (1 word) -; Test mask for ID (1 word) -; Cache type register value (1 word) -; Processor type (1 byte) -; Architecture type (1 byte) -; Reserved (2 bytes) - GBLA tempcpu - - MACRO - CPUDesc $proc, $id, $mask, $arch, $type, $s, $dsz, $das, $dln, $isz, $ias, $iln - LCLA type -type SETA (CT_ctype_$type:SHL:CT_ctype_pos)+($s:SHL:CT_S_pos) -tempcpu CSzDesc $dsz, $das, $dln -type SETA type+(tempcpu:SHL:CT_Dsize_pos) - [ :LNOT:($s=0 :LAND: "$isz"="") -tempcpu CSzDesc $isz, $ias, $iln - ] -type SETA type+(tempcpu:SHL:CT_Isize_pos) - ASSERT ($id :AND: :NOT: $mask) = 0 - DCD $id, $mask, type - DCB $proc, $arch, 0, 0 - MEND - - MACRO -$var CSzDesc $sz, $as, $ln -$var SETA (CT_size_$sz:SHL:CT_size_pos)+(CT_assoc_$as:SHL:CT_assoc_pos)+(CT_len_$ln:SHL:CT_len_pos) -$var SETA $var+(CT_M_$sz:SHL:CT_M_pos) - MEND - - -KnownCPUTable -; /------Cache Type register fields-----\ -; ID reg Mask Arch Type S Dsz Das Dln Isz Ias Iln - CPUDesc ARM600, &000600, &00FFF0, ARMv3, WT, 0, 4K, 64, 4 - CPUDesc ARM610, &000610, &00FFF0, ARMv3, WT, 0, 4K, 64, 4 - CPUDesc ARMunk, &000000, &00F000, ARMv3, WT, 0, 4K, 64, 4 - CPUDesc ARM700, &007000, &FFFFF0, ARMv3, WT, 0, 8K, 4, 8 - CPUDesc ARM710, &007100, &FFFFF0, ARMv3, WT, 0, 8K, 4, 8 - CPUDesc ARM710a, &047100, &FDFFF0, ARMv3, WT, 0, 8K, 4, 4 - CPUDesc ARM7500, &067100, &FFFFF0, ARMv3, WT, 0, 4K, 4, 4 - CPUDesc ARM7500FE, &077100, &FFFFF0, ARMv3, WT, 0, 4K, 4, 4 - CPUDesc ARMunk, &007000, &80F000, ARMv3, WT, 0, 8K, 4, 4 - CPUDesc ARM720T, &807200, &FFFFF0, ARMv4T, WT, 0, 8K, 4, 4 - CPUDesc ARMunk, &807000, &80F000, ARMv4T, WT, 0, 8K, 4, 4 - CPUDesc SA110_preRevT, &01A100, &0FFFFC, ARMv4, WB_Crd, 1, 16K, 32, 8, 16K, 32, 8 - CPUDesc SA110, &01A100, &0FFFF0, ARMv4, WB_Crd, 1, 16K, 32, 8, 16K, 32, 8 - CPUDesc SA1100, &01A110, &0FFFF0, ARMv4, WB_Crd, 1, 8K, 32, 8, 16K, 32, 8 - CPUDesc SA1110, &01B110, &0FFFF0, ARMv4, WB_Crd, 1, 8K, 32, 8, 16K, 32, 8 - CPUDesc ARM920T, &029200, &0FFFF0, ARMv4T, WB_CR7_LDa, 1, 16K, 64, 8, 16K, 64, 8 - CPUDesc ARM922T, &029220, &0FFFF0, ARMv4T, WB_CR7_LDa, 1, 8K, 64, 8, 8K, 64, 8 - CPUDesc X80200, &052000, &0FFFF0, ARMv5TE, WB_Cal_LD, 1, 32K, 32, 8, 32K, 32, 8 - CPUDesc X80321, &69052400, &FFFFF700, ARMv5TE, WB_Cal_LD, 1, 32K, 32, 8, 32K, 32, 8 - DCD -1 - - -; Peculiar characteristics of individual ARMs not deducable otherwise. First field is -; flags to set, second flags to clear. -KnownCPUFlags - DCD 0, 0 ; ARM 600 - DCD 0, 0 ; ARM 610 - DCD 0, 0 ; ARM 700 - DCD 0, 0 ; ARM 710 - DCD 0, 0 ; ARM 710a - DCD CPUFlag_AbortRestartBroken+CPUFlag_InterruptDelay, 0 ; SA 110 pre revT - DCD CPUFlag_InterruptDelay, 0 ; SA 110 revT or later - DCD 0, 0 ; ARM 7500 - DCD 0, 0 ; ARM 7500FE - DCD CPUFlag_InterruptDelay, 0 ; SA 1100 - DCD CPUFlag_InterruptDelay, 0 ; SA 1110 - DCD CPUFlag_NoWBDrain, 0 ; ARM 720T - DCD 0, 0 ; ARM 920T - DCD 0, 0 ; ARM 922T - DCD CPUFlag_ExtendedPages+CPUFlag_XScale, 0 ; X80200 - DCD CPUFlag_XScale, 0 ; X80321 - -; -------------------------------------------------------------------------- -; ----- ARMops ------------------------------------------------------------- -; -------------------------------------------------------------------------- -; -; ARMops are the routines required by the kernel for cache/MMU control -; the kernel vectors to the appropriate ops for the given ARM at boot -; -; The Rules: -; - These routines may corrupt a1 and lr only -; - (lr can of course only be corrupted whilst still returning to correct -; link address) -; - stack is available, at least 16 words can be stacked -; - a NULL op would be a simple MOV pc, lr -; - -; -------------------------------------------------------------------------- -; ----- ARMops for ARMv3 --------------------------------------------------- -; -------------------------------------------------------------------------- -; -; ARMv3 ARMs include ARM710, ARM610, ARM7500 -; - -Cache_Invalidate_ARMv3 - MCR p15, 0, a1, c7, c0 -NullOp MOV pc, lr - -WriteBuffer_Drain_ARMv3 - ;swap always forces unbuffered write, stalling till WB empty - SUB sp, sp, #4 - SWP a1, a1, [sp] - ADD sp, sp, #4 - MOV pc, lr - -TLB_Invalidate_ARMv3 - MCR p15, 0, a1, c5, c0 - MOV pc, lr - -; a1 = page entry to invalidate (page aligned address) -; -TLB_InvalidateEntry_ARMv3 - MCR p15, 0, a1, c6, c0 - MOV pc, lr - -MMU_Changing_ARMv3 - MCR p15, 0, a1, c7, c0 ; invalidate cache - MCR p15, 0, a1, c5, c0 ; invalidate TLB - MOV pc, lr - -MMU_ChangingUncached_ARMv3 - MCR p15, 0, a1, c5, c0 ; invalidate TLB - MOV pc, lr - -; a1 = page affected (page aligned address) -; -MMU_ChangingEntry_ARMv3 - MCR p15, 0, a1, c7, c0 ; invalidate cache - MCR p15, 0, a1, c6, c0 ; invalidate TLB entry - MOV pc, lr - -; a1 = first page affected (page aligned address) -; a2 = number of pages -; -MMU_ChangingEntries_ARMv3 ROUT - CMP a2, #16 ; arbitrary-ish threshold - BHS MMU_Changing_ARMv3 - Push "a2" - MCR p15, 0, a1, c7, c0 ; invalidate cache -10 - MCR p15, 0, a1, c6, c0 ; invalidate TLB entry - SUBS a2, a2, #1 ; next page - ADD a1, a1, #PageSize - BNE %BT10 - Pull "a2" - MOV pc, lr - -; a1 = page affected (page aligned address) -; -MMU_ChangingUncachedEntry_ARMv3 - MCR p15, 0, a1, c6, c0 ; invalidate TLB entry - MOV pc, lr - -; a1 = first page affected (page aligned address) -; a2 = number of pages -; -MMU_ChangingUncachedEntries_ARMv3 ROUT - CMP a2, #16 ; arbitrary-ish threshold - BHS MMU_ChangingUncached_ARMv3 - Push "a2" -10 - MCR p15, 0, a1, c6, c0 ; invalidate TLB entry - SUBS a2, a2, #1 ; next page - ADD a1, a1, #PageSize - BNE %BT10 - Pull "a2" - MOV pc, lr - -Cache_RangeThreshold_ARMv3 - ! 0, "arbitrary Cache_RangeThreshold_ARMv3" - MOV a1, #16*PageSize - MOV pc, lr - -; -------------------------------------------------------------------------- -; ----- generic ARMops for simple ARMs, ARMv4 onwards ---------------------- -; -------------------------------------------------------------------------- -; -; eg. ARM7TDMI based ARMs, unified, writethrough cache -; - -Cache_InvalidateUnified - MOV a1, #0 - MCR p15, 0, a1, c7, c7 - MOV pc, lr - -WriteBuffer_Drain_OffOn - ; used if ARM has no drain WBuffer MCR op - Push "a2" - ARM_read_control a1 - BIC a2, a1, #MMUC_W - ARM_write_control a2 - ARM_write_control a1 - Pull "a2" - MOV pc, lr - -WriteBuffer_Drain - ; used if ARM has proper drain WBuffer MCR op - MOV a1, #0 - MCR p15, 0, a1, c7, c10, 4 - MOV pc, lr - -TLB_Invalidate_Unified - MOV a1, #0 - MCR p15, 0, a1, c8, c7 - MOV pc, lr - -; a1 = page entry to invalidate (page aligned address) -; -TLB_InvalidateEntry_Unified - MCR p15, 0, a1, c8, c7, 1 - MOV pc, lr - -MMU_Changing_Writethrough - MOV a1, #0 - MCR p15, 0, a1, c7, c7 ; invalidate cache - MCR p15, 0, a1, c8, c7 ; invalidate TLB - MOV pc, lr - -MMU_ChangingUncached - MOV a1, #0 - MCR p15, 0, a1, c8, c7 ; invalidate TLB - MOV pc, lr - -; a1 = page affected (page aligned address) -; -MMU_ChangingEntry_Writethrough - Push "a4" - MOV a4, #0 - MCR p15, 0, a4, c7, c7 ; invalidate cache - MCR p15, 0, a1, c8, c7, 1 ; invalidate TLB entry - Pull "a4" - MOV pc, lr - -; a1 = first page affected (page aligned address) -; a2 = number of pages -; -MMU_ChangingEntries_Writethrough ROUT - CMP a2, #16 ; arbitrary-ish threshold - BHS MMU_Changing_Writethrough - Push "a2,a4" - MOV a4, #0 - MCR p15, 0, a4, c7, c7 ; invalidate cache -10 - MCR p15, 0, a1, c8, c7, 1 ; invalidate TLB entry - SUBS a2, a2, #1 ; next page - ADD a1, a1, #PageSize - BNE %BT10 - Pull "a2,a4" - MOV pc, lr - -; a1 = page affected (page aligned address) -; -MMU_ChangingUncachedEntry - MCR p15, 0, a1, c8, c7, 1 ; invalidate TLB entry - MOV pc, lr - -; a1 = first page affected (page aligned address) -; a2 = number of pages -; -MMU_ChangingUncachedEntries ROUT - CMP a2, #16 ; arbitrary-ish threshold - BHS MMU_ChangingUncached - Push "a2" -10 - MCR p15, 0, a1, c8, c7, 1 ; invalidate TLB entry - SUBS a2, a2, #1 ; next page - ADD a1, a1, #PageSize - BNE %BT10 - Pull "a2" - MOV pc, lr - -Cache_RangeThreshold_Writethrough - ! 0, "arbitrary Cache_RangeThreshold_Writethrough" - MOV a1, #16*PageSize - MOV pc, lr - -; -------------------------------------------------------------------------- -; ----- ARMops for ARM9 and the like --------------------------------------- -; -------------------------------------------------------------------------- - -; WB_CR7_LDa refers to ARMs with writeback data cache, cleaned with -; register 7, lockdown available (format A) -; -; Note that ARM920 etc have writeback/writethrough data cache selectable -; by MMU regions. For simpliciity, we assume cacheable pages are mostly -; writeback. Any writethrough pages will have redundant clean operations -; applied when moved, for example, but this is a small overhead (cleaning -; a clean line is very quick on ARM 9). - -Cache_CleanAll_WB_CR7_LDa ROUT -; -; only guarantees to clean lines not involved in interrupts (so we can -; clean without disabling interrupts) -; -; Clean cache by traversing all segment and index values -; As a concrete example, for ARM 920 (16k+16k caches) we would have: -; -; DCache_LineLen = 32 (32 byte cache line, segment field starts at bit 5) -; DCache_IndexBit = &04000000 (index field starts at bit 26) -; DCache_IndexSegStart = &000000E0 (start at index=0, segment = 7) -; - Push "a2, ip" - MOV ip, #0 - LDRB a1, [ip, #DCache_LineLen] ; segment field starts at this bit - LDR a2, [ip, #DCache_IndexBit] ; index field starts at this bit - LDR ip, [ip, #DCache_IndexSegStart] ; starting value, with index at min, seg at max -10 - MCR p15, 0, ip, c7, c10, 2 ; clean DCache entry by segment/index - ADDS ip, ip, a2 ; next index, counting up, CS if wrapped back to 0 - BCC %BT10 - SUBS ip, ip, a1 ; next segment, counting down, CC if wrapped back to max - BCS %BT10 ; if segment wrapped, then we've finished - MOV ip, #0 - MCR p15, 0, ip, c7, c10, 4 ; drain WBuffer - Pull "a2, ip" - MOV pc, lr - - -Cache_CleanInvalidateAll_WB_CR7_LDa ROUT -; -; similar to Cache_CleanAll, but does clean&invalidate of Dcache, and invalidates ICache -; - Push "a2, ip" - MOV ip, #0 - LDRB a1, [ip, #DCache_LineLen] ; segment field starts at this bit - LDR a2, [ip, #DCache_IndexBit] ; index field starts at this bit - LDR ip, [ip, #DCache_IndexSegStart] ; starting value, with index at min, seg at max -10 - MCR p15, 0, ip, c7, c14, 2 ; clean&invalidate DCache entry by segment/index - ADDS ip, ip, a2 ; next index, counting up, CS if wrapped back to 0 - BCC %BT10 - SUBS ip, ip, a1 ; next segment, counting down, CC if wrapped back to max - BCS %BT10 ; if segment wrapped, then we've finished - MOV ip, #0 - MCR p15, 0, ip, c7, c10, 4 ; drain WBuffer - MCR p15, 0, ip, c7, c5, 0 ; invalidate ICache - Pull "a2, ip" - MOV pc, lr - - -Cache_InvalidateAll_WB_CR7_LDa ROUT -; -; no clean, assume caller knows what's happening -; - MOV a1, #0 - MCR p15, 0, a1, c7, c7, 0 ; invalidate ICache and DCache - MOV pc, lr - - -Cache_RangeThreshold_WB_CR7_LDa ROUT - MOV a1, #0 - LDR a1, [a1, #DCache_RangeThreshold] - MOV pc, lr - - -TLB_InvalidateAll_WB_CR7_LDa ROUT -MMU_ChangingUncached_WB_CR7_LDa - MOV a1, #0 - MCR p15, 0, a1, c8, c7, 0 ; invalidate ITLB and DTLB - MOV pc, lr - - -; a1 = page affected (page aligned address) -; -TLB_InvalidateEntry_WB_CR7_LDa ROUT -MMU_ChangingUncachedEntry_WB_CR7_LDa - MCR p15, 0, a1, c8, c5, 1 ; invalidate ITLB entry - MCR p15, 0, a1, c8, c6, 1 ; invalidate DTLB entry - MOV pc, lr - - -WriteBuffer_Drain_WB_CR7_LDa ROUT - MOV a1, #0 - MCR p15, 0, a1, c7, c10, 4 ; drain WBuffer - MOV pc, lr - - -IMB_Full_WB_CR7_LDa ROUT -; -; do: clean DCache; drain WBuffer, invalidate ICache -; - Push "lr" - BL Cache_CleanAll_WB_CR7_LDa ; also drains Wbuffer - MOV a1, #0 - MCR p15, 0, a1, c7, c5, 0 ; invalidate ICache - Pull "pc" - -; a1 = start address (inclusive, cache line aligned) -; a2 = end address (exclusive, cache line aligned) -; -IMB_Range_WB_CR7_LDa ROUT - SUB a2, a2, a1 - CMP a2, #32*1024 ; arbitrary-ish range threshold - ADD a2, a2, a1 - BHS IMB_Full_WB_CR7_LDa - Push "lr" - MOV lr, #0 - LDRB lr, [lr, #DCache_LineLen] -10 - MCR p15, 0, a1, c7, c10, 1 ; clean DCache entry by VA - MCR p15, 0, a1, c7, c5, 1 ; invalidate ICache entry - ADD a1, a1, lr - CMP a1, a2 - BLO %BT10 - MOV a1, #0 - MCR p15, 0, a1, c7, c10, 4 ; drain WBuffer - Pull "pc" - -MMU_Changing_WB_CR7_LDa ROUT - Push "lr" - BL Cache_CleanInvalidateAll_WB_CR7_LDa - MOV a1, #0 - MCR p15, 0, a1, c8, c7, 0 ; invalidate ITLB and DTLB - Pull "pc" - -; a1 = page affected (page aligned address) -; -MMU_ChangingEntry_WB_CR7_LDa ROUT - Push "a2, lr" - ADD a2, a1, #PageSize - MOV lr, #0 - LDRB lr, [lr, #DCache_LineLen] -10 - MCR p15, 0, a1, c7, c14, 1 ; clean&invalidate DCache entry - MCR p15, 0, a1, c7, c5, 1 ; invalidate ICache entry - ADD a1, a1, lr - CMP a1, a2 - BLO %BT10 - MOV lr, #0 - MCR p15, 0, lr, c7, c10, 4 ; drain WBuffer - SUB a1, a1, #PageSize - MCR p15, 0, a1, c8, c6, 1 ; invalidate DTLB entry - MCR p15, 0, a1, c8, c5, 1 ; invalidate ITLB entry - Pull "a2, pc" - -; a1 = first page affected (page aligned address) -; a2 = number of pages -; -MMU_ChangingEntries_WB_CR7_LDa ROUT - Push "a2, a3, lr" - MOV a2, a2, LSL #Log2PageSize - MOV a3, #0 - LDR a3, [a3, #DCache_RangeThreshold] ;check whether cheaper to do global clean - CMP a2, a3 - BHS %FT30 - ADD a2, a2, a1 ;clean end address (exclusive) - MOV a3, #0 - LDRB a3, [a3, #DCache_LineLen] - MOV lr, a1 -10 - MCR p15, 0, a1, c7, c14, 1 ; clean&invalidate DCache entry - MCR p15, 0, a1, c7, c5, 1 ; invalidate ICache entry - ADD a1, a1, a3 - CMP a1, a2 - BLO %BT10 - MOV a1, #0 - MCR p15, 0, a1, c7, c10, 4 ; drain WBuffer - MOV a1, lr ; restore start address -20 - MCR p15, 0, a1, c8, c6, 1 ; invalidate DTLB entry - MCR p15, 0, a1, c8, c5, 1 ; invalidate ITLB entry - ADD a1, a1, #PageSize - CMP a1, a2 - BLO %BT20 - Pull "a2, a3, pc" -; -30 - BL Cache_CleanInvalidateAll_WB_CR7_LDa - MOV a1, #0 - MCR p15, 0, a1, c8, c7, 0 ; invalidate ITLB and DTLB - Pull "a2, a3, pc" - -; a1 = first page affected (page aligned address) -; a2 = number of pages -; -MMU_ChangingUncachedEntries_WB_CR7_LDa ROUT - CMP a2, #32 ; arbitrary-ish threshold - BHS %FT20 - Push "a2" -10 - MCR p15, 0, a1, c8, c6, 1 ; invalidate DTLB entry - MCR p15, 0, a1, c8, c5, 1 ; invalidate ITLB entry - ADD a1, a1, #PageSize - SUBS a2, a2, #1 - BNE %BT10 - Pull "a2" - MOV pc, lr -; -20 - MCR p15, 0, a1, c8, c7, 0 ; invalidate ITLB and DTLB - MOV pc, lr - - -; -------------------------------------------------------------------------- -; ----- ARMops for StrongARM and the like ---------------------------------- -; -------------------------------------------------------------------------- - -; WB_Crd is Writeback data cache, clean by reading data from cleaner area - -; Currently no support for mini data cache on some StrongARM variants. Mini -; cache is always writeback and must have cleaning support, so is very -; awkward to use for cacheable screen, say. - -; Global cache cleaning requires address space for private cleaner areas (not accessed -; for any other reason). Cleaning is normally with interrupts enabled (to avoid a latency -; hit), which means that the cleaner data is not invalidated afterwards. This is fine for -; RISC OS - where the private area is not used for anything else, and any re-use of the -; cache under interrupts is safe (eg. a page being moved is *never* involved in any -; active interrupts). - -; Mostly, cleaning toggles between two separate cache-sized areas, which gives minimum -; cleaning cost while guaranteeing proper clean even if previous clean data is present. If -; the clean routine is re-entered, an independent, double sized clean is initiated. This -; guarantees proper cleaning (regardless of multiple re-entrancy) whilst hardly complicating -; the routine at all. The overhead is small, since by far the most common cleaning will be -; non-re-entered. The upshot is that the cleaner address space available must be at least 4 -; times the cache size: -; 1 : used alternately, on 1st, 3rd, ... non-re-entered cleans -; 2 : used alternately, on 2nd, 4th, ... non-re-entered cleans -; 3 : used only for first half of a re-entered clean -; 4 : used only for second half of a re-entered clean -; -; DCache_CleanBaseAddress : start address of total cleaner space -; DCache_CleanNextAddress : start address for next non-re-entered clean, or 0 if re-entered - - -Cache_CleanAll_WB_Crd ROUT -; -; - cleans data cache (and invalidates it as a side effect) -; - can be used with interrupts enabled (to avoid latency over time of clean) -; - can be re-entered -; - see remarks at top of StrongARM ops for discussion of strategy -; - - Push "a2-a4, v1, v2, lr" - MOV lr, #0 - LDR a1, [lr, #DCache_CleanBaseAddress] - LDR a2, =DCache_CleanNextAddress - LDR a3, [lr, #DCache_Size] - LDRB a4, [lr, #DCache_LineLen] - MOV v2, #0 - SWP v1, v2, [a2] ; read current CleanNextAddr, zero it (semaphore) - TEQ v1, #0 ; but if it is already zero, we have re-entered - ADDEQ v1, a1, a3, LSL #1 ; if re-entered, start clean at Base+2*Cache_Size - ADDEQ v2, v1, a3, LSL #1 ; if re-entered, do a clean of 2*Cache_Size - ADDNE v2, v1, a3 ; if not re-entered, do a clean of Cache_Size -10 - LDR lr, [v1], a4 - TEQ v1, v2 - BNE %BT10 - ADD v2, a1, a3, LSL #1 ; compare end address with Base+2*Cache_Size - CMP v1, v2 - MOVEQ v1, a1 ; if equal, not re-entered and Next wraps back - STRLS v1, [a2] ; if lower or same, not re-entered, so update Next - MCR p15, 0, a1, c7, c10, 4 ; drain WBuffer - Pull "a2-a4, v1, v2, pc" - - -Cache_CleanInvalidateAll_WB_Crd ROUT -IMB_Full_WB_Crd -; -;does not truly invalidate DCache, but effectively invalidates (flushes) all lines not -;involved in interrupts - this is sufficient for OS requirements, and means we don't -;have to disable interrupts for possibly slow clean -; - Push "lr" - BL Cache_CleanAll_WB_Crd ;clean DCache (wrt to non-interrupt stuff) - MCR p15, 0, a1, c7, c5, 0 ;flush ICache - Pull "pc" - -Cache_InvalidateAll_WB_Crd -; -; no clean, assume caller knows what is happening -; - MCR p15, 0, a1, c7, c7, 0 ;flush ICache and DCache - MCR p15, 0, a1, c7, c10, 4 ;drain WBuffer - MOV pc, lr - -Cache_RangeThreshold_WB_Crd - MOV a1, #0 - LDR a1, [a1, #DCache_RangeThreshold] - MOV pc, lr - -TLB_InvalidateAll_WB_Crd -MMU_ChangingUncached_WB_Crd - MCR p15, 0, a1, c8, c7, 0 ;flush ITLB and DTLB - MOV pc, lr - -TLB_InvalidateEntry_WB_Crd -MMU_ChangingUncachedEntry_WB_Crd - MCR p15, 0, a1, c8, c6, 1 ;flush DTLB entry - MCR p15, 0, a1, c8, c5, 0 ;flush ITLB - MOV pc, lr - -WriteBuffer_Drain_WB_Crd - MCR p15, 0, a1, c7, c10, 4 ;drain WBuffer - MOV pc, lr - - -IMB_Range_WB_Crd ROUT - SUB a2, a2, a1 - CMP a2, #64*1024 ;arbitrary-ish range threshold - ADD a2, a2, a1 - BHS IMB_Full_WB_Crd - Push "lr" - MOV lr, #0 - LDRB lr, [lr, #DCache_LineLen] -10 - MCR p15, 0, a1, c7, c10, 1 ;clean DCache entry - ADD a1, a1, lr - CMP a1, a2 - BLO %BT10 - MCR p15, 0, a1, c7, c10, 4 ;drain WBuffer - MCR p15, 0, a1, c7, c5, 0 ;flush ICache - Pull "pc" - -MMU_Changing_WB_Crd - Push "lr" - BL Cache_CleanAll_WB_Crd ;clean DCache (wrt to non-interrupt stuff) - MCR p15, 0, a1, c7, c5, 0 ;flush ICache - MCR p15, 0, a1, c8, c7, 0 ;flush ITLB and DTLB - Pull "pc" - -MMU_ChangingEntry_WB_Crd ROUT -; -;there is no clean&invalidate DCache instruction, however we can do clean -;entry followed by invalidate entry without an interrupt hole, because they -;are for the same virtual address (and that virtual address will not be -;involved in interrupts, since it is involved in remapping) -; - Push "a2, lr" - ADD a2, a1, #PageSize - MOV lr, #0 - LDRB lr, [lr, #DCache_LineLen] -10 - MCR p15, 0, a1, c7, c10, 1 ;clean DCache entry - MCR p15, 0, a1, c7, c6, 1 ;flush DCache entry - ADD a1, a1, lr - CMP a1, a2 - BLO %BT10 - SUB a1, a1, #PageSize - MCR p15, 0, a1, c7, c10, 4 ;drain WBuffer - MCR p15, 0, a1, c7, c5, 0 ;flush ICache - MCR p15, 0, a1, c8, c6, 1 ;flush DTLB entry - MCR p15, 0, a1, c8, c5, 0 ;flush ITLB - Pull "a2, pc" - -MMU_ChangingEntries_WB_Crd ROUT -; -;same comments as MMU_ChangingEntry_WB_Crd -; - Push "a2, a3, lr" - MOV a2, a2, LSL #Log2PageSize - MOV a3, #0 - LDR a3, [a3, #DCache_RangeThreshold] ;check whether cheaper to do global clean - CMP a2, a3 - BHS %FT30 - ADD a2, a2, a1 ;clean end address (exclusive) - MOV a3, #0 - LDRB a3, [a3, #DCache_LineLen] - MOV lr, a1 -10 - MCR p15, 0, a1, c7, c10, 1 ;clean DCache entry - MCR p15, 0, a1, c7, c6, 1 ;flush DCache entry - ADD a1, a1, a3 - CMP a1, a2 - BLO %BT10 - MCR p15, 0, a1, c7, c10, 4 ;drain WBuffer - MCR p15, 0, a1, c7, c5, 0 ;flush ICache - MOV a1, lr ;restore start address -20 - MCR p15, 0, a1, c8, c6, 1 ;flush DTLB entry - ADD a1, a1, #PageSize - CMP a1, a2 - BLO %BT20 - MCR p15, 0, a1, c8, c5, 0 ;flush ITLB - Pull "a2, a3, pc" -; -30 - BL Cache_CleanAll_WB_Crd ;clean DCache (wrt to non-interrupt stuff) - MCR p15, 0, a1, c7, c5, 0 ;flush ICache - MCR p15, 0, a1, c8, c7, 0 ;flush ITLB and DTLB - Pull "a2, a3, pc" - -MMU_ChangingUncachedEntries_WB_Crd ROUT - CMP a2, #32 ;arbitrary-ish threshold - BHS %FT20 - Push "lr" - MOV lr, a2 -10 - MCR p15, 0, a1, c8, c6, 1 ;flush DTLB entry - ADD a1, a1, #PageSize - SUBS lr, lr, #1 - BNE %BT10 - MCR p15, 0, a1, c8, c5, 0 ;flush ITLB - Pull "pc" -; -20 - MCR p15, 0, a1, c8, c7, 0 ;flush ITLB and DTLB - MOV pc, lr - - -; ARMops for XScale, mjs Feb 2001 -; -; WB_Cal_LD is writeback, clean with allocate, lockdown -; -; If the mini data cache is used (XScaleMiniCache true), it is assumed to be -; configured writethrough (eg. used for RISC OS screen memory). This saves an ugly/slow -; mini cache clean for things like IMB_Full. -; -; Sadly, for global cache invalidate with mini cache, things are awkward. We can't clean the -; main cache then do the global invalidate MCR, unless we tolerate having _all_ interrupts -; off (else the main cache may be slightly dirty from interrupts, and the invalidate -; will lose data). So we must reluctantly 'invalidate' the mini cache by the ugly/slow -; mechanism as if we were cleaning it :-( Intel should provide a separate global invalidate -; (and perhaps a line allocate) for the mini cache. -; -; We do not use lockdown. -; -; For simplicity, we assume cacheable pages are mostly writeback. Any writethrough -; pages will be invalidated as if they were writeback, but there is little overhead -; (cleaning a clean line or allocating a line from cleaner area are both fast). - -; Global cache cleaning requires address space for private cleaner areas (not accessed -; for any other reason). Cleaning is normally with interrupts enabled (to avoid a latency -; hit), which means that the cleaner data is not invalidated afterwards. This is fine for -; RISC OS - where the private area is not used for anything else, and any re-use of the -; cache under interrupts is safe (eg. a page being moved is *never* involved in any -; active interrupts). - -; Mostly, cleaning toggles between two separate cache-sized areas, which gives minimum -; cleaning cost while guaranteeing proper clean even if previous clean data is present. If -; the clean routine is re-entered, an independent, double sized clean is initiated. This -; guarantees proper cleaning (regardless of multiple re-entrancy) whilst hardly complicating -; the routine at all. The overhead is small, since by far the most common cleaning will be -; non-re-entered. The upshot is that the cleaner address space available must be at least 4 -; times the cache size: -; 1 : used alternately, on 1st, 3rd, ... non-re-entered cleans -; 2 : used alternately, on 2nd, 4th, ... non-re-entered cleans -; 3 : used only for first half of a re-entered clean -; 4 : used only for second half of a re-entered clean -; -; If the mini cache is used, it has its own equivalent cleaner space and algorithm. -; Parameters for each cache are: -; -; Cache_CleanBaseAddress : start address of total cleaner space -; Cache_CleanNextAddress : start address for next non-re-entered clean, or 0 if re-entered - - - GBLL XScaleMiniCache ; *must* be configured writethrough if used -XScaleMiniCache SETL {FALSE} - - -; MACRO to do Intel approved CPWAIT, to guarantee any previous MCR's have taken effect -; corrupts a1 -; - MACRO - CPWAIT - MRC p15, 0, a1, c2, c0, 0 ; arbitrary read of CP15 - MOV a1, a1 ; wait for it - ; SUB pc, pc, #4 omitted, because all ops have a pc load to return to caller - MEND - - -Cache_CleanAll_WB_Cal_LD ROUT -; -; - cleans main cache (and invalidates as a side effect) -; - if mini cache is in use, will be writethrough so no clean required -; - can be used with interrupts enabled (to avoid latency over time of clean) -; - can be re-entered -; - see remarks at top of XScale ops for discussion of strategy -; - Push "a2-a4, v1, v2, lr" - MOV lr, #0 - LDR a1, [lr, #DCache_CleanBaseAddress] - LDR a2, =DCache_CleanNextAddress - LDR a3, [lr, #DCache_Size] - LDRB a4, [lr, #DCache_LineLen] - MOV v2, #0 - SWP v1, v2, [a2] ; read current CleanNextAddr, zero it (semaphore) - TEQ v1, #0 ; but if it is already zero, we have re-entered - ADDEQ v1, a1, a3, LSL #1 ; if re-entered, start clean at Base+2*Cache_Size - ADDEQ v2, v1, a3, LSL #1 ; if re-entered, do a clean of 2*Cache_Size - ADDNE v2, v1, a3 ; if not re-entered, do a clean of Cache_Size -10 - MCR p15, 0, v1, c7, c2, 5 ; allocate address from cleaner space - ADD v1, v1, a4 - TEQ v1, v2 - BNE %BT10 - ADD v2, a1, a3, LSL #1 ; compare end address with Base+2*Cache_Size - CMP v1, v2 - MOVEQ v1, a1 ; if equal, not re-entered and Next wraps back - STRLS v1, [a2] ; if lower or same, not re-entered, so update Next - MCR p15, 0, a1, c7, c10, 4 ; drain WBuffer (waits, so no need for CPWAIT) - Pull "a2-a4, v1, v2, pc" - - [ XScaleMiniCache - -Cache_MiniInvalidateAll_WB_Cal_LD ROUT -; -; similar to Cache_CleanAll_WB_Cal_LD, but must do direct reads (cannot use allocate address MCR), and -; 'cleans' to achieve invalidate as side effect (mini cache will be configured writethrough) -; - Push "a2-a4, v1, v2, lr" - MOV lr, #0 - LDR a1, [lr, #MCache_CleanBaseAddress] - LDR a2, =MCache_CleanNextAddr - LDR a3, [lr, #MCache_Size] - LDRB a4, [lr, #MCache_LineLen] - MOV v2, #0 - SWP v1, v2, [a2] ; read current CleanNextAddr, zero it (semaphore) - TEQ v1, #0 ; but if it is already zero, we have re-entered - ADDEQ v1, a1, a3, LSL #1 ; if re-entered, start clean at Base+2*Cache_Size - ADDEQ v2, v1, a3, LSL #1 ; if re-entered, do a clean of 2*Cache_Size - ADDNE v2, v1, a3 ; if not re-entered, do a clean of Cache_Size -10 - LDR lr, [v1], a4 ; read a line of cleaner data - TEQ v1, v2 - BNE %BT10 - ADD v2, a1, a3, LSL #1 ; compare end address with Base+2*Size - CMP v1, v2 - MOVEQ v1, a1 ; if equal, not re-entered and Next wraps back - STRLS v1, [a2] ; if lower or same, not re-entered, so update Next - ; note, no drain WBuffer, since we are really only invalidating a writethrough cache - Pull "a2-a4, v1, v2, pc" - - ] ; XScaleMiniCache - - -Cache_CleanInvalidateAll_WB_Cal_LD ROUT -; -; - cleans main cache (and invalidates wrt OS stuff as a side effect) -; - if mini cache in use (will be writethrough), 'cleans' in order to invalidate as side effect -; - Push "lr" - BL Cache_CleanAll_WB_Cal_LD - [ XScaleMiniCache - BL Cache_MiniInvalidateAll_WB_Cal_LD - ] - MCR p15, 0, a1, c7, c5, 0 ; invalidate ICache and BTB - CPWAIT - Pull "pc" - - -Cache_InvalidateAll_WB_Cal_LD ROUT -; -; no clean, assume caller knows what's happening -; - MCR p15, 0, a1, c7, c7, 0 ; invalidate DCache, (MiniCache), ICache and BTB - CPWAIT - MOV pc, lr - - -Cache_RangeThreshold_WB_Cal_LD ROUT - MOV a1, #0 - LDR a1, [a1, #DCache_RangeThreshold] - MOV pc, lr - - -TLB_InvalidateAll_WB_Cal_LD ROUT -MMU_ChangingUncached_WB_Cal_LD - MCR p15, 0, a1, c8, c7, 0 ; invalidate ITLB and DTLB - CPWAIT - MOV pc, lr - - -TLB_InvalidateEntry_WB_Cal_LD ROUT -MMU_ChangingUncachedEntry_WB_Cal_LD - MCR p15, 0, a1, c8, c5, 1 ; invalidate ITLB entry - MCR p15, 0, a1, c8, c6, 1 ; invalidate DTLB entry - CPWAIT - MOV pc, lr - - -WriteBuffer_Drain_WB_Cal_LD ROUT - MCR p15, 0, a1, c7, c10, 4 ; drain WBuffer (waits, so no need for CPWAIT) - MOV pc, lr - - -IMB_Full_WB_Cal_LD - Push "lr" - BL Cache_CleanAll_WB_Cal_LD ; clean DCache (wrt to non-interrupt stuff) - MCR p15, 0, a1, c7, c5, 0 ; invalidate ICache and BTB - CPWAIT - Pull "pc" - - -IMB_Range_WB_Cal_LD ROUT - SUB a2, a2, a1 - CMP a2, #32*1024 ; arbitrary-ish range threshold - ADD a2, a2, a1 - BHS IMB_Full_WB_Cal_LD - Push "lr" - MOV lr, #0 - LDRB lr, [lr, #DCache_LineLen] -10 - MCR p15, 0, a1, c7, c10, 1 ; clean DCache entry - [ :LNOT:XScaleJTAGDebug - MCR p15, 0, a1, c7, c5, 1 ; invalidate ICache entry - ] - ADD a1, a1, lr - CMP a1, a2 - BLO %BT10 - [ XScaleJTAGDebug - MCR p15, 0, a1, c7, c5, 0 ; invalidate ICache and BTB - | - MCR p15, 0, a1, c7, c5, 6 ; invalidate BTB - ] - MCR p15, 0, a1, c7, c10, 4 ; drain WBuffer (waits, so no need for CPWAIT) - Pull "pc" - - -MMU_Changing_WB_Cal_LD ROUT - Push "lr" - BL Cache_CleanAll_WB_Cal_LD - MCR p15, 0, a1, c7, c5, 0 ; invalidate ICache and BTB - MCR p15, 0, a1, c8, c7, 0 ; invalidate ITLB and DTLB - CPWAIT - Pull "pc" - -MMU_ChangingEntry_WB_Cal_LD ROUT -; -;there is no clean&invalidate DCache instruction, however we can do clean -;entry followed by invalidate entry without an interrupt hole, because they -;are for the same virtual address (and that virtual address will not be -;involved in interrupts, since it is involved in remapping) -; - Push "a2, lr" - ADD a2, a1, #PageSize - MOV lr, #0 - LDRB lr, [lr, #DCache_LineLen] -10 - MCR p15, 0, a1, c7, c10, 1 ; clean DCache entry - MCR p15, 0, a1, c7, c6, 1 ; invalidate DCache entry - [ :LNOT:XScaleJTAGDebug - MCR p15, 0, a1, c7, c5, 1 ; invalidate ICache entry - ] - ADD a1, a1, lr - CMP a1, a2 - BLO %BT10 - MCR p15, 0, a1, c7, c10, 4 ; drain WBuffer - [ XScaleJTAGDebug - MCR p15, 0, a1, c7, c5, 0 ; invalidate ICache and BTB - | - MCR p15, 0, a1, c7, c5, 6 ; invalidate BTB - ] - SUB a1, a1, #PageSize - MCR p15, 0, a1, c8, c6, 1 ; invalidate DTLB entry - MCR p15, 0, a1, c8, c5, 1 ; invalidate ITLB entry - CPWAIT - Pull "a2, pc" - - -MMU_ChangingEntries_WB_Cal_LD ROUT -; -;same comments as MMU_ChangingEntry_WB_Cal_LD -; - Push "a2, a3, lr" - MOV a2, a2, LSL #Log2PageSize - MOV a3, #0 - LDR a3, [a3, #DCache_RangeThreshold] ;check whether cheaper to do global clean - CMP a2, a3 - BHS %FT30 - ADD a2, a2, a1 ;clean end address (exclusive) - MOV a3, #0 - LDRB a3, [a3, #DCache_LineLen] - MOV lr, a1 -10 - MCR p15, 0, a1, c7, c10, 1 ; clean DCache entry - MCR p15, 0, a1, c7, c6, 1 ; invalidate DCache entry - [ :LNOT:XScaleJTAGDebug - MCR p15, 0, a1, c7, c5, 1 ; invalidate ICache entry - ] - ADD a1, a1, a3 - CMP a1, a2 - BLO %BT10 - MCR p15, 0, a1, c7, c10, 4 ; drain WBuffer - [ XScaleJTAGDebug - MCR p15, 0, a1, c7, c5, 0 ; invalidate ICache and BTB - | - MCR p15, 0, a1, c7, c5, 6 ; invalidate BTB - ] - MOV a1, lr ; restore start address -20 - MCR p15, 0, a1, c8, c6, 1 ; invalidate DTLB entry - MCR p15, 0, a1, c8, c5, 1 ; invalidate ITLB entry - ADD a1, a1, #PageSize - CMP a1, a2 - BLO %BT20 - CPWAIT - Pull "a2, a3, pc" -; -30 - BL Cache_CleanInvalidateAll_WB_Cal_LD - MCR p15, 0, a1, c8, c7, 0 ; invalidate ITLB and DTLB - CPWAIT - Pull "a2, a3, pc" - -MMU_ChangingUncachedEntries_WB_Cal_LD ROUT - CMP a2, #32 ; arbitrary-ish threshold - BHS %FT20 - Push "lr" - MOV lr, a2 -10 - MCR p15, 0, a1, c8, c6, 1 ; invalidate DTLB entry - MCR p15, 0, a1, c8, c5, 1 ; invalidate ITLB entry - SUBS lr, lr, #1 - ADD a1, a1, #PageSize - BNE %BT10 - CPWAIT - Pull "pc" -; -20 - MCR p15, 0, a1, c8, c7, 0 ; invalidate ITLB and DTLB - CPWAIT - MOV pc, lr - -; -------------------------------------------------------------------------- - - -; IMPORT Write0_Translated - -ARM_PrintProcessorType - MOV a1, #ZeroPage - LDRB a1, [a1, #ProcessorType] - TEQ a1, #ARMunk - MOVEQ pc, lr - - Push "lr" - ADR a2, PNameTable - LDR a1, [a2, a1, LSL #1] - MOV a1, a1, LSL #16 - ADD a1, a2, a1, LSR #16 - BL Write0_Translated - SWI XOS_NewLine - SWI XOS_NewLine - Pull "pc" - -PNameTable - DCW PName_ARM600 - PNameTable - DCW PName_ARM610 - PNameTable - DCW PName_ARM700 - PNameTable - DCW PName_ARM710 - PNameTable - DCW PName_ARM710a - PNameTable - DCW PName_SA110 - PNameTable ; pre rev T - DCW PName_SA110 - PNameTable ; rev T or later - DCW PName_ARM7500 - PNameTable - DCW PName_ARM7500FE - PNameTable - DCW PName_SA1100 - PNameTable - DCW PName_SA1110 - PNameTable - DCW PName_ARM720T - PNameTable - DCW PName_ARM920T - PNameTable - DCW PName_ARM922T - PNameTable - DCW PName_X80200 - PNameTable - DCW PName_X80321 - PNameTable - -PName_ARM600 - = "600:ARM 600 Processor",0 -PName_ARM610 - = "610:ARM 610 Processor",0 -PName_ARM700 - = "700:ARM 700 Processor",0 -PName_ARM710 - = "710:ARM 710 Processor",0 -PName_ARM710a - = "710a:ARM 710a Processor",0 -PName_SA110 - = "SA110:SA-110 Processor",0 -PName_ARM7500 - = "7500:ARM 7500 Processor",0 -PName_ARM7500FE - = "7500FE:ARM 7500FE Processor",0 -PName_SA1100 - = "SA1100:SA-1100 Processor",0 -PName_SA1110 - = "SA1110:SA-1110 Processor",0 -PName_ARM720T - = "720T:ARM 720T Processor",0 -PName_ARM920T - = "920T:ARM 920T Processor",0 -PName_ARM922T - = "922T:ARM 922T Processor",0 -PName_X80200 - = "X80200:80200 Processor",0 -PName_X80321 - = "X80321:80321 Processor",0 - ALIGN - - -; Lookup tables from DA flags PCB (bits 14:12,5,4, packed down to 4:2,1,0) -; to XCB bits in page table descriptors. - -XCB_NB * 1:SHL:0 -XCB_NC * 1:SHL:1 -XCB_P * 1:SHL:2 - - ALIGN 32 - -; WT read-allocate cache (eg ARM720T) -XCBTableWT ; C+B CNB NCB NCNB - = L2_C+L2_B, L2_C, L2_B, 0 ; Default - = L2_C+L2_B, L2_C, L2_B, 0 ; WT, X, Non-merging, X - = L2_C+L2_B, L2_C, L2_B, 0 ; WB/RA, X, Merging, X - = L2_C+L2_B, L2_C, L2_B, 0 ; WB/WA, X, X, X - = L2_C+L2_B, L2_C, L2_B, 0 ; Alt DCache, X, X, X - = L2_C+L2_B, L2_C, L2_B, 0 ; X, X, X, X - = L2_C+L2_B, L2_C, L2_B, 0 ; X, X, X, X - = L2_C+L2_B, L2_C, L2_B, 0 ; X, X, X, X - -; SA-110 in Risc PC - WB only read-allocate cache, non-merging WB -XCBTableSA110 - = L2_C+L2_B, 0, L2_B, 0 ; Default - = L2_B, 0, L2_B, 0 ; WT, X, Non-merging, X - = L2_C+L2_B, 0, L2_B, 0 ; WB/RA, X, Merging, X - = L2_C+L2_B, 0, L2_B, 0 ; WB/WA, X, X, X - = L2_C+L2_B, 0, L2_B, 0 ; Alt DCache, X, X, X - = L2_C+L2_B, 0, L2_B, 0 ; X, X, X, X - = L2_C+L2_B, 0, L2_B, 0 ; X, X, X, X - = L2_C+L2_B, 0, L2_B, 0 ; X, X, X, X - -; ARMv5 WB/WT read-allocate cache, non-merging WB (eg ARM920T) -XCBTableWBR - = L2_C+L2_B, 0, L2_B, 0 ; Default - = L2_C , 0, L2_B, 0 ; WT, X, Non-merging, X - = L2_C+L2_B, 0, L2_B, 0 ; WB/RA, X, Merging, X - = L2_C+L2_B, 0, L2_B, 0 ; WB/WA, X, X, X - = L2_C+L2_B, 0, L2_B, 0 ; Alt DCache, X, X, X - = L2_C+L2_B, 0, L2_B, 0 ; X, X, X, X - = L2_C+L2_B, 0, L2_B, 0 ; X, X, X, X - = L2_C+L2_B, 0, L2_B, 0 ; X, X, X, X - -; SA-1110 - WB only read allocate cache, merging WB, mini D-cache -XCBTableSA1110 - = L2_C+L2_B, 0, L2_B, 0 ; Default - = L2_B, 0, 0, 0 ; WT, X, Non-merging, X - = L2_C+L2_B, 0, L2_B, 0 ; WB/RA, X, Merging, X - = L2_C+L2_B, 0, L2_B, 0 ; WB/WA, X, X, X - = L2_C , 0, L2_B, 0 ; Alt DCache, X, X, X - = L2_C+L2_B, 0, L2_B, 0 ; X, X, X, X - = L2_C+L2_B, 0, L2_B, 0 ; X, X, X, X - = L2_C+L2_B, 0, L2_B, 0 ; X, X, X, X - -; XScale - WB/WT read or write-allocate cache, merging WB, mini D-cache -; defaulting to read-allocate -XCBTableXScaleRA - = L2_C+L2_B, 0, L2_B, 0 ; Default - = L2_C , 0, L2_X+L2_B, 0 ; WT, X, Non-merging, X - = L2_C+L2_B, 0, L2_B, 0 ; WB/RA, X, Merging, X - = L2_X+L2_C+L2_B, 0, L2_B, 0 ; WB/WA, X, X, X - = L2_X+L2_C , 0, L2_B, 0 ; Alt DCache, X, X, X - = L2_C+L2_B, 0, L2_B, 0 ; X, X, X, X - = L2_C+L2_B, 0, L2_B, 0 ; X, X, X, X - = L2_C+L2_B, 0, L2_B, 0 ; X, X, X, X - -; XScale - WB/WT read or write-allocate cache, merging WB, mini D-cache -; defaulting to write-allocate -XCBTableXScaleWA - = L2_X+L2_C+L2_B, 0, L2_B, 0 ; Default - = L2_C , 0, L2_X+L2_B, 0 ; WT, X, Non-merging, X - = L2_C+L2_B, 0, L2_B, 0 ; WB/RA, X, Merging, X - = L2_X+L2_C+L2_B, 0, L2_B, 0 ; WB/WA, X, X, X - = L2_X+L2_C , 0, L2_B, 0 ; Alt DCache, X, X, X - = L2_X+L2_C+L2_B, 0, L2_B, 0 ; X, X, X, X - = L2_X+L2_C+L2_B, 0, L2_B, 0 ; X, X, X, X - = L2_X+L2_C+L2_B, 0, L2_B, 0 ; X, X, X, X - - END diff --git a/s/Arthur2 b/s/Arthur2 deleted file mode 100644 index 02fa3b03..00000000 --- a/s/Arthur2 +++ /dev/null @@ -1,2345 +0,0 @@ -; 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 => Arthur2 - -; GET $.Hdr.Variables - got at start - - MACRO -$l GSVarGetWSpace -$l LDR R12, =GSVarWSpace - MEND - -;mjs performance enhancements for Ursula (ChocolateSysVars) -; - GBLL SysVars_QuickContext - GBLL SysVars_StickyNodes -SysVars_QuickContext SETL {TRUE} :LAND: ChocolateSysVars ;avoid abysmal O(n*n) enumeration of vars -SysVars_StickyNodes SETL {TRUE} :LAND: ChocolateSysVars ;attempt to avoid lots of SysHeap operations, - ;especially grows and shrinks - -SysVars_Vindex_NStart * 256 ;initial no. of vars supported by index -SysVars_Vindex_NBump * 32 ;additional no. of vars each time index size is bumped up - - [ SysVars_QuickContext -; -;format of block anchored at VariableList -; - ^ 0 -SysVars_LastContext # 4 ;last var table index for last context ptr returned, or -1 if invalid -SysVars_VTableOffset # 0 -; -;immediately followed by table data as in old code: -; 1 word = total number of variables (N) -; N words = ptrs to variable blocks (sorted table) -; - ] - - [ SysVars_StickyNodes -SysVars_StickyNode_UnitSize * 32 ;quantise node size to multiples of this many bytes - ;(must be multiple of 8, and power of 2) -SysVars_StickyNode_Log2US * 5 ;Log2 of unit size -SysVars_StickyNode_MaxSize * 320 ;maximum size of node that may stick (be retained on removal as active node) -; -;There are currently 10 words allocated in kernel workspace for sticky pointers - ASSERT SysVars_StickyNode_UnitSize*10 = SysVars_StickyNode_MaxSize - ] - - GBLL DebugSysVars -DebugSysVars SETL {FALSE} - - -;----------------------------------------------------------------------------------- -; -; This file covers: -; System variables: -; InitVariables -; OS_ReadVarVal -; OS_SetVarVal -; GSTrans: -; OS_GSInit -; OS_GSRead -; OS_GSTrans -; OS_BinaryToDecimal -; These have been grouped because GSTrans makes direct use of the system variables' -; structures and OS_BinaryToDecimal is used by readvarval. -; -; The system variables are stored as a one way sorted alphabetically linked list hanging -; off the zero-page location VariableList: -; -; VariableList---->sorted table of pointers to variable blocks (QuickIndex) - format as above -; -; The end is indicated by the link having the value 0. -; -; Each variable is stored in one block in the system heap (block will be word aligned). The -; format of each block is: -; -; No. Bytes Use -; N+1 Variable's name (length N, plus terminator). -; 1 Variable's type: -; 0 string -; 1 number -; 2 macro -; 3 expanded (not valid within sysvar structure) -; 16 code -; M data - depends on the variable's type -; -; The structure of the data is as follows: -; -; Type 0 - string -; Bytes Use -; 3 Length (N) -; N the bytes of the string - may contain any characters -; -; Type 1 - number -; Bytes Use -; 4 its value (not necessarily word aligned) -; -; Type 2 - macro -; Bytes Use -; 3 Length (N) -; N the bytes of the string - must be a valid GSTransable string -; including terminator -; -; Type 16 - code -; Bytes Use -; x Sufficient to word align... -; 4 Write entry -; 4 Read entry -; N The rest of the code - -InitVariables ROUT - Push "lr" - - ; Blank the sysvar list - MOV R0, #0 - LDR R12, =VariableList - STR R0, [R12] - - ; Set up the preset system variables - ADR R0, SystemVarList ; R0 pointer to name -01 MOV R1, R0 - LDRB R2, [R1], #1 - CMP R2, #0 - Pull "PC", EQ -02 LDRB R3, [R1], #1 - CMP R3, #0 - BNE %BT02 - LDRB R4, [R1], #1 ; get type - ADD R1, R1, #3 - BIC R1, R1, #3 - LDR R2, [R1], #4 - SWI XOS_SetVarVal - ADD R0, R1, R2 - B %BT01 - - LTORG - -; System vars have Thunks : -; read thunk returns R0 ptr to string, R2 length. R1 corruptible -; set thunk takes R1 ptr to value, R2 length. Value is always a string. -; Can corrupt R1, R2, R4, R10-12 - -; The list of nodes to copy into RAM : -; name, 0 , type, ALIGN, size of value, value - -SystemVarList ROUT - = "Sys$$Time", 0, VarType_Code - ALIGN - & sv2-.-4 - LDR PC, %FT01 - LDR PC, %FT02 -01 - & SetTimeVar -02 - & ReadTimeVar - -sv2 = "Sys$$Year", 0, VarType_Code - ALIGN - & sv3-.-4 - LDR PC, %FT03 - LDR PC, %FT04 -03 - & SetYear -04 - & ReadYear - -sv3 = "Sys$$Date", 0, VarType_Code - ALIGN - & sv4-.-4 - LDR PC, %FT05 - LDR PC, %FT06 -05 - & SetDate -06 - & ReadDate - -sv4 = "Sys$$ReturnCode", 0, VarType_Code - ALIGN - & sv5-.-4 - LDR PC, %FT07 - LDR PC, %FT08 -07 - & SetRC -08 - & ReadRC - -sv5 = "Sys$$RCLimit", 0, VarType_Code - ALIGN - & sv6-.-4 - LDR PC, %FT09 - LDR PC, %FT10 -09 - & SetRCL -10 - & ReadRCL - -sv6 = "Alias$.", 0, VarType_String - ALIGN - & sv7-.-4 - = "Cat ", 10 - -sv7 = "Sys$$DateFormat", 0, VarType_String - ALIGN - & sv8-.-4 - - [ {TRUE} - = "%24:%mi:%se %dy-%m3-%ce%yr", 10 - | - = "%w3,%dy %m3 %ce%yr.%24:%mi:%se", 10 - ] - -sv8 = 0 - -SysTimeFormat - = "%24:%mi:%se", 0 -SysDateFormat - = "%w3,%dy %m3", 0 -SysYearFormat - = "%ce%yr", 0 - - ALIGN - -; Now the code for our system variables. - -ReadTimeVar - ADR R0, SysTimeFormat - B ReadTimeFormatted -SetTimeVar ROUT - CMP R2, #&FE - BHI TimeVarTooLong - Push "R0, lr" - [ GSWorkspaceInKernelBuffers - LDR R12, =SysVarWorkSpace - | - GSVarGetWSpace - ADD R12, R12, #GSNameBuff - ] - MOV R11, #8 - STRB R11, [R12], #1 - MOV R10, #0 - STRB R10, [R12, R2] - MOV R10, R2 -01 SUBS R10, R10, #1 - LDRPLB R11, [R1, R10] - STRPLB R11, [R12, R10] - BPL %BT01 - SUB R1, R12, #1 - MOV R0, #15 - SWI XOS_Word - STRVS R0, [R13] - Pull "R0, PC" - -TimeVarTooLong - ADRL R0, ErrorBlock_VarTooLong - [ International - B TranslateError - | - RETURNVS - ] - -ReadYear - ADR R0, SysYearFormat - B ReadTimeFormatted -SetYear ROUT - CMP R2, #4 - BHI TimeVarTooLong - Push "R0, lr" - Push "R1,R2" - ADR R0, SetYearPrefixFormat - BL ReadTimeFormatted - ADD R12, R0, R2 ; R12 -> position to copy year to - Pull "R1,R2" - BVS %FT02 - MOV R10, #0 - STRB R10, [R12, R2] - MOV R10, R2 -01 SUBS R10, R10, #1 - LDRPLB R11, [R1, R10] - STRPLB R11, [R12, R10] - BPL %BT01 - SUB R1, R0, #1 - MOV R0, #15 - STRB R0, [R1] - SWI XOS_Word -02 STRVS R0, [R13] - Pull "R0, PC" - -ReadDate - ADR R0, SysDateFormat - B ReadTimeFormatted -SetDate ROUT - CMP R2, #&F8 - BHI TimeVarTooLong - Push "R0, lr" - [ GSWorkspaceInKernelBuffers - LDR R12, =SysVarWorkSpace - | - GSVarGetWSpace - ADD R12, R12, #GSNameBuff - ] - MOV R11, #15 - STRB R11, [R12], #1 - MOV R10, #0 - STRB R10, [R12, R2] - MOV R10, R2 -01 SUBS R10, R10, #1 - LDRPLB R11, [R1, R10] - STRPLB R11, [R12, R10] - BPL %BT01 - ADD R1, R12, R2 - ADR R0, SetDateSuffixFormat ; append year to supplied date - Push "R12" - BL ReadTimeFormattedAtR1 - Pull "R12" - SUB R1, R12, #1 - MOV R0, #15 - SWI XOS_Word - STRVS R0, [R13] - Pull "R0, PC" - - -; in: R0 = format string -; out: R0 -> time string (0 terminated) -; R2 = length of string (excluding terminator) -; R1 corrupt -ReadTimeFormatted ROUT - Push "R3,R4,LR" - [ GSWorkspaceInKernelBuffers - LDR R12, =SysVarWorkSpace - ADD R2, R12, #1 - | - GSVarGetWSpace - ADD R2, R12, #GSNameBuff+1 ; This code copied from OsWord0EAlpha - ] -01 MOV R4, R0 - SUB R13, R13, #8 - MOV R1, R13 - MOV R0, #3 - STRB R0, [R1] - MOV R0, #14 - SWI XOS_Word - BVS %FT02 - MOV R0, #-1 - MOV R1, R13 - [ GSWorkspaceInKernelBuffers - MOV R3, #?SysVarWorkSpace-1 - | - MOV R3, #?GSNameBuff-1 - ] - SWI XTerritory_ConvertDateAndTime -02 ADD R13, R13, #8 - SUBVC R2, R1, R0 - Pull "R3,R4,PC" - -; in: R0 = format string -; R1 -> output buffer -; out: R0 -> time string (0 terminated) -; R1 corrupt -; R2 = length of string (excluding terminator) -ReadTimeFormattedAtR1 - Push "R3,R4,LR" - MOV R2, R1 - B %BT01 - -ReadRC ROUT - MOV R0, #0 - LDR R0, [R0, #ReturnCode] - B ReadNumSysVar -SetRC Push "lr" - BL SetNumSysVar - LDR R4, =ReturnCode - STR R2, [R4] - LDR R4, =RCLimit - LDR R4, [R4] - CMP R2, R4 - BHI %FT03 - CLRV - Pull "PC" -03 ADRGT R0, ErrorBlock_RCExc - ADRLT R0, ErrorBlock_RCNegative - [ International - BL TranslateError - | - SETV - ] - - Pull "PC" -SetYearPrefixFormat - = "%w3,%dy %m3 ", 0 -SetDateSuffixFormat - = " %ce%yr", 0 - ALIGN - - MakeErrorBlock RCExc - MakeErrorBlock RCNegative - -ReadRCL MOV R0, #0 - LDR R0, [R0, #RCLimit] -ReadNumSysVar - Push "lr" - [ GSWorkspaceInKernelBuffers - LDR R12, =SysVarWorkSpace - MOV R1, R12 - | - GSVarGetWSpace - ADD R1, R12, #GSNameBuff - ] - MOV R2, #256 - SWI XOS_BinaryToDecimal - MOV R0, R1 - Pull "PC" -SetRCL Push "lr" - BL SetNumSysVar - LDR R4, =RCLimit - CMP R2, #0 ; can't set -ve RCLimit - RSBMIS R2, R2, #0 - MOVMI R2, #0 ; BIC of MININT - STR R2, [R4] - Pull "PC" - - LTORG - -SetNumSysVar ROUT ; R1 ptr to string, R2 string length - Push "lr" - SUBS R2, R2, #1 - ADDMI R2, R2, #1 ; give 0 in R2 for bad length. - Pull "PC", MI - [ GSWorkspaceInKernelBuffers - LDR R12, =SysVarWorkSpace - | - LDR R12, =GSNameBuff+GSVarWSpace - ] -03 LDRB R10, [R1], #1 ; copy into a buffer so we can terminate it. - STRB R10, [R12], #1 - SUBS R2, R2, #1 - BPL %BT03 - MOV R10, #13 - STRB R10, [R12], #1 - [ GSWorkspaceInKernelBuffers - LDR R1, =SysVarWorkSpace - | - LDR R1, =GSNameBuff+GSVarWSpace - ] - LDRB R10, [R1] - MOV R12, #0 - CMP R10, #"-" - MOVEQ R12, #-1 - CMPNE R10, #"+" - ADDEQ R1, R1, #1 - MOV R0, #0 - SWI XOS_ReadUnsigned - CMP R12, #0 - RSBMI R2, R2, #0 - Pull "PC" - - -;***************************************************************************** -; GSINIT, GSREAD, GSTRANS - -; To enable GSTrans nesting to stand a chance of working don't flatten the -; stack every FSINIT. Instead, pick up the stack pointer (any value is OK) -; and wrap at 255. Stack overflow occurs if you increment the pointer to -; where it started for this GSINIT, and stack underflow occurs if you -; decrement the pointer when it is currently equal to stack limit. -; The stack limit is held in the environment value, R2. -; The stack is empty ascending. - GBLL GS_BufferNotStack -GS_BufferNotStack SETL {TRUE} - -; some semi-arbitrary flags -GS_NoQuoteMess * 1 :SHL: 31 ; flags passed in from user -GS_NoVBarStuff * 1 :SHL: 30 -GS_Spc_term * 1 :SHL: 29 ; clear if user requested terminate on space -GS_In_String * 1 :SHL: 28 ; set if waiting for closing " -GS_ReadingString * 1 :SHL: 27 ; set if reading chars from a string var. -GS_Macroing * 1 :SHL: 26 ; set if reading chars from a macro - [ GS_BufferNotStack - ASSERT GS_StackPtr_Lim = &80 -GS_StackLimitBits * 7 -GS_StackLimitPos * 19 ; The bit position of the LSB of the byte - ; which holds the stack limit -; bits 0-18 hold the string length for string transfers - | -; bits 24-25 are unused -; bits 0-23 hold the string length for string transfers - ] - -; After GSINIT, R2 has these flags, and if expanding a count in the low byte - -GSINIT ROUT -; In : R0 pointer to string to expand -; R2 has flags : -; Bit 29 set means space is a terminator -; Bit 30 set means | characters will not be molested -; Bit 31 set means don't mess with quotes - -; Out : R0, R2 are values to pass back in to GSREAD -; R1 is the first non-blank character -; EQ means char is CR or LF, i.e. string is empty. - - ; Enable interupts as we've no right to have them disabled here - WritePSRc SVC_mode, R1 - - [ GS_BufferNotStack - AND R2, R2, #GS_NoQuoteMess :OR: GS_NoVBarStuff :OR: GS_Spc_term - ; get caller's flags - ] - -; If no tokens to expand then don't reset evaluation stack -; This prevents conflict with modules opening messages files at lower levels - - Push "r0" -10 LDRB r1, [r0], #1 - CMP r1, #13 - CMPNE r1, #10 - CMPNE r1, #0 - Pull "r0",EQ - BEQ %FT20 ; Jump if end of string, nothing to expand - - TEQ r1, #"<" ; Possibly something to expand? - BNE %BT10 ; No then try next - Pull "r0" - -; Expansion may be necessary so flatten evaluation stack - - [ GS_BufferNotStack - GSVarGetWSpace - LDRB R1, [R12, #GS_StackPtr] - AND R1, R1, #(GS_StackPtr_Lim-1) ; Ensure we remain in range - STRB R1, [R12, #GS_StackPtr] - ORR R2, R2, R1, LSL #GS_StackLimitPos - | - MOV R1, #0 - GSVarGetWSpace - STRB R1, [R12, #GS_StackPtr] ; no stacked R0s - ] - -20 - [ GS_BufferNotStack - | - AND R2, R2, #GS_NoQuoteMess :OR: GS_NoVBarStuff :OR: GS_Spc_term - ; get caller's flags - ] - EOR R2, R2, #GS_Spc_term ; and invert for convenience - -01 LDRB R1, [R0], #1 - CMP R1, #" " - BEQ %BT01 - TST R2, #GS_NoQuoteMess - CMPEQ R1, #"""" - SUBNE R0, R0, #1 ; dec if went too far - ORREQ R2, R2, #GS_In_String ; set flag if in string - CMP R1, #13 - CMPNE R1, #10 - CMPNE R1, #0 - ORREQ lr, lr, #Z_bit ; and move EQ/NE to return pc - BICNE lr, lr, #Z_bit - ExitSWIHandler - - LTORG - -; ----------------------------------------------------------------------------- - - -GSREAD ROUT -; In : R0, R2 from last GSREAD/GSINIT -; Out : R1 character, R0, R2 updated. -; VS => "Bad String" error -; CS => string ended (in which case R1 = terminator) - - ; enable interupts as (a) they'll get enabled by a <thing> entry - ; and (b) GSREAD may take some time - WritePSRc SVC_mode, R10 - - BIC lr, lr, #C_bit - MOV R10, #0 - TST R2, #GS_ReadingString - BNE GSREAD_RStringGetNextByte ; take byte from stringvar - -GSREAD_XPandGetNextByte - LDRB R1, [R0], #1 - CMP R1, #13 - CMPNE R1, #10 - CMPNE R1, #0 - BEQ GSREAD_XPandGotToEnd - CMP R1, #" " - BEQ GSREAD_XPandGotSpace - BLT GSREAD_BadStringError ; bad string : control code in string - CMP R1, #"""" - BEQ GSREAD_XPandGotQuote - CMP R1, #"|" - TSTEQ R2, #GS_NoVBarStuff - BEQ GSREAD_WorkOutBarChar - CMP R1, #"<" - BNE GSREAD_ReturnWithChar ; OS_Exit with valid character - -; got to try and get a variable value. - Push "R0, R2, lr" - LDRB R1, [R0] - CMP R1, #">" - CMPNE R1, #" " - BEQ GSREAD_AngleBraDaftSoIsnt ; <> and < > are silly. - - ; Copy angle bracketed thing checking for correct termination - GSVarGetWSpace - ADD R12, R12, #GSNameBuff - MOV R11, #0 -20 LDRB R1, [R0], #1 - STRB R1, [R12], #1 - ADD R11, R11, #1 - CMP R11, #255 - CMPNE R1, #13 - CMPNE R1, #10 - CMPNE R1, #0 - BEQ GSREAD_AngleBraDaftSoIsnt - CMP R1, #">" - BNE %BT20 - - ; Check for number first - MOV R1, #0 - STRB R1, [R12, #-1] ; terminate it - SUB R1, R12, R11 ; pointer to name or number - Push "R0" - SWI XOS_ReadUnsigned ; check for number - Pull "R0" - BVS GSREAD_AngledThingAintNumber ; silly - has to be name - LDRB R1, [R1] ; check terminated by the null - CMP R1, #0 - BNE GSREAD_AngledThingAintNumber - MOV R1, R2 ; character value - ADD stack, stack, #4 ; discard old R0 value. - Pull "R2, lr" - B GSREAD_ReturnWithChar ; exit-R1's the char value. - -GSREAD_AngledThingAintNumber - ; R0, R2, lr on stack - Push "R0, R3, R4, R10" ; corrupted by VarFindIt - MOV R3, #0 ; context ptr - SUB R0, R12, R11 ; name ptr - BL VarFindIt - Pull "R0, R3, R4, R10", EQ ; not found mate - BEQ GSREAD_AngledThingNotThere ; return null expansion -; well, we've found it - better stack old R0 - Pull "R0" - GSVarGetWSpace - [ GS_BufferNotStack - LDRB r1, [r12, #GS_StackPtr] - LDR r2, [sp, #4*4] ; r3,r4,r10,r0,r2,lr on stack, hence r2 retrieved - MOV r2, r2, ASL #32-(GS_StackLimitPos+GS_StackLimitBits) - SUB r2, r2, #1:SHL:(32-GS_StackLimitBits) - TEQ r1, r2, LSR #32-GS_StackLimitBits - BEQ GSREAD_CantNestMore - | - LDRB R1, [R12, #GS_StackPtr] - CMP R1, #GS_StackPtr_Lim - BHS GSREAD_CantNestMore - ] - ADD R12, R12, #GS_Stack - STR R0, [R12, R1, LSL #2] - ADD R1, R1, #1 - [ GS_BufferNotStack - AND R1, R1, #(GS_StackPtr_Lim-1) - ] - STRB R1, [R12, #GS_StackPtr-GS_Stack] - MOV R0, R4 - LDRB R1, [R0], #1 ; type - CMP R1, #VarType_Code - BEQ GSREAD_CallCodeVar - CMP R1, #VarType_Number - LDRB R1, [R0], #1 - - LDRB R3, [R0], #1 - ORR R1, R1, R3, LSL #8 - LDRB R3, [R0], #1 - ORR R1, R1, R3, LSL #16 - - BLO GSREAD_GotVarAsString - BHI GSREAD_GotMacroVar - LDRB R3, [R0], #1 - ORR R1, R1, R3, LSL #24 - MOV R0, R1 - ADD R1, R12, #GSNameBuff-GS_Stack - MOV R2, #256 - SWI XOS_BinaryToDecimal - MOV R0, R1 - MOV R1, R2 - -; it's a string variable, by now. -GSREAD_GotVarAsString - Pull "R3, R4, R10" - ADD stack, stack, #4 ; discard that R0 - Pull "R2, lr" - CMP R1, #0 - BEQ ZeroLengthVar - ORR R2, R2, R1 ; old flags+new count - ORR R2, R2, #GS_ReadingString - LDRB R1, [R0], #1 - B GSREAD_ReturnWithChar - -GSREAD_GotMacroVar - ; Macro - R0 is now the ptr to the macro value. - Pull "R3, R4, R10" - ADD stack, stack, #4 - Pull "R2, lr" - ORR R2, R2, #GS_Macroing - B GSREAD_XPandGetNextByte ; loop, transforming chars. - -GSREAD_CantNestMore - Pull "R3, R4, R10" ; no room to stack pointer, so don't expand -GSREAD_AngledThingNotThere - ADD stack, stack, #4 ; skip R0 - return null string - Pull "R2, lr" - B GSREAD_XPandGetNextByte ; get next char - -GSREAD_AngleBraDaftSoIsnt - Pull "R0, R2, lr" - MOV R1, #"<" - B GSREAD_ReturnWithChar ; failed to get sensible variable - -GSREAD_XPandGotToEnd - TST R2, #GS_In_String ; got CR or LF - BNE GSREAD_BadStringError ; bad string - TST R2, #GS_Macroing -GSREAD_GotToAnEnd - ORREQ lr, lr, #C_bit ; got terminator - ExitSWIHandler EQ - - ; Nest out by one level - GSVarGetWSpace - LDRB R11, [R12, #GS_StackPtr] - [ GS_BufferNotStack - SUB R11, R11, #1 - AND R11, R11, #(GS_StackPtr_Lim-1) - MOV r2, r2, ROR #GS_StackLimitPos+GS_StackLimitBits - TEQ r11, r2, LSR #32-GS_StackLimitBits - MOV r2, r2, ROR #32-(GS_StackLimitPos+GS_StackLimitBits) - | - SUBS R11, R11, #1 - ] - BICEQ R2, R2, #GS_Macroing - STRB R11, [R12, #GS_StackPtr] - ADD R12, R12, #GS_Stack - LDR R0, [R12, R11, LSL #2] - B GSREAD_XPandGetNextByte ; return to prevstring - -GSREAD_XPandGotSpace - TST R2, #(GS_In_String :OR: GS_Spc_term :OR: GS_Macroing) - ; got space : check termination - BEQ GSREAD_GotToAnEnd ; terminates - -GSREAD_ReturnWithChar - ORR R1, R1, R10 ; valid character - ExitSWIHandler - -GSREAD_XPandGotQuote - TST R2, #GS_In_String - BEQ GSREAD_ReturnWithChar ; if not in string, " is valid. - LDRB R1, [R0], #1 - CMP R1, #"""" ; "" in string? - BEQ GSREAD_ReturnWithChar ; yup - - -; TMD 25-Sep-89: Fix termination here - -10 - CMP R1, #" " - LDREQB R1, [R0], #1 - BEQ %BT10 - SUB R0, R0, #1 - ORR lr, lr, #C_bit ; got terminator (second ") - ExitSWIHandler ; and out - -GSREAD_WorkOutBarChar - LDRB R1, [R0], #1 ; got |, do traditional escaping - CMP R1, #"|" - CMPNE R1, #"""" - CMPNE R1, #"<" - BEQ GSREAD_ReturnWithChar ; || gives |, |" gives ", |< gives < - CMP R1, #"?" - MOVEQ R1, #&7F ; delete - BEQ GSREAD_ReturnWithChar ; valid ch - CMP R1, #"!" - MOVEQ R10, #&80 - BEQ GSREAD_XPandGetNextByte ; tbs char - CMP R1, #" " - BLT GSREAD_BadStringError ; OS_Control character is naff - CMP R1, #&7F ; CTRL-delete is delete - EORGT R1, R1, #&20 ; softkey - BGE GSREAD_ReturnWithChar ; now valid ch - CMP R1, #"`" ; CTRL-` = CTRL-_ - MOVEQ R1, #"_" - CMP R1, #"@" - ANDGE R1, R1, #&1F ; transform if @<=ch<delete - B GSREAD_ReturnWithChar - -GSREAD_RStringGetNextByte - SUB R2, R2, #1 ; we're reading a string - [ GS_BufferNotStack - MOVS R12, R2, ASL #32-GS_StackLimitPos - | - ANDS r12, r2, #&00ffffff - ] - LDRNEB R1, [R0], #1 ; and this is already expanded - ExitSWIHandler NE ; so finished -ZeroLengthVar - GSVarGetWSpace - LDRB R0, [R12, #GS_StackPtr] ; pull an R0 from our stack - SUB R0, R0, #1 - [ GS_BufferNotStack - AND R0, R0, #(GS_StackPtr_Lim-1) - ] - STRB R0, [R12, #GS_StackPtr] - ADD R12, R12, #GS_Stack - LDR R0, [R12, R0, LSL #2] - BIC R2, R2, #GS_ReadingString - B GSREAD_XPandGetNextByte - -GSREAD_BadStringError - ADR R0, BadStrErr - [ International - Push "lr" - BL TranslateError - Pull "lr" - ] - ORR lr, lr, #V_bit :OR: C_bit - ExitSWIHandler - -BadStrErr - MakeErrorBlock BadString - -GSREAD_CallCodeVar - ADD R0, R0, #3 + 4 ; 3 to ALIGN, 4 to get to read entry - MOV lr, PC ; get link - BIC PC, R0, #3 ; call entrypoint to Read Thunk - MOV R1, R2 - B GSREAD_GotVarAsString - -; --------------------------------------------------------------------------- - - -GSTRANS ROUT ; enables interrupts -; In : R0 ptr to input string - ; R1 ptr to Out buffer - ; R2 max number of chars, with flags at top. - -; Out : R0 points at terminator - ; R1 unchanged - ; R2 Number of chars got, - ; C set if too many chars - ; V set if bad string. - - BIC lr, lr, #C_bit - Push "R1, R3-R5, lr" - WritePSRc SVC_mode, R3 ; enable ints. - - MOV R3, R1 - MOV R4, R1 ; two copies of start ptr - BIC R5, R2, #&E0000000 - ADD R5, R5, R1 ; 1st byte we can't write to. - SWI XOS_GSInit -01 CMP R3, R5 - BHS %FT03 ; no rheum for byte. - SWI XOS_GSRead - BVS %FT02 ; bad string - STRB R1, [R3], #1 - BCC %BT01 -04 SUB R2, R3, R4 ; no chars got - SUB R2, R2, #1 - Pull "R1, R3-R5, lr" - ExitSWIHandler - -02 SUB R2, R3, R4 - Pull "R1, R3-R5, lr" - B SLVK_SetV ; bad string: error set by GSRead - -03 SUB R2, R3, R4 - Pull "R1, R3-R5, lr" - ORR lr, lr, #C_bit ; buffer overflow - ExitSWIHandler - -;**************************************************************************** -; Read/Write variables -; Also the binary->decimal SWI. -; All the var SWIs enable interrupts - they all take quite a while. - -; First the lookup SWI, ReadVarValue -; In: -; R0 -> name; maybe wildcarded (* and #) -; R1 -> buffer -; R2 = buffer max length -; R3 = 0 or pointer to name returned from previous ReadVarVal -; R4 = VarType_Expanded or something else - -; Out: -; Not found: -; R0 -> VarCantFind error -; R1 unaltered -; R2 = 0 -; R3,r4 trashed -; VSet -; Found, r2 < 0 and r4 <> VarType_Expanded on entry: -; R0, R1 unaltered -; R2 = NOT length of value -; R3 -> name of variable (0-terminated) -; R4 = type of result -; Found, r2 < 0 and r4 = VarType_Expanded on entry: -; R0, R1 unaltered -; R2 = -ve -; R3 -> name of variable (0-terminated) -; R4 = type of result -; Found, r2 >= 0 on entry: -; R0, R1 unaltered -; R2 no chars got -; R3 -> name of variable. Can be passed to this SWI to continue enumeration -; of wildcard. -; R4 type of result (VarType_String, VarType_Number, VarType_Macro) -; VSet if buffer overflowed (R0->error block) - - [ Oscli_QuickAliases -; R0 in = -1 is special case: skip call to VarFindIt (r5,r6,r7 in supply r3,r4,r12) - ] - -ReadVarValue ROUT - WritePSRc SVC_mode, r11 ; enable interupts (mode remains unchanged) - Entry "r0,r1" - - MOV r11, r4 - - [ Oscli_QuickAliases - CMP r0, #-1 - BNE rvv_noqaspecialentry - MOV r3,r5 - MOV r4,r6 - MOV r12,r7 - B rvv_qaspecialentry -rvv_noqaspecialentry - ] - - BL VarFindIt ; name=r0,context=r3 -> name found in node=r3,r4=after namein,r12=prev - BEQ RVVNotFound - - [ Oscli_QuickAliases -rvv_qaspecialentry - ] - ; Regardless of expanded or not - always call the code to get value - LDRB lr, [r4], #1 - TEQ lr, #VarType_Code - BEQ ReadVarVal_CallCode - - ; Check whether expanded value wanted and pick up found variable's type - TEQ r11, #VarType_Expanded - MOV r11, r4 - MOV r4, lr - BEQ ReadVarVal_ExpandedWanted - - ; Unexpanded value wanted.... - - ; If number then want 4 bytes, else however many there are in the varval - TEQ r4, #VarType_Number - MOVEQ r10, #4 - -ReadVarVal_CopyStringVarToUserBuffer - ; R1 -> user buffer - ; R2 = user buffer size - ; R3 -> name of sysvar found - ; R4 = sysvar type to return - ; R10 = length to transfer to user buffer (EQ only) - ; R11 -> length byte(s) of sysvar (NE only) - ; -> bytes string to transfer (EQ only) - LDRNEB r10, [r11], #1 - LDRNEB lr, [r11], #1 - ORRNE r10, r10, lr, ASL #8 - LDRNEB lr, [r11], #1 - ORRNE r10, r10, lr, ASL #16 - -ReadVarVal_CopyR10BytesToUserBuffer - ; R1 -> user buffer - ; R2 = user buffer size - ; R3 -> name of sysvar found - ; R4 = type byte to be returned - ; R10 = bytes to be copied - ; R11 -> bytes to be copied - - CMP R10, R2 - BGT ReadVarVal_BufWillOFlow - -VarNoOFlo - ; Guaranteed the the buffer won't overflow now - MOV R2, R10 ; bytes he's gonna get -; now copy R10 bytes into buffer -02 SUBS R10, R10, #1 - LDRPLB R12, [R11, R10] - STRPLB R12, [R1, R10] - BPL %BT02 - -ReadVarVal_OKExit - PullEnv - ExitSWIHandler - -ReadVarVal_BufWillOFlow - ; Have determined that the buffer will overflow, so generate an error - ; and shorten down to the buffer's size - ADR r0, BufferOFloError - [ International - BL TranslateError - ] - STR r0, [stack, #Proc_LocalStack + 0*4] - LDR lr, [stack, #Proc_LocalStack + 2*4] - ORR lr, lr, #V_bit ; set for return - STR lr, [stack, #Proc_LocalStack + 2*4] - - ; ensure NOT length returned in r2 when returning with r2<0 on entry - CMP r2, #0 - MVNMI r10, r10 - MOVPL r10, r2 - B VarNoOFlo - -BufferOFloError - MakeErrorBlock BuffOverflow - -ReadVarVal_CallCode - Push "r0-r2" ; read sysvar : r4 points after type - ADD r11, r4, #3 + 4 ; 3 to align and 4 to get to read entry - MOV lr, pc ; construct link - BIC pc, r11, #3 ; call read code in var - MOV r11, r0 ; ptr to value - MOV r10, r2 ; no of chars. - Pull "r0-r2" - - ; error may be returned from reading the var val - MOVVS r0, r11 - BVS ReadVarVal_TestVExit - - MOV r4, #VarType_String - B ReadVarVal_CopyR10BytesToUserBuffer - -ReadVarVal_ExpandedWanted - ; Request for expanded value.... - - ; Check for number, string or macro - CMP R4, #VarType_Number - BLT ReadVarVal_CopyStringVarToUserBuffer - BEQ ReadVarVal_FoundNumber - -; macro - gstrans it. R1 buffer ptr, r2 max chars, R11+1 ptr to value. -; Macros have a terminator after their value, to allow GSTRANS. - - CMP r2, #0 ; if negative, then don't call GSTrans because bits 29..31 have - MVNMI r10, r2 ; return r2 out by this method - BMI ReadVarVal_BufWillOFlow ; a special meaning - just branch back to the normal overflow code - - ADD r0, r11, #3 ; skip length - SWI XOS_GSTrans - BVS ReadVarVal_TestVExit - BCC ReadVarVal_OKExit - - ADR R0, BufferOFloError - [ International - BL TranslateError - ] - B ReadVarVal_SetVExit - - -ReadVarVal_FoundNumber - ; Found a number - extract its value and convert to string - LDRB R0, [R11], #1 ; number - convert to string. - LDRB R12, [R11], #1 - ORR R0, R0, R12, LSL #8 - LDRB R12, [R11], #1 - ORR R0, R0, R12, LSL #16 - LDRB R12, [R11] - ORR R0, R0, R12, LSL #24 - - ; got number in R0, buffptr in R1, max chars in R2 - SWI XOS_BinaryToDecimal - - MOV r4, #VarType_String - -ReadVarVal_TestVExit - STRVS r0, [stack, #Proc_LocalStack + 0*4] - PullEnv - B SLVK_TestV - -RVVNotFound - [ International - MOV r4, r0 - ADR r0, RVVNFError - BL TranslateError_UseR4 - | - ADR R0, RVVNFError - ] - MOV r2, #0 ; indicate not found. - -ReadVarVal_SetVExit - STR r0, [stack, #Proc_LocalStack + 0*4] - PullEnv - B SLVK_SetV ; general error return - -RVVNFError - MakeErrorBlock VarCantFind - -;*************************************************************************** - -; The convert number to string SWI -; In : R0 signed 32-bit integer -; R1 pointer to buffer -; R2 max buffer length -; Out : R0, R1 unmodified -; R2 actual chars given -; V Set if buffer overflow - -; Format : - if negative, leading zeros stripped. - -CvtToDecimal ROUT - Push "R0, R3-R5" - MOV R12, R2 - MOV R2, #0 - CMP R0, #0 - BPL %FT01 - SUBS R12, R12, #1 - BMI %FT10 - MOV R11, #"-" - STRB R11, [R1] - MOV R2, #1 - RSB R0, R0, #0 - -; now do digits. - -01 RSB R0, R0, #0 ; get negative so minint works. - ADR R3, TenTimesTable - MOV R10, #9 ; max entry - MOV R4, #0 ; non-0 had flag -02 LDR R11, [R3, R10, LSL #2] - MOV R5, #-1 ; digit value -03 ADDS R0, R0, R11 - ADD R5, R5, #1 - BLE %BT03 - SUB R0, R0, R11 - CMP R5, #0 - CMPEQ R4, #0 - BNE %FT04 ; put digit -05 SUBS R10, R10, #1 - BPL %BT02 ; next digit - CMP R4, #0 - BEQ %FT04 ; R5 must be 0 - Pull "R0, R3-R5" - ExitSWIHandler - -04 SUBS R12, R12, #1 - BMI %FT10 ; naff Exit - ADD R5, R5, #"0" - MOV R4, #-1 - STRB R5, [R1, R2] - ADD R2, R2, #1 - B %BT05 -10 - ADR R0, BufferOFloError - [ International - Push "lr" - BL TranslateError - Pull "lr" - ] - Pull "R3" ; discard R0 in - Pull "R3-R5" - B SLVK_SetV - -TenTimesTable - & 1 - & 10 - & 100 - & 1000 - & 10000 - & 100000 - & 1000000 - & 10000000 - & 100000000 - & 1000000000 - -; ***************************************************************************** -; SWI OS_SetVarVal : create/update/destroy a variable. - -; In: R0 pointer to name (can be wildcarded for update/delete) -; ctrl/char or space terminated -; R1 pointer to value. String values must be CR or LF terminated. -; R2 negative means destroy the variable. +ve is update/create -; R3 name pointer or 0 -; R4 type. -; -; Evaluation of value : this depends on the type. -; VarType_String : GSTRANS the given value -; VarType_Number : Value is a 4 byte (signed) integer -; VarType_Macro : Copy value (may be GSTRANSed on use) -; VarType_Expanded : the value is a string which should be evaluated as an -; expression. Variable is then numeric or string -; VarType_LiteralString : Copy the given value as a string -; -; VarType_Code : R2 is the length of the code to copy in, including -; padding to align the code. -; Can only delete sysvars if R4 = VarType_Code - -; Out: R3 new name pointer (so can delete all occurrences of f*, etc. -; slightly more efficiently). -; R4 type created for expressions -; V set for : -; 1) bad name (creation of wildcarded names is banned) -; 2) Bad string from GSTRANS -; 3) Bad macro value (control codes not allowed) -; 4) Bad expression from ReadExpression -; 5) Can't find (for deletion) -; 6) Not enough room to create/update it (system heap full) -; 7) Value too long (variables are limited to 256 bytes in length) -; 8) Bad type (update/create) - - - [ DebugSysVars -SysVar_Write0 Entry "r0,r1" - MOV r1, r0 -10 - LDRB r0, [r1], #1 - CMP r0, #" " - EXIT LO - SWI XOS_WriteC - B %BT10 - - ] - -SetVarValue - ; enable IRQs - WritePSRc SVC_mode, r10 - - Entry "r0,r1,r2,r4,r5,r6,r9" - - [ DebugSysVars - SWI XOS_WriteS - = "SetVarVal ",0 - BL SysVar_Write0 - SWI XOS_NewLine - ] - - MOV r9, stack - MOV r10, r4 - - CMP r2, #0 - BMI SetVarVal_DeleteIt - - ; Range check type - CMP r10, #VarType_Code - CMPNE r10, #VarType_LiteralString - ADRHIL r0, ErrorBlock_BadVarType - BHI SetVarValBadExit_Translate - - ; Always expand a VarType_Expanded: - TEQ r10, #VarType_Expanded - BNE SetVarVal_AintExpanded - - ; Process VarType_Expanded - - [ LongCommandLines - MOV r0, stack, LSR #20 ; SVC stack base assumed on 1M boundary - SUB r0, sp, r0, LSL #20 ; amount of stack left - CMP r0, #LongCLISize + 2048 ; insist on 2k left after long buffer - MOVHS r2, #LongCLISize ; ok, got a long buffer - MOVLO r2, #256 ; stack full-ish, use a 256 buffer and hope it's big enough - SUB stack, stack, r2 - | - SUB stack, stack, #256 - MOV r2, #256 - ] - - MOV r0, r1 ; ptr to expression - MOV r1, stack - SWI XOS_EvaluateExpression - BVS SetVarVal_TestVExit - TEQ r1, #0 ; integer? - MOVNE r10, #VarType_LiteralString - MOVEQ r10, #VarType_Number - STREQ r2, [stack] - MOVEQ r2, #4 - STR r10, [r9, #3*4] ; r4 out - MOV r1, stack - LDR r0, [r9, #0*4] - -SetVarVal_AintExpanded - - ; Setting a variable - BL VarFindIt - BNE SetVarVal_NodeAlreadyExists - - ; Node missing.... - - ; Check variable name has no wildcards - SUB r4, r0, #1 -05 - LDRB lr, [r4, #1]! - CMP lr, #"#" - CMPNE lr, #"*" - CMPNE lr, #" " - BHI %BT05 - CMP lr, #"#" - CMPNE lr, #"*" - CMPNE r4, r0 - ADREQL r0, ErrorBlock_BadVarNam - BEQ SetVarValBadExit_Translate ; error no. 1) - - ; R12 index of 1st entry in QuickIndex >= the entry we're interested in - MOV r3, #0 ; To indicate absence of current - B SetVarVal_CreateNode - -SetVarVal_NodeAlreadyExists - MOV r0, r3 ; If already there use that's name in case supplied name wildcarded - LDRB lr, [r4] - TEQ lr, #VarType_Code - BNE SetVarVal_CreateNode - TEQ r10, #VarType_Code - BEQ SetVarVal_CreateNode - - ; Assign non code value to code node - CMP r10, #VarType_Number - BHI SetVarVal_AssignToCodeDoIt - - BLO SetVarVal_AssignStringToCode - - SUB stack, stack, #256 ;buffer - MOV r2, #256 - - ; Assign a number to the code variable - LDRB r0, [r1], #1 - LDRB lr, [r1], #1 - ORR r0, r0, lr, LSL #8 - LDRB lr, [r1], #1 - ORR r0, r0, lr, LSL #16 - LDRB lr, [r1], #1 - ORR r0, r0, lr, LSL #24 - MOV r1, stack - SWI XOS_BinaryToDecimal - - B SetVarVal_AssignToCodeDoIt - -SetVarVal_AssignStringToCode - - [ LongCommandLines - MOV r0, stack, LSR #20 ; SVC stack base assumed on 1M boundary - SUB r0, sp, r0, LSL #20 ; amount of stack left - CMP r0, #LongCLISize + 2048 ; insist on 2k left after long buffer - MOVHS r2, #LongCLISize ; ok, got a long buffer - MOVLO r2, #256 ; stack full-ish, use a 256 buffer and hope it's big enough - SUB stack, stack, r2 - | - SUB stack, stack, #256 - MOV r2, #256 - ] - - ; Expand string to stack frame then do it - MOV r0, r1 - MOV r1, stack - SWI XOS_GSTrans - BVS SetVarVal_TestVExit - ADRCSL r0, ErrorBlock_VarTooLong - BCS SetVarValBadExit_Translate - -SetVarVal_AssignToCodeDoIt - - ADDS r4, r4, #3 + 1 ; skip type, add 3 for ALIGN , clear V - MOV lr, PC - BIC PC, R4, #3 ; complete align and call - - B SetVarVal_TestVExit - - -SetVarVal_CreateNode - ; Create a node - ; - ; r0 -> name (already confirmed non-wildcarded) - ; r1 -> value - ; r2 = length (where appropriate) - ; r3 = this or 0 - ; r10 = type - ; r12 = insertion point - - MOV r5, r1 - MOV r6, r3 - - ; first work out the length of those things we can work the length of - - ; Header and name... - MOV r3, #0 ;accumulator for length of things we know - MOV r1, r0 -10 - LDRB lr, [r1], #1 - ADD r3, r3, #1 - CMP lr, #" " - BHI %BT10 - -;r3 is now name length +1 for terminator - ADD r3, r3, #1 ;add in 1 for the type byte - - ; Deal with number and string type - CMP r10, #VarType_Number - ADDLO r3, r3, #64 ; only an initial guess for the string type - ADDEQ r3, r3, #4 - MOVEQ r2, #4 - BLS SetVarVal_GotInitialLength - - CMP r10, #VarType_Code - ADDEQ r3, r3, #3 ; ALIGN - BICEQ r3, r3, #3 - ADDEQ r3, r3, r2 ; code - BEQ SetVarVal_GotInitialLength - - TEQ r10, #VarType_LiteralString - BEQ %FT20 - - ; Macro - strlen and check the value is vaguely OK - MOV r2, r5 -15 - LDRB lr, [r2], #1 - CMP lr, #" " - BHS %BT15 - TEQ lr, #0 ; must terminate with NUL, CR or LF - TEQNE lr, #10 - TEQNE lr, #13 - ADRNE r0, ErrorBlock_BadMacVal - BNE SetVarValBadExit_Translate - SUB r2, r2, r5 -20 - ADD r3, r3, r2 - ADD r3, r3, #3 ; for the length bytes - -SetVarVal_GotInitialLength - ; r0 -> node's name - ; r2 = value length (Number, Macro and Code) - ; r3 = node length needed (maybe initial guess for Strings) - ; r5 -> value (r1 in) - ; r6 -> name of node to be replaced (0 if no node being replaced) - ; r10 = value's type (String, Number, Macro or Code) - ; r12 -> insertion point - - Push "r0-r2" - [ SysVars_StickyNodes - ADD r3,r3,#SysVars_StickyNode_UnitSize-1 - BIC r3,r3,#SysVars_StickyNode_UnitSize-1 ;so we don't fight sticky routines over sizes - BL SysVars_ClaimVNode - | - BL ClaimSysHeapNode - ] - Pull "r0-r2",VS - BVS SetVarVal_VarNoRoom - - ; Got a heap block - fill it in - - ; Copy name - - MOV r4, r2 - LDR r0,[sp] -25 - LDRB lr, [r0], #1 - CMP lr, #" " - MOVLS lr, #0 - STRB lr, [r4], #1 - BHI %BT25 - - LDR r1,[sp,#8] - ADD sp,sp,#12 ; balances push r0-r2 above - value length (entry r2) now in r1 - - ; Variable's type - TEQ r10, #VarType_LiteralString - MOVEQ lr, #VarType_String - MOVNE lr, r10 - STRB lr, [r4], #1 - - TEQ r10, #VarType_String - BEQ SetVarVal_FillInString - - TEQ r10, #VarType_Code - ADDEQ r4, r4, #3 - BICEQ r4, r4, #3 - TEQNE r10, #VarType_Number - BEQ SetVarVal_CopyR1BytesToR4 - - ; For macro type fill in a length - TEQ r10, #VarType_Macro - SUBEQ r1, r1, #1 ; ghastly fudge to avoid display of terminator - STRB r1, [r4], #1 - MOV r1, r1, ROR #8 - STRB r1, [r4], #1 - MOV r1, r1, ROR #8 - STRB r1, [r4], #1 - MOV r1, r1, ROR #16 - ADDEQ r1, r1, #1 ; undo ghastly fudge - -SetVarVal_CopyR1BytesToR4 - B %FT35 -30 - LDRB lr, [r5], #1 - STRB lr, [r4], #1 -35 - SUBS r1, r1, #1 - BHS %BT30 - - B SetVarVal_NewNodeReady - -SetVarVal_FillInString - ; Here's the real smart bit of code - - ; The idea is this: - ; Instead of GSTransing, we GSInit and GSRead ourselves. When the - ; block gets full expand it and carry on. At the end the block is shrunk to fit. - - ADD r4, r4, #3 ; for the length bytes - MOV r11, r4 ; preserve location of string start for when we've done - MOV r0, r5 ; r1 in - MOV r5, r2 - MOV r2, #0 - SWI XOS_GSInit - BVS SetVarVal_DisasterExpandingString - B %FT45 - -40 - SWI XOS_GSRead - BVS SetVarVal_DisasterExpandingBadString - BCS SetVarVal_StringFinishedExpanding - STRB r1, [r4], #1 - CMP r4, r3 - BLO %BT40 - - ; Run out of room in this block - stretch it - Push "r0-r2" - MOV r0, #HeapReason_ExtendBlock - MOV r2, r5 - MOV r3, #64 ;should be a multiple of StickyNode_UnitSize if SysVars_StickyNodes TRUE - [ SysVars_StickyNodes - BL SysVars_ExpandOrShrinkVNode - | - BL DoSysHeapOpWithExtension - ] - STRVS r0, [sp] - SUBVC lr, r2, r5 - ADDVC r4, r4, lr - ADDVC r11, r11, lr - MOVVC r5, r2 - Pull "r0-r2" - BVS SetVarVal_DisasterExpandingString - -45 - LDR r3, [r5, #-4] ; The heap block's size - [ SysVars_StickyNodes - SUB r3, r3, #8 ; the amount we're allowed to use - | - SUB r3, r3, #4 ; the amount we're allowed to use - ] - ADD r3, r3, r5 ; the block's end - B %BT40 - -SetVarVal_StringFinishedExpanding - - ; Shorten block to required size - MOV r0, #HeapReason_ExtendBlock - [ SysVars_StickyNodes - Push "r4" - ADD r4, r4, #SysVars_StickyNode_UnitSize-1 - BIC r4, r4, #SysVars_StickyNode_UnitSize-1 ;so we don't fight over sticky sizes - SUB r3, r4, r3 - Pull "r4" - MOV r2, r5 - BL SysVars_ExpandOrShrinkVNode - | - SUB r3, r4, r3 - MOV r2, r5 - BL DoSysHeapOpWithExtension - ] - BVS SetVarVal_DisasterExpandingString - - ; Relocate pointers - SUB lr, r2, r5 - ADD r4, r4, lr - ADD r11, r11, lr - - ; Work out ultimate size and store it - SUB lr, r4, r11 - STRB lr, [r11, #-3] - MOV lr, lr, LSR #8 - STRB lr, [r11, #-2] - MOV lr, lr, LSR #8 - STRB lr, [r11, #-1] - -SetVarVal_NewNodeReady - ; r2 -> new node - ; r6 -> old node's name (or is 0 if no old node) - ; r12 = insertion point - - [ DebugSysVars - Push "r0,r1,r2" - SUB sp, sp, #12 - MOV r0, r2 - MOV r1, sp - MOV r2, #12 - SWI XOS_ConvertHex8 - SWI XOS_Write0 - SWI XOS_WriteI+" " - MOV r0, r6 - MOV r1, sp - MOV r2, #12 - SWI XOS_ConvertHex8 - SWI XOS_Write0 - SWI XOS_WriteI+" " - MOV r0, r12 - MOV r1, sp - MOV r2, #12 - SWI XOS_ConvertHex8 - SWI XOS_Write0 - SWI XOS_WriteI+" " - ADD sp, sp, #12 - Pull "r0,r1,r2" - ] - LDR r11, =VariableList - LDR r10, [r11] - [ SysVars_QuickContext - TEQ r10,#0 - ADDNE r10,r10,#SysVars_VTableOffset - ] - MOV r5, r2 - TEQ r6, #0 - BEQ SetVarVal_Insertion - - [ DebugSysVars - SWI XOS_WriteS - = "-straight replace-",0 - ] - - MOV r2, r6 - [ SysVars_StickyNodes - BL SysVars_FreeVNode - | - BL FreeSysHeapNode - ] - B SetVarVal_Replace - -SetVarVal_Insertion - [ DebugSysVars - SWI XOS_WriteS - = "-insert-",0 - ] - TEQ r10, #0 - BNE SetVarVal_PossibleExtend - - [ DebugSysVars - SWI XOS_WriteS - = "-create index-",0 - ] - - [ SysVars_QuickContext - ; SysVars_Vindex_NStart nodes, 1 word for the count, plus data before table - MOV r3, #SysVars_Vindex_NStart*4 - ADD r3, r3, #4+SysVars_VTableOffset - | - MOV r3, #(10*4)+4 ; 10 nodes and 1 word for the count - ] - BL ClaimSysHeapNode ; this is not a variable node (its the index) - BVS SetVarVal_NoRoomForIndex - [ SysVars_QuickContext - MOV r10,#-1 - STR r10, [r2, #SysVars_LastContext] ; initialise last context as invalid - ] - MOV r10, r2 - MOV r4, #0 - B SetVarVal_DoInsertNewBlock - -SetVarVal_PossibleExtend - [ DebugSysVars - SWI XOS_WriteS - = "-extend index-",0 - ] - LDR r4, [r10] - [ SysVars_QuickContext - LDR lr, [r10, #-(4+SysVars_VTableOffset)] ; Block length, from heap block - SUB lr, lr, #4+4+SysVars_VTableOffset ; 4 for heap adjustment, 4 for entry count word, plus name buffer - | - LDR lr, [r10, #-4] ; Block length, from heap block - SUB lr, lr, #4+4 ; 4 for heap adjustment and 4 for entry count word - ] - CMP lr, r4, ASL #2 - BHI SetVarVal_DoInsert ; we've got room with this block - - [ DebugSysVars - SWI XOS_WriteS - = "-do extend-",0 - ] - - MOV r0, #HeapReason_ExtendBlock - [ SysVars_QuickContext - SUB r2, r10, #SysVars_VTableOffset - MOV r3, #SysVars_Vindex_NBump*4 ; room for SysVars_Vindex_NBump more nodes - | - MOV r2, r10 - MOV r3, #40 ; room for 10 more nodes - ] - BL DoSysHeapOpWithExtension ;not a variable node (expanding index) - BVS SetVarVal_NoRoomForIndex - - MOV r10, r2 - -SetVarVal_DoInsertNewBlock - STR r10, [r11] - [ SysVars_QuickContext - ADD r10,r10,#SysVars_VTableOffset - ] -SetVarVal_DoInsert - [ DebugSysVars - SWI XOS_WriteS - = "-doinsert-",0 - ] - ADD r0, r10, r12, ASL #2 ; insertion point - ADD r1, r10, r4, ASL #2 ; rover - B SetVarVal_DoInsertEnd - -SetVarVal_DoInsertStart - LDR lr, [r1], #-4 - STR lr, [r1, #8] - -SetVarVal_DoInsertEnd - CMP r1, r0 - BHS SetVarVal_DoInsertStart - - ADD r4, r4, #1 - STR r4, [r10] - -SetVarVal_Replace - [ DebugSysVars - SWI XOS_WriteS - = "-doreplace-",0 - ] - STR r5, [r10, r12, ASL #2] - [ DebugSysVars - SWI XOS_WriteS - = "-done-",0 - ] - - ; All done - B SetVarVal_TestVExit - -SetVarVal_DeleteIt - BL VarFindIt - - ; Error if not found - ADREQL r0, ErrorBlock_VarCantFind ; V set no. 1) - BEQ SetVarValBadExit_Translate - ; Check if found vartype code that the supplied vartype was code too - LDRB lr, [r4] - TEQ lr, #VarType_Code - BNE %FT80 - - TEQ r10, #VarType_Code - BNE SetVarVal_TestVExit -80 - LDR r11, =VariableList - LDR r10, [r11] - [ SysVars_QuickContext - ADD r10,r10,#SysVars_VTableOffset - ] - LDR r4, [r10] - ADD r0, r10, r12, ASL #2 ; rover - ADD r1, r10, r4, ASL #2 ; end - B SetVarVal_DoRemoveEnd -SetVarVal_DoRemoveStart - LDR lr, [r0, #4]! - STR lr, [r0, #-4] -SetVarVal_DoRemoveEnd - CMP r0, r1 - BLO SetVarVal_DoRemoveStart - MOV r2, r3 - [ SysVars_StickyNodes - BL SysVars_FreeVNode - | - BL FreeSysHeapNode - ] - - ; Reduce number of nodes - SUB r4, r4, #1 - STR r4, [r10] - - ; Construct best guess context ptr to be prev node (if present) - TEQ r12, #1 - SUBHI r12, r12, #1 - LDRHI r3, [r10, r12, ASL #2] - MOVLS r3, #0 - - -SetVarVal_TestVExit - MOV stack, r9 - STRVS r0, [stack] - PullEnv - B SLVK_TestV - -SetVarValBadExit_Translate - [ International - BL TranslateError - ] -SetVarValBadExit_NoTranslate - SETV - B SetVarVal_TestVExit - -SetVarVal_DisasterExpandingString -SetVarVal_NoRoomForIndex - MOV r2, r5 - BL FreeSysHeapNode ;forget stickiness (return node to heap is best here) -SetVarVal_VarNoRoom - ADR r0, ErrorBlock_VarNoRoom - B SetVarValBadExit_Translate - -SetVarVal_DisasterExpandingBadString - Push "r0" ; Save bad string error - MOV r2, r5 - BL FreeSysHeapNode ;forget stickiness (return node to heap is best here) - Pull "r0" - SETV - B SetVarVal_TestVExit - - MakeErrorBlock BadVarType - MakeErrorBlock BadVarNam - MakeErrorBlock VarTooLong - MakeErrorBlock BadMacVal - MakeErrorBlock VarNoRoom - - -; ***************************************************************************** -; Utility routines. - -; ----------------------------------------------------------------------------- -; -; VarFindIt -; -; In -; r0 -> (wildcard) name of variable to find -; r3 = context pointer -; -; Out -; r3 = name pointer -; r4 = pointer after name terminator -; r12 = insertion point (1st node >= this node) -; NE if found, EQ if not found -; -VarFindIt Entry "r0,r1,r2,r5,r6,r7,r8,r9,r10,r11" - -; validate R3 by looking down the list to see if we find it. -; Crude, but effective! - - [ DebugSysVars - SWI XOS_WriteS - = "VarFindIt(",0 - BL SysVar_Write0 - ] - - LDR r9, =VariableList - LDR r9, [r9] - TEQ r9, #0 - [ SysVars_QuickContext - LDRNE r12,[r9,#SysVars_LastContext] - MOVEQ r12,#-1 ;r12 = var table index for last context, or -1 if notvalid/notthere - ADDNE r9,r9,#SysVars_VTableOffset - ] - LDRNE r8, [r9] - MOVEQ r8, #0 - TEQ r3, #0 - BEQ %FT20 - - [ DebugSysVars - SWI XOS_WriteS - = "-scan-",0 - ] - ; r3 non-zero - scan list for entry - - [ SysVars_QuickContext - ;massive short cut - see if context is the last context we returned - CMP r12, r8 ;if not valid, or higher than current number of vars, forget it - BHI %FT04 - LDR lr, [r9, r12, ASL #2] - CMP lr, r3 - BEQ %FT70 -04 - ;no such luck - scan list anyway - ] - - ADD r12, r8, #1 - B %FT10 -05 - LDR lr, [r9, r12, ASL #2] - CMP lr, r3 - BEQ %FT70 ; continue scan down list -10 - SUBS r12, r12, #1 - BHI %BT05 - -20 - [ DebugSysVars - SWI XOS_WriteS - = "-wildcheck-",0 - ] - ; not found in scan - check for name being wildcarded - - MOV r10, r0 -25 - LDRB lr, [r10], #1 - TEQ lr, #"*" - TEQNE lr, #"#" - BEQ %FT65 - CMP lr, #" " - BHI %BT25 - - [ DebugSysVars - SWI XOS_WriteS - = "-bchop-",0 - ] - - ; Name not wildcarded - do binary chop search - ORRS r7, r8, r8, LSR #1 - ORR r7, r7, r7, LSR #2 - ORR r7, r7, r7, LSR #4 - ORR r7, r7, r7, LSR #8 - ORR r7, r7, r7, LSR #16 - BICS r7, r7, r7, LSR #1 ; least 2^n <= number of entries - MOV r6, #0 - - B %FT60 -40 - ADD r5, r6, r7 - CMP r5, r8 - BHI %FT55 - - MOV r1, r0 - LDR r4, [r9, r5, ASL #2] - -45 - LDRB r2, [r1], #1 - CMP r2, #" " - MOVLS r2, #0 - LDRB r3, [r4], #1 - CMP r3, #" " - MOVLS r3, #0 - UpperCase R2,LR - UpperCase R3,LR - CMP r3, r2 - BNE %FT50 - CMP r3, #0 - BNE %BT45 - -50 - MRSHS r10, CPSR ; preserve last HS result we got - MOVHS r11, r4 - MOVLO r6, r5 -55 - MOVS r7, r7, LSR #1 -60 - BNE %BT40 - - ; We always want the element above. - ; If r6<r8 then we want the preserved result - ; else we want the result HI - ADD r6, r6, #1 - CMP r6, r8 - LDRLS r3, [r9, r6, ASL #2] - [ SysVars_QuickContext - ASSERT SysVars_LastContext = SysVars_VTableOffset - 4 - STRLS r6, [r9, #-4] ;save var table index for context we're returning, in LastContext - ] - MOVLS r4, r11 - MOVHI r3, #0 - MSRLS CPSR_f, r10 - - [ DebugSysVars - SWI XOS_WriteS - = "-complete-",0 - SWI XOS_NewLine - ] - MOV r12, r6 - TOGPSR Z_bit, lr - EXIT - -65 - [ DebugSysVars - SWI XOS_WriteS - = "-listscan-",0 - SWI XOS_NewLine - ] - ; Scan down list looking for wildmatch - MOV r12, #0 -70 - ADD r12, r12, #1 - CMP r12, r8 - BHI %FT90 ; end of list reached - LDR r4, [r9, r12, ASL #2] - BL WildMatch ; trashes r10,r11 - BNE %BT70 - -80 - [ DebugSysVars - SWI XOS_WriteS - = "-complete-",0 - SWI XOS_NewLine - ] - ; Found - ; r4->name end - ; r12 = entry number - LDR r3, [r9, r12, ASL #2] - [ SysVars_QuickContext - ASSERT SysVars_LastContext = SysVars_VTableOffset - 4 - STR r12, [r9, #-4] ;save var table index for context we're returning, in LastContext - ] - MOVS r12, r12 ; set NE - EXIT - -90 - ; Not found - [ DebugSysVars - SWI XOS_WriteS - = "-not found-",0 - SWI XOS_NewLine - ] - MOV r12, #1 - MOVS r3, #0 - EXIT - -WildMatch ROUT -; In : R0 is wildcard spec ptr, R4 is name ptr. -; Wild Terminators are any ch <=" ", name terminator 0 -; Wildcards are *, # -; Out : EQ/NE for match (EQ if matches) -; R4 points after name terminator for found -; R0 preserved, R10, 11 corrupted - - Push "R0-R3" - MOV R11, #0 ; this is the wild backtrack pointer - MOV R3, #0 ; and this is the name backtrack ptr. -01 LDRB R1, [R0], #1 ; nextwild - CMP R1, #"*" - BEQ %FT02 ; IF nextwild = "*" - LDRB R2, [R4], #1 ; nextname - CMP R2, #0 - BEQ %FT03 - UpperCase R1, R10 - UpperCase R2, R10 - CMP R1, R2 ; IF nextwild=nextname - CMPNE R1, #"#" ; OR nextwild = # (terminator checked already) - BEQ %BT01 ; THEN LOOP (stepped already) - MOV R0, R11 ; try backtrack - MOVS R4, R3 ; if * had at all - BNE %FT02 - CMP PC, #0 ; set NE -04 Pull "R0-R3" ; return NE (failed) - MOV PC, lr - -03 CMP R1, #" " ; name terminated : has wildcard? - BHI %BA04 ; note HI has NE set. - CMP R1, R1 ; set EQ - Pull "R0-R3" - MOV PC, lr - -02 MOV R11, R0 ; wild backtrack ptr is char after * - LDRB R1, [R0], #1 ; step wild - CMP R1, #"*" - BEQ %BT02 ; fujj ** - UpperCase R1, R10 -05 LDRB R2, [R4], #1 ; step name - CMP R2, #0 ; terminator? - BEQ %BT03 - UpperCase R2, R10 - CMP R1, R2 - CMPNE R1, #"#" ; match if # - BNE %BT05 - MOV R3, R4 ; name backtrack ptr is char after match - B %BT01 ; LOOP - - - [ Oscli_QuickAliases - -;routines to speed up alias checking for OS_CLI - -;VarFindIt_QA - similar to VarFindIt -; -; In -; r3 -> non-wildcarded, already upper-cased name of var to find -; will be of form ALIAS$<whatever> -; -; Out -; r5 = name pointer (equivalent to r3 for VarFindIt -; r6 = pointer after name terminator (equivalent to r4 for VarFindIt) -; r7 = insertion point (equivalent to r12 for VarFindIt) -; NE if found, EQ if not found -; -VarFindIt_QA ROUT - Push "r0,r1,r2,r3,r4,r8,r9,r10,r11,LR" - MOV r0, r3 - LDR r9, =VariableList - LDR r9, [r9] - TEQ r9,#0 - BEQ %FT99 ;exit with EQ (not found) - [ SysVars_QuickContext - ADD r9,r9,#SysVars_VTableOffset - ] - LDR r8, [r9] - - ; do binary chop search - ORRS r7, r8, r8, LSR #1 - ORR r7, r7, r7, LSR #2 - ORR r7, r7, r7, LSR #4 - ORR r7, r7, r7, LSR #8 - ORR r7, r7, r7, LSR #16 - BICS r7, r7, r7, LSR #1 ; least 2^n <= number of entries - MOV r6, #0 - - B %FT60 -40 - ADD r5, r6, r7 - CMP r5, r8 - BHI %FT55 - - MOV r1, r0 - LDR r4, [r9, r5, ASL #2] - -45 - LDRB r2, [r1], #1 - CMP r2, #" " - MOVLS r2, #0 - LDRB r3, [r4], #1 - CMP r3, #" " - MOVLS r3, #0 - UpperCase R3,LR - CMP r3, r2 - BNE %FT50 - CMP r3, #0 - BNE %BT45 - -50 - MRSHS r10, CPSR ; preserve last HS result we got - MOVHS r11, r4 - MOVLO r6, r5 -55 - MOVS r7, r7, LSR #1 -60 - BNE %BT40 - - ; We always want the element above. - ; If r6<r8 then we want the preserved result - ; else we want the result HI - ADD r6, r6, #1 - CMP r6, r8 - LDRLS r5, [r9, r6, ASL #2] -;don't want to save context in this version of routine -; [ SysVars_QuickContext -; ASSERT SysVars_LastContext = SysVars_VTableOffset - 4 -; STRLS r6, [r9, #-4] ;save var table index for context we're returning, in LastContext -; ] - MOV r7, r6 - MOVLS r6, r11 - MOVHI r5, #0 - MSRLS CPSR_f, r10 - - TOGPSR Z_bit, lr -99 - Pull "r0,r1,r2,r3,r4,r8,r9,r10,r11,PC" - - - ] ;Oscli_QuickAliases - - [ SysVars_StickyNodes -; -; SysVars_ClaimVNode -; -; entry: R3 = size required -; exit: R2 = address of allocated node, or V set for error -; -; if R3 > max sticky size, just delegates to ClaimSysHeapNode -; if R3 <= max sticky size, rounds up to next unit size, and attempts to pick -; up sticky node of that size - if not found, gets one from heap (now of size that can -; stick on free) -; -SysVars_ClaimVNode ROUT - Push "r0,r1,r3,LR" - CMP r3,#SysVars_StickyNode_MaxSize - BHI %FT80 ;too big for sticky node - ADD r3,r3,#SysVars_StickyNode_UnitSize-1 - BIC r3,r3,#SysVars_StickyNode_UnitSize-1 ;round up to unit size - MOV r1,#SysVars_StickyPointers - LDR r2,[r1,r3,LSR #(SysVars_StickyNode_Log2US-2)] ;sticky pointer for this size - CMP r2,#0 ;also clears V - BEQ %FT80 - MOV LR,#0 - STR LR,[r1,r3,LSR #(SysVars_StickyNode_Log2US-2)] ;used it - [ mjsSysHeapNodesTrace - Push "r0-r2" - MOV r0,#0 - LDR r1,[r0,#mjsSHNT_vcs_total] - ADD r1,r1,#1 - STR r1,[r0,#mjsSHNT_vcs_total] - Pull "r0-r2" - ] - Pull "r0,r1,r3,PC" -80 BL ClaimSysHeapNode - STRVS r0,[SP] - [ mjsSysHeapNodesTrace - Push "r0-r2" - MOV r0,#0 - LDR r1,[r0,#mjsSHNT_vch_total] - ADD r1,r1,#1 - STR r1,[r0,#mjsSHNT_vch_total] - Pull "r0-r2" - ] - Pull "r0,r1,r3,PC" - -; -; SysVars_FreeVNode -; -; entry: R2 = address of node to free (must be valid) -; exit: - -; OR V set, error -; -; - checks size of node (uses internal knowledge of Heap blocks - naughty!) -; - if size is a sticky size, and the corresponding sticky pointer is 0, retains it, -; else delegates to FreeSysHeapNode -; -SysVars_FreeVNode - Push "r0,r1,r3,LR" - LDR r1,[r2,#-4] ;pick up OS_Heap's size word - SUB r1,r1,#8 ;sticky sizes will be 8 less than heap sizes - CMP r1,#SysVars_StickyNode_MaxSize ;is it too big? - BHI %FT80 - TST r1,#SysVars_StickyNode_UnitSize-1 ;is it a multiple of unit size - BNE %FT80 - MOV r3,#SysVars_StickyPointers - LDR LR,[r3,r1,LSR #(SysVars_StickyNode_Log2US-2)] ;sticky pointer for this size - CMP LR,#0 - STREQ r2,[r3,r1,LSR #(SysVars_StickyNode_Log2US-2)] ;stick! -80 - [ mjsSysHeapNodesTrace - Push "r0-r2" - MOV r0,#0 - LDREQ r1,[r0,#mjsSHNT_vfs_total] - LDRNE r1,[r0,#mjsSHNT_vfh_total] - ADD r1,r1,#1 - STREQ r1,[r0,#mjsSHNT_vfs_total] - STRNE r1,[r0,#mjsSHNT_vfh_total] - Pull "r0-r2" - ] - BLNE FreeSysHeapNode - STRVS r0,[SP] - Pull "r0,r1,r3,PC" - -; -; SysVars_ExpandOrShrinkVNode -; -; entry: R2 = address of block -; R3 = change of size required in bytes (signed integer) -; exit: R2 = address of block, which may have changed (block moved/copied) -; OR V set, error returned -; -; - checks size of node (uses internal knowledge of Heap blocks - naughty!) -; - assumes all VNodes currently less than MaxSize and of sticky size *must* be stickily -; allocated nodes (so that maximum current size that could be presumed by client is heap -; size minus 8, rather than minus 4) -; - if new size is small enough to be a sticky node, attempts to return a sticky node, -; without doing an OS_Heap grow or shrink, else delegates to DoSysHeapOpWithExtension -; -SysVars_ExpandOrShrinkVNode - Push "r0,r1,r3-r6,LR" - LDR r5,[r2,#-4] ;pick up OS_Heap's size word - SUB r5,r5,#4 ;usable sizes are 4 less than heap sizes - ADD r4,r5,r3 ;putative new size - CMP r4,#SysVars_StickyNode_MaxSize ;is it too big? - BHI %FT90 - SUB r6,r5,#4 ;sticky sizes will be 8 less than heap sizes - SUB r4,r4,#4 - ADD r4,r4,#SysVars_StickyNode_UnitSize-1 - BIC r4,r4,#SysVars_StickyNode_UnitSize-1 ;round up to unit size - CMP r4,r6 ;same as current size? - BEQ %FT55 - MOV r1,#SysVars_StickyPointers - LDR LR,[r1,r4,LSR #(SysVars_StickyNode_Log2US-2)] ;sticky pointer for this size - CMP LR,#0 - BEQ %FT40 - MOV r3,#0 - STR r3,[r1,r4,LSR #(SysVars_StickyNode_Log2US-2)] ;used it - MOV r5,r2 - MOV r2,LR - B %FT50 -40 - MOV r5,r2 - MOV r3,r4 - BL SysVars_ClaimVNode - BVS %FT95 -50 ;copy min(r6,r4) bytes (multiple of 8) from old node at r5 to new node at r2 - CMP r4,r6 - MOVLO r6,r4 - MOV r3,r2 - MOV LR,r5 -52 - LDMIA LR!,{r0,r1} - STMIA r3!,{r0,r1} - SUBS r6,r6,#8 - BGT %BT52 - MOV r6,r2 - MOV r2,r5 - BL SysVars_FreeVNode - MOV r2,r6 - BVS %FT95 -55 - [ mjsSysHeapNodesTrace - Push "r0-r2" - MOV r0,#0 - LDR r1,[r0,#mjsSHNT_vxs_total] - ADD r1,r1,#1 - STR r1,[r0,#mjsSHNT_vxs_total] - Pull "r0-r2" - ] - CLRV - Pull "r0,r1,r3-r6,PC" -90 - [ mjsSysHeapNodesTrace - Push "r0-r2" - MOV r0,#0 - LDR r1,[r0,#mjsSHNT_vxh_total] - ADD r1,r1,#1 - STR r1,[r0,#mjsSHNT_vxh_total] - Pull "r0-r2" - ] - MOV r0,#HeapReason_ExtendBlock - BL DoSysHeapOpWithExtension -95 - STRVS r0,[SP] - Pull "r0,r1,r3-r6,PC" - - ] ;SysVars_StickyNodes - - LTORG - - END diff --git a/s/Arthur3 b/s/Arthur3 deleted file mode 100644 index 9861f131..00000000 --- a/s/Arthur3 +++ /dev/null @@ -1,2478 +0,0 @@ -; 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 => Arthur3 - -; the IF command - -IF_Code ROUT - Push "R2, lr" - LDR R2, =GeneralMOSBuffer -01 - LDRB R1, [R0], #1 - STRB R1, [R2], #1 - CMP R1, #10 - CMPNE R1, #13 - CMPNE R1, #0 - BEQ NoTHEN - CMP R1, #" " - BNE %BT01 - LDRB R1, [R0] - CMP R1, #"t" - CMPNE R1, #"T" - BNE %BT01 - LDRB R1, [R0, #1] - CMP R1, #"h" - CMPNE R1, #"H" - BNE %BT01 - LDRB R1, [R0, #2] - CMP R1, #"e" - CMPNE R1, #"E" - BNE %BT01 - LDRB R1, [R0, #3] - CMP R1, #"n" - CMPNE R1, #"N" - BNE %BT01 - LDRB R1, [R0, #4] - CMP R1, #" " - CMPNE R1, #13 - CMPNE R1, #10 - CMPNE R1, #0 - BNE %BT01 - MOV R1, #13 - STRB R1, [R2, #-1] - ADD R0, R0, #4 ; skip THEN - Push "R0" - LDR R0, =GeneralMOSBuffer - MOV R2, #-1 ; integers only mate - SWI XOS_EvaluateExpression - BVS WantInteger - Pull "R1" - CMP R2, #0 - BEQ %FT02 ; false - LDR R2, =GeneralMOSBuffer -03 - LDRB R0, [R1], #1 - STRB R0, [R2], #1 - CMP R0, #10 - CMPNE R0, #13 - CMPNE R0, #0 - BEQ %FT04 - CMP R0, #" " - BLEQ %FT05 - BNE %BT03 -04 - MOV R0, #13 - STRB R0, [R2, #-1] - LDR R0, =GeneralMOSBuffer -07 - SWI XOS_CLI -06 - Pull "R2, PC" - -05 - LDRB R0, [R1] - CMP R0, #"e" - CMPNE R0, #"E" - MOVNE PC, lr - LDRB R0, [R1, #1] - CMP R0, #"l" - CMPNE R0, #"L" - MOVNE PC, lr - LDRB R0, [R1, #2] - CMP R0, #"s" - CMPNE R0, #"S" - MOVNE PC, lr - LDRB R0, [R1, #3] - CMP R0, #"e" - CMPNE R0, #"E" - MOVNE PC, lr - LDRB R0, [R1, #4] - CMP R0, #" " - CMPNE R1, #13 - CMPNE R1, #10 - CMPNE R1, #0 - MOV PC, lr - -02 - LDRB R0, [R1], #1 - CMP R0, #10 - CMPNE R0, #13 - CMPNE R0, #0 - BEQ %BT06 - CMP R0, #" " - BLEQ %BT05 - BNE %BT02 - ADD R0, R1, #4 - B %BT07 - -NoTHEN ROUT - ADR R0, %FT01 - [ International - BL TranslateError - ] -IfError - SETV - Pull "R2, pc" -01 - & ErrorNumber_Syntax - = "NoThen:There is no THEN", 0 - ALIGN - -WantInteger ROUT - CMP R1, #0 - Pull "R1" - BNE %FT10 - SETV - Pull "R2, pc" ; integer returned, so leave expranal error there -10 - ADR R0, %FT01 - [ International - BL TranslateError - ] - B IfError -01 - & ErrorNumber_Syntax - = "IsString:Expression is a string", 0 - ALIGN - -;************************************************************************ -; the expression analysis SWI - -; truth values -Expr_True * -1 -Expr_False * 0 - -; Type symbols - -type_Integer * 0 -type_String * 1 -type_Operator * 2 - -; operators : -; single char syms have their ascii value -op_Bra * "(" ; 40 -op_Ket * ")" ; 41 -op_Times * "*" ; 42 -op_Plus * "+" ; 43 -op_Minus * "-" ; 45 -op_Divide * "/" ; 47 -op_LT * "<" ; 60 -op_EQ * "=" ; 61 -op_GT * ">" ; 62 - -; now fill in some gaps - -op_NE * 44 ; <> -op_STR * 46 ; STR -op_GE * 48 ; >= -op_LE * 49 ; <= -op_RShift * 50 ; >> -op_LShift * 51 ; << -op_AND * 52 ; AND -op_OR * 53 ; OR -op_EOR * 54 ; EOR -op_NOT * 55 ; NOT -op_Right * 56 ; RIGHT -op_Left * 57 ; LEFT -op_MOD * 58 ; MOD -op_Bottom * 59 -op_VAL * 63 ; VAL -op_LRShift * 64 ; >>> -op_LEN * 65 ; LEN - -; TMD 12-Sep-89 - add separate tokens for monadic versions of + and - - -op_UnaryPlus * 66 ; unary plus -op_UnaryMinus * 67 ; unary minus - -; so 40-67 inclusive is filled. - - MACRO -$label ePush $reglist -$label STMFD R11!, {$reglist} - CMP R11, R10 - BLE StackOFloErr - MEND - - MACRO -$label ePull $reglist, $writeback, $cc - [ "$writeback" = "" - LDM$cc.FD R11!, {$reglist} - | - LDM$cc.FD R11, {$reglist} - ] - MEND - -;************************************************************************* -; SWI EvalExp. -; In : R0 -> string -; R1 -> buffer -; R2 maxchars -; Out : R0 unchanged. -; IF R1 = 0, R2 is an integer -; IF R1<>0, buffer has a string, length in R2. -; V set if bad expression, buffer overflow -;************************************************************************* - -ExprBuffOFlo ROUT - ADRL R0, ErrorBlock_BuffOverflow - [ International - BL TranslateError - ] - STR R0, [stack] - Pull "R0-R4, lr" - B SLVK_SetV - -ReadExpression ROUT - Push "R0-R4, lr" - CLRPSR I_bit, R12 ; interrupts on, ta. - LDR R12, =ExprWSpace - STR R13, ExprSVCstack - [ LongCommandLines - LDR R1, =ExprBuff - MOV R2, #LongCLISize - | - ADR R1, ExprBuff - MOV R2, #256 - ] - ORR R2, R2, #(1 :SHL: 30) :OR: (1 :SHL: 31) - SWI XOS_GSTrans ; No | transformation, no " or space termination. - ; so can never go wrong! - BCS ExprBuffOFlo - MOV R0, #13 - STRB R0, [R1, R2] - - LDR R11, =ExprStackStart - LDR R10, =ExprStackLimit - MOV R0, #0 - STRB R0, exprBracDif - MOV R0, #type_Operator - MOV R2, #op_Bottom - STRB R2, tos_op - STMFD R11!, {R0, R2} ; push "bottom" - -; All set : now chug round items. - -01 - BL GetFactor - CMP R0, #type_Operator - BNE %BT01 - - CMP R2, #op_Ket - BNE %FT02 - LDRB R3, exprBracDif - [ {TRUE} ; TMD 11-Sep-89 - save an instruction - SUBS R3, R3, #1 - BCC BadBraErr - | - CMP R3, #0 - BEQ BadBraErr - SUB R3, R3, #1 - ] - STRB R3, exprBracDif - -03 - LDRB R3, tos_op - CMP R3, #op_Bra - BEQ %FT55 - BL compile_top_op - B %BT03 -55 - ePull "R0, R2" - CMP R0, #type_Operator - BEQ MissingOpErr - CMP R0, #type_String - BLEQ Pull_String - Push "R0, R2" - ePull "R0, R2" - CMP R0, #type_Operator - BNE MissingOrErr ; discard "(" - ePull "R0, R2", No - CMP R0, #type_Operator - BNE MissingOrErr - STRB R2, tos_op ; reset tosop - Pull "R0, R2" - CMP R0, #type_String - BLEQ Push_String - ePush "R0, R2" ; move temp result down. - B %BT01 - -02 - CMP R2, #op_Bra - LDREQB R3, exprBracDif - ADDEQ R3, R3, #1 - STREQB R3, exprBracDif ; bracdif +:= 1 - -; TMD 12-Sep-89 - now check for unary plus or minus - - CMP R2, #op_Plus ; if EQ then CS - TEQNE R2, #(op_Minus :SHL: 2),2 ; if EQ then CC - ePull "R0, R4", No, EQ ; if +/- and top item is op - TEQEQ R0, #type_Operator, 0 ; then it's unary plus/minus - BNE %FT10 ; else normal - - MOVCS R2, #op_UnaryPlus ; CS => unary plus - MOVCC R2, #op_UnaryMinus ; CC => unary minus -10 - -; WHILE lp (tos.op) > rp (itemtype) DO compile.top.op () - - ADR R4, rightprectab-op_Bra - LDRB R4, [R4, R2] -04 - ADR R0, leftprectab-op_Bra - LDRB R3, tos_op - LDRB R0, [R0, R3] - CMP R0, R4 - BLE %FT75 - BL compile_top_op - B %BT04 -75 - MOV R0, #type_Operator - ePush "R0, R2" ; push (operator) - STRB R2, tos_op - CMP R2, #op_Bottom - BNE %BT01 - -; check proper expr, return it. -; should have bum/result/bum on stack. - - ePull "R0, R2" ; this one's forced to be bottom - ePull "R0, R2" - CMP R0, #type_Operator - BEQ MissingOpErr - CMP R0, #type_String - BLEQ Pull_String - Push "R0, R2" - ePull "R0, R2" - CMP R0, #type_Operator ; if an op's there, it has to be bottom - Pull "R1, R2" - BNE MissingOpErr - - Pull "R0, R3, R4" ; original R1, R2 -> R3, R4 - CMP R1, #type_Integer - Pull "R3, R4, lr", EQ - ExitSWIHandler EQ - CMP R4, R2 - BGE ExprBuffOK - MOV R2, R4 ; no chars to move. - ADRL R0, BufferOFloError - LDR lr, [stack, #4*2] - ORR lr, lr, #V_bit - STR lr, [stack, #4*2] -ExprBuffOK - MOV R1, R3 - LDR R4, =exprSTRACC ; get ptr to it. - Push "R2" -06 - SUBS R2, R2, #1 - LDRPLB R3, [R4, R2] - STRPLB R3, [R1, R2] - BPL %BT06 - Pull "R2-R4, lr" - ExitSWIHandler - -leftprectab -; Bra Ket Time Plus NE Minu STR Divi GE LE RShi LShift - = 2, 1, 8, 7, 6, 7, 9, 8, 6, 6, 6, 6 -; AND OR EOR NOT Righ Left MOD Bott LT EQ GT VAL LRSh - = 5, 4, 4, 9, 9, 9, 8, 1, 6, 6, 6, 9, 6 -; LEN Un+ Un- - = 9, 9, 9 - -rightprectab -; Bra Ket Time Plus NE Minu STR Divi GE LE RShi LShift - = 11, 0, 7, 6, 5, 6, 10, 7, 5, 5, 5, 5 -; AND OR EOR NOT Righ Left MOD Bott LT EQ GT VAL LRSh - = 4, 3, 3, 10, 10, 10, 7, 1, 5, 5, 5, 10, 5 -; LEN Un+ Un- - = 10, 10, 10 - - ALIGN - -;***************************************************************************** - -compile_top_op ROUT -; corrupts the flags - Push "R2-R4, lr" - ePull "R0, R2" - CMP R0, #type_Operator - BEQ MissingOpErr ; everybody needs a rhs op - CMP R0, #type_String - BLEQ Pull_String - ePull "R3, R4" ; must be tosop - CMP R3, #type_Operator - BNE MissingOrErr - - SUB R4, R4, #op_Bra - ADR R3, Operator_Dispatch - LDR R4, [R3, R4, LSL #2] - ADD PC, R3, R4 - -DispatchReturn - ePull "R3, R4", No ; pull with no writeback - CMP R3, #type_Operator - BNE MissingOrErr - STRB R4, tos_op - CMP R0, #type_String - BLEQ Push_String - ePush "R0, R2" ; temp val -> stack - - Pull "R2-R4, PC" - -; the routines in this table are entered with one operand popped, -; any other op on stack ready to pop. -; Return with temp val set up (R0, R2 and maybe exprSTRACC) -; Can use R0, R2-R4 as reqd - -Operator_Dispatch - & Bra_Code - Operator_Dispatch - & 0 ; Ket_Code - Operator_Dispatch - can't happen - & Times_Code - Operator_Dispatch - & Plus_Code - Operator_Dispatch - & NE_Code - Operator_Dispatch - & Minus_Code - Operator_Dispatch - & STR_Code - Operator_Dispatch - & Divide_Code - Operator_Dispatch - & GE_Code - Operator_Dispatch - & LE_Code - Operator_Dispatch - & RShift_Code - Operator_Dispatch - & LShift_Code - Operator_Dispatch - & AND_Code - Operator_Dispatch - & OR_Code - Operator_Dispatch - & EOR_Code - Operator_Dispatch - & NOT_Code - Operator_Dispatch - & Right_Code - Operator_Dispatch - & Left_Code - Operator_Dispatch - & MOD_Code - Operator_Dispatch - & 0 ; Bottom_Code - Operator_Dispatch - can't happen - & LT_Code - Operator_Dispatch - & EQ_Code - Operator_Dispatch - & GT_Code - Operator_Dispatch - & VAL_Code - Operator_Dispatch - & LRShift_Code- Operator_Dispatch - & LEN_Code- Operator_Dispatch - & UnPlus_Code- Operator_Dispatch - & UnMinus_Code- Operator_Dispatch - -;************************************************************************** -; dispatch routines - -;-------------------------------------------------------------------------- -; monadic operators - -VAL_Code ROUT ; VAL string (VAL integer is NOP) -UnPlus_Code ROUT ; + integer (same code as VAL) - CMP R0, #type_String - BLEQ StringToInteger - B DispatchReturn - -STR_Code ROUT ; STR integer (STR string is NOP) - CMP R0, #type_Integer - BLEQ IntegerToString - B DispatchReturn - -LEN_Code ROUT ; LEN string - CMP R0, #type_Integer - BLEQ IntegerToString - MOV R0, #type_Integer ; and R2 is length! - B DispatchReturn - -NOT_Code ROUT ; NOT integer - CMP R0, #type_String - BLEQ StringToInteger - MVN R2, R2 - B DispatchReturn - -UnMinus_Code ROUT ; - integer - CMP R0, #type_String - BLEQ StringToInteger - RSB R2, R2, #0 - B DispatchReturn - -;-------------------------------------------------------------------------- -; diadic plus - -Plus_Code ROUT ; integer+integer ; string+string - ePull "R3, R4" -; CMP R3, #type_Operator ; can't be operator as unary plus -; BEQ %FT01 ; is separately dispatched now - CMP R0, #type_String - BEQ %FT02 - CMP R3, #type_String - BLEQ PullStringToInteger ; in R4 - ADD R2, R2, R4 - B DispatchReturn - -02 - CMP R3, #type_String - BEQ %FT03 - BL StringToInteger - ADD R2, R2, R4 - B DispatchReturn - -03 - ADD R0, R2, R4 - [ LongCommandLines - CMP R0, #LongCLISize - BGE StrOFloErr - | - CMP R0, #255 - BGT StrOFloErr - ] - LDR R3, =exprSTRACC - Push "R0" ; new length - ADD R0, R3, R0 - ADD R3, R3, R2 - ; copy R2 bytes from --(R3) to --(R0) -04 - SUBS R2, R2, #1 - LDRGEB R4, [R3, #-1]! - STRGEB R4, [R0, #-1]! - BGE %BT04 -; R0-exprSTRACC is no of chars in stacked string - LDR R3, =exprSTRACC - SUB R0, R0, R3 -05 - SUBS R0, R0, #1 - LDRGEB R2, [R11], #1 - STRGEB R2, [R3], #1 - BGE %BT05 - ADD R11, R11, #3 - BIC R11, R11, #3 ; realign stack - Pull "R2" - MOV R0, #type_String - B DispatchReturn - -Minus_Code ROUT ; integer-integer -; ePull "R3, R4", No ; can't be unary minus - this is -; CMP R3, #type_Operator ; separately dispatched now -; BEQ %FT01 - BL TwoIntegers - SUB R2, R4, R2 - B DispatchReturn - -;--------------------------------------------------------------------------- -; integer pair only : maths - -Times_Code ROUT ; integer*integer - BL TwoIntegers - MOV R3, R2 - MUL R2, R4, R3 ; get R3*R4->R2 - B DispatchReturn - -MOD_Code ROUT ; integer MOD integer - Push "R5" - MOV R5, #&80000000 - B DivModCommon - -Divide_Code ROUT ; integer/integer - Push "R5" - MOV R5, #0 -DivModCommon - BL TwoIntegers ; want R4/R2 - CMP R2, #0 - Pull "R5", EQ - BEQ DivZeroErr - RSBMI R2, R2, #0 - EORMIS R5, R5, #1 - EORMI R5, R5, #1 ; oops-wanted MOD, ignore this sign - CMP R4, #0 - EORMI R5, R5, #1 - RSBMI R4, R4, #0 - DivRem R3, R4, R2, R0 ; R3 := R4 DIV R2; R4 := R4 REM R2 - MOVS R5, R5, LSL #1 ; CS if MOD, NE if -ve - MOVCS R2, R4 - MOVCC R2, R3 - RSBNE R2, R2, #0 - MOV R0, #type_Integer - Pull "R5" - B DispatchReturn - -;--------------------------------------------------------------------------- -; integer pair only : logical - -AND_Code ROUT ; integer AND integer - BL TwoIntegers - AND R2, R2, R4 - B DispatchReturn - -OR_Code ROUT ; integer OR integer - BL TwoIntegers - ORR R2, R2, R4 - B DispatchReturn - -EOR_Code ROUT ; integer EOR integer - BL TwoIntegers - EOR R2, R2, R4 - B DispatchReturn - -;---------------------------------------------------------------------------- -; mixed operands - -Right_Code ROUT ; string RIGHT integer - CMP R0, #type_Integer - BLNE StringToInteger - MOV R4, R2 - ePull "R0, R2" - CMP R0, #type_String - BNE %FT01 - BL Pull_String -02 ; string in stracc, R2 chars available, R4 chars wanted. - CMP R2, R4 - BLO DispatchReturn ; ignore if R4 -ve or bigger than available - LDR R0, =exprSTRACC - ADD R3, R0, R2 - SUB R3, R3, R4 ; mov from R3 to R0, R4 bytes -03 - LDRB R2, [R3], #1 - SUBS R4, R4, #1 - STRGEB R2, [R0], #1 - BGE %BT03 - LDR R2, =exprSTRACC - SUB R2, R0, R2 ; get length back. - MOV R0, #type_String - B DispatchReturn - -01 - CMP R0, #type_Operator - BEQ MissingOpErr - BL IntegerToString - B %BT02 - -Left_Code ROUT ; string LEFT integer - CMP R0, #type_Integer - BLNE StringToInteger - MOV R4, R2 - ePull "R0, R2" - CMP R0, #type_String - BNE %FT01 - BL Pull_String -02 - CMP R4, R2 - MOVLO R2, R4 ; only use new length if +ve and < current length - B DispatchReturn - -01 - CMP R0, #type_Operator - BEQ MissingOpErr - BL IntegerToString - B %BT02 - -;----------------------------------------------------------------------- -; relational operators - -EQ_Code ROUT ; integer = integer ; string = string - BL Comparison - MOVEQ R2, #Expr_True - MOVNE R2, #Expr_False - B DispatchReturn - -NE_Code ROUT ; integer<>integer ; string<>string - BL Comparison - MOVNE R2, #Expr_True - MOVEQ R2, #Expr_False - B DispatchReturn - -GT_Code ROUT ; integer > integer ; string>string - BL Comparison - MOVGT R2, #Expr_True - MOVLE R2, #Expr_False - B DispatchReturn - -LT_Code ROUT ; integer < integer ; string<string - BL Comparison - MOVLT R2, #Expr_True - MOVGE R2, #Expr_False - B DispatchReturn - -GE_Code ROUT ; integer >= integer ; string>=string - BL Comparison - MOVGE R2, #Expr_True - MOVLT R2, #Expr_False - B DispatchReturn - -LE_Code ROUT ; integer <= integer ; string<=string - BL Comparison - MOVLE R2, #Expr_True - MOVGT R2, #Expr_False - B DispatchReturn - -;-------------------------------------------------------------------------- -; shift operators - -RShift_Code ROUT ; integer >> integer - BL TwoIntegers - CMP R2, #0 - RSBLT R2, R2, #0 - BLT NegRShift -NegLShift - CMP R2, #32 - MOVGE R2, R4, ASR #31 ; sign extend all through - MOVLT R2, R4, ASR R2 - B DispatchReturn - -LRShift_Code ROUT ; integer >>> integer - BL TwoIntegers - CMP R2, #0 - RSBLT R2, R2, #0 - BLT NegRShift - CMP R2, #32 - MOVGE R2, #0 - MOVLT R2, R4, LSR R2 - B DispatchReturn - -LShift_Code ROUT ; integer << integer - BL TwoIntegers - CMP R2, #0 - RSBLT R2, R2, #0 - BLT NegLShift -NegRShift - CMP R2, #32 - MOVGE R2, #0 - MOVLT R2, R4, LSL R2 - B DispatchReturn - -;--------------------------------------------------------------------------- -; Support routines : - -TwoIntegers ROUT - Push "lr" - CMP R0, #type_String - BLEQ StringToInteger - ePull "R3, R4" - CMP R3, #type_Operator - BEQ MissingOpErr - CMP R3, #type_String - BLEQ PullStringToInteger - Pull "PC" - -Comparison ROUT - Push "lr" - ePull "R3, R4" - CMP R3, #type_Operator - BEQ MissingOpErr - CMP R0, #type_String - BEQ %FT01 - CMP R3, #type_String - BLEQ PullStringToInteger - CMP R4, R2 - Pull "PC" - -01 - CMP R3, #type_String - BEQ %FT02 - BL StringToInteger - CMP R4, R2 - Pull "PC" - -02 - MOV R3, R11 - ADD R11, R11, R4 - ADD R11, R11, #3 - BIC R11, R11, #3 -; $R3, length R4 against $exprSTRACC, length R2 - Push "R1, R2, R4, R5" - CMP R2, R4 - MOVGT R2, R4 ; minm length -> R2 - LDR R0, =exprSTRACC -03 - SUBS R2, R2, #1 - BLT %FT04 - LDRB R1, [R0], #1 - LDRB R5, [R3], #1 - CMP R5, R1 - BEQ %BT03 - MOV R0, #type_Integer - Pull "R1, R2, R4, R5, PC" - -04 - Pull "R1, R2, R4, R5" - CMP R4, R2 - MOV R0, #type_Integer - Pull "PC" - -StringToInteger ROUT - Push "R1, R3, R4, lr" - LDR R1, =exprSTRACC - ADD R3, R1, R2 ; end pointer to check all string used. - MOV R0, #13 - STRB R0, [R1, R2] ; force terminator in -01 - LDRB R0, [R1], #1 - CMP R0, #" " - BEQ %BT01 - MOV R4, #0 - CMP R0, #"-" - MOVEQ R4, #-1 - CMPNE R0, #"+" - SUBNE R1, R1, #1 - MOV R0, #10 - SWI XOS_ReadUnsigned -02 - LDRB R0, [R1], #1 - CMP R0, #" " - BEQ %BT02 - SUB R1, R1, #1 - CMP R1, R3 - BNE BadIntegerErr - MOV R0, #type_Integer - CMP R4, #0 - RSBNE R2, R2, #0 - Pull "R1, R3, R4, PC" - -IntegerToString ROUT - Push "R1, lr" - MOV R0, R2 - LDR R1, =exprSTRACC - [ LongCommandLines - MOV R2, #LongCLISize - SUB R2, R2, #1 - | - MOV R2, #255 - ] - SWI XOS_BinaryToDecimal - MOV R0, #type_String - Pull "R1, PC" - -PullStringToInteger ROUT ; corrupts exprSTRACC - Push "R0, R2, lr" - MOV R2, R4 - BL Pull_String - BL StringToInteger - MOV R4, R2 - MOV R3, #type_Integer - Pull "R0, R2, PC" - -;****************************************************************************** - -GetFactor ROUT -; return type in R0 -; if operator, R2 has op_xxx -; if integer/string, it has been pushed -; R1 updated, R2 corrupted. - -10 - LDRB R0, [R1], #1 - CMP R0, #" " - BEQ %BT10 - - CMP R0, #13 - BNE %FT11 - MOV R2, #op_Bottom - MOV R0, #type_Operator - MOV PC, lr - -31 - CMP R0, #"@"-1 ; chars >= "@" are OK - BGT %FT32 - CMP R0, #" " ; chars <= " " always terminate - MOVLE PC, lr - Push "R2, R3" - ADR R2, terminatename_map-"!" - LDRB R3, [R2, R0] ; termination map for " " < char < "@" - CMP R3, #0 - Pull "R2, R3" - MOVEQ PC, lr -32 - STRB R0, [R3], #1 - MOV PC, lr ; return with GT for OK, LE for naff - -terminatename_map ; 1 means character allowed - ; ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? - = 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1 - ALIGN - -11 - CMP R0, #"&" ; hex number? - CMPNE R0, #"0" - RSBGTS R2, R0, #"9" - BGE %FT03 ; got to get a number. - - CMP R0, #"""" - BEQ %FT04 ; string. - - ; look for operator - Push "R3" - ADR R2, operator_table -20 - LDRB R3, [R2], #1 - CMP R3, #0 ; end of table? - BEQ %FT30 - CMP R0, R3 - BEQ %FT21 -22 - LDRB R3, [R2], #1 - CMP R3, #0 - BNE %BT22 - ADD R2, R2, #1 ; skip op_xxx - B %BT20 -21 - Push "R1" -24 - LDRB R3, [R2], #1 - CMP R3, #0 - BEQ %FT23 - LDRB R0, [R1], #1 - CMP R0, R3 - BEQ %BT24 - Pull "R1" - LDRB R0, [R1, #-1] - B %BT22 -23 - Pull "R3" ; junk R1 - Pull "R3" - LDRB R2, [R2] - MOV R0, #type_Operator - MOV PC, lr ; got an operator. - -30 - LDR R3, =exprSTRACC - ; assume variable name : try and read it. - Push "lr" - BL %BT31 ; check R0 for allowed in name, insert. - BLE NaffItemErr -33 - LDRB R0, [R1], #1 - BL %BT31 - BGT %BT33 - SUB R1, R1, #1 - MOV R0, #13 - STRB R0, [R3], #1 - ; potential name in exprSTRACC - Push "R1, R4" - LDR R0, =exprSTRACC - MOV R2, #-1 ; just test for existence first - MOV R3, #0 - MOV R4, #0 ; no expansion - SWI XOS_ReadVarVal - CMP R2, #0 - BEQ NaffItemErr - LDR R1, =exprSTRACC ; overwrite name with value - MOV R0, R1 ; overwritten by VSet return - [ LongCommandLines - MOV R2, #LongCLISize - SUB R2, R2, #1 - | - MOV R2, #255 - ] - MOV R3, #0 - CMP R4, #VarType_Macro - MOVEQ R4, #VarType_Expanded - SWI XOS_ReadVarVal - BVS StrOFloErr - CMP R4, #VarType_Number - LDREQ R2, [R1] - MOVEQ R0, #type_Integer - BLNE Push_String - MOVNE R0, #type_String - ePush "R0, R2" - Pull "R1, R4, lr" - Pull "R3" - MOV PC, lr - -operator_table - = "(" , 0, op_Bra - = ")" , 0, op_Ket - = "+" , 0, op_Plus - = "-" , 0, op_Minus - = "*" , 0, op_Times - = "/" , 0, op_Divide - = "=" , 0, op_EQ - = "<>" , 0, op_NE - = "<=" , 0, op_LE - = "<<" , 0, op_LShift - = "<" , 0, op_LT - = ">=" , 0, op_GE - = ">>>" , 0, op_LRShift - = ">>" , 0, op_RShift - = ">" , 0, op_GT - = "AND" , 0, op_AND - = "OR" , 0, op_OR - = "EOR" , 0, op_EOR - = "NOT" , 0, op_NOT - = "RIGHT", 0, op_Right - = "LEFT" , 0, op_Left - = "MOD" , 0, op_MOD - = "STR" , 0, op_STR - = "VAL" , 0, op_VAL - = "LEN" , 0, op_LEN - = 0 - ALIGN - -03 - SUB R1, R1, #1 ; point at string start - Push "lr" - MOV R0, #10 - SWI XOS_ReadUnsigned - LDRVS R13, ExprSVCstack - BVS BumNumber2 ; already messagetransed, so don't do it again MED-01583 - MOV R0, #type_Integer - ePush "R0, R2" - Pull "PC" - -ExprErrCommon -BumNumber - LDR R13, ExprSVCstack - [ International - BL TranslateError - ] -BumNumber2 - STR R0, [stack] - Pull "R0-R4, lr" - MOV R1, #0 ; haven't put anything in buffer - B SLVK_SetV -BadStringErr - ADRL R0, ErrorBlock_BadString - B ExprErrCommon -Bra_Code -BadBraErr - ADR R0, ErrorBlock_BadBra - B ExprErrCommon - MakeErrorBlock BadBra -StackOFloErr - ADR R0, ErrorBlock_StkOFlo - B ExprErrCommon - MakeErrorBlock StkOFlo -MissingOpErr - ADR R0, ErrorBlock_MissOpn - B ExprErrCommon - MakeErrorBlock MissOpn -MissingOrErr - ADR R0, ErrorBlock_MissOpr - B ExprErrCommon - MakeErrorBlock MissOpr -BadIntegerErr - ADR R0, ErrorBlock_BadInt - B ExprErrCommon - MakeErrorBlock BadInt -StrOFloErr - ADR R0, ErrorBlock_StrOFlo - B ExprErrCommon - MakeErrorBlock StrOFlo -NaffItemErr - ADR R0, ErrorBlock_NaffItm - B ExprErrCommon - MakeErrorBlock NaffItm -DivZeroErr - ADR R0, ErrorBlock_DivZero - B ExprErrCommon - MakeErrorBlock DivZero - -04 - LDR R2, =exprSTRACC -05 - LDRB R0, [R1], #1 - CMP R0, #13 - CMPNE R0, #10 - CMPNE R0, #0 - BEQ BadStringErr - CMP R0, #"""" - BEQ %FT06 -07 - STRB R0, [R2], #1 ; can't overflow - comes from buffer - B %BT05 - -06 - LDRB R0, [R1], #1 - CMP R0, #"""" - BEQ %BT07 - SUB R1, R1, #1 - LDR R0, =exprSTRACC - SUB R2, R2, R0 ; length to R2 - Push "lr" - BL Push_String - ePush "R0, R2" - Pull "PC" - -Push_String ROUT - Push "R2, R3" - SUBS R2, R2, #1 - BMI %FT02 - BIC R2, R2, #3 - LDR R0, =exprSTRACC -01 - LDR R3, [R0, R2] - ePush "R3" - SUBS R2, R2, #4 - BGE %BT01 -02 - Pull "R2, R3" - MOV R0, #type_String - MOV PC, lr - -Pull_String ROUT - CMP R2, #0 - MOVEQ PC, lr - Push "R0, R2, R3" - LDR R0, =exprSTRACC -01 - ePull "R3" - STR R3, [R0], #4 - SUBS R2, R2, #4 - BGT %BT01 - Pull "R0, R2, R3" - MOV PC, lr - - LTORG - -;***************************************************************************** - -; Configure and Status - -; The configuration table : some types and macros first. - -ConType_NoParm * 1 -ConType_Field * 2 -ConType_Special * 3 -ConType_Size * 4 - -; Type Special has another table : -; code to set it -; code to show it -; string to print for Configure listing. -; Keep table position as offset from table entry - - MACRO - Config_Special $name - = ConType_Special, "$name", 0 - ALIGN - & Config_$name._table - . - MEND - -; Table offset : -Config_Special_SetCode * 0 -Config_Special_ShowCode * 4 -Config_Special_String * 8 - -; Type NoParm : *con. name -; put $value into bits $bitoff to $bitoff+$fwidth in byte $byteoff - - MACRO - Config_NoParm $name, $bitoff, $fwidth, $bytoff, $value - = ConType_NoParm, "$name", 0 - ALIGN - = $bitoff, $fwidth, $bytoff, $value - MEND - -; Type Field : *con. name number -; read value & put into bits $bitoff to $bitoff+$fwidth in byte $byteoff - - MACRO - Config_Field $name, $bitoff, $fwidth, $bytoff - = ConType_Field, "$name", 0 - ALIGN - = $bitoff, $fwidth, $bytoff, 0 - MEND - -; Type Size : *con. name number|nK -; read value & put into bits $bitoff to $bitoff+$fwidth in byte $byteoff - - MACRO -$l Config_Size $name, $bitoff, $fwidth, $bytoff - = ConType_Size, "$name", 0 - ALIGN -$l = $bitoff, $fwidth, $bytoff, 0 - MEND - -;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; now the table - -Config_Table - Config_Special Baud -AlternateBoot - Config_NoParm Boot, 4, 0, DBTBCMOS, 1 -AlternateNoBoot - Config_NoParm NoBoot, 4, 0, DBTBCMOS, 0 -AlternateCaps - Config_NoParm Caps, 3, 2, StartCMOS, 4 -AlternateNoCaps - Config_NoParm NoCaps, 3, 2, StartCMOS, 2 -ExpandShCaps - Config_NoParm ShCaps, 3, 2, StartCMOS, 1 -EndListCapsFrig - Config_Field Data, 5, 2, DBTBCMOS - Config_Field Delay, 0, 7, KeyDelCMOS -ExpandDir - Config_NoParm Dir, 6, 0, StartCMOS, 0 -ExpandNoDir - Config_NoParm NoDir, 6, 0, StartCMOS, 1 - Config_Field DumpFormat, 0, 4, TutuCMOS - Config_Size FontSize, 0, 7, FontCMOS -FontSizeFrig - Config_Special Ignore - Config_Field Language, 0, 7, LanguageCMOS -AlternateLoud - Config_NoParm Loud, 1, 0, DBTBCMOS, 1 - Config_Special Mode - Config_Special MonitorType - Config_Special MouseStep - [ AssemblePointerV - Config_Special MouseType - ] - Config_Field Print, 5, 2, PSITCMOS - Config_Size PrinterBufferSize, 0, 7, PrinterBufferCMOS -PrinterBufferFrig -AlternateQuiet - Config_NoParm Quiet, 1, 0, DBTBCMOS, 0 - Config_Size RamFSSize, 0, 6, RAMDiscCMOS - Config_Field Repeat, 0, 7, KeyRepCMOS - Config_Size RMASize, 0, 6, RMASizeCMOS - Config_Size ScreenSize, 0, 6, ScreenSizeCMOS -ScreenSizeFrig -AlternateScroll - Config_NoParm Scroll, 3, 0, DBTBCMOS, 0 -AlternateNoScroll - Config_NoParm NoScroll, 3, 0, DBTBCMOS, 1 - Config_Size SpriteSize, 0, 6, SpriteSizeCMOS - Config_Special Sync - Config_Size SystemSize, 0, 5, SysHeapCMOS - Config_Special TV - Config_Special WimpMode - = 0 - -NoDirString = "No" -DirString = "Directory", 0 -ShCapsString = "ShiftCaps", 0 - - ALIGN - -ExpandFrig * 8 ; see code that shows NoParm options. -ExpandTab - & ExpandDir - ExpandFrig-. - & DirString - .-1 ; another printing fudge! - & ExpandNoDir - ExpandFrig-. - & NoDirString - .-1 - & ExpandShCaps - ExpandFrig-. - & ShCapsString - .-1 - & 0 - -;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - MACRO - Config_Special_Table $name, $text -Config_$name._table - B Config_$name._setcode - B Config_$name._showcode - = "$text", 0 - ALIGN - MEND - - ALIGN - Config_Special_Table Baud, "<D>" - Config_Special_Table TV, "[<D> [[,] <D>]]" - Config_Special_Table Mode, "<D> | Auto" - Config_Special_Table Ignore, "[<D>]" - Config_Special_Table MouseStep, "<D>" - [ AssemblePointerV - Config_Special_Table MouseType, "<D>" - ] - Config_Special_Table MonitorType, "<D> | Auto" - Config_Special_Table Sync, "<D> | Auto" - Config_Special_Table WimpMode, "<D> | Auto" - -;***************************************************************************** -; Lookup : R0 -> option -; Exit : R2 -> table entry, EQ for not found -; R0 stepped on - -FindOption Entry "r1, r3-r5" - ADRL r2, Config_Table+1 -04 - MOV r1, #0 ; offset -01 - LDRB r3, [r0, r1] - LDRB r4, [r2, r1] - CMP r3, #32 - CMPLE r4, #32 - BLE %FT02 - UpperCase r3, r5 - UpperCase r4, r5 - CMP r3, r4 - ADDEQ r1, r1, #1 - BEQ %BT01 - CMP r3, #"." - TOGPSR Z_bit, r3 ; invert EQ/NE - CMPNE r1, #0 - ADDNE r1, r1, #1 ; skip . - BNE %FT02 -03 - LDRB r1, [r2], #1 - CMP r1, #0 - BNE %BT03 - ADD r2, r2, #7 ; skip infoword - BIC r2, r2, #3 - LDRB r1, [r2], #1 - CMP r1, #0 - BNE %BT04 - EXIT ; failure exit - -02 - ADD r0, r0, r1 ; point at char after option - SUBS r2, r2, #1 - EXIT ; return with success - -;**************************************************************************** -; -; Configure -; IF noparms OR parm=. THEN list options : issue service call : finish listing -; ELSE lookup parm1 : doit -; IF notfound THEN issue service - -Configure_Help ROUT - Push "r0, lr" - ADR r0, %FT01 - MOV r1, #Status_Keyword_Flag - B KeyHelpCommon -01 - DCB "HUTMCON", 0 - ALIGN - -Configure_Code ROUT - Push "lr" - CMP r1, #0 ; noparms? - MOVEQ r3, #0 - BEQ ListAll ; go listem. - BL FindOption - BEQ %FT01 - LDRB r4, [r2], #1 -03 - LDRB r1, [r2], #1 - CMP r1, #0 - BNE %BT03 - ADD r2, r2, #3 - BIC r2, r2, #3 - LDR r1, [r2] - CMP r4, #ConType_Size - BEQ ReadSizeParm - - CMP r4, #ConType_Field - ASSERT ConType_Special > ConType_Field -; if special dispatch it - ADDGT r1, r1, r2 ; point at node - ADDGT pc, r1, #Config_Special_SetCode ; call it -; if noparm get value - MOVLT r2, r1, LSR #24 - BLEQ ReadNumParm - BVS BadConParm -BaudEntry - BL ConfigCheckEOL - Pull "pc", VS -IgnoreEntry - MOV r0, r1 ; info word - BL ReadByte ; current byte into R1 - - MOV r3, r0, LSR #8 - AND r3, r3, #&FF ; get fwidth - MOV r4, #2 - MOV r4, r4, LSL r3 - SUB r4, r4, #1 ; get mask/maximum value - CMP r2, r4 - BHI ConParmTooBig - - AND r3, r0, #&FF ; get bitoff - BIC r1, r1, r4, LSL r3 ; clear bits in correct position - ORR r2, r1, r2, LSL r3 ; OR in new bits - - MOV r1, r0, LSR #16 ; get bytoff - AND r1, r1, #&FF - MOV r0, #WriteCMOS - SWI XOS_Byte ; and set it. Assume this clears V! - - Pull "pc" - -BadConParm - MOV r0, #1 - B ConfigGenErr -BadConParmError - & ErrorNumber_Syntax - = "NotNumeric:Numeric parameter needed", 0 - ALIGN - -ConParmTooBig - MOV r0, #2 - B ConfigGenErr -ConParmTooBigError - & ErrorNumber_Syntax - = "ConParmTooBig:Configure parameter too big", 0 - ALIGN -01 - MOV r12, #Module_List -conoptloop - LDR r12, [r12] - CMP r12, #0 - BEQ conoptservice - LDR r1, [r12, #Module_code_pointer] - LDR r2, [r1, #Module_HC_Table] - CMP r2, #0 - BEQ conoptloop - MOV r4, #Status_Keyword_Flag - BL FindItem - BCC conoptloop ; next module - ADD r0, r0, r3 ; point at commtail - LDR r12, [r12, #Module_incarnation_list] ; preferred life - ADDS r12, r12, #Incarnation_Workspace ; clear V - Push "r1-r6" - -StKey_SkipSpaces - LDRB r4, [r0], #1 - CMP r4, #" " - BEQ StKey_SkipSpaces - SUB r0, r0, #1 - - MOV lr, pc - ADD pc, r1, r5 ; call im - Pull "r1-r6" - Pull "pc", VC -ConfigGenErr - CMP r0, #3 - BHI ExitConfig - ADREQL r0, Config2manyparms - CMP r0, #2 - ADREQ r0, ConParmTooBigError - CMP r0, #1 - ADRLO r0, BadConOptError - ADREQ r0, BadConParmError - [ International - BL TranslateError - ] -ExitConfig - SETV - Pull "pc" - -conoptservice - MOV r1, #Service_UKConfig - BL Issue_Service - CMP r1, #0 - BNE BadConOpt - CMP r0, #0 - BGE ConfigGenErr - Pull "pc" ; TBS means OK: note CMP has cleared V - -BadConOpt - MOV r0, #0 - B ConfigGenErr -BadConOptError - & ErrorNumber_Syntax - = "BadConOpt:Bad configure option", 0 - ALIGN - -ReadNumParm Entry "r1" -10 - LDRB r2, [r0], #1 - CMP r2, #" " - BEQ %BT10 - SUB r1, r0, #1 - MOV r0, #10 ; set base - SWI XOS_ReadUnsigned - EXIT VS - MOV r0, r1 - LDRB r1, [r0] - CMP r1, #" " - SETV GT - EXIT - -; read a number or Auto -; returns R2 = number or -1 for Auto -; R0 -> terminator - -ReadNumAuto Entry "r1,r3,r4" -10 - LDRB r2, [r0], #1 - CMP r2, #" " - BEQ %BT10 - SUB r1, r0, #1 - ADR r3, AutoString ; string to match against - MOV r4, #0 ; no other terminators for $R1 - BL Module_StrCmp ; out: EQ => match, r1 -> terminator - ; NE => no match, r1 preserved - ; r3 corrupted in both cases - MOVEQ r2, #-1 - BEQ %FT20 - MOV r0, #10 ; set base - SWI XOS_ReadUnsigned - EXIT VS -20 - MOV r0, r1 - LDRB r1, [r0] - CMP r1, #" " - SETV GT - EXIT - -AutoString - = "Auto", 0 - ALIGN - -ReadSizeParm ROUT - Push "r1, r8" - MOV r8, r2 -02 - LDRB r2, [r0], #1 - CMP r2, #" " - BEQ %BT02 - SUB r1, r0, #1 - MOV r0, #10 ; set base - SWI XOS_ReadUnsigned - Pull "r1, r8", VS - BVS BadConParm - MOV r0, r1 - LDRB r1, [r0] - CMP r1, #" " - BLE %FT01 - CMP r1, #"k" - CMPNE r1, #"K" - Pull "r1, r8", NE - BNE BadConParm - ADRL r14, PrinterBufferFrig-4 - TEQ r8, r14 ; if printer buffer size - TEQEQ r2, #1 ; and 1K - MOVEQ r2, #0 ; then use zero (default) - ADRL r14, FontSizeFrig-4 ; point at info word for fontsize - TEQ r8, r14 ; if fontsize - MOVEQ r8, #4*1024 ; then use 4K (lucky it's a pagesize!) - MOVNE r8, #0 ; else use pagesize units - LDRNE r8, [r8, #Page_Size] - ADRL r14, PageShifts-1 - LDRB r14, [r14, r8, LSR #12] - SUB r14, r14, #10 ; *1024 - MOV r8, r8, LSR #10 ; /1024 - SUB r8, r8, #1 - ADD r2, r2, r8 - BIC r2, r2, r8 ; round up to nearest pagesize - MOV r2, r2, LSR r14 ; divide parm by pagesize - ADD r0, r0, #1 ; point past "K" for EOL checking -01 - Pull "r1, r8" - B BaudEntry - -;***************************************************************************** -; Status -; list all options matched : allow . and <terminator> to match all -; issue service - -Status_Code ROUT - Push "lr" - CMP r1, #0 ; noparms? - MOVEQ r3, #1 - BEQ ListAll ; go listemall - CMP r1, #1 - BNE %FT01 - BL FindOption - BEQ %FT01 - MOV r3, #2 - BL ListOneConfig - Pull "pc" - -01 - MOV r6, #Module_List -statoptloop - LDR r6, [r6] - CMP r6, #0 - BEQ statoptservice - LDR r1, [r6, #Module_code_pointer] - LDR r2, [r1, #Module_HC_Table] - CMP r2, #0 - BEQ statoptloop - MOV r4, #Status_Keyword_Flag - BL FindItem - BCC statoptloop ; next module - MOV r0, #1 - LDR r12, [r6, #Module_incarnation_list] - ADD r12, r12, #Incarnation_Workspace - Push "r0-r6" - MOV lr, pc - ADD pc, r1, r5 ; call im - STRVS r0, [sp] - Pull "r0-r6, pc" - -statoptservice - MOV r1, #Service_UKStatus - BL Issue_Service - CMP r1, #0 - Pull "pc", EQ - ADR r0, %FT03 - [ International - BL TranslateError - ] - SETV - Pull "pc" -03 - & ErrorNumber_Syntax - = "BadStat:Bad status option", 0 - ALIGN - -;***************************************************************************** - -; routine to list everything : on entry R3 = 0 means entered from configure -; = 1 " " " status -; lr stacked for return - -ListAll ROUT - MOV r0, #117 ; Read current VDU status - SWI XOS_Byte ; Won't fail - Push "r1" - - [ International - SWI XOS_WriteI+14 - BL WriteS_Translated - = "Config:Configuration",0 - ALIGN - SWIVC XOS_WriteI+" " - | - SWI XOS_WriteS - = 14, "Configuration ", 0 ; paged mode on. - ALIGN - ] - Pull "r1, pc", VS ; Wrch can fail - CMP r3, #0 - ADREQ r0, %FT06 - ADRNE r0, %FT08 - [ International - BL Write0_Translated - | - SWI XOS_Write0 - ] - SWIVC XOS_NewLine - SWIVC XOS_NewLine - Pull "r1, pc", VS - - ADRL r2, Config_Table -02 - ADRL r4, AlternateCaps - CMP r4, r2 - CMPEQ r3, #1 - BEQ FrigCapsList - LDRB r4, [r2] - CMP r4, #0 - BLNE ListOneConfig - Pull "r1, pc", VS - BNE %BT02 - -10 - ADRL r0, dotstring ; match all - Push "r3, r7" - MOV r7, #Module_List -listallmloop - LDR r7, [r7] - CMP r7, #0 - BEQ listallservice - LDR r1, [r7, #Module_code_pointer] - LDR r2, [r1, #Module_HC_Table] - CMP r2, #0 - BEQ listallmloop -listalltryfind - MOV r4, #Status_Keyword_Flag - BL FindItem - BCC listallmloop ; next module - LDR r0, [stack] ; pick up r3 - LDR r12, [r7, #Module_incarnation_list] - ADD r12, r12, #Incarnation_Workspace - Push "r0-r6" - MOV lr, pc - ADD pc, r1, r5 ; call im - Pull "r0-r6" - ADD r2, r2, #16 ; step to next field - ADRL r0, dotstring - B listalltryfind - - [ International -06 - = "Options:options:",0 -08 - = "Status:status:",0 - | -06 - = "options:",0 -08 - = "status:",0 - ] - ALIGN - -listallservice - Pull "r3, r7" - CMP r3, #0 - MOVEQ r1, #Service_UKConfig - MOVNE r1, #Service_UKStatus - MOV r0, #0 ; indicate list wanted - BL Issue_Service - CMP r3, #0 - [ International - BEQ %FT20 - BL GSWriteS_Translated - = "STail:|J|MUse *Configure to set the options.|J|M",0 - ALIGN - B %FT30 -20 - BL GSWriteS_Translated - = "CTail1:|J|MWhere:|J|MD is a decimal number, a hexadecimal number preceded by &,|J|M" - = "or the base followed by underscore, followed|J|M",0 - ALIGN - BL GSWriteS_Translated - = "CTail2:by digits in the given base.|J|MItems within [ ] are optional.|J|M" - = "Use *Status to display the current settings.|J|M",0 - ALIGN -30 - | - ADRNE r0, statuslastline - ADREQ r0, configlastline - SWI XOS_Write0 - ] - Pull "r1" - Pull "pc", VS ; return error if set - TST r1, #5 - SWIEQ XOS_WriteI+15 ; paged mode off - Pull "pc" - - [ :LNOT: International -statuslastline - = 10,13, "Use *Configure to set the options.", 10,13,0 -configlastline - = 10,13, "Where:", 10,13 - = "D is a decimal number, " ;, 10,13 - = "a hexadecimal number preceded by &, ", 10,13 - = "or the base followed by underscore, followed", 10,13 - = "by digits in the given base.", 10,13 - = "Items within [ ] are optional.", 10,13 - = "Use *Status to display the current settings.", 10,13, 0 - ALIGN - ] - -FrigCapsList - MOV r3, #2 - BL ListOneConfig - Pull "r1, pc", VS - MOV r3, #1 - ADRL r2, EndListCapsFrig - B %BT02 - -;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -; routine to list one item : -; R3 = 0 means entered from configure -; = 1 " " " status -; = 2 " " " status <item> -; R2 points at the item, stepped to next on exit -; Preserves flags - -ListOneConfig ROUT - EntryS - LDRB r4, [r2] - CMP r4, #ConType_Field - CMPNE r4, #ConType_Size - CMPNE r3, #0 - BNE %FT20 - - ADD r0, r2, #1 - SWI XOS_Write0 - BVS ExitShow - SUB r1, r0, r2 ; get length - ADD r2, r0, #3 ; skip terminator - BIC r2, r2, #3 ; and align - - CMP r4, #ConType_NoParm - BEQ %FT07 -04 - SWI XOS_WriteI+" " - BVS ExitShow - ADD r1, r1, #1 - CMP r1, #12 - BLS %BT04 - - CMP r3, #0 - BNE %FT30 - - CMP r4, #ConType_Size - ADREQ r0, %FT42 - BEQ %FT43 - - CMP r4, #ConType_Field - ASSERT ConType_Special > ConType_Field - ADREQ r0, %FT05 - LDRGT r0, [r2] - ADDGT r0, r0, r2 ; point at node - ADDGT r0, r0, #Config_Special_String ; point at string -43 - SWI XOS_Write0 -07 - ADD r2, r2, #4 -ExitShow - SWIVC XOS_NewLine -11 - EXITV -05 - = "<D>", 0 -42 - = "<D>[K]", 0 - -; status bits : - - ALIGN -20 - ADD r0, r2, #1 ; got to do *status on a NoParm or Special -21 - LDRB r1, [r0], #1 - CMP r1, #0 ; step past name - BNE %BT21 - ADD r0, r0, #3 - BIC r0, r0, #3 ; align - LDR r1, [r0] ; get info word. - CMP r4, #ConType_Special - ADDEQ r1, r1, r0 ; point at node - ADDEQ pc, r1, #Config_Special_ShowCode - -; if CRbytevalue = infowordvalue then print something - - MOV r4, r0 ; hang on to it - MOV r0, r1 - BL GetValue - MOV r1, r1, LSR #24 ; value. - CMP r0, r1 - BNE %FT10 ; check for *Status <Item> - -; first see if expansion needed - - ADRL r0, ExpandTab -22 - LDR r1, [r0], #8 - CMP r1, #0 - BEQ %FT23 - ADD r1, r1, r0 ; get real address - CMP r1, r2 - BNE %BT22 - LDR r2, [r0, #-4]! -14 - ADD r2, r2, r0 ; new string -23 - ADD r2, r2, #1 - -; now write chars with space between lowercase then upper - - MOV r1, #1 ; indicate uppercase last -24 - LDRB r0, [r2], #1 - CMP r0, #0 - BEQ %FT25 - CMP r0, #"Z" ; uppercase if LE - CMPLE r1, #0 - SWILE XOS_WriteI+" " - BVS ExitShow - CMP r0, #"Z" - MOVLE r1, #1 - MOVGT r1, #0 - SWI XOS_WriteC - BVC %BT24 - -25 - ADDVC r2, r4, #4 - B ExitShow - -30 - LDR r0, [r2], #4 ; got to do *status for Field - CMP r4, #ConType_Size - MOV r4, r2 - BL GetValue - BEQ %FT31 - BL PrintR0 - B ExitShow -31 - Push "r8, r9" - ADRL r8, FontSizeFrig - CMP r4, r8 - MOVNE r8, #0 - LDRNE r8, [r8, #Page_Size] - MOVEQ r8, #4*1024 - ADRL r9, PageShifts-1 - LDRB r9, [r9, r8, LSR #12] - SUB r9, r9, #10 - MOVS r0, r0, LSL r9 ; size in K - BNE %FT35 - ADRL r8, PrinterBufferFrig ; if zero and PrinterBufferSize, then 1K - TEQ r8, r2 - MOVEQ r0, #1 - BEQ %FT35 - ADRL r8, ScreenSizeFrig ; if zero and it's ScreenSize, then call OS_ReadSysInfo to find appropriate amount - TEQ r8, r2 - BNE %FT35 - SWI XOS_ReadSysInfo ; proper screen size (r0=0) on entry - MOV r0, r0, LSR #10 -35 - Pull "r8, r9" - BL PrintR0 - SWIVC XOS_WriteI+"K" - B ExitShow - -10 - CMP r3, #2 - ADDNE r2, r4, #4 - BNE %BT11 - -; R0 is the value set : can corrupt R3 as this is the do-one entry - - MOV r3, r0 - ADRL r0, AlternateTab ; look for option really set -12 - LDR r1, [r0], #8 ; better find a match! - ADD r1, r1, r0 ; get real address - CMP r1, r2 - BNE %BT12 - LDR r2, [r0, #-4]! - ADD r2, r2, r0 ; translation table - LDR r0, [r2, r3, LSL #2] - B %BT14 ; go printit - -AlternateTab - & AlternateBoot - ExpandFrig-. - & %FT91 -. - & AlternateNoBoot - ExpandFrig-. - & %FT91 -. - & AlternateCaps - ExpandFrig-. - & %FT92 -. - & AlternateNoCaps - ExpandFrig-. - & %FT92 -. - & ExpandShCaps - ExpandFrig-. - & %FT92 -. - & ExpandDir - ExpandFrig-. - & %FT93 -. - & ExpandNoDir - ExpandFrig-. - & %FT93 -. - & AlternateLoud - ExpandFrig-. - & %FT95 -. - & AlternateQuiet - ExpandFrig-. - & %FT95 -. - & AlternateScroll - ExpandFrig-. - & %FT96 -. - & AlternateNoScroll - ExpandFrig-. - & %FT96 -. - -91 - & AlternateNoBoot -%BT91 - & AlternateBoot -%BT91 -92 - & ShCapsString -%BT92-1 - & ShCapsString -%BT92-1 - & AlternateNoCaps -%BT92 - & AlternateNoCaps -%BT92 - & AlternateCaps -%BT92 - & AlternateCaps -%BT92 - & AlternateCaps -%BT92 - & AlternateCaps -%BT92 -93 - & DirString -%BT93-1 - & NoDirString -%BT93-1 -95 - & AlternateQuiet -%BT95 - & AlternateLoud -%BT95 -96 - & AlternateScroll -%BT96 - & AlternateNoScroll -%BT96 - -;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -; read byte from CMOS RAM : info word in R0, byte -> R1 - -ReadByte Entry "r0, r2" - MOV r1, r0, LSR #16 ; get bytoff - AND r1, r1, #&FF - MOV r0, #ReadCMOS - SWI XOS_Byte - MOV r1, r2 - EXIT - -; take infoword in R0, return value in R0 - -GetValue EntryS "r1" - BL ReadByte ; now extract the value - AND r14, r0, #&FF ; get bitoff - MOV r1, r1, LSR r14 ; throw away low bits - MOV r0, r0, LSR #8 - AND r0, r0, #&FF ; get fwidth - RSB r0, r0, #31 ; number of positions to shift up to remove unwanted bits - MOV r1, r1, LSL r0 ; shift up... - MOV r0, r1, LSR r0 ; ...then down again - EXITS - -PrintR0 Entry "r1, r2" - CMP r0, #-1 - BNE %FT10 - ADRL r0, AutoString - SWI XOS_Write0 - EXIT -10 - SUB sp, sp, #32 - MOV r1, sp - MOV r2, #32 - SWI XOS_ConvertInteger4 - SWIVC XOS_Write0 - ADD sp, sp, #32 - EXIT - -NoString = "No ", 0 - ALIGN - -ConfigCheckEOL ROUT - LDRB r3, [r0], #1 - CMP r3, #" " - BEQ ConfigCheckEOL - CMP r3, #13 - CMPNE r3, #10 - CMPNE r3, #0 - MOVEQ pc, lr - ADR R0, Config2manyparms - [ International - Push "lr" - BL TranslateError - Pull "lr" - | - SETV - ] - MOV pc, lr - -Config2manyparms - & ErrorNumber_Syntax - = "Config2manyparms:Too many parameters" - -;************************************************************************* - -IgnoreBitoff * 1 - -Config_TV_setcode ROUT - LDRB r2, [r0], #1 - CMP r2, #" " - BEQ Config_TV_setcode - SUB r1, r0, #1 - MOV r0, #10 ; set base - SWI XOS_ReadUnsigned - BVS %FT01 - CMP r2, #3 - SUBGT r0, r2, #252 - CMPGT r0, #3 - BHI BadConOpt - CMP r2, #3 - ANDGT r2, r2, #7 ; top bit set in field means 252-255 - Push "r2" - MOV r0, #0 -03 - LDRB r2, [r1], #1 - CMP r2, #" " - BEQ %BT03 - CMP r2, #"," - CMPEQ r0, #0 - MOVEQ r0, #"," - BEQ %BT03 - SUB r1, r1, #1 - Push "r0" - MOV r0, #10 - SWI XOS_ReadUnsigned - Pull "r0" - BVC %FT04 - CMP r0, #0 - Pull "r0", NE - BNE BadConOpt -04 - CMP r2, #1 - Pull "r0" - BHI ConParmTooBig - ORR r2, r2, r0, LSL #1 -01 - MOV r0, r1 - LDR r1, %FT02 - B BaudEntry -02 - = 4, 3, MODETVCMOS, 0 - -Config_TV_showcode - MOV r4, r0 - SWI XOS_WriteS - = "TV ", 0 - ALIGN - MOVVC r0, #ReadCMOS - MOVVC r1, #MODETVCMOS - SWIVC XOS_Byte - MOVVC r2, r2, LSL #24 - MOVVC r0, r2, ASR #29 ; get signed TV shift - ANDVC r0, r0, #&FF - BLVC PrintR0 - SWIVC XOS_WriteI+"," - MOVVC r0, r2, LSR #28 - ANDVC r0, r0, #1 ; interlace bit - BLVC PrintR0 - ADD r2, r4, #4 - B ExitShow - -Config_Ignore_setcode ROUT - LDRB r2, [r0], #1 - CMP r2, #" " - BEQ Config_Ignore_setcode - SUB r1, r0, #1 - MOV r0, #10 ; set base - SWI XOS_ReadUnsigned - MOV r0, r1 - Push "r2" - ADR lr, %FT03 - Push lr ; return reg for BaudEntry - MOVVS r2, #1 - MOVVC r2, #0 ; if number had clear noignore - LDR r1, %FT01 - B BaudEntry ; pseudo-BL -03 - Pull "r2" ; set to 0 if noignore, but we don't care! - LDR r1, %FT02 - B IgnoreEntry -01 - = IgnoreBitoff, 0, PSITCMOS, 0 -02 - = 0, 7, PigCMOS, 0 - -Config_Ignore_showcode - MOV r4, r0 - MOV r0, #ReadCMOS - MOV r1, #PSITCMOS - SWI XOS_Byte - TST r2, # 1 :SHL: IgnoreBitoff - ADRNE r0, NoString - SWINE XOS_Write0 - BVS ExitShow - SWI XOS_WriteS - = "Ignore", 0 - ALIGN - BVS ExitShow - ADDNE r2, r4, #4 - BNE ExitShow - MOV r1, #PigCMOS - SWI XOS_Byte - SWI XOS_WriteS - = " ", 0 - ALIGN - MOV r1, #PigCMOS - SWIVC XOS_Byte - MOVVC r0, r2 - BLVC PrintR0 - ADD r2, r4, #4 - B ExitShow - -Config_Mode_setcode ROUT -Config_WimpMode_setcode ROUT - ADR r1, ModeCMOSTable -ConfigMultiField ROUT - BL ReadNumAuto - BVS BadConParm - CMP r2, #-1 - LDR r14, [r1], #4 ; get auto number - MOVEQ r2, r14 ; if auto number then replace by auto value - LDR r14, [r1], #4 ; get maximum value - CMPNE r2, r14 ; if not auto then check maximum value - BHI ConParmTooBig - BL ConfigCheckEOL - BVS ExitConfig - MOV r0, r1 - BL WriteMultiField - Pull "pc" ; was already stacked by *Configure - -ModeCMOSTable - & 256 ; Auto value - & 255 ; maximum valid number -; address, mask from bit 0, shift to 1st bit in value, shift to 1st bit in CMOS - [ {TRUE} ; mode = wimpmode - = WimpModeCMOS, &FF, 0, 0 ; normal bits here - = Mode2CMOS, &01, 8, 4 ; mode auto bit - ASSERT WimpModeAutoBit = 16 - | - = MODETVCMOS, &0F, 0, 0 ; bits 0 to 3 here - = VduCMOS, &01, 4, 1 ; bit 4 here - = Mode2CMOS, &0F, 5, 0 ; bits 5 to 7, and auto bit here - ] - = 0 - ALIGN - -; Write a number of CMOS RAM bit fields from a value - -; in: r0 -> table -; r2 -> value to split -; -; out: - - -WriteMultiField Entry "r0-r5" - MOV r3, r0 ; pointer to where we're at in table - MOV r4, r2 ; value -10 - LDRB r1, [r3], #1 - TEQ r1, #0 - EXIT EQ - MOV r0, #ReadCMOS - SWI XOS_Byte - LDRB r0, [r3], #1 ; r0 = mask - LDRB r5, [r3], #1 ; r5 = shift to 1st bit in value - LDRB r14, [r3], #1 ; r14 = shift to 1st bit in CMOS - BIC r2, r2, r0, LSL r14 ; knock out previous bits - AND r5, r0, r4, LSR r5 ; get new bits, at bottom of byte - ORR r2, r2, r5, LSL r14 ; form new CMOS value - MOV r0, #WriteCMOS - SWI XOS_Byte - B %BT10 - -; Read a value formed by merging a number of CMOS RAM bit fields - -; in: r0 -> table -; out: r0 = value - -ReadMultiField Entry "r1-r6" - LDR r6, [r0, #4] ; get maximum value allowed - ADD r3, r0, #2*4 ; pointer to where we're at in table (skip auto, max) - MOV r4, #0 ; cumulative value -10 - LDRB r1, [r3], #1 - TEQ r1, #0 - BEQ %FT20 - MOV r0, #ReadCMOS - SWI XOS_Byte - LDRB r0, [r3], #1 ; r0 = mask - LDRB r5, [r3], #1 ; r5 = shift to 1st bit in value - LDRB r14, [r3], #1 ; r14 = shift to 1st bit in CMOS - AND r2, r0, r2, LSR r14 ; get relevant bits in bottom of byte - ORR r4, r4, r2, LSL r5 ; merge new bits with value - B %BT10 -20 - CMP r4, r6 ; if within range - MOVLS r0, r4 ; then return that value - MOVHI r0, #-1 ; else return -1 indicating Auto - EXIT - -Config_Mode_showcode ROUT - MOV r4, r0 - ADR r0, ModeSpacedString -ModeWimpModeShowCode - SWI XOS_Write0 - BVS %FT10 - BL Read_Configd_Mode - BL PrintR0 -10 - ADD r2, r4, #4 - B ExitShow - -ModeSpacedString - = "Mode ", 0 -WimpModeSpacedString - = "WimpMode ", 0 - ALIGN - -Config_WimpMode_showcode ROUT - MOV r4, r0 - ADR r0, WimpModeSpacedString - B ModeWimpModeShowCode - -Read_Configd_Mode Entry - ADR r0, ModeCMOSTable - BL ReadMultiField - EXIT - -Config_Baud_setcode ROUT - BL ReadNumParm - BVS BadConParm - CMP r2, #8 - BGT ConParmTooBig - SUBS r2, r2, #1 - MOVMI r2, #6 - LDR r1, %FT01 ; set up info word - B BaudEntry -01 - = 2, 2, PSITCMOS, 0 - -Config_Baud_showcode - MOV r4, r0 - SWI XOS_WriteS - = "Baud ", 0 - ALIGN - LDRVC r0, %BT01 ; get infoword - BLVC GetValue - ADDVC r0, r0, #1 - BLVC PrintR0 - ADD r2, r4, #4 - B ExitShow - -Config_MouseStep_setcode ROUT - LDRB r2, [r0], #1 - CMP r2, #" " - BEQ Config_MouseStep_setcode - CMP r2, #"-" - Push "r2" - SUBNE r1, r0, #1 - MOV r0, #10 ; set base - SWI XOS_ReadUnsigned - Pull "r0" - BVS BadConParm - CMP r0, #"-" - RSBEQ r2, r2, #0 - CMP r2, #0 - BEQ BadConOpt - CMP r2, #-128 - BLT BadConOpt - CMP r2, #127 - BGT ConParmTooBig - MOV r0, r1 - LDR r1, %FT02 - B BaudEntry -02 - = 0, 7, MouseStepCMOS, 0 - -Config_MouseStep_showcode ROUT - MOV r4, r0 - SWI XOS_WriteS - = "MouseStep ", 0 - ALIGN - MOVVC r0, #ReadCMOS - MOVVC r1, #MouseStepCMOS - SWIVC XOS_Byte - BVS %FT01 - MOVS r2, r2, LSL #24 - MOVNE r0, r2, ASR #24 ; get sign extended byte - MOVEQ r0, #1 - BL PrintR0 -01 ADD r2, r4, #4 - B ExitShow - -Config_MouseType_setcode ROUT - LDRB r2, [r0], #1 - CMP r2, #" " - BEQ Config_MouseType_setcode - SUB r1, r0, #1 - MOV r0, #10 ; set base - SWI XOS_ReadUnsigned - BVS BadConParm - CMP r2, #&100 - BCS ConParmTooBig - MOV r4, r1 - MOV r0, #1 - MOV r1, r2 - SWI XOS_Pointer - MOV r0, r4 - LDR r1, %FT01 - B BaudEntry -01 - = 0, 7, MouseCMOS, 0 - -Config_MouseType_showcode - MOV r4, r0 - SWI XOS_WriteS - = "MouseType ", 0 - ALIGN - LDRVC r0, %BT01 - BLVC GetValue - BLVC PrintR0 - ADD r2, r4, #4 - B ExitShow - -Config_MonitorType_setcode - [ ModeSelectors - ADR r1, MonitorTypeCMOSTable - BL ReadNumAuto - BVS BadConParm - MOV r4, r2 ; save value to store in current monitortype - CMP r2, #-1 - LDR r14, [r1], #4 ; get auto number - MOVEQ r2, r14 ; if auto number then replace by auto value - LDR r14, [r1], #4 ; get maximum value - CMPNE r2, r14 ; if not auto then check maximum value - BHI ConParmTooBig - BL ConfigCheckEOL - BVS ExitConfig - - LDR r0, =VduDriverWorkSpace+CurrentMonitorType - STR r4, [r0] ; update current value - - MOV r0, r1 - BL WriteMultiField - Pull "pc" ; was already stacked by *Configure - | - ADR r1, MonitorTypeCMOSTable - B ConfigMultiField - ] - - LTORG - -MonitorTypeCMOSTable - & MonitorTypeAuto :SHR: MonitorTypeShift ; Auto value - & MonitorTypeF :SHR: MonitorTypeShift ; maximum valid number -; address, mask from bit 0, shift to 1st bit in value, shift to 1st bit in CMOS - = VduCMOS, MonitorTypeBits :SHR: MonitorTypeShift, 0, MonitorTypeShift - = 0 - ALIGN - -Config_MonitorType_showcode ROUT - MOV r4, r0 - SWI XOS_WriteS - = "MonitorType ", 0 - ALIGN - BVS %FT10 - BL Read_Configd_MonitorType - BL PrintR0 -10 - ADD r2, r4, #4 - B ExitShow - -Read_Configd_MonitorType Entry - ADR r0, MonitorTypeCMOSTable - BL ReadMultiField - EXIT - -Config_Sync_setcode - ADR r1, SyncCMOSTable - B ConfigMultiField - -SyncCMOSTable - & 3 ; Auto value - & 1 ; maximum valid number -; address, mask from bit 0, shift to 1st bit in value, shift to 1st bit in CMOS - = VduCMOS, 1, 0, 0 - = VduCMOS, 1, 1, 7 - = 0 - ALIGN - -Config_Sync_showcode ROUT - MOV r4, r0 - SWI XOS_WriteS - = "Sync ", 0 - ALIGN - BVS %FT10 - BL Read_Configd_Sync - BL PrintR0 -10 - ADD r2, r4, #4 - B ExitShow - -Read_Configd_Sync Entry - ADR r0, SyncCMOSTable - BL ReadMultiField - EXIT - -SetUpPrinterBuffer Entry "r1-r3" - MOV r0, #PrinterBufferCMOS - BL Read - MOV r2, #0 - 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 - MOV r0, #0 - STR r2, [r0, #PrinterBufferAddr] - STR r3, [r0, #PrinterBufferSize] - EXIT - - END diff --git a/s/ArthurSWIs b/s/ArthurSWIs deleted file mode 100644 index c7a83898..00000000 --- a/s/ArthurSWIs +++ /dev/null @@ -1,1281 +0,0 @@ -; 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 => ArthurSWIs - ReadUnsigned, Vectors, Bits - -;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; -; ReadUnsigned. -; ============ -; -; Read an unsigned number from a string in decimal (no prefix), hex (&) -; or given base (nn_). Leading spaces are stripped. -; 'Bad base for number' is given if a base is not in 02..10_36 -; 'Bad number' is given if -; (i) No valid number was -; or (ii) a '<base>_' or '&' has no following valid number -; 'Number too big' is given if the result overflowed a 32-bit word - -; In r1 -> string -; r0 = base to read number in (0 means any based number allowed) -; bit 31 set -> check term chars for ok-ness -; bit 30 set -> restrict range to 00..FF -; bit 29 set -> restrict range to 0..R2 (inclusive) -; (overrides bit 30) - -; Out VC : r1 -> first unused char, r2 = number -; VS : r1 unchanged, r2 = 0, current error block set - -ReadUnsigned_Routine Entry "r0-r1, r3-r4, r9" - - WritePSRc SVC_mode, r9 - -; first set range limit - MOV r9, r2 ; limit value - TST r0, #3 :SHL: 29 - MOVEQ r9, #-1 ; used unsigned; allows anything - TSTNE r0, #1 :SHL: 30 - MOVNE r9, #&FF - - MOV r11, r0 ; Remember the input flags - BIC r12, r0, #(2_111 :SHL: 29) ; r12 := base - CMP r12, #2 ; If base nonsensical, default to 10 - RSBGES r14, r12, #36 ; ie. try to match most generally - MOVLT r12, #10 - -01 LDRB r0, [r1], #1 ; Skip spaces for Bruce - TEQ r0, #" " - BEQ %BT01 - SUB r10, r1, #1 ; Keep ptr to start of string after spaces - - TEQ r0, #"&" ; '&' always forces hex read - BNE %FT20 - MOV r4, #16 - BL ReadNumberInBase - BVS %FT95 - -10 STR r1, [sp, #4] ; Update string^ - TST r11, #(1 :SHL: 31) ; Was the termcheck flag set ? - BEQ %FT15 - LDRB r0, [r1] ; What was the term char ? - CMP r0, #" " ; CtrlChar + space all ok - BGT %FT85 ; For bad term errors - -15 CMP r2, r9 - BHI %FT80 - PullEnv - ExitSWIHandler ; VClear already in lr - - -20 SUB r1, r1, #1 ; Skip back to first char of string - MOV r4, #10 ; Try reading a decimal number - BL ReadNumberInBase - MOVVS r4, r12 ; If we failed to read a decimal number - BVS %FT30 ; then use the one supplied (r12). r1 ok - LDRB r0, [r1] ; Is it base_number ? - CMP r0, #"_" ; If not based, use supplied base - MOVNE r1, r10 ; to read from given start of string (spaces !) - MOVNE r4, r12 ; restore supplied base! - ADDEQ r1, r1, #1 ; Skip the '_' - MOVEQ r4, r2 ; Use this as new base - -; Reading number in base r4 - -30 CMP r4, #2 ; Is base valid (2..36) ? - RSBGES r0, r4, #36 ; LT -> invalid - BLT %FT90 - BL ReadNumberInBase ; Read rest of number - BVS %FT95 - B %BT10 - - -80 ADR r2, ErrorBlock_NumbTooBig - [ International - B %FT94 - | - B %FT95 - ] - -85 ADR r2, ErrorBlock_BadNumb - [ International - B %FT94 - | - B %FT95 - ] - -90 ADR r2, ErrorBlock_BadBase - - [ International -94 - Push "r0,lr" - MOV r0,r2 - BL TranslateError - MOV r2,r0 - Pull "r0,lr" - ] - -95 - STR r2, [stack] ; Go set the current error - PullEnv - MOV r2, #0 ; Defined to return 0 on error - B SLVK_SetV - - MakeErrorBlock BadBase - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; -; ReadNumberInBase -; ================ - -; In r1 -> string, r4 = base (valid) - -; Out VC : Number read in r2, r1 updated. r3 = number of chars used -; VS : r1 preserved, r2 -> error block - -ReadNumberInBase Entry "r0, r1, r12" - - MOV r2, #0 ; Result - MOV r3, #0 ; Number of valid digits read - -10 BL GetCharForReadNumber - BNE %FT50 ; Finished ? - MOV r12, r4 - - MOV r14, #0 ; Multiply by repeated addition. Base <> 0 ! -20 ADDS r14, r14, r2 - BCS %FT90 ; Now checks for overflow ! - SUBS r12, r12, #1 ; result *:= base - BNE %BT20 - ADDS r2, r14, r0 ; result +:= digit - BCC %BT10 - B %FT90 ; Now checks for overflow here too! - -50 CMP r3, #0 ; Read any chars at all ? VClear - STRNE r1, [sp, #4] ; Update string^ - EXIT NE ; Resultis r2 - - [ International - Push "r0" - ADR r0, ErrorBlock_BadNumb - BL TranslateError - MOV r2,r0 - Pull "r0" - | - ADR r2, ErrorBlock_BadNumb - SETV - ] - EXIT - MakeErrorBlock BadNumb - -90 - [ International - Push "r0" - ADR r0, ErrorBlock_NumbTooBig - BL TranslateError - MOV r2,r0 - Pull "r0" - | - ADR r2, ErrorBlock_NumbTooBig - SETV - ] - EXIT - MakeErrorBlock NumbTooBig - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; -; GetCharForReadNumber -; ==================== -; -; Read a digit and validate for reading in current base. Bases 2..36 are valid - -; In r1 -> string, r4 = base for number input - -; Out EQ -> r0 = valid number in [0..base-1], r1++ -; NE -> r0 invalid, r1 same - -GetCharForReadNumber Entry - - LDRB r0, [r1] - CMP r0, #"0" - BLO %FT95 - CMP r0, #"9" - BLS %FT50 - UpperCase r0, r14 - CMP r0, #"A" ; Always hex it, even if reading in decimal - RSBGES r14, r0, #"Z" ; Inverse compare as nicked from UpperCase - BLT %FT95 ; GE -> in range A..Z - SUB r0, r0, #"A"-("0"+10) -50 SUB r0, r0, #"0" - CMP r0, r4 ; digit in [0..base-1] ? - BHS %FT95 - ADD r1, r1, #1 ; r1++ - ADD r3, r3, #1 ; Valid digit has been read - CMP r0, r0 ; EQ - EXIT - -95 CMP r0, #-1 ; NE - EXIT - -;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; Initialise_vectors() -;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - ^ 0 -TailPtr # 4 ; order very carefully chosen! -VecWSpace # 4 -Address # 4 -VecNodeSize # 0 - -InitVectors - -; for vec:=0 to NVECTORS-1 do vectab!(vec*4):= defaultvectab+8*vec - - MOV R0, #NVECTORS - ADR R1, defaultvectab ; Point at the default vector table - LDR R2, =VecPtrTab ; Point at table of head pointers - -VecInitLoop - STR R1, [R2], #4 - ADD R1, R1, #VecNodeSize ; defaultvectab+vns*vec - SUBS R0, R0, #1 ; Next vec - BGT VecInitLoop - - MOV PC, link - LTORG - -;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; Call_vector (n) -;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; In: r10 = vector number - [ No26bitCode -; lr contains return address -; cpsr contains flags/int state to set up before calling - | -; lr contains return address + flags/int state to set up before calling - ] - -; Out: r10, r12, lr corrupted - -CallVector ROUT - - [ No26bitCode - MRS r12, CPSR - CMP r10, #NVECTORS - BHS CallVecTooHigh ; return - silly value - - MSR CPSR_f, r12 ; put back caller's flags + int state - Push lr ; claimed return goes back to caller - | - CMP r10, #NVECTORS - MOVCSS pc, lr ; return - silly value - - Push lr ; claimed return goes back to caller - TEQP lr, #0 ; put back caller's flags + int state - ] - - LDR r14, =VecPtrTab ; Point at table of head pointers - LDR r10, [r14, r10, LSL #2] ; nextblock:=vecptrtab!(n*4) - -CallVecLoop - MOV lr, pc ; Set up the return address - LDMIA r10, {r10, r12, pc} ; CALL the vectored routine, step chain - -; NB. It is the responsibility of vector code NOT to corrupt flags that are -; part of the input conditions if they are going to pass the call on, eg. INSV -; must not do CMP as C,V are needed by old handler - - TEQ r10, #0 ; until nextblock points to zero - BNE CallVecLoop - - [ No26bitCode - Pull pc ; can't restore all flags. CV will be preserved - -CallVecTooHigh - MSR CPSR_f, r12 - MOV pc, lr - | - Pull pc,,^ ; we don't expect to get to here - ; (should always be claimed), - ; but return to caller, restoring flags - ] - -;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -;Add_To_vector(n, Addressess) -;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -Add_ToVector_SWICode ROUT - - CMP R0, #NVECTORS - BCS BadClaimNumber - Push "R0-R4, link" - B GoForAddToVec - -;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -;Claim_vector(n, Addressess) -;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -ClaimVector_SWICode ROUT - ; On Entry : R0 = Vector number, R1 = Address, R2 = workspace reqd - - CMP R0, #NVECTORS - BCS BadClaimNumber - - Push "R0-R4, link" - - PHPSEI R4, R14 ; Disable IRQs - - MOV R3, #0 ; List of de-linked nodes is empty - LDR R11, =VecPtrTab ; Get ptr to table of head pointers - LDR R10, [R11, R0, LSL #2]! ; R10 "nextblock" := *oldptr, R11= root ptr -01 BL FindAndDelinkNode ; R10,R11->R10,R11,R12 - STRVC R3, [R12, #TailPtr] ; Attach de-linked nodes onto this node - MOVVC R3, R12 ; New head of de-linked nodes - BVC %BT01 ; Repeat until all nodes de-linked - - PLP R4 ; Restore IRQ state - -; Free the list of de-linked nodes, pointed to by R3, enter with VS - -02 LDRVC R3, [R3, #TailPtr] ; Update head of de-linked nodes - BLVC FreeNode ; Free the node pointed to by R12 - SUBS R12, R3, #0 ; Any more nodes to free? - BNE %BT02 ; Yes then jump - -GoForAddToVec - LDR R11, =VecPtrTab ; Point at table of head pointers - - ADD R11, R11, R0, LSL #2 - MOV R10, R1 ; Address - MOV R4, R2 ; TailPtr pointer is "nextblock" - - [ ChocolateSysHeap - ASSERT ChocolateSVBlocks = ChocolateBlockArrays + 4 - MOV r3,#ChocolateBlockArrays - LDR r3,[r3,#4] - BL ClaimChocolateBlock - MOVVS R3, #VecNodeSize ; Ask for this number of bytes - BLVS ClaimSysHeapNode ; The result is in R2 : R12 corrupted - | - MOV R3, #VecNodeSize ; Ask for this number of bytes - BL ClaimSysHeapNode ; The result is in R2 : R12 corrupted - ] - BVS BadClaimVector ; Failed : Exit - - WritePSRc SVC_mode+I_bit, R3 ; force noirq - LDR R3, [R11] ; "nextblock" :=vecptrtab!(n*4) - STMIA R2, {R3, R4, R10} ; Atomic Operation thus links in the new - ; routine - STR R2, [R11] ; vectab!(n*4) := "thisblock" -BadClaimVector - STRVS R0, [stack] - Pull "R0-R4, link" - B SLVK_TestV - -BadClaimNumber - ADR R0, ErrorBlock_BadClaimNum - [ International - Push "lr" - BL TranslateError - Pull "lr" - ] - B SLVK_SetV - - MakeErrorBlock BadClaimNum - -;Release_vector(n, Addressess) -;+++++++++++++++++++++++++ - -ReleaseVector_SWICode - ; On Entry : R0 = vector number, R1 = Address, R2 = workspace, SVC mode - - CMP R0, #NVECTORS - SETV CS - BVS BadVectorRelease - - Push "R0-R2,R9,link" - - PHPSEI R9, R14 ; Disable IRQs - - LDR R11, =VecPtrTab ; Get ptr to table of head pointers - LDR R10, [R11, R0, LSL #2]! ; R10 "nextblock" := *oldptr, R11= root ptr - BL FindAndDelinkNode ; R10,R11->R10,R11,R12 - PLP R9 ; Restore IRQ state - BLVC FreeNode ; If found, free the node in R12 - - Pull "R0-R2,R9,link" - -BadVectorRelease - ADRVS R0, ErrorBlock_NaffRelease - [ International - Push "lr",VS - BLVS TranslateError - Pull "lr",VS - ] - B SLVK_TestV - - MakeErrorBlock NaffRelease - - [ IrqsInClaimRelease -; Find a node and de-link it from the vector chain -; In: -; R1 = code address -; R2 = workspace address -; R10 -> Node -; R11 -> Root ptr -; Out: -; VC: -; R10 -> Node following found -; R11 -> New root ptr -; R12 -> Node de-linked -; VS: -; R10,11,12 trashed - node not found - -10 ADD R11, R10, #TailPtr ; oldptr := thisblock+TailPtr - LDR R10, [R11] ; nextblock:=thisblock!TailPtr - -FindAndDelinkNode - CMP R10, #0 ; End of chain? - RETURNVS EQ ; Yes, return error - - LDR R12, [R10, #VecWSpace] - CMP R12, R2 ; Workspace matches? - LDREQ R12, [R10, #Address] - CMPEQ R12, R1 ; And code address matches? - BNE %BT10 ; No then jump, try next node - -; Remove node from vector chain - - MOV R12, R10 ; R12-> node to de-link - LDR R10, [R12, #TailPtr] ; Get link to next node - STR R10, [R11] ; Previous node's link -> next node - RETURNVC EQ ; Return no error - -; Return node to heap space -; In: -; R12-> node to release - -FreeNode - Push "R0-R2, lr" - MOV R2, R12 - [ ChocolateSysHeap - ASSERT ChocolateSVBlocks = ChocolateBlockArrays + 4 - MOV r1,#ChocolateBlockArrays - LDR r1,[r1,#4] - BL FreeChocolateBlock - BLVS FreeSysHeapNode - | - BL FreeSysHeapNode - ] - STRVS R0, [stack] - Pull "R0-R2, PC" ; returns Vset if sysheap poo'd. - | -FreeLink ; find given vector entry from R10 currptr, R11 prevptr - CMP R10, #0 - ORREQS PC, lr, #V_bit - -ReleaseWLoop - LDR R12, [R10, #VecWSpace] - CMP R12, R2 - LDREQ R12, [R10, #Address] - CMPEQ R12, R1 - BEQ FoundRelease ; IF thisblock!Address=OneWanted THEN do it - ADD R11, R10, #TailPtr ; oldptr := thisblock+TailPtr - LDR R10, [R11] ; nextblock:=thisblock!TailPtr - CMP R10, #0 ; IF thisblock!TailPtr = 0 THEN naff - BNE ReleaseWLoop - ORRS PC, lr, #V_bit ; entry not found - -FoundRelease ; else !oldptr := nextblock!TailPtr : release_block(nextblock) - - LDR R12, [R10, #TailPtr] - STR R12, [R11] - - Push "R0-R2, lr" - MOV R2, R10 - MOV R10, R12 ; keep updated thisblk - BL FreeSysHeapNode - STRVS R0, [stack] - Pull "R0-R2, PC" ; returns Vset if sysheap poo'd. - ] - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - LTORG - -defaultvectab - & 0, 0, NaffVector ; UserV * &00 - & 0, 0, ErrHandler ; ErrorV * &01 - & 0, 0, NOIRQ ; IrqV * &02 - & 0, OsbyteVars, PMFWrch ; WrchV * &03 - - & 0, 0, NewRdch ; RdchV * &04 - start of VecNo=SWINo section - & 0, 0, VecOsCli - & 0, OsbyteVars, OsByte - & 0, OsbyteVars, OsWord - & 0, 0, NaffVector ; filev - & 0, 0, NaffVector ; argsv - & 0, 0, NaffVector ; bgetv - & 0, 0, NaffVector ; bputv - & 0, 0, NaffVector ; gbpbv - & 0, 0, NaffVector ; findv - & 0, OsbyteVars, VecRdLine ; ReadlineV * &0E - end of VecNo=SWINo - - & 0, 0, NaffVector ; fscv - - & 0, EvtHan_ws, DefEvent ; EventV * &10 - - & 0, 0, NaffVector ; UPTV * &11 - & 0, 0, NaffVector ; NETV * &12 - - [ AssembleKEYV - & 0, 0, KeyVector ; KEYV * &13 - | - & 0, 0, NaffVector ; KEYV * &13 - ] - - & 0, BuffParms+0, NewInsV ; INSV * &14 - & 0, BuffParms+0, NewRemV ; REMV * &15 - & 0, BuffParms+4, NewCnpV ; CNPV * &16 ; Count/Purge Buffer V - - & 0, 0, NaffVector ; UKVDU23V * &17 ; ---| VDU23 (decimal) - - & 0, HiServ_ws, HighSWI ; UKSWIV * &18 ; ---| Unknown SWI numbers - - & 0, 0, NaffVector ; UKPLOTV * &19 ; ---| VDU25 (decimal) - - & 0, 0, ReadMouse ; MouseV * &1A - - & 0, 0, NaffVector ; VDUXV * &1B - & 0, 0, Def_100HZ ; TickerV * &1C - - & 0, UpCallHan_ws, CallUpcallHandler - ; UpCallV * &1D - & 0, 0, AdjustOurSet ; ChangeEnvironment * &1E - - & 0, VduDriverWorkSpace, SpriteVecHandler ; SpriteV * &1F - & 0, 0, NaffVector ; DrawV * &20 - & 0, 0, NaffVector ; EconetV * &21 - & 0, 0, NaffVector ; ColourV * &22 - & 0, VduDriverWorkSpace, MOSPaletteV ; PaletteV * &23 - & 0, 0, NaffVector ; SerialV * &24 - - & 0, 0, NaffVector ; FontV * &25 - - [ AssemblePointerV - & 0, 0, PointerVector ; PointerV * &26 - | - & 0, 0, NaffVector ; PointerV * &26 - ] - & 0, 0, NaffVector ; TimeCodeV * &27 - & 0, 0, NaffVector ; LowPriorityEventV &28 - & 0, 0, NaffVector ; &29 - [ UseGraphicsV - & 0, 0, MOSGraphicsV ; GraphicsV * &2a - | - & 0, 0, NaffVector ; GraphicsV * &2a - ] - - ; the spares - & 0, 0, NaffVector ; &2b - & 0, 0, NaffVector ; &2c - & 0, 0, NaffVector ; &2d - & 0, 0, NaffVector ; &2e - & 0, 0, NaffVector ; &2f - - assert (.-defaultvectab) = NVECTORS*VecNodeSize - -NaffVector ROUT -Def_100HZ - MRS lr, CPSR - BIC lr, lr, #V_bit - MSR CPSR_f, lr ; Clear V, preserve rest - LDR pc, [sp], #4 ; Claim vector, do nowt - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; SWIs to save any vector entries pointing into application workspace -; -; Delink SWI: -; R0 pointer to buffer -; R1 buffer size -; Returns R1 bytes left in buffer -; V set if buffer not large enough - -Application_Delink ROUT - Push "R0, R2-R4, lr" - - CMP R1, #4 - BLT %FT99 ; invalid buffer size - - MOV R3, #NVECTORS-1 - LDR R4, [R3, #AplWorkSize-(NVECTORS-1)] - SETPSR I_bit, R3 ; IRQs off while holding context. - -03 LDR R11, =VecPtrTab ; Point at table of head pointers - ADD R10, R11, R3, LSL #2 -04 MOV R11, R10 ; step chain - LDR R10, [R11] -05 CMP R10, #0 - BNE %FT02 - SUBS R3, R3, #1 - BPL %BT03 ; next vector - MOV R3, #-1 - STR R3, [R0] - SUB R1, R1, #4 - Pull "R0, R2-R4, lr" - ExitSWIHandler - -02 LDR R12, [R10, #Address] - CMP R12, R4 - BGT %BT04 - CMP R12, #UserMemStart - BLT %BT04 - -; appl entry found: put in buffer, free it - CMP R1, #12+4 - BLT %FT99 ; no rheum - LDR R14, [R10, #VecWSpace] - STMIA R0!, {R3, R12, R14} - SUB R1, R1, #12 ; buffer entry added - - LDR R12, [R10, #TailPtr] - STR R12, [R11] ; vector delinked - - Push "R0-R2" - MOV R2, R10 - MOV R10, R12 ; keep updated thisblk - [ ChocolateSysHeap - ASSERT ChocolateSVBlocks = ChocolateBlockArrays + 4 - MOV r1,#ChocolateBlockArrays - LDR r1,[r1,#4] - BL FreeChocolateBlock - BLVS FreeSysHeapNode - | - BL FreeSysHeapNode - ] - MOVVS lr, R0 - Pull "R0-R2" - BVC %BT05 - -98 STR lr, [stack] - MOV R3, #-1 ; terminate buffer even if error - CMP r1, #4 - STRGE R3, [R0] - SUB R1, R1, #4 - Pull "R0, R2-R4, lr" - B SLVK_SetV - -99 - [ International - Push "r0" - ADRL r0, ErrorBlock_BuffOverflow - BL TranslateError - MOV lr,r0 - Pull "r0" - | - ADRL lr, ErrorBlock_BuffOverflow - ] - B %BT98 - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; Relink SWI: -; R0 pointer to buffer as set by Delink -; Returns V set if can't relink all - -Application_Relink ROUT - [ {TRUE} -; Run through the buffer BACKWARDS to ensure that the vectors are -; reinstalled in the same order. - Push "R0-R3, lr" - MOV R3, R0 ; R3 -> start of buffer - MOV R10, R0 -01 LDR R0, [R10], #12 ; search forwards to find terminator - CMP R0, #-1 - BNE %BT01 - SUB R10, R10, #12 ; R10 -> terminator -02 CMP R10, R3 ; loop backwards until we get to start - Pull "R0-R3, lr", EQ - ExitSWIHandler EQ - - LDMDB R10!, {R0-R2} - SWI XOS_AddToVector - BVC %BT02 - STR R0, [stack] - Pull "R0-R3, lr" - B SLVK_SetV - | - Push "R0-R2, lr" - MOV R10, R0 -02 LDR R0, [R10], #4 - CMP R0, #-1 - Pull "R0-R2, lr", EQ - ExitSWIHandler EQ - - LDMIA R10!, {R1, R2} - SWI XOS_AddToVector - BVC %BT02 - STR R0, [stack] - Pull "R0-R2, lr" - B SLVK_SetV - ] - -;******************************************************************** -; Now the stuff that issues service calls; also deals with the MOS -; being default default FIQ owner, and wanting to see application -; startup. -;******************************************************************** - - GBLL FIQDebug -FIQDebug SETL {FALSE} - - GBLL DebugNeil -DebugNeil SETL {FALSE} ; if TRUE, check R7-R11 preserved over services - -Issue_Service ROUT ; R1 is service number, R2 may be a parameter - ; registers preserved. - Push "R9-R12, lr" - -;do the direct calls to AMBControl for service calls of interest - CMP R1, #Service_MemoryMoved - BLEQ AMBsrv_memorymoved - CMP R1, #Service_PagesSafe - BLEQ AMBsrv_pagessafe - - CMP R1, #Service_ClaimFIQ - CMPNE R1, #Service_ClaimFIQinBackground - BEQ FIQclaim - CMP R1, #Service_ReleaseFIQ - BEQ test_FIQclaim_in_progress - - CMP r1, #Service_NewApplication - BEQ checkmoshandlers - - [ STB - CMP r1, #Service_PortMan - BLEQ svc_PortMan - ] - - [ ChocolateService -05 - CMP R1,#ServMinUsrNumber - BHS %FT84 -;call anyone on the appropriate Sys chain - MOV R10,#0 - LDR R10,[R10,#Serv_SysChains] - CMP R10,#0 - BEQ %FT88 - LDR R11,[R10,R1,LSL #2] ;pick up the chain anchor -80 -;call everyone on the chain, passing R1 value from chain if appropriate - CMP R11,#0 - BEQ %FT88 - LDR R10,[R11,#ServChain_Size] - ADD R11,R11,#ServChain_HdrSIZEOF ;start of chain - ADD R10,R10,R11 ;end of chain -82 - CMP R11,R10 - BHS %FT88 - - Push "R10" - MOV R10,R1 - LDR R9,[R11,#ServEntry_R1] - TEQ R9,#0 ; 0 means pass service number as normal - MOVNE R1,R9 ; else pass R1 value from chain (will be service index) - LDR R12,[R11,#ServEntry_WSpace] - LDR R9,[R11,#ServEntry_Code] - MOV lr, pc ; link inc. PSR, mode - MOV pc, R9 - CMP R1, #Service_Serviced - MOVNE R1,R10 ; restore R1 unless claimed - Pull "R10" - BEQ %FT01 - ADD R11,R11,#ServEntry_SIZEOF - B %BT82 -; -;call anyone on the appropriate Usr chain -84 - LDR R10,=Serv_UsrChains - LDR R10,[R10] - CMP R10,#0 - BEQ %FT88 - ServHashFunction R9,R1 - LDR R11,[R10,R9,LSL #2] ;pick up the chain-array anchor - CMP R11,#0 - BEQ %FT88 - LDR R10,[R11,#ServUChArray_Size] - ADD R11,R11,#ServUChArray_HdrSIZEOF ;start of list - ADD R10,R10,R11 ;end of list -86 - CMP R11,R10 - BHS %FT88 - LDR R9,[R11,#ServUChEntry_ServiceNo] - TEQ R9,R1 - ADDNE R11,R11,#ServUChEntry_SIZEOF - BNE %BT86 - LDR R11,[R11,#ServUChEntry_ChainAnchor] ;found chain for this service number - B %BT80 -; -;call everyone on the chain of Awkward modules, always passing service number in R1 -88 - MOV R10,#0 - LDR R11,[R10,#Serv_AwkwardChain] - CMP R11,#0 - BEQ %FT01 - LDR R10,[R11,#ServChain_Size] - ADD R11,R11,#ServChain_HdrSIZEOF ;start of chain - ADD R10,R10,R11 ;end of chain -90 - CMP R11,R10 - BHS %FT01 - LDR R12,[R11,#ServEntry_WSpace] - LDR R9,[R11,#ServEntry_Code] - MOV lr, pc ; link inc. PSR, mode - MOV pc, R9 - CMP R1, #Service_Serviced - BEQ %FT01 - ADD R11,R11,#ServEntry_SIZEOF - B %BT90 - - | ;IF/ELSE ChocolateService - -05 MOV R10, #Module_List -03 LDR R10, [R10, #Module_chain_Link] - CMP R10, #0 - BEQ %FT01 - LDR R9, [R10, #Module_code_pointer] - LDR R11, [R9, #Module_Service] - CMP R11, #0 - BEQ %BT03 - [ DebugROMPostInit - CMP R1, #Service_PostInit ; If it is a Service_PostInit call - BEQ display_pre_postinit_calls ; Go and display the postinit call -83 - ] - ADD R9, R9, R11 - ADD R11, R10, #Module_incarnation_list - Incarnation_Link -04 LDR R11, [R11, #Incarnation_Link] - CMP R11, #0 - BEQ %BT03 - - [ DebugNeil - Push "R7-R11" - ] - - ADD R12, R11, #Incarnation_Workspace - MOV lr, pc ; link inc. PSR, mode - MOV pc, R9 - - [ DebugNeil - ! 0, "Debug code included to check R7-R11 are preserved over services" - MOV lr, sp - Push "R1-R5" - LDMIA lr, {R1-R5} - TEQ R1, R7 - TEQEQ R2, R8 - TEQEQ R3, R9 - TEQEQ R4, R10 - TEQEQ R5, R11 - MOVNE PC, #0 - Pull "R1-R5" - ADD sp, sp, #5*4 - ] - - [ DebugROMPostInit - CMP R1, #Service_PostInit ; If it is a Service_PostInit call - BEQ display_post_postinit_calls ; Go and display the postinit call -87 - ] - - CMP R1, #Service_Serviced - BNE %BT04 - Pull "R9-R12, PC" - - ] ;ChocolateService - -01 CMP R1, #Service_ReleaseFIQ - Pull "R9-R12, PC",NE - [ :LNOT: HAL - STRB R1, [R1, #MOShasFIQ-Service_ReleaseFIQ] - ] - - [ FIQDebug - TubeChar r0, r1, "MOV r1, #""D""" - ] - assert (Service_ReleaseFIQ :AND: &FF) <> 0 - [ HAL - LDRB R9, [R1, #MOShasFIQ-Service_ReleaseFIQ] - STRB R1, [R1, #MOShasFIQ-Service_ReleaseFIQ] - TEQ R9, #0 - BNE %FT06 - - ADR R1, FIQKiller - MOV R10, #FIQKiller_ws - FIQKiller - MOV R11, #&1C -04 LDR LR, [R1], #4 - SUBS R10, R10, #4 - STR LR, [R11], #4 - BNE %BT04 - AddressHAL R10 - LDR R14, [R9, #-(EntryNo_HAL_FIQDisableAll+1)*4] - STMIA R11, {R9, R14} - Push "R0" - MOV R0, #0 ; in case 32-byte cache lines - MOV R1, #&100 - ARMop IMB_Range,,,R0 - Pull "R0" - ] - - ; MOS is default owner if nobody -06 MOV R1, #Service_Serviced ; else wants it. - Pull "R9-R12, PC" - -FIQclaim - MOV R10, #0 - - [ FIQDebug - TubeChar r0, r1, "MOV r1, #""C""" - ] - - ; first refuse request if a claim is currently in action - - LDRB R9, [R10, #FIQclaim_interlock] - CMP R9, #0 - Pull "R9-R12, PC",NE ; no can do - -; have to issue a genuine FIQ claim call: set interlock to prevent another -; one passing round at an awkward moment. - - MOV r9, #1 - STRB r9, [r10, #FIQclaim_interlock] - - [ FIQDebug - TubeChar r0, r1, "MOV r1, #""I""" - ] - -; now safe to inspect our FIQ state - - LDRB R9, [R10, #MOShasFIQ] - CMP R9, #0 - - [ FIQDebug - BEQ sam001 - TubeChar r0, r1, "MOV r1, #""M""" - CMP r9, #0 -sam001 - ] - - STRNEB R10, [R10, #MOShasFIQ] - MOVNE r1, #Service_Serviced -fakeservicecall - ; do it this way to cope with ARM v4/v3 differences on storing PC - SUBEQ stack,stack,#20 - STREQ PC,[stack,#16] - BEQ %BT05 - MOV r0, r0 - MOV r10, #0 - LDRB r9, [r10, #FIQclaim_interlock] - STRB r10, [r10, #FIQclaim_interlock] - - [ FIQDebug - TubeChar r0, r1, "MOV r1, #""i""" - ] - - CMP r9, #1 ; test for background release - - [ FIQDebug - BEQ sam002 - TubeChar r0, r1, "MOV r1, #""B""" - CMP r9, #1 -sam002 - ] - -; if background release happened, there are 3 possibilities: -; foreground claim; this is defined to have succeeded. Discard release -; background claim, that succeeded: releaser gave it away anyway. Discard -; " " " failed; we are holding a giveaway of FIQ, therefore -; claim service call! -; therefore, if background release happened, always claim the service. - - MOVNE r1, #Service_Serviced - Pull "r9-r12, PC" ; all done - -test_FIQclaim_in_progress - - [ FIQDebug - TubeChar r0, r1, "MOV r1, #""R""" - ] - - MOV r10, #0 - LDRB r9, [r10, #FIQclaim_interlock] - CMP r9, #0 - - [ {TRUE} - MOVEQ r9, #1 - STREQB r9, [r10, #FIQclaim_interlock] ; lock out background calls - BEQ fakeservicecall ; issue call, clear flag - | - BEQ %BT05 ; issue call - ] - - MOV r9, #2 ; mark release as occurring - - [ FIQDebug - TubeChar r0, r1, "MOV r1, #""b""" - ] - - STRB r9, [r10, #FIQclaim_interlock] - Pull "r9-r12, PC" - -; r9-r12, lr corruptible -checkmoshandlers - LDR r9, [r1, #SExitA-Service_NewApplication] - ADRL r10, CLIEXIT - CMP r9, r10 - BNE %BT05 - Push "r0-r7" - BL DEFHAN - BL DEFHN2 - Pull "r0-r7" - B %BT05 - - [ DebugROMPostInit - ; Display the title of the current module in the chain. - ; R9 contains the module pointer. -display_pre_postinit_calls - SWI XOS_WriteS - = "postinit service call to mod ",0 - Push "r0-r7" - LDR R0, [R9, #Module_Title] - ADD R0, R9, R0 - SWI XOS_Write0 - SWI XOS_WriteS - = " sent" - SWI XOS_NewLine - Pull "r0-r7" - B %BT83 - - ; Display a message stating that we have finished the postinit service call. - ; This will appear once for every module called on postinit. -display_post_postinit_calls - SWI XOS_WriteS - = "returned from postinit service call.",0 - SWI XOS_NewLine - B %BT87 - ] - - [ HAL -FIQKiller - SUB R14, R14, #4 - MOV R13, #&100 - ADR R10, FIQKiller_ws - STMFD R13!, {R0-R3,R14} - MOV R14, PC - LDMIA R10, {R9,PC} - LDMFD R13!, {R0-R3,PC}^ -FIQKiller_ws - ] - - -;************************************************ -; SWI to call a vector -;************************************************ -CallAVector_SWI ; R9 is the vector number (!!) - STR lr, [sp, #-4]! ; save caller PSR on stack - MOV R10, R9 - MSR CPSR_f, R12 ; restore caller CCs (including V) - BL CallVector - MRS r10, CPSR ; restore CCs - LDR lr, [sp], #4 - AND r10, r10, #&F0000000 - BIC lr, lr, #&F0000000 - ORR lr, lr, r10 - ExitSWIHandler - -;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -; Now some bits for the dynamic areas - -DoSysHeapOpWithExtension - Push "R0, lr" - B IntoSysHeapOp - -ClaimSysHeapNode ROUT ; size in R3 - MOV R0, #HeapReason_Get - Push "R0, lr" -IntoSysHeapOp - LDR R1, =SysHeapStart - SWI XOS_Heap - Pull "R0, PC", VC - - LDR r14, [r0] ; look at error number - TEQ r14, #ErrorNumber_HeapFail_Alloc - STRNE r0, [stack] - Pull "r0, r3, PC", NE ; can only retry if ran out of room - - Push r3 ; in case extension - LDR r1, [stack, #4] - CMP r1, #HeapReason_ExtendBlock - BNE notsysheapextendblock - - Push "r5, r6" - LDR r5, =SysHeapStart - LDR r6, [r5, #:INDEX:hpdbase] - ADD r6, r6, r5 ; free space - LDR r1, [r2, #-4] ; pick up block size - ADD r5, r1, r2 ; block end +4 - SUB r5, r5, #4 ; TMD 02-Aug-93: block size includes size field (optimisation was never taken) - CMP r5, r6 ; does block butt against end? - ADDNE r3, r3, r1 ; max poss size needed - Pull "r5, r6" - - ; note that this doesn't cope well with a block at the end preceded by a - ; free block, but tough. - -notsysheapextendblock - LDR r1, =SysHeapStart - LDR R0, hpdbase - LDR R1, hpdend - SUB R1, R1, R0 ; size left in heap - SUB R1, R3, R1 ; size needed - Pull r3 - ADD R1, R1, #8 ; plus safety space. - MOV R0, #0 - SWI XOS_ChangeDynamicArea - LDRVC R0, [stack] ; and retry. - LDRVC R1, =SysHeapStart - SWIVC XOS_Heap - Pull "R0, PC", VC -SysClaimFail - ADD stack, stack, #4 - ADR R0, ErrorBlock_SysHeapFull - [ International - BL TranslateError - ] - Pull "PC" - MakeErrorBlock SysHeapFull - -;************************************************************************** -; -; FreeSysHeapNode - Free a node in system heap -; -; in: R2 -> node to free -; -; out: R0 = HeapReason_Free or pointer to error if V=1 -; R1 = SysHeapStart -; - -FreeSysHeapNode Entry - MOV R0, #HeapReason_Free - LDR R1, =SysHeapStart - SWI XOS_Heap - EXIT - -;************************************************************************** - -; ValidateAddress_Code -; R0, R1 are limits of address range to check -; return CC for OK, CS for naff - -ValidateAddress_Code ROUT - Push "R1, lr" - CMP R0, R1 - SUBNE R1, R1, #1 ; cope with zero length range sensibly - MOV R10, #0 - - MOV R11, #0 - LDR R12, [R10, #AplWorkSize] - BL RangeCheck - - LDR r11, =SVCStackAddress - ADD r12, r11, #SVCStackSize - BL RangeCheck - - [ IRQStackAddress <> CursorChunkAddress - LDR r11, =IRQStackAddress - ADD r12, r11, #IRQStackSize - BL RangeCheck - ] - - LDR r11, =UNDStackAddress - ADD r12, r11, #UNDStackSize - BL RangeCheck - - LDR r11, =ABTStackAddress - ADD r12, r11, #ABTStackSize - BL RangeCheck - - ! 0, "ValidateAddress - what about CAM and page tables? - strictly should be included" - - LDR R11, =CursorChunkAddress - ADD R12, R11, #32*1024 - BL RangeCheck - - VDWS R12 ; in case of external framestore - LDR R11, [R12, #ScreenEndAddr] - LDR R12, [R12, #TotalScreenSize] - SUB R11, R11, R12 - ADD R12, R11, R12, LSL #1 ; doubly-mapped friggage - BL RangeCheck - -; not in one of those ranges, so check against dynamic area list - MOV r10, #DAList -10 - LDR r10, [r10, #DANode_Link] - TEQ r10, #0 ; end of list - BEQ %FT20 - LDR r11, [r10, #DANode_Base] - LDR r12, [r10, #DANode_Flags] - TST r12, #DynAreaFlags_DoublyMapped - LDR r12, [r10, #DANode_Size] - SUBNE r11, r11, r12 ; if doubly mapped, move base back by size - MOVNE r12, r12, LSL #1 ; and double size - ADD r12, r12, r11 ; make r12 point at end (exclusive) - CMP r0, r12 ; if start >= end (excl) - BCS %BT10 ; then go onto next node - - CMP r0, r11 ; if range starts below this area - BCC %FT20 ; then not totally within this area - CMP r1, r12 ; else if range ends before end+1 of this area - BCC AddressIsValid ; then it's valid -20 - -; not in one of those ranges, so issue service so modules can add other valid areas - - Push "R2, R3" - MOV R2, R0 ; pass parameters to service in R2 and R3 - LDR R3, [stack, #2*4] ; reload stacked R1 into R3 - MOV R1, #Service_ValidateAddress - BL Issue_Service - TEQ R1, #0 ; EQ => service claimed, so OK - Pull "R2, R3" - Pull "R1, lr" - ORRNE lr, lr, #C_bit ; return CS if invalid - BICEQ lr, lr, #C_bit ; return CC if valid - ExitSWIHandler - -RangeCheck ; check R0 - R1 lies totally within R11 - (r12-1) - - SUB R12, R12, #1 - CMP R0, R11 - CMPCS R12, R0 - CMPCS R1, R11 - CMPCS R12, R1 - MOVCC PC, lr ; failed -AddressIsValid - Pull "R1, lr" - BIC lr, lr, #C_bit - ExitSWIHandler - - LTORG - - END diff --git a/s/ChangeDyn b/s/ChangeDyn deleted file mode 100644 index 0a263c3f..00000000 --- a/s/ChangeDyn +++ /dev/null @@ -1,4773 +0,0 @@ -; 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 => ChangeDyn - -;****************************************************************************** -; ChangeDynamic SWI -; In : R0 = 0 => System Heap, -; 1 => RMA -; 2 => Screen -; 3 => Sprite area -; 4 => Font cache -; 5 => RAM disc -; 6 => Free pool -; R1 = no of bytes to change by -; -; Out : V set if CAO in AplWork or couldn't move all the bytes requested. -; R1 set to bytes moved. -;****************************************************************************** - -; The following flag controls the operation of ReadCMOSAndConfigure and FudgeConfigureRMA -; -; If false, then no memory is in the free pool to start off, and these routines just allocate pages -; starting at page R2, and update this on exit. -; -; If true, then routine InitDynamicAreas initially moves all non-static free memory into the free pool, -; and then the above routines just take pages off the end of that. - - GBLL GetPagesFromFreePool ; whether ReadCMOSAndConfigure extract pages from the free pool -GetPagesFromFreePool SETL {TRUE} - -AP_AppSpace * 0 ; user r/w, CB -AP_SysHeap * 0 ; user r/w, CB -AP_RMA * 0 ; user r/w, CB -AP_Screen * 0 :OR: DynAreaFlags_NotCacheable :OR: DynAreaFlags_DoublyMapped :OR: DynAreaFlags_NeedsSpecificPages -AP_Sprites * 0 ; user r/w, CB -AP_FontArea * 2 ; user none, CB -AP_RAMDisc * 2 :OR: DynAreaFlags_NotCacheable ; user none, ~CB (poor performance for current StrongARMs) -AP_RAMDisc_SA * 2 ; user none, -AP_Duff * 2 :OR: DynAreaFlags_NotCacheable :OR: DynAreaFlags_NotBufferable ; user none, ~C~B -AP_FreePool * 2 :OR: DynAreaFlags_NotCacheable ; user none, ~CB -AP_CursorChunk * 1 :OR: DynAreaFlags_NotCacheable :OR: DynAreaFlags_NotBufferable :OR: PageFlags_Unavailable -AP_PageZero * 0 - -AP_L2PT * 2 :OR: DynAreaFlags_NotCacheable :OR: DynAreaFlags_NotBufferable ; user none, ~C~B -AP_L1PT * AP_L2PT :OR: PageFlags_Unavailable -AP_UndStackSoftCam * PageFlags_Unavailable - - [ DA_Batman -ChangeDyn_Batcall * -3 ; special DA number to select Batman usage of OS_ChangeDynamicArea - ] -ChangeDyn_FreeAndApl * -2 ; special reason code for when we're sucking out of free pool and apl space -ChangeDyn_AplSpace * -1 -ChangeDyn_SysHeap * 0 -ChangeDyn_RMA * 1 -ChangeDyn_Screen * 2 -ChangeDyn_SpriteArea * 3 -ChangeDyn_FontArea * 4 -ChangeDyn_RamFS * 5 -ChangeDyn_FreePool * 6 -ChangeDyn_MaxArea * 6 - -; Area handler reason codes - -DAHandler_PreGrow * 0 -DAHandler_PostGrow * 1 -DAHandler_PreShrink * 2 -DAHandler_PostShrink * 3 - [ ShrinkableDAs -DAHandler_TestShrink * 4 ; new reason added to find amount area could shrink by - ] - -; Number of entries in page block on stack - -NumPageBlockEntries * 63 -PageBlockSize * NumPageBlockEntries * 12 -PageBlockChunk * NumPageBlockEntries * 4096 - -; -; mjs - performance enhancements (from Ursula, merged into HALised kernel June 2001) -; Workspace for acceleration of operations on a DA, by reducing need to traverse DA list. -; -; - accelerates allocating non-quick DA numbers to O(n) instead of laughable O(n*n), where n is no. of DAs -; - accelerates enumeration to O(n) instead of laughable O(n*n) -; - allocation of a quick handle (DA number) is O(1) -; - access of a DA node from a quick handle is O(1) -; - access of a DA node from a non-quick handle is O(1), if it repeats the most recent non-quick handle access (else O(n)) -; -; - creation of a DA still has some O(n) work (requires search for address space), but is now rather quicker -; - removal of a DA is still O(n) (requires traversal of list in order to get previous node) -; - other uses of a DA with a quick handle (eg. get info, change size) avoid any O(n) work -; -; - all system handles will be quick. -; - non-system handles will be quick, except for very large numbers of DAs, or silly modules like the Wimp who insist on -; their own silly DA number (the latter can still benefit from LastTreacleHandle - see below) -; -; Limitations: -; - does not allow anyone to choose their own DA number that clashes with the quick handle set - should not -; be a problem since choosing own number reserved for Acorn use -; - does not allow anyone to renumber a DA with a quick handle - again, reserved for system use -; - DA names will be truncated to a maximum of 31 characters (or as defined below) -; - GBLL DynArea_QuickHandles -DynArea_QuickHandles SETL {TRUE} -; - ;various bad things happen if DynArea_QuickHandles is FALSE (eg. some new API disappears) - ;should remove FALSE build option to simplify source code next time kernel is updated (kept for reference/testing now) - ASSERT DynArea_QuickHandles - - GBLL DynArea_NullNamePtrMeansHexString -DynArea_NullNamePtrMeansHexString SETL {TRUE} :LAND: DynArea_QuickHandles -; - [ DynArea_QuickHandles -DynArea_MaxNameLength * 31 ;maximum length of DA name, excluding terminator (multiple of 4, -1) -DynArea_NumQHandles * 256 ;maximum no. of non-system quick handles available simultaneously -; - ^ 0,R11 -DynArea_TreacleGuess # 4 ;guess for next non-quick handle to allocate, if needed, is TreacleGuess+1 -DynArea_CreatingHandle # 4 ;handle proposed but not yet committed, during DynArea_Create, or -1 if none -DynArea_CreatingPtr # 4 ;ptr to proposed DANode during DynArea_Create (invalid if CreatingHandle = -1) -DynArea_LastTreacleHandle # 4 ;last non-quick handle accessed by a client (usually the Wimp), or -1 if none -DynArea_LastTreaclePtr # 4 ;ptr to DANode for last non-quick handle accessed (invalid if LastTreacleHandle = -1) -DynArea_LastEnumHandle # 4 ;last handle enumerated, or -1 if none -DynArea_LastEnumPtr # 4 ;ptr to DANode for last handle enumerated (invalid if LastEnumHandle = -1) -DynArea_ShrinkableSubList # 4 ;sub list of dynamic areas that are Shrinkable (0 if none) -DynArea_OD6Signature # 4 ;signature of changes to non-system DAs since last call to OS_DynamicArea 6 - ;bit 0 = 1 if any DAs have been created - ;bit 1 = 1 if any DAs have been removed - ;bit 2 = 1 if any DAs have been resized (excluding grow or shrink at creation or removal) - ;bit 3 = 1 if any DAs have been renumbered - ;bits 4-30 reserved (0) - ;bit 31 = 1 if next resize is not to update signature (used during create, remove) -DynArea_OD6PrevSignature # 4 ;previous signature, used to distinguish single from multiple changes -DynArea_OD6Handle # 4 ;handle of last DA that affected signature -DynArea_OD8Clamp1 # 4 ;clamp value on area max size for OS_DynamicArea 0 with R5 = -1 - ;(default -1, set by R1 of OS_DynamicArea 8) -DynArea_OD8Clamp2 # 4 ;clamp value on area max size for OS_DynamicArea 0 with R5 > 0 (not Sparse) - ;(default -1, set by R2 of OS_DynamicArea 8) -DynArea_OD8Clamp3 # 4 ;clamp value on area max size for OS_DynamicArea 0 for a Sparse area - ;(default 4G-4k, set by R3 of OS_DynamicArea 8) -DynArea_SortedList # 4 ;alphabetically sorted list of non-system areas, or 0 if none -DynArea_SysQHandleArray # 4*(ChangeDyn_MaxArea+1) ;for system areas 0..MaxArea, word = ptr to DANode, or 0 if not created yet -DynArea_FreeQHandles # 4 ;index of first free quick handle, starting at 1 (or 0 for none) -DynArea_QHandleArray # 4*DynArea_NumQHandles ;1 word per quick handle - ; - if free, word = index of next free quick handle (or 0 if none) - ; - if used, word = ptr to DANode (must be > DynArea_NumQHandles) -; -DynArea_ws_size * :INDEX:@ ;must be multiple of 4 -; - ASSERT DynArea_QHandleArray = DynArea_FreeQHandles +4 - ] -; - - -; InsertDebugRoutines - -; Exit from ChangeDynamicArea with error Not all moved - -failure_IRQgoingClearSemaphore - MOV r0, #0 - STR r0, [r0, #CDASemaphore] -failure_IRQgoing - ADR r0, ErrorBlock_ChDynamNotAllMoved -ChangeDynamic_Error - MOV r10, #0 - STR r0, [stack] - LDR lr, [stack, #4*10] - ORR lr, lr, #V_bit - STR lr, [stack, #4*10] -CDS_PostServiceWithRestore - [ International - LDR r0, [stack] - BL TranslateError - STR r0, [stack] - ] - -; and drop thru to ... - -CDS_PostService - MOV r1, #Service_MemoryMoved - MOV r0, r10 ; amount moved - MOVS r2, r11 ; which way was transfer? - BMI %FT47 ; [definitely a grow] - CMP r11, #ChangeDyn_FreePool - BNE %FT48 ; [definitely a shrink] - CMP r12, #ChangeDyn_AplSpace - BEQ %FT48 ; [a shrink] -47 - RSB r0, r0, #0 ; APLwork or free was source - MOV r2, r12 ; r2 = area indicator -48 - BL Issue_Service - - MOV r1, r10 ; amount moved - - Pull "r0, r2-r9, r10, lr" - ExitSWIHandler - - MakeErrorBlock ChDynamNotAllMoved - - -; in: r0 = logical address where page is now - -GetPageFlagsForR0IntoR6 Entry "R0-R2, R4-R5, R7" -; -; code from MoveCAMatR0toR3 -; - LDR r5, =L2PT - ADD r4, r5, r0, LSR #10 ; r4 -> L2PT for log addr r0 - MOV r2, r4, LSR #12 - LDR r2, [r5, r2, LSL #2] ; r2 = L2PT entry for r4 - TST r2, #3 ; if no page there - BEQ %FT90 ; then cam corrupt - - LDR r4, [r4] ; r4 = L2PT entry for r0 - TST r4, #3 ; check entry is valid too - BEQ %FT91 - MOV r4, r4, LSR #12 ; r4 = phys addr >> 12 - - MOV r2, #0 - LDR r6, [r2, #MaxCamEntry] - MOV r5, #PhysRamTable -10 - CMP r2, r6 ; if page we've got to is > max - BHI %FT92 ; then corrupt - LDMIA r5!, {r7, lr} ; get phys.addr, size - SUB r7, r4, r7, LSR #12 ; number of pages into this bank - CMP r7, lr, LSR #12 ; if too many - ADDCS r2, r2, lr, LSR #12 ; then advance physical page no. - BCS %BT10 ; and loop - - ADD r2, r2, r7 ; add on number of pages within bank -; -; code from BangCamUpdate -; - MOV r1, #0 - LDR r1, [r1, #CamEntriesPointer] - ADD r1, r1, r2, LSL #3 ; point at cam entry (logaddr, PPL) - LDMIA r1, {r0, r6} ; r0 = current logaddress, r6 = current PPL - EXIT - -90 - ADR lr, NoL2ForPageBeingRemovedError ; NB don't corrupt r0 yet - we need that in block as evidence -95 - STR lr, [sp] ; update returned r0 - BL StoreDebugRegs - PullEnv ; seriously broken memory - SETV - MOV pc, lr - -91 - ADR lr, PageBeingRemovedNotPresentError - B %BT95 - -92 - ADR lr, PhysicalAddressNotFoundError - B %BT95 - - -; MoveCAMatR0toR3 -; in: r0 = old logaddr -; r3 = new logaddr -; r9 = MEMC CR -; r11 = page protection level -; -; out: r2 = physical page number of page moved, unless there was a serious error -; r0,r1,r3,r6-r12 preserved -; r4,r5 corrupted - -MoveCAMatR0toR3 Entry "r0,r1,r6,r7" - LDR r5, =L2PT - ADD r4, r5, r0, LSR #10 ; r4 -> L2PT for log addr r0 - MOV r2, r4, LSR #12 - LDR r2, [r5, r2, LSL #2] ; r2 = L2PT entry for r4 - TST r2, #3 ; if no page there - BEQ %FT90 ; then cam corrupt - - LDR r4, [r4] ; r4 = L2PT entry for r0 - TST r4, #3 ; check entry is valid too - BEQ %FT91 - MOV r4, r4, LSR #12 ; r4 = phys addr >> 12 - - MOV r2, #0 - LDR r6, [r2, #MaxCamEntry] - MOV r5, #PhysRamTable -10 - CMP r2, r6 ; if page we've got to is > max - BHI %FT92 ; then corrupt - LDMIA r5!, {r7, lr} ; get phys.addr, size - SUB r7, r4, r7, LSR #12 ; number of pages into this bank - CMP r7, lr, LSR #12 ; if too many - ADDCS r2, r2, lr, LSR #12 ; then advance physical page no. - BCS %BT10 ; and loop - - ADD r2, r2, r7 ; add on number of pages within bank - BL BangCamUpdate - CLRV - EXIT - -90 - ADR lr, NoL2ForPageBeingRemovedError ; NB don't corrupt r0 yet - we need that in block as evidence -95 - STR lr, [sp] ; update returned r0 - BL StoreDebugRegs - PullEnv ; seriously broken memory - SETV - MOV pc, lr - -91 - ADR lr, PageBeingRemovedNotPresentError - B %BT95 - -92 - ADR lr, PhysicalAddressNotFoundError - B %BT95 - -StoreDebugRegs - Push "lr" - MOV lr, #CamMapCorruptDebugBlock - STMIA lr, {r0-lr} - LDR r0, [sp, #1*4] ; reload stacked r0 (error pointer) - STR r0, [lr, #15*4] ; store in stacked PC position - Pull "pc" - -NoL2ForPageBeingRemovedError - & 0 - = "Memory Corrupt: No L2PT for page being removed", 0 - ALIGN - -PageBeingRemovedNotPresentError - & 0 - = "Memory Corrupt: Page being removed was not present", 0 - ALIGN - -PhysicalAddressNotFoundError - & 0 - = "Memory Corrupt: Physical address not found", 0 - ALIGN - -CamMapBroke - & 0 - = "!!!! CAM Map Corrupt !!!!", 0 - ALIGN -Call_CAM_Mapping - Push "r0, r1, r4, r6, lr" - BL BangCamUpdate - Pull "r0, r1, r4, r6, pc" - - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; In r0 bits 0..6 = area number -; r0 bit 7 set => return max area size in r2 (implemented 13 Jun 1990) -; this will return an error if not implemented -; Out r0 = address of area -; r1 = current size of area -; r2 = max size of area if r0 bit 7 set on entry (preserved otherwise) - -; TMD 19-May-93: When this is updated to new CDA list, change meaning as follows: - -; r0 in range 0..&7F return address, size of area r0 -; &80..&FF return address, size, maxsize of area (r0-&80) -; &100.. return address, size, maxsize of area r0 - -; TMD 20-Aug-93: New bit added - if r0 = -1 on entry, then returns info on application space -; r0 = base address (&8000) -; r1 = current size (for current task) -; r2 = maximum size (eg 16M-&8000) - -ReadDynamicArea ROUT - -readdyn_returnR2bit * &80 - ASSERT ChangeDyn_MaxArea < readdyn_returnR2bit - - CMP r0, #-1 ; if finding out about app space - LDREQ r1, [r0, #AplWorkSize+1] ; then r1 = current size -; [ HAL32 -; LDREQ r2, [r0, #RAMLIMIT+1] -; | - LDREQ r2, =AplWorkMaxSize ; and r2 = max size -; ] - MOVEQ r0, #&8000 ; r0 = base address - SUBEQ r1, r1, r0 ; adjust size and maxsize - SUBEQ r2, r2, r0 ; to remove bottom 32K - ExitSWIHandler EQ - -; first check if it's one of the new ones - - Push "r1,lr" - CMP r0, #&100 ; if area >= &100 - MOVCS r1, r0 ; then just use area - BICCC r1, r0, #readdyn_returnR2bit ; else knock off bit 7 - [ DynArea_QuickHandles - BL QCheckAreaNumber ; out: r10 -> node - | - BL CheckAreaNumber ; out: r10 -> node - ] - Pull "r1,lr" - BCC %FT05 ; [not a new one, so use old code] - - CMP r0, #&80 ; CS => load maxsize into R2 - ; (do this either if bit 7 set, or area >=&100) - LDRCS r2, [r10, #DANode_MaxSize] - LDR r11, [r10, #DANode_Flags] ; if doubly mapped - LDR r1, [r10, #DANode_Size] ; r1 = current size - LDR r0, [r10, #DANode_Base] ; r0 -> base - TST r11, #DynAreaFlags_DoublyMapped - SUBNE r0, r0, r1 ; then return start of 1st copy for compatibility - ExitSWIHandler -05 - ADRL r0, ErrorBlock_BadDynamicArea - [ International - Push "lr" - BL TranslateError - Pull "lr" - ] - B SLVK_SetV - - MakeErrorBlock BadDynamicArea - -; ************************************************************************* -; User access to CAM mapping -; ReadMemMapInfo: -; returns R0 = pagsize -; R1 = number of pages in use (= R2 returned from SetEnv/Pagesize) -; ************************************************************************* - -ReadMemMapInfo_Code - MOV R10, #0 - LDR R0, [R10, #Page_Size] - LDR R1, [R10, #RAMLIMIT] ; = total memory size - ADRL R11, PageShifts-1 - LDRB R11, [R11, R0, LSR #12] - MOV R1, R1, LSR R11 - ExitSWIHandler - -; ************************************************************************ -; SWI ReadMemMapEntries: R0 pointer to list. -; Entries are three words long, the first of which is the CAM page number. -; List terminated by -1. -; Returns pagenumber (unaltered)/address/PPL triads as below -; ************************************************************************ - -ReadMemMapEntries_Code ROUT - Push "r0,r14" - MOV r14, #0 - LDR r10, [r14, #CamEntriesPointer] - LDR r14, [r14, #MaxCamEntry] -01 - LDR r12, [r0], #4 ; page number - CMP r12, r14 - Pull "r0,r14", HI - ExitSWIHandler HI - - [ ChocolateAMB - ;may need AMB to make mapping honest (as if not lazy), if page is in currently mapped app - Push "r0, lr" - MOV r0, r12 ; page number to make honest - BL AMB_MakeHonestPN - Pull "r0, lr" - ] - - ADD r11, r10, r12, LSL #3 - LDMIA r11, {r11, r12} - STMIA r0!, {r11, r12} - B %BT01 - -; ************************************************************************ -; SWI FindMemMapEntries: -; In: R0 -> table of 12-byte page entries -; +0 4 probable page number (0..npages-1) (use 0 if no idea) -; +4 4 logical address to match with -; +8 4 undefined -; terminated by a single word containing -1 -; -; Out: table of 12-byte entries updated: -; +0 4 actual page number (-1 => not found) -; +4 4 address (preserved) -; +8 4 page protection level (3 if not found) -; terminator preserved -; -; ************************************************************************ - -FindMemMapEntries_Code ROUT - -; Code for expanded CAM map version - - Push "r0, r9, r14" - MOV r14, #0 - LDR r9, [r14, #MaxCamEntry] - LDR r14, [r14, #CamEntriesPointer] ; r14 -> start of cam map - ADD r9, r14, r9, LSL #3 ; r9 -> first word of last entry in cam map -10 - LDR r10, [r0, #0] ; r10 = guess page number (or -1) - CMP r10, #-1 ; if -1 then end of list - Pull "r0, r9, r14", EQ ; so restore registers - ExitSWIHandler EQ ; and exit - - LDR r11, [r0, #4] ; r11 = logical address - - [ ChocolateAMB - ;may need AMB to make mapping honest (as if not lazy), if page is in currently mapped app - Push "r0, lr" - MOV r0, r11 ; logical address to make honest - BL AMB_MakeHonestLA ; note, quickly dismisses non app space addresses - Pull "r0, lr" - ] - - ADD r10, r14, r10, LSL #3 ; form address with 'guess' page - CMP r10, r9 ; if off end of CAM - BHI %FT20 ; then don't try to use the guess - - LDR r12, [r10] ; load address from guessed page - TEQ r11, r12 ; compare address - BEQ %FT60 ; if equal, then guessed page was OK -20 - -; for now, cheat by looking in L2PT, to see if we can speed things up - - Push "r5-r8" ; need some registers here! - LDR r10, =L2PT - MOV r8, r11, LSR #12 ; r8 = logical page number - ADD r8, r10, r8, LSL #2 ; r8 -> L2PT entry for log.addr - MOV r5, r8, LSR #12 ; r5 = page offset to L2PT entry for log.addr - LDR r5, [r10, r5, LSL #2] ; r5 = L2PT entry for L2PT entry for log.addr - TST r5, #3 ; if page not there - SUBEQ r10, r9, #8 ; then invalid page so go from last one - BEQ %FT45 - LDR r8, [r8] ; r8 = L2PT entry for log.addr - MOV r8, r8, LSR #12 ; r8 = physaddr / 4K - - MOV r5, #PhysRamTable - SUB r10, r14, #8 -30 - CMP r10, r9 ; have we run out of RAM banks? - BCS %FT40 ; then fail - LDMIA r5!, {r6,r7} ; load next address, size - SUB r6, r8, r6, LSR #12 ; number of pages into this bank - CMP r6, r7, LSR #12 ; if more than there are - ADDCS r10, r10, r7, LSR #12-3 ; then advance CAM entry position - BCS %BT30 ; and loop to next bank - - ADD r10, r10, r6, LSL #3 ; advance by 2 words for each page in this bank -40 - SUBCS r10, r9, #8 ; search from last one, to fail quickly (if CS) -45 - Pull "r5-r8" -50 - CMP r10, r9 ; if not just done last one, - LDRNE r12, [r10, #8]! ; then get logical address - TEQNE r11, r12 ; compare address - BNE %BT50 ; loop if not same and not at end - -; either found page or run out of pages - - TEQ r11, r12 ; see if last one matched - ; (we always load at least one!) -60 - LDREQ r12, [r10, #4] ; if match, then r12 = PPL - SUBEQ r10, r10, r14 ; and page number=(r10-r14)>>3 - MOVEQ r10, r10, LSR #3 - - MOVNE r10, #-1 ; else unknown page number indicator - MOVNE r12, #3 ; and PPL=3 (no user access) - - STMIA r0!, {r10-r12} ; store all 3 words - B %BT10 ; and go back for another one - -;************************************************************************** -; SWI SetMemMapEntries: R0 pointer to list of CAM page/address/PPL triads, -; terminated by -1. -; address of -1 means "put the page out of the way" -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -; note, if ChocolateAMB, no MakeHonest consideration here, this SWI just -; changes the mapping of pages regardless of their current mapping, and -; assumes the caller knows what he is doing (ho ho) -; - -SetMemMapEntries_Code ROUT - Push "r0-r6, r9, lr" - MOV r12, r0 - -; BangCamUpdate takes entry no in r2, logaddr to set to in r3 -; r9 current MEMC, r11 = PPL -; corrupts r0,r1,r4,r6 - - MOV r9, #0 - LDR r5, [r9, #MaxCamEntry] - LDR r9, [r9, #MEMC_CR_SoftCopy] -01 - LDR r2, [r12], #4 - CMP r2, r5 - BHI %FT02 ; finished - LDMIA r12!, {r3, r11} - [ {FALSE} - AND r11, r11, #3 - ] - CMP r3, #-1 - LDRHS r3, =DuffEntry - MOVHS r11, #AP_Duff - BL BangCamUpdate - B %BT01 -02 - Pull "r0-r6, r9, lr" - ExitSWIHandler - - LTORG - - - -;************************************************************************** -; -; DynamicAreaSWI - Code to handle SWI OS_DynamicArea -; -; in: r0 = reason code -; Other registers depend on reason code -; -; out: Depends on reason code -; - - -DAReason_Create * 0 -DAReason_Remove * 1 -DAReason_GetInfo * 2 -DAReason_Enumerate * 3 -DAReason_Renumber * 4 - [ ShrinkableDAs -DAReason_ReturnFree * 5 ;if ShrinkableDAs, else reason code invalid - ] - [ DynArea_QuickHandles -DAReason_GetChangeInfo * 6 ;if DynArea_Quickhandles, else reason code invalid -DAReason_EnumerateInfo * 7 ;if DynArea_Quickhandles, else reason code invalid -DAReason_SetClamps * 8 ;if DynArea_Quickhandles, else reason code invalid - ] - [ DA_Batman -DAReason_SparseClaim * 9 ;if DA_Batman, else reason code invalid -DAReason_SparseRelease * 10 ;if DA_Batman, else reason code invalid - ] -DAReason_Limit * 11 ;end of defined DA reasons - - -DynArea_NewAreas * &100 ; Allocated area numbers start here -DynArea_NewAreasBase * &04000000 ; Allocated area addresses start here - - -; Bits in dynamic area flags (and page flags) -; -; rearranged slightly for Ursula - allow room for some expansion of DA flags in future without moving page flags -; mjs June 2001 merged the Ursula arrangement into HALised kernel -; -DynAreaFlags_APBits * 15 :SHL: 0 ; currently only uses 2 bits, but may extend to allow svc/usr read-only -DynAreaFlags_NotBufferable * 1 :SHL: 4 -DynAreaFlags_NotCacheable * 1 :SHL: 5 -DynAreaFlags_DoublyMapped * 1 :SHL: 6 -DynAreaFlags_NotUserDraggable * 1 :SHL: 7 -DynAreaFlags_NeedsSpecificPages * 1 :SHL: 8 ; whether area will ever require particular physical pages -DynAreaFlags_Shrinkable * 1 :SHL: 9 ; whether area may be shrunk when need more space in free pool -DynAreaFlags_SparseMap * 1 :SHL: 10 ; whether area may have non-contiguous mapping of pages (Holey dynamic areas Batman!) -DynAreaFlags_PiersBinding * 1 :SHL: 11 ; whether area is bound to client application, and so may be swapped out with it (not implemented yet) -DynAreaFlags_CPBits * 7 :SHL: 12 ; cache policy variant for NotBufferable and NotCacheable bits - -; Cache policies -; -CP_NCNB_Default * 0 ; no policy variants - -CP_NCB_Default * 0 ; OS decides buffer policy (currently always coalescing) -CP_NCB_NonMerging * 1 ; Non-merging write buffer. If not available, unbuffered. -CP_NCB_Merging * 2 ; Merging write buffer. If not available, non-merging. - -CP_CNB_Default * 0 ; OS decides cache policy (writethrough). NCNB if not available -CP_CNB_Writethrough * 1 ; Writethrough cacheable, non-buffered. If not available, NCNB. -CP_CNB_Writeback * 2 ; Writeback cacheable, non-buffered. If not available,CNB_Writethrough. - -CP_CB_Default * 0 ; OS decides cache policy (WB if available, W alloc if HAL requests) -CP_CB_Writethrough * 1 ; Writethrough cacheable, read allocate. If not available, NCB_Merging -CP_CB_WritebackReadAlloc * 2 ; Writeback cacheable, read allocate. If not available, writethrough. -CP_CB_WritebackWriteAlloc * 3 ; Writeback cacheable, write allocate. If not available, WB/R. -CP_CB_AlternativeDCache * 4 ; Use XScale/SA11x0 mini-data cache. If not available, CB_Default. - -; -; bits 15 nominally reserved for future DA flags expansion -; -DynAreaFlags_AccessMask * DynAreaFlags_APBits :OR: DynAreaFlags_NotBufferable :OR: DynAreaFlags_NotCacheable :OR: DynAreaFlags_DoublyMapped :OR: DynAreaFlags_CPBits -; -; The following bits are only present in page flags -; -TempUncacheableShift * 16 -PageFlags_TempUncacheableBits * 15 :SHL: TempUncacheableShift ; temporary count of uncacheability, used by DMA mgr -PageFlags_Unavailable * 1 :SHL: 20 ; physical page may not be requested by a PreShrink handler -; -; Temporary flags only used by kernel -; -PageFlags_Required * 1 :SHL: 21 ; physical page asked for by handler - - -DynamicAreaSWI Entry - BL DynAreaSub - PullEnv - ORRVS lr, lr, #V_bit - ExitSWIHandler - -DynAreaSub - CMP r0, #DAReason_Limit - ADDCC pc, pc, r0, LSL #2 - B DynArea_Unknown - B DynArea_Create - B DynArea_Remove - B DynArea_GetInfo - B DynArea_Enumerate - B DynArea_Renumber - [ ShrinkableDAs - B DynArea_ReturnFree - | - B DynArea_Unknown - ] - [ DynArea_QuickHandles - B DynArea_GetChangeInfo - B DynArea_EnumerateInfo - B DynArea_SetClamps - | - B DynArea_Unknown - B DynArea_Unknown - B DynArea_Unknown - ] - [ DA_Batman - B DynArea_SparseClaim - B DynArea_SparseRelease - | - B DynArea_Unknown - B DynArea_Unknown - ] -; -; unknown OS_DynamicArea reason code -; -DynArea_Unknown - ADRL r0, ErrorBlock_HeapBadReason -DynArea_TranslateAndReturnError - [ International - Push lr - BL TranslateError - Pull lr - ] -DynArea_ReturnError - SETV - MOV pc, lr - -;************************************************************************** -; -; DynArea_Create - Create a dynamic area -; -; Internal routine called by DynamicAreaSWI and by reset code -; -; in: r0 = reason code (0) -; r1 = new area number, or -1 => RISC OS allocates number -; r2 = initial size of area (in bytes) -; r3 = base logical address of area, or -1 => RISC OS allocates address space -; r4 = area flags -; bits 0..3 = access privileges -; bit 4 = 1 => not bufferable -; bit 5 = 1 => not cacheable -; bit 6 = 0 => area is singly mapped -; = 1 => area is doubly mapped -; bit 7 = 1 => area is not user draggable in TaskManager window -; bit 8 = 1 => area may require specific physical pages -; bit 9 = 1 => area is shrinkable (only implemented if ShrinkableDAs) -; bit 10 = 1 => area may be sparsely mapped (only implemented if DA_Batman) -; bit 11 = 1 => area is bound to client application (allows areas to be overlayed in address space) -; not implemented yet, but declared in public API for Ursula -; bits 12..15 reserved for future DA flag expansion (should be 0) -; bits 16..31 reserved for internal page flags (should be 0) -; -; r5 = maximum size of area, or -1 for total RAM size -; r6 -> area handler routine -; r7 = workspace pointer for area handler (-1 => use base address) -; r8 -> area description string (null terminated) (gets copied) -; -; out: r1 = given or allocated area number -; r3 = given or allocated base address of area -; r5 = given or allocated maximum size -; r0, r2, r4, r6-r9 preserved -; r10-r12 may be corrupted -; - -DynArea_Create Entry "r2,r6-r8" - CMP r1, #-1 ; do we have to allocate a new area number - BEQ %FT10 - - [ DynArea_QuickHandles - CMP r1, #DynArea_NewAreas - BLO %FT06 - CMP r1, #DynArea_NewAreas+DynArea_NumQHandles - BLO %FT08 ; can't choose your own quick handle - ] - -06 - [ DynArea_QuickHandles - BL QCheckAreaNumber ; see if area number is unique - | - BL CheckAreaNumber ; see if area number is unique - ] - BCC %FT20 ; didn't find it, so OK - -08 - ADR r0, ErrorBlock_AreaAlreadyExists -DynArea_ErrorTranslateAndExit - PullEnv - B DynArea_TranslateAndReturnError - - MakeErrorBlock AreaAlreadyExists - MakeErrorBlock AreaNotOnPageBdy - MakeErrorBlock OverlappingAreas - MakeErrorBlock CantAllocateArea - MakeErrorBlock CantAllocateLevel2 - MakeErrorBlock UnknownAreaHandler - -; we have to allocate an area number for him - - [ DynArea_QuickHandles -10 - MOV r11, #0 - LDR r11, [r11, #DynArea_ws ] - LDR r1, DynArea_FreeQHandles ;get index of next available quick handle, if any free - CMP r1, #0 - ADDNE r1, r1, #DynArea_NewAreas-1 ;compute quick handle from index - BNE %FT20 - LDR r1, DynArea_TreacleGuess ;last non-quick number allocated -12 - ADD r1, r1, #1 ; increment for next guess (collisions should be *very* rare) - CMP r1, #DynArea_NewAreas+DynArea_NumQHandles - MOVLO r1, #DynArea_NewAreas+DynArea_NumQHandles - BL QCheckAreaNumber - BCS %BT12 ; and try again - | -10 - MOV r1, #DynArea_NewAreas -12 - BL CheckAreaNumber - ADDCS r1, r1, #1 ; that area number already exists, so increment - BCS %BT12 ; and try again - ] - -20 - -; now validate maximum size of area - - [ DynArea_QuickHandles - ; - ; apply clamps on max size, as set by last call to OS_DynamicArea 8 - ; - MOV r11, #0 - LDR r11, [r11, #DynArea_ws] - [ DA_Batman - TST r4, #DynAreaFlags_SparseMap - BEQ DAC_notsparse - LDR r10, DynArea_OD8Clamp3 ; clamp for sparse dynamic area - CMP r5, r10 ; if requested max size is > relevant clamp - MOVHI r5, r10 ; then clamp it! - LDR r10, [sp] ; requested initial size, from stack - CMP r5, r10 - MOVLO r5, r10 ; we must try to honour initial size (allowed to break clamp) - MOV r10, #0 - LDR r11, [r10, #Page_Size] - B DAC_roundup -DAC_notsparse - ] - CMP r5, #-1 - LDREQ r10, DynArea_OD8Clamp1 ; clamp for max size requested of -1 - LDRNE r10, DynArea_OD8Clamp2 ; clamp for max size requested of some specific value - CMP r5, r10 ; if requested max size is > relevant clamp - MOVHI r5, r10 ; then clamp it! - LDR r10, [sp] ; requested initial size, from stack - CMP r5, r10 - MOVLO r5, r10 ; we must try to honour initial size (allowed to break clamp) - ] - - MOV r10, #0 - LDR r11, [r10, #Page_Size] - LDR r10, [r10, #RAMLIMIT] ; get total RAM size - CMP r5, r10 ; if requested maximum size is > total - MOVHI r5, r10 ; then set max to total (NB. -1 passed in always yields HI) - -DAC_roundup - SUB r10, r11, #1 ; also round up to a page multiple - ADD r5, r5, r10 - BIC r5, r5, r10 - -; now see if we have to allocate a logical address space - - CMP r3, #-1 ; if we are to allocate the address space - BEQ %FT30 ; then go do it - -; otherwise we must check that the address does not clash with anything else - - TST r3, r10 ; does it start on a page boundary - ADRNE r0, ErrorBlock_AreaNotOnPageBdy ; if not then error - BNE DynArea_ErrorTranslateAndExit - - BL CheckForOverlappingAreas ; in: r3 = address, r4 = flags, r5 = size; out: if error, r0->error, V=1 - BVC %FT40 -25 - PullEnv - B DynArea_ReturnError - -30 - BL AllocateAreaAddress ; in: r4 = flags, r5 = size of area needed; out: r3, or V=1, r0->error - BVS %BT25 -40 - BL AllocateBackingLevel2 ; in: r3 = address, r4 = flags, r5 = size; out: VS if error - BVS %BT25 - - Push "r0,r1,r3" - [ DynArea_QuickHandles - ;we save work and reduce stress on system heap by claiming only one block, consisting of node followed by - ;string space (always maximum length, but typically not overly wasteful compared to 2nd block overhead) - ; - MOV r3, #DANode_NodeSize + DynArea_MaxNameLength + 1 - | - MOV r3, #DANode_NodeSize - ] - BL ClaimSysHeapNode ; out: r2 -> node - STRVS r0, [sp] - Pull "r0,r1,r3" - BVS %BT25 ; failed to claim node - -; now store data in node (could probably use STM if we shuffled things around) - - CMP r7, #-1 ; if workspace ptr = -1 - MOVEQ r7, r3 ; then use base address - - STR r1, [r2, #DANode_Number] - STR r3, [r2, #DANode_Base] - [ DA_Batman - ;disallow some awkward flag options if SparseMap set (no error), and temporarily create as not sparse - ;also disallow a DA handler - TST r4, #DynAreaFlags_SparseMap - STREQ r4, [r2, #DANode_Flags] - BICNE r7, r4, #DynAreaFlags_DoublyMapped + DynAreaFlags_NeedsSpecificPages + DynAreaFlags_Shrinkable + DynAreaFlags_SparseMap - ORRNE r7, r7, #DynAreaFlags_NotUserDraggable - STRNE r7, [r2, #DANode_Flags] - MOVNE r6, #0 - MOVNE r7, #0 - | - STR r4, [r2, #DANode_Flags] - ] - STR r5, [r2, #DANode_MaxSize] - STR r6, [r2, #DANode_Handler] - STR r7, [r2, #DANode_Workspace] - MOV r7, #0 ; initial size is zero - STR r7, [r2, #DANode_Size] ; before we grow it - - [ HAL - ; update lower limit on IO space growth, if this DA exceeds previous limit - LDR r6, [r7, #IOAllocLimit] - ADD lr, r3, r5 - CMP lr, r6 - STRHI lr, [r7, #IOAllocLimit] - ] - -; now make copy of string - first find out length of string - - [ DynArea_QuickHandles - - ADD r7, r2, #DANode_NodeSize - STR r7, [r2, #DANode_Title] - Push "r0" - MOV r0, #DynArea_MaxNameLength - TEQ r8, #0 - [ DynArea_NullNamePtrMeansHexString - ASSERT DynArea_MaxNameLength > 8 - BNE %FT45 - Push "r1, r2" - MOV r0, r1 ;string is 8-digit hex of DA number - MOV r1, r7 - MOV r2, #DynArea_MaxNameLength+1 - SWI XOS_ConvertHex8 - Pull "r1, r2" - B %FT55 - | - BEQ %FT50 ;assume NULL ptr to mean no DA name - ] -45 - LDRB r6, [r8], #1 - STRB r6, [r7], #1 - SUB r0, r0, #1 - TEQ r6, #0 - TEQNE r0, #0 - BNE %BT45 -50 - MOV r0, #0 - STRB r0, [r7], #1 -55 - Pull "r0" - - | - - MOV r7, r8 -45 - LDRB r6, [r7], #1 - TEQ r6, #0 - BNE %BT45 - - Push "r0-r3" - SUB r3, r7, r8 ; r3 = length inc. term. - BL ClaimSysHeapNode - STRVS r0, [sp] - MOV r7, r2 - Pull "r0-r3" - BVS StringNodeClaimFailed - - STR r7, [r2, #DANode_Title] -50 - LDRB r6, [r8], #1 ; copy string into claimed block - STRB r6, [r7], #1 - TEQ r6, #0 - BNE %BT50 - - ] ;DynArea_QuickHandles - -; now put node on list - list is sorted in ascending base address order - - MOV r8, #DAList - LDR r6, [r2, #DANode_Base] -60 - MOV r7, r8 - ASSERT DANode_Link = 0 - LDR r8, [r7, #DANode_Link] ; get next node - TEQ r8, #0 ; if no more - BEQ %FT70 ; then put it on here - LDR lr, [r8, #DANode_Base] - CMP lr, r6 ; if this one is before ours - BCC %BT60 ; then loop - -70 - STR r8, [r2, #DANode_Link] - STR r2, [r7, #DANode_Link] - - [ DynArea_QuickHandles - MOV r11, #0 - LDR r11, [r11, #DynArea_ws] - ;so XOS_ChangeDynamicArea can pick up the node we are still creating - STR r1, DynArea_CreatingHandle - STR r2, DynArea_CreatingPtr - ;so initial grow won't leave resize signature - LDR lr, DynArea_OD6Signature - ORR lr, lr, #&80000000 - STR lr, DynArea_OD6Signature - ] - -; now we need to grow the area to its requested size - - Push "r0, r1, r2" - LDR r0, [r2, #DANode_Number] - LDR r1, [sp, #3*4] ; reload requested size off stack - SWI XOS_ChangeDynamicArea ; deal with error - r0,r1,r2 still stacked - BVS %FT90 - Pull "r0, r1, r2" - - [ DynArea_QuickHandles -; -; Now put node on alphabetically sorted list -; - Push "r3,r4,r5,r7,r8,r9" - MOV r11, #0 - LDR r11, [r11, #DynArea_ws] - ADR r8, DynArea_SortedList - DANode_SortLink ;so that [r8, #DANode_SortLink] addresses list header) -75 - MOV r7, r8 ; previous - LDR r8, [r7, #DANode_SortLink] - TEQ r8, #0 - BEQ %FT78 - ;ho hum, UK case insensitive string compare - LDR r3, [r2, #DANode_Title] - LDR r9, [r8, #DANode_Title] -76 - LDRB r4, [r3],#1 - uk_LowerCase r4,r11 - LDRB r5, [r9],#1 - uk_LowerCase r5,r11 - CMP r4, r5 - BNE %FT77 - CMP r4, #0 - BNE %BT76 -77 - BHI %BT75 -78 - STR r2, [r7, #DANode_SortLink] - STR r8, [r2, #DANode_SortLink] -79 - Pull "r3,r4,r5,r7,r8,r9" - ] ;DynArea_QuickHandles - - [ DA_Batman - TST r4, #DynAreaFlags_SparseMap - LDRNE r11, [r2, #DANode_Flags] - ORRNE r11, r11, #DynAreaFlags_SparseMap ; set this in node now (after initial grow) - STRNE r11, [r2, #DANode_Flags] - LDRNE r11, [r2, #DANode_Size] - LDRNE lr, [r2, #DANode_Base] - ADDNE r11, r11, lr - STRNE r11, [r2, #DANode_SparseHWM] ; initial high water mark - ] - - [ DynArea_QuickHandles - MOV r11, #0 - LDR r11, [r11, #DynArea_ws] - - TST r4, #DynAreaFlags_Shrinkable - LDRNE lr, DynArea_ShrinkableSubList - STRNE lr, [r2, #DANode_SubLink] - STRNE r2, DynArea_ShrinkableSubList ;link onto front of Shrinkable sublist if Shrinkable - - MOV lr, #-1 - STR lr, DynArea_CreatingHandle ;invalidate this now - CMP r1, #ChangeDyn_MaxArea - BHI %FT72 - ADR lr, DynArea_SysQHandleArray - STR r2, [lr, r1, LSL #2] ;system handle - store ptr to node for quick reference - B %FT80 -72 - LDR lr, DynArea_OD6Signature - STR lr, DynArea_OD6PrevSignature - ORR lr, lr, #1 - STR lr, DynArea_OD6Signature - STR r1, DynArea_OD6Handle - CMP r1, #DynArea_NewAreas - BLO %FT80 - CMP r1, #DynArea_NewAreas+DynArea_NumQHandles - BHS %FT74 - SUB r10, r1, #DynArea_NewAreas - ADR lr, DynArea_QHandleArray - LDR r6, [lr, r10, LSL #2] ;pick up index of next free quick handle - STR r6, DynArea_FreeQHandles ;store as index of first free quick handle - STR r2, [lr, r10, LSL #2] ;store ptr to node for quick reference - B %FT80 -74 - LDR r10, DynArea_TreacleGuess - ADD r10, r10, #1 - STR r10, DynArea_TreacleGuess ;non-quick handle allocated, increment for next allocate -80 - ] ;DynArea_QuickHandles - - -; Now issue service to tell TaskManager about it - - Push "r0, r1, r2" - MOV r2, r1 ; r2 = area number - MOV r1, #Service_DynamicAreaCreate - BL Issue_Service - Pull "r0, r1, r2" - - CLRV - EXIT - -90 - -; The dynamic area is not being created, because we failed to grow the area to the required size. -; The area itself will have no memory allocated to it (since if grow fails it doesn't move any). -; We must delink the node from our list, free the string node, and then the area node itself. - - STR r0, [sp, #0*4] ; remember error pointer in stacked r0 - STR r8, [r7, #DANode_Link] ; delink area - [ :LNOT: DynArea_QuickHandles - LDR r2, [r2, #DANode_Title] - BL FreeSysHeapNode ; free title string node - ] - Pull "r0, r1, r2" ; pull stacked registers, and drop thru to... - - [ :LNOT: DynArea_QuickHandles -; The dynamic area is not being created, because there is no room to allocate space for the title string -; We must free the DANode we have allocated -; It would be nice to also free the backing L2, but we'll leave that for now. - -; in: r2 -> DANode - -StringNodeClaimFailed - ] - - Push "r0, r1" - BL FreeSysHeapNode - Pull "r0, r1" - [ DynArea_QuickHandles - MOV r11, #0 - LDR r11, [r11, #DynArea_ws] - MOV lr, #-1 - STR lr, DynArea_CreatingHandle - ] - PullEnv - B DynArea_ReturnError - -;************************************************************************** -; -; DynArea_Remove - Remove a dynamic area -; -; Internal routine called by DynamicAreaSWI -; -; in: r0 = reason code (1) -; r1 = area number -; -; out: r10-r12 may be corrupted -; All other registers preserved -; - -DynArea_Remove Entry - - ;*MUST NOT USE QCheckAreaNumber* (need r11 = previous) - BL CheckAreaNumber ; check that area is there - BCC UnknownDyn ; [not found] - - [ DA_Batman - Push "r11" - LDR r11,[r10,#DANode_Flags] - TST r11,#DynAreaFlags_SparseMap - Pull "r11" - BEQ DAR_notsparse - Push "r0,r2-r3" - MOV r0,#DAReason_SparseRelease - LDR r2,[r10,#DANode_Base] - LDR r3,[r10,#DANode_MaxSize] - SWI XOS_DynamicArea ;release all pages in sparse area - STRVS r0,[SP] - Pull "r0,r2-r3" - EXIT VS - B DAR_delink -DAR_notsparse - ] - - [ DynArea_QuickHandles - Push "r11" - MOV r11, #0 - LDR r11, [r11, #DynArea_ws] - ;so final shrink won't leave resize signature - LDR lr, DynArea_OD6Signature - ORR lr, lr, #&80000000 - STR lr, DynArea_OD6Signature - Pull "r11" - ] - -; First try to shrink area to zero size - - Push "r0-r2" - MOV r0, r1 ; area number - LDR r2, [r10, #DANode_Size] ; get current size - RSB r1, r2, #0 ; negate it - SWI XOS_ChangeDynamicArea - BVS %FT80 - Pull "r0-r2" - -DAR_delink - - [ DynArea_QuickHandles -; -; delink from sorted list -; - Push "r7,r8,r11" - MOV r11, #0 - LDR r11, [r11, #DynArea_ws] - ADR r8, DynArea_SortedList - DANode_SortLink ;so that [r8, #DANode_SortLink] addresses list header) -DAR_sdloop - MOV r7, r8 ;previous - LDR r8, [r7, #DANode_SortLink] - TEQ r8, #0 ;just in case not on list, shouldn't happen - BEQ DAR_sddone - TEQ r8, r10 - BNE DAR_sdloop - LDR r8, [r8, #DANode_SortLink] - STR r8, [r7, #DANode_SortLink] -DAR_sddone - Pull "r7,r8,r11" - - ] ;DynArea_QuickHandles - -; Now just de-link from list (r10 -> node, r11 -> prev) - - LDR lr, [r10, #DANode_Link] ; store our link - STR lr, [r11, #DANode_Link] ; in prev link - - [ DynArea_QuickHandles - ;if it is a Shrinkable area, find on Shrinkable sublist and remove it - Push "r0-r2, r11" - LDR r0, [r10, #DANode_Flags] - TST r0, #DynAreaFlags_Shrinkable - BEQ %FT06 - MOV r11, #0 - LDR r11, [r11, #DynArea_ws] - ADR r1, DynArea_ShrinkableSubList - LDR r2, [r1] -04 - CMP r2, r10 - LDREQ r2, [r2, #DANode_SubLink] - STREQ r2, [r1] - BEQ %FT06 - ADD r1, r2, #DANode_SubLink - LDR r2, [r2, #DANode_SubLink] - B %BT04 -06 - Pull "r0-r2, r11" - ] - - Push "r0-r2" - [ :LNOT: DynArea_QuickHandles - LDR r2, [r10, #DANode_Title] ; free title string block - BL FreeSysHeapNode - ] - MOV r2, r10 ; and free node block - BL FreeSysHeapNode - Pull "r0-r2" - - [ DynArea_QuickHandles - Push "r2, r3" - MOV r11, #0 - LDR r11, [r11, #DynArea_ws] - MOV r2,#-1 - STR r2, DynArea_CreatingHandle ; invalidate these, just in case - STR r2, DynArea_LastTreacleHandle - STR r2, DynArea_LastEnumHandle - CMP r1, #ChangeDyn_MaxArea - BLS %FT08 ; system area being removed - LDR r2, DynArea_OD6Signature - STR r2, DynArea_OD6PrevSignature - ORR r2, r2, #2 - STR r2, DynArea_OD6Signature - STR r1, DynArea_OD6Handle - CMP r1, #DynArea_NewAreas - BLO %FT10 - CMP r1, #DynArea_NewAreas+DynArea_NumQHandles - BHS %FT10 - SUB r2, r1, #DynArea_NewAreas-1 ; index of quick handle - ADR r10, DynArea_FreeQHandles ; so we can index array from 1 - LDR r3, DynArea_FreeQHandles - STR r3, [r10, r2, LSL #2] - STR r2, DynArea_FreeQHandles ; put on front of free list - B %FT10 -08 - ADR r10, DynArea_SysQHandleArray - MOV r2, #0 - STR r2, [r10, r1, LSL #2] ; reset system Qhandle -10 - Pull "r2, r3" - - ] - -; Issue service to tell TaskManager - - Push "r0, r1, r2" - MOV r2, r1 - MOV r1, #Service_DynamicAreaRemove - BL Issue_Service - Pull "r0, r1, r2" - - CLRV - EXIT - -; come here if shrink failed - r0-r2 stacked - -80 - STR r0, [sp] ; overwrite stacked r0 with error pointer - LDR r0, [sp, #1*4] ; reload area number - LDR r1, [r10, #DANode_Size] ; get size after failed shrink - SUB r1, r2, r1 ; change needed to restore original size - SWI XOS_ChangeDynamicArea ; ignore any error from this - Pull "r0-r2" - SETV - EXIT - -UnknownDyn - ADRL r0, ErrorBlock_BadDynamicArea - [ International - BL TranslateError - ] -90 - SETV - EXIT - -;************************************************************************** -; -; DynArea_GetInfo - Get info on a dynamic area -; -; Internal routine called by DynamicAreaSWI -; -; in: r0 = reason code (2) -; r1 = area number -; -; out: r2 = current size of area -; r3 = base logical address -; r4 = area flags -; r5 = maximum size of area -; r6 -> area handler routine -; r7 = workspace pointer -; r8 -> title string -; r10-r12 may be corrupted -; All other registers preserved -; - -DynArea_GetInfo ALTENTRY - [ DynArea_QuickHandles - BL QCheckAreaNumber ; check area exists - | - BL CheckAreaNumber ; check area exists - ] - BCC UnknownDyn ; [it doesn't] - -; r10 -> node, so get info - - LDR r2, [r10, #DANode_Size] - LDR r3, [r10, #DANode_Base] - LDR r4, [r10, #DANode_Flags] - LDR r5, [r10, #DANode_MaxSize] - LDR r6, [r10, #DANode_Handler] - LDR r7, [r10, #DANode_Workspace] - LDR r8, [r10, #DANode_Title] - CLRV - EXIT - -;************************************************************************** -; -; DynArea_GetChangeInfo -; -; Get info on changes to *non-system* dynamic areas -; Reserved for Acorn use (intended for TaskManager, can only serve one client) -; -; Internal routine called by DynamicAreaSWI -; -; in: r0 = reason code (6) -; -; out: r1 = Number of affected area, if a single change has occurred since last call, -; = -1, if no changes or more than one change have occurred -; r2 = signature of changes to non-system dynamic areas since last call to -; OS_DynamicArea 6 -; bit 0 = 1 if any non-system areas have been created -; bit 1 = 1 if any non-system areas have been removed -; bit 2 = 1 if any non-system areas have been resized -; bit 3 = 1 if any non-system areas have been renumbered -; bits 4-31 reserved (undefined) -; -;Notes: -; (1) bit 2 of r2 excludes the initial grow of a created area, and the final -; shrink of a removed area -; (2) if a single renumber has occurred, r1 is the old number - - [ DynArea_QuickHandles - -DynArea_GetChangeInfo ROUT - Push "lr" - MOV r11, #0 - LDR r11, [r11, #DynArea_ws] - LDR r1, DynArea_OD6Handle - LDR r2, DynArea_OD6Signature - LDR lr, DynArea_OD6PrevSignature - CMP lr, #0 - MOVNE r1, #-1 - CMP r2, #0 - MOVEQ r1, #-1 - MOV lr, #0 - STR lr, DynArea_OD6Signature - STR lr, DynArea_OD6PrevSignature - CLRV - Pull "PC" - - ] ;DynArea_QuickHandles - -;************************************************************************** -; -; DynArea_EnumerateInfo -; -; Enumerate *non-system* dynamic areas, returning selected info -; Reserved for Acorn use (intended for TaskManager) -; -; in: r0 = reason code (7) -; r1 = -1 to start enumeration, or area number to continue from -; -; out: r1 = number of next area found, or -1 if no more areas -; r2 = current size of area, if area found -; r3 = base logical address, if area found -; r4 = area flags, if area found -; r5 = maximum size of area, if area found -; r6 -> title string, if area found -; -;Notes: -; (1) r2-r6 on exit are undefined if r1 = -1 -; - - [ DynArea_QuickHandles - -DynArea_EnumerateInfo ROUT - Push "lr" - - MOV r11, #0 - LDR r11, [r11, #DynArea_ws] - - CMP r1, #-1 ; if starting from beginning - LDREQ r10, DynArea_SortedList ; then load pointer to 1st node on sorted list - BEQ %FT10 ; and skip - - LDR r10, DynArea_LastEnumHandle - CMP r10, r1 - LDREQ r10, DynArea_LastEnumPtr ; pick up where we left off - BEQ %FT08 - BL QCheckAreaNumber ; else check valid area number - BCC %FT14 - -08 - LDR r10, [r10, #DANode_SortLink] ; find next one -10 - TEQ r10, #0 ; if at end - MOVEQ r1, #-1 ; then return -1 - BEQ %FT12 - LDR r1, [r10, #DANode_Number] ; else return number - CMP r1, #ChangeDyn_MaxArea - BLS %BT08 ; skip if system area - - LDR r2, [r10, #DANode_Size] ; return rest of info - LDR r3, [r10, #DANode_Base] - LDR r4, [r10, #DANode_Flags] - LDR r5, [r10, #DANode_MaxSize] - LDR r6, [r10, #DANode_Title] - - MOV r11, #0 - LDR r11, [r11, #DynArea_ws] - STR r1, DynArea_LastEnumHandle - STR r10, DynArea_LastEnumPtr ; save a lot of messing about on next call -12 - CLRV - Pull "PC" - -;it's a reserved call, so naff off internationalisation -14 - ADR r0,DynArea_badei - SETV - Pull "PC" -DynArea_badei - DCD 0 - DCB "bad DA number",0 - ALIGN - - ] ;DynArea_QuickHandles - -;************************************************************************** -; -; DynArea_SetClamps -; -; Set clamps on max size of dynamic areas created by subsequent -; calls to OS_DynamicArea 0 -; -; On entry -; R0 = 8 (reason code) -; R1 = limit on maximum size of (non-Sparse) areas created by -; OS_DynamicArea 0 with R5 = -1, or 0 to read only -; R2 = limit on maximum size of (non-Sparse) areas created by -; OS_DynamicArea 0 with R5 > 0, or 0 to read only -; R3 = limit on maximum size of Sparse areas created by -; OS_DynamicArea 0 with R4 bit 10 set, or 0 to read only -; -; On exit -; R1 = previous limit for OS_DynamicArea 0 with R5 = -1 -; R2 = previous limit for OS_DynamicArea 0 with R5 > 0 -; R3 = previous limit for OS_DynamicArea 0 with R4 bit 10 set -; -; Specifying -1 in R1 or R2 means the respective limit -; is the RAM limit of the machine (this is the default). -; Specifiying larger than the RAM limit in R1 or R2 is -; equivalent to specifiying -1. -; - [ DynArea_QuickHandles - -DynArea_SetClamps ROUT - Push "r9,lr" - - MOV r11, #0 - LDR r11, [r11, #DynArea_ws] - - LDR r10, DynArea_OD8Clamp1 - LDR lr, DynArea_OD8Clamp2 - LDR r9, DynArea_OD8Clamp3 - -;insist on at least 1M for a clamp value (ignore anything lower) -; - CMP r1, #&100000 - STRHS r1, DynArea_OD8Clamp1 - CMP r2, #&100000 - STRHS r2, DynArea_OD8Clamp2 - CMP r3, #&100000 - STRHS r3, DynArea_OD8Clamp3 - - MOV r1, r10 - MOV r2, lr - MOV r3, r9 - - CLRV - Pull "r9,PC" - - ] ;DynArea_QuickHandles - -;************************************************************************** - -; DynArea_SparseClaim -; -; Ensure region of sparse dynamic area is mapped to valid memory -; -; in: r0 = reason code (9) -; r1 = area number -; r2 = base of region to claim -; r3 = size of region to claim -; -; out: r0-r3 preserved (error if not all of region successfully mapped) -; r10-r12 may be corrupted -; -; action: - round base and size to page granularity -; - scan the L2PT for each page covered -; - find contiguous fragments of 1 or more pages that are not yet mapped-in -; - pass each of these fragments as a psuedo DANode to OS_ChangeDynamicArea -; via special Batcall), to 'grow' pages into each fragment -; - [ DA_Batman - -DynArea_SparseClaim ROUT - Push "r0-r9,lr" - MOV r4,#1 ; flags operation as a claim - -DynArea_SparseChange ; common entry point for claim and release - - [ DynArea_QuickHandles - BL QCheckAreaNumber ; check area exists - | - BL CheckAreaNumber ; check area exists - ] - BCC DA_naffsparse ; area not there - - LDR r9,[r10,#DANode_Flags] - TST r9,#DynAreaFlags_SparseMap - BEQ DA_naffsparse ; area not sparse - - MOV r9,#&1000 ;page size - SUB r9,r9,#1 - ADD r3,r3,r2 ;base+size - CMP r4,#1 - BICEQ r2,r2,r9 ;round base down to page granularity for claim - ADDEQ r3,r3,r9 - BICEQ r3,r3,r9 ;round base+size up to page granularity for claim - ADDNE r2,r2,r9 - BICNE r2,r2,r9 ;round base up to page granularity for release - BICNE r3,r3,r9 ;round base+size down to page granularity for release - SUB r3,r3,r2 ;rounded size - - ADD r9,r3,r2 - LDR r5,[r10,#DANode_Base] - LDR r6,[r10,#DANode_MaxSize] - ADD r6,r6,r5 - CMP r2,r5 - CMPHS r9,r5 - BLO DA_naffsparse - CMP r2,r6 - CMPLS r9,r6 - BHI DA_naffsparse - - ADD r5,r2,r3 ;base+size of mapping - LDR r6,[r10,#DANode_SparseHWM] ;high water mark = highest claim base+size seen - CMP r4,#1 - BEQ %FT08 - CMP r5,r6 - SUBHI r3,r6,r2 ;for release we can save work by trimming to high water mark - B %FT09 ;r3 is now trimmed size (may be <=0 for trim to nothing) -08 - CMP r5,r6 - STRHI r5,[r10,#DANode_SparseHWM] ;for claim remember highest base+size as high water mark -09 - SUB SP,SP,#DANode_NodeSize ;room for temporary DANode on stack - MOV r9,r10 ;actual sparse area DANode - MOV r5,SP - MOV r6,#DANode_NodeSize -10 - LDR r7,[r9],#4 ;copy sparse area node to temp node - STR r7,[r5],#4 - SUBS r6,r6,#4 - BNE %BT10 - ADD r3,r2,r3 ;stop address -; - MOV r5,#L2PT - ADD r5,r5,r2,LSR #10 ;r5 -> L2PT for base (assumes 4k page) - MOV r8,r2 ;start address -; -;look for next fragment of region that needs to have mapping change -20 - CMP r8,r3 - BHS %FT50 ;done - LDR r6,[r5],#4 ;pick-up next L2PT entry - CMP r4,#0 ;if operation is a release... - CMPEQ r6,#0 ;...and L2PT entry is 0 (not mapped)... - ADDEQ r8,r8,#&1000 ;...then skip page (is ok) - BEQ %BT20 - CMP r4,#0 ;if operation is a claim (not 0)... - CMPNE r6,#0 ;...and L2PT entry is non-0 (mapped)... - ADDNE r8,r8,#&1000 ;...then skip page (is ok) - BNE %BT20 - MOV r1,#&1000 ;else we need to do a change (1 page so far) -30 - ADD r9,r8,r1 - CMP r9,r3 - BHS %FT40 - LDR r6,[r5],#4 ;pick-up next L2PT entry - CMP r4,#1 ;if operation is a release (not 1)... - CMPNE r6,#0 ;...and L2PT entry is non-0 (mapped)... - ADDNE r1,r1,#&1000 ;...then count page as needing change - BNE %BT30 - CMP r4,#1 ;if operation is a claim... - CMPEQ r6,#0 ;...and L2PT entry is 0 (not mapped)... - ADDEQ r1,r1,#&1000 ;...then count page as needing change - BEQ %BT30 -;set up pseudo DA and do Batcall to change mapping of fragment we have found -40 - MOV r2,SP ;temp DANode - STR r8,[r2,#DANode_Base] - ADD r8,r8,r1 - ADD r8,r8,#&1000 ;next address to check after fragment - CMP r4,#1 - MOVEQ r9,#0 ;start size of 0 for claim - MOVNE r9,r1 ;start size of fragment size for release - STR r9,[r2,#DANode_Size] - STR r1,[r2,#DANode_MaxSize] - MOV r0,#ChangeDyn_Batcall - CMP r4,#0 - RSBEQ r1,r1,#0 ;batshrink for release, batgrow for claim - SWI XOS_ChangeDynamicArea - CMP r4,#0 - RSBEQ r1,r1,#0 - LDR r9,[r10,#DANode_Size] - ADD r9,r9,r1 - STR r9,[r10,#DANode_Size] - BVC %BT20 -; -50 - ADD SP,SP,#DANode_NodeSize ;drop temp DANode - BVS %FT52 - BL DA_sparse_serviceandsig - Pull "r0-r9,PC" -; -52 - BL DA_sparse_serviceandsig - SETV - STR r0,[SP] - Pull "r0-r9,PC" - -DA_naffsparse - ADR r0,DA_naffsparseinnit - SETV - STR r0,[SP] - Pull "r0-r9,PC" -DA_naffsparseinnit - DCD 0 - DCB "invalid OS_DynamicArea sparse claim/release",0 - ALIGN - -DA_sparse_serviceandsig ROUT - Push "r0,LR" - LDR r1,[r10,#DANode_Number] - [ DynArea_QuickHandles - MOV r11,#0 - LDR r11,[r11, #DynArea_ws] - LDR r5,DynArea_OD6Signature - STR r5,DynArea_OD6PrevSignature - ORR r5,r5,#4 ;signal a resize - STR r5,DynArea_OD6Signature - STR r1,DynArea_OD6Handle - ] - MOV r2,r1 ;area number - MOV r0,#0 ;nominal 'grow/shrink' of 0 for service call - MOV r1,#Service_MemoryMoved - BL Issue_Service - Pull "r0,PC" - - ] ;DA_Batman - -;************************************************************************** -; -; DynArea_SparseRelease -; -; Allow region of sparse dynamic area to release memory to free pool -; -; in: r0 = reason code (10) -; r1 = area number -; r2 = base of region to release -; r3 = size of region to release -; -; out: r0-r3 preserved (error if not all of region successfully released) -; r10-r12 may be corrupted -; -; -; action: - similar to DynArea_SparseClaim, but does 'shrinks' on fragments -; that are mapped in - - [ DA_Batman - -DynArea_SparseRelease ROUT - Push "r0-r9,lr" - MOV r4,#0 ; flags operation as a release - B DynArea_SparseChange ; jump to common code - - ] ;DA_Batman - -;************************************************************************** -; -; DynArea_Enumerate - Enumerate dynamic areas -; -; Internal routine called by DynamicAreaSWI -; -; in: r0 = reason code (3) -; r1 = -1 to start enumeration, or area number to continue from -; -; out: r1 = next area number or -1 if no next -; r10-r12 may be corrupted -; All other registers preserved - -DynArea_Enumerate ALTENTRY - [ DynArea_QuickHandles - MOV r11, #0 - LDR r11, [r11, #DynArea_ws] - ] - CMP r1, #-1 ; if starting from beginning - [ DynArea_QuickHandles - LDREQ r10, DynArea_SortedList ; then load pointer to 1st node on sorted list - | - LDREQ r10, [r1, #DAList+1] ; then load pointer to 1st node - ] - BEQ %FT10 ; and skip - - [ DynArea_QuickHandles - LDR r10, DynArea_LastEnumHandle - CMP r10, r1 - LDREQ r10, DynArea_LastEnumPtr ; pick up where we left off - BEQ %FT08 - BL QCheckAreaNumber ; else check valid area number - | - BL CheckAreaNumber ; else check valid area number - ] - BCC UnknownDyn ; complain if passed in duff area number - -08 - [ DynArea_QuickHandles - LDR r10, [r10, #DANode_SortLink] ; find next one - | - LDR r10, [r10, #DANode_Link] ; find next one - ] -10 - TEQ r10, #0 ; if at end - MOVEQ r1, #-1 ; then return -1 - BEQ %FT12 - LDR r1, [r10, #DANode_Number] ; else return number - - [ DynArea_QuickHandles - MOV r11, #0 - LDR r11, [r11, #DynArea_ws] - STR r1, DynArea_LastEnumHandle - STR r10, DynArea_LastEnumPtr ; save a lot of messing about on next call - ] -12 - CLRV - EXIT - -;************************************************************************** -; -; DynArea_Renumber - Renumber dynamic area -; -; Internal routine called by DynamicAreaSWI -; -; in: r0 = reason code (4) -; r1 = old area number -; r2 = new area number -; - -DynArea_Renumber ALTENTRY - CMP r1, #ChangeDyn_MaxArea - BLS %FT92 ; can't renumber a system area - CMP r1, #ChangeDyn_MaxArea - BLS %FT92 - [ DynArea_QuickHandles - CMP r1, #DynArea_NewAreas - BLO %FT10 - CMP r1, #DynArea_NewAreas+DynArea_NumQHandles - BLO %FT92 ; can't renumber a quick handle -10 - CMP r2, #DynArea_NewAreas - BLO %FT12 - CMP r2, #DynArea_NewAreas+DynArea_NumQHandles - BLO %FT92 ; can't choose your own quick handle -12 - BL QCheckAreaNumber - | - BL CheckAreaNumber ; check valid area number - ] - BCC UnknownDyn ; [it's not] - - Push "r1" - MOV r12, r10 ; save pointer to node - MOV r1, r2 - [ DynArea_QuickHandles - BL QCheckAreaNumber ; check area r2 doesn't already exist - | - BL CheckAreaNumber ; check area r2 doesn't already exist - ] - Pull "r1" - BCS %FT90 ; [area r2 already exists] - - STR r2, [r12, #DANode_Number] - -; Now issue service to tell TaskManager - - Push "r1-r3" - MOV r3, r2 ; new number - MOV r2, r1 ; old number - MOV r1, #Service_DynamicAreaRenumber - BL Issue_Service - Pull "r1-r3" - - [ DynArea_QuickHandles - MOV r11, #0 ; we know system areas cannot be renumbered - LDR r11, [r11, #DynArea_ws] - MOV r10, #-1 - STR r10, DynArea_CreatingHandle ; invalidate these, just in case - STR r10, DynArea_LastTreacleHandle - STR r10, DynArea_LastEnumHandle - LDR lr, DynArea_OD6Signature - STR lr, DynArea_OD6PrevSignature - ORR lr, lr, #8 - STR lr, DynArea_OD6Signature - STR r1, DynArea_OD6Handle - ] - - CLRV - EXIT - -90 - ADRL r0, ErrorBlock_AreaAlreadyExists - [ International - BL TranslateError - ] - SETV - EXIT - -;if you think this is worth internationalising, I pity you -92 - ADR r0, DynArea_NaughtyRenum - SETV - EXIT -DynArea_NaughtyRenum - DCD 0 - DCB "illegal DA renumber",0 - ALIGN - - [ ShrinkableDAs -;************************************************************************** -; -; DynArea_ReturnFree - Return total free space, including shrinkables -; -; Internal routine called by DynamicAreaSWI -; -; in: r0 = reason code (5) -; r1 = area number to exclude, or -1 to include all shrinkable areas -; -; out: r2 = total amount of free memory -; - -DynArea_ReturnFree ALTENTRY - CMP r1, #-1 ; if no excluded area, - MOVEQ r10, r1 ; then point r10 nowhere - BEQ %FT10 - - [ DynArea_QuickHandles - BL QCheckAreaNumber ; else check area number is valid - | - BL CheckAreaNumber ; else check area number is valid - ] - BCC UnknownDyn ; [unknown area] -10 - MOV r2, #0 - LDR r2, [r2, #FreePoolDANode + DANode_Size] ; start with current size of free pool - [ DynArea_QuickHandles - ;traverse the Shrinkable sublist - MOV r11, #0 - LDR r11, [r11, #DynArea_ws] - LDR r11, DynArea_ShrinkableSubList - B %FT21 - | - MOV r11, #DAList - ] -20 - [ DynArea_QuickHandles - LDR r11, [r11, #DANode_SubLink] ; load next area on sublist - | - LDR r11, [r11, #DANode_Link] ; load next area - ] -21 - TEQ r11, #0 ; if end of list - EXIT EQ ; then exit, with r2 = correct value - - [ DynArea_QuickHandles - TEQ r11, r10 ; must not be the excluded area - | - LDR lr, [r11, #DANode_Flags] ; load area flags - TST lr, #DynAreaFlags_Shrinkable ; must be shrinkable - TEQNE r11, r10 ; and not excluded area - ] - BEQ %BT20 ; [don't try this one] - - Push r3 - BL CallTestShrink - ADD r2, r2, r3 ; add on amount if any - Pull r3 - B %BT20 ; then go back for more - ] - -;************************************************************************** -; -; CheckAreaNumber - Try to find area with number r1 -; -; Internal routine called by DynArea_Create -; -; in: r1 = area number to match -; out: If match, then -; C=1, r10 -> node, r11 -> previous node -; else -; C=0, r10,r11 corrupted -; endif - -CheckAreaNumber Entry - [ DynArea_QuickHandles -QCheckAreaNumber_nonQ - ] - MOV r10, #DAList - ASSERT DANode_Link = 0 ; because DAList has only link -10 - MOV r11, r10 ; save prev - LDR r10, [r10, #DANode_Link] ; and load next - CMP r10, #1 ; any more nodes? - EXIT CC ; no, then no match - LDR lr, [r10, #DANode_Number] ; get number - CMP lr, r1 ; does number match - BNE %BT10 ; no, try next - [ DynArea_QuickHandles - Push "r11" - MOV r11, #0 - LDR r11, [r11, #DynArea_ws] - STR r1, DynArea_LastTreacleHandle - STR r10, DynArea_LastTreaclePtr - Pull "r11" - ] - EXIT ; (C=1 from CMP lr,r1) - - [ DynArea_QuickHandles - -; QCheckAreaNumber - similar to CheckAreaNumber, but blisteringly quick for system or for quick -; numbers. However, DOES NOT return previous node in r11. -; -QCheckAreaNumber ROUT - Push "lr" - MOV r11, #0 - LDR r11, [r11, #DynArea_ws] - CMP r1, #-1 - BEQ QCheckAreaNumber_nonQ ;just to protect against -1 as a proposed number - LDR lr, DynArea_LastTreacleHandle - CMP lr, r1 - LDREQ r10, DynArea_LastTreaclePtr - EXIT EQ ;found node is slow one we handled last time (carry set) - LDR lr, DynArea_CreatingHandle - CMP lr, r1 - LDREQ r10, DynArea_CreatingPtr - EXIT EQ ;found node is one we're creating (carry set) - CMP r1, #ChangeDyn_MaxArea - BLS %FT10 - CMP r1,#DynArea_NewAreas - BLO QCheckAreaNumber_nonQ - SUB lr, r1, #DynArea_NewAreas - CMP lr, #DynArea_NumQHandles - BHS QCheckAreaNumber_nonQ -;quick handle - ADR r10, DynArea_QHandleArray - LDR r10, [r10, lr, LSL #2] - CMP r10, #DynArea_NumQHandles - MOVLS r10, #0 ;not a valid pointer - CMP r10, #1 - Pull "pc" ;handle free, carry clear - ;or word is ptr to node, carry set -;system handle -10 - ADR r10, DynArea_SysQHandleArray - LDR r10, [r10, r1, LSL #2] - CMP r10, #1 - Pull "pc" ;DA does not exist, carry clear - ;or word is ptr to node, carry set - ] ;DynArea_QuickHandles - -;************************************************************************** -; -; CheckForOverlappingAreas - Check that given area does not overlap any existing ones -; -; Internal routine called by DynArea_Create -; -; in: r3 = base address -; r4 = area flags (NB if doubly mapped, then have to check both halves for overlap) -; r5 = size (of each half in doubly mapped areas) -; -; out: If this area overlaps with an existing one, then -; r0 -> error -; V=1 -; else -; r0 preserved -; V=0 -; endif -; - -CheckForOverlappingAreas Entry "r0-r5" - TST r4, #DynAreaFlags_DoublyMapped ; check if doubly mapped - BEQ %FT05 ; [not, so don't mangle] - - SUBS r3, r3, r5 ; move start address back - BCC %FT20 ; oh dear! - it went back to below 0 - MOVS r5, r5, LSL #1 ; and double size - BCS %FT20 ; if that wrapped then that's bad, too -05 - ADDS r5, r5, r3 ; r5 -> end +1 - BHI %FT20 ; if CS, indicating wrap, and not EQ (ie just ending at 0), then bad - - [ HAL - MOV lr, #0 - LDR r0, [lr, #IOAllocPtr] - CMP r5, r0 ; end must be below I/O space (allocated down from high memory) - BHI %FT20 - ] - -; check against list of fixed areas - - ADR lr, FixedAreasTable -10 - LDMIA lr!, {r0, r1} ; r0 = start addr, r1 = size - CMP r0, #-1 ; if at end of list - BEQ %FT30 ; then OK wrt fixed areas - ADD r1, r1, r0 ; r1 = end addr+1 - CMP r5, r0 ; if end of our area is <= start of fixed, then OK wrt fixed areas - BLS %FT30 - CMP r3, r1 ; if start of our area is >= end of fixed, then go onto next area - BCS %BT10 - -20 - ADRL r0, ErrorBlock_OverlappingAreas - [ International - BL TranslateError - ] - STR r0, [sp] - SETV - EXIT - -; Now, check against DAList - -30 - MOV lr, #DAList - ASSERT DANode_Link = 0 -40 - LDR lr, [lr, #DANode_Link] - CMP lr, #0 ; if got to end of list (V=0) - BEQ %FT50 ; then exit saying OK - LDR r0, [lr, #DANode_Base] - LDR r1, [lr, #DANode_Flags] - TST r1, #DynAreaFlags_DoublyMapped - LDR r1, [lr, #DANode_MaxSize] - SUBNE r0, r0, r1 ; if doubly mapped then move back - MOVNE r1, r1, LSL #1 ; and double size - ADD r1, r1, r0 ; r1 -> end - CMP r5, r0 ; if end of our area is <= start of dyn, then OK wrt dyn areas) - BLS %FT50 - CMP r3, r1 ; if start of our area is >= end of dyn, then go onto next area - BCS %BT40 - B %BT20 ; else it overlaps - -50 - CLRV ; OK exit - EXIT - - -FixedAreasTable ; table of fixed areas (address, size) - [ HAL - & 0, AplWorkMaxSize ; application space - [ CursorChunkAddress < IO - & CursorChunkAddress, 64*1024 ; 32K for cursor, 32K for "nowhere" - ] - [ ROM < IO - [ OSROM_ImageSize > 8192 - & &03800000, OSROM_ImageSize*1024 ; ROM - | - & &03800000, 8*1024*1024 ; ROM - ] - ] - & IO, &FFFFFFFF-IO ; Kernel workspace (code will also check dynamic value IOAllocPtr) - | - & 0, AplWorkMaxSize ; application space - & UndStackSoftCamChunk, 1024*1024 ; undefined stack / soft cam map - & CursorChunkAddress, 1504*1024 ; cursor, Nowhere, cache cleaners, reserved (up to kernel buffers) - & L2PT, 4*1024*1024 ; L2PT (and L1PT) - [ OSROM_ImageSize > 8192 - & &03000000, 8*1024*1024+OSROM_ImageSize*1024 ; I/O + ROM - | - & &03000000, 16*1024*1024 ; I/O + ROM - ] - & PhysSpace, 512*1024*1024 ; PhysSpace - [ No26bitCode - & AbtStack, AbtStackSize - ] - [ ShadowROM - & &FF800000, &007FFFFF ; Shadow ROM (length has been bodged to avoid wrap problems) - ] - ] ; HAL - & -1, 0 ; termination - -;************************************************************************** -; -; AllocateAreaAddress - Find an area of logical space to use for this area -; -; Internal routine called by DynArea_Create -; -; in: r4 = area flags (NB if doubly mapped, we have to find space for both halves) -; r5 = size (of each half in doubly mapped areas) -; -; out: If successfully found an address, then -; r0 preserved -; r3 = logical address -; V=0 -; else -; r0 -> error -; r3 preserved -; V=1 -; endif - -AllocateAreaAddress Entry "r0-r2,r4-r7" - TST r4, #DynAreaFlags_DoublyMapped ; check if doubly mapped - BEQ %FT05 ; [not, so don't mangle] - MOVS r5, r5, LSL #1 ; double size - BCS %FT90 ; if that wrapped then that's bad -05 - LDR r3, =DynArea_NewAreasBase ; r3 is our current attempt - ADR r0, FixedAreasTable ; r0 is ptr into fixed areas table - MOV r1, #DAList ; r1 is ptr into dyn areas list -10 - ADDS r7, r3, r5 ; r7 is our end+1 - BHI %FT90 ; if we wrapped (but not end+1=0) then we failed - [ HAL - MOV lr, #0 - LDR r2, [lr, #IOAllocPtr] - CMP r7, r2 - BHI %FT90 ; if we walked into IOspace (assumed higher than any DA space) then we failed - ] -15 - BL GetNextRange ; get next range from either list (r2=start, r6=end+1) - CMP r7, r2 ; if end(ours) <= start(next) then this is OK - BLS %FT80 ; (note this also works when r2=-1) - CMP r3, r6 ; else if start(ours) >= end(next) - BCS %BT15 ; then get another - MOV r3, r6 ; else make start(ours) := end(next) - B %BT10 ; and go back for another try - -; we've succeeded - just apply unbodge for doubly-mapped areas - -80 - TST r4, #DynAreaFlags_DoublyMapped ; if doubly mapped - MOVNE r5, r5, LSR #1 ; halve size again - ADDNE r3, r3, r5 ; and advance base address to middle - CLRV - EXIT - -90 - ADRL r0, ErrorBlock_CantAllocateArea - [ International - BL TranslateError - ] - STR r0, [sp] - SETV - EXIT ; say we can't do it - -;************************************************************************** -; -; GetNextRange - Get next lowest range from either fixed or dynamic list -; -; Internal routine called by AllocateAreaAddress -; -; in: r0 -> next entry in fixed list -; r1!0 -> next entry in dyn list -; -; out: r2 = next lowest area base (-1 if none) -; r6 = end of that range (undefined if none) -; Either r0 or r1 updated to next one (except when r2=-1 on exit) -; - -GetNextRange Entry "r7,r8" - LDMIA r0, {r2, r6} ; load start, size from fixed list - ADD r6, r6, r2 ; r6 = end+1 - - ASSERT DANode_Link = 0 - LDR r7, [r1, #DANode_Link] ; get next from dyn - TEQ r7, #0 ; if none - MOVEQ r8, #-1 ; then use addr -1 - BEQ %FT10 - - LDR r8, [r7, #DANode_Flags] ; more double trouble - TST r8, #DynAreaFlags_DoublyMapped - LDR r8, [r7, #DANode_Base] - LDR lr, [r7, #DANode_MaxSize] - SUBNE r8, r8, lr - MOVNE lr, lr, LSL #1 - ADD lr, lr, r8 ; now r8 = start addr, lr = end+1 -10 - CMP r8, r2 ; if dyn one is earlier - MOVCC r2, r8 ; then use dyn start - MOVCC r6, lr ; and end - MOVCC r1, r7 ; and advance dyn ptr - EXIT CC ; then exit - CMP r2, #-1 ; else if not at end of fixed - ADDNE r0, r0, #8 ; then advance fixed ptr - EXIT - -;************************************************************************** -; -; AllocateBackingLevel2 - Allocate L2 pages for an area -; -; Internal routine called by DynArea_Create -; -; in: r3 = base address (will be page aligned) -; r4 = area flags (NB if doubly mapped, then have to allocate for both halves) -; r5 = size (of each half in doubly mapped areas) -; -; out: If successfully allocated pages, then -; All registers preserved -; V=0 -; else -; r0 -> error -; V=1 -; endif - -AllocateBackingLevel2 Entry "r0-r8,r11" - TST r4, #DynAreaFlags_DoublyMapped ; if doubly mapped - SUBNE r3, r3, r5 ; then area starts further back - MOVNE r5, r5, LSL #1 ; and is twice the size - -; NB no need to do sanity checks on addresses here, they've already been checked - -; now round address range to 4M boundaries - - ADD r5, r5, r3 ; r5 -> end - MOV r0, #1 :SHL: 22 - SUB r0, r0, #1 - BIC r8, r3, r0 ; round start address down (+ save for later) - ADD r5, r5, r0 - BIC r5, r5, r0 ; but round end address up - -; first go through existing L2PT working out how much we need - - LDR r7, =L2PT - ADD r3, r7, r8, LSR #10 ; r3 -> start of L2PT for area - ADD r5, r7, r5, LSR #10 ; r5 -> end of L2PT for area +1 - - ADD r1, r7, r3, LSR #10 ; r1 -> L2PT for r3 - ADD r2, r7, r5, LSR #10 ; r2 -> L2PT for r5 - - TEQ r1, r2 ; if no pages needed - BEQ %FT30 - - MOV r4, #0 ; number of backing pages needed -10 - LDR r6, [r1], #4 ; get L2PT entry for L2PT - TST r6, #3 ; EQ if translation fault - ADDEQ r4, r4, #1 ; if not there then 1 more page needed - TEQ r1, r2 - BNE %BT10 - -; if no pages needed, then exit - - TEQ r4, #0 - BEQ %FT30 - -; now we need to claim r4 pages from the free pool, if possible; return error if not - - MOV r1, #0 - LDR r6, [r1, #FreePoolDANode + DANode_Size] - SUBS r6, r6, r4, LSL #12 ; reduce free pool size by that many pages - BCS %FT14 ; if enough, skip next bit - -; not enough pages in free pool currently, so try to grow it by the required amount - - Push "r0, r1" - MOV r0, #ChangeDyn_FreePool - RSB r1, r6, #0 ; size change we want (+ve) - SWI XOS_ChangeDynamicArea - Pull "r0, r1" - BVS %FT90 ; didn't manage change, so report error - - MOV r6, #0 ; will be no pages left in free pool after this -14 - STR r6, [r1, #FreePoolDANode + DANode_Size] ; if possible then update size - -; after that we need to zero all these pages out (=> cause translation fault for area initially) - - LDR r0, [r1, #FreePoolDANode + DANode_Base] ; r0 -> base of free pool - ADD r0, r0, r6 ; r0 -> first byte we're taking out of free pool - ADD r6, r0, r4, LSL #12 ; r6 -> byte after last in free pool - Push r8 ; save original logical address - MOV r8, #0 ; 0 => translation fault (note r1 already zero) - MOV r11, #0 - MOV lr, #0 -15 - STMIA r0!, {r1,r8,r11,lr} ; store data - TEQ r0, r6 - BNE %BT15 - Pull r8 - -; now r0 -> after end of free pool (log addr) - - LDR lr, =L1PT - ADD r8, lr, r8, LSR #18 ; point r8 at start of L1 we may be updating - ADD r1, r7, r3, LSR #10 ; point r1 at L2PT for r3 again - MOV r11, #AP_L2PT ; access privs (+CB bits) -20 - LDR r6, [r1], #4 ; get L2PT entry again - TST r6, #3 ; if no fault - BNE %FT25 ; then skip - - SUB r0, r0, #4096 ; move free pointer back - Push "r2,r4,r5" - BL MoveCAMatR0toR3 ; else move page from end of free pool to r3 - Pull "r2,r4,r5" - - MOV lr, #ZeroPage - LDR r6, [lr, #L2PTUsed] - ADD r6, r6, #4096 - STR r6, [lr, #L2PTUsed] - -; now update 4 words in L1PT (corresponding to 4M of address space which is covered by the 4K of L2) -; and point them at the physical page we've just allocated (r1!-4 will already hold physical address+bits now!) - - LDR r6, [r1, #-4] ; r6 = physical address for L2 page + other L2 bits - MOV r6, r6, LSR #12 ; r6 = phys.addr >> 12 - [ ECC - LDR lr, =L1_Page + L1_U + L1_P ; form other bits to put in L1 - | - LDR lr, =L1_Page + L1_U ; form other bits to put in L1 - ] - ORR lr, lr, r6, LSL #12 ; complete L1 entry - STR lr, [r8, #0] ; store entry for 1st MB - ADD lr, lr, #1024 ; advance L2 pointer - STR lr, [r8, #4] ; store entry for 2nd MB - ADD lr, lr, #1024 ; advance L2 pointer - STR lr, [r8, #8] ; store entry for 3rd MB - ADD lr, lr, #1024 ; advance L2 pointer - STR lr, [r8, #12] ; store entry for 4th MB - ;;;ARM_flush_TLB r6 junk TLB(s) shouldn't be needed, would have to be ARMop now -25 - ADD r3, r3, #4096 ; advance L2PT logical address - ADD r8, r8, #16 ; move onto L1 for next 4M - - TEQ r1, r2 - BNE %BT20 -30 - CLRV - EXIT - -; Come here if not enough space in free pool to allocate level2 - -90 - ADRL r0, ErrorBlock_CantAllocateLevel2 - [ International - BL TranslateError - ] - STR r0, [sp] - SETV - EXIT - -;************************************************************************** - - [ ChocolateSysHeap -; -; CreateChocolateBlockArray -; -; entry: r2 = No. of blocks to be created in array (N) -; r3 = size of each block in bytes (S, must be multiple of 4) -; -; exit: -; r2 = address of chocolate block array (parent SysHeap block address) -; array is initialised to all blocks free -; OR V set, r0=error pointer, if error (from OS_Heap) -; -; - A Chocolate block array is only suitable for blocks of single fixed size. -; These blocks may be allocated and freed in any order, but never resized. -; - Allocating and freeing blocks from a Chocolate block array is much faster -; than OS_Heap, and the cost of operations is independent of N. -; - A Chocolate block array is a single block in the SysHeap, and looks like this -; (excluding the internal structure of OS_Heap blocks): -; -; - array header (3 words): -; - word 0 = total no. of blocks in array (N) -; - word 1 = size of each block container (S+4) -; - word 2 -> first free block container in array, or 0 if none free -; - followed immediately by N block containers, each of form: -; - container header (1 word): -; - word 0 : bits 0..30 = container id (C) -; C = (S+4)*I, where I is array index, 0..N-1 -; bit 31 = 1 if block is free, 0 if block is in use -; - followed immediately by the S/4 words of the block itself -; - if the block is in use, these words are as defined by the client -; - if the block is free, the first word is a pointer to the next free -; block container (or 0 if end of free list), and the other words -; are undefined -; -; - A Chocolate block array requires a SysHeap block of 3*4 + N*(S + 4) bytes -; -CreateChocolateBlockArray ROUT - Push "r0,r1,r3,r4,r5,lr" - MOV r5,r2 ;N - ADD r4,r3,#4 ;S+4 - MUL r3,r5,r4 - ADD r3,r3,#3*4 - BL ClaimSysHeapNode - STRVS r0,[SP] - BVS %FT50 - STR r5,[r2] - STR r4,[r2,#4] - ADD r1,r2,#3*4 - STR r1,[r2,#8] - MOV lr,r5 - ADD r0,r2,#3*4 - MOV r1,#&80000000 ;free flag -10 - STR r1,[r0] - ADD r3,r0,r4 - STR r3,[r0,#4] - ADD r1,r1,r4 - SUBS lr,lr,#1 - MOVNE r0,r3 - BNE %BT10 - MOV r1,#0 - STR r1,[r0,#4] ;end of free list -50 - Pull "r0,r1,r3,r4,r5,pc" - -; -; ClaimChocolateBlock -; -; entry: r3 = address of parent ChocolateBlockArray (must be valid) -; exit: r2 = address of allocated block -; r3 = size of block -; OR V set, R0=error (no free blocks) -; -ClaimChocolateBlock ROUT - Push "r1,r4,lr" - MRS r4,CPSR - ORR r1,r4,#I32_bit - MSR CPSR_c,r1 ;protect critical manipulation from interrupt re-entry - LDR r2,[r3,#8] ;pick up block container at front of free list - CMP r2,#0 - BEQ ClaimChocolateBlock_NoneFree - LDR r1,[r2] - BIC r1,r1,#&80000000 ;clear the free flag - STR r1,[r2] - LDR r1,[r2,#4] ;next free block container - STR r1,[r3,#8] ;put it at front - ADD r2,r2,#4 ;address of block - LDR r3,[r3,#4] - SUB r3,r3,#4 ;size of block - BIC r4,r4,#V_bit ;return with V clear - MSR CPSR_cf,r4 ;restore IRQ state - Pull "r1,r4,pc" -; -;DON'T even think about internationalisation - this exit route must be fast -ClaimChocolateBlock_NoneFree - ADR R0,ChocolateBlock_NFError - ORR r4,r4,#V_bit ;return with V set - MSR CPSR_cf,r4 ;restore IRQ state - Pull "r1,r4,pc" - -; -; FreeChocolateBlock -; -; entry: r1 = address of parent ChocolateBlockArray (must be valid) -; r2 = address of block to free (may be invalid) -; exit: - -; OR V set, R0=error (not a ChocolateBlock), r1,r2 still preserved -; -FreeChocolateBlock ROUT - Push "r2,r3,r4,lr" - MRS r4,CPSR - ORR r3,r4,#I32_bit - MSR CPSR_c,r3 ;protect critical manipulation from interrupt re-entry - ADD r3,r1,#12 ;r3 -> first block container - SUB r2,r2,#4 ;r2 -> container for block (if valid) - CMP r2,r3 - BLO FreeChocolateBlock_NaffOff - LDR lr,[r1,#-4] ;OS_Heap's size word (naughty!) - ADD lr,lr,r1 - CMP r2,lr - BHS FreeChocolateBlock_NaffOff - LDR lr,[r2] ;block container id - TST lr,#&80000000 ;free flag - BNE FreeChocolateBlock_NaffOff - ADD lr,lr,r3 ;lr := address of block container, from container id - CMP lr,r2 - BNE FreeChocolateBlock_NaffOff -; -;we now believe caller is freeing a valid block, currently in use -; - LDR lr,[r2] - ORR lr,lr,#&80000000 - STR lr,[r2] ;set free flag in container id - LDR lr,[r1,#8] ;current front of free list - STR lr,[r2,#4] ;chain free list to block container we are freeing - STR r2,[r1,#8] ;put freed block container at front - BIC r4,r4,#V_bit ;return with V clear - MSR CPSR_cf,r4 ;restore IRQ state - Pull "r2,r3,r4,pc" -; -;DON'T even think about internationalisation - this exit route must be fast -FreeChocolateBlock_NaffOff - ADR R0,ChocolateBlock_NOError - ORR r4,r4,#V_bit ;return with V set - MSR CPSR_cf,r4 ;restore IRQ state - Pull "r2,r3,r4,pc" - -; -;forget internationalisation - if these errors aren't dealt with silently, -; the kernel's stuffed anyway -ChocolateBlock_NFError - DCD 0 - DCB "Chocolate SysHeap claim failed",0 - ALIGN -ChocolateBlock_NOError - DCD 0 - DCB "not a Chocolate SysHeap block",0 - ALIGN - - ] ;ChocolateSysHeap - -;************************************************************************** -; -; InitDynamicAreas - Initialise nodes for dynamic areas -; -; It only initialises free pool, appspace and sysheap nodes -; The other areas are created properly, after the screen area has been created (improperly) -; -; in: - -; out: - -; - -InitDynamicAreas Entry "r0-r8,r11,r12" - MOV lr, #AppSpaceDANode - ADR r0, InitAppSpaceTable - LDMIA r0, {r0-r8} - STMIA lr, {r0-r8} - - MOV lr, #FreePoolDANode - ADR r0, InitFreePoolTable - LDMIA r0, {r0-r8} ; copy initial data into node - LDR r5, [lr, #RAMLIMIT-FreePoolDANode] ; max size is RAMLIMIT - STMIA lr, {r0-r8} - - -; We have to move all free pages (ie ones not occupied by the static pages) into the free pool -; The lowest numbered physical pages must be put in last, so that when ReadCMOSAndConfigure is -; called to put in the screen, it will get the pages starting at 0 (when the screen is created -; as a dynamic area, this limitation can be removed). - -; The free pages consist of two chunks of pages, each of which having consecutive physical page -; numbers. We start at MaxCamEntry and move back until we hit the end of the statics (which are -; at the start of the 1st non-video-RAM chunk). We then separately do the video RAM. - - [ HAL - MOV r11, r3 ; r11 = PPL (inc CB) for free pool - MOV r6, r2 ; r6 = base address of free pool, ie where to put stuff - MOV r5, #0 ; r5 = amount of memory in free pool so far (and ptr to 0) - LDR r0, [r5, #InitUsedStart] - ADD r0, r0, #DRAMOffset_FirstFixed - DRAMOffset_L1PT - BL PhysAddrToPageNo - MOV r7, r0 ; r7 = page number of start of static chunk - LDR r0, [r5, #InitUsedEnd] - BL PhysAddrToPageNo - MOV r8, r0 ; r8 = page number of 1st page in 1st chunk not used for statics - - LDR r2, [r5, #MaxCamEntry] ; r2 = 1st page to put in free pool - MOV r3, r6 ; r3 = base address of free pool, ie where to put stuff - SUB lr, r8, r7 - SUB lr, r2, lr - ADD r3, r3, lr, LSL #12 ; r3 = end address of free pool - - ! 0, "Sort out static check in InitDynamicAreas" -10 - CMP r2, r8 ; are we into statics already - SUBCC r2, r7, #1 ; if so, then move to last page of video RAM - MOVCC r8, #0 ; and move barrier so we never hit it again - BL BangCamUpdate - SUB r3, r3, #4096 ; advance logical address - ADD r5, r5, #4096 - SUBS r2, r2, #1 ; decrement page number - BCS %BT10 ; if we haven't gone negative, then loop - | - MOV r11, r3 ; r11 = PPL (inc CB) for free pool - MOV r3, r2 ; r3 = base address of free pool, ie where to put stuff - MOV r5, #0 ; r5 = amount of memory in free pool so far (and ptr to 0) - LDR r2, [r5, #MaxCamEntry] ; r2 = 1st page to put in free pool - LDR r7, [r5, #VideoSize] ; r7 = size of video RAM - MOV r7, r7, LSR #12 ; r7 = page number of start of static chunk - ASSERT SoftCamMapSize = L2PTSize +4 - MOV r0, #L2PTSize - LDMIA r0, {r0, r8} ; r0 = L2PTSize, r8 = SoftCamMapSize - ADD r8, r8, r0 ; add sizes together - ADD r8, r8, #StaticPagesSize + UndStackSize ; + number of bytes used for other static bits - ADD r8, r7, r8, LSR #12 ; r8 = page number of 1st page in 1st chunk not used for statics -10 - CMP r2, r8 ; are we into statics already - SUBCC r2, r7, #1 ; if so, then move to last page of video RAM - MOVCC r8, #0 ; and move barrier so we never hit it again - BL BangCamUpdate - ADD r3, r3, #4096 ; advance logical address - ADD r5, r5, #4096 - SUBS r2, r2, #1 ; decrement page number - BCS %BT10 ; if we haven't gone negative, then loop - ] - - MOV lr, #FreePoolDANode ; may be used below to update DAList head ptr - STR r5, [lr, #DANode_Size] ; update size of free pool in node - -; Now initialise the system heap by hand, so we can start creating dynamic areas - - LDR r0, =SysHeapStart - LDR r1, =magic_heap_descriptor - MOV r2, #Nil - MOV r3, #hpdsize - MOV r4, #32*1024 - (SysHeapStart-SysHeapChunkAddress) - STMIA r0, {r1-r4} - - MOV r0, #0 ; initialise module list to empty - STR r0, [r0, #Module_List] - - MOV lr, #SysHeapDANode ; initialise system heap node - ADR r0, InitSysHeapTable - LDMIA r0, {r0-r8} - STMIA lr, {r0-r8} - MOV r0, #0 - [ FreePoolAddress < SysHeapStart - MOV lr, #FreePoolDANode ; cf comments above/below - what was old code? KJB - ] - STR lr, [r0, #DAList] ; store pointer to 1st node on list (either free pool or sys heap) - - [ ChocolateSysHeap - ASSERT ChocolateCBBlocks = ChocolateBlockArrays + 0 - ASSERT ChocolateSVBlocks = ChocolateBlockArrays + 4 - ASSERT ChocolateTKBlocks = ChocolateBlockArrays + 8 - ASSERT ChocolateMRBlocks = ChocolateBlockArrays + 12 - ASSERT ChocolateMABlocks = ChocolateBlockArrays + 16 - ASSERT ChocolateMSBlocks = ChocolateBlockArrays + 20 - MOV r1,#ChocolateBlockArrays - MOV r2,#MaxChocolateCBBlocks - MOV r3,#3*4 - BL CreateChocolateBlockArray ; better not fail - STR r2,[r1,#0] - MOV r2,#MaxChocolateSVBlocks - MOV r3,#VecNodeSize - BL CreateChocolateBlockArray ; better not fail - STR r2,[r1,#4] - MOV r2,#MaxChocolateTKBlocks - MOV r3,#TickNodeSize - BL CreateChocolateBlockArray ; better not fail - STR r2,[r1,#8] - MOV r2,#MaxChocolateMRBlocks - MOV r3,#ROMModule_NodeSize - BL CreateChocolateBlockArray ; better not fail - STR r2,[r1,#12] - MOV r2,#MaxChocolateMABlocks - MOV r3,#ModInfo + Incarnation_Postfix + 8 - BL CreateChocolateBlockArray ; better not fail - STR r2,[r1,#16] - MOV r2,#MaxChocolateMSBlocks - MOV r3,#ModSWINode_Size - BL CreateChocolateBlockArray ; better not fail - STR r2,[r1,#20] - - ] - - [ Oscli_HashedCommands - MOV r3,#4*(Oscli_MHashValMask+1) - BL ClaimSysHeapNode ; better not fail - MOV r0,#0 - STR r0,[r0,#Oscli_CmdHashSum] - STR r2,[r0,#Oscli_CmdHashLists] - MOV r3,#Oscli_MHashValMask+1 -DynArea_OHinit_loop - STR r0,[r2],#4 - SUBS r3,r3,#1 - BNE DynArea_OHinit_loop - ] - - [ DynArea_QuickHandles - - LDR r3, =DynArea_ws_size - BL ClaimSysHeapNode ; should not give error - kernel boot - MOV r0, #0 - STR r2, [r0, #DynArea_ws] - MOV r11, r2 - LDR r3, =DynArea_ws_size - ADD r3, r3, r2 -DynArea_QHinit_loop1 - STR r0, [r2], #4 - CMP r2, r3 - BLO DynArea_QHinit_loop1 - - MOV r1, #-1 - STR r1, DynArea_CreatingHandle - STR r1, DynArea_LastTreacleHandle - STR r1, DynArea_LastEnumHandle - STR r1, DynArea_OD8Clamp1 - STR r1, DynArea_OD8Clamp2 - MOV r1, #&1000 - RSB r1, r1, #0 - STR r1, DynArea_OD8Clamp3 ; 4G - 4k - - ADR r1, DynArea_QHandleArray ; init all Qhandles as free, free list = 1..DynArea_NumQHandles - MOV r2, #1 - STR r2, DynArea_FreeQHandles -DynArea_QHinit_loop2 - ADD r2, r2, #1 - STR r2, [r1], #4 - CMP r2, #DynArea_NumQHandles - BLO DynArea_QHinit_loop2 - MOV r2, #0 - STR r2, [r1] ; 0 = end of free list - - MOV r1, #DynArea_NewAreas-1 - ADD r1, r1, #DynArea_NumQHandles ; first non-quick DA number -1 - STR r1, DynArea_TreacleGuess - - LDR r1, =FreePoolDANode - STR r1, DynArea_SortedList ; initially, FreePool at front of sorted list, - LDR r2, =SysHeapDANode - STR r2, [r1, #DANode_SortLink] ; and SysHeap second... - MOV r1, #0 - STR R1, [r2, #DANode_SortLink] ; ...and last - - ADR r1, DynArea_SysQHandleArray - MOV r2, #SysHeapDANode - STR r2, [r1, #ChangeDyn_SysHeap:SHL:2] - MOV r2, #FreePoolDANode - STR r2, [r1, #ChangeDyn_FreePool:SHL:2] - - | - - MOV r0, #0 - STR r0, [r0, #DynArea_ws] - - ] ;DynArea_QuickHandles - - MOV r0, #0 - STR r0, [r0, #CDASemaphore] ; clear CDASemaphore - - EXIT - - LTORG - -InitFreePoolTable - [ FreePoolAddress > SysHeapStart - & 0 ; link: no more nodes on list - | - & SysHeapDANode - ] - & ChangeDyn_FreePool -; [ HAL32 -; ! 0, "Sort out FreePoolInitTable" -; & -1 -; | - & FreePoolAddress -; ] - & AP_FreePool - & 0 ; size will be updated later - & 0 ; max size is computed - & 0 ; no workspace needed - & 0 ; no handler needed - & FreePoolString ; title - -InitSysHeapTable - [ FreePoolAddress > SysHeapStart - & FreePoolDANode ; link -> free pool node, since FreePoolAddress > SysHeapStart - | - & 0 - ] - & ChangeDyn_SysHeap - & SysHeapStart - & AP_SysHeap - & 32*1024-(SysHeapStart-SysHeapChunkAddress) ; size - & SysHeapMaxSize - & SysHeapStart ; workspace pointer -> base of heap - & DynAreaHandler_SysHeap ; area handler - & SysHeapString ; title - -InitAppSpaceTable - & 0 ; link: not on list - & ChangeDyn_AplSpace - & 0 ; base address - & AP_AppSpace - & 0 ; size will be set up later - & AplWorkMaxSize - & 0 ; no workspace needed - & 0 ; no handler needed - & AppSpaceString ; title - -FreePoolString - = "Free pool", 0 -AppSpaceString - = "Application space", 0 -SysHeapString - = "System heap", 0 - ALIGN - -;************************************************************************** -; -; ChangeDynamicSWI - implement OS_ChangeDynamicArea (change the -; size of a dynamic area) -; -; in: r0 = area number -; r1 = size of change (in bytes, signed integer) -; -; out: r0 preserved -; r1 = actual amount moved (in bytes, unsigned integer) -; - - [ DA_Batman -;OR, a special call is allowed for internal use: -; -; in: r0 = ChangeDyn_Batman (-3) -; r1 = size of change (in bytes, signed integer) -; r2 -> pseudo DANode for this call - base of DA will be base of fragment to map/unmap, -; magnitude of r1 will give size of fragment, sign of r1 is +ve for map -ve for unmap - ] - -ChangeDynamicSWI ROUT - Push "r0, r2-r9, r10, lr" - - MOV r10, #0 ; check we're not in an IRQ - LDR r10, [r10, #IRQsema] - TEQ r10, #0 - LDREQ r10, [r10, #CDASemaphore] ; now also check whether ChangeDynamicArea is already threaded - TEQEQ r10, #0 - LDREQB r10, [r10, #VRAMRescue_control] ; also check that wimp has not locked Free Pool - TSTEQ r10, #VRRc_wimp_lock - BNE failure_IRQgoing - MOV r10, #1 - STR r10, [r10, #CDASemaphore-1] ; store non-zero value in CDASemaphore, to indicate we're threaded - - [ DebugCDA2 - DLINE "Entering OS_ChangeDynamicArea (new code)" - ] - - [ DA_Batman - ;check for special Batman call (which uses OS_ChangeDynamicArea to map or unmap a fragment of a sparse DA) - CMP r0, #ChangeDyn_Batcall - MOVEQ r10, r2 ; Batman call passes a pseudo DANode in r2 - BEQ CDA_handlechecked - ] - - Push "r1" - MOV r1, r0 - [ DebugCDA2 - DREG r1, "Checking list for area number " - ] - - [ DynArea_QuickHandles - BL QCheckAreaNumber ; check area number is on list - | - BL CheckAreaNumber ; check area number is on list - ] - - Pull "r1" - BCC failure_IRQgoingClearSemaphore - - [ DebugCDA2 - DLINE "Found entry on list" - ] - - [ DA_Batman - ;a sparse area is not allowed to do an ordinary grow or shrink - ; - LDR r11, [r10, #DANode_Flags] - TST r11, #DynAreaFlags_SparseMap - BNE failure_IRQgoingClearSemaphore - ] - -CDA_handlechecked - - [ DynArea_QuickHandles - MOV r11, #0 - LDR r11, [r11, #DynArea_ws] - LDR r5, DynArea_OD6Signature - CMP r0, #ChangeDyn_MaxArea - BLS daq_cda_od6done - CMP r0, #&FFFFFFF0 ;don't count special DA numbers, such as ChangeDyn_AplSpace - BHI daq_cda_od6done - TST r5, #&80000000 ;if set, disables resize signature for this call - STREQ r5, DynArea_OD6PrevSignature - STREQ r0, DynArea_OD6Handle - ORREQ r5, r5, #4 -daq_cda_od6done - BIC r5, r5, #&80000000 ;clear any disable - STR r5, DynArea_OD6Signature - ] - - MOV r5, #0 - LDR r5, [r5, #Page_Size] ; r5 = page size throughout - SUB r12, r5, #1 ; r12 = page mask - ADD r1, r1, r12 - BICS r1, r1, r12 - BEQ IssueServiceMemoryMoved ; zero pages! (r0 = area number, r1 = size change (0)) - BPL AreaGrow - -AreaShrink - RSB r1, r1, #0 ; make size change positive - [ DebugCDA2 - DREG r0, "Shrinking area ", cc - DREG r1, " by " - ] - MOV r11, r10 ; source is area - CMP r0, #ChangeDyn_FreePool ; if source is free pool - ADREQ r12, AppSpaceDANode ; then dest is appspace - ADRNE r12, FreePoolDANode ; else dest is free pool - - ASSERT DANode_MaxSize = DANode_Size +4 - ADD r2, r12, #DANode_Size - LDMIA r2, {r2, r3} - SUB lr, r3, r2 ; lr = amount dest could grow - - [ ShrinkableDAs - CMP r1, lr - MOVHI r1, lr ; r1 = the most we want to move if we could - BLHI GenNotAllMovedError ; but if not all we still want error - SUB lr, r5, #1 ; lr = pagesize mask - BICS r1, r1, lr ; a pagesize multiple - BEQ IssueServiceMemoryMoved - ] - - [ ShrinkableDAs - LDR r2, [r11, #DANode_Size] ; amount src could shrink - CMP r2, r1 - BLCC TryToShrinkShrinkables - BCS %FT15 ; [we can now do it all] - -; we can't move all that is required, so move smaller amount - - MOV r1, r2 ; move smaller amount - | - LDR r2, [r11, #DANode_Size] ; amount src could shrink - CMP r2, lr - MOVCC lr, r2 ; lr = min(amount dest could grow, amount src could shrink) - - CMP r1, lr - BLS %FT15 - -; we can't move all that is required, so move smaller amount - - MOV r1, lr ; move smaller amount - ] - BL GenNotAllMovedError - SUB lr, r5, #1 ; lr = pagesize mask - BICS r1, r1, lr ; a pagesize multiple - BEQ IssueServiceMemoryMoved -15 - CMP r11, #AppSpaceDANode ; if src <> appspace - CMPNE r12, #AppSpaceDANode ; and dst <> appspace - BNE %FT17 ; then don't call app - Push "r10" ; save -> to area we tried to shrink - MOV r10, r1 - BL CheckAppSpace - Pull "r10" - BVS ChangeDynError -17 - BL CallPreShrink - BVS ChangeDynError ; (r10 still points to area we tried to shrink) - CMP r2, r1 ; can we move as much as we wanted? - MOVCS r2, r1 ; if not, then move lesser amount (r2 = amount we're moving) - BLCC GenNotAllMovedError ; store error, but continue - - TEQ r2, #0 ; if can't move any pages - BEQ NoMemoryMoved ; then exit, issuing Service_MemoryMoved - -; Now move pages starting from end of area - - LDR r0, [r11, #DANode_Base] - LDR r3, [r11, #DANode_Size] - LDR r6, [r11, #DANode_Flags] ; r6 = src flags - Push "r3, r6" ; save src old size, src flags for later - TST r6, #DynAreaFlags_DoublyMapped ; if src is doubly mapped - MOVNE r9, r3 ; then set up offset from 1st copy to 2nd copy = old src size - ADD r0, r0, r3 ; move r0 to point to after end of area (2nd copy) - SUB r3, r3, r2 - STR r3, [r11, #DANode_Size] ; store reduced source size - - LDR r1, [r12, #DANode_Base] ; this is free pool or app space, so it can't be doubly mapped! - LDR r3, [r12, #DANode_Size] - ADD r1, r1, r3 ; r1 -> address of 1st extra page - - LDR lr, =DynAreaFlags_AccessMask - MOV r4, r2 - LDR r6, [r12, #DANode_Flags] ; r6 = dst flags - AND r6, r6, lr -20 - SUB r0, r0, r5 ; pre-decrement source pointer - [ DebugCDA2 - DREG r0, "Moving page at ", cc - DREG r1, " to ", cc - DREG r6, " with PPL " - ] - BL MovePageAtR0ToR1WithAccessR6 - ADD r1, r1, r5 - SUBS r4, r4, r5 - BNE %BT20 - - ADD r3, r3, r2 - STR r3, [r12, #DANode_Size] ; store increased destination size - EORS lr, r12, #AppSpaceDANode ; check if dest = appspace (if so lr:=0) - STREQ r3, [lr, #MemLimit] ; update memlimit if so - - Pull "r3, r6" ; restore src old size, src flags - TST r6, #DynAreaFlags_DoublyMapped ; if src doubly mapped - SUBNES r4, r3, r2 ; then set r4 = number of pages to shuffle up - BEQ %FT30 ; [not doubly mapped, or no pages left, so skip] - - SUB r0, r0, r3 ; move r0 back to end of 1st copy of pages remaining - ADD r1, r0, r2 ; r1 is end of where they're moving to (should be src base address!) - [ 1 = 1 - | - AND r6, r6, #DynAreaFlags_AccessMask - ] - MOV r9, #0 ; no funny stuff while moving these pages -25 - SUB r0, r0, r5 - SUB r1, r1, r5 - [ 1 = 1 - BL GetPageFlagsForR0IntoR6 - ] - BL MovePageAtR0ToR1WithAccessR6 - SUBS r4, r4, r5 - BNE %BT25 - -30 - [ EarlierReentrancyInDAShrink - MOV r4, #0 ; indicate no page block (and ptr to semaphore) - STR r4, [r4, #CDASemaphore] ; OK to reenter now (we've done the damage) - ] - BL CallPostShrink - RSB r1, r2, #0 - LDR r0, [r11, #DANode_Number] ; reload dynamic area number - B IssueServiceMemoryMoved - -AreaGrow - [ DebugCDA2 - DREG r0, "Growing area ", cc - DREG r1, " by " - ] - MOV r12, r10 ; dest is area specified - CMP r0, #ChangeDyn_FreePool ; if dest is free pool - ADREQ r11, AppSpaceDANode ; then src is appspace - ADRNE r11, FreePoolDANode ; else src is free pool (may later be free+apl) - - ASSERT DANode_MaxSize = DANode_Size +4 - ADD r2, r12, #DANode_Size - LDMIA r2, {r2, r3} - SUB lr, r3, r2 ; lr = amount dest could grow - - [ DebugCDA2 - DREG lr, "Dest could grow by " - ] - - LDR r2, [r11, #DANode_Size] ; amount src could shrink - CMP r11, #AppSpaceDANode ; if appspace - SUBEQ r2, r2, #&8000 ; then can't take away last 32K (0..&7FFF) - - [ DebugCDA2 - DREG r2, "Src could shrink by " - ] - - CMP r1, lr ; if enough room in dest - CMPLS r1, r2 ; and enough space in src - MOVLS r3, r1 ; then can do full amount - BLS %FT65 ; so skip this bit - -; we can't move all that is required -; -; if src = AplSpace then -; (dest must be free pool) -; move reduced amount -; else -; (src must be free pool) -; (dest <> AplSpace, cos that's a shrink!) -; so check if adding aplspace would allow us to succeed -; if it does then adjust registers, else give error -; endif -; - - [ DebugCDA2 - DLINE "Can't move all required using just free pool" - ] - - CMP r11, #AppSpaceDANode - BNE %FT62 - MOV r1, lr - CMP r1, r2 - MOVHI r1, r2 ; move min(max addable to dest, max removable from src) - - [ DebugCDA2 - DREG r1, "Dest is free pool, moving reduced amount of " - ] - -61 - BL GenNotAllMovedError - SUB lr, r5, #1 ; lr = pagesize mask - BICS r1, r1, lr ; a pagesize multiple - BEQ IssueServiceMemoryMoved - MOV r3, r1 - B %FT65 - -62 - - [ ShrinkableDAs -; growing another area from free pool -; insert code here to check for shrinking shrinkable areas - - CMP r1, lr ; if dest can't grow by this amount, - BHI %FT64 ; we're definitely not doing anything - - CMP r2, r1 ; this should definitely set C=0 as required by TryToShrinkShrinkables - Push "lr" - BLCC TryToShrinkShrinkables - Pull "lr" - MOVCS r3, r1 ; if succeeded set r3 to number of bytes to do - BCS %FT65 ; and do it -64 - -; end of inserted code - ] - - MOV r4, #AppSpaceDANode - LDR r6, [r4, #DANode_Size] ; get current size of apl space - SUB r6, r6, #&8000 ; can't take away 0-&7FFF - ADD r3, r2, r6 ; add on to amount we could remove from free pool - - [ DebugCDA2 - DREG r6, "Can get from app space an additional ", cc - DREG r3, " making a total of " - ] - - CMP r1, lr ; if not enough room in dest - CMPLS r1, r3 ; or src still doesn't have enough - MOVHI r1, #0 ; then don't move any - BHI %BT61 ; and return error - - MOV r3, r1 ; amount actually doing - - TEQ r2, #0 ; else check to see if there was any at all in free pool - MOVEQ r11, #AppSpaceDANode ; if not, then just take from aplspace - MOVEQ r7, r3 ; and do all - - MOVNE r11, #0 ; else make src indicator reflect that we need both - MOVNE r7, r2 ; but save amount we are taking from freepool - -65 - - Push "r10" - MOV r10, #0 ; default value if apl space not involved - CMP r11, #AppSpaceDANode ; if source = aplspace - RSBEQ r10, r3, #0 ; then make amount -ve - CMP r11, #0 ; if source = free and apl - SUBEQ r10, r7, r3 ; then make it -(amount removing from apl space) - MOVNE r7, r3 ; else set up r7 to be total amount (wasn't set up above) - - [ DebugCDA2 - DREG r3, "Amount actually moving into area = " - DREG r7, "Amount coming from 1st src area = " - ] - - CMP r10, #0 ; if neither of the above then don't talk to app (CMP clears V) - BLNE CheckAppSpace ; else check app agrees - Pull "r10" - BVS ChangeDynError - -; now split up grow into bite-size chunks, and call DoTheGrow to do each one - - Push "r3" ; save original total amount - TEQ r11, #0 ; if taking from both free + apl - MOVEQ r11, #FreePoolDANode ; then start with free - - LDR lr, [r12, #DANode_Flags] ; could this area require particular physical pages at all? - TST lr, #DynAreaFlags_NeedsSpecificPages - BNE %FT70 ; [yes it could, so do it in lumps] - - MOV r1, #0 ; no page block - MOV r2, r3, LSR #12 ; number of pages to do - BL CallPreGrow - LDRVS r3, [sp] ; if error, haven't done any, so restore total as how much to do - BVS %FT95 - - Push "r3, r7" - MOV r2, r7, LSR #12 - BL DoTheGrowNotSpecified - Pull "r3, r7" - SUBS r3, r3, r7 ; subtract off what we just did - - MOVHI r7, r3 ; if not finished, then start 2nd half - MOVHI r11, #AppSpaceDANode ; which is app space - MOVHI r2, r7, LSR #12 - BLHI DoTheGrowNotSpecified - - LDR r3, [sp] ; restore total amount - MOV r1, #0 ; indicate no page block (and ptr to semaphore) - STR r1, [r1, #CDASemaphore] ; OK to reenter now (we've done the damage) - MOV r2, r3, LSR #12 - BL CallPostGrow - BVS %FT95 - B %FT80 - -70 - Push "r3, r7" - CMP r7, #PageBlockChunk ; only do 1 area, so do min(r7,page) - MOVHI r7, #PageBlockChunk - MOV r2, r7, LSR #12 ; number of entries to fill in in page block - BL DoTheGrow - Pull "r3, r7" - BVS %FT95 - CMP r7, #PageBlockChunk ; if 1st area is more than 1 page - SUBHI r3, r3, #PageBlockChunk ; then reduce total - SUBHI r7, r7, #PageBlockChunk ; and partial amounts by 1 page and do it again - BHI %BT70 - - SUBS r3, r3, r7 ; subtract off what we just did - MOVHI r7, r3 ; if not finished, then start 2nd half - MOVHI r11, #AppSpaceDANode ; which is app space - BHI %BT70 ; and loop -80 - Pull "r3" ; restore total amount - - MOV r1, r3 - LDR r0, [r12, #DANode_Number] ; reload dynamic area number - B IssueServiceMemoryMoved - -95 - Pull "r1" ; restore total amount - SUB r1, r1, r3 ; subtract off amount left, to leave done amount - B ChangeDynErrorSomeMoved - -GenNotAllMovedError Entry "r0" - ADRL r0, ErrorBlock_ChDynamNotAllMoved - [ International - BL TranslateError - ] - STR r0, [sp, #2*4] ; sp -> r0,lr, then stacked r0,r2-r9,r10,lr - LDR lr, [sp, #12*4] - ORR lr, lr, #V_bit - STR lr, [sp, #12*4] - EXIT - - LTORG - -ChangeDynError - -; in: r0 -> error -; r10 -> area that we tried to shrink/grow - - MOV r1, #0 -ChangeDynErrorSomeMoved - STR r0, [sp] - LDR lr, [sp, #10*4] - ORR lr, lr, #V_bit - STR lr, [sp, #10*4] - B SomeMemoryMoved - -NoMemoryMoved - MOV r1, #0 ; nothing moved -SomeMemoryMoved - LDR r0, [r10, #DANode_Number] ; reload area number - -; and drop thru to... - -IssueServiceMemoryMoved - -; in: r0 = area number that was shrunk/grown -; r1 = amount moved (signed) -; - [ DA_Batman - CMP r0, #ChangeDyn_Batcall - BEQ ISMM_BatCloak ; cloaking device (no service issue) - ] - Push "r1" - MOV r2, r0 ; r2 = area number - MOV r0, r1 ; amount moved (signed) - MOV r1, #Service_MemoryMoved - BL Issue_Service - Pull "r1" ; restore amount moved - [ DA_Batman -ISMM_BatCloak - ] - TEQ r1, #0 - RSBMI r1, r1, #0 ; r1 on exit = unsigned amount - - MOV r0, #0 - STR r0, [r0, #CDASemaphore] ; clear CDASemaphore - Pull "r0, r2-r9, r10, lr" - ExitSWIHandler - - [ ShrinkableDAs -; *********************************************************************************** -; -; TryToShrinkShrinkables - Attempt to make more space by shrinking shrinkable areas if appropriate -; -; in: r1 = total amount we wish to have in src area (already limited by max_size of destination area) -; r2 = current size of src area -; r11 -> src area node (we don't do anything unless this is the free pool) -; r12 -> dst area node -; C = 0 -; -; out: r2 = new size of src area -; C=0 => failed to move as much as we wanted -; C=1 => succeeded in moving as much as we wanted - -TryToShrinkShrinkables Entry "r0,r1,r10" - LDR lr, [r11, #DANode_Number] - TEQ lr, #ChangeDyn_FreePool - EXIT NE ; if src <> free pool, exit with C, V flags intact - - MOV r10, #DAList - ASSERT DANode_Link = 0 ; because DAList has only link -10 - LDR r10, [r10, #DANode_Link] ; and load next - CMP r10, #1 ; any more nodes? - EXIT CC ; no, then no match - TEQ r10, r12 ; check area <> dest - LDRNE lr, [r10, #DANode_Flags] ; and area is shrinkable - TSTNE lr, #DynAreaFlags_Shrinkable - BEQ %BT10 ; if not, try next area - - SUBS r1, r1, r2 ; r1 = amount we still need - LDR lr, [r10, #DANode_Size] ; available size of this area - CMP lr, r1 - MOVCC r1, lr ; min(amount we need, size of this area) - RSB r1, r1, #0 ; make negative - it's a shrink - MOV r0, #0 - STR r0, [r0, #CDASemaphore] ; momentarily pretend we're not threaded - LDR r0, [r10, #DANode_Number] - SWI XOS_ChangeDynamicArea - MOV r0, #1 - STR r0, [r0, #CDASemaphore-1] ; we're threaded again - LDR r1, [sp, #4] ; reload original r1 - LDR r2, [r11, #DANode_Size] ; get new size of src area - CMP r2, r1 - BCC %BT10 ; if still too small, loop - EXIT ; exit CS indicating success - ] - -; *********************************************************************************** -; -; DoTheGrow - Do one chunk of growing, small enough to fit into the page block on the stack -; -; in: r2 = number of entries to put in page block (for this chunk) -; r5 = page size -; r7 = amount taking from src area (in this chunk) -; (r10 -> dest area) -; r11 -> src area -; r12 -> dest area -; -; out: r0-r2,r4,r6-r9 may be corrupted -; r3,r5,r10-r12 preserved -; -; Note: Removal is from one area only, the calling routine breaks the chunks up at free/app boundary. - -; Temporary (stack frame) workspace used by this routine - - ^ 0, sp -NumEntries # 4 ; Number of entries to do for this chunk -DestAddr # 4 ; Log addr of 1st page being added to dest -DestFlags # 4 ; Page flags for destination area -TotalAmount # 4 ; Total size of grow for this chunk (ie entry value of r3) -SavedPSR # 4 ; PSR before IRQs disabled -Offset1To2 # 4 ; Offset from 1st to 2nd bank - -DoTheGrowNotSpecifiedStackSize * :INDEX: @ ; amount of stack needed for 'not specified' version - -PageBlock1 # PageBlockSize ; 1st page block, for original page numbers and phys. addrs -PageBlock2 # PageBlockSize ; 2nd page block, for new page numbers and phys. addrs - -DoTheGrowStackSize * :INDEX: @ - -DoTheGrow Entry "r3,r5,r10-r12", DoTheGrowStackSize - -; First fill in the page block with -1 in the physical page number words - - STR r2, NumEntries ; save number of entries for use later - STR r7, TotalAmount ; save amount growing by - - ADR r1, PageBlock1 ; point at 1st page block on stack - ADD lr, r2, r2, LSL #1 ; lr = number of words in page block - ADD lr, r1, lr, LSL #2 ; lr -> off end of page block - MOV r0, #-1 -10 - STR r0, [lr, #-12]! ; store -1, going backwards - STR r0, [lr, #PageBlockSize] ; and put -1 in 2nd page block as well - TEQ lr, r1 ; until the end - BNE %BT10 - -; Now call the pre-grow handler - - MOV r3, r7 - BL CallPreGrow - EXIT VS - -; now check to see if particular pages are required - - LDR lr, [r1] ; load page number in 1st entry - CMP lr, #-1 ; is it -1? - BNE DoTheGrowPagesSpecified ; if not, then jump to special code - -; now move pages starting from end of area - - MOV r2, r3 ; amount moving - LDR r0, [r11, #DANode_Base] - LDR r3, [r11, #DANode_Size] - ADD r0, r0, r3 ; move r0 to point to after end of area - SUB r3, r3, r2 ; reduce by amount moving from area - STR r3, [r11, #DANode_Size] ; store reduced source size - TEQ r11, #AppSpaceDANode ; if just appspace - STREQ r3, [r11, #MemLimit-AppSpaceDANode] ; then store in memlimit - - LDR r1, [r12, #DANode_Base] - LDR r3, [r12, #DANode_Size] - - LDR r6, [r12, #DANode_Flags] ; r6 = dst flags - LDR lr, =DynAreaFlags_AccessMask - TST r6, #DynAreaFlags_DoublyMapped ; check if dst is doubly mapped - AND r6, r6, lr - BEQ %FT25 ; [it's not, so skip all this] - -; we must shunt all existing pages in dest area down - - MOVS r4, r3 ; amount to do - BEQ %FT20 ; [none, so skip all this] - Push "r0, r1" - SUB r0, r1, r3 ; src starts at start of 1st copy = start of 2nd - old size - SUB r1, r0, r2 ; dst start = src start - amount of room needed - MOV r9, #0 ; no funny business while moving these pages -15 - BL MovePageAtR0ToR1WithAccessR6 ; move page - ADD r0, r0, r5 ; advance src ptr - ADD r1, r1, r5 ; advance dst ptr - SUBS r4, r4, r5 ; one less page to move - BNE %BT15 ; loop if more - Pull "r0, r1" ; restore original regs -20 - ADD r9, r3, r2 ; set up offset from 1st copy to 2nd copy (= new size) -25 - ADD r1, r1, r3 ; r1 -> address of 1st extra page - MOV r4, #0 ; amount done so far - MOV r10, r2 ; move amount to do into r10, as routine returns page number in r2 - ADR r3, PageBlock1 ; point at 1st entry we have to update -30 - SUB r0, r0, r5 ; pre-decrement source pointer - [ DebugCDA2 - DREG r0, "Moving page at ", cc - DREG r1, " to ", cc - DREG r6, " with PPL " - ] - BL MovePageAtR0ToR1WithAccessR6ReturnPageNumber - STR r2, [r3], #12 ; store page number and move on - ADD r1, r1, r5 - ADD r4, r4, r5 - CMP r4, r10 ; have we done all of it? - BNE %BT30 ; [no, so loop] -35 - LDR r3, [r12, #DANode_Size] - ADD r3, r3, r10 - STR r3, [r12, #DANode_Size] ; store increased destination size - - MOV r3, r10 ; r3 = size of change - LDR r2, NumEntries ; restore number of entries in page block - ADR r1, PageBlock1 ; point at page block 1 with page numbers filled in - BL CallPostGrow - CLRV - EXIT - -37 - -; Come here if a required page is not available -; First we need to go back thru all the part of the page block we've already done, -; marking the pages as not being used after all - - ADR r2, PageBlock1 -38 - LDR r4, [r1, #-12]! ; r4 = physical page number - ADD r4, r0, r4, LSL #3 ; point at cam entry - LDMIA r4, {r8, lr} - BIC lr, lr, #PageFlags_Required - STMIA r4, {r8, lr} - TEQ r1, r2 - BNE %BT38 - -; since pre-grow handler exited without an error, we have to keep our promise -; to call the post-grow handler - - MOV r3, #0 ; no pages moved - MOV r2, #0 ; no pages moved - ADR r1, PageBlock1 ; not really relevant - BL CallPostGrow - - ADR r0, ErrorBlock_CantGetPhysMem - [ International - BL TranslateError - ] - SETV - EXIT - - MakeErrorBlock CantGetPhysMem - -DoTheGrowPagesSpecified - -; First check if any of the pages requested are unavailable -; At the same time as we're doing this, we fill in the log. and phys. addresses in the block - - MOV r0, #0 - LDR r0, [r0, #CamEntriesPointer] - LDR r6, =L2PT -40 - LDR r3, [r1], #12 ; r4 = physical page number - ADD r4, r0, r3, LSL #3 ; point at cam entry - LDMIA r4, {r8, lr} ; r8 = log. addr, lr = PPL - STR r8, [r1, #4-12] ; store log. addr in page block - STR r8, [r1, #PageBlockSize+4-12] ; and in 2nd page block - - TST lr, #PageFlags_Unavailable :OR: PageFlags_Required ; if page in use by someone else, or by us, then return error - BNE %BT37 - ORR lr, lr, #PageFlags_Required ; set bit in flags to say page will be needed - STR lr, [r4, #4] ; and store back - -; work out physical address direct from physical page number, NOT from logical address, since log addr may be Nowhere (multiply mapped) - - MOV r4, #PhysRamTable -42 - LDMIA r4!, {r8, lr} ; load phys addr, size - SUBS r3, r3, lr, LSR #12 ; subtract off number of pages in this chunk - BCS %BT42 - - ADD r3, r3, lr, LSR #12 ; put back what could not be subtracted - ADD r8, r8, r3, LSL #12 ; and add onto base address - STR r8, [r1, #8-12] ; store physical address in page block - - SUBS r2, r2, #1 - BNE %BT40 - -; now issue Service_PagesUnsafe - - ADR r2, PageBlock1 ; r2 -> 1st page block - LDR r3, NumEntries ; r3 = number of entries in page block - MOV r1, #Service_PagesUnsafe - BL Issue_Service - -; now move the pages - - LDR r2, TotalAmount ; amount moving - LDR r0, [r11, #DANode_Base] - LDR r3, [r11, #DANode_Size] - ADD r0, r0, r3 ; move r0 to point to after end of area - SUB r3, r3, r2 ; reduce by amount moving from area - STR r3, [r11, #DANode_Size] ; store reduced source size - TEQ r11, #AppSpaceDANode ; if appspace - STREQ r3, [r11, #MemLimit-AppSpaceDANode] ; then update memlimit - - LDR r1, [r12, #DANode_Base] - LDR r3, [r12, #DANode_Size] - - LDR r6, [r12, #DANode_Flags] ; r6 = dst flags - LDR lr, =DynAreaFlags_AccessMask - AND r6, r6, lr - ORR r6, r6, #PageFlags_Unavailable ; set unavailable bit - STR r6, DestFlags ; save for later - TST r6, #DynAreaFlags_DoublyMapped ; check if dst is doubly mapped - BEQ %FT55 ; [it's not, so skip all this, and r9 will be irrelevant] - -; we must shunt all existing pages in dest area down - - MOVS r4, r3 ; amount to do - BEQ %FT50 ; [none, so skip all this] - Push "r0, r1" - SUB r0, r1, r3 ; src starts at start of 1st copy = start of 2nd - old size - SUB r1, r0, r2 ; dst start = src start - amount of room needed - MOV r9, #0 ; no funny business while moving these pages -45 - BL MovePageAtR0ToR1WithAccessR6 ; move page - ADD r0, r0, r5 ; advance src ptr - ADD r1, r1, r5 ; advance dst ptr - SUBS r4, r4, r5 ; one less page to move - BNE %BT45 ; loop if more - Pull "r0, r1" ; restore original regs -50 - ADD r9, r3, r2 ; set up offset from 1st copy to 2nd copy (= new size) -55 - STR r9, Offset1To2 ; store offset 1st to 2nd copy - ADD r1, r1, r3 ; r1 -> address of 1st extra page - STR r1, DestAddr - ADR r8, PageBlock1 ; r8 -> position in 1st page block - SUB r2, r0, r2 ; r2 = lowest address being removed from src - MOV r3, #0 - LDR r3, [r3, #CamEntriesPointer] - MOV r4, r0 ; r4 is where we're at in allocating spare logical addresses - LDR r9, NumEntries ; number of entries still to do in 1st loop - -; Now before we start, we must construct the second page block, with replacement page numbers - -; DLINE "Start of 1st loop" - -60 - LDR r6, [r8], #12 ; r6 = page number required - LDR r10, [r8, #8-12] ; r10 = phys addr - LDR lr, [r3, r6, LSL #3] ; lr = logical address for this page - -; DREG r6, "Checking page ", cc -; DREG lr, "at address " - - CMP lr, r2 ; check if address is one being taken from src anyway - BCC %FT63 - CMP lr, r0 - BCS %FT63 - -; DLINE "Page is being taken away anyway" - B %FT68 ; [page is being taken anyway, so use same page number + phys addr in 2nd block] - -; page is not one being taken away, so put in 1st replacement page that isn't required by area - -63 -; DLINE "Page is not being taken, looking for replacement" - -64 - SUB r4, r4, r5 ; go onto next page being taken from src -; DREG r4, "Considering address " - - LDR lr, =L2PT - LDR lr, [lr, r4, LSR #10] ; get L2PT entry (to get phys addr) for next free page - MOV r10, lr, LSR #12 ; r10 = phys addr >>> 12 - -; now convert phys addr to page number - - MOV r6, #0 - MOV r1, #PhysRamTable -66 - LDMIA r1!, {r7, lr} ; load phys addr, size - SUB r7, r10, r7, LSR #12 ; number of pages into this bank - CMP r7, lr, LSR #12 ; if more than there are here, - ADDCS r6, r6, lr, LSR #12 ; then advance page number by number of pages in this bank - BCS %BT66 ; and go onto next bank - - ADD r6, r6, r7 ; advance page number by no. of pages into this bank - - ADD r1, r3, r6, LSL #3 ; r1 -> cam entry for this page - LDR r1, [r1, #4] ; get PPL for this page - TST r1, #PageFlags_Required ; if this page is required for the operation - BNE %BT64 ; then try next page - - MOV r10, r10, LSL #12 ; make r10 proper phys addr -; DREG r6, "Using page number " -68 - STR r6, [r8, #PageBlockSize-12] ; store page number in 2nd block - STR r10, [r8, #PageBlockSize+8-12] ; and store phys addr - - SUBS r9, r9, #1 ; one less entry to do - BNE %BT60 - - MOV r7, r3 ; r7 -> camentries - -; Now we can go onto the 2nd loop which actually moves the pages - - LDR r1, DestAddr - MOV r4, #0 ; amount done - MOV r0, r7 ; point r0 at camentries - LDR r7, TotalAmount ; amount to do - ADR r8, PageBlock1 - LDR r9, Offset1To2 -70 - MRS r14, CPSR - STR r14, SavedPSR ; save old PSR (note: stack must be flat when we do this!) - - Push "r0-r4,r7-r12" ; save regs used during copy - MOV r1, #Service_ClaimFIQ - BL Issue_Service - - WritePSRc I_bit+SVC_mode, r6 ; disable IRQs round here (we don't want interrupt code to update - ; the old mapping behind us while we're trying to copy it) - - LDR r6, [r8, #0] ; r6 = page number required - LDR lr, [r8, #PageBlockSize+0] ; lr = page number of replacement page - TEQ r6, lr ; if the same - Pull "r0-r4,r7-r12", EQ ; then restore registers - BEQ %FT76 ; and skip copy and first page move - - ;mjs - ; - if the old page is currently mapped in, copy normally - ; - if the old page is not mapped in, copy via temporary mapping - ; The old scheme, always copying from other mapping, had interrupt cache coherency hole, at least for - ; ARM with writeback cache (bug in 3.7, fixed in Ursula, then lost) - - LDR r0, [r0, lr, LSL #3] ; r0 = log. address for replacement page (NB use logical address to write to, for cache consistency) - - LDR r6, [r8, #4] ;logical address of src page - LDR r3, =Nowhere - TEQ r6, r3 ;will be 'Nowhere' if not mapped in - BNE %FT71 - - ASSERT HAL - SUB sp, sp, #4 ; for oldp - Push "r0,r1" - MOV r0, #0 - LDR r1, [r8, #8] ; r1 = physical address of src for copy - ADD r2, sp, #8 ; must use physical address, as page may be mapped to nowhere along with others - BL RISCOS_AccessPhysicalAddress - MOV r6, r0 ; r6 = logical address of src for copy - Pull "r0,r1" - -71 - ADD lr, r6, r5 ; lr = end src address -72 - LDMIA r6!, {r2, r3, r4, r7, r9, r10, r11, r12} - STMIA r0!, {r2, r3, r4, r7, r9, r10, r11, r12} - TEQ r6, lr - BNE %BT72 - - LDR r0, [r8, #4] ;logical address of src page - LDR r3, =Nowhere - TEQ r0, r3 - - Pull "r0", EQ ; oldp - BLEQ RISCOS_ReleasePhysicalAddress - -; now check if page we're replacing is in L2PT, and if so then adjust L1PT entries (4 of these) - - LDR r6, [r8, #4] ; look at logical address of page being replaced - SUBS r6, r6, #L2PT - BCC %FT74 ; address is below L2PT - CMP r6, #4*1024*1024 - BCS %FT74 ; address is above L2PT - - LDR r2, =L1PT - ADD r2, r2, r6, LSR #(12-4) ; address in L1 of 4 consecutive words to update - LDR r3, [r2] ; load 1st word, to get AP etc bits - MOV r3, r3, LSL #(31-9) ; junk other bits - LDR r4, [r8, #PageBlockSize+8] ; load new physical address for page - ORR r3, r4, r3, LSR #(31-9) ; and merge with AP etc bits - STR r3, [r2], #4 - ADD r3, r3, #&400 - STR r3, [r2], #4 - ADD r3, r3, #&400 - STR r3, [r2], #4 - ADD r3, r3, #&400 - STR r3, [r2], #4 -74 - Pull "r0-r4,r7-r12" ; restore registers - - ; mjs - ; OK, what we are about to do is: - ; 1) move replacement page in (to replace needed page) - ; 2) move needed page to required destination - ; This order means that we don't leave a temporary hole at the logical address we're substituting, - ; which is vital at least in the horrendous case where the logical page is itself used for L2PT. - ; However, this means there is a potential temporary degeneracy in the caches, two physical pages - ; having been seen at the same logical address (undefined behaviour). - ; So, to be safe, we do a MMUChangingEntry first, for the logical page, which will clean/invalidate - ; caches and invalidate TLBs, to avoid degeneracy. This is slight overkill in some cases, but vital - ; to avoid serious grief in the awkward cases. Fortunately, these page substitutions are relatively - ; rare, so performance is not critical. - - MOV lr, #0 - LDR lr, [lr, #CamEntriesPointer] ; lr -> soft cam map - ADD lr, lr, #4 ; point at PPLs, not addresses - LDR r2, [r8, #0] ; need to get PPL for page being replaced - LDR r11, [lr, r2, LSL #3] - BIC r11, r11, #PageFlags_Required ; knock off bits that indicate that it was a required page - - ADD lr, r8, #PageBlockSize - LDMIA lr, {r2, r3} ; get page number, logical address - - Push "r0, r4" - MOV r0, r3 - MOV r4, #0 - ARMop MMU_ChangingEntry,,,r4 - Pull "r0, r4" - - BL Call_CAM_Mapping ; move replacement page in -76 - LDR r2, [r8, #0] - MOV r3, r1 - LDR r11, DestFlags - BL Call_CAM_Mapping ; move needed page to destination - - LDR lr, SavedPSR - MSR CPSR_cf, lr - - Push "r1" - MOV r1, #Service_ReleaseFIQ - BL Issue_Service - Pull "r1" - - ADD r1, r1, r5 ; advance dest ptr - ADD r4, r4, r5 ; increment amount done - ADD r8, r8, #12 ; advance page block ptr - CMP r4, r7 ; have we done all? - BNE %BT70 ; [no, so loop] - - LDR r3, [r12, #DANode_Size] - ADD r3, r3, r7 - STR r3, [r12, #DANode_Size] ; store increased destination size - -; now issue Service_PagesSafe - - LDR r2, NumEntries - ADR r3, PageBlock1 - ADR r4, PageBlock2 - MOV r1, #Service_PagesSafe - BL Issue_Service - -; now call Post_Grow handler - - LDR r3, TotalAmount ; size of grow - LDR r2, NumEntries ; restore number of entries in page block - ADR r1, PageBlock1 ; point at page block 1 with page numbers filled in - BL CallPostGrow - CLRV - EXIT - - LTORG - -; *********************************************************************************** -; -; DoTheGrowNotSpecified - Do one chunk of growing, with no page block -; But don't call pre-grow or post-grow either -; -; in: r2 = number of pages to do (in this chunk) -; r5 = page size -; r7 = amount taking from src area (in this chunk) -; (r10 -> dest area) -; r11 -> src area -; r12 -> dest area -; -; out: r0-r2,r4,r6-r9 may be corrupted -; r3,r5,r10-r12 preserved -; -; Note: Removal is from one area only, the calling routine breaks the chunk at free/app boundary. - - -DoTheGrowNotSpecified Entry "r3,r5,r10-r12", DoTheGrowNotSpecifiedStackSize - - STR r2, NumEntries ; save number of entries for use later - STR r7, TotalAmount ; save amount growing by - -; now move pages starting from end of area - - MOV r2, r7 ; amount moving - LDR r0, [r11, #DANode_Base] - LDR r3, [r11, #DANode_Size] - ADD r0, r0, r3 ; move r0 to point to after end of area - SUB r3, r3, r2 ; reduce by amount moving from area - STR r3, [r11, #DANode_Size] ; store reduced source size - TEQ r11, #AppSpaceDANode ; if just appspace - STREQ r3, [r11, #MemLimit-AppSpaceDANode] ; then store in memlimit - - LDR r1, [r12, #DANode_Base] - LDR r3, [r12, #DANode_Size] - - LDR r6, [r12, #DANode_Flags] ; r6 = dst flags - LDR lr, =DynAreaFlags_AccessMask - AND r6, r6, lr - TST r6, #DynAreaFlags_DoublyMapped ; check if dst is doubly mapped - BEQ %FT25 ; [it's not, so skip all this] - -; we must shunt all existing pages in dest area down - - MOVS r4, r3 ; amount to do - BEQ %FT20 ; [none, so skip all this] - Push "r0, r1" - SUB r0, r1, r3 ; src starts at start of 1st copy = start of 2nd - old size - SUB r1, r0, r2 ; dst start = src start - amount of room needed - MOV r9, #0 ; no funny business while moving these pages -15 - BL MovePageAtR0ToR1WithAccessR6 ; move page - ADD r0, r0, r5 ; advance src ptr - ADD r1, r1, r5 ; advance dst ptr - SUBS r4, r4, r5 ; one less page to move - BNE %BT15 ; loop if more - Pull "r0, r1" ; restore original regs -20 - ADD r9, r3, r2 ; set up offset from 1st copy to 2nd copy (= new size) -25 - ADD r1, r1, r3 ; r1 -> address of 1st extra page - MOV r4, #0 ; amount done so far - MOV r10, r2 ; move amount to do into r10 -30 - SUB r0, r0, r5 ; pre-decrement source pointer - [ DebugCDA2 - DREG r0, "Moving page at ", cc - DREG r1, " to ", cc - DREG r6, " with PPL " - ] - BL MovePageAtR0ToR1WithAccessR6 - ADD r1, r1, r5 - ADD r4, r4, r5 - CMP r4, r10 ; have we done all of it? - BNE %BT30 ; [no, so loop] -35 - LDR r3, [r12, #DANode_Size] - ADD r3, r3, r10 - STR r3, [r12, #DANode_Size] ; store increased destination size - - CLRV - EXIT - -; *********************************************************************************** -; -; CheckAppSpace - If appspace involved in transfer, issue Service or UpCall -; -; Internal routine, called by OS_ChangeDynamicArea -; -; in: r0 = area number passed in to ChangeDyn -; r10 = size of change (signed) -; r11 -> node for src -; r12 -> node for dest -; -; out: If appspace not involved, or application said it was OK, then -; V=0 -; All registers preserved -; else -; V=1 -; r0 -> error -; All other registers preserved -; endif -; - -CheckAppSpace Entry "r0-r3" - MOV r2, #0 - LDR r3, [r2, #AplWorkSize] - LDR r2, [r2, #Curr_Active_Object] - CMP r2, r3 ; check if CAO outside application space - BHI %FT20 ; [it is so issue Service not UpCall] - -; CAO in application space, so issue UpCall to check it's OK - - MOV r0, #UpCall_MovingMemory :AND: &FF - ORR r0, r0, #UpCall_MovingMemory :AND: &FFFFFF00 - MOVS r1, r10 - RSBMI r1, r1, #0 ; r1 passed in is always +ve (probably a bug, but should be compat.) - - SWI XOS_UpCall - CMP r0, #UpCall_Claimed ; if upcall claimed - [ ChocolateAMB - BNE %FT05 - BL Do_AMB_MakeUnsparse ; then ok to move memory, so undo laziness and exit - CLRV - EXIT - | - EXIT EQ ; then OK to move memory, so exit (V=0 from CMP) - ] - -05 - ADR r0, ErrorBlock_ChDynamCAO -10 - [ International - BL TranslateError - ] - STR r0, [sp] - SETV - EXIT - -; IF service call claimed Then Error AplWSpaceInUse - -20 - MOV r0, r10 ; amount removing from aplspace - MOV r1, #Service_Memory - BL Issue_Service - CMP r1, #Service_Serviced - ADREQ r0, ErrorBlock_AplWSpaceInUse ; if service claimed, then return error - BEQ %BT10 - [ ChocolateAMB - BL Do_AMB_MakeUnsparse ; undo laziness - ] - CLRV ; else OK - EXIT - - [ ChocolateAMB -Do_AMB_MakeUnsparse ROUT - Push "r0, lr" - MOVS r0, r10 - RSBMI r0, r0, #0 - BL AMB_MakeUnsparse ;shrinking AppSpace, so make sure unsparse over area of shrink - Pull "r0, pc" - ] ;ChocolateAMB - - MakeErrorBlock AplWSpaceInUse - MakeErrorBlock ChDynamCAO - -; *********************************************************************************** -; -; CallPreShrink - Call pre-shrink routine -; -; in: r1 = amount shrinking by (+ve) -; r5 = page size -; r11 -> node for area being shrunk -; -; out: If handler exits VC, then r2 = no. of bytes area can shrink by -; else r0 -> error block or 0 for generic error, and r2=0 -; - -CallPreShrink Entry "r0,r3,r4, r12" - LDR r0, [r11, #DANode_Handler] ; check if no handler - CMP r0, #0 ; if none (V=0) - EXIT EQ ; then exit - - MOV r0, #DAHandler_PreShrink ; r0 = reason code - MOV r3, r1 ; r3 = amount shrinking by - LDR r4, [r11, #DANode_Size] ; r4 = current size - ASSERT DANode_Handler = DANode_Workspace +4 - ADD r12, r11, #DANode_Workspace - MOV lr, pc - LDMIA r12, {r12, pc} ; load workspace pointer and jump to handler - -; shrink amount returned by handler may not be page multiple (according to spec), -; so we'd better make it so. - - SUB lr, r5, #1 - BIC r2, r3, lr ; make page multiple and move into r2 - EXIT VC - TEQ r0, #0 ; if generic error returned - ADREQL r0, ErrorBlock_ChDynamNotAllMoved ; then substitute real error message - [ International - BLEQ TranslateError - ] - STR r0, [sp] - SETV - EXIT - -; *********************************************************************************** -; -; CallPostShrink - Call post-shrink routine -; -; in: r2 = amount shrinking by (+ve) -; r5 = page size -; r11 -> node for area being shrunk -; -; out: All registers preserved -; - -CallPostShrink Entry "r0,r3,r4, r12" - LDR r0, [r11, #DANode_Handler] ; check if no handler - CMP r0, #0 ; if none (V=0) - EXIT EQ ; then exit - - MOV r0, #DAHandler_PostShrink ; r0 = reason code - MOV r3, r2 ; r3 = amount shrunk by - LDR r4, [r11, #DANode_Size] ; r4 = new size - ASSERT DANode_Handler = DANode_Workspace +4 - ADD r12, r11, #DANode_Workspace - MOV lr, pc - LDMIA r12, {r12, pc} ; load workspace pointer and jump to handler - - EXIT - -; *********************************************************************************** -; -; CallPreGrow - Call pre-grow routine -; -; in: Eventually r1 -> page block (on stack) -; r2 = number of entries in block -; but for now these are both undefined -; r3 = amount area is growing by -; r5 = page size -; r12 -> node for area being grown -; -; out: If can't grow, then -; r0 -> error -; V=1 -; else -; page block may be updated with page numbers (but not yet!) -; All registers preserved -; V=0 -; endif -; - -CallPreGrow Entry "r0,r4, r12" - LDR r0, [r12, #DANode_Handler] ; check if no handler - CMP r0, #0 ; if none (V=0) - EXIT EQ ; then exit - - MOV r0, #DAHandler_PreGrow ; r0 = reason code - LDR r4, [r12, #DANode_Size] ; r4 = current size - ASSERT DANode_Handler = DANode_Workspace +4 - ADD r12, r12, #DANode_Workspace - MOV lr, pc - LDMIA r12, {r12, pc} ; load workspace pointer and jump to handler - EXIT VC ; if no error then exit - - TEQ r0, #0 ; if generic error returned - ADREQL r0, ErrorBlock_ChDynamNotAllMoved ; then substitute real error message - [ International - BLEQ TranslateError - ] - STR r0, [sp] - SETV - EXIT - -; *********************************************************************************** -; -; CallPostGrow - Call post-grow routine -; -; in: Eventually, r1 -> page block with actual pages put in -; r2 = number of entries in block -; r3 = size of change -; r5 = page size -; r12 -> node for area being grown -; -; out: All registers preserved -; - -CallPostGrow Entry "r0,r3,r4, r12" - LDR r0, [r12, #DANode_Handler] ; check if no handler - CMP r0, #0 ; if none (V=0) - EXIT EQ ; then exit - - MOV r0, #DAHandler_PostGrow ; r0 = reason code - LDR r4, [r12, #DANode_Size] ; r4 = new size - ASSERT DANode_Handler = DANode_Workspace +4 - ADD r12, r12, #DANode_Workspace - MOV lr, pc - LDMIA r12, {r12, pc} ; load workspace pointer and jump to handler - EXIT - - [ ShrinkableDAs -; *********************************************************************************** -; -; CallTestShrink - Call test-shrink routine -; -; in: r11 -> area node -; -; out: If handler exits VC, then r3 = no. of bytes area can shrink by -; else r0 -> error block or 0 for generic error, and r3=0 -; - -CallTestShrink Entry "r0,r4,r5, r12" - LDR r0, [r11, #DANode_Handler] ; check if no handler - CMP r0, #0 ; if none (V=0) - EXIT EQ ; then exit - - MOV r0, #DAHandler_TestShrink ; r0 = reason code - LDR r4, [r11, #DANode_Size] ; r4 = current size - MOV r5, #0 - LDR r5, [r5, #Page_Size] ; set r5 = page size - ASSERT DANode_Handler = DANode_Workspace +4 - ADD r12, r11, #DANode_Workspace - MOV lr, pc - LDMIA r12, {r12, pc} ; load workspace pointer and jump to handler - -; shrink amount returned by handler may not be page multiple (according to spec), -; so we'd better make it so. - - SUBVC lr, r5, #1 - BICVC r3, r3, lr ; make page multiple - EXIT VC - TEQ r0, #0 ; if generic error returned - ADREQL r0, ErrorBlock_ChDynamNotAllMoved ; then substitute real error message - [ International - BLEQ TranslateError - ] - STR r0, [sp] - MOV r3, #0 ; indicate no shrink possible - SETV - EXIT - ] - -; *********************************************************************************** -; -; MovePageAtR0ToR1WithAccessR6 -; -; Internal routine, called by OS_ChangeDynamicArea -; -; in: r0 = logical address where page is now -; r1 = logical address it should be moved to -; r6 = area flags (which contain access privileges, and cacheable/bufferable bits) -; -; out: All registers preserved -; - -MovePageAtR0ToR1WithAccessR6 Entry "r2-r5,r11" - MOV r3, r1 - MOV r11, r6 - BL MoveCAMatR0toR3 ; use old internal routine for now - EXIT - -; Same as above, but returns with r2 = page number of page that moved - -MovePageAtR0ToR1WithAccessR6ReturnPageNumber Entry "r3-r5,r11" - MOV r3, r1 - MOV r11, r6 - BL MoveCAMatR0toR3 ; use old internal routine for now - EXIT - -; *********************************************************************************** -; -; DynAreaHandler_SysHeap - Dynamic area handler for system heap -; DynAreaHandler_RMA - Dynamic area handler for RMA -; -; in: r0 = reason code (0=>pre-grow, 1=>post-grow, 2=>pre-shrink, 3=>post-shrink) -; r12 -> base of area -; - -DynAreaHandler_SysHeap -DynAreaHandler_RMA ROUT - CMP r0, #4 - ADDCC pc, pc, r0, LSL #2 - B UnknownHandlerError - B PreGrow_Heap - B PostGrow_Heap - B PreShrink_Heap - B PostShrink_Heap - -PostGrow_Heap -PostShrink_Heap - STR r4, [r12, #:INDEX:hpdend] ; store new size - -; and drop thru to... - -PreGrow_Heap - CLRV ; don't need to do anything here - MOV pc, lr ; so just exit - -PreShrink_Heap - Push "r0, lr" - PHPSEI ; disable IRQs round this bit - LDR r0, [r12, #:INDEX:hpdbase] ; get minimum size - SUB r0, r4, r0 ; r0 = current-minimum = max shrink - CMP r3, r0 ; if requested shrink > max - MOVHI r3, r0 ; then limit it - SUB r0, r5, #1 ; r0 = page mask - BIC r3, r3, r0 ; round size change down to page multiple - SUB r0, r4, r3 ; area size after shrink - STR r0, [r12, #:INDEX:hpdend] ; update size - - PLP ; restore IRQ status - CLRV - Pull "r0, pc" - -AreaName_RMA - = "Module area", 0 - [ LongCommandLines :LAND: (:LNOT: HAL) -AreaName_Kbuffs - = "Kernel buffers", 0 - ] - ALIGN - - -UnknownHandlerError - Push "lr" - ADRL r0, ErrorBlock_UnknownAreaHandler - [ International - BL TranslateError - ] - SETV - Pull "pc" - -DynAreaHandler_Sprites - CMP r0, #4 - ADDCC pc, pc, r0, LSL #2 - B UnknownHandlerError - B PreGrow_Sprite - B PostGrow_Sprite - B PreShrink_Sprite - B PostShrink_Sprite - -PostGrow_Sprite -PostShrink_Sprite Entry "r0" - -; in - r3 = size change (+ve), r4 = new size, r5 = page size - - MOV lr, #VduDriverWorkSpace - TEQ r4, #0 ; if new size = 0 - STREQ r4, [lr, #SpAreaStart] ; then set area ptr to zero - STRNE r12, [lr, #SpAreaStart] ; else store base address - - MOV r0, #0 - LDR lr, [r0, #SpriteSize] ; load old size - STR r4, [r0, #SpriteSize] ; and store new size - BEQ %FT10 ; if new size is zero, don't try to update header - - STR r4, [r12, #saEnd] ; store new size in header - TEQ lr, #0 ; if old size was zero - STREQ lr, [r12, #saNumber] ; then initialise header (no. of sprites = 0) - MOVEQ lr, #saExten - STREQ lr, [r12, #saFirst] ; ptr to first sprite -> after header - STREQ lr, [r12, #saFree] ; ptr to first free byte -> after header - -10 - CLRV ; don't need to do anything here - EXIT ; so just exit - -PreGrow_Sprite - CLRV ; don't need to do anything here - MOV pc, lr ; so just exit - -PreShrink_Sprite Entry "r0" - TEQ r4, #0 ; if current size is zero - BEQ %FT10 ; then any shrink is OK (shouldn't happen) - - LDR r0, [r12, #saFree] ; get used amount - TEQ r0, #saExten ; if only header used, - MOVEQ r0, #0 ; then none really in use - - SUB r0, r4, r0 ; r0 = current-minimum = max shrink - CMP r3, r0 ; if requested shrink > max - MOVHI r3, r0 ; then limit it - SUB r0, r5, #1 ; r0 = page mask - BIC r3, r3, r0 ; round size change down to page multiple -10 - CLRV - EXIT - -AreaName_SpriteArea - = "System sprites", 0 - ALIGN - - -DynAreaHandler_RAMDisc - CMP r0, #4 - ADDCC pc, pc, r0, LSL #2 - B UnknownHandlerError - B PreGrow_RAMDisc - B PostGrow_RAMDisc - B PreShrink_RAMDisc - B PostShrink_RAMDisc - -PostGrow_RAMDisc -PostShrink_RAMDisc Entry "r0-r6" - -; in - r3 = size change (+ve), r4 = new size, r5 = page size -; but we don't really care about any of these - -; The only thing we have to do here is ReInit RAMFS, but NOT if -; a) no modules are initialised yet (eg when we're created), or -; b) RAMFS has been unplugged - - MOV r0, #0 - LDR r0, [r0, #Module_List] - TEQ r0, #0 ; any modules yet? - BEQ %FT90 ; no, then don't do anything - - MOV r0, #ModHandReason_EnumerateROM_Modules - MOV r1, #0 - MOV r2, #-1 ; enumerate ROM modules looking for RAMFS -10 - SWI XOS_Module - BVS %FT50 ; no more modules, so it can't be unplugged - ADR r5, ramfsname -20 - LDRB r6, [r3], #1 ; get char from returned module name - CMP r6, #" " ; if a terminator then we have a match - BLS %FT30 ; so check for unplugged - LowerCase r6, lr ; else force char to lower case - LDRB lr, [r5], #1 ; get char from "ramfs" string - CMP lr, r6 ; and if matches - BEQ %BT20 ; then try next char - B %BT10 ; else try next module - -30 - CMP r4, #-1 ; is module unplugged? - BEQ %FT90 ; if so, then mustn't reinit it -50 - MOV r0, #ModHandReason_ReInit ; reinit module - ADR r1, ramfsname - SWI XOS_Module ; ignore any errors from this -90 - CLRV - EXIT - -PreGrow_RAMDisc -PreShrink_RAMDisc Entry "r0-r5" - MOV r0, #0 - LDR r0, [r0, #Module_List] ; first check if any modules going - TEQ r0, #0 - BEQ %FT90 ; if not, don't look at filing system - - MOV r0, #5 - ADR r1, ramcolondollardotstar - SWI XOS_File - CMPVC r0, #0 - BVS %FT90 ; if no RAMFS then change OK - BEQ %FT90 ; or if no files, then change OK - ADR r0, ErrorBlock_RAMFsUnchangeable - [ International - BL TranslateError - ] - STR r0, [sp] - SETV - EXIT - -90 - CLRV - EXIT - - MakeErrorBlock RAMFsUnchangeable - -AreaName_RAMDisc - = "RAM disc", 0 -ramcolondollardotstar - = "ram:$.*", 0 -ramfsname - = "ramfs", 0 - ALIGN - - -DynAreaHandler_FontArea - CMP r0, #4 - ADDCC pc, pc, r0, LSL #2 - B UnknownHandlerError - B PreGrow_FontArea - B PostGrow_FontArea - B PreShrink_FontArea - B PostShrink_FontArea - -PostGrow_FontArea Entry "r0-r2" - -; in - r3 = size change (+ve), r4 = new size, r5 = page size - - MOV r1, #0 - LDR r1, [r1, #Module_List] ; any modules active? - TEQ r1, #0 - MOVNE r1, r4 ; there are, so inform font manager of size change - SWINE XFont_ChangeArea - CLRV - EXIT - -PostShrink_FontArea -PreGrow_FontArea - CLRV ; don't need to do anything here - MOV pc, lr ; so just exit - -PreShrink_FontArea Entry "r0-r2" - MOV r1, #-1 ; ask font manager for minimum size of font area - MOV r2, #0 ; default value if no font manager - SWI XFont_ChangeArea ; out: r2 = minimum size - - SUB r0, r4, r2 ; r0 = current-minimum = max shrink - CMP r3, r0 ; if requested shrink > max - MOVHI r3, r0 ; then limit it - SUB r0, r5, #1 ; r0 = page mask - BIC r3, r3, r0 ; round size change down to page multiple - - SUB r1, r4, r3 ; r1 = new size - SWI XFont_ChangeArea ; tell font manager to reduce usage - - CLRV - EXIT - -AreaName_FontArea - = "Font cache", 0 - ALIGN - - -; **** New screen stuff **** -; -; -; This source collects together all the new routines needed to make -; the screen into a new dynamic area. -; -; It has the following dependencies elsewhere in the kernel before -; it can be expected to work: -; -; * Definition of AP_Screen in ChangeDyn needs doubly_mapped and -; name_is_token bits set -; * name_is_token handling needs adding (or scrap the bit designation) -; * Call to CreateNewScreenArea from NewReset to create area -; * Tim says doubly-mapped areas are broken - this must be fixed first -; * Old CDA routine may be retired, since screen is its last client -; * Has Tim completed the rest of this work? -; -; Once these routines work, they should be grafted into appropriate -; places in the kernel sources -; -; This source is not intended for stand-alone assembly: it should be -; plumbed into the kernel source build -; -; Version history - remove this once integrated with kernel sources -; -; Vsn Date Who What -; --- -------- --- ---------------------------------------------- -; 000 23/08/93 amg Written -; 001 24/08/93 amg Fixes and changes following review by TMD -; 002 03/09/93 tmd Updated to work! - -; ********************************************************************* -; Create a new style dynamic area for the screen -; ********************************************************************* - -; Entry requirements -; none - -AreaName_Screen - = "Screen memory",0 ;needs replacing with message token - ALIGN - -; ********************************************************************* -; Handler despatch routine for screen dynamic area -; ********************************************************************* - -DynAreaHandler_Screen ;despatch routine for pre/post grow/shrink handlers - CMP r0, #4 - ADDCC pc, pc, R0, LSL #2 - B UnknownHandlerError ;already defined in ChangeDyn - B PreGrow_Screen ;the rest are defined here - B PostGrow_Screen - B PreShrink_Screen - B PostShrink_Screen - -;The sequence of events which these handlers must do is: -; -;Grow Screen -; -;Pre : Remove cursors -; Work out which physical page numbers are needed and return a list -;CDA : Move existing pages lower in memory within first copy (ie change logical address -; associated with physical pages) -; Locate and free the next physical pages in line (if used a page swap must occur) -; Assign the new pages logical addresses in the gap between the end of the present -; logical range and the start of the second physical range -;Post: Adjust screen memory contents & screen start addresses to retain screen display -; -;Shrink Screen -; -;Pre : Remove cursors -; Adjust screen memory contents & screen start addresses to retain screen display -;CDA : Move pages from screen to free pool (creates a gap in first logical range) -; Close up the gap in logical addressing -;Post: Restore cursors -; - -; *********************************************************************************** -; Handlers for the screen dynamic area -; *********************************************************************************** - -;Pregrow entry parameters -; R0 = 0 (reason code) -; R1 -> page block (entries set to -1) -; R2 = number of entries in page block == number of pages area is growing by -; R3 = number of bytes area is growing by (r2 * pagesize) -; R4 = current size (bytes) -; R5 = page size -; -; exit with V clear, all preserved - -PreGrow_Screen Entry "r0-r2,r4" - LDR r0, [WsPtr, #CursorFlags] ; test if VDU inited yet - LDRB lr, [WsPtr, #ExternalFramestore] - TEQ r0, #0 ; if not, CursorFlags will be zero - BEQ %FT05 - TEQ lr, #0 - SWIEQ XOS_RemoveCursors ; if VDU inited, then remove cursors - -05 ADRL r0, PageShifts-1 - LDRB r0, [r0, r5, LSR #12] ; grab log2Pagesize for shifting - MOV r4, r4, LSR r0 ; change present size into number of pages - ; since page numbers are 0 to n-1 thus n - ; is the first page number we want to insist on -10 - STR r4, [r1], #12 ; store physical page number and increment to next - SUBS r2, r2, #1 ; one less to do - ADDNE r4, r4, #1 ; next physical page number - BNE %BT10 ; continue until all pages done - CLRV ; ok, so I'm paranoid... - EXIT - -; ********************************************************************** - -;PostGrow entry parameters -;R0 = 1 (reason code) -;R1 -> page block (only physical page numbers are meaningful) -;R2 = number of entries in page block (= number of pages area grew by) -;R3 = number of bytes area grew by -;R4 = new size of area (bytes) -;R5 = page size - -PostGrow_Screen Entry "r0,r5" - LDR r0, [WsPtr, #CursorFlags] ; test if VDU inited (CursorFlags=0 => not) - TEQ r0, #0 - BEQ %FT90 ; if not inited, do nothing - - PHPSEI r5 ; disable IRQs - - MOV r0, r3 ; move number of bytes area grew by into r0 - BL InsertPages ; only call InsertPages if VDU inited - - PLP r5 ; restore IRQ state - SWI XOS_RestoreCursors ; and restore cursors -90 - CLRV - EXIT - -; *********************************************************************** - -;PreShrink Entry parameters -;R0 = 2 (reason code) -;R3 = number of bytes area is shrinking by -;R4 = current size of area (bytes) -;R5 = page size -;R12 = vdu workspace - -PreShrink_Screen Entry "R0-R2,R4-R5" - - ;need to check whether the proposed shrink still leaves enough for - ;the current amount needed by the vdu drivers, if it doesn't we - ;reduce R3 to be the most we can spare (in whole pages) - - [ HAL - MOV LR, #0 - LDR LR, [LR, #VRAMFlags] ;is VRAM suitable for general use? - TST LR, #2 ;if not - don't shrink screen memory - MOVNE R3, #0 - ] - SUB R2, R5, #1 ;make a page mask - - LDRB R14, [R12, #ExternalFramestore] - TEQ R14, #0 ;okay to shrink if using external framestore - BEQ %FT12 - RSB R0, R3, #0 ;R0= -(number of bytes) for RemovePages - BL RemovePages - CLRV - EXIT - -12 LDR R5, [R12, #ScreenSize] ;get current minimum size - - SUB R1, R4, R5 ;R1 = maximum shrink (current - screensize) - CMP R3, R1 ;if requested shrink > max... - MOVHI R3, R1 ;...then limit it, and... - BICS R3, R3, R2 ;...round down to multiple of page size - BEQ %FT10 ;don't shuffle screen data if resultant - ;shrink is 0 bytes/0 pages - SWI XOS_RemoveCursors - PHPSEI R5 ;disable interrupts - RSB R0, R3, #0 ;R0= -(number of bytes) for RemovePages - BL RemovePages ;entry: R0 = -(number of bytes) - PLP R5 ;restore interrupts -10 - CLRV - EXIT - -; ************************************************************************ - -;PostShrink Entry parameters -;R0 = 3 (reason code) -;R3 = number of bytes area shrank by -;R4 = new size of area (bytes) -;R5 = page size - -PostShrink_Screen Entry - SWI XOS_RestoreCursors - CLRV ;ok, so I'm paranoid... - EXIT - -; ************************************************************************ - - - END diff --git a/s/Convrsions b/s/Convrsions deleted file mode 100644 index 85c156bd..00000000 --- a/s/Convrsions +++ /dev/null @@ -1,387 +0,0 @@ -; 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 => Convrsions : varicose number->string routines - -despatchConvert ROUT - - MOV r12, #0 ; All conversions want initial cnt = 0 - - CMP R11, #OS_ConvertFixedNetStation - BGE EconetStation - - Push "R1, lr" - SUB R10, R11, #OS_ConvertHex1 + 1 - BIC R10, R10, #3 - ADD PC, PC, R10 - B Hex_Output ; one digit : -4 - B Hex_Output ; 2,3,4,8 digits: 0 - B Cardinal_Output ; 4 - B Signed_Output ; 8 - B Binary_Output ; 12 - B Cardinal_Spaced_Output ; 16 - B Signed_Spaced_Output ; 20 - -Hex_Output ROUT - - SUBS R11, R11, #OS_ConvertHex1 - MOVNE R11, R11, LSL #3 - MOVEQ R11, #4 - MOV R0, R0, ROR R11 - -01 MOV R0, R0, ROR #28 - AND R10, R0, #&F - CMP R10, #10 - ADDGE R10, R10, #"A"-10 - ADDLT R10, R10, #"0" - BL addconvchar - BVS naffconversion - SUBS R11, R11, #4 - BNE %BT01 - -endconversion - MOVVC R10, #0 - BLVC addconvchar - BVS naffconversion - - Pull "R0, lr" - SUB R2, R2, R12 - ADD R2, R2, #1 ; null not really a char. - SUB R1, R1, #1 - ExitSWIHandler - -naffconversion - ADRL R0, ErrorBlock_BuffOverflow -naffconversion_ErrorSet - [ International - BL TranslateError - ] - Pull "R1, lr" - B SLVK_SetV - -Binary_Output ROUT - - SUB R11, R11, #OS_ConvertBinary1-1 - MOV R11, R11, LSL #3 - MOV R0, R0, ROR R11 -01 MOV R0, R0, ROR #31 - AND R10, R0, #1 - ADD R10, R10, #"0" - BL addconvchar - BVS naffconversion - SUBS R11, R11, #1 - BNE %BT01 - B endconversion - - -; cardinal output very similar to BinaryToDecimal - -Cardinal_Output ROUT - - SUB R11, R11, #OS_ConvertCardinal1-1 - MOV R11, R11, LSL #3 - MOV R10, #-1 - MOV R10, R10, LSL R11 - BIC R0, R0, R10 - Push "R3-R5" - ADRL R3, TenTimesTable - MOV R5, #9 ; max entry - MOV R4, #0 ; non-0 had flag -02 LDR R11, [R3, R5, LSL #2] - MOV R10, #"0"-1 ; digit value -03 SUBS R0, R0, R11 - ADD R10, R10, #1 - BCS %BT03 - ADD R0, R0, R11 - CMP R10, #"0" - CMPEQ R4, #0 - BNE %FT04 ; put digit - -05 SUBS R5, R5, #1 - BPL %BT02 ; next digit - CMP R4, #0 - BEQ %FT04 ; R5 must be 0 - Pull "R3-R5" - B endconversion - -04 MOV R4, #-1 - BL addconvchar - BVC %BT05 - Pull "R3-R5" - B naffconversion - - -Signed_Output ROUT - - SUB R11, R11, #OS_ConvertInteger1-1 - MOV R11, R11, LSL #3 - AND R11, R11, #31 - RSB R11, R11, #32 - AND R11, R11, #31 - MOV R0, R0, LSL R11 - MOV R0, R0, ASR R11 - MOV R12, R2 - SWI XOS_BinaryToDecimal - MOVVS r2, r12 - ADDVC R1, R1, R2 - Swap R2, R12, VC - B endconversion - - -Cardinal_Spaced_Output ROUT -Signed_Spaced_Output - - SUB sp, sp, #12 ; get 12 byte buffer - Push "r1,r2,lr" - LDR r10,code_of_swi - ADD r10,r10,r11 - ADD r1, sp, #3*4 - MOV r2, #12 - SWI XOS_CallASWI - RSB r0, r2, #12 ; bytes got - Pull "r1,r2,lr" - MOV R12, #0 - MOV R11, sp -01 LDRB R10, [R11], #1 - BL addconvchar - BVS space_conv_exit - SUBS R0, R0, #1 - BEQ space_conv_exit - CMP R10, #"-" - BEQ %BT01 - CMP R0, #3 - CMPNE R0, #6 - CMPNE R0, #9 - BNE %BT01 - MOV R10, #" " - BL addconvchar - BVC %BT01 - -space_conv_exit - ADD sp, sp, #12 - B endconversion - -code_of_swi - DCD XOS_ConvertCardinal1 - OS_ConvertSpacedCardinal1 - - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; R1 current buffer pos -; R12 character count, R2 character limit -; R10 character - -addconvchar ROUT - - CMP R2, R12 - BLE addconvcharoverflow - - ADD R12, R12, #1 - STRB R10, [R1], #1 - RETURNVC - -addconvcharoverflow - RETURNVS - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; EcoNet conversions - -EconetStation ROUT - - CMP R11, #OS_ConvertFixedFileSize - BGE FileSizeConversion - - Push "R1, lr" - Push "R0" - LDR R0, [R0, #4] - CMP R0, #256 - BHS invalidnetworknumber - MOV R10, #" " - BL doabyte - BVS %FT01 - CMP R10, #"0" - MOVEQ R10, #"." - CMPNE R11, #OS_ConvertFixedNetStation - BLEQ addconvchar - CMP R10, #"." - MOVEQ R10, #"0" - -01 - Pull "R0" - BVS naffconversion - LDR R0, [R0] - CMP R0, #0 - CMPNE R0, #256 - BHS invalidstationnumber - BL doabyte - B endconversion - -invalidnetworknumber - INC sp, 4 ; Pull "R0" - ADR R0, ErrorBlock_BadNetwork - B naffconversion_ErrorSet - -invalidstationnumber - ADR R0, ErrorBlock_BadStation - B naffconversion_ErrorSet - -ErrorBlock_BadNetwork - DCD ErrorNumber_BadNetwork - DCB "BadNet" ; The token for the Global message - DCB 0 - ALIGN - -ErrorBlock_BadStation - DCD ErrorNumber_BadStation - DCB "BadStn" ; The token for the Global message - DCB 0 - ALIGN - -doabyte ROUT - ; R0 is byte, R11 SWI number (to indicate pad or not) - ; return VS for oflo - Push "lr" - CMP R11, #OS_ConvertNetStation - BEQ %FT03 - CMP R0, #100 - BGE %FT03 - BL addconvchar - Pull "PC", VS -02 CMP R0, #10 - BGE %FT03 - BL addconvchar - Pull "PC", VS -03 CMP R0, #0 - BNE %FT01 - CMP R11, #OS_ConvertNetStation - Pull "PC", EQ - Pull "lr" - B addconvchar - -01 MOV R10, R2 - SUB R2, R2, R12 ; bytes left - SWI XOS_BinaryToDecimal - ADD R12, R12, R2 - ADD R1, R1, R2 - MOV R2, R10 - MOV R10, #"0" - Pull "PC" - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; Do length as xxxx bytes or xxxx Kbytes or xxxx Mbytes - -; In r0 = size in bytes -; r1 -> buffer -; r2 = buffer length -; r12 = 0 - -; Out r0 = r1in -; r1 -> terminating zero -; r2 = amount of buffer left - -FileSizeConversion ROUT - - Push "r1, lr" - - Push "r4-r7" - SUB sp, sp, #16 ; May need temp frame - - MOV r4, #0 ; No char by default - CMP r0, #4096 ; Only go to 'K' format if > 4K - MOVCS r4, #"K" ; Kilo - MOVCSS r0, r0, LSR #10 ; /1024 - ADC r0, r0, #0 ; Round up iff divided and bit fell out - CMP r0, #4096 ; Only go to 'M' format if > 4M - MOVCS r4, #"M" ; Mega - MOVCSS r0, r0, LSR #10 ; /1024 again - ADC r0, r0, #0 ; Round up iff divided and bit fell out - -; No need to go to 'G' format as 2^32 = 4096M! - - MOV r5, r0 ; Remember for prettiness - - CMP r11, #OS_ConvertFixedFileSize - BNE %FT50 - - Push "r1, r2" ; Remembering state - ADD r1, sp, #4*2 ; Point to our temp buffer - MOV r2, #16 - SWI XOS_BinaryToDecimal ; This will not give error - MOV r7, r2 ; Number of chars to do - RSBS r6, r2, #4 ; Number of spaces needed - Pull "r1, r2" - BLE %FT39 - -30 MOV r10, #" " - BL addconvchar - BVS %FA95 - SUBS r6, r6, #1 - BNE %BT30 - -39 MOV r6, sp ; Stick string in punter's buffer -40 LDRB r10, [r6], #1 - BL addconvchar - BVS %FA95 - SUBS r7, r7, #1 - BNE %BT40 - - B %FT60 - - -50 MOV r12, r2 ; No padding on LHS, easy case - SWI XOS_BinaryToDecimal - MOVVS r2, r12 - ADDVC r1, r1, r2 - Swap r2, r12, VC - -60 MOVVC r10, #" " - BLVC addconvchar - BVS %FA95 - - MOVS r10, r4 ; Char to print ? VClear - BNE %FT70 - - CMP r11, #OS_ConvertFixedFileSize ; VClear - BNE %FT75 - - MOV r10, #" " ; Need to pad in middle - -70 BL addconvchar - -75 MOVVC r10, #"b" ; 'byte' - BLVC addconvchar - MOVVC r10, #"y" - BLVC addconvchar - MOVVC r10, #"t" - BLVC addconvchar - MOVVC r10, #"e" - BLVC addconvchar - BVS %FA95 - - CMP r5, #1 ; Prettify (unpluralisationism). VClear - MOVNE r10, #"s" - BNE %FT90 - - CMP r11, #OS_ConvertFixedFileSize ; VClear - BNE %FA95 - MOV r10, #" " ; Need to pad to right - -90 BL addconvchar - -95 ADD sp, sp, #16 - Pull "r4-r7" - B endconversion - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - END diff --git a/s/End b/s/End deleted file mode 100644 index bae768eb..00000000 --- a/s/End +++ /dev/null @@ -1,22 +0,0 @@ -; Copyright 2002 Tematic 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. -; - EXPORT EndOfKernel - - AREA ZZZZZ, CODE, READONLY, ALIGN=16 ; align to 64K (yuck) - -EndOfKernel - & 0 ; for patching by BigSplit et al - - END diff --git a/s/ExtraSWIs b/s/ExtraSWIs deleted file mode 100644 index 1e7e3f48..00000000 --- a/s/ExtraSWIs +++ /dev/null @@ -1,81 +0,0 @@ -; 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. -; -; > ExtraSWIs - - [ ProcessorVectors - -;---------------------------------------------------------------------------------------- -; ClaimProcVecSWI -; -; In: r0 = vector and flags -; bit meaning -; 0-7 vector number -; 0 = 'Branch through 0' vector -; 1 = Undefined instruction -; 2 = SWI -; 3 = Prefetch abort -; 4 = Data abort -; 5 = Address exception (only on ARM 2 & 3) -; 6 = IRQ -; 7+ = reserved for future use -; 8 0 = release -; 1 = claim -; 9-31 reserved (set to 0) -; r1 = replacement value -; r2 = value which should currently be on vector (only needed for release) -; -; Out: r1 = value which has been replaced (only returned on claim) -; -; Allows a module to attach itself to one of the processor vectors. -; -ClaimProcVecSWI ROUT - Entry "r3-r5" - - AND r3, r0, #&FF ; Get vector number. - CMP r3, #(ProcVec_End-ProcVec_Start):SHR:2 - ADRCSL r0, ErrorBlock_BadClaimNum - BCS %FT30 - - MOV r4, r1 ; r4 = replacement value - LDR r5, =ProcVec_Start - PHPSEI ; Disable IRQs while we mess around with vectors. - - TST r0, #1:SHL:8 - LDRNE r1, [r5, r3, LSL #2]! ; If claiming then return current value (r5->vector to replace). - BNE %FT10 - - LDR r3, [r5, r3, LSL #2]! ; Releasing so get current value (r5->vector to replace). - TEQ r2, r3 ; Make sure it's what the caller thinks it is. - ADRNEL r0, ErrorBlock_NaffRelease - BNE %FT20 -10 - STR r4, [r5] ; Store replacement value. - PLP ; Restore IRQs. - PullEnv - ExitSWIHandler - -20 - PLP ; Restore IRQs and return error. -30 - [ International - BL TranslateError - ] - PullEnv - B SLVK_SetV - - ] - - - END diff --git a/s/FlashROM b/s/FlashROM deleted file mode 100644 index 506bc3c1..00000000 --- a/s/FlashROM +++ /dev/null @@ -1,671 +0,0 @@ -; Copyright 1999 Element 14 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. -; -; This file handles the programming of flash devices in ROM bank 0 with -; a ROM image transferred via the parallel port. This is for development -; purposes only, and is only likely to work on the system for which it was -; designed. - -; Flash Memory Settings - -FR_FlashBase * &00000000 - -FR_DeviceBufferSize * 32 ; 28F640J5 has 32 byte buffer -FR_DeviceBlockSizeBits * 17 ; 28F640J5 has 128KB blocks -FR_DeviceBlocks * 64 ; 64 blocks in a 28F640J5 - -FR_BufferSize * FR_DeviceBufferSize*2 ; 2 devices -FR_BlockSizeBits * FR_DeviceBlockSizeBits+1 ; 2 devices -FR_BlockSize * 1 :SHL: FR_BlockSizeBits ; 256KB -FR_FlashSize * FR_BlockSize*FR_DeviceBlocks ; 16MB - -; Sizes of things in memory - -FR_StackSize * 1024 -FR_RAMCodeSize * 4096 -FR_ScreenSize * 472*1024 - -; Addresses of where we put things in memory - -FR_PageTableBaseAddr * DRAM0PhysRam -FR_StackBase * FR_PageTableBaseAddr+16*1024+FR_StackSize -FR_RAMCodeAddr * FR_StackBase -FR_ScreenBase * (FR_RAMCodeAddr+FR_RAMCodeSize+15):AND::NOT:&F -FR_TransferBuffAddr * FR_ScreenBase - -; Combo chip addresses -FR_ComboCfgBase * &03010000 + &3F0*4 -FR_PPortBase * &03010000 + &278*4 -FR_ECRPortBase * FR_PPortBase + &402*4 - - -; On entry, R11->IOMD -; Will either reprogram the flash, or branch back to 0. -; We're in SVC32 mode with the MMU off, by the way. - - ASSERT IOMD_C_FrontPanelButton <> 0 -ConsiderFlashROM - LDRB R0,[R11,#IOMD_CLINES] - TST R0,#IOMD_C_FrontPanelButton - MOVNE PC,#0 - -FlashROM -; Switch CPU to 32-bit mode - MOV R0,#MMUC_L :OR: MMUC_D :OR: MMUC_P ; Set PROG32 and DATA32 - ARM_write_control R0 - msr ,CPSR_c,#I32_bit :OR: F32_bit :OR: SVC32_mode - -; Initialise various CPU control registers - MOV R0,#IOMD_ROMCR_NSTicks_5 :OR: IOMD_ROMCR_HalfSpeed :OR: IOMD_ROMCR_32bit - STRB R0,[R11,#IOMD_ROMCR0] - MOV R0,#IOMD_CLKCTL_CpuclkHalf :OR: IOMD_CLKCTL_MemclkNormal :OR: IOMD_CLKCTL_IOclkNormal - STRB R0,[R11,#IOMD_CLKCTL] - MOV R0,#IOMD_DRAMWID_RASPre_3 :OR: IOMD_DRAMWID_RASCAS_3 :OR: IOMD_DRAMWID_EDO_Enable :OR: IOMD_DRAMWID_DRAM_32bit - STRB R0,[R11,#IOMD_DRAMWID] - MOV R0,#IOMD_IOTCR_Combo_TypeB :OR: IOMD_IOTCR_Network_TypeC - STRB R0,[R11,#IOMD_IOTCR] - MOV R0,#1 ; Card 0 type C, the rest type A - STRB R0,[R11,#IOMD_ECTCR] - MOV R0,#IOMD_ASTCR_WaitStates - STRB R0,[R11,#IOMD_ASTCR] - MOV R0,#IOMD_C_ReadMask :OR: IOMD_C_ROMCardVpp ; Green LED on - STRB R0,[R11,#IOMD_CLINES] - -; Main setup - MOV R10,#VIDC ; Keep R10 pointing to video registers from here on - BL FR_InitVideo - BL FR_FillScreen - BL FR_SetPageTable - BL FR_SetMMU - BL FR_InitParallel ; Sets R9 to parallel base address - keep it this way - -; Copy the rest of code to RAM and jump to it - ADR R0,FR_CopyBlockStart - LDR R1,=FR_RAMCodeAddr - MOV LR,R1 - LDR R2,=FR_RAMCodeEnd - FR_CopyBlockStart -01 LDR R3,[R0],#4 - STR R3,[R1],#4 - SUBS R2,R2,#4 - BNE %BT01 - MOV PC,LR - -FR_InitVideo ROUT -; Set DMA registers - LDR R1,=FR_ScreenBase - ADD R2,R1,#FR_ScreenSize - SUB R2,R2,#16 - STR R1,[R11,#IOMD_VIDSTART] - STR R2,[R11,#IOMD_VIDEND] - STR R1,[R11,#IOMD_VIDINIT] - STR R1,[R11,#IOMD_VIDCUR] - STR R1,[R11,#IOMD_CURSINIT] - STR R1,[R11,#IOMD_CURSCUR] - MOV R1,#0 - STR R1,[R11,#IOMD_VIDINITB] - MOV R1,#IOMD_VIDCR_DRAMMode :OR: IOMD_VIDCR_Enable - STRB R1,[R11,#IOMD_VIDCR] -; Set video registers - ADR R1,FR_InitVidRegs - MOV R2,#(FR_InitVidRegsEnd-FR_InitVidRegs) -02 LDR R3,[R1],#4 - STR R3,[R10] - SUBS R2,R2,#4 - BNE %BT02 -; Set grey palette - MOV R1,#&10000000 - STR R1,[R10] - MOV R1,#0 - MOV R2,#&000001 - ORR R2,R2,#&000100 - ORR R2,R2,#&010000 - MOV R3,#256 -03 STR R1,[R10] - ADD R1,R1,R2 - SUBS R3,R3,#1 - BNE %BT03 - MOV PC,LR - -; Frequency synthesizer register settings -FR_ModR * 8 -FR_ModV * 9 ; 36 MHz -; Video control register settings -FR_FIFO * 3 ; 12 loads -FR_BPP * 3 ; 8bpp -FR_PixelRate * 0 ; CK/1 -FR_ClockSource * 0 ; VCLK -; Horizontal timings -FR_HSync * 72 -FR_HBPch * 86 -FR_HLBdr * 24 -FR_HDisp * 800 -FR_HRBdr * 24 -FR_HFPch * 18 -FR_HDWR * FR_HDisp / 4 -; Vertical timings -FR_VSync * 2 -FR_VBPch * 22 -FR_VTBdr * 0 -FR_VDisp * 600 -FR_VBBdr * 0 -FR_VFPch * 1 - -FR_InitVidRegs ROUT - DCD &E0000000+(FR_FIFO:SHL:8)+(FR_BPP:SHL:5)+(FR_PixelRate:SHL:2)+FR_ClockSource - DCD &D0000000+&C288 - DCD &80000000+FR_HSync+FR_HBPch+FR_HLBdr+FR_HDisp+FR_HRBdr+FR_HFPch-8 - DCD &81000000+FR_HSync-8 - DCD &82000000+FR_HSync+FR_HBPch-12 - DCD &83000000+FR_HSync+FR_HBPch+FR_HLBdr-18 - DCD &84000000+FR_HSync+FR_HBPch+FR_HLBdr+FR_HDisp-18 - DCD &85000000+FR_HSync+FR_HBPch+FR_HLBdr+FR_HDisp+FR_HRBdr-12 - DCD &90000000+FR_VSync+FR_VBPch+FR_VTBdr+FR_VDisp+FR_VBBdr+FR_VFPch-2 - DCD &91000000+FR_VSync-2 - DCD &92000000+FR_VSync+FR_VBPch-1 - DCD &93000000+FR_VSync+FR_VBPch+FR_VTBdr-1 - DCD &94000000+FR_VSync+FR_VBPch+FR_VTBdr+FR_VDisp-1 - DCD &95000000+FR_VSync+FR_VBPch+FR_VTBdr+FR_VDisp+FR_VBBdr-1 - DCD &40008000 - DCD &C0000000+(1:SHL:12)+3 - DCD &D0000000+&C080+((FR_ModV-1):SHL:8)+(FR_ModR-1) - DCD &D0000000+((FR_ModV-1):SHL:8)+(FR_ModR-1) - DCD &F0000000+(1:SHL:16)+(1:SHL:12)+FR_HDWR - DCD &B1000000 -FR_InitVidRegsEnd - -FR_FillScreen ROUT - LDR R1,=FR_ScreenBase - MOV R2,#((256:SHL:16)/600):AND:&00FF - ORR R2,R2,#((256:SHL:16)/600):AND:&FF00 - MOV R3,R2 - MOV R4,#FR_VDisp -01 MOV R5,#FR_HDisp - MOV R0,R3,LSR #16 - ORR R0,R0,R0,LSL #8 - ORR R0,R0,R0,LSL #16 -02 STR R0,[R1],#4 - SUBS R5,R5,#4 - BNE %BT02 - ADD R3,R3,R2 - SUBS R4,R4,#1 - BNE %BT01 - MOV PC,LR - -;Make a page table that basically gives flat addressing with the C and B bits -;set approriately for the RAM areas. The RAM areas are set with both the C and B -;bits on, and all other areas have both C and B off. The flash area must not -;be made cacheable, or programming won't work. -;On exit -; r0-r4 corrupted -FR_SetPageTable ROUT - MOV R1,#FR_PageTableBaseAddr - MOV R2,#0 ; Address - MOV R4,#L1_U + L1_Section - ORR R4,R4,#AP_Full * L1_APMult -01 BICS R3,R2,#&E0000000 ; Repeats at &00000000, &20000000, &4000000, etc. - BICEQ R4,R4,#L1_C + L1_B ; Clear B and C bits from start of ROM area - CMP R3,#&10000000 - ORREQ R4,R4,#L1_C + L1_B ; Set B and C bits (RAM area cacheable and bufferable) - ORR R0,R3,R4 - STR R0,[R1],#4 - ADDS R2,R2,#1024*1024 - BCC %BT01 - MOV PC,LR - -FR_SetMMU ROUT - MOV R0,#FR_PageTableBaseAddr - ARM_MMU_transbase R0 - MVN R0,#0 ; Full access to all domains - ARM_MMU_domain R0 - MOV R0,#MMUC_L + MMUC_D + MMUC_P + MMUC_W + MMUC_C + MMUC_M - ARM_write_control R0 ; Enable write buffer, cache and MMU - MOV PC,LR - -FR_InitParallel ROUT - LDR R1,=FR_ComboCfgBase -; Enter config mode - MOV R0,#&55 - STRB R0,[R1] - STRB R0,[R1] -; Write CR0 - MOV R0,#0 - STRB R0,[R1] - MOV R0,#&22 - STRB R0,[R1,#4] ; CR0=&22 (FDC, IDE off) -; Write CR1 - MOV R0,#1 - STRB R0,[R1] - MOV R0,#&97 - STRB R0,[R1,#4] ; CR1=&97 (Parallel port on, extended) -; Write CR4 - MOV R0,#4 - STRB R0,[R1] - MOV R0,#&03 ; CR4=&03 (ECP & EPP mode) - STRB R0,[R1,#4] -; Write ECR - MOV R0,#&34 ; PS/2 Parallel Port mode, DMA off, interrupts off - LDR R9,=FR_ECRPortBase - STRB R0,[R9] -; Exit config mode - MOV R0,#&AA - STRB R0,[R1] -; Initialise parallel port - LDR R9,=FR_PPortBase -; Clear nSTROBE bit (puts nACK high) and clear nSLCTIN bit (puts BUSY high) to -; indicate we are busy and not accepting data. - MOV R0,#&20 ; Input, IRQ off, nSLCTIN clear, nSTROBE clear - STRB R0,[R9,#8] -; Keep parallel port base address in R9 from here on - MOV PC,LR - - LTORG - -FR_CopyBlockStart - -; Dont use literals from here on in - the assembler's liable to pull them -; the non-RAM stuff above. - -; Code from here on gets copied to RAM (at FR_RAMCodeAddr) and run from there. - -FR_RAMCodeStart - MOV R0,#IOMD_C_ReadMask :OR: IOMD_C_FrontPanelLED :OR: IOMD_C_ROMCardVpp - STRB R0,[R11,#IOMD_CLINES] ; Red LED on - LDR R13,FR_StackBaseVal -FR_LoopForever - MOV R0,#FR_WaitCmdState-FR_BorderStateTable - BL FR_ShowStateBorder -; Wait for a command header - BL FR_ParallelRead - CMP R0,#'M' - BNE FR_LoopForever - BL FR_ParallelRead - CMP R0,#'P' - BNE FR_LoopForever - BL FR_ParallelRead - CMP R0,#'T' - BNE FR_LoopForever - BL FR_ParallelRead - CMP R0,#'!' - BNE FR_LoopForever - BL FR_ParallelRead - CMP R0,#'P' - BEQ FR_BeginProgram - CMP R0,#'V' - BEQ FR_BeginVerify - B FR_LoopForever - -FR_BeginProgram ROUT - MOV R0,#FR_BeginProgramState-FR_BorderStateTable - BL FR_ShowStateBorder -; Read in parameters - BL FR_ReadOffsetAndCount -; Ready to go - first make the ROM area writable - BL FR_MakeROM0Writable -01 -; Begin erasing the block - MOV R0,R7 - BL FR_StartErase -; Read the block data into the buffer - BL FR_ReadBlockIntoBuffer -; Data read in OK - wait for erase to finish - BL FR_CheckErase -; Now write block - MOV R0,#FR_WriteBlockState-FR_BorderStateTable - BL FR_ShowStateBorder - MOV R0,R7 - LDR R1,FR_TransferBuffVal - BL FR_DoWriteBlock -; Verify the block - BL FR_ResetToReadArray - MOV R0,#FR_VerifyBlockState-FR_BorderStateTable - BL FR_ShowStateBorder - MOV R0,R7 - LDR R1,FR_TransferBuffVal - BL FR_VerifyBlock -; Block done, on to the next - ADD R7,R7,#FR_BlockSize - SUBS R8,R8,#1 - BNE %BT01 -; All finished - make ROM area read-only - BL FR_MakeROM0ReadOnly - B FR_LoopForever - -FR_BeginVerify ROUT - MOV R0,#FR_BeginVerifyState-FR_BorderStateTable - BL FR_ShowStateBorder -; Read in parameters - BL FR_ReadOffsetAndCount -01 -; Read the block data into the buffer - BL FR_ReadBlockIntoBuffer -; Data read in OK - now verify - MOV R0,#FR_VerifyBlockState-FR_BorderStateTable - BL FR_ShowStateBorder - MOV R0,R7 - LDR R1,FR_TransferBuffVal - BL FR_VerifyBlock -; Block done, on to the next - ADD R7,R7,#FR_BlockSize - SUBS R8,R8,#1 - BNE %BT01 -; All done - B FR_LoopForever - -FR_ReadOffsetAndCount ROUT -;Called by the program and verify commands to read their parameters (offset -;and count) from the parallel port. -;On exit -; r7 = Initial offset in Flash ROM area -; r8 = Block count -; r0-r3 corrupted - STMFD R13!,{LR} -; Next incoming word is the block offset to start from - BL FR_ParallelReadWord - MOV R7,R0 -; Check the offset is valid - CMP R7,#FR_FlashSize - BHS FR_OffsetError - MOVS R0,R7,LSL#(32-FR_BlockSizeBits) ; The offset within the block should be 0 - BNE FR_OffsetError -; Next incoming byte is the number of blocks - BL FR_ParallelRead - MOVS R8,R0 - BEQ FR_BlockCountError - ADD R0,R7,R8,LSL #FR_BlockSizeBits - CMP R0,#FR_FlashSize - BHI FR_BlockCountError -; Turn the offset into a real address - ADD R7,R7,#FR_FlashBase - LDMFD R13!,{PC} - -FR_ReadBlockIntoBuffer ROUT -;Read a block of data from the parallel port into the transfer buffer -;Corrupts r0-r6 - STMFD R13!,{LR} - MOV R0,#FR_ReadBlockState-FR_BorderStateTable - BL FR_ShowStateBorder - MOV R6,#FR_BlockSize - LDR R5,FR_TransferBuffVal - MOV R4,#0 ; Checksum -01 BL FR_ParallelReadWord - STR R0,[R5],#4 - ADD R4,R4,R0 - SUBS R6,R6,#4 - BNE %BT01 -; Next word is the checksum - BL FR_ParallelReadWord - CMP R0,R4 - BNE FR_ChecksumError - LDMFD R13!,{PC} - -FR_ChecksumError ROUT - MOV R0,#FR_ChecksumErrorState-FR_BorderStateTable - B FR_Error -FR_OffsetError - MOV R0,#FR_OffsetErrorState-FR_BorderStateTable - B FR_Error -FR_BlockCountError - MOV R0,#FR_BlockCountErrorState-FR_BorderStateTable -FR_Error - BL FR_ShowStateBorder -; Wait for front panel button to be pressed -01 LDRB R0,[R11,#IOMD_CLINES] - TST R0,#IOMD_C_FrontPanelButton - BNE %BT01 -; Start again (note this also resets the stack pointer) - B FR_RAMCodeStart - -FR_ShowStateBorder - STMFD R13!,{R1} - ADR R1,FR_BorderStateTable - LDR R0,[R1,R0] - STR R0,[R10] - LDMFD R13!,{R1} - MOV PC,LR - -FR_BorderStateTable -FR_WaitCmdState DCD &40FF0000 ;Waiting for command - Blue -FR_BeginProgramState DCD &40808080 ;Begin Program command - Grey -FR_BeginVerifyState DCD &40404040 ;Begin Verify command - Dark grey -FR_ReadBlockState DCD &40FFFF00 ;Reading block - Cyan -FR_WriteBlockState DCD &4000FF00 ;Writing block - Green -FR_VerifyBlockState DCD &40FFFFFF ;Verifying block - White -FR_OffsetErrorState DCD &400000FF ;Offset error - Red -FR_BlockCountErrorState DCD &4000FFFF ;Block count error - Yellow -FR_ChecksumErrorState DCD &40FF00FF ;Checksum error - Magenta -FR_EraseErrorState DCD &40808000 ;Erase error - Dark Cyan -FR_VoltageRangeErrorState DCD &40000080 ;Voltage range error - Dark Red -FR_DeviceProtectErrorState DCD &40800000 ;Device protect error - Dark Blue -FR_ProgramErrorState DCD &40008080 ;Program error - Dark Yellow -FR_VerifyErrorState DCD &4000BBFF ;Verify error - Orange - -FR_ParallelRead ROUT -;Read a byte of data from the parallel port -;On entry -; r9 = Parallel port base address -;On exit -; r0 = byte read -; r1 corrupted -;Set nSLCTIN bit (puts BUSY low) and clear nSTROBE bit (puts nACK high), -;to indicate that we are ready to receive data - MOV R0,#&28 ; Input, IRQ off, BUSY low, nACK high - STRB R0,[R9,#8] -;Now wait until nACK bit (nSTROBE) goes low, meaning a byte is ready to be read -01 LDRB R0,[R9,#4] - TST R0,#&40 - BNE %BT01 -;Read the byte - LDRB R0,[R9] -;Set nSTROBE bit (puts nACK low) to indicate we read the byte, and -;clear nSLCTIN bit (puts BUSY high) to indicate we are busy and won't accept -;any more data - MOV R1,#&21 ; Input, IRQ off, BUSY high, nACK low - STRB R1,[R9,#8] -;Make sure nACK bit (nSTROBE) has returned high -02 LDRB R1,[R9,#4] - TST R1,#&40 - BEQ %BT02 -;Finish nAck pulse by clearing nSTROBE bit (puts nACK high). Keep BUSY high - MOV R1,#&20 ; Input, IRQ off, BUSY high, nACK high - STRB R1,[R9,#8] - MOV pc,lr - -FR_ParallelReadWord ROUT -;Read a word of data from the parallel port -;On entry -; r9 = Parallel port base address -;On exit -; r0 = word read -; r1-r3 corrupted - MOV R3,LR - BL FR_ParallelRead - MOV R2,R0 - BL FR_ParallelRead - ORR R2,R2,R0,LSL #8 - BL FR_ParallelRead - ORR R2,R2,R0,LSL #16 - BL FR_ParallelRead - ORR R0,R2,R0,LSL #24 - MOV PC,R3 - -FR_MakeROM0Writable - STMFD R13!,{R0} - LDRB R0,[R11,#IOMD_ROMCR0] - ORR R0,R0,#&80 - STRB R0,[R11,#IOMD_ROMCR0] - LDMFD R13!,{R0} - MOV PC,LR - -FR_MakeROM0ReadOnly - STMFD R13!,{R0} - LDRB R0,[R11,#IOMD_ROMCR0] - BIC R0,R0,#&80 - STRB R0,[R11,#IOMD_ROMCR0] - LDMFD R13!,{R0} - MOV PC,LR - -FR_ResetToReadArray ROUT -;Reset the flash devices to Read Array mode - STMFD R13!,{R0,R1} - MOV R0,#FR_FlashBase - MOV R1,#&FF - ORR R1,R1,R1,LSL #8 - STR R1,[R0] ; Write the Read Array command (&FF) to both devices - LDMFD R13,{R0,R1} - MOV PC,LR - -FR_StartErase ROUT -;Start to erase a block (256KB) of flash memory -;On entry -; r0=Block Address (real memory address) - STMFD R13!,{R1} - MOV R1,#&20 - ORR R1,R1,R1,LSL #8 - STR R1,[R0] ; Write the Block Erase command (&20) to both devices - MOV R1,#&D0 - ORR R1,R1,R1,LSL #8 - STR R1,[R0] ; Write the Confirm command (&D0) to both devices - LDMFD R13!,{R1} - MOV PC,LR - -FR_CheckErase ROUT -;Wait for erase to finish - STMFD R13!,{R0,R1} - MOV R0,#FR_FlashBase -01 LDR R1,[R0] ; Read the status register - TST R1,#&0080 ; Check even SR.7 - TSTNE R1,#&8000 ; Check odd SR.7 - BEQ %BT01 ; Repeat until both set - TST R1,#&0020 ; Check even SR.5 - TSTEQ R1,#&2000 ; Check odd SR.5 - BNE FR_ceEraseError - LDMFD R13!,{R0,R1} - MOV PC,LR -FR_ceEraseError - MOV R1,#&50 - ORR R1,R1,R1,LSL #8 - STR R1,[R0] ; Write Clear Status Register command (&50) to beth devices - BL FR_ResetToReadArray - BL FR_MakeROM0ReadOnly - LDMFD R13!,{R0,R1} - MOV R0,#FR_EraseErrorState-FR_BorderStateTable - B FR_Error - -FR_DoWriteBlock ROUT -;Writes a block (256KB) of data to flash memory -;On entry -; r0=Block Address (real memory address) -; r1=Pointer to data to write -;On exit -; r0,r1 have advanced by the block size (256KB) - STMFD R13!,{R2,R3,LR} - MOV R2,R1 - MOV R1,R0 - MOV R3,#FR_BlockSize -01 BL FR_DoWriteBuffer - SUBS R3,R3,#FR_BufferSize - BNE %BT01 - MOV R0,R1 - MOV R1,R2 - LDMFD R13!,{R2,R3,PC} - -FR_DoWriteBuffer ROUT -;Write a buffer full of data (64 bytes) to flash memory -;On entry -; r0=Block Address -; r1=Start Address -; r2=Pointer to data to write -;On exit -; r0 preserved -; r1,r2 have increased by 64 bytes - STMFD R13!,{R3,R4,LR} - MOV R3,#&E8 - ORR R3,R3,R3,LSL #8 -01 STR R3,[R0] ; Write the Write to Buffer command (&E8) to both devices - LDR R4,[R0] ; Read the XSR - TST R4,#&0080 ; Check even XSR.7 - TSTNE R4,#&8000 ; Check odd XSR.7 - BEQ %BT01 ; Repeat until both set - MOV R3,#(FR_DeviceBufferSize:SHR:1)-1 ; No. of (16-bit) words to write - 1 - ORR R3,R3,R3,LSL #8 - STR R3,[R0] ; Write the (16-bit) word count to both devices - MOV R3,#FR_BufferSize -02 LDR R4,[R2],#4 - STR R4,[R1],#4 ; Write a (16-bit) word of data to each device - SUBS R3,R3,#4 - BNE %BT02 - MOV R3,#&D0 - ORR R3,R3,R3,LSL #8 - STR R3,[R0] ; Write the Confirm command (&D0) to both devices -03 LDR R4,[R0] ; Read the status register - TST R4,#&0080 ; Check even SR.7 - TSTNE R4,#&8000 ; Check odd SR.7 - BEQ %BT03 ; Repeat until both set - TST R4,#&0008 ; Check even SR.3 - TSTEQ R4,#&0800 ; Check odd SR.3 - BNE FR_dwbfVoltageRangeError - TST R4,#&0002 ; Check even SR.1 - TSTEQ R4,#&0200 ; Check odd SR.1 - BNE FR_dwbfDeviceProtectError - TST R4,#&0010 ; Check even SR.4 - TSTEQ R4,#&1000 ; Check odd SR.4 - BNE FR_dwbfProgramError -; Programming completed successfully - LDMFD R13!,{R3,R4,PC} - -FR_dwbfVoltageRangeError - MOV R0,#FR_VoltageRangeErrorState-FR_BorderStateTable - B FR_dwbfErrorExit -FR_dwbfDeviceProtectError - MOV R0,#FR_DeviceProtectErrorState-FR_BorderStateTable - B FR_dwbfErrorExit -FR_dwbfProgramError - MOV R0,#FR_ProgramErrorState-FR_BorderStateTable -FR_dwbfErrorExit - MOV R3,#&50 - ORR R3,R3,R3,LSL #8 - MOV R4,#FR_FlashBase - STR R1,[R4] ; Write Clear Status Register command (&50) to beth devices - BL FR_ResetToReadArray - BL FR_MakeROM0ReadOnly - LDMFD R13!,{R3,R4,LR} - B FR_Error - -FR_VerifyBlock ROUT -;Compare a block (256KB) of data to flash memory -;On entry -; r0=Block Address (real memory address) -; r1=Pointer to block to compare -;On exit -; r0,r1 have advanced by the block size (256KB) - STMFD R13!,{R2-R4} - MOV R2,#FR_BlockSize -01 LDR R3,[R0],#4 - LDR R4,[R1],#4 - CMP R3,R4 - BNE FR_VerifyError - SUBS R2,R2,#4 - BNE %BT01 - LDMFD R13!,{R2-R4} - MOV PC,LR -FR_VerifyError - MOV R0,#FR_VerifyErrorState-FR_BorderStateTable - B FR_Error - -FR_StackBaseVal & FR_StackBase -FR_TransferBuffVal & FR_TransferBuffAddr - -FR_RAMCodeEnd - - END diff --git a/s/GetAll b/s/GetAll deleted file mode 100644 index 0cd9bdc6..00000000 --- a/s/GetAll +++ /dev/null @@ -1,205 +0,0 @@ -; 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. -; -; > GetAll - - GET Hdr:ListOpts - GET Hdr:Macros - GET Hdr:System - GET Hdr:Machine.<Machine> - GET Hdr:ImageSize.<ImageSize> - GET Hdr:UserIF.<UserIF> - $GetCPU - $GetIO - $GetMEMC - $GetMEMM - $GetVIDC - - GET hdr.Options - -; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; now get the headers -; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - GBLL ShowWS -ShowWS SETL {TRUE} ; Make KernelWS be verbose - - GET Hdr:CMOS - GET Hdr:Heap - GET Hdr:PublicWS - GET Hdr:KernelWS - GET Hdr:HALEntries - GET Hdr:HALDevice - GET Hdr:OSEntries - GET Hdr:Services - GET Hdr:FSNumbers - GET Hdr:HighFSI - GET Hdr:NewErrors - GET Hdr:Proc - GET Hdr:Sprite - GET Hdr:KeyWS - GET Hdr:RS423 - GET Hdr:ModHand - GET Hdr:Variables - GET Hdr:EnvNumbers - GET Hdr:UpCall - GET Hdr:Sound - GET Hdr:Pointer - GET Hdr:Podule - GET Hdr:VduExt - GET Hdr:Buffer - GET Hdr:Font - GET Hdr:DevNos - GET Hdr:Territory - GET Hdr:Portable - GET Hdr:MsgTrans - GET Hdr:PaletteV - GET Hdr:GraphicsV - GET Hdr:Wimp - GET Hdr:ColourTran - GET Hdr:Debug - GET Hdr:nvram - GET Hdr:PortMan - GET s.PMF.DEF ; Common with 6502 code in the keyboard - Protocol - -; now the main parts of the MOS - -; IMPORT EndOfKernel - - GET hdr.Copro15ops ; some macros - GET hdr.ARMops - - GET s.Kernel - $GetFlashROM - GET s.ARMops - GET s.NewIRQs - GET s.Oscli - GET s.SysComms - GET s.HeapMan - GET s.ModHand - $GetUnsqueeze - GET s.ArthurSWIs - GET s.ChangeDyn - $GetHAL - GET s.Arthur2 - GET s.LibKern - GET s.Utility - GET s.MoreComms - GET s.Convrsions - GET s.MoreSWIs - GET s.ExtraSWIs - GET s.HeapSort - GET s.Arthur3 - GET s.SWINaming - GET s.TickEvents - $GetKbdRes - GET s.NewReset - $GetMessages - GET s.Middle - GET s.Super1 - $GetKernelMEMC - $GetMemInfo - ! 0, "Main kernel size = &" :CC: :STR: (.-KernelBase) -StartOfVduDriver - GET s.vdu.vduhint - GET s.vdu.VduDriver - GET s.vdu.VduSWIs - GET s.vdu.VduPalette - $GetPalette - GET s.vdu.VduPlot - GET s.vdu.VduGrafA - GET s.vdu.VduGrafB - GET s.vdu.VduGrafC - GET s.vdu.VduGrafD - GET s.vdu.VduGrafE - GET s.vdu.VduGrafF - GET s.vdu.VduGrafG - GET s.vdu.VduGrafH - GET s.vdu.VduGrafI - GET s.vdu.VduGrafJ - GET s.vdu.VduGrafK - GET s.vdu.VduGrafL - GET s.vdu.VduGrafV - GET s.vdu.VduWrch - GET s.vdu.Vdu23 - GET s.vdu.VduPointer - GET s.vdu.Vdu5 - GET s.vdu.VduCurSoft - GET s.vdu.VduTTX - - GBLS GiveMeBfontAnyDay - [ BleedinDaveBell -GiveMeBfontAnyDay SETS "GET s.vdu.VduFontL1" - | -GiveMeBfontAnyDay SETS "GET s.vdu.VduFont" - ] - - $GiveMeBfontAnyDay - - ! 0, "Vdu drivers size = &" :CC: :STR: (.-StartOfVduDriver) - -StartOfPMF - GET s.PMF.osinit - GET s.PMF.oseven - GET s.PMF.osbyte - GET s.PMF.osword - GET s.PMF.realtime - GET s.PMF.convdate - GET s.PMF.i2cutils - GET s.PMF.IIC - GET s.PMF.oswrch - GET s.PMF.buffer - $GetKbdDrA1 - GET s.PMF.key - GET s.PMF.mouse - ALIGN -EndOfPMF - - ! 0, "PMF section size = &" :CC: :STR: (EndOfPMF - StartOfPMF) - - [ {FALSE} -StartOfAMB_beforealign - ALIGN 4096 ;align to 4k page boundary, for easy ROMpatch - ] - -StartOfAMB - GET s.AMBControl.AMB -EndOfAMB - - ! 0, "AMB section size = &" :CC: :STR: (EndOfAMB - StartOfAMB) - -; ALIGN 65536 -EndOfKernel - DCD 0 - - [ med_00001_debug - ! 0,"" - ! 0,",-----------------------------------------------------------------," - ! 0,"| **** WARNING **** |" - ! 0,"| |" - ! 0,"| Audit trail debugging for MED-00001 is enabled. This reuses the |" - ! 0,"| first three words of OldIRQ1Vspace. This should be turned off |" - ! 0,"| once MED-00001 has been tested and marked 'fixed'. |" - ! 0,"| |" - ! 0,"| Usage: |" - ! 0,"| +0 start of area used by flood fill |" - ! 0,"| +4 end+1 of area used by flood fill |" - ! 0,"| +8 amount the rma was grown by |" - ! 0,"'-----------------------------------------------------------------'" - ! 0,"" - ] - - - END diff --git a/s/HAL b/s/HAL deleted file mode 100644 index 2836f646..00000000 --- a/s/HAL +++ /dev/null @@ -1,2154 +0,0 @@ -; Copyright 2000 Pace Micro Technology plc -; -; 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. -; - GBLL MinorL2PThack -MinorL2PThack SETL {TRUE} - -; Fixed page allocation is as follows - - ^ 0 -DRAMOffset_FirstFixed # 0 -DRAMOffset_ScratchSpace # 16*1024 -DRAMOffset_PageZero # 16*1024 -DRAMOffset_L1PT # 16*1024 ; L1PT must be 16K-aligned -DRAMOffset_LastFixed # 0 - -; IMPORT Init_ARMarch -; IMPORT ARM_Analyse - - - -; void RISCOS_InitARM(unsigned int flags) -; -RISCOS_InitARM - MOV a4, lr - ; Check if we're architecture 3. If so, don't read the control register. - BL Init_ARMarch - MOVEQ a1, #0 - ARM_read_control a1, NE - ; Late abort (ARM6 only), 32-bit Data and Program space. No Write buffer (ARM920T - ; spec says W bit should be set, but I reckon they're bluffing). - ; - ; The F bit's tricky. (1 => CPCLK=FCLK, 0=>CPCLK=FCLK/2). The only chip using it was the - ; ARM700, it never really reached the customer, and it's always been programmed with - ; CPCLK=FCLK. Therefore we'll keep it that way, and ignore the layering violation. - ORR a1, a1, #MMUC_F+MMUC_L+MMUC_D+MMUC_P - ; All of these bits should be off already, but just in case... - BIC a1, a1, #MMUC_B+MMUC_W+MMUC_C+MMUC_A+MMUC_M - BIC a1, a1, #MMUC_RR+MMUC_V+MMUC_I+MMUC_Z+MMUC_R+MMUC_S - - ; Off we go. - ARM_write_control a1 - - ; In case it wasn't a hard reset - MOV a2, #0 - MCR ARM_config_cp,0,a2,ARMv4_cache_reg,C7 ; invalidate I+D caches - MCREQ ARM_config_cp,0,a2,ARMv3_TLBflush_reg,C0 ; flush TLBs - MCRNE ARM_config_cp,0,a2,ARMv4_TLB_reg,C7 ; flush TLBs - - ; We assume that ARMs with an I cache can have it enabled while the MMU is off. - [ :LNOT:CacheOff - ORRNE a1, a1, #MMUC_I - ARM_write_control a1, NE ; whoosh - ] - - ; Check if we are in a 26-bit mode. - MRS a2, CPSR - ; Keep a soft copy of the CR in a banked register (R13_und) - MSR CPSR_c, #F32_bit+I32_bit+UND32_mode - MOV sp, a1 - ; Switch into SVC32 mode (we may have been in SVC26 before). - MSR CPSR_c, #F32_bit+I32_bit+SVC32_mode - - ; If we were in a 26-bit mode, the lr value given to us would have had PSR flags in. - TST a2, #2_11100 - MOVNE pc, a4 - BICEQ pc, a4, #ARM_CC_Mask - - -; void *RISCOS_AddRAM(unsigned int flags, void *start, void *end, uintptr_t sigbits, void *ref) -; Entry: -; flags bit 0: video memory (currently only one block permitted) -; bit 1: video memory is not suitable for general use -; bits 8-11: speed indicator (arbitrary, higher => faster) -; other bits reserved (SBZ) -; start = start address of RAM (inclusive) (no alignment requirements) -; end = end address of RAM (exclusive) (no alignment requirements, but must be >= start) -; sigbits = significant address bit mask (1 => this bit of addr decoded, 0 => this bit ignored) -; ref = reference handle (NULL for first call) - -; A table is built up at the head of the first block of memory. -; The table consists of (addr, len, flags) pairs, terminated by a count of those pairs; ref points to that -; counter. -; Twelve bits of flags are stored at the bottom of the length word. - - ROUT -RISCOS_AddRAM - Push "v1,v2,v3,v4,lr" - LDR v4, [sp, #20] ; Get ref - - ; Round to pages. If we were extra sneaky we could not do this and chuck out incomplete - ; pages after concatanation, but it would be a weird HAL that gave us pages split across - ; calls. - ; - ADD a2, a2, #4096 ; round start address up - SUB a2, a2, #1 - MOV a2, a2, LSR #12 - MOV a2, a2, LSL #12 - MOV a3, a3, LSR #12 ; round end address down - MOV a3, a3, LSL #12 - - CMP a3, a2 - BLS %FT90 ; check we aren't now null - - CMP v4, #0 - BEQ %FT20 - - ; We are not dealing with the first block since v4 != 0. Make an attempt to merge this block - ; with the previous block. - LDMDB v4, {v1, v2} ; Get details of the previous block - MOV v3, v2, LSL #20 ; Isolate flags - BIC v2, v2, v3, LSR #20 ; And strip from length - ADD v2, v1, v2 ; Get the end address - EOR v2, v2, a2 ; Compare with the current block start address... - TST v2, a4 ; ... but only check the decoded bits. - EOR v2, v2, a2 ; Restore the previous block end address. - TEQEQ v3, a1, LSL #20 ; And are the page flags the same? - BNE %FT10 ; We can't merge it after the previous block - - ; v1 = previous start - ; v2 = previous end - ; The block is just after the previous block. That means the start address is unchanged, but - ; the length is increased. - SUB v2, v2, v1 ; Calculate the previous block length. - SUB a3, a3, a2 ; Find the length of the new block. - ; a3 = length of block - ADD v2, v2, a3 ; Add it to the previous length. - ORR v2, v2, v3, LSR #20 ; And put the flags back in. - STR v2, [v4, #-4] ; Update the block size in memory. - MOV a1,v4 - Pull "v1,v2,v3,v4,pc" - - ; The block is not just after the previous block, but it may be just before. This may be the - ; case if we are softloaded. -10 SUB v1, v1, #1 ; Compare the address before the previous block start ... - SUB a3, a3, #1 ; ... with the address of the last byte in this block ... - EOR v1, v1, a3 - TST v1, a4 ; ... but check only the decoded bits. - ADD a3, a3, #1 ; Restore the end address. - TEQEQ v3, a1, LSL #20 ; And are the page flags the same? - BNE %FT20 ; Skip if we cannot merge the block. - - ; The block is just before the previous block. The start address and length both change. - LDR v1, [v4, #-8] ; Get the previous block start again. - - SUB a3, a3, a2 ; Calculate the current block size. - SUB v1, v1, a3 ; Subtract from the previous block start address. - SUB v2, v2, v1 ; Calculate the new length=end-start - ORR v2, v2, v3, LSR #20 ; And put the flags back in. - STMDB v4, {v1, v2} ; Update the block info in memory. - MOV a1,v4 - Pull "v1,v2,v3,v4,pc" - - ; We now have a region which does not merge with a previous region. We move it up to the - ; highest address we can in the hope that this block will merge with the next block. -20 SUB a3, a3, a2 ; Calculate the block size - MOV a1, a1, LSL #20 - ORR a3, a3, a1, LSR #20 ; Put the flags at the bottom - MVN v1, a4 ; Get the non-decoded address lines. - ORR a2, v1, a2 ; Set the non-decoded address bit in the start address. - -30 CMP v4, #0 ; If the workspace has not been allocated... - MOVEQ v4, a2 ; ... use this block. - MOVEQ v1, #0 ; Initialise the counter. - - ; The block/fragment to be added is between a2 and a2+a3. - LDRNE v1, [v4] ; Get the old counter if there was one. - STMIA v4!, {a2, a3} ; Store address and size. - ADD v1, v1, #1 ; Increment the counter. - STR v1, [v4] ; Store the counter. - -90 MOV a1,v4 - Pull "v1,v2,v3,v4,pc" ; We've done with this block now. - - - -; Subtractv1v2fromRAMtable -; -; On entry: v1 = base of memory area -; v2 = size of memory area -; a4 = RAM table handle (ie pointer to terminator word containing number of entries) -; -; On exit: a1-a3 preserved -; a4 and RAM table updated -; other registers corrupted -Subtractv1v2fromRAMtable - ADD v2, v1, v2 ; v2 = end address - MOV v1, v1, LSR #12 - MOV v1, v1, LSL #12 ; round base down - ADD v2, v2, #4096 - SUB v2, v2, #1 - MOV v2, v2, LSR #12 - MOV v2, v2, LSL #12 ; round end up - - LDR v5, [a4] - SUB v8, a4, v5, LSL #3 -10 TEQ v8, a4 - MOVEQ pc, lr - LDMIA v8!, {v3, v4} - MOV v6, v4, LSR #12 - ADD v6, v3, v6, LSL #12 ; v6 = end of RAM block - CMP v2, v3 ; if our end <= RAM block start - CMPHI v6, v1 ; or RAM block end <= our start - BLS %BT10 ; then no intersection - - MOV v4, v4, LSL #20 ; extract flags - - CMP v1, v3 - BHI not_bottom - - ; our area is at the bottom - CMP v2, v6 - BHS remove_block - - SUB v6, v6, v2 ; v6 = new size - ORR v6, v6, v4, LSR #20 ; + flags - STMDB v8, {v2, v6} ; store new base (= our end) and size - B %BT10 - - ; we've completely covered a block. Remove it. -remove_block - MOV v6, v8 -20 TEQ v6, a4 ; shuffle down subsequent blocks in table - LDMNEIA v6, {v3, v4} - STMNEDB v6, {v3, v4} - ADDNE v6, v6, #8 - BNE %20 - SUB v5, v5, #1 - SUB a4, a4, #8 - STR v5, [a4] - SUB v8, v8, #8 - B %BT10 - - ; our area is not at the bottom. -not_bottom - CMP v2, v6 - BLO split_block - - ; our area is at the top - SUB v6, v1, v3 ; v6 = new size - ORR v6, v6, v4, LSR #20 ; + flags - STMDB v8, {v3, v6} ; store original base and new size - B %BT10 - -split_block - MOV v6, a4 -30 TEQ v6, v8 ; shuffle up subsequent blocks in table - LDMNEDB v6, {v3, v4} - STMNEIA v6, {v3, v4} - SUBNE v6, v6, #8 - BNE %BT30 - ADD v5, v5, #1 - ADD a4, a4, #8 - STR v5, [a4] - - SUB v7, v1, v3 ; v7 = size of first half - SUB v6, v6, v2 ; v6 = size of second half - ORR v7, v7, v4, LSR #20 - ORR v6, v6, v4, LSR #20 ; + flags - STMDB v8, {v3, v7} - STMIA v8!, {v2, v6} - B %BT10 - - -;void RISCOS_Start(unsigned int flags, int *riscos_header, int *hal_header, void *ref) -; - -; We don't return, so no need to obey ATPCS, except for parameter passing. -; register usage: v4 = location of VRAM -; v6 = amount of VRAM - - ROUT -RISCOS_Start - TEQ a4, #0 -01 BEQ %BT01 ; Stop here if no RAM - - ; subtract the HAL and OS from the list of RAM areas - MOV v1, a2 - LDR v2, [a2, #OSHdr_ImageSize] - BL Subtractv1v2fromRAMtable - LDR v1, [a3, #HALDesc_Start] - ADD v1, a3, v1 - LDR v2, [a3, #HALDesc_Size] - BL Subtractv1v2fromRAMtable - - LDR v5, [a4] ; v5 = the number of RAM blocks - SUB v8, a4, v5, LSL #3 ; Jump back to the start of the list. - - ; Search for some VRAM -05 LDMIA v8!, {v1, v2} ; Get a block from the list. (v1,v2)=(addr,size+flags) - TST v2, #1 ; Is it VRAM? - BNE %FT20 ; If so, deal with it below - TEQ v8, a4 ; Carry on until end of list or we find some. - BNE %BT05 - - ; Extract some pseudo-VRAM from first RAM block - SUB v8, a4, v5, LSL #3 ; Rewind again. - LDMIA v8!, {v1, v2} - MOV v2, v2, LSR #12 ; Remove flags - MOV v2, v2, LSL #12 - MOV v4, v1 ; Allocate first block as video memory - MOV v6, v2 - TEQ v8, a4 ; Was this the only block? If so, leave 1M - SUBEQS v6, v6, #1024*1024 - MOVCC v6, v2, LSR #1 ; If that overflowed, take half the bank. - CMP v6, #32*1024*1024 - MOVHS v6, #32*1024*1024 ; Limit allocation to 32M (arbitrary) - - ADD v1, v1, v6 ; Adjust the RAM block base... - SUBS v2, v2, v6 ; ... and the size - LDMEQIA v8!, {v1, v2} ; Fetch the next block if we claimed it all - B %FT30 - - ; Note real VRAM parameters -20 MOV v6, v2 ; Remember the size and address - MOV v4, v1 ; of the VRAM -22 TEQ v8, a4 ; if not at the end of the array - LDMNEIA v8, {v1, v2} ; pack the array tighter - STMNEDB v8, {v1, v2} - ADDNE v8, v8, #8 - BNE %BT22 -25 SUB v5, v5, #1 ; decrease the counter - STR v5, [a4, #-8]! ; and move the end marker down - - SUB v8, a4, v5, LSL #3 ; Rewind to start of list - LDMIA v8!, {v1, v2} - - ; Fill in the Kernel's permanent memory table -30 ADD ip, v1, #DRAMOffset_PageZero - ADD v7, ip, #DRAMPhysAddrA - - ADD sp, v1, #DRAMOffset_ScratchSpace + ScratchSpaceSize - - Push "a1,a2,a3" ; Remember our arguments - - CMP v5, #DRAMPhysTableSize ; Don't overflow our table - ADDHI a4, v8, #DRAMPhysTableSize*8 - 8 - -35 MOV v2, v2, LSR #12 - MOVS v2, v2, LSL #12 ; strip out flags - STMNEIA v7!, {v1, v2} ; if non-zero length, add it to real list - TEQ v8, a4 - LDMNEIA v8!, {v1, v2} - BNE %BT35 - - ; Now go back and put the VRAM information in - - STR v6, [ip, #VRAMFlags] - MOV v6, v6, LSR #12 - MOV v6, v6, LSL #12 ; strip out flags - ADD a3, ip, #VideoPhysAddr - STMIA a3, {v4, v6} - - ; Now we have to work out the total RAM size - MOV a2, #0 - MOV v6, a3 -40 - LDMIA v6!, {v1, v2} ; get address, size - ADD a2, a2, v2 ; add on size - TEQ v6, v7 - BNE %BT40 - - -; a2 = Total memory size (bytes) -; a3 = PhysRamTable -; v7 = After last used entry in PhysRamTable - -; now store zeros to fill out table - -55 - ADD v2, a3, #PhysRamTableEnd-PhysRamTable - MOV v3, #0 - MOV v4, #0 -57 - CMP v7, v2 - STMLOIA v7!, {v3, v4} - BLO %BT57 - -; Time to set up the L1PT. Just zero it out for now. - - LDR a3, [a3, #DRAMPhysAddrA-PhysRamTable] ; get address of 1st RAM bank - ADD a3, a3, #DRAMOffset_L1PT+16*1024 ; make a3 -> L1PT end - MOV a4, #16*1024 - MOV v2, #0 - MOV v3, #0 - MOV v4, #0 - MOV v5, #0 - MOV v6, #0 - MOV v7, #0 - MOV v8, #0 - MOV ip, #0 -60 - STMDB a3!, {v2-v8,ip} ; start at end and work back - SUBS a4, a4, #8*4 - BNE %BT60 - - ADD v1, a3, #DRAMOffset_PageZero - DRAMOffset_L1PT - ADD v2, a3, #DRAMOffset_LastFixed - DRAMOffset_L1PT - STR a2, [v1, #RAMLIMIT] ; remember the RAM size - MOV lr, a2, LSR #12 - SUB lr, lr, #1 - STR lr, [v1, #MaxCamEntry] - MOV lr, a2, LSR #12-3+12 - CMP a2, lr, LSL #12-3+12 - ADDNE lr, lr, #1 - MOV lr, lr, LSL #12 - STR lr, [v1, #SoftCamMapSize] - STR a3, [v1, #InitUsedStart] ; store start of L1PT - - ADD v1, v1, #DRAMPhysAddrA - MOV v3, a3 - -; For the next batch of allocation routines, v1-v3 are treated as globals. -; v1 -> current entry in PhysRamTable -; v2 -> next address to allocate in v1 (may point at end of v1) -; v3 -> L1PT (or 0 if MMU on - not yet) - -; Allocate the L2PT backing store for the logical L2PT space, to -; prevent recursion. - LDR a1, =L2PT - MOV a2, #&00400000 - LDR a3, =(AP_None * L2X_APMult) - BL AllocateL2PT - -; Allocate workspace for the HAL - - ADD a4, v3, #DRAMOffset_PageZero - DRAMOffset_L1PT - LDR a3, [sp, #8] ; recover pushed HAL header - LDR a1, =HALWorkspace - LDR a2, =(AP_Read * L2X_APMult) + L2_C + L2_B - LDR lr, [a3, #HALDesc_Workspace] ; their workspace - LDR ip, [a3, #HALDesc_NumEntries] ; plus 1 word per entry - ADD lr, lr, ip, LSL #2 - MOV a3, lr, LSR #12 ; round workspace up to whole - MOV a3, a3, LSL #12 ; number of pages - CMP a3, lr - ADDNE a3, a3, #&1000 - STR a3, [a4, #HAL_WsSize] ; Make a note of allocated space - ADD ip, a1, ip, LSL #2 ; Their workspace starts - STR ip, [a4, #HAL_Workspace] ; after our table of entries - BL Init_MapInRAM - - LDR a3, [sp, #8] ; recover pushed HAL header - LDR lr, [a3, #HALDesc_Flags] - TST lr, #HALFlag_NCNBWorkspace ; do they want uncacheable - LDRNE a1, =HALWorkspaceNCNB ; workspace? - LDRNE a2, =(AP_None * L2X_APMult) - LDRNE a3, =32*1024 - BLNE Init_MapInRAM - -; Bootstrap time. We want to get the MMU on ASAP. We also don't want to have to -; clear up too much mess later. So what we'll do is map in the three fixed areas -; (L1PT, scratch space and page zero), the CAM, ourselves, and the HAL, -; then turn on the MMU. The CAM will be filled in once the MMU is on, by -; reverse-engineering the page tables? - - ; Map in page zero - ADD a1, v3, #DRAMOffset_PageZero - DRAMOffset_L1PT - MOV a2, #0 - [ ECC - LDR a3, =(AP_Read * L2X_APMult) + L2_C + L2_B + 1:SHL:31 - | - LDR a3, =(AP_Read * L2X_APMult) + L2_C + L2_B - ] - MOV a4, #16*1024 - BL Init_MapIn - - ; Map in scratch space - ADD a1, v3, #DRAMOffset_ScratchSpace - DRAMOffset_L1PT - MOV a2, #ScratchSpace - [ ECC - LDR a3, =(AP_Read * L2X_APMult) + L2_C + L2_B + 1:SHL:31 - | - LDR a3, =(AP_Read * L2X_APMult) + L2_C + L2_B - ] - MOV a4, #16*1024 - BL Init_MapIn - - ; Map in L1PT - MOV a1, v3 - LDR a2, =L1PT - [ ECC - LDR a3, =(AP_None * L2X_APMult) + 1:SHL:31 - | - LDR a3, =(AP_None * L2X_APMult) - ] - MOV a4, #16*1024 - BL Init_MapIn - - ; Map in L1PT again in PhysicalAccess (see below) - MOV a1, v3, LSR #20 - MOV a1, a1, LSL #20 ; megabyte containing L1PT - LDR a2, =PhysicalAccess - [ ECC - LDR a3, =(AP_None * L2X_APMult) + 1:SHL:31 - | - LDR a3, =(AP_None * L2X_APMult) - ] - MOV a4, #1024*1024 - BL Init_MapIn - - ; Examine HAL and RISC OS locations - LDMFD sp, {v4,v5,v6} ; v4 = flags, v5 = RO desc, v6 = HAL desc - LDR lr, [v6, #HALDesc_Size] - LDR v7, [v6, #HALDesc_Start] - ADD v6, v6, v7 ; (v6,v8)=(start,end) of HAL - ADD v8, v6, lr - - LDR v7, [v5, #OSHdr_ImageSize] - ADD v7, v5, v7 ; (v5,v7)=(start,end) of RISC OS - - TEQ v8, v5 ; check contiguity (as in a ROM image) - BNE %FT70 - - ; HAL and RISC OS are contiguous. Yum. - MOV a1, v6 - LDR a2, =RISCOS_Header - SUB a2, a2, lr - - SUB ip, a2, a1 ; change physical addresses passed in - LDMIB sp, {a3, a4} ; into logical addresses - ADD a3, a3, ip - ADD a4, a4, ip - STMIB sp, {a3, a4} - - MOV a3, #(AP_ROM * L2X_APMult) + L2_C + L2_B - SUB a4, v7, v6 - BL Init_MapIn - MOV a3, v6 - B %FT75 - -70 - ; HAL is separate. (We should cope with larger images) - LDR a2, =ROM - MOV a1, v6 - SUB ip, a2, a1 ; change physical address passed in - LDR a3, [sp, #8] ; into logical address - ADD a3, a3, ip - STR a3, [sp, #8] - SUB a4, v8, v6 - MOV a3, #(AP_ROM * L2X_APMult) + L2_C + L2_B - BL Init_MapIn - - ; And now map in RISC OS - LDR a2, =RISCOS_Header ; Hmm - what if position independent? - MOV a1, v5 - SUB ip, a2, a1 ; change physical address passed in - LDR a3, [sp, #4] ; into logical address - ADD a3, a3, ip - STR a3, [sp, #4] - SUB a4, v7, v5 - MOV a3, #(AP_ROM * L2X_APMult) + L2_C + L2_B - BL Init_MapIn - MOV a3, v5 -75 - ; We've now allocated all the pages we're going to before the MMU comes on. - ; Note the end address (for RAM clear) - ADD a1, v3, #DRAMOffset_PageZero - DRAMOffset_L1PT - STR v1, [a1, #InitUsedBlock] - STR v2, [a1, #InitUsedEnd] - STR a3, [a1, #ROMPhysAddr] - - ; Note the HAL flags passed in. - 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) - MSR CPSR_c, #IRQ32_mode + I32_bit + F32_bit - LDR sp_irq, =ScratchSpace + ScratchSpaceSize/2 - MSR CPSR_c, #SVC32_mode + I32_bit + F32_bit - LDR a2, =Reset_IRQ_Handler - STR a2, [a1, #InitIRQHandler] - - ; Fill in some initial processor vectors. These will be used during ARM - ; analysis, once the MMU is on. We do it here before the data cache is - ; activated to save any IMB issues. - ADRL a2, InitProcVecs - ADD a3, a2, #InitProcVecsEnd - InitProcVecs -76 LDR a4, [a2], #4 - CMP a2, a3 - STR a4, [a1], #4 - BLO %BT76 - -MMU_activation_zone - -; The time has come to activate the MMU. Steady now... Due to unpredictability of MMU -; activation, need to ensure that mapped and unmapped addresses are equivalent. To -; do this, we temporarily make the section containing virtual address MMUon_instr map -; to the same physical address. In case the code crosses a section boundary, do the -; next section as well. -; -; Also note, no RAM access until we've finished the operation, as we don't know it's -; available, and we might lose it due to lack of cache cleaning. -; - MOV a1, #4_3333333333333333 ; All domain manager - in case MMU already on - ARM_MMU_domain a1 ; (who knows what domains/permissions they are using) - - ADR a1, MMU_activation_zone - MOV a1, a1, LSR #20 ; a1 = megabyte number (stays there till end) - ADD lr, v3, a1, LSL #2 ; lr -> L1PT entry - LDMIA lr, {a2, a3} ; remember old mappings - [ ARM6support - LDR ip, =(AP_None * L1_APMult) + L1_U + L1_Section - | - LDR ip, =(AP_ROM * L1_APMult) + L1_U + L1_Section - ] - ORR a4, ip, a1, LSL #20 ; not cacheable, as we don't want - ADD v4, a4, #1024*1024 ; to fill the cache with rubbish - STMIA lr, {a4, v4} - - MOV a4, a1 - BL Init_ARMarch ; corrupts a1 and ip - - MOV a1, a4 - MSREQ CPSR_c, #F32_bit+I32_bit+UND32_mode ; Recover the soft copy of the CR - MOVEQ v5, sp - ARM_read_control v5, NE - [ CacheOff - ORR v5, v5, #MMUC_M ; MMU on - ORR v5, v5, #MMUC_R ; ROM mode enable - | - ORR v5, v5, #MMUC_W+MMUC_C+MMUC_M ; Write buffer, data cache, MMU on - ORR v5, v5, #MMUC_R+MMUC_Z ; ROM mode enable, branch predict enable - ] - ARM_MMU_transbase v3 ; Always useful to tell it where L1PT is... - - MOV ip, #0 - MCREQ p15, 0, ip, c5, c0 ; MMU may already be on (but flat mapped) - MCRNE p15, 0, ip, c8, c7 ; if HAL needed it (eg XScale with ECC) - ; so flush TLBs now -MMUon_instr - ARM_write_control v5 - MOVEQ sp, v5 - MSREQ CPSR_c, #F32_bit+I32_bit+SVC32_mode - - MOV ip, #0 ; junk MMU-off contents of I-cache - MCR ARM_config_cp,0,ip,ARMv4_cache_reg,C7 ; (works on ARMv3) - - MOV ip, #4_0000000000000001 ; domain 0 client only - ARM_MMU_domain ip - -; MMU now on. Need to jump to logical copy of ourselves. Complication arises if our -; physical address overlaps our logical address - in that case we need to map -; in another disjoint copy of ourselves and branch to that first, then restore the -; original two sections. - ADRL a4, RISCOS_Header - LDR ip, =RISCOS_Header - SUB ip, ip, a4 - ADR a4, MMU_activation_zone - MOV a4, a4, LSR #20 - MOV a4, a4, LSL #20 ; a4 = base of scrambled region - ADD v4, a4, #2*1024*1024 ; v4 = top of scrambled region - SUB v4, v4, #1 ; (inclusive, in case wrapped to 0) - ADR v5, MMUon_resume - ADD v5, v5, ip ; v5 = virtual address of MMUon_resume - CMP v5, a4 - BLO MMUon_nooverlap - CMP v5, v4 - BHI MMUon_nooverlap - - ASSERT ROM > 3*1024*1024 -; Oh dear. We know the ROM lives high up, so we'll mangle 00100000-002FFFFF. -; But as we're overlapping the ROM, we know we're not overlapping the page tables. - LDR lr, =L1PT ; accessing the L1PT virtually now - [ ARM6support - LDR ip, =(AP_None * L1_APMult) + L1_U + L1_Section - | - LDR ip, =(AP_ROM * L1_APMult) + L1_U + L1_Section - ] - ORR v6, a4, ip - ADD ip, v6, #1024*1024 - LDMIB lr, {v7, v8} ; sections 1 and 2 - STMIB lr, {v6, ip} - RSB ip, a4, #&00100000 - ADD pc, pc, ip - NOP -MMUon_overlapresume ; now executing from 00100000 - ADD ip, lr, a4, LSR #18 - STMIA ip, {a2, a3} ; restore original set of mappings - BL Init_PageTablesChanged - - MOV a2, v7 ; arrange for code below - MOV a3, v8 ; to restore section 1+2 instead - MOV a1, #1 - -MMUon_nooverlap - ADRL lr, RISCOS_Header - LDR ip, =RISCOS_Header - SUB ip, ip, lr - ADD pc, pc, ip - NOP -MMUon_resume -; What if the logical address of the page tables is at the physical address of the code? -; Then we have to access it via PhysicalAccess instead. - LDR lr, =L1PT - CMP lr, a4 - BLO MMUon_nol1ptoverlap - CMP lr, v4 - BHI MMUon_nol1ptoverlap -; PhysicalAccess points to the megabyte containing the L1PT. Find the L1PT within it. - LDR lr, =PhysicalAccess - MOV v6, v3, LSL #12 - ORR lr, lr, v6, LSR #12 -MMUon_nol1ptoverlap - ADD lr, lr, a1, LSL #2 - STMIA lr, {a2, a3} - BL Init_PageTablesChanged - -; The MMU is now on. Wahey. Let's get allocating. - - LDR sp, =ScratchSpace + ScratchSpaceSize - 4*3 ; 3 items already on stack :) - - LDR a1, =ZeroPage - - ADD lr, v3, #DRAMOffset_PageZero-DRAMOffset_L1PT ; lr = PhysAddr of zero page - SUB v1, v1, lr - ADD v1, v1, a1 ; turn v1 from PhysAddr to LogAddr - - LDR a2, [a1, #InitUsedBlock] ; turn this from Phys to Log too - SUB a2, a2, lr - ADD a2, a2, a1 - STR a2, [a1, #InitUsedBlock] - - -; Store the logical address of the HAL descriptor - LDR a2, [sp, #8] - STR a2, [a1, #HAL_Descriptor] - - MOV v3, #0 ; "MMU is on" signal - - BL ARM_Analyse - - ChangedProcVecs a1 - - MOV a1, #L1_Fault - BL RISCOS_ReleasePhysicalAddress - - ASSERT ZeroPage = 0 - LDR a1, =HALWorkspace - MOV a2, #0 - LDR a3, [a2, #HAL_WsSize] - BL memset - - MOV a2, #ZeroPage - LDR a1, =IOLimit - STR a1, [a2, #IOAllocLimit] - LDR a1, =IO - STR a1, [a2, #IOAllocPtr] - - BL SetUpHALEntryTable - -; Initialise the HAL. Due to its memory claiming we need to get our v1 and v2 values -; into workspace and out again around it. - - MOV a1, #ZeroPage - STR v1, [a1, #InitUsedBlock] - STR v2, [a1, #InitUsedEnd] - - LDR a1, =RISCOS_Header - LDR a2, =HALWorkspaceNCNB - AddressHAL - CallHAL HAL_Init - - MOV a1, #ZeroPage - LDR v1, [a1, #InitUsedBlock] - LDR v2, [a1, #InitUsedEnd] - -; Start timer zero, at 100 ticks per second - MOV a1, #0 - CallHAL HAL_TimerGranularity - - MOV a2, a1 - MOV a1, #100 - BL __rt_udiv - - MOV a2, a1 - MOV a1, #0 - CallHAL HAL_TimerSetPeriod - - MOV a1, #InitIRQWs - MOV a2, #1 - STRB a2, [a1, #KbdScanActive] - - CallHAL HAL_KbdScanSetup - - MSR CPSR_c, #F32_bit+SVC32_mode ; enable IRQs for scan - -; Remember some stuff that's about to get zapped - LDR v8, =ZeroPage - LDR v4, [v8, #ROMPhysAddr] - LDR v5, [v8, #RAMLIMIT] - LDR v7, [v8, #MaxCamEntry] - - MOV a1, #0 - LDR a1, [a1, #HAL_StartFlags] - TST a1, #OSStartFlag_RAMCleared -; Clear the memory. - BLEQ ClearPhysRAM - -; Put it back - STR v4, [v8, #ROMPhysAddr] - STR v5, [v8, #RAMLIMIT] - STR v7, [v8, #MaxCamEntry] - -; Set v4 to XCB bits for default cacheable+bufferable - MOV v5, #0 - LDR v4, [v5, #MMU_PCBTrans] - LDRB v4, [v4, #0] -; Set v5 to XCB bits for default bufferable - LDR v5, [v5, #MMU_PCBTrans] - LDRB v5, [v5, #XCB_NC] - -; Set up the data cache cleaner space if necessary (eg. for StrongARM core) - MOV a1, #-1 - CallHAL HAL_CleanerSpace - CMP a1, #-1 ;-1 means none needed (HAL only knows this if for specific ARM core eg. system-on-chip) - BEQ %FT20 - LDR a2, =DCacheCleanAddress - ORR a3, v4, #AP_None * L2X_APMult ; ideally, svc read only, user none but hey ho - ASSERT DCacheCleanSize = 4*&10000 ; 64k of physical space used 4 times (allows large page mapping) - MOV a4, #&10000 - MOV ip, #4 - SUB sp, sp, #5*4 ;room for a1-a4,ip -10 - STMIA sp, {a1-a4, ip} - BL Init_MapIn - LDMIA sp, {a1-a4, ip} - SUBS ip, ip, #1 - ADD a2, a2, #&10000 - BNE %BT10 - ADD sp, sp, #5*4 - -20 -; Allocate the CAM - LDR a3, [v8, #SoftCamMapSize] - ORR a2, v4, #AP_None * L2X_APMult - LDR a1, =CAM - BL Init_MapInRAM - -; Allocate the supervisor stack - LDR a1, =SVCStackAddress - ORR a2, v4, #AP_Read * L2X_APMult - LDR a3, =SVCStackSize - BL Init_MapInRAM - - [ HAL32 -; Allocate the interrupt stack - LDR a1, =IRQStackAddress - ORR a2, v4, #AP_None * L2X_APMult - LDR a3, =IRQStackSize - BL Init_MapInRAM - ] - -; Allocate the abort stack - LDR a1, =ABTStackAddress - ORR a2, v4, #AP_None * L2X_APMult - LDR a3, =ABTStackSize - BL Init_MapInRAM - -; Allocate the undefined stack - LDR a1, =UNDStackAddress - ORR a2, v4, #AP_None * L2X_APMult - LDR a3, =UNDStackSize - BL Init_MapInRAM - -; Allocate the system heap - LDR a1, =SysHeapAddress - ORR a2, v4, #AP_Full * L2X_APMult - LDR a3, =32*1024 - BL Init_MapInRAM - -; Allocate the cursor/system/sound block - first the cached bit - LDR a1, =CursorChunkAddress - ORR a2, v4, #AP_Read * L2X_APMult ; Should be AP_None? - LDR a3, =SoundDMABuffers - CursorChunkAddress - BL Init_MapInRAM -; then the uncached bit - LDR a1, =SoundDMABuffers - ORR a2, v5, #AP_Read * L2X_APMult ; Should be AP_None? - LDR a3, =?SoundDMABuffers - BL Init_MapInRAM - - [ LongCommandLines - LDR a1, =KbuffsBaseAddress - ORR a2, v4, #AP_Read * L2X_APMult - LDR a3, =(KbuffsSize + &FFF) :AND: &FFFFF000 ;(round to 4k) - BL Init_MapInRAM - ] - - [ MinorL2PThack -; Allocate backing L2PT for the free pool - MOV a1, #FreePoolAddress - LDR a2, [v8, #RAMLIMIT] - ORR a3, v5, #AP_None * L2X_APMult - BL AllocateL2PT -; And for application space - MOV a1, #0 - MOV a2, #AplWorkMaxSize ; Not quite right, but the whole thing's wrong anyway - ORR a3, v4, #AP_Full * L2X_APMult - BL AllocateL2PT -; And for the system heap. Sigh - LDR a1, =SysHeapAddress - LDR a2, =SysHeapMaxSize - ORR a3, v4, #AP_Full * L2X_APMult - BL AllocateL2PT - ] - - LDR a1, =ZeroPage - STR v2, [a1, #InitUsedEnd] - - - MSR CPSR_c, #F32_bit+I32_bit+IRQ32_mode - LDR sp, =IRQSTK - MSR CPSR_c, #F32_bit+I32_bit+ABT32_mode - LDR sp, =ABTSTK - MSR CPSR_c, #F32_bit+I32_bit+UND32_mode - LDR sp, =UNDSTK - MSR CPSR_c, #F32_bit+SVC2632 - LDR sp, =SVCSTK - - LDR ip, =CAM - STR ip, [a1, #CamEntriesPointer] - - BL ConstructCAMfromPageTables - - MOV a1, #4096 - STR a1, [v8, #Page_Size] - - 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 - -CountPageTablePages ROUT - MOV a1, #ZeroPage - LDR a2, =CAM - LDR a3, [a1, #MaxCamEntry] - MOV a1, #0 - ADD a3, a3, #1 - ADD a4, a2, a3, LSL #3 -10 LDR ip, [a4, #-8]! - ASSERT (L2PT :AND: &3FFFFF) = 0 - MOV ip, ip, LSR #22 - TEQ ip, #L2PT :SHR: 22 - ADDEQ a1, a1, #4096 - TEQ a4, a2 - BNE %BT10 - MOV a2, #0 - STR a1, [a2, #L2PTUsed] - MOV pc, lr - -; int PhysAddrToPageNo(void *addr) -; -; Converts a physical address to the page number of the page containing it. -; Returns -1 if address is not in RAM. - -PhysAddrToPageNo - MOV a4, #0 - LDR ip, =ZeroPage + PhysRamTable -10 LDMIA ip!, {a2, a3} ; get phys addr, size - TEQ a3, #0 ; end of list? (size=0) - BEQ %FT90 ; then it ain't RAM - SUB a2, a1, a2 ; a2 = amount into this bank - CMP a2, a3 ; if more than size - ADDHS a4, a4, a3 ; increase counter by size of bank - BHS %BT10 ; and move to next - ADD a4, a4, a2 ; add offset to counter - MOV a1, a4, LSR #12 ; convert counter to a page number - MOV pc, lr - -90 MOV a1, #-1 - MOV pc, lr - - -; A routine to construct the soft CAM from the page tables. This is used -; after a soft reset, and also on a hard reset as it's an easy way of -; clearing up after the recursive page table allocaton. - - ROUT -ConstructCAMfromPageTables - Push "v1-v8, lr" - MOV a1, #ZeroPage - LDR a2, [a1, #MaxCamEntry] - LDR ip, [a1, #MMU_PCBTrans] - LDR v1, =CAM ; v1 -> CAM (for whole routine) - ADD a2, a2, #1 - ADD a2, v1, a2, LSL #3 - - LDR a3, =DuffEntry ; Clear the whole CAM, from - MOV a4, #AP_Duff ; the top down. -10 STMDB a2!, {a3, a4} - CMP a2, v1 - BHI %BT10 - - MOV v2, #0 ; v2 = logical address - LDR v3, =L1PT ; v3 -> L1PT (not used much) - LDR v4, =L2PT ; v4 -> L2PT - -30 LDR v5, [v3, v2, LSR #18] ; lr = first level descriptor - ASSERT L1_Fault = 0 - AND a1, v5, #2_11 ; move to next section if not - TEQ a1, #L1_Page ; a page table (we ignore section maps - BEQ %FT40 ; and we don't do fine tables) - ADDS v2, v2, #&00100000 - BCC %BT30 - Pull "v1-v8, pc" - -40 LDR v5, [v4, v2, LSR #10] ; lr = second level descriptor - ASSERT L2_Fault = 0 - ANDS v6, v5, #2_11 ; move to next page if fault - BEQ %FT80 - - TEQ v6, #L2_SmallPage ; convert small pages to extended pages - BNE %FT50 - MOV lr, #0 ; if we now know that CPU supports them - LDR a1, [lr, #ProcessorFlags] - TST a1, #CPUFlag_ExtendedPages - BEQ %FT50 - - ASSERT ZeroPage = 0 - LDR a1, [lr, #MMU_PCBTrans] ; reprocess C and B bits as per XCB table - TST v5, #L2_C ; (eg if C and B both set, replace with - ORREQ lr, lr, #DynAreaFlags_NotCacheable ; default cacheable+bufferable XCB) - TST v5, #L2_B - ORREQ lr, lr, #DynAreaFlags_NotBufferable - LDRB lr, [a1, lr, LSR #2] - EOR v5, v5, #L2_ExtPage:EOR:L2_SmallPage - BIC v5, v5, #2_111111000000 ; remove excess 3 AP fields - BIC v5, v5, #2_000000001100 ; remove old C+B - BIC a1, v5, #2_000000110011 ; remove all other bits for just address - ORR v5, v5, lr ; put in new XCB - MOV a2, #ZeroPage - ARMop MMU_ChangingEntry,,,a2 - STR v5, [v4, v2, LSR #10] ; update page table - -50 MOV a1, v5, LSR #12 - MOV a1, a1, LSL #12 ; a1 = address (flags stripped out),,, - TEQ v6, #L2_LargePage - BICEQ a1, a1, #&0000F000 ; large pages get bits 12-15 - ANDEQ lr, v2, #&0000F000 ; from the virtual address - ORREQ a1, a1, lr - - BL PhysAddrToPageNo - CMP a1, #-1 - BEQ %FT80 - - ADD a2, v1, a1, LSL #3 ; a2 -> CAM entry - - AND a1, v5, #&30 ; a1 = access permission - MOV a1, a1, LSR #4 - ; ARM access goes 0 => all R/O, 1 => user none, 2 => user R/O, 3 => user R/W - ; PPL access goes 0 => user R/W, 1 => user R/O, 2 => user none, (and let's say 3 all R/O) - RSB v6, a1, #3 ; v6 = PPL access - AND a1, v5, #2_11 ; a1 = page type - CMP a1, #L2_SmallPage - ANDHI a1, v5, #2_0000001111001100 ; Extended TEX and CB bits - ANDLS a1, v5, #2_0000000000001100 ; Small/Large CB bits only - ANDLO lr, v5, #2_1111000000000000 ; Large TEX bits - ORRLO a1, a1, lr, LSR #6 ; Move Large TEX back to Extended TEX position - MOV lr, #3 ; lr = PCB value (funny loop to do NCNB first) -60 LDRB a3, [ip, lr] ; look in XCBTrans table - TEQ a3, a1 ; found a match for our XCB? - BEQ %FT70 - TST lr, #2_11 - SUBNE lr, lr, #1 ; loop goes 3,2,1,0,7,6,5,4,...,31,30,29,28 - ADDEQ lr, lr, #7 - TEQ lr, #35 - BNE %BT60 -70 AND a1, lr, #2_00011 - ORR v6, v6, a1, LSL #4 ; extract NCNB bits - AND a1, lr, #2_11100 - ORR v6, v6, a1, LSL #10 ; extract P bits - ORR v6, v6, #PageFlags_Unavailable ; ???? pages from scratch to cam only? - STMIA a2, {v2, v6} ; store logical address, PPL - -80 ADD v2, v2, #&00001000 - TST v2, #&000FF000 - BNE %BT40 - TEQ v2, #0 ; yuck (could use C from ADDS but TST corrupts C - BNE %BT30 ; because of big constant) - - Pull "v1-v8, pc" - - - -; Allocate a physical page from DRAM -; -; On entry: -; v1 -> current entry in PhysRamTable -; v2 -> end of last used physical page -; On exit: -; a1 -> next free page -; v1, v2 updated -; -; No out of memory check... - -Init_ClaimPhysicalPage - MOV a1, v2 - LDMIA v1, {a2, a3} - ADD a2, a2, a3 ; ip = end of this bank - CMP v2, a2 ; advance v2 to next bank if - LDRHS a1, [v1, #8]! ; this bank is fully used - ADD v2, a1, #4096 - MOV pc, lr - -; Allocate and map in some RAM. -; -; On entry: -; a1 = logical address -; a2 = access permissions (see Init_MapIn) -; a3 = length -; v1 -> current entry in PhysRamTable -; v2 = next physical address -; v3 -> L1PT -; -; On exit: -; a1 -> physical address of start of RAM (deduce the rest from PhysRamTable) -; -; No out of memory check... -Init_MapInRAM ROUT - Push "v4-v8,lr" - MOV v8, #-1 - MOV v5, a3 ; v5 = amount of memory required - MOV v6, a1 ; v6 = logical address - MOV v7, a2 ; v7 = access permissions -10 LDMIA v1, {ip, v4} ; ip = addr of bank, v4 = len - SUB ip, v2, ip ; ip = amount of bank used - SUBS v4, v4, ip ; v4 = amount of bank left - LDREQ v2, [v1, #8]! ; move to next bank if 0 left - BEQ %BT10 - - CMP v8, #-1 ; is this the first bank? - MOVEQ v8, v2 ; remember it - - CMP v4, v5 ; sufficient in this bank? - MOVHS a4, v5 - MOVLO a4, v4 ; a4 = amount to take - - MOV a1, v2 ; set up parameters for MapIn call - MOV a2, v6 ; then move globals (in case MapIn - [ ECC - ORR a3, v7, #1:SHL:31 - | - MOV a3, v7 ; needs to allocate for L2PT) - ] - ADD v2, v2, a4 ; advance physaddr - SUB v5, v5, a4 ; decrease wanted - ADD v6, v6, a4 ; advance address pointer - BL Init_MapIn ; map in the RAM - TEQ v5, #0 ; more memory still required? - BNE %BT10 - - MOV a1, v8 - Pull "v4-v8,pc" - -; Map a range of physical addresses to a range of logical addresses. -; -; On entry: -; a1 = physical address -; a2 = logical address -; a3 = access permissions + C + B bits (bits 11-2 of an extended descriptor) -; (also set bit 31 to indicate that P bit in L1PT should -; be set) -; a4 = area size -; v1 -> current entry in PhysRamTable -; v2 = last used physical address -; v3 -> L1PT (or 0 if MMU on) - -Init_MapIn ROUT - Push "lr" - ORR lr, a1, a2 ; OR together, physaddr, logaddr - ORR lr, lr, a4 ; and size. - MOVS ip, lr, LSL #12 ; If all bottom 20 bits 0 - BEQ Init_MapIn_Sections ; it's section mapped - - MOVS ip, lr, LSL #16 ; If bottom 16 bits not all 0 - ORRNE a3, a3, #L2_ExtPage ; then extended small pages (4K) - BNE %FT10 - - ORR a3, a3, #L2_LargePage ; else large pages (64K) - AND lr, a3, #L2_TEX ; extract TEX from ext page flags - AND ip, a3, #L2X_AP ; extract AP from ext page flags - BIC a3, a3, #L2_AP ; clear way for large page AP - ORR ip, ip, ip, LSL #2 ; duplicate up AP to 4 sub-pages - ORR ip, ip, ip, LSL #4 - ORR a3, a3, lr, LSL #6 ; replace TEX in large page position - ORR a3, a3, ip ; replace quadrupled AP -10 - Push "v4-v7" - MOV v4, a1 ; v4 = physaddr - MOV v5, a2 ; v5 = logaddr - MOV v6, a3 ; v6 = access permissions - MOV v7, a4 ; v7 = area size - -20 MOV a1, v4 - MOV a2, v5 - MOV a3, v6 - BL Init_MapInPage ; Loop through mapping in each - ADD v4, v4, #4096 ; page in turn - ADD v5, v5, #4096 - SUBS v7, v7, #4096 - BNE %BT20 - Pull "v4-v7,pc" - -Init_MapIn_Sections - MOVS ip, v3 ; is MMU on? - LDREQ ip, =L1PT ; then use virtual address - AND lr, a3, #4_033300 ; extract TEX and AP bits - BIC a3, a3, #4_033300 ; and clear them (now P, Domain and U bits) - ORR a3, a3, lr, LSL #6 ; put TEX and AP bits back in new position - [ ARM6support - ASSERT AP_ROM = 0 - TST a3, #4_300000 ; If ROM permission - ARM_6 lr,EQ ; and ARM 6 - ORREQ a3, a3, #AP_Read * L1_APMult ; then make it Read permission, non-updateable - ORRNE a3, a3, #L1_U - ORRS a3, a3, #L1_Section ; Add section indicator to permission - | - ORRS a3, a3, #L1_U+L1_Section ; Add section + U indicators to permission - ] - ORRMI a3, a3, #L1_P - BICMI a3, a3, #1:SHL:31 - ORR a1, a1, a3 ; Merge with physical address - ADD a2, ip, a2, LSR #18 ; a2 -> L1PT entry -70 STR a1, [a2], #4 ; And store in L1PT - ADD a1, a1, #1024*1024 ; Advance one megabyte - SUBS a4, a4, #1024*1024 ; and loop - BNE %BT70 - Pull "pc" - - -; Map a logical page to a physical page, allocating L2PT as necessary. -; -; On entry: -; a1 = physical address -; a2 = logical address -; a3 = access permissions + C + B bits + size (all non-address bits, of appropriate type) -; (also set bit 31 to indicate that P bit in L1PT should be set) -; v1 -> current entry in PhysRamTable -; v2 = last used physical address -; v3 -> L1PT (or 0 if MMU on) -; On exit: -; a1 = logical address -; a2-a4, ip corrupt -; v1, v2 updated -; -; ROM permission is caught if on an ARM 6 and turned into Read -; Extended pages are caught if not available (or MMU off) and turned into Small - -Init_MapInPage - Push "v4-v6, lr" - MOV v4, a1 ; v4 = physical address - MOV v5, a2 ; v5 = logical address - MOV v6, a3 ; v6 = access permissions - MOV a1, v5 - MOV a2, #4096 - BL AllocateL2PT - TEQ v3, #0 ; if MMU on, access L2PT virtually... - LDREQ a1, =L2PT ; a1 -> L2PT virtual address - MOVEQ ip, v5 ; index using whole address - BEQ %FT40 - MOV ip, v5, LSR #20 - LDR a1, [v3, ip, LSL #2] ; a1 = level one descriptor - MOV a1, a1, LSR #10 - MOV a1, a1, LSL #10 ; a1 -> L2PT tables for this section - AND ip, v5, #&000FF000 ; extract L2 table index bits -40 AND lr, v6, #3 - TEQ lr, #L2_LargePage ; strip out surplus address bits from - BICEQ v6, v6, #&0000F000 ; large page descriptors - TEQ lr, #L2_ExtPage - BNE %FT50 - TEQ v3, #0 ; if we've been given an extended page - BNE %FT45 ; must check that (a) the MMU is on - MOV lr, #0 - LDR lr, [lr, #ProcessorFlags] ; and (b) the CPU supports them - TST lr, #CPUFlag_ExtendedPages - BNE %FT50 -45 EOR v6, v6, #L2_SmallPage :EOR: L2_ExtPage - AND lr, v6, #L2X_AP ; convert the extended page descriptor - BIC v6, v6, #L2_AP ; into a small page descriptor - ORR lr, lr, lr, LSL #2 ; (losing the TEX bits in the - ORR v6, v6, lr ; process, but they should have been 0) - ORR v6, v6, lr, LSL #4 -50 ORR lr, v4, v6 ; lr = value for L2PT entry - [ ARM6support - ASSERT AP_ROM = 0 - TST lr, #4_333300 ; if ROM permission - ARM_6 a2,EQ ; and ARM 6 - ORREQ lr, lr, #AP_Read * L2_APMult ; then make it Read permission - ] - STR lr, [a1, ip, LSR #10] ; update L2PT entry - MOV a1, v5 - Pull "v4-v6, pc" - - - -; On entry: -; a1 = virtual address L2PT required for -; a2 = number of bytes of virtual space -; a3 = access permissions that will be placed in L2PT (bits 11-2 of Extended L2 descriptor) -; (also set bit 31 to indicate that P bit in L1PT should be set) -; v1 -> current entry in PhysRamTable -; v2 = last used physical address -; v3 -> L1PT (or 0 if MMU on) -; On exit -; a1-a4,ip corrupt -; v1, v2 updated -AllocateL2PT - Push "a3,v4-v8,lr" - MOV v8, a1, LSR #20 ; round base address down to 1M - ADD lr, a1, a2 - MOV v7, lr, LSR #20 - TEQ lr, v7, LSL #20 - ADDNE v7, v7, #1 ; round end address up to 1M - - MOVS v6, v3 - LDREQ v6, =L1PT ; v6->L1PT (whole routine) - -05 LDR v5, [v6, v8, LSL #2] ; L1PT contains 1 word per M - TEQ v5, #0 ; if non-zero, the L2PT has - ; already been allocated - [ ARM6support - BEQ %FT10 - - TST v5, #L1_U ; if section is already updateable - BNE %FT40 ; leave it. - LDR a3, [sp, #0] - TST a3, #4_333300 ; if they want anything other than - ORRNE v5, v5, #L1_U ; ROM access, make the section - STRNE v5, [v6, v8, LSL #2] ; updateable. - B %FT40 -10 - | - BNE %FT40 - ] - - BIC lr, v8, #3 ; round down to 4M - each page - ADD lr, v6, lr, LSL #2 ; of L2PT maps to 4 sections - LDMIA lr, {a3,a4,v5,ip} ; check if any are page mapped - ASSERT L1_Fault = 2_00 :LAND: L1_Page = 2_01 :LAND: L1_Section = 2_10 - TST a3, #1 - TSTEQ a4, #1 - TSTEQ v5, #1 - TSTEQ ip, #1 - BEQ %FT20 ; nothing page mapped - claim a page - - TST a4, #1 ; at least one of the sections is page mapped - SUBNE a3, a4, #1*1024 ; find out where it's pointing to and - TST v5, #1 ; derive the corresponding address for our - SUBNE a3, v5, #2*1024 ; section - TST ip, #1 - SUBNE a3, ip, #3*1024 - - AND lr, v8, #3 - ORR a3, a3, lr, LSL #10 - [ ARM6support - ASSERT AP_ROM = 0 - ARM_6 lr ; if ARM 6 - BNE %FT15 - LDR lr, [sp, #0] ; do they want ROM access? - TST lr, #4_000300 - BICEQ a3, a3, #L1_U ; set the updateable bit accordingly - ORRNE a3, a3, #L1_U -15 - ] - STR a3, [v6, v8, LSL #2] ; fill in the L1PT entry - B %FT40 ; no more to do - -20 BL Init_ClaimPhysicalPage ; Claim a page to put L2PT in - MOV v4, a1 - - [ ARM6support - ASSERT AP_ROM = 0 - ARM_6 lr ; if ARM 6 - LDREQ lr, [sp, #0] ; do they want ROM access? - TSTEQ lr, #4_000300 - ORREQ a3, a1, #L1_Page ; set the updateable bit accordingly - ORRNE a3, a1, #L1_Page + L1_U - | - ORR a3, a1, #L1_Page + L1_U - ] - [ ECC - ORR a3, a3, #L1_P - ] - AND lr, v8, #3 - ORR a3, a3, lr, LSL #10 - STR a3, [v6, v8, LSL #2] ; fill in the L1PT - -; Need to zero the L2PT. Must do it before calling in MapInPage, as that may well -; want to put something in the thing we are clearing. If the MMU is off, no problem, -; but if the MMU is on, then the L2PT isn't accessible until we've called MapInPage. -; Solution is to use the AccessPhysicalAddress call. - - TEQ v3, #0 ; MMU on? - MOVNE a1, v4 ; if not, just access v4 - MOVEQ a1, #L1_B ; if so, map in v4 - MOVEQ a2, v4 - MOVEQ a3, #0 - BLEQ RISCOS_AccessPhysicalAddress - - MOV a2, #0 - MOV a3, #4*1024 - BL memset - - MOV a1, v4 ; Map in the L2PT page itself - LDR a2, =L2PT ; (can't recurse, because L2PT - ADD a2, a2, v8, LSL #10 ; backing for L2PT is preallocated) - BIC a2, a2, #&C00 - LDR a3, =(AP_None * L2X_APMult) + L2_ExtPage - [ ECC - ORR a3, a3, #1:SHL:31 - ] - BL Init_MapInPage - - -40 ADD v8, v8, #1 ; go back until all - CMP v8, v7 ; pages allocated - BLO %BT05 - - Pull "a3,v4-v8,pc" - - -; void *RISCOS_AccessPhysicalAddress(unsigned int flags, void *addr, void **oldp) -RISCOS_AccessPhysicalAddress - [ ECC - Push "a1-a3,lr" - MOV a1, a2 - BL PhysAddrToPageNo - CMP a1, #-1 - Pull "a1-a3,lr" - ] - LDR ip, =L1PT + (PhysicalAccess:SHR:18) ; ip -> L1PT entry - LDR a4, =(AP_None * L1_APMult) + L1_U + L1_Section - AND a1, a1, #L1_B ; user can ask for bufferable - [ ECC - ORRNE a1, a1, #L1_P - ] - ORR a1, a4, a1 ; a1 = flags for 2nd level descriptor - MOV a4, a2, LSR #20 ; rounded to section - ORR a1, a1, a4, LSL #20 ; a1 = complete descriptor - TEQ a3, #0 - LDRNE a4, [ip] ; read old value (if necessary) - STR a1, [ip] ; store new one - STRNE a4, [a3] ; put old one in [oldp] - - LDR a1, =PhysicalAccess - MOV a3, a2, LSL #12 ; take bottom 20 bits of address - ORR a3, a1, a3, LSR #12 ; and make an offset within PhysicalAccess - Push "a3,lr" - ARMop TLB_InvalidateEntry ; sufficient, cause not cacheable - Pull "a1,pc" - -; void RISCOS_ReleasePhysicalAddress(void *old) -RISCOS_ReleasePhysicalAddress - LDR ip, =L1PT + (PhysicalAccess:SHR:18) ; ip -> L1PT entry - STR a1, [ip] - LDR a1, =PhysicalAccess - ARMop TLB_InvalidateEntry,,tailcall ; sufficient, cause not cacheable - - -; void Init_PageTablesChanged(void) -; -; A TLB+cache invalidation that works on all known ARMs. Invalidate all I+D TLB is the _only_ TLB -; op that works on ARM720T, ARM920T and SA110. Ditto invalidate all I+D cache. -; -; DOES NOT CLEAN THE DATA CACHE. This is a helpful simplification, but requires that don't use -; this routine after we've started using normal RAM. -; -Init_PageTablesChanged - MOV a3, lr - BL Init_ARMarch - MOV ip, #0 - MCREQ ARM_config_cp,0,ip,ARMv3_TLBflush_reg,C0 - MCRNE ARM_config_cp,0,ip,ARMv4_TLB_reg,C7 - MCR ARM_config_cp,0,ip,ARMv4_cache_reg,C7 ; works on ARMv3 - MOV pc, a3 - - -HAL_Write0 - Push "v1, lr" - MOV v1, a1 - LDRB a1, [v1], #1 - TEQ a1, #0 - - - - - -;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; -; 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). -; -; We also have to avoid the page tables and the PhysRamTable. -; The latter is also used to tell us which areas of memory we should clear. - -; We don't have to worry about trampling on the ROM image as it's -; already been excluded from PhysRamTable. - -; This routine must work in 32-bit mode. - -; in: r7 = memory speed -; r8 = page size -; r9 = MEMC control register -; r13 = total RAM size -; -; None of the above are actually used by this routine -; -; out: r7-r9, r13 preserved -; - -ClearPhysRAM ROUT - MSR CPSR_c, #F32_bit+FIQ32_mode ; get some extra registers - MOV r8, #0 - MOV r9, #0 - MOV r10, #0 - MOV r11, #0 - MOV r12, #0 - MOV r13, #0 - MOV r14, #0 - MSR CPSR_c, #F32_bit+SVC32_mode - - [ EmulatorSupport - ARM_on_emulator r0 - BEQ CPR_skipped - ] - -;now let us do the clear - MOV r0,#ZeroPage+InitClearRamWs ;we can preserve r7-r9,r13 at logical address 52..67 - STMIA r0,{r4-r11,lr} - MOV r8, #0 - MOV r9, #0 - LDR r7, =PhysRamTable ; point to 5 lots of (physaddr,size) - ADR r6, RamSkipTable - ADD r4, r7, #PhysRamTableEnd-PhysRamTable ; r4 -> end of table -10 - LDR r5, [r6], #4 ; load first skip offset - - LDMIA r7, {r10, r11} ; load next address, size - TEQ r11, #0 - BEQ %FT50 -15 - ASSERT ZeroPage=0 - ADD r11, r10, r11 ; r11 = end address - - ; Need to check for RAM we've already used - LDR r0, [r8, #InitUsedStart] ; check for intersection with used space - CMP r0, r10 - BLO %FT18 - CMP r0, r11 - BHS %FT18 - - ;BKPT 0 - - LDR r1, [r8, #InitUsedEnd] - TEQ r0, r10 ; if at start of block, easy - BEQ %FT17 ; just move start pointer forwards - - MOV r11, r0 ; else set end pointer to start address - B %FT18 ; next time round, will be at start address - - -16 LDR r1, [r8, #InitUsedEnd] -17 CMP r1, r10 ; advance until we find block with end pointer in - CMPHS r11, r1 ; intersection if r10 <= r1 <= r11 - ADDLS r7, r7, #8 ; get next block if r1 = r11 or r1 outside [r10,r11] - LDRLS r5, [r6], #4 - LDMLSIA r7, {r10, r11} ; (if r1 = r11, will just move straight to next block) - ADDLS r11, r10, r11 - BLO %BT17 ; check next block if r1 outside [r10,r11] - MOVHI r10, r1 ; if r11 > r1, advance r10 to r1 (do partial block) - - -18 MOV r0, #L1_B ; map in the appropriate megabyte, - MOV r1, r10 ; making it bufferable - MOV r2, #0 - BL RISCOS_AccessPhysicalAddress - SUB lr, r0, r10 ; lr = offset from phys to log - ADD r1, r11, lr - - MOV r2, r0, LSR #20 - TEQ r2, r1, LSR #20 ; if end in different megabyte to start - MOVNE r1, r2, LSL #20 ; then stop at end of megabyte - ADDNE r1, r1, #&00100000 - - MSR CPSR_c, #F32_bit+FIQ32_mode ; switch to our bank o'zeros - MOV r2, #0 - -19 ADD r5, r5, r0 - -20 TEQ r0, r1 ; *this* is the speed critical bit - executed - TEQNE r0, r5 ; 32768 times per outer loop - STMNEIA r0!, {r2,r8-r14} - BNE %BT20 - - TEQ r0, r1 - BEQ %FT30 - - LDR r5, [r6], #4 ; load skip amount - ADD r0, r0, r5 ; and skip it - LDR r5, [r6], #4 ; load next skip offset (NB relative to end of last skip) - B %BT19 - -30 MSR CPSR_c, #F32_bit+SVC32_mode ; back to supervisor mode - MOV r10, r0 - MOV r11, r1 - LDMIA r7, {r0, r1} - SUB r11, r11, lr ; turn r11 back into physical address - SUB r5, r5, r0 ; r5 back into offset - ADD r0, r0, r1 ; r0 = physical end address of block - TEQ r0, r11 ; did we reach the real end? - MOVNE r10, r11 ; if not, carry on from where we stopped - SUBNE r11, r0, r11 ; (this also deals with avoiding InitUsed area) - BNE %BT15 - -40 ADD r7, r7, #8 - TEQ r7, r4 ; have we done all areas? - BNE %BT10 - -50 MOV r1, #0 - MOV r0, #ZeroPage+InitClearRamWs - LDMIA r0, {r4-r11,r14} ;restore - -CPR_skipped - - LDR r0, =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 - MOV r0, #ZeroPage ; soft copy - STR sp, [r0, #MMUControlSoftCopy] - MSR CPSR_c, #F32_bit + SVC32_mode - - MOV pc, lr - - LTORG - - GBLA lastaddr -lastaddr SETA 0 - GBLA lastregion -lastregion SETA 0 - - MACRO - MakeSkipTable $region, $addr, $size - [ ($region)<>lastregion - & -1 -lastaddr SETA 0 - ] - & ($addr)-lastaddr, $size -lastaddr SETA ($addr)+($size) -lastregion SETA $region - MEND - - MACRO - EndSkipTables - WHILE lastregion < (PhysRamTableEnd-PhysRamTable)/8 - & -1 -lastregion SETA lastregion +1 - WEND - MEND - - -RamSkipTable - MakeSkipTable 1, DRAMOffset_PageZero + 0, InitWsEnd - MakeSkipTable 1, DRAMOffset_PageZero + SkippedTables, SkippedTablesEnd-SkippedTables - EndSkipTables - - -InitProcVecs - BKPT &C000 ; Reset - BKPT &C004 ; Undefined Instruction - BKPT &C008 ; SWI - BKPT &C00C ; Prefetch Abort - SUBS pc, lr, #4 ; ignore data aborts - BKPT &C014 ; Address Exception - LDR pc, InitProcVecs + InitIRQHandler ; IRQ - BKPT &C01C ; FIQ -InitProcVec_FIQ - DCD 0 -InitProcVecsEnd - -; -; In: a1 = flags (L1_B,L1_C,L1_AP) -; a2 = physical address -; a3 = size -; Out: a1 = assigned logical address, or 0 if failed (no room) -; -; Will detect and return I/O space already mapped appropriately, or map and return new space -; For simplicity and speed of search, works on a section (1Mb) granularity -; - - ASSERT L1_B = 1:SHL:2 - ASSERT L1_C = 1:SHL:3 - ASSERT L1_AP = 3:SHL:10 -MapInFlag_DoublyMapped * 1:SHL:20 -MapInFlag_APSpecified * 1:SHL:21 - -RISCOS_MapInIO ROUT - Entry "v1-v5,v7" - MOV v7, #L1_B:OR:L1_C - ORR v7, v7, #L1_AP ; v7 = user-specifiable flags - MOV v5, a1 ; v5 = original flags - MOV v4, a2 ; v4 = original requested address - ADD a3, a2, a3 ; a3 -> end (exclusive) - MOV a2, a2, LSR #20 - MOV a2, a2, LSL #20 ; round a2 down to a section boundary - SUB v4, v4, a2 ; v4 = offset of original within section-aligned area - MOV lr, a3, LSR #20 - TEQ a3, lr, LSL #20 - ADDNE lr, lr, #1 - MOV a3, lr, LSL #20 ; round a3 up to a section boundary - - TST v5, #MapInFlag_APSpecified - BICEQ a1, a1, #L1_AP - ORREQ a1, a1, #L1_APMult * AP_None - - ANDS v5, v5, #MapInFlag_DoublyMapped - SUBNE v5, a3, a2 ; v5 = offset of second mapping or 0 - - LDR ip, =ZeroPage - LDR a4, =L1PT - AND a1, a1, v7 ; only allow bufferable as flags option - LDR v2, =IO ; logical end (exclusive) of currently mapped IO - LDR v1, [ip, #IOAllocPtr] ; logical start (inclusive) - - SUB v1, v1, #&100000 -10 - ADD v1, v1, #&100000 ; next mapped IO section - CMP v1, v2 - BHS %FT32 ; no more currently mapped IO - LDR v3, [a4, v1, LSR #(20-2)] ; L1PT entry (must be for mapped IO) - MOV lr, v3, LSR #20 ; physical address bits - CMP lr, a2, LSR #20 - BNE %BT10 ; no address match - AND lr, v3, v7 - TEQ lr, a1 - BNE %BT10 ; no flags match - - TEQ v5, #0 ; doubly mapped? - BEQ %FT19 - - ADD lr, v1, v5 ; address of second copy - CMP lr, v2 - BHS %FT32 - LDR v3, [a4, lr, LSR #(20-2)] - MOV lr, v3, LSR #20 ; physical address bits - CMP lr, a2, LSR #20 - BNE %BT10 ; no address match - AND lr, v3, v7 - TEQ lr, a1 - BNE %BT10 ; no flags match - -19 -; -; alright, found start of requested IO already mapped, and with required flags -; - Push "a2, v1" -20 - ADD a2, a2, #&100000 - CMP a2, a3 - Pull "a2, v1", HS - BHS %FT40 ; its all there already! - ADD v1, v1, #&100000 ; next mapped IO section - CMP v1, v2 - BHS %FT30 ; no more currently mapped IO - LDR v3, [a4, v1, LSR #(20-2)] ; L1PT entry - MOV lr, v3, LSR #20 ; physical address bits - CMP lr, a2, LSR #20 - BNE %FT29 ; address match failed - AND lr, v3, v7 - TEQ lr, a1 - TEQEQ v5, #0 ; doubly mapped? - BEQ %BT20 ; address and flags match so far - ADD lr, v1, v5 ; where duplicate should be - CMP lr, v2 - BHS %FT30 ; no more currently mapped IO - LDR v3, [a4, lr, LSR #(20-2)] - MOV lr, v3, LSR #20 ; physical address bits - CMP lr, a2, LSR #20 - BNE %FT29 ; address match failed - AND lr, v3, v7 - TEQ lr, a1 - BEQ %BT20 -29 - Pull "a2, v1" - B %BT10 -30 - Pull "a2, v1" -; -; request not currently mapped, only partially mapped, or mapped with wrong flags -; -32 - MOV ip, #ZeroPage - LDR v2, [ip, #IOAllocPtr] - ADD v1, v2, a2 - SUB v1, v1, a3 ; attempt to allocate size of a3-a2 - SUB v1, v1, v5 ; double if necessary - LDR v3, [ip, #IOAllocLimit] ; can't extend down below limit - CMP v1, v3 - MOVLS a1, #0 - BLS %FT90 - STR v1, [ip, #IOAllocPtr] - ORR a2, a2, a1 - ORR a2, a2, #L1_Section ; first L1PT value -34 - STR a2, [a4, v1, LSR #(20-2)] - TEQ v5, #0 - ADDNE v2, v1, v5 - STRNE a2, [a4, v2, LSR #(20-2)] - ADD a2, a2, #&100000 - ADD v1, v1, #&100000 ; next section - CMP a2, a3 - BLO %BT34 - LDR v1, [ip, #IOAllocPtr] -40 - ADD a1, v1, v4 ; logical address for request -90 - EXIT - - -; void RISCOS_AddDevice(unsigned int flags, struct device *d) -RISCOS_AddDevice - ADDS a1, a2, #0 ; also clears V - B HardwareDeviceAdd_Common - -; uint32_t RISCOS_LogToPhys(const void *log) -RISCOS_LogToPhys - Push "r4,r5,r8,r9,lr" - MOV r4, a1 - LDR r8, =L2PT - BL logical_to_physical - MOVCC a1, r5 - MOVCS a1, #-1 - Pull "r4,r5,r8,r9,pc" - - -SetUpHALEntryTable ROUT - LDR a1, =ZeroPage - LDR a2, [a1, #HAL_Descriptor] - LDR a3, [a1, #HAL_Workspace] - LDR a4, [a2, #HALDesc_Entries] - LDR ip, [a2, #HALDesc_NumEntries] - ADD a4, a2, a4 ; a4 -> entry table - MOV a2, a4 ; a2 -> entry table (increments) -10 SUBS ip, ip, #1 ; decrement counter - LDRCS a1, [a2], #4 - MOVCC pc, lr - TEQ a1, #0 - ADREQ a1, NullHALEntry - ADDNE a1, a4, a1 ; convert offset to absolute - STR a1, [a3, #-4]! ; store backwards below HAL workspace - B %BT10 - -NullHALEntry - MOV pc, lr - -; Can freely corrupt r10-r12 (v7,v8,ip). -HardwareSWI - AND ip, v5, #&FF - CMP ip, #1 - BLO HardwareCall - BEQ HardwareLookup - CMP ip, #3 - BLO HardwareDeviceAdd - BEQ HardwareDeviceRemove - CMP ip, #5 - BLO HardwareDeviceEnumerate - BHS HardwareBadReason - -HardwareCall - Push "v1-v4,sb,lr" - ADD v8, sb, #1 ; v8 = entry no + 1 - MOV ip, #0 - LDR v7, [ip, #HAL_Descriptor] - AddressHAL ip ; sb set up - LDR v7, [v7, #HALDesc_NumEntries] ; v7 = number of entries - CMP v8, v7 ; entryno + 1 must be <= number of entries - BHI HardwareBadEntry2 - LDR ip, [sb, -v8, LSL #2] - ADR v7, NullHALEntry - TEQ ip, v7 - BEQ HardwareBadEntry2 - MOV lr, pc - MOV pc, ip - ADD sp, sp, #4*4 - Pull "sb,lr" - ExitSWIHandler - -HardwareLookup - ADD v8, sb, #1 ; v8 = entry no + 1 - MOV ip, #0 - LDR v7, [ip, #HAL_Descriptor] - AddressHAL ip - LDR v7, [v7, #HALDesc_NumEntries] - CMP v8, v7 ; entryno + 1 must be <= number of entries - BHI HardwareBadEntry - LDR a1, [sb, -v8, LSL #2] - ADR v7, NullHALEntry - TEQ a1, v7 - BEQ HardwareBadEntry - MOV a2, sb - ExitSWIHandler - -HardwareDeviceAdd - Push "r1-r3,lr" - BL HardwareDeviceAdd_Common - Pull "r1-r3,lr" - B SLVK_TestV - -HardwareDeviceRemove - Push "r1-r3,lr" - BL HardwareDeviceRemove_Common - Pull "r1-r3,lr" - B SLVK_TestV - -HardwareDeviceAdd_Common - Entry - BL HardwareDeviceRemove_Common ; first try to remove any device already at the same address - EXIT VS - MOV lr, #0 - LDR r1, [lr, #DeviceCount] - LDR r2, [lr, #DeviceTable] - TEQ r2, #0 - BEQ %FT80 - ADD r1, r1, #1 ; increment DeviceCount - LDR lr, [r2, #-4] ; word before heap block is length including length word - TEQ r1, lr, LSR #2 ; block already full? - BEQ %FT81 - MOV lr, #0 -10 STR r1, [lr, #DeviceCount] - ADD lr, r2, r1, LSL #2 - SUB lr, lr, #4 -11 LDR r1, [lr, #-4]! ; copy existing devices up, so new ones get enumerated first - STR r1, [lr, #4] - CMP lr, r2 - BHI %BT11 - STR r0, [r2] - MOV r2, r0 - MOV r1, #Service_Hardware - MOV r0, #0 - BL Issue_Service - ADDS r0, r2, #0 ; exit with V clear - EXIT - -80 ; Claim a system heap block for the device table - Push "r0" - MOV r3, #16 - BL ClaimSysHeapNode - ADDVS sp, sp, #4 - EXIT VS - Pull "r0" - MOV lr, #0 - MOV r1, #1 - STR r2, [lr, #DeviceTable] - B %BT10 - -81 ; Extend the system heap block - Push "r0" - MOV r0, #HeapReason_ExtendBlock - MOV r3, #16 - BL DoSysHeapOpWithExtension - ADDVS sp, sp, #4 - EXIT VS - Pull "r0" - MOV lr, #0 - LDR r1, [lr, #DeviceCount] - STR r2, [lr, #DeviceTable] - ADD r1, r1, #1 - B %BT10 - -HardwareDeviceRemove_Common - Entry "r4" - MOV lr, #0 - LDR r3, [lr, #DeviceCount] - LDR r4, [lr, #DeviceTable] - TEQ r3, #0 - EXIT EQ ; no devices registered -01 LDR r2, [r4], #4 - SUBS r3, r3, #1 - TEQNE r2, r0 - BNE %BT01 - TEQ r2, r0 - EXIT NE ; this device not registered - MOV r0, #1 - MOV r1, #Service_Hardware - BL Issue_Service - CMP r1, #0 ; if service call claimed - CMPEQ r1, #1:SHL:31 ; then set V (r0 already points to error block) - EXIT VS ; and exit - MOV r0, r2 - SUBS r3, r3, #1 -02 LDRCS r2, [r4], #4 ; copy down remaining devices - STRCS r2, [r4, #-8] - SUBCSS r3, r3, #1 - BCS %BT02 - MOV lr, #0 - LDR r3, [lr, #DeviceCount] - SUB r3, r3, #1 - STR r3, [lr, #DeviceCount] - EXIT - -HardwareDeviceEnumerate - Push "r3-r4,lr" - MOV lr, #0 - LDR r2, [lr, #DeviceCount] - LDR r3, [lr, #DeviceTable] - SUBS r4, r2, r1 - MOVLS r1, #-1 - BLS %FT90 ; if r1 is out of range then exit - ADD r3, r3, r1, LSL #2 -10 ADD r1, r1, #1 - LDR r2, [r3], #4 - LDR lr, [r2, #HALDevice_Type] - EOR lr, lr, r0 - MOVS lr, lr, LSL #16 ; EQ if types match - SUBNES r4, r4, #1 - BNE %BT10 - TEQ lr, #0 - MOVNE r1, #-1 - BNE %FT90 - LDR lr, [r2, #HALDevice_Version] - MOV lr, lr, LSR #16 - CMP lr, r0, LSR #16 ; newer than our client understands? - BHI %BT10 -90 - Pull "r3-r4,lr" - ExitSWIHandler - -HardwareBadReason - ADR r0, ErrorBlock_HardwareBadReason - [ International - Push "lr" - BL TranslateError - Pull "lr" - ] - B SLVK_SetV - -HardwareBadEntry2 - ADD sp, sp, #4*4 - Pull "sb,lr" -HardwareBadEntry - ADR r0, ErrorBlock_HardwareBadEntry - [ International - Push "lr" - BL TranslateError - Pull "lr" - ] - B SLVK_SetV - - MakeErrorBlock HardwareBadReason - MakeErrorBlock HardwareBadEntry - - [ DebugTerminal -DebugTerminal_Rdch - Push "a2-a4,sb,ip" - WritePSRc SVC_mode, r1 - MOV sb, ip -20 - CallHAL HAL_DebugRX - CMP a1, #27 - BNE %FT25 - LDR a2, =OsbyteVars + :INDEX: RS423mode - LDRB a2, [a2] - TEQ a2, #0 ; is RS423 raw data,or keyb emulator? - BNE %FT25 - MOV a2, #0 - LDRB a1, [a2, #ESC_Status] - ORR a1, a1, #&40 - STRB a1, [a2, #ESC_Status] ; mark escape flag - MOV a1, #27 - SEC ; tell caller to look carefully at R0 - Pull "a2-a4,sb,ip,pc" -25 - CMP a1, #-1 - Pull "a2-a4,sb,ip,pc",NE ; claim it - MOV R0, #0 - LDRB R14, [R0, #CallBack_Flag] - TST R14, #CBack_VectorReq - BLNE process_callback_chain - B %BT20 - - -DebugTerminal_Wrch - Push "a1-a4,sb,ip,lr" - MOV sb, ip - CallHAL HAL_DebugTX - Pull "a1-a4,sb,ip,pc" ; don't claim it - ] - - [ DebugHALTX -DebugHALPrint - Push "a1-a4,v1,sb,ip" - AddressHAL - MOV v1, lr -10 LDRB a1, [v1], #1 - TEQ a1, #0 - BEQ %FT20 - CallHAL HAL_DebugTX - B %BT10 -20 MOV a1, #13 - CallHAL HAL_DebugTX - MOV a1, #10 - CallHAL HAL_DebugTX - ADD v1, v1, #3 - BIC lr, v1, #3 - Pull "a1-a4,v1,sb,ip" - MOV pc, lr - ] - -Reset_IRQ_Handler - SUB lr, lr, #4 - Push "a1-a4,sb,ip,lr" - MRS lr, SPSR - Push "lr" - MOV a1, #ZeroPage - AddressHAL a1 - LDR a2, [a1, #IICType] - TST a2, #IICFlag_Background - MOVNE ip, sb - BLNE IICIRQ - MOV a1, #InitIRQWs - LDRB a1, [a1, #KbdScanActive] - TEQ a1, #0 - CallHAL HAL_KbdScanInterrupt,NE - Pull "lr" - MSR SPSR_cxsf, lr - Pull "a1-a4,sb,ip,pc",,^ - - END - diff --git a/s/HeapMan b/s/HeapMan deleted file mode 100644 index 662009a4..00000000 --- a/s/HeapMan +++ /dev/null @@ -1,1637 +0,0 @@ -; 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 => HeapMan : Heap Allocation SWI - -; Interruptible heap SWI. - -; Look down the IRQ stack to see if anybody was in a heap operation. -; If they were, then (with IRQs off) the foreground call is done first, by -; picking up info from a fixed block. Patch the IRQ stack so that the heap SWI -; is returned to at a "it happened in the background" fixup routine. Current -; request can then be dealt with! Ta Nick. - - -; Also has an interlock on the register restore area; otherwise anybody -; with an IRQ process doing heap ops with interrupts enabled will cause -; trouble. - - GBLL TubeInfo -TubeInfo SETL {FALSE} - - GBLL debheap -debheap SETL 1=0 - - [ DebugHeaps -FreeSpaceDebugMask * &04000000 -UsedSpaceDebugMask * &08000000 - ] - -Nil * 0 - -hpd RN r1 ; The punter sees these -addr RN r2 -size RN r3 - -HpTemp RN r10 ; But not these -tp RN r11 -bp RN r12 -work RN r4 ; This is the only one we have to save. - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; + H E A P O R G A N I S A T I O N + -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; A heap block descriptor (hpd) has the form - -; +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ -+ -+ -+ -+ -; | magic | free | base | end | debug | -; +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+- +- +- +- + -; 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 - - ^ 0, hpd -hpdmagic # 4 -hpdfree # 4 -hpdbase # 4 -hpdend # 4 ; Needed for debugging heap, and top end validation - [ debheap -hpddebug # 4 ; 0 -> No debug, ~0 -> Debug - ] - -hpdsize * @-hpdmagic - -magic_heap_descriptor * (((((("p":SHL:8)+"a"):SHL:8)+"e"):SHL:8)+"H") - -; hpdmagic is a unique identification field -; hpdfree is the offset of the first block in the free space list -; hpdbase is the offset of the byte above the last one used -; hpdend is the offset of the byte above the last one usable - -; | hpdbase -; \|/ -; +---+--------------------+--------+ -; low |hpd| heap blocks | unused | high -; +---+--------------------+---------+ -; /|\ /|\ -; | hpdfree | hpdend -; | in here somewhere. - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; Blocks in the free space list have the form : - -; +--+--+--+--+--+--+--+--+--+ ~ -+--+ -; | long link | long size | | -; +--+--+--+--+--+--+--+--+--+ ~ -+--+ -; 0 1 2 3 4 5 6 7 8 (size-1) -; -; where the link field is an offset to the next free block - - ^ 0 ; Can't use register relative unfortunately as many regs used -frelink # 4 -fresize # 4 -freblksize # 0 - -; The link field is Nil (0) for the last block in the list - -; Block sizes must be forced to a multiple of 8 bytes for subsequent link and -; size information to be stored in them if they are disposed of by the user. - -; They must also be capable of storing a 4 byte size field while allocated. -; This field is used to size the block to free when FreeArea is called. - - - ALIGN - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; The Macros -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; Check hpd valid - - MACRO -$label ValidateHpd $faildest -$label BL ValidateHpdSubr - BNE $faildest._badhpd - MEND - - -;**************************************************************************** - -; These bits of ExtendBlock are outside the IRQ HeapOp range because they -; don't update the heap structure, so we can safely restore old IRQ status - -CopyBackwardsInSafeZone - LDR work, [stack, #3*4] ; get user link - ANDS work, work, #I_bit ; look at I_bit - - WritePSRc SVC_mode, work, EQ ; if was clear then clear it now - - ADD bp, bp, #4 ; new block pointer - STR bp, [stack] ; return to user - -; copy wackbords: HpTemp-4 bytes from addr+4 to bp, in appropriate order! -cpe_prev - SUBS HpTemp, HpTemp, #4 - LDRGT work, [addr, #4]! - STRGT work, [bp], #4 - BGT cpe_prev - - WritePSRc SVC_mode + I_bit, work; disable IRQs before we venture back - B GoodExtension ; into danger zone - -ReallocateInSafeZone - LDR work, [addr, hpd]! ; get block size, set block addr - ADD size, size, work - SUB size, size, #4 ; block size to claim - ADD addr, addr, #4 - MOV bp, addr ; address to copy from - Push addr ; save for later freeing - - MOV R0, #HeapReason_Get - SWI XOS_Heap - Pull addr, VS - BVS SafeNaffExtension - - [ debheap - LDR HpTemp, hpddebug - CMP HpTemp, #0 - BEQ %FT06 - DREG work, "got new block : copying " -06 - ] - - STR addr, [stack, #4] - -; claimed : copy work-4 bytes from bp to addr -CopyForExtension - SUBS work, work, #4 - LDRGT HpTemp, [bp],#4 - STRGT HpTemp, [addr],#4 - BGT CopyForExtension - -; free the old block! - - [ debheap - LDR HpTemp, hpddebug - CMP HpTemp, #0 - BEQ %FT08 - WRLN "freeing old block" -08 - ] - -; recursive SWI to free old block; we have invalidated any held information - - MOV R0, #HeapReason_Free - Pull addr ; heap block addr - SWI XOS_Heap - - MOV R0, #HeapReason_ExtendBlock - WritePSRc SVC_mode + I_bit,work ; disable IRQs before we venture back - B GoodExtension ; into danger zone - -SafeNaffExtension - WritePSRc SVC_mode + I_bit,work ; disable IRQs before we venture back - B NaffExtension ; into danger zone - - -;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; Here's the bit that gets returned to if the heap op was done in the -; background. Pick up the registers, look at the saved PSR to see if error -; return or OK. -; This bit musn't be in range of the IRQ Heap Op checking!!! -;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -heapopdoneinbackground ROUT - LDR R12, =HeapReturnedReg_R0 - - [ TubeInfo - LDR R0, [R12] - BL TubeDumpR0 - LDR R0, [R12, #4] - BL TubeDumpR0 - LDR R0, [R12, #8] - BL TubeDumpR0 - LDR R0, [R12, #24] - TST R0, #V_bit - MOVEQ R0, #"v" - MOVNE R0, #"V" - TubeChar R1, R2, "MOV R2, r0" - TubeChar R0, R1, "MOV R1, #10" - TubeChar R0, R1, "MOV R1, #13" - ] - - LDMIA R12, {R0-R4, R10, R11} - MOV stack, R10 - MOV R10, #0 - STR R10, [R12, #HeapReturnedReg_PSR-HeapReturnedReg_R0] - ; clear the interlock - TST R11, #V_bit ; look at returned error - BEQ GoodHeapExit - B NaffHeapExit - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; -; HeapEntry. SWI level entry -; ========= -; -; Perform actions on the heap block described by r1(hpd) - -; In r0 = heap action requested -; r1(hpd) -> heap block -; r2(addr) -> start of block -; r3(size) = size of block - -; Out VClear -> Action performed -; VSet -> Something terrible has happened, error set -; Rest of universe ok - -HeapEntry ROUT - Push lr - SavePSR lr ; hang on to interrupt state - - ; First check that we aren't in an interrupted Heap Op - WritePSRc SVC_mode+I_bit, R11 - MOV R11, #IRQsema -inspect_IRQ_stack - LDR R11, [R11] - CMP R11, #0 - BEQ iis_end - LDR R10, [R11, #4*8] ; Get LR from IRQ stack - ADR R12, first_heap_address_to_trap - CMP R10, R12 - ADRGEL R12, HeapCode_end - CMPGE R12, R10 - BLT inspect_IRQ_stack - - ; somebody's in the heap code! Time for perversion. - ; Pick up registers, do foreground op, poke IRQstack return address - - ADRL R10, heapopdoneinbackground - STR R10, [R11, #4*8] ; return address zapped - LDR R10, [R11, #4*6] ; get stored SPSR - BIC R10, R10, #&FF - ORR R10, R10, #I32_bit:OR:SVC2632 - STR R10, [R11, #4*6] ; return into SVC26/32 mode with IRQs disabled - - Push "R0-R3, lr" - - LDR R10, =HeapSavedReg_R0 - -; This can't happen: heap ops are non-interruptible while foreground ops -; are waiting to complete -; LDR R12, [R10, #HeapReturnedReg_PSR-HeapSavedReg_R0] -; CMP R12, #0 -; BNE HeapInUse - - LDMIA R10, {R0-R3, R10, R11} - SWI XOS_Heap ; with interrupts off! - LDR R12, =HeapReturnedReg_R0 - - ; Could we poke these into the IRQ stack too...? - ; would allow interruptible IRQ processes to do heap ops!!! - MRS lr, CPSR - STMIA R12, {R0-R3, R10, R11, lr} - Pull "R0-R3, lr" - -iis_end ; store the registers in the info block - LDR R12, =HeapSavedReg_R0 - STMIA R12, {R0-R4, stack} - -first_heap_address_to_trap ; because register saveblock now set. - LDR R12, [R12, #HeapReturnedReg_PSR-HeapSavedReg_R0] - CMP R12, #0 - RestPSR lr, EQ ; restore callers interrupt state - ; only if no foreground waiting to - ; complete - - CMP r0, #MaxHeapCode ; now despatch it. - ADDLS pc, pc, r0, LSL #2 ; Tutu : faster & shorter - B NaffHeapReason ; Return if unknown call reason - -HeapJumpTable ; Check reason codes against Hdr:Heap defs - - assert ((.-HeapJumpTable) :SHR: 2) = HeapReason_Init - B InitHeap - assert ((.-HeapJumpTable) :SHR: 2) = HeapReason_Desc - B DescribeHeap - assert ((.-HeapJumpTable) :SHR: 2) = HeapReason_Get - B GetArea - assert ((.-HeapJumpTable) :SHR: 2) = HeapReason_Free - B FreeArea - assert ((.-HeapJumpTable) :SHR: 2) = HeapReason_ExtendBlock - B ExtendBlock - assert ((.-HeapJumpTable) :SHR: 2) = HeapReason_ExtendHeap - B ExtendHeap - assert ((.-HeapJumpTable) :SHR: 2) = HeapReason_ReadBlockSize - B ReadBlockSize - [ debheap - B ShowHeap - ] -MaxHeapCode * (.-HeapJumpTable-4) :SHR: 2 ; Largest valid reason code - - -NaffHeapReason - ADR R0, ErrorBlock_HeapBadReason - [ International - BL TranslateError - ] -NaffHeapExit ; get here with R0 = error ptr - SETV -GoodHeapExit ; V cleared on entry to SWI dispatch - SETPSR I_bit, R12 ; IRQs off - Pull lr - ORRVS lr, lr, #V_bit ; VSet Exit - - ExitSWIHandler ; Like all good SWI handlers - -;HeapInUse -; $HeapBadAsModuleBRA -; SetBorder R10, R11, 15, 0, 0 -; $HeapBadAsModuleKET - -; ADR R0, ErrorBlock_HeapFail_HeapLocked -; B NaffHeapExit - -; Errors - MakeErrorBlock HeapBadReason - MakeErrorBlock HeapFail_Init - MakeErrorBlock HeapFail_BadDesc - MakeErrorBlock HeapFail_BadLink - MakeErrorBlock HeapFail_Alloc - MakeErrorBlock HeapFail_NotABlock - MakeErrorBlock HeapFail_BadExtend - MakeErrorBlock HeapFail_ExcessiveShrink -; MakeErrorBlock HeapFail_HeapLocked - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; Subroutine to validate heap pointer -; checks hpd points at existing LogRam -; and also that internal offsets fall into the same block of RAM - -ValidateHpdSubr - Push "R0-R3, lr" - - SavePSR R3 - WritePSRc SVC_mode+I_bit, R0 ; interrupts off for validation - MOV R0, hpd - ADD R1, hpd, #hpdsize+freblksize - SWI XOS_ValidateAddress - BCS vhpds_fail - - TST R0, #3 ; check alignment - LDREQ HpTemp, =magic_heap_descriptor - LDREQ tp, [R0, #:INDEX: hpdmagic] - CMPEQ tp, HpTemp - BNE vhpds_fail ; failure - - LDR R1, [R0, #:INDEX: hpdend] - ADD R1, R1, R0 - SWI XOS_ValidateAddress - BCS vhpds_fail ; failure - - ORR R3, R3, #Z_bit ; success - RestPSR R3 - Pull "R0-R3, PC" - -vhpds_fail - BIC R3, R3, #Z_bit ; NE returned ; fails - RestPSR R3 - Pull "R0-R3, PC" - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; -; InitHeap. Top level HeapEntry -; ======== -; -; Initialise a heap descriptor block - -; In : hpd -> block to initialise, size = size of block - -; Out : VClear -> Block initialised -; VSet -> Something terrible has happened -; Rest of universe ok - -; To initialise (or even reinitialise) a heap descriptor: -; $( -; hpd!magic := magic_heap_descriptor -; hpd!free := Nil -; hpd!base := hpdsize -; hpd!end := size -; $) - -InitHeap ROUT - CMP size,#hpdsize+freblksize - BLT NaffHeapInitialise ; can't get hpd and 1 block in - - Push "R0, R1" - MOV R0, hpd - ADD R1, hpd, size - SWI XOS_ValidateAddress - Pull "R0, R1" - BCS NaffHeapInitialise - - [ DebugHeaps - ORR lr, hpd, #FreeSpaceDebugMask ; form word to store throughout heap - ADD HpTemp, hpd, size ; HpTemp -> end of heap -10 - STR lr, [HpTemp, #-4]! ; store word, pre-decrementing - TEQ HpTemp, hpd ; until we get to start - BNE %BT10 - ] - - LDR HpTemp, =magic_heap_descriptor - STR HpTemp, hpdmagic ; hpd!magic := magic_heap_desc - MOV HpTemp, #Nil - STR HpTemp, hpdfree ; hpd!free := Nil - MOV HpTemp, #hpdsize - STR HpTemp, hpdbase ; hpd!base := hpdsize - STR size, hpdend ; hpd!end := size - - [ debheap - MOV HpTemp, #0 ; No debugging until the punter sets this Word - STR HpTemp, hpddebug - ] - B GoodHeapExit - -NaffHeapInitialise - [ debheap - WRLN "Unaligned/too big hpd/size: InitHeap failed" - ] - ADR R0, ErrorBlock_HeapFail_Init - [ International - BL TranslateError - ] - B NaffHeapExit ; VSet exit - - LTORG - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; -; DescribeHeap. Top level HeapEntry -; ============ -; -; Return information about the heap whose descriptor is pointed to by hpd - -; In : hpd -> heap descriptor - -; Out : VClear -> addr = max block size claimable, size = total free store -; VSet -> Something wrong -; Rest of universe ok - -DescribeHeap ROUT - ValidateHpd describefailed - - [ debheap - LDR HpTemp, hpddebug - CMP HpTemp, #0 - BEQ %FT00 - Push link - WRLN "DescribeHeap" - BL iShowHeap - Pull link -00 - ] - LDR addr, hpdend - LDR HpTemp, hpdbase - - SUB addr, addr, HpTemp ; unused area at base to end - MOV size, addr - - LDR bp, hpdfree - ADR tp, hpdfree - ADD HpTemp, HpTemp, hpd ; address of end of allocated memory - B %FT20 - - -; Main loop chaining up free space list. size = total, addr = maxvec - -15 ADD tp, tp, bp ; get address of next - CMP tp, HpTemp - BHS describefailed_badlink ; points outside allocated memory - LDR bp, [tp, #fresize] ; Size of this block. - CMP bp, addr ; if size > maxvec then maxvec := size - MOVHI addr, bp - ADD size, size, bp ; tfree +:= size - LDR bp, [tp, #frelink] ; Get offset to next block -20 CMP bp,#Nil ; we know Nil is 0! - BLT describefailed_badlink ; -ve are naff - BNE %BT15 - - CMP addr, #0 - SUBGT addr, addr, #4 ; max block claimable - B GoodHeapExit ; VClear Exit - - -describefailed_badhpd - [ debheap - WRLN "Invalid heap descriptor: DescribeHeap failed" - ] - ADR R0, ErrorBlock_HeapFail_BadDesc - [ International - BL TranslateError - ] - B NaffHeapExit ; VSet Exit - -describefailed_badlink - [ debheap - WRLN "Invalid heap link: DescribeHeap failed" - ] - ADR R0, ErrorBlock_HeapFail_BadLink - [ International - BL TranslateError - ] - B NaffHeapExit ; VSet Exit - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; -; GetArea. Top level HeapEntry -; ======= -; -; Allocate a block of memory from the heap - -; This will allocate the first block of sufficiently large size in the free -; list, with an oversize block being split. -; Failure to find a large enough block on the free list will try to claim -; space out of the heap block. -; Fails if requesting size = 0 - -; In : hpd -> heap pointer, size = size of block required - -; Out : VClear : addr -> got a block -; VSet : addr = 0, couldn't get block -; Rest of universe ok - -GetArea ROUT - Push "size" - ValidateHpd garfailed - - [ debheap -; HpTemp not critical - LDR HpTemp, hpddebug - CMP HpTemp, #0 - BEQ %FT00 - Push "r0, link" - MOV r0, size - DREG r0, "GetArea " - BL iShowHeap - Pull "r0, link" -00 - ] - - CMP size, #0 ; Can't deallocate 0, so there! - BLE garfailed_zero ; And -ve is invalid as well! - ; note sizes of many megabytes thrown out by looking. - - ADD size, size, #(freblksize-1)+4 ; Make block size granular - BIC size, size, #(freblksize-1) ; with size field added - - ADR addr, hpdfree-frelink ; addr:= @(hpd!free)-frelink - -garloop - LDR tp, [addr, #frelink] ; tp := addr!fre.link - CMP tp, #Nil ; Is this the end of the chain ? - BEQ garmore ; - so try main blk - ADD addr, addr, tp ; convert offset - LDR HpTemp, [addr, #fresize] ; If length < size then no good - SUBS HpTemp, HpTemp, size ; In case this works, for below split - BLO garloop - -; Now addr -> a block on the free space list that our item will fit in -; If we have an exact fit (or as close as the granularity of the free list will -; allow), unlink this block and return it - - BNE SplitFreeBlock - - [ debheap - LDR HpTemp, hpddebug - CMP HpTemp, #0 - BEQ %FT60 - WRLN "Got an exact fit block" -60 - ] - - LDR HpTemp, [addr, #frelink] ; Move this block's link field - CMP HpTemp, #Nil - ADDNE HpTemp, HpTemp, tp ; convert offset into offset from - ; previous block - WritePSRc SVC_mode+I_bit, lr - ASSERT frelink=0 - STR HpTemp, [addr, -tp] ; store in link of previous block - B ResultIsAddrPlus4 - -SplitFreeBlock -; Need to split the free block, returning the end portion to the caller - - [ debheap -; HpTemp critical - Push HpTemp - LDR HpTemp, hpddebug - CMP HpTemp, #0 - BEQ %FT70 - WRLN "Splitting free block" -70 - Pull HpTemp - ] - - WritePSRc SVC_mode+I_bit, lr - STR HpTemp, [addr, #fresize] ; Adjust size of free block remaining - ADD addr, addr, HpTemp ; addr -> free block just deallocated - -ResultIsAddrPlus4 - [ DebugHeaps - ORR lr, hpd, #UsedSpaceDebugMask ; form word to store throughout block - ADD HpTemp, addr, size ; HpTemp -> end of block -75 - STR lr, [HpTemp, #-4]! ; store word, pre-decrementing - TEQ HpTemp, addr - BNE %BT75 - ] - - STR size, [addr], #4 ; Store block size and increment addr - Pull "size" ; Return original value to the punter - ; Note : real size got would be an option! - B GoodHeapExit ; RESULTIS addr - - -; Got no more free blocks of length >= size, so try to allocate more heap space -; out of the block described by hpd - -garmore - [ debheap -; HpTemp not critical - LDR HpTemp, hpddebug - CMP HpTemp, #0 - BEQ %FT80 - WRLN "Trying to get more from main block" -80 - ] - - LDR addr, hpdbase - ADD tp, addr, size ; addr := (hpd!base +:= size) - LDR HpTemp, hpdend - WritePSRc SVC_mode+I_bit, lr - CMP tp, HpTemp ; See if we'd fall out of the bottom - STRLS tp, hpdbase ; Only adjust hpdbase if valid alloc - ADDLS addr, addr, hpd ; offset conversion - BLS ResultIsAddrPlus4 - [ debheap - STRIM "Not enough room to allocate in main block" - ] - -garfailed - ADR R0, ErrorBlock_HeapFail_Alloc - [ International - BL TranslateError - ] - [ debheap - WRLN " : GetArea failed" - ] -garfail_common - MOV addr, #0 ; addr := 0 if we couldn't allocate - Pull "size" ; RESULTIS 0 - B NaffHeapExit ; VSet Exit - -garfailed_badhpd - [ debheap - STRIM "Invalid heap descriptor" - ] - ADR R0, ErrorBlock_HeapFail_BadDesc - [ International - BL TranslateError - ] - B garfail_common - - [ debheap -garfailed_zero - STRIM "Can't allocate 0 or less bytes" - B garfailed - | -garfailed_zero * garfailed - ] - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; -; FreeArea. Top level HeapEntry -; ======== -; -; Return an area of store to the heap - -; In : hpd -> heap descriptor, addr -> block to free - -; Out : VClear -> block freed -; VSet -> failed to free block, size invalid -; Rest of universe ok - -; The block to be freed is matched against those on the free list and inserted -; in it's correct place, with the list being maintained in ascending address -; order. If possible, the freed block is merged with contigous blocks above -; and below it to give less fragmentation, and if contiguous with main memory, -; is merged with that. If the latter, check to see if there is a block which -; would be made contiguous with main memory by the former's freeing, and if so, -; merge that with main memory too. Phew ! - -FreeArea ROUT - Push "addr, size, work" - - [ debheap -; HpTemp not critical - LDR HpTemp, hpddebug - CMP HpTemp, #0 - BEQ %FT00 - Push "r0, link" - STRIM "FreeArea " - SUB r0, addr, hpd - SUB r0, r0, #4 - BL PrintOffsetLine - BL iShowHeap - Pull "r0, link" -00 - ] - BL FindHeapBlock - BLVC FreeChunkWithConcatenation - - Pull "addr, size, work" - BVC GoodHeapExit - B NaffHeapExit ; VSet Exit - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; -; ExtendBlock. Top level HeapEntry -; =========== -; -; Extend or reallocate existing block - -; In : hpd -> heap descriptor, addr -> block, size = size to change by - -; Out : VClear -> block freed, addr new block pointer -; VSet -> failed to extend block -; Rest of universe ok - -ExtendBlock - - Push "addr, size, work" - - [ debheap -; HpTemp not critical - LDR HpTemp, hpddebug - CMP HpTemp, #0 - BEQ %FT00 - Push "r0, link" - DREG size, "ExtendBlock by ",concat - STRIM " block at " - SUB r0, addr, hpd - SUB r0, r0, #4 - BL PrintOffsetLine - BL iShowHeap - Pull "r0, link" -00 - ] - BL FindHeapBlock - BVS NaffExtension - - ADD size, size, #freblksize-1 ; round size as appropriate : - BICS size, size, #freblksize-1 ; round up to nearest 8 - - BEQ GoodExtension ; get the easy case done. - BPL MakeBlockBigger - - RSB size, size, #0 - LDR bp, [addr, hpd] ; get block size - WritePSRc SVC_mode+I_bit, R14 - SUBS bp, bp, size ; size of block left - - [ debheap -; HpTemp not critical, GE/LT critical - BLE %FT01 - LDR HpTemp, hpddebug - CMP HpTemp, #0 - BEQ %FT01 - WRLN "Freeing part of block" -01 - CMP bp, #0 ; restore GE/Lt - ] - - MOVLE HpTemp, #-1 ; if discarding block, then - STRLE HpTemp, [stack] ; make pointer really naff. - - STRGT bp, [addr, hpd] ; update size of block left - ADDGT addr, addr, bp ; offset of block to free - STRGT size, [addr, hpd] ; construct block for freeing - - BL FreeChunkWithConcatenation ; work still set from block lookup -GoodExtension - Pull "addr, size, work" - [ DebugHeaps - ADD lr, size, #freblksize-1 ; work out how much we actually extended by - BICS lr, lr, #freblksize-1 - BEQ %FT99 ; if zero or negative - BMI %FT99 ; then nothing to do - LDR HpTemp, [addr, #-4] ; get new block size - SUB HpTemp, HpTemp, #4 ; Exclude size word itself - ADD HpTemp, addr, HpTemp ; end of new block - SUB lr, HpTemp, lr ; start of new extension - ORR bp, hpd, #UsedSpaceDebugMask -98 - STR bp, [HpTemp, #-4]! ; store word - TEQ HpTemp, lr - BNE %BT98 -99 - ] - B GoodHeapExit - -MakeBlockBigger - LDR HpTemp, [addr, hpd] ; get size - ADD HpTemp, HpTemp, addr ; block end -; TMD 01-Mar-89: FindHeapBlock now never returns tp=Nil, only tp=hpdfree, -; so no need for check - LDR bp, [tp, hpd] ; next free - CMP bp, #Nil - ADDNE bp, bp, tp - LDREQ bp, hpdbase - -; bp is potential following block - CMP HpTemp, bp - BNE try_preceding_block - -; now get size available, see if fits - - LDR HpTemp, hpdbase - CMP bp, HpTemp - ADDNE HpTemp, bp, hpd - LDRNE HpTemp, [HpTemp, #fresize] - LDREQ HpTemp, hpdend - SUBEQ HpTemp, HpTemp, bp - BICEQ HpTemp, HpTemp, #(freblksize-1) - ; force it to a sensible blocksize - MRS lr, CPSR ; save EQ/NE state - - CMP HpTemp, size - BLT try_add_preceding_block - - ORR lr, lr, #I32_bit ; disable IRQs - MSR CPSR_cf, lr - - [ debheap -; HpTemp, EQ/NE critical - Push "HpTemp,lr" - LDR HpTemp, hpddebug - CMP HpTemp, #0 - BEQ %FT02 - STRIM "Extending block into " -02 - Pull "HpTemp,lr" - msr ,CPSR_f, lr - ] - - LDR work, [addr, hpd] ; get size back - ADD work, work, size ; new size - STR work, [addr, hpd] ; block updated - -; now see which we're extending into - BNE IntoFreeEntry - - [ debheap - Push HpTemp - LDR HpTemp, hpddebug - CMP HpTemp, #0 - BEQ %FT03 - WRLN "base-end area" -03 - Pull HpTemp - ] - ADD work, work, addr - STR work, hpdbase - B GoodExtension - -IntoFreeEntry - - [ debheap - Push HpTemp - LDR HpTemp, hpddebug - CMP HpTemp, #0 - BEQ %FT04 - WRLN "free entry" -04 - Pull HpTemp - ] - - CMP HpTemp, size - BNE SplitFreeBlockForExtend - -; free entry just right size : remove from free list - LDR HpTemp, [bp, hpd] ; free link - CMP HpTemp, #Nil - ADDNE HpTemp, HpTemp, bp ; offset from heap start - SUBNE HpTemp, HpTemp, tp - STR HpTemp, [tp, hpd] ; free list updated - B GoodExtension - -SplitFreeBlockForExtend - LDR work, [tp, hpd] - ADD work, work, size - STR work, [tp, hpd] ; prevnode points at right place - ADD work, work, tp ; offset of new free entry - ADD work, work, hpd - SUB HpTemp, HpTemp, size ; new freblk size - STR HpTemp, [work, #fresize] - LDR HpTemp, [bp, hpd] - CMP HpTemp, #Nil - SUBNE HpTemp, HpTemp, size ; reduced offset for free link - STR HpTemp, [work, #frelink] - B GoodExtension - -try_preceding_block -; TMD 01-Mar-89: FindHeapBlock now never returns tp=Nil, only tp=hpdfree, -; so no need for check - CMP tp, #:INDEX: hpdfree ; no real preceder? - BEQ got_to_reallocate - ADD bp, tp, hpd - LDR bp, [bp, #fresize] - ADD bp, bp, tp ; end of preceding block - CMP addr, bp - BNE got_to_reallocate - -; now get size available, see if fits - - SUB bp, bp, tp ; freblk size - SUBS bp, bp, size ; compare, find free size left - BLT got_to_reallocate - - [ debheap - Push "HpTemp,lr" - LDR HpTemp, hpddebug - CMP HpTemp, #0 - BEQ %FT10 - CMP bp, #0 - BEQ %FT11 - STRIM "Extending block into previous free" - B %FT12 -11 - STRIM "Previous free perfect fit" -12 - SWI XOS_NewLine -10 - Pull "HpTemp,lr" - ] - - WritePSRc SVC_mode+I_bit, HpTemp ; IRQs off - -hack_preceder -; bp is new size of preceding block -; tp is prevfree offset -; work is prevprevfree offset -; size is amount block grows by -; addr is block offset - CMP bp, #0 - ADDNE HpTemp, tp, hpd - STRNE bp, [HpTemp, #fresize] ; prevblock shrunk - BNE copy_backwards - - ; free freblk: work is still prevprevblk pointer - LDR HpTemp, [tp, hpd] - CMP HpTemp, #Nil - ADDNE HpTemp, HpTemp, tp ; offset from heap start - SUBNE HpTemp, HpTemp, work - STR HpTemp, [work, hpd] ; free list updated - -copy_backwards - ADD bp, bp, tp - LDR HpTemp, [addr, hpd]! ; current block size - ADD size, HpTemp, size - STR size, [bp, hpd]! ; update blocksize - - [ debheap - Push r0 - LDR r0, hpddebug - CMP r0, #0 - BEQ %FT06 - DREG HpTemp, "copying -4+",concat - STRIM " from " - SUB R0, addr, hpd - BL PrintOffset - STRIM " to " - SUB R0, bp, hpd - BL PrintOffsetLine -06 - Pull r0 - ] - -; TMD 02-Mar-89: We've finished messing about with the heap structure -; so we can branch outside danger zone and restore IRQ status while doing copy - B CopyBackwardsInSafeZone - -try_add_preceding_block - [ {TRUE} -; HpTemp is size of following block - CMP tp, #:INDEX: hpdfree ; no real preceder? - BEQ got_to_reallocate - Push "work, size" ; need prevprevblk ptr - SUB size, size, HpTemp ; size still needed - ADD HpTemp, tp, hpd - LDR HpTemp, [HpTemp, #fresize] - ADD HpTemp, HpTemp, tp ; end of preceding block - CMP addr, HpTemp - BNE got_to_reallocate2 - -; now get size available, see if fits - - SUB HpTemp, HpTemp, tp ; freblk size - SUBS HpTemp, HpTemp, size - BLT got_to_reallocate2 - - [ debheap - Push "HpTemp,lr" - LDR HpTemp, hpddebug - CMP HpTemp, #0 - BEQ %FT10 - Pull HpTemp - CMP HpTemp, #0 - BEQ %FT11 - STRIM "Extending block into previous free and block after" - B %FT12 -11 - STRIM "Previous free+nextblock perfect fit" -12 - SWI XOS_NewLine -10 - Pull "lr" - ] - - WritePSRc SVC_mode+I_bit, work ; IRQs off - ; delink block at bp - LDR work, hpdbase - CMP bp, work ; extend into free, or delink block? - BNE ext_delink - LDR work, hpdend - SUB work, work, bp ; get back real size - BIC work, work, #(freblksize-1) - ADD work, work, bp - STR work, hpdbase ; all free allocated - B ext_hack -ext_delink - LDR work, [bp, hpd] - CMP work, #Nil - ADDNE work, work, bp - SUBNE work, work, tp - STR work, [tp, hpd] ; block delinked -ext_hack - MOV bp, HpTemp - Pull "work, size" -; bp is new size of preceding block -; tp is prevfree offset -; work is prevprevfree offset -; size is amount block grows by -; addr is block offset - B hack_preceder - -got_to_reallocate2 - Pull "work, size" - ] -got_to_reallocate -; claim block of new size ; copy data -; Done by recursive SWIs: somewhat inefficient, but simple. - - [ debheap - LDR HpTemp, hpddebug - CMP HpTemp, #0 - BEQ %FT05 - WRLN "reallocating block" -05 - ] - - B ReallocateInSafeZone - -NaffExtension - Pull "addr, size, work" - B NaffHeapExit - - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; -; ExtendHeap. Top level HeapEntry -; ========== -; -; Extend or shrink heap - -; In : hpd -> heap descriptor, size = size to change by - -; Out : VClear -> heap size changed OK -; VSet -> failed to change by specified amount -; size = amount changed by - -ExtendHeap ROUT - ValidateHpd ExtendHeap - - CMP r3, #0 - ADDMI r3, r3, #3 ; round towards 0 - BIC R3, R3, #3 ; ensure word amount - - LDR HpTemp, hpdend - ADD HpTemp, HpTemp, R3 ; HpTemp := new size - LDR tp, hpdbase - CMP tp, HpTemp - BGT ExtendHeap_badshrink - - WritePSRc SVC_mode+I_bit, lr - Push "R0, R1" - MOV R0, hpd ; Ensure heap will be in valid area - ADD R1, hpd, HpTemp - SWI XOS_ValidateAddress - Pull "R0, R1" - BCS ExtendHeap_nafforf - - [ DebugHeaps - CMP R3, #0 ; if shrunk or stayed same - BLE %FT15 ; then nothing to do - ADD tp, hpd, HpTemp ; tp -> end of heap - SUB bp, tp, R3 ; bp -> start of new bit - ORR lr, hpd, #FreeSpaceDebugMask -10 - STR lr, [tp, #-4]! ; store word - TEQ tp, bp - BNE %BT10 -15 - ] - - STR HpTemp, hpdend ; uppy date him - B GoodHeapExit ; moved all the size asked for - -ExtendHeap_badhpd - ADRL R0, ErrorBlock_HeapFail_BadDesc - [ International - BL TranslateError - ] - MOV size, #0 - B NaffHeapExit - -ExtendHeap_nafforf - ADRL R0, ErrorBlock_HeapFail_BadExtend - [ International - BL TranslateError - ] - MOV size, #0 - B NaffHeapExit - -ExtendHeap_badshrink - LDR HpTemp, hpdend - STR tp, hpdend ; update heap - SUB size, HpTemp, tp ; size managed to change by - ADRL R0, ErrorBlock_HeapFail_ExcessiveShrink - [ International - BL TranslateError - ] - B NaffHeapExit ; and sort of fail - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; -; ReadBlockSize. Top level HeapEntry -; ============= -; - -ReadBlockSize - - Push "addr, work" - BL FindHeapBlock - LDRVC size, [addr, hpd] - Pull "addr, work" - BVC GoodHeapExit - B NaffHeapExit - -;************************************************************************** -; Common routines for free/extend - -FindHeapBlock ROUT -; Convert addr to address -; Validate heap -; check block is an allocated block -; return tp = free list entry before the block (hpdfree if none) -; work = free list before that (if exists) -; corrupts HpTemp, bp - - Push lr - - ValidateHpd findfailed - - SUB addr, addr, hpd ; convert to offset - SUB addr, addr, #4 ; real block posn - -; Find block in heap by chaining down freelist, stepping through blocks - -; TMD 01-Mar-89 -; no need to check explicitly for null free list, code drops thru OK - - [ debheap - LDR HpTemp, hpddebug - CMP HpTemp, #0 - BEQ %FT03 - Push lr - WRLN "Scanning freelist" - Pull lr -03 - ] - -; step down free list to find appropriate chunk -; get tp = free block before addr -; HpTemp = " " after " -; work = block before tp - - MOV tp, #:INDEX: hpdfree -StepDownFreeList - LDR HpTemp, [hpd, tp] ; link offset - CMP HpTemp,#Nil - BEQ ListEnded ; EQ state used! - ADD HpTemp, HpTemp, tp - CMP HpTemp, addr - MOVLS work, tp - MOVLS tp, HpTemp - BLS StepDownFreeList -ListEnded - LDREQ HpTemp, hpdbase ; if EQ from CMP HpTemp, addr - ; then bad block anyway - CMP tp, #:INDEX: hpdfree - MOVEQ bp, #hpdsize ; is this a fudge I see before me? - BEQ ScanAllocForAddr - ADD bp, tp, #fresize - LDR bp, [hpd, bp] - ADD bp, tp, bp - -ScanAllocForAddr -; bp -> start of allocated chunk -; HpTemp -> end " " " -; scan to find addr, error if no in here - - Push work ; keep prevlink ptr - - [ debheap -; HpTemp critical - Push "HpTemp, R0, link" - LDR HpTemp, hpddebug - CMP HpTemp, #0 - BEQ %FT02 - STRIM "Scan for addr from " - MOV R0, bp - BL PrintOffset - STRIM " to " - LDR R0,[stack,#4] ; HpTemp - BL PrintOffsetLine -02 - Pull "HpTemp, r0, link" - ] - B CheckForNullAllocn - -ScanAllocForAddrLoop - CMP bp, addr - BEQ ValidBlock - LDR work, [bp, hpd] ; get size - ADD bp, bp, work -CheckForNullAllocn - CMP bp, HpTemp - BLT ScanAllocForAddrLoop - - [ debheap - Push lr - STRIM "Given pointer not a block" - Pull lr - ] - ADRL R0, ErrorBlock_HeapFail_NotABlock - [ International - BL TranslateError - | - SETV - ] - Pull "work, pc" - -ValidBlock ; tp = free link offset, addr = block offset - CLRV - Pull "work, pc" - -findfailed_badhpd - [ debheap - Push lr - STRIM "Invalid heap descriptor" - Pull lr - ] - ADRL R0, ErrorBlock_HeapFail_BadDesc - [ International - BL TranslateError - | - SETV - ] - Pull PC - -;**************************************************************************** - -FreeChunkWithConcatenation ROUT -; in : addr -> block -; tp -> preceding free list entry -; out : block freed, concatenated with any free parts on either side, -; base reduced if can do -; corrupts HpTemp, bp, size, addr - -; TMD 01-Mar-89: FindHeapBlock now never returns tp=Nil, only tp=hpdfree, -; so no need for check, code will get there eventually! - -; attempt concatenation with free blocks on both/either side - [ debheap - Push "R0, lr" - LDR HpTemp, hpddebug - CMP HpTemp, #0 - BEQ %FT04 - STRIM "concatenation attempt with free ptr " - MOV R0,tp - BL PrintOffsetLine -04 - Pull "R0, lr" - ] - - [ DebugHeaps - ORR bp, hpd, #FreeSpaceDebugMask - LDR size, [addr, hpd]! - ADD HpTemp, addr, size - SUB HpTemp, HpTemp, #4 ; HpTemp -> last word of block -10 - STR bp, [HpTemp], #-4 ; store word, then go back - TEQ HpTemp, addr ; loop until done, but don't overwrite size field - BNE %BT10 ; otherwise we might get an IRQ with a duff heap - SUB addr, addr, hpd ; make addr an offset again - ] - - LDR size, [addr, hpd] ; block size - ADD bp, size, addr ; eob offset - LDR HpTemp, [tp, hpd] ; Nil doesn't matter here! - ADD HpTemp, HpTemp, tp ; offset of free block after ours - CMP HpTemp, bp ; if tp was hpdfree then <> bp - BNE NoConcatWithNext ; so will take branch - - [ debheap - Push lr - LDR bp, hpddebug - CMP bp, #0 - BEQ %FT05 - WRLN "concatenating with block after" -05 - Pull lr - ] - ADD bp, hpd, HpTemp - LDR bp, [bp, #fresize] - ADD bp, bp, size - WritePSRc SVC_mode+I_bit, size - STR bp, [addr, hpd] ; enlarge our block - LDR bp, [HpTemp, hpd] ; offset in free list - CMP bp, #Nil - ADDNE bp, HpTemp, bp ; offset from heap start - SUBNE bp, bp, tp ; free list offset - STR bp, [tp, hpd] ; free list updated, our block bigger - ; - but not in the free list yet! - -NoConcatWithNext ; tp = free link offset, addr = block offset - ; now try for concatenation with previous block - CMP tp, #:INDEX: hpdfree ; are we before any real free blocks? - BEQ NoConcatenation ; yup - - ADD HpTemp, tp, hpd - LDR size, [HpTemp, #fresize] - ADD bp, size, tp - CMP bp, addr - BNE NoConcatenation - [ debheap - Push lr - LDR bp, hpddebug - CMP bp, #0 - BEQ %FT06 - WRLN "concatenating with block before" - STRIM "prevfree = " - Push R0 - MOV R0, work - BL PrintOffsetLine - Pull R0 -06 - Pull lr - ] - LDR bp, [addr, hpd] ; get block size - ADD size, bp, size ; new free block size - WritePSRc SVC_mode+I_bit, bp - STR size, [HpTemp, #fresize] -; now check for butts against base : work is still prevnode to tp - ADD HpTemp, size, tp - LDR bp, hpdbase - CMP bp, HpTemp - BNE %FT06 ; all done : exit keeping IRQs off - SUB bp, bp, size - STR bp, hpdbase ; step unused bit back - MOV bp, #Nil ; this MUST have been last free block! - STR bp, [work, hpd] -06 - CLRV - MOV PC, lr ; Whew! - -NoConcatenation ; check if block butts against base -; tp = previous freelink offset - LDR size, [addr, hpd] - ADD HpTemp, size, addr - LDR bp, hpdbase - CMP bp, HpTemp - BNE AddToFreeList - SUB bp, bp, size - WritePSRc SVC_mode+I_bit, HpTemp - STR bp, hpdbase - CLRV - MOV PC, lr - -AddToFreeList ; block at addr, previous free at tp - [ debheap - Push "R0, lr" - LDR HpTemp, hpddebug - CMP HpTemp, #0 - BEQ %FT07 - STRIM "add to free list : free link " - MOV R0,tp - BL PrintOffset - STRIM ", block " - MOV R0, addr - BL PrintOffsetLine -07 - Pull "R0, lr" - ] - LDR size, [addr, hpd]! - WritePSRc SVC_mode+I_bit, HpTemp - STR size, [addr, #fresize] - SUB addr, addr, hpd - LDR size, [hpd, tp] ; prevlink - CMP size, #Nil - SUBNE size, size, addr - ADDNE size, size, tp ; form offset if not eolist - STR size, [addr, hpd] - SUB size, addr, tp - STR size, [tp, hpd] - CLRV - MOV PC, lr - -;***************************************************************************** - - [ debheap -; -; ShowHeap. Top level HeapEntry -; ======== -; -; Dump the heap pointed to by hpd - -ShowHeap - Push link - BL iShowHeap ; Needed to fudge link for SVC mode entry - Pull link - B GoodHeapExit - - -iShowHeap ROUT ; Internal entry point for debugging heap - - Push "r0, hpd, addr, size, work, bp, tp, link" - - ValidateHpd showfailed ; debugging heaps won't work interruptibly - - LDR tp, hpdfree - CMP tp, #Nil - ADDNE tp, tp, #:INDEX: hpdfree - LDR bp, hpdbase - MOV addr, #hpdsize - LDR work, hpdend - - SWI OS_NewLine ; Initial blurb about hpd contents - DREG hpd, "**** Heap map **** : hpd " - STRIM "-> free" - MOV r0, tp - BL PrintOffset - STRIM ", base" - MOV r0, bp - BL PrintOffsetLine - STRIM "-> start" - MOV r0, addr - BL PrintOffset - STRIM ", end" - MOV r0, work - BL PrintOffsetLine - - SUB r0, work, bp ; hpdend-hpdbase - DREG r0,"Bytes free: ",concat, Word - SUB r0, bp, addr ; hpdbase-hpdsize - DREG r0,", bytes used: ",, Word - SWI XOS_NewLine - - CMP tp, #Nil ; No free blocks at all ? - BNE %FT10 - WRLN "No Free Blocks" - - CMP bp, addr ; Is a block allocated at all ? - MOVNE r0, addr ; hpdsize - BNE %FT40 - WRLN "No Used Blocks" - B %FT99 - - -10 CMP tp, addr ; hpdsize ; Allocated block below first free ? - BEQ %FT15 - - MOV r0, addr ; hpdbase - BL HexUsedBlk - SUB r0, tp, addr ; hpdfree-hpdsize - DREG r0 - SWI XOS_NewLine - -; Main loop chaining up free space list - -15 ADD addr, tp, hpd ; convert to address - LDR size, [addr, #fresize] ; Size of this block - LDR addr, [addr, #frelink] ; offset to next block - - STRIM "Free Block " - MOV r0, tp - BL PrintOffset - DREG size, ", size " - - ADD r0, tp, size ; r0 -> eob. Adjacent free blocks don't exist - - CMP addr, #Nil ; If last block, then must we see if we're = hpdbase - BEQ %FT40 - -; Used block starts at r0, ends at addr+tp - so size = (addr+tp)-r0 - - BL HexUsedBlk - SUB r0, addr, r0 ; addr-r0 - ADD r0, r0, tp ; used block size - DREG r0 - SWI XOS_NewLine - - ADD tp, addr, tp ; step down free list - B %BT15 ; And loop - - -40 CMP r0, bp ; Is there any allocated space after this block ? - BEQ %FT99 - BL HexUsedBlk - SUB r0, bp, r0 ; hpdbase-sob - DREG r0 - SWI XOS_NewLine - -99 - CLRV - GRAB "r0, hpd, addr, size, work, bp, tp, pc" - - -showfailed_badhpd - WRLN "Invalid heap descriptor : ShowHeap failed" - GRAB "r0, hpd, addr, size, work, bp, tp, pc" - - -HexUsedBlk - Push "lr" - STRIM "Used Block " - BL PrintOffset - STRIM ", size" - Pull "lr" - MOV PC, R14 - -PrintOffset - Push "r0, lr" - DREG r0 - CMP R0, #0 - ADDNE R0, R0, hpd - DREG r0," (",concat - STRIM ")" - GRAB "R0, PC" - -PrintOffsetLine - Push "lr" - BL PrintOffset - SWI XOS_NewLine - Pull "PC" - - ] - - [ TubeInfo -TubeDumpR0 ROUT - Push "R1, R2, lr" - TubeChar R0, R1, "MOV R1, #10" - TubeChar R0, R1, "MOV R1, #13" - MOV R1, #7 -01 MOV R0, R0, ROR #28 - AND R2, R0, #&F - TubeChar R0, R1, "ADD R1, R2, #""0""" - SUBS R1, R1, #1 - BPL %BT01 - Pull "R1, R2, PC" - ] - -HeapCode_end - -; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - END diff --git a/s/HeapSort b/s/HeapSort deleted file mode 100644 index 9004035d..00000000 --- a/s/HeapSort +++ /dev/null @@ -1,411 +0,0 @@ -; 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 > HeapSort - -; Old API - same as OS_HeapSort32 but flags in top bits of r1 - -; Just to make this more confusing, the old API always behaves as if bit 31 -; of r1 mirrors bit 30 (ie. bit 30 set forces bit 31 set, see PRM 5a-662), so -; we preserve this for old API, but do originally intended thing for new API. - -HeapSortRoutine - Push "r1,r7,lr" - AND r7, r1, #2_011 :SHL: 29 - BIC r1, r1, #2_111 :SHL: 29 - TST r7, #1 :SHL: 30 - ORRNE r7, r7, #1 :SHL: 31 - SWI XOS_HeapSort32 - Pull "r1,r7,lr" - B SLVK_TestV - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; HeapSort routine. Borrowed from Knuth by Tutu. Labels h(i) correspond to -; steps in the algorithm. - -; In r0 = n -; r1 = array(n) of word size objects (r2 determines type) -; r2 = address of comparison procedure -; Special cases: -; 0 -> treat r(n) as array of cardinal -; 1 -> treat r(n) as array of integer -; 2 -> treat r(n) as array of cardinal* -; 3 -> treat r(n) as array of integer* -; 4 -> treat r(n) as array of char* (case insensitive) -; 5 -> treat r(n) as array of char* (case sensitive) -; r3 = wsptr for comparison procedure (only needed if r2 > 5) -; r4 = array(n) of things (only needed if r7 & &C0000000) -; r5 = sizeof(element) ( --------- ditto ---------- ) -; r6 = address of temp slot (only needed if r5 > 16K or r7 & &20000000) -; r7 = flags -; bit 31 set -> use r4,r5 on postpass -; bit 30 set -> build (r1) from r4,r5 in prepass -; bit 29 set -> use r6 as temp slot - -; r10-r12 trashable - -hs_array RN r4 -hs_procadr RN r5 -hs_i RN r6 -hs_j RN r7 -hs_K RN r8 -hs_R RN r9 -hs_l RN r10 -hs_r RN r11 -;wp RN r12 - -; User sort procedure entered in SVC mode, interrupts enabled -; r0 = contents of array(1) -; r1 = contents of array(2) -; r0-r3 may be trashed -; wp = value requested (trash at your peril; you'll get the bad one next time) - -; User sort procedure returns: -; LT: if f(r0) < f(r1) -; GE: if f(r0) => f(r1) -; (ie. N_bit and V_bit only considered) - -HeapSortRoutine32 ROUT - - CMP r0, #2 ; 0 or 1 elements? No data moved either - ExitSWIHandler LO ; VClear in lr and psr - - Push "r0-r3, hs_array, hs_procadr, hs_i, hs_j, hs_K, hs_R, lr" - - CLRPSR I_bit, r14 ; Enable interrupts (may take ages) - - [ False - STR r0, ndump ; For debugging porpoises - ] - TST r7, #1 :SHL: 30 ; Are we to build the pointer array? - BEQ %FT01 - -; Build array of pointers to data blocks for the punter if he desires this -; (lazy slobs abound ...) - -; for (i=0; i<n; i++) r(i) = &block + i*sizeof(element); - - MOV r10, r0 ; n - MOV r14, r1 ; r14 -> base of pointer array -00 STR r4, [r14], #4 - ADD r4, r4, r5 ; r4 += sizeof(element) - SUBS r10, r10, #1 - BNE %BT00 - - -01 SUB hs_array, r1, #4 ; HeapSort assumes r(1..n) not (0..n-1) - - MOV hs_procadr, r2 ; Put proc address where we need it - - CMP hs_procadr, #6 ; Special procedure ? - ADRLO r14, hs_Procedures - LDRLO hs_procadr, [r14, hs_procadr, LSL #2] - ADDLO hs_procadr, hs_procadr, r14 - - MOV wp, r3 ; Can now use r3 temp. Keep set up - ; for speed during execution - - MOV hs_l, r0, LSR #1 ; l = floor(n/2) + 1 - ADD hs_l, hs_l, #1 - MOV hs_r, r0 ; r = n - - -h2 CMP hs_l, #1 - BEQ %FT10 - - SUB hs_l, hs_l, #1 - LDR hs_R, [hs_array, hs_l, LSL #2] ; R = R(l) - MOV hs_K, hs_R - B %FT20 - -10 LDR hs_R, [hs_array, hs_r, LSL #2] ; R = R(r) - MOV hs_K, hs_R - LDR r14, [hs_array, #4] ; R(r) = R(1) - STR r14, [hs_array, hs_r, LSL #2] - SUB hs_r, hs_r, #1 - CMP hs_r, #1 ; IF r=1 THEN R(1) = R - STREQ hs_R, [hs_array, #4] -20 - [ False - BL DoDebug - ] - - CMP hs_r, #1 - BEQ %FT90 ; [finished sorting the array] - - -h3 MOV hs_j, hs_l - - -h4 MOV hs_i, hs_j - MOV hs_j, hs_j, LSL #1 - - [ False - DREG hs_i," i ",cc - DREG hs_j," j " - ] - CMP hs_j, hs_r - BEQ h6 - BHI h8 - - -h5 LDR r0, [hs_array, hs_j, LSL #2] - ; IF K(R(j)) < K(R(j+1)) THEN j +:= 1 - ADD r14, hs_j, #1 - LDR r1, [hs_array, r14, LSL #2] - - MOV lr, pc ; r0, r1 for comparison - MOV pc, hs_procadr - - ADDLT hs_j, hs_j, #1 ; Assumes signed comparison done <<<<<< - - -h6 MOV r0, hs_K ; IF K >= K(R(j)) THEN h8 - LDR r1, [hs_array, hs_j, LSL #2] - - MOV lr, pc ; r0, r1 for comparison - MOV pc, hs_procadr - - LDRLT r14, [hs_array, hs_j, LSL #2] ; R(i) = R(j) - STRLT r14, [hs_array, hs_i, LSL #2] - BLT h4 - - -h8 STR hs_R, [hs_array, hs_i, LSL #2] ; R(i) = R - B h2 - - -; Array now sorted into order - -90 LDR r14, [sp, #4*7] ; r7in - TST r14, #1 :SHL: 31 - BEQ %FA99 ; [no shuffle required, exit] - -; Reorder the blocks according to the sorted array of pointers - - LDR r2, [sp, #4*1] ; r2 -> list of pointers (r1in) - - ADD r1, sp, #4*4 - LDMIA r1, {r1, r8, r9} ; r4,r5,r6in - ; r1 -> list of blocks - [ False - DREG r2, "pointer array " - DREG r1, "base of blocks " - DREG r8, "sizeof(element) " - ] - MOV r3, r2 ; r3 -> first item of current cycle - LDR r0, [sp, #0*4] ; r0 = n - ADD r6, r2, r0, LSL #2 ; r6 -> end of array of pointers - TST r14, #1 :SHL: 29 ; punter forcing use of his temp slot? - BNE %FT94 ; fine by me! - CMP r8, #ScratchSpaceSize - LDRLS r9, =ScratchSpace ; r9 -> temp slot (normally ScratchSpc) -94 - [ False - DREG r9, "temp slot " - ] - -91 SUB r14, r3, r2 - MOV r14, r14, LSR #2 ; r14 = index (0..n-1) of current item - MLA r4, r14, r8, r1 ; r4 -> current block - - MOV r5, r3 ; r5 -> current item - BL MoveToTempSlot ; save first block in temp slot - -92 LDR r7, [r5] ; r7 -> next block - MOV r14, #0 - STR r14, [r5] ; mark item 'done' - - SUB r5, r7, r1 ; r14 := index of next item (r8 pres.) - DivRem r14, r5, r8, r0 ; r5,r0 corrupt - ADD r5, r2, r14, LSL #2 ; r5 -> next item - [ False - DREG r7, " next block " - DREG r5, " next item " - ] - - CMP r5, r3 ; reached start of cycle? - MOVEQ r7, r9 ; get back from temp slot if last one - BL MoveFromGivenSlot ; corrupts flags, but preserves r5, r3... - - CMP r5, r3 - MOVNE r4, r7 ; update r4 (current block) - BNE %BT92 - -93 LDR r14, [r3, #4]! ; skip already-copied items - CMP r3, r6 - BCS %FA99 ; [reached end] - CMP r14, #0 - BEQ %BT93 - - B %BT91 ; [found one that hasn't been copied] - - -; No error return from HeapSort - -99 Pull "r0-r3, hs_array, hs_procadr, hs_i, hs_j, hs_K, hs_R, lr" - -; SWIHandler exit takes flags + mode from lr, not psr !!! - - ExitSWIHandler - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; In r4 -> element to be copied -; r8 = sizeof(element) -; r9 -> temp slot - -; Out all preserved - -MoveToTempSlot Entry "r4, r8, r9" - - TST r4, #3 ; If base and element size wordy - TSTEQ r8, #3 ; then do faster copy. Also temp wordy - BNE %FT01 - -00 SUBS r8, r8, #4 - LDRPL r14, [r4], #4 - STRPL r14, [r9], #4 - BPL %BT00 - EXIT - -01 SUBS r8, r8, #1 - LDRPLB r14, [r4], #1 - STRPLB r14, [r9], #1 - BPL %BT01 - EXIT - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; In r4 -> where element is to be copied -; r7 -> element to be copied -; r8 = sizeof(element) - -; Out all preserved - -MoveFromGivenSlot Entry "r4, r7, r8" - - TST r4, #3 ; If dest and element size wordy - TSTEQ r8, #3 ; then do faster copy. Also src wordy - BNE %FT01 - -00 SUBS r8, r8, #4 - LDRPL r14, [r7], #4 - STRPL r14, [r4], #4 - BPL %BT00 - EXIT - -01 SUBS r8, r8, #1 - LDRPLB r14, [r7], #1 - STRPLB r14, [r4], #1 - BPL %BT01 - EXIT - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; Built-in sorting procedures - -hs_Procedures - - DCD hs_CardinalCMP - hs_Procedures - DCD hs_IntegerCMP - hs_Procedures - DCD hs_CardinalPtrCMP - hs_Procedures - DCD hs_IntegerPtrCMP - hs_Procedures - DCD hs_StringCMP - hs_Procedures - DCD hs_StringSensCMP - hs_Procedures - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; In r0, r1 -> cardinals - -; Out flags set on (*r0) - (*r1) - -hs_CardinalPtrCMP - - LDR r0, [r0] - LDR r1, [r1] - -; ............................................................................. -; In r0, r1 = cardinals - -; Out flags set on r0 - r1 - -hs_CardinalCMP - - CMP r0, r1 - MSRCS CPSR_f, #C_bit ; CS -> GE (nv) - MSRCC CPSR_f, #N_bit ; CC -> LT (Nv) - MOV pc, lr - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; In r0, r1 -> integers - -; Out flags set on (*r0) - (*r1) - -hs_IntegerPtrCMP - - LDR r0, [r0] - LDR r1, [r1] - -; ............................................................................. -; In r0, r1 = integers - -; Out flags set on r0 - r1 - -hs_IntegerCMP - - CMP r0, r1 - MOV pc, lr - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; Case-insensitive string comparison - -; In r0, r1 -> strings - CtrlChar terminated (NB. Must be same CtrlChar !) - -; Out flags set on (char *)(r0) - (char *)(r1) compare - -hs_StringCMP ROUT - -10 LDRB r2, [r0], #1 - LowerCase r2, r12 - LDRB r3, [r1], #1 - LowerCase r3, r12 - CMP r2, r3 ; Differ ? - MOVNE pc, lr ; GE or LT - CMP r2, #space-1 ; Finished ? - BHI %BT10 - - CMP r2, r2 ; return EQ (also GE) - MOV pc, lr - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; Case-sensitive string comparison - -; In r0, r1 -> strings - CtrlChar terminated (NB. Must be same CtrlChar !) - -; Out flags set on (char *)(r0) - (char *)(r1) - -hs_StringSensCMP ROUT - -10 LDRB r2, [r0], #1 - LDRB r3, [r1], #1 - CMP r2, r3 ; Differ ? - MOVNE pc, lr ; GE or LT - CMP r2, #space-1 ; Finished ? - BHI %BT10 - - CMP r2, r2 ; return EQ (also GE) - MOV pc, lr - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - LTORG - - END diff --git a/s/KbdResA1 b/s/KbdResA1 deleted file mode 100644 index aa1625bb..00000000 --- a/s/KbdResA1 +++ /dev/null @@ -1,326 +0,0 @@ -; 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. -; -; > KbdResA1 - -; This file contains all the old-style keyboard control stuff that the kernel does on reset -; The only two hooks in this file used externally are IRQ_Test_CTRL_or_R_Pressed -; and SetUpKbd. - - GBLL KeyboardDebungling -KeyboardDebungling SETL {FALSE} - -; reset code needs to know where CTRL, SHIFT and R are in the kbd matrix -; these are codes given by the keyboard - - [ Keyboard_Type = "A1A500" -A1CtrlLeft * &3B -A1CtrlRight * &61 -A1ShiftLeft * &4C -A1ShiftRight * &58 -A1CTRLLCol * K1kdda + (A1CtrlLeft :AND: 15) -A1CTRLLRow * K1kdda + (A1CtrlLeft :SHR: 4) -A1CTRLRCol * K1kdda + (A1CtrlRight :AND: 15) -A1CTRLRRow * K1kdda + (A1CtrlRight :SHR: 4) -A1SHIFTLCol * K1kdda + (A1ShiftLeft :AND: 15) -A1SHIFTLRow * K1kdda + (A1ShiftLeft :SHR: 4) -A1SHIFTRCol * K1kdda + (A1ShiftRight :AND: 15) -A1SHIFTRRow * K1kdda + (A1ShiftRight :SHR: 4) -A1R_Col * K1kdda + 10 -A1R_Row * K1kdda + 2 -A1T_Col * K1kdda + 11 -A1T_Row * K1kdda + 2 -A1Del_Col * K1kdda + 4 -A1Del_Row * K1kdda + 3 -A1Copy_Col * K1kdda + 5 -A1Copy_Row * K1kdda + 3 - ] - - [ Keyboard_Type = "A1A500" -; old (A500) keyboard positions - -A500CTRLRow * KEYDOWN + &C -A500CTRLCol * KEYDOWN + 0 -A500SHIFTRow * KEYDOWN + &A -A500SHIFTCol * KEYDOWN + 0 -A500R_Row * KEYDOWN + 2 -A500R_Col * KEYDOWN + 7 -A500T_Row * KEYDOWN + 2 -A500T_Col * KEYDOWN + 6 -A500Del_Row * KEYDOWN + 5 -A500Del_Col * KEYDOWN + 7 -A500Copy_Row * KEYDOWN + 0 -A500Copy_Col * KEYDOWN + 8 - ] - -; On ARM600, this routine must work in IRQ32 mode - -IRQ_Test_CTRL_or_R_Pressed ROUT - Push "r0-r2, R10-R12, lr" - - MOV R12, #IOC - - MOV r2, #IOC - MOV r0, #32 - BL DoMicroDelay ; quick thumb twiddle until it's REALLY there - LDRB R11, KARTRx ; read byte transmitted by keyboard - - [ KeyboardDebungling - Push R12 - MOV R12, R11, LSR #4 - TubeChar R10, R11, "MOV R11, #""R""" - TubeChar R10, R11, "ADD R11, R12, #""0""" - AND R12, R11, #&F - TubeChar R10, R11, "ADD R11, R12, #""0""" - Pull R12 - ] - - CMP R11, #HRDRESET ; first check for part of reset sequence and reply accordingly - - BEQ fartaboutfornewkbd - - CMP R11, #RST1ACK - MOVEQ R10, #RST2ACK - BEQ send_ack_byte - - CMP R11, #RST2ACK - BNE keytransmission - - MOV R10, #InitKbdWs - LDR R10, [R10, #KeyDataPtr] - CMP R10, #0 - MOVNE R10, #ACK+SCAN - BNE send_ack_byte - MOV R10, #ACK - - [ KeyboardDebungling - Push R12 - MOV R12, R10, LSR #4 - TubeChar R10, R11, "MOV R11, #""k""" - TubeChar R10, R11, "ADD R11, R12, #""0""" - AND R12, R10, #&F - TubeChar R10, R11, "ADD R11, R12, #""0""" - Pull R12 - ] - - STRB R10, KARTTx - BL PollTxBit - MOV R11, #K1rqid - BL SendAndPollRxBit - - [ Keyboard_Type = "A1A500" - AND r10, r11, #&F0 - CMP R11, #IDTYPE ; a500 kbd? - ADREQ R10, DataA500Kbd - BEQ gotkbdid - ] - SUB r11, r11, #K1kbid + 1 - CMP r11, #30 - ADRLSL R10, DataA1Kbd ; only accept ID 1-31 - MOVHI R10, #0 ; else don't know - -gotkbdid - MOV R11, #InitKbdWs - STR R10, [R11, #KeyDataPtr] - [ Keyboard_Type = "A1A500" - ASSERT (DataA1Kbd :AND: 255) <> 0 - ] - [ Keyboard_Type = "A1A500" - ASSERT (DataA500Kbd :AND: 255) <> 0 - ] - STRB R10, [R11, #KB_There_Flag] - ; only there once ID understood - MOV R10, #HRDRESET ; and from the top - B send_ack_byte - -keytransmission -; assume it's key info - MOV R10, #InitKbdWs - LDRB R10, [R10] ; the "had a byte" flag - CMP R10, #0 - BNE hadabyteofkey - MOV R10, #InitKbdWs - STRB R11, [R10] ; first part of 2 byte protocol: set flag - MOV R10, #ACK+&F - B send_ack_byte - -fartaboutfornewkbd - -kickitagain - MOV R11, #HRDRESET - BL SendAndPollRxBit ; get a byte to R11 - BL PollTxBit - CMP R11, #HRDRESET - BNE kickitagain - MOV R11, #RST1ACK - BL SendAndPollRxBit ; get a byte to R11 - BL PollTxBit - CMP R11, #RST1ACK - BNE kickitagain - MOV R10, #RST2ACK - B send_ack_byte - -hadabyteofkey -; now got 1st byte in R10, second byte in R11 : test for CTRL or R - MOV R0, #InitKbdWs - LDR R0, [R0, #KeyDataPtr] -10 LDRB R1, [R0], #1 - CMP R1, #0 - BEQ %FT11 - CMP R1, R10 - LDRB R1, [R0], #1 - CMPEQ R1, R11 - LDRB R1, [R0], #1 - BNE %BT10 - MOV R11, #InitKbdWs - STRB R1, [R11, R1] ; non-zero means pressed -11 - MOV R10, #ACK+SCAN -send_ack_byte - - [ KeyboardDebungling - Push R12 - MOV R12, R10, LSR #4 - TubeChar R10, R11, "MOV R11, #""T""" - TubeChar R10, R11, "ADD R11, R12, #""0""" - AND R12, R10, #&F - TubeChar R10, R11, "ADD R11, R12, #""0""" - Pull R12 - ] - - STRB R10, KARTTx ; assume always able to transmit? - CMP R10, #ACK+&F - MOVNE R11, #InitKbdWs - STRNEB R11, [R11] ; clear "one byte of 2 byte seq had" flag - - Pull "r0-r2, R10-R12, lr" - SUBS PC, R14, #4 - - DCD 0 ; temp fudge - - [ Keyboard_Type = "A1A500" - [ . :AND: 255 = 0 - DCB "S" ; Odd length, should throw us - ] -DataA1Kbd - = A1CTRLLRow, A1CTRLLCol, CTRL_Down_Flag - = A1CTRLRRow, A1CTRLRCol, CTRL_Down_Flag - = A1SHIFTRRow, A1SHIFTRCol, SHIFT_Down_Flag - = A1SHIFTLRow, A1SHIFTLCol, SHIFT_Down_Flag - = A1R_Row, A1R_Col, R_Down_Flag - = A1T_Row, A1T_Col, T_Down_Flag - = A1Del_Row, A1Del_Col, Del_Down_Flag - = A1Copy_Row, A1Copy_Col, Copy_Down_Flag - = 0 - ] - - [ Keyboard_Type = "A1A500" - [ . :AND: 255 = 0 - DCB "K" - ] -DataA500Kbd - = A500CTRLRow, A500CTRLCol, CTRL_Down_Flag - = A500SHIFTRow, A500SHIFTCol, SHIFT_Down_Flag - = A500R_Row, A500R_Col, R_Down_Flag - = A500T_Row, A500T_Col, T_Down_Flag - = A500Del_Row, A500Del_Col, Del_Down_Flag - = A500Copy_Row, A500Copy_Col, Copy_Down_Flag - = 0 - ] - - ALIGN - - LTORG - -PollTxBit ROUT - -01 LDRB R10, [R12, #IOCIRQSTAB] - TST R10, #KARTTxBit - BEQ %BT01 - MOV pc, lr - - -SendAndPollRxBit ROUT - - Push lr - - [ KeyboardDebungling - Push R12 - MOV R12, R11, LSR #4 - TubeChar R10, R11, "MOV R11, #""t""" - TubeChar R10, R11, "ADD R11, R12, #""0""" - AND R12, R11, #&F - TubeChar R10, R11, "ADD R11, R12, #""0""" - Pull R12 - ] - - STRB R11, KARTTx - -01 LDRB R10, [R12, #IOCIRQSTAB] - TST R10, #KARTRxBit - BEQ %BT01 - - MOV r2, #IOC - MOV r0, #32 - BL DoMicroDelay - LDRB R11, KARTRx ; purge KART, or get reply - - [ KeyboardDebungling - Push R12 - MOV R12, R11, LSR #4 - TubeChar R10, R11, "MOV R11, #""r""" - TubeChar R10, R11, "ADD R11, R12, #""0""" - AND R12, R11, #&F - TubeChar R10, R11, "ADD R11, R12, #""0""" - Pull R12 - ] - - Pull pc - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -SetUpKbd -; set up keyboard: initialise baud rate, send dummy, read dummy - MOV R12, #IOC ; code ripped off from pmf.Key - MOV R0, #1 - STRB R0, Timer3Low - MOV R0, #0 - STRB R0, Timer3High - STRB R0, Timer3Go ; baud rate set and going - - STRB R0, KARTTx ; send dummy - - MOV r1, r13 - MOV r13, #&8000 ; need a quick stack - scratchspace - Push r1 ; probably the best bet. - - MOV r0, #&800*2 ; magic delay - MOV r2, #IOC - BL DoMicroDelay - - LDMFD r13, {r13} ; finished with stack - - LDRB R0, KARTRx ; ensure no wally byte in KARTRx - - BL PollTxBit - MOV R0, #HRDRESET ; start reset protocol - STRB R0, KARTTx - - B SetUpKbdReturn - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -KeyboardDebungling SETL {FALSE} - - END diff --git a/s/KbdResPC b/s/KbdResPC deleted file mode 100644 index d3cb621c..00000000 --- a/s/KbdResPC +++ /dev/null @@ -1,190 +0,0 @@ -; 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. -; -; > KbdResPC - -; This file contains the minimal PC keyboard control stuff that the kernel does on reset. -; The only two hooks in this file used externally are IRQ_Test_CTRL_or_R_Pressed -; and SetUpKbd. - -; For now, use development podule in slot 0. -IOBase * IOMD_Base -IOData * IOCSERTX -IOStatus * IOMD_KBDCR -IOControl * IOMD_KBDCR -stat_RXF * IOMD_KBDCR_RxF -stat_TXE * IOMD_KBDCR_TxE -ctl_Enable * IOMD_KBDCR_Enable -ctl_EnableIRQ * 0 ; not needed on IOMD - - -; PC keyboard codes we are interested in. -PCReset * &AA -PCSpecial * &E0 -PCCTRLL * &14 -PCCTRLR * &14 ; Preceded by &E0 -PCSHIFTL * &12 -PCSHIFTR * &59 -PCR * &2D -PCT * &2C -PCDelete * &71 ; Preceded by &E0 -PCBSpace * &66 -PCEnd * &69 ; Preceded by &E0 - -KeyData - DCB PCCTRLL, CTRL_Down_Flag - DCB PCSHIFTL, SHIFT_Down_Flag - DCB PCSHIFTR, SHIFT_Down_Flag - DCB PCR, R_Down_Flag - DCB PCT, T_Down_Flag - DCB PCBSpace, Del_Down_Flag - DCB 0 - ALIGN - -SpecialData - DCB PCCTRLR, CTRL_Down_Flag - DCB PCDelete, Del_Down_Flag - DCB PCEnd, Copy_Down_Flag - DCB 0 - ALIGN - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - [ :LNOT HAL - -SetUpKbd - MOV r0, #IOBase - MOV r1, #ctl_Enable + ctl_EnableIRQ - STRB r1, [r0, #IOControl] -10 - LDRB r1, [r0, #IOStatus] - TST r1, #stat_TXE - MOVNE r1, #&FF - STRNEB r1, [r0, #IOData] - BEQ %BT10 - - [ MorrisSupport - [ {TRUE} ; ARM7500FE support -; Change test to check for IOMD_Original, rather than IOMD_7500, so we include IOMD_7500FE -; in the latter category - - LDRB r1, [r0, #IOMD_ID0] - LDRB r2, [r0, #IOMD_ID1] ; safe to use r2, since SetUpKbdReturn corrupts it - ORR r1, r1, r2, LSL #8 ; straight away - LDR r2, =IOMD_Original - TEQ r1, r2 - BEQ %FT30 - | - LDRB R1, [R0, #IOMD_ID0] ;Are we running on Morris - CMP R1, #&E7 - LDRB R1, [R0, #IOMD_ID1] - CMPEQ R1, #&5B - BNE %FT30 ;NE: no, assume IOMD, so only one PS2 port - ] - - MOV R1, #IOMD_MSECR_Enable ;yes, so initialise 2nd PS2 (mouse) port cos - STRB R1, [R0, #IOMD_MSECR] ;keyboard may be connected there instead -20 - LDRB R1, [R0, #IOMD_MSECR] - TST R1, #IOMD_MSECR_TxE ;Is port ready to accept data - MOVNE R1, #&FF ;NE: port ready, so send 'reset' command - STRNEB R1, [R0, #IOMD_MSEDAT] ; - BEQ %BT20 ;EQ: loop til port ready - - MOV R1, #IOMD_MouseRxFull_IRQ_bit - STRB R1, [R0, #IOMD_IRQMSKD] - - MOV R0, #InitKbdWs - MOV R1, #2 - STRB R1, [R0, #Port2Present] -30 - ] - MOV r0, #InitKbdWs - ADR r1, KeyData - STR r1, [r0, #KeyDataPtr] - - B SetUpKbdReturn - - ] ; :LNOT: HAL - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -; On ARM600, this routine must work in IRQ32 mode - -IRQ_Test_CTRL_or_R_Pressed ROUT - SUB lr, lr, #4 - Push "r0-r2,lr" - - MOV r2, #IOBase - [ MorrisSupport - MOV lr, #InitIRQWs - LDRB r1, [lr, #Port2Present] ;Check if 2nd PS2 port (in Morris) is available - TEQ r1, #0 - - LDRNEB r0, [r2, #IOMD_MSECR] ;NE: yes, so check if interrupt is from it - TSTNE r0, #IOMD_MSECR_RxF ; - LDRNEB r2, [r2, #IOMD_MSEDAT] ;NE: 2nd port present and interrupting, get scan code - MOVNE r1, #2 ;NE: indicate which port - BNE %FT5 ;NE: process it - ;EQ: 2nd port not present or interrupting - ; drop through and check 1st port - ] - LDRB r0, [r2, #IOStatus] - TST r0, #stat_RXF ; If not keyboard then - Pull "r0-r2,pc",EQ,^ ; exit. - - LDRB r2, [r2, #IOData] ; Get scan code. - - [ MorrisSupport - MOV r1, #1 -5 - LDRB r0, [lr, #KB_There_Flag] - - TEQ r2, #0 ;Assume that zero is the end of a mouse AA 00 start up - BICEQ r0, r0, r1 ; sequence, so clear keyboard present indication. - STREQB r0, [lr, #KB_There_Flag] - Pull "r0-r2,pc",EQ,^ ; and exit - - ORRNE r0, r0, r1 ;Not zero, mark keyboard present - ] - - MOV lr, #InitIRQWs - - STRB r0, [lr, #KB_There_Flag] ; Keyboard must be there (r0<>0 from above). - - ADR r1, SpecialData - - TEQ r2, #PCSpecial ; If special code then - STREQ r1, [lr, #KeyDataPtr] ; switch tables - Pull "r0-r2,pc",EQ,^ ; and exit. - - LDR r0, [lr, #KeyDataPtr] ; Get pointer to current table. - - TEQ r0, r1 ; Only use special table once, then - ADREQ r1, KeyData ; switch back to normal table. - STREQ r1, [lr, #KeyDataPtr] -10 - LDRB r1, [r0], #2 ; Get key code from table. - TEQ r1, #0 ; If at end of table then - Pull "r0-r2,pc",EQ,^ ; ignore key. - - TEQ r1, r2 ; If not this key then - BNE %BT10 ; try the next. - - LDRB r1, [r0, #-1] ; Get flag. - STRB r1, [lr, r1] ; Non-zero means pressed. - - Pull "r0-r2,pc",,^ - - END diff --git a/s/KbdResRCMM b/s/KbdResRCMM deleted file mode 100644 index 41ae804d..00000000 --- a/s/KbdResRCMM +++ /dev/null @@ -1,280 +0,0 @@ -; Copyright 1999 Pace Micro Technology plc -; -; 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. -; -; > KbdResRCMM - -; This file contains the minimal RCMM keyboard control stuff that the kernel does on reset. -; The only two hooks in this file used externally are IRQ_Test_CTRL_or_R_Pressed -; and SetUpKbd. - -; These asserts are to do with the need to pull forward the combo chip configuration. -; As the code presently stands, ConfigureCombo will only work without calling -; ReadMachineType and PowerHardware in these conditions. -; -; The reason for not calling them is that they mess with variables and VIDC things -; that aren't ready yet. -; -; ConfigureCombo etc only write to IOSystemType, which has now been moved to SkippedTables -; so it doesn't get wiped by ClearPhysRam. - - ASSERT :LNOT: BatManSupport - -UART2 * ComboBase + &2F8*4 ; -> base of UART 2 - - ^ 0, R2 -UART_RBR # 0 ; 0 Receive buffer register (read only) { DLAB=0 } -UART_THR # 4 ; 0 Transmit holding register (write only) { DLAB=0 } -UART_IER # 4 ; 1 Interrupt enable register (RW) { DLAB=0 } -UART_FCR # 0 ; 2 FIFO control register (write only) -UART_IIR # 4 ; 2 Interrupt identification register (read only) -UART_LCR # 4 ; 3 Line control register -UART_MCR # 4 ; 4 Modem control register -UART_LSR # 4 ; 5 Line status register -UART_MSR # 4 ; 6 Modem status register -UART_SCR # 4 ; 7 Scratchpad register - - ^ 0, R2 -UART_DLL # 4 ; 0 Divisor latch (LS) { DLAB=1 } -UART_DLH # 4 ; 1 Divisor latch (MS) { DLAB=1 } - - -; States - ^ 0 -RCMM_HaveNowt # 1 -RCMM_HaveBasic # 1 -RCMM_HaveOEM # 1 -RCMM_HaveOEM_Key # 1 -RCMM_HaveOEM_Remote # 1 -RCMM_HaveOEM_Remote_2 # 1 - -; RCMM keyboard codes we are interested in. -RCMMCtrlL * 74 -RCMMCtrlR * 81 -RCMMShiftL * 61 -RCMMShiftR * 72 -RCMMR * 38 -RCMMT * 39 -RCMMDelete * 88 -RCMMBSpace * 33 -RCMMEnd * 89 - -; RCMM remote control codes we are interested in. - -RCMMRemRight * 91+128 - -KeyData - DCB RCMMCtrlL, CTRL_Down_Flag - DCB RCMMCtrlR, CTRL_Down_Flag - DCB RCMMShiftL, SHIFT_Down_Flag - DCB RCMMShiftR, SHIFT_Down_Flag - DCB RCMMR, R_Down_Flag - DCB RCMMT, T_Down_Flag - DCB RCMMDelete, Del_Down_Flag - DCB RCMMBSpace, Del_Down_Flag - DCB RCMMEnd, Copy_Down_Flag - DCB RCMMRemRight, Del_Down_Flag - DCB 0 - ALIGN - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -SetUpKbd -; Tricky - we don't have R13_svc set up yet - indeed it contains the RAM size -; and musn't be corrupted. These calls will need it though. The SVC stack does -; exist, so we can use it temporarily. - MOV R3, R13 - LDR R13, =SVCSTK - -; We're going to be using the serial port on the combo chip, so we need to -; pull forward the combo chip initialisation from PMF.osinit. - [ STB - BL ConfigureCombo - | - BL Configure37C665 ;RiscPC, Kryten and Stork use only SMC 37C665 - ] - -; Set up the serial port - - LDR R2, =UART2 ; R2 -> UART - - LDRB R0, UART_LCR - ORR R1, R0, #2_10000000 ; set DLAB (enable Divisor Latch Access) - STRB R1, UART_LCR - - MOV R1, #12 ; divisor latch := 12 (9600 baud) - STRB R1, UART_DLL - MOV R1, #0 - STRB R1, UART_DLH - - MOV R0, #2_00000011 ; 8N1, DLAB off - STRB R0, UART_LCR - - STRB R1, UART_FCR ; FIFOs off - - LDRB R0, UART_RBR ; clear the receive buffer - LDRB R0, UART_RBR - LDRB R0, UART_LSR ; clear any error condition - - MOV R0, #2_00000101 ; received data and line status interrupts only - STRB R0, UART_IER - - MOV R0, #2_00001011 ; enable IRQ; RTS and DTR on - STRB R0, UART_MCR - - MOV R0, #IOMD_Base - [ ReassignedIOMDInterrupts - MOV R1, #IOMDr_serial_IRQ_bit - | - MOV R1, #IOMD_serial_IRQ_bit - ] - STRB R1, [R0, #IOCIRQMSKB] - - MOV R0, #InitKbdWs - STRB R1, [R0, #KB_There_Flag] ; keyboard is always there (it's infra-red...) - - MOV R13, R3 ; restore R13 - - B SetUpKbdReturn - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -; On ARM600, this routine must work in IRQ32 mode - -; This is called on receipt of a serial interrupt. - -IRQ_Test_CTRL_or_R_Pressed ROUT - SUB lr, lr, #4 - Push "r0-r2,lr" - - LDR R2, =UART2 - LDRB R0, UART_IIR - AND R1, R0, #2_00000111 ; check the interrupt source - TEQ R1, #2_100 - BEQ IRQ_RCMM_Receive - TEQ R1, #2_110 - BEQ IRQ_RCMM_LineStatus - Pull "R0-R2,PC",,^ ; shouldn't happen. Hope it goes away :) - -IRQ_RCMM_LineStatus - LDRB R0, UART_LSR ; this clears the interrupt - TST R0, #2_00011110 ; overrun, parity, framing or break error? - Pull "R0-R2,PC",EQ,^ ; no? then why did you call us? - - TST R0, #2_00000001 ; data ready? - LDRNEB R0, UART_RBR ; junk it then. - - MOV R0, #RCMM_HaveNowt - MOV LR, #InitKbdWs - STRB R0, [LR, #KeyState] - Pull "R0-R2,PC",,^ - - -; Problem we have is no flow control; we could be looking at any -; part of a message. Deal with this by resynchronising every time -; we get something we don't expect. - -; Basic mode keypress is binary 10xx0kkk kkkk0000 -; OEM mode keypress is binary 000011xx xxxx10xx 0kkkkkkk -; or 001xxxxx xxxx10xx 0kkkkkkk -; Remote control press is binary 000011xx xxxx00xx xxxxxxxx 0rrrrrrr -; or 001xxxxx xxxx00xx xxxxxxxx 0rrrrrrr - -IRQ_RCMM_Receive - LDRB R0, UART_RBR ; received data in R0 (interrupt cleared) - MOV R2, #InitKbdWs - LDRB LR, [R2, #KeyState] - ADD PC, PC, LR, LSL #2 - NOP - B IRQ_RCMM_Nowt - B IRQ_RCMM_Basic - B IRQ_RCMM_OEM - B IRQ_RCMM_OEM_Key - B IRQ_RCMM_OEM_Remote - B IRQ_RCMM_OEM_Remote_2 - -IRQ_RCMM_Nowt - AND LR, R0, #2_11001000 - TEQ LR, #2_10000000 ; is it a basic mode keypress? - BNE %FT10 - - MOV LR, #RCMM_HaveBasic - STRB LR, [R2, #KeyState] - AND LR, R0, #2_00000111 - STRB LR, [R2, #KeyMSB] - -10 AND LR, R0, #2_11111100 ; is it a short ID OEM message? - TEQ LR, #2_00001100 - ANDNE LR, R0, #2_11100000 ; or a long ID one? - TEQNE LR, #2_00100000 - MOVEQ LR, #RCMM_HaveOEM - STREQB LR, [R2, #KeyState] - Pull "R0-R2,PC",,^ - -IRQ_RCMM_Basic - TST R0, #2_00001111 - BNE ResyncRCMM - LDRB LR, [R2, #KeyMSB] - MOV R0, R0, LSR #4 - ORR R0, R0, LR, LSL #4 ; R0 = key code - B GotRCMMKey - -IRQ_RCMM_OEM - AND LR, R0, #2_00001100 - TEQ LR, #2_00000000 ; Remote control? - TEQNE LR, #2_00001000 ; Keyboard? - BNE ResyncRCMM - TEQ LR, #2_00000000 - MOVEQ LR, #RCMM_HaveOEM_Remote - MOVNE LR, #RCMM_HaveOEM_Key - B UpdateRCMMState - -IRQ_RCMM_OEM_Key - TST R0, #2_10000000 ; Key up rather than down? - BNE ResyncRCMM - B GotRCMMKey - -IRQ_RCMM_OEM_Remote - MOV LR, #RCMM_HaveOEM_Remote_2 - B UpdateRCMMState ; This byte can be anything :) - -IRQ_RCMM_OEM_Remote_2 - TST R0, #2_10000000 ; Key up rather than down? - BNE ResyncRCMM - ADD R0, R0, #128 ; Indicate a remote code - B GotRCMMKey - -ResyncRCMM - MOV LR, #RCMM_HaveNowt -UpdateRCMMState - STRB LR, [R2, #KeyState] - Pull "R0-R2,PC",,^ - -; In: R0 = key code, R2 = InitKbdWs -GotRCMMKey - - ADR R1, KeyData -10 - LDRB LR, [R1], #2 ; Get key code from table. - TEQ LR, #0 ; If at end of table then - Pull "R0-R2,PC",EQ,^ ; ignore key. - - TEQ LR, R0 ; If not this key then - BNE %BT10 ; try the next. - - LDRB LR, [R1, #-1] ; Get flag. - STRB LR, [R2, LR] ; Non-zero means pressed. - - B ResyncRCMM - - END diff --git a/s/Kernel b/s/Kernel deleted file mode 100644 index d9bfb95e..00000000 --- a/s/Kernel +++ /dev/null @@ -1,1619 +0,0 @@ -; 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 => Kernel : SWI Despatch, simple SWIs - SUBT Arthur Variables - OPT 4 - -; ----------------------------------------------------------------------------- -; -; mjs Oct 2000 kernel/HAL split -; -; macros that can be switched between doing real HAL calls and pseudo -; HAL calls with r9-> mjs pseudo HAL workspace -; -; these have been handy for interim HALising of kernel code in-situ -; (particularly used for video stuff), but can probably disappear later -; - - [ HAL - - MACRO - mjsAddressHAL $zero - AddressHAL $zero - MEND - - MACRO - mjsCallHAL $rout - CallHAL $rout - MEND - - MACRO - DebugTX $str - [ DebugHALTX - BL DebugHALPrint - = "$str", 0 - ALIGN - ] - MEND - | - - MACRO - mjsAddressHAL - LDR r9, =mjs_tempHALworkspace - LDR r9, [r9] ; sb -> pseudo HAL workspace - MEND - - MACRO - mjsCallHAL $rout - BL $rout - MEND - - ] ;HAL - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; handy macros: -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - MACRO -$l CheckSpaceOnStack $space, $faildest, $tmp - [ True ; SKS -$l MOV $tmp, sp, LSR #15 ; Stack base on 32K boundary - SUB $tmp, sp, $tmp, LSL #15 ; Amount of stack left - CMP $tmp, #$space ; Must have at least this much left - BMI $faildest - | -$l MOV $tmp, #32*1024 ; assume stack ends at next 32K boundary - SUB $tmp, $tmp, #1 - AND $tmp, $tmp, stack - CMP $tmp, #$space - BLT $faildest - ] - MEND - - MACRO - assert $condition - [ :LNOT: ($condition) - ! 1,"Assert failed: $condition" - ] - MEND - -; one that builds a module command table entry: -; set Module_BaseAddr to module base before use. - - GBLA Module_BaseAddr -Module_BaseAddr SETA 0 - -; Command $cmd, $max, $min - declared in hdr.macros. - -; debug macro: set the border colour - - MACRO -$l SetBorder $reg1, $reg2, $red, $green, $blue, $delay - ! 0, "Setborder used" -$l LDR $reg1, =VIDC -; Note $reg, $green and $blue are 4 bit values - LDR $reg2, =&40000000+(($red)*&11)+(($green)*&1100)+(($blue)*&110000) - STR $reg2, [$reg1] - [ "$delay"<>"" - MOV $reg1, #$delay -10 - SUBS $reg1, $reg1, #1 - BNE %BT10 - ] - MEND - -; Fake a 26-bit pc, given a PSR currently in lr (or reg), and the 32-bit address on -; the stack. The stacked address is pulled, and the result is left in lr. - - MACRO - FakeLR $temp, $dontpull, $reg - [ "$reg" = "" - AND $temp,lr,#&F0000003 - | - AND $temp,$reg,#&F0000003 - ] - AND lr,lr,#I32_bit+F32_bit - ORR $temp,$temp,lr,LSL #IF32_26Shift - [ "$dontpull" = "dontpull" - LDR lr,[sp] - | - LDR lr,[sp],#4 - ] - BIC lr,lr,#ARM_CC_Mask - ORR lr,lr,$temp - MEND - -; - - [ AddTubeBashers - [ TubeType = Tube_Normal -DebugTUBE * &03340000+3*&4000 ; tube in podule #3 -; Tube register offsets - ^ 0 -R1STAT # 4 -R1DATA # 4 - | -DebugTUBE * &03000000 ; simulator tube address -R1DATA * 0 - ] - ] - -; routine to stuff a char down the Tube -; should be inside above conditional, but AAsm winges pitifully. - MACRO -$l TubeChar $reg1, $reg2, $charset, $stackthere - ! 0, "TubeChar used." -$l - [ "$stackthere"="" - Push "$reg1, $reg2" - ] - LDR $reg1, =DebugTUBE - [ TubeType = Tube_Normal ; normal tubes have status register, simulator one doesn't -01 LDRB $reg2, [$reg1, #R1STAT] - TST $reg2, #&40 - BEQ %BT01 - ] - $charset - STRB $reg2, [$reg1, #R1DATA] - [ "$stackthere"="" - Pull "$reg1, $reg2" - ] - MEND - - MACRO -$l TubeString $reg1, $reg2, $reg3, $string, $cc - LDR $reg1, =DebugTUBE - ADR $reg2, %FT20 -10 - [ TubeType = Tube_Normal - LDRB $reg3, [$reg1, #R1STAT] - TST $reg3, #&40 - BEQ %BT10 - ] - - LDRB $reg3, [$reg2], #1 - TEQ $reg3, #0 - STRNEB $reg3, [$reg1, #R1DATA] - BNE %BT10 - B %FT30 -20 - = "$string" - [ "$cc" = "" - = 10, 13 - ] - = 0 - ALIGN -30 - MEND - - MACRO -$l TubeDumpNoStack $dump, $t1, $t2, $t3 -$l MOV $t1, #7 -01 - ADRL $t2, HexTable - TubeChar $t3, $t2, "LDRB $t2, [$t2, $dump, LSR #28]", NoStack - MOV $dump, $dump, ROR #28 - SUBS $t1, $t1, #1 - BPL %BT01 - TubeChar $t3, $t2, "MOV $t2, #"" """, NoStack - MEND - - MACRO -$l TubeNewlNoStack $t1, $t2 -$l TubeChar $t1, $t2, "MOV $t2, #10", NoStack - TubeChar $t1, $t2, "MOV $t2, #13", NoStack - MEND - - -a1 RN 0 -a2 RN 1 -a3 RN 2 -a4 RN 3 -v1 RN 4 -v2 RN 5 -v3 RN 6 -v4 RN 7 -v5 RN 8 -v6 RN 9 -sb RN 9 -v7 RN 10 -v8 RN 11 - -; Set sb up ready for CallHAL. - MACRO - AddressHAL $zero - [ "$zero" <> "" - LDR sb, [$zero, #HAL_Workspace] - | - LDR sb, =ZeroPage - LDR sb, [sb, #HAL_Workspace] - ] - MEND - -; Calls the HAL. $rout is the routine. sb must have been set up by AddressHAL - MACRO - CallHAL $rout, $cond - MOV$cond lr, pc - LDR$cond pc, [sb, #-(EntryNo_$rout+1) * 4] - MEND - -; Checks whether a HAL routine exits. If it does, a1 points to it (probably -; not useful), and Z is clear. lr corrupted. - MACRO - CheckHAL $rout - LDR a1, [sb, #-(EntryNo_$rout+1) * 4] - ADRL lr, NullHALEntry - TEQ a1, lr - MEND - - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; Various constants -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -PageSize * (4*1024) ;MMU page size (normal pages) -Log2PageSize * 12 ;for shifts - -MinAplWork * 40*1024 ; minimum size of AplWork - -; Fixed addresses - -MEMCADR * &03600000 - GBLL ROMatTop - [ HAL32 :LAND: {TRUE} -ROM * &FC000000 -ROMatTop SETL {TRUE} - | -ROM * &03800000 -ROMLimit * &04000000 - ] -OSMD * &11111111 - -VideoPhysRam * &02000000 ; Amazing - it's in the same place! -DRAM0PhysRam * &10000000 ; 4 DRAM banks -DRAM1PhysRam * &14000000 -DRAM2PhysRam * &18000000 -DRAM3PhysRam * &1C000000 -DRAMBaseAddressMask * &1C000000 ; used to mask off bits after stealing video RAM -PhysSpaceSize * &20000000 ; IOMD physical map is 512M big -PhysROM * &00000000 ; and real ROM starts at 0 - [ STB -PhysExtROM * &01000000 ; 2nd ROM bank starts at 16M - ] -SAMLength * 512*4 ; SAM length in bytes for 1 bank of VRAM - [ :LNOT: HAL -EASISpacePhys * &08000000 -EASISpace * PhysSpace + EASISpacePhys - ] - -; Manifests - -CR * 13 -LF * 10 -space * " " - -; Registers - -SPIRQ RN R13 - -; Callback byte bits: -CBack_OldStyle * 1 -CBack_Postpone * 2 -CBack_VectorReq * 4 - -; Set up symbols for the SWIs which aren't really there yet - - - SUBT Arthur Code - OPT 4 - - [ HAL - ORG ROM + 64*1024 - | - ORG ROM - ] - - AREA |!!!!OSBase|,CODE,READONLY - - ENTRY ; Not really, but we need it to link -KernelBase - -; ***************************************************************************** -; -; Now ready to start the code: off we go! -; -; ***************************************************************************** - - [ HAL -; ORG ROM + 64*1024 - | -; ORG ROM - ] - - GBLS DoMorrisROMHeader - GBLS DoTestThings -DoMorrisROMHeader SETS "" -DoTestThings SETS "" - - [ HAL -; BIN HAL.L7200.HAL - -; RISC OS image header -RISCOS_Header - = "OSIm" - DCD 0 - DCD OSROM_ImageSize*1024 - 64*1024 - DCD RISCOS_Entries - RISCOS_Header - DCD (RISCOS_Entries_End - RISCOS_Entries) / 4 - -RISCOS_Entries - DCD RISCOS_InitARM - RISCOS_Entries - DCD RISCOS_AddRAM - RISCOS_Entries - DCD RISCOS_Start - RISCOS_Entries - DCD RISCOS_MapInIO - RISCOS_Entries - DCD RISCOS_AddDevice - RISCOS_Entries - DCD RISCOS_LogToPhys - RISCOS_Entries -RISCOS_Entries_End - - | - - - [ MorrisSupport -DoMorrisROMHeader SETS " GET s.Morris" - ] - -; now include the test code, if there is any - - - [ IncludeTestSrc -DoTestThings SETS " GET TestSrc.Begin" - ] - $DoTestThings - - [ IncludeTestSrc -DoMorrisROMHeader SETS "" - ] - - $DoMorrisROMHeader - ] - - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; If there is no test code then we want a branch table at the start of ROM to -; handle reset and any aborts etc. in the reset code. -; If MorrisSupport we've already generated 16/32 ROM entry code, so skip this bit - - [ :LNOT: IncludeTestSrc :LAND: :LNOT: MorrisSupport :LAND: :LNOT: HAL - LDR pc, .+ResetIndirection ; load PC, PC relative - B UndInstInReset - B SWIInReset - B PrefAbInReset - B DataAbInReset - B AddrExInReset - B IRQInReset - -UndInstInReset - SUB pc, pc, #8 -SWIInReset - SUB pc, pc, #8 -PrefAbInReset - SUB pc, pc, #8 -DataAbInReset - SUB pc, pc, #8 -AddrExInReset - SUB pc, pc, #8 -IRQInReset - SUB pc, pc, #8 - ] - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; This bit (up to EndFiq) is copied to location 0. Processor vectors are -; indirected through 0 page locations so that they can be claimed using -; OS_ClaimProcessorVector. IRQs are initially handled specially so that the -; keyboard can be handled during reset but the load is replaced with the -; standard one later on. - -MOSROMVecs - LDR pc, MOSROMVecs+ProcVec_Branch0 - LDR pc, MOSROMVecs+ProcVec_UndInst - LDR pc, MOSROMVecs+ProcVec_SWI - LDR pc, MOSROMVecs+ProcVec_PrefAb - LDR pc, MOSROMVecs+ProcVec_DataAb - LDR pc, MOSROMVecs+ProcVec_AddrEx - LDR pc, MOSROMVecs+InitIRQHandler -EndMOSROMVecs - - ASSERT InitIRQHandler >= EndMOSROMVecs - MOSROMVecs - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; This is the table of default processor vectors which is copied to 0 page. - -DefaultProcVecs - & Branch0_NoTrampoline - & UndPreVeneer - & SVC - & PAbPreVeneer - & DAbPreVeneer - & AdXPreVeneer - & Initial_IRQ_Code - - ASSERT (.-DefaultProcVecs) = ProcVec_End-ProcVec_Start - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; These are preveneers which must be copied to 0 page locations so that the -; relevant handler can be branched to. This is mainly for non-ARM600 platforms -; although the address exception preveneer (which should not actually be required -; on ARM600) is always copied. - -DefaultPreVeneers - [ No26bitCode -UndPreVeneer * ProcVecPreVeneers+(.-DefaultPreVeneers) - LDR PC, DefaultPreVeneers-ProcVecPreVeneers+UndHan - [ ChocolateAMB - DCD 0 - | -PAbPreVeneer * ProcVecPreVeneers+(.-DefaultPreVeneers) - LDR PC, DefaultPreVeneers-ProcVecPreVeneers+PAbHan - ] - DCD 0 - | - DCD 0 - DCD 0 - DCD 0 - ] -AdXPreVeneer * ProcVecPreVeneers+(.-DefaultPreVeneers) - LDR PC, DefaultPreVeneers-ProcVecPreVeneers+AdXHan - - ASSERT (.-DefaultPreVeneers) = ProcVecPreVeneersSize - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; This is the trampoline in the system heap used to handle branch through 0. - -Branch0_Trampoline - STR r1, Branch0_Trampoline + Branch0_Trampoline_SavedR1 - STR lr, Branch0_Trampoline + Branch0_Trampoline_SavedR14 - ADD lr, pc, #4 - LDR pc, .+4 - & Branch0_FromTrampoline -Branch0_Trampoline_Init * .-Branch0_Trampoline -Branch0_Trampoline_SavedR1 * .-Branch0_Trampoline -Branch0_Trampoline_SavedR14 * .-Branch0_Trampoline+4 -Branch0_Trampoline_Size * .-Branch0_Trampoline+8 - - - [ :LNOT: IncludeTestSrc :LAND: :LNOT: HAL - -; We now waste space until the offset into the ROM is the same as the RAM address of ResetIndirection -; This is so that -; a) on a reset, ROM is paged in at the bottom, so we jump to CONT, and -; b) on a break, RAM is paged in at the bottom, so we jump to CONT_Break - - ASSERT .-ROM <= ResetIndirection - % ResetIndirection-(.-ROM) - & CONT-ROM+PhysROM ; address of reset code in physical space - ] - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; Now some initialised workspace/vectors that go at &100 - -; All the stuff from here to after the DirtyBranch instruction is read -; consecutively out of ROM, so don't put anything in between without changing -; the code - - -StartData - ASSERT IRQ1V = &100 - & DefaultIRQ1V - - ASSERT ESC_Status = IRQ1V+4 - & &00FF0000 ; IOCControl set to FF on reset - - ASSERT IRQsema = ESC_Status+4 - & 0 -EndData - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; SWI return handler: checks callback -; no branches or interlocks in the common case: V clear, no callback - -SVCDespatcher ROUT - -SWIRelocation * SVCDespatcher-SWIDespatch - -SLVK_SetV * {PC}-SWIRelocation - - ORR lr, lr, #V_bit - -SLVK_TestV * {PC}-SWIRelocation - ! 0,"SLVK_TestV at ":CC:(:STR:SLVK_TestV) - - ORRVS lr, lr, #V_bit - -SLVK * {PC}-SWIRelocation - ! 0,"SLVK at ":CC:(:STR:SLVK) -Local_SLVK - - LDR r12, [sp], #4 - MOV r10, #0 - [ FixCallBacks - MSR CPSR_c, #I32_bit + SVC32_mode ; IRQs off makes CallBackFlag atomic; 32bit so ready for SPSR use - ] - LDRB r11, [r10, #CallBack_Flag] - - TST lr, #V_bit - BNE %FT50 - -SWIReturnWithCallBackFlag * {PC}-SWIRelocation - ! 0,"SWIReturnWithCallBackFlag at ":CC:(:STR:SWIReturnWithCallBackFlag) - -40 TEQ r11, #0 - - [ :LNOT: FixCallBacks - MSREQ CPSR_c, #I32_bit + SVC32_mode ; IRQs off for SPSR use - ] - MSREQ SPSR_cxsf, lr - LDREQ lr, [sp], #4 - Pull "r10-r12", EQ - MOVEQS pc, lr - - B callback_checking + SWIRelocation - - ! 0,"VSetReturn at ":CC:(:STR:({PC}-SWIRelocation)) -50 TST r12, #Auto_Error_SWI_bit - [ FixCallBacks - BNE callback_checking + SWIRelocation ; we need to do this for X errors even if the callback flags - ; are all clear, so that the postpone flag can be set - | - BNE %BT40 - ] - - B VSet_GenerateError + SWIRelocation - - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; The SWI Despatch routine - -SVC * {PC}-SWIRelocation - - Push "r10-r12" - [ No26bitCode - MRS r12, SPSR ; r12 = saved PSR - TST r12, #T32_bit ; depending on processor state (ARM/Thumb) - LDREQ r11, [r14, #-4] ; extract SWI number to r11 - LDRNEB r11, [r14, #-2] ; (ordering to prevent interlocks) - BICEQ r11, r11, #&FF000000 - | - LDR r11, [r14, #-4] ; extract SWI number to r11 - MRS r12, SPSR ; r12 = saved PSR - BIC r11, r11, #&FF000000 ; (ordering to prevent interlocks) - ] - - Push "r11,r14" ; push SWI number and return address - - AND r10, r12, #I32_bit+F32_bit - ORR r10, r10, #SVC2632 ; set IFTMMMMM = IF0x0011 - MSR CPSR_c, r10 ; restore caller's IRQ state - - BIC r14, r12, #V_bit ; clear V (some SWIs need original PSR in r12) - -SVC_CallASWI * {PC}-SWIRelocation ; CallASWI,CallASWIR12 re-entry point - - BIC r11, r11, #Auto_Error_SWI_bit - - CMP r11, #OS_WriteI - LDRLO pc, [pc, r11, LSL #2] - - B NotMainMOSSwi + SWIRelocation - - ASSERT {PC}-SVCDespatcher = SWIDespatch_Size - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; The SWI table - -JTABLE & SWIWriteC - & SWIWriteS - & SWIWrite0 - & SWINewLine - -; next section is one where VectorNumber = SWINumber - & VecSwiDespatch ; readc - & VecSwiDespatch ; cli - & NoIrqVecSwiDespatch ; byte - & NoIrqVecSwiDespatch ; word - & VecSwiDespatch ; file - & VecSwiDespatch ; args - & BGetSWI ; bget - & BPutSWI ; bput - & VecSwiDespatch ; gbpb - & VecSwiDespatch ; find - [ No26bitCode - & ReadLineSWI - | - & VecSwiDespatch ; readline - ] - - & SCTRL - & SWI_GetEnv_Code - & SEXIT - & SSTENV - & SINTON - & SINTOFF - & SCALLB - & SENTERSWI - & SBRKPT - & SBRKCT - & SUNUSED - & SSETMEMC - & SSETCALL - & VecMouse - & HeapEntry - & ModuleHandler - & ClaimVector_SWICode - & ReleaseVector_SWICode - & ReadUnsigned_Routine - & GenEvent - & ReadVarValue - & SetVarValue - & GSINIT - & GSREAD - & GSTRANS - & CvtToDecimal - & FSControlSWI - & ChangeDynamicSWI - & GenErrorSWI - & ReadEscapeSWI - & ReadExpression - & SwiSpriteOp - & SWIReadPalette - & Issue_Service_SWI - & SWIReadVduVariables - & SwiReadPoint - & DoAnUpCall - & CallAVector_SWI - & SWIReadModeVariable - & SWIRemoveCursors - & SWIRestoreCursors - & SWINumberToString_Code - & SWINumberFromString_Code - & ValidateAddress_Code - & CallAfter_Code - & CallEvery_Code - & RemoveTickerEvent_Code - & InstallKeyHandler - & SWICheckModeValid - & ChangeEnvironment - & SWIClaimScreenMemory - & ReadMetroGnome - & XOS_SubstituteArgs_code - & XOS_PrettyPrint_code - & SWIPlot - & SWIWriteN - & Add_ToVector_SWICode - & WriteEnv_SWICode - & RdArgs_SWICode - & ReadRAMFSLimits_Code - & DeviceVector_Claim - & DeviceVector_Release - & Application_Delink - & Application_Relink - & HeapSortRoutine - & TerminateAndSodOff - & ReadMemMapInfo_Code - & ReadMemMapEntries_Code - & SetMemMapEntries_Code - & AddCallBack_Code - & ReadDefaultHandler - & SWISetECFOrigin - & SerialOp - & ReadSysInfo_Code - & Confirm_Code - & SWIChangedBox - & CRC_Code - & ReadDynamicArea - & SWIPrintChar - & ChangeRedirection - & RemoveCallBack - & FindMemMapEntries_Code - & SWISetColour - & NoSuchSWI ; Added these to get round OS_ClaimSWI and - & NoSuchSWI ; OS_ReleaseSWI (should not have been allocated here). - [ AssemblePointerV - & PointerSWI - | - & NoSuchSWI - ] - & ScreenModeSWI - & DynamicAreaSWI - & NoSuchSWI ; OS_AbortTrap - & MemorySWI - [ ProcessorVectors - & ClaimProcVecSWI - | - & NoSuchSWI - ] - & PerformReset - & MMUControlSWI - [ STB - & NoSuchSWI - | - & ResyncTimeSWI - ] - [ StrongARM - & PlatFeatSWI - & SyncCodeAreasSWI - & CallASWI - & AMBControlSWI - & CallASWIR12 - | - & NoSuchSWI - & NoSuchSWI - & NoSuchSWI - & NoSuchSWI - & NoSuchSWI - ] -; The following SWIs are not available in this kernel. - & NoSuchSWI ; SpecialControl - & NoSuchSWI ; EnterUSR32SWI - & NoSuchSWI ; EnterUSR26SWI -; End of unavailable SWIs. -; Should not cause any problems on any machine. STB flag just to be safe though. - [ STB :LAND: {FALSE} - & VIDCDividerSWI - | - ! 0, "mjsHAL - VIDCDividerSWI not implemented" - & NoSuchSWI - ] - & NVMemorySWI - & NoSuchSWI - & NoSuchSWI - & NoSuchSWI - & HardwareSWI - & IICOpSWI - & SLEAVESWI - & ReadLine32SWI - & XOS_SubstituteArgs32_code - & HeapSortRoutine32 - - - ASSERT (.-JTABLE)/4 = MaxSwi - ASSERT MaxSwi < OS_ConvertStandardDateAndTime - -; SWIs for time/date conversion are poked in specially - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; The fudge branch to exit a dirty SWI handler - -DirtyBranch - B SLVK +DirtyBranch-BranchToSWIExit - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - [ StrongARM -;StrongARM needs these - -;SWI number passed in r10 -CallASWI ROUT - LDR r11, [sp, #8] ;pick-up target SWI code (r10 pushed by dispatcher) - BIC r11, r11, #&FF000000 ;just in case - STR r11, [sp, #0] ;CallASWI now incognito as target SWI - B SVC_CallASWI ;re-dispatch - -;SWI number passed in r12 (better for C veneers) -CallASWIR12 ROUT - LDR r11, [sp, #16] ;pick-up target SWI code (r12 pushed by dispatcher) - BIC r11, r11, #&FF000000 ;just in case - STR r11, [sp, #0] ;CallASWIR12 now incognito as target SWI - B SVC_CallASWI ;re-dispatch - ] - - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; In return address, r10-r12 stacked, lr has SPSR for return - -VSet_GenerateError ROUT - - Push lr - [ FixCallBacks - BIC lr, lr, #&0F - ORR lr, lr, #SVC_mode - MSR CPSR_c, lr ; Set caller's interrupt state and 26/32bitness - ] - MOV r1, #Service_Error - BL Issue_Service - - MOV r10, #ErrorV - BL CallVector ; Normally gets to default handler... - - Pull lr ; which raises error; otherwise just - BIC lr, lr, #V_bit ; return with V clear: error claimed! - - MOV r10, #0 ; set up r10 and r11 as required - [ FixCallBacks - MSR CPSR_c, #I32_bit + SVC32_mode ; IRQs off makes CallBackFlag atomic; 32bit so ready for SPSR use - ] - LDRB r11, [r10, #CallBack_Flag] - B SWIReturnWithCallBackFlag - - LTORG - -; ....................... default owner of ErrorV ............................. -; In r0 -> error in current error block - -; Out Exits to user's error handler routine as given by ErrHan -; r1-r9 possibly corrupt. Indeed r10-r12 MAY be duff ... eg. REMOTE - -ErrHandler ROUT - - BL OscliTidy ; close redirection, restore curr FS - - MOV r10, #0 - LDR r11, [r10, #ErrBuf] ; Get pointer to error buffer - - [ No26bitCode - LDR sp_svc, =SVCSTK-4*4 ; Just below top of stack - Pull r14 - STR r14, [r11], #4 ; Return PC for error - | - LDR sp_svc, =SVCSTK-5*4 ; Just below top of stack - Pull r14 ; PSR will be on stack if error at top level - FakeLR r12 ; Fake up the PC+PSR - STR r14, [r11], #4 - ] - - LDR r14, [r0], #4 ; Copy error number - STR r14, [r11], #4 - - ; Copy error string - truncating at 252 - MOV r12, #256-4 - -10 LDRB r14, [r0], #1 - SUBS r12, r12, #1 - MOVLS r14, #0 - STRB r14, [r11], #1 - TEQ r14, #0 - BNE %BT10 - - LDR r14, [r10, #ErrHan] ; And go to error handler - [ :LNOT: No26bitCode - BIC r14, r14, #ARM_CC_Mask - ] - STR r14, [r10, #Curr_Active_Object] - LDR r0, [r10, #ErrHan_ws] ; r0 is his wp - - [ :LNOT: FixCallBacks - LDRB r11, [r10, #CallBack_Flag] - CMP r11, #0 - ] - - MRS r12, CPSR - BIC r12, r12, #I32_bit+F32_bit+&0F ; USR26/32 mode, ARM, IRQs enabled - - [ FixCallBacks - MSR CPSR_c, #I32_bit+SVC32_mode ; disable interrupts for SPSR use and CallBackFlag atomicity - LDRB r11, [r10, #CallBack_Flag] - CMP r11, #0 - | - MSREQ CPSR_c, #I32_bit+SVC32_mode ; disable interrupts for SPSR use - ] - MSREQ SPSR_cxsf, r12 - - Pull "r10-r12", EQ - MOVEQS pc, r14 ; USR mode, IRQs enabled - - Push r14 ; Stack return address - MOV r14, r12 ; Put PSR in R14 - B Do_CallBack ; Can't need postponement, r0,r14,stack - ; such that callback code will normally - ; call error handler - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; check for CallBack possible - -callback_checking - - TST lr, #I32_bit+&0F ; user 26/32 mode, ints enabled? - [ :LNOT: FixCallBacks ; already entered with this CPSR - MSRNE CPSR_c, #I32_bit + SVC32_mode - ] - MSRNE SPSR_cxsf, lr - LDRNE lr, [sp], #4 - Pull "r10-r12", NE - MOVNES pc, lr ; Skip the branch for SVC code speed - -; Further checks: postpone callback if returning V set and R0->RAM - - TST lr, #V_bit ; if no error then do callbacks - BEQ Do_CallBack - TST r11, #CBack_Postpone - [ FixCallBacks - TSTNE r11, #CBack_OldStyle :OR: CBack_VectorReq ; can only postpone if not already or if no callbacks pending - ] - BNE Do_CallBack - [ ROMatTop - CMP r0, #ROM - BHS Do_CallBack - | - CMP r0, #ROM - RSBHIS r12, r0, #ROMLimit - BHI Do_CallBack - ] - [ :LNOT: FixCallBacks - MSR CPSR_c, #I32_bit + SVC32_mode ; ints off while flag updated - LDRB r11, [r10, #CallBack_Flag] - ] - ORR r11, r11, #CBack_Postpone ; signal to IRQs - STRB r11, [r10, #CallBack_Flag] -back_to_user - [ :LNOT: FixCallBacks ; already entered with this CPSR - MSR CPSR_c, #I32_bit + SVC32_mode - ] -back_to_user_irqs_already_off - MSR SPSR_cxsf, lr - LDR lr, [sp], #4 - Pull "r10-r12" - MOVS pc, lr - -Do_CallBack ; CallBack allowed: - [ FixCallBacks - ; Entered in SVC32 mode with IRQs off, r10 = 0 - TST r11, #CBack_Postpone - BICNE r11, r11, #CBack_Postpone - STRNEB r11, [r10, #CallBack_Flag] -Do_CallBack_postpone_already_clear - ] - TST r11, #CBack_VectorReq ; now process any vector entries - MOV r12,lr - BLNE process_callback_chain - MOV lr,r12 - - [ FixCallBacks - LDRB r11, [r10, #CallBack_Flag] ; non-transient callback may have been set during transient callbacks - ] - TST r11, #CBack_OldStyle - BEQ back_to_user - [ :LNOT:No26bitCode - TST r14, #&10 ; must be returning to 26-bit - BNE back_to_user ; on 26-bit systems - ] - [ {TRUE} ; LRust, Fix RP-0609 -; Check that SVC_sp is empty (apart from r14,r10-r12), i.e. system truly is idle - - LDR r12, =SVCSTK-4*4 ; What SVC_sp should be if system idle - CMP sp, r12 ; Stack empty? - BLO back_to_user ; No then no call back - ] - [ FixCallBacks - [ :LNOT: No26bitCode - MSR CPSR_c, #I32_bit + SVC2632 ; back to 26-bit mode - ] - BIC r11, r11, #CBack_OldStyle - | - MSR CPSR_c, #I32_bit + SVC2632 ; ints off while flag updated - LDRB r11, [r10, #CallBack_Flag] - BIC r11, r11, #CBack_Postpone+CBack_OldStyle - ] - STRB r11, [r10, #CallBack_Flag] - - MOV r12, #0 - LDR R12, [R12, #CallBf] - [ No26bitCode - STR r14, [r12, #4*16] ; user PSR - Pull r14 - STR r14, [r12, #4*15] ; user PC - | - FakeLR r10 - STR r14, [r12, #4*15] ; user PC/PSR - ] - MOV r14, r12 - Pull "r10-r12" - [ SASTMhatbroken - STMIA r14!,{r0-r12} - STMIA r14,{r13,r14}^ ; user registers - NOP ; doesn't matter that r14 is different - | - STMIA r14, {r0-r14}^ ; user registers - ] - - MOV R12, #CallAd_ws - LDMIA R12, {R12, PC} ; jump to CallBackHandler - - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; Also called from source.pmf.key, during readc - -process_callback_chain ROUT - - Push "r0-r6, r10-r12, lr" ; save some for the callee too. - [ FixCallBacks :LAND: No26bitCode - MRS r0, CPSR - Push "r0" - ] - MOV r10, #0 - - MSR CPSR_c, #I32_bit + SVC2632 ; ints off while flag updated - LDRB r11, [r10, #CallBack_Flag] - BIC r11, r11, #CBack_VectorReq - STRB r11, [r10, #CallBack_Flag] - -01 - MSR CPSR_c, #I32_bit + SVC2632 ; ints off while flag updated - MOV r2, #0 - LDR r2, [r2, #CallBack_Vector] - TEQ r2, #0 - [ No26bitCode - [ FixCallBacks - Pull "r0", EQ - MSREQ CPSR_c, r0 ; restore original interrupt state and 32bitness - | - MSREQ CPSR_c, #SVC2632 ; ensure exit with ints on - ] - Pull "r0-r6, r10-r12, PC",EQ - | - Pull "r0-r6, r10-r12, PC",EQ,^ - ] - - LDMIA r2, {r10, r11, r12} ; link, addr, r12 - MOV r0, #HeapReason_Free - STR r10, [r0, #CallBack_Vector-HeapReason_Free] ; Keep head valid - - MSR CPSR_c, #SVC2632 ; enable ints for long bits - - [ ChocolateSysHeap - ASSERT ChocolateCBBlocks = ChocolateBlockArrays + 0 - MOV r1,#ChocolateBlockArrays - LDR r1,[r1,#0] - BL FreeChocolateBlock - LDRVS r1, =SysHeapStart - SWIVS XOS_Heap - | - LDR r1, =SysHeapStart - SWI XOS_Heap - ] - - MOV lr, pc - MOV pc, r11 ; call im, with given r12 - - B %BT01 ; loop - - LTORG - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; SWI OS_WriteC - -; In r11 = 0 (look, up there ^) ! - -SWIWriteC ROUT - - MSR CPSR_c, #SVC2632 ; enable interrupts - - Push lr - - [ ROMatTop - LDR r11, [r11, #VecPtrTab+WrchV*4] ; load top node pointer - CMP r11, #ROM - [ StrongARM - BCC WrchThruVector - Push pc, CS ; need to get to ReturnFromVectoredWrch - push PC+12 (old ARM) or PC+8 (StrongARM) - BCS PMFWrchDirect - MOV R0,R0 ; NOP for PC+8 - | - Push pc, CS ; push address of ReturnFromVectoredWrch (PC+12) - BCS PMFWrchDirect - BCC WrchThruVector - ] - | - B WrchThruVector - ] -ReturnFromVectoredWrch - Pull lr - B SLVK_TestV - - -WrchThruVector - MOV r10, #WrchV - BL CallVector - B ReturnFromVectoredWrch - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -SWINewLine ROUT - - MOV r11, lr - SWI XOS_WriteI+10 - SWIVC XOS_WriteI+13 - MOV lr, r11 - B SLVK_TestV - -; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; SWI OS_WriteI+n - -SWIWriteI ROUT - - MOV r10, r0 - AND r0, r11, #&FF - MOV r11, lr ; NB. Order !!! - SWI XOS_WriteC - MOVVC r0, r10 - MOV lr, r11 - B SLVK_TestV ; return setting V - -; ............................................................................. -; define module SWI node format - -ModSWINode_CallAddress * 0 -ModSWINode_MListNode * 4 -ModSWINode_Link * 8 -ModSWINode_Number * 12 -ModSWINode_Size * 16 ; not a field - the node size! - - MACRO -$l ModSWIHashvalOffset $swino, $startreg - [ "$startreg"="" -$l MOV $swino, $swino, LSR #4 - | -$l MOV $swino, $startreg, LSR #4 - ] - AND $swino, $swino, #(ModuleSHT_Entries-1)*4 - MEND - - MACRO -$l ModSWIHashval $swino, $startreg -$l ModSWIHashvalOffset $swino, $startreg - ADD $swino, $swino, #ModuleSWI_HashTab - MEND - - - -NotMainMOSSwi ; Continuation of SWI despatch - - CMP R11, #&200 - BCC SWIWriteI - -; ............................................................................. -; Look round RMs to see if they want it - -ExtensionSWI ROUT - - [ No26bitCode - ASSERT FixR9CorruptionInExtensionSWI - Push "lr" - | - Push "r9, lr" ; first construct the link to pass on. - AND r10, lr, #&F0000000 ; copy in user CCodes - AND r12, lr, #F32_bit+I32_bit ; (inc. IRQ state) - ORR r10, r10, r12, LSL #IF32_26Shift - ADR lr, %FT02 + SVC_mode - ORR lr, lr, r10 - ] - - BIC r12, r11, #Module_SWIChunkSize-1 - ModSWIHashvalOffset r10, r12 - LDR r10, [r10, #ModuleSWI_HashTab] -loopoverhashchain - CMP r10, #0 - BEQ VectorUserSWI - [ No26bitCode - LDR lr, [r10, #ModSWINode_Number] - CMP lr, r12 - | - LDR r9, [r10, #ModSWINode_Number] - CMP r9, r12 - ] - LDRNE r10, [r10, #ModSWINode_Link] - BNE loopoverhashchain - - LDMIA r10, {r10, r12} - LDR r12, [r12, #Module_incarnation_list] ; preferred life - CMP r12, #0 - - [ FixR9CorruptionInExtensionSWI:LAND::LNOT:No26bitCode - Pull "r9", NE ; restore corrupted r9 before calling SWI handler - ;RCM added 'NE' above to fix MED=04655 - ] - - ANDNE r11, r11, #Module_SWIChunkSize-1 - ADDNE r12, r12, #Incarnation_Workspace - [ No26bitCode - ADRNE lr, %FT02 - ] - MOVNE pc, r10 - - -VectorUserSWI ; Not in a module, so call vec - [ FixR9CorruptionInExtensionSWI:LAND::LNOT:No26bitCode - Pull "r9" ; restore corrupted r9 before calling UKSWIV - ] - MOV r10, #UKSWIV ; high SWI number still in R11 - [ No26bitCode - BL CallVector - | - B CallVector ; lr still has user CCs (if 26bit) & points at%FT02 - ] - - -02 - [ FixR9CorruptionInExtensionSWI - Pull "lr" ; r9 already pulled off stack before calling SWI handler or UKSWIV - | - Pull "r9,lr" - ] - MRS r10, CPSR - BIC lr, lr, #&FF000000 ; Can mangle any/all of punter flags - AND r10, r10, #&FF000000 - ORR lr, lr, r10 - B SLVK - -; ....................... default owner of UKSWIV ............................. -; Call UKSWI handler -; Also used to call the upcall handler - -; In r12 = HiServ_ws (or UpCallHan_ws) - -CallUpcallHandler -HighSWI ROUT ; no one on vec wants it: give to handler - - Pull lr ; the link pointing at %BT02 to pass in. - LDMIA r12, {r12, pc} - -; ........................ default UKSWI handler .............................. - -NoSuchSWI ROUT - - Push lr - BL NoHighSWIHandler - Pull lr - B SLVK_SetV - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; .................... default Unused SWI handler ............................. - -NoHighSWIHandler ROUT - - MOV r0, #0 - LDR r0, [r0, #IRQsema] - CMP r0, #0 - ADR r0, ErrorBlock_NoSuchSWI ; Must return static error here - [ No26bitCode - BEQ %FT01 - SETV - MOV pc, lr -01 - | - ORRNES pc, lr, #V_bit - ] - -; Not in IRQ: can safely build a dynamic error - [ International - Push "r1-r4, lr" - SUB sp, sp,#12 - MOV r1, sp - MOV r2, #12 - MOV r0, r11 - SWI XOS_ConvertHex6 ; SWI argument is 00xxxxxx - - MOV r4, r0 ; now strip leading 0s -02 LDRB r2, [r4], #1 - CMP r2, #"0" - BEQ %BT02 - - SUB r4,r4,#1 - ADR r0, ErrorBlock_NoSuchSWI1 - BL TranslateError_UseR4 - ADD sp,sp,#12 - - Pull "r1-r4, lr" - [ No26bitCode - SETV - MOV pc, lr - | - ORRS pc, lr, #V_bit - ] - - MakeErrorBlock NoSuchSWI1 - - | - Push "r1-r3, lr" - LDR r1, =EnvString - LDMIA r0!, {r2, r3} ; number, "SWI " - STMIA r1!, {r2, r3} - MOV r2, #"&" - STRB r2, [r1], #1 - MOV r3, r0 - MOV r0, r11 - MOV r2, #256 - SWI XOS_ConvertHex6 ; SWI argument is 00xxxxxx - -; now strip leading 0s - - MOV r1, r0 -02 LDRB r2, [r1], #1 - CMP r2, #"0" - BEQ %BT02 - CMP r2, #0 - ADDEQ r1, r0, #1 - BEQ %FT03 -04 STRB r2, [r0], #1 - LDRB r2, [r1], #1 - CMP r2, #0 - BNE %BT04 - MOV r1, r0 -03 MOV r2, #" " -01 STRB r2, [r1], #1 - CMP r2, #0 - LDRNEB r2, [r3], #1 - BNE %BT01 - - Pull "r1-r3, lr" - LDR r0, =EnvString - [ No26bitCode - SETV - MOV pc, lr - | - ORRS pc, lr, #V_bit - ] - ] - - MakeErrorBlock NoSuchSWI - - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; Fast SWI handlers for BGet and BPut caches - -BGetSWI ROUT ; Done separately for highest speed - - Push lr - MOV r10, #BGetV ; Cache hit failed, call victor - BL CallVector - Pull lr ; Punter lr has VClear - BIC lr, lr, #C_bit ; Copy C,V to punter lr - ORRCS lr, lr, #C_bit - B SLVK_TestV - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -BPutSWI ROUT ; Done separately for highest speed - - Push "lr" - MOV r10, #BPutV ; Cache hit failed, call victor - BL CallVector - Pull "lr" ; Destack lr(VC) - B SLVK_TestV - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; SWI handlers for all the vectored SWIs that have vecnum=swinum - -; All defined to affect C & V at most - -FSControlSWI ROUT - - MOV r11, #FSCV ; Pretend to be vecnum = swinum swi - ; and just drop through to ... - -VecSwiDespatch ROUT - - Push lr ; this is user's link (or PSR in 32-bit case) - MOV r10, r11 ; SWI number from R11->R10 - - [ No26bitCode - MRS r11, CPSR - AND r14, r14, #&F0000000 ; extract caller's CCs - BIC r11, r11, #&F0000000 ; mask out ours - BIC r11, r11, #I32_bit ; enable IRQs - ORR r11, r11, r14 ; add in CCs - MSR CPSR_cf, r11 ; and set it all up - | - ORR r14, lr, #SVC_mode - BIC r14, r14, #I_bit ; Enable IRQs - TEQP r14, #0 - ] - - BL CallVector - -; So the vectored routine can update the pushed link CCodes if wanted -; No update return is therefore LDMIA stack!, {PC}^ (sort of) -; Update return pulls lr, molests it, then MOVS PC, lr -; Note either return enables IRQ, FIQ - -; ???? Is the DEFAULT owner allowed to corrupt r10,r11 IFF he claims it ???? - - Pull lr ; Punter lr has VClear - BICCC lr, lr, #C_bit ; Copy C,V to punter lr - ORRCS lr, lr, #C_bit - B SLVK_TestV - - -NoIrqVecSwiDespatch ROUT - - Push lr ; this is user's link - MOV r10, r11 ; SWI number from R11->R10 - [ No26bitCode - MRS r11, CPSR - AND r14, r14, #&F0000000 ; extract caller's CCs - BIC r11, r11, #&F0000000 ; mask out ours - ORR r11, r11, #I32_bit ; disable IRQs - ORR r11, r11, r14 ; add in CCs - MSR CPSR_cf, r11 ; and set it all up - | - ORR r14, lr, #SVC_mode+I_bit ; Disable IRQ - TEQP r14, #0 - ] - BL CallVector - Pull lr ; Punter lr has VClear - BICCC lr, lr, #C_bit ; Copy C,V to punter lr - ORRCS lr, lr, #C_bit - B SLVK_TestV - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; SWI OS_GetEnv - -SWI_GetEnv_Code ROUT - - LDR r0, =EnvString - MOV r1, #0 - LDR r1, [r1, #MemLimit] - LDR r2, =EnvTime - B SLVK - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; SWI OS_Exit - -SEXIT ROUT - - BL OscliTidy ; shut redirection, restore FS - -; now see if it's an abort Exit - - LDR r12, ABEX - CMP r1, r12 - [ No26bitCode - TSTEQ r0, #3 - | - TSTEQ r0, #ARM_CC_Mask - ] - MOVNE r2, #0 - MOV r12, #0 - STR r2, [r12, #ReturnCode] - LDR r12, [r12, #RCLimit] - CMP r2, r12 - SWIHI OS_GenerateError ; really generate an error - - ADD sp, sp, #8 ; junk SWI no and R14 on stack - Pull "r10-r12" - MOV r0, #0 - LDR lr, [r0, #SExitA] - STR lr, [r0, #Curr_Active_Object] - LDR r12, [r0, #SExitA_ws] - LDR sp_svc, =SVCSTK - [ No26bitCode - MRS r0, CPSR - MSR CPSR_c, #I32_bit+SVC2632 ; IRQs off (to protect SPSR_svc) - BIC r0, r0, #I32_bit+F32_bit+&0F - MSR SPSR_cxsf, r0 ; Get ready for USR26/32, IRQs on - MOVS pc, lr ; lr->pc, SPSR->CPSR - | - BICS pc, lr, #ARM_CC_Mask - ] - -ABEX = "ABEX" ; Picked up as word - - LTORG - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; SWI OS_CallBack: Set/read callback buffer and handler - -SCALLB MOV r10, #CallBackHandler - -handlecomm - Push "r2, r3, lr" - MOV r3, r0 ; buffer - MOV r0, r10 - BL CallCESWI - MOV r0, r3 - Pull "r2, r3, lr" - B SLVK_TestV - -; ............................................................................. -; SWI OS_BreakSet: Set/read breakpoint buffer and handler - -SBRKCT MOV r10, #BreakPointHandler - B handlecomm - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; SWI OS_ReadEscapeState - -ReadEscapeSWI ROUT - - MOV r10, #0 - LDRB r10, [r10, #ESC_Status] - TST r10, #1 :SHL: 6 - BICEQ lr, lr, #C_bit - ORRNE lr, lr, #C_bit - B SLVK - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; SWI OS_ServiceCall - -Issue_Service_SWI ROUT - - Push lr - BL Issue_Service - Pull lr - B SLVK - - [ StrongARM -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; SWI XOS_PlatformFeatures - -PlatFeatSWI ROUT - Push lr - CMP r0, #0 ;Is it a known reason code? - BNE %FT50 ;No, so send out a service call - - ;Ok, it's the 'code_features' reason code. - LDR r0,[r0, #ProcessorFlags] - TST r0, #CPUFlag_InterruptDelay - ADRNE r1, platfeat_irqinsert ;Yep, so point R1 to the delay routine - MOVEQ r1, #0 - Pull lr - B SLVK ;Return - -platfeat_irqinsert - MOV r0, r0 - MOV r0, r0 - MOV r0, r0 - MOV r0, r0 - MOV r0, r0 - MOV pc, lr - -50 - [ {FALSE} - Push "r1-r8" - MOV r1, #Service_UnknownPlatformFeatures - Pull "r2-r9" - BL Issue_Service - CMP r1, #0 - BNE %FT75 - Push "r2-r9" - Pull "r1-r8" - B SLVK ;Return - ] - -75 ;Get here if the service call isn't claimed. - ADR R0,platfeaterror - [ International - Push "lr" - BL TranslateError - Pull "lr" - ] - B SLVK_SetV - -platfeaterror - & 0 - [ International - = "BadPlatReas", 0 - | - = "Unknown OS_PlatformFeatures reason code", 0 - ] - ALIGN - ] - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; SWI OS_GenerateError - -GenErrorSWI * SLVK_SetV - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - END diff --git a/s/LibKern b/s/LibKern deleted file mode 100644 index cee8aea7..00000000 --- a/s/LibKern +++ /dev/null @@ -1,120 +0,0 @@ -; Copyright 2000 Pace Micro Technology plc -; -; 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. -; -; Kernel utility library - -; void *memset(void *s, int c, size_t n) ------------------------------------------------- - - ROUT -memset - TEQ a3, #0 ; return immediately if zero bytes - MOVEQ pc, lr - - ADD a1, a1, a3 - TST a1, #3 ; check for unaligned end - BNE %FT80 -05 SUBS a3, a3, #32 ; if at least 32, do 32 at a time - BLO %FT50 - - Push "v1-v5" - AND a2, a2, #&FF - ORR a2, a2, a2, LSL #8 - ORR a2, a2, a2, LSL #16 - MOV a4, a2 - MOV v1, a2 - MOV v2, a2 - MOV v3, a2 - MOV v4, a2 - MOV v5, a2 - MOV ip, a2 -10 STMDB a1!, {a2,a4,v1,v2,v3,v4,v5,ip} - SUBS a3, a3, #32 - BHS %BT10 - Pull "v1-v5" - -50 ADDS a3, a3, #32-4 ; if at least 4, do 4 at a time - BMI %FT70 -60 STR a2, [a1, #-4]! - SUBS a3, a3, #4 - BPL %BT60 - -70 ADDS a3, a3, #4 - MOVEQ pc, lr - -80 STRB a2, [a1, #-1]! ; byte at a time until finished or - SUBS a3, a3, #1 ; aligned (if at end, will finish) - MOVEQ pc, lr - TST a1, #3 - BNE %BT80 - B %BT05 - -; unsigned __rt_udiv(unsigned divisor, unsigned dividend) -------------------------------- - ROUT -|__rt_udiv| -; Unsigned divide of a2 by a1: returns quotient in a1, remainder in a2 -; Destroys a3 and ip only - - MOV a3, #0 - RSBS ip, a1, a2, LSR #3 - BCC u_sh2 - RSBS ip, a1, a2, LSR #8 - BCC u_sh7 - MOV a1, a1, LSL #8 - ORR a3, a3, #&FF000000 - RSBS ip, a1, a2, LSR #4 - BCC u_sh3 - RSBS ip, a1, a2, LSR #8 - BCC u_sh7 - MOV a1, a1, LSL #8 - ORR a3, a3, #&00FF0000 - RSBS ip, a1, a2, LSR #8 - MOVCS a1, a1, LSL #8 - ORRCS a3, a3, #&0000FF00 - RSBS ip, a1, a2, LSR #4 - BCC u_sh3 - RSBS ip, a1, #0 - BCS dividebyzero -u_loop MOVCS a1, a1, LSR #8 -u_sh7 RSBS ip, a1, a2, LSR #7 - SUBCS a2, a2, a1, LSL #7 - ADC a3, a3, a3 -u_sh6 RSBS ip, a1, a2, LSR #6 - SUBCS a2, a2, a1, LSL #6 - ADC a3, a3, a3 -u_sh5 RSBS ip, a1, a2, LSR #5 - SUBCS a2, a2, a1, LSL #5 - ADC a3, a3, a3 -u_sh4 RSBS ip, a1, a2, LSR #4 - SUBCS a2, a2, a1, LSL #4 - ADC a3, a3, a3 -u_sh3 RSBS ip, a1, a2, LSR #3 - SUBCS a2, a2, a1, LSL #3 - ADC a3, a3, a3 -u_sh2 RSBS ip, a1, a2, LSR #2 - SUBCS a2, a2, a1, LSL #2 - ADC a3, a3, a3 -u_sh1 RSBS ip, a1, a2, LSR #1 - SUBCS a2, a2, a1, LSL #1 - ADC a3, a3, a3 -u_sh0 RSBS ip, a1, a2 - SUBCS a2, a2, a1 - ADCS a3, a3, a3 - BCS u_loop - MOV a1, a3 - MOV pc, lr - -dividebyzero - B dividebyzero - - END diff --git a/s/MEMC1 b/s/MEMC1 deleted file mode 100644 index 2709f320..00000000 --- a/s/MEMC1 +++ /dev/null @@ -1,571 +0,0 @@ -; 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. -; -; > MEMC1 - -; MEMC interface file - MEMC1 version - -; Created by TMD 10-Aug-90 - -VInit * &03600000 -VStart * &03620000 -VEnd * &03640000 -CInit * &03660000 -; SStart * &03680000 -; SEnd * &036A0000 -; SPtr * &036C0000 - -; ***************************************************************************** -; -; SetDAG - Program DMA address generator R1 with physical address R0 -; -; in: r0 = physical address -; r1 = index of DMA address generator to program, as defined in vdudecl -; -; out: All registers preserved, operation ignored if illegal -; - -SetDAG ENTRY "r0" - CMP r1, #MEMCDAG_MaxReason - EXIT HI - ADR r14, DAGAddressTable - LDR r14, [r14, r1, LSL #2] ; load base address in MEMC1 - MOV r0, r0, LSR #4 ; bottom 4 bits irrelevant - CMP r0, #(1 :SHL: 15) ; ensure in range - ORRCC r14, r14, r0, LSL #2 - STRCC r14, [r14] ; any old data will do - EXIT - - GBLA DAGIndex -DAGIndex SETA 0 - - MACRO - DAGTab $reason, $address - ASSERT ($reason)=DAGIndex - & $address -DAGIndex SETA DAGIndex + 1 - MEND - -DAGAddressTable - DAGTab MEMCDAG_VInit, VInit - DAGTab MEMCDAG_VStart, VStart - DAGTab MEMCDAG_VEnd, VEnd - DAGTab MEMCDAG_CInit, CInit - -;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; CAM manipulation utility routines - -BangCamUpdate ROUT - -; R2 = CAM entry no -; R3 = logaddr -; R9 = current MEMC value -; R11 = PPL -; set and update tables - - MOV R4, #0 - LDR R4, [R4, #CamEntriesPointer] - ORR r0, r3, r11, LSL #28 ; top nibble is PPL - STR r0, [R4, R2, LSL #2] - -BangCam - -; r0 corrupted -; r1 corrupted -; R2 = CAM entry no -; R3 = logaddr -; r4 corrupted -; r5 spare! -; r6 corrupted -; r7, r8 spare -; R9 = current MEMC value -; r10 spare -; R11 = PPL -; r12 spare - - AND R4, R9, #&C ; pagesize - ADR R0, PageMangleTable - LDR R0, [R0, R4] ; load data table pointer - MOV R4, #0 -01 LDR R1, [R0], #4 - CMP R1, #-1 - BEQ %FT02 - AND R6, R2, R1 - LDR R1, [R0], #4 - CMP R1, #0 - RSBMI R1, R1, #0 - ORRPL R4, R4, R6, LSL R1 - ORRMI R4, R4, R6, LSR R1 - B %BT01 - -02 LDR R1, [R0], #4 - CMP R1, #-1 - BEQ %FT03 - AND R6, R3, R1 - LDR R1, [R0], #4 - CMP R1, #0 - RSBMI R1, R1, #0 - ORRPL R4, R4, R6, LSL R1 - ORRMI R4, R4, R6, LSR R1 - B %BT02 - -03 ORR R4, R4, #CAM - ORR R4, R4, R11, LSL #8 ; stuff in PPL - STR R4, [R4] ; and write it - MOV PC, LR - -; Data to drive CAM setting - -PageMangleTable - & PageMangle4K - & PageMangle8K - & PageMangle16K - & PageMangle32K - -; For each page size, pairs of masks and shift factors to put the bits in the -; right place. Two sets: operations on Physical Page Number, operations on -; Logical Page Number. - -; Shifts are Shift Left values (<<). Each section terminated by -1 - -PageMangle4K -; PPN: - & 2_011111111 - & 0 ; bits in right place - & -1 -; LPN: - & 2_1100000000000:SHL:12 - & (11-12)-12 ; LPN[12:11] -> A[11:10] - & 2_0011111111111:SHL:12 - & (22-10)-12 ; LPN[10:0 ] -> A[22:12] - & -1 - -PageMangle8K -; PPN: - & 2_010000000 - & 7-7 ; PPN[7] -> A[7] - & 2_001000000 - & 0-6 ; PPN[6] -> A[0] - & 2_000111111 - & 6-5 ; PPN[5:0] -> A[6:1] - & -1 -; LPN: - & 2_110000000000:SHL:13 - & (11-11)-13 ; LPN[11:10] -> A[11:10] - & 2_001111111111:SHL:13 - & (22-9)-13 ; LPN[9:0] -> A[22:13] - & -1 - -PageMangle16K -; PPN: - & 2_010000000 - & 7-7 ; PPN[7] -> A[7] - & 2_001100000 - & 1-6 ; PPN[6:5] -> A[1:0] - & 2_000011111 - & 6-4 ; PPN[4:0] -> A[6:2] - & -1 -; LPN: - & 2_11000000000:SHL:14 - & (11-10)-14 ; LPN[10:9] -> A[11:10] - & 2_00111111111:SHL:14 - & (22-8)-14 ; LPN[8:0] -> A[22:14] - & -1 - -PageMangle32K -; PPN: - & 2_100000000 - & 12-8 ; PPN[8] -> A[12] - & 2_010000000 - & 7-7 ; PPN[7] -> A[7] - & 2_001000000 - & 1-6 ; PPN[6] -> A[1] - & 2_000100000 - & 2-5 ; PPN[5] -> A[2] - & 2_000010000 - & 0-4 ; PPN[4] -> A[0] - & 2_000001111 - & 6-3 ; PPN[3:0] -> A[6:3] - & -1 -; LPN: - & 2_1100000000:SHL:15 - & (11-9)-15 ; LPN[9:8] -> A[11:10] - & 2_0011111111:SHL:15 - & (22-7)-15 ; LPN[7:0] -> A[22:15] - & -1 - -PageSizes - & 4*1024 ; 0 is 4K - & 8*1024 ; 4 is 8K - & 16*1024 ; 8 is 16 - & 32*1024 ; C is 32 - -PageShifts - = 12, 13, 0, 14 ; 1 2 3 4 - = 0, 0, 0, 15 ; 5 6 7 8 - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; SWI OS_UpdateMEMC: Read/write MEMC1 control register - -SSETMEMC ROUT - - AND r10, r0, r1 - MOV r12, #0 - TEQP pc, #SVC_mode+I_bit+F_bit - LDR r0, [r12, #MEMC_CR_SoftCopy] ; return old value - BIC r11, r0, r1 - ORR r11, r11, R10 - BIC r11, r11, #&FF000000 - BIC r11, r11, #&00F00000 - ORR r11, r11, #MEMCADR - STR r11, [r12, #MEMC_CR_SoftCopy] - STR r11, [r11] - TEQP pc, #SVC_mode+I_bit - ExitSWIHandler - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; -; ClearPhysRAM - Routine to clear "all" memory -; -; While this routine is running, keyboard IRQs may happen. For this reason -; it avoids LogRAM 0..31 (where hardware IRQ vector is) and PhysRAM -; 0..31 where the IRQ workspace is. -; -; r7 contains memory speed and must be preserved -; r8 contains page size and must be preserved -; r9 contains MEMC control register and must be preserved -; - -ClearPhysRAM ROUT - MOV r0, #0 - MOV r1, #0 - MOV r2, #0 - MOV r3, #0 - MOV r4, #0 - MOV r5, #0 - MOV r6, #0 - MOV r11, #0 - MOV r12, #PhysRam - CMP r13, #512*1024 - ADDEQ r10, r12, #(512-64)*1024 ; get address that's logram 0 - ADDNE r10, r12, #512*1024 - ADD r13, r13, #PhysRam ; end of memory - ADD r12, r12, #4*8 ; skip minimal startup workspace -10 CMP r12, R10 - ADDEQ r12, r12, #4*8 ; skip physram that's logram 0 - STMNEIA r12!, {r0-r6, r11} - CMP r12, r13 - BNE %BT10 - SUB r13, r13, #PhysRam - - LDR r0, =OsbyteVars + :INDEX: LastBREAK - MOV r1, #&80 - STRB r1, [r0] ; flag the fact that RAM cleared - MOV pc, lr - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; -; InitMEMC - Initialise memory controller -; - -InitMEMC ROUT - LDR R0, ResetMemC_Value - STR R0, [R0] ; set ROM access times, refresh on flyback, no DMA - MOV pc, lr - -; -> MemSize - -; (non-destructive) algorithm to determine MEMC RAM configuration -; -; Dave Flynn and Alasdair Thomas -; 17-March-87 -; -; Spooling checkered by NRaine and SSwales ! -; 8MByte check bodged in by APT -; -; NOTE: Routines MemSize and TimeCPU are called by the power-on test software, -; so their specifications MUST not change. -; -; Set MEMC for 32-k page then analyse signature of possible -; external RAM configurations... -; The configurations are: -; -; Ram Size Page Size Configuration (Phys RAM) Signature -;-------------------------------------------------------------------- -; 16MByte 32k 4*32*1Mx1 A13,A20,A21,A22,A23,A23.5 distinct -; 16MByte 32k 16*8*256kx4 A13,A20,A21,A22,A23,A23.5 distinct -; -; 12MByte 32k 3*32*1Mx1 A13,A20,A21,A22,A23 OK, A23.5 fail -; 12MByte 32k 12*8*256kx4 A13,A20,A21,A22,A23 OK, A23.5 fail -; -; 8MByte 32k 2*32*1Mx1 A13,A20,A21,A22 distinct, A23 fail -; 8MByte 32k 8*8*256kx4 A13,A20,A21,A22 distinct, A23 fail -; -; 4Mbyte 32k 32*1Mx1 A13,A21,A20 distinct, A22,A23 fail -; 4Mbyte 32k 4*8*256kx4 A13,A21,A20 distinct, A22,A23 fail -; -; 2Mbyte 32k expandable 2*8*256kx4 A13,A20 distinct, A21 fails -; 2Mbyte ??? 16k fixed 2*8*256kx4 A13,A21 distinct, A20 fails -; -; 1Mbyte 8k 32*256kx1 A13,A20 fail, A19,A18,A12 distinct -; 1Mbyte 8k 8*256kx1 A13,A20 fail, A19,A18,A12 distinct -; 1Mbyte 8k 4*8*64kx4 A13,A20 fail, A19,A18,A12 distinct -; -; 512Kbyte 8k expandable 2*8*64kx4 A13,A20,A19 fail, A12,A18 distinct -; 512Kbyte 4k fixed 2*8*64kx4 A13,A20,A12 fail, A19,A18 distinct -; -; 256Kbyte 4K 8*64kx4 A13,A20,A12,A18 fail, A21,A19 ok -; 256Kbyte 4K 32*64kx1 A13,A20,A12,A18 fail, A21,A19 ok -; - -Z_Flag * &40000000 - -; MemSize routine... enter with 32K pagesize set -; R0 returns page size -; R1 returns memory size -; R2 returns value set in MEMC -; uses R3-R7 - -MemSize ROUT - MOV r7, lr - MOV r0, #PhysRam - ADD r1, r0, #A13 - BL DistinctAddresses - BNE %10 - ADD r1, r0, #A21 - BL DistinctAddresses - MOVNE r0, #Page32K - MOVNE r1, #2048*1024 - BNE MemSizeDone - - MOV r0, #PhysRam - ADD r1, r0, #4*1024*1024 - BL DistinctAddresses - MOVNE r0, #Page32K - MOVNE r1, #4*1024*1024 - BNE MemSizeDone - - MOV r0, #PhysRam - ADD r1, r0, #8*1024*1024 - BL DistinctAddresses - MOVNE r0, #Page32K - MOVNE r1, #8*1024*1024 - BNE MemSizeDone - - MOV r0, #PhysRam - ADD r1, r0, #12*1024*1024 - BL DistinctAddresses - MOV r0, #Page32K - MOVNE r1, #12*1024*1024 - MOVEQ r1, #16*1024*1024 - B MemSizeDone - -10 ADD r1, r0, #A20 - BL DistinctAddresses - BNE %20 - MOV r0, #Page16K - MOV r1, #2048*1024 - B MemSizeDone - -20 ADD r1, r0, #A19 - BL DistinctAddresses - BEQ %30 - MOV r0, #Page8K - MOV r1, #512*1024 - B MemSizeDone - -30 ADD r1, r0, #A18 - BL DistinctAddresses - BEQ %40 - MOV r0, #Page4K - MOV r1, #256*1024 - B MemSizeDone - -40 ADD r1, r0, #A12 - BL DistinctAddresses - BEQ %50 - MOV r0, #Page4K - MOV r1, #512*1024 - B MemSizeDone - -50 MOV r0, #Page8K - MOV r1, #1024*1024 - -MemSizeDone - LDR r2, ResetMemC_Value - BIC r2, r2, #&C - ORR r2, r2, r0 - STR r2, [r2] ; set MEMC to right state - ADR r3, PageSizes - LDR r0, [r3, r0] ; r0 = convert from page size indicator into actual page size (in bytes) - MOV pc, r7 - - -; DistinctAddresses routine... -; r0,r1 are the addresses to check -; uses r2-5 -; writes interleaved patterns (to prevent dynamic storage...) -; checks writing every bit low and high... -; return Z-flag set if distinct - -DistinctAddresses ROUT - LDR r2, [r0] ; preserve - LDR r3, [r1] - LDR r4, Pattern - STR r4, [r0] ; mark first - MOV r5, r4, ROR #16 - STR r5, [r1] ; mark second - LDR r5, [r0] - CMP r5, r4 ; check first - BNE %10 ; exit with Z clear - LDR r5, [r1] ; check second - CMP r5, r4, ROR #16 ; clear Z if not same - BNE %10 -; now check inverse bit writes - STR r4, [r1] ; mark second - MOV r5, r4, ROR #16 - STR r5, [r0] ; mark first - LDR r5, [r1] - CMP r5, r4 ; check second - BNE %10 ; exit with Z clear - LDR r5, [r0] ; check first - CMP r5, r4, ROR #16 ; clear Z if not same -10 STR r3, [r1] ; restore - STR r2, [r0] - ORREQ lr, lr, #Z_Flag - BICNE lr, lr, #Z_Flag - MOVS pc, lr - -Pattern - & &AAFF5500 ; shiftable bit check pattern - -; init state with masked out page size - -ResetMemC_Value - & &E010C :OR: MEMCADR ; slugged ROMs + flyback refresh only + 32K page - -; Constants -; -A21 * 1:SHL:21 -A20 * 1:SHL:20 -A19 * 1:SHL:19 -A18 * 1:SHL:18 -A13 * 1:SHL:13 -A12 * 1:SHL:12 - -Page32K * &C ; in MEMC control reg patterns... -Page16K * &8 -Page8K * &4 -Page4K * &0 - - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; In r0-r6 trashable -; r9 = Current MEMC CR - -; Out r9 MEMC value with slowest ROM speed, correct pagesize -; r7 processor speed in kHz, tbs -> MEMC1a - -ncpuloops * 1024 ; don't go longer than 4ms without refresh ! -nmulloops * 128 - -TimeCPU ROUT - - BIC r9, r9, #3 :SHL: 8 - STR r9, [r9] ; turn off refresh for a bit - -; Time CPU/Memory speed - - LDR r1, =&7FFE ; 32K @ 2MHz = ~16ms limit - MOV r3, #IOC - - MOV r0, r1, LSR #8 - STRB r1, [r3, #Timer1LL] - STRB r0, [r3, #Timer1LH] - LDR r0, =ncpuloops - STRB r0, [r3, #Timer1GO] ; start the timer NOW - B %FT10 ; Looks superfluous, but is required - ; to get ncpuloops pipeline breaks - -10 SUBS r0, r0, #1 ; 1S - BNE %BT10 ; 1N + 2S - - STRB r0, [r3, #Timer1LR] ; latch count NOW - LDRB r2, [r3, #Timer1CL] - LDRB r0, [r3, #Timer1CH] - ADD r2, r2, r0, LSL #8 ; count after looping is ... - - SUB r2, r1, r2 ; decrements ! - MOV r2, r2, LSR #1 ; IOC clock decrements at 2MHz - -; Time CPU/MEMC Multiply time - - MOV r4, #-1 ; Gives worst case MUL - - MOV r0, r1, LSR #8 - STRB r1, [r3, #Timer1LL] - STRB r0, [r3, #Timer1LH] - LDR r0, =nmulloops - STRB r0, [r3, #Timer1GO] ; start the timer NOW - B %FT20 ; Looks superfluous, but is required - ; to get nmulloops pipeline breaks - -20 MUL r5, r4, r4 ; 1S + 16I - MUL r5, r4, r4 ; 1S + 16I - SUBS r0, r0, #1 ; 1S - BNE %BT20 ; 1N + 2S - - STRB r0, [r3, #Timer1LR] ; latch count NOW - LDRB r4, [r3, #Timer1CL] - LDRB r0, [r3, #Timer1CH] - ADD r4, r4, r0, LSL #8 ; count after looping is ... - - SUB r4, r1, r4 ; decrements ! - MOV r4, r4, LSR #1 ; IOC clock decrements at 2MHz - - ORR r9, r9, #1 :SHL: 8 ; set refresh on flyback - STR r9, [r9] ; restore MEMC state a.s.a.p. - -; In ROM - each cpu loop took 4R cycles @ 8/f*500ns/cycle - - LDR r0, =4*(8*500/1000)*ncpuloops*1000 - DivRem r7, r0, r2, r1 ; r2 preserved - MOV r0, #&80 ; At 8 MHz and below, run fast ROMs - LDR r1, =8050 ; Over 8 MHz, need medium ROMs - CMP r7, r1 - MOVHI r0, #&40 - LDR r1, =13000 ; Over 13 MHz, need slowest ROMs - CMP r7, r1 - MOVHI r0, #&00 - ORR r9, r9, r0 - STR r9, [r9] ; Set ROM speed appropriately - - ASSERT ncpuloops = 8*nmulloops ; for given ratio cutoff <------------ - - MOV r4, r4, LSL #10 ; *1024 to get resolution on divide - DivRem r0, r4, r2, r1 - LDR r1, =1100 ; Cutoff point; MEMC1 longer than this - CMP r0, r1 - ORRLO r7, r7, #1 :SHL: 16 ; Note MEMC1a prescence - - MOV pc, lr - -; Typical figures give (in ROM at 8MHz): - -; MEMC1 2048 CPU, 2432 MEMC -> MUL ratio 1216 -; MEMC1a 2048 864 432 - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - END diff --git a/s/MEMC2 b/s/MEMC2 deleted file mode 100644 index ea1afe57..00000000 --- a/s/MEMC2 +++ /dev/null @@ -1,713 +0,0 @@ -; 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. -; -; > MEMC2 - -; MEMC interface file - MEMC2 version - -; Created by TMD 10-Aug-90 - -PhysRAML2PT * &02000000 + (512+64)*1024 - -; Synonyms - -VInit * MEMC2Address + MEMC2_VINITe -VStart * MEMC2Address + MEMC2_VSTRTe -VEnd * MEMC2Address + MEMC2_VENDe -CInit * MEMC2Address + MEMC2_CINIT - -; ***************************************************************************** -; -; SetDAG - Program DMA address generator R1 with physical address R0 -; -; in: r0 = physical address -; r1 = index of DMA address generator to program, as defined in vdudecl -; -; out: All registers preserved, operation ignored if illegal -; - -SetDAG ENTRY "r0,r1" - CMP r1, #MEMCDAG_MaxReason - EXIT HI - ADR r14, DAGAddressTable - LDR r14, [r14, r1, LSL #2] ; load base address in MEMC2 - MOV r1, r0, LSR #16 ; r1 is top 16 bits - EOR r0, r0, r1, LSL #16 ; and r0 is bottom 16 bits - BIC r0, r0, #&0F ; bits 0..3 must be clear - BIC r1, r1, #&F000 ; and bits 28..31 must be clear - STMIA r14, {r0, r1} ; atomic update (we believe) - EXIT - - GBLA DAGIndex -DAGIndex SETA 0 - - MACRO - DAGTab $reason, $address - ASSERT ($reason)=DAGIndex - & $address -DAGIndex SETA DAGIndex + 1 - MEND - -DAGAddressTable - DAGTab MEMCDAG_VInit, VInit - DAGTab MEMCDAG_VStart, VStart - DAGTab MEMCDAG_VEnd, VEnd - DAGTab MEMCDAG_CInit, CInit - -; **************** CAM manipulation utility routines *********************************** - -; ************************************************************************************** -; -; BangCamUpdate - Update CAM entry and soft copy -; -; This part of the routine has to do more work on MEMC2 -; -; First look in the CamEntries table to find the logical address L this physical page is -; currently allocated to. Then check in the Level 2 page tables to see if page L is currently -; at page R2. If it is, then map page L to be inaccessible, otherwise leave page L alone. -; Then map logical page R3 to physical page R2. -; -; in: r2 = physical page number -; r3 = logical address -; r9 = current MEMC1 control register (irrelevant on MEMC2) -; r11 = PPL -; -; out: r0, r1, r4, r6 corrupted -; r2, r3, r5, r7-r12 preserved -; -; NB Use of stack is allowed in this routine - -BangCamUpdate ROUT - MOV r1, #0 - LDR r1, [r1, #CamEntriesPointer] - LDR r0, [r1, r2, LSL #2] ; r0 = current logaddress + PPL for phys page r2 - ORR r4, r3, r11, LSL #28 ; new entry for CamEntries - STR r4, [r1, r2, LSL #2] ; update - - BIC r0, r0, #&F0000000 ; just get logical address - LDR r1, =PhysRAML2PT ; point to page tables - LDR r4, [r1, r0, LSR #11] ; get physical page + PPL for this logical page - TEQ r2, r4, LSR #3 ; see if still there - BNE %FT10 ; if not there, then just put in new page - - Push "r3, r14" - MOV r3, r0 ; map out old page at this logical address - MOV r0, #0 ; physical page 0 but PPL(MEMC2)=0 ie no access, not even for me! - BL BangL2PT ; map page out - Pull "r3, r14" -10 - -; and drop thru to ... - -; ************************************************************************************** -; -; BangCam - Update CAM entry, but not soft copy -; -; This routine maps a physical page to a given logical address -; For MEMC2, I assume that the physical page was previously not mapped -; anywhere else - on MEMC1 it would automatically unmap any logical -; address that the physical page was previously at, but on MEMC2 it won't -; -; in: r2 = physical page number -; r3 = logical address -; r9 = current MEMC1 control register (irrelevant on MEMC2) -; r11 = PPL -; -; out: r0, r1, r4, r6 corrupted -; r2, r3, r5, r7-r12 preserved -; -; NB Can't use stack - there might not be one! - -BangCam - ADR r0, PPLTrans ; translate MEMC1 PPL to MEMC2 PPL - LDRB r0, [r0, r11] - ORR r0, r0, r2, LSL #3 ; value to store in level 2 page table - ; is PPL :OR: (phys page number << 3) - - LDR r1, =PhysRAML2PT ; point to level 2 page tables - -BangL2PT ; internal entry point used only by BangCamUpdate - BICS r4, r3, #(3 :SHL: 11) ; ensure going to be on word boundary (EQ => logical page zero) - STR r0, [r1, r4, LSR #11] ; update level 2 page table - - MOV r6, #MEMC2Address - STREQ r0, [r6, #MEMC2_SuperPageZero] ; if logical page 0 then update special entry - - MOV r0, #0 ; now flush the TLB - STR r0, [r6, #MEMC2_Flush] - - MOV pc, lr - -PPLTrans - = 6 ; R any W any - = 3 ; R any W sup - = 2 ; R sup W sup - = 2 ; R sup W sup - -PageSizes - & 4*1024 ; 0 is 4K - & 8*1024 ; 4 is 8K - & 16*1024 ; 8 is 16 - & 32*1024 ; C is 32 - -PageShifts - = 12, 13, 0, 14 ; 1 2 3 4 - = 0, 0, 0, 15 ; 5 6 7 8 - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; SWI OS_UpdateMEMC: Read/write MEMC1 control register - -SSETMEMC ROUT - - AND r10, r0, r1 - MOV r12, #0 - TEQP pc, #SVC_mode+I_bit+F_bit - LDR r0, [r12, #MEMC_CR_SoftCopy] ; return old value - BIC r11, r0, r1 - ORR r11, r11, R10 - BIC r11, r11, #&FF000000 - BIC r11, r11, #&00F00000 - ORR r11, r11, #MEMCADR - STR r11, [r12, #MEMC_CR_SoftCopy] - -; We now have to mimic the relevant bits of the MEMC1 control register -; -; bits 0,1 => unused -; bits 2,3 => page size, irrelevant since always 8K -; bits 4,5 => low ROM access time, irrelevant since this has to be fixed -; bits 6,7 => hi ROM access time, -----------------""------------------ -; bits 8,9 => DRAM refresh control, irrelevant (refresh must always be on) -; bit 10 => Video/cursor DMA enable, corresponds to bit venbe of VATT -; (and possibly bit venbo of IATT for interlaced displays) -; Unfortunately VATT (and IATT) is a write-only register. Later on -; we might have a soft copy of these, but for now just write whole -; register. -; bit 11 => Sound DMA enable, ignore for now -; bit 12 => OS mode, ignore - -; Program all of VATT -; -; vdis = 0 (don't disable DMA after one buffer) -; venbe = (bit 10 of r11) -; vrnw = 1 (read from RAM, not write) -; vmske = 0 (no interrupts at end of buffer) - - MOV r12, # (0 * VATT_vdis) + (0 * VATT_venbe) + (1 * VATT_vrnw) + (0 * VATT_vmske) - TST r11, # (1 :SHL: 10) - ORRNE r12, r12, # VATT_venbe - MOV r10, #MEMC2Address - STR r12, [r10, #MEMC2_VATT] - - TEQP pc, #SVC_mode+I_bit - ExitSWIHandler - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; -; ClearPhysRAM - Routine to clear "all" memory -; -; While this routine is running, keyboard IRQs may happen. For this reason -; it avoids LogRAM 0..31 (where hardware IRQ vector is) and PhysRAM -; 0..31 where the IRQ workspace is. -; -; On MEMC2 it also has to avoid the pages where the level 2 page tables are -; -; r7 contains memory speed and must be preserved -; r8 contains page size and must be preserved -; r9 contains MEMC control register and must be preserved -; - -ClearPhysRAM ROUT - MOV r0, #0 - MOV r1, #0 - MOV r2, #0 - MOV r3, #0 - MOV r11, #0 - MOV r4, #PhysRam - CMP r13, #512*1024 - ADDEQ r10, r4, #(512-64)*1024 ; get address that's logram 0 - ADDNE r10, r4, #512*1024 - ADD r13, r13, #PhysRam ; end of memory - ADD r12, r4, #PhysRAML2PT-PhysRam - ADD r4, r4, #4*8 ; skip minimal startup workspace -10 - CMP r4, r10 - ADDEQ r4, r4, #4*8 ; skip physram that's logram 0 - CMP r4, r12 - ADDEQ r4, r4, #32*1024 ; skip 32K of L2PT - STMNEIA r4!, {r0-r3} - CMP r4, r13 - BNE %BT10 - SUB r13, r13, #PhysRam - - LDR r0, =OsbyteVars + :INDEX: LastBREAK - MOV r1, #&80 - STRB r1, [r0] ; flag the fact that RAM cleared - MOV pc, lr - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; -; InitMEMC - Initialise memory controller -; - -InitMEMC ROUT - MOV r0, # MEMC2Address - MOV r1, # Control_romfast - STR r1, [r0, #MEMC2_Control] ; make ROMS go fast - - ADR r1, ClockTimingTable ; initialise CLK block - LDMIA r1, {r2-r5} - ADD r1, r0, #MEMC2_clkj0 - STMIA r1, {r2-r5} - - ADR r1, DRAMTimingTable ; initialise DRAM block - LDMIA r1, {r2-r8} - ADD r1, r0, #MEMC2_rwt0 - STMIA r1, {r2-r8} - - LDR r1, rtype_value - STR r1, [r0, #MEMC2_rtype] - - LDR r1, refr_value - STR r1, [r0, #MEMC2_refr] - - MOV r1, # (PhysRAML2PT-PhysRam)/(8*1024) ; level 1 entry (paged) for 0..16M - MOV r2, # (PhysRAML2PT+8*1024-PhysRam)/(8*1024) ; level 1 entry (paged) for 16M..32M - MOV r3, # Prot_UrwSRW+(L1D_RAM :SHL: 3)+(L1D_RAM :SHL: 5)+(L1D_RAM :SHL: 7)+(L1D_RAM :SHL: 9)+(0 :SHL: 11) - ; level 1 entry (direct) for 32M..48M (all RAM, base 0) - LDR r4, = Prot_URwSRW+(L1D_IO :SHL: 3)+(L1D_PROG :SHL: 5)+(L1D_ROM :SHL: 7)+(L1D_ROM :SHL: 9)+(0 :SHL: 11) - ; level 1 entry (direct) for 48M..64M (IO,PROG,ROM,ROM) - ADD r5, r0, #MEMC2_Level1+L1_Paged+L1_Sec0 - ADD r6, r5, #4*2*16 ; cycle thru all 4 bus masters and (USR,SPV) - ADD r7, r5, #(L1_Direct+L1_Sec2)-(L1_Paged+L1_Sec0) -10 - STMIA r5, {r1,r2} ; set up the paged sections 0,1 - STMIA r7, {r3,r4} ; set up the direct sections 2,3 - ADD r5, r5, #16 - ADD r7, r7, #16 - TEQ r5, r6 ; have we got to the end ? - BNE %BT10 - -; Now turn on the translation, but don't set up the level 2 page tables until later, -; when we know the DRAM multiplex option - - LDR r1, = Control_ton + Control_l1on + Control_romfast - STR r1, [r0, #MEMC2_Control] - -; now set up VINC - - MOV r1, #&10 ; low bits - MOV r2, #&00 ; high bits - ADD r3, r0, #MEMC2_VINC - STMIA r3, {r1,r2} - - MOV pc, lr - -ClockTimingTable -J0 & &F200 ; 3 / 2 -J1 & &F200 ; 3 / 2 -RSPEED & &1C00 ; 3 / 3 -ISPEED & &B800 ; 2.5 / 2.5 - -DRAMTimingTable -RWT0 & &2A320 -RRD0 & &2AC80 -RSQ0 & &0B200 -B0Dummy & 0 -RWT1 & &2A320 -RRD1 & &2AC80 -RSQ1 & &0B200 - -rtype_value & &3333 ; Bank Type [x,bank,s1,s0] * 4 ; set largest memory type by default - -refr_value & &1086 ; Enable refresh, refresh length = 10 hclk ticks, refresh period = 12us - -; -> MemSize - -; (non-destructive) algorithm to determine MEMC RAM configuration -; -; Dave Flynn and Alasdair Thomas -; 17-March-87 -; -; Spooling checkered by NRaine and SSwales ! -; 8MByte check bodged in by APT -; -; NOTE: Routines MemSize and TimeCPU are called by the power-on test software, -; so their specifications MUST not change. -; -; Set MEMC for 32-k page then analyse signature of possible -; external RAM configurations... -; The configurations are: -; -; Ram Size Page Size Configuration (Phys RAM) Signature -;-------------------------------------------------------------------- -; 16MByte 32k 4*32*1Mx1 A13,A20,A21,A22,A23,A23.5 distinct -; 16MByte 32k 16*8*256kx4 A13,A20,A21,A22,A23,A23.5 distinct -; -; 12MByte 32k 3*32*1Mx1 A13,A20,A21,A22,A23 OK, A23.5 fail -; 12MByte 32k 12*8*256kx4 A13,A20,A21,A22,A23 OK, A23.5 fail -; -; 8MByte 32k 2*32*1Mx1 A13,A20,A21,A22 distinct, A23 fail -; 8MByte 32k 8*8*256kx4 A13,A20,A21,A22 distinct, A23 fail -; -; 4Mbyte 32k 32*1Mx1 A13,A21,A20 distinct, A22,A23 fail -; 4Mbyte 32k 4*8*256kx4 A13,A21,A20 distinct, A22,A23 fail -; -; 2Mbyte 32k expandable 2*8*256kx4 A13,A20 distinct, A21 fails -; 2Mbyte ??? 16k fixed 2*8*256kx4 A13,A21 distinct, A20 fails -; -; 1Mbyte 8k 32*256kx1 A13,A20 fail, A19,A18,A12 distinct -; 1Mbyte 8k 8*256kx1 A13,A20 fail, A19,A18,A12 distinct -; 1Mbyte 8k 4*8*64kx4 A13,A20 fail, A19,A18,A12 distinct -; -; 512Kbyte 8k expandable 2*8*64kx4 A13,A20,A19 fail, A12,A18 distinct -; 512Kbyte 4k fixed 2*8*64kx4 A13,A20,A12 fail, A19,A18 distinct -; -; 256Kbyte 4K 8*64kx4 A13,A20,A12,A18 fail, A21,A19 ok -; 256Kbyte 4K 32*64kx1 A13,A20,A12,A18 fail, A21,A19 ok -; - -Z_Flag * &40000000 - -; MemSize routine... enter with 32K pagesize set -; R0 returns page size -; R1 returns memory size -; R2 returns value set in MEMC -; uses R3-R7 - -MemSize ROUT - [ {TRUE} ; now work on different configurations, but only bank zero - MOV r7, lr - -; first find out appropriate rtype value -; initial routine has set DRAM type to 3 - - MOV r0, #PhysRam - ADD r1, r0, #A9 ; if A9 ghosts - BL DistinctAddresses - MOVNE r0, #2_00 ; then type 00 - BNE %FT10 - - ADD r1, r0, #A11 ; else if A11 ghosts - BL DistinctAddresses - MOVNE r0, #2_01 ; then type 01 - BNE %FT10 - - ADD r1, r0, #A12 ; else if A12 ghosts - BL DistinctAddresses - MOVNE r0, #2_01 ; then type 01 - MOVEQ r0, #2_11 ; else type 11 -10 - LDR r1, rtype_value - BIC r1, r1, #2_11 - ORR r1, r1, r0 - MOV r0, #MEMC2Address - STR r1, [r0, #MEMC2_rtype] - -; having set up the DRAM multiplexing correctly, we can now zap the L2PT -; to no access for any page - - LDR r1, =PhysRAML2PT - ADD r2, r1, #2*8*1024 ; two L2PT tables at the moment - MOV r3, #0 ; page 0, no access - MOV r4, #0 - MOV r5, #0 - MOV r6, #0 -15 - STMIA r1!,{r3-r6} - TEQ r1, r2 - BNE %BT15 - - STR r3, [r0, #MEMC2_SuperPageZero] ; don't forget super page zero - -; now find out the memory size - - MOV r0, #PhysRam - MOV r6, #256*1024 -20 - ADD r1, r0, r6 - BL DistinctAddresses ; try next address line - BNE %FT30 ; if ghosts or not there then finish - MOV r6, r6, LSL #1 - CMP r6, #16*1024*1024 ; give up if we've got 16MBytes or more - BCC %BT20 -30 - MOV r1, r6 - LDR r2, ResetMemC_Value - BIC r2, r2, #&C - ORR r2, r2, #Page8K - MOV r0, #8*1024 ; fixed 8K page size - MOV pc, r7 - | - MOV r7, lr - MOV r0, #PhysRam - ADD r1, r0, #A13 - BL DistinctAddresses - BNE %10 - ADD r1, r0, #A21 - BL DistinctAddresses - MOVNE r0, #Page32K - MOVNE r1, #2048*1024 - BNE MemSizeDone - - MOV r0, #PhysRam - ADD r1, r0, #4*1024*1024 - BL DistinctAddresses - MOVNE r0, #Page32K - MOVNE r1, #4*1024*1024 - BNE MemSizeDone - - MOV r0, #PhysRam - ADD r1, r0, #8*1024*1024 - BL DistinctAddresses - MOVNE r0, #Page32K - MOVNE r1, #8*1024*1024 - BNE MemSizeDone - - MOV r0, #PhysRam - ADD r1, r0, #12*1024*1024 - BL DistinctAddresses - MOV r0, #Page32K - MOVNE r1, #12*1024*1024 - MOVEQ r1, #16*1024*1024 - B MemSizeDone - -10 ADD r1, r0, #A20 - BL DistinctAddresses - BNE %20 - MOV r0, #Page16K - MOV r1, #2048*1024 - B MemSizeDone - -20 ADD r1, r0, #A19 - BL DistinctAddresses - BEQ %30 - MOV r0, #Page8K - MOV r1, #512*1024 - B MemSizeDone - -30 ADD r1, r0, #A18 - BL DistinctAddresses - BEQ %40 - MOV r0, #Page4K - MOV r1, #256*1024 - B MemSizeDone - -40 ADD r1, r0, #A12 - BL DistinctAddresses - BEQ %50 - MOV r0, #Page4K - MOV r1, #512*1024 - B MemSizeDone - -50 MOV r0, #Page8K - MOV r1, #1024*1024 - -MemSizeDone - LDR r2, ResetMemC_Value - BIC r2, r2, #&C - ORR r2, r2, r0 - STR r2, [r2] ; set MEMC to right state - MOV pc, r7 - - ] - -; DistinctAddresses routine... -; r0,r1 are the addresses to check -; uses r2-5 -; writes interleaved patterns (to prevent dynamic storage...) -; checks writing every bit low and high... -; return Z-flag set if distinct - -DistinctAddresses ROUT - LDR r2, [r0] ; preserve - LDR r3, [r1] - LDR r4, Pattern - STR r4, [r0] ; mark first - MOV r5, r4, ROR #16 - STR r5, [r1] ; mark second - LDR r5, [r0] - CMP r5, r4 ; check first - BNE %10 ; exit with Z clear - LDR r5, [r1] ; check second - CMP r5, r4, ROR #16 ; clear Z if not same - BNE %10 -; now check inverse bit writes - STR r4, [r1] ; mark second - MOV r5, r4, ROR #16 - STR r5, [r0] ; mark first - LDR r5, [r1] - CMP r5, r4 ; check second - BNE %10 ; exit with Z clear - LDR r5, [r0] ; check first - CMP r5, r4, ROR #16 ; clear Z if not same -10 STR r3, [r1] ; restore - STR r2, [r0] - ORREQ lr, lr, #Z_Flag - BICNE lr, lr, #Z_Flag - MOVS pc, lr - -Pattern - & &AAFF5500 ; shiftable bit check pattern - -; init state with masked out page size - -ResetMemC_Value - & &E010C :OR: MEMCADR ; slugged ROMs + flyback refresh only + 32K page - -; Constants -; -A0 * 1 :SHL: 00 -A1 * 1 :SHL: 01 -A2 * 1 :SHL: 02 -A3 * 1 :SHL: 03 -A4 * 1 :SHL: 04 -A5 * 1 :SHL: 05 -A6 * 1 :SHL: 06 -A7 * 1 :SHL: 07 -A8 * 1 :SHL: 08 -A9 * 1 :SHL: 09 -A10 * 1 :SHL: 10 -A11 * 1 :SHL: 11 -A12 * 1 :SHL: 12 -A13 * 1 :SHL: 13 -A14 * 1 :SHL: 14 -A15 * 1 :SHL: 15 -A16 * 1 :SHL: 16 -A17 * 1 :SHL: 17 -A18 * 1 :SHL: 18 -A19 * 1 :SHL: 19 -A20 * 1 :SHL: 20 -A21 * 1 :SHL: 21 -A22 * 1 :SHL: 22 -A23 * 1 :SHL: 23 -A24 * 1 :SHL: 24 -A25 * 1 :SHL: 25 -A26 * 1 :SHL: 26 -A27 * 1 :SHL: 27 -A28 * 1 :SHL: 28 -A29 * 1 :SHL: 29 -A30 * 1 :SHL: 30 -A31 * 1 :SHL: 31 - -Page32K * &C ; in MEMC control reg patterns... -Page16K * &8 -Page8K * &4 -Page4K * &0 - - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; In r0-r6 trashable -; r9 = Current MEMC CR - -; Out r9 MEMC value with slowest ROM speed, correct pagesize -; r7 processor speed in kHz, bit 16 => can do STM to I/O (ie MEMC1a, MEMC2), bit 17 => MEMC2 - -ncpuloops * 1024 ; don't go longer than 4ms without refresh ! -nmulloops * 128 - -TimeCPU ROUT - [ {TRUE} -; fudge it for now - LDR r7, =6000 + (3 :SHL: 16) ; pretend 6MHz system, and MEMC2 - MOV pc, lr - | - BIC r9, r9, #3 :SHL: 8 - STR r9, [r9] ; turn off refresh for a bit - -; Time CPU/Memory speed - - LDR r1, =&7FFE ; 32K @ 2MHz = ~16ms limit - MOV r3, #IOC - - MOV r0, r1, LSR #8 - STRB r1, [r3, #Timer1LL] - STRB r0, [r3, #Timer1LH] - LDR r0, =ncpuloops - STRB r0, [r3, #Timer1GO] ; start the timer NOW - B %FT10 ; Looks superfluous, but is required - ; to get ncpuloops pipeline breaks - -10 SUBS r0, r0, #1 ; 1S - BNE %BT10 ; 1N + 2S - - STRB r0, [r3, #Timer1LR] ; latch count NOW - LDRB r2, [r3, #Timer1CL] - LDRB r0, [r3, #Timer1CH] - ADD r2, r2, r0, LSL #8 ; count after looping is ... - - SUB r2, r1, r2 ; decrements ! - MOV r2, r2, LSR #1 ; IOC clock decrements at 2MHz - -; Time CPU/MEMC Multiply time - - MOV r4, #-1 ; Gives worst case MUL - - MOV r0, r1, LSR #8 - STRB r1, [r3, #Timer1LL] - STRB r0, [r3, #Timer1LH] - LDR r0, =nmulloops - STRB r0, [r3, #Timer1GO] ; start the timer NOW - B %FT20 ; Looks superfluous, but is required - ; to get nmulloops pipeline breaks - -20 MUL r5, r4, r4 ; 1S + 16I - MUL r5, r4, r4 ; 1S + 16I - SUBS r0, r0, #1 ; 1S - BNE %BT20 ; 1N + 2S - - STRB r0, [r3, #Timer1LR] ; latch count NOW - LDRB r4, [r3, #Timer1CL] - LDRB r0, [r3, #Timer1CH] - ADD r4, r4, r0, LSL #8 ; count after looping is ... - - SUB r4, r1, r4 ; decrements ! - MOV r4, r4, LSR #1 ; IOC clock decrements at 2MHz - - ORR r9, r9, #1 :SHL: 8 ; set refresh on flyback - STR r9, [r9] ; restore MEMC state a.s.a.p. - -; In ROM - each cpu loop took 4R cycles @ 8/f*500ns/cycle - - LDR r0, =4*(8*500/1000)*ncpuloops*1000 - DivRem r7, r0, r2, r1 ; r2 preserved - MOV r0, #&80 ; At 8 MHz and below, run fast ROMs - LDR r1, =8050 ; Over 8 MHz, need medium ROMs - CMP r7, r1 - MOVHI r0, #&40 - LDR r1, =13000 ; Over 13 MHz, need slowest ROMs - CMP r7, r1 - MOVHI r0, #&00 - ORR r9, r9, r0 - STR r9, [r9] ; Set ROM speed appropriately - - ASSERT ncpuloops = 8*nmulloops ; for given ratio cutoff <------------ - - MOV r4, r4, LSL #10 ; *1024 to get resolution on divide - DivRem r0, r4, r2, r1 - LDR r1, =1100 ; Cutoff point; MEMC1 longer than this - CMP r0, r1 - ORRLO r7, r7, #1 :SHL: 16 ; Note MEMC1a prescence - - MOV pc, lr - -; Typical figures give (in ROM at 8MHz): - -; MEMC1 2048 CPU, 2432 MEMC -> MUL ratio 1216 -; MEMC1a 2048 864 432 - - ] - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - END diff --git a/s/MOSDict b/s/MOSDict deleted file mode 100644 index 6bcc4f15..00000000 --- a/s/MOSDict +++ /dev/null @@ -1,69 +0,0 @@ -; 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 ==> MOSDict - -TokenEscapeChar * 27 -Token0 * 0 - MACRO - TokenString $n,$s -Token$n * $n - = ?Token$n.String +1 -Token$n.String = $s - MEND - -MOSdictionary - TokenString 1,"""Syntax: *"",TokenEscapeChar,Token0,0" - TokenString 2,""" the "",0" - TokenString 3,"""director"",0" - TokenString 4,"""filing system"",0" - TokenString 5,"""current"",0" - TokenString 6,""" to a variable. Other types of value can be assigned with *"",0" - TokenString 7,"""file"",0" - TokenString 8,"""default "",0" - TokenString 9,"""tion"",0" - TokenString 10,"""*Configure "",0" - TokenString 11,"""name"",0" - TokenString 12,""" server"",0" - TokenString 13,"""number"",0" - TokenString 14,"TokenEscapeChar,Token1,"" <"",0" - TokenString 15,""" one or more "",TokenEscapeChar,Token7,""s that match"",TokenEscapeChar,Token2,""given wildcard"",0" - TokenString 16,""" and "",0" - TokenString 17,"""relocatable module"",0" - TokenString 18,"13,""C(onfirm)"",9,""Prompt for confirma"",TokenEscapeChar,Token9,"" of each "",0" - TokenString 19,"""sets"",TokenEscapeChar,Token2,0" - TokenString 20,"TokenEscapeChar,Token1,"" [<disc spec.>]"",0" - TokenString 21,"""}"",13,""V(erbose)"",9,""Print informa"",TokenEscapeChar,Token9,"" on each "",TokenEscapeChar,Token7,"" "",0" - TokenString 22, 0 - TokenString 23,"TokenEscapeChar,Token31,""Landscape [<XScale> [<YScale> [<Margin> [<Threshold>]]]]]"",0" - TokenString 24,"TokenEscapeChar,Token41,""used"",TokenEscapeChar,Token40,""print a hard copy of"",TokenEscapeChar,Token2,""screen on EPSON-"",0" - TokenString 25,"""."",13,""Op"",TokenEscapeChar,Token9,""s: (use ~"",TokenEscapeChar,Token40,""force off, eg. ~"",0" - TokenString 26,"""printe"",0" - TokenString 27,"TokenEscapeChar,Token14,TokenEscapeChar,Token7,TokenEscapeChar,Token11,"">"",0" - TokenString 28,""" select"",0" - TokenString 29,"""xpression"",0" - TokenString 30,"TokenEscapeChar,Token1,"" ["",0" - TokenString 31,"""sprite"",0" - TokenString 32,""" displays"",0" - TokenString 33,"""free space"",0" - TokenString 34,""" {off}"",0" - TokenString 35,"""library"",0" - TokenString 36,"""parameter"",0" - TokenString 37,"""object"",0" - TokenString 38,""" all "",0" - TokenString 39,"""disc"",0" - TokenString 40,""" to "",0" - TokenString 41,""" is "",0" - = 0,0,0,0 - END diff --git a/s/MemInfo b/s/MemInfo deleted file mode 100644 index 8ac3a23e..00000000 --- a/s/MemInfo +++ /dev/null @@ -1,1220 +0,0 @@ -; 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. -; -; > MemInfo - - LTORG - -;---------------------------------------------------------------------------------------- -; MemorySWI -; -; In: r0 = reason code and flags -; bits 0-7 = reason code -; bits 3-31 = reason specific flags -; Out: specific to reason codes -; -; Perform miscellaneous operations for memory management. -; -MemorySWI ROUT - Push lr ; Save real return address. - AND lr, r0, #&FF ; Get reason code. - CMP lr, #(%40-%30):SHR:2 ; If valid reason code then - ADDCC lr, lr, #(%30-%10):SHR:2 ; determine where to jump to in branch table, - ADDCC lr, pc, lr, LSL #2 - Push lr, CC ; save address so we can -10 - ADRCC lr, MemReturn ; set up default return address for handler routines - Pull pc, CC ; and jump into branch table. -20 - ADRL r0, ErrorBlock_HeapBadReason ; Otherwise, unknown reason code. - SETV - ; Drop through to... - -MemReturn - [ International - BLVS TranslateError - ] - Pull lr ; Get back real return address. - BVS SLVK_SetV - ExitSWIHandler - -30 - B MemoryConvert ; 0 - B %BT20 ; Reason codes 1-5 are reserved. - B %BT20 - B %BT20 - B %BT20 - B %BT20 - B MemoryPhysSize ; 6 - B MemoryReadPhys ; 7 - B MemoryAmounts ; 8 - B MemoryIOSpace ; 9 - B MemoryFreePoolLock ; 10 - B %BT20 ; Reason code 11 reserved (for PCImapping). - B RecommendPage ; 12 - B MapIOpermanent ; 13 - B AccessPhysAddr ; 14 - B ReleasePhysAddr ; 15 - B MemoryAreaInfo ; 16 -40 - - -;---------------------------------------------------------------------------------------- -; MemoryConvert -; -; In: r0 = flags -; bit meaning -; 0-7 0 (reason code) -; 8 page number provided when set -; 9 logical address provided when set -; 10 physical address provided when set -; 11 fill in page number when set -; 12 fill in logical address when set -; 13 fill in physical address when set -; 14-15 0,1=don't change cacheability -; 2=disable caching on these pages -; 3=enable caching on these pages -; 16-31 reserved (set to 0) -; r1 -> page block -; r2 = number of 3 word entries in page block -; -; Out: r1 -> updated page block -; -; Converts between representations of memory addresses. Can also set the -; cacheability of the specified pages. -; - -; Declare symbols used for decoding flags (given and wanted are used -; so that C can be cleared by rotates of the form a,b). We have to munge -; the flags a bit to make the rotates even. -; -ppn * 1:SHL:0 ; Bits for address formats. -logical * 1:SHL:1 -physical * 1:SHL:2 -all * ppn :OR: logical :OR: physical -given * 24 ; Rotate for given fields. -wanted * 20 ; Rotate for wanted fields. -ppn_bits * ((ppn :SHL: 4) :OR: ppn) -logical_bits * ((logical :SHL: 4) :OR: logical) -physical_bits * ((physical :SHL: 4) :OR: physical) -cacheable_bit * 1:SHL:15 -alter_cacheable * 1:SHL:16 -flush_tlb * 1:SHL:30 ; Internal flag -flush_cache * 1:SHL:31 ; Internal flag. -flush_all * flush_tlb :OR: flush_cache - -MemoryConvert ROUT - Entry "r0-r11" ; Need lots of registers!! - -; MRS lr, CPSR -; Push "lr" -; ORR lr, lr, #I32_bit+F32_bit -; MSR CPSR_c, lr - - BIC lr, r0, #all,given ; Need to munge r0 to get rotates to work (must be even). - AND r0, r0, #all,given - ORR r0, r0, lr, LSL #1 ; Move bits 11-30 to 12-31. - - TST r0, #all,given ; Check for invalid argument (no fields provided) - TEQNE r2, #0 ; (no entries in table). - ADREQL r0, ErrorBlock_BadParameters - BEQ %FT95 - - EOR lr, r0, r0, LSL #given-wanted ; If flag bits 8-10 and 12-14 contain common bits then - AND lr, lr, #all,wanted ; clear bits in 12-14 (ie. don't fill in fields already given). - EOR lr, lr, #all,wanted - BIC r0, r0, lr - - MOV r6, #0 - LDR r7, [r6, #MaxCamEntry] - LDR r6, [r6, #CamEntriesPointer] - LDR r8, =L2PT - - BIC r0, r0, #flush_all ; Bit set if any page is really made uncacheable (we must flush the cache). -10 - SUBS r2, r2, #1 - BCC %FT70 - - LDMIA r1!, {r3-r5} ; Get next three word entry (PN,LA,PA) and move on pointer. - - [ ChocolateAMB - BL handle_AMBHonesty ; may need to make page honest (as if not lazily mapped) - ] - - TST r0, #physical,wanted ; If PA not wanted - BEQ %FT20 ; then skip. - TST r0, #logical,given ; If LA not given (rotate clears C) then - BLEQ ppn_to_logical ; get it from PN (PA wanted (not given) & LA not given => PN given). - BLCC logical_to_physical ; Get PA from LA. - BCS %FT80 - TST r0, #logical,wanted - STRNE r4, [r1, #-8] ; Store back LA if wanted. - STR r5, [r1, #-4] ; Store back PA. -20 - TST r0, #alter_cacheable ; If altering cacheability - EORNE lr, r0, #ppn,given ; and PN not given - TSTNE lr, #ppn,given - TSTEQ r0, #ppn,wanted ; OR PN wanted then don't skip - BEQ %FT30 ; else skip. - TST r0, #physical_bits,given ; If PA not given and PA not wanted (rotate clears C) then - BLEQ logical_to_physical ; get it from LA (PN wanted/not given & PA not given => LA given). - BLCC physical_to_ppn ; Get PN from PA. - BCS %FT80 - TST r0, #ppn,wanted - STRNE r3, [r1, #-12] ; Store back PN if wanted. -30 - TST r0, #logical,wanted ; If LA wanted - EORNE lr, r0, #physical,wanted - TSTNE lr, #physical,wanted ; and PA not wanted then don't skip - BEQ %FT40 ; else skip. - TST r0, #alter_cacheable ; If not changing cacheability (already have PN) - TSTEQ r0, #ppn_bits,given ; and PN not given and PN not wanted (rotate clears C) then - BLEQ physical_to_ppn ; get it from PA (LA wanted (not given) & PN not given => PA given). - BLCC ppn_to_logical ; Get LA from PN. - BCS %FT80 - STR r4, [r1, #-8] ; Store back LA. -40 - TST r0, #alter_cacheable - BEQ %BT10 - - CMP r7, r3 ; Make sure page number is valid (might not have done any conversion). - BCC %FT80 - - ADD r3, r6, r3, LSL #3 ; Point to CAM entry for this page. - LDMIA r3, {r4,r5} ; Get logical address and PPL. - - AND lr, r5, #PageFlags_TempUncacheableBits - TST r0, #cacheable_bit - BNE %FT50 - - TEQ lr, #PageFlags_TempUncacheableBits ; Make uncacheable (increment count). - BEQ %BT10 ; If count has reached max then go no further (should not happen). - TEQ lr, #0 ; EQ => we have to change L2. - ADD r5, r5, #1:SHL:TempUncacheableShift - B %FT60 -50 - TEQ lr, #0 ; Make cacheable (decrement count). - BEQ %BT10 ; If count is already 0 then go no further (page already cacheable). - SUB r5, r5, #1:SHL:TempUncacheableShift - TST r5, #PageFlags_TempUncacheableBits ; EQ => we have to change L2. -60 - STR r5, [r3, #4] ; Write back new PPL. - BNE %BT10 ; Do next entry if we don't have to change L2. - - MOV r4, r4, LSR #12 - ADD r4, r8, r4, LSL #2 ; Address of L2 entry for logical address. - LDR r5, [r4] ; Get L2 entry (safe as we know address is valid). - ORR r0, r0, #flush_tlb - TST r0, #cacheable_bit - BICEQ r5, r5, #L2_C ; Disable/enable cacheability. - ORREQ r0, r0, #flush_cache ; If disable then we must flush cache later. - ORRNE r5, r5, #L2_C - STR r5, [r4] ; Write back new L2 entry. - - B %BT10 ; Do next entry. - -70 - ; *** KJB - this assumes that uncacheable pages still allow cache hits (true on all - ; ARMs so far). - ; *** Also, fix it up to do it page by page. - TST r0, #flush_tlb - EXIT EQ ; If not flush_tlb, can't have flush_cache - MOV r1, r0 - MOV r0, #0 - ARMop TLB_InvalidateAll,,,r0 - TST r1, #flush_cache ; If any page has been made uncacheable in L2 then flush! - EXIT EQ - MOV r0, #0 - ARMop Cache_CleanInvalidateAll,,,r0 -;75 -; Pull "lr" -; MSR CPSR_c, lr - EXIT - -80 - TST r0, #alter_cacheable ; If we haven't changed any cacheability stuff then - BEQ %FT90 ; just return error. - - AND lr, r0, #all,wanted ; Get wanted flags. - LDMIA sp, {r0,r1,r3} ; Get back original flags, pointer and count. - ORR r0, r0, lr, LSR #given-wanted ; Wanted fields are now also given as we have done the conversion. - BIC r0, r0, #all:SHL:11 ; Clear wanted flags, we only want to change cacheability. - EOR r0, r0, #cacheable_bit ; If we made them uncacheable then make them cacheable again & v.v. - SUB r2, r3, r2 - SUBS r2, r2, #1 ; Change back the entries we have changed up to (but excluding) the error entry. - BLNE MemoryConvert -90 - ADRL r0, ErrorBlock_BadAddress -95 - STR r0, [sp] - SETV - EXIT - - [ ChocolateAMB -; -; entry: r3,r4,r5 = provided PN,LA,PA triple for entry to make honest (at least one given) -; r0 bits flag which of PN,LA,PA are given -; exit: mapping made honest (as if not lazily mapped) if necessary -handle_AMBHonesty ROUT - Push "r0, r3-r5, lr" - TST r0, #logical,given - BEQ %FT10 - MOV r0, r4 - BL AMB_MakeHonestLA - B %FT90 -10 - TST r0, #ppn,given - BEQ %FT20 -15 - MOV r0, r3 - BL AMB_MakeHonestPN - B %FT90 -20 - TST r0, #physical,given - BEQ %FT90 - Push "r7, r9-r11" - MOV r14, #0 - LDR r7, [r14, #MaxCamEntry] - BL physical_to_ppn - Pull "r7, r9-r11" - BCC %BT15 -90 - Pull "r0, r3-r5, pc" - - ] ;ChocolateAMB - - -;---------------------------------------------------------------------------------------- -; ppn_to_logical -; -; In: r3 = page number -; r5 = physical address if given -; r6 = CamEntriesPointer -; r7 = MaxCamEntry -; -; Out: r9 corrupted -; CC => r4 = logical address -; CS => invalid page number -; -; Convert physical page number to logical address. -; -ppn_to_logical - CMP r7, r3 ; Validate page number. - [ No26bitCode - BCC meminfo_returncs ; Invalid so return C set. - | - ORRCCS pc, lr, #C_bit ; Invalid so return C set. - ] - - LDR r4, [r6, r3, LSL #3] ; If valid then lookup logical address. - TST r0, #physical,given ; If physical address was given then - LDRNE r9, =&FFF - ANDNE r9, r5, r9 ; mask off page offset - ORRNE r4, r4, r9 ; and combine with logical address. - [ No26bitCode - CLC - MOV pc, lr - | - BICS pc, lr, #C_bit ; Return C clear. - ] - - -;---------------------------------------------------------------------------------------- -; logical_to_physical -; -; In: r4 = logical address -; r8 = L2PT -; -; Out: r9 corrupted -; CC => r5 = physical address -; CS => invalid logical address, r5 corrupted -; -; Convert logical address to physical address. -; -logical_to_physical - MOV r9, r4, LSR #12 ; r9 = logical page number - ADD r9, r8, r9, LSL #2 ; r9 -> L2PT entry for logical address - MOV r5, r9, LSR #12 ; r5 = page offset to L2PT entry for logical address - LDR r5, [r8, r5, LSL #2] ; r5 = L2PT entry for L2PT entry for logical address - EOR r5, r5, #2_10 ; Check for valid page. - TST r5, #3 - [ No26bitCode - BNE meminfo_returncs - | - ORRNES pc, lr, #C_bit - ] - - LDR r5, [r9] ; r5 = L2PT entry for logical address - EOR r5, r5, #2_10 ; Check for valid page. - TST r5, #3 - [ No26bitCode - BNE meminfo_returncs - | - ORRNES pc, lr, #C_bit - ] - - LDR r9, =&FFF ; Valid so - BIC r5, r5, r9 ; mask off bits 0-11, - AND r9, r4, r9 ; get page offset from logical page - ORR r5, r5, r9 ; combine with physical page address. - [ No26bitCode - CLC - MOV pc, lr - | - BICS pc, lr, #C_bit - ] - -meminfo_returncs - SEC - MOV pc, lr - -;---------------------------------------------------------------------------------------- -; physical_to_ppn -; -; In: r5 = physical address -; r7 = MaxCamEntry -; -; Out: r9-r11 corrupted -; CC => r3 = page number -; CS => invalid physical address, r3 corrupted -; -; Convert physical address to physical page number. -; -physical_to_ppn ROUT - MOV r9, #PhysRamTable - MOV r3, #0 ; Start at page 0. -10 - CMP r7, r3 ; Stop if we run out of pages - [ No26bitCode - BCC meminfo_returncs - | - ORRCCS pc, lr, #C_bit ; (return with C set). - ] - - LDMIA r9!, {r10,r11} ; Get start address and size of next block. - SUB r10, r5, r10 ; Determine if given address is in this block. - CMP r10, r11 - ADDCS r3, r3, r11, LSR #12 ; Move on to next block. - BCS %BT10 - - ADD r3, r3, r10, LSR #12 - [ No26bitCode - CLC - MOV pc, lr - | - BICS pc, lr, #C_bit ; Return with C clear. - ] - - -;---------------------------------------------------------------------------------------- -; Symbols used in MemoryPhysSize and MemoryReadPhys -; - -; Shifts to determine number of bytes/words to allocate in table. -BitShift * 10 -ByteShift * BitShift + 3 -WordShift * ByteShift + 2 - -; Bit patterns for different types of memory. -NotPresent * &00000000 -DRAM_Pattern * &11111111 -VRAM_Pattern * &22222222 -ROM_Pattern * &33333333 -IO_Pattern * &44444444 -NotAvailable * &88888888 - - -;---------------------------------------------------------------------------------------- -; MemoryPhysSize -; -; In: r0 = 6 (reason code with flag bits 8-31 clear) -; -; Out: r1 = table size (in bytes) -; r2 = page size (in bytes) -; -; Returns information about the memory arrangement table. -; -MemoryPhysSize - [ HAL - Entry "r0,r3,sb,ip" - AddressHAL - MOV r0, #0 - CallHAL HAL_PhysInfo - MOV r1, r0 - MOV r2, #4*1024 - EXIT - | - MOV r1, #PhysSpaceSize :SHR: ByteShift - MOV r2, #4*1024 - MOV pc, lr - ] - - -;---------------------------------------------------------------------------------------- -; MemoryReadPhys -; -; In: r0 = 7 (reason code with flag bits 8-31 clear) -; r1 -> memory arrangement table to be filled in -; -; Out: r1 -> filled in memory arrangement table -; -; Returns the physical memory arrangement table in the given block. -; -MemoryReadPhys ROUT - - [ HAL - Entry "r0-r12" - AddressHAL - MOV r0, r1 - SUB sp, sp, #4 - MOV r1, sp - CallHAL HAL_PhysInfo ; fills in everything except DRAM - LDR r11, [sp], #4 - - ; r0 to r11 is DRAM or not present. - LDR r1, [sp, #4] ; Get table address back - ADD r1, r1, r0, LSR #ByteShift - MOV r2, r0 ; Current physical address. - MOV r3, #0 ; Next word to store in table. - MOV r4, #32 ; How much more we have to shift r3 before storing it. - MOV r5, #0 ; Current page number. - MOV r6, #PhysRamTable - LDR r7, [r3, #CamEntriesPointer] - ADD r7, r7, #4 ; Point to PPL entries. - LDR r8, [r3, #MaxCamEntry] -10 - LDMIA r6!, {r9,r10} ; Get physical address and size of next block. - - CMP r9, r0 ; If not DRAM then - CMPHS r11, r9 - ADDLO r5, r5, r10, LSR #12 ; adjust current page number - BLO %BT10 ; and try next block. - - ADD r10, r10, r9 ; Add amount of unused space between current and start of block. - SUB r10, r10, r2 ; size = size + (physaddr - current) -20 - SUBS r4, r4, #4 ; Reduce shift. - MOVCS r3, r3, LSR #4 ; If more space in current word then shift it. - STRCC r3, [r1], #4 ; Otherwise, store current word - MOVCC r3, #0 ; and start a new one. - MOVCC r4, #28 - - CMP r2, r9 ; If not reached start of block then page is not present. - ORRCC r3, r3, #(NotPresent :OR: NotAvailable) :SHL: 28 - BCC %FT30 - LDR lr, [r7, r5, LSL #3] ; Page is there so get PPL and determine if it's available or not. - TST lr, #PageFlags_Unavailable - ORREQ r3, r3, #DRAM_Pattern :SHL: 28 - ORRNE r3, r3, #(DRAM_Pattern :OR: NotAvailable) :SHL: 28 - ADD r5, r5, #1 ; Increment page count. -30 - ADD r2, r2, #&1000 ; Increase current address. - SUBS r10, r10, #&1000 ; Decrease size of block. - BGT %BT20 ; Stop if no more block left. - - CMP r8, r5 ; Stop if we run out of pages. - BCS %BT10 - - TEQ r3, #0 ; If not stored last word then - MOVNE r3, r3, LSR r4 ; put bits in correct position - ADDNE r2, r2, r4, LSL #BitShift ; adjust current address - RSBNE r4, r4, #32 ; rest of word is not present - LDRNE lr, =NotPresent :OR: NotAvailable - ORRNE r3, r3, lr, LSL r4 - STRNE r3, [r1], #4 ; and store word. - - ; End of last block of DRAM to r11 is not present. - MOV r6, r0 - ADD lr, r11, #1 - RSBS r2, r2, lr - MOVNE r0, r1 - LDRNE r1, =NotPresent :OR: NotAvailable - MOVNE r2, r2, LSR #ByteShift - BLNE memset - - ; If softloaded (ie ROM image is wholely within DRAM area returned - ; by HAL_PhysInfo), mark that as unavailable DRAM. - MOV r0, #0 - LDR r0, [r0, #ROMPhysAddr] - LDR r1, [sp, #4] - CMP r0, r6 - ADDHS lr, r0, #OSROM_ImageSize*1024 - SUBHS lr, lr, #1 - CMPHS r11, lr - ADDHS r0, r1, r0, LSR #ByteShift - LDRHS r1, =DRAM_Pattern :OR: NotAvailable - MOVHS r2, #(OSROM_ImageSize*1024) :SHR: ByteShift - BLHS memset - | - Entry "r1-r10" - ; &00000000 to OSROM_ImageSize*1024 is ROM. - MOV r2, #(OSROM_ImageSize*1024-&00000000) :SHR: WordShift - LDR r3, =ROM_Pattern :OR: NotAvailable - BL fill_words - - ; OSROM_ImageSize*1024 to &02000000 is allocated to ROM but is not present. - MOV r2, #(&02000000-OSROM_ImageSize*1024) :SHR: WordShift - LDR r3, =NotPresent :OR: NotAvailable - BL fill_words - - ; &02000000 to &02400000 is VRAM or not present. - MOV r4, #0 - LDR r4, [r4, #VRAMSize] ; Get amount of VRAM (in bytes). - TEQ r4, #0 - MOVNE r2, r4, LSR #WordShift ; If there is some then fill part of table. - LDRNE r3, =VRAM_Pattern :OR: NotAvailable - BLNE fill_words - - ; End of VRAM to &03000000 is not present. - RSB r4, r4, #&03000000-&02000000 - MOV r2, r4, LSR #WordShift - LDR r3, =NotPresent :OR: NotAvailable - BL fill_words - - ; &03000000 to &03800000 is I/O. - MOV r2, #(&03800000-&03000000) :SHR: WordShift - LDR r3, =IO_Pattern :OR: NotAvailable - BL fill_words - - ; &03800000 to &08000000 is not present. - MOV r2, #(&08000000-&03800000) :SHR: WordShift - LDR r3, =NotPresent :OR: NotAvailable - BL fill_words - - ; &08000000 to &10000000 is I/O (EASI space). - MOV r2, #(&10000000-&08000000) :SHR: WordShift - LDR r3, =IO_Pattern :OR: NotAvailable - BL fill_words - - ; &10000000 to &20000000 is DRAM or not present. - MOV r2, #&10000000 ; Current physical address. - MOV r3, #0 ; Next word to store in table. - MOV r4, #32 ; How much more we have to shift r3 before storing it. - MOV r5, #0 ; Current page number. - MOV r6, #PhysRamTable - LDR r7, [r3, #CamEntriesPointer] - ADD r7, r7, #4 ; Point to PPL entries. - LDR r8, [r3, #MaxCamEntry] -10 - LDMIA r6!, {r9,r10} ; Get physical address and size of next block. - - CMP r9, #&10000000 ; If not DRAM then - ADDCC r5, r5, r10, LSR #12 ; adjust current page number - BCC %BT10 ; and try next block. - - ADD r10, r10, r9 ; Add amount of unused space between current and start of block. - SUB r10, r10, r2 ; size = size + (physaddr - current) -20 - SUBS r4, r4, #4 ; Reduce shift. - MOVCS r3, r3, LSR #4 ; If more space in current word then shift it. - STRCC r3, [r1], #4 ; Otherwise, store current word - MOVCC r3, #0 ; and start a new one. - MOVCC r4, #28 - - CMP r2, r9 ; If not reached start of block then page is not present. - ORRCC r3, r3, #(NotPresent :OR: NotAvailable) :SHL: 28 - BCC %FT30 - LDR lr, [r7, r5, LSL #3] ; Page is there so get PPL and determine if it's available or not. - TST lr, #PageFlags_Unavailable - ORREQ r3, r3, #DRAM_Pattern :SHL: 28 - ORRNE r3, r3, #(DRAM_Pattern :OR: NotAvailable) :SHL: 28 - ADD r5, r5, #1 ; Increment page count. -30 - ADD r2, r2, #&1000 ; Increase current address. - SUBS r10, r10, #&1000 ; Decrease size of block. - BGT %BT20 ; Stop if no more block left. - - CMP r8, r5 ; Stop if we run out of pages. - BCS %BT10 - - TEQ r3, #0 ; If not stored last word then - MOVNE r3, r3, LSR r4 ; put bits in correct position - ADDNE r2, r2, r4, LSL #BitShift ; adjust current address - RSBNE r4, r4, #32 ; rest of word is not present - LDRNE lr, =NotPresent :OR: NotAvailable - ORRNE r3, r3, lr, LSL r4 - STRNE r3, [r1], #4 ; and store word. - - ; End of last block of DRAM to &20000000 is not present. - RSBS r2, r2, #&20000000 - MOVNE r2, r2, LSR #WordShift - LDRNE r3, =NotPresent :OR: NotAvailable - BLNE fill_words - ] - - EXIT - - -fill_words - STR r3, [r1], #4 - SUBS r2, r2, #1 - BNE fill_words - MOV pc, lr - - -;---------------------------------------------------------------------------------------- -; MemoryAmounts -; -; In: r0 = flags -; bit meaning -; 0-7 8 (reason code) -; 8-11 1=return amount of DRAM (excludes any soft ROM) -; 2=return amount of VRAM -; 3=return amount of ROM -; 4=return amount of I/O space -; 5=return amount of soft ROM (ROM loaded into hidden DRAM) -; 12-31 reserved (set to 0) -; -; Out: r1 = number of pages of the specified type of memory -; r2 = page size (in bytes) -; -; Return the amount of the specified type of memory. -; -MemoryAmounts ROUT - Entry "r3" - - [ HAL - ! 0, "Sort out MemoryAmounts" - ; - ;temp bodge for DRAM,VRAM - ; - BICS lr, r0, #&FF ; Get type of memory required (leave bits 12-31, non-zero => error). - BEQ %FT30 ; Don't understand 0 (so the spec says). - - TEQ lr, #5:SHL:8 ; Check for soft ROM - BNE %FT05 - Push "r0" - MOV r0, #8 - SWI XOS_ReadSysInfo ; are we softloaded? - MOVVS r1, #0 - Pull "r0" - AND r1, r1, r2 - ANDS r1, r1, #1:SHL:4 - MOVNE r1, #OSROM_ImageSize*1024 ; this much soft ROM - B %FT20 - -05 TEQ lr, #1:SHL:8 - MOVEQ r1, #0 - LDREQ r1, [r1, #RAMLIMIT] ; assume 0 VRAM - BEQ %FT20 -10 - TEQ lr, #2:SHL:8 - BNE %FT40 ; not implementing anything else in this bodge - MOV r1, #0 ; assume 0 VRAM -20 - MOV r1, r1, LSR #12 ; Return as number of pages. - MOV r2, #4*1024 ; Return page size. - EXIT -30 - ADRL r0, ErrorBlock_BadParameters - SETV -40 - EXIT - | - BICS lr, r0, #&FF ; Get type of memory required (leave bits 12-31, non-zero => error). - BEQ %FT30 ; Don't understand 0 (so the spec says). - - TEQ lr, #5:SHL:8 ; Check for soft ROM - BNE %FT10 - LDR r1, =L1PT - MOV r2, #ROM - ADD r1, r1, r2, LSR #(20-2) ; L1PT address for ROM - LDR r2, [r1] - MOV r2, r2, LSR #12 - TEQ r2, #PhysROM :SHR: 12 ; see if we have hard or soft ROM - MOVEQ r1, #0 ; no soft ROM - MOVNE r1, #OSROM_ImageSize*1024 ; this much soft ROM - B %FT20 - -10 - TEQ lr, #4:SHL:8 ; Check for IO space. - LDREQ r1, =136*1024*1024 ; Just return 136M (includes VIDC and EASI space). - BEQ %FT20 - - TEQ lr, #3:SHL:8 ; Check for ROM. - LDREQ r1, =OSROM_ImageSize*1024 - BEQ %FT20 - - TEQ lr, #2:SHL:8 ; Check for VRAM. - MOVEQ r1, #0 ; Return amount of VRAM. - LDREQ r1, [r1, #VRAMSize] - BEQ %FT20 - - TEQ lr, #1:SHL:8 ; Check for DRAM. - BNE %FT30 - MOV r1, #0 - LDR lr, [r1, #RAMLIMIT] - LDR r1, [r1, #VRAMSize] - SUB r1, lr, r1 ; Return amount of RAM - amount of VRAM. - -20 - MOV r1, r1, LSR #12 ; Return as number of pages. - MOV r2, #4*1024 ; Return page size. - EXIT - -30 - ADRL r0, ErrorBlock_BadParameters - SETV - EXIT - ] - - -;---------------------------------------------------------------------------------------- -; MemoryIOSpace -; -; In: r0 = 9 (reason code with flag bits 8-31 clear) -; r1 = controller ID -; bit meaning -; 0-7 controller sequence number -; 8-31 controller type: -; 0 = EASI card access speed control -; 1 = EASI space(s) -; 2 = VIDC1 -; 3 = VIDC20 -; 4 = S space (IOMD,podules,NICs,blah blah) -; 5 = Extension ROM(s) -; -; Out: r1 = controller base address or 0 if not present -; -; Return the location of the specified controller. -; - - [ HAL -MemoryIOSpace ROUT - Entry "r0,r2,r3,sb,ip" - AddressHAL - CallHAL HAL_ControllerAddress - CMP r0, #-1 - MOVNE r1, r0 - ADREQL r0, ErrorBlock_BadParameters - STREQ r0, [sp, #0] - SETV EQ - EXIT - | -MemoryIOSpace ROUT - Entry "r2" - - AND r2, r1, #&FF ; Get sequence number. - MOV r1, r1, LSR #8 ; Get controller type. - CMP r1, #6 ; Make sure it's in range. - ADRCSL r0, ErrorBlock_BadParameters - SETV CS - EXIT CS - - ADR lr, controller_types - LDR r1, [lr, r1, LSL #2] ; Get base address or offset to table. - TEQ r1, #0 ; If not present or - CMPNE r1, #1024 ; not offset to table then - EXIT GE ; return. - - ADD lr, lr, r1 ; Point to table indexed by sequence number. - LDR r1, [lr], #4 ; Get sequence number limit. - CMP r2, r1 ; Make sure it's in range. - BCS %FT20 - LDR r1, [lr, r2, LSL #2] ; Get base address. - EXIT - -controller_types - DCD IOMD_Base + IOMD_ECTCR ; Expansion card timing control. - DCD easi_space_table - controller_types - DCD 0 - DCD VIDC - DCD IOMD_Base - DCD 0 - -easi_space_table - DCD 8 ; Maximum of 8 expansion cards. - DCD PhysSpace + IOMD_EASI_Base0 - DCD PhysSpace + IOMD_EASI_Base1 - DCD PhysSpace + IOMD_EASI_Base2 - DCD PhysSpace + IOMD_EASI_Base3 - DCD PhysSpace + IOMD_EASI_Base4 - DCD PhysSpace + IOMD_EASI_Base5 - DCD PhysSpace + IOMD_EASI_Base6 - DCD PhysSpace + IOMD_EASI_Base7 - ] ; HAL - -;---------------------------------------------------------------------------------------- -; MemoryFreePoolLock -; -; -; In: r0 bits 0..7 = 10 (reason code 10) -; r0 bit 8 = 1 if call is by Wimp (reserved for Acorn use), 0 otherwise -; r0 bits 9..31 reserved (must be 0) -; r1 = 0 to resume any background actions that may manipulate FreePool mapping -; (currently, this is just VRAMRescue) -; = 1 to suspend any background actions that may manipulate FreePool mapping -; all other values reserved (undefined behaviour) -; -; Out: r1 = previous state (1=suspended, 0=not suspended) -; -; A suspend call from the Wimp will be taken to mean that the whole FreePool is locked, and -; memory cannot be moved (supports Wimp_ClaimFreeMemory) -; -; VRAM rescue doesn't happen in this Kernel, but we still support the call for the Wimp. -; -MemoryFreePoolLock ROUT - Push "r2,r3,lr" - MOV r3,#0 - LDRB lr,[r3,#VRAMRescue_control] - TEQ r1,#0 - BNE %FT10 -;flush TLB(s) for resume - needed for Wimp resume, precaution for other - no cache flush -;since Free Pool is uncached - ARM_flush_TLB r2 -10 - TST r0,#&100 ;is it Wimp? - MOVEQ r2,#VRRc_suspend - MOVNE r2,#VRRc_wimp_lock - TEQ r1,#0 - AND r1,lr,r2 ;previous state - BICEQ lr,lr,r2 - ORRNE lr,lr,r2 - STRB lr,[r3,#VRAMRescue_control] ;set/clear relevant bit - TEQ r1,#0 - MOVNE r1,#1 - Pull "r2,r3,pc" - -;---------------------------------------------------------------------------------------- -;PCImapping - reserved for Acorn use (PCI manager) -; -; See code on Ursula branch - - -;---------------------------------------------------------------------------------------- -;RecommendPage -; -; In: r0 bits 0..7 = 12 (reason code 12) -; r0 bits 8..31 = 0 (reserved flags) -; r1 = size of physically contiguous RAM region required (bytes) -; r2 = log2 of required alignment of base of region (eg. 12 = 4k, 20 = 1M) -; -; Out: r3 = page number of first page of recommended region that could be -; grown as specific pages by dynamic area handler (only guaranteed -; if grow is next page claiming operation) -; - or error if not possible (eg too big, pages unavailable) -; -RecommendPage ROUT - Push "r0-r2,r4-r10,lr" - CMP r2,#30 - BHI RP_failed ;refuse to look for alignments above 1G -; - ADD r1,r1,#&1000 - SUB r1,r1,#1 - MOV r1,r1,LSR #12 - MOVS r1,r1,LSL #12 ;size rounded up to whole no. of pages -; - CMP r2,#12 - MOVLO r2,#12 ;log2 alignment must be at least 12 (4k pages) - MOV r0,#1 - MOV r4,r0,LSL r2 ;required alignment-1 -; - MOV r0,#PhysRamTable - MOV r3,#0 ;page number, starts at 0 - LDR r5,=CamEntriesPointer - LDR r5,[r5] - ADD r5,r5,#4 ; [r5,<page no.>,LSL #3] addresses flags word in CAM - LDMIA r0!,{r7,r8} ;address,size of video chunk (skip this one) -; -RP_nextchunk - ADD r3,r3,r8,LSR #12 ;page no. of first page of next chunk - LDMIA r0!,{r7,r8} ;address,size of next physical chunk - CMP r8,#0 - BEQ RP_failed -; - ADD r6,r7,r4 - SUB r6,r6,#1 ;round up - MOV r6,r6,LSR r2 - MOV r6,r6,LSL r2 - SUB r6,r6,r7 ;adjustment to first address of acceptable alignment - CMP r6,r8 - BHS RP_nextchunk ;negligible chunk - ADD r7,r3,r6,LSR #12 ;first page number of acceptable alignment - SUB r9,r8,r6 ;remaining size of chunk -; -;find first available page -RP_nextpage - CMP r9,r1 - BLO RP_nextchunk - LDR r6,[r5,r7,LSL #3] ;page flags from CAM - ;must not be marked Unavailable or Required - TST r6,#PageFlags_Unavailable :OR: PageFlags_Required - BEQ RP_checkotherpages -RP_nextpagecontinue - CMP r9,r4 - BLS RP_nextchunk - ADD r7,r7,r4,LSR #12 ;next page of suitable alignment - SUB r9,r9,r4 - B RP_nextpage -; -RP_checkotherpages - ADD r10,r7,r1,LSR #12 - SUB r10,r10,#1 ;last page required -RP_checkotherpagesloop - LDR r6,[r5,r10,LSL #3] ;page flags from CAM - TST r6,#PageFlags_Unavailable :OR: PageFlags_Required - BNE RP_nextpagecontinue - SUB r10,r10,#1 - CMP r10,r7 - BHI RP_checkotherpagesloop -; -;success! -; - MOV r3,r7 - Pull "r0-r2,r4-r10,pc" - -RP_failed - MOV r3,#0 - ADR r0,RP_error - SETV - STR r0,[sp] - Pull "r0-r2,r4-r10,pc" - -RP_error - DCD 0 - DCB "No chunk available (OS_Memory 12)",0 - ALIGN - -;---------------------------------------------------------------------------------------- -;MapIOpermanent - map IO space (if not already mapped) and return logical address -; -; In: r0 bits 0..7 = 13 (reason code 13) -; r0 bit 8 = 1 to map bufferable space (0 is normal, non-bufferable) -; r0 bit 9 = 1 to map cacheable space (0 is normal, non-cacheable) -; r0 bits 10..12 = 0 (reserved for cache policy) -; r0 bits 13..15 = 0 (reserved flags) -; r0 bit 16 = 1 to doubly map -; r0 bit 17 = 1 if access privileges specified -; r0 bits 18..23 = 0 (reserved flags) -; r0 bits 24..27 = access privileges (if bit 17 set) -; r0 bits 28..31 = 0 (reserved flags) -; r1 = physical address of base of IO space required -; r2 = size of IO space required (bytes) -; -; Out: r3 = logical address of base of IO space -; - or error if not possible (no room) -; -MapIOpermanent ROUT - Push "r0-r2,r12,lr" - MOV lr, r0 - TST lr, #1:SHL:8 ;test bufferable bit - MOVNE r0, #L1_B - MOVEQ r0, #0 - TST lr, #1:SHL:9 ;test bufferable bit - ORRNE r0, r0, #L1_C - TST lr, #1:SHL:16 - ORRNE r0, r0, #MapInFlag_DoublyMapped - TST lr, #1:SHL:17 - ANDNE lr, lr, #2_1111:SHL:24 - ADRNEL r12, PPLTransL1 - LDRNE r12, [r12, lr, LSR #22] - ORRNE r0, r0, #MapInFlag_APSpecified - ORRNE r0, r0, r12 - BL RISCOS_MapInIO - MOV r3, r0 - CMP r3, #0 ;MOV,CMP rather than MOVS to be sure to clear V - Pull "r0-r2,r12,pc",NE - ADR r0, MIp_error - SETV - STR r0, [sp] - Pull "r0-r2,r12,pc" - -MIp_error - DCD 0 - DCB "No room for IO space (OS_Memory 13)",0 - ALIGN - -;---------------------------------------------------------------------------------------- -;AccessPhysAddr - claim temporary access to given physical address (in fact, -; controls access to the 1Mb aligned space containing the address) -; The access remains until the next AccessPhysAddr or until a -; ReleasePhysAddr (although interrupts or subroutines may temporarily -; make their own claims, but restore on Release before returning) -; -; In: r0 bits 0..7 = 14 (reason code 14) -; r0 bit 8 = 1 to map bufferable space, 0 for unbufferable -; r0 bits 9..31 = 0 (reserved flags) -; r1 = physical address -; -; Out: r2 = logical address corresponding to phys address r1 -; r3 = old state (for ReleasePhysAddr) -; -; Use of multiple accesses: it is fine to make several Access calls, and -; clean up with a single Release at the end. In this case, it is the old state -; (r3) of the *first* Access call that should be passed to Release in order to -; restore the state before any of your accesses. (The r3 values of the other -; access calls can be ignored.) -; -AccessPhysAddr ROUT - Push "r0,r1,r12,lr" - TST r0, #&100 ;test bufferable bit - MOVNE r0, #L1_B - MOVEQ r0, #0 - SUB sp, sp, #4 ; word for old state - MOV r2, sp ; pointer to word - BL RISCOS_AccessPhysicalAddress - MOV r2, r0 - Pull r3 ; old state - Pull "r0,r1,r12,pc" - -;---------------------------------------------------------------------------------------- -;ReleasePhysAddr - release temporary access that was claimed by AccessPhysAddr -; -; In: r0 bits 0..7 = 15 (reason code 15) -; r0 bits 8..31 = 0 (reserved flags) -; r1 = old state to restore -; -ReleasePhysAddr - Push "r0-r3,r12,lr" - MOV r0, r1 - BL RISCOS_ReleasePhysicalAddress - Pull "r0-r3,r12,pc" - -;---------------------------------------------------------------------------------------- -; -; In: r0 = flags -; bit meaning -; 0-7 16 (reason code) -; 8-15 1=cursor/system/sound -; 2=IRQ stack -; 3=SVC stack -; 4=ABT stack -; 5=UND stack -; 6=Soft CAM -; 7=Level 1 page tables -; 8=Level 2 page tables -; 9=HAL workspace -; 10=Kernel buffers -; 11=HAL uncacheable workspace -; 16-31 reserved (set to 0) -; -; Out: r1 = base of area -; r2 = address space allocated for area (whole number of pages) -; r3 = actual memory used by area (whole number of pages) -; all values 0 if not present, or incorporated into another area -; -; Return size of various low-level memory regions -MemoryAreaInfo ROUT - Entry "r0" - MOV r1, #0 - MOV r2, #0 - MOV r3, #0 - MOV lr, r0, LSR #8 - AND lr, lr, #&FF - CMP lr, #(MAI_TableEnd - MAI_TableStart)/4 - ADDLO pc, pc, lr, LSL #2 - B %FT70 -MAI_TableStart - B %FT70 - B MAI_CursSysSound - B MAI_IRQStk - B MAI_SVCStk - B MAI_ABTStk - B MAI_UNDStk - B MAI_SoftCAM - B MAI_L1PT - B MAI_L2PT - B MAI_HALWs - B MAI_Kbuffs - B MAI_HALWsNCNB -MAI_TableEnd - -70 - ADRL r0, ErrorBlock_BadParameters - SETV - STR r0, [sp, #Proc_RegOffset+0] - EXIT - -MAI_CursSysSound - LDR r1, =CursorChunkAddress - MOV r2, #32*1024 - MOV r3, r2 - EXIT - -MAI_IRQStk - [ IRQSTK < CursorChunkAddress :LOR: IRQSTK > CursorChunkAddress+32*1024 - LDR r1, =IRQStackAddress - MOV r2, #IRQSTK-IRQStackAddress - MOV r3, r2 - ] - EXIT - -MAI_SVCStk - LDR r1, =SVCStackAddress - MOV r2, #SVCSTK-SVCStackAddress - MOV r3, r2 - EXIT - -MAI_ABTStk - [ No26bitCode - LDR r1, =ABTStackAddress - MOV r2, #ABTSTK-ABTStackAddress - MOV r3, r2 - ] - EXIT - -MAI_UNDStk - LDR r1, =UNDSTK :AND: &FFF00000 - LDR r2, =UNDSTK :AND: &000FFFFF - MOV r3, r2 - EXIT - -MAI_SoftCAM - MOV r0, #ZeroPage - LDR r1, [r0, #CamEntriesPointer] - LDR r2, =CAMspace - LDR r3, [r0, #SoftCamMapSize] - EXIT - -MAI_L1PT - LDR r1, =L1PT - MOV r2, #16*1024 - MOV r3, r2 - EXIT - -MAI_L2PT - MOV r0, #ZeroPage - LDR r1, =L2PT - MOV r2, #4*1024*1024 - LDR r3, [r0, #L2PTUsed] - EXIT - -MAI_HALWs - [ HAL - MOV r0, #ZeroPage - LDR r1, =HALWorkspace - MOV r2, #HALWorkspaceSpace - LDR r3, [r0, #HAL_WsSize] - ] - EXIT - -MAI_HALWsNCNB - [ HAL - MOV r0, #ZeroPage - LDR r1, =HALWorkspaceNCNB - MOV r2, #32*1024 - LDR r3, [r0, #HAL_Descriptor] - LDR r3, [r3, #HALDesc_Flags] - ANDS r3, r3, #HALFlag_NCNBWorkspace - MOVNE r3, r2 - ] - EXIT - -MAI_Kbuffs - LDR r1, =KbuffsBaseAddress - MOV r2, #KbuffsMaxSize - LDR r3, =(KbuffsSize + &FFF) :AND: :NOT: &FFF - EXIT - - END diff --git a/s/Middle b/s/Middle deleted file mode 100644 index a4f660e4..00000000 --- a/s/Middle +++ /dev/null @@ -1,1957 +0,0 @@ -; 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 - -; Compatibility fudgery for OS_ReadLine and ReadLineV with 32-bit addresses - - [ No26bitCode -ReadLineSWI - Push "r4,lr" - MOV r4, #0 - SWI XOS_ReadLine32 - Pull "r4,lr" - ; Pass back NZCV bits - MRS r11, CPSR - BIC lr, lr, #N_bit+Z_bit+C_bit+V_bit - AND r11, r11, #N_bit+Z_bit+C_bit+V_bit - ORR lr, lr, r11 - B SLVK - -ReadLine32SWI - MOV r11, #OS_ReadLine - B VecSwiDespatch - | -ReadLine32SWI - TST r0, #ARM_CC_Mask-3 - BNE %FT90 - AND r11, r4, #ARM_CC_Mask - ORR r0, r0, r11 - Push "r4,lr" - AND r4, r4, #&FF - SWI XOS_ReadLine - Pull "r4,lr" - B SLVK_TestV - -90 Push "lr" - BL SetErrorBadAddress - Pull "lr" - B SLVK_SetV - ] - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; VecRdLine - Read line from input stream (OSWORD 0 equivalent) - -; In r0 -> buffer for characters - [ :LNOT:No26bitCode -; bit 31 set means don't reflect characters that don't go in the buffer -; bit 30 set means reflect with the character in R4 - ] -; r1 = max length of line (excluding carriage return) -; r2 = lowest character put into buffer -; r3 = highest character put into buffer - [ No26bitCode -; r4 = flags -; bit 31 set means don't reflect characters that don't go in the buffer -; bit 30 set means reflect with the character in R4 -; bits 7-0 = character to echo if r4 bit 30 is set - | -; r4 = character to echo if r1 bit 30 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 - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -VecRdLine ROUT - - Push "R4-R7" - - [ No26bitCode - MOV R7, R4 ; R7 = flags + echo byte - MOV R4, R0 ; R4 -> buffer - | - AND R7, R0, #&C0000000 ; extract flags - AND R4, R4, #&FF - ORR R7, R7, R4 ; got flags, potential echo byte in R7 - - BIC R4, R0, #ARM_CC_Mask-3 ; 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, #&80000000 ; no reflection - BNE %BT10 ; of non-entered chars - -80 TST R7, #&40000000 - 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 - - SWI XOS_EnterOS - 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 ; switches back to User mode for us - -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 - - [ :LNOT:No26bitCode - LDR R0, BranchThroughZeroInstruction ; load the B RESET1 instr. - STR R0, [R1, -R1] ; and store it at zero again - - 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 - ; ??? 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] - ] - MOV R0, R14 - BL DumpyTheRegisters - - MakeErrorBlock AddressException - - -; Can branch through zero in any mode -; We go through a trampoline which stores R1 and R14 (at R14 on entry) - -Branch0_NoTrampoline_DummyRegs - & &DEADDEAD, &DEADDEAD -RESET1 ROUT -Branch0_NoTrampoline - ADR R14, Branch0_NoTrampoline_DummyRegs -Branch0_FromTrampoline - - MOV R1, #0 - LDR R1, [R1, #ExceptionDump] - STMIA R1, {R0-R13} - LDR R0, [R14, #0] - STR R0, [R1, #1*4] - LDR R0, [R14, #4] - STR R0, [R1, #14*4] - [ XScaleJTAGDebug - MRS R0, CPSR - AND R0, R0, #&1F - TEQ R0, #&15 ; Debug mode? - BNE %FT20 - MOV R13, #0 - LDR R0, [R13, #ProcessorFlags] - ORR R0, R0, #CPUFlag_XScaleJTAGconnected - STR R0, [R13, #ProcessorFlags] - LDMIA R1, {R0, R1} - B DebugStub -20 - ] - [ 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] - ] - MOV R0, #0 - SWI XOS_EnterOS - - BL UNDEF1 - MakeErrorBlock BranchThrough0 - - [ :LNOT: No26bitCode -BranchThroughZeroInstruction - [ ProcessorVectors - LDR PC, .+ProcVec_Branch0 - | - B .+Branch0_Trampoline - ] - ] - - [ XScaleJTAGDebug - ; Magic from the Multi-ICE User Guide - ALIGN 32 -DebugStub ROUT - ARM_read_control R13 - AND R13, R13, #MMUC_I - ORR R14, R14, R13, LSR #12 - ARM_read_control R13 - ORR R13, R13, #MMUC_I - ARM_write_control R13 - ADR R13, DebugStubLine2 - MCR p15, 0, R13, C7, C5, 1 - MCR p15, 0, R13, C7, C5, 6 -10 MRC p14, 0, R15, C14, C0 - BVS %BT10 - MOV R13, #&00B00000 - MCR p14, 0, R13, C8, C0 -20 MRC p14, 0, R15, C14, C0 - BPL %BT20 - ARM_read_control R13 - TST R14, #1 - BICEQ R13, R13, #MMUC_I - ARM_write_control R13 - MRC p14, 0, R13, C9, C0 - MOV PC, R13 - ALIGN 32 -DebugStubLine2 - SPACE 32 - ] - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; 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,#10 ;R0 > 9, so illegal value - ADDLO PC, PC, R0,LSL #2 - B ReadSysInfo_InvalidReason - - B %FT00 - B %FT10 - B %FT20 - B %FT30 - B %FT40 - B %FT50 - B %FT60 - B %FT70 - B %FT80 - B %FT90 - -ReadSysInfo_InvalidReason - 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] - 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 - 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 - ] - -; ReadSysInfo(4) -; -; On entry: r0 = 4 (reason code) -; -; On exit: r0 = LS32bits of Ethernet Network Address (or 0) -; r1 = MS16bits 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 ; Excellent,a custom part - we'll use it - BNE ExitNoEthernetAddress - LDR r1, [ r0, #RawMachineID+4 ] ; Acorn's ID and part# - BIC r1, r1, #&FF000000 ; Remove the CRC - LDR r0, =&0050A4 ; Acorn's ID is &005 - TEQ r1, r0 ; Is this an Acorn part? - MOV r0, #0 - BNE %FT45 - LDR r0, [ r0, #RawMachineID ] - MOV r0, r0, LSR #8 ; Lose family byte - LDR r1, =&0000A4100000 - ADD r0, r1, r0 ; Add Acorn base Ethernet address to number from Dallas - [ 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 in Acorn's MAC address allocation - ExitSWIHandler -45 - MOV r1, r1, LSR #8 ; It's unique,but not an Acorn part - extract MAC address verbatim - Push "r2" - LDR r2, [ r0, #RawMachineID ] - MOV r2, r2, LSR #8 - LDRB r0, [r0, #RawMachineID+4] - ORR r0, r2, r0, LSL#24 - Pull "r2" - 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 - - ] - -; ReadSysInfo(5) -; -; On entry: r0 = 5 (reason code) -; -; On exit: r0 = LSW of Raw data from unique id chip -; r1 = MSW of Raw data from unique id chip - -50 - MOV r0, #0 - LDR r1, [r0, #RawMachineID+4] - LDR r0, [r0, #RawMachineID+0] - ExitSWIHandler - -; 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 - LDRLS r0,[r3,r0,LSL #2] - MOVHI r0,#0 - STR r0,[r2],#4 - B %BT62 -64 - CMP r2,#osri6_maxvalue - LDRLS r2,[r3,r2,LSL #2] - MOVHI r2,#0 - 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) - 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 - DCD JTABLE-SWIRelocation ;18 - relocated base of OS SWI despatch table - DCD DefaultIRQ1V+(Devices-DefaultIRQ1Vcode) ;19 - relocated base of IRQ device head nodes - DCD DefaultIRQ1V+(DevicesEnd-DefaultIRQ1Vcode) ;20 - relocated end of IRQ device head nodes - DCD IRQSTK ;21 - top of the IRQ stack - DCD SoundWorkSpace ;22 - workspace (8K) and buffers (2*4K) -osri6_maxvalue * (.-4-osri6_table) :SHR: 2 - - -; 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 - LDMIA r0, {r2, r3} - LDR r1, [r0,#2*4] - Pull "r0" - ExitSWIHandler - -; 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) -; 5 = HAL (returned for machines running a HAL) -; 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 = software power off -; 4 = OS in RAM, else executing in ROM -; 5..31 reserved (currently undefined) -; -80 - [ HAL - Push "r9,r14" - AddressHAL - SUB sp, sp, #8 - ADD a2, sp, #0 - ADD a3, sp, #4 - CallHAL HAL_PlatformInfo - Pull "a2,a3,r9,r14" - MOV r0, #5 - 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, &00000005, &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 - ] - -; OS_ReadSysInfo 9 - Read ROM info -; -; On entry: -; r0 = 9 (reason code 9) -; r1 = item number to return -; -; On exit: -; r0 = pointer to requested string (NULL terminated) or NULL if it wasn't found -; -; Currently defined item numbers are: -; -; 0 = OS name -; 1 = Part number -; 2 = Build date -; 3 = Dealer name -; 4 = User name -; 5 = User address - -90 - CMP R1, #0 - ADREQ R0, RSI9_OSname ; The OS name - BEQ %FT95 - CMP R1, #2 - ADREQ R0, RSI9_Builddate ; The build date (dynamically generated) - MOVNE R0, #0 ; Other ones are unimplemented -95 - ExitSWIHandler - - GET s.Time+Date -RSI9_OSname = "$SystemName $VString",0 -RSI9_Builddate = "$Builddate",0 - - ALIGN - LTORG - - END diff --git a/s/ModHand b/s/ModHand deleted file mode 100644 index eaa12084..00000000 --- a/s/ModHand +++ /dev/null @@ -1,3794 +0,0 @@ -; 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 => ModHand - the Relocatable Module Handler - -ExtraRMANeeded * 24*1024 ; Amount you get extra on top of what you configured - - -;mjs changes for Ursula (ChocolateOSMod) - reduce stress on SysHeap -; - GBLL ModHand_IntrinsicBI -ModHand_IntrinsicBI SETL {TRUE} :LAND: ChocolateOSMod ;base module incarnation 'node' is in module node - - GBLL ModHand_InitDieServices -ModHand_InitDieServices SETL {TRUE} :LAND: ModHand_IntrinsicBI - -; Test version, incorporating multiple incarnation attempt - -; The module handler needs to know the structure of the HPD, and nodes. -; See RMTidy in particular. - -;************************************************************** -; -; Module chain structure: ModuleList points at a (singly-linked) list of -; nodes with following fields: - - ^ 0 -Module_chain_Link # 4 ; the link to the next module info block -Module_code_pointer # 4 ; pointer to the module. -Module_Hardware # 4 ; hardware base for podules; 0 for soft loaders -Module_incarnation_list # 4 ; pointer to list of incarnation specifiers -Module_ROMModuleNode # 4 ; pointer to ROM module node if in ROM (main, podule, extn), else zero - -ModInfo * @ - -; The incarnation list is a list of sub-nodes, one for each incarnation. - - ^ 0 -Incarnation_Link # 4 ; link to next incarnation -Incarnation_Workspace # 4 ; 4 private bytes for this life -Incarnation_Postfix # 0 ; postfix string starts here - -; Incarnations are distinguished by their postfix, which is separated -; from the module name by a special character: - -Postfix_Separator * "%" - -;************************************************************** - -; Handler initialisation. -; registers preserved - -; ROM module descriptor format - - ^ 0 -ROMModule_Link # 4 ; pointer to next node -ROMModule_Name # 4 ; pointer to module name (either directly in ROM, or in an RMA block) -ROMModule_BaseAddress # 4 ; start of module, if directly accessible -ROMModule_Version # 4 ; BCD version number, decimal point between bits 15,16 eg "1.23" => &00012300 -ROMModule_PoduleNumber # 4 ; podule number (0..3 = normal podule, -1 = main ROM, -2..-n = extension ROM) -ROMModule_ChunkNumber # 4 ; chunk number if in podule or extension ROM, unused (?) if in main ROM -ROMModule_OlderVersion # 4 ; pointer to node holding the next older version of this module, 0 if none -ROMModule_NewerVersion # 4 ; pointer to node holding the next newer version of this module, 0 if none -ROMModule_CMOSAddrMask # 4 ; CMOS address of frugal bit (bits 0..15) and bit mask (16..23) - ; and 'initialised' flag in bit 24 (bits 25..31 = 0) -ROMModule_Initialised * ROMModule_CMOSAddrMask + 3 -ROMModule_Size # 4 ; size of module -ROMModule_NodeSize # 0 - -;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -UnplugCMOSTable ; in reverse order - = Unplug17CMOS - = Unplug16CMOS, Unplug15CMOS - = Unplug14CMOS, Unplug13CMOS - = Unplug12CMOS, Unplug11CMOS - = Unplug10CMOS, Unplug9CMOS - = Unplug8CMOS, Unplug7CMOS - = FrugalCMOS+1, FrugalCMOS+0 - = MosROMFrugalCMOS+3, MosROMFrugalCMOS+2 - = MosROMFrugalCMOS+1 -UnplugCMOSTableEnd ; used for backwards indexing - = MosROMFrugalCMOS+0 - = 0 - ALIGN - -;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -ModuleInit Entry "r0-r12" ; call here on system startup - - 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) - - ADRL r6, SysModules_Info+4 - LDR r1, [r6, #-4] - ADD r1, r6, r1 - LDR r14, [r1, #-4] - TEQ r14, #0 - MOVNE r0, #ModHandReason_AddArea - SWINE XOS_Module - -; now for each module in the main ROM, create a node for it - - ASSERT ROMModule_Link = 0 - - LDR r9, =ROMModuleChain ; pointer to 'previous' node - MOV r8, #0 ; initial head ptr is zero - STR r8, [r9] ; set up null list - MOV r3, #-1 ; podule -1 is main ROM - MOV r10, #0 ; chunk number 0 to start -10 - LDR r7, [r6, #-4] ; get size of this module - TEQ r7, #0 ; if zero - BEQ %FT20 ; then no more main rom modules - - LDR r4, [r6, #Module_Title] ; 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 - - 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! - - 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 %BT10 - -; now do podule ROMs - -20 - MOV r3, #0 ; start at podule 0 -21 - MOV r10, #0 ; for each podule start at chunk 0 - CMP r3, #-1 - MOVGT r12, #0 ; if real podule then start at CMOS bit number 0 for this podule - ; else carry on from where we're at -22 - MOV r0, r10 - SWI XPodule_EnumerateChunksWithInfo - BVS %FT40 ; bad podule or some such - CMP r0, #0 ; no more chunks? - BEQ %FT45 ; then step to next podule - CMP r2, #OSType_Module - MOVNE r10, r0 - BNE %BT22 - -; now claim a block to copy module title into - - MOV r7, r1 ; pass size in r7 - Push "r0, r3, r4" - MOV r3, #0 -23 - LDRB r14, [r4, r3] ; find length of title string - ADD r3, r3, #1 ; increment length (include zero at end) - TEQ r14, #0 - BNE %BT23 - - BL ClaimSysHeapNode - Pull "r0, r3, r14" ; restore chunk no., podule no., old ptr to title - BVS %FT50 ; if error then no more ROMs (doesn't matter that error ptr is naff) - - MOV r4, r2 ; save pointer to block -24 - LDRB r1, [r14], #1 ; now copy string into block - STRB r1, [r2], #1 - TEQ r1, #0 - BNE %BT24 - - MOV r14, #(1 :SHL: 16) ; bit mask ready to shift - CMP r3, #-1 - BLT %FT30 - -; doing podule ROM - - ASSERT ?PoduleFrugalCMOS = 8 ; ensure we're using the correct Hdr:CMOS - CMP r12, #7 ; if bit number <= 7 - CMPLS r3, #8 ; then if podule number <= 8 - ADDCC r11, r3, #PoduleFrugalCMOS ; then use one of the 8 PoduleFrugalCMOS bytes - MOVEQ r11, #NetworkFrugalCMOS ; elif podule number = 8 then use network card CMOS - MOVHI r11, #0 ; otherwise no CMOS - ORRLS r11, r11, r14, LSL r12 ; OR in bit mask - B %FT36 - B %FT35 - -; doing extension ROM -30 - CMP r12, #16 ; 2 bytes of CMOS for extension ROMs - MOVCC r1, #ExtnUnplug1CMOS ; form CMOS address in r1 - ADDCC r1, r1, r12, LSR #3 - ANDCC r11, r12, #7 ; get bit mask - ORRCC r11, r1, r14, LSL r11 ; and OR in -35 - MOVCS r11, #0 ; if out of range then no CMOS -36 - ADD r12, r12, #1 ; increment bit - BL AddROMModuleNode - BVS %FT50 - - MOV r10, r0 ; go onto next chunk - MOV r9, r2 ; this node is now previous one - B %BT22 - -40 - CMP r3, #0 ; are we doing extension ROMs - BMI %FT50 ; if so, then stop if we get an error -45 - TEQ r3, #0 ; if doing extension ROMs - SUBMI r3, r3, #1 ; then go backwards - BMI %BT21 - ADD r3, r3, #1 ; go onto next podule - CMP r3, #16 ; more podules than you could ever fit - MOVEQ r3, #-2 ; if got to end, try extension ROMs - MOVEQ r12, #0 ; start by using bit 0 of CMOS - B %BT21 - -; now go down ROM module chain, initialising things - -50 - LDR r12, =ROMModuleChain - LDR r12, [r12] -55 - TEQ r12, #0 ; if no more modules - BEQ %FT90 ; then skip - - LDR r3, [r12, #ROMModule_CMOSAddrMask] ; get CMOS for LOCATION version - ANDS r2, r3, #&FF - MOVNE r1, r2 - MOVNE r0, #ReadCMOS ; if there is a CMOS address - SWINE XOS_Byte ; then read it - TST r2, r3, LSR #16 ; test bit - BNE %FT80 ; [LOCATION unplugged, so don't initialise here] - - MOV r11, r12 ; start with current one - -; now find the newest version that isn't unplugged - -; first find the newest version - -60 - LDR r14, [r11, #ROMModule_NewerVersion] - TEQ r14, #0 ; if there is a newer version - MOVNE r11, r14 ; then link to it - BNE %BT60 ; and loop - -; now work backwards until we find a version that isn't unplugged - there must be one, since LOCATION version is not unplugged - -65 - TEQ r11, r12 ; back to LOCATION version? - BEQ %FT68 ; [yes, so use that version] - LDR r3, [r11, #ROMModule_CMOSAddrMask] ; get CMOS for CODE version - ANDS r2, r3, #&FF - MOVNE r1, r2 - MOVNE r0, #ReadCMOS ; if there is a CMOS address - SWINE XOS_Byte ; then read it - TST r2, r3, LSR #16 ; test bit - LDRNE r11, [r11, #ROMModule_OlderVersion] ; CODE is unplugged, so try next older version - BNE %BT65 - -68 - LDR r7, [r12, #ROMModule_PoduleNumber] ; get podule number (for LOCATION version) - CMP r7, #-1 ; is it an extension ROM - BGE %FT70 ; if not then initialise newer one - -; it's an extension ROM, so only initialise if it's the newest, and hasn't yet been initialised - - TEQ r11, r12 - LDREQB r10, [r11, #ROMModule_Initialised] ; only initialise if this is zero and r11=r12 - TEQEQ r10, #0 - BNE %FT80 ; don't initialise - -; not an extension ROM, so initialise the newest version (r11) of this module - -70 - [ DebugROMInit - SWI XOS_WriteS -;;; = "About to initialise module ",0 - = "init mod ",0 - LDR r0, [r11, #ROMModule_Name] - SWI XOS_Write0 - SWI XOS_NewLine - ] - BL InitialiseROMModule - [ DebugROMErrors ; print errors in ROM module init for debugging - BVC %FT80 - SWI XOS_WriteS -;;; = "Error in ROM module init: ",0 - = " error: ",0 - ALIGN - ADDVC r0, r0, #4 - SWIVC XOS_Write0 - SWIVC XOS_NewLine - ] -80 - LDR r12, [r12, #ROMModule_Link] - B %BT55 - -90 - [ DebugROMInit - SWI XOS_WriteS - = "mod init done",0 - SWI XOS_NewLine - ] - MOV r1, #RMASizeCMOS - MOV r0, #ReadCMOS - SWI XOS_Byte - MOV r0, #0 - LDR r0, [r0, #Page_Size] - MUL r3, r0, r2 - ADD r3, r3, #ExtraRMANeeded - MOV r0, #ModHandReason_Claim - SWI XOS_Module - MOV r0, #ModHandReason_Free - SWI XOS_Module - EXIT - -;****************************************************************************************************** -; -; InitialiseROMModule - Initialise a ROM module -; -; in: r11 -> ROM module node for CODE version -; r12 -> ROM module node for LOCATION version -; -; out: All registers preserved -; - -InitialiseROMModule Entry "r0-r12" - MOV r14, #1 - STRB r14, [r11, #ROMModule_Initialised] ; indicate it's been initialised - LDR r2, [r11, #ROMModule_ChunkNumber] - LDR r3, [r11, #ROMModule_PoduleNumber] - LDR r4, [r11, #ROMModule_Name] - LDR r6, [r11, #ROMModule_BaseAddress] - LDR r7, [r12, #ROMModule_PoduleNumber] - ADRL r1, crstring - MOV lr, pc ; ADRS lr, %FT10 - ADD lr, lr, #%FT20-%FT10 ; ADRS lr, %FT20 -10 - Push "r0-r7,r9,lr" - LDR r1, [r11, #ROMModule_Size] - MOV r5, r11 ; r5 -> ROM module node - B APMInitEntry -20 - STRVS r0, [sp] ; if error, preserve r0 - EXIT - -;****************************************************************************************************** -; -; AddROMModuleNode - Create a ROM module node and link it with the chain -; -; in: R3 = podule number -; R4 -> module name -; R5 -> module help string -; R6 -> module base if directly executable, otherwise zero -; R7 = module size -; R8 = 0 -; R9 -> previous node -; R10 = chunk number -; R11 = CMOS address (in bits 0..15) and bit mask (in bits 16..23) for unplugging (0 if none) -; -; out: R2 -> node created -; All other registers preserved, except if error (when R0 -> error) -; - -AddROMModuleNode Entry "r0,r1,r3-r12" - [ ChocolateSysHeap - ASSERT ChocolateMRBlocks = ChocolateBlockArrays + 12 - MOV r3,#ChocolateBlockArrays - LDR r3,[r3,#12] - BL ClaimChocolateBlock - MOVVS r3, #ROMModule_NodeSize - BLVS ClaimSysHeapNode - | - MOV r3, #ROMModule_NodeSize ; claim a rom module node - BL ClaimSysHeapNode ; r0,r1 corrupted, r2 -> block - ] - STRVS r0, [stack] - EXIT VS - - STR r8, [r2, #ROMModule_Link] ; set link for this node to 0 - STR r7, [r2, #ROMModule_Size] ; store size in node - STR r4, [r2, #ROMModule_Name] ; store pointer to title string - STR r6, [r2, #ROMModule_BaseAddress] ; store base address - MOV r0, r5 - BL GetVerNoFromHelpString ; read version number in BCD into r1 - STR r1, [r2, #ROMModule_Version] ; store version number - LDR r3, [stack, #2*4] ; reload podule number - STR r3, [r2, #ROMModule_PoduleNumber] ; store podule number - STR r10, [r2, #ROMModule_ChunkNumber] ; store chunk number - STR r11, [r2, #ROMModule_CMOSAddrMask] ; store CMOS address and mask - -; now check if module is a copy of one already on the list - - MOV r10, #0 ; next oldest node - MOV r11, #0 ; next newest node - CMP r3, #-1 ; if in main ROM, no need to look for duplicates - BEQ %FT40 - - MOV r1, r4 ; make r1 -> additional module's name - MOV r4, #0 ; zero terminator for Module_StrCmp - MOV r12, #0 ; search from start of chain - BL FindROMModule - TEQ r12, #0 ; did we find it? - BEQ %FT40 ; no, then module is unique - - TEQ r6, #0 ; set r6 to 1 if extra is directly executable, otherwise 0 - MOVNE r6, #1 - CMP r3, #-1 ; set r3 to 1 if extra is an extension ROM, otherwise 0 - MOVGE r3, #0 - MOVLT r3, #1 - LDR r1, [r2, #ROMModule_Version] ; reload version number of extra node - BL CompareVersions ; compare r2 version with r12 version - BCC %FT30 ; extra one is older than this one, so search down older chain - -; extra one is newer than this one, so search down newer chain - -20 - MOV r10, r12 ; old = this - LDR r12, [r12, #ROMModule_NewerVersion] ; this = newer(this) - MOVS r11, r12 ; new = this - BEQ %FT40 ; if no newer then that's it! - BL CompareVersions - BCS %BT20 - -; extra one is older than this one, so search down older chain - -30 - MOV r11, r12 ; new = this - LDR r12, [r12, #ROMModule_OlderVersion] ; this = older(this) - MOVS r10, r12 ; old = this - BEQ %FT40 - BL CompareVersions - BCC %BT30 - -40 - STR r10, [r2, #ROMModule_OlderVersion] ; older(extra)=old - STR r11, [r2, #ROMModule_NewerVersion] ; newer(extra)=new - TEQ r10, #0 ; if old <> 0 - STRNE r2, [r10, #ROMModule_NewerVersion] ; then newer(old)=extra - TEQ r11, #0 ; if new <> 0 - STRNE r2, [r11, #ROMModule_OlderVersion] ; then older(new)=extra - - STR r2, [r9] ; point previous node at this one - CLRV - EXIT - -CompareVersions Entry - LDR r14, [r12, #ROMModule_Version] ; r14 = version(this) - CMP r1, r14 - EXIT NE ; exit with this condition codes, unless equal - LDR r14, [r12, #ROMModule_BaseAddress] - TEQ r14, #0 ; set r14 to 1 if this one is directly executable, otherwise 0 - MOVNE r14, #1 - CMP r6, r14 - EXIT NE ; directly executables are "newer" - LDR r14, [r12, #ROMModule_PoduleNumber] - CMP r14, #-1 ; set r14 to 1 if ext. ROM, otherwise 0 - MOVGE r14, #0 - MOVLT r14, #1 - CMP r3, r14 ; extension ROMs are "newer" than anything else - EXIT ; if equal in all other respects, the later one is "newer" - -;****************************************************************************************************** -; -; FindROMModule - Find a named module in the ROM module list -; -; in: R1 -> name to match -; R4 = potential additional termintor for R1 string -; R12 -> node before 1st node to be checked (0 => search from start) -; -; out: R12 -> found node, or 0 if no match -; If match, then R1 -> terminator of R1 string, otherwise preserved -; All other registers preserved -; - -FindROMModule Entry - TEQ r12, #0 ; if zero passed in on entry - LDREQ r12, =ROMModuleChain ; then search from start of chain -10 - LDR r12, [r12, #ROMModule_Link] ; go to next module - TEQ r12, #0 ; any more modules? - EXIT EQ ; no, then exit - Push "r1, r3" - LDR r3, [r12, #ROMModule_Name] ; point to name of module on chain - BL Module_StrCmp ; compare names - STREQ r1, [sp] ; if match, then patch stacked r1 - Pull "r1, r3" - BNE %BT10 ; if different then try next one - EXIT - -; start of module handler SWI - - GBLA mhrc -mhrc SETA 0 - - MACRO -$l ModuleDispatchEntry $entry -$l B Module_$entry - ASSERT ModHandReason_$entry = mhrc -mhrc SETA mhrc + 1 - MEND - -ModuleHandler ROUT - - CMP r0, #(NaffSWI - (.+12))/4 ; Range check - ADDLO pc, pc, r0, LSL #2 ; dispatch - B NaffSWI - - ModuleDispatchEntry Run - ModuleDispatchEntry Load - ModuleDispatchEntry Enter - ModuleDispatchEntry ReInit - ModuleDispatchEntry Delete - ModuleDispatchEntry RMADesc - ModuleDispatchEntry Claim - ModuleDispatchEntry Free - ModuleDispatchEntry Tidy - ModuleDispatchEntry Clear - ModuleDispatchEntry AddArea - ModuleDispatchEntry CopyArea - ModuleDispatchEntry GetNames - ModuleDispatchEntry ExtendBlock - ModuleDispatchEntry NewIncarnation - ModuleDispatchEntry RenameIncarnation - ModuleDispatchEntry MakePreferred - ModuleDispatchEntry AddPoduleModule - ModuleDispatchEntry LookupName - ModuleDispatchEntry EnumerateROM_Modules - ModuleDispatchEntry EnumerateROM_ModulesWithInfo - ModuleDispatchEntry FindEndOfROM_ModuleChain - -NaffSWI ; Set V and return - ADR R0, ErrorBlock_BadModuleReason - [ International -BumDealInModule_Translate - Push "lr" - BL TranslateError - Pull "lr" - ] -BumDealInModule - B SLVK_SetV - - MakeErrorBlock BadModuleReason - -;************************************************************* - -Module_Run ROUT - WritePSRc SVC_mode, R12 ; interrupts on - Push "R9, lr" - BL Load_Module - BVS LoadFailed - ; BL EnvStringSkipName - done in load -EnterIt - ; R9 now ptr to node, R10 ptr to command string to set up. - ; Enters preferred incarnation. - - LDR R12, [R9, #Module_incarnation_list] - ADD R12, R12, #Incarnation_Workspace - - LDR R9, [R9, #Module_code_pointer] - LDR R11, [R9, #Module_Start] - TEQ R11, #0 - Pull "R9, lr", EQ - ExitSWIHandler EQ - - Push "R1-R3" - MOV R1, R10 - MOV R0, #FSControl_StartApplication - MOV R2, R9 - LDR R3, [R9, #Module_Title] ; prefix with module title - ADD R3, R3, R9 - - SWI XOS_FSControl - BVS CantGoIntoModule - - LDR stack, =SVCSTK - MOV R0, R10 - WritePSRc 0, R14 - MOV r0, r0 ; NOP because we've changed mode - - TST R11, #ARM_CC_Mask ; check for B startit, etc. - MOVNE R11, #0 - ADD PC, R9, R11 - -CantGoIntoModule - Pull "R1-R3" -LoadFailed - Pull "R9, lr" - B BumDealInModule - -;************************************************************* - -Module_Load ROUT - WritePSRc SVC_mode, R12 ; interrupts on - Push "R9, lr" - BL Load_Module - Pull "R9, lr" - B SLVK_TestV - -;************************************************************* - -Module_Enter ROUT - Push "R9, lr" ; ready for EnterIt - Push "R0-R4" - BL lookup_commoned - - STRVS R0, [stack] - Pull "R0-R4, R9, lr", VS - BVS BumDealInModule - - BLNE PreferIncarnation - Pull "R0-R4" - MOV R10, R2 ; envstring pointer - B EnterIt - -;************************************************************* - -Module_ReInit ROUT - Push "R0-R4, R9, lr" - - BL lookup_commoned - BVS %FT01 - - ADDEQ R3, R9, #Module_incarnation_list - LDREQ R12, [R9, #Module_incarnation_list] - - ; R12 -> incarnation node, R3 -> previous incarnation - - MOV R10, #1 ; fatal die - BL CallDie - BVS %FT03 - [ ModHand_InitDieServices - BL IssueServicePostFinal - ] - - SUB R10, R1, #1 - BL EnvStringSkipName - - BL CallInit - BLVS LoseModuleSpace_if_its_the_only_incarnation - STRVC R12, [R3, #Incarnation_Link] - [ ModHand_InitDieServices - BLVC IssueServicePostInit - ] -03 STRVS R0, [stack] - Pull "R0-R4, R9, lr" - B SLVK_TestV - - -01 LDR R11, [R0] - LDR R2, =ErrorNumber_RMNotFound - CMP R11, R2 - BEQ %FT02 -05 - SETV - B %BT03 - -02 MOV R0, #0 - BL AddModuleIfInROM - B %BT03 - -;************************************************************* - -Module_Delete ROUT - Push "R0-R4, R9, lr" - BL lookup_commoned - BVS %FT01 - - ADDEQ R3, R9, #Module_incarnation_list - LDREQ R12, [R9, #Module_incarnation_list] - - ; R12 -> incarnation node, R3 -> previous incarnation - - BL KillIncarnation -01 STRVS R0, [stack] - Pull "R0-R4, R9, lr" - B SLVK_TestV - -;************************************************************* - -Module_Free ROUT -Module_RMADesc - Push "R0, R1, lr" - - SUB R0, R0, #(ModHandReason_RMADesc-HeapReason_Desc) - ASSERT HeapReason_Desc-HeapReason_Free=ModHandReason_RMADesc-ModHandReason_Free - MOV R1, #RMAAddress - SWI XOS_Heap - STRVS R0, [stack] - Pull "R0, R1, lr" - B SLVK_TestV - -;************************************************************* - -Module_Claim ROUT - Push "R0, R1, lr" - BL RMAClaim_Chunk - STRVS R0, [stack] - Pull "R0, R1, lr" - B SLVK_TestV - -;************************************************************* -; Garbage collect the RMA. We know there's always one module, -; and some RMA space. - - [ RMTidyDoesNowt ; on Medusa we do nothing, because we would always fail - ; due to FSLock being Captain Scarlet -Module_Tidy - B SLVK - | -Module_Tidy ROUT - Push "R0-R6, R9, lr" - - WritePSRc SVC_mode, r0 - - MOV r0, #0 - LDR r0, [r0, #Curr_Active_Object] - MOV r1, #RMAAddress - LDR r2, [r1, #:INDEX:hpdend] - SUBS r0, r0, r1 - CMPHI r2, r0 - ADRHIL r0, ErrorBlock_CantKill - [ International - BLHI TranslateError - | - SETV HI - ] - - BLVC Genocide ; warn all of impending calamity - BVS ExitRMTidy - -; now for the great adventure. R2 is old contents of ModuleList -; First build a list of block addresses, together with address of pointer to -; block, in ascending order. - - LDR R2, =ScratchSpace - STR R9, [R2], #4 ; save original module list - MOV R3, R2 - -; in loop, R0 is block address, R1 is pointer to pointer to block -; R2 is ptr to list start -; R3 is list limit - -01 ADD R1, R9, #Module_code_pointer - LDR R0, [R1] - BL %FT10 ; insert pair - - LDR R1, [R9, #Module_incarnation_list] -02 ADD R1, R1, #Incarnation_Workspace - LDR R0, [R1] - CMP R0, #0 - BLNE %FT10 ; insert workspace block if there - LDR R1, [R1, #-Incarnation_Workspace] - CMP R1, #0 - BNE %BT02 - - LDR R9, [R9, #Module_chain_Link] ; next module - CMP R9, #0 - BNE %BT01 - -; Now iterate over claimed blocks, to discard non-heap pointers. - - MOV R5, R2 ; currblock ptr - -; if hpdfree <> hpdsize then -; doblock (hpdsize, hpdfree=Nil -> hpdbase, hpdfree) - - MOV R12, #RMAAddress - LDR R4, [R12, #:INDEX: hpdfree] - CMP R4, #Nil - ADDNE R4, R4, #:INDEX: hpdfree ; convert to heapstart offset - - CMP R4, #hpdsize - BEQ %FT04 - MOV R0, #hpdsize - CMP R4, #Nil - LDREQ R1, [R12, #:INDEX: hpdbase] - MOVNE R1, R4 - BL ScanAllocBlock - CMP R4, #Nil - BEQ BlocksScanned - -; while hpdfree <> Nil -; doblock (hpdfree+fresize, step(hpdfree)=Nil -> hpdbase, hpdfree) - -04 ADD R4, R4, R12 - LDR R1, [R4, #frelink] - LDR R0, [R4, #fresize] - SUB R4, R4, R12 - - ADD R0, R0, R4 - CMP R1, #Nil - ADDNE R4, R4, R1 - MOVNE R1, R4 - LDREQ R1, [R12, #:INDEX: hpdbase] - BL ScanAllocBlock - BNE %BT04 - -BlocksScanned - MOV R3, R5 ; new list end - -; copy blocks, relocate ptrs -; R2, R3 list limits -; R12 heap start - - ADD R0, R12, #hpdsize ; get addr for first block -StripBlocks - CMP R2, R3 - BEQ %FT09 ; nowt to copy - LDR R1, [R2], #8 - CMP R1, #0 - BEQ StripBlocks - LDR R4, [R1] ; block size - CMP R1, R0 - ADDEQ R0, R4, R0 - BEQ StripBlocks - -; R1 address of first block, R0 address to copy to - gopher it! -; R4 size - LDR R5, [R2, #-4] ; pointer to - ADD R0, R0, #4 - STR R0, [R5] ; relocate ptr - SUB R0, R0, #4 - -CopyBlock - LDR R5, [R1], #4 - STR R5, [R0], #4 - SUBS R4, R4, #4 - BGT CopyBlock - B StripBlocks - -09 -; Update Hpd - SUB R0, R0, R12 ; convert to offset - STR R0, [R12, #:INDEX: hpdbase] - - MOV R0, #Nil - STR R0, [R12, #:INDEX: hpdfree] ; no free list. - - ; for restarting, we need - ; R1 -> prevmod to R9 - ; R9 -> the whinger, R12 -> incarnation list, R2 stop point - ; R4 -> dead module list - ; R3 -> previnc - - MOV R9, #Module_List ; "module" that's linked at end - LDR R4, =ScratchSpace - LDR R4, [R4] ; dead list - MOV R2, #0 ; persuade it to step module - MOV R12, #0 ; immediately. - BL RestartModuleStructure - BVS ExitRMTidy - - MOV R0, #1 - MOV R1, #-16*1024*1024 - SWI XOS_ChangeDynamicArea - CLRV - -ExitRMTidy - STRVS R0, [stack] - Pull "R0-R6, R9, lr" - B SLVK_TestV - -;------------------------------------------------------------------------- -; RMTidy support routines - -; Insertion routine. (R0, 1) is pair to insert, R2 list start, R3 list end. -; Uses R10, 11, 4 - -10 MOV R11, R2 ; take curr posn ptr - - SUB R0, R0, #4 ; genuine internal heap pointer value -11 CMP R11, R3 ; list ended? - BEQ %FT13 - LDR R4, [R11], #8 - CMP R4, R0 ; or right posn? - BLO %BT11 - - SUB R11, R11, #8 ; where we will store new entry to - SUB R4, R3, #4 ; R4 is OS_Word to move from. -12 LDR R10, [R4], #-4 ; now copy between R11 and R3 up 8. - STR R10, [R4, #12] - CMP R4, R11 - BHS %BT12 - -13 ADD R3, R3, #8 ; update list end - STMIA R11, {R0, R1} ; new entry in - ADD R0, R0, #4 ; and back to link. - MOV PC, lr - -;------------------------------------------------------------------- -ScanAllocBlock ROUT - ; R0 block start - ; R1 block end - ; R12 heap start - ; R3 list end - ; R5 current list entry - - ; poke out list entries that aren't proper heap pointers - - Push "R0, R1, R7, R8, lr" - mrs ,lr, CPSR - MOV R8, #0 - ADD R0, R0, R12 ; convert to addressi - ADD R1, R1, R12 - -01 CMP R5, R3 - BHS %FT02 - LDR R7, [R5], #8 - - CMP R7, R0 ; while entry at R5 LO R0 pokeout - STRLO R8, [R5, #-8] - BLO %BT01 - - SUBHI R5, R5, #8 - - LDR R7, [R0] - ADD R0, R0, R7 ; next block - CMP R0, R1 ; step block until end - BLO %BT01 -02 - msr ,CPSR_f, lr - Pull "R0, R1, R7, R8, PC" - - LTORG - -;----------------------------------------------------------------------------- - -Genocide ROUT ; non-fatally kill de lot of em, stiff the module chain - ; corrupts R1-R5, R9, R10, R12 - ; returns R9 = original module chain - - Push "lr" - MOV R4, #0 ; chain so far - -FindChainEnd - MOV R1, #Module_List ; prevnode - LDR R9, [R1, #Module_chain_Link] ; currnode - CMP R9, #0 - BNE %FT01 - MOV R9, R4 - Pull "PC" - -01 LDR R11, [R9, #Module_chain_Link] ; lastnode? - CMP R11, #0 - MOVNE R1, R9 ; step chain - MOVNE R9, R11 - BNE %BT01 - - LDR R2, [R9, #Module_incarnation_list] ; keep chain head - ADD R3, R9, #Module_incarnation_list -02 LDR R12, [R3, #Incarnation_Link] ; currinc - CMP R12, #0 - BNE %FT03 - STR R12, [R1, #Module_chain_Link] ; remove from chain - STR R2, [R9, #Module_incarnation_list] ; replace incarnations - STR R4, [R9, #Module_chain_Link] ; make into dead head - MOV R4, R9 - B FindChainEnd - -03 MOV R10, #0 ; not fatal indicator - [ {FALSE} ; debug RMTidy - Push "r0" - LDR r0, [r9, #Module_code_pointer] - LDR r14, [r0, #Module_Title] - ADD r0, r0, r14 - SWI XOS_WriteS - = "RMTidy: killing '", 0 - ALIGN - SWI XOS_Write0 - SWI XOS_WriteS - = "'", 10, 13, 0 - ALIGN - Pull "r0" - ] - BL CallDie - BVC %BT02 - -; Copy the error in case overwritten - - MOV R5,R0 ; Error block - LDR R0,=GeneralMOSBuffer ; R0-> stashed error - LDR LR,[R5],#4 - STR LR,[R0],#4 ; Copy error number -05 LDRB LR,[R5],#1 - STRB LR,[R0],#1 - CMP LR,#' ' ; End of string? - BGE %BT05 ; No then more - LDR R0,=GeneralMOSBuffer ; R0-> stashed error - SETV - - MOV R5, R12 - MOV R12, R2 - MOV R2, R5 ; r12 now incarnation to start, R2 stop point - BL RestartModuleStructure - ; somebody winged, so try and restore consistency before error. - Pull "PC" - -;------------------------------------------------------------------------------ - -RestartModuleStructure ROUT - - ; R1 -> prevmod to R9 - ; R9 -> the whinger, R12 -> incarnation list, R2 stop point - ; R4 -> dead module list - ; R3 -> previnc - - Push "R0, R8, lr" - MRS R8, CPSR - -11 CMP R2, R12 - BNE %FT12 ; more incarnations to do - - CMP R4, #0 - BNE %FT13 - - MSR CPSR_f, R8 - Pull "R0, R8, PC" - -13 MOV R1, R9 -14 MOV R9, R4 - LDR R4, [R4, #Module_chain_Link] - MOV R2,#0 ; indicate reinit all incarnations - LDR R12, [R9, #Module_incarnation_list] - STR R2, [R9, #Module_incarnation_list] - ADD R3, R9, #Module_incarnation_list ; previnc ptr - - STR R2, [R9, #Module_chain_Link] ; relink next - STR R9, [R1, #Module_chain_Link] - B %BT11 ; start incarnations - -12 LDR R11, [R12, #Incarnation_Link] ; get next in case problems - ADRL R10, crstring ; no environment - BL CallInit ; frees node if error - BVC %FT15 - - STR R0, [stack] - ORR R8, R8, #V_bit - Push "R2" - MOV R2, R1 ; prevnode - BL LoseModuleSpace_if_its_the_only_incarnation - Pull "R2" - - CMP R9, #0 ; did we just discard that module? - BEQ %BT14 ; yup - next one - -15 LDRVC R0, [R3, #Incarnation_Link] - STRVC R0, [R12,#Incarnation_Link] - STRVC R12, [R3, #Incarnation_Link] - MOVVC R3, R12 - - MOV R12, R11 - B %BT11 ; next incarnation - ] ; endif <RMTidyDoesNowt> - -;**************************************************************************** - -Module_Clear Entry "r0-r3" - WritePSRc SVC_mode, r3 ; interrupts on - MOV r3, #0 ; position in chain - -; now find entry in chain to kill : one with successor = R3 - -MHC_GetEndOne - MOV r2, #Module_List ; prevnode for killing - LDR r0, [r2, #Module_chain_Link] - CMP r0, r3 - PullEnv EQ - ExitSWIHandler EQ -MHC_StepOn - LDR r1, [r0, #Module_chain_Link] - CMP r1, r3 - MOVNE r2, r0 - MOVNE r0, r1 - BNE MHC_StepOn - - LDR r11, [r0, #Module_ROMModuleNode] ; don't kill if it's a ROM module (note that this would also - CMP r11, #1 ; account for squeezed ROM modules, so the invincible bit in the - LDRCC r11, [r0, #Module_code_pointer] ; die entry is not strictly necessary any more, but never mind!) - LDRCC r11, [r11, #Module_Die] ; Check for invincible module - CMPCC r11, #&80000000 ; (die entry has top bit set) - MOVCS r3, r0 ; step if not about to delete - ; - don't assassinate ROM modules. - BLCC KillAndFree - BVC MHC_GetEndOne - - LDR r3, [r2, #Module_chain_Link] - STR r0, [stack] - LDR r0, [stack, #4*4] - ORR r0, r0, #V_bit - STR r0, [stack, #4*4] - B MHC_GetEndOne - -;************************************************************* -; AddArea: -; Entry; R1 -> module in memory to add, leaving it in place. -; Return: registers preserved, V set if problem -;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -Module_AddArea ROUT - Push "R9, lr" - WritePSRc SVC_mode, R10 ; interrupts on - ADRL R10, crstring ; null environment - BL ModuleIn_CheckForDuplicate ; altentry to Load_Module - Pull "R9, lr" - B SLVK_TestV - -;************************************************************* -; CopyArea -; R1 -> area of memory to add to the module list, -; copying into the RMA -; R2 = size of the area. - -Module_CopyArea ROUT - Push "R0-R5, R9, lr" - WritePSRc SVC_mode, lr - - ; R1 address, R2 size - BL CheckHeader - BVS AreaFail - - MOV R10, R1 - - LDR R1, [R10, #Module_Title] - ADD R1, R1, R10 - BL LookUp_Module ; check for duplicate - BLNE KillAndFree - STRVS R0, [stack] - Pull "R0-R5, R9, lr", VS - BVS SLVK_TestV - -; R10 points at area - LDR R3, [stack, #4*2] ; get size back - BL RMAClaim_Chunk - ADRVSL R0, ErrorBlock_MHNoRoom - [ International - BLVS TranslateError - ] - BVS AreaFail - - MOV R9, R2 ; new module pointer - -; copy R3 bytes from R10 to R2 -01 LDR R1, [R10], #4 - STR R1, [R2], #4 - SUBS R3, R3, #4 - BHI %BT01 ; was BPL, which is wrong! - - ADRL R10, crstring ; no environment string - MOV R11, #0 ; not podular - BL LinkAndInit - -AreaFail - STRVS R0, [stack] - Pull "R0-R5, R9, lr" - B SLVK_TestV - -;************************************************************* -; Enumerate modules -; Entry: R0 Reason code -; R1 module number -; R2 incarnation number -; Exit: R1, R2 updated to refer to next existing module -; R3 -> module code -; R4 private word contents -; R5 -> postfix string - -Module_GetNames ROUT - WritePSRc SVC_mode, R11 ; interrupts on - MOV R11, R1 - MOV R12, R2 - MOV R10, #Module_List -01 LDR R10, [R10, #Module_chain_Link] - CMP R10, #0 - BEQ %FT10 ; no more modules - SUBS R11, R11, #1 - BPL %BT01 - LDR R3, [R10, #Module_code_pointer] - ADD R10, R10, #Module_incarnation_list -02 LDR R10, [R10, #Incarnation_Link] - CMP R10, #0 - BEQ %FT11 ; no more incarnations - SUBS R12, R12, #1 - BPL %BT02 - LDR R4, [R10, #Incarnation_Workspace] - ADD R5, R10, #Incarnation_Postfix - LDR R10, [R10, #Incarnation_Link] -20 CMP R10, #0 - ADDNE R2, R2, #1 - MOVEQ R2, #0 - ADDEQ R1, R1, #1 - ExitSWIHandler - -10 ADR R0, ErrorBlock_NoMoreModules - [ International - B BumDealInModule_Translate - | - B BumDealInModule - ] - MakeErrorBlock NoMoreModules - -11 CMP r2, #0 - LDREQ r4, =&DEADDEAD - MOVEQ r10, #0 - BEQ %BT20 ; fudge for modules that go bang in init/die - ADR R0, ErrorBlock_NoMoreIncarnations - [ International - B BumDealInModule_Translate - | - B BumDealInModule - ] - MakeErrorBlock NoMoreIncarnations - LTORG - -;************************************************************* - -Module_ExtendBlock ROUT - Push "R0, r1, R3, lr" - - ADD R3, R3, #31 - BIC R3, R3, #31 - - MOV R0, #HeapReason_ExtendBlock - BL DoRMAHeapOpWithExtension - - STRVS R0, [stack] - Pull "R0, r1, R3, lr" - B SLVK_TestV - -;************************************************************* -; New Incarnation -; R1 -> module%newpostfix - -Module_NewIncarnation ROUT - Push "R0-R4, R9, lr" - WritePSRc SVC_mode, lr - BL LookUp_Module - BEQ CheckTheROM - CMP R12, #0 - BEQ Incarnation_needed - CMP R12, #-1 - BNE Incarnation_exists - MOV R9, R0 ; node pointer - MOV R0, R1 ; postfix - MOV R10, R1 - BL EnvStringSkipName ; envstring ptr in R10 - BL Add_Incarnation -01 STRVS R0, [stack] - Pull "R0-R4, R9, lr" - B SLVK_TestV - -CheckTheROM - MOV R0, #Postfix_Separator ; passed string must have postfix - LDR R1, [stack, #1*4] - BL AddModuleIfInROM - B %BT01 - -Incarnation_needed - Pull "R0-R4, R9, lr" - ADR R0, ErrorBlock_PostfixNeeded - [ International - B BumDealInModule_Translate - | - B BumDealInModule - ] - MakeErrorBlock PostfixNeeded - -Incarnation_exists - Pull "R0-R4, R9, lr" - ADR R0, ErrorBlock_IncarnationExists - [ International - B BumDealInModule_Translate - | - B BumDealInModule - ] - MakeErrorBlock IncarnationExists - -;************************************************************* -; Rename Incarnation -; R1 -> current module title -; R2 -> new postfix. - -Module_RenameIncarnation ROUT - Push "R0-R4, R9, lr" - BL lookup_commoned - BVS %FT01 - -; R12 -> incarnation node (0 for not specified) -; R3 -> previous incarnation - - MOV R11, R12 - MOV R0, R9 ; check incarnation - LDR R1, [stack, #4*2] ; not already there - Push R3 ; preserve pointer to - BL FindIncarnation - Pull R3 ; previous incarnation - BNE %FT03 ; already exists - MOV R12, R11 - - CMP R12, #0 - ADDEQ R3, R9, #Module_incarnation_list - LDREQ R12, [R9, #Module_incarnation_list] - MOV R11, R3 - - ADD R1, R12, #Incarnation_Postfix - BL %FT10 ; old postfix length -> R0 - MOV R10, R0 - LDR R1, [stack, #4*2] ; new postfix - BL %FT10 ; new length - > R0 - SUB R3, R0, R10 - - MOV R2, R12 ; incarnation node - MOV R0, #HeapReason_ExtendBlock - BL DoSysHeapOpWithExtension - BVS %FT01 - - STR R2, [R11, #Incarnation_Link] ; relink - ADD R2, R2, #Incarnation_Postfix - LDR R1, [stack, #4*2] -02 LDRB R0, [R1], #1 - CMP R0, #" " - MOVLE R0, #0 - STRB R0, [R2], #1 - BGT %BT02 -01 STRVS R0, [stack] - Pull "R0-R4, R9, lr" - B SLVK_TestV - -03 ADR R0, ErrorBlock_IncarnationExists - [ International - Push "LR" - BL TranslateError - Pull "LR" - | - SETV - ] - B %BT01 - -10 MOV R0, #0 -11 LDRB R3, [R1, R0] - CMP R3, #" " - ADDGT R0, R0, #1 - BGT %BT11 - MOV PC, lr - -;************************************************************* -; MakePreferred -; R1 -> name - -Module_MakePreferred ROUT - Push "R0-R4, R9, lr" - BL lookup_commoned - BVS %FT01 - BLNE PreferIncarnation ; only prefer it if found! -01 - STRVS R0, [sp, #0] - Pull "R0-R4, R9, lr" - B SLVK_TestV - -;************************************************************* -; AddPoduleModule -; -; in: R1 -> envstring -; R2 = chunk number -; R3 = podule number -; -; out: All registers preserved - -Module_AddPoduleModule Entry - WritePSRc SVC_mode, lr ; interrupts on - BL APMEntry - PullEnv - B SLVK_TestV - -APMEntry Entry "r0-r7,r9" - MOV r0, r2 - SWI XPodule_EnumerateChunksWithInfo ; out: r1=size, r2=type, r4->name, r5->help string, r6=module address if in ROM - BVS %FT99 - CMP r2, #OSType_Module - BNE %FT98 - - MOV r7, r3 - MOV r5, #0 ; indicate not a ROM module (although strictly speaking, it is!) -APMInitEntry - Push "r1" ; size - MOV r1, r4 - BL LookUp_Module ; check for duplicate - BLNE KillAndFree - Pull "r3" ; get size back - BVS %FT99 - - MOVS r1, r6 ; if module address non-zero, then it's a directly executable ext. ROM - BNE %FT10 ; and don't claim a block, or read the chunk - - BL RMAClaim_Chunk - BVS %FT99 - LDR r0, [stack, #4*2] - LDR r3, [stack, #4*3] - SWI XPodule_ReadChunk - MOV r1, r2 ; r1 = address of module -10 - LDR r2, [r1, #-4] ; r2 = size - BLVC CheckHeader - BVS %FT97 ; free space too (doesn't matter that it fails for extension ROM) - - MOV r9, r1 - LDR r10, [stack, #4] ; envptr - - MOVS r3, r7 ; if not a podule (r7 < 0) - MOVMI r11, #0 ; then use hardware address zero - BMI %FT20 - Push "r1" ; else compute hardware address from 'fake' podule number - SWI XPodule_HardwareAddresses ; get raw hardware address for podule r3 into r0 (r1 = combined) - Pull "r1" - BVS %FT97 - MOV r11, r0 ; move into r11 -20 - BL LinkAndInit - STRVC r5, [r9, #Module_ROMModuleNode] ; store zero or pointer to ROM module node (if no error in init) -99 - STRVS r0, [stack] - EXIT - -98 - ADR r0, ErrorBlock_ChunkNotRM - [ International - BL TranslateError - ] -96 - SETV - B %BT99 - MakeErrorBlock ChunkNotRM - -97 - MOV r2, r1 ; free claimed RMA space - MOV r1, #RMAAddress - Push "r0" - MOV r0, #HeapReason_Free - SWI XOS_Heap - Pull "r0" - B %BT96 - - LTORG - -;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; LookupName -; Take module name, return info on it suitable for use with Enumeration -; (e.g. to get all incarnations of it) -; In : R1 -> name -; Out: R1 module number \ of THIS module; first enumerate -; R2 incarnation number / call will give back this module -; R3 -> module code -; R4 private word contents -; R5 -> postfix string - -Module_LookupName ROUT - Push "R0-R4, R9, lr" - BL lookup_commoned - BVC %FT01 - STR R0, [stack] - Pull "R0-R4, R9, lr" - B SLVK_SetV - -01 MOV R1, #0 ; module number - MOV R0, #Module_List - -; R9 -> module chain node -; R12 -> incarnation node (0 for not specified, -1 for not found) - - LDREQ R12, [R9, #Module_incarnation_list] ; preferred inc. - -02 LDR R0, [R0] - CMP R0, R9 - ADDNE R1, R1, #1 - BNE %BT02 - ADD R0, R0, #Module_incarnation_list - MOV R2, #0 -03 LDR R0, [R0] - CMP R0, R12 - ADDNE R2, R2, #1 - BNE %BT03 - LDR R3, [R9, #Module_code_pointer] - LDR R4, [R12, #Incarnation_Workspace] - ADD R5, R12, #Incarnation_Postfix - LDR r0, [sp], #5*4 ; Load r0, skip r1-r4 - Pull "R9, lr" - ExitSWIHandler - -;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; EnumerateROM_Modules and EnumerateROM_ModulesWithInfo -; -; In : R1 = module number -; R2 = -1 => ROM -; = other => Podule R2 -; -; Out: R1 = incremented: next call will return next module -; R2 = preserved -; R3 -> name -; R4 = -1 => unplugged -; = 0 => inserted but not currently in the module chain -; = 1 => active -; = 2 => running -; R5 = chunk number of podule RM -; If R0 = ModHandReason_EnumerateROM_ModulesWithInfo then -; R6 = BCD version number of module (decimal point between top and bottom half-words) - -Module_EnumerateROM_Modules ROUT -Module_EnumerateROM_ModulesWithInfo ROUT - LDR r12, =ROMModuleChain - MOV r10, r1 ; module count -10 - LDR r12, [r12, #ROMModule_Link] ; follow link to next module - TEQ r12, #0 ; if no more modules - ADREQL r0, ErrorBlock_NoMoreModules - [ International - Push "lr",EQ - BLEQ TranslateError - Pull "lr",EQ - ] - BEQ SLVK_SetV ; then report error - LDR r11, [r12, #ROMModule_PoduleNumber] - CMP r2, #-1 ; if searching for podule -1, then this one must be ">=" - BEQ %FT30 - BGT %FT20 ; searching from normal podules onwards - -; searching from extension ROMs onwards - - CMP r11, r2 ; so if r11 > r2 then not there yet - BGT %BT10 - -; searching from normal podules onwards - -20 - CMP r11, #-1 ; if found one is extension ROM - BLT %FT30 ; then will be OK - CMP r11, r2 ; else is only OK if r11 >= r2 - BLT %BT10 -30 - CMP r11, r2 ; check for equality - MOVNE r1, #0 ; if not correct podule then this is the one to return - BNE %FT50 - - SUBS r10, r10, #1 ; decrement module count - BCS %BT10 ; not there yet, so go back -50 - Push "r0-r2, lr" - LDR r10, [r12, #ROMModule_CMOSAddrMask] ; get CMOS address and mask - ANDS r2, r10, #&FF ; extract address - MOVNE r1, r2 ; if there is a CMOS address - MOVNE r0, #ReadCMOS - SWINE XOS_Byte ; then read it - TST r2, r10, LSR #16 ; test bit - Pull "r0-r2" - Push "r8, r9" - MOVNE r4, #-1 ; indicate unplugged - BNE %FT90 - -; not unplugged, so check for module in module list - - MOV r4, #Module_List -60 - LDR r4, [r4, #Module_chain_Link] - TEQ r4, #0 ; module not active - BEQ %FT90 - LDR r11, [r4, #Module_ROMModuleNode] ; get active module's pointer to ROM module node - TEQ r11, r12 ; if it matches - BNE %BT60 - LDR r10, [r4, #Module_code_pointer] ; get pointer to code - MOV r11, #0 - LDR r11, [r11, #Curr_Active_Object] - LDR r4, [r10, #-4] ; node size of code - ADD r4, r4, r10 - CMP r11, r10 - CMPCS r4, r11 - MOVHI r4, #2 ; indicate running - MOVLS r4, #1 ; indicate just active -90 - LDR r2, [r12, #ROMModule_PoduleNumber] ; reload podule number - CMP r2, #-1 ; if not main ROM - LDRNE r5, [r12, #ROMModule_ChunkNumber] ; then load chunk number - LDR r3, [r12, #ROMModule_Name] ; load pointer to name - ADD r1, r1, #1 ; move module number onto next one - TEQ r0, #ModHandReason_EnumerateROM_ModulesWithInfo - LDREQ r6, [r12, #ROMModule_Version] - Pull "r8, r9, lr" ; restore registers - ExitSWIHandler ; and exit - -;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; FindEndOfROM_ModuleChain -; -; In : R1 = -1 => ROM -; = other => reserved -; -; Out: R1 = preserved -; R2 -> first word after ROM module chain - -Module_FindEndOfROM_ModuleChain ROUT - CMP r1, #-1 ; Only works for the system ROM at present - ADRNEL r0, ErrorBlock_BadParameters - [ International - Push "lr",NE - BLNE TranslateError - Pull "lr",NE - ] - BNE SLVK_SetV - - ADRL r2, SysModules_Info + 4 ; Step through until the end of the module chain -10 LDR r11, [r2, #-4] - TEQ r11, #0 - ADDNE r2, r2, r11 - BNE %BT10 - - ExitSWIHandler ; and exit - -;************************************************************* -; Support routines. -; -;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; Load_Module -; takes filename pointer in R1, and loads and initialises the given file. -; Returns R9 as a pointer to the node claimed -; and V/current error set if fails - -Load_Module ROUT - - Push "R0-R5, lr" - - MOV r0, #OSFile_ReadInfo - SWI XOS_File - BVS modfailxit ; return FileSwitch error - CMP r0, #object_file - BNE HeNotFile - - BIC R2, R2, #&FF ; low byte ignored by me. - CMP R2, #Module_LoadAddr - BNE NotAModule - -; it's a module, so try and claim. - MOV R10, R1 ; keep string pointer - MOV R3, R4 ; size of vector needed - BL RMAClaim_Chunk - BVS modfailxit - -02 MOV R9, R2 ; keep a copy of node ptr. - MOV R1, R10 - MOV R3, #0 ; load to R2 posn - MOV R0, #OSFile_Load - SWI XOS_File - BVS modfailxit ; return FileSwitch error - -50 MOV R11, #0 ; not loaded from hardware. - -; R9 address, R9!-4 size - MOV R1, R9 - LDR R2, [R9, #-4] - BL CheckHeader - BVS Duplicate_Immortal ; actually means naff header field - -; now we've got it, see if any other modules have the same name. - - LDR R1, [R9, #Module_Title] - ADD R1, R1, R9 - BL LookUp_Module - BEQ %FT01 ; no module at all - CMP R12, #0 - BNE nopostfixwanted ; postfix given: bad name - BL KillAndFree - BVS Duplicate_Immortal - -; now claim a link -; R9 module pointer, R10 environment - -01 BL EnvStringSkipName - BL LinkAndInit ; takes R2 prevnode from lookup - - STRVS R0, [stack] - Pull "R0-R5, pc" - -Duplicate_Immortal ; free space claimed for loading - STR R0, [stack] - MOV R2, R9 - MOV R0, #HeapReason_Free - MOV R1, #RMAAddress - SWI XOS_Heap - SETV - Pull "R0-R5, PC" - - MakeErrorBlock MHNoRoom - -nopostfixwanted - ADR R0, ErrorBlock_ModulePostfix - [ International - BL TranslateError - ] - B modfailxit - - MakeErrorBlock ModulePostfix - - MakeErrorBlock NotMod - -NotAModule - ADR R0, ErrorBlock_NotMod - [ International - BL TranslateError - ] -modfailxit - STR R0, [stack] - SETV - Pull "R0-R5, PC" - -HeNotFile - MOV r2, r0 - MOV r0, #OSFile_MakeError - SWI XOS_File - B modfailxit - -;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; ModuleIn_CheckForDuplicate -; Altentry to Load_Module for AddArea: module already in, initialise it. - -ModuleIn_CheckForDuplicate - Push "R0-R5, lr" - MOV R9, R1 ; move module ptr to handy place - B %BT50 - -;************************************************************* -; AddModuleIfInROM -; in: R1 -> name -; R0 = Postfix_Separator => called from AddNewIncarnation when module is not active -; find newest version in ROM, and initialise it in its own location (even if unplugged) -; then rename the base incarnation of it to specified postfix -; -; = 0 => called from ReInit when module is not active -; plug in all versions of module, and initialise newest one in its own location -; -; out: R5-R8 preserved -; Other registers may be corrupted -; - -AddModuleIfInROM Entry "r5-r8" - MOV r4, r0 - MOV r12, #0 ; search entire ROM set - MOV r7, r1 ; save pointer to beginning of name - BL FindROMModule - TEQ r12, #0 - BNE %FT10 - BL MakeNotFoundError ; in: r1 -> module name 'foo' - ; out: r0 -> "Module 'foo' not found" error, V=1 - EXIT - -10 - MOV r6, r1 ; save pointer to terminator of module name -15 - LDR r14, [r12, #ROMModule_OlderVersion] ; find oldest version - TEQ r14, #0 - MOVNE r12, r14 - BNE %BT15 - -20 - TEQ r4, #0 ; if doing AddIncarnation rather than ReInit - BNE %FT30 ; then don't plug module in - MOV r5, #&FF ; set up byte mask (and indicate found) - LDR r1, [r12, #ROMModule_CMOSAddrMask] - AND r3, r5, r1, LSR #16 ; get bit mask - ANDS r1, r1, r5 - BEQ %FT30 ; if no CMOS, then look for another module - MOV r0, #ReadCMOS - SWI XOS_Byte - EXIT VS - TST r2, r3 ; test if module unplugged - BEQ %FT30 ; if not, then don't write to CMOS (so RMReInit works when FSLock enabled) - BIC r2, r2, r3 ; otherwise clear bit - MOV r0, #WriteCMOS - SWI XOS_Byte - EXIT VS -30 - LDR r14, [r12, #ROMModule_NewerVersion] - TEQ r14, #0 - MOVNE r12, r14 - BNE %BT20 - - TEQ r4, #0 ; if AddIncarnation then check that name terminator is "%" - LDRNEB r14, [r6], #1 ; load next character (and skip it) - TEQNE r14, #Postfix_Separator - BEQ %FT40 - ADRL r0, ErrorBlock_PostfixNeeded - [ International - BL TranslateError - | - SETV - ] - EXIT - -40 - MOV r11, r12 - BL InitialiseROMModule ; in both cases initialise newest version - ; (in AddIncarnation case it may still be unplugged) - EXIT VS - - TEQ r4, #0 ; if ReInit then we've finished (V=0 from above) - EXIT EQ - - SUB r8, r6, r7 ; length of module name including '%' - ADD r8, r8, #4+1+3 ; allow for 'Base<0>' and round up to whole number of words - BIC r8, r8, #3 - SUB stack, stack, r8 - - MOV r0, stack -50 - LDRB r14, [r7], #1 ; copy name, including '%' - STRB r14, [r0], #1 - TEQ r7, r6 - BNE %BT50 - - ADR r1, base_postfix -60 - LDRB r14, [r1], #1 ; copy 'Base<0>' - STRB r14, [r0], #1 - TEQ r14, #0 - BNE %BT60 - - MOV r0, #ModHandReason_RenameIncarnation - MOV r1, stack ; pointer to '<module>%Base<0>' - MOV r2, r6 ; pointer to 'newinc' - SWI XOS_Module - ADD stack, stack, r8 ; junk name - EXIT - -;************************************************************* -; LinkAndInit : -; module pointer in R9 -; module list position in R2 : added at end if posn not found -; environment string pointer in R10 -; "hardware" in R11 -; returns module node pointer in R9 - -LinkAndInit Entry "r2, r3" - - - [ ChocolateSysHeap - ASSERT ChocolateMABlocks = ChocolateBlockArrays + 16 - MOV r3,#ChocolateBlockArrays - LDR r3,[r3,#16] - BL ClaimChocolateBlock - [ ModHand_IntrinsicBI - MOVVS r3, #ModInfo + Incarnation_Postfix + 8 ;enough for 'Base',0 - | - MOVVS r3, #ModInfo - ] - BLVS ClaimSysHeapNode - | - [ ModHand_IntrinsicBI - MOV r3, #ModInfo + Incarnation_Postfix + 8 ;enough for 'Base',0 - | - MOV r3, #ModInfo - ] - BL ClaimSysHeapNode - ] - EXIT VS - - STR r9, [r2, #Module_code_pointer] - STR r11, [r2, #Module_Hardware] - MOV r9, r2 ; keep node pointer - - MOV r0, #0 - STR r0, [r2, #Module_ROMModuleNode] ; assume not a ROM module - STR r0, [r2, #Module_incarnation_list] ; terminate list - ADR r0, base_postfix - [ ModHand_IntrinsicBI - BL Add_intrinsic_Incarnation ; add Base incarnation - | - BL Add_Incarnation ; add Base incarnation - ] - BVS %FT01 - - Pull "r2" - ADR r0, Module_List -05 - LDR r1, [r0] - CMP r1, #0 - CMPNE r0, r2 - MOVNE r0, r1 - BNE %BT05 - -; add module to chain end - give ROM modules priority. - - STR r1, [r9, #Module_chain_Link] - STR r9, [r0, #Module_chain_Link] - Pull "r3, pc" ; V clear from EQ compare with 0 - -01 - Push "r0" - LDR r2, [r9, #Module_code_pointer] - MOV r1, #RMAAddress - MOV r0, #HeapReason_Free - SWI XOS_Heap - MOV r2, r9 ; node pointer - [ ChocolateSysHeap - ASSERT ChocolateMABlocks = ChocolateBlockArrays + 16 - MOV r1,#ChocolateBlockArrays - LDR r1,[r1,#16] - BL FreeChocolateBlock - BLVS FreeSysHeapNode - | - BL FreeSysHeapNode - ] - SETV - Pull "r0, r2, r3, pc" - -base_postfix - = "Base",0 ; postfix used for 1st incarnation - ALIGN - - LTORG - -;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - [ ModHand_IntrinsicBI -Add_intrinsic_Incarnation ROUT - Push "R0-R3, lr" - ADD r2, r9, #ModInfo ;base incarnation at end of node - MOV r3, #Incarnation_Postfix + 5 - B Add_Incarnation_AltEntry - ] - -; Add_Incarnation -; takes postfix pointer in R0 (terminated by <= space -; module node pointer in R9 -; envstring in R10 -; Adds an incarnation node, reinitialises the module - -Add_Incarnation ROUT - Push "R0-R3, lr" - - MOV R3, #Incarnation_Postfix ; node size needed -01 LDRB R1, [R0], #1 - ADD R3, R3, #1 - CMP R1, #" " - BGT %BT01 - BL ClaimSysHeapNode - STRVS R0, [stack] - Pull "R0-R3, PC", VS - - LDR R0, [stack] -Add_Incarnation_AltEntry - ADD R3, R2, #Incarnation_Postfix -02 LDRB R1, [R0], #1 - CMP R1, #" " - STRGTB R1, [R3], #1 - BGT %BT02 - MOV R1, #0 - STRB R1, [R3] - - MOV R3, #0 - STR R3, [R2, #Incarnation_Workspace] ; zero private word - MOV R12, R2 - BL CallInit -; BLVS FreeIncarnation done by CallInit - STRVS R0, [stack] - - LDRVC R3, [R9, #Module_incarnation_list] - STRVC R3, [R2, #Incarnation_Link] - STRVC R2, [R9, #Module_incarnation_list] - [ ModHand_InitDieServices - BLVC IssueServicePostInit - ] - Pull "R0-R3, PC" - -;************************************************************* -CallInit ROUT -; take R9 -> module node -; R12 -> incarnation node -; R10 -> envstring -; set R11 appropriately -; initialise module with R10 given - - Push "R0-R6, R11, R12, lr" - - [ SqueezeMods - BL CheckForSqueezedModule ; unsqueeze module if squeezed - BVS %FT02 - ] - - ; if ChocolateService, we must not add to service chains yet, because we have - ; to make sure module's init entry is called before service entry (command - ; and SWI hashing don't have these worries - they won't be used yet) - - [ Oscli_HashedCommands - ; see if we need to update command hash nodes - BL AddCmdHashEntries - BVS %FT02 - ] - - ; see if we need to set up a module swi node - - BL CheckForSWIEntries - LDR R12, [stack, #4*(6+2)] - BNE %FT03 - - ; the module really does have a SWI chunk. Add node to hashtable. - ; KJB - after v3.71 add new modules at end, on grounds that first-registered - ; modules are probably more important. Exception is when a second module wants - ; an already used SWI chunk - it should get priority. - - MOV R4, R0 - MOV R11, R1 - [ ChocolateSysHeap - ASSERT ChocolateMSBlocks = ChocolateBlockArrays + 20 - MOV r3,#ChocolateBlockArrays - LDR r3,[r3,#20] - BL ClaimChocolateBlock - MOVVS R3, #ModSWINode_Size - BLVS ClaimSysHeapNode - | - MOV R3, #ModSWINode_Size - BL ClaimSysHeapNode - ] - BVS %FT02 - STR R9, [R2, #ModSWINode_MListNode] - STR R4, [R2, #ModSWINode_CallAddress] - STR R11, [R2, #ModSWINode_Number] - ModSWIHashval R3,R11 - LDR R4, [R3] - B %FT09 - ; top of loop: R4 = node under consideration, R3 = pointer to this node from previous -08 LDR R14, [R4, #ModSWINode_Number] - TEQ R11, R14 ; if numbers match, jump to end. This also sets - BEQ %FT10 ; the new node's link to this node - ADD R3, R4, #ModSWINode_Link ; update R3 to this node's link - LDR R4, [R3] ; and move R4 to next node -09 TEQ R4, #0 - BNE %BT08 ; if no next node, exit loop and tack on new one -10 STR R4, [R2, #ModSWINode_Link] - STR R2, [R3] - -03 ; now prepared to look at module - - LDR R3, [R9, #Module_code_pointer] - - [ StrongARM - LDR R4, [R9, #Module_ROMModuleNode] - CMP R4, #0 - BNE %FT04 ;It's a ROM module, so it already knows it's code - Push "r0-r2" - LDR r4, [r3, #-4] ;Read the length of the module from the RMA. - MOV r0, r3 ;start address - MOV r2, r4 ;length - MOV r1, #&B9 ;Service_ModulePreInit ; a chance to patch things - SWI XOS_ServiceCall - MOV r0, #1 ;It's a ranged synchronisation - MOV r1, r3 ;Start address - ADD r2, r3, r4 ;End address - SWI XOS_SynchroniseCodeAreas - Pull "r0-r2" -04 - ] - - LDR R4, [R3, #Module_Init] - CMP R4, #0 - [ ChocolateService - BEQ %FT05 - | - Pull "R0-R6, R11, R12, PC", EQ ; V clear - ] - - ADD R12, R12, #Incarnation_Workspace - MOV R11, #0 - ADD R5, R9, #Module_incarnation_list - Incarnation_Link -01 LDR R5, [R5, #Incarnation_Link] - CMP R5, #0 ; count incarnations - ADDNE R11, R11, #1 - BNE %BT01 - CMP R11, #0 - LDREQ R11, [R9, #Module_Hardware] - - ; R11, R12 now set: initialise - - MOV lr, PC ; pseudo BL - ADD PC, R3, R4 ; call 'im - - [ ChocolateService - ;now safe to try to add to service chains (init entry has been called) - ;note that AddToServiceChains may cause error (ran out of room) -05 - LDRVC R12, [stack, #4*(6+2)] - BLVC AddToServiceChains - ] - Pull "R0-R6, R11, R12, PC", VC - -02 LDR R12, [stack, #4*(6+2)] - BL FreeIncarnation - [ Oscli_HashedCommands - BL FreeCmdHashEntries - ] - [ ChocolateService - BL RemoveFromServiceChains - ] - BL FreeSWIEntry - STR R0, [stack] - Pull "R0-R6, R11, R12, PC" ; V set return - -;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; Enter with module pointer in R1 -; " size in R2 - -CheckHeader ROUT - Push "R3, lr" - LDR R3, [R1, #Module_HC_Table] - BL %FT11 - LDR R3, [R1, #Module_HelpStr] - BL %FT11 - LDR R3, [R1, #Module_Title] - BL %FT11 - LDR R3, [R1, #Module_Service] - BL %FT10 - LDR R3, [R1, #Module_Die] - BIC R3, R3, #&80000000 ; ignore top-bit (means cannot be RMCleared) - BL %FT10 - LDR R3, [R1, #Module_Init] - TST R3, #&80000000 - BLEQ %FT10 ; only check init offset if an unsqueezed module - [ No26bitCode -; Need to go through extra checks to see that (a) we have a module -; flags table, and (b) it says that we're 32-bit - LDR R3, [R1, #Module_SWIChunk] - TST R3, #&FF000000 - TSTEQ R3, #Module_SWIChunkSize-1 - BNE %FT88 - LDR R3, [R1, #Module_SWIEntry] - BL %FT20 - LDR R3, [R1, #Module_NameTable] - BL %FT21 - LDR R3, [R1, #Module_NameCode] - BL %FT20 - LDR R3, [R1, #Module_MsgFile] - BL %FT20 - LDR R3, [R1, #Module_FlagTable] - BL %FT20 - LDR R3, [R1, R3] - TST R3, #ModuleFlag_32bit - BEQ %FT88 - ] - CLRV - Pull "R3, PC" - -10 TST R3, #3 - BNE %FT99 -11 CMP R3, R2 - MOVLO PC, lr -99 - ADR R0, ErrorBlock_BadRMHeaderField - [ International - BL TranslateError - | - SETV - ] - Pull "R3, PC" - - [ No26bitCode -20 TST R3, #3 - BNE %FT88 -21 CMP R3, R2 - MOVLO PC, lr -88 - ADR R0, ErrorBlock_RMNot32bit - [ International - MOV R3, R4 - LDR R4, [R1, #Module_Title] - ADD R4, R1, R4 - BL TranslateError_UseR4 - MOV R4, R3 - | - SETV - ] - Pull "R3, PC" - MakeErrorBlock RMNot32bit - ] - - MakeErrorBlock BadRMHeaderField - -;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; Enter with module node pointer in R9 -; Sets R12 to module code pointer, R0 SWI code offset, R1 to SWI number -; Only returns SWIs extant if no incarnations of module yet - -CheckForSWIEntries ROUT - LDR R12, [R9, #Module_incarnation_list] - CMP R12, #0 - LDREQ R12, [R9, #Module_code_pointer] - LDREQ R1, [R12, #Module_SWIChunk] - BICEQ R1, R1, #Auto_Error_SWI_bit - TSTEQ R1, #Module_SWIChunkSize-1 - TSTEQ R1, #&FF000000 - MOVNE PC, lr ; naff chunk number. - CMP R1, #0 - LDRNE R0, [R12, #Module_SWIEntry] - CMPNE R0, #0 - BEQ %FT02 - TST R0, #3 - MOVNE PC, lr - Push "R5" - LDR R5, [R12, #-4] - CMP R5, R0 - Pull "R5" -01 BLS %FT02 - ADD R0, R0, R12 - CMP R0, R0 - MOV PC, lr ; EQ for success -02 CMP PC, #0 - MOV PC, lr ; NE return - -;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; Takes R9 pointer to module node; frees any module SWI hashtab node - -FreeSWIEntry ROUT - Push "R0-R5, R12, lr" - MRS R5, CPSR - BL CheckForSWIEntries - BEQ %FT05 - MSR CPSR_f, R5 - Pull "R0-R5, R12, PC" -05 - MOV R3, R1 ; copy of SWIno - ModSWIHashval R1 - LDR R2, [R1], #-ModSWINode_Link - - ; R1 predecessor, R2 currnode, R0 call address, R3 SWIno - ; look down chain until find right call address and number -01 CMP R2, #0 - BNE %FT03 - MSR CPSR_f, R5 - Pull "R0-R5, R12, PC" -03 - LDR R4, [R2, #ModSWINode_CallAddress] - CMP R4, R0 - LDREQ R4, [R2, #ModSWINode_Number] - CMPEQ R4, R3 - MOVNE R1, R2 - LDRNE R2, [R2, #ModSWINode_Link] - BNE %BT01 - LDR R4, [R2, #ModSWINode_Link] - STR R4, [R1,#ModSWINode_Link] - [ ChocolateSysHeap - ASSERT ChocolateMSBlocks = ChocolateBlockArrays + 20 - MOV r1,#ChocolateBlockArrays - LDR r1,[r1,#20] - BL FreeChocolateBlock - BLVS FreeSysHeapNode - | - BL FreeSysHeapNode - ] - MSR CPSR_f, R5 - Pull "R0-R5, R12, PC" - -;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - [ Oscli_HashedCommands - - ASSERT Oscli_MHashValMask = &ff - -;entry: R11 -> module cmd table, R4-> 8-word (256-bit) sieve workspace -;exit: sieve updated, R0-R3,R5,R6 trashed -; -CmdHashSieve ROUT - MOV R0,R4 - MOV R1,#0 - MOV R2,#8 -10 - STR R1,[R0],#4 ;zero the sieve - SUBS R2,R2,#1 - BNE %BT10 - ;commands with either of these flags set in information word won't be of interest: - MOV R5,#FS_Command_Flag :OR: Status_Keyword_Flag - MOV R0,R11 -18 - MOV R6,#0 ;hash value accumulator - LDRB R1,[R0],#1 - CMP R1,#0 - BEQ %FT40 ;no more entries -20 - UpperCase R1,R2 - ADD R6,R6,R1 ;hash value is sum of upper cased char values - LDRB R1,[R0],#1 - CMP R1,#0 - BNE %BT20 - ADD R0,R0,#3 - BIC R0,R0,#3 ;align to word boundary - LDR R1,[R0,#4] ;pick up information word - TST R1,R5 - BNE %FT30 ;not interested in this type of command - AND R6,R6,#&FF ;hash value (256-wide) - AND R2,R6,#&1F - MOV R3,#1 - MOV R3,R3,LSL R2 ;position in sieve word - MOV R6,R6,LSR #5 ;sieve word index - LDR R1,[R4,R6,LSL #2] - ORR R1,R1,R3 ;set bit in sieve for this hash value - STR R1,[R4,R6,LSL #2] -30 - ADD R0,R0,#4*4 ;next command entry (skip 4 word fields) - B %BT18 -40 - MOV PC,LR - -; -;entry: R0 -> Oscli_CmdHashLists array -; R6 = hash index -;exit: node created/expanded if necessary to allow room for at least 1 more hash ptr -; R1 -> node (may have moved, or been created) -; OR V set, error returned if no room -; -; - a cmd hash node is: -; 1 word = max count (according to current size of node) -; 1 word = current count (N) -; N words = the entries themselves (entries are module node pointers) -; -CheckRoomForNewCmdHash ROUT - Push "R0,R2,R3,LR" - LDR R1,[R0,R6,LSL #2] ;pick up list for this hash value - CMP R1,#0 - BNE %FT10 - Push "R0,R1" - MOV R3,#(5+2)*4 ;enough for 5 entries, plus the two count words - BL ClaimSysHeapNode - STRVS R0,[SP] - Pull "R0,R1" - BVS %FT90 - MOV R1,R2 - MOV R3,#5 - STR R3,[R1,#0] ;set the max count word - MOV R3,#0 - STR R3,[R1,#4] ;zero the current count word - STR R1,[R0,R6,LSL #2] ;store pointer to node in array - B %FT90 -10 - LDR R3,[R1,#0] ;pick up the max count - LDR R2,[R1,#4] ;pick up thr current count - ADD R2,R2,#1 ;need one more entry - CMP R2,R3 - BLS %FT90 - Push "R0" - MOV R0,#HeapReason_ExtendBlock - MOV R2,R1 - MOV R3,#4*4 ;enough for 4 more entries - BL DoSysHeapOpWithExtension - STRVS R0,[SP] - Pull "R0" - BVS %FT90 - MOV R1,R2 - STR R1,[R0,R6,LSL #2] ;store pointer to node in array (may have moved) - LDR R3,[R1,#0] - ADD R3,R3,#4 - STR R3,[R1,#0] ;bump max count by 4 -90 - STRVS R0,[SP] - Pull "R0,R2,R3,PC" -; -; -;entry: R9 -> module node -;exit: module entered into command hash table(s) where appropriate -; OR V set, error returned if no room -; -AddCmdHashEntries ROUT - Push "R0-R6,R11,R12,LR" - LDR R12,[R9,#Module_incarnation_list] - CMP R12,#0 - BNE %FT90 ;only do stuff if no incarnations yet - LDR R12,[R9,#Module_code_pointer] - LDR R11,=UtilityMod - CMP R12,R11 - BEQ %FT90 ;ignore UtilityModule (Oscli deals directly with it) - LDR R11,[R12,#Module_HC_Table] - CMP R11,#0 - BEQ %FT90 ;no commands - ADD R11,R12,R11 ;R11 -> command table - SUB SP,SP,#8*4 ;256-bit workspace for 256-wide hashing sieve - MOV R4,SP - BL CmdHashSieve - ;now our sieve has a bit set for each hash value that this module occupies for commands - MOV R0,#0 - LDR R0,[R0,#Oscli_CmdHashLists] - MOV R6,#0 -42 - AND R2,R6,#&1F - MOV R3,#1 - MOV R3,R3,LSL R2 ;position in sieve word - MOV R5,R6,LSR #5 ;sieve word index - LDR R1,[R4,R5,LSL #2] - TST R1,R3 - BEQ %FT50 ;module does not occupy this hash value - BL CheckRoomForNewCmdHash ;returns R1 -> cmd hash node - BVS %FT88 - LDR R2,[R1,#4] ;current no. of entries on list - ADD R2,R2,#1 - STR R2,[R1,#4] - ADD R1,R1,#4 - STR R9,[R1,R2,LSL #2] ;store ptr to module node at end of list -50 - ADD R6,R6,#1 ;next hash value - CMP R6,#256 - BLO %BT42 -88 - ADD SP,SP,#8*4 ;drop sieve workspace -90 - STRVS R0,[SP] - Pull "R0-R6,R11,R12,PC" -; -; -;entry: R9 -> module node -;exit: module removed from cmd hash table(s) as necessary -; -FreeCmdHashEntries ROUT - Push "R0-R7,R11,R12,LR" - MRS R7,CPSR - LDR R12,[R9,#Module_incarnation_list] - CMP R12,#0 - BNE %FT90 ;only do stuff if no incarnations - LDR R12,[R9,#Module_code_pointer] - LDR R11,=UtilityMod - CMP R12,R11 - BEQ %FT90 ;ignore UtilityModule (Oscli deals directly with it) - LDR R11,[R12,#Module_HC_Table] - CMP R11,#0 - BEQ %FT90 ;no commands - ADD R11,R12,R11 ;R11 -> command table - SUB SP,SP,#8*4 ;256-bit workspace for 256-wide hashing sieve - MOV R4,SP - BL CmdHashSieve - ;now our sieve has a bit set for each hash value that this module occupies for commands - MOV R0,#0 - LDR R0,[R0,#Oscli_CmdHashLists] - MOV R6,#0 -42 - AND R2,R6,#&1F - MOV R3,#1 - MOV R3,R3,LSL R2 ;position in sieve word - MOV R5,R6,LSR #5 ;sieve word index - LDR R1,[R4,R5,LSL #2] - TST R1,R3 - BEQ %FT50 ;module does not occupy this hash value - LDR R1,[R0,R6,LSL #2] ;pick up list for this hash value - LDR R2,[R1,#4] ;current no. of entries on list - SUB R2,R2,#1 - STR R2,[R1,#4] - ADD R1,R1,#8 ;scrunch list to remove module (R9) - MOV R3,R1 - CMP R2,#0 - BEQ %FT50 - ADD R2,R2,#1 -40 - LDR R5,[R1],#4 - CMP R5,R9 - STRNE R5,[R3],#4 - SUBS R2,R2,#1 - BNE %BT40 -50 - ADD R6,R6,#1 ;next hash value - CMP R6,#256 - BLO %BT42 - ADD SP,SP,#8*4 ;drop sieve workspace -90 - MSR CPSR_f,R7 - Pull "R0-R7,R11,R12,PC" ;MUST preserve flags -; - ] ;Oscli_HashedCommands - -;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - [ ChocolateService - - LTORG - -; must maintain service call chains, all attached to the 3 moorings in -; kernel workspace: -; -; - Serv_SysChains holds a fixed array of chain anchors for the 'system' -; service calls, in the range 1..ServMinUsrNumber -; - Serv_UsrChains holds an array of hashed list headers, each header -; holds an array of chains (open ended service number handling for -; service numbers >= ServMinUsrNumber) -; - Serv_AwkwardChain is a simple anchor for a single chain of non-compliant -; modules (either old format, or new format without table) that do not -; say what service calls they are interested in -; -; The order of modules on the chains is just a convenient as-seen order, so -; there will be subtle changes in the order of modules receiving service calls -; compared to their order in the active module list. This only affects cases -; where a service call may be claimed. Essentially, the new kernel does not -; guarantee who gets a chance to claim first, but this was never defined -; anyway. - -; -;a service call chain is a block looking like this: -; word 0 = current capacity (max entries*entry_size before block must grow) -; word 1 = current size (current number of entries*entry_size) -; - followed by an array of the current entries in the chain (cache friendly stuff) -; - each entry is 3 words and looks like this: -; word 0 = address of client service handler code -; word 1 = workspace value for client service handler code -; word 2 = R1 value for client (will be index for branch table), or 0 meaning pass service number -; - ^ 0 -ServChain_Capacity # 4 -ServChain_Size # 4 -ServChain_Entries # 0 -ServChain_HdrSIZEOF # 0 -; - ^ 0 -ServEntry_Code # 4 -ServEntry_WSpace # 4 -ServEntry_R1 # 4 -ServEntry_SIZEOF # 0 -; - -;Usr service numbers are those >= ServMinUsrNumber (see below) -;A Usr service array of chains is a block looking like this: -; word 0 = current capacity max entries*entry_size before block must grow) -; word 1 = current size (current number of entries*entry_size) -; - followed by an array of the current entries in the array of chains -; - each entry is 2 words and looks like this: -; word 0 = service call number for chain -; word 1 = anchor for chain (or 0 if no chain allocated) -; - ^ 0 -ServUChArray_Capacity # 4 -ServUChArray_Size # 4 -ServUChArray_Entries # 0 -ServUChArray_HdrSIZEOF # 0 -; - ^ 0 -ServUChEntry_ServiceNo # 4 -ServUChEntry_ChainAnchor # 4 -ServUChEntry_SIZEOF # 0 - - -ServMinUsrNumber * 256 ;'System' services in range 1..255, 'User' services >= 256 -ServUsrHashSize * 16 ; power of 2 - -ServMagicInstruction * &E1A00000 ; (MOV R0,R0) indicates new module format with service table -ServIndexInR1 * 1 ; bit 0 of table flags word, if set, means pass index in R1 - ; to handler, rather than service number - ; index corresponds directly to the position of the service - ; number in the table, and starts at 1 (0 is reserved for service claim) - -ServInitChainCapacity * 4 ;no. of entries to start at for a chain block -ServBumpChainCapacity * 4 ;no. of entries to grow by for a chain block - - -;hashing function for Usr service numbers is (number + (number>>8)) AND (hashsize-1) -; - MACRO - ServHashFunction $result,$service_number - ADD $result,$service_number,$service_number,LSR #8 - AND $result,$result,#ServUsrHashSize-1 - MEND - -; -;entry: [R1] -> chain block ([R1] = 0 if no block created yet) -; R5 = Code for entry, R6 = WSpace for entry, R7 = R1 value for entry -;exit: [R1] -> chain block (may have been created, or moved if had to grow) -; V clear if done, V set and error if ran out of room -; -AddServChainEntry ROUT - Push "R0-R4,LR" - LDR R2,[R1] ;get pointer to chain block from anchor - CMP R2,#0 - BNE %FT10 - MOV R3,#ServChain_HdrSIZEOF + ServInitChainCapacity*ServEntry_SIZEOF - Push "R1" - BL ClaimSysHeapNode ;need to create block - Pull "R1" - BVS %FT90 - STR R2,[R1] - MOV R0,#ServInitChainCapacity*ServEntry_SIZEOF - STR R0,[R2,#ServChain_Capacity] - MOV R0,#0 - STR R0,[R2,#ServChain_Size] -10 - LDR R0,[R2,#ServChain_Size] - LDR R3,[R2,#ServChain_Capacity] - CMP R0,R3 - BLO %FT20 - Push "R0,R1" - MOV R3,#ServBumpChainCapacity*ServEntry_SIZEOF - MOV R0, #HeapReason_ExtendBlock - BL DoSysHeapOpWithExtension ;need to grow block - STRVS R0,[SP] - Pull "R0,R1" - BVS %FT90 - STR R2,[R1] - LDR R3,[R2,#ServChain_Capacity] - ADD R3,R3,#ServBumpChainCapacity*ServEntry_SIZEOF - STR R3,[R2,#ServChain_Capacity] -20 - ADD R3,R2,#ServChain_HdrSIZEOF - ADD R3,R3,R0 - STR R5,[R3,#ServEntry_Code] - STR R6,[R3,#ServEntry_WSpace] - STR R7,[R3,#ServEntry_R1] - LDR R3,[R2,#ServChain_Size] - ADD R3,R3,#ServEntry_SIZEOF - STR R3,[R2,#ServChain_Size] -90 - STRVS R0,[SP] - Pull "R0-R4,PC" - -; -;entry: R2 -> chain block, R5 = Code for entry to remove, R6 = WSpace for entry to remove -;exit: registers preserved, entry removed and chain scrunched if entry was found -; -RemoveServChainEntry ROUT - Push "R0-R4,LR" - CMP R2,#0 - BEQ %FT90 - LDR R1,[R2,#ServChain_Size] - CMP R1,#0 - BEQ %FT90 - ADD R3,R2,#ServChain_HdrSIZEOF ;start of chain - ADD R1,R1,R3 ;end of chain -10 - LDR R4,[R3,#ServEntry_Code] - LDR R0,[R3,#ServEntry_WSpace] - TEQ R4,R5 - TEQEQ R0,R6 - BEQ %FT20 - ADD R3,R3,#ServEntry_SIZEOF - CMP R3,R1 - BLO %BT10 - B %FT90 -20 - ADD R3,R3,#ServEntry_SIZEOF ;found, scrunch up rest of chain - CMP R3,R1 - BHS %FT30 - LDR R4,[R3,#ServEntry_Code] - STR R4,[R3,#ServEntry_Code - ServEntry_SIZEOF] - LDR R4,[R3,#ServEntry_WSpace] - STR R4,[R3,#ServEntry_WSpace - ServEntry_SIZEOF] - LDR R4,[R3,#ServEntry_R1] - STR R4,[R3,#ServEntry_R1 - ServEntry_SIZEOF] - B %BT20 -30 - LDR R1,[R2,#ServChain_Size] - SUB R1,R1,#ServEntry_SIZEOF - STR R1,[R2,#ServChain_Size] -90 - Pull "R0-R4,PC" - -; -;entry: R9 -> module node, R4 -> start of module, R5 -> service handler specified by module header -;exit: R0 is -> table, or 0 if no table -; -FindServTable ROUT - Push "R1-R2,LR" - MOV R0,#0 - LDR R1,[R5] - LDR R2,=ServMagicInstruction - TEQ R1,R2 ;check for new format - BNE %FT90 ;nope - LDR R0,[R5,#-4] ;yes, so previous word is anchor (offset) for table - CMP R0,#0 ;if anchor is 0, new format but no table specified - ADDNE R0,R0,R4 ;else get address by adding module start to offset -90 - Pull "R1-R2,PC" - -; -;entry: R2 -> array of chains, R3 = service number, R5,R6,R7 = Code,WSpace,R1 for chain entry -;exit: R0=1 if success,service number added to array if necessary, entry added to appropriate chain, -; R0=0 if fail, because service number not yet in array, and array is full (grow not attempted) -; or V set, error returned if no room (for chain extension) -; -AddServUsr_Hashed ROUT - Push "R1-R4,LR" - ADD R1,R2,#ServUChArray_HdrSIZEOF ;chain start - LDR R0,[R2,#ServUChArray_Size] - ADD R0,R0,R1 ;chain end -10 - CMP R1,R0 - BHS %FT20 - LDR R4,[R1,#ServUChEntry_ServiceNo] - TEQ R4,R3 - ADDNE R1,R1,#ServUChEntry_SIZEOF - BNE %BT10 -;found entry for this service number in array - ADD R1,R1,#ServUChEntry_ChainAnchor ;R1 is address of anchor for chain - BL AddServChainEntry - MOVVC R0,#1 - B %FT90 ;succeeded (or OS error because no room) -; -20 -;entry for this service number not found, add it if array has room - LDR R0,[R2,#ServUChArray_Capacity] - LDR R4,[R2,#ServUChArray_Size] - CMP R4,R0 - MOVHS R0,#0 - BHS %FT90 ;failed (array needs extension) - STR R3,[R1,#ServUChEntry_ServiceNo] ;add entry at end of current list - MOV R4,#0 - STR R4,[R1,#ServUChEntry_ChainAnchor] ;no chain yet - LDR R4,[R2,#ServUChArray_Size] - ADD R4,R4,#ServUChEntry_SIZEOF - STR R4,[R2,#ServUChArray_Size] - ADD R1,R1,#ServUChEntry_ChainAnchor ;R1 is address of anchor for chain - BL AddServChainEntry - MOVVC R0,#1 -90 - Pull "R1-R4,PC" - -; -;entry: R2 -> hash header array, R3 = service number, R5,R6,R7 = Code,WSpace,R1 for chain entry -;exit: service number added to array on appropriate hash list if necessary, entry added to appropriate chain, -; or V set, error returned if no room (for either chain or chain array extension) -; -AddServUsr ROUT - Push "R0-R4,LR" - ServHashFunction R4,R3 ;result in R4 - ADD R1,R2,R4,LSL #2 ;R1 -> entry for this service number in hash header array - LDR R2,[R1] ;pick up anchor for array of chains - CMP R2,#0 - BNE %FT10 -;must create array of chains - Push "R1,R3" - MOV R3,#ServUChArray_HdrSIZEOF + 4*ServUChEntry_SIZEOF ;initially room for 4 entries - BL ClaimSysHeapNode - Pull "R1,R3" - BVS %FT90 - STR R2,[R1] - MOV R0,#4*ServUChEntry_SIZEOF - STR R0,[R2,#ServUChArray_Capacity] - MOV R0,#0 - STR R0,[R2,#ServUChArray_Size] -10 - BL AddServUsr_Hashed - BVS %FT90 - CMP R0,#1 - BEQ %FT90 ;add succeeded, done -;add failed, so we need to grow the array of chains - Push "R1,R3" - MOV R3,#4*ServUChEntry_SIZEOF ;bump up capacity by 4 entries - MOV R0, #HeapReason_ExtendBlock - BL DoSysHeapOpWithExtension - Pull "R1,R3" - BVS %FT90 - STR R2,[R1] - LDR R0,[R2,#ServUChArray_Capacity] - ADD R0,R0,#4*ServUChEntry_SIZEOF - STR R0,[R2,#ServUChArray_Capacity] -;now we can do the add and it cannot fail - BL AddServUsr_Hashed -90 - STRVS R0,[SP] - Pull "R0-R4,PC" - -; -;entry: R3 = service number, R5,R6,R7 = Code,WSpace,R1 for chain entry -;exit: registers preserved, entry added to appropriate chain, -; or V set, error returned if no room -; -AddServSysOrUsr ROUT - Push "R0-R4,LR" - CMP R3,#ServMinUsrNumber - BHS %FT50 - LDR R1,=Serv_SysChains - LDR R2,[R1] - CMP R2,#0 - BNE %FT30 -;need to create array of service chain anchors, for service codes 0 to ServMinUserNumber-1 -;(0 is not used, because reserved for service cliamed, but done for convenience) - Push "R1,R3" - MOV R3,#ServMinUsrNumber*4 - BL ClaimSysHeapNode - Pull "R1,R3" - BVS %FT90 - STR R2,[R1] - MOV R0,#0 - MOV LR,#ServMinUsrNumber - MOV R4,R2 -10 - STR R0,[R4],#4 ;zero the anchors (no chains yet) - SUBS LR,LR,#1 - BNE %BT10 -30 - ADD R1,R2,R3,LSL #2 ;address of anchor for this Sys service number - BL AddServChainEntry ;add to chain - B %FT90 -; -50 - LDR R1,=Serv_UsrChains - LDR R2,[R1] - CMP R2,#0 - BNE %FT70 -;need to create array of hash headers for Usr chain arrays - Push "R1,R3" - MOV R3,#ServUsrHashSize*4 - BL ClaimSysHeapNode - Pull "R1,R3" - BVS %FT90 - STR R2,[R1] - MOV R0,#0 - MOV LR,#ServUsrHashSize - MOV R4,R2 -60 - STR R0,[R4],#4 ;zero the hash headers - SUBS LR,LR,#1 - BNE %BT60 -70 - BL AddServUsr -90 - STRVS R0,[SP] - Pull "R0-R4,PC" - -; -;entry: R9 -> module node, R12 -> incarnation node -;exit: module incarnation added onto service call chains as necessary -; OR V set, error returned if no room -; -; IRQs are disabled during update to make sure service distribution does not happen -; under interrupt, with possibly incomplete chains still under construction. A little -; worrying that this may mean interrupts are sometimes off for a while, but there you go. -; -AddToServiceChains ROUT - Push "R0-R8,LR" - MRS R8,CPSR - ORR R4,R8,#I32_bit - MSR CPSR_c,R4 ;IRQs off for update of chain structures - LDR R4,[R9,#Module_code_pointer] ;start of module - LDR R5,[R4,#Module_Service] - CMP R5,#0 - BEQ %FT90 - ADD R5,R5,R4 - ADD R6,R12,#Incarnation_Workspace - BL FindServTable - CMP R0,#0 - BEQ %FT50 - LDR R1,[R0],#4 ;flags word from table - LDR R5,[R0],#4 ;handler code offset from table - ADD R5,R5,R4 ;handler code address - MOV R2,#0 -10 - ADD R2,R2,#1 ;next index in table (start at 1) - LDR R3,[R0],#4 ;next service call number from table - CMP R3,#0 ;table terminated by 0 - BEQ %FT90 - TST R1,#ServIndexInR1 - MOVNE R7,R2 ;we must pass index to handler - MOVEQ R7,#0 ;we must pass service number - BL AddServSysOrUsr - BVS %FT90 - B %BT10 -; -50 ;awkward customer, with no service table - MOV R7,#0 ;must pass service number to handler (there is no index) - LDR R1,=Serv_AwkwardChain - BL AddServChainEntry -90 - STRVS R0,[SP] - MSR CPSR_c,R8 ;restore IRQ state (26-bit code used to corrupt V!) - Pull "R0-R8,PC" - -; -;entry: R9 -> module node, R12 -> incarnation node -;exit: module incarnation removed from service call chains as necessary -; flags preserved -; -; IRQs are disabled during update to make sure service distribution does not happen -; under interrupt, with possibly incomplete chains still under construction. A little -; worrying that this may mean interrupts are sometimes off for a while, but there you go. -; -RemoveFromServiceChains ROUT - Push "R0-R8,R10,LR" - MRS R10,CPSR - ORR R4,R10,#I32_bit - MSR CPSR_c,R4 ;IRQs off for update of chain structures - LDR R4,[R9,#Module_code_pointer] - LDR R5,[R4,#Module_Service] - CMP R5,#0 - BEQ %FT90 - ADD R5,R5,R4 - ADD R6,R12,#Incarnation_Workspace - BL FindServTable - CMP R0,#0 - BEQ %FT50 - LDR R1,[R0],#4 ;flags word from table - LDR R5,[R0],#4 ;handler code offset from table - ADD R5,R5,R4 ;handler code address -10 - LDR R3,[R0],#4 ;next service call number from table - CMP R3,#0 ;table terminated by 0 - BEQ %FT90 - CMP R3,#ServMinUsrNumber - BHS %FT20 - LDR R1,=Serv_SysChains - LDR R1,[R1] - CMP R1,#0 - BEQ %BT10 - ADD R1,R1,R3,LSL #2 - LDR R2,[R1] ;pick up anchor for Sys chain - BL RemoveServChainEntry - B %BT10 -; -20 - ServHashFunction R4,R3 ;result in R4 - LDR R1,=Serv_UsrChains - LDR R1,[R1] - CMP R1,#0 - BEQ %BT10 - LDR R1,[R1,R4,LSL #2] ;pick up anchor for array of chains - CMP R1,#0 - BEQ %BT10 - LDR R8,[R1,#ServUChArray_Size] - ADD R4,R1,#ServUChArray_HdrSIZEOF ;chain start - ADD R8,R8,R4 ;chain end -30 - CMP R4,R8 - BHS %BT10 - LDR LR,[R4,#ServUChEntry_ServiceNo] - TEQ LR,R3 - ADDNE R4,R4,#ServUChEntry_SIZEOF - BNE %BT30 - LDR R2,[R4,#ServUChEntry_ChainAnchor] - BL RemoveServChainEntry - B %BT10 -; -50 - LDR R1,=Serv_AwkwardChain - CMP R1,#0 - BEQ %FT90 - LDR R2,[R1] - BL RemoveServChainEntry -90 - MSR CPSR_cf,R10 ;restore IRQ state - Pull "R0-R8,R10,PC" ;MUST preserve flags - - ] ;ChocolateService - - LTORG - -;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -FreeIncarnation ROUT - ; copy error, free any workspace, incarnation link. - ; R12 incarnation pointer, R9 module node pointer - Push "R0-R2,R5,lr" - MRS R5, CPSR - BL Module_CopyError - STR R0, [stack] - LDR R2, [R12, #Incarnation_Workspace] - CMP R2, #0 - MOV R0, #HeapReason_Free - MOV R1, #RMAAddress - SWINE XOS_Heap - [ ModHand_IntrinsicBI - SUB R2, R12, R9 - CMP R2, #ModInfo - BEQ FreeIncarnation_Exit ;if equal, this is the intrinsic incarnation 'node' - ] - MOV R2, R12 - BL FreeSysHeapNode -FreeIncarnation_Exit - MSR CPSR_f, R5 - Pull "R0-R2,R5,PC" - -;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; KillAndFree: -; R0 -> module -; R2 -> prevmodule -; Kills all incarnations, frees all space. - -KillAndFree ROUT - Push "R2, R3, R9, R12, lr" - MOV R9, R0 - ADDS R3, R9, #Module_incarnation_list ; ensure V clear -01 LDR R12, [R9, #Module_incarnation_list] - BL KillIncarnation - Pull "R2, R3, R9, R12, PC", VS - CMP R9, #0 - BNE %BT01 ; more incarnations yet - Pull "R2, R3, R9, R12, PC" - -;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; KillIncarnation -; R9 module ptr -; R12 incarnation ptr -; R3 previous incarnation -; R2 previous module -; Exit: R9 zeroed if module completely gone -; -KillIncarnation ROUT - Push "R0-R2, R6, R10, lr" - MRS R6, CPSR - MOV R10, #1 ; fatal die - CMP r12, #0 ; fudge for 0 incarnations: - BLNE CallDie ; tidy up anyway - STRVS R0, [stack] - Pull "R0-R2, R6, R10, PC", VS - [ ModHand_InitDieServices - BL IssueServicePostFinal - ] - [ ModHand_IntrinsicBI - SUB R2, R12, R9 - CMP R2, #ModInfo - BEQ %FT01 ;if equal, this is the intrinsic incarnation 'node' - ] - MOV R2, R12 - BL FreeSysHeapNode ; free incarnation node -01 LDR R0, [R9, #Module_incarnation_list] - CMP R0, #0 ; last incarnation? - LDREQ R2, [stack, #2*4] - BLEQ DelinkAndFreeModule - MOVEQ R9, #0 - MSR CPSR_f, R6 - Pull "R0-R2, R6, R10, PC" - -LoseModuleSpace_if_its_the_only_incarnation - Push "R0-R2, R6, R10, lr" - MRS R6, CPSR - B %BT01 - -;************************************************************* -; CallDie -; take R9 -> module node -; R12 -> incarnation node -; R3 -> previous incarnation -; R10 = fatality -; check against CAO -; delink incarnation, issue die, deal with workspace. - -CallDie ROUT - Push "R0-R7, R11, R12, lr" - MRS R7, CPSR - - MOV R11, #0 - LDR R11, [R11, #Curr_Active_Object] - - ; check killability - - LDR R0, [R9, #Module_code_pointer] - BL %FT10 ; is_CAO? - BLO %FT04 ; code block is CAO - - ; check if workspace block could be CAO: may have handler in there - - LDR R0, [R12, #Incarnation_Workspace] - BL %FT20 ; check block before getting size - BVS ModuleIsntCAO ; not heap block - we don't - BL %FT10 ; know what's going on. - BHS ModuleIsntCAO ; not CAO - -04 CMP R10, #0 ; fatal? - BNE CantKill - LDR R0, [R12, #Incarnation_Workspace] - BL %FT20 - BVS ModuleIsntCAO ; soft die of non-heap module OK -CantKill - ADR R0, ErrorBlock_CantKill - [ International - BL TranslateError - ] -01 STR R0, [stack] - LDR R3, [stack, #4*3] - LDR R12, [stack, #4*(7+2)] - STR R12, [R3, #Incarnation_Link] ; relink - ORR R7, R7, #V_bit - MSR CPSR_f, R7 - Pull "R0-R7, R11, R12, PC" - MakeErrorBlock CantKill - -ModuleIsntCAO - MOV R11, #0 ; set R11 to incarnation number. - LDR R0, [R9, #Module_incarnation_list] -03 CMP R0, R12 - ADDNE R11, R11, #1 - LDRNE R0, [R0, #Incarnation_Link] - BNE %BT03 - - [ ChocolateService - ;remove from service chains now, as part of delink - BL RemoveFromServiceChains - ] - LDR R0, [R12, #Incarnation_Link] - STR R0, [R3, #Incarnation_Link] ; delink - ADD R12, R12, #Incarnation_Workspace - LDR R1, [R9, #Module_code_pointer] - LDR R0, [R1, #Module_Die] - BIC R0, R0, #&80000000 ; knock out invincibility bit - CMP R0, #0 ; WARNING: don't try to combine these 2 instructions in a BICS - it wouldn't clear V - MOV lr, PC - ADDNE PC, R1, R0 ; call. - [ ChocolateService - BVC HaveKilled - ;add back to service chains as part of relink (cant error through lack of memory, since we had room before delink) - LDR R12, [stack, #4*(7+2)] - BL AddToServiceChains - B %BT01 -HaveKilled - | - BVS %BT01 - ] - [ Oscli_HashedCommands - BL FreeCmdHashEntries - ] - BL FreeSWIEntry - - CMP R10, #0 ; soft die? - BEQ %FT02 - - LDR R12, [stack, #4*(7+2)] - LDR R2, [R12, #Incarnation_Workspace] - CMP R2, #0 - MOVNE R1, #RMAAddress - MOVNE R0, #HeapReason_Free - SWINE XOS_Heap - MOV R0, #0 - STR R0, [R12, #Incarnation_Workspace] ; orgone -02 - BIC R7, R7, #V_bit - MSR CPSR_f, R7 - Pull "R0-R7, R11, R12, PC" - -; check if block @ R0 contains address R11 -10 LDR R1, [R0, #-4] - ADD R1, R1, R0 - CMP R0, R11 - CMPLS R11, R1 - MOV PC, lr ; return LO for Yes - -; check block @ R0 is a valid RMA heap block -20 - Push "R0-R3, lr" - MOV R2, R0 - MOV R0, #HeapReason_ExtendBlock - MOV R1, #RMAAddress - MOV R3, #0 - SWI XOS_Heap - Pull "R0-R3, PC" ; V set if not. - -;************************************************************* -; DelinkAndFreeModule -; R9 -> Module -; R2 -> prevmodule - -DelinkAndFreeModule ROUT - Push "R0-R2,R5,lr" - MRS R5, CPSR - -; loop here to find predecessor; make death re-entrant - MOV R0, #Module_List -01 - LDR R1, [R0, #Module_chain_Link] - CMP R1, R9 - MOVNE R0, R1 - BNE %BT01 - - LDR R1, [R9, #Module_chain_Link] - STR R1, [R0, #Module_chain_Link] ; delinked - - LDR R2, [R9, #Module_code_pointer] - MOV R1, #RMAAddress - MOV R0, #HeapReason_Free - SWI XOS_Heap - - MOV R2, R9 - [ ChocolateSysHeap - ASSERT ChocolateMABlocks = ChocolateBlockArrays + 16 - MOV r1,#ChocolateBlockArrays - LDR r1,[r1,#16] - BL FreeChocolateBlock - BLVS FreeSysHeapNode - | - BL FreeSysHeapNode - ] - - MSR CPSR_f, R5 - Pull "R0-R2,R5,PC" - -;************************************************************************* -; common lookup for reinit, enter, die -; -; Exits with EQ if incarnation not specified, NE if incarnation specified -; and found. - -lookup_commoned ROUT - Push "lr" - WritePSRc SVC_mode, lr ; we will exit with IRQs enabled - BL LookUp_Module ; node ptr in R0 - BEQ %FT01 ; not found - CMP R12, #-1 - BEQ %FT02 ; incarnation not found - CMP R12, #0 - MOV R9, R0 - Pull "PC" -01 - ADR R0, ErrorBlock_RMNotFound - Push "r1-r6" - MOV r3, #0 - LDR r3, [r3, #IRQsema] - CMP r3, #0 - BNE %FT03 - [ International - MOV R4, R1 - BL TranslateError_UseR4 - Push "r0" - | - BL GetOscliBuffer - Push r5 - LDR r2, [r0], #4 - STR r2, [r5], #4 - BL rmecopystr -copynfrmname - LDRB r2, [r1], #1 - CMP r2, #32 - STRGTB r2, [r5], #1 - BGT copynfrmname - - BL rmecopystr - STRB r2, [r5] ; terminate - ] - Pull "r0-r6" - - -03 - SETV - Pull "PC" - MakeErrorBlock RMNotFound -02 - ADR R0, ErrorBlock_IncarnationNotFound - [ International - BL TranslateError - ] - B %BT03 - MakeErrorBlock IncarnationNotFound - -MakeNotFoundError ; r1 -> module name - Push lr - B %BT01 - -;************************************************************* -; Lookup_Module -; Entry: R1 -> module name -; Exit: R0 -> module chain node (0 for not found) -; R1 -> postfix of name -; R12 -> incarnation node (0 for not specified, -1 for not found) -; R2 -> previous module for potential delinking -; R3 -> previous incarnation " " " -; NE for found/EQ for not - - -LookUp_Module ROUT - Push "R4, R5, lr" - - WritePSRc SVC_mode, R2 ; interrupts on - LDR R2, =Module_List -01 LDR R0, [R2, #Module_chain_Link] - CMP R0, #0 - Pull "R4, R5, PC", EQ ; return if not found - LDR R4, [R0, #Module_code_pointer] - LDR R3, [R4, #Module_Title] - ADD R3, R3, R4 ; got ptr to title - MOV R4, #Postfix_Separator ; allowed terminator for StrCmp - BL Module_StrCmp ; compare with abbreviation. - MOVNE R2, R0 - BNE %BT01 ; loop if not found - LDRB R4, [R1], #1 ; get terminator - CMP R4, #Postfix_Separator - BEQ %FT02 - - ; now a quick fudge to spot recursive ModHand calls during module death. - LDR R12, [R0, #Module_incarnation_list] - CMP R12, #0 - MOVEQ R12, #-1 ; no incarnations! - MOVNE R12, #0 ; no postfix/incarnation specified - CMP PC, #0 - Pull "R4, R5, PC" ; back with NE - -02 LDRB R4, [R1] - CMP R4, #" " - BGT %FT03 - CMP R1, R1 ; force EQ - Pull "R4, R5, PC" ; not found: naff postfix -03 - Push "R1" ; updated value to return - BL FindIncarnation - MOVEQ R12, #-1 ; failed to find postfix. - CMP PC, #0 ; force NE - Pull "R1, R4, R5, PC" ; back with NE - -;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; FindIncarnation -; R0 is node pointer, need to loop to find incarnation ($R1) -; Return EQ if not found, -; NE => R12 -> incarnation, R3 -> previnc - -FindIncarnation ROUT - Push "lr" - ADD R3, R0, #Module_incarnation_list ; previnc -03 LDR R12, [R3, #Incarnation_Link] - CMP R12, #0 - Pull "PC", EQ ; failed to find postfix. - Push "R3,R4" - ADD R3, R12, #Incarnation_Postfix - MOV R4, #0 ; no special terminator - BL Module_StrCmp - Pull "R3,R4" - MOVNE R3, R12 - BNE %BT03 - CMP PC, #0 ; force NE - Pull "PC" - -;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; -; Module_StrCmp -; -; Do a string comparison, given pointers in R1, R3. -; Ignore case, allow $R1 to be an abbreviation of $R3 -; Strings are terminated by ctrl-char, or ASC(R4) for $R1 -; -; out: EQ => match found, R1 -> terminator of R1 string -; NE => match not found, R1 preserved -; R3 corrupted in all cases -; - -Module_StrCmp Entry "r1,r2,r5-r7" - MOV r2, #0 -01 - LDRB r7, [r1], #1 - LDRB r5, [r3], #1 - CMP r7, r4 - CMPNE r7, #32 - CMPLE r5, #32 - BLE %FT02 - UpperCase r7, r6 - UpperCase r5, r6 - CMP r7, r5 - ADDEQ r2, r2, #1 - BEQ %BT01 - CMP r2, #0 - TOGPSR Z_bit, r2 ; invert EQ/NE - CMPEQ r7, #"." ; success if abbreviation - EXIT NE - CMP r5, #" " ; reject abbreviation - EXIT LT ; after full match - ADD r1, r1, #1 -02 - SUB r1, r1, #1 - CMP r2, #0 ; reject 0-length match - TOGPSR Z_bit, r2 ; invert EQ/NE - STREQ r1, [stack] ; r1 -> terminator - EXIT ; return with success - -;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -EnvStringSkipName ROUT - Push "R0" -01 LDRB R0, [R10], #1 - CMP R0, #" " - BGT %BT01 -02 LDREQB R0, [R10], #1 - CMP R0, #" " - BEQ %BT02 - SUB R10, R10, #1 - Pull "R0" - MOV PC, lr - -;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; PreferIncarnation -; R9 -> module node -; R12 -> incarnation node -; R3 -> previous incarnation -PreferIncarnation - Push "R0" - LDR R0, [R12, #Incarnation_Link] - STR R0, [R3, #Incarnation_Link] - LDR R0, [R9, #Module_incarnation_list] - STR R0, [R12, #Incarnation_Link] - STR R12, [R9, #Module_incarnation_list] - Pull "R0" - MOV PC, R14 - -;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -Module_CopyError ROUT -; grab an oscli buffer for the error, -; rather than having a permanent module buffer - Push "R0, R2, R5, R6, lr" - BL GetOscliBuffer - - STR R5, [stack] - LDR R2, [R0], #4 - STR R2, [R5], #4 -01 LDRB R2, [R0], #1 - STRB R2, [R5], #1 - CMP R2, #0 - BNE %BT01 - Pull "R0, R2, R5, R6, PC" - -;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; Claim chunk from RMA : increase RMA if can, -; force size to multiple of 32 -4 to keep alignment OK - -RMAClaim_Chunk ROUT - MOV R0, #HeapReason_Get - Push "R0, R3, lr" - - ADD R3, R3, #31+4 ; now force size to 32*n-4 - BIC R3, R3, #31 ; so heap manager always has - SUB R3, R3, #4 ; 8-word aligned blocks - - B IntoRMAHeapOp - -;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -DoRMAHeapOpWithExtension - Push "R0, R3, lr" - -IntoRMAHeapOp - MOV R1, #RMAAddress - SWI XOS_Heap - Pull "R0, R3, PC", VC - - LDR r14, [r0] ; look at error number - TEQ r14, #ErrorNumber_HeapFail_Alloc - STRNE r0, [stack] - Pull "r0, r3, PC", NE ; can only retry if ran out of room - - Push r3 ; in case extension - LDR r1, [stack, #4] - CMP r1, #HeapReason_ExtendBlock - BNE notRMAextendblock - Push "r5, r6" - LDR r1, [r2, #-4] ; pick up block size - ADD r5, r1, r2 ; block end +4 - SUB r5, r5, #4 ; TMD 02-Aug-93: block size includes size field (optimisation was never taken) - MOV r6, #RMAAddress - LDR r6, [r6, #:INDEX:hpdbase] - ADD r6, r6, #RMAAddress ; free space - CMP r5, r6 ; does block butt against end? - ADDNE r3, r3, r1 ; max poss size needed - Pull "r5, r6" - - ; note that this doesn't cope well with a block at the end preceded by a - ; free block, but tough. - -notRMAextendblock - MOV r1, #RMAAddress - LDR R0, [R1, #:INDEX: hpdbase] - LDR R1, [R1, #:INDEX: hpdend] - SUB R1, R1, R0 ; bytes free - SUB R1, R3, R1 ; bytes needed - - Pull r3 - ADD R1, R1, #8 ; safety factor - - MOV R0, #1 ; try and expand RMA. - SWI XOS_ChangeDynamicArea - Pull "R0" ; heap reason code back - MOV R1, #RMAAddress - SWIVC XOS_Heap -01 - ADRVSL R0, ErrorBlock_MHNoRoom - [ International - Push "LR",VS - BLVS TranslateError - Pull "LR",VS - ] - Pull "r3, PC" - -;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; Data - -crstring = 13 - ALIGN - -;***************************************************************************** -; *Unplug code. - -Unplug_Code Entry "r7-r9" - CMP r1, #0 - BNE ZapTheModule - -; If name not given, list unplugged modules - -; MOV r1, #0 ; start with module 0 (r1 is already zero indicating no parameters to command!) - MOV r2, #-1 ; start with main ROMs - MOV r7, #0 ; flag indicating whether we've had any unplugged modules already -10 - MOV r0, #ModHandReason_EnumerateROM_ModulesWithInfo - SWI XOS_Module - BVS %FT30 ; no more, so finish off - CMP r4, #-1 ; is it unplugged? - BNE %BT10 ; no, then go for another one - - MOV r8, r1 ; save module and podule numbers - MOV r9, r2 - TEQ r7, #0 ; if already printed header message - BNE %FT20 ; then skip - [ International - BL WriteS_Translated - = "Unp:Unplugged modules are:", 10, 13, 0 - ALIGN - | - ADR r0, AreUnpluggedMessage - SWI XOS_Write0 - ] - EXIT VS - MOV r7, #1 -20 - MOV r0, r3 - SWI XOS_Write0 - EXIT VS - CMP r2, #-1 - BEQ %FT25 ; if a main ROM, then no blurb after name (and V=0) - [ International - MOV r4, r2 - | - ADRGT r4, podbra ; is a podule module - ADRLT r4, extnbra ; is an extn rom module - ] - MVNLT r2, r2 ; so invert number - SUB r0, r0, r3 ; length of module name - RSB r0, r0, #24 ; number of spaces to pad out to column 24 (may be -ve) -21 - SWI XOS_WriteI + " " ; always print at least one space - EXIT VS - SUBS r0, r0, #1 - BGT %BT21 - [ :LNOT: International - MOV r0, r4 - SWI XOS_Write0 - EXIT VS - ] - SUB sp, sp, #3*4 ; make buffer on stack - MOV r0, r2 - MOV r1, sp - MOV r2, #3*4 - SWI XOS_ConvertCardinal4 - [ International - CMP r4,#-1 - MOV r4,r0 ; r4 -> number - BLT %FT23 - BL WriteS_Translated_UseR4 - = "Podule:(Podule %0)",0 - ALIGN - B %FT24 -23 - BL WriteS_Translated_UseR4 - = "Extn:(Extn ROM %0)",0 - ALIGN -24 - ADD sp, sp, #3*4 ; restore stack - | - SWIVC XOS_Write0 - ADD sp, sp, #3*4 ; restore stack - SWIVC XOS_WriteI + ")" - ] -25 - SWIVC XOS_NewLine - MOVVC r1, r8 ; restore module and podule number - MOVVC r2, r9 - BVC %BT10 - EXIT - -30 - CMP r7, #0 ; NB will clear V in any case - [ International - BNE %FT31 - BL WriteS_Translated - = "NoUnp:No modules are unplugged", 10, 13, 0 - ALIGN -31 - EXIT - | - ADREQ r0, NoUnpluggedMessage - SWIEQ XOS_Write0 - EXIT ; exit with V=0 unless error in Write0 - -AreUnpluggedMessage - = "Unplugged modules are:", 10, 13, 0 -NoUnpluggedMessage - = "No modules are unplugged", 10, 13, 0 -podbra - = "(" -rommposp - = "Podule ", 0 -extnbra - = "(" -rommposer - = "Extn ROM ", 0 - ALIGN - ] - -ZapTheModule - MOV r9, #0 ; indicate unplug, not insert -UnplugInsertEntry - MOV r12, #0 ; search from start of chain - MOV r7, r0 ; name pointer - MOV r4, #0 ; no extra terminator - MOV r5, #0 ; indicate no versions found yet - - MOV r6, #0 ; indicate no version found that was initialised - MOV r1, r7 - BL SkipToSpace ; leaves r1 pointing to 1st space or control char - BL SkipSpaces ; leaves r1 -> 1st non-space, r0 = 1st non-space char - CMP r0, #&7F - CMPNE r0, #" " ; if a ctrl char, then - MOVLS r8, #&80000000 ; indicate to unplug all versions - BLS %FT40 - CMP r0, #"-" - ADDEQ r1, r1, #1 - MOVEQ r8, #-1 - MOVNE r8, #1 - MOV r0, #1 :SHL: 31 ; check terminator is control char or space - SWI XOS_ReadUnsigned - EXIT VS - MUL r8, r2, r8 ; apply sign -40 - MOV r1, r7 - BL FindROMModule - TEQ r12, #0 - BEQ %FT60 ; no versions of this module found, so report error - -42 - LDR r14, [r12, #ROMModule_OlderVersion] ; find oldest version of this module - TEQ r14, #0 - MOVNE r12, r14 - BNE %BT42 - -45 - TEQ r8, #&80000000 ; if not doing any old podule - LDRNE r14, [r12, #ROMModule_PoduleNumber] - TEQNE r14, r8 ; and podule number doesn't match - BNE %FT50 ; then skip this one - - LDRB r14, [r12, #ROMModule_Initialised] ; if this version of CODE was initialised then keep pointer to it - TEQ r14, #0 - MOVNE r6, r12 ; save pointer to it - MOV r5, #&FF ; set up byte mask (and indicate found) - LDR r1, [r12, #ROMModule_CMOSAddrMask] - AND r3, r5, r1, LSR #16 ; get bit mask - ANDS r1, r1, r5 - BEQ %FT50 ; if no CMOS, then look for another module - MOV r0, #ReadCMOS - SWI XOS_Byte - EXIT VS - TEQ r9, #0 - ORREQ r2, r2, r3 ; set unplug bit - BICNE r2, r2, r3 ; or clear it as appropriate - MOV r0, #WriteCMOS - SWI XOS_Byte - EXIT VS -50 - LDR r14, [r12, #ROMModule_NewerVersion] ; go to next newer version - TEQ r14, #0 - MOVNE r12, r14 - BNE %BT45 - -60 - TEQ r5, #0 ; if we've seen any versions, then don't report error - BNE %FT70 - ADR r0, ErrorBlock_RMNotFoundInROM - [ International - BL TranslateError - | - SETV - ] - EXIT - -70 - CMP r9, #1 ; if doing unplug not insert - CMPNE r6, #0 ; and we found a match on an initialised version (else V=0) - [ 1 = 1 -;RCM's fix for MED-04173 - EXIT EQ - -; see if module is active, by checking for module in module list - MOV r0, #Module_List -60 - LDR r0, [r0, #Module_chain_Link] - TEQ r0, #0 ; module not active - BEQ %FT90 - LDR r1, [r0, #Module_ROMModuleNode] ; get active module's pointer to ROM module node - TEQ r1, r12 ; if it matches - BNE %BT60 - - MOV r0, #ModHandReason_Delete ; then tell him he's dead - LDR r1, [r6, #ROMModule_Name] - SWI XOS_Module -90 - | - MOVNE r0, #ModHandReason_Delete ; then tell him he's dead - LDRNE r1, [r6, #ROMModule_Name] - SWINE XOS_Module - ] - EXIT - -RMInsert_Code ALTENTRY - MOV r9, #1 ; indicate insert, not unplug - B UnplugInsertEntry - - MakeErrorBlock RMNotFoundInROM - -;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - [ ModHand_InitDieServices -; IssueServicePostInit -; On entry -; R9 -> module chain node -; R12 -> incarnation node -; On exit -; R0-R3 corrupted -; flags preserved - -IssueServicePostInit - Push "R4-R5, lr" - MRS R5, CPSR - - ASSERT ModHand_IntrinsicBI ; can't be bothered to support old world - - LDR R2, [R9, #Module_code_pointer] - LDR R0, [R2, #Module_HelpStr] - ADD R0, R2, R0 - BL GetVerNoFromHelpString - MOV R0, R2 - LDR R2, [R0, #Module_Title] - ADD R2, R0, R2 - MOV R4, R1 - MOV R1, #Service_ModulePostInit - SUB R3, R12, R9 - SUBS R3, R3, #ModInfo ; R3 = 0 if intrinsic base incarnation - ADDNE R3, R12, #Incarnation_Postfix - SWI XOS_ServiceCall - - MSR CPSR_f, R5 - Pull "R4-R5, pc" - -; IssueServicePostFinal -; On entry -; R9 -> module chain node -; R12 -> incarnation node (incarnation workspace is already freed) -; On exit -; R0 corrupted -; flags corrupted - -IssueServicePostFinal - Push "R1-R4, lr" - - ASSERT ModHand_IntrinsicBI ; can't be bothered to support old world - - LDR R2, [R9, #Module_code_pointer] - LDR R0, [R2, #Module_HelpStr] - ADD R0, R2, R0 - BL GetVerNoFromHelpString - MOV R0, R2 - LDR R2, [R0, #Module_Title] - ADD R2, R0, R2 - MOV R4, R1 - MOV R1, #Service_ModulePostFinal - SUB R3, R12, R9 - SUBS R3, R3, #ModInfo ; R3 = 0 if intrinsic base incarnation - ADDNE R3, R12, #Incarnation_Postfix - SWI XOS_ServiceCall - - Pull "R1-R4, pc" - ] - -;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - END diff --git a/s/MoreComms b/s/MoreComms deleted file mode 100644 index 53af73a2..00000000 --- a/s/MoreComms +++ /dev/null @@ -1,574 +0,0 @@ -; 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 => MoreComms - -Error_Code ROUT - ; Use MessageTrans to construct an error block by substituting the error text into - ; an error - - Push "r7,r8,lr" - - ASSERT ?Error_CodeTag <= 8 - ADR lr, Error_CodeTag - LDMIA lr, {r1,r2} - Push "r1,r2" - - MOV r1, r0 ; pointer - MOV r0, #0 ; base - SWI XOS_ReadUnsigned - Push "r2" - - MOV r0, sp ; Error block - [ :LNOT:International - ; Haven't got any alternate code, but at least it'll assemble - | - BL TranslateError_VClear - ] - - ; If error number's changed don't substitute - LDR r3, [r0] - TEQ r3, r2 - BNE %FT90 - - ; GSTrans the text into the error buffer - MOV r3, r0 - MOV r0, r1 - ADD r1, r3, #4 - MOV r2, #252 - SWI XOS_GSTrans - - ; Ensure 0-terminated - MOV r0, #0 - CMP r2, #252 - MOVHI r2, #252 - STRB r0, [r1, r2] - - MOV r0, r3 -90 - ADD sp, sp, #12 - SETV - Pull "r7,r8,pc" - -Error_CodeTag DCB "ErrSub", 0 - - LTORG - -Eval_Code ROUT - Push "lr" - LDR R1, =GeneralMOSBuffer - [ LongCommandLines - MOV R2, #LongCLISize - | - MOV R2, #256 - ] - SWI XOS_EvaluateExpression - Pull "PC", VS - [ :LNOT: International - SWI XOS_WriteS - = "Result is a",0 - ALIGN - Pull "PC", VS - CMP R1, #0 - ADREQ R0, %FT01 - ADRNE R0, %FT02 - SWI XOS_Write0 - Pull "PC", VS - SWI XOS_WriteS - = ", value : ",0 - ALIGN - Pull "PC", VS - | - Push "r4" - CMP R1, #0 - ADREQ R0, %FT01 - ADRNE R0, %FT02 - BL FindToken - MOV R4,R0 - BL WriteS_Translated_UseR4 - = "Result:Result is %0, value :",0 - ALIGN - SWI XOS_WriteI + " " - Pull "r4" - - ] - LDREQ R1, =GeneralMOSBuffer - MOVEQ R0, R2 - MOVEQ R2, #256 - SWIEQ XOS_BinaryToDecimal - MOV R5, #-1 -03 ADD R5, R5, #1 - CMP R5, R2 - BEQ %FT04 - LDRB R0, [R1, R5] - CMP R0, #&7F - MOVEQ R0, #"?"-"@" ; preversion!! - CMP R0, #31 - ADDLE R0, R0, #"@" - SWILE XOS_WriteI+"|" - Pull "PC", VS - CMP R0, #"|" - CMPNE R0, #"""" - CMPNE R0, #"<" - SWIEQ XOS_WriteI+"|" - SWIVC XOS_WriteC - BVC %BT03 - -04 SWIVC XOS_NewLine - Pull "PC" - - [ International -01 - = "Integer:an integer",0 -02 - = "String:a string",0 - | -01 - = "n integer",0 -02 - = " string",0 - ] - - ALIGN - -;**************************************************************************** -; Coupla utility commands - -Time_Code ROUT - Push "lr" - SUB R13, R13, #8 - MOV R1, R13 - MOV R0, #3 - STRB R0, [R1] - MOV R0, #14 - SWI XOS_Word - BVS %FT01 - MOV R0, #-1 - MOV R1, R13 - LDR R2, =GeneralMOSBuffer - MOV R3, #256 - ADRL R4, TimeFormat - SWI XTerritory_ConvertDateAndTime -01 ADD R13, R13, #8 - SWIVC XOS_Write0 - SWIVC XOS_NewLine - Pull "PC" - - -Ignore_Code ROUT - Push "lr" - MOVS R4, R1 - MOV R1, R0 - MOV R0, #10+ (1:SHL:30) - SWINE XOS_ReadUnsigned - Pull "PC", VS - MOV R6, R2 ; maybe number - BL CheckEOL - BNE %FT01 - - CMP R4, #0 - MOV R0, #&B6 - MOVEQ R1, #255 - MOVNE R1, #0 - MOV R2, #0 - SWI XOS_Byte - MOV R0, #6 - MOV R1, R6 - SWINE XOS_Byte - Pull "PC" - -01 ADRL R0, ErrorBlock_BadNumb - [ International - BL TranslateError - | - SETV - ] - Pull "PC" - -;***************************************************************************** - -ROMModules_Code Entry - [ International - BL GSWriteS_Translated - = "ROMMTitle:No. Position|IModule Name|I|IVersion|IStatus|M|J",0 - EXIT VS - | - ADRL r0, romm_helpstr - MOV r1, #0 - SWI XOS_PrettyPrint - EXIT VS - ] - MOV r1, #0 - MOV r2, #-1 -01 - SWI XOS_ReadEscapeState - PullEnv CS - BCS AckEscape - MOV r0, #ModHandReason_EnumerateROM_ModulesWithInfo - SWI XOS_Module - BVC %FT08 - CLRV - EXIT ; exit V clear - -; R1 = module number +1 -; R2 = podule number -; R3 -> name -; R4 = status (-1 unplugged, 0 dormant, 1 active, 2 running) -; R5 = chunk number -; R6 = version number - -; Copy info into buffer and prettyprint -08 - MOV r5, r1 ; save r1 and r2 for next call to OS_Module - MOV r10, r2 - MOV r0, r1 - MOV r2, #4 - SUB sp, sp, #4 - MOV r1, sp - SWI XOS_ConvertCardinal2 - ADD sp, sp, #4 - SUB r12, r1, r0 - LDR r1, =GeneralMOSBuffer - MOV r2, #256 - MOV r0, #31 - RSBS r12, r12, #3 -15 BLNE %FT20 - SUBS r12, r12, #1 - BPL %BT15 - MOV r0, r5 - SWI XOS_ConvertCardinal2 - MOV r0, #" " - BL %FT20 ; add space - CMP r10, #-1 - [ International - ADREQL r0, rommpossysrom - ADRLTL r0, rommposextrom - ADRGTL r0, rommpospodule - BL FindToken - | - ADREQL r0, rommpossr - ADRLTL r0, rommposer - ADRGTL r0, rommposp - ] - BL %FT21 ; add string - MOV r0, #" " - BL %FT20 ; add space - MOVGT r0, r10 ; if normal podule then use plain number (flags still set from CMP) - MVNLT r0, r10 ; if extension ROM then NOT it (-2 => 1, -3 => 2 etc) - SWINE XOS_ConvertCardinal1 - MOV r0, #TAB - BL %FT20 ; tab to col. 16 - MOV r0, r3 - BL %FT21 ; copy name in - MOV r3, r0 ; string length - MOV r0, #TAB -03 - CMP r3, #24 - ADDCC r3, r3, #8 - BLCC %FT20 - BCC %BT03 -04 - MOV r11, #"0" - TST r6, #&F0000000 ; 1st digit of integer part - ORRNE r0, r11, r6, LSR #28 - BLNE %FT20 - MOV r6, r6, LSL #4 - TSTEQ r6, #&F0000000 ; 2nd digit of integer part - ORRNE r0, r11, r6, LSR #28 - BLNE %FT20 - MOV r6, r6, LSL #4 - TSTEQ r6, #&F0000000 ; 3rd digit of integer part - ORRNE r0, r11, r6, LSR #28 - BLNE %FT20 - MOV r6, r6, LSL #4 - ORR r0, r11, r6, LSR #28 ; 4th digit of integer part - BL %FT20 - MOV r0, #"." - BL %FT20 - MOV r6, r6, LSL #4 - ORR r0, r11, r6, LSR #28 ; 1st digit of decimal part - BL %FT20 - MOV r6, r6, LSL #4 - ORR r0, r11, r6, LSR #28 ; 2nd digit of decimal part - BL %FT20 - MOVS r6, r6, LSL #4 ; only print 3rd and 4th digits of decimal part if non-zero - ORRNE r0, r11, r6, LSR #28 - BLNE %FT20 - MOVS r6, r6, LSL #4 - ORRNE r0, r11, r6, LSR #28 - BLNE %FT20 - MOV r0, #TAB - BL %FT20 - - CMP r4, #0 - [ International - ADRMIL r0, rommstatu - ADREQL r0, rommstatd - ADRGTL r0, rommstata - BL FindToken - | - ADRMIL r0, rommstu - ADREQL r0, rommstd - ADRGTL r0, rommsta - ] - CMP r4, #2 - [ International - ADREQL r0, rommstatr - BLEQ FindToken - | - ADREQL r0, rommstr - ] - BL %FT21 - MOV r0, #13 - BL %FT20 - MOV r0, #0 - BL %FT20 - LDR r0, =GeneralMOSBuffer - MOV r1, #0 - SWI XOS_PrettyPrint - EXIT VS - MOV r1, r5 - MOV r2, r10 - B %BT01 - -; R1 buffer ptr, R2 bufflen left - -20 - EntryS - SUBS r2, r2, #1 - STRPLB r0, [r1], #1 - EXITS -21 - EntryS - Push "r0" - MOV r12, r0 -22 - LDRB r0, [r12], #1 - CMP r0, #TokenEscapeChar - BEQ %FT23 - CMP r0, #0 - [ International - CMPNE r0, #10 - ] - BLNE %BT20 - BNE %BT22 - Pull "r0" - SUB r0, r12, r0 ; length of string - SUB r0, r0, #1 - EXITS - -23 - BL %BT20 - LDRB r0, [r12], #1 - BL %BT20 - B %BT22 - - [ International -rommpossysrom - = "SYSROM:System ROM", 0 -rommposextrom - = "EXTROM:Extn ROM", 0 -rommpospodule - = "PODROM:Podule", 0 - -rommstata - = "Active:Active", 0 - -rommstatd - = "Dormant:Dormant", 0 - -rommstatu - = "Unplugged:Unplugged", 0 - -rommstatr - = "Running:Running",0 - - ALIGN - | -romm_helpstr - = "No. Position",9,"Module Name",9,9,"Version",9,"Status",10,13,0 -rommpossr - = "System ROM", 0 -rommstu - = "Unplugged", 0 -rommstd - = "Dormant", 0 -rommsta - = "Active", 0 -rommstr - = "Running", 0 - - ALIGN - ] - -;***************************************************************************** - -RMEnsure_Code Entry "r0, r1" - MOV r1, r0 ; name pointer - MOV r0, #ModHandReason_LookupName - SWI XOS_Module - MOVVS r10, r0 ; module handler will build a nice error - BVS RMEDoCommand ; module not found - LDR r0, [stack] ; now find version number -01 - LDRB r6, [r0], #1 - CMP r6, #" " - BNE %BT01 - BL RMEGetVerNo - MOV r6, r1 - LDR r0, [r3, #Module_HelpStr] - TEQ r0, #0 - BEQ RMEDoCommand ; no help string, so do command - ADD r0, r0, r3 - BL GetVerNoFromHelpString - CMP r1, r6 - EXIT GE - MOV r10, #0 -RMEDoCommand - Pull "r0, r1" - CMP r1, #2 - BEQ BuildRMEnsureError -04 - LDRB r1, [r0], #1 - CMP r1, #" " - BNE %BT04 -05 - LDRB r1, [r0], #1 - CMP r1, #" " - BEQ %BT05 -06 - LDRB r1, [r0], #1 - CMP r1, #" " - BNE %BT06 - SUB r0, r0, #1 -03 - SWI XOS_CLI - Pull PC - -BuildRMEnsureError - MOVS r0, r10 - BEQ %FT10 - SETV - Pull pc -10 ADR r0, ErrorBlock_ModuleTooOld - [ International - LDR r4,[r3, #Module_Title] - ADD r4,r4,r3 - BL TranslateError_UseR4 - SETV - Pull pc - | - BL GetOscliBuffer - MOV r10, r5 - LDR r2, [r0], #4 - STR r2, [r5], #4 - BL rmecopystr - MOV r6, r0 - - LDR r2, [r3, #Module_Title] ; r3 still module pointer - ADD r0, r2, r3 - BL rmecopystr - MOV r0, r6 - BL rmecopystr - STRB r2, [r5] ; terminate - B BuildRMEnsureError - ] - -rmecopystr - LDRB r2, [r0], #1 - CMP r2, #32 - STRGEB r2, [r5], #1 - BGE rmecopystr - MOV pc, lr - - MakeErrorBlock ModuleTooOld - -; ************************************************************************* -; -; RMEGetVerNo - Read version number from a string -; -; in: R0 -> string -; -; out: R0, R4, R5, R12 corrupted -; R1 = version number in BCD with the decimal point between bits 15 and 16 -; eg "2.34" => &00023400, "5.6789" => &00056789, "17" => &00170000 -; only the last 4 digits of the integer part, and the first 4 decimal places are stored -; - -RMEGetVerNo Entry - MOV r1, #0 -10 - LDRB r12, [r0], #1 - CMP r12, #" " - BEQ %BT10 -11 - SUB r12, r12, #"0" - CMP r12, #9 - ORRLS r1, r12, r1, LSL #4 ; just keep nibbles - we only need the - LDRLSB r12, [r0], #1 ; result to be ordered, not continous - BLS %BT11 - MOV r5, #0 - CMP r12, #"."-"0" - BNE %FT13 - MOV r4, #16 -12 - SUBS r4, r4, #4 - BMI %FT13 - LDRB r12, [r0], #1 - SUB r12, r12, #"0" - CMP r12, #9 - ORRLS r5, r5, r12, LSL r4 - BLS %BT12 -13 - ORR r1, r5, r1, LSL #16 - EXIT - -; ************************************************************************* -; -; GetVerNoFromHelpString - Read version number from a module help string -; -; in: R0 -> module help string -; -; out: R1 = version number in BCD with the decimal point between bits 15 and 16 -; eg "2.34" => &00023400, "5.6789" => &00056789, "17" => &00170000 -; only the last 4 digits of the integer part, and the first 4 decimal places are stored -; All other registers preserved -; - -GetVerNoFromHelpString Entry "r0, r4, r5, r12" - MOV r5, #0 ; char count -10 - LDRB r1, [r0], #1 - CMP r1, #0 ; check character - EXIT EQ ; if end of string then no version number so return zero - ADD r5, r5, #1 - CMP r1, #TAB - ADDEQ r5, r5, #7 - BICEQ r5, r5, #7 - CMP r5, #16 ; hit verno col yet? - BLT %BT10 -20 - LDRB r1, [r0], #1 - CMP r1, #TAB - CMPNE r1, #31 ; if a control character (except TAB) - MOVLT r1, #0 ; then no version number so return zero - EXIT LT - SUB r1, r1, #"0" - CMP r1, #9 ; if not a digit - BHI %BT20 ; then try next character - SUB r0, r0, #1 ; was a digit so go back to it - BL RMEGetVerNo ; read version number from here - EXIT - - END diff --git a/s/MoreSWIs b/s/MoreSWIs deleted file mode 100644 index 051f907c..00000000 --- a/s/MoreSWIs +++ /dev/null @@ -1,1198 +0,0 @@ -; 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 => MoreSWIs - -;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; SubstituteArgs -; in: R0 -> arglist (space delimited args, terminated by 10,13,0) - [ :LNOT:No26bitCode -; top bit set => don't append unused part of line - ] -; R1 -> buffer -; R2 = bufflen -; R3 -> string to mangle -; R4 = no of chars in $R3 -; out: R2 = no of chars in buffer - -XOS_SubstituteArgs_code - Push "r5,lr" - [ No26bitCode - MOV r5, #0 - | - BIC r0, r0, #&80000000 - AND r5, r0, #&80000000 - ] - SWI XOS_SubstituteArgs32 - Pull "r5,lr" - B SLVK_TestV - -;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; SubstituteArgs32 -; in: R0 -> arglist (space delimited args, terminated by 10,13,0) -; R1 -> buffer -; R2 = bufflen -; R3 -> string to mangle -; R4 = no of chars in $R3 -; R5 = flags -; top bit set => don't append unused part of line -; out: R2 = no of chars in buffer - -XOS_SubstituteArgs32_code ROUT - - WritePSRc SVC_mode, R12 ; enable IRQs - - Push "R0-R8, lr" - ADD R8, R4, R3 - -; try and get parameter positions. -; Items starting with " can have spaces in - - MOV R6, #0 ; parameter number - LDR R12, =MacExStartPtrs - LDR R4, =MacExEndPtrs -35 LDRB R5, [R0], #1 - CMP R5, #" " - BEQ %BT35 - MOV R2, #" " - CMP R5, #"""" - MOVEQ R2, #"""" ; quoted param - CMP r6, #10 ; "rest of line" item? - MOVEQ r2, #-1 ; terminate on EOL only - SUB R0, R0, #1 - STR R0, [R12, R6, LSL #2] - CMP r5, #"""" - ADDEQ R0, R0, #1 -36 LDRB R5, [R0], #1 - BL suba_chktrm - CMPNE R5, R2 - BNE %BT36 - CMP R5, #"""" - LDREQB R5, [R0] - CMPEQ R5, #"""" ; check for "" in string - ADDEQ R0, R0, #1 - BEQ %BT36 - CMP R2, #"""" - SUBNE R0, R0, #1 - STR R0, [R4, R6, LSL #2] - ADD R6, R6, #1 - CMP R6, #11 ; Parameters 0-9 and a "rest" set. - BNE %BT35 - -; Keep track of highest param used, so can tack any unused stuff on end. -; R3 points at string to get chars from -; R12 at start ptrs -; R4 at end ptrs - - MOV R6, #0 ; count. - MOV R7, #0 ; highest param used. - LDR R2, [stack, #4*2] -37 BL suba_getchar - BEQ %FT41 - CMP R5, #"%" - BEQ %FT44 -38 BL suba_addchar - B %BT37 - -PCnotparm - ADD R5, R5, #"0" - MOV R11, R5 - MOV R5, #"%" - BL suba_addchar - MOV R5, R11 - B %BT38 - -44 BL suba_getchar - MOVEQ R5, #"%" - BEQ %FT40 - CMP R5, #"%" - BEQ %BT38 - CMP R5, #"*" - BEQ DoStarParams - SUBS R5, R5, #"0" - BMI PCnotparm - CMP R5, #9 - BGT PCnotparm - -; itsa parameter! Get ptrs from R12, R4 - CMP R5, R7 - ADDGE R7, R5, #1 - LDR R11, [R4, R5, LSL #2] -CopyToR11FromParamR5 - LDR R10, [R12, R5, LSL #2] ; start ptr -39 LDRB R5, [R10], #1 - CMP R10, R11 - BGT %BT37 - BL suba_addchar - B %BT39 - -DoStarParams ; had %* : find limits to copy between - BL suba_getchar - BEQ PCStarTerminates - SUBS R5, R5, #"0" - BMI PCStarNoDigit - CMP R5, #9 - MOVLE R7, #11 ; flag * used - LDRLE R11, [R4, #10*4] ; always to EOL - BLE CopyToR11FromParamR5 -PCStarNoDigit - ADD R5, R5, #"0" - MOV R11, R5 - MOV R5, #"%" - BL suba_addchar - MOV R5, #"*" - BL suba_addchar - MOV R5, R11 - B %BT38 - -PCStarTerminates - MOV R5, #"%" - BL suba_addchar - MOV R5, #"*" -40 BL suba_addchar -41 CMP r7, #11 - LDREQ r12, [r4, #10*4] ; no more to copy - BEQ %FT42 - LDR r0, [stack, #4*5] - CMP r0, #0 - LDRPL R12, [R12, R7, LSL #2] ; ptr to rest of command line : copy - LDRMI r12, [r4, #10*4] ; caller wants no appending. -42 LDRB R5, [R12], #1 - BL suba_addchar - BL suba_chktrm - BNE %BT42 - - STR R6, [stack, #4*2] - Pull "R0-R8, lr" - ExitSWIHandler - -suba_addchar - EntryS - ADD R6, R6, #1 - CMP R6, R2 - STRNEB R5, [R1], #1 - EXITS NE - - PullEnv - - ADRL R0, ErrorBlock_BuffOverflow - [ International - BL TranslateError - ] - STR R0, [stack] - Pull "R0-R8, lr" - B SLVK_SetV - -suba_getchar - CMP R3, R8 - LDRNEB R5, [R3], #1 - MOV PC, lr - -suba_chktrm - CMP R5, #13 - CMPNE R5, #10 - CMPNE R5, #0 - MOV PC, lr - - LTORG - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; Take R0 as pointer to null-terminated string, print it -; with line breaks before words that won't fit on the current line. -; CR forces a newline. TAB=tab to next column of 8. CHR$31 = hard space -; <27,n> => substitute nth dictionary entry: -; dictionary is pointed at by r1, consists of a list of null-terminated -; strings, with preceding length bytes. -; 0th dictentry => use string at r2. - -XOS_PrettyPrint_code ROUT - -; Inside here, r1 is the current string pointer -; R3 is the linelength to format to -; R4 is the current position in the line. -; r6 is the return addr in word counting -; r7 is the r1 restore value in reading word length -; r8 is used in dictionary selection in getbytepp -; r9 is the stack restoration level for exiting. -; r11 is the dictionary pointer (0 means use MOS dict) -; r12 is the special token pointer - - WritePSRc SVC_mode, r11 - - Push "r0-r9, lr" - - BL ReadWindowWidth ; read linelength - MOV R3, R0 - MOV R0, #165 ; read output cursor - SWI XOS_Byte - ORR R4, R1, #&80000000 ; no leading space even if in line. - LDMFD stack, {r1, r11, r12} ; reload strptr, dictptr, tokptr - CMP r11, #0 - ADREQL r11, MOSdictionary - MOV r9, stack - -; loop over all words -01 BL getwordlength - CMP R2, #0 - BNE %FT03 - BL getbytepp - B %FT21 ; null word - test for done -03 - CMP R4, #0 - ADDGT R2, R2, #1 ; allow for separator - ADD R0, R2, R4 - BIC R0, R0, #&80000000 ; clear R4 flag - CMP R0, R3 - BLE %FT10 - CMP R4, #0 - SUBGT R2, R2, #1 ; remove leading space length - MOV R4, #0 ; if word too long to fit, do newline - SWI XOS_NewLine - BVS exitpp - -10 CMP R4, #0 - BIC R4, R4, #&80000000 ; clear "no leading space" flag - ADD R4, R4, R2 - SUBGT R2, R2, #1 - SWIGT XOS_WriteI+" " ; output separator if not 1st on line - BVS exitpp - -04 BL getbytepp - CMP R0, #31 ; hard space? - MOVEQ R0, #" " - SWI XOS_WriteC - BVS exitpp - SUBS R2, R2, #1 - BNE %BT04 - -21 CMP R0, #13 - MOVEQ R4, #0 - SWIEQ XOS_NewLine - BVS exitpp - - CMP R0, #TAB - BEQ %FT20 - CMP R0, #0 - BNE %BT01 - -exitpp MOV stack, r9 - STRVS r0, [stack] - Pull "r0-r9,lr" - B SLVK_TestV - -; TAB had: align to next multiple of 8 -20 BIC R4, R4, #&80000000 - ; first want to get next word length, to see if it's worth doing - ADD R5, R4, #8 - BIC R5, R5, #7 - SUB R5, R5, R4 ; spaces for this tab - -24 BL getwordlength - CMP R2, #0 - BNE %FT23 ; got the word - BL getbytepp - CMP R0, #13 - BEQ %BT21 ; TAB, CR - whalley! - CMP R0, #TAB - SUBNE R5, R5, #1 ; leading spaces, junk ignored - ADDEQ R5, R5, #8 ; multiple tabs OK tho. - CMP r0, #0 ; terminator? - BNE %BT24 ; only case to allow zero-length word - SUB r1, r1, #1 ; we know this rewinds OK - -23 ADD R0, R4, R5 - ADD R0, R0, R2 - CMP R0, R3 - MOVGT R0, #13 ; next tab stop too far : newline - BGT %BT21 -22 SWI XOS_WriteI+" " - BVS exitpp - ADD R4, R4, #1 - SUBS r5, r5, #1 - BNE %BT22 - ORR R4, R4, #&80000000 ; set top bit to disable leading space - B %BT01 - -getwordlength - MOV r6, lr - MOV r10, r9 ; first copy context - MOV r2, stack - MOV r7, r1 -copycontextpp - CMP r9, r2 - LDRNE r0, [r9, #-4]! - Push r0, NE - BNE copycontextpp - - MOV r2, #0 ; word length -02 BL getbytepp - CMP R0, #31 - CMPNE R0, #" "+1 - ADDGE r2, r2, #1 - BGE %BT02 - MOV r1, r7 - MOV stack, r9 - MOV r9, r10 - MOV pc, r6 - -getbytepp LDRB r0, [r1], #1 - CMP r0, #TokenEscapeChar - BEQ gettokenpp - CMP r0, #0 - MOVNE pc, lr - CMP stack, r9 - MOVHS pc, lr - Pull r1 ; back to previous token - B getbytepp - -gettokenpp - LDRB r0, [r1], #1 ; tokno - Push r1 ; save context - CMP r0, #0 - MOVEQ r1, r12 - BEQ getbytepp - MOV r1, r11 -gtoklp SUBS r0, r0, #1 - LDRNEB r8, [r1] - ADDNE r1, r1, r8 - BNE gtoklp - ADD r1, r1, #1 - B getbytepp - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -ReadWindowWidth ROUT ; read "number of chars printable after Newline - ; before we're on the next line" - MOV R0, #VduExt_WindowWidth -ReadVduVarForSam - Push "R0, R1, lr" ; R1 reserves space - MOV R0, #-1 - STR R0, [stack, #4] ; overwrite R1 value - MOV R0, sp - MOV R1, sp - SWI XOS_ReadVduVariables - Pull "R0, R14, PC" - -;***************************************************************************** -; R0 -> envstring, R1 -> 5 byte time - -WriteEnv_SWICode ROUT ; for debugger use - CMP R0, #0 - BEQ %FT01 - LDR R10, =EnvString - MOV R11, R0 -02 LDRB R12, [R11], #1 - CMP R12, #" " - MOVLT R12, #0 - STRB R12, [R10], #1 - BGE %BT02 - -01 CMP R1, #0 - ExitSWIHandler EQ - LDR R10, =EnvTime - MOV R11, #4 -03 LDRB R12, [R1, R11] - STRB R12, [R10, R11] - SUBS R11, R11, #1 - BPL %BT03 - ExitSWIHandler - -;***************************************************************************** - -; LET RdArgs() BE -; R0 ptr to key defn string -; R1 ptr to command line to decode -; R2 ptr to workspace -; R3 size of workspace -; Returns R3 size left - -; Flags used in initial args decoding - -AFlag * 1:SHL:8 ; flags shifted up a byte; avoid looking like chars. -KFlag * 1:SHL:9 -SFlag * 1:SHL:10 -EFlag * 1:SHL:11 -GFlag * 1:SHL:12 -UnsetBase * &FF000000 ; only if all bits set (cannot be RAM address) - -PresentFlag * &7FFFFFFF -AbsentFlag * 0 - -; Type flags - -EndType * 0 -FlagType * 1 -KeywordType * 2 -ItemType * 3 - -RdArgs_SWICode ROUT - - WritePSRc SVC_mode, R10 - - Push "R4, R8, R9, lr" - MOV R10, R2 ; R10 points at next available word - MOV R12, R0 -01 MOV R11, #UnsetBase - SUBS R3, R3, #4 - BMI %FT99 ; insufficient space - STR R11, [R10], #4 -02 LDRB R11, [R12], #1 - CMP R11, #"/" - BNE %FT03 - LDRB R11, [R12], #1 - UpperCase R11, R9 - CMP R11, #"A" - MOVEQ R11, #AFlag - CMP R11, #"K" - MOVEQ R11, #KFlag - CMP R11, #"S" - MOVEQ R11, #SFlag - CMP R11, #"E" - MOVEQ R11, #EFlag - CMP R11, #"G" - MOVEQ R11, #GFlag - CMP R11, #256 - LDRGE R9, [R10, #-4] - ORRGE R9, R11, R9 - STRGE R9, [R10, #-4] -03 - CMP R11, #"," - BEQ %BT01 - CMP R11, #" " - BGE %BT02 - -; Initialisation complete: all flags set, R10 implies number of args. - MOV R8, R10 - -10 BL RdItem - BVS %FT90 - CMP R12, #KeywordType - BNE %FT11 - ADD R11, R2, R4, LSL #2 ; keyword ptr - BL RdItem - BVS %FT90 - CMP R12, #ItemType - BNE %FT98 - BL SetKeyword - BVS %FT90 - B %BT10 - -11 CMP R12, #ItemType - BNE %FT12 - -; next positional arg := itemptr - - MOV R11, R2 -20 CMP R11, R8 - BEQ %FT98 ; no more positional args - LDR R12, [R11], #4 - CMP R12, #UnsetBase - BLO %BT20 - TST R12, #KFlag :OR: SFlag - BNE %BT20 - SUB R11, R11, #4 - BL SetKeyword - BVS %FT90 - B %BT10 - -12 CMP R12, #EndType - BNE %BT10 - -; postscan to check all /a args set. - MOV R12, R2 -30 CMP R12, R8 - BEQ %FT31 - LDR R11, [R12], #4 - CMP R11, #UnsetBase - BLO %BT30 - TST R11, #AFlag - BNE %FT98 ; bum args error - MOV R11, #AbsentFlag - STR R11, [R12, #-4] ; force "not present" - B %BT30 - -31 - Pull "R4, R8, R9, lr" - ExitSWIHandler - -98 ADR R0, ErrorBlock_BadParameters - [ International - BL TranslateError - ] - B %FT90 - -99 ADRL R0, ErrorBlock_BuffOverflow - [ International - BL TranslateError - ] -90 - Pull "R4, R8, R9, lr" - B SLVK_SetV - - MakeErrorBlock BadParameters - MakeErrorBlock ArgRepeated - ALIGN - -;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; RdItem: strips next item from command line -; In: R1 -> cmd line -; Out: R1 updated -; R12 contains type -; R4 contains ptr for Item, argno for Flag/Keyword -; VS means buffer full -;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -RdItem ROUT - Push "R1, R7, R8, lr" - MOV R8, #0 ; not demanding new arg -01 LDRB R12, [R1], #1 - CMP R12, #" " - BEQ %BT01 - BGE %FT33 - MOV R12, #EndType - CLRV - Pull "R1, R7, R8, PC" -33 - CMP R12, #"""" - BEQ ohnoitsquotedargumentsagain - - CMP R12, #"-" ; options? - BNE %FT02 ; nope - boring item -05 BL GetArg - LDRVS R1, [stack] - BVS %FT02 ; not recognised - boring item - STR R1, [stack] ; new restore value. - MRS R12, CPSR - Push R12 ; save EQ/NE - LDR R12, [R2, R4, LSL #2] - CMP R12, #UnsetBase - BHS %FT34 - ADR R0, ErrorBlock_ArgRepeated - [ International - BL TranslateError - ] - ADD stack, stack, #4 ; discard PSR - SETV - Pull "R1, R7, R8, PC" -34 - ANDS R12, R12, #SFlag - BNE %FT35 - MOV R12, #KeywordType - ADD stack, stack, #4 ; discard PSR - CLRV - Pull "R1, R7, R8, PC" -35 - MOV R12, #PresentFlag - STR R12, [R2, R4, LSL #2] - -; now deal with flag elision: if nextchar valid keyword char, rescan - Pull R12 - TST R12, #Z_bit - BEQ %FT20 ; GetArg returned NE, so not single char abbr - Push "R2, R3" - LDRB R2, [R1] - BL CheckR2OKChar - Pull "R2, R3" - MOVEQ R8, #1 ; MUST get another arg - BEQ %BT05 -20 MOV R12, #FlagType - CLRV - Pull "R1, R7, R8, PC" - -02 CMP R8, #0 - BEQ %FT39 - ADR R0, ErrorBlock_BadParameters - [ International - BL TranslateError - ] - SETV - Pull "R1, R7, R8, PC" -39 - ; copy arg until <" " - - MOV R7, #" " - SUB R1, R1, #1 -06 MOV R4, R10 -03 LDRB R12, [R1], #1 - CMP R12, R7 - CMPNE R12, #" "-1 - BLE %FT04 -10 - SUBS R3, R3, #1 - STRPLB R12, [R10], #1 - BPL %BT03 -23 - ADRL R0, ErrorBlock_BuffOverflow - [ International - BL TranslateError - ] - SETV - Pull "R1, R7, R8, PC" - -04 CMP R7, #"""" - BNE %FT07 - CMP R12, #"""" - BNE %FT08 - LDRB R12, [R1], #1 - CMP R12, #"""" - BEQ %BT10 -07 MOV R12, #0 ; terminate - SUBS R3, R3, #1 - BMI %BT23 - STRB R12, [R10], #1 - MOV R12, #ItemType - SUB R1, R1, #1 - STR R1, [stack] - CLRV - Pull "R1, R7, R8, PC" - -ohnoitsquotedargumentsagain - MOV R7, #"""" - B %BT06 - -08 ADRL R0, ErrorBlock_BadString - [ International - BL TranslateError - ] - SETV - Pull "R1, R7, R8, PC" - -;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; GetArg -; Look through keys: allow only full match on first pass, then -; single char abbreviation on second pass -; Return V set if not key, EQ if single letter abbreviation -;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -GetArg ROUT -; In: R0 ptr to keystring -; R1 ptr to potential option. -; Out: VS if nomatch or -; R1 updated -; R4 argument number - - Push "R0-R3, R5-R6, lr" - MOV R6, #-1 ; pass number -20 MOV R4, #0 - -01 LDRB R2, [R0], #1 - CMP R2, #" " - BEQ %BT01 - -02 BL CheckR2OKChar - BNE %FT03 ; matched in full - LDRB R3, [R1], #1 - UpperCase R2, R5 - UpperCase R3, R5 - CMP R2, R3 - LDREQB R2, [R0], #1 - BEQ %BT02 - - CMP R6, #0 - BLT %FT04 - -; 2nd pass: allow abbreviation -; IF single char abbreviation THEN success ELSE skip - LDR R2, [stack, #4] - SUB R2, R1, R2 ; length of match+1 - CMP R2, #2 - SUBEQ R1, R1, #1 - BEQ %FT13 ; success - -; skip to next keyword -04 LDRB R2, [R0], #1 - CMP R2, #" " - BLT %FT05 - CMP R2, #"," - ADDEQ R4, R4, #1 - CMPNE R2, #"=" - BNE %BT04 - LDR R1, [stack, #4] - B %BT01 - -03 ; NE on first pass: check input string terminated OK - LDRB R2, [R1] ; check for end of input word - BL CheckR2OKChar - BNE %FT13 ; yaay! full & correct match - SUB R0, R0, #1 - B %BT04 - -05 ADDS R6, R6, #1 - LDMLEFD stack, {R0, R1} - BLE %BT20 - SETV - Pull "R0-R3, R5-R6, PC" ; back with failure - -13 STR R1, [stack, #4] - CLRPSR V_bit, R0 ; clrV (just) - Pull "R0-R3, R5-R6, PC" ; back with success - -CheckR2OKChar ROUT - CMP R2, #"A" - RSBGES R3, R2, #"Z" - BGE %FT50 - CMP R2, #"a" - RSBGES R3, R2, #"z" - BGE %FT50 - CMP R2, #"0" - RSBGES R3, R2, #"9" - BGE %FT50 - CMP R2, #"_" - MOV PC, lr -50 CMP R0, R0 ; set EQ - MOV PC, lr - -;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -SetKeyword ROUT -; R11 ptr at keyword flags -; R4 ptr to value - Push "R0-R2, R5, R6, lr" - LDR R0, [R11] - TST R0, #EFlag :OR: GFlag - STR R4, [R11] ; result will always be here anyway - BEQ %FT01 - SUB R5, R10, R4 ; length of value - ADD R3, R3, R5 ; increase free space - ADD R2, R5, #11 ; round up to nearest word, then 1 - BIC R2, R2, #3 - - MOV R6, stack ; STR stack, [stack, -R2]! is unpredictable - STR R6, [stack, -R2]! ; reserve stack frame - - ADD R2, stack, #4 ; input value ptr -03 LDRB R6, [R4, R5] - STRB R6, [R2, R5] - SUBS R5, R5, #1 - BPL %BT03 ; copy the value - - TST R0, #EFlag - MOV R0, R2 - BNE %FT02 - ADD R1, R4, #2 ; free space pointer - SUBS R3, R3, #2 - MOV R2, R3 - BMI %FT04 - ORR R2, R2, #1:SHL:31 - SWI XOS_GSTrans -05 SUB R3, R3, R2 - ADD R10, R1, R2 ; update freespace pointer - STRB R2, [R1, #-2] - MOV R2, R2, LSR #8 - STRB R2, [R1, #-1] - BCS %FT04 - -90 LDR stack, [stack, #0] ; unwind frame (and don't let AAsm use - STRVS R0, [stack] ; postindexed!!!) - Pull "R0-R2, R5, R6,PC" - -04 ADRL R0, ErrorBlock_BuffOverflow - [ International - BL TranslateError - | - SETV - ] - B %BT90 - -02 ADD R1, R4, #3 ; free space pointer - SUBS R3, R3, #3 ; adjust for type (1 byte) + length (2 bytes) - BMI %BT04 - MOV R2, R3 - SWI XOS_EvaluateExpression - BVS %BT90 - TEQ R1, #0, 2 ; if non-zero, then string, so update length - MOVNE R14, #1 ; set type byte to definitely non-zero - STRNEB R14, [R4] - BNE %BT05 ; (C=0 so no buffer overflow, V=0 from SWI) - STRB R1, [R4] ; set type byte to zero (=> integer) - SUBS R3, R3, #5 - BMI %BT04 - STRB R2, [R4, #1] - MOV R2, R2, LSR #8 - STRB R2, [R4, #2] - MOV R2, R2, LSR #8 - STRB R2, [R4, #3] - MOV R2, R2, LSR #8 - STRB R2, [R4, #4] - ADD R10, R4, #5 - B %BT90 - -01 - CLRV - Pull "R0-R2, R5, R6,PC" - - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; ReadRAMFSLimits -; Return R0 start, R1 end (i.e. 1st byte out of area) - -ReadRAMFSLimits_Code ROUT - Push "lr" - MOV r0, #ChangeDyn_RamFS - SWI XOS_ReadDynamicArea ; out: r0 = base, r1 = current size - Pull "lr" - ADDVC r1, r1, r0 ; if no error, make r1 -> after end - ORRVS lr, lr, #V_bit ; if error, then set V_bit on return - ExitSWIHandler - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; ExitAndDie -; r0-r2 parameters for Exit -; r3 pointer to module name - -TerminateAndSodOff ROUT - - Push "r0-r2" - MOV r10, #0 - STR r10, [r10, #Curr_Active_Object] - MOV r1, r3 - MOV r0, #ModHandReason_Delete - SWI XOS_Module - Pull "r0-r2" - SWI XOS_Exit - -;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; AddCallBack entry to callback vector -; r0 address to call -; r1 workspace ptr - -AddCallBack_Code ROUT - - Push "r0-r3, lr" - [ ChocolateSysHeap - ASSERT ChocolateCBBlocks = ChocolateBlockArrays + 0 - MOV r3,#ChocolateBlockArrays - LDR r3,[r3,#0] - BL ClaimChocolateBlock - MOVVS r3, #12 - BLVS ClaimSysHeapNode - | - MOV r3, #12 - BL ClaimSysHeapNode - ] - BVS %FT99 - Pull "r0, r1" - MOV r10, #0 - WritePSRc SVC_mode+I_bit, r3 ; IRQs off while holding context. - LDR r3, [r10, #CallBack_Vector] - [ True - STR r3, [r2, #0] - STMIB r2, {r0, r1} - STR r2, [r10, #CallBack_Vector] - Pull "r2, r3, lr" - | - STR r3, [r2], #4 - STMIA r2, {r0, r1} - SUB r2, r2, #4 - STR r2, [r10, #CallBack_Vector] - Pull "r2, r3, lr" - MOV r10, #0 - ] - LDRB r11, [r10, #CallBack_Flag] - ORR r11, r11, #CBack_VectorReq - STRB r11, [r10, #CallBack_Flag] - B SLVK - -99 STR r0, [stack] - Pull "r0-r3, lr" - B SLVK_SetV - -;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; -; RemoveCallBack - Entry for SWI OS_RemoveCallBack -; -; Removes an entry on the callback vector before it has been called -; -; in: r0 = address that would have been called -; r1 = workspace ptr -; -; out: - -; - -RemoveCallBack ROUT - Push "r2-r4" - SavePSR r10 ; save old I bit -10 - WritePSRc SVC_mode+I_bit, r11 ; disable IRQs while looking at list - MOV r11, #0 - LDR r2, [r11, #CallBack_Vector]! ; r11 -> prev, r2 -> this -20 - TEQ r2, #0 - Pull "r2-r4", EQ - ExitSWIHandler EQ - - LDMIA r2, {r3,r4,r12} ; r3 -> next, r4 = addr, r12 = ws - TEQ r4, r0 ; check if correct address - TEQEQ r12, r1 ; and correct ws ptr - MOVNE r11, r2 ; if not, then prev:=this - MOVNE r2, r3 ; and this:=next - BNE %BT20 ; and loop - - STR r3, [r11] ; prev.link := next - RestPSR r10 ; safe now to restore IRQ status - - Push "r0, r1, lr" ; now free this node - [ ChocolateSysHeap - ASSERT ChocolateCBBlocks = ChocolateBlockArrays + 0 - MOV r1,#ChocolateBlockArrays - LDR r1,[r1,#0] - BL FreeChocolateBlock - BLVS FreeSysHeapNode - | - BL FreeSysHeapNode ; and then start again (NB we must - ; restart from head of list again, as - ; enabling IRQs could have changed list - ] - STRVS r0, [sp, #0] - Pull "r0, r1, lr" - BVC %BT10 - - Pull "r2-r4" ; had an error while releasing block - ORR lr, lr, #V_bit - ExitSWIHandler - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; SWI OS_Confirm - -; If pointer visible, change pointer shape and look at mouse keys too. -; Flush mouse buffer first. -; Wait until key pressed. -; Returns: (lowercased) character in r0 (if mouse scanned, LH button = 'y', -; other buttons = 'n') -; C set for Escape condition -; EQ set if r0 = 'y' - - [ International -confirm_yn DCB "YesNo:yn",0 ; Token to lookup message for Yes/No - | -confirm_yn DCB "yn" - ] -ptr_confirm DCB "ptr_confirm",0 ; Wimp's confirm pointer sprite shape -confirm_scale DCD 1,1,1,1 ; Scaling factor for sprite op -Confirm_Code ROUT - WritePSRc SVC_mode, r10 ; enable IRQs - Push "r0-r7, lr" - -; Lookup the symbols for Y/N - - ADR r0, confirm_yn - [ International - BL FindToken ; Lookup in messages, use default if error - ] - LDRB r1, [r0], #1 ; Y character - LDRB r2, [r0], #1 ; N character - ORR r1, r1, r2, LSL #8 - Push "r1" ; Y=[sp], N=[sp+1] - -; Save current pointer selected - - MOV r0, #106 - MOV r1, #255 ; read pointer state - SWI XOS_Byte - BVS confirm_error - BIC r2, r1, #&80 - MOV r10, r1 - TST r10, #15 ; Pointer enabled? - BEQ confirm_waitloop ; Jump if not - -; Find Wimp's "ptr_confirm" sprite, searching first RMA then ROM - - SWI XWimp_BaseOfSprites - MOVVS r10, #0 ; If error then don't use mouse - BVS confirm_waitloop ; And jump to poll keyboard - - MOV r11, r0 ; Save -> ROM sprites, r1 -> RMA sprites - ADR r2, ptr_confirm ; -> sprite name - MOV r0, #&128 ; Read sprite info - SWI XOS_SpriteOp - BVC %FT10 ; Jump if sprite in RMA - - ADR r2, ptr_confirm ; -> sprite name - MOV r1, r11 ; -> ROM sprites - MOV r0, #&128 ; Read sprite info - SWI XOS_SpriteOp - MOVVS r10, #0 ; If error then don't use mouse - BVS confirm_waitloop ; And jump to poll keyboard - -; Set pointer shape from the sprite area found (r1) - -10 MOV r7, #0 ; No pixel translation - ADR r6, confirm_scale ; pointer scaling factor (1:1) - MOV r5, #0 ; y hot spot offset - MOV r4, #0 ; x hot spot offset - MOV r3, #&23 ; No palette, shape 3 - ADR r2, ptr_confirm ; -> sprite name - MOV r0, #&124 ; Set pointer shape - SWI XOS_SpriteOp ; Ignore errors - - MOV r0, #21 - MOV r1, #9 - SWI XOS_Byte ; flush mouse buffer - - MOV r0, #&C4 - MOV r1, #0 - MOV r2, #255 - SWI XOS_Byte ; read current repeat rate. - MOV r0, #0 - LDR r0, [r0, #MetroGnome] - ADD r11, r1, r0 ; time to wait for - -confirm_mouserepeat - SWI XOS_Mouse - CMP r2, #0 ; any buttons down? - BEQ confirm_waitloop - - CMP r3, r11 - BMI confirm_mouserepeat - -confirm_waitloop - MOV r0, #129 - MOV r1, #1 - MOV r2, #0 - SWI XOS_Byte ; scan for key - BVS confirm_error - CMP r2, #255 - BNE confirm_gotkey - - TST r10, #15 - BEQ confirm_waitloop ; no mouse scan wanted. - - SWI XOS_Mouse - BVS confirm_error - CMP r2, #0 - BEQ confirm_waitloop - - TST r2, #4 ; LH button? - LDRNEB r1, [sp] ; Yes - LDREQB r1, [sp, #1] ; No - -confirm_gotkey - CMP r2, #&1B ; ESCAPE or normal char read ? - ORREQ r11, r1, #&100 - MOVNE r11, r1 - LowerCase r11, r1 - - TSTS r10, #15 ; Was pointer changed? - MOV r1, r10 - MOV r0, #106 - SWINE XOS_Byte ; Yes then restore shape - - Pull "r10" ; r10=YN - AND r10, r10, #&ff ; Retain Y byte - Pull "r0-r7, lr" - BIC lr, lr, #C_bit :OR: Z_bit ; SKS. Punter lr has VClear - AND r0, r11, #&FF - TST r11, #&100 ; ESCAPE condition ? (SKS) - ORRNE lr, lr, #C_bit - CMP r0, r10 - ORREQ lr, lr, #Z_bit - B SLVK - -confirm_error - ADD sp, sp, #4 ; Drop YN - STR r0, [stack] - Pull "r0-r7, lr" - B SLVK_SetV - - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; In r0 = continuation crc (0 to start) -; r1 -> start of core -; r2 -> end of core -; r3 = increment (typically 1, 2 or 4), but can be -ve - -; Out r0 = crc so far - -CRC_Code ROUT - - [ {TRUE} - WritePSRc SVC_mode, r10 ; Could take a long time - - Push "r3, r14" - TEQ r3, #0 ; is increment 0? - if so, it's silly - BEQ %FT80 ; so return error, rather than going on forever - - MOV r10, r1 - MOV r12, #&A000 ; CRC EOR pattern = &A001 - ORR r12, r12, #&0001 -10 - CMP r10, r2 ; Finished ? - BEQ %FA90 ; Must be exact end, allows -ve offset - - LDRB r14, [r10], r3 - EOR r0, r0, r14 ; EOR the data with current crc lo - CMP r10, r2 ; length might be odd so check again - MOVEQ r11, #8 ; if equal then only do 8 bits - BEQ %FT20 - - LDRB r14, [r10], r3 - EOR r0, r0, r14, LSL #8 ; EOR the data with current crc hi - MOV r11, #16 ; do 16 bits - -20 - MOVS r0, r0, LSR #1 ; acc >>= 1; CS/CC - EORCS r0, r0, r12 ; CS -> eor, CC -> ok - SUBS r11, r11, #1 ; 8 bits per byte - BNE %BT20 - B %BT10 - -80 - ADRL r0, ErrorBlock_BadParameters ; return "Bad parameters" error - [ International - BL TranslateError - ] - Pull "r3, r14" - B SLVK_SetV - -90 - Pull "r3, r14" - ExitSWIHandler - | - WritePSRc SVC_mode, r10 ; Could take a long time - - Push "r3, r4, lr" - MOV r10, r1 - MOV r12, #&A000 ; CRC EOR pattern = &A001 - ORR r12, r12, #&0001 - MOV r14, #1 ; A single bit to be shifted - -10 CMP r10, r2 ; Finished ? - BEQ %FA90 ; Must be exact end, allows -ve offset - - LDRB r4, [r10], r3 - MOV r11, #0 ; Go round the bits - -20 TST r4, r14, LSL r11 ; Is data bit = carry ?; NE/EQ - BEQ %FT30 - - MOVS r0, r0, LSR #1 ; acc >>= 1; CS/CC - EORCC r0, r0, r12 ; NE, CC -> eor, NE, CS -> ok - B %FT40 - -30 MOVS r0, r0, LSR #1 ; acc >>= 1; CS/CC - EORCS r0, r0, r12 ; EQ, CS -> eor, EQ, CC -> ok - -40 ADD r11, r11, #1 ; 8 bits per byte - CMP r11, #8 - BLO %BT20 - - B %BT10 - -90 Pull "r3, r4, lr" - ExitSWIHandler - ] - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - END diff --git a/s/Morris b/s/Morris deleted file mode 100644 index 3e8350b6..00000000 --- a/s/Morris +++ /dev/null @@ -1,81 +0,0 @@ -; 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. -; -; > Morris - -; -; ROM entry code for RISC OS Black -; - -MorrisHeaderCodeSize * (24*4) ;Code occupies less than this, we pad to this boundary so POST code - ;has a nicely defined place for its romsize and code entry points -; VECTOR AREA: - - LDR pc, .+ResetIndirection - LDR PC, UNDEF_VEC - LDR PC, SWI_VEC - LDR PC, PREF_VEC - LDR PC, DATA_VEC - LDR PC, RES_VEC ; addr. exn not generated - LDR PC, IRQ_VEC - LDR PC, FIQ_VEC - - ! 0, "*** WARNING *** assembling Morris code" - -; The above 8 instructions will operate as expected in 32-bit ROM mode, -; or in 16-bit ROM mode with a 16-bit ROM used. In 16-bit ROM mode, and -; with 32-bit wide ROMs in use, they will instead be intepreted as 4 -; NV-condition instructions (exact meaning not determined and should be -; irrelevant) which should do nothing and so allow control to drop -; through to this point, still in 16-bit mode. Force IOMD into 32-bit -; ROM mode for bank 0. The following instruction sequence has been -; produced in 16-in-32 form by extracting hex values from a listing... - - DCD &0000B632, &0000E3A0 ; 20: MOV R11, #IO+IOMDREGS - point at IOMD - DCD &00000000, &0000E3A0 ; 28: MOV R0, #&0 - ROMCR:32b,slow,218.75us,no burst - DCD &00000080, &0000E5CB ; 30: STRB R0,[R11,#ROMCR0] - switch mode - [ :LNOT: ParallelFlashUpgrade - DCD &0000F000, &0000E3A0 ; 38: MOV PC, #0 - jump to 0 (this instr pre-fetched) - | -; At this point, we know that we're in an ARM 7500-based box with 32-bit ROMs that's -; just been powered up. These are the conditions under which we may wish to reprogram -; ourselves. -CFR_Offset * (ConsiderFlashROM - ROM - ((.-ROM)/2) - 8)/4 - DCD CFR_Offset :AND: &FFFF ; 38: B ConsiderFlashROM (this instr pre-fetched) - DCD &0000EA00 + (CFR_Offset:SHR:16) - ] - -; vector absolute targets for use from physical vector instructions - -UNDEF_VEC DCD UndInstInReset-ROM -SWI_VEC DCD SWIInReset -ROM -PREF_VEC DCD PrefAbInReset -ROM -DATA_VEC DCD DataAbInReset -ROM -RES_VEC DCD AddrExInReset -ROM -IRQ_VEC DCD IRQInReset -ROM -FIQ_VEC DCD FIQInReset -ROM - -UndInstInReset -SWIInReset -PrefAbInReset -DataAbInReset -AddrExInReset -IRQInReset -FIQInReset - SUB pc, pc, #8 - - ASSERT .-ROM <= MorrisHeaderCodeSize - % MorrisHeaderCodeSize-(.-ROM) - - END diff --git a/s/MsgCode b/s/MsgCode deleted file mode 100644 index e002c02f..00000000 --- a/s/MsgCode +++ /dev/null @@ -1,632 +0,0 @@ -; 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. -; -; Kernel.Messages -; -; This file deals with translating text and errors in an international -; kernel. -; -; -; TranslateError -; Entry: -; R0 = Pointer to error block (Error number followed by token:default). -; Exit -; R0 = pointer to error block to use. -; If the error semaphore is set a pointer to the original block is -; returned. -; V Set. -; - -; EXPORT Write0_Translated - - GBLL countmsgusage -countmsgusage SETL {FALSE} - [ countmsgusage - ! 0, "*** WARNING: Cacheing *ALL* messages - even those with substitutions" - ] - -TranslateError_VClear ROUT - Push "r4,LR" - MOV r4,#0 - BL TranslateError_UseR4 - [ No26bitCode - CLRV - Pull "r4,PC" - | - Pull "r4,PC",,^ - ] - -TranslateError ROUT - Push "r4,LR" - MOV r4,#0 - BL TranslateError_UseR4 - Pull "r4,PC" - -TranslateError_UseR4 - Push "R8,R9,LR" - MRS R8,CPSR - ORR R8,R8,#V_bit ; V set ready :) - - MOV LR,#0 - LDRB LR, [LR, #ErrorSemaphore] - TEQ LR,#0 - BNE %FT90 - - BIC R9, R8, #&0F - ORR R9, R9, #SVC_mode ; SVC mode, preserve IRQ state - MSR CPSR_c, R9 - - Push "R0-R7" - - MOV R5,#0 - MOV R6,#0 - MOV R7,#0 - MOV R1,#-1 ; We are looking up an error, don't bother - STRB R1, [R5, #ErrorSemaphore] ; translating other errors. - - [ CacheCommonErrors - BL CheckCommonErrorCache ; sets R9 to memory address for cached result - MOVNE R1,#0 - STRNE R9,[SP] - BNE %FT80 - MOV R2,R9 ; 0 - or our cached area! - MOV R3,#256 - | - MOV R2,#0 - ] - - ADR R1,KernelMessagesBlock+4 - SWI XMessageTrans_ErrorLookup - LDR R14,[R0] - LDR R1,[SP] - LDR R1,[R1] - CMP R14,R1 - STREQ R0,[SP] - - MOV R1,#0 ; To clear the semaphore - [ CacheCommonErrors - TEQNE R9,#0 ; Did we try to cache this message? - STRNE R1,[R9] ; blat out the error number -80 - ] - STRB R1, [R1 ,#ErrorSemaphore] ; Clear error semaphore - - Pull "R0-R7" -90 - MSR CPSR_cf, R8 ; Back to original mode, V set - Pull "R8,R9,PC" - - [ CacheCommonErrors - ; This block MUST not be empty -CommonErrorAddresses - [ countmsgusage - & ErrorBlock_RCExc - & ErrorBlock_RCNegative - & ErrorBlock_BadString - & ErrorBlock_VarCantFind - & ErrorBlock_BadVarType - & ErrorBlock_BadVarNam - & ErrorBlock_VarTooLong - & ErrorBlock_BadMacVal - & ErrorBlock_VarNoRoom - & ErrorBlock_BadBra - & ErrorBlock_StkOFlo - & ErrorBlock_MissOpn - & ErrorBlock_MissOpr - & ErrorBlock_BadInt - & ErrorBlock_StrOFlo - & ErrorBlock_NaffItm - & ErrorBlock_DivZero - & ErrorBlock_BadBase - & ErrorBlock_NumbTooBig - & ErrorBlock_BadClaimNum - & ErrorBlock_SysHeapFull - & ErrorBlock_BadDynamicArea - & ErrorBlock_AreaAlreadyExists - & ErrorBlock_AreaNotOnPageBdy - & ErrorBlock_OverlappingAreas - & ErrorBlock_CantAllocateArea - & ErrorBlock_CantAllocateLevel2 - & ErrorBlock_UnknownAreaHandler - & ErrorBlock_CantGetPhysMem - & ErrorBlock_AplWSpaceInUse - & ErrorBlock_ChDynamCAO - & ErrorBlock_RAMFsUnchangeable - & ErrorBlock_HeapBadReason - & ErrorBlock_HeapFail_Init - & ErrorBlock_HeapFail_BadDesc - & ErrorBlock_HeapFail_BadLink - & ErrorBlock_HeapFail_Alloc - & ErrorBlock_HeapFail_NotABlock - & ErrorBlock_HeapFail_BadExtend - & ErrorBlock_HeapFail_ExcessiveShrink - & ErrorBlock_NoSuchSWI1 - & ErrorBlock_NoSuchSWI - & ErrorBlock_UndefinedInstruction - & ErrorBlock_InstructionAbort - & ErrorBlock_DataAbort - & ErrorBlock_AddressException - & ErrorBlock_BranchThrough0 - & ErrorBlock_BadEnvNumber - & ErrorBlock_BadReadSysInfo - & ErrorBlock_BadModuleReason - & ErrorBlock_NoMoreModules - & ErrorBlock_NoMoreIncarnations - & ErrorBlock_PostfixNeeded - & ErrorBlock_IncarnationExists - & ErrorBlock_ChunkNotRM - & ErrorBlock_MHNoRoom - & ErrorBlock_ModulePostfix - & ErrorBlock_NotMod - & ErrorBlock_BadRMHeaderField - & ErrorBlock_CantKill - & ErrorBlock_RMNotFound - & ErrorBlock_IncarnationNotFound - & ErrorBlock_RMNotFoundInROM - & ErrorBlock_ModuleTooOld - & ErrorBlock_BadParameters - & ErrorBlock_ArgRepeated - & ErrorBlock_NaffDevNo - & ErrorBlock_BadDevVecRel - & ErrorBlock_RedirectFail - & ErrorBlock_StackFull - & ErrorBlock_OscliLongLine - & ErrorBlock_NoOscliSpecials - & ErrorBlock_OscliTooHard - & ErrorBlock_BadParmString - & ErrorBlock_CoreNotWriteable - & ErrorBlock_CoreNotReadable - & ErrorBlock_BadCommand - & ErrorBlock_NoSuchSWI2 - & ErrorBlock_TooManyParms - & ErrorBlock_BadKey - & ErrorBlock_BadAddress - & ErrorBlock_OutsideFile - & ErrorBlock_Escape - & ErrorBlock_BadTime - & ErrorBlock_BadMODE - & ErrorBlock_ModeNotAvailable - & ErrorBlock_BadPixelDepth - & ErrorBlock_Sprite_BadDPI - & ErrorBlock_BadMSFlags - & SpriteErr_NoWorkSpace - & SpriteErr_NoRoom - & SpriteErr_DoesntExist - & SpriteErr_NoSprites - & SpriteErr_NotGraphics - & SpriteErr_NotEnoughRoom - & SpriteErr_BadSpriteFile - & SpriteErr_NoRoomToMerge - & SpriteErr_Bad2ndPtr - & SpriteErr_InvalidRowOrCol - & SpriteErr_InvalidHeight - & SpriteErr_InvalidWidth - & SpriteErr_NoRoomToInsert - & SpriteErr_SpriteAlreadyExists - & SpriteErr_InvalidSpriteMode - & SpriteErr_BadReasonCode - & SpriteErr_CantInTeletext - & SpriteErr_InvalidSaveArea - & SpriteErr_SpriteIsCurrentDest - & SpriteErr_NoMaskOrPaletteAllowedInThisDepth - ] - & ErrorBlock_ChDynamNotAllMoved - & ErrorBlock_NaffRelease - & ErrorBlock_BuffOverflow - & ErrorBlock_BadNumb -EndCommonErrorAddresses - - GBLA ECEACount -ECEACount SETA (EndCommonErrorAddresses-CommonErrorAddresses)/4 - ASSERT (EndCommonErrorAddresses <> CommonErrorAddresses) - - ! 0, "Requiring ":CC:(:STR:(ECEACount*256)):CC:" bytes for error cache" - ! 0, "Cached error block pointer at ":CC::STR:CachedErrorBlocks - ! 0, "Cacheing ":CC:(:STR:ECEACount):CC:" error messages" - -; This routine exits with Z clear if it can supply a cached translation; else must set Z -; so that the TranslateError_UseR4 routine continues to function and set R9 to the cache -; block to use for the result (or set R9 to zero to indicate no cacheing for this error) -CheckCommonErrorCache ROUT - Entry "r1-r3" - [ countmsgusage - MOV r4, #0 ; prevents substitutions - | - CMP r4, #1 ; is R4 = 0? If so, clear C for next instruction - SBCS r9, r4, r4 ; R9=0,Z set - if R4 was >0, else R9=-1, Z clear - EXIT EQ - ] - LDR r9, [r4, #KernelMessagesBlock] ; R4 guaranteed zero from above - TEQ r9, #0 - EXIT EQ ; not initialised messages yet! Exit R9=0, Z set - LDR r9, [r4, #CachedErrorBlocks] - TEQ r9, #0 - ; in: R9=cached error blocks memory pointer - BLEQ CommonErrorCacheInit - ; out: R9=0 and EQ on error; else NE and R9 valid (also case if routine wasn't called) - EXIT EQ ; not initialised cache yet - ADR lr, CommonErrorAddresses - MOV r2, #ECEACount - 1 -10 - LDR r1, [lr, r2, LSL #2] - TEQ r1, r0 - BEQ %FT20 - SUBS r2, r2, #1 - BPL %BT10 - ; Set Z if message not found, set R9 zero to mark we don't want to cache this - MOVS r9, #0 - EXIT -20 - [ countmsgusage - ADD r3, r9, #ECEACount*256 - LDR r1, [r3, r2, LSL #2] - ADD r1, r1, #1 - STR r1, [r3, r2, LSL #2] - ] - ; Read the cached error number (0 = we don't have this cached or we have uncached it) - ; Update R9 to point to the actual error buffer at the same time. - LDR r1, [r9, r2, LSL #8]! - ; Set Z if we don't have that error cached yet, clear it and copy the cached - ; block to R0 if we do already have this message. - TEQ r1, #0 - MOVNE r0, r9 - EXIT - -; On entry, R9 points to the error cache memory, or 0 to indicate we don't have it yet. -; If this routine exits Z clear (NE), it MUST have pointed R9 at the sys heap memory -CommonErrorCacheInit ROUT - Entry "r0-r8" - MOVS r2, r9 ; copy R9 to R2 - only claim memory if it was 0 - BNE %FT10 - [ countmsgusage - LDR r3, =ECEACount*260 ; size of block required - | - LDR r3, =ECEACount*256 ; size of block required - ] - BL ClaimSysHeapNode - MOVS r9, #0 ; set Z for STREQ below and for return - EXIT VS -10 - MOV r3, #0 - STREQ r2, [R3, #CachedErrorBlocks] - - GBLA CECLoop -CECLoop SETA 0 - [ countmsgusage - LDR r4, =ECEACount*260 -90 - SUBS r4, r4, #4 - STR r3, [r2, r4] - BNE %BT90 - | - WHILE CECLoop < ECEACount - STR r3, [r2, #CECLoop * 256] -CECLoop SETA CECLoop+1 - WEND - ] - - MOVS r9, r2 ; set up R9; clear Z - EXIT - -; Invoked by the service call handler in the UtilityModule to clear out our cache -; whenever the territory changes or messagetrans says that a messages file was changed. -CacheCommonErrorsReinit - Entry "r9" - MOV r9, #0 - LDR r9, [r9, #CachedErrorBlocks] - TEQ r9, #0 - BLNE CommonErrorCacheInit - EXIT - ] - -;---------------------------------------------------------------------------------------- -; -;WriteS_Translated -;Entry: -; R14 -> Token. -;*NOTE* -; MUST BE TOKEN:DEFAULT -; -;Exit: -; Message printed -; Returns to word after end of token. -; -WriteS_Translated ROUT - [ No26bitCode - Push "r0-r8,LR" - | - Push "r0-r7,LR" - ] - MOV r4,#0 - B Int_WriteS_Translated_UseR4 - -WriteS_Translated_UseR4 - - [ No26bitCode - Push "r0-r8,LR" - | - Push "r0-r7,LR" - ] - -Int_WriteS_Translated_UseR4 - [ No26bitCode - MRS r8,CPSR - MOV r1,LR - | - BIC r1,LR,#ARM_CC_Mask ; r1 -> Token. - ] - MOV r0,#0 - LDR r0,[r0,#KernelMessagesBlock] - CMP r0,#0 ; If no messages file, try the global one. - ADRNE r0,KernelMessagesBlock+4 - MOV r2,#0 ; Use message in place. - MOV r3,#0 - MOV r5,#0 - MOV r6,#0 - MOV r7,#0 ; No arguments. - SWI XMessageTrans_Lookup - BVC %FT01 - - MOV R2,R1 ; MessageTrans not present or token not found. -00 - LDRB r0,[r2],#1 ; Skip to after ":" - CMP r0,#":" - BNE %BT00 - -; Now -; r1 -> terminator -; r2 -> message -; Print the message. - -01 - LDRB r0,[r2],#1 ; Print all characters of message - CMP r0,#" " - BLT %FT02 - CMP r0,#"%" - SWINE XOS_WriteC - BNE %BT01 - - LDRB r0,[r2],#1 ; Found a % - CMP r0,#" " - BLT %FT02 ; Trailing % sign! - CMP r0,#"0" - SWINE XOS_WriteI+"%" - SWINE XOS_WriteC - BNE %BT01 ; Just in case it isn't %0 - - CMP r4,#0 ; r4 = original parameter - BEQ %BT01 - -11 - LDRB R0,[R4],#1 - CMP R0,#" " - SWIGE XOS_WriteC - BGE %BT11 - B %BT01 - ; Now skip to end of token. -02 - [ No26bitCode - LDR r1,[sp,#9*4] ; Get original token pointer - | - LDR r1,[sp,#8*4] ; Get original token pointer - BIC r1,r1,#ARM_CC_Mask ; r1 -> Token. - ] -03 - LDRB r0,[r1],#1 - CMP r0,#32 - BGE %BT03 ; Skip to control character. -04 - CMP r0,#0 ; Print all control characters to terminating 0. - SWINE XOS_WriteC - LDRNEB r0,[r1],#1 - BNE %BT04 - -; r1 now points at byte after end of token. - - ADD r1,r1,#3 ; Round up to next word. - BIC r1,r1,#3 - - [ No26bitCode - STR r1,[sp,#9*4] ; Store back as return address on stack - ORRVS r8,r8,#V_bit - MSR CPSR_f,r8 - - Pull "r0-r8,PC" ;Return. - | - LDR r2,[sp,#8*4] - AND r2,r2,#ARM_CC_Mask ; Just the flags and mode bits. - ORR r1,r1,r2 - ORRVS r1,r1,#V_bit - STR r1,[sp,#8*4] ; Store back as return address on stack - - Pull "r0-r7,PC",,^ ;Return. - ] - -;---------------------------------------------------------------------------------------- -; -;GSWriteS_Translated -;Entry: -; R14 -> Token. -;*NOTE* -; MUST BE TOKEN:DEFAULT -; -;Exit: -; Message printed -; Returns to word after end of token. -; -GSWriteS_Translated ROUT - [ No26bitCode - Push "r0-r8,LR" - | - Push "r0-r7,LR" - ] - MOV r4,#0 - B Int_GSWriteS_Translated_UseR4 - -GSWriteS_Translated_UseR4 - - [ No26bitCode - Push "r0-r8,LR" - | - Push "r0-r7,LR" - ] - -Int_GSWriteS_Translated_UseR4 - [ No26bitCode - MRS r8,CPSR - MOV r1,LR - | - BIC r1,LR,#ARM_CC_Mask ; r1 -> Token. - ] - MOV r0,#0 - LDR r0,[r0,#KernelMessagesBlock] - CMP r0,#0 ; If no messages file, try the global one. - ADRNE r0,KernelMessagesBlock+4 - LDR r2,=GeneralMOSBuffer - MOV r3,#256 - MOV r5,#0 - MOV r6,#0 - MOV r7,#0 ; No arguments. - SWI XMessageTrans_GSLookup - BVC %FT01 - - MOV R2,R1 ; MessageTrans not present or token not found. -00 - LDRB r0,[r2],#1 ; Skip to after ":" - CMP r0,#":" - BNE %BT00 - -; Now -; r1 -> terminator -; r2 -> message -; Print the message using OS_PrettyPrint. - -01 - LDR r0, =GeneralMOSBuffer - MOV r1, #0 - SWI XOS_PrettyPrint - ; Now skip to end of token. -02 - [ No26bitCode - LDR r1,[sp,#9*4] ; Get original token pointer - | - LDR r1,[sp,#8*4] ; Get original token pointer - BIC r1,r1,#ARM_CC_Mask ; r1 -> Token. - ] -03 - LDRB r0,[r1],#1 - CMP r0,#0 - BNE %BT03 ; Skip to 0. - -; r1 now points at byte after end of token. - - ADD r1,r1,#3 ; Round up to next word. - BIC r1,r1,#3 - - [ No26bitCode - STR r1,[sp,#9*4] ; Store back as return address on stack - ORRVS r8,r8,#V_bit - MSR CPSR_f,r8 - - Pull "r0-r8,PC" ;Return. - | - LDR r2,[sp,#8*4] - AND r2,r2,#ARM_CC_Mask ; Just the flags and mode bits. - ORR r1,r1,r2 - ORRVS r1,r1,#V_bit - STR r1,[sp,#8*4] ; Store back as return address on stack - - Pull "r0-r7,PC",,^ ;Return. - ] - -;---------------------------------------------------------------------------------------- -;FindToken -; -;Entry: -; R0 -> Token. -;*NOTE* -; MUST BE TOKEN:DEFAULT -; -;Exit: -; r0 -> Message, or after the : if MessageTrans is dead. -; -; -FindToken ROUT - [ No26bitCode - Push "r0-r8,LR" - MRS r8,CPSR - | - Push "r0-r7,LR" - ] - - MOV r1,r0 - MOV r0,#0 - LDR r0,[r0,#KernelMessagesBlock] - CMP r0,#0 ; If no messages file, try the global one. - ADRNE r0,KernelMessagesBlock+4 - MOV r2,#0 - MOV r3,#0 - MOV r4,#0 - MOV r5,#0 - MOV r6,#0 - MOV r7,#0 ; No arguments. - SWI XMessageTrans_Lookup - BVC %FT01 - - MOV R2,R1 ; MessageTrans not present or token not found. -00 - LDRB r0,[r2],#1 ; Skip to after ":" - CMP r0,#":" - BNE %BT00 -01 - STR r2,[sp] - - [ No26bitCode - MSR CPSR_f,r8 - Pull "r0-r8,PC" - | - Pull "r0-r7,PC",,^ - ] - -;---------------------------------------------------------------------------------------- -;Write0_Translated -; -;Entry: -; R0 -> Token. -;*NOTE* -; MUST BE TOKEN:DEFAULT -; -;Exit: -; Message printed, r0->Message. -; -Write0_Translated ROUT - EntryS "r0,r1" - BL FindToken - MOV R1,R0 -01 - LDRB R0,[R1],#1 - CMP R0,#31 - SWIGT XOS_WriteC - STRVS r0,[SP] - EXIT VS - BGT %BT01 - - EXITS - - END - - - - - diff --git a/s/NewIRQs b/s/NewIRQs deleted file mode 100644 index 2bf8c61b..00000000 --- a/s/NewIRQs +++ /dev/null @@ -1,1537 +0,0 @@ -; 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 => NewIRQs - -; ***************************************************************************** -; -; Main IRQ routine: -; Push workregs,lr -; IRQsema -> TOS -; stack -> IRQsema -; call IRQ1V -; IRQs off -; TOS ->IRQsema -; process callback, pulling workregs,pc at some point -; -; ***************************************************************************** - - ALIGN 32 - -Initial_IRQ_Code ROUT - SUB lr, lr, #4 - Push "r0, lr" - MRS lr, SPSR - Push "r1-r3, r11, r12, lr" -; ** For Pete's sake remember to change the heap manager if you change the above -; ** register list!!!!!!! And the [sp_irq, #4*5] below - - [ :LNOT:No26bitCode - BIC r0, lr, #&1F ; clear out foreground mode bits - ORR r0, r0, #I32_bit + IRQ26_mode ; force IRQ_26 mode and I bit set - MSR CPSR_c, r0 - ] - - MOV r12, #0 - LDR r0, [r12, #IRQsema] - Push r0 - STR sp_irq, [r12, #IRQsema] - MOV lr, pc - LDR pc, [r12, #IRQ1V] - -; IRQ1V called with r0-r3,r11,r12 trashable. r12=0 - -; Stu has a theory that 1N cycle can be saved by the default IRQ1V pointing -; at a location containing a branch to our code; we then do something like -; LDR R0, [R12, #IRQ1V] -; CMP R0, #OurIRQ1V -; BNE somebodysonIRQ1V -; .... fall into default IRQ1V code - - MOV r11, #0 - Pull r0 - STR r0, [r11, #IRQsema] - - [ :LNOT:No26bitCode - MRS r0, CPSR - ORR r0, r0, #&10 - MSR CPSR_c, r0 ; switch back to IRQ32 mode - ] - - LDRB r11, [r11, #CallBack_Flag] - TEQ r11, #0 - Pull "r1-r3, r11, r12, lr", EQ - MSREQ SPSR_cxsf, lr - Pull "r0, pc", EQ, ^ - - TST r11, #CBack_Postpone - LDREQ lr, [sp_irq, #4*5] ; get SPSR off stack - TSTEQ lr, #I32_bit :OR: &0F ; check we came from USR26 or USR32 mode, with IRQs enabled - Pull "r1-r3, r11, r12, lr", NE - MSRNE SPSR_cxsf, lr - Pull "r0, pc", NE, ^ - -; Do a CallBack: asked for, not postponed, and we're returning into USR26/32 mode. - - ASSERT IRQ32_mode :AND: SVC32_mode = IRQ32_mode ; so the following dodgy ops work - - Pull "r1-r3, r11, r12" - MRS r0, CPSR - ORR r0, r0, #SVC32_mode - MSR CPSR_c, r0 - Push "r10-r12" ; push r10-r12 onto the SVC stack - BIC r0, r0, #IRQ32_mode :EOR: SVC32_mode - MSR CPSR_c, r0 - Pull "r10-r12" ; SPSR, R0, LR really - [ No26bitCode :LOR: FixCallBacks - ORR r0, r0, #SVC32_mode - | - BIC r0, r0, #&1F - ORR r0, r0, #SVC26_mode - ] - MSR CPSR_c, r0 - Push r12 ; Save the return address - MOV r14, r10 ; SPSR into R14 - MOV r0, r11 ; restore original R0 - MOV r10, #0 - LDRB r11, [r10, #CallBack_Flag] - [ FixCallBacks - B Do_CallBack_postpone_already_clear - | - B Do_CallBack - ] - - LTORG - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; Default IRQ1V: despatch on interrupting device - -; Now copied to RAM, together with vector entries and device tables - - ^ 0 - [ HAL -IRQDesp_Link # 4 -IRQDesp_R12Val # 4 -IRQDesp_CallAddr # 4 - -IRQDesp_Link_Unshared * 1 ; flag in Link (for _this_ node) - | -IRQDesp_R12Val # 4 -IRQDesp_CallAddr # 4 -IRQDesp_Link # 4 - ] - ASSERT IRQDesp_CallAddr = IRQDesp_R12Val + 4 - - ALIGN 32 - -DefaultIRQ1Vcode ROUT - - [ HAL - Push "r9,lr" - AddressHAL ; modifies r9 -; MOV r11, r14 ; r11 trashable - CallHAL HAL_IRQSource - Pull "r9" - ADR r2, Devices - ADD r1, r0, r0, LSL #1 ; multiply by 3 -; MOV r14, r11 - ADD r11, r2, r1, LSL #2 ; so table contains DevNo * 3 - ; ASSERT IRQDesp_R12Val = 4 - ; LDMIB r1, {r12, pc} -01 MOV lr, pc - LDMIA r11, {r11, r12, pc} - TST r11, #IRQDesp_Link_Unshared - BEQ %BT01 - Pull pc - | - MOV r3, #IOC ; base for IOC and IOMD - LDRB r0, [r3, #IOMD_DMAREQ] - TEQ r0, #0 - ADRNE r1, IrqDMADevnos - LDREQB r0, [r3, #IOCIRQREQB] ; if not DMA then assume IRQB until we know otherwise - ADREQ r1, IrqReqBDevnos - - [ MorrisSupport -;>>>RCM Says should we use separate Morris specific code, cos Morris doesn't support -;>>>RCM all IOMD_DMAREQ bits and non Morris machines don't have IOMD_IRQRQD. -;>>>RCM Look at use of NoInterrupt. - ADREQ r12, DeviceTables ; can't reach these tables with ADR - - TEQEQ r0, #0 - LDREQB r0, [r3, #IOMD_IRQRQD] - ADDEQ r1, r12, #IrqReqDDevnos-DeviceTables - - TEQEQ r0, #0 - LDREQB r0, [r3, #IOMD_IRQRQC] - ADDEQ r1, r12, #IrqReqCDevnos-DeviceTables - ] ; MorrisSupport - - TEQEQ r0, #0 - LDREQB r0, [r3, #IOCIRQREQA] ; not DMA and not IRQB so assume IRQA - ADREQ r1, IrqReqADevnos - - LDRB r0, [r1, r0] ; pick up offset in device despatcher - ADD r1, pc, r0, LSL #2 ; so table contains DevNo * 3 - ASSERT IRQDesp_R12Val = 0 - LDMIA r1, {r12, pc} - ] ; HAL - -; ******* IRQ device handlers entered with r0-r3,r11,r12,r14 trashable ******* -; r0 = device number (if HAL) -; r3 -> IOC (not in HAL world, unless IOMD HAL is helpful) -; r12 = what they asked for -; r14 = return address to MOS IRQ exit sequence - - [ HAL - -DefaultIRQ1Vcode_end - -Devices * DefaultIRQ1Vcode_end + 12 - -NoInterrupt * -1 -MaxInterrupts * 64 - -DevicesEnd * Devices + MaxInterrupts * 12 - - ASSERT DevicesEnd - DefaultIRQ1Vcode <= DefIRQ1Vspace - - | ; HAL - [ MorrisSupport -NoInterrupt * 38 ; Morris has IOMD's extra interrupts plus 16 of its own - | -NoInterrupt * 22 ; IOMD has 6 more interrupts for DMA - ] - -Devices - -; Register A devices -; pbusy handler - & 0 ; R12 value - & IRQ ; call address - & 0 ; link -; ringing handler - & 0 - & IRQ - & 0 -; printer acknowledge - & 0 - & IRQ - & 0 -; vsync handler - & OsbyteVars - & VsyncIRQ - & 0 -; power on reset: this can't happen, but call IRQ2V if it does. - & 0 - & IRQ - & 0 -; timer0 - & OsbyteVars - & TickOne - & 0 -; timer1 - & 0 - & IRQ - & 0 -; FIQ downgrade - & 0 - & IRQ - & 0 - -; register B devices -; PFIQ downgrade - & PFIQasIRQ_Chain - (PodDesp_Link-PodDesp_R12Val) - & PFIQasIRQ_Despatch - & 0 -; sound - & 0 - & IRQ - & 0 -; serial - & 0 - & IRQ - & 0 -; winnie IRQ - & 0 - & IRQ - & 0 -; Disc changed - & 0 - & IRQ - & 0 -; podule IRQ - & PIRQ_Chain - (PodDesp_Link-PodDesp_R12Val) - & PIRQ_Despatch - & 0 -; serial TX (Keyboard serial transmit register empty) - & IOC - [ Keyboard_Type = "A1A500" - & IrqTx - | - & IRQ - ] - & 0 -; serial RX (Keyboard serial receive register full) - & IOC - [ Keyboard_Type = "A1A500" - & IrqRx - | - & IRQ - ] - & 0 - -; IOMD DMA devices -; DMA channel 0 - & 0 - & IRQ - & 0 -; DMA channel 1 - & 0 - & IRQ - & 0 -; DMA channel 2 - & 0 - & IRQ - & 0 -; DMA channel 3 - & 0 - & IRQ - & 0 -; Sound DMA channel 0 - & 0 - & IRQ - & 0 -; Sound DMA channel 1 - & 0 - & IRQ - & 0 - - [ MorrisSupport -; register D devices -; Mouse port Rx full - & IOC - & IRQ - & 0 -; Mouse port Tx empty - & IOC - & IRQ - & 0 -; AtoD (Joystick) - & 0 - & IRQ - & 0 -; Nevent1 - & 0 - & IRQ - & 0 -; Nevent2 - & 0 - & IRQ - & 0 -; The following are just place fillers in case IRQD bits 5 to 7 are ever used. -; NoInterrupt - & 0 - & IRQ - & 0 -; NoInterrupt - & 0 - & IRQ - & 0 -; NoInterrupt - & 0 - & IRQ - & 0 - -; register C devices -; Bit0 - & 0 - & IRQ - & 0 -; Bit1 - & 0 - & IRQ - & 0 -; Bit2 - & 0 - & IRQ - & 0 -; Bit3 - & 0 - & IRQ - & 0 -; Bit4 - & 0 - & IRQ - & 0 -; Bit5 - & 0 - & IRQ - & 0 -; Bit6 - & 0 - & IRQ - & 0 -; Bit7 - & 0 - & IRQ - & 0 - ] - -; Neither A or B is interrupting, which is impossible: just call IRQ2V anyway - & 0 - & IRQ - & 0 - -DevicesEnd - -; Following tables encode the priority of the devices within each register -; -DeviceTables - -; Prioritised IOMD DMA device numbers - -IrqDMAPrio0 * 1:SHL:5 -IrqDMADev0 * IOMD_DMASound1_DevNo - -IrqDMAPrio1 * 1:SHL:4 -IrqDMADev1 * IOMD_DMASound0_DevNo - -IrqDMAPrio2 * 1:SHL:3 -IrqDMADev2 * IOMD_DMAChannel3_DevNo - -IrqDMAPrio3 * 1:SHL:2 -IrqDMADev3 * IOMD_DMAChannel2_DevNo - -IrqDMAPrio4 * 1:SHL:1 -IrqDMADev4 * IOMD_DMAChannel1_DevNo - -IrqDMAPrio5 * 1:SHL:0 -IrqDMADev5 * IOMD_DMAChannel0_DevNo - - - GBLA DTabC -DTabC SETA 1 - -IrqDMADevnos - = NoInterrupt*3 - -; Top 2 bits are always 0 so table need only be 64 bytes - WHILE DTabC <64 - [ (DTabC:AND:IrqDMAPrio5)<>0 - = IrqDMADev5*3 - | - [ (DTabC:AND:IrqDMAPrio4)<>0 - = IrqDMADev4*3 - | - [ (DTabC:AND:IrqDMAPrio3)<>0 - = IrqDMADev3*3 - | - [ (DTabC:AND:IrqDMAPrio2)<>0 - = IrqDMADev2*3 - | - [ (DTabC:AND:IrqDMAPrio1)<>0 - = IrqDMADev1*3 - | - [ (DTabC:AND:IrqDMAPrio0)<>0 - = IrqDMADev0*3 - ] - ] - ] - ] - ] - ] -DTabC SETA DTabC+1 - WEND - -; generic IRQA bits -IrqReqAPrio0 * por_bit -IrqReqADev0 * PowerOn_DevNo - -IrqReqAPrio4 * timer1_bit -IrqReqADev4 * Timer1_DevNo - -IrqReqAPrio5 * vsync_bit -IrqReqADev5 * VSync_DevNo - -IrqReqAPrio6 * timer0_bit -IrqReqADev6 * Timer0_DevNo - -IrqReqAPrio7 * force_bit -IrqReqADev7 * FIQDowngrade_DevNo - -; Machine specific IRQB bits (devices 0-2) - - -IrqReqAPrio1 * 1:SHL:1 ; not used -IrqReqADev1 * 1 - - [ ReassignedIOMDInterrupts - ASSERT IOMDr_PrinterIRQ_DevNo = 2 - -IrqReqAPrio2 * IOMDr_printer_IRQ_bit -IrqReqADev2 * IOMDr_PrinterIRQ_DevNo - -IrqReqAPrio3 * 1:SHL:0 ; not used -IrqReqADev3 * 0 - | - ASSERT IOMD_PrinterIRQ_DevNo = 0 - ASSERT IOMD_FloppyIndex_DevNo = 2 - -IrqReqAPrio2 * IOMD_printer_IRQ_bit -IrqReqADev2 * IOMD_PrinterIRQ_DevNo - -IrqReqAPrio3 * IOMD_floppy_index_bit -IrqReqADev3 * IOMD_FloppyIndex_DevNo - ] - - -DTabC SETA 1 - -IrqReqADevnos - = NoInterrupt*3 - WHILE DTabC <256 - [ (DTabC:AND:IrqReqAPrio7)<>0 - = IrqReqADev7*3 - | - [ (DTabC:AND:IrqReqAPrio6)<>0 - = IrqReqADev6*3 - | - [ (DTabC:AND:IrqReqAPrio5)<>0 - = IrqReqADev5*3 - | - [ (DTabC:AND:IrqReqAPrio4)<>0 - = IrqReqADev4*3 - | - [ (DTabC:AND:IrqReqAPrio3)<>0 - = IrqReqADev3*3 - | - [ (DTabC:AND:IrqReqAPrio2)<>0 - = IrqReqADev2*3 - | - [ (DTabC:AND:IrqReqAPrio1)<>0 - = IrqReqADev1*3 - | - [ (DTabC:AND:IrqReqAPrio0)<>0 - = IrqReqADev0*3 - ] - ] - ] - ] - ] - ] - ] - ] -DTabC SETA DTabC+1 - WEND - - -; generic IRQB bits -IrqReqBPrio2 * podule_FIQ_as_IRQ_bit -IrqReqBDev2 * PFIQasIRQ_DevNo - -IrqReqBPrio3 * serial_Tx_bit -IrqReqBDev3 * SerialTx_DevNo - -IrqReqBPrio4 * serial_Rx_bit -IrqReqBDev4 * SerialRx_DevNo - -IrqReqBPrio5 * podule_IRQ_bit -IrqReqBDev5 * Podule_DevNo - -; Machine specific IRQB bits - - [ ReassignedIOMDInterrupts -IrqReqBPrio0 * IOMDr_MPEGAudio_IRQ_bit -IrqReqBDev0 * IOMDr_MPEGAudio_DevNo - -IrqReqBPrio1 * IOMDr_MPEGVideo_IRQ_bit -IrqReqBDev1 * IOMDr_MPEGVideo_DevNo - -IrqReqBPrio6 * IOMDr_Network_IRQ_bit -IrqReqBDev6 * IOMDr_Network_DevNo - -IrqReqBPrio7 * IOMDr_serial_IRQ_bit -IrqReqBDev7 * IOMDr_Serial_DevNo - | -IrqReqBPrio0 * IOMD_floppy_IRQ_bit -IrqReqBDev0 * DiscChanged_DevNo - -IrqReqBPrio1 * IOMD_HardDisc_IRQ_bit -IrqReqBDev1 * Sound_DevNo - -IrqReqBPrio6 * IOMD_Network_IRQ_bit -IrqReqBDev6 * WinnieIRQ_DevNo - -IrqReqBPrio7 * IOMD_serial_IRQ_bit -IrqReqBDev7 * IOMD_Serial_DevNo - ] - -DTabC SETA 1 - -IrqReqBDevnos - = NoInterrupt*3 - - WHILE DTabC <256 - [ (DTabC:AND:IrqReqBPrio7)<>0 - = IrqReqBDev7*3 - | - [ (DTabC:AND:IrqReqBPrio6)<>0 - = IrqReqBDev6*3 - | - [ (DTabC:AND:IrqReqBPrio5)<>0 - = IrqReqBDev5*3 - | - [ (DTabC:AND:IrqReqBPrio4)<>0 - = IrqReqBDev4*3 - | - [ (DTabC:AND:IrqReqBPrio3)<>0 - = IrqReqBDev3*3 - | - [ (DTabC:AND:IrqReqBPrio2)<>0 - = IrqReqBDev2*3 - | - [ (DTabC:AND:IrqReqBPrio1)<>0 - = IrqReqBDev1*3 - | - [ (DTabC:AND:IrqReqBPrio0)<>0 - = IrqReqBDev0*3 - ] - ] - ] - ] - ] - ] - ] - ] -DTabC SETA DTabC+1 - WEND - - - [ MorrisSupport -; Prioritised IRQD device numbers - -IrqReqDPrio0 * 1:SHL:4 -IrqReqDDev0 * IOMD_Event2_DevNo - -IrqReqDPrio1 * 1:SHL:3 -IrqReqDDev1 * IOMD_Event1_DevNo - -IrqReqDPrio2 * 1:SHL:2 -IrqReqDDev2 * IOMD_AtoD_DevNo - -IrqReqDPrio3 * 1:SHL:1 -IrqReqDDev3 * IOMD_MouseTxEmpty_DevNo - -IrqReqDPrio4 * 1:SHL:0 -IrqReqDDev4 * IOMD_MouseRxFull_DevNo - - -DTabC SETA 1 - -IrqReqDDevnos - = NoInterrupt*3 - -; Top 3 bits are always 0 so table need only be 32 bytes (this will -; need to change if bits 5 to 7 are ever used). - WHILE DTabC <32 - [ (DTabC:AND:IrqReqDPrio4)<>0 - = IrqReqDDev4*3 - | - [ (DTabC:AND:IrqReqDPrio3)<>0 - = IrqReqDDev3*3 - | - [ (DTabC:AND:IrqReqDPrio2)<>0 - = IrqReqDDev2*3 - | - [ (DTabC:AND:IrqReqDPrio1)<>0 - = IrqReqDDev1*3 - | - [ (DTabC:AND:IrqReqDPrio0)<>0 - = IrqReqDDev0*3 - ] - ] - ] - ] - ] -DTabC SETA DTabC+1 - WEND - -; Prioritised IRQC device numbers. We have to handle ALL interrupts -; using specific device numbers as we don't know what the IO pins -; are connected to and the NOIRQ code has to know what bit to clear -; when an unknown interrupt is triggered. - -IrqReqCPrio0 * 1:SHL:0 -IrqReqCDev0 * IOMD_C_Bit0_DevNo - -IrqReqCPrio1 * 1:SHL:1 -IrqReqCDev1 * IOMD_C_Bit1_DevNo - -IrqReqCPrio2 * 1:SHL:2 -IrqReqCDev2 * IOMD_C_Bit2_DevNo - -IrqReqCPrio3 * 1:SHL:3 -IrqReqCDev3 * IOMD_C_Bit3_DevNo - -IrqReqCPrio4 * 1:SHL:4 -IrqReqCDev4 * IOMD_C_Bit4_DevNo - -IrqReqCPrio5 * 1:SHL:5 -IrqReqCDev5 * IOMD_C_Bit5_DevNo - -IrqReqCPrio6 * 1:SHL:6 -IrqReqCDev6 * IOMD_C_Bit6_DevNo - -IrqReqCPrio7 * 1:SHL:7 -IrqReqCDev7 * IOMD_C_Bit7_DevNo - - -DTabC SETA 1 - -IrqReqCDevnos - = NoInterrupt*3 - - WHILE DTabC <256 - [ (DTabC:AND:IrqReqCPrio7)<>0 - = IrqReqCDev7*3 - | - [ (DTabC:AND:IrqReqCPrio6)<>0 - = IrqReqCDev6*3 - | - [ (DTabC:AND:IrqReqCPrio5)<>0 - = IrqReqCDev5*3 - | - [ (DTabC:AND:IrqReqCPrio4)<>0 - = IrqReqCDev4*3 - | - [ (DTabC:AND:IrqReqCPrio3)<>0 - = IrqReqCDev3*3 - | - [ (DTabC:AND:IrqReqCPrio2)<>0 - = IrqReqCDev2*3 - | - [ (DTabC:AND:IrqReqCPrio1)<>0 - = IrqReqCDev1*3 - | - [ (DTabC:AND:IrqReqCPrio0)<>0 - = IrqReqCDev0*3 - ] - ] - ] - ] - ] - ] - ] - ] -DTabC SETA DTabC+1 - WEND - ] - -DefaultIRQ1Vcode_end - - ASSERT DefaultIRQ1Vcode_end - DefaultIRQ1Vcode <= DefIRQ1Vspace - - ] ; :LNOT: HAL - - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -InitialiseIRQ1Vtable - - Push "v1,sb,lr" -; copy IRQ handler: not done with rest of copying -; because soft break needs the info to free any claimed blocks. - - LDR a1, =DefaultIRQ1V - ADRL a2, DefaultIRQ1Vcode - ADRL a3, DefaultIRQ1Vcode_end -CopyDefaultIRQ1V - LDR a4, [a2], #4 - STR a4, [a1], #4 - CMP a2, a3 - BNE CopyDefaultIRQ1V - - [ HAL - AddressHAL - ADD v1, a1, #12 - ADD a3, v1, #MaxInterrupts*12 - MOV a2, #0 - MOV a4, #-1 - LDR ip, =IRQ -FillInDefaultIRQ1VDevices - STMIA a1!, {a2, a4, ip} - ADD a4, a4, #1 - CMP a1, a3 - BNE FillInDefaultIRQ1VDevices - -; Now fill in our basic device handlers. First the timer. - MOV a1, #0 - CallHAL HAL_TimerDevice - LDR a2, =OsbyteVars - LDR a3, =TickOne - ADD a1, a1, a1, LSL #1 - ADD a1, v1, a1, LSL #2 - STMIB a1, {a2, a3} - -; Now the VSync - MOV a1, #0 - CallHAL HAL_VideoFlybackDevice - CMP a1, #-1 - LDRNE a2, =OsbyteVars - LDRNE a3, =VsyncIRQ - ADDNE a1, a1, a1, LSL #1 - ADDNE a1, v1, a1, LSL #2 - STMNEIB a1, {a2, a3} - - [ :LNOT:{FALSE} -; Now Podule bits - MOV a1, #IRQDesp_Link_Unshared - LDR a2, =PIRQ_Chain - (PodDesp_Link-PodDesp_R12Val) - ADR a3, PFIQasIRQ_Despatch - ADD lr, v1, #8*12 - STMIA lr, {a1, a2, a3} - ADR a3, PIRQ_Despatch - ADD lr, v1, #13*12 - STMIA lr, {a1, a2, a3} - ] - -; Now IIC - if any - MOV a1, #0 - CallHAL HAL_IICType - LDR a2, =IICType - STR a1, [a2] - TST a1, #IICFlag_HighLevel - TSTNE a1, #IICFlag_Background - BEQ %FT90 - SUB sp, sp, #12 - MOV a1, sp - MOV a2, #0 - CallHAL HAL_IICDevice -; I think it's safe to call A SWI here... - LDMIA sp!, {r0, r3, r4} - LDR r1, =IICIRQ - MOV r2, sb - SWI XOS_ClaimDeviceVector -90 - ] - Pull "v1,sb,pc" - - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; Specialist despatchers for podules - - ^ 0 -PodDesp_Address # 4 ; address of IRQ status byte -PodDesp_Mask # 4 ; for use on above -PodDesp_R12Val # 4 -PodDesp_CallAddr # 4 ; address to call if (?Address EOR (Mask>>8)) AND Mask <> 0 -PodDesp_Link # 4 ; next node -PodDesp_NodeSize # 0 - - [ HAL:LAND:{FALSE} - ROUT -; In r1 -> top level node -; r12 = sub chain -01 LDR r12, [r12, #PodDesp_Link-PodDesp_R12Val] -SubInterrupt_Despatch - LDMIA r12!, {r2, r3} ; address and mask - CMP r3, #&10000 - LDRLOB r2, [r2] - BHS %FT02 - EOR r2, r2, r3, LSR #8 ; polarity inversion - TST r2, r3 ; check against mask - BEQ %BT01 - LDMIA r12, {r12, pc} -02 - Push "r0,r1,r12,lr" - MOV r0, r3 - MOV r12, r3 - MOV lr, pc - MOV pc, r2 - TEQ r0, #0 - Pull "r0,r1,r12,lr" - BEQ %BT01 - LDMIA r12, {r12, pc} - - -NotSubInterrupt - LDR r1, [r1, #8] ; call next (full) handler - LDMIA r1, {r12, pc} - | - -; In r12 = PFIQasIRQ_Chain - (PodDesp_Link-PodDesp_R12Val) -; or PIRQ_Chain - (PodDesp_Link-PodDesp_R12Val) from despatcher - -PFIQasIRQ_Despatch ROUT -PIRQ_Despatch ; All the same thing now - -01 LDR r12, [r12, #PodDesp_Link-PodDesp_R12Val] - LDMIA r12!, {r1, r2} ; address and mask - -; TMD 09-Jun-89: Don't corrupt r0 - it's needed by the default IRQ2 routine - LDRB r1, [r1] - EOR r1, r1, r2, LSR #8 - ANDS r1, r1, r2 - BEQ %BT01 - LDMIA r12, {r12, pc} - ] - -Default_SubInterruptHandler_Node -Default_PIRQHandler_Node -Default_PFIQasIRQHandler_Node - & .+4 ; address we know has non-zero value! - & -1 ; mask - & 0 ; handler r12 - [ HAL:LAND:{FALSE} - & NotSubInterrupt ; handler code - | - & IRQ ; handler code - ] - & 0 ; null link for naff release checking - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; Claim of device vectors - -; r0 = Device number -; r1 = call address -; r2 = r12 value - [ HAL -; r3 = interrupt location or r3 = 0 or (if r4 > 64K) r3 = routine -; r4 = interrupt mask/polarity r4 = workspace - | -; r0 = PFIQ|PIRQ devno -> r3 = interrupt location -; r4 = interrupt mask - ] - -CDV_Flags * &FF000000 -CDV_Shared * 1:SHL:31 - -DeviceVector_Claim ROUT - - Push "r0-r3, lr" - -01 SWI XOS_ReleaseDeviceVector ; Release until bored - BVC %BT01 - - LDR r0, [sp] - [ HAL - BIC r0, r0, #CDV_Flags - ] - CMP r0, #MaxInterrupts - BHS DV_Fail_NaffDevNo - - [ HAL:LAND:{FALSE} -; TEQ r3, #0 -; BNE SubInterruptClaim - | - CMP r0, #Podule_DevNo - CMPNE r0, #PFIQasIRQ_DevNo - BEQ PoduleChainClaim - ] - - MOV r3, #12 - BL ClaimSysHeapNode - BVS DV_Exit - LDR r11, [sp] - BIC r0, r11, #CDV_Flags - ADD r0, r0, r0, LSL #1 ; *3 - LDR r1, =DefaultIRQ1V-DefaultIRQ1Vcode+Devices - ADD r1, r1, r0, LSL #2 - WritePSRc SVC_mode+I_bit, r10 ; IRQs off for update (on again on SWI exit) - LDMIA r1, {r0, r3, r10} - STMIA r2, {r0, r3, r10} ; copy current head into node - [ HAL - MOV r10, r2 - TST r11, #CDV_Shared - ORREQ r10, r10, #IRQDesp_Link_Unshared - LDR r11, [sp, #4*2] ; r12 value - LDR r12, [sp, #4*1] ; call address - | - LDR r10, [sp, #4*2] ; r12 value - LDR r11, [sp, #4*1] ; call address - MOV r12, r2 - ] - STMIA r1, {r10-r12} ; copy given info into head - - -DV_Exit STRVS r0, [sp] ; Common exit for both claim + release - Pull "r0-r3, lr" - B SLVK_TestV - - -DV_Fail_NaffDevNo - ADR r0, ErrorBlock_NaffDevNo - [ International - BL TranslateError - | - SETV - ] - B DV_Exit - - MakeErrorBlock NaffDevNo - - [ HAL:LAND:{FALSE} -SubInterruptClaim - Push "r5" - ADD r0, r0, r0, LSL #1 ; *3 - LDR r5, =DefaultIRQ1V-DefaultIRQ1Vcode+Devices - ADD r5, r5, r0, LSL #2 - LDR r2, [r5, #IRQDesp_CallAddr] - ADR r3, SubInterrupt_Despatch - TEQ r2, r3 - BEQ AlreadySubbed - ; Need to claim the top-level interrupt. - MOV r3, #12 - BL ClaimSysHeapNode - Pull "r5",VS - BVS DV_Exit - WritePSRc SVC_mode+I_bit, r10 ; IRQs off for update (on again on SWI exit) - LDMIA r5, {r0, r3, r10} - STMIA r2, {r0, r3, r10} ; copy current head into node - ADR r0, Default_SubInterruptHandler_Node - ADR r3, SubInterrupt_Despatch - STR r0, [r5, #IRQDesp_R12Val] - STR r3, [r5, #IRQDesp_CallAddr] - STR r2, [r5, #IRQDesp_Link] - -AlreadySubbed - ; r1 -> top level interrupt entry - MOV r3, #PodDesp_NodeSize - BL ClaimSysHeapNode - Pull "r5",VS - BVS DV_Exit - MOV r10, r2 - ADD r1, sp, #8 - LDMFD r1, {r1-r3} - STR r1, [r10, #PodDesp_CallAddr] - STR r2, [r10, #PodDesp_R12Val] - STR r3, [r10, #PodDesp_Address] - STR r4, [r10, #PodDesp_Mask] - WritePSRc SVC_mode+I_bit, r2 ; IRQs off for update - LDR r0, [r5, #IRQDesp_R12Val] - STR r0, [r10, #PodDesp_Link] - STR r10, [r5, #IRQDesp_R12Val] - Pull "r5" - B DV_Exit - | -PoduleChainClaim - MOV r3, #PodDesp_NodeSize - BL ClaimSysHeapNode - BVS DV_Exit - MOV r10, r2 - LDMFD sp, {r0-r3} - STR r1, [r10, #PodDesp_CallAddr] - STR r2, [r10, #PodDesp_R12Val] - STR r3, [r10, #PodDesp_Address] - STR r4, [r10, #PodDesp_Mask] - CMP r0, #Podule_DevNo - LDREQ r0, =PIRQ_Chain - LDRNE r0, =PFIQasIRQ_Chain - WritePSRc SVC_mode+I_bit, r1 ; IRQs off for update - LDR r1, [r0] - STR r1, [r10, #PodDesp_Link] - STR r10, [r0] - B DV_Exit - ] - -; ............................................................................. -; Release of device vectors - -; r0 = Device number -; r1 = call address -; r2 = r12 value -; r0 = PFIQ|PIRQ devno -> r3 = interrupt location (LDRB always used) -; r4 = interrupt mask - -DeviceVector_Release ROUT - - Push "r0-r3, lr" ; Ensure same regset as above - [ HAL - BIC r0, r0, #CDV_Flags - ] - CMP r0, #MaxInterrupts - BHS DV_Fail_NaffDevNo - - WritePSRc SVC_mode + I_bit, r12 ; IRQs off while holding context - [ :LNOT:(HAL:LAND:{FALSE}) - CMP r0, #Podule_DevNo - CMPNE r0, #PFIQasIRQ_DevNo - BEQ PoduleChainRelease - ] - - ADD r0, r0, r0, LSL #1 ; *3 - LDR r12, =DefaultIRQ1V-DefaultIRQ1Vcode+Devices - ADD r12, r12, r0, LSL #2 ; address of node - MOV r11, #-1 ; "fudge" predecessor node - - [ HAL -; TEQ r3, #0 -; BNE SubInterruptRelease - ] - - [ HAL -01 LDMIB r12, {r3, r10} - | -01 LDMIA r12, {r3, r10} - ] - CMP r3, r2 - CMPEQ r10, r1 - BEQ %FT02 ; found it - MOV r11, r12 - LDR r12, [r12, #IRQDesp_Link] - [ HAL - BICS r12, r12, #IRQDesp_Link_Unshared - | - CMP r12, #0 - ] - BNE %BT01 - -11 ADR r0, ErrorBlock_BadDevVecRel - [ International - BL TranslateError - | - SETV - ] - B DV_Exit - - MakeErrorBlock BadDevVecRel - - -02 CMP r11, #-1 - BEQ %FT03 - MOV r2, r12 - LDR r12, [r2, #IRQDesp_Link] - [ HAL - LDR r14, [r11, #IRQDesp_Link] ; preserve r11's "unshared" flag - BIC r12, r12, #IRQDesp_Link_Unshared - AND r14, r14, #IRQDesp_Link_Unshared - ORR r12, r12, r14 - ] - STR r12, [r11, #IRQDesp_Link] ; node delinked - B %FT04 - -03 LDR r2, [r12, #IRQDesp_Link]; freeable = nextnode - LDMIA r2, {r0, r1, r3} ; copy next node into head posn - STMIA r12, {r0, r1, r3} - -04 - BL FreeSysHeapNode ; free block - B DV_Exit - - - [ HAL:LAND:{FALSE} -SubInterruptRelease - ADR r10, SubInterrupt_Despatch -10 LDR r0, [r12, #IRQDesp_CallAddr] - TEQ r0, r10 - BEQ %FT15 - -13 MOV r11, r12 - LDR r12, [r12, #IRQDesp_Link] - TEQ r12, #0 - BEQ %BT11 - B %BT10 - -15 SUB r0, r12, #PodDesp_Link -17 LDR r14, [r0, #PodDesp_Link] - TEQ r14, #0 - BEQ %BT13 - - LDR r10, [r14, #PodDesp_Address] - CMP r10, r3 - LDREQ r10, [r14, #PodDesp_Mask] - CMPEQ r10, r4 - LDREQ r10, [r14, #PodDesp_CallAddr] - CMPEQ r10, r1 - LDREQ r10, [r14, #PodDesp_R12Val] - CMPEQ r10, r2 - MOVNE r0, r14 - BNE %BT17 - - LDR r10, [r14, #PodDesp_Link] - STR r10, [r0, #PodDesp_Link]! - - LDR r0, [r12, #IRQDesp_R12Val] - MOV r2, r14 - ADR r14, Default_SubInterruptHandler_Node - TEQ r0, r14 ; last sub-interrupt gone? - BNE %BT04 - - BL FreeSysHeapNode ; free sub-interrupt - BVS DV_Exit - B %BT02 ; then go back to delink top level - | -PoduleChainRelease - CMP r0, #Podule_DevNo - LDREQ r0, =PIRQ_Chain-PodDesp_Link - LDRNE r0, =PFIQasIRQ_Chain-PodDesp_Link - -10 LDR r12, [r0, #PodDesp_Link] - CMP r12, #0 - BEQ %BT11 - LDR r11, [r12, #PodDesp_Address] - CMP r11, r3 - LDREQ r11, [r12, #PodDesp_Mask] - CMPEQ r11, r4 - LDREQ r11, [r12, #PodDesp_CallAddr] - CMPEQ r11, r1 - LDREQ r11, [r12, #PodDesp_R12Val] - CMPEQ r11, r2 - MOVNE r0, r12 - BNE %BT10 - - LDR r11, [r12, #PodDesp_Link] - STR r11, [r0, #PodDesp_Link] - MOV r2, r12 - B %BT04 - ] - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; Default device owner for IRQ not recognised by system: pass to IRQ2V - -IRQ ROUT - - Push "r10, lr" - [ False - ASSERT VIDC_Type <> "VIDC20" - MOV r14, #11 - MUL r14, r0, r14 - MOV r14, r14, LSR #5 - ADR r10, irq_vtable - LDR r14, [r10, r14, LSL #2] - MOV r10, #VIDC - STR r14, [r10] - ] - MOV r10, #IrqV - BL CallVector - - [ HAL - Pull "r10, lr, pc" ; new-style CDV - pull return address - | - Pull "r10, pc" ; return: someone will always claim it. - ] - - [ False -irq_vtable - DCD &40000000 + &444 - DCD &40000000 + &008 - DCD &40000000 + &080 - DCD &40000000 + &088 - - DCD &40000000 + &800 - DCD &40000000 + &808 - DCD &40000000 + &880 - DCD &40000000 + &FA8 - - DCD &40000000 + &8AF - DCD &40000000 + &00F - DCD &40000000 + &0F0 - DCD &40000000 + &0FF - - DCD &40000000 + &F00 - DCD &40000000 + &F0F - DCD &40000000 + &FF0 - DCD &40000000 + &FFF - ] - -; ***************************************************************************** -; Default IRQ2V: - [ HAL -; r0 must still have devno in it -; r12 is 0 (from vector) - | -; r0 must still have devno*3 in it -; r12 is 0 (from vector) - ] - -; Clear mask, clear IRQ as appropriate/possible - -; NB. a cheap way of dividing by ~3 is *11,/32: accurate for 0..31 result ... - -NOIRQ ROUT - - [ False - ASSERT VIDC_Type <> "VIDC20" - MOV r14, #11 - MUL r14, r0, r14 - MOV r14, r14, LSR #5 - ADR r10, irq_vtable - LDR r14, [r10, r14, LSL #2] - MOV r10, #VIDC - STR r14, [r10] - ] - [ HAL - TEQ r0, #0 - Pull pc, MI - MOV r11, r9 - AddressHAL - CallHAL HAL_IRQDisable - MOV r9, r11 - | -01 SUBS r0, r0, #3 - ADDGE r12, r12, #1 - BGT %BT01 ; r12 := r0 DIV 3 - - CMP R12, #8 - MOVLO R0, #IOCIRQMSKA - BLO %FT03 - - CMP R12, #16 - SUBLO R12, R12, #8 - MOVLO R0, #IOCIRQMSKB - BLO %FT03 - - CMP R12, #IOMD_MouseRxFull_DevNo - SUBLO R12, R12, #IOMD_DMAChannel0_DevNo - MOVLO R0, #IOMD_DMAMSK - BLO %FT03 - - [ MorrisSupport - CMP R12, #IOMD_C_Bit0_DevNo - SUBLO R12, R12, #IOMD_MouseRxFull_DevNo ;reduce to bit number 0..7 - MOVLO R0, #IOMD_IRQMSKD ; in IRQ D interrupt register - - SUBHS R12, R12, #IOMD_C_Bit0_DevNo - MOVHS R0, #IOMD_IRQMSKC - ] - -03 - ADD r0, r0, #IOC - MOV r1, #1 - MOV r1, r1, LSL r12 ; bit to clear - - MRS lr, CPSR - BIC r12, lr, #&0F - ORR r12, r12, #I32_bit+F32_bit+IRQ_mode - MSR CPSR_c, r12 - LDRB r12, [r0] ; FIQs off for updating IOCIRQMSKA - BIC r12, r12, r1 - STRB r12, [r0] ; relevant IRQ disabled - MSR CPSR_c, lr ; absolute minimum FIQ disable period - - STRB r1, [r0, #IOCIRQCLRA-IOCIRQMSKA] ; Clear IRQ - ] - Pull pc ; claim vector - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; The following bits have been appropriated from source.pmf.oseven to make -; sure Tim's old code doesn't overwrite us when he gets back! - -; SWI OS_GenerateEvent: call event vector if enabled - -GenEvent ROUT - - Push lr - WritePSRc SVC_mode+I_bit, lr ; Disable IRQs. MUST call these ones - BL OSEVEN ; in SVC mode as people expect it - Pull lr - B SLVK - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; Subroutine call version - -; In r0 = event type -; r1,r2 parameters - -; Out C=0 => event was enabled, or was >= 32 anyway -; C=1 => event was disabled, so vector not called - -OSEVEN ROUT - - Push lr - - CMP r0, #31 ; Events >= 32 are ALWAYS raised. SKS - ; flags are HI if so, ie. NE - LDRLSB r14, [r0, #OsbyteVars + :INDEX: EventSemaphores] - ; get semaphore for this event 0..31 - CMPLS r14, #0 ; non-zero => enabled - Pull pc, EQ ; if disabled, exit with C=1 - - Push "r0-r3, r10-r12" ; r3 excessive ??? - MOV r10, #EventV ; call event vector - BL CallVector - CLC ; indicate event enabled - Pull "r0-r3, r10-r12, pc" - -; ...................... default owner of EventV .............................. -; Call Event handler - -; In r12 = EvtHan_ws - -DefEvent ROUT - - MOV lr, pc ; link with all the bits - LDMIA r12, {r12, pc} ; call EventHandler, returns to ... - - TEQ r12, #1 - Pull pc,NE - - LDRB r14, [r12, #CallBack_Flag-1] ; IRQs are still disabled - ORR r14, r14, #CBack_OldStyle - STRB r14, [r12, #CallBack_Flag-1] - Pull pc ; claim EventV - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; Process timer zero IRQ device (100Hz clock) -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - ALIGN 32 - -TickOne ROUT - - [ HAL - ; Don't push r14 - we're using new interface, and claim the vector - Push "r9,r12" - AddressHAL - CallHAL HAL_IRQClear - Pull "r9,r12" - | - Push r14 - - MOV R0, #timer0_bit - STRB R0, [R3, #IOCIRQCLRA] ; clear timer 0 interrupt - ] - - MOV R1, #0 - LDR R0, [R1, #MetroGnome] - ADD R0, R0, #1 - STR R0, [R1, #MetroGnome] - - LDRB R0, CentiCounter ; Counter for VDU CTRL timing - SUBS R0, R0, #1 - STRCSB R0, CentiCounter ; decrement if not zero - - LDR R0, IntervalTimer +0 - ADDS R0, R0, #1 ; Increment the low 4 bytes - STR R0, IntervalTimer +0 - - LDREQB R0, IntervalTimer +4 - ADDEQ R0, R0, #1 ; and carry into 5th byte if necessary - STREQB R0, IntervalTimer +4 - - Push "R4,R12" ; R0-R3 already pushed - - TEQEQ R0, #&100 ; has interval timer crossed zero ? - MOVEQ R0, #Event_IntervalTimer ; Event ITCZ - BLEQ OSEVEN - - BL CentiSecondTick ; Notify keyboard of a centisecond - - Pull "R4,R12" - - LDR R0, RealTime +0 ; Increment 5-byte real time - ADDS R0, R0, #1 - STR R0, RealTime +0 - LDRCSB R0, RealTime +4 - ADDCS R0, R0, #1 ; Won't wrap until 2248 and then it - STRCSB R0, RealTime +4 ; all falls over anyway - - LDRB R0, TimerState ; get switch state - TEQ R0, #5 ; toggles between 5 and 10 - - LDREQ R1, TimerAlpha +0 ; either load from one - LDREQB R2, TimerAlpha +4 - - LDRNE R1, TimerBeta +0 ; or the other - LDRNEB R2, TimerBeta +4 - - ADREQ R3, TimerBeta +0 ; and point to t'other - ADRNE R3, TimerAlpha +0 - - ADDS R1, R1, #1 ; increment - ADC R2, R2, #0 ; with carry - - STR R1, [R3] ; and store back - STRB R2, [R3, #4] - - EOR R0, R0, #&0F ; 5 <-> 10 - STRB R0, TimerState - - Push R10 - - [ TickIrqReenter - MOV R10, #TickerV ; call 100Hz vector - BL CallVector ; IRQ's still disabled - - BL ProcessTickEventChain ; Re-enables IRQs - | - BL ProcessTickEventChain - - MOV R10, #TickerV ; call 100Hz vector - BL CallVector - ] - Pull "R10,PC" - -; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; Process VSync IRQ device -; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - ALIGN 32 - -VsyncIRQ ROUT - - [ HAL - ; Don't push r14 - we're using new interface, and claim the vector - Push "r9,r12" - AddressHAL - CallHAL HAL_IRQClear - Pull "r9,r12" - | - Push r14 - - MOV R0, #vsync_bit - STRB R0, [R3, #IOCIRQCLRA] ; Clear the vsync interrupt - ] - -VsyncIRQ_ExtEntry - LDRB R0, CFStime ; decrement 'CFS' timer ! - SUB R0, R0, #1 - STRB R0, CFStime - - VDWS WsPtr ; Do our stuff before issuing VSYNC event - BL VsyncCall - BYTEWS WsPtr - - MOV R0, #Event_VSync ; VSYNC event number - BL OSEVEN - - LDRB R1, FlashCount - SUBS R1, R1, #1 - Pull PC, CC ; was zero, so frozen - STRNEB R1, FlashCount ; else if now non-zero, store it back - Pull PC, NE ; not time to flash yet - - LDRB R1, FlashState ; Get the state and - EORS R1, R1, #1 ; flip to the other one (setting flags) - STRB R1, FlashState - - LDREQB R2, SpacPeriod ; get appropriate new period - LDRNEB R2, MarkPeriod - STRB R2, FlashCount ; and put into counter - - VDWS WsPtr - Push R4 - BEQ dothesecondflash - -dothefirstflash - BL DoFirstFlash - Pull "R4, PC" - -dothesecondflash - BL DoSecondFlash - Pull "R4, PC" - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - END diff --git a/s/NewReset b/s/NewReset deleted file mode 100644 index 859f647f..00000000 --- a/s/NewReset +++ /dev/null @@ -1,2337 +0,0 @@ -; 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 - -; DuffEntry is the address of "Nowhere" -; - there should never be any page actually mapped to this address (L2PT entry always 0) -; - a page that is not mapped in should always have this special address in its CAM entry, -; ie. should only be one Nowhere -; - [ HAL32 -DuffEntry * &FAFF8000 - | -DuffEntry * &01F08000 - ] - -Nowhere * DuffEntry ; synonym - - -SoftReset * 0 ; Reset types -PowerOnReset * 1 -ControlReset * 2 - -; CMOS RAM resetting stuff: -CMOSLimit * &F0 - -; Keyboard flags - ^ 1 - [ HAL -KbdScanActive # 1 - # 2 -KbdFlags # 4 - -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 - | -CTRL_Down_Flag # 1 -SHIFT_Down_Flag # 1 -KB_There_Flag # 1 - -R_Down_Flag # 1 ; note that these 4 form one word!! -T_Down_Flag # 1 -Del_Down_Flag # 1 -Copy_Down_Flag # 1 - -KeyDataPtr # 4 - -Port2Present # 1 ; note that these 4 form one word!! -Port3Present # 1 -KeyState # 1 -KeyMSB # 1 - ] - -; On ARM600, InitIRQWs is in zero page - check it's big enough - - ASSERT @ <= ?InitIRQWs - - -; AddCamEntries -; -; in: r0 -> appropriate part of CAM map -; r1 = ap (+ CB bits in new world) -; r2 = log address -; r7 = amount of cam map to do -; r8 = PageSize -; -; out: r0, r3-r12 preserved -; r1 corrupted -; r2 updated by relevant amount - -AddCamEntries ROUT - Push "r0, lr" - MOV lr, r1 ; access privs (PPL) - MOV r1, r7 -01 - STMIA r0!, {r2, lr} ; store logaddr, PPL - ADD r2, r2, r8 ; increment address by 1 page - SUBS r1, r1, #8 ; decrement count of how much to do - BNE %BT01 - Pull "r0, pc" - -; 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" - MOV r1, #0 - 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 - -FudgeConfigureRMA - Push lr - B ConfigureRMA - -ReadCMOSAndConfigure ROUT -; R0 = index into CMOS RAM of byte with size in -; R1 = place to save amount moved -; R2 = CAM entry number to start at: updated -; R3 = LogRam Address to move memory to -; r11 PPL -; Check for memory left, move as much as poss - Push lr - BL Read ; CMOS byte -> R0 - - AND R0, R0, #127 ; mask to same bitfield as status -ConfigureRMA - MOV R10, #0 - LDR R10, [R10, #Page_Size] - MUL R0, R10, R0 ; get size in bytes - MOV R5, #0 ; amount moved - CMP R0, #0 - BEQ NoMoreMemory - - [ GetPagesFromFreePool - -; r0 = amount of memory to move -; r1 = address to store size in -; (r2 = page number to start at, ignored in our method) -; r3 = address of where to put memory -; r10 = page size -; r11 = ap + CB - - LDR r4, =FreePoolDANode - MOV r6, r11 ; r6 = ap + CB - LDR r7, [r4, #DANode_Base] - LDR r8, [r4, #DANode_Size] - ADD r7, r7, r8 ; r7 -> end of free pool +1 -10 - CMP r8, r10 ; if no free memory left - BCC %FT20 ; then tidy up - SUB r7, r7, r10 ; move free pool pointer backwards - Push "r0, r1" - MOV r0, r7 - MOV r1, r3 - BL MovePageAtR0ToR1WithAccessR6 - Pull "r0, r1" - ADD r3, r3, r10 ; advance "to" pointer - SUB r8, r8, r10 ; one less page of free memory - ADD r5, r5, r10 ; one more page done - SUBS r0, r0, r10 - BNE %BT10 -20 - STR r8, [r4, #DANode_Size] - | - LDR R8, [R5, #RAMLIMIT] - -; now set R6 = first entry not to use -; R7 = end of gap " " " -; R8 = last entry we can use - - MOV r7, #0 - LDR r6, [r7, #VideoSize] ; find out how many pages in video area - MOV r6, r6, LSR #12 ; = page number of start of skipped bit - ASSERT SoftCamMapSize = L2PTSize +4 - MOV r7, #L2PTSize - LDMIA r7, {r7, lr} ; r7 = L2PTSize, lr = SoftCamMapSize - ADD r7, r7, lr ; add sizes together - ADD r7, r7, #StaticPagesSize + UndStackSize ; + number of bytes used for other static bits - ADD r7, r6, r7, LSR #12 ; r7 = page number after static bit - MOV r8, r8, LSR #12 ; make r8 into highest page number+1 - -CAMZapLoop - CMP R2, R6 ; if at gap, skip - MOVEQ R2, R7 - CMP R2, R8 ; if no more memory, give in - BEQ NoMoreMemory - ADD R5, R5, R10 - Push "R0, R1, R6" - BL BangCamUpdate - Pull "R0, R1, R6" - ADD R2, R2, #1 - ADD R3, R3, R10 - SUBS R0, R0, R10 - BGT CAMZapLoop - ] -NoMoreMemory - STR R5, [R1] - Pull "PC" - -; MassageScreenSize - called from ReadCMOSAndConfigure (above) and also from -; ReadSysInfo - -MassageScreenSize ROUT - Push lr - MOV lr, #0 - LDR lr, [lr, #VRAMFlags] - TST lr, #2 - MOVNE lr, #0 - LDRNE r0, [lr, #VideoSize] - Pull pc, NE - - CMP r0, #0 - BNE CmosScreenWillDo - LDR r0, [r0, #RAMLIMIT] - CMP r0, #512*1024 - 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 - - [ HAL - ! 0, "*** DUMMY CONT_Break, soft breaks/resets will not work yet with HAL" -CONT_Break - AddressHAL - MOV a1, #1 - CallHAL HAL_Reset - ] - - - [ :LNOT: HAL - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; Data tables: VIDC := mode 0, all palette black - -VIDCTAB - -; Program Control Register first, to clear power-down bit -; Now depending upon the VIDCClockSource flag, re-program the clock source. - [ VIDCClockSource = "VCO" - [ VCOstartfix - & &E0000404 ; CR: FIFO load 16 words, 1 bpp, ck/2, vclk (allow for doubled VCO freq) - | - & &E0000400 ; CR: FIFO load 16 words, 1 bpp, ck/1, vclk - ] - ] - [ VIDCClockSource = "HCLK" - & &E0000401 ; CR: FIFO load 16 words, 1 bpp, ck/1, hclk - ] - [ VIDCClockSource = "RCLK" - & &E0000406 ; CR: FIFO load 16 words, 1 bpp, ck/2, rclk - ] - -; Don't bother programming all 256 palette entries, we'll be here all night -; Since we're setting up a 1 bit-per-pixel mode, just do colours 0 and 1 - - & &10000000 ; Palette address register = 0 - & &00000000 ; Colour 0 = black - & &00000000 ; Colour 1 = black - & &40000000 ; Border colour = black - & &50000000 ; Pointer colour 1 = black - & &60000000 ; Pointer colour 2 = black - & &70000000 ; Pointer colour 3 = black - -; Get a stable display up so we get stable signals - - & &800003F8 ; HCR = 76 + 88 + 96 + 640 + 96 + 28 - & &81000044 ; HSWR = 76 - & &82000098 ; HBSR = 76 + 88 - & &830000F2 ; HDSR = 76 + 88 + 96 - & &84000372 ; HDER = 76 + 88 + 96 + 640 - & &850003D8 ; HBER = 76 + 88 + 96 + 640 + 96 - & &860000F3 ; HCSR = HDSR - - & &90000137 ; VCR = 3 + 19 + 16 + 256 + 16 + 2 - & &91000002 ; VSWR = 3 - & &92000015 ; VBSR = 3 + 19 - & &93000025 ; VDSR = 3 + 19 + 16 - & &94000125 ; VDER = 3 + 19 + 16 + 256 - & &95000135 ; VBER = 3 + 19 + 16 + 256 + 16 - & &96000025 ; VCSR = VDSR - & &97000025 ; VCER = VDSR - - & &B1000001 ; SCR: sound disabled (+use 24MHz clock) - - & &C00F1003 ; EREG = comp sync, DACs on, ereg output ext lut - [ VCOstartfix - & &D0000302 ; FSYNREG, clk = (3+1)/(2+1) * 24MHz = 32MHz (higher frequency as part of fix) - | - & &D0000305 ; FSYNREG, clk = (3+1)/(5+1) * 24MHz = 16MHz - ] - & &F0013000 ; DCR: bus D[31:0], Hdisc ;RCM 29/9/94: changed from &F0012000 at PSwindells request - & &FFFFFFFF ; That's the lot - - -VIDCPhys * &03400000 ; used to address VIDC when MMU is off - - -; Entered here after RESET (or BREAK) - -; This code must be capable of being executed at a non-ROM address and with the MMU off, -; and running in 32-bit mode up until the call to MemSize. - -CONT_Break - MOV r1, #1 ; parameter passed to InitMEMC, to indicate Break not Reset - B Continue - -CONT ROUT - MOV r1, #0 ; parameter passed to InitMEMC, to indicate Reset not Break -Continue - -; First bang MEMC to ensure safety - - BL InitMEMC ; initialise MEMC CR, and turn off MMU if it's on - -; VInit etc set on ze mode change: no DMA going yet so don't set owt. - - MOV R1, #VIDCPhys ; Must ALWAYS initialise VIDC on reset or else - ADR R2, VIDCTAB ; we may get vsync interrupts that stiff us -10 LDR R0, [R2], #4 ; permanently as VIDC is in an undefined state - CMP R0, #-1 ; so have mode 0 with all black palette - STRNE R0, [R1] - BNE %BT10 - -; Now bang IOC (disable all but keyboard interrupts) - - MOV R1, #IOC - MOV R0, #&FF ; all inputs - STRB R0, [R1, #IOCControl] ; in case called by Tim - - MOV R0, #0 - STRB R0, [R1, #IOCIRQMSKA] ; kein interrupts - STRB R0, [R1, #IOCFIQMSK] ; disable FIQs - STRB R0, [R1, #IOMD_DMAMSK] ; disable DMA interrupts, too - STRB R0, [R1, #IOMD_IRQMSKC] ; and the rest... - STRB R0, [R1, #IOMD_IRQMSKD] - - [ Keyboard_Type = "A1A500" :LOR: Keyboard_Type = "PC" - MOV R0, #KARTRxBit ; used for Archi keyboard or IOMD PC keyboard - ] - STRB R0, [R1, #IOCIRQMSKB] ; allow communication with kbd, when I_bit gets cleared - -; now bits to allow CMOS read/write : need timer - - LDR R0, =20000-1 ; R0 = Timer delay (units of 0.5 microsecond) - ; 20000*0.5E-6 = 0.01 Seconds (100Hz ticker) - ; TMD 21-May-93: "-1" correction applied - - STRB R0, [R1, #Timer0LL] ; Set up the delay - MOV R0, R0, LSR #8 - STRB R0, [R1, #Timer0LH] - STRB R0, [R1, #Timer0GO] ; and start the ticks - - MOV R0, #timer0_bit - STRB R0, [R1, #IOCIRQCLRA] ; Clear pending t0 interrupt j.i.c. - - [ VCOstartfix - ;2nd part of fix for VCO failing to start on A7000 (esp. 7500FE) - forcing PCOMP high for about 3 ms - LDRB R0, [R1,#IOMD_ID0] - CMP R0, #&E7 - LDREQB R0, [R1,#IOMD_ID1] - CMPEQ R0, #&D4 - BEQ vcofix_notMorris ; risky to force PCOMP on Risc PC - MOV R0, #VIDCPhys - LDR R2, =&D0000342 ; VIDC20 FSYNREG, as in VIDCTAB but with force PCOMP high - STR R2, [R0] - MOV R0, #3072*2 ; time delay of about 3 ms (0.5 us units) - STRB R0, [R1, #Timer0LR] ; copy counter into output latch - LDRB R2, [R1, #Timer0CL] ; R2 := low output latch -vcofix_waitloop - STRB R0, [R1, #Timer0LR] ; copy counter into output latch - LDRB R3, [R1, #Timer0CL] ; R3 := low output latch - TEQ R3, R2 ; unchanged ? - BEQ vcofix_waitloop ; then loop - MOV R2, R3 ; copy anyway - SUBS R0, R0, #1 ; decrement count - BNE vcofix_waitloop ; loop if not finished - MOV R0, #VIDCPhys - LDR R2, =&D0000302 ; VIDC20 FSYNREG, as in VIDCTAB (PCOMP low again) - STR R2, [R0] -vcofix_notMorris - ] - -; now size memory - - BL MemSize ; out: r0 = page size, r1 = memory size, r2 = MEMC CR value, r3-r14 corrupt - -MemSized - MOV R8, R0 ; R8 = page size in bytes - MOV R13, R1 ; R13 is now the RAM size - MOV R9, R2 ; need this to set soft copy right - - [ EmulatorSupport - ARM_on_emulator R7 - MOVEQ R7,#&80 - ORREQ R7,R7,#&3E00 ; r7 := &3E80 = 16000 (standard Risc PC value) - BLNE TimeCPU ; r7 := CPU speed in kHz/MEMC1a flag - | - BL TimeCPU ; r7 := CPU speed in kHz/MEMC1a flag - ] - -; the fixed areas give us : IRQ stack (in cursor), SVC stack (in sysheap base) -; and bottom block makes most sense done here - -; now keyboard initialisation: initialise baud rate, send dummy, read dummy - - MOV R0, #InitKbdWs - MOV R1, #0 - STRB R1, [R0, #CTRL_Down_Flag] ; clear CTRL down flag, R down flag - STRB R1, [R0, #SHIFT_Down_Flag] - STRB R1, [R0, #KB_There_Flag] - STR R1, [R0, #R_Down_Flag] ; all CMOS reset flags - STR R1, [R0, #KeyDataPtr] - STR R1, [R0, #Port2Present] ; all KbdRes vars - - B SetUpKbd ; No stack yet so branch and branch back. -SetUpKbdReturn - - -; set up reset interrupt handler (reads, discards keys, setting flags if CTRL or R) -; NB on ARM600 we need to go into 32-bit mode, so we can safely overwrite vectors - - MRS r0, CPSR ; switch into IRQ32, still IRQs disabled - BIC r0, r0, #&1F - ORR r1, r0, #IRQ32_mode - MSR CPSR_c, r1 - - LDR sp_irq, =IRQSTK ; set up sp_irq - - ADRL R2, MOSROMVecs ; pick up from table - LDR R2, [R2, #&18] ; this gets overwritten while active, - MOV R3, #0 - STR R2, [R3, #&18] ; but hopefully by the same value! - - ADDR R2, IRQ_Test_CTRL_or_R_Pressed ; (could use ADRL, but ADDR macro is nicer) - STR R2, [R3, #InitIRQHandler] ; instruction is now a LDR PC,InitKbdHandler - - ORR r0, r0, #SVC32_mode ; switch into SVC32 - - [ StrongARM - ;for StrongARM, we need to do an IMB type thing for modifying code in vector area - ARM_read_ID r1 - AND r1,r1,#&F000 - CMP r1,#&A000 - BNE vectorpoke_notSA_1 - MOV r1,#0 ;we clean one cache entry, 0..1F, = vector area - [ SAcleanflushbroken - ARMA_clean_DCentry r1 - ARMA_flush_DCentry r1 - | - ARMA_cleanflush_DCentry r1 - ] - ARMA_drain_WB - ARMA_flush_IC -vectorpoke_notSA_1 - ] - - BIC r0, r0, #I32_bit ; and enable IRQs - MSR CPSR_c, r0 - - ; in SVC32 from now until we've finished poking around with vectors - - - - [ :LNOT: AlwaysClearRAM - -; IF por OR FX200 bit set THEN clear memory - MOV R0, #IOC - LDRB R1, [R0, #IOCIRQSTAA] - ANDS R1, R1, #por_bit - BNE %FT20 - - LDR R0, =OsbyteVars + :INDEX: ESCBREAK - LDRB R1, [R0] - CMP R1, #2 ; unlike popular rumour, bit 1 ain't - CMPNE R1, #3 ; a flag - BNE %FT30 -20 - ] - BL ClearPhysRAM -30 - MOV r0, #0 - STR r9, [r0, #MEMC_CR_SoftCopy] ; set soft copy. - STR r7, [r0, #MemorySpeed] ; Remember CPU speed/MEMC1a flag - STR r8, [r0, #Page_Size] ; r8 is still page size from way up there - STR r13, [r0, #RAMLIMIT] ; save sussed memory size in LogRam - - LDR sp, =SVCSTK ; set up a stack - -; do as much other initialisation as possible, to give keyboard stuff time - [ StrongARM - BL Processor_Type ; Determines the processor type & stores it in page 0. - ] - - - ] ; :LNOT: HAL - -Continue_after_HALInit - -;StrongARM: 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). - - [ ProcessorVectors -; 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, =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! - MOV R0, #4 - -40 - LDR R2, [R1], #4 ; N.B. IRQ handler better be same as the one in there - STR R2, [R0], #4 - TEQ R0, #EndMOSROMVecs-MOSROMVecs - BNE %BT40 - - ChangedProcVecs r0 - - [ :LNOT: No26bitCode -; Now we have set up the hardware vectors we can drop back to SVC26 mode - - MRS r0, CPSR - BIC r0, r0, #&1F - ORR r0, r0, #SVC26_mode - MSR CPSR_c, r0 - ] - -; Ensure any CMOS operation aborted - - BL IICAbort - - BL IICInit - - [ CacheCMOSRAM - DebugTX "InitCMOSCache entry" - BL InitCMOSCache ; initialise cache of CMOS RAM - DebugTX "InitCMOSCache done" - TEQ R0, #0 ; returns zero on failure - LDREQ R1, [R0, #HAL_StartFlags] - ORREQ R1, R1, #OSStartFlag_NoCMOS - STREQ R1, [R0, #HAL_StartFlags] - ] - -; Now copy the initialised data - MOV R0, #IRQ1V - -; first save IOC soft copy so can restore it - - LDRB R2, [R0, #IOCControlSoftCopy-IRQ1V] - Push "R2" - LDRB R2, [R0, #CannotReset-IRQ1V] - Push "R2" - - ADRL r1, StartData -DatCopy - LDR R2, [R1], #4 - STR R2, [R0], #4 - TEQ R0, #(EndData-StartData+IRQ1V) - BNE DatCopy - - ADR r2, CONT_Break - MOV r0, #0 - STR r2, [r0, #ResetIndirection] - - MOV r0, #0 ; initialise abort list - STR r0, [r0, #AbortIndirection] - -; 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] - -; now the time/date conversions - - LDR R0, =SvcTable - ADRL R1, ConvertStandardDateAndTime - STR R1, [R0, #OS_ConvertStandardDateAndTime*4] - ADD R1, R1, #ConvertDateAndTime - ConvertStandardDateAndTime ; SKS - STR R1, [R0, #OS_ConvertDateAndTime*4] - -; other conversion SWIs, all go through same entry point - - ADRL R1, despatchConvert - MOV R2, #OS_ConvertHex1 -conversionSWIfill - STR R1, [R0, R2, LSL #2] - ADD R2, R2, #1 - CMP R2, #OS_ConvertFileSize+1 - BNE conversionSWIfill - -; OK, that completes the poking around, some of which is code. Now let's -; do a full IMB type thing, to be safe -; - MOV r0, #0 - ARMop IMB_Full,,,r0 - DebugTX "IMB_Full done" - -; Initialise CAO ptr to none. - - MOV R0, #0 - LDR R1, =DuffEntry ; nothing will be here!! - STR R1, [R0, #Curr_Active_Object] - -KeyWait * 200000 ; 1/5 sec wait (in microseconds) - [ HAL -us * 1 - | -us * 2 - ] - - [ HAL - AddressHAL - MOV r6, #25 ; Check for keyboard 25 times (5 secs max). - MOV r4, #InitIRQWs - -kbdwait - CallHAL HAL_KbdScan - STR r0, [r4, #KbdFlags] - - TST r0, #KbdFlag_Done - BNE kbddone - - [ EmulatorSupport - ARM_on_emulator r0 - MOVEQ r0, #us - LDRNE r0, =KeyWait*us ; Wait 1/5 second (give keys down a chance to come in). - | - LDR r0, =KeyWait*us ; Wait 1/5 second (give keys down a chance to come in). - ] - CallHAL HAL_CounterDelay - SUBS r6, r6, #1 ; else wait a maximum of 5 seconds. - BNE kbdwait -kbddone - MSR CPSR_c, #I32_bit+SVC32_mode - CallHAL HAL_KbdScanFinish - MOV r1, #InitIRQWs - MOV r0, #0 - STRB r0, [r1, #KbdScanActive] - MSR CPSR_c, #SVC32_mode - | - [ KeyWait <> 0 -; Check for keyboard there every 1/5 sec. but give up after 2 secs. - MOV r2, #IOC - MOV r6, #10 ; Check for keyboard 10 times (2 secs max). - MOV r4, #InitKbdWs -kbdwait - LDRB r5, [r4, #KB_There_Flag] - [ EmulatorSupport - ARM_on_emulator r0 - MOVEQ r0, #us - LDRNE r0, =KeyWait*us ; Wait 1/5 second (give keys down a chance to come in). - | - LDR r0, =KeyWait*us ; Wait 1/5 second (give keys down a chance to come in). - ] - BL DoMicroDelay - TEQ r5, #0 ; If keyboard was there 1/5 second ago then - BNE kbdthere ; continue reset - SUBS r6, r6, #1 ; else wait a maximum of 2 seconds. - BNE kbdwait -kbdthere - ] - ] - - [ ValidateCMOS -; Do a POR if some super-critical values are shagged or if checksum is invalid. - MOV R3, #-1 ; do all RAM if we do any - BL ValChecksum ; Always check the checksum - BNE cmos_reset - - ] - - [ ValidateCMOS :LAND: STB - -; ScreenSizeCMOS, RAMDiscCMOS, SysHeapCMOS, RMASizeCMOS and SpriteSizeCMOS -; should be 0. Happily they are at consecutive addresses so we can loop through -; them. - MOV R1, #ScreenSizeCMOS -reset_loop - MOV R0, R1 - BL Read - TEQ R0, #0 - BNE cmos_reset - INC R1 - TEQ R1, #SpriteSizeCMOS - BHI reset_loop - - [ {FALSE} - ; Oh, just leave it be - MOV R0, #VduCMOS - BL Read - [ IOMD_C_MonitorType = 0 :LAND: IOMD_C_PALNTSCType = 0 -; Force TV if we don't have a MonitorType auto-detect bit - TEQ R0, #(Sync_Separate :OR: MonitorType0) - | -; Force auto-detect of monitor stuff if we have a MonitorType auto-detect bit - TEQ R0, #(Sync_Auto :OR: MonitorTypeAuto) - ] - BNE cmos_reset - ] - -; Year should be >=1995, <=2020 -; (2020 is arbitrary, but everything breaks soon after that) - MOV R0, #YearCMOS+1 - BL Read - TEQ R0, #19 - BNE check20 - -; 20th century: year should be 95 to 99 - MOV R0, #YearCMOS - BL Read - CMP r0,#95 - BLT cmos_reset - CMP r0,#99 - BHI cmos_reset - B checkboot - -check20 - TEQ R0, #20 - BNE cmos_reset - -; 21st century: year should <= 20 - MOV R0, #YearCMOS - BL Read - CMP R0, #20 - BHI cmos_reset - -checkboot -; Bit 4 of DBTBCMOS should be 1 (Boot) - MOV R0, #DBTBCMOS - BL Read - TST R0, #(1:SHL:4) - BEQ cmos_reset - ] - - -; IF power-on bit set AND R/T/Del/Copy pressed THEN reset CMOS RAM -; note that memory cleared if POR, so key info has had plenty of time! - [ HAL - MOV R0, #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 - [ CheckProtectionLink - TST R1, #OSStartFlag_NoCMOSReset - BNE no_cmos_reset - ] - TST R1, #OSStartFlag_CMOSReset - BNE cmos_reset - | - MOV R0, #IOC - LDRB R1, [R0, #IOCIRQSTAA] - ANDS R1, R1, #por_bit - BEQ no_cmos_reset - - [ CheckProtectionLink - LDR r0, =IOMD_MonitorType - - ; on Issue A's the protection bit is only weakly pulled up, - ; so force it high, then read it back - LDRB r1, [r0] - ORR r1, r1, #IOMD_ProtectionLinkBit - STRB r1, [r0] - - LDRB r1, [r0] - TST r1, #IOMD_ProtectionLinkBit - BEQ no_cmos_reset ; if zero then CMOS is protected - ] - - [ STB :LAND: IOMD_C_FrontPanelButton <> 0 - [ FrontPanelButtClearsCMOS - MOV r0, #IOMD_Base ; if front panel button pressed then CMOS reset - LDRB r0, [r0, #IOMD_CLINES] - TST r0, #IOMD_C_FrontPanelButton - BEQ cmos_reset - ] - ] - - ] - - MOV R0, #InitIRQWs - [ HAL - LDR R7, [R0, #KbdFlags] - TST R7, #KbdFlag_R:OR:KbdFlag_T:OR:KbdFlag_Delete:OR:KbdFlag_Copy - | - LDR R7, [R0, #R_Down_Flag] - CMP R7, #0 - ] - BEQ no_cmos_reset ; power on bit checked again there - - [ :LNOT: STB - ADD sp, sp, #4 ; junk CannotReset flag from stack - ] - -; CMOS reset detectified. -; ************************************************************************** -; Note: if this CMOS reset code ever needs changing again, it's probably -; better to rewrite it. The Compact apparently has a table of default -; CMOS values; R-p.o. just writes the table, DEL-p.o. zeroes all, then -; writes the table. With skipping of the time CMOS, and post-prodding of -; the sync, that would probably be a better algorithm. -; ************************************************************************** - - [ HAL - ! 0, "Sort out SetBorder for CMOS reset" - TST R7, #KbdFlag_Copy:OR:KbdFlag_Delete - | - SetBorder R0, R1, 15, 0, 0 ; flash the border as warning! - ASSERT (Del_Down_Flag - R_Down_Flag) = 2 - ASSERT (Copy_Down_Flag - Del_Down_Flag) = 1 - MOVS R3, R7, LSR #16 ; full reset or just system? - ] - - 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 - [ STB - ADD sp, sp, #4 ; junk CannotReset flag from stack - ] - MOVNE R0, #0 ; even the econet station number - MOVEQ R0, #1 - | - MOV R0, #1 ; leave the econet station number - ] - MOV R1, #0 ; zero it first -cmrlp BL Write ; CMOS(R0) := R1 - ADD R0, R0, #1 - CMP R0, R3 - MOVEQ R0, #&80 ; skip user cmos - CMP r0, #YearCMOS - ADDEQ r0, r0, #2 - CMP r3, #UserCMOS ; system only? - BNE skipskipforTC - CMP r0, #NewADFSCMOS - CMPNE r0, #CountryCMOS ; skip these if so - ADDEQ r0, r0, #1 -skipskipforTC - CMP R0, #CMOSLimit - BNE cmrlp - [ ChecksumCMOS - BL MakeChecksum ; create a valid checksum - ] -; now put nice values in where necessary -; first full reset defaults - CMP r3, #-1 - BNE not_full_reset - - [ STB :LAND: IOMD_C_PALNTSCType <> 0 - MOV r4, #IOMD_Base ; configure territory, country and timezone based on PAL/NTSC bit - LDRB r4, [r4, #IOMD_CLINES] - MOV r0, #TerritoryCMOS - TST r4, #IOMD_C_PALNTSCType - MOVEQ r1, #0 ; PAL = territory UK - MOVNE r1, #49 ; NTSC = territory USA - BL Write - MOV r0, #CountryCMOS - TST r4, #IOMD_C_PALNTSCType - MOVEQ r1, #1 ; PAL = country UK - MOVNE r1, #48 ; NTSC = country USA - BL Write - MOV r0, #TimeZoneCMOS - TST r4, #IOMD_C_PALNTSCType - MOVEQ r1, #0 ; PAL = 0 from UTC (GMT) - MOVNE r1, #&E0 ; NTSC = -8 hours from UTC (USA Pacific) - BL Write - [ STB :LAND: :DEF: ObsoleteNC1CMOS - MOV r0, #MiscellaneousNCCMOS - TST r4, #IOMD_C_PALNTSCType - MOVEQ r1, #0 ; PAL = A4 paper size - MOVNE r1, #1 ; NTSC = US letter paper size - BL Write - ] - | - MOV r0, #CountryCMOS - MOV r1, #1 ; country UK - BL Write - ] - - [ :LNOT: STB - MOV r0, #NewADFSCMOS - MOV r1, #&41 ; floppies=1, ST506=0, IDE=1 (changed 01-Sep-93) - BL Write - ] - -not_full_reset - -; IF R or Delete pressed THEN set sync 0 ELSE set sync Auto - MOV R0, #InitIRQWs - [ HAL - LDR R1, [R0, #KbdFlags] - TST R1, #KbdFlag_R:OR:KbdFlag_Delete - | - LDRB R1, [R0, #R_Down_Flag] - CMP R1, #0 - LDREQB R1, [R0, #Del_Down_Flag] - CMPEQ R1, #0 - ] - 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 - - [ HAL - MOV R0, #MouseCMOS - MOV R1, #PointerDevice_USB - BL Write - -; set print and sound CMOS (16bit sound) - MOV R0, #TutuCMOS - MOV R1, #2_10100100 ; tbs chars valid, ctrlchars '|x' - BL Write - - | - - [ MorrisSupport - MOV R8, #IOMD_Base - LDRB r0, [r8, #IOMD_ID0] - LDRB r1, [r8, #IOMD_ID1] - ORR r0, r0, r1, LSL #8 - LDR r1, =IOMD_Original - TEQ r0, r1 - BEQ dont_program_mousetype -; -; Morris based machines use PS2 mice/tracker balls -; - MOV R0, #MouseCMOS - MOV R1, #PointerDevice_PS2Mouse ;type 3 - BL Write - - [ Select16BitSound -; set print and sound CMOS (16bit sound) - B Config16BitSound - ] -dont_program_mousetype - ] ; MorrisSupport - - [ Select16BitSound - LDR r0, =IOMD_MonitorType - -; on Issue A's the protection bit is only weakly pulled up, -; so force it high, then read it back - - LDR r1, [r0] - ORR r1, r1, #IOMD_SoundsystemLinkBit - STR r1, [r0] - - LDR r1, [r0] - TST r1, #IOMD_SoundsystemLinkBit - BEQ Config16BitSound ; if zero, must be Rimmer, so assume 16bit sound hardware present - -; set print and sound CMOS (8bit sound) - MOV R0, #TutuCMOS - MOV R1, #2_0100 ; tbs chars valid, ctrlchars '|x' - BL Write - B ConfigSoundDone - -Config16BitSound -; set print and sound CMOS (16bit sound) - MOV R0, #TutuCMOS - MOV R1, #2_10100100 ; tbs chars valid, ctrlchars '|x' - BL Write - -ConfigSoundDone - ] - ] ; HAL - - ADR R8, DefaultCMOSTable -50 - LDRB R0, [R8], #1 - CMP R0, #&FF - BEQ hard_reset ; power on bit musta bin set - LDRB R1, [R8], #1 - BL Write - B %BT50 - - LTORG - - [ ValidateCMOS :LAND: STB -DefaultCMOSTable ; list of non-zero options wanted : -; byte pairs of offset, value -; terminated by offset &FF - = KeyDelCMOS, 32 - = KeyRepCMOS, 8 - = MODETVCMOS, &10 ; TV 0,1 - = StartCMOS, (2:SHL:3) ; NOCAPS - = DBTBCMOS, (1:SHL:4) ; Boot - = YearCMOS, 02 - = YearCMOS+1, 20 - [ IOMD_C_MonitorType = 0 :LAND: IOMD_C_PALNTSCType = 0 -; TV if we don't have a MonitorType auto-detect bit - = VduCMOS, Sync_Separate :OR: MonitorType0 - | -; auto-detect if we have a MonitorType auto-detect bit - = VduCMOS, Sync_Auto :OR: MonitorTypeAuto - ] - = MouseStepCMOS, 2 - = SystemSpeedCMOS, (1:SHL:2):OR:(1:SHL:4):OR:(0:SHL:5) - ; Delete-etc reset - ; WimpMode auto - ; Cache on - | ;ValidateCMOS -DefaultCMOSTable ; list of non-zero options wanted : -; byte pairs of offset, value -; terminated by offset &FF - = KeyDelCMOS, 32 - = FileLangCMOS, 8 - = FontCMOS, 64 ; KJB 13-Dec-02: Changed to 256K from 64K - = PigCMOS, 10 - = KeyRepCMOS, 8 - = RMASizeCMOS, 0 - = SpriteSizeCMOS, 0 - = SysHeapCMOS, 8 - = MODETVCMOS, &10 ; TV 0,1 - = NetFSIDCMOS, 254 - = NetPSIDCMOS, 235 - = PSITCMOS, (3:SHL:2) :OR: (1:SHL:5) - ; Baud 3 - ; print 1 - - = DBTBCMOS, (1:SHL:4) :OR: (4:SHL:5) - ; Boot (changed from NoBoot 01-Sept-93) - ; Data 4 - - = StartCMOS, (4:SHL:0) :OR: (2:SHL:3) :OR: (1:SHL:6) - ; Drive 4 (changed from Drive 0 01-Sept-93) - ; NOCAPS (changed from CAPS 02-May-91) - ; NODIR - - [ NewClockChip ; only on A1's! - = NewADFSCMOS+1, &FF ; step 3 for each drive - ] - - = NewADFSCMOS+2, 1 ; ADFSBuffers 1 - = SoundCMOS, &F0 ; speaker on, volume 7, channel 1 - - = LanguageCMOS, ConfiguredLang - = YearCMOS, 02 - = YearCMOS+1, 20 - [ :LNOT: Select16BitSound - = TutuCMOS, 2_0100 ; tbs chars valid, ctrlchars '|x' - ] - = NetFilerCMOS, (0:SHL:0) :OR: (1:SHL:1) :OR: (0:SHL:2) - ; FS list order by name - ; Use $.Arthurlib - ; Large icons - - ; = Mode2CMOS, WimpModeAutoBit :OR: CMOSResetBit ;AKA SystemSpeedCMOS - removed by RManby and SCormie 8/3/95 - = DesktopCMOS, 2_01000000 ; verbose ON - = WimpFlagsCMOS, 2_01101111 ; instant effects, drags off screen - = ProtectionCMOS, 2_01110110 ; allow only peek and user RPC - = MouseStepCMOS, 2 - = FileSwitchCMOS,(1:SHL:0) :OR: (1:SHL:1) :OR: (0:SHL:2) :OR: (0:SHL:3) :OR: (0:SHL:6) - ; truncate names - ; Use DragASprite (changed 01-Sept-93) - ; Interactive file copying - ; Wimp dither colours off - ; last shutdown ordinary - - = DesktopFeaturesCMOS,(1:SHL:0) :OR: (8:SHL:1) :OR: (0:SHL:7) - ; 3D look - ; Homerton.Medium - ; tiled window background - - [ STB - = SystemSpeedCMOS,(1:SHL:0):OR:(0:SHL:1):OR:(1:SHL:2):OR:(0:SHL:3):OR:(1:SHL:4):OR:(0:SHL:5):OR:(1:SHL:6):OR:(0:SHL:7) - ; AUN ROMBoot Enabled - ; AUN auto-station numbering off - ; Delete-etc reset - ; power saving off - ; WimpMode auto - ; Cache on - ; Broadcast loader disabled - ; broadcast loader colours off - | - = SystemSpeedCMOS,(0:SHL:0):OR:(0:SHL:1):OR:(1:SHL:2):OR:(0:SHL:3):OR:(1:SHL:4):OR:(0:SHL:5):OR:(1:SHL:6):OR:(0:SHL:7) - ; AUN BootNet Disabled - ; AUN auto-station numbering off - ; Delete-etc reset - ; power saving off - ; WimpMode auto - ; Cache on - ; Broadcast loader disabled - ; broadcast loader colours off - ] - - [ :LNOT: STB - = FontMaxCMOS, 64 ; 4096k - = FontMax2CMOS, 36:EOR:12 ; 36 point - = FontMax3CMOS, 36:EOR:24 ; 36 point - = FontMax4CMOS, 16 ; 16 point - | - ; yes, omitting FontMaxCMOS is deliberate! - = FontMax2CMOS, &2C ; 32 point - = FontMax3CMOS, &38 ; 32 point - ] - = AlarmAndTimeCMOS,2_00010000 ; !Alarm autosave on - = FSLockCMOS+5, &EA ; Checksum for no password - = CDROMFSCMOS, &C1 ; drives = 1, buffer size = 256K - ] - = &FF - ALIGN - - -no_cmos_reset ; R1 has por_bit set if power on - Push "r1" - MOV r0, #SystemSpeedCMOS - BL Read - BIC r1, r0, #CMOSResetBit ; clear bit indicating CMOS reset - MOV r0, #SystemSpeedCMOS - BL Write - Pull "r1" - - Pull r0 ; always pull CannotReset flag - [ SoftResets - TST r1, #por_bit - BNE hard_reset ; it was a power-on, so it's a hard reset - CMP r0, #0 - [ DebugForcedReset - MOVNE r2, #Reset_CannotResetFlag - ] - BNE hard_reset_forced - -; IF control pressed OR memory implausible (Check SysHpd, CAM map sensible) THEN hard reset - - LDR R0, =SysHeapStart - LDR R8, [R0, #:INDEX: hpdmagic] - LDR R2, =magic_heap_descriptor - CMP R8, R2 ; check sysheap initialised - [ DebugForcedReset - MOVNE r2, #Reset_SysHeapCorrupt - ] - BNE hard_reset_forced - -; also check CAM map sensible - - MOV R5, #0 - LDR R4, [R5, #Page_Size] ; R4 = page size - ADRL R3, PageShifts-1 - LDRB R4, [R3, R4, LSR #12] ; R4 = log2(pagesize) - LDR R3, [R5, #RAMLIMIT] ; R3 = total RAM size - MOV R2, R3, LSR R4 ; number of pages=total memory / pagesize - CMP R2, #256 ; but if fewer than 128 (eg 64 on A305) (NB if <256 then <=128) - MOVCC R2, #128 ; then use 128 (all MEMC1's pages need initialising, - ; even if half of them are not in use) - SUB R2, R2, #1 - LDR R3, =CamEntriesForVicky - - LDR R4, [R5, #MaxCamEntry] ; get highest CAM entry - LDR R5, [R5, #CamEntriesPointer] ; and pointer to CAM soft copy - - CMP R5, R3 ; if not the same - [ DebugForcedReset - MOVNE r2, #Reset_WrongCamMapAddress - BNE hard_reset_forced - ] - CMPEQ R4, R2 ; or number of pages not the same - [ DebugForcedReset - MOVNE r2, #Reset_WrongNumberOfPages - ] - BNE hard_reset_forced ; then do a hard reset - -; now check all cam contains sensible values - - MOV R4, #0 - LDR R4, [R4, #Page_Size] - SUB R4, R4, #1 - ORR R4, R4, #&F0000000 ; can have addresses above 64M -CamCheck - LDR R3, [R5, R2, LSL #2] - BIC r3, r3, #&F0000000 ; remove PPL - TST R3, R4 - [ DebugForcedReset - MOVNE r2, #Reset_CamMapCorrupt - ] - BNE hard_reset_forced ; wally entry: not pagesize multiple, or >= 32M - SUBS R2, R2, #1 - BPL CamCheck - -; leave CTRL test till last, so the keyboard's had as much time to -; wiggle the wet string as we can give it - MOV R0, #InitKbdWs - LDRB R1, [R0, #CTRL_Down_Flag] - CMP R1, #0 - BNE hard_reset - -soft_reset -; clear out 4K of scratchspace, to use as a reverse CAM soft copy; -; set bytes to indicate page mapped to that address. Can then recalculate -; end of memory. - -; This code doesn't currently work on ARM600 versions - -; 4K of workspace isn't enough to do this with a 4K page size -; We'd probably want to do it differently anyway, using the L2PT -; But since we're removing soft resets it's not worth the effort - - ASSERT MEMM_Type <> "ARM600" - - MOV R5, #ScratchSpace - MOV R1, #4*1024 - MOV R2, #0 -clrscratch - SUBS R1, R1, #4 - STRPL R2, [R5, R1] - BPL clrscratch - - LDR R2, [R2, #Page_Size] - ADRL R8, PageShifts-1 - LDRB R8, [R8, R2, LSR #12] - - MOV r7, #0 - LDR r2, [r7, #RAMLIMIT] - MOV r2, r2, LSR r8 ; last valid page - SUB r2, r2, #1 - - LDR R7, [R7, #CamEntriesPointer] - LDR R12, =DuffEntry - -restoreCAMloop - LDR R3, [R7, R2, LSL #2] - MOV r11, r3, LSR #28 - BIC r3, r3, #&F0000000 - - MOV R0, R3, LSR R8 ; logram page number - LDRB R4, [R5, R0] - CMP r4, #0 ; check for doubly mapped pages - BEQ rclon - - ORR r3, r12, #&30000000 ; force to invalid place if so. - STR r3, [R7, R2, LSL #2] - MOV r3, r12 - MOV r11, #3 ; protected - MOV R0, R3, LSR R8 - LDRB R4, [R5, R0] -rclon - CMP r3, #16*1024*1024 ; in application space? - MOVLT r11, #0 ; noprot if so - STRLT r3, [R7, R2, LSL #2] - ADD R4, R4, #1 - STRB R4, [R5, R0] ; sema for interesting pages - BL BangCam - SUBS R2, R2, #1 - BPL restoreCAMloop - -; now do post-scan to see if we need to do more CAM bashing to get pages back. -; any entries that aren't validateable should be remapped. - - MOV R7, #0 - MOV R12, #ScratchSpace - LDR R2, [R7, #Page_Size] -findapplend - LDRB R3, [R12], #1 - CMP R3, #0 - ADDNE R7, R7, R2 - BNE findapplend - MOV R1, #0 - STR R7, [R1, #AplWorkSize] ; verified value - LDR R3, [R1, #RAMLIMIT] ; calc last valid page: - MOV R3, R3, LSR R8 ; RAMLIMIT >> R8 - MOV R11, #0 ; no PPL - LDR R4, [R11, #CamEntriesPointer] -testforremap - SUBS R3, R3, #1 - BMI finishedremap - LDR R0, [R4, R3, LSL #2] - BIC r0, r0, #&F0000000 ; remove PPL - ADD R1, R0, R2 - SWI XOS_ValidateAddress - BCC testforremap - - Push "R2-R4" - MOV R0, R0, LSR R8 ; curr logram page number - LDRB R4, [R5, R0] - SUB R4, R4, #1 - STRB R4, [R5, R0] ; dec sema - MOV R2, R3 ; entry no - MOV R3, R7 ; addr to set to - BL BangCamUpdate - Pull "R2-R4" -holefilled - ADD R7, R7, R2 - LDRB R0, [R12], #1 ; reinspect our reverse map - CMP R0, #0 - BNE holefilled - MOV R0, #0 - STR R7, [R0, #AplWorkSize] - B testforremap - -finishedremap - MOV R12, #NVECTORS-1 - LDR R11, =VecPtrTab -freenextvec - LDR R2, [R11, R12, LSL #2] -loseveclink - LDR R3, [R2, #TailPtr] - BL FreeSysHeapNode - MOVVC R2, R3 - BVC loseveclink - CMP R3, #0 ; were we at the end of the chain? - [ DebugForcedReset - MOVNE r2, #Reset_VectorChainCorrupt - ] - BNE hard_reset_forced - SUBS R12, R12, #1 - BPL freenextvec -; so that's the code for restore default vectors, basically - BL InitVectors - MOV R0, #0 - LDR R1, [R0, #AplWorkSize] - STR R1, [R0, #MemLimit] - - LDR R3, =TickNodeChain - LDR R2, [R3] - -loseticknodes - CMP R2, #0 - BEQ ticknodesallgone - - LDR R3, [R2] - BL FreeSysHeapNode - [ DebugForcedReset - MOVVS r2, #Reset_TickNodesCorrupt - ] - BVS hard_reset_forced - MOV R2, R3 - B loseticknodes - -ticknodesallgone -; and now it's time to free the IRQ structures - - MOV R12, #(NoInterrupt-1)*12+8 ; last device link offset - LDR R11, =DefaultIRQ1V-DefaultIRQ1Vcode+Devices -freenextdev - LDR R2, [R11, R12] -losedevlink - CMP R2, #0 - BEQ stepdevice - - LDR R3, [R2, #8] - BL FreeSysHeapNode - [ DebugForcedReset - MOVVS r2, #Reset_DeviceVectorCorrupt - ] - BVS hard_reset_forced - MOV R2, R3 - B losedevlink -stepdevice - SUBS R12, R12, #12 - BPL freenextdev - -; now the PIRQ structures and CallBack_Vector - LDR R11, =PIRQ_Chain - MOV r4, #PodDesp_Link -losepirqchain - LDR R2, [R11] - CMP r2, #0 ; for CallBack_Vector - BEQ doobry -losepirqlink - LDR R3, [R2, r4] - BL FreeSysHeapNode - MOVVC R2, R3 - BVC losepirqlink - CMP R3, #0 ; were we at the end of the chain? - [ DebugForcedReset - MOVNE r2, #Reset_PoduleOrCallBackCorrupt - ] - BNE hard_reset_forced - LDR R2, =PIRQ_Chain - CMP R11, R2 - LDR R2, =PFIQasIRQ_Chain - MOVEQ R11, R2 - CMPNE r11, r2 - LDREQ r11, =CallBack_Vector - [ PodDesp_Link <> 0 - MOVEQ r4, #0 - ] - BEQ losepirqchain - - -doobry Pull "R1" ; IOCControl restoration - MOV R0, #0 - STRB R1, [R0, #IOCControlSoftCopy] - MOV R0, #IOC ; and bash the hardware - STRB R1, [R0, #IOCControl] - - MOV R0, #SoftReset - B ResetPart1Done - - | - -; if soft resets are disabled, drop thru into hard reset code - - ] ; end of code to do with soft resets - -hard_reset - [ DebugForcedReset - MOV r2, #0 ; indicate normal hard reset - ] -hard_reset_forced - [ DebugForcedReset - STR r2, [r0, -r0] ; store to logical address zero - ] - - Pull "R2" ; discard old IOC state - -; fill in relevant CamMap entries, so can soft start. - - MOV R8, #0 - LDR R8, [R8, #Page_Size] - ADRL R1, PageShifts-1 - LDRB R1, [R1, R8, LSR #12] - - MOV r2, #0 - LDR r0, [r2, #VideoSize] ; offset from start of physical pages to static part - MOV r0, r0, LSR r1 ; r0 := cam entry number - MOV r0, r0, LSL #3 ; r0 := offset into CAM map for start of static part - - MOV R7, #32*1024*8 - MOV R7, R7, LSR R1 ; r7 := cam entry offset for 32K - - LDR R12, [R2, #RAMLIMIT] ; R12 = total RAM size - - [ :LNOT:HAL - ; new code which allows for MEMC2's small pages - MOV R1, R12, LSR R1 ; R1 = number of pages - CMP R1, #256 ; but if fewer than 128 (eg 64 on A305) (NB if <256 then <=128) - MOVCC R1, #128 ; then use 128 (all MEMC1's pages need initialising, - ; even if half of them are not in use) - - SUB R3, R1, #1 - STR R3, [R2, #MaxCamEntry] - - LDR R1, =CamEntriesForVicky - STR R1, [R2, #CamEntriesPointer] - - -; On ARM600 we must zap all the soft CAM map before adding any entries, -; since the old contents are used in BangCamUpdate - - Push "r0" - ADD r2, r1, r3, LSL #3 ; r2 -> last entry to do - LDR r0, =DuffEntry - MOV lr, #AP_Duff ; PPL = no access -WallopDuffOnes - STMDA r2!, {r0, lr} ; store address, PPL - CMP r2, r1 - BCS WallopDuffOnes - Pull "r0" - ADD R0, R0, R1 - - LDR R2, =CursorChunkAddress - LDR r1, =AP_CursorChunk - BL AddCamEntries - - CMP R12, #512*1024 - SUBEQ R0, R0, R7 ; previous entries - ADDNE R0, R0, R7 ; next entries - MOV R2, #0 - MOV r1, #AP_PageZero - BL AddCamEntries - - CMP R12, #512*1024 - SUBEQ R0, R0, R7 ; previous entries - ADDNE R0, R0, R7 ; next entries - LDR R2, =SysHeapChunkAddress - MOV r1, #AP_SysHeap :OR: PageFlags_Unavailable - BL AddCamEntries - - ADD R0, R0, R7 ; next entries (ignore 512K machines) - MOV r7, #0 - LDR r7, [r7, #L2PTSize] - MOV r7, r7, LSR #12-3 ; number of pages * 8 - LDR R2, =L2PT - LDR r1, =AP_L2PT :OR: PageFlags_Unavailable - BL AddCamEntries - - ADD r2, r0, #((L1PT-L2PT):SHR:(12-3)) ; point at PPL for 1st L1 page - ADD r2, r2, #4 - LDR r1, =AP_L1PT - STR r1, [r2], #8 ; store 4 CAM entries for 4 x 4K = 16K of L1 - STR r1, [r2], #8 ; mark them as unavailable for removal - STR r1, [r2], #8 - STR r1, [r2], #8 - - ADD R0, R0, R7 ; add on enough pages for L2PT - - MOV r7, #0 - LDR r7, [r7, #SoftCamMapSize] ; number of bytes in soft cam map - ADD r7, r7, #UndStackSize - MOV r7, r7, LSR #12-3 ; number of bytes of cam map for this - LDR R2, =UndStackSoftCamChunk - MOV r1, #AP_UndStackSoftCam - BL AddCamEntries - ] - -; let's boogie with the CMOS for a bit -; read info and move as much memory as we can - - BL InitDynamicAreas - -; RMA - Push "r0-r12" - MOV r1, #ChangeDyn_RMA ; Area number - MOV r2, #4096 ; Initial size - MOV r3, #RMAAddress ; Base address - MOV r4, #AP_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 - - MOV r5, #0 - LDR r10, [r5, #Page_Size] ; needed by MassageScreenSize - MUL r0, r10, r0 ; convert to bytes - LDR r5, [r5, #VideoSize] ; maximum size - BL MassageScreenSize - - MOV r1, #ChangeDyn_Screen ; area number - MOV r2, r0 ; initial size - MOV r3, #-1 ; Base address dynamic - LDR r4, =AP_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" - - [ LongCommandLines :LAND: (:LNOT: HAL) - ;sort out the Kernel buffers dynamic area - Push "r0-r12" - MOV r1, #ChangeDyn_Kbuffs ; Area number - MOV r2, #KbuffsSize ; Initial (and in fact permanent) size - LDR r3, =KbuffsBaseAddress ; Base address - MOV r4, #AP_Kbuffs ; Area flags - MOV r5, #KbuffsMaxSize ; Maximum size - MOV r6, #0 ; no handler - MOV r7, #0 - ADRL r8, AreaName_Kbuffs ; 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" - ] - -; SpriteArea - Push "r0-r12" - MOV r0, #0 ; initialise SpriteSize to zero - STR r0, [r0, #SpriteSize] ; (fixes bug MED-00811) - - 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, #AP_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! - Pull "r0-r12" - -; RAMDisc - Push "r0-r12" - MOV r0, #RAMDiscCMOS ; find out how much RAM disc configured - BL GetConfiguredSize ; in: r0 = CMOS address, out: r2 = size - - 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, #AP_RAMDisc_SA ; Area flags, if StrongARM (introduced for Ursula) - MOVNE r4, #AP_RAMDisc ; Area flags - [ {FALSE} - MOV r5, #16*1024*1024 ; Limit maximum size to 16MB while fiddling with FileCore - | - 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! - Pull "r0-r12" - -; FontArea - Push "r0-r12" - 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, #AP_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" - -; get here with R2 = highest CAM entry used (in old model) - -; [ HAL32 -; MOV R0, #0 -; LDR R0, [R0, #RAMLIMIT] -; SUB R0, R0, #32*1024 -; MOV R0, R0, LSR #12 -; | - LDR R0, =(AplWorkMaxSize-32*1024):SHR:12 ; maximum number of pages in aplspace -; ] - MOV R3, #32*1024 ; aplwork start - LDR R1, =AplWorkSize ; aplwork size - MOV r11, #AP_AppSpace - BL FudgeConfigureRMA ; put as much as possible in aplspace - - MOV R0, #0 - LDR R1, [R0, #AplWorkSize] - ADD R1, R1, #32*1024 - STR R1, [R0, #AplWorkSize] - STR R1, [R0, #MemLimit] - - BL InitVectors ; ready for OsByte to read mode - - LDR R1, =ModuleSWI_HashTab - MOV R2, #ModuleSHT_Entries-1 -clearmswis - STR R0, [R1, R2, LSL #2] - SUBS R2, R2, #1 - BGE clearmswis - - [ International - MOV R1, #-1 ; We don't have a message file yet ! - STRB R1, [R0, #ErrorSemaphore] ; Don't translate errors. - STR R0, [R0, #KernelMessagesBlock] ; No message file open. - [ CacheCommonErrors - STR R0, [R0, #CachedErrorBlocks] ; No cached errors - ] - ] - - [ HAL - MOV R0, #HAL_StartFlags - LDR R1, [R0] - TST R1, #OSStartFlag_POR - | - MOV R0, #IOC - LDRB R1, [R0, #IOCIRQSTAA] - ANDS R1, R1, #por_bit - STRNEB R1, [R0, #IOCIRQCLRA] ; clear POR if set - ] - - - ; Make the choice between PowerOn and Hard reset based purely on - ; the state of the POR bit and NOT on whether memory was cleared. - [ {FALSE} - LDREQ R0, =OsbyteVars + :INDEX: LastBREAK - LDREQB R0, [R0] - TSTEQ R0, #&80 ; tbs set if memory cleared - ] - MOVNE R0, #PowerOnReset - MOVEQ R0, #ControlReset - - -ResetPart1Done ; R0 is reset type - WritePSRc SVC_mode + I_bit, r1 ; interrupts off since kbd bash done - LDR R1, =OsbyteVars + :INDEX: LastBREAK - STRB R0, [R1] - - MOV R1, #InitIRQWs - [ HAL - LDR R0, [R1, #KbdFlags] - AND R1, R0, #KbdFlag_Shift - AND R0, R0, #KbdFlag_Present - | - LDRB R0, [R1, #KB_There_Flag] - LDRB R1, [R1, #SHIFT_Down_Flag] - ] - Push "R0, R1" ; save until after MOSInit - - BL InitialiseIRQ1Vtable - - LDR R0, =PIRQ_Chain - ADRL R1, Default_PIRQHandler_Node - STR R1, [R0] - STR R1, [R0, #PFIQasIRQ_Chain-PIRQ_Chain] - ASSERT Default_PFIQasIRQHandler_Node = Default_PIRQHandler_Node - - MOV R0, #0 ; put in IRQ handler, word at 0 - STRB r0, [r0, #FIQclaim_interlock] - STRB r0, [r0, #CallBack_Flag] - STR r0, [r0, #CallBack_Vector] - -; 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} - MOVVC R0, #0 - STRVC R2, [R0, #ProcVec_Branch0] - - [ :LNOT: No26bitCode - -; we're poking locations 0 and &18 here, so we'd best go back to SVC32 - - MRS r2, CPSR - BIC r3, r2, #&1F - ORR r3, r3, #SVC32_mode - MSR CPSR_c, r3 - ] - - [ DebugForcedReset - LDR R1, [R0] - TEQ R1, #0 ; if normal hard reset - LDREQ R1, BranchThroughZeroInstruction2 ; then get branchthruzero code - | - LDR R1, BranchThroughZeroInstruction2 - ] - STR R1, [R0] ; put branch through 0 code at 0 - - LDR R1, RealIRQHandler - STR R1, [R0, #&18] - - MOV R2, #InitIRQWs ; clear temp ws - MOV R3, #0 - MOV R4, #0 - STMIA R2!, {R3,R4} - STMIA R2!, {R3,R4} - - ;we need to do an IMB type thing for modifying code in vector area, - ;and for copying irq handler code - ; - Push "r0" - MOV r0, #0 - ARMop IMB_Full,,,r0 - ChangedProcVecs r0 - Pull "r0" - - - [ :LNOT:No26bitCode - -; now back to SVC26 - - MSR CPSR_c, r2 - ] - - MOV R1, #&100 - STR R1, [R0, #RCLimit] - STR R0, [R0, #ReturnCode] - STR R0, [R0, #TickNodeChain] - -; clear the keyboard workspace (tidy!) - MOV R0, #&1C - MOV R1, #0 - MOV R2, #InitWsEnd - &1C - BL memset - -;now put in error handler and escape handler - BL DEFHAN - BL DEFHN2 - MOV R0, #ExceptionDumpArea - LDR R1, =DUMPER - SWI XOS_ChangeEnvironment - - VDWS WsPtr ; main MOS initialisation - BL VduInit - BL ExecuteInit - BL KeyInit - BL MouseInit - BL OscliInit ; before initialising modules - - WritePSRc SVC_mode, R14 ; enable IRQs - - [ DebugTerminal - MOV R0, #RdchV - ADRL R1, DebugTerminal_Rdch - MOV R2, #0 - LDR R2, [R2, #HAL_Workspace] - SWI XOS_Claim - MOV R0, #WrchV - ADRL R1, DebugTerminal_Wrch - SWI XOS_Claim - ] - - [ DoInitialiseMode :LOR: :LNOT: STB - BL InitialiseMode ; select correct screen mode, in case any - ; module prints anything in initialisation - ] - - MOV R0, #&FD ; read last reset type - MOV R1, #0 - MOV R2, #&FF - SWI XOS_Byte - CMP R1, #SoftReset ; soft reset? - BEQ SkipHardResetPart2 - -; HardResetPart2 - [ HAL - AddressHAL - MOV R0, #0 - STR R0, [R0, #DeviceCount] - STR R0, [R0, #DeviceTable] - CallHAL HAL_InitDevices ; get HAL to register any devices it has - | - BL L1L2PTenhancements ; little tricks on cacheability etc for performance - ] - BL InitVariables - BL AMBControl_Init ; initialise AMBControl section - BL ModuleInit ; initialise modules - ; scan podules, copy modules. - - 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 - MOV R0, #0 - LDR R0, [R0, #Page_Size] - MULTIPLY 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 - - [ DebugROMInit - SWI XOS_WriteS - = "Service_PostInit",0 - SWI XOS_NewLine - ] - MOV r1, #Service_PostInit ; issue post-initialisation service - BL Issue_Service - -; New code added here by TMD 01-Apr-92 -; Changed to use OS_LeaveOS 16-Oct-02 - - [ DebugROMInit - SWI XOS_WriteS - = "callbacks",0 - SWI XOS_NewLine - ] - SWI XOS_LeaveOS - SWI XOS_EnterOS ; switch back to SVC mode (IRQs, FIQs enabled) - [ :LNOT: HAL :LAND: RO371Timings - BL finalmemoryspeed - ] -; end of added code - - [ International ; Open the kernel messages file. - ADR r0, KernelMessagesBlock+4 - ADR r1, MessageFileName - MOV r2, #0 ; Use file directly. - SWI XMessageTrans_OpenFile - MOVVC r0, #-1 - STRVC r0, [r0, #KernelMessagesBlock+1] ; Message file is now open. - ] - -SkipHardResetPart2 ; code executed on all types of reset - [ International - MOV r0, #0 - LDR r1, [r0, #KernelMessagesBlock] ; if we've managed to open message file - TEQ r1, #0 - STRNEB r0, [r0, #ErrorSemaphore] ; then allow errors to be translated - ] - - [ DoInitialiseMode :LOR: :LNOT: STB - BL InitialiseMode - [ :LNOT: STB ; don't print stuff on STB type products - SWI XOS_WriteS - = 10, "$SystemName ", 0 ; now RISC OS (no +) again - ALIGN - - MOV R0, #0 - LDR R0, [R0, #RAMLIMIT] - - Push "R0" - MOV R0, #8 - ORR R0, R0, #&500 - SWI XOS_Memory ; returns amount of soft ROM (pages) in r1 - MOVVS R1, #0 - Pull "R0" - MLA R0, R1, R2, R0 ; convert pages to bytes and add in - - MOV R0, R0, LSR #20 ; /(1024*1024) 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 - ] - ] - - [ StrongARM - [ STB - ! 0,"Printing of processor type disabled" - | -; IMPORT ARM_PrintProcessorType - BL ARM_PrintProcessorType - ] - ] - -01 MOV r0, #0 ; Set DomainId to 0 every reset - STR r0, [r0, #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 - - [ SoftResets :LAND: STB - ! 0, "!!!! SoftReset is true => resets close all open files !!!!" - MOV R0, #FSControl_Shut ; Open files get closed at reset - SWI XOS_FSControl - ] - - BL PostInit - - MOV r0, #&FD ; read last reset type (again!) - MOV r1, #0 - MOV r2, #&FF - SWI XOS_Byte - CMP r1, #SoftReset ; a softie? - SWINE XOS_WriteI+7 ; go beep! Yaay! - - CMP r1, #PowerOnReset - BNE %FT75 - - [ HAL :LAND: CheckProtectionLink - LDR r1, =HAL_StartFlags - LDR r1, [r1] - TST r1, #OSStartFlag_NoCMOSReset - BNE %FT75 - | - [ CheckProtectionLink - LDR r1, =IOMD_MonitorType ; check link bit again - LDRB r1, [r1] ; no need to preload bus, since should - TST r1, #IOMD_ProtectionLinkBit ; be still there from earlier - BEQ %FT75 ; zero => protected - ] - ] - - -; if any monitor key pressed, reconfigure, otherwise hang around for a bit -; till keys get a chance to come in again after being reset for the umpteenth -; time by yet another keyboard handler! SKS 07-Jun-88 - - MOV r3, #0 - LDR r3, [r3, #MetroGnome] - [ EmulatorSupport - ARM_on_emulator r0 - ADDEQ r3, r3, #1 - ADDNE r3, r3, #10 ; Hang about for a little while - | - ADD r3, r3, #10 ; Hang about for a little while - ] - -KeypadStar_key * -92 - -HorologicalDelayLoop1 - MOV r0, #&79 ; 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 check if we've run out of time - - ADR r2, MonitorKeypadTable -62 - LDRB r14, [r2], #2 ; search for key in table - TEQ r14, #&FF - BEQ %FT70 - 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 - [ DoInitialiseMode :LOR: :LNOT: STB - BL InitialiseMode - - [ International - SWI XOS_WriteI+10 - BLVC WriteS_Translated - = "MonType:Monitor type reconfigured.",10,13,10,0 - ALIGN - | - SWI XOS_WriteS - = 10,"Monitor type reconfigured.",10,13,10,0 - ALIGN - ] - ] - B %FT75 - -BranchThroughZeroInstruction2 - [ ProcessorVectors - LDR PC, .+ProcVec_Branch0 - | - B .+Branch0_Trampoline - ] - -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 - -cputable - DCD &6000,0,0 - DCD &6100,1,0 - DCD &7000,2,0 - DCD &7100,3,0 - DCD &8100,4,2_11101 - DCD &a100,5,2_11011 ;corrected for 3.71 (SA does not abort for vector reads in 26-bit mode) - DCD &7500,6,0 - DCD &7501,7,0 - DCD -1 - - [ International -MessageFileName DCB "Resources:$.Resources.Kernel.Messages",0 - ALIGN - ] - - [ StrongARM -Processor_Type - MOV r0,#IOMD_Base - LDRB r1,[r0,#IOMD_ID0] - CMP r1,#&E7 - LDRB r1,[r0,#IOMD_ID1] - CMPEQ r1,#&D4 - BEQ PT_RiscPC ; E7,D4 means Risc PC - CMP r1,#&5B - MOVEQ r0,#&7500 ; 5B means 7500 - BEQ PT_lookup - CMP r1,#&AA - MOVEQ r0,#&7500 - ORREQ r0,r0,#&0001 ; AA means 7500FE - mark as 7501 - BEQ PT_lookup -PT_RiscPC - ReadCop R0,CR_ID ; see data sheets for values - ; ARM 600 funny - TST R0,#&f000 - MOVEQ R0,R0, LSL #4 - AND R0,R0,#&ff00 -PT_lookup - ADR R1,cputable -66 - LDR R2,[R1],#4 - TEQ R2,#0 - MOVMI R0,#0 - STRMI R2,[R0,#ProcessorType] - MOVMI PC,LR - TEQ R2,R0 - ADDNE R1,R1,#8 - BNE %BT66 - LDMIA R1,{R0,R2} - MOV R1,#0 - STRB R0,[R1,#ProcessorType] - STR R2,[R1,#ProcessorFlags] - MOV PC,LR - ] - -70 - MOV r14, #0 - LDR r14, [r14, #MetroGnome] - CMP r14, r3 - BLO HorologicalDelayLoop1 -75 - - -; Deal with SHIFT pressed/SHIFT-BREAK configured: -; do appropriate FSControl if wanted - - Pull "R0" ; first check kbd there - - CMP R0, #0 - BEQ AutoBootCosNoKbd - - MOV R0, #&FF - MOV R1, #0 - MOV R2, #&FF ; read shifty state - SWI XOS_Byte - AND R0, R1, #8 ; picka da bit - EOR R0, R0, #8 ; invert sense - Pull "R1" - CMP R1, #0 - MOVNE R1, #8 - EORS R1, R1, R0 - BEQ %FT80 - -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 either * pressed, drop into * prompt, otherwise hang around for a bit -; till keys get a chance to come in again after being reset for the umpteenth -; time by yet another keyboard handler! SKS 01-Jun-88 - - MOV r3, #0 - LDR r3, [r3, #MetroGnome] - [ EmulatorSupport - ARM_on_emulator r1 - ADDEQ r3, r3, #1 - ADDNE r3, r3, #10 ; Hang about for a little while - | - ADD r3, r3, #10 ; Hang about for a little while - ] - -HorologicalDelayLoop2 - MOV r1, #KeypadStar_key :AND: &FF - BL IsKeyPressedAtReset - BEQ DoStartSuper ; EQ -> start up supervisor - - MOV r0, #0 - LDR r0, [r0, #MetroGnome] - CMP r0, r3 - BLO HorologicalDelayLoop2 - - -; 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_Title] - 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 - - -AutoBootCosNoKbd - [ :LNOT: STB - [ International - SWI XOS_WriteI+7 - BLVC 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 - - -RealIRQHandler - [ ProcessorVectors - LDR PC, .-&18+ProcVec_IRQ - | - B Initial_IRQ_Code+.-&18 - ] - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; In r1 = INKEY -ve key code to look for - -; Out EQ: key pressed -; NE: key not pressed - -IsKeyPressedAtReset Entry "r0-r2" - - MOV r0, #129 - MOV r2, #&FF - SWI XOS_Byte - TEQ r1, #&FF - TEQEQ r2, #&FF - EXIT - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - [ AddTubeBashers -TubeDumpR0 ROUT - EntryS "R1, R2" - ADR lr, HexTable - TubeChar r0, r1, "MOV r1, #"" """ - MOV R1, #7 -01 MOV R0, R0, ROR #28 - AND R2, R0, #&F - TubeChar R0, R1, "LDRB R1, [lr, R2]" - SUBS R1, R1, #1 - BPL %BT01 - TubeChar r0, r1, "MOV r1, #"" """ - EXITS - -TubeNewl - EntryS - TubeChar R0, R1, "MOV R1, #10" - TubeChar R0, R1, "MOV R1, #13" - EXITS - -HexTable = "0123456789ABCDEF" - - ] - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - END diff --git a/s/Oscli b/s/Oscli deleted file mode 100644 index 5b438bb2..00000000 --- a/s/Oscli +++ /dev/null @@ -1,1500 +0,0 @@ -; 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 => Oscli - main Oscli code and system commands. - -; -;mjs performance enhancements for Ursula (ChocolateOscli) -; -Oscli_CHashValMask * &1f ;32-wide Command hashing, for commands within kernel -Oscli_MHashValMask * &ff ;256-wide Module hashing, for command groups in other modules - ; - kernel cmd hashed tables must be reorganised if Oscli_CHashValMask is changed - ; - UtilityModule MUST be first in module chain, if hashing in use - - - MACRO -$l CheckUID $reg, $tmp -$l MOV $tmp, #0 - LDR $tmp, [$tmp, #OscliCBbotUID] - CMP $reg, $tmp - MEND -; exits with HI if buffer OK. - -;****************************************************************************** -; redirection utility routines - -; In: R10 points at filename, V clear -; R1 is type - -; Out: R0, R1, R12 corrupted, redirection done, flags preserved (or V set) - -doredirect ROUT - EntryS "R1, R2" -60 LDRB R0, [R10], #1 - CMP R0, #" " - BEQ %BT60 - MOV R2, R1 - LDR R1, =RedirectBuff -61 CMP R0, #" " ; we know it's terminated by space - STRNEB R0, [R1], #1 - LDRNEB R0, [R10], #1 - BNE %BT61 - SUB R10, R10, #1 - MOV R0, #13 - STRB R0, [R1] - LDR R1, =RedirectBuff - MOV R0, #0 - CMP R2, #&40 - LDREQB R1, [R0, #RedirectInHandle] - LDRNEB R1, [R0, #RedirectOutHandle] - STREQB R0, [R0, #RedirectInHandle] - STRNEB R0, [R0, #RedirectOutHandle] - CMP R1, #0 - SWINE XOS_Find ; close any previous File - MOV R12, R1 ; don't really care if handle was invalid - LDR R1, =RedirectBuff - ORR R0, R2, #open_mustopen + open_nodir - SWI XOS_Find ; Open the File - BVS abort_redirect ; bad name etc - CMP R0, #0 ; worked? - BEQ %FT63 - CMP R2, #&40 - MOV R1, #0 - STREQB R0, [R1, #RedirectInHandle] - BEQ %FT00 - STRNEB R0, [R1, #RedirectOutHandle] - MOVNE R0, #WrchV - ADRNEL R1, RedirectWrch - CMP R12, #0 ; Ensure only vectored the once - MOVEQ R2, #0 - SWIEQ XOS_Claim - BVS abort_redirect ; Claim will leave "Sysheap full" msg. -00 - LDR R2, [stack, #Proc_RegOffset] - CMP R2, #&C0 - EXITS NE - -; >> file, so move to EOF - - MOV R1, #0 - LDRB R1, [R1, #RedirectOutHandle] - MOV R0, #2 ; read extent - SWI XOS_Args - MOVVC R0, #1 ; write ptr - SWIVC XOS_Args - EXITS VC - - B abort_redirect - - MakeErrorBlock RedirectFail - -63 ADR R0, ErrorBlock_RedirectFail - [ International - BL TranslateError - ] -abort_redirect ; current error set - EXITVS - - -ParseRDNSpec ROUT -; In : R11 points at string to test. -; Out : EQ/NE for "is it a rdnspec?". V always clear. -; If EQ : R11 points after filename -; R10 points at start of filename -; R1=&40 => redirect input, -; =&80 => redirect output, -; =&C0 => redirect & append output - MOV R1, #&40 -01 LDRB R10, [R11], #1 - CMP R10, #" " - BEQ %BT01 ; skip leading spaces - CMP R10, #"<" - BEQ %FT04 - CMP R10, #">" - MOVNE PC, lr - MOV R1, #&80 - LDRB R10, [R11], #1 - CMP R10, #">" - MOVEQ R1, #&C0 -04 LDREQB R10, [R11], #1 - CMP R10, #" " - MOVNE PC, lr - SUB R10, R11, #1 ; filename start ptr - Push "R0" -02 LDRB R0, [R11], #1 - CMP R0, #" " - BGT %BT02 - Pull "R0" - MOV PC, lr ; it's EQ if had space at end. - - MakeErrorBlock StackFull - -OscliStackFull - ADR R0, ErrorBlock_StackFull - [ International - BL TranslateError - ] - [ No26bitCode - SETV - Pull "pc" - | - Pull "lr" - ORRS PC, lr, #V_bit - ] - -;****************************************************************************** -; Main OSCLI code - -VecOsCli ROUT - -; first check for rheum on the stack. -; Oscli will have pushed 5 registers when it calls module code : let's -; guarantee 256 bytes (=64 registers) for the module code -; so check half a K left, leaving 236 bytes for any interrupt processing. - - CheckSpaceOnStack 512, OscliStackFull, R10 - - Push "R0-R2" ; lr on stack from caller - -; first skip * and space - -01 LDRB R10, [R0], #1 - CMP R10, #" " - CMPNE R10, #"*" - BEQ %BT01 - CMP R10, #"%" - LDREQB R10, [R0] ; fixed 29-Mar-89; was LDREQ - CMP R10, #13 - CMPNE R10, #10 - CMPNE R10, #0 - CMPNE R10, #"|" - Pull "R0-R2, PC", EQ ; V clear return - -; now check for redirection. -; Redirection setter ::= "{ " [ >= 1 Redirection spec] "}" -; where -; Redirection spec ::= "> "filename" " | "< "filename" " | ">> "filename" " - [ LongCommandLines -; Also check terminator in first LongCLISize chars. - | -; Also check terminator in first 256 chars. - ] - SUB R11, R0, #1 - MOV R1, #0 - [ LongCommandLines - ADD R2, R0, #LongCLISize - | - ADD R2, R0, #256 - ] -02 LDRB R10, [R11], #1 - CMP R11, R2 - BEQ OscliLineTooLong - CMP R10, #13 - CMPNE R10, #10 - CMPNE R10, #0 - BEQ %FT58 - CMP R10, #"""" - EOREQ R1, R1, R10 - CMP R10, #"{" - CMPEQ R1, #0 - BNE %BT02 - Push "R11" - LDRB R10, [R11], #1 - CMP R10, #" " - BLEQ ParseRDNSpec - Pull "R11", NE - BNE %BT02 -60 BL ParseRDNSpec - BEQ %BT60 - CMP R10, #"}" - Pull "R11" - BNE %BT02 -; R11 points 1 char after { - Push "R5, R6" - BL GetOscliBuffer ; get a buffer - SUB R0, R0, #1 - MOV R2, #0 -50 LDRB R10, [R0], #1 - CMP R0, R11 - STRNEB R10, [R5, R2] - ADDNE R2, R2, #1 - BNE %BT50 - -61 BL ParseRDNSpec - BLEQ doredirect - BVS RedirectionError ; close any redirection set up - BEQ %BT61 - -53 LDRB R10, [R11], #1 - CMP R10, #" " - BEQ %BT53 - SUB R11, R11, #1 - -52 LDRB R10, [R11], #1 - STRB R10, [R5, R2] - ADD R2, R2, #1 - CMP R2, #OscliBuffSize - BEQ %FT51 - CMP R10, #13 - CMPNE R10, #10 - CMPNE R10, #0 - BNE %BT52 - MOV R2, R6 ; buffer UID - ADD R0, R5, #1 ; point after 1st char. - Pull "R5, R6" - B %FT03 - -51 MOV R2, R6 ; longer than 256 - ADR R0, ErrorBlock_OscliLongLine - [ International - BL TranslateError - ] -RedirectionError - BL ReleaseBuff - BL OscliTidy ; shut down the redirection just done. - Pull "R5, R6" -OscliFailure - STR R0, [stack] - [ No26bitCode - SETV - Pull "R0-R2, PC" - | - Pull "R0-R2, lr" - ORRS PC, lr, #V_bit - ] - -OscliLineTooLong - ADR R0, ErrorBlock_OscliLongLine - [ International - BL TranslateError - ] - B OscliFailure - MakeErrorBlock OscliLongLine - -58 MOV R2, #-1 ; naff buffer UID. -; Redirection dealt with. R0 points after 1st ch command -03 - Push "R2" ; save buffer UID - -; now check for filing system name as prefix - Push "R3" - MOV R3, #0 ; j.i.c. fileswitch is dead!! - SUB R1, R0, #1 - MOV R0, #FSControl_StarMinus - SWI XOS_FSControl - -; here we have: -; V set if -nafffsname encountered -; VC: R2 = -1 if no fs name found -; R3 = 0 if no specials encountered - - BVS letmodprefatit - CMP R3, #0 - BEQ letmodprefatit - Pull "R3" - Push "R2" ; save "temp FS set" indicator - ADR R0, ErrorBlock_NoOscliSpecials - [ International - BL TranslateError - | - SETV - ] - B OscliExit - MakeErrorBlock NoOscliSpecials - -letmodprefatit - Pull "R3" - Push "R2" ; save "temp FS set" indicator - BL CheckForModuleAsPrefix - BVS OscliExit - -; special char checks -pfssss LDRB R10, [R1], #1 - CMP R10, #" " - BEQ pfssss - SUB R0, R1, #1 - CMP R2, #-1 - RSBLT R11, R2, #0 - Push "R2",LT - BLT OnlyOneModuleWanted - - CMP R10, #"/" - BEQ %FT06 - -; see if skip macro expansion - CMP R10, #"%" - LDREQB R10, [R0], #1 - BEQ %FT05 - - CMP R10, #"." ; fudge . - BEQ %FT07 - -; try macro expansion : if find it, expand into a buffer. -; Also scan for parameters while expanding. -; R0 ptr to command, R10 first char. -; If success : Recursively call OSCLI for each line in expansion. - - Push "R0, R3-R6" - - [ Oscli_QuickAliases - ; - ;at least make a vague attempt not to run like a drain - since we can do a binary - ;chop search for an exactly known var name, do this unless command is abbreviated - ; - ADR R6,AliasStr_QA - LDR R3,=AliasExpansionBuffer ; construct the alias name here - MOV R5,#6 -oqa_loop1 ; bung in "ALIAS$" - LDRB R4,[R6],#1 - STRB R4,[R3],#1 - SUBS R5,R5,#1 - BNE oqa_loop1 - MOV R6,R0 - ADRL R2, Up_ItAndTerm_Check_Table -oqa_loop2 ; bung in command, upper cased - LDRB R4,[R6],#1 - CMP R4,#&80 ; char in table ? - LDRCCB R4,[R2,R4] - STRB R4,[R3],#1 - CMP R4,#0 - BNE oqa_loop2 - LDRB R4,[R3,#-2] ; pick up last char of command - CMP R4,#"." - BEQ oqa_treacletime ; it's abbreviated, go to slow code - LDR R3,=AliasExpansionBuffer - Push "r6,r7" - BL VarFindIt_QA ; quick binary chop type stuff - Pull "r6,r7",EQ - BEQ oqa_quicksilvertime_noalias ; no alias - carry on -;found alias - MOV R0,#-1 ; special, VarFindIt skipping call (r5,r6,r7 from VarFindIt_QA) - MOV R1,R3 ; output buffer - [ LongCommandLines - MOV R2,#LongCLISize - | - MOV R2,#256 - ] - MOV R3,#0 - MOV R4,#VarType_Expanded - SWI XOS_ReadVarVal ; expand it - Pull "r6,r7" - SUB R6,R6,#1 ; arg ptr - B oqa_quicksilvertime_alias -oqa_treacletime -; - ] ;Oscli_Quickaliases - - [ International - MOV R3,#0 - LDRB R6,[R3,#ErrorSemaphore] ; We are about to get lots of buffer overflow errors, - SUB R6,R6,#1 - STRB R6,[R3,#ErrorSemaphore] - ] - MOV R6, R0 - MOV R3, #:LEN: "Alias$" -31 SUB R3, R3, #:LEN: "Alias$" - MOV R2, #-1 ; negative length means just look for it. - ADRL R0, AliasStr - SWI XOS_ReadVarVal - CMP R2, #0 ; V always set anyway - [ International - LDREQB R0,[R2,#ErrorSemaphore] - ADDEQ R0,R0,#1 - STREQB R0,[R2,#ErrorSemaphore] - ] - BEQ %FT10 - - ADD R3, R3, #:LEN: "Alias$" - -; match $R6 with $R3 - - MOV R1, #0 ; offset -32 LDRB R4, [R6, R1] - LDRB R5, [R3, R1] - CMP R4, #&80 ; in table ? - ADRCCL R2, Up_ItAndTerm_Check_Table - LDRCCB R4, [R2, R4] - CMP R4, #" " - CMPLE R5, #" " - BLE %FT33 - UpperCase R5, R2 - CMP R4, R5 - ADDEQ R1, R1, #1 - BEQ %BT32 - CMP R1, #0 - BEQ %BT31 ; failed - CMP R5, #" " - BLE %BT31 - CMP R4, #"." - BNE %BT31 - ADD R1, R1, #1 -33 -; success : copy name, read value - - [ International - MOV R4,#0 - LDRB R0,[R4,#ErrorSemaphore] - ADD R0,R0,#1 - STRB R0,[R4,#ErrorSemaphore] ; We can go back to translating errors. - ] - - SUB R3, R3, #:LEN: "Alias$" -99 LDR R0, =AliasExpansionBuffer - ADD R6, R6, R1 ; save arglist ptr - MOV R4, #0 -34 LDRB R5, [R3], #1 - STRB R5, [R0, R4] - ADD R4, R4, #1 - CMP R5, #0 - BNE %BT34 - MOV R1, R0 ; output buffer same as input! - [ LongCommandLines - MOV R2, #LongCLISize - | - MOV R2, #256 - ] - MOV R3, #0 - MOV R4, #VarType_Expanded - SWI XOS_ReadVarVal - [ Oscli_QuickAliases -oqa_quicksilvertime_alias - ] - BVS AliasOscliTooLong - MOV R3, #13 - STRB R3, [R1, R2] - - MOV R3, R1 - MOV R0, R6 ; arglist - MOV R4, R2 ; no of chars got. - BL GetOscliBuffer ; gives buffer ptr in R5, ID in R6 - MOV R1, R5 - MOV R2, #OscliBuffSize - MOV R5, #0 - SWI XOS_SubstituteArgs32 - BVS AliasOscliTooLong - -; Whew! Now ready to recursively call OSCLI with all lines in the buffer. - MOV R0, R1 - ADD R2, R1, R2 -43 SWI XOS_CLI - BVS %FT46 - CheckUID R6, R1 ; check buffer still valid. - BLS FailInAlias -44 LDRB R1, [R0], #1 - CMP R1, #13 - CMPNE R1, #10 - CMPNE R1, #0 - BNE %BT44 - CMP R0, R2 - BLO %BT43 - MOV R2, R6 - BL ReleaseBuff ; release buffer, UID in R2 - Pull "R0, R3-R6" - CLRV - B OscliExit - - MakeErrorBlock OscliTooHard - -FailInAlias - CheckUID R2, R1 - BLGT ReleaseBuff - ADR R0, ErrorBlock_OscliTooHard - [ International - BL TranslateError - ] -46 STR R0, [stack] - Pull "R0, R3-R6" - SETV - B OscliExit - -AliasOscliTooLong - MOV R2, R6 ; buffer UID - BL ReleaseBuff - Pull "R0, R3-R6" - ADRL R0, ErrorBlock_OscliLongLine - [ International - BL TranslateError - | - SETV - ] - B OscliExit - - LTORG - - [ Oscli_QuickAliases -AliasStr_QA = "ALIAS$", 0 - ] -AliasStr = "Alias$*", 0 -AliasDot = "Alias$" -dotstring = ".", 0 - ALIGN - - [ Oscli_QuickAliases -oqa_quicksilvertime_noalias - ] -10 ; Failed macro expansion. - Pull "R0, R3-R6" - -; try for system command first. -05 LDRB R1, [R0] ; quick check for . tho - CMP R1, #"." - BEQ PercentDot - - [ Oscli_HashedCommands - BL Oscli_cmd_hashsum ; => hash value in r1 - MOV r2,#0 - STR r1,[r2,#Oscli_CmdHashSum] - CMP r1,#0 - BEQ oscli_sysabbrevation - BL SysCommsHashedLookup - B oscli_syslook_done -oscli_sysabbrevation - ] - ADRL R1, SysCommsModule - MOV R2, #SCHCTab-SysCommsModule - SEC ; carry set means sys module - BL ModCommsLookUp -oscli_syslook_done - BCS OscliExit - - [ Oscli_HashedCommands - ;now try UtilityModule, if non-abbreviated command - Push "R2" - MOV r2,#0 - LDR r1,[r2,#Oscli_CmdHashSum] - CMP r1,#0 - Pull "R2",EQ - BEQ oscli_modabbreviation - BL UtilCommsHashedLookup - ADDCS stack, stack, #4 ;discard R2 - BCS OscliExit - ;now try list of modules on hash value - MOV r2,#0 - LDR r1,[r2,#Oscli_CmdHashSum] - AND r1,r1,#Oscli_MHashValMask - LDR r11,[r2,#Oscli_CmdHashLists] - CMP r11,#0 - LDRNE r11,[r11,r1,LSL #2] - CMPNE r11,#0 - BEQ %FT75 - Push "r3,r4" - ADD r3,r11,#8 - LDR r4,[r11,#4] - ADD r4,r4,#1 -oscli_hlist_loop - SUBS r4,r4,#1 - Pull "r3,r4",EQ - BEQ %FT75 - LDR R2,[stack,#2*4] - CMP R2, #0 - Pull "r3,r4",MI - BMI OneModule_Failed - LDR R11,[R3],#4 - LDR R1, [R11, #Module_code_pointer] - LDR R2, [R1, #Module_HC_Table] - CMP R2, #0 - BEQ oscli_hlist_loop - LDR R12, [R11, #Module_incarnation_list] ; preferred life - ADD R12, R12, #Incarnation_Workspace - CLC - BL ModCommsLookUp - BCC oscli_hlist_loop - Pull "r3,r4" - ADD stack,stack,#4 - B OscliExit -oscli_modabbreviation - ] ;Oscli_HashedCommands - -; now try looking round the modules. - MOV R11, #Module_List - Push "R2" -74 LDR R2, [stack] - CMP R2, #0 - BMI OneModule_Failed - LDR R11, [R11, #Module_chain_Link] - CMP R11, #0 - BEQ %FT75 -OnlyOneModuleWanted - LDR R1, [R11, #Module_code_pointer] - LDR R2, [R1, #Module_HC_Table] - CMP R2, #0 - BEQ %BT74 - LDR R12, [R11, #Module_incarnation_list] ; preferred life - ADD R12, R12, #Incarnation_Workspace - CLC - BL ModCommsLookUp - BCC %BT74 - ADD stack, stack, #4 ; discard R2 - B OscliExit - -75 - ; not in a module : try for current filing system command - STR R0, [stack] ; pull R2, push R0 - MOV R0, #FSControl_ReadModuleBase - SWI XOS_FSControl - Pull "R0" - CMP R1, #0 - BEQ NoFSCommands ; no selected FS! - MOV R12, R2 ; module's workspace ptr - LDR R2, [R1, #Module_HC_Table] - CMP R2, #0 - BEQ SecondaryFSCTab - ORR R2, R2, #&80000000 ; FS command needed flag - CLC - BL ModCommsLookUp - BCC SecondaryFSCTab - B OscliExit - -SecondaryFSCTab - Push "R0" - MOV R0, #FSControl_ReadSecondaryModuleBase - SWI XOS_FSControl - Pull "R0" - MOVVS R1, #0 - CMP R1, #0 - BEQ NoFSCommands - MOV R12, R2 ; module's workspace ptr - LDR R2, [R1, #Module_HC_Table] - CMP R2, #0 - BEQ NoFSCommands - ORR R2, R2, #&80000000 ; FS command needed flag - CLC - BL ModCommsLookUp - BCC NoFSCommands - B OscliExit - -NoFSCommands - MOV R1, #Service_UKCommand - BL Issue_Service - CMP R1, #0 - BNE UKCNotClaimed - CMP R0, #0 ; any error? - SETV NE ; V clear if EQ - B OscliExit - -OneModule_Failed - ADD stack, stack, #4 - ADRL R0, ErrorBlock_BadCommand - [ International - BL TranslateError - | - SETV - ] - B OscliExit - -UKCNotClaimed - MOV R1, R0 -DoFSCV_Run - MOV R0, #FSControl_RUN -71 SWI XOS_FSControl -OscliExit - Pull "R2" - SavePSR R1 - Push "R0" - CMP R2, #0 ; -ve means no FS selected. - MOVGE R0, #FSControl_RestoreCurrent - SWIGE XOS_FSControl - Pull "R0" - - Pull "R2" - CMP R2, #-1 - BEQ %FT80 - BL ReleaseBuff - BL RemoveOscliCharJobs ; shut down redirection -80 TST R1, #V_bit - BNE %FT81 - CLRV - Pull "R0-R2, pc" -81 - SETV - ADD sp, sp, #4 - Pull "R1-R2, pc" - -06 ADD R1, R0, #1 ; */ so skip the /, do RUN reason code - B DoFSCV_Run - -07 - Push "R0, R3-R6" - MOV R6, R0 - ADRL R0, AliasDot - MOV R3, #0 - MOV R2, #-1 ; negative length means just look for it. - SWI XOS_ReadVarVal - CMP R2, #0 ; V always set anyway - MOVNE R1, #1 ; index to step past . - BNE %BT99 - Pull "R0, R3-R6" -PercentDot ; entry for *%. - ADD R1, R0, #1 - MOV R0, #FSControl_CAT ; *., skip . - B %BT71 - -;*************************************************************************** - - [ Oscli_HashedCommands -; -; - routine to compute hash value for unabbreviated commands -; - does not apply mask to hash value (since different hash widths are -; required in different cases) -; -; hash value = sum of all chars of command, excluding terminator, all -; chars being processed through Up_ItAndTerm_Check_Table -; -; entry: -; R0 -> command -; exit: -; R1 = hash value, or 0 if invalid (abbreviation encountered) -; -Oscli_cmd_hashsum ROUT - Push "r0,r2-r3,lr" - MOV r1,#0 - ADRL r2, Up_ItAndTerm_Check_Table - B %FT15 -10 - ADD r1,r1,r3 -15 - LDRB r3,[r0],#1 - CMP r3,#&80 - LDRCCB r3,[r2,r3] - CMP r3,#"." - BEQ %FT30 - CMP r3,#0 - BNE %BT10 -20 - Pull "r0,r2-r3,PC" -30 - MOV r1,#0 - Pull "r0,r2-r3,PC" -; -;special entry of ModCommsLookUp, for hashed lookup of commands in SysCommsModule -;entry: R0 -> command, r1 = hash value of command -; -SysCommsHashedLookup ROUT - Push "R0, R2-R10, lr" -; -;first a fudge, to allow old syntax (no space before first, numeric, parameter) -;for *fx, *key, *opt and *tv - look for '&' or a numeric char at R0 + 2, 3 or 4 -; - MOV R4, #2 -schl_fudgeloop - LDRB R2, [R0,R4] - CMP R2, #' ' - BLS schl_nofudge - CMP R2, #'&' - BEQ schl_fudge - CMP R2, #'0' - BLO schl_nofudgesofar - CMP R2, #'9' - BLS schl_fudge -schl_nofudgesofar - ADD R4, R4, #1 - CMP R4, #4 - BLS schl_fudgeloop -schl_nofudge - AND R4, R1,#Oscli_CHashValMask ;hash value, masked for command hashing - ADRL R1, SysCommsModule - ADRL R2, SysCoHashedCmdTab - LDR R2, [R2, R4, LSL #2] ;command list for this hash value - SEC ;carry set means sys module - B ModCommsLookUp_AltEntry -schl_fudge - ADRL R1, SysCommsModule - ADRL R2, SHC_fudgeulike - SUB R2, R2, R1 ;fudge command list (offset) - SEC ;carry set means sys module - B ModCommsLookUp_AltEntry - -; -;special entry of ModCommsLookUp, for hashed lookup of commands in UtilityMod -;entry: R0 -> command, r1 = hash value of command -; - -UtilCommsHashedLookup ROUT - Push "R0, R2-R10, lr" - AND R4, R1,#Oscli_CHashValMask ;hash value, masked for command hashing - ADRL R1, UtilityMod - ADRL R2, UtilHashedCmdTab - LDR R2, [R2, R4, LSL #2] ;command list for this hash value - CLC - B ModCommsLookUp_AltEntry -; - ] ;Oscli_HashedCommands - -;*************************************************************************** - -; Routine to look through a module table for a command, and call it. -; Set up R12 yourself if needed. -; R0 points at command to find -; R1 points at module -; R2 offset of command table : top bit set for "want FS command" -; C set means allow messy matching, i.e. it's the system command table - -; Return C set if found and called, V flag from code called -; Might not return if module starts up as current object. - -ModCommsLookUp ROUT - Push "R0, R2-R10, lr" - [ Oscli_HashedCommands -ModCommsLookUp_AltEntry - ] - MOV R4, #0 ; want all flags clear - TEQ R2, #0 ; don't corrupt C! - MOVMI R4, #FS_Command_Flag - BICMI R2, R2, #&80000000 - BL FindItem - BLCS %FT05 - CLC ; clears C and V - Pull "R0, R2-R10, PC" -05 - Push r4 ; save pointer in case needed for syntax mess - -; check number of arguments, error with syntaxmessage if naff. - - ADD R2, R2, R1 ; get R2 back to pointer. - ADD R0, R0, R3 ; point at terminator. -09 LDRB R4, [R0], #1 - CMP R4, #" " ; skip spaces. - BEQ %BT09 - MOV R3, R1 ; hang on to module ptr. - MOV R1, #0 ; no of parms. - MOV R7, #-1 ; flag for buffer got for GSTRANSing - - MOV R6, R0 - SUB R0, R0, #1 - -; Now we have : -; R0 -> commtail, ready for module -; R1 number of parameters -; R2 -> info block for command -; R3 -> module -; R4 current char -; R5 execute offset -; R6 working commtail ptr -; R7 -1 or buffer UID -; R8 becomes gstrans map -; R9 may be a workin gstrans map copy -; R10 may be a working buffer ptr for copying - - LDRB R8, [R2, #5] ; get gstrans_map - MOVS R9, R8 - BEQ nogstransingta - - Push "R2, R5, R6" - BL GetOscliBuffer - MOV R0, R5 ; buffer ptr - MOV R7, R6 ; buffer UID - MOV R10, #0 ; buffer offset for copying - Pull "R2, R5, R6" - -nogstransingta - CMP R4, #13 ; check for more to scan - CMPNE R4, #10 - CMPNE R4, #0 - BEQ %FT12 - - MOVS R9, R9, LSR #1 - BCC stripnextparm - - ; gstrans next ; scan afterwards for naffchars - Push "R0-R2" - - ADD R1, R0, R10 ; buffer pointer - RSB R2, R10, #OscliBuffSize ; room left - ORR R2, R2, #GS_Spc_term - - SUB R0, R6, #1 ; parameter pointer - SWI XOS_GSTrans - BCS buffer_overflowed_oh_bother - BVS bad_string - - CMP R2, #0 - BEQ preversion_detectified ; empty expansions are naff - ADD R10, R10, R2 - ADD R6, R1, R2 -nastycharscan - LDRB R2, [R1], #1 - CMP R2, #&7F - CMPNE R2, #" " - BLE preversion_detectified - CMP R1, R6 - BLO nastycharscan - - MOV R6, R0 - Pull "R0-R2" - B next_parameter - -preversion_detectified - ADR R0, ErrorBlock_BadParmString - [ International - BL TranslateError - ] - B pgstcomm -buffer_overflowed_oh_bother - ADRL R0, ErrorBlock_OscliLongLine - [ International - BL TranslateError - ] - B pgstcomm -bad_string - ADR R0, ErrorBlock_BadParmString - [ International - BL TranslateError - ] -pgstcomm - STR R0, [stack] - MOV R2, R7 - BL ReleaseBuff - Pull "R0-R2, r4" - B unpleasantness_in_ModCommsLookUp - - MakeErrorBlock BadParmString - -AddCharForGSTP - CMP R8, #0 - MOVEQ PC, lr - CMP R10, #OscliBuffSize - STRLTB R4, [R0, R10] - ADDLT R10, R10, #1 - MOVLT PC, lr - Push "R0-R2" - B buffer_overflowed_oh_bother - -stripnextparm - Push "R11" - CMP R4, #"""" - MOVEQ R11, #&80000000 - ORREQ R1, R1, R11 - MOVNE R11, #0 -stripnextchar - BL AddCharForGSTP - LDRB R4, [R6], #1 - CMP R4, #"""" - EOREQ R1, R1, R11 - CMP R4, #" " - TSTEQ R1, #&80000000 - BEQ parmfinished - CMP R4, #13 - CMPNE R4, #10 - CMPNE R4, #0 - BNE stripnextchar -parmfinished - BIC R1, R1, #&80000000 - Pull "R11" - -next_parameter - MOV R4, #" " - BL AddCharForGSTP - SUB R6, R6, #1 - -30 LDRB R4, [R6], #1 - CMP R4, #" " - BEQ %BT30 - - ADD R1, R1, #1 - B nogstransingta ; next parameter - - ; parameters counted : check number - -12 BL AddCharForGSTP ; terminate the copy - - BIC R1, R1, #&80000000 - LDR R4, [R2, #4] - MOV R6, R4, LSR #16 ; max no parms - AND R6, R6, #&FF - AND R4, R4, #&FF ; min no parms - CMP R1, R4 - CMPGE R6, R1 - BLT %FT11 - - ; checks finished : call the man. - - Push "R7" ; j.i.c. module writer can't read - - MOV lr, PC ; make link - ADD PC, R3, R5 ; and call - - Pull "R2, r4" - BL ReleaseBuff ; discard buffer got for GSTRANSing - - MRS R10, CPSR - ORR R10, R10, #C_bit ; set C carefully - MSR CPSR_f, R10 - STRVS R0, [stack] - Pull "R0, R2-R10, pc" - -; Return a command syntax error. First issue Service_SyntaxError for translation -11 - [ International ; Internationalize syntax error messages - Pull "r4" ; r4-> command string in module - MOV r1, #Service_SyntaxError ; r2->info block for command, r3->module - BL Issue_Service ; Issue SyntaxError service for possible translation - CMP r1, #0 ; Service claimed? - BEQ unpleasantness_in_ModCommsLookUp ; Yes then r0-> error block - - Push "r4" ; Save -> command string - ] - - LDR r4, [r2, #4] - MOV r7, r2 - BL GetOscliBuffer ; get space for error - MOV R2, #ErrorNumber_BadNoParms - STR R2, [R5] - LDR R2, [R7, #8] - CMP R2, #0 - ADREQ R0, %FT13 ; default error message - ADDNE R0, R2, R3 ; point at message - ORREQ r4, r4, #International_Help - TST r4, #International_Help - ADREQL r4, MOSdictionary - BEQ %FT37 - MOV r7, r0 - SUB sp, sp, #16 - LDR r2, [r3, #-4] - LDR r0, [r3, #Module_MsgFile] - TST r0, #12,2 - CMPEQ r0, #1 - CMPCS r2, r0 - MOVLS r0, #0 - BLS %FT33 - ADD r1, r3, r0 - MOV r2, #0 - MOV r0, sp - SWI XMessageTrans_OpenFile - MOVVS r0, #0 -33 MOV r1, r7 - MOV r7, r0 - MOV r2, #0 - SWI XMessageTrans_Lookup - ADDVS r2, r0, #4 - SWI XMessageTrans_Dictionary - ADDVS r2, r0, #4 - MOV r4, r0 - MOV r0, r2 - LDR r2, [sp, #16] - ADD r1, r5, #4 - BL expandsyntaxmessage - MOVS r0, r7 - SWINE XMessageTrans_CloseFile - ADD sp, sp, #16 - Pull r2 - B %FT39 -37 - Pull r2 - ADD r1, r5, #4 - BL expandsyntaxmessage -39 - MOV r0, r5 - -unpleasantness_in_ModCommsLookUp - STR R0, [stack] - MSR CPSR_f, #V_bit+C_bit - Pull "R0, R2-R10, PC" -13 - DCB "NumParm", 0 - - ALIGN - -expandsyntaxmessage - LDRB R3, [R0], #1 - CMP r3, #TokenEscapeChar - BEQ esm_tok - STRB R3, [R1], #1 - CMP R3, #0 - BNE expandsyntaxmessage - SUB r1, r1, #1 - MOV pc, lr - -esm_tok LDRB r3, [r0], #1 - Push "r0, lr" - CMP r3, #0 - MOVEQ r0, r2 - BEQ esm001 - MOV r0, r4 -esmlp SUBS r3, r3, #1 - LDRNEB r14, [r0] ; ECN: Use R14 instead of R4 as using R4 corrupts - ADDNE r0, r0, r14 ; the dictionary pointer thus disallowing recusive tokens - BNE esmlp - ADD r0, r0, #1 -esm001 BL expandsyntaxmessage - Pull "r0, lr" - B expandsyntaxmessage - -;--------------------------------------------------------------------------- -; routine to just find a keyword in a table that has the flags specified. -; R0 points at command to find -; R1 points at module -; R2 offset of command table -; R4 word to EOR with flags : demand 0 result for match -; C set means allow messy matching, i.e. it's the system command table -; Uses R2-R5 - -; Return C set if found : R5 is execute offset, R3 length of string -; R2 is offset of execute offset of field found -; r4 is command pointer - -FindItem ROUT - Push "R4, R6, R7" - MRS R7, CPSR ; to remember C flag (32-bit clean) - ADD R2, R2, R1 - LDRB R4, [R2] - CMP R4, #0 - BEQ FindItem_EOTab -05 MOV R3, #0 ; offset -01 LDRB R4, [R0, R3] - LDRB R5, [R2, r3] - CMP R4, #&80 ; in table ? - ADRCC R6, Up_ItAndTerm_Check_Table - LDRCCB R4, [R6, R4] - CMP R4, #32 - CMPLE R5, #32 - BLE %FT04 ; matched, and we're at the terminator - UpperCase R5, R6 - CMP R4, R5 - ADDEQ R3, R3, #1 - BEQ %BT01 - CMP R4, #"." ; success if abbreviation - BEQ %FT02 - TST R7, #C_bit ; C flag on entry - BEQ %FT07 ; nomatch - CMP R5, #32 - BGT %FT07 - CMP R4, #"A" - RSBGES R6, R4, #"Z" - BLT %FT04 ; matched, at terminator -07 LDRB R5, [R2], #1 - CMP R5, #32 - BGT %BT07 ; skip to terminator - ADD R2, R2, #3 - BIC R2, R2, #3 ; ALIGN -06 ADD R2, R2, #16 ; !!! DEPENDANT ON TABLE FORMAT!!! - LDRB R5, [R2] - CMP R5, #0 - BNE %BT05 -FindItem_EOTab - Pull "R4, R6, R7" - CLC - MOV PC, lr ; back with not found. - -Up_ItAndTerm_Check_Table -; Table to uppercase and test for terminators for passed * commands -; 0 1 2 3 4 5 6 7 8 9 A B C D E F - = 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ; 0 - = 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ; 1 - = 0 , "!", 0 , "#" , 0, 0, 0, "'", "(", ")", "*" , "+", 0 , "-", ".", "/" ; 2 - = "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", 0, ";", 0 , "=", 0 , "?" ; 3 - = "@", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O" ; 4 - = "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "[", 0, "]", 0, "_" ; 5 - = "`", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O" ; 6 - = "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "{", 0 , "}", "~", 0 ; 7 - -; WHILE . < Up_ItAndTerm_Check_Table+256 ; top bit stuff done by CMP #&80 -; = . - Up_ItAndTerm_Check_Table -; WEND ; entry for chars > 127 = char - -02 CMP R5, #32 ; only success if $R2 not terminated. - BLE %BT07 - ADD R3, R3, #1 ; skip . -04 MOV r6, r2 - ADD r2, r2, r3 -08 LDRB R5, [R2], #1 - CMP R5, #0 - BNE %BT08 ; demand NULL terminator - ADD R2, R2, #3 - BIC R2, R2, #3 ; ALIGN - LDR R5, [R2, #4] ; get information word - - AND R5, R5, #&C0000000 :AND::NOT:Help_Is_Code_Flag - ; clear param numbers/low flags. - LDR R4, [stack] - EORS R5, R5, R4 - BNE %BT06 ; flags don't match - - LDR R5, [R2] ; get Execute offset - CMP R5, #0 - BEQ %BT06 ; not a command - STR r6, [stack] ; return r4 - Pull "R4, R6, R7" - SUB R2, R2, R1 ; get back to offset. - SEC - MOV PC, lr - -;**************************************************************************** -; variegated routines -;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -OscliInit -; circular buffer initialisation : -; botUID := topUID := 0 ; currend := circbuffstart -; Redirection handles := 0 - MOV R0, #0 - STR R0, [R0, #OscliCBbotUID] - STR R0, [R0, #OscliCBtopUID] - LDR R1, =OscliCircBuffStart - STR R1, [R0, #OscliCBcurrend] - STRB R0, [R0, #RedirectInHandle] - STRB R0, [R0, #RedirectOutHandle] - MOV PC, R14 - -; buffer is valid if botUID < UID - - -; GetOscliBuffer used in module handler to get error buffers - saves workspace! - -GetOscliBuffer ROUT - ; return ptr in R5 to next buffer in Oscli's circular job - ; UID in R6 - ; corrupts R2 - -; currend +:= 256 - MOV R2, #0 - LDR R5, [R2, #OscliCBcurrend] - ADD R5, R5, #OscliBuffSize - -; IF currend >= circbufflimit -; THEN currend := circbuffstart - LDR R6, =OscliCircBuffLimit - CMP R5, R6 - LDRHS R5, =OscliCircBuffStart - STR R5, [R2, #OscliCBcurrend] - -; topUID +:= 1 - LDR R6, [R2, #OscliCBtopUID] - ADD R6, R6, #1 - STR R6, [R2, #OscliCBtopUID] -; IF topUID > botUID + noBuffers -; THEN botUID +:= 1 - LDR R5, [R2, #OscliCBbotUID] - SUB R2, R6, R5 - CMP R2, #OscliNoBuffs - MOV R2, #0 - ADDGE R5, R5, #1 - STRGE R5, [R2, #OscliCBbotUID] - -; RETURN currend, topUID - LDR R5, [R2, #OscliCBcurrend] - MOV PC, lr - - -ReleaseBuff ; take UID in R2, check whether can step back topUID - EntryS "R1-R4" - MOV R1, #0 - LDR R3, [R1, #OscliCBtopUID] - LDR R4, [R1, #OscliCBbotUID] -; IF UID = topUID AND topUID <> botUID - CMP R3, R4 - EXITS EQ - CMP R2, R3 - EXITS NE -; THEN $( -; topUID -:= 1 - SUB R3, R3, #1 - STR R3, [R1, #OscliCBtopUID] - -; IF currend = circbuffstart THEN currend := circbufflimit - LDR R3, [R1, #OscliCBcurrend] - LDR R4, =OscliCircBuffStart - CMP R3, R4 - LDREQ R3, =OscliCircBuffLimit -; currend -:= 256 - SUB R3, R3, #OscliBuffSize - STR R3, [R1, #OscliCBcurrend] - EXITS - - LTORG ; needed now not at top level - -OscliRestoreFS - Push "R0, lr" - MOV R0, #FSControl_RestoreCurrent - SWI XOS_FSControl - Pull "R0, PC" - -OscliTidy ROUT ; shut down redirection, restore permanent FS - Push "lr" - BL RemoveOscliCharJobs - BL OscliRestoreFS - Pull "PC" - -RemoveOscliCharJobs ROUT - Push "R0-R2, lr" - MOV R0, #0 - LDRB R1, [R0, #RedirectInHandle] - CMP R1, #0 - STRNEB R0, [R0, #RedirectInHandle] - SWINE XOS_Find - MOV R0, #0 ; May have got error (discarded) - LDRB R1, [R0, #RedirectOutHandle] - CMP R1, #0 - STRNEB R0, [R0, #RedirectOutHandle] - SWINE XOS_Find - MOV R2, #0 - MOV R0, #WrchV - ADR R1, RedirectWrch - SWI XOS_Release - CLRV - Pull "R0-R2, PC" - -RedirectWrch ROUT - Push "R1, R2" - SavePSR R2 - MOV R1, #0 - LDRB R1, [R1, #RedirectOutHandle] - SWI XOS_BPut - RestPSR R2 ; VClear in entry psr - Pull "R1, R2, pc", VC - -RedirectError - BL RemoveOscliCharJobs - ORR R2, R2, #V_bit - RestPSR R2 - Pull "R1, R2, pc" - -; ************************************************************************** -; -; SWI OS_ChangeRedirection - Read/write redirection handles -; -; in: R0 = new input handle (0 => not redirected, -1 => leave alone) -; R1 = new output handle (0 => not redirected, -1 => leave alone) -; -; out: R0 = old input handle (0 => not redirected) -; R1 = old output handle (0 => not redirected) -; - -ChangeRedirection ROUT - MOV R12, #0 - LDRB R10, [R12, #RedirectInHandle] - LDRB R11, [R12, #RedirectOutHandle] - -; do input handle - - CMP R0, #&100 ; if out of range then just read - BCS %FT20 - - STRB R0, [R12, #RedirectInHandle] - -20 - -; do output handle - - CMP R1, #&100 ; if out of range then just read - BCS %FT40 - - STRB R1, [R12, #RedirectOutHandle] - CMP R1, #1 ; CS <=> (R1 non-zero) - TEQ R11, #0 ; NE <=> (R11 non-zero) - BHI %FT40 ; [both non-zero, skip] - - BCS %FT30 ; [just R1 non-zero, so claim] - BEQ %FT40 ; [both zero, skip] - -; R11 non-zero, R1 zero, so release vector - - Push "R0-R2, lr" ; set up registers for claim or release - MOV R0, #WrchV - ADR R1, RedirectWrch - MOV R2, #0 - SWI XOS_Release - STRVS R0, [sp, #0*4] - Pull "R0-R2, lr" - ORRVS lr, lr, #V_bit - ExitSWIHandler VS - B %FT40 - -; R11 zero, R1 non-zero, so claim vector - -30 - Push "R0-R2, lr" - MOV R0, #WrchV - ADR R1, RedirectWrch - MOV R2, #0 - SWI XOS_Claim - STRVS R0, [sp, #0*4] - Pull "R0-R2, lr" - ORRVS lr, lr, #V_bit - ExitSWIHandler VS - -40 - MOV R0, R10 - MOV R1, R11 - ExitSWIHandler - -;************************************************************************** -; Module selection -; Entered with V set if FileSwitch found a - : must get module or give error -; R2 >= 0 if filing system selected: do nothing -; R1 -> command prefix -; Out: R1 updated -; R2 = -1: no module -; R2 = -<larger>: R2 is selected module node -; Selected prefix also preferred - -CheckForModuleAsPrefix ROUT - EntryS "R0-R6" - ADDVS R1, R1, #1 ; skip - - MOVVS R2, #"-" - BVS %FT02 - CMP R2, #-1 - BNE %FT01 - MOV R2, #":" ; terminators for lookup - -02 ADR R5, %FT10 - STR R1, [stack, #Proc_RegOffset + 4] -03 LDRB R3, [R1], #1 - UpperCase R3, R4 - LDRB R4, [R5], #1 - CMP R3, R4 - BEQ %BT03 - CMP R4, #0 - LDRNE R1, [stack, #Proc_RegOffset + 4] - SUBEQ R1, R1, #1 - MOV R6, R1 - LDR R1, =AliasExpansionBuffer -05 LDRB R3, [R6], #1 - CMP R3, #"." ; disallow abbreviations: they're confusing! - CMPNE R3, #" " - BLE %FT01 - CMP R3, R2 - STRNEB R3, [R1], #1 - BNE %BT05 - - MOV R3, #0 - STRB R3, [R1] - - MOV R0, #ModHandReason_LookupName - LDR R1, =AliasExpansionBuffer - SWI XOS_Module - BVS %FT01 - MOV R2, R1 - LDR R1, =AliasExpansionBuffer - MOV R0, #ModHandReason_MakePreferred - SWI XOS_Module - - MOV R0, #Module_List -04 LDR R0, [R0] - SUBS R2, R2, #1 - BPL %BT04 - MOV R1, R6 ; point at rest of command line. - RSB R2, R0, #0 - STR R1, [stack, #Proc_RegOffset + 4] - STR R2, [stack, #Proc_RegOffset + 8] - EXITS VC - -01 - EXITS ; return fileswitch error if set -10 - = "MODULE#",0 - ALIGN - - LTORG - - END diff --git a/s/PMF/Buffer b/s/PMF/Buffer deleted file mode 100644 index a8046566..00000000 --- a/s/PMF/Buffer +++ /dev/null @@ -1,319 +0,0 @@ -; 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.Buffer - -; ***************************************************************************** -; -; NewInsV - Routine for InsVec -; -; in: R0 = character to be inserted -; R1 = buffer number -; -; out: R0, R1, R3-R12 preserved -; R2 undefined -; C=1 <=> insertion failed -; - -NewInsV ROUT - CMP R1, #NBuffers - MOVCS PC, R14 ; not known about, pass it on - - Push "R3-R5" - MOV R3, R1, LSL #2 ; make index a word index - ADR R2, BuffParms - ADD R2, R2, R3, LSL #1 - LDMIA R2, {R2, R5} ; get address, size - - LDR R4, [R3, #BuffInPtrs] - STRB R0, [R2, R4] ; store byte anyway - ADD R4, R4, #1 ; increment pointer - - TEQ R4, R5 - MOVEQ R4, #0 - - LDR R5, [R3, #BuffOutPtrs] ; does inptr=outptr ? - CMP R4, R5 ; C=1 <=> R4 >= R5 - CMPHI R5, R4 ; C=1 <=> R4 = R5 - STRCC R4, [R3, #BuffInPtrs] ; if not, then safe - - BCC %FT10 ; no event, cos not full - TEQ R1, #(Buff_Mouse :SHL: 2), 2 ; clear carry and test if mouse - CMPNE R1, #Buff_RS423Out ; C=1 => output buffer - BCS %FT10 ; no event, cos not input - - MOV R2, R0 ; put character in 'Y' - MOV R0, #Event_InputFull ; event number - BL OSEVEN ; preserves R0-R3 - MOV R0, R2 ; restore character - SEC ; indicate buffer full -10 - Pull "R3-R5,PC" ; claim call - -; ***************************************************************************** -; -; NewRemV - Routine for RemVec -; -; in: R1 = buffer number (0 => keyboard buffer) -; V=0 => remove character -; V=1 => examine only -; -; out: R0 = R2 = next character for examine option or character removed -; R1, R3-R12 preserved -; C=1 <=> buffer was empty on entry -; - -NewRemV ROUT - BVS Examine - - [ No26bitCode - Push R14 - MRS R14, CPSR - CMP R1, #NBuffers - BLO %FT10 - MSR CPSR_f, R14 - Pull PC ; not known about, pass it on (preserving V) -10 - ADD R13, R13, #4 - | - CMP R1, #NBuffers - MOVCSS PC, R14 ; not known about, pass it on (preserving V) - ] - - Push "R3-R5" - - MOV R3, R1, LSL #2 - LDR R4, [R3, #BuffOutPtrs] - LDR R5, [R3, #BuffInPtrs] - - CMP R4, R5 - CMPHI R5, R4 ; C=1 <=> (R4 = R5) ie empty - BCS RemVExit - - ADR R2, BuffParms - ADD R2, R2, R3, LSL #1 - LDMIA R2, {R2, R5} ; get address, size - - LDRB R2, [R2, R4] ; get next byte to be read out - MOV R0, R2 - ADD R4, R4, #1 ; increment out pointer - - TEQ R4, R5 ; wrap pointer if necessary - MOVEQ R4, #0 - - STR R4, [R3, #BuffOutPtrs] ; bugfix - was STRB - TEQ R1, #Buff_Mouse ; mouse => not output buffer - BEQ RemVExit ; exit (C=0) if not - CMP R1, #Buff_RS423Out ; C=1 => output buffer - BCC RemVExit ; exit (C=0) if not - - LDR R5, [R3, #BuffInPtrs] ; reload in-ptr - TEQ R4, R5 ; are ptrs same now ? - BNE RemVExitCLC ; no, then exit setting C=0 - - Push R0 ; save character - MOV R0, #Event_OutputEmpty ; output buffer empty event - BL OSEVEN ; generate event - Pull R0 ; restore character - -RemVExitCLC - CLC ; make sure carry clear - -RemVExit - Pull "R3-R5,PC" - -Examine - [ No26bitCode - Push R14 - MRS R14, CPSR - CMP R1, #NBuffers - BLO %FT10 - MSR CPSR_f, R14 - Pull PC ; not known about, pass it on (preserving V) -10 - | - CMP R1, #NBuffers - MOVCSS PC, R14 ; not known about, pass it on (preserving V) - ] - - Push "R3-R5" - - MOV R3, R1, LSL #2 - ADR R2, BuffParms - - LDR R2, [R2, R3, LSL #1] ; R2 -> buffer - - LDR R4, [R3, #BuffOutPtrs] - LDR R5, [R3, #BuffInPtrs] - - CMP R4, R5 - CMPHI R5, R4 ; C=1 <=> (R4 = R5) ie empty - - LDRCCB R2, [R2, R4] ; if ok then examine byte - MOVCC R0, R2 - - Pull "R3-R5,PC" - -; ***************************************************************************** -; -; NewCnpV - Routine for CnpVec -; -; in: R1 = buffer number (0 => keyboard) -; V=0, C=0 => count entries -; V=0, C=1 => count spaces -; V=1 => purge buffer -; -; out: R0 undefined -; (purge) R1-R12 preserved -; (count) R1,R2 = count, R3-R12 preserved -; - -NewCnpV - [ No26bitCode - Push R14 - MRS R14, CPSR - CMP R1, #NBuffers - BLO %FT10 - MSR CPSR_f, R14 - Pull "PC" ; not known about, pass it on (preserving V) -10 - ADD R13, R13, #4 - | - CMP R1, #NBuffers - MOVCSS PC, R14 ; not known about, pass it on (preserving V) - ] - - Push "R3-R5" - - [ No26bitCode - MSR CPSR_f, R14 ; restore V and C - | - TEQP R14, #0 ; restore V and C - ] - - MOV R3, R1, LSL #2 - - LDR R4, [R3, #BuffOutPtrs] - - STRVS R4, [R3, #BuffInPtrs] ; if purge, then make in=out - Pull "R3-R5,PC", VS ; and return - - LDR R5, [R3, #BuffInPtrs] - SUB R1, R5, R4 ; in - out (don't stamp on carry) - - ADR R5, BuffParms+4 - LDR R5, [R5, R3, LSL #1] ; get size - - TEQ R1, #0 ; don't stamp on carry - ADDMI R1, R1, R5 ; wrap number of chars if negative - - SUBCS R1, R5, R1 ; C=1 => convert to spaces - SUBCS R1, R1, #1 ; one fewer spaces than BuffSizes - - MOV R2, R1, LSR #8 ; make R2 = hi-byte - AND R1, R1, #&FF ; and R1 = lo-byte - - Pull "R3-R5,PC" - -; ***************************************************************************** - -BuffParms - & KeyBuff - & KeyBuffSize - - & RS423InBuff - & RS423InBuffSize - - & RS423OutBuff - & RS423OutBuffSize - - & PrintBuff - & PrintBuffSize - - & Sound0Buff - & Sound0BuffSize - - & Sound1Buff - & Sound1BuffSize - - & Sound2Buff - & Sound2BuffSize - - & Sound3Buff - & Sound3BuffSize - - & SpeechBuff - & SpeechBuffSize - - & MouseBuff - & MouseBuffSize - -; ***************************************************************************** -; -; DoInsertESC - Insert character into buffer, checking for escape -; -; in: R1 = buffer id -; R2 = character -; - -DoInsertESC - CMP R1, #2 ; if not keyboard or serial input - BCS INSERT ; then don't treat as special - - LDROSB R0, RS423mode ; Z => simulate keyboard - TST R0, R1 ; NZ => RS423 input and RS8Bit - BNE INSERT - - Push R14 - - LDROSB R0, ESCch ; escape character - TEQ R2, R0 ; if escape character - LDROSB R0, ESCaction, EQ - TEQEQ R0, #0 ; and FX229,0 - BNE CKESCY ; not escape or let it thru - -; ESCAPE detected - - LDROSB R0, ESCBREAK ; FX 200 - TST R0, #1 ; bit 0 set ? - BNE %FT10 ; escape ignored - - MOV R0, #Event_Escape - BL OSEVEN ; exits carry set if disabled - BCC %FT10 ; [event enabled, so don't do - ; normal escape action] - Push "R1, R12" - BL DoOsbyte7D ; generate escape condition - Pull "R1, R12" -10 - CLC ; character inserted OK - Pull PC - -CKESCY - MOV R0, #Event_CharInput - BL OSEVEN ; preserves R0-R2 - Pull R14 -INSERT - MOV R0, R2 -INSRT - Push "R10,R12,R14" - MOV R10, #INSV -GoVec - BL GoVec2 - Pull "R10,R12,PC" - -GoVec2 - CallAVector - - END diff --git a/s/PMF/Def b/s/PMF/Def deleted file mode 100644 index 049ca858..00000000 --- a/s/PMF/Def +++ /dev/null @@ -1,148 +0,0 @@ -; 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.Def - MACRO - Protocol -; -; Protocol constants -; -; 4 bit codes for input commands -; -LEDON * &00 -LEDOFF * &10 -REQUEST * &20 -ACK * &30 -SPDDATA * &40 ;Bottom four bits are data to convert -RSTREQ * &80 ;Request for reset -; -; 4 bit input data types -; -; Requests -; -KBID * 0 -SPDRESET * 1 -MDATA * 2 ;New mouse position, even if it hasn't moved -; -; Acks -; -BYTE * 0 -SCAN * 1 -MOUSE * 2 -ALL * 3 -; -; data output -; -; Type d7 d6 d5 d4 d3 d2 d1 d0 number of bytes -; Reset 1 x x x x x x x 1 -; Key up 0 0 1 1 x x x x 2 (row then column) -; Key down 0 0 1 0 x x x x 2 (row then column) -; Mouse change 0 1 x x x x x x 2 (X, Y) -; SPD data 0 0 0 0 x x x x 8 -; KB Ids 0 0 0 1 x x x x 2 (low nibble then high nibble) -; -; The keyboard type -; -IDTYPE * &10 -KBTYPE * 0 ;This is keyboard 0 -; -; Key transitions -; -KEYDOWN * &20 -KEYUP * &30 -; -; Mouse transitions -; -MMOVED * &40 -; -; SPD converted data -; -SPDDONE * 0 -; -; Reset types -; -HRDRESET * &FF -RST1ACK * &FE -RST2ACK * &FD - -; New keyboard protocols - -; Keyboard -> ARM - -K1mdat * &00 ; 0xxx xxxx Mouse data from keyboard -K1kbid * &80 ; 10xx xxxx Keyboard ID from keyboard -K1kdda * &C0 ; 1100 xxxx Key down data -K1kuda * &D0 ; 1101 xxxx Key up data -K1pdat * &E0 ; 1110 xxxx SPD data from keyboard (won't happen) -K1rak2 * &FD ; 1111 1101 Reset acknowledge 2 -K1rak1 * &FE ; 1111 1110 Reset acknowledge 1 -K1hrst * &FF ; 1111 1111 Hard reset - -K1kbidmask * &3F ; 0011 1111 Valid bits in keyboard id - -K1notmousedata * &80 - -; ARM -> Keyboard - -; -; The IOC registers -; - ^ &04, R12 -KARTTx # 0 -KARTRx # 0 - - ^ &20, R12 -IRQStatusB # 4 -IRQReqB # 4 -IRQMaskB # 4 - - ^ &70, R12 -Timer3Low # 4 -Timer3High # 4 -Timer3Go # 4 -Timer3Latch # 4 - -; Register bits - -KARTRxBit * &80 -KARTTxBit * &40 -KARTIRQBits * KARTTxBit :OR: KARTRxBit - -K1leds * &00 ; 0000 0xxx Set LED states -K1rqid * &20 ; 0010 0000 Request keyboard id -K1prst * &21 ; 0010 0001 SPD reset -K1rqmp * &22 ; 0010 0010 Request mouse position -K1nack * &30 ; 0011 0000 Acknowledge (keys- mouse-) -K1sack * &31 ; 0011 0001 Acknowledge (keys+ mouse-) -K1mack * &32 ; 0011 0010 Acknowledge (keys- mouse+) -K1smak * &33 ; 0011 0011 Acknowledge (keys+ mouse+) -K1back * &3F ; 0011 1111 Byte acknowledge (between 2 data bytes) -K1rqpd * &40 ; 0100 xxxx Request SPD data conversion - -; Keyboard vector offsets - - ^ 0 - -KVKeyTran # 4 -KVKeyTranSize # 4 -KVInkeyTran # 4 -KVShiftingList # 4 -KVSpecialList # 4 -KVSpecialCodeTable # 4 -KVInit # 4 -KVPendingAltCode # 4 -KVPendingAltSpecial # 4 ; Used only internally - - MEND - END diff --git a/s/PMF/IIC b/s/PMF/IIC deleted file mode 100644 index e6ecb9f4..00000000 --- a/s/PMF/IIC +++ /dev/null @@ -1,948 +0,0 @@ -; Copyright 2001 Pace Micro Technology plc -; -; 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. -; -; 19-Feb-01 KJB Separated IIC operations from NVMemory and RTC code -; 05-Feb-02 BJGA Added re-entrant capability - - -PollMax * 150 ; Number of times to poll for an Ack (increase if you - ; clock faster - need to allow 5ms for write cycle). - - -; Choose a lower limit on the number of ticks per clock phase based on the -; MaxI2Cspeed variable defined in Hdr:Machine.<Machine> - [ MaxI2Cspeed >= 1000 -I2Cticks * 1 - | - [ MaxI2Cspeed >= 400 -I2Cticks * 3 - | -I2Cticks * 10 - ] - ] - - -IICStackAlignment * 7 ; log2 of stack size, also stack alignment - ; current requirement is 19 words = 2_01001100 bytes - - ^ 0 -IICLink_Next # 4 -IICLink_Error # 4 -IICLink_Array # 4 -IICLink_Size # 4 - -; SVC stack format, in descending address order: -; 16 bytes first link (also bottom of stacked registers) -; n bytes align to address with bottom x bits set -; 2^x-4 bytes align to address with bottom x bits clear (the local stack) -; 4 bytes linked list head -; 4 bytes linked list tail -; 4 bytes original sp -; . -; . -; . -; 16 bytes another link (also bottom of stacked registers) -; 4 bytes original sp - -; IRQ stack format, in descending address order, for reference: -; 4 bytes lr_irq-4 (interrupted PC) -; 4 bytes r0 -; 4 bytes spsr_irq (interrupted CPSR) -; 20 bytes r1-r3, r11, r12 -; 4 bytes IRQsema link - - -iicsp RN 11 -iiclr RN 12 - - - MACRO -$label iicBL $destination, $cond -$label MOV$cond iiclr, pc - B$cond $destination - MEND - - MACRO -$label iicPull $reglist, $cond, $hat - LCLS temps - LCLL onereg -temps SETS "$reglist" -onereg SETL "$hat" = "" - WHILE onereg :LAND: :LEN: temps > 0 - [ temps :LEFT: 1 = "," :LOR: temps :LEFT: 1 = "-" -onereg SETL {FALSE} - ] -temps SETS temps :RIGHT: (:LEN: temps - 1) - WEND - [ onereg -$label LDR$cond $reglist, [iicsp], #4 - | -$label LDM$cond.FD iicsp!, {$reglist}$hat - ] - MEND - - MACRO -$label iicPush $reglist, $cond - LCLS temps - LCLL onereg -temps SETS "$reglist" -onereg SETL {TRUE} - WHILE onereg :LAND: :LEN: temps > 0 - [ temps :LEFT: 1 = "," :LOR: temps :LEFT: 1 = "-" -onereg SETL {FALSE} - ] -temps SETS temps :RIGHT: (:LEN: temps - 1) - WEND - [ onereg -$label STR$cond $reglist, [iicsp, #-4]! - | -$label STM$cond.FD iicsp!, {$reglist} - ] - MEND - - - -IICOpSWI - Push LR - BL IIC_OpV - Pull LR - B SLVK_TestV - - -; ***************************************************************************** -; -; in: R0 = device address (bit 0 set => read, clear => write) -; R1 -> data block -; R2 = length of data block -; -IIC_Op - Push "R0-R2,LR" - Push "R0-R2" ; soft copy for IIC_OpV to work on - MOV R0, R13 - MOV R1, #1 - BL IIC_OpV - ADD R13, R13, #12 ; junk soft copy - Pull "R0-R2,PC",VC - ADD R13, R13, #4 - Pull "R1-R2,PC" - -; ***************************************************************************** -; -; IIC_OpV - perform IIC operations based on a list of descriptors -; -; in: R0 -> array of transfer descriptors -; R1 = number of transfers -; -; out: transfer descriptors may be updated (beware) -; -; Transfer descriptor is 3 words: word 0 = device address (+direction) -; (bit 29 signifies retry for response) -; (bit 30 signifies checksum read only - ie fill in word 1 with -; sum of bytes read) -; (bit 31 signifies continued transfer - ie no start or address) -; word 1 -> data block -; word 2 = length of data block -IIC_OpV ROUT - Push "r0-r3,r6-r12,lr" - MOV lr, #0 - STR lr, [sp, #-8]! - MRS r10, CPSR - BIC r7, r10, #I32_bit :OR: F32_bit - ORR r8, r7, #I32_bit - [ HAL - AddressHAL - | - MOV r9, #IOC - ] - MOV r2, #IRQsema - MOV r12, sp ; original sp, also pointer to link - ORR lr, r8, #2_10000 - MSR CPSR_c, lr ; IRQs off, force 32-bit mode - -01 LDR r2, [r2] - TEQ r2, #0 - BEQ %FT50 ; I²C code not in IRQ stack - LDR r6, [r2, #4*8] ; interrupted PC -IIC_OpV_PCReference - RSB lr, pc, r6 - LDR r0, =(interrupt_protected_end-4) - (IIC_OpV_PCReference+8) - CMP lr, r0 - RSBLES lr, lr, #interrupt_protected_start - (IIC_OpV_PCReference+8) - BGT %BT01 - - ; I²C code is already threaded - Push "r12" ; put original sp on stack for our exit routine - LDR r0, [r2, #4*4] ; retrieve interrupted iicsp - BIC r0, r0, #(1:SHL:IICStackAlignment)-1 - LDR r1, [r0, #-8] ; old list tail - STR r12, [r0, #-8] ; new list tail - STR r12, [r1, #IICLink_Next] ; point old link to new link - ADR r0, IIC_OpV_CommonExit - STR r0, [r2, #4*8] ; poke IRQ stack so previous operation returns as though completed - LDR r0, [r2, #4*6] ; get interrupted CPSR - MSR SPSR_cxsf, r0 ; stick it in SPSR (okay, because IRQs are off) - LDR r0, [r2, #4*7] - LDMIB r2, {r1-r3,r11,r12} - MOVS pc, r6 ; copy SPSR to CPSR and resume execution - -50 ; I²C code not currently threaded - create new environment - ADD iicsp, sp, #4 - BIC iicsp, iicsp, #(1:SHL:IICStackAlignment)-1 - SUB iicsp, iicsp, #4 - BIC sp, iicsp, #(1:SHL:IICStackAlignment)-1 - Push "r12" ; list head pointer - Push "r12" ; list tail pointer - Push "r12" ; original sp - LDR r0, [r12, #IICLink_Array] - LDR r1, [r12, #IICLink_Size] - B IICStart ; start working through list - -IIC_OpV_CommonExit - MSR CPSR_c, r10 ; restore original IRQ disable state - LDR sp, [sp] - ADD sp, sp, #4 ; skip next pointer - Pull "r0" - CMP r0, #0 - Pull "r0-r3,r6-r12,pc", EQ - SETV - ADD sp, sp, #4 - Pull "r1-r3,r6-r12,pc" - - -interrupt_protected_start - -; Protected routines register usage: -; r0-r3 general purpose -; r7 MRS style PSR with c bits = SVC26/32, IRQs/FIQs enabled -; r8 MRS style PSR with c bits = SVC26/32, IRQs disabled, FIQs enabled -; r9 IOC, or base of HAL workspace, depending on HAL switch -; r11 stack pointer -; r12 link register / general purpose -; CPSR is also non-volatile - -IICStart - MSR CPSR_c, r7 ; enable IRQs (inside protected code) - this may take some time - ; drop through... - -; ***************************************************************************** -; -; IICLoop - serial-execution outermost loop, stepping along pending IIC operations -; - -IICLoop - iicBL IICDoOp - MOVVC r0, #0 - BIC r1, iicsp, #(1:SHL:IICStackAlignment)-1 - LDR r2, [r1, #-4] ; list head - STR r0, [r2, #IICLink_Error] ; set up return value - MSR CPSR_c, r8 ; disable IRQs while we work on the list - LDR r2, [r2] - TEQ r2, #0 ; end of list? - BEQ IIC_OpV_CommonExit ; finished! - STR r2, [r1, #-4] ; update list head - MSR CPSR_c, r7 ; IRQs back on - LDR r0, [r2, #IICLink_Array] - LDR r1, [r2, #IICLink_Size] ; get next array - B IICLoop ; and loop - -; ***************************************************************************** -; -; IICDoOp - main serial-execution entry point -; -; in: R0 -> array of transfer descriptors -; R1 = number of transfers -; -; out: if V set, r0 -> error block -; otherwise r0-r3,r12 may be corrupted -; - -IICDoOp ROUT - MOV R2, #0 - iicPush "R1,R2,iiclr" ; two words on stack are RepeatedStart flag and transfers remaining - - MOV R3, R0 - - LDR iiclr, [R2, #IICType] - TST iiclr, #IICFlag_HighLevel - BNE IIC_OpV_HAL ; HAL can make use of a hardware IIC engine - -05 LDR R0, [iicsp] - SUBS R0, R0, #1 - BCC %FT90 - STR R0, [iicsp] - - LDMIA R3!, {R0-R2} - TST R0, #1:SHL:31 ; skip start? - BNE %FT08 - - LDR iiclr, [iicsp, #4] - TEQ iiclr, #0 - MOV iiclr, pc - ADD iiclr, iiclr, #8 - BEQ Start - BNE RepeatedStart ; these are effectively conditional BL's - - TST R0, #1:SHL:29 - BNE %FT06 - iicBL TXAck ; transmit device address without retries - B %FT07 - -06 - iicBL TXPollAck ; transmit device address with retries -07 BVS %FT80 - -08 MOV iiclr, #1 - STR iiclr, [iicsp, #4] - TEQ R2, #0 - BEQ %BT05 - - TST R0, #1 ; Z => write, NZ => read - BNE %FT20 - -; Write case -10 LDRB R0, [R1], #1 ; read byte from data block - iicBL TXAck ; transmit, checking for ack - BVS %FT80 - SUBS R2, R2, #1 ; decrement byte count - BNE %BT10 ; loop until finished - B %BT05 ; then next transfer - -20 TST R0, #1:SHL:30 ; checksum? - BNE %FT30 - -; Read case -21 - iicBL RXByte ; read byte from bus - STRB R0, [R1], #1 ; store in data block - MOV R0, #1 ; start with the assumption that it's the last byte, and so shouldn't be acknowledged - SUBS R2, R2, #1 ; is it last byte in this descriptor? - MOVNES R0, R0, LSR #2 ; no, so definitely needs acknowledging (with 0 bit) - ; now Z is set, and C set => just read last byte for this descriptor - LDRCS iiclr, [iicsp] - TEQCS iiclr, #0 ; if we've finished this descriptor, check for another transfer descriptor - ; Z clear => last byte, and there is another descriptor - LDRNE iiclr, [R3] - TSTNE iiclr, #1:SHL:31 ; if appropriate, check if next descriptor is a continuation - MOVNE R0, #0 ; if read is going to continue, we need to acknowledge - iicBL ClockData ; but always send ack clock pulse - BCC %BT21 - B %BT05 ; next transfer - -; Checksum case -30 MOV R1, #0 -31 - iicBL RXByte ; read byte from bus - ADD R1, R1, R0 - MOV R0, #1 ; start with the assumption that it's the last byte, and so shouldn't be acknowledged - SUBS R2, R2, #1 ; is it last byte in this descriptor? - MOVNES R0, R0, LSR #2 ; no, so definitely needs acknowledging (with 0 bit) - ; now Z is set, and C set => just read last byte for this descriptor - LDRCS iiclr, [iicsp] - TEQCS iiclr, #0 ; if we've finished this descriptor, check for another transfer descriptor - ; Z clear => last byte, and there is another descriptor - LDRNE iiclr, [R3] - TSTNE iiclr, #1:SHL:31 ; if appropriate, check if next descriptor is a continuation - MOVNE R0, #0 ; if read is going to continue, we need to acknowledge - iicBL ClockData ; but always send ack clock pulse - BCC %BT31 - STR R1, [R3, #-8] ; store checksum - B %BT05 ; next transfer - -90 - iicBL Stop -IIC_ExitOK - CLRV - ADD iicsp, iicsp, #8 ; skip junk on stack - iicPull "pc" - -80 - iicBL Stop -IIC_ExitNoAck - MOV R0, #0 - STR R0, [R0, #IICStatus] - ADR R0, ErrorBlock_IIC_NoAcknowledge - -IIC_ExitError - [ International :LAND: {FALSE} - ; KJB - problematical - this may be done very early, before SWI dispatch - ; is ready, so we can't call MessageTrans. Think about this. - ; BJGA - we also can't use TranslateError, because it doesn't conform to - ; our calling standard (unless we turn interrupts off) - BL TranslateError - ADD iicsp, iicsp, #8 ; skip junk on stack - iicPull "pc" - - MakeInternatErrorBlock IIC_NoAcknowledge,, "NoAck:No acknowledge from IIC device" - | - SETV - ADD iicsp, iicsp, #8 ; skip junk on stack - iicPull "pc" - - MakeErrorBlock IIC_NoAcknowledge - ] - - - -; ***************************************************************************** -; -; SetC1C0 - Set clock and data lines to values in R1 and R0 respectively -; -; out: r0,r1 corrupted -; - -SetC1C0 ROUT - iicPush "r2,r3,iiclr" - [ HAL - MOV R2, R1 - MOV R1, R0 - MOV R0, #0 - MSR CPSR_c, r8 ; IRQs off for use of ATPCS - Push "lr" - CallHAL HAL_IICSetLines - Pull "lr" - MSR CPSR_c, r7 ; IRQs back on - | - ADD R0, R0, R1, LSL #1 ; R0 := C0 + C1*2 - - MOV R2, #0 ; prepare to index soft copy - LDRB R1, [R2, #IOCControlSoftCopy] ; read soft copy - BIC R1, R1, #&03 ; clear clock and data - ORR R0, R1, R0 ; put in new clock and data - ORR R0, R0, #&C0 ; make sure two test bits are - ; always set to 1 ! - STRB R0, [R2, #IOCControlSoftCopy] ; store back to soft copy - - MOV R2, #IOC - STRB R0, [R2, #IOCControl] - ] - - [ E2ROMSupport - MOV R0, #0 - LDRB R0, [R0, #NVRamSpeed] - TEQ R0, #0 - MOVEQ R0, #10 ; default value if speed not checked yet - | - MOV R0, #10 ; default to slowest value if we have E2ROMSupport is false - ] - iicBL iicDoMicroDelay - - iicPull "r2,r3,pc" - -; ***************************************************************************** -; -; ReadC1C0 - Read clock and data lines to R1 and R0 respectively -; -; out: R0, R1 updated -; - -ReadC1C0 ROUT - [ HAL - iicPush "r2,r3,iiclr" - MSR CPSR_c, r8 ; IRQs off for use of ATPCS - Push "lr" - CallHAL HAL_IICReadLines - Pull "lr" - MSR CPSR_c, r7 ; IRQs back on - iicPull "r2,r3,pc" - | - LDRB a1, [r9, #IOCControl] - MOV a2, a1, LSR #1 - AND a1, a1, #1 - AND a2, a2, #1 - MOV pc, iiclr - ] - -; ***************************************************************************** -; -; iicDoMicroDelay - Delay for >= R0/2 microseconds, IIC calling standard -; -; in: R0 = time delay in 1/2 microsecond units -; On ARM600, we may or may not be in a 32-bit mode -; -; out: R0,R1 corrupted -; - -iicDoMicroDelay ROUT - [ HAL - iicPush "a3,a4,iiclr" - MOVS a1, a1, LSR #1 - ADC a1, a1, #0 - MSR CPSR_c, r8 ; IRQs off for use of ATPCS - Push "lr" - CallHAL HAL_CounterDelay - Pull "lr" - MSR CPSR_c, r7 ; IRQs back on - iicPull "a3,a4,pc" - | - iicPush "iiclr" - STRB R0, [R9, #Timer0LR] ; copy counter into output latch - LDRB R1, [R9, #Timer0CL] ; R1 := low output latch -10 - STRB R0, [R9, #Timer0LR] ; copy counter into output latch - LDRB iiclr, [R9, #Timer0CL] ; iiclr := low output latch - TEQ iiclr, R1 ; unchanged ? - BEQ %BT10 ; then loop - MOV R1, iiclr ; copy anyway - SUBS R0, R0, #1 ; decrement count - BNE %BT10 ; loop if not finished - - iicPull "pc" - ] - - LTORG - -; ***************************************************************************** -; -; ClockData - Clock a bit of data down the IIC bus -; -; in: R0 = data bit -; -; out: All registers preserved, including PSR -; - -ClockData ROUT - [ No26bitCode - iicPush "R0-R3,iiclr" - MRS R2,CPSR - | - iicPush "R0-R1,R3,iiclr" - ] - MOV R3, R0 - - MOV R1, #0 ; Clock lo - iicBL SetC1C0 - -; Disable interrupts to ensure clock hi with data hi is only transient -; This allows BMU to detect idle condition by polling - MSR CPSR_c, r8 - - MOV R0, R3 - MOV R1, #1 ; Clock hi - iicBL SetC1C0 - -; Delay here must be >= 4.0 microsecs - - MOV R0, R3 - MOV R1, #0 ; Clock lo - iicBL SetC1C0 - - [ No26bitCode - MSR CPSR_cf,R2 ; Restore interrupts and flags - iicPull "R0-R3,PC" - | - iicPull "R0-R1,R3,PC",,^ - ] - -; ***************************************************************************** -; -; Start - Send the Start signal -; -; out: All registers preserved, PSR corrupted -; - -Start ROUT - iicPush "R0-R1,iiclr" - - MOV R0, #1 ; clock HI, data HI - MOV R1, #1 - iicBL SetC1C0 - -; Delay here must be >= 4.7 microsecs (1.3 for fast device) - - MOV R0, #0 ; clock HI, data LO - MOV R1, #1 - iicBL SetC1C0 - -; Delay here must be >= 4.0 microsecs (0.6 for fast device) - - MOV R0, #0 ; clock LO, data LO - MOV R1, #0 - iicBL SetC1C0 - - iicPull "R0-R1,PC" - -; ***************************************************************************** -; -; RepeatedStart - Send a Repeated Start signal -; -; out: All registers preserved, PSR corrupted -; - -RepeatedStart ROUT - iicPush "R0-R1,iiclr" - - MOV R0, #1 - MOV R1, #0 ; clock LO, data HI - iicBL SetC1C0 - - MOV R0, #1 ; clock HI, data HI - MOV R1, #1 - iicBL SetC1C0 - -; Delay here must be >= 4.7 microsecs (1.3 for fast device) - - MOV R0, #0 ; clock HI, data LO - MOV R1, #1 - iicBL SetC1C0 - -; Delay here must be >= 4.0 microsecs (0.6 for fast device) - - MOV R0, #0 ; clock LO, data LO - MOV R1, #0 - iicBL SetC1C0 - - iicPull "R0-R1,PC" - -; ***************************************************************************** -; -; Acknowledge - Check acknowledge after transmitting a byte -; -; out: All registers preserved -; V=0 => acknowledge received -; V=1 => no acknowledge received -; - -Acknowledge ROUT - iicPush "R0-R2,iiclr" - - MOV R0, #1 ; clock LO, data HI - MOV R1, #0 - iicBL SetC1C0 - - [ {TRUE} -; Disable interrupts to ensure clock hi with data hi is only transient -; This allows BMU to detect idle condition by polling - - MSR CPSR_c, R8 - ] - MOV R0, #1 ; clock HI, data HI - MOV R1, #1 - iicBL SetC1C0 - -; Delay here must be >= 4.0 microsecs (0.6 for fast device) - - iicBL ReadC1C0 - MOV R2, R0 ; should be LO for correct acknowledge - - MOV R0, #1 - MOV R1, #0 ; clock LO, data HI - iicBL SetC1C0 - - [ {TRUE} - MSR CPSR_c, R7 - ] - - TST R2, #1 - MRS R2, CPSR - BICEQ R2, R2, #V_bit ; clear V if correct acknowledge - ORRNE R2, R2, #V_bit ; set V if no acknowledge - MSR CPSR_f, R2 - - iicPull "R0-R2,PC" - -; ***************************************************************************** -; -; Stop - Send the Stop signal -; -; out: All registers preserved, PSR corrupted -; - -Stop ROUT - iicPush "R0-R1,iiclr" - - MOV R0, #0 ; clock LO, data LO - MOV R1, #0 - iicBL SetC1C0 - - MOV R0, #0 ; clock HI, data LO - MOV R1, #1 - iicBL SetC1C0 - -; Delay here must be >= 4.0 microsecs (0.6 for fast device) - - MOV R0, #1 ; clock HI, data HI - MOV R1, #1 - iicBL SetC1C0 - - iicPull "R0-R1,PC" - -; ***************************************************************************** -; -; TXByte - Transmit a byte -; -; in: R0 = byte to be transmitted -; -; out: All registers preserved, PSR corrupted -; - -TXByte ROUT - iicPush "R0-R2,iiclr" - MOV R1, #&80 ; 2^7 the bit mask - MOV R2, R0 ; byte goes into R2 -10 - ANDS R0, R2, R1 ; zero if bit is zero - MOVNE R0, #1 - iicBL ClockData ; send the bit - MOVS R1, R1, LSR #1 - BNE %BT10 - iicPull "R0-R2,PC" - -TXAck ROUT - iicPush iiclr - iicBL TXByte - iicPull iiclr - B Acknowledge - - -; ***************************************************************************** -; -; TXPollAck - Transmit a byte and poll for acknowledge -; -; This is intended for devices with a slow internal write cycle which -; don't ack until the write cycle is finished ( eg ATMEL AT24C01A/x ) -; -; in: R0 = byte to be transmitted -; -; out: All registers preserved -; - -TXPollAck ROUT - iicPush "R1,iiclr" - MOV R1, #1 -10 - iicBL TXByte - iicBL Acknowledge - iicPull "R1,PC",VC - ADD R1, R1, #1 - TEQ R1, #PollMax - BEQ %FT90 - [ {FALSE} - BREG R1, "i2c tries:" - ] - iicBL RepeatedStart - B %BT10 -90 - iicPull "R1,PC" - -; ***************************************************************************** -; -; RXByte - Receive a byte -; -; out: R0 = byte received -; All other registers preserved, PSR corrupted -; - -RXByte ROUT - iicPush "R1-R3,iiclr" - MOV R3, #0 ; byte:=0 - MOV R2, #7 - - MOV R0, #1 ; clock LO, data HI - MOV R1, #0 - iicBL SetC1C0 -10 - [ {TRUE} -; Disable interrupts to ensure clock hi with data hi is only transient -; This allows BMU to detect idle condition by polling - - MSR CPSR_c, R8 - ] - MOV R0, #1 ; pulse clock HI - MOV R1, #1 - iicBL SetC1C0 - - iicBL ReadC1C0 - ADD R3, R0, R3, LSL #1 ; byte:=byte*2+ SDA - - MOV R0, #1 ; return clock LO - MOV R1, #0 - iicBL SetC1C0 - - [ {TRUE} - MSR CPSR_c, R7 - ] - SUBS R2, R2, #1 - BCS %BT10 - - MOV R0, R3 ; return the result in R0 - iicPull "R1-R3,PC" - -; ***************************************************************************** - -IIC_OpV_HAL -; R2 = 0 -; R3 -> array of transfer descriptors -; [iicsp, #0] = number of transfers -; [iicsp, #4] unused on entry, used to hold number of retries remaining -; [iicsp, #8] = return address - - LDR iiclr, [R2, #IICStatus] - TEQ iiclr, #0 - BNE IIC_Busy - - LDR iiclr, [R3] - TST iiclr, #1:SHL:29 ; retries reqd? - MOVNE iiclr, #PollMax - MOVEQ iiclr, #1 ; no,just try once - STR iiclr, [iicsp, #4] - -IIC_OpV_HAL_Retry - MOV iiclr, #1 - STR iiclr, [R2, #IICStatus] - - iicPush "R3" - MOV R0, #0 - LDR R1, [iicsp, #4] - MOV R2, R3 - MSR CPSR_c, R8 ; IRQs off for use of ATPCS - Push "lr" - CallHAL HAL_IICTransfer - Pull "lr" - MSR CPSR_c, R7 ; IRQs back on - iicPull "R3" - MOV R2, #0 - -20 TEQ R0, #2 - BEQ IIC_NoAck - TEQ R0, #3 - BEQ IIC_Busy - TEQ R0, #0 - STREQ R0, [R2, #IICStatus] ; mark IIC system as free - BEQ IIC_ExitOK - TEQ R0, #1 - BNE IIC_Error - LDR R0, [R2, #IICStatus] - B %BT20 - -IIC_NoAck - LDR iiclr, [iicsp, #4] - SUBS iiclr, iiclr, #1 - STRNE iiclr, [iicsp, #4] - BNE IIC_OpV_HAL_Retry ; worth another go? - B IIC_ExitNoAck - -IIC_Busy - ADR R0,IICBusy_Error - B IIC_ExitError - -IICBusy_Error - MakeErrorBlock IIC_Busy - -IIC_Error - MOV R0, #0 - STR R0, [R0, #IICStatus] - ADR R0,IICError_Error - B IIC_ExitError - -IICError_Error - MakeErrorBlock IIC_Error - -interrupt_protected_end - - -IICIRQ - Push "R9,R14" - MOV R9, R12 - MOV R0, #0 - CallHAL HAL_IICMonitorTransfer - MOV R12, #0 - STR R0, [R12, #IICStatus] - Pull "R9,PC" - -IICAbort - Push "R7,R8,R9,R11,R12" - MOV R11,R13 - SUB R13,R13,#&80 - MRS R7,CPSR - ORR R8,R7,#I32_bit - [ HAL - AddressHAL - | - MOV R9,#IOC - ] - [ {FALSE} - MOV R1,#16 ; Two bytes in case RTC transmitting -35 - iicBL Start ; Start/clock edge - iicBL Stop - SUBS R1,R1,#1 - BNE %BT35 - | - iicBL Start - MOV R0, #1 - iicBL TXAck - iicBL Stop - ] - ADD R13,R13,#&80 - Pull "R7,R8,R9,R11,R12" - MOV PC,R14 - -IICInit - Push "R9,R14" - AddressHAL - MOV a1, #0 - CallHAL HAL_IICType - MOV a2, #0 - STR a1, [a2, #IICType] - TST a1, #IICFlag_Background - Pull "R9,PC",EQ - SUB sp, sp, #12 - MOV a1, sp - MOV a2, #0 - CallHAL HAL_IICDevice - LDR a1, [sp] - CallHAL HAL_IRQEnable - ADD sp, sp, #12 - Pull "R9,PC" - -; We need to retain a version of DoMicroDelay with standard calling conventions, because -; it is called from elsewhere in the kernel. But it can't live inside the protected -; region above in case it's interrupted by a routine that does an IIC operation. - -; ***************************************************************************** -; -; DoMicroDelay - Delay for >= R0/2 microseconds -; -; in: R0 = time delay in 1/2 microsecond units -; R2 -> IOC -; On ARM600, we may or may not be in a 32-bit mode -; -; out: R0,R1 corrupted -; - -DoMicroDelay ROUT - [ HAL - Push "a3,a4,sb,ip,lr" - AddressHAL - MOVS a1, a1, LSR #1 - ADC a1, a1, #0 - CallHAL HAL_CounterDelay - Pull "a3,a4,sb,ip,pc" - | - Push R14 - STRB R0, [R2, #Timer0LR] ; copy counter into output latch - LDRB R1, [R2, #Timer0CL] ; R1 := low output latch -10 - STRB R0, [R2, #Timer0LR] ; copy counter into output latch - LDRB R14, [R2, #Timer0CL] ; R14 := low output latch - TEQ R14, R1 ; unchanged ? - BEQ %BT10 ; then loop - MOV R1, R14 ; copy anyway - SUBS R0, R0, #1 ; decrement count - BNE %BT10 ; loop if not finished - - Pull PC - ] - - END diff --git a/s/PMF/Internat b/s/PMF/Internat deleted file mode 100644 index 24eb7052..00000000 --- a/s/PMF/Internat +++ /dev/null @@ -1,250 +0,0 @@ -; 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. -; -; > Internat - -The International module -======================== - -Author: Tim Dobson -Name: International -Version: 0.01 -Circulation: Acorn -History: - 0.01: 17-Mar-89 to 03-Apr-89: First draft. - -This document describes the International module version 1.13, as found in -RISC OS 2.00. It also describes the differences between this version and -version 1.05 (the version in Arthur 1.20). - -The International module allows the user to tailor his machine for use in -different countries by setting:- - - a) the mapping of keys to character codes (the *keyboard*), and - - b) the mapping from character codes to characters (the *alphabet*), or - - c) both mappings a) and b) at once (the *country*). - -This module, in conjunction with the MOS, controls the selection of these -mappings, but the interface allows the actual mappings to be implemented in -one or more separate relocatable modules, via the service mechanism. - -Explanation of terms --------------------- - -Each country has a *country name* and an associated *country number*. - -Each alphabet has an *alphabet name* and an associated *alphabet number*. - -Each country has an associated alphabet, but a given alphabet may be -associated with more than one country. - -Each country also has an associated keyboard, but keyboards do not have their -own names or numbers; keyboards are specified by country name or country -number. - -Country numbers are in the range 0 to 99, alphabet numbers are in the -range 100 to 126. - -Modules can provide new country/alphabet names/numbers by responding to -various sub-reason codes of service call Service_International (&43). - -Operating system interface --------------------------- - -The operating system maintains the following variables:- - -1) The current alphabet number, ie the alphabet number of the currently -selected alphabet. - -2) The current keyboard number, ie the country number of the currently -selected keyboard. - -3) The current country number, ie the country number of the currently -selected country. NB This may not be relevant if the alphabet and/or keyboard -have been set separately. - -These variables are controlled by a number of OS_Byte calls:- - -OS_Byte &46 - Read/set country ------------------------------- - -in: R1 <> 127 : Select country whose country number is R1. - -out: R1 = old country number, if R1 on entry was valid. - R1 = 0 => R1 on entry did not correspond to a known country (checked - for by issuing the service to convert the country number into an - alphabet number). - - -in: R1 = 127 : Read country number. - -out: R1 = current country number. - - -OS_Byte &47 - Read/set alphabet/keyboard ----------------------------------------- - -in: R1 in range 0..126: Select alphabet from alphabet number or country - number specified by R1. - -out: R1 = old alphabet number, if R1 on entry was valid. - R1 = 0 => R1 on entry did not correspond to a known country or - alphabet. - - -in: R1 = 127: Read alphabet number. - -out: R1 = current alphabet number. - - -in: R1 in range 128..254: Select keyboard from country number specified - by (R1-128). - -out: R1 = old keyboard number, if R1 on entry was valid. - R1 = 0 => R1 on entry did not correspond to a known country. - - -in: R1 = 255: Read keyboard number. - -out: R1 = current keyboard number. - - -OS_Byte &F0 - Read country number ---------------------------------- - -in: R1 = 0 - R2 = &FF - -out: R1 = current country number - -This call is provided for backwards compatibility with international versions -of the Master Compact. - - -Service calls -------------- - -The service call Service_International (R1=&43) is issued at various times by -the operating system and by the International module. The reason for the call -is specified by the contents of R2, as follows:- - -R2 = &00: Convert country name to country number - -in: R3 -> null-terminated country name string (may be abbreviated - with '.') - -out: All registers preserved if country not recognised, otherwise:- - R1 = 0 (call claimed) - R4 = country number - -R2 = &01: Convert alphabet name to alphabet number - -in: R3 -> null-terminated alphabet name string (may be abbreviated - with '.') - -out: All registers preserved if alphabet not recognised, otherwise:- - R1 = 0 (call claimed) - R4 = alphabet number - -R2 = &02: Convert country number to country name - -in: R3 = country number - R4 -> buffer for name - R5 = buffer length - -out: All registers preserved if country number not recognised, otherwise:- - R1 = 0 (call claimed) - Buffer holds country name (no terminator) truncated to buffer length - R5 = number of characters put into buffer - -R2 = &03: Convert alphabet number to alphabet name - -in: R3 = alphabet number - R4 -> buffer for name - R5 = buffer length - -out: All registers preserved if alphabet number not recognised, otherwise:- - R1 = 0 (call claimed) - Buffer holds alphabet name (no terminator) truncated to buffer length - R5 = number of characters put into buffer - - -R2 = &04: Convert country number to alphabet number - -in: R3 = country number - -out: All registers preserved if country number not recognised, otherwise:- - R1 = 0 (call claimed) - R4 = alphabet number - - -R2 = &05: Define a range of characters from a given alphabet - -in: R3 = alphabet number - R4 = ASCII code of first character in range - R5 = ASCII code of last character in range - -out: All registers preserved if alphabet number not recognised, otherwise:- - R1 = 0 (call claimed) - -If the alphabet number is recognised by the module, it should define all -characters in the range R4 to R5 inclusive with the appropriate character -shapes (using VDU 23,code,...). Any characters which do not have defined -shapes in the specified alphabet (eg codes &80-&9F in Latin1) should be left -unchanged. - -R2 = &06: Notification that the keyboard number has changed. - -in: R3 = new keyboard number - R4 = alphabet number associated with the keyboard number (not - necessarily the same as the current alphabet number) - -out: All registers preserved (call should never be claimed). - -This call is issued so that modules providing keyboard handlers. - - -OS_CLI commands provided ------------------------- - - *Alphabet [<country name> | <alphabet name>] - -*Alphabet sets an alphabet from a country or alphabet name. -*Alphabet with no parameter displays the currently selected alphabet. - - - *Country [<country name>] - -*Country sets the appropriate alphabet and keyboard driver for a particular -country. -*Country with no parameter displays the currently selected country. - - - *Keyboard [<country name>] - -*Keyboard sets the keyboard driver for a particular country. -*Keyboard with no parameter displays the currently selected keyboard. - - - *Alphabets - -*Alphabets lists the names of the available alphabets. - - - *Countries - -*Countries lists the names of known countries - diff --git a/s/PMF/KbdDrA1 b/s/PMF/KbdDrA1 deleted file mode 100644 index cce231fc..00000000 --- a/s/PMF/KbdDrA1 +++ /dev/null @@ -1,611 +0,0 @@ -; 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. -; -; > Sources.PMF.KbdDrA1 - -; Archimedes keyboard driver. - -; *********************************** -; *** C h a n g e L i s t *** -; *********************************** - -; Date Who Description -; ---- --- ----------- -; 24-Feb-93 SMC Split from file "key". -; Use generic keyboard/mouse interfaces. - - [ PollMouse -K1ack * K1sack - | -K1ack * K1smak - ] - - MACRO -$lab RXonTXoff $reg, $cond -$lab - LDR$cond.B $reg, IRQMaskB - BIC$cond $reg, $reg, #KARTTxBit - ORR$cond $reg, $reg, #KARTRxBit - STR$cond.B $reg, IRQMaskB - MEND - - MACRO -$lab TXonRXoff $reg, $cond -$lab - LDR$cond.B $reg, IRQMaskB - BIC$cond $reg, $reg, #KARTRxBit - ORR$cond $reg, $reg, #KARTTxBit - STR$cond.B $reg, IRQMaskB - MEND - - MACRO -$lab RXon $reg, $cond -$lab - LDR$cond.B $reg, IRQMaskB - ORR$cond $reg, $reg, #KARTRxBit - STR$cond.B $reg, IRQMaskB - MEND - - MACRO -$lab TXon $reg, $cond -$lab - LDR$cond.B $reg, IRQMaskB - ORR$cond $reg, $reg, #KARTTxBit - STR$cond.B $reg, IRQMaskB - MEND - - MACRO -$lab TXoff $reg, $cond -$lab - LDR$cond.B $reg, IRQMaskB - BIC$cond $reg, $reg, #KARTTxBit - STR$cond.B $reg, IRQMaskB - MEND - - GBLS irqregs -irqregs SETS """R4-R10, PC""" - -; ***************************************************************************** -; -; Start of code - -ArthurKeyDriver - -; ***************************************************************************** -; -; Initialise driver. -; -A1KeyInit -; Initialise the baud rate generator - - MOV R12, #IOC - MOV R0, #1 - STRB R0, Timer3Low - MOV R0, #0 - STRB R0, Timer3High - STRB R0, Timer3Go - - STRB R0, KARTTx ; Write dummy byte - - MOV R0, #&800 -10 - SUBS R0, R0, #1 ; copy Jon's loop - BNE %BT10 - - LDRB R0, KARTRx ; Read dummy byte - - [ AssemblePointerV - MOV r0, #PointerV - ADR r1, A1Pointer - Push lr - SWI OS_Claim - Pull lr - ] - - [ AssembleKEYV - MOV r0, #KEYV - ADR r1, A1KeyVec - MOV r2, r12 - Push lr - SWI OS_Claim - Pull pc - | - MOV pc, lr - ] - -; ***************************************************************************** -; -; Reset keyboard hardware. -; -A1Reset - MOV R0, #HRDRESET - STRB R0, ResetState - - ASSERT HRDRESET = &FF - STRB R0, KeyRow ; no key being received - STRB R0, Reply - STRB R0, LastKbId - STRB R0, KbIdHalf - STRB R0, RequestLED - - MOV R0, #K1rqid - STRB R0, RequestKbId - - MOV R0, #0 - STRB R0, JustGotKbId - STRB R0, MouseCount ; start with an X coordinate - STRB R0, SPDRec - STRB R0, RequestSPD - STRB R0, RequestMouse - [ AssemblePointerV - STR r0, MouseXCount - STR r0, MouseYCount - ] - - TXonRXoff R0 ; enable Tx IRQ, disable Rx IRQ - - MOV pc, lr - -; ***************************************************************************** -; -; Handle enable and update LEDs (r1=state (bit 2=scroll, 1=num, 0=ctrl)). -; -; In: r0 = reason code 3 or 4 -; r1 = state (bit 2=scroll lock, 1=num lock, 0=caps lock) if r0=3 -; r12 = IOC -; -A1KeyVec - TEQ r0, #3 ; if not set LED - TEQNE r0, #4 ; and not enable then - MOVNE pc, lr ; pass it on - - Push "r0,r1,r11,lr" - - MOV r11, #KeyWorkSpace - - TEQ r0, #4 ; if enable then - MOVEQ r0, #0 - STREQB r0, JustGotKbId ; clear flag - RXon r0, EQ ; enable RX IRQs - Pull "r0,r1,r11,pc",EQ ; and pass on call - - LDRB r0, KbId - CMP r0, #1 ; if id >= 1 then new (C=1) - BCS %FT10 - - TST r1, #1 - MOVEQ r1, #LEDOFF - MOVNE r1, #LEDON -10 - STRB r1, RequestLED - TXon r0 - - Pull "r0,r1,r11,pc" - - [ AssemblePointerV - -; ***************************************************************************** -; -; A1Pointer - Return mouse movements on PointerV poll. -; -; In: r0 = reason code 0 -; r1 = pointer device type (must be 0 for us) -; Out: r2 = signed 32-bit X movement -; r3 = signed 32-bit Y movement -; -A1Pointer - TEQ r0, #0 ; If not poll - TEQEQ r1, #0 ; or not type 0 then - MOVNE pc, lr ; pass on call. - - LDR r2, MouseXCount - STR r0, MouseXCount - LDR r3, MouseYCount - STR r0, MouseYCount - - Pull pc ; Claim call. - ] - -; ***************************************************************************** -; -; IRQ routine -; -; in: R2 = IOC request B flags -; R0-R3, R11, R12 already saved, R14 irrelevant - - - [ AssemblingArthur -IrqRx ROUT - Push "R4-R10, R14" ; stack regs if new MOS IRQ vector - | -KeyIrq ROUT - TST R2, #KARTTxBit ; transmit empty ? - BNE IrqTx - Push "R4-R10" - MOV R12, #IOC ; already set up in new IRQ scheme - ] - MOV R11, #KeyWorkSpace - -; Keyboard receive interrupt - -; We now have to wait around for a period of 16 microseconds (or so they say) -; because of the hardware design. - -; This is doubly annoying because I have no idea what speed this processor is -; going at, so I don't know how many S-cycles this is, and there aren't enough -; hardware timers around to waste one doing this thankless task. - -; In addition, because I am on the IRQ vector, the other IRQ users have -; probably wasted at least 16 microseconds anyway - at least the code seems -; to work perfectly well without this delay loop. - -; Nevertheless, until we can come up with a better solution, I shall do a -; delay of (about) 16*8 S-cycles. -; - - MOV R0, #16*8/5 ; delay for an unspecified period -IrqRxDelayLoop - SUBS R0, R0, #1 ; this breaks my heart, - BNE IrqRxDelayLoop ; it really does ! - - LDRB R0, KARTRx ; get data byte - LDRB R1, ResetState ; and what we sent last - - CMP R0, #K1rak2 ; is it a reset thingy ? - BCS ProcessReset ; [yes, so check it] - - CMP R1, #K1rak2 ; are we resetting anyway ? - BCS IrqBadRx ; if so then bad reset - - AND R2, R0, #&F0 ; get reason code - - LDRB R1, LastKbId ; get last keyboard ID - TEQ R1, #&FF ; is it valid yet ? - BNE ValidKbId ; [yes, so we know what to expect] - - TEQ R2, #IDTYPE ; is it old keyboard id - BEQ IsOldKeyboard ; [is old keyboard] - - BIC R2, R2, #K1kbidmask ; check for new keyboard id - TEQ R2, #K1kbid - BNE IrqBadRx ; not a keyboard id, so reset - - AND R1, R0, #K1kbidmask ; get relevant bits - [ AssembleA1KeyHandler - ADRL R0, NewKeyStruct - ] - B AcknowledgeId - -IsOldKeyboard - AND R0, R0, #&0F ; get ID part - LDRB R1, KbIdHalf - TST R1, #&80 - STRNEB R0, KbIdHalf ; got half of keyboard id - MOVNE R0, #K1nack - BNE IrqRxAck - - ORR R1, R1, R0, LSL #4 ; get full keyboard id - MOV R0, #&FF - STRB R0, KbIdHalf - [ AssembleA1KeyHandler - ADRL R0, OldKeyStruct - ] - -AcknowledgeId - [ AssembleA1KeyHandler - LDRB R8, LastKbId ; get last keyboard id - TEQ R8, R1 ; is it same - STRNE R0, KeyVec ; if different, set up our handler - ] - MOV R0, #&FF - STRB R0, JustGotKbId ; tell TX handler to disable interrupts until KEYV enable call - - [ AssembleKEYV - MOV r0, #0 - MOV r10, #KEYV - BL CallVector - | - BL GotKbId - ] - - B IrqRxAckScan ; send ack - -; R1 = keyboard ID - now dispatch code - -ValidKbId - TEQ R1, #0 - BNE NewKeyboardDispatch - -OldKeyboardDispatch - TST R0, #MMOVED ; is it mouse data ? - BNE ProcessOldMouseData - TEQ R2, #KEYDOWN ; is it key down ? - BEQ ProcessOldKeyDown - TEQ R2, #KEYUP ; is it key up ? - BEQ ProcessOldKeyUp - TEQ R2, #SPDDONE ; is it SPD data ? - BEQ ProcessOldSPDData - B IrqBadRx ; spurious - -NewKeyboardDispatch - TST R2, #K1notmousedata ; is it mouse data ? - BEQ ProcessNewMouseData - TEQ R2, #K1kdda ; is it key down ? - BEQ ProcessNewKeyDown - TEQ R2, #K1kuda ; is it key up ? - BEQ ProcessNewKeyUp - TEQ R2, #K1pdat ; is it SPD data ? - BEQ ProcessNewSPDData - B IrqBadRx ; spurious - - -; ***************************************************************************** -; -; ProcessReset - Process reset code from keyboard -; -; in: R0 = code from keyboard -; R1 = ResetState - -ProcessReset ROUT - -; Check sequencing - - TEQ R1, R0 ; is reply what was expected - BNE IrqBadRx ; no, so reset - -; Now continue the sequence - - TEQ R1, #K1rak2 ; end of sequence ? - MOVEQ R1, #K1nack ; then send a nack - SUBNE R1, R1, #1 ; else next thing to go - STRB R1, ResetState ; store back - - TXonRXoff R0 - - Pull $irqregs - -IrqBadRx - -; Restart the reset sequence - - BL A1Reset - Pull $irqregs - -; ***************************************************************************** - -ProcessOldSPDData -ProcessNewSPDData - LDRB R1, SPDRec - SUBS R1, R1, #1 - STRCSB R1, SPDRec ; dec number to go (if not 0) - - LDRCS R1, SPDoutput - MOVCS R1, R1, LSR #4 - ORRCS R1, R1, R0, LSL #28 ; put in new data - STRCS R1, SPDoutput - - B IrqRxAckScan - -; ***************************************************************************** - -ProcessOldMouseData ; R0 = 01xx xxxx - TST R0, #&20 ; get sign bit of data (bit 5) - BICEQ R0, R0, #&40 ; move to bit 6 (where it is on new) -ProcessNewMouseData - LDRB R1, MouseCount - ADR R2, MouseDelta - STRB R0, [R2, R1] ; no need to clear top bit - - EORS R1, R1, #1 ; move to other coordinate - STRB R1, MouseCount - - MOVNE R0, #K1back - BNE IrqRxAck - - LDRB R3, [R2, #1] ; get delta Y - MOV R3, R3, LSL #25 ; sign extend it - MOV R3, R3, ASR #25 - - LDRB R2, [R2] ; get delta X - MOV R2, R2, LSL #25 ; sign extend it - MOV R2, R2, ASR #25 - - [ AssemblePointerV - LDR r0, MouseXCount - ADD r0, r0, r2 - STR r0, MouseXCount - LDR r0, MouseYCount - ADD r0, r0, r3 - STR r0, MouseYCount - | - BL ProcessMouseXY - ] - - B IrqRxAckScan - -; ***************************************************************************** - -; in: R1 = keyboard id - -ProcessOldKeyDown -ProcessNewKeyDown ROUT - LDRB R2, KeyRow - TEQ R2, #&FF ; have we had a row already ? - STREQB R0, KeyRow ; no so store row - MOVEQ R0, #K1back - BEQ IrqRxAck ; and acknowledge Rx - - EOR R3, R0, R2 ; test if save movement type - TST R3, #&F0 - BNE IrqBadRx ; not same, so reset - - AND R0, R0, #&0F ; get new data - AND R2, R2, #&0F ; and row data - - TEQ R1, #0 - ORREQ R2, R2, R0, LSL #4 ; old keyboard number - ORRNE R2, R0, R2, LSL #4 ; new key number - - MOV R0, #&FF - STRB R0, KeyRow ; reset 'had row' flag - - MOV r0, #2 ; indicate key down - MOV r1, r2 - [ AssembleKEYV - MOV r10, #KEYV - BL CallVector - MOV r12, #IOC - | - BL GotKey - ] - -IrqRxAckScan - -; Re-enable Tx interrupts and queue an acknowledge - - MOV R0, #K1ack ; either sack or smak as appropriate -IrqRxAck - STRB R0, Reply - TXonRXoff R0 - Pull $irqregs ; claimed irq, so grab link and PC - -; ***************************************************************************** - -; in: R1 = keyboard id - -ProcessOldKeyUp -ProcessNewKeyUp ROUT - LDRB R2, KeyRow - TEQ R2, #&FF ; have we had a row already ? - STREQB R0, KeyRow ; no so store row - MOVEQ R0, #K1back - BEQ IrqRxAck ; and acknowledge Rx - - EOR R3, R0, R2 ; test if save movement type - TST R3, #&F0 - BNE IrqBadRx ; not same, so reset - - AND R0, R0, #&0F ; get new data - AND R2, R2, #&0F ; and row data - - TEQ R1, #0 - ORREQ R2, R2, R0, LSL #4 ; old key number - ORRNE R2, R0, R2, LSL #4 ; new key number - - MOV R0, #&FF - STRB R0, KeyRow ; reset 'had row' flag - - MOV r0, #1 ; indicate key up - MOV r1, r2 - [ AssembleKEYV - MOV r10, #KEYV - BL CallVector - MOV r12, #IOC - | - BL GotKey - ] - - B IrqRxAckScan - -; ***************************************************************************** - -IrqTx ROUT - [ AssemblingArthur - Push "R4-R10, R14" ; stack regs if new MOS IRQ vector - | - Push "R4-R10" - MOV R12, #IOC ; already set up in new IRQ scheme - ] - MOV R11, #KeyWorkSpace - -; First see if we're in a reset sequence - - LDRB R0, ResetState ; are we in a reset ? - TEQ R0, #0 - BEQ %FT05 ; not in a reset - - CMP R0, #K1rak2 ; are we sending the reset nack ? - BCS %FT25 ; no, just send reset code - MOV R1, #0 ; yes, zero the reset state - STRB R1, ResetState - STRB R0, KARTTx - Pull $irqregs ; don't disable TX - -; Now see if any outstanding requests - -05 - LDRB R0, RequestSPD ; is there an SPD request ? - TEQ R0, #0 - BEQ %FT10 ; [no SPD request] - - MOV R1, #K1prst ; code to send keyboard - MOV R2, #0 ; no further SPD request - STRB R2, RequestSPD - MOV R2, #8 - STRB R2, SPDRec ; nibbles still to be sent/received - STRB R1, KARTTx ; send the byte - Pull $irqregs ; exit without disabling Tx - -10 - LDRB R0, RequestKbId ; is there a pending keyboard request ? - TEQ R0, #0 - MOVNE R1, #0 - STRNEB R1, RequestKbId ; no further request - STRNEB R0, KARTTx ; send the byte - Pull $irqregs, NE ; exit without disabling Tx - - LDRB R0, RequestMouse ; is there a pending mouse request ? - TEQ R0, #0 - MOVNE R1, #0 - STRNEB R1, RequestMouse ; no further request - STRNEB R0, KARTTx - Pull $irqregs, NE ; exit without disabling Tx - - LDRB R0, RequestLED ; is there a pending LED request ? - TEQ R0, #&FF - MOVNE R1, #&FF - STRNEB R1, RequestLED - STRNEB R0, KARTTx - Pull $irqregs, NE ; exit without disabling Tx - - LDRB R0, SPDRec ; are we converting some SPD data - TEQ R0, #0 - BEQ %FT20 ; branch if not - - LDR R1, SPDinput - AND R2, R1, #&F ; get nybble to be sent - ORR R2, R2, #K1rqpd - MOV R1, R1, LSR #4 ; shift out the nybble sent - STR R1, SPDinput - STRB R2, KARTTx - B %FT30 ; disable Tx, so we don't send another - ; nibble before we get the conversion -20 - LDRB R0, Reply - TEQ R0, #&FF - BEQ %FT30 ; no reply to send -25 - STRB R0, KARTTx ; send the reply - MOV R0, #&FF - STRB R0, Reply ; nothing else to send - - LDRB R0, JustGotKbId - TEQ R0, #0 ; if just got keyboard id then - TXoff R0, NE ; disable all interrupts - Pull $irqregs, NE ; and wait for KEYV enable call -30 - RXonTXoff R0 - Pull $irqregs - - END diff --git a/s/PMF/convdate b/s/PMF/convdate deleted file mode 100644 index 58d209eb..00000000 --- a/s/PMF/convdate +++ /dev/null @@ -1,109 +0,0 @@ -; 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.ConvDate - - MACRO - CDATT $mnemonic, $stackoffset, $digits - ASSERT (:LEN: "$mnemonic") = 2 - ASSERT ((CDAT$mnemonic-(CDATBranch+8)) :AND: &FFFFFC03) = 0 - ASSERT ($stackoffset >=0) :LAND: ($stackoffset < 64) - LCLA digits - [ "$digits"="" -digits SETA 2 - | -digits SETA $digits - ] - ASSERT (digits >= 1) :LAND: (digits <= 3) - - DCB digits :OR: ($stackoffset :SHL: 2) - DCB (CDAT$mnemonic-(CDATBranch+8)) :SHR: 2 - = "$mnemonic" - MEND - -; ***************************************************************************** -; -; ConvertStandardDateAndTime - Convert from 5-byte cs representation to -; format specified in <SYS$DateFormat> -; -; in: R0 -> time block -; [R0, #0..4] = 5-byte centisecond representation -; R1 -> buffer to accept conversion -; R2 = size of buffer -; -; out: V=0 => successful conversion -; R0 = input value of R1 -; R1 = updated pointer to buffer -; R2 = updated size of buffer -; -; V=1 => failed conversion -; R0 -> error block -; R1 = input value of R1 -; R2 = input value of R2 -; - - -ConvertStandardDateAndTime ROUT -; KJB 980908 - International version just calls TerrMgr (as documented in PRM!) - Push "R3,R14" - - MOV R3,R2 ; Territory SWI wants things one register up. - MOV R2,R1 - MOV R1,R0 - MOV R0,#-1 ; Use configured territory. - SWI XTerritory_ConvertStandardDateAndTime - Pull "R3,R14" - ORRVS R14, R14, #V_bit ; set V in R14 for exit - ExitSWIHandler - -; ***************************************************************************** -; -; ConvertDateAndTime - Convert from 5-byte cs representation to -; format specified by user -; -; in: R0 -> time block -; [R0, #0..4] = 5-byte centisecond representation -; R1 -> buffer to accept conversion -; R2 = size of buffer -; R3 -> format string -; -; out: V=0 => successful conversion -; R0 = input value of R1 -; R1 = updated pointer to buffer -; R2 = updated size of buffer -; -; V=1 => failed conversion -; R0 -> error block -; R1 = input value of R1 -; R2 = input value of R2 -; - -ConvertDateAndTime ROUT - - Push "R4,R14" - - - MOV R4,R3 ; Territory SWI wants things one register up. - MOV R3,R2 - MOV R2,R1 - MOV R1,R0 - MOV R0,#-1 ; Use configured territory. - SWI XTerritory_ConvertDateAndTime - Pull "R4,R14" - ORRVS R14, R14, #V_bit ; set V in R14 for exit - ExitSWIHandler - - LTORG - - END diff --git a/s/PMF/i2cutils b/s/PMF/i2cutils deleted file mode 100644 index 213649b9..00000000 --- a/s/PMF/i2cutils +++ /dev/null @@ -1,1871 +0,0 @@ -; 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.i2cutils - -; Authors JBiggs (m2), PFellows, TDobson, AGodwin - -; *********************************** -; *** C h a n g e L i s t *** -; *********************************** - -; Date Name Description -; ---- ---- ----------- -; 28-Mar-95 JRH Added support for E2ROMs and/or CMOS, conditioned on -; E2ROMSupport which is defined elsewhere -; Uses RTCFitted and NVRamSize in KernelWS -; 03-Jul-96 JRH Took out code conditioned on :LNOT: NewClockChip -; Fixed support for E2ROM. E2 works in the same gross way as -; CMOS. Any E2 fitted > 256 bytes will not be accessed by these -; routines. -; 07-Dec-96 AMG Renaissance. Leave this file as is, allowing the E2ROMSupport -; switch to disable non-STB bits -; 12-Jun-97 TMD (Really) fix OTP access problem. -; 17-Sep-98 KJB Add support for 16K 24C128 EEPROM. -; 21-Sep-98 KJB Add OS_NVMemory SWI. -; 30-Jul-99 KJB Add support for 8K 24C64 EEPROM. -; 23-Sep-99 KJB Remove support for 24C64, add support for 4K and 8K protectable ATMEL parts. - -PhysChecksum * (((CheckSumCMOS + &30) :MOD: &F0) + &10) - -; Device addresses -RTCAddressPHI * &a0 ; Philips RTC + 240 byte CMOS -RTCAddressDAL * &d0 ; Dallas RTC + 56 byte CMOS -E2ROMAddress2K * &e0 ; 24C174 device - 2K -E2ROMAddress2K_OTP * &60 ; 24C174 device - OTP section -E2ROMAddress4K * &a4 ; 24C32 device - 4K (top 1K protectable) -E2ROMAddress8K_prot * &a2 ; 24C64 device - 8K (top 2K protectable) -E2ROMAddress8K * &ae ; 24C64 device - 8K -E2ROMAddress16K * &a8 ; 24C128 device - 16K -E2ROMAddress32K * &a6 ; 24CS256 device - 32K (top 2K possibly OTP) - - -; ***************************************************************************** -; -; HexToBCD - Convert byte in hex to BCD -; -; in: R0 = byte in hex -; -; out: R0 = byte in BCD (ie R0 := (R0 DIV 10)*16 + R0 MOD 10) -; All other registers preserved -; - -HexToBCD ROUT - Push "R1,R2, R14" - MOV R1, #10 - DivRem R2, R0, R1, R14 ; R2=R0 DIV 10; R0=R0 MOD 10 - ADD R0, R0, R2, LSL #4 - Pull "R1,R2, PC" - -; ***************************************************************************** -; -; BCDToHex - Convert byte in BCD to hex -; -; in: R0 = byte in BCD (ie x*16 + y) -; -; out: R0 = byte in hex (ie x*10 + y) -; All other registers preserved -; - -BCDToHex ROUT - Push "R14" - MOV R14, R0, LSR #4 ; R14 := x - ADD R14, R14, R14, LSL #1 ; R14 := x*3 - SUB R0, R0, R14, LSL #1 ; R0 := R0 - x*6 = x*10 - Pull "PC" - - -; ***************************************************************************** -; -; HTBSR9 - hex to BCD and store at "next free byte" R9 -; -HTBS9 ROUT - Push R14 - BL HexToBCD - STRB R0, [R9], #1 - Pull PC - -; ***************************************************************************** -; -; Write - Write a byte of CMOS RAM specified by logical address -; -; in: R0 = address in CMOS RAM -; R1 = data -; -; out: All registers preserved -; - -WriteWithError ROUT - Push "R0-R4, R14" - BL MangleCMOSAddress - BCC %FT05 - - ADD R13, R13, #4 ; junk stacked R0 - ADR R0, ErrorBlock_CoreNotWriteable - [ International - BL TranslateError - | - SETV - ] - Pull "R1-R4,PC" - - MakeErrorBlock CoreNotWriteable - -WriteWithoutProtection ; allowing write to "OTP" and protected section - Push "R0-R4, R14" - BL MangleCMOSAddress - Pull "R0-R4, PC", CS ; if invalid, then exit - MOV R2, R0 - MOV R3, R1 - CMP R0, #&10 - MOVLO R4, #&1000000 ; don't change checksum for OTP - BLO %FT10 - B %FT08 ; do change checksum for protected region - -Write - Push "R0-R4, R14" - BL MangleCMOSAddress - Pull "R0-R4, PC", CS ; if invalid, then exit -05 - [ E2ROMSupport - CMP r0, #&10 - Pull "R0-R4, PC", CC ; don't write to OTP section - ] - - [ E2ROMSupport - MOV R14, #0 ; don't write to protected section - LDRB R14, [R14, #NVRamWriteSize] - CMP R0, R14, LSL #8 ; (note assumption that NVRamWriteSize is - Pull "R0-R4, PC", HS ; outside mangled region). - ] - - MOV R2, R0 - MOV R3, R1 -08 - [ ChecksumCMOS - BL ReadStraight ; calculate new checksum : - MOV R4, R0 - TEQ R4, R3 ; don't bother with write if - Pull "R0-R4, PC", EQ ; oldcontents == newcontents - - MOV R0, #PhysChecksum - BL ReadStraight - SUB R0, R0, R4 ; = oldsum - oldcontents - ADD R4, R0, R3 ; + newcontents - - AND R4, R4, #&FF - CMPS R2, #PhysChecksum ; don't write new checksum ... - ORREQ R4, R4, #&1000000 ; if checksum is being written - ] -10 - CMP r2, #&100 ; check small cache limit - BCS %FT15 - LDR R1, =CMOSRAMCache ; update cache, but always write to - STRB R3, [R1, R2] ; real hardware as well -15 - - [ HAL - Push "R2,R3,sb,R12" - AddressHAL - CallHAL HAL_NVMemoryType - AND R0, R0, #NVMemoryFlag_Provision - TEQ R0, #NVMemoryFlag_None - - ; If there's no NVmemory, all we have is the internal cache. - Pull "R2,R3,sb,R12", EQ - Pull "R0-R4,PC", EQ - - TEQ R0, #NVMemoryFlag_HAL - BNE %FT20 ; Go and do IIC stuff. - - ; Make the HAL call - we have to write the data into a buffer. - Pull "R0" - STRB R3, [sp, #-4]! - MOV R1, sp - MOV R2, #1 - CallHAL HAL_NVMemoryWrite - TST R4, #&1000000 - BNE %FT18 - LDR R1, =CMOSRAMCache - STRB R4, [R1, #PhysChecksum] - STRB R4, [sp] - MOV R0, #PhysChecksum - MOV R1, sp - MOV R2, #1 - CallHAL HAL_NVMemoryWrite -18 - ADD sp, sp, #4 - Pull "R3,sb,R12" - Pull "R0-R4,PC" -20 - Pull "R2,R3,sb,R12" - ] - - - [ E2ROMSupport - MOV R0, R2 - BL GetI2CAddress ; convert to device address + offset - MOV R2, R0 ; save the offset - | - MOV R1, #RTCAddressPHI - ] - - - AND R0, R1, #&FF ; device address for write - ORR R0, R0, #1:SHL:29 ; retry - TST R1, #&100 ; NE if two byte offset - SUB R13, R13, #4 - MOV R14, R13 - MOVNE R1, R2, LSR #8 - STRNEB R1, [R14], #1 ; offset (MSB) - STRB R2, [R14], #1 ; offset (LSB) - STRB R3, [R14], #1 ; data - MOV R1, R13 - SUB R2, R14, R13 - BL IIC_Op - ADD R13, R13, #4 - - [ ChecksumCMOS - TST R4, #&1000000 ; loop again to write new checksum - MOV R3, R4 - MOV R2, #PhysChecksum - ORR R4, R4, #&1000000 ; but ensure it only happens once - BEQ %BT10 - ] - Pull "R0-R4, PC" - -; ***************************************************************************** -; -; WriteBlock - Write a block of CMOS RAM specified by logical address -; -; in: R0 = address in CMOS RAM -; R1 = address to copy from -; R2 = length -; -; out: All registers preserved -; - - -WriteBlock ROUT - Push "R0-R4,R14" - [ E2ROMSupport - MOV R14, #0 - LDRB R4, [R14, #NVRamWriteSize] - LDRB R14, [R14, #NVRamSize] - MOV R4, R4, LSL #8 - MOV R14, R14, LSL #8 - | - MOV R14, #240 - MOV R4, R14 - ] - - CMP R0, R14 - BHS %FT90 - - ADDS R3, R0, R2 ; R3 = end address - check unsigned overflow - BCS %FT90 - CMP R3, R14 - BHI %FT90 - - CMP R0, R4 ; ignore writes totally outside writable area - BHS %FT80 - - SUBS R14, R3, R4 - SUBGT R2, R2, R14 ; truncate writes partially outside writable area - - TEQ R2, #0 - BEQ %FT80 - - CMP R0, #CheckSumCMOS ; are we going to write the checksum byte? - BHI %FT03 - CMP R3, #CheckSumCMOS - BHS %FT05 - -03 -; we're not writing the checksum byte manually, so we need to update it - MOV R4, R1 - MOV R1, #0 - BL ChecksumBlock ; find the checksum of what we're about to - ORR R3, R1, #&80000000 ; overwrite - MOV R1, R4 - B %FT08 - -05 MOV R3, #0 -08 MOV R4, #0 -10 BL WriteSubBlock - BVS %FT80 - TEQ R2, #0 - BNE %BT10 - - TST R3, #&80000000 ; were we going to write the checksum? - BEQ %FT80 - - MOV R0, #CheckSumCMOS - BL Read ; get old checksum byte - ADD R0, R0, R4 ; add new data checksum - SUB R1, R0, R3 ; subtract old checksum - MOV R0, #CheckSumCMOS - BL Write ; write back new checksum - -80 - Pull "R0-R4,PC" - -90 - ADD SP, SP, #4 ; junk stacked R0 - ADR R0, ErrorBlock_CoreNotWriteable - [ International - BL TranslateError - | - SETV - ] - Pull "R1-R4,PC" - -; ***************************************************************************** -; -; WriteSubBlock - Write a block of CMOS RAM specified by logical address. -; Assumes the address is valid, and will only read as much -; as it can in a single IIC transaction. -; -; in: R0 = address in CMOS RAM -; R1 = address to copy from -; R2 = length -; -; out: R0-R2 updated to reflect the amount written. -; R4 incremented by sum of bytes written. -; -WriteSubBlock ROUT - Push "R3,R5-R6,R14" - MOV R6, R4 -; establish end of the current contiguous block, and the logical->physical address offset. - CMP R0, #1 ; 00 -> 40 uncached - MOVLO R3, #1 - MOVLO R4, #&40-&00 - BLO %FT10 - CMP R0, #&C0 ; [01..C0) -> [41..100) cached - MOVLO R3, #&C0 - MOVLO R4, #&41-&01 - BLO %FT10 - CMP R0, #&F0 ; [C0..F0) -> [10..40) cached - MOVLO R3, #&F0 - MOVLO R4, #&10-&C0 - BLO %FT10 - CMP R0, #&100 - ADDHS R3, R0, R2 ; [100..) -> [100..) uncached - MOVHS R4, #0 - BHS %FT10 - -; [F0..100) -> not written - MOV R3, #&100 - ADD R14, R0, R2 - CMP R3, R14 - MOVHI R3, R14 - SUB R14, R3, R0 - ADD R0, R0, R14 - ADD R1, R1, R14 - SUB R2, R2, R14 - Pull "R3,R5-R6,PC" - -; R3 = logical end of current segment (exclusive) -; R4 = offset from logical to physical address for this segment -10 - ADD R14, R0, R2 - CMP R3, R14 - MOVHI R3, R14 - [ E2ROMSupport -; R3 = logical end of possible transaction (exclusive). Now check we don't cross page boundaries. - MOV R14, #0 - LDRB R14, [R14, #NVRamPageSize] - MOV R5, #1 - MOV R14, R5, LSL R14 ; R14 = (1<<pagesize) - - ADD R5, R0, R4 ; R5 = physical start address - ADD R5, R5, R14 - SUB R14, R14, #1 - BIC R5, R5, R14 ; R5 = physical end of page with start address in - SUB R5, R5, R4 ; R5 = logical end of page with start address in - - CMP R5, R3 - MOVLO R3, R5 ; adjust R3 to not cross page boundary - ] - - CMP R0, #&100 ; check it's a cacheable segment - BHS %FT15 - - LDR R14, =CMOSRAMCache - Push "R3, R4" - ADD R3, R3, R4 ; R3 = physical end address - ADD R4, R4, R0 ; R4 = physical address - ADD R3, R3, R14 ; R3 = cache end address - ADD R4, R4, R14 ; R4 = cache address - SUB R14, R3, R4 ; R14 = bytes being written - MOV R5, R1 ; remember R1 -12 LDRB R14, [R1], #1 ; update cache copy - STRB R14, [R4], #1 - CMP R4, R3 - BLO %BT12 - MOV R1, R5 ; restore R1, and continue to update real memory - Pull "R3, R4" -15 - Push "R0-R2" - ADD R0, R0, R4 ; R0 = physical address - [ HAL - Push "sb, R12" - MOV R5, R0 ; save address - AddressHAL - CallHAL HAL_NVMemoryType - AND R0, R0, #NVMemoryFlag_Provision - TEQ R0, #NVMemoryFlag_None - - ; If there's no NVmemory, tough - we just return. - Pull "sb,R12", EQ - Pull "R0-R2", EQ - MOVEQ R2, #0 ; nothing written - Pull "R3,R5-R6,PC", EQ - - TEQ R0, #NVMemoryFlag_HAL - MOV R0, R5 ; restore address - BNE %FT17 ; do IIC things. - - ; Make the HAL call - CallHAL HAL_NVMemoryWrite ; returns bytes wrtten in R0 - MOV R5, R0 - Pull "sb,R12" - - Pull "R0-R2" - - ADD R0, R0, R5 - SUB R2, R2, R5 - -16 SUBS R5, R5, #1 ; update checksum - LDRCS R14, [R1], #1 - ADDCS R6, R6, R14 - BCS %BT16 - MOV R4, R6 - - Pull "R3,R5-R6,PC" - -17 - Pull "sb,R12" - ] - - [ E2ROMSupport - BL GetI2CAddress ; convert to device address and offset - | - MOV R1, #RTCAddressPHI - ] - - MOV R2, R0 ; save the offset - SUB R13, R13, #12*2+4 - MOV R14, R13 - TST R1, #&100 ; 2-byte address? - MOVNE R0, R2, LSR #8 - STRNEB R0, [R14], #1 ; offset (MSB) - STRB R2, [R14], #1 ; offset (LSB) - - SUB R14, R14, R13 - STR R14, [R13, #12] ; transfer 1 length - - AND R14, R1, #&FF - ORR R0, R14, #1:SHL:29 ; (retry) - STR R0, [R13, #4] ; transfer 1 address - ORR R14, R14, #1:SHL:31 ; (no repeated start) - STR R14, [R13, #16] ; transfer 2 address - STR R13, [R13, #8] ; transfer 1 data - - ADD R14, R13, #12*2+4 - LDMIA R14, {R0-R2} - SUB R5, R3, R0 ; R5 = bytes being written - ADD R0, R0, R5 ; update return R0 - SUB R2, R2, R5 ; update return R2 - STMIB R14, {R0,R2} - - STR R1, [R13, #20] ; transfer 2 data - STR R5, [R13, #24] ; transfer 2 length - ADD R0, R13, #4 - MOV R1, #2 - BL IIC_OpV - - LDR R1, [R13, #20] ; recover data pointer - ADD R13, R13, #12*2+4+4 -20 - LDRB R0, [R1], #1 - SUBS R5, R5, #1 - ADD R6, R6, R0 ; update checksum counter - BNE %BT20 - ; V clear - MOV R4, R6 - - Pull "R0,R2,R3,R5,R6,PC" - -; ***************************************************************************** -; -; Read - Read a byte of CMOS RAM specified by logical address -; ReadStraight - Read a byte of CMOS RAM specified by physical address -; ReadWithError - Read a byte of CMOS RAM specified by logical address, giving error if out of range -; -; in: R0 = address in CMOS RAM -; -; out: R0 = data (illegal address return 0, or error for ReadWithError) -; All other registers preserved -; - -ReadStraight ROUT - Push "R1,R2,R14" - B %FT10 - -ReadWithError - Push "R1,R2,R14" - BL MangleCMOSAddress - BCC %FT10 - ADR R0, ErrorBlock_CoreNotReadable - [ International - BL TranslateError - | - SETV - ] - Pull "R1,R2,PC" - - MakeErrorBlock CoreNotReadable - -Read - Push "R1,R2,R14" - BL MangleCMOSAddress - MOVCS R0, #0 ; pretend illegal addresses contain 0 - Pull "R1,R2,PC", CS -10 - TEQ R0, #&40 ; is it Econet station number - BEQ %FT15 ; if so then don't use cache - CMP R0, #&10 ; don't cache the clock - [ E2ROMSupport - BHS %FT13 - MOV R14, #0 - LDR R14, [R14, #RTCFitted] - TEQ R14, #0 - BNE %FT15 - | - BLO %FT15 - ] -13 CMP R0, #&100 ; check small cache limit - LDRCC R2, =CMOSRAMCache ; if in range - LDRCCB R0, [R2, R0] ; read from cache - Pull "R1,R2,PC", CC ; and exit -15 - -; else drop thru into real CMOS reading code - - [ HAL - Push "R3,sb,R12" - MOV R4, R0 ; save address - AddressHAL - CallHAL HAL_NVMemoryType - AND R0, R0, #NVMemoryFlag_Provision - TEQ R0, #NVMemoryFlag_None - - ; If there's no NVmemory, pretend addresses contain 0 - Pull "R3,sb,R12", EQ - MOVEQ R0, #0 - Pull "R1,R2,PC", EQ - - TEQ R0, #NVMemoryFlag_HAL - MOV R0, R4 ; restore address - BNE %FT20 - - ; Make the HAL call - we have to provide a buffer. - SUB sp, sp, #4 ; make some space on the stack - MOV R1, sp - MOV R2, #1 - CallHAL HAL_NVMemoryRead - LDRB R0, [sp], #4 ; read back from stack and restore - Pull "R3,sb,R12" - Pull "R1,R2,PC" - -20 - Pull "R3, sb,R12" - ] - - [ E2ROMSupport - BL GetI2CAddress ; convert to device address and offset - | - MOV R1, #RTCAddressPHI - ] - - SUB R13, R13, #2*12+4 - MOV R14, R13 - TST R1, #&100 - MOVNE R2, R0, LSR #8 - STRNEB R2, [R14], #1 ; offset (MSB) - STRB R0, [R14], #1 ; offset (LSB) - SUB R14, R14, R13 - STR R13, [R13, #8] ; transfer 1 data - STR R14, [R13, #12] ; transfer 1 length - AND R14, R1, #&FF - ORR R2, R14, #1:SHL:29 ; retry - STR R2, [R13, #4] ; transfer 1 address - ORR R14, R14, #1 ; device address for read - STR R14, [R13, #16] ; transfer 2 address - ADD R14, R13, #3 - STR R14, [R13, #20] ; transfer 2 data - MOV R14, #1 - STR R14, [R13, #24] ; transfer 2 length - ADD R0, R13, #4 - MOV R1, #2 - BL IIC_OpV - LDRB R0, [R13, #3] - ADD R13, R13, #2*12+4 - - Pull "R1,R2,PC" - - -; ***************************************************************************** -; -; ReadBlock - Read a block of CMOS RAM specified by logical address -; -; in: R0 = address in CMOS RAM -; R1 = address to copy to -; R2 = length -; -; out: All registers preserved -; - - -ReadBlock ROUT - Push "R0-R3,R14" - [ E2ROMSupport - MOV R14, #0 - LDRB R14, [R14, #NVRamSize] - MOV R14, R14, LSL #8 - | - MOV R14, #240 - ] - - CMP R0, R14 - BHS %FT90 - - ADDS R3, R0, R2 ; R3 = end address - check unsigned overflow - BCS %FT90 - CMP R3, R14 - BHI %FT90 - - TEQ R2, #0 - BEQ %FT80 - -10 BL ReadSubBlock - BVS %FT80 - TEQ R2, #0 - BNE %BT10 -80 - Pull "R0-R3,PC" - -90 - ADD SP, SP, #4 ; junk stacked R0 - ADR R0, ErrorBlock_CoreNotReadable - [ International - BL TranslateError - | - SETV - ] - Pull "R1-R3,PC" - -; ***************************************************************************** -; -; ReadSubBlock - Read a block of CMOS RAM specified by logical address. -; Assumes the address is valid, and will only read as much -; as it can in a single IIC transaction. -; -; in: R0 = address in CMOS RAM -; R1 = address to copy to -; R2 = length -; -; out: R0-R2 updated to reflect the amount read. -; -ReadSubBlock ROUT - Push "R3-R5,R14" -; establish end of the current contiguous block, and the logical->physical address offset. - CMP R0, #1 ; 00 -> 40 uncached - MOVLO R3, #1 - MOVLO R4, #&40-&00 - BLO %FT10 - CMP R0, #&C0 ; [01..C0) -> [41..100) cached - MOVLO R3, #&C0 - MOVLO R4, #&41-&01 - BLO %FT10 - CMP R0, #&F0 ; [C0..F0) -> [10..40) cached - MOVLO R3, #&F0 - MOVLO R4, #&10-&C0 - BLO %FT10 - CMP R0, #&100 ; [F0..100) -> [00..10) cached - MOVLO R3, #&100 - MOVLO R4, #&00-&F0 - ADDHS R3, R0, R2 ; [100..) -> [100..) uncached - MOVHS R4, #0 -; R3 = logical end of current segment (exclusive) -; R4 = offset from logical to physical address for this segment -10 - ADD R14, R0, R2 - CMP R3, R14 - MOVHI R3, R14 -; R3 = logical end of this transaction (exclusive) - TEQ R0, #0 ; check it's a cacheable segment - BEQ %FT15 - CMP R0, #&100 - BHS %FT15 - - LDR R14, =CMOSRAMCache - ADD R3, R3, R4 ; R3 = physical end address - ADD R4, R4, R0 ; R4 = physical address - ADD R3, R3, R14 ; R3 = cache end address - ADD R4, R4, R14 ; R4 = cache address - SUB R14, R3, R4 ; R14 = bytes being read - ADD R0, R0, R14 ; update return R0 - SUB R2, R2, R14 ; update return R2 - -12 LDRB R14, [R4], #1 - CMP R4, R3 - STRB R14, [R1], #1 - BLO %BT12 - Pull "R3-R5,PC" ; V will be clear -15 - Push "R0-R2" - ADD R0, R0, R4 ; R0 = physical start address - ADD R3, R3, R4 ; R3 = physical end address - [ HAL - Push "sb" - SUB R2, R3, R0 - MOV R5, R0 ; save address - AddressHAL - Push "R1-R3,R12" - CallHAL HAL_NVMemoryType - Pull "R1-R3,R12" - AND R0, R0, #NVMemoryFlag_Provision - TEQ R0, #NVMemoryFlag_None - - ; If there's no NVmemory, tough - we just return. - MOVEQ R2, #0 ; nothing read - Pull "sb", EQ - Pull "R3-R5,PC", EQ - - TEQ R0, #NVMemoryFlag_HAL - MOV R0, R5 ; restore address - BNE %FT17 ; do IIC things. - - ; Make the HAL call - Push "R12" - CallHAL HAL_NVMemoryRead ; returns bytes read in R0 - Pull "R12" - MOV R4, R0 - Pull "sb" - Pull "R0-R2" - ADD R0, R0, R4 - ADD R1, R1, R4 - SUB R2, R2, R4 - Pull "R3-R5,PC" - -17 - Pull "sb" - ] - - SUB R5, R3, R0 ; R5 = bytes being read - - [ E2ROMSupport - BL GetI2CAddress ; convert to device address and offset - | - MOV R1, #RTCAddressPHI - ] - - - MOV R2, R0 ; save the offset - SUB R13, R13, #12*2+4 - MOV R14, R13 - TST R1, #&100 ; 2-byte address? - MOVNE R0, R2, LSR #8 - STRNEB R0, [R14], #1 ; offset (MSB) - STRB R2, [R14], #1 ; offset (LSB) - - SUB R14, R14, R13 - STR R14, [R13, #12] ; transfer 1 length - - AND R14, R1, #&FF - ORR R0, R14, #1:SHL:29 ; retry - STR R0, [R13, #4] ; transfer 1 address - ORR R14, R14, #1 ; device address for read - STR R14, [R13, #16] ; transfer 2 address - STR R13, [R13, #8] ; transfer 1 data - - ADD R14, R13, #12*2+4 - LDMIA R14, {R0-R2} - ADD R0, R0, R5 ; update return R0 - SUB R2, R2, R5 ; update return R2 - STMIB R14, {R0,R2} - - STR R1, [R13, #20] ; transfer 2 data - STR R5, [R13, #24] ; transfer 2 length - ADD R0, R13, #4 - MOV R1, #2 - BL IIC_OpV - - LDR R1, [R13, #20] ; recover data pointer - ADD R1, R1, R5 - ADD R13, R13, #12*2+4+4 - - CLRV - - Pull "R0,R2,R3-R5,PC" - -; ***************************************************************************** -; -; ChecksumBlock - Checksum a block of CMOS RAM specified by logical address -; Assumes the address is valid. -; -; in: R0 = address in CMOS RAM -; R1 = initial checksum -; R2 = length -; -; out: R1 incremented by sum of bytes in range -; - - -ChecksumBlock ROUT - Push "R0,R2,R14" - -10 BL ChecksumSubBlock - BVS %FT80 - TEQ R2, #0 - BNE %BT10 -80 - Pull "R0,R2,PC" - - -; ***************************************************************************** -; -; ChecksumSubBlock - Checksum a block of CMOS RAM specified by logical address. -; Assumes the address is valid, and will only read as much -; as it can in a single IIC transaction. Skips over -; 239 (the checksum byte itself), and 240-255 (OTP area). -; -; in: R0 = address in CMOS RAM -; R1 = initial checksum -; R2 = length -; -; out: R0-R2 updated to reflect the data read. -; -ChecksumSubBlock ROUT - Push "R3-R5,R14" -; establish end of the current contiguous block, and the logical->physical address offset. - CMP R0, #1 ; 00 -> 40 uncached - MOVLO R3, #1 - MOVLO R4, #&40-&00 - BLO %FT10 - CMP R0, #&C0 ; [01..C0) -> [41..100) cached - MOVLO R3, #&C0 - MOVLO R4, #&41-&01 - BLO %FT10 - CMP R0, #&EF ; [C0..EF) -> [10..3F) cached - MOVLO R3, #&EF - MOVLO R4, #&10-&C0 - BLO %FT10 - CMP R0, #&100 - ADDHS R3, R0, R2 ; [100..) -> [100..) uncached - MOVHS R4, #0 - BHS %FT10 - -; [EF..100) -> not checksummed - MOV R3, #&100 - ADD R14, R0, R2 - CMP R3, R14 - MOVHI R3, R14 - SUB R14, R3, R0 - ADD R0, R0, R14 - SUB R2, R2, R14 - Pull "R3-R5,PC" - - -; R3 = logical end of current segment (exclusive) -; R4 = offset from logical to physical address for this segment -10 - ADD R14, R0, R2 - CMP R3, R14 - MOVHI R3, R14 -; R3 = logical end of this transaction (exclusive) - - TEQ R0, #0 ; check it's a cacheable segment - BEQ %FT15 - CMP R0, #&100 - BHS %FT15 - - LDR R14, =CMOSRAMCache - ADD R3, R3, R4 ; R3 = physical end address - ADD R4, R4, R0 ; R4 = physical address - ADD R3, R3, R14 ; R3 = cache end address - ADD R4, R4, R14 ; R4 = cache address - SUB R14, R3, R4 ; R14 = bytes being read - ADD R0, R0, R14 ; update return R0 - SUB R2, R2, R14 ; update return R2 - -12 LDRB R14, [R4], #1 - CMP R4, R3 - ADD R1, R1, R14 - BLO %BT12 - Pull "R3-R5,PC" -15 - Push "R0-R2" - ADD R0, R0, R4 ; R0 = physical start address - ADD R3, R3, R4 ; R3 = physical end address - [ HAL - Push "sb,R12" - MOV R5, R0 ; save address - AddressHAL - Push "R1-R3" - CallHAL HAL_NVMemoryType - Pull "R1-R3" - AND R4, R0, #NVMemoryFlag_Provision - MOV R0, R5 ; restore address - TEQ R4, #NVMemoryFlag_None - TEQNE R4, #NVMemoryFlag_HAL - BNE %FT17 ; do IIC things. - - SUB R14, R3, R0 - LDR R1, [R13,#8] - LDR R3, [R13,#16] - ADD R1, R1, R14 - SUB R3, R3, R14 - STR R1, [R13,#8] - STR R3, [R13,#16] - - TEQ R4, #NVMemoryFlag_None - ; If there's no NVmemory, tough - we just return. - Pull "sb,R12", EQ - Pull "R0-R5,PC", EQ - - Push "R6" - MOV R4, #0 - ADD R6, R5, R14 - SUB R13, R13, #4 -16 - MOV R0, R5 - MOV R1, sp - MOV R2, #1 - CallHAL HAL_NVMemoryRead - LDRB R14, [R13] - ADD R4, R4, R14 - ADD R5, R5, #1 - TEQ R5, R6 - BNE %BT16 - ADD R13, R13, #4 - Pull "R6,sb,R12" - Pull "R0-R2" - ADD R1,R1,R4 - Pull "R3-R5,PC" -17 - Pull "sb,R12" - ] - SUB R5, R3, R0 ; R5 = bytes being read - - [ E2ROMSupport - BL GetI2CAddress ; convert to device address and offset - | - MOV R1, #RTCAddressPHI - ] - - MOV R2, R0 ; save the offset - SUB R13, R13, #12*2+4 - MOV R14, R13 - TST R1, #&100 ; 2-byte address? - MOVNE R0, R2, LSR #8 - STRNEB R0, [R14], #1 ; offset (MSB) - STRB R2, [R14], #1 ; offset (LSB) - - SUB R14, R14, R13 - STR R14, [R13, #12] ; transfer 1 length - - AND R14, R1, #&FF - ORR R0, R14, #1:SHL:29 ; retry - STR R0, [R13, #4] ; transfer 1 address - ORR R14, R14, #1 ; device address for read - ORR R14, R14, #1:SHL:30 ; checksum only please - STR R14, [R13, #16] ; transfer 2 address - STR R13, [R13, #8] ; transfer 1 data - - ADD R14, R13, #12*2+4 - LDMIA R14, {R0-R2} - ADD R0, R0, R5 ; update return R0 - SUB R2, R2, R5 ; update return R2 - STMIB R14, {R0,R2} - MOV R4, R1 ; remember checksum - - STR R5, [R13, #24] ; transfer 2 length - ADD R0, R13, #4 - MOV R1, #2 - BL IIC_OpV - - LDR R1, [R13, #20] ; read back checksum - ADD R1, R1, R4 ; update checksum - ADD R13, R13, #12*2+4+4 - - Pull "R0,R2,R3-R5,PC" - -; ***************************************************************************** -; -; GetI2CAddress - Convert NVRam physical address to i2c device address -; and offset -; -; in: R0 = NVRam physical address (&00..size of NVRam) -; -; out: R0 preserved -; -; C=0 => NVRam address is valid -; R0 = physical address within i2c device -; R1 = i2c device address for writing. Increment this device address -; by 1 for reading. Bit 8 is set if device requires 2-byte physical address. -; -; C=1 => NVRam address is out of range of CMOS or E2ROM chips -; R0 preserved -; R1 preserved - - [ E2ROMSupport -GetI2CAddress ROUT - Push "R14" - MOV R14, #0 ; get no 256 byte blocks and calculate end address - LDRB R14, [R14, #NVRamSize] - MOV R14, R14, LSL #8 - CMP R0, R14 - Pull "PC",CS ; indicate invalid - -; address is < end address -> is valid - MOV R1, #0 - ;LDRB R1, [R1, #RTCFitted] ; This causes a headache if both an RTC and NVRAM are fitted - ;TEQ R1, #0 - ;LDREQB R1, [R1, #NVRamBase] ; RTC overlaps bottom of NVRAM - LDRB R1, [R1, #NVRamBase] ; RTC overlaps bottom of NVRAM - - CMP R14, #2*1024 ; is the device bigger than 2K? If so, new addressing scheme - ORRHI R1, R1, #&100 ; set magic bit => 2 byte address - BHI %FT50 - - MOVS R14, R0, LSR #8 ; put top bits of physical address into device address - ORRNE R1, R1, R14, LSL #1 - ANDNE R0, R0, #&FF ; and use address within 256 byte block -50 - CLC - Pull "PC" ; indicate valid - - ] - - -; ***************************************************************************** -; -; MangleCMOSAddress - Convert from logical to physical address -; -; Doesn't check if address is larger than the amount of NVRam installed -; -; in: R0 = logical address (&00...) -; -; out: C=0 => valid logical address -; R0 = physical address (&40..&FF,&10..&3F,&00..0F,&100..) -; -; C=1 => invalid logical address -; R0 preserved -; - -MangleCMOSAddress ROUT - [ E2ROMSupport - Push "R14" - MOV R14, #0 ; read no 256 byte blocks and calculate end address - LDRB R14, [R14, #NVRamSize] - MOV R14, R14, LSL #8 - CMP R0, R14 ; if >= end address then - Pull "R14" - MOVCS PC, R14 ; invalid (exit C set) - - CMP R0, #&100 ; if < end address && >= &100 then - BLO %FT05 - CLC - MOV PC, R14 ; valid (no mungeing) - ] -05 - CMP R0, #&F0 ; if < &100 && >= &f0 then - [ E2ROMSupport - BCC %FT10 - SUB R0, R0, #&F0 ; map &F0->&FF to &00->0F for OTP section - CLC - MOV PC, R14 - | - MOVCS PC, R14 ; invalid - ] -10 - ADD R0, R0, #&40 ; now in range &40..&13F - CMP R0, #&100 - SUBCS R0, R0, #(&100-&10) ; now in range &40..&FF, &10..&3F - CLC - MOV PC, R14 ; valid - -; ***************************************************************************** -; -; ValChecksum - test to see if the CMOS checksum is OK -; -; This routine performs MangleCMOSAddress inherently. -; -; The checksum does not include physical locations &00->&0F, even -; if they are OTP section (as this is usually used for a unique id -; which will be different for every machine and can't be changed). -; -; in: none -; -; out: R0 = calculated checksum -; Z set if checksum is valid -; All other registers preserved -; - - [ ChecksumCMOS - -ValChecksum Entry "R1-R2" - - MOV R0, #0 - MOV R1, #CMOSxseed - [ E2ROMSupport - MOV R2, #0 ; read number of 256 byte blocks and calculate end address - LDRB R2, [R2, #NVRamSize] - MOV R2, R2, LSL #8 - | - MOV R2, #240 - ] - BL ChecksumBlock - -; -; R1 contains the actual checksum. Compare it with the recorded checksum -; -40 - MOV R0, #CheckSumCMOS - BL Read - AND R2, R0, #&FF ; value from checksum location - AND R0, R1, #&FF ; calculated value into R0 - CMPS R0, R2 - - EXIT - ] - -; ***************************************************************************** -; -; MakeChecksum - calculate and write a correct checksum -; -; in: none -; -; out: R0 = calculated checksum -; All other registers preserved -; - - [ ChecksumCMOS - -MakeChecksum ROUT - Push "R1-R2,R14" - MOV R0, #0 - MOV R1, #CMOSxseed - [ E2ROMSupport - MOV R2, #0 - LDRB R2, [R2, #NVRamSize] - MOV R2, R2, LSL #8 - | - MOV R2, #240 - ] - BL ChecksumBlock - MOV R0, #CheckSumCMOS - BL Write - Pull "R1-R2,PC" - ] - - LTORG - -; ***************************************************************************** -; -; SetTime - Write the CMOS clock time and update 5-byte RealTime -; -; in: UTC time: -; R0 = hours -; R1 = minutes -; R2 = day of month -; R3 = month -; R5 = year (lo) -; R6 = year (hi) -; R7 = seconds -; R8 = centiseconds -; -; If R0,R2,R5 or R6 is -1 then the time,date,year,century (respectively) will not be written -; - -SetTime ROUT - Push "R4, R9-R10, R14" ; save registers - - LDR R10, =ZeroPage - LDRB R10, [R10, #RTCFitted] - TEQ R10, #0 ; no RTC - just set soft copy - BNE %FT20 - - BL RegToRealTime - Pull "R4, R9-R10, PC" - -20 - Push "R0-R2" - MOV R4, R0 ; copy hours in R4 - - Push "R1" - MOVS R1, R5 ; year held seperately from the RTC - MOVPL R0, #YearCMOS - BLPL Write - MOVS R1, R6 - MOVPL R0, #YearCMOS+1 - BLPL Write - Pull "R1" - - CMP R4, #-1 ; are we writing time ? - BEQ %FT30 - - SUB R13, R13, #8 - MOV R9, R13 - TEQ R10, #RTCAddressPHI - MOVEQ R0, #1 ; offset to start of time (varies) - MOVNE R0, #0 - STRB R0, [R9], #1 - MOVEQ R0, R8 ; centiseconds (not for Dallas parts) - BLEQ HTBS9 - MOV R0, R7 ; seconds - BL HTBS9 - MOV R0, R1 ; minutes - BL HTBS9 - MOV R0, R4 ; hours - BL HTBS9 - MOV R6, R2 - BL %FT45 - MOV R2, R6 ; preserve D-O-M for later - ADD R13, R13, #8 - -30 - CMP R2, #-1 ; are we writing date ? - BEQ %FT40 - - SUB R13, R13, #8 - MOV R9, R13 - TEQ R10, #RTCAddressPHI - BNE %FT35 - - ; Philips specific handling - MOV R0, #5 ; offset 5 - STRB R0, [R9], #1 - MOV R0, R2 ; day of month - BL HexToBCD - ORR R0, R0, R5, LSL #6 ; year in bits 6,7; day in bits 0..5 - STRB R0, [R9], #1 - MOV R0, R3 ; months - BL HTBS9 - B %FT37 -35 - ; Dallas specific handling - MOV R0, #4 ; offset 4 - STRB R0, [R9], #1 - MOV R0, R2 - BL HTBS9 - MOV R0, R3 - BL HTBS9 - MOV R0, R5 - BL HTBS9 ; don't bother setting the D-O-W -37 - BL %FT45 - ADD R13, R13, #8 - -40 - Pull "R0-R2" - BL RTCToRealTime ; update RAM copy - Pull "R4, R9-R10, PC" - -45 - MOV R0, R10 - ORR R0, R0, #1:SHL:29 - MOV R1, R13 - SUB R2, R9, R13 - Push "R14" - BL IIC_Op ; write the prepared block with retries - Pull "PC" - -; ***************************************************************************** -; -; ReadTime - Read the CMOS clock time -; -; in: - -; -; out: R0 = hours -; R1 = minutes -; R2 = days -; R3 = months -; R5 = year (lo) -; R6 = year (hi) -; R7 = seconds -; R8 = centiseconds -; - -ReadTime ROUT - Push "R4, R14" - SUB R13, R13, #(12*2)+6+1+1 - - LDR R14, =ZeroPage - LDRB R2, [R14, #RTCFitted] - ORR R14, R2, #1:SHL:29 ; retry - STR R14, [R13, #8] ; transfer 1 address - ADD R0, R14, #1 - STR R0, [R13, #20] ; transfer 2 address - TEQ R2, #RTCAddressPHI - MOVEQ R0, #1 ; PHI time starts at +1 - MOVNE R0, #0 ; DAL time starts at +0 - STRB R0, [R13, #0] - STR R13, [R13, #12] ; transfer 1 dataptr - MOV R0, #1 - STR R0, [R13, #16] ; transfer 1 length - ADD R0, R13, #1 - STR R0, [R13, #24] ; transfer 2 dataptr - MOV R0, #6 - STR R0, [R13, #28] ; transfer 2 length - - ADD R0, R13, #8 - MOV R1, #2 - BL IIC_OpV - - TEQ R2, #RTCAddressPHI - BNE %FT50 - - ; Philips specific read - LDRB R0, [R13, #1] - BL BCDToHex - MOV R8, R0 ; centiseconds - LDRB R0, [R13, #2] - BL BCDToHex - MOV R7, R0 ; seconds - LDRB R0, [R13, #3] - BL BCDToHex - MOV R1, R0 ; minutes - LDRB R0, [R13, #4] - BL BCDToHex - MOV R4, R0 ; hours - LDRB R0, [R13, #5] - AND R0, R0, #&3F ; day of month (clear year bits) - BL BCDToHex - MOV R2, R0 - LDRB R0, [R13, #6] - AND R0, R0, #&1F ; month (clear day of week bits) - BL BCDToHex - MOV R3, R0 - B ReadTimeYear - -50 - ; Dallas specific read - MOV R8, #0 ; centiseconds - LDRB R0, [R13, #1] - BL BCDToHex - MOV R7, R0 ; seconds - LDRB R0, [R13, #2] - BL BCDToHex - MOV R1, R0 ; minutes - LDRB R0, [R13, #3] - BL BCDToHex - MOV R4, R0 ; hours - LDRB R0, [R13, #5] - BL BCDToHex - MOV R2, R0 ; day of month - LDRB R0, [R13, #6] - BL BCDToHex - MOV R3, R0 ; month - -ReadTimeYear - ADD R13, R13, #(12*2)+6+1+1 - MOV R0, #YearCMOS - BL Read - MOV R5, R0 ; year (lo) - MOV R0, #YearCMOS+1 - BL Read - MOV R6, R0 ; year (hi) - - MOV R0, R4 ; put hours in R0 - - TEQ R2, #0 ; Ensure day/month are non-zero (LRust, fix RP-0370) - MOVEQ R2, #1 ; No then force 1st - TEQ R3, #0 ; Invalid month? - MOVEQ R3, #1 ; Yes then force Jan - - Pull "R4, PC" - -; ***************************************************************************** -; -; InitRTC - Force the clock into a known state (incase of new battery) -; -; in: R0 = RTC IIC address - -InitRTC - Push "R0-R2, R14" - SUB R13, R13, #4 - MOV R1, R13 - TEQ R0, #RTCAddressPHI - BEQ %FT60 - ORR R0, R0, #1:SHL:29 - MOV R2, #0 ; to write 0 to address ptr - STRB R2, [R1] - MOV R2, #1 - BL IIC_Op - ORR R0, R0, #1 - BL IIC_Op - LDRB R2, [R1] - ANDS R2, R2, #&80 ; test clock disabled bit - BEQ %FT65 - EOR R0, R0, #1 - DebugTX "Forced RTC on" -60 - ORR R0, R0, #1:SHL:29 - MOV R2, #0 - STR R2, [R1] - MOV R2, #2 ; to write 0 to control reg 0 - BL IIC_Op -65 - ADD R13, R13, #4 - Pull "R0-R2, PC" - -; ***************************************************************************** -; -; InitCMOSCache - Initialise cache of CMOS RAM -; in: - -; -; out: R0 = 0 for failure - -InitCMOSCache Entry "r1-r6, sb,r12" - [ E2ROMSupport - - ; Need to set the slowest speed so we can probe - LDR R4, =ZeroPage - MOV R3, #10 ; Default speed setting (5µs delays) - STRB R3, [R4, #NVRamSpeed] - - ; Have we got an RTC ? - LDR R2, =ZeroPage - MOV R4, #0 - MOV R0, #RTCAddressDAL - BL DummyAccess - BVC %FT13 - MOV R0, #RTCAddressPHI - BL DummyAccess - STRVSB R4, [R2, #RTCFitted] -13 - STRVCB R0, [R2, #RTCFitted] - BLVC InitRTC - - [ HAL - AddressHAL - CallHAL HAL_NVMemoryType - ANDS R0, R0, #NVMemoryFlag_Provision - BEQ InitCMOSCache_NoCMOS - MOV R5, R0 - - ; If it's only a maybe, then we probe - TEQ R5, #NVMemoryFlag_MaybeIIC - BEQ %FT03 - - ; Else we read the size - - CallHAL HAL_NVMemorySize ; returns number of bytes but.. - MOV R0, R0, LSR#8 ; .. expecting no. of 256 blocks - STRB R0, [R4, #NVRamSize] - - TST R5, #NVMemoryFlag_ProtectAtEnd - STREQB R0, [R4, #NVRamWriteSize] - BEQ %FT02 - CallHAL HAL_NVMemoryProtectedSize - LDRB R1, [R4, #NVRamSize] - SUB R0, R1, R0, LSR#8 - STRB R0, [R4, #NVRamWriteSize] - -02 - CallHAL HAL_NVMemoryPageSize ; returns size in bytes but.. - TEQ R0, #0 ; .. expecting power of 2 - MVNEQ R0, #0 - MOV R1, #0 -22 MOVS R0, R0, LSR #1 - ADDNE R1, R1, #1 - BNE %BT22 - STRB R1, [R4, #NVRamPageSize] - - CallHAL HAL_NVMemoryIICAddress - STRB R0, [R4, #NVRamBase] - - MOV R0, #0 - CallHAL HAL_IICType - MOV R3, #10 - TST R0, #IICFlag_Fast - MOVNE R3, #3 - TST R0, #IICFlag_HighSpeed - MOVNE R3, #1 - STRB R3, [R4, #NVRamSpeed] - - ; If we're using IIC then read in the cache manually - AND R0, R5, #NVMemoryFlag_Provision - TEQ R0, #NVMemoryFlag_IIC - BEQ %FT06 - - ; Else use HAL routine. - MOV R0, #0 - LDR R1, =CMOSRAMCache - MOV R2, #&100 - CallHAL HAL_NVMemoryRead - TEQ R0, #&100 - MOVNE R0, #0 ; Failure exit condition - EXIT -03 - ] - -; No HAL,so determine what hardware we've got fitted by probing, -; R4 holds the number of 256 byte blocks that we've found - - MOV R3, #10 ; assume 100kHz to start with - MOV R5, #4 ; assume 16 byte page size to start with - MOV R6, #0 ; assume not protected - -; Have we got a 2K device ? - MOV r1, #E2ROMAddress2K - MOV r0, #(E2ROMAddress2K+14) - BL DummyAccess - MOVVC R4, #8 - MOVVC R3, #3 ; Fast speed setting (1.5µs delays) - BVC %FT5 - -; Have we got a 16K device ? - MOV r1, #E2ROMAddress16K - MOV r0, #E2ROMAddress16K - BL DummyAccess - MOVVC R4, #64 - MOVVC R5, #6 ; 64 byte page size - MOVVC R3, #3 ; Fast speed setting (1.5µs delays) - BVC %FT5 - -; Have we got a 4K device? - MOV r1, #E2ROMAddress4K - MOV r0, #E2ROMAddress4K - BL DummyAccess - MOVVC R4, #16 - MOVVC R6, #12 ; Only bottom 3K writable - MOVVC R5, #5 ; 32 byte page size - MOVVC R3, #3 ; Fast speed setting (1.5µs delays) - BVC %FT5 - -; Have we got an 8K device? - MOV r1, #E2ROMAddress8K - MOV r0, #E2ROMAddress8K - BL DummyAccess - MOVVC R4, #32 - MOVVC R5, #5 ; 32 byte page size - MOVVC R3, #3 ; Fast speed setting (1.5µs delays) - BVC %FT5 - -; Have we got a protected 8K device? - MOV r1, #E2ROMAddress8K_prot - MOV r0, #E2ROMAddress8K_prot - BL DummyAccess - MOVVC R4, #32 - MOVVC R6, #24 ; Only bottom 6K writable - MOVVC R5, #5 ; 32 byte page size - MOVVC R3, #3 ; Fast speed setting (1.5µs delays) - BVC %FT5 - -; Have we got a 32K device? - MOV r1, #E2ROMAddress32K - MOV r0, #E2ROMAddress32K - BL DummyAccess - MOVVC R4, #128 ; 128,120,6,1 - MOVVC R6, #120 ; Only bottom 30K writable - MOVVC R5, #6 ; 64 byte page size - MOVVC R3, #1 ; Hyper-fast speed setting (0.5µs delays - 1MHz part) - BVC %FT5 - -; Any storeage in the Philips RTC? (Dallas capacity is tiny,ignored) - MOV R1, #RTCAddressPHI - MOV R0, #RTCAddressPHI - BL DummyAccess - MOV R5, #8 ; 256 byte page size for CMOS - BVC %FT5 - -; We ain't got anything! -InitCMOSCache_NoCMOS - LDR R2, =ZeroPage - MOV R5, #8 - STRB R5, [R2, #NVRamPageSize] ; Act as though we have 256 bytes of - MOV R1, #1 ; single page CMOS. - STRB R1, [R2, #NVRamSize] - STRB R1, [R2, #NVRamWriteSize] - MOV R0, #0 ; Exit failure - EXIT - -5 - ; Set the NVRam count - STRB R1, [R2, #NVRamBase] - STRB R4, [R2, #NVRamSize] - STRB R5, [R2, #NVRamPageSize] - TEQ R6, #0 - MOVEQ R6, R4 - STRB R6, [R2, #NVRamWriteSize] - - CMP R3, #I2Cticks ; clamp speed to maximum bus speed - MOVLO R3, #I2Cticks - STRB R3, [R2, #NVRamSpeed] -06 - ; Initialise the cache - LDR R3, =CMOSRAMCache - - TEQ R4, #8 ; check for 2K part - MOVNE r0, #&00 ; if not, then start at 0 anyway and read non-OTP data into location 0..15 - BNE %FT07 - BL ReadOTPArea - MOV r0, #&10 ; read rest of it from 16 onwards -07 - BL GetI2CAddress ; and convert to device address and offset - MOV R2, R0 ; save the offset - MOV R4, #&100 ; stop at &100 - | - ; No E2ROM support,assume a Philips RTC - MOV R1, #RTCAddressPHI - MOV R2, #&10 - MOV R4, #&100 ; stop at address &100 - LDR R3, =CMOSRAMCache - ] - - ; Note - R4 MUST be &100 to prevent crossover between 256-byte pages - ; (for devices with multiple addresses) -09 - - SUB R13, R13, #2*12+4 - AND R0, R1, #&FF - STR R0, [R13, #4] ; transfer 1 address - ADD R0, R0, #1 ; read address - STR R0, [R13, #16] ; transfer 2 address - TST R1, #&100 ; 2-byte address? - MOV R14, R13 - MOVNE R0, R2, LSR #8 - STRNEB R0, [R14], #1 ; memory word address (MSB) - STRB R2, [R14], #1 ; memory word address (LSB) - STR R13, [R13, #8] ; transfer 1 data - SUB R14, R14, R13 - STR R14, [R13, #12] ; transfer 1 length - ADD R14, R3, R2 - STR R14, [R13, #20] ; transfer 2 data - SUB R14, R4, R2 - STR R14, [R13, #24] ; transfer 2 length - - ADD R0, R13, #4 - MOV R1, #2 - BL IIC_OpV - - ADD R13, R13, #2*12+4 - MOV R0, #1 - EXIT - - [ E2ROMSupport -ReadOTPArea Entry - SUB R13, R13, #2*12+4 - MOV R0, #0 - STRB R0, [R13, #0] ; offset 0 - MOV R0, #E2ROMAddress2K_OTP - STR R0, [R13, #4] ; transfer 1 address - STR R13, [R13, #8] ; transfer 1 data - MOV R0, #1 - STR R0, [R13, #12] ; transfer 1 length - MOV R0, #E2ROMAddress2K_OTP + 1 - STR R0, [R13, #16] ; transfer 2 address - STR R3, [R13, #20] ; transfer 2 data - MOV R0, #16 - STR R0, [R13, #24] ; transfer 2 length - ADD R0, R13, #4 - MOV R1, #2 - BL IIC_OpV - ADD R13, R13, #2*12+4 - EXIT - ] - -; ***************************************************************************** -; -; DummyAccess - do a dummy access of the specified device to find out -; if it is present -; -; in: R0 = Write address of device -; -; out: All registers preserved -; V=0 => device is present -; V=1 => device is not present - - [ E2ROMSupport -DummyAccess - - [ {TRUE} - ; Blooming 80321 HW IIC can't do just START address STOP - Entry "R0-R2",4 - ORR R0, R0, #1 - MOV R1, R13 - MOV R2, #1 - BL IIC_Op - | - Entry "R1,R2" - MOV R1, #0 - MOV R2, #0 - BL IIC_Op - ] - - EXIT ; Exit with V set appropriately - ] - -; ***************************************************************************** -; -; SWI OS_NVMemory -; -; in: R0 = reason code -; - -NVMemorySWI Entry - BL NVMemorySub - PullEnv - ORRVS LR, LR, #V_bit - ExitSWIHandler - -NVMemorySub - CMP R0, #4 - ADDLS PC, PC, R0, LSL #2 - B NVMemory_Unknown - B NVMemory_Size - B NVMemory_Read - B NVMemory_Write - B NVMemory_ReadBlock - B NVMemory_WriteBlock - -NVMemory_Unknown - ADRL R0, ErrorBlock_HeapBadReason - [ International - Push LR - BL TranslateError - Pull LR - ] - RETURNVS - -; ----------------------------------------------------------------------------- -; OS_NVMemory 0 - find NV memory size -; -; in: R0 = 0 -; -; out: R1 = NV memory size in bytes -; -NVMemory_Size - [ E2ROMSupport - LDRB R1, [R0, #NVRamSize] - MOV R1, R1, LSL #8 - | - MOV R1, #240 - ] - MOV PC, LR - -; ----------------------------------------------------------------------------- -; OS_NVMemory 1 - read a byte -; -; in: R0 = 1 -; R1 = location -; -; out: R2 = value -; -NVMemory_Read - Entry "R4" - MRS R4, CPSR - BIC R0, R4, #I32_bit - MSR CPSR_c, R0 ; enable interrupts - this may take some time - MOV R0, R1 - BL ReadWithError - MOVVC R2, R0 - MOVVC R0, #1 ; must preserve R0 - ORRVS R4, R4, #V_bit - MSR CPSR_cf, R4 ; restore interrupt state - EXIT - -; ----------------------------------------------------------------------------- -; OS_NVMemory 2 - write a byte -; -; in: R0 = 1 -; R1 = location -; R2 = value -; -NVMemory_Write ROUT - [ ProtectStationID - TEQ R1, #0 ; just ignore writes to byte 0 - MOVEQ PC, R14 - ] - Entry "R1,R4" - MRS R4, CPSR - BIC R0, R4, #I32_bit - MSR CPSR_c, R0 ; enable interrupts - this may take some time - MOV R0, R1 - MOV R1, R2 - BL WriteWithError - MOVVC R0, #2 ; must preserve R0 - ORRVS R4, R4, #V_bit - MSR CPSR_cf, R4 ; restore interrupt state - EXIT - -; ----------------------------------------------------------------------------- -; OS_NVMemory 3 - read a block -; -; in: R0 = 3 -; R1 = location -; R2 = buffer -; R3 = length -; -NVMemory_ReadBlock - Entry "R1-R4" - MOV R4, PC - MRS R4, CPSR - BIC R0, R4, #I32_bit - MSR CPSR_c, R0 ; enable interrupts - this may take some time - MOV R0, R1 - MOV R1, R2 - MOV R2, R3 - BL ReadBlock - MOVVC R0, #3 ; must preserve R0 - ORRVS R4, R4, #V_bit - MSR CPSR_cf, R4 ; restore interrupt state - EXIT - -; ----------------------------------------------------------------------------- -; OS_NVMemory 4 - write a block -; -; in: R0 = 3 -; R1 = location -; R2 = buffer -; R3 = length -; -NVMemory_WriteBlock ROUT - Entry "R1-R4" - MRS R4, CPSR - BIC R0, R4, #I32_bit - MSR CPSR_c, R0 ; enable interrupts - this may take some time - [ ProtectStationID - TEQ R1, #0 - BNE %FT10 - ADD R1, R1, #1 - ADD R2, R2, #1 - TEQ R3, #0 - SUBNE R3, R3, #1 ; steer clear of station ID - ] -10 MOV R0, R1 - MOV R1, R2 - MOV R2, R3 - BL WriteBlock - MOVVC R0, #4 ; must preserve R0 - ORRVS R4, R4, #V_bit - MSR CPSR_cf, R4 ; restore interrupt state - EXIT - - END diff --git a/s/PMF/key b/s/PMF/key deleted file mode 100644 index d972148e..00000000 --- a/s/PMF/key +++ /dev/null @@ -1,1478 +0,0 @@ -; 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.Key - -; ARTHUR keyboard code - -; Authors Tim Dobson, Jon Thackray -; Started 13-Oct-86 - -; ************************************************************ -; *** C h a n g e L i s t (better late than never!) *** -; ************************************************************ - -; Date Who Description -; ---- --- ----------- -; 17-Feb-88 Added Sam's code to call the callback vector in RDCH/INKEY -; idle loop -; 02-Mar-88 Initialise KeyVec to NewKeyStruct before the keyboard has told -; us its ID, so Sam can call INKEY(-ve) with no keyboard -; 13-Apr-88 Fixed RDCH from RS423 if treating as keyboard, getting NUL+char -; (didn't try to reenable RTS on 2nd char) -; 11-Jun-88 Put input redirection where it was needed really. SKS -; 12-Aug-88 Read mouse position from buffer forces inside bounding box -; 02-Sep-88 Buffered mouse coords stored in absolute terms, not relative to -; origin at time of click. Made relative after reading out and -; clipping to bounding box. Mouse event coords are still relative -; to origin at time of click. -; 06-Feb-91 LastLED added to stop unnecessary LED transmissions -; -; 24-Feb-93 SMC Split off Archimedes keyboard driver into file KbdDrA1. -; Split off mouse stuff into file mouse. -; Added new interfaces for generic keyboard driver. -; 23-Aug-93 SMC GotKbId now sets KbId but remembers the last in LastKbId. -; 24-Aug-93 SMC Key handler can now get keyboard stuff going. -; 18-Nov-93 SMC Fixed bug in key handler stuff (no handler => KeyVec=-1). -; 25-Nov-93 SMC Key handler and keyboard driver now trigger each other correctly. -; 25-Apr-94 RCM ReadCh modified for Stork's power saving scheme. -; - - GBLL MouseBufferFix -MouseBufferFix SETL {TRUE} - - -; ***************************************************************************** -; -; Entry point for keyboard code - Initialisation -; - -KeyInit ROUT - MOV R11, #KeyWorkSpace - Push R14 - - WritePSRc I_bit :OR: SVC_mode, R14 - - [ Keyboard_Type = "A1A500" - BL A1KeyInit - ] - - MOV R0, #-1 ; no default key handler - STR R0, KeyVec - - MOV R0, #&FF ; indicate no previous keyboard id - STRB R0, LastKbId - STRB R0, KbId - - BL ClearKbd - - [ Keyboard_Type = "A1A500" - BL A1Reset - ] - - Pull PC ; go back to user - -; ***************************************************************************** -; -; KeyPostInit - Called after modules have initialised -; - -KeyPostInit ROUT - Push R14 - MOV R11, #KeyWorkSpace - PHPSEI ; disable interrupts round this bit - Push R14 ; save I_bit indication - LDRB R1, LastKbId - TEQ R1, #&FF ; if no keyboard initialised yet then - LDREQB R1, KbId ; try now - BLEQ GotKbId - Pull R14 ; restore I_bit indication - PLP ; set I_bit from this - - LDROSB R1, LastBREAK ; is it a soft reset ? - TEQ R1, #0 - Pull PC, EQ ; if so, then exit - - MOV R0, #OsbyteSetCountry - LDROSB R1, Country - SWI XOS_Byte - Pull PC - -; ***************************************************************************** - -ClearKbd ROUT - Push R14 - - MOV R0, #&FF - STRB R0, CurrKey ; no current key - STRB R0, OldKey - STRB R0, LastLED - -; Set up keyboard table - - MOV R0, #0 ; All keys up - STR R0, KeysDown ; zero 160 bits = 5 words - STR R0, KeysDown +4 - STR R0, KeysDown +8 - STR R0, KeysDown +12 - STR R0, KeysDown +16 - - Pull PC - -; ***************************************************************************** -; -; UpdateLEDs - Update the LED(s) from the keyboard status byte -; -; in: R11 -> keyboard workspace -; R12 -> IOC -; -; out: R0, R1 corrupted -; - -UpdateLEDs ROUT - LDRB r0, KbId ; get keyboard id - TEQ r0, #&FF ; if not found yet - MOVEQ pc, lr ; then exit - - LDROSB r0, KeyBdStatus ; Build current LED state byte. - TST r0, #KBStat_NoCapsLock - MOVEQ r1, #1 - MOVNE r1, #0 - TST r0, #KBStat_NoNumLock - ORREQ r1, r1, #2 - TST r0, #KBStat_ScrollLock - ORRNE r1, r1, #4 - - ; fall through - ASSERT . = SetLEDs - -; ***************************************************************************** -; -; SetLEDs - Set the LED(s) to a specific value -; -; in: R1 = desired LED state (bit 0 = caps lock, 1 = num lock, 2 = scroll lock) -; R11 -> keyboard workspace -; R12 -> IOC -; -; out: R0, R1 corrupted -; - -SetLEDs - LDRB r0, LastLED ; Only update if different. - TEQ r0, r1 - MOVEQ pc,lr - - STRB r1, LastLED - - MOV r0, #3 - [ AssembleKEYV - Push "r10-r12,lr" - MRS r11, CPSR ; Save current PSR. - ORR r10, r11, #SVC_mode + I32_bit - MSR CPSR_c, r10 ; Call KEYV in SVC mode, no IRQs. - MOV r10, #KEYV - Push "lr" ; Save SVC lr. - BL CallVector - Pull "lr" ; Restore SVC lr. - MSR CPSR_cf, r11 ; Go back to old mode. - NOP - Pull "r10-r12,pc" - | - [ Keyboard_Type = "A1A500" - B A1KeyVec - | - MOV pc, lr - ] - ] - -; ***************************************************************************** -; -; LEDsOn - Turn on all the LEDs -; -; out: all registers preserved -; - -LEDsOn Push "r0,r1,r11,lr" - MOV r1, #7 - MOV r11, #KeyWorkSpace - BL SetLEDs - Pull "r0,r1,r11,pc" - -; ***************************************************************************** -; -; LEDsOff - Restore the LEDs to keyboard status -; -; out: all registers preserved -; - -LEDsOff Push "r0,r1,r11,lr" - MOV r11, #KeyWorkSpace - BL UpdateLEDs - Pull "r0,r1,r11,pc" - -; ***************************************************************************** -; -; Handle new keyboard id. -; In: r1 = keyboard id -; r11 = KeyWorkSpace -; Out: preserve flags -; -GotKbId - EntryS - - STRB r1, KbId ; Store the new keyboard id. - - LDR r0, KeyVec - Push r0 ; Save old key handler so we know if it's changed. - - LDRB r8, LastKbId - TEQ r8, r1 ; If we have a different keyboard id then - BLNE IssueKeyboardService ; issue service. - - LDR lr, KeyVec ; Get possibly new key handler. - Pull r0 ; And old handler. - TEQ r0, lr ; If key handler has not changed then - BLEQ KeyboardEnable ; handler has not initialised with OS_InstallKeyHandler so we try. - - EXITS - -; ***************************************************************************** -; Initialise keyboard handler and enable keyboard driver. -; -; In: r1 = keyboard id -; -KeyboardEnable - Push lr - - BL ClearKbd - - LDR r0, KeyVec - CMP r0, #-1 ; If no key handler - LDRNEB r1, KbId ; or no keyboard yet then - TEQNE r1, #&FF - Pull pc, EQ ; can't initialise. - - STRB r1, LastKbId ; Remember last keyboard id that initialised. - - LDR r8, [r0, #KVInit] ; Initialise key handler. - ADD r8, r8, r0 - BL CallUserKeyCode - - MOV r0, #4 ; Initialise keyboard driver. - [ AssembleKEYV - MOV r10, #KEYV - BL CallVector - | - [ Keyboard_Type = "A1A500" - BL A1KeyVec - ] - ] - Pull pc - - [ AssembleKEYV -; ***************************************************************************** -; -; Default KEYV handler (deal with keyboard id, keys up/down). -; -; In: r0 = reason code 0 -; r1 = keyboard id -; or -; r0 = reason code 1 or 2 -; r1 = key code -; -KeyVector ROUT - CMP r0, #3 ; If not id/key up/key down then - Pull pc, CS ; just claim call. - - Push "r0-r12" - - MOV r11, #KeyWorkSpace - - TEQ r0, #0 ; If keyboard id then - BLEQ GotKbId ; handle it - Pull "r0-r12,pc",EQ ; and claim call. - | -GotKey ROUT - Push lr - ] - - MOV r2, r1 - SUB r1, r0, #1 - - CMP R2, #&A0 - BCS %FT05 - ADR R0, KeysDown - MOV lr, R2, LSR #5 - LDR lr, [R0, lr, LSL #2]! ; load appropriate word - MOV R3, #&80000000 ; index 0 is in top bit - TEQ r1, #0 - BNE %FT03 - - TST lr, R3, ROR R2 ; if going up and key already up (keyboard reinitialised) then - BEQ %FT50 ; nothing to do - B %FT04 ; else clear flag, generate event etc. -03 - TST lr, R3, ROR R2 ; if going down and key already down (weird) then - BNE %FT50 ; nothing to do else... -04 - EOR lr, lr, R3, ROR R2 ; switch state of flag - STR lr, [R0] ; store back -05 - BL KeyboardEvent ; generate key up/down event - - BL CheckForShiftingKey - BCC %FT10 ; [not shifting key] - - BL CallSpecialReturnNChars - B %FT50 - -10 - TEQ r1, #0 ; if key up then - BEQ %FT30 ; go and deal with it - - LDRB R0, CurrKey - TEQ R0, #&FF ; have we got a current key ? - BEQ %FT20 - - LDRB R1, OldKey - TEQ R1, #&FF ; have we got an old key ? - BNE %FT50 ; ignore new - we've got 2 down already - - STRB R0, OldKey ; make current key old -20 - STRB R2, CurrKey ; update current - MOV R0, #2 - STRB R0, Debouncing - STRB R0, AutoRepeatCount ; generate char after 2 100Hz ticks - - B %FT50 - -30 - LDRB R0, OldKey - TEQ R0, R2 ; is it old key going up ? - BNE %FT40 - -; Old key going up - - LDRB R0, CurrKey ; current key is one to ignore in scan - BL ScanKeys - - STRPLB R0, OldKey ; found key, so current -> old - BPL %BT20 ; and R2 -> current - - MOV R0, #&FF ; else mark old key invalid - STRB R0, OldKey - B %FT50 ; and return - -40 - LDRB R1, CurrKey - TEQ R1, R2 ; is it current key going up ? - BNE %FT50 ; not interested if not - - BL ScanKeys ; R0 was OldKey - BPL %BT20 ; was a key so make that current - - STRB R2, CurrKey ; mark current key up (R2 = -1) - -50 - [ AssembleKEYV - Pull "r0-r12,pc" - | - Pull pc - ] - -; ***************************************************************************** -; -; KeyboardEvent - Generate key up/down event -; -; in: R1 = 0 for up, 1 for down -; R2 = key index -; - -KeyboardEvent ROUT - LDRB R3, KbId ; tell event user the keyboard id - MOV R0, #Event_Keyboard - B OSEVEN - -; ***************************************************************************** -; -; Scan keyboard for keys down, ignoring key number R0 and shifting keys -; -; in: R0 = key number to ignore -; -; out: N=0 => R2 = key number found -; N=1 => no key found; R2 = -1 -; R0 preserved -; - -ScanKeys ROUT - Push "R0, R14" - ADR R1, KeysDown - MOV R2, #4 -10 - LDR R3, [R1, R2, LSL #2] ; get the word - TEQ R3, #0 ; if any keys in this down, skip - BNE %FT20 -15 - SUBS R2, R2, #1 ; N=1 last time round - BPL %BT10 - Pull "R0, PC" - -20 - MOV R2, R2, LSL #5 ; multiply by 32 - ADD R2, R2, #32 ; and add 32 -30 - TEQ R3, #0 ; no more bits ? - MOVEQ R2, R2, LSR #5 ; then reset R2 to word offset - BEQ %BT15 ; and continue word loop - SUB R2, R2, #1 ; decrement key number - MOVS R3, R3, LSR #1 ; shift out bit - BCC %BT30 - - CMP R2, R0 ; is it old key (C=1 if it is) - BLNE CheckForShiftingKeyR0R3 ; check that it's not shifting key - BCS %BT30 ; C=1 => invalid, so loop - - TEQ R2, #0 ; N := 0 - Pull "R0, PC" - -; ***************************************************************************** -; -; CheckForShiftingKey - either going down or going up -; -; in: R2 = key number -; -; out: C=1 <=> is shifting key, so don't set current key etc -; R0 -> key structure -; R4 = shifting key index, or 0 if not shifting key -; R3,R5 undefined -; R1,R2,R6-R12 preserved -; - -CheckForShiftingKeyR0R3 ROUT ; version that saves R0, for ScanKeys - Push "R0,R3,R14" - BL CheckForShiftingKey - Pull "R0,R3,PC" - -CheckForShiftingKey ROUT - LDR R0, KeyVec - CMP R0, #-1 - MOVEQ PC, R14 - LDR R3, [R0, #KVKeyTranSize] ; maximum internal key number +1 - CMP R2, R3 ; is it outside table ? - LDRCC R3, [R0, #KVKeyTran] ; no, R3 := offset to keytran - ADDCC R3, R3, R0 ; R3 -> keytran - LDRCC R3, [R3, R2, LSL #2] ; R3 = table word for this key - CMNCC R3, #1 ; C=1 <=> outside table or is special - MOVCC PC, R14 ; can't be shifting key - - LDR R3, [R0, #KVShiftingList] ; R3 = offset to shifting key list - LDRB R4, [R3, R0]! ; R4 = length of shifting key list - TEQ R4, #0 -10 - LDRNEB R5, [R3, R4] - TEQNE R5, R2 - SUBNES R4, R4, #1 - BNE %BT10 - - CMP R4, #1 ; C=1 <=> shifting key - MOV PC, R14 ; not one of the shifting keys - -; ***************************************************************************** -; -; CallSpecialCode - Call code for a special key -; -; in: R0 -> Key structure -; R1 = 0 for up, 1 for down (shifting keys); 2 for first, 3 for repeat -; R2 = key number -; - -CallSpecialCode ROUT - ADR R6, NullCharList - LDR R3, [R0, #KVSpecialList] ; R3 = offset to special list - LDRB R4, [R3, R0]! ; R4 = length of special list - TEQ R4, #0 - MOVEQ PC, R14 ; no special keys, so can't be one -10 - LDRB R5, [R3, R4] - TEQ R5, R2 - BEQ %FT20 - SUBS R4, R4, #1 - BNE %BT10 - MOV PC, R14 - -20 - LDR R3, [R0, #KVSpecialCodeTable] ; R3 = offset to special table - ADD R3, R3, R0 ; R3 -> special code table - SUB R5, R3, #4 ; 0th entry is for 1st special - - LDR R8, [R5, R4, LSL #2] ; R8 = offset to code for this special - ADD R8, R8, R3 ; R8 = address of code for this special - ADR R3, ReturnVector - -; and drop thru to ... - -CallUserKeyCode ROUT - Push R14 - LDROSB R5, KeyBdStatus - LDRB R7, PendingAltType - Push R5 - BL %FT10 - Pull R12 - STRB R7, PendingAltType - TEQ R5, R12 - BLNE OfferKeyStatusUpCall - STROSB R5, KeyBdStatus, R12 - Pull R14 - MOV R12, #IOC - B UpdateLEDs - -10 - ADRL R12, UserKeyWorkSpace - MOV PC, R8 - -NullCharList - = 0 - ALIGN - -ReturnVector - B MouseButtonChange - B DoBreakKey - -; On entry: R5 = new status, R12 = old -; On exit: R5 = new new status, R12 corrupt, all other registers preserved -OfferKeyStatusUpCall - Entry "R0-R3,R10,R11" - MRS R11, CPSR - ORR R10, R11, #SVC_mode + I32_bit - MSR CPSR_c, R10 - Push "R14" - MOV R10, #UpCallV - MOV R3, R5 ; new value - MOV R2, R12 ; old value - MOV R1, #0 ; pre-change - MOV R0, #UpCall_KeyboardStatus - BL CallVector - MOV R5, R3 ; R5 = value, after interference -10 TEQ R5, R2 - MOVNE R10, #UpCallV - MOVNE R1, #1 ; post-change - MOVNE R0, #UpCall_KeyboardStatus - BLNE CallVector - Pull "R14" - MSR CPSR_cf, R11 - NOP - EXIT - -OfferPostKeyStatusUpCall - ALTENTRY - MRS R11, CPSR - ORR R10, R11, #SVC_mode + I32_bit - MSR CPSR_c, R10 - Push "R14" - MOV R3, R5 - MOV R2, R12 - B %BT10 - - -; ***************************************************************************** -; -; Centisecond tick routine -; -; out: R12 corrupted - -CentiSecondTick ROUT - Push "R11, R14" - MOV R11, #KeyWorkSpace - MOV R12, #IOC - - [ PollMouse - MOV R0, #K1rqmp - STRB R0, RequestMouse - TXon R0 - ] - - LDR R0, InkeyCounter - SUBS R0, R0, #1 ; decrement - STRCS R0, InkeyCounter ; store back unless was frozen at 0 - - LDRB R2, CurrKey - TEQ R2, #&FF - Pull "R11,PC", EQ ; no current key, so no auto-repeat - - BL UpdateLEDs ; update LEDs from keyboard status - - LDRB R0, AutoRepeatCount - SUBS R0, R0, #1 ; decrement count (if frozen then C:=0) - STRHIB R0, AutoRepeatCount ; store back if now non-zero and not frozen - Pull "R11,PC", NE ; return if non-zero or was frozen - - LDRB R1, Debouncing ; get debounce flag - TEQ R1, #0 - - STRNEB R0, Debouncing ; if not zero, zero it - LDROSB R0, KeyRepDelay, NE ; and load delay - MOVNE R1, #2 ; indicate first time - - LDROSB R0, KeyRepRate, EQ ; if zero, then load repeat - MOVEQ R1, #3 ; indicate subsequent time - - STRB R0, AutoRepeatCount ; in any case, store back - - Push "R4-R10" ; save registers - BL GenerateChar ; R2 = key number - Pull "R4-R11,PC" - -; ***************************************************************************** -; -; DoBreakKey - Called by key handler when break key up or down -; -; in: R0 -> key structure -; R1 = 0 for up, 1 for down (shouldn't be 2 or 3) -; R2 = ARM internal key number -; R3 = address of ReturnVector -; R4 = special number 1..n -; R5 = keyboard status -; -; out: R6 -> list of chars to return -; - -DoBreakKey ROUT - TST R5, #KBStat_ShiftEngaged ; shift down ? - MOVEQ R3, #31 - MOVNE R3, #29 - - TST R5, #KBStat_CtrlEngaged ; ctrl down ? - BICNE R3, R3, #4 - - LDROSB R2, BREAKvector - MOVS R2, R2, LSL R3 ; put relevant bits in C,N - - MOVCS PC, R14 ; 2 or 3 => ignore - BPL %FT10 ; 0 => do a reset - - TEQ R1, #1 ; is it key down ? - ADREQ R6, EscList ; yes, return ESCAPE - MOV PC, R14 ; else just return - -10 - [ AssemblingArthur - TEQ R1, #0 ; is it key up ? - MOVNE PC, R14 ; no, then return - -; This entry point is used by new SWI OS_Reset (TMD 06-Jan-94) -; If it's break on the keyboard R0 <> the magic 'power off' word,when '&OFF' is -; passed in R0 the power will be turned off assuming the hardware supports it - -PerformReset - - Push R0 - WritePSRc F_bit+I_bit+SVC_mode, R14 - - BL IICAbort ; Ensure any CMOS operation aborted - MOV R1, #Service_PreReset ; offer the pre-reset service - IssueService - - WritePSRc F_bit+I_bit+SVC_mode, R14 ; just in case! - Pull R0 - - LDR R1, PowerDownMagic - TEQ R0, R1 - BNE %FT15 - [ :LNOT: HAL - LDR r0, =&83900000 ; Address in IOMD to force power off - LDR r0, [r0] - | - AddressHAL - MOV a1, #0 - CallHAL HAL_Reset - ] -15 - B CONT_Break ; If we can't turn the power off,we may end up back here anyway - | - MOV PC, R14 ; do nowt - ] - -EscList - = 1, &1B - ALIGN -PowerDownMagic - DCD &46464F26 - -; ***************************************************************************** -; -; Generate a character in keyboard buffer, if necessary -; -; in: R1 = 2 if first press; 3 if repetition -; R2 = key number -; R12 -> IOC -; - -GenerateChar ROUT - Push R14 - LDR R0, KeyVec - CMP R0, #-1 - Pull PC,EQ - LDR R3, [R0, #KVKeyTranSize] ; get size - CMP R2, R3 ; if outside table - BCS %FT04 ; then assume special - - LDR R3, [R0, #KVKeyTran] ; R3 = offset to KeyTran - ADD R3, R3, R0 ; R3 -> KeyTran - -; now modify for CTRL and SHIFT - - LDROSB R5, KeyBdStatus - - TST R5, #KBStat_CtrlEngaged - ADDNE R3, R3, #2 - - TST R5, #KBStat_ShiftEngaged - ADDNE R3, R3, #1 - - LDRB R3, [R3, R2, LSL #2] ; get real code - -; apply CAPS lock modifying - - BIC R6, R3, #&20 ; get upper-case code - CMP R6, #"A" - RSBCSS R6, R6, #"Z" ; is it alphabetic ? - BCC %FT20 - - TST R5, #KBStat_ShiftEnable ; if SHCAPS - EORNE R3, R3, #&20 ; then swap case - - TSTEQ R5, #KBStat_NoCapsLock ; else if CAPS - BICEQ R3, R3, #&20 ; force upper case -20 - TEQ R3, #&FF ; is it a special ? - BEQ %FT04 ; [yes, so skip] - - LDROSB R6, ESCch ; if ESCAPE character - TEQ R3, R6 - LDROSB R6, ESCaction, EQ ; and normal ESCAPE action - TEQEQ R6, #0 - LDROSB R6, ESCBREAK, EQ ; and ESCAPE not disabled - TSTEQ R6, #1 - BNE %FT21 - - TST R5, #KBStat_PendingAlt - BEQ %FT21 - MOV R5, R12 - BIC R5, R5, #KBStat_PendingAlt ; then cancel pending alt - BL OfferPostKeyStatusUpCall ; don't let them interfere - STROSB R5, KeyBdStatus, R6 ; and store back - -21 TST R5, #KBStat_PendingAlt ; is there a pending Alt ? - BNE ProcessPendingAlt - - TEQ R3, #0 ; is it NUL ? - BNE %FT10 ; no, so skip - - ADR R6, NULNULList ; then insert NUL NUL - B ReturnNChars - -CallSpecialReturnNChars - Push R14 -04 - BL CallSpecialCode - -ReturnNChars - LDRB R3, [R6], #1 ; R1 = count of characters - -; TMD 25-Sep-89: Fix bug which resulted in Break key (acting as Escape) not -; working if buffer was full - only count spaces if more than 1 character going -; into buffer - - [ {TRUE} - CMP R3, #1 - Pull PC, CC ; no chars, so exit now - BEQ %FT05 ; only 1 char, don't count - | - TEQ R3, #0 ; no chars? - Pull PC, EQ ; then exit now - ] - - MOV R1, #Buff_Key - CMP PC, #0 ; C=1, V=0 so count spaces - BL CnpEntry - ORR R1, R1, R2, LSL #8 ; R1 = number of spaces - CMP R3, R1 ; are there enough ? - Pull PC, HI ; no, then forget them - -05 - LDRB R2, [R6], #1 ; send chars - BL InsertKeyZCOE ; one at a time - SUBS R3, R3, #1 - BNE %BT05 - Pull PC - -10 - Pull R14 ; restore stacked R14 - MOV R2, R3 - -; and drop thru to ... - -; ***************************************************************************** -; -; InsertKeyZCOE - Insert key zeroing count on escape -; -; in: R2 = character -; - -InsertKeyZCOE - LDROSB R0, KeyBdDisable ; disable insertion of codes ? - TEQ R0, #0 - MOVNE PC, R14 ; [disabled] - LDROSB R0, ESCch ; escape character - TEQ R0, R2 ; if is esc char - LDROSB R0, ESCaction, EQ - TEQEQ R0, #0 ; and FX229,0 - - STREQB R0, AutoRepeatCount ; then zero repeat counter - -; and drop thru to ... - -; ***************************************************************************** -; -; RDCHS - Insert character into keyboard buffer -; -; in: R2 = character -; - -RDCHS ROUT - MOV R1, #Buff_Key ; keyboard buffer id - -; Insert character R2 into buffer R1, checking for escape character - - B DoInsertESC - -; ***************************************************************************** - -NULNULList ; list for returning NUL NUL - = 2, 0, 0 - ALIGN - -; ***************************************************************************** - -ProcessPendingAlt - ADR R6, NullCharList - LDR R8, [R0, #KVPendingAltCode] - ADD R8, R8, R0 - BL CallUserKeyCode - B ReturnNChars - -; ***************************************************************************** -; -; Read character entry point -; -; in: - -; out: R0 = character -; C=1 => ESCAPE -; R1-R13 preserved -; - -NewRdch - Push "R1-R4,R11" - MOV R11, #KeyWorkSpace - MOV R4, #1 ; indicate RDCH not INKEY - BL RdchInkey - Pull "R1-R4,R11,PC" - -; ***************************************************************************** -; -; RDCH/INKEY -; -; in: R4 = 0 => INKEY -; R4 <> 0 => RDCH ; *** TMD This changed 25-Apr-91 *** -; -; out: V=1 => error (and possibly R0 -> error block if you're lucky!) -; - -RdchInkey Entry - -; Enable interrupts so that keyboard can work properly - - WritePSRc SVC_mode, r1 - - MOV r1, #0 - LDRB r1, [r1, #RedirectInHandle] - TEQ r1, #0 - BEQ %FT10 - -; Tutu doesn't believe that an escape condition should break redirection -; - similar to exec if you turn off escape ack side-effects - - SWI XOS_BGet ; get byte from redirection handle - BVS RedirectBadExit - BCC ReturnChar ; (C=0) - -; EOF, so close redirect file and read from exec file or keyboard - -; stop redirecting, BEFORE closing file, in case the CLOSE gets an error - - MOV r0, #0 - STRB r0, [r0, #RedirectInHandle] ; Convenient, huh ? - SWI XOS_Find ; close file (R0=0, R1=handle) - EXIT VS - -10 - -; First check for EXEC file - - LDROSB R1, ExecFileH ; read EXEC handle - TEQ R1, #0 - BEQ %FT20 ; no exec file - - SWI XOS_BGet ; get byte from exec handle - BVS ExecBadExit - BCC ReturnChar ; (C=0) - -; EOF, so close exec file and read from keyboard - -; stop EXECing, BEFORE closing file, in case the CLOSE gets an error - - STROSB R0, ExecFileH, R0 ; (STROSB sets temp reg to 0) - SWI XOS_Find ; close file (R0=0, R1=handle) - EXIT VS -20 - Push "R5,R6" - MOV R5, #0 - [ StorkPowerSave - LDRB R5, [R5, #PortableFlags] ; 0 if not a portable, else Portable_Features result - | - LDRB R5, [R5, #PortableFlag] ; 0 if want to try issuing SWI, 1 if know it's hopeless - ] - -RdchLoop - MOV R0, #0 - LDRB R0, [R0, #ESC_Status] - MOVS R0, R0, LSL #(32-6) ; shift relevant bit into carry - MOVCS R0, #27 ; escape detected - BCS ReturnChar2 - - LDROSB R1, InputStream ; 0 => keyboard, 1 => RS423 - BL RDCHG - BCC ReturnChar2 - -; Sam's hack to call the callback vector if appropriate - - [ AssemblingArthur - MOV R0, #0 - LDRB R14, [R0, #CallBack_Flag] - TST R14, #CBack_VectorReq - BLNE process_callback_chain - ] - -; here endeth the hack - - TEQ R4, #0 ; EQ => inkey, NE => rdch - LDREQ R0, InkeyCounter ; if inkey - TEQEQ R0, #0 ; and count expired - BEQ InkeyTimeout - - [ StorkPowerSave - TST R5, #PortableFeature_Idle - SWINE XPortable_Idle - TST R5, #PowerSave - BNE RdchLoop ; if we've gone slow already, then loop - TST R5, #PortableFeature_Speed - BEQ RdchLoop ; if speed change doesn't work, then loop - MOV R0, #1 ; go slow - MOV R1, #0 - SWI XPortable_Speed ; out: R0 = old speed, R1 = new speed - ORRVC R5, R5, #PowerSave ; if OK, indicate power save mode - MOVVC R6, R0 ; and remember old speed - MOVVS R5, #0 ; if got error, then indicate we don't want to try again - STRVSB R5, [R5, #PortableFlags] ; and store this back for future RDCHs - | - CMP R5, #1 ; if we've gone slow already (2), or there's no portable module (1), then loop - BCS RdchLoop - MOV R0, #1 ; go slow - MOV R1, #0 ; ignore old speed - SWI XPortable_Speed ; out: R0 = old speed, R1 = new speed - MOVVC R5, #2 ; if OK, indicate we've successfully gone slow - MOVVC R6, R0 ; and remember old speed - MOVVS R5, #1 ; if got error, then indicate we don't want to try again - STRVSB R5, [R5, #PortableFlag-1] ; and store this back for future RDCHs - ] - B RdchLoop - -InkeyTimeout - MOV R0, #&FF ; indicate timeout - SEC ; and set carry -ReturnChar2 - [ StorkPowerSave - TST R5, #PowerSave ; NB preserves carry - BLNE RestoreSpeed - | - TEQ R5, #2 ; NB preserves carry - BLEQ RestoreSpeed - ] - Pull "R5,R6" -ReturnChar - CLRPSR V_bit, R14 - EXIT - -RestoreSpeed EntryS "R0" - MOV R0, R6 ; restore old speed - MOV R1, #0 ; AND mask of 0 - SWI XPortable_Speed - EXITS ; restore R0 and carry - -ExecBadExit ; got an error from BGET - Push R0 ; save error pointer - STROSB R0, ExecFileH, R0 ; (STROSB sets temp reg to 0) - SWI XOS_Find ; close file (R0=0, R1=handle) - Pull "R1, R14" ; pull registers - MOVVC R0, R1 ; if closed OK, then restore old error - SETV ; still indicate error - MOV PC, R14 - -RedirectBadExit ; got an error from BGET - BL RemoveOscliCharJobs ; preserves r0 - SETV ; still indicate error - Pull "PC" ; pull register - -; ***************************************************************************** -; -; RDCHG - Fetch character from input buffer -; Expand soft keys as necessary -; Pass cursor control keys to VDU driver -; Return carry set if character not available -; -; in: R1 = input buffer id (0 => keyboard, 1 => RS423) - -RDCHG ROUT - Push R14 - -; insert check here for ECONET interception of RDCH - -RDCHNM - LDROSB R0, SoftKeyLen ; are we expanding a soft key - TEQ R0, #0 - BEQ RDCHG1 ; not expanding - - LDROSB R2, RS423mode - TST R1, R2 ; if RS423 and 8 bit data - BNE RDCHG1 ; ignore soft keys - - LDR R2, SoftKeyPtr - LDRB R2, [R2, -R0] ; get character out of buffer - - SUB R0, R0, #1 ; decrement character count - STROSB R0, SoftKeyLen, R3 ; store back - - MOV R0, R2 ; put character in R0 - CLC ; and exit with carry clear - Pull PC - -RDCHG1 - BL KeyREMOVECheckRS423 ; remove character, if none, exit CS - - LDROSB R2, RS423mode ; 0 => treat RS423 as keyboard - TST R1, R2 ; NZ => let RS423 deliver 8-bit codes - BNE RDCHGCLC - - TEQ R0, #0 ; is it NUL ? - BNE %FT10 - - BL KeyREMOVECheckRS423 ; get another char, if none then - ; spurious, so ignore - - TEQ R0, #0 ; is it NUL NUL ? - BNE RDCHGCLC ; no, then return this character - - LDRB R2, [R0, #OsbyteVars + :INDEX: IPbufferCh]! - ; R0 was 0, so now -> 1st of 8 keybases - ADD R3, R0, #8 -05 - TEQ R2, #2 ; is this key base = 2 ? - MOVEQ R0, #0 ; if so then return NUL NUL - BEQ ReturnNULR0 - LDRB R2, [R0, #1]! ; load next key base - TEQ R0, R3 ; if not tried all of them - BNE %BT05 ; then loop - MOV R0, #0 ; no special key bases, - ; so just return NUL -10 - TST R0, #&80 - BEQ RDCHGCLC - -; now check for cursor key movement - - AND R3, R0, #&0F ; save bottom nybble - CMP R3, #&0B ; is it a cursor key ? - BCC NotCursorKey - - TST R0, #&40 ; don't let Cx-Fx be cursor keys - BNE NotCursorKey - - LDROSB R2, CurEdit ; FX 4 state - CMP R2, #1 - ADDLS R0, R3, #&87-&0B ; 0 or 1 => force in range &87-&8B - BCC ItsCursorEdit ; 0 => cursor edit - BEQ RDCHGCLC ; 1 => return these codes - -NotCursorKey - MOV R0, R0, LSR #4 - EOR R0, R0, #&0C ; 4..7, 0..3 - LDRB R2, [R0, #OsbyteVars+IPbufferCh-OSBYTEFirstVar] - ; get key variable - CMP R2, #1 ; is it 0 (ignore) or 1 (softkey) - BCC RDCHG1 ; get another char if 0 - - BEQ ExpandSoftKey ; expand soft key if 1 - - TEQ R2, #2 ; is it special Compact option ? - EOREQ R0, R0, #&0C ; undo that mangling ! - ORREQ R0, R3, R0, LSL #4 ; if so, then return NUL <code> - BEQ ReturnNULR0 - - ADD R0, R2, R3 ; add offset to base - AND R0, R0, #&FF ; make it wrap - -RDCHGCLC - CLC - Pull PC - - -ItsCursorEdit - LDROSB R2, WrchDest - TST R2, #2 ; if wrch not to VDU - BNE RDCHG1 ; then ignore character - - Push "R1,R4-R12" - [ AssemblingArthur - VDWS WsPtr - BL DoCursorEdit - | - BL DCE10 - ] - Pull "R1,R4-R12" - - BCS RDCHG1 ; no character yet, so loop - Pull PC ; NB carry clear - no ESCAPE ! - - [ :LNOT: AssemblingArthur -DCE10 - MOV R1, #VduDriver - ADD PC, R1, #CursorEdit - ] - -; ***************************************************************************** -; -; ReturnNULR0 - Return NUL followed by R0 from RDCH -; - -ReturnNULR0 ROUT - ADR R2, SoftKeyExpand ; store code in SoftKeyExpand +0 - STRB R0, [R2], #1 ; and set ptr to SoftKeyExpand +1 - STR R2, SoftKeyPtr - MOV R2, #1 ; set key length to 1 - STROSB R2, SoftKeyLen, R0 ; (sets R0 to 0!) - B RDCHGCLC ; return NUL as first character - -; ***************************************************************************** - -KeyREMOVECheckRS423 ROUT - Push R14 - BL KeyREMOVE - Pull "R14, PC", CS ; pull stacked R14 if CS - Pull PC - -; ***************************************************************************** - -KeyREMOVE - Push "R10,R12,R14" - CLRV ; do remove not examine - MOV R10, #REMV - B GoVec - - -; expand a soft key as a variable (R3 = key number) - -ExpandSoftKey ROUT - Push "R1,R4" - BL SetupKeyName - ADR R1, SoftKeyExpand - MOV R2, #255 ; max length of string - MOV R3, #0 ; no name pointer - MOV R4, #VarType_Expanded - SWI XOS_ReadVarVal - - Pull "R1,R4", VS - BVS RDCHG1 ; no string or bad - - STROSB R2, SoftKeyLen, R0 ; store length (may be zero) - ADD R1, R1, R2 ; R1 -> last char+1 - STR R1, SoftKeyPtr - Pull "R1,R4" - B RDCHNM ; try to expand it - -KeyName - = keyprefix,0 - ALIGN - -; ***************************************************************************** -; -; SetupKeyName - Set up the name <keyprefix><n><0> in SoftKeyName -; -; in: R11 -> KeyWS -; R3 = key number -; -; out: R0 -> SoftKeyName, which contains <keyprefix><n><0> -; R2-R4 corrupted -; - -SetupKeyName ROUT - ADR R2, KeyName - ADR R0, SoftKeyName -10 - LDRB R4, [R2], #1 ; copy keyprefix in - TEQ R4, #0 - STRNEB R4, [R0], #1 - BNE %BT10 ; now put digits at R0 - - ORR R3, R3, #"0" - CMP R3, #"9"+1 - - MOVCS R2, #"1" ; if >=10 then put in "1" - STRCSB R2, [R0], #1 - SUBCS R3, R3, #10 ; and subtract 10 - - STRB R3, [R0], #1 - STRB R4, [R0] ; (R4=0) terminate - - ADR R0, SoftKeyName - MOV PC, R14 - -; ***************************************************************************** -; -; DoInkeyOp - Perform INKEY - -DoInkeyOp - TST R2, #&80 ; INKEY(+ve) ? - BNE NewInkeyNeg - -NewInkeyPos - Push R4 - MOV R11, #KeyWorkSpace - AND R1, R1, #&FF ; no funny business - AND R2, R2, #&FF ; ditto - ORR R1, R1, R2, LSL #8 ; get combined count - STR R1, InkeyCounter - - MOV R4, #0 ; indicate inkey not rdch - BL RdchInkey - - MOV R1, R0 ; make X the character - MOVCC R2, #0 ; Y := 0 if normal exit - MOVCS R2, R0 ; Y := &1B or &FF for ESC or timeout - - Pull "R4,PC" ; return preserving V and R0 - -NewInkeyNeg - EOR R1, R1, #&7F ; invert bits for scan call - BL BBCScanKeys - Pull PC - -; ***************************************************************************** -; -; BBCScanKeys - Test individual key or scan for key depression -; -; in: R1 = 0..&7F => scan keyboard from BBC internal key R1 -; out: C=0 => R1 = BBC internal key found -; C=1 => R1 = &FF (no key found) -; -; in: R1 = &80..&FF => test if BBC internal key (R1 EOR &80) is down -; out: C=0, R1=R2=&00 => key is up -; C=1, R1=R2=&FF => key is down -; - -BBCScanKeys ROUT - Push R11 - MOV R11, #KeyWorkSpace - AND R1, R1, #&FF ; trap wallies - - LDR R2, KeyVec - - TST R1, #&80 ; >=&80 => test single key - ; < &80 => scan for key - BEQ DoBBCScan ; [is scanning not testing] - - ADD R0, R2, #1 - CMP R0, #1 ; if no key handler then - MOVCC R1, #0 ; return key up (C=0) - BCC ExitBBCScan - - LDR R0, [R2, #KVInkeyTran] - ADD R0, R2, R0 ; R0 -> InkeyTran or InkeyTran2 - - ADD R0, R0, #4 * &FF ; R0 -> InkeyTran+4*&FF - LDR R0, [R0, -R1, LSL #2] ; get word of indexes into KeysDown - MOV R2, #&FF000000 -02 - CMP R0, #-1 ; is it all FF's - MOVEQ R1, #0 ; if so then none of keys down - BEQ %FT04 - - AND R1, R0, #&FF ; just get bottom byte - ADR R3, KeysDown ; look up in KeysDown - MOV R1, R1, LSR #5 - LDR R3, [R3, R1, LSL #2] ; get word of 32 bits - AND R1, R0, #31 - MOV R3, R3, LSL R1 ; put relevant bit into top bit - MOVS R1, R3, LSR #31 ; R1 = 0 if up, 1 if down - ORREQ R0, R2, R0, LSR #8 ; shift down, putting FF in top byte - BEQ %BT02 -04 - CMP R1, #1 ; C=1 <=> at least one of keys down - MOVCC R1, #0 - MOVCS R1, #&FF - MOV R2, R1 -ExitBBCScan - Pull R11 - MOV PC, R14 - -DoBBCScan - CMP R2, #-1 ; if no key handler then - MOVEQ r1, #&FF ; return all keys up (C=1) - BEQ ExitBBCScan - LDR R0, [R2, #KVInkeyTran] - ADD R0, R2, R0 ; R0 -> InkeyTran or InkeyTran2 - - Push "R4, R5" - ADD R0, R0, #4 * &7F ; R0 -> InkeyTran+4*&7F - MOV R4, #&FF000000 -10 - LDR R3, [R0, -R1, LSL #2] ; get word of indexes into KeysDown -15 - CMP R3, #-1 ; all FFs ? - BEQ %FT18 ; then not one of these keys - - AND R5, R3, #&FF - ADR R2, KeysDown - MOV R5, R5, LSR #5 - LDR R2, [R2, R5, LSL #2] ; get word of bits - AND R5, R3, #31 - MOV R2, R2, LSL R5 ; put relevant bit into top bit - MOVS R5, R2, LSR #31 ; R5 = 0 for up, 1 for down - BNE %FT20 ; [down, so stop] - ORR R3, R4, R3, LSR #8 ; up -> shift down putting FF in top - B %BT15 -18 - ADD R1, R1, #1 ; go to next key - TEQ R1, #&80 ; if not run out of keys - BNE %BT10 ; then loop - MOV R1, #&FF ; indicate no key -20 - CMP R1, #&FF ; C=0 <=> found key - Pull "R4,R5,R11" - MOV PC, R14 - -; ***************************************************************************** -; -; Write keys down information -; -; in: R1 = Current key (in BBC internal key format) -; R2 = Old key (------------""------------) -; -; out: R1, R2 preserved -; - -WriteKeysDown ROUT - Push R14 - MOV R11, #KeyWorkSpace - MOV R0, R1 - BL ConvertInternalKey - STRB R0, CurrKey - MOV R0, R2 - BL ConvertInternalKey - STRB R0, OldKey - Pull PC - -ConvertInternalKey - TST R0, #&80 ; if not in range &80..&FF - MOVEQ R0, #&FF ; return value &FF (key not valid) - MOVEQ PC, R14 - - EOR R0, R0, #&7F ; else convert to inkey value - Push R4 - LDR R3, KeyVec - CMP R3, #-1 ; if no key handler then - MOVEQ R0, #&FF ; return no key - MOVEQ PC, R14 - LDR R4, [R3, #KVInkeyTran] - ADD R3, R3, R4 ; R3 -> InkeyTran or InkeyTran2 - Pull R4 - - SUB R3, R3, #&80*4 ; R3 -> InkeyTran-4*&80 - - LDRB R0, [R3, R0, LSL #2] ; convert to ARM internal key - ; (just get 1st key for this key) - MOV PC, R14 - - -; ***************************************************************************** -; -; InstallKeyHandler - Install user key handler -; -; in: R0 = new key handler -; 0 => just read old key handler -; 1 => just read keyboard id -; -; out: R0 = old key handler, or -; R0 = keyboard id if R0 was 1 on entry (&FF => no keyboard id yet) -; - -InstallKeyHandler ROUT - MRS R11, CPSR - ORR R11, R11, #I32_bit - MSR CPSR_c, R11 ; disable IRQs - - MOV R11, #KeyWorkSpace - TEQ R0, #1 ; asking for keyboard id ? - LDREQB R0, KbId ; then load it - ExitSWIHandler EQ ; and exit - - LDR R10, KeyVec ; R10 -> old key handler - TEQ R0, #0 ; if not just reading it - STRNE R0, KeyVec ; then store new one - MOV R0, R10 ; R0 -> old key handler - ExitSWIHandler EQ ; exit if just reading - - Push "R0-R12,LR" - BL KeyboardEnable - Pull "R0-R12,LR" - ExitSWIHandler - -; ***************************************************************************** -; -; IssueKeyboardService - Issue keyboard handler service -; -; in: R11 -> KeyWorkSpace -; -; out: R0 preserved -; - -IssueKeyboardService - Push "R0,R14" - MOV R1, #Service_KeyHandler - LDRB R2, KbId - IssueService - Pull "R0,PC" - - - END diff --git a/s/PMF/mouse b/s/PMF/mouse deleted file mode 100644 index be0bb0a4..00000000 --- a/s/PMF/mouse +++ /dev/null @@ -1,474 +0,0 @@ -; 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.Mouse - -; Mouse driving code - -; Author: Steve Cormie -; Started: 24-Feb-93 - -; Change history: -; -; Date Who Description -; ---- --- ----------- -; 24-Feb-93 SMC Created. - -; ***************************************************************************** -; -; Mouse initialisation -; -MouseInit - Push "lr" - MOV r11, #KeyWorkSpace - - [ :LNOT: AssemblingArthur - MOV r0, #MouseV - ADRL r1, ReadMouse - SWI OS_Claim - ] - - MOV r0, #MouseStepCMOS ; setup mouse multipliers from CMOS - BL Read - MOV r0, r0, LSL #24 ; sign extend it - MOVS r0, r0, ASR #24 - MOVEQ r0, #1 ; if would be zero, set to 1 - STR r0, MouseXMult - STR r0, MouseYMult - - MOV r0, #0 - STRB r0, MouseButtons - [ STB - STRB r0, MousePresent - ] - - MOV r0, #MouseCMOS - BL Read - STRB r0, MouseType - - Pull "pc" - -; ***************************************************************************** -; -; MouseButtonChange - Called by keyboard handler when mouse button change -; -; in: R0 = state of buttons (bit0=R, bit1=C, bit2=L) -; R11 -> KeyWorkSpace -; - -MouseButtonChange ROUT - Push "R0-R5, R12, R14" - - VDWS WsPtr - STRB R0, MouseButtons ; save it for ReadMouse calls - MOV R3, R0 - - LDR R1, MouseX - LDR R0, [WsPtr, #OrgX] - SUB R1, R1, R0 ; mouse X - - LDR R2, MouseY - LDR R0, [WsPtr, #OrgY] - SUB R2, R2, R0 ; mouse Y - - [ AssemblingArthur :LOR: Module - MOV R4, #0 - LDR R4, [R4, #MetroGnome] ; use monotonic variable now - | - BYTEWS WsPtr - LDR R4, RealTime ; doesn't exist in my world - ] - - MOV R0, #Event_Mouse - BL OSEVEN - MOV WsPtr, #IOC - - [ :LNOT:MouseBufferManager - [ MouseBufferFix - LDR R0, MouseX - | - MOV R5, R2 ; save mouse Y - MOV R0, R1 - ] - BL MouseInsert ; send mouse X low - BCS %FT10 ; buffer full, so don't send rest - - MOV R0, R0, LSR #8 ; send mouse X high - BL MouseInsert - - [ MouseBufferFix - LDR R0, MouseY - | - MOV R0, R5 - ] - BL MouseInsert ; send mouse Y low - - MOV R0, R0, LSR #8 ; send mouse Y high - BL MouseInsert - - MOV R0, R3 - BL MouseInsert ; send buttons - - MOV R0, R4 - BL MouseInsert ; send realtime(0) - - MOV R0, R4, LSR #8 - BL MouseInsert ; send realtime(1) - - MOV R0, R4, LSR #16 - BL MouseInsert ; send realtime(2) - - MOV R0, R4, LSR #24 - BL MouseInsert ; send realtime(3) - | -; Use buffer manager's 'block insert' function - - [ {TRUE} - -; TMD 26-Feb-93: Fix bug - if X is negative, Y would be inserted in the buffer as -1 - - LDR R0, MouseX ; 16 bits, sign-extended to 32 bits - MOV R0, R0, LSL #16 - LDR R1, MouseY ; ditto - MOV R1, R1, LSL #16 - ORR R0, R1, R0, LSR #16 ; combine, having knocked off the troublesome bits - | - LDR R0, MouseX ; 16 bits - LDR R1, MouseY ; 16 bits - ORR R0, R0, R1, LSL #16 ; R0 = Combined 16bit X/Y mouse position - ] - ORR R1, R3, R4, LSL #8 ; R1 = Combined 8bit buttons and 24 LSB's of time - MOV R2, R4, LSR #24 ; R2 = MSB of time - SUB SP, SP, #3*4 ; Create local mouse data buffer - STMIA SP, {R0,R1,R2} ; Write mouse data to buffer - - MOV R3, #9 ; Mouse packet size - MOV R2, SP ; R2-> block to insert - MOV R1, #(Buff_Mouse:OR:(1:SHL:31)) ; Block insert to mouse buffer - Push "R10,R12" - MOV R10, #INSV ; Insert - BL GoVec2 ; Call the vector in R10 - Pull "R10,R12" - ADD SP, SP, #3*4 ; Destroy mouse data buffer - ] -10 - Pull "R0-R5, R12, PC" - - [ :LNOT:MouseBufferManager -MouseInsert - Push "R10,R12,R14" - MOV R10, #INSV - MOV R1, #Buff_Mouse - B GoVec - ] - -; ***************************************************************************** -; -; Read mouse position -; - -ReadMouse ROUT - Push "R4-R6,R10-R12" - MOV R11, #KeyWorkSpace - - [ :LNOT:MouseBufferManager - MOV R1, #Buff_Mouse - BL KeyREMOVE - BCS %FT10 ; MouseAhead buffer empty - - MOV R4, R2, LSL #16 ; Mouse X Low - BL KeyREMOVE - ORR R4, R4, R2, LSL #24 ; R4 := Mouse X << 16 - - BL KeyREMOVE - MOV R5, R2, LSL #16 ; Mouse Y Low - BL KeyREMOVE - ORR R5, R5, R2, LSL #24 ; R5 := Mouse Y << 16 - - BL KeyREMOVE - MOV R6, R2 ; Button state - - BL KeyREMOVE ; get realtime - MOV R3, R2 - BL KeyREMOVE - ORR R3, R3, R2, LSL #8 - BL KeyREMOVE - ORR R3, R3, R2, LSL #16 - BL KeyREMOVE - ORR R3, R3, R2, LSL #24 - - MOV R0, R4, ASR #16 ; sign extend mouse coords - MOV R1, R5, ASR #16 - MOV R2, R6 - | - SUB SP, SP, #3*4 ; Create 9 byte local mouse data buffer - MOV R3, #9 ; Mouse packet size - MOV R2, SP ; R2-> buffer for data - MOV R1, #(Buff_Mouse:OR:(1:SHL:31)) ; Block remove from mouse buffer - CLRV ; Remove not examine - Push "R10,R12" - MOV R10, #REMV - BL GoVec2 ; Call the vector in R10 - Pull "R10,R12" - - LDMCCIA SP, {R4,R5,R6} - ADD SP, SP, #3*4 ; Destroy mouse data buffer - BCS %FT10 ; Jump if no buffered data - - MOV R0, R4, LSL #16 - MOV R0, R0, ASR #16 ; R0 = sign extended x coord - MOV R1, R4, ASR #16 ; R1 = sign extended y coord - AND R2, R5, #&FF ; R2 = button state - MOV R3, R5, LSR #8 ; R3 = 3 low order bytes of time - ORR R3, R3, R6, LSL #24 ; R3 = time - ] - -; code inserted here 12-Aug-88 to force position read from buffer to be inside -; CURRENT bounding box; this removes the need to flush buffer when changing -; the bounding box. - - ADR R4, MouseBounds - LDMIA R4, {R4-R6,R10} ; R4=LCol; R5=BRow; R6=RCol; R10=TRow; - CMP R0, R4 - MOVLT R0, R4 - CMP R0, R6 - MOVGT R0, R6 - CMP R1, R5 - MOVLT R1, R5 - CMP R1, R10 - MOVGT R1, R10 - - [ MouseBufferFix - B %FT20 ; correct for origin after clipping - | - Pull "R4-R6,R10-R12,PC" - ] - -10 - LDRB R2, MouseButtons - - [ AssemblingArthur :LOR: Module - MOV R3, #0 - LDR R3, [R3, #MetroGnome] ; use monotonic variable now - | - BYTEWS WsPtr - LDR R3, RealTime ; doesn't exist in my world - ] - - LDR R0, MouseX - LDR R1, MouseY -20 - VDWS WsPtr - - LDR R4, [WsPtr, #OrgX] - SUB R0, R0, R4 - - LDR R4, [WsPtr, #OrgY] - SUB R1, R1, R4 - - Pull "R4-R6,R10-R12,PC" - -Abso DCB "Abso" - -; ***************************************************************************** -; -; ProcessMouseXY - Called to update mouse position. -; -; in: r2 = signed 32-bit X movement -; r3 = signed 32-bit Y movement -; r4 = "Abso" if absolute movement -; r11 ->KeyWorkSpace -; out: r2,r3 corrupted -; -ProcessMouseXY - Push "r4,lr" - -; check for absolute position - LDR lr, Abso - TEQ r4, lr - BEQ %FT40 - -; process X movement - CMP r2, #0 - BEQ %FT10 - - MOV r2, r2, LSL #16 ; move delta X to top 16 bits - - LDR r4, MouseXMult - MUL r2, r4, r2 - - LDR r4, MouseX - ADD r2, r2, r4, LSL #16 ; add signed value in top 16 bits - MOV r2, r2, ASR #16 ; sign extend to 32 bits - - LDR r4, MouseBoundLCol ; bound to bounding box - CMP r2, r4 - MOVLT r2, r4 - LDR r4, MouseBoundRCol - CMP r4, r2 - MOVLT r2, r4 - STR r2, MouseX - -10 -; process Y movement - CMP r3, #0 - Pull "r4,pc",EQ - - MOV r3, r3, LSL #16 ; move delta Y to top 16 bits - - LDR r4, MouseYMult - MUL r3, r4, r3 - - LDR r4, MouseY - ADD r3, r3, r4, LSL #16 ; add signed value in top 16 bits - MOV r3, r3, ASR #16 ; sign extend to 32 bits - - LDR r4, MouseBoundBRow ; bound to bounding box - CMP r3, r4 - MOVLT r3, r4 - LDR r4, MouseBoundTRow - CMP r4, r3 - MOVLT r3, r4 - STR r3, MouseY - - Pull "r4,pc" - -40 -; process absolute position - MOV r2, r2, ASL #16 ; look only at bottom 16 bits, - MOV r3, r3, ASL #16 ; sign extended - MOV r2, r2, ASR #16 - MOV r3, r3, ASR #16 - - LDR r4, MouseBoundLCol ; bound to bounding box - CMP r2, r4 - MOVLT r2, r4 - LDR r4, MouseBoundRCol - CMP r4, r2 - MOVLT r2, r4 - STR r2, MouseX - LDR r4, MouseBoundBRow ; bound to bounding box - CMP r3, r4 - MOVLT r3, r4 - LDR r4, MouseBoundTRow - CMP r4, r3 - MOVLT r3, r4 - STR r3, MouseY - Pull "r4,pc" - - - [ AssemblePointerV - -; ***************************************************************************** -; -; PollPointer - Called on VSync to get mouse changes. -; -; out: corrupts r0-r3,r9-r11 -; -PollPointer - Push "r4,r12,lr" - MOV r11, #KeyWorkSpace - - LDRB r0, MouseReporting - TEQ r0, #0 - Pull "r4,r12,pc",NE - - MOV r0, #0 ; Request pointer state. - LDRB r1, MouseType - MOV r2, #0 ; Default to no movement. - MOV r3, #0 - MOV r4, #0 ; They might fill this in - SavePSR r9 ; Save current PSR. - WritePSRc SVC_mode+I_bit, r10 ; Call PointerV in SVC mode, no IRQs. - MOV r10, #PointerV ; Call PointerV to get movements & button states - Push "lr" ; Save SVC lr. - BL CallVector - Pull "lr" ; Restore SVC lr. - RestPSR r9 - [ STB - TEQ r2, #0 - TEQEQ r3, #0 - MOVNE lr, #1 - STRNEB lr, MousePresent - BLNE ProcessMouseXY - | - BL ProcessMouseXY - ] - - Pull "r4,r12,pc" - -; ***************************************************************************** -; -; PointerVector - the default PointerV claimant -; -PointerVector - CMP r0, #PointerReason_Report - Pull pc, NE - Push "r2,r3,r11" - MOV r11, #KeyWorkSpace - LDRB lr, MouseType - TEQ r1, lr - MOVEQ lr, #1 - STREQB lr, MouseReporting - [ STB - TEQ r2, #0 - TEQEQ r3, #0 - MOVNE lr, #1 - STRNEB lr, MousePresent - BLNE ProcessMouseXY - | - BL ProcessMouseXY - ] - Pull "r2,r3,r11,pc" - - - -; ***************************************************************************** -; -; PointerSWI - Handle SWI OS_Pointer calls (read/set pointer type). -; -PointerSWI - MOV r11, #KeyWorkSpace - TEQ r0, #0 - LDREQB r0, MouseType - BEQ SLVK - - [ STB - TEQ r0, #2 - LDREQB r0, MousePresent - BEQ SLVK - ] - - TEQ r0, #1 - BNE %FT10 - - Push "r0,r10,r12,lr" - STRB r1, MouseType - MOV r0, #0 - STRB r0, MouseReporting - MOV r0, #2 - MOV r10, #PointerV - BL CallVector - Pull "r0,r10,r12,lr" - B SLVK - -10 - ADRL r0, ErrorBlock_BadParameters - [ International - BL TranslateError - ] - B SLVK_SetV - ] - - END diff --git a/s/PMF/osbyte b/s/PMF/osbyte deleted file mode 100644 index 839269ad..00000000 --- a/s/PMF/osbyte +++ /dev/null @@ -1,1267 +0,0 @@ -; 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.osbyte -; New version of OSBYTE which claims the ByteV(ector) properly -; PMF 18/9/86 -; Updates: -; Kernel -; Version Date Who Why -; 2.01 15-June-90 JSR Change OS_Byte 124/125/126 to update the CallBack_Flag byte -; correctly, rather than setting it to 1. The bug caused vector -; callbacks to be delayed over much when escape was pressed. -; ???? 08-Feb-95 WT Change OS_Byte 106 to support the new cursor storage method -; introduced for Stork LCD support. - -OsbyteLowLimit * &6A ; osbytes lower than this get Y set to 0 -OsbyteVeryLow * &1A ; osbytes lower than this are all recognised -OsbyteSetCountry * &46 -OsbyteSetAlphKey * &47 -OsbyteKeyStatus * &CA ; only OS_Byte variable which isn't pure any more! - -; ***************************************************************************** - - MACRO - MyOsbyte $cond - B$cond GoMyOsbyte - MEND - - MACRO - MyOsWord $cond - B$cond GoMyOsword - MEND - - MACRO - Unused $cond - MOV$cond PC, R14 ; just return and let the next person have a go - MEND - - MACRO - ByteReturnV $cond - ASSERT "$cond"="" :LOR: "$cond"="VS" - - [ "$cond"="" - Pull "R0,R3,R14,PC", VC - ] - ADDVS R13, R13, #4 ; junk stacked R0 - Pull "R3,R14,PC", VS - MEND - -; Main OSbyte entry point -; R0,R1,R2 are parameters - -OsByte - Push "R0, R3, R14" - BL OsByteGo ; Call the subsid entry pt. - Pull "R0,R3" - Push "R0-R4" - LDMIA R13, {R2-R4} ; R2=A, R3=X, R4=Y - MOV R1, #Service_UKByte ; osbyte service reason - IssueService - TEQ R1, #0 - STMEQIA R13, {R2-R4} ; if claimed, then update - ; returned R0-R2 - CLRPSR V_bit, R3 ; clear V flag - - Pull R0 - ADRNE R0, BadCommandError ; not claimed, R0 -> error - [ International - BLNE TranslateError - ] - SWINE XOS_GenerateError ; set V if not claimed - Pull "R1-R4, R14, PC" - -BadCommandError MakeErrorBlock BadCommand - -GoMyOsbyte - CLRPSR V_bit, R3 - Pull "R0,R3, R14,PC" ; pull the world AND the PC to return - - -; ***************************************************************************** - -OsByteGo ROUT - AND R0, R0, #&FF ; no funny business! - SUBS R3, R0, #OsbyteLowLimit ; is it a low one ? - BCS HiOsbyte - MOV R2, #0 ; lo one, so set Y to 0 - CMP R0, #OsbyteVeryLow ; is it one we recognise ? -10 - ADDCC PC, PC, R0, LSL #2 ; then go thru despatch table - B TryInternational ; else issue unknown osbyte service -20 - ASSERT %BT20-%BT10 = 8 - - BAL Osbyte00 - BAL Osbyte01 - BAL Osbyte02 - BAL Osbyte03 - BAL Osbyte04 - BAL Osbyte05 - BAL Osbyte06 - BAL Osbyte07 - - BAL Osbyte08 - BAL Osbyte09 - BAL Osbyte0A - BAL Osbyte0B - BAL Osbyte0C - BAL Osbyte0D - BAL Osbyte0E - BAL Osbyte0F - - BAL Osbyte10 - BAL Osbyte11 - BAL Osbyte12 - BAL Osbyte13 - BAL Osbyte14 - BAL Osbyte15 - BAL Osbyte16 - BAL Osbyte17 - - BAL Osbyte18 - BAL Osbyte19 - -HiOsbyte - CMP R0, #MainVars ; is it a variable ? -30 - ADDCC PC, PC, R3, LSL #2 - B DoOsbyteVar ; yes, then do variable mangling -40 - ASSERT %BT40-%BT30=8 - - BAL Osbyte6A - BAL Osbyte6B - BAL Osbyte6C - BAL Osbyte6D - BAL Osbyte6E - BAL Osbyte6F - - BAL Osbyte70 - BAL Osbyte71 - BAL Osbyte72 - BAL Osbyte73 - BAL Osbyte74 - BAL Osbyte75 - BAL Osbyte76 - BAL Osbyte77 - - BAL Osbyte78 - BAL Osbyte79 - BAL Osbyte7A - BAL Osbyte7B - BAL Osbyte7C - BAL Osbyte7D - BAL Osbyte7E - BAL Osbyte7F - - BAL Osbyte80 - BAL Osbyte81 - BAL Osbyte82 - BAL Osbyte83 - BAL Osbyte84 - BAL Osbyte85 - BAL Osbyte86 - BAL Osbyte87 - - BAL Osbyte88 - BAL Osbyte89 - BAL Osbyte8A - BAL Osbyte8B - BAL Osbyte8C - BAL Osbyte8D - BAL Osbyte8E - BAL Osbyte8F - - BAL Osbyte90 - BAL Osbyte91 - BAL Osbyte92 - BAL Osbyte93 - BAL Osbyte94 - BAL Osbyte95 - BAL Osbyte96 - BAL Osbyte97 - - BAL Osbyte98 - BAL Osbyte99 - BAL Osbyte9A - BAL Osbyte9B - BAL Osbyte9C - BAL Osbyte9D - BAL Osbyte9E - BAL Osbyte9F - - BAL OsbyteA0 - BAL OsbyteA1 - BAL OsbyteA2 - BAL OsbyteA3 - BAL OsbyteA4 - BAL OsbyteA5 - -TryInternational ; special ones in the middle - TEQ R0, #OsbyteSetCountry - BEQ DoOsbyteSetCountry - TEQ R0, #OsbyteSetAlphKey - BEQ DoOsbyteSetAlphKey - MOV PC, R14 - -; ***************************************************************************** - -; The Osbyte routines themselves - - -; Mos version number and title string -; R1 = 0 -> give an error with and string MosTitle -; R1 <>0 -> RETURN with R1 = MosVer - -; R2 is Preserved - -Osbyte00 ROUT - TEQ R1, #0 - MOVNE R1, #MosVer - MyOsbyte NE - ADR R0, FX0Error - SWI XOS_GenerateError - ByteReturnV - -FX0Error - & &F7 - = "$MosTitle",0 - ALIGN - -; ***************************************************************************** - -; Write User Flag -Osbyte01 -V2B156 - ADD R0, R0, #&F0 ; convert 1,5,6 to &F1,&F5,&F6 - B DoOsbyteVar - -; Select input stream -Osbyte02 ROUT - AND R0, R1, #1 ; new buffer id - TEQ R1, #0 ; 0 => disable RXI - Push "r0" - BNE %FT10 ; [enabling serial] - -; disable serial by closing stream - - LDRB r1, SerialInHandle - TEQ r1, #0 - MOVNE r0, #0 ; close file if handle non-zero - STRNEB r0, SerialInHandle ; zero handle first - SWINE XOS_Find - B %FT20 - -; enable serial by opening stream - -10 - LDRB r0, SerialInHandle - TEQ r0, #0 ; if a stream open already - BNE %FT20 ; then skip - - MOV r0, #open_read + open_mustopen - ADR r1, SerialInFilename ; open serial stream for input - SWI XOS_Find - STRVCB r0, SerialInHandle ; if did open then store handle - ; (may store same value if already open, but who cares?) -20 - Pull "r0" - LDRB R1, InputStream ; old input stream - STRB R0, InputStream - MyOsbyte - - LTORG - -SerialInFilename - = "Serial#Buffer1:", 0 - ALIGN - -; Select output stream -Osbyte03 - -Osbyte04 ; select cursor keys actions -V2B34 - ADD R0, R0, #&E9 ; convert 3,4 to &EC,&ED - B DoOsbyteVar - -; Write Printer driver type -Osbyte05 ROUT - BL MakePrinterDormant ; for netprint - SavePSR R14 ; for restoring I afterwards -10 - CLRPSR I_bit, R3 - [ StrongARM - NOP - NOP - NOP - NOP - NOP - ] - RestPSR R14 ; restore old I - - MOV R3, #0 - LDRB R3, [R3, #ESC_Status] - TST R3, #&40 - MyOsbyte NE ; ESCAPE, so don't change - - LDR R3, PrinterActive - TEQ R3, #0 - BNE %BT10 ; still active, then loop - -; insert code here to notify UPTVEC of change - - B V2B156 ; R0 = 5, update variable - -; Write Printer Ignore Character -Osbyte06 - STRB R2, NoIgnore ; (R2=0) allow chars to be ignored - B V2B156 - -; Write RS423 receive rate -; Write RS432 transmit rate -Osbyte07 -Osbyte08 - SUB r0, r0, #2 ; 7 -> 5; 8 -> 6 - SWI XOS_SerialOp - MyOsbyte - -; Write First Flash Time -Osbyte09 - MOV R2, #1 -; and drop thru to ... - -; Write Second Flash Time -Osbyte0A ; (R2=0) -Osbyte910 - MOV R0, R1 ; new period - LDRB R1, [R2, #OsbyteVars + :INDEX: SpacPeriod] ; get old state - STRB R0, [R2, #OsbyteVars + :INDEX: SpacPeriod] ; store new - - LDRB R3, FlashCount - TEQ R3, #0 ; are we frozen ? - MyOsbyte NE ; no, then finish - - STRB R0, FlashCount ; kick the counter - STRB R2, FlashState ; force new state - - VDWS WsPtr - - TEQ R2, #0 - BEQ ForceSecondState - - Push "R1,R2" - BL DoFirstFlash - Pull "R1,R2" - MyOsbyte - -ForceSecondState - Push "R1,R2" - BL DoSecondFlash - Pull "R1,R2" - MyOsbyte - - -; Write Keyboard Delay -Osbyte0B -V2BBC - ADD R0, R0, #(&C4-&0B) - B DoOsbyteVar - -; Write Keyboard Rate -Osbyte0C - TEQ R1, #0 - BNE V2BBC - CLRPSR I_bit, R0 ; this may take some time - BL ReadKeyDefaults - MyOsbyte - -; ***************************************************************************** - -; Disable / Enable Events -; R1 = Event number. Decrement/Increment semaphore for this event - -Osbyte0D ROUT -Osbyte0E ROUT - CMP R1, #32 ; if illegal event number - MOVCS R2, #0 ; then return + say was disabled - BCS %FT10 - - ADD R3, WsPtr, #:INDEX: EventSemaphores - LDRB R2, [R3, R1] ; get semaphore for this event - - CMP R0, #13 ; 13 => disable, 14 => enable - SUBEQ R0, R2, #1 ; decrement semaphore - ADDNE R0, R2, #1 ; increment semaphore - - CMP R0, #&100 ; C=1 => wrapped, so don't store back - STRCCB R0, [R3, R1] -10 - MOV R1, R2 ; R1 = R2 = old semaphore - MyOsbyte - -; ***************************************************************************** - -; Flush Buffer -Osbyte0F ROUT - TEQ R1, #0 - BNE FlushInput - BL FlushAll - MyOsbyte - -; flush all buffers - -FlushAll - Push R14 - MOV R1, #(NBuffers-1) -10 - BL FlushThis - SUBS R1, R1, #1 - BPL %BT10 - Pull PC - -; flush input buffer - -FlushInput - LDROSB R1, InputStream ; get buffer id of input stream - BL FlushThis - MyOsbyte - -; ***************************************************************************** - -; Clear out the softkeys -Osbyte12 ROUT - MOV R0, #0 - STRB R0, SoftKeyLen ; purge current expansion - MOV R11, #KeyWorkSpace ; can corrupt R11 - Push R4 - MOV R1, #15 -10 - MOV R3, R1 - BL SetupKeyName ; exits with R0 -> SoftKeyName - MOV R2, #-1 ; destroy variable - MOV R3, #0 ; context pointer 0 - MOV R4, #0 ; type irrelevant - SWI XOS_SetVarVal ; V will be set if not present - SUBS R1, R1, #1 - BPL %BT10 - Pull R4 - MyOsbyte - -; ***************************************************************************** - -; Wait for Vsync - -Osbyte13 ROUT - - MRS R3, CPSR ; Interrupts disabled at the moment - - ; bug fix for MED-03165. Having a DPMS-blanked screen stopped printing. - ; The reason is that HSyncs stop and VSyncs stop as a consequence, - ; but the Hourglass module uses this call to wait for the next VSync - ; before animating the hourglass. - ; When the screen is DPMS-blanked this osbyte will now return - ; immediately. This is equivalent to the operation of the DPMSUtils - ; module shipped with OS 3.50. - - VDWS R2 - - LDRB R0, [R2,#ScreenBlankFlag] - LDRB R1, [R2,#ScreenBlankDPMSState] - - TEQ R0, #0 ; NE => blanked - TSTNE R1, #1 ; NE => blanked and DPMS turned off HSyncs - MyOsbyte NE ; if true exit immediately - - LDRB R2, CFStime -10 - BIC R1, R3, #I32_bit - MSR CPSR_c, R1 ; CLI - - ;StrongARM core will not see interrupt unless disable is cleared for at least 5 cycles, - ;in order to fill synchroniser pipe - [ StrongARM - NOP - NOP - NOP - NOP - NOP - ] - MSR CPSR_c, R3 ; SEI - LDRB R1, CFStime - TEQ R1, R2 - MyOsbyte NE - - [ StorkPowerSave -; It is actually better to call Idle with interrupts disabled as it stops the interrupt -; going off on the way through the SWI dispatch and accidentally waiting for the next -; interrupt... The Idle will return when an interrupt is pending - it will be handled when -; we branch back up and enable interrupts. - MOV R0, #0 - LDRB R0, [R0, #PortableFlags] - TST R0, #PortableFeature_Idle - SWINE XPortable_Idle - ] - B %BT10 - -; ***************************************************************************** - -; Restore font definitions -Osbyte14 - MOV R1, #1 ; start at character 1*32 - MOV R2, #3 ; do 3 pages - B ResetPartFont - -; ***************************************************************************** - -; Flush Selected Buffer -Osbyte15 ROUT -; -; TMD 24-Apr-92: Don't check buffer number, as this prevents the flushing -; of buffer manager buffers. -; -; CMP R1, #NBuffers -; BCS %FT10 ; invalid buffer number - BL FlushThis -;10 - MyOsbyte - - -FlushThis - -; code inserted here to zero PrinterActive iff you are flushing the printer -; buffer and the print destination is not a stream one - - CMP R1, #Buff_RS423Out ; is it an input buffer ? (not mouse) - BCS %FT20 ; no, then branch - - MOV R0, #0 - STRB R0, SoftKeyLen ; kill soft key expansion - STRB R0, VDUqueueItems ; flush VDU queue -20 - SETV ; indicate purge not count - B CnpEntry - -; Reset Group of font definitions -Osbyte19 ROUT - CMP R1, #8 - MyOsbyte CS ; not in range 0..7, ignore - TEQ R1, #0 - - MOVEQ R1, #1 ; if 0 then start at 1*32, do 7 pages - MOVEQ R2, #7 - - MOVNE R2, #1 ; else start at n*32, do 1 page -ResetPartFont - -; first offer to International module - - Push "R1, R2, R4, R5" - MOV R4, R1, LSL #5 ; R4 = start character - ADD R5, R4, R2, LSL #5 ; R5 = end character+1 - SUB R5, R5, #1 ; R5 = end character - LDRB R3, Alphabet - MOV R2, #Inter_Define - BL OfferInternationalService - Pull "R1, R2, R4, R5" - MyOsbyte EQ ; if claimed, don't use hard font - - ByteToNosbod DoResetFont - MyOsbyte - -; ***************************************************************************** - -; Set country number -; in: R1 = country number - -DoOsbyteSetCountry ROUT - TEQ R1, #&7F ; if 127, just read country - LDREQB R1, Country - MyOsbyte EQ - - BL GetCountry - Push R4 - BL ConvertCNoToANo ; convert country no. to alphabet no. - Pull R4, NE - MOVNE R1, #0 ; if not claimed, return with X=0 - MyOsbyte NE - -; was claimed, so have country number in R1 and R3, alphabet no. in R4 - - LDRB R1, Country ; save old country - STRB R3, Country ; store new country - STRB R4, Alphabet ; and new alphabet - BL NewKeyboard ; R3=new keyboard, R4=alphabet for it - BL SetAlphabet - Pull R4 - MyOsbyte - -SetAlphabet - Push "R1,R5,R14" - MOV R2, #Inter_Define ; now redefine the chars - MOV R3, R4 - MOV R4, #32 - MOV R5, #255 - BL OfferInternationalService - Pull "R1,R5,PC" - -ConvertCNoToANo - MOV R3, R1 ; put country no. in R3 - MOV R2, #Inter_CNoToANo -OfferInternationalService - Push R14 - MOV R1, #Service_International - IssueService - TEQ R1, #0 ; set Z flag if claimed - Pull PC - -; Notify keyboard handler of new keyboard - -NewKeyboard - Push "R1,R4,R14" - STRB R3, Keyboard - STRB R4, KeyAlphabet - MOV R2, #Inter_Keyboard - BL OfferInternationalService - Pull "R1,R4,PC" - -; ***************************************************************************** - -; Set keyboard/alphabet for a particular country - -DoOsbyteSetAlphKey ROUT - TST R1, #&80 ; if set then setting keyboard - BNE %FT10 ; [setting keyboard] - -; setting alphabet - - TEQ R1, #&7F ; 127 => just read alphabet - LDREQB R1, Alphabet - MyOsbyte EQ - -; 20/8/87 added code to do setting of default alphabet - - BL GetCountry - Push R4 - BL ConvertCNoToANo ; try to convert R1 to alphabet number - MOVNE R4, R3 ; if failed, try without converting - BL SetAlphabet ; try to set this alphabet - Pull R4 - MOVNE R1, #0 ; if not claimed, return with X=0 - MyOsbyte NE - - LDRB R1, Alphabet - STRB R3, Alphabet - MyOsbyte - -; setting keyboard - -10 - AND R1, R1, #&7F - TEQ R1, #&7F ; 127 => just read keyboard - LDREQB R1, Keyboard - MyOsbyte EQ - - BL GetCountry - Push R4 - BL ConvertCNoToANo ; validating country no. - Pull R4, NE - MOVNE R1, #0 ; if not claimed, return with X=0 - MyOsbyte NE - - LDRB R1, Keyboard ; load old keyboard - BL NewKeyboard ; R3=new keyboard, R4=alphabet for it - Pull R4 - MyOsbyte - -; ***************************************************************************** - -; All osbytes from &1A to &69 are unused (apart from international ones!) - -; End of unused block - -; Write pointer shape number, mouse linkage -; -; R1 = 0 => pointer off -; R1 = 1..4 => use pointer shape 1..4, linked to mouse -; R1 = &81..&84 => use pointer shape 1..4, unlinked -; -Osbyte6A - VDWS R0 - LDRB R3, [R0, #PointerShapeNumber] ; get old shape number - AND R2, R1, #&7F ; allow 0..4, &80..&84 - CMP R2, #4 - BHI %FT90 ; ignore change if too high - - TEQ R1, R3 - BEQ %FT90 ; same as old - - STRB R1, [R0, #PointerShapeNumber] ; will take effect on next vsync (UpdatePointer) - -90 MOV R1, R3 - MyOsbyte - -; Set vdu driver's screen number -Osbyte70 - ByteToNosbod DoSetDriverBank - MyOsbyte - -; Set displayed screen number -Osbyte71 - ByteToNosbod DoSetDisplayBank - MyOsbyte - -; *SHADOW -Osbyte72 - MOV R0, #&EF ; redirect to shadow variable - MOV R2, #0 - B DoOsbyteVar - -; ***************************************************************************** - -; Read VDU Status -Osbyte75 - Push R2 - ByteToNosbod DoReadVDUStatus - Pull R2 - MyOsbyte - -; Reflect Keyboard Status In LEDs -Osbyte76 - MOV R11, #KeyWorkSpace - MOV R12, #IOC - BL UpdateLEDs - MyOsbyte - -; Write Keys Pressed Info -Osbyte78 - BL WriteKeysDown - MyOsbyte - -; Perform Keyboard Scan from 16 -Osbyte7A - MOV R1, #&10 -; and drop thru to ... - -; Perform Keyboard Scan -Osbyte79 - BL BBCScanKeys - MyOsbyte - -; Inform OS Printer Driver going Dormant -Osbyte7B - BL MakePrinterDormant - ByteReturnV - -; Clear Escape Condition -Osbyte7C - BL DoOsbyte7C - MyOsbyte - -; Set Escape Condition -Osbyte7D - BL DoOsbyte7D - MyOsbyte - -DoOsbyte7C - Push "R11, R14" - MOV R11, #0 - B Osbyte7C7D - -DoOsbyte7D - Push "R11, R14" - MOV R11, #&FF -Osbyte7C7D - MOV R12, #EscHan_ws - STRB R11, [R12, #ESC_Status-EscHan_ws] ; set escape flag - MOV R14, PC - LDMIA R12, {R12, PC} -Exit7D - TEQ R12, #1 - [ Version >= 201 - Pull "R11, PC", NE - - MRS R11, CPSR ; Preserve old processor state - ORR R12, R11, #SVC_mode ; Switch to SVC mode preserving IRQ_bit - MSR CPSR_c, R12 - Push R14 ; Preserve SVC_R14 - SWI XOS_SetCallBack - Pull R14 ; Restore SVC_R14 - MSR CPSR_c, R11 ; Switch back to original mode, with V_bit intact from SWI - - Pull "R11, PC" - | - STREQB R12, [R12, #IRQ_CallBack_Flag-1] - ] - Pull "R11, PC" - -; Acknowledge ESCAPE -Osbyte7E ROUT - MOV R3, #0 - LDRB R3, [R3, #ESC_Status] - TST R3, #&40 - BEQ NoESCToAck ; escape flag clear - - LDRB R0, ESCeffect - TEQ R0, #0 - BNE NoESCToAck ; escape effects disabled - - CLRPSR I_bit, R0 ; enable interrupts (doing SOUNDs and - ; closing files may take some time!) - - SWI XSound_QInit - BVS %FT99 ; no noises anyway! - LDR R0, =&01010008 ; channel 8, amplitude &101 - MOV R1, #&00010000 ; pitch 0, duration 1 -10 - SWI XSound_ControlPacked - BVS %FT99 ; (R0 would be corrupted) - SUB R0, R0, #1 ; decrement channel - TST R0, #&FF ; if channel <> 0 then loop - BNE %BT10 -99 - MOV R0, #0 - - STRB R0, PageModeLineCount ; zero line count - - LDRB R1, ExecFileH - CMP R1, #0 ; is EXEC file open (and V:=0) - STRNEB R0, ExecFileH ; if so, zero handle and close - ; (will enable IRQs for me) - SWINE XOS_Find ; (R0=0, R1=handle) - ByteReturnV VS ; if error then bomb out - - BL FlushAll - -NoESCToAck - BL DoOsbyte7C - ANDS R1, R3, #&40 ; set R1 to 0 if wasn't escape, - MOVNE R1, #&FF ; &FF if was - MyOsbyte - - -; Check for EOF -Osbyte7F - MOV R0, #OSArgs_EOFCheck - SWI XOS_Args ; result comes back in R2 - MOV R1, R2 - ByteReturnV - -; ***************************************************************************** - -; Read ADC or buffer status -Osbyte80 - AND R1, R1, #&FF ; no funny business - - TST R1, #&80 ; is it ADVAL(-n) - BEQ AdvalPositive ; no, then do adval(+ve) - EOR R1, R1, #&FF ; convert to buffer number - CLC ; (C:=0 and V:=0) - TEQ R1, #Buff_Mouse ; is it mouse (only input buf >= 2) ? - CMPNE R1, #Buff_RS423Out ; C=1 <=> output buffer, so count spaces - ; V=0, so will do count not purge - - ADR R14, MyOsbyte80 -CnpEntry - Push "R10,R12,R14" - MOV R10, #CNPV - B GoVec - -MyOsbyte80 - MyOsbyte - -AdvalPositive ROUT - TEQ R1, #7 - TEQNE R1, #8 - Unused NE - - Push R11 - - MOV R11, R1 ; save adval number - SWI XOS_Mouse - Pull R11, VS - ByteReturnV VS - - TEQ R11, #7 - MOVEQ R1, R0 ; R1 is required value - - MOV R2, R1, LSR #8 ; put lo in R1, hi in R2 - AND R1, R1, #&FF - AND R2, R2, #&FF - - Pull R11 - MyOsbyte - -; ***************************************************************************** - -; Perform INKEY operation -Osbyte81 ROUT - TST R2, #&80 ; is it negative inkey ? - BEQ %FT10 ; no, then not INKEY-256 - ANDS R1, R1, #&FF ; zero => INKEY(-256) - MOVEQ R1, #OSVersionID ; then X := OS version number - MOVEQ R2, #0 ; and Y := 0 - MyOsbyte EQ ; if was INKEY-256 then claim -10 - Push R14 ; save return address for if passing on - ADR R14, My81 - Push R14 ; stack 'claiming' return address - BL DoInkeyOp ; R14 = 'passing on' return address -NotMy81 ; DoInkeyOp passed it on - - Pull "R3,R14" ; Throw away 'claiming' return address - ; and restore real passing on return address - Unused ; else pass it on still - -My81 - Pull R14 ; throw away real passing on address - ByteReturnV - - -; ***************************************************************************** - -; Read Machine High Order Address -Osbyte82 - MOV R1, #&FF ; Pretend we're an I/O processor ! - MOV R2, #&FF - MyOsbyte - -; ***************************************************************************** - -; Read OSHWM -Osbyte83 - LDRB R2, OSHWM ; Read from silly variable - MOV R1, #0 ; lo-byte is 0 - MyOsbyte - -; ***************************************************************************** - -; Read Text Cursor Position (input cursor if split) -Osbyte86 - ByteToNosbod DoReadPOSVPOSI ; Results in R1, R2 (i.e. POS, VPOS) - MyOsbyte - -; ***************************************************************************** - -; Read Screen Mode and Character at text cursor position -Osbyte87 - [ {FALSE} - ; The user's PSR is no longer there. In fact, it never was (or hasn't been - ; for a long time), because the return address passed to the vector always - ; had the I bit set. - LDR R3, [R13, #StackOffset] ; get user's psr - ANDS R3, R3, #I_bit ; EQ => irqs were on - CLRPSR I_bit, R3, EQ ; so clear I_bit now - ] - ; However, the SPSR _should_ have the user's interrupt state. If he had - ; IRQs off, we will not have turned them back on, so neither we nor an - ; interrupt routine will have called a a SWI, so SPSR will still be the - ; SPSR from the original OS_Byte, with I set. - ; - ; If someone else is on ByteV, and passed it on, the rules say that they - ; mustn't have enabled interrupts either, in which case any corrupted SPSR - ; must still have I set. - ; - ; If the caller had interrupts enabled, an interrupt may have corrupted SPSR - ; the worst effect of this is that we may not enable interrupts. So... - MRS R3, SPSR - TST R3, #I32_bit ; EQ => IRQs were on - MSREQ CPSR_c, #SVC2632 ; so turn them on - ByteToNosbod DoOSBYTE87 ; Results in R1, R2 (i.e. char, mode) - MyOsbyte - -; ***************************************************************************** - -; Insert Character Into Buffer -Osbyte8A - BL INSERT - MyOsbyte - -; ***************************************************************************** - -; Write Filing System Options : *OPT -Osbyte8B - MOV R0, #FSControl_OPT - SWI XOS_FSControl - ByteReturnV - -; ***************************************************************************** - -; Issue Paged ROM Service Request -Osbyte8F - IssueService - MyOsbyte - -; ***************************************************************************** - -; Select vertical screen shift and interlace option :*TV -Osbyte90 - LDRB R0, TVVertical - STRB R1, TVVertical - MOV R1, R0 ; old vertical in R1 - - AND R0, R2, #1 - LDRB R2, TVInterlace ; old interlace in R2 - STRB R0, TVInterlace - - MyOsbyte - -; ***************************************************************************** - -; Get Character From Buffer -Osbyte91 - CLRV ; remove not examine -RemVEntry - ADR R14, MyOsbyte80 -REMOVE - Push "R10,R12,R14" - MOV R10, #REMV - B GoVec - -; ***************************************************************************** - -; Examine Buffer Status -Osbyte98 - SETV ; examine not remove - B RemVEntry - -; ***************************************************************************** - -; Insert Character Code Into buffer checking for ESCAPE -Osbyte99 - BL DoInsertESC - MyOsbyte - -; ***************************************************************************** - -; Update pseudo 6850 control register and soft copy - -Osbyte9C - MOV r0, #7 ; OS_SerialOp to modify 6850 control register - SWI XOS_SerialOp - MyOsbyte - -; ***************************************************************************** - -; 'Fast TUBE BPUT' - -Osbyte9D - MOV R0, R1 ; R0 := character - MOV R1, R2 ; R1 := handle - SWI XOS_BPut - ByteReturnV - -; ***************************************************************************** - -; Read VDU Variable (0..15 implemented) -OsbyteA0 - ByteToNosbod DoReadVDUVariable - MyOsbyte - -; ***************************************************************************** - -; Read CMOS RAM -OsbyteA1 ; R1 = address , R2 = result - CLRPSR I_bit, R0 ; this may take some time - MOV R0, R1 - BL Read ; Read CMOS ram at address <R0> - MOV R2, R0 ; Result in R0, return in R2 - MyOsbyte - -; Write CMOS RAM -OsbyteA2 - CLRPSR I_bit, R0 ; this may take some time - MOVS R0, R1 - [ ProtectStationID - MyOsbyte EQ - ] - [ STB :LAND: :DEF: ObsoleteNC1CMOS - ; Protect machine address CMOS (if not corrupt) - ASSERT EtherCheckCMOS = EtherAddrCMOS+6 - CMP r0, #EtherAddrCMOS - BLT %FT10 - CMP r0, #EtherCheckCMOS - BGT %FT10 - Push "r0,r1" - BL GetMachineAddressCMOS - Pull "r0,r1" - MyOsbyte EQ ; don't allow write if address is valid -10 - ] - MOV R1, R2 - BL Write - MOV R1, R0 ; R1 is supposed to be preserved - MyOsbyte - -; ***************************************************************************** - -; OsByte 163,... applications call -OsbyteA3 ROUT - TEQ R1, #242 - Unused NE ; not 242 - pass it on - BL %FT10 - MyOsbyte ; if come to here, has been claimed - -10 - Push R14 - ByteToNosbod DoOsbyte163_242 - Pull R14 ; if come to here, wasn't claimed - Unused - -; ***************************************************************************** - -; Read Output cursor Position -OsbyteA5 - ByteToNosbod DoReadPOSVPOSO ; Result in R1,R2 (Horiz,vert) - MyOsbyte - -; ***************************************************************************** -; -; All calls &A6 to &FF are implemented together. -; <NEW VALUE> = (<OLD VALUE> AND R2 ) EOR R1 -; The old value is returned in R1 and the next location is returned in R2 -; -; ***************************************************************************** - -DoOsbyteVar - SUB R0, R0, #MainVars ; Point to this block starting at &A6 - LDRB R3, [WsPtr, R0] ; Load the byte - AND R11, R3, R2 ; Mangle it as required by the law - EOR R11, R11, R1 ; ................................ - MOV R1, R3 ; Return old value in R1 - TEQ R0, #OsbyteKeyStatus - MainVars ; sorry - it's not pure any more. - BEQ DoOsbyteKeyStatus ; mea culpa. KJB. - STRB R11, [R0, WsPtr]! ; R0 +:= WsPtr - LDRB R2, [R0, #1] ; Return contents of next loc in R2 - MyOsbyte - -; Keyboard status (OS_Byte 202). -; on entry: R0 = OsbyteKeyStatus - MainVars -; R1 = old value -; R11 = new value -DoOsbyteKeyStatus ROUT - Push "R0-R3,R10" - MOV R10,#UpCallV ; (Can't use OS_UpCall - it enables IRQs and we're documented as not doing so) - MOV R3,R11 ; R3 = new value - MOV R2,R1 ; R2 = old value - MOV R1,#0 ; pre-change - MOV R0,#UpCall_KeyboardStatus - BL CallVector ; go on then, interfere (Corrupts R10 & WsPtr) - - LDR R0, [R13] ; get back original R0 - STRB R3, [R0, #OsbyteVars]! ; R0 +:= WsPtr - LDRB R14, [R0, #1] ; Return contents of next loc in R2 - STR R14, [R13, #8] ; by popping it on the stack - - TEQ R2, R3 ; don't bother with UpCall if it didn't change... - - MOVNE R10,#UpCallV - MOVNE R1,#1 ; post-change - MOVNE R0,#UpCall_KeyboardStatus - BLNE CallVector ; can't do anything about it now... - - Pull "R0-R3,R10" - MyOsbyte - - LTORG - -; All the unused OS_Byte calls - -; ADC stuff -Osbyte10 ROUT -Osbyte11 ROUT -; Incr/Decr Polling Int -Osbyte16 -Osbyte17 -; Unused -Osbyte18 -; Write 1MHz bus selection -Osbyte6B -; Write Usage of Shadow memory for normal access -Osbyte6C -; Make temporary filing system permanent -Osbyte6D -; &6E and &6F are reserved by 3rd parties -Osbyte6E -Osbyte6F -; &73 and &74 reserved for Electron -Osbyte73 -Osbyte74 -; Close SPOOL(ON) & EXEC files -Osbyte77 -; Read top of USER RAM -Osbyte84 -; Read top of user RAM for given mode -Osbyte85 -; *CODE -Osbyte88 -; *MOTOR -Osbyte89 -; *TAPE -Osbyte8C -; *ROM -Osbyte8D -; Enter Language ROM -Osbyte8E -; Access Mem.Map.IO &92..&97 -Osbyte92 -Osbyte93 -Osbyte94 -Osbyte95 -Osbyte96 -Osbyte97 -; Write to VidULA & COPY -Osbyte9A -Osbyte9B -; Old Style Speech -Osbyte9E -Osbyte9F -; Check Processor Type -OsbyteA4 - Unused - -; ***************************************************************************** -; -; GetCountry - Read country -; -; in: R1 = country number or alphabet number -; -; out: IF R1=0 THEN -; R1:=Configured Country -; IF R1=0 THEN -; R1:=LastKbId -; IF R1>=&20 THEN R1:=0 -; ENDIF -; ENDIF -; -; R0 undefined -; - -GetCountry ROUT - TEQ R1, #0 ; if not setting default, exit - MOVNE PC, R14 - - Push R14 - MOV R0, #CountryCMOS ; read configured country - BL Read - MOVS R1, R0 ; if not Country Default, exit - Pull PC, NE - - MOV R0, #KeyWorkSpace - LDRB R1, [R0, #:INDEX: LastKbId] ; read last valid keyboard id - CMP R1, #&20 ; if <&20 then use this - MOVCS R1, #0 ; else set to 0 - Pull PC - - END diff --git a/s/PMF/oseven b/s/PMF/oseven deleted file mode 100644 index 2d87b29b..00000000 --- a/s/PMF/oseven +++ /dev/null @@ -1,230 +0,0 @@ -; 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.oseven - -; ***************************************************************************** -; -; SWIPrintChar - Entry for SWI OS_PrintChar -; -; in: R0 = character - -SWIPrintChar ROUT - Push "R0-R9, R14" ; save registers - BYTEWS WsPtr - CLRV ; R14 on entry must have V=0 - BL SWIPrintCharEntry - STRVS R0, [R13, #0] ; if error then poke R0 to stack - Pull "R0-R9, R14" - B SLVK_TestV ; return appropriately - -; ***************************************************************************** -; -; MOSDoPrint - Print a character via VDU 1 -; -; in: R0 = character -; -; out: V=0 => printed OK -; V=1 => error, R0 -> error block -; - -MOSDoPrint ROUT - Push "R12,R14" - BYTEWS WsPtr - BL MOSDoPrintWS - Pull "R12,PC" - -MOSDoPrintWS ; entry point when R12-> BYTEWS - CLRV - LDRB R1, WrchDest - TST R1, #4 ; is 'printer disabled' bit set ? - MOVNE PC, R14 ; yes, then return with V clear -SWIPrintCharEntry - LDRB R1, PrinterDrivType ; get the stream type - B FudgePrinterInsert - -; ***************************************************************************** -; -; WRITE - Insert character into buffer -; Retries until successful or ESCAPE condition -; -; in: R0 = character -; R1 = buffer number -; - -WRITE ROUT - Push R14 -10 - BL INSRT - Pull PC, CC - -; insert code here to turn LEDs on - - MOV R2, #0 - LDRB R2, [R2, #ESC_Status] - MOVS R2, R2, LSL #(32-6) - Pull PC, CS ; escape - - MRS R14, CPSR - BIC R2, R14, #I32_bit - MSR CPSR_c, R2 ; CLI - [ StrongARM - NOP - NOP - NOP - NOP - NOP - ] - MSR CPSR_c, R14 ; restore I - B %BT10 - -; ***************************************************************************** -; -; FudgePrinterInsert - Write byte to printer stream -; -; in: R0 = character to send -; R1 = printer type (3..255) -; R12 -> BYTEWS -; R14 has V_bit clear -; -; out: V=0 => printed OK -; V=1 => error, R0 -> error block -; - -FudgePrinterInsert ROUT - Push R14 - - LDR R2, PrinterActive ; R1=handle for printer stream - TEQ R2, #0 - MOVNE R1, R2 ; already have handle, so can - BNE %FT10 ; corrupt R1 - - Push R0 ; save character - ADR R0, PrinterTypeString - ADR R2, PrinterTypeName -05 - LDRB R3, [R0], #1 ; copy string from ROM to RAM - TEQ R3, #0 - STRNEB R3, [R2], #1 - BNE %BT05 - - BL OutputDecimalR1ToR2 - - MOV R0, #0 ; terminate with 0 - STRB R0, [R2] - ADR R0, PrinterTypeName+1 ; pointer to variable name - MOV R1, R2 ; dummy expansion pointer - ; (saving ptr to end of string!) - MOV R2, #-1 ; don't accept chars - MOV R3, #0 ; no wildcarding - MOV R4, #VarType_Expanded - SWI XOS_ReadVarVal ; on exit, R2=0 => no such var - CMP R2, #0 - Pull "R0,PC", EQ ; so ignore this stream (V:=0) - - MOV R0, #">" ; now stick ">",13 on end - STRB R0, [R1], #1 - MOV R0, #13 - STRB R0, [R1] - - ADR R1, PrinterTypeName ; point to "<PrinterType$nnn>" - MOV R0, #(open_write + open_mustopen + open_nodir) - SWI XOS_Find - BLVS StopPrinting ; stop printing - Pull "R1, PC", VS ; exit V set, not corrupting R0 - - MOV R1, R0 ; will always be non-zero - Pull R0 ; restore character - - STR R1, PrinterActive ; store new handle -10 - SWI XOS_BPut ; R0 = byte to send - Pull PC, VC ; no error, so exit - - BL StopPrinting ; preserves R0,R1 - Push R0 ; save error pointer - MOV R0, #0 ; CLOSE reason code - STR R0, PrinterActive ; zero handle - SWI XOS_Find ; close channel - SETV - Pull "R0,PC" ; return V set - - -PrinterTypeString - = "<",PrinterPrefix,0 - ALIGN - -MakePrinterDormant - LDR R3, PrinterActive ; printer handle - CMP R3, #0 ; no active handle if 0 (also clears V if zero) - MOVEQ PC, R14 - Push "R0,R1,R14" - MOV R1, R3 ; R1 = handle - MOV R0, #0 ; close reason code - STR R0, PrinterActive ; zero handle - SWI XOS_Find - BLVS StopPrinting - Pull R0, VC ; if no error, preserve R0 - ADDVS R13, R13, #4 ; else junk R0 - Pull "R1,PC" - -; ***************************************************************************** -; -; StopPrinting - Clear bits 3 and 5 of FX3, bit 0 of VduStatus -; -; Preserves all registers (including status) -; - -StopPrinting ROUT - Push "R0,R1" ; don't corrupt the flags! - LDRB R0, WrchDest - BIC R0, R0, #(1:SHL:3) :OR: (1:SHL:5) - STRB R0, WrchDest - VDWS R1 - LDR R0, [R1, #VduStatus] - BIC R0, R0, #1 ; clear VDU 2 bit - STR R0, [R1, #VduStatus] - Pull "R0,R1" - MOV PC, R14 ; returning preserving flags - -; ***************************************************************************** -; -; OutputDecimalR1ToR2 - Output a decimal byte -; -; in: R1 = number to output -; R2 = buffer to accept chars -; -; out: R0, R3 corrupt - -OutputDecimalR1ToR2 ROUT - MOV R0, #100 ; do hundreds first -10 - MOV R3, #"0" -20 - SUBS R1, R1, R0 - ADDCS R3, R3, #1 - BCS %BT20 - ADD R1, R1, R0 - CMP R3, #"0" ; if digit non-zero - STRNEB R3, [R2], #1 ; then output - TEQ R0, #10 - MOVNE R0, #10 ; then do tens digit - BNE %BT10 - - ORR R1, R1, #"0" - STRB R1, [R2], #1 ; output units digit - MOV PC, R14 - - - END diff --git a/s/PMF/osinit b/s/PMF/osinit deleted file mode 100644 index bd52866b..00000000 --- a/s/PMF/osinit +++ /dev/null @@ -1,1409 +0,0 @@ -; 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 - - GBLL ErrorsInR0 -ErrorsInR0 SETL Module ; if FALSE, use XOS_GenerateError for - ; RAM version - ; if TRUE, return error ptr in R0 - - GBLL ProtectStationID ; if TRUE, disallow OSBYTE &A2,0,n -ProtectStationID SETL {TRUE}:LAND::LNOT:Embedded_UI - - [ STB - ; STB and NC machines probably want Num lock off. -KBStat_Default * KBStat_NoShiftLock :OR: KBStat_NoNumLock - | - ; Desktop machines probably want Num lock on. -KBStat_Default * KBStat_NoShiftLock - ] - -; ***************************************************************************** - -ExecuteInit ROUT - Push R14 - - ; Point to OsbyteVars - ; and initialise them - - BYTEWS WsPtr - - LDRB R1, LastBREAK ; 0 => soft, 1 => power-on, 2 => hard - CMP R1, #1 - ADRCC R2, SoftResetVars - ADREQ R2, PowerOnResetVars - ADRHI R2, HardResetVars - - LDRCCB R3, NoIgnore ; preserve NoIgnore over soft reset - MOVCS R3, #0 ; if hard or power-on reset, zero it - STRCS R3, TimerAlpha +0 ; and zero both copies of TIME - STRCS R3, TimerAlpha +4 - STRCS R3, TimerBeta +0 - STRCS R3, TimerBeta +4 - MOV R4, R1 ; preserve LastBREAK - - 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 ; put NoIgnore back - STRB R4, LastBREAK ; put LastBREAK back - -; Initialise buffer pointers - - MOV R0, #4*(NBuffers-1) ; index to pointer - MOV R1, #0 ; value to store -BuffPtrInitLoop - STR R1, [R0, #BuffInPtrs] - STR R1, [R0, #BuffOutPtrs] - SUBS R0, R0, #4 - BPL BuffPtrInitLoop - -; mark printer as dormant - - STR R1, PrinterActive ; (R1=0) - -; 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 - - [ HAL -; This has already been done much earlier in initialisation - | -; set up IOC timer 0 before we read from CMOS (cos it uses timer for delays) - - MOV R1, #IOC - LDR R0, =20000-1 ; R0 = Timer delay (units of 0.5 microsecond) - ; 20000*0.5E-6 = 0.01 Seconds 100Hz - ; TMD 21-May-93: "-1" correction applied - - STRB R0, [R1, #Timer0LL] ; Set up the delay - MOV R0, R0, LSR #8 - STRB R0, [R1, #Timer0LH] - STRB R0, [R1, #Timer0GO] ; and start the ticks - ] - - LDRB R0, LastBREAK - TEQ R0, #0 - BEQ %FT20 - - BL ReadMachineType - BL ReadUniqueID - BL ReadHardCMOSDefaults -20 - BL ReadCMOSDefaults - - [ :LNOT: HAL - [ StorkPowerSave - BL PowerHardware ;On Stork, ensure Combo chip, Winnie, Floppy etc are powered - ] - [ Keyboard_Type <> "RCMM" ; On RCMM machines, this is done in SetUpKbd. - [ STB - BL ConfigureCombo - | - BL Configure37C665 ;RiscPC, Kryten and Stork use only SMC 37C665 - ] - ] ; <> "RCMM" - ] - - [ HAL - Push "r9,r12" - AddressHAL - MOV R0, #0 - CallHAL HAL_TimerDevice - MOV R4, R0 - CallHAL HAL_VideoFlybackDevice - CMP R0, #-1 - MOVNE R5, R0 - CallHAL HAL_IRQClear, NE ; clear vsync IRQ - MOV R0, R4 - CallHAL HAL_IRQClear ; clear timer 0 IRQ - MOV R0, R5 - CallHAL HAL_IRQEnable ; enable vsync IRQ - MOV R0, R4 - CallHAL HAL_IRQEnable ; enable timer 0 IRQ - Pull "r9,r12" - | - MOV R1, #IOC - - MOV r0, #timer0_bit :OR: vsync_bit - STRB R0, [R1, #IOCIRQCLRA] ; clear pending tim0, vsync irqs (+ pack irq if appropriate) - LDRB R0, [R1, #IOCIRQMSKA] - ORR R0, R0, #timer0_bit :OR: vsync_bit - STRB R0, [R1, #IOCIRQMSKA] ; Enable timer 0 + vsync irqs - ] - - [ :LNOT: HAL - MOV R0, #0 - STRB R0, [R1, #IOMD_ATODICR] ; power down the A to D convertor - ] - -; Don't set time to value held in RTC if the RTC chip is not fitted -; system time will default to UNIX epoch + 1 day (so time() doesn't return -1) -secs0070 * (86400*(365*70+18)) ; from time() in risc_oslib.c.armsys - - MOV R1, #0 - LDRB R0, [R1, #RTCFitted] - TEQ R0, #0 ; when zero,no RTC - BNE %FT28 - LDR R7, =(secs0070 * 100) ; centiseconds LSW - MOV R8, #&33 ; centiseconds MSW - BL Store5ByteInRealTime - B %FT30 -28 - BL CheckYear ; check for year wrap scenario - BL RTCToRealTime - -; insert soft key 10 -30 - MOV R2, #&CA - BL RDCHS - Pull PC - - LTORG - -; ***************************************************************************** -; -; ReadHardCMOSDefaults - Read CMOS values for a hard/power-on reset -; NB must be called in supervisor mode - -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, =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 -; NB must be called in supervisor mode - -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 R0, R0, LSL #(32-5) ; bit 5 -> carry, bit 4 -> N bit - MOVPL R0, #KBStat_Default + KBStat_ShiftEnable ; SHCAPS - MOVMI R0, #KBStat_Default + KBStat_NoCapsLock ; NOCAPS - MOVCS R0, #KBStat_Default ; CAPS - STRB R0, KeyBdStatus - - [ ModeSelectors - BL Read_Configd_MonitorType - LDR r1, =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 - LDRB R0, LastBREAK ; get reset type - TEQ R0, #0 - BEQ %FT10 ; [soft reset, skip] - - [ StorkPowerSave - 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) - MOV R0, #0 - STRB R1, [R0, #PortableFlags] - | - MOV r0, #0 ; allow SWI Portable_Speed to be issued - STRB r0, [r0, #PortableFlag] - ] - - [ BleedinDaveBell - MOV R0, #1 ; indicate keyboard UK - MOV R1, #101 ; indicate alphabet Latin1 - | - MOV R0, #2 ; indicate keyboard Master - MOV R1, #100 ; indicate alphabet Bfont - ] - STRB R0, Keyboard - STRB R1, Alphabet - STRB R1, KeyAlphabet ; alphabet corresponding to keyboard - -10 - Pull R14 - B KeyPostInit - -; ***************************************************************************** -; -; SWI OS_ResyncTime -; -; in: r0 = 0 - Real time clock soft copy only -; r0 <> 0 reserved for future expansion -; -; out: r0 preserved -; -ResyncTimeSWI - Push "R12,LR" - BYTEWS WsPtr - BL CheckYear ;may have been frozen over new year! - BL RTCToRealTime - Pull "R12,LR" - ExitSWIHandler - -; ***************************************************************************** -; -; UpdateLatchB - update latch B and soft copy -; -; LATCHB := (LATCHB AND R1) EOR R0 -; - -UpdateLatchB - Push "R2, R3, R14" - PHPSEI ; disable IRQ - - MOV R2, #0 - LDRB R3, [R2, #LatchBSoftCopy] - AND R3, R3, R1 - EOR R3, R3, R0 - STRB R3, [R2, #LatchBSoftCopy] - - PLP - Pull "R2, R3, PC" - - [ :LNOT: STB :LAND: :LNOT: HAL -; ***************************************************************************** -; -; UpdateMonitorTypeLatch - update monitor type latch and soft copy -; -; Returns the result in R4 - -UpdateMonitorTypeLatch - Push "R2, R3, R14" - MRS R14, CPSR - ORR R2, R14, #I32_bit - MSR CPSR_c, R2 ; disable IRQ - - MOV R2, #0 - LDRB R3, [R2, #CLine_Softcopy] - MOV R3, #1 ;Set our bit only - STRB R3, [R2, #CLine_Softcopy] - - MOV R2, #IOMD_Base - STRB R3, [R2, #IOMD_CLINES] ;Write the new reg out - LDRB R3, [R2, #IOMD_CLINES] ;Read it back - - AND R4, R3, #1 ;Clear all but our bit into R4 - - MSR CPSR_cf, R14 ;Re-enable IRQ, restore flags - 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 - = 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 - = KBStat_Default ; 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 - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; -; ReadMachineType - Determine machine type and store it in IOSystemType -; - -ReadMachineType Entry "r0-r12" - [ HAL - MOV r2, #4_3330 ; Fudge 1 - VGA - ;MOV r2, #4_3111 ; Fudge 2 - no connection - will do LCD - MOV r1, #0 - STRB r2, [r1, #MonitorLeadType] - - MOV r2, #0 - STRB r2, [r1, #IOSystemType] - - EXIT - | - MOV r12, #IOMD_Base - LDRB r0, [r12, #IOMD_ID0] - LDRB r11, [r12, #IOMD_ID1] - ORR r0, r0, r11, LSL #8 - LDR r11, =IOMD_Original - TEQ r0, r11 - MOVEQ r11, #0 ; assume Medusa - MOVNE r11, #IOST_7500 ; else assume Morris - TEQ r11, #IOST_7500 ; and set EQ if Morris to do conditional stuff below -; -; On Kryten, Morris pin Event2 is tied low so bit Nevent2 is a ONE -; On Stork, Morris pin Event2 is tied high so bit Nevent2 is a ZERO -; On STB/NCD, Morris pin Event2 is tied high so bit Nevent2 is a ZERO, but we don't have a LCD -; controller or battery manager so we'll not set IOST_BATMAN -; - LDREQB r0, [r12, #IOMD_IRQSTD] ;EQ, Morris - [ BatManSupport - TSTEQ r0, #IOMD_Nevent2_bit - ORREQ r11, r11, #IOST_BATMAN ;EQ, Stork ie Morris & BATMAN - ] - ORR r0, r11, #IOST_IOEB ; pretend we've got IOEB -; -; r11 holds 0 for IOMD (Risc PC) -; or IOST_7500 for Morris (Kryten, Falcon, Omega) -; or IOST_7500 + IOST_BATMAN for Morris (Stork) - - MOV r1, #0 ; normal Hsync and address pointer - LDRB r3, [r1, #IOSystemType] - AND r3, r3, #IOST_COMBOMASK ; preserve combo type which may already - ORR r3, r3, r0 ; be in there on RCMM machines - STRB r3, [r1, #IOSystemType] - -; now read monitor lead type. - - TEQ r0, #0 ; no IOEB - MOVEQ r2, #&FF ; then return all ones for monitor lead type - BEQ %FT90 - - [ MPEGPoduleNTSCNotPALMask <> 0 - ! 1, "Sorry, I don't do MPEGPoduleNTSCNotPALMask any more" - ] - - [ STB - LDR r0, =VIDC ; on VIDC20 we invert HSYNC by writing to External Register - - [ IOMD_C_MonitorType <> 0 - ASSERT (IOMD_C_MonitorType = (1<<0)) ; this code only understands auto-detect in bit 0 - ] - TST R11, #IOST_7500 - LDREQ r3, =IOMD_MonitorType ; Not Morris, address is in old place - LDRNE r3, =(IOMD_Base + IOMD_CLINES) - - LDR r1, =VIDCExternal+Ext_InvertCompVSYNC+Ext_DACsOn+Ext_ERegExt ; normal HSYNC value - STR r1, [r0] - ORR r2, r1, #Ext_InvertHSYNC ; value for inverted HSYNC - - LDRB r4, [r3] ; base value - [ MorrisSupport - [ IOMD_C_PALNTSCType <> 0 - ASSERT (IOMD_C_PALNTSCType = (1<<4)) ; this code only understands PAL/NTSC auto-detect in bit 4 - AND r4, r4, #(IOMD_C_MonitorType :OR: IOMD_C_PALNTSCType) - ORR r4, r4, r4, LSR #1 ; Shift PAL/NTSC bit into bit 3 - AND r4, r4, #&0F ; only use bits 0..3 - | - AND r4, r4, #IOMD_C_MonitorType ; only one bit - ] - | - AND r4, r4, #&0F ; only use bits 0..3 - ] - MOV r5, #0 ; bits 0..3 = bits which have ever changed - ; bits 4..7 = bits whose deinverted value was high last time - ; bits 8..11 = bits whose deinverted value just went high-low - ; bits 12..15 = bits whose deinverted value just went high-low-low - ; bits 16..19 = bits which could be hsync - ; ie after every high-low there was low-low (after deinversion) - ; bits 20..23 = bits which are definitely random - MOV r10, #&0F ; used inside CheckBits - MOV r12, #256 ; number of iterations -20 - STR r2, [r0] - LDRB r6, [r3] ; read value with inverted sync - STR r1, [r0] - LDRB r7, [r3] ; read value with normal sync - - [ MorrisSupport - [ IOMD_C_PALNTSCType <> 0 - AND r6, r6, #(IOMD_C_MonitorType :OR: IOMD_C_PALNTSCType) - ORR r6, r6, r6, LSR #1 ; Shift PAL/NTSC bit into bit 3 - AND r6, r6, #&0F ; only use bits 0..3 - AND r7, r7, #(IOMD_C_MonitorType :OR: IOMD_C_PALNTSCType) - ORR r7, r7, r7, LSR #1 ; Shift PAL/NTSC bit into bit 3 - AND r7, r7, #&0F ; only use bits 0..3 - | - AND r6, r6, #IOMD_C_MonitorType ; only one bit - AND r7, r7, #IOMD_C_MonitorType - ] - | - AND r6, r6, #&0F ; only use bits 0..3 - AND r7, r7, #&0F - ] - EOR r8, r6, r4 ; bits which have changed from steady value to inverted one - ORR r5, r5, r8 ; OR into mask of bits which have ever changed - EOR r8, r7, r4 ; bits which have changed from steady value to normal one - ORR r5, r5, r8 ; OR into mask of bits which have ever changed - EOR r6, r6, #&0F ; deinvert inverted value - BL CheckBits ; call check routine with first value - MOV r6, r7 - BL CheckBits ; call check routine with second value - SUBS r12, r12, #1 - BNE %BT20 - | ; STB - - LDR r0, =VIDC ; on VIDC20 we invert HSYNC by writing to External Register - LDR r3, =IOMD_MonitorType - - LDR r1, =VIDCExternal+Ext_InvertCompVSYNC+Ext_DACsOn+Ext_ERegExt ; normal HSYNC value - STR r1, [r0] - ORR r2, r1, #Ext_InvertHSYNC ; value for inverted HSYNC - - [ MorrisSupport - TST R11, #IOST_7500 - BLNE UpdateMonitorTypeLatch ;Result back in R4 - LDREQB r4, [r3] - | - LDRB r4, [r3] ; base value - ] - AND r4, r4, #&0F ; only use bits 0..3 - MOV r5, #0 ; bits 0..3 = bits which have ever changed - ; bits 4..7 = bits whose deinverted value was high last time - ; bits 8..11 = bits whose deinverted value just went high-low - ; bits 12..15 = bits whose deinverted value just went high-low-low - ; bits 16..19 = bits which could be hsync - ; ie after every high-low there was low-low (after deinversion) - ; bits 20..23 = bits which are definitely random - MOV r10, #&0F ; used inside CheckBits - MOV r12, #256 ; number of iterations -20 - STR r2, [r0] - - [ MorrisSupport - TST R11, #IOST_7500 - BLNE UpdateMonitorTypeLatch ;Result back in R4 - MOVNE r6, r4 - LDREQB r6, [r3] - | - LDRB r6, [r3] ; read value with inverted sync - ] - - STR r1, [r0] - - [ MorrisSupport - TST R11, #IOST_7500 - BLNE UpdateMonitorTypeLatch ;Result back in R4 - MOVNE r7,r4 - LDREQB r7,[r3] - | - LDRB r7, [r3] ; read value with normal sync - ] - AND r6, r6, #&0F - AND r7, r7, #&0F - EOR r8, r6, r4 ; bits which have changed from steady value to inverted one - ORR r5, r5, r8 ; OR into mask of bits which have ever changed - EOR r8, r7, r4 ; bits which have changed from steady value to normal one - ORR r5, r5, r8 ; OR into mask of bits which have ever changed - EOR r6, r6, #&0F ; deinvert inverted value - BL CheckBits ; call check routine with first value - MOV r6, r7 - BL CheckBits ; call check routine with second value - SUBS r12, r12, #1 - BNE %BT20 - - - - ] ; STB - -; now process result - - LDR r1, =VIDCExternal+Ext_InvertCompVSYNC+Ext_InvertCompHSYNC+Ext_DACsOn+Ext_ERegExt ; put back default value - STR r1, [r0] - - BIC r4, r4, r5 ; don't put port value in for bits that have changed - BIC r5, r5, r5, LSR #16 ; make bits 0..3 of r5 indicate random bits - - ANDS r2, r4, #1 ; for each bit pair 00 => low, 01 => high, 10 => Hsync, 11 => random - TST r5, #1 :SHL: 16 - MOVNE r2, #2 :SHL: 0 - TST r5, #1 - MOVNE r2, #3 :SHL: 0 - - TST r4, #2 - ORRNE r2, r2, #1 :SHL: 2 - TST r5, #2 :SHL: 16 - ORRNE r2, r2, #2 :SHL: 2 - TST r5, #2 - ORRNE r2, r2, #3 :SHL: 2 - - TST r4, #4 - ORRNE r2, r2, #1 :SHL: 4 - TST r5, #4 :SHL: 16 - ORRNE r2, r2, #2 :SHL: 4 - TST r5, #4 - ORRNE r2, r2, #3 :SHL: 4 - - TST r4, #8 - ORRNE r2, r2, #1 :SHL: 6 - TST r5, #8 :SHL: 16 - ORRNE r2, r2, #2 :SHL: 6 - TST r5, #8 - ORRNE r2, r2, #3 :SHL: 6 - - [ {FALSE} - ASSERT IOMD_MonitorIDMask = 1 - AND r2, r2, #3 ; only bit 0 of ID valid on IOMD-based systems - ] - -90 - MOV r1, #0 - STRB r2, [r1, #MonitorLeadType] - EXIT - ] - -CheckBits ROUT - AND r8, r10, r5, LSR #12 ; bits that were H-L-L - BIC r8, r8, r6 ; bits that are H-L-L-L - ORR r5, r5, r8, LSL #16 ; OR into bits that could be hsync - ORR r8, r5, r5, LSR #4 - AND r8, r6, r8, LSR #8 ; bits that just went H-L-H or H-L-L-H - AND r8, r8, r5, LSR #16 ; bits that just went H-L-H or H-L-L-H and could have been hsync - ORR r5, r5, r8, LSL #20 ; they're definitely random now - BIC r5, r5, r8, LSL #16 ; and they're definitely not hsync now - AND r8, r5, #&FF :SHL: 4 ; get H bits, and H-L bits - BIC r8, r8, r6, LSL #4 ; knock out bits that were H and are now H - BIC r8, r8, r6, LSL #8 ; knock out bits that were H-L and are now H - BIC r5, r5, #&FF :SHL: 8 ; knock out all H-L and H-L-L bits - ORR r5, r5, r8, LSL #4 ; put in new H-L and H-L-L bits - BIC r5, r5, #&F :SHL: 4 ; knock out old H bits - ORR r5, r5, r6, LSL #4 ; put in new H bits - BIC r5, r5, r5, LSR #20 ; knock out H bits if we know it's random - MOV pc, lr - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; -; 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" - MOV r1, #Service_MonitorLeadTranslation - LDRB r2, [r1, #MonitorLeadType-Service_MonitorLeadTranslation] - 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 - 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 - [ STB - [ IOMD_C_MonitorType = 0 ; no auto-detect bit - [ IOMD_C_PALNTSCType = 0 ; no PAL/NTSC bits: - MonitorLeadItem 4_3333, 12, 0, 1 ; PAL TV assumed - | ; IOMD_C_PALNTSCType = 0 - MonitorLeadItem 4_0333, 12, 0, 1 ; PAL TV - MonitorLeadItem 4_1333, 46, 8, 1 ; NTSC TV - ] ; IOMD_C_PALNTSCType = 0 - | - [ :LNOT: ChrontelSupport - [ IOMD_C_PALNTSCType = 0 ; no PAL/NTSC bits: - MonitorLeadItem 4_3331, 12, 0, 1 ; PAL TV assumed - | ; IOMD_C_PALNTSCType = 0 ; wealth of bits: - MonitorLeadItem 4_0331, 12, 0, 1 ; PAL TV - MonitorLeadItem 4_1331, 46, 8, 1 ; NTSC TV - ] ; IOMD_C_PALNTSCType = 0 - ] ; :LNOT: ChrontelSupport - ] ; IOMD_C_MonitorType = 0 - MonitorLeadItem 4_3333, 28, 3, 0 ; VGA-capable monitors 256 colours - | ; STB - ; 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 - ]; STB - - - [ StorkPowerSave -; -; List of latch addresses and initial values. -; -PowerTab - DCD HWLatchPA, InitLatchPA - DCD HWLatchPB, InitLatchPB - DCD HWLatchMC, InitLatchMC - DCD HWLatchMA, InitLatchMA - DCD 0 - -PowerHardware ;On Stork, ensure Combo chip, Winnie, Floppy etc are powered - Entry "r0,r1" - - MOV r0, #0 - LDRB lr, [r0, #IOSystemType] - TST lr, #IOST_BATMAN - EXIT EQ ;EQ, not Stork, so hardware already powered -; -; On Stork. -; -; Now would be a good time to hit the power control latches -; to ensure everything is powered up. -; - ADR R14, PowerTab -05 - LDMIA R14!, {R0, R1} - TEQ R0, #0 - STRNEB R1, [R0] - BNE %BT05 - -10 - EXIT - ] - - [ STB -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; -; ConfigureCombo - Configure SMC 665/669 or UMC 8669 if present -; - -ComboBase * &03010000 ; Base address of combo chip = PC/AT I/O 000H - -; SMC-type stuff -SMC_CSR * &03F0 * 4 ; Configuration Select Register (CSR) -SMC_CSRalt669 * &0370 * 4 ; Alternative Configuration Select Register on SMC 669 - ; (this register is used if RTS2 is high on reset, which we don't have direct control of) -SMC_config * &55 ; value to write to enter configuration mode -SMC_endconfig * &AA ; value to write to end configuration mode -SMC_IDreg * &0D ; device ID register -SMC_data * &03F1 * 4 ; Configuration Access Port (data) -SMC_665 * &65 ; 665 ID -SMC_669 * &03 ; 669 ID - -; UMC-type stuff -UMC_CSR * &0108 * 4 ; Configuration Select Register (CSR) -UMC_config * &AA ; value to write to enter configuration mode -UMC_endconfig * &55 ; value to write to end configuration mode -UMC_data * &0109 * 4 ; Configuration Access Port (data) - - -; -; Configure SMC 37C665/669 or UMC8669 combo chip -; Note that older devices (eg 82C710, 82C711, SMC651) are no longer supported - ASSERT :LNOT: OldComboSupport - -ConfigureCombo Entry "r0-r2" - WritePSRc SVC_mode + I_bit + F_bit, R0 ; Disable FIQ and IRQ - LDR r0, =ComboBase ; R0-> Base address of combo chip - -; See if we have a SMC665/669 and try to configure it - ADD r2, r0, #SMC_CSR ; first try in normal place - - MOV lr, #SMC_config - STRB lr, [r2] ; Write &55 to CSR twice - STRB lr, [r2] ; to enter configuration mode - - MOV lr, #SMC_IDreg - STRB lr, [r2] - LDRB lr, [r2, #SMC_data-SMC_CSR] - TEQ lr, #SMC_665 ; 665 ? - ADREQ r1, ConfigSMC665Table - BEQ %FT20 - TEQ lr, #SMC_669 ; 669 ? - BEQ %FT18 - -; Not a SMC chip at the normal place, but the SMC 669 may move its configuration registers -; to &370 if RTS2 was high on trailing edge of reset, so try there - - ADD r2, r0, #SMC_CSRalt669 - - MOV lr, #SMC_config - STRB lr, [r2] ; Write &55 to CSR twice - STRB lr, [r2] ; to enter configuration mode - - MOV lr, #SMC_IDreg - STRB lr, [r2] - LDRB lr, [r2, #SMC_data-SMC_CSR] - TEQ lr, #SMC_669 ; 669 ? - BEQ %FT18 - -; Not a SMC chip that we recognise, maybe we have a UMC8669 - ADR r1, ConfigUMC8669Table -10 - LDRB lr, [r1], #1 ; get "Index Entry Valid" - STRB lr, [r0, #UMC_CSR] - TEQ lr, #UMC_endconfig ; end of table? - BEQ %FT12 - LDRB lr, [r1], #1 ; get config index - STRB lr, [r0, #UMC_CSR] - LDRB lr, [r1], #1 ; get config data - STRB lr, [r0, #UMC_data] ; and write it - BNE %BT10 - -12 -; UMC8669 is not self-identifying, so see if what we wrote is still there - MOV lr, #UMC_config - STRB lr, [r0, #UMC_CSR] ; Write &AA to enter config mode - MOV lr, #&C0 - STRB lr, [r0, #UMC_CSR] ; CR0 - LDRB r2, [r0, #UMC_data] - MOV lr, #UMC_endconfig ; maybe don't need to do this - STRB lr, [r0, #UMC_CSR] ; exit config mode - TEQ r2, #2_00111110 ; Value for CR0 from ConfigUMC8669Table - - MOVEQ r1, #IOST_UMC669 - MOVNE r1, #0 ; Don't know what this is, give up - B %FT30 - -; SMC config loop -18 - ADR r1, ConfigSMC669Table -20 - LDRB lr, [r1], #1 ; get config index - STRB lr, [r2] - TEQ lr, #SMC_endconfig ; end of table? - LDRNEB lr, [r1], #1 ; if not then get config data - STRNEB lr, [r2, #SMC_data-SMC_CSR] ; and write it - BNE %BT20 - - LDRB r1, [r1] ; pull chip ID out of table - -; Record type of chip found -30 - MOV r0, #0 - LDRB lr, [r0, #IOSystemType] - BIC lr, lr, #IOST_COMBOMASK - ORR lr, lr, r1 - STRB lr, [r0, #IOSystemType] - - WritePSRc SVC_mode + I_bit, lr ; Restore IRQ/FIQ state - EXIT - - -ConfigSMC665Table - [ ComboIRQsActiveHigh - DCB &01, 2_10010111 ; Enable config, COM3@338, COM4@238, IRQs active hi, - ; // is extended & powered @278 - | - DCB &01, 2_10000111 ; Enable config, COM3@338, COM4@238, IRQs active low, - ; // is extended & powered @278 - ] - DCB &02, 2_11011100 ; COM2 powered & enabled @2F8, COM1 powered & enabled @3F8 - ; (default) - DCB &03, 2_01111000 ; floppy stuff (default) - DCB &04, 2_00000011 ; EPP v1.9, MIDI disabled, normal //floppy, - ; // uses ECP & EPP modes - DCB &05, 0 ; 4 drive support, don't swap drives, normal density, - ; FDC burst mode, IDE@1F0-7,3F6-7, FDC@3F0-7 (default) -; DCB &06, &FF ; floppy drive types (default) -; DCB &07, 0 ; don't auto-powerdown anything (default) -; DCB &08, 0 ; ADRA7:4 address decode (default) -; DCB &09, 0 ; ADRA10:8 address decode (default) -; DCB &0A, 0 ; FIFO threshold for ECP // = ??? (default) -; DCB &0B, 0 ; floppy data rates (default) -; DCB &0C, 0 ; UART2 & UART1 standard speed, UART2 standard mode, - ; UART2 full duplex, XMIT active hi, RCV active hi (default) - DCB &00, 2_10111011 ; Valid config, OSC & BR on, FDC enabled & powered, - ; IDE AT & enabled - DCB SMC_endconfig ; Exit config mode - DCB IOST_37C665 ; Handy place to keep ID - -ConfigSMC669Table - DCB &01, 2_10010100 ; Enable config, // is extended, // is powered - DCB &02, 2_10001000 ; COM2 powered, COM1 powered (default) - DCB &03, 2_01110000 ; floppy stuff (bit 3 now reserved) - DCB &04, 2_00000011 ; IR rx&tx on COM2 rx & tx pins, EPP v1.9, MIDI disabled, - ; normal //floppy, uses ECP & EPP modes - DCB &05, 0 ; 4 drive support, don't swap drives, normal density, - ; FDC burst mode (default) -; DCB &06, &FF ; floppy drive types (default) -; DCB &07, 0 ; don't auto-powerdown anything -; DCB &08, 0 ; ADRA7:4 address decode (default) -; DCB &09, 0 ; ADRx disabled, ADRA10:8 address decode (default) -; DCB &0A, 0 ; FIFO threshold for ECP // = ??? (default) -; DCB &0B, 0 ; floppy data rates (default) -; DCB &0C, 0 ; UART2 & UART1 standard speed, UART2 standard mode, - ; UART2 full duplex, XMIT active hi, RCV active hi (default) - [ ComboClock14MHz -; DCB &10, 2_00000000 ; 14.318MHz input to PLL (default) - | - DCB &10, 2_01000000 ; 24MHz input to PLL - ] -; DCB &1E, &80 ; GAMECS disabled (default) -; DCB &1F, 0 ; floppy drive types (default) - DCB &20, &FC ; FDC@3F0-7 - DCB &21, &7C ; IDE@1F0-7 - DCB &22, &FD ; IDE Alternate Status Register @3F6 - DCB &23, &9E ; //@278 - DCB &24, &FE ; COM1@3F8 - DCB &25, &BE ; COM2@2F8 - DCB &26, 0 ; no FDC DMA, no // DMA (default) - DCB &27, 2_01100101 ; FDC uses IRQ_F, // uses IRQ_E - DCB &28, 2_01000011 ; UART1 uses IRQ_D, UART2 uses IRQ_C - DCB &29, 0 ; IRQIN does not use any IRQ_x (default) - DCB &00, 2_10001010 ; Valid config, FDC powered, IDE enabled - DCB SMC_endconfig ; Exit config mode - DCB IOST_37C669 - -ConfigUMC8669Table - DCB UMC_config, &C0, 2_00111110 ; IR full-duplex, games off, IDE on, - ; // in EPP & ECP mode, UART2 on, UART1 on, FDC off - DCB UMC_config, &C1, 2_00101111 ; Direct access PnP register, Disable PnP, - ; IDE@1F0-7,3F6-7, //@278, COM2@2F8, COM1@3F8, - ; FDC@3F0-7 - DCB UMC_config, &C2, 2_10000001 ; Not supspended, IR unselected/disabled, - ; don't swap floppy, IBM mode floppy, - ; floppy is R/W (default) - DCB UMC_endconfig, 0 ; Exit config mode - - ALIGN - | -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; -; Configure82C710 - Configure 82C710/82C711/SMC 665 if present -; - -; 82C710 stuff - -CnTbase * &03010000 ; Base address of 82C710 = PC/AT I/O 000H -CRI710 * &0390 -CRI710Off * CRI710*4 ; 82C710 Configuration Register Index port -CAP710Off * CRI710Off +4 ; 82C710 Configuration Access Port (data) -ConRegA710 * &02FA*4 -ConRegB710 * &03FA*4 - -CRI711Off * &03F0*4 ; 82C711 Configuration Register Index port -CAP711Off * CRI711Off +4 ; 82C711 Configuration Access Port (data) - - -ConfigSMCTable - DCB &01, 2_10000111 ; Enable config read, IRQ active low, parallel powered/extended, default addr. - DCB &02, 2_00011100 ; 2nd serial port disabled, 1st enabled at &3F8 - DCB &03, &78 ; extra stuff for SMC - DCB &04, 2_00000011 ; allow extended parallel port modes - DCB &05, 0 - DCB &06, &FF - DCB &07, 0 - DCB &08, 0 - DCB &09, 0 - DCB &0A, 0 - DCB &00, 2_10111011 ; Valid config, OSC/BR on, FDC enabled/powered, IDE AT,enabled - DCB &AA, 0 ; Exit config mode - - ALIGN - -; -; Simplified version of Configure82C710 programs SMC 37C665 only. -; -Configure37C665 Entry "r0,r1" - WritePSRc SVC_mode + I_bit + F_bit, r0 ; Disable FIQ and IRQ - LDR r0, =CnTbase ; R0-> SMC 665 base address - -; First try to configure the SMC665 - - MOV lr, #&55 - STRB lr, [r0, #CRI711Off] ; Write &55 to CRI711 twice - STRB lr, [r0, #CRI711Off] ; to enter configuration mode - - MOV lr, #&0D ; Check for SMC 665 - STRB lr, [r0, #CRI711Off] - LDRB lr, [r0, #CAP711Off] - TEQ lr, #&65 - MOVNE r1, #0 ;NE: not a SMC 665 this should never happen - BNE %FT30 ;NE: on a RiscPC, Kryten or Stork - - ADR r1, ConfigSMCTable ; R1-> SMC 665 configuration data -20 - LDRB lr, [r1], #1 ; get config index - STRB lr, [r0, #CRI711Off] - TEQ lr, #&AA ; end of table? - LDRNEB lr, [r1], #1 ; if not then get config data - STRNEB lr, [r0, #CAP711Off] ; and write it - BNE %BT20 - - MOV r1, #IOST_37C665 -30 - MOV r0, #0 - LDRB lr, [r0, #IOSystemType] - BIC lr, lr, #IOST_COMBOMASK - ORR lr, lr, r1 - STRB lr, [r0, #IOSystemType] - - WritePSRc SVC_mode + I_bit, lr ; Restore IRQ/FIQ state - EXIT - - ] - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; -; ReadUniqueID - Read unique machine ID -; - - [ HAL -ReadUniqueID - Entry "r0-r3,r9,r12" - AddressHAL - CallHAL HAL_MachineID - MOV r3, #0 - STR r0, [r3, #RawMachineID+0] - STR r1, [r3, #RawMachineID+4] ; now fall through and check the CRC below - | - -defaultlatch * 20000-1 ; TMD 21-May-93: "-1" correction applied -Tsyc * 5 ; time between frames - minimum of 1µs, so give it a bit more -Trstl * 500 ; time reset pulse held low - minimum of 480µs, so give it a bit more -Trsth * 500 ; time reset pulse held high - minimum of 480µs, so give it a bit more -Tlow0 * 80 ; time for write0 low - min 60µs, max 120µs -Tlow1 * 5 ; time for write1 low - min 1µs, max 15µs -Tslot * 90 ; time for total read/write slot - min 60µs, max 120µs -Trdlow * 5 ; time for read slot low before release - min 1µs, max 15µs -Trddat * 3 ; time after read slot high before read it - - ASSERT Tslot-Tlow0 > Tsyc - ASSERT Trdlow+Trddat < 15 - -; Macro to set wire to a given state, and optionally count transitions (starting at low) while waiting for a given time - - MACRO - SetWire $hilo, $time, $monstate, $count - LCLS reg - [ "$hilo"="LOW" -reg SETS "r4" - | - ASSERT "$hilo"="HIGH" -reg SETS "r5" - ] - [ ($time) = 0 - STRB $reg, [r1, #IOCControl] ; set appropriate level on line - | - ASSERT ($time) < 32768 - MOV r12, #(($time)*2):AND:&FF - STRB r12, [r1, #Timer0LL] ; program low latch - MOV r12, #(($time)*2):SHR:8 - STRB r12, [r1, #Timer0LH] ; program high latch - STRB $reg, [r1, #IOCControl] ; set appropriate level on line - STRB r12, [r1, #Timer0GO] ; and start timer - LDRB r12, [r1, #IOCIRQSTAA] ; dummy instruction to avoid bug in IOC - LDRB r12, [r1, #IOCIRQSTAA] ; dummy instruction (repeated for FE) - STRB r11, [r1, #IOCIRQCLRA] ; immediately clear IRQ bit - [ "$monstate"<>"" - MOV $monstate, #0 - ] - [ "$count"<>"" - MOV $count, #0 - ] -10 - LDRB r12, [r1, #IOCIRQSTAA] - TST r12, r11 - [ "$count"<>"" - ADDEQ $count, $count, #1 - ] - [ "$monstate"="" - BEQ %BT10 ; not timed out, so just loop - | - BNE %FT30 ; timed out - LDRB r12, [r1, #IOCControl] - TST r12, #IOEB_unique_machine_ID_bit - BEQ %BT10 ; if still low then loop to 10 - - ADD $monstate, $monstate, #1 ; increment number of transitions -20 - LDRB r12, [r1, #IOCIRQSTAA] - TST r12, r11 - [ "$count"<>"" - ADDEQ $count, $count, #1 - ] - BNE %FT30 ; timed out - LDRB r12, [r1, #IOCControl] - TST r12, #IOEB_unique_machine_ID_bit - BNE %BT20 ; if still high then loop to 20 - ADD $monstate, $monstate, #1 ; increment number of transitions - B %BT10 -30 - ] - ] - MEND - -RestoreIOCState Entry - STRB r3, [r1, #IOCControl] ; put back old value - MOV r12, #defaultlatch :AND: &FF - STRB r12, [r1, #Timer0LL] ; and restore old timer 0 latch values - MOV r12, #defaultlatch :SHR: 8 - STRB r12, [r1, #Timer0LH] - STRB r12, [r1, #Timer0GO] - WritePSRc SVC_mode + I_bit, lr ; restore old interrupt state - EXIT - -SendResetPulse ROUT - SetWire HIGH, Tsyc - SetWire LOW, Trstl,,r6 - SetWire HIGH, Trsth,r10 - TEQ r6, #0 - [ :DEF: DebugOneWireBus - ADREQ r0, IOCBugHappenedError - ] - BEQ %FT05 - CMP r10, #3 ; H-L-H is ok - MOVEQ pc, lr ; V clear - [ :DEF: DebugOneWireBus - ADRHI r0, TooManyTransitionsError ; H-L-H-L... - CMP r10, #2 - ADREQ r0, NeverWentHighAgainError ; H-L - CMP r10, #1 - ADREQ r0, NeverWentLowError ; H - ADRCC r0, NeverWentHighError ; stayed low permanently even though we released it - ] -05 - SETV - MOV pc, lr - - [ :DEF: DebugOneWireBus -NeverWentHighError - = "Never went high", 0 -NeverWentLowError - = "Never went low", 0 -NeverWentHighAgainError - = "Never went high again", 0 -TooManyTransitionsError - = "Too many transitions", 0 -IOCBugHappenedError - = "IOC bug happened", 0 - ALIGN - ] - -SendCommandWord ROUT - CLRV - LDR r6, =&10F ; &0F is command word -10 - MOVS r6, r6, LSR #1 - MOVEQ pc, lr - BCS SendOne - SetWire LOW, Tlow0 - SetWire HIGH, Tslot-Tlow0 - B %BT10 - -SendOne - SetWire LOW, Tlow1 - SetWire HIGH, Tslot-Tlow1 - B %BT10 - -GetAByte ROUT - MOV r6, #&80 -10 - SetWire LOW, Trdlow - SetWire HIGH, Trddat - LDRB r10, [r1, #IOCControl] - SetWire HIGH, Tslot-Trdlow-Trddat - MOVS r10, r10, LSR #IOEB_ID_bit_number+1 ; move bit into carry - MOVS r6, r6, RRX - BCC %BT10 - MOV r6, r6, LSR #24 - MOV pc, lr - -ReadUniqueID Entry "r0-r12" - MOV r0, #0 - LDR r1, =IOC - WritePSRc SVC_mode + I_bit + F_bit, r3 - LDRB r3, [r0, #IOCControlSoftCopy] - BIC r4, r3, #IOEB_unique_machine_ID_bit ; r4 is value to pull ID line low - ORR r5, r3, #IOEB_unique_machine_ID_bit ; r5 is value to pull ID line high - MOV r11, #timer0_bit - BL SendResetPulse - BVS ResetFailed - BL SendCommandWord - - MOV r7, #-8 ; -no. of bytes to store = 8 bits type + 48 bits ID + 8 bits checksum -10 - BL GetAByte - STRB r6, [r7, #RawMachineID+8] - ADDS r7, r7, #1 - BNE %BT10 - - BL RestoreIOCState - ] ; HAL - BL CheckCRC - BVS IDError - EXIT - - [ :LNOT: HAL -ResetFailed - BL RestoreIOCState - ] - -IDError - DebugTX "Machine ID duff,zero substituted" - MOV r0, #0 - STR r0, [r0, #RawMachineID+0] ; indicate no ID by putting zero here - STR r0, [r0, #RawMachineID+4] - EXIT - -CheckCRC ROUT - LDR r1, =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 diff --git a/s/PMF/osword b/s/PMF/osword deleted file mode 100644 index 92e513ed..00000000 --- a/s/PMF/osword +++ /dev/null @@ -1,776 +0,0 @@ -; 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.osword - -maxword * &16 ; highest known osword - -; ***************************************************************************** - - MACRO - WordReturnV $cond - - ASSERT "$cond"="" :LOR: "$cond"="VS" - - [ "$cond"="" - Pull "R0-R4,R11,WsPtr,link,PC", VC - ] - ADDVS R13, R13, #4 ; junk stacked R0 - Pull "R1-R4,R11,WsPtr,link,PC", VS - - MEND - -; Main OsWord entry point -; R0,R1,R2 are parameters - - -OsWord - Push "R0-R4, R11, R12, R14" - CMP R0, #(maxword+1) - BLCC OsWordGo ; Call the subsid entry pt. - LDMIA R13, {R2-R4} ; R2=A, R3=X, R4=Y - MOV R1, #Service_UKWord ; osword service reason - CLRPSR V_bit, R0 ; in case there's no service - IssueService - TEQ R1, #0 - STMEQIA R13, {R2-R4} ; if claimed, then update - ; returned R0-R2 - Pull "R0-R4, R11, R12, PC" ; pass V back from service - -GoMyOsword - CLRPSR V_bit, R4 - Pull "R0-R4, R11, R12, R14, PC" - -; ***************************************************************************** - -OsWordGo ROUT - BYTEWS WsPtr -10 ; Point to despatch table - ADD PC, PC, R0, LSL #2 ; add in the action*4 and go - & 0 - ASSERT DespatchWord-%BT10 = 8 - -; ***************************************************************************** - -DespatchWord - - BAL OsWord00 - BAL OsWord01 - BAL OsWord02 - BAL OsWord03 - BAL OsWord04 - BAL OsWord05 - BAL OsWord06 - BAL OsWord07 - - BAL OsWord08 - BAL OsWord09 - BAL OsWord0A - BAL OsWord0B - BAL OsWord0C - BAL OsWord0D - BAL OsWord0E - BAL OsWord0F - - BAL OsWord10 - BAL OsWord11 - BAL OsWord12 - BAL OsWord13 - BAL OsWord14 - BAL OsWord15 - BAL OsWord16 - -; ***************************************************************************** -; That's All Folks -; ***************************************************************************** - -; ***************************************************************************** -; The OsWord routines themselves -; ***************************************************************************** - -; Osword Zero : Input a line - -OsWord00 ROUT - LDRB R0, [R1, #0] ; lo-byte of address - LDRB R2, [R1, #1] ; hi-byte of address - ORR R0, R0, R2, LSL #8 ; R0 := address - LDRB R2, [R1, #3] ; lo limit - LDRB R3, [R1, #4] ; hi limit - LDRB R1, [R1, #2] ; length of buffer - MOV R4, #0 ; flags - SWI XOS_ReadLine32 - WordReturnV VS - - MOV R2, R1 ; put line length into R2 - Pull "R0,R1,R3" ; don't overwrite R2 - Pull "R3, R4, R11, R12, R14, PC" - -; ***************************************************************************** - -; Read/Write System Clock -; entered with IRQs off -; in: R0 = 1 => read clock -; R0 = 2 => write clock - -OsWord01 ROUT -OsWord02 ROUT - CMP R0, #2 ; C=1 <=> write clock - LDRB R0, TimerState - EORCS R0, R0, #&0F ; if writing, then write to other state - ; in case user resets in middle - TEQ R0, #5 ; 5 => alpha, 10 => beta (C preserved) - ADREQ R2, TimerAlpha - ADRNE R2, TimerBeta - Swap R1, R2, CS ; if writing then R2 is destination - MOV R3, #5 -10 - LDRB R4, [R2], #1 - STRB R4, [R1], #1 - SUBS R3, R3, #1 - BNE %BT10 - STRB R0, TimerState ; if writing, switch state - ; (if reading, write current state) - MyOsWord - -; ***************************************************************************** - -; Read/Write Interval Timer -; entered with IRQs off -; in: R0 = 3 => read interval timer -; R0 = 4 => write interval timer - -OsWord03 ROUT -OsWord04 ROUT - CMP R0, #4 ; C=1 => write timer - MOVCS R2, R1 ; if writing then R1 is source - ADRCS R1, IntervalTimer - ADRCC R2, IntervalTimer ; else R2 is source - MOV R0, #5 -10 - LDRB R3, [R2], #1 - STRB R3, [R1], #1 - SUBS R0, R0, #1 - BNE %BT10 - MyOsWord - -; ***************************************************************************** - -; Perform a SOUND command -OsWord07 ROUT - TST R1, #3 - BNE %FT05 - LDMIA R1, {R0,R1} - SWI XSound_ControlPacked - MyOsWord -05 - -; Block not word aligned, so push it on the stack - - SUB R13, R13, #8 ; create stack frame of 8 bytes - MOV R0, #7 -10 - LDRB R2, [R1, R0] ; copy block into stack frame - STRB R2, [R13, R0] - SUBS R0, R0, #1 - BCS %BT10 - - Pull "R0, R1" ; then pull stack frame into R0 and R1 - SWI XSound_ControlPacked - MyOsWord - -; ***************************************************************************** -; Read the logical colour of a Pixel ( BASIC'S POINT function) -; Uses SWI ReadPoint - -OsWord09 ROUT - Push R1 ; save pointer - - LDRB R2, [R1, #0] ; X lo-byte - LDRB R0, [R1, #1] ; X hi-byte - ORR R0, R2, R0, LSL #8 - - MOV R0, R0, LSL #16 ; sign extend X - MOV R0, R0, ASR #16 - - LDRB R2, [R1, #2] ; Y lo-byte - LDRB R1, [R1, #3] ; Y hi-byte - ORR R1, R2, R1, LSL #8 - - MOV R1, R1, LSL #16 ; sign extend Y - MOV R1, R1, ASR #16 - - SWI XOS_ReadPoint ; in: R0=X, R1=Y - ; out: R2=colour, R3=tint, R4=0/-1 (on/off) - Pull R1 - STRB R2, [R1, #4] - WordReturnV - -; ***************************************************************************** - -; Read a character definition - -OsWord0A ROUT - ByteToNosbod DoReadFont - MyOsWord - -; ***************************************************************************** - -; Read the palette setting (VDU19,L,P,R,G,B) - -OsWord0B ROUT - ByteToNosbod DoReadPalette - MyOsWord - -; ***************************************************************************** - -; Write the palette setting (see VDU19) - -OsWord0C ROUT - ByteToNosbod DoSetPalette - MyOsWord - -; ***************************************************************************** - -; Read the last two graphics cursor positions - -OsWord0D ROUT - ByteToNosbod DoOsWord13 - MyOsWord - -; ***************************************************************************** - -; Osword 14 (&0E) -- Read Real Time Clock -; Four (was six) different calls - -; Read CMOS clock -OsWord0E ROUT - Push "R5-R8, R14" ; R0-R4 saved by Osword - - MOV R4, R1 ; pointer to the Osword Block - - LDRB R0, [R4, #0] - CMP R0, #1 - BCC OsWord0EAlpha - BEQ OsWord0EBeta - CMP R0, #3 - BCC OsWord0EGamma - BEQ OsWord0EDelta - [ {FALSE} - CMP R0, #5 - BCC OsWord0EEpsilon - BEQ OsWord0EZeta ; this is getting ridiculous ! - ] - - Pull "R5-R8, PC" ; unknown option - -; ***************************************************************************** -; -; OsWord0EAlpha - Read time as a string in the form -; eg Wed,01 Jan 1986.12:34:56 -; -; in: R1 -> buffer for string -; - -OsWord0EAlpha ROUT - -; TMD 30-May-89: We want to enable IRQs here, but OS_ConvertDateAndTime -; loads bytes out of the block, and if IRQs are on it might end using an -; inconsistent value, so we must make a copy of the block on the stack -; and use that. The label OsWord0EDandT was used by a commented out routine -; in file 'RealTime' which will have to be rewritten if it needs to be -; included again. - - ADR R0, RealTime ; load snapshot of 5 bytes of real time - LDMIA R0, {R0, R2} ; while IRQs are still off - Push "R0, R2" ; save on stack - CLRPSR I_bit, R0 ; enable IRQs now -OSWord0EReturnString - MOV R0, R13 ; point to stacked copy -; KJB 07-Sep-98: No-one is guaranteeing anywhere the length of %w3 or %m3 - -; see PRM 1-402 and 1-415. So give an indefinite buffer length here (making -; overflow the caller's problem - this call is obsolete anyway). Problem -; first noted with territory Japan, for which %m3 is potentially 5 bytes long. - MOV R2, #&10000000 - ADR R3, TimeFormat - SWI XOS_ConvertDateAndTime - ADD R13, R13, #8 ; junk stack frame - MOVVC R0, #13 ; if no error - STRVCB R0, [R1] ; overwrite terminating 0 with CR - - Pull "R5-R8,R14" - WordReturnV - -TimeFormat - = "%w3,%dy %m3 %ce%yr.%24:%mi:%se", 0 - ALIGN - - -; ***************************************************************************** -; -; OsWord0EBeta - Read time in BCD format -; -; in: R4 -> parameter block -; -; out: [R4, #0] = year (00-99) -; [R4, #1] = month (01-12) -; [R4, #2] = day of month (01-31) -; [R4, #3] = day of week (01-07) Sun=01 -; [R4, #4] = hours (00-23) -; [R4, #5] = minutes (00-59) -; [R4, #6] = seconds (00-59) -; - -OsWord0EBeta ROUT - - ADR R0, RealTime ; load snapshot of 5 bytes of real time - LDMIA R0, {R0, R2} ; while IRQs are still off - Push "R0, R2" ; save on stack - CLRPSR I_bit, R0 ; this may take some time - - MOV R0,#-1 - MOV R1,SP - SUB SP,SP,#36 ; Space for ordinals. - MOV R2,SP - SWI XTerritory_ConvertTimeToOrdinals - ADDVS SP,SP,#36+(2*4) - BVS OSWord0Eerror - -; [R2] = CS. ; all values are for LOCAL time -; [R2+4] = Second -; [R2+8] = Minute -; [R2+12] = Hour (out of 24) -; [R2+16] = Day number in month. -; [R2+20] = Month number in year. -; [R2+24] = Year number. -; [R2+28] = Day of week. -; [R2+32] = Day of year - - LDR R0,[R2,#24] ; Get year - LDR R1,=1900 - SUB R0,R0,R1 -01 - CMP R0,#100 - SUBGT R0,R0,#100 - BGT %BT01 ; Get year MOD 100. - - STRB R0,[R4,#0] ; Store it. - LDR R0,[R2,#20] - STRB R0,[R4,#1] - LDR R0,[R2,#16] - STRB R0,[R4,#2] - LDR R0,[R2,#28] - STRB R0,[R4,#3] - LDR R0,[R2,#12] - STRB R0,[R4,#4] - LDR R0,[R2,#8] - STRB R0,[R4,#5] - LDR R0,[R2,#4] - STRB R0,[R4,#6] - - ADD SP,SP,#36+(2*4) ; junk stack frame and 5 byte time. - - -; now we have the time in hex in the parameter block -; so convert each item into BCD - - MOV R1, #6 ; seven bytes to convert - -10 - LDRB R0, [R4, R1] - BL HexToBCD - STRB R0, [R4, R1] - SUBS R1, R1, #1 - BPL %BT10 - - B OsWord0Eend - -; ***************************************************************************** -; -; OsWord0EGamma - Convert time in BCD format (at offsets 1..7) -; into string format at offsets (0..24) -; -; in: R4 -> BCD time -; - -OsWord0EGamma ROUT - -;build a block for Territory_ConvertOrdinalsToTime -; [R2] = CS. ; all values are for LOCAL time -; [R2+4] = Second -; [R2+8] = Minute -; [R2+12] = Hour (out of 24) -; [R2+16] = Day number in month. -; [R2+20] = Month number in year. -; [R2+24] = Year number. - - SUB SP,SP,#28 - MOV R2,SP - MOV R0,#0 - STR R0,[R2] - - LDRB R0,[R4,#7] ; Seconds - BL BCDToHex - STR R0,[R2,#4] - - LDRB R0,[R4,#6] ; Minutes - BL BCDToHex - STR R0,[R2,#8] - - LDRB R0,[R4,#5] ; Hours - BL BCDToHex - STR R0,[R2,#12] - - LDRB R0,[R4,#3] ; Day of month - BL BCDToHex - STR R0,[R2,#16] - - LDRB R0,[R4,#2] ; Month - BL BCDToHex - STR R0,[R2,#20] - - - LDRB R0,[R4,#1] ; Year - BL BCDToHex - LDR R1,=1900 - ADD R0,R0,R1 - STR R0,[R2,#24] - - MOV R0,#-1 - ADD R1,SP,#20 ; Put value on satck - SWI XTerritory_ConvertOrdinalsToTime - ADDVS SP,SP,#28 - BVS OSWord0Eerror - - ADD SP,SP,#20 - MOV R1,R4 - B OSWord0EReturnString ; Now we have 5 byte value on stack, - ; use same code as OSWord0EAlpha - -; ***************************************************************************** -; -; OsWord0EDelta - Read 5-byte RealTime -; -; in: R4 -> block -; -; out: [R4, #0..4] = RealTime -; - -OsWord0EDelta ROUT - LDR R1, RealTime +0 - STRB R1, [R4, #0] - MOV R1, R1, LSR #8 - STRB R1, [R4, #1] - MOV R1, R1, LSR #8 - STRB R1, [R4, #2] - MOV R1, R1, LSR #8 - STRB R1, [R4, #3] - LDRB R1, RealTime +4 - STRB R1, [R4, #4] - -; and drop thru to ... - -OsWord0Eend - Pull "R5-R8, R14" - MyOsWord - -OSWord0Eerror - Pull "R5-R8, R14" - WordReturnV - -; ***************************************************************************** -; -; GetDecimalPair - Get pair of decimal digits from [R4+R1+0..1] -; -; in: R1 is offset from R4 to find 1st digit -; -; out: if valid, R1=value of pair of digits, C=0 -; if invalid, R1=undefined, C=1 -; R10 is corrupted -; - -GetDecimalPair ROUT - LDRB R10, [R1, R4]! ; get hi-digit - SUB R10, R10, #"0" ; put in range 0..9 - CMP R10, #10 ; C=1 if bad digit - ADD R10, R10, R10, LSL #2 ; R10 = 5*hi - - LDRB R1, [R1, #1] ; get lo-digit - SUB R1, R1, #"0" ; put in range 0..9 - CMPCC R1, #10 ; C=1 if bad digit - ADD R1, R1, R10, LSL #1 ; R1 = lo + 2*(5*hi) - - MOV PC, R14 - -; ***************************************************************************** - -; Osword 15 (&0F) Write the Real Time Clock. -; Three different calls - -OsWord0F ROUT - CLRPSR I_bit, R0 ; this may take some time - - Push "R5-R10, R14" - MOV R4, R1 ; Copy the parameter block pointer - LDRB R0, [R1] - MOV R9, #0 - - TEQ R0, #5 ; write all of time (5-byte UTC) - BEQ OsWord0F_5byte - - TEQ R0, #8 ; write hours, minutes, seconds - MOVEQ R9, #1 - - TEQ R0, #15 ; write day, date, month, year - MOVEQ R9, #2 - - TEQ R0, #24 ; write all of time - MOVEQ R9, #3 - - TEQ R9, #0 - Pull "R5-R10, PC", EQ ; unknown call, pass it on - -; first set up data in registers as follows :- -; R0 = hours -; R1 = minutes -; R2 = days -; R3 = months -; (R4 -> block) -; R5 = year(lo) -; R6 = year(hi) -; R7 = seconds -; R8 = centiseconds - - TST R9, #2 - BEQ %FT01 - -; KJB 980908 - can't assume length of date, as %w3, %dy and %m3 may be any length. Unfortunately, -; the string may not be terminated. Best we can do is plop a terminator at the maximum length position, -; which will at least cope with territories with fixed-length strings. Territories with variable length -; strings may work anyway, as territory modules are quite good at ignoring trailing junk. I've -; fixed things I've spotted that didn't terminate, such as BASIC. - - SUB SP, SP, #48 - MOV R0, #-1 - MOV R2, SP ; R1 points to real memory - contents don't matter to us - SWI XTerritory_ReadCalendarInformation - ADDVS SP, SP, #48 - BVS Bad0F - -; need to work out maximum length of "%w3,%dy %m3 %ce%yr[.%24:%mi:%se]" - TST R9, #1 - MOVEQ R0, #7 ; length of ", %ce%yr" - MOVNE R0, #16 ; length of ", %ce%yr.%24:%mi:%se" - LDR R10, [R2, #24] - LDR R14, [R2, #28] - ADD R0, R0, R10 ; + max length of %w3 - LDR R10, [R2, #40] - ADD R0, R0, R14 ; + max length of %dy - ADD R0, R0, R10 ; + max length of %m3 - ADD SP, SP, #48 - -01 ADD r10, r0, #3+1 ; round up number of bytes in block to word boundary, including null terminator - BIC r10, r10, #3 - SUB sp, sp, r10 - - ADD r2, r1, #1 ; point at actual string - MOV r1, #0 -02 - LDRB r14, [r2, r1] ; copy string (not terminated) on stack - STRB r14, [sp, r1] - ADD r1, r1, #1 - TEQ r1, r0 ; have we copied all bytes of string? - BNE %BT02 ; loop if not - - MOV r14, #0 ; null terminator - STRB r14, [sp, r0] - - MOV r0,#-1 ; set things up for territory SWI - r0 = -1 for current territory - MOV r1, r9 ; r1 = reason code (1, 2 or 3) - MOV r2, sp ; r2 -> terminated string on stack - SUB sp, sp, #36 ; get space for result. - MOV r3, sp - - SWI XTerritory_ConvertTimeStringToOrdinals - ADDVS sp, sp, #36 ; if error then junk return block - ADDVS sp, sp, r10 ; and junk variable length string on stack - BVS Bad0F - - CMP r9, #2 ; if just writing the date, write it ! - BEQ %FT10 - BGT %FT05 ; if writing everything just get UTC time - -; We only have the time from the string, we now need the date -; because changing the time may change it. - - ADR r0, RealTime - LDMIA r0, {r0,r1} ; LDM is atomic wrt interrupts - - Push "r0,r1" ; put value on stack - MOV r0,#-1 ; use configured territory. - ADD r2, sp, #8 - LDMIA r2, {r3-r6} ; preserve time values from entry string - MOV r1, sp - SWI XTerritory_ConvertTimeToOrdinals ; get ordinals for current time - ADDVS sp, sp, #44 ; 36 From above + 8 for 5 byte time - ADDVS sp, sp, r10 ; and junk string as well - BVS Bad0F - ADD sp, sp, #8 ; dump 5 byte time on TOS - STMIA r2, {r3-r6} ; restore the time we read from the string. - -05 -; Now [SP] -> ordinals in local time, but we want time in UTC -; First convert the ordinals to 5 byte UTC time - - MOV r0, #-1 ; use configured territory. - MOV r2, sp ; r2 -> ordinals block - SUB sp, sp, #8 ; two more words to contain 5 byte time - MOV r1, sp - SWI XTerritory_ConvertOrdinalsToTime - ADDVS sp, sp, #44 ; 36 From above + 8 for 5 byte time. - ADDVS sp, sp, r10 ; and junk string as well - BVS Bad0F - -; Now we have a 5 byte UTC time, convert it to UTC ordinals - - MOV r1, sp ; our 5 byte time - ADD r2, sp, #8 ; place to put ordinals - SWI XTerritory_ConvertTimeToUTCOrdinals - ADDVS sp, sp, #44 ; 36 bytes ordinals + 8 for 5 byte time. - ADDVS sp, sp, r10 ; and junk string as well - BVS Bad0F - - ADD sp, sp, #8 ; discard 5 byte time - -10 -; Load the registers. (SP->Ordinals) - - LDR r8, [sp], #4 ; centiseconds - LDR r7, [sp], #4 ; seconds - LDR r1, [sp], #4 ; minutes - Pull "r0,r2,r3,r5" ; hours, day of month, month, year - ADD sp, sp, #8 ; junk day of week, day of year - ADD sp, sp, r10 ; and string on stack - MOV r4, #100 - DivRem r6, r5, r4, r14 ; r5 = Year (lo), r6 = Year (hi) - - BL SetTime ; also updates 5-byte RealTime - -Bad0F ; come here if setting invalid - Pull "R5-R10, R14" - MyOsWord - -OsWord0F_5byte - SUB SP, SP, #36 - ADD R1, R1, #1 ; process the user's 5-byte block - MOV R2, SP - SWI XTerritory_ConvertTimeToUTCOrdinals - ADDVS SP, SP, #36 - BVS Bad0F - MOV R10, #0 ; no string on stack - B %BT10 ; nip back in to the main handler - - - -; ***************************************************************************** -; -; CheckYear - Check for year wrap (year in RTC <> year "YearCMOS") -; and for leap year fudging -; - -CheckYear ROUT - Push "R0,R1,R2,R14" - MOV R0, #0 - LDRB R0, [R0, #RTCFitted] - TEQ R0, #RTCAddressPHI - MOVEQ R1, #5 - MOVNE R1, #6 ; year address (dependant on RTC) - SUB R13, R13, #4 - STRB R1, [R13] - MOV R1, R13 - ORR R0, R0, #1:SHL:29 - MOV R2, #1 - BL IIC_Op - ORR R0, R0, #1 - BL IIC_Op - AND R1, R0, #&FF - LDRB R0, [R13] - ADD R13, R13, #4 - - TEQ R1, #RTCAddressPHI+1 - MOVEQ R1, R0, LSR #6 - ANDNE R1, R0, #3 ; R1= year MOD 4 - MOV R0, #YearCMOS - BL Read - AND R2, R0, #3 - SUBS R2, R1, R2 ; same year ? - Pull "R0,R1,R2,PC", EQ ; [yes, so no bother] - ADDCC R2, R2, #4 ; if lower, then must be carry - ADD R2, R0, R2 ; new year value - CMP R2, #100 - BCC %FT10 ; no carry thru to next century - - SUB R2, R2, #100 - MOV R0, #YearCMOS +1 - BL Read - ADD R1, R0, #1 - TEQ R1, #100 - MOVEQ R1, #0 ; wrap century - MOV R0, #YearCMOS +1 - BL Write -10 - MOV R1, R2 - MOV R0, #YearCMOS - BL Write - - BL RTCToRealTime - Pull "R0,R1,R2,PC" - - -; ***************************************************************************** - -; Define hardware cursor size, shape and active point - -OsWord15 - ByteToNosbod DoPointerStuff - MyOsWord - -; ***************************************************************************** - -; Set start of screen address (for VDU drivers and display) -; [R1, #0] = bit mask (bit0 set => change drivers; bit1 set => change display) -; [R1, #1..4] = byte offset from start of screen memory - -OsWord16 - ByteToNosbod DoSetScreenStart - MyOsWord - -; ************************************************************************** - -; All the unused OS_Word calls - -; Read Byte of I/O proc memory -OsWord05 ROUT -; Write byte of I/O proc memory -OsWord06 ROUT -; Define an ENVELOPE -OsWord08 ROUT -; Allocated to the net -OsWord10 -OsWord11 -OsWord12 -OsWord13 -OsWord14 - Unused - - END diff --git a/s/PMF/oswrch b/s/PMF/oswrch deleted file mode 100644 index bfdc75f2..00000000 --- a/s/PMF/oswrch +++ /dev/null @@ -1,182 +0,0 @@ -; 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.oswrch - - GBLS WrchLimReg - -; ***************************************************************************** -; -; PMFWrch - Entry point for WriteC vector -; This routine used to be nice and structured before I -; optimised it for plain wrch ! -; -; in: R0 = character -; -; out: All registers preserved -; - - [ {FALSE} -WrchLimReg SETS "R9" ; would like to only push R0-R9, but - ; PMFWrchDirect is called by SWIs like - ; OS_WriteN etc, which need R10-R12 - -PMFWrchDirect - BYTEWS WsPtr ; if called direct, then set up R12 -PMFWrch ROUT - Push "R0-$WrchLimReg" ; if called thru vec, already set up - | -WrchLimReg SETS "R12" ; 0.046N, so need to save R0-R12 - -PMFWrchDirect -PMFWrch ROUT - Push "R0-$WrchLimReg" - BYTEWS WsPtr - ] - - LDRB R1, WrchDest - LDRB R2, SpoolFileH - ORRS R3, R1, R2 - BNE %FT10 - - [ AssemblingArthur - VDWS WsPtr - BL Vdu - | - BL WrchVdu ; call VDU - ] - BVS %FT45 - Pull "R0-$WrchLimReg,PC", CC - B %FT15 - -10 - TST R1, #&22 ; branch if wrch not to VDU - BNE %FT50 ; or wrch to extension vector - - [ AssemblingArthur - VDWS WsPtr - BL Vdu - | - BL WrchVdu ; call VDU - ] -15 - BVS %FT45 ; error from VDU - LDMFD R13, {R0} ; reload R0 with character - BYTEWS WsPtr ; reload workspace pointer - LDRB R1, WrchDest ; and wrch destinations - BCS PrintVdu ; VDU says "Print it" -20 - TST R1, #8 ; printer enabled, independent of - ; CTRL-B and CTRL-C ? - BNE PrintVdu ; yes, then branch -40 - TST R1, #1 ; output to RS423 ? - BNE RS423Vdu ; yes, then do it -42 - LDRB R2, SpoolFileH ; spool file open ? - CMP R2, #0 ; (set V=0 for if we drop thru) - BLNE SpoolVdu ; yes, then go -45 - [ AssemblingArthur :LOR: ErrorsInR0 - Pull "R0-$WrchLimReg, PC", VC - ADD R13, R13, #4 - Pull "R1-$WrchLimReg, PC" - | - Pull "R0-$WrchLimReg, PC" ; that's it (phew!) - ] - -; Come here when Wrch not to VDU or Wrch to VDUXV - -50 - TST R1, #&02 ; wrch not to VDU at all ? - BNE %BT20 ; then skip - ; else must be VDU sent thru VDUXV - MOV R10, #VDUXV - BL GoVec2 ; call vector - B %BT15 - -; ***************************************************************************** - -PrintVdu - TST R1, #&40 ; only print via VDU 1 ? - BNE %BT40 ; yes, then skip - - LDRB R2, PrinterIgnore ; is it ignore character ? - TEQ R0, R2 - LDREQB R2, NoIgnore ; and ignoring enabled ? - TSTEQ R2, #&80 - BEQ %BT40 ; yes, then don't print it - - BL MOSDoPrintWS ; else print it (R12 -> ByteWS) - BVS %BT45 ; error in printing - LDMFD R13, {R0} ; reload R0 with character - LDRB R1, WrchDest ; and reload wrchdest - B %BT40 - -RS423Vdu - Push "r0,r1" - LDRB r1, SerialOutHandle - TEQ r1, #0 - BNE %FT60 - MOV r0, #open_write - ADR r1, SerialOutFilename - SWI XOS_Find - BVS %FT70 ; if can't open serial output stream, report error - ; and don't put anything in buffer - STRB r0, SerialOutHandle - LDMFD sp, {r0} ; get char back -60 - PHPSEI - Push "r14" ; save IRQ indication - MOV r1, #Buff_RS423Out ; RS423 output buffer id - BL WRITE ; write to buffer (waiting) - Pull "r14" - PLP ; restore IRQ state from lr - Pull "r0,r1" - B %BT42 - -; we got an error from the open, so in order to report it, -; we'd better stop outputting to RS423 - -70 - ADD sp, sp, #4 ; junk stacked r0 - Pull "r1" - BIC r1, r1, #1 ; clear RS423 output bit - STRB r1, WrchDest ; write back to OS_Byte - B %BT45 ; report error - -SerialOutFilename - = "Serial#Buffer2:", 0 - ALIGN - -SpoolVdu ; entered with V=0 - TST R1, #&10 ; spooling enabled ? - MOVNE PC, R14 ; no, then return - - Push R14 ; cos we're doing a SWI in SVC mode - MOV R1, R2 ; put handle in R1 - SWI XOS_BPut ; put byte to file - Pull PC, VC ; if no error, return with V clear - ; (no need to reload R1, since SPOOL - ; is done last) -SpoolBadExit - Push R0 - MOV R0, #0 ; stop spooling FIRST - STRB R0, SpoolFileH - SWI XOS_Find ; and close file (R0=0, R1=handle) - Pull "R1, R14" - MOVVC R0, R1 ; if closed OK, then restore old error - RETURNVS ; still indicate error - - END diff --git a/s/PMF/realtime b/s/PMF/realtime deleted file mode 100644 index ec04f33a..00000000 --- a/s/PMF/realtime +++ /dev/null @@ -1,177 +0,0 @@ -; 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.realtime - -; ***************************************************************************** -; -; RTCToRealTime - Set RealTime from actual RTC -; -; in: R12 -> BYTEWS -; out: all registers preserved -; - - [ {FALSE} -Construct5Byte ROUT - Push R14 - B Construct5ByteEntry - ] - -RTCToRealTime ROUT - Push "R0-R9, R14" - BL ReadTime ; R0 := hours, R1 := minutes - ; R2 := days, R3 := months - ; R5 := year(lo), R6 := year(hi) - ; R7 := seconds, R8 := centiseconds - BL ConvertTo5Byte - BL Store5ByteInRealTime - Pull "R0-R9, PC" - -RegToRealTime ROUT - Push "R0-R9, R14" - BL ConvertTo5Byte - BL Store5ByteInRealTime - Pull "R0-R9, PC" - -ConvertTo5Byte ROUT - Push R14 - - MOV R4, R5 ; R4 := year MOD 100 - MOV R5, R6 ; R5 := year DIV 100 - MOV R6, R7 ; R6 := seconds - MOV R7, R8 ; R7 := centiseconds - -Construct5ByteEntry - MOV R9, #24 - SUB R2, R2, #1 ; decrement day (day=1 => nowt to add) - MLA R0, R9, R2, R0 ; R0 = hours + day*24 - MOV R9, #60 - MLA R1, R0, R9, R1 ; R1 = mins + hours*60 - MLA R6, R1, R9, R6 ; R6 = secs + mins*60 - MOV R9, #100 - MLA R7, R6, R9, R7 ; R7 = centisecs + secs*100 - - ADR R0, STMonths-4 ; Point to table (month = 1..12) - LDR R1, [R0, R3, LSL #2] ; get word of offset - ADD R7, R7, R1 ; add to total - -; if not had leap day in this year yet, then exclude this year from the -; leap day calculations - - CMP R3, #3 ; if month >= 3 - SBCS R0, R4, #0 ; then R0,R1 = R4,R5 - MOVCC R0, #99 ; else R0,R1 = R4,R5 -1 - SBC R1, R5, #0 - -; want (yl+100*yh) DIV 4 - (yl+100*yh) DIV 100 + (yl+100*yh) DIV 400 -; = (yl DIV 4)+ (25*yh) - yh + (yh DIV 4) -; = (yl >> 2) + 24*yh + (yh >> 2) - - MOV R0, R0, LSR #2 ; yl >> 2 - ADD R0, R0, R1, LSR #2 ; + yh >> 2 - ADD R0, R0, R1, LSL #4 ; + yh * 16 - ADD R0, R0, R1, LSL #3 ; + yh * 8 - -; now subtract off the number of leap days in first 1900 years = 460 - - SUBS R0, R0, #460 - BCC BadYear ; before 1900, so bad - CMP R0, #86 ; if more than 86 days, then it's - BCS BadYear ; after 2248, so bad - - LDR R9, =ticksperday ; multiply by ticksperday and add to - MLA R7, R9, R0, R7 ; total (no overflow possible as this - ; can never be more than 85+31 days) - -; now add on (year-1900)*ticksperyear - - SUBS R5, R5, #19 ; subtract off 1900 - BCC BadYear - MOV R9, #100 - MLA R4, R9, R5, R4 ; R4 = year-1900 - - LDR R0, =ticksperyear ; lo word of amount to add on - MOV R1, #0 ; hi word of amount to add on - MOV R8, #0 ; hi word of result -10 - MOVS R4, R4, LSR #1 - BCC %FT15 - - ADDS R7, R7, R0 ; if bit set then add on amount - ADCS R8, R8, R1 - BCS BadYear ; overflow => bad time value -15 - ADDS R0, R0, R0 ; shift up amount - ADCS R1, R1, R1 - TEQ R4, #0 ; if still bits to add in - BNE %BT10 ; then loop - - CMP R8, #&100 ; R8 must only be a byte - Pull PC, CC - -BadYear - MOV R7, #-1 - MOV R8, #-1 - Pull PC - - -Store5ByteInRealTime - Push R14 - PHPSEI ; disable IRQs for this bit - STR R7, RealTime +0 - STRB R8, RealTime +4 - - [ :LNOT: AssemblingArthur :LAND: :LNOT: Module -; for now, also put into normal time - - LDRB R0, TimerState - TEQ R0, #5 - - ADREQ R3, TimerAlpha +0 - ADRNE R3, TimerBeta +0 - - STR R7, [R3] - STRB R8, [R3, #4] - ] - PLP - - Pull PC - -; ***************************************************************************** - -tickspersecond * 100 -ticksperminute * tickspersecond * 60 -ticksperhour * ticksperminute * 60 -ticksperday * ticksperhour * 24 -ticksperyear * ticksperday * 365 ; &BBF81E00 - -STMonths - & &00000000 ; Jan - & &0FF6EA00 ; Feb - & &1E625200 ; Mar - & &2E593C00 ; Apr - & &3DCC5000 ; May - & &4DC33A00 ; Jun - & &5D364E00 ; Jul - & &6D2D3800 ; Aug - & &7D242200 ; Sep - & &8C973600 ; Oct - & &9C8E2000 ; Nov - & &AC013400 ; Dec - & &F0000000 ; terminator, must be less than this (+1) - - - LTORG - - END diff --git a/s/SWINaming b/s/SWINaming deleted file mode 100644 index c2671e12..00000000 --- a/s/SWINaming +++ /dev/null @@ -1,675 +0,0 @@ -; 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 => SWINaming - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - MACRO -$l AddSwiNameToDecodeTab $name -$l = "$name", 0 -SwisInSystemTable SETA SwisInSystemTable+1 - MEND - -;*********************************************************************** -; -; SWI OS_SWINumberToString -; -; in: R0 = SWI number -; R1 = buffer pointer -; R2 = buffer length -; -; out: Buffer holds SWI name, null-terminated -; - -SWINumberToString_Code ROUT - WritePSRc SVC_mode, r12 ; interrupts on! - MOV r12, lr ; keep here so subroutines can update flags - Push "r3, r9" - MOV r9, r0 ; r0 to pass back - MOV r3, r2 ; buffer limit - MOV r2, #0 ; characters so far - - TST r0, #Auto_Error_SWI_bit - MOVNE r10, #"X" - BLNE AddChar - BIC r0, r0, #Auto_Error_SWI_bit - CMP r0, #512 - BCS NotASystemSWI ; TMD 11-May-89: changed from GE - - ADR r11, OS_Prefix - BL AddString - MOV r10, #"_" - BL AddChar - - CMP r0, #256 - BCS Swi_Is_WriteI ; TMD 11-May-89: changed from GE - CMP r0, #MaxSwi - BCS SWINotInTable ; TMD 11-May-89: changed from GE - - ADR r11, System_Swi_Names - BL GetStringFromTable - -AddStringAndExit - BL AddString - -ExitSwiSwi - MOV r10, #0 - BL AddChar - - MOV r0, r9 ; error pointer or restoration - Pull "r3, r9" - MOV lr, r12 - ExitSWIHandler - - GBLA SwisInSystemTable -SwisInSystemTable SETA -1 - -OS_Prefix = "OS",0 - -System_Swi_Names - AddSwiNameToDecodeTab WriteC - AddSwiNameToDecodeTab WriteS - AddSwiNameToDecodeTab Write0 - AddSwiNameToDecodeTab NewLine - AddSwiNameToDecodeTab ReadC - AddSwiNameToDecodeTab CLI - AddSwiNameToDecodeTab Byte - AddSwiNameToDecodeTab Word - AddSwiNameToDecodeTab File - AddSwiNameToDecodeTab Args - AddSwiNameToDecodeTab BGet - AddSwiNameToDecodeTab BPut - AddSwiNameToDecodeTab GBPB - AddSwiNameToDecodeTab Find - AddSwiNameToDecodeTab ReadLine - AddSwiNameToDecodeTab Control - AddSwiNameToDecodeTab GetEnv - AddSwiNameToDecodeTab Exit - AddSwiNameToDecodeTab SetEnv - AddSwiNameToDecodeTab IntOn - AddSwiNameToDecodeTab IntOff - AddSwiNameToDecodeTab CallBack - AddSwiNameToDecodeTab EnterOS - AddSwiNameToDecodeTab BreakPt - AddSwiNameToDecodeTab BreakCtrl - AddSwiNameToDecodeTab UnusedSWI - AddSwiNameToDecodeTab UpdateMEMC - AddSwiNameToDecodeTab SetCallBack - AddSwiNameToDecodeTab Mouse - - AddSwiNameToDecodeTab Heap - AddSwiNameToDecodeTab Module - AddSwiNameToDecodeTab Claim - AddSwiNameToDecodeTab Release - AddSwiNameToDecodeTab ReadUnsigned - AddSwiNameToDecodeTab GenerateEvent - AddSwiNameToDecodeTab ReadVarVal - AddSwiNameToDecodeTab SetVarVal - AddSwiNameToDecodeTab GSInit - AddSwiNameToDecodeTab GSRead - AddSwiNameToDecodeTab GSTrans - AddSwiNameToDecodeTab BinaryToDecimal - AddSwiNameToDecodeTab FSControl - AddSwiNameToDecodeTab ChangeDynamicArea - AddSwiNameToDecodeTab GenerateError - AddSwiNameToDecodeTab ReadEscapeState - AddSwiNameToDecodeTab EvaluateExpression - AddSwiNameToDecodeTab SpriteOp - AddSwiNameToDecodeTab ReadPalette - AddSwiNameToDecodeTab ServiceCall - AddSwiNameToDecodeTab ReadVduVariables - AddSwiNameToDecodeTab ReadPoint - AddSwiNameToDecodeTab UpCall - AddSwiNameToDecodeTab CallAVector - AddSwiNameToDecodeTab ReadModeVariable - AddSwiNameToDecodeTab RemoveCursors - AddSwiNameToDecodeTab RestoreCursors - AddSwiNameToDecodeTab SWINumberToString - AddSwiNameToDecodeTab SWINumberFromString - AddSwiNameToDecodeTab ValidateAddress - AddSwiNameToDecodeTab CallAfter - AddSwiNameToDecodeTab CallEvery - AddSwiNameToDecodeTab RemoveTickerEvent - AddSwiNameToDecodeTab InstallKeyHandler - AddSwiNameToDecodeTab CheckModeValid - AddSwiNameToDecodeTab ChangeEnvironment - AddSwiNameToDecodeTab ClaimScreenMemory - AddSwiNameToDecodeTab ReadMonotonicTime - AddSwiNameToDecodeTab SubstituteArgs - AddSwiNameToDecodeTab PrettyPrint - AddSwiNameToDecodeTab Plot - AddSwiNameToDecodeTab WriteN - AddSwiNameToDecodeTab AddToVector - AddSwiNameToDecodeTab WriteEnv - AddSwiNameToDecodeTab ReadArgs - AddSwiNameToDecodeTab ReadRAMFsLimits - AddSwiNameToDecodeTab ClaimDeviceVector - AddSwiNameToDecodeTab ReleaseDeviceVector - AddSwiNameToDecodeTab DelinkApplication - AddSwiNameToDecodeTab RelinkApplication - AddSwiNameToDecodeTab HeapSort - AddSwiNameToDecodeTab ExitAndDie - AddSwiNameToDecodeTab ReadMemMapInfo - AddSwiNameToDecodeTab ReadMemMapEntries - AddSwiNameToDecodeTab SetMemMapEntries - AddSwiNameToDecodeTab AddCallBack - AddSwiNameToDecodeTab ReadDefaultHandler - AddSwiNameToDecodeTab SetECFOrigin - AddSwiNameToDecodeTab SerialOp - AddSwiNameToDecodeTab ReadSysInfo - AddSwiNameToDecodeTab Confirm - AddSwiNameToDecodeTab ChangedBox - AddSwiNameToDecodeTab CRC - AddSwiNameToDecodeTab ReadDynamicArea - AddSwiNameToDecodeTab PrintChar - AddSwiNameToDecodeTab ChangeRedirection - AddSwiNameToDecodeTab RemoveCallBack - AddSwiNameToDecodeTab FindMemMapEntries - AddSwiNameToDecodeTab SetColour - AddSwiNameToDecodeTab ClaimSWI ; These two are not actually - AddSwiNameToDecodeTab ReleaseSWI ; kernel SWIs. - AddSwiNameToDecodeTab Pointer - AddSwiNameToDecodeTab ScreenMode - AddSwiNameToDecodeTab DynamicArea - AddSwiNameToDecodeTab AbortTrap - AddSwiNameToDecodeTab Memory - AddSwiNameToDecodeTab ClaimProcessorVector - AddSwiNameToDecodeTab Reset - AddSwiNameToDecodeTab MMUControl - AddSwiNameToDecodeTab ResyncTime - AddSwiNameToDecodeTab PlatformFeatures - AddSwiNameToDecodeTab SynchroniseCodeAreas - AddSwiNameToDecodeTab CallASWI - AddSwiNameToDecodeTab AMBControl - AddSwiNameToDecodeTab CallASWIR12 - AddSwiNameToDecodeTab SpecialControl - AddSwiNameToDecodeTab EnterUSR32 - AddSwiNameToDecodeTab EnterUSR26 - AddSwiNameToDecodeTab VIDCDivider - AddSwiNameToDecodeTab NVMemory - AddSwiNameToDecodeTab ClaimOSSWI - AddSwiNameToDecodeTab TaskControl - AddSwiNameToDecodeTab DeviceDriver - AddSwiNameToDecodeTab Hardware - AddSwiNameToDecodeTab IICOp - AddSwiNameToDecodeTab LeaveOS - AddSwiNameToDecodeTab ReadLine32 - AddSwiNameToDecodeTab SubstituteArgs32 - AddSwiNameToDecodeTab HeapSort32 - = 0 - - [ SwisInSystemTable+1 <> MaxSwi - ! 1, :CHR:10:CC::CHR:13:CC::CHR:7:CC::CHR:7:CC:"Swi Disassembly table not consistent with despatch table":CC::CHR:10:CC::CHR:13 - ] - -convswitab = "OS",0 - -Conversion_Swi_Names - AddSwiNameToDecodeTab ConvertHex1 - AddSwiNameToDecodeTab ConvertHex2 - AddSwiNameToDecodeTab ConvertHex4 - AddSwiNameToDecodeTab ConvertHex6 - AddSwiNameToDecodeTab ConvertHex8 - AddSwiNameToDecodeTab ConvertCardinal1 - AddSwiNameToDecodeTab ConvertCardinal2 - AddSwiNameToDecodeTab ConvertCardinal3 - AddSwiNameToDecodeTab ConvertCardinal4 - AddSwiNameToDecodeTab ConvertInteger1 - AddSwiNameToDecodeTab ConvertInteger2 - AddSwiNameToDecodeTab ConvertInteger3 - AddSwiNameToDecodeTab ConvertInteger4 - AddSwiNameToDecodeTab ConvertBinary1 - AddSwiNameToDecodeTab ConvertBinary2 - AddSwiNameToDecodeTab ConvertBinary3 - AddSwiNameToDecodeTab ConvertBinary4 - AddSwiNameToDecodeTab ConvertSpacedCardinal1 - AddSwiNameToDecodeTab ConvertSpacedCardinal2 - AddSwiNameToDecodeTab ConvertSpacedCardinal3 - AddSwiNameToDecodeTab ConvertSpacedCardinal4 - AddSwiNameToDecodeTab ConvertSpacedInteger1 - AddSwiNameToDecodeTab ConvertSpacedInteger2 - AddSwiNameToDecodeTab ConvertSpacedInteger3 - AddSwiNameToDecodeTab ConvertSpacedInteger4 - AddSwiNameToDecodeTab ConvertFixedNetStation - AddSwiNameToDecodeTab ConvertNetStation - AddSwiNameToDecodeTab ConvertFixedFileSize - AddSwiNameToDecodeTab ConvertFileSize - AddSwiNameToDecodeTab ConvertHex16 - AddSwiNameToDecodeTab ConvertCardinal8 - AddSwiNameToDecodeTab ConvertInteger8 - AddSwiNameToDecodeTab ConvertBinary8 - AddSwiNameToDecodeTab ConvertSpacedCardinal8 - AddSwiNameToDecodeTab ConvertSpacedInteger8 - AddSwiNameToDecodeTab ConvertFixedFileSize64 - AddSwiNameToDecodeTab ConvertFileSize64 - = 0 - ALIGN - - -SWINotInTable - SUB r11, r0, #OS_ConvertHex1 - CMP r11, #OS_ConvertFileSize - OS_ConvertHex1 - BHI %FT10 - - MOV r0, r11 - addr r11, Conversion_Swi_Names - BL GetStringFromTable - B AddStringAndExit - -10 - ADR r11, %FT01 - CMP r0, #OS_ConvertStandardDateAndTime - ADREQ r11, %FT05 - CMP r0, #OS_ConvertDateAndTime - ADREQ r11, %FT06 - B AddStringAndExit -01 - = "Undefined", 0 - -othersysswitab - = "OS", 0 -05 - = "ConvertStandardDateAndTime", 0 -06 - = "ConvertDateAndTime", 0 - = 0 - -02 - = "User", 0 - -andfiddleaboutwithWriteI - = "OS", 0 - = "WriteI", 0 - = 0 -03 - = "WriteI+", 0 - - ALIGN - -NotASystemSWI - Push "r9, r12" - BIC r10, r0, #Module_SWIChunkSize-1 - ModSWIHashvalOffset r9, r10 - LDR r9, [r9, #ModuleSWI_HashTab] -lohc - CMP r9, #0 - BEQ giveemaboringname - LDR r12, [r9, #ModSWINode_Number] - CMP r10, r12 - LDRNE r9, [r9, #ModSWINode_Link] - BNE lohc - - LDR r12, [r9, #ModSWINode_MListNode] - LDR r9, [r12, #Module_code_pointer] - LDR r10, [r9, #Module_NameTable] - LDR r14, [r9, #-4] ; get module size - CMP r10, #1 ; must be non-zero - CMPCS r14, r10 ; and must be within code - BLS trymodule_SWIdecode_code - ADD r11, r10, r9 - Pull "r9, r12" - BL AddString - MOV r10, #"_" - BL AddChar - AND r0, r0, #Module_SWIChunkSize-1 - Push "r0" - BL GetStringFromTable - Pull "r0" - BVC AddStringAndExit - B AddNumericBit ; not in table - -trymodule_SWIdecode_code - LDR r10, [r9, #Module_NameCode] - TST r10, #12,2 ; test bottom 2 bits and clear carry - CMPEQ r10, #1 ; must be non-zero - CMPCS r14, r10 ; and must be within code - BLS usethemoduletitle - -; got r0 is SWI number, r1 buffer pointer, r2 is buffer offset to use -; r3 is buffer limit - CMP r2, r3 - BGE dont_confuse_the_poor_dears - Push "r4-r6" - AND r0, r0, #Module_SWIChunkSize - 1 - LDR r12, [r12, #Module_incarnation_list] - ADDS r12, r12, #Incarnation_Workspace ; force V clear - MOV lr, pc - ADD pc, r9, r10 - Pull "r4-r6, r9, r12" - BVC ExitSwiSwi - -dont_confuse_the_poor_dears - [ International - Push "r0" - ADRL r0, BufferOFloError - BL TranslateError - MOV r9,r0 - Pull "r0" - | - ADRL r9, BufferOFloError - ] - ORR r12, r12, #V_bit - B ExitSwiSwi - -usethemoduletitle - LDR r10, [r9, #Module_Title] - ADD r11, r10, r9 - Pull "r9, r12" - BL AddString - MOV r10, #"_" - BL AddChar - AND r0, r0, #Module_SWIChunkSize-1 - B AddNumericBit - -giveemaboringname ; not found anywhere interesting - Pull "r9, r12" - ADR r11, %BT02 - B AddStringAndExit - -Swi_Is_WriteI - ADR r11, %BT03 - BL AddString - - AND r0, r0, #255 - CMP r0, #32 - BLT AddNumericBit - CMP r0, #127 - BCS AddNumericBit - MOV r10, #"""" - BL AddChar - MOV r10, r0 - BL AddChar - MOV r10, #"""" - BL AddChar - B ExitSwiSwi - -AddNumericBit - Push "r1, r2" - ADD r1, r1, r2 ; point at remaining buffer - SUB r2, r3, r2 ; buffer left - SWI XOS_BinaryToDecimal - ORRVS r12, r12, #V_bit - MOVVS r9, r0 - MOV r0, r2 - Pull "r1, r2" - ADD r2, r2, r0 ; adjust chars given - B ExitSwiSwi - -; AddChar -; -; in: R1 = buffer pointer -; R2 = buffer position -; R3 = buffer size -; R10 = character -; -; out: If overflow, V_bit set in R12, and R9 -> error -; PSR preserved - -AddChar ROUT - EntryS - CMP r2, r3 - BGE %FT01 - STRB r10, [r1, r2] - ADD r2, r2, #1 - EXITS - -01 - [ International - Push "r0,lr" - ADRL r0, BufferOFloError - BL TranslateError - MOV r9,r0 - Pull "r0,lr" - | - ADRL r9, BufferOFloError - ] - EXITVS - -; AddString -; -; in: R11 points at string to add -; -; out: R10, R11 corrupted - -AddString Entry -01 - LDRB r10, [r11], #1 - CMP r10, #0 - BLNE AddChar - BNE %BT01 - EXIT - -; GetStringFromTable -; -; in: R0 is table offset -; R11 points at first SWI name in table -; -; out: R11 -> string or V set if not in table -; R0, R10 corrupted - -GetStringFromTable ROUT - LDRB r10, [r11] - CMP r10, #0 - BEQ %FT02 ; end of table - SUBS r0, r0, #1 - BPL %FT01 - CLRV - MOV pc, lr -01 - LDRB r10, [r11], #1 - CMP r10, #0 - BNE %BT01 - B GetStringFromTable -02 - SETV - MOV pc, lr - -;*********************************************************************** - -; R1 pointer to name terminated by char <= " " -; return R0 as SWI number - -SWINumberFromString_Code Entry "r1,r2" - - WritePSRc SVC_mode, r10 ; enable interrupts - LDRB R10, [R1] - CMP R10, #"X" - MOVEQ R0, #Auto_Error_SWI_bit - ADDEQ R1, R1, #1 - MOVNE R0, #0 - - MOV r10, #0 ; indicate doing OS SWIs, so disallow OS_<number> - ADRL r11, OS_Prefix ; point at system table - BL LookForSwiName - BVC GotTheSWIName - - BIC r0, r0, #255 - ADRL r11, othersysswitab - BL LookForSwiName - ORRVC r0, r0, #OS_ConvertStandardDateAndTime - BVC GotTheSWIName - - BIC r0, r0, #255 - ADRL r11, convswitab - BL LookForSwiName - ADDVC r0, r0, #OS_ConvertHex1 - BVC GotTheSWIName - - BIC r0, r0, #255 - ADRL r11, andfiddleaboutwithWriteI - BL LookForSwiName - ORRVC r0, r0, #OS_WriteI - BVC GotTheSWIName - - MOV r12, #Module_List -10 - LDR r12, [r12] - CMP r12, #0 - BEQ this_swi_nexiste_pas - LDR r10, [r12, #Module_code_pointer] - LDR r11, [r10, #Module_SWIChunk] ; first validate swi chunk - BICS r11, r11, #Auto_Error_SWI_bit - BEQ %BT10 ; SWI chunk zero not allowed - TST r11, #Module_SWIChunkSize-1 - TSTEQ r11, #&FF000000 - BNE %BT10 ; invalid SWI chunk - - LDR r2, [r10, #-4] - LDR r11, [r10, #Module_SWIEntry] - TST r11, #12,2 ; test bottom 2 bits and clear carry - CMPEQ r11, #1 ; must be non-zero - CMPCS r2, r11 ; and must be within code - BLS %BT10 - - LDR r11, [r10, #Module_NameTable] - CMP r11, #1 ; must be non-zero - CMPCS r2, r11 ; and must be within code - BLS %FT20 ; if no name table, try name code - - ADD r11, r10, r11 - BIC r0, r0, #Module_SWIChunkSize-1 - BL LookForSwiName - BVS %FT20 -gotmodulejobbie - LDR r11, [r10, #Module_SWIChunk] - BIC r11, r11, #Auto_Error_SWI_bit - ORR r0, r0, r11 - B GotTheSWIName - -; call module code if it exists - -20 - LDR r11, [r10, #Module_NameCode] - TST r11, #12,2 ; test bottom 2 bits and clear carry - CMPEQ r11, #1 ; must be non-zero - CMPCS r2, r11 ; and must be within code - BLS %FT30 ; try <module-title>_<numeric> - -; got R1 string pointer - - Push "r0-r6, r12" - MOV r0, #-1 ; indicate string being given - LDR r12, [r12, #Module_incarnation_list] - ADDS r12, r12, #Incarnation_Workspace ; force V clear - MOV lr, pc - ADD pc, r11, r10 - ADDS r2, r0, #0 ; NB clears V for SWI return - Pull "r0" - ADDPL r0, r0, r2 - Pull "r1-r6, r12" - BPL gotmodulejobbie - -; check against module title - -30 - LDR r11, [r10, #Module_Title] - ADD r11, r10, r11 - Push r10 - MOV r10, #1 ; indicate only check for prefix_numeric - BL LookForSwiName - Pull r10 - BVS %BT10 - B gotmodulejobbie - -this_swi_nexiste_pas - SETV -GotTheSWIName - PullEnv - ADRVS r0, ErrorBlock_NoSuchSWI2 - [ International - Push "lr",VS - BLVS TranslateError - Pull "lr",VS - ] - B SLVK_TestV - - MakeErrorBlock NoSuchSWI2 - - -LookForSwiName ROUT -; R11 points at name table -; R1 points at name -; R10 = 0 => allow only prefix_name (for OS_SWI) -; R10 = 1 => allow only prefix_numeric (for checking moduletitle_numeric) -; otherwise => allow prefix_name or prefix_numeric -; return R0 ORed with number if found -; V set if not - - Entry "r8,r9, r12" - MOV r12, #0 ; offset in name - -; first check that prefix matches -10 - LDRB r14, [r1, r12] - CMP r14, #" " ; if we terminate before we get an "_", then fail - BLE %FT50 - ADD r12, r12, #1 - LDRB r9, [r11], #1 - CMP r9, r14 - BEQ %BT10 - - CMP r14, #"_" ; check correct terminators - CMPEQ r9, #0 - BNE %FT50 - -; prefix OK: scan table for rest of name - - TEQ r10, #1 ; if doing modulename_numeric - BEQ CheckForNumericPostFix ; don't look for any names - MOV r8, r12 ; keep pointer to after prefix -20 - LDRB r14, [r11], #1 - CMP r14, #0 - BEQ CheckForNumericPostFix -30 - LDRB r9, [r1, r12] - ADD r12, r12, #1 - CMP r14, #0 - CMPEQ r9, #" " - BGT %FT35 - CLRV - EXIT - -35 - CMP r9, r14 - LDREQB r14, [r11], #1 - BEQ %BT30 - - MOV r12, r8 ; restore name pointer - ADD r0, r0, #1 ; step SWI number -40 - CMP r14, #0 ; find end of failed name - LDRNEB r14, [r11], #1 - BNE %BT40 - B %BT20 -50 - SETV - EXIT - -CheckForNumericPostFix -; [R1, R12] points at postfix - Push "r0-r2" - ADD r1, r1, r12 - CMP r10, #0 ; if OS SWI then EQ,VC else NE,VC - SETV EQ ; if OS SWI then VS else VC - MOVVC r0, #10 + (1 :SHL: 29) - MOVVC r2, #Module_SWIChunkSize -1 - SWIVC XOS_ReadUnsigned - Pull "r0" - BIC r0, r0, #Module_SWIChunkSize -1 - ADDVC r0, r0, r2 - Pull "r1, r2, r8,r9, r12, pc" - - END diff --git a/s/Super1 b/s/Super1 deleted file mode 100644 index ef68f7c8..00000000 --- a/s/Super1 +++ /dev/null @@ -1,101 +0,0 @@ -; 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 => Super1 - -CliDPrompt = "CLI$Prompt",0 -DefaultPrompt = "*" - ALIGN - -StartSuper ; Start entry for UtilModule - BL DEFHAN ; set error handler in case spooling - [ International ; We are in USR mode and have no stack ... - ADR R0,KernelMessagesBlock+4 - ADR R1,%FT11 - MOV R2,#0 - SWI XMessageTrans_Lookup - MOVVS R2,R1 -01 - LDRB R0,[R2],#1 - CMP R0,#31 - BLT %FT02 - SWI OS_WriteC - B %BT01 -02 SWI OS_NewLine - SWI OS_NewLine - B CLILOP -11 - = "Supervisor",0 - ALIGN - | - SWI OS_WriteS - = "Supervisor",10,13,10,13,0 - ALIGN - B CLILOP - ] - - -CLIEXIT BL DEFHN2 ; restore all our world - -GOSUPV - WritePSRc 0, R0 - BL DEFHAN ; including error handler! - -CLILOP ROUT - - ADR R0, CliDPrompt ; try looking it up - LDR R1, =GeneralMOSBuffer - MOV R2, #?GeneralMOSBuffer - MOV R3, #0 - MOV R4, #VarType_Expanded - SWI XOS_ReadVarVal - ADRVS r1, DefaultPrompt ; gnot gthere or gnaff - MOVVS r2, #1 - MOV r0, r1 - MOV r1, r2 - SWI OS_WriteN - LDR R0, =GeneralMOSBuffer - LDR R1, =?GeneralMOSBuffer-1 - MOV R2, #" " - MOV R3, #255 - MOV R4, #0 - SWI OS_ReadLine32 - BCS ESCAPE - MOV lr, pc ; construct lr for wallies to return to - SWI XOS_CLI - BVC CLILOP - - SWI XOS_NewLine - BL PrintError - B CLILOP - - LTORG - -ESCAPE MOV R0, #&7E - SWI OS_Byte ; May yield error - [ International - SWI XOS_EnterOS ; GO into SVC mode to get some stack - SWI OS_NewLine - BLVC WriteS_Translated - = "Escape:Escape",10,13,0 - ALIGN - WritePSRc 0, R0 ; Back to user mode. - | - SWI OS_WriteS - = 10,13, "Escape", 10,13, 0 - ALIGN - ] - B CLILOP - - END diff --git a/s/SysComms b/s/SysComms deleted file mode 100644 index 67cea435..00000000 --- a/s/SysComms +++ /dev/null @@ -1,1875 +0,0 @@ -; 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 => SysComms , the system commands file: Load save dump etc. - -TAB * 9 -FSUTtemp RN r10 - - GBLS UtilRegs ; Save the same set so we can common up exits -UtilRegs SETS "r7-r10" ; Sam will preserve r0-r6 on module star entry - -AnyNoParms * &FF0000 ; Between 0 and 255 parameters: all flags clear - - -SysCommsModule ROUT - -Module_BaseAddr SETA SysCommsModule - - & 0 ; No Start entry - & 0 ; Not initialised - & 0 - & 0 - & 0 - & SysTitle-SysCommsModule - & SCHCTab-SysCommsModule - & 0 - & 0 - & 0 - & 0 - [ International_Help <> 0 - & MessageFileName-SysCommsModule - | - & 0 - ] - -SysTitle - = "$SystemName", 9 - [ :LEN: "$SystemName" < 8 - = 9 - ] - = "$VersionNo", 0 - - [ Oscli_HashedCommands -; -;***WARNING*** if commands are added or changed, SysCoHashedCmdTab MUST be updated correspondingly -; - ] -SCHCTab ; Alphabetically ordered so it's easier to find stuff - - Command Append, 1, 1, International_Help - Command Build, 1, 1, International_Help - Command Close, 0, 0, International_Help - Command Create, 4, 1, International_Help - Command Delete, 1, 1, International_Help - Command Dump, 3, 1, International_Help - Command Exec, 1, 0, International_Help - Command FX, 5, 1, International_Help ; 1-3 parms, but up to 2 commas may be there - Command GO, 255, 0, International_Help -HelpText - Command Help, 255, 0, International_Help - Command Key, 255, 1, International_Help - Command Load, 2, 1, International_Help ; Fudge order for compatibility (*L.) - Command List, 3, 1, International_Help - Command Opt, 2, 0, International_Help - Command Print, 1, 1, International_Help - Command Quit, 0, 0, International_Help - Command Remove, 1, 1, International_Help - Command Save, 6, 2, International_Help ; *SAVE Fn St + Le Ex Lo (compatibility) - Command Shadow, 1, 0, International_Help - Command Spool, 1, 0, International_Help - Command SpoolOn, 1, 0, International_Help - Command TV, 3, 0, International_Help - Command Type, 3, 1, International_Help ; -file fred -tabexpand - = 0 - - [ Oscli_HashedCommands -; -; - Hashing table is 32 wide -; - Hashing function is: -; -; hash = (sum of all chars of command, each upper-cased) & 0x1f -; -; - Order of commands in each hashed list is alphabetical - -; Table MUST be reorganised if hashing function changed, or command set altered -; - ALIGN -SysCoHashedCmdTab -; -; ! 0,"SysCoHashedCmdTab at ":CC::STR:(SysCoHashedCmdTab) -; -;First, 1 word per table entry, giving offset to hashed list on each hash value -; - DCD SHC_hash00 - SysCommsModule - DCD 0 ;null list on this hash value - DCD SHC_hash02 - SysCommsModule - DCD SHC_hash03 - SysCommsModule - DCD 0 - DCD SHC_hash05 - SysCommsModule - DCD SHC_hash06 - SysCommsModule - DCD 0 - DCD 0 - DCD SHC_hash09 - SysCommsModule - DCD SHC_hash0A - SysCommsModule - DCD 0 - DCD 0 - DCD SHC_hash0D - SysCommsModule - DCD SHC_hash0E - SysCommsModule - DCD SHC_hash0F - SysCommsModule - DCD SHC_hash10 - SysCommsModule - DCD 0 - DCD 0 - DCD SHC_hash13 - SysCommsModule - DCD SHC_hash14 - SysCommsModule - DCD 0 - DCD SHC_hash16 - SysCommsModule - DCD 0 - DCD SHC_hash18 - SysCommsModule - DCD 0 - DCD 0 - DCD 0 - DCD SHC_hash1C - SysCommsModule - DCD 0 - DCD SHC_hash1E - SysCommsModule - DCD 0 -; -; Now the hashed lists -; -SHC_hash00 - Command Load, 2, 1, International_Help ; Fudge order for compatibility (*L.) - = 0 - ALIGN -SHC_hash02 - Command Type, 3, 1, International_Help ; -file fred -tabexpand - = 0 - ALIGN -SHC_hash03 - Command Quit, 0, 0, International_Help - = 0 - ALIGN -SHC_hash05 - Command Exec, 1, 0, International_Help - = 0 - ALIGN -SHC_hash06 - Command Shadow, 1, 0, International_Help - = 0 - ALIGN -SHC_hash09 - Command Help, 255, 0, International_Help - Command Key, 255, 1, International_Help - = 0 - ALIGN -SHC_hash0A - Command SpoolOn, 1, 0, International_Help - Command TV, 3, 0, International_Help - = 0 - ALIGN -SHC_hash0D - Command Print, 1, 1, International_Help - Command Spool, 1, 0, International_Help - = 0 - ALIGN -SHC_hash0E - Command Remove, 1, 1, International_Help - = 0 - ALIGN -SHC_hash0F - Command Save, 6, 2, International_Help ; *SAVE Fn St + Le Ex Lo (compatibility) - = 0 - ALIGN -SHC_hash10 - Command Build, 1, 1, International_Help - = 0 - ALIGN -SHC_hash13 - Command Delete, 1, 1, International_Help - Command Opt, 2, 0, International_Help - = 0 - ALIGN -SHC_hash14 - Command Create, 4, 1, International_Help - = 0 - ALIGN -SHC_hash16 - Command Close, 0, 0, International_Help - Command Dump, 3, 1, International_Help - Command GO, 255, 0, International_Help - = 0 - ALIGN -SHC_hash18 - Command Append, 1, 1, International_Help - = 0 - ALIGN -SHC_hash1C - Command List, 3, 1, International_Help - = 0 - ALIGN -SHC_hash1E - Command FX, 5, 1, International_Help ; 1-3 parms, but up to 2 commas may be there - = 0 - ALIGN - -;now a small table to fudge around need for old syntax for *fx etc (ie. -;allow zero spaces between command and first, numeric, parameter) -; -SHC_fudgeulike - Command FX, 5, 1, International_Help ; 1-3 parms, but up to 2 commas may be there - Command Key, 255, 1, International_Help - Command Opt, 2, 0, International_Help - Command TV, 3, 0, International_Help - = 0 - ALIGN - - ] ;Oscli_HashedCommands - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; Most help and syntax messages go together to save ALIGNing wastage - - GET s.MosDict - GET s.TMOSHelp - -GO_Syntax * Module_BaseAddr -Help_Syntax * Module_BaseAddr - - ALIGN ; Just the one, please ! - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -HelpBufferSize * 512 - -Help_Code ROUT ; got R0 ptr to commtail, R1 no parameters - Push "r7, lr" - -; first pass round a service call to let wally user code do things. - MOV r2, r1 - MOV r1, #Service_Help - BL Issue_Service - CMP r1, #0 - Pull "r7, pc", EQ - - CMP r2, #0 - MOVNE r6, r0 - addr r6, HelpText, EQ - - MOV r0, #117 ; Read current VDU status - SWI XOS_Byte ; Won't fail - SWI XOS_WriteI+14 ; paged mode on. - Pull "r7, pc", VS ; Wrch can fail - - Push "r1" ; Save page mode state - MOV r0, r6 - MOV r7, #0 ; anyhelpdoneyet flag - -DoHelpOnNextKeyWord -; now look at syscomms module. - addr r1, SysCommsModule - BL ShowHelpInModule - BVS %FT67 - -; now try looking round the modules. - MOV R2, #Module_List -11 LDR R2, [R2] - CMP R2, #0 - BEQ tryagainstmodulename - LDR R1, [R2, #Module_code_pointer] - LDR R12, [R2, #Module_incarnation_list] - ADD R12, R12, #Incarnation_Workspace - BL ShowHelpInModule - BVS %FT67 - B %BT11 - -tryagainstmodulename - Push "r0" - MOV r1, #0 - MOV r2, #0 -tamn_loop - MOV r0, #ModHandReason_GetNames - SWI XOS_Module - Pull r0, VS - BVS %FT02 - LDR r0, [stack] ; kword ptr - Push "r1, r2" - LDR r4, [r3, #Module_Title] - CMP r4, #0 - BEQ tamn_notit - ADD r4, r4, r3 - MOV R5, #0 ; offset -tamn_chk - LDRB R1, [R0, R5] - LDRB R2, [R4, R5] - CMP R1, #32 - CMPLE R2, #32 - BLE tamn_dojacko ; matched at terminator - UpperCase R1, R6 - UpperCase R2, R6 - CMP R1, R2 - ADDEQ R5, R5, #1 - BEQ tamn_chk - RSBS R2, R2, #33 ; only if not terminated - CMPLE R1, #"." ; success if abbreviation - BNE tamn_notit -tamn_dojacko - BL ModuleJackanory - STRVS r0, [stack, #2*4] -tamn_notit - Pull "r1, r2" - Pull r0, VS - BVS %FT67 - CMP r2, #0 - ADDNE r1, r1, #1 - MOVNE r2, #0 - B tamn_loop - -02 LDRB R1, [R0], #1 - CMP R1, #"." - CMPNE R1, #" " - BGT %BT02 - CMP R1, #" " - BLT %FT67 -66 LDRB R1, [R0], #1 - CMP R1, #" " - BEQ %BT66 - SUBGT R0, R0, #1 - BGT DoHelpOnNextKeyWord -67 BLVC testnohelpdone - Pull "R1" - MRS r6, CPSR - TST R1, #5 - SWIEQ XOS_WriteI+15 ; paged mode off - MSR CPSR_f, r6 ; restore V state - Pull "r7, PC" - -testnohelpdone - CMP r7, #0 - MOVNE pc, lr - MOV r7, lr - [ International - BL WriteS_Translated - = "NoHelp:No help found.",10,13,0 - ALIGN - | - SWI XOS_WriteS - = "No help found.",10,13,0 - ALIGN - ] - MOV pc, r7 - -;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -ModuleJackanory ROUT ; give summary of info in module @ r3 - Push "r0, lr" - CheckSpaceOnStack HelpBufferSize+256, modjack_noroom, r6 - SUB stack, stack, #HelpBufferSize - MOV r2, r3 - LDR r3, [r2, #Module_Title] - CMP r3, #0 - ADDNE r3, r3, r2 - ADREQL r3, NoRIT - BL PrintMatch - BVS %FT99 - LDR r3, [r2, #Module_HelpStr] - CMP r3, #0 - BEQ nohstring - STMDB sp!, {r2, r3} - MOV r0, #0 ; Try our message file before Global. - LDR r0, [r0, #KernelMessagesBlock] - TEQ r0, #0 - ADRNE r0, KernelMessagesBlock+4 - ADRL r1, modjack_hstr - MOV r2, #0 - SWI XMessageTrans_Lookup - SWIVC XMessageTrans_Dictionary - MOVVC r1, r0 - MOVVC r0, r2 - SWIVC XOS_PrettyPrint - SWIVC XOS_WriteI + 32 - LDMIA sp!, {r2, r3} - ADDVC r0, r2, r3 - SWIVC XOS_PrettyPrint - BVS %FT99 -nohstring - MOV r3, stack ; buffer address - MOV r1, #0 ; flags for commands - ADRL r0, modjack_comms - BL OneModuleK_Lookup - MOVVC r1, #FS_Command_Flag - ADRVCL r0, modjack_filecomms - BLVC OneModuleK_Lookup - MOVVC r1, #Status_Keyword_Flag - ADRVCL r0, modjack_confs - BLVC OneModuleK_Lookup - MOVVC r1, #-1 - ADRVCL r0, modjack_aob - BLVC OneModuleK_Lookup -99 ADD stack, stack, #HelpBufferSize - SWIVC XOS_NewLine -98 STRVS r0, [stack] - Pull "r0, PC" -modjack_noroom - ADRL r0, ErrorBlock_StackFull - [ International - BL TranslateError - | - SETV - ] - B %BT98 - -OneModuleK_Lookup - STMDB sp!, {r1-r3, lr} - MOV r1, r0 - MOV r0, #0 ; Try our message file before Global. - LDR r0, [r0, #KernelMessagesBlock] - TEQ r0, #0 - ADRNE r0, KernelMessagesBlock+4 - MOV r2, #0 - SWI XMessageTrans_Lookup - MOVVC r0, r2 - LDMIA sp!, {r1-r3, lr} - MOVVS pc, lr - B OneModuleK - -;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; Print match header, keyword @ r3 - -PrintMatch ROUT - [ International - Push "r0-r4, lr" - SWI XOS_ReadEscapeState - BLCS AckEscape - - SWI XOS_WriteI+CR - MOVVC r4,r3 - BL WriteS_Translated_UseR4 - = "HelpFound:==> Help on keyword %0",0 - ALIGN - SWIVC XOS_NewLine - STRVS R0, [stack] - MOV R7, #1 - Pull "r0-r4, PC" - | - Push "r0-r2, lr" - SWI XOS_ReadEscapeState - BLCS AckEscape - ADRVC r0, HelpMatchString - MOV r2, r3 - SWIVC XOS_PrettyPrint ; print matched keyword - SWIVC XOS_NewLine - STRVS R0, [stack] - MOV R7, #1 - Pull "r0-r2, PC" - -HelpMatchString = CR, "==> Help on keyword ",TokenEscapeChar,Token0, 0 - ALIGN - ] - -;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -ShowHelpInModule ROUT ; take module ptr in R1, give relevant help. - - Push "R2-R6, lr" - - LDR R2, [R1, #Module_HC_Table] - CMP R2, #0 - Pull "R2-R6, PC", EQ - - ADD R2, R1, R2 ; point at table -fujjnulltables - LDRB R5, [R2] - CMP R5, #0 - BNE %FT21 - Pull "R2-R6, PC" ; finished - -21 MOV R3, #0 ; offset -22 LDRB R4, [R0, R3] - LDRB R5, [R2, R3] - CMP R4, #32 - CMPLE R5, #32 - BLE %FT25 ; matched at terminator - UpperCase R4, R6 - UpperCase R5, R6 - CMP R4, R5 - ADDEQ R3, R3, #1 - BEQ %BT22 - RSBS R5, R5, #33 ; only if not terminated - CMPLE R4, #"." ; success if abbreviation - BEQ %FT25 - ADD R2, R2, R3 -23 LDRB R5, [R2], #1 - CMP R5, #32 - BGT %BT23 ; skip to terminator - ADD R2, R2, #3 - BIC R2, R2, #3 ; ALIGN -24 ADD R2, R2, #16 - B fujjnulltables - -25 ADD R2, R2, R3 - SUB R3, R2, R3 ; hang on to keyword ptr -28 LDRB R5, [R2], #1 - CMP R5, #0 - BNE %BT28 ; demand null terminator - ADD R2, R2, #3 - BIC R2, R2, #3 ; ALIGN - - LDR R5, [R2, #12] ; get help offset - CMP R5, #0 - BEQ %BT24 ; no help. - - BL PrintMatch ; r3 -> keyword - Pull "R2-R6, PC", VS - - LDR R6, [R2, #4] ; get info word - TST R6, #Help_Is_Code_Flag - BNE CallHelpKeywordCode - - Push "R0-r3" - TST R6, #International_Help - BEQ %FT35 - SUB sp, sp, #16 - LDR r2, [r1, #-4] - LDR r0, [r1, #Module_MsgFile] - TST r0, #12,2 - CMPEQ r0, #1 - CMPCS r2, r0 - MOVLS r0, #0 - BLS %FT29 - ADD r1, r1, r0 - MOV r2, #0 - MOV r0, sp - SWI XMessageTrans_OpenFile - MOVVS r0, #0 -29 MOV r6, r0 - LDR r1, [sp, #16 + 1 * 4] - ADD r1, r5, r1 - MOV r2, #0 - SWI XMessageTrans_Lookup - ADDVS r2, r0, #4 - SWI XMessageTrans_Dictionary - MOVVS r0, #0 - MOV r1, r0 - MOV r0, r2 - LDR r2, [sp, #16 + 3 * 4] - SWI XOS_PrettyPrint ; Error check not done yet - SWI XOS_NewLine - MOV r0, r6 - LDR r2, [sp, #16 + 2 * 4] - LDR R5, [r2, #8] - CMP R5, #0 - BEQ %FT30 ; Should print default message? - LDR r1, [sp, #16 + 1 * 4] - ADD r1, r5, r1 - MOV r2, #0 - SWI XMessageTrans_Lookup - ADDVS r2, r0, #4 - SWI XMessageTrans_Dictionary - MOVVS r0, #0 - MOV r1, r0 - MOV r0, r2 - LDR r2, [sp, #16 + 3 * 4] - SWI XOS_PrettyPrint ; No Error check!!! - SWI XOS_NewLine -30 MOVS r0, r6 - SWINE XMessageTrans_CloseFile - ADD sp, sp, #16 - Pull "R0-R3" - B %BT24 - -35 ADD R0, R5, R1 - MOV r1, #0 - MOV r2, r3 - SWI XOS_PrettyPrint - SWIVC XOS_NewLine - STRVS R0, [stack] - Pull "R0-r3" - Pull "R2-R6, PC", VS - B %BT24 - -helpnostack - ADRL R0, ErrorBlock_StackFull - [ International - BL TranslateError - ] - SETV - Pull "R2-R6, pc" - -CallHelpKeywordCode - CheckSpaceOnStack HelpBufferSize+256, helpnostack, R6 - SUB stack, stack, #HelpBufferSize - Push "R0-R2, R12" ; code allowed to corrupt R1-R6, R12 - MOV R2, R1 - ADD R0, stack, #4*4 - MOV R1, #HelpBufferSize - MOV lr, PC ; R12 set by our caller - ADD PC, R5, R2 - BVS hkc_threwawobbly - CMP R0, #0 - MOVNE r1, #0 - SWINE XOS_PrettyPrint - SWIVC XOS_NewLine -hkc_threwawobbly - STRVS R0, [stack] - Pull "R0-R2, R12" - ADD stack, stack, #HelpBufferSize - BVC %BT24 - Pull "R2-R6, PC" - -;************************************************************************** - -GO_Code ROUT - Push "R7, lr" - MOV R4, R0 - BL SPACES - CMP R5, #13 - TEQNE R5, #";" - MOVLS R7, #UserMemStart - BCC GOEX - BEQ GOEX0 - BL ReadHex - MOVVS R7, #UserMemStart - BL SPACES -GOEX0 TEQ R5, #";" - BLEQ SPACES -GOEX SUB R1, R4, #1 - MOV R0, #FSControl_StartApplication - MOV R2, R7 - ADR R3, GOSMUDGE - SWI XOS_FSControl - Pull "R7, PC", VS - - LDR sp_svc, =SVCSTK ; remove supervisor stuff - WritePSRc 0, R14 ; in to user mode - MOV PC, R7 - -GOSMUDGE = "GO ", 0 - ALIGN - -ReadHex Push "R0-R2, lr" - MOV R0, #16 - SUB R1, R4, #1 - SWI XOS_ReadUnsigned - MOV R4, R1 - MOV R7, R2 - Pull "R0-R2, PC" - -SPACES LDRB R5, [R4], #1 - TEQ R5, #" " - BEQ SPACES - MOV PC, R14 - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -Close_Code Entry - - MOV R0, #0 - MOV R1, #0 - SWI XOS_Find - EXIT - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -FX_Code Entry - - MOV R1, #0 - MOV R2, #0 - Push "R1-R2" ; Put optional parms (default 0, 0) on stack - MOV R1, R0 - MOV R0, #10 - SWI XOS_ReadUnsigned - Push "R2" ; Pulled as R0 when OSByte called - BVS %FT90 - BL %FT10 - -TV_EntryPoint - - MOV R0, #10 - SWI XOS_ReadUnsigned - BVS %FT90 - STR R2, [stack, #4] - BL %FT10 - MOV R0, #10 - SWI XOS_ReadUnsigned - BVS %FT90 - STR R2, [stack, #8] - - BL %FT10 ; check for EOL: goes to 05 if end - ADR R0, ErrorBlock_TooManyParms - [ International - BL TranslateError - | - SETV - ] -90 ADD sp, sp, #12 ; Error before we'd pulled r0-r2 for osbyte - EXIT - - MakeErrorBlock TooManyParms - -05 - Pull "R0-R2" - SWI XOS_Byte - EXIT - -; Skip leading spaces and optional comma - -10 LDRB R2, [R1], #1 - CMP R2, #" " - BEQ %BT10 - CMP R2, #"," - MOVEQ PC, lr ; Let ReadUnsigned strip leading spaces. - CMP R2, #CR - CMPNE R2, #LF - CMPNE R2, #0 - BEQ %BT05 ; Terminated command, so execute the osbyte - SUB R1, R1, #1 ; Back to first char - MOV PC, lr - - -TV_Code ALTENTRY ; must be same as FX_Code ! - - MOV R1, #144 ; OSBYTE number - MOV R2, #0 - MOV R14, #0 - Push "R1, R2, lr" - MOV R1, R0 - B TV_EntryPoint - - -Shadow_Code Entry - - CMP R1, #0 - MOV R1, R0 - MOV R0, #10 + (1:SHL:30) - SWINE XOS_ReadUnsigned - MOVEQ R2, #0 - EXIT VS - BL CheckEOL - BNE ShadowNaff - MOV R0, #114 - MOV R1, R2 - SWI XOS_Byte - EXIT - -ShadowNaff - ADRL R0, ErrorBlock_BadNumb - [ International - BL TranslateError - | - SETV - ] - EXIT - -CheckEOL - LDRB R0, [R1], #1 - CMP R0, #" " - CMPNE R0, #13 - CMPNE R0, #10 - CMPNE R0, #0 - MOV PC, lr - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -Key_Code Entry - - SUB sp, sp, #32 - MOV R1, R0 - MOV r6, sp - LDR R2, %FT02 ; Load 'Key$' - STR R2, [R6], #4 - MOV R0, #10 + (1 :SHL: 29) ; default base - MOV R2, #15 ; maximum key - SWI XOS_ReadUnsigned - BVS %FT90 - CMP R2, #10 - MOVGE R4, #"1" - STRGEB R4, [R6], #1 - SUBGE R2, R2, #10 - ADD R2, R2, #"0" - STRB R2, [R6] - MOV R2, #0 - STRB R2, [R6, #1] - MOV R0, sp - MOV R3, #0 - MOV R4, #VarType_String - SWI XOS_SetVarVal - -80 ADD sp, sp, #32 - EXIT - -90 ADR r0, ErrorBlock_BadKey - [ International - BL TranslateError - | - SETV ; It needs setting here ! - ] - B %BT80 - - MakeErrorBlock BadKey -02 - DCB "Key$" ; Must be aligned - ALIGN - - LTORG - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; Exec, Spool and SpoolOn share a common body - -Exec_Code Entry "$UtilRegs" - - MOV r3, #&40 ; OPENIN exec - MOV r4, #198 ; r0b for osbyte exec - B %FT01 - - -Spool_Code ALTENTRY - - MOV r3, #&80 ; OPENOUT spool - B %FT00 - - -SpoolOn_Code ALTENTRY - - MOV r3, #&C0 ; OPENUP spoolon - -00 MOV r4, #199 ; r0b for osbyte spool/spoolon - -01 MOV r5, r0 ; Save filename^ - MOV r6, r1 ; Save n parms - - MOV r0, r4 ; Read old exec/spool handle - MOV r1, #0 ; Write 0 as handle; we may be just closing - MOV r2, #0 ; and keep zero if open error (cf. RUN) - SWI XOS_Byte ; Won't cause error - BL CloseR1 - EXIT VS - - CMP r6, #0 ; No filename present ? - EXIT EQ ; ie. just closing down exec/spool ? - - MOV r1, r5 ; -> filename - MOV r0, r3 ; OPENIN exec/OPENUP spoolon/OPENOUT spool - BL OpenFileWithWinge - EXIT VS - - CMP r3, #&C0 ; Doing SPOOLON ? VClear - BLEQ MoveToEOF ; PTR#r1:= EXT#r1 - - MOV r0, r4 ; Write new exec/spool handle (r1) - MOV r2, #0 - SWIVC XOS_Byte ; May have got error in moving to EOF - EXIT - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; List, Print and Type share a common body - -listopt RN r2 -lastchar RN r3 -linecount RN r4 -charcount RN r5 - -lnum * 2_01 ; Line numbers -type * 2_10 ; GSREAD format ? - -filterprinting * 2_10000000 ; Bits controlling printing -linenumbering * 2_01000000 -expandtabs * 2_00100000 - -forcetbsrange * 2_00001000 -allowtbschar * 2_00000100 -unprintangle * 2_00000010 -unprinthex * 2_00000001 -unprintdot * 2_00000001 - -Print_Code Entry "$UtilRegs" - - MOV listopt, #0 ; No line numbers, raw ASCII - B %FT01 - - -List_Code ALTENTRY - - MOV listopt, #(filterprinting + linenumbering) - MOV linecount, #0 - B %FT00 - - -TypeArgs = "File/A,TabExpand/S",0 - ALIGN - -Type_Code ALTENTRY - - MOV listopt, #filterprinting - -00 MOV r6, r1 ; no. params - BL ReadGSFormat ; Read configured GSFormat bits - EXIT VS ; I2C could be faulty ! File not open - ORR listopt, listopt, r1 - - CMP r6, #1 - BEQ %FT01 - Push "R2, R3" - MOV R1, R0 ; args given - ADR R0, TypeArgs - LDR R2, =ArgumentBuffer - [ LongCommandLines - MOV R3, #LongCLISize - | - MOV R3, #256 - ] - SWI XOS_ReadArgs - Pull "R2, R3", VS - EXIT VS - LDR R0, [R2, #4] ; tabflag - CMP R0, #0 - LDR R0, [R2, #0] ; filename ptr - Pull "R2, R3" - ORRNE listopt, listopt, #expandtabs - -01 MOV lastchar, #0 ; Reset NewLine indicator - - MOV r1, r0 ; Point to filename - MOV r0, #&40 ; han := OPENIN <filename> - BL OpenFileWithWinge - EXIT VS - -10 SWI XOS_ReadEscapeState ; Won't cause error - BCS CloseThenAckEscape - - MOV charcount, #0 ; No characters printed this line - - SWI XOS_BGet ; Get first character of line - BVS UtilityExitCloseR1 - BCS UtilityExitCloseR1 ; EOF ? - - TST listopt, #linenumbering ; Do we want to print the line number ? - BLNE LineNumberPrint - BVS UtilityExitCloseR1 - -; Doing ASCII (print) or GSREAD (type, list) ? - -30 TST listopt, #filterprinting - BEQ %FT35 - -; GSREAD format printing - - CMP r0, #CR ; CR and LF both line terminators - CMPNE r0, #LF - BEQ %FT70 - - CMP r0, #TAB - BNE %FT31 - TST listopt, #expandtabs - BEQ %FT31 - -; simple tab expansion: 8 spaces - SWI XOS_WriteS - = " ",0 - ALIGN - B %FT32 - -31 MOV lastchar, r0 - CMP r0, #"""" ; Don't display quotes in GSREAD though - CMPNE r0, #"<" ; Or left angle - BEQ %FT35 - BL PrintCharInGSFormat - -32 BVC %FT40 - -35 SWIVC XOS_WriteC - BVS UtilityExitCloseR1 - ADD charcount, charcount, #1 - -40 SWI XOS_ReadEscapeState ; Won't cause error - BCS CloseThenAckEscape - - SWI XOS_BGet ; Get another character on this line - BVS UtilityExitCloseR1 - BCC %BT30 ; Loop if not EOF - -50 TST listopt, #filterprinting - SWINE XOS_NewLine ; Terminate with NewLine if not *Print - B UtilityExitCloseR1 - - -; Hit LF or CR in GSFormat mode, decide whether to give a NewLine or not - -70 CMP r0, lastchar ; NewLine if same as last time eg LF,LF - SWIEQ XOS_NewLine - BVS UtilityExitCloseR1 - BEQ %BT10 ; Loop back and do another line - - CMP lastchar, #CR ; Don't give another NewLine if we've - CMPNE lastchar, #LF ; had CR, LF or LF, CR - MOVEQ lastchar, #0 ; Reset NewLine indicator so more will - BEQ %BT40 ; Loop and do more chars in this line - - MOV lastchar, r0 ; Save char forcing this NewLine - SWI XOS_NewLine ; Do NewLine then another line - BVC %BT10 - B UtilityExitCloseR1 - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -Dump_Code Entry "$UtilRegs" - - MOV r7, r1 ; Remember nparms - MOV r8, r0 ; Remember filename^ for below - MOV r1, r0 ; -> filename - - MOV r0, #&40 ; han := OPENIN <filename> - BL OpenFileWithWinge - EXIT VS ; File not yet open - MOV r9, r1 ; Save handle - - MOV r0, #OSFile_ReadInfo ; Read file info - MOV r1, r8 ; Restore filename^ - SWI XOS_File ; Must exist and be a file now - MOV r1, r9 ; Restore handle in case of error/exit - BVS UtilityExitCloseR1 - - CMP r4, #0 ; Zero length ? - BEQ UtilityExitCloseR1 ; Nothing to do then ! VClear - - MOV r5, r9 ; Standard place for handle below - -; Default display at load addr of file (r2) unless special - - BL ReadGSFormat ; Only interested in some bits - BVS UtilityExitCloseR1 - AND r10, r1, #forcetbsrange + allowtbschar - - CMP r2, #0 ; Command file ? - CMPEQ r3, #-1 - BEQ %FT04 - - MOV r14, r2, ASR #(32-12) ; Date stamped file ? - CMP r14, #-1 ; &FFFtttdd -04 MOVEQ r2, #0 ; Display start = 0 - - MOV r3, #0 ; Default PTR# = 0 - ; Funny order 'cos of ReadOptLoadAndExe - - CMP r7, #1 ; Only filename specified ? - BEQ %FA10 ; If so, use loadaddr and ptr=0 - - MOV r1, r8 ; Get back filename^ - BL SkipToSpace ; Over the filename - BL ReadOptionalLoadAndExec ; Abuse ! r3 := start, r2 := disp start - MOVVS r1, r5 - BVS UtilityExitCloseR1 - - ADD r2, r3, r2 ; Display offset = disparm/loadaddr+ptr - -10 Swap r2, r3 ; r2 := start, r3 := disp start - CMP r2, r4 ; Is ptr > ext ? VClear - MOVHS r1, r5 - BLHS SetErrorOutsideFile - - MOVVC r0, #OSArgs_SetPTR - MOVVC r1, r5 - SWIVC XOS_Args ; PTR#r1 := start offset - MOVVC r7, #0 - - BLVC ReadWindowWidth - BVS UtilityExitCloseR1 - - SUB r9, r0, #12+1 ; -ExtraFields (address and separators) - MOV r9, r9, LSR #2 ; Two nibbles, one space and one char per byte - - Push r10 ; Save format bits - MOV r10, #(1 :SHL: 31) ; Move 1 bit down until not zero -12 MOVS r10, r10, LSR #1 - MOVEQ r9, #1 ; Always 1 byte per line at least - BEQ %FT15 - TST r10, r9 ; Mask against r9 (byte count) - BEQ %BT12 ; Not hit yet ? - - AND r9, r9, r10, LSR #1 ; Take the bit one lower down - ORR r9, r9, r10 ; And the bit we matched. Yowzay ! - -15 MOV r1, r5 ; Get handle back - Pull r10 ; Get format back - - - SUB sp, sp, #256 ; Need temp frame now - -; Main Dump loop - -30 SWI XOS_ReadEscapeState ; Won't cause error - ADDCS sp, sp, #256 - BCS CloseThenAckEscape - -; Get line of data (r9 bytes). Keep track of how many bytes were read in r4 - - MOV r2, sp ; Temp buffer - MOV r4, #0 -35 SWI XOS_BGet ; Fall out of loop if EOF - BVS UtilityExitCloseR1_256 - STRCCB r0, [r2, r4] - ADDCC r4, r4, #1 - CMPCC r4, r9 - BCC %BT35 - - CMP r4, #0 ; No bytes to do this line ? - BEQ UtilityExitCloseR1_256 - -; Must preserve r4 till end for testing - - ANDS r7, r7, #15 ; Print title every 16 lines of data - BNE %FT54 - - - [ International - SWI XOS_NewLine - BL WriteS_Translated - DCB "Address:Address :",0 - ALIGN - | - SWI XOS_WriteS ; Print title start - DCB LF, CR - DCB "Address :", 0 - ALIGN - ] - BVS UtilityExitCloseR1_256 - - MOV r8, #0 -50 ADD r0, r3, r8 ; Print byte == LSB of - SWI XOS_WriteI+" " ; display across page - BLVC HexR0Byte - BVS UtilityExitCloseR1_256 - ADD r8, r8, #1 - CMP r8, r9 - BNE %BT50 - - CMP r9, #11 ; No room to print title end ? - BLO %FT52 ; VClear - - SWI XOS_WriteS - DCB " : ", 0 - ALIGN - BVS UtilityExitCloseR1_256 - - SUB r8, r9, #10 ; Centre 'ASCII data' over data - MOVS r8, r8, LSR #1 -51 SUBS r8, r8,#1 ; VClear - SWI XOS_WriteI+" " - BVS UtilityExitCloseR1_256 - BPL %BT51 - - [ International - BL WriteS_Translated - DCB "ASCII:ASCII data",0 - ALIGN - | - SWI XOS_WriteS - DCB "ASCII data", 0 - ALIGN - ] - -52 SWIVC XOS_NewLine - SWIVC XOS_NewLine - -54 MOVVC r0, r3 ; Print start of line address - BLVC HexR0LongWord - SWIVC XOS_WriteI+" " - SWIVC XOS_WriteI+":" - BVS UtilityExitCloseR1_256 - -; Print line of data in hex - - MOV r5, #0 -55 LDRB r0, [r2, r5] - SWI XOS_WriteI+" " - BVS UtilityExitCloseR1_256 - CMP r5, r4 ; Byte valid ? - SWICS XOS_WriteI+" " - BVS UtilityExitCloseR1_256 - SWICS XOS_WriteI+" " - BVS UtilityExitCloseR1_256 - BLCC HexR0Byte ; Alters C, so do last - BVS UtilityExitCloseR1_256 - ADD r5, r5, #1 - CMP r5, r9 - BCC %BT55 - - SWI XOS_WriteS - DCB " : ", 0 - ALIGN - BVS UtilityExitCloseR1_256 - -; Print line of data in ASCII - - MOV r5, #0 -65 LDRB r0, [r2, r5] - TST r10, #forcetbsrange ; Forcing into 00..7F ? - BICNE r0, r0, #&80 - TST r10, #allowtbschar - BEQ %FT66 - CMP r0, #&80 ; Print tbs unmolested - BHS %FT67 -66 CMP r0, #" " ; Space through twiddle are valid - RSBGES r14, r0, #&7E - MOVLT r0, #"." -67 SWI XOS_WriteC - BVS UtilityExitCloseR1_256 - ADD r5, r5, #1 - CMP r5, r4 - BCC %BT65 - - SWI XOS_NewLine - BVS UtilityExitCloseR1_256 - ADD r7, r7, #1 ; Increment line count - ADD r3, r3, r9 ; Increment display address by r9 bytes - CMP r4, r9 ; Loop till we couldn't fill a line - BEQ %BT30 - -; ............................................................................. - -UtilityExitCloseR1_256 - - ADD sp, sp, #256 ; Kill temp frame - -; ............................................................................. - -UtilityExitCloseR1 - - BL CloseR1 ; Accumulates V - - Pull "$UtilRegs, pc" ; Back to *Command handler - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; Append and Build share a common body - -Append_Code Entry "$UtilRegs" - - MOV r1, r0 ; -> filename - MOV r0, #&C0 ; OPENUP - B %FT01 - - -Build_Code ALTENTRY - - MOV r1, r0 ; -> filename - MOV r0, #&80 ; OPENOUT - -01 BL OpenFileWithWinge - EXIT VS - - SUB sp, sp, #256 - - MOV r5, r1 ; Save handle for later - BL MoveToEOF ; Can do this anyhow as ext#(openout)=0 - - MOV linecount, #0 - -10 BLVC LineNumberPrint ; Escape is tested for on OS_ReadLine.Err below - BVS UtilityExitCloseR1_256 - - MOV r0, sp ; Get a line from Joe Punter - MOV r1, #256-1 ; -1 for terminator - MOV r2, #" " - MOV r3, #&FF - SWI XOS_ReadLine32 - MOVVS r1, r5 - BVS UtilityExitCloseR1_256 - MOV r3, #CR ; Terminate source string - STRB r3, [r0, r1] - MOVCC FSUTtemp, #0 ; Ended with ESCAPE ? - MOVCS FSUTtemp, #-1 - MOVCS r0, #&7E ; Ack. ESCAPE, not error - SWICS XOS_Byte - BVS UtilityExitCloseR1_256 - - MOV r2, sp ; r2 -> buffer to translate - MOV r1, r5 ; Get handle back -18 LDRB r0, [r2], #1 ; Put all the spaces out ourselves ! - CMP r0, #" " ; VClear - SWIEQ XOS_BPut - BVS UtilityExitCloseR1_256 - BEQ %BT18 - - SUB r0, r2, #1 ; r0 -> past spaces, rest to translate - MOV r2, #(1 :SHL: 31) ; No quote funnies, don't end on space, do | - SWI XOS_GSInit - -20 SWIVC XOS_GSRead ; Get a char - MOVVS R1, R5 - BVS UtilityExitCloseR1_256 - BCS %FT30 ; End of string ? - MOV r3, r0 ; Save GSState - MOV r0, r1 ; Char from GSRead - MOV r1, r5 ; Get handle back - SWI XOS_BPut - BVS UtilityExitCloseR1_256 - MOV r0, r3 ; Restore GSState - B %BT20 ; And loop - -30 CMP FSUTtemp, #0 ; Did we read ESCAPE ? VClear - MOV r1, r5 ; In any case, we want r1 handle - MOV r0, #CR ; If not, stick a CR on eoln - SWIEQ XOS_BPut - BEQ %BT10 ; Finished if ESCAPE was pressed - ; Catch error back there too - - SWIVC XOS_NewLine - - B UtilityExitCloseR1_256 - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; OSFile routines: Load, Save, Create, Delete and Remove - -Load_Code Entry "$UtilRegs" - - MOV r7, r0 ; -> filename - CMP r1, #1 ; Just filename (1 parm) ? - MOVEQ r3, #&FF ; Load at its own address if so - BEQ %FT90 - - BL SkipNameAndReadAddr - EXIT VS - BLCS SetErrorBadAddress ; Must check for trailing junk - MOVVC r3, #0 ; Got load address from command line - -90 MOVVC r0, #OSFile_Load - [ StrongARM - ORRVC r3, r3, #1<<31 - ] - MOVVC r1, r7 ; Get filename^ back - SWIVC XOS_File - EXIT - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -Save_Error - DCD ErrorNumber_Syntax - [ International - DCB "BadSav:Bad parameters for *Save", 0 - ] - ALIGN - -Save_Code Entry "$UtilRegs" - - BL SkipNameAndReadAddr - EXIT VS - - MOV r4, r2 ; Got start address - BL SkipSpaces - MOV r5, r0 ; Preserve state - CMP r0, #"+" ; Is it a +<length> parm ? - ADDEQ r1, r1, #1 ; Skip '+' then - BLEQ SkipSpaces ; And any trailing spaces - BL ReadAtMost8Hex ; Read a word anyway - EXIT VS - - CMP r5, #"+" - MOVNE r5, r2 ; <end addr> ? - ADDEQ r5, r2, r4 ; Form <end addr> := <start addr> + <length> - MOV r2, r4 ; r2, r3 := both r4 by default - MOV r3, r4 - BL ReadOptionalLoadAndExec - SETV CS - ADRVS R0, Save_Error ; If there's anything on the end, it's an error - [ International - BLVS TranslateError - ] - MOVVC r0, #OSFile_Save - MOVVC r1, r7 ; Get filename^ back - SWIVC XOS_File - EXIT - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -Create_Code Entry "r1, $UtilRegs" - - CMP r1, #1 ; Filename only -> length 0, dated - MOVEQ r7, r0 ; Filename^ - MOVEQ r2, #0 ; Will be copied to r5 in a bit - BLNE SkipNameAndReadAddr - EXIT VS - MOV r5, r2 ; Got length, put in as end address - MOV r4, #0 ; So start addr shall be .. 0 ! - - LDR r14, [sp] ; No load, exec -> datestamp FFD - CMP r14, #3 - MOVLO r0, #OSFile_CreateStamp - LDRLO r2, =&FFFFFFFD ; Only bottom 12 bits are of interest - MOVHS r0, #OSFile_Create ; Makes it an immediate constant - MOVHS r2, #0 ; Load/Exec default to 0 - MOVHS r3, #0 - BLHS ReadOptionalLoadAndExec - - MOVVC r1, r7 ; Get filename^ back - SWIVC XOS_File - EXIT - - LTORG - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; Delete and Remove share a common body - -Delete_Code Entry - - MOV r6, #0 ; Give error if file doesn't exist - B %FT01 ; Use a reg. not affected by OSFile ! - -Remove_Code ALTENTRY - - MOV r6, #-1 ; Don't winge - -01 MOV r1, r0 ; -> filename - MOV r0, #OSFile_Delete - SWI XOS_File - EXIT VS - - CMP r0, r6 ; Are we going to winge ? - MOVEQ r0, #OSFile_MakeError ; Give pretty error now, says Tutu - MOVEQ r2, #object_nothing - SWIEQ XOS_File - EXIT - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; Gosh, doesn't use UtilRegs !!! - -Opt_Code Entry - - MOV r3, #0 ; Default parms are 0, 0 - MOV r4, #0 - CMP r1, #0 ; No parms ? VClear - BEQ %FT50 - - MOV r1, r0 - MOV r0, #10 ; Default base 10, allow naff term ',' - SWI XOS_ReadUnsigned ; Read first parm - EXIT VS - MOV r3, r2 - - BL FS_SkipSpaces ; Try getting another parm anyway - BCC %FT50 ; End of the line - - TEQ r0, #"," ; commas too ! - ADDEQ r1, r1, #1 - BLEQ FS_SkipSpaces - CMP r0, #space ; Anything here ? - BEQ %FT99 - - MOV r0, #(1 :SHL: 31) + 10 ; Default base 10, no bad terms - SWI XOS_ReadUnsigned ; Read second parm - MOVVC r4, r2 - -50 MOVVC r0, #FSControl_Opt - MOVVC r1, r3 - MOVVC r2, r4 - SWIVC XOS_FSControl - EXIT - -99 ADR r0, SyntaxError_StarOpt - [ International - BL TranslateError - | - SETV - ] - EXIT - - -SyntaxError_StarOpt - DCD ErrorNumber_Syntax - DCB "OptErr:Syntax: *Opt [<x> [[,] <y>]]", 0 - ALIGN - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; H o r r i b l e l i t t l e s u b r o u t i n e s -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; Variegated output routines - -HexR0LongWord Entry "r0" - - MOV r0, r0, ROR #16 - BL HexR0Word - MOVVC r0, r0, ROR #32-16 - BLVC HexR0Word - STRVS r0, [sp] - EXIT - - -HexR0Word Entry "r0" - - MOV r0, r0, ROR #8 - BL HexR0Byte - MOVVC r0, r0, ROR #32-8 - BLVC HexR0Byte - STRVS r0, [sp] - EXIT - - -HexR0Byte Entry "r0" - - MOV r0, r0, ROR #4 - BL HexR0Nibble - MOVVC r0, r0, ROR #32-4 - BLVC HexR0Nibble - STRVS r0, [sp] - EXIT - - -HexR0Nibble Entry "r0" - - AND r0, r0, #15 - CMP r0, #10 - ADDCC r0, r0, #"0" - ADDCS r0, r0, #"A"-10 - SWI XOS_WriteC - STRVS r0, [sp] - EXIT - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -SkipSpaces ROUT - -10 LDRB r0, [r1], #1 - CMP r0, #" " ; Leave r1 -> ~space - BEQ %BT10 - SUB r1, r1, #1 - CLRV - MOV pc, lr ; r0 = first ~space. Can't really fail - - -SkipToSpace Entry - -10 LDRB lr, [r1], #1 - CMP lr, #&7F - CMPNE lr, #" " ; Leave r1 -> space or CtrlChar - BHI %BT10 - SUB r1, r1, #1 - CLRV - EXIT - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; In r1 -> string - -; Out flags from CMP r0, #space for eol detection - -FS_SkipSpaces ROUT - -10 LDRB r0, [r1], #1 - CMP r0, #space ; Leave r1 -> ~space - BEQ %BT10 - SUB r1, r1, #1 - MOV pc, lr ; r0 = first ~space - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; In r0 = open mode -; r1 -> filename - -; Out VC: r0 = r1 = handle -; VS: r0 -> error (FilingSystemError or 'NotFound') - -OpenFileWithWinge Entry - - ORR r0, r0, #(open_mustopen :OR: open_nodir) ; Saves us code here - SWI XOS_Find - MOVVC r1, r0 - EXIT - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; PTR#handle := EXT#handle - -; In r1 = handle to use - -; Out VC: PTR moved -; VS: r0 -> Filing System Error - -MoveToEOF Entry "r0, r2" - - MOV r0, #OSArgs_ReadEXT - SWI XOS_Args - MOVVC r0, #OSArgs_SetPTR - SWIVC XOS_Args - STRVS r0, [sp] - EXIT - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -CloseThenAckEscape - - BL CloseR1 - - BL AckEscape - Pull "$UtilRegs, pc" ; Common exit - back to MOS - - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; In r1 = handle to close, or 0 means don't do anything - -; Out VC: file closed, or nothing done -; VS: r0 -> Filing System Error, or VSet on entry - -CloseR1 EntryS "r0" - - CMP r1, #0 ; Is there a handle to close ? VClear - MOVNE r0, #0 ; CLOSE#han - SWINE XOS_Find - EXITS VC ; Accumulate V - - STR r0, [sp] - EXIT - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; Increment then print a line number in decimal - -LineNumberPrint Entry "r0-r1" - - ADD linecount, linecount, #1 ; r0 := ++linecount - MOV r0, linecount - MOV r1, #1 ; Print leading spaces - BL PrintR0Decimal - SWIVC XOS_WriteI+" " - STRVS r0, [sp] - EXIT - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; In r0 = number to print -; r1 = 0 -> strip spaces -; 1 -> print leading spaces - -; Number gets printed RJ in a field of 4 if possible, or more as necessary - -PrintR0Decimal Entry "r0-r3" - - SUB sp, sp, #32 - MOV r3, r1 ; Save flag - MOV r1, sp - MOV r2, #32 - SWI XOS_BinaryToDecimal ; No errors from this - CMP r3, #0 ; If not doing spaces or >= 4 chars - CMPNE r2, #4 ; in the number, son't print any - - ADRLT r0, %FT98-1 ; Point to right amount of spaces - ADDLT r0, r0, r2 - SWILT XOS_Write0 - -10 LDRVCB r0, [r1], #1 - SWIVC XOS_WriteC - BVS %FT99 - SUBS r2, r2, #1 - BNE %BT10 - -99 ADD sp, sp, #32 - STRVS r0, [sp] - EXIT - -98 - DCB " ", 0 ; Three spaces, null - ALIGN - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; Read configured info of Tutu's wally byte - -; Out r1 = bits read from CMOS ram - -ReadGSFormat Entry "r0, r2" - - MOV r0, #ReadCMOS - MOV r1, #TutuCMOS - SWI XOS_Byte - ANDVC r1, r2, #2_1111 ; Mask out all but my bits - STRVS r0, [sp] - EXIT - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; In r0b = char to print using current listopt - -; Out r0 corrupt - -PrintCharInGSFormat Entry "r1, listopt" - - AND r0, r0, #&FF ; Just in case - TST listopt, #forcetbsrange ; Forcing tbs into 00..7F ? - BIC listopt, listopt, #forcetbsrange - BICNE r0, r0, #&80 ; Take top bit out if so - - CMP r0, #" " ; Do we need to do this at all ? - RSBGES r14, r0, #&7E - BLT %FT10 ; LT if not in range &20-&7E - CMP r0, #"|" ; Solidus ? VClear - CMPNE r0, #"""" ; Quote ? - CMPNE r0, #"<" ; Left angle ? - SWINE XOS_WriteC ; Nope, so let's print the char and exit - EXIT VS - EXIT NE - - -10 TST listopt, #allowtbschar ; International format bit ? - BIC listopt, listopt, #allowtbschar - BEQ %FT15 - CMP r0, #&80 - BHS %FT45 ; Print tbs char and exit - -15 TST listopt, #unprintangle ; Angle bracket format ? - BNE %FT50 - - TST listopt, #unprintdot ; Doing unprintable dot format (2_01) ? - BEQ %FT16 - - CMP r0, #" " ; Only space to twiddle are printable - RSBGES r14, r0, #&7E - MOVLT r0, #"." ; All others are dot - B %FT45 ; Print char and exit - - -; Normal BBC GSREAD format (2_00) - -16 CMP r0, #&80 ; Deal with tbs first - BIC r0, r0, #&80 - BLO %FT17 - SWI XOS_WriteI+"|" - SWIVC XOS_WriteI+"!" - EXIT VS - -17 CMP r0, #&7F ; Delete ? -> |?. VClear - MOVEQ r0, #"?" - CMPNE r0, #"""" ; Quote ? -> |" - CMPNE r0, #"|" ; Solidus ? -> || - SWIEQ XOS_WriteI+"|" - EXIT VS - CMP r0, #&1F ; CtrlChar ? -> |<char+@>. VClear - ADDLS r0, r0, #"@" - SWILS XOS_WriteI+"|" - -45 SWI XOS_WriteC ; Used from above - EXIT - - -50 ; Angle bracket format, either hex (2_11) or decimal (2_10) - - SWI XOS_WriteI+"<" - TST listopt, #unprinthex - BNE %FT60 - MOV r1, #0 ; Strip leading spaces - BLVC PrintR0Decimal - SWIVC XOS_WriteI+">" - EXIT - - -60 SWIVC XOS_WriteI+"&" - BLVC HexR0Byte - SWIVC XOS_WriteI+">" - EXIT - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; In r0 -> filename. Used by most MOS OSFile routines for initial decoding - -; Out r1 -> past address read -; r2 = address read -; r7 = initial filename^ -; VS : failed to read address, r0 -> error -; CS : text present comes immediately after address - -SkipNameAndReadAddr Entry - - MOV r7, r0 ; Save filename^ - MOV r1, r0 ; -> filename - BL SkipToSpace ; Over the filename - BL SkipSpaces ; To the address - BL ReadAtMost8Hex ; Go read it Floyd ! - LDRVCB r0, [r1] ; Anything on the end ? - CMPVC r0, #" "+1 ; CtrlChar + space ok - EXIT ; VC/VS from readhex or VC, CC/CS from CMP - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; In r2, r3 = load/exec addresses to use if none provided. r1 -> string - -; Out r2, r3 conditionally updated, r1 updated, past any trailing spaces -; VS if failed, error ('Bad Address' or whatever) set -; CS if something comes afterwards ... - -ReadOptionalLoadAndExec Entry "r0, FSUTtemp" - - MOV FSUTtemp, r2 ; Save initial value - - BL SkipSpaces - CMP r0, #" " ; No more parms ? - EXIT LO ; VClear, r2, r3 unaffected - - BL ReadAtMost8Hex - BVS %FT99 - MOV r3, r2 - MOV r2, FSUTtemp - BL SkipSpaces - CMP r0, #" " ; No more parms ? - EXIT LO ; VClear, r2 unaffected, r3 updated - - BL ReadAtMost8Hex - BLVC SkipSpaces ; Anything on the end ? - CMPVC r0, #" " -99 STRVS r0, [sp] - EXIT ; VC/VS from readhex or VC, CC/CS from CMP - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; Read a hex (default) address from a string - -; In r1 -> string - -; Out VC: r1 -> first char not used in building number, r2 = number -; VS: error ('Bad Address') set - -ReadAtMost8Hex Entry "r0, r3-r4" - - MOV R0, #16 ; default base, don't trap bad terms - SWI XOS_ReadUnsigned - STRVS r0, [sp] - EXIT ; VClear -> good hex number / VSet -> bad - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; Set various errors: VSet always on exit - -SetErrorBadAddress - - ADR r0, ErrorBlock_BadAddress - [ International - Push "lr" - BL TranslateError - Pull "lr" - ] - RETURNVS - - MakeErrorBlock BadAddress - - -SetErrorOutsideFile - - ADR r0, ErrorBlock_OutsideFile - [ International - Push "lr" - BL TranslateError - Pull "lr" - ] - RETURNVS - - MakeErrorBlock OutsideFile - - -SetErrorEscape - - ADR r0, ErrorBlock_Escape - [ International - Push "lr" - BL TranslateError - Pull "lr" - ] - RETURNVS - - MakeErrorBlock Escape - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -AckEscape - Push "r1-r2, lr" - MOV r0, #&7E - SWI XOS_Byte - - BLVC SetErrorEscape ; Only set ESCAPE error if no override - Pull "r1-r2, pc" - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - END diff --git a/s/TickEvents b/s/TickEvents deleted file mode 100644 index eadff25c..00000000 --- a/s/TickEvents +++ /dev/null @@ -1,250 +0,0 @@ -; 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 => TickEvents - -; This file revised by TMD 28-Jan-94 to -; a) Correct internals to time n ticks not n+1 -; b) Change externals to add 1 to compensate for user subtracting 1 -; c) Fix RemoveTickerEvent to add this nodes time onto the next one -; These fix bug MED-02498. - -; There are two (centisecond) ticker SWIs : -; SWI CallAfter calls the given address once, after the given number of ticks -; SWI CallEvery " " " " every N centiseconds - -; In : R0 is (signed) number of centiseconds -; R1 is address to call -; R2 is value of R12 to pass to code - -CallAfter_Code ROUT - MOV r10, #0 -TickTockCommon - Push "r0-r3, lr" - CMP r0, #0 - BLE %FT99 - - [ ChocolateSysHeap - ASSERT ChocolateTKBlocks = ChocolateBlockArrays + 8 - MOV r3,#ChocolateBlockArrays - LDR r3,[r3,#8] - BL ClaimChocolateBlock - MOVVS r3, #TickNodeSize - BLVS ClaimSysHeapNode - | - MOV r3, #TickNodeSize - BL ClaimSysHeapNode - ] - BVS %FT97 - - MOV r3, r2 - LDMFD stack, {r0-r2} - STR r1, [r3, #TickNodeAddr] - STR r10, [r3, #TickNodeRedo] - STR r2, [r3, #TickNodeR12] - MOV r1, r3 - - ADD r0, r0, #1 ; compensate for n+1 bug - BL InsertTickerEvent - - Pull "r0-r3, lr" - ExitSWIHandler - -99 ADR r0, ErrorBlock_BadTime - [ International - BL TranslateError - ] -97 - ADD sp, sp, #1*4 ; junk old R0 - Pull "r1-r3, lr" - B SLVK_SetV - - MakeErrorBlock BadTime - -CallEvery_Code - ADD r10, r0, #1 ; compensate for n+1 bug - B TickTockCommon - -; Data structure : -; chain of nodes -; -; +----------------------------------+ -; | Link to next node or 0 | -; +----------------------------------+ -; | Reload flag | -; +----------------------------------+ -; | Address to call | -; +----------------------------------+ -; | Value of R12 | -; +----------------------------------+ -; | No of ticks to go before call | -; +----------------------------------+ -; -; The head node's no of ticks is decremented until 0 -; Subsequent nodes contain the no of ticks to wait when they reach the -; chain head. -; If the reload flag is non-0, the node is reinserted at that number of ticks -; down the chain after every use. - - ^ 0 -TickNodeLink # 4 ; -TickNodeRedo # 4 ; These are together -TickNodeAddr # 4 ; -TickNodeR12 # 4 ; so can LDM them - -TickNodeLeft # 4 - -TickNodeSize # 0 - -InsertTickerEvent ROUT -; R1 is node pointer, R0 ticks to wait -; R10-R12 corrupted - - Push "r0,r2" - PHPSEI r2 - LDR r10, =TickNodeChain -01 - MOV r11, r10 - LDR r10, [r11, #TickNodeLink] - CMP r10, #0 - BEQ %FT02 ; end of chain - LDR r12, [r10, #TickNodeLeft] - SUBS r0, r0, r12 - BGE %BT01 - ADD r0, r0, r12 - SUB r12, r12, r0 - STR r12, [r10, #TickNodeLeft] -02 - STR r1, [r11, #TickNodeLink] - STR r0, [r1, #TickNodeLeft] - STR r10, [r1, #TickNodeLink] - - PLP r2 - Pull "r0,r2" - MOV pc, lr - -ProcessTickEventChain ROUT -; R0-R3, R10-R12 corruptible - LDR r3, =TickNodeChain - - LDR r1, [r3, #TickNodeLink] - CMP r1, #0 - MOVEQ pc, lr ; no timers - - LDR r2, [r1, #TickNodeLeft] - SUBS r2, r2, #1 - STR r2, [r1, #TickNodeLeft] - MOVGT pc, lr ; nothing to call yet (was MOVPL) - - Push "lr" ; save IRQ_lr - [ TickIrqReenter - WritePSRc SVC_mode+I_bit, r10 ; switch to SVC mode, IRQ's off - NOP - Push "lr" ; save SVC_lr - ] -01 - LDMIA r1, {r2, r10, r11, r12} ; load next ptr, redo state, - ; address and R12val - STR r2, [r3] ; de-link from chain - MOV lr, pc - MOV pc, r11 ; call event handler - - LDR r0, [r1, #TickNodeRedo] - CMP r0, #0 ; CallEvery? - BLE %FT05 - - BL InsertTickerEvent ; yes, then re-insert timer - B %FT10 - -05 -; Return spent ticker node to heap - - WritePSRc SVC_mode, r2 ; IRQ's ON for the S L O W bit - MOV r2, r1 ; R2->node to free - [ ChocolateSysHeap - ASSERT ChocolateTKBlocks = ChocolateBlockArrays + 8 - MOV r1,#ChocolateBlockArrays - LDR r1,[r1,#8] - BL FreeChocolateBlock - LDRVS r1, =SysHeapStart - MOVVS r0, #HeapReason_Free - SWIVS XOS_Heap - | - LDR r1, =SysHeapStart - MOV r0, #HeapReason_Free - SWI XOS_Heap - ] - WritePSRc SVC_mode+I_bit, r1 ; IRQ's off again - -; Check for more events down the list -10 - LDR r1, [r3, #TickNodeLink] ; get top of list - CMP r1, #0 ; list empty? - BEQ %FT02 ; yes then exit - - LDR r0, [r1, #TickNodeLeft] - CMP r0, #0 ; timed out? - BLE %BT01 ; yes then jump -02 - Pull "lr" ; restore SVC_lr - WritePSRc IRQ_mode+I_bit, r10 ; back to IRQ mode - NOP - Pull "pc" ; pull IRQ_lr from IRQ stack - -RemoveTickerEvent_Code -; R0 is address of code to remove, R1 the R12 value - WritePSRc SVC_mode+I_bit, r10 - LDR r10, =TickNodeChain -01 - LDR r11, [r10] - CMP r11, #0 - ExitSWIHandler EQ - LDR r12, [r11, #TickNodeAddr] - CMP r12, r0 - LDREQ r12, [r11, #TickNodeR12] - CMPEQ r12, r1 - MOVNE r10, r11 - BNE %BT01 - - Push "r0-r2, lr" - MOV r2, r11 - LDR r11, [r11, #TickNodeLink] ; prev->link = this->link - STR r11, [r10] - - TEQ r11, #0 ; if next node exists - LDRNE r14, [r11, #TickNodeLeft] ; then add our time-to-go onto its - LDRNE r0, [r2, #TickNodeLeft] - ADDNE r14, r14, r0 - STRNE r14, [r11, #TickNodeLeft] - - [ ChocolateSysHeap - ASSERT ChocolateTKBlocks = ChocolateBlockArrays + 8 - MOV r1,#ChocolateBlockArrays - LDR r1,[r1,#8] - BL FreeChocolateBlock - BLVS FreeSysHeapNode - | - BL FreeSysHeapNode - ] - Pull "r0-r2, lr" - B %BT01 - -ReadMetroGnome - MOV r0, #0 - LDR r0, [r0, #MetroGnome] - ExitSWIHandler - - LTORG - - END diff --git a/s/UnSqueeze b/s/UnSqueeze deleted file mode 100644 index 9fc745ac..00000000 --- a/s/UnSqueeze +++ /dev/null @@ -1,353 +0,0 @@ -; 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. -; -; -; s.UnSqueeze by RCC 25-Aug-87 -; This is a bit of code to be included in self-decompressing images to -; expand the image in place. See elsewhere for details of the compression -; algorithm. -; -; *********************************** -; *** C h a n g e L i s t *** -; *********************************** - -; Date Name Description -; ---- ---- ----------- -; 13-Feb-90 TDobson Minor optimisation which saves 1 instruction for -; every output word that isn't a "short" or a "long". -; 15-Feb-90 TDobson Started conversion for inclusion in RISC OS kernel - -; GET Hdr:Debug - -; Constants defining partition of nibble value space: these must match -; corresponding values in mod.squeeze. - -NibsLong * 7 -NibsShort * (14-NibsLong) -MinShort * (2+NibsLong) -MinLong * 2 - -; ************************************************************************** -; -; CheckForSqueezedModule - Check whether a module is squeezed, and -; unsqueeze it if it is -; -; in: R9 -> module node -; R10 -> environment string -; R12 -> incarnation node -; -; out: R9 preserved, but module node pointed to may have code entry changed -; to point to expanded copy of module -; R10, R12 preserved -; R0-R6 may be corrupted -; -; If offset to init entry is negative, then (offset BIC &80000000) is the -; offset from the size of the encoded module. The last 5 words of this are -; as follows - - ^ -5*4 -Squeeze_DecodedSize # 4 ; size of decoded image (bytes) -Squeeze_EncodedSize # 4 ; size of encoded image (--"--) -Squeeze_TablesSize # 4 ; size of short+long tables (--"--) -Squeeze_NShorts # 4 ; number of "short" entries -Squeeze_NLongs # 4 ; number of "long" entries - ASSERT @=0 - -CheckForSqueezedModule ROUT - CLRV ; prepare for normal exit (V clear) - LDR R6, [R9, #Module_code_pointer] ; R6 -> module code - LDR R5, [R6, #Module_Init] ; R5 = offset to init entry - EORS R5, R5, #&80000000 ; take off top bit - MOVMI PC, lr ; if -ve now, then it's a normal module, so exit doing nothing - -; it's a squeezed module, R5 = size of compressed module - - Push "R6-R12,lr" ; save other registers (and pointer to module base) - -; DLINE "Unsqueezing module" - - ADD R5, R6, R5 ; R5 -> byte after end of module - LDMDB R5!, {R8-R12} ; load all the data - R8=decoded size, R9=encoded size - ; R10=tables size, R11=no. of shorts, R12=no. of longs - - SUB R10, R5, R10 ; R10 -> start (lowest address) of encoded tables - ; = highest address +1 of encoded data - SUB R9, R10, R9 ; R9 -> lowest address of encoded data - -; DREG R8, "Claiming block for module of size " - - MOV R3, R8 ; now claim a block for the expanded code - BL RMAClaim_Chunk - BVS ExpandFailed1 - -; DREG R2, "Successfully claimed block for expanded code at " - - MOV R7, R2 ; R7 -> start of expanded module - - ADD R3, R11, R12 ; R3 = no. of shorts and longs - MOV R3, R3, LSL #2 ; convert to bytes - -; DREG R3, "Claiming block for shorts+longs of size " - - BL RMAClaim_Chunk - BVS ExpandFailed2 ; must free module block before exiting! - -; DREG R2, "Successfully claimed block for shorts+longs at " - - MOV R6, R2 ; R6 -> start of expanded table of shorts+longs - - ADD R8, R7, R8 ; R8 -> highest address of decoded image +1 - -; We only need nLongs and nShorts while we are decoding the tables. -; Afterwards we will re-use the registers for pointers to start of tables. - - MOV R5, R10 ; R5 is ptr into encoded tables - MOV R4, #0 ; this is the first table el - -; DLINE "Expanding shorts+longs table" - -decodeTab - ; Require: R11 -- no of els left to decode - ; R6 -- ptr into decoded table - ; R5 -- ptr into encoding - ; R4 -- = 0 iff this is the shorts table (i.e. 4-byte vals) - -; I believe this loop could be made good deal smaller and possibly -; faster, but it's only a couple of hundred bytes and it works. - - MOV R2, R6 ; stash away base of first table - MOV R3, #-1 ; start as if previous entry was -1 -decodeEntry - SUBS R11, R11, #1 ; while (--nEntries >= 0) { - BLT decodedTab ; assert: previous word is in R3 - LDRB R1, [R5], #1 ; byte = *p++ - SUBS R0, R1, #10 - BGE greaterThan9 -literalOrOnes - CMPS R1, #0 - BNE ones -literal - LDRB R0, [R5], #1 - LDRB R1, [R5], #1 - ORR R0, R0, R1, LSL #8 - LDRB R1, [R5], #1 - ORR R0, R0, R1, LSL #16 - CMPS R4, #0 ; in the 4-byte (short encodings) table? - LDREQB R1, [R5], #1 ; yes, so include the 4th byte - ORREQ R0, R0, R1, LSL #24 ; in the resultant word - ADD R3, R3, R0 - STR R3, [R6], #4 - B decodeEntry -ones - SUB R11, R11, R1 - ADD R11, R11, #1 -anotherOne ; Have number of increment-by-ones in R1 - ADD R3, R3, #1 - STR R3, [R6], #4 - SUBS R1, R1, #1 - BGT anotherOne - B decodeEntry -greaterThan9 - CMPS R1, #92 - ADDLT R3, R3, R0 - STRLT R3, [R6], #4 - BLT decodeEntry -greaterThan91 - SUBS R0, R1, #174 - BLT oneMore -twoMore - LDRB R1, [R5], #1 - ORR R0, R1, R0, LSL #16 - LDRB R1, [R5], #1 - ORR R0, R0, R1, LSL #8 - ADD R3, R3, R0 - STR R3, [R6], #4 - B decodeEntry -oneMore - SUBS R0, R1, #92 - LDRB R1, [R5], #1 - ORR R0, R1, R0, LSL #8 - ADD R3, R3, R0 - STR R3, [R6], #4 - B decodeEntry ; } /* end while (--nEntries >= 0) { */ - -decodedTab - CMPS R4, #0 ; if isShorts then - BNE finishLongs ; else finishLongs -finishShorts - MOV R11, R12 ; no of els to decode = nLongs - MOV R12, R2 ; R12 = &shorts[0] - MOV R2, R6 ; stash away start of longs table - MOV R4, #1 ; next table is longs - B decodeTab -finishLongs - MOV R11, R2 ; R11 = &longs[0] - -; DLINE "Finished expanding shorts+longs table" - -decodedBothTabs - ; Now have: R12 = &shorts[0] - ; R11 = &longs[0] - ; R10 = highest address +1 of encoded data - ; R9 = lowest address of encoded data - ; R8 = highest address +1 of decoded data - ; - ; R0..R7 are free for workspace - -; DREG R12, "Shorts table at " -; DREG R11, "Longs table at " -; DREG R9, "Encoded data start " -; DREG R10, "Encoded data end+1 " -; DREG R8, "Decoded data end+1 " - -decodePair - CMPS R10, R9 ; Have we reached the base ? - BLE doneDecode - LDRB R6, [R10, #-1]! ; byte value - ; The words will be put in R4 and R5, to be STMDB'd - AND R3, R6, #15 ; first nibble - SUBS R0, R3, #MinShort ; idx = (val - 8) - BLT notshort0 -short0 - LDRB R1, [R10, #-1]! - ORR R0, R1, R0, LSL #8 - LDR R4, [R12, R0, LSL #2] ; w = shorts[(nibble-8)<<8 | *p--] - B gotFirst -notshort0 - SUBS R0, R3, #MinLong ; idx = (val - 2) - BLT notlong0 -long0 - LDRB R1, [R10, #-1]! - ORR R0, R1, R0, LSL #8 - LDR R0, [R11, R0, LSL #2] ; w = longs[(nibble-2)<<8 | *p--] - LDRB R1, [R10, #-1]! - ORR R4, R1, R0, LSL #8 - B gotFirst -notlong0 - MOVS R4, R3 ; TMD 13-Feb-90: combine 2 instructions here - ; used to be CMPS R3,#0; MOVEQ R4,R3 - BEQ gotFirst -literal0 - LDRB R0, [R10, #-1]! - LDRB R1, [R10, #-1]! - ORR R0, R0, R1, LSL #8 - LDRB R1, [R10, #-1]! - ORR R0, R0, R1, LSL #16 - LDRB R1, [R10, #-1]! - ORR R4, R0, R1, LSL #24 - -gotFirst - ; Phew! We have the first word of the pair (in R4), now we have - ; to do (almost) the same again, result in R5, and STMDB. - - MOV R3, R6, LSR #4 ; second nibble - SUBS R0, R3, #MinShort ; idx = (val - 8) - BLT notshort1 -short1 - LDRB R1, [R10, #-1]! - ORR R0, R1, R0, LSL #8 - LDR R5, [R12, R0, LSL #2] ; w = shorts[(nibble-8)<<8 | *p--] - STMDB R8!, {R4,R5} - B decodePair -notshort1 - SUBS R0, R3, #MinLong ; idx = (val - 2) - BLT notlong1 -long1 - LDRB R1, [R10, #-1]! - ORR R0, R1, R0, LSL #8 - LDR R0, [R11, R0, LSL #2] ; w = longs[(nibble-2)<<8 | *p--] - LDRB R1, [R10, #-1]! - ORR R5, R1, R0, LSL #8 - STMDB R8!, {R4,R5} - B decodePair -notlong1 - MOVS R5, R3 ; TMD 13-Feb-90: combine 2 instructions here - ; used to be CMPS R3,#0; MOVEQ R5,R3 - - ; This doesn't pay off much - STMEQDB R8!, {R4,R5} ; might be better to swap round - BEQ decodePair ; literal and zero, to save 3S on -literal1 ; the longer path ? - LDRB R0, [R10, #-1]! - LDRB R1, [R10, #-1]! ; If I had the right byte-sex and - ORR R0, R0, R1, LSL #8 ; a couple of registers to spare, - LDRB R1, [R10, #-1]! ; could do this in 15S instead of 22S - ORR R0, R0, R1, LSL #16 ; using the load non-aligned word code - LDRB R1, [R10, #-1]! ; given in ARM CPU Manual. - ORR R5, R0, R1, LSL #24 - STMDB R8!, {R4,R5} - B decodePair - -doneDecode - -; DREG R8, "Finished decoding, module at " - -; now R8 -> the completely unsqueezed module - -; so first, free the shorts+longs table block -; R12 -> shorts, which is first of the two - - MOV R2, R12 - -; DREG R2, "Freeing shorts+longs table at " - - BL FreeRMABlock - -; ignore any error from this - MOV R3, R8 ; save pointer to expanded module - Pull "R2,R7-R12" ; pull pointer to original module base into R2 and restore other registers - -; DREG R2, "Freeing original module block at " - - BL FreeRMABlock ; may fail because original module is in ROM, so ignore error - -; DLINE "Returning new module to OS" - - STR R3, [R9, #Module_code_pointer] ; point module node at expanded module - CLRV - Pull PC ; exit (VC) - -; come here if failed to claim block for tables - -ExpandFailed2 - -; DLINE "Failed to claim table block, freeing module block" - - Push R0 ; save original error pointer - MOV R2, R7 - BL FreeRMABlock - Pull R0 ; restore error pointer, and drop thru to ... - -; come here if failed to claim block for expanded module - -ExpandFailed1 - SETV - Pull "R6-R12, pc" ; restore registers, and exit V set - -; subroutine to free a block in RMA -; in: R2 -> block -; out: R0,R1 corrupted - -FreeRMABlock Entry -; LDR R0, [R2, #-4] -; DREG R0, "FreeRMABlock called, block size purports to be " - - MOV R0, #HeapReason_Free - MOV R1, #RMAAddress - SWI XOS_Heap - EXIT - -; InsertDebugRoutines - - END diff --git a/s/Utility b/s/Utility deleted file mode 100644 index e1c0742f..00000000 --- a/s/Utility +++ /dev/null @@ -1,1112 +0,0 @@ -; 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 => Utility - -; ***************************************************************************** -; Arthur Utility commands - -SysModules_Info ROUT ; start of ROM modules chain - & EndOfKernel-SysModules_Info - -UtilityMod - & StartSuper-UtilityMod - & 0 ; no initialisation - & Util_Die-UtilityMod - & Util_Service-UtilityMod ; code to register printer buffer with Buffer manager - & UtilModTitle-UtilityMod - & UtilHelpStr-UtilityMod - & UtilHelpTab-UtilityMod - & &F00000 - & Util_SWI-UtilityMod - & Util_SWITab-UtilityMod - & 0 - [ International_Help <> 0 - & MessageFileName-UtilityMod - | - & 0 - ] - [ :LNOT: No32bitCode - & UtilFlags-UtilityMod - ] - -Util_SWITab - = "ARM",0 - = "IMB",0 - = "IMBRange",0 - = 0 - ALIGN - -Module_BaseAddr SETA UtilityMod - - [ ChocolateService - ;service table - ; - ASSERT Service_MessageFileClosed < Service_BufferStarting - ASSERT Service_BufferStarting < Service_TerritoryStarted - ASSERT Service_TerritoryStarted < Service_DeviceFSCloseRequest - ; - -Util_ChocServTab - DCD 0 ;flags word - DCD Util_ChocService-UtilityMod ;offset to handler - [ CacheCommonErrors - DCD Service_MessageFileClosed - ] - DCD Service_BufferStarting ;service 1 - [ CacheCommonErrors - DCD Service_TerritoryStarted - ] - DCD Service_DeviceFSCloseRequest ;service 2 - DCD 0 ;terminator - DCD Util_ChocServTab-UtilityMod ;table anchor - ] -Util_Service ROUT - [ ChocolateService - MOV r0, r0 ;magic instruction for new service table format - ] - TEQ r1, #Service_BufferStarting - TEQNE r1, #Service_DeviceFSCloseRequest - [ CacheCommonErrors - TEQNE r1, #Service_TerritoryStarted - TEQNE r1, #Service_MessageFileClosed - ] - MOVNE pc, lr - [ ChocolateService - ;entry point excluding pre-rejection code -Util_ChocService - ] - [ CacheCommonErrors - TEQ r1, #Service_TerritoryStarted - TEQNE r1, #Service_MessageFileClosed - BEQ CacheCommonErrorsReinit - ] - TEQ r1, #Service_BufferStarting - BNE %FT10 - Push "r0-r3,lr" - -; Register buffers with buffer manager in order of speed - first is fast - - [ MouseBufferManager - MOV r0, #BufferFlags_GenerateInputFull - LDR r1, =MouseBuff - LDR r2, =MouseBuff + MouseBuffSize - MOV r3, #Buff_Mouse - SWI XBuffer_Register ; register mouse input buffer - ] - MOV r0, #BufferFlags_GenerateInputFull :OR: BufferFlags_SendThresholdUpCalls - LDR r1, =RS423InBuff - LDR r2, =RS423InBuff + RS423InBuffSize - MOV r3, #Buff_RS423In - SWI XBuffer_Register ; register serial input buffer - - MOV r0, #BufferFlags_GenerateOutputEmpty - LDR r1, =RS423OutBuff - LDR r2, =RS423OutBuff + RS423OutBuffSize - MOV r3, #Buff_RS423Out - SWI XBuffer_Register ; register serial output buffer - - MOV r0, #0 ; used as index to PrinterBufferThing - LDR r1, [r0, #PrinterBufferAddr] ; r1 -> start of buffer - LDR r2, [r0, #PrinterBufferSize] ; r2 = size - ADD r2, r2, r1 ; r2 -> end+1 of buffer - MOV r3, #Buff_Print - MOV r0, #BufferFlags_GenerateOutputEmpty - SWI XBuffer_Register ; register the MOS's printer buffer - - Pull "r0-r3,pc" - -; service DeviceFSCloseRequest -; in: r2 = handle we are requested to close -; if r2 = PrinterActive (word) or SerialInHandle (byte) or SerialOutHandle (byte) -; then zero appropriate variable and close file, then claim service -; NB there is a disadvantage to doing it for SerialInHandle, in that it won't get -; opened again, but we assume they accidentally left it in an fx2,2 state -; - -10 - Push "r0,r1,lr" - MOV r0, #0 - LDR r1, [r0, #OsbyteVars + :INDEX: PrinterActive] - TEQ r1, r2 - STREQ r0, [r0, #OsbyteVars + :INDEX: PrinterActive] - BEQ %FT20 - LDRB r1, [r0, #OsbyteVars + :INDEX: SerialInHandle] - TEQ r1, r2 - STREQB r0, [r0, #OsbyteVars + :INDEX: SerialInHandle] - BEQ %FT20 - LDRB r1, [r0, #OsbyteVars + :INDEX: SerialOutHandle] - TEQ r1, r2 - Pull "r0,r1,pc",NE ; if not any of these then exit preserving everything - STRB r0, [r0, #OsbyteVars + :INDEX: SerialOutHandle] -20 - SWI XOS_Find ; close file, ignore errors (if we get an error it's closed anyway) - MOV r1, #Service_Serviced ; indicate we closed it - Pull "r0,lr,pc" ; restore r0, junk r1, and exit - - -Util_Die ROUT - CMP R10, #0 - MOVEQ PC, lr ; non-fatal : can cope - ADR R0, %FT01 - [ International - Push "lr" - BL TranslateError - Pull "pc" - | - RETURNVS - ] - -01 - & ErrorNumber_CantKill - [ International - = "CantKill", 0 - | - = "Deleting the utility module is foolish", 0 - ] - - -UtilModTitle = "UtilityModule", 0 - -UtilHelpStr = "MOS Utilities", 9, "$VersionNo", 0 - - [ Oscli_HashedCommands -; -;***WARNING*** if commands are added or changed, UtilHashedCmdTab MUST be updated correspondingly -; - ] -UtilHelpTab - Command Break, 0, 0, International_Help ; just help - Command ChangeDynamicArea,255, 0, International_Help - Command Configure, 255, 0, Help_Is_Code_Flag :OR: International_Help - Command Commands, 0, 0, Help_Is_Code_Flag :OR: International_Help - Command Echo, 255, 0, International_Help - Command Error, 255, 1, International_Help - Command Eval, 255, 1, International_Help - Command FileCommands, 0, 0, Help_Is_Code_Flag :OR: International_Help - Command GOS, 0, 0, International_Help - Command IF, 255, 2, International_Help - Command Ignore, 1, 0, International_Help - Command Modules, 0, 0, Help_Is_Code_Flag :OR: International_Help - Command PowerOn, 0, 0, International_Help ; just help - Command Reset, 0, 0, International_Help ; just help - Command RMClear, 0, 0, International_Help - Command RMEnsure, 255, 2, International_Help - Command RMFaster, 1, 1, International_Help - Command RMInsert, 2, 1, International_Help - Command RMKill, 1, 1, International_Help - Command RMLoad, 255, 1, International_Help - Command RMReInit, 255, 1, International_Help - Command RMRun, 255, 1, International_Help - Command RMTidy, 0, 0, International_Help - Command ROMModules, 0, 0, International_Help - Command Set, 255, 2, International_Help - Command SetEval, 255, 2, International_Help - Command SetMacro, 255, 2, International_Help - Command Show, 1, 0, International_Help ; *show = *show * - Command Status, 255, 0, International_Help - Command Syntax, 0, 0, International_Help - Command Time, 0, 0, International_Help - Command Unplug, 2, 0, International_Help - Command Unset, 1, 1, International_Help - = 0 - - [ Oscli_HashedCommands -; -; - Hashing table is 32 wide -; - Hashing function is: -; -; hash = (sum of all chars of command, each upper-cased) & 0x1f -; -; - Order of commands in each hashed list is chosen as 'most common' first - -; Table MUST be reorganised if hashing function changed, or command set altered -; - ALIGN -UtilHashedCmdTab -; -; ! 0,"UtilHashedCmdTab at ":CC::STR:(UtilHashedCmdTab) -; -;First, 1 word per table entry, giving offset to hashed list on each hash value -; - DCD 0 ;null list on this hash value - DCD UHC_hash01 - UtilityMod - DCD UHC_hash02 - UtilityMod - DCD 0 - DCD UHC_hash04 - UtilityMod - DCD 0 - DCD UHC_hash06 - UtilityMod - DCD UHC_hash07 - UtilityMod - DCD UHC_hash08 - UtilityMod - DCD UHC_hash09 - UtilityMod - DCD UHC_hash0A - UtilityMod - DCD UHC_hash0B - UtilityMod - DCD UHC_hash0C - UtilityMod - DCD 0 - DCD 0 - DCD UHC_hash0F - UtilityMod - DCD 0 - DCD UHC_hash11 - UtilityMod - DCD 0 - DCD 0 - DCD UHC_hash14 - UtilityMod - DCD 0 - DCD 0 - DCD 0 - DCD 0 - DCD UHC_hash19 - UtilityMod - DCD 0 - DCD UHC_hash1B - UtilityMod - DCD 0 - DCD 0 - DCD UHC_hash1E - UtilityMod - DCD UHC_hash1F - UtilityMod -; -; Now the hashed lists -; -UHC_hash01 - Command Show, 1, 0, International_Help - = 0 - ALIGN -UHC_hash02 - Command Configure, 255, 0, Help_Is_Code_Flag :OR: International_Help - = 0 - ALIGN -UHC_hash04 - Command ChangeDynamicArea,255, 0, International_Help - Command RMFaster, 1, 1, International_Help - Command Status, 255, 0, International_Help - Command Ignore, 1, 0, International_Help - = 0 - ALIGN -UHC_hash06 - Command RMClear, 0, 0, International_Help - = 0 - ALIGN -UHC_hash07 - Command ROMModules, 0, 0, International_Help - = 0 - ALIGN -UHC_hash08 - Command Eval, 255, 1, International_Help - = 0 - ALIGN -UHC_hash09 - Command GOS, 0, 0, International_Help - = 0 - ALIGN -UHC_hash0A - Command RMReInit, 255, 1, International_Help - Command Error, 255, 1, International_Help - = 0 - ALIGN -UHC_hash0B - Command RMKill, 1, 1, International_Help - = 0 - ALIGN -UHC_hash0C - Command Set, 255, 2, International_Help - = 0 - ALIGN -UHC_hash0F - Command IF, 255, 2, International_Help - Command Unset, 1, 1, International_Help - Command Time, 0, 0, International_Help - = 0 - ALIGN -UHC_hash11 - Command RMEnsure, 255, 2, International_Help - = 0 - ALIGN -UHC_hash14 - Command SetEval, 255, 2, International_Help - Command RMRun, 255, 1, International_Help - Command RMInsert, 2, 1, International_Help - = 0 - ALIGN -UHC_hash19 - Command Modules, 0, 0, Help_Is_Code_Flag :OR: International_Help - Command RMTidy, 0, 0, International_Help - = 0 - ALIGN -UHC_hash1B - Command Unplug, 2, 0, International_Help - = 0 - ALIGN -UHC_hash1E - Command SetMacro, 255, 2, International_Help - = 0 - ALIGN -UHC_hash1F - Command RMLoad, 255, 1, International_Help - Command Echo, 255, 0, International_Help - = 0 - ALIGN - - ] ;Oscli_HashedCommands - -Configure_Syntax * Module_BaseAddr -Commands_Code * Module_BaseAddr -Commands_Syntax * Module_BaseAddr -Syntax_Code * Module_BaseAddr -Syntax_Syntax * Module_BaseAddr -Echo_Syntax * Module_BaseAddr -Status_Syntax * Module_BaseAddr -FileCommands_Code * Module_BaseAddr -FileCommands_Syntax * Module_BaseAddr -Reset_Code * Module_BaseAddr -Reset_Syntax * Module_BaseAddr -Break_Code * Module_BaseAddr -Break_Syntax * Module_BaseAddr -PowerOn_Code * Module_BaseAddr -PowerOn_Syntax * Module_BaseAddr - -RMFaster_Code - Push "lr" - MOV R1, R0 - MOV R0, #ModHandReason_LookupName - SWI XOS_Module - Pull "PC", VS - CMP R3, #ROM ; HS if R3 >= ROM - BLO RMFast_notinROM - [ :LNOT:ROMatTop - CMP R3, #ROMLimit - BHS RMFast_notinROM - ] - MOV R1, R3 - LDR R2, [R1, #-4] - MOV R0, #ModHandReason_CopyArea - SWI XOS_Module - Pull PC - -RMFast_notinROM - ADRL R0, ErrorBlock_RMNotFoundInROM - [ International - BL TranslateError - ] - Pull lr - RETURNVS - -RMKill_Code - MOV R6, #ModHandReason_Delete - -Rmcommon Push "lr" - MOV r1, r0 - MOV r0, r6 - SWI XOS_Module - Pull "PC" - -RMLoad_Code - MOV R6, #ModHandReason_Load - B Rmcommon - -RMRun_Code - MOV R6, #ModHandReason_Run - B Rmcommon - -RMTidy_Code - MOV R6, #ModHandReason_Tidy - B Rmcommon - -RMClear_Code - MOV R6, #ModHandReason_Clear - B Rmcommon - -RMReInit_Code - MOV R6, #ModHandReason_ReInit - B Rmcommon - -Modules_Help ROUT - Push "r2, r3, lr" - MOV r0, #0 ; Try our own message file before Global. - LDR r0, [r0, #KernelMessagesBlock] - TEQ r0, #0 - ADRNE r0, KernelMessagesBlock+4 - ADRL r1, modules_help1 - MOV r2, #0 - SWI XMessageTrans_Lookup - SWIVC XMessageTrans_Dictionary - MOVVC r1, r0 - MOVVC r0, r2 - SWIVC XOS_PrettyPrint - Pull "r2, r3, PC", VS - MOV R1, #Module_List -03 LDR R1, [R1] - CMP R1, #0 - BEQ %FT05 - LDR R0, [R1, #Module_code_pointer] - BL PrintTitle - BVC %BT03 -05 MOVVC R0, #0 - Pull "r2, r3, PC" - -PrintTitle ; of module at R0 : corrupts R0 - Push "R1, lr" - LDR R1, [R0, #Module_HelpStr] - CMP R1, #0 - ADREQ R0, NoRIT - [ International - BLEQ Write0_Translated - ADDNE R0, R1, R0 - SWINE XOS_PrettyPrint - | - ADDNE R0, R1, R0 - SWI XOS_PrettyPrint - ] - SWIVC XOS_NewLine - Pull "R1, PC" - -Modules_Code ROUT - Push "R7, lr" - - [ International - BL WriteS_Translated - = "Modules:No. Position Workspace Name", 10, 13, 0 - ALIGN - | - SWI XOS_WriteS - = "No. Position Workspace Name", 10, 13, 0 - ALIGN - ] - Pull "R7, PC", VS - - MOV R1, #0 - MOV R2, #0 - MOV R6, #0 - MOV R7, #0 -06 - SWI XOS_ReadEscapeState - Pull "R7, lr", CS - BCS AckEscape - MOV R0, #ModHandReason_GetNames - SWI XOS_Module - BVC %FT07 - CLRV - Pull "R7, pc" ; back, clearing V - -07 - Push "R1, R2" - CMP R6, #0 - MOVNE R1, #0 - BNE %FT02 - ADD R7, R7, #1 - MOV R0, R7 - LDR R1, =GeneralMOSBuffer - MOV R2, #256 - SWI XOS_ConvertCardinal2 - SUB R1, R1, R0 ; characters in buffer -02 CMP R1, #3 - SWILT XOS_WriteI+" " - BVS %FT03 - ADDLT R1, R1, #1 - BLT %BT02 -03 - Pull "R1, R2" - BVS %FT04 - CMP R6, #0 - SWIEQ XOS_Write0 - SWIVC XOS_WriteI+" " - MOV R0, R3 - BLVC HexR0LongWord - SWIVC XOS_WriteI+" " - MOV R0, R4 - BLVC HexR0LongWord - SWIVC XOS_WriteI+" " - SWIVC XOS_WriteI+" " - BLVC %FT01 ; title out - SWIVC XOS_NewLine - BVC %BT06 -04 - Pull "R7, PC" -01 - Push "lr" - LDR R0, [R3, #Module_Title] - CMP R0, #0 - ADDNE R0, R3, R0 - ADREQ R0, NoRIT - [ International - BLEQ Write0_Translated - SWINE XOS_Write0 - | - SWI XOS_Write0 - ] - Pull "PC", VS - CMP R6, #0 - CMPEQ R2, #0 - MOV R6, R2 - Pull "PC", EQ ; only one incarnation - SWI XOS_WriteI + Postfix_Separator - MOV R0, R5 - SWIVC XOS_Write0 - Pull "PC" - - [ International -NoRIT = "Untitled:<Untitled>", 0 - | -NoRIT = "<Untitled>", 0 - ] -starstr = "*", 13 - ALIGN - - - -Show_Code - CMP r1, #0 ; *show only? - ADREQ r0, starstr - Entry "r0,r7",8+256 - MRS r7, CPSR - - ADD r6, sp, #8 ; initial buffer for var expansions - MOV lr, #256+4 - STR lr, [sp, #4] ; fake heap block size - MOV lr, #&ffffffff - STR lr, [sp, #0] ; inhibit page mode off on exit - - ; Read current VDU status and save it away - MOVVC r0, #117 - SWIVC XOS_Byte - STRVC R1, [sp, #0] - SWIVC XOS_WriteI+14 ; paged mode on. - BVS ShowBang - - MOV r3, #0 ; enumeration pointer -01 - LDR r0, [sp, #Proc_RegOffset + 0*4] ; wildcard -10 - MOV r1, r6 ; 'heap' block - LDR r2, [r6, #-4] ; block size - SUB r2, r2, #4 - MOV r4, #0 ; no expansion - SWI XOS_ReadVarVal - BVS Show_ErrorReading - - ; Varname - MOV r0, r3 - SWI XOS_Write0 - BVS ShowBang - - ; (Number) or (Macro) as appropriate - CMP R4, #VarType_String - BEQ skipvalprt - [ :LNOT: International - SWI XOS_WriteS - = " (", 0 - ALIGN - BVS ShowBang - ] - CMP R4, #VarType_Number - MOVEQ R2, #256 - LDREQ R0, [R1] - SWIEQ XOS_BinaryToDecimal - ADREQ R0, %FT02 - ADRHI R0, %FT03 - [ International - BLVC Write0_Translated - | - SWIVC XOS_Write0 - SWIVC XOS_WriteI+")" - ] - BVS ShowBang -skipvalprt - ; " : " - SWI XOS_WriteS - = " : ", 0 - ALIGN - BVS ShowBang - - ; Now output the value's value - MOV R5, #-1 -05 ADD R5, R5, #1 - CMP R5, R2 - BEQ %FT06 - SWI XOS_ReadEscapeState - BLCS AckEscape - BVS ShowBang - LDRB R0, [R1, R5] - CMP R0, #&7F - MOVEQ R0, #"?"-"@" - CMP R0, #31 - ADDLE R0, R0, #"@" - SWILE XOS_WriteI+"|" - BVS ShowBang - - CMP R0, #"|" - CMPNE R0, #"""" - CMPNE R0, #"<" - SWINE XOS_WriteC - BVS ShowBang - BNE %BT05 - - CMP R4, #VarType_Macro - SWINE XOS_WriteI+"|" - SWIVC XOS_WriteC - BVC %BT05 -ShowBang - STR r0, [sp, #Proc_RegOffset + 0*4] - ORR r7, r7, #V_bit ; CPSR in - -Show_Exit - ; Release buffer if necessary - ADD lr, sp, #8 ; stack buffer - TEQ r6, lr - MOVNE r0, #ModHandReason_Free - MOVNE r2, r6 - SWINE XOS_Module - - ; Switch paged mode off if necessary - LDR lr, [sp, #0] - TST lr, #5 - SWIEQ XOS_WriteI+15 ; paged mode off - - MSR CPSR_f, r7 - EXIT - -06 SWI XOS_NewLine - BVS ShowBang - B %BT01 - - [ International -02 - = "Number:(Number)", 0 -03 - = "Macro:(Macro)", 0 - | -02 - = "Number", 0 -03 - = "Macro", 0 - ] - ALIGN - -Show_ErrorReading - ; Error from OS_ReadVarVal: - ; VarCantFind - end of *show - ; BuffOverflow - try and extend buffer - ; other - return as error - LDR r5, [r0] - LDR lr, =ErrorNumber_VarCantFind - TEQ r5, lr - BEQ Show_Exit - LDR lr, =ErrorNumber_BuffOverflow - TEQ r5, lr - BNE ShowBang - - ; try and extend the buffer - CLRV - MOV r1, r3 ; actual name so retry gets this node exactly - ADD lr, sp, #8 ; stack buffer - TEQ r6, lr - MOV r0, #ModHandReason_Free - MOV r2, r6 - MOV r6, lr ; to prevent any attempt at freeing in ShowBang - SWINE XOS_Module - BVS ShowBang - - MOV r0, r1 - MOV r1, #ARM_CC_Mask - MOV r2, #-1 ; To sence size - MOV r3, #0 ; 1st var - MOV r4, #0 ; unexpanded - SWI XOS_ReadVarVal - CLRV ; error will be buffer overflow - MOV r1, r3 ; varname again - MVN r3, r2 - ADD r3, r3, #&ff ; round up to 256 byte boundary - BIC r3, r3, #&ff - MOV r0, #ModHandReason_Claim - SWI XOS_Module - BVS ShowBang - MOV r6, r2 - MOV r0, r1 - MOV r3, #0 ; restart from that node - B %BT10 - -Set_Code ROUT - MOV R4, #VarType_String -01 - Push "lr" - - ; space terminated name in R0 - - ; Skip name in R1 - MOV R1, R0 -02 LDRB R2, [R1], #1 - CMP R2, #" " - BNE %BT02 - - ; Then skip spaces -03 LDRB R2, [R1], #1 - CMP R2, #" " - BEQ %BT03 - SUB R1, R1, #1 - - ; r2 +ve to set, r3 = 0 for 1st var - MOV R2, #1 - MOV R3, #0 - SWI XOS_SetVarVal - Pull "PC" - - LTORG - -SetMacro_Code MOV R4, #VarType_Macro - B %BT01 - -SetEval_Code MOV R4, #VarType_Expanded - B %BT01 - -Unset_Code ROUT - Push "lr" - MOV R2, #-1 - MOV R3, #0 -01 SWI XOS_SetVarVal - BVC %BT01 - CLRV - Pull "pc" - -Echo_Code ROUT - Push "lr" - MOV R2, #GS_NoQuoteMess - SWI XOS_GSInit -01 SWI XOS_GSRead - BVS %FT02 - MOVCC R3, R0 - MOVCC R0, R1 - SWICC XOS_WriteC - BVS %FT02 - MOVCC R0, R3 - BCC %BT01 - SWI XOS_NewLine -02 - Pull "PC" - -Commands_Help ROUT - Push "R0, lr" ; keep buffer pointer - ADRL R0, commands_helpstr - MOV R1, #0 -KeyHelpCommon ; also used by *Configure - Push r1 -; R2 & R3 can be junked here? - MOV r1, r0 - MOV r0, #0 ; Try our own message file before Global. - LDR r0, [r0, #KernelMessagesBlock] - TEQ r0, #0 - ADRNE r0, KernelMessagesBlock+4 - MOV r2, #0 - SWI XMessageTrans_Lookup - SWIVC XMessageTrans_Dictionary - MOVVC r1, r0 - MOVVC r0, r2 - SWIVC XOS_PrettyPrint - Pull "r1,lr,PC", VS ; if error, pull R1, junk stacked R0 and exit - Pull "r1,r3" ; restore r1 and get buffer pointer - MOV r0, #0 - ADRL R2, SysCommsModule - BL OneModuleK - BVS %FT10 - MOV R6, #Module_List -12 LDR R6, [R6] - CMP R6, #0 - BEQ %FT10 - LDR R2, [R6, #Module_code_pointer] - BL OneModuleK - BVC %BT12 -10 MOVVC R0, #0 - Pull "PC" - -FileCommands_Help - Push "R0, lr" - ADRL R0, fscommands_helpstr - MOV R1, #FS_Command_Flag - B KeyHelpCommon - -; take module code pointer in r2 -; flags in r1 -; HelpBufferSize buffer in r3 -; string to print in r0 - -OneModuleK ROUT - Push "r2-r7, lr" - LDR R4, [R2, #Module_HC_Table] - CMP R4, #0 - Pull "r2-r7, PC", EQ ; no table - MOV R7, #&80000000 ; flag - MOV R5, #0 ; buffer offset - - ADD R2, R2, R4 ; point at table start. -03 MOV R6, R2 - LDRB R4, [R2] - CMP R4, #0 - BEQ %FT06 - -04 LDRB R4, [R6], #1 - CMP R4, #0 - BNE %BT04 - ADD lr, R6, #3 - BIC lr, lr, #3 ; align but leave r6 at end of command for below (05) - LDR R4, [lr, #0] ; code offset - CMP r1, #-1 ; fudge? - BEQ %FT78 - CMP R4, #0 - ADDEQ R2, lr, #16 - BEQ %BT03 - LDRB R4, [lr, #7] - BIC R4, R4, #(Help_Is_Code_Flag:OR:International_Help) :SHR: 24 - CMP R4, R1, LSR #24 ; move flags into bottom byte -79 ADDNE R2, lr, #16 - BNE %BT03 - TST R7, #&80000000 - BEQ %FT05 - SWI XOS_NewLine - SWIVC XOS_NewLine - BVS %FT77 - MOV r4, r0 - CMP r0, #0 - BEQ OneModuleK_PrintTitle ; Don't trust MessageTrans to preserve Z - SWI XMessageTrans_Dictionary - STMDB sp!, {r1} - MOVVC r1, r0 - MOVVC r0, r4 - SWIVC XOS_PrettyPrint - LDMIA sp!, {r1} - B %FT77 -OneModuleK_PrintTitle - LDR r0, [stack] - BL PrintTitle -77 - MOVVC r0, r4 - Pull "r2-r7, PC", VS - BIC R7, R7, #&80000000 -05 - SUB lr, r6, r2 - RSB r4, r5, #HelpBufferSize - CMP r4, lr ; have we got enough space for command+tab - BCS %FT07 - MOV r4, #0 ; no, so 0 terminate what we've got and print it - SUB r5, r5, #1 ; write 0 over trailing tab - STRB r4, [r3, r5] - MOV r4, r0 - MOV r0, r3 - SWI XOS_PrettyPrint - SWIVC XOS_NewLine - Pull "r2-r7,pc",VS - MOV r0, r4 - MOV r5, #0 ; start again with empty buffer -07 - LDRB r4, [r2], #1 ; copy command - CMP r4, #0 - STRNEB r4, [r3, r5] - ADDNE r5, r5, #1 - BNE %BT07 - MOV r4, #TAB ; add tab - STRB r4, [r3, r5] - ADD r5, r5, #1 - ADD r2, r2, #3+16 ; align and move on to next command - BIC r2, r2, #3 - B %BT03 - -78 CMP r4, #0 - B %BT79 - -06 TST R7, #&80000000 - Pull "r2-r7, PC", NE - Push "R0" - MOV R0, #0 - SUB R5, R5, #1 - STRB R0, [R5, R3] - MOV R0, R3 - SWI XOS_PrettyPrint - STRVS r0, [stack] - Pull "R0, r2-r7, PC" - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -GOS_Code - Push lr - MOV r2, r0 - addr R1, UtilModTitle - MOV R0, #ModHandReason_Enter - SWI XOS_Module - Pull pc - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -; Deal with UtilityModule SWIs. -; -; The UtilityModule provides "OS-independent" SWIs. At present these are: -; -; SWI &F00000 (ARM_IMB) -; SWI &F00001 (ARM_IMBRange) -; -; as specified by the ARMv5 ARM (section 2.7.4 Prefetching and self-modifying -; code) - -Util_SWI - CMP r11, #1 - BLO SyncCodeAreasFull ; (00) will do tail-call return from SWI - BHI Util_SWINotKnown ; (02..3F) - -; Ranged wotsit (01) - Push "r1,r2,lr" - SUB r2, r1, #4 ; convert from exclusive to inclusive - MOV r1, r0 - BL SyncCodeAreasRange - Pull "r1,r2,pc" - -Util_SWINotKnown - ADR r0, ErrorBlock_ModuleBadSWI - [ International - addr r4, UtilModTitle - B TranslateError_UseR4 - | - RETURNVS - ] - - MakeErrorBlock ModuleBadSWI - -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -; ChangeDynamicArea - moved here from the Task Manager as embedded devices -; tend not to have the Task Manager -; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -rmaarea * 1 ; RMA area -screenarea * 2 ; screen area -spritearea * 3 ; sprite area -fontarea * 4 ; font cache dynamic area number -ramfsarea * 5 ; RAM disc area - - ^ 0 -vec_fontsize # 4 ; fields in output vector -vec_spritesize # 4 -vec_ramfssize # 4 -vec_rmasize # 4 -vec_screensize # 4 -ss_outputvec * &100 - -Keydef DCB "FontSize/K,SpriteSize/K,RamFSSize/K,RMASize/K,ScreenSize/K" - DCB 0 - ALIGN - -; NB: R12 -> private word (don't use workspace, as it may not be present) - -ChangeDynamicArea_Code ROUT - Push "R11,LR" - MOV R11,sp ; remember stack for later -; - SUB sp,sp,#ss_outputvec ; local workspace -; -; scan the comand line by calling OS_ReadArgs -; - MOV R1,R0 ; R1 = input string - ADR R0,Keydef ; R0 = key defion string - MOV R2,sp ; R2 = output vector - MOV R3,#ss_outputvec ; R3 = max output vector length - SWI XOS_ReadArgs -; -; scan the resulting vector for known fields -; - MOVVC R0,#rmaarea - LDRVC R1,[sp,#vec_rmasize] - BLVC changeR0R1 ; R0 = area number, R1 = size required - - MOVVC R0,#screenarea - LDRVC R1,[sp,#vec_screensize] - BLVC changeR0R1 ; R0 = area number, R1 = size required - - MOVVC R0,#fontarea - LDRVC R1,[sp,#vec_fontsize] - BLVC changeR0R1 ; R0 = area number, R1 = size required - - MOVVC R0,#spritearea - LDRVC R1,[sp,#vec_spritesize] - BLVC changeR0R1 ; R0 = area number, R1 = size required - - MOVVC R0,#ramfsarea ; NB: do RAMFS last so others get done if it fails - LDRVC R1,[sp,#vec_ramfssize] - BLVC changeR0R1 ; R0 = area number, R1 = size required - - MOV sp,R11 ; restore stack - Pull "R11,PC" - -; In R0 = dynamic area number -; R1 -> string specifying size required (<=0 => don't bother) -; Out calls OS_ChangeDynamicArea, which gives Service_MemoryMoved -; this is intercepted, and sets [memoryupdated] -; this causes a pollword event: -; which calls set_memory for all memory slots -; if the RAM disc slot size changes to/from 0 -; [ramfsflag] is set -; unless dragging the ram slot bar: -; reramfsfiler re-ialises the RAMFSFiler -; otherwise it waits till the bar is dropped - -changeR0R1 ROUT - Push "R0-R3,LR" - - CMP R1,#0 - Pull "R0-R3,PC",EQ - - SWI XOS_ReadDynamicArea ; R1 = current size of area - MOVVC R3,R1 - - LDRVC R1,[sp,#1*4] - BLVC getK ; R1 = new amount required - - LDRVC R0,[sp,#0*4] - SUBVC R1,R1,R3 ; R1 = change required - SWIVC XOS_ChangeDynamicArea - - STRVS R0,[sp] - Pull "R0-R3,PC" - - -; In R1 --> string -; Out R1 = parameter value (number) -; Errors: "Bad number" -; - -getK ROUT - Push "R2-R3,LR" -; - MOV R0,#10 - SWI XOS_ReadUnsigned - Pull "R2-R3,PC",VS -; - LDRB R3,[R1] - UpperCase R3, R14 - TEQ R3,#"K" ; if terminator is "K" or "k", - ADDEQ R1,R1,#1 - MOVEQ R2,R2,LSL #10 ; multiply by 1024 - TEQ R3,#"M" ; if terminator is "M" or "m", - ADDEQ R1,R1,#1 - MOVEQ R2,R2,LSL #20 ; multiply by 1048576 - TEQ R3,#"G" ; if terminator is "G" or "g", - ADDEQ R1,R1,#1 - MOVEQ R2,R2,LSL #30 ; multiply by 1073741824 -; - LDRB R14,[R1] ; check terminator - RSBS R14,R14,#" "+1 ; ensure GT set if OK - ADRLEL R0,ErrorBlock_BadNumb ; "Number not recognised" - [ International - BLLE TranslateError - ] -; - MOVVC R1,R2 ; R1 = answer - Pull "R2-R3,PC" - - - [ :LNOT: No32bitCode -UtilFlags DCD ModuleFlag_32bit - ] - - END diff --git a/s/vdu/vdu23 b/s/vdu/vdu23 deleted file mode 100644 index 84e68a7a..00000000 --- a/s/vdu/vdu23 +++ /dev/null @@ -1,1700 +0,0 @@ -; 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.Vdu23 - -; ***************************************************************************** -; -; DefineChar - define soft character -; -; in: R0 = char to be defined -; - -DefineChar - ADD R1, WsPtr, #(Font-32*8) - ADD R1, R1, R0, LSL #3 ; point to char definition - - ADD R2, WsPtr, #QQ+1 - LDMIA R2, {R2, R3} ; load 8 bytes - STMIA R1, {R2, R3} ; store 8 bytes -Nop - MOV PC, R14 - -; ***************************************************************************** -; -; VDU 23,7,m,d,z| - Scroll window directly -; -; m=0 Scroll text window -; m=1 Scroll entire screen -; -; d=0 Scroll right -; d=1 Scroll left -; d=2 Scroll down -; d=3 Scroll up -; d=4 Scroll "right" -; d=5 Scroll "left" -; d=6 Scroll "down" -; d=7 Scroll "up" -; -; z=0 Scroll by 1 character cell -; z=1 Scroll by 1 char vertically, 1 byte (whatever that is) horiz. -; - -Vdu23_7 ROUT - LDRB R0, [WsPtr, #QQ+1] ; R0 := m - LDRB R1, [WsPtr, #QQ+2] ; R1 := d - LDRB R2, [WsPtr, #QQ+3] ; R2 := z -Scroll012 - LDR R6, [WsPtr, #CursorFlags] - AND R1, R1, #7 ; ignore higher bits - CMP R1, #4 - BCC %FT10 - LDR R4, ScrollDirWord - CMP R1, #6 - MOVCS R4, R4, ROR #16 - AND R3, R6, #&0E - MOV R3, R3, LSL #1 - MOV R4, R4, LSR R3 - MOVS R1, R1, LSR #1 - AND R1, R4, #&0F - EORCS R1, R1, #1 -10 - Push R14 - TST R6, #ClipBoxEnableBit ; if calculating clip box - BLNE ClipScroll ; then add text window or whole screen - CMP R0, #1 ; C=1 => whole screen - ADC R1, R1, R1 ; put m into bit 0 - TEQ R2, #0 - ORRNE R1, R1, #&08 ; put z into bit 3 - ADR R0, ScrollTab - LDR R2, [R0, R1, LSL #2] - ADR R14, ScrollRetn - ADD PC, R0, R2 ; carry on entry is m - -ScrollRetn - Pull R14 - -; insert code here to re-address input cursor as well - - B AddressCursors ; re-address cursor positions - -ScrollDirWord - & &33221010 - -ScrollTab - & ScrollRightChar-ScrollTab ; window right char - & ScrollRightChar-ScrollTab ; screen right char - & ScrollLeftChar-ScrollTab ; window left char - & ScrollLeftChar-ScrollTab ; screen left char - & ScrollDown-ScrollTab ; window down char - & HardScrollDown-ScrollTab ; screen down char - & ScrollUp-ScrollTab ; window up char - & HardScrollUp-ScrollTab ; screen up char - & ScrollRightByte-ScrollTab ; window right byte - & ScrollRightByte-ScrollTab ; screen right byte - & ScrollLeftByte-ScrollTab ; window left byte - & ScrollLeftByte-ScrollTab ; screen left byte - & ScrollDown-ScrollTab ; window down byte - & HardScrollDown-ScrollTab ; screen down byte - & ScrollUp-ScrollTab ; window up byte - & HardScrollUp-ScrollTab ; screen up byte - - -; ***************************************************************************** -; -; VDU 23,17,c,t| - Set tint -; -; c=0 Set text foreground tint (default &FF) -; c=1 Set text background tint (default &00) -; c=2 Set graphics foreground tint (default &FF) -; c=3 Set graphics background tint (default 0) -; c=4 t=0 => BBC compatible ECFs, t=1 => native ECFs (default 0) -; c=5 Swap foreground and background text colours/tints -; c=6 VDU 23,17,6,x;y; - Set ECF origin to (x,y) -; c=7 VDU 23,17,7,flags,x;y;0,0 - Set character size(s) -; c=8-255 Reserved -; -; t=tint Only bits 6,7 relevant with this hardware - -Vdu23_17 - LDRB R0, [WsPtr, #QQ+1] ; get c - CMP R0, #7 - MOVHI R0, #17 ; if unknown (>7), reload R0 - BHI UnknownVdu23 ; and call UKVDU23 vector - BEQ SetCharSizes - - CMP R0, #6 - BEQ SetECFOrigin - - CMP R0, #4 - BHI SwapColours ; 5 => swap colours - - LDRB R1, [WsPtr, #QQ+2] ; tint or BBC parm - STREQ R1, [WsPtr, #BBCcompatibleECFs] ; VDU 23,17,4,t... - MOVEQ PC, R14 - - ADD R2, WsPtr, #TFTint - LDR R3, [R2, R0, LSL #2] ; get old tint - STR R1, [R2, R0, LSL #2] - - CMP R0, #2 ; graphics tint ? - BCS SetColour ; then update masks - - EOR R1, R1, R3 - TST R1, #&C0 ; are top two bits different ? - MOVEQ PC, R14 ; no need to redo table - - ; amg: use R1 here instead of 'bpp' which is R0. I need R0 in a moment. - LDR R1, [WsPtr, #BitsPerPix] - CMP R1, #8 ; are we in 8 bits-per-pixel or more? - MOVCC PC, R14 ; no, then exit - - Push "lr" - - ; amg: only do foreground or background as appropriate - CMP R0,#1 - BEQ %FT05 - BL CompileTextFg - B %FT10 -05 - BL CompileTextBg ; update TextFgColour/TextBgColour -10 - Pull "lr" - -SetColoursDirty - LDR R6, [WsPtr, #CursorFlags] - ORR R6, R6, #TEUpdate ; yes, then set colours dirty - STR R6, [WsPtr, #CursorFlags] - MOV PC, R14 - -; ***************************************************************************** - -SwapColours ROUT - LDR R1, [WsPtr, #TForeCol] - LDR R2, [WsPtr, #TBackCol] - STR R1, [WsPtr, #TBackCol] - STR R2, [WsPtr, #TForeCol] - - LDR R1, [WsPtr, #TextFgColour] - LDR R2, [WsPtr, #TextBgColour] - STR R1, [WsPtr, #TextBgColour] - STR R2, [WsPtr, #TextFgColour] - - LDR R3, [WsPtr, #BitsPerPix] - CMP R3, #8 ; C=1 <=> 256 colour mode - BCC %FT10 ; [not 256 colour mode] - - LDR R1, [WsPtr, #TFTint] - LDR R2, [WsPtr, #TBTint] - STR R1, [WsPtr, #TBTint] - STR R2, [WsPtr, #TFTint] -10 - B SetColoursDirty ; don't bother optimising the case - ; when both colours are the same - -; ***************************************************************************** -; -; SetECFOrigin - Set the origin of the ECF pattern -; -; Called by VDU 23,17,6,x;y;0,0,0 -; -; in: QQ+2, QQ+3 = xlo, xhi -; QQ+4, QQ+5 = ylo, yhi -; - -SetECFOrigin ROUT - -; *****Change made by DJS -; Original code was: -; LDRB R0, [WsPtr, #QQ+3] ; xhi -; LDRB R1, [WsPtr, #QQ+2] ; xlo -; PackXtnd R0, R0, R1 ; pack 2 bytes and sign extend -; LDRB R1, [WsPtr, #QQ+5] ; yhi -; LDRB R2, [WsPtr, #QQ+4] ; ylo -; PackXtnd R1, R1, R2 ; pack 2 bytes and sign extend - - LoadCoordPair R0, R1, WsPtr, QQ+2 - -; *****End of change made by DJS - -SetECFOriginCommon - Push R14 - ADD R8, WsPtr, #GCsX ; save ECursor away, cos EIG changes it - LDMIA R8, {R6, R7} ; and we don't want it to! - - MOV R2, #&FF ; convert external-to-internal - BL EIG ; as absolute coordinates - -; now R0 = internal X; R1 = internal Y - - LDR R3, [WsPtr, #NPix] - LDR R4, [WsPtr, #Log2BPC] - - AND R0, R0, R3 ; X MOD (number of pixels per word) - -; *****Change made by DJS -; Original code was: -; MOVS R0, R0, LSL R4 ; number of bits to rotate ECF left by -; MOVEQ R0, #32 ; if zero then make 32 -; RSB R0, R0, #32 ; so we make it zero again! -; I don't think anything cares whether this value is 0 or 32 in this case - it -; is only used as Rm in a couple of MOV Rn, Rn, ROR Rm instructions. So change -; to: - MOV R0, R0, LSL R4 ; number of bits to rotate ECF left by - RSB R0, R0, #32 -; *****End of change made by DJS - - STR R0, [WsPtr, #ECFShift] ; number of bits to rotate right by - - LDR R3, [WsPtr, #YWindLimit] -; *****Change made by DJS -; Need to increase R3 by one to produce correct alignment of the ECF patterns, -; as YWindLimit is an inclusive bound, not an exclusive one. - ADD R3, R3, #1 -; *****End of change made by DJS - SUB R1, R3, R1 ; invert Y - AND R1, R1, #7 ; modulo 8 - STR R1, [WsPtr, #ECFYOffset] - - STMIA R8, {R6, R7} - - BL SetColour ; update colours now - - Pull PC - -; ***************************************************************************** -; -; SWISetECFOrigin - Entry point for SWI OS_SetECFOrigin -; -; in: R0 = x-coordinate (external coords) -; R1 = y-coordinate (-------""------) -; - -SWISetECFOrigin ROUT - Push "R0-R9, R14" - VDWS WsPtr - BL SetECFOriginCommon - Pull "R0-R9, R14" - ExitSWIHandler - -; ***************************************************************************** -; -; Scroll left and right -; -; in: C=0 => scroll window -; C=1 => scroll screen - -ScrollLeftChar - MOV R9, #0 - B ScrollLeft - -ScrollLeftByte - LDR R9, [WsPtr, #Log2BPP] - LDR R10, [WsPtr, #ModeFlags] - TST R10, #Flag_BBCGapMode ; if in BBC gap mode - [ True - -; TMD 23-May-89: BBC gap modes were done wrong here - it scrolled by 1/2 a -; BBC byte instead of 1 - - SUBNE R9, R9, #1 ; then 1 BBC byte = 2 ARM bytes - | - MOVNE R9, #1 ; then 1 BBC byte = 2 ARM bytes - ] - -ScrollLeft - LDR R10, [WsPtr, #Log2BPC] - SUB R9, R10, R9 - - MOV R10, #1 - MOV R9, R10, LSL R9 ; R9 = bytes to move by - - ADC R0, R0, R0 ; bit0(R0) set => whole screen - TST R6, #TeletextMode ; if teletext, then do special - BNE TTXScrollLeft - - Push "R0, R14" ; save link and carry - MOVS R0, R0, LSR #1 ; C=0/1 => window/screen - BL GetScrWindInfo - BL ScrollLeft2 - Pull R0 - MOVS R0, R0, LSR #1 - -; now clear right hand column - - ADDCC R0, WsPtr, #TWBRow ; C=0 => window - LDMCCIA R0, {R1-R3} ; R1 = TWBRow; R2 = TWRCol - MOVCC R0, R2 ; R3 = TWTRow; R0 = TWRCol - - ADDCS R0, WsPtr, #ScrRCol ; C=1 => screen - LDMCSIA R0, {R0, R1} ; R0 = ScrRCol; R1 = ScrBRow - MOVCS R2, R0 ; R2 = ScrRCol; R3 = 0 - MOVCS R3, #0 - -; R9 = width of column to clear (in bytes) - - BL GetBoxInfo ; get info for right hand char column - ; R2 -> top left of right hand char col - ; R5 := number of bytes for one char - ADD R2, R2, R5 ; R2 -> off right of top line - MOV R5, R9 ; R5 := real number of bytes to do - SUB R2, R2, R5 ; R2 -> top left of column to clear - Pull R14 - B ClearThisBox - -; ***************************************************************************** - -GetScrWindInfo - BCC GetWindowInfo -GetScreenInfo - MOV R0, #0 - LDR R1, [WsPtr, #ScrBRow] - LDR R2, [WsPtr, #ScrRCol] - MOV R3, #0 - B GetBoxInfo - -; ***************************************************************************** -; -; ScrollLeft2 - Scroll area of screen left (don't clear right column) -; -; in: R2 -> screen(left,top) -; R5 = width of box in bytes -; R6 = number of scan lines in box -; R7 = linelength -; R9 = number of bytes to scroll by -; - -ScrollLeft2 ROUT - SUBS R5, R5, R9 ; number of bytes to scroll - MOVEQ PC, R14 ; none to scroll - - MOV R10, R9, LSL #3 ; number of bits moving by - CMP R10, #32 - MOVCS R10, #32 ; only do 32 at a time - RSB R11, R10, #32 ; 32-number of bits moving by - -ScrollLineLeft - MOV R0, R2 ; to addr (left) - ADD R1, R0, R9 ; from addr (right) - ADD R3, R0, R5 ; end+1 to addr -10 - TST R0, #3 ; if not on word boundary - LDRNEB R4, [R1], #1 ; then copy a byte from R1 - STRNEB R4, [R0], #1 ; to R0 - CMPNE R0, R3 ; if not on bdy and not at end - BNE %BT10 ; then loop - -20 - ADD R1, R1, #3 ; round R1 up to next word - BIC R1, R1, #3 - - TEQ R11, #0 ; if no shifts, use fast code - BEQ %FT60 - - SUB R3, R3, #3 ; fudge factors anonymous - CMP R0, R3 ; if can't do any words - BCS %FT40 ; then skip - LDR R8, [R0] ; get word to be put into R4 -30 - MOV R4, R8, LSR R10 ; get 2nd bits of old word - LDR R8, [R1], #4 ; load new word - ORR R4, R4, R8, LSL R11 ; merge with 1st bits of new - STR R4, [R0], #4 ; and store - CMP R0, R3 ; if more words to do then loop - BCC %BT30 -40 - ADD R3, R3, #3 ; put it back again - -; finish off the odd bytes -; R0 -> next dest byte - - ADD R1, R0, R9 ; R1 -> next source byte - CMP R0, R3 ; if not at end -50 - LDRCCB R4, [R1], #1 ; then copy a byte from R1 - STRCCB R4, [R0], #1 ; to R0 - CMPCC R0, R3 ; check for end - BCC %BT50 ; and loop if not - - ADD R2, R2, R7 ; goto next line down - SUBS R6, R6, #1 ; one less line to do - BNE ScrollLineLeft - MOV PC, R14 - -; fast code for when R10=32, R11=0 - -60 - SUB R3, R3, #7 ; must be able to do 8 bytes - CMP R0, R3 -70 - LDMCCIA R1!, {R4, R8} ; if OK then copy 2 words - STMCCIA R0!, {R4, R8} - CMPCC R0, R3 ; check for end - BCC %BT70 - ADD R3, R3, #4 ; must be able to do 4 bytes - CMP R0, R3 -80 - LDRCC R4, [R1], #4 ; if OK then copy a word - STRCC R4, [R0], #4 - CMPCC R0, R3 ; check for end - BCC %BT80 - B %BT40 ; do odd bytes at end - -; ***************************************************************************** - -ScrollRightChar - MOV R9, #0 - B ScrollRight - -ScrollRightByte - LDR R9, [WsPtr, #Log2BPP] - LDR R10, [WsPtr, #ModeFlags] - TST R10, #Flag_BBCGapMode ; if in BBC gap mode - - [ True - -; TMD 23-May-89: BBC gap modes were done wrong here - it scrolled by 1/2 a -; BBC byte instead of 1 - - SUBNE R9, R9, #1 ; then 1 BBC byte = 2 ARM bytes - | - MOVNE R9, #1 ; then 1 BBC byte = 2 ARM bytes - ] - -ScrollRight - LDR R10, [WsPtr, #Log2BPC] - SUB R9, R10, R9 - - MOV R10, #1 - MOV R9, R10, LSL R9 ; R9 = bytes to move by - - ADC R0, R0, R0 ; bit0(R0) set => whole screen - TST R6, #TeletextMode ; if teletext, then do special - BNE TTXScrollRight - - Push "R0, R14" ; save link and carry - MOVS R0, R0, LSR #1 ; C=0/1 => window/screen - BL GetScrWindInfo - BL ScrollRight2 - Pull R0 - MOVS R0, R0, LSR #1 - -; now clear left column - - ADDCC R0, WsPtr, #TWLCol ; C=0 => window - LDMCCIA R0, {R0-R3} ; R0 = TWLCol; R1 = TWBRow - MOVCC R2, R0 ; R2 = TWLCol; R3 = TWTRow - - MOVCS R0, #0 - LDRCS R1, [WsPtr, #ScrBRow] - MOVCS R2, R0 - MOVCS R3, #0 - -; R9 = width of column to clear (in bytes) - - BL GetBoxInfo ; get info for right hand char column - ; R2 -> top left of left hand char col - ; R5 := number of bytes for one char - MOV R5, R9 ; R5 := real number of bytes to do - Pull R14 - B ClearThisBox - -; ***************************************************************************** -; -; ScrollRight2 - Scroll area of screen right (don't clear left column) -; -; in: R2 -> screen(left,top) -; R5 = width of box in bytes -; R6 = number of scan lines in box -; R7 = linelength -; R9 = number of bytes to scroll by -; - -ScrollRight2 ROUT - ADD R2, R2, R5 ; R2 -> off top right - SUB R2, R2, #1 ; R2 -> top right - - SUBS R5, R5, R9 ; number of bytes to scroll - MOVEQ PC, R14 ; none to scroll - - MOV R10, R9, LSL #3 ; number of bits moving by - CMP R10, #32 - MOVCS R10, #32 ; only do 32 at a time - RSB R11, R10, #32 ; 32-number of bits moving by - -ScrollLineRight - MOV R0, R2 ; to addr (right) - SUB R1, R0, R9 ; from addr (left) - SUB R3, R0, R5 ; end-1 to addr - - MOV R8, #(3 :SHL: 30) -10 - CMP R8, R0, LSL #30 ; EQ if (R0 AND 3)=3 - LDRNEB R4, [R1], #-1 ; if not then copy a byte - STRNEB R4, [R0], #-1 - CMPNE R0, R3 ; if not aligned and not end - BNE %BT10 ; then loop - - SUB R1, R1, #3 ; round R1 down to next word - BIC R1, R1, #3 - - SUB R0, R0, #3 ; make R0 -> word boundary - TEQ R11, #0 ; if no shifts, use fast code - BEQ %FT60 - - CMP R0, R3 ; if no words - BLS %FT40 ; then skip - LDR R8, [R0] ; get word to be put into R4 -30 - MOV R4, R8, LSL R10 - LDR R8, [R1], #-4 - ORR R4, R4, R8, LSR R11 - STR R4, [R0], #-4 - CMP R0, R3 ; if R3 < R1 then no more words - BHI %BT30 -40 - ADD R0, R0, #3 ; put it back again - -; finish off the odd bytes -; R0 -> next dest byte - - SUB R1, R0, R9 ; R1 -> next source byte - CMP R0, R3 ; check for end -50 - LDRHIB R4, [R1], #-1 ; if not end then copy byte - STRHIB R4, [R0], #-1 - CMPHI R0, R3 ; check for end - BHI %BT50 - - ADD R2, R2, R7 ; move to next row - SUBS R6, R6, #1 ; one less row to do - BNE ScrollLineRight - MOV PC, R14 - -; fast code for when R10=32, R11=0 - -60 - ADD R3, R3, #4 ; need to do at least 8 bytes - CMP R0, R3 -70 - LDMHIDA R1!, {R4, R8} ; if OK then copy 2 words - STMHIDA R0!, {R4, R8} - CMPHI R0, R3 ; check for end - BHI %BT70 - - SUB R3, R3, #4 ; put it back - CMP R0, R3 -80 - LDRHI R4, [R1], #-4 ; if OK then copy 1 word - STRHI R4, [R0], #-4 - CMPHI R0, R3 ; check for end - BHI %BT80 - B %BT40 - -; ***************************************************************************** -; -; VDU 23,16,x,y| - Change cursor flags -; -; new := (old AND y) EOR x - -Vdu23_16 - LDRB R0, [WsPtr, #CursorFlags] ; just affect bottom byte - LDRB R1, [WsPtr, #QQ+1] ; x - LDRB R2, [WsPtr, #QQ+2] ; y - AND R0, R0, R2 - EOR R0, R0, R1 - STRB R0, [WsPtr, #CursorFlags] - - TST R0, #1 - BEQ RCRLF ; leaving 81 column mode - ; so release CRLF - MOV PC, R14 - -; ***************************************************************************** -; -; Move cursor to R0 chars from boundary -; and check for being legal -; -; out: C=1 => was within window -; C=0 => outside window - - ASSERT CursorY = CursorX +4 - -CursorBdyCheck - Push R14 - BL CursorBdy - ADD R9, WsPtr, #CursorX - LDMIA R9, {R9, R10} - CMP R4, R9 - CMPCS R3, R10 - Pull PC - -; ***************************************************************************** -; -; Move cursor to boundary indicated by value of R6 in bits 1-3 -; (0 or 4 = left, 2 or 6 = right, 8 or 10 = up, 12 or 14 = down) -; + R0 character positions in -; -; out: R7, R8, R11 undefined -; R0, R1, R6, R9, R10, R12, R13 preserved -; R2-R5 are window coords (left,down,right,up) -; - ASSERT TWBRow = TWLCol + 4 - ASSERT TWRCol = TWLCol + 8 - ASSERT TWTRow = TWLCol + 12 - -InputCursorB0 - MOV R0, #0 -InputCursorBdy - ADD R11, WsPtr, #InputCursorX - B CBDY05 - -CursorB0 - MOV R0, #0 -CursorBdy - ADD R11, WsPtr, #CursorX -CBDY05 - ADD R7, WsPtr, #TWLCol ; point to window coords - LDMIA R7, {R2-R5} - - ADR R7, CBDYTab -DoJumpTable - AND R8, R6, #&0E - LDR R8, [R7, R8, LSL #1] - ADD PC, R7, R8 - -CBDYTab - & CursorLBdy-CBDYTab - & CursorRBdy-CBDYTab - & CursorLBdy-CBDYTab - & CursorRBdy-CBDYTab - & CursorUBdy-CBDYTab - & CursorUBdy-CBDYTab - & CursorDBdy-CBDYTab - & CursorDBdy-CBDYTab - -; Move cursor to left boundary + R0 characters in - -CursorLBdy - ADD R7, R0, R2 -CBDY10 - STR R7, [R11, #CursorX-CursorX] - MOV PC, R14 - -; Move cursor to right boundary + R0 characters in - -CursorRBdy - SUB R7, R4, R0 - B CBDY10 - -; Move cursor to up boundary + R0 characters in - -CursorUBdy - ADD R7, R0, R5 -CBDY20 - STR R7, [R11, #CursorY-CursorX] - MOV PC, R14 - -; Move cursor to down boundary + R0 characters in - -CursorDBdy - SUB R7, R3, R0 - B CBDY20 - -; ***************************************************************************** -; -; CursorMove - Move cursor in direction corresponding to R6 bits 1-3 -; (0,4 = right; 2,6 = left; 8,10 = down; 12,14 = up) -; R6 is preserved - - ASSERT InputCursorY-InputCursorX = CursorY-CursorX - ASSERT InputCursorAddr-InputCursorX = CursorAddr-CursorX - -InputCursorMove - ADD R11, WsPtr, #InputCursorX - B CurM10 - -CursorMove - ADD R11, WsPtr, #CursorX -CurM10 - ADR R7, CMVTab - B DoJumpTable - -CMVTab - & MoveRight-CMVTab - & MoveLeft-CMVTab - & MoveRight-CMVTab - & MoveLeft-CMVTab - & MoveDown-CMVTab - & MoveDown-CMVTab - & MoveUp-CMVTab - & MoveUp-CMVTab - -; Move cursor right if possible - on exit C=1 iff at RHS - -MoveRight - LDR R0, [R11, #CursorX-CursorX] - LDR R4, [WsPtr, #TWRCol] - CMP R0, R4 - MOVCS PC, R14 - LDR R2, [R11, #CursorAddr-CursorX] - [ HiResTTX - LDR R3, [WsPtr, #CharWidth] - | - LDR R3, [WsPtr, #BytesPerChar] - ] - ADD R0, R0, #1 - ADD R2, R2, R3 - STR R0, [R11, #CursorX-CursorX] - STR R2, [R11, #CursorAddr-CursorX] - MOV PC, R14 - -; Move cursor left if possible - on exit C=1 iff at LHS - -MoveLeft - LDR R0, [R11, #CursorX-CursorX] - LDR R4, [WsPtr, #TWLCol] - CMP R4, R0 - MOVCS PC, R14 - LDR R2, [R11, #CursorAddr-CursorX] - [ HiResTTX - LDR R3, [WsPtr, #CharWidth] - | - LDR R3, [WsPtr, #BytesPerChar] - ] - SUB R0, R0, #1 - SUB R2, R2, R3 - STR R0, [R11, #CursorX-CursorX] - STR R2, [R11, #CursorAddr-CursorX] - MOV PC, R14 - -; Move cursor down if possible - on exit C=1 iff at bottom - -MoveDown - LDR R1, [R11, #CursorY-CursorX] - LDR R4, [WsPtr, #TWBRow] - CMP R1, R4 - MOVCS PC, R14 - LDR R2, [R11, #CursorAddr-CursorX] - LDR R3, [WsPtr, #RowLength] - ADD R1, R1, #1 - ADD R2, R2, R3 - STR R1, [R11, #CursorY-CursorX] - STR R2, [R11, #CursorAddr-CursorX] - MOV PC, R14 - -; Move cursor up if possible - on exit C=1 iff at top - -MoveUp - LDR R1, [R11, #CursorY-CursorX] - LDR R4, [WsPtr, #TWTRow] - CMP R4, R1 - MOVCS PC, R14 - LDR R2, [R11, #CursorAddr-CursorX] - LDR R3, [WsPtr, #RowLength] - SUB R1, R1, #1 - SUB R2, R2, R3 - STR R1, [R11, #CursorY-CursorX] - STR R2, [R11, #CursorAddr-CursorX] - MOV PC, R14 - -; ***************************************************************************** -; -; Special HT - used when abnormal cursor direction selected -; or if C81Bit set -; -; in: R6 = CursorFlags -; - -SpecialHT - TST R6, #Vdu5Bit - BNE Vdu5HT - Push "R6,R14" - BL RCRLFR6 - Pull R6 - BL CursorMove ; try to move in appropriate direction - Pull PC, CC ; if successful, finish - BL CursorB0 ; else move cursor to -ve X boundary - BL AddressCursor ; re-address cursor - Pull R14 - B VduLF ; and do a line-feed - -; ***************************************************************************** -; -; CHT - version of HT used after printing character -; will set pending CRLF if necessary -; -; in: R6 = CursorFlags - -CHT - TST R6, R6, ROR #10 ; test for Vdu5 or &1E or C81Bit, latter not - ; possible as we just printed a char - BNE SpecialCHT - - LDR R0, [WsPtr, #CursorX] - LDR R2, [WsPtr, #CursorAddr] - [ HiResTTX - LDR R3, [WsPtr, #CharWidth] - | - LDR R3, [WsPtr, #BytesPerChar] - ] - LDR R4, [WsPtr, #TWRCol] - - ADD R0, R0, #1 - ADD R2, R2, R3 - CMP R0, R4 - STRLS R0, [WsPtr, #CursorX] - STRLS R2, [WsPtr, #CursorAddr] - MOVLS PC, R14 - - TST R6, #1 ; are we in "81-column" mode - BNE CHT10 ; yes, then just set C81Bit - - BSR PageTest - - LDR R0, [WsPtr, #TWLCol] - LDR R1, [WsPtr, #CursorY] - LDR R4, [WsPtr, #TWBRow] - - ADD R1, R1, #1 - CMP R1, R4 - BLS CursorR0R1 ; not on bottom line - - STR R0, [WsPtr, #CursorX] - BSR ScrollUp - B AddressCursor ; re-address cursor position - -CHT10 - ORR R6, R6, #C81Bit - STR R6, [WsPtr, #CursorFlags] - MOV PC, R14 - -SpecialCHT - TST R6, #Vdu5Bit - BNE Vdu5HT - BSR CursorMove ; try to move in appropriate direction - MOVCC PC, R14 ; if successful, finish - - TST R6, #1 - BNE CHT10 - - Push R14 - BL CursorB0 ; else move cursor to -ve X boundary - BL AddressCursor ; re-address cursor - Pull R14 - B VduLF ; and do a line-feed - -; ***************************************************************************** -; -; Special BS - used when abnormal cursor direction selected -; or Vdu5 mode -; or if C81Bit was set -; -; in : R6 = CursorFlags -; - -SpecialBS - TST R6, #Vdu5Bit ; VDU 5 mode ? - BNE Vdu5BS ; then branch - - TST R6, #C81Bit ; did we come here cos of C81Bit - BICNE R6, R6, #C81Bit ; if so then clear the bit - STRNE R6, [WsPtr, #CursorFlags] ; store it back - MOVNE PC, R14 ; and leave cursor where it is - - EOR R6, R6, #6 ; move "left" - Push R14 - BL CursorMove - Pull PC, CC ; if successful - BL CursorB0 ; move to +ve X boundary - BL AddressCursor ; re-address cursor - Pull R14 - B VT ; and do reverse line-feed - -; ***************************************************************************** -; -; Special LF - used when abnormal cursor direction selected -; -; in : R6 = CursorFlags -; - -SpecialLF - EOR R6, R6, #8 ; move "down" - Push R14 - BL CursorMove - Pull PC, CC ; if successful - BL CanScroll ; see if we can scroll - Pull PC, CS ; if failed, exit with all done - Pull R14 - MOV R0, #0 ; scroll window - MOV R1, #7 ; "up" - MOV R2, #0 ; by 1 char - B Scroll012 - -; ***************************************************************************** -; -; Special VT - used when abnormal cursor direction selected -; -; in : R6 = CursorFlags -; - -SpecialVT - EOR R6, R6, #14 ; move "up" - Push R14 - BL CursorMove - Pull PC, CC ; if successful - BL CanScroll ; see if we can scroll - Pull PC, CS ; if failed, exit with all done - Pull R14 - MOV R0, #0 ; scroll window - MOV R1, #6 ; "down" - MOV R2, #0 ; by 1 char - B Scroll012 - -; ***************************************************************************** -; -; CanScroll - check whether we can scroll in direction R6 -; -; in: R6 = CursorFlags - -CanScroll ROUT - Push R14 - TST R6, #&10 ; do we scroll or move to other edge - BNE CantScroll - - TST R6, #CursorsSplit - BEQ %FT10 ; cursors not split, so input cursor - ; not relevant - EOR R6, R6, #6 - BL InputCursorMove ; if cursor fails to move, it's OK - ; where it is - BL AddressInputCursor ; readdress it anyway, just in case - EOR R6, R6, #6 ; put R6 back -10 - CLC - Pull PC - -CantScroll - BL CursorB0 ; move to opposite edge - BL AddressCursor - SEC - Pull PC - -; ***************************************************************************** -; -; Release any pending CRLF -; - -RCRLF - LDR R6, [WsPtr, #CursorFlags] - -; Extra entry point when R6 already loaded - -RCRLFR6 - TST R6, #C81Bit - MOVEQ PC, R14 ; no pending CRLF - BSR CR10 ; (clears C81Bit) - B VduLF - -; ***************************************************************************** -; -; VDU 23,8,t1,t2,x1,y1,x2,y2| - Clear block of text -; -; t=0 Top left of window -; t=1 Top of cursor column -; t=2 Off top right of window -; -; t=4 Left end of cursor line -; t=5 Cursor position -; t=6 Off right of cursor line -; -; t=8 Bottom left of window -; t=9 Bottom of cursor column -; t=10 Off bottom right of window -; - -Vdu23_8 - MOV R0, #0 ; top left of window - STRB R0, [WsPtr, #CBWS+0] - STRB R0, [WsPtr, #CBWS+1] - BSR CP81 ; cursor position - STRB R0, [WsPtr, #CBWS+2] - STRB R1, [WsPtr, #CBWS+3] - BSR WBotRig ; bottom right of window - ADD R0, R0, #1 ; off bottom right of window - STRB R0, [WsPtr, #CBWS+4] - STRB R1, [WsPtr, #CBWS+5] - - ADD R3, WsPtr, #CBWS - ADD R2, R3, #QQ+2-CBWS - LDRB R0, [WsPtr, #QQ+1] ; t1 - BSR CLBL50 - LDRB R0, [WsPtr, #QQ+2] ; t2 - BSR CLBL50 - -; Check end is after start - - LDRB R2, [WsPtr, #CBStart] ; start X - LDRB R3, [WsPtr, #CBStart+1] ; start Y - LDRB R4, [WsPtr, #CBEnd] ; end X - LDRB R5, [WsPtr, #CBEnd+1] ; end Y - - CMP R5, R3 - CMPEQ R4, R2 - MOVLS PC, R14 ; end <= start so do nothing - - LDR R0, [WsPtr, #CursorX] ; save cursor position - LDR R1, [WsPtr, #CursorY] - Push "R0,R1" - - MOV R0, R3 ; First row to clear - MOV R1, R2 ; Start position for first row - LDRB R7, [WsPtr, #CBWS+4] ; End position for all but last row - - ADD R6, WsPtr, #TWLCol - LDMIA R6, {R8-R11} - - LDR R6, [WsPtr, #CursorFlags] -CLBL20 - TEQ R0, R5 - BEQ CLBL40 - BSR RowClear - ADD R0, R0, #1 - MOV R1, #0 ; start position for subsequent rows - B CLBL20 - -CLBL40 - MOV R7, R4 ; end position for last row - BSR RowClear - - Pull "R0,R1" - STR R0, [WsPtr, #CursorX] - STR R1, [WsPtr, #CursorY] - B AddressCursor - -CLBL50 - AND R1, R0, #3 - MOV R1, R1, LSL #1 - LDRB R6, [WsPtr, #CBWS+4] - BSR CLBL60 - MOV R1, R0, LSR #1 - ORR R1, R1, #1 - LDRB R6, [WsPtr, #CBWS+5] -CLBL60 - LDRB R4, [R3, R1] ; get base coordinate to use - LDRB R5, [R2, #1]! ; get x or y offset - - MOV R5, R5, LSL #24 - ADDS R4, R4, R5, ASR #24 ; add sign extended offset to base - MOVMI R4, #0 ; if <0 then make =0 - CMP R4, R6 - MOVHI R4, R6 ; is this stringent enough ? - - STRB R4, [R2, #CBStart-(QQ+3)] - MOV PC, R14 - -; ***************************************************************************** -; -; RowClear - Clear a "row" {R1 <= X < R7, Y = R0} - -RowClear - Push "R0-R11,R14" - SUB R7, R7, #1 - CMP R1, R7 - BHI RowCL10 ; left > right, so ignore - - TST R6, #8 - - MOVEQ R2, R1 ; left - MOVEQ R3, R0 ; bottom - MOVEQ R4, R7 ; right - MOVEQ R5, R0 ; top - - MOVNE R2, R0 ; left - MOVNE R3, R7 ; bottom - MOVNE R4, R0 ; right - MOVNE R5, R1 ; top - - TST R6, #2 - - ADDEQ R0, R8, R2 - ADDEQ R2, R8, R4 - - SUBNE R0, R10, R4 - SUBNE R2, R10, R2 - - TST R6, #4 - - ADDEQ R1, R11, R3 - ADDEQ R3, R11, R5 - - SUBNE R1, R9, R5 - SUBNE R3, R9, R3 - - BL ClearBox - -RowCL10 - Pull "R0-R11,PC" - - [ :LNOT: AssemblingArthur - -; ***************************************************************************** -; -; DoVduExternal - External entry point for -; a) reading input cursor position -; b) reading output cursor position -; c) reading character at cursor position and screen mode -; d) resetting all or part of font -; e) reading font definitions -; f) reading VDU status -; g) reading VDU variables -; h) reading palette (OSWORD &0B) -; i) setting palette (OSWORD &0C) -; j) various mouse/pointer stuff -; k) set top of screen address -; l) set VDU driver bank -; m) set display bank -; -; in: R0 = 0 => read input cursor position -; R0 = 1 => read output cursor position -; R0 = 2 => OSBYTE &87 - R1 := char at cursor, R2 := screen mode -; R0 = 3 => reset font (R1*32 = start char, R2 = number of pages) -; R0 = 4 => OSWORD 10 (R1 -> control block) -; R0 = 5 => read VDU status -; R0 = 6 => read VDU variables number R1, R1+1 -; R0 = 7 => read palette -; R0 = 8 => set palette -; R0 = 9 => mouse/pointer control -; R0 = 10 => set top of screen address -; R0 = 11 => set VDU driver bank -; R0 = 12 => set display bank -; -; out: a,b; R1 = X, R2 = Y -; c; R1=char, R2=screen mode -; f; R1=VDU status -; g; R1=variable(n), R2=variable(n+1) -; R0, R3 destroyed -; R4-R11 preserved -; - -DoVduExternal ROUT - CMP R0, #ExtEntries - MOVCS PC, R14 - LDR R3, [PC, R0, LSL #2] - ADD PC, PC, R3 - -ExtTable OutputExternals - - ] - -; ***************************************************************************** - -DoReadPOSVPOSI ROUT - MOV R0, #0 - B %FT05 -DoReadPOSVPOSO - MOV R0, #1 -05 - Push "R4-R11, R14" - LDR R6, [WsPtr, #CursorFlags] - TST R6, #CursorsSplit ; if cursors are split - TEQNE R0, #1 ; and reading input cursor - BNE %FT10 ; then use input cursor - BL CP81 ; else read output cursor - B %FT20 -10 - BL CP79 -20 - MOV R2, R1 - MOV R1, R0 - Pull "R4-R11, PC" - -; ***************************************************************************** -; -; DoSetScreenStart - Set top of screen address (display + drivers) -; -; in: R1 -> control block -; [R1, #0] = bit mask; bit 0 set => change drivers address -; bit 1 set => change display address -; -; [R1, #1..4] = byte offset from lowest screen address -; -; out: - -; - -DoSetScreenStart ROUT - Push R14 - LDRB R3, [R1, #0] ; R3 = bitmask - LDRB R0, [R1, #1] - LDRB R2, [R1, #2] - ORR R0, R0, R2, LSL #8 - LDRB R2, [R1, #3] - ORR R0, R0, R2, LSL #16 - LDRB R2, [R1, #4] - ORR R0, R0, R2, LSL #24 ; R0 is now the offset - LDR R2, [WsPtr, #TotalScreenSize] - CMP R0, R2 - BCS %FT10 ; offset too large - Push "R0,R2,R3,R5-R10" - - MOV R0, #1 - STRB R0, [WsPtr, #ScreenMemoryClaimed] - ; indicate memory not available - BL PreWrchCursor - Pull "R0,R2,R3,R5-R10" - LDR R14, [WsPtr, #ScreenEndAddr] - ADD R0, R0, R14 - SUB R0, R0, R2 ; make into a LOGRAM address - - TST R3, #1 - BEQ %FT05 - Push R0 - BL NewScreenStart - Pull R0 -05 - TST R3, #2 - BLNE SetVinit ; program vinit and set DisplayStart - - Push "R5-R10" ; save registers - BL PostWrchCursor - Pull "R5-R10" -10 - Pull PC - -; ***************************************************************************** -; -; NewScreenStart - Update ScreenStart and readdress cursors -; -; in: R0 = new screen start -; -; out: R0, R2 corrupted; all others preserved -; - -NewScreenStart ROUT - Push R14 - - LDR R2, [WsPtr, #DisplayScreenStart] - BL SetDisplayScreenStart - LDR R14, [WsPtr, #VduSprite] ; test if outputting to sprite - TEQ R14, #0 ; Z => outputting to screen - MOVNE PC, R14 ; if outputting to sprite, don't update - ; Screenstart or cursor addresses - - STR R0, [WsPtr, #ScreenStart] - SUB R0, R0, R2 ; R0 := new-old -AdjustCursorVars - LDR R14, [WsPtr, #CursorAddr] - ADD R14, R14, R0 - STR R14, [WsPtr, #CursorAddr] - LDR R14, [WsPtr, #InputCursorAddr] - ADD R14, R14, R0 - STR R14, [WsPtr, #InputCursorAddr] - Pull PC - -; ***************************************************************************** -; -; DoSetDriverBank - Set VDU driver's screen bank (OSBYTE &70) -; -; in: R1 = bank number (1..n) (NOTE: starts at 1) -; - -DoSetDriverBank ROUT - Push R14 - MOVS R2, R1 - BNE %FT10 - LDR R1, [WsPtr, #VduStatus] - TST R1, #Shadowing - MOVEQ R2, #1 - MOVNE R2, #2 -10 - MOV R0, #0 - LDRB R1, [R0, #OsbyteVars + :INDEX: MemDriver] ; old value - - Push "R1,R4-R10" ; save registers - BL ConvertBankToAddress ; R3 := start address of NEXT bank - LDR R14, [WsPtr, #ScreenEndAddr] - CMP R3, R14 ; if after end, can't do it - Pull "R1,R4-R10,PC", HI ; so exit - - STRB R2, [WsPtr, #ScreenMemoryClaimed] - ; indicate memory not available (R2<>0) - STRB R2, [R0, #OsbyteVars + :INDEX: MemDriver] ; store new value - - LDR R0, [WsPtr, #DriverBankAddr] ; R0:=old default bank start - LDR R2, [WsPtr, #DisplayScreenStart] ; R2:=old current screen start - SUB R0, R2, R0 ; R0 := (current-default) - ; in range 1-TotalSize..TotalSize-1 - - LDR R2, [WsPtr, #ScreenSize] - SUB R3, R3, R2 ; default start of THIS bank - STR R3, [WsPtr, #DriverBankAddr] ; R3 := new default bank start - - ADD R0, R0, R3 ; new current start (not bound checked) - - LDR R2, [WsPtr, #TotalScreenSize] - - RSBS R0, R0, R14 - ADDLS R0, R0, R2 - CMP R0, R2 - SUBHI R0, R0, R2 ; now in bounds (but inverted) - RSB R0, R0, R14 - - Push R0 - BL PreWrchCursor - Pull R0 - - BL NewScreenStart - - BL PostWrchCursor - Pull "R1,R4-R10,PC" - -; ***************************************************************************** -; -; DoSetDisplayBank - Set displayed screen bank (OSBYTE &71) -; -; in: R1 = bank number (1..n) (NOTE: starts at 1) -; - -DoSetDisplayBank ROUT - Push R14 - MOVS R2, R1 - BNE %FT10 - LDR R1, [WsPtr, #VduStatus] - TST R1, #Shadowing - MOVEQ R2, #1 - MOVNE R2, #2 -10 - MOV R0, #0 - LDRB R1, [R0, #OsbyteVars + :INDEX: MemDisplay] ; old value - Push "R1,R4-R5" ; save registers - BL ConvertBankToAddress ; R3 := start address of NEXT bank - LDR R14, [WsPtr, #ScreenEndAddr] - CMP R3, R14 ; if after end, can't do it - Pull "R1,R4-R5,PC", HI ; so exit - - STRB R2, [WsPtr, #ScreenMemoryClaimed] - ; indicate memory not available (R2<>0) - STRB R2, [R0, #OsbyteVars + :INDEX: MemDisplay] ; store new value - - LDR R0, [WsPtr, #DisplayBankAddr] ; R0 := old default bank start - LDR R2, [WsPtr, #DisplayStart] ; R2 := old current display start - SUB R0, R2, R0 ; R0 := (current-default) - ; in range 1-TotalSize..TotalSize-1 - - LDR R2, [WsPtr, #ScreenSize] - SUB R3, R3, R2 ; default start of THIS bank - STR R3, [WsPtr, #DisplayBankAddr] ; R3 := new default bank start - - ADD R0, R0, R3 ; new current start (not bound checked) - - LDR R2, [WsPtr, #TotalScreenSize] - - RSBS R0, R0, R14 - ADDLS R0, R0, R2 - CMP R0, R2 - SUBHI R0, R0, R2 ; now in bounds (but inverted) - RSB R0, R0, R14 - - BL SetVinit ; program vinit and set DisplayStart - Pull "R1,R4-R5,PC" - -; ***************************************************************************** -; -; CP81 - Read output cursor position, -; taking C81Bit and CursorFlags into account -; -; out: R0=X, R1=Y - -CP81 - Push R14 - BL CP80 - LDR R6, [WsPtr, #CursorFlags] - TST R6, #C81Bit - ADDNE R0, R0, #1 ; in hidden column, so inc X - Pull PC - -; ***************************************************************************** -; -; CP79 - Read input cursor position, -; taking CursorFlags into account -; -; out: R0=X, R1=Y - -CP79 - MOV R1, #InputCursorX-TWLCol - B CP80R1 - -; ***************************************************************************** -; -; WBotRig - Read coordinates of "bottom right" in user coords -; -; out: R0=X, R1=Y - -WBotRig - ADD R5, WsPtr, #TWLCol - LDR R6, [WsPtr, #CursorFlags] - LDR R0, [R5, #TWLCol-TWLCol] ; get TWLCol - LDR R1, [R5, #TWRCol-TWLCol] ; get TWRCol - SUB R4, R1, R0 - MOV R2, #0 - MOV R1, #0 - B CP8010 - -; ***************************************************************************** -; -; CP80 - Read cursor position, taking CursorFlags into account - -CP80 - MOV R1, #CursorX-TWLCol -CP80R1 - ADD R5, WsPtr, #TWLCol - LDR R6, [WsPtr, #CursorFlags] - MOV R2, #2 - MOV R0, #0 - BSR CP8020 - MOV R4, R2 - MOV R2, #4 -CP8010 - ADD R1, R1, #4 - MOV R0, #TWTRow-TWLCol - BSR CP8020 - MOV R0, R2 - MOV R1, R2 - TST R6, #8 - MOVEQ R0, R4 - MOVNE R1, R4 - - MOV PC, R14 - -CP8020 - TST R2, R6 - EORNE R0, R0, #8 - LDR R2, [R5, R0] - LDR R3, [R5, R1] - SUBNE R2, R2, R3 - SUBEQ R2, R3, R2 - MOV PC, R14 - -; ***************************************************************************** -; -; Vdu23_0 - Program "6845" -; - -Vdu23_0 - LDRB R1, [WsPtr, #QQ+1] ; get register number - AND R2, R1, #31 ; address register is 5 bits - CMP R2, #8 - MOVCC PC, R14 - BEQ Vdu23_0_8 - CMP R2, #10 - BEQ Vdu23_0_10 - CMP R2, #12 - BCC Vdu23_0_11 - - [ DoVdu23_0_12 - BEQ Vdu23_0_12 - CMP R2, #13 - BEQ Vdu23_0_13 - ] - B UnknownVdu23 - - -; ***************************************************************************** -; -; Vdu23_0_8 - Program interlace -; -; in: R1 = unmasked register number (bits 5-7 may be set) - -Vdu23_0_8 ROUT - LDRB R0, [WsPtr, #QQ+2] ; value to program into interlace - TST R0, #&80 ; if negative, don't EOR with *TV - TSTEQ R1, #&E0 ; if not register 8, don't EOR - BNE %FT10 ; don't EOR - - LDROSB R1, TVInterlace - TST R1, #1 - EORNE R0, R0, #1 ; toggle if *TV n,1 and number +ve -10 - [ UseGraphicsV - Push "R14" - MOV R4, #GraphicsV_SetInterlace - BL CallGraphicsV - Pull "R14" - | - Push "R0-R3, R9, R12, LR" - mjsAddressHAL - mjsCallHAL HAL_Video_SetInterlace - Pull "R0-R3, R9, R12, LR" - ] - - MOV PC, R14 - - [ DoVdu23_0_12 - -; ***************************************************************************** -; -; Vdu23_0_12 - Program "hi" byte of start of screen -; - -Vdu23_0_12 - MOV R2, #11 ; starting bit number -V23012_10 - LDRB R0, [WsPtr, #QQ+2] ; get parameter - LDR R1, [WsPtr, #VinitCopy] - MOV R1, R1, ROR R2 ; move changing bits to bottom - BIC R1, R1, #&FF ; clear old bits out - ORR R1, R1, R0 ; put in new bits - RSB R2, R2, #32 ; fudge cos we ain't got ROL - MOV R0, R1, ROR R2 ; put back to correct position - B SetVinitPhys - -; ***************************************************************************** -; -; Vdu23_0_13 - Program "lo" byte of start of screen -; - -Vdu23_0_13 - MOV R2, #3 ; starting bit number - B V23012_10 - - ] - -; ***************************************************************************** -; -; Vdu23_9 - Equivalent of FX 9 -; Vdu23_10 - Equivalent of FX 10 -; -; in: R0 = 9 or 10 -; - -Vdu23_9 -Vdu23_10 - Push R14 ; for the SWI - LDRB R1, [WsPtr, #QQ+1] ; get X parameter - SWI XOS_Byte - Pull PC, VC ; no error, then return - - Pull R14 ; get stack back - B VduBadExit ; and tell the world - -; ***************************************************************************** -; -; DoReadVDUStatus - Read VDU status -; -; out: R1 = status -; bit 0 set => printer enabled by VDU 2 -; bit 1 set => N/A -; bit 2 set => in page mode -; bit 3 set => text window in force -; bit 4 set => in a shadow mode -; bit 5 set => in VDU 5 mode -; bit 6 set => cursor editing in progress -; bit 7 set => VDU disabled (by VDU 21) -; -; R2 corrupted -; - -DoReadVDUStatus - LDR R1, [WsPtr, #VduStatus] ; Vdu2, Window, Shadow bits - - LDR R2, [WsPtr, #CursorFlags] - - TST R2, #PageMode - ORRNE R1, R1, #&04 - - TST R2, #Vdu5Bit - ORRNE R1, R1, #&20 - - TST R2, #CursorsSplit - ORRNE R1, R1, #&40 - - TST R2, #VduDisabled - ORRNE R1, R1, #&80 - - MOV PC, R14 - -; ***************************************************************************** -; -; DoReadVDUVariable - Read BBC-style VDU variables -; -; in: R1 = variable to read (only &00..&0F are supported) -; -; out: R1 = value of that variable -; R2 = value of next variable -; - -DoReadVDUVariable - CMP R1, #(BBCVduVarsEnd-BBCVduVars) - MOVCS PC, R14 ; don't support this variable - ADR R3, BBCVduVars ; point to lookup table - LDRB R0, [R3, R1]! ; get index for first variable - LDRB R1, [WsPtr, R0] ; get first variable - LDRB R0, [R3, #1] ; get index for second variable - LDRB R2, [WsPtr, R0] ; get second variable - MOV PC, R14 - -BBCVduVars - EQUB GWLCol - EQUB GWLCol+1 - EQUB GWBRow - EQUB GWBRow+1 - EQUB GWRCol - EQUB GWRCol+1 - EQUB GWTRow - EQUB GWTRow+1 - EQUB TWLCol - EQUB TWBRow - EQUB TWRCol - EQUB TWTRow - EQUB OrgX - EQUB OrgX+1 - EQUB OrgY - EQUB OrgY+1 -BBCVduVarsEnd - -; ***************************************************************************** -; -; SetCharSizes - Set char sizes for VDU 4 or VDU 5 text -; -; in: QQ+2 = flags: bit 0 set => set VDU 4 size -; bit 1 set => set VDU 5 size -; bit 2 set => set VDU 5 spacing -; QQ+3,4 x size in pixels -; QQ+5,6 y size in pixels -; - - ASSERT YEigFactor = XEigFactor +4 - -SetCharSizes ROUT - LDRB R0, [WsPtr, #QQ+3] - LDRB R2, [WsPtr, #QQ+4] - ORR R0, R0, R2, LSL #8 ; R0 = x size - - LDRB R1, [WsPtr, #QQ+5] - LDRB R2, [WsPtr, #QQ+6] - ORR R1, R1, R2, LSL #8 ; R1 = y size - - LDRB R2, [WsPtr, #QQ+2] - - ADD R3, WsPtr, #GCharSizes - TST R2, #2 ; if modifying VDU 5 size - STMNEIA R3, {R0, R1} - - ADD R3, R3, #8 - TST R2, #4 ; if modifying VDU 5 spacing - STMNEIA R3, {R0, R1} - - MOV PC, R14 - - END diff --git a/s/vdu/vdu5 b/s/vdu/vdu5 deleted file mode 100644 index ba18836b..00000000 --- a/s/vdu/vdu5 +++ /dev/null @@ -1,656 +0,0 @@ -; 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.Vdu5 - -; ***************************************************************************** -; -; Print a character in VDU 5 mode -; - -; *****This file has been extensively modified by DJS - -; Alter these at your peril ! - -cxl RN 0 -scr RN 0 - -ecfptr RN 1 -cword0 RN 1 - -cyb RN 2 -cyt2 RN 2 -scrend RN 2 -cword1 RN 2 - -cxr RN 3 -cyb2 RN 3 -ormask RN 3 - -cxl2 RN 4 -eormask RN 4 - -cyb3 RN 5 -charmsk RN 5 -cword2 RN 5 - -cyt RN 6 -llength RN 6 -chartmp RN 6 - -sizex RN 7 -charptr RN 7 - -sizey RN 8 -invcharshf RN 8 - -charbyte RN 9 - -cxr2 RN 10 -charshf RN 10 - -lgBPC RN 11 - -Vdu5Wrch - Push R14 - BL Vdu5DoChar - Pull R14 - B PostCharMove - -; Vdu23_18 -; LDR R0, [WsPtr, #QQ+1] -Vdu5DoChar - ADD ecfptr, WsPtr, #FgEcfOraEor ;Base address of OR/EOR pairs -Vdu5DoChar10 - Push "R14" - MOV charbyte, R0 ;Put character out of harm's - ; way - ASSERT cxl < cyt - ASSERT GCsIY = GCsIX +4 - ADD cxl, WsPtr, #GCsIX - LDMIA cxl, {cxl, cyt} ; cxl=where left pixel would be - ; cyt=where top pixel would be - - ASSERT sizex < sizey - ADD sizex, WsPtr, #GCharSizes - LDMIA sizex, {sizex, sizey} - CMP sizey, #16 ; if SizeY=8 or SizeY=16 - TEQNE sizey, #8 ; (leaving CS <=> SizeY=16) - TEQEQ sizex, #8 ; and SizeX=8, then do it fast - BNE SlowVdu5 ; else do by scaled char - - TEQ charbyte, #127 ; Which font do we use? - ADDNE charptr, WsPtr, #(Font-32*8) ; Soft if character not DELETE - ADREQL charptr, HardFont-32*8 ; Hard if character is DELETE - ADD charptr, charptr, charbyte, LSL #3 ;Point at char def - - MOVCS charptr, charptr, ASL #1 ; Double address if SizeY = 16 - SUBCS charptr, charptr, #1 ; (tricky code, originally - ; designed by TMD) - - SUB cyb, cyt, sizey - ADD cyb, cyb, #1 ; where bottom pixel would be - ADD cxr, cxl, #7 ; where right pixel would be - - ASSERT GWBRow = GWLCol+4 - ASSERT GWRCol = GWLCol+8 - ASSERT GWTRow = GWLCol+12 - ASSERT cyb3 > cxl2 - ASSERT cxr2 > cyb3 - ASSERT R14 > cxr2 - ADD cxl2, WsPtr, #GWLCol - LDMIA cxl2, {cxl2, cyb3, cxr2, R14} - - Greatest cxl2, cxl2, cxl ; cxl2 := windowed left - ; (2 instructions) - Least cxr2, cxr2, cxr ; cxr2 := windowed right - ; (2 instructions) - Greatest cyb2, cyb3, cyb ; cyb2 := windowed bottom - ; (3 instructions) - Least cyt2, R14, cyt ; cyt2 := windowed top - ; (3 instructions) - - SUBS cyb2, cyt2, cyb2 ; top >= bottom ? - CMPGE cxr2, cxl2 ; and right >= left ? - Pull "PC", LT ; Exit if not. Otherwise cyb2 - ; has become clipped height - - LDR R14, [WsPtr, #CursorFlags] ; update changed box, if wanted - TST R14, #ClipBoxEnableBit - BLNE ClipVdu5 - - ADD charptr, charptr, cyt ; adjust charptr to point at - SUB charptr, charptr, cyt2 ; first used row of character - - MOV charmsk, #&FF ; Produce mask to do left/right - SUB R14, cxl2, cxl ; clipping - MOV charmsk, charmsk, LSR R14 - SUB R14, cxr2, cxl2 - ADD R14, R14, #1 - BIC charmsk, charmsk, charmsk, LSR R14 - - TEQ sizey, #16 ; If double height, signal this - ORREQ charmsk, charmsk, #1:SHL:31 ; by making charmsk negative - - ASSERT llength > scr - ASSERT LineLength = YWindLimit+4 - LDR lgBPC, [WsPtr, #Log2BPC] ; Address point at (cxl, cyt2), - MOV charshf, cxl, LSL lgBPC ; putting address in scr, bit - ADD scr, WsPtr, #YWindLimit ; offset in charshf and - LDMIA scr, {scr, llength} ; adjusting ecfptr - SUB scr, scr, cyt2 - AND R14, scr, #7 - ADD ecfptr, ecfptr, R14, LSL #3 - LDR R14, [WsPtr, #ScreenStart] - MLA scr, llength, scr, R14 - MOV R14, charshf, ASR #5 - ADD scr, scr, R14, LSL #2 - AND charshf, charshf, #31 - - MLA scrend, llength, cyb2, scr ;Calculate terminating address - - RSB invcharshf, charshf, #32 ;And inverse shift - -Vdu5NextLine - ASSERT eormask > ormask - LDMIA ecfptr!, {ormask, eormask} ;Pick up ecf info and advance - TST ecfptr, #63 ; ecf pointer, wrapping if - SUBEQ ecfptr, ecfptr, #64 ; necessary - - ASSERT HardFont < &40000000 :LOR: HardFont >= &C0000000 - ASSERT WsPtr < &40000000 :LOR: WsPtr >= &C0000000 - TEQ charmsk, #0 ; Double height? (MI=yes) - LDRMIB charbyte, [charptr, -charptr, ASR #1] ; Use ASR, as font will be at - LDRPLB charbyte, [charptr] ; top or bottom of memory (zero page, - ADD charptr, charptr, #1 ; system heap or ROM) - - ANDS charbyte, charbyte, charmsk ;Clip left & right; skip loop - BEQ Vdu5TryNextLine ; body if nothing to plot - - Push "ecfptr,scrend,charmsk,llength,charptr" - - LDR R14, [WsPtr, #TextExpandArea] ;Address correct expansion - - ADD charptr, charbyte, #&100 ; table entry, assuming that - ADD charptr, R14, charptr, LSL lgBPC ; this is not mode 10 or greater - - CMP lgBPC, #1 ;Pick up this entry: - LDRLSB cword0, [charptr, #0] ; 1 byte if lgBPC = 0 - LDREQB R14, [charptr, #1] ; 2 bytes if lgBPC = 1 - ORREQ cword0, cword0, R14, LSL #8 - MOV cword1, #0 - BLS Vdu5DoOneWord - CMP lgBPC, #3 - LDRLO cword0, [charptr, #0] ; 1 word if lgBPC = 2 - BLO Vdu5DoOneWord - BHI Vdu5Mode10 ; 4 words if lgBPC = 4 - LDMIA charptr, {cword0, cword1} ; 2 words if lgBPC = 3 - MOVS cword2, cword1, LSR invcharshf - - MACRO -$l DoVdu5Word $c, $reg, $off -$l - LDR$c chartmp, [scr, #$off] - AND$c R14, ormask, $reg - ORR$c chartmp, chartmp, R14 - AND$c R14, eormask, $reg - EOR$c chartmp, chartmp, R14 - STR$c chartmp, [scr, #$off] - MEND - -Vdu5DoTwoWords - DoVdu5Word NE, cword2, 8 - MOV cword1, cword1, LSL charshf -Vdu5DoOneWord - ORRS cword1, cword1, cword0, LSR invcharshf - DoVdu5Word NE, cword1, 4 - MOVS cword0, cword0, LSL charshf - DoVdu5Word NE, cword0, 0 - -Vdu5LinePainted - Pull "ecfptr,scrend,charmsk,llength,charptr" - -Vdu5TryNextLine - TEQ scr, scrend - ADDNE scr, scr, llength - BNE Vdu5NextLine - - Pull "PC" - -; This is mode 10 (or similar) - we must do bit expansion on the fly - -Vdu5Mode10 - CMP lgBPC, #5 ; is this a 32 bit per pixel mode, if so then ignore the - BEQ Vdu5Mode32 ; existing code and use a newer function - - ADRL charptr, C16BTab - AND R14, charbyte, #&0F - ADD R14, charptr, R14, LSL #3 - LDMIA R14, {cword0, cword1} - - MOVS cword2, cword1, LSR invcharshf - DoVdu5Word NE, cword2, 16 - MOV cword1, cword1, LSL charshf - ORRS cword1, cword1, cword0, LSR invcharshf - DoVdu5Word NE, cword1, 12 - MOVS cword2, cword0, LSL charshf - - AND R14, charbyte, #&F0 - ADD R14, charptr, R14, LSR #1 - LDMIA R14, {cword0, cword1} - ORRS cword2, cword2, cword1, LSR invcharshf - B Vdu5DoTwoWords - -; Expand the character data out to 32 bit per pixel (mode 48 or similar) - - MACRO -$l PixMunge32 $reg, $mask, $offset -$l - TST $reg, #$mask - LDRNE chartmp, [scr, #$offset] - ORRNE chartmp, chartmp, ormask - EORNE chartmp, chartmp, eormask - STRNE chartmp, [scr, #$offset] - MEND - - MACRO -$l PixSolid32 $reg, $mask, $offset -$l - TST $reg, #$mask - STRNE chartmp, [scr, #$offset] - MEND - -; Perform bit expansion on the fly, this is a word based operation, no need to -; extract sub-pixels from the ORR / EOR masks, simply perform the bit test and -; then write the character data to the screen! - -Vdu5Mode32 - - [ AvoidScreenReads - CMP ormask, #&FFFFFFFF - BNE Vdu5Mode32_NotSolid - - MVN chartmp, eormask - PixSolid32 charbyte, 1<<7, 0 - PixSolid32 charbyte, 1<<6, 4 - PixSolid32 charbyte, 1<<5, 8 - PixSolid32 charbyte, 1<<4, 12 - PixSolid32 charbyte, 1<<3, 16 - PixSolid32 charbyte, 1<<2, 20 - PixSolid32 charbyte, 1<<1, 24 - PixSolid32 charbyte, 1<<0, 28 - - B Vdu5LinePainted - -Vdu5Mode32_NotSolid - ] - PixMunge32 charbyte, 1<<7, 0 - PixMunge32 charbyte, 1<<6, 4 - PixMunge32 charbyte, 1<<5, 8 - PixMunge32 charbyte, 1<<4, 12 - PixMunge32 charbyte, 1<<3, 16 - PixMunge32 charbyte, 1<<2, 20 - PixMunge32 charbyte, 1<<1, 24 - PixMunge32 charbyte, 1<<0, 28 - - B Vdu5LinePainted ; flow down and try the next line - - -; ***************************************************************************** -; -; Slow VDU 5 - Print char by scaled method (in SprExtend) -; -; in: R1 (ecfptr) = pointer to ecf pattern -; R7 (sizex) = SizeX -; R8 (sizey) = SizeY -; R9 (charbyte) = character to plot -; -; Stack: Return address -; - - ASSERT ecfptr = R1 - ASSERT sizex = R7 - ASSERT sizey = R8 - ASSERT charbyte = R9 - -SlowVdu5 ROUT - - MOV R10, R1 ; R10 := ecfptr - -; now save current GCOL on stack if necessary - - ADD R11, WsPtr, #FgEcfOraEor - TEQ R10, R11 ; if going to use this one - BEQ %FT20 ; then skip - - MOV R0, #64 ; 64 bytes -10 - LDMIA R11, {R3-R6} ; copy old GCOL into stack - Push "R3-R6" ; frame, reversing order of - ; 16 byte chunks - LDMIA R10!, {R3-R6} ; copy new colour - STMIA R11!, {R3-R6} ; into GCOL - SUBS R0, R0, #16 - BNE %BT10 - -20 - MOV R4, #8 - MOV R5, #8 - Push "R4,R5" - Push "R7,R8" - MOV R6, R13 ; R6 -> scaling block - - SUB R1, R8, #1 ; SizeY-1 - LDR R5, [WsPtr, #YEigFactor] - ADD R3, WsPtr, #GCsX - LDMIA R3, {R3, R4} ; R3 = ext X; R4 = ext Y (top) - SUB R4, R4, R1, LSL R5 ; R4 = ext Y (bottom) - MOV R1, R9 ; R1 = char - MOV R0, #SpriteReason_PaintCharScaled - SWI XOS_SpriteOp - - ADD R13, R13, #4*4 ; junk scaling block - - TEQ R10, R11 ; if we didn't copy GCOLs - Pull "PC", EQ ; then return, else copy back - - MOV R0, #64 -30 - Pull "R3-R6" ; Reverse order of 16 byte - STMDB R11!, {R3-R6} ; chunks during copy again - SUBS R0, R0, #16 - BNE %BT30 - Pull PC - - -; ***************************************************************************** -; -; VDU 5 - Start printing text at graphics cursor - -ENQ - GraphicsMode R0 - MOVNE PC, R14 - - MOV R1, #0 - BSR CursorOnOff ; turn cursor off without - ; saving to copy - - LDR R6, [WsPtr, #CursorFlags] - ORR R6, R6, #Vdu5Bit - B R6toCursorFlags - -; ***************************************************************************** -; -; VDU 4 - Return to printing text at text cursor - -EOT - GraphicsMode R0 - MOVNE PC,LR - - MOV R1, #1 - BSR CursorOnOff ; restore cursor from copy - - LDR R6, [WsPtr, #CursorFlags] - BIC R6, R6, #Vdu5Bit - B R6toCursorFlags - -; ***************************************************************************** -; -; Vdu5HT - Move cursor "right" when in VDU 5 mode -; -; in: R6 = CursorFlags - -Vdu5HT - Push R14 - BL GCursorMove ; try to move in +ve X direction - BCC EndVdu5HT ; if successful, finish - BL GCursorB0 ; else move cursor to -ve X boundary -Vdu5HT10 - EOR R6, R6, #8 ; change to +ve Y direction - BL GCursorMove ; try to move in that direction - BLCS GCursorB0 ; if unsuccessful, move to -ve Y bdy -EndVdu5HT - Pull R14 - B IEG - -; ***************************************************************************** -; -; Vdu5BS - Move cursor "left" when in VDU 5 mode -; -; in: R6 = CursorFlags - -Vdu5BS - EOR R6, R6, #6 ; go to -ve X direction - B Vdu5HT ; dead easy, huh ? - -; ***************************************************************************** -; -; Vdu5LF - Move cursor "down" when in VDU 5 mode -; -; in: R6 = CursorFlags - -Vdu5LF - Push R14 - B Vdu5HT10 - -; ***************************************************************************** -; -; Vdu5VT - Move cursor "up" when in VDU 5 mode -; -; in: R6 = CursorFlags - -Vdu5VT - EOR R6, R6, #6 ; go to -ve Y direction (eventually) - B Vdu5LF - -; ***************************************************************************** -; -; Vdu5CR - Carriage return in VDU 5 mode -; -; in: R6 = CursorFlags - -Vdu5CR - BSR GCursorB0 - B IEG - -; ***************************************************************************** -; -; Vdu5FF - Clear screen in VDU 5 mode -; -; in: R6 = CursorFlags - -Vdu5FF - BSR Home - B CLG - -; ***************************************************************************** -; -; Vdu5TAB - TAB(X,Y) in VDU 5 mode -; -; in: R0 = X, R1 = Y, R6 = CursorFlags - -Vdu5TAB - BSR GCursorBdy - EOR R6, R6, #8 - MOV R0, R1 - BSR GCursorBdy - B IEG - -; ***************************************************************************** -; -; Vdu5Delete - Delete in VDU 5 mode (already done backspace) -; -; in: R6 = CursorFlags - -Vdu5Delete - ADD ecfptr, WsPtr, #BgEcfStore ; STORE background colour/ecf - MOV R0, #127 ; uses hard font for this char - B Vdu5DoChar10 - -; ***************************************************************************** -; -; GCursorMove - Move graphics cursor in direction specified by R6 -; (0,4 = right; 2,6 = left; 8,10 = down; 12,14 = up) -; R6 is preserved - -GCursorMove - ADD R0, WsPtr, #GCsIX - LDMIA R0, {R0, R1} ; R0 = GCsIX; R1 = GCsIY - ADD R2, WsPtr, #GCharSpacing+8 ; +8 needed to address it - LDMDB R2, {R2, R3} ; R2=GCharSpaceX;R3=GCharSpaceY - WINDow R0, R1, R8,R9,R10,R11 ; return LT if outside window - ADR R7, GCMVTab - B DoJumpTable - -GCMVTab - & GMoveRight-GCMVTab - & GMoveLeft-GCMVTab - & GMoveRight-GCMVTab - & GMoveLeft-GCMVTab - & GMoveDown-GCMVTab - & GMoveDown-GCMVTab - & GMoveUp-GCMVTab - & GMoveUp-GCMVTab - -; Move graphics cursor right if possible - on exit C=0 iff OK to move - -GMoveRight - ADD R0, R0, R2 ; add on GCharSpaceX -GMove10 - STR R0, [WsPtr, #GCsIX] -GMove15 - BLT GMoveOK ; if we were outside already - TST R6, #&40 ; or we are in nowrap mode - BNE GMoveOK ; then we were OK to move - WINDow R0, R1, R8,R9,R10,R11 - BGE GMoveOK ; if inside now, then OK - SEC - MOV PC, R14 - -GMoveOK - CLC - MOV PC, R14 - -; Move graphics cursor left if possible - on exit C=0 iff OK to move - -GMoveLeft - SUB R0, R0, R2 ; subtract off GCharSpaceX - B GMove10 - -; Move graphics cursor down if possible - on exit C=0 iff OK to move - -GMoveDown - SUB R1, R1, R3 ; subtract off GCharSpaceY -GMove20 - STR R1, [WsPtr, #GCsIY] - B GMove15 - -; Move graphics cursor up if possible - on exit C=0 iff OK to move - -GMoveUp - ADD R1, R1, R3 ; add on GCharSpaceY - B GMove20 - -; ***************************************************************************** -; -; Move graphics cursor to boundary indicated by value of R6 in bits 1-3 -; (0 or 4 = left, 2 or 6 = right, 8 or 10 = up, 12 or 14 = down) -; + R0 character positions in -; - -GCursorB0 - MOV R0, #0 -GCursorBdy - ADR R7, GCBDYTab - B DoJumpTable - -GCBDYTab - & GCursorLBdy-GCBDYTab - & GCursorRBdy-GCBDYTab - & GCursorLBdy-GCBDYTab - & GCursorRBdy-GCBDYTab - & GCursorUBdy-GCBDYTab - & GCursorUBdy-GCBDYTab - & GCursorDBdy-GCBDYTab - & GCursorDBdy-GCBDYTab - -; Move graphics cursor to left boundary + R0 characters in - -GCursorLBdy - LDR R7, [WsPtr, #GWLCol] - LDR R2, [WsPtr, #GCharSpaceX] - MLA R0, R2, R0, R7 ; GCsIX := GWLCol + (X*SpaceX) - STR R0, [WsPtr, #GCsIX] - MOV PC, R14 - -; Move graphics cursor to right boundary + R0 characters in -; (adjust for character size) - -GCursorRBdy - LDR R7, [WsPtr, #GWRCol] - LDR R2, [WsPtr, #GCharSizeX] - SUB R7, R2, R7 ; R7 = SizeX-GWRCol - LDR R2, [WsPtr, #GCharSpaceX] - MLA R0, R2, R0, R7 ; R0 = SizeX-GWRCol+X*SpaceX - RSB R0, R0, #1 ; GWRCol-X*SpaceX-(SizeX-1) - STR R0, [WsPtr, #GCsIX] - MOV PC, R14 - -; Move graphics cursor to up boundary + R0 characters in - -GCursorUBdy - LDR R7, [WsPtr, #GWTRow] - LDR R2, [WsPtr, #GCharSpaceY] - RSB R2, R2, #0 ; -SizeY - MLA R0, R2, R0, R7 ; GWTRow-Y*SizeY - STR R0, [WsPtr, #GCsIY] - MOV PC, R14 - -; Move graphics cursor to down boundary + R0 characters in -; (adjust for character size) - -GCursorDBdy - LDR R7, [WsPtr, #GWBRow] - LDR R2, [WsPtr, #GCharSpaceY] - MLA R0, R2, R0, R7 ; GWBRow+Y*SpaceY - LDR R2, [WsPtr, #GCharSizeY] - ADD R0, R0, R2 - SUB R0, R0, #1 ; GWBRow+Y*SpaceY+(SizeY-1) - STR R0, [WsPtr, #GCsIY] - MOV PC, R14 - -; ***************************************************************************** -; -; ClipVdu5 - Add a VDU 5 char to clip box -; -; in: cxl2 = left -; cyb2 = top-bottom -; cxr2 = right -; cyt2 = top -; -; out: All registers preserved -; - - ASSERT (cxl2=R4) :LAND: (cyb2=R3) :LAND: (cxr2=R10) :LAND: (cyt2=R2) - -ClipVdu5 ROUT - Push "R0-R3, R4, R10, R14" - MOV R0, cxl2 - SUB R1, cyt2, cyb2 ; top-(top-bottom) = bottom - MOV R3, cyt2 - MOV R2, cxr2 - BL MergeClipBox - Pull "R0-R3, R4, R10, PC" - - END diff --git a/s/vdu/vducursoft b/s/vdu/vducursoft deleted file mode 100644 index e25dc363..00000000 --- a/s/vdu/vducursoft +++ /dev/null @@ -1,712 +0,0 @@ -; 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.VduCurSoft - -SlowCursorSpeed * 16 -FastCursorSpeed * 8 -OnFlashTime * 48 -OffFlashTime * 16 - -; InitCursor - initialise cursor shape and address - -InitCursor ROUT - Push R14 - LDR R6, [WsPtr, #CursorFlags] - TST R6, #TeletextMode ; if teletext mode - MOVNE R0, #&72 ; then start at 9 (slow flash) - MOVEQ R0, #&67 ; else start at 7 (slow flash) - BL ProgReg10AndCopy - - MOV R0, #1 ; set to flash immediately - STR R0, [WsPtr, #CursorCounter] ; AFTER setting CursorSpeed - ; in case VSYNC happens - LDR R1, [WsPtr, #VduSprite] - TEQ R1, #0 ; if outputting to sprite - MOVNE R0, #&20 ; then turn cursor off - BLNE ProgReg10AndCopy - - LDR R0, [WsPtr, #RowMult] ; 8 or 10 or 16 or 20 - Pull R14 - -; and drop thru to ... - -SetCursorBottom - LDR R1, [WsPtr, #LineLength] - MUL R2, R1, R0 - STR R2, [WsPtr, #CursorEndOffset] - MOV PC, R14 - -SetCursorTop - LDR R1, [WsPtr, #LineLength] - MUL R2, R1, R0 - STR R2, [WsPtr, #CursorStartOffset] - MOV PC, R14 - -; ***************************************************************************** - -; Cursors are split, so remove output cursor - -DoOutputCursor ROUT - Push R14 - LDR R1, [WsPtr, #LineLength] - MOV R1, R1, LSL #3 ; and end after 8 rows - LDR R0, [WsPtr, #ModeFlags] - TST R0, #Flag_DoubleVertical ; if double vertical - ADDNE R1, R1, R1 ; end after 16 rows - MOV R0, #0 ; start on top line - BL EORCursor - LDR R2, [WsPtr, #InputCursorAddr] ; flashing cursor is at input - Pull R14 - B PreWC10 - -; ***************************************************************************** -; -; PreWrchCursor - Remove cursors prior to Wrch -; -; out: R6 = new CursorFlags; R5,R7 preserved; others corrupted -; - -PreWrchCursor - -; Need to disable IRQs here to stop Vsync modifying CursorFlags in between -; us reading it and writing it - - [ No26bitCode - MRS R3, CPSR - ORR R1, R3, #I32_bit - MSR CPSR_c, R1 - | - SETPSR I_bit, R1 - ] - LDR R6, [WsPtr, #CursorFlags] - MOVS R0, R6, LSL #(32-InWrchBitPosn) ; CS => was already off - ORRCC R6, R6, #InWrchBit ; protect against vsyncs - STRCC R6, [WsPtr, #CursorFlags] - - LDR R0, [WsPtr, #CursorStack] - MOV R0, R0, RRX ; shift down + put current - ; state in top bit - STR R0, [WsPtr, #CursorStack] - - [ No26bitCode - MSR CPSR_c, R3 ; restore old I bit - MOVCS PC, R14 ; already off, so exit - | - MOVCSS PC, R14 ; already off, so exit - ; (restoring I_bit) - TEQP R14, #0 ; restore old I_bit - ] - - LDR R2, [WsPtr, #CursorAddr] ; point to output - TST R6, #CursorsSplit - BNE DoOutputCursor -PreWC10 - TST R6, #ActualState - MOVEQ PC, R14 ; flash cursor is off anyway - BIC R6, R6, #ActualState - STR R6, [WsPtr, #CursorFlags] - -; and drop thru to EORFlashCursor - -; ***************************************************************************** -; -; EORCursor - Exclusive-OR cursor with screen -; -; in: R0 = Start offset from top of cursor -; R1 = End+1 offset -; R2 = Screen address of appropriate cursor -; R6 = CursorFlags -; -; out: R5-R7 preserved; R0-R4, R8-R11 corrupted -; - -EORFlashCursor - ASSERT CursorEndOffset-CursorStartOffset=4 - ADD R0, WsPtr, #CursorStartOffset - LDMIA R0, {R0,R1} -EORCursor - CMP R0, R1 - MOVCS PC, R14 ; top >= bottom, so nowt - - ADD R1, R1, R2 - - LDR R3, [WsPtr, #LineLength] - - ASSERT CursorNbit = CursorFill +4 - ADD R4, WsPtr, #CursorFill - LDMIA R4, {R4, PC} ; load CursorFill and CursorNbit - -Cursor1bit - LDRB R8, [R0, R2]! - EOR R8, R8, R4 - STRB R8, [R0], R3 - TEQ R0, R1 - MOVEQ PC, R14 -Cursor1loop - LDRB R8, [R0] - EOR R8, R8, R4 - STRB R8, [R0], R3 - TEQ R0, R1 - BNE Cursor1loop - MOV PC, R14 - -Cursor2bit - ADD R0, R0, R2 -Cursor2loop - LDRB R8, [R0, #1] - EOR R8, R8, R4 - STRB R8, [R0, #1] - LDRB R8, [R0] - EOR R8, R8, R4 - STRB R8, [R0], R3 - TEQ R0, R1 - BNE Cursor2loop - MOV PC, R14 - -CursorTeletext - [ TTX256 - ASSERT HiResTTX - Push "R0, R1, R14" - ADD R0, R0, #320*1024 ; go to other screen - ADD R1, R1, #320*1024 - BL Cursor16bit - Pull "R0, R1, R14" - B Cursor16bit - | - [ HiResTTX - Push "R0, R1, R14" - ADD R0, R0, #160*1024 ; go to other screen - ADD R1, R1, #160*1024 - BL Cursor8bit - Pull "R0, R1, R14" - B Cursor8bit - | - Push "R0, R1, R14" - ADD R0, R0, #40*1024 ; go to other screen - ADD R1, R1, #40*1024 - BL Cursor4bit - Pull "R0, R1, R14" - -; and drop thru to ... - ] - ] - -Cursor4bit - LDR R8, [R0, R2]! - EOR R8, R8, R4 - STR R8, [R0], R3 - TEQ R0, R1 - MOVEQ PC, R14 -Cursor4loop - LDR R8, [R0] - EOR R8, R8, R4 - STR R8, [R0], R3 - TEQ R0, R1 - BNE Cursor4loop - MOV PC, R14 - -Cursor8bit - ADD R0, R0, R2 -Cursor8loop - LDMIA R0, {R8,R9} - EOR R8, R8, R4 - EOR R9, R9, R4 - STMIA R0, {R8,R9} - ADD R0, R0, R3 - TEQ R0, R1 - BNE Cursor8loop - MOV PC, R14 - -Cursor16bit - ADD R0, R0, R2 -Cursor16loop - LDMIA R0, {R8-R11} - EOR R8, R8, R4 - EOR R9, R9, R4 - EOR R10, R10, R4 - EOR R11, R11, R4 - STMIA R0, {R8-R11} - ADD R0, R0, R3 - TEQ R0, R1 - BNE Cursor16loop - MOV PC, R14 - -Cursor32bit - ADD R0, R0, R2 - SUB R3, R3, #32 -Cursor32loop - LDMIA R0, {R8-R11} - EOR R8, R8, R4 - EOR R9, R9, R4 - EOR R10, R10, R4 - EOR R11, R11, R4 - STMIA R0!, {R8-R11} - LDMIA R0, {R8-R11} - EOR R8, R8, R4 - EOR R9, R9, R4 - EOR R10, R10, R4 - EOR R11, R11, R4 - STMIA R0!, {R8-R11} - ADD R0, R0, R3 - TEQ R0, R1 - BNE Cursor32loop - MOV PC, R14 - -; ***************************************************************************** -; -; PostWrchCursor - Put back cursors after Wrch -; -; out: R6 = new CursorFlags, R5,R7 preserved, all others undefined -; - -PostWrchCursor - LDR R6, [WsPtr, #CursorFlags] - LDR R0, [WsPtr, #CursorStack] - MOVS R0, R0, LSL #1 - STR R0, [WsPtr, #CursorStack] - MOVCS PC, R14 ; we're still off, so do nowt - - Push R14 - [ ForceMark - LDR R0, [WsPtr, #CursorCounter] - TEQ R0, #0 ; are we flashing - LDRNE R0, [WsPtr, #CursorSpeed] ; force to start of mark state - STRNE R0, [WsPtr, #CursorCounter] - MOVNE R0, #ActualState - STRNE R0, [WsPtr, #CursorDesiredState] - ] - - [ RePlot - LDR R1, [WsPtr, #CursorDesiredState] - EOR R1, R1, R6 ; EOR of desired and actual - ANDS R1, R1, #ActualState ; just get that bit - BEQ PWC10 ; same, then go home - - EOR R6, R1, R6 ; EOR actual bit - - TST R6, #CursorsSplit - LDRNE R2, [WsPtr, #InputCursorAddr] - LDREQ R2, [WsPtr, #CursorAddr] - BL EORFlashCursor -PWC10 - ] - - BIC R6, R6, #InWrchBit ; coming out of wrch now - TST R6, #CursorsSplit - STREQ R6, [WsPtr, #CursorFlags] - Pull PC, EQ ; return if no output cursor - - LDR R2, [WsPtr, #CursorAddr] - LDR R1, [WsPtr, #LineLength] - MOV R1, R1, LSL #3 ; and end after 8 rows - LDR R0, [WsPtr, #ModeFlags] - TST R0, #Flag_DoubleVertical ; if double vertical - ADDNE R1, R1, R1 ; end after 16 rows - MOV R0, #0 ; start on top line - BL EORCursor - STR R6, [WsPtr, #CursorFlags] ; only clear it now ? - Pull PC - - -; ***************************************************************************** - -VsyncCall ROUT - Push "R0-R11,R14" - - [ AssemblePointerV - BL PollPointer - ] - BL UpdatePointer - - LDR R6, [WsPtr, #CursorFlags] - TST R6, #TeletextMode - BLNE TeletextFlashTest ; if TTX, do other stuff -VsyncReturn - LDR R1, [WsPtr, #CursorDesiredState] - LDR R0, [WsPtr, #CursorCounter] - SUBS R0, R0, #1 - LDREQ R0, [WsPtr, #CursorSpeed] ; if is zero, reload - EOREQ R1, R1, #ActualState ; and toggle desired state - STREQ R1, [WsPtr, #CursorDesiredState] - - STRCS R0, [WsPtr, #CursorCounter] ; store back unless was frozen - - TST R6, #InWrchBit - Pull "R0-R11,PC", NE ; in wrch, so don't touch screen - ; or modify CursorFlags - - EOR R1, R1, R6 ; EOR of desired and actual - ANDS R1, R1, #ActualState ; just get that bit - Pull "R0-R11,PC", EQ ; same, then go home - - EOR R6, R1, R6 ; EOR actual bit - STR R6, [WsPtr, #CursorFlags] - - TST R6, #CursorsSplit - LDRNE R2, [WsPtr, #InputCursorAddr] - LDREQ R2, [WsPtr, #CursorAddr] - BL EORFlashCursor - - Pull "R0-R11,PC" - -; ***************************************************************************** - -TeletextFlashTest ROUT - LDR R3, [WsPtr, #TeletextCount] - SUBS R3, R3, #1 - BNE %FT20 ; count not expired - - LDR R1, [WsPtr, #TeletextOffset] - [ TTX256 - ASSERT HiResTTX - EORS R1, R1, #320*1024 ; switch to other flash bank - | - [ HiResTTX - EORS R1, R1, #160*1024 ; switch to other flash bank - | - EORS R1, R1, #40*1024 ; switch to other flash bank - ] - ] - STR R1, [WsPtr, #TeletextOffset] - MOVEQ R3, #OnFlashTime - MOVNE R3, #OffFlashTime - LDR R0, [WsPtr, #DisplayStart] - BL SetVinit ; preserves R3 -20 - STR R3, [WsPtr, #TeletextCount] - B VsyncReturn - -; ***************************************************************************** -; -; Vdu23_0_10 - Program cursor start, flash/steady, on/off -; - -Vdu23_0_10 - LDRB R0, [WsPtr, #QQ+2] ; get parameter -ProgReg10AndCopy - STR R0, [WsPtr, #Reg10Copy] - -; and drop thru to ... - -ProgReg10 - AND R1, R0, #&60 - CMP R1, #&40 - BCS IsFlashing - MOV R2, #0 - STR R2, [WsPtr, #CursorCounter] ; freeze the flashing - TST R1, #&20 - MOVEQ R2, #ActualState ; steady cursor - STR R2, [WsPtr, #CursorDesiredState] - B PR1010 - -IsFlashing - TST R1, #&20 - MOVEQ R2, #FastCursorSpeed - MOVNE R2, #SlowCursorSpeed - STR R2, [WsPtr, #CursorSpeed] - LDR R2, [WsPtr, #CursorCounter] - TEQ R2, #0 ; was flashing frozen ? - ; if not, don't perturb flash - MOVEQ R2, #1 ; set to flash immediately - STREQ R2, [WsPtr, #CursorCounter] - -PR1010 - AND R0, R0, #&1F ; get start position bits - TST R6, #TeletextMode ; if teletext mode - MOVNE R0, R0, LSR #1 ; then divide by 2 - LDR R1, [WsPtr, #ModeFlags] - TST R1, #Flag_DoubleVertical ; if double vertical - MOVNE R0, R0, LSL #1 ; then double cursor value - - LDR R1, [WsPtr, #RowMult] - CMP R0, R1 ; is it > rowmult ? - MOVHI R0, R1 ; set to rowmult if so - B SetCursorTop - - -; ***************************************************************************** -; -; Vdu23_0_11 - Program cursor end -; - -Vdu23_0_11 - LDRB R0, [WsPtr, #QQ+2] ; get parameter - TST R6, #TeletextMode ; if teletext - MOVNE R0, R0, LSR #1 ; then divide by 2 - - ADD R0, R0, #1 ; get end line +1 - - LDR R1, [WsPtr, #ModeFlags] - TST R1, #Flag_DoubleVertical ; if double vertical - MOVNE R0, R0, LSL #1 ; then double cursor value - - LDR R1, [WsPtr, #RowMult] - CMP R0, R1 - MOVHI R0, R1 ; if > rowmult, set to rowmult - B SetCursorBottom - -; ***************************************************************************** -; -; Vdu23_1 - Program cursor -; - -Vdu23_1 - LDR R0, [WsPtr, #CursorFlags] - TST R0, #Vdu5Bit - MOVNE PC, R14 ; none of this nonsense in VDU5 mode - - LDRB R1, [WsPtr, #QQ+1] ; get parameter - -CursorOnOff - CMP R1, #1 - MOVCC R0, #&20 ; 0 -> just turn off - LDRCS R0, [WsPtr, #Reg10Copy] ; 1,2,3 -> read old state - BLS ProgReg10 ; 0,1 -> program hardware - TEQ R1, #2 - BICEQ R0, R0, #&60 ; 2 -> steady - ORRNE R0, R0, #&60 ; 3 -> slow flashing - STR R0, [WsPtr, #Reg10Copy] ; save in copy - B ProgReg10 - -; ***************************************************************************** -; -; DoCursorEdit -; -; in: R0 = &87 => COPY -; &88 => cursor left -; &89 => cursor right -; &8A => cursor down -; &8B => cursor up -; -; out: C=0 => doing COPY and valid character -; C=1 otherwise -; - - -DoCursorEdit - LDR R6, [WsPtr, #CursorFlags] - TEQ R0, #&87 - BNE IsCursorMove - -; COPY character under cursor - - Push R14 - TST R6, #CursorsSplit - BEQ BadCopyExit ; cursors not split so don't copy - - TST R6, #Vdu5Bit - BNE BadCopyExit ; can't copy in VDU5 mode - - BL ReadCharacter - - TEQ R0, #0 - BEQ BadCopyExit - - BL VDUBE ; is a cursor movement valid ? - BNE DoCE10 - - Push R0 - BL PreWrchCursor - BL InputCursorHT - BL PostWrchCursor - Pull R0 - -DoCE10 - CLC - Pull PC - -BadCopyExit - BL BEL ; make bell sound - SEC - Pull PC - -; ***************************************************************************** -; -; VDUBE - Check if valid to move cursor -; -; out: R0 preserved -; R1 = 0 => OK, R1<>0 => OK -; R6 = CursorFlags -; Z => OK, NZ => not OK -; C = 1 - -VDUBE - LDR R6, [WsPtr, #CursorFlags] - LDROSB R1, VDUqueueItems ; zero if not buffering - TEQ R1, #0 - - ANDEQS R1, R6, #Vdu5Bit ; zero if not in VDU 5 mode - -; insert check for vdu disabled here - - CMP R1, #0 ; set Z on R1, C:=1 - MOV PC, R14 - -; ***************************************************************************** - -IsCursorMove - Push R14 - BL VDUBE - Pull PC, NE - - Push R0 - BL PreWrchCursor ; remove both cursors - Pull R0 - BL ICM10 - BL PostWrchCursor - - SEC - Pull PC - -ICM10 - TST R6, #CursorsSplit - BNE AlreadySplit - - Push R0 - LDR R0, [WsPtr, #Reg10Copy] - AND R0, R0, #&DF ; use double flash rate - BSR ProgReg10 - - LDR R0, [WsPtr, #CursorX] ; copy parameters - STR R0, [WsPtr, #InputCursorX] - LDR R0, [WsPtr, #CursorY] - STR R0, [WsPtr, #InputCursorY] - LDR R0, [WsPtr, #CursorAddr] - STR R0, [WsPtr, #InputCursorAddr] - - ORR R6, R6, #CursorsSplit - STR R6, [WsPtr, #CursorFlags] - - Pull R0 - -AlreadySplit - CMP R0, #&89 - BCC InputCursorLeft ; &88 - BEQ InputCursorRight ; &89 - CMP R0, #&8B - BCC InputCursorDown ; &8A - -; and drop thru to ... - -InputCursorUp - LDR R1, [WsPtr, #InputCursorY] - LDR R2, [WsPtr, #InputCursorAddr] - LDR R3, [WsPtr, #RowLength] - LDR R4, [WsPtr, #TWTRow] - - SUB R1, R1, #1 - SUB R2, R2, R3 - CMP R1, R4 - LDRLT R1, [WsPtr, #TWBRow] - STR R1, [WsPtr, #InputCursorY] ; need signed comparison - STRGE R2, [WsPtr, #InputCursorAddr] ; in case Y went -ve - MOVGE PC, R14 - B AddressInputCursor - -InputCursorDown - LDR R1, [WsPtr, #InputCursorY] - LDR R2, [WsPtr, #InputCursorAddr] - LDR R3, [WsPtr, #RowLength] - LDR R4, [WsPtr, #TWBRow] - - ADD R1, R1, #1 - ADD R2, R2, R3 - CMP R1, R4 - LDRHI R1, [WsPtr, #TWTRow] - STR R1, [WsPtr, #InputCursorY] - STRLS R2, [WsPtr, #InputCursorAddr] - MOVLS PC, R14 - -; and drop thru to ... - -AddressInputCursor - Push R14 - LDR R0, [WsPtr, #InputCursorX] - LDR R1, [WsPtr, #InputCursorY] - BL AddressR0R1 - STR R2, [WsPtr, #InputCursorAddr] - Pull PC - -AddressCursors - LDR R6, [WsPtr, #CursorFlags] - TST R6, #CursorsSplit - BEQ AddressCursor - BSR AddressInputCursor - B AddressCursor - - -InputCursorLeft - LDR R0, [WsPtr, #InputCursorX] - LDR R2, [WsPtr, #InputCursorAddr] - [ HiResTTX - LDR R3, [WsPtr, #CharWidth] - | - LDR R3, [WsPtr, #BytesPerChar] - ] - LDR R4, [WsPtr, #TWLCol] - - SUB R0, R0, #1 - SUB R2, R2, R3 - CMP R0, R4 - LDRLT R0, [WsPtr, #TWRCol] - STR R0, [WsPtr, #InputCursorX] - STRGE R2, [WsPtr, #InputCursorAddr] ; I do mean GE ! - MOVGE PC, R14 - - BSR AddressInputCursor - B InputCursorUp - -InputCursorRight - LDR R0, [WsPtr, #InputCursorX] - LDR R2, [WsPtr, #InputCursorAddr] - [ HiResTTX - LDR R3, [WsPtr, #CharWidth] - | - LDR R3, [WsPtr, #BytesPerChar] - ] - LDR R4, [WsPtr, #TWRCol] - - ADD R0, R0, #1 - ADD R2, R2, R3 - CMP R0, R4 - LDRHI R0, [WsPtr, #TWLCol] - STR R0, [WsPtr, #InputCursorX] - STRLS R2, [WsPtr, #InputCursorAddr] - MOVLS PC, R14 - - BSR AddressInputCursor - B InputCursorDown - -; ***************************************************************************** -; -; InputCursorHT - move input cursor "right" after copying -; - -InputCursorHT - Push R14 - LDR R6, [WsPtr, #CursorFlags] - BL InputCursorMove - BCC ICHTExit - - BL InputCursorB0 - BL AddressInputCursor - EOR R6, R6, #8 - BL InputCursorMove - BLCS InputCursorB0 -ICHTExit - Pull R14 - B AddressInputCursor - - END diff --git a/s/vdu/vdudecl b/s/vdu/vdudecl deleted file mode 100644 index 51a982a7..00000000 --- a/s/vdu/vdudecl +++ /dev/null @@ -1,423 +0,0 @@ -; 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.VduDecl - -; ARTHUR OPERATING SYSTEM - Vdu Drivers -; ======================= -; -; Vdu driver workspace and macro declarations -; -; Author R C Manby -; Date 5.9.86 -; - - GBLL ForceMark ; whether we force start of mark state -ForceMark SETL {FALSE} ; of cursor on exit from WRCH - - GBLL RePlot ; Re-plot cursor after wrch -RePlot SETL {TRUE} - - GBLL UseVLineOnSolidLines ; When TRUE VLine is assembled and used -UseVLineOnSolidLines SETL {TRUE} ; to plot vertical solid lines - - GBLL AvoidScreenReads ; When TRUE, use extra code to avoid -AvoidScreenReads SETL {TRUE} ; reading the screen when we can avoid it - -; -; Register usage -; ============== -; -StkPtr RN 13 ;Restore on exit to keep BASIC happy!! -Link RN 14 - -; -; Manifest constants -; ================== -; - -PhysCursorStartAdr * CursorSoundPhysRAM - -; Reason codes for generalised DAG interface - -HALDAG_VInit * 0 -HALDAG_VStart * 1 -HALDAG_VEnd * 2 -HALDAG_VRender * 3 - - - [ ModeSelectors - -; OS_ScreenMode reason codes - -ScreenModeReason_SelectMode * 0 -ScreenModeReason_ReturnMode * 1 -ScreenModeReason_EnumerateModes * 2 -ScreenModeReason_SelectMonitorType * 3 -ScreenModeReason_Limit * 4 - -; Mode selector format - - ^ 0 -ModeSelector_Flags # 4 ; flags word -ModeSelector_XRes # 4 ; x-resolution in pixels -ModeSelector_YRes # 4 ; y-resolution in pixels -ModeSelector_PixelDepth # 4 ; pixel depth (=Log2BPP) -ModeSelector_FrameRate # 4 ; nominal frame rate (in Hz) -ModeSelector_ModeVars # 0 ; start of pairs of (mode var index, value) - -ModeSelectorFlags_FormatMask * &FF -ModeSelectorFlags_ValidFormat * 1 - -ModeSelector_MaxSize * ModeSelector_ModeVars+(NumModeVars * 8)+4 - ; maximum size of a mode selector, with each mode variable overridden - ; plus terminator on end - - ] - - - -; -; Macro Definitions -; ================= -; - -; -; Macro Sort - Sort two values into increasing order -; - MACRO - Sort $lo, $hi - CMP $hi, $lo - EORLT $lo, $lo, $hi - EORLT $hi, $lo, $hi - EORLT $lo, $lo, $hi - MEND - -; -; Macro SortT - Sort two values into increasing order using a temporary reg -; - MACRO - SortT $lo, $hi, $temp - SUBS $temp, $hi, $lo - MOVLT $hi, $lo - ADDLT $lo, $lo, $temp - MEND - -; -; Macro CompSwap - Compare and sort a pair of coordinates into -; order of increasing Y -; If Y values equal, sort in order of decreasing X -; - MACRO - CompSwap $xl,$yl, $xh,$yh - CMP $yh, $yl - EORLT $yl, $yl, $yh - EORLT $yh, $yl, $yh - EORLT $yl, $yl, $yh - CMPEQ $xl, $xh - EORLT $xl, $xl, $xh - EORLT $xh, $xl, $xh - EORLT $xl, $xl, $xh - MEND - -; -; Macro CompSwapT - Compare and sort a pair of coordinates into -; order of increasing Y -; If Y values equal, sort in order of decreasing X -; Uses a temporary register -; - MACRO - CompSwapT $xl,$yl, $xh,$yh, $temp - SortT $yl, $yh, $temp - CMPEQ $xl, $xh - EORLT $xl, $xl, $xh - EORLT $xh, $xl, $xh - EORLT $xl, $xl, $xh - MEND - -; -; Macro Difference - rc := ABS(ra-rb) -; -; Test GE/LT for ra>=rb / ra<rb -; - MACRO - Difference $rc,$ra,$rb - SUBS $rc,$ra,$rb - RSBLT $rc,$rc,#0 - MEND - -; -; Macro Least - Select the smallest value (signed) -; - MACRO - Least $rc,$ra,$rb - CMP $ra,$rb - [ $rc = $ra - | - MOVLE $rc,$ra - ] - [ $rc = $rb - | - MOVGT $rc,$rb - ] - MEND - -; -; Macro Greatest - Select the largest (signed) value -; - MACRO - Greatest $rc,$ra,$rb - CMP $ra,$rb - [ $rc = $ra - | - MOVGE $rc,$ra - ] - [ $rc = $rb - | - MOVLT $rc,$rb - ] - MEND - -; -; Macro PackXtnd - pack 2 bytes into 1 word and sign extend -; - - MACRO - PackXtnd $result,$hi,$lo - [ $lo = $result - ADD $result,$lo,$hi,LSL #8 - MOV $result,$result,LSL #16 - MOV $result,$result,ASR #16 - | - MOV $result,$hi,LSL #24 - ORR $result,$lo,$result,ASR #16 - ] - MEND - - MACRO - LoadCoordPair $x, $y, $basereg, $offset - ASSERT $x < $y - [ ($offset) :AND: 3 = 2 - ADD $x, $basereg, #($offset)-2 - LDMIA $x, {$x, $y} ; (Xh,Xl,??,??) (??,??,Yh,Yl) - MOV $x, $x, ASR #16 ; (Xs,Xs,Xh,Xl) - MOV $y, $y, LSL #16 ; (Yh,Yl, 0, 0) - MOV $y, $y, ASR #16 ; (Ys,Ys,Yh,Yl) - | - [ ($offset) :AND: 3 = 0 - LDR $x, [$basereg, #$offset] ; (Yh,Yl,Xh,Xl) - | - [ ($offset) :AND: 3 = 1 - ADD $x, $basereg, #($offset)-1 - LDMIA $x, {$x, $y} ; (Yl,Xh,Xl,??) (??,??,??,Yh) - MOV $x, $x, LSR #8 ; ( 0,Yl,Xh,Xl) - ORR $x, $x, $y, LSL #24 ; (Yh,Yl,Xh,Xl) - | - ADD $x, $basereg, #($offset)-3 - LDMIA $x, {$x, $y} ; (Xl,??,??,??) (??,Yh,Yl,Xh) - MOV $x, $x, LSR #24 ; ( 0, 0, 0,Xl) - ORR $x, $x, $y, LSL #8 ; (Yh,Yl,Xh,Xl) - ] - ] - MOV $y, $x, ASR #16 ; (Ys,Ys,Yh,Yl) - MOV $x, $x, LSL #16 ; (Xh,Xl, 0, 0) - MOV $x, $x, ASR #16 ; (Xs,Xs,Xh,Xl) - ] - MEND - -; -; Macro SaveRetAdr - Push R14 to our pseudo stack -; - MACRO - SaveRetAdr - Push R14 - MEND - -; -; Macro Return - Pull from stack into PC -; - MACRO - Return $cond - LDM$cond.FD StkPtr!, {PC} - MEND - -; -; Macro SuperMode - Set supervisor mode -; - MACRO - SuperMode - SWI &16 - MEND - -; -; Macro WINDow - Compare coordinate against graphics window -; -; Test GE/LT for within/outside window -; - MACRO - WINDow $rx,$ry, $rl,$rb,$rr,$rt -; ASSERT ($rl < $rb) AND ($rb < $rr) AND ($rr < $rt) - ADD $rt,WsPtr,#GWLCol - LDMIA $rt,{$rl,$rb,$rr,$rt} - CMP $rx,$rl - CMPGE $rr,$rx - CMPGE $ry,$rb - CMPGE $rt,$ry - MEND - -; -; Macro WindowRes - Window a coordinate, giving status word -; -; Result word is as follows: -; -; | | -; 1001 | 1000 | 1010 -; | | -; -----+------+----- GWTRow -; | | -; 0001 | 0000 | 0010 -; | | -; -----+------+----- GWBRow -; | | -; 0101 | 0100 | 0110 -; | | -; -; GWLCol GWRCol -; -; - MACRO - WindowRes $result, $rx,$ry, $rl,$rb,$rr,$rt -; ASSERT ($rl < $rb) AND ($rb < $rr) AND ($rr < $rt) - MOV $result,#0 - ADD $rt,WsPtr,#GWLCol - LDMIA $rt,{$rl,$rb,$rr,$rt} - CMP $rx,$rl - ORRLT $result,$result,#1 ;Set bit 0 if X < window - CMP $rr,$rx - ORRLT $result,$result,#2 ;Set bit 1 if X > window - CMP $ry,$rb - ORRLT $result,$result,#4 ;Set bit 2 if Y < window - CMP $rt,$ry - ORRLT $result,$result,#8 ;Set bit 3 if Y > window - MEND - - MACRO -$lab EQUB $var - ASSERT $var >= &00 - ASSERT $var <= &FF -$lab = $var - MEND - - MACRO - OrrEor $d,$s, $or,$eor - ORR $d,$s,$or - EOR $d,$d,$eor - MEND - - - MACRO ;Scr:=ScrOR(oraANDmsk)EOR(eorANDmsk) - OrrEorMASK $scr,$msk, $ora,$eor, $tmp - AND $tmp,$msk,$ora - ORR $scr,$scr,$tmp - AND $tmp,$msk,$eor - EOR $scr,$scr,$tmp - MEND - - - MACRO - ORoreorEORoreor $d,$s, $oo,$eo,$oe,$ee, $tmp - OrrEor $tmp,$s, $oo,$eo - ORR $d,$d,$tmp - OrrEor $tmp,$s, $oe,$ee - EOR $d,$d,$tmp - MEND - - - MACRO - ORoreorEORoreorMASK $d,$s,$m, $oo,$eo,$oe,$ee, $tmp - OrrEor $tmp,$s, $oo,$eo - AND $tmp,$tmp,$m - ORR $d,$d,$tmp - OrrEor $tmp,$s, $oe,$ee - AND $tmp,$tmp,$m - EOR $d,$d,$tmp - MEND - - - MACRO - ShiftR $d,$e, $r,$rcomp - MOV $d,$d,LSR $r - ORR $d,$d,$e,LSL $rcomp - MEND - - MACRO - ShiftL $d,$e, $r,$rcomp - MOV $e,$e,LSL $rcomp - ORR $e,$e,$d,LSR $r - MEND - - - MACRO - BitLOffset $b,$x, $xshftfactor,$npix,$log2bpc - AND $b,$x,$npix - MOV $b,$b,LSL $log2bpc - MEND - - - MACRO - BitROffset $b,$x, $xshftfactor,$npix,$log2bpc - AND $b,$x,$npix - ADD $b,$b,#1 - MOV $b,$b,LSL $log2bpc - SUB $b,$b,#1 - MEND - - - MACRO - WordOffset $w,$x, $xshftfactor,$npix,$log2bpc - MOV $w,$x,ASR $xshftfactor - MEND - - - MACRO - OffsetWordAndBit $o,$b,$x,$tmp - LDR $tmp,[WsPtr,#XShftFactor] - MOV $o,$x,ASR $tmp ;Word offset into scanline - LDR $tmp,[WsPtr,#NPix] - AND $b,$x,$tmp ;Pixel offset into word - LDR $tmp,[WsPtr,#Log2BPC] - MOV $b,$b,LSL $tmp ;Bit offset into word - MEND - - - MACRO -$label ErrorMsg $num,$string -$label DCD $num - DCB "$string", 0 - ALIGN - MEND - -; -; Macro when given a register will return the state to indicate -; if we are in a graphics mode. Originally lots of code used to simply -; load NPix and look for a null parameter (fair enough in 1-8 bit per pixel) -; but now we look at the mode flags, the choice of a new generation! -; - MACRO -$label GraphicsMode $scrap -$label LDR $scrap, [WsPtr, #ModeFlags] - TST $scrap, #Flag_NonGraphic ;NE then non-graphic mode! - MEND - - END diff --git a/s/vdu/vdudriver b/s/vdu/vdudriver deleted file mode 100644 index b220034d..00000000 --- a/s/vdu/vdudriver +++ /dev/null @@ -1,2450 +0,0 @@ -; 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.VduDriver -; -; ARTHUR OPERATING SYSTEM - Vdu Drivers -; ======================= -; -; Vdu driver code - Vdu queue, mode, default windows etc. -; -; Author R C Manby -; Date 5.9.86 -; - GBLL NewStyleEcfs -NewStyleEcfs SETL 1=1 - - GBLL DoVdu23_0_12 -DoVdu23_0_12 SETL {FALSE} - - GBLL BleedinDaveBell -BleedinDaveBell SETL {TRUE} - - GBLL LCDPowerCtrl -LCDPowerCtrl SETL {TRUE} :LAND: :LNOT: STB - - GET s.vdu.VduDecl - GET s.vdu.VduGrafDec - - MACRO - HostVdu - Push "R0,R14" - LDR R0, [R0, -R0] - TEQ R0, #0 - ADREQ R0, %FT01 - SWIEQ OS_CLI - Pull "R0,R14" - B %FT02 -01 - = "HOSTVDU", 0 - ALIGN -02 - MEND - - MACRO - Print $string - Push "R0,R14" - LDR R0, [R0, -R0] - TEQ R0, #0 - BNE %FT01 - SWI OS_WriteS - = "$string", 0 - ALIGN - SWI OS_ReadC - Pull "R0,R14",CS - SWICS OS_BreakPt - SWI OS_NewLine -01 - Pull "R0,R14" - MEND - - MACRO - RMVT $var, $BW - [ "$BW"="B" - = (wk$var-wkstart)*2 - | - [ "$BW"="W" - = (wk$var-wkstart)*2 +1 - | - .... Invalid option on RMVT .... - ] - ] - MEND - - MACRO - RVVT $var - ASSERT ($var >= 0) :LAND: ($var < &400) :LAND: (($var :AND: 3)=0) - = $var :SHR: 2 - MEND - - MACRO - IssueService - BL Issue_Service - MEND - - MACRO - MALIGN $length, $phase - LCLA temp - LCLS string -temp SETA .-ArthurVduDriver - [ "$phase"="" -string SETS "ALIGN $length" - | -string SETS "ALIGN $length, $phase" - ] - $string -temp SETA .-ArthurVduDriver-temp - [ temp=0 - ! 0, string :CC: " fitted exactly" - | - ! 0, string :CC: " wasted " :CC: :STR: temp - ] - MEND - - -; Macro to load up video bandwidth and video memory size - - MACRO - GetBandwidthAndSize $bw, $size - [ HAL - MOV $size, #0 - MOV $bw, #100*1024*1024 - LDR $size, [$size, #VideoSize] - ! 0, "Sort out GetBandwidthAndSize" - | - MOV $size, #0 - LDR $bw, [$size, #VideoBandwidth] ; load bandwidth - LDR $size, [$size, #VideoSize] ; and total amount of video RAM - ] - MEND - -; ***************************************************************************** - -; Vdu status bits - -Vdu2ModeBitPosn * 0 -Vdu2Mode * 1 :SHL: Vdu2ModeBitPosn -Windowing * 1 :SHL: 3 -Shadowing * 1 :SHL: 4 - -; ***************************************************************************** - -ArthurVduDriver - -; ***************************************************************************** -; -; VduInit - Once only initialisation of Vdu drivers eg after Break -; ======= -; -VduInit ROUT - Push R14 - MOV R0, #0 - STRB R0, [R0, #OsbyteVars + :INDEX: VDUqueueItems] ;purge queue - STRB R0, [WsPtr, #ScreenBlankFlag] ; not blanked - STR R0, [WsPtr, #CursorCounter] - STR R0, [WsPtr, #CursorDesiredState] - STR R0, [WsPtr, #VduStatus] - STRB R0, [WsPtr, #PointerShapeNumber] ; make sure pointer off - STR R0, [WsPtr, #PointerShapeLA] ; no shape passed to HAL yet - STR R0, [WsPtr, #CursorStack] ; 0 bits => on - STR R0, [WsPtr, #VduSaveAreaPtr] ; indicate no save area yet - STR R0, [WsPtr, #ClipBoxEnable] ; no clip box calculating - STRB R0, [WsPtr, #ExternalFramestore] - - [ :LNOT:UseGraphicsV - Push "r4, r9, r12" - mjsAddressHAL - MOV r4, r12 ; temp WsPtr - mjsCallHAL HAL_Video_PixelFormats - STR r0, [r4, #HWPixelFormats] - mjsCallHAL HAL_Video_Features - STR r0, [r4, #HWVideoFeatures] - mjsCallHAL HAL_Video_BufferAlignment - STR r0, [r4, #HWBufferAlign] - Pull "r4, r9, r12" - ] - - ;;; sort this out! - ! 0, "mjsHAL not doing anything useful with HAL_Video_BufferAlignment" - ! 0, "mjsHAL not dealing with lack of h/w pointer" - - LDR R0, =RangeC+SpriteReason_SwitchOutputToSprite - STR R0, [WsPtr, #SpriteMaskSelect] - - MOV R0, #InitialCursorFlags ; TMD 25/9/86 - STR R0, [WsPtr, #CursorFlags] - - ADRL R0, NUL ; point to MOV PC,R14 - STR R0, [WsPtr, #WrchNbit] ; just in case ... - - ADRL R0, ExportedHLine - STR R0, [WsPtr, #HLineAddr] - ADD R0, WsPtr, #FgEcfOraEor - STR R0, [WsPtr, #GcolOraEorAddr] - - MOV R0, #maxmode - STR R0, [WsPtr, #MaxMode] ; constant now - - - LDROSB R0, LastBREAK ; is it a hard reset ? - TEQ R0, #0 - BEQ %FT10 ; [no, don't reset font] - - -; allocate buffer for Tim's whizzy text expansion. This now lives -; in the system heap, unless the claim request fails. If the request -; fails then the pointer points at the original buffer in the Vdu -; driver workspace. - -; This allows the user to access depths upto 16 bit per pixel before -; strings things things become afoot at the Circle K. - - LDR R3, =TextExpandArea_Size - BL ClaimSysHeapNode ; allocate buffer for heap data - ADDVS R2, WsPtr, #TextExpand - STR R2, [WsPtr, #TextExpandArea] - - LDR R3, =ModeSelector_MaxSize+4 ; get block for two overlapping copies - BL ClaimSysHeapNode ; of mode selector, 1 word apart - STR R2, [WsPtr, #KernelModeSelector] - - -; now reset soft font from hard font - - MOV R1, #1 ; start at character 1*32 - STRB R1, [WsPtr, #ScreenMemoryClaimed] - ; can't claim memory till a mode change - MOV R2, #7 ; copy 7 pages - BL DoResetFont - - [ :LNOT: HAL - ; - ; mjsHAL - temporary workspace while semi HALised code still in kernel - ; - MOV r3, #mjs_thalwk_size - BL ClaimSysHeapNode ; this had better succeed! - LDR r4, =mjs_tempHALworkspace - STR r2, [r4, #0] - BL mjs_tempHALworkspace_init - ; - ] - -;initialise the 6 pointer shape pointers and blocks -;(shape buffers are 6 * &100 starting at CursorData) -; - ADD r0, WsPtr, #PointerShapes - LDR r2, =CursorData - MOV r3, #6 - ADD r4, WsPtr, #PointerShapeBlocks -02 - STR r4, [r0] ; attach pointer to block - STR r2, [r4, #PointerBuffLA] - Push "r0-r2" - MOV r1, #0 - STRB r1, [r4, #PointerWidth] ; zero width - STRB r1, [r4, #PointerHeight] ; zero height (no shape) - SUB sp, sp, #3*4 ; room for one entry of OS_Memory page block - MOV r1, sp - STR r2, [r1, #4] ; provide logical address - MOV r2, #1 - MOV r0, #&2200 ; convert logical to physical address - SWI XOS_Memory - LDR r2, [r1, #8] ; read physical address - STR r2, [r4, #PointerBuffPA] - ADD sp, sp, #3*4 - Pull "r0-r2" - ADD r4, r4, #PointerBlkSize - ADD r2, r2, #&100 - ADD r0, r0, #4 - SUBS r3, r3, #1 - BNE %BT02 - -; palette space (256 normal + 1 border + 3 pointer = 260), and allowing for Gamma Correction -; this space is: blank palette, 260 words -; logical and physical copies of both flash states, 260*4 words -; 3 lookup tables for r,g,b mapping, 3*256 bytes -; - MOV r3, #260*4 - ADD r3, r3, #260*4*4 + 3*256 - BL ClaimSysHeapNode ; this had better succeed! - - STR r2, [WsPtr, #BlankPalAddr] - ADD r3, r2, #260*4 - STR r3, [WsPtr, #FirPalAddr] - ADD r3, r3, #260*4 - STR r3, [WsPtr, #SecPalAddr] - -; initialise blank palette to all solid black - - MOV r3, #0 - MOV r4, #260 -04 STR r3, [r2], #4 - SUBS r4, r4, #1 - BNE %BT04 - - ADD r2, r2, #260*4*4 ; r2 -> rgb tables - -; initialise red, green and blue transfer function tables to 1-1 mapping - - MOV r0, #0 -05 - STRB r0, [r2, #&200] ; store in blue table - STRB r0, [r2, #&100] ; store in green table - STRB r0, [r2], #1 ; store in red table, and advance - ADD r0, r0, #1 - CMP r0, #256 - BCC %BT05 -10 - BL SpriteInit - - LDR R14, [WsPtr, #ScreenEndAddr] - LDR R0, [WsPtr, #TotalScreenSize] - RSB R0, R0, R14 - STR R0, [WsPtr, #DisplayStart] - BL SetDisplayScreenStart - STR R0, [WsPtr, #ScreenStart] - STR R0, [WsPtr, #CursorAddr] - STR R0, [WsPtr, #InputCursorAddr] - - Pull PC - - LTORG - -; ***************************************************************************** -; -; InitialiseMode - Select mode number given by ModeNo variable -; -; Called by MOS once before initialisation, and then afterwards -; before printing "RISC OS ..." -; -; in: - -; out: All registers may be corrupted (except R13_svc !) -; - -InitialiseMode Entry - [ SoftResets - MOV r0, #&FD ; read last reset type - MOV r1, #0 - MOV r2, #&FF - SWI XOS_Byte - CMP r1, #SoftReset - LDREQ r0, =VduDriverWorkSpace+ModeNo - LDREQ r0, [r0] ; use previous mode if a soft reset - MOVNE r0, #1 ; otherwise read configured mode - SWINE XOS_ReadSysInfo - | - MOV r0, #1 ; no need to check for soft reset, - SWI XOS_ReadSysInfo ; always use configured value - ] - MOV r1, r0 - MOV r0, #ScreenModeReason_SelectMode - SWI XOS_ScreenMode - EXIT VC - - MOV r0, #114 ; failed, so get rid of any shadow - MOV r1, #1 - SWI XOS_Byte - SWI XOS_WriteI+22 - SWIVC XOS_WriteI+0 ; and if we can't get mode 0, we're really fooked!!! - EXIT - -; -;------------------------------------------------------------------------------ -; -; Vdu - Main VDU driver entry point -; === Queue up bytes and dispatch via JVec -; -; in: R0 = character to be printed -; -; out: C=1 <=> send character to printer if enabled -; - -Vdu ROUT - MOV R11, #0 ; NB used later in Vdu07 as well - LDRB R10, [R11, #OsbyteVars + :INDEX: VDUqueueItems] - MOVS R9, R10, LSL #24 ; move up to top byte (for sign extend) - BEQ Vdu07 ; not queueing, then start Vdu sequence - -; *****Comment made by DJS: Changing this to fall through if not queueing -; and branch if queueing might be a good idea - it would speed up all -; printable characters and simple cursor movements. - - LDR R8, [WsPtr, #QOffset] - STRB R0, [R8, R9, ASR #24] ; add byte to queue - - ADD R10, R10, #1 ; move on pointer - STRB R10, [R11, #OsbyteVars + :INDEX: VDUqueueItems] - - CMP R10, #&100 ; finished sequence ? - MOVCC PC, R14 ; no, then return (no printing) - - Push "R0, R14" - BL PreWrchCursor ; exits with R6 = CursorFlags - Pull "R0" -05 - [ No26bitCode - ADR R14, VduPrintExit - | - MOV R14, PC - ADD R14, R14, #(VduPrintExit-%BT05-8) ; push address of SEC exit - ; (with flags) - ] - Push R14 - BL Vdu05 - BL PostWrchCursor - CLC ; also clears V - Pull "R14,PC" - -VduPrintExit ; exit used if print required - BL PostWrchCursor - SEC ; also clears V - Pull PC - -; ***************************************************************************** - -Vdu05 ROUT - TST R6, #VduDisabled ; VDU enabled ? - LDREQ PC, [WsPtr, #JVec] ; yes, then do it (no printing) - -; Queue sequence has just completed, but VDU is disabled -; Only interesting case is VDU 1 (SOH), which must still print -; the character if the printer is enabled - - LDR R10, [WsPtr, #JVec] - ADR R11, SOH - TEQ R10, R11 ; JVec -> SOH ? - MOVNE PC, R14 ; no, then return (no printing) -SOH - LDR R1, [WsPtr, #VduStatus] ; in VDU 2 mode ? - TST R1, #Vdu2Mode - MOVEQ PC, R14 ; no, then return - - Push R14 - BL MOSDoPrint - Pull PC, VC ; good exit, so return - - Pull R14 ; bad exit, return with error - B VduBadExit - -; ***************************************************************************** - -Vdu07 ROUT - AND R0, R0, #&FF ; Only look at bottom byte! - - CMP R0,#127 ;If DELETE, change R0 to 32 and - MOVEQ R0,#32 ; drop through to control char code - CMPNE R0,#31 ;Otherwise, branch to printable char - BHI Vdu20 ; code if not a control char - -; *****Further desirable change: Make printable characters fall through, -; control characters take the branch - speeding up printable characters is -; important! - - ADR R10, VduJTb ; Address of beginning of jump table - LDR R9, [R10, R0, LSL #2] ; Get routine address from VduJTB - STR R9, [WsPtr, #JVec] ; save address - - ADD R10, R10, #(VduQTb-VduJTb) - - LDRB R9, [R10, R0] ; Pick up QQ + length of queue - RSBS R10, R9, #QQ ; -(length of queue) & test if none - - STRNEB R10, [R11, #OsbyteVars + :INDEX: VDUqueueItems] - ; yes, then set up Osbyte variable - ADDNE R9, R9, WsPtr - STRNE R9, [WsPtr, #QOffset] ; and QOffset - MOVNE PC, R14 - - Push "R0,R14" - BL PreWrchCursor ; exits with R6 = CursorFlags - Pull "R0" -10 - MOV R14, PC - ADD R14, R14, #(VduPrintExit-%BT10-8) ; push address of SEC exit - ; (with flags) - Push R14 - BL Vdu10 - BL PostWrchCursor - CLC ; also clears V - Pull "R14,PC" - -; -; This is the only byte of a single byte Vdu sequence -; -; R6 = CursorFlags -; R11 = 0 (used to index VDUqueueItems) -; - -Vdu10 ROUT - TST R6, #CursorsSplit ; are we cursor editing ? - BNE Vdu15 -Vdu10Continue - -; TMD 31/7/87; bug fixed here - chars 8 to 13 should still go to printer if -; enabled, even if VDU is disabled - - CMP R0, #8 ; is char in range 8-13 ? - RSBCSS R1, R0, #13 ; if so then we want to print it - LDRCS R1, [WsPtr, #VduStatus] - MOVCSS R1, R1, LSR #(Vdu2ModeBitPosn +1) ; providing printer enabled - Pull R14, CS ; so pull old R14 - - TST R6, #VduDisabled ; are we disabled - LDREQ PC, [WsPtr, #JVec] ; enabled, so go get em floyd ! - - TEQ R0, #6 ; disabled, so is it ACK (enable VDU) - BICEQ R6, R6, #VduDisabled - STREQ R6, [WsPtr, #CursorFlags] - -NUL ;Does nothing -ESC ;Does nothing - MOV PC, R14 ; return anyway - -; ***************************************************************************** - -Vdu15 - TEQ R0, #13 ; and is it a carriage return ? - BNE Vdu10Continue - - Push "R0, R14" - BIC R6, R6, #CursorsSplit ; then stop cursor editing - STR R6, [WsPtr, #CursorFlags] - MOV R1, #1 ; restore old Reg10Copy - BL CursorOnOff - Pull "R0, R14" - B Vdu10Continue - -; ***************************************************************************** - -Vdu20 ROUT - Push "R0,R14" - BL PreWrchCursor ; exits with R6 = CursorFlags - Pull "R0" -05 - MOV R14, PC - ADD R14, R14, #(VduPrintExit-%BT05-8) ; push address of SEC exit - ; (with flags) - Push R14 - BL TimWrch - BL PostWrchCursor - CLC ; also clears V - Pull "R14,PC" - -; ***************************************************************************** - -VduJTb ; Table of addresses - & NUL ; Does nothing - & SOH ; Next char to printer only - & STX ; Enable printer - & ETX ; Disable printer - & EOT ; Write text at text cursor - & ENQ ; Write text at graphics cursor - & NUL ; Enable VDU drivers - & BEL ; Beep - & BS ; Cursor left - & HT ; Cursor right - & VduLF ; Cursor down - & VT ; Cursor up - & FF ; Clear text area (CLS) - & VduCR ; Carriage return - & SO ; Page mode on - & SI ; Page mode off - & DLE ; Clear graphics area (CLG) - & DC1 ; Define text colour (COLOUR) - & DC2 ; Define graphics colour and action (GCOL) - & DC3 ; Define logical colour - & VDU20 ; Restore default logical colours - & NAK ; Disable VDU drivers - & SYN ; Select screen mode (MODE) - & ETB ; Reprogram display character (VDU23,...) - & CAN ; Define graphics window - & EM ; (PLOT k,x,x,y,y) - & DefaultWindows ; Restore default windows - & ESC ; Does nothing - & FS ; Define text window - & GS ; Define graphics origin - & RS ; Home cursor to "top left" - & US ; Move text cursor (TAB x,y) - & Delete ; Delete character (127) - - ASSERT QQ+9 < 256 - -VduQTb ; QQ + length of queue for each of the above - DCB QQ+0, QQ+1, QQ+0, QQ+0, QQ+0, QQ+0, QQ+0, QQ+0 - DCB QQ+0, QQ+0, QQ+0, QQ+0, QQ+0, QQ+0, QQ+0, QQ+0 - DCB QQ+0, QQ+1, QQ+2, QQ+5, QQ+0, QQ+0, QQ+1, QQ+9 - DCB QQ+8, QQ+5, QQ+0, QQ+0, QQ+4, QQ+4, QQ+0, QQ+2 - DCB QQ+0 ; (delete) - ALIGN - -; ***************************************************************************** - -WrchNbitTab - & Wrch1bit-WrchNbitTab - & Wrch2bit-WrchNbitTab - & Wrch4bit-WrchNbitTab - & Wrch8bit-WrchNbitTab - & Wrch16bit-WrchNbitTab - & Wrch32bit-WrchNbitTab -WrchNbitDoubleTab - & Wrch1bitDouble-WrchNbitDoubleTab - -CursorNbitTab - & Cursor1bit-CursorNbitTab - & Cursor2bit-CursorNbitTab - & Cursor4bit-CursorNbitTab - & Cursor8bit-CursorNbitTab - & Cursor16bit-CursorNbitTab - & Cursor32bit-CursorNbitTab - -; table of susbstitute mode numbers to cater for hardware that might -; not support all of 1,2,4,8 bpp (bits per pixel) modes -; -; indexed by mode number (0..49), pairs of byte values: -; bpp = bits per pixel of this mode number -; promo = promoted mode number (0..49), or &FF if none -; -; promoted number is: -; 1) same resolution at next higher bpp (up to 8), if available, or -; 2) similar resolution at 8 bpp (8 bpp should be available on most h/w) -; -ModePromoTable -; -; bpp promo mode no. -; - DCB 1, 8 ; 0 - DCB 2, 9 ; 1 - DCB 4, 10 ; 2 - DCB 1, 15 ; 3 - DCB 1, 1 ; 4 - DCB 2, 2 ; 5 - DCB 1, 13 ; 6 - [ TTX256 - DCB 8, &FF ; 7 - | - DCB 4, 13 ; 7 - ] - DCB 2, 12 ; 8 - DCB 4, 13 ; 9 - DCB 8, &FF ; 10 - DCB 2, 14 ; 11 - DCB 4, 15 ; 12 - DCB 8, &FF ; 13 - DCB 4, 15 ; 14 - DCB 8, &FF ; 15 - DCB 4, 24 ; 16 - DCB 4, 24 ; 17 - DCB 1, 19 ; 18 - DCB 2, 20 ; 19 - DCB 4, 21 ; 20 - DCB 8, &FF ; 21 - DCB 4, 36 ; 22 - DCB 1, 28 ; 23 - DCB 8, &FF ; 24 - DCB 1, 26 ; 25 - DCB 2, 27 ; 26 - DCB 4, 28 ; 27 - DCB 8, &FF ; 28 - DCB 1, 30 ; 29 - DCB 2, 31 ; 30 - DCB 4, 32 ; 31 - DCB 8, &FF ; 32 - DCB 1, 34 ; 33 - DCB 2, 35 ; 34 - DCB 4, 36 ; 35 - DCB 8, &FF ; 36 - DCB 1, 38 ; 37 - DCB 2, 39 ; 38 - DCB 4, 40 ; 39 - DCB 8, &FF ; 40 - DCB 1, 42 ; 41 - DCB 2, 43 ; 42 - DCB 4, 28 ; 43 - DCB 1, 45 ; 44 - DCB 2, 46 ; 45 - DCB 4, 15 ; 46 - DCB 8, &FF ; 47 - DCB 4, 49 ; 48 - DCB 8, &FF ; 49 -; - ALIGN - - -; ***************************************************************************** -; -; SYN - Perform MODE change -; -; External routine -; -; in: Vdu queue contains mode number -; - -SYN ROUT ; Select screen mode (MODE) - Push lr - LDRB R2, [WsPtr, #QQ] ; Read mode number from queue - BL ModeChangeSub - Pull lr - MOVVC pc, lr ; if no error, exit to Vdu - ; (which calls PostWrchCursor) -; else drop thru into ... - -VduBadExit ; jumped to if an error in VDU code - Push R0 ; save error pointer - BL PostWrchCursor - SETV - Pull "R0, R14,PC" - -ModeChangeSub ROUT - Push lr - - ;If its a common mode number (0..49) consider a possible mode number - ;substitution, if hardware does not support given bits per pixel. - ;We are vaguely assuming h/w supports at least 8 bpp, otherwise we may - ;not be able to find a usable mode number, and later code may not handle - ;that well. This is probably ok, 8 bpp is almost universal. - ; - CMP r2, #256 - BHS mchsub_3 - AND r1, r2, #&7F - CMP r1, #50 ; mode number - BHS mchsub_3 - Push "r3, r4" - [ UseGraphicsV - Push "r0-r2" - MOV r4, #GraphicsV_DisplayFeatures - BL CallGraphicsV - TEQ r4, #0 - MOVEQ r4, r1 - MOVNE r4, #2_111111 - Pull "r0-r2" - | - LDR r4, [WsPtr, #HWPixelFormats] ; bits 0 to 3 set for 1,2,4,8 bpp supported - ] - ADR lr, ModePromoTable ; table of mode promotions -mchsub_1 - MOV r1, r1, LSL #1 - LDRB r3, [lr, r1] ; bpp for this mode number (1,2,4,8) - TST r3, r4 ; supported in h/w? - ANDNE r2, r2, #&80 ; if yes, take mode number that passed - ORRNE r2, r2, r1, LSR #1 - BNE mchsub_2 - ADD r1, r1, #1 ; else look for promotion - LDRB r1, [lr, r1] ; new mode number - CMP r1, #&FF ; &FF if none - BNE mchsub_1 - ;alright, dont panic, just try to get a VGA-like mode of any bpp, if not tried already - CMP r1, #28 ; VGA 8 bpp - MOVNE r1, #25 ; VGA 1 bpp - BNE mchsub_1 -mchsub_2 - Pull "r3, r4" -; -mchsub_3 -; BKPT &600D - MOV R1, #Service_PreModeChange - IssueService - TEQ R1, #0 ; was service claimed ? - BNE %FT03 ; no, so continue - - CMP R0, #0 ; service claimed; generate error ? - Pull PC, EQ ; no, just exit (V=0 from CMP) - B %FT07 ; yes, then generate error -03 - MOV R0, R2 ; put mode (possibly changed) in R0 - MOV R2, R0, LSR #7 ; R2 = 0/1 if bit 7 of mode clear/set - CMP r2, #2 ; if mode number >= 256 then mode selector - MOVCS r2, #0 ; so no shadow - LDROSB R1, Shadow - TEQ R1, #0 ; if shadow 0 then force shadow mode - MOVEQ R2, #1 - - BL FindOKMode ; out: R1 = mode we are going to use - BVS %FT07 - - TEQ R0, R1 ; if substitute mode - MOVNE R2, #0 ; then don't use shadow - - CMP r1, #&100 - BICCC r10, r1, #&80 - MOVCS r10, r1 - MOV R11, R10 - BL PushModeInfo - BVS %FT07 ; [probably duff mode selector] - - LDR R11, [R13, #wkScreenSize] ; get screen size for this mode - LDR R9, [WsPtr, #TotalScreenSize] ; maximum allowed amount - - Push R1 ; save proper mode - RSBS R1, R9, R11, LSL R2 ; extra amount we need - BLS %FT08 ; enough memory, so skip - - [ UseGraphicsV - LDRB R0, [WsPtr, #ExternalFramestore] - TEQ R0, #0 - BNE %FT06 ; can't grow an external framestore - ] - -; try to extend the amount of screen memory - - MOV R0, #2 ; expand screen memory - SWI XOS_ChangeDynamicArea - BVC %FT08 -06 - ADD R13, R13, #PushedInfoSize + 1*4 ; junk stacked info + mode no. - ADR R0, ErrorBlock_BadMODE - [ International - BL TranslateError - ] -07 - SETV ; indicate error - Pull PC - - [ STB -TV_Mode_string - = "TV_Mode", 0 - ALIGN - ] - -; valid mode and enough memory - -08 - Pull R0 ; restore mode we are using - CMP r0, #&100 ; if not mode selector - BICCC r0, r0, #&80 ; then knock off shadow bit - BCC %FT12 - -; it's a mode selector, so copy it to our static mode selector block - - LDR r1, [WsPtr, #KernelModeSelector] ; point at block - - SUBS r3, r0, r1 ; if r0 -> 1st mode block position - TEQNE r3, #4 ; or r0 -> 2nd mode block position - MOVEQ r1, r0 ; then use it in place - BEQ %FT09 - - LDR r3, [WsPtr, #DisplayModeNo] ; else check if current mode is a mode selector - SUB r3, r3, r1 ; r3 = offset from start of block - CMP r3, #8 ; if 0 or 4 - EORCC r3, r3, #4 ; then make 4 or 0 (ie toggle between them) - ADDCC r1, r1, r3 ; and add on base - - ASSERT (ModeSelector_ModeVars+4) :AND: 7 = 0 -09 - MOV r3, #0 -10 - LDR r6, [r0, r3] ; copy 1st word - after fixed bit this will be previous var value - STR r6, [r1, r3] - ADD r3, r3, #4 - LDR r6, [r0, r3] ; copy 2nd word - after fixed bit this will be next var index - STR r6, [r1, r3] - ADD r3, r3, #4 - CMP r3, #ModeSelector_ModeVars + 4 ; only exit if we've done the essential bit - CMPCS r6, #-1 ; AND we've had a -1 as the var index (NOT as the value) - CMPCC r3, #ModeSelector_MaxSize ; OR we've gone off the end of our block - BCC %BT10 ; [we haven't, so loop] - - CMP r3, #ModeSelector_MaxSize ; if we did go off the end - MOVCS r6, #-1 - STRCS r6, [r1, #ModeSelector_MaxSize-4] ; then terminate it properly - - MOV r0, r1 ; point at static block -12 - STR R0, [WsPtr, #DisplayModeNo] ; store the new display mode - -; now issue Service_ModeChanging - - MOV R1, #Service_ModeChanging - BL IssueModeService - - - [ {FALSE} ;;; LCDPowerCtrl :LAND: :LNOT: STB - ;;; mjsHAL no LCD support - ;Switch LCD off here if it is _not_ an LCD mode - MOV R3, #0 - LDRB R3, [R3, #LCD_Active] - ANDS R0, R3, #&7F ;Pick out the lcd mode bits, ignoring the single/dual panel bit - Push "r0-r1" - MOVEQ R0, #0 - LDREQ R1, =:NOT:(PortableControl_LCDEnable :OR: PortableControl_BacklightEnable) - SWIEQ XPortable_Control - Pull "r0-r1" - ] - -; R13 -> mode variables - -13 LDR R3, [R13, #wkScreenSize] - STR R3, [WsPtr, #ScreenSize] ; store screensize BEFORE calling - ; ConvertBankToAddress (was a bug!) - - [ UseGraphicsV - Push "r0-r4" - MOV r4, #GraphicsV_FramestoreAddress - BL CallGraphicsV - TEQ r4, #0 - BNE %FT581 - MOV r1, r1, LSR #20 ; round size down to 1MB - MOV r2, r1, LSL #20 - ADD r0, r0, #1:SHL:20 ; round addr up to 1MB - SUB r0, r0, #1 - MOV r0, r0, LSR #20 ; (because of OS_Memory 13 limits) - MOV r1, r0, LSL #20 - MOV r0, #13 ; map in permanently - ORR r0, r0, #1:SHL:8 ; buffered, uncached - ORR r0, r0, #1:SHL:16+1:SHL:17 ; doubly map, access permission specified - SWI XOS_Memory - BVS %FT581 - STR r2, [WsPtr, #TotalScreenSize] - ADD r3, r3, r2 - STR r3, [WsPtr, #ScreenEndAddr] - MOV r14, #1 - B %FT582 -581 - MOV r0, #128+2 - SWI XOS_ReadDynamicArea - STRVC r1, [WsPtr, #TotalScreenSize] - ADDVC r0, r0, r1 - STRVC r0, [WsPtr, #ScreenEndAddr] - MOV r14, #0 -582 - Pull "r0-r4" - STRB r14, [WsPtr, #ExternalFramestore] - ] - - TEQ R2, #0 ; Shadowing or not ? - LDR R3, [WsPtr, #VduStatus] - BICEQ R3, R3, #Shadowing - ORRNE R3, R3, #Shadowing - STR R3, [WsPtr, #VduStatus] - - STRB R2, [WsPtr, #ScreenMemoryClaimed] ; only allow ADFS to claim - ; if non-shadow (simplifies things!) - - BL ConvertBankToAddress ; R3 := default start for this bank - STR R3, [WsPtr, #DriverBankAddr] - STR R3, [WsPtr, #DisplayBankAddr] - - MOV R6, #0 - STRB R6, [R6, #OsbyteVars + :INDEX:MemDriver] ; indicate default - STRB R6, [R6, #OsbyteVars + :INDEX:MemDisplay] ; for both of these - - LDR R6, [R13, #wkModeFlags] - STR R6, [WsPtr, #DisplayModeFlags] - - MOV R2, #wkend-wkdispstart ; number of bytes to do - ADD R1, R13, #wkdispstart - - ADD R4, WsPtr, #PalIndex ; first display mode variable -15 - LDR R3, [R1], #4 ; copy variables - STR R3, [R4], #4 - SUBS R2, R2, #4 ; loop until all done - BNE %BT15 - -; now set up other mode variables by calling SwitchOutput - - ADD R3, WsPtr, #VduSaveArea+InitFlag - STR R2, [R3] ; indicate uninitialised (R2=0) - TST R6, #Flag_Teletext - MOVNE R3, #0 ; if teletext, then no save area - MOVEQ R3, #1 ; else MOS's save area - MOV R1, #0 ; just in case - MOV R0, #SpriteReason_SwitchOutputToSprite - SWI XOS_SpriteOp - -; now create other variables from simple ones - - LDR R3, [WsPtr, #NColour] - STR R3, [WsPtr, #DisplayNColour] - - ASSERT YWindLimit = XWindLimit +4 - ASSERT DisplayYWindLimit = DisplayXWindLimit +4 - ADD R0, WsPtr, #XWindLimit - LDMIA R0, {R3, R4} - ADD R0, WsPtr, #DisplayXWindLimit - STMIA R0, {R3, R4} - - ASSERT YEigFactor = XEigFactor +4 - ASSERT DisplayYEigFactor = DisplayXEigFactor +4 - ADD R0, WsPtr, #XEigFactor - LDMIA R0, {R3, R4} - ADD R0, WsPtr, #DisplayXEigFactor - STMIA R0, {R3, R4} - - ASSERT Log2BPP = Log2BPC +4 - ADD R0, WsPtr, #Log2BPC - LDMIA R0, {R0, R1} ; R0 = Log2BPC; R1 = Log2BPP - SUB R3, R3, R0 ; adjust XEig for double pixels - ADD R3, R3, R1 - STR R3, [WsPtr, #PointerXEigFactor] - - LDR R3, [R13, #wkModeFlags] - STR R3, [WsPtr, #ModeFlags] - -; finished doing other variables - - [ :LNOT:UseGraphicsV - Push "R0-R3, R9, R12" ; preserve registers ready to make HAL call later - ADD R0, R13, #wkwordsize+6*4 ; R0 -> VIDCList3 (we have just pushed 6 regs) - | - ADD R0, R13, #wkwordsize ; R0 -> VIDCList3 - ] - -;adjust vertical porch parameters in VIDCList3 for TVVertical (from *TV) -; - LDROSB R1, TVVertical - MOV R1, R1, LSL #24 ; sign extend to 32 bits - MOV R1, R1, ASR #24-3 ; and multiply by 8 - LDR R2, [WsPtr, #ModeFlags] - TST R2, #Flag_GapMode ; gap mode ? - ADDNE R1, R1, R1, ASR #2 ; add on 2 rows if so - TST R2, #Flag_DoubleVertical ; if double vertical - ADDNE R1, R1, R1 ; then double it - LDR R2, [R0, #VIDCList3_VertiBackPorch] - SUBS R2, R2, R1 - MOVMI R2, #0 - STR R2, [R0, #VIDCList3_VertiBackPorch] ;subtract from back porch, clamp at 0 - LDR R2, [R0, #VIDCList3_VertiFrontPorch] - ADDS R2, R2, R1 - MOVMI R2, #0 - STR R2, [R0, #VIDCList3_VertiFrontPorch] ;add to front porch, clamp at 0 - -;remember pixel rate (kHz) from VIDCList3 -; - LDR R2, [R0, #VIDCList3_PixelRate] - STR R2, [WsPtr, #PixelRate] - -;remember DPMSState (if specified) from VIDCList3 -; - MOV R2, #0 ; DPMSState = 0 if not specified in list - ADD R1, R0, #VIDCList3_ControlList -20 LDR R3, [R1], #8 ; loop over the control parameter list - CMP R3, #-1 - BEQ %FT30 ; didn't find the DPMSState entry - TEQ R3, #ControlList_DPMSState - BNE %BT20 ; next control parameter - LDR R2, [R1, #-4] ; read DPMSState value - AND R2, R2, #3 ; only bits 0,1 valid -30 - STRB R2, [WsPtr, #ScreenBlankDPMSState] - -;kernel/HAL split - call the HAL to program video controller for mode, -; - [ UseGraphicsV - MOV R4, #GraphicsV_SetMode - BL CallGraphicsV - | - mjsAddressHAL - mjsCallHAL HAL_Video_SetMode - - Pull "R0-R3, R9, R12" ; restore registers after HAL call - ] - - ADD R13, R13, #PushedInfoSize ; junk stacked data - - ; for backward compatibility, show that video DMA is enabled in - ; MEMC soft copy (DON'T call OS_UpdateMEMC, which would also - ; make redundant call to HAL) - ; - SavePSR R2 - MOV R0, #0 - WritePSRc SVC_mode+I_bit+F_bit, R14 - LDR R1, [R0, #MEMC_CR_SoftCopy] - ORR R1, R1, #(1 :SHL: 10) - STR R1, [R0, #MEMC_CR_SoftCopy] - RestPSR R2 - - BL SetVendDefault - - LDR R1, [WsPtr, #ScreenEndAddr] ; need to reload cos corrupt - LDR R2, [WsPtr, #TotalScreenSize] - SUB R0, R1, R2 ; R0 = Vstart - BL SetVstart - MOV R0, #0 - STRB R0, [WsPtr, #PointerShapeNumber] - STR R0, [WsPtr, #TeletextOffset] - STR R0, [WsPtr, #CursorStack] ; restore cursor on a mode - - BL PalInit ; set default palette - BL UnblankScreen - BL SetMouseRectangle - BL FF - - [ {FALSE} ;;; LCDPowerCtrl :LAND: :LNOT: STB - ;;; mjsHAL no LCD support - ;Switch the LCD on if LCD mode - Push "r0" - MOV R1, #0 - LDRB R1, [R1, #LCD_Active] - ANDS R1, R1, #&7F ;Check the LCD mode bits only, not the single/dual panel bit - LDRNE R0, =(PortableControl_LCDEnable :OR: PortableControl_BacklightEnable) - LDRNE R1, =:NOT:(PortableControl_LCDEnable :OR: PortableControl_BacklightEnable) - SWINE XPortable_Control - Pull "r0" - ] - - MOV R1, #Service_ModeChange - BL IssueModeService - - CLRV ; indicate no error - Pull PC ; return to caller - - MakeErrorBlock BadMODE - - LTORG - -; The following symbols, apart from being used in NColourTable, -; are also used in constructing mode selectors for mode numbers in VduModes - -NColour_0 * 1 -NColour_1 * 3 -NColour_2 * 15 -NColour_3 * 63 -NColour_4 * &FFFF -NColour_5 * &FFFFFFFF - - GET s.vdu.VduModes - -; ***************************************************************************** -; -; IssueModeService - Issue service (either ModeChanging or ModeChange) -; -; in: R1 = service code -; -; out: R1 corrupted -; - -IssueModeService Entry "r2,r3" - BL ReadMonitorType - LDR r2, [WsPtr, #DisplayModeNo] - IssueService - EXIT - -; ***************************************************************************** -; -; PushModeInfo - Push appropriate mode table and video controller params -; onto stack, having generated it by possibly issuing service -; -; in: R10 = mode to try for -; R11 = mode to use if service not claimed -; R10 and R11 should have bit 7 CLEAR (if mode numbers) -; -; out: If r10 is an invalid mode selector or invalid new format sprite word then -; V=1 -; r0 -> error -; stack flat (no pushed info) -; else -; V=0 -; Stack holds a mode table (size wkwordsize) and VIDCList -; type 3 (size VIDCList3Size) (total size PushedInfoSize) -; endif -; All other registers preserved -; - -PushModeInfoAnyMonitor ROUT - SUB sp, sp, #PushedInfoSize - Push "r2-r4,r7-r11, lr" - MOV r3, #-1 - MOV r7, #-1 ; indicate no VIDC stuff necessary - CMP r10, #&100 ; is it a mode selector - BCS PushModeInfoCommonNoService - BranchIfKnownMode r10, PushModeInfoCommonNoService - B PushModeInfoCommon - -PushModeInfo ROUT - SUB sp, sp, #PushedInfoSize - Push "r2-r4,r7-r11, lr" - MOV r7, #0 ; indicate VIDC stuff IS necessary - BL ReadMonitorType -PushModeInfoCommon - MOV r2, r10 ; r2 = original mode - BL OfferModeExtension - BEQ %FT30 ; [service claimed] - - CMP r2, #&100 ; service not claimed - check if mode selector - MOVCC r10, r11 ; unrecognised mode number, so use substitute - BCC PushModeInfoCommonNoService - -; service not claimed and it's a mode selector - return error "Screen mode not available" - - ADR r0, ErrorBlock_ModeNotAvailable - [ International - BL TranslateError - ] - B %FT40 - - MakeErrorBlock ModeNotAvailable - -30 - TEQ r4, #0 ; if r4 returned zero, then a mode selector was used - ; either initially or after translation from mode number - BEQ %FT35 ; so no ws list - LDR r2, [r4, #4]! ; else if claimed, then find ws base mode - CMP r2, #&100 ; if ws base mode is a mode selector, it's invalid - ANDCC r2, r2, #&7F ; else knock off shadow bit - BCC %FT35 - MOV r10, r11 ; invalid ws base mode, so pretend service not responded to - -; and drop thru to PushModeInfoCommonNoService - -PushModeInfoCommonNoService - MOV r2, r10 ; else use provided mode - MOV r3, #0 - MOV r4, #0 -35 - ADD r9, sp, #9*4 ; adjust for pushed registers - CMP r2, #&100 - BCC %FT45 - BL GenerateModeSelectorVars ; also copes with new sprite mode word - BVC %FT55 - -; we got an error - -40 - SETV - Pull "r2-r4,r7-r11,lr" ; restore registers - ADD sp, sp, #PushedInfoSize ; junk stack frame - MOV pc, lr ; exit VS, r0 -> error - -45 - ADRL r14, Vwstab - LDR r10, [r14, r2, LSL #2] - ADD r14, r14, r10 ; r14 -> mode table - MOV r10, #wkwordsize-4 -50 - LDR r2, [r14, r10] - STR r2, [r9, r10] - SUBS r10, r10, #4 - BCS %BT50 - -; now change any variables specified in workspace block or mode selector overrides - -55 - TEQ r4, #0 ; if service was claimed - ADDNE r4, r4, #4 ; then skip ws base mode - BLNE ProcessModeVarPairs - -; special VIDCListType3 widgetry -; 1) Set SyncPol_Interlace (according to TVInterlace) if not already specified -; 2) check for the interlaced flag in the control parameters - if set, set the interlaced -; flag in the mode flags - - TEQ r3, #0 ; do we have a VIDC list? - BEQ %FT58 - LDR r2, [r3, #0] ; is it type 3? (actually, it always should be now) - TEQ r2, #3 - BNE %FT58 - - LDR r10, [r3, #VIDCList3_SyncPol] - TST r10, #SyncPol_InterlaceSpecified - BNE %FT56 ; Interlace already specified - LDROSB R14, TVInterlace - TST R14, #1 - ORRNE R10, R10, #SyncPol_InterlaceSpecified ; specify as non-interlaced - ORREQ R10, R10, #(SyncPol_InterlaceSpecified+SyncPol_Interlace) ; specify as interlaced - STR R10, [r3, #VIDCList3_SyncPol] - -56 - ADD r10, r3, #VIDCList3_ControlList -57 LDR r14, [r10], #8 ; loop over the control parameter list - CMP r14, #-1 - BEQ %FT58 ; didn't find the interlaced entry - not interlaced - - TEQ r14, #ControlList_Interlaced - BNE %BT57 ; check the next one then - - LDR r14, [r10, #-4] ; read value - TEQ r14, #0 - BEQ %FT58 ; if zero, not interlaced - -; it's interlaced - LDR r14, [r9, #wkModeFlags] - ORR r14, r14, #Flag_InterlacedMode - STR r14, [r9, #wkModeFlags] -58 - [ UseGraphicsV - Push "r0-r2,r4" - MOV r4, #GraphicsV_DisplayFeatures - BL CallGraphicsV - TEQ r4, #0 - TSTEQ r0, #1 ; bit 0 is h/w scroll support - Pull "r0-r2,r4" - | - LDR r14, [WsPtr, #HWVideoFeatures] - TST r14, #1 ; bit 0 is h/w scroll support - ] - LDREQ r14, [r9, #wkModeFlags] - ORREQ r14, r14, #Flag_HardScrollDisabled - STREQ r14, [r9, #wkModeFlags] - -; hopefully, R7 is still set from up there to be NZ if no VIDC stuff necessary - - CMP r7, #0 - Pull "r2-r4,r7-r11, pc", NE ; if no VIDC stuff required, exit (NB V=0 from CMP) - -; mjs Kernel/HAL split -; pushed video controller info is now hardware independent, it is a VIDCList type 3 - - TEQ R3, #0 ; if no module claimed service - MOVEQ R2, R11 ; then use provided mode - BEQ %FT62 -59 - ADD R14, R9, #wkwordsize ; R14 -> space for VIDCList3 - MOV R10, #VIDCList3Size ; its a VIDCList3, R10 is max room we have -60 - LDR R8, [R3], #4 ; copy list - SUBS R10, R10, #4 - MOVEQ R8, #-1 ; emergency terminate (source list too long) - STR R8, [R14], #4 - CMP R8, #-1 - BNE %BT60 - CLRV - Pull "R2-R4,R7-R11, PC" ; done - -62 ; arrive here if service not claimed, R2 = provided mode number - BL ReadMonitorType ; get monitor type in R3 - CMP R3, #NumMonitorTypes ; monitor type must be in range - CMPCC R2, #NumModes ; and mode must be in range - MOVCC R11, #NumModes - MLACC R11, R3, R11, R2 ; then form monitortype*numberofmodes + modenumber - MOVCS R11, #0 ; if illegal then use mode 0 monitortype 0 -64 - ADRL R14, BigVIDCTable ; point to big table - LDR R11, [R14, R11, LSL #2] ; and load offset - CMP R11, #-1 ; if table offset is valid - ADDCC R3, R14, R11 ; then add to table address (R3 -> VIDCList3 from table) - BCC %BT59 ; copy it and exit - MOV R11, #0 ; desperate again, use mode 0 monitortype 0 (this had better have valid entry) - B %BT64 - -; ***************************************************************************** -; -; GenerateModeSelectorVars - Work out mode variables from mode selector -; or new format sprite mode word -; -; Note: the algorithms used to generate these variables are duplicated in -; s.vdu.vduswis in the OS_ReadModeVariable code. - -; in: r2 = new format sprite word or pointer to mode selector -; r9 -> stack frame to store vars in -; -; out: If valid then -; V=0 -; r0 preserved -; else -; V=1 -; r0 -> error -; endif -; All other registers preserved -; - -GenerateModeSelectorVars Entry "r0,r1,r3-r8,r10-r12" - ASSERT ModeSelector_Flags = 0 - ASSERT ModeSelector_XRes = 4 - ASSERT ModeSelector_YRes = 8 - ASSERT ModeSelector_PixelDepth = 12 - TST r2, #1 ; is it a new format sprite mode word? - BNE %FT50 ; [yes, so skip] - MOV r0, r2 - BL ValidateModeSelector - BVS %FT95 ; invalid - return error - LDMIB r2, {r4-r6} ; r4 = xres; r5 = yres; r6 = pixdepth - - STR r6, [r9, #wkLog2BPC] ; log2bpc = log2bpp = pixdepth - STR r6, [r9, #wkLog2BPP] - ADR lr, NColourTable - LDR lr, [lr, r6, LSL #2] ; load NColour value - STR lr, [r9, #wkNColour] - ADR lr, PalIndexTable - LDRB lr, [lr, r6] - STR lr, [r9, #wkPalIndex] - ADR lr, ECFIndexTable - LDRB lr, [lr, r6] - STR lr, [r9, #wkECFIndex] - - MOV lr, #0 - STR lr, [r9, #wkYShftFactor] ; yshftfactor = 0 (obsolete) - STR lr, [r9, #wkModeFlags] ; modeflags = 0 - - [ RogerEXEY -; TMD 09-Dec-93 -; New algorithms for xeig, yeig from Roger: -; xeig = 1: yeig = 1 -; if yres<xres/2 OR yres<400 then yeig = 2 -; if (xres<<xeig)<(yres<<yeig) then xeig = 2 - - CMP r5, r4, LSR #1 ; if yres < xres/2 - CMPCS r5, #400 ; or yres < 400 - MOVCC r7, #2 ; then yeig = 2 - MOVCS r7, #1 ; else yeig = 1 - STR r7, [r9, #wkYEigFactor] - - MOV r7, r5, LSL r7 ; r7 = yres << yeig - CMP r7, r4, LSL #1 ; if (xres<<1) < (yres<<yeig) - MOVHI r7, #2 ; then xeig = 2 - MOVLS r7, #1 ; else xeig = 1 - STR r7, [r9, #wkXEigFactor] - - MOV lr, #1 - | - MOV lr, #1 - STR lr, [r9, #wkXEigFactor] ; xeig = 1 - CMP r5, r4, LSR #1 ; if yres < xres/2 - MOVCC r7, #2 ; then yeig = 2 - MOVCS r7, #1 ; else yeig = 1 - STR r7, [r9, #wkYEigFactor] - ] - RSB r7, lr, r4, LSR #3 ; scrrcol = (xres >> 3) -1 - STR r7, [r9, #wkScrRCol] - RSB r7, lr, r5, LSR #3 ; scrbrow = (yres >> 3) -1 - STR r7, [r9, #wkScrBRow] - - SUB r7, r4, #1 - STR r7, [r9, #wkXWindLimit] ; xwindlimit = xres-1 - SUB r7, r5, #1 - STR r7, [r9, #wkYWindLimit] ; ywindlimit = yres-1 - - MOV r7, r4, LSL r6 ; r7 = xres << pixdepth - MOV lr, r7, LSR #3 - STR lr, [r9, #wkLineLength] ; linelen = (xres << pixdepth) >> 3 - - MUL r7, r5, r7 ; r7 = (xres * yres) << pixdepth - MOV lr, r7, LSR #3 - STR lr, [r9, #wkScreenSize] ; screensize = ((xres * yres) << pixdepth) >> 3 - - ADD r4, r2, #ModeSelector_ModeVars ; now do pairs of mode variables - BL ProcessModeVarPairs - - CLRV - EXIT - - -; store info for new format sprite word in stack frame - -50 - MOV r0, #0 - STR r0, [r9, #wkYShftFactor] ; yshftfactor = 0 - STR r0, [r9, #wkModeFlags] ; modeflags = 0 - - MOV r0, r2, LSR #27 ; get type - CMP r0, #SpriteType_MAX ; check for legality - NB type 0 is illegal because r2>=&100 - MOVCS r0, #SpriteType_Substitute ; substitute if unknown - ADRL lr, NSM_bpptable-4 - LDR r0, [lr, r0, LSL #2] ; get the bpp from table - - STR r0, [r9, #wkLog2BPC] - STR r0, [r9, #wkLog2BPP] - - ADR r1, NColourTable - LDR r1, [r1, r0, LSL #2] - STR r1, [r9, #wkNColour] - - ADR r1, PalIndexTable - LDRB r1, [r1, r0] - STR r1, [r9, #wkPalIndex] - - ADR r1, ECFIndexTable - LDRB r1, [r1, r0] - STR r1, [r9, #wkECFIndex] - - MOV r1, r2, LSL #(31-13) - MOV r1, r1, LSR #(31-13)+1 ; extract xdpi (bits 1..13) - - TEQ r1, #180 ; 180 => xeig=0 - MOVEQ r1, #0 - BEQ %FT70 - - TEQ r1, #22 ; 22/23 => xeig=3 - TEQNE r1, #23 - MOVEQ r1, #3 - BEQ %FT70 - - TEQ r1, #(45 :SHL: 2), 2 ; check if 45 (EQ,CC if so) - CMPNE r1, #90 ; or 90 (EQ,CS if so) - BNE %FT80 - MOVCC r1, #2 ; 45 => xeig=2 - MOVCS r1, #1 ; 90 => xeig=1 -70 - STR r1, [r9, #wkXEigFactor] - - MOV r1, r2, LSL #(31-26) - MOV r1, r1, LSR #(31-26)+14 ; extract ydpi (bits 14..26) - - TEQ r1, #180 ; 180 => yeig=0 - MOVEQ r1, #0 - BEQ %FT71 - - TEQ r1, #22 ; 22/23 => yeig=3 - TEQNE r1, #23 - MOVEQ r1, #3 - BEQ %FT71 - - TEQ r1, #(45 :SHL: 2), 2 ; check if 45 (EQ,CC if so) - CMPNE r1, #90 ; or 90 (EQ,CS if so) - BNE %FT80 - MOVCC r1, #2 ; 45 => yeig=2 - MOVCS r1, #1 ; 90 => yeig=1 -71 - STR r1, [r9, #wkYEigFactor] - - CLRV - EXIT - -80 - ADR r0, ErrorBlock_Sprite_BadDPI -90 - [ International - BL TranslateError - ] -95 - STR r0, [sp] ; update saved r0 - SETV ; indicate error - EXIT - -NColourTable & NColour_0, NColour_1, NColour_2 - & NColour_3, NColour_4, NColour_5 -PalIndexTable = 0, 1, 2, 3, 6, 7 - ALIGN ; makes ECFIndexTable more accessible -ECFIndexTable = 4, 2, 3, 5, 5, 5 - ALIGN - - MakeErrorBlock BadPixelDepth - MakeErrorBlock Sprite_BadDPI - -; ***************************************************************************** -; -; ValidateModeSelector - Check a mode selector is valid -; -; in: r0 -> mode selector -; -; out: If OK, then -; V=0 -; All registers preserved -; else -; V=1 -; r0 -> error -; All other registers preserved -; endif -; - -ValidateModeSelector Entry - LDR lr, [r0, #ModeSelector_Flags] - AND lr, lr, #ModeSelectorFlags_FormatMask - TEQ lr, #ModeSelectorFlags_ValidFormat - ADRNE r0, ErrorBlock_BadMSFlags - BNE %FT90 - LDR lr, [r0, #ModeSelector_PixelDepth] - CMP lr, #6 - ADRCS r0, ErrorBlock_BadPixelDepth - BCS %FT90 - CLRV - EXIT - -90 - [ International - BL TranslateError - ] - SETV - EXIT - - MakeErrorBlock BadMSFlags - - -; ***************************************************************************** -; -; ProcessModeVarPairs - Modify stacked variable info from -; mode variable (index, value) pairs -; -; Internal routine used to do Service_ModeExtension workspace lists and -; mode selectors -; -; in: r4 -> first pair (may be none) -; r9 -> stack frame -; -; out: All registers preserved - -ProcessModeVarPairs Entry "r4, r8, r10" - ADRL r14, RMVTab -10 - LDR r10, [r4], #4 ; get next entry in ws table - CMP r10, #-1 - EXIT EQ ; no more to do - CMP r10, #(SWIRVVTabModeEnd-SWIRVVTab) ; is it a mode variable ? - BCS %BT10 ; no, then ignore - LDRB r10, [r14, r10] ; load index out of RMVTab - MOVS r10, r10, LSR #1 ; shift byte/word flag into carry - LDR r8, [r4], #4 ; load value - STRCCB r8, [r9, r10] ; either store byte - STRCS r8, [r9, r10] ; or store word - B %BT10 - -; ***************************************************************************** -; -; OfferModeExtension - Issue mode extension service -; -; in: R2 = mode specifier -; -; out: EQ => service claimed, R3 -> VIDC list, R4 -> workspace list -; NE => service not claimed, R3,R4 preserved -; All other registers preserved -; - -OfferModeExtensionAnyMonitor ROUT - MOV r3, #-1 -OfferModeExtension ROUT - Push "r1,r2,r4,r5,r14" - -; TMD 10-Jan-94 - added code here to check for erroneous passing in of a sprite mode word. -; This prevents data aborts when modules try to index off a bad address. -; -; We could have done OS_ValidateAddress, but that would be rather slow, and mode selectors -; are of indeterminate length. -; -; If we detect one of these, we pretend the service wasn't claimed. Hopefully this should -; ensure that the mode change returns an error. - -; Fixes bug MED-00483. - - BICS r14, r2, #&FF ; NE if not a mode number - TSTNE r2, #3 ; NE if not a mode number, but invalid mode selector - Pull "r1,r2,r4,r5,pc", NE ; so exit NE, pretending that service not claimed - - GetBandwidthAndSize r4, r5 - MOV r1, #Service_ModeExtension - IssueService - TEQ r1, #0 ; if service claimed - CMPNE r3, #-1 ; or if "don't care" monitortype - BEQ %FT90 ; then we can't do any more - - CMP r2, #&100 ; if it's a mode selector - BCS %FT90 ; then we can't help them either - BranchIfNotKnownMode r2, %FA90 ; if we don't recognise screen mode number we can't either - -; it is a known numbered mode, so create a mode selector on the stack that we can pass to service - - Push "r6,r7" - SUB sp, sp, #ModeSelector_ModeVars+4 ; make room for block including terminator - MOV r6, #ModeSelectorFlags_ValidFormat - STR r6, [sp, #ModeSelector_Flags] - ADRL r6, FrameRateTable - LDRB r6, [r6, r2] - STR r6, [sp, #ModeSelector_FrameRate] - - ADRL r6, Vwstab - LDR r14, [r6, r2, LSL #2] - ADD r6, r6, r14 - LDR r14, [r6, #wkLog2BPP] - STR r14, [sp, #ModeSelector_PixelDepth] ; pixdepth = log2bpp - - LDR r7, [r6, #wkLog2BPC] - SUB r14, r7, r14 ; r14 = log2bpc-log2bpp - - LDR r7, [r6, #wkXWindLimit] - ADD r7, r7, #1 - MOV r7, r7, LSL r14 - STR r7, [sp, #ModeSelector_XRes] - - LDR r7, [r6, #wkYWindLimit] - ADD r7, r7, #1 - STR r7, [sp, #ModeSelector_YRes] - - MOV r7, #-1 - STR r7, [sp, #ModeSelector_ModeVars] - - MOV r2, sp - IssueService - TEQ r1, #0 - BEQ %FT10 ; service was claimed - -; not claimed, so try again with -1 as frame rate - - MOV r7, #-1 - STR r7, [sp, #ModeSelector_FrameRate] - IssueService - TEQ r1, #0 -10 - ADD sp, sp, #ModeSelector_ModeVars+4 ; junk mode selector - Pull "r6, r7" -90 - CMP r2, #&100 ; if we started or ended up with a mode selector - MOVCS r4, #0 ; then return r4 = 0 (if claimed) - - TEQ r1, #0 - STREQ r4, [sp, #2*4] ; if service claimed, then return r4 from service, else preserve it - Pull "r1,r2,r4,r5,pc" - - [ STB -svc_PortMan - TEQ R0, #0 ; PortManager starting - MOVNE PC, LR - - [ {TRUE} -;;;mjsHAL - may need sorting/HAL split -;;; for now, switched out coz kernel doesn't have VIDCControlSoftCopy any more! -;;; - ! 0, "mjsHAL - svc_PortMan currently broken by kernel/HAL split" - MOV PC, LR - | -; When PortManager restarts, we need to put TV_Mode back. PortMan defaults to -; output high, but we don't know polarity of bit, so must set either way. - Entry "r0-r1, WsPtr" - VDWS WsPtr - LDR R0, [WsPtr, #VIDCControlSoftCopy] ; get saved VIDC control register - AND R0, R0, #CR_VCLK :OR: CR_HCLK :OR: CR_RCLK - TEQ R0, #CR_HCLK ; are we using HCLK? - MOVNE R0, #1 ; no: TV_Mode = 0 - MOVEQ R0, #3 ; yes: TV_Mode = 1 - addr R1, TV_Mode_string - SWI XPortMan_AccessBit - EXIT - ] - ] - - -; ***************************************************************************** -; -; ETB - Redefine character -; === & other stuff -; -; VDU 23,0,r,v,0| Talk to 6845 ! -; VDU 23,1,n,m,r,g,b| Program cursor -; VDU 23,2,n1..n8 Ecf pattern 1 -; VDU 23,3,n1..n8 Ecf pattern 2 -; VDU 23,4,n1..n8 Ecf pattern 3 -; VDU 23,5,n1..n8 Ecf pattern 4 -; VDU 23,6,n1..n8 Dot dash line style -; VDU 23,7,m,d,z| Scroll window directly -; VDU 23,8,t1,t2,x1,y1,x2,y2| Clear block -; VDU 23,9,n| Set 1st flash time -; VDU 23,10,n| Set 2nd flash time -; VDU 23,11| Default Ecf patterns -; VDU 23,12,n1..n8 Ecf pattern 1 (simple setting) -; VDU 23,13,n1..n8 Ecf pattern 2 (simple setting) -; VDU 23,14,n1..n8 Ecf pattern 3 (simple setting) -; VDU 23,15,n1..n8 Ecf pattern 4 (simple setting) -; VDU 23,16,x,y| Cursor movement control -; VDU 23,17,c,t| Set colour tints, ECF info, char sizes -; -; -ETB - LDRB R0, [WsPtr, #QQ+0] - CMP R0, #32 ; defining a normal character ? - BCS DefineChar - LDR R2, [PC, R0, LSL #2] - ADD PC, PC, R2 ; enters routine with R0 => byte after 23 - - -ETBtab - & Vdu23_0-ETBtab-4 - & Vdu23_1-ETBtab-4 - & ComplexEcfPattern-ETBtab-4 - & ComplexEcfPattern-ETBtab-4 - & ComplexEcfPattern-ETBtab-4 - & ComplexEcfPattern-ETBtab-4 - & LineStyle-ETBtab-4 - & Vdu23_7-ETBtab-4 - & Vdu23_8-ETBtab-4 - & Vdu23_9-ETBtab-4 - & Vdu23_10-ETBtab-4 - & DefaultEcfPattern-ETBtab-4 - & SimpleEcfPattern-ETBtab-4 - & SimpleEcfPattern-ETBtab-4 - & SimpleEcfPattern-ETBtab-4 - & SimpleEcfPattern-ETBtab-4 - & Vdu23_16-ETBtab-4 - & Vdu23_17-ETBtab-4 - & Vdu23_18-ETBtab-4 - & Vdu23_19-ETBtab-4 - & Vdu23_20-ETBtab-4 - & Vdu23_21-ETBtab-4 - & Vdu23_22-ETBtab-4 - & Vdu23_23-ETBtab-4 - & Vdu23_24-ETBtab-4 - & Vdu23_25-ETBtab-4 - & Vdu23_26-ETBtab-4 - & Vdu23_27-ETBtab-4 - & Vdu23_28-ETBtab-4 - & Vdu23_29-ETBtab-4 - & Vdu23_30-ETBtab-4 - & Vdu23_31-ETBtab-4 - -; NB All other labels for Vdu23 are in TMD files so I don't have to pester RCM - -;Vdu23_18 ; Assigned to Teletext operations -Vdu23_19 -Vdu23_20 -Vdu23_21 -Vdu23_22 -Vdu23_23 -Vdu23_24 -Vdu23_25 -Vdu23_26 -; Vdu23_27 ; Assigned to Richard (well some of it, anyway) -Vdu23_28 -Vdu23_29 -Vdu23_30 -Vdu23_31 -UnknownVdu23 - -; R0 already contains first parameter to VDU23 - - MOV R10, #UKVDU23V - Push "WsPtr, R14" ; calling a vector corrupts R12 - BL VduQQVec ; so we have to preserve it - Pull "WsPtr, PC", VC ; before we return to PostWrchCursor - -; error in UKVDU23 vector, so go to vdu error exit - - Pull "WsPtr, R14" - B VduBadExit - -; ***************************************************************************** -; -; DLE -; CLG - Clear graphics window -; === -; -; On exit, R0..R11 corrupt -; -DLE -CLG ROUT - GraphicsMode R0 - MOVNE PC,LR ; check for graphics mode (changed by DDV 15/9/92) - - ADD R0, WsPtr, #BgEcfOraEor ; point at background colour - STR R0, [WsPtr, #GColAdr] - ADD R11, WsPtr, #GWLCol ; load window coordinates into - LDMIA R11, {R0-R3} ; RectFill's parameter space - - LDR R6, [WsPtr, #CursorFlags] ; if clip box is not enabled - TST R6, #ClipBoxEnableBit ; then goto code directly - BEQ RectFillA - - Push R14 ; else merge graphics window (in R0-R3) - BL MergeClipBox ; with clip box - Pull R14 - B RectFillA - -; ***************************************************************************** -; -; DC2 -; GCol - Set Graphics action and colour -; ==== -; -; On entry, R0 holds GCol action -; R1 holds GCol colour, 0..127 means program fg -; 128..255 means program bg -; -; In 256-colour modes, the extra colours are accessed via TINT -; -DC2 -GCol ROUT - LDRB R0, [WsPtr, #QQ+0] ; GCol action, eg store, eor etc. - LDRB R1, [WsPtr, #QQ+1] ; GCol colour - LDR R2, [WsPtr, #NColour] ; number of colours-1 - TST R1, #&80 - AND R1, R1, R2 ; limit colour to range available - - STREQ R0, [WsPtr, #GPLFMD] ; GCOL(a,0..127) is foreground - STREQ R1, [WsPtr, #GFCOL] - - STRNE R0, [WsPtr, #GPLBMD] ; GCOL(a,128..255) is background - STRNE R1, [WsPtr, #GBCOL] - ; drop into SetColour to.... - -; SetColour - Setup FgEcf & BgEcf, used after GCOL or setting of Ecfs -; ========= or default palette (does a gcol). - -SetColour - Push R14 - LDR R1, [WsPtr, #GPLFMD] ; setup FgEcf, maybe solid or Ecf - LDR R0, [WsPtr, #GFCOL] - ADD R2, WsPtr, #FgEcf - LDR R3, [WsPtr, #GFTint] ; tint only used in 256 colour modes - ADD R4, WsPtr, #FgPattern ; used if OS_SetColour call - BL SetCol10 - - LDR R1, [WsPtr, #GPLBMD] ; and BgEcf - LDR R0, [WsPtr, #GBCOL] - ADD R2, WsPtr, #BgEcf - LDR R3, [WsPtr, #GBTint] - ADD R4, WsPtr, #BgPattern ; used if OS_SetColour call - BL SetCol10 - - ADD R0, WsPtr, #FgEcf ; setup FgEcfOraEor - ADD R1, WsPtr, #BgEcf - ADD R2, WsPtr, #FgEcfOraEor - LDR R3, [WsPtr, #GPLFMD] - BL SetCol60 - - ADD R0, WsPtr, #BgEcf ; and BgEcfOraEor - ADD R1, WsPtr, #FgEcf - ADD R2, WsPtr, #BgEcfOraEor - LDR R3, [WsPtr, #GPLBMD] - BL SetCol60 - - ADD R0, WsPtr, #BgEcf ; and BgEcfStore - ADD R1, WsPtr, #FgEcf - ADD R2, WsPtr, #BgEcfStore - MOV R3, #0 - BL SetCol60 - - Pull PC - -; SetCol10 - Internal to SetColour -; Build up an Ecf, given action and colour numbers -; -; On entry, R0 holds colour (0..255, where 127..255 means 0..127) -; R1 holds action (may indicate ecf) -; R2 holds address to write data (FgEcf or BgEcf) -; R3 holds tint information (only used in 256 colour modes) -; R4 holds pointer to suitable pattern table for OS_SetColour call - -SetCol10 ROUT - ANDS R1, R1, #&F0 ; actions >=16 mean Ecf - BNE SetCol30 - - Push R14 - LDR R4, [WsPtr, #NColour] ; else use given colour number - AND R0, R0, R4 - AND R0, R0, #63 ; another bodge in the house of bodges - TST R4, #&F0 ; if 256 colour (ie 8bpp) - BLNE AddTintToColour ; then combine tint with colour - -; R0 contains colour number for current mode - - LDR LR, [WsPtr, #BitsPerPix] -10 - TEQ LR, #32 - ORRNE R0, R0, R0, LSL LR ; replicate again - MOVNE LR, LR, LSL #1 ; doubling the shift for each pass - BNE %BT10 - - STR R0, [R2] - STR R0, [R2, #4] - STR R0, [R2, #8] - STR R0, [R2, #12] - STR R0, [R2, #16] - STR R0, [R2, #20] - STR R0, [R2, #24] - STR R0, [R2, #28] - - Pull "PC" - -; R1 = ecf number as 16,32,48,64,80,96 -; R2 -> destination -; R4 -> pattern block (if R1 =96!) - -SetCol30 - CMP R1, #96 ; special internal plot? - MOVCS R0, R4 ; yes, so point at pattern to be copied - MOVCS R3, #1 ; col step =1 - MOVCS R4, #0 ; row step =0 (already there!) - BCS SetCol35 - - CMP R1, #80 ; 80 => giant ecf (>80 does same) - ADDCS R0, WsPtr, #Ecf1 ; then point at ecf0 - MOVCS R3, #8 ; col step=8 - MOVCS R4, #(1-8*4) ; row step, back to 1st ecf on 1 byte - BCS SetCol35 - - ADD R0, WsPtr, #(Ecf1-8) - ADD R0, R0, R1, LSR #1 ; else point R0 at Ecf1,2,3 or 4 - - LDR R4, [WsPtr, #BitsPerPix] ; if BitsPerPix <> 'fudged' BitsPerPix - LDR R5, [WsPtr, #BytesPerChar] - TEQ R4, R5 - BNE SetCol52 ; then double up the pixels - ; else its a normal Ecf - MOV R3, #0 ; col step=0, same byte each coloum - MOV R4, #1 ; row step=1 -SetCol35 - MOV R5, #8 ; do 8 rows -SetCol40 - MOV R6, #4 ; of 4 columns -SetCol50 - LDRB R7, [R0], R3 ; read from source & move by col step - STRB R7, [R2], #1 ; write to dest, update dest pointer - SUBS R6, R6, #1 - BNE SetCol50 - ADD R0, R0, R4 ; step source pointer to next row - SUBS R5, R5, #1 - BNE SetCol40 - MOV PC, R14 - -; Double up the pixels for Mode2 etc -; -; R0 points to Ecf(n) -; R2 points to destination -; -; Uses -; -; R3 - NColour used as PixMsk -; R4 - BitsPerPix -; R5 - BytesPerChar (unused) -; R6 - byte cntr 7..0 -; R7 - source byte -; R8 - ExtrtShftFact -; R9 - InsrtShftFact -; R10 - result word -; R11 - temp - -SetCol52 - LDR R3, [WsPtr, #NColour] ; mask for extracting pixels from ecf - TST R3, #&F0 ; ** if 256 colour mode - MOVNE R3, #&FF ; ** then use &FF (TMD 25-Mar-87) - LDR R4, [WsPtr, #BitsPerPix] - MOV R6, #7 ; 8 bytes/rows to do -SetCol54 - LDRB R7, [R0, R6] ; get byte of Ecf(n) - RSB R8, R4, #8 - RSB R9, R4, #32 - MOV R10, #0 ; clear result word -SetCol57 - AND R11, R3, R7, ROR R8 ; extract 1 pixel from Ecf - ORR R10, R10, R11, LSL R9 ; double it into result word - SUB R9, R9, R4 - ORR R10, R10, R11, LSL R9 - - SUB R8, R8, R4 - AND R8, R8, #7 - - SUBS R9, R9, R4 - BGE SetCol57 ; process next pixel in result word - - STR R10, [R2, R6, LSL #2] ; write expanded word to (Fg/Bg)Ecf - - SUBS R6, R6, #1 - BGE SetCol54 ; process next row/byte - MOV PC, R14 - -; Tables of full colours for 2,4 & 16 colour modes (256 colour modes -; use colour number directly). -; -; N.B. these are tables of bytes - -TBFullCol - = &FF ; not used - remove sometime - ; (DJS comment: don't bother!) - = &00, &FF ; 2 colour mode - = &00, &55, &AA, &FF ; 4 colour mode - - = &FF, &FF, &FF, &FF ; not used but cannot be removed - = &FF, &FF, &FF, &FF ; (8 colour mode!) - - = &00, &11, &22, &33 ; 16 colour mode - = &44, &55, &66, &77 - = &88, &99, &AA, &BB - = &CC, &DD, &EE, &FF - - ALIGN - -; ***************************************************************************** -; -; SetCol60 - Build up an ecf, ORed and EORed appropriate to GCOL action -; -; Internal to SetColour -; -; in: R0 -> ecf colour (FgEcf/BgEcf) -; R1 -> transparent colour (BgEcf/FgEcf) -; R2 -> destination FgEcfOraEor/BgEcfOraEor/BgEcfStore -; R3 = gcol action number (may indicate ecf) -; -; uses: R4 = index into ecf (7..0) -; R5 = ecf colour word -; R6 = transparency mask, set to &FFFFFFFF for NO transparency -; R7 -> zgoo..zgee for gcol action -; R8 = mask for pixel under examination -; R9 = shift factor to move mask to next pixel (BytesPerChar) -; R10, R11 temporary -; - -SetCol60 ROUT - MOV R4, #7 ; 7..0 words to process - AND R3, R3, #&F ; extract action bits - AND R11, R3, #7 ; 0-7 Store etc - ; 8-15 ditto with transparency - MOV R11, R11, LSL #2 ; 4 bits for each - LDR R7, =TBscrmasks - MOV R7, R7, ROR R11 ; relevant bits are in top 4 - AND R7, R7, #&F0000000 ; isolate these bits (N,Z,C,V) -SetCol70 - LDR R5, [R0, R4, LSL #2] ; get ecf word - TST R3, #8 ; if action < 8 - MOVEQ R6, #&FFFFFFFF - BEQ SetCol90 ; then not transparent - ; else build transparency mask - LDR R8, [WsPtr, #RAMMaskTb] ; fetch mask for leftmost pixel - LDR R9, [WsPtr, #BytesPerChar] ; shift factor for next pixel - LDR R6, [R1, R4, LSL #2] ; get 'transparent' colour - EOR R6, R6, R5 -SetCol80 - TST R6, R8 ; if pixels the same, - ; then it's transparent - ORRNE R6, R6, R8 ; else set mask to plot it - MOVS R8, R8, LSL R9 - BNE SetCol80 - -SetCol90 - MSR CPSR_f, R7 ; put bits into N, Z, C, V - ; OO,EO,OE,EE - - MOVCC R10, R5 ; if ORing with &00000000 - MOVCS R10, #&FFFFFFFF ; if ORing with &FFFFFFFF - MVNVS R10, R10 ; if EORing with &FFFFFFFF - -; MOVPL R5, R5 ; if ORing with &00000000 - MOVMI R5, #&FFFFFFFF ; if ORing with &FFFFFFFF - MVNEQ R5, R5 ; if EORing with &FFFFFFFF - -; now R5 = OR mask, R10 = EOR mask - - AND R5, R5, R6 ; then clear 'transparent' - AND R10, R10, R6 ; pixels - - LDR R11, [WsPtr, #ECFShift] - MOV R5, R5, ROR R11 ; rotate OR and EOR masks - MOV R10, R10, ROR R11 ; to correct for ECF X origin - - LDR R11, [WsPtr, #ECFYOffset] - ADD R11, R11, R4 ; add on ECF Y offset - AND R11, R11, #7 ; and wrap - - ADD R11, R2, R11, LSL #3 - STMIA R11, {R5, R10} ; write to (Fg/Bg)EcfOraEor - - SUBS R4, R4, #1 - BCS SetCol70 - - MOV PC, R14 - -; ***************************************************************************** -; -; AddTintToColour - in 256 colour modes -; -; Internal to SetColour (derived from TMD's FudgeColour) -; -; in: R0 = colour (0..255), where 6 LSBits are used -; R3 = tint -; -; out: R0 holds colour byte with tint added -; R1-R3 preserved -; R4 undefined -; PSR preserved -; - - ! 0,"WARNING: AddTintToColour returns > 8 bit values now, check ECF handling!" - -AddTintToColour - Push "R3,LR" - AND R0, R0, #63 ; extract suitable set of bits - AND R3, R3, #192 ; and another set - ORR R0, R0, R3 - BL ConvertGCOLToColourNumber - Pull "R3,PC" - -; ***************************************************************************** -; -; CAN - Define graphics window -; -; External routine -; -; in: The window is given by bytes in the vdu queue, as follows :- -; QQ+0 = leftLo -; QQ+1 = leftHi -; QQ+2 = bottomLo -; QQ+3 = bottomHi -; QQ+4 = rightLo -; QQ+5 = rightHi -; QQ+6 = topLo -; QQ+7 = topHi -; -; These are relative to the current graphics origin. -; The resultant window must obey the following rules :- -; RCol >= LCol -; TRow >= BRow -; LCol >= 0 -; BRow >= 0 -; YWindLimit >= TRow -; XWindLimit >= RCol -; - -CAN ROUT - Push R14 - ADD R8, WsPtr, #GCsX ; save ECursor away, cos EIG changes it - LDMIA R8, {R6, R7} ; and we don't want it to! - -; *****Change made by DJS -; Original code was: -; LDRB R0, [WsPtr, #QQ+5] ; rightHi -; LDRB R1, [WsPtr, #QQ+4] ; rightLo -; PackXtnd R0,R0,R1 ; pack 2 bytes and sign extend -; -; LDRB R1, [WsPtr, #QQ+7] ; topHi -; LDRB R2, [WsPtr, #QQ+6] ; topLo -; PackXtnd R1,R1,R2 ; pack 2 bytes and sign extend - - LoadCoordPair R0, R1, WsPtr, QQ+4 ;Get top right point - -; *****End of change made by DJS - - MOV R2, #&FF ; convert external-to-internal - BL EIG ; as absolute coordinates - - MOV R4, R0 ; move internal version of top right - MOV R5, R1 ; out of harm's way - -; *****Change made by DJS -; Original code was: -; LDRB R0, [WsPtr, #QQ+1] ; leftHi -; LDRB R1, [WsPtr, #QQ+0] ; leftLo -; PackXtnd R0,R0,R1 ; pack 2 bytes and sign extend -; -; LDRB R1, [WsPtr, #QQ+3] ; bottomHi -; LDRB R2, [WsPtr, #QQ+2] ; bottomLo -; PackXtnd R1,R1,R2 ; pack 2 bytes and sign extend - - LoadCoordPair R0, R1, WsPtr, QQ+0 ;Get bottom left point - -; *****End of change made by DJS - - MOV R2, #&FF ; convert external-to-internal - BL EIG ; as absolute coordinates - -; For a valid window, the following must be true - - CMP R4, R0 ; RCol >= LCol - CMPGE R5, R1 ; TRow >= BRow - CMPGE R0, #0 ; LCol >= 0 - CMPGE R1, #0 ; BRow >= 0 - LDRGE R2, [WsPtr, #YWindLimit] ; YWindLimit >= TRow - CMPGE R2, R5 - LDRGE R2, [WsPtr, #XWindLimit] ; XWindLimit >= RCol - CMPGE R2, R4 - - ADD R2, WsPtr, #GWLCol - STMGEIA R2, {R0,R1, R4,R5} ; if the new window is OK, update it - - STMIA R8, {R6, R7} ; restore ECursor (EIG corrupted it) - Pull PC - -; ***************************************************************************** -; -; DefaultWindows - Restore default windows -; -; External routine, and called by mode change + switch output to sprite -; -; Set default text and graphics windows, -; Clear graphics origin and both cursors -; - -DefaultWindows ROUT - Push R14 - MOV R0, #0 - MOV R1, #0 - ADD R4, WsPtr, #GWLCol - - ASSERT YWindLimit = XWindLimit +4 - - ADD R2, WsPtr, #XWindLimit - LDMIA R2, {R2,R3} ; R2 := XWindLimit; R3 := YWindLimit - STMIA R4, {R0-R3} ; zero GWLCol, GWBRow - ; GWRCol:=XWindLimit; GWTRow:=YWindLimit - MOV R3, #0 - LDR R1, [WsPtr, #ScrBRow] - LDR R2, [WsPtr, #ScrRCol] - ADD R4, WsPtr, #TWLCol ; zero TWLCol, TWTRow - STMIA R4!, {R0-R3} ; TWRCol := ScrRCol; TWBRow := ScrBRow - - MOV R1, #0 - MOV R2, #0 - STMIA R4!, {R0-R3} ; zero OrgX, OrgY, GCsX, GCsY - STMIA R4!, {R0-R3} ; zero OlderCsX, OlderCsY, OldCsX, OldCsY - STMIA R4!, {R0-R3} ; zero GCsIX, GCsIY, NewPtX, NewPtY - - LDR R0, [WsPtr, #VduSprite] - TEQ R0, #0 - - LDR R0, [WsPtr, #VduStatus] ; if not outputting to sprite - BICEQ R0, R0, #Windowing ; then indicate no text window - ORRNE R0, R0, #Windowing ; else indicate is text window - STR R0, [WsPtr, #VduStatus] - - BL HomeVdu4 ; home TEXT cursor - ; (even in VDU 5 mode) - Pull PC - -; ***************************************************************************** -; -; GS - Define graphics origin -; -; External routine -; -; in: The origin is given by bytes in the vdu queue, as follows :- -; QQ+0 = xLo -; QQ+1 = xHi -; QQ+2 = yLo -; QQ+3 = yHi -; -; The coordinates are in external 16 bit form. -; This does not move the windows, but does move the graphics cursor -; - -GS ROUT - Push R14 - -; *****Change made by DJS -; Original code was: -; LDRB R0, [WsPtr, #QQ+1] ; xHi -; LDRB R1, [WsPtr, #QQ+0] ; xLo -; PackXtnd R0,R0,R1 ; pack 2 bytes and sign extend -; LDRB R1, [WsPtr, #QQ+3] ; yHi -; LDRB R2, [WsPtr, #QQ+2] ; yLo -; PackXtnd R1,R1,R2 ; pack 2 bytes and sign extend - - LoadCoordPair R0, R1, WsPtr, QQ+0 - -; *****End of change made by DJS - - ADD R2, WsPtr, #OrgX - STMIA R2, {R0,R1} ; write the new origin - BL IEG ; update external cursor - Pull PC - - LTORG - -;------------------------------------------------------------------------------ -; -; OS_SetColour implementation -; ------------ -; -; This call can be used to change the current GCOL/pattern table used for -; plotting with the VDU primitives. -; -; in R0 = flags / logical operation -; bit 0-3 = logical operation -; bit 4 = set => bg, else fg flag -; bit 5 = set => pattern block supplied -; bit 6 = set => set text colour -; bit 7 = set => read colour -; R1 = colour number / -> pattern block to use -; out - -; -;------------------------------------------------------------------------------ - -setcol_LogicOpMask * &0F -setcol_FgBgFlag * &10 -setcol_PatternFlag * &20 -setcol_TextColour * &40 -setcol_ReadFlag * &80 - - ASSERT WsPtr > 9 - -SWISetColour ROUT - - Push "R0-R9,WsPtr,R14" - - VDWS WsPtr ; Obtain base of the VDU driver workspace - - TST R0, #setcol_ReadFlag ; Are we reading? - BNE %FT75 - - TST R0, #setcol_TextColour ; Are we changing the text colour? - BNE %FT70 - - AND R2, R0, #setcol_LogicOpMask ; Get the logical operation - ORR R2, R2, #&60 ; Mark as being a special kind of pattern - - TST R0, #setcol_FgBgFlag - STREQ R2, [WsPtr, #GPLFMD] ; Store the relevant logical operation away for fg/bg - STRNE R2, [WsPtr, #GPLBMD] - ADDEQ R3, WsPtr, #FgPattern - ADDNE R3, WsPtr, #BgPattern ; Setup the pointer to a store for the pattern - - TST R0, #setcol_PatternFlag ; Did the caller specify a pattern block? - BNE %FT50 ; Yes so don't try to expand colour value to pattern - - MOV R2, #1 - LDR R4, [WsPtr, #Log2BPP] ; Get the Log2 depth of the mode - MOV R4, R2, ASL R4 ; R4 = bits per pixel - RSB R2, R2, R2, LSL R4 ; Get a mask to extract only meaningful bits from word - AND R1, R1, R2 ; Extract bits suitable for this depth of mode -10 - TEQ R4, #32 ; Do we need to do any more replication - ORRNE R1, R1, R1, LSL R4 ; Yes so or word with itself shifted - MOVNE R4, R4, LSL #1 ; and double amount to shift next time - BNE %BT10 - - MOV R2, #8 -20 - STR R1, [R3], #4 ; now copy word 8 times into block - SUBS R2, R2, #1 - BNE %BT20 - B %FT60 - -50 - LDMIA R1,{R0,R2,R4-R9} - STMIA R3,{R0,R2,R4-R9} ; Copy the pattern into the buffer (assumes word aligned) -60 - BL SetColour ; And then setup the internal GCOL tables -65 - Pull "R0-R9,WsPtr,R14" - ExitSWIHandler -70 - TST R0, #setcol_FgBgFlag ; Store the foreground or background colour? - STREQ R1, [WsPtr, #TextFgColour] - STRNE R1, [WsPtr, #TextBgColour] - - LDR R0, [WsPtr, #CursorFlags] ; Indicate the text colour needs re-computing! - ORR R0, R0, #TEUpdate - STR R0, [WsPtr, #CursorFlags] - - B %BT65 ; Leave gracefully .... - -75 - ; Reading the colour... - TST R0, #setcol_TextColour - BEQ %FT80 - - ; Reading text colour - TST R0, #setcol_FgBgFlag - LDREQ R1, [WsPtr, #TextFgColour] - LDRNE R1, [WsPtr, #TextBgColour] - BIC R0, R0, #setcol_PatternFlag :OR: setcol_ReadFlag - -77 - ; Standard exit for reading the colour - STMIA SP, {R0,R1} - B %BT65 - -80 - ; Reading graphics colour - TST R0, #setcol_FgBgFlag - LDREQ R2, [WsPtr, #GPLFMD] ; Get the relevant logical operation for fg/bg - LDRNE R2, [WsPtr, #GPLBMD] - - ; SetColour setting - copy block - ADDEQ R3, WsPtr, #FgEcf - ADDNE R3, WsPtr, #BgEcf - - ; Copy the pattern to the user's buffer - LDMIA R3,{R0,R3,R4-R9} - STMIA R1,{R0,R3,R4-R9} - - ; Construct a suitable reason code - AND R0, R2, #setcol_LogicOpMask - ORRNE R0, R0, #setcol_FgBgFlag - ORR R0, R0, #setcol_PatternFlag - B %BT77 - - END diff --git a/s/vdu/vdufont b/s/vdu/vdufont deleted file mode 100644 index 5d14964a..00000000 --- a/s/vdu/vdufont +++ /dev/null @@ -1,243 +0,0 @@ -; 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.VduFont - -HardFont - = &00, &00, &00, &00, &00, &00, &00, &00 - = &18, &18, &18, &18, &18, &00, &18, &00 - = &6C, &6C, &6C, &00, &00, &00, &00, &00 - = &36, &36, &7F, &36, &7F, &36, &36, &00 - = &0C, &3F, &68, &3E, &0B, &7E, &18, &00 - = &60, &66, &0C, &18, &30, &66, &06, &00 - = &38, &6C, &6C, &38, &6D, &66, &3B, &00 - = &0C, &18, &30, &00, &00, &00, &00, &00 - = &0C, &18, &30, &30, &30, &18, &0C, &00 - = &30, &18, &0C, &0C, &0C, &18, &30, &00 - = &00, &18, &7E, &3C, &7E, &18, &00, &00 - = &00, &18, &18, &7E, &18, &18, &00, &00 - = &00, &00, &00, &00, &00, &18, &18, &30 - = &00, &00, &00, &7E, &00, &00, &00, &00 - = &00, &00, &00, &00, &00, &18, &18, &00 - = &00, &06, &0C, &18, &30, &60, &00, &00 - = &3C, &66, &6E, &7E, &76, &66, &3C, &00 - = &18, &38, &18, &18, &18, &18, &7E, &00 - = &3C, &66, &06, &0C, &18, &30, &7E, &00 - = &3C, &66, &06, &1C, &06, &66, &3C, &00 - = &0C, &1C, &3C, &6C, &7E, &0C, &0C, &00 - = &7E, &60, &7C, &06, &06, &66, &3C, &00 - = &1C, &30, &60, &7C, &66, &66, &3C, &00 - = &7E, &06, &0C, &18, &30, &30, &30, &00 - = &3C, &66, &66, &3C, &66, &66, &3C, &00 - = &3C, &66, &66, &3E, &06, &0C, &38, &00 - = &00, &00, &18, &18, &00, &18, &18, &00 - = &00, &00, &18, &18, &00, &18, &18, &30 - = &0C, &18, &30, &60, &30, &18, &0C, &00 - = &00, &00, &7E, &00, &7E, &00, &00, &00 - = &30, &18, &0C, &06, &0C, &18, &30, &00 - = &3C, &66, &0C, &18, &18, &00, &18, &00 - = &3C, &66, &6E, &6A, &6E, &60, &3C, &00 - = &3C, &66, &66, &7E, &66, &66, &66, &00 - = &7C, &66, &66, &7C, &66, &66, &7C, &00 - = &3C, &66, &60, &60, &60, &66, &3C, &00 - = &78, &6C, &66, &66, &66, &6C, &78, &00 - = &7E, &60, &60, &7C, &60, &60, &7E, &00 - = &7E, &60, &60, &7C, &60, &60, &60, &00 - = &3C, &66, &60, &6E, &66, &66, &3C, &00 - = &66, &66, &66, &7E, &66, &66, &66, &00 - = &7E, &18, &18, &18, &18, &18, &7E, &00 - = &3E, &0C, &0C, &0C, &0C, &6C, &38, &00 - = &66, &6C, &78, &70, &78, &6C, &66, &00 - = &60, &60, &60, &60, &60, &60, &7E, &00 - = &63, &77, &7F, &6B, &6B, &63, &63, &00 - = &66, &66, &76, &7E, &6E, &66, &66, &00 - = &3C, &66, &66, &66, &66, &66, &3C, &00 - = &7C, &66, &66, &7C, &60, &60, &60, &00 - = &3C, &66, &66, &66, &6A, &6C, &36, &00 - = &7C, &66, &66, &7C, &6C, &66, &66, &00 - = &3C, &66, &60, &3C, &06, &66, &3C, &00 - = &7E, &18, &18, &18, &18, &18, &18, &00 - = &66, &66, &66, &66, &66, &66, &3C, &00 - = &66, &66, &66, &66, &66, &3C, &18, &00 - = &63, &63, &6B, &6B, &7F, &77, &63, &00 - = &66, &66, &3C, &18, &3C, &66, &66, &00 - = &66, &66, &66, &3C, &18, &18, &18, &00 - = &7E, &06, &0C, &18, &30, &60, &7E, &00 - = &7C, &60, &60, &60, &60, &60, &7C, &00 - = &00, &60, &30, &18, &0C, &06, &00, &00 - = &3E, &06, &06, &06, &06, &06, &3E, &00 - = &18, &3C, &66, &42, &00, &00, &00, &00 - = &00, &00, &00, &00, &00, &00, &00, &FF - = &1C, &36, &30, &7C, &30, &30, &7E, &00 - = &00, &00, &3C, &06, &3E, &66, &3E, &00 - = &60, &60, &7C, &66, &66, &66, &7C, &00 - = &00, &00, &3C, &66, &60, &66, &3C, &00 - = &06, &06, &3E, &66, &66, &66, &3E, &00 - = &00, &00, &3C, &66, &7E, &60, &3C, &00 - = &1C, &30, &30, &7C, &30, &30, &30, &00 - = &00, &00, &3E, &66, &66, &3E, &06, &3C - = &60, &60, &7C, &66, &66, &66, &66, &00 - = &18, &00, &38, &18, &18, &18, &3C, &00 - = &18, &00, &38, &18, &18, &18, &18, &70 - = &60, &60, &66, &6C, &78, &6C, &66, &00 - = &38, &18, &18, &18, &18, &18, &3C, &00 - = &00, &00, &36, &7F, &6B, &6B, &63, &00 - = &00, &00, &7C, &66, &66, &66, &66, &00 - = &00, &00, &3C, &66, &66, &66, &3C, &00 - = &00, &00, &7C, &66, &66, &7C, &60, &60 - = &00, &00, &3E, &66, &66, &3E, &06, &07 - = &00, &00, &6C, &76, &60, &60, &60, &00 - = &00, &00, &3E, &60, &3C, &06, &7C, &00 - = &30, &30, &7C, &30, &30, &30, &1C, &00 - = &00, &00, &66, &66, &66, &66, &3E, &00 - = &00, &00, &66, &66, &66, &3C, &18, &00 - = &00, &00, &63, &6B, &6B, &7F, &36, &00 - = &00, &00, &66, &3C, &18, &3C, &66, &00 - = &00, &00, &66, &66, &66, &3E, &06, &3C - = &00, &00, &7E, &0C, &18, &30, &7E, &00 - = &0C, &18, &18, &70, &18, &18, &0C, &00 - = &18, &18, &18, &00, &18, &18, &18, &00 - = &30, &18, &18, &0E, &18, &18, &30, &00 - = &31, &6B, &46, &00, &00, &00, &00, &00 - = &FF, &FF, &FF, &FF, &FF, &FF, &FF, &FF - = &66, &00, &3C, &66, &7E, &66, &66, &00 - = &3C, &66, &3C, &66, &7E, &66, &66, &00 - = &3F, &66, &66, &7F, &66, &66, &67, &00 - = &3C, &66, &60, &60, &60, &66, &3C, &60 - = &0C, &18, &7E, &60, &7C, &60, &7E, &00 - = &66, &3C, &66, &66, &66, &66, &3C, &00 - = &66, &00, &66, &66, &66, &66, &3C, &00 - = &7E, &C3, &9D, &B1, &9D, &C3, &7E, &00 - = &00, &18, &38, &7F, &38, &18, &00, &00 - = &00, &18, &1C, &FE, &1C, &18, &00, &00 - = &18, &18, &18, &18, &7E, &3C, &18, &00 - = &00, &18, &3C, &7E, &18, &18, &18, &18 - = &30, &18, &3C, &06, &3E, &66, &3E, &00 - = &30, &18, &3C, &66, &7E, &60, &3C, &00 - = &66, &00, &3C, &66, &7E, &60, &3C, &00 - = &3C, &66, &3C, &66, &7E, &60, &3C, &00 - = &66, &00, &3C, &06, &3E, &66, &3E, &00 - = &3C, &66, &3C, &06, &3E, &66, &3E, &00 - = &00, &00, &3F, &0D, &3F, &6C, &3F, &00 - = &00, &00, &3C, &66, &60, &66, &3C, &60 - = &0C, &18, &3C, &66, &7E, &60, &3C, &00 - = &66, &00, &3C, &66, &66, &66, &3C, &00 - = &66, &00, &66, &66, &66, &66, &3E, &00 - = &30, &18, &00, &38, &18, &18, &3C, &00 - = &3C, &66, &00, &38, &18, &18, &3C, &00 - = &30, &18, &00, &3C, &66, &66, &3C, &00 - = &3C, &66, &00, &3C, &66, &66, &3C, &00 - = &30, &18, &00, &66, &66, &66, &3E, &00 - = &3C, &66, &00, &66, &66, &66, &3E, &00 - = &66, &00, &66, &66, &66, &3E, &06, &3C - = &00, &66, &3C, &66, &66, &3C, &66, &00 - = &3C, &60, &3C, &66, &3C, &06, &3C, &00 - = &3C, &66, &3C, &00, &00, &00, &00, &00 - = &00, &00, &00, &18, &18, &18, &18, &18 - = &00, &00, &00, &1F, &00, &00, &00, &00 - = &00, &00, &00, &1F, &18, &18, &18, &18 - = &00, &00, &00, &F8, &00, &00, &00, &00 - = &00, &00, &00, &F8, &18, &18, &18, &18 - = &00, &00, &00, &FF, &00, &00, &00, &00 - = &00, &00, &00, &FF, &18, &18, &18, &18 - = &18, &18, &18, &18, &00, &00, &00, &00 - = &18, &18, &18, &18, &18, &18, &18, &18 - = &18, &18, &18, &1F, &00, &00, &00, &00 - = &18, &18, &18, &1F, &18, &18, &18, &18 - = &18, &18, &18, &F8, &00, &00, &00, &00 - = &18, &18, &18, &F8, &18, &18, &18, &18 - = &18, &18, &18, &FF, &00, &00, &00, &00 - = &18, &18, &18, &FF, &18, &18, &18, &18 - = &00, &00, &00, &07, &0C, &18, &18, &18 - = &00, &00, &00, &E0, &30, &18, &18, &18 - = &18, &18, &0C, &07, &00, &00, &00, &00 - = &18, &18, &30, &E0, &00, &00, &00, &00 - = &18, &00, &18, &18, &30, &66, &3C, &00 - = &18, &00, &18, &18, &18, &18, &18, &00 - = &36, &6C, &00, &66, &76, &6E, &66, &00 - = &36, &6C, &00, &7C, &66, &66, &66, &00 - = &18, &7E, &18, &18, &18, &18, &18, &00 - = &18, &7E, &18, &18, &18, &7E, &18, &00 - = &18, &18, &18, &00, &00, &00, &00, &00 - = &30, &18, &0C, &00, &00, &00, &00, &00 - = &3F, &7B, &7B, &3B, &1B, &1B, &1F, &00 - = &00, &00, &00, &18, &18, &00, &00, &00 - = &03, &03, &06, &06, &76, &1C, &0C, &00 - = &AA, &55, &AA, &55, &AA, &55, &AA, &55 - = &3E, &63, &67, &6B, &73, &63, &3E, &00 - = &1C, &36, &63, &63, &7F, &63, &63, &00 - = &7E, &33, &33, &3E, &33, &33, &7E, &00 - = &7F, &63, &60, &60, &60, &60, &60, &00 - = &1C, &1C, &36, &36, &63, &63, &7F, &00 - = &7F, &33, &30, &3E, &30, &33, &7F, &00 - = &7E, &66, &0C, &18, &30, &66, &7E, &00 - = &77, &33, &33, &3F, &33, &33, &77, &00 - = &3E, &63, &63, &7F, &63, &63, &3E, &00 - = &3C, &18, &18, &18, &18, &18, &3C, &00 - = &63, &66, &6C, &78, &6C, &66, &63, &00 - = &1C, &1C, &36, &36, &63, &63, &63, &00 - = &63, &77, &7F, &6B, &63, &63, &63, &00 - = &63, &73, &7B, &6F, &67, &63, &63, &00 - = &7E, &00, &00, &3C, &00, &00, &7E, &00 - = &3E, &63, &63, &63, &63, &63, &3E, &00 - = &7F, &36, &36, &36, &36, &36, &36, &00 - = &7E, &33, &33, &3E, &30, &30, &78, &00 - = &7F, &63, &30, &18, &30, &63, &7F, &00 - = &7E, &5A, &18, &18, &18, &18, &18, &00 - = &66, &66, &66, &3C, &18, &18, &3C, &00 - = &3E, &08, &3E, &6B, &3E, &08, &3E, &00 - = &63, &63, &36, &1C, &36, &63, &63, &00 - = &3E, &08, &6B, &6B, &3E, &08, &3E, &00 - = &3E, &63, &63, &63, &36, &36, &63, &00 - = &7F, &63, &63, &36, &36, &1C, &1C, &00 - = &18, &18, &7E, &18, &18, &00, &7E, &00 - = &00, &7E, &00, &18, &18, &7E, &18, &18 - = &18, &18, &18, &18, &18, &18, &18, &00 - = &36, &36, &36, &36, &36, &36, &36, &00 - = &00, &66, &66, &66, &66, &66, &3C, &00 - = &00, &3C, &66, &66, &66, &66, &66, &00 - = &00, &03, &3E, &67, &6B, &73, &3E, &60 - = &00, &00, &3B, &6E, &66, &6E, &3B, &00 - = &1E, &33, &33, &3E, &33, &33, &3E, &60 - = &00, &00, &66, &36, &1C, &18, &30, &30 - = &3C, &60, &30, &3C, &66, &66, &3C, &00 - = &00, &00, &1E, &30, &1C, &30, &1E, &00 - = &3E, &0C, &18, &30, &60, &60, &3E, &06 - = &00, &00, &7C, &66, &66, &66, &06, &06 - = &3C, &66, &66, &7E, &66, &66, &3C, &00 - = &00, &00, &18, &18, &18, &18, &0C, &00 - = &00, &00, &66, &6C, &78, &6C, &66, &00 - = &60, &30, &18, &1C, &36, &63, &63, &00 - = &00, &00, &33, &33, &33, &33, &3E, &60 - = &00, &00, &63, &33, &1B, &1E, &1C, &00 - = &3C, &60, &60, &3C, &60, &60, &3E, &06 - = &00, &00, &3E, &63, &63, &63, &3E, &00 - = &00, &00, &7F, &36, &36, &36, &36, &00 - = &00, &00, &3C, &66, &66, &7C, &60, &60 - = &00, &00, &3F, &66, &66, &66, &3C, &00 - = &00, &00, &7E, &18, &18, &18, &0C, &00 - = &00, &00, &73, &33, &33, &33, &1E, &00 - = &00, &00, &3E, &6B, &6B, &3E, &18, &18 - = &00, &00, &66, &36, &1C, &1C, &36, &33 - = &00, &00, &63, &6B, &6B, &3E, &18, &18 - = &00, &00, &36, &63, &6B, &7F, &36, &00 - = &38, &0C, &06, &3E, &66, &66, &3C, &00 - = &00, &31, &6B, &46, &00, &7F, &00, &00 - = &00, &7E, &00, &7E, &00, &7E, &00, &00 - = &07, &1C, &70, &1C, &07, &00, &7F, &00 - = &06, &0C, &7E, &18, &7E, &30, &60, &00 - = &70, &1C, &07, &1C, &70, &00, &7F, &00 - = &FF, &FF, &FF, &FF, &FF, &FF, &FF, &FF - - END diff --git a/s/vdu/vdufontl1 b/s/vdu/vdufontl1 deleted file mode 100644 index f4c6ba12..00000000 --- a/s/vdu/vdufontl1 +++ /dev/null @@ -1,247 +0,0 @@ -; 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.VduFontL1 - -; KJB 990917 - definitions updated from International 1.54 - -HardFont - = &00,&00,&00,&00,&00,&00,&00,&00 ;ISO "space" - = &18,&18,&18,&18,&18,&00,&18,&00 ;ISO "exclamation mark" - = &6C,&6C,&6C,&00,&00,&00,&00,&00 ;ISO "quotation mark" - = &36,&36,&7F,&36,&7F,&36,&36,&00 ;ISO "number sign" - = &0C,&3F,&68,&3E,&0B,&7E,&18,&00 ;ISO "dollar sign" - = &60,&66,&0C,&18,&30,&66,&06,&00 ;ISO "percent sign" - = &38,&6C,&6C,&38,&6D,&66,&3B,&00 ;ISO "ampersand" - = &18,&18,&18,&00,&00,&00,&00,&00 ;ISO "apostrophe" (vertical) - = &0C,&18,&30,&30,&30,&18,&0C,&00 ;ISO "left parenthesis" - = &30,&18,&0C,&0C,&0C,&18,&30,&00 ;ISO "right parenthesis" - = &00,&18,&7E,&3C,&7E,&18,&00,&00 ;ISO "asterisk" - = &00,&18,&18,&7E,&18,&18,&00,&00 ;ISO "plus sign" - = &00,&00,&00,&00,&00,&18,&18,&30 ;ISO "comma" - = &00,&00,&00,&7E,&00,&00,&00,&00 ;ISO "hyphen-minus" - = &00,&00,&00,&00,&00,&18,&18,&00 ;ISO "full stop" - = &00,&06,&0C,&18,&30,&60,&00,&00 ;ISO "solidus" - = &3C,&66,&6E,&7E,&76,&66,&3C,&00 ;ISO "digit zero" - = &18,&38,&18,&18,&18,&18,&7E,&00 ;ISO "digit one" - = &3C,&66,&06,&0C,&18,&30,&7E,&00 ;ISO "digit two" - = &3C,&66,&06,&1C,&06,&66,&3C,&00 ;ISO "digit three" - = &0C,&1C,&3C,&6C,&7E,&0C,&0C,&00 ;ISO "digit four" - = &7E,&60,&7C,&06,&06,&66,&3C,&00 ;ISO "digit five" - = &1C,&30,&60,&7C,&66,&66,&3C,&00 ;ISO "digit six" - = &7E,&06,&0C,&18,&30,&30,&30,&00 ;ISO "digit seven" - = &3C,&66,&66,&3C,&66,&66,&3C,&00 ;ISO "digit eight" - = &3C,&66,&66,&3E,&06,&0C,&38,&00 ;ISO "digit nine" - = &00,&00,&18,&18,&00,&18,&18,&00 ;ISO "colon" - = &00,&00,&18,&18,&00,&18,&18,&30 ;ISO "semicolon" - = &0C,&18,&30,&60,&30,&18,&0C,&00 ;ISO "less-than sign" - = &00,&00,&7E,&00,&7E,&00,&00,&00 ;ISO "equals sign" - = &30,&18,&0C,&06,&0C,&18,&30,&00 ;ISO "greater-than sign" - = &3C,&66,&0C,&18,&18,&00,&18,&00 ;ISO "question mark" - = &3C,&66,&6E,&6A,&6E,&60,&3C,&00 ;ISO "commercial at" - = &3C,&66,&66,&7E,&66,&66,&66,&00 ;ISO "Latin capital letter A" - = &7C,&66,&66,&7C,&66,&66,&7C,&00 ;ISO "Latin capital letter B" - = &3C,&66,&60,&60,&60,&66,&3C,&00 ;ISO "Latin capital letter C" - = &78,&6C,&66,&66,&66,&6C,&78,&00 ;ISO "Latin capital letter D" - = &7E,&60,&60,&7C,&60,&60,&7E,&00 ;ISO "Latin capital letter E" - = &7E,&60,&60,&7C,&60,&60,&60,&00 ;ISO "Latin capital letter F" - = &3C,&66,&60,&6E,&66,&66,&3C,&00 ;ISO "Latin capital letter G" - = &66,&66,&66,&7E,&66,&66,&66,&00 ;ISO "Latin capital letter H" - = &7E,&18,&18,&18,&18,&18,&7E,&00 ;ISO "Latin capital letter I" - = &3E,&0C,&0C,&0C,&0C,&6C,&38,&00 ;ISO "Latin capital letter J" - = &66,&6C,&78,&70,&78,&6C,&66,&00 ;ISO "Latin capital letter K" - = &60,&60,&60,&60,&60,&60,&7E,&00 ;ISO "Latin capital letter L" - = &63,&77,&7F,&6B,&6B,&63,&63,&00 ;ISO "Latin capital letter M" - = &66,&66,&76,&7E,&6E,&66,&66,&00 ;ISO "Latin capital letter N" - = &3C,&66,&66,&66,&66,&66,&3C,&00 ;ISO "Latin capital letter O" - = &7C,&66,&66,&7C,&60,&60,&60,&00 ;ISO "Latin capital letter P" - = &3C,&66,&66,&66,&6A,&6C,&36,&00 ;ISO "Latin capital letter Q" - = &7C,&66,&66,&7C,&6C,&66,&66,&00 ;ISO "Latin capital letter R" - = &3C,&66,&60,&3C,&06,&66,&3C,&00 ;ISO "Latin capital letter S" - = &7E,&18,&18,&18,&18,&18,&18,&00 ;ISO "Latin capital letter T" - = &66,&66,&66,&66,&66,&66,&3C,&00 ;ISO "Latin capital letter U" - = &66,&66,&66,&66,&66,&3C,&18,&00 ;ISO "Latin capital letter V" - = &63,&63,&6B,&6B,&7F,&77,&63,&00 ;ISO "Latin capital letter W" - = &66,&66,&3C,&18,&3C,&66,&66,&00 ;ISO "Latin capital letter X" - = &66,&66,&66,&3C,&18,&18,&18,&00 ;ISO "Latin capital letter Y" - = &7E,&06,&0C,&18,&30,&60,&7E,&00 ;ISO "Latin capital letter Z" - = &7C,&60,&60,&60,&60,&60,&7C,&00 ;ISO "left square bracket" - = &00,&60,&30,&18,&0C,&06,&00,&00 ;ISO "reverse solidus" - = &3E,&06,&06,&06,&06,&06,&3E,&00 ;ISO "right square bracket" - = &3C,&66,&00,&00,&00,&00,&00,&00 ;ISO "circumflex accent" - = &00,&00,&00,&00,&00,&00,&00,&FF ;ISO "low line" - = &30,&18,&00,&00,&00,&00,&00,&00 ;ISO "grave accent" - = &00,&00,&3C,&06,&3E,&66,&3E,&00 ;ISO "Latin small letter a" - = &60,&60,&7C,&66,&66,&66,&7C,&00 ;ISO "Latin small letter b" - = &00,&00,&3C,&66,&60,&66,&3C,&00 ;ISO "Latin small letter c" - = &06,&06,&3E,&66,&66,&66,&3E,&00 ;ISO "Latin small letter d" - = &00,&00,&3C,&66,&7E,&60,&3C,&00 ;ISO "Latin small letter e" - = &1C,&30,&30,&7C,&30,&30,&30,&00 ;ISO "Latin small letter f" - = &00,&00,&3E,&66,&66,&3E,&06,&3C ;ISO "Latin small letter g" - = &60,&60,&7C,&66,&66,&66,&66,&00 ;ISO "Latin small letter h" - = &18,&00,&38,&18,&18,&18,&3C,&00 ;ISO "Latin small letter i" - = &18,&00,&38,&18,&18,&18,&18,&70 ;ISO "Latin small letter j" - = &60,&60,&66,&6C,&78,&6C,&66,&00 ;ISO "Latin small letter k" - = &38,&18,&18,&18,&18,&18,&3C,&00 ;ISO "Latin small letter l" - = &00,&00,&36,&7F,&6B,&6B,&63,&00 ;ISO "Latin small letter m" - = &00,&00,&7C,&66,&66,&66,&66,&00 ;ISO "Latin small letter n" - = &00,&00,&3C,&66,&66,&66,&3C,&00 ;ISO "Latin small letter o" - = &00,&00,&7C,&66,&66,&7C,&60,&60 ;ISO "Latin small letter p" - = &00,&00,&3E,&66,&66,&3E,&06,&07 ;ISO "Latin small letter q" - = &00,&00,&6C,&76,&60,&60,&60,&00 ;ISO "Latin small letter r" - = &00,&00,&3E,&60,&3C,&06,&7C,&00 ;ISO "Latin small letter s" - = &30,&30,&7C,&30,&30,&30,&1C,&00 ;ISO "Latin small letter t" - = &00,&00,&66,&66,&66,&66,&3E,&00 ;ISO "Latin small letter u" - = &00,&00,&66,&66,&66,&3C,&18,&00 ;ISO "Latin small letter v" - = &00,&00,&63,&6B,&6B,&7F,&36,&00 ;ISO "Latin small letter w" - = &00,&00,&66,&3C,&18,&3C,&66,&00 ;ISO "Latin small letter x" - = &00,&00,&66,&66,&66,&3E,&06,&3C ;ISO "Latin small letter y" - = &00,&00,&7E,&0C,&18,&30,&7E,&00 ;ISO "Latin small letter z" - = &0C,&18,&18,&70,&18,&18,&0C,&00 ;ISO "left curly bracket" - = &18,&18,&18,&18,&18,&18,&18,&00 ;ISO "vertical line" - = &30,&18,&18,&0E,&18,&18,&30,&00 ;ISO "right curly bracket" - = &31,&6B,&46,&00,&00,&00,&00,&00 ;ISO "tilde" - = &FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF ;BFNT "Solid block" - = &3C,&66,&60,&F8,&60,&66,&3C,&00 ;ISO "euro sign" - = &1C,&36,&00,&63,&6B,&7F,&63,&00 ;ISO "Latin capital letter W with circumflex" - = &1C,&36,&00,&6B,&6B,&7F,&36,&00 ;ISO "Latin small letter w with circumflex" - = &06,&01,&06,&61,&96,&60,&90,&60 ; "83" - = &05,&05,&07,&61,&91,&60,&90,&60 ; "84" - = &3C,&66,&00,&66,&3C,&18,&18,&00 ;ISO "Latin capital letter Y with circumflex" - = &3C,&66,&00,&66,&66,&3E,&06,&3C ;ISO "Latin small letter y with circumflex" - = &07,&01,&02,&64,&94,&60,&90,&60 ; "87" - = &06,&09,&06,&69,&96,&60,&90,&60 ; "88" - = &06,&09,&07,&61,&96,&60,&90,&60 ; "89" - = &06,&09,&0F,&69,&99,&60,&90,&60 ; "8A" - = &0E,&09,&0E,&69,&9E,&60,&90,&60 ; "8B" - = &00,&00,&00,&00,&00,&DB,&DB,&00 ;ISO "horizontal ellipsis" - = &F1,&5B,&55,&51,&00,&00,&00,&00 ;ISO "trade mark sign" - = &C0,&CC,&18,&30,&60,&DB,&1B,&00 ;ISO "per mille sign" - = &00,&00,&3C,&7E,&7E,&3C,&00,&00 ;ISO "bullet" - = &0C,&18,&18,&00,&00,&00,&00,&00 ;ISO "left single quotation mark" - = &0C,&0C,&18,&00,&00,&00,&00,&00 ;ISO "right single quotation mark" - = &00,&0C,&18,&30,&30,&18,&0C,&00 ;ISO "single left-pointing angle quotation mark" - = &00,&30,&18,&0C,&0C,&18,&30,&00 ;ISO "single right-pointing angle quotation mark" - = &1B,&36,&36,&00,&00,&00,&00,&00 ;ISO "left double quotation mark" - = &36,&36,&6C,&00,&00,&00,&00,&00 ;ISO "right double quotation mark" - = &00,&00,&00,&00,&00,&36,&36,&6C ;ISO "double low-9 quotation mark" - = &00,&00,&00,&3C,&00,&00,&00,&00 ;ISO "en dash" - = &00,&00,&00,&FF,&00,&00,&00,&00 ;ISO "em dash" - = &00,&00,&00,&7E,&00,&00,&00,&00 ;ISO "minus sign" - = &77,&CC,&CC,&CF,&CC,&CC,&77,&00 ;ISO "Latin capital ligature OE" - = &00,&00,&6E,&DB,&DF,&D8,&6E,&00 ;ISO "Latin small ligature oe" - = &18,&18,&7E,&18,&18,&18,&18,&18 ;ISO "dagger" - = &18,&18,&7E,&18,&7E,&18,&18,&18 ;ISO "double dagger" - = &3C,&66,&60,&F6,&66,&66,&66,&00 ;ISO "Latin small ligature fi" - = &3E,&66,&66,&F6,&66,&66,&66,&00 ;ISO "Latin small ligature fl" - = &00,&00,&00,&00,&00,&00,&00,&00 ;ISO "no-break space" - = &18,&00,&18,&18,&18,&18,&18,&00 ;ISO "inverted exclamation mark" - = &08,&3E,&6B,&68,&6B,&3E,&08,&00 ;ISO "cent sign" - = &1C,&36,&30,&7C,&30,&30,&7E,&00 ;ISO "pound sign" - = &00,&66,&3C,&66,&66,&3C,&66,&00 ;ISO "currency sign" - = &66,&3C,&18,&18,&7E,&18,&18,&00 ;ISO "yen sign" - = &18,&18,&18,&00,&18,&18,&18,&00 ;ISO "broken bar" - = &3C,&60,&3C,&66,&3C,&06,&3C,&00 ;ISO "section sign" - = &66,&00,&00,&00,&00,&00,&00,&00 ;ISO "diaeresis" - = &3C,&42,&99,&A1,&A1,&99,&42,&3C ;ISO "copyright sign" - = &1C,&06,&1E,&36,&1E,&00,&3E,&00 ;ISO "feminine ordinal indicator" - = &00,&33,&66,&CC,&CC,&66,&33,&00 ;ISO "left-pointing double angle quotation mark" - = &7E,&06,&00,&00,&00,&00,&00,&00 ;ISO "not sign" - = &00,&00,&00,&7E,&00,&00,&00,&00 ;ISO "soft hyphen" - = &3C,&42,&B9,&A5,&B9,&A5,&42,&3C ;ISO "registered sign" - = &7E,&00,&00,&00,&00,&00,&00,&00 ;ISO "macron" - = &3C,&66,&3C,&00,&00,&00,&00,&00 ;ISO "degree sign" - = &18,&18,&7E,&18,&18,&00,&7E,&00 ;ISO "plus-minus sign" - = &38,&04,&18,&20,&3C,&00,&00,&00 ;ISO "superscript two" - = &38,&04,&18,&04,&38,&00,&00,&00 ;ISO "superscript three" - = &0C,&18,&00,&00,&00,&00,&00,&00 ;ISO "acute accent" - = &00,&00,&33,&33,&33,&33,&3E,&60 ;ISO "micro sign" - = &03,&3E,&76,&76,&36,&36,&3E,&00 ;ISO "pilcrow sign" - = &00,&00,&00,&18,&18,&00,&00,&00 ;ISO "middle dot" - = &00,&00,&00,&00,&00,&00,&18,&30 ;ISO "cedilla" - = &10,&30,&10,&10,&38,&00,&00,&00 ;ISO "superscript one" - = &1C,&36,&36,&36,&1C,&00,&3E,&00 ;ISO "masculine ordinal indicator" - = &00,&CC,&66,&33,&33,&66,&CC,&00 ;ISO "right-pointing double angle quotation mark" - = &40,&C0,&40,&48,&48,&0A,&0F,&02 ;ISO "vulgar fraction one quarter" - = &40,&C0,&40,&4F,&41,&0F,&08,&0F ;ISO "vulgar fraction one half" - = &E0,&20,&E0,&28,&E8,&0A,&0F,&02 ;ISO "vulgar fraction three quarters" - = &18,&00,&18,&18,&30,&66,&3C,&00 ;ISO "inverted question mark" - = &30,&18,&3C,&66,&7E,&66,&66,&00 ;ISO "Latin capital letter A with grave" - = &0C,&18,&3C,&66,&7E,&66,&66,&00 ;ISO "Latin capital letter A with acute" - = &18,&66,&3C,&66,&7E,&66,&66,&00 ;ISO "Latin capital letter A with circumflex" - = &36,&6C,&3C,&66,&7E,&66,&66,&00 ;ISO "Latin capital letter A with tilde" - = &66,&00,&3C,&66,&7E,&66,&66,&00 ;ISO "Latin capital letter A with diaeresis" - = &3C,&66,&3C,&66,&7E,&66,&66,&00 ;ISO "Latin capital letter A with ring above" - = &3F,&66,&66,&7F,&66,&66,&67,&00 ;ISO "Latin capital letter AE (ash)" - = &3C,&66,&60,&60,&60,&66,&3C,&60 ;ISO "Latin capital letter C with cedilla" - = &30,&18,&7E,&60,&7C,&60,&7E,&00 ;ISO "Latin capital letter E with grave" - = &0C,&18,&7E,&60,&7C,&60,&7E,&00 ;ISO "Latin capital letter E with acute" - = &3C,&66,&7E,&60,&7C,&60,&7E,&00 ;ISO "Latin capital letter E with circumflex" - = &66,&00,&7E,&60,&7C,&60,&7E,&00 ;ISO "Latin capital letter E with diaeresis" - = &30,&18,&7E,&18,&18,&18,&7E,&00 ;ISO "Latin capital letter I with grave" - = &0C,&18,&7E,&18,&18,&18,&7E,&00 ;ISO "Latin capital letter I with acute" - = &3C,&66,&7E,&18,&18,&18,&7E,&00 ;ISO "Latin capital letter I with circumflex" - = &66,&00,&7E,&18,&18,&18,&7E,&00 ;ISO "Latin capital letter I with diaeresis" - = &78,&6C,&66,&F6,&66,&6C,&78,&00 ;ISO "Latin capital letter ETH" - = &36,&6C,&66,&76,&7E,&6E,&66,&00 ;ISO "Latin capital letter N with tilde" - = &30,&18,&3C,&66,&66,&66,&3C,&00 ;ISO "Latin capital letter O with grave" - = &0C,&18,&3C,&66,&66,&66,&3C,&00 ;ISO "Latin capital letter O with acute" - = &18,&66,&3C,&66,&66,&66,&3C,&00 ;ISO "Latin capital letter O with circumflex" - = &36,&6C,&3C,&66,&66,&66,&3C,&00 ;ISO "Latin capital letter O with tilde" - = &66,&00,&3C,&66,&66,&66,&3C,&00 ;ISO "Latin capital letter O with diaeresis" - = &00,&63,&36,&1C,&1C,&36,&63,&00 ;ISO "multiply sign" - = &3D,&66,&6E,&7E,&76,&66,&BC,&00 ;ISO "Latin capital letter O with slash" - = &30,&18,&66,&66,&66,&66,&3C,&00 ;ISO "Latin capital letter U with grave" - = &0C,&18,&66,&66,&66,&66,&3C,&00 ;ISO "Latin capital letter U with acute" - = &3C,&66,&00,&66,&66,&66,&3C,&00 ;ISO "Latin capital letter U with circumflex" - = &66,&00,&66,&66,&66,&66,&3C,&00 ;ISO "Latin capital letter U with diaeresis" - = &0C,&18,&66,&66,&3C,&18,&18,&00 ;ISO "Latin capital letter Y with acute" - = &F0,&60,&7C,&66,&7C,&60,&F0,&00 ;ISO "Latin capital letter THORN" - = &3C,&66,&66,&6C,&66,&66,&6C,&C0 ;ISO "Latin small letter sharp s" - = &30,&18,&3C,&06,&3E,&66,&3E,&00 ;ISO "Latin small letter a with grave" - = &0C,&18,&3C,&06,&3E,&66,&3E,&00 ;ISO "Latin small letter a with acute" - = &18,&66,&3C,&06,&3E,&66,&3E,&00 ;ISO "Latin small letter a with circumflex" - = &36,&6C,&3C,&06,&3E,&66,&3E,&00 ;ISO "Latin small letter a with tilde" - = &66,&00,&3C,&06,&3E,&66,&3E,&00 ;ISO "Latin small letter a with diaeresis" - = &3C,&66,&3C,&06,&3E,&66,&3E,&00 ;ISO "Latin small letter a with ring above" - = &00,&00,&3F,&0D,&3F,&6C,&3F,&00 ;ISO "Latin small letter ae (ash)" - = &00,&00,&3C,&66,&60,&66,&3C,&60 ;ISO "Latin small letter c with cedilla" - = &30,&18,&3C,&66,&7E,&60,&3C,&00 ;ISO "Latin small letter e with grave" - = &0C,&18,&3C,&66,&7E,&60,&3C,&00 ;ISO "Latin small letter e with acute" - = &3C,&66,&3C,&66,&7E,&60,&3C,&00 ;ISO "Latin small letter e with cirumflex" - = &66,&00,&3C,&66,&7E,&60,&3C,&00 ;ISO "Latin small letter e with diaeresis" - = &30,&18,&00,&38,&18,&18,&3C,&00 ;ISO "Latin small letter i with grave" - = &0C,&18,&00,&38,&18,&18,&3C,&00 ;ISO "Latin small letter i with acute" - = &3C,&66,&00,&38,&18,&18,&3C,&00 ;ISO "Latin small letter i with circumflex" - = &66,&00,&38,&18,&18,&18,&3C,&00 ;ISO "Latin small letter i with diaeresis" - = &18,&3E,&0C,&06,&3E,&66,&3E,&00 ;ISO "Latin small letter eth" - = &36,&6C,&00,&7C,&66,&66,&66,&00 ;ISO "Latin small letter n with tilde" - = &30,&18,&00,&3C,&66,&66,&3C,&00 ;ISO "Latin small letter o with grave" - = &0C,&18,&00,&3C,&66,&66,&3C,&00 ;ISO "Latin small letter o with acute" - = &3C,&66,&00,&3C,&66,&66,&3C,&00 ;ISO "Latin small letter o with circumflex" - = &36,&6C,&00,&3C,&66,&66,&3C,&00 ;ISO "Latin small letter o with tilde" - = &66,&00,&00,&3C,&66,&66,&3C,&00 ;ISO "Latin small letter o with diaeresis" - = &00,&18,&00,&FF,&00,&18,&00,&00 ;ISO "divide sign" - = &00,&02,&3C,&6E,&76,&66,&BC,&00 ;ISO "Latin small letter o with slash" - = &30,&18,&66,&66,&66,&66,&3E,&00 ;ISO "Latin small letter u with grave" - = &0C,&18,&66,&66,&66,&66,&3E,&00 ;ISO "Latin small letter u with acute" - = &3C,&66,&00,&66,&66,&66,&3E,&00 ;ISO "Latin small letter u with circumflex" - = &66,&00,&66,&66,&66,&66,&3E,&00 ;ISO "Latin small letter u with diaeresis" - = &0C,&18,&66,&66,&66,&3E,&06,&3C ;ISO "Latin small letter y with acute" - = &60,&60,&7C,&66,&7C,&60,&60,&00 ;ISO "Latin small letter thorn" - = &66,&00,&66,&66,&66,&3E,&06,&3C ;ISO "Latin small letter y with diaeresis" - - ASSERT (.-HardFont)=(256-32)*8 - - END diff --git a/s/vdu/vdugrafa b/s/vdu/vdugrafa deleted file mode 100644 index 82da602f..00000000 --- a/s/vdu/vdugrafa +++ /dev/null @@ -1,396 +0,0 @@ -; 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.VduGrafA -; -; ARTHUR OPERATING SYSTEM - Vdu Drivers -; ======================= -; -; Vdu driver code - Graphics rectangle, triangle -; -; Author R C Manby -; Date 5.9.86 -; - -; ***************************************************************************** -; -; GenLineParm - Generate a control block for a line -; -; Internal routine, called by TriangleFill, LowerTri, ParallelogramFill, -; SegmentLineO5, GenArcParmBlk, GenSegParmBlk, LineDraw -; -; in: R0 (X), R1(Y) hold start of line -; R2 (X), R3(Y) hold end of line -; -; out: R0..R6 hold the following control block -; R0 - StartX -; R1 - StartY -; R2 - Bres -; R3 - DeltaX -; R4 - DeltaY -; R5 - StepX (+1/-1) (Equv bit6 of Sign in 6502 version) -; R6 - StepY (+1/-1) (Equv bit7 of Sign in 6502 version) -; R7 - EndX -; R8 - EndY -; - -GenLineParm ROUT - MOV R7, R2 ; EndX,EndY - might be worth passing them - MOV R8, R3 ; in R7,R8 not R2,R3 - - SUB R3, R7, R0 ; Crude deltaX - SUB R4, R8, R1 ; Crude deltaY - - CMP R4, R3 - MOVLT R2, #0 ; if deltaY >= deltaX R2 := -1 - MOVGE R2, #-1 ; else R2 := 0 - ; this is used to fudge the bres - ; variable so lines of grad -1 are - ; the same as lines of grad 1 - - MOVS R5, R3, ASR #31 ; R5 := SGN(DeltaX) - MOVPL R5, #1 - RSBMI R3, R3, #0 ; DeltaX := ABS(DeltaX) - - MOVS R6, R4, ASR #31 ; R6 := SGN(DeltaY) - MOVPL R6, #1 - RSBMI R4, R4, #0 ; DeltaY := ABS(DeltaY) - - CMP R4, R3 ; Bres = MAX(DeltaX,DeltaY) + fudge factor - ADDPL R2, R4, R2 - ADDMI R2, R3, R2 - - RSB R2, R4, R2, ASR #1 ; Bres = Bres/2 - DeltaY - MOV PC, R14 ; Return - -; ***************************************************************************** -; -; AdvLineParm - Advance a set of line parameters -; -; Internal routine, called by TrapFill, SegLineStep, ArcLineStep, -; LineDraw, InYWind, InXWind -; -; in: R0..R6, (R7,R8) hold a line parameter block -; -; out: R0 (X), R1 (Y) R2 (Bres) updated -; -; Format of a control block -; R0 - StartX (CurrentX) -; R1 - StartY (CurrentY) -; R2 - Bres -; R3 - DeltaX -; R4 - DeltaY -; R5 - StepX (+1/-1) (Equv bit6 of Sign in 6502 version) -; R6 - StepY (+1/-1) (Equv bit7 of Sign in 6502 version) -; R7 - EndX (Not used in this routine, so) -; R8 - EndY (doesnt need to be passed in) -; - -AdvLineParm ROUT - CMP R2, #0 ; If Bres +ve, advance in X dirn only - ADDLT R1, R1, R6 ; Advance in Y dirn - ADDLTS R2, R2, R3 ; Add DeltaX to Bres - ; If new Bres +ve advance X as well - ; Advance X - SUBGE R2, R2, R4 ; Sub DeltaY from Bres to advance in X dirn - ADDGE R0, R0, R5 ; Add or subtract 1 dependent on sign DeltaX - MOV PC, R14 - -; ***************************************************************************** -; -; AdvLineParm_GE - Macro to advance line in XDirn if flags are GE -; -; Used by Triangles,Parallelograms,Arcs etc -; -; Use: CMP R2,#0 -; AdvLineParm_GE -; -; Instead of: CMP R2,#0 -; BLGE AdvLineParm -; - - MACRO - AdvLineParm_GE - SUBGE R2, R2, R4 - ADDGE R0, R0, R5 - MEND - -; ***************************************************************************** -; -; RectangleFill - Fill a rectangle -; -; External routine, and RectFillA entry point used by BlockCopyMove, CLG -; and RectFillB entry point used by PlotMask -; -; in: ICursor & NewPt mark a diagonal of the rectangle -; -; out: R0-R11 corrupt -; -; - -RectangleFill ROUT - ADD R11,WsPtr,#GCsIX ; load ICursor & NewPt - LDMIA R11, {R0-R3} -RectFillA - Push R14 -RectFillB - SortT R0, R2, R11 ; ensure R0 holds the lesser X value - SortT R3, R1, R11 ; ensure R1 holds the higher Y value - [ UseGraphicsV - BL CheckAcceleration - BNE RectFillC - -; try calling GraphicsV for some acceleration - -; R0 = left, R1 = top, R2 = right, R3 = bottom - - ADD R4, WsPtr, #GWLCol - LDMIA R4, {R4-R7} ; GWLCol,GWBRow,GWRCol,GWTRow - - CMP R6, R0 ; Test xcoords against window - CMPGE R2, R4 - CMPGE R7, R3 ; Test ycoords against window - CMPGE R1, R5 - MOVLT PC, R14 ; Quit if above,below,left or right - - Greatest R0, R0, R4 ; Clip all coords to window - Greatest R3, R3, R5 - Least R2, R2, R6 - Least R1, R1, R7 - - LDR R4, [WsPtr, #GColAdr] - Push "R0-R4" - MOV R0, #GVRender_Sync - MOV R1, #GVRender_FillRectangle - MOV R2, R13 - MOV R4, #GraphicsV_Render - BL CallGraphicsV - TEQ R4, #GraphicsV_Complete - Pull "R0-R4" - Pull PC, EQ - -; if it didn't claim, we proceed with the pre-clipped coordinates - - ] -RectFillC - MOV R11, R3 ; place end Y out of harm's way -10 - BL NewHLine - SUB R1, R1, #1 ; step Y down a line - CMP R1, R11 - BGE %BT10 - Pull PC - -; ***************************************************************************** -; -; TriangleFill - Triangular area fill -; -; External routine -; -; in: OldCs, ICursor & NewPt are verticies of the triangle -; -; out: R0-R11 corrupt -; - -TriangleFill ROUT - Push R14 - ADD R11, WsPtr, #OldCsX ; vertices are OldCs,ICursor - LDMIA R11, {R0-R5} ; and NewPt - BL LowerTri ; sort vertices and fill the - ; lower triangle - ADD R11, WsPtr, #Vertex2X ; restart TLine1 to run from - LDMIA R11, {R0-R3} ; Vertex2 to Vertex3 - ADD R11, WsPtr, #TLine1 -TriangleFil5 ; entry point from par fill - BL GenLineParm - STMIA R11, {R0-R8} ; initialise parameter block - STR R8, [WsPtr, #TEndY] ; end Y point for both lines - BL TrapFill ; fill the upper trapezoid - MOV R0, R9 ; fill top line LeftX,RightX - MOV R2, R10 ; leftY already in R1 - BL NewHLine - Pull PC - -; ***************************************************************************** -; -; LowerTri - Sort 3 vertices and fill the lower triangle between the -; points up to but excluding the horizontal through the middle point -; -; Internal routine, called by TriangleFill and ParallelogramFill -; - -LowerTri ROUT - Push R14 - CompSwapT R0,R1, R2,R3, R14 ; bubble highest vertex into R4,R5 - CompSwapT R2,R3 ,R4,R5, R14 - - CompSwapT R0,R1, R2,R3, R14 ; place lowest in R0,R1 and middle in R2,R3 - - ADD R11, WsPtr, #Vertex1X - STMIA R11, {R0-R7} ; save all our vertices - - MOV R9, R0 ; initalise TLeftX,TRightX - MOV R10, R0 ; to lowest point - BL GenLineParm ; Run TLine1 from lowest to - ADD R11, WsPtr, #TLine1 ; middle point - STMIA R11, {R0-R8} - STR R8, [WsPtr, #TEndY] ; this line ends first - - ADD R2, WsPtr, #Vertex3X ; run TLine2 from lowest to - LDMIA R2, {R2, R3} ; highest point - BL GenLineParm - ADD R11, WsPtr, #TLine2 - STMIA R11, {R0-R8} - BL TrapFill ; fill the lower trapezoid - - Pull PC - -; ***************************************************************************** -; -; ParallelogramFill - Fill a parallelogram -; -; External routine -; -; in: OldCs, ICursor & NewPt are 3 vertices of the parallelogram -; -; out: R0-R11 corrupt -; - -ParallelogramFill ROUT - Push R14 - ADD R11, WsPtr, #OldCsX ; vertices are OldCs,ICursor - LDMIA R11, {R0-R5} ; and NewPt - -; now calculate Vertex4 from other three - - ADD R6, R0, R4 ; Vertex4X := Vertex1X + Vertex3X - Vertex2X - SUB R6, R6, R2 - - ADD R7, R1, R5 ; Vertex4Y := Vertex1Y + Vertex3Y - Vertex2Y - SUB R7, R7, R3 - - CompSwapT R0,R1, R2,R3, R14 ; Bubble the highest point into R6,R7 - CompSwapT R2,R3 ,R4,R5, R14 - CompSwapT R4,R5 ,R6,R7, R14 - - BL LowerTri ; sort other vertices and draw lower triangle - - ADD R11, WsPtr, #Vertex2X ; restart TLine1 to run from - LDMIA R11!, {R0-R3} ; Vertex2 to Vertex4 - STR R3, [WsPtr, #TEndY] ; and indicate line Vertex1 to - LDMIA R11, {R2,R3} ; Vertex3 as the next to finish - - BL GenLineParm - ADD R11, WsPtr, #TLine1 - STMIA R11, {R0-R8} ; TLine1 parameter block - - BL TrapFill ; fill the middle trapezoid - - ADD R11, WsPtr, #Vertex3X ; restart TLine2 to run from - LDMIA R11, {R0-R3} ; Vertex3 to Vertex4 - ADD R11, WsPtr, #TLine2 - B TriangleFil5 ; Use common code with - ; triangles to initialise and - ; fill upper trapezoid - -; ***************************************************************************** -; -; TrapFill - Fill a trapezoid -; -; Internal routine, called by TriangleFill, LowerTri, ParallelogramFill -; -; in: R9 = TLeftX } the line limits for this scanline -; R10 = TRightX } -; -; out: R9,R10 updated -; - -TrapFill ROUT - Push R14 -10 - ADD R11, WsPtr, #TLine1 ; Advance TLine1 until currentY about - BL TrapLineStep ; to change, or end of line reached - - ADD R11, WsPtr, #TLine2 ; ditto TLine2 - BL TrapLineStep - - LDR R11, [WsPtr, #TEndY] - CMP R11, R1 ; if CurrentY = EndY - Pull PC, EQ ; then quit - - MOV R0, R9 ; LeftX - MOV R2, R10 ; RightX - ; LeftY already in R1 - BL NewHLine ; Plot current scanline - - ADD R11, WsPtr, #TLine1 ; advance TLine1 to next scanline - LDMIA R11, {R0-R6} - BL AdvLineParm - STMIA R11, {R0-R2} ; save the changes - - MOV R9, R0 ; assume currentX will be LeftX - - ADD R11, WsPtr, #TLine2 ; advance TLine2 to next scanline - LDMIA R11, {R0-R6} - BL AdvLineParm - STMIA R11, {R0-R2} ; save the changes - - CMP R0, R9 ; LeftX=Min(CurrentX,CurrentY) - MOVGE R10, R0 ; RightX=Max(CurrentX,CurrentY) - MOVLT R10, R9 - MOVLT R9, R0 - B %BT10 ; continue with next scanline - - -; ***************************************************************************** -; -; TrapLineStep - Step line parameters until CurrentY about to change -; or end of line reached - compares CurrentX with line limits -; (LeftX,RightX) and widens them if needed -; -; Internal routine, called by TrapFill -; -; in: R9 = LeftX -; R10 = RightX -; R11 = address of parameter block -; -; out: R0-R8 parameter block for this line -; R9, R10 updated -; R11 preserved -; - -TrapLineStep ROUT - Push R14 - LDMIA R11, {R0-R8} ; get line parameter block - CMP R8, R1 ; if on last scanline - MOVEQ R0, R7 ; then set currentX to EndX - BEQ TrapLin20 ; (bres unchanged, but who cares) - - CMP R2, #0 ; else While bres >= 0 do AdvLineParm -TrapLin10 ; {step until Y about to change} - ADDGE R0, R0, R5 - SUBGES R2, R2, R4 - BGE TrapLin10 - -TrapLin20 - STMIA R11, {R0-R2} ; update the changes to parameter block - CMP R0, R9 ; LeftX=Min(LeftX,CurrentX) - MOVLT R9, R0 - CMP R0, R10 - MOVGT R10, R0 ; RightX=Max(RightX,CurrentX) - Pull PC - - - - END diff --git a/s/vdu/vdugrafb b/s/vdu/vdugrafb deleted file mode 100644 index 45bf1c40..00000000 --- a/s/vdu/vdugrafb +++ /dev/null @@ -1,1120 +0,0 @@ -; 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.VduGrafB -; -; ARTHUR OPERATING SYSTEM - Vdu Drivers -; ======================= -; -; Vdu driver code - Graphics circle outline, fill, arc, sector & segment -; -; Author R C Manby -; Date 5.9.86 -; - -; ***************************************************************************** -; -; CircleOutline - Circle outline -; -; External routine -; -; in: ICursor is the centre of the circle -; NewPt is a point on the circumference -; -; out: R0-R11 corrupt -; - -CircleOutline ROUT - Push R14 - ADD R11, WsPtr, #GCsIX ; R0 := CentreX; R1 := CentreY - LDMIA R11, {R0-R3} ; R2 := NewPtX; R3 := NewPtY - BL GenCircleParm ; set up parm. block in R0-R7 - ADD R9, WsPtr, #CircleBlk ; R9 -> saved R0 - ADD R11, R9, #5*4 ; R11 -> saved R5 - STMIA R11, {R5-R7} ; save R5-R7 once and for all -10 - STMIA R9, {R0-R4} ; save R0-R4 before plotting pt - - SUB R10, R5, R0 ; upper left point - ADD R0, R5, R0 ; upper right point - ADD R1, R6, R1 - BL PlotPoint ; do upper right point - - CMP R10, R0 - MOVNE R0, R10 ; do upper left point - BLNE PlotPoint ; unless same as upper right - - LDMIA R9, {R0,R1} ; reload X, Y - CMP R1, #0 ; if yPnt=0, skip lower - BEQ %FT20 ; pixel pair - - LDMIA R11, {R5,R6} ; reload CentreX, CentreY - - SUB R10, R5, R0 ; lower left point - ADD R0, R5, R0 ; lower right point - SUB R1, R6, R1 - BL PlotPoint - - CMP R10, R0 - MOVNE R0, R10 ; do lower left point - BLNE PlotPoint ; unless same as lower right - -20 - LDMIA R9, {R0-R7} ; reload the parameter block - TEQ R0, #0 ; if xPnt=0 - Pull PC,EQ ; then finish - BL AdvCircleParm ; else step to next point - B %BT10 ; and go round again - -; ***************************************************************************** -; -; CircleFill - Circular area fill -; -; External routine -; -; in: ICursor is the centre of the circle -; NewPt is a point on the circumference -; -; out: R0-R11 corrupt -; - -CircleFill ROUT - Push R14 - ADD R11, WsPtr, #GCsIX ; centre is ICursor - LDMIA R11, {R0-R3} ; point is NewPt - BL GenCircleParm ; set up parameter block - ADD R11, WsPtr, #CircleBlk ; in R0-R6 -10 - STMIA R11, {R0-R7} ; save prior to line drawing - ADD R2, R5, R0 ; RightX = CentreX+xPnt - SUB R11, R6, R1 ; LowerY = CentreY-yPnt - - SUB R0, R5, R0 ; LeftX = CentreX-xPnt - ADD R1, R6, R1 ; UpperY = CentreY+yPnt - BL NewHLine ; draw upper slice - - CMP R11, R1 ; unless UpperY=LowerY - MOV R1, R11 - BLNE NewHLine ; do draw lower slice - - ADDS R11, WsPtr, #CircleBlk ; (C := 0) - LDMIA R11, {R0-R7} ; reload the parameter block -20 - TEQ R0, #0 - Pull PC, EQ ; finish if xPnt=0 - BL AdvCircleParm ; else step to next point - BCC %BT20 ; step until yPnt changes - B %BT10 ; do next slice - -; ***************************************************************************** -; -; CircleArc - Circular arc outline -; -; External routine -; -; in: OldCs is the centre of the circle -; ICursor is the start of the arc -; NewPt is the finishing point of the arc -; -; out: R0-R11 corrupt -; - -CircleArc ROUT - Push R14 - BL GenArcParmBlk - ADD R11, WsPtr, #CircleBlk - LDMIA R11, {R0-R7} ; reload the parameter block -10 - STMIA R11, {R0-R7} ; save prior to line drawing - BL Reflect - BL UpdateQuadrants - - LDRB R8, [WsPtr, #Quad0Draw] ; if LSBit set, plot this point - TST R8, #1 - LDRNE R0, [WsPtr, #ArcPoint0X] - LDRNE R1, [WsPtr, #ArcPoint0Y] - BLNE PlotPoint - - LDR R0, [WsPtr, #CircleBlk] ; if xPnt=0, ignore left pixel - CMP R0, #0 - BEQ %FT20 - - LDRB R8, [WsPtr, #Quad1Draw] ; if LSBit set, plot this point - TST R8, #1 - LDRNE R0, [WsPtr, #ArcPoint1X] - LDRNE R1, [WsPtr, #ArcPoint1Y] - BLNE PlotPoint -20 - LDR R0, [WsPtr, #(CircleBlk+4)] ; if yPnt=0, skip lower - CMP R0, #0 ; pixel pair - BEQ %FT30 - - LDRB R8, [WsPtr, #Quad3Draw] ; if LSBit set, plot this point - TST R8, #1 - LDRNE R0, [WsPtr, #ArcPoint3X] - LDRNE R1, [WsPtr, #ArcPoint3Y] - BLNE PlotPoint - - LDR R0, [WsPtr, #CircleBlk] ; if xPnt=0, ignore left pixel - CMP R0, #0 - BEQ %FT30 - - LDRB R8, [WsPtr, #Quad2Draw] ; if LSBit set, plot this point - TST R8,#1 - LDRNE R0, [WsPtr, #ArcPoint2X] - LDRNE R1, [WsPtr, #ArcPoint2Y] - BLNE PlotPoint -30 - ADD R11, WsPtr, #CircleBlk - LDMIA R11, {R0-R7} ; reload the parameter block - TEQ R0, #0 - Pull PC, EQ ; finish if xPnt=0 - - BL AdvCircleParm ; else step to next point - B %BT10 ; and go round again - -; ***************************************************************************** -; -; SegmentFill - Circular segment fill -; -; External routine -; -; in: OldCs is the centre of the circle -; ICursor is the start of the segment -; NewPt is the finishing point of the segment -; -; out: R0-R11 corrupt -; - -SegmentFill ROUT - Push R14 - BL GenArcParmBlk - BL GenSegParmBlk - ADD R11, WsPtr,#CircleBlk - LDMIA R11, {R0-R7} ; reload the parameter block -10 - STMIA R11, {R0-R7} ; save prior to line drawing - BL Reflect - BL UpdateQuadrants - LDR R0, [WsPtr, #Quad0StateChange] ; if any quadrant changes state - CMP R0, #0 - BLNE SegmentLineOn ; try starting segment line - - LDR R7, [WsPtr, #ArcPoint1X] ; limits of segment line - LDR R8, [WsPtr, #ArcPoint0X] - LDR R9, [WsPtr, #ArcPoint1Y] ; current scanline - LDR R11, [WsPtr, #UpperSegLinePtr] ; holds 0 or points at CLine2 - CMP R11, #0 - BLNE SegLineStep ; and advance if active - - LDR R0, [WsPtr, #ArcPoint1X] - LDR R1, [WsPtr, #ArcPoint1Y] - LDR R2, [WsPtr, #ArcPoint0X] - LDRB R3, [WsPtr, #Quad1Draw] - LDRB R4, [WsPtr, #Quad0Draw] - BL SegmentSlice - - LDR R0, [WsPtr, #(CircleBlk+4)] ; if yPnt=0, skip lower line - CMP R0, #0 - BEQ %FT15 - - LDR R7, [WsPtr, #ArcPoint2X] ; limits of segment line - LDR R8, [WsPtr, #ArcPoint3X] - LDR R9, [WsPtr, #ArcPoint3Y] ; current scanline - LDR R11, [WsPtr, #LowerSegLinePtr] ; holds 0 or points at CLine3 - CMP R11, #0 - BLNE SegLineStep ; and advance if active - - Swap R7,R8 - - LDR R0, [WsPtr, #ArcPoint3X] - LDR R1, [WsPtr, #ArcPoint3Y] - LDR R2, [WsPtr, #ArcPoint2X] - LDRB R3, [WsPtr, #Quad3Draw] - LDRB R4, [WsPtr, #Quad2Draw] - BL SegmentSlice -15 - LDR R0, [WsPtr, #Quad0StateChange] ; if any quadrant state changes - CMP R0, #0 ; left, kill segment line - BLNE SegmentLineOff - - ADD R11, WsPtr, #CircleBlk - LDMIA R11, {R0-R7} ; reload the parameter block -20 - TEQ R0, #0 - Pull PC, EQ ; finish if xPnt=0 - - BL AdvCircleParm ; else step to next point - BCS %BT10 ; do next slice - BCC %BT20 ; step until yPnt changes - -; ***************************************************************************** -; -; SegLineStep - Advance the segment line, limited to be within the circle -; -; Internal routine, called by SegmentFill -; -; in: R7 = left circleX -; R8 = right circleX -; R9 = current scanline -; R11 = pointer to Line (CLine2 or CLine3) (can't hold zero any more) -; - -SegLineStep ROUT - Push R14 - LDMIA R11, {R0-R6,R10} ; N.B. EndX is in R10 - CMP R4, #0 ; if line is horizontal - MOVEQ R9, R10 ; then line limits are in R0 & R10, - BEQ %FT50 ; R9 := R10 and branch - ; else find limits - - CMP R9, R1 ; advance line until currentY = circleY -20 - BLNE AdvLineParm ; (this usually takes one step) - CMP R9, R1 - BNE %BT20 - - MOV R9, R0 ; assume CurrentX is the left most point - - CMP R10, R0 ; if currentX=EndX - BEQ %FT40 ; then no need to advance line - - CMP R2, #0 ; else While bres >= 0 do AdvLineParm -30 - AdvLineParm_GE ; this leaves us furthest point on segment - CMP R10, R0 - BEQ %FT40 - CMP R2, #0 ; line for this scanline in R0 - BGE %BT30 -40 - STMIA R11, {R0-R4} ; update the line parameter block -50 - CMP R9, R0 ; R9 := LeftX - MOVGT R10, R9 - MOVGT R9, R0 - MOVLE R10, R0 ; R10 := RightX - - CMP R8, R10 ; force R10 into range R7..R8 - MOVLT R10, R8 - CMP R7, R10 - MOVGT R10, R7 - - CMP R7, R9 ; force R9 into range R7..R8 - MOVGT R9, R7 - CMP R8, R9 - MOVLT R9, R8 - - MOV R8, R10 - MOV R7, R9 - Pull PC - -; ***************************************************************************** -; -; SegmentSlice - Draw a slice of a circular segment -; -; Internal routine, called by SegmentFill -; -; in: R0 = circleX left -; R1 = circleY -; R2 = circleX right -; R3 = left quadrant control word (TopL or BotR) -; R4 = right quadrant control word (TopR or BotL) -; R7 = left most point of segment line for this slice -; R8 = right most point of segment line for this slice -; -; out: R0-R11 corrupt -; - -SegmentSlice ROUT - TST R3, #1 ; if both quadrants empty - TSTEQ R4, #1 ; or not at start of segment - MOVEQ PC, R14 ; then return - - TST R3, #1 ; if both quadrants to be filled - TSTNE R4, #1 ; or filling below segment line - BNE HLine ; then draw a slice of circle - -; 0 0 ; ...... -; 1 1 ; (----) - -; 0 1 ; \) ; /) ; \---) ; /---) -; 1 0 ; (/ ; (\ ; (---/ ; (---\ - -; From here on, all plotting decisions can be made from -; the LSBit of one quadrant field - - TST R3, #1 - MOVEQ R0, R7 ; Draw ---) - BEQ HLine - - MOV R2, R8 ; Draw (--- - B HLine - -; ***************************************************************************** -; -; SegmentLineOn - Try to start segment line -; -; Internal routine, called by SegmentFill -; - -SegmentLineOn ROUT - Push R14 - ; quadrant 0 - LDRB R10, [WsPtr, #Quad0StateChange] ; state change 0..2 - ADD R9, WsPtr, #ArcPoint0X ; address of point on circle - ADD R8, WsPtr, #CLine2 ; line block to use if starting - LDR R11, [WsPtr, #UpperSegLinePtr] ; 0 or ptr to active line - BL SegmentLineO5 - STRB R10, [WsPtr, #Quad0StateChange] ; new state change flag - - LDRB R10, [WsPtr, #Quad1StateChange] ; quadrant 1 - ADD R9, WsPtr, #ArcPoint1X - ADD R8, WsPtr, #CLine2 - BL SegmentLineO5 - STRB R10, [WsPtr, #Quad1StateChange] - STR R11, [WsPtr, #UpperSegLinePtr] ; unchanged/updated lineptr - - ; lower hemisphere - LDRB R10, [WsPtr, #Quad2StateChange] ; quadrant 2 - ADD R9, WsPtr, #ArcPoint2X - ADD R8, WsPtr, #CLine3 - LDR R11, [WsPtr, #LowerSegLinePtr] - BL SegmentLineO5 - STRB R10, [WsPtr, #Quad2StateChange] - - LDRB R10, [WsPtr, #Quad3StateChange] ; quadrant 3 - ADD R9, WsPtr, #ArcPoint3X - ADD R8, WsPtr, #CLine3 - BL SegmentLineO5 - STRB R10, [WsPtr, #Quad3StateChange] - STR R11, [WsPtr, #LowerSegLinePtr] - - Pull PC - -; ***************************************************************************** -; -; SegmentLineO5 - On state change, start segment line and update -; statechange - if line already active, do nothing -; -; Internal routine, called by SegmentLineOn -; -; in: R8 -> CLine(2..3) -; R9 -> ArcPoint(0..3)X -; R10 = Quad(0..3)StateChange -; 0 means no change -; 1 means one line hit -; 2 means both lines hit -; R11 = 0 or pointer to segment line -; -; out: R10 = updated Quad(0..3)StateChange -; R11 = 0 or points at newly created line -; - -SegmentLineO5 ROUT - CMP R10, #0 ; if state unchanged - MOVEQ PC, R14 ; then go home - - CMP R11, #0 ; else if segment line active - MOVNE PC, R14 ; then go home - - Push R14 ; else start the segment line - MOV R11, R8 - LDMIA R9, {R0,R1} ; run from point on circle - LDMIA R11, {R2,R3} ; to other end - BL GenLineParm - STMIA R11, {R0-R8} - MOV R10, R10, LSR #1 ; state1->state0, state2->state1 - Pull PC - -; ***************************************************************************** -; -; SegmentLineOff - Try to kill segment line -; -; Internal routine, called by SegmentFill -; -; in: R0 = stateflags for each quadrant -; -; out: R0 preserved -; R1 corrupted -; - -SegmentLineOff ROUT - MOV R1, #0 - TST R0, #&3 ; if statechange occurred in - TSTEQ R0, #&300 ; Quad0 or Quad1 - STRNE R1, [WsPtr, #UpperSegLinePtr] ; then kill upper segment line - - TST R0, #&30000 ; if statechange occured in - TSTEQ R0, #&3000000 ; Quad2 or Quad3 - STRNE R1, [WsPtr, #LowerSegLinePtr] ; then kill lower segment line - - MOV PC, R14 - -; ***************************************************************************** -; -; SectorFill - Circular sector (pie) fill -; -; External routine -; -; in: OldCs is the centre of the circle -; ICursor is the start of the sector -; NewPt is the finishing point of the sector -; -; out: R0-R11 corrupt -; - -SectorFill ROUT - Push R14 - BL GenArcParmBlk - ADD R11, WsPtr, #CircleBlk - LDMIA R11, {R0-R7} ; reload the parameter block -SectorFi10 - STMIA R11, {R0-R7} ; save prior to line drawing - BL Reflect - BL UpdateQuadrants - - LDR R0, [WsPtr, #(CircleBlk+4)] ; if yPnt=0, panic - CMP R0, #0 - BEQ SectorFi40 - - LDR R0, [WsPtr, #ArcPoint1X] - LDR R1, [WsPtr, #ArcPoint1Y] - LDR R2, [WsPtr, #ArcPoint0X] - LDRB R3, [WsPtr, #Quad1Draw] - LDRB R4, [WsPtr, #Quad0Draw] - BL SectorSlice - - LDR R0, [WsPtr, #ArcPoint3X] - LDR R1, [WsPtr, #ArcPoint3Y] - LDR R2, [WsPtr, #ArcPoint2X] - LDRB R3, [WsPtr, #Quad3Draw] - LDRB R4, [WsPtr, #Quad2Draw] - BL SectorSlice - -SectorFi20 - ADD R11, WsPtr, #CircleBlk - LDMIA R11, {R0-R7} ; reload the parameter block -SectorFi30 - TEQ R0, #0 - Pull PC, EQ ; finish if xPnt=0 - BL AdvCircleParm ; else step to next point - BCS SectorFi10 ; do next slice - BCC SectorFi30 ; step until yPnt changes - -SectorFi40 - LDR R0, [WsPtr, #CLine0Near] ; equal to CLine1NearX & - LDR R1, [WsPtr, #ArcPoint0Y] ; centre of circle - LDR R3, [WsPtr, #CLine0Far] - LDR R4, [WsPtr, #CLine1Far] - - Greatest R2, R0,R3 ; draw from rightmost of CLine0, Cline1 - Greatest R2, R2,R4 - - Least R0, R0,R3 ; to left most of CLine0, Cline1 - Least R0, R0,R4 - - LDR R3, [WsPtr, #Quad0Draw] ; all 4 drawing control bytes - - TST R3, #&00000001 ; if Quad0 or - TSTEQ R3, #&01000000 ; Quad3 fills against circle - LDRNE R2, [WsPtr, #ArcPoint0X] ; then override R2 - - TST R3, #&00000100 ; If Quad1 or - TSTEQ R3, #&00010000 ; Quad2 fills against circle - LDRNE R0, [WsPtr, #ArcPoint1X] ; then override R0 - - BL NewHLine ; draw the line (sorted coords) - B SectorFi20 - - -; -; Internal subroutine for sector (pie) fills -; -; On entry, R0 - circleX left -; R1 - circleY -; R2 - circleX right -; R3 - left quadrant control word (TopL or BotR) -; R4 - right quadrant control word (TopR or BotL) -; -; On exit, R0-R11 corrupt -; -SectorSlice - CMP R4,#&57 ; (--//) - LDREQ R3,[WsPtr,#CLine0Far] - LDREQ R4,[WsPtr,#CLine1Near] - BEQ DoubleHLine - - CMP R3,#&73 ; (\\--) - LDREQ R3,[WsPtr,#CLine0Near] - LDREQ R4,[WsPtr,#CLine1Far] - BEQ DoubleHLine - - CMP R4,#&07 ; (-\/-) - CMPEQ R3,#&03 - LDREQ R3,[WsPtr,#CLine0Near] - LDREQ R4,[WsPtr,#CLine1Near] - BEQ DoubleHLine - - CMP R4,#&07 ; /-) - LDREQ R0,[WsPtr,#CLine1Near] - BEQ HLine - CMP R3,#&03 ; (-\ - LDREQ R2,[WsPtr,#CLine0Near] - BEQ HLine - - CMP R4,#&3A ; /-/ - LDREQ R0,[WsPtr,#CLine1Near] - LDREQ R2,[WsPtr,#CLine0Far] - BEQ HLine - - CMP R3,#&1E ; \-\ - LDREQ R0,[WsPtr,#CLine1Far] - LDREQ R2,[WsPtr,#CLine0Near] - BEQ HLine - - CMP R4,#1 ; ...--) - MOVLT PC,Link ;Nothing in either quadrant - LDRGT R2,[WsPtr,#CLine0Far] ; ...--/ - CMP R3,#1 ; (--... - LDRGT R0,[WsPtr,#CLine1Far] ; \--... - B HLine -; -; -; -;------------------------------------------------------------------------------ -; -; Reflect - Generate four point on a circle by -; ======= reflection about its centre -; -; On entry, R0..R7 hold a circle parameter block -; On exit, R0 (X), R1 (Y) point in Quadrant0 -; R2 (X), R3 (Y) point in Quadrant1 -; R7 (X), R8 (Y) point in Quadrant2 -; R9 (X), R10 (Y) point in Quadrant3 -; R11 points at ArcPoint0X -; -; ArcPoint(0..3) updated -; -; Format of a circle control block -; R0 - xPnt (CurrentX - relative to centre) -; R1 - yPnt (CurrentY - relative to centre) -; R2 - sum (Bres) -; R3 - upcnt -; R4 - downcnt -; R5 - CentreX -; R6 - CentreY -; R7 - Aspect (pixel shape : 0 square, 1 horz rect, 2 vert rect) -; -Reflect - ADD R9,R5,R0 ;Quad 3 CentreX+xPnt ;Calculate all 4 points - SUB R10,R6,R1 ; CentreY-yPnt ; by reflection about centre - - SUB R7,R5,R0 ;Quad 2 CentreX-xPnt - SUB R8,R6,R1 ; CentreY-yPnt - - SUB R2,R5,R0 ;Quad 1 CentreX-xPnt - ADD R3,R6,R1 ; CentreY+yPnt - - ADD R0,R5,R0 ;Quad 0 CentreX+xPnt - ADD R1,R6,R1 ; CentreY+yPnt - - ADD R11,WsPtr,#ArcPoint0X - STMIA R11,{R0,R1, R2,R3, R7,R8, R9,R10} ;And store the lot for later on - - MOV PC,Link -; -; -; -; update lines & quadrant data -; -; use R9 as offset from WsPtr to ArcPoint(0..3)X -; use R10 as offset from WsPtr to QuadControl(0..3) -; use R11 as address of line parameter block(0..1) -; -; -UpdateQuadrants - SaveRetAdr - - MOV R0,#0 - STR R0,[WsPtr,#Quad0StateChange] ;Clear flags for each quadrant - - LDR R0,[WsPtr,#Quad0Control] ;Update the 4 'drawing' - STR R0,[WsPtr,#Quad0Draw] ; control bytes - - ;Start by looking at quadrant 0 - ADD R10,WsPtr,#Quad0Control ;Address of control byte - ADD R9,WsPtr,#ArcPoint0X ;Address of point on circle - BL UpdateQuadr10 - - ADD R10,R10,#(Quad1Control-Quad0Control) ;Quadrant 1 - ADD R9,R9,#(ArcPoint1X-ArcPoint0X) - BL UpdateQuadr10 - - ADD R10,R10,#(Quad1Control-Quad0Control) ;Quadrant 2 - ADD R9,R9,#(ArcPoint1X-ArcPoint0X) - BL UpdateQuadr10 - - ADD R10,R10,#(Quad1Control-Quad0Control) ;Quadrant 3 - ADD R9,R9,#(ArcPoint1X-ArcPoint0X) - BL UpdateQuadr10 - - Return - - -UpdateQuadr10 - LDRB R0,[R10] ;Get control block for quadrant - TST R0,#&2 ;If 0 or 1 - MOVEQ PC,Link ; then nothing to do - - SaveRetAdr ; else update the line - - LDMIA R9,{R7,R8} ;Point on circle in this quad - - TST R0,#4 - ADDEQ R11,WsPtr,#CLine0 ;Load parm blk for line(0/1) - ADDNE R11,WsPtr,#CLine1 - - LDMIA R11,{R0,R1,R2,R3,R4,R5,R6} ;EndX,EndY (R7,R8) not needed - BL ArcLineStep - STMIA R11,{R0,R1,R2,R3,R4,R5,R6,R8} ;Update the changes, EndX - ; used for NearX - - CMP R7,#1 ; 'change state' flag - MOV R7,#1 ;Convert to one line hit - STRGEB R7,[R10,#(Quad0StateChange-Quad0Control)] - - LDRB R0,[R10] ;Get control block for quadrant and look at - MOV R0,R0,LSR #3 ; next control field - STRGEB R0,[R10] ;If 'change state' write back next field - - ;If outside circle - TSTEQ R0,#1 ; or changing into a - STRGTB R0,[R10,#(Quad0Draw-Quad0Control)] ; plotting state update - ; drawing control byte - - TST R0,#2 ;If new field doesnt advance a - Return EQ ; line then quit - ; else update second line - Push R0 - - LDMIA R9,{R7,R8} ;Point on circle in this quad - - TST R0,#4 - ADDEQ R11,WsPtr,#CLine0 ;Load parm blk for line(0/1) - ADDNE R11,WsPtr,#CLine1 - - LDMIA R11,{R0,R1,R2,R3,R4,R5,R6} ;EndX,EndY (R7,R8) not needed - BL ArcLineStep - STMIA R11,{R0,R1,R2,R3,R4,R5,R6,R8} ;Update the changes, EndX - ; used for NearX - - CMP R7,#1 ; 'change state' flag - MOV R7,#2 ;Convert to both lines hit - STRGEB R7,[R10,#(Quad0StateChange-Quad0Control)] - - Pull R0 ;Use earlier value instead of reloading control block, - ; as whally lines (dy/dx = 0/0) blewup when 2nd line - ; terminated before 1st line. This case should not - ; now get through, but you never now. - - MOV R0,R0,LSR #3 ;Next field in control field - STRGEB R0,[R10] ;If 'changing state' write this back - - STRGTB R0,[R10,#(Quad0Draw-Quad0Control)] ; and update drawing - ; control byte - Return -; -; -; -; ArcLineStep - Step line parameter block checking for interception -; =========== with circle. -; -; Return first ('near') and last ('far') points of line -; that fall on this scanline, limiting 'far' to the point on -; the circle if interception occurs. -; -; On entry, R0..R6 hold a line parameter block (EndX,EndY are not loaded) -; -; Format of a line control block -; R0 - StartX (CurrentX) -; R1 - StartY (CurrentY) -; R2 - Bres -; R3 - DeltaX -; R4 - DeltaY -; R5 - StepX (+1/-1) (Equv bit6 of Sign in 6502 version) -; R6 - StepY (+1/-1) (Equv bit7 of Sign in 6502 version) -; (R7 - EndX Not used in this routine,) -; (R8 - EndY so not passed in) -; -; R7,R8 CircleX,CircleY -; -; On exit, R0 (X), R1 (Y), R2 (bres) updated -; R7 0/1/2 for within/on/outside circle -; R8 nearX -; -; -; R9,R10,R11 unused -; -ArcLineStep - SaveRetAdr - - CMP R8,R1 ;Advance line until CurrentY = CircleY -ArcLineSt10 - BLNE AdvLineParm - CMP R8,R1 ; {this usually takes one step} - BNE ArcLineSt10 - - MOV R8,R0 ;This point is nearX - ; ie the first point on this scanline - - [ No26bitCode - SUBS R14,R0,R7 ;If (CurrentX=CircleX) then farX is on circle - TEQNE R5,R14 ;If ((CurrentX-CircleX) EOR StepX is +ve) - | - CMP R0,R7 ;If (CurrentX=CircleX) then farX is on circle - TEQNE R5,PC ;If ((CurrentX-CircleX) EOR StepX is +ve) - ] - ;then farX is outside circle - MOVPL R0,R7 ; limit farX to circleX - MOVPL R7,#2 ; set change flag =2 for outside - MOVEQ R7,#1 ; =1 for on circle - Return PL ; and return - - - CMP R2,#0 ;While bres >= 0 and within circle AdvLineParm -ArcLineSt20 ; this leaves us with farX,farY in R0,R1 - AdvLineParm_GE - - CMP R0,R7 ;If (CurrentX=CircleX) then farX is on circle - MOVEQ R7,#1 ; set change flag - Return EQ ; and return - ; else within circle - - CMP R2,#0 ;If y about to change, return farX,farY - BGE ArcLineSt20 ; else loop back to step the line - MOV R7,#0 - Return -; -; -; -; Assumes R9, R10 & R11 are not corrupted over calls to GenLineParm -; -; -GenArcParmBlk - SaveRetAdr - - ADD R11,WsPtr,#OldCsX ;Build parm block for a circle - LDMIA R11,{R0,R1,R2,R3} ; centre OldCs, point on - BL GenCircleParm ; circumference in ICursor - - ADD R11,WsPtr,#CircleBlk - STMIA R11,{R0,R1,R2,R3,R4,R5,R6,R7} - - ADD R10,WsPtr,#CLine0 - ADD R11,WsPtr,#OldCsX - - LDMIA R11!,{R0,R1,R2,R3} ;CLine0 gives start of arc - BL GenLineParm ; (OldCs->ICursor) - STMIA R10!,{R0,R1,R2,R3,R4,R5,R6,R7,R8} -; -; Use StepX and StepY for 'start of arc' line to form the beginnings of -; an index into the arc control block table -; StepX & StepY each hold +1 or -1 and the value left in R9 is -; -; R9 | Quad -; ------+------ -; 0000 | 0 -; 0100 | 1 -; 1100 | 2 -; 1000 | 3 -; -; - AND R5,R5,#&4 ; - AND R6,R6,#&8 ; See above for details - ORR R9,R6,R5 ; - - LDMIA R11,{R2,R3} ;CLine1 gives end line of arc - ; (OldCs->NewPt) - - CMP R0,R2 ;If OldCs=NewPt - CMPEQ R1,R3 ; use OldCs->(NewPtX+1,NewPtY) - ADDEQ R2,R2,#1 ; for compatability with Master - - BL GenLineParm - STMIA R10,{R0,R1,R2,R3,R4,R5,R6,R7,R8} - - AND R5,R5,#&4 - AND R6,R6,#&8 - ORR R6,R6,R5 ; 'end of arc' - - CMP R9,R6 ;If start and end quadrants different - ORRNE R9,R9,R6,LSL #2 ; then index = start OR (end <<2) - BNE GenArcPar10 ; and branch - - ;else special case code for index, based - ; on gradients of line - - LDR R7,[WsPtr,#(CLine0+12)] ; DeltaX0.DeltaY1 - LDR R8,[WsPtr,#(CLine1+16)] - MUL R0, R7, R8 - - LDR R7,[WsPtr,#(CLine0+16)] ; DeltaX1.DeltaY0 - LDR R8,[WsPtr,#(CLine1+12)] - MUL R9, R7, R8 - - CMP R0,R9 ;For gradients <,>,= - ORRLT R9,R6,#&40 ; generate index into table - ORRGT R9,R6,#&50 - ORREQ R9,R6,R6,LSL #2 - -GenArcPar10 - ADR R0,GenArcTb ; GenArcTb - - LDR R0,[R0,R9] - STR R0,[WsPtr,#Quad0Control] ;Setup all FOUR control BYTEs - - Return - - - -; -; -; 00 000 000 &00 no points to be plotted -; 00 000 001 &01 all points to be plotted -; 00 001 x10 &0A,0E plot nothing until line x hits circle then start plotting -; 00 000 x11 &03,07 plot points until line x hits circle then stop -; 00 y11 x10 &3A,1E plot points only between line x and line y -; 01 y10 x11 &73,57 plot points from x axis to line x, then line y to y axis -; -; -GenArcTb - & &0000003A ; 0->0 (short arc) - & &01010307 ; 1->0 - & &03000007 ; 3->0 - & &010A0007 ; 2->0 - - & &00000E0A ; 0->1 - & &00001E00 ; 1->1 (short arc) - & &03000E01 ; 3->1 - & &010A0E01 ; 2->1 - - & &0E01010A ; 0->3 - & &0E010300 ; 1->3 - & &1E000000 ; 3->3 (short arc) - & &0E0A0000 ; 2->3 - - & &0007010A ; 0->2 - & &00070300 ; 1->2 - & &03070101 ; 3->2 - & &003A0000 ; 2->2 (short arc) - - - & &01010157 ; 0->0 (long arc) grad line0 > grad line1 - & &00001E00 ; 1->1 (short arc) - & &1E000000 ; 3->3 (short arc) - & &01570101 ; 2->2 (long arc) - - & &0000003A ; 0->0 (short arc) grad line0 < grad line 1 - & &01017301 ; 1->1 (long arc) - & &73010101 ; 3->3 (long arc) - & &003A0000 ; 2->2 (short arc) -; -; -; - - -GenSegParmBlk - SaveRetAdr - - ADD R11,WsPtr,#CLine1 ;Get all line data except EndX,EndY - LDMIA R11,{R0,R1,R2,R3,R4,R5,R6} - - LDR R11,[WsPtr,#AspectRatio] ;Frigging non square frigging pixels - ; 0=Sq, 1=horz, 2=vert - CMP R11,#1 - MOVEQ R3,R3,LSL #1 ;If horz, scale up deltaX - MOVGT R4,R4,LSL #1 ;If vert, scale up deltaY - - [ {TRUE} - LDR R8, [WsPtr, #CircleRadSquare] ; R8 = r2 - MUL R9, R3, R3 ; R9 = DX2 - MUL R10, R4, R4 ; R10 = DY2 - ADD R11, R9, R10 ; R11 = R2 - - MOV R3, R10 - BL DoubleMulDivSquareRoot - MOV R4, R3 ; R4 = dy - - MOV R3, R9 - BL DoubleMulDivSquareRoot ; R3 = dx - | - MUL R9,R3,R3 ;R9 := Square(deltaX) - MOV R2,R9 ;R2 := Square(deltaX) - - LDR R8,[WsPtr,#CircleRadSquare] - MUL R3,R9,R8 ;R3 := Square(radius) * Square(deltaX) - - MUL R9,R4,R4 ;R9 := Square(deltaY) - ADD R2,R2,R9 ;R2 := Square(deltaX) + Square(deltaY) - - MUL R10,R9,R8 ;R10 := Square(radius) * Square(deltaY) - - MOV R9,R2 -; *****Change made by DJS -; Use new DivRem macro, not old DIVREM -; Original code was: -; DIVREM R7,R10,R9, R8 ;R7 := (rad^2 * deltaY^2)/R2 - DivRem R7,R10,R9, R8 ;R7 := (rad^2 * deltaY^2)/R2 -; *****End of change made by DJS - BL SquareRoot ;Iy left in R8 - MOV R4,R8 - -; *****Change made by DJS -; Use new DivRem macro, not old DIVREM -; Original code was: -; DIVREM R7,R3,R2, R8 ;R7 := (rad^2 * deltaX^2)/R2 - DivRem R7,R3,R2, R8 ;R7 := (rad^2 * deltaX^2)/R2 -; *****End of change made by DJS - BL SquareRoot ;Ix left in R8 - MOV R3,R8 - ] - - LDR R11,[WsPtr,#AspectRatio] ; 0=Sq, 1=horz, 2=vert - CMP R11,#1 - MOVEQ R3,R3,LSR #1 ;If horz, scale down deltaX - MOVGT R4,R4,LSR #1 ;If vert, scale down deltaY - - CMP R5,#0 ;If StepX >= 0 - ADDGE R0,R0,R3 ; then R0 := StartX+R3 - SUBLT R0,R0,R3 ; else R0 := StartX-R3 - - CMP R6,#0 ;If StepY >= 0 - ADDGE R1,R1,R4 ; then R1 := StartY+R4 - SUBLT R1,R1,R4 ; else R1 := StartY-R4 - -; -; R0,R1 is the intercept of CLine1 and the circle -; so, segment line runs from here to endpoint of CLine0 -; - - LDR R2,[WsPtr,#CLine0EndX] - LDR R3,[WsPtr,#CLine0EndY] - - CompSwapT R0,R1, R2,R3, R4 ; Order coords - -; -; If segment line crosses X axis -; then initialise both upper & lower segment lines -; else leave endpoints for later use -; - - LDR R4,[WsPtr,#Quad0Control] ;All 4 control bytes - ORR R4,R4,R4,LSR #8 ;If bit1 =0, not in upper hemisphere - ;If bit9 =0, not in lower hemisphere - AND R4,R4,R4,LSR #16 - TST R4,#2 ;If bit1 =0 - BEQ GenSegParmB10 ; then line does not cross X axis - - ; else start both CLine2 & CLine3 - ; running, so.. - - BL GenLineParm ;Initialise CLine2 as the - ADD R11,WsPtr,#CLine2 ; upper hemisphere segment line - STMIA R11,{R0,R1,R2,R3,R4,R5,R6,R7,R8} - STR R11,[WsPtr,#UpperSegLinePtr] - - MOV R2,R0 ;Run CLine3, in the opposite - MOV R3,R1 ; direction for use as the - MOV R0,R7 ; lower hemisphere segment line - MOV R1,R8 - BL GenLineParm - ADD R11,WsPtr,#CLine3 - STMIA R11,{R0,R1,R2,R3,R4,R5,R6,R7,R8} - STR R11,[WsPtr,#LowerSegLinePtr] - - Return - -GenSegParmB10 ;Line does not cross X axis, so.. - ADD R11,WsPtr,#CLine2 ;Upper hemisphere segment line, runs - STMIA R11,{R2,R3} ; to R2,R3 (if it runs at all) - - ADD R11,WsPtr,#CLine3 ;Lower hemisphere segment line, runs - STMIA R11,{R0,R1} ; to R0,R1 (if it runs at all) - - MOV R11,#0 ;Both lines inactive - STR R11,[WsPtr,#UpperSegLinePtr] - STR R11,[WsPtr,#LowerSegLinePtr] - - Return - -; ***************************************************************************** -; -; DoubleMulDivSquareRoot - Compute SQR(a*b/c) in double precision -; -; in: R3 = a -; R8 = b -; R11 = c -; -; out: R3 = result -; R2, R7 corrupted -; - -DoubleMulDivSquareRoot ROUT - Push "R8-R11,R14" - MOV R2, R3, LSR #16 ; R2 = ah - EOR R7, R3, R2, LSL #16 ; R7 = al - MOV R9, R8, LSR #16 ; R9 = bh - EOR R10, R8, R9, LSL #16 ; R10 = bl - - MUL R3, R7, R10 ; R3 = al.bl - MUL R14, R7, R9 ; R14 = al.bh - MLA R14, R10, R2, R14 ; R14 = al.bh + ah.bl - MUL R8, R2, R9 ; R8 = ah.bh - - ADDS R3, R3, R14, LSL #16 ; R3 = lower 32 bits of a.b - ADC R8, R8, R14, LSR #16 ; R8 = upper 32 bits of a.b - -; now do divide of a.b by c -; we know that a.b < 2^61, so no problem with top bit of a.b - - MOV R9, R11 ; R9 = low 32 bits of shifted c - MOV R10, #0 ; R10 = hi 32 bits of shifted c -10 - ADDS R9, R9, R9 ; shift R9,R10 left one place - ADC R10, R10, R10 - CMP R9, R3 ; compare R9,R10 with a.b - SBCS R14, R10, R8 - BCC %BT10 ; if lower then loop - - MOV R7, #0 ; zero result -20 - CMP R3, R9 ; if a.b >= R9,R10 - SBCS R14, R8, R10 - SUBCS R3, R3, R9 ; then a.b -:= R9,R10 - MOVCS R8, R14 - ADC R7, R7, R7 ; shift result up with new bit - MOVS R10, R10, LSR #1 ; shift R9,R10 right one bit - MOV R9, R9, RRX - BNE %BT20 ; for termination, R10 = 0 - CMP R9, R11 ; and R9 < R11 - BCS %BT20 - - BL SquareRoot ; in: R7 = arg - ; out: R8 = result, R9-R11 corrupt - MOV R3, R8 - Pull "R8-R11,PC" - - - - END diff --git a/s/vdu/vdugrafc b/s/vdu/vdugrafc deleted file mode 100644 index a088b783..00000000 --- a/s/vdu/vdugrafc +++ /dev/null @@ -1,441 +0,0 @@ -; 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.VduGrafC -; -; ARTHUR OPERATING SYSTEM - Vdu Drivers -; ======================= -; -; Vdu driver code - Ellipse outline & fill -; -; Author R C Manby -; Date 29.9.86 -; - - - - -; -; -; -;------------------------------------------------------------------------------ -; -; EllipseOutline -; ============== -; -; On entry, OldCs is centre of the ellipse -; ICursor is a point giving the width of the ellipse -; NewPt is the highest/lowest point on the ellipse -; -; On exit, R0..R11 corrupt -; -EllipseOutline - SaveRetAdr - - BL GenEllParm - B EllipseOut20 -EllipseOut10 - BL AdvEllParm -EllipseOut20 - ; Registers hold - ; R4 , R5 , R6 , R7 , R8 , R9 , R10 - ; ellY,prevL,prevR,thisL,thisR,nextL,nextR - - MOV R0,R7 ;Left line runs from thisL rightwards - MOV R1,R4 - Greatest R3,R5,R9 - SUB R3,R3,#1 - Greatest R3,R3,R7 ; to max(thisL, max(prevL-1,nextL-1)) - - MOV R2,R8 ;Right line runs from thisR leftwards - Least R4,R6,R10 - ADD R4,R4,#1 - Least R4,R4,R8 ; to min(thisR, min(prevR+1,nextR+1)) - - BL EllDoubleHLine ;Any overlap handled by EllDoubleHLine - - LDR R0,[WsPtr,#EllBlkSliceCnt] - CMP R0,#0 - BGE EllipseOut10 - B EllipseFi30 ;Use common code with ellipse fill for - ; last scanline -; -; -; -; -;------------------------------------------------------------------------------ -; -; EllipseFill -; =========== -; -; On entry, OldCs is centre of the ellipse -; ICursor is a point giving the width of the ellipse -; NewPt is the highest/lowest point on the ellipse -; -; On exit, R0..R11 corrupt -; -EllipseFill - SaveRetAdr - - BL GenEllParm - B EllipseFi20 -EllipseFi10 - BL AdvEllParm -EllipseFi20 - ; Registers hold - ; R4 , R5 , R6 , R7 , R8 , R9 , R10 - ; ellY,prevL,prevR,thisL,thisR,nextL,nextR - - MOV R0,R7 ;Draw slice thisL -> thisR - MOV R1,R4 - MOV R2,R8 - - BL EllHLine - - LDR R0,[WsPtr,#EllBlkSliceCnt] - CMP R0,#0 - BGE EllipseFi10 -EllipseFi30 - LDR R0,[WsPtr,#EllNextL] ;Last slice nextL -> nextR - LDR R1,[WsPtr,#EllBlkEllY] - ADD R1,R1,#1 - LDR R2,[WsPtr,#EllNextR] - - BL EllHLine - - Return -; -; -; -; EllHLine - Draw a slice then reflect around ellipse origin -; ======== -; -; On entry, R0 (X) - Left point of line -; R1 (Y) - Y ordinate of line -; R2 (X) - Right point of line -; -; On exit, R0..R11 corrupt -; -EllHLine - SaveRetAdr - - LDR R3,[WsPtr,#OldCsX] ;All points relative to OldCs - LDR R4,[WsPtr,#OldCsY] - - ADD R11,WsPtr,#EllHLineWs ;Save points given plus centre of - STMIA R11,{R0-R4} ; ellipse for later use - - ADD R0,R3,R0 ;OldCsX + LeftX - ADD R1,R4,R1 ;OldCsY + Y - ADD R2,R3,R2 ;OldCsX + RightX - - BL NewHLine ;Draw top slice - - ADD R11,WsPtr,#EllHLineWs - LDMIA R11,{R3-R7} - - CMP R4,#0 ;If EllY = 0 - Return EQ ; then quit to prevent double plotting - ; else reflect around ellipse origin - - SUB R0,R6,R5 ;OldCsX - RightY - SUB R1,R7,R4 ;OldCsY - Y - SUB R2,R6,R3 ;OldCsX - LeftY - - BL NewHLine - - Return -; -; -; -; EllDoubleHLine -; ============== -; -; On entry, R0 (X) - Left most point -; R1 (Y) - y ordinate of line -; R2 (X) - Right most point -; R3 (X) - end of left most line -; R4 (X) - start of right most line -; -EllDoubleHLine - CMP R3,R4 ;If end of left line overlaps - ; start of right - BGE EllHLine ;then draw and reflect R0->R2 - ;else - SaveRetAdr - - ADD R11,WsPtr,#EllDoubleHLineWs - STMIA R11,{R0-R4} - - MOV R2,R3 ;Draw and reflect R0->R3 - BL EllHLine - - ADD R11,WsPtr,#EllDoubleHLineWs - LDMIA R11,{R0-R4} - MOV R0,R4 - BL EllHLine ;Draw and reflect R4->R2 - - Return -; -; -; -;------------------------------------------------------------------------------ -; -; GenEllParm - Generate a control block for an ellipse -; ========== -; -; On entry, OldCs is centre of the ellipse -; ICursor is a point giving the width of the ellipse -; NewPt is the highest/lowest point on the ellipse -; -; On exit, EllBlk holds the ellipse parameter block -; -; EllThisL..EllNextR setup -; -; R4 - EllY -; R5, R6 - prevL,prevR -; R7, R8 - thisL,thisR -; R9, R10 - nextL,nextR -; -; -; Format of ellipse parameter block -; -; Var R0 - SliceCnt count of slices remaining -; R1 - EllYSqr square of current slice height -; R2 - OddNo used to give next EllYSqr value -; R3 - XOffset [bb.bb] offset in X dirn along shear line -; R4 - EllY -; Const R5 - ShearX [bb.bb] shear factor per scanline -; R6 - SliceX [0bb.b] axis ratio -; R7 - MaxYSqr [bbbb] -; -; -; -GenEllParm - SaveRetAdr - - ADD R11,WsPtr,#OldCsX - LDMIA R11,{R0,R1, R2,R3, R4,R5} ;OldCs, ICursor, NewPt - - SUBS R6,R2,R0 - RSBLT R6,R6,#0 ;R6 := ABS(width of slice) - ;R6 is sliceX (ie maxwidth) - SUBS R7,R5,R1 - MOV R8,R7 - RSBLT R7,R7,#0 ;R7 := ABS(height of ellipse) - -; -; Leave R0,R1,R2 intact upto here -; R6 is ABS(width of slice) - - BEQ EllipseZeroHeight ;If NewPtY=OldCsY draw a single line - - SUBS R5,R4,R0 - EOR R8,R8,R5 - RSBLT R5,R5,#0 ;R5 := ABS(shear at top of ellipse) - -; -; R5 holds shear in x dirn -; R6 holds width -; R7 holds height (also shearY) -; R8 sign bit is slope of shearline -; - - MOV R0,R7 ;Setup SliceCnt - - ;MOV R7,R0 ;Div R5,R5,R0 using R7,R9,R10 - MOV R9,R5,LSL #16 -; *****Change made by DJS -; Use new DivRem macro, not old DIVREM -; Original code was: -; DIVREM R5,R9,R7,R10 ;R5 := totalshear/ellipseheight - DivRem R5,R9,R7,R10 ;R5 := totalshear/ellipseheight -; *****End of change made by DJS - - ;BIC R5,R5,#&FF ;Slugg accuracy for compatability? - - CMP R8,#0 - RSBLT R5,R5,#0 ;Correct for negative slope - - MOV R7,R0 ;Div R6,R6,R0 using R7,R9,R10 - MOV R9,R6,LSL #8 -; *****Change made by DJS -; Use new DivRem macro, not old DIVREM -; Original code was: -; DIVREM R6,R9,R7,R10 ;R6 := slicewidth/ellipseheight - DivRem R6,R9,R7,R10 ;R6 := slicewidth/ellipseheight -; *****End of change made by DJS - - -; R5 holds shear per scanline -; R6 ratio of ellipse axis - - MUL R7,R0,R0 ;MaxYSqr - - MOV R1,#0 ;EllYSqr - MOV R2,#1 ;Oddno - MOV R3,#0 ;XOffset - MOV R4,#-2 ;EllY - - ADD R11,WsPtr,#EllBlk - STMIA R11,{R0-R7} - - BL AdvEllP20 ;Start by calculating first two slices - STR R9,[WsPtr,#EllThisL] ;Limits passed back in R9,R10 - STR R10,[WsPtr,#EllThisR] - - BL AdvEllP20 - - ADD R11,WsPtr,#EllThisL - LDMIA R11,{R7,R8} - - RSB R5,R10,#0 ;prevL := -nextR - RSB R6,R9,#0 ;prevR := -nextL - - ; Stretch slice if disconnected - - Least R7,R7,R6 ; thisL := min(thisL,prevR) - Least R7,R7,R10 ; thisL := min(thisL,nextR) - - Greatest R8,R8,R5 ; thisR := max(thisR,prevL) - Greatest R8,R8,R9 ; thisR := max(thisR,nextL) - - STMIA R11,{R7,R8,R9,R10} - - Return ; On return, registers hold - ; R4 , R5 , R6 , R7 , R8 , R9 , R10 - ; ellY,prevL,prevR,thisL,thisR,nextL,nextR -; -; -; -; EllipseZeroHeight - Draw a single line, no pips -; ================= -; -; On entry, R0 (X), R1 (Y) holds centre of ellipse -; R6 is ABS(width of slice/2) -; -EllipseZeroHeight - - ADD R2,R0,R6 - SUB R0,R0,R6 - - Pull Link ;Return address into ellipse code - Pull Link ;Return address to whoever called - ; ellipses - - B NewHLine ;Sorted coords - ;This will return to whoever called - ; the ellipse code -; -; -; -;------------------------------------------------------------------------------ -; -; AdvEllParm -; ========== -; -; On entry, R11 points to ellipse parameter block -; -; On exit, EllBlk, EllThisL..EllNextR updated -; -; R4 - EllY -; R5, R6 - prevL,prevR -; R7, R8 - thisL,thisR -; R9, R10 - nextL,nextR -; -; -; Format of ellipse parameter block -; -; Var R0 - SliceCnt count of slices remaining -; R1 - EllYSqr square of current slice height -; R2 - OddNo used to give next EllYSqr value -; R3 - XOffset [bb.bb] offset in X dirn along shear line -; R4 - EllY -; Const R5 - ShearX [bb.bb] shear factor per scanline -; R6 - SliceX [0bb.b] axis ratio -; R7 - MaxYSqr [bbbb] -; -; -; -AdvEllParm - SaveRetAdr - - BL AdvEllP20 ;Advance scanline - ; On return, registers hold - ; R4 , R9 , R10 - ; ellY, nextL,nextR - - ;Shuffle points - ;R9/R10 -> nextLR - ;nextLR -> thisLR - stretch if disconnected - ;thisLR -> prevLR - - ADD R11,WsPtr,#EllThisL - LDMIA R11,{R5,R6, R7,R8} - ; Stretch slice if disconnected - Greatest R8,R8,R9 ; thisR := max(thisR,nextL) - Least R7,R7,R10 ; thisL := min(thisL,nextR) - - STMIA R11,{R7,R8, R9,R10} - Return ; R4 , R5 , R6 , R7 , R8 , R9 , R10 - ; ellY,prevL,prevR,thisL,thisR,nextL,nextR -; -; -; -; -; -; -; -AdvEllP20 - SaveRetAdr - - ADD R11,WsPtr,#EllBlk - LDMIA R11,{R0-R7} ;Load ellipse parm block - - SUB R7,R7,R1 ;Sqroot(MaxYSqr-EllYSqr) - MOV R11,#24 ;Use 24 instead of 16 iterations in the - BL SquareRootAlt ; SquareRoot routine, gives result [0bb.b] - - ;Mult by axis ratio - MOV R7,R6 ; [0bb.b] * [0bb.b] - MUL R9,R7,R8 ; Result in R9 is [bb.bb] - - ADD R10,R3,R9 ;NextR [bb.bb] - ADD R10,R10,#&8000 - MOV R10,R10,ASR #16 ; [00bb] - - SUB R9,R3,R9 ;NextL [bb.bb] - ADD R9,R9,#&8000 - MOV R9,R9,ASR #16 ; [00bb] - - ADD R1,R1,R2 ;New value of EllYSqr by adding oddno - ADD R2,R2,#2 ;Next oddno in sequence - - ADD R3,R3,R5 ;XOffSet for next scanline - SUB R0,R0,#1 ;Decrement count of slices left - ADD R4,R4,#1 ;Increment EllY - - ADD R11,WsPtr,#EllBlk - STMIA R11,{R0,R1,R2,R3,R4} ;Save updated section - - Return ; R4 , R9 , R10 - ; ellY, nextL,nextR - -; -; -; -;------------------------------------------------------------------------------ - - - END diff --git a/s/vdu/vdugrafd b/s/vdu/vdugrafd deleted file mode 100644 index fe688d74..00000000 --- a/s/vdu/vdugrafd +++ /dev/null @@ -1,592 +0,0 @@ -; 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.VduGrafD - -; -; ARTHUR OPERATING SYSTEM - Vdu Drivers -; ======================= -; -; Vdu driver code - Block Copy and Move -; -; Author R C Manby -; Date 2.10.86 -; - -; ***************************************************************************** -; -; BlockCopyMove - Copy/Move a rectangular area -; -; in: OldCs marks start of area to copy/move -; ICursor marks end of area to copy/move -; NewPt is lower left of destination area -; R2 = plot number &B8..&BF -; -; out: R0..R11 corrupt -; - -BlockCopyMove ROUT - TST R2, #3 ; Do nowt on 'MoveOnly' codes - MOVEQ PC, R14 - - SaveRetAdr - - ADD R0, WsPtr, #BgEcfStore ; Select 'store' in background - STR R0, [WsPtr, #GColAdr] ; to be used by HLine when - ; clearing source & dest lines - -; Build up source & destination data as follows -; -; R0 R1 R2 R3 R4 R5 R6 R7 R8 -; SrcL,SrcB,SrcR,SrcT,DestL,DestB,DestR,DestT,CopyFlag - - AND R8, R2, #2 ; 0/2 means Move/Copy - - ADD R11, WsPtr, #OldCsX - LDMIA R11, {R0,R1, R2,R3, R4,R5} ; OldCs, ICursor, NewPt - - SortT R0, R2, R6 ; Order SrcL,SrcB,SrcR,SrcT - SortT R1, R3, R6 ; R0 , R1 , R2 , R3 - - SUB R6, R2, R0 - ADD R6, R6, R4 ; DestR := SrcR-SrcL+DestL - - SUB R7, R3, R1 - ADD R7, R7, R5 ; DestT := SrcT-SrcB+DestB - - ADD R11, WsPtr, #CMSrc - STMIA R11, {R0-R7,R8} ; Unclipped src & dest areas - ; and CopyFlag - LDR R11, [WsPtr, #CursorFlags] - TST R11, #ClipBoxEnableBit - BLNE ClipBlockCopyMove - -; now work out ACTUAL area to copy -; first, we window destination area - - LDR R10, [WsPtr, #GWLCol] - LDR R11, [WsPtr, #GWRCol] - - SUBS R8, R10, R4 ; R8 = GWLCol - DestL - ADDGT R4, R4, R8 ; if > 0 then DestL := GWLCol - ADDGT R0, R0, R8 ; and adjust SrcL to match - - SUBS R8, R6, R11 ; R8 = DestR - GWRCol - SUBGT R6, R6, R8 ; if > 0 then DestR := GWRCol - SUBGT R2, R2, R8 ; and adjust SrcR to match - - CMP R6, R4 ; check DestR >= DestL - BLT EraseSource ; if not then just erase source - ; if a block move - - STR R4, [WsPtr, #CMDest2L] ; save horizontal dest coords - STR R6, [WsPtr, #CMDest2R] ; windowed at dest - - SUBS R8, R10, R0 ; R8 = GWLCol - SrcL - ADDGT R0, R0, R8 ; if > 0 then SrcL := GWLCol - ADDGT R4, R4, R8 ; and adjust DestL to match - - SUBS R8, R2, R11 ; R8 = SrcR - GWRCol - SUBGT R2, R2, R8 ; if > 0 then SrcR := GWRCol - SUBGT R6, R6, R8 ; and adjust DestR to match - - LDR R10, [WsPtr, #GWBRow] - LDR R11, [WsPtr, #GWTRow] - - SUBS R8, R10, R5 ; R8 = GWBRow - DestB - ADDGT R5, R5, R8 ; if > 0 then DestB := GWBRow - ADDGT R1, R1, R8 ; and adjust SrcB to match - - SUBS R8, R7, R11 ; R8 = DestT - GWTRow - SUBGT R7, R7, R8 ; if > 0 then DestT := GWTRow - SUBGT R3, R3, R8 ; and adjust SrcT to match - - CMP R7, R5 ; check DestT >= DestB - BLT EraseSource ; if not then just erase source - ; if a block move - - STR R5, [WsPtr, #CMDest2B] ; save vertical dest coords - STR R7, [WsPtr, #CMDest2T] ; windowed at dest - - SUBS R8, R10, R1 ; R8 = GWBRow - SrcB - ADDGT R1, R1, R8 ; if > 0 then SrcB := GWBRow - ADDGT R5, R5, R8 ; and adjust DestB to match - - SUBS R8, R3, R11 ; R8 = SrcT - GWTRow - SUBGT R3, R3, R8 ; if > 0 then SrcT := GWTRow - SUBGT R7, R7, R8 ; and adjust DestT to match - -; now R0-R3 is source windowed both ways -; R4-R7 is dest windowed both ways - - ADD R8, WsPtr, #CMDest3L - STMIA R8, {R4-R7} ; save destination windowed - ; both ways - - LDR R9, [WsPtr, #VduSprite] - - CMP R2, R0 ; check SrcR >= SrcL - SUBGES R8, R3, R1 ; and SrcT >= SrcB (R8=lines-1) - BLT EraseDest ; if not, then go to wiping out - ; destination stage - - STR R8, [WsPtr, #CMVertCount] ; no. of vertical lines -1 - - [ UseGraphicsV - BL CheckAcceleration ; okay to accelerate? - BNE %FT05 - -; not redirected to sprite - try calling GraphicsV for some acceleration - - Push "R2" - Push "R8" - SUB R14, R2, R0 - Push "R0,R1,R4,R5,R14" ; srcL,srcB,dstL,dstB,W-1,H-1 - MOV R0, #GVRender_Sync - MOV R1, #GVRender_CopyRectangle - MOV R2, R13 - MOV R4, #GraphicsV_Render - BL CallGraphicsV ; (R0,R1,R2,R4->R4) - TEQ R4, #GraphicsV_Complete ; did it do it? - Pull "R0,R1,R4" - ADD R13, R13, #3*4 - Pull "R2" - BEQ EraseDest ; then go straight to erase - ] - -05 LDR R9, [WsPtr, #Log2BPC] - LDR R10, [WsPtr, #XShftFactor] - LDR R11, [WsPtr, #NPix] - - MOV R8, R6, LSR R10 ; DestR word offset - SUB R8, R8, R4, LSR R10 ; -DestL word offset - STR R8, [WsPtr, #CMDestCount] ; No. of dest words -1 - - AND R8, R6, R11 ; R8 = DestR pixel offset - ADD R14, WsPtr,#RAMMaskTb - LDR R8, [R14, R8, LSL #2] ; R8 = mask for right pixel - SUB R14, R8, #1 ; In rh mask, set all bits lower than - ORR R14, R14, R8 ; pixel, RHM := RHM OR (RHM-1) - STR R14, [WsPtr, #CMRMask] - - AND R8, R4, R11 ; R8 = DestL pixel offset - ADD R14, WsPtr, #RAMMaskTb - LDR R8, [R14, R8, LSL #2] ; R8 = mask for left pixel - RSB R14, R8, #0 ; In lh mask, set all bits higher than - ORR R14, R14, R8 ; pixel, LHM := LHM OR (0-LHM) - STR R14, [WsPtr, #CMLMask] - - CMP R0, R4 ; test whether SrcL >= DestL - BLT SrcHLTDest - -; source is to the right of dest, so start at left hand side - - AND R8, R4, R11 ; R8 = DestL pixel offset - AND R14, R0, R11 ; R14 = SrcL pixel offset - SUB R11, R14, R8 ; R11 = Src-Dest pixel offset - MOV R11, R11, LSL R9 ; R11 = Src-Dest bit offset - - CMP R11, #0 ; if rightshift < 0 - ADDLT R11, R11, #32 ; if < 0, correct result - MOVGE R10, #0 - MOVLT R10, #-4 ; and subtract 4 off src addr - - STR R11, [WsPtr, #CMRShift] - RSB R11, R11, #32 - STR R11, [WsPtr, #CMLShift] - - LDR R6, [WsPtr, #LineLength] ; (no longer need DestR) - - CMP R1, R5 ; if SrcB >= DestB - RSBGE R6, R6, #0 ; then go upwards - STR R6, [WsPtr, #CMVertDir] - - MOVLT R1, R3 ; else go down - MOVLT R5, R7 ; so use top coords - - BL ScreenAddr ; R2 = address of src corner - ADD R2, R2, R10 - STR R2, [WsPtr, #CMSourceAddr] - - MOV R0, R4 - MOV R1, R5 - BL ScreenAddr ; R2 = address of dest corner - STR R2, [WsPtr, #CMDestAddr] - - ADD R11, WsPtr, #CMStuff - LDMIA R11, {R0-R6} ; src,dest,cnt,rtshf,lfshf,rtmsk,ltmsk -10 - TEQ R2, #0 ; only one word on a line ? - ANDEQ R5, R5, R6 ; then rightmask:=rightmask AND lftmask - LDREQ R14, [R0], #4 ; and load first word up - BEQ %FT45 ; and do endword - -; do first word - - LDMIA R0!, {R11,R14} ; load 2 words - ShiftR R11, R14, R3, R4 ; shift them - AND R11, R11, R6 ; AND with leftmask - LDR R10, [R1] ; load word from dest - BIC R10, R10, R6 ; clear out bits in leftmask - ORR R10, R10, R11 ; OR in new bits - STR R10, [R1], #4 - SUBS R2, R2, #1 ; decrement count - BEQ %FT40 ; if zero, do finish word - - SUBS R2, R2, #7 ; can we do 7 words ? - BCC %FT30 ; no, then do 1 word at a time - -; do 7 words at a time - - TEQ R3, #0 ; if rightshf = 0 - BEQ %FT60 ; then do non-shifting version -20 - [ {TRUE} ; TMD optimisation 12-May-93 - MOV R5, R14, LSR R3 - LDMIA R0!, {R6-R11,R14} - ORR R5, R5, R6, LSL R4 - | - MOV R5, R14 - LDMIA R0!, {R6-R11,R14} ; load next 7 words - ShiftR R5, R6, R3, R4 - ] - ShiftR R6, R7, R3, R4 - ShiftR R7, R8, R3, R4 - ShiftR R8, R9, R3, R4 - ShiftR R9, R10, R3, R4 - ShiftR R10, R11, R3, R4 - ShiftR R11, R14, R3, R4 - STMIA R1!, {R5-R11} - SUBS R2, R2, #7 - BCS %BT20 - -30 - ADDS R2, R2, #7 - BEQ %FT40 ; if count expired, do last word - -; do 1 word at a time - -35 - MOV R5, R14 - LDR R14, [R0], #4 - ShiftR R5, R14, R3, R4 - STR R5, [R1], #4 - SUBS R2, R2, #1 - BNE %BT35 - -; do last word - -40 - LDR R5, [WsPtr, #CMRMask] ; load right mask -45 - -; now test if any bits would be used (so we don't go off end of memory) - - MOV R11, #&FFFFFFFF - TST R5, R11, LSL R4 ; NE => safe to read from here - LDRNE R11, [R0], #4 ; R14 = left word; R11 = right word - ShiftR R14, R11, R3, R4 ; form single word - AND R14, R14, R5 ; mask source word - LDR R10, [R1] ; load dest word - BIC R10, R10, R5 ; mask dest word - ORR R10, R10, R14 ; OR two words - STR R10, [R1], #4 ; store back - -; now go on to next row - - LDR R7, [WsPtr, #CMVertCount] - SUBS R7, R7, #1 - BCC EraseDest ; finished, so go to erase dest stage - STR R7, [WsPtr, #CMVertCount] - ADD R11, WsPtr, #CMStuff - LDMIA R11, {R0-R6} ; load up info again - LDR R7, [WsPtr, #CMVertDir] - ADD R0, R0, R7 ; move source pointer - ADD R1, R1, R7 ; and dest pointer - STMIA R11, {R0,R1} ; store these back - B %BT10 ; and loop - -; non-shifting version, for speed -; do 7 words at a time - -60 - MOV R5, R14 - LDMIA R0!, {R6-R11,R14} ; load next 7 words - STMIA R1!, {R5-R11} - SUBS R2, R2, #7 - BCS %BT60 - ADDS R2, R2, #7 - BNE %BT35 ; count not expired, do last few words - B %BT40 ; count expired, do last word - -; ***************************************************************************** - -; source is to the left of dest, so start at right hand side - -SrcHLTDest ROUT - MOV R0, R2 ; rt coords are relevant ones - MOV R4, R6 - - AND R8, R4, R11 ; R8 = DestR pixel offset - AND R14, R0, R11 ; R14 = SrcR pixel offset - SUB R11, R14, R8 ; R11 = Src-Dest pixel offset - MOV R11, R11, LSL R9 ; R11 = Src-Dest bit offset - - RSB R11, R11, #32 ; R11 = leftshift - CMP R11, #32 ; if >= 32 - SUBCS R11, R11, #32 ; then put in range - MOVCC R10, #4 ; else add 4 - MOVCS R10, #0 ; to src addr - - STR R11, [WsPtr, #CMLShift] - RSB R11, R11, #32 - STR R11, [WsPtr, #CMRShift] - - LDR R6, [WsPtr, #LineLength] ; (no longer need R6) - - CMP R1, R5 ; if SrcB >= DestB - RSBGE R6, R6, #0 ; then go upwards - STR R6, [WsPtr, #CMVertDir] - - MOVLT R1, R3 ; else go down - MOVLT R5, R7 ; so use top coords - - BL ScreenAddr ; R2 = address of src corner - ADD R2, R2, R10 - STR R2, [WsPtr, #CMSourceAddr] - - MOV R0, R4 - MOV R1, R5 - BL ScreenAddr ; R2 = address of dest corner - STR R2, [WsPtr, #CMDestAddr] - - ADD R11, WsPtr, #CMStuff - LDMIA R11, {R0-R6} ; src,dest,cnt,rtshf,lfshf,rtmsk,ltmsk -10 - TEQ R2, #0 ; only one word on a line ? - ANDEQ R6, R6, R5 ; then leftmask:=leftmask AND rightmask - LDREQ R5, [R0], #-4 ; and load first word up - BEQ %FT45 ; and do endword - -; do first word - - LDMDA R0!, {R11,R14} ; load 2 words - ShiftL R11, R14, R3, R4 ; shift them - AND R14, R14, R5 ; AND with rightmask - LDR R10, [R1] ; load word from dest - BIC R10, R10, R5 ; clear out bits in rightmask - ORR R10, R10, R14 ; OR in new bits - STR R10, [R1], #-4 - MOV R5, R11 - SUBS R2, R2, #1 ; decrement count - BEQ %FT40 ; if zero, do finish word - - SUBS R2, R2, #7 ; can we do 7 words ? - BCC %FT30 ; no, then do 1 word at a time - -; do 7 words at a time - - TEQ R4, #0 ; if leftshf=0 - BEQ %FT60 ; then do non-shifting version -20 - [ {TRUE} ; TMD optimisation 12-May-93 - MOV R14, R5, LSL R4 - LDMDA R0!, {R5-R11} - ORR R14, R14, R11, LSR R3 - | - MOV R14, R5 - LDMDA R0!, {R5-R11} ; load next 7 words - ShiftL R11, R14, R3, R4 - ] - ShiftL R10, R11, R3, R4 - ShiftL R9, R10, R3, R4 - ShiftL R8, R9, R3, R4 - ShiftL R7, R8, R3, R4 - ShiftL R6, R7, R3, R4 - ShiftL R5, R6, R3, R4 - STMDA R1!, {R6-R11,R14} - SUBS R2, R2, #7 - BCS %BT20 - -30 - ADDS R2, R2, #7 - BEQ %FT40 ; if count expired, do last word - -; do 1 word at a time - -35 - MOV R14, R5 - LDR R5, [R0], #-4 - ShiftL R5, R14, R3, R4 - STR R14, [R1], #-4 - SUBS R2, R2, #1 - BNE %BT35 - -; do last word - -40 - LDR R6, [WsPtr, #CMLMask] ; load left mask -45 - -; now test if any bits would be used (so we don't go off start of memory) - - MOV R11, #&FFFFFFFF - TST R6, R11, LSR R3 ; NE => safe to read from here - LDRNE R11, [R0], #-4 ; R11 = left word; R5 = right word - ShiftL R11, R5, R3, R4 ; form single word - AND R5, R5, R6 ; mask source word - LDR R10, [R1] ; load dest word - BIC R10, R10, R6 ; mask dest word - ORR R10, R10, R5 ; OR two words - STR R10, [R1], #-4 ; store back - -; now go on to next row - - LDR R7, [WsPtr, #CMVertCount] - SUBS R7, R7, #1 - BCC EraseDest ; finished, so go to erase dest stage - STR R7, [WsPtr, #CMVertCount] - ADD R11, WsPtr, #CMStuff - LDMIA R11, {R0-R6} ; load up info again - LDR R7, [WsPtr, #CMVertDir] - ADD R0, R0, R7 ; move source pointer - ADD R1, R1, R7 ; and dest pointer - STMIA R11, {R0,R1} ; store these back - B %BT10 ; and loop - -; non-shifting version, for speed -; do 7 words at a time - -60 - MOV R14, R5 - LDMDA R0!, {R5-R11} ; load next 8 words - MOV R11, R11 - ! 0, "Block copy has dummy instruction for XScale weirdness" - STMDA R1!, {R6-R11,R14} - SUBS R2, R2, #7 - BCS %BT60 - ADDS R2, R2, #7 - BNE %BT35 ; count not expired, do last few words - B %BT40 ; count expired, do last word - -; ***************************************************************************** - -; Erase the area Dest2\Dest3 - -EraseDest ROUT - -; first do the flat rectangle - - ADD R8, WsPtr, #CMDest2L - LDMIA R8, {R0-R7} ; R0..R3 = Dest2; R4..R7 = Dest3 - BL EraseDifference - -; and drop thru to ... - -EraseSource - LDR R8, [WsPtr, #CMCopyFlag] ; 0 => move, 2 => copy - TEQ R8, #0 ; is it a move - Return NE ; no, then exit - - ADD R8, WsPtr, #CMSrc ; R0..R3 = unclipped src - LDMIA R8, {R0-R7} ; R4..R7 = unclipped dest - -; window both source and destination in source domain - - LDR R10, [WsPtr, #GWLCol] - LDR R11, [WsPtr, #GWRCol] - - SUBS R8, R10, R0 ; R8 = GWLCol - SrcL - ADDGT R0, R0, R8 ; if > 0 then SrcL := GWLCol - ADDGT R4, R4, R8 ; and adjust DestL to match - - SUBS R8, R2, R11 ; R8 = SrcR - GWRCol - SUBGT R2, R2, R8 ; if > 0 then SrcR := GWRCol - SUBGT R6, R6, R8 ; and adjust DestR to match - - CMP R2, R0 ; check SrcR >= SrcL - Return LT ; if not then nothing to erase - - LDR R10, [WsPtr, #GWBRow] - LDR R11, [WsPtr, #GWTRow] - - SUBS R8, R10, R1 ; R8 = GWBRow - SrcB - ADDGT R1, R1, R8 ; if > 0 then SrcB := GWBRow - ADDGT R5, R5, R8 ; and adjust DestB to match - - SUBS R8, R3, R11 ; R8 = SrcT - GWTRow - SUBGT R3, R3, R8 ; if > 0 then SrcT := GWTRow - SUBGT R7, R7, R8 ; and adjust DestT to match - - CMP R3, R1 ; check SrcT >= SrcB - Return LT ; if not then nothing to erase - -; now window the dest coords to the source - - CMP R7, R3 ; if DestT >= SrcT - MOVGE R7, R3 ; then DestT := SrcT - MOVLT R5, R1 ; else DestB := SrcB - CMP R6, R2 ; if DestR >= SrcR - MOVGE R6, R2 ; then DestR := SrcR - MOVLT R4, R0 ; else DestL := SrcL - - Pull R14 - -; and drop thru to ... - -; ***************************************************************************** -; -; EraseDifference - Erase the difference between two rectangles with at -; least one vertical and one horizontal shared boundary -; -; in: R0-R3 = larger one -; R4-R7 = smaller one -; - -EraseDifference ROUT - -; first do the flat rectangle - - CMP R6, R4 ; check for Dest3 being null - CMPGE R7, R5 - BLT RectFillA ; if is, just clear Dest2 - - Push "R0-R7,R14" - - TEQ R3, R7 ; if Dest2T = Dest3T - SUBEQ R3, R5, #1 ; then top = Dest3B -1 - ADDNE R1, R7, #1 ; else bottom = Dest3T +1 - CMP R3, R1 ; if top >= bottom - BLGE RectFillA - -; now do the tall rectangle - - Pull "R0-R7" - - TEQ R3, R7 ; if Dest2T = Dest3T - MOVEQ R1, R5 ; then bottom = Dest3B - MOVNE R3, R7 ; else top = Dest3T - - TEQ R0, R4 ; if Dest2L = Dest3L - ADDEQ R0, R6, #1 ; then left = Dest3R +1 - SUBNE R2, R4, #1 ; else right = Dest3L -1 - - CMP R3, R1 ; if top >= bottom - CMPGE R2, R0 ; and right >= left - BLGE RectFillA ; then fill it - - Pull PC - - - END diff --git a/s/vdu/vdugrafdec b/s/vdu/vdugrafdec deleted file mode 100644 index d7311c39..00000000 --- a/s/vdu/vdugrafdec +++ /dev/null @@ -1,308 +0,0 @@ -; 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.VduGrafDec -; -; ARTHUR OPERATING SYSTEM - Vdu Drivers -; ======================= -; -; Graphics workspace and macro declarations -; -; Author R C Manby -; Date 5.9.86 -; - - GBLL UseNewerHLine -UseNewerHLine SETL 1=1 - - -; -; Graphics work space, overlaid in main vdu w/s area -; - - - ^ GraphicWs - -Line1Blk # 4*9 ;Parameter block for a crudeline - ASSERT @ < EndGraphicWs - - - ^ GraphicWs - -LineBlk # 4*5 ;Parameter block for a crudeline - -LineEcfBase # 4 ; -- -LineEcfIndx # 4 ; | -LineDeltaY # 4 ; | -LineScanStp # 4 ; -- - -LineEndPtFlags # 4 ;Bit0 set - plot start pt, bit1 set - plot end pt -LineDotPtr # 4 ;Holds 0/Adr(LineDotCnt) for Solid/Dotted lines - -DotCycleStartX # 4 -DotCycleStartY # 4 -DotCycleEndX # 4 -DotCycleEndY # 4 -DotCycleCount # 4 -PostCycleCount # 4 - -;The following are defined in Hdr.System -; LineDotCnt # 4 ;Count down to restarting pattern -; LineDotPatLSW # 4 ;Current state of pattern LSWord -; LineDotPatMSW # 4 ; " " " " MSWord - ASSERT @ < EndGraphicWs - - - ^ GraphicWs - -TLine1 # 4*9 ;Line parameters used by Tri & Par fill -TLine2 # 4*9 -TEndY # 4 -Vertex1X # 4 ; -- -Vertex1Y # 4 ; | -Vertex2X # 4 ; | -Vertex2Y # 4 ; | -Vertex3X # 4 ; | -Vertex3Y # 4 ; | -Vertex4X # 4 ; | -Vertex4Y # 4 ; -- - ASSERT @ < EndGraphicWs - - - ^ GraphicWs - -CircleBlk # 4*8 ;Parameter block for circle arc segments etc -- -CLine0 # 4*9 ;Line parameters used by Arc, Segment & Sector | -CLine1 # 4*9 ; -- -CLine2 # 4*9 ;CLine2 & CLine3 used only for segments -CLine3 # 4*9 ; - -UpperSegLinePtr # 4 ;Address of CLine2 or 0 - used only for segments -LowerSegLinePtr # 4 ;Address of CLine3 or 0 - used only for segments - -CircleRadSquare # 4 ;Square of radius of circle - -CLine0EndX * CLine0+7*4 -CLine0EndY * CLine0+8*4 -CLine1EndX * CLine1+7*4 -CLine1EndY * CLine1+8*4 -CLine0Far * CLine0 -CLine0Near * CLine0EndX -CLine1Far * CLine1 -CLine1Near * CLine1EndX - -Quad0Control # 1 ;Control bytes for each quadrant for -- -Quad1Control # 1 ; Arc, Segment & Sector plotting | -Quad2Control # 1 ; | -Quad3Control # 1 ; | - ; | -Quad0StateChange # 1 ;Flag to indicate line/circle | -Quad1StateChange # 1 ; intersection | -Quad2StateChange # 1 ; | -Quad3StateChange # 1 ; | - ; | -Quad0Draw # 1 ;Controls point/line plotting | -Quad1Draw # 1 ; | -Quad2Draw # 1 ; | -Quad3Draw # 1 ; -- - -ArcPoint0X # 4 ; -- -ArcPoint0Y # 4 ; | -ArcPoint1X # 4 ; | -ArcPoint1Y # 4 ; | -ArcPoint2X # 4 ; | -ArcPoint2Y # 4 ; | -ArcPoint3X # 4 ; | -ArcPoint3Y # 4 ; -- - - ASSERT @ < EndGraphicWs - - - ^ GraphicWs - -EllBlk # 4*8 ;Parameter block for ellipses - -EllBlkSliceCnt * EllBlk -EllBlkEllY * EllBlk + 4*4 - - -EllPrevL # 4 ;Slice limits for previous line -- -EllPrevR # 4 ; | -EllThisL # 4 ; current line | -EllThisR # 4 ; | -EllNextL # 4 ; next line | -EllNextR # 4 ; -- - -EllHLineWs # 4*5 ;This could be pushed to the stack -EllDoubleHLineWs # 4*5 ;This could be pushed to the stack - ASSERT @ < EndGraphicWs - - - ^ GraphicWs - -CMSrc # 4*4 ;Unclipped source area -- -CMDest # 4*4 ;Unclipped destination area | -CMCopyFlag # 4 ; 0/2 means Move/Copy area -- - -CMDest2L # 4 ; destination coords clipped at dest -CMDest2B # 4 -CMDest2R # 4 -CMDest2T # 4 -CMDest3L # 4 ; destination coords clipped both ways -CMDest3B # 4 -CMDest3R # 4 -CMDest3T # 4 - -CMStuff # 0 ; these 7 loaded together -CMSourceAddr # 4 ; source screen address -CMDestAddr # 4 ; destination screen address -CMDestCount # 4 ; no. of destination words per line -1 -CMRShift # 4 ; LSR shift factor -CMLShift # 4 ; LSL shift factor -CMRMask # 4 ; right mask -CMLMask # 4 ; left mask - -CMVertCount # 4 ; no. of lines to do -1 -CMVertDir # 4 ; offset to add to source/dest on each line - - ASSERT @ < EndGraphicWs - - - ^ GraphicWs - -LineFillBlk # 4 * 11 - -FldLeftXLimit # 4 ;-- -FldY # 4 ; | -FldRightXLimit # 4 ;-- - -FldBoundaryCol # 4 -FldBoundaryFlag # 4 -FldYWindLimit # 4 - -QueuePtrs # 4*4 ; head, tail, end, start - -FldSaveArea # 5*4 ; saved Y, target colour, NPix, zgora, zgeor -FldSaveY * FldSaveArea +0 - -FldStackLevel # 4 - [ med_00001_userma -flood_cda_rma # 4 ; amount we've changed the rma size by - ] - - ASSERT @ < EndGraphicWs - - - ^ GraphicWs - -RetnReg0 # 4 ;Save area for SWI SpriteOp -- -RetnReg1 # 4 ; | -RetnReg2 # 4 ; | -RetnReg3 # 4 ; | -RetnReg4 # 4 ; | -RetnReg5 # 4 ; | -RetnReg6 # 4 ; | -RetnReg7 # 4 ; | -RetnReg8 # 4 ; | -RetnReg9 # 4 ; | -RetnLink # 4 ; -- - -SprReadNColour # 4 ;Vdu vars for the mode the -- -SprWriteNColour # 4 ; the sprite is in | -SprBytesPerChar # 4 ; | -SprXShftFactor # 4 ; | -SprNPix # 4 ; | -SprLog2BPC # 4 ; -- - -NameBuf # 16 ; 12 char name + gap for good measure - -SpriteWs # 0 - - - - ^ SpriteWs ;Sprite plot & ScreenLoad - -SPltWidth # 4 ;Don't try re-arranging this lot unless -SPltHeight # 4 ; you fully understand the code!! -SPltScrOff # 4 -SPltMemOff # 4 -SPltScrAdr # 4 -SPltColCnt # 4 -SPltMemAdr # 4 -SPltShftR # 4 -SPltShftL # 4 -SPltMskAdr # 4 -SPltLMask # 4 -SPltRMask # 4 -; SPltzgooPtr # 4 -SPltEcfPtr # 4 -SPltEcfIndx # 4 -SPltPixPerWord # 4 -SPltBPP # 4 -SPltMaskBit # 4 -SPltMaskPtr # 4 -SPltMaskRowBit # 4 -SPltMaskRowPtr # 4 -SPltMaskRowLen # 4 - -SPltzgooMasks # 16 ; zgoo, zgeo, zgoe, zgee - -ScrLoaHandle # 4 ; -- -ScrLoaBufAdr # 4 ; | -ScrLoaBytes # 4 ; | -ScrLoaFilPtr # 4 ; | -ScrLoaFilOfst # 4 ; -- - -ScrLoaAreaCB # SpriteAreaCBsize - -SPltAction # 4 ; Plot action used (0 => store) - -SloadModeSel # 48 ; Mode selector for screenloading new sprites - - ASSERT @ < EndGraphicWs - - - ^ SpriteWs ;SGet,SCreate & ScreenSave - -SGetTopLeft # 8 ; top and left of 'on screen' area - -SGetTopMargin # 4 -SGetBotMargin # 4 -SGetLWrdMargin # 4 -SGetLBitMargin # 4 -SGetRWrdMargin # 4 -SGetRBitMargin # 4 - -SGetColWCnt # 4 -SGetRowOfst # 4 -SGetEcfIndx # 4 - -SGetNext # 4 ; -- -SGetName # 12 ;Name is 3 words (12 chars) ; | -SGetWidth # 4 ; | -SGetHeight # 4 ; | -SGetLBit # 4 ; | -SGetRBit # 4 ; | -SGetImage # 4 ; | -SGetTrans # 4 ; | -SGetMode # 4 ; | -SGetPalette # 0 ; -- - - ASSERT @ < EndGraphicWs - - ^ ScrSavCommon -ScrSavAreaCB # SpriteAreaCBsize -ScrSavSpriteCB # SpriteCBsize + MaxSpritePaletteSize - - END diff --git a/s/vdu/vdugrafe b/s/vdu/vdugrafe deleted file mode 100644 index e899a1c2..00000000 --- a/s/vdu/vdugrafe +++ /dev/null @@ -1,995 +0,0 @@ -; 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.VduGrafE -; -; ARTHUR OPERATING SYSTEM - Vdu Drivers -; ======================= -; -; Vdu driver code - Line Fill L & R and Flood Fill -; -; Author R C Manby -; Date 17.10.86 -; - -; ***************************************************************************** -; -; FillLRnonBg -; =========== -; -; On entry, R0 (X), R1 (Y) hold point to fill from -; -; On exit, R0..R11 corrupt -; - -FillLRtoFg - ADD R2, WsPtr, #FgEcf - MOV R3, #0 - B FillLRnonBg10 ; Fill L <-> R - -FillLRnonBg - ADD R2, WsPtr, #BgEcf - MOV R3, #&80000000 -FillLRnonBg10 - SaveRetAdr - BL FillAlong2 - SUBCS R1, R1, #1 ; indicate nothing filled by Y-=1 - STR R0, [WsPtr, #GCsIX] ; left X - STR R1, [WsPtr, #GCsIY] ; Y - Return CS ; external new pt hasn't changed - STR R2, [WsPtr, #NewPtX] ; right X - MOV R0, R2 - BL IEGB ; update external version of new NewPt - Return ; then things get shuffled - -; ***************************************************************************** -; -; FillLRtoBg (Really only fill right!) -; ========== -; -; On entry, R0 (X), R1 (Y) hold point to fill from -; -; On exit, R0..R11 corrupt -; - -FillLRnonFg - ADD R2, WsPtr, #FgEcf - MOV R3, #&80000000 - B FillLRtoBg10 ; Fill -> R - -FillLRtoBg - ADD R2, WsPtr, #BgEcf - MOV R3, #&0 -FillLRtoBg10 - SaveRetAdr - STR R0, [WsPtr, #GCsIX] ; "left hand point" = given point - STR R1, [WsPtr, #GCsIY] - BL GenLineFillParm ; if C=1 (nothing can be plotted) - SUBCS R0, R0, #1 ; then NewPtX-=1 ie NewPtX < GCsIX - BLCC FillLineRightRegs ; else fill right - STR R0, [WsPtr, #NewPtX] ; Convert NewPt(X,Y) (internal) into - LDR R1, [WsPtr, #NewPtY] ; GCs(X,Y) (external) - BL IEGB - Return ; On returning, cursors are shuffled - ; which updates GCsI(X,Y) - -; ***************************************************************************** -; -; GenLineFillParm -; =============== -; -; On entry, R0 (X), R1 (Y) hold point to fill from -; R2 points to delimiting colour (FgEcf/BgEcf) -; R3 fill flag, 0/&80000000 for fill to/to-non -; -; On exit, Carry=0, valid parameter setup, R0-R10 contain copy of control block -; Carry=1, point outside window, R0 preserved, R1-R10 undefined -; -; Format of control block -; -; R0 - StartX -; R1 - DelimitColour -; R2 - FillFlag -; R3 - ScreenAdr -; R4 - PixelMsk -; R5 - zgora -; R6 - zgeor -; R7 - GWLCol -; R8 - GWRCol -; R9 - BytesPerChar -; R10 - NPix -; -GenLineFillParm - WINDow R0,R1, R7,R8,R9,R10 ; Window(R0,R1) using R7-R10 - ; gives GE if in window - [ No26bitCode - BGE %FT01 - SEC ; If point outside window - MOV PC, Link ; then quit with carry set -01 - | - ORRLTS PC, Link, #C_bit ; If point outside window - ; then quit with carry set - ] - Push "R2,R3,R7,R9,Link" ; Save colourptr, fillflag - ; GWLCol, GWRCol - BL ScreenAddr ; Returns R2 = Addr, R3 = Mask - - LDR R9, [WsPtr, #YWindLimit] - SUB R9, R9, R1 ; Flip Ycoord - AND R9, R9, #7 ; Line within ecf - LDR R5, [WsPtr, #GColAdr] ; Base address of ecf pattern - ADD R5, R5, R9, LSL #3 - LDMIA R5, {R5, R6} ; Get zgora,zgeor - - MOV R4, R3 - MOV R3, R2 - - Pull "R1,R2,R7,R8,Link" ; restore other registers - LDR R1, [R1, R9, LSL #2] ; load delimiting colour - LDR R9, [WsPtr, #BytesPerChar] - LDR R10, [WsPtr, #NPix] - - ADD R11, WsPtr, #LineFillBlk ; now save completed control block - STMIA R11, {R0-R10} - - LDR R11, [R3] ; load screen - EOR R11, R11, R1 ; screen EOR boundary - TST R11, R4 ; just look at this pixel - [ No26bitCode - ; Blimey. - MRS R7, CPSR - TEQ R2, R7, LSL #1 ; N := (Z EOR R2) ie invert test if - ; stopping on non-colour - BICPL R7, R7, #C_bit ; point can be filled, exit CC - ORRMI R7, R7, #C_bit ; point cannot be filled, exit CS - MSR CPSR_f, R7 - MOV PC, Link - | - TEQ R2, PC, LSL #1 ; N := (Z EOR R2) ie invert test if - ; stopping on non-colour - BICPLS PC, Link, #C_bit ; point can be filled, exit CC - ORRMIS PC, Link, #C_bit ; point cannot be filled, exit CS - ] - -; ***************************************************************************** -; -; FillLineRight - Fill right from point upto delimiting colour -; ============= or graphics window -; -; -; R0 - RightLimitX -; R1 - LimitColour -; R2 - FillFlag -; R3 - ScreenAdr -; R4 - PixelMsk -; R5 - zgora -; R6 - zgeor -; R7 - GWLCol /BPC/NPIX -; R8 - GWRCol -; R9 - ScreenWord -; R10 - NPix -; R11 - MultPixMsk / temp -; -; out: PSR must be preserved -; -FillLineRight ROUT - ADD R11, WsPtr, #LineFillBlk - LDMIA R11, {R0-R10} -FillLineRightRegs - Push R14 - [ No26bitCode - MRS R14, CPSR - Push "WsPtr, R14" ; we also need R12 for a temp - ] - RSB R7, R9, #32 ; shift factor for next pixel position - SUB R0, R8, R0 -10 - MOV R11, #0 ; clear partial word mask - LDR R9, [R3] ; screen word EOR delimit colour - EOR R14, R9, R1 -30 - TST R14, R4 ; test pixel position for delimiting - [ No26bitCode - MRS WsPtr, CPSR - TEQ R2, WsPtr, LSL #1 ; invert condition if necessary - | - TEQ R2, PC, LSL #1 ; invert condition if necessary - ] - - ORRPL R11, R11, R4 ; add pixel to partial word mask - SUBPLS R0, R0, #1 ; "increment" X; if on edge of window - BMI %FT40 ; then give up and plot partial word - - TEQ R4, #0 ; test for end of word - MOV R4, R4, ROR R7 ; shift pixel mask left - BPL %BT30 - - AND R14, R5, R11 ; fill partial word, using pixel mask - AND R11, R6, R11 ; in R11 - ORR R9, R9, R14 - EOR R9, R9, R11 - STR R9, [R3], #4 - - CMP R2, #2 ; CC => filling until pixel=target - BCC %BT10 ; so do it slowly (goto next word) - - RSB R0, R0, #0 ; make X in range GWLCol-GWRCol .. 0 - ADDS R0, R0, R10 ; move R0 to end of word - BGT %FT36 ; outside window, continue slowly - - ORR R14, R1, R5 ; word to store if going fast - EOR R14, R14, R6 - -32 - LDR R9, [R3] ; screen word - CMP R9, R1 ; EOR target colour (CS if EQ) - BNE %FT36 - STR R14, [R3], #4 - ADCS R0, R0, R10 ; C=1, so add NPix+1 - BLE %BT32 -36 - SUBS R0, R10, R0 ; R0 back to start of word and negate - BGE %BT10 ; if still inside, continue slowly - B %FT50 - -40 - AND R14, R5, R11 ; fill partial word, using pixel mask - AND R11, R6, R11 ; in R11 - ORR R9, R9, R14 - EOR R9, R9, R11 - STR R9, [R3] -50 - SUB R0, R8, R0 ; make back into normal coord again - SUB R0, R0, #1 ; correct end point - [ No26bitCode - Pull "WsPtr, R14" - MSR CPSR_f, R14 - Pull PC - | - Pull R14 - MOVS PC, R14 - ] - -; ***************************************************************************** -; -; FillLineLeft - Fill left from point upto delimiting colour -; ============ or graphics window -; -; N.B. Starts one pixel left of point given, since -; FillLineRight will have already plotted it. -; -; R0 - LeftLimitX -; R1 - LimitColour -; R2 - FillFlag -; R3 - ScreenAdr -; R4 - PixelMsk -; R5 - zgora -; R6 - zgeor -; R7 - GWLCol } Slightly different from FillLineRight -; R8 - GWRCol /BPC/NPIX } -; R9 - ScreenWord -; R10 - LimitEorScreen / temp -; R11 - MultPixMsk / temp -; -; -; -FillLineLeft ROUT - ADD R11, WsPtr, #LineFillBlk - LDMIA R11, {R0-R10} -FillLineLeftRegs - Push R14 - [ No26bitCode - MRS R14, CPSR - Push "WsPtr, R14" ; also need WsPtr for a temp - ] - MOV R8, R9 ; shift factor for next pixel position - - SUB R0, R0, R7 - LDR R9, [R3] ; screen word EOR delimit colour - EOR R14, R9, R1 - MOVS R11, #0 ; clear partial word mask (and set PL) - B %FT31 - -10 - MOV R11, #0 ; clear partial word mask - LDR R9, [R3] ; screen word EOR delimit colour - EOR R14, R9, R1 - -30 - TST R14, R4 ; test pixel position for delimiting - [ No26bitCode - MRS WsPtr, CPSR - TEQ R2, WsPtr, LSL #1 ; invert condition if appropriate - | - TEQ R2, PC, LSL #1 ; invert condition if appropriate - ] - ORRPL R11, R11, R4 ; add pixel to partial word mask -31 - SUBPLS R0, R0, #1 ; decrement X; if on edge of window - BMI %FT40 ; then give up and plot partial word - - MOVS R4, R4, ROR R8 ; test for end of word - BPL %BT30 ; loop until mask exhausted - - AND R14, R5, R11 ; fill partial word, using pixel mask - AND R11, R6, R11 ; in R11 - ORR R9, R9, R14 - EOR R9, R9, R11 - STR R9, [R3], #-4 - - CMP R2, #2 ; CC => filling until pixel=target - BCC %BT10 ; so do it slowly (goto next word) - - SUBS R0, R0, R10 ; move R0 to beginning of word - BCC %FT36 ; if outside window continue slowly - ADD R10, R10, #1 - ORR R14, R1, R5 ; compute target word - EOR R14, R14, R6 -32 - LDR R9, [R3] ; screen word - CMP R9, R1 - BNE %FT35 ; NZ => terminate - STR R14, [R3], #-4 - SUBS R0, R0, R10 - BCS %BT32 -35 - SUB R10, R10, #1 -36 - ADDS R0, R0, R10 ; point R0 back to end of word - BGE %BT10 ; if still inside, continue but slowly - B %FT50 - -40 - AND R14, R5, R11 ; fill partial word, using pixel mask - AND R11, R6, R11 ; in R11 - ORR R9, R9, R14 - EOR R9, R9, R11 - STR R9, [R3] -50 - ADD R0, R0, R7 ; add GWLCol back on - ADD R0, R0, #1 ; Correct endpoint value - [ No26bitCode - Pull "WsPtr, R14" - MSR CPSR_f, R14 - Pull PC - | - Pull R14 - MOVS PC, R14 - ] - -; ***************************************************************************** -; -; FillAlong - Fill left and right from point given -; ========= -; -; On entry, R0 (X), R1(Y) hold point to fill from -; -; On exit, R0 (X) End of scan left -; R1 (Y) Preserved -; R2 (X) End of scan right -; -; Carry set = no fill performed ie outside window or already filled -; Carry clear = fill occured -; - ASSERT FldBoundaryFlag = FldBoundaryCol +4 - -FillAlong - ADD R2, WsPtr, #FldBoundaryCol - LDMIA R2, {R2,R3} ; R2 = colour, R3 = flag -FillAlong2 ; entry point when R2, R3 loaded - Push "R1, R14" - BL GenLineFillParm ; On exit C=1 if nothing can be plotted - BLCC FillLineRightRegs - Push R0 ; New RightX - BLCC FillLineLeft - Pull R2 ; Recover RightX - Pull "R1, PC" ; Recover Y, C=1 <=> fill occured - -; ***************************************************************************** -; -; FloodFill -; ========= -; -; On entry, R0 (X), R1 (Y) hold point to flood from -; R2 Delimit colour, pointer to FgEcf/BgEcf -; R3 0/&80000000 for flood until/over -; - ASSERT FldBoundaryFlag = FldBoundaryCol +4 - ASSERT FldY = FldLeftXLimit +4 - ASSERT FldRightXLimit = FldLeftXLimit +8 - -FloodToFg - ADD R2, WsPtr, #FgEcf ; delimit colour - MOV R3, #0 ; flood until - B FloodFill - -FloodNonBg - ADD R2, WsPtr, #BgEcf ; delimit colour - MOV R3, #&80000000 ; flood over -FloodFill ROUT - Push R14 - STR R13, [WsPtr, #FldStackLevel] ; save stack level ! - - ADD R14, WsPtr, #FldBoundaryCol - LDR R4, [WsPtr, #YWindLimit] - STMIA R14, {R2-R4} ; store colour, flag, YWindLimit - - [ med_00001_userma - - ; the idea here is to try to use between 48k and 128k of rma instead of 16k of - ; scratchspace. if there's less than 48k of rma in the first place we go back to - ; scratchspace. if there's 128k or more we claim the 128k and proceed. For values - ; between 48k and 128k we first grow the rma by 128k-largest_free_space. If this - ; results in a lump of 128k now being free we claim it and proceed. If the largest - ; free space hasn't grown to 128k we then claim the additional balance needed to - ; have 128k available. Should either grow fail, we just use whatever (over 48k) - ; was available - - ;R3-R7 spare at presenet - Push "R0-R2" - MOV R0, #0 - STR R0, [WsPtr, #flood_cda_rma] ; set amount to change dyn. area by - MOV R0, #ModHandReason_RMADesc - SWI XOS_Module ; get the largest free space in rma - BVC %FT91 ; if that failed, use scratchspace - -use_scratchspace - LDR R3, =FldQueueStart ; head ptr (== scratchspace) - MOV R4, R3 ; tail ptr - ADD R5, R3, #FldQueueSize ; end ptr (== scratchspace size) - MOV R6, R3 ; start ptr - B %FT92 -91 - CMP R2, #smallest_rma_size ; compare against small threshold - BLT use_scratchspace ; not enough free - use scratchspace - CMP R2, #largest_rma_size ; compare against high threshold - BHS %FT96 ; lots free - use largest ceiling value - - RSB R1, R2, #largest_rma_size ; work out how much more to claim - MOV R0, #1 ; rma - SWI XOS_ChangeDynamicArea - STRVC R1, [WsPtr, #flood_cda_rma] ; save the amount we grew the rma - BVS %FT94 ; if it failed, use the minimum<size<maximum lump - - MOV R0, #ModHandReason_RMADesc ; reread the largest free space to see if - SWI XOS_Module ; it has risen to maximum - BVS use_scratchspace - CMP R2, #largest_rma_size - BHS %FT96 ; it has, so claim the maximum - - LDR R1, [WsPtr, #flood_cda_rma] ; the free space didn't grow to maximum, so the - RSB R1, R1, #largest_rma_size ; largest space wasn't at the end. Do a second - MOV R0, #1 ; grow of the rma to make the maximum - SWI XOS_ChangeDynamicArea - LDRVC R0, [WsPtr, #flood_cda_rma] ; if it succeeded, update the amount that we - ADDVC R0, R0, R1 ; need to shrink the rma by - STRVC R0, [WsPtr, #flood_cda_rma] - ; and fall into the claim largest space routine -94 - MOV R0, #ModHandReason_RMADesc - SWI XOS_Module - BVS use_scratchspace ; find the largest lump now available - CMP R2, #largest_rma_size -96 - MOVGT R3, #largest_rma_size - MOVLE R3, R2 ; cap it at the maximum size we want - MOV R0, #ModHandReason_Claim ; try to claim it - SWI XOS_Module - BVS use_scratchspace - - ADD R5, R2, R3 ; do it in a slightly different order so - MOV R3, R2 ; we can use the R2 and R3 back from the claim - MOV R4, R3 ; (R2=where, R3=size) - MOV R6, R3 - -92 - ADD R7, WsPtr, #QueuePtrs - STMIA R7, {R3, R4, R5, R6} ; initialise queue - Pull "R0-R2" - | - LDR R3, =FldQueueStart ; head ptr - MOV R4, R3 ; tail ptr - ADD R5, R3, #FldQueueSize ; end ptr - MOV R6, R3 ; start ptr - ADD R7, WsPtr, #QueuePtrs - STMIA R7, {R3, R4, R5, R6} ; initialise queue - ] - - BL FillAlong ; try filling L&R from given point - Pull PC, CS ; quit if can't be filled - - MOV R3, #3 ; bit0 => fill up, bit1 => fill down -10 - ADD R14, WsPtr, #FldLeftXLimit - STMIA R14, {R0-R2} ; store leftX, Y, rightX - - TST R3, #1 - BEQ %FT20 - - LDR R10, [WsPtr, #GWTRow] ; if below Top of window - CMP R10, R1 - BLE %FT20 - - ADD R4, WsPtr, #FldBoundaryCol ; R4=target colour ptr,R5=flag, - LDMIA R4, {R4,R5,R6} ; R6=YWindLimit - - ORR R5, R5, #FillingUpBit ; fill line above - Push R3 - BL CheckAlong ; (will bomb out if queue explodes) - Pull R3 - - ADD R14, WsPtr, #FldLeftXLimit - LDMIA R14, {R0,R1} ; reload leftX, Y -20 - TST R3, #2 - BEQ %FT30 - - LDR R10, [WsPtr, #GWBRow] ; if above bottom of window - CMP R1, R10 - BLE %FT30 - - ADD R4, WsPtr, #FldBoundaryCol ; R4=target colour ptr,R5=flag, - LDMIA R4, {R4,R5,R6} ; R6=YWindLimit - -; BIC R5, R5, #FillingUpBit ; fill line below - BL CheckAlong ; (will bomb out if queue explodes) -30 - ADD R11, WsPtr, #QueuePtrs ; unqueue one item - LDMIA R11, {R3,R4,R5} ; head,tail,limit - TEQ R3, R4 ; if queue empty - [ med_00001_userma - BLEQ release_memory - ] - Pull PC, EQ ; then exit - - [ med_00001_twowords - LDR R1, [R3], #4 - MOV R0, R1, LSR #16 ; LeftX - MOV R2, R1 - EOR R2, R2, R0, LSL #16 ; RightX (with LeftX EORed out) - LDR R1, [R3], #4 ; Recover Y - | - LDR R1, [R3], #4 ; then load word - MOV R2, R1, LSR #21 ; Recover RightX - EOR R1, R1, R2, LSL #21 ; clear those bits out - MOV R0, R1, LSR #10 ; Recover LeftX - EOR R1, R1, R0, LSL #10 ; Recover Y - ] - TEQ R3, R5 ; if at limit - LDREQ R3, [R11, #12] ; then reload with start - STR R3, [R11, #0] ; store head ptr back - - MOV R3, #2 ; indicate fill down - CMP R2, R0 ; if right < left then subtract 1 off - ; larger and swap - SBCCC R0, R0, R2 ; R0 := large-small-1 - ADDCC R2, R0, R2 ; R2 := (large-small-1)+small = large-1 - SUBCC R0, R2, R0 ; R0 := (large-1)-(large-small-1)=small - MOVCC R3, #1 ; and indicate fill up - B %BT10 - -; ***************************************************************************** -; -; CheckAlong - Fill and skip background between LeftXLimit & RightXLimit -; ========== -; -; On entry, R0 LeftXLimit -; R1 Y -; R4 target colour -; R5 fill flag -; R6 YWindLimit -; -; Exits using R14 if normal termination -; Exits using FldStackLevel if queue full -; - -FillingUpBit * 1 - - ASSERT FldBoundaryFlag = FldBoundaryCol +4 - ASSERT FldYWindLimit = FldBoundaryCol +8 - - ASSERT FldY = FldLeftXLimit +4 - ASSERT FldRightXLimit = FldLeftXLimit +8 - -CheckAlong ROUT - Push R14 - - TST R5, #FillingUpBit ; if going up - ADDNE R1, R1, #1 ; then increment Y - SUBEQ R1, R1, #1 ; else decrement Y - - BL ScreenAddr ; R2=screen addr, R3=mask - - SUB R6, R6, R1 ; flip Y - AND R6, R6, #7 ; ecf offset - LDR R4, [R4, R6, LSL #2] ; R4=target colour - LDR R7, [WsPtr, #GColAdr] ; base address of plot ecf - ADD R7, R7, R6, LSL #3 ; R7 -> zgora, zgeor - LDMIA R7, {R10,R11} ; R10=zgora, R11=zgeor - LDR R6, [WsPtr, #BytesPerChar] ; R6=pixel shift - LDR R9, [WsPtr, #NPix] ; R9=no. of pixels per word-1 - - ADD R7, WsPtr, #FldSaveArea ; save Y, target colour, - STMIA R7, {R1, R4, R9, R10, R11} ; NPix, zgora, zgeor - -; test first pixel, to see if we can go left - - LDR R7, [R2] - EOR R1, R7, R4 - TST R1, R3 - [ No26bitCode - MRS R8, CPSR - TEQ R5, R8, LSL #1 ; PL => it's fillable - | - TEQ R5, PC, LSL #1 ; PL => it's fillable - ] - RSBMI R6, R6, #32 ; not fillable, reverse pixel shift - LDRMI R8, [WsPtr, #GWRCol] ; load right window limit - BMI %FT37 ; and skip left+right filling bit - - Push "R0, R2, R3" ; save X, screen address, mask - LDR R8, [WsPtr, #GWLCol] - SUB R0, R0, R8 ; make X in range 0..GWRCol-GWLCol - [ No26bitCode - MOV R14, #0 ; clear partial word mask - TEQ R5, #0 ; get into correct loop - BMI %FT84 - BPL %FT64 - | - MOVS R14, #0 ; clear partial word mask (and set PL) - B %FT14 - ] - -10 - MOV R14, #0 ; clear partial word mask - LDR R7, [R2] ; R7 = screen - EOR R1, R7, R4 - [ No26bitCode - ; ***KJB - very cumbersome. Surely a temporary reg somewhere? - TEQ R5, #0 ; check "not" flag - BMI %FT80 - -61 TST R1, R3 ; test pixel position for delimiter - BEQ %FT22 ; NE => it's fillable - ORR R14, R14, R3 ; add pixel to partial word mask -64 SUBS R0, R0, #1 ; decrement X; if on edge of window - BMI %FT22 ; then give up and plot partial word - - MOVS R3, R3, ROR R6 ; test for end of word - BPL %BT61 ; loop until mask wraps - B %FT89 - -80 TST R1, R3 ; test pixel position for delimiter - BNE %FT22 ; EQ => it's fillable - ORR R14, R14, R3 ; add pixel to partial word mask -84 SUBS R0, R0, #1 ; decrement X; if on edge of window - BMI %FT22 ; then give up and plot partial word - - MOVS R3, R3, ROR R6 ; test for end of word - BPL %BT80 ; loop until mask wraps -89 - | -12 - TST R1, R3 ; test pixel position for delimiter - TEQ R5, PC, LSL #1 ; PL => it's fillable - ORRPL R14, R14, R3 ; add pixel to partial word mask -14 - SUBPLS R0, R0, #1 ; decrement X; if on edge of window - BMI %FT22 ; then give up and plot partial word - - MOVS R3, R3, ROR R6 ; test for end of word - BPL %BT12 ; loop until mask wraps - ] - - AND R1, R10, R14 ; R1 := zgora AND pixmask - ORR R7, R7, R1 ; screen := screen OR R1 - AND R1, R11, R14 ; R1 := zgeor AND pixmask - EOR R7, R7, R1 ; screen := screen EOR R1 - STR R7, [R2], #-4 - - CMP R5, #2 ; CC => filling until target - BCC %BT10 ; so do it slowly (do next word) - - SUBS R0, R0, R9 ; move R0 to start of word - BCC %FT20 ; if outside window continue slowly - - ADD R9, R9, #1 ; R9 := pixels per word - ORR R1, R4, R10 ; compute word to plonk on screen - EOR R1, R1, R11 -16 - LDR R7, [R2] ; screen word - CMP R7, R4 - BNE %FT18 ; NZ => terminate - STR R1, [R2], #-4 - SUBS R0, R0, R9 ; back another word - BCS %BT16 -18 - SUB R9, R9, #1 ; R9 := pixels per word -1 -20 - ADDS R0, R0, R9 ; point R0 back to end of word - BGE %BT10 ; if still inside, continue but slowly - B %FT24 ; else exit - - [ :LNOT: AssemblingArthur - MALIGN 16, 0 ; try to get %FT30 aligned ! - ] -22 - AND R1, R10, R14 ; R1 := zgora AND pixmask - ORR R7, R7, R1 ; screen := screen OR R1 - AND R1, R11, R14 ; R1 := zgeor AND pixmask - EOR R7, R7, R1 ; screen := screen EOR R1 - STR R7, [R2] -24 - ADD R0, R0, R8 ; add GWLCol back on - ADD R0, R0, #1 - Pull "R1, R2, R3" ; restore X, screen addr, mask - Push R0 ; save left-of-line coordinate - MOV R0, R1 ; R0 = start X - RSB R6, R6, #32 ; reverse pixel shift - LDR R8, [WsPtr, #GWRCol] ; load right window limit - -; now the filling right part - -26 - SUB R0, R8, R0 ; make X in range GWRCol-GWLCol .. 0 - -; start of each word - -27 - MOV R14, #0 - LDR R7, [R2] ; screen word - EOR R1, R7, R4 - - [ No26bitCode -; ***KJB - very cumbersome. Surely a temporary reg somewhere? - TEQ R5, #0 - BMI %FT75 -72 - TST R1, R3 ; test pixel position for delimiter - BEQ %FT34 ; NE => it's fillable - ORR R14, R14, R3 ; add pixel to partial word mask - SUBS R0, R0, #1 ; "increment" X; if on edge of window - BMI %FT34 ; then give up and plot partial word - - TEQ R3, #0 ; test for end of word - MOV R3, R3, ROR R6 ; shift pixel mask - BPL %BT72 ; loop until mask wraps - B %FT79 - -75 - TST R1, R3 ; test pixel position for delimiter - BNE %FT34 ; EQ => it's fillable - ORR R14, R14, R3 ; add pixel to partial word mask - SUBS R0, R0, #1 ; "increment" X; if on edge of window - BMI %FT34 ; then give up and plot partial word - - TEQ R3, #0 ; test for end of word - MOV R3, R3, ROR R6 ; shift pixel mask - BPL %BT75 ; loop until mask wraps -79 - | -28 - TST R1, R3 ; test pixel position for delimiter - TEQ R5, PC, LSL #1 ; PL => it's fillable - ORRPL R14, R14, R3 ; add pixel to partial word mask - SUBPLS R0, R0, #1 ; "increment" X; if on edge of window - BMI %FT34 ; then give up and plot partial word - - TEQ R3, #0 ; test for end of word - MOV R3, R3, ROR R6 ; shift pixel mask - BPL %BT28 ; loop until mask wraps - ] - - AND R1, R10, R14 ; R1 := zgora AND pixmask - ORR R7, R7, R1 ; screen := screen OR R1 - AND R1, R11, R14 ; R1 := zgeor AND pixmask - EOR R7, R7, R1 ; screen := screen EOR R1 - STR R7, [R2], #4 - - CMP R5, #2 ; CC => filling until target - BCC %BT27 ; so do it slowly (do next word) - - RSB R0, R0, #0 ; make X in range GWLCol-GWRCol .. 0 - ADDS R0, R0, R9 ; move R0 to end of word - BGT %FT32 ; outside window, continue slowly - - ORR R1, R4, R10 ; word to store if going fast - EOR R1, R1, R11 - - [ :LNOT: AssemblingArthur - ASSERT ((.-ArthurVduDriver):AND:15) = 0 - ] -30 - LDR R7, [R2] ; screen word - CMP R7, R4 ; EOR target colour (CS if EQ) - BNE %FT32 ; NZ => terminate - STR R1, [R2], #4 - ADCS R0, R0, R9 ; C=1, so add NPix +1 - BLE %BT30 -32 - SUBS R0, R9, R0 ; R0 back to start of word and negate - BGE %BT27 ; if still inside, continue slowly - B %FT36 ; else exit - -34 - AND R1, R10, R14 ; R1 := zgora AND pixmask - ORR R7, R7, R1 ; screen := screen OR R1 - AND R1, R11, R14 ; R1 := zgeor AND pixmask - EOR R7, R7, R1 ; screen := screen EOR R1 - STR R7, [R2] -36 - SUB R0, R8, R0 ; make back into normal coord again - -; now queue this segment - - Pull R4 ; R4 := LH end point - SUB R7, R0, #1 ; R7 := corrected RH end point - LDR R1, [WsPtr, #FldSaveY] ; reload Y coordinate of THIS segment - BL Queue - - ADD R14, WsPtr, #FldLeftXLimit ; load lxlim, (Y+?), rxlim - LDMIA R14, {R7,R10,R11} - - EOR R5, R5, #FillingUpBit ; invert direction - - SUB R7, R7, #2 ; lxlim -2 - CMP R4, R7 ; if leftX <= lxlim-2 - BLLE Queue ; then Q LH end bit in opposite dir - - ADD R4, R11, #2 ; rxlim +2 - SUB R7, R0, #1 ; R7 = RH end point - CMP R7, R4 ; if rightX >= rxlim+2 - BLGE Queue ; then Q RH end bit in opposite dir - - EOR R5, R5, #FillingUpBit ; invert direction back again - - SUB R4, R4, #3 ; rxlim -1 - CMP R7, R4 ; if rightX >= rxlim-1 - Pull PC, GE ; no point in skipping any more - -; now do the skipping -; R0 points to first non-fillable pixel; R3=correct mask for this pixel - - ADD R7, WsPtr, #FldSaveArea ; reload target colour, NPix, - LDMIB R7, {R4, R9, R10, R11} ; zgora, zgeor -37 - LDR R1, [WsPtr, #FldRightXLimit] -38 - LDR R7, [R2], #4 - EOR R7, R7, R4 ; screen EOR target -40 - TST R7, R3 ; if pixel is fillable - [ No26bitCode - MRS R14, CPSR - TEQ R5, R14, LSL #1 - | - TEQ R5, PC, LSL #1 - ] - SUBPL R2, R2, #4 ; then correct address - Push R0, PL ; and push new X coord - BPL %BT26 ; and go to fill right bit -50 - CMP R0, R1 ; on limit of segment ? - Pull PC, CS ; yes, so give up - ADD R0, R0, #1 ; step coord - TEQ R3, #0 ; test for mask wrap - MOV R3, R3, ROR R6 ; rotate mask to next pixel - BPL %BT40 ; continue within this word - B %BT38 ; continue with next word - -; ***************************************************************************** -; -; Queue - Queue a line segment -; -; in: R1 = Y coordinate of segment -; R4 = left X coordinate -; R5 = fill flag (Bit0=0/1 => look downwards/upwards) -; R7 = right X coordinate -; -; out: R0-R8, R11, R12 preserved -; R9,R10 corrupted -; exits by pulling stacked R14 if queue was full -; - -Queue ROUT - Push "R0,R11,R14" - TEQ R5, R5, LSR #1 ; CS => mangle coords - - MOVCC R9, R4 - MOVCC R10, R7 - - SUBCS R9, R7, R4 ; R9 = R-L - SUBCS R10, R7, R9 ; R10 = R-(R-L) = L - ADCCS R9, R9, R10 ; R9 = (R-L)+L+1 = R+1 - - [ med_00001_twowords - ; revised packing, expanded to two words, LeftX in 31..16 of word 1, - ; RightX in 15..0 of word 1, and Y in 15..0 of word 2 - - MOV R9, R9, LSL #16 ; shift LeftX up - ORR R9, R9, R10 ; combine in RightX - - ADD R0, WsPtr, #QueuePtrs - LDMIA R0, {R10, R11, R14} ; head,tail,limit - - STR R9, [R11], #4 ; store word at tail and move on - STR R1, [R11], #4 ; store second word - | - ; pack Y into bits 0..9, L into bits 10..20, R into bits 21..31 - - ORR R9, R1, R9, LSL #10 ; R9 = Y + (L << 10) - ORR R9, R9, R10, LSL #21 ; R9 = Y + (L << 10) + (R <<21) - - ADD R0, WsPtr, #QueuePtrs - LDMIA R0, {R10, R11, R14} ; head,tail,limit - - STR R9, [R11], #4 ; store word at tail and move on - ] - - TEQ R11, R14 ; if at limit - LDREQ R11, [R0, #12] ; then reload with start ptr - CMP R11, R10 ; EQ and CS if queue full - STRNE R11, [R0, #4] ; store tail ptr back if OK - - Pull "R0,R11,PC", NE ; queue not full, terminate normally - - [ med_00001_userma - BL release_memory - ] - LDR R13, [WsPtr, #FldStackLevel] - Pull PC ; else bomb out - -; ***************************************************************************** - - [ med_00001_userma -release_memory - ROUT - Push "R0-R5,lr" - - ADD R0, WsPtr, #QueuePtrs - LDMIA R0, {R0-R3} - - [ med_00001_debug - LDR R0, =med_00001_debug_start - STR R3, [R0], #4 - STR R2, [R0], #4 - LDR R5, [WsPtr, #flood_cda_rma] - STR R5, [R0] - ] - - LDR R5, =FldQueueStart - - CMP R3, R5 ; did we use scratchspace ? - BEQ %FT20 - - MOV R2, R3 - MOV R0, #ModHandReason_Free - SWI XOS_Module -20 - LDR R0, [WsPtr, #flood_cda_rma] - CMP R0, #0 - BEQ %FT30 ; no need to shrink rma - - RSB R1, R0, #0 ; get the signed negative value - MOV R0, #1 ; rma - SWI XOS_ChangeDynamicArea -30 - CMP r0, r0 ; ensure we return EQ set - Pull "r0-r5,pc" - ] - -; ***************************************************************************** - - END diff --git a/s/vdu/vdugraff b/s/vdu/vdugraff deleted file mode 100644 index 9eff4a76..00000000 --- a/s/vdu/vdugraff +++ /dev/null @@ -1,906 +0,0 @@ -; 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.VduGrafF -; -; ARTHUR OPERATING SYSTEM - Vdu Drivers -; ======================= -; -; Vdu driver code - Solid & Dotted Line drawing routines -; -; Author R C Manby -; Date 27.10.86 -; - - -; -; -; -;------------------------------------------------------------------------------ -; -; DoOsbyte163_242 - Set dotted line length and return status information -; =============== -; -; We are only interested in OsByte 163,242,0..66 -; -; OsByte 163,242,0..64 set dotted line length -; 163,242,0 set default dot pattern and length -; 163,242,1..64 set specified pattern length -; -; OsByte 163,242,65 return graphics status -; returns R1 = &Cn (means GXR on & flood on (for GXR)) -; (means SpriteRom on (for master/compact)) -; n = dotted line length MOD 64 -; R2 = number of sprite pages -; -; OsByte 163,242,66 return sprite status -; returns R1 = R2 = 0 if no sprite selected -; R1 = current sprite width -; R2 = current sprite height -; -; When entered, we know it is FX 163,242,n -; Exit by MOV PC, R14 if still don't understand (ie n>66) -; Otherwise exit with Pull PC - -DoOsbyte163_242 ROUT - CMP R2,#66 - MOVHI PC, R14 ; Not 0..66, so pass it on - - Push "R3-R12" ; Preserve the world - VDWS WsPtr ; Point R12 at Vdu driver workspace - - CMP R2,#65 - BLLT SetPatLength ; R2 holds 0/1..64 ; PSR preserved - BLT OsByte_QuitA - BGT OsByte163_242_66 - -OsByte163_242_65 ; OsByte 163,242,65 - graphics status - LDR R1,[WsPtr,#DotLineLength] - AND R1,R1,#&3F ; Dot count MOD 64 - ORR R1,R1,#&C0 ; GXR on, Flood on - LDR R2,[WsPtr,#SpAreaStart] - CMP R2,#0 - LDRNE R2,[R2,#saEnd] ; SpriteWS size - B OsByte_QuitA - -OsByte163_242_66 ; OsByte 163,242,66 - sprite status - - MOV R0,#SpriteReason_ReadSpriteSize - LDR R2,=SpChooseName - ADD R2,R2,WsPtr ; Sprite name ptr - - SWI XOS_SpriteOp - - MOVVS R1,#0 ; If no sprite memory, or no sprite - MOVVS R2,#0 ; chosen, return 0,0 as width,height - - MOVVC R1,R3 ; else return width,height in pixels - MOVVC R2,R4 - -OsByte_QuitA - Pull "R3-R12,PC" ; restore registers and claim call -; -; -; -;------------------------------------------------------------------------------ - - - - - MACRO - WriteToScreen $Adr,$Msk,$Ecf, $a,$b,$c - LDMIA $Ecf,{$a,$b} - AND $a,$a,$Msk - AND $b,$b,$Msk - [ AvoidScreenReads - CMP $a,#&FFFFFFFF - LDRNE $c,[$Adr] - | - LDR $c,[$Adr] - ] - ORR $c,$c,$a - EOR $c,$c,$b - STR $c,[$Adr] - MEND - - -; -; -; -;------------------------------------------------------------------------------ - - - - -rXCnt RN 0 -rYCnt RN 1 -rBres RN 2 -rDeltaY RN 3 -rPixShft RN 4 -rScrAdr RN 5 -rPixMsk RN 6 -rDotPtr RN 7 - -rEcfPtr RN 8 - -rEcfBase RN 8 -rEcfIndx RN 9 -rDeltaX RN 10 -rScanStp RN 11 - -rDotCnt RN 9 -rDotPatLSW RN 10 -rDotPatMSW RN 11 - -rDOTCnt RN 10 -rDOTPatLSW RN 11 -rDOTPatMSW RN 14 - - -; -;------------------------------------------------------------------------------ -; -; LineDraw - General line drawing routine -; ======== -; -; On entry, ICursor is the start point of the line -; NewPt is the end point -; -; R2 holds plot code, where bits mean :- -; bit 5 clear/set - include/exclude initial point -; bit 4 clear/set - solid/dotted line -; bit 3 clear/set - include/exclude final point -; -; bit 5 implies - restart/continue dot pattern -; -LineDrawSolid - TST R2, #&03 ; if a no action one - MOVEQ PC, R14 ; then do nowt, just shunt coords -LineDrawDotted ROUT - EOR R11, R2, #&18 ; Flip solid/dotted flag, and final point flag - ; bit 4 set/clear - solid/dotted line - ; bit 3 set/clear - include/exclude final point - MOV R9, #0 - ADD R10, WsPtr, #LineDotCnt - - TST R11, #&10 - STRNE R9, [WsPtr, #LineDotPtr] ; Solid line - STREQ R10, [WsPtr, #LineDotPtr] ; Dotted line - - TSTEQ R11, #&20 ; If dotted line & first point included - STREQ R9, [WsPtr, #LineDotCnt] ; then force a restart of the pattern - - STR R9, [WsPtr, #PostCycleCount] ; Assume all dots get plotted - - ADD R0,WsPtr,#GCsIX ;Start ICursor - LDMIA R0,{R0,R1,R2,R3} ;End NewPt - - TEQ R1, R3 ; If line is horizontal - BEQ TryHLine ; try to use HLine - [ UseVLineOnSolidLines - TEQ R0, R2 ; If line is vertical - BEQ TryVLine ; try to use VLine -CantUseVLine - ] -CantUseHLineOrVLine - SaveRetAdr - - Difference R4,R0,R2 - Difference R5,R1,R3 - Greatest R10,R4,R5 - ADD R10,R10,#1 ;Total number of dots on line - - BL GenLineParm ;Generate line control block - ; in R0..R8 - - TST R11,#&20 ;If first point excluded - SUBNE R10,R10,#1 ; then dec DotCycleCount and - BLNE AdvLineParm ; advance to first pixel and - - TST R11,#&08 ;If last point excluded - SUBEQ R10,R10,#1 ; then dec DotCycleCount - - CMP R10,#0 ;IF DotCycleCount <= 0 - Return LE ; then nothing to plot - - STR R10,[WsPtr,#DotCycleCount] - STR R11,[WsPtr,#LineEndPtFlags] - - WINDow R0,R1, R9,R10,R11,R14 ;If start point outside window - BLLT LineStartsOutsideWindow ; then panic {won't return if whole - ; line outside window} - - WINDow R7,R8, R9,R10,R11,R14 ;If end point outside window - BLLT LineEndsOutsideWindow ; then panic as well - -; -; R0 ,R1 ,R2 ,R3 ,R4 ,R5 ,R6 -; StartX,StartY,Bres,DeltaX,DeltaY,StepX,StepY -; - - ;Modify StepX (+1/-1 means right/left) - CMP R5,#0 ; to give PixelMask shift factor - LDR R5,[WsPtr,#BytesPerChar] ; "Left" - RSBPL R5,R5,#0 ; "Right" - - ;Modify StepY (+1/-1 means up/down) - CMP R6,#0 ; to give offset to next scan line - LDR R6,[WsPtr,#LineLength] ; "Down" - RSBPL R6,R6,#0 ; "Up" - - Push "R2-R6" ;Bres,DeltaX,DeltaY,StepX,StepY - - BL ScreenAddr - MOV R7,R2 ;Screen Adr - MOV R8,R3 ;Pixel Mask - - LDR R9,[WsPtr, #YWindLimit] - SUB R9,R9,R1 ;subtract Y from YWindLimit - AND R9,R9,#7 ;EcfIndx - - Pull "R2-R6" ;Bres,DeltaX,DeltaY,StepX,StepY - - LDR R0,[WsPtr,#DotCycleCount] ;Number of on screen pixels - CMP R0,#0 ; An LPO line starting outside & ending - Return LE ; on the window leaves zero dots! - - LDR R1,[WsPtr,#LineDotPtr] - CMP R1,#0 - BNE DotDashLine - -SolidLine ROUT - Push R12 - LDR R1, [WsPtr, #GColAdr] ; Base address of ECF - ADD R1, R1, R9, LSL #3 ; current address of ECF -; -; R0 ,R1 ,R2 ,R3 ,R4 ,R5 ,R6 ,R7 ,R8 ,R9 -; PixCnt,EcfBase,Bres,DeltaX,DeltaY,MskShft,LineStp,ScrAdr,Mask,Indx -; - - LDMIA R1, {R9, R10} ; R9 = zgora; R10 = zgeor -20 - MOV R12, R8 -30 - SUBS R0, R0, #1 ; Dec pixel count - BEQ %FT57 ; if zero, then finish off - -40 -; Advance the screen address and pixel mask one pixel - - TEQ R2, #0 ; If Bres positive - BPL %FT55 ; then advance in X dirn only - ; else advance in Y direction, which - ; may involve advancing X afterwards -45 - AND R14, R9, R12 ; R14 = zgora AND pixmask - [ AvoidScreenReads - CMP R14, #&FFFFFFFF - LDRNE R11, [R7] ; R11 = word from screen - | - LDR R11, [R7] ; R11 = word from screen - ] - ORR R11, R11, R14 ; OR with screen - AND R14, R10, R12 ; R14 = zgeor AND pixmask - EOR R11, R11, R14 ; EOR with screen - STR R11, [R7], R6 ; and store back, moving on - - CMP R6, #&80000000 ; C=1 => going up the screen - TSTCS R1, #63 ; so check being at word 0 of ECF - SUBCS R1, R1, #8 ; and then subtract 2 words - ADDCC R1, R1, #8 ; else add on 2 words first - TSTCC R1, #63 ; and then test for wrap - BEQ %FT60 - LDMIA R1, {R9, R10} ; reload zgora and zgeor - ADDS R2, R2, R3 ; Advance Bres, in Y dirn - - BMI %BT20 ; [don't need to move in X direction] -50 - MOV R12, #0 ; clear total pixel mask -55 -; -; Advance in X direction -; - CMP R5, #&80000000 ; if +ve then RORing, so test if - TSTCC R8, #1 ; bottom bit set before shifting - MOV R8, R8, ROR R5 ; shift word - TSTCS R8, #1 ; else test after shifting - SUB R2, R2, R4 ; always advance Bres in X direction - ORREQ R12, R12, R8 ; if not wrapped, OR in new pixel - BEQ %BT30 ; and loop - -57 - [ AvoidScreenReads - TEQ R12, #0 - BEQ %FT58 - ] - AND R14, R9, R12 ; R14 = zgora AND pixmask - [ AvoidScreenReads - MVNS R11, R14 - LDRNE R11, [R7] ; R11 = word from screen - | - LDR R11, [R7] ; R11 = word from screen - ] - ORR R11, R11, R14 ; OR with screen - AND R14, R10, R12 ; R14 = zgeor AND pixmask - EOR R11, R11, R14 ; EOR with screen - [ AvoidScreenReads - STR R11, [R7] ; and store back -58 SUBCC R7, R7, #4 ; increment or decrement - ADDCS R7, R7, #4 - | - STRCC R11, [R7], #-4 ; and store back - STRCS R11, [R7], #4 ; incrementing or decrementing - ] - - MOV R12, R8 ; reset total pixel mask - - SUBS R0, R0, #1 - Pull "R12, PC", LT ; exit if COMPLETELY finished - BEQ %BT57 ; if no more to do, then output word! - TEQ R2, #0 ; test Bres again - BPL %BT55 - B %BT45 - - -; come here when ECF wraps (ie every eight Y coords) - -60 - ADDCS R1, R1, #64 ; if wrap and going up, then add 64 - SUBCC R1, R1, #64 ; if wrap and going down, subtract 64 - LDMIA R1, {R9, R10} ; reload zgora and zgeor - ADDS R2, R2, R3 ; Advance Bres, in Y dirn - BMI %BT20 ; [don't need to move in X direction] - B %BT50 - -; ***************************************************************************** -; -; TryHLine - Try to use HLine (we already know Y1=Y2) -; -; in: R0 = X1 -; R1 = R3 = Y -; R2 = X2 -; R11 = plot code EOR &18 -; bit 3 set => include last point -; bit 4 set => solid -; bit 5 set => exclude first point -; - -TryHLine ROUT - TST R11, #&10 ; is it dotted - BEQ CantUseHLineOrVLine ; yes, then can't use HLine - - CMP R2, R0 - MOVGE R4, #1 - MOVLT R4, #-1 - TST R11, #&20 ; if first point excluded - ADDNE R0, R0, R4 ; then move R0 one pixel towards R2 - TST R11, #&08 ; if last point excluded - SUBEQ R2, R2, R4 ; then move R2 one pixel towards R0 - - CMP R2, R0 ; check order again - EORLT R0, R0, R2 ; make sure R0 <= R2 - EORLT R2, R0, R2 - EORLT R0, R0, R2 - RSBLT R4, R4, #0 ; if swapped, then invert sign of R4 - TEQNE R4, #1 ; if order is now different - ; (and they're not equal now) - MOVNE PC, R14 ; then there's nothing to plot - B NewHLine ; else go and do it! - -; ***************************************************************************** -; -; TryVLine - Try to use VLine (we already know X1=X2) -; -; in: R0 = R2 = X -; R1 = Y1 -; R3 = Y2 -; R11 = plot code EOR &18 -; bit 3 set => include last point -; bit 4 set => solid -; bit 5 set => exclude first point -; - -TryVLine ROUT - TST R11, #&10 ; is it dotted - BEQ CantUseHLineOrVLine ; yes, then can't use VLine (or HLine) - -; now make sure that we are using a solid pattern (not an ECF) -; this is true if the appropriate GCOL action is < 8 - - AND R4, R11, #3 ; look at bottom 2 bits of R11 - CMP R4, #2 ; to check which action - ; (already ruled out 0 (no action)) - LDRCC R4, [WsPtr, #GPLFMD] ; <2 => 1 => foreground action - MOVEQ R4, #4 ; =2 => 2 => invert action - LDRHI R4, [WsPtr, #GPLBMD] ; >2 => 3 => background action - CMP R4, #8 ; is it a solid action - BCS CantUseVLine - - CMP R3, R1 - MOVGE R4, #1 - MOVLT R4, #-1 - TST R11, #&20 ; if first point excluded - ADDNE R1, R1, R4 ; then move R1 one pixel towards R3 - TST R11, #&08 ; if last point excluded - SUBEQ R3, R3, R4 ; then move R3 one pixel towards R1 - - CMP R3, R1 ; check order again - EORLT R1, R1, R3 ; make sure R1 <= R3 - EORLT R3, R1, R3 - EORLT R1, R1, R3 - RSBLT R4, R4, #0 ; if swapped, then invert sign of R4 - TEQNE R4, #1 ; if order is now different - ; (and they're not equal now) - MOVNE PC, R14 ; then there's nothing to plot - B NewVLine ; else go and do it! - - -; -; -; -DotDashLine - -; -; R0 ,R1 ,R2 ,R3 ,R4 ,R5 ,R6 ,R7 ,R8 ,R9 -; PixCnt,DotPtr,Bres,DeltaX,DeltaY,MskShft,LineStp,ScrAdr,Mask,Indx -; - -DotDash20 - LDMIA R1,{rDOTCnt,rDOTPatLSW,rDOTPatMSW} - - CMP rDOTCnt,#0 - - ADDEQ rDOTCnt,WsPtr,#DotLineStyle ;Restart pattern - LDMEQIA rDOTCnt,{rDOTPatLSW,rDOTPatMSW} - LDREQ rDOTCnt,[WsPtr,#DotLineLength] - - SUB rDOTCnt,rDOTCnt,#1 - - MOVS rDOTPatMSW,rDOTPatMSW,LSL #1 - ORR rDOTPatMSW,rDOTPatMSW,rDOTPatLSW,LSR #31 - MOV rDOTPatLSW,rDOTPatLSW,LSL #1 - - STMIA R1,{rDOTCnt,rDOTPatLSW,rDOTPatMSW} - - BCC DotDash30 ;Don't plot this dot - - LDR R10,[WsPtr,#GColAdr] ;Base address of ECF - ADD R10,R10,R9,LSL #3 ;Address of ECFora & ECFeor - WriteToScreen R7,R8,R10, R10,R11,R14 - -DotDash30 - SUBS R0,R0,#1 ;Dec pixel count - BEQ DotDash60 ;Finished on screen - -DotDash40 -; -; Advance the screen address and pixel mask one pixel -; - - CMP R2,#0 ;If Bres positive - BPL DotDash50 ;then advance in X dirn only - ;else advance in Y direction, which may - ; involve advancement in X afterwards - - CMP R6,#0 ;Advance Ecf to next scanline - SUBLT R9,R9,#1 ; "Up" = (Old-1) Mod 7 - ADDGE R9,R9,#1 ; "Doun" = (Old+1) Mod 7 - AND R9,R9,#7 - - ADD R7,R7,R6 ;Advance screen address one scanline - - ADDS R2,R2,R3 ;Advance Bres, in Y dirn - BMI DotDash20 ; - ; may now need advancing in X dirn -DotDash50 -; -; Advance in X direction -; -; Rotate PixMsk to next pixel position, altering ScrAdr if we cross to -; the next word. -; - - TST R8, R5 ;If PixMsk at MSEnd of word - ; and shifting left - ADDMI R7, R7, #4 ;then inc ScrAdr {PixMsk will wrap} - - MOVS R8, R8, ROR R5 ;Move PixMsk - - ;If PixMsk now at MSEnd of word - RSBMIS R11, R5, #0 ; and shift was right - SUBMI R7, R7, #4 ;then dec ScrAdr {PixMsk wrapped} - - SUB R2, R2, R4 ;Advance Bres, in X dirn - B DotDash20 - -DotDash60 - - LDR R0,[WsPtr,#PostCycleCount] - CMP R0,#0 - BLNE AdvanceDotPattern - - Return - - LTORG - - DCD 0 ; *** Inserted for diagnostic purposes ! *** - -; -; -; -;------------------------------------------------------------------------------ -; -; LineEndsOutSideWindow -; ===================== -; -LineEndsOutsideWindow - - Push "R0-R8,Link" ;Push whole parameter block - - ADD R0,WsPtr,#GCsIX ;Start ICursor - LDMIA R0,{R0,R1,R2,R3} ;End NewPt - Swap R0,R2 - Swap R1,R3 - - BL GenLineParm ;Generate line control block - ; in R0..R8 - LDR R11,[WsPtr,#LineEndPtFlags] - - TST R11,#&08 ;If last point excluded - BLEQ AdvLineParm ; then advance to actual last point - - Push "R0,R1" ;EndX,EndY - - WindowRes R11,R0,R1, R7,R8,R9,R10 ;R11 := Window(End) - -; -; R0 ,R1 ,R2 ,R3 ,R4 ,R5 ,R6 , ,R11 -; EndX,EndY,Bres,DeltaX,DeltaY,StepX,StepY, ,WEnd -; - - TST R11,#&C ;If above/below window - BEQ LEO10 - - BL InYWind ; then bring Y into window - - WindowRes R11,R0,R1, R7,R8,R9,R10 ;R11 := Window(NewEnd) - -LEO10 - TST R11,#&3 - BEQ LEO20 ;If start outside X window - - BL InXWind - - WindowRes R11,R0,R1, R7,R8,R9,R10 ;R11 := Window(NewEnd) - -LEO20 - Pull "R9,R10" ;EndX,EndY - - Difference R0,R0,R9 - Difference R1,R1,R10 - Greatest R0,R0,R1 - - LDR R1,[WsPtr,#DotCycleCount] - SUB R1,R1,R0 - STR R1,[WsPtr,#DotCycleCount] - STR R0,[WsPtr,#PostCycleCount] - - Pull "R0-R8,PC" -; -; -; -;------------------------------------------------------------------------------ -; -; LineStartsOutSideWindow -; ======================= -; -LineStartsOutsideWindow - - Push Link - Push "R0,R1" ;StartX,StartY - - Push "R5,R6" - WindowRes R10,R0,R1, R5,R6,R9,R14 ;R10 := Window(Start) - WindowRes R11,R7,R8, R5,R6,R9,R14 ;R11 := Window(End) - Pull "R5,R6" - - TST R10,R11 - BNE LineOutsideWindow ;Line completely outside window - - -; -; R0 ,R1 ,R2 ,R3 ,R4 ,R5 ,R6 ,R7 ,R8 ,R10 ,R11 -; StartX,StartY,Bres,DeltaX,DeltaY,StepX,StepY,EndX,EndY ,WStart,WEnd -; - - TST R10,#&C ;If above/below window - BEQ LSO10 - - Push R11 - BL InYWind ; then bring Y into window - Pull R11 - - Push "R6-R8" - WindowRes R10,R0,R1, R6,R7,R8,R9 ;R10 := Window(NewStart) - Pull "R6-R8" - - TST R10,R11 - BNE LineOutsideWindow ;Line completely outside window -LSO10 - TST R10,#&3 - BEQ LSO20 ;If start outside X window - - Push R11 - BL InXWind - Pull R11 - - Push "R6-R8" - WindowRes R10,R0,R1, R6,R7,R8,R9 ;R10 := Window(NewStart) - Pull "R6-R8" - CMP R10,#0 - - BNE LineOutsideWindow ;Cannot clip to window -LSO20 - Pull "R9,R10" ;StartX,StartY - - Push "R0-R8" - Difference R0,R0,R9 - Difference R1,R1,R10 - Greatest R0,R0,R1 - BL AdvanceDotPattern - Pull "R0-R8" - - Pull "PC" - - -LineOutsideWindow - Pull "R0,R1" ;Balance the stack - LDR R0,[WsPtr,#DotCycleCount] - BL AdvanceDotPattern - - Pull "Link" - Return ;To caller of the line routine -; -; -; -;------------------------------------------------------------------------------ -; - - -lpStartX RN 0 -lpStartY RN 1 -lpBres RN 2 -lpDeltaX RN 3 -lpDeltaY RN 4 -lpStepX RN 5 -lpStepY RN 6 - - - - - - -; -; InYWind - Bring a set of line parameters into the Y window -; ======= -; -; On entry, R0-R6 contain a line parameter block -; R0 - StartX -; R1 - StartY -; R2 - Bres -; R3 - DeltaX -; R4 - DeltaY -; R5 - StepX (+1/-1) (Equv bit6 of Sign in 6502 version) -; R6 - StepY (+1/-1) (Equv bit7 of Sign in 6502 version) -; R7 - EndX -; R8 - EndY -; -; R9 - gwbrow -; R10 - gwtrow -; -; Algorithm: -; 1. Calculate distance to Y window -; 2. Change StartY by (distance-1) -; 3. Add (distance-1)*DeltaX to Bres -; 4. Divide Bres by DeltaY -; 5. Subtract (quotient+1)*DeltaY from Bres -; 6. Change StartX by (quotient+1) -; 7. Do one more pixel advance by AdvLineParm -; (N.B. this is always the Bres -ve case) -; -; -; -InYWind - SaveRetAdr - - LDR R9,[WsPtr,#GWBRow] - LDR R10,[WsPtr,#GWTRow] - ;(1) - CMP lpStepY,#0 - SUBGE R11,R9,lpStartY - SUBLT R11,lpStartY,R10 - SUB R11,R11,#1 ;(Distance to window) - 1 - - BL InYW30 ;Steps 2-6 - - BL AdvLineParm ;Step to first pixel in window - Return -; -; Flags still valid, GE/LT -; -; R11 holds distance to window -1 -; -InYW30 ;(2) - ADDGE lpStartY,lpStartY,R11 ;StartY := GWBRow-1 - SUBLT lpStartY,lpStartY,R11 ;StartY := GWTRow+1 - ;(3) - MOV R10,lpDeltaX - MUL R9,R11,R10 - ADDS lpBres,lpBres,R9 ;Bres := Bres+(dist-1)*DeltaX - - ;If lpBres now -ve, - MOVLT PC,Link ;then don't modify StartX - ; (quotient+1 is 0) - ;else - MOV R10,lpDeltaY -; *****Change made by DJS -; Use new DivRem macro, not old DIVREM -; Original code was: -; DIVREM R11,lpBres,R10,R9 - DivRem R11,lpBres,R10,R9 -; *****End of change made by DJS - SUB lpBres,lpBres,lpDeltaY - - ADD R11,R11,#1 ; quotient := 1+bres/deltay - ;(6) - CMP lpStepX,#0 - ADDGE lpStartX,lpStartX,R11 - SUBLT lpStartX,lpStartX,R11 - - MOV PC,Link - - - - -; -; InXWind - Bring a set of line parametres into the X window -; ======= -; -; On entry, R0-R6 contain a line parameter block -; R0 - StartX -; R1 - StartY -; R2 - Bres -; R3 - DeltaX -; R4 - DeltaY -; R5 - StepX (+1/-1) (Equv bit6 of Sign in 6502 version) -; R6 - StepY (+1/-1) (Equv bit7 of Sign in 6502 version) -; R7 - EndX -; R8 - EndY -; -; R9 - gwlcol -; R10 - gwrcol -; -; Algorithm: -; 1. Replace Bres by -Bres-1 -; 2. Swap StartX and StartY -; 3. Swap DeltaX and DeltaY -; 3a Swap StepX and StepY -; 4. Calculate distance to X window -; 5. Do steps 2-6 of InYWind -; 6. Repeat steps 1-3 -; 7. Do one more pixel advance by AdvLineParm -; (N.B. this is always the Bres +ve case) -; -InXWind - SaveRetAdr - - LDR R9,[WsPtr,#GWLCol] - LDR R10,[WsPtr,#GWRCol] - ;(1) - MVN lpBres,lpBres - ;(2)(3) - Push "lpStartX,lpDeltaX,lpStepX" - Push "lpStartY,lpDeltaY,lpStepY" - Pull "lpStartX,lpDeltaX,lpStepX" - Pull "lpStartY,lpDeltaY,lpStepY" - - CMP lpStepY,#0 ;Really StepX - SUBGE R11,R9,lpStartY - SUBLT R11,lpStartY,R10 - SUB R11,R11,#1 ;(Distance to window) - 1 - - BL InYW30 ;Steps 2-6 - ;(1) - MVN lpBres,lpBres - ;(2)(3) - Push "lpStartX,lpDeltaX,lpStepX" - Push "lpStartY,lpDeltaY,lpStepY" - Pull "lpStartX,lpDeltaX,lpStepX" - Pull "lpStartY,lpDeltaY,lpStepY" - - BL AdvLineParm ;Step to first pixel in window - Return - - - - -; -; rDotPtr RN 7 -; rDotCnt RN 9 -; rDotPatLSW RN 10 -; rDotPatMSW RN 11 - -; -; On entry R0 holds number of places to step dot pattern -; -AdvanceDotPattern - LDR R1,[WsPtr,#DotCycleCount] - SUB R1,R1,R0 - STR R1,[WsPtr,#DotCycleCount] - - LDR rDotPtr,[WsPtr,#LineDotPtr] - CMP rDotPtr,#0 - MOVEQ PC,Link - - LDR R1,[WsPtr,#DotLineLength] - MOV R2,R1 -; *****Change made by DJS -; Use new DivRem macro, not old DIVREM -; Original code was: -; DIVREM R3,R0,R2,R4 ;R0:=R0 REM DotLineLength - DivRem R3,R0,R2,R4 ;R0:=R0 REM DotLineLength -; *****End of change made by DJS - - LDMIA rDotPtr,{rDotCnt,rDotPatLSW,rDotPatMSW} - - CMP rDotCnt,R0 - SUBLT R0,R0,rDotCnt - - ADDLT rDotCnt,WsPtr,#DotLineStyle ;Restart pattern - LDMLTIA rDotCnt,{rDotPatLSW,rDotPatMSW} - LDRLT rDotCnt,[WsPtr,#DotLineLength] - - SUB rDotCnt,rDotCnt,R0 ;New value - - [ {TRUE} - -; need special code if R0 > 32 - - RSBS R1, R0, #32 - MOVLT rDotPatMSW, rDotPatLSW - MOVLT rDotPatLSW, #0 ; probably not necessary - SUBLT R0, R0, #32 - RSBLT R1, R0, #32 - - MOV rDotPatMSW,rDotPatMSW,LSL R0 - ORR rDotPatMSW,rDotPatMSW,rDotPatLSW,LSR R1 - MOV rDotPatLSW,rDotPatLSW,LSL R0 - | - -; old code - - RSB R1,R0,#32 - MOV rDotPatMSW,rDotPatMSW,LSL R0 - ORR rDotPatMSW,rDotPatMSW,rDotPatLSW,LSR R1 - MOV rDotPatLSW,rDotPatLSW,LSL R0 - ] - - STMIA rDotPtr,{rDotCnt,rDotPatLSW,rDotPatMSW} - - MOV PC,Link -; -;--------------------------------------------------------------------------- -; - - END diff --git a/s/vdu/vdugrafg b/s/vdu/vdugrafg deleted file mode 100644 index 19f2847e..00000000 --- a/s/vdu/vdugrafg +++ /dev/null @@ -1,2678 +0,0 @@ -; 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.VduGrafG -; -; ARTHUR OPERATING SYSTEM - Vdu Drivers -; ======================= -; -; Vdu driver code - Sprite stuff -; -; Author R C Manby -; Date 10.11.86 -; - -RangeB * 256 -RangeC * 512 - -; Macros for various sprite operations - - MACRO - KillSpChoosePtr - MOV R0, #0 - STR R0, [WsPtr, #SpChoosePtr] - MEND - - MACRO - CopyDown $to,$from,$bytes, $tmp, $tmp2 - LDR $tmp2, [WsPtr, #VduSprite] ; sprite being output to by Vdu - ADD $tmp, $from, $bytes - SUB $tmp, $tmp, #1 ; from + bytes -1 - CMP $tmp2, $to ; if VOTS >= to - CMPCS $tmp, $tmp2 ; and from+bytes-1 >= VOTS - BCC %FT00 - Push "R0, R14" - SUB R0, $to, $from ; then adjust address vars - BL AdjustSpriteAddress ; by offset = to-from - Pull "R0, R14" -00 - CMP $bytes, #0 ; bytes must be a multiple of 4 -01 - LDRNE $tmp, [$from], #4 - STRNE $tmp, [$to], #4 - SUBNES $bytes, $bytes, #4 - BNE %BT01 - MEND - - MACRO - CopyUp $to,$from,$bytes, $tmp, $tmp2 - LDR $tmp2, [WsPtr, #VduSprite] ; sprite being output to by Vdu - ADD $tmp, $to, $bytes - SUB $tmp, $tmp, #1 ; to + bytes -1 - CMP $tmp2, $from ; if VOTS >= from - CMPCS $tmp, $tmp2 ; and to+bytes-1 >= VOTS - BCC %FT00 - Push "R0, R14" - SUB R0, $to, $from ; then adjust address vars - BL AdjustSpriteAddress ; by offset = to-from - Pull "R0, R14" -00 -01 - SUBS $bytes, $bytes, #4 - LDRCS $tmp, [$from, $bytes] - STRCS $tmp, [$to, $bytes] - BHI %BT01 - MEND - -; copy R0 bytes from R3 to R2 (R2+:=R0; R3+:=R0) -; corrupts R0, R4-R11, R14 -; NB not used at present - - MACRO - CopyDownFast - SUBS R0, R0, #9*4 -10 - LDMCSIA R3!, {R4-R11,R14} - STMCSIA R2!, {R4-R11,R14} - SUBCSS R0, R0, #9*4 - BCS %BT10 - ADDS R0, R0, #9*4 -20 - LDRNE R4, [R3], #4 - STRNE R4, [R2], #4 - SUBNES R0, R0, #4 - BNE %BT20 - MEND - - MACRO - ClearWords $from,$words, $tmp - MOV $tmp,#0 -01 - SUBS $words, $words, #1 - STRCS $tmp, [$from], #4 - BHI %BT01 - MEND - -; ***************************************************************************** -; -; AdjustSpriteAddress - Move VduSprite, ScreenStart, CursorAddr and -; InputCursorAddr by R0 -; -; Internal routine, called by routines that use macros -; CopyDown, CopyUp -; -; in: R0 = no. of bytes to add on (can be -ve) -; - -AdjustSpriteAddress ROUT - Push R14 - LDR R14, [WsPtr, #VduSprite] - ADD R14, R14, R0 - STR R14, [WsPtr, #VduSprite] - LDR R14, [WsPtr, #ScreenStart] - ADD R14, R14, R0 - STR R14, [WsPtr, #ScreenStart] - B AdjustCursorVars ; update CursorAddr, InputCursorAddr - -; ***************************************************************************** -; -; SpriteInit - Setup sprite workspace on reset (called whenever break -; is pressed) -; - -SpriteInit ROUT - Push R14 - [ :LNOT: AssemblingArthur - LDR R0, =SvcTable ; intercept SWI SpriteOp - ADR R1, SwiSpriteOp - STR R1, [R0, #(OS_SpriteOp*4)] - - ADRL R1, SwiReadPoint ; might as well catch ReadPoint - STR R1, [R0, #(OS_ReadPoint*4)] ; here - ] - - BL ClearSpritePtrName ; clear SpChoosePtr,SpChooseName - - Pull PC - - LTORG - -; ***************************************************************************** -; -; Vdu23_27 - SCHOOSE/SGET a numbered sprite -; -; in: QQ?0 = 0 => Select sprite STR$(QQ?1) for plotting -; QQ?0 = 1 => Sget an area of screen and put it in sprite STR$(QQ?1) -; - -Vdu23_27 ROUT - LDRB R0, [WsPtr, #QQ+1] - CMP R0, #1 - MOVCC R3, #SpriteReason_SelectSprite ; 0-Select sprite - MOVEQ R3, #SpriteReason_GetSprite ; 1-Pickup sprite - MOVHI PC, R14 - - Push R14 - - LDRB R0, [WsPtr, #QQ+2] ; sprite number - ADD R1, WsPtr, #NameBuf - MOV R2, #4 - SWI XOS_BinaryToDecimal - MOV R0, #13 - STRB R0, [R1, R2] ; $NameBuf := STR$(n) - - MOV R0, R3 ; R0 = sprite-op reason code - MOV R2, R1 ; R2 -> sprite name - MOV R3, #0 ; extension gap size - SWI XOS_SpriteOp ; perform operation, ignore errors - - Pull PC - -; ***************************************************************************** -; -; SpritePlot - PLOT &E8-&EF,X,Y -; -; in: R2 = plot code -; -; The 2 LSBits of the plot code specify fg/bg colour and action as :- -; 0 => No effect eqv. of Gcol(5,c) -; 1 => Plot sprite using foreground Gcol action -; 2 => Invert eqv. of Gcol(4,c) -; 3 => Plot mask in background colour and Gcol action -; - -SpritePlot ROUT - Push R14 - - AND R3, R2, #3 ; 2 LSBits of plot code - CMP R3, #1 - MOVCC R5, #5 ; gcol action - no effect - LDREQ R5, [WsPtr, #GPLFMD] ; foreground - MOVHI R5, #4 ; invert or background - - AND R5, R5, #&0F ; knock out any ecf bits - - LDR R2, [WsPtr, #SpChoosePtr] ; If ChoosePtr <> 0 - CMP R2, #0 - BNE %FT10 ; then use as pointer to sprite - - MOV R0, #SpriteReason_SelectSprite ; else select it first - LDR R2, =SpChooseName - ADD R2, R2, WsPtr ; sprite name ptr - SWI XOS_SpriteOp - LDR R2, [WsPtr, #SpChoosePtr] - -10 ; R2 points to the sprite - CMP R3, #3 - MOVNE R0, #RangeC+SpriteReason_PutSprite - LDREQ R0, =RangeC+SpriteReason_PlotMask - LDR R1, [WsPtr, #SpAreaStart] - SWI XOS_SpriteOp ; perform operation, ignoring errors - - Pull PC - -; ***************************************************************************** -; -; SwiSpriteOp - Entry point for SWI OS_SpriteOp -; -; in: R0 = sprite op reason code -; R1 -> sprite area (usually) -; R2 -> sprite (usually) -; R3..? parameters -; - -SwiSpriteOp ROUT - Push R14 - BranchNotJustUs %F10, SpriteV, R11, R14 - -; we are sole owners of SpriteV, so call our internal routine - - Push PC ; push address of SwiSpriteReturn - B SpriteVecHandler - & 0 - -SwiSpriteReturn - Pull R14 - ORRVS R14, R14, #V_bit ; if error, set V_bit in link - ExitSWIHandler - -; we are not the sole owners of SpriteV, so call the vector - -10 - MOV R10, #SpriteV - BL %FT20 - Pull R14 - ORRVS R14, R14, #V_bit ; if error, set V_bit in link - ExitSWIHandler - -20 - CallAVector - -; ***************************************************************************** -; -; SpriteVecHandler - Default owner of SpriteV -; -; in: R0-R7 contain our entry parameters -; -; out: R0-R7 contain exit parameters -; R8-R12 are preserved -; - - MACRO - SpriteOpDispatch $cond - ADD$cond PC, R10, R11, ASR #8 - MEND - - MACRO - SpriteOpEntry $addr, $flags - & (($addr - SwiSpriteOpCallTb) :SHL: 8) + $flags - MEND - -; The end of this code is put before the beginning, so that -; SpriteDispatchReturn + SVC_mode is within ADR reach of the dispatcher - -BadReasonCode ROUT - ADRL R0, SpriteErr_BadReasonCode - [ International - BL TranslateError - ] - B %FT20 -SpriteIsCurrentDest - ADRL R0, SpriteErr_SpriteIsCurrentDest - [ International - BL TranslateError - ] - B %FT20 - -15 - ADRL R0, SpriteErr_DoesntExist - [ International - BL TranslateError - ] - -20 ; Exit SWI with error, error code in R0 - STR R0, [WsPtr, #RetnReg0] -30 - SETV ; indicate an error - -; and drop thru to... - -SpriteDispatchReturn - ADD R11, WsPtr, #RetnReg0 - LDMIA R11, {R0-R9} ; Restore R0-R9 - MOV R10, R13 ; Point at old returned registers - Push "R0-R9" ; Save new returned registers on stack - LDMIA R10, {R0-R9} ; Load old returned registers - STMIA R11, {R0-R9} ; and put them in the dump area - Pull "R0-R9" ; restore new returned registers - ADD R13, R13, #10*4 ; remove stack frame - Pull "R10-R12,PC" - -SpriteVecHandler - Push "R10-R12" - WritePSRc SVC_mode, WsPtr ; Re-enable interupts - - VDWS WsPtr ; Point R12 at Vdu driver workspace - ADD R11, WsPtr, #RetnReg0 - - SUB R13, R13, #10*4 ; Create stack frame for old RetnRegs - MOV R10, R13 ; Keep pointer to this frame - Push "R0-R9" ; Save new regs while we copy old ones - LDMIA R11, {R0-R9} ; Load old regs - STMIA R10, {R0-R9} ; and push them onto stack - Pull "R0-R9" ; Restore new regs - STMIA R11, {R0-R9} ; Dump R0-R9 - - CMP R0, #RangeC + &100 ; if top bits out of range - BCS BadReasonCode ; then error - - CMP R0, #RangeB ; if Range A type - LDRCC R1, [WsPtr, #SpAreaStart] ; then point at MOS sprite area - - AND R0, R0, #&FF ; Kill the range bits - CMP R0, #SpriteReason_BadReasonCode - BCS BadReasonCode - - ADR R10, SwiSpriteOpCallTb - [ No26bitCode - ADR R14, SpriteDispatchReturn ; return address - | - ADR R14, SpriteDispatchReturn + SVC_mode ; return address - ] - LDR R11, [R10, R0, LSL #2] ; load (offset<<8) + flags - - TST R11, #SSO_ScreenNotAllowed ; if call can specify screen (R2=0) - TEQEQ R2, #0 ; and it is specified - MOVEQ R1, #0 ; then make sprite area ptr 0 as well - TSTNE R11, #SSO_NeedsSomething ; or nothing needed anyway - SpriteOpDispatch EQ ; then dispatch - - TEQ R1, #0 ; else needs sprite area ptr - ADREQ R0, SpriteErr_NoWorkSpace ; so if zero then invalid - [ International - BLEQ TranslateError - ] - BEQ %BT20 - - TST R11, #SSO_DangerAreaOp ; if not a danger area op - BEQ %FT32 ; then skip - - LDR R9, [WsPtr, #VduSpriteArea] ; else check if sprite area is same - TEQ R9, R1 - BEQ SpriteIsCurrentDest ; and error if so - -32 - TST R11, #SSO_NeedsSprite ; if doesn't need sprite - BNE %FT33 - - TEQ R0,#SpriteReason_CreateSprite - BEQ %FT21 - - TEQ R0,#SpriteReason_ScreenSave - TEQNE R0,#SpriteReason_GetSprite - TEQNE R0,#SpriteReason_GetSpriteUserCoords - - SpriteOpDispatch NE ; let it go if we're not interested in it - - LDR R9,[WsPtr, #Log2BPP] ; fetch the current bpp - - CMP R9,#4 - SpriteOpDispatch CC ; let it go if below 16bpp -22 - CMP R3,#0 - BNE %FT34 ; bang if it has a palette - - SpriteOpDispatch ; then dispatch - -21 ;createsprite. R6=mode number or sprite mode word, or => mode descriptor - Push "R0-R3,R14" - MOV R0,R6 - MOV R1,#VduExt_Log2BPP - SWI XOS_ReadModeVariable - MOVCS R2,#0 - CMP R2,#4 - Pull "R0-R3,R14" - SpriteOpDispatch CC - B %BT22 - -33 - TEQ R2, #0 ; if sprite ptr is zero it's a boob - BEQ %BT15 ; so say SpriteDoesntExist - - LDR R9, [WsPtr, #RetnReg0] - CMP R9, #RangeC ; if not range C then must look up - BCS %FT35 ; sprite name and convert to pt4 - Push R14 - BL SpriteCtrlBlk ; in: R2 -> name; out: R2 -> sprite - Pull R14 - BVS %BT15 ; no such sprite - -35 - -;medusa note. -; -;On Medusa masks and palettes for 16/32bpp sprites are in a transient state -;Medusa will fault 16/32bpp mask/palette operations, in readiness for the -;introduction of new (more compact) mask/palette formats. -; -;another medusa note. -; -;Mask operations using 1bpp masks on new format sprites are now being included. -;However palettes on 16/32bpp are still not allowed. -; - -;amg 12/11/93, sort out the logic here so that palettes on new format sprites -;really do get faulted - -;amg 25th May 1994. We now allow palettes on new format sprites of 8bpp -;and below - - ; find the sprite type - LDR R9,[R2,#spMode] - - MOVS R9,R9,LSR #27 ; put the sprite type at b0 - BEQ %FT37 ; t=0 (ie old format) -39 - - CMP R9,#SpriteType_New16bpp ; check sprite type number - BCC %FT37 ; despatch if new format and under 8bpp - - ; so, does it have a palette - Push "R14" ; I need another register for CMP - - ; now check for a palette - ADD R9,R2,#spImage - LDMIA R9,{R9,R14} ; pick up offsets to mask & image - CMP R9,R14 - MOVGT R9,R14 ; R9->top of palette block - SUBS R9,R9,#spPalette ; R9 = size of palette block - Pull "R14" - BEQ %FT38 ; no palette, so no error - -34 - ADRL R0, SpriteErr_NoMaskOrPaletteAllowedInThisDepth - [ International - BL TranslateError - ] - B %BT20 - -37 ;however, until mode selectors work there are some 16/32bpp old modes - Push "R0-R3,R14" ; save context - MOV R0,R9 - MOV R1,#VduExt_Log2BPP - SWI XOS_ReadModeVariable ; read log2bpp for the sprite's mode - MOV R9,R2 ; and move it for posterity - Pull "R0-R3,R14" - CMP R9,#4 - BCS %BT39 ; log2bpp of 4 = 16bpp, so see if we want to fault it -38 - TST R11, #SSO_DangerOp ; if a destructive op - BEQ %FT40 - - LDR R9, [WsPtr, #VduSprite] - TEQ R9, R2 - BEQ SpriteIsCurrentDest ; then stop him! - -40 - TST R11, #SSO_NeedsSpriteModeData - SpriteOpDispatch EQ - - Push "R5-R7, R10, R11, R14" - BL SetupSprModeData - Pull "R5-R7, R10, R11, R14" - SpriteOpDispatch VC - - B %BT30 ; Invalid spMode field - - -SSO_ScreenNotAllowed * 1 :SHL: 0 -SSO_NeedsSomething * 1 :SHL: 1 -SSO_NeedsSprite * 1 :SHL: 2 -SSO_NeedsSpriteModeData * 1 :SHL: 3 -SSO_DangerOp * 1 :SHL: 4 -SSO_DangerAreaOp * 1 :SHL: 5 - -Group1 * SSO_ScreenNotAllowed -Group2 * Group1 + SSO_NeedsSomething -Group3 * Group2 + SSO_NeedsSprite -Group4 * Group3 + SSO_NeedsSpriteModeData -Group5 * SSO_NeedsSomething + SSO_NeedsSprite - -SwiSpriteOpCallTb - SpriteOpEntry DoesNowt, Group1 - - [ AssemblingArthur :LOR: Module - SpriteOpEntry DoesNowt, Group1 - | - SpriteOpEntry ClaimSpace, Group1 ; *SSpace <size> - ] - - SpriteOpEntry ScreenSave, Group1 - SpriteOpEntry ScreenLoad, Group1 - SpriteOpEntry DoesNowt, Group1 - SpriteOpEntry DoesNowt, Group1 - SpriteOpEntry DoesNowt, Group1 - SpriteOpEntry DoesNowt, Group1 - -; The following need valid workspace - - SpriteOpEntry ReadAreaCB, Group2 - SpriteOpEntry ClearSprites, Group2 + SSO_DangerAreaOp ; *SNew - SpriteOpEntry LoadSpriteFile, Group2 + SSO_DangerAreaOp - ; *SLoad <filename> - SpriteOpEntry MergeSpriteFile, Group2 + SSO_DangerAreaOp - ; *SMerge <filename> - SpriteOpEntry SaveSpriteFile, Group2 ; *SSave <filename> - SpriteOpEntry ReturnName, Group2 - SpriteOpEntry GetSprite, Group2 ; *SGet <name> - SpriteOpEntry CreateSprite, Group2 - SpriteOpEntry GetSpriteUserCoords, Group2 - SpriteOpEntry DoesNowt, Group2 - SpriteOpEntry DoesNowt, Group2 - SpriteOpEntry DoesNowt, Group2 - SpriteOpEntry DoesNowt, Group2 - SpriteOpEntry DoesNowt, Group2 - SpriteOpEntry DoesNowt, Group2 - SpriteOpEntry DoesNowt, Group2 - -; The following need a sprite - - SpriteOpEntry SelectSprite, Group3 ; *SChoose <n> [<m>] - SpriteOpEntry DeleteSprite, Group3 + SSO_DangerOp ; *SDelete <n> - SpriteOpEntry RenameSprite, Group3 ; *SRename - SpriteOpEntry CopySprite, Group3 ; *SCopy - SpriteOpEntry PutSprite, Group3 - SpriteOpEntry CreateMask, Group3 - SpriteOpEntry RemoveMask, Group3 + SSO_DangerOp - SpriteOpEntry InsertRow, Group3 + SSO_DangerOp - SpriteOpEntry DeleteRow, Group3 + SSO_DangerOp - SpriteOpEntry FlipAboutXAxis, Group3 - SpriteOpEntry PutSpriteUserCoords, Group3 - SpriteOpEntry DoesNowt, Group3 - SpriteOpEntry DoesNowt, Group3 - SpriteOpEntry DoesNowt, Group3 - SpriteOpEntry DoesNowt, Group3 - SpriteOpEntry DoesNowt, Group3 - -; The following need sprite mode data - - SpriteOpEntry ReadSpriteSize, Group4 - SpriteOpEntry ReadPixelColour, Group4 - SpriteOpEntry WritePixelColour, Group4 - SpriteOpEntry ReadPixelMask, Group4 - SpriteOpEntry WritePixelMask, Group4 - SpriteOpEntry InsertCol, Group4 + SSO_DangerOp - SpriteOpEntry DeleteCol, Group4 + SSO_DangerOp - SpriteOpEntry FlipAboutYAxis, Group4 + SSO_DangerOp - SpriteOpEntry PlotMask, Group4 - SpriteOpEntry PlotMaskUserCoords, Group4 - SpriteOpEntry DoesNowt, Group4 ; 50 ; PlotMaskScaled - SpriteOpEntry DoesNowt, Group4 ; 51 ; PaintCharScaled - SpriteOpEntry DoesNowt, Group4 ; 52 ; PutSpriteScaled - SpriteOpEntry DoesNowt, Group4 ; 53 ; PutSpriteGreyScaled - SpriteOpEntry RemoveLeftHandWastage, Group4 - SpriteOpEntry DoesNowt, Group4 ; 55 PlotMaskTransformed - SpriteOpEntry DoesNowt, Group4 ; 56 PutSpriteTransformed - SpriteOpEntry DoesNowt, Group4 ; 57 InsertDeleteRows - SpriteOpEntry DoesNowt, Group4 ; 58 InsertDeleteColumns - SpriteOpEntry DoesNowt, Group4 ; 59 pseudo reason used by Wimp - -; The following need (sprite area + sprite) or (anything + 0), meaning screen - - SpriteOpEntry SwitchOutputToSprite, Group5 ; 60 - SpriteOpEntry SwitchOutputToMask, Group5 ; 61 - SpriteOpEntry ReadSaveAreaSize, Group5 ; 62 - -; ***************************************************************************** -; -; SetupSprModeData - Set up registers and variables from the sprite mode -; -; Internal routine: called by sprite dispatch, CreateHeader -; -; in: R2 -> sprite -; -; out: R0-R5 preserved -; R6 = ReadNColour (for a single screen pixel) -; R7 = WriteNColour (=R6 except in double pixel modes) -; R8 = BytesPerChar } -; R9 = XShftFactor } calculated from Log2BPC which is BitsPerPix -; R10 = NPix } corrected for double pixel modes -; R11 = Log2BPC } -; -; SprReadNColour..SprLog2BPC setup accordingly -; -; If error, then RetnReg0 updated - -SetupSprModeData ROUT - Push R14 - LDR R11, [R2, #spMode] - [ ModeSelectors - CMP r11, #&100 ; check for mode selector/new format sprite word - BCC %FT05 ; [it's a mode number so check for known ones] - TST r11, #1 ; if it's a new format sprite word - BNE %FT10 ; then call pushmodeinfo to get info on it - B %FT20 ; else it's a mode selector, which is illegal as a sprite mode word -05 - ] - BranchIfKnownMode R11, %FA10 - Push "R2-R4" - MOV R2, R11 - BL OfferModeExtensionAnyMonitor - Pull "R2-R4" - BNE %FT20 - -10 - MOV R10, R11 - BL PushModeInfoAnyMonitor - BVS %FT30 ; if duff new format sprite word, return error - - LDR R11, [R13, #wkModeFlags] - TST R11, #Flag_NonGraphic - BNE %FT15 ; non-graphic mode - - LDR R6, [R13, #wkNColour] ; ReadNColour - ;changed by amg 12/11/93 to stop it mistaking 16/32bpp for 8 -; TST R6, #&F0 ; 256 colour mode ? -; MOVNE R6, #&FF ; then use &FF - CMP R6,#63 - MOVEQ R6,#255 - LDR R11, [R13, #wkLog2BPC] ; Log2BPC - - ADD R13, R13, #PushedInfoSize -11 - MOV R7, #1 - RSB R9, R11, #5 ; XShftFactor - RSB R10, R7, R7, LSL R9 ; NPix - MOV R8, R7, LSL R11 ; BytesPerChar - RSB R7, R7, R7, LSL R8 ; WriteNColour - - Push R5 - ADD R5, WsPtr, #SprReadNColour - STMIA R5, {R6-R11} ; SprRead..SprLog2BPC - [ No26bitCode - CLRV - Pull "R5, PC" - | - Pull "R5, R14" - BICS PC, R14, #V_bit - ] - -15 - ADD R13, R13, #PushedInfoSize -20 - ADRL R0, SpriteErr_InvalidSpriteMode - [ International - BL TranslateError - ] -30 - STR R0, [WsPtr, #RetnReg0] - SETV - Pull pc - - -; ***************************************************************************** - -; Blocks for sprite errors - -SpriteErr_NoWorkSpace MakeErrorBlock Sprite_NoWorkSpace -SpriteErr_NoRoom MakeErrorBlock Sprite_NoRoom -SpriteErr_DoesntExist MakeErrorBlock Sprite_DoesntExist -SpriteErr_NoSprites MakeErrorBlock Sprite_NoSprites -SpriteErr_NotGraphics MakeErrorBlock Sprite_NotGraphics -SpriteErr_NotEnoughRoom MakeErrorBlock Sprite_NotEnoughRoom -SpriteErr_BadSpriteFile MakeErrorBlock Sprite_BadSpriteFile -SpriteErr_NoRoomToMerge MakeErrorBlock Sprite_NoRoomToMerge -SpriteErr_Bad2ndPtr MakeErrorBlock Sprite_Bad2ndPtr -SpriteErr_InvalidRowOrCol MakeErrorBlock Sprite_InvalidRowOrCol -SpriteErr_InvalidHeight MakeErrorBlock Sprite_InvalidHeight -SpriteErr_InvalidWidth MakeErrorBlock Sprite_InvalidWidth -SpriteErr_NoRoomToInsert MakeErrorBlock Sprite_NoRoomToInsert -SpriteErr_SpriteAlreadyExists MakeErrorBlock Sprite_SpriteAlreadyExists -SpriteErr_InvalidSpriteMode MakeErrorBlock Sprite_InvalidSpriteMode -SpriteErr_BadReasonCode MakeErrorBlock Sprite_BadReasonCode -SpriteErr_CantInTeletext MakeErrorBlock Sprite_CantInTeletext -SpriteErr_InvalidSaveArea MakeErrorBlock Sprite_InvalidSaveArea -SpriteErr_SpriteIsCurrentDest MakeErrorBlock Sprite_SpriteIsCurrentDest -SpriteErr_NoMaskOrPaletteAllowedInThisDepth MakeErrorBlock Sprite_NoMaskOrPaletteAllowedInThisDepth - -; ***************************************************************************** -; -; ClearSprites - Clear sprite area (*SNEW) -; -; External routine + dropped thru to -; - -ClearSprites ROUT - LDR R2, [R1, #saFirst] - STR R2, [R1, #saFree] - MOV R2, #0 - STR R2, [R1,#saNumber] - - LDR R0, [WsPtr, #RetnReg0] ; if rangeb or rangec - CMP R0, #RangeB - BHS DoesNowt ; exit immediately - -; else its rangea, so drop thru to ... - -ClearSpritePtrName ROUT - MOV R0, #0 - STR R0, [WsPtr, #SpChoosePtr] - STR R0, [WsPtr, #SpChooseName] - STR R0, [WsPtr, #SpChooseName+4] - STR R0, [WsPtr, #SpChooseName+8] - MOV R0, #13 - STRB R0, [WsPtr, #SpChooseName+12] ; *SChoose <null name> -DoesNowt - RETURNVC - -; ***************************************************************************** -; -; ReadAreaCB - Read information from sprite area CB into registers -; -; External routine -; -; in: R1 -> sprite area -; -; out: R2 = offset to end of sprite area (ie total size) -; R3 = number of sprites in area -; R4 = offset to first sprite -; R5 = offset to first free word -; - -ReadAreaCB ROUT - LDMIA R1, {R2,R3,R4,R5} ; saEnd,saNumber,saFirst,saFree - ADD R11, WsPtr, #RetnReg2 - STMIA R11, {R2,R3,R4,R5} - RETURNVC - -; ***************************************************************************** -; -; SelectSprite - Select a named sprite for use by PLOT &E8..&EF -; -; External routine + called by GetSprite -; -; in: R2 -> sprite CB -; -; out: R0, R9..R11 corrupted -; If not using system sprite area, then R2 -> address of sprite -; - -SelectSprite ROUT - Push R14 - LDR R0, [WsPtr, #RetnReg0] ; if not in system sprite area - CMP R0, #RangeB - STRCS R2, [WsPtr, #RetnReg2] ; return the sprite address - Pull PC, CS - - STR R2, [WsPtr, #SpChoosePtr] ; else store name & address - ADD R14, R2, #spName ; for use by PLOT - LDMIA R14, {R9,R10,R11} ; load 12 bytes of name - LDR R14, =SpChooseName - ADD R14, R14, WsPtr ; RetnReg2 NOT altered, so user - STMIA R14, {R9,R10,R11} ; can't poke the workspace - Pull PC - -; ***************************************************************************** -; -; ReturnName - Return name of nth sprite in sprite area as a string -; -; External routine -; -; in: R1 -> sprite area -; R2 -> buffer -; R3 = max buffer length -; R4 = sprite number (n) -; -; out: R3 actual string length -; RetnReg3 updated -; - -ReturnName ROUT - LDR R5, [R1, #saNumber] ; check for 1 <= R4 <= saNumber - CMP R4, #1 - CMPGE R5, R4 - BGE %FT05 - - ADRL R0, SpriteErr_DoesntExist ; out of range, so generate error - [ International - Push "lr" - BL TranslateError_VClear - Pull "lr" - ] - STR R0, [WsPtr, #RetnReg0] - RETURNVS - -05 LDR R5, [R1, #saFirst] - ADD R5, R5, R1 ; ptr to 1st sprite -10 - SUBS R4, R4, #1 - LDRNE R6, [R5, #spNext] ; if not sprite we want - ADDNE R5, R5, R6 ; chain to next one - BNE %BT10 - - ADD R5, R5, #spName ; found sprite, R5 -> name - - SUBS R3, R3, #1 - MOVLS R3, #0 ; if was 0 or 1 then set R3 to 0 - STRLS R3, [WsPtr, #RetnReg3] - STREQB R3, [R2] ; if was 1 then store 0 terminator - MOVLS PC, R14 ; if was 0 or 1 then exit (assume SUB cleared V) - - CMP R3, #SpriteNameSize ; if length > maximum sprite name len - MOVHI R3, #SpriteNameSize ; then limit to maximum sprite name len - -; R3 is now maximum number of characters to store, excluding terminator - - MOV R6, R2 ; remember start address -20 - LDRB R4, [R5], #1 ; load a byte from sprite name - CMP R4, #" " ; if char > " " - STRHIB R4, [R2], #1 ; then store character and inc ptr - SUBHIS R3, R3, #1 ; and decrement character count - BHI %BT20 ; loop until char<=" " or count expired - - MOV R4, #0 ; store terminating 0 - STRB R4, [R2] - SUB R3, R2, R6 ; R3 = no. of characters, - STR R3, [WsPtr, #RetnReg3] ; excluding terminator - RETURNVC ; indicate no error - -; ***************************************************************************** -; -; RenameSprite - Rename a sprite -; -; External routine (AlreadyExists is used by CopySprite) -; -; in: R2 -> sprite -; R3 -> new name -; - -RenameSprite ROUT - Push "R2, R14" - MOV R2, R3 - BL GetName ; returns name in R9-R11 - BL SpriteCtrlBlk ; try to find sprite of that name - BVC AlreadyExists - Pull "R2, R14" - ADD R8, R2, #spName - STMIA R8, {R9-R11} - KillSpChoosePtr ; in case it points to renamed sprite - RETURNVC - -AlreadyExists ; sprite with new name already exists - Pull "R3, R14" - TEQ R2, R3 ; if it's the same one, then exit VC - RETURNVC ; (SRename/SCopy fred fred is allowed) - - ADRL R0, SpriteErr_SpriteAlreadyExists - [ International - Push "lr" - BL TranslateError - Pull "lr" - ] - STR R0, [WsPtr,#RetnReg0] - RETURNVS - -; ***************************************************************************** -; -; CopySprite - Make a copy of a sprite -; -; External routine -; -; in: R1 -> sprite area -; R2 -> sprite -; R3 -> new name -; - -CopySprite ROUT - Push "R2, R14" ; save ptr to sprite to be copied - MOV R2, R3 - BL GetName ; returns new name in R9-R11 - BL SpriteCtrlBlk ; try to find sprite of that name - BVC AlreadyExists ; [we found one of that name] - Pull R2 - LDR R8, [R1, #saFree] - ADD R8, R8, R1 ; address sprite will be copied to - ADD R8, R8, #spName ; address of its name field - BL AppendSprite ; copy it - STMVCIA R8, {R9-R11} ; if copy OK, rename it - Pull PC ; exit with V clear/set appropriately - -; ***************************************************************************** -; -; ReadSpriteSize - Read sprite size and other info -; -; External routine -; -; in: R2 -> sprite -; -; out: R1,R2 preserved -; R3 = width in pixels -; R4 = height in pixels -; R5 = 0/1 for solid/transparent -; R6 = mode sprite was defined in -; -; RetnReg3..RetnReg6 updated -; - -ReadSpriteSize ROUT - ADD R3, R2, #spWidth - LDMIA R3, {R3,R4,R5,R6} ; spWidth,spHeight,spLBit,spRBit - ADD R4, R4, #1 ; R4 := height in pixels - ADD R3, R3, #1 ; R3 := width in words - RSB R3, R5, R3, LSL #5 ; convert to bits and sub LH wastage - SUB R3, R3, #31 ; subtract RH wastage - ADD R3, R3, R6 - LDR R11, [WsPtr, #SprLog2BPC] - MOV R3, R3, LSR R11 ; number of pixels in row - LDR R5, [R2, #spImage] - LDR R6, [R2, #spTrans] - SUBS R5, R5, R6 - MOVNE R5, #1 ; if spImage=spTrans then no mask - LDR R6, [R2, #spMode] - - ADD R11, WsPtr, #RetnReg3 - STMIA R11, {R3-R6} - - RETURNVC - -; ***************************************************************************** -; -; ReadSpriteWidth - Read width of a sprite -; -; Internal routine, called by PlotMask, InsertCol, DeleteCol -; -; in: R2 -> sprite -; -; out: R0 = sprite width in pixels -; All other registers preserved -; - -ReadSpriteWidth ROUT - Push "R4-R6, R14" - ADD R0, R2, #spWidth - LDMIA R0, {R0,R4,R5,R6} ; spWidth,spHeight,spLBit,spRBit - ADD R0, R0, #1 ; width in words - RSB R0, R5, R0, LSL #5 - SUB R0, R0, #31 - ADD R0, R0, R6 ; total number of bits in row - LDR R5, [WsPtr, #SprLog2BPC] - MOV R0, R0, LSR R5 ; number of pixels in row - Pull "R4-R6, PC" - -; ***************************************************************************** -; -; DeleteSpriteByName -; -; Internal routine, called by MergeSprite, GetSprite, CreateSprite -; -; in: R1 -> sprite area -; R2 -> name of sprite to be deleted -; -; out: All registers preserved -; - -DeleteSpriteByName ROUT - Push "R2-R4, R14" - BL SpriteCtrlBlk ; R2: In , SpriteNamePtr - ; Out, SpriteCBptr - BLVC DeleteSprite ; if found, then delete it - Pull "R2-R4, PC" - -; ***************************************************************************** -; -; DeleteSprite -; -; External routine + called by DeleteSpriteByName -; -; in: R1 -> sprite area -; R2 -> sprite -; -; out: All registers preserved -; - -DeleteSprite ROUT - Push "R0, R3,R4, R14" - LDR R3, [R2, #spNext] - ADD R3, R3, R2 - LDR R0, [R1, #saFree] - ADD R0, R0, R1 - SUB R0, R0, R3 - CopyDown R2, R3, R0, R14, R4 - LDR R3, [R1, #saNumber] ; decrement sprite count - SUB R3, R3, #1 - STR R3, [R1, #saNumber] - SUB R3, R2, R1 ; (R2 points to first free location) - STR R3, [R1, #saFree] ; update saFree - - KillSpChoosePtr ;Because the sprites have moved - - Pull "R0, R3,R4, PC" - -; ***************************************************************************** -; -; GetName - Read sprite name into buffer, lower cased, padded to 12 chars -; -; Internal routine, called by RenameSprite, CopySprite, -; SpriteCtrlBlk, CreateHeader -; -; in: R2 -> sprite name (terminated by char <= 32) -; -; out: Name returned in R9-R11 and NameBuf -; All other registers preserved -; - -GetName ROUT - Push "R2-R5, R14" - ADD R3, WsPtr, #NameBuf - MOV R4, #SpriteNameSize -10 - LDRB R5, [R2], #1 - uk_LowerCase R5, R14 - CMP R5, #" " - STRHIB R5, [R3], #1 - SUBHIS R4, R4, #1 ; loop until char<=32 or done 12 chars - BHI %BT10 - - MOV R5, #0 - CMP R4, #0 ; pad with 0 or more nulls -20 - STRHIB R5, [R3], #1 - SUBHIS R4, R4, #1 - BHI %BT20 - - ADD R9, WsPtr, #NameBuf - LDMIA R9, {R9-R11} ; name returned in R9-R11 and NameBuf - - Pull "R2-R5, PC" - -; ***************************************************************************** -; -; SpriteCtrlBlk - Search for control block of named sprite -; -; Internal routine, called by sprite dispatch, RenameSprite, -; CopySprite, DeleteSpriteByName -; -; in: R1 -> sprite area -; R2 -> sprite name -; -; out: V=0 => R2 -> sprite -; V=1 => sprite not found -; R2 -> first free byte (this fact not used by anyone yet) -; All other registers preserved -; - -SpriteCtrlBlk ROUT - Push "R3-R11, R14" - LDMIA R1, {R3,R4,R5} ; saEnd, saNumber, saFirst - ADD R3, R5, R1 ; point to first sprite/free space - CMP R4, #0 - BEQ %FT20 ; no sprites, exit with R3 pointing - ; at free space and R4=0 - BL GetName ; search name in R9-R11 and NameBuf -10 - LDMIA R3, {R5, R6,R7,R8} ; spNext, spName(0..2) - CMP R6, R9 - CMPEQ R7, R10 - CMPEQ R8, R11 ; (V:=0 if equal) - BEQ %FT30 ; sprite found - - ADD R3, R3, R5 - SUBS R4, R4, #1 ; try next sprite - BNE %BT10 -20 - SETV ; indicate not found -30 - MOV R2, R3 ; R2 -> sprite or to free space - Pull "R3-R11, PC" - - LTORG - -; ***************************************************************************** -; -; InternaliseCoords - Convert from external to internal coords -; for sprite plotting -; -; Internal routine called by PutSpriteUserCoords, PlotMaskUserCoords -; -; in: R3 = external X coordinate -; R4 = external Y coordinate -; -; out: R3 = internal X coordinate -; R4 = internal Y coordinate -; R1, R2, R5 preserved -; - -InternaliseCoords ROUT - Push "R1,R2,R5, R14" - MOV R0, R3 ; put external coordinate in R0,R1 - MOV R1, R4 - ADD R7, WsPtr, #GCsX - LDMIA R7, {R8,R9} ; preserve GCsX,GCsY around EIG - MOV R2, #4 ; indicate absolute coords - BL EIG - STMIA R7, {R8,R9} ; restore GcsX,GCsY - MOV R3, R0 ; internal coord of plotting point - MOV R4, R1 - Pull "R1,R2,R5, PC" - -; ***************************************************************************** -; -; PutSpriteUserCoords - Draw sprite to screen using given ext. coords -; -; External routine -; -; in: R1 -> sprite area (not used) -; R2 -> sprite -; R3 = X coordinate to plot at -; R4 = Y coordinate to plot at -; R5 = GCOL action to be used -; - -PutSpriteUserCoords ROUT - Push R14 - BL InternaliseCoords - Pull R14 - B PutSpri20 - -; ***************************************************************************** -; -; PutSprite - Draw sprite to screen at NewPt -; -; External routine + PutSpri20 called by PutSpriteUserCoords -; (also external) -; -; in: R1 -> sprite area (not used) -; R2 -> sprite -; R5 = GCOL action to be used -; - -; Values held in Ram -; -; N.B. The ordering of these variables is VERY important -; rearrange at your peril -; -; Within the 'memory to screen' drawing loop, WsPtr (R12) points at -; ScrAdr, variables either side being loaded/saved in groups using -; LDMDB / STMIA / LDMIB -; -; SPltWidth } -; SPltHeight } -; SPltScrOff } -; SPltMemOff } LDMDB -; WsPtr -> SPltScrAdr } STMIA -; SPltColCnt } } LDMIB -; SPltMemAdr } -; SPltShftR } -; SPltShftL } -; -; SPltMskAdr -; -; SPltLMask -; SPltRMask -; -; SPltzgooPtr -; -; - -PutSprite ROUT - ASSERT NewPtY = NewPtX +4 - ADD R3, WsPtr, #NewPtX - LDMIA R3, {R3, R4} ; plot sprite at NewPt(X,Y) -PutSpri20 - GraphicsMode R0 - BNE PutSpriNotGraphics ; quit with error if not graphics mode - - Push "WsPtr, R14" ; push both so R12,R14 are free for use - - Push "R2" ; save the pointer to the sprite - - BL GenSpritePlotParmBlk - - Pull "R11" - - BVS SpriteOffScreen - - SWI XOS_RemoveCursors ; assume no error can occur! - - LDR R5, [WsPtr, #SPltMemAdr] - LDR R6, [WsPtr, #SPltMskAdr] - TEQ R6, #0 - BEQ %FT20 - - ADD R6, R6, R5 - STR R6, [WsPtr, #SPltMskAdr] - - LDR R14, [R11, #spMode] - MOV R14,R14,LSR #27 - - ;note: new format 1bpp sprites are thrown at the old routine, since it - ;will render them faster - - CMP R14, #2 - BCC TransPlot ; it's got transparent bits in it! ( - BCS NewTransPlot ; it's got 1bpp transparent bits in it!!! -20 - -; Plot sprite ignoring transparency mask (if any) - - - ADD R11, WsPtr, #SPltzgooMasks - LDMIA R11, {R8-R11} ; masks for screen access (zgoo..zgee) - - LDR R2, [WsPtr, #SPltAction] ; GCOL action - ADD WsPtr, WsPtr, #SPltScrAdr ; repoint WsPtr at SPltScrAdr - LDMIA WsPtr, {R0-R1,R5-R7} - - TEQ R2, #0 - BNE SolPl10 ; not store, do it slowly - -; SimpleCase - -SolPlFast10 - -; R0 ,R1 , R5 ,R6 ,R7 ,(R8 ,R9 ,R10 ,R11 ) -; ScrAdr,ColCnt, MemAdr,ShftR,ShftL,(zgoo,zgeo,zgoe,zgee) - -; Plot the first (leftmost) word - - LDMIA R5, {R2,R3} - ADD R5, R5, #4 - - ShiftR R2,R3, R6,R7 ; shift R3,R2 right R6 places - ; we only need result word R2 - LDR R4, [WsPtr, #SPltLMask-SPltScrAdr] ; on leftmost word - AND R3, R2, R4 ; mask down to just the required pixels - - [ AvoidScreenReads - CMP R4, #&FFFFFFFF - LDRNE R2, [R0] ; plot 1 word - BICNE R2, R2, R4 ; knock out mask bits - ORRNE R3, R2, R3 ; and or sprite bits - | - LDR R2, [R0] ; plot 1 word - BIC R2, R2, R4 ; knock out mask bits - ORR R3, R2, R3 ; and or sprite bits - ] - STR R3, [R0], #4 - - SUBS R1, R1, #1 - BLT SolPlFast50 ; if all plotted, try next scanline - ; else try for blocks of 7 - SUBS R1, R1, #7 - BLT SolPlFast30 - - TEQ R6, #0 ; if shift needed, use loop 20 - BNE SolPlFast20 ; else loop 15 - -SolPlFast15 - -; R0 ,R1 ,R5 -; ScrAdr,ColCnt, ,MemAdr - - LDMIA R5!, {R2-R4,R8-R11} ; read 7 words - STMIA R0!, {R2-R4,R8-R11} ; write 7 words back to screen - SUBS R1, R1, #7 - BGE SolPlFast15 - B SolPlFast30 - -SolPlFast20 - -; R0 ,R1 ,R5 ,R6 ,R7 -; ScrAdr,ColCnt, ,MemAdr,ShftR,ShftL - - LDMIA R5, {R2-R4,R8-R11,R14} ; 8 words needed, gives 7 after shift - ADD R5, R5, #7*4 ; advance source ptr 7 words - - ShiftR R2,R3, R6,R7 ; shift right R6 bits - ShiftR R3,R4, R6,R7 ; we only want result words - ShiftR R4,R8, R6,R7 ; R2-R4, R8-R11 - ShiftR R8,R9, R6,R7 - ShiftR R9,R10, R6,R7 - ShiftR R10,R11, R6,R7 - ShiftR R11,R14, R6,R7 - - STMIA R0!, {R2-R4,R8-R11} ; write 7 words back to screen - SUBS R1, R1, #7 - BGE SolPlFast20 - -SolPlFast30 ; try 1 word at a time - ADDS R1, R1, #7 - -; R0 ,R1 , R5 ,R6 ,R7 -; ScrAdr,ColCnt, MemAdr,ShftR,ShftL - -; If EQ this is rightmost word - -SolPlFast40 - LDMIA R5, {R2,R3} - ADD R5, R5, #4 - - ShiftR R2,R3, R6,R7 ; shift R3,R2 right R6 places - ; we only need result word R2 - BEQ SolPlFast45 ; if rightmost word, jump out. - STR R2, [R0], #4 - - SUBS R1, R1, #1 - B SolPlFast40 - -SolPlFast45 - LDR R4, [WsPtr, #SPltRMask-SPltScrAdr] - AND R3, R2, R4 ; mask down to just the required pixels - - [ AvoidScreenReads - CMP R4, #&FFFFFFFF - LDRNE R2, [R0] ; plot 1 word - BICNE R2, R2, R4 ; knock out mask bits - ORRNE R3, R2, R3 ; and or sprite bits - | - LDR R2, [R0] ; plot 1 word - BIC R2, R2, R4 ; knock out mask bits - ORR R3, R2, R3 ; and or sprite bits - ] - STR R3, [R0], #4 - -SolPlFast50 ; now try the next scanline - LDMDB WsPtr, {R1,R2,R3,R4} ; R1 ,R2 ,R3 ,R4 - ; Width,Height,ScrOff,MemOff - ADD R0, R0, R3 - ADD R5, R5, R4 - SUBS R2, R2, #1 - STRGE R2, [WsPtr, #SPltHeight-SPltScrAdr] - BGE SolPlFast10 ; plot next scanline -ComplicatedExit - SWI XOS_RestoreCursors -SpriteOffScreen - Pull "WsPtr, R14" - RETURNVC - -PutSpriNotGraphics - ADRL R0, SpriteErr_NotGraphics - [ International - Push "lr" - BL TranslateError - Pull "lr" - ] - STR R0, [WsPtr, #RetnReg0] - RETURNVS - - -; Complicated case - -SolPl10 - -; R0 ,R1 , R5 ,R6 ,R7 ,R8 ,R9 ,R10 ,R11 -; ScrAdr,ColCnt, MemAdr,ShftR,ShftL,zgoo,zgeo,zgoe,zgee - -; Plot the first (leftmost) word - - LDMIA R5, {R2,R3} - ADD R5, R5, #4 - - ShiftR R2,R3, R6,R7 ; shift R3,R2 right R6 places - ; we only need result word R2 - - OrrEor R3,R2, R10,R11 ; form EOR mask - OrrEor R2,R2, R8,R9 ; form OR mask - - LDR R4, [WsPtr, #SPltLMask-SPltScrAdr] ; on leftmost word - AND R2, R2, R4 ; mask down to just the required pixels - AND R3, R3, R4 - - LDR R4, [R0] ; plot 1 word - OrrEor R4,R4, R2,R3 - STR R4, [R0], #4 - - SUBS R1, R1, #1 - BLT SolPl50 ; if all plotted, try next scanline - ; else try for blocks of 4 - SUBS R1, R1, #4 - BLT SolPl30 - -SolPl20 - STMIA WsPtr, {R0,R1} ; save ScrAdr,ColCnt - -; R0 ,R1 ,R5 ,R6 ,R7 ,R8 ,R9 ,R10 ,R11 -; ScrAdr,ColCnt, ,MemAdr,ShftR,ShftL,zgoo,zgeo,zgoe,zgee - - LDMIA R5, {R0-R4} ; 5 words needed, gives 4 after shift - ADD R5, R5, #16 ; advance source ptr 4 words - STR R5, [WsPtr, #SPltMemAdr-SPltScrAdr] - - ShiftR R0,R1, R6,R7 ; shift R4-R0 right R6 bits - ShiftR R1,R2, R6,R7 ; we only want result words R3-R0 - ShiftR R2,R3, R6,R7 - ShiftR R3,R4, R6,R7 - - LDR R4, [WsPtr] ; get screen address - LDMIA R4, {R4-R7} ; get 4 screen words - - ORoreorEORoreor R4,R0, R8,R9,R10,R11, R14 - ORoreorEORoreor R5,R1, R8,R9,R10,R11, R14 - ORoreorEORoreor R6,R2, R8,R9,R10,R11, R14 - ORoreorEORoreor R7,R3, R8,R9,R10,R11, R14 - - LDR R0, [WsPtr] ; screen address - STMIA R0!, {R4-R7} ; write 4 words back to screen - LDMIB WsPtr, {R1,R5-R7} ; reload anything we shat on - - SUBS R1, R1, #4 - BGE SolPl20 - -SolPl30 ; try 1 word at a time - ADDS R1, R1, #4 - -; R0 ,R1 , R5 ,R6 ,R7 ,R8 ,R9 ,R10 ,R11 -; ScrAdr,ColCnt, MemAdr,ShftR,ShftL,zgoo,zgeo,zgoe,zgee - -; If EQ this is rightmost word - -SolPl40 - LDMIA R5, {R2,R3} - ADD R5, R5, #4 - - ShiftR R2,R3, R6,R7 ; shift R3,R2 right R6 places - ; we only need result word R2 - OrrEor R3,R2, R10,R11 ; form EOR mask - OrrEor R2,R2, R8,R9 ; form OR - - LDREQ R4, [WsPtr, #SPltRMask-SPltScrAdr] ; if rightmost word, - ANDEQ R2, R2, R4 ; mask down to just the - ANDEQ R3, R3, R4 ; required pixels - - LDR R4, [R0] - OrrEor R4,R4, R2,R3 - STR R4, [R0], #4 - - SUBS R1, R1, #1 - BGE SolPl40 - -SolPl50 ; now try the next scanline - LDMDB WsPtr, {R1,R2,R3,R4} ; R1 ,R2 ,R3 ,R4 - ; Width,Height,ScrOff,MemOff - ADD R0, R0, R3 - ADD R5, R5, R4 - SUBS R2, R2, #1 - STRGE R2, [WsPtr, #SPltHeight-SPltScrAdr] - BGE SolPl10 ; plot next scanline - B ComplicatedExit - -; ***************************************************************************** -; -; NewTransPlot - Plot sprite using 1 bpp transparency mask -; Called with R11 -> sprite -; TransPlot is used for 1bpp new sprites since it will be faster - -NewTransPlot ROUT - - ; need to derive: bpp, and 1<<(5-log2bpp) - - LDR R10, [R11, #spMode] - MOV R10, R10, LSR #27 - ADRL R0, NSM_bpptable-4 - LDR R10, [R0, R10, LSL #2] ; get the log2bpp to R10 - - ;R10=log2bpp, R11=>sprite - - LDR R8, [R11, #spWidth] ; words-1 - - ADD R9, R8, #1 - MOV R9, R9, LSL #2 ; number of bytes per row - STR R9, [WsPtr, #SPltMaskRowPtr] - - LDR R9, [R11, #spRBit] ; last bit used - ADD R9, R9, #1 ; change to number of bits - MOV R9, R9, LSR R10 ; number of pixels - - RSB R0, R10, #5 - MOV R8, R8, LSL R0 ; number of pixels for full words - - ADD R8, R8, R9 ; total number of pixels - - ANDS R9, R8, #&1F - MOVNE R9, #4 - BIC R8, R8, #&1F - ADD R9, R9, R8, LSR #3 ; number of bytes per mask row - - STR R9, [WsPtr, #SPltMaskRowLen] - - LDR R8, [R11, #spImage] - LDR R9, [R11, #spTrans] - ADD R8, R8, R11 - ADD R9, R9, R11 - - ;RSB R0, R10, #5 <- DONE ABOVE - - MOV R1, #1 - MOV R2, R1, LSL R0 ; r2 holds number of pixels per word - - MOV R3, R1, LSL R10 ; r3 holds bits per pixel - - ADD WsPtr, WsPtr, #SPltScrAdr ; repoint WsPtr, at SPltScrAdr - - LDMIA WsPtr, {R0-R1,R5-R7,R14} - - STR R2, [WsPtr, #SPltPixPerWord-SPltScrAdr] - STR R3, [WsPtr, #SPltBPP-SPltScrAdr] - - ; sort out where to begin in 1bpp mask (rewritten Aug '93) - - MOV LR, R9 ; LR = mask pointer - MOV R3, #0 ; R3 = mask bit - CMP R5, R8 ; R5=>data to plot, R8=>start of sprite - - BEQ %FT11 ; nothing to do, go store R3 & LR - BCC %FT13 ; start is before sprite data - - ;R3, R9, r10, R11 free - ;R2 comes in holding pix per word - - ;if R6 is non zero the image will be a word early. - MOV R9, R5 ; working copy of pointer within sprite - CMP R6, #0 - ADDNE R9, R9, #4 ; take out the extra word for now - - LDR R11,[WsPtr, #SPltMaskRowLen-SPltScrAdr] ; bytes per mask row - - SUBS R10, R9, R8 ; difference in bytes - - LDR R8,[WsPtr, #SPltMaskRowPtr-SPltScrAdr] ; loaded with bytes per image row - BEQ %FT13 -14 - ;is it less than a row of data - CMP R10, R8 - BCC %FT12 ; yes it is - - ;deal with a row (or more of data) - SUB R10, R10, R8 - ADD LR, LR, R11 - B %BT14 - -12 ;start point is on this row. subtract 4 from difference and add - ;pix per word to mask bit/ptr until diff=0 - CMP R10, #0 - BEQ %FT13 - - SUB R10, R10, #4 - - ADD R3, R3, R2 - CMP R3, #32 - SUBCS R3, R3, #32 - ADDCS LR, LR, #4 - CMP R10, #0 - BNE %BT12 - -13 - ;deal with R6 - CMP R6,#0 - BEQ %FT11 - - SUBS R3, R3, R2 ;subtract pix per word - ADDMI R3, R3, #32 - SUBMI LR, LR, #4 ;deal with going into previous word - -11 - STR R3, [WsPtr, #SPltMaskBit-SPltScrAdr] - STR LR, [WsPtr, #SPltMaskPtr-SPltScrAdr] - - ; and save it for the end of row increments - STR R3, [WsPtr, #SPltMaskRowBit-SPltScrAdr] - STR LR, [WsPtr, #SPltMaskRowPtr-SPltScrAdr] - - ADD R11, WsPtr, #SPltzgooMasks-SPltScrAdr - LDMIA R11, {R8-R11} ; masks for screen access (zgoo..zgee) - -NTrnPl10 - -; R0 ,R1 , R5 ,R6 ,R7 ,R8 ,R9 ,R10 ,R11, R14 -; ScrAdr,ColCnt, MemAdr,ShftR,ShftL,zgoo,zgeo,zgoe,zgee, -; -; As far as possible this is based on the original transplot. -; - -; Plot the first (leftmost) word - - BL getmaskword - MOV R2, R3 - - BL getmaskword_noinc - ShiftR R2,R3, R6,R7 ; we only need result word R2 - - LDMIA R5, {R3,R4} ; fetch and shift image - ADD R5, R5, #4 - ShiftR R3,R4, R6,R7 ; shift R4,R3 right R6 places - - OrrEor R4,R3, R10,R11 ; form EOR mask - OrrEor R3,R3, R8,R9 ; form OR mask - - AND R3, R3, R2 ; clear out any transparent pixels - AND R4, R4, R2 - - LDR R2, [WsPtr, #SPltLMask-SPltScrAdr] ; on leftmost word - AND R3, R3, R2 ; mask down to just the required pixels - AND R4, R4, R2 - - LDR R2, [R0] ; plot 1 word - OrrEor R2,R2, R3,R4 - STR R2, [R0], #4 - - SUBS R1, R1, #1 - BLT NTrnPl50 ; if all plotted, try next scanline - ; else try for blocks of 2 - SUBS R1, R1, #2 - BLT NTrnPl30 - -NTrnPl20 - STMIA WsPtr, {R0,R1} ; ScrAdr,ColCnt - -; R0 ,R1 ,R5 ,R6 ,R7 ,R8 ,R9 ,R10 ,R11 , R14 -; ScrAdr,ColCnt, ,MemAdr,ShftR,ShftL,zgoo,zgeo,zgoe,zgee, MskAdr - - - BL getmaskword - MOV R0, R3 - BL getmaskword - MOV R1, R3 - - BL getmaskword_noinc - MOV R2, R3 - ShiftR R0,R1, R6,R7 - ShiftR R1,R2, R6,R7 ; aligned mask in R0,R1 - - LDMIA R5, {R2-R4} ; 3 image words needed, gives 2 after - ADD R5, R5, #8 ; shifting - STR R5, [WsPtr, #SPltMemAdr-SPltScrAdr] - ShiftR R2,R3, R6,R7 - ShiftR R3,R4, R6,R7 ; aligned image in R2,R3 - - LDR R4, [WsPtr] ; screen address - LDMIA R4, {R4,R5} ; 2 screen words - - ORoreorEORoreorMASK R4,R2,R0, R8,R9,R10,R11, R14 - ORoreorEORoreorMASK R5,R3,R1, R8,R9,R10,R11, R14 - - LDR R0, [WsPtr] ; screen address - STMIA R0!, {R4,R5} ; write 2 words back to screen - LDMIB WsPtr, {R1,R5,R6} ; reload anything we shat on - - SUBS R1, R1, #2 - BGE NTrnPl20 - -NTrnPl30 ; try 1 word at a time - ADDS R1, R1, #2 - -; R0 ,R1 , R5 ,R6 ,R7 ,R8 ,R9 ,R10 ,R11 -; ScrAdr,ColCnt, MemAdr,ShftR,ShftL,zgoo,zgeo,zgoe,zgee - -; If EQ this is rightmost word - -NTrnPl40 - - BL getmaskword - MOV R2, R3 - - BL getmaskword_noinc - ShiftR R2,R3, R6,R7 ; shift R3,R2 right R6 places, result in R2 - - LDMIA R5, {R3,R4} ; fetch and align image - ADD R5, R5, #4 - ShiftR R3,R4, R6,R7 ; shift R4,R3 right R6 places, result in R3 - - OrrEor R4,R3, R10,R11 ; form EOR mask - OrrEor R3,R3, R8,R9 ; form OR - - AND R3, R3, R2 ; clear out transparant pixels - AND R4, R4, R2 - - LDREQ R2, [WsPtr, #SPltRMask-SPltScrAdr] ; if rightmost word, - ANDEQ R3, R3, R2 ; mask down to just the - ANDEQ R4, R4, R2 ; required pixels - - LDR R2, [R0] - OrrEor R2,R2, R3,R4 - STR R2, [R0], #4 - - SUBS R1, R1, #1 - BGE NTrnPl40 - -NTrnPl50 - ; now try the next scanline - - ; BEWARE ... genspriteplotparmblock returns values for memoff and - ; scroff which take account of alignment of screen and sprite data - ; - ; Do not alter the logic below unless you really know what - ; to expect from this routine!! - - LDR LR, [WsPtr, #SPltMaskRowPtr-SPltScrAdr] - LDR R3, [WsPtr, #SPltMaskRowBit-SPltScrAdr] - - LDR R2, [WsPtr, #SPltMaskRowLen-SPltScrAdr] - - ADD LR, LR, R2 - - STR LR, [WsPtr, #SPltMaskPtr-SPltScrAdr] - STR R3, [WsPtr, #SPltMaskBit-SPltScrAdr] - STR LR, [WsPtr, #SPltMaskRowPtr-SPltScrAdr] - STR R3, [WsPtr, #SPltMaskRowBit-SPltScrAdr] - - LDMDB WsPtr, {R1,R2,R3,R4} ; R1 ,R2 ,R3 ,R4 - ; Width,Height,ScrOff,MemOff - - ADD R0, R0, R3 - ADD R5, R5, R4 - - SUBS R2, R2, #1 - STRGE R2, [WsPtr, #SPltHeight-SPltScrAdr] - BGE NTrnPl10 ; plot next scanline - - SWI XOS_RestoreCursors - - Pull "WsPtr, R14" - RETURNVC - -; get a mask word without incrementing the pointers - -getmaskword_noinc ROUT - Push "R4, R5, LR" - - LDR R4, [WsPtr, #SPltMaskBit-SPltScrAdr] - LDR R5, [WsPtr, #SPltMaskPtr-SPltScrAdr] - BL getmaskword ; preserves flags - STR R4, [WsPtr, #SPltMaskBit-SPltScrAdr] - STR R5, [WsPtr, #SPltMaskPtr-SPltScrAdr] - - LDMFD R13!,{R4,R5,R15} ; must preserve flags - -; get a mask word, and increment pointers - -getmaskword ROUT - [ No26bitCode - Push "R2,R4,R5,R6,R7,R8,R14" - MRS R8, CPSR - | - Push "R2,R4,R5,R6,R7,R14" - ] - -;R6 -> mask -;R7 = bit offset - -;return in R3, update R6, R7, restore other registers - - MOV R3, #0 ; initial result - LDR LR, [WsPtr, #SPltPixPerWord-SPltScrAdr] ; pixels per word - LDR R2, [WsPtr, #SPltBPP-SPltScrAdr] ; bpp - - LDR R7, [WsPtr, #SPltMaskBit-SPltScrAdr] - LDR R6, [WsPtr, #SPltMaskPtr-SPltScrAdr] - - LDR R4, [R6] ; get the mask word -10 - CMP R7, #0 - LDREQ R4, [R6] ; fetch a new word if required - MOV R5, R4, LSR R7 ; shift desired bit down to bit 0 - - MOV R3, R3, LSR #1 ; shift down the result by one bit - ORR R3, R3, R5, LSL #31 ; and put bit 0 in at bit 31 - - ; now use an ASR of bpp-1 to finish off - SUB R5, R2, #1 - MOV R3, R3, ASR R5 - - ADD R7, R7, #1 ; next mask bit - - CMP R7, #32 ; on to next word ? - ADDEQ R6, R6, #4 ; increment mask word pointer - MOVEQ R7, #0 ; bit pointer back to 0 - ; but don't fetch new word until it is needed! - - SUBS LR, LR, #1 ; one pixel done - BNE %BT10 - - STR R7, [WsPtr, #SPltMaskBit-SPltScrAdr] - STR R6, [WsPtr, #SPltMaskPtr-SPltScrAdr] - - ;result in R3, MaskBit/MaskPtr adjusted - - [ No26bitCode - MSR CPSR_f, R8 - LDMFD R13!,{R2,R4,R5,R6,R7,R8,R15} ; must save flags - | - LDMFD R13!,{R2,R4,R5,R6,R7,R15}^ ; must save flags - ] - - LTORG - -; ***************************************************************************** -; -; TransPlot - Plot sprite using transparency mask -; - -TransPlot - ADD R11, WsPtr, #SPltzgooMasks - LDMIA R11, {R8-R11} ; masks for screen access (zgoo..zgee) - - ADD WsPtr, WsPtr, #SPltScrAdr ; repoint WsPtr, at SPltScrAdr - - LDMIA WsPtr, {R0-R1,R5-R7,R14} - -TrnPl10 - -; R0 ,R1 , R5 ,R6 ,R7 ,R8 ,R9 ,R10 ,R11, R14 -; ScrAdr,ColCnt, MemAdr,ShftR,ShftL,zgoo,zgeo,zgoe,zgee, MskAdr - -; Plot the first (leftmost) word - - LDMIA R14, {R2,R3} ; fetch and shift mask right R6 places - ADD R14, R14, #4 - ShiftR R2,R3, R6,R7 ; we only need result word R2 - - LDMIA R5, {R3,R4} ; fetch and shift image - ADD R5, R5, #4 - ShiftR R3,R4, R6,R7 ; shift R4,R3 right R6 places - ; we only need result word R3 - OrrEor R4,R3, R10,R11 ; form EOR mask - OrrEor R3,R3, R8,R9 ; form OR mask - - AND R3, R3, R2 ; clear out any transparent pixels - AND R4, R4, R2 - - LDR R2, [WsPtr, #SPltLMask-SPltScrAdr] ; on leftmost word - AND R3, R3, R2 ; mask down to just the required pixels - AND R4, R4, R2 - - LDR R2, [R0] ; plot 1 word - OrrEor R2,R2, R3,R4 - STR R2, [R0], #4 - - SUBS R1, R1, #1 - BLT TrnPl50 ; if all plotted, try next scanline - ; else try for blocks of 2 - SUBS R1, R1, #2 - BLT TrnPl30 - -TrnPl20 - STMIA WsPtr, {R0,R1} ; ScrAdr,ColCnt - -; R0 ,R1 ,R5 ,R6 ,R7 ,R8 ,R9 ,R10 ,R11 , R14 -; ScrAdr,ColCnt, ,MemAdr,ShftR,ShftL,zgoo,zgeo,zgoe,zgee, MskAdr - - LDMIA R14, {R0-R2} ; 3 mask words, gives 2 after shifting - ADD R14, R14, #8 ; advance mask ptr 2 words - ShiftR R0,R1, R6,R7 - ShiftR R1,R2, R6,R7 ; aligned mask in R0,R1 - - LDMIA R5, {R2-R4} ; 3 image words needed, gives 2 after - ADD R5, R5, #8 ; shifting - STR R5, [WsPtr, #SPltMemAdr-SPltScrAdr] - ShiftR R2,R3, R6,R7 - ShiftR R3,R4, R6,R7 ; aligned image in R2,R3 - - LDR R4, [WsPtr] ; screen address - LDMIA R4, {R4,R5} ; 2 screen words - - ORoreorEORoreorMASK R4,R2,R0, R8,R9,R10,R11, R6 - ORoreorEORoreorMASK R5,R3,R1, R8,R9,R10,R11, R6 - - LDR R0, [WsPtr] ; screen address - STMIA R0!, {R4,R5} ; write 2 words back to screen - LDMIB WsPtr, {R1,R5-R6} ; reload anything we shat on - - SUBS R1, R1, #2 - BGE TrnPl20 - -TrnPl30 ; try 1 word at a time - ADDS R1, R1, #2 - -; R0 ,R1 , R5 ,R6 ,R7 ,R8 ,R9 ,R10 ,R11 -; ScrAdr,ColCnt, MemAdr,ShftR,ShftL,zgoo,zgeo,zgoe,zgee - -; If EQ this is rightmost word - -TrnPl40 - LDMIA R14, {R2,R3} ; fetch and align trans mask - ADD R14, R14, #4 - ShiftR R2,R3, R6,R7 ; shift R3,R2 right R6 places, result in R2 - - LDMIA R5, {R3,R4} ; fetch and align image - ADD R5, R5, #4 - ShiftR R3,R4, R6,R7 ; shift R4,R3 right R6 places, result in R3 - - OrrEor R4,R3, R10,R11 ; form EOR mask - OrrEor R3,R3, R8,R9 ; form OR - - AND R3, R3, R2 ; clear out transparant pixels - AND R4, R4, R2 - - LDREQ R2, [WsPtr, #SPltRMask-SPltScrAdr] ; if rightmost word, - ANDEQ R3, R3, R2 ; mask down to just the - ANDEQ R4, R4, R2 ; required pixels - - LDR R2, [R0] - OrrEor R2,R2, R3,R4 - STR R2, [R0], #4 - - SUBS R1, R1, #1 - BGE TrnPl40 - -TrnPl50 ; now try the next scanline - LDMDB WsPtr, {R1,R2,R3,R4} ; R1 ,R2 ,R3 ,R4 - ; Width,Height,ScrOff,MemOff - ADD R0, R0, R3 - ADD R5, R5, R4 - ADD R14, R14, R4 - SUBS R2, R2, #1 - STRGE R2, [WsPtr, #SPltHeight-SPltScrAdr] - BGE TrnPl10 ; plot next scanline - - SWI XOS_RestoreCursors - - Pull "WsPtr, R14" - RETURNVC - - LTORG - -; ***************************************************************************** -; -; PlotMaskUserCoords - Draw a rectangle through a sprite mask -; using given external coordinates -; -; External routine -; -; in: R1 -> sprite area (not used) -; R2 -> sprite -; R3 = X coordinate to plot at -; R4 = Y coordinate to plot at -; - -PlotMaskUserCoords ROUT - Push R14 - BL InternaliseCoords - Pull R14 - B PlotMa20 - -; ***************************************************************************** -; -; PlotNewMask -; -; Version of PlotMask for new 1bpp format sprites - -PlotNewMask ROUT - - LDR R10, [R2, #spMode] - MOV R10, R10, LSR #27 - ADRL R0, NSM_bpptable-4 - LDR R10, [R0, R10, LSL #2] ;get the log2bpp - - ;derive mask row length - ;r10=log2bpp, r2=>sprite - - LDR R8, [R2, #spWidth] ; words-1 - - ADD R9, R8, #1 ; total words for a line of image - MOV R9, R9, LSL #2 ; total bytes for a line of image - STR R9, [WsPtr, #SPltMaskRowPtr] - ; save it for determining mask start position - - LDR R9, [R2, #spRBit] ; last bit used - ADD R9, R9, #1 ; change to number of bits - MOV R9, R9, LSR R10 ; number of pixels - - RSB R0, R10, #5 - MOV R8, R8, LSL R0 ; number of pixels for full words - - ADD R8, R8, R9 ; total number of pixels - - ANDS R9, R8, #&1F - MOVNE R9, #4 - BIC R8, R8, #&1F - ADD R9, R9, R8, LSR #3 ; number of bytes per mask row - - STR R9, [WsPtr, #SPltMaskRowLen] - - MOV R1, #1 - MOV R0, R1, LSL R0 ;number of pixels - - MOV R6, R1, LSL R10 ;bits per pixel - - STR R0, [WsPtr, #SPltPixPerWord] - STR R6, [WsPtr, #SPltBPP] - - LDR R0, [R2, #spHeight] - ADD R0, R0, R4 - LDR R10, [WsPtr, #GWTRow] - Least R0, R0, R10 ; top scanline within window - - LDR R10, [WsPtr, #YWindLimit] - SUB R0, R10, R0 ; flip Y - AND R0, R0, #7 - STR R0, [WsPtr, #SPltEcfIndx] ; index into Ecf - - ADD R0, WsPtr, R0, LSL #3 - ADD R0, R0, #BgEcfOraEor - STR R0, [WsPtr, #SPltEcfPtr] ; ptr to ECF for highest row plotted - - ;STR R2, [WsPtr, #SPltMaskRowPtr] ;temp, to save it - - LDR R8, [R2, #spImage] - LDR R9, [R2, #spTrans] - ADD R8, R8, R2 - ADD R9, R9, R2 - - Push "WsPtr, R14" ; push both so R12,R14 are free for use - Push "R2" - - BL GenSpritePlotParmBlk - - Pull "R2" - - BVS SpriteOffScreen - SWI XOS_RemoveCursors ; assume no error can occur! - - ;LDR R2, [WsPtr, #SPltMaskRowPtr] ;recover pointer to sprite - - LDR R8, [R2, #spImage] ;offset to image - LDR R9, [R2, #spTrans] ;offset to mask - ADD R8, R8, R2 ;change to address of image - ADD R9, R9, R2 ;change to address of mask - - LDR R5, [WsPtr, #SPltMemAdr] ;start memory address to plot - LDR LR, [WsPtr, #SPltMskAdr] ;start mask address to plot - TEQ LR, #0 ;off screen ? - BEQ SpriteOffScreen ;so plot nothing - - ;amg 19/1/94 rip out the original algorithm and replace it with the correct one - ;used with newtransplot which correctly handles genspriteplotparmblk's oddities - - ;now deal with sprites where we aren't starting - ;at the beginning.... - LDR R2, [WsPtr, #SPltPixPerWord] ;pick up pixels per word - - MOV LR, R9 ;save mask address - MOV R3, #0 ;set mask pixel counter to 0 - CMP R5, R8 ;memory address to plot from = image address ? - BEQ %FT11 ;yes - no fudging needed - BCC %FT13 - - MOV R9, R5 ;working copy of plot start within sprite - CMP R6, #0 - ADDNE R9, R9, #4 ;take out the extra word for now - - LDR R11, [WsPtr, #SPltMaskRowLen] ;bytes per mask row - SUBS R10, R9, R8 ;difference between plot start & sprite start - LDR R8, [WsPtr, #SPltMaskRowPtr] ;bytes per image row - BEQ %FT13 ;no difference - -14 - ;is it less than a row of data different ? - CMP R10, R8 - BCC %FT12 ;yes, it is - - ;deal with whole rows - SUB R10, R10, R8 ;decrease difference by size of image row - ADD LR, LR, R11 ;increase mask pointer by size of mask row - B %BT14 ;and loop until less than a row to do - -12 ;start pointer is on this row. reduce the difference and increase the mask start - ;point until they match - - CMP R10, #0 ;check for nothing to do - BEQ %FT13 - - SUB R10, R10, #4 ;reduce image by a word - - ADD R3, R3, R2 ;increase mask start pixel by the number of - ;pixels in that word - - CMP R3, #32 - SUBCS R3, R3, #32 - ADDCS LR, LR, #4 ;get the mask bit back into a word's worth - - CMP R10, #0 ;extra test down here to avoid taking two - BNE %BT12 ;branches - -13 ;remember R6 ? uncompensate now - CMP R6, #0 - BEQ %FT11 - - SUBS R3, R3, R2 ;go back by the number of pixels in a word - ADDMI R3, R3, #32 - SUBMI LR, LR, #4 ;deal with going back into previous mask word - -11 - STR R3, [WsPtr, #SPltMaskBit] ;starting mask bit to plot - STR LR, [WsPtr, #SPltMaskPtr] ;starting mask word to plot - - ; and save it for the end of row increments - STR R3, [WsPtr, #SPltMaskRowBit] - STR LR, [WsPtr, #SPltMaskRowPtr] - - STR LR, [WsPtr, #SPltMskAdr] - STR LR, [WsPtr, #SPltMemAdr] - - ADD WsPtr, WsPtr, #SPltScrAdr ; repoint WsPtr at SPltScrAdr - - LDMIA WsPtr, {R0-R1,R5-R7} - - LDR R5, [WsPtr, #SPltMaskPtr-SPltScrAdr] - LDR R8, [WsPtr, #SPltEcfPtr-SPltScrAdr] -10 - LDMIA R8, {R8,R9} ; ora,eor for this row - -; R0 ,R1 , R5 ,R6 ,R7 ,R8 ,R9 -; ScrAdr,ColCnt, MemAdr,ShftR,ShftL,ora,eor - -; Plot the first (Leftmost) word - - BL getmaskword - MOV R2, R3 - - BL getmaskword_noinc - - ShiftR R2,R3, R6,R7 ; shift R3,R2 right R6 places - ; we only need result word R2 - LDR R10, [WsPtr, #SPltLMask-SPltScrAdr] ; on leftmost word - AND R2, R2, R10 ; mask down to just the required pixels - - LDR R4, [R0] ; plot 1 word - OrrEorMASK R4,R2, R8,R9, R14 - STR R4, [R0], #4 - - SUBS R1, R1, #1 - BLT %FT50 ; if all plotted, try next scanline - ; else try for blocks of 4 - SUBS R1, R1, #4 - BLT %FT30 - -20 - STMIA WsPtr, {R0,R1} ; save ScrAdr,ColCnt - -; R0 ,R1 ,R5 ,R6 ,R7 -; ScrAdr,ColCnt, ,MemAdr,ShftR,ShftL - - - BL getmaskword - MOV R0, R3 - BL getmaskword - MOV R1, R3 - BL getmaskword - MOV R2, R3 - BL getmaskword - MOV R8, R3 - BL getmaskword_noinc - MOV R4,R3 - MOV R3,R8 - - ShiftR R0,R1, R6,R7 ; shift R4-R0 right R6 bits - ShiftR R1,R2, R6,R7 ; we only want result words R3-R0 - ShiftR R2,R3, R6,R7 - ShiftR R3,R4, R6,R7 - - LDR R4, [WsPtr] ; get screen address - LDMIA R4, {R8-R11} ; get 4 screen words - - LDR R6, [WsPtr, #SPltEcfPtr-SPltScrAdr] - LDMIA R6, {R6,R7} ; ora,eor for this row - - OrrEorMASK R8,R0, R6,R7, R14 ; Scr:=ScrOR(oraANDmsk)EOR(eorANDmsk) - OrrEorMASK R9,R1, R6,R7, R14 - OrrEorMASK R10,R2, R6,R7, R14 - OrrEorMASK R11,R3, R6,R7, R14 - - LDR R0, [WsPtr] ; screen address - STMIA R0!, {R8-R11} ; write 4 words back to screen - LDMIB WsPtr, {R1,R5-R7} ; reload anything we shat on - - SUBS R1, R1, #4 - BGE %BT20 - -30 ; try 1 word at a time - ADDS R1, R1, #4 - -; R0 ,R1 , R5 ,R6 ,R7 ,R8 ,R9 -; ScrAdr,ColCnt, MemAdr,ShftR,ShftL,ora,eor - -; If EQ this is rightmost word - - LDR R8, [WsPtr, #SPltEcfPtr-SPltScrAdr] - LDMIA R8, {R8,R9} ; ora,eor for this row - LDR R10, [WsPtr, #SPltRMask-SPltScrAdr] -40 - - BL getmaskword - MOV R2, R3 - - BL getmaskword_noinc - ShiftR R2,R3, R6,R7 ; shift R3,R2 right R6 places, result in R2 - ; we only need result word R2 - - ANDEQ R2, R2, R10 ; if rightmost word, mask down to just the - ; required pixels - LDR R4, [R0] - OrrEorMASK R4,R2, R8,R9, R14 - STR R4, [R0], #4 - - SUBS R1, R1, #1 - BGE %BT40 - -50 ; now try the next scanline - ; BEWARE ... genspriteplotparmblock returns values for memoff and - ; scroff which take account of alignment of screen and sprite data - ; - ; Do not alter the logic below unless you really know what - ; to expect from this routine!! - - LDMDB WsPtr, {R1,R2,R3,R4} ; R1 ,R2 ,R3 ,R4 - ; Width,Height,ScrOff,MemOff - - - LDR LR, [WsPtr, #SPltMaskRowPtr-SPltScrAdr] - LDR R3, [WsPtr, #SPltMaskRowBit-SPltScrAdr] - - LDR R2, [WsPtr, #SPltMaskRowLen-SPltScrAdr] - - ADD LR, LR, R2 - - STR LR, [WsPtr, #SPltMaskPtr-SPltScrAdr] - STR R3, [WsPtr, #SPltMaskBit-SPltScrAdr] - STR LR, [WsPtr, #SPltMaskRowPtr-SPltScrAdr] - STR R3, [WsPtr, #SPltMaskRowBit-SPltScrAdr] - - LDMDB WsPtr, {R1,R2,R3,R4} ; R1 ,R2 ,R3 ,R4 - ; Width,Height,ScrOff,MemOff - ADD R0, R0, R3 - - ADD R10, WsPtr, #(SPltEcfPtr-SPltScrAdr) - - LDMIA R10, {R8,R9} ; EcfPtr,EcfIndx - ADD R8, R8, #8 ; step both to next row in Ecf - ADD R9, R9, #1 - CMP R9, #8 - MOVGE R9, #0 ; it's a wrap! - SUBGE R8, R8, #(8*8) - STMIA R10, {R8,R9} - - SUBS R2, R2, #1 - STRGE R2, [WsPtr, #SPltHeight-SPltScrAdr] - BGE %BT10 ; plot next scanline - - SWI XOS_RestoreCursors - - Pull "WsPtr, R14" - RETURNVC - -; ***************************************************************************** -; -; PlotMask - Draw a rectangle through a sprite mask -; -; External routine + PlotMa20 called by PlotMaskUserCoords -; (also external) -; -; in: R1 -> sprite area (not used) -; R2 -> sprite -; - -PlotMask ROUT - ASSERT NewPtY = NewPtX +4 - ADD R3, WsPtr, #NewPtX - LDMIA R3, {R3, R4} ; plot sprite at NewPt(X,Y) -PlotMa20 - GraphicsMode R0 - BNE PutSpriNotGraphics ; quit with error if not graphics mode - - LDR R5, [WsPtr, #GPLBMD] ; background GCOL action - ORR R5, R5, #8 ; force 'use mask' - LDR R10, [R2, #spImage] - LDR R11, [R2, #spTrans] - TEQ R10, R11 ; spImage=spTrans if no mask - BEQ %FT90 ; so plot a rectangle - - LDR R0, [R2, #spMode] - MOVS R0, R0, LSR #27 - BNE PlotNewMask - - LDR R0, [R2, #spHeight] - ADD R0, R0, R4 - LDR R10, [WsPtr, #GWTRow] - Least R0, R0, R10 ; top scanline within window - - LDR R10, [WsPtr, #YWindLimit] - SUB R0, R10, R0 ; flip Y - AND R0, R0, #7 - STR R0, [WsPtr, #SPltEcfIndx] ; index into Ecf - - ADD R0, WsPtr, R0, LSL #3 - ADD R0, R0, #BgEcfOraEor - STR R0, [WsPtr, #SPltEcfPtr] ; ptr to ECF for highest row plotted - - Push "WsPtr, R14" ; push both so R12,R14 are free for use - BL GenSpritePlotParmBlk - BVS SpriteOffScreen - SWI XOS_RemoveCursors ; assume no error can occur! - - LDR R5, [WsPtr, #SPltMemAdr] - LDR R6, [WsPtr, #SPltMskAdr] - TEQ R6, #0 - BEQ SpriteOffScreen - - ADD R6, R6, R5 - STR R6, [WsPtr, #SPltMskAdr] - STR R6, [WsPtr, #SPltMemAdr] - - ADD WsPtr, WsPtr, #SPltScrAdr ; repoint WsPtr at SPltScrAdr - - LDMIA WsPtr, {R0-R1,R5-R7} - LDR R8, [WsPtr, #SPltEcfPtr-SPltScrAdr] -10 - LDMIA R8, {R8,R9} ; ora,eor for this row - -; R0 ,R1 , R5 ,R6 ,R7 ,R8 ,R9 -; ScrAdr,ColCnt, MemAdr,ShftR,ShftL,ora,eor - -; Plot the first (Leftmost) word - - LDMIA R5, {R2,R3} - ADD R5, R5, #4 - - ShiftR R2,R3, R6,R7 ; shift R3,R2 right R6 places - ; we only need result word R2 - LDR R10, [WsPtr, #SPltLMask-SPltScrAdr] ; on leftmost word - AND R2, R2, R10 ; mask down to just the required pixels - - LDR R4, [R0] ; plot 1 word - OrrEorMASK R4,R2, R8,R9, R14 - STR R4, [R0], #4 - - SUBS R1, R1, #1 - BLT %FT50 ; if all plotted, try next scanline - ; else try for blocks of 4 - SUBS R1, R1, #4 - BLT %FT30 - -20 - STMIA WsPtr, {R0,R1} ; save ScrAdr,ColCnt - -; R0 ,R1 ,R5 ,R6 ,R7 -; ScrAdr,ColCnt, ,MemAdr,ShftR,ShftL - - LDMIA R5, {R0-R4} ; 5 words needed, gives 4 after shift - ADD R5, R5, #16 ; advance source ptr 4 words - STR R5, [WsPtr, #SPltMemAdr-SPltScrAdr] - - ShiftR R0,R1, R6,R7 ; shift R4-R0 right R6 bits - ShiftR R1,R2, R6,R7 ; we only want result words R3-R0 - ShiftR R2,R3, R6,R7 - ShiftR R3,R4, R6,R7 - - LDR R4, [WsPtr] ; get screen address - LDMIA R4, {R8-R11} ; get 4 screen words - - LDR R6, [WsPtr, #SPltEcfPtr-SPltScrAdr] - LDMIA R6, {R6,R7} ; ora,eor for this row - - OrrEorMASK R8,R0, R6,R7, R14 ; Scr:=ScrOR(oraANDmsk)EOR(eorANDmsk) - OrrEorMASK R9,R1, R6,R7, R14 - OrrEorMASK R10,R2, R6,R7, R14 - OrrEorMASK R11,R3, R6,R7, R14 - - LDR R0, [WsPtr] ; screen address - STMIA R0!, {R8-R11} ; write 4 words back to screen - LDMIB WsPtr, {R1,R5-R7} ; reload anything we shat on - - SUBS R1, R1, #4 - BGE %BT20 - -30 ; try 1 word at a time - ADDS R1, R1, #4 - -; R0 ,R1 , R5 ,R6 ,R7 ,R8 ,R9 -; ScrAdr,ColCnt, MemAdr,ShftR,ShftL,ora,eor - -; If EQ this is rightmost word - - LDR R8, [WsPtr, #SPltEcfPtr-SPltScrAdr] - LDMIA R8, {R8,R9} ; ora,eor for this row - LDR R10, [WsPtr, #SPltRMask-SPltScrAdr] -40 - LDMIA R5, {R2,R3} - ADD R5, R5, #4 - - ShiftR R2,R3, R6,R7 ; shift R3,R2 right R6 places - ; we only need result word R2 - - ANDEQ R2, R2, R10 ; if rightmost word, mask down to just the - ; required pixels - LDR R4, [R0] - OrrEorMASK R4,R2, R8,R9, R14 - STR R4, [R0], #4 - - SUBS R1, R1, #1 - BGE %BT40 - -50 ; now try the next scanline - - LDMDB WsPtr, {R1,R2,R3,R4} ; R1 ,R2 ,R3 ,R4 - ; Width,Height,ScrOff,MemOff - ADD R0, R0, R3 - ADD R5, R5, R4 - - ADD R10, WsPtr, #(SPltEcfPtr-SPltScrAdr) - - LDMIA R10, {R8,R9} ; EcfPtr,EcfIndx - ADD R8, R8, #8 ; step both to next row in Ecf - ADD R9, R9, #1 - CMP R9, #8 - MOVGE R9, #0 ; it's a wrap! - SUBGE R8, R8, #(8*8) - STMIA R10, {R8,R9} - - SUBS R2, R2, #1 - STRGE R2, [WsPtr, #SPltHeight-SPltScrAdr] - BGE %BT10 ; plot next scanline - - SWI XOS_RestoreCursors - - Pull "WsPtr, R14" - RETURNVC - -; Sprite has no mask or gcol says dont use it, so draw a rectangle - -90 - Push R14 - BL ReadSpriteWidth ; on exit R0=width in pixels - ADD R5, R3, R0 - MOV R0, R3 ; x0 - MOV R1, R4 ; y0 - - LDR R3, [R2, #spHeight] - ADD R3, R3, R4 ; y1 - SUB R2, R5, #1 ; x1 - - LDR R4, [WsPtr, #CursorFlags] - TST R4, #ClipBoxEnableBit - BLNE ClipPlotMask - - ADD R4, WsPtr, #BgEcfOraEor ; select Bg colour & action - STR R4, [WsPtr, #GColAdr] - B RectFillB - -ClipPlotMask ROUT - Push "R0-R7,R10,R11, R14" - ADD R10, R13, #2*4 ; R10 -> last point (R2,R3) - MOV R11, #2 ; merge two points - BL MergeR11PointsFromR10 - Pull "R0-R7,R10,R11, PC" - -; ***************************************************************************** -; -; GenSpritePlotParmBlk - Generate lots of useful variables to help us -; to plot sprite -; -; Internal routine, called by PutSprite, PlotMask, ScreenLoad -; -; in: R2 -> sprite -; R3 = X coordinate to plot at -; R4 = Y coordinate to plot at -; R5 = GCOL action -; - -GenSpritePlotParmBlk ROUT - Push R14 - AND R5, R5, #&F ; lose any ECF colour bits - LDR R6, [R2, #spImage] - LDR R7, [R2,#spTrans] - SUB R6, R7, R6 ; offset from Image to Trans mask - ; =0 if no mask - STR R5, [WsPtr, #SPltAction] ; save action for simple case spotting - CMP R5, #8 ; if GCOL action < 8 - MOVLT R6, #0 ; plot as solid anyway - STR R6, [WsPtr, #SPltMskAdr] - - AND R5, R5, #7 - MOV R5, R5, LSL #2 ; 4 bits for each - LDR R6, =TBscrmasks - MOV R6, R6, ROR R5 ; put correct bits in top 4 bits - MOV R7, R6, ASR #31 ; set R7 to 0 or -1 on bit 31 - MOV R6, R6, LSL #1 - MOV R8, R6, ASR #31 ; set R8 to 0 or -1 on bit 30 - MOV R6, R6, LSL #1 - MOV R9, R6, ASR #31 ; set R9 to 0 or -1 on bit 29 - MOV R6, R6, LSL #1 - MOV R10, R6, ASR #31 ; set R10 to 0 or -1 on bit 28 - - ADD R6, WsPtr, #SPltzgooMasks - STMIA R6, {R7-R10} ; store zgoo, zgeo, zgoe, zgee - - MOV R14, R2 ; leave sprite CB ptr in R14 - MOV R0, R3 ; leave X coord in R0 - MOV R1, R4 ; leave Y coord in R1 - - ADD R11, R14, #spWidth - LDMIA R11, {R2,R3} ; Width-1, Height-1 - - ADD R4, WsPtr, #GWLCol ; R4 ,R5 ,R6 ,R7 - LDMIA R4, {R4,R5,R6,R7} ; LCol,BRow,RCol,TRow - - SUBS R5, R5, R1 - MOVLT R5, #0 ; no. of rows below window - - ADD R1, R1, R3 ; Coord of topLH of sprite - - SUBS R7, R1, R7 - MOVLT R7, #0 ; no. of rows above window - SUB R1, R1, R7 ; clipped topLH coord - - ADD R5, R5, R7 ; reduction factor for height - - ADD R2, R2, #1 - - MOV R8, R14 - LDR R9, [WsPtr, #CursorFlags] - TST R9, #ClipBoxEnableBit - BLNE ClipSpritePlot - MOV R14, R8 - - MUL R3, R7, R2 ; word offset into sprite image - - Push "R3,R5" ; word offset and height reduction - - Push R14 - BL ScreenAddr - Pull R14 - MOV R4, R2 ; address of top left corner - - LDR R5, [R14, #spImage] - ADD R5, R5, R14 ; address of sprite image - - Pull R6 - ADD R5, R5, R6, LSL #2 - - LDR R9, [WsPtr, #XShftFactor] - LDR R10, [WsPtr, #NPix] - LDR R11, [WsPtr, #Log2BPC] - - BitLOffset R7,R0, R9,R10,R11 ; R7 := bit position to align to - WordOffset R8,R0, R9,R10,R11 ; R8 := word offset on line - - LDR R0, [WsPtr, #GWRCol] - BitROffset R1,R0, R9,R10,R11 - WordOffset R2,R0, R9,R10,R11 - Push "R1,R2" - - LDR R0, [WsPtr, #GWLCol] - BitLOffset R1,R0, R9,R10,R11 - WordOffset R2,R0, R9,R10,R11 - - Push "R1,R2,R8" - - ADD R11, R14, #spWidth - LDMIA R11, {R0,R1,R6,R8} ; Width-1, Height-1, LBit, RBit - - MOV R3, #0 ; offset to next row in sprite - - SUBS R6, R6, R7 ; no. of bits to shift sprite - ; before plotting - ; use R7 as LBit - SUBS R8, R8, R6 ; calculate new RBit - ADDLT R8, R8, #32 - ADDLT R3, R3, #4 - - CMP R8, #32 - SUBGE R8, R8, #32 - SUBGE R3, R3, #4 - -; R9 Offset on line to plot point, R7 LBit -; R11 Offset on line to GWLCol R10 bit position - - Pull "R10,R11" - Pull R9 - - SUBS R9, R11, R9 - SUBLT R11, R11, R9 - - ADDGT R4, R4, R9, LSL #2 - ADDGT R5, R5, R9, LSL #2 - ADDGT R3, R3, R9, LSL #2 - - CMPEQ R10, R7 - MOVGT R7, R10 - -; R10 Offset to GWRCol, R9 bit position -; R11 Offset to RHedge of sprite, R8 RBit - - ADD R11, R11, R0 - SUB R11, R11, R3, ASR #2 - - Pull "R9,R10" - - SUBS R10, R11, R10 - ADDGT R3, R3, R10, LSL #2 - - CMPEQ R8, R9 - MOVGT R8, R9 - - Pull R10 - - SUBS R1, R1, R10 ; correct height - BLT %FT20 - - SUBS R0, R0, R3, ASR #2 ; corrected width - BLT %FT20 - - LDR R2,[WsPtr,#LineLength] - SUB R2, R2, #4 - SUB R2, R2, R0, LSL #2 ; offset to next screen line - - MOV R9, #&FFFFFFFE ; RHand partial word mask - MVN R9, R9, LSL R8 - MOV R8, #&FFFFFFFF - MOV R8, R8, LSL R7 ; LHand partial word mask - - ANDEQ R8, R8, R9 ; if width=0, combine LH & RH masks - MOVEQ R9, R8 - - CMP R6, #0 - ADDLT R6, R6, #32 ; correct if neg - SUBLT R5, R5, #4 - RSB R7, R6, #32 ; its complement - - ADD R11, WsPtr, #SPltWidth - STMIA R11, {R0,R1,R2,R3,R4} ; SPltWidth..SPltScrAdr - - ADD R11, WsPtr, #SPltColCnt - STMIA R11, {R0,R5,R6,R7} ; SPltColCnt..SPltShftL - - ADD R11, WsPtr, #SPltMskAdr - STMIB R11, {R8,R9} ; SPltLMask,SPltRMask - - [ No26bitCode - CLRV - Pull PC - | - Pull R14 - BICS PC, R14, #V_bit ; VC some/all of sprite in window - ] - -20 - [ No26bitCode - SETV - Pull PC - | - Pull R14 - ORRS PC, R14, #V_bit ; VS sprite completely outside window - ] - - LTORG - - END diff --git a/s/vdu/vdugrafh b/s/vdu/vdugrafh deleted file mode 100644 index 6df775af..00000000 --- a/s/vdu/vdugrafh +++ /dev/null @@ -1,1191 +0,0 @@ -; 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.VduGrafH -; -; ARTHUR OPERATING SYSTEM - Vdu Drivers -; ======================= -; -; Vdu driver code - Sprite stuff -; -; Authors RManby, TDobson -; Started 10.11.86 - -; ************************************************************ -; *** C h a n g e L i s t (better late than never!) *** -; ************************************************************ - -; Date Description -; ---- ----------- -; 17-Feb-88 Created change list -; Fixed bug in SLOAD (errors weren't reported) -; 08-Apr-88 Changed LoadFile to use open with nodir + mustopen -; 20-May-88 Changed NoRoomToLoad to NotEnoughRoom - -; ***************************************************************************** -; -; MergeSpriteFile - Merge sprite file from filing system -; -; External routine -; -; in: R1 -> sprite area -; R2 -> filename -; - -MergeSpriteFile ROUT - Push R14 - KillSpChoosePtr - LDR R3, [R1, #saFree] - ADD R3, R3, R1 - BL LoadFile ; R1 -> sprite area, R2 -> filename - Pull PC, VS ; R3 -> free space - SUB R2, R3, #4 - BL MergeSpriteAreas ; in: R1 -> destination, R2 -> source, V=0 - Pull R14 - RETURNVC - -; ***************************************************************************** -; -; LoadSpriteFile - Load sprite file from filing system -; -; External routine -; -; in: R1 -> sprite area -; R2 -> filename -; - -LoadSpriteFile ROUT - KillSpChoosePtr - ADD R3, R1, #saNumber ; R3 = load address - -; and drop thru to LoadFile (V will be set/cleared by that routine) - -; ***************************************************************************** -; -; LoadFile - Load sprite file to particular address -; -; Internal routine, called by LoadSpriteFile, MergeSpriteFile -; -; in: R1 -> sprite area -; R2 -> filename -; R3 = load address -; -; out: VS => error during load, R0 -> error -; VC => loaded OK, R0 undefined -; R1-R11 preserved -; - -LoadFile ROUT - Push "R1-R6, R14" - - ; new version (07-Dec-89) to help broadcast loader a bit - - Push "R2,R3" ; filename ptr, load address - LDR R6, [R1, #saEnd] - ADD R6, R6, R1 - SUB R6, R6, R3 ; free space = saEnd-LoadAddress - - MOV R0, #OSFile_ReadInfo - MOV R1, R2 ; filename ptr - SWI XOS_File ; OSFILE(5), returns R0 type, R4 length - BVS %FT10 ; R0 file type, R4 length - - TEQ R0, #object_file ; if not a file - BNE %FT08 ; then make into suitable error - - CMP R6, R4 ; will file fit in available space ? - ADRCCL R0, SpriteErr_NotEnoughRoom - [ International - BLCC TranslateError - ] - BCC %FT10 - -; There is room to load file, so load the lot - - MOV R0, #OSFile_Load - Pull "R1, R2" ; filename ptr, load address - MOV R3, #0 ; use given address - SWI XOS_File - BVS %FT20 - -; TMD 07-Oct-91 (G-RO-9262) -; New code inserted here -; Check validity of sprite file -; R4 = file length from XOS_File above - -; TMD 06-Mar-92 (RP-0589) -; Validity check weakened to only check that -; offset to first sprite is < length of file - - LDR R3, [sp, #2*4] ; R3 = load address - LDR R1, [R3, #saFirst-4] ; offset to first sprite must be < length of file - CMP R1, R4 - Pull "R1-R6, PC",CC ; R0 is corrupt, R1-R11 preserved, V=0 - -; it was a bad file, so make it look like an empty sprite area before erroring -; so that in SLoad case we don't get a naff sprite area. - -05 - MOV R0, #0 - STR R0, [R3, #saNumber-4] - MOV R0, #SpriteAreaCBsize - STR R0, [R3, #saFirst-4] - STR R0, [R3, #saFree-4] - - ADRL R0, SpriteErr_BadSpriteFile - [ International - BL TranslateError - ] - B %FT20 - -08 - MOV R2, R0 - MOV R0, #OSFile_MakeError ; then make into suitable error - SWI XOS_File -10 - ADD R13, R13, #2*4 ; balance stack -20 - Pull "R1-R6, R14" ; return with error - STR R0, [WsPtr, #RetnReg0] - RETURNVS ; R1-R11 preserved - -; ***************************************************************************** -; -; SaveSpriteFile - Save sprite area to filing system -; -; External routine -; -; in: R1 -> sprite area -; R2 -> filename -; - -SaveSpriteFile ROUT - LDR R3, [R1, #saNumber] ; if no sprites - TEQ R3, #0 - BEQ %FT10 ; then quit with error - - Push R14 - ADD R4, R1, #saNumber ; save sprite area, excluding - LDR R5, [R1, #saFree] ; free space or saEnd - ADD R5, R5, R1 - - [ AssemblingArthur :LOR: Module - MOV R0, #OSFile_SaveStamp - MOV R1, R2 ; filename ptr - LDR R2, =&FF9 ; type=SpriteFile - MOV R3, #0 ; junk - | - MOV R0, #0 ; normal save - MOV R1, R2 ; filename ptr - MOV R2, #0 - MOV R3, #0 - ] - - SWI XOS_File ; save file - STRVS R0, [WsPtr, #RetnReg0] - Pull PC - -10 - ADRL R0, SpriteErr_NoSprites - [ International - Push "lr" - BL TranslateError - Pull "lr" - ] - STR R0, [WsPtr, #RetnReg0] - RETURNVS - - LTORG - -; ***************************************************************************** -; -; MergeSpriteAreas - Merge two sprite areas -; -; Internal routine, called by MergeSpriteFile -; -; in: R1 -> destination sprite area -; R2 -> source sprite area -; V=0 -; -; out: All registers preserved -; - -MergeSpriteAreas ROUT - TEQ R2, #0 ; validate R2 (R1 already checked) - BEQ %FT30 - Push "R1-R4, R14" - - LDR R4, [R2, #saNumber] ; number of sprites to merge - TEQ R4, #0 - BEQ %FT20 ; nothing to merge - - LDR R3, [R2, #saFirst] - ADD R2, R2, R3 -10 ; R1 -> dest area CB, - BL MergeSprite ; R2 -> to sprite CB - ; return R2 -> next sprite - BVS %FT20 ; error 'NoRoomToMerge' - SUBS R4, R4, #1 ; (V:=0 if becoming zero) - BNE %BT10 -20 - Pull "R1-R4, PC" ; exit with V already set up - -30 - ADRL R0, SpriteErr_Bad2ndPtr - [ International - Push "lr" - BL TranslateError - Pull "lr" - ] - STR R0, [WsPtr, #RetnReg0] - RETURNVS - -; ***************************************************************************** -; -; MergeSprite - Merge sprite into sprite area -; -; Internal routine, called by MergeSpriteAreas -; -; in: R1 -> destination area -; R2 -> source sprite -; -; out: R2 -> past end of source sprite (ie next sprite) -; - -MergeSprite ROUT - Push "R1, R3-R5, R14" - ADD R2, R2, #spName - BL DeleteSpriteByName ; in: R1-R2; out: all preserved - SUB R2, R2, #spName -AddSprite - LDR R3, [R1, #saFree] - LDR R5, [R1, #saEnd] - SUB R5, R5, R3 ; amount of free ram in dest area - - LDR R4, [R2, #spNext] ; space needed for sprite - CMP R5, R4 - BCC %FT10 - - ADD R3, R3, R1 ; first free locn in dest. area - CopyDown R3,R2,R4,R5,R14 ; NB CopyDown will exit with R3 -> end - ; of dest area - LDR R4, [R1, #saNumber] ; update number of sprites - ADD R4, R4, #1 - STR R4, [R1, #saNumber] - - SUB R3, R3, R1 ; and free space offset - STR R3, [R1, #saFree] - - Pull "R1, R3-R5, R14" - RETURNVC ; ignore 'not found' from DeleteSprite - -10 - Pull "R1, R3-R5, R14" - ADRL R0, SpriteErr_NoRoomToMerge - [ International - Push "lr" - BL TranslateError - Pull "lr" - ] - STR R0, [WsPtr, #RetnReg0] - RETURNVS - -; ***************************************************************************** -; -; AppendSprite - Append sprite to sprite area -; -; Internal routine, called by CopySprite -; -; in: R1 -> destination area -; R2 -> source sprite -; -; out: R2 -> past end of source sprite (ie next sprite) -; - -AppendSprite ROUT - Push "R1, R3-R5, R14" - B AddSprite - -; ***************************************************************************** -; -; ExtendHorizontally - Add one column to RHS of the sprite -; -; Internal routine, called by InsertCol -; -; in: R1 -> sprite area -; R2 -> sprite -; - -ExtendHorizontally ROUT - Push "R3-R6, R9-R11, R14" - LDR R3, [R2, #spRBit] - LDR R4, [WsPtr, #SprBytesPerChar] - ADD R3, R3, R4 ; alter spRBit to include next pixel - CMP R3, #32 - BCC %FT20 - ; >=32 means add 1 word to each row - LDR R3, [R2, #spHeight] - ADD R3, R3, #1 ; extend by (spHeight+1) words - BL ExtendSprite ; (space doubled if mask present) - Pull "R3-R6, R9-R11, PC", VS ; no room, then give error - - MOV R4, #0 - BL MaskOffset ; use spHeight+1 as row counter, - MOVNE R3, R3, LSL #1 ; doubled if mask present - - LDRNE R5, [R2, #spTrans] ; correct mask ptr, if mask present - ADDNE R5, R5, R3, LSL #1 ; R3 is words*2, hence LSL - STRNE R5, [R2, #spTrans] - - BL InsertWords ; Insert R3 words at position R4 in - ; sprite, ie at beginning - LDR R5, [R2, #spWidth] - ADD R5, R5, #1 ; new spWidth - STR R5, [R2, #spWidth] - - LDR R9, [R2, #spImage] - ADD R9, R9, R2 ; to - ADD R10, R9, R3, LSL #2 ; from - -10 - MOV R11, R5, LSL #2 - ; move one row - CopyDown R9,R10,R11,R14,R6 ; To,From,Size, Temp - - STR R4, [R9], #4 ; add 1 word at RH end of row - SUBS R3, R3, #1 - BHI %BT10 ; next row - - LDR R3, [WsPtr, #SprBytesPerChar] - SUBS R3, R3, #1 -20 - STR R3, [R2, #spRBit] - Pull "R3-R6, R9-R11, R14" - RETURNVC - -; ***************************************************************************** -; -; ReduceHorizontally - Remove some bits from the RHS of the sprite -; -; Internal routine, called by DeleteCol -; -; in: R0 = number of bits to delete off right hand side -; R1 -> sprite area -; R2 -> sprite -; - -ReduceHorizontally ROUT - Push "R3-R6, R9-R11, R14" - LDR R3, [R2, #spRBit] - SUBS R3, R3, R0 ; alter spRBit to exclude those bits - ADDCC R3, R3, #32 ; if underflow then extract whole word - STR R3, [R2, #spRBit] - BCS %FT20 - ; < 0 means remove 1 word per row - LDR R3, [R2, #spHeight] - ADD R3, R3, #1 ; remove (spHeight+1) words - MOV R4, #0 - BL MaskOffset - MOVNE R3, R3, LSL #1 ; doubled if mask present - - LDRNE R5, [R2, #spTrans] ; correct mask ptr, if mask present - SUBNE R5, R5, R3, LSL #1 ; R3 is words*2, hence LSL - STRNE R5, [R2, #spTrans] - - LDR R9, [R2, #spImage] - ADD R9, R9, R2 ; to - MOV R10, R9 ; from - LDR R5, [R2, #spWidth] -10 - MOV R11, R5, LSL #2 - ; move one row - CopyDown R9,R10,R11,R14,R6 ; To,From,Size, Temp - - - ADD R10, R10, #4 ; skip unwanted word - SUBS R3, R3, #1 - BHI %BT10 ; next row - -; R9 -> past end of this sprite -; R10 -> next sprite - - SUB R3, R10, R9 - MOV R3, R3, LSR #2 ; no. of words to remove - SUB R4, R9, R2 - LDR R9, [R2, #spImage] - SUB R4, R4, R9 ; byte offset within image - - BL RemoveWords - - LDR R5, [R2, #spWidth] - SUB R5, R5, #1 ; new spWidth - STR R5, [R2, #spWidth] -20 - Pull "R3-R6, R9-R11, R14" - RETURNVC - -; ***************************************************************************** -; -; InsertRow - Insert blank row into sprite -; -; External routine -; -; in: R1 -> sprite area -; R2 -> sprite -; R3 = row number to insert below (0 => bottom, spHeight+1 => above top) -; - -InsertRow ROUT - Push "R0,R4,R14" - MOV R0, #57 ; SpriteOp reason code for insert/delete rows - ORR R0, R0, #512 ;Set it to use pointers to user area & sprite - MOV R4, #1 ; We're only inserting one row! (put 1 in) - SWI XOS_SpriteOp - BVS %FT20 - - Pull "R0,R4,R14" - RETURNVC ; exit OK - -20 - STR R0, [WsPtr, #RetnReg0] - Pull "R0,R4,R14" - RETURNVS ; exit with error - -; ***************************************************************************** -; -; DeleteRow - Delete row from sprite -; -; External routine -; -; in: R1 -> sprite area -; R2 -> sprite -; R3 = row number to remove (0=bottom, spHeight=top) -; - -DeleteRow ROUT - Push "R0,R4,R14" - MOV R0, #57 ; SpriteOp reason code for insert/delete rows - ORR R0, R0, #512 ;Set it to use pointers to user area & sprite - MVN R4, #0 ; We're only removing one row! (put -1 in) - SWI XOS_SpriteOp - BVS %FT20 - - Pull "R0,R4,R14" - RETURNVC ; exit OK - -20 - STR R0, [WsPtr, #RetnReg0] - Pull "R0,R4,R14" - RETURNVS ; exit with error - -; ***************************************************************************** -; -; InsertCol - Insert blank column into sprite -; -; External routine -; -; in: R1 -> sprite area -; R2 -> sprite -; R3 = column to insert at (0 => before left..width => after right) -; - -InsertCol ROUT - Push "R0,R4,R14" - MOV R0, #58 ; SpriteOp reason code for insert/delete cols - ORR R0, R0, #512 ;Set it to use pointers to user area & sprite - MOV R4, #1 ; We're only inserting one column! (put 1 in) - SWI XOS_SpriteOp - BVS %FT20 - - Pull "R0,R4,R14" - RETURNVC ; exit OK - -20 - STR R0, [WsPtr, #RetnReg0] - Pull "R0,R4,R14" - RETURNVS ; exit with error - -; ***************************************************************************** -; -; DeleteCol - Delete column from sprite -; -; External routine, and LHWastageEntry called from RemoveLeftHandWastage -; -; in: R1 -> sprite area -; R2 -> sprite -; R3 = column number to remove (0 => left, width-1 => right) -; - -DeleteCol ROUT - Push "R0,R4,R14" - MOV R0, #58 ; SpriteOp reason code for insert/delete cols - ORR R0, R0, #512 ;Set it to use pointers to user area & sprite - MVN R4, #0 ; We're only removing one row! (put -1 in) - SWI XOS_SpriteOp - BVS %FT20 - - Pull "R0,R4,R14" - RETURNVC ; exit OK - -20 - STR R0, [WsPtr, #RetnReg0] - Pull "R0,R4,R14" - RETURNVS ; exit with error - -; ***************************************************************************** -; -; ExtendSprite - Add R3 words to the end of the sprite (R3*2 if mask) -; -; Internal routine, called by ExtendHorizontally, InsertRow, CreateMask, -; and ExtendSpriteByR3 called by GetSprite -; -; in: R1 -> sprite area -; R2 -> sprite -; R3 = no. of words to insert (gets doubled if mask present) -; - -ExtendSpriteByR3 ROUT - Push "R3, R8-R11, R14" - B ExtendSprite10 - -ExtendSprite ROUT - Push "R3, R8-R11, R14" - BL MaskOffset - MOVNE R3, R3, LSL #1 ; double no. of words if mask present -ExtendSprite10 - LDR R10, [R1, #saEnd] - LDR R11, [R1, #saFree] - SUB R10, R10, R3, LSL #2 - CMP R10, R11 - BCC %FT10 - - LDR R10, [R2, #spNext] - ADD R10, R10, R2 ; copy source - ADD R9, R10, R3, LSL #2 ; copy destination - - LDR R11, [R1, #saFree] - ADD R11, R11, R1 - SUB R11, R11, R10 ; size (bytes) to copy - CopyUp R9,R10,R11, R14, R8 ; To,From,Size,Temp, Temp2 - - LDR R9, [R1, #saFree] - ADD R9, R9, R3, LSL #2 - STR R9, [R1, #saFree] ; update saFree - - LDR R9, [R2, #spNext] - ADD R9, R9, R3, LSL #2 - STR R9, [R2, #spNext] ; update spNext - - Pull "R3, R8-R11, R14" - RETURNVC - -10 - ADRL R0, SpriteErr_NoRoomToInsert - [ International - BL TranslateError - ] - STR R0, [WsPtr, #RetnReg0] - Pull "R3, R8-R11, R14" - RETURNVS - -; ***************************************************************************** -; -; InsertWords - Insert R3 words into given sprite at specified position -; -; Internal routine, called by ExtendHorizontally, InsertRow -; -; in: R1 -> sprite area -; R2 -> sprite -; R3 = number of words to insert -; R4 = insertion point (byte offset within sprite image) -; -; NB Assumes ExtendSprite has been called to leave R3 extra words -; at the end of the sprite -; -; out: All registers preserved -; - -InsertWords ROUT - Push "R8-R11, R14" - LDR R10, [R2, #spImage] - ADD R10, R10, R2 - ADD R10, R10, R4 ; copy source - ADD R9, R10, R3, LSL #2 ; copy destination - LDR R11, [R2, #spNext] - ADD R11, R11, R2 - SUB R11, R11, R9 ; size (bytes) to copy - CopyUp R9,R10,R11, R14,R8 ; To,From,Size,Temp, Temp2 - Pull "R8-R11, R14" - RETURNVC - -; ***************************************************************************** -; -; ClearWords - Clear R3 words in sprite -; -; Internal routine, called by InsertRow, CreateSprite -; -; in: R1 -> sprite area -; R2 -> sprite -; R3 = number of words to clear -; R4 = byte offset within sprite image to clear from -; -; out: All registers preserved -; - -ClearWords ROUT - Push "R9-R11, R14" - LDR R10, [R2, #spImage] - ADD R10, R10, R2 - ADD R10, R10, R4 ; clear from - MOVS R9, R3 - MOVNE R11, #0 -10 - STRNE R11, [R10], #4 - SUBNES R9, R9, #1 - BNE %BT10 - Pull "R9-R11, R14" - RETURNVC - -; ***************************************************************************** -; -; RemoveWords - Delete R3 words from given sprite -; -; Internal routine, called by ReduceHorizontally, DeleteRow, RemoveMask, -; GetSprite -; -; in: R1 -> sprite area -; R2 -> sprite -; R3 = number of words to remove -; R4 = removal point (byte offset within sprite image) -; -; out: All registers preserved -; spNext (in sprite) and spFree (in sprite area) updated -; - -RemoveWords ROUT - Push "R8-R11, R14" - LDR R9, [R2, #spImage] - ADD R9, R9, R2 - ADD R9, R9, R4 ; copy destination - ADD R10, R9, R3, LSL #2 ; copy source - LDR R11, [R1, #saFree] - ADD R11, R11, R1 - SUB R11, R11, R10 ; size (bytes) to copy - CopyDown R9,R10,R11, R14,R8 ; To,From,Size,Temp, temp2 - SUB R9, R9, R1 - STR R9, [R1, #saFree] ; update saFree - LDR R9, [R2, #spNext] - SUB R9, R9, R3, LSL #2 - STR R9, [R2, #spNext] ; update spNext - Pull "R8-R11, PC" - -; ***************************************************************************** -; -; MaskOffset - Read mask size (0 if absent) -; -; Internal routine, called by ExtendHorizontally, ReduceHorizontally, -; InsertRow, DeleteRow, ExtendSprite, FlipAboutXAxis -; -; in: R2 -> sprite -; -; out: R0 = 0 if no mask, otherwise mask size -; EQ if no mask, NE if mask present -; - -MaskOffset ROUT - Push R14 - LDR R0, [R2, #spImage] - LDR R14, [R2, #spTrans] - SUBS R0, R14, R0 ; offset from Image to Trans mask - ; =0 if no mask - Pull PC ; return EQ/NE for nomask/mask - -; ***************************************************************************** -; -; ReadPixelColour - Read colour of a pixel in a given sprite -; -; External routine -; -; in: R1 -> sprite area -; R2 -> sprite -; R3 = X coordinate of pixel (0 = left) -; R4 = Y coordinate of pixel (0 = bottom) -; -; out: RetnReg5 = colour (0..NColour) or 0..63 -; RetnReg6 = tint 0 or 0/64/128/192 -; - -ReadPixelColour ROUT - Push R14 - BL SpriteGenAddr ; returns R6, R7 - Pull PC, VS ; Address, Bit position - LDR R5, [R6] ; word from sprite - LDR R6, [WsPtr, #SprReadNColour] - - CMP R6, #63 ; check for 256 colour - MOVEQ R6, #255 - - AND R0, R6, R5, LSR R7 ; extract one pixel (bit0..) - - CMP R6, #255 - - MOVNE R2, R0 ; colour = pixel - MOVNE R3, #0 ; tint = 0 - BNE %FT10 - - ;now check for size of palette - ADD R2, R2, #spImage ; point to image/mask start - LDMIA R2, {R2, R3} - CMP R3, R3 - MOVGT R3, R3 - SUB R2, R2, #spPalette - CMP R2, #&0800 - BEQ %FT05 - - ;see comment below - for this call to work we have to temporarily - ;set NColour to SprReadNColour - - LDR R8,[WsPtr,#NColour] - STR R6,[WsPtr,#NColour] - - BL ExtractTintAndColour ; else extract colour & tint from pixel - - STR R8,[WsPtr,#NColour] - B %FT10 -05 - MOV R2, R0 - MOV R3, #0 -10 - STR R2, [WsPtr, #RetnReg5] ; pass colour in R5 - STR R3, [WsPtr, #RetnReg6] ; and tint in R6 - Pull R14 - RETURNVC - -; ***************************************************************************** -; -; WritePixelColour - Write a pixel in a given sprite -; -; External routine -; -; in: R1 -> sprite area -; R2 -> sprite -; R3 = X coordinate of pixel (0 = left) -; R4 = Y coordinate of pixel (0 = bottom) -; R5 = pixel colour -; R6 = tint -; -; out: R1-R11 preserved -; - -; amg: note. need to handle full palettes differently here - since the GCOL and TINT -; model should not apply. Check for a full palette on an 8bpp sprite and deal with -; it accordingly. -; amg: bug fix to MED-01885. Although ReadPixel and WritePixel use SprReadNColour, -; then call AddTintToColour which uses NColour - being the screen's value not the -; sprites. Therefore, the safest fix this near freeze is to simply temporarily change -; the NColour value for the call, and then restore it. - -WritePixelColour ROUT - Push "R1-R4, R14" - LDR R8, [WsPtr, #SprReadNColour] - - AND R0, R5, R8 ; limit colour to 0..NColour - - CMP R8, #63 ; check for 256 colours - CMPNE R8, #255 - BNE %FT08 ; despatch non 8bpp - - ;now need to determine size of 8bpp sprite's palette - ADD R3, R2, #spImage ; point to image/mask start - LDMIA R3, {R2, R3} ; fetch them - CMP R2, R3 ; which is higher - MOVGT R2, R3 ; use the lesser - SUB R2, R2, #spPalette ; subtract start offset - CMP R2, #&800 - - MOVNE R3, R6 ; then combine - - ;see comment above - for this call to work we have to temporarily - ;set NColour to SprReadNColour - - LDRNE R7,[WsPtr,#NColour] - STRNE R8,[WsPtr,#NColour] - - BLNE AddTintToColour ; colour & tint - - STRNE R7,[WsPtr,#NColour] - - B %FT05 ; 8 bpp take this branch -08 - ADDCC R0, R0, R8 ; else index into full colour table - ADRCCL R5, TBFullCol - LDRCCB R0, [R5, R0] ; N.B. a table of bytes - BCC %FT05 ; 1,2,4 bpp take this branch - - ; if 16bpp only need to shift round once, if 32bpp not at all - LDR LR, [R2, #spMode] - MOV LR, LR, LSR #27 - CMP LR, #6 - MOV R5, R0 - BCS %FT06 ; 32 bpp takes this branch - - B %FT07 ; and 16 bpp takes this one -05 - ORR R5, R0, R0, LSL #8 ; expand byte value into a word -07 - ORR R5, R5, R5, LSL #16 -06 - Pull "R1-R4" - BL SpriteGenAddr ; returns R6, R7 - Pull PC, VS ; Address, Bit position - LDR R8, [WsPtr, #SprWriteNColour] - AND R5, R5, R8 ; limit colour to pixel width - LDR R0, [R6] ; word from sprite - BIC R0, R0, R8, LSL R7 - ORR R0, R0, R5, LSL R7 - STR R0, [R6] - Pull R14 - RETURNVC - -; ***************************************************************************** -; -; ReadPixelMask - Read mask state for a pixel in a given sprite -; -; External routine -; -; in: R1 -> sprite area -; R2 -> sprite -; R3 = X coordinate of pixel (0 = left) -; R4 = Y coordinate of pixel (0 = bottom) -; -; out: RetnReg5 = 0/1 (transparent/solid) -; - -ReadPixelMask ROUT - Push R14 - LDR R5, [R2, #spImage] - LDR R6, [R2, #spTrans] - SUBS R5, R6, R5 ; offset from Image to Trans mask - MOVEQ R5, #1 ; if =0, no mask so pixel is solid - BEQ %FT10 - BL SpriteMaskAddr ; returns R6, R7 - Pull PC, VS ; Address, Bit position - LDR R5, [R6, R5] ; word from mask - - LDR LR, [R2, #spMode] ; check for 1bpp masks - MOVS LR, LR, LSR #27 - MOVNE R6, #1 - LDREQ R6, [WsPtr, #SprReadNColour] - - ANDS R5, R6, R5, LSR R7 ; extract one mask pixel (bit0..) - MOVNE R5, #1 -10 - STR R5, [WsPtr, #RetnReg5] - Pull R14 - RETURNVC - -; ***************************************************************************** -; -; WritePixelMask - Write a pixel in the mask for a given sprite -; -; External routine -; -; in: R1 -> sprite area -; R2 -> sprite -; R3 = X coordinate of pixel (0 = left) -; R4 = Y coordinate of pixel (0 = bottom) -; R5 = pixel mask 0/1 (transparent/solid) -; - -WritePixelMask ROUT - Push R14 - LDR R8, [R2, #spImage] - LDR R9, [R2, #spTrans] - SUBS R9, R9, R8 ; offset from Image to Trans mask - BEQ %FT10 ; if =0, no mask so quit - BL SpriteMaskAddr ; returns R6, R7 - Pull PC, VS ; Address, Bit position - - LDR LR, [R2, #spMode] - MOVS LR, LR, LSR #27 - LDREQ R8, [WsPtr, #SprWriteNColour] - MOVNE R8, #1 ; adjust for new format sprites - - TEQ R5, #0 - MOVNE R5, R8 - LDR R0, [R6, R9] ; word from mask - BIC R0, R0, R8, LSL R7 - ORR R0, R0, R5, LSL R7 - STR R0, [R6, R9] -10 - Pull R14 - RETURNVC - -; ***************************************************************************** -; -; SpriteGenAddr - Generate address for a given (X,Y) position -; -; SpriteMaskAddr - For use on mask (copes with old/new masks) -; -; Internal routine, called by InsertCol, DeleteCol, ReadPixelColour, -; WritePixelColour, ReadPixelMask, WritePixelMask -; -; Note that InsertCol and DeleteCol are *not* being altered for the -; present round of 1bpp mask work. -; -; -; in: R1 -> sprite area -; R2 -> sprite -; R3 = X coordinate of pixel (0 = left) -; R4 = Y coordinate of pixel (0 = bottom) -; -; out: R6 = address -; R7 = bit position of pixel -; R1-R5, R8-R11 preserved -; V=1 => outside sprite, R0 -> error -; - -SpriteMaskAddr ROUT - Push "R1-R5, R8-R11, LR" - - LDR LR, [R2, #spMode] - MOVS LR, LR, LSR #27 ; get the sprite type from the mode word - BEQ %FT10 ; branch: old format, use old routine as is - - ADD R5, R2, #spWidth - LDMIA R5, {R5-R8} ; R5 ,R6 ,R7 ,R8 - ; spWidth,spHeight,spLBit,spRBit - SUBS R4, R6, R4 ; invert Y coord - BCC %FT90 ; must be in range 0..spHeight - - BL GetMaskspWidth ; change R5 to suit the mask width - ; and R8 to new last bit used - - MLA R0, R5, R4, R4 ; word offset to row = Y*(width+1) - - ;for new format masks the depth is fixed, so... - - MOV R9, #5 ; XShftFactor - MOV R10, #31 ; SprNPix - MOV R11, #0 ; Log2BPC - - B %FT20 ; and continue in the old code - -SpriteGenAddr - Push "R1-R5, R8-R11, LR" -10 - ADD R5, R2, #spWidth - LDMIA R5, {R5-R8} ; R5 ,R6 ,R7 ,R8 - ; spWidth,spHeight,spLBit,spRBit - SUBS R4, R6, R4 ; invert Y coord - BCC %FT90 ; must be in range 0..spHeight - - MLA R0, R5, R4, R4 ; word offset to row = Y*(width+1) - - LDR R9, [WsPtr, #SprXShftFactor] - LDR R10, [WsPtr, #SprNPix] - LDR R11, [WsPtr, #SprLog2BPC] -20 - BitLOffset R6,R3, R9,R10,R11 - WordOffset R3,R3, R9,R10,R11 - -; sprite starts LBit bits into word -; so add LBit to bit offset - - ADD R7, R6, R7 - ADD R3, R3, R7, LSR #5 ; if offset>=32 then inc word address - AND R7, R7, #31 ; force offset into range 0..31 - - CMP R3, R5 ; R3 should now be in range 0..spWidth - CMPEQ R7, R8 ; if R3=spWidth, then check bit posn - BHI %FT90 ; is within sprite - - ADD R6, R0, R3 ; word offset into sprite - ADD R6, R2, R6, LSL #2 - LDR R8, [R2, #spImage] - ADD R6, R6, R8 ; byte address of word in sprite - - Pull "R1-R5, R8-R11, LR" - RETURNVC - -90 - ADRL R0, SpriteErr_InvalidRowOrCol - [ International - Push "lr" - BL TranslateError - Pull "lr" - ] - STR R0, [WsPtr, #RetnReg0] - Pull "R1-R5, R8-R11, LR" - RETURNVS - - -; ***************************************************************************** -; -; GetMaskspWidth - convert spWidth for data to spWidth for mask (1bpp masks) -; -; Internal routine, called from spritemaskaddr & switchouputtomask -; -; in: R5 = spWidth (ie width in words-1) -; (expects R2->sprite) -; -; out: R5 = spWidth (words -1) for mask data -; R8 modified for new last bit used in mask data - -; should only be called for new format sprites, but will cope with old too - -;NOTE: If any changes are made to this routine, please look at the SpriteExtend -;source too, as there is a very similiar routine there too (in SprAdjSize). WT - -GetMaskspWidth ROUT - Push "R0,LR" - - LDR LR, [R2, #spMode] ; fetch the sprite mode - MOVS LR, LR, LSR #27 ; isolate the sprite type and test for =0 - - Pull "R0,PC",EQ ; if an old format sprite, return R5 unchanged - - ; treat any T>max sprites as 32bpp - CMP LR, #SpriteType_MAX - MOVCS LR, #SpriteType_Substitute - - ; bugfix 9/8/93: get log2bpp this way - ADRL R0, NSM_bpptable-4 - LDR LR, [R0, LR, LSL #2] ; get the log2bpp to LR - - RSB LR, LR, #5 ; and change to 5-log2bpp - - MOV R5, R5, LSL LR ; number of pixels for full words - - RSB LR, LR, #5 ; now switch back to log2bpp - LDR R0, [R2, #spRBit] - ADD R0, R0, #1 - ADD R5, R5, R0, LSR LR - - ANDS LR, R5, #&1F ; fit exactly in a number of words ? - SUB R8, LR, #1 ; alter the last bit used for the mask data - ; fix bug MED-01130.... - AND R8, R8, #&1F ; ....bring back into range 00-1F (may be -1 here) - MOVNE LR, #1 ; if not, add an extra word - ADD R5, LR, R5, LSR #5 ; add the whole number of words - SUB R5, R5, #1 ; returns as words-1 - - Pull "R0,PC" - - -; ***************************************************************************** -; -; RemoveLeftHandWastage - Remove left-hand wastage from a sprite -; -; Internal routine, but made external for testing -; -; in: R1 -> sprite area -; R2 -> sprite -; - -RemoveLeftHandWastage ROUT - LDR R0, [R2, #spLBit] - CMP R0, #0 ; is there any wastage ? - MOVEQ PC, R14 ; no, then exit straight away - - Push "R1, R2, R14" ; get stack the same as in DeleteCol - LDR R11, [R2, #spImage] - ADD R11, R11, R2 ; R11 := address of first word - MOV R7, #0 ; bit position of first pixel - STR R7, [R2, #spLBit] ; pretend LBit = 0 - MOV R10, #0 ; byte offset from LH end to delete pt. - - LDR R9, [R2, #spWidth] - MOV R9, R9, LSL #2 ; byte offset from delete pt to LH end - ; of next row -4 - LDR R8, [R2, #spNext] - ADD R8, R8, R2 ; first byte after sprite - - MOV R2, R0 ; number of bits to delete -LHWastageEntry - RSB R3, R2, #32 ; LShft := 32-RShft - - MOV R4, #1 - RSB R4, R4, R4, LSL R7 ; mask for pixels left of deletion pt. - MVN R5, R4 ; inclusive & right of extractn. pt. - -; R0, R1, R2 ,R3 ,R4 ,R5 ,R6 ,R7 ,R8 ,R9 ,R10 .R11 -; , , RShft,LShft,LMask,RMask, ,WordCnt,EndAdr,WordOff,RowOff,Adr - -; R11 -> LH end of row - -10 - ADD R11, R11, R10 ; step to deletion point - LDR R0, [R11] - AND R1, R5, R0, LSR R2 ; extract & shift rightmost pixels - ; (ie MSBits) - AND R0, R4, R0 ; extract leftmost pixels (ie LSBits) - ORR R0, R0, R1 ; recombine (unwanted pixel removed) - LDR R1, [R11, #4] ; shift leftmost pixel of next word - ORR R0, R0, R1, LSL R3 ; in at rightmost end of this word - STR R0, [R11], #4 ; NB #4 to cope with naff rowoff (R10) - CMP R9, #0 - BEQ %FT30 - MOV R7, R9 -20 - LDMIA R11,{R0,R1} ; now do a 1 pixel shift left - MOV R0, R0, LSR R2 ; of the rest of the row - ORR R0, R0, R1, LSL R3 - STR R0, [R11], #4 - SUBS R7, R7, #4 - BGT %BT20 - -; R11 -> LH end of next row - -30 - CMP R8, R11 - BHI %BT10 ; if EndAdr>Adr, do next row - - MOV R0, R2 ; R0 = number of bits to delete - LDMFD R13, {R1,R2} - BL ReduceHorizontally - Pull "R1-R2, R14" - RETURNVC - -60 - STR R0, [WsPtr, #RetnReg0] -70 - Pull "R1-R2, R14" - RETURNVS - - -; ****************************************************************************** -; -; bounce_new_format_masks - object to masks on new format sprites -; -; enter with R2->sprite -; either returns with all registers preserved, or VS and R0->error - -bounce_new_format_masks ROUT - STMFD R13!,{R0,R14} - LDR LR, [R2, #spMode] ; fetch the sprites mode - MOVS LR, LR, LSR #27 ; set NE if new format - LDMEQFD R13!,{R0,R15} ; out now if old format - BL MaskOffset ; returns R0=mask size, EQ if no mask, NE if mask - LDMEQFD R13!,{R0,R15} ; out now if no mask - ADRL R0, SpriteErr_NoMaskOrPaletteAllowedInThisDepth - [ International - BL TranslateError - ] - SETV - STR R0,[R13] - STR R0,[WsPtr, #RetnReg0] - LDMFD R13!,{R0,R15} - - END diff --git a/s/vdu/vdugrafi b/s/vdu/vdugrafi deleted file mode 100644 index f0ff0666..00000000 --- a/s/vdu/vdugrafi +++ /dev/null @@ -1,339 +0,0 @@ -; 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.VduGrafI -; -; ARTHUR OPERATING SYSTEM - Vdu Drivers -; ======================= -; -; Vdu driver code - Sprite stuff -; -; Author R C Manby -; Date 10.11.86 -; -; CHANGES -; ------- -; 12.04.94 W Turner Updated to allow the use of 1bpp masks -; 12.01.95 G Simms Fixed MED-04130 where New format sprites with -; LH wastage were being created. - -; ***************************************************************************** -; -; FlipAboutXAxis - Flip sprite about X axis -; -; External routine -; -; in: R2 -> sprite -; - -FlipAboutXAxis ROUT - Push R14 - - BL MaskOffset - MOV R7, R0 ; 0/offset for nomask/mask - LDR R4, [R2, #spWidth] ; width-1 - LDR R5, [R2, #spHeight] ; height-1 - LDR R6, [R2, #spImage] - TEQ R5, #0 - BEQ %FT05 ; nothing to do, if only 1 row - - ADD R0, R2, R6 ; R0 -> top row in image - ADD R3, R4, #1 ; width - MUL R1, R5, R3 ; R1 = word offset to bottom row - ADD R1, R0, R1, LSL #2 ; R1 -> bottom row in image - - Push "R0-R1, R2, R4-R5, R7" ; preserve ptrs & mask offset - BL FlipAbX10 ; flip main image - Pull "R0-R1, R2, R4-R5, R7" - - CMP R7, #0 - BEQ %FT05 ; No mask so skip this bit - - ADD R0, R0, R7 ; Update the start pointer - - ;If a new format sprite (we know it has a mask) - ;redo R1 & call the 'GetMaskspWidth' routine to alter R3 - - LDR R8, [R2, #spMode] ; Get sprite mode - MOVS R8, R8, LSR #27 ; Isolate sprite type & test for 0 - - ADDEQ R1, R1, R7 ; Old format, so simple - BEQ %FT04 - - ;Here, we know it is a 1bpp mask - MOV R6, R5 ; Better keep R5 safe, we'll need it in a bit - MOV R5, R4 ; The sub wants R4 in r5 - BL GetMaskspWidth ; Update the 'width' if needed - ADD R3, R5, #1 ; R3=width in words - - MUL R1, R6, R3 ; R1 = word offset to bottom row - ADD R1, R0, R1, LSL #2 ; R1 -> Bottom row in image -04 - BL FlipAbX10 ; flip mask -05 - Pull R14 - RETURNVC - -; ***************************************************************************** -; -; FlipAbX10 - Flip area given ptrs and width -; -; Internal routine, called by FlipAboutXAxis -; -; in: R0 -> top row -; R1 -> bottom row -; R3 = width in words -; -; out: R0-R2,R4-R11 corrupted -; R3 preserved -; - -FlipAbX10 ROUT -10 - SUBS R2, R3, #4 ; initialise width count - BLT %FT30 -20 ; flip in blocks of 4 words - LDMIA R0, {R4-R7} - LDMIA R1, {R8-R11} - STMIA R1!, {R4-R7} - STMIA R0!, {R8-R11} - SUBS R2, R2, #4 - BGE %BT20 -30 - ADDS R2, R2, #4 - BLE %FT50 -40 ; do remaining words one by one - LDR R4, [R0] - LDR R8, [R1] - STR R4, [R1], #4 - STR R8, [R0], #4 - SUBS R2, R2, #1 - BNE %BT40 -50 - SUB R1, R1, R3, LSL #3 ; point to previous row - CMP R1, R0 - BHI %BT10 ; loop until pointers meet or cross - MOV PC, R14 ; only R3 preserved - -; ***************************************************************************** -; -; FlipAboutYAxis - Flip a sprite about Y axis -; -; External routine -; -; in: R2 -> sprite -; - -FlipAboutYAxis ROUT - Push R14 - - BL MaskOffset - MOV R8, R0 ;Bung result in R8 'till we want it... - - ADD R3, R2, #spWidth - LDMIA R3, {R3-R7} ; R3 ,R4 ,R5 ,R6 ,R7 - ; spWidth,spHeight,spLBit,spRBit,spImage - ADD R3, R3, #1 ; use width as row offset (words) - - MUL R4, R3, R4 ; R4=width x (height-1) in words - ADD R4, R4, R3 ; R4=width x height in words - ADD R4, R7, R4, LSL #2 ; offset past end of sprite image - ADD R4, R4, R2 ; address past end of image - - RSB R5, R5, #31 ; reflect LBit & RBit - RSB R6, R6, #31 - STR R5, [R2, #spRBit] ; new RBit := 31- old LBit - STR R6, [R2, #spLBit] ; new LBit := 31- old RBit - ADD R0, R2, R7 ; R0 -> start of first row - LDR R11, [WsPtr, #SprBytesPerChar] ; shift factor to - ; reach next pixel - LDR R9, [WsPtr, #SprWriteNColour] ; mask for leftmost pixel - MOV R10, R9, ROR R11 ; mask for rightmost pixel - - Push "R0, R2, R5-R8" - BL FlipAbY10 ; Do the sprite image - Pull "R0, R2, R5-R8" - - Push "R0,R8" - LDR R8, [R2, #spMode] ; Get sprite mode - MOVS R8, R8, LSR #27 ; Isolate sprite type & test for 0 - BEQ %FT03 ; If old format ignore next bit - - ; If this is a new format sprite we may have to remove any LH - ; wastage that was created by the flip. - CMP R6, #0 ; Is there any LH wastage? - BEQ %FT03 ; If not skip the next bit. - MOV R8, R6 - BL RemLHWastage - ; If this is a new format sprite then LH wastage = 0 and the RH wastage - ; is the same as it was to start with. - RSB R5, R6, #31 ; restore old RBit - MOV R6, #0 - STR R5, [R2, #spRBit] ; new RBit := 31- old LBit - STR R6, [R2, #spLBit] ; new LBit := 0 -03 - Pull "R0,R8" - CMP R8, #0 ; Does the sprite have a mask? - BEQ %FT05 ; Nope, so skip the mask flip! - - ;Now, is it an old or new sprite? - LDR R1, [R2, #spMode] ; Get sprite mode - ADD R0, R0, R8 ; R0 points to start of mask - MOVS R1, R1, LSR #27 ; Isolate sprite type & test for 0 - - ADDEQ R4, R4, R8 ;R4 points to end of mask now - BEQ %FT04 ;Skip the next bit (it's for new format only) - - Push "R5" - LDR R5, [R2, #spWidth] - BL GetMaskspWidth - ADD R3, R5, #1 ;R3 is new row offset (words) - Pull "R5" - - Push "R8" ;Last Bit used for mask, this will enable - ;us to remove the left hand wastage after - ;the flip - - LDR R4, [R2, #spHeight] - LDR R8, [R2, #spTrans] - MUL R4, R3, R4 ; R4=width x (height-1) in words - ADD R4, R4, R3 ; R4=width x height in words - ADD R4, R8, R4, LSL #2 ; offset past end of sprite mask - ADD R4, R4, R2 ; address past end of mask - - ADD R0, R2, R8 ; R0 -> start of first row of mask -; LDR R11, [WsPtr, #SprBytesPerChar] ; shift factor to - ; reach next pixel -; LDR R9, [WsPtr, #SprWriteNColour] ; mask for leftmost pixel - - MOV R11, #1 - MOV R9, #1 - - MOV R10, R9, ROR R11 ; mask for rightmost pixel - - Push "R0" - BL FlipAbY10 ; Now do the mask - Pull "R0" - Pull "R8" ; Retrieve last bit used to find LHwastage - RSB R8, R8, #31 - CMP R8, #0 - BEQ %FT05 - BL RemLHWastage - B %FT05 -04 - BL FlipAbY10 ; Now do the mask -05 - Pull R14 - RETURNVC - -; ***************************************************************************** -; -; FlipAbY10 - Flip area given ptrs and width -; -; Internal routine, called by FlipAboutYAxis -; -; N.B. This reflects 'user pixels', ie in double pixel modes it -; reflects pairs of screen pixels, this should not matter. -; -; ON ENTRY, we have R0, R3-R4, R9-R11 -; ON EXIT, of these, only R0 is corrupted - -; Internally: -; R0 RowPtr, R1 LPtr , R2 RPtr , R3 Row offset, R4 EndAdr -; R5 LWord , R6 RWord, R7 LTemp, R8 RTemp , R9 LPixMask -; R10 RPixMask, R11 ShftFactor, R14 Cnt - -; R0-R2, R5-R8 get corrupted - -FlipAbY10 - Push R14 -10 - MOV R1, R0 ; R1 -> left end of row - ADD R0, R0, R3, LSL #2 ; R0 -> past right end of row - MOV R2, R0 ; R2 := R0 -20 - LDR R5, [R1] - LDR R6, [R2, #-4]! - MOV R14, #32 ; total number of bits to process -30 ; circular pixel shift of LWord & RWord - AND R7, R5, R9 ; leftmost pixel (LSPart of LWord) - AND R8, R6, R10 ; rightmost pixel (MSPart of RWord) - ORR R5, R8, R5, LSR R11 - ORR R6, R7, R6, LSL R11 - SUBS R14, R14, R11 ; process next pixel - BNE %BT30 ; TMD 12-Jan-88 bug fixed here - ; I had changed RCM's code and put BCS - - STR R5, [R1], #4 - STR R6, [R2] - CMP R2, R1 - BHI %BT20 ; loop until pointers meet or cross - - CMP R0, R4 - BCC %BT10 ; if address < end, reflect next row - - Pull R14 - MOV PC, R14 - -; ***************************************************************************** -; -; RemLHWastage - Dedicated routine to remove x bits of LH wastage -; after a new format Sprite has been flipped -; -; On Entry: R0 = Start of data -; R3 = Row Offset -; R4 = End of data -; R8 = No. Bits to Remove -; R0 RowPtr, R1 LPtr , R2 RPtr , R3 Row offset, R4 EndAdr - -RemLHWastage - Push "R1,R2,R5-R8,R14" -10 -;start of loop for each line - MOV R1, R0 ; R1 -> left end of row - ADD R0, R0, R3, LSL #2 ; R0 -> past right end of row - SUB R2, R0, #4 ; R2 -> last word in row - ; (used for loop check) - LDR R5, [R1] ; load current word -20 -;Start of loop for each word - CMP R2, R1 - ;If we have reached the last word then just shift and store - MOVEQ R5, R5, LSR R8 - STREQ R5, [R1] - BEQ %FT99 - ;There are more words left so we need to shift in the LSBits from the next - ;word. - LDR R6, [R1, #4] ; load next word - MOV R5, R5, LSR R8 ; Throw away wastage bits in current word - RSB R14, R8, #32 - MOV R7, R6, LSL R14 ; Move LSBs from next word to current - ORR R5, R5, R7 - STR R5, [R1],#4 ; store current word - MOV R5, R6 ; move next word to current word ready for - ; next loop iteration. - - B %BT20 -; CMP R2, R1 -; BHI %BT20 ; loop until pointers meet or cross - -99 - CMP R0, R4 - BCC %BT10 ; if address < end, reflect next row - - Pull "R1,R2,R5-R8,R14" - MOV PC, R14 - - - END diff --git a/s/vdu/vdugrafj b/s/vdu/vdugrafj deleted file mode 100644 index dfac8679..00000000 --- a/s/vdu/vdugrafj +++ /dev/null @@ -1,1331 +0,0 @@ -; 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.VduGrafJ -; -; ARTHUR OPERATING SYSTEM - Vdu Drivers -; ======================= -; -; Vdu driver code - Sprite stuff -; -; Author R C Manby -; Date 10.11.86 -; - -; ***************************************************************************** -; -; GetSpriteUserCoords - Pick up area of screen as sprite using -; given external coordinates -; -; External routine -; -; in: R1 -> sprite area -; R2 -> sprite name -; R3 = 0 => exclude palette data -; 1 => include palette data -; R4,R5 = (X,Y) EXTERNAL coordinates of one corner of box -; R6,R7 = (X,Y) EXTERNAL coordinates of opposite corner of box -; - -GetSpriteUserCoords ROUT - Push "R1-R3, R14" - ADD R8, WsPtr, #GCsX - LDMIA R8, {R9,R10} ; preserve GCsX,GCsY around EIG - - MOV R0, R4 - MOV R1, R5 - MOV R2, #4 ; indicate absolute coord - BL EIG - MOV R4, R0 - MOV R5, R1 - - MOV R0, R6 - MOV R1, R7 - BL EIG - MOV R6, R0 - MOV R7, R1 - - STMIA R8, {R9,R10} ; restore GcsX,GCsY - Pull "R1-R3, R14" - B GetSpr05 - -; ***************************************************************************** -; -; GetSprite - Pick up area of screen bounded by OldCs and GCsI as sprite -; -; External routine + GetSpr05 called by GetSpriteUserCoords -; (also external) -; -; in: R1 -> sprite area -; R2 -> sprite name -; R3 = 0 => exclude palette data -; 1 => include palette data -; OldCsX,OldCsY = (X,Y) INTERNAL coordinates of one corner of box -; GCsIX, GCsIY = (X,Y) INTERNAL coordinates of opposite corner of box -; - -GetSprite ROUT - ADD R4, WsPtr, #OldCsX ; pickup area given by OldCs - LDMIA R4, {R4-R7} ; and GCsIX -GetSpr05 - Push R14 - [ {TRUE} - GraphicsMode R0 - BNE %FT70 - | - LDR R0, [WsPtr, #NPix] - TEQ R0, #0 - BEQ %FT70 ; quit with error if not graphics mode - ] - - KillSpChoosePtr - - SortT R4, R6, R8 ; R4 ,R5, R6 ,R7 N.B. BotL & - SortT R5, R7, R8 ; sL ,sB, sR ,sT TopR - - LDR R8, [WsPtr, #YWindLimit] - SUB R8, R8, R7 ; use inverted sT as index - AND R8, R8, #7 ; into EcfPatternTable - STR R8, [WsPtr, #SGetEcfIndx] - - LDR R0, [WsPtr, #ModeNo] - STR R0, [WsPtr, #SGetMode] ; needs setting up before CreateHeader - - Push R2 - BL SpriteCtrlBlk - BVC %FT90 ; sprite already exists, so be clever - Pull R2 ; restore name pointer - - ; R1 ,R2 ,R3 ,R4,R5,R6,R7 - BL CreateHeader ; In : AreaPtr,NamePtr,Palette ,sl,sb,sr,st - ; Out: ImageSize,lx,ty, - BVS %FT80 ; Error, (no room/not a graphics mode) - - BL GetSpriteData - -; R1 -> sprite area, R2 -> sprite -; now add the sprite to the sprite area - - LDR R3, [R2, #spNext] ; total size of new sprite - LDMIA R1, {R4-R7} ; saEnd,saNumber,saFirst,saFree - ADD R5, R5, #1 - ADD R7, R7, R3 - STMIA R1, {R4-R7} - -; have we made a new format sprite ? if so no left hand wastage is allowed. - - LDR R3, [R2, #spMode] - CMP R3, #256 - - BLCS RemoveLeftHandWastage - - BL SelectSprite - SWI XOS_RestoreCursors - Pull R14 - RETURNVC - -70 - ADRL R0, SpriteErr_NotGraphics - [ International - BL TranslateError - ] -75 - STR R0, [WsPtr, #RetnReg0] -80 ; return point after an error - Pull R14 - RETURNVS - -; come here if sprite already exists -; we want to extend or reduce existing sprite as necessary - -90 - ADD R13, R13, #4 ; throw away stacked name ptr - LDR R14, [WsPtr, #VduSprite] - TEQ R14, R2 ; if same as vdu output sprite - ADREQL R0, SpriteErr_SpriteIsCurrentDest - [ International - BLEQ TranslateError - ] - BEQ %BT75 ; then error - - ADR R14, %FT95 + SVC_mode - Push "R1, R14" - ADD R8, WsPtr, #NameBuf - LDMIA R8, {R9-R11} ; load 3 words of name - ADD R8, WsPtr, #SGetName - STMIA R8, {R9-R11} ; and store in SGetName - - Push "R1, R2, R3" ; save sprite area, sprite, palflag - BL PreCreateHeader - Pull "R1, R2" ; restore sprite area ptr + sprite ptr - BVS %FT93 - ; R4 = total size of sprite - Push R4 ; save new size of sprite - LDR R0, [R2, #spNext] - SUBS R3, R4, R0 ; compare required size with existing - MOV R3, R3, ASR #2 ; no. of words to extend/reduce by - BEQ %FT94 ; [is exactly right already] - BHI %FT92 ; need to extend sprite - -; need to reduce sprite - - RSB R3, R3, #0 ; no. of words to reduce by - LDR R4, [R2, #spImage] - SUB R4, R0, R4 ; offset from Image to Next - SUB R4, R4, R3, LSL #2 ; dest. start as offset from spImage - BL RemoveWords - RSB R3, R3, #0 ; put R3 back to no. of words to extend - B %FT94 - -; need to extend sprite - -92 - BL ExtendSpriteByR3 -93 - ADDVS R13, R13, #4*4 ; junk size, palflag, - ; sprite area, fake return address - BVS %BT80 ; no room to extend sprite -94 - Pull R4 ; restore new size of sprite - B PostCreateHeader - -; come back to here after PostCreateHeader exits -; R1 -> sprite area, R2 -> sprite, R3 = no. of words to extend by - -95 - BL GetSpriteData - BL SelectSprite - -; have we made a new format sprite ? if so no left hand wastage is allowed. - - LDR R3, [R2, #spMode] - CMP R3, #256 - BLCS RemoveLeftHandWastage - - SWI XOS_RestoreCursors - Pull R14 - RETURNVC - -; ***************************************************************************** - -GetSpriteData ROUT - Push "R1-R3, R14" - SWI XOS_RemoveCursors - MOV R0, R4 - MOV R1, R5 - BL ScreenAddr - MOV R0, R2 ; screen addr of TopL of area - LDMIA R13, {R4,R5} ; R4->sprite area, R5->sprite - LDR R1, [WsPtr, #SGetImage] - ADD R1, R1, R5 ; memory address - LDR R2, [WsPtr, #SGetWidth] - ADD R2, R2, #1 ; sprite width (words) - LDR R3, [WsPtr, #SGetHeight] ; height - ADD R3, R3, #1 - - LDR R8, [WsPtr, #SGetTopMargin] ; gap above window (rows) - LDR R9, [WsPtr, #SGetBotMargin] ; below (rows) - LDR R10, [WsPtr, #SGetLWrdMargin] ; left of (words) - LDR R11, [WsPtr, #SGetRWrdMargin] ; right of (words) - - SUB R2, R2, R10 - SUBS R2, R2, R11 ; number words in window per scanline - BLEQ PaintSprite ; Left or Right of window - BEQ %FT60 - - SUB R3, R3, R8 - SUBS R3, R3, R9 ; number of rows in window - BLEQ PaintSprite ; above or below window - BEQ %FT60 - - LDR R14, [WsPtr, #LineLength] ; offset from RHend of row to LHend - SUB R14, R14, R2, LSL #2 ; of next row - STR R14, [WsPtr, #SGetRowOfst] - - LDR R11, [WsPtr, #SGetLBitMargin] - MOV R5, #&FFFFFFFF - MOV R5, R5, LSL R11 ; LmarginMask - - LDR R11, [WsPtr, #SGetRBitMargin] - MOV R6, #&FFFFFFFE - MVN R6, R6, LSL R11 ; RmarginMask - - SUBS R2, R2, #1 - STR R2, [WsPtr, #SGetColWCnt] ; if only one word in window per row - ANDEQ R5, R5, R6 ; then combine L&R masks - MOVEQ R6, R5 - STR R5, [WsPtr, #SGetLBitMargin] - STR R6, [WsPtr, #SGetRBitMargin] - - LDR R5, [WsPtr, #SGetTopMargin] ; paint TopMargin (if any) - CMP R5, #0 - BLNE PaintBlock - -; R0 ,R1 ,R2 ,R3 ,R4 .. R11 -; ScrAdr,MemAdr,ColWCnt,RowCnt,{8 words from screen}, - -10 - LDR R4, [WsPtr, #SGetLWrdMargin] ; paint 1 row of LHmargin (if any) - CMP R4, #0 - BLNE PaintRow ; on exit R6 holds word of BgEcf, if not called - ; R6 is corrupt, but it doesn't matter - LDR R2, [WsPtr, #SGetColWCnt] ; on screen word count ( >0 in words) - LDR R5, [WsPtr, #SGetLBitMargin] - LDR R4, [R0], #4 ; get first on screen word - AND R4, R4, R5 - BIC R6, R6, R5 ; Write BgEcf (or nonsense) to out of window - ORR R4, R4, R6 ; pixels - STR R4, [R1], #4 - SUBS R2, R2, #1 - BLT %FT50 ; if all plotted - - SUBS R2, R2, #8 ; try for 8 words -20 - LDMCSIA R0!, {R4-R11} ; copy 8 words from screen to memory - STMCSIA R1!, {R4-R11} - SUBCSS R2, R2, #8 - BCS %BT20 -30 - ADDS R2, R2, #8 - LDR R6, [WsPtr,#SGetEcfIndx] - ADD R6, WsPtr, R6, LSL #2 - LDR R6, [R6, #BgEcf] ; BgEcf for this scanline - LDR R5, [WsPtr,#SGetRBitMargin] - BIC R6, R6, R5 -40 - LDR R4, [R0], #4 - ANDEQ R4, R4, R5 - ORREQ R4, R4, R6 - STR R4, [R1], #4 - SUBS R2, R2, #1 - BCS %BT40 -50 - LDR R4, [WsPtr, #SGetRWrdMargin] - CMP R4, #0 - BLNE PaintRow - - LDR R2, [WsPtr, #SGetColWCnt] - LDR R4, [WsPtr, #SGetRowOfst] - LDR R5, [WsPtr,#SGetEcfIndx] - ADD R0, R0, R4 ; offset ScrAdr to next row - ADD R5, R5, #1 - AND R5, R5, #7 - STR R5, [WsPtr, #SGetEcfIndx] ; update EcfIndx to next row - SUBS R3, R3, #1 - BGT %BT10 ; do next screen line - - LDR R5, [WsPtr, #SGetBotMargin] ; paint bottom margin (if any) - CMP R5, #0 - BLNE PaintBlock -60 - Pull "R1-R3, PC" - - -; ***************************************************************************** -; -; PaintSprite - Paint the whole of the sprite in background colour -; -; Internal routine, called by GetSprite when all area is outside window -; -; in: R1 -> first byte in sprite -; - -PaintSprite ROUT - LDR R5, [WsPtr, #SGetHeight] - ADD R5, R5, #1 ; R5 = number of rows in sprite - -; and drop thru to ... - -; ***************************************************************************** -; -; PaintBlock - Paint a number of rows of the sprite in background colour -; -; Internal routine, called by GetSprite to do area above and below window -; and dropped thru to by PaintSprite -; -; in: R1 -> start of first row to paint -; R5 = number of rows to do -; -; out: Flags preserved - -PaintBlock ROUT - [ No26bitCode - MRS R4, CPSR - Push "R4,R14" - | - Push R14 - ] - LDR R4, [WsPtr, #SGetWidth] - ADD R4, R4, #1 -10 - BL PaintRow - LDR R6, [WsPtr, #SGetEcfIndx] - ADD R6, R6, #1 - AND R6, R6, #7 - STR R6, [WsPtr, #SGetEcfIndx] - SUBS R5, R5, #1 - BNE %BT10 - - [ No26bitCode - Pull "R4,R14" - MSR CPSR_f, R4 - MOV PC,R14 - | - Pull PC,,^ ; we must preserve the flags - ] - -; ***************************************************************************** -; -; PaintRow - Paint part of a row in sprite with background colour -; -; Internal routine, called by GetSprite to do areas left+right of window -; and by PaintBlock -; -; in: R1 -> first word to paint -; R4 = number of words to paint -; -; out: R4 preserved -; - -PaintRow ROUT - Push R4 - LDR R6, [WsPtr, #SGetEcfIndx] - ADD R6, WsPtr, R6, LSL #2 - LDR R6, [R6, #BgEcf] ; BgEcf for this scanline -10 - STR R6, [R1], #4 - SUBS R4, R4, #1 - BNE %BT10 - Pull R4 - MOV PC, R14 - -; ***************************************************************************** -; -; CreateSprite - Create a sprite with given attributes -; -; External routine -; -; in: R1 -> sprite area -; R2 -> sprite name -; R3 = 0/1 => exclude/include palette data -; R4 = width in pixels -; R5 = height in pixels -; R6 = mode number of sprite -; - -CreateSprite ROUT - Push R14 - KillSpChoosePtr - BL DeleteSpriteByName ; delete any existing sprite - STR R6, [WsPtr, #SGetMode] ; needs setting up before CreateHeader - SUB R6, R4, #1 ; width in pixels-1 - SUB R7, R5, #1 ; height-1 - MOV R4, #0 - MOV R5, #0 - ; R3 ,R4,R5,R6,R7 - BL CreateHeader ; In : Palette,sl,sb,sr,st - ; Out: ImageSize - Pull PC, VS ; if error, then bomb out - - MOV R4, #0 ; clear R3 words at offset 0 in sprite - BL ClearWords ; ie clear image to 0 - - ; Now add the sprite to the sprite area - - LDR R3, [R2, #spNext] ; total size of new sprite - LDMIA R1, {R4-R7} ; saEnd,saNumber,saFirst,saFree - ADD R5, R5, #1 - ADD R7, R7, R3 - STMIA R1, {R4-R7} - - Pull R14 - RETURNVC - -; ***************************************************************************** -; -; CreateHeader - Create a header and info for a sprite -; -; Internal routine, called by GetSprite, CreateSprite, ScreenSave -; -; in: R1 -> sprite area -; R2 -> sprite name -; R3 = 0/1 => exclude/include palette data -; R4,R5 = (X,Y) INTERNAL coordinate of bottom left -; R6,R7 = (X,Y) INTERNAL coordinate of top right -; -; out: R1 preserved -; R2 -> new sprite -; R3 = size of image in words -; R4,R5 = (X,Y) INTERNAL coordinate of top left of on screen area -; R0, R6-R11 corrupted -; - -CreateHeader ROUT - Push "R1, R14" - Push R3 - - BL GetName ; name returned in R9-R11 - ADD R8, WsPtr, #SGetName - STMIA R8, {R9-R11} ; save the name away - - BL PreCreateHeader - - Pull "R0, R1, PC", VS - -; now the updating the sprite area bit - - LDR R1, [R13, #1*4] ; reload sprite area ptr off stack - LDR R2, [R1, #saFree] - LDR R5, [R1, #saEnd] - SUB R5, R5, R2 - CMP R5, R4 - BCC %FT10 - - ADD R2, R2, R1 ; address of new sprite - -PostCreateHeader - ADD R5, WsPtr, #SGetName - LDMIA R5, {R5-R11} - -; R4 spNext, R5-R7 spName(0..2), -; R8 spWidth, R9 spHeight, R10 spLBit, R11 spRBit - - STMIA R2, {R4-R11} ; write control block for sprite - LDR R11, [WsPtr, #SGetImage] - STR R11, [R2, #spImage] - STR R11, [R2, #spTrans] ; spImage=spTrans ie no mask - - LDR R11, [WsPtr, #SGetMode] - - [ {FALSE} ; TMD 08-Jun-93: SGetMode sanitation done in PreCreateHeader now -; Previously we simply copied the current SGetMode straight into spmode. -; With the advent of mode descriptors and the new sprite mode word this -; has to get a bit more intelligent. New logic is: -; i) is the value > 256 (unsigned) ? Y - mode descriptor - have to make -; a new sprite mode word, N - proceed to next... -; ii) is this higher than 8bpp ? Y - have to use a new sprite mode word -; N - use the mode number - -; Note: Once all the mode descriptor work is complete the second test -; may be removed, since no 16/32bpp modes will have mode numbers -; associated with them. However, until then it stays. - - ! 0,"vdugrafj: remove marked section when mode descriptors" - ! 0," work, and no 16/32bpp modes have old mode numbers." - - CMP R11, #256 - BCC %FT20 ;branch if under 256 - -30 ; this mode is not available in RISC OS 3, so give it a new format - ; sprite mode word instead - - Push "R0-R3" - - MOV R0,R11 - MOV R1,#VduExt_Log2BPP - SWI XOS_ReadModeVariable - - MOV R11,#1 ;bit 0 is always set - - ADD LR, R2, #1 ;turn it into the sprite type - ORR R11, R11, LR, LSL #27 ;and put it into position - - MOV R1, #VduExt_XEigFactor - SWI XOS_ReadModeVariable - - MOV R4, #180 - MOV LR, R4, LSR R2 ;convert to a dpi (180 >> eig) - ORR R11, R11, LR, LSL #1 ;and put it into position - - MOV R1, #VduExt_YEigFactor - SWI XOS_ReadModeVariable - - MOV LR, R4, LSR R2 ;convert to a dpi (180 >> eig) - ORR R11, R11, LR, LSL #14 ;and put it into position - - Pull "R0-R3" - - B %FT40 - -20 ;************************************************************************** - ;The test and branch below should be removed once mode descriptors are done - ;************************************************************************** - - ; ,---------------- BEGIN REMOVE SECTION ################################## - ; v # - Push "R0-R3" ; # - MOV R0,R11 ; # - MOV R1,#VduExt_Log2BPP ; # - SWI XOS_ReadModeVariable ; # - CMP R2, #4 ; # - Pull "R0-R3" ; # - BCS %BT30 ;over 3 ?, put in a new sprite mode word # - ; ^ # - ; '---------------- END REMOVE SECTION #################################### - - ; it is an old fashioned mode number, so use that to allow RO 3.00/3.10 - ; to understand this sprite -40 - ] - STR R11, [R2, #spMode] - MOVS LR, R11, LSR #27 ; do we have an old or new sprite ? EQ=old - - ADD R4, WsPtr, #SGetTopLeft - LDMIA R4, {R4, R5} ; (R4,R5) = TopLeft of 'on screen' area - Pull R11 ; R11 = 0/1 for (ex/in)clude palette - -;amg 25th May 1994. We now allow palettes on new format sprites in 8bpp and below - - CMP LR,#SpriteType_New16bpp - BCS %FT11 ; check for new 16/32 bpp - - TEQ R11,#0 ; was a palette wanted in the first place? - BLNE WritePaletteToSprite ; do it if so - -; ;only allow palette data to be written if EQ and R11<>0 -; -; BNE %FT11 -; -; TEQ R11, #0 -; BLNE WritePaletteToSprite - -11 - Pull "R1, R14" - RETURNVC - -10 - ADRL R0, SpriteErr_NoRoom - [ International - BL TranslateError - ] - STR R0, [WsPtr, #RetnReg0] - Pull "R0, R1, R14" ; junk palflag, sprite area ptr - RETURNVS - -; ***************************************************************************** -; -; SanitizeSGetMode - Convert SGetMode into a new format sprite word if necessary -; -; If SGetMode is either a) a mode selector pointer, or -; b) a mode number which has more than 8bpp -; then SGetMode is replaced by a suitable sprite mode word -; -; amg: 15/10/93: changed to be more keen to generate old format mode numbers. It is -; now also called from createsprite, so it will pass through a new -; sprite mode word unchanged. Mode numbers will be unchanged. Mode -; selectors will be changed to a mode number if one of suitable -; eigs and depth exists --- size of screen is *not* taken into -; account here. - - -; in: WsPtr -> VDU workspace -; -; out: If OK, then -; V=0 -; All registers preserved -; else -; V=1 -; r0 -> error -; RetnReg0 -> error -; endif -; - -SanitizeSGetMode Entry "r0-r4,r11" - LDR r11, [WsPtr, #SGetMode] - - CMP r11, #&100 - BCC %FT20 ; [not a mode selector or new format sprite word] - - TST r11, #1 ; is it already a new format sprite word? - EXIT NE -10 - MOV r0, r11 ; r0 -> mode selector - [ ModeSelectors - BL ValidateModeSelector - STRVS r0, [sp] - STRVS r0, [WsPtr, #RetnReg0] - EXIT VS - ] - -15 -; convert to new format sprite word - - MOV r4, r11 ; preserve the mode for later - - MOV r11,#1 ; bit 0 is always set - - MOV r1, #VduExt_XEigFactor - SWI XOS_ReadModeVariable - - MOV lr, #180 - MOV lr, lr, LSR r2 ; cope with 45, 90, 180 dpi - - ORR r11, r11, lr, LSL #1 ; put into xdpi position - - MOV r1, #VduExt_YEigFactor - SWI XOS_ReadModeVariable - - MOV lr, #180 - MOV lr, lr, LSR r2 - ORR r11, r11, lr, LSL #14 ; put into ydpi position - - ;amg: add check for log2bpp=log2bpc - - MOV r0, r4 - MOV r1, #VduExt_Log2BPC - SWI XOS_ReadModeVariable - MOV R3,R2 - - MOV r0, r4 - MOV r1, #VduExt_Log2BPP - SWI XOS_ReadModeVariable - - CMP R3, R2 - BNE %FT20 - - ADD lr, r2, #1 ; turn it into the sprite type - ORR r11, r11, lr, LSL #27 ; and put it into position - - STR r11, [WsPtr, #SGetMode] ; store new value - - ;now check if we can force it back to a mode number - - ;if the bpp is > 8 the answer is no - CMP r2, #4 - EXIT CS - - BIC r0, r11, #&F8000000 ; take off the type information - ADR r1, substitute_list - ADD r2, r1, #12 ; end of list -27 - LDR r3, [r1], #4 - TEQ r3, r0 - BEQ %FT28 - TEQ r1, r2 - EXIT EQ ; can't do anything with it - BNE %BT27 -28 - ADD r1, r1, #8 ; point at modes word, allowing for post inc - ADD r1, r1, r11, LSR #27 ; add in the sprite's type - SUB r1, r1, #1 ; and reduce it by one - LDRB r1, [r1] ; fetch the right mode number - - ;if we got 255, we can't save the day - CMP r1,#255 - STRNE r1, [WsPtr, #SGetMode] ; and store it - - EXIT - -substitute_list - DCD &001680B5 ;90 X 90 DPI, X/Y EIG 1 1 - DCD &000B40B5 ;90 X 45 DPI, X/Y EIG 1 2 - DCD &000B405B ;45 X 45 DPI, X/Y EIG 2 2 - - ;amg: used to use mode 4 for 2 colour eig 2 x 2 - now doesn't because of - ;confusion about double pixels - - DCD &1C1B1A19 ;modes 25, 26, 27, 28 for 90 x 90 - DCD &0F0C0800 ;modes 0, 8, 12, 15 for 90 x 45 - DCD &0D0901FF ;modes n/a, 1, 9, 13 for 45 x 45 -20 - MOV r0, r11 ; check if bpp for mode is > 8 - MOV r1, #VduExt_Log2BPP - SWI XOS_ReadModeVariable - CMP r2, #4 - BCS %BT15 ; if so then convert to new format sprite as well - EXIT - -; ***************************************************************************** - -PreCreateHeader ROUT - Push R14 - BL SanitizeSGetMode ; convert SGetMode to new format sprite if nec. - Pull PC, VS ; duff mode selector - - ;amg 25th May 1994 - ;We now allow palettes on new format sprites of 8bpp and below - -; ;force to no palette space if a new format sprite -; LDR LR, [WsPtr, #SGetMode] ; get the mode -; MOVS LR, LR, LSR #27 ; set NE if new -; MOVNE R3, #0 ; turn off palette - - LDR LR, [WsPtr, #SGetMode] ; get the sprite mode word - MOV LR, LR, LSR #27 ; isolate the sprite type - CMP LR, #SpriteType_New16bpp ; check for 16/32bpp - MOVCS R3, #0 ; turn off the palette request - - TEQ R3, #0 ; convert R3 into mask to (ex/in)clude - MOVNE R3, #&FF ; space for palette data - -; amg need more palette space in case it's going to be a full palette - ORRNE R3, R3, #&300 - - Push "R6, R7" ; preserve R6,R7 over the call - ADD R2, WsPtr, #SGetNext - BL SetupSprModeData - -; R6 ,R7 ,R8 ,R9 ,R10 ,R11 -; Out: RdNCol,WrNCol,BytePC,XShft,NPix,Log2BPC - -; amg 26th October 1993 - kill another bit of Arthur compatibility in favour -; of full palette 8bpp sprites -; AND R6, R6, #63 ; make 64 palette entries like MOS 1.2 - - LDR R7,[WsPtr,#ModeFlags] - TST R7, #Flag_FullPalette - ANDEQ R6, R6, #63 - - ADD R6, R6, #1 ; number of palette entries in this mode - AND R3, R3, R6 ; if (palette not wanted) OR (256 colour mode) - ; then R3=0 else R3=number of palette entries - ; N.B. in 256 colour modes we end up ignoring - ; the palette - Pull "R6,R7" - Pull PC, VS ; error, not a graphics mode - - MOV R3, R3, LSL #3 ; two words per palette entry - ADD R3, R3, #SpriteCBsize - STR R3, [WsPtr, #SGetImage] ; R0-R3 now free for use - ; R4 ,R5, R6 ,R7 - ; sL ,sB, sR ,sT - SUB R0, R7, R5 ; height-1 - STR R0, [WsPtr, #SGetHeight] - ADD R0, R0, #1 ; actual height in rows - - LDR R1, [WsPtr, #GWTRow] ; if SpriteTopRow > GWTopRow - SUBS R2, R7, R1 - MOVGT R7, R1 ; then clip for ScreenAddr's benefit - MOVLE R2, #0 - Least R2, R2, R0 - STR R2, [WsPtr, #SGetTopMargin] ; number of blank rows at top - - LDR R1, [WsPtr, #GWBRow] - SUBS R2, R1, R5 - MOVLT R2, #0 - Least R2, R2, R0 - STR R2, [WsPtr, #SGetBotMargin] ; number of blank rows at bottom - - WordOffset R0,R4, R9,R10,R11 ; offset to sL - WordOffset R1,R6, R9,R10,R11 ; to sR - SUB R2, R1, R0 ; width-1 - STR R2, [WsPtr, #SGetWidth] - ADD R2, R2, #1 ; actual width in words - - BitLOffset R3,R4, R9,R10,R11 ; LBit - STR R3, [WsPtr, #SGetLBit] - BitROffset R3,R6, R9,R10,R11 ; RBit - STR R3, [WsPtr, #SGetRBit] - - LDR R8, [WsPtr, #GWLCol] - Greatest R4,R4,R8 - WordOffset R3,R4, R9,R10,R11 ; offset to clipL - SUB R3, R3, R0 - Least R3,R3,R2 - STR R3, [WsPtr, #SGetLWrdMargin] ; no. of blank words at left - BitLOffset R3,R4, R9,R10,R11 - STR R3, [WsPtr, #SGetLBitMargin] ; no. of blank words at right - - LDR R8, [WsPtr, #GWRCol] - Least R6, R6, R8 - WordOffset R3,R6, R9,R10,R11 ; offset to clipR - SUB R3, R1, R3 - Least R3, R3, R2 - STR R3, [WsPtr, #SGetRWrdMargin] - BitROffset R3,R6, R9,R10,R11 - STR R3, [WsPtr, #SGetRBitMargin] - - ADD R0, WsPtr, #SGetTopLeft - STMIA R0, {R4, R7} ; store top & left of 'on screen' area - LDR R0, [WsPtr, #SGetWidth] - LDR R1, [WsPtr, #SGetHeight] - ADD R0, R0, #1 ; width in words - ADD R1, R1, #1 ; height in words - - MUL R3, R1, R0 ; image size in words - LDR R4, [WsPtr, #SGetImage] - ADD R4, R4, R3, LSL #2 ; total size in bytes - - Pull R14 - RETURNVC - -; ***************************************************************************** -; -; Decide mask size -; -; Internal routine called from CreateMask -; -; in: R1 -> sprite area -; R2 -> sprite -; R3 = size of image data (bytes) -; -; out: R3 = size of mask data (words) - -DecideMaskSize ROUT - Push "R0-R2,R4-R5,R14" - - LDR LR, [R2, #spMode] ; get the sprite mode - MOVS LR, LR, LSR #27 ; isolate the type - - MOVEQ R3,R3,LSR #2 ; if T=0 then return the same size as - Pull "R0-R2,R4-R5,R15",EQ ; the image (but returns in words not - ; bytes) - - ADRL R5, NSM_bpptable-4 - LDR R4, [R5, LR, LSL #2] ; get the log2bpp value - - LDR R5, [R2, #spWidth] ; number of words-1 per row - - LDR LR, [R2, #spRBit] ; fetch the last bit used - ADD LR, LR, #1 ; turn into a number of bits rather than bit number - MOV LR, LR, LSR R4 ; turn into a number of pixels - - RSB R4, R4, #5 - MOV R5, R5, LSL R4 ; number of pixels on the row for the full words - - ADD R5, R5, LR - - ANDS LR, R5, #&1F ; is it a whole number of words - MOVNE LR, #1 ; if not start at 1 not 0 - ADD LR, LR, R5, LSR #5 ; add the number of whole words - - ; now have number of words per mask row - - LDR R5, [R2, #spHeight] ; number of rows (minus 1) - ADD R5, R5, #1 - MUL R3, LR, R5 ; number of words for the mask - - Pull "R0-R2,R4-R5,R15" - -; ***************************************************************************** -; -; CreateMask - Add mask to sprite or set existing mask to 'solid' -; -; External routine -; -; in: R1 -> sprite area -; R2 -> sprite -; - -CreateMask ROUT - Push R14 - KillSpChoosePtr - LDR R4, [R2, #spNext] - LDR R5, [R2, #spImage] ; NB Image=Trans if NO mask - LDR R6, [R2, #spTrans] - SUB R3, R4, R6 - - BL DecideMaskSize ; returns R3=size of mask (words) - - TEQ R5, R6 - BNE %FT10 ; mask exists - - MOV R6, R4 - BL ExtendSprite - ADRVSL R0, SpriteErr_NotEnoughRoom ; only error is NoRoomToInsert - [ International - BLVS TranslateError - ] - STRVS R0, [WsPtr, #RetnReg0] ; correct this to 'Not enough room' - Pull PC, VS - - STR R6, [R2, #spTrans] ; new spTrans := old spNext -10 ; R3 mask size (words), R6 spTrans - ADD R6, R6, R2 - MOV R4, #&FFFFFFFF -20 - STR R4, [R6], #4 - SUBS R3, R3, #1 - BNE %BT20 - - Pull R14 - RETURNVC - -; ***************************************************************************** -; -; RemoveMask - Remove mask from sprite -; -; External routine -; -; in: R1 -> sprite area -; R2 -> sprite -; - -RemoveMask ROUT - Push R14 - KillSpChoosePtr - LDR R4, [R2, #spNext] - LDR R5, [R2, #spImage] ; NB spTrans = spImage, if NO mask - LDR R6, [R2, #spTrans] - TEQ R5, R6 - BEQ %FT10 ; no mask so ignore - - SUB R3, R4, R6 - - BL DecideMaskSize ; returns R3=size in words - - SUB R4, R6, R5 - BL RemoveWords - LDR R5, [R2, #spImage] ; spTrans := spImage, ie NO mask - STR R5, [R2, #spTrans] -10 - Pull R14 - RETURNVC - -; ***************************************************************************** -; -; WritePaletteToSprite - Write palette information into sprite CB -; -; Internal routine, called by CreateHeader -; -; in: R2 -> sprite -; -; out: All registers preserved -; - -WritePaletteToSprite ROUT - Push "R0-R4, R14" - LDR R0, [WsPtr, #SprReadNColour] ; highest palette entry - -; amg 26th October 1993 - this bit of Arthur compatibility bites the -; dust to make screensaving full palette sprites work properly -; AND R0, R0, #63 ; make 63 if 255 like MOS 1.20 - LDR R4, [WsPtr,#ModeFlags] - TST R4, #Flag_FullPalette - ANDEQ R0, R0, #63 - - ADD R4, R2, R0, LSL #3 - ADD R4, R4, #spPalette ; ptr to last pal pos in spPalette -10 - MOV R1, #16 ; read 'normal' colour - SWI XOS_ReadPalette - STMIA R4, {R2,R3} - SUB R4, R4, #8 - SUBS R0, R0, #1 - BCS %BT10 - Pull "R0-R4,PC" - -; ***************************************************************************** -; -; WritePaletteFromSprite - Write palette from information in sprite CB -; -; Internal routine, called by ScreenLoad -; -; in: R2 -> sprite -; -; out: All registers preserved -; - -WritePaletteFromSprite ROUT - Push "R0-R6, R14" - LDR R0, [WsPtr, #ModeNo] - LDR R1, [R2, #spMode] - - [ {TRUE} :LAND: ModeSelectors - - ;logic for this routine - ; - ;[WsPtr, #ModeNo] is the current mode/ptr to mode selector - ;R2 points at sprite data - ;[WsPtr, #SloadModeSel] is 36 bytes for building a mode selector for the sprite - ; - ;sprite mode < 256 ? - ;yes: equal to current mode ? - ; yes: already in correct mode. done. - ; no: change to mode sprite wants, done. - ;no: build a mode selector for the sprite - ; check pixel depth, xres, yres, xdpi and ydpi - ; all identical ? - ; yes: already in suitable mode. done. - ; no: change mode. done. - ;if we do a mode change, remember to re-remove cursors - - ;amg 15 Oct '93 Screensave is about to be changed to use a representative - ;mode number of the eigs and depth (only), so screenload no longer believes - ;the screen mode number in the file. - - ;amg 21 Dec '93 Slight modification - if the screen mode change failed, and - ;we have an old screen mode number, use that as a last gasp - -; CMP R1, #256 -; BCS %FT30 ;branch if a new format sprite mode word - -; CMP R1, R0 ;are we in the right (old style) mode ? -; BEQ %FT10 - -; MOV R0,#ScreenModeReason_SelectMode -; SWI XOS_ScreenMode -; STRVS R0, [WsPtr, #RetnReg0] ;exit on error -; Pull "R0-R6,PC", VS -; B %FT40 ;otherwise get on with it - -30 ; new format sprite mode word - ; build the mode selector at SLoadModeSel - - MOV R5, R1 ;keep the mode number/sprite mode word safe - - ;do the absolutes first - MOV R3, #-1 - STR R3, [WsPtr, #SloadModeSel+ModeSelector_FrameRate] - STR R3, [WsPtr, #SloadModeSel+ModeSelector_ModeVars+16] ;list terminator after two pairs - STR R3, [WsPtr, #SloadModeSel+ModeSelector_ModeVars+32] ;list terminator after four pairs - MOV R3, #128 - STR R3, [WsPtr, #SloadModeSel+ModeSelector_ModeVars+20] ;modeflags value, if needed - MOV R3, #VduExt_NColour - STR R3, [WsPtr, #SloadModeSel+ModeSelector_ModeVars+24] - MOV R3, #255 - STR R3, [WsPtr, #SloadModeSel+ModeSelector_ModeVars+28] - - - MOV R3, #1 - STR R3, [WsPtr, #SloadModeSel+ModeSelector_Flags] - MOV R3, #VduExt_XEigFactor - STR R3, [WsPtr, #SloadModeSel+ModeSelector_ModeVars] ; modevar 1 = xeig - MOV R3, #VduExt_YEigFactor - STR R3, [WsPtr, #SloadModeSel+ModeSelector_ModeVars+8] ; modevar 2 = Yeig - - ;now the things from the sprite -; MOV R3, R1, LSR #27 ;sprite type -; ADRL R4, NSM_bpptable-4 ;readmodevar's table -; LDR R3, [R4, R3, LSL #2] ;word index -; STR R3, [WsPtr, #SloadModeSel+ModeSelector_PixelDepth] - - ;change to calling read mode variable to cope with mode number or sprite mode word - MOV R4, R2 ;save the sprite pointer - MOV R0, R5 ;sprite mode word/mode number - MOV R1, #VduExt_Log2BPP - SWI XOS_ReadModeVariable - STR R2, [WsPtr, #SloadModeSel+ModeSelector_PixelDepth] - MOV R3, R2 - - ;if log2bpp=3, and size of palette data indicates full palette, we need to force - ;a suitable mode - CMP R3, #3 - BNE %FT40 - - ADD LR, R4, #spImage ;point to image/mask start - LDMIA LR,{R2,LR} ;fetch them - CMP R2,LR ;which is bigger ? - MOVGT R2,LR ;use the least - SUB R2,R2,#spPalette ;and the palette size is... - - CMP R2,#&800 ;full entry 256 colour - - ;change the mode selector so it includes a modeflags word - ;(following two words already set up) - - MOVEQ R2, #0 - ;amg 28/4/94 bugfix - following inst wasn't conditional - STREQ R2, [WsPtr, #SloadModeSel+ModeSelector_ModeVars+16] - -40 - MOV R2, R4 ;restore the sprite pointer - - LDR R4, [R2, #spWidth] ;number of words - MOV R4, R4, LSL #5 ;convert to a number of bits - LDR LR, [R2, #spRBit] ;last bit used - ADD LR, LR, #1 ;convert to number of bits - ADD R4, R4, LR ;combine - MOV R4, R4, LSR R3 ;and convert to pixels - STR R4, [WsPtr, #SloadModeSel+ModeSelector_XRes] - - LDR R3, [R2, #spHeight] - ADD R3, R3, #1 - STR R3, [WsPtr, #SloadModeSel+ModeSelector_YRes] - MOV R6, R2 ;save the sprite pointer for later - - ;that leaves the x and y eig factors, which are derived - ;from the dpi - - MOV R0, R5 ;R0 = sprite mode word - MOV R1, #VduExt_XEigFactor - SWI XOS_ReadModeVariable - STRCC R2, [WsPtr, #SloadModeSel+ModeSelector_ModeVars+4] - MOVCC R1, #VduExt_YEigFactor - SWICC XOS_ReadModeVariable - STRCC R2, [WsPtr, #SloadModeSel+ModeSelector_ModeVars+12] - BCS %FT90 ;we canna take it captain.... - - ;do the comparison which involve the mode selectors first - - ;depth - LDR LR, [WsPtr, #ModeNo] - - LDR R3, [LR, #ModeSelector_PixelDepth] - LDR R4, [WsPtr, #SloadModeSel+ModeSelector_PixelDepth] - TEQ R3, R4 - BNE %FT80 ;need to change mode to new mode selr - - LDR R3, [LR, #ModeSelector_XRes] - LDR R4, [WsPtr, #SloadModeSel+ModeSelector_XRes] - TEQ R3, R4 - BNE %FT80 ;need to change mode to new mode selr - - LDR R3, [LR, #ModeSelector_YRes] - LDR R4, [WsPtr, #SloadModeSel+ModeSelector_YRes] - TEQ R3, R4 - BNE %FT80 ;need to change mode to new mode selr - - ;now the eigs - LDR R3, [WsPtr, #XEigFactor] - LDR R4, [WsPtr, #SloadModeSel+ModeSelector_Flags+4] - TEQ R3, R4 - BNE %FT80 ;need to change mode to new mode selr - - LDR R3, [WsPtr, #YEigFactor] - LDR R4, [WsPtr, #SloadModeSel+ModeSelector_Flags+12] - TEQ R3, R4 - - BEQ %FT10 ;this mode is suitable - -80 - MOV R0,#ScreenModeReason_SelectMode - ADD R1,WsPtr,#SloadModeSel - SWI XOS_ScreenMode - - - [ {TRUE} - ;ensure we preserve the error pointer in situations where we can't try to - ;fall back to the mode number in the sprite header - - ;if it errored try again if there's a mode number available - BVC %FT40 - - LDR R1, [R6, #spMode] - BICS R14, R1, #&FF ; EQ if sprite mode is a number (< 256), (V still set afterwards) - MOVEQ R0, #ScreenModeReason_SelectMode - SWIEQ XOS_ScreenMode ; if called, will set V appropriately - | - ;if it errored try again if there's a mode number available - BVC %FT40 - - MOV R0, #ScreenModeReason_SelectMode - LDR R1, [R6, #spMode] - BICS R14, R1, #&FF ; EQ if sprite mode is a number (< 256), (V still set afterwards) - SWIEQ XOS_ScreenMode ; if called, will set V appropriately - ] - - STRVS R0, [WsPtr, #RetnReg0] ;exit on error - Pull "R0-R6,PC", VS - B %FT40 ;otherwise get on with it -90 - ADRL R0,SpriteErr_InvalidSpriteMode - [ International - BL TranslateError - ] - STR R0, [WsPtr, #RetnReg0] - SETV - Pull "R0-R6,PC" - | - - ;as originally done this code tended to compare mode specifiers against new - ;sprite mode words, and worse still tried to select a mode from a new sprite - ;mode word. the rewrite above takes a more logical approach - - CMP R0, R1 ; if already in correct mode - BEQ %FT10 ; then skip - - [ ModeSelectors - MOV r0, #ScreenModeReason_SelectMode - SWI XOS_ScreenMode - | - MOV R0, #22 - SWI XOS_WriteC - MOVVC R0, R1 - SWIVC XOS_WriteC - ] - STRVS R0, [WsPtr, #RetnReg0] - Pull "R0-R6,PC", VS - ] -40 - SWI XOS_RemoveCursors ; remove cursors again -10 - MOV R2, R6 - LDR R3, [R2, #spImage] - CMP R3, #spPalette ; will clear V if EQ - Pull "R0-R6, PC", EQ ; no palette data - - LDR R4, [WsPtr, #NColour] - - ADD R3, R2, #spPalette - ADD R3, R3, R4, LSL #3 -20 - LDMIA R3, {R1,R2} - MOV R0, R4 - - BL SendPalettePair - Pull "R0-R6, PC", VS - - SUB R3, R3, #8 - SUBS R4, R4, #1 ; (V will be cleared by this) - BCS %BT20 - Pull "R0-R6, PC" - -; ***************************************************************************** -; -; SendPalettePair - Program palette with flash pair -; -; Internal routine, called by WritePaletteFromSprite -; -; in: R0 = logical colour -; R1 = first flash colour -; R2 = second flash colour -; -; out: R1 corrupted -; - -SendPalettePair ROUT - Push "R0-R3, R14" - TEQ R1, R2 ; are colours the same ? - BNE %FT10 ; if not then do in two halves - - MOV R3, #16 - BL SendPaletteEntry ; then send with 16 - Pull "R0-R3, PC" -10 - MOV R3, #17 ; else send 1st flash with 17 - BL SendPaletteEntry - MOVVC R1, R2 - MOVVC R3, #18 ; then 2nd flash with 18 - BLVC SendPaletteEntry - Pull "R0-R3, PC" - -; ***************************************************************************** -; -; SendPaletteEntry - Program one palette entry -; -; Internal routine, called by SendPalettePair -; -; in: R0 = logical colour -; R1 = physical colour BGRx -; R3 = PP field to use -; -; out: All registers preserved -; - -SendPaletteEntry ROUT - Push "R0,R1, R14" - BIC R1, R1, #&7F ; clear all bits except sup. bit - ORR R1, R1, R3 ; or in new bits - MOV R0, R0, LSL #24 ; move log. col. up to top 8 bits - Push "R0, R1" ; create an OSWORD block at R13+3 - - MOV R0, #12 - ADD R1, R13, #3 ; R1 -> block - SWI XOS_Word - STRVS R0, [WsPtr, #RetnReg0] - ADD R13, R13, #8 - Pull "R0,R1, PC" - - END diff --git a/s/vdu/vdugrafk b/s/vdu/vdugrafk deleted file mode 100644 index fd333b01..00000000 --- a/s/vdu/vdugrafk +++ /dev/null @@ -1,458 +0,0 @@ -; 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.VduGrafK -; -; ARTHUR OPERATING SYSTEM - Vdu Drivers -; ======================= -; -; Vdu driver code - Sprite stuff -; -; Author R C Manby -; Date 5.3.87 -; - -; ***************************************************************************** -; -; ScreenSave - Save screen within graphics window as a sprite file -; -; External routine -; -; in: R2 -> file name -; R3 = 0/1 => exclude/include palette data -; - -ScreenSave ROUT - Push R14 - SWI XOS_RemoveCursors - - [ {TRUE} - GraphicsMode R0 - BNE %FT20 - | - LDR R0, [WsPtr, #NPix] - CMP R0, #0 - BEQ %FT20 ; quit with error if not graphics mode - ] - - ; build a temporary sprite area header - ADD R1, WsPtr, #ScrSavAreaCB - MOV R4, #&7FFFFFFF ; size, very large - MOV R5, #1 ; one sprite - LDR R6, =(ScrSavSpriteCB-ScrSavAreaCB) ;saFirst - MOV R7, R6 ; saFree=saFirst - STMIA R1, {R4-R7} - - ADD R11, WsPtr, #GWLCol ; R4 ,R5 ,R6 ,R7 - LDMIA R11, {R4,R5,R6,R7} ; wL ,wB ,wR ,wT - - LDR R0, [WsPtr, #ModeNo] - STR R0, [WsPtr, #SGetMode] ; needs setting up before CreateHeader - - Push R2 ; preserve file name pointer - - ; if it is a mode selector mode with >256 colours force it to have no - ; palette. CreateHeader will deal with <=256. - LDR R2, [WsPtr, #Log2BPP] - CMP R2, #4 - MOVCS R3, #0 - - ; amg 25th May 1994. The above is no longer completely true. We still - ; don't allow palettes on 16/32bpp. Below that (whether new or old - ; format of sprite) palettes are now allowed. No actual code change - ; here, but CreateHeader has been changed. - - ADR R2, ScrSavSpriteName - ; R3 ,R4,R5,R6,R7 - BL CreateHeader ; In : Palette,sl,sb,sr,st - ADDVS sp, sp, #4 ; (if error, junk stacked filename ptr and exit) - BVS %FT35 - ; Out: ImageSize - ; now add the sprite to the sprite area - LDR R3, [R2, #spNext] ; total size of new sprite - LDMIA R1, {R4,R5,R6,R7} ; saEnd,saNumber,saFirst,saFree - ADD R7, R7, R3 ; new saFree - MOV R4, R7 - STMIA R1, {R4,R5,R6,R7} - -; Create file to prevent "Can't extend" - - [ AssemblingArthur :LOR: Module - MOV R0, #OSFile_CreateStamp - LDR R1, [R13, #0] ; R1 -> filename - LDR R2, =&FF9 ; Type=SpriteFile - MOV R3, #0 ; Junk - MOV R4, #0 - SUB R5, R7, #4 ; File size (ie exclude saEnd) - SWI XOS_File - | - CLRV - ] - Pull R1 - BVS %FT30 - -; OpenUp file and save the Sprite area and sprite headers - - [ AssemblingArthur :LOR: Module - MOV R0, #open_update :OR: open_mustopen :OR: open_nodir - | - MOV R0, #open_write - ] - SWI XOS_Find - BVS %FT30 - - MOV R1, R0 - MOV R0, #2 ; write bytes to file - - LDR R2, =(ScrSavAreaCB+saNumber) - ADD R2, R2, WsPtr - LDR R3, =(ScrSavSpriteCB+spImage) - LDR R3, [WsPtr, R3] - ADD R3, R3, #(SpriteAreaCBsize-saNumber) - - MOV R4, #0 - SWI XOS_GBPB - BVS %FT40 ; FileSwitchGotYa ! - - Push R1 - LDR R0, [WsPtr, #GWLCol] - LDR R1, [WsPtr, #GWTRow] - BL ScreenAddr ; R2 = ScrAdr of TopL of area - Pull R1 - - LDR R5, [WsPtr, #SGetWidth] - ADD R5, R5, #1 - MOV R5, R5, LSL #2 ; width (bytes) - LDR R6, [WsPtr, #SGetHeight] ; height-1 - - LDR R7, [WsPtr, #LineLength] - SUBS R7, R7, R5 ; zero then can do as one lump - MLAEQ R5, R6, R5, R5 ; R5 = R5*(R6+1) - MOVEQ R6, #0 ; only one chunk to do - -; -; R0 ,R1 ,R2 ,R3 ,R4 ,R5 ,R6 ,R7 -; ,Handle,ScrAdr,Size , ,Width,RowCnt,RowOfSt - -10 - MOV R0, #2 - MOV R3, R5 - SWI XOS_GBPB - BVS %FT40 ; something went wrong - - ADD R2, R2, R7 ; step to next screen line - SUBS R6, R6, #1 - BGE %BT10 - - MOV R0, #0 ; close file - SWI XOS_Find - BVS %FT30 - SWI XOS_RestoreCursors - Pull R14 - RETURNVC ; no error, return VC - -20 - ADRL R0, SpriteErr_NotGraphics - [ International - BL TranslateError - | - SETV - ] - B %FT30 - -40 ; return point after an error - STR R0, [WsPtr, #RetnReg0] ; R0 ptr to message, R1 file handle - MOV R0, #0 ; close file - SWI XOS_Find -30 ; return point after an error - STRVS R0, [WsPtr, #RetnReg0] ; R0 ptr to message -35 - SWI XOS_RestoreCursors - Pull R14 - RETURNVS - -ScrSavSpriteName - = "screendump", 0 - ALIGN - - LTORG - -; ***************************************************************************** -; -; ScreenLoad - Plot sprite file directly into graphics window -; -; External routine -; -; in: R2 -> file name -; - -ScreenLoad ROUT - Push R14 - SWI XOS_RemoveCursors - - MOV R0, #open_read+open_mustopen+open_nodir - MOV R1, R2 - SWI XOS_Find - BVS %FT80 - - STR R0, [WsPtr, #ScrLoaHandle] - MOV R1, R0 - MOV R0, #4 ; read areaCB from file - ADD R2, WsPtr, #ScrLoaAreaCB+saNumber - MOV R3, #(SpriteAreaCBsize-saNumber) - MOV R4, #0 - SWI XOS_GBPB - BVS %FT70 ; FileSwitchGotYa ! - - MOV R0, #3 ; read spriteCB from file - ADD R2, WsPtr, #ScrLoaSpriteCB - MOV R3, #SpriteCBsize - ADD R3, R3, #MaxSpritePaletteSize - LDR R4, [WsPtr, #(ScrLoaAreaCB+saFirst)] - SUB R4, R4, #4 - SWI XOS_GBPB - BVS %FT70 - - ADD R2, WsPtr, #ScrLoaSpriteCB - BL WritePaletteFromSprite ; mode change (if needed) - ;branch to 75 rather than 70 because RetnRegR0 is already set up - BVS %FT75 ; and palette setting - - [ {TRUE} - GraphicsMode R0 - BNE %FT60 - | - LDR R0, [WsPtr, #NPix] - CMP R0, #0 - BEQ %FT60 ; quit with error if not graphics mode - ] - -; now check for being able to do it all at once - - ADD R0, WsPtr, #GWLCol ; R3=GWLCol; R4=GWBRow - LDMIA R0, {R3-R6} ; R5=GWRCol; R6=GWTRow - - ADD R0, WsPtr, #ScrLoaSpriteCB - ADD R0, R0, #spWidth ; R7=width-1; R8=height-1 - LDMIA R0, {R7-R10} ; R9=LBit; R10=RBit - - SUB R5, R5, R3 ; R5 = window width - LDR R0, [WsPtr, #XWindLimit] - TEQ R0, R5 ; if window width=full screen - TEQEQ R9, #0 ; and LBit=0 - TEQEQ R10, #31 ; and RBit=31 - BNE %FT05 - - ADD R5, R5, #1 ; R5 = screen width in pixels - ADD R7, R7, #1 ; R7 = sprite width in words - LDR R0, [WsPtr, #NPix] - MLA R0, R7, R0, R7 ; R0 = width*(npix+1) - TEQ R0, R5 ; and spritewidth=full screen - BNE %FT05 - - [ {TRUE} - LDR R14, [WsPtr, #Log2BPC] - MOV R1, R5, LSL R14 ; bit size of 1 row of pixels - MOV R1, R1, LSR #3 ; byte size of 1 row of pixels - LDR R14, [WsPtr, #LineLength] ; LineLength (in bytes) - TEQ R1, R14 ; if they differ (eg interlaced mode) - BNE %FT05 ; then we can't optimise - ] - -; we know we can do it all in one chunk -; work out screen address and sprite offset - - LDR R1, [WsPtr, #CursorFlags] ; if computing clip box - TST R1, #ClipBoxEnableBit - Push "R0-R4", NE - BLNE SetClipBoxToFullScreen ; then set to full screen - Pull "R0-R4", NE ; above routine preserves PSR - - MOV R7, R7, LSL #2 ; R7 = line width in bytes - ADD R1, R8, R4 ; R1 = height-1 + GWBRow = YT - SUBS R9, R1, R6 ; if YT > GWTRow then - ; start at row (YT-GWTRow) - MOVHI R1, R6 ; and YT=GWTRow, else - MOVLS R9, #0 ; start at row 0 (and YT=YT) - - LDR R0, [WsPtr, #ScrLoaAreaCB+saFirst] - ADD R2, WsPtr, #ScrLoaSpriteCB - LDR R2, [R2, #spImage] - ADD R0, R0, R2 - SUB R0, R0, #4 ; R0=offset into file of image - MLA R4, R7, R9, R0 ; add on vertical wastage*width - - SUB R9, R8, R9 ; R9 = height-1-wastage - MLA R9, R7, R9, R7 ; number of bytes to transfer - - MOV R0, #0 - BL ScreenAddr ; R2 := screen address - MOV R3, R9 - - LDR R1, [WsPtr, #ScrLoaHandle] - MOV R0, #3 ; read from this position - SWI XOS_GBPB - BVS %FT70 ; if error - B %FT52 ; no error - -; can't do it all at once; R3 = GWLCol, R4 = GWBRow - -05 - ADD R2, WsPtr, #ScrLoaSpriteCB ; point at the spriteCB - MOV R5, #0 - BL GenSpritePlotParmBlk ; "plotting" at (GWLCol,GWBRow) - BVS %FT55 ; off screen (not an error) - - ADD R2, WsPtr, #ScrLoaSpriteCB - LDR R4, [WsPtr, #SPltMemAdr] ; convert MemAdr into - LDR R5, [WsPtr, #ScrLoaAreaCB+saFirst] - SUB R4, R4, #4 - SUB R4, R4, R2 - ADD R4, R4, R5 - STR R4, [WsPtr, #ScrLoaFilPtr] ; file ptr - - LDR R4, [R2, #spWidth] ; convert spWidth into - ADD R4, R4, #1 - MOV R4, R4, LSL #2 - STR R4, [WsPtr, #ScrLoaFilOfst] ; file ptr offset - - LDR R4, [WsPtr, #SPltColCnt] - ADD R4, R4, #2 - MOV R4, R4, LSL #2 - STR R4, [WsPtr, #ScrLoaBytes] - - ADD R4, WsPtr, #ScrLoaBuffer - STR R4, [WsPtr, #SPltMemAdr] - STR R4, [WsPtr, #ScrLoaBufAdr] - -10 ; read row from file - ADD R1, WsPtr, #ScrLoaHandle - LDMIA R1, {R1,R2,R3,R4} ; Handle,BufAdr,Bytes,FilPtr - MOV R0, #3 - SWI XOS_GBPB - BVS %FT70 - - ADD R0, WsPtr, #SPltScrAdr - LDMIA R0, {R0-R1,R5-R7} ; R0 ,R1 , R5 ,R6 ,R7 - ; ScrAdr,ColCnt, BufAdr,ShftR,ShftL - - LDMIA R5, {R2,R3} ; plot the first (leftmost) word - ADD R5, R5, #4 - - ShiftR R2,R3, R6,R7 ; shift R3,R2 right R6 places - ; we only need result word R2 - - LDR R3, [WsPtr, #SPltLMask] ; on leftmost word, mask down - AND R2, R2, R3 ; to just the required pixels - - LDR R4, [R0] ; plot 1 word - BIC R4, R4, R3 - ORR R4, R4, R2 - STR R4, [R0], #4 - - SUBS R1, R1, #1 - BLT %FT50 ; if all plotted, try next scanline - ; else try for blocks of 4 - SUBS R1, R1, #4 - BLT %FT30 - -20 - ;R0 ,R1 ,R5 ,R6 ,R7 - ;ScrAdr,ColCnt, ,BufAdr,ShftR,ShftL - - LDMIA R5, {R2,R3,R8-R10} ; 5 words needed, gives 4 after shift - ADD R5, R5, #16 ; advance source ptr 4 words - - ShiftR R2,R3, R6,R7 ; shift R4-R0 right R6 bits - ShiftR R3,R8, R6,R7 ; we only want result words R3-R0 - ShiftR R8,R9, R6,R7 - ShiftR R9,R10,R6,R7 - - STMIA R0!, {R2,R3,R8-R9} ; write 4 words back to screen - SUBS R1, R1, #4 - BGE %BT20 - -30 ; try 1 word at a time - ADDS R1, R1, #4 - -;R0 ,R1 , R5 ,R6 ,R7 -;ScrAdr,ColCnt, BufAdr,ShftR,ShftL -; -; If EQ this is rightmost word - - BEQ %FT45 -40 - LDMIA R5, {R2,R3} - ADD R5, R5, #4 - - ShiftR R2,R3, R6,R7 ; shift R3,R2 right R6 places - ; we only need result word R2 - STR R2, [R0], #4 - SUBS R1, R1, #1 - BGT %BT40 - -45 - LDMIA R5, {R2,R3} - ADD R5, R5, #4 - - ShiftR R2,R3, R6,R7 ; shift R3,R2 right R6 places - ; we only need result word R2 - - LDR R3, [WsPtr, #SPltRMask] ; rightmost word, so mask down to - AND R2, R2, R3 ; just the required pixels - - LDR R4, [R0] - BIC R4, R4, R3 - ORR R4, R4, R2 - STR R4, [R0], #4 - -50 ; now try the next scanline - ADD R11, WsPtr, #SPltWidth - LDMIA R11, {R1,R2,R3,R4} ; Width,Height,ScrOff,MemOff - ADD R5, R0, R3 - SUBS R2, R2, #1 - STMIA R11, {R1,R2,R3,R4,R5} ; Width,Height,ScrOff,MemOff,ScrAdr - - ADD R11, WsPtr, #ScrLoaHandle ; R1 ,R2 ,R3 ,R4 ,R5 - LDMIA R11, {R1,R2,R3,R4,R5} ; Handle,BufAdr,Bytes,FilPtr,FilOfst - ADD R4, R4, R5 - STR R4, [WsPtr, #ScrLoaFilPtr] - BGE %BT10 ; plot next scanline -52 - MOV R0, #0 ; close file - SWI XOS_Find - BVS %FT80 -55 - SWI XOS_RestoreCursors - Pull R14 - RETURNVC - -60 - ADRL R0,SpriteErr_NotGraphics - [ International - BL TranslateError - ] -70 ; return point after an error - STR R0, [WsPtr, #RetnReg0] ; R0 ptr to message, R1 file handle -75 - MOV R0, #0 ; close file - SWI XOS_Find -80 ; error, file not open - STRVS R0, [WsPtr, #RetnReg0] - SWI XOS_RestoreCursors - Pull R14 - RETURNVS - - - END diff --git a/s/vdu/vdugrafl b/s/vdu/vdugrafl deleted file mode 100644 index 4c74b284..00000000 --- a/s/vdu/vdugrafl +++ /dev/null @@ -1,700 +0,0 @@ -; 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.VduGrafL -; -; ARTHUR OPERATING SYSTEM - Vdu Drivers -; ======================= -; -; Vdu driver code - Sprite stuff -; -; Author T M Dobson -; Date 22-Sep-87 -; - -; ***************************************************************************** -; -; ReadSaveAreaSize - Read size of a VDU context save area -; -; in: R0 = SpriteReason_ReadSaveAreaSize -; R1 -> sprite area -; R2 -> sprite (0 => screen (possibly)) -; -; out: R3 = size of an area suitable for this sprite -; - -ReadSaveAreaSize ROUT - MOV R3, #MainSize ; I was kidding about it depending - STR R3, [WsPtr, #RetnReg3] ; on the sprite! - MOV PC, R14 - -; ***************************************************************************** -; -; SwitchOutputToSprite - Make VDU(graphics) output go to a sprite -; -; External routine -; -; in: R0 = SpriteReason_SwitchOutputTo <Sprite or Mask> -; R1 -> sprite area -; R2 -> sprite (0 => screen) -; R3 -> save area for VDU variables relating to sprite -; 0 => no save area, initialise variables from mode number of sprite -; or display mode number -; 1 => use MOS's save area -; -; First word of save area = 0 => uninitialised save area -; "VOTS" => initialised save area -; else error -; - -; From Medusa onwards, things are further complicated here by the fact that -; the sprite may have a new sprite mode word rather than a mode number. When -; the former case occurs calling pushmodeinfoanymonitor doesn't really help -; very much. Instead, when a sprite mode word is given, it will derive or -; fudge all the variables that it is really interested from the sprite mode -; word directly. - -SwitchOutputToSprite ROUT -SwitchOutputToMask ROUT - CMP R3, #1 ; check for values 0 and 1 - MOVCC R4, #0 ; R3=0 => no save area, so not inited - - ADDEQ R5, WsPtr, #VduSaveArea ; R3=1 => MOS's area - MOVHI R5, R3 ; else user area - LDRCS R4, [R5, #InitFlag] ; if is an area, load R4 with init flag - LDR R5, VOTS ; compare with initialised identifier - TEQ R4, R5 ; if not initialised - TEQNE R4, #0 ; and not uninitialised - BNE InvalidSaveArea - -; no more errors can be generated, so update returned registers - - ADD R5, WsPtr, #VduOutputCurrentState - LDMIA R5, {R6-R9} - ADD R5, WsPtr, #RetnReg0 - STMIA R5, {R6-R9} - - Push "R0-R4,R14" - - ASSERT SpriteMaskSelect = VduOutputCurrentState +0 - ASSERT VduSpriteArea = VduOutputCurrentState + 4 - ASSERT VduSprite = VduOutputCurrentState + 8 - - ORR R0, R0, #RangeC ; make R0 into &2nn - - ADD R5, WsPtr, #VduOutputCurrentState - STMIA R5, {R0-R2} - - BL PreWrchCursor ; remove cursor - BL PackVars ; save away current vars into save area - ; (if any) - Pull "R0-R4" - STR R3, [WsPtr, #VduSaveAreaPtr] ; save new save area ptr - - TEQ R2, #0 ; if switching to screen - LDREQ R9, [WsPtr, #DisplayScreenStart] ; then load up new ScreenStart - LDREQ R11, [WsPtr, #DisplayModeNo] ; and mode number - BEQ %FT20 ; and skip sprite stuff - -; do stuff for switching to sprite - - Push R0 - BL RemoveLeftHandWastage ; then remove LH wastage from sprite - Pull R0 ; (spLBit := 0) - - ASSERT spHeight = spWidth +4 - ASSERT spLBit = spWidth +8 - ASSERT spRBit = spWidth +12 - ASSERT spImage = spWidth +16 - ASSERT spTrans = spWidth +20 - ASSERT spMode = spWidth +24 - - ADD R5, R2, #spWidth ; R5=width:R6=height:R7=LBit(=0) - LDMIA R5, {R5-R11} ; R8=RBit:R9=Image:R10=Trans:R11=Mode - - TEQ R0, #SpriteReason_SwitchOutputToMask - BNE %FT23 - - MOV R9, R10 ; point at mask instead of image - MOVS R0, R11, LSR #27 - BEQ %FT23 ; check for old format masks - - BL GetMaskspWidth ; adjust R5 and R8 to mask dimensions - BIC R11, R11, #&F8000000 - ORR R11, R11, #&08000000 ; force it to a type 1 (1bpp) sprite -23 - ADD R9, R9, R2 ; R9 -> sprite data or mask -20 - STR R9, [WsPtr, #ScreenStart] - STR R11, [WsPtr, #ModeNo] ; new mode number - - MOV R10, R11 - BL PushModeInfoAnyMonitor - MOV R11, R13 - - TEQ R2, #0 ; if outputting to screen - LDREQ R5, [R11, #wkLineLength] ; then load up values - LDREQ R6, [R11, #wkYWindLimit] ; from mode table - LDREQ R7, [R11, #wkXWindLimit] - LDREQ R8, [R11, #wkScrRCol] - LDREQ R10, [R11, #wkScrBRow] - BEQ %FT30 ; and skip more sprite stuff - - ADD R5, R5, #1 - MOV R5, R5, LSL #2 ; R5 = width in bytes - - ADD R7, R8, R5, LSL #3 ; R7 = LineLength*8 + spRBit - SUB R7, R7, #31 ; R7=active area width in bits - - LDR R8, [R11, #wkLog2BPC] - MOV R7, R7, LSR R8 ; R7 = width in pixels - MOV R8, R7, LSR #3 ; R8 = width in text columns - SUB R7, R7, #1 ; R7 = max value of GWRCol - - SUB R8, R8, #1 ; R8 = max column number - - ADD R10, R6, #1 ; R10 = no. of pixel rows - MOV R10, R10, LSR #3 ; R10 = number of char rows - SUB R10, R10, #1 ; R4 = maximum row number - -30 - STR R5, [WsPtr, #LineLength] - STR R6, [WsPtr, #YWindLimit] - STR R7, [WsPtr, #XWindLimit] - STR R8, [WsPtr, #ScrRCol] - STR R10, [WsPtr, #ScrBRow] - - LDR R0,[R11, #wkNColour] - STR R0,[WsPtr, #NColour] ; copy number of colours -1 - - ADD R11, R11, #wkmiddle - MOV R0, #wkmidend-wkmiddle ; number of bytes to do - ADD R1, WsPtr, #YShftFactor ; first mode variable that we do - -40 - LDR R5, [R11], #4 ; copy byte from mode table - STR R5, [R1], #4 ; into word variable - SUBS R0, R0, #4 ; decrement count - BNE %BT40 ; loop until finished - - ADD R13, R13, #PushedInfoSize ; junked stacked info - -; now create other variables from simple ones - - LDR R0, [WsPtr, #Log2BPP] - LDR R1, [WsPtr, #Log2BPC] - LDR R5, [WsPtr, #XEigFactor] - LDR R6, [WsPtr, #ModeFlags] - TEQ R2, #0 - ORRNE R6, R6, #Flag_HardScrollDisabled ; if sprite then disable hard - STR R6, [WsPtr, #ModeFlags] - - ;if switching to a sprite, check for full palette 8bpp, and set modeflags and - ;NColour to suit. - - TEQ R2, #0 - BEQ %FT65 ; switching to a sprite ? - - CMP R0, #3 - BNE %FT65 ; which is 8bpp ? - - ADD R7, R2, #spImage ; point R7 at the image/mask start pair - LDMIA R7, {R7, LR} ; fetch them - CMP R7, LR ; which is lower - MOVGT R7, LR ; use the lowest - SUB R7, R7, #spPalette ; get the size of the palette - CMP R7, #&800 ; full 8bpp palette ? - BNE %FT65 - - ORR R6, R6, #Flag_FullPalette - STR R6, [WsPtr, #ModeFlags] ; set the full palette flag - - MOV R7, #255 - STR R7, [WsPtr, #NColour] ; and set the number of colours - -65 - TST R6, #Flag_DoubleVertical - ADREQL R7, WrchNbitTab ; point to correct table - ADRNEL R7, WrchNbitDoubleTab - LDR R8, [R7, R1, LSL #2] ; get offset to correct code - ADD R8, R8, R7 ; convert to absolute address - STR R8, [WsPtr, #WrchNbit] - - ADRL R7, CursorNbitTab - LDR R8, [R7, R1, LSL #2] - ADD R8, R8, R7 - TST R6, #Flag_Teletext - ADRNEL R8, CursorTeletext - STR R8, [WsPtr, #CursorNbit] - - TST R6, #Flag_NonGraphic - MOVEQ R7, #32 ; if graphic mode - MOVEQ R7, R7, LSR R1 ; then = (32 >> lbpc)-1 - SUBEQ R7, R7, #1 - MOVNE R7, #0 ; else = 0 ;;; NOT REALLY SAFE BET ANYMORE!!! - STR R7, [WsPtr, #NPix] - - RSB R7, R1, #5 ; XShftFactor = 5-log2bpc - STR R7, [WsPtr, #XShftFactor] - - LDR R7, [WsPtr, #YEigFactor] - SUBS R7, R5, R7 ; XEigFactor-YEigFactor - MOVLT R7, #2 ; X<Y => 2 (vert rect) - MOVGT R7, #1 ; X>Y => 1 (horz rect) - ; else X=Y => 0 (square) - STR R7, [WsPtr, #AspectRatio] - - MOV R8, #1 - MOV R7, R8, LSL R0 ; bpp = 1 << lbpp - STR R7, [WsPtr, #BitsPerPix] - - MOV R7, R8, LSL R1 ; bpc = 1 << lbpc - STR R7, [WsPtr, #BytesPerChar] - - [ HiResTTX - TST R6, #Flag_Teletext ; in teletext mode - MOVNE R7, R7, LSL #1 ; characters are 16 pixels - STR R7, [WsPtr, #CharWidth] - ] - - TST R6, #Flag_BBCGapMode ; is it a BBC gap mode ? - MOVNE R7, #&55 ; yes, then use colour 1 - BNE %FT70 - TEQ R0, #2 ; if (1<<2=4) bits per pixel - MOVEQ R7, #&77 ; then use colour 7 for cursor - MOVNE R7, #&FF ; else use colour 15 - [ TTX256 - TST R6, #Flag_Teletext ; unless it's teletext - MOVNE R7, #&07 ; in which case still use colour 7 - ] -70 - ORR R7, R7, R7, LSL #8 ; fill out to whole word - ORR R7, R7, R7, LSL #16 - STR R7, [WsPtr, #CursorFill] - - TST R6, #Flag_DoubleVertical - MOVEQ R7, #8 ; if single vertical then 8 pixels - MOVNE R7, #16 ; if double vertical then 16 pixels - STR R7, [WsPtr, #TCharSizeY] - TST R6, #Flag_GapMode - ADDNE R7, R7, R7, LSR #2 ; make 10 or 20 if gap mode - STR R7, [WsPtr, #RowMult] - STR R7, [WsPtr, #TCharSpaceY] - MOV R8, #8 - [ HiResTTX - TST R6, #Flag_Teletext - MOVNE R8, #16 - ] - STR R8, [WsPtr, #TCharSizeX] - STR R8, [WsPtr, #TCharSpaceX] - - LDR R8, [WsPtr, #LineLength] - MUL R7, R8, R7 - STR R7, [WsPtr, #RowLength] - -; finished doing other variables - - SWI XColourTrans_InvalidateCache ; let ColourTrans know we've changed mode - ; so that colours get set up correctly - - TEQ R4, #0 ; initialising from a save area ? - BEQ %FT80 ; no, then set to defaults - - BL UnpackVars - BL AddressCursors - BL ValidateVars - BL PlainBit - BL SetColour - LDR R6, [WsPtr, #CursorFlags] - ORR R6, R6, #TEUpdate ; TextExpand needs updating - STR R6, [WsPtr, #CursorFlags] - B %FT90 -80 - -; *****Change made by DJS -; Original code was: -; MOV R0, #0 -; STR R0, [WsPtr, #ECFShift] -; STR R0, [WsPtr, #ECFYOffset] -; This needed to be changed to make the bottom left of the screen (rather -; than the top left) be the default ECF origin. - LDR R0, [WsPtr, #YWindLimit] - ADD R0, R0, #1 - AND R0, R0, #7 - STR R0, [WsPtr, #ECFYOffset] - MOV R0, #0 - STR R0, [WsPtr, #ECFShift] -; *****End of change made by DJS - - STR R0, [WsPtr, #ClipBoxEnable] - STRB R0, [R0, #OsbyteVars + :INDEX: VDUqueueItems] - - MOV R0, #8 - STR R0, [WsPtr, #GCharSizeX] ; chars are 8x8 by default - STR R0, [WsPtr, #GCharSizeY] - STR R0, [WsPtr, #GCharSpaceX] ; and with 8x8 spacing - STR R0, [WsPtr, #GCharSpaceY] - - LDR R1, [WsPtr, #ModeFlags] - - LDR R0, [WsPtr, #CursorFlags] - BIC R0, R0, #(ActualState :OR: Vdu5Bit) - BIC R0, R0, #(CursorsSplit :OR: PageMode :OR: TeletextMode :OR: ClipBoxEnableBit) - TST R1, #Flag_Teletext ; is it teletext ? - ORRNE R0, R0, #TeletextMode ; yes, then set bit - STR R0, [WsPtr, #CursorFlags] - BLNE TeletextInit ; initialise TTX if appropriate - - BL InitCursor ; initialise cursor after - ; cursorflags - BL PlainBit ; also sets up RAMMaskTb - BL DefaultColours ; N.B. SetColour is called by both - BL DefaultEcfPattern ; of these. - BL DefaultLineStyle - BL DefaultWindows - BL Home -90 - [ STB ; Change made by TMD 29-May-96, to stop cursor flashing before interlace module has - ; fixed up LineLength on Service_SwitchingOutputToSprite - MOV R1, #Service_SwitchingOutputToSprite ; issue the service *first* - ADD R2, WsPtr, #VduOutputCurrentState - LDMIA R2, {R2-R5} ; load the registers that were in R0-R3 on entry - IssueService - BL PostWrchCursor ; it should now be safe to restore the cursor - | - BL PostWrchCursor - - MOV R1, #Service_SwitchingOutputToSprite ; call Ran's service - ADD R2, WsPtr, #VduOutputCurrentState - LDMIA R2, {R2-R5} ; load the registers that were in R0-R3 on entry - IssueService - ] - - Pull R14 - RETURNVC - -InvalidSaveArea - ADRL R0, SpriteErr_InvalidSaveArea - [ International - Push "lr" - BL TranslateError - Pull "lr" - ] - STR R0, [WsPtr, #RetnReg0] - RETURNVS - -VOTS = "VOTS" - - -; ***************************************************************************** - -; Specially saved items - - ^ 0 -InitFlag # 4 ; 0 => uninit, "VOTS" => init -SavedSpoolFileH # 1 ; an OSBYTE variable -SavedWrchDest # 1 ; --------""-------- -SavedVDUqueueItems # 1 ; --------""-------- - # 1 ; padding to word align it -SavedDataOffset # 0 ; start of compressed data - - GBLA FirstOffset - GBLA NextOffset - GBLA CompressedSize - - MACRO - CompStart -FirstOffset SETA -1 -NextOffset SETA -1 -CompressedSize SETA 0 - MEND - - MACRO - Compress $v0, $v1, $v2, $v3, $v4, $v5, $v6, $v7 - [ "$v0"<>"" - Compo $v0 - ] - [ "$v1"<>"" - Compo $v1 - ] - [ "$v2"<>"" - Compo $v2 - ] - [ "$v3"<>"" - Compo $v3 - ] - [ "$v4"<>"" - Compo $v4 - ] - [ "$v5"<>"" - Compo $v5 - ] - [ "$v6"<>"" - Compo $v6 - ] - [ "$v7"<>"" - Compo $v7 - ] - MEND - - MACRO - Compo $var - [ FirstOffset <> -1 - [ $var = NextOffset -NextOffset SETA ($var)+4 - | - DCW FirstOffset - DCW NextOffset -CompressedSize SETA CompressedSize + (NextOffset-FirstOffset) -FirstOffset SETA $var -NextOffset SETA ($var)+4 - ] - | -FirstOffset SETA $var -NextOffset SETA ($var)+4 - ] - MEND - - MACRO - CompMult $start, $size - [ FirstOffset <> -1 - [ $start = NextOffset -NextOffset SETA $start + $size - | - DCW FirstOffset - DCW NextOffset -CompressedSize SETA CompressedSize + (NextOffset-FirstOffset) -FirstOffset SETA $start -NextOffset SETA $start + $size - ] - | -FirstOffset SETA $start -NextOffset SETA $start + $size - ] - MEND - - MACRO - CompRange $start, $end - CompMult $start, ($end+4-$start) - MEND - - MACRO - CompEnd - [ FirstOffset <> -1 - DCW FirstOffset - DCW NextOffset -CompressedSize SETA CompressedSize + (NextOffset-FirstOffset) - ] - & -1 - MEND - -CompressionTable - CompStart - -; CompMult FgEcf, 8*4 ; recreated from GCOLs + ecfs by -; CompMult BgEcf, 8*4 ; call to SetColour - - Compress GPLFMD, GPLBMD, GFCOL, GBCOL, GWLCol, GWBRow, GWRCol, GWTRow - CompRange qqqPad, JVec - -; Compress ScreenStart ; worked out from sprite address each time - - Compress TWLCol, TWBRow, TWRCol, TWTRow - CompRange OrgX, NewPtY - Compress TForeCol, TBackCol, CursorX, CursorY - -; Compress CursorAddr, InputCursorAddr - computed from (Input)CursorX,Y - - Compress InputCursorX, InputCursorY - - Compress VduStatus - Compress CursorDesiredState, CursorStartOffset, CursorEndOffset - Compress CursorCounter, CursorSpeed, Reg10Copy - -; Compress CursorFill, CursorNbit - computed from mode variables - -; Compress DriverBankAddr - refers to screen always - - CompRange Ecf1, Ecf4+4 - CompMult DotLineStyle, 8 - -; Compress ModeNo - stored in sprite itself - - Compress TFTint, TBTint, GFTint, GBTint - -; Compress TotalScreenSize, MaxMode, ScreenEndAddr - refer to screen always - - Compress CursorFlags, CursorStack - Compress ECFShift, ECFYOffset - - Compress GCharSizeX, GCharSizeY, GCharSpaceX, GCharSpaceY -; Compress TCharSizeX, TCharSizeY ; recomputed from mode number -; Compress TCharSpaceX, TCharSpaceY ; each time - -; CompMult FgEcfOraEor, 64 ; recreated from GCOLs and ecfs -; CompMult BgEcfOraEor, 64 ; by call to SetColour -; CompMult BgEcfStore, 64 ; - - Compress LineDotCnt, LineDotPatLSW, LineDotPatMSW, DotLineLength - Compress BBCcompatibleECFs - -; Compress WrchNbit - computed from mode number - - CompRange ClipBoxEnable, ClipBoxTRow - - CompMult FgPattern, 4*8 - CompMult BgPattern, 4*8 - - Compress TextFgColour - Compress TextBgColour - - CompEnd -CompressionTableEnd -MainSize * CompressedSize + SavedDataOffset - - ASSERT MainSize <= SaveAreaSize - ! 0, "Space free in VDU save area = ":CC::STR:(SaveAreaSize-MainSize) - - [ {FALSE} ; don't allow teletext mode for now -TTXCompressionTable - CompStart - CompMult TTXDoubleCounts, 28 ; (25 rounded up to a word) - CompMult TTXMap, 41*25*4 - CompEnd -TTXCompressionTableEnd -TTXSize * CompressedSize - ] - - -; ***************************************************************************** -; -; PackVars - Pack variables into save area -; - -PackVars ROUT - CLC ; clear carry - indicate packing -PackOrUnpack - Push "R0-R4,R14" - LDR R0, [WsPtr, #VduSaveAreaPtr] - TEQ R0, #0 - Pull "R0-R4,PC", EQ ; ptr=0 => no area - - TEQ R0, #1 - ADDEQ R0, WsPtr, #VduSaveArea ; ptr=1 => use MOS's save area - - BL DoSpecialVars ; process special vars - - ADD R0, R0, #SavedDataOffset ; move on to compressed data - ADR R1, CompressionTable -10 - LDR R2, [R1], #4 - MVNS R3, R2 ; set Z if it was -1 (end of table) - Pull "R0-R4,PC", EQ ; (preserves C) - - ADD R3, WsPtr, R2, LSR #16 ; R3 = end pointer - MOV R2, R2, LSL #16 - ADD R2, WsPtr, R2, LSR #16 ; R2 = start pointer -20 - LDRCC R4, [R2], #4 ; load a word from vars - LDRCS R4, [R0], #4 ; or from save area - STRCC R4, [R0], #4 ; store into save area - STRCS R4, [R2], #4 ; or into vars - TEQ R2, R3 ; end of this block ? - BNE %BT20 ; [no, so loop] - B %BT10 ; go back for another block - -; ***************************************************************************** -; -; UnpackVars - Unpack variables from save area -; - -UnpackVars ROUT - SEC ; set carry - indicate unpacking - B PackOrUnpack - -; ***************************************************************************** -; -; DoSpecialVars - Pack/unpack special vars: CursorAddr, InputCursorAddr, -; (stored relative to ScreenStart); SpoolFileH, WrchDest, VDUqueueItems -; -; in: R0 -> save area -; -; out: R0 preserved -; R1-R2 corrupted -; Flags preserved -; - -DoSpecialVars ROUT - BYTEWS R1 - BCS %FT10 - LDRB R2, [R1, #:INDEX: SpoolFileH] - STRB R2, [R0, #SavedSpoolFileH] - LDRB R2, [R1, #:INDEX: WrchDest] - STRB R2, [R0, #SavedWrchDest] - LDRB R2, [R1, #:INDEX: VDUqueueItems] - STRB R2, [R0, #SavedVDUqueueItems] - LDR R1, VOTS ; initialised save area identifier - STR R1, [R0, #InitFlag] - MOV PC, R14 - -; unpack special vars (R1 -> ByteWS) - -10 - LDRB R2, [R0, #SavedSpoolFileH] - STRB R2, [R1, #:INDEX: SpoolFileH] - LDRB R2, [R0, #SavedWrchDest] - STRB R2, [R1, #:INDEX: WrchDest] - LDRB R2, [R0, #SavedVDUqueueItems] - STRB R2, [R1, #:INDEX: VDUqueueItems] - MOV PC, R14 - -; ***************************************************************************** -; -; ValidateVars - Validate unpacked variables (windows, cursor posns) -; - -ValidateVars ROUT - Push R14 - ASSERT ScrBRow = ScrRCol + 4 - ADD R4, WsPtr, #ScrRCol - LDMIA R4, {R4, R5} ; R4 = ScrRCol; R5 = ScrBRow - - ADD R6, WsPtr, #TWLCol ; R0 = TWLCol; R1 = TWBRow - LDMIA R6, {R0-R3} ; R2 = TWRCol; R3 = TWTRow - - MOV R7, #0 - MOV R8, R5 - MOV R9, R4 - MOV R10, #0 - STMIA R6, {R7-R10} ; set up default window - - BL FSRegs ; and attempt to define text window - - ASSERT YWindLimit = XWindLimit + 4 - ADD R0, WsPtr, #XWindLimit - LDMIA R0, {R2, R3} ; R2 = XWindLimit; R3 = YWindLimit - - ADD R8, WsPtr, #GWLCol ; R4 = GWLCol; R5 = GWBRow - LDMIA R8, {R4-R7} ; R6 = GWRCol; R7 = GWTRow - - CMP R6, R2 ; if GWRCol > XWindLimit - CMPLS R7, R3 ; or GWTRow > YWindLimit - - MOVHI R0, #0 - MOVHI R1, #0 - STMHIIA R8, {R0-R3} ; then set default graphics window - - Pull PC - - END diff --git a/s/vdu/vdugrafv b/s/vdu/vdugrafv deleted file mode 100644 index c6c87487..00000000 --- a/s/vdu/vdugrafv +++ /dev/null @@ -1,172 +0,0 @@ -; Copyright 2002 Tematic 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.VduGrafV -; -; ARTHUR OPERATING SYSTEM - Vdu Drivers -; ======================= -; -; Vdu driver code - Default GraphicsV claimant -; -; Author K J Bracey -; Date 30.8.02 -; - - [ UseGraphicsV - - ASSERT GraphicsV_VSync = 1 - ASSERT GraphicsV_SetMode = 2 - ASSERT GraphicsV_SetInterlace = 3 - ASSERT GraphicsV_SetBlank = 4 - ASSERT GraphicsV_UpdatePointer = 5 - ASSERT GraphicsV_SetDMAAddress = 6 - ASSERT GraphicsV_VetMode = 7 - ASSERT GraphicsV_DisplayFeatures = 8 - ASSERT GraphicsV_WritePaletteEntry = 10 - ASSERT GraphicsV_WritePaletteEntries = 11 - -MOSGraphicsV ROUT - CMP r4, #11 - ADDLS pc, pc, r4, LSL #2 - MOV pc, lr ; reason code not known, so pass it on - MOV pc, lr ; 0 - B GV_VSync ; 1 - B GV_SetMode ; 2 - B GV_SetInterlace ; 3 - B GV_SetBlank ; 4 - B GV_UpdatePointer ; 5 - B GV_SetAddress ; 6 - B GV_VetMode ; 7 - B GV_Features ; 8 - MOV pc, lr ; 9 - B GV_WritePaletteEntry ; 10 - B GV_WritePaletteEntries ; 11 - -GV_VSync ROUT - [ {FALSE} - [ HAL - Push "lr" - ] - LDR WsPtr, =OsbyteVars - MOV r4, #0 - B VsyncIRQ_ExtEntry - | -; Switch to interrupt mode to process this. - ASSERT No26bitCode - LDR WsPtr, =OsbyteVars - MRS r4, CPSR - Push "lr" - MSR CPSR_c, #I32_bit + IRQ32_mode - Push "r4, lr" - [ HAL - Push "pc" - B VsyncIRQ_ExtEntry - NOP - | - BL VsyncIRQ_ExtEntry - ] - Pull "r4, lr" - MSR CPSR_c, r4 - MOV r4, #0 - Pull "pc" - ] - -GV_SetMode - Push "r0-r3, r9, lr" - mjsAddressHAL WsPtr - MOV r4, #0 - mjsCallHAL HAL_Video_SetMode - Pull "r0-r3, r9, pc" - -GV_SetInterlace - Push "r0-r3, r9, lr" - mjsAddressHAL WsPtr - MOV r4, #0 - mjsCallHAL HAL_Video_SetInterlace - Pull "r0-r3, r9, pc" - -GV_SetBlank - Push "r0-r3, r9, lr" - mjsAddressHAL WsPtr - MOV r4, #0 - mjsCallHAL HAL_Video_SetBlank - Pull "r0-r3, r9, pc" - -GV_UpdatePointer - Push "r0-r3, r9, lr" - mjsAddressHAL WsPtr - MOV r4, #0 - mjsCallHAL HAL_Video_UpdatePointer - Pull "r0-r3, r9, pc" - -GV_SetAddress - Push "r0-r3, r9, lr" - mjsAddressHAL WsPtr - MOV r4, #0 - mjsCallHAL HAL_Video_SetDAG - Pull "r0-r3, r9, pc" - -GV_VetMode - Push "r1-r3, r9, lr" - mjsAddressHAL WsPtr - MOV r4, #0 - mjsCallHAL HAL_Video_VetMode - Pull "r1-r3, r9, pc" - -GV_Features - Push "r0,r1,r3, r9, lr" - mjsAddressHAL WsPtr - MOV r4, #0 - mjsCallHAL HAL_Video_Features - STR r0, [sp, #0] - mjsCallHAL HAL_Video_PixelFormats - STR r0, [sp, #4] - mjsCallHAL HAL_Video_BufferAlignment - MOV r2, r0 - Pull "r0,r1,r3, r9, pc" - -GV_WritePaletteEntry - Push "r0-r3, r9, lr" - mjsAddressHAL WsPtr - MOV r4, #0 - mjsCallHAL HAL_Video_WritePaletteEntry - Pull "r0-r3, r9, pc" - -GV_WritePaletteEntries - Push "r0-r3, r9, lr" - mjsAddressHAL WsPtr - MOV r4, #0 - mjsCallHAL HAL_Video_WritePaletteEntries - Pull "r0-r3, r9, pc" - -CallGraphicsV - Push "r10,r12,lr" - MOV r10, #GraphicsV - BL CallVector - Pull "r10,r12,pc" - -; Corrupts R9-R11 -; returns EQ if acceleration valid -CheckAcceleration - ASSERT Log2BPP = Log2BPC +4 - ADD R9, WsPtr, #Log2BPC - LDMIA R9, {R9, R10} ; R9 = Log2BPC; R10 = Log2BPP - LDR R11, [WsPtr, #VduSprite] - TEQ R9, R10 ; BPC must equal BPP - TEQEQ R11, #0 ; Must not be redirected - MOV PC, R14 - - ] ; UseGraphicsV - - END diff --git a/s/vdu/vduhint b/s/vdu/vduhint deleted file mode 100644 index eeaaaff8..00000000 --- a/s/vdu/vduhint +++ /dev/null @@ -1,1398 +0,0 @@ -; Copyright 2000 Pace Micro Technology plc -; -; 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. -; -; vduhint -; -; VDU hardware interface -; -; part of Kernel/HAL division -; -; Author Mike Stephens (mjs) -; Date Sep 2000 - -;;;mjsHAL -; -; vduhint is currently also a repository for VIDC20/IOMD specific HAL -; code, as stage 1 of Kernel/HAL split for video code -; eventually, vduhint should either have any veneer code/defns or -; should disappear altogether - -; temp mjs versions of macros to call HAL routines are -; defined in s.Kernel -; -; mjsAddressHAL and mjsCallHAL -; -; the HAL calls will be ARM ATPCS compliant (HAL API defined in C) -; for calls from kernel assembler code this means: -; r0-r3 (a1-a4) used for up to first 4 args -; any further args on stack (SP would need adjusting back after call) -; any scalar result of 'C' function in r0 (a1) -; HAL w/s pointer must be passed in r9 (SB or static base in ATPCS) -; So, register usage: -; -; r0-r3,r12 corrupted (a1-a4,IP) -; r4-r8,r10,r11 (v1-v5,v7,v8) preserved by all HAL calls -; r9 is HAL w/s pointer (preserved) -; r13,r14 are SP,LR as usual! -; -; The real routines make calls via symbols that are indices in a jump -; table - see s.HAL -; -; The mjs routines make calls via symbols that are routines still -; temporarily in kernel, but simulate the same register usage -; -; - - [ HAL - - ;;; nothing at all here so far in HAL case! - - ! 0, "vdu.vduhint compiles as empty in HAL case" - - | - - ;;; non-HAL case, pseudo HAL code - -; ----------------------------------------------------------------------------------- - -; -; TEMP defn for workspace while code still in kernel -; layout of workspace block anchored at mjs_tempHALworkspace -; - - ^ 0 -mjs_thalwk_start # 0 -VIDC_Address # 4 ; so code doesn't need a compile-time constant if in HAL -IOMD_Address # 4 ; so code doesn't need a compile-time constant if in HAL -VIDC_NextPaletteIndex # 4 ; last index used in setting normal palette entry -VIDC_SoftPalette0 # 4 ; soft copy of BBGGRRSS for normal palette entry 0 - ; (used to support ReadPaletteEntry) -VIDC_Interlace # 4 ; flag from VIDCList3 SyncPol word -VIDC_VertiDisplaySize # 4 ; we keep this for vertical pointer clipping -VIDC_PointerVAdjust # 4 ; vertical adjust for pointer -VIDC_PointerHAdjust # 4 ; horizontal adjust for pointer -VIDC_ExternalSoftCopy # 4 -VIDC_FSynSoftCopy # 4 -VIDC_ControlSoftCopy # 4 -VIDC_HSWRSoftCopy # 4 ; horizontal sync width -VIDC_VSWRSoftCopy # 4 ; vertical sync width -IOMD_VInitSoftCopy # 4 -IOMD_VEndSoftCopy # 4 -mjs_thalwk_end # 0 - -mjs_thalwk_size * mjs_thalwk_end - mjs_thalwk_start - -mjs_tempHALworkspace_init ROUT - Push "r0, lr" - LDR r0, =mjs_tempHALworkspace - LDR r0, [r0, #0] - MOV lr, #VIDC - STR lr, [r0, #VIDC_Address] - MOV lr, #IOMD_Base - STR lr, [r0, #IOMD_Address] - MOV lr, #-1 - STR lr, [r0, #VIDC_NextPaletteIndex] ; init to invalid - MOV lr, #0 - STR lr, [r0, #VIDC_SoftPalette0] - STR lr, [r0, #VIDC_Interlace] - Pull "r0, pc" - - -; ------------------------------------------------------------------------- - -;VIDC20 parameters size (for table of VIDC20 registers) -; -VIDC20ParmsSize * (128*4) ; 128 words from 80xxxxxx to FFxxxxxx step 01000000 - -; --- VIDC20 Registers --- - -VIDCPalAddress * &10000000 ; used in palette programming - -LCDOffsetRegister0 * &30000000 -LCDOffsetRegister1 * &31000000 - -VIDC20BorderColour * &40000000 ; added by mjs -VIDC20PointerColour * &50000000 ; added by mjs - -HorizCycle * &80000000 -HorizSyncWidth * &81000000 -HorizBorderStart * &82000000 -HorizDisplayStart * &83000000 -HorizDisplayEnd * &84000000 -HorizBorderEnd * &85000000 -HorizCursorStart * &86000000 ; used in pointer programming -HorizInterlace * &87000000 - -VertiCycle * &90000000 -VertiSyncWidth * &91000000 ; Needed to set up FSIZE register in IOMD -VertiBorderStart * &92000000 ; First register affected by *TV -VertiDisplayStart * &93000000 -VertiDisplayEnd * &94000000 -VertiBorderEnd * &95000000 -VertiCursorStart * &96000000 -VertiCursorEnd * &97000000 ; Last register affected by *TV - -VIDCExternal * &C0000000 -VIDCFSyn * &D0000000 -VIDCControl * &E0000000 -VIDCDataControl * &F0000000 - -; Pseudo-registers used to return additional information to kernel - -PseudoRegisters * 5 ; number of pseudo-register entries at end of table - -PseudoRegister_HClockSpeed * &FB000000 ; used to indicate VIDC hclock speed (and use it) -PseudoRegister_ClockSpeed * &FC000000 ; used to indicate real VIDC rclock speed -;no longer used: -;PseudoRegister_DPMSState * &FD000000 ; used to return desired DPMS state -; [ ChrontelSupport -;PseudoRegister_PixelRate * &FE000000 ; used to indicate the required pixel rate -; ] - - -; Bits in VCSR, VCER -CursorSinglePanel * 0 :SHL: 13 -CursorTopPanel * 1 :SHL: 13 -CursorBottomPanel * 1 :SHL: 14 -CursorStraddle * 3 :SHL: 13 - - -; Bits in external register - -Ext_HSYNCbits * 3 :SHL: 16 -Ext_InvertHSYNC * 1 :SHL: 16 -Ext_CompHSYNC * 2 :SHL: 16 -Ext_InvertCompHSYNC * 3 :SHL: 16 -Ext_VSYNCbits * 3 :SHL: 18 -Ext_InvertVSYNC * 1 :SHL: 18 -Ext_CompVSYNC * 2 :SHL: 18 -Ext_InvertCompVSYNC * 3 :SHL: 18 -Ext_HiResMono * 1 :SHL: 14 -Ext_LCDGrey * 1 :SHL: 13 -Ext_DACsOn * 1 :SHL: 12 -Ext_PedsOn * 7 :SHL: 8 -Ext_PedsShift * 8 -Ext_ERegShift * 4 -Ext_ECKOn * 1 :SHL: 2 -Ext_ERegBits * 3 :SHL: 0 -Ext_ERegRed * 0 :SHL: 0 -Ext_ERegGreen * 1 :SHL: 0 -Ext_ERegBlue * 2 :SHL: 0 -Ext_ERegExt * 3 :SHL: 0 ; use this for lowest power - -; Bits in Frequency Synthesizer Register - -FSyn_VShift * 8 -FSyn_RShift * 0 -FSyn_ClearV * 1 :SHL: 15 -FSyn_ForceLow * 1 :SHL: 14 -FSyn_ClearR * 1 :SHL: 7 -FSyn_ForceHigh * 1 :SHL: 6 - -FSyn_ResetValue * FSyn_ClearV :OR: FSyn_ClearR :OR: FSyn_ForceLow :OR: (63 :SHL: FSyn_RShift) :OR: (0 :SHL: FSyn_VShift) ; value to get PLL working properly - -; Bits in Control Register - -CR_DualPanel * 1 :SHL: 13 -CR_Interlace * 1 :SHL: 12 -CR_FIFOLoadShift * 8 -CR_LBPP0 * 0 :SHL: 5 -CR_LBPP1 * 1 :SHL: 5 -CR_LBPP2 * 2 :SHL: 5 -CR_LBPP3 * 3 :SHL: 5 -CR_LBPP4 * 4 :SHL: 5 -CR_LBPP5 * 6 :SHL: 5 ; spot the gap! -CR_PixelDivShift * 2 -CR_VCLK * 0 :SHL: 0 -CR_HCLK * 1 :SHL: 0 -CR_RCLK * 2 :SHL: 0 - -; Bits in Data Control Register - -DCR_VRAMOff * 0 :SHL: 18 -DCR_VRAMDiv1 * 1 :SHL: 18 -DCR_VRAMDiv2 * 2 :SHL: 18 -DCR_VRAMDiv4 * 3 :SHL: 18 -DCR_BusBits * 3 :SHL: 16 -DCR_Bus31_0 * 1 :SHL: 16 -DCR_Bus63_32 * 2 :SHL: 16 -DCR_Bus63_0 * 3 :SHL: 16 -DCR_HDis * 1 :SHL: 13 -DCR_Sync * 1 :SHL: 12 -DCR_HDWRShift * 0 - -; ------------------------------------------------------------------------- - -; -; void HAL_Video_SetMode(const void *VIDCList3) -; -; program VIDC20 registers from VIDCList3 specification -; -; in: VIDClist -> video mode list (in VIDCList type 3 format) -; (and sb (r9) -> HAL workspace) -; - -HAL_Video_SetMode ROUT - Push "r4, r7,r8,r10,r11, lr" - MOV r3, r0 ; r3 -> VIDCList3 - - SUB sp, sp, #VIDC20ParmsSize ; create workspace for VIDC20 table on stack - SUB r11, sp, #(&80*4) ; r11 indexes into table workspace (allowing for - ; VIDC register numbers starting at &80) - - MOV r2, #-1 ; first clear all entries to -1 (means dont program reg) - MOV r4, #VIDC20ParmsSize - MOV r14, sp -10 - STR r2, [r14], #4 - SUBS r4, r4, #4 - BNE %BT10 - - LDR r2, [r3, #VIDCList3_HorizSyncWidth] - BIC r2, r2, #1 ; must be even - SUB r2, r2, #8 ; horiz parameters start off at n-8 - ORR r14, r2, #HorizSyncWidth - STR r14, [r11, #HorizSyncWidth :SHR: 22] - - LDR r4, [r3, #VIDCList3_HorizBackPorch] - ADD r2, r2, r4 - BIC r2, r2, #1 - SUB r2, r2, #4 ; HBSR is N-12 - ORR r14, r2, #HorizBorderStart - STR r14, [r11, #HorizBorderStart :SHR: 22] - - LDR r4, [r3, #VIDCList3_HorizLeftBorder] - ADD r2, r2, r4 - BIC r2, r2, #1 - SUB r2, r2, #6 ; HDSR is N-18 - ORR r14, r2, #HorizDisplayStart - STR r14, [r11, #HorizDisplayStart :SHR: 22] - - LDR r4, [r3, #VIDCList3_HorizDisplaySize] - BIC r4, r4, #1 - LDR r7, [r3, #VIDCList3_PixelDepth] - MOV r10, r4, LSL r7 ; number of bits in one displayed raster (not needed later any more) - - ANDS r8, r10, #31 ; if line length not multiple of 32 - MOVNE r8, #DCR_HDis ; then set HDis bit - ORR r8, r8, r10, LSR #5 ; OR in number of words per line - -; Note - the DCR_Bus bits get overridden and the HDWR bits modified further down the line by the mode change code -; on the basis of how much VRAM we've got, and on whether we have a dual-panel LCD or not... - - ORR r8, r8, #DCR_VRAMOff :OR: DCR_Bus31_0 :OR: DCR_Sync - ORR r8, r8, #VIDCDataControl - STR r8, [r11, #VIDCDataControl :SHR: 22] - - ADD r2, r2, r4 ; HDER is also N-18 - ORR r14, r2, #HorizDisplayEnd - STR r14, [r11, #HorizDisplayEnd :SHR: 22] - - LDR r4, [r3, #VIDCList3_HorizRightBorder] - ADD r2, r2, r4 - ADD r2, r2, #6 ; HBER is N-12 - BIC r2, r2, #1 - ORR r14, r2, #HorizBorderEnd - STR r14, [r11, #HorizBorderEnd :SHR: 22] - - LDR r4, [r3, #VIDCList3_HorizFrontPorch] - ADD r2, r2, r4 - ADD r2, r2, #4 ; HCR is N-8 - BIC r2, r2, #3 ; must be mult of 4 - ORR r14, r2, #HorizCycle - STR r14, [r11, #HorizCycle :SHR: 22] - - ADD r2, r2, #8 ; HIR is N/2 - MOV r2, r2, LSR #1 - ORR r14, r2, #HorizInterlace - STR r14, [r11, #HorizInterlace :SHR: 22] - - LDR r2, [r3, #VIDCList3_VertiSyncWidth] - SUB r2, r2, #2 ; vertical registers are N-2 - ORR r14, r2, #VertiSyncWidth - STR r14, [r11, #VertiSyncWidth :SHR: 22] - - LDR r4, [r3, #VIDCList3_VertiBackPorch] - ADD r2, r2, r4 - ORR r14, r2, #VertiBorderStart - STR r14, [r11, #VertiBorderStart :SHR: 22] - - LDR r4, [r3, #VIDCList3_VertiTopBorder] - ADD r2, r2, r4 - ORR r14, r2, #VertiDisplayStart - STR r14, [r11, #VertiDisplayStart :SHR: 22] - - LDR r4, [r3, #VIDCList3_VertiDisplaySize] - STR r4, [r9, #VIDC_VertiDisplaySize] ; save it for cursor clipping - ADD r2, r2, r4 - ORR r14, r2, #VertiDisplayEnd - STR r14, [r11, #VertiDisplayEnd :SHR: 22] - - LDR r4, [r3, #VIDCList3_VertiBottomBorder] - ADD r2, r2, r4 - ORR r14, r2, #VertiBorderEnd - STR r14, [r11, #VertiBorderEnd :SHR: 22] - - LDR r4, [r3, #VIDCList3_VertiFrontPorch] - ADD r2, r2, r4 - ORR r14, r2, #VertiCycle - STR r14, [r11, #VertiCycle :SHR: 22] - - LDR r4, [r3, #VIDCList3_SyncPol] - TST r4, #SyncPol_Interlace - MOVEQ r14, #0 - MOVNE r14, #1 - STR r14, [r9, #VIDC_Interlace] - MOV r14, #VIDCExternal - TST r4, #SyncPol_InvertHSync - ORRNE r14, r14, #Ext_InvertHSYNC - TST r4, #SyncPol_InvertVSync - ORRNE r14, r14, #Ext_InvertVSYNC - ORR r14, r14, #Ext_DACsOn - ORR r14, r14, #Ext_ERegExt - STR r14, [r11, #VIDCExternal :SHR: 22] - - MOV r14, #VIDCControl - STR r14, [r11, #VIDCControl :SHR: 22] - - Push "r3" - -; Now go through VIDC control parameters list (not all indices can be handled yet) - - ADD r3, r3, #VIDCList3_ControlList-8 ; point at 1st entry -8 -50 - LDR r4, [r3, #8]! ; load next index - CMP r4, #-1 ; if -1 then end of list - BEQ %FT60 ; so skip - - CMP r4, #0 ; if non-zero (CS if zero) - CMPNE r4, #ControlList_InvalidReason ; and if known reason - LDRCC r2, [r3, #4] ; then load value - BLCC ProcessControlListItem ; and process this item - B %BT50 ; go onto next item in list - -; put a minimum of 4, cos 800 x 600 x 1bpp don't work otherwise -FIFOLoadTable - & 0 ; dummy entry (not used) - & 0 ; never use 0 - & 0 ; use 1 up to (and including) here - & 0 ; use 2 up to (and including) here - & 0 ; use 3 up to (and including) here - & 60000 :SHL: 3 ; use 4 up to (and including) here - & 75000 :SHL: 3 ; use 5 up to (and including) here - & 90000 :SHL: 3 ; use 6 up to (and including) here - ; else use 7 - -60 - Pull "r3" - LDR r0, [r3, #VIDCList3_PixelRate] ; get pixel rate - MOV r10, r0, LSL r7 ; peak mem b/w (x 1E3 bits/sec) - save for FIFO calculation - - ! 0, "mjsHAL - using kernel variable IOSystemType" - - [ MorrisSupport - MOV R1, #0 - LDRB R1, [R1, #IOSystemType] - TST R1, #IOST_7500 - LDREQ R1, =24000 ;RISC PC clocks VIDC20 at 24MHz - MOVNE R1, #32000 ;Morris clocks VIDC20L at 32Mhz - | - LDR r1, =rclk ; eventually will need to replace this if specified in control list - ] - - BL ComputeModuli ; out: r0 = FSync bits, r1 = CR bits - - ORR r0, r0, #VIDCFSyn - STR r0, [r11, #VIDCFSyn :SHR: 22] - - LDR r0, [r11, #VIDCControl :SHR: 22] - ORR r0, r0, r1 - - TEQ r7, #5 ; if 32 bpp, then stick in 6 not 5 - MOVEQ r7, #6 - ORR r0, r0, r7, LSL #5 - -; now work out FIFO load position - r10 is b/w in thousands of bytes/sec - -; do it by means of a binary chop on 3 bits - - ADR r4, FIFOLoadTable - LDR r2, [r4, #4*4] ; load 0-3/4-7 split - CMP r10, r2 - MOVLS r7, #0 ; if <=, then bottom half - MOVHI r7, #4 ; else top half - ADDHI r4, r4, #4*4 ; and advance table pointer - - LDR r2, [r4, #2*4] - CMP r10, r2 - ORRHI r7, r7, #2 - ADDHI r4, r4, #2*4 - - LDR r2, [r4, #1*4] - CMP r10, r2 - ORRHI r7, r7, #1 - - ORR r0, r0, r7, LSL #CR_FIFOLoadShift - STR r0, [r11, #VIDCControl :SHR: 22] - - ADD R0, r11, #(&80*4) ; R0 -> VIDC20 table (remove offset for reg indices starting at &80) - BL ProgramVIDC20Regs - - ; now make sure video DMA enabled - ; - LDR r7, [r9, #IOMD_Address] - LDRB r8, [r7, #IOMD_VIDCR] - AND r8, r8, #&7F ; knock out IOMD_VIDCR_Dup - ORR r8, r8, #IOMD_VIDCR_Enable ; enable video DMA - STRB r8, [r7, #IOMD_VIDCR] - - ADD sp, sp, #VIDC20ParmsSize ; drop workspace for table - Pull "r4, r7,r8,r10,r11, pc" - -; ------------------------------------------------------------------------- - -; ProgramVIDC20Regs - program registers from table -; -; entry: r0 -> VIDC table to program into registers -; (and r9 -> HAL workspace) -; -; allowed to corrupt any of r0-r4, r7,r8,r10,r11 (only called from HAL_Video_SetMode) - -ProgramVIDC20Regs ROUT - Push "r6, lr" - - LDR R4, [R9, #VIDC_Interlace] - TST R4, #1 - MOVNE R4, #CR_Interlace - - MOV R7, R0 ; keep copy in R7 in case we go wrong - LDR R3, [R9, #VIDC_Address] ; R3 -> VIDC20 h/w -18 - MOV R1, #(128-PseudoRegisters)*4 ; number of bytes to do (don't program pseudo-registers!) -20 - LDR R2, [R0], #4 ; Get data from table - CMP R2, #-1 ; unprogrammed register ? - BEQ %FT80 ; then skip - - AND R6, R2, #&FF000000 - - TEQ R6, #HorizDisplayStart - STREQ R2, [R9, #VIDC_PointerHAdjust] ; save here for later calculation of adjust - - TEQ R6, #VertiDisplayStart ; test for display start - BICEQ R14, R2, #&FF000000 ; get rid of register bits - STREQ R14, [R9, #VIDC_PointerVAdjust] ; save for pointer programming - - TEQ R6, #HorizSyncWidth ; if h.sync width register - STREQ R2, [R9, #VIDC_HSWRSoftCopy] ; then save for DPMS stuff - TEQ R6, #VertiSyncWidth ; likewise v.sync width - STREQ R2, [R9, #VIDC_VSWRSoftCopy] - - TEQ R6, #VIDCExternal ; check for external register (which contains syncs) - BNE %FT50 - - ! 0, "mjsHAL - currently assume vertical sync rather than find out (by HAL call to OS?)" -;;; -;;;mjsHAL old code that operated on NE if composite sync found from SWI OS_ReadSysInfo 1 -;;; -;;; BICNE R2, R2, #(Ext_HSYNCbits :OR: Ext_VSYNCbits) ; if composite sync then don't invert syncs -;;; ORRNE R2, R2, #Ext_InvertCompVSYNC :OR: Ext_InvertCompHSYNC ; and force both syncs to be composite (because of lack of - ; swap in A540 VIDC card) - B %FT75 -50 - TEQ R6, #VIDCFSyn - BNE %FT60 - - LDR R8, =FSyn_ResetValue ; set test bits on, and r > v - ORR R8, R8, #VIDCFSyn - STR R8, [R3] - -; we may need some delay in here... - - LDR R8, =FSyn_ClearR :OR: FSyn_ClearV :OR: FSyn_ForceLow :OR: FSyn_ForceHigh - ORR R2, R2, R8 - BIC R2, R2, #FSyn_ForceHigh ; force test bits on, except this one - STR R2, [R3] - -; we may also need some delay in here... - - BIC R2, R2, R8 ; remove test bits - B %FT75 - -60 - TEQ r6, #VIDCDataControl - BNE %FT65 - - ! 0, "mjsHAL - using kernel variable VRAMWidth" - - BIC r2, r2, #DCR_BusBits - MOV r14, #0 - LDRB r14, [r14, #VRAMWidth] - CMP r14, #2 ; if using 64-bit wide VRAM - ORRCS r2, r2, #DCR_Bus63_0 ; then data on all 64 bits - ORRCC r2, r2, #DCR_Bus31_0 ; else for 32-bit wide VRAM or DRAM-only, - ; data is on low 32 bits - BCC %FT65 - -; dual-bank VRAM, so HDWR value needs to be halved - - MOV r14, r2, LSL #(31-10) ; get HDWR bits at top - NB allow bit 10 to be used here! - BIC r2, r2, r14, LSR #(31-10) ; knock off bits - TST r14, #1 :SHL: (31-10) ; see if bottom bit would get knocked off - ORRNE r2, r2, #DCR_HDis ; if so, then disable HDis mechanism (for eg mode 29) - ORREQ r2, r2, r14, LSR #(31-9) ; otherwise, put bits back one bit further down - -65 - TEQ R6, #VIDCControl ; if control register - BNE %FT75 - -; programming control register, so EOR sync/interlace bits, save in soft copy -; then work out horizontal pointer adjust from HorizDisplayStart -; (saved in VIDC_PointerHAdjust) and bits-per-pixel in control register - - EOR R2, R2, R4 ; then EOR sync/interlace bits - STR R2, [R9, #VIDC_ControlSoftCopy] ; and save in copy - -; now compute FSIZE properly - LDR R10, [R7, #(&94-&80)*4] ; get vertidisplayend - BIC R10, R10, #&FF000000 - LDR R8, [R7, #(&93-&80)*4] ; get vertidisplaystart - BIC R8, R8, #&FF000000 - SUB R10, R10, R8 ; verti displayed - LDR R8, [R7, #(&90-&80)*4] ; verti total - BIC R8, R8, #&FF000000 - SUB R10, R8, R10 - ADD R10, R10, #1 ; vidc parms are n-2, we want n-1 - LDR R8, [R9, #IOMD_Address] - STRB R10, [R8, #IOMD_FSIZE] - - LDR R14, [R9, #VIDC_PointerHAdjust] ; R14 = horiz display start (-18) - BIC R14, R14, #&FF000000 - ADD R14, R14, #(18-17) ; horiz cursor start is programmed with n-17 - STR R14, [R9, #VIDC_PointerHAdjust] -75 - TEQ R6, #VIDCExternal - STREQ R2, [R9, #VIDC_ExternalSoftCopy] - TEQ R6, #VIDCFSyn - STREQ R2, [R9, #VIDC_FSynSoftCopy] - TEQ R6, #VIDCControl - STREQ R2, [R9, #VIDC_ControlSoftCopy] - - STR R2, [R3] ; stuff it into VIDC20 -80 - SUBS R1, R1, #4 - BNE %BT20 - - MOV R2, #VertiCursorStart + 0 ; program cursor start and end - STR R2, [R3] - MOV R2, #VertiCursorEnd + 0 ; to zero - STR R2, [R3] - - Pull "r6, pc" - -; ------------------------------------------------------------------------- - -; -; ProcessControlListItem -; -; in: r2 = value for item -; r4 = index for item (guaranteed in range) -; r11 -> VIDC register array -; -; out: r0-r2, r4, r7, r8, r10 may be corrupted -; r3, r9, r11 must be preserved - -ProcessControlListItem Entry - LDR pc, [pc, r4, LSL #2] - NOP - & ProcessControlListNOP ; 0 - NOP - & ProcessControlListLCDMode ; 1 - LCD mode - & ProcessControlListLCDDualPanelMode ; 2 - LCD dual-panel mode - & ProcessControlListLCDOffsetRegister0 ; 3 - LCD offset register 0 - & ProcessControlListLCDOffsetRegister1 ; 4 - LCD offset register 1 - & ProcessControlListHiResMode ; 5 - Hi-res mode - & ProcessControlListDACControl ; 6 - DAC control - & ProcessControlListRGBPedestals ; 7 - RGB pedestal enables - & ProcessControlListExternalRegister ; 8 - External register - & ProcessControlListHClockSelect ; 9 - HClk select/specify - & ProcessControlListNOP ; 10 - RClk frequency - & ProcessControlListDPMSState ; 11 - DPMS state - & ProcessControlListNOP ; 12 - Interlaced mode - - ! 0, "mjsHAL - no LCD support (VIDCList3 control list stuff)" - -ProcessControlListLCDMode - ;;;mjsHAL we have no support - EXIT - -ProcessControlListHiResMode - MOV r1, #Ext_HiResMono ; bit of a misnomer, it's not nec. mono -05 - MOV r0, #VIDCExternal -10 - MOV r7, r1 - TEQ r2, #0 ; if value non-zero - MOVNE r2, r1 ; then use value in r1 -15 - AND r2, r2, r7 ; ensure only relevant bits set - LDR lr, [r11, r0, LSR #22] ; load word from register bank - BIC lr, lr, r7 ; knock out bits in mask - ORR lr, lr, r2 ; OR in new bits - STR lr, [r11, r0, LSR #22] ; and store in array -; -ProcessControlListNOP - EXIT - -ProcessControlListDACControl - MOV r1, #Ext_DACsOn - B %BT05 - -ProcessControlListRGBPedestals - MOV r0, #VIDCExternal - MOV r2, r2, LSL #Ext_PedsShift - MOV r7, #Ext_PedsOn - B %BT15 - -ProcessControlListExternalRegister - MOV r0, #VIDCExternal - MOV r7, #&FF - B %BT15 - -ProcessControlListLCDDualPanelMode - ;;;mjsHAL we have no support - EXIT - -ProcessControlListLCDOffsetRegister0 - ;;;mjsHAL we have no support - EXIT - -ProcessControlListLCDOffsetRegister1 - ;;;mjsHAL we have no support - EXIT - -ProcessControlListHClockSelect - MOV r0, #PseudoRegister_HClockSpeed ; pseudo-register holding HClock speed - ORR r2, r2, r0 ; form combined value - STR r2, [r11, r0, LSR #22] ; store in register - EXIT - -ProcessControlListDPMSState - ; no longer used in HAL code (kernel keeps DPMSState) - EXIT - -; ------------------------------------------------------------------------- - -; -; ComputeModuli - Work out VCO moduli for a given frequency -; -; in: r0 = desired frequency (kHz) -; r1 = rclk frequency (kHz) (normally 24000) -; r11 -> VIDC table -; -; out: r0 = bits to put in bits 0..15 of Frequency Synthesizer Register -; r1 = bits to put in bits 0..4 of Control Register - -rclk * 24000 ; Reference clock into VIDC20 (in kHz) -VCO_Min * 55000 ; minimum VCO frequency (in kHz) -VCO_Max * 110000 ; maximum VCO frequency (in kHz) - -fpshf * 11 ; Shift value for fixed point arithmetic - - ^ 0, sp - -BestDInOrOutOfRange # 4 -BestRInOrOutOfRange # 4 -BestVInOrOutOfRange # 4 -BestDInRange # 4 -BestRInRange # 4 -BestVInRange # 4 -BestRangeError # 4 -ComputeModuliStack * :INDEX: @ - -ComputeModuli Entry "r2-r12", ComputeModuliStack - LDR r2, [r11, #PseudoRegister_HClockSpeed:SHR:22] ; are we using HCLK? - CMP r2, #-1 - BEQ %FT05 ; -1 => no, use VCLK/RCLK - - BIC r1, r2, #&FF000000 ; r1 = HCLK frequency - SUB r1, r1, r1, LSR #2 ; r1 = HCLK * 3/4 - CMP r0, r1 - MOVLO r1, #CR_HCLK :OR: ((2-1) :SHL: CR_PixelDivShift) ; if < 3/4 HCLK, use divide by 2 - MOVHS r1, #CR_HCLK :OR: ((1-1) :SHL: CR_PixelDivShift) ; else use divide by 1 - LDR r0, =(63 :SHL: FSyn_RShift) :OR: (1 :SHL: FSyn_VShift) ; minimum V, maximum R - EXIT - -; Use VCLK/RCLK -05 - MOV r12, #-1 ; smallest error for values in or out of VCO range - MOV r11, #-1 ; smallest error for values in VCO range - STR r11, BestDInRange - STR r11, BestVInRange - STR r11, BestRInRange - STR r11, BestDInOrOutOfRange - STR r11, BestVInOrOutOfRange - STR r11, BestRInOrOutOfRange - STR r11, BestRangeError - MOV r5, r1 ; r5 = rclk frequency, normally 24000 (32000 on Morris) - LDR r1, =VCO_Min ; r1 = minimum VCO frequency (in kHz) - LDR r2, =VCO_Max ; r2 = maximum VCO frequency (in kHz) - MOV r3, #1 ; r3 = D -10 - MOV r4, #1 ; r4 = R -15 - MUL r6, r0, r3 ; r6 = xD - MUL r7, r6, r4 ; r7 = xRD - ADD r7, r7, r5, LSR #1 ; r7 = xRD + vref/2 - DivRem r8, r7, r5, r9 ; r8 = (xRD + vref/2) DIV vref = V value - - TEQ r4, #1 ; if R=1 then V must be 1, else it's no good - BNE %FT20 - TEQ r8, #1 - BNE %FT50 - BEQ %FT25 -20 - CMP r8, #2 ; if R<>1 then V must be in range 2..64 - RSBCSS r7, r8, #64 - BCC %FT50 ; V out of range, so skip -25 - MUL r7, r5, r8 ; r7 = V * vref - MOV r7, r7, LSL #fpshf ; r7 = (V * vref) << fixedpointshift - DivRem r9, r7, r4, r14 ; r9 = ((V * vref) << fixedpointshift)/R = VCO frequency << fixedpointshift - MOV r6, r9 - DivRem r7, r9, r3, r14 ; r7 = output frequency << fixedpointshift - SUBS r7, r7, r0, LSL #fpshf - RSBCC r7, r7, #0 ; r7 = absolute error << fixedpointshift - - TEQ r4, #1 ; if R=1 then no need to check VCO range - BEQ %FT27 ; because VCO won't be used, so it's a 1st class citizen - - CMP r6, r1, LSL #fpshf ; test if VCO freq >= min - RSBCSS r14, r6, r2, LSL #fpshf ; and <= max - BCC %FT40 ; not in range, so not a first class citizen -27 - CMP r7, r11 - BHI %FT40 ; worse than the best case for in VCO range, so ignore - BCC %FT30 ; is definitely better than the best case for in or out - - LDR r14, BestRInRange ; is equal best for in, so check R value - CMP r4, r14 ; is newR < bestR - BCS %FT40 ; is greater or equal R value (ie not higher comp. freq., so not best) -30 - MOV r11, r7 - STR r3, BestDInRange - STR r4, BestRInRange - STR r8, BestVInRange - MOV r14, #0 - B %FT45 - -40 - RSBS r14, r6, r1, LSL #fpshf ; r14 = min-this, if this<min - SUBCC r14, r6, r2, LSL #fpshf ; else r14 = this-max, ie r14 = how much this is outside range - - CMP r7, r12 - BHI %FT50 ; worse than the best case for in or out of VCO range, so ignore - BCC %FT45 ; is definitely better than the best case for in or out - - LDR r9, BestRangeError ; is equal best for in or out, so check error - CMP r14, r9 - BCS %FT50 ; not lower error, so skip -45 - MOV r12, r7 - STR r3, BestDInOrOutOfRange - STR r4, BestRInOrOutOfRange - STR r8, BestVInOrOutOfRange - STR r14, BestRangeError -50 - [ :LNOT: DontUseVCO ; If we don't use the VCO, R has to be 1 - ADD r4, r4, #1 - CMP r4, #16 ; R goes from 2 to 16 (was 2 to 64) - BLS %BT15 - ] - - ADD r3, r3, #1 - CMP r3, #8 ; D goes from 1 to 8 - BLS %BT10 - - ADR r2, BestDInRange - LDR r3, [r2] - CMP r3, #-1 - ADDEQ r2, r2, #BestDInOrOutOfRange - BestDInRange - LDREQ r3, [r2] ; r3 = Best D - LDR r4, [r2, #BestRInRange - BestDInRange] ; r4 = Best R - LDR r5, [r2, #BestVInRange - BestDInRange] ; r5 = Best V - - SUBS r4, r4, #1 ; values in FSyn are n-1 - [ VCOstartfix - ;do *not* do the very slow trick - this will stall the VCO and it may not restart - ;properly later (we don't give a fig for power consumption) - MOVEQ r4, #3 - MOVEQ r5, #8 ; after sub below, (7+1)/(3+1) so VCO runs at twice ref clock - | - MOVEQ r4, #63 ; if R=V=1 then use max R - MOVEQ r5, #2 ; and min V to make VCO go really slow - ] - - SUB r5, r5, #1 ; for both v and r - ASSERT FSyn_RShift = 0 - ORR r0, r4, r5, LSL #FSyn_VShift - - SUB r3, r3, #1 ; D is also stored as n-1 - MOV r1, r3, LSL #CR_PixelDivShift - ASSERT CR_VCLK = 0 - ORREQ r1, r1, #CR_RCLK ; if using VCO then set for VCLK, else RCLK - - EXIT - -; ------------------------------------------------------------------------- - -; -; void HAL_Video_WritePaletteEntry(uint type, uint pcolour, uint index) -; -; write palette entry to video controller -; -; type = 0 for normal palette entry -; 1 for border colour -; 2 for pointer colour -; >= 3 reserved -; pcolour = palette entry colour in BBGGRRSS format (Blue,Green,Red,Supremacy) -; index = index of entry (0..255 for normal, 0 for border, 0..3 for pointer) -; note that RISC OS only uses 1..3 for pointer (0 is assumed to be transparent) -; -; r9 is workspace pointer, may corrupt r0..r3, r12 -; -HAL_Video_WritePaletteEntry ROUT - - AND r12, r1, #&F0 ; 000000S0 (4 MSbits of supremacy) - MOV r1, r1, LSR #8 ; 00BBGGRR - ORR r1, r1, r12, LSL #20 ; 0SBBGGRR - - LDR r12, [r9, #VIDC_Address] - - CMP r0, #1 - BLO HV_WritePaletteEntry_type0 - BEQ HV_WritePalettEntry_type1 -; else fall through to WritePaletteEntry_type2 -; -HV_WritePaletteEntry_type2 - CMP r2, #3 ; index must be in range 0..3 - MOVHI pc, lr - SUBS r2, r2, #1 ; reduce 1..3 to 0..2 - MOVMI pc, lr ; pointer colour 0 is always transparent on VIDC20 - ORR r1, r1,#VIDC20PointerColour ; munge in base address of register - ADD r1, r1, r2, LSL #28 ; add in index (0..2), in bits 28,29 of register - STR r1, [r12] - MOV pc, lr -; -HV_WritePaletteEntry_type0 - ;Note: we only need to hit VIDCPalAddress if the index is not a direct increment - ;of the last programmed index - ;but, for insurance against permanent misalignment if any rogue accesses avoid this - ;interface, we force an update for index 0 - ; - CMP r2, #255 ; index must be in range 0..255 - MOVHI pc, lr - - CMP r2, #0 - - STREQ r1, [r9, #VIDC_SoftPalette0] - - LDRNE r0, [r9, #VIDC_NextPaletteIndex] ;increment from last index programmed - MOVEQ r0, #-1 ;forced invalid for index 0 - - TEQ r0, r2 - ORRNE r0, r2, #VIDCPalAddress - STRNE r0, [r12] ; only update PalAddress if necessary - STR r1, [r12] ; update palette entry - ADD r2, r2, #1 - AND r2, r2, #&FF - STR r2, [r9, #VIDC_NextPaletteIndex] - MOV pc, lr -; -; -HV_WritePalettEntry_type1 - CMP r2, #0 ; index must be 0 - MOVNE pc, lr - ORR r1, r1,#VIDC20BorderColour ; munge in base address of register - STR r1, [r12] - MOV pc, lr - -; ------------------------------------------------------------------------- - -; -; void HAL_Video_WritePaletteEntries(uint type, const uint *pcolours, uint index, uint Nentries) -; -; write block of palette entries to video controller -; -; type = 0 for normal palette entry -; 1 for border colour -; 2 for pointer colour -; >= 3 reserved -; pcolours = pointer to block of palette entry colours in BBGGRRSS format (Blue,Green,Red,Supremacy) -; index = start index in palette (for first entry in block) -; note that RISC OS only uses 1..3 for pointer (0 is assumed to be transparent) -; Nentries = number of entries in block (must be >= 1) -; -; r9 is workspace pointer, may corrupt r0..r3, r12 -; -HAL_Video_WritePaletteEntries ROUT - Push "r4, lr" - - CMP r2, #255 ; all indices in loop must be in range 0..255 - BHI %FT20 - ADD r4, r2, r3 - CMP r4, #256 - BHI %FT20 - - CMP r0, #0 - BNE %FT50 -; -; type 0, try to be efficient -; - LDR r12, [r9, #VIDC_Address] - - CMP r2, #0 - - LDREQ r0, [r1] - STREQ r0, [r9, #VIDC_SoftPalette0] - - LDRNE r0, [r9, #VIDC_NextPaletteIndex] - MOVEQ r0,#-1 ; insurance! (see comments for WritePaletteEntry_type0) - - TEQ r0, r2 - ORRNE r0, r2, #VIDCPalAddress - STRNE r0, [r12] ; only update PalAddress if necessary - - ADD r0, r2, r3 - AND r0, r0, #&FF - STR r0, [r9, #VIDC_NextPaletteIndex] - - MOV r4, r1 -10 - LDR r1, [r4], #4 - AND r0, r1, #&F0 ; 000000S0 (4 msbits of supremacy) - MOV r1, r1, LSR #8 ; 00BBGGRR - ORR r1, r1, r0, LSL #20 ; 0SBBGGRR - STR r1, [r12] - SUBS r3, r3, #1 - BNE %BT10 -20 - Pull "r4, pc" -; -; not type 0 -; -50 - MOV r4, r1 -60 - LDR r1, [r4], #4 ; next pcolour - Push "r2, r3" - BL HAL_Video_WritePaletteEntry - Pull "r2, r3" - ADD r2, r2, #1 - SUBS r3, r3, #1 - BNE %BT60 - Pull "r4, pc" - -; ------------------------------------------------------------------------- - -; -; uint HAL_Video_ReadPaletteEntry(uint type, uint pcolour, uint index) -; -; return the effective palette entry after taking into account any hardware -; restrictions in the video controller, assuming it was programmed with pcolour -; -; type = 0 for normal palette entry -; 1 for border colour -; 2 for pointer colour -; >= 3 reserved -; pcolour = palette entry colour in BBGGRRSS format (Blue,Green,Red,Supremacy) -; index = index of entry (0..255 for normal, 0 for border, 0..3 for pointer) -; note that RISC OS only uses 1..3 for pointer (0 is assumed to be transparent) -; returns : effective BBGGRRSS -; -; r9 is workspace pointer, may corrupt r0..r2, r12 -; -; mjs: depending on h/w capabilities, specific HALs may have to -; remember current settings (eg. bits per pixel), keep soft copy -; of entries or whatever, in their workspace. Because the HAL API -; supplies a pcolour, the need to keep a full palette soft copy -; in the HAL is minimised - -HAL_Video_ReadPaletteEntry ROUT - - CMP r0, #0 - BNE HV_ReadPaletteEntry_not_type0 -; -; type 0 -; only 4 bits of S, and only 16 S entries -; S for indices 16..255 comes from palette entry 0 -; - CMP r2, #16 - LDRHS r12, [r9, #VIDC_SoftPalette0] - MOVLO r12, r1 - - AND r12, r12, #&000000F0 ; effective S bits - BIC r0, r1, #&000000FF ; effective BGR bits - ORR r0, r0, r12 ; munge together - MOV pc, lr -; -HV_ReadPaletteEntry_not_type0 -; no special restrictions, just that there are only 4 bits of S - BIC r0, r1, #&0000000F - MOV pc, lr - -; ------------------------------------------------------------------------- - -; void HAL_Video_SetInterlace(uint interlace) -; -; interlace = 0/1 for interlace off/on - -HAL_Video_SetInterlace ROUT - - LDR r1, [r9, #VIDC_ControlSoftCopy] - BIC r1, r1, #CR_Interlace - TST r0, #1 - ORRNE r1, r1, #CR_Interlace ; zero => no interlace - - LDR r0, [r9, #VIDC_Address] - STR r1, [r0] ; program VIDC - MOV pc, lr - -; ------------------------------------------------------------------------- - -; void HAL_Video_SetBlank(uint blank, uint DPMS) -; -; blank = 0/1 for unblank/blank -; DMPS = 0..3 as specified by monitor DPMSState (from mode file) -; 0 for no DPMS power saving - -; HAL is expected to attempt to turn syncs off according to DPMS, and -; to turn video DMA off for blank (and therefore on for unblank) if possible. -; HAL is not expected to do anything else, eg. blank all palette entries. -; Such things are the responsibility of the OS, and also this call is expected -; to be fast. May be called with interrupts off. - -HAL_Video_SetBlank ROUT - - LDR r3, [r9, #VIDC_Address] - - TEQ r0, #0 - BEQ %FT50 -; -; blanking -; - TST r1, #1 ; if hsyncs should be off, - LDRNE r2, =HorizSyncWidth + ((1:SHL:14) -1) ; maximum value in h.sync width register - STRNE r2, [r3] - - TST r1, #2 ; if vsyncs should be off, - LDRNE r2, =VertiSyncWidth + ((1:SHL:13) -1) ; maximum value in v.sync width register - STRNE r2, [r3] - - LDR r2, [r9, #VIDC_ExternalSoftCopy] - AND r1, r1, #3 - TEQ r1, #3 ; if both syncs off - BICEQ r2, r2, #Ext_HSYNCbits :OR: Ext_VSYNCbits - ORREQ r2, r2, #Ext_InvertHSYNC :OR: Ext_InvertVSYNC ; set sync signals to low (less power) - BIC r2, r2, #Ext_DACsOn ; turn off the DACs - STR r2, [r3] - - LDR r0, [r9, #IOMD_Address] - LDRB r1, [r0, #IOMD_VIDCR] - BIC r1, r1, #IOMD_VIDCR_Enable ; disable video DMA - STRB r1, [r0, #IOMD_VIDCR] - - MOV pc, lr -; -; unblanking -; -50 LDR r2, [r9, #VIDC_ExternalSoftCopy] - STR r2, [r3] ; restore DACs and sync type - - TST r1, #1 ; if hsyncs were turned off, - LDRNE r2, [r9, #VIDC_HSWRSoftCopy] ; then restore from soft copy - STRNE r2, [r3] - - TST r1, #2 ; if vsyncs were turned off, - LDRNE r2, [R9, #VIDC_VSWRSoftCopy] ; then restore from soft copy - STRNE r2, [r3] - - LDR r0, [r9, #IOMD_Address] - LDRB r1, [r0, #IOMD_VIDCR] - ORR r1, r1, #IOMD_VIDCR_Enable ; enable video DMA - STRB r1, [r0, #IOMD_VIDCR] - - MOV pc, lr - -; ------------------------------------------------------------------------- - -; void HAL_Video_SetPowerSave(uint powersave) -; -; powersave = 0/1 for power save off/on - -HAL_Video_SetPowerSave ROUT - - LDR r1, [r9, #VIDC_Address] - - TEQ r0, #0 - BEQ %FT50 -; -; power save on -; - LDR r2, =&C0000003 ;dac off, ereg set to external LUT - STR r2, [r1] - - LDR r2, =&D0004000 ;Vclk off, Pcomp=0 - STR r2, [r1] - - LDR r2, =&E0004049 ;PoDown, Hclk - STR r2, [r1] - - MOV pc, lr -; -; power save off -; -50 - LDR r2, [R9, #VIDC_ControlSoftCopy] ;restore from soft copy - STR r2, [r1] - - LDR r2, [R9, #VIDC_ExternalSoftCopy] ;restore from soft copy - STR r2, [r1] - - LDR r2, [R9, #VIDC_FSynSoftCopy] ;restore from soft copy - - [ {TRUE} - LDR R3, =FSyn_ResetValue ; set test bits on, and r > v - ORR R3, R3, #VIDCFSyn - STR R3, [R1] - -; we may need some delay in here... - - LDR R3, =FSyn_ClearR :OR: FSyn_ClearV :OR: FSyn_ForceLow :OR: FSyn_ForceHigh - ORR R2, R2, R3 - BIC R2, R2, #FSyn_ForceHigh ; force test bits on, except this one - STR R2, [R1] - -; we may also need some delay in here... - - BIC R2, R2, R3 ; remove test bits - ] - STR r2, [r1] - - MOV pc, lr - -; ------------------------------------------------------------------------- - -; void HAL_Video_UpdatePointer(uint flags, int x, int y, const shape_t *shape) -; -; Update the displayed position of the current pointer shape (or turn -; shape off) -; -; HAL code may need to take note of shape updated flag, and make its -; own new copies if true. This is to handle cases like dual scan LCD -; pointer, which typically needs two or more shapes buffers for the -; hardware. This work should _only_ be done when the updated flag -; is true, or possibly because provoked by clipping requirements. -; A simple HAL, using the kernel shape buffer directly, may be able to -; ignore the updated flag. -; -; flags: -; bit 0 = pointer display enable (0=off, 1=on) -; bit 1 = pointer shape update (0=no change, 1=updated) -; bits 2..31 reserved (0) -; xpos = x position of top left of pointer (xpos = 0 for left of display) -; ypos = y position of top left of pointer (ypos = 0 for top of display) -; shape points to shape_t descriptor block: -; typedef struct shape_t -; { -; uint8 width; /* unpadded width in bytes (see notes) */ -; uint8 height; /* in pixels */ -; uint8 padding[2]; /* 2 bytes of padding for field alignment */ -; void *buffLA; /* logical address of buffer holding pixel data */ -; void *buffPA; /* corresponding physical address of buffer */ -; } -; -; Notes: -; 1) if flags bit 0 is 0 (pointer off), x, y, shape are undefined -; 2) the shape data from RISC OS is always padded with transparent pixels -; on the rhs, to a width of 32 pixels (8 bytes) -; 3) pointer clipping is the responsibility of the HAL (eg. may be able to -; allow display of pointer in border region on some h/w) -; 4) buffer for pixel data is aligned to a multiple of 256 bytes or better -; -; This call is made by the OS at a time to allow smoothly displayed changes -; (on a VSync) - -HAL_Video_UpdatePointer - - Push "r4, r5, lr" - - LDR r14, [r9, #VIDC_Address] - - TST r0, #1 - BEQ %FT90 ; pointer off - -; -; process x (and assume shape width is padded 32 pixels) -; - LDR r4, [R9, #VIDC_PointerHAdjust] - ADDS r1, r1, r4 - MOVLT r1, #0 ; x:= x+fudge, clamped to 0 - - CMP r1, #&4000 ; VIDC has 14 bits for cursor start - MOVGE r1, #&4000 - SUBGE r1, r1, #1 - - ORR r1, r1, #HorizCursorStart - STR r1, [r14] -; -; process y -; - LDRB r4, [r3, #1] ; height from shape_t block - LDR r5, [r3, #8] ; buffer physical address from shape_t block - - CMP r2, #0 ; if -ve y - BICLT r2, r2, #1 ; TEMP FUDGE - really ought to have two copies, one offset by 1 row - ; because VIDC can only cope with 16 byte aligned data pointer - ADDLT r4, r4, r2 ; reduce height - SUBLT r5, r5, r2, LSL #3 ; and advance data pointer (8 bytes per row) to clip pointer to 0 - MOVLT r2, #0 - CMP r4, #0 - BLE %FT90 ; pointer off if clipped to oblivion - - LDR r1, [r9, #VIDC_VertiDisplaySize] - SUB r1, r1, r2 ; if display_height - y < pointer height - CMP r1, r4 - MOVLT r4, r1 ; clip pointer height - CMP r4, #0 - BLE %FT90 ; pointer off if clipped to oblivion - - LDR r1, [R9, #VIDC_PointerVAdjust] - ADD r2, r2, r1 ; y := y+adjust - - ORR r1, r2, #VertiCursorStart - STR r1, [r14] - - ADD r2, r2, r4 ; y:= y+height - ORR r1, r2, #VertiCursorEnd - STR r1, [r14] - - LDR r14, [r9, #IOMD_Address] - STR r5, [r14, #IOMD_CURSINIT] - - Pull "r4, r5, pc" - -90 -; -; pointer off -; - MOV r4, #VertiCursorStart - STR r4, [r14] - MOV r4, #VertiCursorEnd - STR r4, [r14] - - Pull "r4, r5, pc" - -; ------------------------------------------------------------------------- - -; void HAL_Video_SetDAG(uint DAG, uint paddr) -; -; set Video DMA address generator value to given physical address -; -; DAG = 0 set start address of current video display -; 1 set start address of total video buffer -; 2 set end address (exclusive) of total video buffer -; all other values reserved -; paddr = physical address for given DAG -; -; Notes: -; The OS has a video buffer which is >= total display size, and may be using -; bank switching (several display buffers) or hardware scroll within the -; total video buffer. -; -; DAG=1 will be start address of current total video buffer -; DAG=2 will be end address (exclusive) of current total video buffer -; DAG=0 will be start address in buffer for current display -; -; HALs should respond as follows: -; 1) If they have no hardware scroll support, only DAG=0 is significant, -; and the end address of the current display is implied by the size -; of the current mode. Calls with DAG=1,2 should be ignored. -; 2) If they support hardware scroll, DAG=0 again defines display start. -; DAG=2 defines the last address (exclusive) that should be displayed -; before wrapping back (if reached within display size), and DAG=1 -; defines the address to which accesses should wrap back. - -HAL_Video_SetDAG ROUT - - LDR r12, [r9, #IOMD_Address] - - CMP r0, #1 - BEQ %FT20 - BHI %FT40 -; -; DAG=0 program VInit -; - STR r1, [r9, #IOMD_VInitSoftCopy] ; save VInit so that writes to VEnd can check - LDR r2, [r9, #IOMD_VEndSoftCopy] - CMP r1, r2 ; if VInit >= VEnd then set L bit - ORRCS r1, r1, #IOMD_DMA_L_Bit - STR r1, [r12, #IOMD_VIDINIT] - MOV pc, lr -; -; DAG=1 program VStart -; -20 STR r1, [r12, #IOMD_VIDSTART] - MOV pc, lr - - ! 0, "mjsHAL - using kernel variable VRAMWidth" -; -; DAG=2 program VEnd -; -40 MOV r2, #0 ; we must adjust address to that of - LDRB r2, [r2, #VRAMWidth] ; last DMA fetch, allowing for fetch size - CMP r2, #1 - MOVLO r2, #16 ; DRAM-only, subtract 16 (quadword) - MOVEQ r2, #SAMLength/2 ; 1 bank of VRAM - 1/2 SAM - MOVHI r2, #SAMLength ; 2 banks of VRAM - 1/2 SAM * 2 - SUB r1, r1, r2 - STR r1, [r9, #IOMD_VEndSoftCopy] ; remember VEnd value - LDR r2, [r9, #IOMD_VInitSoftCopy] ; load current VInit - CMP r2, r1 ; if VInit >= VEnd - ORRCS r2, r2, #IOMD_DMA_L_Bit ; then set L bit - STR r2, [r12, #IOMD_VIDINIT] ; store VInit - STR r1, [r12, #IOMD_VIDEND] ; and VEnd - MOV pc, lr - -; ------------------------------------------------------------------------- - -;;;mjsHAL - is the mode workspace really generic enough to pass to HAL? -;;; - -; -; int HAL_Video_VetMode(const void *VIDClist, const void *workspace) -; -; VIDClist -> generic video controller list (VIDC list type 3) -; workspace -> mode workspace (if mode number), or 0 -; returns 0 if OK (may be minor adjusts to VIDClist and/or workspace values) -; non-zero if not OK -; -HAL_Video_VetMode ROUT - MOV r0,#0 ; do nothing for now - MOV PC,LR - -; ------------------------------------------------------------------------- - - ] ; big HAL if/else switch around whole file - - END diff --git a/s/vdu/vdumodes b/s/vdu/vdumodes deleted file mode 100644 index f72cc34a..00000000 --- a/s/vdu/vdumodes +++ /dev/null @@ -1,1111 +0,0 @@ -; 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. -; -; > $.Kernel.Source.VduModes -; - -; general purpose mode macros - -; mjs Kernel/HAL split -; -; BigVIDCTable is now in hardware independent format, ie. a VIDC list type 3 -; -; Macro VIDC_List10 removed - hardware specific, and very old anyway! (VIDC1 is pre Medusa) -; Macro VIDC_List20 removed - hardware specific, not needed in HAL either -; Macro VIDC_ListT3 newly defined - - MACRO -$label VIDC_List $lbpp,$hsync,$hbpch,$hlbdr,$hdisp,$hrbdr,$hfpch, $vsync,$vbpch,$vlbdr,$vdisp,$vrbdr,$vfpch,$pixrate,$sp -$label VIDC_ListT3 $lbpp,$hsync,$hbpch,$hlbdr,$hdisp,$hrbdr,$hfpch, $vsync,$vbpch,$vlbdr,$vdisp,$vrbdr,$vfpch,$pixrate,$sp - MEND - -; -; format of a VIDC list type 3 -; - ^ 4 -VIDCList3_PixelDepth # 4 -VIDCList3_HorizSyncWidth # 4 -VIDCList3_HorizBackPorch # 4 -VIDCList3_HorizLeftBorder # 4 -VIDCList3_HorizDisplaySize # 4 -VIDCList3_HorizRightBorder # 4 -VIDCList3_HorizFrontPorch # 4 -VIDCList3_VertiSyncWidth # 4 -VIDCList3_VertiBackPorch # 4 -VIDCList3_VertiTopBorder # 4 -VIDCList3_VertiDisplaySize # 4 -VIDCList3_VertiBottomBorder # 4 -VIDCList3_VertiFrontPorch # 4 -VIDCList3_PixelRate # 4 -VIDCList3_SyncPol # 4 ; sync polarity/flag bits -VIDCList3_ControlList # 0 ; possibly empty list of pairs of index,value words -; -; and VIDCList3 is terminated by a -1 word -; -; Indices in VIDCList3_ControlList -; - ^ 1 -ControlList_LCDMode # 1 -ControlList_LCDDualPanelMode # 1 -ControlList_LCDOffset0 # 1 -ControlList_LCDOffset1 # 1 -ControlList_HiResMode # 1 -ControlList_DACControl # 1 -ControlList_RGBPedestals # 1 -ControlList_ExternalRegister # 1 -ControlList_HClockSelect # 1 -ControlList_RClockFrequency # 1 -ControlList_DPMSState # 1 -ControlList_Interlaced # 1 -ControlList_OutputFormat # 1 -ControlList_InvalidReason # 0 - -; bits/flags in VIDCList3_SyncPol word: -; -SyncPol_InvertHSync * 1 -SyncPol_InvertVSync * 2 -SyncPol_InterlaceSpecified * 4 ; if set, interlace bit has been specified, else filled in by kernel -SyncPol_Interlace * 8 ; set=interlaced, either specified by service call claimant or filled in from *TV by kernel - - -; Macro VIDC_ListT3 - for hardware independent table (using 'VIDC' list type 3 format, see PRM 5a-125) -; - MACRO -$label VIDC_ListT3 $lbpp,$hsync,$hbpch,$hlbdr,$hdisp,$hrbdr,$hfpch, $vsync,$vbpch,$vlbdr,$vdisp,$vrbdr,$vfpch,$pixrate,$sp - -$label - LCLA sp - LCLA dwidth - GBLA framerate - LCLA framepixels - - [ "$sp"="" -sp SETA 0 ; normal sync polarity - | - ASSERT $sp<=3 -sp SETA $sp - ] - -; just to check width is whole number of words (to suit rendering code) -dwidth SETA $hdisp :SHL: $lbpp - ASSERT (dwidth :AND: 31) = 0 - -framepixels SETA ($hsync+$hbpch+$hlbdr+$hdisp+$hrbdr+$hfpch)*($vsync+$vbpch+$vlbdr+$vdisp+$vrbdr+$vfpch) -framerate SETA ($pixrate*1000+framepixels/2)/framepixels - -F_$label * framerate ; set up frame rate symbol - -; - & 3 ; format (type 3) - & $lbpp ; log2 bits per pixel -; Horizontal (in pixels) - & $hsync ; sync width - & $hbpch ; back porch - & $hlbdr ; left border - & $hdisp ; display size - & $hrbdr ; right border - & $hfpch ; front porch -; Vertical (in rasters) - & $vsync ; sync width - & $vbpch ; back porch - & $vlbdr ; top border - & $vdisp ; display size - & $vrbdr ; bottom border - & $vfpch ; front porch -; - & $pixrate ; pixel rate (kHz) - & sp ; sync polarity - & -1 ; terminator (no video control parameters) - - MEND ; MACRO VIDC_ListT3 - - - -NumMonitorTypes * 9 -NumModes * 50 -maxmode * NumModes-1 -minmode * 0 - -; These macro are used by various routines in the kernel to check for a valid mode number -; MUST be kept up-to-date with the list of invalid modes between 0 and maxmode - - MACRO - BranchIfKnownMode $reg, $address - CMP $reg, #NumModes - BCC $address ; then branch - MEND - - MACRO - BranchIfNotKnownMode $reg, $address - CMP $reg, #NumModes - BCS $address ; branch if *NOT* known - MEND - - -BigVIDCTable - -; -; monitor type 0, 50Hz TV -; - & VLN_0 - BigVIDCTable ; 0 - & VLN_1 - BigVIDCTable ; 1 - & VLN_2 - BigVIDCTable ; 2 - & VLN_3 - BigVIDCTable ; 3 - & VLN_4 - BigVIDCTable ; 4 - & VLN_5 - BigVIDCTable ; 5 - & VLN_6 - BigVIDCTable ; 6 - [ HiResTTX - & -1 ; 7 - | - & VLN_7 - BigVIDCTable ; 7 - ] - & VLN_8 - BigVIDCTable ; 8 - & VLN_9 - BigVIDCTable ; 9 - & VLN_10 - BigVIDCTable ; 10 - & VLN_11 - BigVIDCTable ; 11 - & VLN_12 - BigVIDCTable ; 12 - & VLN_13 - BigVIDCTable ; 13 - & VLN_14 - BigVIDCTable ; 14 - & VLN_15 - BigVIDCTable ; 15 - & VLN_16 - BigVIDCTable ; 16 - & VLN_17 - BigVIDCTable ; 17 - & -1 ; 18 - & -1 ; 19 - & -1 ; 20 - & -1 ; 21 - & VLN_22 - BigVIDCTable ; 22 - & -1 ; 23 - & VLN_24 - BigVIDCTable ; 24 - & -1 ; 25 - & -1 ; 26 - & -1 ; 27 - & -1 ; 28 - & -1 ; 29 - & -1 ; 30 - & -1 ; 31 - & -1 ; 32 - & VLN_33 - BigVIDCTable ; 33 - & VLN_34 - BigVIDCTable ; 34 - & VLN_35 - BigVIDCTable ; 35 - & VLN_36 - BigVIDCTable ; 36 - & -1 ; 37 - & -1 ; 38 - & -1 ; 39 - & -1 ; 40 - & -1 ; 41 - & -1 ; 42 - & -1 ; 43 - & -1 ; 44 - & -1 ; 45 - & -1 ; 46 - & -1 ; 47 - & -1 ; 48 - & -1 ; 49 - -; -; monitor type 1, multiscan -; - ASSERT (.-BigVIDCTable)=((NumModes*1):SHL:2) - - & VLM_0 - BigVIDCTable ; 0 - & VLM_1 - BigVIDCTable ; 1 - & VLM_2 - BigVIDCTable ; 2 - & VLM_3 - BigVIDCTable ; 3 - & VLM_4 - BigVIDCTable ; 4 - & VLM_5 - BigVIDCTable ; 5 - & VLM_6 - BigVIDCTable ; 6 - & VLM_7 - BigVIDCTable ; 7 - & VLM_8 - BigVIDCTable ; 8 - & VLM_9 - BigVIDCTable ; 9 - & VLM_10 - BigVIDCTable ; 10 - & VLM_11 - BigVIDCTable ; 11 - & VLM_12 - BigVIDCTable ; 12 - & VLM_13 - BigVIDCTable ; 13 - & VLM_14 - BigVIDCTable ; 14 - & VLM_15 - BigVIDCTable ; 15 - & VLM_16 - BigVIDCTable ; 16 - & VLM_17 - BigVIDCTable ; 17 - & VLM_18 - BigVIDCTable ; 18 - & VLM_19 - BigVIDCTable ; 19 - & VLM_20 - BigVIDCTable ; 20 - & VLM_21 - BigVIDCTable ; 21 - & VLM_22 - BigVIDCTable ; 22 - & -1 ; 23 - & VLM_24 - BigVIDCTable ; 24 - & VLM_25 - BigVIDCTable ; 25 - & VLM_26 - BigVIDCTable ; 26 - & VLM_27 - BigVIDCTable ; 27 - & VLM_28 - BigVIDCTable ; 28 - & VLM_29 - BigVIDCTable ; 29 - & VLM_30 - BigVIDCTable ; 30 - & VLM_31 - BigVIDCTable ; 31 - & VLM_32 - BigVIDCTable ; 32 - & VLM_33 - BigVIDCTable ; 33 Ovscn - & VLM_34 - BigVIDCTable ; 34 - & VLM_35 - BigVIDCTable ; 35 - & VLM_36 - BigVIDCTable ; 36 - & VLM_37 - BigVIDCTable ; 37 dtp - & VLM_38 - BigVIDCTable ; 38 - & VLM_39 - BigVIDCTable ; 39 - & VLM_40 - BigVIDCTable ; 40 - & VLM_41 - BigVIDCTable ; 41 EGA - & VLM_42 - BigVIDCTable ; 42 - & VLM_43 - BigVIDCTable ; 43 - & VLM_44 - BigVIDCTable ; 44 CGA - & VLM_45 - BigVIDCTable ; 45 - & VLM_46 - BigVIDCTable ; 46 - & VLM_47 - BigVIDCTable ; 47 PCSoft - & VLM_48 - BigVIDCTable ; 48 Games mode - & VLM_49 - BigVIDCTable ; 49 Games mode - - -; -; monitor type 2, HiRes -; - ASSERT (.-BigVIDCTable)=((NumModes*2):SHL:2) - - & -1 ; 0 - & -1 ; 1 - & -1 ; 2 - & -1 ; 3 - & -1 ; 4 - & -1 ; 5 - & -1 ; 6 - & -1 ; 7 - & -1 ; 8 - & -1 ; 9 - & -1 ; 10 - & -1 ; 11 - & -1 ; 12 - & -1 ; 13 - & -1 ; 14 - & -1 ; 15 - & -1 ; 16 - & -1 ; 17 - & -1 ; 18 - & -1 ; 19 - & -1 ; 20 - & -1 ; 21 - & -1 ; 22 - & VLH_23 - BigVIDCTable ; 23 - & -1 ; 24 - & -1 ; 25 - & -1 ; 26 - & -1 ; 27 - & -1 ; 28 - & -1 ; 29 - & -1 ; 30 - & -1 ; 31 - & -1 ; 32 - & -1 ; 33 - & -1 ; 34 - & -1 ; 35 - & -1 ; 36 - & -1 ; 37 - & -1 ; 38 - & -1 ; 39 - & -1 ; 40 - & -1 ; 41 - & -1 ; 42 - & -1 ; 43 - & -1 ; 44 - & -1 ; 45 - & -1 ; 46 - & -1 ; 47 - & -1 ; 48 - & -1 ; 49 - -; -; monitor type 3, VGA -; - ASSERT (.-BigVIDCTable)=((NumModes*3):SHL:2) - - & VgaX_0 - BigVIDCTable ; 0 - & VgaX_1 - BigVIDCTable ; 1 - & VgaX_2 - BigVIDCTable ; 2 - & VgaX_3 - BigVIDCTable ; 3 - & VgaX_4 - BigVIDCTable ; 4 - & VgaX_5 - BigVIDCTable ; 5 - & VgaX_6 - BigVIDCTable ; 6 - & VgaX_7 - BigVIDCTable ; 7 - & VgaX_8 - BigVIDCTable ; 8 - & VgaX_9 - BigVIDCTable ; 9 - & VgaX_10 - BigVIDCTable ; 10 - & VgaX_11 - BigVIDCTable ; 11 - & VgaX_12 - BigVIDCTable ; 12 - & VgaX_13 - BigVIDCTable ; 13 - & VgaX_14 - BigVIDCTable ; 14 - & VgaX_15 - BigVIDCTable ; 15 - & -1 ; 16 - & -1 ; 17 - & -1 ; 18 - & -1 ; 19 - & -1 ; 20 - & -1 ; 21 - & -1 ; 22 - & -1 ; 23 - & -1 ; 24 - & VLM_25 - BigVIDCTable ; 25 - & VLM_26 - BigVIDCTable ; 26 - & VLM_27 - BigVIDCTable ; 27 - & VLM_28 - BigVIDCTable ; 28 - & -1 ; 29 - & -1 ; 30 - & -1 ; 31 - & -1 ; 32 - & -1 ; 33 - & -1 ; 34 - & -1 ; 35 - & -1 ; 36 - & -1 ; 37 - & -1 ; 38 - & -1 ; 39 - & -1 ; 40 - & VgaX_41 - BigVIDCTable ; 41 EGA - & VgaX_42 - BigVIDCTable ; 42 - & VgaX_43 - BigVIDCTable ; 43 - & VgaX_44 - BigVIDCTable ; 44 CGA - & VgaX_45 - BigVIDCTable ; 45 - & VgaX_46 - BigVIDCTable ; 46 - & VLM_47 - BigVIDCTable ; 47 PCSoft - & VLM_48 - BigVIDCTable ; 48 Games mode - & VLM_49 - BigVIDCTable ; 49 Games mode - -; -; monitor type 4, SVGA -; - ASSERT (.-BigVIDCTable)=((NumModes*4):SHL:2) - - & VgaX_0 - BigVIDCTable ; 0 - & VgaX_1 - BigVIDCTable ; 1 - & VgaX_2 - BigVIDCTable ; 2 - & VgaX_3 - BigVIDCTable ; 3 - & VgaX_4 - BigVIDCTable ; 4 - & VgaX_5 - BigVIDCTable ; 5 - & VgaX_6 - BigVIDCTable ; 6 - & VgaX_7 - BigVIDCTable ; 7 - & VgaX_8 - BigVIDCTable ; 8 - & VgaX_9 - BigVIDCTable ; 9 - & VgaX_10 - BigVIDCTable ; 10 - & VgaX_11 - BigVIDCTable ; 11 - & VgaX_12 - BigVIDCTable ; 12 - & VgaX_13 - BigVIDCTable ; 13 - & VgaX_14 - BigVIDCTable ; 14 - & VgaX_15 - BigVIDCTable ; 15 - & -1 ; 16 - & -1 ; 17 - & -1 ; 18 - & -1 ; 19 - & -1 ; 20 - & -1 ; 21 - & -1 ; 22 - & -1 ; 23 - & -1 ; 24 - & VLM_25 - BigVIDCTable ; 25 - & VLM_26 - BigVIDCTable ; 26 - & VLM_27 - BigVIDCTable ; 27 - & VLM_28 - BigVIDCTable ; 28 - & VLM_29 - BigVIDCTable ; 29 - & VLM_30 - BigVIDCTable ; 30 - & VLM_31 - BigVIDCTable ; 31 - & VLM_32 - BigVIDCTable ; 32 - & -1 ; 33 - & -1 ; 34 - & -1 ; 35 - & -1 ; 36 - & -1 ; 37 - & -1 ; 38 - & -1 ; 39 - & -1 ; 40 - & VgaX_41 - BigVIDCTable ; 41 EGA - & VgaX_42 - BigVIDCTable ; 42 - & VgaX_43 - BigVIDCTable ; 43 - & VgaX_44 - BigVIDCTable ; 44 CGA - & VgaX_45 - BigVIDCTable ; 45 - & VgaX_46 - BigVIDCTable ; 46 - & VLM_47 - BigVIDCTable ; 47 PCSoft - & VLM_48 - BigVIDCTable ; 48 Games mode - & VLM_49 - BigVIDCTable ; 49 Games mode - -; -; monitor type 5, LCD -; - ASSERT (.-BigVIDCTable)=((NumModes*5):SHL:2) - - & -1 ; 0 - & -1 ; 1 - & -1 ; 2 - & -1 ; 3 - & -1 ; 4 - & -1 ; 5 - & -1 ; 6 - & -1 ; 7 - & -1 ; 8 - & -1 ; 9 - & -1 ; 10 - & -1 ; 11 - & -1 ; 12 - & -1 ; 13 - & -1 ; 14 - & -1 ; 15 - & -1 ; 16 - & -1 ; 17 - & -1 ; 18 - & -1 ; 19 - & -1 ; 20 - & -1 ; 21 - & -1 ; 22 - & -1 ; 23 - & -1 ; 24 - & LCD_25 - BigVIDCTable ; 25 - & LCD_26 - BigVIDCTable ; 26 - & LCD_27 - BigVIDCTable ; 27 - & LCD_28 - BigVIDCTable ; 28 - & -1 ; 29 - & -1 ; 30 - & -1 ; 31 - & -1 ; 32 - & -1 ; 33 - & -1 ; 34 - & -1 ; 35 - & -1 ; 36 - & -1 ; 37 - & -1 ; 38 - & -1 ; 39 - & -1 ; 40 - & -1 ; 41 - & -1 ; 42 - & -1 ; 43 - & -1 ; 44 - & -1 ; 45 - & -1 ; 46 - & -1 ; 47 - & -1 ; 48 - & -1 ; 49 - -; -; monitor type 6, reserved? -; - ASSERT (.-BigVIDCTable)=((NumModes*6):SHL:2) - - & -1 ; 0 - & -1 ; 1 - & -1 ; 2 - & -1 ; 3 - & -1 ; 4 - & -1 ; 5 - & -1 ; 6 - & -1 ; 7 - & -1 ; 8 - & -1 ; 9 - & -1 ; 10 - & -1 ; 11 - & -1 ; 12 - & -1 ; 13 - & -1 ; 14 - & -1 ; 15 - & -1 ; 16 - & -1 ; 17 - & -1 ; 18 - & -1 ; 19 - & -1 ; 20 - & -1 ; 21 - & -1 ; 22 - & -1 ; 23 - & -1 ; 24 - & -1 ; 25 - & -1 ; 26 - & -1 ; 27 - & -1 ; 28 - & -1 ; 29 - & -1 ; 30 - & -1 ; 31 - & -1 ; 32 - & -1 ; 33 - & -1 ; 34 - & -1 ; 35 - & -1 ; 36 - & -1 ; 37 - & -1 ; 38 - & -1 ; 39 - & -1 ; 40 - & -1 ; 41 - & -1 ; 42 - & -1 ; 43 - & -1 ; 44 - & -1 ; 45 - & -1 ; 46 - & -1 ; 47 - & -1 ; 48 - & -1 ; 49 - -; -; monitor type 7, file -; - ASSERT (.-BigVIDCTable)=((NumModes*7):SHL:2) - - & -1 ; 0 - & -1 ; 1 - & -1 ; 2 - & -1 ; 3 - & -1 ; 4 - & -1 ; 5 - & -1 ; 6 - & -1 ; 7 - & -1 ; 8 - & -1 ; 9 - & -1 ; 10 - & -1 ; 11 - & -1 ; 12 - & -1 ; 13 - & -1 ; 14 - & -1 ; 15 - & -1 ; 16 - & -1 ; 17 - & -1 ; 18 - & -1 ; 19 - & -1 ; 20 - & -1 ; 21 - & -1 ; 22 - & -1 ; 23 - & -1 ; 24 - & -1 ; 25 - & -1 ; 26 - & -1 ; 27 - & -1 ; 28 - & -1 ; 29 - & -1 ; 30 - & -1 ; 31 - & -1 ; 32 - & -1 ; 33 - & -1 ; 34 - & -1 ; 35 - & -1 ; 36 - & -1 ; 37 - & -1 ; 38 - & -1 ; 39 - & -1 ; 40 - & -1 ; 41 - & -1 ; 42 - & -1 ; 43 - & -1 ; 44 - & -1 ; 45 - & -1 ; 46 - & -1 ; 47 - & -1 ; 48 - & -1 ; 49 - -; -; monitor type 8, 60Hz TV -; - ASSERT (.-BigVIDCTable)=((NumModes*8):SHL:2) - - & -1 ; 0 - & -1 ; 1 - & -1 ; 2 - & -1 ; 3 - & -1 ; 4 - & -1 ; 5 - & -1 ; 6 - & -1 ; 7 - & -1 ; 8 - & -1 ; 9 - & -1 ; 10 - & -1 ; 11 - & -1 ; 12 - & -1 ; 13 - & -1 ; 14 - & -1 ; 15 - & -1 ; 16 - & -1 ; 17 - & -1 ; 18 - & -1 ; 19 - & -1 ; 20 - & -1 ; 21 - & -1 ; 22 - & -1 ; 23 - & -1 ; 24 - & -1 ; 25 - & -1 ; 26 - & -1 ; 27 - & -1 ; 28 - & -1 ; 29 - & -1 ; 30 - & -1 ; 31 - & -1 ; 32 - & -1 ; 33 - & -1 ; 34 - & -1 ; 35 - & -1 ; 36 - & -1 ; 37 - & -1 ; 38 - & -1 ; 39 - & -1 ; 40 - & -1 ; 41 - & -1 ; 42 - & -1 ; 43 - & VLM_44 - BigVIDCTable ; 44 CGA - & VLM_45 - BigVIDCTable ; 45 - & VLM_46 - BigVIDCTable ; 46 - & -1 ; 47 - & -1 ; 48 - & -1 ; 49 - - ASSERT (.-BigVIDCTable)=((NumModes*NumMonitorTypes):SHL:2) - -VLN_0 VIDC_List 0, 76, 88, 96, 640, 96, 28, 3,19,16,256,16, 2,16000,0 ; MODE 0 -VLN_1 VIDC_List 1, 38, 44, 48, 320, 48, 14, 3,19,16,256,16, 2, 8000,0 ; MODE 1 -VLN_2 VIDC_List 2, 38, 44, 48, 320, 48, 14, 3,19,16,256,16, 2, 8000,0 ; MODE 2 -VLN_3 VIDC_List 1, 76, 88, 96, 640, 96, 28, 3,19,19,250,19, 2,16000,0 ; MODE 3 -VLN_4 VIDC_List 0, 76, 88, 96, 640, 96, 28, 3,19,16,256,16, 2,16000,0 ; MODE 4 -VLN_5 VIDC_List 1, 38, 44, 48, 320, 48, 14, 3,19,16,256,16, 2, 8000,0 ; MODE 5 -VLN_6 VIDC_List 1, 38, 44, 48, 320, 48, 14, 3,19,19,250,19, 2, 8000,0 ; MODE 6 - [ :LNOT: HiResTTX -VLN_7 VIDC_List 2, 38, 44, 48, 320, 48, 14, 3,19,19,250,19, 2, 8000,0 ; MODE 7 - ] -VLN_8 VIDC_List 1, 76, 88, 96, 640, 96, 28, 3,19,16,256,16, 2,16000,0 ; MODE 8 -VLN_9 VIDC_List 2, 38, 44, 48, 320, 48, 14, 3,19,16,256,16, 2, 8000,0 ; MODE 9 -VLN_10 VIDC_List 3, 38, 44, 48, 320, 48, 14, 3,19,16,256,16, 2, 8000,0 ; MODE 10 -VLN_11 VIDC_List 1, 76, 88, 96, 640, 96, 28, 3,19,19,250,19, 2,16000,0 ; MODE 11 -VLN_12 VIDC_List 2, 76, 88, 96, 640, 96, 28, 3,19,16,256,16, 2,16000,0 ; MODE 12 -VLN_13 VIDC_List 3, 38, 44, 48, 320, 48, 14, 3,19,16,256,16, 2, 8000,0 ; MODE 13 -VLN_14 VIDC_List 2, 76, 88, 96, 640, 96, 28, 3,19,19,250,19, 2,16000,0 ; MODE 14 -VLN_15 VIDC_List 3, 76, 88, 96, 640, 96, 28, 3,19,16,256,16, 2,16000,0 ; MODE 15 -VLN_16 VIDC_List 2,114,132, 96,1056, 96, 42, 3,19,16,256,16, 2,24000,0 ; MODE 16 -VLN_17 VIDC_List 2,114,132, 96,1056, 96, 42, 3,19,19,250,19, 2,24000,0 ; MODE 17 -VLN_22 VIDC_List 2, 76,120, 0, 768, 0, 60, 3,19, 0,288, 0, 2,16000,0 ; MODE 22 -VLN_24 VIDC_List 3,114,132, 96,1056, 96, 42, 3,19,16,256,16, 2,24000,0 ; MODE 24 -VLN_33 VIDC_List 0, 76,120, 0, 768, 0, 60, 3,19, 0,288, 0, 2,16000,0 ; MODE 33 -VLN_34 VIDC_List 1, 76,120, 0, 768, 0, 60, 3,19, 0,288, 0, 2,16000,0 ; MODE 34 -VLN_35 VIDC_List 2, 76,120, 0, 768, 0, 60, 3,19, 0,288, 0, 2,16000,0 ; MODE 35 -VLN_36 VIDC_List 3, 76,120, 0, 768, 0, 60, 3,19, 0,288, 0, 2,16000,0 ; MODE 36 - -VLM_0 VIDC_List 0, 72, 62, 88, 640, 88, 74, 3,16,17,256,17, 3,16000,0 ; MODE 0 -VLM_1 VIDC_List 1, 36, 30, 44, 320, 44, 38, 3,16,17,256,17, 3, 8000,0 ; MODE 1 -VLM_2 VIDC_List 2, 36, 30, 44, 320, 44, 38, 3,16,17,256,17, 3, 8000,0 ; MODE 2 -VLM_3 VIDC_List 1, 72, 62, 88, 640, 88, 74, 3,16,20,250,20, 3,16000,0 ; MODE 3 -VLM_4 VIDC_List 0, 72, 62, 88, 640, 88, 74, 3,16,17,256,17, 3,16000,0 ; MODE 4 -VLM_5 VIDC_List 1, 36, 30, 44, 320, 44, 38, 3,16,17,256,17, 3, 8000,0 ; MODE 5 -VLM_6 VIDC_List 1, 36, 30, 44, 320, 44, 38, 3,16,20,250,20, 3, 8000,0 ; MODE 6 - [ TTX256 - ASSERT HiResTTX -VLM_7 VIDC_List 3, 56,112, 0, 640, 0, 88, 3,18, 6,500, 6, 1,24000,0 ; MODE 7 - | - [ HiResTTX -VLM_7 VIDC_List 2, 56,112, 0, 640, 0, 88, 3,18, 6,500, 6, 1,24000,0 ; MODE 7 - | -VLM_7 VIDC_List 2, 36, 30, 44, 320, 44, 38, 3,16,20,250,20, 3, 8000,0 ; MODE 7 - ] - ] -VLM_8 VIDC_List 1, 72, 62, 88, 640, 88, 74, 3,16,17,256,17, 3,16000,0 ; MODE 8 -VLM_9 VIDC_List 2, 36, 30, 44, 320, 44, 38, 3,16,17,256,17, 3, 8000,0 ; MODE 9 -VLM_10 VIDC_List 3, 36, 30, 44, 320, 44, 38, 3,16,17,256,17, 3, 8000,0 ; MODE 10 -VLM_11 VIDC_List 1, 72, 62, 88, 640, 88, 74, 3,16,20,250,20, 3,16000,0 ; MODE 11 -VLM_12 VIDC_List 2, 72, 62, 88, 640, 88, 74, 3,16,17,256,17, 3,16000,0 ; MODE 12 -VLM_13 VIDC_List 3, 36, 30, 44, 320, 44, 38, 3,16,17,256,17, 3, 8000,0 ; MODE 13 -VLM_14 VIDC_List 2, 72, 62, 88, 640, 88, 74, 3,16,20,250,20, 3,16000,0 ; MODE 14 -VLM_15 VIDC_List 3, 72, 62, 88, 640, 88, 74, 3,16,17,256,17, 3,16000,0 ; MODE 15 -VLM_16 VIDC_List 2,108, 72,106,1056,106, 88, 3,16,17,256,17, 3,24000,0 ; MODE 16 -VLM_17 VIDC_List 2,108, 72,106,1056,106, 88, 3,16,20,250,20, 3,24000,0 ; MODE 17 -VLM_18 VIDC_List 0, 56,112, 0, 640, 0, 88, 3,18, 0,512, 0, 1,24000,0 ; MODE 18 -VLM_19 VIDC_List 1, 56,112, 0, 640, 0, 88, 3,18, 0,512, 0, 1,24000,0 ; MODE 19 -VLM_20 VIDC_List 2, 56,112, 0, 640, 0, 88, 3,18, 0,512, 0, 1,24000,0 ; MODE 20 -VLM_21 VIDC_List 3, 56,112, 0, 640, 0, 88, 3,18, 0,512, 0, 1,24000,0 ; MODE 21 -VLM_22 VIDC_List 2, 76, 82, 0, 768, 0, 98, 3,19, 0,288, 0, 2,16000,0 ; MODE 22 -VLM_24 VIDC_List 3,108, 72,106,1056,106, 88, 3,16,17,256,17, 3,24000,0 ; MODE 24 -VLM_25 VIDC_List 0, 96, 46, 0, 640, 0, 18, 2,32, 0,480, 0,11,25175,3 ; MODE 25 -VLM_26 VIDC_List 1, 96, 46, 0, 640, 0, 18, 2,32, 0,480, 0,11,25175,3 ; MODE 26 -VLM_27 VIDC_List 2, 96, 46, 0, 640, 0, 18, 2,32, 0,480, 0,11,25175,3 ; MODE 27 -VLM_28 VIDC_List 3, 96, 46, 0, 640, 0, 18, 2,32, 0,480, 0,11,25175,3 ; MODE 28 -VLM_29 VIDC_List 0, 72,128, 0, 800, 0, 24, 2,22, 0,600, 0, 1,36000,0 ; MODE 29 -VLM_30 VIDC_List 1, 72,128, 0, 800, 0, 24, 2,22, 0,600, 0, 1,36000,0 ; MODE 30 -VLM_31 VIDC_List 2, 72,128, 0, 800, 0, 24, 2,22, 0,600, 0, 1,36000,0 ; MODE 31 - -VLM_33 VIDC_List 0, 76,82, 0, 768, 0, 98, 3,19, 0,288, 0, 2,16000,0 ; MODE 33 -VLM_34 VIDC_List 1, 76,82, 0, 768, 0, 98, 3,19, 0,288, 0, 2,16000,0 ; MODE 34 -VLM_35 VIDC_List 2, 76,82, 0, 768, 0, 98, 3,19, 0,288, 0, 2,16000,0 ; MODE 35 -VLM_36 VIDC_List 3, 76,82, 0, 768, 0, 98, 3,19, 0,288, 0, 2,16000,0 ; MODE 36 - -VLM_37 VIDC_List 0,118, 58, 0, 896, 0, 28, 3, 9, 0,352, 0, 0,24000,2 ; DTP 896x352 -VLM_38 VIDC_List 1,118, 58, 0, 896, 0, 28, 3, 9, 0,352, 0, 0,24000,2 ; EGA std -VLM_39 VIDC_List 2,118, 58, 0, 896, 0, 28, 3, 9, 0,352, 0, 0,24000,2 -VLM_40 VIDC_List 3,118, 58, 0, 896, 0, 28, 3, 9, 0,352, 0, 0,24000,2 - -VLM_41 VIDC_List 0, 76, 36, 0, 640, 0, 16, 3, 9, 0,352, 0, 0,16783,2 ; EGA -VLM_42 VIDC_List 1, 76, 36, 0, 640, 0, 16, 3, 9, 0,352, 0, 0,16783,2 -VLM_43 VIDC_List 2, 76, 36, 0, 640, 0, 16, 3, 9, 0,352, 0, 0,16783,2 - -VLM_44 VIDC_List 0, 72,162, 0, 640, 0,146, 3,34, 0,200, 0,25,16000,0 ; CGA -VLM_45 VIDC_List 1, 72,162, 0, 640, 0,146, 3,34, 0,200, 0,25,16000,0 -VLM_46 VIDC_List 2, 72,162, 0, 640, 0,146, 3,34, 0,200, 0,25,16000,0 - -VLM_47 VIDC_List 3, 64, 62, 0, 360, 0, 46, 2,32, 0,480, 0,11,16783,3 ; PC Soft - -VLM_48 VIDC_List 2, 48, 22, 0, 320, 0, 10, 2,32, 0,480, 0,11,12587,3 ; Games mode -VLM_49 VIDC_List 3, 48, 22, 0, 320, 0, 10, 2,32, 0,480, 0,11,12587,3 ; Games mode - -; New modes for VIDC20 - -VLM_32 VIDC_List 3, 72,128, 0, 800, 0, 24, 2,22, 0,600, 0, 1,36000,0 ; MODE 32 (800 x 600 x 8bpp) - - -VLH_23 VIDC_List 2, 52, 46, 2, 288, 2, 2, 3,43, 4,896, 4, 0,24000,0 ; MODE 23 - -VgaX_0 VIDC_List 0, 96, 46, 0, 640, 0,18, 2,106,0,256, 0,85,25175,2 ; TV modes in VGA_350) -VgaX_1 VIDC_List 1, 48, 22, 0, 320, 0,10, 2,106,0,256, 0,85,12587,2 -VgaX_2 VIDC_List 2, 48, 22, 0, 320, 0,10, 2,106,0,256, 0,85,12587,2 -VgaX_3 VIDC_List 1, 96, 46, 0, 640, 0,18, 2,109,0,250, 0,88,25175,2 -VgaX_4 VIDC_List 0, 96, 46, 0, 640, 0,18, 2,106,0,256, 0,85,25175,2 -VgaX_5 VIDC_List 1, 48, 22, 0, 320, 0,10, 2,106,0,256, 0,85,12587,2 -VgaX_6 VIDC_List 1, 48, 22, 0, 320, 0,10, 2,109,0,250, 0,88,12587,2 -VgaX_7 VIDC_List 2, 48, 22, 0, 320, 0,10, 2,109,0,250, 0,88,12587,2 -VgaX_8 VIDC_List 1, 96, 46, 0, 640, 0,18, 2,106,0,256, 0,85,25175,2 -VgaX_9 VIDC_List 2, 48, 22, 0, 320, 0,10, 2,106,0,256, 0,85,12587,2 -VgaX_10 VIDC_List 3, 48, 22, 0, 320, 0,10, 2,106,0,256, 0,85,12587,2 -VgaX_11 VIDC_List 1, 96, 46, 0, 640, 0,18, 2,109,0,250, 0,88,25175,2 -VgaX_12 VIDC_List 2, 96, 46, 0, 640, 0,18, 2,106,0,256, 0,85,25175,2 -VgaX_13 VIDC_List 3, 48, 22, 0, 320, 0,10, 2,106,0,256, 0,85,12587,2 -VgaX_14 VIDC_List 2, 96, 46, 0, 640, 0,18, 2,109,0,250, 0,88,25175,2 -VgaX_15 VIDC_List 3, 96, 46, 0, 640, 0,18, 2,106,0,256, 0,85,25175,2 - -VgaX_41 VIDC_List 0, 96, 46, 0, 640, 0,18, 2,58, 0,352, 0,37,25175,2 ; EGA -VgaX_42 VIDC_List 1, 96, 46, 0, 640, 0,18, 2,58, 0,352, 0,37,25175,2 -VgaX_43 VIDC_List 2, 96, 46, 0, 640, 0,18, 2,58, 0,352, 0,37,25175,2 - -VgaX_44 VIDC_List 0, 96, 46, 0, 640, 0,18,2,134, 0,200,0,113,25175,2 ; CGA -VgaX_45 VIDC_List 1, 96, 46, 0, 640, 0,18,2,134, 0,200,0,113,25175,2 -VgaX_46 VIDC_List 2, 96, 46, 0, 640, 0,18,2,134, 0,200,0,113,25175,2 - -LCD_25 VIDC_List 0, 8, 32, 0, 640, 0,16,1, 0, 0,480,0, 0,27000,0 -LCD_26 VIDC_List 1, 8, 32, 0, 640, 0,16,1, 0, 0,480,0, 0,27000,0 -LCD_27 VIDC_List 2, 8, 32, 0, 640, 0,16,1, 0, 0,480,0, 0,27000,0 -LCD_28 VIDC_List 3, 8, 32, 0, 640, 0,16,1, 0, 0,480,0, 0,27000,0 - - [ ModeSelectors - -; Table of ideal frame rate for each numbered mode, to put in dummy mode selector -; if numbered mode number is not directly available on this monitortype - - -FrameRateTable - [ HiResTTX - = F_VLN_0, F_VLN_1, F_VLN_2, F_VLN_3, F_VLN_4, F_VLN_5, F_VLN_6, F_VLM_7 - | - = F_VLN_0, F_VLN_1, F_VLN_2, F_VLN_3, F_VLN_4, F_VLN_5, F_VLN_6, F_VLN_7 - ] - = F_VLN_8, F_VLN_9, F_VLN_10, F_VLN_11, F_VLN_12, F_VLN_13, F_VLN_14, F_VLN_15 - = F_VLN_16, F_VLN_17, F_VLM_18, F_VLM_19, F_VLM_20, F_VLM_21, F_VLN_22, F_VLH_23 - = F_VLN_24, F_VLM_25, F_VLM_26, F_VLM_27, F_VLM_28, F_VLM_29, F_VLM_30, F_VLM_31 - = F_VLM_32, F_VLN_33, F_VLN_34, F_VLN_35, F_VLN_36, F_VLM_37, F_VLM_38, F_VLM_39 - = F_VLM_40, F_VLM_41, F_VLM_42, F_VLM_43, F_VLM_44, F_VLM_45, F_VLM_46, F_VLM_47 - = F_VLM_48, F_VLM_49 - ASSERT . - FrameRateTable = NumModes - ALIGN - - ] - -Vwstab - & VW_0 - Vwstab ; MODE 0 - & VW_1 - Vwstab ; MODE 1 - & VW_2 - Vwstab ; MODE 2 - & VW_3 - Vwstab ; MODE 3 - & VW_4 - Vwstab ; MODE 4 - & VW_5 - Vwstab ; MODE 5 - & VW_6 - Vwstab ; MODE 6 - & VW_7 - Vwstab ; MODE 7 - & VW_8 - Vwstab ; MODE 8 - & VW_9 - Vwstab ; MODE 9 - & VW_10 - Vwstab ; MODE 10 - & VW_11 - Vwstab ; MODE 11 - & VW_12 - Vwstab ; MODE 12 - & VW_13 - Vwstab ; MODE 13 - & VW_14 - Vwstab ; MODE 14 - & VW_15 - Vwstab ; MODE 15 - & VW_16 - Vwstab ; MODE 16 - & VW_17 - Vwstab ; MODE 17 - & VW_18 - Vwstab ; MODE 18 - & VW_19 - Vwstab ; MODE 19 - & VW_20 - Vwstab ; MODE 20 - & VW_21 - Vwstab ; MODE 21 - & VW_22 - Vwstab ; MODE 22 (new mode for visually handicapped) - & VW_23 - Vwstab ; MODE 23 - & VW_24 - Vwstab ; MODE 24 - & VW_25 - Vwstab ; MODE 25 - & VW_26 - Vwstab ; MODE 26 - & VW_27 - Vwstab ; MODE 27 - & VW_28 - Vwstab ; MODE 28 - & VW_29 - Vwstab ; MODE 29 exp - & VW_30 - Vwstab ; MODE 30 exp - & VW_31 - Vwstab ; MODE 31 - & VW_32 - Vwstab ; MODE 32 - & VW_33 - Vwstab ; MODE 33 - & VW_34 - Vwstab ; MODE 34 - & VW_35 - Vwstab ; MODE 35 - & VW_36 - Vwstab ; MODE 36 - & VW_37 - Vwstab ; MODE 37 - & VW_38 - Vwstab ; MODE 38 - & VW_39 - Vwstab ; MODE 39 - & VW_40 - Vwstab ; MODE 40 - & VW_41 - Vwstab ; MODE 41 - & VW_42 - Vwstab ; MODE 42 - & VW_43 - Vwstab ; MODE 43 - & VW_44 - Vwstab ; MODE 44 - & VW_45 - Vwstab ; MODE 45 - & VW_46 - Vwstab ; MODE 46 - & VW_47 - Vwstab ; MODE 47 - & VW_48 - Vwstab ; MODE 48 - & VW_49 - Vwstab ; MODE 49 - -; To change the order of mode variables, change the following:- -; a) The order of the 'wk' labels below -; b) The order of the output variables in macro VWSTAB below -; c) The order of the variables in '$.Hdr.Workspace' and '$.Hdr.NewSpace' - - ^ 0 -wkstart # 0 -wkScreenSize # 4 -wkXWindLimit # 4 -wkYWindLimit # 4 -wkLineLength # 4 -wkNColour # 4 ; DDV; defined to be a word (17-Sep-92) -wkmiddle # 0 -wkYShftFactor # 4 -wkModeFlags # 4 -wkXEigFactor # 4 -wkYEigFactor # 4 -wkLog2BPC # 4 -wkLog2BPP # 4 -wkECFIndex # 4 -wkmidend # 0 -wkScrRCol # 4 -wkScrBRow # 4 -wkdispstart # 0 -wkPalIndex # 4 -wkend # 0 -wksize * wkend-wkstart -wkwordsize * (wksize + 3) :AND: :NOT: 3 -wklim * wksize-(wkmiddle-wkstart) - -;VIDC list type 3 size (hardware independent video controller list) -; -VIDCList3Size * (64 + 16*8 + 4) ; primary params, up to 16 video control params, terminator - -PushedInfoSize * wkwordsize + VIDCList3Size - -M22S * 1280*976/8 ; screen size -M23S * 1152*896/8 -M25S * 640*480/8 -M31S * 800*600/8 -M37S * 896*352/8 -M41S * 640*352/8 -M44S * 640*200/8 -M47S * 360*480/8 - - MACRO -$label VWSTAB1 $BaseMode, $ScreenSize,$LineLength,$XWindLimit,$YWindLimit,$YShftFactor, $XEigFactor,$YEigFactor,$NColour,$ScrRCol,$ScrBRow,$Log2BPC,$Log2BPP,$PalIndex, $ECFIndex,$ModeFlags -$label - LCLS ScrSize - LCLA xres - LCLA yres - LCLA pixdepth - LCLA yeig - LCLA scrsz - [ ("$ScreenSize" :RIGHT: 1) = "K" -ScrSize SETS ("$ScreenSize" :LEFT: ((:LEN: "$ScreenSize")-1)) -scrsz SETA $ScrSize * 1024 - | -scrsz SETA $ScreenSize - ] - & scrsz - & $XWindLimit, $YWindLimit, $LineLength, $NColour - & $YShftFactor, $ModeFlags, $XEigFactor, $YEigFactor - & $Log2BPC, $Log2BPP, $ECFIndex - & $ScrRCol, $ScrBRow, $PalIndex - ALIGN - [ MakeModeSelectorsForModeNumbers -xres SETA (($XWindLimit+1):SHL:($Log2BPC)):SHR:($Log2BPP) -yres SETA ($YWindLimit)+1 -pixdepth SETA $Log2BPP - [ yres < xres/2 -yeig SETA 2 - | -yeig SETA 1 - ] - -ModeSelector_$label - & 1, xres, yres, pixdepth - & -1 ; frame rate (is this going to be OK?) - [ {FALSE} ; don't need any of this stuff - we're only getting the VIDC stuff via this mechanism - [ ($ModeFlags)<>0 - & VduExt_ModeFlags, $ModeFlags - ] - [ ($ScrRCol) <> (xres :SHR: 3)-1 - & VduExt_ScrRCol, $ScrRCol - ] - [ ($ScrBRow) <> (yres :SHR: 3)-1 - & VduExt_ScrBRow, $ScrBRow - ] - [ ($NColour) <> NColour_$Log2BPP - & VduExt_NColour, $NColour - ] - [ ($XEigFactor) <> 1 - & VduExt_XEigFactor, $XEigFactor - ] - [ ($YEigFactor) <> yeig - & VduExt_YEigFactor, $YEigFactor - ] - [ ($LineLength) <> (xres :SHL: pixdepth) :SHR: 3 - & VduExt_LineLength, $LineLength - ] - [ scrsz <> ((xres * yres) :SHL: pixdepth) :SHR: 3 - & VduExt_ScreenSize, scrsz - ] - [ ($Log2BPC) <> pixdepth - & VduExt_Log2BPC, $Log2BPC - ] - ] - & -1 ; terminator - ] - MEND - - MACRO -$label VWSTAB2 $BaseMode, $ScreenSize,$LineLength,$XWindLimit,$YWindLimit,$YShftFactor, $XEigFactor,$YEigFactor,$NColour,$ScrRCol,$ScrBRow,$Log2BPC,$Log2BPP,$PalIndex, $ECFIndex,$ModeFlags -$label - LCLS ScrSize - & 0 ; wslist type (default) - & $BaseMode - [ ("$ScreenSize" :RIGHT: 1) = "K" -ScrSize SETS ("$ScreenSize" :LEFT: ((:LEN: "$ScreenSize")-1)) - & VduExt_ScreenSize, $ScrSize * 1024 - | - & VduExt_ScreenSize, $ScreenSize - ] - & VduExt_LineLength, $LineLength - & VduExt_XWindLimit, $XWindLimit - & VduExt_YWindLimit, $YWindLimit - & VduExt_YShftFactor, $YShftFactor - & VduExt_XEigFactor, $XEigFactor - & VduExt_YEigFactor, $YEigFactor - & VduExt_NColour, $NColour - & VduExt_ScrRCol, $ScrRCol - & VduExt_ScrBRow, $ScrBRow - & VduExt_Log2BPC, $Log2BPC - & VduExt_Log2BPP, $Log2BPP - & VduExt_ModeFlags, $ModeFlags - & -1 - MEND - - MACRO -$label VWSTAB $BaseMode, $ScreenSize,$LineLength,$XWindLimit,$YWindLimit,$YShftFactor, $XEigFactor,$YEigFactor,$NColour,$ScrRCol,$ScrBRow,$Log2BPC,$Log2BPP,$PalIndex, $ECFIndex,$ModeFlags - [ AssemblingArthur -$label VWSTAB1 $BaseMode, $ScreenSize,$LineLength,$XWindLimit,$YWindLimit,$YShftFactor, $XEigFactor,$YEigFactor,$NColour,$ScrRCol,$ScrBRow,$Log2BPC,$Log2BPP,$PalIndex, $ECFIndex,$ModeFlags - | -$label VWSTAB2 $BaseMode, $ScreenSize,$LineLength,$XWindLimit,$YWindLimit,$YShftFactor, $XEigFactor,$YEigFactor,$NColour,$ScrRCol,$ScrBRow,$Log2BPC,$Log2BPP,$PalIndex, $ECFIndex,$ModeFlags - ] - MEND - -VW_0 VWSTAB 0, 20K, 80, 639,255,4,1,2, 1, 79, 31,0,0,0,1,0 ; MODE 0 -VW_1 VWSTAB 1, 20K, 80, 319,255,4,2,2, 3, 39, 31,1,1,1,2,0 ; MODE 1 -VW_2 VWSTAB 2, 40K,160, 159,255,5,3,2,15, 19, 31,3,2,2,3,0 ; MODE 2 -VW_3 VWSTAB 3, 40K,160, 639,249,5,1,2, 1, 79, 24,1,1,0,0,Flag_NonGraphic+Flag_GapMode+Flag_BBCGapMode ; MODE 3 -VW_4 VWSTAB 4, 20K, 80, 319,255,4,2,2, 1, 39, 31,1,0,0,4,0 ; MODE 4 -VW_5 VWSTAB 5, 20K, 80, 159,255,4,3,2, 3, 19, 31,2,1,1,2,0 ; MODE 5 -VW_6 VWSTAB 6, 20K, 80, 319,249,4,2,2, 1, 39, 24,1,1,0,0,Flag_NonGraphic+Flag_GapMode+Flag_BBCGapMode ; MODE 6 - [ TTX256 - ASSERT HiResTTX -VW_7 VWSTAB 7,640K,640, 639,499,5,1,1,63, 39, 24,3,3,4,0,Flag_NonGraphic+Flag_GapMode+Flag_Teletext+Flag_DoubleVertical ; MODE 7 - | - [ HiResTTX -VW_7 VWSTAB 7,320K,320, 639,499,5,1,1,15, 39, 24,2,2,4,0,Flag_NonGraphic+Flag_GapMode+Flag_Teletext+Flag_DoubleVertical ; MODE 7 - | -VW_7 VWSTAB 7, 80K,160, 319,249,5,2,2,15, 39, 24,2,2,4,0,Flag_NonGraphic+Flag_GapMode+Flag_Teletext ; MODE 7 - ] - ] -VW_8 VWSTAB 8, 40K,160, 639,255,5,1,2, 3, 79, 31,1,1,1,2,0 ; MODE 8 -VW_9 VWSTAB 9, 40K,160, 319,255,5,2,2,15, 39, 31,2,2,2,3,0 ; MODE 9 -VW_10 VWSTAB 10, 80K,320, 159,255,6,3,2,63, 19, 31,4,3,3,5,0 ; MODE 10 -VW_11 VWSTAB 11, 40K,160, 639,249,5,1,2, 3, 79, 24,1,1,1,2,Flag_GapMode ; MODE 11 -VW_12 VWSTAB 12, 80K,320, 639,255,6,1,2,15, 79, 31,2,2,2,3,0 ; MODE 12 -VW_13 VWSTAB 13, 80K,320, 319,255,6,2,2,63, 39, 31,3,3,3,5,0 ; MODE 13 -VW_14 VWSTAB 14, 80K,320, 639,249,6,1,2,15, 79, 24,2,2,2,3,Flag_GapMode ; MODE 14 -VW_15 VWSTAB 15,160K,640, 639,255,7,1,2,63, 79, 31,3,3,3,5,0 ; MODE 15 -VW_16 VWSTAB 16,132K,528,1055,255,0,1,2,15,131, 31,2,2,2,3,0 ; MODE 16 -VW_17 VWSTAB 17,132K,528,1055,249,0,1,2,15,131, 24,2,2,2,3,Flag_GapMode ; MODE 17 -VW_18 VWSTAB 18, 40K, 80, 639,511,4,1,1, 1, 79, 63,0,0,0,4,0 ; MODE 18 -VW_19 VWSTAB 19, 80K,160, 639,511,5,1,1, 3, 79, 63,1,1,1,2,0 ; MODE 19 -VW_20 VWSTAB 20,160K,320, 639,511,6,1,1,15, 79, 63,2,2,2,3,0 ; MODE 20 -VW_21 VWSTAB 21,320K,640, 639,511,7,1,1,63, 79, 63,3,3,3,5,0 ; MODE 21 -VW_22 VWSTAB 22,108K,384, 767,287,0,0,1,15, 95, 35,2,2,2,3,0 ; MODE 22 -VW_23 VWSTAB 23,M23S,144,1151,895,0,1,1, 1,143, 55,0,0,5,4,Flag_HiResMono+Flag_DoubleVertical ; MODE 23 -VW_24 VWSTAB 24,264K,1056,1055,255,0,1,2,63,131,31,3,3,3,5,0 ; MODE 24 -VW_25 VWSTAB 25,M25S , 80, 639,479,4,1,1, 1, 79, 59,0,0,0,4,0 ; MODE 25 -VW_26 VWSTAB 26,M25S*2,160, 639,479,5,1,1, 3, 79, 59,1,1,1,2,0 ; MODE 26 -VW_27 VWSTAB 27,M25S*4,320, 639,479,6,1,1,15, 79, 59,2,2,2,3,0 ; MODE 27 -VW_28 VWSTAB 28,M25S*8,640, 639,479,7,1,1,63, 79, 59,3,3,3,5,0 ; MODE 28 - -VW_29 VWSTAB 29,M31S ,100, 799,599,0,1,1, 1, 99, 74,0,0,0,4,0 ; MODE 29 -VW_30 VWSTAB 30,M31S*2,200, 799,599,0,1,1, 3, 99, 74,1,1,1,2,0 ; MODE 30 -VW_31 VWSTAB 31,M31S*4,400, 799,599,0,1,1,15, 99, 74,2,2,2,3,0 ; MODE 31 -VW_32 VWSTAB 32,M31S*8,800, 799,599,0,1,1,63, 99, 74,3,3,3,5,0 ; MODE 32 - -VW_33 VWSTAB 33, 27K, 96, 767,287,0,1,2, 1, 95, 35,0,0,0,4,0 ; MODE 33 -VW_34 VWSTAB 34, 54K,192, 767,287,0,1,2, 3, 95, 35,1,1,1,2,0 ; MODE 34 -VW_35 VWSTAB 35,108K,384, 767,287,0,1,2,15, 95, 35,2,2,2,3,0 ; MODE 35 -VW_36 VWSTAB 36,216K,768, 767,287,0,1,2,63, 95, 35,3,3,3,5,0 ; MODE 36 - -VW_37 VWSTAB 37,M37S ,112, 895,351,0,1,2, 1,111, 43,0,0,0,4,0 ; MODE 37 -VW_38 VWSTAB 38,M37S*2,224, 895,351,0,1,2, 3,111, 43,1,1,1,2,0 ; MODE 38 -VW_39 VWSTAB 39,M37S*4,448, 895,351,0,1,2,15,111, 43,2,2,2,3,0 ; MODE 39 -VW_40 VWSTAB 40,M37S*8,896, 895,351,0,1,2,63,111, 43,3,3,3,5,0 ; MODE 40 - -VW_41 VWSTAB 41,M41S , 80, 639,351,0,1,2, 1, 79, 43,0,0,0,4,0 ; EGA 1,2,4bpp -VW_42 VWSTAB 42,M41S*2,160, 639,351,0,1,2, 3, 79, 43,1,1,1,2,0 ; -VW_43 VWSTAB 43,M41S*4,320, 639,351,0,1,2,15, 79, 43,2,2,2,3,0 ; 640x352 - -VW_44 VWSTAB 44,M44S , 80, 639,199,0,1,2, 1, 79, 24,0,0,0,4,0 ; CGA 1,2,4bpp -VW_45 VWSTAB 45,M44S*2,160, 639,199,0,1,2, 3, 79, 24,1,1,1,2,0 ; -VW_46 VWSTAB 46,M44S*4,320, 639,199,0,1,2,15, 79, 24,2,2,2,3,0 ; 640x200 - -VW_47 VWSTAB 47,M47S*8,360, 359,479,0,2,2,63, 89, 59,3,3,3,5,0 ; PCSoft 360 x 480 x 8bpp -VW_48 VWSTAB 48, 75K,160, 319,479,0,2,1,15, 39, 59,2,2,2,3,0 ; Games 320 x 480 x 4bpp -VW_49 VWSTAB 49, 150K,320, 319,479,0,2,1,63, 39, 59,3,3,3,5,0 ; Games 320 x 480 x 8bpp - -; $BaseMode $YShftFactor $ScrBRow $ModeFlags -; $ScreenSize $XEigFactor $Log2BPC -; $LineLength $YEigFactor $Log2BPP -; $XWindLimit $NColour $PalIndex -; $YWindLimit $ScrRCol $ECFIndex - - [ MakeModeSelectorsForModeNumbers -ModeSelectorTable - GBLA modecount - GBLS h - GBLS l -modecount SETA 0 - ASSERT NumModes <= 100 - WHILE modecount < NumModes - [ modecount >= 10 -h SETS :CHR:(&30 + modecount/10) - | -h SETS "" - ] -l SETS :CHR:(&30 + modecount :MOD: 10) - & ModeSelector_VW_$h$l-ModeSelectorTable -modecount SETA modecount + 1 - WEND - - ! 0, "Mode selector table at ":CC: :STR: ModeSelectorTable - ] - - END diff --git a/s/vdu/vdupal10 b/s/vdu/vdupal10 deleted file mode 100644 index ecc07288..00000000 --- a/s/vdu/vdupal10 +++ /dev/null @@ -1,603 +0,0 @@ -; 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. -; -; > VduPal10 - -; mjs - not used any more (it's pre-Medusa, for goodness sake) - -; Palette programming for VIDC10 (ie VIDC1 or VIDC1a) - -; ***************************************************************************** - -; PaletteV handler -; ---------------- - -; ***************************************************************************** -; -; MOSPaletteV - Default owner of PaletteV -; - - ASSERT paletteV_Complete = 0 - ASSERT paletteV_Read = 1 - ASSERT paletteV_Set = 2 - ASSERT paletteV_1stFlashState = 3 - ASSERT paletteV_2ndFlashState = 4 - ASSERT paletteV_SetDefaultPalette = 5 - ASSERT paletteV_BlankScreen = 6 - -MOSPaletteV ROUT - CMP r4, #1 - MOVCC pc, lr - BEQ PV_ReadPalette - CMP r4, #3 - BCC PV_SetPalette - BEQ PV_1stFlashState - CMP r4, #5 - BCC PV_2ndFlashState - BEQ PV_SetDefaultPalette - CMP r4, #7 - BCC PV_BlankScreen - MOV pc, lr ; reason code not known, so pass it on - -; ***************************************************************************** - -PV_SetDefaultPalette ROUT - Push "r0-r3,r5-r9" - LDR r0, [WsPtr, #PalIndex] ; the new index 0-5 - ADR r1, paldptab - LDR r2, [r1, r0, LSL #2] ; offset from r1 to start of table - ADD r0, r0, #1 ; point to next item - LDR r5, [r1, r0, LSL #2] ; offset from r1 to end of table +1 - ADD r2, r2, r1 ; r2 -> start of table - ADD r5, r5, r1 ; r5 -> end of table - MOV r0, #0 ; start at palette index 0 - MOV r1, #3 ; set both halves -10 - LDR r6, [r2], #4 - MOVS r3, r6, LSL #17 ; get 1st half word and set carry if flashing - MOV r3, r3, LSR #17 - MOVCC r4, #0 - LDRCS r4, =&FFF ; flashing so invert 2nd half RGB - BL UpdateSettingStraightRGB - ADD r0, r0, #1 - MOVS r3, r6, LSL #1 ; get 2nd half word and set carry if flashing - MOV r3, r3, LSR #17 - MOVCC r4, #0 - LDRCS r4, =&FFF - BL UpdateSettingStraightRGB - ADD r0, r0, #1 - TEQ r2, r5 - BNE %BT10 - -; now ensure all palette entries from 0..15 are initialised - - MOV r3, #0 ; set unused (and border) to black - MOV r4, #0 ; no flashing -20 - CMP r0, #16 - BHS %FT25 - BL UpdateSettingStraightRGB - ADD r0, r0, #1 - B %BT20 - -25 MOV r2, #0 ; Set border to black (sup 0) - BL BorderInitEntry - - MOV r4, #0 ; indicate PaletteV operation complete - Pull "r0-r3,r5-r9,pc" ; restore registers and claim vector - - LTORG - -; ***************************************************************************** - -; Table of offsets from paldata_pointer to palette data - -paldptab - & paldat1-paldptab ; 2 Colour Modes - & paldat2-paldptab ; 4 - & paldat4-paldptab ; 16 - & paldat8-paldptab ; 256 - & paldatT-paldptab ; teletext mode - & paldatHR-paldptab ; Hi-res mono mode - & paldatend-paldptab ; end of table marker - -paldat1 ; Data for 1 bit modes - only necessary to program registers 0 and 1 - -; FSBGR - - DCW &0000 ; 0 Black - DCW &0FFF ; 1 White - -paldat2 ; Data for 2 bit modes - only necessary to program registers 0..3 - -; FSBGR - - DCW &0000 ; 0 Black - DCW &000F ; 1 Red - DCW &00FF ; 2 Yellow - DCW &0FFF ; 3 White - -paldat4 ; Data for 4 bit modes - program all registers - ; Flashing Colours will be needed here - -; FSBGR - - DCW &0000 ; 0 Black - DCW &000F ; 1 Red - DCW &00F0 ; 2 Green - DCW &00FF ; 3 Yellow - DCW &0F00 ; 4 Blue - DCW &0F0F ; 5 Magenta - DCW &0FF0 ; 6 Cyan - DCW &0FFF ; 7 White - DCW &8000 ; 8 Flashing Black - DCW &800F ; 9 Flashing Red - DCW &80F0 ; 10 Flashing Green - DCW &80FF ; 11 Flashing Yellow - DCW &8F00 ; 12 Flashing Blue - DCW &8F0F ; 13 Flashing Magenta - DCW &8FF0 ; 14 Flashing Cyan - DCW &8FFF ; 15 Flashing White - -paldat8 ; Data for 8 bit modes - Program all registers - ; PP field is 16 for all these, cos not true BBC colours - -; FSBGR - - DCW &0000 ; 0 - DCW &0111 ; 1 - DCW &0222 ; 2 - DCW &0333 ; 3 - DCW &0004 ; 4 - DCW &0115 ; 5 - DCW &0226 ; 6 - DCW &0337 ; 7 - DCW &0400 ; 8 - DCW &0511 ; 9 - DCW &0622 ; A - DCW &0733 ; B - DCW &0404 ; C - DCW &0515 ; D - DCW &0626 ; E - DCW &0737 ; F - -paldatT ; Data for teletext mode - - DCW &0000 ; 0 Black - DCW &000F ; 1 Red - DCW &00F0 ; 2 Green - DCW &00FF ; 3 Yellow - DCW &0F00 ; 4 Blue - DCW &0F0F ; 5 Magenta - DCW &0FF0 ; 6 Cyan - DCW &0FFF ; 7 White - -; Colours 8 to 15 have supremacy bit set - - DCW &1000 ; 8 Supremacy+ Black - DCW &100F ; 9 Red - DCW &10F0 ; 10 Green - DCW &10FF ; 11 Yellow - DCW &1F00 ; 12 Blue - DCW &1F0F ; 13 Magenta - DCW &1FF0 ; 14 Cyan - DCW &1FFF ; 15 White - -paldatHR ; data for Hi-res mono mode - DCW &0000 ; Only red gun necessary - DCW &0111 ; but setting all three makes - DCW &0222 ; reading it more natural - DCW &0333 - DCW &0444 - DCW &0555 - DCW &0666 - DCW &0777 - DCW &0888 - DCW &0999 - DCW &0AAA - DCW &0BBB - DCW &0CCC - DCW &0DDD - DCW &0EEE - DCW &0FFF - - DCW &0000 ; border black - DCW &0010 ; fixed pointer colours - DCW &0020 - DCW &0030 -paldatend - - -; ***************************************************************************** - -; PaletteV call to set palette -; in: R0 = logical colour -; R1 = colour type (16,17,18,24,25) -; R2 = BBGGRRS0 -; R4 = PaletteV reason code -; -; out: R4 = 0, claim vector if recognised -; otherwise preserve R4 and pass on -; - -PV_SetPalette ROUT - Push "r0-r3" - TEQ r1, #16 ; if 16 then set both colours - MOVEQ r1, #3 - BEQ UpdateNormalColour - - TEQ r1, #17 ; elif 17 then set 1st colour - MOVEQ r1, #1 - BEQ UpdateNormalColour - - TEQ r1, #18 ; elif 18 then set 2nd colour - MOVEQ r1, #2 - BEQ UpdateNormalColour - - TEQ r1, #24 ; elif 24 then border colour - BEQ BorderColour - - TEQ r1, #25 ; elif 25 then pointer colour - BEQ PointerColour - - Pull "r0-r3" - MOV pc, lr ; else not defined - -; ***************************************************************************** - -UpdateNormalColour ROUT - LDR lr, [WsPtr, #DisplayNColour] ; get the mask - AND r0, r0, lr ; and mask it off - AND r0, r0, #15 ; maximum 15 - BL UpdateSettingAndVIDC - MOV r4, #0 ; indicate successful PaletteV op - Pull "r0-r3, pc" - -BorderInitEntry ENTRY "r0-r3" ; entry used in default palette setting -BorderColour ROUT - LDR r0, [WsPtr, #PalIndex] ; if hi res mono - TEQ r0, #5 - BICEQ r2, r2, #&00300000 ; then knock out bits 0,1 of green palette - - MOV r0, #16 ; palette index for border colour - MOV r1, #3 ; both colours - BL UpdateSettingAndVIDC - -; Now test for BBC gap mode (ie 3 or 6) -; if so then set colour 2 to same as border, and colour 3 to inverse - - LDR lr, [WsPtr, #DisplayModeFlags] - TST lr, #Flag_BBCGapMode - BEQ %FT10 - - MOV r0, #2 ; make colour 2 (gap) same as border - BL UpdateSettingAndVIDC - - MOV r0, #3 ; make colour 3 inverse gap - MVN r2, r2 ; invert R, G and B - EOR r2, r2, #&FF ; but use same supremacy - BL UpdateSettingAndVIDC -10 - MOV r4, #0 ; indicate successful PaletteV op - Pull "r0-r3, pc" - - -PointerColour ROUT - LDR r1, [WsPtr, #PalIndex] ; if hi res mono, then don't allow - TEQ r1, #5 ; pointer palette changes - ANDNES r0, r0, #3 ; force pointer colour number in range 1..3 - BEQ %FT10 ; zero is invalid - ADD r0, r0, #16 ; form palette index 17..19 - MOV r1, #3 - BL UpdateSettingAndVIDC -10 - MOV r4, #0 ; indicate successful PaletteV op - Pull "r0-r3,pc" - -UpdateSettingAndVIDC ROUT - AND r4, r2, #&F0000000 - MOV r3, r4, LSR #(28-8) ; move blue to bits 8..11 - AND r4, r2, #&00F00000 - ORR r3, r3, r4, LSR #(20-4) ; move green to bits 4..7 - AND r4, r2, #&0000F000 - ORR r3, r3, r4, LSR #(12-0) ; move red to bits 0..3 - AND r4, r2, #&00000080 - ORR r3, r3, r4, LSL #(12-7) ; move sup to bit 12 - - CMP r0, #16 ; if not normal colour - BCS %FT10 ; then OK for hi-res-mono - LDR r4, [WsPtr, #PalIndex] - TEQ r4, #5 - BEQ UpdateHiResRGB -10 - MOV r4, #0 ; indicate no EORing between parts - -; and drop thru to ... - -UpdateSettingStraightRGB ENTRY "r2,r5,r6" - PHPSEI ; protect against IRQs - ORR r3, r3, r0, LSL #26 ; form VIDC register number at top - LDRB r5, [WsPtr, #ScreenBlankFlag] - TEQ r5, #0 - MOVNE r5, #&00FFFFFF ; bits to knock out if blanked - - LDROSB r2, FlashState ; 0 => second, 1 => first - CMP r2, #1 ; C=0 => second, C=1 => first - - TST r1, #1 - BEQ %FT10 ; skip if not setting 1st colour - ADD r2, WsPtr, #FirPalSetting - STR r3, [r2, r0, LSL #2] - MOVCS r2, #VIDC - BICCS r6, r3, r5 ; knock out bits for blanking - STRCS r6, [r2] ; poke VIDC if setting 1st colour and in 1st state -10 - TST r1, #2 - BEQ %FT20 ; skip if not setting 2nd colour - ADD r2, WsPtr, #SecPalSetting - EOR r3, r3, r4 ; toggle requested bits for 2nd half - STR r3, [r2, r0, LSL #2] - MOVCC r2, #VIDC - BICCC r6, r3, r5 ; knock out bits for blanking - STRCC r6, [r2] ; poke VIDC if setting 2nd colour and in 2nd state -20 - PLP - EXIT ; restore registers, claim vector - -; ***************************************************************************** -; -; UpdateHiResRGB - Routine to program normal palette for Hi-Res-Mono display -; -; in: r0 = logical colour -; r1 = mask of which states to update (bit 0 = 1st flash state, bit 1 = 2nd) -; r3 = &0000SBGR -; -; out: r3, r4 may be corrupted -; - -UpdateHiResRGB ENTRY "r5" - PHPSEI - Push "lr" - LDROSB r5, FlashState - TEQ r5, #0 ; 0 => 2nd state, 1 => 1st state - MOVNE r5, #VIDC ; 1st state => r5 = VIDC, else = 0 - - TST r1, #1 - ADDNE r4, WsPtr, #FirPalSetting - BLNE UpdateOneHiResSetting - - EOR r5, r5, #VIDC ; 2nd state => r5 = VIDC, else = 0 - TST r1, #2 - ADDNE r4, WsPtr, #SecPalSetting - BLNE UpdateOneHiResSetting - Pull "lr" - PLP - EXIT - -UpdateOneHiResSetting ENTRY "r1,r2,r6-r9" - LDRB lr, [WsPtr, #ScreenBlankFlag] - TEQ lr, #0 - MOVNE lr, #&00FFFFFF ; if blanked, mask off these bits - - LDR r2, =&FFF - TEQ r0, #0 - MOVEQ r1, r3 ; if programming colour 0 then 1st colour is r3 - LDREQ r6, [r4, #15*4] ; and 2nd colour is what's in colour 15 - LDRNE r1, [r4, #0*4] ; else 1st colour is what's in colour 0 - MOVNE r6, r3 ; and 2nd colour is r3 - - EOR r6, r6, #&008 ; invert bit R3 of colour 15 - EOR r6, r6, r1 ; inverted EOR of colours 0 and 15 - ANDS r6, r6, #&008 ; just use R3 for black/white - MOVNE r6, r2 ; if non-zero make BIC mask full RGB else 0 - ANDS r1, r1, #&008 ; if colour 0 = white then make EOR mask full RGB else 0 - MOVNE r1, r2 - - ADD r7, r4, #16*4 ; end of table - MOV r8, #0 ; start - LDR r2, =&04000111 ; amount to add on each time round - -10 - BIC r9, r8, r6 ; take value and knock out BIC mask - EOR r9, r9, r1 ; then toggle EOR mask - STR r9, [r4], #4 ; store in soft copy - TEQ r5, #0 ; if updating VIDC - BICNE r9, r9, lr ; knock out bits (for blanking) - STRNE r9, [r5] ; then do it - ADD r8, r8, r2 ; move on to next value - TEQ r4, r7 ; if not done all 16 entries - BNE %BT10 ; then loop - - EXIT - - LTORG - -; ***************************************************************************** -; -; PV_ReadPalette - PaletteV read palette handler -; -; in: R0 = logical colour -; R1 = 16 (read normal colour) -; 24 (read border colour) -; 25 (read cursor colour) -; -; out: R2 = first flash setting (BBGGRRS0), supremacy bit 7 -; R3 = second flash setting (BBGGRRS0), supremacy bit 7 -; - -PV_ReadPalette ROUT - Push "r10,r11" - LDR r10, [WsPtr, #DisplayNColour] ; logical colours in this mode -1 - TEQ r1, #24 ; is it reading border palette - MOVEQ r11, #16 ; then set up border index - BEQ %FT10 ; and go - - TEQ r1, #25 ; is it reading pointer palette - BEQ %FT05 - AND r11, r0, r10 ; no, then force into suitable range - AND r11, r11, #15 ; only allow 0..15 - LDR r2, [WsPtr, #PalIndex] - TEQ r2, #5 ; if hi res mono - TEQEQ r11, #1 ; and reading colour 1 - MOVEQ r11, #15 ; then read colour 15 instead - B %FT10 ; always skip -05 - ANDS r11, r0, #3 ; else force logical colour 0..3 - BEQ %FT99 ; and 0 is illegal, so do nothing - ADD r11, r11, #16 ; set up correct index -10 - CMP r11, #16 ; is it normal one (not border/cursor) - MOVCSS r3, #0 ; no, then don't fudge colours; Z=1 - ; (carry preserved from CMP) - ANDCCS r3, r10, #&F0 ; yes, then fudge if 256 colour mode - - ADD r10, WsPtr, #FirPalSetting - - LDR r11, [r10, r11, LSL #2]! ; r11 := 1st XX00SBGR - BLNE FudgeRGB - - AND lr, r11, #&F00 ; lr := 1st 00000B00 - MOV r2, lr, LSL #20 ; r2 := 1st B0000000 - AND lr, r11, #&0F0 ; lr := 1st 000000G0 - ORR r2, r2, lr, LSL #16 ; r2 := 1st B0G00000 - AND lr, r11, #&00F ; lr := 1st 0000000R - ORR r2, r2, lr, LSL #12 ; r2 := 1st B0G0R000 - ORR r2, r2, r2, LSR #4 ; r2 := 1st BBGGRR00 - AND lr, r11, #&1000 - ORR r2, r2, lr, LSR #5 ; r2 := 1st BBGGRRS0 - - LDR r11, [r10, #SecPalSetting-FirPalSetting] - BLNE FudgeRGB - - AND lr, r11, #&F00 ; lr := 2nd 00000B00 - MOV r3, lr, LSL #20 ; r3 := 2nd B0000000 - AND lr, r11, #&0F0 ; lr := 2nd 000000G0 - ORR r3, r3, lr, LSL #16 ; r3 := 2nd B0G00000 - AND lr, r11, #&00F ; lr := 2nd 0000000R - ORR r3, r3, lr, LSL #12 ; r3 := 2nd B0G0R000 - ORR r3, r3, r3, LSR #4 ; r3 := 2nd BBGGRR00 - AND lr, r11, #&1000 - ORR r3, r3, lr, LSR #5 ; r3 := 2nd BBGGRRS0 -99 - MOV r4, #0 - Pull "r10, r11, pc" - -FudgeRGB ROUT - [ No26bitCode - mrs ,r4, CPSR - ] - BIC r11, r11, #&C8 ; knock out top bit R, top 2 bits G - BIC r11, r11, #&800 ; knock out top bit B - - TST r0, #&10 ; override top bit of red - ORRNE r11, r11, #&8 - TST r0, #&20 ; override next to top bit of green - ORRNE r11, r11, #&40 - TST r0, #&40 ; override top bit of green - ORRNE r11, r11, #&80 - TST r0, #&80 ; override top bit of blue - ORRNE r11, r11, #&800 - [ No26bitCode - msr ,CPSR_f, r4 - | - MOVS pc, lr - ] - -; ***************************************************************************** -; -; PV_1stFlashState - PaletteV routine to set first flash state -; - -PV_1stFlashState ROUT - Push "r0-r3" - ADD r0, WsPtr, #FirPalSetting -DoR0Flash - MOV r1, #15 ; logical colour -DoAllUpdate - LDRB lr, [WsPtr, #ScreenBlankFlag] - TEQ lr, #0 - MOVEQ lr, #&FF000000 ; unblanked, just knock off top 8 bits - MOVNE lr, #&FFFFFFFF ; blanked, knock off all bits! - MOV r2, #VIDC -10 - LDR r3, [r0, r1, LSL #2] - BIC r3, r3, lr ; get rid of top bits, or all if blanked - ORR r3, r3, r1, LSL #26 ; OR in register number - STR r3, [r2] ; program VidC - SUBS r1, r1, #1 - BPL %BT10 - - MOV r4, #0 - Pull "r0-r3, pc" - -; ***************************************************************************** -; -; PV_2ndFlashState - PaletteV routine to set second flash state -; - -PV_2ndFlashState ROUT - Push "r0-r3" - ADD r0, WsPtr, #SecPalSetting - B DoR0Flash - -; ***************************************************************************** -; -; UpdateAllPalette - Update all VIDC palette entries -; - -UpdateAllPalette ENTRY "r0-r3" ; "r0-r3,lr" stacked ready to branch to code - LDROSB r0, FlashState - CMP r0, #1 - ADDCS r0, WsPtr, #FirPalSetting ; FlashState = 1 => 1st state, 0 => 2nd state - ADDCC r0, WsPtr, #SecPalSetting - MOV r1, #19 ; do 0-15 and border + 3 pointer - B DoAllUpdate - -; ***************************************************************************** -; -; PV_BlankScreen - Blank/unblank screen -; -; in: R0 = -1 => read blank state -; R0 = 0 => unblank screen -; R0 = 1 => blank screen -; -; out: R0 = old state (0=unblanked, 1=blanked) -; R4 = 0 - -PV_BlankScreen ROUT - Push "r1-r3" - LDRB r3, [WsPtr, #ScreenBlankFlag] - CMP r0, #1 - BHI %FT99 - - TEQ r0, r3 ; changing to same state? (carry preserved) - BEQ %FT99 ; if so, do nothing - - STRB r0, [WsPtr, #ScreenBlankFlag] ; update new state - - MOVCC r0, #(1 :SHL: 10) :OR: (0 :SHL: 8) ; unblank: video DMA on, no refresh - MOVCS r0, #(0 :SHL: 10) :OR: (3 :SHL: 8) ; blank: video DMA off, continuous refresh - MOV r1, #(1 :SHL: 10) :OR: (3 :SHL: 8) ; bits to modify - SWI XOS_UpdateMEMC - - PHPSEI r0, lr ; disable IRQs so we don't get a flash in the middle - BL UpdateAllPalette ; update all palette, including border + pointer - PLP r0 ; restore old IRQ state -99 - MOV r0, r3 - MOV r4, #0 - Pull "r1-r3, pc" - - - END diff --git a/s/vdu/vdupal20 b/s/vdu/vdupal20 deleted file mode 100644 index 0bc36016..00000000 --- a/s/vdu/vdupal20 +++ /dev/null @@ -1,1167 +0,0 @@ -; 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. -; -; > VduPal20 - -; mjs Sep 2000 -; -; not used any more, since kernel/HAL split -; vdupalxx is the file now used for generic palette programming - -; Palette programming for VIDC20 - -; ***************************************************************************** - -; PaletteV handler -; ---------------- - -; ***************************************************************************** -; -; MOSPaletteV - Default owner of PaletteV -; - - ASSERT paletteV_Complete = 0 - ASSERT paletteV_Read = 1 - ASSERT paletteV_Set = 2 - ASSERT paletteV_1stFlashState = 3 - ASSERT paletteV_2ndFlashState = 4 - ASSERT paletteV_SetDefaultPalette = 5 - ASSERT paletteV_BlankScreen = 6 - ASSERT paletteV_BulkRead = 7 - ASSERT paletteV_BulkWrite = 8 - ASSERT paletteV_GammaCorrection = 9 - [ LCDInvert - ASSERT paletteV_LCDInvert = 10 - ] - [ StorkPowerSave - ASSERT paletteV_VIDCDisable = 12 - ASSERT paletteV_VIDCRestore = 13 - ] - -MOSPaletteV ROUT - CMP r4, #1 - MOVCC pc, lr - BEQ PV_ReadPalette - CMP r4, #3 - BCC PV_SetPalette - BEQ PV_1stFlashState - CMP r4, #5 - BCC PV_2ndFlashState - BEQ PV_SetDefaultPalette - CMP r4, #7 - BCC PV_BlankScreen - BEQ PV_BulkRead - CMP r4, #9 - BCC PV_BulkWrite - BEQ PV_GammaCorrect - [ LCDInvert - CMP r4, #11 - BCC PV_LCDInvert - ] - [ StorkPowerSave - MOVEQ pc, lr - CMP r4, #13 - BCC PV_VIDCDisable - BEQ PV_VIDCRestore - MOVEQ pc, lr - ] - MOV pc, lr ; reason code not known, so pass it on - -; ***************************************************************************** - -PV_SetDefaultPalette ROUT - Push "r0-r3,r5-r9" - LDR r0, [WsPtr, #PalIndex] ; the new index 0-7 - ADR r1, paldptab - LDR r2, [r1, r0, LSL #2] ; offset from r1 to start of table - ADD r0, r0, #1 ; point to next item - LDR r5, [r1, r0, LSL #2] ; offset from r1 to end of table +1 - ADDS r2, r2, r1 ; r2 -> start of table - BICMI pc, r2, #&80000000 ; if negative then it's a routine - ADD r5, r5, r1 ; r5 -> end of table - BIC r5, r5, #&80000000 - MOV r0, #0 ; start at palette index 0 - MOV r1, #3 ; set both halves -10 - LDR r6, [r2], #4 - MOVS r3, r6, LSL #17 ; get 1st half word and set carry if flashing - MOV r3, r3, LSR #17 - MOVCC r4, #0 - LDRCS r4, =&FFF ; flashing so invert 2nd half RGB - BL UpdateSettingStraightRGB - ADD r0, r0, #1 - MOVS r3, r6, LSL #1 ; get 2nd half word and set carry if flashing - MOV r3, r3, LSR #17 - MOVCC r4, #0 - LDRCS r4, =&FFF - BL UpdateSettingStraightRGB - ADD r0, r0, #1 - TEQ r2, r5 - BNE %BT10 - -; now ensure all palette entries from 0..255 are initialised - - MOV r3, #0 ; set unused (and border) to black - MOV r4, #0 ; no flashing -20 - CMP r0, #256 - BHS FinishDefault - BL UpdateSettingStraightRGB - ADD r0, r0, #1 - B %BT20 - -FinishDefault - MOV r2, #0 ; set border to black (and setup colours 2,3 in BBC gap modes) - BL BorderInitEntry - - MOV r4, #0 ; indicate PaletteV operation complete - Pull "r0-r3,r5-r9,pc" ; restore registers and claim vector - - LTORG - -; ***************************************************************************** - -; Table of offsets from paldata_pointer to palette data - -paldptab - & paldat1-paldptab ; 2 Colour Modes - & paldat2-paldptab ; 4 - & paldat4-paldptab ; 16 - & (paldat8-paldptab) :OR: &80000000 ; 256 (VIDC10 compatible) - use routine - & paldatT-paldptab ; teletext mode - & paldatHR-paldptab ; Hi-res mono mode - & (paldat16-paldptab) :OR: &80000000 ; 16 bpp - use routine - & (paldat32-paldptab) :OR: &80000000 ; 32 bpp (or 256 greys - they're identical!) - use routine - & paldatend-paldptab ; end of table marker - -paldat1 ; Data for 1 bit modes - only necessary to program registers 0 and 1 - -; FSBGR - - DCW &0000 ; 0 Black - DCW &0FFF ; 1 White - -paldat2 ; Data for 2 bit modes - only necessary to program registers 0..3 - -; FSBGR - - DCW &0000 ; 0 Black - DCW &000F ; 1 Red - DCW &00FF ; 2 Yellow - DCW &0FFF ; 3 White - -paldat4 ; Data for 4 bit modes - program all registers - ; Flashing Colours will be needed here - -; FSBGR - - DCW &0000 ; 0 Black - DCW &000F ; 1 Red - DCW &00F0 ; 2 Green - DCW &00FF ; 3 Yellow - DCW &0F00 ; 4 Blue - DCW &0F0F ; 5 Magenta - DCW &0FF0 ; 6 Cyan - DCW &0FFF ; 7 White - DCW &8000 ; 8 Flashing Black - DCW &800F ; 9 Flashing Red - DCW &80F0 ; 10 Flashing Green - DCW &80FF ; 11 Flashing Yellow - DCW &8F00 ; 12 Flashing Blue - DCW &8F0F ; 13 Flashing Magenta - DCW &8FF0 ; 14 Flashing Cyan - DCW &8FFF ; 15 Flashing White - -; Routine to initialise palette for VIDC10-compatible 8bpp modes -; Note this must still be in between paldat4 and paldatT - -paldat8 ROUT - MOV r1, #3 ; set both halves of palette - MOV r0, #0 ; starting index -10 - AND r2, r0, #3 ; get tint bits - ORR r2, r2, r2, LSL #4 ; and duplicate into bits 8,9,12,13,16,17,20,21,24,25,28,29 - ORR r2, r2, r2, LSL #8 - ORR r2, r2, r2, LSL #16 - BIC r2, r2, #&FF - TST r0, #4 - ORRNE r2, r2, #&00004400 - TST r0, #8 - ORRNE r2, r2, #&44000000 - TST r0, #&10 - ORRNE r2, r2, #&00008800 - TST r0, #&20 - ORRNE r2, r2, #&00440000 - TST r0, #&40 - ORRNE r2, r2, #&00880000 - TST r0, #&80 - ORRNE r2, r2, #&88000000 - BL UpdateSettingAndVIDC - ADD r0, r0, #1 - TEQ r0, #&100 - BNE %BT10 - B FinishDefault - -paldatT ; Data for teletext mode - - DCW &0000 ; 0 Black - DCW &000F ; 1 Red - DCW &00F0 ; 2 Green - DCW &00FF ; 3 Yellow - DCW &0F00 ; 4 Blue - DCW &0F0F ; 5 Magenta - DCW &0FF0 ; 6 Cyan - DCW &0FFF ; 7 White - -; Colours 8 to 15 have supremacy bit set - - DCW &1000 ; 8 Supremacy+ Black - DCW &100F ; 9 Red - DCW &10F0 ; 10 Green - DCW &10FF ; 11 Yellow - DCW &1F00 ; 12 Blue - DCW &1F0F ; 13 Magenta - DCW &1FF0 ; 14 Cyan - DCW &1FFF ; 15 White - -paldatHR ; data for Hi-res mono mode - DCW &0000 ; Only red gun necessary - DCW &0111 ; but setting all three makes - DCW &0222 ; reading it more natural - DCW &0333 - DCW &0444 - DCW &0555 - DCW &0666 - DCW &0777 - DCW &0888 - DCW &0999 - DCW &0AAA - DCW &0BBB - DCW &0CCC - DCW &0DDD - DCW &0EEE - DCW &0FFF - - DCW &0000 ; border black - DCW &0010 ; fixed pointer colours - DCW &0020 - DCW &0030 - -paldat16 ROUT - ADR r5, paldat16tab -palmetatab - MOV r1, #3 ; set both halves of palette - MOV r0, #0 ; starting index -10 - MOV r8, r5 - MOV r2, #0 - MOV r6, r0 -20 - LDR r7, [r8], #4 - MOVS r6, r6, LSR #1 - ORRCS r2, r2, r7 - BNE %BT20 - BL UpdateSettingAndVIDC - ADD r0, r0, #1 - TEQ r0, #&100 - BNE %BT10 - B FinishDefault - -paldat16tab - & &00000800 ; palette bit 0 - & &00081000 ; 1 - & &08102100 ; 2 - & &10214200 ; 3 - & &21428400 ; 4 - & &42840000 ; 5 - & &84000000 ; 6 - & &00000000 ; 7 - -paldat32 ROUT - ADR r5, paldat32tab - B palmetatab - -paldat32tab - & &01010100 ; palette bit 0 - & &02020200 ; 1 - & &04040400 ; 2 - & &08080800 ; 3 - & &10101000 ; 4 - & &20202000 ; 5 - & &40404000 ; 6 - & &80808000 ; 7 - -paldatend - -; ***************************************************************************** - -; PaletteV call to set palette in bulk -; in: R0 => list of colours, or 0 -; R1 = colour type (16,17,18,24,25) in b24-31 & number to do in b23-b00 -; R2 => list of palette entries (both flash states if 16, one if 17/18) -; R4 = PaletteV reason code -; -; out: R4 = 0, claim vector if recognised -; otherwise preserve R4 and pass on - -PV_BulkWrite ROUT - Push "R0-R3,R5-R11" ; pc already stacked - - ;register usage: - ;[R6] colour list - ;R7 colour type - ;R8 max number - ;[R9] palette entries - ;R10 loop counter - ;R11 colour number - - MOV R7,R1,LSR #24 - BIC R8,R1,#&FF000000 - MOV R6,R0 - MOV R9,R2 - - MOV R10,#0 -10 - TEQ R6,#0 - MOVEQ R11,R10 - LDRNE R11,[R6],#4 - - TEQ R7,#16 - TEQNE R7,#17 - - MOVEQ R0,R11 - MOVEQ R1,#1 - LDREQ R2,[R9],#4 - BLEQ UpdateNormalColour - - TEQ R7,#16 - TEQNE R7,#18 - - MOVEQ R0,R11 - MOVEQ R1,#2 - LDREQ R2,[R9],#4 - BLEQ UpdateNormalColour - - TEQ R7,#24 - - MOVEQ R0,R11 - LDREQ R2,[R9],#4 - BLEQ BorderColour - - TEQ R7,#25 - - MOVEQ R0,R11 - LDREQ R2,[R9],#4 - BLEQ PointerColour - - ADD R10,R10,#1 - CMP R10,R8 - BCC %BT10 - - MOV R4,#0 - Pull "R0-R3,R5-R11,PC" - -; ***************************************************************************** - -; PaletteV call to set palette -; in: R0 = logical colour -; R1 = colour type (16,17,18,24,25) -; R2 = BBGGRRS0 -; R4 = PaletteV reason code -; -; out: R4 = 0, claim vector if recognised -; otherwise preserve R4 and pass on -; - -;amg 19/4/93 - change this routine to make all the calls subroutines rather -; than branches. Although it will slow this down a bit, it makes the bulk -; write a lot simpler and involves less duplication of mungeing code. - -PV_SetPalette ROUT - Push "r0-r3" - TEQ r1, #16 ; if 16 then set both colours - MOVEQ r1, #3 - BEQ Call_UpdateNormalColour - - TEQ r1, #17 ; elif 17 then set 1st colour - MOVEQ r1, #1 - BEQ Call_UpdateNormalColour - - TEQ r1, #18 ; elif 18 then set 2nd colour - MOVEQ r1, #2 - BEQ Call_UpdateNormalColour - - TEQ r1, #24 ; elif 24 then border colour - BEQ Call_BorderColour - - TEQ r1, #25 ; elif 25 then pointer colour - BEQ Call_PointerColour -10 - Pull "r0-r3" - MOV pc, lr ; else not defined - -Call_UpdateNormalColour - BL UpdateNormalColour - Pull "r0-r3,pc" - -BorderInitEntry Push "r0-r3,lr" ; entry used in default palette setting -Call_BorderColour - BL BorderColour - Pull "r0-r3,pc" - -Call_PointerColour - BL PointerColour - Pull "r0-r3,pc" - -; ***************************************************************************** - -UpdateNormalColour ROUT - Push "LR" - LDR lr, [WsPtr, #DisplayNColour] ; get the mask - TEQ lr, #63 ; is it brain-damaged VIDC10-compatible 256 colour mode? - BEQ %FT10 - AND r0, r0, lr ; and mask it off - AND r0, r0, #255 ; definitely no more than 256 palette entries - BL UpdateSettingAndVIDC -05 - MOV r4, #0 ; indicate successful PaletteV op - Pull "pc" - -10 - AND r0, r0, #15 ; starting palette entry -20 - LDR r3, =&88CC8800 ; r3 = bits controlled by bits 4..7 of pixel value - BIC r2, r2, r3 - TST r0, #&10 ; test bit 4 (r3,7) - ORRNE r2, r2, #&00008800 - TST r0, #&20 ; test bit 5 (g2,6) - ORRNE r2, r2, #&00440000 - TST r0, #&40 ; test bit 6 (g3,7) - ORRNE r2, r2, #&00880000 - TST r0, #&80 ; test bit 7 (b3,7) - ORRNE r2, r2, #&88000000 - BL UpdateSettingAndVIDC - ADD r0, r0, #&10 - CMP r0, #&100 - BCC %BT20 - B %BT05 - -BorderColour ROUT - Push "LR" - MOV r0, #&40000000 ; pseudo-palette-index for border colour - MOV r1, #3 ; both colours - BL UpdateSettingAndVIDC - -; Now test for BBC gap mode (ie 3 or 6) -; if so then set colour 2 to same as border, and colour 3 to inverse - - LDR lr, [WsPtr, #DisplayModeFlags] - TST lr, #Flag_BBCGapMode - BEQ %FT10 - - MOV r0, #2 ; make colour 2 (gap) same as border - BL UpdateSettingAndVIDC - - MOV r0, #3 ; make colour 3 inverse gap - MVN r2, r2 ; invert R, G and B - EOR r2, r2, #&FF ; but use same supremacy - BL UpdateSettingAndVIDC -10 - MOV r4, #0 ; indicate successful PaletteV op - Pull "pc" - - -PointerColour ROUT - Push "LR" - ANDS r0, r0, #3 ; force pointer colour number in range 1..3 - BEQ %FT10 ; zero is invalid - MOV r0, r0, LSL #28 ; move up to top nybble - ORR r0, r0, #&40000000 ; form pseudo-palette-index - MOV r1, #3 - BL UpdateSettingAndVIDC -10 - MOV r4, #0 ; indicate successful PaletteV op - Pull "pc" - -; UpdateSettingStraightRGB -; -; in: r0 = logical colour (border = 4 << 28, pointer colours = 5,6,7 << 28) -; r1 = bit mask of which flash states to update (bit 0 set => 1st, bit 1 set => 2nd) -; r3 = SBGR -; r4 = SBGR to EOR with to go from 1st to 2nd flash state - -; out: r0,r1,r2,r4 preserved -; r3 corrupted - -UpdateSettingStraightRGB EntryS "r2,r5,r6,r7" - ANDS r5, r3, #1 :SHL: 12 ; get supremacy bit in 1st colour - MOVNE r5, #1 :SHL: 27 ; put in r5 in new position - AND r6, r3, #&FF0 ; r6 = 00000BG0 - ORR r5, r5, r6, LSL #8 ; r5 = 0s0BG000 - AND r6, r3, #&0FF ; r6 = 000000GR - ORR r5, r5, r6, LSL #4 ; r5 = 0s0BGGR0 - AND r6, r3, #&00F ; r6 = 0000000R - ORR r5, r5, r6 ; r5 = 0s0BGGRR - AND r6, r3, #&F00 ; r6 = 00000B00 - ORR r3, r5, r6, LSL #12 ; r3 = 0sBBGGRR - - ANDS r5, r4, #1 :SHL: 12 ; get supremacy bit in EOR mask - MOVNE r5, #1 :SHL: 27 ; put in r5 in new position - AND r6, r4, #&FF0 ; r6 = 00000BG0 - ORR r5, r5, r6, LSL #8 ; r5 = 0s0BG000 - AND r6, r4, #&0FF ; r6 = 000000GR - ORR r5, r5, r6, LSL #4 ; r5 = 0s0BGGR0 - AND r6, r4, #&00F ; r6 = 0000000R - ORR r5, r5, r6 ; r5 = 0s0BGGRR - AND r6, r4, #&F00 ; r6 = 00000B00 - ORR r4, r5, r6, LSL #12 ; r5 = 0sBBGGRR - B UpdateSettingCommon - - -; UpdateSettingAndVIDC -; -; in: r0 = logical colour (border = 4 << 28, pointer colours = 5,6,7 << 28) -; r1 = bit mask of which flash states to update (bit 0 set => 1st, bit 1 set => 2nd) -; r2 = BBGGRRS0 -; -; out: r0, r1, r2 preserved -; r3, r4 corrupted -; - -UpdateSettingAndVIDC ALTENTRY - - ;amg: changed to handle 4 bits of supremacy - - MOV r3, r2, LSR #8 ; r3 = 00bbggrr - ANDS r2, r2, #&F0 ; r2 = 000000s0 - ORRNE r3, r3, r2, LSL #20 ; r3 = 0sbbggrr - - MOV r4, #0 ; indicate no EORing between parts - -; ... and drop thru to - -; UpdateSettingCommon -; -; in: r0 = logical colour (border = 4 << 28, pointer colours = 5,6,7 << 28) -; r1 = bit mask of which flash states to update (bit 0 set => 1st, bit 1 set => 2nd) -; r3 = 0sBBGGRR (s in bits 24-27) -; r2, r5, r6, r7, lr stacked -; -; out: r0, r1, r2, r4 preserved -; r3 corrupted -; -UpdateSettingCommon ROUT - PHPSEI ; protect against IRQs - - Push "r0, r8, r9" - MOV r7, #VIDC - - TST r0, #&40000000 ; if border or pointer - ORRNE r3, r3, r0 ; then merge with RGB - MOVNE r0, r0, LSR #28 ; and make r0 into index for soft copy - ADDNE r0, r0, #(256-4) ; ie 256, 257, 258 or 259 - - ORREQ r5, r0, #VIDCPalAddress ; else set up palette index register - STREQ r5, [r7] - - LDRB r5, [WsPtr, #ScreenBlankFlag] - TEQ r5, #0 - MOVNE r5, #&0FFFFFFF ; bits to knock out if blanked (EBBGGRR) - - LDROSB r2, FlashState ; 0 => second, 1 => first - CMP r2, #1 ; C=0 => second, C=1 => first - - TST r1, #1 - BEQ %FT10 ; skip if not setting 1st colour - LDR r2, [WsPtr, #FirPalAddr] - ADD r8, r2, #(256+1+3)*4*4 ; r8 -> rgb transfer tables - STR r3, [r2, r0, LSL #2]! ; store in logical colour and write back pointer - AND r6, r3, #&FF ; r6 = red - LDRB r6, [r8, r6] ; r6 = gamma(red) - ADD r8, r8, #&100 ; r8 -> green transfer - AND r9, r3, #&FF00 ; r9 = green << 8 - LDRB r9, [r8, r9, LSR #8] ; r9 = gamma(green) - ORR r6, r6, r9, LSL #8 ; r6 = gamma(red) + (gamma(green)<<8) - ADD r8, r8, #&100 ; r8 -> blue transfer - AND r9, r3, #&FF0000 ; r9 = blue << 16 - LDRB r9, [r8, r9, LSR #16] ; r9 = gamma(blue) - ORR r6, r6, r9, LSL #16 ; r6 = gamma(red) + (gamma(green)<<8) + (gamma(blue)<<16) - AND r9, r3, #&FF000000 ; knock out rgb from original - ORR r6, r6, r9 ; and or in new bits - STR r6, [r2, #(256+1+3)*4*2] ; store in physical copy - - BICCS r6, r6, r5 ; knock out bits for blanking - [ LCDSupport - Push "lr", CS - BLCS Poke_VIDC - Pull "lr", CS - | - STRCS r6, [r7] ; poke VIDC if setting 1st colour and in 1st state - ] -10 - EOR r3, r3, r4 ; toggle requested bits for 2nd half - TST r1, #2 - BEQ %FT20 ; skip if not setting 2nd colour - LDR r2, [WsPtr, #SecPalAddr] - ADD r8, r2, #(256+1+3)*4*3 ; r8 -> rgb transfer tables - STR r3, [r2, r0, LSL #2]! ; store in logical copy and write back - - AND r6, r3, #&FF ; r6 = red - LDRB r6, [r8, r6] ; r6 = gamma(red) - ADD r8, r8, #&100 ; r8 -> green transfer - AND r9, r3, #&FF00 ; r9 = green << 8 - LDRB r9, [r8, r9, LSR #8] ; r9 = gamma(green) - ORR r6, r6, r9, LSL #8 ; r6 = gamma(red) + (gamma(green)<<8) - ADD r8, r8, #&100 ; r8 -> blue transfer - AND r9, r3, #&FF0000 ; r9 = blue << 16 - LDRB r9, [r8, r9, LSR #16] ; r9 = gamma(blue) - ORR r6, r6, r9, LSL #16 ; r6 = gamma(red) + (gamma(green)<<8) + (gamma(blue)<<16) - AND r9, r3, #&FF000000 ; knock out rgb from original - ORR r6, r6, r9 ; and or in new bits - STR r6, [r2, #(256+1+3)*4*2] ; store in physical copy - - BICCC r6, r6, r5 ; knock out bits for blanking - [ LCDSupport - Push "lr", CC - BLCC Poke_VIDC - Pull "lr", CC - | - STRCC r6, [r7] ; poke VIDC if setting 2nd colour and in 2nd state - ] -20 - PLP - Pull "r0, r8, r9" - EXITS ; restore registers, claim vector - -; ***************************************************************************** -; -; PV_BulkRead - Read multiple palette entries with one call -; -; in: R0 => list of colours wanted, or 0 to start with first and increment -; R1 = b24-b31 - colour type: 16/17/18/24/25 -; b00-b23 - number of colours to do -; -; R2 => memory for first flash state colours (and second if R3=0) -; R3 => memory for second flash state colours (if 0, intermingle with R2 instead) -; -; out: all preserved (R4 set to 0 to show call handled) - -; flags used to control routine - -PV_BR_WantFirst * 1 ; doing 16 or 17 -PV_BR_WantSecond * 2 ; doing 16 or 18 -PV_BR_HaveList * 4 ; we have a list of colours -PV_BR_TwoLists * 8 ; we have two output areas (R2 & R3 valid) -PV_BR_Border * 16 ; doing 24 -PV_BR_Mouse * 32 ; doing 25 - -PV_BulkRead ROUT - Push "R0-R3,R6-R11" ; return addr already stacked - - MOV R6,R1,LSR #24 ; isolate the colour type - - MOV R7,#(PV_BR_WantFirst + PV_BR_WantSecond) - - CMP R6,#17 ; do we want both flash states ? - BICEQ R7,R7,#PV_BR_WantSecond ; if 17 only want first flash state - - CMP R6,#18 - BICEQ R7,R7,#PV_BR_WantFirst ; if 18 only want second flash state - - CMP R6,#24 - ORREQ R7,R7,#PV_BR_Border - ORRGT R7,R7,#PV_BR_Mouse - - ;now set up other control flags - CMP R0,#0 - ORRNE R7,R7,#PV_BR_HaveList ; we have a list of colours - - CMP R3,#0 - ORRNE R7,R7,#PV_BR_TwoLists ; we have two output areas - - ;set up a mask for the number of colours - LDR R8,[WsPtr,#DisplayNColour] - TEQ R8,#63 - MOVEQ R8,#255 ; deal with braindamaged 8BPP case - - ;the mouse has colours 1-3 - TST R7,#PV_BR_Mouse - MOVNE R8,#3 - - ;take the colour type off the top of R1, leaving #colours wanted - BIC R1,R1,#&FF000000 - - ; register usage: - ; [R0]: colour list - ; R1: number of colours - ; [R2]: first flash state list - ; [R3]: second flash state list - ; R7: control flags - ; R8: mask for colour number - ; R9: loop counter - ; R10: misc - ; LR: misc - - MOV R9,#0 -30 - TST R7,#PV_BR_HaveList - LDRNE LR,[R0],#4 - MOVEQ LR,R9 ; LR = wanted colour number - - AND LR,LR,R8 ; ensure it is sensible - - TST R7,#PV_BR_Border - MOVNE LR,#256 ; border is stored as colour 256 - - TST R7,#PV_BR_Mouse - BEQ %FT40 - - TEQ LR,#0 - BEQ %FT50 ;colour 0 is invalid - ADD LR,LR,#256 ;bring into range (257-259) - -40 - TST R7,#PV_BR_WantFirst - - LDRNE R10,[WsPtr,#FirPalAddr] - - LDRNE R10,[R10,LR,LSL#2] ; xsbbggrr - could be 4 sup. bits - MOVNE R11,R10,LSL #8 ; bbggrr00 - ANDNE R10,R10,#&0F000000 ; 0s000000 - ORRNE R11,R11,R10,LSR #20 ; bbggrrs0 - STRNE R11,[R2],#4 - - TST R7,#PV_BR_WantSecond - BEQ %FT60 ; have to use a branch here - another TST coming up - - LDR R10,[WsPtr,#SecPalAddr] - - LDR R10,[R10,LR,LSL#2] ; xsbbggrr - MOV R11,R10,LSL #8 ; bbggrr00 - ANDNE R10,R10,#&0F000000 ; 0s000000 - ORR R11,R11,R10,LSR #20 ; bbggrrs0 - - TST R7,#PV_BR_TwoLists - - STREQ R11,[R2],#4 - STRNE R11,[R3],#4 - -60 ADD R9,R9,#1 - CMP R9,R1 - BCC %BT30 -50 - MOV R4,#0 - Pull "R0-R3,R6-R11,PC" ; return addr already stacked - - -; ***************************************************************************** -; -; PV_ReadPalette - PaletteV read palette handler -; -; in: R0 = logical colour -; R1 = 16 (read normal colour) -; 24 (read border colour) -; 25 (read cursor colour) -; -; out: R2 = first flash setting (BBGGRRS0), supremacy bits 4-7 -; R3 = second flash setting (BBGGRRS0), supremacy bits 4-7 -; - -PV_ReadPalette ROUT - Push "r10,r11" - LDR r10, [WsPtr, #DisplayNColour] ; logical colours in this mode -1 - TEQ r10, #63 ; if bodgy 256 colour mode - MOVEQ r10, #255 ; then use AND mask of 255 - - TEQ r1, #24 ; is it reading border palette - MOVEQ r11, #&100 ; then set up border index - BEQ %FT10 ; and go - - TEQ r1, #25 ; is it reading pointer palette - BEQ %FT05 - AND r11, r0, r10 ; no, then force into suitable range - B %FT10 ; always skip -05 - ANDS r11, r0, #3 ; else force logical colour 0..3 - BEQ %FT99 ; and 0 is illegal, so do nothing - ADD r11, r11, #&100 ; set up correct index -10 - -; note no need to fudge 256-colour modes, since we have the correct full 256 entry palette - -; bjga: changed to handle 4 bits of supremacy (BulkRead already does) - - LDR r10, [WsPtr, #FirPalAddr] - LDR r10, [r10, r11, LSL #2] ; r10 := 1st XSBBGGRR - MOV r2, r10, LSL #8 ; r2 := 1st BBGGRR00 - AND r10, r10, #&0F000000 ; r10 := 1st 0S000000 - ORR r2, r2, r10, LSR #20 ; r2 := 1st BBGGRRS0 - - LDR r10, [WsPtr, #SecPalAddr] - LDR r10, [r10, r11, LSL #2] ; r10 := 2nd XSBBGGRR - MOV r3, r10, LSL #8 ; r3 := 2nd BBGGRR00 - AND r10, r10, #&0F000000 ; r10 := 2nd 0S000000 - ORR r3, r3, r10, LSR #20 ; r3 := 2nd BBGGRRS0 -99 - MOV r4, #0 - Pull "r10, r11, pc" - -; ***************************************************************************** -; -; PV_1stFlashState - PaletteV routine to set first flash state -; - -PV_1stFlashState ROUT - Push "r0-r3" - LDR r0, [WsPtr, #FirPalAddr] -DoR0Flash - MOV r1, #256 ; just update normal palette -DoAllUpdate - ADD r0, r0, #(256+1+3)*4*2 ; move pointer to physical palette copy - ADD r1, r0, r1, LSL #2 - MOV r2, #VIDC - MOV r3, #VIDCPalAddress + 0 ; initialise palette address to 0 - PHPSEI ; disable IRQs round this bit - STR r3, [r2] - - LDRB r4, [WsPtr, #ScreenBlankFlag] - TEQ r4, #0 ; if unblanked, leave all bits alone - MOVNE r4, #&0FFFFFFF ; blanked, knock off all bits, except register bits -10 - LDR r3, [r0], #4 - BIC r3, r3, r4 - [ LCDSupport - Push "r6,r7,r14" - MOV r6, r3 - MOV r7, r2 - BL Poke_VIDC - Pull "r6,r7,r14" - | - STR r3, [r2] - ] - TEQ r0, r1 - BNE %BT10 - - PLP - MOV r4, #0 - Pull "r0-r3, pc" - -; ***************************************************************************** -; -; PV_2ndFlashState - PaletteV routine to set second flash state -; - -PV_2ndFlashState ROUT - Push "r0-r3" - LDR r0, [WsPtr, #SecPalAddr] - B DoR0Flash - -; ***************************************************************************** -; -; UpdateAllPalette - Update all VIDC palette entries -; - -UpdateAllPalette Entry "r0-r3" ; "r0-r3,lr" stacked ready to branch to code - LDROSB r0, FlashState - CMP r0, #1 - LDRCS r0, [WsPtr, #FirPalAddr] ; FlashState = 1 => 1st state, 0 => 2nd state - LDRCC r0, [WsPtr, #SecPalAddr] - MOV r1, #260 ; update normal palette and border/pointer - B DoAllUpdate - -; ***************************************************************************** -; -; PV_BlankScreen - Blank/unblank screen -; -; in: R0 = -1 => read blank state -; R0 = 0 => unblank screen -; R0 = 1 => blank screen -; -; out: R0 = old state (0=unblanked, 1=blanked) -; R4 = 0 - -PV_BlankScreen ROUT - Push "r1-r3" - LDRB r3, [WsPtr, #ScreenBlankFlag] - CMP r0, #1 - BHI %FT99 - - TEQ r0, r3 ; changing to same state? (carry preserved) - BEQ %FT99 ; if so, do nothing - - STRB r0, [WsPtr, #ScreenBlankFlag] ; update new state - MOV r4, #VIDC - LDRB r0, [WsPtr, #ScreenBlankDPMSState] - BCC %FT50 - -; blanking - - TST r0, #1 ; if hsyncs should be off, - LDRNE r1, =HorizSyncWidth + ((1:SHL:14) -1) ; maximum value in h.sync width register - STRNE r1, [r4] - - TST r0, #2 ; if vsyncs should be off, - LDRNE r1, =VertiSyncWidth + ((1:SHL:13) -1) ; maximum value in v.sync width register - STRNE r1, [r4] - - LDR r1, [WsPtr, #VIDCExternalSoftCopy] - AND r0, r0, #3 - TEQ r0, #3 ; if both syncs off - BICEQ r1, r1, #Ext_HSYNCbits :OR: Ext_VSYNCbits - ORREQ r1, r1, #Ext_InvertHSYNC :OR: Ext_InvertVSYNC ; set sync signals to low (less power) - BIC r1, r1, #Ext_DACsOn ; turn off the DACs - STR r1, [r4] - - MOV r0, #(0 :SHL: 10) :OR: (3 :SHL: 8) ; blank: video DMA off, continuous refresh - B %FT60 - -50 - -; unblanking - - LDR r1, [WsPtr, #VIDCExternalSoftCopy] - STR r1, [r4] ; restore DACs and sync type - - TST r0, #1 ; if hsyncs were turned off, - LDRNE r1, [WsPtr, #HSWRSoftCopy] ; then restore from soft copy - STRNE r1, [r4] - - TST r0, #2 ; if vsyncs were turned off, - LDRNE r1, [WsPtr, #VSWRSoftCopy] ; then restore from soft copy - STRNE r1, [r4] - - MOV r0, #(1 :SHL: 10) :OR: (0 :SHL: 8) ; unblank: video DMA on, no refresh -60 - MOV r1, #(1 :SHL: 10) :OR: (3 :SHL: 8) ; bits to modify - SWI XOS_UpdateMEMC - - PHPSEI r0, lr ; disable IRQs so we don't get a flash in the middle - BL UpdateAllPalette ; update all palette, including border + pointer - PLP r0 ; restore old IRQ state -99 - MOV r0, r3 - MOV r4, #0 - Pull "r1-r3, pc" - - -; ***************************************************************************** -; -; PV_GammaCorrect - Update gamma correction tables -; -; in: r0 -> red table -; r1 -> green table -; r2 -> blue table -; -; out: r4 = 0 - -PV_GammaCorrect ROUT - Push "r0-r3,r5-r8" - LDR r4, [WsPtr, #FirPalAddr] - ADD r4, r4, #(256+1+3)*4*4 ; point to gamma tables - ADD r3, r4, #256 -10 - LDR lr, [r0], #4 - STR lr, [r4], #4 - TEQ r4, r3 - BNE %BT10 - - ADD r3, r4, #256 -20 - LDR lr, [r1], #4 - STR lr, [r4], #4 - TEQ r4, r3 - BNE %BT20 - - ADD r3, r4, #256 -30 - LDR lr, [r2], #4 - STR lr, [r4], #4 - TEQ r4, r3 - BNE %BT30 - -; now go through the logical palette, recomputing the physical from it using the new tables - - SUB r0, r4, #3*256 ; r0 -> red table - SUB r1, r4, #2*256 ; r1 -> green table - SUB r2, r4, #1*256 ; r2 -> blue table - - LDR r4, [WsPtr, #FirPalAddr] ; r4 -> start of logical palette - ADD r5, r4, #260*4*2 ; r5 -> start of physical palette - MOV r6, r5 ; r6 = r5 = end of logical palette -40 - LDR r7, [r4], #4 ; get word - AND r8, r7, #&FF ; r8 = red - LDRB r8, [r0, r8] ; r8 = gamma(red) - AND lr, r7, #&FF00 ; lr = green << 8 - LDRB lr, [r1, lr, LSR #8] ; lr = gamma(green) - ORR r8, r8, lr, LSL #8 ; r8 = gamma(red) + (gamma(green)<<8) - AND lr, r7, #&FF0000 ; lr = blue << 16 - LDRB lr, [r2, lr, LSR #16] ; lr = gamma(blue) - ORR r8, r8, lr, LSL #16 ; r8 = gamma(red) + (gamma(green)<<8) + (gamma(blue)<<16) - AND lr, r7, #&FF000000 ; lr = other bits - ORR r8, r8, lr ; r8 = gamma-corrected combined value - STR r8, [r5], #4 ; store word - TEQ r4, r6 - BNE %BT40 - - BL UpdateAllPalette - - MOV r4, #0 - Pull "r0-r3,r5-r8, pc" - - - [ LCDInvert -; ***************************************************************************** -; -; PV_LCDInvert - Invert the LCD palette -; -; in: r0 = inversion state to use (0=uninverted, 1=inverted) -; -; out: r4 = 0 - -PV_LCDInvert ROUT - MOV r4, #0 - STRB r0, [r4, #LCD_Inverted] - - BL UpdateAllPalette - MOV r4, #0 - Pull "pc" - ] - - [ StorkPowerSave -; ***************************************************************************** -PV_VIDCDisable - ROUT - Push "r2" - - MOV r4, #VIDC - - LDR r2, =&C0000003 ;dac off, ereg set to external LUT - STR r2, [r4] - - LDR r2, =&D0004000 ;Vclk off, Pcomp=0 - STR r2, [r4] - - LDR r2, =&E0004049 ;PoDown, Hclk - STR r2, [r4] - - MOV r4, #0 - Pull "r2, pc" - -; ***************************************************************************** -PV_VIDCRestore - ROUT - Push "r2,r3,R8" - MOV r3, #VIDC - - LDR r2, [WsPtr, #VIDCControlSoftCopy] ;restore from soft copy - STR r2, [r3] - - LDR r2, [WsPtr, #VIDCExternalSoftCopy] ;restore from soft copy - STR r2, [r3] - - LDR r2, [WsPtr, #VIDCFSynSoftCopy] ;restore from soft copy - [ 1 = 1 - LDR R8, =FSyn_ResetValue ; set test bits on, and r > v - STR R8, [R3] - -; we may need some delay in here... - - LDR R8, =FSyn_ClearR :OR: FSyn_ClearV :OR: FSyn_ForceLow :OR: FSyn_ForceHigh - ORR R2, R2, R8 - BIC R2, R2, #FSyn_ForceHigh ; force test bits on, except this one - STR R2, [R3] - -; we may also need some delay in here... - - BIC R2, R2, R8 ; remove test bits - ] - STR r2, [r3] - - - MOV r4, #0 - Pull "r2,r3,R8, pc" - ] -; ***************************************************************************** -; -; Poke_VIDC -; -; in: r6 = CRT palette VIDC entry &AeBbGgRr (where A is the VIDC register 'address') -; r7 = address to poke -; -; out: all registers preserved -; -; NOTE: If LCD_Active in the KernelWS != 0, the value bunged into VIDC is the -; value required by the greyscaler to approximate the luminance of r6 on entry. - -Poke_VIDC - EntryS "r0-r4" - [ :LNOT: STB - MOV r0, #0 - LDRB r0, [r0, #LCD_Active] - CMP r0, #0 - STREQ r6,[r7] ;Ho hum, it's a CRT, so no mucking about - EXITS EQ - ] - - MOV r0, #&0f - AND r4, r0, r6, LSR #28 ;r4 = VIDC register 'address' (in bottom 4 bits) - MOV r0, #&ff - AND r2, r0, r6, LSR #16 ;r2 = blue - AND r1, r0, r6, LSR #8 ;r1 = green - ADD r2, r2, r1, LSL #2 ;r2 = 4green + blue - AND r1, r0, r6 ;r1 = red - ADD r2, r2, r1, LSL #1 ;r2 = 4green + 2red + blue - _Very_ approx CIE weightings! - - [ :LNOT: STB - MOV r0, #0 - LDRB r0, [r0, #LCD_Inverted] - CMP r0, #0 - MOVNE r0, #255 - RSBNE r0, r0, r0, LSL #3 ;Move 1785 into R0 - RSBNE r2, r2, r0 - ] - ADR r3, NewPalTab ; perform binary chop using table (lifted from PortableA4 module, with added comments) - - LDR r0, [r3, #8*4] ;read the middle table value - CMP r2, r0 - ADDCC r1, r3, #0*4 - ADDCS r1, r3, #8*4 - LDR r0, [r1, #4*4] - CMP r2, r0 - ADDCS r1, r1, #4*4 - LDR r0, [r1, #2*4] - CMP r2, r0 - ADDCS r1, r1, #2*4 - LDR r0, [r1, #1*4] - CMP r2, r0 - ADDCS r1, r1, #1*4 - SUB r3, r1, r3 - - MOV r2, r3, LSR #2 ;R2 is now in the range 0-14 - CMP r2, #7 - ADDGT r2, r2, #1 ;Now R2 in range 0-7,9-15 - AND r2, r2, #&0f ;Just to be on the safe side.... - - ORR r2, r2, r2, LSL #8 - ORR r2, r2, r2, LSL #16 ;Now &0x0x0x0x (where x is 0-7,9-15) - ORR r2, r2, r4, LSL #28 ;Now &Ax0x0x0x (A is the VIDC address) - STR r2, [r7] ;And into the VIDC we go! - - EXITS - -NewPalTab - DCD 0, 119, 238, 357, 476, 595, 714, 833, 953, 1072, 1191, 1310, 1429, 1548, 1667, -1 - - END diff --git a/s/vdu/vdupalette b/s/vdu/vdupalette deleted file mode 100644 index cd6e8cc9..00000000 --- a/s/vdu/vdupalette +++ /dev/null @@ -1,226 +0,0 @@ -; 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. -; -; > VduPalette -; -; ARTHUR OPERATING SYSTEM - Vdu Drivers -; ======================= -; -; Vdu driver code - Palette setting (VIDC independent parts) -; -; ***************************************************************************** - -; Routines above PaletteV -; ----------------------- - -; ***************************************************************************** -; -; PalInit - Restore default palette for the displayed mode -; -; out: R6 is preserved (may contain CursorFlags) -; - -PalInit ROUT - MOV r4, #paletteV_SetDefaultPalette - B CallPaletteV - -; ***************************************************************************** -; -; UnblankScreen - Unblank screen (called on mode change) -; - -UnblankScreen ROUT - MOV r0, #0 - MOV r4, #paletteV_BlankScreen - B CallPaletteV - -; ***************************************************************************** -; -; DoSetPalette - Entry point for OSWORD 12 (program palette) -; -; in: R1 -> Control block -; [R1, #0] = logical colour -; [R1, #1] = physical colour or action -; [R1, #2] = red -; [R1, #3] = green -; [R1, #4] = blue -; -; R12 -> VDUWS -; -; R0-R4, R11, R12 may be corrupted -; -; -DoSetPalette - Push "R5-R10,R14" - BL SetPal - Pull "R5-R10,PC" - -; ***************************************************************************** -; -; DC3 - Entry point for VDU 19 (program palette) -; -; in: QQ+0..QQ+4 contain the parameters in the same format as OSWORD -; - -DC3 ROUT - ADD R1, WsPtr, #QQ ; Point R1 at the queued data - ; and drop thru to Palette OSWORD code -SetPal EntryS - LDR R6, [WsPtr, #DisplayModeFlags] - TST R6, #Flag_Teletext ; if teletext mode - EXITS NE ; then ignore VDU 19 - -; Now we must check for BBC style colours (VDU 19,n,0..15,...) and map these onto -; 16 or (17 and 18) - - MOV lr, r1 - LDRB r0, [lr, #0] ; r0 = logical colour - LDRB r1, [lr, #1] - AND r2, r1, #&80 ; r2 = sup bit - BIC r1, r1, #&80 ; r1 = type of colour - CMP r1, #16 ; r1 < 16 => BBC style colour - BCS %FT10 - - TST r1, #1 ; bit 0 set => red full on - ORRNE r2, r2, #&0000FF00 - TST r1, #2 ; bit 1 set => green full on - ORRNE r2, r2, #&00FF0000 - TST r1, #4 ; bit 2 set => blue full on - ORRNE r2, r2, #&FF000000 - - LDRB lr, [WsPtr, #PalIndex] - CMP lr, #3 ; only flash colours if PalIndex = 0, 1 or 2 - BICCS r1, r1, #8 - - TST r1, #8 - MOVEQ r1, #16 - BEQ %FT20 ; not a flashing colour, so just set it once - - MOV r1, #17 ; set first flash colour - BL CallSetPalette - MVN r2, r2 ; then toggle all bits of R, G and B - EOR r2, r2, #&FF ; (don't toggle supremacy) - MOV r1, #18 ; set second flash colour - B %FT20 - -10 - LDRB r3, [lr, #2] ; r3 = red - ORR r2, r2, r3, LSL #8 ; r2 = &0000RRS0 - LDRB r3, [lr, #3] ; r3 = green - ORR r2, r2, r3, LSL #16 ; r2 = &00GGRRS0 - LDRB r3, [lr, #4] ; r3 = blue - ORR r2, r2, r3, LSL #24 ; r2 = &BBGGRRS0 -20 - BL CallSetPalette - EXITS - - -CallSetPalette - MOV r4, #paletteV_Set -CallPaletteV - EntryS r9 - MOV r9, #PaletteV - SWI XOS_CallAVector - EXITS - -; ***************************************************************************** -; -; SWIReadPalette - SWI ReadPalette handler -; -; in: R0 = logical colour -; R1 = 16 (read normal colour) -; 24 (read border colour) -; 25 (read cursor colour) -; -; out: R2 = first flash setting (B0G0R0PP), supremacy bit 7 -; R3 = second flash setting (B0G0R0PP), supremacy bit 7 -; R10-R12 corrupted (preserved by Sam), all others preserved -; - -SWIReadPalette Entry "r4" - VDWS WsPtr - MOV r4, #paletteV_Read - BL CallPaletteV - BIC r2, r2, #&7F ; knock out any weird bits - BIC r3, r3, #&7F - ORR r2, r2, r1 ; put in nominal PP field - ORR r3, r3, r1 - TEQ r1, #16 ; if reading normal colour - BNE %FT10 - TEQ r2, r3 ; and colours different - ORRNE r2, r2, #1 ; then make 1st PP field 17 - ORRNE r3, r3, #2 ; and 2nd PP field 18 -10 - PullEnv - ExitSWIHandler - -; ***************************************************************************** -; -; DoReadPalette - Entry point from OSWORD 11 (read palette) -; -; in: R1 -> control block -; [R1, #0] = logical colour to read -; -; out: [R1, #1] (bits 0..6) = physical colour 0..15 or 16; (bit 7) = supremacy -; [R1, #2] = red (in bits 4..7) -; [R1, #3] = green (-----""-----) -; [R1, #4] = blue (-----""-----) -; R0-R4, R11, R12 can be corrupted -; - -DoReadPalette Entry - MOV r4, r1 ; save pointer to block - LDRB r0, [r4] ; r0 = logical colour - MOV r1, #16 - SWI XOS_ReadPalette - LDROSB r0, FlashState - CMP r0, #1 ; CS => 1st state, CC => 2nd state - MOVCC r2, r3 ; r2 = current state - MOV r1, #4 -10 - STRB r2, [r4, #1]! ; store 4 bytes of data in block, starting R1+1 - MOV r2, r2, LSR #8 - SUBS r1, r1, #1 - BNE %BT10 - EXIT - -; ***************************************************************************** -; -; DoFirstFlash - Set palette to first palette setting -; Called in either SVC or IRQ mode -; - -DoFirstFlash EntryS "r0,r4" - MOV r4, #paletteV_1stFlashState -SetFlashState - MRS r0, CPSR - ORR r1, r0, #I32_bit + SVC_mode ; to SVC26/32 mode - MSR CPSR_c, r1 - Push "lr" - BL CallPaletteV - Pull "lr" - MSR CPSR_c, r0 - EXITS - -; ***************************************************************************** -; -; DoSecondFlash - Set palette to second palette setting -; Called in either SVC or IRQ mode -; - -DoSecondFlash ALTENTRY - MOV r4, #paletteV_2ndFlashState - B SetFlashState - - END diff --git a/s/vdu/vdupalxx b/s/vdu/vdupalxx deleted file mode 100644 index 10a8fc1b..00000000 --- a/s/vdu/vdupalxx +++ /dev/null @@ -1,1129 +0,0 @@ -; Copyright 2000 Pace Micro Technology plc -; -; 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. -; -; vdupalxx - -; mjs Sep 2000 -; -; Palette programming for generic video controller, delegating h/w -; specifics to HAL calls. Think of any 'VIDC' references here as for a -; generic video controller. - -; Format of a 32-bit palette entry in soft palette tables (eg. FirPalAddr) and -; for calls to HAL is: -; -; BBGGRRSS -; -; ie. 8-8-8-8 bits for Blue-Green-Red-Supremacy -; 'Supremacy' is expected to be 0=solid .. 255=transparent -; [pre-HAL, Medusa kernels used a soft palette format of 0SBBGGRR, being VIDC20-ish] -; -; soft palette tables are indexed by 0..259, where: -; -; 0..255 are normal (display) palette entries -; type 0, index 0..255 for HAL calls -; 256 is border entry -; type 1, index 0 for HAL calls -; 257..259 are pointer palette entries -; type 2, index 1..3 for HAL calls (HAL index 0 assumed to -; correspond to transparent, and not used) - - -; ***************************************************************************** - -; PaletteV handler -; ---------------- - -; ***************************************************************************** -; -; MOSPaletteV - Default owner of PaletteV -; - - ASSERT paletteV_Complete = 0 - ASSERT paletteV_Read = 1 - ASSERT paletteV_Set = 2 - ASSERT paletteV_1stFlashState = 3 - ASSERT paletteV_2ndFlashState = 4 - ASSERT paletteV_SetDefaultPalette = 5 - ASSERT paletteV_BlankScreen = 6 - ASSERT paletteV_BulkRead = 7 - ASSERT paletteV_BulkWrite = 8 - ASSERT paletteV_GammaCorrection = 9 - [ LCDInvert - ASSERT paletteV_LCDInvert = 10 - ] - [ StorkPowerSave - ASSERT paletteV_VIDCDisable = 12 - ASSERT paletteV_VIDCRestore = 13 - ] - -MOSPaletteV ROUT - CMP r4, #13 - ADDLS pc, pc, r4, LSL #2 - MOV pc, lr ; reason code not known, so pass it on - MOV pc, lr ; 0 - B PV_ReadPalette ; 1 - B PV_SetPalette ; 2 - B PV_1stFlashState ; 3 - B PV_2ndFlashState ; 4 - B PV_SetDefaultPalette ; 5 - B PV_BlankScreen ; 6 - B PV_BulkRead ; 7 - B PV_BulkWrite ; 8 - B PV_GammaCorrect ; 9 - [ LCDInvert - B PV_LCDInvert ; 10 - | - MOV pc, lr ; 10 - ] - MOV pc, lr ; 11 - [ StorkPowerSave - B PV_VIDCDisable ; 12 - B PV_VIDCRestore ; 13 - | - MOV pc, lr ; 12 - MOV pc, lr ; 13 - ] - -; ***************************************************************************** - -PV_SetDefaultPalette ROUT - Push "r0-r3,r5-r9" - LDR r0, [WsPtr, #PalIndex] ; the new index 0-7 - ADR r1, paldptab - LDR r2, [r1, r0, LSL #2] ; offset from r1 to start of table - ADD r0, r0, #1 ; point to next item - LDR r5, [r1, r0, LSL #2] ; offset from r1 to end of table +1 - TST r2, #&80000000 ; if bit 31 set, it's a routine - BIC r2, r2, #&80000000 ; clear that flag - ADD r2, r2, r1 ; r2 -> start of table - MOVNE pc, r2 ; or call routine - BIC r5, r5, #&80000000 ; clear routine flag - ADD r5, r5, r1 ; r5 -> end of table - MOV r0, #0 ; start at palette index 0 - MOV r1, #3 ; set both halves -10 - LDR r6, [r2], #4 - MOVS r3, r6, LSL #17 ; get 1st half word and set carry if flashing - MOV r3, r3, LSR #17 - MOVCC r4, #0 - LDRCS r4, =&FFF ; flashing so invert 2nd half RGB - BL UpdateSettingStraightRGB - ADD r0, r0, #1 - MOVS r3, r6, LSL #1 ; get 2nd half word and set carry if flashing - MOV r3, r3, LSR #17 - MOVCC r4, #0 - LDRCS r4, =&FFF - BL UpdateSettingStraightRGB - ADD r0, r0, #1 - TEQ r2, r5 - BNE %BT10 - -; now ensure all palette entries from 0..255 are initialised - - MOV r3, #0 ; set unused (and border) to black - MOV r4, #0 ; no flashing -20 - CMP r0, #256 - BHS FinishDefault - BL UpdateSettingStraightRGB - ADD r0, r0, #1 - B %BT20 - -FinishDefault - MOV r2, #0 ; set border to black (and setup colours 2,3 in BBC gap modes) - BL BorderInitEntry - - MOV r4, #0 ; indicate PaletteV operation complete - Pull "r0-r3,r5-r9,pc" ; restore registers and claim vector - - LTORG - -; ***************************************************************************** - -; Table of offsets from paldata_pointer to palette data - -paldptab - & paldat1-paldptab ; 2 Colour Modes - & paldat2-paldptab ; 4 - & paldat4-paldptab ; 16 - & (paldat8-paldptab) :OR: &80000000 ; 256 (VIDC10 compatible) - use routine - & paldatT-paldptab ; teletext mode - & paldatHR-paldptab ; Hi-res mono mode - & (paldat16-paldptab) :OR: &80000000 ; 16 bpp - use routine - & (paldat32-paldptab) :OR: &80000000 ; 32 bpp (or 256 greys - they're identical!) - use routine - & paldatend-paldptab ; end of table marker - -paldat1 ; Data for 1 bit modes - only necessary to program registers 0 and 1 - -; FSBGR - - DCW &0000 ; 0 Black - DCW &0FFF ; 1 White - -paldat2 ; Data for 2 bit modes - only necessary to program registers 0..3 - -; FSBGR - - DCW &0000 ; 0 Black - DCW &000F ; 1 Red - DCW &00FF ; 2 Yellow - DCW &0FFF ; 3 White - -paldat4 ; Data for 4 bit modes - program all registers - ; Flashing Colours will be needed here - -; FSBGR - - DCW &0000 ; 0 Black - DCW &000F ; 1 Red - DCW &00F0 ; 2 Green - DCW &00FF ; 3 Yellow - DCW &0F00 ; 4 Blue - DCW &0F0F ; 5 Magenta - DCW &0FF0 ; 6 Cyan - DCW &0FFF ; 7 White - DCW &8000 ; 8 Flashing Black - DCW &800F ; 9 Flashing Red - DCW &80F0 ; 10 Flashing Green - DCW &80FF ; 11 Flashing Yellow - DCW &8F00 ; 12 Flashing Blue - DCW &8F0F ; 13 Flashing Magenta - DCW &8FF0 ; 14 Flashing Cyan - DCW &8FFF ; 15 Flashing White - -; Routine to initialise palette for VIDC10-compatible 8bpp modes -; Note this must still be in between paldat4 and paldatT - -paldat8 ROUT - MOV r1, #3 ; set both halves of palette - MOV r0, #0 ; starting index -10 - AND r2, r0, #3 ; get tint bits - ORR r2, r2, r2, LSL #4 ; and duplicate into bits 8,9,12,13,16,17,20,21,24,25,28,29 - ORR r2, r2, r2, LSL #8 - ORR r2, r2, r2, LSL #16 - BIC r2, r2, #&FF - TST r0, #4 - ORRNE r2, r2, #&00004400 - TST r0, #8 - ORRNE r2, r2, #&44000000 - TST r0, #&10 - ORRNE r2, r2, #&00008800 - TST r0, #&20 - ORRNE r2, r2, #&00440000 - TST r0, #&40 - ORRNE r2, r2, #&00880000 - TST r0, #&80 - ORRNE r2, r2, #&88000000 - BL UpdateSettingAndVIDC - ADD r0, r0, #1 - TEQ r0, #&100 - BNE %BT10 - B FinishDefault - -paldatT ; Data for teletext mode - - DCW &0000 ; 0 Black - DCW &000F ; 1 Red - DCW &00F0 ; 2 Green - DCW &00FF ; 3 Yellow - DCW &0F00 ; 4 Blue - DCW &0F0F ; 5 Magenta - DCW &0FF0 ; 6 Cyan - DCW &0FFF ; 7 White - -; Colours 8 to 15 have supremacy bit set - - DCW &1000 ; 8 Supremacy+ Black - DCW &100F ; 9 Red - DCW &10F0 ; 10 Green - DCW &10FF ; 11 Yellow - DCW &1F00 ; 12 Blue - DCW &1F0F ; 13 Magenta - DCW &1FF0 ; 14 Cyan - DCW &1FFF ; 15 White - -paldatHR ; data for Hi-res mono mode - DCW &0000 ; Only red gun necessary - DCW &0111 ; but setting all three makes - DCW &0222 ; reading it more natural - DCW &0333 - DCW &0444 - DCW &0555 - DCW &0666 - DCW &0777 - DCW &0888 - DCW &0999 - DCW &0AAA - DCW &0BBB - DCW &0CCC - DCW &0DDD - DCW &0EEE - DCW &0FFF - - DCW &0000 ; border black - DCW &0010 ; fixed pointer colours - DCW &0020 - DCW &0030 - -paldat16 ROUT - ADR r5, paldat16tab -palmetatab - MOV r1, #3 ; set both halves of palette - MOV r0, #0 ; starting index -10 - MOV r8, r5 - MOV r2, #0 - MOV r6, r0 -20 - LDR r7, [r8], #4 - MOVS r6, r6, LSR #1 - ORRCS r2, r2, r7 - BNE %BT20 - BL UpdateSettingAndVIDC - ADD r0, r0, #1 - TEQ r0, #&100 - BNE %BT10 - B FinishDefault - -paldat16tab - & &00000800 ; palette bit 0 - & &00081000 ; 1 - & &08102100 ; 2 - & &10214200 ; 3 - & &21428400 ; 4 - & &42840000 ; 5 - & &84000000 ; 6 - & &00000000 ; 7 - -paldat32 ROUT - ADR r5, paldat32tab - B palmetatab - -paldat32tab - & &01010100 ; palette bit 0 - & &02020200 ; 1 - & &04040400 ; 2 - & &08080800 ; 3 - & &10101000 ; 4 - & &20202000 ; 5 - & &40404000 ; 6 - & &80808000 ; 7 - -paldatend - -; ***************************************************************************** - -; PaletteV call to set palette in bulk -; in: R0 => list of colours, or 0 -; R1 = colour type (16,17,18,24,25) in b24-31 & number to do in b23-b00 -; R2 => list of palette entries (both flash states if 16, one if 17/18) -; R4 = PaletteV reason code -; -; out: R4 = 0, claim vector if recognised -; otherwise preserve R4 and pass on - -PV_BulkWrite ROUT - Push "R0-R3,R5-R11" ; pc already stacked - - ;register usage: - ;[R6] colour list - ;R7 colour type - ;R8 max number - ;[R9] palette entries - ;R10 loop counter - ;R11 colour number - - MOV R7,R1,LSR #24 - BIC R8,R1,#&FF000000 - MOV R6,R0 - MOV R9,R2 - - MOV R10,#0 -10 - TEQ R6,#0 - MOVEQ R11,R10 - LDRNE R11,[R6],#4 - - TEQ R7,#16 - TEQNE R7,#17 - - MOVEQ R0,R11 - MOVEQ R1,#1 - LDREQ R2,[R9],#4 - BLEQ UpdateNormalColour - - TEQ R7,#16 - TEQNE R7,#18 - - MOVEQ R0,R11 - MOVEQ R1,#2 - LDREQ R2,[R9],#4 - BLEQ UpdateNormalColour - - TEQ R7,#24 - - MOVEQ R0,R11 - LDREQ R2,[R9],#4 - BLEQ BorderColour - - TEQ R7,#25 - - MOVEQ R0,R11 - LDREQ R2,[R9],#4 - BLEQ PointerColour - - ADD R10,R10,#1 - CMP R10,R8 - BCC %BT10 - - MOV R4,#0 - Pull "R0-R3,R5-R11,PC" - -; ***************************************************************************** - -; PaletteV call to set palette -; in: R0 = logical colour -; R1 = colour type (16,17,18,24,25) -; R2 = BBGGRRSS -; R4 = PaletteV reason code -; -; out: R4 = 0, claim vector if recognised -; otherwise preserve R4 and pass on -; - -;amg 19/4/93 - change this routine to make all the calls subroutines rather -; than branches. Although it will slow this down a bit, it makes the bulk -; write a lot simpler and involves less duplication of mungeing code. - -PV_SetPalette ROUT - Push "r0-r3" - TEQ r1, #16 ; if 16 then set both colours - MOVEQ r1, #3 - BEQ Call_UpdateNormalColour - - TEQ r1, #17 ; elif 17 then set 1st colour - MOVEQ r1, #1 - BEQ Call_UpdateNormalColour - - TEQ r1, #18 ; elif 18 then set 2nd colour - MOVEQ r1, #2 - BEQ Call_UpdateNormalColour - - TEQ r1, #24 ; elif 24 then border colour - BEQ Call_BorderColour - - TEQ r1, #25 ; elif 25 then pointer colour - BEQ Call_PointerColour -10 - Pull "r0-r3" - MOV pc, lr ; else not defined - -Call_UpdateNormalColour - BL UpdateNormalColour - Pull "r0-r3,pc" - -BorderInitEntry Push "r0-r3,lr" ; entry used in default palette setting -Call_BorderColour - BL BorderColour - Pull "r0-r3,pc" - -Call_PointerColour - BL PointerColour - Pull "r0-r3,pc" - -; ***************************************************************************** - -UpdateNormalColour ROUT - Push "LR" - LDR lr, [WsPtr, #DisplayNColour] ; get the mask - TEQ lr, #63 ; is it brain-damaged VIDC10-compatible 256 colour mode? - BEQ %FT10 - AND r0, r0, lr ; and mask it off - AND r0, r0, #255 ; definitely no more than 256 palette entries - BL UpdateSettingAndVIDC -05 - MOV r4, #0 ; indicate successful PaletteV op - Pull "pc" - -10 - AND r0, r0, #15 ; starting palette entry -20 - LDR r3, =&88CC8800 ; r3 = bits controlled by bits 4..7 of pixel value - BIC r2, r2, r3 - TST r0, #&10 ; test bit 4 (r3,7) - ORRNE r2, r2, #&00008800 - TST r0, #&20 ; test bit 5 (g2,6) - ORRNE r2, r2, #&00440000 - TST r0, #&40 ; test bit 6 (g3,7) - ORRNE r2, r2, #&00880000 - TST r0, #&80 ; test bit 7 (b3,7) - ORRNE r2, r2, #&88000000 - BL UpdateSettingAndVIDC - ADD r0, r0, #&10 - CMP r0, #&100 - BCC %BT20 - B %BT05 - -BorderColour ROUT - Push "LR" - MOV r0, #256 ; pseudo-palette-index for border colour - MOV r1, #3 ; both colours - BL UpdateSettingAndVIDC - -; Now test for BBC gap mode (ie 3 or 6) -; if so then set colour 2 to same as border, and colour 3 to inverse - - LDR lr, [WsPtr, #DisplayModeFlags] - TST lr, #Flag_BBCGapMode - BEQ %FT10 - - MOV r0, #2 ; make colour 2 (gap) same as border - BL UpdateSettingAndVIDC - - MOV r0, #3 ; make colour 3 inverse gap - MVN r2, r2 ; invert R, G and B - EOR r2, r2, #&FF ; but use same supremacy - BL UpdateSettingAndVIDC -10 - MOV r4, #0 ; indicate successful PaletteV op - Pull "pc" - - -PointerColour ROUT - Push "LR" - ANDS r0, r0, #3 ; force pointer colour number in range 1..3 - BEQ %FT10 ; zero is invalid - ADD r0, r0, #256 ; index in range 257..259 - MOV r1, #3 - BL UpdateSettingAndVIDC -10 - MOV r4, #0 ; indicate successful PaletteV op - Pull "pc" - -; UpdateSettingStraightRGB -; -; in: r0 = index (0..255 for normal, 256 for border, 257..259 for pointer) -; r1 = bit mask of which flash states to update (bit 0 set => 1st, bit 1 set => 2nd) -; r3 = SBGR -; r4 = SBGR to EOR with to go from 1st to 2nd flash state - -; out: r0,r1,r2,r4 preserved -; r3 corrupted - -UpdateSettingStraightRGB EntryS "r2,r5,r6,r7" - - ANDS r5, r3, #1 :SHL: 12 ; get supremacy bit (s) in 1st colour - MOVNE r5, #&FF ; r5 = 000000SS - AND r6, r3, #&FF0 ; r6 = 00000BG0 - ORR r5, r5, r6, LSL #16 ; r5 = 0BG000SS - AND r6, r3, #&0FF ; r6 = 000000GR - ORR r5, r5, r6, LSL #12 ; r5 = 0BGGR0SS - AND r6, r3, #&00F ; r6 = 0000000R - ORR r5, r5, r6, LSL #8 ; r5 = 0BGGRRSS - AND r6, r3, #&F00 ; r6 = 00000B00 - ORR r3, r5, r6, LSL #20 ; r3 = BBGGRRSS - - ANDS r5, r4, #1 :SHL: 12 ; get supremacy bit (s) in EOR mask - MOVNE r5, #&FF ; r5 = 000000SS - AND r6, r4, #&FF0 ; r6 = 00000BG0 - ORR r5, r5, r6, LSL #16 ; r5 = 0BG000SS - AND r6, r4, #&0FF ; r6 = 000000GR - ORR r5, r5, r6, LSL #12 ; r5 = 0BGGR0SS - AND r6, r4, #&00F ; r6 = 0000000R - ORR r5, r5, r6, LSL #8 ; r5 = 0BGGRRSS - AND r6, r4, #&F00 ; r6 = 00000B00 - ORR r4, r5, r6, LSL #20 ; r4 = BBGGRRSS - - B UpdateSettingCommon - - -; UpdateSettingAndVIDC -; -; in: r0 = index (0..255 for normal, 256 for border, 257..259 for pointer) -; r1 = bit mask of which flash states to update (bit 0 set => 1st, bit 1 set => 2nd) -; r2 = BBGGRRSS -; -; out: r0, r1, r2 preserved -; r3, r4 corrupted -; - -UpdateSettingAndVIDC ALTENTRY - - MOV r3, r2 - MOV r4, #0 ; indicate no EORing between parts - -; ... and drop thru to - -; UpdateSettingCommon -; -; in: r0 = index (0..255 for normal, 256 for border, 257..259 for pointer) -; r1 = bit mask of which flash states to update (bit 0 set => 1st, bit 1 set => 2nd) -; r3 = BBGGRRSS -; r4 = BBGGRRSS to EOR with to go from 1st to 2nd flash state -; r2, r5, r6, r7, lr stacked -; -; out: r0, r1, r2, r4 preserved -; r3 corrupted -; -UpdateSettingCommon ROUT - PHPSEI ; protect against IRQs - - Push "r8, r9" - - LDRB r5, [WsPtr, #ScreenBlankFlag] - TEQ r5, #0 - MOVNE r5, #&FFFFFFFF ; bits to knock out if blanked - - LDROSB r2, FlashState ; 0 => second, 1 => first - CMP r2, #1 ; C=0 => second, C=1 => first - - TST r1, #1 - BEQ %FT10 ; skip if not setting 1st colour - LDR r2, [WsPtr, #FirPalAddr] - ADD r8, r2, #(256+1+3)*4*4 ; r8 -> rgb transfer tables - STR r3, [r2, r0, LSL #2]! ; store in logical colour and write back pointer - AND r6, r3, #&0000FF00 ; r6 = red << 8 - LDRB r6, [r8, r6, LSR #8] ; r6 = gamma(red) - ADD r8, r8, #&100 ; r8 -> green transfer - AND r9, r3, #&00FF0000 ; r9 = green << 16 - LDRB r9, [r8, r9, LSR #16] ; r9 = gamma(green) - ORR r6, r6, r9, LSL #8 ; r6 = gamma(red) + (gamma(green)<<8) - ADD r8, r8, #&100 ; r8 -> blue transfer - AND r9, r3, #&FF000000 ; r9 = blue << 24 - LDRB r9, [r8, r9, LSR #24] ; r9 = gamma(blue) - ORR r6, r6, r9, LSL #16 ; r6 = gamma(red) + (gamma(green)<<8) + (gamma(blue)<<16) - AND r9, r3, #&000000FF ; knock out rgb from original - ORR r6, r9, r6, LSL #8 ; and or in new bits - STR r6, [r2, #(256+1+3)*4*2] ; store in physical copy - - BCC %FT10 ; only hit hardware if flash state = first - -;;;mjsHAL -;;; old code had possible LCD greyscale munging, not supported in interim s.vduhint code -;;; - [ UseGraphicsV - Push "r0-r2,r4,lr" - MOV r4, #GraphicsV_WritePaletteEntry - BIC r1, r6, r5 ; r1 = palette colour after knocking out blanking bits - AND r2, r0, #255 ; reduced index (0..255 normal, 0 border, 1..3 pointer) - CMP r0, #256 ; HI if pointer - MOVLS r0, r0, LSR #8 ; type 0=normal, 1=border - MOVHI r0, #2 ; type 2=pointer - BL CallGraphicsV - Pull "r0-r2,r4,lr" - | - Push "r0-r3, r12, lr" - BIC r1, r6, r5 ; r1 = palette colour after knocking out blanking bits - AND r2, r0, #255 ; reduced index (0..255 normal, 0 border, 1..3 pointer) - CMP r0, #256 ; HI if pointer - MOVLS r0, r0, LSR #8 ; type 0=normal, 1=border - MOVHI r0, #2 ; type 2=pointer - mjsAddressHAL - mjsCallHAL HAL_Video_WritePaletteEntry - Pull "r0-r3, r12, lr" - ] - -10 - EOR r3, r3, r4 ; toggle requested bits for 2nd half - TST r1, #2 - BEQ %FT20 ; skip if not setting 2nd colour - LDR r2, [WsPtr, #SecPalAddr] - ADD r8, r2, #(256+1+3)*4*3 ; r8 -> rgb transfer tables - STR r3, [r2, r0, LSL #2]! ; store in logical copy and write back - - AND r6, r3, #&0000FF00 ; r6 = red << 8 - LDRB r6, [r8, r6, LSR #8] ; r6 = gamma(red) - ADD r8, r8, #&100 ; r8 -> green transfer - AND r9, r3, #&00FF0000 ; r9 = green << 16 - LDRB r9, [r8, r9, LSR #16] ; r9 = gamma(green) - ORR r6, r6, r9, LSL #8 ; r6 = gamma(red) + (gamma(green)<<8) - ADD r8, r8, #&100 ; r8 -> blue transfer - AND r9, r3, #&FF000000 ; r9 = blue << 24 - LDRB r9, [r8, r9, LSR #24] ; r9 = gamma(blue) - ORR r6, r6, r9, LSL #16 ; r6 = gamma(red) + (gamma(green)<<8) + (gamma(blue)<<16) - AND r9, r3, #&000000FF ; knock out rgb from original - ORR r6, r9, r6, LSL #8 ; and or in new bits - STR r6, [r2, #(256+1+3)*4*2] ; store in physical copy - - BCS %FT20 ; only hit hardware if flash state = second - -;;;mjsHAL -;;; old code had possible LCD greyscale munging, not supported in interim s.vduhint code -;;; - [ UseGraphicsV - Push "r0-r2,r4,lr" - MOV r4, #GraphicsV_WritePaletteEntry - BIC r1, r6, r5 ; r1 = palette colour after knocking out blanking bits - AND r2, r0, #255 ; reduced index (0..255 normal, 0 border, 1..3 pointer) - CMP r0, #256 ; HI if pointer - MOVLS r0, r0, LSR #8 ; type 0=normal, 1=border - MOVHI r0, #2 ; type 2=pointer - BL CallGraphicsV - Pull "r0-r2,r4,lr" - | - Push "r0-r3, r12, lr" - BIC r1, r6, r5 ; r1 = palette colour after knocking out blanking bits - AND r2, r0, #255 ; reduced index (0..255 normal, 0 border, 1..3 pointer) - CMP r0, #256 ; HI if pointer - MOVLS r0, r0, LSR #8 ; type 0=normal, 1=border - MOVHI r0, #2 ; type 2=pointer - mjsAddressHAL - mjsCallHAL HAL_Video_WritePaletteEntry - Pull "r0-r3, r12, lr" - ] - -20 - PLP - Pull "r8, r9" - EXITS ; restore registers, claim vector - -; ***************************************************************************** -; -; PV_BulkRead - Read multiple palette entries with one call -; -; in: R0 => list of colours wanted, or 0 to start with first and increment -; R1 = b24-b31 - colour type: 16/17/18/24/25 -; b00-b23 - number of colours to do -; -; R2 => memory for first flash state colours (and second if R3=0) -; R3 => memory for second flash state colours (if 0, intermingle with R2 instead) -; -; out: all preserved (R4 set to 0 to show call handled) - -; flags used to control routine - -PV_BR_WantFirst * 1 ; doing 16 or 17 -PV_BR_WantSecond * 2 ; doing 16 or 18 -PV_BR_HaveList * 4 ; we have a list of colours -PV_BR_TwoLists * 8 ; we have two output areas (R2 & R3 valid) -PV_BR_Border * 16 ; doing 24 -PV_BR_Mouse * 32 ; doing 25 - -PV_BulkRead ROUT - Push "R0-R3,R6-R11" ; return addr already stacked - - MOV R6,R1,LSR #24 ; isolate the colour type - - MOV R7,#(PV_BR_WantFirst + PV_BR_WantSecond) - - CMP R6,#17 ; do we want both flash states ? - BICEQ R7,R7,#PV_BR_WantSecond ; if 17 only want first flash state - - CMP R6,#18 - BICEQ R7,R7,#PV_BR_WantFirst ; if 18 only want second flash state - - CMP R6,#24 - ORREQ R7,R7,#PV_BR_Border - ORRGT R7,R7,#PV_BR_Mouse - - ;now set up other control flags - CMP R0,#0 - ORRNE R7,R7,#PV_BR_HaveList ; we have a list of colours - - CMP R3,#0 - ORRNE R7,R7,#PV_BR_TwoLists ; we have two output areas - - ;set up a mask for the number of colours - LDR R8,[WsPtr,#DisplayNColour] - TEQ R8,#63 - MOVEQ R8,#255 ; deal with braindamaged 8BPP case - - ;the mouse has colours 1-3 - TST R7,#PV_BR_Mouse - MOVNE R8,#3 - - ;take the colour type off the top of R1, leaving #colours wanted - BIC R1,R1,#&FF000000 - - ; register usage: - ; [R0]: colour list - ; R1: number of colours - ; [R2]: first flash state list - ; [R3]: second flash state list - ; R7: control flags - ; R8: mask for colour number - ; R9: loop counter - ; R10: misc - ; LR: misc - - MOV R9,#0 -30 - TST R7,#PV_BR_HaveList - LDRNE LR,[R0],#4 - MOVEQ LR,R9 ; LR = wanted colour number - - AND LR,LR,R8 ; ensure it is sensible - - TST R7,#PV_BR_Border - MOVNE LR,#256 ; border is stored as colour 256 - - TST R7,#PV_BR_Mouse - BEQ %FT40 - - TEQ LR,#0 - BEQ %FT50 ;colour 0 is invalid - ADD LR,LR,#256 ;bring into range (257-259) - -40 - TST R7,#PV_BR_WantFirst - - LDRNE R10,[WsPtr,#FirPalAddr] - - LDRNE R11,[R10,LR,LSL#2] ; BBGGRRSS - STRNE R11,[R2],#4 - - TST R7,#PV_BR_WantSecond - BEQ %FT60 ; have to use a branch here - another TST coming up - - LDR R10,[WsPtr,#SecPalAddr] - - LDR R11,[R10,LR,LSL#2] ; BBGGRRSS - - TST R7,#PV_BR_TwoLists - - STREQ R11,[R2],#4 - STRNE R11,[R3],#4 - -60 ADD R9,R9,#1 - CMP R9,R1 - BCC %BT30 -50 - MOV R4,#0 - Pull "R0-R3,R6-R11,PC" ; return addr already stacked - - -; ***************************************************************************** -; -; PV_ReadPalette - PaletteV read palette handler -; -; in: R0 = logical colour -; R1 = 16 (read normal colour) -; 24 (read border colour) -; 25 (read cursor colour) -; -; out: R2 = first flash setting (BBGGRRSS) -; R3 = second flash setting (BBGGRRSS) -; - -PV_ReadPalette ROUT - Push "r10,r11" - LDR r10, [WsPtr, #DisplayNColour] ; logical colours in this mode -1 - TEQ r10, #63 ; if bodgy 256 colour mode - MOVEQ r10, #255 ; then use AND mask of 255 - - TEQ r1, #24 ; is it reading border palette - MOVEQ r11, #&100 ; then set up border index - BEQ %FT10 ; and go - - TEQ r1, #25 ; is it reading pointer palette - BEQ %FT05 - AND r11, r0, r10 ; no, then force into suitable range - B %FT10 ; always skip -05 - ANDS r11, r0, #3 ; else force logical colour 0..3 - BEQ %FT99 ; and 0 is illegal, so do nothing - ADD r11, r11, #&100 ; set up correct index -10 - -; note no need to fudge 256-colour modes, since we have the correct full 256 entry palette - - LDR r10, [WsPtr, #FirPalAddr] - LDR r2, [r10, r11, LSL #2] ; r2 := 1st BBGGRRSS - LDR r10, [WsPtr, #SecPalAddr] - LDR r3, [r10, r11, LSL #2] ; r3 := 2nd BBGGRRSS -99 - MOV r4, #0 - Pull "r10, r11, pc" - -; ***************************************************************************** -; -; PV_1stFlashState - PaletteV routine to set first flash state -; - -PV_1stFlashState ROUT - [ UseGraphicsV - Entry "r0-r3" - | - Entry "r0-r3, r9, r10, r12" - ] - LDRB r1, [WsPtr, #ScreenBlankFlag] - TEQ r1, #0 - LDREQ r1, [WsPtr, #FirPalAddr] - ADDEQ r1, r1, #(256+1+3)*4*2 ; move pointer to physical palette copy - LDRNE r1, [WsPtr, #BlankPalAddr] -DoR0Flash - MOV r0, #0 ; type 0 (normal) - MOV r2, #0 ; start at entry 0 - MOV r3, #256 ; 256 entries - [ UseGraphicsV - MOV r4, #GraphicsV_WritePaletteEntries - BL CallGraphicsV - | - PHPSEI r10 ; disable IRQs round this bit - mjsAddressHAL - mjsCallHAL HAL_Video_WritePaletteEntries - PLP r10 - MOV r4, #0 - ] - EXIT - -; ***************************************************************************** -; -; PV_2ndFlashState - PaletteV routine to set second flash state -; - -PV_2ndFlashState ROUT - ALTENTRY - LDRB r1, [WsPtr, #ScreenBlankFlag] - TEQ r1, #0 - LDREQ r1, [WsPtr, #SecPalAddr] - ADDEQ r1, r1, #(256+1+3)*4*2 ; move pointer to physical palette copy - LDRNE r1, [WsPtr, #BlankPalAddr] - B DoR0Flash - -; ***************************************************************************** -; -; UpdateAllPalette - Update all VIDC palette entries -; - -UpdateAllPalette ROUT - [ UseGraphicsV - Entry "r0-r3, r10-r11" - | - Entry "r0-r3, r9, r10-r12" - mjsAddressHAL - ] -;sort out which palette to use - LDROSB r0, FlashState - CMP r0, #1 - LDRCS r1, [WsPtr, #FirPalAddr] ; FlashState = 1 => 1st state, 0 => 2nd state - LDRCC r1, [WsPtr, #SecPalAddr] - ADD r1, r1, #(256+1+3)*4*2 ; move pointer to physical palette copy - LDRB r10, [WsPtr, #ScreenBlankFlag] - TEQ r10, #0 - LDRNE r1, [WsPtr, #BlankPalAddr] ; blank palette after all -; - ADD r10, r1, #256*4 ; pointer to border colour - PHPSEI r11 ; disable IRQs round this bit - [ UseGraphicsV -;first, the normal colours - MOV r0, #0 ; type 0 (normal) - MOV r2, #0 ; start at entry 0 - MOV r3, #256 ; 256 entries - MOV r4, #GraphicsV_WritePaletteEntries - BL CallGraphicsV -;next, border colour - LDR r1, [r10] ; border colour - MOV r0, #1 ; type 1 - MOV r2, #0 ; index 0 - MOV r4, #GraphicsV_WritePaletteEntry - BL CallGraphicsV -;finally, pointer colours - ADD r1, r10, #4 ; pointer to pointer colours (oh yes) - MOV r0, #2 ; type 2 - MOV r2, #1 ; start at index 1 - MOV r3, #3 ; 3 entries - MOV r4, #GraphicsV_WritePaletteEntries - BL CallGraphicsV - | -;first, the normal colours - MOV r0, #0 ; type 0 (normal) - MOV r2, #0 ; start at entry 0 - MOV r3, #256 ; 256 entries - mjsCallHAL HAL_Video_WritePaletteEntries -;next, border colour - LDR r1, [r10] ; border colour - MOV r0, #1 ; type 1 - MOV r2, #0 ; index 0 - mjsCallHAL HAL_Video_WritePaletteEntry -;finally, pointer colours - ADD r1, r10, #4 ; pointer to pointer colours (oh yes) - MOV r0, #2 ; type 2 - MOV r2, #1 ; start at index 1 - MOV r3, #3 ; 3 entries - mjsCallHAL HAL_Video_WritePaletteEntries - ] -; - PLP r11 - MOV r4, #0 - EXIT - -; ***************************************************************************** -; -; PV_BlankScreen - Blank/unblank screen -; -; in: R0 = -1 => read blank state -; R0 = 0 => unblank screen -; R0 = 1 => blank screen -; -; out: R0 = old state (0=unblanked, 1=blanked) -; R4 = 0 - -PV_BlankScreen ROUT - Push "r1-r3, r9" - - LDRB r4, [WsPtr, #ScreenBlankFlag] - CMP r0, #1 - BHI %FT99 ; just reading - TEQ r0, r4 ; changing to same state? - BEQ %FT99 ; if so, do nothing - - AND r0, r0, #1 - STRB r0, [WsPtr, #ScreenBlankFlag] ; update new state - LDRB r1, [WsPtr, #ScreenBlankDPMSState] - - [ UseGraphicsV - MOV r4, #GraphicsV_SetBlank - BL CallGraphicsV - | - Push "r0, r12" - mjsAddressHAL - mjsCallHAL HAL_Video_SetBlank - Pull "r0, r12" - ] - - ; for backward compatibility, show video DMA state in - ; MEMC soft copy (DON'T call OS_UpdateMEMC, which would also - ; make redundant call to HAL) - ; - SavePSR r2 - MOV r9, #0 - WritePSRc SVC_mode+I_bit+F_bit, r14 - LDR r1, [r9, #MEMC_CR_SoftCopy] - TEQ r0, #1 - BICEQ r1, r1, #(1 :SHL: 10) - ORRNE r1, r1, #(1 :SHL: 10) - STR r1, [r9, #MEMC_CR_SoftCopy] - RestPSR r2 - - BL UpdateAllPalette ; update all palette, including border + pointer - -99 - MOV r0, r4 - MOV r4, #0 - Pull "r1-r3, r9, pc" - -; ***************************************************************************** -; -; PV_GammaCorrect - Update gamma correction tables -; -; in: r0 -> red table -; r1 -> green table -; r2 -> blue table -; -; out: r4 = 0 - -PV_GammaCorrect ROUT - Push "r0-r3,r5-r8" - LDR r4, [WsPtr, #FirPalAddr] - ADD r4, r4, #(256+1+3)*4*4 ; point to gamma tables - ADD r3, r4, #256 -10 - LDR lr, [r0], #4 - STR lr, [r4], #4 - TEQ r4, r3 - BNE %BT10 - - ADD r3, r4, #256 -20 - LDR lr, [r1], #4 - STR lr, [r4], #4 - TEQ r4, r3 - BNE %BT20 - - ADD r3, r4, #256 -30 - LDR lr, [r2], #4 - STR lr, [r4], #4 - TEQ r4, r3 - BNE %BT30 - -; now go through the logical palette, recomputing the physical from it using the new tables - - SUB r0, r4, #3*256 ; r0 -> red table - SUB r1, r4, #2*256 ; r1 -> green table - SUB r2, r4, #1*256 ; r2 -> blue table - - LDR r4, [WsPtr, #FirPalAddr] ; r4 -> start of logical palette - ADD r5, r4, #260*4*2 ; r5 -> start of physical palette - MOV r6, r5 ; r6 = r5 = end of logical palette -40 - LDR r7, [r4], #4 ; get word - AND r8, r7, #&0000FF00 ; r8 = red << 8 - LDRB r8, [r0, r8, LSR #8] ; r8 = gamma(red) - AND lr, r7, #&00FF0000 ; lr = green << 16 - LDRB lr, [r1, lr, LSR #16] ; lr = gamma(green) - ORR r8, r8, lr, LSL #8 ; r8 = gamma(red) + (gamma(green)<<8) - AND lr, r7, #&FF000000 ; lr = blue << 24 - LDRB lr, [r2, lr, LSR #24] ; lr = gamma(blue) - ORR r8, r8, lr, LSL #16 ; r8 = gamma(red) + (gamma(green)<<8) + (gamma(blue)<<16) - AND lr, r7, #&000000FF ; lr = 000000SS - ORR r8, lr, r8, LSL #8 ; r8 = gamma-corrected BBGGRRSS value - STR r8, [r5], #4 ; store word - TEQ r4, r6 - BNE %BT40 - - BL UpdateAllPalette - - MOV r4, #0 - Pull "r0-r3,r5-r8, pc" - - - [ LCDInvert -; ***************************************************************************** -; -; PV_LCDInvert - Invert the LCD palette -; -; in: r0 = inversion state to use (0=uninverted, 1=inverted) -; -; out: r4 = 0 - -PV_LCDInvert ROUT - ;;;mjsHAL not supported - ;;; - MOV r4, #0 - Pull "pc" - ] - - [ StorkPowerSave - -; ***************************************************************************** - -PV_VIDCDisable ROUT - Push "r0-r3, r9, r12" - - MOV r0, #1 - mjsAddressHAL - mjsCallHAL HAL_Video_SetPowerSave - - MOV r4, #0 - Pull "r0-r3, r9, r12, pc" - -; ***************************************************************************** - -PV_VIDCRestore ROUT - Push "r0-r3, r9, r12" - - MOV r0, #0 - mjsAddressHAL - mjsCallHAL HAL_Video_SetPowerSave - - MOV r4, #0 - Pull "r0-r3, r9, r12, pc" - - ] ; StorkPowerSave - - END diff --git a/s/vdu/vduplot b/s/vdu/vduplot deleted file mode 100644 index 2cf8dfe2..00000000 --- a/s/vdu/vduplot +++ /dev/null @@ -1,1611 +0,0 @@ -; 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.VduPlot -; -; ARTHUR OPERATING SYSTEM - Vdu Drivers -; ======================= -; -; Vdu graphics code - Entry point for plotting & low level primitives -; & Ecf pattern setting -; Author R C Manby -; Date 5.9.86 -; - -; ***************************************************************************** -; -; EM -; PLOT - Graphics operation, eg triangle, line etc. -; ==== -; -; The plot operation, and the co-ordinate to plot at given by bytes -; in the vdu queue, as follows -; QQ+0 - plot number -; QQ+1 - xLo -; QQ+2 - xHi -; QQ+3 - yLo -; QQ+4 - yHi -; -; The co-ordinate is in external 16 bit form. -; If 2 or 3 are required, they are taken from ICursor & OldCs -; -; Also, both PLOT and EntryFromSWIPlot are entered with R6 = CursorFlags -; -EM -PLOT ROUT - [ {TRUE} - GraphicsMode R0 ; Quit if not a graphics mode - MOVNE PC, Link - | - LDR R0, [WsPtr, #NPix] - CMP R0, #0 ; Quit if not a graphics mode - MOVEQ PC, Link - ] - - ASSERT ((QQ+1):AND:3)=0 - LDR R2, [WsPtr, #QQ+1] ; R2 = xlo,xhi,ylo,yhi - MOV R0, R2, LSL #16 ; R0 = 0 ,0 ,xlo,xhi - MOV R0, R0, ASR #16 ; R0 = xlo,xhi,sgn,sgn - MOV R1, R2, ASR #16 ; R1 = ylo,yhi,sgn,sgn - - LDRB R2, [WsPtr, #QQ+0] ; plot mode - MOV R9, #0 ; indicate coming from VDU Plot - -EntryFromSWIPlot - SaveRetAdr - -; now convert to internal coords (modified EIG code) - - ASSERT OrgY = OrgX +4 - ASSERT GCsX = OrgX +8 - ASSERT GCsY = OrgX +12 - ASSERT YEigFactor = XEigFactor +4 - - ADD R3, WsPtr, #OrgX - - LDMIA R3!, {R4-R5} ; R4 = OrgX: R5 = OrgY - TST R2, #4 ; If bit2 is clear, then relative - LDMEQIA R3, {R7-R8} ; so load old cursor position - ADDEQ R0, R0, R7 ; and add - ADDEQ R1, R1, R8 - STMIA R3, {R0-R1} ; store new coords in GCsX,GCsY - - ADD R3, WsPtr, #XEigFactor - LDMIA R3, {R7-R8} ; R7 = XEigFactor: R8 = YEigFactor - ADD R0, R0, R4 ; add on origin - ADD R1, R1, R5 - MOV R0, R0, ASR R7 ; and shift down - MOV R1, R1, ASR R8 - - ADD R3, WsPtr, #NewPtX - STMIA R3, {R0-R1} - -; -; The 2 LSBits of the plot code specify fg/bg colour and action as :- -; 0 No effect eqv. of Gcol(5,c) -; 1 Foreground colour using foreground Gcol action -; 2 Invert eqv. of Gcol(4,c) -; 3 Background colour using background Gcol action -; - -; *****Change made by DJS -; Original code was: -; MOV R3, R2, LSL #30 ; put bottom 2 bits into top 2 bits -; CMP R3, #&40000000 ; set lots of flags -; -; ADDMI R4, WsPtr, #BgEcfOraEor ; if 0 or 3 -; ADRCC R4, NoEffect ; if 0 -; ADDEQ R4, WsPtr, #FgEcfOraEor ; if 1 -; ADRVS R4, Invert ; if 2 - - MOVS R3, R2, LSL #31 ;Put bit 1 in C, NOT(bit 0) in Z - ADR R4, NoEffect ; if 0, 1, 2 or 3 - ADDNE R4, WsPtr, #FgEcfOraEor ; if 1 or 3 - ADRCS R4, Invert ; if 2 or 3 - ADDHI R4, WsPtr, #BgEcfOraEor ; if CS & NE - i.e. 3 - -; *****End of change made by DJS - - STR R4, [WsPtr, #GColAdr] ; save address of Ecf to plot with - - TST R6, #ClipBoxEnableBit - BLNE DoPlotClipBox - - BIC R11, R2, #2_111 ; ARMv4 says we have to keep bits 1:0 of PC =0 - [ No26bitCode - ADR R14, CTidy ; set up return address - | - ADR R14, CTidy + SVC_mode ; set up return address - ] - ; R0=X, R1=Y, R2=plot code - ADD PC, PC, R11, LSR #1 ; jump to branch - & 0 ; dummy word - - B LineDrawSolid ; 0 - Solid line - B LineDrawSolid ; 8 - Solid line, endpoint omitted - B LineDrawDotted ; 16 - Dot-dash line, restart pattern - B LineDrawDotted ; 24 - Dot-dash line, restart pattern, - ; endpoint omitted - B LineDrawSolid ; 32 - Solid extension line - B LineDrawSolid ; 40 - Solid extension line, endpoint omitted - B LineDrawDotted ; 48 - Dot-dash extension line, continue pattern - B LineDrawDotted ; 56 - Dot-dash extension line, continue pattern, - ; endpoint omitted - B PlotPoint ; 64 - Point plot - B FillLRnonBg ; 72 - Line fill L&R, upto non-background - B TriangleFill ; 80 - Triangle fill - B FillLRtoBg ; 88 - Fill right, upto background - B RectangleFill ; 96 - Rectangle fill - B FillLRtoFg ; 104 - Line fill L&R, upto foreground - B ParallelogramFill ; 112 - Parallelogram Fill - B FillLRnonFg ; 120 - Fill right, upto non-foreground - B FloodNonBg ; 128 - Flood to non-bg (ie over bg) - B FloodToFg ; 136 - Flood to fg (ie over non-fg) - B CircleOutline ; 144 - Circle outline - B CircleFill ; 152 - Circle fill - B CircleArc ; 160 - Circular arc outline - B SegmentFill ; 168 - Segment fill - B SectorFill ; 176 - Sector (pie) fill - B BlockCopyMove ; 184 - Block copy/move - B EllipseOutline ; 192 - Ellipse outline - B EllipseFill ; 200 - Ellipse fill - B NYA ; 208 - Unassigned - B NYA ; 216 - Unassigned - B NYA ; 224 - Unassigned - B SpritePlot ; 232 - Sprite plot - B NYA ; 240 - Assigned to applications - B NYA ; 248 - Assigned to applications - -CTidy ; The "normal" return point after a plot - ; operation, any call that does not want - ; the cursors moving should pull return - ; address off the stack - - ; Shuffle the cursors along - ; NewPt -> ICursor -> OldCs -> OlderCs - ; - ; ECursor was set earlier by EIG - - ADD R0, WsPtr, #OldCsX - LDMIA R0, {R1,R2, R3,R4, R5,R6} ; OldCs(X,Y) ICursor(X,Y) NewPt(X,Y) - ADD R0, WsPtr, #OlderCsX - STMIA R0, {R1,R2, R3,R4, R5,R6} - Return - -NYA - MOV R0, R2 ; R0 := plot code - MOV R10, #UKPLOTV - Push "R9, WsPtr, R14" ; save SWIPlot indicator, WsPtr + link - BL VduQQVec - Pull "R9, WsPtr, PC", VC ; return to CTidy if no error - -; error in UKPLOTV - - Pull "R9, WsPtr" ; restore SWIPlot indicator and WsPtr - ADD R13, R13, #8 ; throw away return to CTidy - ; and return address stacked by PLOT - TEQ R9, #0 ; called from Wrch ? - BEQ VduBadExit ; yes, then go to error exit code - B SWIPlotBadExit ; no, then go to SWIPlot error exit - -VduQQVec - ADD R1, WsPtr, #QQ -VduGoVec - CallAVector - - - -; -; Words for forming ZGORA & ZGEOR for colour actions 0 to 7, where -; 0=Store, 1=OR, 2=AND, 3=EOR, 4=Inverse, 5=No change, -; 6=And Not(colour) ie BIC, 7=Or Not(colour) -; -; -; The values correspond to TBzgoo etc on the 6502 and are stored -; in the following order zgoo,zgeo,zgoe,zgee to allow LDM to be used -; -; Action -; 0 1 2 3 4 5 6 7 -; TBzgoo OR the OR :- F,0,0,F,F,F,0,0 -; TBzgeo EOR the OR :- 0,0,F,F,F,F,0,F -; TBzgoe OR the EOR :- 0,F,0,0,F,F,0,F -; TBzgee EOR the EOR :- F,F,F,0,0,F,0,F -; - -TBscrmasks * 2_10010111000011111110110001010011 - - [ {FALSE} -TBscrmask - & &FFFFFFFF ;Store colour to screen ( OR the OR) - & &00000000 ; (EOR the OR) - & &00000000 ; ( OR the EOR) - & &FFFFFFFF ; (EOR the EOR) - - & &00000000 ;OR colour to screen - & &00000000 - & &FFFFFFFF - & &FFFFFFFF - - & &00000000 ;AND - & &FFFFFFFF - & &00000000 - & &FFFFFFFF - - & &FFFFFFFF ;EOR - & &FFFFFFFF - & &00000000 - & &00000000 - - & &FFFFFFFF ;Invert - & &FFFFFFFF - & &FFFFFFFF - & &00000000 - - & &FFFFFFFF ;No change - & &FFFFFFFF - & &FFFFFFFF - & &FFFFFFFF - - & &00000000 ;BIC (ie AND NOTcol) - & &00000000 - & &00000000 - & &00000000 - - & &00000000 ;OR NOTcol - & &FFFFFFFF - & &FFFFFFFF - & &FFFFFFFF - ] - - MALIGN 64 ; Invert and NoEffect must be aligned to a multiple - ; of 64 for line drawing routines (TMD) - - ;Interleaved zgora & zgeor values to give invert - ; and no effect plotting, used when plot code -Invert ; overrides Fg/Bg Gcol colour and action. - & &00000000 - & &FFFFFFFF - & &00000000 - & &FFFFFFFF - & &00000000 - & &FFFFFFFF - & &00000000 - & &FFFFFFFF - & &00000000 - & &FFFFFFFF - & &00000000 - & &FFFFFFFF - & &00000000 - & &FFFFFFFF - & &00000000 - & &FFFFFFFF -NoEffect - & &00000000 - & &00000000 - & &00000000 - & &00000000 - & &00000000 - & &00000000 - & &00000000 - & &00000000 - & &00000000 - & &00000000 - & &00000000 - & &00000000 - & &00000000 - & &00000000 - & &00000000 - & &00000000 - -; ***************************************************************************** -; -; EIG - External to internal graphic coordinate conversion -; === -; -; Convert external coordinates (either relative or absolute) into -; internal ones. No windowing is done. -; -; -; On entry, R0 (X), R1 (Y) hold coordinate (external co-ords) -; R2 holds plot mode, where bit2 = 0 for relative (add ECursor) -; = 1 for absolute (add origin) -; -; On exit, R0 (X), R1 (Y) hold internal representation -; R2 preserved -; -; R3 corrupt -; -; The external cursor (GCsX,GCsY) is updated to the new point, -; hence in triangle relative mode, the points are relative to -; the last point specified, not the original. -; -EIG - ;Do Ycoord first - TST R2,#4 ;If bit2 is clear - LDREQ R3,[WsPtr,#GCsY] ;then co-ord is relative - ADDEQ R1,R1,R3 ; so add previous cursor (ext. rep.) - - STR R1,[WsPtr,#GCsY] ;Update previous cursor - LDR R3,[WsPtr,#OrgY] ;Add origin - ADD R1,R1,R3 - - LDR R3, [WsPtr, #YEigFactor] - MOV R1,R1,ASR R3 ;Transform 0-1023 to 0-255 or 0-511 - - ;Do Xcoord - LDREQ R3,[WsPtr,#GCsX] ;If relative then - ADDEQ R0,R0,R3 ; add previous cursor (ext. rep.) - - STR R0,[WsPtr,#GCsX] ;Update previous cursor - LDR R3,[WsPtr,#OrgX] ;Add origin - ADD R0,R0,R3 - - LDR R3,[WsPtr,#XEigFactor] - MOV R0,R0,ASR R3 ;Transform 0-1279 to 0-639/0-319/0-159 - - [ No26bitCode - MOV PC,R14 - | - MOVS PC,R14 - ] - -; ***************************************************************************** -; -; IEG - Inverse of EIG. Convert ICursor to ECursor -; === -; -; On exit, R0 (X), R1 (Y) holds ECursor, ECursor updated -; R2, R3 hold XEigFactor, YEigFactor -; R4, R5 corrupt -; - ASSERT GCsIY = GCsIX +4 - ASSERT YEigFactor = XEigFactor +4 - ASSERT OrgY = OrgX +4 - ASSERT GCsY = GCsX +4 -IEG - ADD R0, WsPtr, #GCsIX - LDMIA R0, {R0,R1} ; load graphics cursor (internal) -IEGB - ADD R2, WsPtr, #XEigFactor - LDMIA R2, {R2, R3} ; R2 = XEigFactor; R3 = YEigFactor - ADD R4, WsPtr, #OrgX - LDMIA R4, {R4, R5} ; R4 = OrgX; R5 = OrgY - RSB R0, R4, R0, LSL R2 ; R0 = (X << XEigFactor)-OrgX - RSB R1, R5, R1, LSL R3 ; R1 = (Y << YEigFactor)-OrgY - ADD R4, WsPtr, #GCsX - STMIA R4, {R0,R1} ; write graphics cursor (external) - - [ No26bitCode - MOV PC,R14 - | - MOVS PC,R14 - ] - - [ {FALSE} -; ***************************************************************************** -; -; Window - Check a coordinate against the graphics window -; ====== -; -; On entry, R0 (X), R1 (Y) holds coordinate to window -; On exit, R0,R1 preserved, -; R3 corrupt -; R2 holds result, as follows: -; -; | | -; 1001 | 1000 | 1010 -; | | -; -----+------+----- -; | | -; 0001 | 0000 | 0010 -; | | -; -----+------+----- -; | | -; 0101 | 0100 | 0110 -; | | -; -; -; -Window - MOV R2,#0 - LDR R3,[WsPtr,#GWBRow] ;Test ycoord against window - CMP R1,R3 - ORRLT R2,R2,#4 ;Set bit 2 if Y < window - - LDR R3,[WsPtr,#GWTRow] - CMP R3,R1 - ORRLT R2,R2,#8 ;Set bit 3 if Y > window - - LDR R3,[WsPtr,#GWLCol] ;Test xcoord against window - CMP R0,R3 - ORRLT R2,R2,#1 ;Set bit 0 if X < window - - LDR R3,[WsPtr,#GWRCol] - CMP R3,R0 - ORRLT R2,R2,#2 ;Set bit 1 if X > window - - [ No26bitCode - MOV PC,R14 - | - MOVS PC,R14 ;Return to whence we came - ] - - ] -; ***************************************************************************** -; -; ScreenAddr - Generate screen address of coordinate -; ========== -; -; On entry, R0 (X), R1 (Y) holds coordinate - must be within graphics window -; On exit, R0,R1 preserved, -; R2 holds word address -; R3 holds pixel mask -; -; R7,R8 corrupt -ScreenAddr - ASSERT LineLength = YWindLimit +4 - - ADD R7, WsPtr, #YWindLimit - LDMIA R7, {R7,R8} ; R7=YWindLimit,R8=LineLength - SUB R2, R7, R1 ; flip ycoord into R2 - - LDR R7, [WsPtr, #ScreenStart] ; add the screen start - MLA R2, R8, R2, R7 ; to Ycoord * bytes per row - - LDR R3, [WsPtr, #XShftFactor] ; R7 := 2,3,4 or 5 - MOV R8, R0, ASR R3 ; R8 := word offset - ADD R2, R2, R8, LSL #2 ; add on to screen address - - EOR R7, R0, R8, LSL R3 ; R7 := pixel offset - ADD R3, WsPtr, #RAMMaskTb - LDR R3, [R3, R7, LSL #2] ; R3 := mask for this pixel - - [ No26bitCode - MOV PC, R14 - | - MOVS PC, R14 ; and return - ] - -; ***************************************************************************** -; -; PlotPoint - Plot a point in the current colour -; ========= -; -; On entry, R0 (X), R1 (Y) holds coordinate of point -; On exit, R0,R1 preserved -; R2-R8 corrupt -; R9-R11 preserved -; - -PlotPoint - WINDow R0,R1, R2,R3,R4,R5 - MOVLT PC, R14 ; If outside window, give up - - ASSERT LineLength = YWindLimit +4 - - ADD R7, WsPtr, #YWindLimit - LDMIA R7, {R7,R8} ; R7=YWindLimit; R8=LineLength - SUB R2, R7, R1 ; flip ycoord into R2 - -; *****Change made by DJS -; Original code was: -; ASSERT GColAdr = XShftFactor +4 -; ASSERT ScreenStart = XShftFactor +8 -; -; ADD R4, WsPtr, #XShftFactor ; R4=XShftFactor; R5=GColAdr -; LDMIA R4, {R4, R5, R7} ; R7=ScreenStart -; -; MLA R2, R8, R2, R7 ; R2=ScreenStart+Y*LineLength -; MOV R8, R0, ASR R4 ; R8 := XCoord DIV 4,8,16 -; ; or 32 -; EOR R7, R0, R8, LSL R4 ; R7 := pixel offset in word -; ADD R3, WsPtr, #RAMMaskTb -; LDR R3, [R3, R7, LSL #2] ; R3 := mask for this pixel -; -; EOR R6, R1, #7 ; flip Ycoord -; AND R6, R6, #7 ; line within ecf -; This does not calculate the ecf line correctly, resulting in bugs if (e.g.) -; a destination sprite is not a multiple of 8 pixels high. - - AND R6, R2, #7 ; R6 := line with ecf - - ASSERT GColAdr = XShftFactor +4 - ASSERT ScreenStart = XShftFactor +8 - - ADD R4, WsPtr, #XShftFactor ; R4=XShftFactor; R5=GColAdr - LDMIA R4, {R4, R5, R7} ; R7=ScreenStart - - MLA R2, R8, R2, R7 ; R2=ScreenStart+Y*LineLength - MOV R8, R0, ASR R4 ; R8 := XCoord DIV 4,8,16 or 32 - EOR R7, R0, R8, LSL R4 ; R7 := pixel offset in word - ADD R3, WsPtr, #RAMMaskTb - LDR R3, [R3, R7, LSL #2] ; R3 := mask for this pixel - -; *****End of change made by DJS - - ADD R5, R5, R6, LSL #3 - LDMIA R5, {R5, R6} ; get zgora,zgeor - - AND R5, R5, R3 ; mask zgora - AND R6, R6, R3 ; & zgeor for this pixel - [ AvoidScreenReads - CMP R5, #&FFFFFFFF - LDRNE R7, [R2, R8, LSL #2] - | - LDR R7, [R2, R8, LSL #2] - ] - ORR R7, R7, R5 ; and hit the screen - EOR R7, R7, R6 - STR R7, [R2, R8, LSL #2] - MOV PC, R14 - -; ***************************************************************************** -; -; ComplexEcfPattern -; ================= -; -; On entry, R0 holds pattern number, where 2..6 means Ecf1..4 -; -; Vdu queue holds -; -; QQ+0 pattern number -; QQ+1 pattern bytes 0 -; | | -; QQ+8 7 -; -; ComplexEcfPat10 is an entry point from simple Ecf setting for 8 bpp modes -; ie simple=complex in 8 bpp modes -; R1 points to Ecf(n) to be programmed. -; -; Corrupts R0..R3 -; - -ComplexEcfPattern ROUT ; R0 holds 2,3,4,5 for Ecfs 1,2,3,4 - ADD R1, WsPtr, #(Ecf1-2*8) - ADD R1, R1, R0, LSL #3 ; point R1 at Ecf(n) -ComplexEcfPat10 - ADD R0, WsPtr, #(QQ+1) - LDR R2, [WsPtr, #BBCcompatibleECFs] ; if in BBC mode - CMP R2, #0 - BEQ ComplexEcfPat20 ; then unmangle the interleaved - ; pixels - LDMIA R0, {R2,R3} ; else (native) use as given - STMIA R1, {R2,R3} - B SetColour ; update FgEcf & BgEcf incase they use this Ecf - -; R1 points at Ecf(n) -; R0 points at QQ+1 -; -; Uses R2 - pointer into InterleaveTB(BitsPerPix) -; R3 - byte to process 7..0 -; R4 - #1 -; R5 - bit within byte to process 7..0 -; R6 - result byte -; R7 - byte from queue -; R8 - bit mask from InterleaveTB(BitsPerPix,R5) - -ComplexEcfPat20 - ADR R2, InterleaveTB - LDR R3, [WsPtr, #Log2BPP] ; 0,1,2,3 means 1,2,4,8 bits per pixel - ADD R2, R2, R3, LSL #3 ; point R2 at entry in interleave table - MOV R3, #7 ; 7..0 bytes to process - MOV R4, #1 -ComplexEcfPat30 - MOV R5, #7 ; 7..0 bits per byte - MOV R6, #0 ; clear result byte - LDRB R7, [R0, R3] ; byte from queue -ComplexEcfPat40 - LDRB R8, [R2, R5] - TST R8, R7 - ORRNE R6, R6, R4, LSL R5 ; set bit in result byte - SUBS R5, R5, #1 - BGE ComplexEcfPat40 ; process next bit - - STRB R6, [R1, R3] ; write de-interleaved byte to Ecf(n) - SUBS R3, R3, #1 - BGE ComplexEcfPat30 ; process next byte from queue - - B SetColour ; update FgEcf & BgEcf incase they use this Ecf - -; -; InterleaveTB - Values used to unpack BBC style interleaved pixels -; -InterleaveTB -; 1 bit per pixel eg Mode 0 & 4 - Log2BPP is 0 - = &80, &40, &20, &10, &08, &04, &02, &01 -; 2 bits per pixel eg Mode 1 & 5 - Log2BPP is 1 - = &08, &80, &04, &40, &02, &20, &01, &10 -; 4 bits per pixel eg Mode 2 - Log2BPP is 2 - = &02, &08, &20, &80, &01, &04, &10, &40 -; 8 bits per pixel - no effect - Log2BPP is 3 - = &01, &02, &04, &08, &10, &20, &40, &80 - - ALIGN - -; ***************************************************************************** -; -; LineStyle - Setup dotted line style (does not affect repeat length) -; ========= -; -; Corrupts R0..R3 -; - -LineStyle ROUT - MOV R3, #8 ; Copy 8 bytes in reverse order - ADD R1, WsPtr, #QQ+9 - ADD R2, WsPtr, #DotLineStyle ; from Queue into DotLineStyle -LineSty10 - LDRB R0, [R1, #-1]! - STRB R0, [R2], #1 - SUBS R3, R3, #1 - BNE LineSty10 - MOV PC, R14 - - LTORG ;limited offsets - -; ***************************************************************************** -; -; DefaultLineStyle - Setup default line style and length -; -; Internal routine, called by mode change, SwitchOutputToSprite and -; FX163,242,n code -; -; out: Can corrupt R0-R3, -; PSR preserved -; - -DefaultLineStyle ROUT - [ No26bitCode - MRS R3, CPSR - ] -DefaultLineStylePSRready - MOV R0, #8 ; dot pattern repeats after 8 pixels - STR R0, [WsPtr, #DotLineLength] - LDR R0, =&AAAAAAAA ; on-off pattern - STR R0, [WsPtr, #DotLineStyle+0] ; 64 bits of pattern - STR R0, [WsPtr, #DotLineStyle+4] - MOV R0, #0 ; force a restart of the pattern - STR R0, [WsPtr, #LineDotCnt] ; if the user does a "continue" - [ No26bitCode - MSR CPSR_f, R3 - MOV PC, R14 - | - MOVS PC, R14 - ] - -; ***************************************************************************** -; -; SetPatLength - Set dotted line repeat length -; -; Internal routine, called by DoOsbyte163_242 -; -; in: R2 = 1..64 => set pattern length to this -; 0 => set default length and pattern -; -; out: Can corrupt R0-R3, -; PSR preserved -; - -SetPatLength ROUT - [ No26bitCode - MRS R3, CPSR - ] - CMP R2, #0 - BEQ DefaultLineStylePSRready - STR R2, [WsPtr, #DotLineLength] ; 1..64 - MOV R2, #0 ; force restart of the pattern - STR R2, [WsPtr, #LineDotCnt] ; if the user does a "continue" - [ No26bitCode - MSR CPSR_f, R3 - MOV PC, R14 - | - MOVS PC, R14 - ] - -; ***************************************************************************** -; -; DefaultEcfPattern - Setup all 4 ecf patterns for this mode -; (does not affect line style) -; -; Internal routine, called by mode change, SwitchOutputToSprite and -; VDU 23_11 -; - -DefaultEcfPattern ROUT - MOV R0, #0 - STR R0, [WsPtr, #BBCcompatibleECFs] ;Select BBC compatible ECF mode - - LDR R0, [WsPtr, #ECFIndex] - ADR R1, DefEcfTb - ADD R0, R1, R0, LSL #4 ; 16 bytes per entry - ADD R1, WsPtr, #Ecf1 - - LDMIA R0, {R2,R4,R6,R8} ; Get all four patterns for each mode - LDMIA R0, {R3,R5,R7,R9} ; duplicate top half into bottom half - STMIA R1, {R2-R9} ; Write all 4 Ecfs - B SetColour ; update FgEcf & BgEcf in case they are Ecfs - - -DefEcfTb ; Table of default ECFs, indexed by ECFIndex (a mode variable) - -; Modes 3,6,7 - & 0 - & 0 - & 0 - & 0 - -; Mode 0 - & &00330033 ;Dark grey (3 black, 1 white) - & &CC33CC33 ;Grey (2 black, 2 white) - & &CCFFCCFF ;Light grey (1 black, 3 white) - & &030C30C0 ;Hatching - -; Modes 1,5,8,11,19 - & &55665566 ;Red orange (3 red, 1 yellow) - & &99669966 ;Orange (2 red, 2 yellow) - & &99AA99AA ;Yellow orange (1 red, 3 yellow) - & &BBEEBBEE ;Cream (2 white, 2 yellow) - -; Modes 2,9,12,14,16,17,20(,21) - & &31133113 ;Orange (2 red, 2 yellow) - & &51155115 ;Pink (2 red, 2 magenta) - & &32233223 ;Yellow green (2 green, 2 yellow) - & &37733773 ;Cream (2 white, 2 yellow) - -; Modes 4,18,22,23 - & &00550055 ;Dark grey (3 black, 1 white) - & &AA55AA55 ;Grey (2 black, 2 white) - & &AAFFAAFF ;Light grey (1 black, 3 white) - & &11224488 ;Hatching - -; Modes 10,13,15 - & &FFFEFDFC ;Its runnier than yoy'll lik itt - & &00010203 - & &20212223 - & &DFDEDDDC - -; ***************************************************************************** -; -; SimpleEcfPattern - Setup simple ecf pattern -; -; Internal routine, called by VDU23_12..15 -; -; in: R0 = 12..15 for ecfs 1..4 -; Vdu queue holds -; QQ+0 pattern number -; QQ+1 pattern bytes 0 -; | | -; QQ+8 7 -; - -SimpleEcfPattern ROUT - ADD R1, WsPtr, #(Ecf1-12*8) - ADD R1, R1, R0, LSL #3 ; Point R1 at ECF(n) - ADD R2, WsPtr, #(QQ+1) ; Point R2 at first colour in queue - ADR R3, SimpEcfTb - LDR R4, [WsPtr, #ECFIndex] - LDRB R10, [R3, R4] ; Mask for this mode - CMP R10, #&FF - BEQ SimplEc20 ; 256 colour modes are different - LDR R5, [WsPtr, #NColour] - ADRL R4, TBFullCol ; Base of full colour table (of bytes) - ADD R4, R4, R5 ; Access to table is always - ; TBFullCol(NColour+(byte AND NColour)) - ; so add NColour in now ! - MOV R7, #4 ; There are 4 pairs of bytes in queue -SimplEc10 - LDRB R6, [R2], #1 ; Get first colour of pair from queue - AND R6, R6, R5 ; (byte AND NColour) - LDRB R6, [R4, R6] ; The full byte for this colour - AND R6, R6, R10 ; Extract required pixels - LDRB R9, [R2], #1 ; Get next colour of pair from queue - AND R9, R9, R5 ; (byte AND Ncolour) - LDRB R9, [R4, R9] - BIC R9, R9, R10 ; Extract required pixels and - ORR R6, R6, R9 ; build into final pattern - STRB R6, [R1, #4] ; Replicate pattern in both halves - STRB R6, [R1], #1 ; of ECF - SUBS R7, R7, #1 - BNE SimplEc10 - B SetColour ; update FgEcf & BgEcf in case they use this - -; R1 -> ECF(n) -; R2 -> first colour in queue - -SimplEc20 - Push R14 - MOV R5, #8 -SimplEc30 - LDRB R0, [R2], #1 ; Get byte from queue - AND R3, R0, #&C0 ; Extract Tint - AND R0, R0, #&3F ; Colour - - BL AddTintToColour ; Recombine in our funny fashion - STRB R0, [R1], #1 ; And store in the Ecf - SUBS R5, R5, #1 - BNE SimplEc30 - Pull R14 - B SetColour ; Update FgEcf & BgEcf incase they use this Ecf - -SimpEcfTb ; Table of masks for simple ECFs, indexed by ECFIndex - ; (bit set => use left pixel, bit clear => use right pixel) - - = &00 ; Modes 3,6,7 - = &33 ; Mode 0 - = &33 ; Modes 1,5,8,11,19 - = &0F ; Modes 2,9,12,14,16,17,20 - = &55 ; Modes 4,18,21,22 - = &FF ; Modes 10,13,15 - - ALIGN - -; ***************************************************************************** -; -; ExportedHLine - Routine exported via VDU variable HLineAddr -; -; in: R0,R2 = X coords in some order (internal coords) -; R1 = Y coord (internal coord) -; R3 = 0 => no effect -; R3 = 1 => foreground colour/action -; R3 = 2 => invert -; R3 = 3 => background colour/action -; R3 >= 4 => R3 -> eight word pairs -; - -ExportedHLine ROUT - Push "R0,R2,R4-R10,WsPtr,R14" - VDWS WsPtr - CMP R3, #4 - BCS %FT10 - -; *****Change made by DJS -; Original code was: -; MOV R3, R3, LSL #30 ; put bottom 2 bits into top 2 bits -; CMP R3, #&40000000 ; set lots of flags -; -; ADDMI R3, WsPtr, #BgEcfOraEor ; if 0 or 3 -; ADRCC R3, NoEffect ; if 0 -; ADDEQ R3, WsPtr, #FgEcfOraEor ; if 1 -; ADRVS R3, Invert ; if 2 - - MOVS R3, R3, LSL #31 ;Put bit 1 in C, NOT(bit 0) in Z - ADR R3, NoEffect ; if 0, 1, 2 or 3 - ADDNE R3, WsPtr, #FgEcfOraEor ; if 1 or 3 - ADRCS R3, Invert ; if 2 or 3 - ADDHI R3, WsPtr, #BgEcfOraEor ; if CS & NE - i.e. 3 - -; *****End of change made by DJS - -10 - STR R3, [WsPtr, #GColAdr] ; save address of Ecf to plot with - BL HLine - CLRV - Pull "R0,R2,R4-R10,WsPtr,PC" - -; ***************************************************************************** -; -; NewHLine - Horizontal line draw an even newer version what does 8 words -; ======== at a time if it can -; -; On entry, R0 (X), R1 (Y) holds coordinate of point -; R2 holds right hand XCoord -; On exit, R3 preserved -; R4..R10 corrupt -; PSR preserved -; -; N.B. R11 WILL BE PRESERVED - This is assumed by rectangle fill and all circle -; operations -; - -HLine - SortT R0, R2, R4 ; Sort the Xcoord into order R0<=R2 - -NewHLine ROUT ; Entry point for sorted Xcoords - - ADD R4, WsPtr, #GWLCol - LDMIA R4, {R4-R7} ; GWLCol,GWBRow,GWRCol,GWTRow - - CMP R7, R1 ; Test ycoord against window - CMPGE R1, R5 - - CMPGE R6, R0 ; Test xcoords against window - CMPGE R2, R4 - [ No26bitCode - MOVLT PC, R14 ; Quit if above,below,left or right - | - MOVLTS PC, R14 ; Quit if above,below,left or right - ] - ; of window - - Greatest R0, R0, R4 ; If start of line to left of window - ; pull to window edge - Least R2, R2, R6 ; If end of line to right of window - ; pull to window edge - - Push "R0-R3,R11,Link" - -; -; Now, R0 holds Start (leftX), R1 holds Y and R2 holds End (rightX) -; -; Now pick up ecf word and form the ZGORA & ZGEOR masks -; - - ASSERT LineLength = YWindLimit +4 - ASSERT GColAdr = XShftFactor +4 - ASSERT ScreenStart = XShftFactor +8 - - ADD R11, WsPtr, #YWindLimit - LDMIA R11, {R10-R11} ; R10 = YWindLimit; R11 = LineLength - - ADD R9, WsPtr, #XShftFactor - LDMIA R9, {R7-R9} ; R7 = XShftFactor; R8 = GColAdr - ; R9 = ScreenStart - - SUB R1, R10, R1 ; flip ycoord into R1 - AND R6, R1, #7 ; R6 = line within ecf - ADD R8, R8, R6, LSL #3 ; R8 -> zgora, zgeor - LDMIA R8, {R8, R10} ; R8 = zgora; R10 = zgeor - - MLA R9, R11, R1, R9 ; R9 -> start of this scan line - - MOV R6, R0, LSR R7 ; R6 = X1Coord word offset - MOV R11, R2, LSR R7 ; R11 = X2Coord word offset - ADD R9, R9, R6, LSL #2 ; R9 = address of lefthand word - -; *****Change made by DJS -; Original code was: -; -; EOR R4, R0, R6, LSL R7 ; R4 = X1 pixel offset -; EOR R5, R2, R11, LSL R7 ; R5 = X2 pixel offset -; -; SUBS R11, R11, R6 ; R11 = number of words -1 -; ; and set Z on it -; -; ADD R7, WsPtr, #RAMMaskTb ; R7 -> MaskTb for this mode -; LDR R6, [R7, R4, LSL #2] ; R6 = left mask -; LDR R14, [R7, R5, LSL #2] ; R14 = right mask -; -; SUB R7, R14, #1 ; in right mask set all bits lower -; ORR R14, R14, R7 ; by RM = RM OR (RM-1) -; -; RSB R7, R6, #0 ; in left mask, set all bits higher -; ORR R6, R6, R7 ; by LM = LM OR (-LM) -; -; The following code is shorter and faster. - - SUBS R11, R11, R6 ; R11 = number of words -1 - ; and set Z on it - - RSB R7, R7, #5 ; R7 = Log2BPC (quicker than loading!) - MOV R14, #31 ; constant to extract bit offsets - AND R4, R14, R0, LSL R7 ; R4 = start of X1 pixel offset - AND R5, R14, R2, LSL R7 ; R5 = start of X2 pixel offset - MOV R14, #-1 ; Useful both as -1 and as &FFFFFFFF - SUB R5, R5, R14, LSL R7 ; R5 = end of X2 pixel offset - MOV R6, R14, LSL R4 ; R6 = left mask - MVN R14, R14, LSL R5 ; R14 = right mask - -; *****End of change made by DJS - - ANDEQ R14, R14, R6 ; if start word = end word - BEQ %FT40 ; then combine masks - - [ AvoidScreenReads - AND R1, R8, R6 ; zgora AND left mask - CMP R1, #&FFFFFFFF - LDRNE R0, [R9] ; do left hand word of line - | - LDR R0, [R9] ; do left hand word of line - AND R1, R8, R6 ; zgora AND left mask - ] - AND R2, R10, R6 ; zgeor AND left mask - ORR R0, R0, R1 ; screen OR or mask - EOR R0, R0, R2 ; EOR eor mask - STR R0, [R9], #4 ; store to screen - - SUBS R11, R11, #1 ; decrement word count, if =0 - BEQ %FT40 ; then plot RH partial word - - CMP R8, #-1 ; if R8 = -1 then store action - BNE %FT05 ; else do it the slow way - - MVN R0, R10 ; R0 = word of colour to plot - MOV R1, R0 - MOV R2, R0 - MOV R3, R0 - ADDS R8, R8, R11, LSR #3 ; R8 = (no. of words DIV 8)-1 - BCC %FT60 ; must be fewer than 8 - MOV R4, R0 - MOV R5, R0 - MOV R6, R0 - MOV R7, R0 - -; *****Additional message inserted by DJS - - [ ((.-KernelBase) :AND: 15) = 12 - ! 0, "HLine critical loop has bad alignment for running in RAM" - ] - -; *****End of message inserted by DJS - -50 - STMCSIA R9!, {R0-R7} ; write 8 words to screen if >=0 - STMHIIA R9!, {R0-R7} ; write 8 words to screen if > 0 - SUBS R8, R8, #2 ; try for another 16 - BCS %BT50 -60 - TST R11, #4 ; can we do 4 words ? - STMNEIA R9!, {R0-R3} ; write 4 words to screen - TST R11, #2 ; can we do 2 words ? - STMNEIA R9!, {R0-R1} ; write 2 words to screen - TST R11, #1 ; can we do 1 word ? - STMNEIA R9!, {R0} ; write 1 word to screen - AND R10, R10, R14 ; do partial word at end - [ AvoidScreenReads - CMP R14, #&FFFFFFFF - LDRNE R0, [R9] - | - LDR R0, [R9] - ] - OrrEor R0,R0, R14,R10 - STR R0, [R9],#4 -70 - [ No26bitCode - Pull "R0-R3,R11,PC" - | - Pull "R0-R3,R11,PC",,^ ; pretty certain flag preservation not required - ] - -; code for when not store action - -05 - SUBS R11, R11, #8 ; else try for 8 words at a time - BMI %FT20 ; failed, so try for 4 at a time -10 - LDMIA R9, {R0-R7} - OrrEor R0,R0, R8,R10 ; Write 8 words to screen - OrrEor R1,R1, R8,R10 - OrrEor R2,R2, R8,R10 - OrrEor R3,R3, R8,R10 - OrrEor R4,R4, R8,R10 - OrrEor R5,R5, R8,R10 - OrrEor R6,R6, R8,R10 - OrrEor R7,R7, R8,R10 - STMIA R9!, {R0-R7} - SUBS R11, R11, #8 ; try for another 8 - BPL %BT10 - -20 - ADDS R11, R11, #4 ; can we do 4 words ? - BMI %FT30 ; no, then do 1 word at a time - - LDMIA R9, {R0-R3} - OrrEor R0,R0, R8,R10 ; Write 4 words to screen - OrrEor R1,R1, R8,R10 - OrrEor R2,R2, R8,R10 - OrrEor R3,R3, R8,R10 - STMIA R9!, {R0-R3} - - SUB R11, R11, #4 -30 - ADDS R11, R11, #4 ; Correct for earlier SUB #4 - -40 ; Plot single words - ANDEQ R8, R8, R14 ; If EQ, this is RH word, - ANDEQ R10, R10, R14 ; so mask down to required pixels - LDR R0, [R9] - OrrEor R0,R0, R8,R10 - STR R0, [R9],#4 - - SUBS R11,R11,#1 - BPL %BT40 - - [ No26bitCode - Pull "R0-R3,R11,PC" - | - Pull "R0-R3,R11,PC",,^ - ] - -; ***************************************************************************** -; -; NewVLine - Vertical line draw for non-dotted solid pattern lines -; -; in: R0 = R2 = X coord -; R1 = bottom Y coord -; R3 = top Y coord -; -; out: R4-R10 corrupt -; PSR preserved -; - -NewVLine ROUT ; Entry point for sorted Ycoords - - ADD R4, WsPtr, #GWLCol - LDMIA R4, {R4-R7} ; GWLCol,GWBRow,GWRCol,GWTRow - - CMP R7, R1 ; Test ycoord against window - CMPGE R3, R5 - - CMPGE R6, R0 ; Test xcoords against window - CMPGE R2, R4 - [ No26bitCode - MOVLT PC, R14 ; Quit if above,below,left or right - ; of window - | - MOVLTS PC, R14 ; Quit if above,below,left or right - ; of window - ] - - Greatest R1, R1, R5 ; If bottom of line below window - ; pull to window edge - Least R3, R3, R7 ; If top of line above window - ; pull to window edge - - - Push "R0-R3,R11,Link" - -; Now, R0 holds X, R1 holds bottom Y and R3 holds top Y -; -; Now pick up ecf word and form the ZGORA & ZGEOR masks -; - - ASSERT LineLength = YWindLimit +4 - ASSERT GColAdr = XShftFactor +4 - ASSERT ScreenStart = XShftFactor +8 - - ADD R11, WsPtr, #YWindLimit - LDMIA R11, {R10-R11} ; R10 = YWindLimit; R11 = LineLength - - ADD R9, WsPtr, #XShftFactor - LDMIA R9, {R7-R9} ; R7 = XShftFactor; R8 = GColAdr - ; R9 = ScreenStart - SUB R1, R3, R1 ; R1 = number of dots to do -1 - - SUB R3, R10, R3 ; R3 = flipped top ycoord - MLA R9, R11, R3, R9 ; R9 -> start of this scan line - - LDMIA R8, {R8, R10} ; R8 = zgora; R10 = zgeor - ; (no need to index with Y cos we - ; know there's no ECF pattern) - - MOV R6, R0, LSR R7 ; R6 = X coord word offset - ADD R9, R9, R6, LSL #2 ; R9 = address of top word - - EOR R4, R0, R6, LSL R7 ; R4 = X pixel offset - - ADD R7, WsPtr, #RAMMaskTb ; R7 -> MaskTb for this mode - LDR R6, [R7, R4, LSL #2] ; R6 = pixel mask - AND R8, R8, R6 ; zgora = zgora AND pixelmask - AND R10, R10, R6 ; zgeor = zgeor AND pixelmask - - [ AvoidScreenReads - CMP R8, #&FFFFFFFF - BEQ %FT20 - ] - -; now do the plotting - -10 - LDR R6, [R9] - ORR R6, R6, R8 - EOR R6, R6, R10 - STR R6, [R9], R11 - SUBS R1, R1, #1 - BPL %BT10 - - [ No26bitCode - Pull "R0-R3,R11,PC" - | - Pull "R0-R3,R11,PC",,^ - ] - - [ AvoidScreenReads -20 MVN R6, R10 -25 STR R6, [R9], R11 - SUBS R1, R1, #1 - BPL %BT25 - [ No26bitCode - Pull "R0-R3,R11,PC" - | - Pull "R0-R3,R11,PC",,^ - ] - ] - - -; ***************************************************************************** -; -; DoubleHLine - Draw 2 horizontal lines -; =========== -; -; On entry, R0 (X) - Left most point -; R1 (Y) - y ordinate of line -; R2 (X) - Right most point -; R3 (X) - end of left most line -; R4 (X) - start of right most line -; -; On exit, R0..R10 preserved } subject -; R11 corrupt } to change -; -DoubleHLine - Push "R0-R10, R14" - MOV R2, R3 ; draw left line, R0->R3 inc. - BL HLine - LDMIB R13, {R1-R4} - MOV R0, R4 ; draw right line, R4->R2 inc. - BL HLine - Pull "R0-R10, PC" - -; ***************************************************************************** -; -; ExtractTintAndColour - Convert 256-colour mode byte value into -; colour and tint -; -; Internal routine, called by ReadPixelColour, SwiReadPoint -; -; in: R0 = single screen pixel (ie 'half' user pixel in double modes) -; -; out: R0 corrupt -; R2 = colour value (GCOL a,colour) -; R3 = tint Vdu 23,17 etc -; - -ExtractTintAndColour ROUT - ; R0 := B3 G3 G2 R3 B2 R2 T1 T0 - MOV R3, R0, LSL #6 ; R3 := T1 T0 0 0 0 0 0 0 - AND R3, R3, #&C0 - AND R2, R0, #&84 ; R2 := B3 0 0 0 0 R2 0 0 - TST R0, #8 - ORRNE R2, R2, #&40 ; R2 := B3 B2 0 0 0 R2 0 0 - AND R0, R0, #&70 ; R0 := 0 G3 G2 R3 0 0 0 0 - ORR R2, R2, R0, LSR #1 ; R2 := B3 B2 G3 G2 R3 R2 0 0 - MOV R2, R2, LSR #2 ; R2 := 0 0 B3 B2 G3 G2 R3 R2 - MOV PC, R14 - -; ***************************************************************************** -; -; SwiReadPoint - Read colour of screen pixel -; -; External routine - entry point for SWI OS_ReadPoint -; -; in: R0, R1 = X, Y coordinate of point -; -; out: R2 = colour (as in GCOL a,colour) } -1 if off screen -; R3 = tint value (as in VDU 23,17 etc) } 0 if off screen -; R4 = 0/-1 for On/Off screen -; R0,R1, R5-R9 preserved (R10-R12 preserved by MOS) -; - -SwiReadPoint ROUT - WritePSRc SVC_mode, WsPtr ; re-enable interrupts - VDWS WsPtr ; point R12 at vdu driver workspace - - [ {TRUE} - GraphicsMode R10 ; if not a graphics mode then give up now! - BNE %FT20 - | - LDR R10, [WsPtr, #NPix] ; if not a graphics mode then - CMP R10, #0 ; indicate off screen - BEQ %FT20 - ] - - Push "R0-R9, R14" ; save registers - - ADD R7, WsPtr, #GCsX - LDMIA R7, {R8,R9} ; preserve GCsX,GCsY around EIG - MOV R2, #4 ; absolute coord - BL EIG - STMIA R7, {R8,R9} ; restore GcsX,GCsY - - WINDow R0,R1, R2,R3,R4,R5 - BLT %FT10 ; outside window - - Push "R0,R1" ; save internal coords - BL PreWrchCursor ; remove any split cursors etc - Pull "R0,R1" - ; R0,R1,R2 ,R3 ,R4 ,R5 ,R6 ,R7 ,R8 - BL ScreenAddr ; in :X ,Y - ; out:X ,Y ,Adr,Msk, , , ,crp,crp - LDR R8, [WsPtr, #NColour] - -;amg - changes here to cope with 16/32bpp which will also return an NCOL with b4-b7 set - -; TST R8, #&F0 ; if NColour=63 -; MOVNE R8, #&FF ; then use 255 - - CMP R8,#63 - MOVEQ R8,#255 - - LDR R9, [WsPtr, #XShftFactor] - LDR R10, [WsPtr, #NPix] - LDR R11, [WsPtr, #Log2BPC] - - BitLOffset R7,R0, R9,R10,R11 ; R7 := bit position to align to - - LDR R0, [R2] - AND R0, R8, R0, LSR R7 ; extract one pixel - - TEQ R8,#255 - MOVNE R2,R0 - MOVNE R3,#0 - BLEQ ExtractTintAndColour - -; TST R8, #&F0 ; if not a 256 colour mode -; MOVEQ R2, R0 ; colour = pixel -; MOVEQ R3, #0 ; tint = 0 -; BLNE ExtractTintAndColour ; else extract colour & tint from pixel - - MOV R4, #0 ; indicate on screen - - ADD R0, R13, #2*4 ; point to stacked R2 - STMIA R0, {R2-R4} - - BL PostWrchCursor - - Pull "R0-R9, R14" ; restore R0-R9 & return address - BIC R14, R14, #V_bit - ExitSWIHandler - -10 - Pull "R0-R9, R14" ; restore R0-R9 & return address -20 - MOV R2, #-1 - MOV R3, #0 - MOV R4, #-1 - - BIC R14, R14, #V_bit - ExitSWIHandler - -; ***************************************************************************** -; -; GenCircleParm - Generate a control block for a circle -; -; Internal routine, called by CircleOutline, CircleFill, GenArcParmBlk -; -; in: R0 (X), R1(Y) centre of circle -; R2 (X), R3(Y) point on circumference -; -; out: R0-R7 hold the following control block -; R0 - xPnt (CurrentX - relative to centre) -; R1 - yPnt (CurrentY - relative to centre) -; R2 - sum (Bres) -; R3 - upcnt -; R4 - downcnt -; R5 - CentreX -; R6 - CentreY -; R7 - Aspect (pixel shape : 0 square, 1 horz rect, 2 vert rect) -; R8-R11 undefined -; -GenCircleParm - Push R14 - LDR R11, [WsPtr, #AspectRatio] - SUB R7, R2, R0 - TST R11, #1 ; if pixels are horz rects, adjust - MOVNE R7, R7, LSL #1 ; x distance - MUL R2, R7, R7 ; R2 = (x-cx)^2 - - SUB R7, R3, R1 - TST R11, #2 ; if pixels are vert rects, adjust - MOVNE R7, R7, LSL #1 ; y distance - - MLA R2, R7, R7, R2 ; rawradsqr=(x-cx)^2 + (y-cy)^2 - MOV R7, R2 - BL SquareRoot - - ADD R2, R2, R8 ; radsqr=rawradsqr+rawrad - STR R2, [WsPtr, #CircleRadSquare] ; needed in seg. line calc - - MOV R7, R2 - BL SquareRoot - MOV R4, R8 ; R4=rad, R2=radsqr - -; -; Now build the parameter block proper -; -; R0 = CentreX, R1 = CentreY, R2 = radsqr, R4 = rad -; - MUL R9, R4, R4 ; R9=rad*rad - SUB R2, R2, R9 ; Sum=radsqu-rad*rad - - MOV R5, R0 ; CentreX - MOV R6, R1 ; CentreY - - MOV R0, R4 ; xPnt starts at rad - - ADD R4, R4, R4 - SUB R4, R4, #1 ; downcnt = 2*rad-1 - - MOV R1, #0 ; yPnt starts at 0 - MOV R3, #1 ; upcnt = 1 - - LDR R7, [WsPtr,#AspectRatio] ; taking account of pixel shape - LDR R11, [WsPtr, #CursorFlags] - TST R11, #ClipBoxEnableBit - BLNE ClipCircle - - CMP R7, #1 - - MOVEQ R0, R0, ASR #1 ; if horz pixel (ie like mode2) - ADDEQ R2, R2, R4 - SUBEQ R4, R4, #2 - - SUBGT R2, R2, R3 ; if vert pixel (ie like mode0) - ADDGT R3, R3, #2 - - Pull PC - -; ***************************************************************************** -; -; AdvCircleParm - Advance a set of circle parameters -; -; Internal routine, called by CircleOutline, CircleFill, CircleArc, -; SegmentFill, SectorFill -; -; in: R0..R7 hold a circle parameter block -; -; out: R0 (X), R1 (Y) updated -; C=1 <=> R1 (Y) has changed -; Z preserved -; -; Format of a control block -; R0 - xPnt (CurrentX - relative to centre) -; R1 - yPnt (CurrentY - relative to centre) -; R2 - sum (Bres) -; R3 - upcnt -; R4 - downcnt -; R5 - CentreX -; R6 - CentreY -; R7 - Aspect (pixel shape : 0 square, 1 horz rect, 2 vert rect) -; - -AdvCircleParm ROUT - CMP R2, R3 ; if sum >= upcnt advance Y only - BGE %FT10 - - SUB R0, R0, #1 ; else step xPnt inward one point - - ADD R2, R2, R4 ; Sum := Sum + DownCnt - SUB R4, R4, #2 ; DownCnt = next lower odd number - - TST R7, #1 ; if pixels are horizontal rectangles - ADDNE R2, R2, R4 ; modify sum again, so x steps at - SUBNE R4, R4, #2 ; half normal rate - - CMP R2, R3 - [ No26bitCode - BGE %FT10 - CLC ; if not doing Y, indicate with C=0 - MOV PC, R14 - | - BICLTS PC, R14, #C_bit ; if not doing Y, indicate with C=0 - ] -10 - ; if sum >= upcnt then advance Y - ADD R1, R1, #1 ; step yPnt up a line - - SUB R2, R2, R3 ; Sum := Sum - UpCnt - ADD R3, R3, #2 ; UpCnt = next higher odd number - - TST R7, #2 ; if pixels are vertical rectangles - SUBNE R2, R2, R3 ; modify sum again, so y steps - ADDNE R3, R3, #2 ; at half normal rate - - [ No26bitCode - SEC ; Y modified, so return C=1 - MOV PC, R14 - | - ORRS PC, R14, #C_bit ; Y modified, so return C=1 - ] - -; ***************************************************************************** -; -; SquareRoot - Calculate the square root of a 32-bit number -; -; Internal routine, called by GenSegParmBlk, GenCircleParm -; -; SquareRootAlt is a alternative routine which specifies the precision -; of the result in R11 (SquareRoot produces a 16-bit result) -; -; in: R7 = number to squareroot -; -; out: R8 = result -; R9-R11 corrupted -; R9 temp -; R10 sqdiff -; R11 counter -; - -SquareRoot ROUT - MOV R11, #16 ; 16 bit result -SquareRootAlt - MOV R8, #0 ; result=0 - MOV R10, #0 ; sqdiff=0 -10 - -; *****Change made by DJS -; Original code was: -; ADDS R7, R7, R7 ; (sqdiff,number) = (sqdiff,number)*4 -; ADC R10, R10, R10 -; ADDS R7, R7, R7 -; ADCS R10, R10, R10 ; (C:=0 we hope!) - - MOVS R10, R10, LSL #2 ; C:=0 (we hope!) while doing (sqdiff, - ORR R10, R10, R7, LSR #30 ; number) := (sqdiff, number) * 4 - MOV R7, R7, LSL #2 - -; *****End of change made by DJS - - SBCS R9, R10, R8, LSL #2 ; C=0 here, so try to subtract - ; result*4 +1 from sqdiff - MOVCS R10, R9 ; if successful then shift in a "1" bit - ADC R8, R8, R8 ; else shift in a "0" bit - SUBS R11, R11, #1 ; decrement loop counter - BNE %BT10 - - [ No26bitCode - MOV PC, R14 - | - MOVS PC, R14 - ] - -; ***************************************************************************** -; -; DoOsWord13 - Read graphics cursors (in external coords) -; -; in: R1 -> control block -; -; out: [R1+0..1] = old cursor X -; [R1+2..3] = old cursor Y -; [R1+4..5] = current cursor X -; [R1+6..7] = current cursor Y -; - ASSERT OldCsY = OldCsX +4 - ASSERT YEigFactor = XEigFactor +4 - ASSERT OrgY = OrgX +4 - ASSERT GCsY = GCsX +4 - -DoOsWord13 ROUT - Push "R0-R6" - MOV R6, R1 ; pointer to control block - - ADD R0, WsPtr, #OldCsX - LDMIA R0, {R0, R1} - ADD R2, WsPtr, #XEigFactor - LDMIA R2, {R2, R3} ; R2 = XEigFactor; R3 = YEigFactor - ADD R4, WsPtr, #OrgX - LDMIA R4, {R4, R5} ; R4 = OrgX; R5 = OrgY - RSB R0, R4, R0, LSL R2 ; R0 = (X << XEigFactor)-OrgX - RSB R1, R5, R1, LSL R3 ; R1 = (Y << YEigFactor)-OrgY - - STRB R0, [R6], #1 - MOV R0, R0, LSR #8 - STRB R0, [R6], #1 - STRB R1, [R6], #1 - MOV R1, R1, LSR #8 - STRB R1, [R6], #1 - - ADD R0, WsPtr, #GCsX - LDMIA R0, {R0, R1} ; get current cursor - - STRB R0, [R6], #1 - MOV R0, R0, LSR #8 - STRB R0, [R6], #1 - STRB R1, [R6], #1 - MOV R1, R1, LSR #8 - STRB R1, [R6], #1 - - Pull "R0-R6" - MOV PC, R14 - - LTORG - END diff --git a/s/vdu/vdupointer b/s/vdu/vdupointer deleted file mode 100644 index 8243d9a4..00000000 --- a/s/vdu/vdupointer +++ /dev/null @@ -1,554 +0,0 @@ -; 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.VduPointer - -; mjs Sep 2000 -; -; kernel/HAL split -; display pointer updating is no longer VIDC/IOMD specific -; - -; ***************************************************************************** -; -; DoPointerStuff - Entry point for OSWORD nn -; -; in: R1 -> control block -; [R1, #0] : Reason code -; -; Reason code 0 - Define pointer size, shape and active point -; -; [R1, #1] : Shape number (1..4) -; [R1, #2] : Width (w) in bytes (0..8) -; [R1, #3] : Height (h) in pixels (0..32) -; [R1, #4] : ActiveX in pixels from left (0..w*4-1) -; [R1, #5] : ActiveY in pixels from top (0..h-1) -; [R1, #6..9] : Pointer (P) to data -; [P, #0..w*h-1] : Data bytes in rows from top to bottom, -; left to right in each row. -; -; Reason code 1 - Define mouse coordinate bounding box -; -; [R1, #1..2] : left ; all treated as -; [R1, #3..4] : bottom ; signed 16-bit values, -; [R1, #5..6] : right ; relative to screen origin at the time -; [R1, #7..8] : top ; the command is issued -; -; If (left > right) or (bottom > top) then the command is ignored -; An infinite box can be obtained by setting -; left=&8000, right=&7FFF, bottom=&8000, top=&7FFF -; -; If the current mouse position is outside the box, it is moved to -; the nearest point inside the box -; -; The mouse buffer is NOT flushed - any buffered coords will be moved -; inside the bounding box when they are read. -; -; Reason code 2 - Define mouse multipliers -; -; [R1, #1] : X multiplier ; both treated as -; [R1, #2] : Y multiplier ; signed 8-bit values -; -; Reason code 3 - Set mouse position -; -; [R1, #1..2] : X position ; both treated as -; [R1, #3..4] : Y position ; signed 16-bit values -; The mouse buffer is flushed -; -; Reason code 4 - Read mouse position (not buffered) -; -; out: [R1, #1..2] : X position ; both treated as -; [R1, #3..4] : Y position ; signed 16-bit values -; -; Reason code 5 - Set pointer position -; -; [R1, #1..2] : X position ; both treated as -; [R1, #3..4] : Y position ; signed 16-bit values -; -; Reason code 6 - Read pointer position -; -; out: [R1, #1..2] : X position ; both treated as -; [R1, #3..4] : Y position ; signed 16-bit values -; - -DoPointerStuff ROUT - LDRB R0, [R1, #0] - - CMP R0, #7 - - LDRCC PC, [PC, R0, LSL #2] - MOV PC, R14 ; ***** WHY NO ERROR???????? - DCD DoDefinePointer - DCD DoMouseBox - DCD SetMouseMult - DCD SetMousePosn - DCD ReadMousePosn - DCD SetPointerPosn - DCD ReadPointerPosn - -; ***************************************************************************** - -DoDefinePointer - - ; We allow interrupts during time we copy shape, but we copy into a - ; holding descriptor, so shape will never be displayed (whether its the - ; current one, or becomes the current one with an OSByte 6A) until the - ; vsync after we have a complete definition. - ; - ; We have two holding buffers, so that we can always choose a holding - ; buffer that is not currently being used for display by the HAL, - ; despite multiple definitions between vsyncs. This all assumes we - ; are never re-entered, but the documentation for OS_Word 21,0 says - ; re-entrancy undefined anyway - should really say not re-entrant. - - Push "R1-R7, R14" - - ; interrupts still off for critical choosing of buffer - ; - ADD R6, WsPtr, #PointerShapesH - MOV R7, #0 ; try holding shape 1 - LDR R14, [R6, R7, LSL #2] ; R14 -> shape - LDR R2, [R14, #PointerBuffLA] ; shape buffer we propose to use - LDR R0, [WsPtr, #PointerShapeLA] ; shape buffer owned by HAL - TEQ R0, R2 ; identical? - MOVEQ R7, #1 ; alright then, holding shape 2 - LDREQ R14, [R6, R7, LSL #2] ; R14 -> shape - - ; now R7 = holding shape index (0,1), R14 -> shape, not owned by HAL - - CLRPSR I_bit, R0 ; re-enable interrupts - - LDRB R6, [R1, #1] ; shape number we're defining - SUB R6, R6, #1 - CMP R6, #4 ; now in range 0..3 ? - BCS %FT90 ; bad shape number - - LDRB R0, [R1, #2] ; R0 = width (bytes) - LDRB R2, [R1, #3] ; R2 = height - LDRB R3, [R1, #4] ; R3 = ActiveX - LDRB R4, [R1, #5] ; R4 = ActiveY - - CMP R2, #0 ; C=1 if EQ - STREQB R2, [R14, #PointerWidth] - STREQB R2, [R14, #PointerHeight] - BEQ %FT80 ; empty shape (off) - - CMP R0, #0 ; C=1 if EQ - STREQB R0, [R14, #PointerWidth] - STREQB R0, [R14, #PointerHeight] - CMPNE R0, #8+1 - BCS %FT90 ; bad width - - CMP R2, #32+1 ; C=1 => bad height - CMPCC R3, R0, LSL #2 ; ActiveX >= (width * 4) ? - CMPCC R4, R2 ; ActiveY >= height - - BCS %FT90 ; bad definition - - STRB R0, [R14, #PointerWidth ] ; actual width in bytes, before padding to constant 8 - STRB R2, [R14, #PointerHeight] - STRB R3, [R14, #PointerActiveX] - STRB R4, [R14, #PointerActiveY] - - ADD R4, R1, #6 - LDW R1, R4, R3, R5 ; load word from - ; unknown alignment -; Now R1 -> user's data - - LDR R3, [R14, #PointerBuffLA] ; R3 -> buffer to receive shape -20 - ADD R4, R3, R0 ; terminating R3 for this row -30 - LDRB R5, [R1], #1 -40 - STRB R5, [R3], #1 ; store to buffer - CMP R3, R4 ; still within user data - BCC %BT30 ; for this row ? - -; now fill up rest of row - - MOV R5, #0 - TST R3, #7 ; are we on a multiple of 8 - BNE %BT40 ; no, then store 0 - - SUBS R2, R2, #1 ; done all rows ? - BNE %BT20 ; no, then loop - -80 - ; we now have a completely defined shape in a holding buffer - ; - PHPSEI R0 ; disable interrupts for critical shape logic - ADD R3, WsPtr, #PointerShapes - ADD R4, WsPtr, #PointerShapesH - LDR R1, [R3, R6, LSL #2] ; swap the holding shape (R7=0,1) into - LDR R2, [R4, R7, LSL #2] ; the shape we've just defined (R6 = 0..3) - STR R2, [R3, R6, LSL #2] - STR R1, [R4, R7, LSL #2] - PLP R0 ; restore interrupts -90 - Pull "R1-R7,PC" - - -; ***************************************************************************** -; -; SetMouseRectangle - Called on mode change to set appropriate mouse -; rectangle and mouse position -; -; in: WsPtr -> VDWS -; - -SetMouseRectangle ROUT - Push R14 - - ASSERT DisplayYWindLimit = DisplayXWindLimit +4 - ASSERT DisplayXEigFactor = DisplayXWindLimit +8 - ASSERT DisplayYEigFactor = DisplayXWindLimit +12 - - ADD R2, WsPtr, #DisplayXWindLimit - LDMIA R2, {R2-R5} - - ADD R2, R2, #1 ; XWindLimit+1 - MOV R2, R2, LSL R4 ; (XWindLimit+1) << XEigFactor - SUB R4, R2, #1 ; ((XWindLimit+1) << XEigFactor)-1 - MOV R2, R2, LSR #1 ; centre x of window - - ADD R3, R3, #1 ; YWindLimit+1 - MOV R3, R3, LSL R5 ; (YWindLimit+1) << YEigFactor - SUB R5, R3, #1 ; ((YWindLimit+1) << YEigFactor)-1 - MOV R3, R3, LSR #1 ; centre y of window - - BL SetMousePosnRegs - - MOV R2, #0 ; left = 0 - MOV R3, #0 ; bottom = 0 - - Push "R1-R6" - B DoMouseBoxRegs - - -DoMouseBox ROUT - Push "R1-R6, R14" - - LDRB R2, [R1, #1] ; R2 = left - LDRB R0, [R1, #2] - ORR R2, R2, R0, LSL #8 - - LDRB R3, [R1, #3] ; R3 = bottom - LDRB R0, [R1, #4] - ORR R3, R3, R0, LSL #8 - - LDRB R4, [R1, #5] ; R4 = right - LDRB R0, [R1, #6] - ORR R4, R4, R0, LSL #8 - - LDRB R5, [R1, #7] ; R5 = top - LDRB R0, [R1, #8] - ORR R5, R5, R0, LSL #8 - -DoMouseBoxRegs - -; now add on graphics origin - - LDR R0, [WsPtr, #OrgX] - ADD R2, R2, R0 - ADD R4, R4, R0 - LDR R0, [WsPtr, #OrgY] - ADD R3, R3, R0 - ADD R5, R5, R0 - -; now sign extend all coords - - MOV R2, R2, LSL #16 - MOV R2, R2, ASR #16 - MOV R3, R3, LSL #16 - MOV R3, R3, ASR #16 - MOV R4, R4, LSL #16 - MOV R4, R4, ASR #16 - MOV R5, R5, LSL #16 - MOV R5, R5, ASR #16 - -; now check right >= left and top >= bottom - - CMP R4, R2 - CMPGE R5, R3 - BLT %FT10 ; bad definition - -; everything seems OK, so disable IRQs while we update vars - - MRS R14, CPSR - ORR R0, R14, #I32_bit - MSR CPSR_c, R0 - - Push R11 - MOV R11, #KeyWorkSpace - - ADR R0, MouseBounds - STMIA R0, {R2-R5} - -; check mouse position is within box - - LDR R0, MouseX - CMP R0, R2 ; if X < left - STRLT R2, MouseX ; then X := left - CMP R4, R0 ; if right < X - STRLT R4, MouseX ; then X := right - - LDR R0, MouseY - CMP R0, R3 ; if Y < bottom - STRLT R3, MouseY ; then Y := bottom - CMP R5, R0 ; if top < Y - STRLT R5, MouseY ; then Y := top - - Pull R11 - - MSR CPSR_c, R14 ; restore old IRQ state -10 - Pull "R1-R6, PC" - -; ***************************************************************************** -; -; UpdatePointer - Called on vsync to update pointer position -; -; in: WsPtr (R12) -> VduDriverWorkSpace -; -UpdatePointer ROUT - - LDRB R5, [WsPtr, #PointerShapeNumber] - - TST R5, #&80 ; pointer unlinked if bit 7 set - - LDREQ R6, MouseX - STREQ R6, [WsPtr, #PointerX] - LDREQ R6, MouseY - STREQ R6, [WsPtr, #PointerY] - - ANDS R5, R5, #&7F ; clear bit 7 and set Z if 0 ie off - BNE %FT20 - -10 - MOV R0, #0 ; flags = 0 (pointer off) - MOV R1, #0 ; x = 0 - MOV R2, #0 ; y = 0 - MOV R3, #0 ; shape descriptor = NULL - STR R3, [WsPtr, #PointerShapeLA] ; NULL passed as last buffer address - B %FT40 - -20 - ADD R3, WsPtr, #PointerShapes-4 - LDR R3, [R3, R5, LSL #2] ; R3 -> current shape block (R5 = shape 1..4) - - LDRB R0, [R3, #PointerHeight] ; height of 0 switches pointer off - TEQ R0, #0 - BEQ %BT10 - - MOV R0, #1 ; R0 = flags, set pointer on (bit 0 = 1) - - LDR R1, [WsPtr, #PointerShapeLA] ; last shape buffer given to HAL - LDR R4, [R3, #PointerBuffLA] ; shape buffer we're about to give - TEQ R1, R4 ; same as last time? - STRNE R4, [WsPtr, #PointerShapeLA] ; update - ORRNE R0, R0, #2 ; flag new shape (bit 1 = 1) - - LDR R1, [WsPtr, #PointerX] - LDR R4, [WsPtr, #PointerXEigFactor] - MOV R1, R1, ASR R4 ; R1 = pointer x, pixels - LDRB R4, [R3, #PointerActiveX] - SUB R1, R1, R4 ; R1 = pointer x, adjusted for active point - - LDR R2, [WsPtr, #PointerY] - LDR R4, [WsPtr, #DisplayYEigFactor] - LDR R5, [WsPtr, #DisplayYWindLimit] ; R5 = display height -1 - SUB R2, R5, R2, ASR R4 ; R2 = pointer y, pixels, inverted - LDRB R4, [R3, #PointerActiveY] - SUB R2, R2, R4 ; R2 = pointer y, adjusted for active point - - ; and its up to the HAL to handle clipping according to h/w capabilities -40 - [ UseGraphicsV - Push "LR" - MOV R4, #GraphicsV_UpdatePointer - BL CallGraphicsV - Pull "PC" - | - Push "R9, R12, LR" - mjsAddressHAL - mjsCallHAL HAL_Video_UpdatePointer - Pull "R9, R12, PC" - ] - - - LTORG - -; ***************************************************************************** - -SetMouseMult ROUT - Push "R11,R14" - MOV R11, #KeyWorkSpace - - LDRB R0, [R1, #1] - MOV R0, R0, ASL #24 ; sign extend to 32 bits - MOV R0, R0, ASR #24 - STR R0, MouseXMult - - LDRB R0, [R1, #2] - MOV R0, R0, ASL #24 ; sign extend to 32 bits - MOV R0, R0, ASR #24 - STR R0, MouseYMult - - Pull "R11,PC" - -; ***************************************************************************** -; -; GetCoordPair - get pair of 2-byte coords from R1+1..R1+4 -; adds on graphics origin and sign extends to 32 bits -; and puts X into R2, Y into R3 -; - -GetCoordPair ROUT - LDRB R0, [R1, #1] ; get X coordinate - LDRB R2, [R1, #2] - ORR R0, R0, R2, LSL #8 - - LDR R2, [WsPtr, #OrgX] ; add on origin - ADD R0, R0, R2 - - MOV R0, R0, ASL #16 ; sign extend 16 to 32 - MOV R2, R0, ASR #16 - - LDRB R0, [R1, #3] ; get Y coordinate - LDRB R3, [R1, #4] - ORR R0, R0, R3, LSL #8 - - LDR R3, [WsPtr, #OrgY] ; add on origin - ADD R0, R0, R3 - - MOV R0, R0, ASL #16 ; sign extend 16 to 32 - MOV R3, R0, ASR #16 - - MOV PC, R14 - -; ***************************************************************************** - -SetMousePosn ROUT - Push "R2, R3, R11, R14" - MOV R11, #KeyWorkSpace - - BL GetCoordPair - -; now check point is within bounding box - - LDR R0, MouseBoundLCol - CMP R2, R0 - LDRGE R0, MouseBoundRCol - CMPGE R0, R2 - LDRGE R0, MouseBoundBRow - CMPGE R3, R0 - LDRGE R0, MouseBoundTRow - CMPGE R0, R3 - - BLGE SetMousePosnRegs - - Pull "R2, R3, R11, PC" - -SetMousePosnRegs - MOV R11, #KeyWorkSpace - STR R2, MouseX - STR R3, MouseY - B FlushMouse - -; ***************************************************************************** -; -; StoreCoordPair - Stores X,Y coords in R2,R3 in R1+1..R1+4 -; subtracts graphics origin - -StoreCoordPair ROUT - - LDR R0, [WsPtr, #OrgX] ; subtract off origin - SUB R2, R2, R0 - - STRB R2, [R1, #1] ; store lo-byte of X - MOV R2, R2, LSR #8 - STRB R2, [R1, #2] ; store hi-byte of X - - LDR R0, [WsPtr, #OrgY] ; subtract off origin - SUB R3, R3, R0 - - STRB R3, [R1, #3] ; store lo-byte of Y - MOV R3, R3, LSR #8 - STRB R3, [R1, #4] ; store hi-byte of Y - - MOV PC, R14 - -; ***************************************************************************** - -ReadMousePosn ROUT - [ AssemblePointerV :LAND: {TRUE} - Push "r0-r3, r9-r11, lr" - BL PollPointer ; update mouse position on a read - LDR r1, [sp, #1*4] ; reload pointer to buffer - MOV R11, #KeyWorkSpace - - LDR R2, MouseX ; get mouse X - LDR R3, MouseY ; get mouse Y - BL StoreCoordPair - Pull "r0-r3, r9-r11, pc" - - | - Push "R2, R3, R11, R14" - MOV R11, #KeyWorkSpace - - LDR R2, MouseX ; get mouse X - LDR R3, MouseY ; get mouse Y - BL StoreCoordPair - - Pull "R2, R3, R11, PC" - ] - -; ***************************************************************************** - -SetPointerPosn ROUT - Push "R2, R3, R14" - - BL GetCoordPair - - STR R2, [WsPtr, #PointerX] - STR R3, [WsPtr, #PointerY] - - Pull "R2, R3, PC" - -; ***************************************************************************** - -ReadPointerPosn ROUT - Push "R2, R3, R14" - - LDR R2, [WsPtr, #PointerX] - LDR R3, [WsPtr, #PointerY] - BL StoreCoordPair - - Pull "R2, R3, PC" - -; ***************************************************************************** -; -; FlushMouse - Flush mouse buffer -; -; out: All registers preserved - -FlushMouse ROUT - Push "R0-R2, R14" - MOV R0, #21 - MOV R1, #Buff_Mouse - SWI XOS_Byte - Pull "R0-R2, PC" - - END diff --git a/s/vdu/vduswis b/s/vdu/vduswis deleted file mode 100644 index 420d3138..00000000 --- a/s/vdu/vduswis +++ /dev/null @@ -1,2102 +0,0 @@ -; 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.VduSWIs - - MACRO - BranchNotJustUs $label, $vector, $tmp1, $tmp2 - MOV R11, #0 - [ $tmp1=R11 - LDR R12, [R11, #VecPtrTab+$vector*4]! ; load vector node - | - LDR R12, [R11, #VecPtrTab+$vector*4] ; load vector, leave R11=0 - ] - CMP R12, #&FC000000 ; fudge - BCC $label - MEND - - MACRO - BranchNotJustUsWrch $label - BranchNotJustUs $label, WrchV, R11, R14 - MEND - - MACRO - SWIEntry $swiname - & OS_$swiname - & SWI$swiname-(.+4) - MEND - - -; ***************************************************************************** -; -; SWIRVV - SWI ReadVduVariables handler -; -; in: R0 -> input block -; R1 -> output block -; -; out: All registers preserved -; -; The input block consists of a string of words, terminated by -1 -; Each word indicates which VDU variable to read. -; The (word) values of these variables are put in sequence into the -; output block (no terminator is put in this block). Invalid variables -; are returned as zero. - -SWIRVV ROUT -SWIReadVduVariables ; alternative symbol used for init'ing - TST R0, #3 ; input block not aligned - TSTEQ R1, #3 ; or output block not aligned - ExitSWIHandler NE ; then exit - Push R9 - VDWS WsPtr - MOV R10, #0 ; offset into both blocks -10 - LDR R11, [R0, R10] - CMP R11, #-1 ; end of block ? - Pull R9, EQ - ExitSWIHandler EQ - - CMP R11, #&100 ; is it fudged "code" variable - BCS %FT30 ; yes, then use special code - - CMP R11, #(SWIRVVTabModeEnd-SWIRVVTab) ; a mode variable - ADRCC R9, SWIRVVTab ; if so then point to them - BCC %FT20 - SUB R11, R11, #&80 ; base for non-mode variables - CMP R11, #(SWIRVVTabEnd-SWIRVVTabModeEnd) - ADRCCL R9, SWIRVVTabModeEnd -20 - LDRCCB R11, [R9, R11] ; yes, then load offset - LDRCC R11, [WsPtr, R11, LSL #2] ; and then load variable - MOVCS R11, #0 ; no, then put zero in it -25 - STR R11, [R1, R10] - ADD R10, R10, #4 - B %BT10 - -; Special code to read window width for Bruce et al. - -30 - SUB R11, R11, #&100 - CMP R11, #2 ; 0 => WindowWidth, 1 => WindowHeight - BCS %BT20 ; not one of those, so illegal - - Push "R0-R7" - LDR R6, [WsPtr, #CursorFlags] - TST R6, #Vdu5Bit - ADDEQ R4, WsPtr, #TWLCol ; if VDU 4 mode, use text window - ADDNE R4, WsPtr, #GWLCol ; else use graphics window - LDMIA R4, {R0-R3} - SUB R0, R2, R0 ; R0 = horizontal width -1 - SUB R1, R1, R3 ; R1 = vertical height -1 - - BEQ %FT32 - - ADD R2, WsPtr, #GCharSizes ; R2=GCharSizeX; R3=GCharSizeY - LDMIA R2, {R2-R5} ; R4=GCharSpaceX; R5=GCharSpaceY - - TST R6, #2 ; if going from right to left - SUBNE R2, R2, #1 ; then width reduction = sizex-1 - MOVEQ R2, #0 ; else 0 - - TST R6, #4 ; if going from bottom to top - RSBNE R3, R3, #1 ; then -height reduction = 1-sizey - MOVEQ R3, #0 ; else 0 - - SUB R7, R0, R2 ; R7 = width-1-(width reduction) - DivRem R0, R7, R4, R2 ; R0 = (width-(1 or sizex))DIV spacex - - SUB R7, R3, R1 ; R7 = height-(1-height reduction) - DivRem R1, R7, R5, R3 ; R1 = (height-(1 or sizey))DIV spacey -32 - TST R6, #8 ; are X and Y reversed ? - EORNE R0, R0, R1 ; yes, then swap - EORNE R1, R0, R1 - EORNE R0, R0, R1 - - TST R6, #Vdu5Bit - BNE %FT35 - TST R6, #1 ; is it "81 column mode ?" and VDU 4 - ADDNE R0, R0, #1 ; yes, then extra column -35 - TEQ R11, #0 ; reading width ? - MOVEQ R11, R0 ; yes, then use X - MOVNE R11, R1 ; no, use Y - - Pull "R0-R7" ; restore registers - B %BT25 ; and store result away - - -SWIRVVTab - -; Note these first variables should be the same as in SWI ReadModeVariable - - RVVT ModeFlags - RVVT ScrRCol - RVVT ScrBRow - RVVT NColour - RVVT XEigFactor - RVVT YEigFactor - RVVT LineLength - RVVT ScreenSize - RVVT YShftFactor - RVVT Log2BPP - RVVT Log2BPC - RVVT XWindLimit - RVVT YWindLimit -SWIRVVTabModeEnd - - RVVT GWLCol - RVVT GWBRow - RVVT GWRCol - RVVT GWTRow - RVVT TWLCol - RVVT TWBRow - RVVT TWRCol - RVVT TWTRow - RVVT OrgX - RVVT OrgY - RVVT GCsX - RVVT GCsY - RVVT OlderCsX - RVVT OlderCsY - RVVT OldCsX - RVVT OldCsY - RVVT GCsIX - RVVT GCsIY - RVVT NewPtX - RVVT NewPtY - RVVT ScreenStart - RVVT DisplayStart - RVVT TotalScreenSize - RVVT GPLFMD - RVVT GPLBMD - RVVT GFCOL - RVVT GBCOL - RVVT TForeCol - RVVT TBackCol - RVVT GFTint - RVVT GBTint - RVVT TFTint - RVVT TBTint - RVVT MaxMode - RVVT GCharSizeX - RVVT GCharSizeY - RVVT GCharSpaceX - RVVT GCharSpaceY - RVVT HLineAddr - RVVT TCharSizeX - RVVT TCharSizeY - RVVT TCharSpaceX - RVVT TCharSpaceY - RVVT GcolOraEorAddr - RVVT VIDCClockSpeed - RVVT PixelRate -SWIRVVTabEnd - - ALIGN - - [ {FALSE} - -; ***************************************************************************** -; -; SWISetVduVariables - SWI OS_SetVduVariables handler -; -; in: R0 -> block of variable numbers (word aligned) -; R1 -> block of variable values (word aligned) -; -; out: All registers preserved -; -; The block pointed to by R0 consists of a string of words, terminated -; by -1. Each word indicates which variable to write. The corresponding -; value in the R1 block is written to this variable. Invalid variables -; are ignored. -; - -SWISetVduVariables ROUT - TST R0, #3 ; index block not aligned - TSTEQ R1, #3 ; or value block not aligned - ExitSWIHandler NE ; then exit - Push R9 - VDWS WsPtr - MOV R10, #0 ; offset into both blocks -10 - LDR R11, [R0, R10] - CMP R11, #-1 ; end of block ? - Pull R9, EQ - ExitSWIHandler EQ - - TEQ R11, #VduExt_XEigFactor - TEQNE R11, #VduExt_YEigFactor - BNE %FT25 - - CMP R11, #(SWIRVVTabModeEnd-SWIRVVTab) ; a mode variable - ADRCC R9, SWIRVVTab ; if so then point to them - SUBCS R11, R11, #&80 ; base for non-mode variables - ADRCS R9, SWIRVVTabModeEnd -20 - LDRB R11, [R9, R11] ; yes, then load offset - LDR R9, [R1, R10] ; load value - STR R9, [WsPtr, R11, LSL #2] ; store in variable - Push "R0-R5,R14" - BL IEG ; update ext. cursor - ; on exit, R2=XEigFactor, R3=YEigFactor - SUBS R0, R2, R3 ; XEigFactor-YEigFactor - MOVLT R0, #2 ; X<Y => 2 (vert rect) - MOVGT R0, #1 ; X>Y => 1 (horz rect) else 0 (square) - STR R0, [WsPtr, #AspectRatio] - -; mouse bounding box, mouse position ??? - - Pull "R0-R5,R14" -25 - ADD R10, R10, #4 - B %BT10 - - ] - -; ***************************************************************************** -; -; SWIReadModeVar - Handler for SWI OS_ReadModeVariable -; -; in: R0 = screen mode you want the information for, -1 => current mode -; R1 = number of variable to read -; -; out: R2 = value of variable -; - -; Note: the algorithms used to derive the variables for mode selectors -; are duplicated in source.vdudriver, in GenerateModeSelectorVars - -SWIReadModeVar ROUT -SWIReadModeVariable ; alternative symbol used for init'ing - Push "R0,R1,R14" - - CMP R1, #(RMVTabEnd-RMVTab) ; valid variable number ? - BCS BadReadModeVar ; no, then exit - - ; AMG - note that the new sprite mode word code assumes that this - ; test has been done! - - VDWS WsPtr - -; AMG - add readmodevariable returns for new format sprite mode words. Much of -; this is munging the word passed in. A new sprite mode word can be -; distinguished from a pointer to a mode selector structure because -; b0 will be set in the new sprite mode word. 11/3/93 - -; TMD - serious optimisation introduced 17-Feb-93 -; TMD - additional optimisation for current mode added 16-Mar-93 - -; AMG - Fix bug MED-00414 ... need to support eig=0 modes here 26-Oct-93 - - LDR r11, [WsPtr, #ModeNo] ; get current mode - - CMP r0, #-1 ; if explicitly asking for current mode - BEQ RMVForCurrentMode ; then use optimised code - - CMP r0, #&100 - BCC %FT11 ; an old style mode number, branch past - ; the new code below - TST r0, #&01 - BNE NewSpriteModeWord ; b0 set, so it is a NewSpriteModeWord - ; rather than a pointer to a mode selector - -; it's a mode selector, so check if valid first - - BL ValidateModeSelector - BVS BadReadModeVar - -; check if variable is in workspace list - - ADD r10, r0, #ModeSelector_ModeVars ; point at list - BL CheckWorkspaceList ; check list - BCC GoodReadModeVar ; [it was in list, so exit] - -; not in list, so deduce from other parms -; (we know the variable number is in range) - - LDR pc, [pc, r1, LSL #2] - NOP - & RMVMS_ModeFlags - & RMVMS_ScrRCol - & RMVMS_ScrBRow - & RMVMS_NColour - & RMVMS_XEigFactor - & RMVMS_YEigFactor - & RMVMS_LineLength - & RMVMS_ScreenSize - & RMVMS_YShftFactor - & RMVMS_Log2BPP - & RMVMS_Log2BPC - & RMVMS_XWindLimit - & RMVMS_YWindLimit - -RMVMS_ModeFlags -RMVMS_YShftFactor - MOV r2, #0 ; default modeflags, yshftfactor = 0 - B GoodReadModeVar - -RMVMS_ScrRCol - LDR r2, [r0, #ModeSelector_XRes] ; default scrcol = (xres>>3)-1 - MOV r2, r2, LSR #3 - SUB r2, r2, #1 - B GoodReadModeVar - -RMVMS_ScrBRow - LDR r2, [r0, #ModeSelector_YRes] ; default scrbrow = (yres>>3)-1 - MOV r2, r2, LSR #3 - SUB r2, r2, #1 - B GoodReadModeVar - -RMVMS_NColour - LDR r2, [r0, #ModeSelector_PixelDepth] - CMP r2, #6 ; if pixel depth is sensible - ADRCCL r11, NColourTable ; then lookup in table - LDRCC r2, [r11, r2, LSL #2] - MOVCS r2, #1 ; else return 1 - B GoodReadModeVar - -; TMD 09-Dec-93 -; New algorithms for xeig, yeig from Roger: -; xeig = 1: yeig = 1 -; if yres<xres/2 OR yres<400 then yeig = 2 -; if (xres<<xeig)<(yres<<yeig) then xeig = 2 - - [ RogerEXEY -RMVMS_XEigFactor - LDR r2, [r0, #ModeSelector_XRes] - LDR r11, [r0, #ModeSelector_YRes] - CMP r11, r2, LSR #1 ; if yres < xres/2 - CMPCS r11, #400 ; or yres < 400 - MOVCC r11, r11, LSL #2 ; then yeig = 2 - MOVCS r11, r11, LSL #1 ; else yeig = 1 - CMP r11, r2, LSL #1 ; if (xres<<1) < (yres<<yeig) - MOVHI r2, #2 ; then xeig = 2 - MOVLS r2, #1 ; else xeig = 1 - B GoodReadModeVar - -RMVMS_YEigFactor - LDR r2, [r0, #ModeSelector_XRes] - LDR r11, [r0, #ModeSelector_YRes] - CMP r11, r2, LSR #1 ; if yres < xres/2 - CMPCS r11, #400 ; or yres < 400 - MOVCC r2, #2 ; then yeig = 2 - MOVCS r2, #1 ; else yeig = 1 - B GoodReadModeVar - | -RMVMS_XEigFactor - MOV r2, #1 ; default xeig = 1 - B GoodReadModeVar - -RMVMS_YEigFactor - LDR r2, [r0, #ModeSelector_XRes] - LDR r11, [r0, #ModeSelector_YRes] - CMP r11, r2, LSR #1 ; if yres < xres/2 - MOVCC r2, #2 ; then yeig = 2 - MOVCS r2, #1 ; else yeig = 1 - B GoodReadModeVar - ] - -RMVMS_LineLength - LDR r2, [r0, #ModeSelector_XRes] -RMVMS_ShiftByPixDepthMinus3 - LDR r11, [r0, #ModeSelector_PixelDepth] - CMP r11, #6 ; if out of range - MOVCS r11, #0 ; use log2bpp=0 - MOV r2, r2, LSL r11 - MOV r2, r2, LSR #3 ; ll = (xres << pixdepth) >> 3 - B GoodReadModeVar - -RMVMS_ScreenSize - LDR r2, [r0, #ModeSelector_XRes] - LDR r11, [r0, #ModeSelector_YRes] - MUL r2, r11, r2 ; xres * yres - B RMVMS_ShiftByPixDepthMinus3 - -RMVMS_Log2BPP -RMVMS_Log2BPC - LDR r2, [r0, #ModeSelector_PixelDepth] - CMP r2, #6 ; range check - MOVCS r2, #0 - B GoodReadModeVar - -RMVMS_XWindLimit - LDR r2, [r0, #ModeSelector_XRes] ; default xwindlimit = xres-1 - SUB r2, r2, #1 - B GoodReadModeVar - -RMVMS_YWindLimit - LDR r2, [r0, #ModeSelector_YRes] ; default ywindlimit = yres-1 - SUB r2, r2, #1 - B GoodReadModeVar - -11 - CMP r0, r11 ; if implicitly asking for current mode (and mode <> mode selector) - BEQ RMVForCurrentMode ; then use optimised code - - BIC r11, r0, #&80 ; clear shadow bit - - BranchIfKnownMode r11, %FA50 - -; not known mode, so look - - Push "r2-r4" - MOV r2, r11 - BL OfferModeExtensionAnyMonitor - MOVEQ r11, r4 ; if service responded to, save pointer to workspace list - Pull "r2-r4" - BNE BadReadModeVar ; exit if mode not known about - -; now search down list checking for variable number - - ADD r10, r11, #8 ; skip list type and base mode - BL CheckWorkspaceList ; look up variable in list - BCC GoodReadModeVar ; if there then exit - -; not in workspace list provided, so use base mode to look up in MOS's table - - LDR r11, [r11, #4] ; load workspace list base mode - BranchIfKnownMode r11, %FA50 - -; panic - base mode unrecognised -; existing code simply loads off end of table! - instead of that, return value zero -; alternatively we could return carry set, but that might cause backward compatibility problems (maybe) - - MOV r2, #0 - B GoodReadModeVar - -50 - ADR r10, RMVTab - LDRB r10, [r10, r1] ; R10 = offset in each mode table * 2 - ; if bit 0 set, then word value - ADRL r14, Vwstab - LDR r11, [r14, r11, LSL #2] ; get offset to table for this mode - ADD r11, r11, r14 ; convert to pointer - MOVS r10, r10, LSR #1 ; put byte/word flag into carry - LDRCCB r2, [r11, r10] ; load either a byte - LDRCS r2, [r11, r10] ; or a word out of table - -; and drop thru to GoodModeVar - -GoodReadModeVar - Pull "R0,R1,R14" - BIC R14, R14, #C_bit ; indicate successful read - ExitSWIHandler - -BadReadModeVar - Pull "R0,R1,R14" - ORR R14, R14, #C_bit ; indicate bad read - ExitSWIHandler - -; CheckWorkspaceList - Check a mode variable (index, value) list for a match -; in: r1 = variable number -; r10 -> list -; -; out: If match found, then -; r2 = value -; C=0 -; else -; C=1 -; endif -; r10 corrupted in both cases - -CheckWorkspaceList Entry -10 - LDR r14, [r10], #8 ; load next index (and skip index+value) - CMP r14, #-1 ; if end of list - EXIT EQ ; then not in workspace list, so exit (C=1 from CMP) - TEQ r14, r1 - BNE %BT10 - - LDR r2, [r10, #-4] ; load value of variable - CLC ; clear carry - EXIT - -RMVForCurrentMode - ADR r10, MVToVVTable - LDR r10, [r10, r1, LSL #2] - LDR r2, [WsPtr, r10] - B GoodReadModeVar - -MVToVVTable - & ModeFlags - & ScrRCol - & ScrBRow - & NColour - & XEigFactor - & YEigFactor - & LineLength - & ScreenSize - & YShftFactor - & Log2BPP - & Log2BPC - & XWindLimit - & YWindLimit - -; Note these should be the same as the first few in SWI ReadVduVariables - -RMVTab - RMVT ModeFlags, W ; was B - RMVT ScrRCol, W ; was B - RMVT ScrBRow, W ; was B - RMVT NColour, W - RMVT XEigFactor, W ; was B - RMVT YEigFactor, W ; was B - RMVT LineLength, W - RMVT ScreenSize, W - RMVT YShftFactor, W ; was B - RMVT Log2BPP, W ; was B - RMVT Log2BPC, W ; was B - RMVT XWindLimit, W - RMVT YWindLimit, W -RMVTabEnd - ALIGN - -; ***************************************************************************** -; -; NewSpriteModeWord, called from ReadModeVariable -; -; in: R0 = new sprite mode word -; R1 = number of variable to read -; (R0,R1,R14 stacked) -; -; out: R2 = value of variable -; -; Return parameters as follows: - -; (Unknown types will return an error. Invalid mode variable numbers will already -; have been weeded out at the entry to ReadModeVariable) - -; 0 ModeFlags Error -; 1 ScrRCol Error -; 2 ScrBRow Error -; 3 NColour derived from bpp passed in (255 for 8bpp) -; 4 XEigFactor returns 0,1,2 for 180,90,45 dpi, error otherwise -; 5 YEigFactor as XEigFactor -; 6 LineLength Error -; 7 ScreenSize Error -; 8 YShftFactor Error -; 9 Log2BPP returns 0,1,2,3,4,5 for T=1-6, error otherwise -; 10 Log2BPC as Log2BPP -; 11 XWindLimit Error -; 12 YWindLimit Error - -NewSpriteModeWord ROUT - -; validate the sprite type. Types 1-6 only at present. Type 0 is a -; mode number, but if it comes this way, it's bad, since mode >= 256 - - MOVS r14, r0, LSR #27 ; shift type word into b4-b0 - BEQ BadReadModeVar ; zero is bad cos mode >= 256 - ;if it's an unknown one, apply a substitute - CMP r14, #SpriteType_MAX - MOVCS r14, #SpriteType_Substitute - -; it's a valid type, now branch by the mode variable number - - ADR r2, NewSpriteModeWordRoutines - ADD pc, r2, r1, LSL #2 ; and despatch it - -NewSpriteModeWordRoutines - B NSM_modeflags ; 0 ModeFlags (zero) - B BadReadModeVar ; 1 ScrRCol Error - B BadReadModeVar ; 2 ScrBRow Error - B NSM_ncol ; 3 NColour - B NSM_xeig ; 4 XEigFactor - B NSM_yeig ; 5 YEigFactor - B BadReadModeVar ; 6 LineLength Error - B BadReadModeVar ; 7 ScreenSize Error - B NSM_yshftfactor ; 8 YShftFactor (zero) - B NSM_bpp ; 9 Log2BPP - B NSM_bpp ; 10 Log2BPC as Log2BPP - B BadReadModeVar ; 11 XWindLimit Error - B BadReadModeVar ; 12 YWindLimit Error - -; entry conditions here -; r14 - sprite type in b0-b6 for a word offset -; r0 - mode word -; r1 - mode variable (no longer needed at this point) - -NSM_ncol ; r14 is already the type bits shifted down to b0-b6, ie a word offset - ADRL r2, NColourTable -4 ; results table (adjust for T=0 never occurring here) - LDR r2, [r2, r14, LSL #2] ; pull the correct value - CMP r2, #63 - MOVEQ r2, #255 ; make sure we return 255 not 63 - B GoodReadModeVar ; and return happily - -NSM_bpp - ADR r2, NSM_bpptable-4 ; (adjusted for T=0 never occurring here) - LDR r2, [r2, r14, LSL #2] - B GoodReadModeVar - -NSM_bpptable - ; note, yes - I know this could be type-1, but at some point some new type - ; will break the relationship so it's a table from day 1 to cope with this - & 0, 1, 2, 3, 4, 5 - -NSM_eig_mask - & &00001FFF - -NSM_yeig - MOV r0, r0, LSR #14 ; move ydpi into b0-b12 - B %FT10 - -NSM_xeig - MOV r0, r0, LSR #1 ; move xdpi into b0-b12 -10 - LDR r14, =&00001FFF ; mask for dpi bits - AND r0, r0, r14 - - CMP r0, #180 - MOVEQ r2, #0 - BEQ GoodReadModeVar - - CMP r0, #22 - CMPNE r0, #23 - MOVEQ r2, #3 - BEQ GoodReadModeVar - - TEQ r0, #(45 :SHL: 2), 2 ; check if 45 (EQ,CC if so) - CMPNE r0, #90 ; or 90 (EQ,CS if so) - BNE BadReadModeVar - MOVCC r2, #2 ; 45 => xeig=2 - MOVCS r2, #1 ; 90 => xeig=1 - B GoodReadModeVar - -NSM_modeflags -NSM_yshftfactor - MOV r2, #0 ; both these return zero - B GoodReadModeVar - -; ***************************************************************************** -; -; SWICheckModeValid - The 'Can I get into this mode?' call -; -; in: r0 = mode you want to get into (may be pointer to mode selector) -; out: C=0 => yes you can, r0 preserved -; C=1 => no you can't ... -; r0 = -1 => ... because the mode doesn't exist -; r1 = substitute mode -; r1 = -2 => not enough memory for even the substitute mode ! -; r0 = -2 => ... because not enough memory -; - -SWICheckModeValid ROUT - VDWS WsPtr - Push "r1,r9,lr" - BL FindOKMode ; out: r1 = substitute mode - BVS %FT90 - - CMP r1, #&100 ; if it's a mode number - BICCC r10, r1, #&80 ; then knock off shadow bit - MOVCS r10, r1 ; else don't - MOV r11, r10 - BL PushModeInfo - BVS %FT90 - - LDR r11, [r13, #wkScreenSize] ; get screen size for this mode - ADD r13, r13, #PushedInfoSize ; junk stacked mode table + VIDC info - - MOV r10, r1, LSR #7 ; 'shadow' bit (NB will be 0 or 1) - CMP r10, #2 ; except if its a mode selector - MOVCS r10, #0 ; in which case no shadow - LDROSB r9, Shadow - TEQ r0, r1 ; if substitute different from original - MOV r0, r1 ; (always set r0 to be substitute mode) - MOVNE r14, #-1 ; then indicate original is silly - MOVEQ r14, #0 ; else indicate sensible - TEQEQ r9, #0 ; and if shadow 0 - MOVEQ r10, #1 ; then force shadow mode - - LDR r9, [WsPtr, #TotalScreenSize] ; maximum allowed amount - CMP r9, r11, LSL r10 ; compare with this (*2 if shadow) - ; C=0 => No room - TEQ r14, #0 ; NZ => silly, CC => no room - - MOV r1, #-2 ; for if silly mode and bad space - Pull r1, EQ ; if not silly, restore old R1 - ADDNE r13, r13, #4 ; else junk stacked R1 - MOVHI r1, r0 ; silly mode, ok space, R1=subst. mode - - MOVCC r0, #-2 ; if no room, indicate it - MOVNE r0, #-1 ; but silly overrides this - - Pull "r9, r14" - CMP r0, #-2 ; C=1 => bad exit - BICCC r14, r14, #C_bit - ORRCS r14, r14, #C_bit - ExitSWIHandler - -; exit point in case of error from FindOKMode or PushModeInfo - -90 - Pull "r1, r9, r14" - MOV r0, #-1 ; indicate no such mode - MOV r1, #-2 ; and no substitute mode - ORR r14, r14, #C_bit - ExitSWIHandler - -; ***************************************************************************** -; -; FindOKMode - Convert mode number into an appropriate one for -; this monitor type -; -; in: r0 = original mode specifier -; -; out: If no error, then -; r0 preserved -; r1 = appropriate mode specifier -; V = 0 -; else -; r0 -> error -; r1 corrupted -; V = 1 -; endif -; All other registers preserved -; - -FindOKMode ROUT - Push "r0,r2-r4,r10,r11,lr" - BL ReadMonitorType - CMP r0, #&100 ; if it's a mode number - BICCC r2, r0, #&80 ; then knock off shadow bit - MOVCS r2, r0 ; else don't - BL OfferModeExtension - BNE %FT05 - -; service claimed - -; mjs Kernel/HAL split -; call HAL vetting routine to possibly disallow mode -; - Push "r0-r3, r9, r12" - MOV r0,r3 - MOV r1,r4 - ;we'll do the vet on whether h/w supports the pixel depth ourselves - LDR r2,[r0,#VIDCList3_PixelDepth] - MOV r3,#1 - MOV r3,r3,LSL r2 ; bits per pixel - [ UseGraphicsV - Push "r0-r2,r4" - MOV r4,#GraphicsV_DisplayFeatures - BL CallGraphicsV - TEQ r4,#0 - TSTEQ r3,r1 - Pull "r0-r2,r4" - | - LDR r2,[WsPtr,#HWPixelFormats] - TST r3,r2 - ] - MOVEQ r0,#1 - BEQ %FT04 ; not supported - ;now any vet the HAL might want to do - [ UseGraphicsV - Push "r4" - MOV r4, #GraphicsV_VetMode - BL CallGraphicsV - TEQ r4, #0 - MOVNE r0, #0 - Pull "r4" - | - mjsAddressHAL - mjsCallHAL HAL_Video_VetMode - ] -04 - CMP r0,#0 - Pull "r0-r3,r9,r12" - BNE %FT05 ; HAL says "Oi, Kernel, No!" - -; service claimed and happy HAL so return with this mode - - MOV r1, r0 - CLRV - Pull "r0,r2-r4,r10,r11,pc" - -05 - -; not claimed, so r2 (=mode without shadow) and r3 (=monitortype) are preserved - - Pull "r0" - CMP r0, #&100 ; if a mode selector and not responded to - BCS %FT30 ; then return error - - MOV r10, r2 ; mode without shadow bits - MOV r1, r0 ; start from existing mode - - CMP r3, #NumMonitorTypes ; monitor type must be in range - BCS %FT10 ; if not then must issue service - CMPCC r10, #NumModes ; and mode must be in range - MOVCC r11, #NumModes - MLACC r11, r3, r11, r10 ; then form monitortype*numberofmodes + modenumber - ADRCCL r14, BigVIDCTable ; point to big table - LDRCC r11, [r14, r11, LSL #2] ; and load offset - CMPCC r11, #-1 ; CS if mode number or monitor type out of range, or if not known in table - BCC %FT20 ; else it's known about, so OK - -; known monitor type, but unknown mode, so find substitute - - ADR r14, SubstModeTable - LDR r11, [r14, r3, LSL #2] - TEQ r11, #0 ; if r0=0, monitor type is actually unknown - issue service call - BEQ %FT10 - ADD r1, r11, r14 -05 - BL FindSubstitute - Pull "r2-r4,r10,r11, pc" ; exit VC or VS - -; unknown monitor type, so offer service - -10 - MOV r2, r10 - MOV r1, #Service_ModeTranslation - IssueService - TEQ r1, #0 - MOVEQ r1, r2 ; if claimed, then use module's mode - BEQ %FT20 - -; unknown monitor type -; if monitor type 7 (file), use substitution table for VGA (reasonable assumption) - - TEQ r3, #7 - ADREQ r1, SubstType3 - BEQ %BT05 - - MOV r1, #0 ; else panic and use mode 0 - -20 - CLRV - Pull "r2-r4,r10,r11, pc" - -30 - ADRL r0, ErrorBlock_ModeNotAvailable ; then return error - [ International - BL TranslateError - ] - SETV ; error exit - Pull "r2-r4,r10,r11, pc" - -SubstModeTable - & SubstType01-SubstModeTable - & SubstType01-SubstModeTable - & SubstType2-SubstModeTable - & SubstType3-SubstModeTable - & SubstType4-SubstModeTable - & 0 - & 0 - & 0 - & SubstType8-SubstModeTable - -SubstType01 - = 0, 8, 12, 15 -SubstType2 - = 23, 23, 23, 23 -SubstType3 - = 25, 26, 27, 28 -SubstType4 - = 29, 30, 31, 32 -SubstType8 - = 44, 45, 46, 46 - -; ***************************************************************************** -; -; FindSubstitute - Find substitute mode with right no. of bpp -; -; in: r1 -> table of 4 bytes; subst. modes for 1, 2, 4, 8 bpp respectively -; r10 = mode specifier to be tested (shadow bit clear) -; -; out: If no error, then -; r0 preserved -; r1 = substitute mode -; V=0 -; else -; r0 -> error -; r1 preserved -; endif -; r11 corrupted, all other registers preserved -; - -FindSubstitute Entry - MOV r11, #0 - BL PushModeInfoAnyMonitor - EXIT VS ; if error, then exit now - LDR r11, [r13, #wkLog2BPP] - ADD r13, r13, #PushedInfoSize - CMP r11, #4 - MOVCS r11, #0 - [ UseGraphicsV - Push "r0-r4" - MOV r4, #GraphicsV_DisplayFeatures - BL CallGraphicsV - TEQ r4, #0 - MOVEQ r2, r1 - MOVNE r2, #2_111111 - | - Push "r2, r3" - LDR r2, [WsPtr, #HWPixelFormats] ; see if h/w supports this BPP - ] - MOV r3, #1 - MOV r3, r3, LSL r11 - TST r2, r3 - MOVEQ r11, #3 ; if not, use 8 BPP (assumed best chance for a mode number) - [ UseGraphicsV - Pull "r0-r4" - | - Pull "r2, r3" - ] - LDRB r1, [r1, r11] - CLRV - EXIT - -; ***************************************************************************** -; -; ReadMonitorType - Read monitor type -; -; out: R3 = monitor type -; All other registers preserved -; - -ReadMonitorType Entry "r0-r2" - MOV r0, #1 - SWI XOS_ReadSysInfo ; out: r0 = mode, r1 = monitortype, r2 = sync - MOV r3, r1 ; move into r3 - EXIT - -; ***************************************************************************** -; -; SWIClaimScreenMemory - Claim unused screen memory (for ADFS etc.) -; -; in: R0 = 0 => release, 1 => claim -; R1 = length you require -; -; out: (for claim) -; C=0 => success -; R1 = actual length -; R2 = address -; -; C=1 => failure -; R1 = length you could have -; - -SWIClaimScreenMemory ROUT - MRS R11, CPSR ; disable IRQs, so can be called from - ORR R11, R11, #I32_bit ; an IRQ routine - MSR CPSR_c, R11 - - VDWS WsPtr - TEQ R0, #0 ; 0 => release - STREQB R0, [WsPtr, #ScreenMemoryClaimed] ; indicate free again - ExitSWIHandler EQ - -; is claim - - LDRB R10, [WsPtr, #ScreenMemoryClaimed] - TEQ R10, #0 ; already claimed (NZ) - MOVNE R1, #0 ; indicate you could have zero bytes - BNE %FT10 ; failure exit - - LDRB R10, [WsPtr, #ExternalFramestore] - TEQ R10, #0 - BNE %FT15 - - LDR R10, [WsPtr, #TotalScreenSize] - LDR R11, [WsPtr, #ScreenSize] - SUB R10, R10, R11 ; amount available - CMP R1, R10 ; is this enough - MOV R1, R10 ; tell him how much he could have - BHI %FT10 ; if not enough, then exit - - MOV R10, #1 ; indicate now claimed - STRB R10, [WsPtr, #ScreenMemoryClaimed] - - LDR R2, [WsPtr, #DisplayStart] - ADD R2, R2, R11 ; R2 -> start of usable area - - BIC R14, R14, #C_bit - ExitSWIHandler - -10 - ORR R14, R14, #C_bit - ExitSWIHandler - -; using external framestore - they can have the whole screen memory DA -15 - Push "R0,R1,R14" - MOV R0, #2 - SWI XOS_ReadDynamicArea ; R0 -> start, R1 = len - MOVVC R10, R0 - MOVVC R11, R1 - MOVVS R11, #0 - Pull "R0,R1,R14" - CMP R1, R11 ; is this enough - MOV R1, R11 ; tell him how much he could have - BHI %BT10 ; if not enough, then exit - - MOV R11, #1 ; indicate now claimed - STRB R11, [WsPtr, #ScreenMemoryClaimed] - - MOV R2, R10 - - BIC R14, R14, #C_bit - ExitSWIHandler - -; ***************************************************************************** -; -; SWIPlot - PLOT R0,R1,R2 -; -; in: R0 = plot code -; R1 = X coordinate -; R2 = Y coordinate -; -; out: - -; - -SWIPlot ROUT - CMP R0, #256 ; is plot code >= 256 ? - ExitSWIHandler CS ; yes, then do nothing - ; (for future expansion) - BranchNotJustUs %F10, WrchV, R12, R12 - - LDRB R12, [R11, #OsbyteVars + :INDEX: WrchDest] - LDRB R10, [R11, #OsbyteVars + :INDEX: SpoolFileH] - ORRS R10, R10, R12 - LDREQB R10, [R11, #OsbyteVars + :INDEX: VDUqueueItems] - TEQEQ R10, #0 - - VDWS WsPtr - LDREQ R10, [WsPtr, #CursorFlags] - TSTEQ R10, #VduDisabled ; if VDU disabled, go thru normal stuff - LDREQ R10, [WsPtr, #ModeFlags] ; if non-graphic, then send - TSTEQ R10, #Flag_NonGraphic ; thru normal chans - BNE %FT10 - - Push "R0-R9,R14" - [ No26bitCode - BL PreWrchCursor - WritePSRc SVC_mode, R14 ; interrupts on - | - ADR R14, %FT05 + SVC_mode ; R14 will have I_bit clear - -; TMD 16-May-89: Next instruction used to be B PreWrchCursor2, a secondary -; entry point that didn't disable IRQs as they were assumed to be already -; off. However this caused a bug in RISC OS 2.00, since SWIs are now entered -; with the IRQ state of the caller, so this has now been changed back to -; use the primary entry point (PreWrchCursor) which does disable them. - - B PreWrchCursor ; this exits by MOVS PC, R14 so it - ; clears the I_bit for us -; PreWrchCursor also exits with R6 = CursorFlags, needed for the -; EntryFromSWIPlot routine to do clip window calculations if necessary - -05 - ] - LDMFD R13, {R0-R2} - MOV R3, R0 ; save plot code - MOV R0, R1, LSL #16 - MOV R0, R0, ASR #16 ; R0 := sign extended X coord - MOV R1, R2, LSL #16 - MOV R1, R1, ASR #16 ; R1 := sign extended Y coord - MOV R2, R3 - MOV R9, #1 ; indicate entry from SWI Plot - BL EntryFromSWIPlot - BL PostWrchCursor - Pull "R0-R9,R14" - ExitSWIHandler - -SWIPlotBadExit - STR R0, [R13] ; save error block pointer in saved R0 - BL PostWrchCursor - Pull "R0-R9,R14" - ORR R14, R14, #V_bit - ExitSWIHandler - -10 - Push "R0,R14" - SWI XOS_WriteI+25 ; send 25 - SWIVC XOS_WriteC ; send plot code - ANDVC R0, R1, #&FF - SWIVC XOS_WriteC ; send X (lo) - MOVVC R0, R1, LSR #8 - SWIVC XOS_WriteC ; send X (hi) - ANDVC R0, R2, #&FF - SWIVC XOS_WriteC ; send Y (lo) - MOVVC R0, R2, LSR #8 - SWIVC XOS_WriteC ; send Y (hi) - - Pull "R0,R14", VC ; if no error, pull stacked R0 and R14 - ExitSWIHandler VC - - ADD R13, R13, #4 ; if error, junk stacked R0 - Pull "R14" - ORR R14, R14, #V_bit ; and set V bit in link - ExitSWIHandler - -; ***************************************************************************** -; -; SWIRemoveCursors - Remove input and output cursors for screen bashing -; -; out: All registers preserved (R10-R12 preserved by Sam) -; - -SWIRemoveCursors - Push "R0-R4,R6,R8-R9,R14" - VDWS WsPtr - BL PreWrchCursor - Pull "R0-R4,R6,R8-R9,R14" - ExitSWIHandler - -; ***************************************************************************** -; -; SWIRestoreCursors - Restore input and output cursors after screen bash -; -; out: All registers preserved (R10-R12 preserved by Sam) -; - -SWIRestoreCursors - Push "R0-R4,R6,R8-R9,R14" - VDWS WsPtr - BL PostWrchCursor - Pull "R0-R4,R6,R8-R9,R14" - ExitSWIHandler - -; ***************************************************************************** -; -; SWIWriteN - Write R1 bytes from address R0 to wrch -; -; in: R0 -> string -; R1 -> number of chars to print -; -; out: - -; - -SWIWriteN ROUT - Push "R0,R1,R14" - WritePSRc SVC_mode, R14 ; enable interrupts - - BranchNotJustUsWrch %F70 - -; R11 now points to either vector node or 1st address on chain, as appropriate -; R12 holds current value of this location, to be checked each time - - MOV R10, R0 -10 - SUBS R1, R1, #1 - BCC %FT90 ; count has expired (V=0) - [ StrongARM - LDRB R0, [R10], #1 - Push PC ; need to get to %FT20 - push PC+12 (old ARM) or PC+8 (StrongARM) - [ AssemblingArthur - B PMFWrchDirect - | - LDR PC, =(MOSDriver + MOSPMFWrch) - ] - MOV R0,R0 ; NOP for PC+8 case - | - Push PC ; push address of %FT20 - LDRB R0, [R10], #1 - [ AssemblingArthur - B PMFWrchDirect - | - LDR PC, =(MOSDriver + MOSPMFWrch) - ] - ] - -20 - BVS %FT90 - LDR R0, [R11] - TEQ R0, R12 ; vector still the same ? - BEQ %BT10 ; yes, then loop - B %FT75 ; no, do rest with wrch - -70 - ADDS R10, R0, #0 ; R10 := R0 and V := 0 -75 - ADD R11, R10, R1 - TEQ R10, R11 -80 - LDRNEB R0, [R10], #1 - SWINE XOS_WriteC - MOVVS R10, R11 - TEQ R10, R11 - BNE %BT80 -90 - Pull "R0,R1,R14", VC ; if no error, pull stacked R0,R1 & R14 - ExitSWIHandler VC - - ADD R13, R13, #4 ; if error, junk stacked R0 - Pull "R1,R14" - ORR R14, R14, #V_bit ; and set V bit in link - ExitSWIHandler - - -; ***************************************************************************** -; -; SWIWrite0 - Write a zero-terminated string pointed to by R0 -; -; in: R0 -> string -; -; out: R0 -> char after the zero -; - -SWIWrite0 ROUT - Push "R14" - WritePSRc SVC_mode, R10 ; enable interrupts - - MOV R10, R0 ; R10 -> string - - BranchNotJustUsWrch %F70 - -; R11 now points to either vector node or 1st address on chain, as appropriate -; R12 holds current value of this location, to be checked each time - -10 - LDRB R0, [R10], #1 - CMP R0, #0 - [ StrongARM - BEQ %FT80 ; no more characters - Push PC, NE ; need to get to %FT20 - push PC+12 (old ARM) or PC+8 (StrongARM) - [ AssemblingArthur - BNE PMFWrchDirect - | - LDRNE PC, =(MOSDriver + MOSPMFWrch) - ] - MOV R0,R0 ;NOP for PC+8 - | - Push PC, NE ; push address of %FT20 - [ AssemblingArthur - BNE PMFWrchDirect - | - LDRNE PC, =(MOSDriver + MOSPMFWrch) - ] - B %FT80 ; no more characters - ] - -20 - BVS %FT80 - LDR R0, [R11] - TEQ R0, R12 ; vector still the same ? - BEQ %BT10 ; yes, then loop - ; no, then drop thru - ; and do rest with Wrch -70 - LDRB R0, [R10], #1 - CMP R0, #0 ; (V:=0) - SWINE XOS_WriteC - BGT %BT70 ; branch if no error and not terminated -80 - MOVVC R0, R10 ; if no error, R0 -> char after zero - - Pull "R14" - ORRVS R14, R14, #V_bit - ExitSWIHandler - -; ***************************************************************************** -; -; SWIWriteS - Write a zero-terminated in-line string -; -; in: R14 -> first char of string (but has PSR bits in it) -; -; out: - -; - -SWIWriteS ROUT - Push "R0, R14" - WritePSRc SVC_mode, R10 ; enable interrupts - -; return address is on the stack, above our R0, R14, and SWI number - LDR R10, [R13, #12] - - BranchNotJustUsWrch %F70 - -; R11 now points to either vector node or 1st address on chain, as appropriate -; R12 holds current value of this location, to be checked each time - -10 - LDRB R0, [R10], #1 - CMP R0, #0 - [ StrongARM - BEQ %FT80 ; no more characters - Push PC, NE ; need to get to %FT20 - push PC+12 (old ARM) or PC+8 (StrongARM) - BNE PMFWrchDirect - MOV R0,R0 ;NOP for PC+8 - | - Push PC, NE ; push address of %FT20 - BNE PMFWrchDirect - B %FT80 ; no more characters - ] -20 - BVS %FT80 - LDR R0, [R11] - TEQ R0, R12 ; vector still the same ? - BEQ %BT10 ; yes, then loop - ; no, then drop thru - ; and do rest with Wrch -70 - LDRB R0, [R10], #1 - CMP R0, #0 ; (V:=0) - SWINE XOS_WriteC - BGT %BT70 ; branch if no error and not terminated -80 - BVS %FT90 - Pull "R0, R14" -85 - [ No26bitCode - TST R14, #T32_bit - ADDNE R10, R10, #1 ; if Thumb - BICNE R10, R10, #1 ; round up to next halfword boundary - ADDEQ R10, R10, #3 ; else - BICEQ R10, R10, #3 ; round up to next word boundary - | - ADD R10, R10, #3 - BIC R10, R10, #3 ; round up to next word boundary - ] - STR R10, [R13, #4] ; Poke new address into stack - ExitSWIHandler - -90 - Pull "R11, R14" ; junk the stacked R0 - ORR R14, R14, #V_bit -95 - LDRB R11, [R10], #1 ; skip to the zero terminator - TEQ R11, #0 - BNE %BT95 - B %BT85 - - [ AssemblingArthur - -; ***************************************************************************** -; -; RemovePages - Called by MOS when ChangeDynamicArea reduces the -; amount of screen memory -; -; in: R0 = - number of bytes being removed -; R4 = current size -; -; out: All registers preserved -; - -RemovePages ROUT - Push "R0-R8,R12,R14" - BL InsertRemovePagesCommon - BNE RemovePages_ExternalFramestore - LDR R14, [WsPtr, #ScreenEndAddr] - ADD R2, R0, R14 ; end of remaining screen memory - -; display starts in pages that remain - - SUB R5, R3, R0 ; new DisplayStart - -05 - CMP R5, R14 ; if off end of 1st copy - SUBCS R5, R5, R4 ; then repeatedly subtract off new size - BCS %BT05 ; until in range - - Push "R0-R2" - MOV R0, R5 ; put new display start in r0 - BL SetVinit ; this updates DisplayStart - Pull "R0-R2" - - ADD R3, R3, R4 ; end of area to copy +1 - CMP R3, R2 - BLS %FT20 ; nothing to copy - - SUB R4, R3, R0 ; destination end -10 - LDMDB R3!, {R5-R8} ; load 4 words (minimum amount) - STMDB R4!, {R5-R8} ; store 4 words - TEQ R3, R2 - BNE %BT10 - -20 -InsertRemovePagesExit - LDR R14, [WsPtr, #ScreenEndAddr] - LDR R4, [WsPtr, #DisplayScreenStart] - SUB R0, R4, R0 - LDR R3, [WsPtr, #TotalScreenSize] -25 - CMP R0, R14 ; ensure displayscreenstart in range too - SUBCS R0, R0, R3 - BCS %BT25 - BL NewScreenStart -30 - BL SetVendDefault - - Pull "R0-R8,R12,PC" - -; in: R0 = - number of bytes being removed -; R4 = current size -RemovePages_ExternalFramestore - - [ {FALSE} -; Should do the copy, but need access to address - ADD R3, R3, R4 ; end of area to copy +1 - CMP R3, R2 - BLS %FT20 ; nothing to copy - - SUB R4, R3, R0 ; destination end -10 - LDMDB R3!, {R5-R8} ; load 4 words (minimum amount) - STMDB R4!, {R5-R8} ; store 4 words - TEQ R3, R2 - BNE %BT10 - -20 - ] -InsertRemovePages_ExternalFramestoreExit - Pull "R0-R8,R12,PC" - -; ***************************************************************************** -; -; InsertPages - Called by MOS when ChangeDynamicArea increases the -; amount of screen memory -; -; in: R0 = number of bytes being added -; R4 = new size -; - -InsertPages ROUT - Push "R0-R8,R12,R14" - BL InsertRemovePagesCommon - BNE InsertPages_ExternalFramestore - SUB R5, R3, R0 ; new DisplayStart - STR R5, [WsPtr, #DisplayStart] - ADD R2, R3, R1 ; end of block to copy - - LDR R3, [WsPtr, #ScreenEndAddr] - SUB R4, R3, R0 -10 - TEQ R3, R2 - LDMNEIA R3!, {R5-R8} - STMNEIA R4!, {R5-R8} - BNE %BT10 - B InsertRemovePagesExit - -InsertPages_ExternalFramestore -; Should do copy here - B InsertRemovePages_ExternalFramestoreExit - -; ***************************************************************************** - -InsertRemovePagesCommon ROUT - VDWS WsPtr - LDR R1, [WsPtr, #ExternalFramestore] - TEQ R1, #0 - MOVNE PC, R14 - - LDR R1, [WsPtr, #TotalScreenSize] ; old size - - MOV R4, #0 - STRB R4, [R4, #OsbyteVars + :INDEX:MemDriver] ; indicate default - STRB R4, [R4, #OsbyteVars + :INDEX:MemDisplay] ; for both of these - - LDR R4, [WsPtr, #VduStatus] ; not shadowing any more - BIC R4, R4, #Shadowing - STR R4, [WsPtr, #VduStatus] - - ADD R4, R1, R0 ; length of remaining screen memory - STR R4, [WsPtr, #TotalScreenSize] ; new size - LDR R3, [WsPtr, #ScreenEndAddr] - RSB R5, R4, R3 ; start of remaining screen memory - STR R5, [WsPtr, #DriverBankAddr] - STR R5, [WsPtr, #DisplayBankAddr] - - LDR R3, [WsPtr, #DisplayStart] - MOV PC, R14 - - ] - -; ***************************************************************************** -; -; SWIChangedBox - Entry point for SWI OS_ChangedBox -; -; in: R0 = 0 => disable clip box calculations -; 1 => enable clip box calculations -; 2 => reset clip box to null -; -1 => do nothing -; -; out: R0 = old enable state (0 => disabled, 1 => enabled) -; R1 -> clipbox info, consisting of 5 words -; [R1, #0] = disable/enable flag (in bit 0) -; [R1, #4] = internal X-coord of left edge of box -; [R1, #8] = internal Y-coord of bottom edge of box -; [R1, #12] = internal X-coord of right edge of box -; [R1, #16] = internal Y-coord of top edge of box -; - -SWIChangedBox ROUT - VDWS WsPtr - MOV R1, WsPtr - LDR R10, [R1, #ClipBoxEnable]! ; R10 = old state, R1 -> state - CMP R0, #2 ; known reason ? - BHI %FT10 ; no, then just read state - BEQ %FT20 ; reset rectangle to null - - STR R0, [R1] ; then store R0 in ClipBoxEnable - WritePSRc SVC_mode + I_bit, R11 ; disable IRQs to update CursorFlags - TST R0, #1 - LDR R0, [WsPtr, #CursorFlags] - BICEQ R0, R0, #ClipBoxEnableBit - ORRNE R0, R0, #ClipBoxEnableBit - STR R0, [WsPtr, #CursorFlags] -10 - MOV R0, R10 ; R0 = old state - ExitSWIHandler - -20 - Push "R4-R7" - ADR R0, NullRectangle - LDMIA R0, {R4-R7} - STMIB R1, {R4-R7} ; store over coordinates - Pull "R4-R7" - B %BT10 - -NullRectangle - & &7FFFFFFF, &7FFFFFFF, &80000000, &80000000 - -; ***************************************************************************** -; -; SetClipBoxToFullScreen - Called by FF -; -; in: WsPtr -> VduDriverWorkSpace -; -; out: R0-R4 corrupted -; PSR preserved -; - - ASSERT YWindLimit = XWindLimit +4 - -SetClipBoxToFullScreen ROUT - ADD R4, WsPtr, #XWindLimit - LDMIA R4, {R2, R3} - MOV R0, #0 - MOV R1, #0 - ADD R4, WsPtr, #ClipBoxCoords - STMIA R4, {R0-R3} - MOV PC, R14 - -; ***************************************************************************** -; -; MergeClipBox - Merge a given rectangle into clip box -; -; in: R0..R3 = Left, bottom, right, top of rectangle to merge -; WsPtr -> VduDriverWorkSpace -; -; out: All registers preserved -; - -MergeClipBox ROUT - Push "R4-R8, R14" - ADD R8, WsPtr, #ClipBoxCoords - LDMIA R8, {R4-R7} - BL MergeClipBoxes - STMIA R8, {R4-R7} - Pull "R4-R8, PC" - -MergeClipBoxes ROUT - CMP R0, R4 - MOVLT R4, R0 - CMP R1, R5 - MOVLT R5, R1 - CMP R2, R6 - MOVGT R6, R2 - CMP R3, R7 - MOVGT R7, R3 - MOV PC, R14 - -; ***************************************************************************** -; -; DoPlotClipBox - Compute clip box for a PLOT command -; -; in: R2 = plot code -; -; out: R0-R2 preserved -; - -DoPlotClipBox ROUT - TST R2, #3 ; (R2 AND 3)=0 => move operation - ADRNE R11, ClipBoxPlotTable - LDRNEB R11, [R11, R2, LSR #3] ; get 'type' of this plot - TEQNE R11, #0 ; 0 => don't change clip window - MOVEQ PC, R14 - Push "R0-R2, R14" - CMP R11, #3 ; if 1..3 - BLS ClipLastR11Points ; then use last R11 points - CMP R11, #ClipIndex_Ellipse - BCC ClipFullWindow ; flood fill => merge graphics window - BEQ ClipEllipse - CMP R11, #ClipIndex_LineFill - BCC ClipParallelogram - BEQ ClipLineFill - Pull "R0-R2, PC" - -ClipIndex_FloodFill * 4 -ClipIndex_Ellipse * 5 -ClipIndex_Parallelogram * 6 -ClipIndex_LineFill * 7 - -ClipBoxPlotTable - = 2,2,2,2,2,2,2,2 ; 00..38 line drawing - = 1 ; 40 point plot - = ClipIndex_LineFill ; 48 line fill - = 3 ; 50 triangle - = ClipIndex_LineFill ; 58 line fill - = 2 ; 60 rectangle fill - = ClipIndex_LineFill ; 68 line fill - = ClipIndex_Parallelogram ; 70 parallelogram - = ClipIndex_LineFill ; 78 line fill - = ClipIndex_FloodFill ; 80 flood fill - = ClipIndex_FloodFill ; 88 flood fill - = 0,0,0,0,0 ; 90..B0 circle things - ; (done in GenCircleParm) - = 0 ; B8 block copy/move (done in code) - = ClipIndex_Ellipse ; C0 ellipse outline - = ClipIndex_Ellipse ; C8 ellipse fill - = 0, 0, 0 ; D0..E0 do nothing - = 0 ; E8 sprite plot (done in SWI SpriteOp) - = 0, 0 ; F0,F8 do nothing - ALIGN - -ClipLastR11Points ROUT - ADD R10, WsPtr, #NewPtX - BL MergeR11PointsFromR10 - Pull "R0-R2, PC" - -MergeR11PointsFromR10 ROUT - Push R14 - LDMIA R10, {R4,R5} ; get last point - MOV R6, R4 ; right=left - MOV R7, R5 ; top=bottom - SUBS R11, R11, #1 - BEQ %FT10 -05 - LDMDB R10!, {R0,R1} ; get another point (X,Y) - MOV R2, R0 - MOV R3, R1 - BL MergeClipBoxes - SUBS R11, R11, #1 ; one less point to do - BNE %BT05 -10 - -; now clip this to graphics window - - ADD R10, WsPtr, #GWLCol - LDMIA R10, {R0-R3} - CMP R4, R0 - MOVGE R0, R4 - CMP R5, R1 - MOVGE R1, R5 - CMP R6, R2 - MOVLE R2, R6 - CMP R7, R3 - MOVLE R3, R7 - CMP R2, R0 - CMPGE R3, R1 - BLGE MergeClipBox ; if R>=L and T>=B then merge - Pull PC - - -ClipLineFill ROUT - ADD R10, WsPtr, #GWLCol - LDMIA R10, {R0-R3} - ADD R10, WsPtr, #NewPtX - LDMIA R10, {R4-R5} - CMP R4, R0 ; if point is inside window - CMPGE R2, R4 - CMPGE R5, R1 - CMPGE R3, R5 - MOVGE R1, R5 ; then top=bottom=Y - MOVGE R3, R5 ; and left=GWLCol, right=GWRCol - BLGE MergeClipBox - Pull "R0-R2, PC" - -ClipParallelogram ROUT - ADD R10, WsPtr, #OldCsX - LDMIA R10, {R0-R5} ; load up last 3 points -ClipParallelRegs - ADD R6, R0, R4 ; 4th point = 1st + 3rd - 2nd - SUB R6, R6, R2 - ADD R7, R1, R5 - SUB R7, R7, R3 - Push "R0-R7" ; stack all four points - ADD R10, R13, #6*4 ; point R10 at last point - MOV R11, #4 ; 4 points to merge - BL MergeR11PointsFromR10 - ADD R13, R13, #8*4 ; junk stacked points - Pull "R0-R2, PC" - -ClipEllipse ROUT - ADD R10, WsPtr, #OldCsX - LDMIA R10, {R0-R5} ; last 3 points (AX,AY,BX,BY,CX,CY) - SUB R6, R2, R0 ; R6 = BX-AX - ADD R0, R0, R2 ; R0 = AX+BX - SUB R0, R0, R4 ; R0 = AX+BX-CX - ADD R2, R4, R6 ; R2 = CX+BX-AX - SUB R4, R4, R6 ; R4 = CX-(BX-AX) = CX+AX-BX - RSB R1, R5, R1, LSL #1 ; R1 = 2*AY-CY - MOV R3, R5 ; R3 = CY - B ClipParallelRegs - -ClipFullWindow ROUT - ADD R10, WsPtr, #GWLCol ; merge graphics window with - LDMIA R10, {R0-R3} ; clip rectangle (which can be larger) - BL MergeClipBox - Pull "R0-R2, PC" - -; ***************************************************************************** -; -; ClipBlockCopyMove - Calculate clip box for block copy/move -; -; in: R0-R7 = SrcL, SrcB, SrcR, SrcT, DestL, DestB, DestR, DestT -; R8 = 0 => move, 2 => copy -; -; out: R0-R7 preserved -; R8-R11 undefined -; - -ClipBlockCopyMove ROUT - Push "R0-R7, R14" - ADD R10, R13, #6*4 ; R10 -> last point (DestR,DestT) - RSB R11, R8, #4 ; R11 = 4 if move, 2 if copy - ; (number of points to merge) - BL MergeR11PointsFromR10 - Pull "R0-R7, PC" - -; ***************************************************************************** -; -; ClipCircle - Add circle bounding box to clip box -; -; in: R0 = radius of circle in square pixels -; R5, R6 = CentreX, CentreY -; R7 = AspectRatio (0 => square, 1 => flat rect, 2 => tall rect) -; -; out: R0-R7 preserved -; R8-R11 undefined -; - -ClipCircle ROUT - Push "R0-R7,R14" - CMP R7, #1 - MOVEQ R8, R0, LSR #1 ; if flat then dX = rad/2 - MOVNE R8, R0 ; else dX = rad - MOVHI R9, R0, LSR #1 ; if tall then dY = rad/2 - MOVLS R9, R0 ; else dY = rad - SUB R0, R5, R8 ; left - SUB R1, R6, R9 ; bottom - ADD R2, R5, R8 ; right - ADD R3, R6, R9 ; top - Push "R0-R3" - ADD R10, R13, #2*4 ; point R10 at last point - MOV R11, #2 ; 2 points to merge - BL MergeR11PointsFromR10 - ADD R13, R13, #4*4 ; junk stacked points - Pull "R0-R7,PC" - -; ***************************************************************************** -; -; ClipCursorCell - Add current cursor cell to clip box -; -; in: - -; -; out: All registers preserved -; - -ClipCursorCell ROUT - ASSERT CursorY = CursorX +4 - Push "R0-R3, R14" - ADD R0, WsPtr, #CursorX - LDMIA R0, {R0, R1} - MOV R2, R0 ; RCol = LCol - MOV R3, R1 ; TRow = BRow - BL ClipTextArea - Pull "R0-R3, PC" - -; ***************************************************************************** -; -; ClipTextArea - Add a text area to the clip box -; -; in: R0 = LCol of area -; R1 = BRow of area -; R2 = RCol of area -; R3 = TRow of area -; -; out: All registers preserved -; - -ClipTextArea ROUT - Push "R0-R3, R14" - MOV R0, R0, LSL #3 ; left = LCol*8 - MOV R2, R2, LSL #3 - ADD R2, R2, #7 ; right = RCol*8 + 7 - LDR R14, [WsPtr, #RowMult] - MUL R3, R14, R3 ; TRow * RowMult - MLA R1, R14, R1, R14 ; (BRow+1) * RowMult - LDR R14, [WsPtr, #YWindLimit] - SUB R3, R14, R3 ; top = YWindLimit-TRow*RowMult - SUB R1, R14, R1 - ADD R1, R1, #1 ; bot = YWindLimit-(BRow+1)*Mult+1 - BL MergeClipBox - Pull "R0-R3, PC" - -; ***************************************************************************** -; -; ClipScroll - Add clip box when scrolling -; -; in: R0 = 0 => add text window -; R0 <> 0 => set to full screen -; -; out: All registers preserved -; - -ClipScroll ROUT - Push "R0-R4, R14" - CMP R0, #1 ; if scrolling screen - BLCS SetClipBoxToFullScreen ; set to full screen - - ADDCC R4, WsPtr, #TWLCol ; else add text window - LDMCCIA R4, {R0-R3} - BLCC ClipTextArea - - Pull "R0-R4, PC" - -; ***************************************************************************** -; -; ClipSpritePlot - Compute and merge sprite plot bounding box -; -; in: R0 = unclipped X-coord (internal) -; R1 = clipped topY (internal) -; R2 = width of sprite in words -; R3 = height of sprite -1 -; R4 = GWLCol -; R5 = height reduction -; R6 = GWRCol -; R8 -> sprite -; -; out: All registers preserved -; - -ClipSpritePlot ROUT - Push "R0-R11, R14" - ADD R9, R8, #spLBit - LDMIA R9, {R9, R10} ; R9 = spLBit; R10 = spRBit - ADD R2, R9, R2, LSL #5 ; R2 = width*32+spLBit - RSB R10, R10, #32 ; R10 = 32-spRBit - SUB R2, R2, R10 ; R2 = width in bits-1 - LDR R9, [WsPtr, #Log2BPC] - ADD R2, R0, R2, LSR R9 ; R2 = unclipped rightX - CMP R0, R4 - MOVLT R0, R4 ; R0 = clipped leftX - CMP R2, R6 - MOVGT R2, R6 ; R2 = clipped rightX - SUB R3, R3, R5 ; R3 = no. of lines on screen -1 - SUB R1, R1, R3 ; R1 = clipped botY - ADD R3, R1, R3 ; R3 = clipped topY - - CMP R2, R0 ; if right>=left - CMPGE R3, R1 ; and top>=bot - BLGE MergeClipBox ; then add rectangle - Pull "R0-R11, PC" - - -; ***************************************************************************** -; -; ScreenModeSWI - Entry point for SWI OS_ScreenMode -; -; in: r0 = reason code -; Other registers depend on reason code -; -; out: Depends on reason code -; - -ScreenModeSWI Entry - BL ScreenModeSub - PullEnv - ORRVS lr, lr, #V_bit - ExitSWIHandler - - ASSERT ScreenModeReason_SelectMode = 0 - ASSERT ScreenModeReason_ReturnMode = 1 - ASSERT ScreenModeReason_EnumerateModes = 2 - ASSERT ScreenModeReason_SelectMonitorType = 3 - ASSERT ScreenModeReason_Limit = 4 - -ScreenModeSub - CMP r0, #ScreenModeReason_Limit - ADDCC pc, pc, r0, LSL #2 - B ScreenMode_Unknown - B ScreenMode_SelectMode - B ScreenMode_ReturnMode - B ScreenMode_EnumerateModes - B ScreenMode_SelectMonitorType - -; unknown OS_ScreenMode reason code - -ScreenMode_Unknown - ADR r0, ErrorBlock_ScreenModeBadReason -ScreenMode_TranslateAndReturnError - [ International - Push lr - BL TranslateError - Pull lr - ] -ScreenMode_ReturnError - SETV - MOV pc, lr - -; Temporary error blocks, so we don't have to claim Hdr:NewErrors every 5 mins. - -ErrorBlock_ScreenModeBadReason - & 0 - = "Zonk:Unknown OS_ScreenMode reason code", 0 - ALIGN - -;************************************************************************** -; -; ScreenMode_SelectMode - Select a screen mode -; -; Internal routine called by ScreenModeSWI -; -; in: r0 = reason code (0) -; r1 = mode specifier -; -; out: r10-r12 may be corrupted -; All other registers preserved -; - -ScreenMode_SelectMode Entry "r0-r9" - WritePSRc SVC_mode, WsPtr ; enable IRQs - VDWS WsPtr - BL PreWrchCursor ; remove cursor - LDR r2, [sp, #1*4] ; reload mode specifier - BL ModeChangeSub ; perform mode change - BVS %FT90 - BL PostWrchCursor ; if no error, then restore cursor - CLRV ; indicate no error - EXIT ; and exit - -90 - STR r0, [sp] ; overwrite stacked r0 with error ptr - BL PostWrchCursor ; restore cursor - SETV ; indicate error - EXIT ; and exit - -;************************************************************************** -; -; ScreenMode_ReturnMode - Return current screen mode specifier -; -; Internal routine called by ScreenModeSWI -; -; in: r0 = reason code (1) -; -; out: r1 = mode specifier -; r10-r12 may be corrupted -; All other registers preserved -; - -ScreenMode_ReturnMode ROUT - VDWS WsPtr - LDR r1, [WsPtr, #ModeNo] - CLRV - MOV pc, lr - -;************************************************************************** -; -; ScreenMode_EnumerateModes - Enumerate screen modes -; -; Internal routine called by ScreenModeSWI -; -; in: r0 = reason code (2) -; r2 = enumeration index (0 to start from beginning) -; r6 -> block to return data into, or 0 to just count entries -; r7 = size of block if r6<>0, or zero if r6=0 -; -; out: r1 = 0 if service claimed, otherwise r1<>0 -; r2 = updated enumeration index -; r6 = updated block pointer -; r7 = size of remaining free area in block -; r10-r12 may be corrupted -; All other registers are preserved -; - -ScreenMode_EnumerateModes Entry "r3-r5" - MOV r1, #Service_EnumerateScreenModes - BL ReadMonitorType - GetBandwidthAndSize r4, r5 - BL Issue_Service - EXIT - -;************************************************************************** -; -; ScreenMode_SelectMonitorType - Select current monitor type -; -; Internal routine called by ScreenModeSWI -; -; in: r0 = reason code (3) -; r1 = monitor type to set, or -1 to restore from configured value -; -; out: r10-r12 may be corrupted -; All other registers preserved -; - -ScreenMode_SelectMonitorType Entry "r0" - VDWS WsPtr - CMP r1, #-1 ; if not restoring configured value - BNE %FT10 ; then skip - BL Read_Configd_MonitorType ; else read CMOS value (returns in r0) - MOV r1, r0 -10 - STR r1, [WsPtr, #CurrentMonitorType] ; update current value - EXIT - -;;;mjsHAL - VIDCDividerSWI is horrible VIDC specific API, compiled out -;;; -; Should not cause any problems on any machine. STB flag just to be safe though. - [ STB :LAND: {FALSE} -; ***************************************************************************** -; -; VIDCDividerSWI - Entry point for SWI OS_VIDCDivider -; -; in: r0 = Value for divider - 1 -; -; out: r0 = Preserved or error if V set -; - -VIDCDividerSWI Entry "r0-r1,WsPtr" - CMP r0, #8 ; Check the value is in range. - BCC %FT10 ; Continue if so. - PullEnv ; Else return an error. - ADR r0, ErrorBlock_BadVIDCDivider ; Get address of error. - [ International - BL TranslateError ; Translate the error. - ] - ORR lr, lr, #V_bit ; Return with V bit set. - ExitSWIHandler - -10 - VDWS WsPtr ; Get the VDU work space. - LDR r1, [WsPtr, #VIDCControlSoftCopy] ; Get the old control register value. - BIC r1, r1, #7:SHL:CR_PixelDivShift ; Mask out the old divider. - ORR r1, r1, r0, LSL #CR_PixelDivShift ; ORR in the new... - STR r1, [WsPtr, #VIDCControlSoftCopy] ; Write back to work space. - MOV r0, #VIDC - STR r1, [r0, #0] ; Write to VIDC also. - PullEnv ; Done. - ExitSWIHandler - -ErrorBlock_BadVIDCDivider - & 0 - = "BadVIDCDiv:Bad VIDC divider value.", 0 - - ] - - END diff --git a/s/vdu/vduttx b/s/vdu/vduttx deleted file mode 100644 index d8992c59..00000000 --- a/s/vdu/vduttx +++ /dev/null @@ -1,1834 +0,0 @@ -; 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.VduTTX - -; Teletext (MODE 7) emulation -; --------------------------- - -; Author Tim Dobson -; Started 24-Feb-87 - -; ***************************************************************************** - -; Teletext control codes - -TTX_AlphaRed * &01 -TTX_AlphaGreen * &02 -TTX_AlphaYellow * &03 -TTX_AlphaBlue * &04 -TTX_AlphaMagenta * &05 -TTX_AlphaCyan * &06 -TTX_AlphaWhite * &07 -TTX_Flash * &08 -TTX_Steady * &09 -TTX_EndBox * &0A -TTX_StartBox * &0B -TTX_NormalHeight * &0C -TTX_DoubleHeight * &0D - -TTX_GraphRed * &11 -TTX_GraphGreen * &12 -TTX_GraphYellow * &13 -TTX_GraphBlue * &14 -TTX_GraphMagenta * &15 -TTX_GraphCyan * &16 -TTX_GraphWhite * &17 -TTX_Conceal * &18 -TTX_Contiguous * &19 -TTX_Separated * &1A -TTX_BlackBackgd * &1C -TTX_NewBackgd * &1D -TTX_HoldGraph * &1E -TTX_RelGraph * &1F - -TTXGraphContFontA * TTXSoftFonts +0 ; Contiguous graphics font (&20-&3F) -TTXGraphSepaFontA * TTXSoftFonts +&140 ; Separated graphics font (&20-&3F) -TTXGraphContFontB * TTXSoftFonts +&280 ; Contiguous graphics font (&60-&7F) -TTXGraphSepaFontB * TTXSoftFonts +&3C0 ; Separated graphics font (&60-&7F) - -; Bits in the map - -; Bits 0-7 8 bit character -; Bit 8 0 => Alpha, 1 => Graphics -; Bit 9 0 => Contiguous, 1 => Separated -; Bit 10 0 => Steady, 1 => Flash -; Bit 11 0 => Release, 1 => Hold -; Bit 12 0 => Reveal, 1 => Conceal -; Bits 13-14 Bit 13 Bit 14 -; 0 0 Single Height -; 1 0 Undefined -; 0 1 Double Height Top -; 1 1 Double Height Bottom -; Bit 15 1 => Pending Start Box -; Bit 16 1 => Pending End Box -; Bits 17-19 Foreground colour -; Bit 20 0 => Unboxed, 1 => Boxed -; Bits 21-23 Background colour -; Bit 24 0 => Unboxed, 1 => Boxed -; Bits 25-29,31 Held graphic -; Bit 30 0 => Held graphic contiguous, 1 => separated - -MapBit_Char * 1 :SHL: 0 -MapBit_Graph * 1 :SHL: 8 -MapBit_Separated * 1 :SHL: 9 -MapBit_Flash * 1 :SHL: 10 -MapBit_Hold * 1 :SHL: 11 -MapBit_Conceal * 1 :SHL: 12 -MapBit_Bottom * 1 :SHL: 13 -MapBit_Double * 1 :SHL: 14 -MapBit_PendingStart * 1 :SHL: 15 - -MapBit_PendingEnd * 1 :SHL: 16 -MapBit_ForeMask * 7 :SHL: 17 -MapBit_BackMask * 7 :SHL: 21 -MapBits_Boxed * (1 :SHL: 20) :OR: (1 :SHL: 24) -MapBit_HeldMask * &7F :SHL: 25 -MapBit_HeldSeparated * 1 :SHL: 30 - -MapForeShift * 17 -MapBackShift * 21 -MapHeldShift * 25 - -MapBit_Default * (7 :SHL: MapForeShift)+32 ; default at start of line - -; ***************************************************************************** -; -; TeletextInit - Initialise teletext workspace -; Called when MODE 7 (or 135) is selected -; - -TeletextInit ROUT - MOV R0, #1 ; set to flash immediately - STR R0, [WsPtr, #TeletextCount] - - MOV R0, #TTXFlag_Conceal - ORR R0, R0, #TTXFlag_FgTransBIC :OR: TTXFlag_BgTransBIC - STR R0, [WsPtr, #TTXFlags] - - [ :LNOT: HiResTTX -; compute the graphics fonts - - ADD R0, WsPtr, #TTXSoftFonts ; R0 -> contiguous font - MOV R2, #&20 ; R2 = character number - MOV R3, #0 ; R3 = byte to store -10 - ADD R1, R0, #&140 ; R1 -> separated font -20 - TST R2, #1 ; top left - ORRNE R3, R3, #&F0 - TST R2, #2 ; top right - ORRNE R3, R3, #&0F - STRB R3, [R0], #1 ; 3 pixel rows for top - STRB R3, [R0], #1 - STRB R3, [R0], #1 - AND R3, R3, #&77 ; do separated - STRB R3, [R1], #1 - STRB R3, [R1], #1 - MOV R3, #0 - STRB R3, [R1], #1 - - TST R2, #4 ; middle left - ORRNE R3, R3, #&F0 - TST R2, #8 ; middle right - ORRNE R3, R3, #&0F - STRB R3, [R0], #1 ; 4 pixel rows for middle - STRB R3, [R0], #1 - STRB R3, [R0], #1 - STRB R3, [R0], #1 - AND R3, R3, #&77 ; do separated - STRB R3, [R1], #1 - STRB R3, [R1], #1 - STRB R3, [R1], #1 - MOV R3, #0 - STRB R3, [R1], #1 - - TST R2, #&10 ; bottom left - ORRNE R3, R3, #&F0 - TST R2, #&40 ; bottom right - ORRNE R3, R3, #&0F - STRB R3, [R0], #1 ; 3 pixel rows for bottom - STRB R3, [R0], #1 - STRB R3, [R0], #1 - AND R3, R3, #&77 ; do separated - STRB R3, [R1], #1 - STRB R3, [R1], #1 - MOV R3, #0 - STRB R3, [R1], #1 - - ADD R2, R2, #1 - TEQ R2, #&40 ; if at end of 1st part - MOVEQ R2, #&60 ; then start 2nd - ADDEQ R0, R0, #&140 ; skipping separated already done - BEQ %BT10 ; and resetting R1 too - - TEQ R2, #&80 ; finished - BNE %BT20 - ] - - MOV PC, R14 - -; ***************************************************************************** -; -; Vdu23_18 - Miscellaneous Teletext operations -; - -Vdu23_18 - LDRB R2, [WsPtr, #QQ+1] - CMP R2, #(Vdu23_18_TabEnd - Vdu23_18_TabStart) / 4 - ADDCC PC, PC, R2, LSL #2 - B UnknownVdu23 -Vdu23_18_TabStart - B Vdu23_18_0 - B Vdu23_18_1 - B Vdu23_18_2 - B Vdu23_18_3 -Vdu23_18_TabEnd - -; ***************************************************************************** -; -; Vdu23_18_0 - Set transparency -; - -Vdu23_18_0 ROUT - Push "R14" - LDRB R5, [WsPtr, #QQ+2] - AND R5, R5, #3 - LDR R6, [WsPtr, #TTXFlags] - AND R14, R6, #TTXFlag_TransModeMask - TEQ R14, R5, LSL #TTXFlag_TransModeShift - Pull "PC", EQ ; fast exit if nothing's changed - - ; Because the border is being reprogrammed, switches in and out of mode 0 (solid) - ; look messy unless we reprogram the palette too (on the non-solid side of the switch) - TEQ R5, #0 ; switching into mode 0? - ADREQ R2, TTXPalette_Solid ; if so, program a solid palette - MOVEQ R7, #0 ; use a black border - BLEQ SetTTXPalette - - ; Munge the TTXFlags to match the transparency mode - ORR R6, R6, #TTXFlag_FgTransEOR :OR: TTXFlag_BgTransEOR - ORR R6, R6, #TTXFlag_FgTransBIC :OR: TTXFlag_BgTransBIC - TEQ R5, #3 ; already adjusted for mode 3 (transparent) - BEQ %FT10 - TEQ R5, #2 ; in modes 0 (solid) and 1 (mix) - BICNE R6, R6, #TTXFlag_FgTransEOR ; we just clear the fg transparency bit - BICEQ R6, R6, #TTXFlag_FgTransBIC ; in mode 2 (box) we just toggle it - TEQ R5, #0 ; in modes 1 (mix) and 2 (box) - BICNE R6, R6, #TTXFlag_BgTransBIC ; we just toggle the bg transparency bit - BICEQ R6, R6, #TTXFlag_BgTransEOR ; in mode 0 (solid) we just clear it -10 - ; Move the mode bits from TTXFlags to R7, and then from R5 to TTXFlags - MOV R7, R6 - BIC R6, R6, #TTXFlag_TransModeMask - ORR R6, R6, R5, LSL #TTXFlag_TransModeShift - STR R6, [WsPtr, #TTXFlags] - - ; Redraw the screen - Push "R7" - BL RefreshBitmap - Pull "R7" - - ; Deal with the opposite palette programming case (switching away from mode 0) - TST R7, #TTXFlag_TransModeMask - ADREQ R2, TTXPalette_Mixed ; use a mixed palette for all other modes - MOVEQ R7, #&FF ; and they all have a transparent border, too - BLEQ SetTTXPalette - - Pull "PC" - -SetTTXPalette - Push "R14" - ; Set 1st flash states - MOV R0, #0 ; start at colour 0 - MOV R1, #16 ; program 16 colours - ORR R1, R1, #17:SHL:24 ; program 1st flash state - MOV R4, #paletteV_BulkWrite - BL CallPaletteV - ; Set 2nd flash states - MOV R0, #0 ; start at colour 0 - MOV R1, #16 ; program 16 colours - ORR R1, R1, #18:SHL:24 ; program 2nd flash state - MOV R4, #paletteV_BulkWrite - BL CallPaletteV - ; Set up the border colour - MOV R0, #0 ; logical colour 0 - MOV R1, #24 ; type 24 (border) - MOV R2, R7 ; palette entry passed in R7 - MOV R4, #paletteV_Set - BL CallPaletteV - Pull "PC" - -TTXPalette_Solid - & &00000000 ; black - & &0000FF00 ; red - & &00FF0000 ; green - & &00FFFF00 ; yellow - & &FF000000 ; blue - & &FF00FF00 ; magenta - & &FFFF0000 ; cyan - & &FFFFFF00 ; white -TTXPalette_Mixed - & &00000000 ; black - & &0000FF00 ; red - & &00FF0000 ; green - & &00FFFF00 ; yellow - & &FF000000 ; blue - & &FF00FF00 ; magenta - & &FFFF0000 ; cyan - & &FFFFFF00 ; white - & &000000FF ; transparent - & &0000FFFF ; transparent - & &00FF00FF ; transparent - & &00FFFFFF ; transparent - & &FF0000FF ; transparent - & &FF00FFFF ; transparent - & &FFFF00FF ; transparent - & &FFFFFFFF ; transparent - -; ***************************************************************************** -; -; Vdu23_18_1 - Suspend/resume bitmap updates -; - -Vdu23_18_1 ROUT - Push "R14" - LDRB R0, [WsPtr, #QQ+2] - LDR R1, [WsPtr, #TTXFlags] - TST R0, #1 ; bit 0 of 3rd parameter - BICEQ R2, R1, #TTXFlag_Suspend ; determines new setting of suspend flag - ORRNE R2, R1, #TTXFlag_Suspend - STR R2, [WsPtr, #TTXFlags] - BICS R14, R1, R2 ; if coming out of suspension - BLNE RefreshBitmap ; then redraw screen - Pull "PC" - -; ***************************************************************************** -; -; Vdu23_18_2 - Reveal/conceal -; - -Vdu23_18_2 ROUT - Push "R14" - LDRB R0, [WsPtr, #QQ+2] - LDR R1, [WsPtr, #TTXFlags] - TST R0, #1 ; bit 0 of 3rd parameter - ORREQ R1, R1, #TTXFlag_Conceal ; determines new setting of reveal flag - BICNE R1, R1, #TTXFlag_Conceal - STR R1, [WsPtr, #TTXFlags] - TST R1, #TTXFlag_Suspend ; unless suspended, - BLEQ RefreshBitmap ; redraw the screen - Pull "PC" - -; ***************************************************************************** -; -; Vdu23_18_3 - Enable/disable black foreground control codes -; - -Vdu23_18_3 ROUT - Push "R14" - LDRB R0, [WsPtr, #QQ+2] - LDR R1, [WsPtr, #TTXFlags] - TST R0, #1 ; bit 0 of 3rd parameter - BICEQ R2, R1, #TTXFlag_BlackEnable ; determines new setting of blackenable flag - ORRNE R2, R1, #TTXFlag_BlackEnable - EOR R1, R1, R2 - TST R1, #TTXFlag_BlackEnable ; has blackenable changed? - Pull "PC", EQ ; if not, then exit - - Push "R2" ; save R2 for later - ORR R2, R2, #TTXFlag_Suspend ; temporarily suspend bitmap update - STR R2, [WsPtr, #TTXFlags] - - MOV R0, #0 ; start at left - MOV R1, #0 ; start at top - ADRL R2, TTXLineStarts - LDR R2, [R2] ; R2 -> start of map - ADD R7, R2, #4*1 ; R7 -> map entry for first real char - ADD R5, R2, #4*40 ; R5 -> map entry for last char on first line - MOV R11, #0 ; R11 = top line - MOV R10, #25 ; R10 = bottom line + 1 - ADR R14, %FT50 - Push "R14" ; set up return address on stack - B TTXScanZap2 ; recalculate the map -50 - Pull "R2" ; retrieve the final TTXFlags - STR R2, [WsPtr, #TTXFlags] ; save them - TST R2, #TTXFlag_Suspend ; and unless we were suspended on entry - BLEQ RefreshBitmap ; then redraw the screen - Pull "PC" - -; ***************************************************************************** -; -; RefreshBitmap - Brings bitmap up-to-date with TTXMap -; - -RefreshBitmap ROUT - Push "R14" - MOV R0, #0 - MOV R1, #0 - BL AddressR0R1 ; R2 -> top-left character in bitmap - MOV R6, #0 ; R6 is line number: 0 <= R11 <= 24 - LDR R7, [WsPtr, #RowLength] - ADRL R8, TTXLineStarts -10 - LDR R4, [R8, R6, LSL #2] ; R4 -> map entry for magic 0th character - ADD R5, R4, #40*4 ; R5 -> last map entry on line -20 - LDR R1, [R4], #4 ; load map entry for previous character - LDR R0, [R4] ; load map entry for current character - BIC R1, R1, #&FF - AND R0, R0, #&FF - ORR R0, R1, R0 ; construct R0 and R1 as required by DoPreControl - AND R1, R0, #&7F - CMP R1, #&20 ; is it a control char - BLCC DoPreControl ; [do pre-control things] - BL UpdateHeldBits - BL TTXPaintChar ; paint it to the screen - [ TTX256 - ASSERT HiResTTX - ADD R2,R2, #16 - | - [ HiResTTX - ADD R2, R2, #8 - | - ADD R2, R2, #4 ; move to next char on same line - ] - ] - CMP R4, R5 - BCC %BT20 - [ TTX256 - ASSERT HiResTTX - SUB R2, R2, #640 - | - [ HiResTTX - SUB R2, R2, #320 - | - SUB R2, R2, #160 ; move back to start of this line - ] - ] - ADD R2, R2, R7 ; and drop down to start of next line - ADD R6, R6, #1 - CMP R6, #24 - BLS %BT10 - Pull "PC" - - [ HiResTTX -; ***************************************************************************** -; -; ComputeGraphic - Called on a character-by-character basis -; Generates a graphic character on the fly -; - -ComputeGraphic ROUT - Push "R1,mask,R10,R14" - ; R1 -> space to build character in - ; R3 = character: bits 0-4,6 are block flags, bit 5 is separated flag - ; mask (R4), R10, R14 corrupted - MOV mask, #&FF000000 - ORR mask, mask, mask, LSR #16 ; mask for setting left-hand blocks (shift for right-hand) - MOV R10, #&C0000000 - ORR R10, R10, R10, LSR #16 - ORR R10, R10, R10, LSR #8 ; mask for separated graphics vertical lines - - MOV R14, #0 ; holds each word of the character as we build it up - TST R3, #1:SHL:0 - ORRNE R14, R14, mask - TST R3, #1:SHL:1 - ORRNE R14, R14, mask, LSR #8 - TST R3, #1:SHL:5 - BICNE R14, R14, R10 - STR R14, [R1], #4 ; first 4 lines identical - STR R14, [R1], #4 - MOVNE R14, #0 ; if separated, then 2 horizontal lines, else same as above - STR R14, [R1], #4 - - MOV R14, #0 - TST R3, #1:SHL:2 - ORRNE R14, R14, mask - TST R3, #1:SHL:3 - ORRNE R14, R14, mask, LSR #8 - TST R3, #1:SHL:5 - BICNE R14, R14, R10 - STR R14, [R1], #4 ; 8 lines total for middle blocks - STR R14, [R1], #4 - STR R14, [R1], #4 - MOVNE R14, #0 - STR R14, [R1], #4 - - MOV R14, #0 - TST R3, #1:SHL:4 - ORRNE R14, R14, mask - TST R3, #1:SHL:6 - ORRNE R14, R14, mask, LSR #8 - TST R3, #1:SHL:5 - BICNE R14, R14, R10 - STR R14, [R1], #4 ; 6 lines total for bottom blocks - STR R14, [R1], #4 - MOVNE R14, #0 - STR R14, [R1], #4 - Pull "R1,mask,R10,PC" - ] - -; ***************************************************************************** -; -; TTXFastCLS - Called when clearing whole screen -; Clears the teletext map to default -; - -TTXFastCLS ROUT - ADD R0, WsPtr, #TTXMap ; R0 -> map - ADD R1, R0, #TTXMapSize-4 ; R1 -> last word of map - LDR R2, =MapBit_Default ; R2 = default status at start of line -10 - STR R2, [R0], #4 - CMP R0, R1 - BLS %BT10 - - ADD R0, WsPtr, #TTXDoubleCounts ; zero double counts on each line - ADD R1, R0, #25 - MOV R2, #0 -20 - STRB R2, [R0], #1 - TEQ R0, R1 - BNE %BT20 - - MOV PC, R14 - -; ***************************************************************************** -; -; TTXUpdateColours - Update colour table for new colours -; -; in: R5 = new foregd colour -; R6 = new backgd colour -; -; out: R0, R2 preserved -; - -TTXUpdateColours ROUT - Push "R0,R2,R14" - ADD R14, WsPtr, #TForeCol - STMIA R14, {R5,R6} - MOV fore, R5 - MOV back, R6 - LDR bpp, [WsPtr, #BitsPerPix] - BL SetColours - Pull "R0,R2,PC" - - [ :LNOT: HiResTTX -; ***************************************************************************** -; -; PrintDoubleHeight - Process font for double height -; -; in: R0 = char + attributes -; tophalf contains bytes 0123 -; bottomhalf contains bytes 4567 -; R10 contains bytes xx89 -; We know that at least one of MapBit_Bottom or MapBit_Double is set -; - -PrintDoubleHeight ROUT - TST R0, #MapBit_Double ; if not double height, - MOVEQ tophalf, #0 ; then must be single height - MOVEQ bottomhalf, #0 ; part on line below double, - MOVEQ R10, #0 ; so make it invisible - MOVEQ PC, R14 - - TST R0, #MapBit_Bottom - BNE %FT10 ; [bottom half of double] - - [ 1=1 ; 0 1 2 3 4 -; do top half, we want tophalf=0112, bottomhalf=2334, R10=xx45 - MOV R10, bottomhalf, LSL #16 ; R10 := o o 4 5 - ORR R10, R10, R10, LSL #8 ; R10 := o o 4 4/5 - AND R3, tophalf, #&FF000000 ; R3 := o o o 3 - ORR bottomhalf, R3, bottomhalf, LSL #24 ; bot := o o o 3/4 - MOV R3, tophalf, LSR #16 ; R3 := 2 3 o o - ORR R3, R3, R3, LSL #8 ; R3 := 2 2/3 3 o - ORR bottomhalf, bottomhalf, R3 ; bot := 2 2/3 3 3/4 - MOV tophalf, tophalf, LSL #16 ; top := o o 0 1 - ORR tophalf, tophalf, tophalf, LSR #8 ; top := o 0 0/1 1 - MOV tophalf, tophalf, LSR #8 ; top := 0 0/1 1 o - ORR tophalf, tophalf, bottomhalf, LSL #24 ; top := 0 0/1 1 2 - AND R3, tophalf, #&00FF0000 ; R3 := o o 1 o - ORR tophalf, tophalf, R3, LSL #8 ; top := 0 0/1 1 1/2 - MOV PC, R14 - -10 ; 5 6 7 8 9 -; do bottom half, we want tophalf=5667, bottomhalf=7889, R10=xx9o - AND tophalf, bottomhalf, #&FF000000 ; top := o o o 7 - MOV R3, bottomhalf, LSL #8 ; R3 := o 4 5 6 - MOV R3, R3, LSR #16 ; R3 := 5 6 o o - ORR tophalf, tophalf, R3 ; top := 5 6 o 7 - ORR tophalf, tophalf, R3, LSL #8 ; top := 5 5/6 6 7 - AND R3, R3, #&0000FF00 ; R3 := o 6 o o - ORR tophalf, tophalf, R3, LSL #16 ; top := 5 5/6 6 6/7 - MOV bottomhalf, bottomhalf, LSR #24 ; bot := 7 o o o - AND R3, R10, #&00FF0000 ; R3 := o o 8 o - ORR bottomhalf, bottomhalf, R3, LSR #8 ; bot := 7 8 o o - ORR bottomhalf, bottomhalf, bottomhalf, LSL #8 ; bot := 7 7/8 8 o - ORR R3, R10, R10, LSL #8 ; R3 := x x x 8/9 - AND R3, R3, #&FF000000 ; R3 := o o o 8/9 - ORR bottomhalf, bottomhalf, R3 ; bot := 7 7/8 8 8/9 - MOV R10, R10, LSR #24 ; R10 := 9 o o o - ORR R10, R10, R10, LSL #8 ; R10 := 9 9 o o - MOV R10, R10, LSL #16 ; R10 := o o 9 9 - MOV PC, R14 - | -; do top half, we want tophalf=0011, bottomhalf=2233, R10=xx44 - - MOV R10, bottomhalf, LSL #24 ; R10 := ooo4 - ORR R10, R10, R10, LSR #8 ; R10 := oo44 - AND bottomhalf, tophalf, #&00FF0000 ; bottom := oo2o - ORR bottomhalf, bottomhalf, tophalf, LSR #24 ; bottom := 3o2o - ORR bottomhalf, bottomhalf, bottomhalf, LSL #8 ; bottom := 3322 - MOV bottomhalf, bottomhalf, ROR #16 ; bottom := 2233 - AND R3, tophalf, #&0000FF00 ; R3 := o1oo - AND tophalf, tophalf, #&FF ; top := 0ooo - ORR tophalf, tophalf, R3, LSL #8 ; top := 0o1o - ORR tophalf, tophalf, tophalf, LSL #8 ; top := 0011 - MOV PC, R14 - -; do bottom half, we want tophalf=5566, bottomhalf=7788, R10=xx99 - -10 - AND tophalf, bottomhalf, #&0000FF00 ; top := o5oo - MOV bottomhalf, bottomhalf, LSR #16 ; bot := 67oo - ORR tophalf, tophalf, bottomhalf, LSL #24 ; top := o5o6 - ORR tophalf, tophalf, tophalf, LSR #8 ; top := 5566 - MOV bottomhalf, bottomhalf, LSR #8 ; bot := 7ooo - MOV R10, R10, LSR #16 ; R10 := 89oo - ORR bottomhalf, bottomhalf, R10, LSL #16 ; bot := 7o89 - BIC bottomhalf, bottomhalf, #&FF000000 ; bot := 7o8o - ORR bottomhalf, bottomhalf, bottomhalf, LSL #8 ; bot := 7788 - BIC R10, R10, #&FF ; R10 := o9oo - ORR R10, R10, R10, LSR #8 ; R10 := 99oo - MOV R10, R10, LSL #16 ; R10 := oo99 - MOV PC, R14 - ] - ] - -; ***************************************************************************** -; -; TTXWrch - Print a character in the range &20-&FF -; -; in: R0 = character -; out: cursor has been moved on if appropriate -; - -TTXWrch ROUT - Push R14 - BL TTXDoChar - Pull R14 - B PostCharMove - -; ***************************************************************************** -; -; TTXDoChar - Print a character (don't move cursor) -; -; in: R0 = character -; - -TTXDoChar ROUT - Push R14 - - MOV R3, R0 - TEQ R3, #"#" ; swap around the three - MOVEQ R0, #"_" ; old favourites - TEQ R3, #"_" - MOVEQ R0, #"`" - TEQ R3, #"`" - MOVEQ R0, #"#" - - LDR R11, [WsPtr, #CursorY] ; R11 = current Y position - LDR R3, [WsPtr, #CursorX] ; R3=start X posn on this line - LDR R2, [WsPtr, #CursorAddr] ; screen address -TTXScanFromHere - MOV R4, #0 ; Xmin and - MOV R5, #0 ; Xmax are irrelevant - MOV R10, #0 ; Ymax always <= Y so no zap -TTXScanZap - ADRL R1, TTXLineStarts ; R1 -> table of line starts - LDR R8, [R1, R11, LSL #2] ; R8 -> map entry at st.of line - ADD R7, R8, #40*4 ; R7 -> end of this line - LDR R1, [R8, R3, LSL #2]! ; R1 = prev. char+attr -08 - ADD R3, WsPtr, #TTXDoubleCounts - LDRB R9, [R3, R11] ; R9 = no. of dbls on this line -10 - BIC R1, R1, #&FF ; clear char bits - ORR R0, R1, R0 ; store new char - AND R1, R0, #&7F ; just look at char bits - - Push R14 - CMP R1, #&20 ; is it a control char - BLCC DoPreControl ; [do pre-control things] - - BL UpdateHeldBits ; this needs doing irrespective of suspension - LDR R14, [WsPtr, #TTXFlags] - TST R14, #TTXFlag_Suspend - BLEQ TTXPaintChar - - BIC R0, R0, #(MapBit_PendingStart :OR: MapBit_PendingEnd) - - CMP R1, #&20 - BLCC DoPostControl ; [do post-control things] - Pull R14 ; restore zap flag - - LDR R1, [R8, #4]! ; get old character - STR R0, [R8] ; store character away - - AND R3, R1, #&7F ; if overwriting double height - TEQ R3, #TTX_DoubleHeight - SUBEQ R9, R9, #1 ; then one less - - EOR R1, R0, R1 ; get difference - BIC R3, R1, #&FF ; difference in attributes - MOV R1, R0 ; R1 = prev char + new attr - - CMP R11, R10 ; if Y >= Ymax - BCS %FT20 ; then load from map - CMPCC R8, R5 ; else if X <= Xmax - MOVLS R3, #1 ; then pretend attr different - CMPCC R4, R8 ; if Xmin < X < Xmax - CMPCC R14, #1 ; and we're zapping (not scan) - MOVCC R0, #32 ; then zap to space -20 - LDRCSB R0, [R8, #4] ; else load from map - - TEQ R3, #0 ; if attributes different - TEQNE R8, R7 ; and not at end of line - [ TTX256 - ASSERT HiResTTX - ADDNE R2, R2, #16 - | - [ HiResTTX - ADDNE R2, R2, #8 - | - ADDNE R2, R2, #4 ; then move to next char - ] - ] - BNE %BT10 ; and loop - - ADD R3, WsPtr, #TTXDoubleCounts - STRB R9, [R3, R11] ; update no. of doubles - - ADD R11, R11, #1 ; go to next line - TEQ R11, #25 ; if off bottom of screen - Pull PC, EQ ; then finished - - MOVS R3, R9 ; if no doubles - ; then next line is top line - EORNE R3, R1, #MapBit_Bottom ; else next line is opposite - ; to this line - - LDR R1, [R7, #4] ; get dummy word on next line - EOR R3, R1, R3 ; difference - ANDS R3, R3, #MapBit_Bottom ; difference in 'bottom' bit - EORNE R1, R1, #MapBit_Bottom ; if different then toggle bit - STR R1, [R7, #4]! ; always store back - BNE %FT30 ; and do another row - - CMP R11, R10 ; else if finished zap - Pull PC, CS ; then exit -30 - -; now compute new R2 - - SUB R3, R7, R8 ; (no. of chars before eol) * 4 - RSB R3, R3, #160 ; (current char number) * 4 - [ TTX256 - ASSERT HiResTTX - SUB R2, R2, R3, LSL #2 ; back to start of old line - | - [ HiResTTX - SUB R2, R2, R3, LSL #1 ; back to start of old line - | - SUB R2, R2, R3 ; back to start of old line - ] - ] - LDR R3, [WsPtr, #RowLength] - ADD R2, R2, R3 ; move down a row - - MOV R8, R7 ; R8 -> dummy char on new line - ADD R7, R7, #40*4 ; R7 -> last char on new line - - ADD R4, R4, #41*4 ; move Xmin to next line - ADD R5, R5, #41*4 ; move Xmax to next line - - CMP R11, R10 ; if Y < Ymax - CMPCC R8, R5 ; and X < Xmax - CMPCC R4, R8 ; if also Xmin < X - CMPCC R14, #1 ; & we're zapping not scanning - MOVCC R0, #32 ; then zap to space - LDRCSB R0, [R8, #4] ; else load from map - B %BT08 - -; ***************************************************************************** -; -; TTXClearBox - Fill a rectangle with spaces, and update screen -; -; in: R0 = left column -; R1 = bottom row -; R2 = right column -; R3 = top row -; Return address already stacked -; - -TTXClearBox - ADD R10, R1, #1 ; R10 := bottom +1 - MOV R11, R3 ; R11 := top - ADD R5, R2, #1 ; R5 := right + 1 - - MOV R1, R3 - BL AddressR0R1 ; R2 := address(topleft) - ; R1, R3, R4 corrupted - MOV R3, R0 ; R3 := left - - ADRL R4, TTXLineStarts - LDR R0, [R4, R11, LSL #2] ; R0 -> dummy(top) - ADD R5, R0, R5, LSL #2 ; R5 := map(topright) - ADD R4, R0, R3, LSL #2 ; R4 := map(topleft)-4 - SUB R4, R4, #4 ; R4 := map(topleft)-8 - MOV R0, #32 ; start with a space - MOV R14, #0 ; indicate zapping - B TTXScanZap ; go and do it - -; ***************************************************************************** -; -; TTXHardScrollUp - Scroll teletext screen upwards -; - -TTXHardScrollUp ROUT - -; first scroll map up - - LDR R0, [WsPtr, #RowLength] ; save real RowLength - Push "R0, R6, R14" ; and save CursorFlags - - MOV R0, #1 ; pretend rowmult = 1 - LDR R2, TTXLineStarts ; R2 -> TTXMap - MOV R5, #41*4 ; R5 = no. of bytes horiz - STR R5, [WsPtr, #RowLength] ; pretend rowlength - MOV R6, #25 ; no. of 'pixel' rows - MOV R7, R5 ; linelength - BL SoftScrollUp2 - - Pull "R0, R6" - STR R0, [WsPtr, #RowLength] ; restore RowLength - -; now 'scroll' DoubleCounts - - ADD R0, WsPtr, #TTXDoubleCounts - ADD R1, R0, #24 -10 - LDRB R2, [R0, #1] - STRB R2, [R0], #1 - TEQ R0, R1 - BNE %BT10 - -; now see if top line was a 'bottom' row -; if so, we need to rescan from the top - - LDR R8, TTXLineStarts ; R8 -> top left map - LDR R1, [R8] ; R1 = dummy word - TST R1, #MapBit_Bottom ; if not bottom - BEQ %FT20 ; then OK - - BIC R1, R1, #MapBit_Bottom ; make into a 'top' line - STR R1, [R8] ; store back - LDRB R0, [R8, #4] ; R0 = first char - MOV R3, #0 ; X = 0 - MOV R11, #0 ; Y = 0 - LDR R2, [WsPtr, #ScreenStart] ; screen address for top-left - - ADR R14, %FT20 - Push R14 - B TTXScanFromHere - -20 - -; now see if new bottom line should be a 'bottom' or a 'top' line - - ADRL R0, TTXLineStarts - LDR R0, [R0, #23*4] ; R0 -> dummy word on line 23 - LDRB R1, [WsPtr, #TTXDoubleCounts+23] ; no. of dbls on line 23 - TEQ R1, #0 ; if R1=0 then line 24 is 'top' - LDRNE R1, [R0] ; else line 24 is opposite - EORNE R1, R1, #MapBit_Bottom ; of line 23 - ANDNE R1, R1, #MapBit_Bottom - LDR R2, [R0, #41*4] ; R2 = dummy word on line 24 - BIC R2, R2, #MapBit_Bottom ; clear that bit - ORR R2, R2, R1 ; OR in new bit - STR R2, [R0, #41*4] ; and store back - - Pull PC - -; ***************************************************************************** -; -; TTXSoftScrollUp - Scroll screen up by software in teletext mode -; - -TTXSoftScrollUp ROUT - -; first scroll map up - - LDR R0, [WsPtr, #RowLength] ; save real RowLength - LDR R1, [WsPtr, #TWTRow] ; top row - LDR R3, [WsPtr, #TWBRow] ; bottom row - - ADRL R2, TTXLineStarts - LDR R2, [R2, R1, LSL #2] ; R2 -> dummy char top row - ADD R2, R2, #4 ; R2 -> 0th char top row - LDR R4, [WsPtr, #TWLCol] - LDR R5, [WsPtr, #TWRCol] - - Push "R0-R6,R14" ; and save CursorFlags - - ADD R2, R2, R4, LSL #2 ; R2 -> top left char - - SUB R5, R5, R4 - ADD R5, R5, #1 ; R5 = no. of chars wide - MOV R5, R5, LSL #2 ; R5 = no. of bytes / line - - SUB R6, R3, R1 - ADD R6, R6, #1 ; R6 = no. of 'pixel' rows - - MOV R7, #41*4 ; R7 = line length - STR R7, [WsPtr, #RowLength] ; pretend row length - MOV R0, #1 ; pretend rowmult =1 - - BL SoftScrollUp2 - - Pull "R0-R6" - STR R0, [WsPtr, #RowLength] ; restore RowLength - -; now R1=top row, R2 -> char 0 on row R1, R3=bottom row, R4=left, R5=right - -; now clear bottom row - - ADRL R7, TTXLineStarts - LDR R7, [R7, R3, LSL #2] ; R7 -> dummy word(bottom) - ADD R8, R7, R5, LSL #2 ; R8 -> char before bottom rt - ADD R7, R7, R4, LSL #2 ; R7 -> char before bottom left - MOV R0, #32 -30 - STRB R0, [R7, #4]! ; zap to space - CMP R7, R8 ; if <= char before bottom rt - BLS %BT30 ; then loop - - MOV R9, R2 -CountAndRescan - BL CountDoubles - -; now rescan from top of window - - ADD R10, R3, #1 ; R10 = bottom + 1 - MOV R11, R1 ; R11 = top - ADD R7, R2, R4, LSL #2 ; R7 = map(left,top) - ADD R5, R2, R5, LSL #2 ; R5 = map(right,top) - MOV R0, R4 ; R0 = left -TTXScanZap2 - BL AddressR0R1 ; R2 = screen(left,top) - ; (R1,R3,R4 corrupted) - SUB R4, R7, #8 ; R4 = map(left,top)-8 - MOV R3, R0 ; R3 = left - LDRB R0, [R4, #8] ; R0 = first char - MOV R14, #1 ; scan not zap - B TTXScanZap - -; ***************************************************************************** -; -; CountDoubles - Count double height characters in a range of rows -; -; in: R1 = top row to count -; R3 = bottom row to count -; R9 -> map(0,top) -; -; out: R1-R6 preserved -; - -CountDoubles ROUT - ADD R7, WsPtr, #TTXDoubleCounts - ADD R7, R7, R1 ; R7 -> current double count - MOV R11, R1 -10 - ADD R8, R9, #40*4 ; R8 -> dummy char next row - MOV R10, #0 ; count so far -20 - LDR R0, [R9], #4 ; load char word - AND R0, R0, #&7F ; only look at bottom 7 bits - TEQ R0, #TTX_DoubleHeight ; if double height - ADDEQ R10, R10, #1 ; then increment count - TEQ R9, R8 ; if not at end of row - BNE %BT20 ; then loop - - STRB R10, [R7], #1 ; store double count - ADD R9, R9, #4 ; skip dummy char - ADD R11, R11, #1 ; goto next row - CMP R11, R3 ; if <= bottom - BLS %BT10 ; then loop - - MOV PC, R14 - -; ***************************************************************************** -; -; TTXHardScrollDown - Scroll teletext screen downwards -; - -TTXHardScrollDown ROUT - -; first scroll map down - - LDR R0, [WsPtr, #RowLength] ; save real RowLength - Push "R0, R6, R14" ; and save CursorFlags - - MOV R0, #1 ; pretend rowmult = 1 - LDR R2, TTXLineStarts+24*4 ; R2 -> dummy char on bottom - MOV R5, #41*4 ; R5 = no. of bytes horiz - STR R5, [WsPtr, #RowLength] ; pretend rowlength - MOV R6, #25 ; no. of 'pixel' rows - MOV R7, R5 ; linelength - BL SoftScrollDown2 - - Pull "R0, R6" - STR R0, [WsPtr, #RowLength] ; restore RowLength - -; now 'scroll' DoubleCounts - - ADD R0, WsPtr, #TTXDoubleCounts - ADD R1, R0, #24 -10 - LDRB R2, [R1, #-1] - STRB R2, [R1], #-1 - TEQ R1, R0 - BNE %BT10 - -; now make top row a 'top' row - - LDR R0, TTXLineStarts ; R0 -> top line dummy word - LDR R1, [R0] ; R1 = dummy word - BIC R1, R1, #MapBit_Bottom ; clear 'bottom' bit - STR R1, [R0] ; and store back - - Pull PC - -; ***************************************************************************** -; -; TTXSoftScrollDown - Scroll screen down by software in teletext mode -; - -TTXSoftScrollDown ROUT - -; first scroll map down - - LDR R0, [WsPtr, #RowLength] ; save real RowLength - LDR R1, [WsPtr, #TWTRow] ; top row - LDR R3, [WsPtr, #TWBRow] ; bottom row - - ADR R2, TTXLineStarts - LDR R2, [R2, R3, LSL #2] ; R2 -> dummy char bottom row - ADD R2, R2, #4 ; R2 -> 0th char bottom row - LDR R4, [WsPtr, #TWLCol] - LDR R5, [WsPtr, #TWRCol] - - Push "R0-R6,R14" ; and save CursorFlags - - ADD R2, R2, R4, LSL #2 ; R2 -> bottom left char - - SUB R5, R5, R4 - ADD R5, R5, #1 ; R5 = no. of chars wide - MOV R5, R5, LSL #2 ; R5 = no. of bytes / line - - SUB R6, R3, R1 - ADD R6, R6, #1 ; R6 = no. of 'pixel' rows - - MOV R7, #41*4 ; R7 = line length - STR R7, [WsPtr, #RowLength] ; pretend row length - MOV R0, #1 ; pretend rowmult =1 - - BL SoftScrollDown2 - - Pull "R0-R6" - STR R0, [WsPtr, #RowLength] ; restore RowLength - -; now R1=top row, R2 -> char 0 on row R3, R3=bottom row, R4=left, R5=right - -; now clear top row - - ADR R7, TTXLineStarts - LDR R7, [R7, R1, LSL #2] ; R7 -> dummy word(top) - ADD R8, R7, R5, LSL #2 ; R8 -> char before top rt - ADD R7, R7, R4, LSL #2 ; R7 -> char before top left - MOV R0, #32 -30 - STRB R0, [R7, #4]! ; zap to space - CMP R7, R8 ; if <= char before bottom rt - BLS %BT30 ; then loop - - SUB R9, R8, R5, LSL #2 ; R9 -> dummy word(top) - ADD R9, R9, #4 ; R9 -> map(0,top) - MOV R2, R9 - B CountAndRescan ; count doubles and rescan - ; from top of window - -; ***************************************************************************** -; -; TTXScrollLeft - Scroll left (by software) in Teletext mode -; -; in: R0 bit0=0 => scroll window -; 1 => scroll screen -; - -TTXScrollLeft ROUT - Push R14 - BL TTXSideScroll1 - MOV R5, R0 ; R5 = left = column to check - ; for double height chars - BL TTXSideScroll2 ; do second part - BL ScrollLeft2 - -; now store spaces in right hand column - - Pull "R0-R3, R6, R9" - ADD R4, R9, R2, LSL #2 ; R4 -> map(right,top) -TTXSideScroll3 - MOV R7, R3 ; R7 = current row - MOV R8, #32 ; poke spaces -20 - STRB R8, [R4], #41*4 ; store space and move down - ADD R7, R7, #1 ; next row - CMP R7, R1 ; if row <= bottom - BLS %BT20 ; then loop - -; now rescan from top of window/screen - - ADD R10, R1, #1 ; R10 = bottom+1 - MOV R11, R3 ; R11 = top - ADD R7, R9, R0, LSL #2 ; R7 -> map(left,top) - ADD R5, R9, R2, LSL #2 ; R5 -> map(right,top) - MOV R1, R3 ; R1 = top - B TTXScanZap2 - -; ***************************************************************************** -; -; TTXScrollRight - Scroll right (by software) in Teletext mode -; -; in: R0 bit0=0 => scroll window -; 1 => scroll screen -; - -TTXScrollRight ROUT - Push R14 - BL TTXSideScroll1 - MOV R5, R2 ; R5 = right = column to check - ; for double height chars - BL TTXSideScroll2 - BL ScrollRight2 - -; now store spaces in left hand column - - Pull "R0-R3, R6, R9" - ADD R4, R9, R0, LSL #2 ; R4 -> map(left,top) - B TTXSideScroll3 - -; ***************************************************************************** -; -; TTXSideScroll1 - Do first part of sideways scroll -; - -TTXSideScroll1 ROUT - MOVS R0, R0, LSR #1 - -; C=0 => scroll window - - ADDCC R0, WsPtr, #TWLCol ; R0 = left, R1 = bottom - LDMCCIA R0, {R0-R3} ; R2 = right, R3 = top - -; C=1 => scroll screen - - MOVCS R0, #0 ; left - LDRCS R1, [WsPtr, #ScrBRow] ; bottom - LDRCS R2, [WsPtr, #ScrRCol] ; right - MOVCS R3, #0 ; top - - MOV PC, R14 - -; ***************************************************************************** -; -; TTXSideScroll2 - Do second part of sideways scroll -; -; in: R5 = left or right hand column for left or right scroll respectively -; - -TTXSideScroll2 ROUT - -; first check char R5 on each line and decrement double count if a double - - ADR R4, TTXLineStarts - LDR R4, [R4, R3, LSL #2] ; R4 -> map(dummy,top) - ADD R9, R4, #4 ; R9 -> map(0,top) - ADD R4, R9, R5, LSL #2 ; R4 -> map(left or right,top) - - ADD R5, WsPtr, #TTXDoubleCounts - MOV R7, R3 ; R7 = current row -10 - LDR R8, [R4], #41*4 ; get char+attr - AND R8, R8, #&7F - TEQ R8, #TTX_DoubleHeight ; test if double height char - - LDREQB R8, [R5, R7] ; if so then load double count - SUBEQ R8, R8, #1 ; decrement it - STREQB R8, [R5, R7] ; and store back - - ADD R7, R7, #1 ; next row - CMP R7, R1 ; if row <= bottom - BLS %BT10 ; then loop - -; now scroll map - - Push "R0-R3, R6, R9" - SUB R5, R2, R0 ; R5 = right-left - ADD R5, R5, #1 ; R5 = right-left+1 - MOV R5, R5, LSL #2 ; R5 = (right-left+1)*4 - ADD R2, R9, R0, LSL #2 ; R2 -> map(left,top) - SUB R6, R1, R3 ; R6 = bottom-top - ADD R6, R6, #1 ; R6 = bottom-top+1 - MOV R7, #41*4 ; linelength - MOV R9, #4 ; no. of bytes to scroll by - - MOV PC, R14 - -; ***************************************************************************** -; -; UpdateHeldBits - change the held graphic bits of R0 if necessary -; TTXPaintChar used to have this functionality -; - -UpdateHeldBits ROUT - TST R0, #&60 :OR: MapBit_Hold ; if a control code and not holding, - BICEQ R0, R0, #MapBit_HeldMask ; clear mask - MOVEQ PC, R14 - - TST R0, #MapBit_Graph - TSTNE R0, #&20 ; if not a graphic character, - MOVEQ PC, R14 ; preserve the bits that were copied from the previous character - - BIC R0, R0, #MapBit_HeldMask ; else copy the character to the held graphic bits - ORR R0, R0, R0, LSL #MapHeldShift - TST R0, #MapBit_Separated - BICEQ R0, R0, #MapBit_HeldSeparated - ORRNE R0, R0, #MapBit_HeldSeparated - MOV PC, R14 - -; ***************************************************************************** -; -; TTXPaintChar - Paint char according to attributes -; -; in: R0 = character + attributes word -; R2 -> screen (for the time being) -; -; out: R0,R2 preserved - -TTXPaintChar ROUT - Entry "R1,R4-R11" - VDWS WsPtr ; for now - -; first set up the colours - - ADD R1, WsPtr, #TForeCol - LDMIA R1, {R1, R3} ; R1 = TForeCol; R3 = TBackCol - MOV R4, #&0F - LDR R14, [WsPtr, #TTXFlags] - BIC R5, R0, R14 ; apply BIC masks - EOR R14, R5, R14, LSL #8 ; apply EOR masks - AND R5, R4, R14, LSR #MapForeShift ; R5 = new foregd colour - AND R6, R4, R14, LSR #MapBackShift ; R6 = new backgd colour - - TEQ R1, R5 ; if foregd different - TEQEQ R3, R6 ; or backgd different - BLNE TTXUpdateColours ; then update colour table - - [ HiResTTX - ADR R1, TTXHardFont-32*40 ; R1 -> base for font - | - ADR R1, TTXHardFont-32*10 ; R1 -> base for font - ] - MOVS R3, R0, LSL #26 ; C := bit6, N := bit5 - AND R3, R0, #&7F ; R3 = char - BMI %FT10 ; [&20-&3F or &60-&7F] - BCS %FT20 ; [&40-&5F (definitely Alpha)] - -; control code, so display as space or held graphic - - TST R0, #MapBit_Hold ; zero if not holding - MOVEQ R3, #&20 ; pretend to be space - BEQ %FT20 ; [display as space] - -; next instruction assumes no valid bits above held graphic bits - - MOV R3, R0, LSR #MapHeldShift ; R3 = char to display - B %FT30 ; [display as held graphic] - -; char in range &20-&3F or &60-&7F, so check for alpha/graphics - -10 - TST R0, #MapBit_Graph ; in graphics mode - BEQ %FT20 ; [no, so definitely Alpha] - TST R0, #MapBit_Separated ; separated graphics ? - BICEQ R3, R3, #&20 ; no, then make &00-&1F,&40-&5F -30 - ADD R1, WsPtr, #TTXSoftFonts - [ HiResTTX - TST R3, #&5F ; if a space - ADREQ R1, TTXHardFont ; then just use the hard font, for speed - BLNE ComputeGraphic ; else generate the bitmap - B %FT40 -20 - ADD R1, R1, R3, LSL #5 ; add 32*char - ADD R1, R1, R3, LSL #3 ; add 8*char -40 - | -20 - ADD R1, R1, R3, LSL #3 ; add 8*char - ADD R1, R1, R3, LSL #1 ; add 2*char - ] - - TST R0, #MapBit_Conceal ; concealing ? - LDRNE R14, [WsPtr, #TTXFlags] - TSTNE R14, #TTXFlag_Conceal ; and reveal is off? - ADRNE R1, TTXHardFont ; yes, then display as space - - [ :LNOT: HiResTTX -; now load font bytes -; 0..3 into tophalf -; 4..7 into bottomhalf -; 8..9 into R10 (top 2 bytes) - - TST R1, #2 ; starting on a word bdy ? - - SUBNE R1, R1, #2 ; if not, move back - LDMIA R1, {tophalf, bottomhalf, R10} ; yes, so load all 3 up - MOVEQ R10, R10, LSL #16 - MOVNE tophalf, tophalf, LSR #16 - ORRNE tophalf, tophalf, bottomhalf, LSL #16 - MOVNE bottomhalf, bottomhalf, LSR #16 - ORRNE bottomhalf, bottomhalf, R10, LSL #16 - - TST R0, #(MapBit_Bottom :OR: MapBit_Double) - BLNE PrintDoubleHeight - - LDR bigfont, [WsPtr, #TextExpandArea] - MOV mask, #&FF000000 - LDR linelen, [WsPtr, #LineLength] - Push "R0, screen" - MOV R0, #0 ; indicate 10 rows - BL Wrch4bitTTX ; do 1st bank - - LDMFD R13, {R0, screen} ; restore char + scr. addr - ADD screen, screen, #40*1024 - TST R0, #MapBit_Flash - MOVNE mask, #0 ; flash => 2nd bank is space - MOV R0, #0 - BL Wrch4bitTTX - Pull "R0, screen" - EXIT - | -; here we do the two screen banks in an outer loop and have a -; 5-stage inner loop each time plotting 4 rows (1/5th of the character) - - TST R0, #MapBit_Bottom ; for bottom-half characters - ADDNE R1, R1, #2*10 ; start half-way through the character - - LDR bigfont, [WsPtr, #TextExpandArea] - - MOV mask, #&FF000000 - LDR linelen, [WsPtr, #LineLength] - [ TTX256 - SUB linelen, linelen, #8 ; adjust line offset to account for writing 2 words/line - Push "R1, screen" - BL Wrch8bitTTX ; do 1st bank - - LDMFD R13, {R1, screen} ; restore pointers to character and screen address - ADD screen, screen, #320*1024 ; point to 2nd bank - TST R0, #MapBit_Flash - MOVNE mask, #0 ; flash => 2nd bank is space - BL Wrch8bitTTX ; do 2nd bank - - Pull "R1, screen" - | - SUB linelen, linelen, #4 ; adjust line offset to account for writing 2 words/line - Push "R1, screen" - BL Wrch4bitTTX ; do 1st bank - - LDMFD R13, {R1, screen} ; restore pointers to character and screen address - ADD screen, screen, #160*1024 ; point to 2nd bank - TST R0, #MapBit_Flash - MOVNE mask, #0 ; flash => 2nd bank is space - BL Wrch4bitTTX ; do 2nd bank - - Pull "R1, screen" - ] - EXIT - - [ TTX256 -Wrch8bitTTX ROUT - | -Wrch4bitTTX ROUT - ] - MOV R7, #4 ; do each plot in 5 stages; R7 holds stage number -01 TST R0, #MapBit_Double - LDMEQIA R1!, {tophalf, bottomhalf} ; single height characters, load 4 rows - LDRNE tophalf, [R1], #4 ; double height characters, load 2 rows - MOVNE bottomhalf, tophalf, LSR #16 ; and double up - ORRNE bottomhalf, bottomhalf, bottomhalf, LSL #16 - MOVNE tophalf, tophalf, LSL #16 - ORRNE tophalf, tophalf, tophalf, LSR #16 - AND byte, R0, #(MapBit_Double :OR: MapBit_Bottom) ; byte is used here as a scratch register - TEQ byte, #MapBit_Bottom ; if single height on line below top-half double height, - MOVEQ tophalf, #0 ; make it invisible - MOVEQ bottomhalf, #0 - - [ TTX256 - AND byte, mask, tophalf, LSL #16 - ADD byte, bigfont, byte, LSR #21 - LDMIA byte, {scrbyte, scrbyte2} - STMIA screen!, {scrbyte, scrbyte2} - AND byte, mask, tophalf, LSL #24 - ADD byte, bigfont, byte, LSR #21 - LDMIA byte, {scrbyte, scrbyte2} - STMIA screen, {scrbyte, scrbyte2} - ADD screen, screen, linelen - AND byte, mask, tophalf - ADD byte, bigfont, byte, LSR #21 - LDMIA byte, {scrbyte, scrbyte2} - STMIA screen!, {scrbyte, scrbyte2} - AND byte, mask, tophalf, LSL #8 - ADD byte, bigfont, byte, LSR #21 - LDMIA byte, {scrbyte, scrbyte2} - STMIA screen, {scrbyte, scrbyte2} - ADD screen, screen, linelen - - AND byte, mask, bottomhalf, LSL #16 - ADD byte, bigfont, byte, LSR #21 - LDMIA byte, {scrbyte, scrbyte2} - STMIA screen!, {scrbyte, scrbyte2} - AND byte, mask, bottomhalf, LSL #24 - ADD byte, bigfont, byte, LSR #21 - LDMIA byte, {scrbyte, scrbyte2} - STMIA screen, {scrbyte, scrbyte2} - ADD screen, screen, linelen - AND byte, mask, bottomhalf - ADD byte, bigfont, byte, LSR #21 - LDMIA byte, {scrbyte, scrbyte2} - STMIA screen!, {scrbyte, scrbyte2} - AND byte, mask, bottomhalf, LSL #8 - ADD byte, bigfont, byte, LSR #21 - LDMIA byte, {scrbyte, scrbyte2} - STMIA screen, {scrbyte, scrbyte2} - ADD screen, screen, linelen - | - AND byte, mask, tophalf, LSL #16 - LDR scrbyte, [bigfont, byte, LSR #22] - STR scrbyte, [screen], #4 - AND byte, mask, tophalf, LSL #24 - LDR scrbyte, [bigfont, byte, LSR #22] - STR scrbyte, [screen], linelen - AND byte, mask, tophalf - LDR scrbyte, [bigfont, byte, LSR #22] - STR scrbyte, [screen], #4 - AND byte, mask, tophalf, LSL #8 - LDR scrbyte, [bigfont, byte, LSR #22] - STR scrbyte, [screen], linelen - - AND byte, mask, bottomhalf, LSL #16 - LDR scrbyte, [bigfont, byte, LSR #22] - STR scrbyte, [screen], #4 - AND byte, mask, bottomhalf, LSL #24 - LDR scrbyte, [bigfont, byte, LSR #22] - STR scrbyte, [screen], linelen - AND byte, mask, bottomhalf - LDR scrbyte, [bigfont, byte, LSR #22] - STR scrbyte, [screen], #4 - AND byte, mask, bottomhalf, LSL #8 - LDR scrbyte, [bigfont, byte, LSR #22] - STR scrbyte, [screen], linelen - ] - - SUBS R7, R7, #1 - BPL %BT01 - MOV PC, R14 - ] - -; ***************************************************************************** - -TTXLineStarts - GBLA lineno -lineno SETA 0 - WHILE lineno < 25 - & VduDriverWorkSpace+TTXMap+4*41*lineno -lineno SETA lineno +1 - WEND - - LTORG - -; ***************************************************************************** -; -; DoPreControl - Process 'at' action of control char -; DoPostControl - Process 'after' action of control char -; -; in: R0 = new char + attributes of current previous char -; R1 = new char AND &7F -; (0 <= R1 <= 31) -; - -DoPreControl ROUT - ADD PC, PC, R1, LSL #3 -DoPostControl ROUT - ADD PC, PC, R1, LSL #3 - MOV PC, R14 ; &00 Pre - B DoAlphaBlack ; &00 Post - MOV PC, R14 ; &01 Pre - B DoAlphaColour ; &01 Post - MOV PC, R14 ; &02 Pre - B DoAlphaColour ; &02 Post - MOV PC, R14 ; &03 Pre - B DoAlphaColour ; &03 Post - MOV PC, R14 ; &04 Pre - B DoAlphaColour ; &04 Post - MOV PC, R14 ; &05 Pre - B DoAlphaColour ; &05 Post - MOV PC, R14 ; &06 Pre - B DoAlphaColour ; &06 Post - MOV PC, R14 ; &07 Pre - B DoAlphaColour ; &07 Post - MOV PC, R14 ; &08 Pre - B DoFlash ; &08 Post - BIC R0, R0, #MapBit_Flash ; &09 Pre ; clear flash mode - MOV PC, R14 ; &09 Post - B DoPreEndBox ; &0A Pre - B DoPostEndBox ; &0A Post - B DoPreStartBox ; &0B Pre - B DoPostStartBox ; &0B Post - B DoSingleHeight ; &0C Pre - MOV PC, R14 ; &0C Post - B DoDoubleHeight ; &0D Pre - MOV PC, R14 ; &0D Post - MOV PC, R14 ; &0E Pre - MOV PC, R14 ; &0E Post - MOV PC, R14 ; &0F Pre - MOV PC, R14 ; &0F Post - MOV PC, R14 ; &10 Pre - B DoGraphBlack ; &10 Post - MOV PC, R14 ; &11 Pre - B DoGraphColour ; &11 Post - MOV PC, R14 ; &12 Pre - B DoGraphColour ; &12 Post - MOV PC, R14 ; &13 Pre - B DoGraphColour ; &13 Post - MOV PC, R14 ; &14 Pre - B DoGraphColour ; &14 Post - MOV PC, R14 ; &15 Pre - B DoGraphColour ; &15 Post - MOV PC, R14 ; &16 Pre - B DoGraphColour ; &16 Post - MOV PC, R14 ; &17 Pre - B DoGraphColour ; &17 Post - ORR R0, R0, #MapBit_Conceal ; &18 Pre ; set conceal mode - MOV PC, R14 ; &18 Post - MOV PC, R14 ; &19 Pre - BIC R0, R0, #MapBit_Separated ; &19 Post ; clear separated - MOV PC, R14 ; &1A Pre - ORR R0, R0, #MapBit_Separated ; &1A Post ; set separated - MOV PC, R14 ; &1B Pre - MOV PC, R14 ; &1B Post - BIC R0, R0, #MapBit_BackMask ; &1C Pre ; clear backgd colour - MOV PC, R14 ; &1C Post - B DoNewBackgd ; &1D Pre - MOV PC, R14 ; &1D Post - ORR R0, R0, #MapBit_Hold ; &1E Pre ; set hold graph mode - MOV PC, R14 ; &1E Post - MOV PC, R14 ; &1F Pre - BIC R0, R0, #MapBit_Hold ; &1F Post ; clear hold graph mode - MOV PC, R14 - -; ***************************************************************************** - -DoAlphaBlack - LDR R3, [WsPtr, #TTXFlags] - TST R3, #TTXFlag_BlackEnable ; unless enabled, - MOVEQ PC, R14 ; do nothing - ; drop through... -DoAlphaColour - BIC R0, R0, #MapBit_HeldMask ; clear held graphic - BIC R0, R0, #(MapBit_ForeMask :OR: MapBit_Conceal) - ; clear colour + conceal - ORR R0, R0, R1, LSL #MapForeShift ; put in new colour - BIC R0, R0, #MapBit_Graph ; set alpha mode - MOV PC, R14 - -DoGraphBlack - LDR R3, [WsPtr, #TTXFlags] - TST R3, #TTXFlag_BlackEnable ; unless enabled, - MOVEQ PC, R14 ; do nothing - ; drop through... -DoGraphColour - BIC R0, R0, #(MapBit_ForeMask :OR: MapBit_Conceal) - ; clear colour + conceal - AND R3, R1, #&07 ; ensure only colour bits - ORR R0, R0, R3, LSL #MapForeShift ; put in new colour - ORR R0, R0, #MapBit_Graph ; set graph mode - MOV PC, R14 - -DoFlash - ORR R0, R0, #MapBit_Flash ; set flash mode - MOV PC, R14 - -DoNewBackgd - AND R3, R0, #MapBit_ForeMask ; R5 = fore colour - BIC R0, R0, #MapBit_BackMask ; clear old backgd - ORR R0, R0, R3, LSL #(MapBackShift-MapForeShift) ; new backgd - MOV PC, R14 - -DoDoubleHeight - TST R0, #MapBit_Double ; if currently single height - BICEQ R0, R0, #MapBit_HeldMask ; then cancel held graphic - ORR R0, R0, #MapBit_Double ; set double height mode - ADD R9, R9, #1 ; one more double char - MOV PC, R14 - -DoSingleHeight - TST R0, #MapBit_Double ; if currently double height - BICNE R0, R0, #MapBit_HeldMask ; then cancel held graphic - BIC R0, R0, #MapBit_Double ; set single height mode - MOV PC, R14 - -DoPreStartBox - TST R0, #MapBit_PendingStart ; if prev char was start box - ORRNE R0, R0, #MapBits_Boxed ; then start boxed area - MOV PC, R14 - -DoPostStartBox - ORR R0, R0, #MapBit_PendingStart ; "Previous char is Start Box" - MOV PC, R14 - -DoPreEndBox - TST R0, #MapBit_PendingEnd ; if prev char was end box - BICNE R0, R0, #MapBits_Boxed ; then end boxed area - MOV PC, R14 - -DoPostEndBox - ORR R0, R0, #MapBit_PendingEnd ; "Previous char is End Box" - MOV PC, R14 - -; ***************************************************************************** - -TTXHardFont - [ HiResTTX - DCW &0000,&0000,&0000,&0000,&0000,&0000,&0000,&0000,&0000,&0000,&0000,&0000,&0000,&0000,&0000,&0000,&0000,&0000,&0000,&0000 ; space - DCW &0000,&0000,&0300,&0300,&0300,&0300,&0300,&0300,&0300,&0300,&0300,&0300,&0000,&0000,&0300,&0300,&0000,&0000,&0000,&0000 ; ! - DCW &0000,&0000,&0C60,&0C60,&0C60,&0C60,&0C60,&0C60,&0000,&0000,&0000,&0000,&0000,&0000,&0000,&0000,&0000,&0000,&0000,&0000 ; " - DCW &0000,&0000,&03F0,&07F8,&0E1C,&0C0C,&0C00,&0C00,&3F80,&3F80,&0C00,&0C00,&0C00,&0C00,&3FFC,&3FFC,&0000,&0000,&0000,&0000 ; £ - DCW &0000,&0000,&0FF0,&1FF8,&399C,&318C,&3180,&3980,&1FF0,&0FF8,&019C,&018C,&318C,&399C,&1FF8,&0FF0,&0000,&0000,&0000,&0000 ; $ - DCW &0000,&0000,&3C00,&3C0C,&3C1C,&3C38,&0070,&00E0,&01C0,&0380,&0700,&0E00,&1C3C,&383C,&303C,&003C,&0000,&0000,&0000,&0000 ; % - DCW &0000,&0000,&0E00,&1F00,&3B80,&3180,&3380,&3F00,&1E00,&1F00,&3F8C,&31DC,&30F8,&3878,&1FFC,&0FCC,&0000,&0000,&0000,&0000 ; & - DCW &0000,&0000,&0180,&0180,&0180,&0180,&0180,&0180,&0000,&0000,&0000,&0000,&0000,&0000,&0000,&0000,&0000,&0000,&0000,&0000 ; ' - DCW &0000,&0000,&0060,&00E0,&01C0,&0380,&0700,&0600,&0600,&0600,&0600,&0700,&0380,&01C0,&00E0,&0060,&0000,&0000,&0000,&0000 ; ( - DCW &0000,&0000,&0600,&0700,&0380,&01C0,&00E0,&0060,&0060,&0060,&0060,&00E0,&01C0,&0380,&0700,&0600,&0000,&0000,&0000,&0000 ; ) - DCW &0000,&0000,&0180,&318C,&399C,&1DB8,&0FF0,&07E0,&03C0,&03C0,&07E0,&0FF0,&1DB8,&399C,&318C,&0180,&0000,&0000,&0000,&0000 ; * - DCW &0000,&0000,&0000,&0000,&0180,&0180,&0180,&0180,&3FFC,&3FFC,&0180,&0180,&0180,&0180,&0000,&0000,&0000,&0000,&0000,&0000 ; + - DCW &0000,&0000,&0000,&0000,&0000,&0000,&0000,&0000,&0000,&0000,&0000,&0000,&0180,&0180,&0180,&0180,&0380,&0300,&0000,&0000 ; , - DCW &0000,&0000,&0000,&0000,&0000,&0000,&0000,&0000,&0FF0,&0FF0,&0000,&0000,&0000,&0000,&0000,&0000,&0000,&0000,&0000,&0000 ; - - DCW &0000,&0000,&0000,&0000,&0000,&0000,&0000,&0000,&0000,&0000,&0000,&0000,&0000,&0000,&0180,&0180,&0000,&0000,&0000,&0000 ; . - DCW &0000,&0000,&0000,&0018,&0038,&0070,&00E0,&01C0,&0380,&0700,&0E00,&1C00,&1800,&0000,&0000,&0000,&0000,&0000,&0000,&0000 ; / - DCW &0000,&0000,&03C0,&07E0,&0E70,&1C38,&381C,&300C,&300C,&300C,&300C,&381C,&1C38,&0E70,&07E0,&03C0,&0000,&0000,&0000,&0000 ; 0 - DCW &0000,&0000,&0180,&0180,&0F80,&0F80,&0180,&0180,&0180,&0180,&0180,&0180,&0180,&0180,&0FF0,&0FF0,&0000,&0000,&0000,&0000 ; 1 - DCW &0000,&0000,&0FF0,&1FF8,&381C,&300C,&000C,&001C,&07F8,&0FF0,&1C00,&3800,&3000,&3000,&3FFC,&3FFC,&0000,&0000,&0000,&0000 ; 2 - DCW &0000,&0000,&3FFC,&3FFC,&001C,&0038,&0070,&00E0,&01F8,&01FC,&000C,&000C,&300C,&381C,&1FF8,&0FF0,&0000,&0000,&0000,&0000 ; 3 - DCW &0000,&0000,&0070,&00F0,&01F0,&03B0,&0730,&0E30,&1C30,&3830,&3FFC,&3FFC,&0030,&0030,&0030,&0030,&0000,&0000,&0000,&0000 ; 4 - DCW &0000,&0000,&3FFC,&3FFC,&3000,&3000,&3FF0,&3FF8,&001C,&000C,&000C,&000C,&300C,&381C,&1FF8,&0FF0,&0000,&0000,&0000,&0000 ; 5 - DCW &0000,&0000,&01F0,&07F0,&0F00,&1C00,&3800,&3000,&3FF0,&3FF8,&301C,&300C,&300C,&381C,&1FF8,&0FF0,&0000,&0000,&0000,&0000 ; 6 - DCW &0000,&0000,&3FFC,&3FFC,&000C,&001C,&0038,&0070,&00E0,&01C0,&0380,&0700,&0600,&0600,&0600,&0600,&0000,&0000,&0000,&0000 ; 7 - DCW &0000,&0000,&0FF0,&1FF8,&381C,&300C,&300C,&381C,&1FF8,&1FF8,&381C,&300C,&300C,&381C,&1FF8,&0FF0,&0000,&0000,&0000,&0000 ; 8 - DCW &0000,&0000,&0FF0,&1FF8,&381C,&300C,&300C,&380C,&1FFC,&0FFC,&000C,&001C,&0038,&00F0,&0FE0,&0F80,&0000,&0000,&0000,&0000 ; 9 - DCW &0000,&0000,&0000,&0000,&0000,&0000,&0180,&0180,&0000,&0000,&0000,&0000,&0000,&0000,&0180,&0180,&0000,&0000,&0000,&0000 ; : - DCW &0000,&0000,&0000,&0000,&0000,&0000,&0180,&0180,&0000,&0000,&0000,&0000,&0180,&0180,&0180,&0180,&0380,&0300,&0000,&0000 ; ; - DCW &0000,&0000,&0060,&00E0,&01C0,&0380,&0700,&0E00,&1C00,&1C00,&0E00,&0700,&0380,&01C0,&00E0,&0060,&0000,&0000,&0000,&0000 ; < - DCW &0000,&0000,&0000,&0000,&0000,&0000,&3FFC,&3FFC,&0000,&0000,&3FFC,&3FFC,&0000,&0000,&0000,&0000,&0000,&0000,&0000,&0000 ; = - DCW &0000,&0000,&0600,&0700,&0380,&01C0,&00E0,&0070,&0038,&0038,&0070,&00E0,&01C0,&0380,&0700,&0600,&0000,&0000,&0000,&0000 ; > - DCW &0000,&0000,&0FE0,&1FF0,&3838,&3018,&0038,&0070,&00E0,&01C0,&0180,&0180,&0000,&0000,&0180,&0180,&0000,&0000,&0000,&0000 ; ? - DCW &0000,&0000,&0FF0,&1FF8,&381C,&300C,&31FC,&31FC,&318C,&318C,&31FC,&31FC,&3000,&3800,&1FF0,&0FF0,&0000,&0000,&0000,&0000 ; @ - DCW &0000,&0000,&0180,&03C0,&07E0,&0E70,&1C38,&381C,&300C,&300C,&3FFC,&3FFC,&300C,&300C,&300C,&300C,&0000,&0000,&0000,&0000 ; A - DCW &0000,&0000,&3FF0,&3FF8,&301C,&300C,&300C,&301C,&3FF8,&3FF8,&301C,&300C,&300C,&301C,&3FF8,&3FF0,&0000,&0000,&0000,&0000 ; B - DCW &0000,&0000,&0FF0,&1FF8,&381C,&300C,&3000,&3000,&3000,&3000,&3000,&3000,&300C,&381C,&1FF8,&0FF0,&0000,&0000,&0000,&0000 ; C - DCW &0000,&0000,&3FF0,&3FF8,&301C,&300C,&300C,&300C,&300C,&300C,&300C,&300C,&300C,&301C,&3FF8,&3FF0,&0000,&0000,&0000,&0000 ; D - DCW &0000,&0000,&3FFC,&3FFC,&3000,&3000,&3000,&3000,&3FF0,&3FF0,&3000,&3000,&3000,&3000,&3FFC,&3FFC,&0000,&0000,&0000,&0000 ; E - DCW &0000,&0000,&3FFC,&3FFC,&3000,&3000,&3000,&3000,&3FF0,&3FF0,&3000,&3000,&3000,&3000,&3000,&3000,&0000,&0000,&0000,&0000 ; F - DCW &0000,&0000,&0FF0,&1FF8,&381C,&300C,&3000,&3000,&3000,&3000,&303C,&303C,&300C,&380C,&1FFC,&0FFC,&0000,&0000,&0000,&0000 ; G - DCW &0000,&0000,&300C,&300C,&300C,&300C,&300C,&300C,&3FFC,&3FFC,&300C,&300C,&300C,&300C,&300C,&300C,&0000,&0000,&0000,&0000 ; H - DCW &0000,&0000,&0FF0,&0FF0,&0180,&0180,&0180,&0180,&0180,&0180,&0180,&0180,&0180,&0180,&0FF0,&0FF0,&0000,&0000,&0000,&0000 ; I - DCW &0000,&0000,&000C,&000C,&000C,&000C,&000C,&000C,&000C,&000C,&000C,&000C,&300C,&381C,&1FF8,&0FF0,&0000,&0000,&0000,&0000 ; J - DCW &0000,&0000,&1818,&1838,&1870,&18E0,&19C0,&1B80,&1F00,&1F00,&1B80,&19C0,&18E0,&1870,&1838,&1818,&0000,&0000,&0000,&0000 ; K - DCW &0000,&0000,&3000,&3000,&3000,&3000,&3000,&3000,&3000,&3000,&3000,&3000,&3000,&3000,&3FFC,&3FFC,&0000,&0000,&0000,&0000 ; L - DCW &0000,&0000,&300C,&300C,&381C,&3C3C,&3E7C,&37EC,&33CC,&318C,&300C,&300C,&300C,&300C,&300C,&300C,&0000,&0000,&0000,&0000 ; M - DCW &0000,&0000,&300C,&300C,&380C,&3C0C,&3E0C,&370C,&338C,&31CC,&30EC,&307C,&303C,&301C,&300C,&300C,&0000,&0000,&0000,&0000 ; N - DCW &0000,&0000,&0FF0,&1FF8,&381C,&300C,&300C,&300C,&300C,&300C,&300C,&300C,&300C,&381C,&1FF8,&0FF0,&0000,&0000,&0000,&0000 ; O - DCW &0000,&0000,&3FF0,&3FF8,&301C,&300C,&300C,&301C,&3FF8,&3FF0,&3000,&3000,&3000,&3000,&3000,&3000,&0000,&0000,&0000,&0000 ; P - DCW &0000,&0000,&0FF0,&1FF8,&381C,&300C,&300C,&300C,&300C,&300C,&30CC,&30EC,&3078,&3838,&1FFC,&0FCC,&0000,&0000,&0000,&0000 ; Q - DCW &0000,&0000,&3FF0,&3FF8,&301C,&300C,&300C,&301C,&3FF8,&3FF0,&31C0,&30E0,&3070,&3038,&301C,&300C,&0000,&0000,&0000,&0000 ; R - DCW &0000,&0000,&0FF0,&1FF8,&381C,&300C,&3000,&3800,&1FF0,&0FF8,&001C,&000C,&300C,&381C,&1FF8,&0FF0,&0000,&0000,&0000,&0000 ; S - DCW &0000,&0000,&3FFC,&3FFC,&0180,&0180,&0180,&0180,&0180,&0180,&0180,&0180,&0180,&0180,&0180,&0180,&0000,&0000,&0000,&0000 ; T - DCW &0000,&0000,&300C,&300C,&300C,&300C,&300C,&300C,&300C,&300C,&300C,&300C,&300C,&381C,&1FF8,&0FF0,&0000,&0000,&0000,&0000 ; U - DCW &0000,&0000,&300C,&300C,&300C,&300C,&381C,&1818,&1C38,&0C30,&0E70,&07E0,&03C0,&03C0,&0180,&0180,&0000,&0000,&0000,&0000 ; V - DCW &0000,&0000,&300C,&300C,&300C,&300C,&300C,&300C,&318C,&318C,&318C,&318C,&318C,&3FFC,&1FF8,&0E70,&0000,&0000,&0000,&0000 ; W - DCW &0000,&0000,&300C,&300C,&381C,&1C38,&0E70,&07E0,&03C0,&03C0,&07E0,&0E70,&1C38,&381C,&300C,&300C,&0000,&0000,&0000,&0000 ; X - DCW &0000,&0000,&300C,&300C,&381C,&1C38,&0E70,&07E0,&03C0,&0180,&0180,&0180,&0180,&0180,&0180,&0180,&0000,&0000,&0000,&0000 ; Y - DCW &0000,&0000,&3FFC,&3FFC,&001C,&0038,&0070,&00E0,&01C0,&0380,&0700,&0E00,&1C00,&3800,&3FFC,&3FFC,&0000,&0000,&0000,&0000 ; Z - DCW &0000,&0000,&0000,&0000,&0300,&0700,&0E00,&1C00,&3FFC,&3FFC,&1C00,&0E00,&0700,&0300,&0000,&0000,&0000,&0000,&0000,&0000 ; ˆ - DCW &0000,&0000,&3000,&3000,&3000,&3000,&3000,&3000,&3000,&3000,&31F0,&31F8,&000C,&000C,&0018,&0070,&00C0,&0180,&01FC,&01FC ; ½ - DCW &0000,&0000,&0000,&0000,&00C0,&00E0,&0070,&0038,&3FFC,&3FFC,&0038,&0070,&00E0,&00C0,&0000,&0000,&0000,&0000,&0000,&0000 ; ‰ - DCW &0000,&0000,&0000,&0000,&0180,&03C0,&07E0,&0FF0,&1DB8,&1998,&0180,&0180,&0180,&0180,&0000,&0000,&0000,&0000,&0000,&0000 ; ‹ - DCW &0000,&0000,&0630,&0630,&0630,&0630,&1FFC,&1FFC,&0630,&0630,&1FFC,&1FFC,&0630,&0630,&0630,&0630,&0000,&0000,&0000,&0000 ; # - DCW &0000,&0000,&0000,&0000,&0000,&0000,&0000,&0000,&FFFF,&FFFF,&0000,&0000,&0000,&0000,&0000,&0000,&0000,&0000,&0000,&0000 ; ˜ - DCW &0000,&0000,&0000,&0000,&0000,&0000,&1FF0,&1FF8,&001C,&000C,&1FFC,&3FFC,&300C,&300C,&3FFC,&1FFC,&0000,&0000,&0000,&0000 ; a - DCW &0000,&0000,&3000,&3000,&3000,&3000,&3FF0,&3FF8,&301C,&300C,&300C,&300C,&300C,&301C,&3FF8,&3FF0,&0000,&0000,&0000,&0000 ; b - DCW &0000,&0000,&0000,&0000,&0000,&0000,&0FFC,&1FFC,&3800,&3000,&3000,&3000,&3000,&3800,&1FFC,&0FFC,&0000,&0000,&0000,&0000 ; c - DCW &0000,&0000,&000C,&000C,&000C,&000C,&0FFC,&1FFC,&380C,&300C,&300C,&300C,&300C,&380C,&1FFC,&0FFC,&0000,&0000,&0000,&0000 ; d - DCW &0000,&0000,&0000,&0000,&0000,&0000,&0FF0,&1FF8,&381C,&300C,&3FFC,&3FFC,&3000,&3800,&1FF8,&0FF8,&0000,&0000,&0000,&0000 ; e - DCW &0000,&0000,&0030,&00F0,&01C0,&0180,&0180,&0180,&0FF0,&0FF0,&0180,&0180,&0180,&0180,&0180,&0180,&0000,&0000,&0000,&0000 ; f - DCW &0000,&0000,&0000,&0000,&0000,&0000,&0FFC,&1FFC,&380C,&300C,&300C,&300C,&300C,&380C,&1FFC,&0FFC,&000C,&001C,&0FF8,&0FF0 ; g - DCW &0000,&0000,&3000,&3000,&3000,&3000,&3FF0,&3FF8,&301C,&300C,&300C,&300C,&300C,&300C,&300C,&300C,&0000,&0000,&0000,&0000 ; h - DCW &0000,&0000,&0180,&0180,&0000,&0000,&0F80,&0F80,&0180,&0180,&0180,&0180,&0180,&0180,&0FF0,&0FF0,&0000,&0000,&0000,&0000 ; i - DCW &0000,&0000,&0180,&0180,&0000,&0000,&0180,&0180,&0180,&0180,&0180,&0180,&0180,&0180,&0180,&0180,&0180,&0380,&0F00,&0C00 ; j - DCW &0000,&0000,&1800,&1800,&1800,&1800,&1818,&1838,&18F0,&1BC0,&1F80,&1F80,&19C0,&18F0,&1838,&1818,&0000,&0000,&0000,&0000 ; k - DCW &0000,&0000,&0F80,&0F80,&0180,&0180,&0180,&0180,&0180,&0180,&0180,&0180,&0180,&0180,&0FF0,&0FF0,&0000,&0000,&0000,&0000 ; l - DCW &0000,&0000,&0000,&0000,&0000,&0000,&3E30,&3FF8,&33FC,&318C,&318C,&318C,&318C,&318C,&318C,&318C,&0000,&0000,&0000,&0000 ; m - DCW &0000,&0000,&0000,&0000,&0000,&0000,&3FF0,&3FF8,&301C,&300C,&300C,&300C,&300C,&300C,&300C,&300C,&0000,&0000,&0000,&0000 ; n - DCW &0000,&0000,&0000,&0000,&0000,&0000,&0FF0,&1FF8,&381C,&300C,&300C,&300C,&300C,&381C,&1FF8,&0FF0,&0000,&0000,&0000,&0000 ; o - DCW &0000,&0000,&0000,&0000,&0000,&0000,&3FF0,&3FF8,&301C,&300C,&300C,&300C,&300C,&301C,&3FF8,&3FF0,&3000,&3000,&3000,&3000 ; p - DCW &0000,&0000,&0000,&0000,&0000,&0000,&0FFC,&1FFC,&380C,&300C,&300C,&300C,&300C,&380C,&1FFC,&0FFC,&000C,&000C,&000C,&000C ; q - DCW &0000,&0000,&0000,&0000,&0000,&0000,&31FC,&33FC,&3E00,&3C00,&3000,&3000,&3000,&3000,&3000,&3000,&0000,&0000,&0000,&0000 ; r - DCW &0000,&0000,&0000,&0000,&0000,&0000,&0FFC,&1FFC,&3000,&3000,&1FF0,&0FF8,&000C,&000C,&3FF8,&3FF0,&0000,&0000,&0000,&0000 ; s - DCW &0000,&0000,&0180,&0180,&0180,&0180,&0FF0,&0FF0,&0180,&0180,&0180,&0180,&0180,&01C0,&00F0,&0030,&0000,&0000,&0000,&0000 ; t - DCW &0000,&0000,&0000,&0000,&0000,&0000,&300C,&300C,&300C,&300C,&300C,&300C,&300C,&380C,&1FFC,&0FFC,&0000,&0000,&0000,&0000 ; u - DCW &0000,&0000,&0000,&0000,&0000,&0000,&300C,&300C,&300C,&381C,&1818,&1C38,&0E70,&07E0,&03C0,&0180,&0000,&0000,&0000,&0000 ; v - DCW &0000,&0000,&0000,&0000,&0000,&0000,&300C,&300C,&300C,&300C,&318C,&318C,&318C,&3FFC,&1FF8,&0E70,&0000,&0000,&0000,&0000 ; w - DCW &0000,&0000,&0000,&0000,&0000,&0000,&300C,&381C,&1E78,&0FF0,&03C0,&03C0,&0FF0,&1E78,&381C,&300C,&0000,&0000,&0000,&0000 ; x - DCW &0000,&0000,&0000,&0000,&0000,&0000,&300C,&300C,&300C,&300C,&300C,&300C,&300C,&380C,&1FFC,&0FFC,&000C,&001C,&0FF8,&0FF0 ; y - DCW &0000,&0000,&0000,&0000,&0000,&0000,&3FFC,&3FFC,&0038,&00F0,&01E0,&0780,&0F00,&1C00,&3FFC,&3FFC,&0000,&0000,&0000,&0000 ; z - DCW &0000,&0000,&1800,&1800,&1800,&1800,&1800,&1800,&1800,&1800,&1818,&1838,&00F8,&0198,&0318,&0318,&03F8,&03F8,&0018,&0018 ; ¼ - DCW &0000,&0000,&0C60,&0C60,&0C60,&0C60,&0C60,&0C60,&0C60,&0C60,&0C60,&0C60,&0C60,&0C60,&0C60,&0C60,&0000,&0000,&0000,&0000 ; || - DCW &0000,&0000,&3E00,&3F00,&0180,&0180,&3F00,&3F00,&0180,&0180,&3F0C,&3E1C,&007C,&00CC,&018C,&018C,&01FC,&01FC,&000C,&000C ; ¾ - DCW &0000,&0000,&0000,&0000,&0180,&0180,&0000,&0000,&3FFC,&3FFC,&0000,&0000,&0180,&0180,&0000,&0000,&0000,&0000,&0000,&0000 ; ÷ - DCW &0000,&0000,&3FFC,&3FFC,&3FFC,&3FFC,&3FFC,&3FFC,&3FFC,&3FFC,&3FFC,&3FFC,&3FFC,&3FFC,&3FFC,&3FFC,&0000,&0000,&0000,&0000 ; block - | - = &00,&00,&00,&00,&00,&00,&00,&00,&00,&00 ; space - = &00,&08,&08,&08,&08,&08,&00,&08,&00,&00 ; ! - = &00,&14,&14,&14,&00,&00,&00,&00,&00,&00 ; " - = &00,&0C,&12,&10,&38,&10,&10,&3E,&00,&00 ; ` - = &00,&1C,&2A,&28,&1C,&0A,&2A,&1C,&00,&00 ; $ - = &00,&30,&32,&04,&08,&10,&26,&06,&00,&00 ; % - = &00,&10,&28,&28,&10,&2A,&24,&1A,&00,&00 ; & - = &00,&08,&08,&08,&00,&00,&00,&00,&00,&00 ; ' - = &00,&04,&08,&10,&10,&10,&08,&04,&00,&00 ; ( - = &00,&10,&08,&04,&04,&04,&08,&10,&00,&00 ; ) - = &00,&08,&2A,&1C,&08,&1C,&2A,&08,&00,&00 ; * - = &00,&00,&08,&08,&3E,&08,&08,&00,&00,&00 ; + - = &00,&00,&00,&00,&00,&00,&08,&08,&10,&00 ; , - = &00,&00,&00,&00,&1C,&00,&00,&00,&00,&00 ; - - = &00,&00,&00,&00,&00,&00,&00,&08,&00,&00 ; . - = &00,&00,&02,&04,&08,&10,&20,&00,&00,&00 ; / - = &00,&08,&14,&22,&22,&22,&14,&08,&00,&00 ; 0 - = &00,&08,&18,&08,&08,&08,&08,&1C,&00,&00 ; 1 - = &00,&1C,&22,&02,&0C,&10,&20,&3E,&00,&00 ; 2 - = &00,&3E,&02,&04,&0C,&02,&22,&1C,&00,&00 ; 3 - = &00,&04,&0C,&14,&24,&3E,&04,&04,&00,&00 ; 4 - = &00,&3E,&20,&3C,&02,&02,&22,&1C,&00,&00 ; 5 - = &00,&0C,&10,&20,&3C,&22,&22,&1C,&00,&00 ; 6 - = &00,&3E,&02,&04,&08,&10,&10,&10,&00,&00 ; 7 - = &00,&1C,&22,&22,&1C,&22,&22,&1C,&00,&00 ; 8 - = &00,&1C,&22,&22,&1E,&02,&04,&18,&00,&00 ; 9 - = &00,&00,&00,&08,&00,&00,&08,&00,&00,&00 ; : - = &00,&00,&00,&08,&00,&00,&08,&08,&10,&00 ; ; - = &00,&04,&08,&10,&20,&10,&08,&04,&00,&00 ; < - = &00,&00,&00,&3E,&00,&3E,&00,&00,&00,&00 ; = - = &00,&10,&08,&04,&02,&04,&08,&10,&00,&00 ; > - = &00,&1C,&22,&04,&08,&08,&00,&08,&00,&00 ; ? - = &00,&1C,&22,&2E,&2A,&2E,&20,&1C,&00,&00 ; @ - = &00,&08,&14,&22,&22,&3E,&22,&22,&00,&00 ; A - = &00,&3C,&22,&22,&3C,&22,&22,&3C,&00,&00 ; B - = &00,&1C,&22,&20,&20,&20,&22,&1C,&00,&00 ; C - = &00,&3C,&22,&22,&22,&22,&22,&3C,&00,&00 ; D - = &00,&3E,&20,&20,&3C,&20,&20,&3E,&00,&00 ; E - = &00,&3E,&20,&20,&3C,&20,&20,&20,&00,&00 ; F - = &00,&1C,&22,&20,&20,&26,&22,&1E,&00,&00 ; G - = &00,&22,&22,&22,&3E,&22,&22,&22,&00,&00 ; H - = &00,&1C,&08,&08,&08,&08,&08,&1C,&00,&00 ; I - = &00,&02,&02,&02,&02,&02,&22,&1C,&00,&00 ; J - = &00,&22,&24,&28,&30,&28,&24,&22,&00,&00 ; K - = &00,&20,&20,&20,&20,&20,&20,&3E,&00,&00 ; L - = &00,&22,&36,&2A,&22,&22,&22,&22,&00,&00 ; M - = &00,&22,&22,&32,&2A,&26,&22,&22,&00,&00 ; N - = &00,&1C,&22,&22,&22,&22,&22,&1C,&00,&00 ; O - = &00,&3C,&22,&22,&3C,&20,&20,&20,&00,&00 ; P - = &00,&1C,&22,&22,&22,&2A,&24,&1A,&00,&00 ; Q - = &00,&3C,&22,&22,&3C,&28,&24,&22,&00,&00 ; R - = &00,&1C,&22,&20,&1C,&02,&22,&1C,&00,&00 ; S - = &00,&3E,&08,&08,&08,&08,&08,&08,&00,&00 ; T - = &00,&22,&22,&22,&22,&22,&22,&1C,&00,&00 ; U - = &00,&22,&22,&22,&14,&14,&08,&08,&00,&00 ; V - = &00,&22,&22,&22,&2A,&2A,&2A,&14,&00,&00 ; W - = &00,&22,&22,&14,&08,&14,&22,&22,&00,&00 ; X - = &00,&22,&22,&14,&08,&08,&08,&08,&00,&00 ; Y - = &00,&3E,&02,&04,&08,&10,&20,&3E,&00,&00 ; Z - = &00,&00,&08,&10,&3E,&10,&08,&00,&00,&00 ; [ - = &00,&20,&20,&20,&20,&2C,&02,&04,&08,&0E ; \ - = &00,&00,&08,&04,&3E,&04,&08,&00,&00,&00 ; ] - = &00,&00,&08,&1C,&2A,&08,&08,&00,&00,&00 ; ^ - = &00,&14,&14,&3E,&14,&3E,&14,&14,&00,&00 ; # - = &00,&00,&00,&00,&3E,&00,&00,&00,&00,&00 ; _ - = &00,&00,&00,&1C,&02,&1E,&22,&1E,&00,&00 ; a - = &00,&20,&20,&3C,&22,&22,&22,&3C,&00,&00 ; b - = &00,&00,&00,&1E,&20,&20,&20,&1E,&00,&00 ; c - = &00,&02,&02,&1E,&22,&22,&22,&1E,&00,&00 ; d - = &00,&00,&00,&1C,&22,&3E,&20,&1C,&00,&00 ; e - = &00,&04,&08,&08,&1C,&08,&08,&08,&00,&00 ; f - = &00,&00,&00,&1E,&22,&22,&22,&1E,&02,&1C ; g - = &00,&20,&20,&3C,&22,&22,&22,&22,&00,&00 ; h - = &00,&08,&00,&18,&08,&08,&08,&1C,&00,&00 ; i - = &00,&08,&00,&08,&08,&08,&08,&08,&08,&10 ; j - = &00,&10,&10,&12,&14,&18,&14,&12,&00,&00 ; k - = &00,&18,&08,&08,&08,&08,&08,&1C,&00,&00 ; l - = &00,&00,&00,&34,&2A,&2A,&2A,&2A,&00,&00 ; m - = &00,&00,&00,&3C,&22,&22,&22,&22,&00,&00 ; n - = &00,&00,&00,&1C,&22,&22,&22,&1C,&00,&00 ; o - = &00,&00,&00,&3C,&22,&22,&22,&3C,&20,&20 ; p - = &00,&00,&00,&1E,&22,&22,&22,&1E,&02,&02 ; q - = &00,&00,&00,&16,&18,&10,&10,&10,&00,&00 ; r - = &00,&00,&00,&1E,&20,&1C,&02,&3C,&00,&00 ; s - = &00,&08,&08,&1C,&08,&08,&08,&04,&00,&00 ; t - = &00,&00,&00,&22,&22,&22,&22,&1E,&00,&00 ; u - = &00,&00,&00,&22,&22,&14,&14,&08,&00,&00 ; v - = &00,&00,&00,&22,&22,&2A,&2A,&14,&00,&00 ; w - = &00,&00,&00,&22,&14,&08,&14,&22,&00,&00 ; x - = &00,&00,&00,&22,&22,&22,&22,&1E,&02,&1C ; y - = &00,&00,&00,&3E,&04,&08,&10,&3E,&00,&00 ; z - = &00,&10,&10,&10,&10,&12,&06,&0A,&0E,&02 ; { - = &00,&14,&14,&14,&14,&14,&14,&14,&00,&00 ; | - = &00,&30,&08,&30,&08,&32,&06,&0A,&0E,&02 ; } - = &00,&00,&08,&00,&3E,&00,&08,&00,&00,&00 ; ~ - = &00,&3E,&3E,&3E,&3E,&3E,&3E,&3E,&00,&00 ; &FF - ] - - END diff --git a/s/vdu/vduwrch b/s/vdu/vduwrch deleted file mode 100644 index 3e51a9e8..00000000 --- a/s/vdu/vduwrch +++ /dev/null @@ -1,3340 +0,0 @@ -; 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.VduWrch - -; Text printing etc. -; ------------------ - -; Author Tim Dobson -; Started 01-Sep-86 -; Status Mostly Arm-less - -; ***************************************************************************** - -; CursorFlags bits - -; Bit 0 '81 column' mode -; Bits 1-3 Cursor movement directions -; Bit 4 Wrap instead of scroll in VDU4 mode -; Bit 5 Don't move cursor after printing character -; Bit 6 Don't wrap in VDU 5 mode -; Bit 7 Unused but could be set by user -; Bit 8 When in Wrch or screen update operation, set to 1 and forms -; part of mask for ROR #10. -; Otherwise is set to 0. -; Tested by cursor code to see if it can update CursorFlags. -; Bits 9-17 Set to 101111000 so we can TST CursorFlags with itself ROR #10 -; to test for OR of C81Bit, Vdu5Bit, silly movement bits in 1 go -; in order to optimise the case when none of these are present -; Bit 18 Set when cursors are split - since bit 8 is set this triggers -; Bit 19 Set when in teletext mode -; Bit 20 Set when in page mode -; Bit 21 Set when clip box calculations are enabled - this triggers -; Bits 22-24 Unused, but probably have to be zero because of ROR #10 -; Bit 25 Actual cursor state (1 => cursor is on screen) -; Bit 26 Set if VDU disabled -; Bits 27-28 Unused, but probably have to be zero because of ROR #10 -; Bit 29 TextExpand not up-to-date -; Bit 30 VDU 5 mode -; Bit 31 In the '81st' column - -InWrchBitPosn * 8 -InWrchBit * 1 :SHL: InWrchBitPosn -CursorsSplit * 1 :SHL: 18 -TeletextMode * 1 :SHL: 19 -PageMode * 1 :SHL: 20 -ClipBoxEnableBit * 1 :SHL: 21 -ActualState * 1 :SHL: 25 -VduDisabled * 1 :SHL: 26 -TEUpdate * 1 :SHL: 29 -Vdu5Bit * 1 :SHL: 30 -C81Bit * 1 :SHL: 31 -InitialCursorFlags * (&1E :SHL: 10) :OR: (C81Bit :SHR: (32-10)) - -; The TST R6, R6, ROR #10 returns non-zero if -; -; C81Bit OR Vdu5 OR (any of bits 1-4) OR CursorsSplit -; OR ClipBoxEnableBit OR (TEUpdate AND bit7) OR Teletext -; -; The last two of these are slightly undesirable, but fairly harmless since: -; (a) bit 7 is not normally set, and TEUpdate is only set when a colour -; change happens. -; (b) Teletext mode takes quite a long time anyway. -; NB We don't believe that the TST needs to detect Teletext mode, but if you -; want to stop it doing so, it's on your own head. Check everything carefully! - -; ***************************************************************************** -; -; Set default logical and physical colours - -bpp RN 0 -fore RN 1 -back RN 2 -tabaddr RN 3 -index RN 4 -source RN 5 -dest RN 6 -col RN 7 -orrbits RN 8 -addbits RN 9 -bit0 RN 10 - -hiaddr RN 4 -loaddr RN 5 -; dest 6 -hiword RN 7 ; must be higher number than dest (for Colour16Bit) -loword RN 8 -cbyte RN 9 -spare1 RN 10 -spare2 RN 11 - -; ***************************************************************************** -; -; VDU 20 - Set default colours (if output mode not teletext) -; and palette (if display mode not teletext) -; -; External routine, and DefaultColours called by mode change -; and SwitchOutputToSprite -; -; in: R6 = CursorFlags (for output mode) -; - -VDU20 ROUT - LDR R0, [WsPtr, #DisplayModeFlags] ; if display mode is - TST R0, #Flag_Teletext ; not teletext, then restore - BNE %FT10 ; default palette - - Push R14 - BL PalInit ; R6 is preserved over the call - Pull R14 -10 - TST R6, #TeletextMode ; if output mode is teletext - MOVNE PC, R14 ; then don't reset colours - -; else drop thru to ... - -DefaultColours ROUT - Push R14 - - ASSERT GPLBMD = GPLFMD +4 - ASSERT GFCOL = GPLFMD +8 - ASSERT GBCOL = GPLFMD +12 - - ASSERT TBTint = TFTint +4 - ASSERT GFTint = TFTint +8 - ASSERT GBTint = TFTint +12 - - ASSERT TBackCol = TForeCol +4 - ASSERT back > fore - - MOV R0, #0 ; foreground action := store - MOV R1, #0 ; background action := store - LDR R2, [WsPtr, #NColour] ; GCOL(0,(NColour AND 7)) except - TST R2, #&F0 ; for 256 colour modes - ANDEQ R2, R2, #7 ; when we use colour 63 (=NColour) - MOV R3, #0 ; background colour := black - ADD R4, WsPtr, #GPLFMD ; store GPLFMD, GPLBMD, GFCOL, GBCOL - STMIA R4, {R0-R3} - - MOV R0, #&FF ; R0 = TFTint := &FF; R1 = TBTint := 0 - MOV R2, #&FF ; R2 = GFTint := &FF; R3 = GBTint := 0 - ADD R4, WsPtr, #TFTint - STMIA R4, {R0-R3} - - BL SetColour ; Update FgEcf & BgEcf - - LDR bpp, [WsPtr, #BitsPerPix] - LDR fore, [WsPtr, #NColour] ; Number of colours allowed -1 - TEQ fore, #63 ; are we in bodgy 256 colour mode? - MOVEQ fore, #255 ; then use colour 255 (cringe!) - TEQ fore, #15 ; 16 colour mode - MOVEQ fore, #7 ; Default is 7 for this depth of mode - - [ {TRUE} ; TMD 25-Jun-93 - change default text colour in 16bpp to &7FFF, and 32bpp to &00FFFFFF - LDR r14, =&FFFF - CMP fore, r14 - BICEQ fore, fore, #&8000 ; &FFFF -> &7FFF - BICHI fore, fore, #&FF000000 ; &FFFFFFFF -> &00FFFFFF - ] - MOV back, #0 - ADD R14, WsPtr, #TForeCol - STMIA R14, {fore, back} ; save fgd + bgd text colours - Pull R14 - -; and drop thru to ... - -SetColours ROUT - Push R14 - - MOV R8, back, ROR bpp ; move bits to top of word - MOV R9, fore, ROR bpp - - LDR bpp, [WsPtr, #BytesPerChar] ; fudge some more bits - ORR back, R8, back, ROR bpp - ORR fore, R9, fore, ROR bpp - - MOV LR, bpp -10 - TEQ LR, #32 ; have we finished replicating through word yet? - ORRNE back, back, back, LSR LR ; if not then expand again through the word - ORRNE fore, fore, fore, LSR LR - MOVNE LR, LR, LSL #1 ; double the shift ready for the next pass - BNE %BT10 ; and loop again! - - STR fore, [WsPtr, #TextFgColour] - STR back, [WsPtr, #TextBgColour] ; store bit expanded fore / background colour - -; New colour change code -; entered with fore, back expanded to <bytes_per_char> bits -; and bpp set to be <bytes_per_char> - - TEQ bpp, #16 - BEQ Colour16Bit ; can't optimise - - TEQ bpp, #32 - BEQ Colour32Bit ; cannie optimise captin! - - EOR fore, fore, back ; so we can AND and EOR - LDR loaddr, [WsPtr, #TextExpandArea] - ADD dest, loaddr, bpp, LSL #8 ; end+1 destination addr - MOV hiaddr, dest ; TextPlain now moves around, - ; depending on bytes-per-char -10 - LDR cbyte, [hiaddr], #4 - AND cbyte, cbyte, fore - EOR cbyte, cbyte, back - STR cbyte, [loaddr], #4 - TEQ loaddr, dest - BNE %BT10 - - Pull PC - LTORG - -; ***************************************************************************** -; -; Colour16Bit - Set up colour table for MODE 10 -; Entered with R14 already pushed -; - -Colour16Bit - LDR tabaddr, [WsPtr, #TextExpandArea] - - - ADR hiaddr, C16BTab - ADD R10, hiaddr, #128 -C16B20 - ADR loaddr, C16BTab -C16B30 - LDMIA hiaddr, {dest, hiword} - BL OutputColour - MOV dest, hiword - BL OutputColour - - LDMIA loaddr!, {dest, loword} - BL OutputColour - MOV dest, loword - BL OutputColour - - TEQ loaddr, R10 - BNE C16B30 - - ADD hiaddr, hiaddr, #8 - TEQ hiaddr, R10 - BNE C16B20 - - Pull PC - -C16BTab - & &00000000, &00000000 - & &00000000, &FFFF0000 - & &00000000, &0000FFFF - & &00000000, &FFFFFFFF - - & &FFFF0000, &00000000 - & &FFFF0000, &FFFF0000 - & &FFFF0000, &0000FFFF - & &FFFF0000, &FFFFFFFF - - & &0000FFFF, &00000000 - & &0000FFFF, &FFFF0000 - & &0000FFFF, &0000FFFF - & &0000FFFF, &FFFFFFFF - - & &FFFFFFFF, &00000000 - & &FFFFFFFF, &FFFF0000 - & &FFFFFFFF, &0000FFFF - & &FFFFFFFF, &FFFFFFFF - -; ***************************************************************************** -; -; Colour32Bit - Set up colour table for MODE 48 (32 bit per pixel) -; Entered with R14 already pushed -; - -Colour32Bit - LDR tabaddr, [WsPtr, #TextExpandArea] - MOV dest, #0 -C32B20 - -; Expand the value in in 'hiaddr' so that each bit is stored as a word -; zero bits are stored in the background and non-zero bits are stored in -; foreground. This is indexed when expanding the 1BPP VDU font out to -; the current depth. - - TST dest, #1 <<7 - STREQ back, [tabaddr], #4 - STRNE fore, [tabaddr], #4 - TST dest, #1 <<6 - STREQ back, [tabaddr], #4 - STRNE fore, [tabaddr], #4 - TST dest, #1 <<5 - STREQ back, [tabaddr], #4 - STRNE fore, [tabaddr], #4 - TST dest, #1 <<4 - STREQ back, [tabaddr], #4 - STRNE fore, [tabaddr], #4 - TST dest, #1 <<3 - STREQ back, [tabaddr], #4 - STRNE fore, [tabaddr], #4 - TST dest, #1 <<2 - STREQ back, [tabaddr], #4 - STRNE fore, [tabaddr], #4 - TST dest, #1 <<1 - STREQ back, [tabaddr], #4 - STRNE fore, [tabaddr], #4 - TST dest, #1 <<0 - STREQ back, [tabaddr], #4 - STRNE fore, [tabaddr], #4 - - ADD dest, dest, #1 - TEQ dest, #256 - BNE C32B20 - - Pull "PC" - -; ***************************************************************************** -; -; Fast CLS used when no text window defined -; - -FastCLS ROUT - Push R14 - BL CheckTEUpdate - - TST R6, #TeletextMode ; teletext mode ? - LDREQ R0, [WsPtr, #TextBgColour] - BEQ %FT10 ; and skip - - BL TTXFastCLS ; else clear teletext map - MOV R0, #0 ; and clear to zero - [ UseGraphicsV - B %FT15 - ] -10 - [ UseGraphicsV - BL CheckAcceleration - BNE %FT15 - MOV R11, R13 ; try to do an accelerated - BIC R13, R13, #63 ; rectangle fill - need an - MOV R1, #&FFFFFFFF ; alignedOraEor block - MVN R2, R0 - MOV R3, R1 - MOV R4, R2 - Push "R1-R4" - Push "R1-R4" - Push "R1-R4" - Push "R1-R4" - MOV R0, #0 ; left - LDR R1, [WsPtr, #YWindLimit] ; top - LDR R2, [WsPtr, #XWindLimit] ; right (okay because checked BPC=BPP) - MOV R3, #0 ; bottom - MOV R4, R13 ; colour block - Push "R0-R4" - MOV R0, #GVRender_Sync - MOV R1, #GVRender_FillRectangle - MOV R2, R13 - MOV R4, #GraphicsV_Render - BL CallGraphicsV - MOV R13, R11 - TEQ R4, #GraphicsV_Complete - Pull PC, EQ - LDR R0, [WsPtr, #TextBgColour] -15 - ] - LDR R8, [WsPtr, #ScreenStart] - MOV R1, R0 - MOV R2, R0 - MOV R3, R0 - MOV R4, R0 - MOV R5, R0 - MOV R6, R0 - MOV R7, R0 - LDR R9, [WsPtr, #ScreenSize] ; screen size in bytes -20 - SUBS R9, R9, #256 ; if another 256 to do - STMCSIA R8!, {R0 - R7} ; a bit excessive, I know ! - STMCSIA R8!, {R0 - R7} - STMCSIA R8!, {R0 - R7} - STMCSIA R8!, {R0 - R7} - STMCSIA R8!, {R0 - R7} - STMCSIA R8!, {R0 - R7} - STMCSIA R8!, {R0 - R7} - STMCSIA R8!, {R0 - R7} - BHI %BT20 ; only loop if more to do - ADDCC R9, R9, #256 ; add back the last 256 -30 - SUBS R9, R9, #4 - STMCSIA R8!, {R0} - BHI %BT30 - - Pull PC - -; ***************************************************************************** -; -; Home cursor to "top left" - -RS -Home - MOV R0, #0 - MOV R1, #0 - B TabR0R1 - -; ***************************************************************************** -; -; Address text cursor position -; in: R0 = X position -; R1 = Y position -; -; out: CursorAddr contains screen address - -CursorR0R1 - STR R0, [WsPtr, #CursorX] - STR R1, [WsPtr, #CursorY] -CTADDR10 - Push R14 - BL AddressR0R1 - STR R2, [WsPtr, #CursorAddr] - Pull PC - -; Calculate cursor address - -AddressCursor - LDR R0, [WsPtr, #CursorX] - LDR R1, [WsPtr, #CursorY] - B CTADDR10 - - -; Address an X,Y text position in R0,R1 -; R2 is screen address on exit -; R1, R3, R4 corrupted; R0, R5-R13 preserved - -AddressR0R1 ROUT - LDR R4, [WsPtr, #RowLength] - LDR R3, [WsPtr, #Log2BPC] - [ HiResTTX - LDR R2, [WsPtr, #ModeFlags] - TST R2, #Flag_Teletext - ADDNE R3, R3, #1 - ] - LDR R2, [WsPtr, #ScreenStart] ; start address of top of screen - ADD R2, R2, R0, LSL R3 ; add in X offset - MLA R2, R4, R1, R2 ; add in Y*RowLength - MOV PC, R14 - -; ***************************************************************************** -; -; Write character in R0 (>=32) to the screen -; R6 = CursorFlags on entry -; - -font RN 1 -screen RN 2 -bigfont RN 3 -mask RN 4 -tophalf RN 5 -bottomhalf RN 6 -lbpp RN 7 -byte RN 8 -scrbyte RN 9 -scrbyte2 RN 10 -linelen RN 11 - -; *****Comment by DJS: Given we want applications to use the windowing world, -; shouldn't we be optimising VDU 5 characters a bit more here? - even if it -; makes VDU 4 characters a bit less optimal? - -TimWrch ROUT - LDR R1, [WsPtr, #VduStatus] ; test all silly flags at once - TST R1, #Vdu2Mode - TSTEQ R6, #(VduDisabled :OR: TEUpdate :OR: C81Bit :OR: Vdu5Bit) - TSTEQ R6, #(TeletextMode :OR: ClipBoxEnableBit) -10 - ADDEQ font, WsPtr, #(Font-32*8) - ADDEQ font, font, R0, LSL #3 - LDMEQIA font, {tophalf, bottomhalf} - Push R14, EQ - ADREQ R14, %FT15 - LDREQ screen, [WsPtr, #CursorAddr] - LDREQ bigfont, [WsPtr, #TextExpandArea] - LDREQ linelen, [WsPtr, #LineLength] - LDREQ PC, [WsPtr, #WrchNbit] - -; *****Change made by DJS -; Moved the following code down to a place where we don't have to branch -; around it! -; B %FT20 -;15 -; Pull R14 -;PostCharMove -; LDR R6, [WsPtr, #CursorFlags] -; TST R6, #32 ; move cursor after char ? -; BEQ CHT ; move "right" & test for C81 -; MOV PC, R14 -; -;20 -; *****End of change made by DJS - -; if printing enabled then we want to print this character, -; so pull the old R14 off the stack - - TST R1, #Vdu2Mode - Pull R14, NE ; in VDU 2 mode, so pull R14 - TST R6, #VduDisabled ; if VDU disabled - MOVNE PC, R14 ; then don't print it - TST R6, #TEUpdate ; if colours need updating - BNE %FT30 ; then do it + return to %25 -25 - TST R6, #Vdu5Bit - BNE Vdu5Wrch - TST R6, #C81Bit - BNE %FT40 -35 - TST R6, #TeletextMode - BNE TTXWrch - TST R6, #ClipBoxEnableBit - BEQ %BT10 ; must enter with EQ - -; now update clip box - - Push R14 - BL ClipCursorCell - Pull R14 - TST R0, #0 ; set EQ - B %BT10 - -; *****Change made by DJS -; Code moved down from above. - -15 - Pull R14 -PostCharMove - LDR R6, [WsPtr, #CursorFlags] - TST R6, #32 ; move cursor after char ? - BEQ CHT ; move "right" & test for C81 - MOV PC, R14 - -; *****End of change made by DJS - -30 - Push "R0,R14" - BL ReallySetColours ; update colour table - Pull "R0,R14" - B %BT25 - -40 - Push "R0, R14" - BL RCRLFR6 ; do pending CRLF - Pull "R0, R14" - B %BT35 - -; ***************************************************************************** -; -; Write character in 1 bit-per-pixel mode - -Wrch1bit - -; *****Change made by DJS -; Original code was: -; MOV mask, #&FF000000 -; -; AND byte, mask, tophalf, LSL #24 -; LDRB scrbyte, [bigfont, byte, LSR #24] -; STRB scrbyte, [screen], linelen -; AND byte, mask, tophalf, LSL #16 -; LDRB scrbyte, [bigfont, byte, LSR #24] -; STRB scrbyte, [screen], linelen -; AND byte, mask, tophalf, LSL #8 -; LDRB scrbyte, [bigfont, byte, LSR #24] -; STRB scrbyte, [screen], linelen -; LDRB scrbyte, [bigfont, tophalf, LSR #24] -; STRB scrbyte, [screen], linelen -; -; AND byte, mask, bottomhalf, LSL #24 -; LDRB scrbyte, [bigfont, byte, LSR #24] -; STRB scrbyte, [screen], linelen -; AND byte, mask, bottomhalf, LSL #16 -; LDRB scrbyte, [bigfont, byte, LSR #24] -; STRB scrbyte, [screen], linelen -; AND byte, mask, bottomhalf, LSL #8 -; LDRB scrbyte, [bigfont, byte, LSR #24] -; STRB scrbyte, [screen], linelen -; LDRB scrbyte, [bigfont, bottomhalf, LSR #24] -; STRB scrbyte, [screen], linelen -; -; There is no need to use "mask" at all in this... - - MOV byte, tophalf, LSL #24 - LDRB scrbyte, [bigfont, byte, LSR #24] - STRB scrbyte, [screen], linelen - MOV byte, tophalf, LSL #16 - LDRB scrbyte, [bigfont, byte, LSR #24] - STRB scrbyte, [screen], linelen - MOV byte, tophalf, LSL #8 - LDRB scrbyte, [bigfont, byte, LSR #24] - STRB scrbyte, [screen], linelen - LDRB scrbyte, [bigfont, tophalf, LSR #24] - STRB scrbyte, [screen], linelen - - MOV byte, bottomhalf, LSL #24 - LDRB scrbyte, [bigfont, byte, LSR #24] - STRB scrbyte, [screen], linelen - MOV byte, bottomhalf, LSL #16 - LDRB scrbyte, [bigfont, byte, LSR #24] - STRB scrbyte, [screen], linelen - MOV byte, bottomhalf, LSL #8 - LDRB scrbyte, [bigfont, byte, LSR #24] - STRB scrbyte, [screen], linelen - LDRB scrbyte, [bigfont, bottomhalf, LSR #24] - STRB scrbyte, [screen], linelen - -; *****End of change made by DJS - - [ 1=0 ; *** No 1 bpc non-BBC gap modes at present *** - LDR R0, [WsPtr, #ModeFlags] ; now test for non-BBC gap mode - AND R0, R0, #(Flag_GapMode :OR: Flag_BBCGapMode) ; we want R0=0 iff - EORS R0, R0, #Flag_GapMode ; (gapmode AND NOT bbcgapmode) - MOVNE PC, R14 - LDRB scrbyte, [bigfont] ; store backgd in next 2 - STRB scrbyte, [screen], linelen - STRB scrbyte, [screen], linelen - ] - MOV PC, R14 - -Wrch1bitDouble - -; *****Change made by DJS -; Original code was: -; MOV mask, #&FF000000 -; -; AND byte, mask, tophalf, LSL #24 -; LDRB scrbyte, [bigfont, byte, LSR #24] -; STRB scrbyte, [screen], linelen -; STRB scrbyte, [screen], linelen -; AND byte, mask, tophalf, LSL #16 -; LDRB scrbyte, [bigfont, byte, LSR #24] -; STRB scrbyte, [screen], linelen -; STRB scrbyte, [screen], linelen -; AND byte, mask, tophalf, LSL #8 -; LDRB scrbyte, [bigfont, byte, LSR #24] -; STRB scrbyte, [screen], linelen -; STRB scrbyte, [screen], linelen -; LDRB scrbyte, [bigfont, tophalf, LSR #24] -; STRB scrbyte, [screen], linelen -; STRB scrbyte, [screen], linelen -; -; AND byte, mask, bottomhalf, LSL #24 -; LDRB scrbyte, [bigfont, byte, LSR #24] -; STRB scrbyte, [screen], linelen -; STRB scrbyte, [screen], linelen -; AND byte, mask, bottomhalf, LSL #16 -; LDRB scrbyte, [bigfont, byte, LSR #24] -; STRB scrbyte, [screen], linelen -; STRB scrbyte, [screen], linelen -; AND byte, mask, bottomhalf, LSL #8 -; LDRB scrbyte, [bigfont, byte, LSR #24] -; STRB scrbyte, [screen], linelen -; STRB scrbyte, [screen], linelen -; LDRB scrbyte, [bigfont, bottomhalf, LSR #24] -; STRB scrbyte, [screen], linelen -; STRB scrbyte, [screen], linelen -; -; As above, "mask" is not needed. - - MOV byte, tophalf, LSL #24 - LDRB scrbyte, [bigfont, byte, LSR #24] - STRB scrbyte, [screen], linelen - STRB scrbyte, [screen], linelen - MOV byte, tophalf, LSL #16 - LDRB scrbyte, [bigfont, byte, LSR #24] - STRB scrbyte, [screen], linelen - STRB scrbyte, [screen], linelen - MOV byte, tophalf, LSL #8 - LDRB scrbyte, [bigfont, byte, LSR #24] - STRB scrbyte, [screen], linelen - STRB scrbyte, [screen], linelen - LDRB scrbyte, [bigfont, tophalf, LSR #24] - STRB scrbyte, [screen], linelen - STRB scrbyte, [screen], linelen - - MOV byte, bottomhalf, LSL #24 - LDRB scrbyte, [bigfont, byte, LSR #24] - STRB scrbyte, [screen], linelen - STRB scrbyte, [screen], linelen - MOV byte, bottomhalf, LSL #16 - LDRB scrbyte, [bigfont, byte, LSR #24] - STRB scrbyte, [screen], linelen - STRB scrbyte, [screen], linelen - MOV byte, bottomhalf, LSL #8 - LDRB scrbyte, [bigfont, byte, LSR #24] - STRB scrbyte, [screen], linelen - STRB scrbyte, [screen], linelen - LDRB scrbyte, [bigfont, bottomhalf, LSR #24] - STRB scrbyte, [screen], linelen - STRB scrbyte, [screen], linelen - -; *****End of change made by DJS - - [ 1=0 ; *** No 1 bpc non-BBC gap modes at present *** - LDR R0, [WsPtr, #ModeFlags] ; now test for non-BBC gap mode - AND R0, R0, #(Flag_GapMode :OR: Flag_BBCGapMode) ; we want R0=0 iff - EORS R0, R0, #Flag_GapMode ; (gapmode AND NOT bbcgapmode) - MOVNE PC, R14 - LDRB scrbyte, [bigfont] ; store backgd in next 2 - STRB scrbyte, [screen], linelen - STRB scrbyte, [screen], linelen - ] - MOV PC, R14 - -Wrch2bit - -; *****Change made by DJS -; Original code was: -; -; MOV mask, #&FE000000 -; SUB linelen, linelen, #1 -; -; AND byte, mask, tophalf, LSL #24 -; LDR scrbyte, [bigfont, byte, LSR #23] -; MOVS byte, tophalf, LSR #1 -; MOVCS scrbyte, scrbyte, LSR #16 -; STRB scrbyte, [screen], #1 -; MOV scrbyte, scrbyte, LSR #8 -; STRB scrbyte, [screen], linelen -; -; AND byte, mask, tophalf, LSL #16 -; LDR scrbyte, [bigfont, byte, LSR #23] -; MOVS byte, tophalf, LSR #9 -; MOVCS scrbyte, scrbyte, LSR #16 -; STRB scrbyte, [screen], #1 -; MOV scrbyte, scrbyte, LSR #8 -; STRB scrbyte, [screen], linelen -; -; AND byte, mask, tophalf, LSL #8 -; LDR scrbyte, [bigfont, byte, LSR #23] -; MOVS byte, tophalf, LSR #17 -; MOVCS scrbyte, scrbyte, LSR #16 -; STRB scrbyte, [screen], #1 -; MOV scrbyte, scrbyte, LSR #8 -; STRB scrbyte, [screen], linelen -; -; AND byte, mask, tophalf -; LDR scrbyte, [bigfont, byte, LSR #23] -; MOVS byte, tophalf, LSR #25 -; MOVCS scrbyte, scrbyte, LSR #16 -; STRB scrbyte, [screen], #1 -; MOV scrbyte, scrbyte, LSR #8 -; STRB scrbyte, [screen], linelen -; -; AND byte, mask, bottomhalf, LSL #24 -; LDR scrbyte, [bigfont, byte, LSR #23] -; MOVS byte, bottomhalf, LSR #1 -; MOVCS scrbyte, scrbyte, LSR #16 -; STRB scrbyte, [screen], #1 -; MOV scrbyte, scrbyte, LSR #8 -; STRB scrbyte, [screen], linelen -; -; AND byte, mask, bottomhalf, LSL #16 -; LDR scrbyte, [bigfont, byte, LSR #23] -; MOVS byte, bottomhalf, LSR #9 -; MOVCS scrbyte, scrbyte, LSR #16 -; STRB scrbyte, [screen], #1 -; MOV scrbyte, scrbyte, LSR #8 -; STRB scrbyte, [screen], linelen -; -; AND byte, mask, bottomhalf, LSL #8 -; LDR scrbyte, [bigfont, byte, LSR #23] -; MOVS byte, bottomhalf, LSR #17 -; MOVCS scrbyte, scrbyte, LSR #16 -; STRB scrbyte, [screen], #1 -; MOV scrbyte, scrbyte, LSR #8 -; STRB scrbyte, [screen], linelen -; -; AND byte, mask, bottomhalf -; LDR scrbyte, [bigfont, byte, LSR #23] -; MOVS byte, bottomhalf, LSR #25 -; MOVCS scrbyte, scrbyte, LSR #16 -; STRB scrbyte, [screen], #1 -; MOV scrbyte, scrbyte, LSR #8 -; STRB scrbyte, [screen], linelen -; -; Messing around with this a bit, I found the following shorter & faster -; code: - - MOV mask, #&7F - SUB linelen, linelen, #1 - - ANDS byte, mask, tophalf, LSR #1 ;C := bit 0 of tophalf - LDR scrbyte, [bigfont, byte, LSL #2] - MOVCS scrbyte, scrbyte, LSR #16 - STRB scrbyte, [screen], #1 - MOV scrbyte, scrbyte, LSR #8 - STRB scrbyte, [screen], linelen - - ANDS byte, mask, tophalf, LSR #9 ;C := bit 8 of tophalf - LDR scrbyte, [bigfont, byte, LSL #2] - MOVCS scrbyte, scrbyte, LSR #16 - STRB scrbyte, [screen], #1 - MOV scrbyte, scrbyte, LSR #8 - STRB scrbyte, [screen], linelen - - ANDS byte, mask, tophalf, LSR #17 ;C := bit 16 of tophalf - LDR scrbyte, [bigfont, byte, LSL #2] - MOVCS scrbyte, scrbyte, LSR #16 - STRB scrbyte, [screen], #1 - MOV scrbyte, scrbyte, LSR #8 - STRB scrbyte, [screen], linelen - - ANDS byte, mask, tophalf, LSR #25 ;C := bit 24 of tophalf - LDR scrbyte, [bigfont, byte, LSL #2] - MOVCS scrbyte, scrbyte, LSR #16 - STRB scrbyte, [screen], #1 - MOV scrbyte, scrbyte, LSR #8 - STRB scrbyte, [screen], linelen - - ANDS byte, mask, bottomhalf, LSR #1 ;C := bit 0 of b'half - LDR scrbyte, [bigfont, byte, LSL #2] - MOVCS scrbyte, scrbyte, LSR #16 - STRB scrbyte, [screen], #1 - MOV scrbyte, scrbyte, LSR #8 - STRB scrbyte, [screen], linelen - - ANDS byte, mask, bottomhalf, LSR #9 ;C := bit 8 of b'half - LDR scrbyte, [bigfont, byte, LSL #2] - MOVCS scrbyte, scrbyte, LSR #16 - STRB scrbyte, [screen], #1 - MOV scrbyte, scrbyte, LSR #8 - STRB scrbyte, [screen], linelen - - ANDS byte, mask, bottomhalf, LSR #17 ;C := bit 16 of b'half - LDR scrbyte, [bigfont, byte, LSL #2] - MOVCS scrbyte, scrbyte, LSR #16 - STRB scrbyte, [screen], #1 - MOV scrbyte, scrbyte, LSR #8 - STRB scrbyte, [screen], linelen - - ANDS byte, mask, bottomhalf, LSR #25 ;C := bit 24 of b'half - LDR scrbyte, [bigfont, byte, LSL #2] - MOVCS scrbyte, scrbyte, LSR #16 - STRB scrbyte, [screen], #1 - MOV scrbyte, scrbyte, LSR #8 - STRB scrbyte, [screen], linelen - -; *****End of change made by DJS - - LDR R0, [WsPtr, #ModeFlags] ; now test for non-BBC gap mode - AND R0, R0, #(Flag_GapMode :OR: Flag_BBCGapMode) ; we want R0=0 iff - EORS R0, R0, #Flag_GapMode ; (gapmode AND NOT bbcgapmode) - MOVNE PC, R14 - LDRB scrbyte, [bigfont] ; store backgd in next 2 - STRB scrbyte, [screen], #1 - STRB scrbyte, [screen], linelen - STRB scrbyte, [screen], #1 - STRB scrbyte, [screen], linelen - MOV PC, R14 - -Wrch4bit - MOV R10, #0 ; extra rows are 0 if not TTX - LDR R0, [WsPtr, #ModeFlags] ; now test for non-BBC gap mode - AND R0, R0, #(Flag_GapMode :OR: Flag_BBCGapMode) ; we want R0=0 iff - EOR R0, R0, #Flag_GapMode ; (gapmode AND NOT bbcgapmode) - MOV mask, #&FF000000 ; don't set mask in Wrch4bitTTX - [ :LNOT: HiResTTX -Wrch4bitTTX - ] - AND byte, mask, tophalf, LSL #24 - LDR scrbyte, [bigfont, byte, LSR #22] - STR scrbyte, [screen], linelen - AND byte, mask, tophalf, LSL #16 - LDR scrbyte, [bigfont, byte, LSR #22] - STR scrbyte, [screen], linelen - AND byte, mask, tophalf, LSL #8 - LDR scrbyte, [bigfont, byte, LSR #22] - STR scrbyte, [screen], linelen - AND byte, mask, tophalf - LDR scrbyte, [bigfont, byte, LSR #22] - STR scrbyte, [screen], linelen - - AND byte, mask, bottomhalf, LSL #24 - LDR scrbyte, [bigfont, byte, LSR #22] - STR scrbyte, [screen], linelen - AND byte, mask, bottomhalf, LSL #16 - LDR scrbyte, [bigfont, byte, LSR #22] - STR scrbyte, [screen], linelen - AND byte, mask, bottomhalf, LSL #8 - LDR scrbyte, [bigfont, byte, LSR #22] - STR scrbyte, [screen], linelen - AND byte, mask, bottomhalf - LDR scrbyte, [bigfont, byte, LSR #22] - STR scrbyte, [screen], linelen - - TEQ R0, #0 - MOVNE PC, R14 - AND byte, mask, R10, LSL #8 - LDR scrbyte, [bigfont, byte, LSR #22] ;get 1st extra (0 or for TTX) - STR scrbyte, [screen], linelen - AND byte, mask, R10 - LDR scrbyte, [bigfont, byte, LSR #22] ;get 2nd extra (0 or for TTX) - STR scrbyte, [screen], linelen - MOV PC, R14 - -Wrch8bit - MOV mask, #&FF000000 - - AND byte, mask, tophalf, LSL #24 - ADD byte, bigfont, byte, LSR #21 - LDMIA byte, {scrbyte, scrbyte2} - STMIA screen, {scrbyte, scrbyte2} - ADD screen, screen, linelen - - AND byte, mask, tophalf, LSL #16 - ADD byte, bigfont, byte, LSR #21 - LDMIA byte, {scrbyte, scrbyte2} - STMIA screen, {scrbyte, scrbyte2} - ADD screen, screen, linelen - - AND byte, mask, tophalf, LSL #8 - ADD byte, bigfont, byte, LSR #21 - LDMIA byte, {scrbyte, scrbyte2} - STMIA screen, {scrbyte, scrbyte2} - ADD screen, screen, linelen - - AND byte, mask, tophalf - ADD byte, bigfont, byte, LSR #21 - LDMIA byte, {scrbyte, scrbyte2} - STMIA screen, {scrbyte, scrbyte2} - ADD screen, screen, linelen - - AND byte, mask, bottomhalf, LSL #24 - ADD byte, bigfont, byte, LSR #21 - LDMIA byte, {scrbyte, scrbyte2} - STMIA screen, {scrbyte, scrbyte2} - ADD screen, screen, linelen - - AND byte, mask, bottomhalf, LSL #16 - ADD byte, bigfont, byte, LSR #21 - LDMIA byte, {scrbyte, scrbyte2} - STMIA screen, {scrbyte, scrbyte2} - ADD screen, screen, linelen - - AND byte, mask, bottomhalf, LSL #8 - ADD byte, bigfont, byte, LSR #21 - LDMIA byte, {scrbyte, scrbyte2} - STMIA screen, {scrbyte, scrbyte2} - ADD screen, screen, linelen - - AND byte, mask, bottomhalf - ADD byte, bigfont, byte, LSR #21 - LDMIA byte, {scrbyte, scrbyte2} - STMIA screen, {scrbyte, scrbyte2} - - [ 1=0 ; *** No 8 bpc non-BBC gap modes at present *** - LDR R0, [WsPtr, #ModeFlags] ; now test for non-BBC gap mode - AND R0, R0, #(Flag_GapMode :OR: Flag_BBCGapMode) ; we want R0=0 iff - EORS R0, R0, #Flag_GapMode ; (gapmode AND NOT bbcgapmode) - MOVNE PC, R14 - LDMIA bigfont, {scrbyte, scrbyte2} ; store backgd in next 2 - ADD screen, screen, linelen - STMIA screen, {scrbyte, scrbyte2} - ADD screen, screen, linelen - STMIA screen, {scrbyte, scrbyte2} - ] - MOV PC, R14 - -Wrch16bit - MOV mask, #&FF000000 - SUB linelen, linelen, #16 - - AND byte, mask, tophalf, LSL #24 - ADD byte, bigfont, byte, LSR #20 - LDMIA byte!, {scrbyte, scrbyte2} - STMIA screen!, {scrbyte, scrbyte2} - LDMIA byte!, {scrbyte, scrbyte2} - STMIA screen!, {scrbyte, scrbyte2} - ADD screen, screen, linelen - - AND byte, mask, tophalf, LSL #16 - ADD byte, bigfont, byte, LSR #20 - LDMIA byte!, {scrbyte, scrbyte2} - STMIA screen!, {scrbyte, scrbyte2} - LDMIA byte!, {scrbyte, scrbyte2} - STMIA screen!, {scrbyte, scrbyte2} - ADD screen, screen, linelen - - AND byte, mask, tophalf, LSL #8 - ADD byte, bigfont, byte, LSR #20 - LDMIA byte!, {scrbyte, scrbyte2} - STMIA screen!, {scrbyte, scrbyte2} - LDMIA byte!, {scrbyte, scrbyte2} - STMIA screen!, {scrbyte, scrbyte2} - ADD screen, screen, linelen - - AND byte, mask, tophalf - ADD byte, bigfont, byte, LSR #20 - LDMIA byte!, {scrbyte, scrbyte2} - STMIA screen!, {scrbyte, scrbyte2} - LDMIA byte!, {scrbyte, scrbyte2} - STMIA screen!, {scrbyte, scrbyte2} - ADD screen, screen, linelen - - AND byte, mask, bottomhalf, LSL #24 - ADD byte, bigfont, byte, LSR #20 - LDMIA byte!, {scrbyte, scrbyte2} - STMIA screen!, {scrbyte, scrbyte2} - LDMIA byte!, {scrbyte, scrbyte2} - STMIA screen!, {scrbyte, scrbyte2} - ADD screen, screen, linelen - - AND byte, mask, bottomhalf, LSL #16 - ADD byte, bigfont, byte, LSR #20 - LDMIA byte!, {scrbyte, scrbyte2} - STMIA screen!, {scrbyte, scrbyte2} - LDMIA byte!, {scrbyte, scrbyte2} - STMIA screen!, {scrbyte, scrbyte2} - ADD screen, screen, linelen - - AND byte, mask, bottomhalf, LSL #8 - ADD byte, bigfont, byte, LSR #20 - LDMIA byte!, {scrbyte, scrbyte2} - STMIA screen!, {scrbyte, scrbyte2} - LDMIA byte!, {scrbyte, scrbyte2} - STMIA screen!, {scrbyte, scrbyte2} - ADD screen, screen, linelen - - AND byte, mask, bottomhalf - ADD byte, bigfont, byte, LSR #20 - LDMIA byte!, {scrbyte, scrbyte2} - STMIA screen!, {scrbyte, scrbyte2} - LDMIA byte!, {scrbyte, scrbyte2} - STMIA screen!, {scrbyte, scrbyte2} - - [ 1=0 ; *** No 16 bpc non-BBC gap modes at present *** - LDR R0, [WsPtr, #ModeFlags] ; now test for non-BBC gap mode - AND R0, R0, #(Flag_GapMode :OR: Flag_BBCGapMode) ; we want R0=0 iff - EORS R0, R0, #Flag_GapMode ; (gapmode AND NOT bbcgapmode) - MOVNE PC, R14 - LDMIA bigfont, {scrbyte, scrbyte2} ; store backgd in next 2 - ADD screen, screen, linelen - STMIA screen!, {scrbyte, scrbyte2} - STMIA screen!, {scrbyte, scrbyte2} - ADD screen, screen, linelen - STMIA screen!, {scrbyte, scrbyte2} - STMIA screen!, {scrbyte, scrbyte2} - ] - MOV PC, R14 - -; ***************************************************************************** - -; Write a character at 32 bit per pixel -; -; NB: This code assumes that we have no concept of gap modes. - -Wrch32bit - Push "R0-R1,R5-R7,R9-R10,R12,LR" - - MOV mask, #&FF000000 - - AND byte, mask, tophalf, LSL #24 - ADD byte, bigfont, byte, LSR #19 - LDMIA byte, {R0,R1, R6,R7, R9,R10, R12,LR} - STMIA screen, {R0,R1, R6,R7, R9,R10, R12,LR} - ADD screen, screen, linelen - - AND byte, mask, tophalf, LSL #16 - ADD byte, bigfont, byte, LSR #19 - LDMIA byte, {R0,R1, R6,R7, R9,R10, R12,LR} - STMIA screen, {R0,R1, R6,R7, R9,R10, R12,LR} - ADD screen, screen, linelen - - AND byte, mask, tophalf, LSL #8 - ADD byte, bigfont, byte, LSR #19 - LDMIA byte, {R0,R1, R6,R7, R9,R10, R12,LR} - STMIA screen, {R0,R1, R6,R7, R9,R10, R12,LR} - ADD screen, screen, linelen - - AND byte, mask, tophalf - ADD byte, bigfont, byte, LSR #19 - LDMIA byte, {R0,R1, R6,R7, R9,R10, R12,LR} - STMIA screen, {R0,R1, R6,R7, R9,R10, R12,LR} - ADD screen, screen, linelen - - LDR bottomhalf, [SP, #4*3] ; restore 'bottomhalf' (R6 pushed onto stack) - - AND byte, mask, bottomhalf, LSL #24 - ADD byte, bigfont, byte, LSR #19 - LDMIA byte, {R0,R1, R5,R7, R9,R10, R12,LR} - STMIA screen, {R0,R1, R5,R7, R9,R10, R12,LR} - ADD screen, screen, linelen - - AND byte, mask, bottomhalf, LSL #16 - ADD byte, bigfont, byte, LSR #19 - LDMIA byte, {R0,R1, R5,R7, R9,R10, R12,LR} - STMIA screen, {R0,R1, R5,R7, R9,R10, R12,LR} - ADD screen, screen, linelen - - AND byte, mask, bottomhalf, LSL #8 - ADD byte, bigfont, byte, LSR #19 - LDMIA byte, {R0,R1, R5,R7, R9,R10, R12,LR} - STMIA screen, {R0,R1, R5,R7, R9,R10, R12,LR} - ADD screen, screen, linelen - - AND byte, mask, bottomhalf - ADD byte, bigfont, byte, LSR #19 - LDMIA byte, {R0,R1, R5,R7, R9,R10, R12,LR} - STMIA screen, {R0,R1, R5,R7, R9,R10, R12,LR} - ADD screen, screen, linelen - - Pull "R0-R1,R5,R6,R7,R9-R10,R12,PC" - - -; ***************************************************************************** -; -; BS - Backspace -; move cursor "left" -; -; in: R6 = CursorFlags -; - -BS - TST R6, R6, ROR #10 ; test &1E or C81Bit or Vdu5 - BNE SpecialBS - - LDR R0, [WsPtr, #CursorX] - LDR R2, [WsPtr, #CursorAddr] - [ HiResTTX - LDR R3, [WsPtr, #CharWidth] - | - LDR R3, [WsPtr, #BytesPerChar] - ] - LDR R4, [WsPtr, #TWLCol] - - SUB R0, R0, #1 ; no Master wazerks yet ! - SUB R2, R2, R3 - CMP R0, R4 - STRGE R0, [WsPtr, #CursorX] ; I do mean GE ! - STRGE R2, [WsPtr, #CursorAddr] - MOVGE PC, R14 - - MOV R0, #0 - LDRB R1, [R0, #OsbyteVars + :INDEX: PageModeLineCount] - TEQ R1, #0 - SUBNE R1, R1, #1 - STRB R1, [R0, #OsbyteVars + :INDEX: PageModeLineCount] - - LDR R0, [WsPtr, #TWRCol] - LDR R1, [WsPtr, #CursorY] - LDR R4, [WsPtr, #TWTRow] - - SUB R1, R1, #1 - CMP R1, R4 - - BGE CursorR0R1 - - STR R0, [WsPtr, #CursorX] - BSR ScrollDown - B AddressCursor - -; ***************************************************************************** -; -; Horizontal TAB - ie move cursor "right" -; -; in: R6 = CursorFlags -; - -HT - TST R6, R6, ROR #10 ; test for &1E or C81Bit or Vdu5 - BNE SpecialHT - - LDR R0, [WsPtr, #CursorX] - LDR R2, [WsPtr, #CursorAddr] - [ HiResTTX - LDR R3, [WsPtr, #CharWidth] - | - LDR R3, [WsPtr, #BytesPerChar] - ] - LDR R4, [WsPtr, #TWRCol] - - ADD R0, R0, #1 - ADD R2, R2, R3 - CMP R0, R4 - STRLS R0, [WsPtr, #CursorX] - STRLS R2, [WsPtr, #CursorAddr] - MOVLS PC, R14 - - BSR PageTest - - LDR R0, [WsPtr, #TWLCol] - LDR R1, [WsPtr, #CursorY] - LDR R4, [WsPtr, #TWBRow] - - ADD R1, R1, #1 - CMP R1, R4 - BLS CursorR0R1 ; not on bottom line - - STR R0, [WsPtr, #CursorX] - BSR ScrollUp - B AddressCursor ; re-address cursor position - -; ***************************************************************************** -; -; VduLF - Line feed -; -; in: R6 = CursorFlags -; - -VduLF - TST R6, #Vdu5Bit - BNE Vdu5LF - - BSR PageTest ; check for CTRL/SHIFT, page mode - - TST R6, R6, ROR #10 - BNE SpecialLF - - LDR R1, [WsPtr, #CursorY] - LDR R2, [WsPtr, #CursorAddr] - LDR R3, [WsPtr, #RowLength] - LDR R4, [WsPtr, #TWBRow] - - ADD R1, R1, #1 ; no Master wazerks - ADD R2, R2, R3 - CMP R1, R4 - STRLS R1, [WsPtr, #CursorY] - STRLS R2, [WsPtr, #CursorAddr] - MOVLS PC, R14 - - BSR ScrollUp - B AddressCursor - -; ***************************************************************************** -; -; VT - Cursor up -; - -VT - LDR R6, [WsPtr, #CursorFlags] - TST R6, #Vdu5Bit - BNE Vdu5VT - - MOV R0, #0 - LDRB R1, [R0, #OsbyteVars + :INDEX: PageModeLineCount] - TEQ R1, #0 - SUBNE R1, R1, #1 - STRB R1, [R0, #OsbyteVars + :INDEX: PageModeLineCount] - - TST R6, R6, ROR #10 - BNE SpecialVT - - LDR R1, [WsPtr, #CursorY] - LDR R2, [WsPtr, #CursorAddr] - LDR R3, [WsPtr, #RowLength] - LDR R4, [WsPtr, #TWTRow] - - SUB R1, R1, #1 - SUB R2, R2, R3 - CMP R1, R4 - STRGE R1, [WsPtr, #CursorY] - STRGE R2, [WsPtr, #CursorAddr] - MOVGE PC, R14 - - BSR ScrollDown - B AddressCursor - -; ***************************************************************************** -; -; VduCR - Carriage return -; move to "left" boundary -; -; in: R6 = CursorFlags -; -; out: R6 = updated CursorFlags - -VduCR -CR10 ; entry point for releasing pending CRLF - TST R6, #Vdu5Bit - BNE Vdu5CR - - BIC R6, R6, #C81Bit ; destroy pending CRLF - STR R6, [WsPtr, #CursorFlags] - Push R14 - BL CursorB0 ; preserves R6 - BL AddressCursor ; preserves R6 - Pull PC - -; ***************************************************************************** -; -; FS - Define text window -; - -FS ROUT - LDRB R0, [WsPtr, #QQ+0] ; left - LDRB R1, [WsPtr, #QQ+1] ; bottom - LDRB R2, [WsPtr, #QQ+2] ; right - LDRB R3, [WsPtr, #QQ+3] ; top - LDR R4, [WsPtr, #ScrRCol] ; max right - LDR R5, [WsPtr, #ScrBRow] ; max bottom - - LDR R6, [WsPtr, #VduStatus] - ORR R6, R6, #Windowing ; we are windowing - STR R6, [WsPtr, #VduStatus] - -; Secondary entry point, for validating unpacked context variables -; NB doesn't want to set windowing bit - -FSRegs - CMP R2, R0 ; right >= left - CMPCS R4, R2 ; max right >= right - CMPCS R1, R3 ; bottom >= top - CMPCS R5, R1 ; max bottom >= bottom - MOVCC PC, R14 ; invalid window - - ADD R6, WsPtr, #TWLCol - STMIA R6, {R0-R3} ; write new window settings - -; now check for input cursor being outside window - - LDR R6, [WsPtr, #CursorFlags] - TST R6, #CursorsSplit - BEQ %FT10 ; [cursors not split] - - ASSERT InputCursorY = InputCursorX +4 - ADD R6, WsPtr, #InputCursorX ; R6 := InputCursorX - LDMIA R6, {R6, R7} ; R7 := InputCursorY - - CMP R6, R0 ; X >= left - CMPCS R2, R6 ; right >= X - CMPCS R7, R3 ; Y >= top - CMPCS R1, R7 ; bottom >= Y - - BCS %FT10 ; [not outside window] - - LDR R6, [WsPtr, #CursorX] ; get output cursor posn - LDR R7, [WsPtr, #CursorY] - LDR R4, [WsPtr, #CursorAddr] - Push "R0-R4, R6, R7, R14" ; save window and output cursor - - BL HomeVdu4 ; Home output cursor - - LDR R6, [WsPtr, #CursorX] ; Copy output ... - LDR R7, [WsPtr, #CursorY] - LDR R4, [WsPtr, #CursorAddr] - - STR R6, [WsPtr, #InputCursorX] ; ... to input - STR R7, [WsPtr, #InputCursorY] - STR R4, [WsPtr, #InputCursorAddr] - - Pull "R0-R4, R6, R7, R14" ; restore old registers - STR R6, [WsPtr, #CursorX] - STR R7, [WsPtr, #CursorY] - STR R4, [WsPtr, #CursorAddr] -10 - -; now check output cursor is inside window - - LDR R6, [WsPtr, #CursorX] ; get output cursor posn - LDR R7, [WsPtr, #CursorY] - - CMP R6, R0 ; X >= left - CMPCS R2, R6 ; right >= X - CMPCS R7, R3 ; Y >= top - CMPCS R1, R7 ; bottom >= Y - - MOVCS PC, R14 ; cursor inside window - -; and drop thru to ... - -HomeVdu4 ; home TEXT cursor, even in - ; VDU 5 mode - MOV R0, #0 ; move to "0,0" - MOV R1, #0 - LDR R6, [WsPtr, #CursorFlags] - - B TabR0R1NotVdu5 ; (destroys any pending CRLF) - -; ***************************************************************************** -; -; TCOL - Set text colour (foreground or background) -; - ASSERT TBackCol = TForeCol +4 - ASSERT back > fore - -TCOL -DC1 - TST R6, #TeletextMode ; if in teletext - MOVNE PC, R14 ; then ignore - - LDR bpp, [WsPtr, #BitsPerPix] - ADD fore, WsPtr, #TForeCol - LDMIA fore, {fore, back} - - LDR R3, [WsPtr, #NColour] - LDRB R4, [WsPtr, #QQ+0] ; get colour specified - CMP R4, #128 ; C=1 => set background - AND R4, R4, R3 - AND R4, R4, #63 ; oh no not again! - STRCC R4, [WsPtr, #TForeCol] - STRCS R4, [WsPtr, #TBackCol] - MOVCC R5, fore - MOVCS R5, back ; R5 is old appropriate colour - MOVCC fore, R4 - MOVCS back, R4 - - BCS %FT31 ; branch for background - - ; amg: only update the appropriate one - CMP R4,R5 - MOVEQ PC, R14 - Push "LR" - BL CompileTextFg - Pull "LR" - B %FT32 -31 - CMP R4, R5 - MOVEQ PC, R14 ; same as last time - Push "LR" - BL CompileTextBg ; ensure that TextBg is kosher - Pull "LR" ; preserving the return address -32 - LDR R6, [WsPtr, #CursorFlags] - ORR R6, R6, #TEUpdate -R6toCursorFlags - STR R6, [WsPtr, #CursorFlags] - - MOV PC, R14 - -CheckTEUpdate - LDR R6, [WsPtr, #CursorFlags] - TST R6, #TEUpdate - MOVEQ PC, R14 -ReallySetColours - BIC R6, R6, #TEUpdate - STR R6, [WsPtr, #CursorFlags] ; clear update flag - - Push "R6, R14" - LDR bpp, [WsPtr, #BitsPerPix] - LDR fore, [WsPtr, #TextFgColour] - LDR back, [WsPtr, #TextBgColour] - BL SetColours - Pull "R6, PC" - -; ***************************************************************************** -; -; FF - Clear text window (CLS) -; - -FF - LDR R6, [WsPtr, #CursorFlags] - TST R6, #Vdu5Bit - BNE Vdu5FF - - STROSB R0, PageModeLineCount, R0 ; zero page mode line count - - LDR R0, [WsPtr, #VduStatus] - TST R0, #Windowing - BNE SlowCLS ; windowing, so do slowly - - Push R14 - TST R6, #ClipBoxEnableBit - BLNE SetClipBoxToFullScreen - LDR R0, [WsPtr, #DriverBankAddr] ; set driver's screen start - STR R0, [WsPtr, #ScreenStart] - BL SetDisplayScreenStart - - LDR R0, [WsPtr, #DisplayBankAddr] - BL SetVinit ; program Vinit - ; (and set DisplayStart) - BL Home ; home cursor after ScreenStart initialised - TST R6, #CursorsSplit - BLNE AddressInputCursor - Pull R14 - - LDR R0, [WsPtr, #ModeFlags] - TST R0, #Flag_BBCGapMode ; if not BBC gap mode - BEQ FastCLS ; then use fast code - -SlowCLS - BSR Home - - ADD R0, WsPtr, #TWLCol ; R0 := TWLCol; R1 := TWBRow - LDMIA R0, {R0-R3} ; R2 := TWRCol; R3 := TWTRow - -; and drop thru to ... - -; ClearBox - Clears a box of text chars on the screen -; -; in: R0 = left column -; R1 = bottom row -; R2 = right column -; R3 = top row - -ClearBox ROUT - Push R14 - TST R6, #ClipBoxEnableBit - BLNE ClipTextArea - - TST R6, #TeletextMode - BNE TTXClearBox - - BL GetBoxInfo - Pull R14 - -ClearThisBox - STR R8, [WsPtr, #RowsToDo] - - LDR R9, [WsPtr, #CursorFlags] - TST R9, #TEUpdate - BNE %FT99 - -05 - LDR R8, [WsPtr, #TextBgColour] - LDRB R1, [WsPtr, #ModeFlags] - TST R1, #Flag_BBCGapMode ; is it a BBC gap mode ? - LDRNE R1, =&AAAAAAAA ; use colour 2 for gaps if so - MOVEQ R1, R8 ; else use background colour - EOR R1, R1, R8 ; EOR toggle for colour - STR R1, [WsPtr, #EORtoggle] - LDR R0, [WsPtr, #RowMult] ; 8 or 10 - -ClearRow - MOV R6, #0 -ClearLineNew - MOV R9, R8 - MOV R10, R8 - MOV R11, R8 -ClearLine - MOV R1, R2 ; R1 is current address - ADD R3, R2, R5 ; R3 is byte after last one -10 - CMP R1, R3 - BEQ DoneLine - TST R1, #3 - STRNEB R8, [R1], #1 ; store if not on word boundary - BNE %BT10 - - SUB R4, R3, R1 ; number of bytes left on this line - MOV R4, R4, LSR #4 ; number of 4-words left on this line - SUBS R4, R4, #1 ; C=0 if 0, C=1 if >0 -14 - STMHIIA R1!, {R8-R11} ; done if R4 > 0 - STMCSIA R1!, {R8-R11} ; done if R4 >= 0 - SUBCSS R4, R4, #2 ; this code dropped thru if R4 was 0 - BCS %BT14 - - BIC R4, R3, #3 -20 - CMP R1, R4 - STRNE R8, [R1], #4 - BNE %BT20 - -30 - CMP R1, R3 - STRNEB R8, [R1], #1 - BNE %BT30 - -DoneLine - ADD R2, R2, R7 - ADD R6, R6, #1 - CMP R6, #8 - BCC ClearLine - LDR R1, [WsPtr, #EORtoggle] - EOREQ R8, R8, R1 - CMP R6, R0 - BCC ClearLineNew - - EOR R8, R8, R1 - LDR R1, [WsPtr, #RowsToDo] - SUBS R1, R1, #1 - STR R1, [WsPtr, #RowsToDo] - BNE ClearRow - - MOV PC, R14 - -99 - Push "R2, R5-R7, R14" - MOV R6, R9 - BL ReallySetColours - Pull "R2, R5-R7, R14" - B %BT05 - - LTORG - -; ***************************************************************************** -; -; GetWindowInfo - sets up some info for current text window -; -; GetBoxInfo - sets up some info for a given box -; -; in: R0 = left -; R1 = bottom -; R2 = right -; R3 = top -; -; out: R2 = address of top left -; R5 = number of bytes horizontally -; R6 = number of pixel rows vertically -; R7 = LineLength -; R8 = number of character rows vertically - -GetWindowInfo - ADD R0, WsPtr, #TWLCol ; R0 := TWLCol; R1 := TWBRow - LDMIA R0, {R0-R3} ; R2 := TWRCol; R3 := TWTRow -GetBoxInfo - SUB R5, R2, R0 - ADD R5, R5, #1 ; number of chars horiz - LDR R6, [WsPtr, #Log2BPC] ; should be log2 bytes/char - MOV R5, R5, LSL R6 ; number of bytes horiz - - SUB R6, R1, R3 - ADD R8, R6, #1 ; number of char rows vert - - LDR R7, [WsPtr, #ModeFlags] - - MOV R6, R8, LSL #3 ; *8 - TST R7, #Flag_GapMode ; if gap mode - ADDNE R6, R6, R8, LSL #1 ; (+*2) = *10 - TST R7, #Flag_DoubleVertical ; if double mode - ADDNE R6, R6, R6 ; then double - - LDR R7, [WsPtr, #LineLength] - - MOV R1, R3 ; prepare to address top left - B AddressR0R1 - - [ UseGraphicsV -; -; TextWindowToGraphics - current text window converted to graphics -; -; TextBoxToGraphics - given text box converted to graphics coordinates -; -; in: R0 = left -; R1 = bottom -; R2 = right -; R3 = top -; -; out: R0-R3 converted to internal graphics coordinates -; R5 = number of pixels horizontally -; R6 = number of pixel rows vertically -; R7 = row height in pixels -; R8 = number of character rows vertically - -ScreenToGraphics - MOV R0, #0 - LDR R1, [WsPtr, #ScrBRow] - LDR R2, [WsPtr, #ScrRCol] - MOV R3, #0 - B TextBoxToGraphics - -TextWindowToGraphics - ADD R0, WsPtr, #TWLCol ; R0 := TWLCol; R1 := TWBRow - LDMIA R0, {R0-R3} ; R2 := TWRCol; R3 := TWTRow -TextBoxToGraphics - SUB R5, R2, R0 - ADD R5, R5, #1 ; number of chars horiz - [ HiResTTX - LDR R6, [WsPtr, #CharWidth] ; bytes/char (not log2) - LDR R7, [WsPtr, #Log2BPP] ; log2 bits/pixel - - MUL R0, R6, R0 ; number of bytes horiz - MUL R5, R6, R5 - SUB R7, R7, #3 ; log2 bytes/pixel - | - LDR R6, [WsPtr, #Log2BPC] ; should be log2 bytes/char - LDR R7, [WsPtr, #Log2BPP] ; should be log2 bits/pixel - ADD R6, R6, #3 - - MOV R0, R0, LSL R6 ; number of bits horiz - MOV R5, R5, LSL R6 - ] - MOV R0, R0, LSR R7 ; number of pixels horiz - MOV R5, R5, LSR R7 - ADD R2, R0, R5 ; recalculate right coord - SUB R2, R2, #1 - - LDR R6, [WsPtr, #ModeFlags] - - MOV R7, #8 ; 8 pixels high - TST R6, #Flag_GapMode ; if gap mode - MOVNE R7, #10 ; then 10 pixels high - TST R6, #Flag_DoubleVertical ; if double mode - ADDNE R7, R7, R7 ; then double - - SUB R8, R1, R3 - ADD R8, R8, #1 ; number of char rows vert - MUL R3, R7, R3 ; convert top to pixels (from top) - MUL R6, R7, R8 ; convert height to pixels - LDR R1, [WsPtr, #YWindLimit] - SUB R3, R1, R3 ; Y-flip coordinate (bottom-left = 0,0) - SUB R1, R3, R6 ; recalculate bottom coord - ADD R1, R1, #1 - - MOV PC, R14 - ] - -; ***************************************************************************** -; -; US - TAB(X,Y) -; - -US - LDRB R0, [WsPtr, #QQ+0] - LDRB R1, [WsPtr, #QQ+1] -TabR0R1 - - LDR R6, [WsPtr, #CursorFlags] - TST R6, #Vdu5Bit - BNE Vdu5TAB - -TabR0R1NotVdu5 - LDR R9, [WsPtr, #CursorX] - LDR R10, [WsPtr, #CursorY] - Push "R0,R9,R10" ; save old X,Y in case it doesn't work - - EOR R6, R6, #8 ; update Y position - MOV R0, R1 - BSR CursorBdy - - EOR R6, R6, #8 ; now try X position - Pull R0 - BSR CursorBdyCheck - MOV R7, #0 ; will be clearing C81Bit - BCS US10 ; was in window, so OK - - TEQ R6, R6, LSR #1 ; are we in 81 column mode - ; (just want to set carry) - BCC US20 ; can't do it - - SUB R0, R0, #1 ; could be attempt to move to col 81 - BSR CursorBdyCheck - BCC US20 ; still can't do it - MOV R7, #C81Bit ; set C81Bit -US10 - BIC R6, R6, #C81Bit - ORR R6, R6, R7 - STR R6, [WsPtr, #CursorFlags] - -US20 - Pull "R9,R10" - - STRCC R9, [WsPtr, #CursorX] ; couldn't do it, so restore position - STRCC R10, [WsPtr, #CursorY] - - B AddressCursor - -; ***************************************************************************** -; -; ScrollUp - Scroll the current text window up -; - -ScrollUp - LDR R0, [WsPtr, #VduStatus] - TST R0, #Windowing - BNE SoftScrollUp -HardScrollUp - LDR R1, [WsPtr, #ModeFlags] - TST R1, #Flag_HardScrollDisabled - BNE HardScrollSpriteUp - - Push R14 - LDR R1, [WsPtr, #RowLength] - LDR R2, [WsPtr, #TotalScreenSize] - LDR R14, [WsPtr, #ScreenEndAddr] - - LDR R0, [WsPtr, #DisplayScreenStart] - ADD R0, R0, R1 - CMP R0, R14 - SUBCS R0, R0, R2 - BL SetDisplayScreenStart - LDR R14, [WsPtr, #ScreenEndAddr] - STR R0, [WsPtr, #ScreenStart] - - LDR R0, [WsPtr, #DisplayStart] - ADD R0, R0, R1 - CMP R0, R14 - SUBCS R0, R0, R2 - - BL SetVinit ; program vinit and set DisplayStart - - TST R6, #TeletextMode - BLNE TTXHardScrollUp - Pull R14 - -ClearBottomScreenLine - MOV R0, #0 ; Don't use window coords - - LDR R1, [WsPtr, #ScrBRow] ; code also used in VDU23,7 - LDR R2, [WsPtr, #ScrRCol] - MOV R3, R1 - B ClearBox - -; Code to scroll whole 'screen' up, when hard scroll disabled -; (ie outputting to sprite) - -HardScrollSpriteUp - Push R14 - TST R6, #TeletextMode - BNE TTXSoftScrollUp - [ UseGraphicsV - BL TryCopyScreenUp - Pull R14,EQ - BEQ ClearBottomScreenLine - ] - BL GetScreenInfo ; get box info for whole 'screen' - LDR R0, [WsPtr, #RowMult] - BL SoftScrollUp2 - Pull R14 - B ClearBottomScreenLine - -; Clear bottom line of window - -ClearBottomLine - ADD R0, WsPtr, #TWLCol ; R0 := TWLCol; R1 := TWBRow - LDMIA R0, {R0-R2} ; R2 := TWRCol - MOV R3, R1 ; R3 := TWBRow - B ClearBox - -SoftScrollUp - Push R14 - TST R6, #TeletextMode - BNE TTXSoftScrollUp - - [ UseGraphicsV - BL TryCopyWindowUp - Pull R14, EQ - BEQ ClearBottomLine - ] - BL GetWindowInfo - -; R2 = address of top left -; R5 = number of bytes horizontally -; R6 = number of pixel rows in box -; R7 = linelength -; R8 = number of character rows in box - - LDR R0, [WsPtr, #RowMult] - BL SoftScrollUp2 - Pull R14 - B ClearBottomLine - -; ***************************************************************************** -; -; SoftScrollUp2 - Called by SoftScrollUp and by Teletext to scroll map -; -; in: R0 = RowMult -; R2 = screen address of top left of area to scroll -; R5 = number of bytes horizontally -; R6 = number of pixel rows vertically -; R7 = linelength -; - -SoftScrollUp2 ROUT - SUBS R6, R6, R0 ; scroll number of rows-1 - MOVEQ PC, R14 ; single row window, nowt to scroll - -ScrollLineUp - MOV R1, R2 - LDR R3, [WsPtr, #RowLength] - ADD R0, R1, R3 ; R0 -> line below - ADD R3, R2, R5 ; R3 -> byte after last one on upper -10 - CMP R1, R3 - BEQ %FT40 ; finished - TST R1, #3 ; if not word aligned - LDRNEB R8, [R0], #1 ; then copy a byte - STRNEB R8, [R1], #1 - BNE %BT10 - - SUB R4, R3, R1 ; number of bytes left on this line - MOVS R4, R4, LSR #4 ; number of 4-words left on this line - SUBS R4, R4, #1 ; C=0 if 0, C=1 if >0 -14 - LDMHIIA R0!, {R8-R11} ; this code dropped thru if was 0 - STMHIIA R1!, {R8-R11} - LDMCSIA R0!, {R8-R11} - STMCSIA R1!, {R8-R11} - SUBCSS R4, R4, #2 - BCS %BT14 - - BIC R4, R3, #3 -20 - CMP R1, R4 - LDRNE R8, [R0], #4 - STRNE R8, [R1], #4 - BNE %BT20 - -30 - CMP R1, R3 - LDRNEB R8, [R0], #1 - STRNEB R8, [R1], #1 - BNE %BT30 - -40 - ADD R2, R2, R7 - SUBS R6, R6, #1 - BNE ScrollLineUp - - MOV PC, R14 - - [ UseGraphicsV -; ***************************************************************************** -; -; TryCopyScreenUp - use GraphicsV to copy screen up -; -; in: nothing -; out: R0-R11 corrupted -; Z flag set if successful - -TryCopyScreenUp - Push R14 - BL CheckAcceleration - Pull PC, NE ; return with Z clear (unsuccessful) - BL ScreenToGraphics -TryCopyUpCommon - SUB R4, R2, R0 ; width-1 - SUB R5, R3, R1 ; height-1 - SUBS R5, R5, R7 ; less one row - Pull PC,MI ; return with Z clear (unsuccessful) - MOV R2, R0 ; dstL=srcL - ADD R3, R1, R7 ; dstB=srcB +1row - Push "R0-R5" - MOV R0, #3 - MOV R1, #1 - MOV R2, R13 - MOV R4, #GraphicsV_Render - BL CallGraphicsV - ADD R13, R13, #6*4 - TEQ R4, #GraphicsV_Complete - Pull PC - -; ............................................................................. -; -; TryCopyWindowUp - use GraphicsV to copy window up -; -; in: nothing -; out: R0-R11 corrupted -; Z flag set if successful - -TryCopyWindowUp - LDR R0, [WsPtr, #VduSprite] - TEQ R0, #0 ; don't try it if outputting to sprite - MOVNE PC, R14 ; return with Z clear (unsuccessful) - Push R14 - ADR R14, TryCopyUpCommon - B TextWindowToGraphics - ] - -; ***************************************************************************** -; -; ScrollDown - Scroll the current text window down -; - -ScrollDown - LDR R0, [WsPtr, #VduStatus] - TST R0, #Windowing - BNE SoftScrollDown -HardScrollDown - LDR R1, [WsPtr, #ModeFlags] - TST R1, #Flag_HardScrollDisabled - BNE HardScrollSpriteDown - - Push R14 - LDR R1, [WsPtr, #RowLength] - LDR R2, [WsPtr, #TotalScreenSize] - LDR R14, [WsPtr, #ScreenEndAddr] - - LDR R0, [WsPtr, #DisplayScreenStart] - SUB R0, R0, R1 ; down one row - ADD R3, R0, R2 - CMP R3, R14 ; if < then need wrap - MOVCC R0, R3 - BL SetDisplayScreenStart - LDR R14, [WsPtr, #ScreenEndAddr] - STR R0, [WsPtr, #ScreenStart] - - LDR R0, [WsPtr, #DisplayStart] - SUB R0, R0, R1 - ADD R3, R0, R2 - CMP R3, R14 - MOVCC R0, R3 - - BL SetVinit ; program vinit and set DisplayStart - - TST R6, #TeletextMode - BLNE TTXHardScrollDown - Pull R14 - -ClearTopScreenLine - MOV R0, #0 ; don't use window coords - - MOV R1, #0 ; code also used by VDU23,7 - LDR R2, [WsPtr, #ScrRCol] - MOV R3, #0 - B ClearBox - -; Code to scroll whole 'screen' down, when hard scroll disabled -; (ie outputting to sprite) - -HardScrollSpriteDown - Push R14 - TST R6, #TeletextMode - BNE TTXSoftScrollDown - BL GetScreenInfo ; get box info for whole 'screen' - - MOV R0, #0 - LDR R1, [WsPtr, #ScrBRow] - BL AddressR0R1 ; R2 -> top line of bottom left char - - LDR R0, [WsPtr, #RowMult] - BL SoftScrollDown2 - Pull R14 - B ClearTopScreenLine - -; Clear top line of window - -ClearTopLine - ADD R0, WsPtr, #TWLCol ; R0 := TWLCol; (R1 := TWBRow) - LDMIA R0, {R0-R3} ; R2 := TWRCol; R3 := TWTRow - MOV R1, R3 ; R1 := TWTRow - B ClearBox - -SoftScrollDown - Push R14 - TST R6, #TeletextMode - BNE TTXSoftScrollDown - - BL GetWindowInfo - -; R2 = address of top left -; R5 = number of bytes horizontally -; R6 = number of pixel rows in box -; R7 = linelength -; R8 = number of character rows in box - - ADD R0, WsPtr, #TWLCol ; R0 := TWLCol; R1 := TWBRow - LDMIA R0, {R0-R1} - BL AddressR0R1 ; R2 -> top line of bottom left char - - LDR R0, [WsPtr, #RowMult] - BL SoftScrollDown2 - Pull R14 - B ClearTopLine - -; ***************************************************************************** -; -; SoftScrollDown2 - Called by SoftScrollDown and by TTX to scroll map -; -; in: R0 = RowMult -; R2 = screen address of top line of bottom left char -; R5 = number of bytes horizontally -; R6 = number of pixel rows vertically -; R7 = linelength -; - -SoftScrollDown2 ROUT - SUBS R6, R6, R0 ; scroll number of rows-1 - MOVEQ PC, R14 ; single row window, nowt to scroll - - SUB R2, R2, R7 ; R2 -> bottom line of next-to-bottom - LDR R1, [WsPtr, #RowLength] - ADD R2, R2, R1 ; R2 -> bottom line of bottom - -ScrollLineDown - MOV R1, R2 - LDR R3, [WsPtr, #RowLength] - SUB R0, R1, R3 ; R0 -> line above,needs fudging - ADD R3, R2, R5 ; R3 -> byte after last one on upper -10 - CMP R1, R3 - BEQ %FT40 ; finished - TST R1, #3 - LDRNEB R8, [R0], #1 - STRNEB R8, [R1], #1 - BNE %BT10 - - SUB R4, R3, R1 ; number of bytes left on this line - MOVS R4, R4, LSR #4 ; number of 4-words left on this line - SUBS R4, R4, #1 ; C=0 if 0, C=1 if >0 -14 - LDMHIIA R0!, {R8-R11} ; this code dropped thru if was 0 - STMHIIA R1!, {R8-R11} - LDMCSIA R0!, {R8-R11} - STMCSIA R1!, {R8-R11} - SUBCSS R4, R4, #2 - BCS %BT14 - - BIC R4, R3, #3 -20 - CMP R1, R4 - LDRNE R8, [R0], #4 - STRNE R8, [R1], #4 - BNE %BT20 - -30 - CMP R1, R3 - LDRNEB R8, [R0], #1 - STRNEB R8, [R1], #1 - BNE %BT30 - -40 - SUB R2, R2, R7 - SUBS R6, R6, #1 - BNE ScrollLineDown - - MOV PC, R14 - -; ***************************************************************************** -; -; SetVinit - Program Vinit with address in R0 -; SetVstart - Program Vstart with address in R0 -; SetVendDefault - Program Vend with end address for TotalScreenSize -; -; out: R0-R2 corrupted -; - -; mjs Oct 2000 kernel/HAL split -; these routines now call HAL_Video_SetDAG - -; Note that the addresses provided are logical addresses for the software mapping -; of the display, and this starts at (ScreenEndAddr - TotalScreenSize) for -; wonderful historical reasons (h/w scroll, two mappings, blah, blah) - see eg. PRM 1-354 -; -; To get physical address for the HAL, we subtract this software mapping start -; address and add the physical address of the start of video memory. -; - -SetVstart - LDR r2, [WsPtr, #ScreenEndAddr] - SUB r1, r0, r2 - LDR r2, [WsPtr, #TotalScreenSize] - ADD r1, r1, r2 ; now we have offset of Vstart in video RAM - MOV r2, #0 - LDR r2, [r2, #VideoPhysAddr] - ADD r1, r1, r2 ; now we have physical address of Vstart - MOV r0, #HALDAG_VStart - B Do_HALDAG - -SetVendDefault - MOV r2, #0 - LDR r2, [r2, #VideoPhysAddr] - LDR r1, [WsPtr, #TotalScreenSize] - ADD r1, r1, r2 ; physical address of Vend - MOV r0, #HALDAG_VEnd - B Do_HALDAG - -SetDisplayScreenStart - Push "r0-r2,lr" - BL SetVrender - Pull "r0-r2,pc" - -SetVrender - STR r0, [WsPtr, #DisplayScreenStart] - LDR r2, [WsPtr, #ScreenEndAddr] - SUB r1, r0, r2 - LDR r2, [WsPtr, #TotalScreenSize] - ADD r1, r1, r2 ; now we have offset of Vrender in video RAM - LDR r0, [WsPtr, #TeletextOffset] - ADD r1, r1, r0 ; add on teletext bank offset - CMP r1, r2 ; if out of range - SUBCS r1, r1, r2 ; then subtract total size - MOV r2, #0 - LDR r2, [r2, #VideoPhysAddr] ; now we have physical address - ADD r1, r1, r2 - MOV r0, #HALDAG_VRender - B Do_HALDAG - -SetVinit - STR r0, [WsPtr, #DisplayStart] - LDR r2, [WsPtr, #ScreenEndAddr] - SUB r1, r0, r2 - LDR r2, [WsPtr, #TotalScreenSize] - ADD r1, r1, r2 ; now we have offset of Vinit in video RAM - LDR r0, [WsPtr, #TeletextOffset] - ADD r1, r1, r0 ; add on teletext bank offset - CMP r1, r2 ; if out of range - SUBCS r1, r1, r2 ; then subtract total size - MOV r2, #0 - LDR r2, [r2, #VideoPhysAddr] ; now we have physical address - ADD r1, r1, r2 - MOV r0, #HALDAG_VInit -Do_HALDAG - [ UseGraphicsV - Push "r4, lr" - MOV r4, #GraphicsV_SetDMAAddress - BL CallGraphicsV - Pull "r4, pc" - | - Push "r3, r9, r12, lr" ; we can corrupt r0-r2 - mjsAddressHAL - mjsCallHAL HAL_Video_SetDAG - Pull "r3, r9, r12, pc" - ] - -; ***************************************************************************** -; -; ConvertBankToAddress - Convert bank number into default start address -; -; in: R2 = screen bank number (0..n) -; -; out: R3 = default start address for that bank -; R0-R2 preserved -; R4,R5 corrupted -; - -ConvertBankToAddress ROUT - MOV R4, R2 - LDR R3, [WsPtr, #TotalScreenSize] - LDR R5, [WsPtr, #ScreenEndAddr] - RSB R3, R3, R5 ; R3 := start of all screen mem - LDR R5, [WsPtr, #ScreenSize] -10 - MOVS R4, R4, LSR #1 ; add on R4*ScreenSize - ADDCS R3, R3, R5 - ADD R5, R5, R5 - BNE %BT10 - MOV PC, R14 - -; ***************************************************************************** -; -; Delete - delete a character -; -; in: R6 = CursorFlags -; - -Delete ROUT - Push R14 - - TST R6, #TEUpdate ; if colours dirty - BLNE ReallySetColours ; then update them - - TST R6, #32 ; Bit 5 set => no cursor move - BLEQ BS - LDR R6, [WsPtr, #CursorFlags] ; reload in case BS corrupts it - - TST R6, #Vdu5Bit - TSTEQ R6, #(TeletextMode :OR: ClipBoxEnableBit) - BNE %FT20 -10 - Pull R14 - MOV tophalf, #0 ; Print with space - MOV bottomhalf, #0 - LDR screen, [WsPtr, #CursorAddr] - LDR bigfont, [WsPtr, #TextExpandArea] - LDR linelen, [WsPtr, #LineLength] - LDR PC, [WsPtr, #WrchNbit] - -20 - TST R6, #Vdu5Bit - Pull R14, NE - BNE Vdu5Delete - - TST R6, #TeletextMode - MOVNE R0, #32 ; wipe out with space - Pull R14, NE - BNE TTXDoChar - - BL ClipCursorCell ; must be ClipBoxEnable - B %BT10 ; so clip cursor and continue - - [ {FALSE} - -; ***************************************************************************** -; -; Convert colours if in 256 colour mode -; -; in: bpp = BitsPerPix -; fore = foreground colour (in 'user' format) -; back = background colour (-------""-------) -; -; out: fore, back = adjusted colours (if necessary) - -ConvertCol - CMP bpp, #8 - MOVNE PC, R14 - - Push R14 - MOV col, fore - LDR index, [WsPtr, #TFTint] - BL FudgeColour - MOV fore, col - - MOV col, back - LDR index, [WsPtr, #TBTint] - BL FudgeColour - MOV back, col - - Pull PC - -FudgeColour ; col = 0 0 B3 B2 G3 G2 R3 R2 - ; index = t1 t0 0 0 0 0 0 0 - - MOV R3, col, LSL #2 ; R3 := B3 B2 G3 G2 R3 R2 0 0 - AND R3, R3, #&84 ; R3 := B3 0 0 0 0 R2 0 0 - MOVS col, col, LSL #28 ; C := B2 - MOV col, col, LSR #29 ; col := 0 0 0 0 0 G3 G2 R3 - ORR col, R3, col, LSL #4 ; col := B3 G3 G2 R3 0 R2 0 0 - ORRCS col, col, #&08 ; col := B3 G3 G2 R3 B2 R2 0 0 - ORR col, col, index, LSR #6 ; col := B3 G3 G2 R3 B2 R2 T1 T0 - MOV PC, R14 - - ] - -; ***************************************************************************** - -PlainBit ROUT - -; first set up RAMMaskTb - - ASSERT bpp=0 - - LDR bpp, [WsPtr, #BytesPerChar] - MOV R1, #1 - RSB R1, R1, R1, LSL bpp ; first form mask for leftmost pixel - ; = (2^BytesPerChar)-1 - - ADD R3, WsPtr, #RAMMaskTb -10 - STR R1, [R3], #4 ; store mask - MOVS R1, R1, LSL bpp ; shift to next pixel - BNE %BT10 ; loop until all shifted out - -; DDV: Original code used to read: -; -; TEQ bpp, #16 -; MOVEQ PC, R14 ; nothing to do on a mode change in this mode -; -; In 32 bit per pixel modes this used to cause an overflow, new function -; drops out if the bpp >= 16. -; - CMP bpp, #16 - MOVGT PC, R14 ; nothing to do on a mode change in this mode - Push R14 - - LDR tabaddr, [WsPtr, #TextExpandArea] - ADD tabaddr, tabaddr, bpp, LSL #8 ; TextPlain now dynamic - - MOV dest, #&80000000 - - CMP bpp, #4 - BHI Plain8Bit - BEQ Plain4Bit - CMP bpp, #1 - BHI Plain2Bit - -Plain1Bit - ADR hiaddr, P1BTab - ADD R10, hiaddr, #8 ; end address -P1B20 - LDR hiword, [hiaddr], #4 -P1B25 - ADR loaddr, P1BTab -P1B30 - LDR loword, [loaddr], #4 -P1B40 - MOV cbyte, hiword, LSL #28 - ORR dest, cbyte, dest, LSR #4 - MOV cbyte, loword, LSL #28 - ORRS dest, cbyte, dest, LSR #4 - BLCS OutputNoColour - - MOVS loword, loword, LSR #4 - BNE P1B40 - TEQ loaddr, R10 - BNE P1B30 - - MOVS hiword, hiword, LSR #4 - BNE P1B25 - TEQ hiaddr, R10 - BNE P1B20 - - Pull PC - -OutputColour - AND cbyte, dest, fore - BIC dest, back, dest - ORR dest, dest, cbyte -OutputNoColour - STR dest, [tabaddr], #4 - MOV dest, #&80000000 - MOV PC, R14 - -P1BTab - & &E6A2C480 - & &F7B3D591 - -; ***************************************************************************** - -Plain2Bit - ADR hiaddr, P2BTab - ADD R10, hiaddr, #16 -P2B20 - LDR hiword, [hiaddr], #4 -P2B25 - ADR loaddr, P2BTab -P2B30 - LDR loword, [loaddr], #4 -P2B40 - MOV cbyte, hiword, LSL #24 - ORR dest, cbyte, dest, LSR #8 - MOV cbyte, loword, LSL #24 - ORRS dest, cbyte, dest, LSR #8 - BLCS OutputNoColour - - MOVS loword, loword, LSR #8 - BNE P2B40 - TEQ loaddr, R10 - BNE P2B30 - - MOVS hiword, hiword, LSR #8 - BNE P2B25 - TEQ hiaddr, R10 - BNE P2B20 - - Pull PC - -P2BTab - & &F030C000 - & &FC3CCC0C - & &F333C303 - & &FF3FCF0F - -; ***************************************************************************** - -Plain4Bit - ADR hiaddr, P4BTab - ADD R10, hiaddr, #32 -P4B20 - LDR hiword, [hiaddr], #4 -P4B25 - ADR loaddr, P4BTab -P4B30 - LDR loword, [loaddr], #4 -P4B40 - MOV cbyte, hiword, LSL #16 - ORR dest, cbyte, dest, LSR #16 - MOV cbyte, loword, LSL #16 - ORRS dest, cbyte, dest, LSR #16 - BLCS OutputNoColour - - MOVS loword, loword, LSR #16 - BNE P4B40 - TEQ loaddr, R10 - BNE P4B30 - - MOVS hiword, hiword, LSR #16 - BNE P4B25 - TEQ hiaddr, R10 - BNE P4B20 - - Pull PC - -P4BTab - & &F0000000 - & &FF000F00 - & &F0F000F0 - & &FFF00FF0 - & &F00F000F - & &FF0F0F0F - & &F0FF00FF - & &FFFF0FFF - -; ***************************************************************************** - -Plain8Bit - ADR hiaddr, P8BTab - ADD R10, hiaddr, #64 -P8B20 - LDR hiword, [hiaddr], #4 - ADR loaddr, P8BTab -P8B30 - MOV dest, hiword - BL OutputNoColour - LDR dest, [loaddr], #4 - BL OutputNoColour - - TEQ loaddr, R10 - BNE P8B30 - - TEQ hiaddr, R10 - BNE P8B20 - - Pull PC - -P8BTab - & &00000000 - & &FF000000 - & &00FF0000 - & &FFFF0000 - & &0000FF00 - & &FF00FF00 - & &00FFFF00 - & &FFFFFF00 - & &000000FF - & &FF0000FF - & &00FF00FF - & &FFFF00FF - & &0000FFFF - & &FF00FFFF - & &00FFFFFF - & &FFFFFFFF - -; ***************************************************************************** -; -; ReadCharacter - Read character at (input) text cursor position -; -; out: R0 = character, 0 if unrecognised -; - -ReadCharacter - Push R14 - - BL PreWrchCursor ; remove both cursors - BL CheckTEUpdate ; update TextExpand if necessary - ; R6 = CursorFlags on exit - TST R6, #TeletextMode - BNE TTXReadCharacter - - TST R6, #CursorsSplit - LDREQ R2, [WsPtr, #CursorAddr] ; point to correct address - LDRNE R2, [WsPtr, #InputCursorAddr] - - LDR R4, [WsPtr, #TextBgColour] - LDR R8, [WsPtr, #LineLength] - - LDR R1, [WsPtr, #ModeFlags] - TST R1, #Flag_DoubleVertical - BNE RdCh1BitDouble - - LDR R1, [WsPtr, #Log2BPC] - CMP R1, #1 - BCC RdCh1Bit - BEQ RdCh2Bit - CMP R1, #3 - BCC RdCh4Bit - BEQ RdCh8Bit - - CMP R1, #4 - BEQ RdCh16Bit - -; Read character from cursor position for 32 bit per pixel - -; in R2 -> cursor address -; R4 = background colour -; R8 = line length to be used -; -; out R6 = first four bytes of char defn -; R7 = last four bytes of char defn - -; used R0,R1,R3,R5,R9,R10,R11,LR = loading screen data! - - MACRO - ConvertTo1BPP $source, $dest, $bit - EORS $source, $source, R4 - ORRNE $dest, $dest, #$bit - MEND - -RdChr32Bit - Push "R0-R1,R3,R5,R9,R10-R12" - - BL RdCh32Bit_GetData - MOV R6,R7 - BL RdCh32Bit_GetData - - Pull "R0-R1,R3,R5,R9,R10-R12" - B RDCH14 - -; *********************************************************************** - -RdCh32Bit_GetData - MOV R7, #1:SHL:31 - -RdCh32Bit_Loop - MOVS R7, R7, LSR #8 - - LDMIA R2,{R0,R1,R3,R5,R9,R10,R11,R12} - ConvertTo1BPP R0, R7, 1<<31 - ConvertTo1BPP R1, R7, 1<<30 - ConvertTo1BPP R3, R7, 1<<29 - ConvertTo1BPP R5, R7, 1<<28 - ConvertTo1BPP R9, R7, 1<<27 - ConvertTo1BPP R10, R7, 1<<26 - ConvertTo1BPP R11, R7, 1<<25 - ConvertTo1BPP R12, R7, 1<<24 - - ADD R2, R2, R8 - BCC RdCh32Bit_Loop - - MOV PC,LR - -RdCh16Bit - ADD R2, R2, #12 - ADD R5, R2, R8, LSL #2 ; half way - ADD R3, R2, R8, LSL #3 ; one-after-finishing R2 - ADD R8, R8, #12 - MOV R7, #0 -RDCH90 - LDR R1, [R2], #-4 - EOR R1, R1, R4 - CMP R1, #&00010000 - MOV R7, R7, RRX - MOV R1, R1, LSL #16 - CMP R1, #&00010000 - MOV R7, R7, RRX - - LDR R1, [R2], #-4 - EOR R1, R1, R4 - CMP R1, #&00010000 - MOV R7, R7, RRX - MOV R1, R1, LSL #16 - CMP R1, #&00010000 - MOV R7, R7, RRX - - LDR R1, [R2], #-4 - EOR R1, R1, R4 - CMP R1, #&00010000 - MOV R7, R7, RRX - MOV R1, R1, LSL #16 - CMP R1, #&00010000 - MOV R7, R7, RRX - - LDR R1, [R2], R8 - EOR R1, R1, R4 - CMP R1, #&00010000 - MOV R7, R7, RRX - MOV R1, R1, LSL #16 - CMP R1, #&00010000 - MOV R7, R7, RRX - - TEQ R2, R5 ; half-way, so copy out word - MOVEQ R6, R7 ; top word - MOVEQ R7, #0 - - TEQ R2, R3 ; finished ? - BNE RDCH90 - BEQ RDCH14 - - -RdCh8Bit - ADD R2, R2, #4 - ADD R5, R2, R8, LSL #2 ; half way - ADD R3, R2, R8, LSL #3 ; one-after-finishing R2 - MOV R7, #0 - ADD R8, R8, #4 ; alternate between -4 and LL+4 - MVN R9, R8 - EOR R9, R9, #3 ; thing to EOR R8 with -RDCH84 - EOR R8, R8, R9 - LDR R1, [R2], R8 - EOR R1, R1, R4 - CMP R1, #&01000000 - MOV R7, R7, RRX - MOV R1, R1, LSL #8 - ORR R1, R1, #1 ; dummy bit - CMP R1, #&01000000 -RDCH88 - MOV R7, R7, RRX - MOV R1, R1, LSL #8 - CMP R1, #&01000000 ; Z => finish, C = output bit - BNE RDCH88 - - TEQ R2, R5 ; half-way, so copy out word - MOVEQ R6, R7 ; top word - MOVEQ R7, #0 - - TEQ R2, R3 ; finished ? - BNE RDCH84 - BEQ RDCH14 - - -RdCh4Bit - ADD R5, R2, R8, LSL #2 ; half way - ADD R3, R2, R8, LSL #3 ; one-after-finishing R2 - MOV R7, #0 -RDCH44 - LDR R1, [R2], R8 - EOR R1, R1, R4 - CMP R1, #&10000000 - MOV R7, R7, RRX - MOV R1, R1, LSL #4 - ORR R1, R1, #1 ; dummy bit - CMP R1, #&10000000 -RDCH48 - MOV R7, R7, RRX - MOV R1, R1, LSL #4 - CMP R1, #&10000000 ; Z => finish, C = output bit - BNE RDCH48 - - TEQ R2, R5 ; half-way, so copy out word - MOVEQ R6, R7 ; top word - MOVEQ R7, #0 - - TEQ R2, R3 ; finished ? - BNE RDCH44 - BEQ RDCH14 - - -RdCh2Bit - ANDS R0, R2, #3 - EOR R2, R2, R0 ; make R2 -> word boundary - MOVNE R0, #16 ; shift adjust - ADD R5, R2, R8, LSL #2 ; half way - ADD R3, R2, R8, LSL #3 ; one-after-finishing R2 - MOV R7, #0 -RDCH24 - LDR R1, [R2], R8 - EOR R1, R1, R4 - MOV R1, R1, ROR R0 - MOV R1, R1, LSL #16 ; important bits at top - ORR R1, R1, #&4000 ; dummy bit - CMP R1, #&40000000 -RDCH28 - MOV R7, R7, RRX - MOV R1, R1, LSL #2 - CMP R1, #&40000000 ; Z => finish, C = output bit - BNE RDCH28 - - TEQ R2, R5 ; half-way, so copy out word - MOVEQ R6, R7 ; top word - MOVEQ R7, #0 - - TEQ R2, R3 ; finished ? - BNE RDCH24 - BEQ RDCH14 - -RdCh1Bit - LDRB R6, [R2], R8 - MOV R6, R6, LSL #24 - LDRB R0, [R2], R8 - ORR R6, R6, R0, LSL #16 - LDRB R0, [R2], R8 - ORR R6, R6, R0, LSL #8 - LDRB R0, [R2], R8 - ORR R0, R6, R0 - EOR R0, R0, R4 ; make background zero - - MOV R6, #1 ; now invert order of bits -RDCH10 - MOVS R0, R0, LSR #1 - ADCS R6, R6, R6 - BCC RDCH10 - - LDRB R7, [R2], R8 - MOV R7, R7, LSL #24 - LDRB R0, [R2], R8 - ORR R7, R7, R0, LSL #16 - LDRB R0, [R2], R8 - ORR R7, R7, R0, LSL #8 - LDRB R0, [R2], R8 - ORR R0, R7, R0 - EOR R0, R0, R4 - - MOV R7, #1 ; now invert order of bits -RDCH12 - MOVS R0, R0, LSR #1 - ADCS R7, R7, R7 - BCC RDCH12 - -RDCH14 - MOV R0, #32 - ADD R1, WsPtr, # Font -RDCH16 - LDMIA R1!, {R2,R3} - TEQ R2, R6 - TEQEQ R3, R7 - BEQ RDCH17 ; successful match - ADD R0, R0, #1 - TEQ R0, #127 - ADDEQ R0, R0, #1 - ADDEQ R1, R1, #8 - ANDS R0, R0, #&FF ; 0 if finished - BNE RDCH16 - -RDCH17 - Push R0 ; save char - BL PostWrchCursor - Pull "R0, PC" - -; ***************************************************************************** - -RdCh1BitDouble ; double height mode - LDRB R0, [R2], R8 - LDRB R3, [R2], R8 - TEQ R0, R3 - MOVEQ R6, R0, LSL #24 - LDREQB R0, [R2], R8 - LDREQB R3, [R2], R8 - TEQEQ R0, R3 - ORREQ R6, R6, R0, LSL #16 - LDREQB R0, [R2], R8 - LDREQB R3, [R2], R8 - TEQEQ R0, R3 - ORREQ R6, R6, R0, LSL #8 - LDREQB R0, [R2], R8 - LDREQB R3, [R2], R8 - TEQEQ R0, R3 - ORREQ R0, R6, R0 - - MOVNE R0, #0 ; indicate bad character - BNE RDCH17 ; and branch - - EOR R0, R0, R4 ; make background zero - - MOV R6, #1 ; now invert order of bits -RDCH10D - MOVS R0, R0, LSR #1 - ADCS R6, R6, R6 - BCC RDCH10D - - LDRB R0, [R2], R8 - LDRB R3, [R2], R8 - TEQ R0, R3 - MOVEQ R7, R0, LSL #24 - LDREQB R0, [R2], R8 - LDREQB R3, [R2], R8 - TEQEQ R0, R3 - ORREQ R7, R7, R0, LSL #16 - LDREQB R0, [R2], R8 - LDREQB R3, [R2], R8 - TEQEQ R0, R3 - ORREQ R7, R7, R0, LSL #8 - LDREQB R0, [R2], R8 - LDREQB R3, [R2], R8 - TEQEQ R0, R3 - ORREQ R0, R7, R0 - - MOVNE R0, #0 ; indicate bad character - BNE RDCH17 ; and branch - - EOR R0, R0, R4 - - MOV R7, #1 ; now invert order of bits -RDCH12D - MOVS R0, R0, LSR #1 - ADCS R7, R7, R7 - BCC RDCH12D - B RDCH14 - -; ***************************************************************************** - -TTXReadCharacter - TST R6, #CursorsSplit - ADRL R1, TTXLineStarts - LDREQ R2, [WsPtr, #CursorY] - LDRNE R2, [WsPtr, #InputCursorY] - LDR R1, [R1, R2, LSL #2] - LDREQ R2, [WsPtr, #CursorX] - LDRNE R2, [WsPtr, #InputCursorX] - ADD R2, R2, #1 ; skip dummy - LDRB R1, [R1, R2, LSL #2] - MOV R0, R1 - TEQ R1, #"#" ; not those again ! - MOVEQ R0, #"`" - TEQ R1, #"`" - MOVEQ R0, #"_" - TEQ R1, #"_" - MOVEQ R0, #"#" - B RDCH17 - -; ***************************************************************************** -; -; DoOSBYTE87 - OSBYTE &87 entry point -; -; in: - -; -; out: R0 = &87 -; R1 = character at text cursor, 0 if unrecognised -; R2 = screen mode -; - -DoOSBYTE87 - Push "R3-R11,R14" - BL ReadCharacter - MOV R1, R0 - MOV R0, #&87 - LDR R2, [WsPtr, #ModeNo] - CMP R0, #0 ; clear V for any wallies! - Pull "R3-R11,PC" - -; ***************************************************************************** -; -; PageTest - check for CTRL/SHIFT, page mode -; -; in: R6 = CursorFlags -; - -PageTest - Push R14 - - BL Page_ProcessCallbacks ; give callbacks at least one chance per line - - CLC ; don't set leds first time - BL CtrlShiftTest ; on exit, C=CTRL, N=SHIFT - BCC Page20 ; CTRL up, then branch - BPL Page20 ; SHIFT up, then branch - -; CTRL and SHIFT are down - - BL ClearLines ; CTRL+SHIFT down, so clear lines - BL PostWrchCursor ; we may be some time, so enable cursor -CSWaitLoop - SEC ; set leds - BL CtrlShiftTest - BCC Page18 - BLMI Page_ProcessCallbacksIdle - BMI CSWaitLoop ; and wait for change (NB C=1 now) -Page18 - [ {FALSE} - BL LEDsOff ; put LEDs back to normal - ] - BL PreWrchCursor ; get rid of cursor again - -; CTRL and SHIFT are not both down - -Page20 - CLC ; don't set leds first time - BL CtrlShiftTest - BCC Page40 ; [CTRL not down] - -; CTRL down, so wait for auto repeat delay time before continuing - - BL PostWrchCursor ; we may be some time, so enable cursor - - LDROSB R1, KeyRepRate - STROSB R1, CentiCounter, R0 - CLC -Page30 - BL CtrlShiftTest - BCC Page35 ; CTRL no longer down - LDROSB R1, CentiCounter - CMP R1, #1 - BLCS Page_ProcessCallbacksIdle - BCS Page30 ; loop with carry set -Page35 - BL PreWrchCursor ; remove cursor again - -; CTRL not down, test for page mode - -Page40 - EOR R0, R6, #PageMode - TST R0, #(PageMode :OR: CursorsSplit) - Pull PC, NE ; cursors split or not in page mode - - LDROSB R3, PageModeLineCount - BL BotRowCheck ; are we on bottom row ? - BNE IncLinesExit - TST R6, #8 - LDREQ R0, [WsPtr, #TWBRow] - LDREQ R1, [WsPtr, #TWTRow] - LDRNE R0, [WsPtr, #TWRCol] - LDRNE R1, [WsPtr, #TWLCol] - SUB R0, R0, R1 ; get number of lines in window - SUB R0, R0, R0, LSR #2 ; * 3/4 (rounded up) - CMP R0, R3 ; does PageModeLineCount exceed this ? - BCC Page50 ; yes, then wait until SHIFT up -IncLinesExit - ADD R3, R3, #1 - STROSB R3, PageModeLineCount, R0 - Pull PC - -Page50 ; NB C=0 on entry from above - BL CtrlShiftTest - BMI Page55 - -; Waiting for shift - - BL PostWrchCursor ; put cursor back on for now -PageWaitLoop - SEC - BL CtrlShiftTest - BLPL Page_ProcessCallbacksIdle - BPL PageWaitLoop - BL PreWrchCursor - -Page55 - Pull R14 -ClearLines - MOV R0, #1 ; fudge for MASTER compatibility - STROSB R0, PageModeLineCount, R1 - MOV PC, R14 - -BotRowCheck - TST R6, #2 - LDREQ R1, [WsPtr, #TWRCol] - LDRNE R1, [WsPtr, #TWLCol] - TST R6, #4 - LDREQ R0, [WsPtr, #TWBRow] - LDRNE R0, [WsPtr, #TWTRow] - TST R6, #8 - EORNE R0, R0, R1 ; swap R0, R1 - EORNE R1, R0, R1 - EORNE R0, R0, R1 - LDREQ R2, [WsPtr, #CursorY] - LDRNE R2, [WsPtr, #CursorX] - TEQ R0, R2 - MOV PC, R14 - -CtrlShiftTest ROUT - BCC %FT05 - [ {FALSE} - Push R14 - BL LEDsOn - Pull R14 - ] -05 MOV R0, #0 - LDRB R0, [R0, #ESC_Status] - TST R0, #&40 ; escape condition ? - LDROSB R0, KeyBdStatus ; (preserves PSR) - BEQ %FT10 ; [no escape] - - Push R14 - BIC R0, R0, #KBStat_ScrollLock ; escape, so cancel scroll lock - STROSB R0, KeyBdStatus, R14 ; and store back - MOV R0, #&20 ; pretend shift down, ctrl up - MOVS R0, R0, LSL #(32-6) ; C=CTRL, N=SHIFT - Pull PC - -10 - TST R0, #&08 ; shift bit - ORRNE R0, R0, #&20 ; move it to bit below ctrl (bit 6) - BICEQ R0, R0, #&20 - TST R0, #KBStat_ScrollLock ; if scroll lock on - ORRNE R0, R0, #&60 ; then pretend ctrl and shift down - MOVS R0, R0, LSL #(32-6) ; C=CTRL, N=SHIFT - MOV PC, R14 - -Page_ProcessCallbacks - Entry - ; See if there are any pending callbacks - MOV R0, #0 - LDRB R14, [R0, #CallBack_Flag] - TST R14, #CBack_VectorReq - BLNE process_callback_chain - EXIT - -Page_ProcessCallbacksIdle - EntryS ; routine must preserve flags - ; See if there are any pending callbacks - MOV R0, #0 - LDRB R14, [R0, #CallBack_Flag] - TST R14, #CBack_VectorReq - BLNE process_callback_chain - ; Now they're dealt with, we have nothing else to do, so call Idle - [ StorkPowerSave - LDR R14, [r0, #PortableFlags] - TST R14, #PortableFeature_Idle - SWINE XPortable_Idle - ] - EXITS - -; ***************************************************************************** -; -; SO - Page mode on -; -; in: R6 = CursorFlags -; - -SO - MOV R0, #0 - STRB R0, [R0, #OsbyteVars + :INDEX: PageModeLineCount] - - ORR R6, R6, #PageMode - STR R6, [WsPtr, #CursorFlags] - - MOV PC, R14 - -; ***************************************************************************** -; -; SI - Page mode off -; -; in: R6 = CursorFlags -; - -SI - BIC R6, R6, #PageMode - STR R6, [WsPtr, #CursorFlags] - - MOV PC, R14 - -; ***************************************************************************** -; -; DoResetFont - Reset some or all of the soft font from the hard font -; -; in: R1*32 = start character, R2 = number of pages to copy -; -; NB no range checking is done on these numbers - -DoResetFont ROUT - - ADRL R0, HardFont-32*8 - ADD R3, WsPtr, #(Font-32*8) - - ADD R0, R0, R1, LSL #8 ; start source - ADD R3, R3, R1, LSL #8 ; start dest - ADD R1, R0, R2, LSL #8 ; end source - -10 - LDR R2, [R0], #4 - STR R2, [R3], #4 - TEQ R0, R1 - BNE %BT10 - - MOV PC, R14 - -; ***************************************************************************** -; -; DoReadFont - Read character font -; -; in: R1 -> control block -; [R1, #0] = character to read (2..5 => read ecf, 6=> read dotdash) -; -; out: [R1, #1..8] = font for that character -; - -DoReadFont - LDRB R0, [R1] - CMP R0, #32 - ADD R0, WsPtr, R0, LSL #3 - ADDCS R0, R0, #(Font-32*8) ; R0 -> font - ADDCC R0, R0, #(Ecf1-2*8) - LDMIA R0, {R2,R3} - - STRB R2, [R1, #1] - MOV R2, R2, LSR #8 - STRB R2, [R1, #2] - MOV R2, R2, LSR #8 - STRB R2, [R1, #3] - MOV R2, R2, LSR #8 - STRB R2, [R1, #4] - - STRB R3, [R1, #5] - MOV R3, R3, LSR #8 - STRB R3, [R1, #6] - MOV R3, R3, LSR #8 - STRB R3, [R1, #7] - MOV R3, R3, LSR #8 - STRB R3, [R1, #8] - - MOV PC, R14 - -; ***************************************************************************** -; -; NAK - Disable VDU -; -; in: R6 = CursorFlags -; - -NAK - ORR R6, R6, #VduDisabled - STR R6, [WsPtr, #CursorFlags] - MOV PC, R14 - -; ***************************************************************************** -; -; STX - Turn printer on -; ETX - Turn printer off -; -; in: R0 = 2 or 3 -; - -STX -ETX - -; insert code here to call UPTVEC or NETVEC -; (probably need to restore cursor while doing so in case of 'Not listening') - - LDR R1, [WsPtr, #VduStatus] - TEQ R0, #2 ; turning on ? - ORREQ R1, R1, #Vdu2Mode ; yes, then set bit - BICNE R1, R1, #Vdu2Mode ; no, then clear bit - STR R1, [WsPtr, #VduStatus] - MOVEQ PC, R14 ; exit if not turning off - - Push R14 - MOV R0, #&7B ; make printer dormant - SWI XOS_Byte - Pull PC, VC - -; bad exit from the OSBYTE - - Pull R14 - B VduBadExit - -; ***************************************************************************** -; -; BEL - Do VDU 7 -; -; in: BELLchannel, BELLinfo, BELLfreq, BELLdur contain info for bell -; BELLinfo: Bits 0,1 S bits -; Bit 2 H bit -; Bits 3-6 (envelope-1) OR (volume+15) -; Bit 7 0 => envelope, 1 => volume -; -; out: SOUND &HFSC, A, P, D -; - -BEL ROUT - Push R14 - BYTEWS R0 - ADD R1, WsPtr, #(BeepBlock :AND: &FF) - ADD R1, R1, #(BeepBlock :AND: &FF00) - - MOV R2, #0 - STRB R2, [R1, #5] ; zero hi-byte of pitch - STRB R2, [R1, #7] ; zero hi-byte of duration - - LDRB R2, [R0, #:INDEX: BELLchannel] ; copy channel - STRB R2, [R1, #0] ; into OSWORD block - - LDRB R2, [R0, #:INDEX: BELLinfo] ; get info - AND R3, R2, #7 ; bit 2 of R3 is H, bits 0,1=S - TST R3, #4 - EORNE R3, R3, #(4 :EOR: &10) ; put H into bit 4 - STRB R3, [R1, #1] ; store H and S - - MOV R2, R2, LSL #24 - MOV R2, R2, ASR #(24+3) ; shift down, sign extending - ADD R2, R2, #1 - STRB R2, [R1, #2] ; store lo-byte of env/vol - MOV R2, R2, LSR #8 - STRB R2, [R1, #3] ; store hi-byte of env/vol - - LDRB R2, [R0, #:INDEX: BELLfreq] - STRB R2, [R1, #4] ; copy pitch - - LDRB R2, [R0, #:INDEX: BELLdur] - STRB R2, [R1, #6] ; copy duration - - MOV R0, #7 ; OSWORD SOUND - SWI XOS_Word - Pull PC - -; ***************************************************************************** - -; Compile the text fg / bg (and tint info if required) into a sensible set of -; colour words. - -; The routines take the TextFg and TextBg colours, if NColour >= 63 then -; we attempt to combine the tint information, this is then passed onto -; ColourTrans to force the colour change. - -; in - -; out [TextFgColour] / [TextBgColour] updated to contain new values - -; amg: 30/11/93 split these into separate routines to sort out a problem. -; When OS_SetColour was being used for text colours in >=8bpp TForeCol/TBackCol -; and TForeTint/TBackTint went out of step. Thus when a VDU 17 or VDU 23,17,0 | 1 -; came along both fore and back text colours were getting changed. This solution -; is not perfect, since doing a TINT command before a colour change will still -; go wrong but I consider that worth leaving against the alternative of changing -; the function of this area of the code by having some magic value. - -CompileTextBg ROUT - - Entry "R0-R1" - - LDR R1, [WsPtr, #NColour] - CMP R1, #63 ; is this a daft mode? - - LDR R0, [WsPtr, #TBackCol] - LDRCS LR, [WsPtr, #TBTint] - ANDCS LR, LR, #&C0 ; only look at 2 bits of tint - ORRCS R0, R0, LR ; combine tint value to bg colour - BLCS ConvertGCOLToColourNumber - STRVC R0, [WsPtr, #TextBgColour] - - EXIT - -CompileTextFg ROUT - - Entry "R0-R1" - - LDR R1, [WsPtr, #NColour] - CMP R1, #63 ; is this a daft mode? - - LDR R0, [WsPtr, #TForeCol] - LDRCS LR, [WsPtr, #TFTint] - ANDCS LR, LR, #&C0 ; only look at 2 bits of tint - ORRCS R0, R0, LR ; combine in the tint value - BLCS ConvertGCOLToColourNumber ; convert colour using ColourTrans - STRVC R0, [WsPtr, #TextFgColour] ; store the value away - assume it worked!?!@? - - EXIT - - -; ***************************************************************************** -; -; Convert a GCOL including Tint information to a physical colour, returning -; the colour number. This is used for backwards compatibility with the -; existing 8 bit interfaces providided within the kernel. -; -; in R0 = GCOL ( + tint ) := t t b b g g r r -; out R0 = colour number (at current depth) -; V set if no ColourTrans module. - -; don't call CTrans if in 8bpp since otherwise GCOL numbers vary with -; palette changes! - -ConvertGCOLToColourNumber ROUT - - EntryS "R1-R2" - - LDR R1, [WsPtr, #NColour] - CMP R1, #63 - CMPNE R1, #255 - BEQ %FT20 - - AND LR, R0, #4_3000 ; extract the tint information - MOV R0, R0, LSL #14 ; convert to a sensible bit location - AND R2, R0, #4_0003 :SHL: 14 ; extract the red - ORR R2, R2, LR, LSL #6 ; and then combine the tint information - AND R1, R0, #4_0030 :SHL: 14 ; extract the green - ORR R2, R2, R1, LSL #6 - ORR R2, R2, LR, LSL #14 ; and combine with tint and green - AND R1, R0, #4_0300 :SHL: 14 ; finally extract the blue component - ORR R2, R2, R1, LSL #12 - ORR R2, R2, LR, LSL #22 ; combine in the tint and blue - ORR R0, R2, R2, LSR #4 ; ensure physcial colour yields pure-white! - - SWI XColourTrans_ReturnColourNumber - - EXITS -20 - MOV r1, r0, LSR #6 ; r1 = 0 0 0 0 0 0 T1 T0 - AND r2, r0, #2_00100001 ; r2 = 0 0 B3 0 0 0 0 R2 - ORR r1, r1, r2, LSL #2 ; r1 = B3 0 0 0 0 R2 T1 T0 - AND r2, r0, #2_00010000 ; r2 = 0 0 0 B2 0 0 0 0 - ORR r1, r1, r2, LSR #1 ; r1 = B3 0 0 0 B2 R2 T1 T0 - AND r2, r0, #2_00001110 ; r2 = 0 0 0 0 G3 G2 R3 0 - ORR r0, r1, r2, LSL #3 ; r0 = B3 G3 G2 R3 B2 R2 T1 T0 - EXITS - - LTORG - - END -- GitLab