diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000000000000000000000000000000000000..1f3dca796057b324bb1c90d7d0250606acdb7f49
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,2 @@
+hdr/** gitlab-language=armasm linguist-language=armasm linguist-detectable=true
+s/** gitlab-language=armasm linguist-language=armasm linguist-detectable=true
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..b5118ebb10d39902355ff1196786b6aca7d815af
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,97 @@
+# Copyright 2011 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.
+#
+# Makefile for Kernel
+#
+# ***********************************
+# ***    C h a n g e   L i s t    ***
+# ***********************************
+# Date       Name         Description
+# ----       ----         -----------
+# 25-May-94  AMcC         Created.
+#
+
+#
+# Paths
+#
+EXP_HDR = <export$dir>
+C_EXP_HDR = <cexport$dir>.Global.h
+
+#
+# Generic options:
+#
+MKDIR   = mkdir -p
+AS      = aasm
+ARMASM  = objasm
+CP      = copy
+RM      = remove
+CCFLAGS = -c -depend !Depend -IC:
+ASFLAGS = -depend !Depend ${THROWBACK} -Stamp -quit -To $@ -From
+ARMASMFLAGS = -depend !Depend -g -APCS 3/nofp/noswst ${THROWBACK}
+CPFLAGS = ~cfr~v
+
+TOKENISE = tokenise
+TOKENS   = Hdr:Tokens
+
+#
+# Program specific options:
+#
+COMPONENT = S3C6410
+TARGET    = bin.S3C6410
+DBGTARGET = aif.S3C6410
+GPATARGET = gpa.S3C6410
+EXPORTS   =
+
+OBJECTS   = o.Boot o.Interrupts o.Timers o.Video
+# o.Video o.RTC
+
+.s.o:;	${ARMASM} ${ARMASMFLAGS} $< $@
+
+#
+# Generic rules:
+#
+rom: ${TARGET}
+	@echo ${COMPONENT}: rom module built
+
+debug: ${GPATARGET}
+	@echo ${COMPONENT}: debug module built
+
+install_rom: ${TARGET}
+	${CP} ${TARGET} ${INSTDIR}.${COMPONENT} ${CPFLAGS}
+	@echo ${COMPONENT}: rom module installed
+
+clean:
+	${RM} ROM
+	${RM} ${TARGET}
+	-Wipe o.* ~C~V
+	-Wipe aif.* ~C~V
+	-Wipe gpa.* ~C~V
+	@echo ${COMPONENT}: cleaned
+
+export: ${EXPORTS}
+	@echo ${COMPONENT}: export complete
+
+resources:
+	@echo ${COMPONENT}: nothing to do
+
+${TARGET}: ${OBJECTS}
+	Link -bin -base 0xFC000000 -o $@ ${OBJECTS}
+
+${DBGTARGET}: ${OBJECTS}
+	Link -bin -base 0xFC000000 -aif -d -o $@ ${OBJECTS}
+
+${GPATARGET}: ${DBGTARGET}
+	ToGPA -s ${DBGTARGET} $@
+
+# Dynamic dependencies:
diff --git a/MkClean,fd7 b/MkClean,fd7
new file mode 100644
index 0000000000000000000000000000000000000000..65ad88f3eb64b835934c32ccddbd44566687e766
--- /dev/null
+++ b/MkClean,fd7
@@ -0,0 +1,16 @@
+| Copyright 2011 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.
+|
+Dir <Obey$Dir>
+amu_machine clean
diff --git a/MkRom,fd7 b/MkRom,fd7
new file mode 100644
index 0000000000000000000000000000000000000000..04599cc1429b62e7738665e309ecc8871041b5f3
--- /dev/null
+++ b/MkRom,fd7
@@ -0,0 +1,18 @@
+| Copyright 2011 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.
+|
+Dir <Obey$Dir>
+time
+amu_machine rom debug THROWBACK=-throwback
+time
diff --git a/VersionNum b/VersionNum
index 71b63203099c6d983781528cf555998e402ca13a..f56d869add4243975fbe4ff21c421ce322008401 100644
--- a/VersionNum
+++ b/VersionNum
@@ -1,15 +1,15 @@
-/* (0.00)
+/* (0.01)
  *
  * This file is automatically maintained by srccommit, do not edit manually.
  * Last processed by srccommit version: 1.1.
  *
  */
-#define Module_MajorVersion_CMHG        0.00
+#define Module_MajorVersion_CMHG        0.01
 #define Module_MinorVersion_CMHG        
 #define Module_Date_CMHG                03 Jun 2011
 
-#define Module_MajorVersion             "0.00"
-#define Module_Version                  0
+#define Module_MajorVersion             "0.01"
+#define Module_Version                  1
 #define Module_MinorVersion             ""
 #define Module_Date                     "03 Jun 2011"
 
@@ -18,6 +18,6 @@
 #define Module_ComponentName            "S3C6410"
 #define Module_ComponentPath            "castle/RiscOS/Sources/HAL/S3C6410"
 
-#define Module_FullVersion              "0.00"
-#define Module_HelpVersion              "0.00 (03 Jun 2011)"
-#define Module_LibraryVersionInfo       "0:0"
+#define Module_FullVersion              "0.01"
+#define Module_HelpVersion              "0.01 (03 Jun 2011)"
+#define Module_LibraryVersionInfo       "0:1"
diff --git a/hdr/StaticWS b/hdr/StaticWS
new file mode 100644
index 0000000000000000000000000000000000000000..c9c813ca28437faac801ed129c854b8ae37650bb
--- /dev/null
+++ b/hdr/StaticWS
@@ -0,0 +1,59 @@
+; Copyright 2011 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.
+;
+sb              RN      9
+
+                ^       0,sb
+OSheader        #       4
+OSentries       #       4*(HighestOSEntry+1)
+UART_Address    #       4
+CLK_Address     #       4
+Timer_Address   #       4
+INT_Address     #       4
+LCD_Address	#	4
+GPIO_Address	#	4
+USB_Address	#	4
+MEM_Address	#	4
+RTC_Address	#	4
+TimerPeriods    #       4*2
+VIDX_Size	#	4
+VID_BPP		#	4
+IOCRSoftCopy    #       1
+IOSystemType    #       1
+IOST_7500 * 1
+                #       2
+
+; workspace for video functions
+;
+VRAMWidth               #    1
+                        #    3
+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
+;
+
+HAL_WsSize      *       :INDEX:@
+
+                END
diff --git a/hdr/Video b/hdr/Video
new file mode 100644
index 0000000000000000000000000000000000000000..48ad069c6d63f1ff9bd5fcc374968b1920b4817e
--- /dev/null
+++ b/hdr/Video
@@ -0,0 +1,196 @@
+; Copyright 2011 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.
+;
+
+; -----------------------------------------------------------------------------------
+
+;
+;VIDC20 parameters size (for table of VIDC20 registers)
+;
+VIDC20ParmsSize * (128*4) ; 128 words from 80xxxxxx to FFxxxxxx step 01000000
+
+;
+; VRAM SAM length in bytes
+;
+SAMLength *     512*4
+
+; -----------------------------------------------------------------------------------
+
+;
+; 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
+
+; 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
+
+; -----------------------------------------------------------------------------------
+
+; mjs - this had better agree with the format specified in kernel s.vdu.vdumodes
+
+;
+; 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_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
+
+; -----------------------------------------------------------------------------------
+
+       END
diff --git a/s/Boot b/s/Boot
new file mode 100644
index 0000000000000000000000000000000000000000..22aa0331cda4df46ec35f770ca11ff01fc49917b
--- /dev/null
+++ b/s/Boot
@@ -0,0 +1,1227 @@
+; Copyright 2011 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.
+;
+        GET     Hdr:ListOpts
+        GET     Hdr:Macros
+        GET     Hdr:System
+        GET     Hdr:Machine.<Machine>
+        GET     Hdr:ImageSize.<ImageSize>
+        $GetCPU
+        $GetIO
+        $GetMEMC
+        $GetMEMM
+        $GetVIDC
+
+
+        GET     Hdr:Proc
+        GET     Hdr:OSEntries
+        GET     Hdr:HALEntries
+
+        GET     hdr.StaticWS
+
+
+
+
+
+DRAM0PhysRam *  &50000000               ; 2 DRAM banks
+DRAM1PhysRam *  &60000000
+
+UARTPhys     *  &7F005000
+
+
+	EXPORT	serial
+; This version assumes a RISC OS image starting 64K after us.
+
+        AREA    |!!!ROMStart|, CODE, READONLY, PIC
+
+        ENTRY
+
+HAL_Base
+
+vectors
+	B	start
+;        LDR     pc, ResetInd            ; Reset
+        LDR     pc, HaltInd             ; Undefined instruction
+        LDR     pc, HaltInd             ; SWI
+        LDR     pc, HaltInd             ; Prefetch abort
+        LDR     pc, HaltInd             ; Data abort
+        LDR     pc, HaltInd             ; (Address exception)
+        LDR     pc, HaltInd             ; IRQ
+        LDR     pc, HaltInd             ; FIQ
+
+ResetInd
+        DCD     0x50100220  ;(start - HAL_Base)+0x30000000
+HaltInd
+        DCD     0x50100028  ;(halt - HAL_Base) +0x30000000
+
+halt    B       halt
+
+        ASSERT  . - HAL_Base < 0x60
+        %       0x60 - (. - HAL_Base)
+ROMsize
+        DCD     0                       ; patched in by build system
+
+HALdescriptor   DATA
+        DCD     0
+        DCD     HAL_Base - HALdescriptor
+        DCD     64*1024
+        DCD     HAL_EntryTable - HALdescriptor
+        DCD     HAL_Entries
+        DCD     HAL_WsSize
+
+        MACRO
+        HALEntry $name
+        ASSERT  (. - HAL_EntryTable) / 4 = EntryNo_$name
+        DCD     $name - HAL_EntryTable
+        MEND
+
+        MACRO
+        NullEntry
+        DCD     HAL_Null - HAL_EntryTable
+        MEND
+
+;        IMPORT   Video_init
+
+        IMPORT   HAL_IRQEnable
+        IMPORT   HAL_IRQDisable
+        IMPORT   HAL_IRQClear
+        IMPORT   HAL_IRQSource
+        IMPORT   HAL_IRQStatus
+;        IMPORT   HAL_FIQEnable
+;        IMPORT   HAL_FIQDisable
+;        IMPORT   HAL_FIQDisableAll
+;        IMPORT   HAL_FIQClear
+;        IMPORT   HAL_FIQSource
+;        IMPORT   HAL_FIQStatus
+
+        IMPORT   HAL_Timers
+        IMPORT   HAL_TimerDevice
+        IMPORT   HAL_TimerGranularity
+        IMPORT   HAL_TimerMaxPeriod
+        IMPORT   HAL_TimerSetPeriod
+        IMPORT   HAL_TimerPeriod
+        IMPORT   HAL_TimerReadCountdown
+
+;        IMPORT   HAL_CounterRate
+;        IMPORT   HAL_CounterPeriod
+;        IMPORT   HAL_CounterRead
+;        IMPORT   HAL_CounterDelay
+
+;        IMPORT   HAL_IICBuses
+;        IMPORT   HAL_IICType
+;        IMPORT   HAL_IICSetLines
+;        IMPORT   HAL_IICReadLines
+
+;        IMPORT   HAL_NVMemoryType
+;        IMPORT   HAL_NVMemorySize
+;        IMPORT   HAL_NVMemoryPageSize
+;        IMPORT   HAL_NVMemoryProtectedSize
+;        IMPORT   HAL_NVMemoryProtection
+;        IMPORT   HAL_NVMemoryIICAddress
+;        IMPORT   HAL_NVMemoryRead
+;        IMPORT   HAL_NVMemoryWrite
+
+ ;       IMPORT   HAL_VideoFlybackDevice
+ ;       IMPORT   HAL_Video_SetMode
+        IMPORT   HAL_Video_WritePaletteEntry
+        IMPORT   HAL_Video_WritePaletteEntries
+ ;       IMPORT   HAL_Video_ReadPaletteEntry
+ ;       IMPORT   HAL_Video_SetInterlace
+ ;       IMPORT   HAL_Video_SetBlank
+ ;       IMPORT   HAL_Video_SetPowerSave
+ ;       IMPORT   HAL_Video_UpdatePointer
+        IMPORT   HAL_Video_SetDAG
+        IMPORT   HAL_Video_VetMode
+        IMPORT   HAL_Video_PixelFormats
+        IMPORT   HAL_Video_Features
+        IMPORT   HAL_Video_BufferAlignment
+        IMPORT   HAL_Video_OutputFormat
+
+;	IMPORT   HAL_ATAControllerInfo
+;	IMPORT   HAL_ATASetModes
+;	IMPORT   HAL_ATACableID
+        ;IMPORT   HAL_MatrixColumns
+        ;IMPORT   HAL_MatrixScan
+
+;        IMPORT HAL_MachineID
+
+	EXPORT  serial2
+	EXPORT	serialn
+	EXPORT  serial8
+	EXPORT	serials
+
+ ;	IMPORT 	RTC_Init
+
+HAL_EntryTable  DATA
+        HALEntry  HAL_Init
+
+        HALEntry HAL_IRQEnable
+        HALEntry HAL_IRQDisable
+        HALEntry HAL_IRQClear
+        HALEntry HAL_IRQSource
+        HALEntry HAL_IRQStatus
+        NullEntry ;HAL_FIQEnable
+        NullEntry ;HAL_FIQDisable
+        NullEntry ;HAL_FIQDisableAll
+        NullEntry ;HAL_FIQClear
+        NullEntry ;HAL_FIQSource
+        NullEntry ;HAL_FIQStatus
+
+        HALEntry HAL_Timers
+        HALEntry HAL_TimerDevice
+        HALEntry HAL_TimerGranularity
+        HALEntry HAL_TimerMaxPeriod
+        HALEntry HAL_TimerSetPeriod
+        HALEntry HAL_TimerPeriod
+        HALEntry HAL_TimerReadCountdown
+
+        NullEntry ;HAL_CounterRate
+        NullEntry ;HAL_CounterPeriod
+        NullEntry ;HAL_CounterRead
+        NullEntry ;HAL_CounterDelay
+
+        NullEntry ;HAL_NVMemoryType
+        NullEntry ;HAL_NVMemorySize
+        NullEntry ;HAL_NVMemoryPageSize
+        NullEntry ;HAL_NVMemoryProtectedSize
+        NullEntry ;HAL_NVMemoryProtection
+        NullEntry ;HAL_NVMemoryIICAddress
+        NullEntry ;HAL_NVMemoryRead
+        NullEntry ;HAL_NVMemoryWrite
+
+        NullEntry ;HAL_IICBuses
+        NullEntry ;HAL_IICType
+        NullEntry ;HAL_IICSetLines
+        NullEntry ;HAL_IICReadLines
+        NullEntry ;HAL_IICDevice
+        NullEntry ;HAL_IICTransfer
+        NullEntry ;HAL_IICMonitorTransfer
+
+        NullEntry ;HAL_VideoFlybackDevice
+        NullEntry ;HAL_Video_SetMode
+        HALEntry HAL_Video_WritePaletteEntry
+        HALEntry HAL_Video_WritePaletteEntries
+        NullEntry ;HAL_Video_ReadPaletteEntry
+        NullEntry ;HAL_Video_SetInterlace
+        NullEntry ;HAL_Video_SetBlank
+        NullEntry ;HAL_Video_SetPowerSave
+        NullEntry ;HAL_Video_UpdatePointer
+        HALEntry HAL_Video_SetDAG
+        HALEntry HAL_Video_VetMode
+        HALEntry HAL_Video_PixelFormats
+        HALEntry HAL_Video_Features
+        HALEntry HAL_Video_BufferAlignment
+        HALEntry HAL_Video_OutputFormat
+
+        NullEntry ;HAL_MatrixColumns
+        NullEntry ;HAL_MatrixScan
+
+        NullEntry ;HAL_TouchscreenType
+        NullEntry ;HAL_Touchscreenread
+        NullEntry ;HAL_Touchscreenread
+        NullEntry ;HAL_Touchscreenread
+
+        NullEntry ;HAL_MachineID
+
+        NullEntry ;HAL_ControllerAddress
+        HALEntry HAL_HardwareInfo
+        HALEntry HAL_SuperIOInfo
+        HALEntry HAL_PlatformInfo
+        NullEntry ;HAL_CleanerSpace
+
+        NullEntry ;HAL_UARTPorts
+        NullEntry ;HAL_UARTStartUp
+        NullEntry ;HAL_UARTShutdown
+        NullEntry ;HAL_UARTFeatures
+        NullEntry ;HAL_UARTReceiveByte
+        NullEntry ;HAL_UARTTransmitByte
+        NullEntry ;HAL_UARTLineStatus
+        NullEntry ;HAL_UARTInterruptEnable
+        NullEntry ;HAL_UARTRate
+        NullEntry ;HAL_UARTFormat
+        NullEntry ;HAL_UARTFIFOSize
+        NullEntry ;HAL_UARTFIFOClear
+        NullEntry ;HAL_UARTFIFOEnable
+        NullEntry ;HAL_UARTFIFOThreshold
+        NullEntry ;HAL_UARTInterruptID
+        NullEntry ;HAL_UARTBreak
+        NullEntry ;HAL_UARTModemControl
+        NullEntry ;HAL_UARTModemStatus
+        NullEntry ;HAL_UARTDevice
+
+        NullEntry ;HAL_Reset
+        HALEntry  HAL_DebugRX
+        HALEntry  HAL_DebugTX
+
+        NullEntry ;HAL_PCIFeatures
+
+        NullEntry ;HAL_PCIReadConfigByte
+        NullEntry ;HAL_PCIReadConfigHalfword
+        NullEntry ;HAL_PCIReadConfigWord
+        NullEntry ;HAL_PCIWriteConfigByte
+        NullEntry ;HAL_PCIWriteConfigHalfword
+        NullEntry ;HAL_PCIWriteConfigWord
+        NullEntry ;HAL_PCISpecialCycle
+        NullEntry ;HAL_PCISlotTable
+        NullEntry ;HAL_PCIAddresses
+
+        NullEntry ;HAL_ATAControllerInfo
+        NullEntry ;HAL_ATASetModes
+        NullEntry ;HAL_ATACableID
+
+        HALEntry HAL_InitDevices
+
+        NullEntry ;HAL_KbdScanSetup
+        NullEntry ;HAL_KbdScan
+        NullEntry ;HAL_KbdScanFinish
+        NullEntry ;HAL_KbdScanInterrupt
+
+	NullEntry ;HAL_PhysInfo
+
+	HALEntry  HAL_USBControllerInfo
+
+	NullEntry ;HAL_MonitorLeadID
+	NullEntry ;HAL_Video_Render
+
+	NullEntry ;HAL_USBPortPower
+	NullEntry ;HAL_USBPortStatus
+	NullEntry ;HAL_USBPortIRQ
+
+	NullEntry ;HAL_Video_IICOp
+
+HAL_Entries     * (.-HAL_EntryTable)/4
+
+; R11 is used as pointer to RISC OS entry table throughout pre-MMU stage.
+        MACRO
+        CallOSM $entry, $reg
+        LDR     ip, [v8, #$entry*4]
+        MOV     lr, pc
+        ADD     pc, v8, ip
+        MEND
+
+        MACRO
+        CallOS  $entry
+        ASSERT  $entry <= HighestOSEntry
+        MOV     lr, pc
+        LDR     pc, OSentries + 4*$entry
+        MEND
+
+
+start   MOV	R1,#65
+	BL 	serial
+
+	B realstart
+
+crashit B crashit
+
+serial	MOV 	R0,#0x7F000000
+	ORR     R0,R0,#0x5000
+	LDR	R2,[R0,#16]
+	TST     R2,#2
+	BEQ 	serial
+
+	STR	R1,[R0,#32]
+
+	MOV 	PC,LR
+
+serial2	LDR	R2,[R0,#16]
+	TST     R2,#2
+	BEQ 	serial2
+
+	STR	R1,[R0,#32]
+
+	MOV 	PC,LR
+
+realstart
+	ADRL    R5, HAL_Base + 64*1024          ; R5 -> RISC OS image
+
+        LDR     R11, [R5, #OSHdr_Entries]
+        ADD     R11, R11, R5                    ; R11 -> RISC OS entry table
+
+;	MOV	R1,#65
+;	BL      serial
+
+;	MOV 	R1,#66
+;	BL	serial
+
+        MOV     R0, #0
+        CallOSM OS_InitARM
+
+;	MOV 	R1,#66
+;	BL	serial
+
+;	MOV	a1,#0x48000000
+;	MOV	a2,#0xB0
+;	STR	a2,[a1,#0x28]
+
+	MOV	a1,#0
+	MOV	a2,#0x50000000
+	ADD	a2,a2,#0x500000
+;	ADD	a2,a2,#0x00400000
+	MOV	a3,#0x00800000
+	ADD	a3,a3,a2
+	MOV	a4,#-1
+
+	ADD	sp,a2,#4096
+	STR	a1,[sp,#-4]!
+	CallOSM	OS_AddRAM
+
+
+;	MOV	R1,#65
+;	Push	"R1"
+;	MOV	R1,#0
+;	Pull	"R1"
+;;	BL 	serial
+
+;	MOV	a2,#0x38000000
+;	MOV	a3,#0x00800000
+;	ADD	a3,a3,a2
+;	MOV	a4,#-1
+
+;	STR	a1,[sp,#-4]!
+;	MOV	a1, #0
+;	CallOSM	OS_AddRAM
+
+
+;	MOV	R1,#67
+;	BL	serial
+
+	ADRL    R1, HAL_Base + 64*1024
+	ADRL	R2, HALdescriptor
+	MOV	R3, R0
+	MOV	R0, #13
+	CallOSM	OS_Start
+	;B crashit
+;
+;
+;        MOV     R1, R5
+;        ADRL    R2, HALdescriptor
+;
+;        CallOSM OS_Start
+
+serial8 STMDB   sp!,{r1,r3,lr}
+        MOV 	r3,#28
+s8l     MOV	r1,r4,LSR r3
+	AND	r1,r1,#15
+	CMP	r1,#10
+	ADDCC	r1,r1,#48
+	ADDCS	r1,r1,#55
+	BL	serial2
+	SUBS	r3,r3,#4
+	BPL 	s8l
+
+	MOV	r1,#13
+	BL	serial2
+	MOV	r1,#10
+	BL	serial2
+
+	LDMIA	sp!,{r1,r3,pc}
+
+serial3	MOV	r0,#0x50000000
+	B	serial2
+
+serials STMDB 	sp!,{r1,r3,lr}
+ssl	LDRB	r1,[r4],#1
+	TST	r1,r1
+	BEQ	sdone
+	BL	serial2
+	B ssl
+
+sdone   LDMIA	sp!,{r1,r3,pc}
+
+serialn STMDB 	sp!,{lr}
+	MOV	r1,#13
+	BL	serial2
+	MOV	r1,#10
+	BL	serial2
+	LDMIA	sp!,{pc}
+
+Timer_txt = "Timer Address = "
+	= 0
+UART_txt = "UART Address = "
+	 = 0
+INT_txt  = "INT Address = "
+	 = 0
+CLK_txt	 = "CLK Address = "
+	 = 0
+LCD_txt	 = "LCD Address = "
+	 = 0
+MEM_txt	 = "MEM Address = "
+	 = 0
+CLKs_txt = "MPLLCON = "
+	 = 0
+CLKd_txt = "CLKDIVN = "
+	 = 0
+CLKc_txt = "CLOCKCON = "
+	 = 0
+GPIO_txt = "GPIO = "
+	 = 0
+Ready	 = "HAL_Init complete"
+	 = 0
+
+	ALIGN
+
+HAL_Init
+        Entry
+
+	STMDB	sp!,{r0-r1}
+
+;	MOV	r0,#0x50000000
+;	MOV	r1,#65
+;	BL	serial
+;	MOV	r1,#66
+;	BL	serial
+;
+;	MOV	r1,#13
+;	BL	serial
+;	MOV	r1,#10
+;	BL 	serial
+;
+	LDMIA	sp!,{r0-r1}
+
+        BL      SetUpOSEntries
+
+;	MOV     r1,#67
+;	BL      serial
+
+;	MOV	r0,#10
+;	BL	serial
+;	MOV	r1,#13
+;	BL	serial
+
+;;HL_halt
+;	B 	HL_halt
+;	ADRL	r1,OSentries
+;	BL	serial8
+;;
+;	MOV	r1,#13
+;	BL	serial
+;	MOV	r1,#10
+;	BL 	serial
+;
+;        MOV	r4,pc
+;	BL	serial8
+;
+;	MOV	r1,#13
+;	BL	serial
+;;	MOV	r1,#10
+ ;	BL 	serial
+
+;	LDR	r4,OSentries+4*OS_MapInIO
+;	BL	serial8
+
+;;	MOV	r1,#13
+;	BL	serial
+;	MOV	r1,#10
+;	BL 	serial
+
+        MOV     a1, #0		;Map in UART
+        LDR     a2, =0x7F005000
+        MOV     a3, #0x1000
+        CallOS  OS_MapInIO
+
+	STR	a1,UART_Address
+	MOV	a2,#0
+	STR	a2,[a1,#8]
+
+;;	MOV 	r1, #13
+;	BL	serial3
+;	MOV	r1, #10
+;	BL 	serial3
+
+	ADR	r4,UART_txt
+	MOV	r0,a1
+	BL 	serials
+	MOV	r4, a1
+	MOV	r0, r4
+	BL	serial8
+
+	;LDR	r4,UART_Address
+	;BL	serial8
+
+        ;MOV     a1, #0		;Map in MEMCTRL
+        ;MOV     a2, #0x48000000
+        ;MOV     a3, #0x100000
+        ;CallOS  OS_MapInIO
+	;STR	a1,MEM_Address
+
+	;ADR	r4,MEM_txt
+	;LDR	r0,UART_Address
+	;BL 	serials
+	;MOV	r4, a1
+	;MOV	r0, r4
+	;BL	serial8
+
+	;LDR	r4,MEM_Address
+	;BL	serial8
+        ;
+        ;MOV     a1, #0		;Map in CLK
+        ;MOV     a2, #0x4C000000
+        ;MOV     a3, #0x100000
+        ;CallOS  OS_MapInIO
+        ;
+	;STR	a1,CLK_Address
+        ;
+	;ADR	r4,CLK_txt
+	;LDR	r0,UART_Address
+	;BL	serials
+        ;
+	;LDR	r4,CLK_Address
+	;BL	serial8
+        ;
+        ;
+	;ADR	r4, CLKs_txt
+	;BL	serials
+	;LDR	r5,CLK_Address
+	;LDR	r4,[r5,#4]
+	;BL 	serial8
+        ;
+	;ADR	r4, CLKd_txt
+	;BL	serials
+	;LDR	r5,CLK_Address
+	;LDR	r4,[r5,#0x14]
+	;BL 	serial8
+        ;
+	;ADR	r4, CLKc_txt
+	;BL	serials
+	;LDR	r5,CLK_Address
+	;LDR	r4,[r5,#0x0C]
+	;BL 	serial8
+        ;
+        MOV     a1, #0		;Map in TIMER
+        LDR     a2, =0x7F006000
+        MOV     a3, #0x1000
+        CallOS  OS_MapInIO
+	STR	a1, Timer_Address
+
+	ADRL	r4,Timer_txt
+	LDR	r0,UART_Address
+	BL	serials
+
+	LDR	r4,Timer_Address
+	BL	serial8
+
+	LDR	r0,Timer_Address
+
+;Set up timer
+;PCLK = 66mhz ish
+	;MOV	r0, a1
+	MOV	r1, #0xF00 	;Prescaler
+	STR	r1, [r0]
+	MOV	r1, #0     	;Divider
+	STR	r1, [r0,#4]
+	MOV	r1, #0xFF00	;Time
+	STR	r1, [r0,#0x3C]
+	MOV	r1, #0x600000 	;Control
+	STR	r1, [r0,#8]
+	MOV	r1, #0x400000 	;Control
+	STR	r1, [r0,#8]
+	MOV	r1, #0x500000 	;Control
+	STR	r1, [r0,#8]
+	MOV	r1, #0x210	;Interrupt enable
+	STR	r1, [r0,#0x44]
+
+;Timer base now = 66/16 = 4.1mhz
+
+
+        MOV     a1, #0		;Map in INT
+        LDR     a2, =0x71200000
+        MOV     a3,   #0x200000
+        CallOS  OS_MapInIO
+	STR	a1, INT_Address
+
+	ADRL	r4,INT_txt
+	LDR	r0,UART_Address
+	BL	serials
+
+	LDR	r4,INT_Address
+	BL	serial8
+
+	LDR	a1,INT_Address
+
+	MOV	a2,#0
+	STR	a2,[a1,#0xC]
+	MOV	a2,#0xFFFFFFFF
+	STR	a2,[a1,#0x14]
+	STR	a2,[a1,#0x1C]
+	STR     a2,[a1,#0x24]
+	ADD	a1,a1,#0x100000
+	STR	a2,[a1,#0x14]
+	STR	a2,[a1,#0x1C]
+	STR	a2,[a1,#0x24]
+        SUB     a1,a1,#0x100000
+
+;	MOV	a2,#0x18
+	MOV	a3,#0x7C
+        ADD	a1,a1,#0x100
+	ADD	a4,a1,#0x100000
+	MOV	a2,#31
+setlp
+	AND	a2,a2,#31
+
+
+	STR	a2,[a1,a3]
+	ORR	a2,a2,#32
+	STR	a2,[a4,a3]
+	SUB	a2,a2,#1
+	SUBS	a3,a3,#4
+	BNE	setlp
+
+;Set up interrupt controller
+;Just disable everything!
+	;MOV	r0, a1
+        ;MOV	r1, #0
+	;STR	r1, [r0,#4] ;All interrupts in INT mode
+	;STR	r1, [r0,#0xC] ;Normal priorities
+        ;
+	;MOV	r1, #-1
+	;STR	r1, [r0]
+	;STR	r1, [r0,#0x10] ;No interrupts requested
+	;STR	r1, [r0,#0x18] ;No sub interrupts requested
+	;STR	r1, [r0,#8] ;All interrupts masked
+	;STR	r1, [r0,#0x1C] ;All sub interrupts masked
+
+        ;
+        ;MOV     a1, #0		;Map in GPIO
+        ;MOV     a2, #0x56000000
+        ;MOV     a3, #0x100000
+        ;CallOS  OS_MapInIO
+	;STR	a1, GPIO_Address
+
+	;MOV	r0, a1
+	;LDR	r1, =0x7FFFFF
+	;STR	r1, [r0]
+	;LDR	r1, =0x44555
+	;STR	r1, [r0,#0x10]
+	;LDR	r1, =0x7FF
+	;STR	r1, [r0,#0x18]
+	;LDR	r1, =0xAAAAAAAA
+	;STR	r1, [r0,#0x20]
+	;LDR	r1, =0xFFFF
+	;STR	r1, [r0,#0x28]
+	;LDR	r1, =0xAAAAAAAA
+	;STR	r1, [r0,#0x30]
+	;LDR	r1, =0xFFFF
+	;STR	r1, [r0,#0x38]
+	;LDR	r1, =0xAAAAA800
+	;STR	r1, [r0,#0x40]
+	;LDR 	r1, =0xFFFF
+	;STR	r1, [r0,#0x48]
+	;LDR	r1, =0x55AA
+	;STR	r1, [r0,#0x50]
+	;MOV	r1, #0xFF
+	;STR	r1, [r0,#0x58]
+        ;LDR	r1, =0xFF95FFBA
+	;STR	r1, [r0,#0x60]
+	;LDR	r1, =0xFFFF
+	;STR	r1, [r0,#0x68]
+	;LDR	r1, =0x2AFAAA
+	;STR	r1, [r0,#0x70]
+	;LDR	r1, =0x7FF
+	;STR	r1, [r0,#0x78]
+	;LDR	r1, =0x2AAAAAA
+	;STR	r1, [r0,#0xD0]
+	;LDR	r1, =0x1FFF
+	;STR	r1, [r0,#0xD8]
+
+        MOV     a1, #0		;Map in LCD
+        LDR     a2, =0x77100000
+        MOV     a3, #0x100000
+        CallOS  OS_MapInIO
+	STR	a1, LCD_Address
+
+	ADRL	r4,LCD_txt
+	LDR	r0,UART_Address
+	BL	serials
+
+	LDR	r4,LCD_Address
+	BL	serial8
+
+	LDR	r0,LCD_Address
+
+	MOV	r1, #0xC
+	STR	r1, [r0,#0x20]
+	MOV	r1, #0
+	STR	r1, [r0,#0x24]
+	STR	r1, [r0,#0x28]
+	STR	r1, [r0,#0x2C]
+	STR	r1, [r0,#0x30]
+
+	STR	r1, [r0,#0x40]
+	LDR	r1, = 272 + (480 << 11)
+	STR	r1, [r0,#0x44]
+	LDR	r1, = 480 * 272 * 4
+	STR	r1, [r0,#0x48]
+
+	LDR	r1, = 1 + (1 << 8) + (1 << 16) + (1 << 24)
+	STR	r1, [r0,#0x10]
+	LDR	r1, = 39 + (2 << 8) + (1 << 16) + (0 << 24)
+	STR	r1, [r0,#0x14]
+	LDR	r1, = 479 + (271 << 11)
+	STR	r1, [r0,#0x18]
+
+	MOV	r1, #0x60
+	STR	r1, [r0, #4]
+	MOV	r1, #0
+	STR	r1, [r0, #8]
+	STR	r1, [r0]
+
+	LDR	r1, = 0x50100000
+	STR	r1, [r0, #0xA0]
+	STR	r1, [r0, #0xA4]
+	LDR	r1, = 0x50100000 + (640 * 272)
+	STR	r1, [r0,#0xD0]
+	STR	r1, [r0,#0xD4]
+	LDR	r1, = 480 + (160 << 13)
+	STR	r1, [r0,#0x100]
+
+	MOV	r1, #0xD
+	ORR	r1, r1, #0x20000
+	STR	r1, [r0,#0x20]
+	MOV	r1, #0x13
+	ORR	r1, r1, #(9 << 6)
+	ORR	r1, r1, #0x80
+	STR	r1, [r0]
+
+	MOV	r1, #0
+	STR     r1, [r0,#0x130]
+
+	STR	r1, [r0,#0x140]
+	STR	r1, [r0,#0x148]
+	STR	r1, [r0,#0x150]
+	STR	r1, [r0,#0x158]
+
+	STR	r1, [r0,#0x170]
+	STR	r1, [r0,#0x180]
+	MOV	r1,#1
+	STR	r1, [r0,#0x1A0]
+	MOV	r1,#0
+	STR	r1, [r0,#0x1A4]
+	STR	r1, [r0,#0x1B0]
+	STR	r1, [r0,#0x1B4]
+
+	MOV	r1, #-1
+	STR	r1, [r0,#0x144]
+	STR	r1, [r0,#0x14C]
+	STR	r1, [r0,#0x154]
+	STR	r1, [r0,#0x15C]
+
+        MOV     a1, #0		;Map in host interface
+        MOV     a2, #0x74000000
+        MOV     a3, #0x1000
+        CallOS  OS_MapInIO
+
+	MOV	a2, #0
+	STR	a2, [a1, #0xC]
+
+        MOV     a1, #0		;Map in host interface
+        LDR     a2, =0x74108000
+        MOV     a3, #0x1000
+        CallOS  OS_MapInIO
+
+	MOV	a2, #0
+	STR	a2, [a1, #0xC]
+
+
+        MOV     a1, #0		;Map in system controller
+        LDR     a2, =0x7E00F000
+        MOV     a3, #0x1000
+        CallOS  OS_MapInIO
+	LDR	a2, [a1, #0x30]
+	ORR	a2, a2, #8
+	STR	a2, [a1, #0x30]
+	LDR	a2, [a1, #0x38]
+	ORR	a2, a2, #0x40000000
+	STR	a2, [a1, #0x38]
+	LDR	a2, [a1, #0x900]
+	ORR	a2,a2,#0x10000
+	STR	a2, [a1, #0x900]
+
+
+
+        MOV     a1, #0		;Map in GPIO
+        LDR     a2, =0x7F008000
+        MOV     a3, #0x1000
+        CallOS  OS_MapInIO
+
+	Push "a1"
+	ADRL	r4,GPIO_txt
+	LDR	r0,UART_Address
+	BL	serials
+
+	Pull "r4"
+	Push "r4"
+
+	BL	serial8
+	Pull "a1"
+
+	LDR	a2, [a1, #0x1A0]
+	BIC	a2, a2, #3
+	ORR	a2, a2, #1
+	STR	a2, [a1, #0x1A0]
+	LDR	a2, [a1, #0x80]
+	BIC	a2, a2, #15
+	ORR	a2, a2, #1
+	STR	a2, [a1, #0x80]
+	LDR	a2, [a1, #0x84]
+	ORR	a2, a2, #1
+	STR	a2, [a1, #0x84]
+
+	LDR	a2, =0xAAAAAAAA
+	STR	a2, [a1, #0x100]
+	STR	a2, [a1, #0x120]
+
+	;LDR	r0,LCD_Address
+	;LDR	r1, = (4 << 8) ;4 << 8
+	;ORR	r1, r1, #((3<<5) + (11<<1))
+	;STR	r1, [r0]
+	;LDR	r1, = 271 << 14
+;	;ORR	r1, r1, #(1 << 24)
+	;ORR	r1, r1, #(4 << 6)
+	;ORR	r1, r1, #12
+;	;ORR	r1, r1, #1
+	;STR	r1, [r0, #4]
+        ;LDR	r1, = 479 << 8
+	;ORR	r1, r1, #(35 << 19)
+        ;ORR	r1, r1, #18
+	;STR	r1, [r0, #8]
+        ;MOV	r1, #12 ;4
+	;STR	r1, [r0, #12]
+	;MOV	r1, #(1<<12)
+	;;MOV	r1, #(1<<11)
+	;ORR	r1, r1, #(1<<9)
+	;ORR	r1, r1, #(1<<8)
+	;ORR	r1, r1, #(1<<3)
+	;ORR	r1, r1, #2
+;	MOV	r1, #0x308
+	;STR	r1, [r0, #16]
+	;MOV	r1, #(0x30000000 >> 1)
+	;STR	r1, [r0, #0x14] ;Start
+	;MOV	r1, #0x2A800
+	;ORR	r1, r1, #0x10000
+	;STR	r1, [r0, #0x18] ;End
+	;MOV	r1, #240
+;	ORR	r1, r1, #(80 << 11)   Modulo
+	;STR	r1, [r0, #0x1C]
+	;MOV	r1, #0
+	;STR	r1, [r0, #0x50]
+	;STR	r1, [r0, #0x60]
+
+	;MOV	r1, #1
+	;STR	r1, [r0, #0x5C]
+
+	;LDR	r1, [r0]
+	;ORR	r1, r1, #1
+	;STR	r1, [r0]
+
+;	MOV	r1, #0x1000000
+;	ORR	r1, r1, #0xFF
+;        STR	r1, [r0, #0x50]
+
+        MOV     a1, #0		;Map in USB
+        LDR     a2, =0x74300000
+        MOV     a3, #0x100000
+        CallOS  OS_MapInIO
+	STR	a1, USB_Address
+        ;
+        ;MOV     a1, #0		;Map in RTC
+        ;MOV     a2, #0x57000000
+        ;MOV     a3, #0x100000
+        ;CallOS  OS_MapInIO
+	;STR	a1, RTC_Address
+        ;
+	;MOV	a2, #1
+	;STRB	a2, [a1, #0x40]
+        ;
+	;MOV	r4, a1
+	;LDR	r0, UART_Address
+	;BL	serial8
+        ;
+	;LDR 	r0, UART_Address
+	;ADRL	r4, Ready
+	;BL	serials
+	;BL	serialn
+
+;	MOV 	r1, #13
+;	BL	serial3
+;	MOV	r1, #10
+;	BL 	serial3
+
+	;MOV	R0, a1
+	;MOV	R1, #68
+	;BL 	serial2
+
+;	B crashit
+
+;        STR     a1, IO_Address
+;        ADD     a2, a1, #IOMDPhys - IOPhys
+;        STR     a2, IOMD_Address
+;        ADD     a3, a1, #VIDCPhys - IOPhys
+;        STR     a3, VIDC_Address
+;
+;        LDRB    a1, [a2, #IOMD_ID0]
+;        LDRB    a4, [a2, #IOMD_ID1]
+;        ORR     a1, a1, a4, LSL #8
+;        LDR     a4, =IOMD_Original
+;        TEQ     a1, a4
+;        MOVEQ   ip, #0                    ; assume Medusa
+;        MOVNE   ip, #IOST_7500            ; else assume Morris
+;        STRB    ip, IOSystemType
+;
+;        MOV     a1, #0
+;        MOV     a2, #EASIPhys
+;        MOV     a3, #EASISize
+;        CallOS  OS_MapInIO
+;        STR     a1, EASI_Address
+
+;        BL      Video_init
+;
+;	LDR 	a1, IOMD_Address  	; SuperIO at IOMD-0x1f0000
+;	SUB	a1, a1, #0x1f0000
+;
+;	MOV	a2, #0x55               ; Enter config mode
+;	STRB	a2, [a1, #0xfc0]
+;	STRB	a2, [a1, #0xfc0]
+;	MOV	a2, #0x0d
+;	STRB	a2, [a1, #0xfc0]
+;
+;	ADR	a2, SuperIOTab
+;SPL	LDRB 	a3, [a2], #1
+;	CMP	a3, #0xff
+;	LDRNEB  a4, [a2], #1
+;	STRNEB	a3, [a1, #0xfc0]
+;	STRNEB  a4, [a1, #0xfc4]
+;	BNE 	SPL
+;
+;	MOV 	a2, #0xaa       	; Leave config mode
+;	STRB	a2, [a1, #0xfc0]
+;
+        EXIT
+;
+; Initialise and relocate the entry table.
+SetUpOSEntries  ROUT
+        STMDB	sp!,{lr}
+;	STMDB	sp!,{r0-r1}
+;;;	MOV	r1,#65
+;	BL	serial
+;	LDMIA	sp!,{r0-r1}
+
+        STR     a1, OSheader
+        LDR     a2, [a1, #OSHdr_NumEntries]
+        CMP     a2, #HighestOSEntry+1
+        MOVHI   a2, #HighestOSEntry+1
+
+        ADR     a3, OSentries
+        LDR     a4, [a1, #OSHdr_Entries]
+        ADD     a4, a4, a1
+
+;	STMDB 	sp!,{r0-r4}
+;	MOV	r4, a2
+;	BL 	serial8
+;	LDMIA	sp!,{r0-r4}
+
+05      SUBS    a2, a2, #1
+        LDR     ip, [a4, a2, LSL #2]
+        ADD     ip, ip, a4
+        STR     ip, [a3, a2, LSL #2]
+        BNE     %BT05
+
+;	MOV	r1,#66
+;	BL	serial
+
+        LDMIA	sp!,{pc}
+;
+;
+
+HAL_Null
+        MOV     pc, lr
+
+HAL_DebugTX
+	STMDB   sp!,{r0-r4,lr}
+	MOV	r1,a1
+	LDR	r0,UART_Address
+	BL      serial2
+	LDMIA 	sp!,{r0-r4,pc}
+
+HAL_DebugRX
+	STMDB	sp!,{r1-r4,lr}
+	LDR	r1,UART_Address
+	LDR	r0,[r1,#16]
+
+	TST	r0,#1
+	MOVEQ	r0,#-1
+	LDMEQIA	sp!,{r1-r4,pc}
+
+        LDR	r0,[r1,#0x24]
+	;MOV	r0,#-1
+	LDMIA	sp!,{r1-r4,pc}
+
+
+USBc_txt = "HAL_USBControllerInfo"
+	 = 0
+
+HAL_USBControllerInfo
+	CMP	r0,#0  ;Only one host controller
+	MOV	r0,#0
+	MOVNE	pc,lr
+
+;	STMDB	sp!,{r0-r4,lr}
+;	LDR	r1,UART_Address
+;	ADR	r4,USBc_txt
+;	BL	serials
+;	BL	serialn
+;	LDMIA	sp!,{r0-r4,lr}
+
+	STR	r0,[r1] ;OHCI controller
+	STR	r0,[r1,#4] ;Flags
+	LDR	r0,USB_Address
+	STR	r0,[r1,#8] ;Address
+	MOV	r0, #47
+	STR	r0,[r1,#12] ;Device
+
+	MOV 	pc,lr
+
+HAL_HardwareInfo
+	MOV	ip, #0
+	STR	ip, [a1]
+	STR	ip, [a2]
+	STR	ip, [a3]
+	MOV	pc, lr
+
+HAL_PlatformInfo
+	MOV	ip, #16
+	STR	ip, [a2]
+	MOV	ip, #31
+	STR	ip, [a3]
+	MOV	pc, lr
+
+HAL_SuperIOInfo
+	MOV	ip, #0
+	STR	ip, [a1]
+	STR	ip, [a2]
+	MOV 	pc, lr
+
+;
+;HAL_ControllerAddress
+;        MOV     a1, #0                  ; Default to "not fitted"
+;        AND     a3, a2, #&FF            ; Get sequence number.
+;        MOV     a2, a2, LSR #8          ; Get controller type.
+;        CMP     a2, #4
+;        ADDLS   pc, pc, a2, LSL #2
+;        MOV     pc, lr
+;        B       ca_EASIspeed
+;        B       ca_EASIspace
+;        MOV     pc, lr
+;        B       ca_VIDC20
+;        B       ca_IOMD
+;
+;ca_EASIspeed
+;        LDR     ip, IOMD_Address
+;        CMP     a3, #EASISlots
+;        ADDLO   a1, ip, #IOMD_ECTCR
+;        MOV     pc, lr
+;
+;ca_EASIspace
+;        LDR     ip, EASI_Address
+;        CMP     a3, #EASISlots
+;        ADDLO   a1, ip, a3, LSL #EASISlotSizeShift
+;        MOV     pc, lr
+;
+;ca_VIDC20
+;        TEQ     a3, #0
+;        LDREQ   a1, VIDC_Address
+;        MOV     pc, lr
+;
+;ca_IOMD
+;        TEQ     a3, #0
+;        LDREQ   a1, IOMD_Address
+;        MOV     pc, lr
+;
+;HAL_HardwareInfo
+;        LDR     ip, =&01010101
+;        STR     ip, [a1]
+;        MOV     ip, #1
+;        STR     ip, [a2]
+;        MOV     ip, #0
+;        STR     ip, [a3]
+;        MOV     pc, lr
+;
+;HAL_SuperIOInfo
+;        LDR     ip, =&00311111
+;        STR     ip, [a1]
+;        LDR     ip, =&00011100
+;        STR     ip, [a2]
+;        MOV     pc, lr
+;
+;HAL_PlatformInfo
+;        ADR     a4, %86
+;        LDR     ip, IOMD_Address
+;        LDRB    ip, [ip, #IOMD_ID0]
+;82
+;        LDR     a1, [a4], #4
+;        TEQ     a1, #&80000000     ;terminator
+;        TEQNE   a1, ip
+;        LDMEQIA a4, {a4,ip}
+;        STREQ   a4, [a2]
+;        STREQ   ip, [a3]
+;        MOVEQ   pc, lr
+;        ADD     a4, a4, #2*4
+;        B       %BT82
+;86
+;        DCD     IOMD_Original :AND: &FF, &00000005, &0000000F
+;        DCD     IOMD_7500     :AND: &FF, &00000001, &0000000F
+;        DCD     IOMD_7500FE   :AND: &FF, &00000001, &0000000F
+;        DCD     IOMD_IOMD2    :AND: &FF, &0000000F, &0000000F
+;        DCD     &80000000,                       0,         0  ;terminator
+;
+;;must return address of at least 64k of physical space suitable for
+;;cache cleaning (at least 4k aligned, preferably 64k aligned)
+;;or, return -1 if HAL knows not needed (eg. knows core in system)
+;;
+;HAL_CleanerSpace
+;        [ {FALSE}
+;          ???don't know what do yet, in generic memory size case
+;        |
+;          MOV   a1, #&10000000  ; return start of physical RAM
+;        ]
+;        MOV     pc, lr
+;
+;        LTORG
+;
+;
+;        ! 0, "TODO - Sort out keyboard scan for IOMD HAL"
+;HAL_KbdScan
+;        MOV     a1, #&C0000000 ; scan complete, keyboard present
+;HAL_KbdScanSetup
+;HAL_KbdScanInterrupt
+;HAL_KbdScanFinish
+;        MOV     pc, lr
+;
+;SuperIOTab
+;	= 0x01,0x87,0x02,0x1c,0x03,0x78,0x04,0x03,0x05,0x00,0x06,0xff
+;	= 0x07,0x00,0x08,0x00,0x09,0x00,0x0a,0x00,0x00,0xbb,0xff
+;
+
+;HAL_DebugTX
+;	B serial
+
+HAL_InitDevices
+	Entry
+
+	;BL 	RTC_Init
+
+	EXIT
+
+
+        END
diff --git a/s/IIC b/s/IIC
new file mode 100644
index 0000000000000000000000000000000000000000..417401725c0c393ecd92465335fe50a249cb0079
--- /dev/null
+++ b/s/IIC
@@ -0,0 +1,66 @@
+; Copyright 2011 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.
+;
+        GET     Hdr:ListOpts
+        GET     Hdr:Macros
+        GET     Hdr:System
+        GET     Hdr:Machine.<Machine>
+        GET     Hdr:ImageSize.<ImageSize>
+        $GetIO
+
+        GET     Hdr:OSEntries
+        GET     Hdr:HALEntries
+
+        GET     hdr.StaticWS
+
+        EXPORT  HAL_IICBuses
+        EXPORT  HAL_IICType
+        EXPORT  HAL_IICSetLines
+        EXPORT  HAL_IICReadLines
+
+        AREA    |Asm$$Code|, CODE, READONLY, PIC
+
+HAL_IICBuses
+        MOV     a1, #1
+        MOV     pc, lr
+
+HAL_IICType
+        MOV     a1, #IICFlag_LowLevel
+ [ MaxI2Cspeed >= 400
+        ORR     a1, a1, #IICFlag_Fast
+ ]
+        MOV     pc, lr
+
+; In:  a1 = bus number, a2 = SDA, a3 = SCL
+; Out: a1 = SDA, a2 = SCL
+HAL_IICSetLines
+        LDRB    ip, IOCRSoftCopy
+        LDR     a4, IOMD_Address
+        ADD     a2, a2, a3, LSL #1      ; bit 1 = SCL, bit 0 = SDA
+        BIC     ip, ip, #3
+        ORR     ip, ip, a2
+        STRB    ip, IOCRSoftCopy
+        STRB    ip, [a4, #IOCControl]
+10      LDRB    a1, [a4, #IOCControl]
+        MOV     a2, a1, LSR #1
+        AND     a1, a1, #1
+        AND     a2, a2, #1
+        MOV     pc, lr
+
+HAL_IICReadLines
+        LDR     a4, IOMD_Address
+        B       %BT10
+
+        END
+
diff --git a/s/Interrupts b/s/Interrupts
new file mode 100644
index 0000000000000000000000000000000000000000..770dbf159b9901da49d54ae9a2b0100f5b4e0749
--- /dev/null
+++ b/s/Interrupts
@@ -0,0 +1,312 @@
+; Copyright 2011 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.
+;
+        GET     Hdr:ListOpts
+        GET     Hdr:Macros
+        GET     Hdr:System
+        GET     Hdr:Machine.<Machine>
+        GET     Hdr:ImageSize.<ImageSize>
+        $GetIO
+        GET     Hdr:DevNos
+
+        GET     Hdr:OSEntries
+        GET     Hdr:HALEntries
+
+        GET     hdr.StaticWS
+
+        AREA    |Asm32$$Code|, CODE, READONLY, PIC, ALIGN=5
+
+NoInterrupt     * 38
+
+        EXPORT  HAL_IRQSource
+        EXPORT  HAL_IRQEnable
+        EXPORT  HAL_IRQDisable
+        EXPORT  HAL_IRQClear
+        EXPORT  HAL_IRQStatus
+;        EXPORT  HAL_FIQSource
+;        EXPORT  HAL_FIQEnable
+;        EXPORT  HAL_FIQDisable
+;        EXPORT  HAL_FIQDisableAll
+;        EXPORT  HAL_FIQClear
+;        EXPORT  HAL_FIQStatus
+
+	IMPORT  serial2
+	IMPORT	serials
+	IMPORT	serialn
+	IMPORT	serial8
+
+HAL_IRQSource
+	;STMDB	sp!,{r0-r5,lr}
+	;LDR	r0, UART_Address
+	;ADR	r4, IRQSR2_txt
+	;BL 	serials
+	;LDMIA	sp!,{r0-r5,lr}
+
+        LDR     r3, INT_Address
+	LDR	r0, [r3,#0xF00]
+        CMP	r0, #0
+	ADDEQ	r3, r3, #0x100000
+	LDREQ	r0, [r3,#0xF00]
+	;STMDB	sp!,{r0-r5,lr}
+	;MOV	r4,r0
+	;LDR	r0, UART_Address
+	;BL	serial8
+	;LDMIA	sp!,{r0-r5,lr}
+;	LDR	r1, [r3]
+;
+;        MOV     r0, #31
+;	MOV	r2, #1
+;irqlp   CMP	r0, #-1
+;	BEQ 	noirq
+;	TST     r1, r2, LSL r0
+;	SUBEQ   r0,r0,#1
+;	BEQ 	irqlp
+;
+;noirq
+	;STMDB	sp!,{r0-r5,lr}
+        ;STMDB	sp!,{r0}
+	;LDR	r0, UART_Address
+	;ADR	r4, IRQSR_txt
+	;;BL 	serials
+	;;LDMIA	sp!,{r4}
+	;BL	serial8
+	;LDMIA	sp!,{r0-r5,pc}
+
+	MOV 	pc,lr
+
+;HAL_FIQSource
+;        LDR     r3, IOMD_Address
+;        LDRB    r0, [r3, #IOCFIQREQ]
+;        ORR     r0, r0, r0, LSR #4
+;        ORR     r0, r0, r0, LSR #2
+;        ORR     r0, r0, r0, LSR #1
+;        ADD     r0, r0, #1              ; r0 = 2, 4, 8, 16, 32, 64, 128 or 256
+;        MOV     r1, #&0E800000
+;        MUL     r0, r1, r0              ; r0>>29 = 0, 1, 3, 7, 6, 5, 2 or 4
+;        LDRB    r0, [pc, r0, LSR #29]
+;        MOV     pc, lr
+;	        DCB     0, 1, 6, 2, 7, 5, 4, 3
+
+;HAL_FIQEnable
+;        LDR     a4, IOMD_Address
+;        MOV     ip, #1
+;        MRS     a3, CPSR
+;        MOV     ip, ip, LSL a1
+;        ORR     a2, a3, #F32_bit+I32_bit
+;        MSR     CPSR_c, a2
+;        LDRB    a1, [a4, #IOCFIQMSK]
+;        ORR     a2, a1, ip
+;        STRB    a2, [a4, #IOCFIQMSK]
+;        MSR     CPSR_c, a3
+;        AND     a1, a1, ip
+;        MOV     pc, lr
+
+;HAL_FIQDisable
+;        LDR     a4, IOMD_Address
+;        MOV     ip, #1
+;        MRS     a3, CPSR
+;        MOV     ip, ip, LSL a1
+;        ORR     a2, a3, #F32_bit+I32_bit
+;        MSR     CPSR_c, a2
+;        LDRB    a1, [a4, #IOCFIQMSK]
+;        BIC     a2, a1, ip
+;        STRB    a2, [a4, #IOCFIQMSK]
+;        MSR     CPSR_c, a3
+;        AND     a1, a1, ip
+;        MOV     pc, lr
+;
+;HAL_FIQDisableAll
+;        LDR     a4, IOMD_Address
+;        MOV     a1, #0
+;        STRB    a1, [a4, #IOCFIQMSK]
+;        MOV     pc, lr
+;
+;HAL_FIQClear
+;        MOV     pc, lr
+;
+;HAL_FIQStatus
+;        LDR     a4, IOMD_Address
+;        MOV     ip, #1
+;        LDRB    a2, [a4, #IOCFIQSTA]
+;        AND     a1, a2, ip, LSL a1
+;        MOV     pc, lr
+
+
+
+IRQSR2_txt	= "Getting IRQ source"
+		= 10,13,0
+
+IRQEN_txt	= "IRQ enable = "
+		= 0
+IRQDS_txt	= "IRQ disable = "
+		= 0
+IRQCL_txt	= "IRQ clear = "
+		= 0
+IRQSR_txt	= "IRQ source = "
+		= 0
+
+	ALIGN
+
+HAL_IRQEnable
+	STMDB	sp!,{lr}
+;	CMP	a1, #16
+;	LDMEQIA sp!,{pc}
+
+;	STMDB	sp!,{r0-r5}
+;	MOV	r4,a1
+;	LDR	r0, UART_Address
+;	MOV	r4,a1
+;	BL	serial8
+;	LDMIA	sp!,{r0-r5}
+
+	STMDB	sp!,{r0-r5}
+
+	LDR	a2, INT_Address
+	TST	a1, #32
+	ANDNE	a1, a1, #31
+	ADDNE	a2, a2, #0x100000
+
+	MOV	a4, #1
+	MOV	a1, a4, LSL a1
+
+	;LDR	a3, [a2,#8]
+	;BIC	a3, a3, a1
+	STR	a1, [a2,#0x10]
+
+	;STMDB	sp!,{a2}
+
+	STMDB	sp!,{r0-r5}
+	STMDB	sp!,{a2}
+	STMDB	sp!,{a1}
+	LDR	r0, UART_Address
+	ADR	r4, IRQEN_txt
+	BL 	serials
+	LDMIA   sp!,{r4}
+	BL	serial8
+	LDMIA   sp!,{r4}
+	BL	serial8
+	LDMIA	sp!,{r0-r5}
+
+	;LDMIA	sp!,{a2}
+	;STMDB	sp!,{r0-r5}
+	;LDR	r0, UART_Address
+	;MOV	r4,a2
+	;BL	serial8
+	;LDMIA	sp!,{r0-r5}
+
+	LDMIA	sp!,{r0-r5}
+
+	LDMIA	sp!,{pc}
+	MOV 	pc,lr
+
+HAL_IRQDisable
+	;STMDB	sp!,{lr}
+	;STMDB 	sp!,{r0-r5}
+
+	LDR	a2, INT_Address
+	TST	a1, #32
+	ANDNE	a1, a1, #31
+	ADDNE	a2, a2, #0x100000
+
+	MOV	a4, #1
+	MOV	a1, a4, LSL a1
+
+;	LDR	a3, [a2,#8]
+;	ORR	a3, a3, a1
+	STR	a1, [a2,#0x14]
+
+	;STMDB	sp!,{r0-r5}
+	;STMDB	sp!,{a1}
+	;LDR	r0, UART_Address
+	;ADR	r4, IRQDS_txt
+	;BL 	serials
+	;LDMIA   sp!,{r4}
+	;BL	serial8
+	;LDMIA	sp!,{r0-r5}
+
+	;LDMIA	sp!,{r0-r5}
+	;LDMIA	sp!,{pc}
+	MOV 	pc,lr
+
+HAL_IRQClear
+;	STMDB	sp!,{lr}
+	STMDB	sp!,{r0-r12,lr}
+;	CMP	a1, #16
+;	MOVEQ	a4, #3
+;	LDRQ	a2, LCD_Address
+;	STR
+
+;	STREQ	a4, [a2, #0x54]
+;	STREQ	a4, [a2, #0x58]
+
+;	MOV	a4, #1
+;	MOV	a1, a4, LSL a1
+	CMP	a1,#0x1C
+	LDREQ	a2,Timer_Address
+	LDREQ	a3,[a2,#0x44]
+	ORREQ	a3,a3,#0x200
+	STREQ	a3,[a2,#0x44]
+
+        LDR     a2, INT_Address
+	;TST	a1, #32
+	;ANDNE	a1, a1, #31
+	;ADDNE	a2, a2, #0x100000
+ 	STR	a1, [a2,#0xF00]
+        ADD	a2, a2, #0x100000
+	STR	a1, [a2,#0xF00]
+
+;	STR	a1, [a2, #0x10]
+
+;	MOV	r4,a1
+;;	LDR	r0, UART_Address
+;	BL 	serial8
+	;STMDB	sp!,{r0-r5}
+	;STMDB	sp!,{a1}
+	;ADR	r0, UART_Address
+	;ADR	r4, IRQCL_txt
+	;BL 	serials
+	;LDMIA   sp!,{r4}
+	;BL	serial8
+	;LDMIA	sp!,{r0-r5}
+
+	LDMIA	sp!,{r0-r12,lr}
+
+;	LDMIA	sp!,{pc}
+        MOV     pc, lr
+
+HAL_IRQStatus
+;	MOV	a1,#1
+	;STMDB	sp!,{lr}
+	;STMDB	sp!,{r0-r5}
+	;STMDB	sp!,{a1}
+	;LDR	r0, UART_Address
+	;ADR	r4, IRQST_txt
+	;BL 	serials
+	;LDMIA   sp!,{r4}
+	;BL	serial8
+	;LDMIA	sp!,{r0-r5}
+
+	MOV	a1, #1
+	MOV	a4, #1
+	MOV	a1, a4, LSL a1
+        LDR     a2, INT_Address
+	LDR	a3, [a2]
+	AND	a1, a3, a4
+	;LDMIA	sp!,{pc}
+        MOV     pc, lr
+
+IRQST_txt	= "IRQ status = "
+		= 0
+	ALIGN
+        END
diff --git a/s/MachineID b/s/MachineID
new file mode 100644
index 0000000000000000000000000000000000000000..57c95ddcac7454a2a3201a66bba7a54240c511b1
--- /dev/null
+++ b/s/MachineID
@@ -0,0 +1,245 @@
+; Copyright 2011 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.
+;
+        GET     Hdr:ListOpts
+        GET     Hdr:Macros
+        GET     Hdr:System
+        GET     Hdr:Machine.<Machine>
+        GET     Hdr:ImageSize.<ImageSize>
+        $GetIO
+        GET     Hdr:Proc
+
+        GET     Hdr:OSEntries
+        GET     Hdr:HALEntries
+
+        GET     hdr.StaticWS
+
+        AREA    |Asm$$Code|, CODE, READONLY, PIC
+
+        EXPORT  HAL_MachineID
+
+        IMPORT  HAL_TimerPeriod
+        IMPORT  HAL_TimerSetPeriod
+
+; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+;
+;       ReadUniqueID - Read unique machine ID
+;
+; 10-Dec-93  BCockburn  Modified to leave raw 64 bit ID from chip in RawMachineID
+
+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
+
+HAL_MachineID
+        Entry "r4-r11",8
+        MOV     r0, #0
+        LDR     r1, IOMD_Address
+        MRS     r8, CPSR                                ; remember PSR in r8
+        ORR     r3, r8, #I32_bit+F32_bit
+        MSR     CPSR_c, r3                              ; FIQs and IRQs off
+        LDRB    r3, IOCRSoftCopy
+        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, #0                                  ; no. of bytes to store = 8 bits type + 48 bits ID + 8 bits checksum
+10
+        BL      GetAByte
+        STRB    r6, [sp, r7]
+        ADD     r7, r7, #1
+        CMP     r7, #8
+        BNE     %BT10
+
+        BL      RestoreIOCState
+        MOV     r1, sp
+        BL      CheckCRC
+        BVS     IDError
+        LDMIA   sp, {r0, r1}
+        EXIT
+
+ResetFailed
+        BL      RestoreIOCState
+IDError
+        MOV     r0, #0
+        MOV     r1, #0                                  ; indicate no ID by putting zero here
+        EXIT
+
+RestoreIOCState Entry
+        STRB    r3, [r1, #IOCControl]                   ; put back old value
+        MOV     r0, #0
+        BL      HAL_TimerPeriod
+        MOV     r1, r0
+        MOV     r0, #0
+        BL      HAL_TimerSetPeriod
+        MSR     CPSR_c, r8                              ; restore old interrupt state
+        EXIT
+
+SendResetPulse ROUT
+        SetWire HIGH, Tsyc
+        SetWire LOW, Trstl,,r6
+        SetWire HIGH, Trsth,r10
+        TEQ     r6, #0
+;        ADREQ   r0, IOCBugHappenedError
+        BEQ     %FT05
+        CMP     r10, #3                                 ; H-L-H is ok
+        MOVEQ   pc, lr                                  ; V clear
+;        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
+
+ [ {FALSE} ; only for debugging
+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
+
+CheckCRC ROUT
+        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
+
+        END
diff --git a/s/NVRAM b/s/NVRAM
new file mode 100644
index 0000000000000000000000000000000000000000..ac716bf400aef996f47b394722e1a1680b9fccb0
--- /dev/null
+++ b/s/NVRAM
@@ -0,0 +1,69 @@
+; Copyright 2011 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.
+;
+        GET     Hdr:ListOpts
+        GET     Hdr:Macros
+        GET     Hdr:System
+        GET     Hdr:Machine.<Machine>
+        GET     Hdr:ImageSize.<ImageSize>
+        $GetIO
+
+        GET     Hdr:OSEntries
+        GET     Hdr:HALEntries
+
+        GET     hdr.StaticWS
+
+    	EXPORT	HAL_NVMemoryType
+    	EXPORT	HAL_NVMemorySize
+    	EXPORT  HAL_NVMemoryPageSize
+    	EXPORT	HAL_NVMemoryProtectedSize
+    	EXPORT	HAL_NVMemoryProtection
+    	EXPORT	HAL_NVMemoryIICAddress
+    	EXPORT	HAL_NVMemoryRead
+    	EXPORT	HAL_NVMemoryWrite
+
+        AREA    |Asm$$Code|, CODE, READONLY, PIC
+
+HAL_NVMemoryType
+    	LDR 	R0, =NVMemoryFlag_IIC :OR: NVMemoryFlag_ProtectAtEnd
+        MOV     pc, lr
+
+HAL_NVMemorySize
+    	MOV 	R0, #256
+        MOV     pc, lr
+
+HAL_NVMemoryPageSize
+        MOV     R0, #16
+        MOV     pc, lr
+
+HAL_NVMemoryProtectedSize
+    	MOV 	R0, #0
+        MOV     pc, lr
+
+; in: r0 = 0/1 to unprotect/protect
+HAL_NVMemoryProtection
+        MOV     pc, lr
+
+HAL_NVMemoryIICAddress
+    	MOV 	R0, #&a0
+        MOV     pc, lr
+
+HAL_NVMemoryRead
+        MOV     pc, lr
+
+HAL_NVMemoryWrite
+        MOV     pc, lr
+
+        END
+
diff --git a/s/RTC b/s/RTC
new file mode 100644
index 0000000000000000000000000000000000000000..55e4761c42994564b17649c9949f1c9be15d9726
--- /dev/null
+++ b/s/RTC
@@ -0,0 +1,212 @@
+; Copyright 2011 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.
+;
+        GET     Hdr:ListOpts
+        GET     Hdr:Macros
+        GET     Hdr:System
+        GET     Hdr:Machine.<Machine>
+        GET     Hdr:ImageSize.<ImageSize>
+        $GetIO
+
+        GET     Hdr:OSEntries
+        GET     Hdr:HALEntries
+        GET     Hdr:HALDevice
+        GET     Hdr:RTCDevice
+
+        GET     hdr.StaticWS
+
+
+        AREA    |Asm$$Code|, CODE, READONLY, PIC
+
+        EXPORT  RTC_Init
+
+	IMPORT  serial8
+
+
+;       Note - debug stuff won't work since we don't get passed a HAL workspace pointer!
+;        IMPORT  DebugHALPrint
+;        IMPORT  DebugHALPrintReg
+;        IMPORT  DebugMemDump
+;        IMPORT  DebugHALPrintByte
+
+; TWL/TPS RTC IIC address
+TPSRTC_IIC     * &4b
+
+; Some RTC registers
+SECONDS_REG       * &1C
+RTC_CTRL_REG      * &29
+RTC_STATUS_REG    * &2a
+
+
+        MACRO
+        CallOS  $entry, $tailcall
+        ASSERT  $entry <= HighestOSEntry
+ [ "$tailcall"=""
+        MOV     lr, pc
+ |
+   [ "$tailcall"<>"tailcall"
+        ! 0, "Unrecognised parameter to CallOS"
+   ]
+ ]
+        LDR     pc, OSentries + 4*$entry
+        MEND
+
+RTC_Init
+	STMDB	sp!,{lr}
+	MOV	r0,   #0xF9000000
+	ORR	r0, r0, #0xF00000
+	ADR	r1, RTCDevice
+	LDR	r4, [r1, #HALDevice_Activate]
+	BL	serial8
+	LDMIA	sp!,{lr}
+        ; Just register our HAL Device with the OS
+        MOV     a1, #0
+        ADR     a2, RTCDevice
+        CallOS  OS_AddDevice, tailcall
+
+RTCDevice
+        DCW     HALDeviceType_SysPeri + HALDeviceSysPeri_RTC
+        DCW     HALDeviceID_RTC_TPS65950
+        DCD     HALDeviceBus_Pro
+        DCD     0               ; API version
+        DCD     RTCDesc
+        DCD     0               ; Address - N/A
+        %       12              ; Reserved
+        DCD     RTCActivate
+        DCD     RTCDeactivate
+        DCD     RTCReset
+        DCD     RTCSleep
+        DCD     -1              ; Interrupt N/A
+        DCD     0
+        %       8
+        DCB     RTCTimeFormat_BCD
+        DCB     RTCFormatFlags_BCD_YearLOIsGood ; todo - add RTCFormatFlags_BCD_NeedsYearHelp once NVRAM is implemented
+        %       2
+        DCD     RTCReadTime
+        DCD     RTCWriteTime
+
+RTCDesc
+        DCB "S3C6410 real-time clock",0
+
+        ALIGN
+
+RTCActivate
+        MOV     a1, #1
+RTCDeactivate
+RTCReset
+        MOV     pc, lr
+
+RTCSleep
+        MOV     a1, #0 ; Previously at full power
+        MOV     pc, lr
+
+RTCReadTime
+        ; In:
+        ; a1 = HALDevice ptr
+        ; a2 = RTCTimeStruct ptr
+        ; a3 = IICOp func ptr
+        ; a4 = kernel workspace ptr
+        ; Out:
+        ; a1 = return code
+        ; RTCTimeStruct updated
+        Push    "v1-v3,lr"
+        MOV     v1, a3
+        MOV     v2, a4
+        MOV     v3, a2
+
+	STMDB	sp!, {r2-r12}
+	MOV	r0, #13
+	ORR	r0,r0,#&20000
+	ORR	r0,r0,#&3C0000
+	MOV	r1,#&57000000
+	MOV	r2,#&100000
+	SWI	0x68
+	MOV	a1, r3
+	LDMIA	sp!, {r2-r12}
+
+	;LDR	a1, RTC_Address
+
+	LDRB	a2, [a1, #0x70]
+	STRB	a2, [v3, #RTCTimeStruct_BCD_Seconds]
+	LDRB	a2, [a1, #0x74]
+	STRB	a2, [v3, #RTCTimeStruct_BCD_Minutes]
+	LDRB	a2, [a1, #0x78]
+	STRB	a2, [v3, #RTCTimeStruct_BCD_Hours]
+	LDRB	a2, [a1, #0x7C]
+	STRB	a2, [v3, #RTCTimeStruct_BCD_DayOfMonth]
+	LDRB	a2, [a1, #0x84]
+	STRB	a2, [v3, #RTCTimeStruct_BCD_Month]
+	LDRB	a2, [a1, #0x88]
+	STRB	a2, [v3, #RTCTimeStruct_BCD_YearLO]
+	MOV	a2, #0
+	STRB    a2, [v3, #RTCTimeStruct_BCD_Centiseconds]
+
+        ; Construct a fakey YearHI by looking at YearLO
+        ; Anything 70 or above is considered 1970+, else 2000+
+        ; This should work OK, since RISC OS clamps the time to 1970 for unix compatability (or it does on boot, at least)
+        LDRB    a2, [v3, #RTCTimeStruct_BCD_YearLO]
+        CMP     a2, #&70
+        MOVGE   a3, #&19
+        MOVLT   a3, #&20
+        STRB    a3, [v3, #RTCTimeStruct_BCD_YearHI]
+	MOV	a1, #0
+        ASSERT  RTCRetCode_OK = 0
+        Pull    "v1-v3,pc"
+
+RTCWriteTime
+        ; In:
+        ; a1 = HALDevice ptr
+        ; a2 = RTCTimeStruct ptr
+        ; a3 = IICOp func ptr
+        ; a4 = kernel workspace ptr
+        ; Out:
+        ; a1 = return code
+        Push    "v1-v3,lr"
+        MOV     v1, a3
+        MOV     v2, a4
+        MOV     v3, a2
+        ; Writing the time safely involves several transfers:
+        ; 1. Write 0 to RTC_CTRL_REG to stop the clock (just in case there are any issues with the clock updating while it's being written to)
+        ; 2. Write the new time values
+        ; 3. Write 1 to RTC_CTRL_REG to start the clock
+
+	STMDB	sp!, {r2-r12}
+	MOV	r0, #13
+	ORR	r0,r0,#&20000
+	ORR	r0,r0,#&3C0000
+	MOV	r1,#&57000000
+	MOV	r2,#&100000
+	SWI	0x68
+	MOV	a1, r3
+	LDMIA	sp!, {r2-r12}
+
+;	LDR	a1, RTC_Address
+
+	LDRB	a2, [v3, #RTCTimeStruct_BCD_Seconds]
+	STRB	a2, [a1, #0x70]
+	LDRB	a2, [v3, #RTCTimeStruct_BCD_Minutes]
+	STRB	a2, [a1, #0x74]
+	LDRB	a2, [v3, #RTCTimeStruct_BCD_Hours]
+	STRB	a2, [a1, #0x78]
+	LDRB	a2, [v3, #RTCTimeStruct_BCD_DayOfMonth]
+	STRB	a2, [a1, #0x7C]
+	LDRB	a2, [v3, #RTCTimeStruct_BCD_Month]
+	STRB	a2, [a1, #0x84]
+	LDRB	a2, [v3, #RTCTimeStruct_BCD_YearLO]
+	STRB	a2, [a1, #0x88]
+
+        Pull    "v1-v3,pc"
+
+
+        END
diff --git a/s/Timers b/s/Timers
new file mode 100644
index 0000000000000000000000000000000000000000..02551f963119ec620901a088646b72134bbe47cf
--- /dev/null
+++ b/s/Timers
@@ -0,0 +1,115 @@
+; Copyright 2011 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.
+;
+        GET     Hdr:ListOpts
+        GET     Hdr:Macros
+        GET     Hdr:System
+        GET     Hdr:Machine.<Machine>
+        GET     Hdr:ImageSize.<ImageSize>
+        $GetIO
+
+        GET     Hdr:OSEntries
+        GET     Hdr:HALEntries
+
+        GET     hdr.StaticWS
+
+        AREA    |Asm$$Code|, CODE, READONLY, PIC
+
+        EXPORT  HAL_Timers
+        EXPORT  HAL_TimerDevice
+        EXPORT  HAL_TimerGranularity
+        EXPORT  HAL_TimerMaxPeriod
+        EXPORT  HAL_TimerSetPeriod
+        EXPORT  HAL_TimerPeriod
+        EXPORT  HAL_TimerReadCountdown
+
+        EXPORT  HAL_CounterRate
+        EXPORT  HAL_CounterPeriod
+        EXPORT  HAL_CounterRead
+        EXPORT  HAL_CounterDelay
+
+	EXPORT	HAL_VideoFlybackDevice
+
+	IMPORT	serials
+	IMPORT	serial8
+
+HAL_Timers
+        MOV     a1, #1                  ; 1 timer
+        MOV     pc, lr
+
+HAL_TimerDevice
+        ADD     a1, a1, #28             ; device 14
+        MOV     pc, lr
+
+HAL_VideoFlybackDevice
+	MOV	a1, #-1
+	MOV	pc, lr
+
+HAL_CounterRate
+HAL_TimerGranularity
+        LDR     a1, =4000000            ; 4MHz
+        MOV     pc, lr
+
+HAL_TimerMaxPeriod
+        MOV     a1, #&10000             ; 16-bit counter
+        MOV     pc, lr
+
+TSet_txt	= "Timer set = "
+		= 0
+
+	ALIGN
+
+HAL_TimerSetPeriod
+        LDR     a3, Timer_Address
+
+	STR	a2, [a3, #0x3C]
+
+        ADR     a4, TimerPeriods
+        STR     a2, [a4, a1, LSL #2]
+
+	STMDB	sp!,{r0-r5,lr}
+	STMDB	sp!,{a2}
+	LDR	r0, UART_Address
+	ADR	r4, TSet_txt
+	BL	serials
+	LDMIA	sp!,{r4}
+	BL	serial8
+	LDMIA	sp!,{r0-r5,pc}
+        ;MOV     pc, lr
+
+HAL_TimerPeriod
+        ADR     a4, TimerPeriods
+        LDR     a1, [a4, a1, LSL #2]
+        MOV     pc, lr
+
+HAL_CounterRead
+        MOV     a1, #0
+        ; Fall through
+
+HAL_TimerReadCountdown
+        LDR     a4, Timer_Address
+
+	LDR	a1, [a4, #0x40]
+
+        MOV     pc, lr
+
+HAL_CounterPeriod
+        LDR     a1, TimerPeriods + 0
+        MOV     pc, lr
+
+; If they want n ticks, wait until we've seen n+1 transitions of the clock.
+HAL_CounterDelay
+        MOV     pc, lr
+
+        END
diff --git a/s/Video b/s/Video
new file mode 100644
index 0000000000000000000000000000000000000000..862b519da375fc553425b925096448179ce8825e
--- /dev/null
+++ b/s/Video
@@ -0,0 +1,1177 @@
+; Copyright 2011 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.
+;
+        GET     Hdr:ListOpts
+        GET     Hdr:Macros
+        GET     Hdr:System
+        GET     Hdr:Machine.<Machine>
+        GET     Hdr:ImageSize.<ImageSize>
+        $GetIO
+        GET     Hdr:Proc
+
+        GET     Hdr:OSEntries
+        GET     Hdr:HALEntries
+
+        EXPORT  HAL_Video_PixelFormats
+        EXPORT  HAL_Video_Features
+        EXPORT  HAL_Video_BufferAlignment
+        EXPORT  HAL_Video_OutputFormat
+        GET     hdr.StaticWS
+        GET     hdr.Video
+
+        AREA    |Asm$$Code|, CODE, READONLY, PIC
+
+        EXPORT  Video_init
+        ;EXPORT  HAL_VideoFlybackDevice
+        EXPORT  HAL_Video_SetMode
+        EXPORT  HAL_Video_WritePaletteEntry
+        EXPORT  HAL_Video_WritePaletteEntries
+        EXPORT  HAL_Video_ReadPaletteEntry
+        EXPORT  HAL_Video_SetInterlace
+        EXPORT  HAL_Video_SetBlank
+        EXPORT  HAL_Video_SetPowerSave
+        EXPORT  HAL_Video_UpdatePointer
+        EXPORT  HAL_Video_SetDAG
+        EXPORT  HAL_Video_VetMode
+
+	IMPORT 	serials
+	IMPORT	serial8
+; -----------------------------------------------------------------------------------
+
+Video_init ROUT
+    	Push     "lr"
+	Pull 	"pc"
+;    MOV      lr, #-1
+;    STR      lr, VIDC_NextPaletteIndex  ; init to invalid
+;    MOV      lr, #0
+;    STR      lr, VIDC_SoftPalette0
+;    STR      lr, VIDC_Interlace
+    ; Read IOMD_VIDCR and use it to recalculate the VRAM size (based around our knowledge of the values that Allocate_DRAM programs)
+    ; However RPCemu is buggy and always reports DRAMMode + bit 4 set!
+    ; Luckily we only need bits 2 & 3 to get the VRAM size
+;    ASSERT   SAMLength/2/256 = 4 ; 1MB
+;    LDR      lr, IOMD_Address
+;    LDRB     lr, [lr, #IOMD_VIDCR]
+;    MOV      lr, lr, LSR #2
+;    AND      lr, lr, #3 ; Should be 0, 1, 2 depending on VRAM size
+;    STRB     lr, VRAMWidth
+;    Pull     "pc"
+
+; -----------------------------------------------------------------------------------
+
+;HAL_VideoFlybackDevice
+;        MOV     a1, #3
+;        MOV     pc, lr
+
+; -------------------------------------------------------------------------
+
+;
+;  void HAL_Video_SetMode(const void *VIDCList3)
+;
+;  program VIDC20 registers from VIDCList3 specification
+;
+;  in: VIDClist -> video mode list (in VIDCList type 3 format)
+;
+
+VID_Tbl DATA
+	& 1 ;1 bpp
+	& 1 ;2 bpp
+	& 1 ;4 bpp
+	& 2 ;8 bpp
+	& 3 ;16 bpp
+	& 2 ;32 bpp
+
+Vid_txt = "Set mode X = "
+	= 0
+BPP_txt = "Set mode BPP = "
+	= 0
+Pal_txt = "Set pal - "
+	= 0
+	ALIGN
+
+HAL_Video_SetMode ROUT
+
+	STMDB	sp!,{r0-r4,lr}
+ ;	STMDB	sp!,{r0}
+
+;	LDR	r1, [r0, #VIDCList3_HorizDisplaySize]
+;	STR	r1, VIDX_Size
+;	SUB	r1, r1, #480
+;	MOV	r1, r1, LSR #1
+;	LDR	r2, LCD_Address
+;;	LDR	r3, [r2]
+;	BIC	r3, r3, #1
+;	STR	r3, [r2]
+;	MOV	r1, r1, LSL #11
+;	ORR	r1, r1, #240
+;	STR 	r1, [r2, #0x1C]
+;	ORR	r3, r3, #1
+;	STR	r3, [r2]
+;
+;;	LDR	r1, [r0, #VIDCList3_PixelDepth]
+;	STR	r1, VID_BPP
+;;;
+;	LDR	r0,LCD_Address
+;	ADD	r1, r1, #8
+;	MOV	r1, r1, LSL #1
+;	ORR	r1, r1, #((3<<5) + (4<<8))
+;	STR	r1, [r0]
+;
+;	LDR	r1, [r0, #16]
+;	BIC	r1, r1, #3
+;	LDR	r2, VID_BPP
+;	ADR	r3, VID_Tbl
+;	LDR	r2, [r3, r2, LSL #2]
+;	ORR	r1, r1, r2
+;	STR	r1, [r0, #16]
+;
+;	LDR	r0, UART_Address
+;	ADR	r4, Vid_txt
+;	BL	serials
+;	LDR	r4, VIDX_Size
+;	BL	serial8
+
+;	ADR	r4, BPP_txt
+;	BL	serials
+;	LDMIA	sp!,{r1}
+;	LDR	r4, [r1, #VIDCList3_PixelDepth]
+;	BL	serial8
+
+	LDMIA 	sp!,{r0-r4, pc}
+	;MOV	pc,lr
+;        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, 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, 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
+;
+;        MOV     R1, #0
+;        LDRB    R1, IOSystemType
+;        TST     R1, #IOST_7500
+;        LDREQ   R1, =24000              ;(Medusa), VIDC20 at 24MHz;
+;        MOVNE   R1, #32000              ;Morris, VIDC20L at 32Mhz ;
+
+;        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, 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"
+
+; -------------------------------------------------------------------------
+
+;
+;       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
+        ADD     pc, pc, r4, LSL #2
+        NOP
+        B       ProcessControlListNOP                   ; 0 - NOP
+        B       ProcessControlListLCDMode               ; 1 - LCD mode
+        B       ProcessControlListLCDDualPanelMode      ; 2 - LCD dual-panel mode
+        B       ProcessControlListLCDOffsetRegister0    ; 3 - LCD offset register 0
+        B       ProcessControlListLCDOffsetRegister1    ; 4 - LCD offset register 1
+        B       ProcessControlListHiResMode             ; 5 - Hi-res mode
+        B       ProcessControlListDACControl            ; 6 - DAC control
+        B       ProcessControlListRGBPedestals          ; 7 - RGB pedestal enables
+        B       ProcessControlListExternalRegister      ; 8 - External register
+        B       ProcessControlListHClockSelect          ; 9 - HClk select/specify
+        B       ProcessControlListNOP                   ; 10 - RClk frequency
+        B       ProcessControlListDPMSState             ; 11 - DPMS state
+        B       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
+;
+; 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)
+;
+
+
+HAL_Video_WritePaletteEntry ROUT
+	STMDB	sp!,{r0-r3,lr}
+	CMP	r0, #0
+	LDMNEIA	sp!,{r0-r3,pc}
+
+	LDR	r0, LCD_Address
+
+	MOV	r3, #512
+	STR	r3,[r0,#0x1A0]
+
+	ADD	r3, r0, #0x400
+	ADD	r3, r3, r2, LSL #2
+
+;	MOV     r2, r1, LSR #8
+	;AND	r2, r2, #0xF0
+;	AND	r2, r2, #0xF8
+;	MOV	r2, r2, LSL #(11-3)
+
+;	MOV	r3, r1, LSR #16
+	;AND	r3, r3, #0xF0
+;	AND	r3, r3, #0xF8
+;	ORR	r2, r2, r3, LSL #(6-3)
+
+;	MOV	r3, r1, LSR #24
+	;AND	r3, r3, #0xF0
+;	AND     r3, r3, #0xF8
+;	ORR	r2, r2, r3, LSR #2
+
+	MOV	r1, r1, LSR #8
+
+;	Push	"r0,r1,r2,r3,r4,r5"
+;	LDR	r0, UART_Address
+;	ADR	r4, Pal_txt
+;	BL	serials
+ ;	Pull	"r0,r1,r2,r3,r4,r5"
+ ;	Push	"r0,r1,r2,r3,r4,r5"
+;;;	LDR	r0, UART_Address
+;	MOV	r4, r3
+;	BL	serial8
+;	Pull	"r0,r1,r2,r3,r4,r5"
+;	Push	"r0,r1,r2,r3,r4,r5"
+;	LDR	r0, UART_Address
+;	MOV	r4, r1
+;	BL	serial8
+;	Pull	"r0,r1,r2,r3,r4,r5"
+
+
+	STR 	r1, [r3]
+
+	MOV	r3,#1
+	STR	r3,[r0,#0x1A0]
+
+	LDMIA	sp!,{r0-r3,pc}
+
+;        AND     r12, r1, #&F0               ; 000000S0 (4 MSbits of supremacy)
+;        MOV     r1, r1, LSR #8              ; 00BBGGRR
+;        ORR     r1, r1, r12, LSL #20        ; 0SBBGGRR
+;
+;        LDR     r12, 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, VIDC_SoftPalette0
+;
+;        LDRNE   r0, 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, 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)
+;
+HAL_Video_WritePaletteEntries ROUT
+	;MOV	pc,lr
+        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
+
+	B	%FT50
+
+;        CMP     r0, #0
+;        BNE     %FT50
+;;
+; type 0, try to be efficient
+;
+;        LDR     r12, VIDC_Address
+;
+;        CMP     r2, #0
+;
+;        LDREQ   r0, [r1]
+;        STREQ   r0, VIDC_SoftPalette0
+;
+;        LDRNE   r0, 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, 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
+;
+;  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
+        MOV	r0, #0
+	MOV	pc,lr
+;        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, 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, VIDC_ControlSoftCopy
+;        BIC     r1, r1, #CR_Interlace
+;        TST     r0, #1
+;        ORRNE   r1, r1, #CR_Interlace    ; zero => no interlace
+
+;        LDR     r0, 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, 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, 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, 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, VIDC_ExternalSoftCopy
+;        STR     r2, [r3]                     ; restore DACs and sync type
+;
+;        TST     r1, #1                       ; if hsyncs were turned off,
+;        LDRNE   r2, VIDC_HSWRSoftCopy        ; then restore from soft copy
+;        STRNE   r2, [r3]
+;
+;        TST     r1, #2                       ; if vsyncs were turned off,
+;        LDRNE   r2, VIDC_VSWRSoftCopy        ; then restore from soft copy
+;        STRNE   r2, [r3]
+;
+;        LDR     r0, 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
+	MOV	pc,lr
+;        LDR     r1, 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, VIDC_ControlSoftCopy       ;restore from soft copy
+;        STR     r2, [r1]
+;
+;        LDR     r2, VIDC_ExternalSoftCopy      ;restore from soft copy
+;        STR     r2, [r1]
+;
+;        LDR     r2, 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 ROUT
+
+	MOV 	pc,lr
+;        Push    "r4, r5, lr"
+;
+;        LDR     r14, VIDC_Address
+;
+;        TST     r0, #1
+;        BEQ     %FT90          ; pointer off
+;
+;
+; process x (and assume shape width is padded 32 pixels)
+;
+;        LDR     r4, 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, 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, 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, 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
+;         3 set start address of VDU buffer (i.e. as set by OS_Byte 112)
+;         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.
+
+VBL_Wait	;LDR r0, LCD_Address
+ ;	LDR	r1, [r0]
+;;	MOV	r1, r1, LSR #18
+;	BICS	r1, r1, #0xFC00
+;	BNE	VBL_Wait
+
+	MOV	pc,lr
+
+DAG_txt = "DAG = "
+	= 0
+
+HAL_Video_SetDAG ROUT
+
+	CMP	r0, #0
+	MOVNE	pc, lr
+
+	STMDB 	sp!,{r0-r5,lr}
+	;STMDB	sp!,{r1}
+	;STMDB	sp!,{r1}
+	;LDR	r0, UART_Address
+	;ADR	r4, DAG_txt
+	;BL	serials
+	;LDMIA	sp!,{r4}
+	;BL	serial8
+
+
+;	BL	VBL_Wait
+
+	;LDMIA	sp!,{r1}
+ 	LDR	r0, LCD_Address
+
+	STR	r1,[r0,#0xA0]
+	STR	r1,[r0,#0xA4]
+	LDR	r2, = (640*272)
+	ADD	r1, r1, r2
+	BIC	r1, r1, #0xFF000000
+	STR	r1,[r0,#0xD0]
+	STR	r1,[r0,#0xD4]
+;	LDR 	r2, [r0]
+;	BIC	r2, r2, #1
+;	STR	r2, [r0]
+
+;	MOV	r1, r1, LSR #1
+;	STR	r1, [r0, #0x14]
+;	BIC	r1, r1, #0xFF000000
+;	BIC	r1, r1, #0x00800000
+
+;	LDR	r2, VIDX_Size
+;	LDR	r3, VID_BPP
+;	MOV	r2, r2, LSL r3
+;	MOV	r2, r2, LSR #3
+;;	MOV	r3, #272
+;	MUL	r2, r3, r2
+;	MOV	r2, r2, LSR #1
+
+;	ADD	r1, r1, r2 ;#0xFF00
+;	ADD	r1, r1, #0x400
+;	STR	r1, [r0, #0x18]
+
+;	LDR	r2, [r0]
+;	ORR	r2, r2, #1
+;	STR	r2, [r0]
+
+;	MOV	pc,lr
+
+	LDMIA	sp!,{r0-r5,pc}
+
+;        LDR     r12, IOMD_Address
+;
+;        CMP     r0, #2
+;        MOVHI   pc, lr
+;
+;        CMP     r0, #1
+;        BEQ     %FT20
+;        BHI     %FT40
+;;
+; DAG=0 program VInit
+;
+;;        STR     r1, IOMD_VInitSoftCopy   ; save VInit so that writes to VEnd can check
+;        LDR     r2, 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
+;
+;
+; DAG=2 program VEnd
+;
+;40      MOV     r2, #0                          ; we must adjust address to that of
+;        LDRB    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, IOMD_VEndSoftCopy           ; remember VEnd value
+;        LDR     r2, 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
+
+; -------------------------------------------------------------------------
+
+;
+; uint HAL_Video_Features(void)
+;
+; returns a flags word:
+;    bit 0     h/w scroll is supported
+;    bit 1     h/w pointer is supported
+;    bit 2     interlace is supported with progressive framestore
+;    other bits reserved (returned as 0)
+
+HAL_Video_Features ROUT
+        MOV   a1, #0   ; hw scroll, h/w pointer, no interlace
+        MOV   pc, lr
+
+; -------------------------------------------------------------------------
+
+;
+; uint HAL_Video_PixelFormats(void)
+;
+;
+; 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 0-5 refer to support with standard RO pixel layout (little endian
+;    packing for 1,2,4 bpp, 5-5-5 RGB for 16 bpp, etc.)
+;    other formats may be introduced when/if RO supports them
+
+HAL_Video_PixelFormats ROUT
+        MOV   a1, #2_111111   ; 1,2,4,8,16,32 bpp
+        MOV   pc, lr
+
+; -------------------------------------------------------------------------
+
+;
+; uint HAL_Video_BufferAlignment(void)
+;
+; returns the required alignment for the framestore buffer, in bytes
+; (expected to be a power of 2)
+
+HAL_Video_BufferAlignment ROUT
+        MOV   a1, #32          ; align to 32 bytes
+        MOV   pc, lr
+
+; -------------------------------------------------------------------------
+
+;
+; uint HAL_Video_OutputFormat(void)
+;
+; returns current video output format
+;      0 = analogue (or 'normal', unspecified)
+;      1 = 16-bit non-multiplexed RGB 5-6-5 (Chrontel 7003 format 0)
+;     ...
+;     10 = Chrontel 7003 format 9
+;  >= 11 reserved
+;
+
+HAL_Video_OutputFormat
+        MOV   a1, #0     ;normal/unspecified
+        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
+
+; -------------------------------------------------------------------------
+
+        END
+