i2cutils 61.4 KB
Newer Older
Neil Turton's avatar
Neil Turton committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
; Copyright 1996 Acorn Computers Ltd
;
; Licensed under the Apache License, Version 2.0 (the "License");
; you may not use this file except in compliance with the License.
; You may obtain a copy of the License at
;
;     http://www.apache.org/licenses/LICENSE-2.0
;
; Unless required by applicable law or agreed to in writing, software
; distributed under the License is distributed on an "AS IS" BASIS,
; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
; See the License for the specific language governing permissions and
; limitations under the License.
;
; > $.Source.PMF.i2cutils

; Authors JBiggs (m2), PFellows, TDobson, AGodwin

Neil Turton's avatar
Neil Turton committed
19 20 21 22 23 24 25 26 27 28 29 30 31
; ***********************************
; ***    C h a n g e   L i s t    ***
; ***********************************

; Date       Name  Description
; ----       ----  -----------
; 28-Mar-95  JRH   Added support for E2ROMs and/or CMOS, conditioned on
;                  E2ROMSupport which is defined elsewhere
;                  Uses RTCFitted and NVRamSize in KernelWS
; 03-Jul-96  JRH   Took out code conditioned on :LNOT: NewClockChip
;                  Fixed support for E2ROM. E2 works in the same gross way as
;                  CMOS. Any E2 fitted > 256 bytes will not be accessed by these
;                  routines.
Kevin Bracey's avatar
Kevin Bracey committed
32 33
; 07-Dec-96  AMG   Renaissance. Leave this file as is, allowing the E2ROMSupport
;                  switch to disable non-STB bits
Kevin Bracey's avatar
Kevin Bracey committed
34 35 36
; 12-Jun-97  TMD   (Really) fix OTP access problem.
; 17-Sep-98  KJB   Add support for 16K 24C128 EEPROM.
; 21-Sep-98  KJB   Add OS_NVMemory SWI.
37
; 30-Jul-99  KJB   Add support for 8K 24C64 EEPROM.
38
; 23-Sep-99  KJB   Remove support for 24C64, add support for 4K and 8K protectable ATMEL parts.
Neil Turton's avatar
Neil Turton committed
39

Robert Sprowson's avatar
Robert Sprowson committed
40
PhysChecksum            *       (((CheckSumCMOS + &30) :MOD: &F0) + &10)
Neil Turton's avatar
Neil Turton committed
41 42

; Device addresses
Robert Sprowson's avatar
Robert Sprowson committed
43 44 45 46 47 48 49 50
RTCAddressPHI           *       &a0     ; Philips RTC + 240 byte CMOS
E2ROMAddress2K          *       &e0     ; 24C174 device - 2K
E2ROMAddress2K_OTP      *       &60     ; 24C174 device - OTP section
E2ROMAddress4K          *       &a4     ; 24C32 device - 4K (top 1K protectable)
E2ROMAddress8K_prot     *       &a2     ; 24C64 device - 8K (top 2K protectable)
E2ROMAddress8K          *       &ae     ; 24C64 device - 8K
E2ROMAddress16K         *       &a8     ; 24C128 device - 16K
E2ROMAddress32K         *       &a6     ; 24CS256 device - 32K (top 2K possibly OTP)
Robert Catherall's avatar
Robert Catherall committed
51

Dan Ellis's avatar
Dan Ellis committed
52

Neil Turton's avatar
Neil Turton committed
53 54
; *****************************************************************************
;
Robert Sprowson's avatar
Robert Sprowson committed
55
;       HexToBCD - Convert byte in hex to BCD
Neil Turton's avatar
Neil Turton committed
56
;
Robert Sprowson's avatar
Robert Sprowson committed
57
; in:   R0 = byte in hex
Neil Turton's avatar
Neil Turton committed
58
;
Robert Sprowson's avatar
Robert Sprowson committed
59 60
; out:  R0 = byte in BCD (ie R0 := (R0 DIV 10)*16 + R0 MOD 10)
;       All other registers preserved
Neil Turton's avatar
Neil Turton committed
61 62 63
;

HexToBCD ROUT
Robert Sprowson's avatar
Robert Sprowson committed
64 65 66 67 68
        Push    "R1,R2, R14"
        MOV     R1, #10
        DivRem  R2, R0, R1, R14                 ; R2=R0 DIV 10; R0=R0 MOD 10
        ADD     R0, R0, R2, LSL #4
        Pull    "R1,R2, PC"
Neil Turton's avatar
Neil Turton committed
69 70 71

; *****************************************************************************
;
Robert Sprowson's avatar
Robert Sprowson committed
72
;       BCDToHex - Convert byte in BCD to hex
Neil Turton's avatar
Neil Turton committed
73
;
Robert Sprowson's avatar
Robert Sprowson committed
74
; in:   R0 = byte in BCD (ie x*16 + y)
Neil Turton's avatar
Neil Turton committed
75
;
Robert Sprowson's avatar
Robert Sprowson committed
76 77
; out:  R0 = byte in hex (ie x*10 + y)
;       All other registers preserved
Neil Turton's avatar
Neil Turton committed
78 79 80
;

BCDToHex ROUT
Robert Sprowson's avatar
Robert Sprowson committed
81 82 83 84 85
        Push    "R14"
        MOV     R14, R0, LSR #4                 ; R14 := x
        ADD     R14, R14, R14, LSL #1           ; R14 := x*3
        SUB     R0, R0, R14, LSL #1             ; R0 := R0 - x*6 = x*10
        Pull    "PC"
Neil Turton's avatar
Neil Turton committed
86

87
; *****************************************************************************
Kevin Bracey's avatar
Kevin Bracey committed
88 89 90
;
;       HTBSR9 - hex to BCD and store at "next free byte" R9
;
91
HTBS9   ROUT
92
        Push    R14
93 94 95
        BL      HexToBCD
        STRB    R0, [R9], #1
        Pull    PC
Neil Turton's avatar
Neil Turton committed
96 97 98

; *****************************************************************************
;
Robert Sprowson's avatar
Robert Sprowson committed
99
;       Write - Write a byte of CMOS RAM specified by logical address
Neil Turton's avatar
Neil Turton committed
100
;
Robert Sprowson's avatar
Robert Sprowson committed
101 102
; in:   R0 = address in CMOS RAM
;       R1 = data
Neil Turton's avatar
Neil Turton committed
103
;
Robert Sprowson's avatar
Robert Sprowson committed
104
; out:  All registers preserved
Neil Turton's avatar
Neil Turton committed
105 106
;

Kevin Bracey's avatar
Kevin Bracey committed
107 108 109 110 111 112 113 114 115
WriteWithError ROUT
        Push    "R0-R4, R14"
        BL      MangleCMOSAddress
        BCC     %FT05

        ADD     R13, R13, #4            ; junk stacked R0
        ADR     R0, ErrorBlock_CoreNotWriteable
 [ International
        BL      TranslateError
Kevin Bracey's avatar
Kevin Bracey committed
116 117
 |
        SETV
Kevin Bracey's avatar
Kevin Bracey committed
118
 ]
Kevin Bracey's avatar
Kevin Bracey committed
119
        Pull    "R1-R4,PC"
Kevin Bracey's avatar
Kevin Bracey committed
120 121 122

        MakeErrorBlock CoreNotWriteable

Robert Catherall's avatar
Robert Catherall committed
123 124 125 126 127 128 129 130 131 132 133
WriteWithoutProtection                  ; allowing write to "OTP" and protected section
        Push    "R0-R4, R14"
        BL      MangleCMOSAddress
        Pull    "R0-R4, PC", CS         ; if invalid, then exit
        MOV     R2, R0
        MOV     R3, R1
        CMP     R0, #&10
        MOVLO   R4, #&1000000           ; don't change checksum for OTP
        BLO     %FT10
        B       %FT08                   ; do change checksum for protected region

Kevin Bracey's avatar
Kevin Bracey committed
134
Write
Robert Sprowson's avatar
Robert Sprowson committed
135 136 137
        Push    "R0-R4, R14"
        BL      MangleCMOSAddress
        Pull    "R0-R4, PC", CS         ; if invalid, then exit
Kevin Bracey's avatar
Kevin Bracey committed
138 139 140 141 142
05
  [ E2ROMSupport
        CMP     r0, #&10
        Pull    "R0-R4, PC", CC         ; don't write to OTP section
  ]
Neil Turton's avatar
Neil Turton committed
143

Stewart Brodie's avatar
Stewart Brodie committed
144
  [ E2ROMSupport
Jeffrey Lee's avatar
Jeffrey Lee committed
145
        LDR     R14, =ZeroPage          ; don't write to protected section
146
        LDRB    R14, [R14, #NVRamWriteSize]
147
        CMP     R0, R14, LSL #8         ; (note assumption that NVRamWriteSize is
148
        Pull    "R0-R4, PC", HS         ; outside mangled region).
Stewart Brodie's avatar
Stewart Brodie committed
149
  ]
150

Robert Sprowson's avatar
Robert Sprowson committed
151 152
        MOV     R2, R0
        MOV     R3, R1
Robert Catherall's avatar
Robert Catherall committed
153
08
Neil Turton's avatar
Neil Turton committed
154
 [ ChecksumCMOS
Robert Sprowson's avatar
Robert Sprowson committed
155 156
        BL      ReadStraight            ; calculate new checksum :
        MOV     R4, R0
157 158 159
        TEQ     R4, R3                  ; don't bother with write if
        Pull    "R0-R4, PC", EQ         ; oldcontents == newcontents

Robert Sprowson's avatar
Robert Sprowson committed
160 161 162 163
        MOV     R0, #PhysChecksum
        BL      ReadStraight
        SUB     R0, R0, R4              ; = oldsum - oldcontents
        ADD     R4, R0, R3              ;          + newcontents
Neil Turton's avatar
Neil Turton committed
164

Robert Sprowson's avatar
Robert Sprowson committed
165 166 167
        AND     R4, R4, #&FF
        CMPS    R2, #PhysChecksum       ; don't write new checksum ...
        ORREQ   R4, R4, #&1000000       ; if checksum is being written
Neil Turton's avatar
Neil Turton committed
168
 ]
Neil Turton's avatar
Neil Turton committed
169
10
Robert Sprowson's avatar
Robert Sprowson committed
170 171 172 173
        CMP     r2, #&100               ; check small cache limit
        BCS     %FT15
        LDR     R1, =ZeroPage+CMOSRAMCache      ; update cache, but always write to
        STRB    R3, [R1, R2]            ; real hardware as well
Kevin Bracey's avatar
Kevin Bracey committed
174
15
Dan Ellis's avatar
Dan Ellis committed
175 176

  [ HAL
Robert Sprowson's avatar
Robert Sprowson committed
177 178 179 180 181
        Push    "R2,R3,sb,R12"
        AddressHAL
        CallHAL HAL_NVMemoryType
        AND     R0, R0, #NVMemoryFlag_Provision
        TEQ     R0, #NVMemoryFlag_None
Dan Ellis's avatar
Dan Ellis committed
182

Robert Sprowson's avatar
Robert Sprowson committed
183 184 185
        ; If there's no NVmemory, all we have is the internal cache.
        Pull    "R2,R3,sb,R12", EQ
        Pull    "R0-R4,PC", EQ
Dan Ellis's avatar
Dan Ellis committed
186

Robert Sprowson's avatar
Robert Sprowson committed
187 188
        TEQ     R0, #NVMemoryFlag_HAL
        BNE     %FT20                   ; Go and do IIC stuff.
Dan Ellis's avatar
Dan Ellis committed
189

Robert Sprowson's avatar
Robert Sprowson committed
190
        ; Make the HAL call - we have to write the data into a buffer.
191
        Pull    "R0"
192
        STRB    R3, [sp, #-4]!
Robert Sprowson's avatar
Robert Sprowson committed
193 194 195
        MOV     R1, sp
        MOV     R2, #1
        CallHAL HAL_NVMemoryWrite
196 197
        TST     R4, #&1000000
        BNE     %FT18
Jeffrey Lee's avatar
Jeffrey Lee committed
198
        LDR     R1, =ZeroPage+CMOSRAMCache
199 200
        STRB    R4, [R1, #PhysChecksum]
        STRB    R4, [sp]
201
        MOV     R0, #PhysChecksum
Robert Sprowson's avatar
Robert Sprowson committed
202 203 204
        MOV     R1, sp
        MOV     R2, #1
        CallHAL HAL_NVMemoryWrite
205
18
Robert Sprowson's avatar
Robert Sprowson committed
206 207 208
        ADD     sp, sp, #4
        Pull    "R3,sb,R12"
        Pull    "R0-R4,PC"
Dan Ellis's avatar
Dan Ellis committed
209
20
210
        Pull    "R2,R3,sb,R12"
Dan Ellis's avatar
Dan Ellis committed
211 212 213
  ]


Neil Turton's avatar
Neil Turton committed
214
 [ E2ROMSupport
Robert Sprowson's avatar
Robert Sprowson committed
215 216 217
        MOV     R0, R2
        BL      GetI2CAddress           ; convert to device address + offset
        MOV     R2, R0                  ; save the offset
Neil Turton's avatar
Neil Turton committed
218
 |
Robert Sprowson's avatar
Robert Sprowson committed
219
        MOV     R1, #RTCAddressPHI
Neil Turton's avatar
Neil Turton committed
220 221 222
 ]


223 224 225 226 227 228 229 230 231 232 233 234 235
        AND     R0, R1, #&FF            ; device address for write
        ORR     R0, R0, #1:SHL:29       ; retry
        TST     R1, #&100               ; NE if two byte offset
        SUB     R13, R13, #4
        MOV     R14, R13
        MOVNE   R1, R2, LSR #8
        STRNEB  R1, [R14], #1           ; offset (MSB)
        STRB    R2, [R14], #1           ; offset (LSB)
        STRB    R3, [R14], #1           ; data
        MOV     R1, R13
        SUB     R2, R14, R13
        BL      IIC_Op
        ADD     R13, R13, #4
Neil Turton's avatar
Neil Turton committed
236

Robert Sprowson's avatar
Robert Sprowson committed
237 238 239 240 241 242 243 244
        [ ChecksumCMOS
        TST     R4, #&1000000           ; loop again to write new checksum
        MOV     R3, R4
        MOV     R2, #PhysChecksum
        ORR     R4, R4, #&1000000       ; but ensure it only happens once
        BEQ     %BT10
        ]
        Pull    "R0-R4, PC"
Neil Turton's avatar
Neil Turton committed
245

Kevin Bracey's avatar
Kevin Bracey committed
246 247 248 249 250 251 252 253 254 255 256 257 258 259 260
; *****************************************************************************
;
;       WriteBlock - Write a block of CMOS RAM specified by logical address
;
; in:   R0 = address in CMOS RAM
;       R1 = address to copy from
;       R2 = length
;
; out:  All registers preserved
;


WriteBlock ROUT
        Push    "R0-R4,R14"
  [     E2ROMSupport
Robert Sprowson's avatar
Robert Sprowson committed
261
        LDR     R14, =ZeroPage
262
        LDRB    R4, [R14, #NVRamWriteSize]
Robert Sprowson's avatar
Robert Sprowson committed
263
        LDRB    R14, [R14, #NVRamSize]
264
        MOV     R4, R4, LSL #8
Kevin Bracey's avatar
Kevin Bracey committed
265 266 267
        MOV     R14, R14, LSL #8
  |
        MOV     R14, #240
268
        MOV     R4, R14
Kevin Bracey's avatar
Kevin Bracey committed
269 270 271 272 273 274 275 276 277 278
  ]

        CMP     R0, R14
        BHS     %FT90

        ADDS    R3, R0, R2              ; R3 = end address - check unsigned overflow
        BCS     %FT90
        CMP     R3, R14
        BHI     %FT90

279 280 281 282 283 284
        CMP     R0, R4                  ; ignore writes totally outside writable area
        BHS     %FT80

        SUBS    R14, R3, R4
        SUBGT   R2, R2, R14             ; truncate writes partially outside writable area

Kevin Bracey's avatar
Kevin Bracey committed
285 286 287 288 289 290
        TEQ     R2, #0
        BEQ     %FT80

        CMP     R0, #CheckSumCMOS       ; are we going to write the checksum byte?
        BHI     %FT03
        CMP     R3, #CheckSumCMOS
291
        BHI     %FT05
Kevin Bracey's avatar
Kevin Bracey committed
292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326

03
; we're not writing the checksum byte manually, so we need to update it
        MOV     R4, R1
        MOV     R1, #0
        BL      ChecksumBlock           ; find the checksum of what we're about to
        ORR     R3, R1, #&80000000      ; overwrite
        MOV     R1, R4
        B       %FT08

05      MOV     R3, #0
08      MOV     R4, #0
10      BL      WriteSubBlock
        BVS     %FT80
        TEQ     R2, #0
        BNE     %BT10

        TST     R3, #&80000000          ; were we going to write the checksum?
        BEQ     %FT80

        MOV     R0, #CheckSumCMOS
        BL      Read                    ; get old checksum byte
        ADD     R0, R0, R4              ; add new data checksum
        SUB     R1, R0, R3              ; subtract old checksum
        MOV     R0, #CheckSumCMOS
        BL      Write                   ; write back new checksum

80
        Pull    "R0-R4,PC"

90
        ADD     SP, SP, #4              ; junk stacked R0
        ADR     R0, ErrorBlock_CoreNotWriteable
 [ International
        BL      TranslateError
Kevin Bracey's avatar
Kevin Bracey committed
327 328
 |
        SETV
Kevin Bracey's avatar
Kevin Bracey committed
329
 ]
Kevin Bracey's avatar
Kevin Bracey committed
330
        Pull    "R1-R4,PC"
Kevin Bracey's avatar
Kevin Bracey committed
331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384

; *****************************************************************************
;
;       WriteSubBlock - Write a block of CMOS RAM specified by logical address.
;                       Assumes the address is valid, and will only read as much
;                       as it can in a single IIC transaction.
;
; in:   R0 = address in CMOS RAM
;       R1 = address to copy from
;       R2 = length
;
; out:  R0-R2 updated to reflect the amount written.
;       R4 incremented by sum of bytes written.
;
WriteSubBlock ROUT
        Push    "R3,R5-R6,R14"
        MOV     R6, R4
; establish end of the current contiguous block, and the logical->physical address offset.
        CMP     R0, #1                  ; 00 -> 40 uncached
        MOVLO   R3, #1
        MOVLO   R4, #&40-&00
        BLO     %FT10
        CMP     R0, #&C0                ; [01..C0) -> [41..100) cached
        MOVLO   R3, #&C0
        MOVLO   R4, #&41-&01
        BLO     %FT10
        CMP     R0, #&F0                ; [C0..F0) -> [10..40) cached
        MOVLO   R3, #&F0
        MOVLO   R4, #&10-&C0
        BLO     %FT10
        CMP     R0, #&100
        ADDHS   R3, R0, R2              ; [100..) -> [100..) uncached
        MOVHS   R4, #0
        BHS     %FT10

; [F0..100) -> not written
        MOV     R3, #&100
        ADD     R14, R0, R2
        CMP     R3, R14
        MOVHI   R3, R14
        SUB     R14, R3, R0
        ADD     R0, R0, R14
        ADD     R1, R1, R14
        SUB     R2, R2, R14
        Pull    "R3,R5-R6,PC"

; R3 = logical end of current segment (exclusive)
; R4 = offset from logical to physical address for this segment
10
        ADD     R14, R0, R2
        CMP     R3, R14
        MOVHI   R3, R14
 [ E2ROMSupport
; R3 = logical end of possible transaction (exclusive). Now check we don't cross page boundaries.
Robert Sprowson's avatar
Robert Sprowson committed
385 386
        LDR     R14, =ZeroPage
        LDRB    R14, [R14, #NVRamPageSize]
Kevin Bracey's avatar
Kevin Bracey committed
387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402
        MOV     R5, #1
        MOV     R14, R5, LSL R14        ; R14 = (1<<pagesize)

        ADD     R5, R0, R4              ; R5 = physical start address
        ADD     R5, R5, R14
        SUB     R14, R14, #1
        BIC     R5, R5, R14             ; R5 = physical end of page with start address in
        SUB     R5, R5, R4              ; R5 = logical end of page with start address in

        CMP     R5, R3
        MOVLO   R3, R5                  ; adjust R3 to not cross page boundary
 ]

        CMP     R0, #&100               ; check it's a cacheable segment
        BHS     %FT15

Jeffrey Lee's avatar
Jeffrey Lee committed
403
        LDR     R14, =ZeroPage+CMOSRAMCache
Kevin Bracey's avatar
Kevin Bracey committed
404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419
        Push    "R3, R4"
        ADD     R3, R3, R4              ; R3 = physical end address
        ADD     R4, R4, R0              ; R4 = physical address
        ADD     R3, R3, R14             ; R3 = cache end address
        ADD     R4, R4, R14             ; R4 = cache address
        SUB     R14, R3, R4             ; R14 = bytes being written
        MOV     R5, R1                  ; remember R1
12      LDRB    R14, [R1], #1           ; update cache copy
        STRB    R14, [R4], #1
        CMP     R4, R3
        BLO     %BT12
        MOV     R1, R5                  ; restore R1, and continue to update real memory
        Pull    "R3, R4"
15
        Push    "R0-R2"
        ADD     R0, R0, R4              ; R0 = physical address
Dan Ellis's avatar
Dan Ellis committed
420
  [ HAL
Robert Sprowson's avatar
Robert Sprowson committed
421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439
        Push    "sb, R12"
        MOV     R5, R0                  ; save address
        AddressHAL
        CallHAL HAL_NVMemoryType
        AND     R0, R0, #NVMemoryFlag_Provision
        TEQ     R0, #NVMemoryFlag_None

        ; If there's no NVmemory, tough - we just return.
        Pull    "sb,R12", EQ
        Pull    "R0-R2", EQ
        MOVEQ   R2, #0                  ; nothing written
        Pull    "R3,R5-R6,PC", EQ

        TEQ     R0, #NVMemoryFlag_HAL
        MOV     R0, R5                  ; restore address
        BNE     %FT17                   ; do IIC things.

        ; Make the HAL call
        CallHAL HAL_NVMemoryWrite       ; returns bytes wrtten in R0
440
        MOV     R5, R0
Robert Sprowson's avatar
Robert Sprowson committed
441
        Pull    "sb,R12"
442

Robert Sprowson's avatar
Robert Sprowson committed
443
        Pull    "R0-R2"
444 445 446 447 448

        ADD     R0, R0, R5
        SUB     R2, R2, R5

16      SUBS    R5, R5, #1              ; update checksum
449
        LDRCSB  R14, [R1], #1
450
        ADDCS   R6, R6, R14
451
        BCS     %BT16
452
        MOV     R4, R6
453

Robert Sprowson's avatar
Robert Sprowson committed
454
        Pull    "R3,R5-R6,PC"
Dan Ellis's avatar
Dan Ellis committed
455 456

17
Robert Sprowson's avatar
Robert Sprowson committed
457
        Pull    "sb,R12"
Dan Ellis's avatar
Dan Ellis committed
458 459
  ]

Robert Sprowson's avatar
Robert Sprowson committed
460 461
  [     E2ROMSupport
        BL      GetI2CAddress           ; convert to device address and offset
Kevin Bracey's avatar
Kevin Bracey committed
462
  |
Robert Sprowson's avatar
Robert Sprowson committed
463
        MOV     R1, #RTCAddressPHI
Kevin Bracey's avatar
Kevin Bracey committed
464 465
  ]

466 467 468
        MOV     R2, R0                  ; save the offset
        SUB     R13, R13, #12*2+4
        MOV     R14, R13
Kevin Bracey's avatar
Kevin Bracey committed
469
        TST     R1, #&100               ; 2-byte address?
470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485
        MOVNE   R0, R2, LSR #8
        STRNEB  R0, [R14], #1           ; offset (MSB)
        STRB    R2, [R14], #1           ; offset (LSB)

        SUB     R14, R14, R13
        STR     R14, [R13, #12]         ; transfer 1 length

        AND     R14, R1, #&FF
        ORR     R0, R14, #1:SHL:29      ; (retry)
        STR     R0, [R13, #4]           ; transfer 1 address
        ORR     R14, R14, #1:SHL:31     ; (no repeated start)
        STR     R14, [R13, #16]         ; transfer 2 address
        STR     R13, [R13, #8]          ; transfer 1 data

        ADD     R14, R13, #12*2+4
        LDMIA   R14, {R0-R2}
Kevin Bracey's avatar
Kevin Bracey committed
486 487 488
        SUB     R5, R3, R0              ; R5 = bytes being written
        ADD     R0, R0, R5              ; update return R0
        SUB     R2, R2, R5              ; update return R2
489 490 491 492 493 494 495 496 497 498
        STMIB   R14, {R0,R2}

        STR     R1, [R13, #20]          ; transfer 2 data
        STR     R5, [R13, #24]          ; transfer 2 length
        ADD     R0, R13, #4
        MOV     R1, #2
        BL      IIC_OpV

        LDR     R1, [R13, #20]          ; recover data pointer
        ADD     R13, R13, #12*2+4+4
Kevin Bracey's avatar
Kevin Bracey committed
499 500 501
20
        LDRB    R0, [R1], #1
        SUBS    R5, R5, #1
502
        ADD     R6, R6, R0              ; update checksum counter
Kevin Bracey's avatar
Kevin Bracey committed
503
        BNE     %BT20
Kevin Bracey's avatar
Kevin Bracey committed
504
                                        ; V clear
Kevin Bracey's avatar
Kevin Bracey committed
505 506
        MOV     R4, R6

Robert Sprowson's avatar
Robert Sprowson committed
507
        Pull    "R0,R2,R3,R5,R6,PC"
Kevin Bracey's avatar
Kevin Bracey committed
508

Neil Turton's avatar
Neil Turton committed
509 510
; *****************************************************************************
;
Robert Sprowson's avatar
Robert Sprowson committed
511 512
;       Read - Read a byte of CMOS RAM specified by logical address
;       ReadStraight - Read a byte of CMOS RAM specified by physical address
Kevin Bracey's avatar
Kevin Bracey committed
513
;       ReadWithError - Read a byte of CMOS RAM specified by logical address, giving error if out of range
Neil Turton's avatar
Neil Turton committed
514
;
Robert Sprowson's avatar
Robert Sprowson committed
515
; in:   R0 = address in CMOS RAM
Neil Turton's avatar
Neil Turton committed
516
;
Robert Sprowson's avatar
Robert Sprowson committed
517 518
; out:  R0 = data (illegal address return 0, or error for ReadWithError)
;       All other registers preserved
Neil Turton's avatar
Neil Turton committed
519 520 521
;

ReadStraight ROUT
Robert Sprowson's avatar
Robert Sprowson committed
522 523
        Push    "R1,R2,R14"
        B       %FT10
Neil Turton's avatar
Neil Turton committed
524

Kevin Bracey's avatar
Kevin Bracey committed
525 526 527 528 529 530 531
ReadWithError
        Push    "R1,R2,R14"
        BL      MangleCMOSAddress
        BCC     %FT10
        ADR     R0, ErrorBlock_CoreNotReadable
 [ International
        BL      TranslateError
Kevin Bracey's avatar
Kevin Bracey committed
532 533
 |
        SETV
Kevin Bracey's avatar
Kevin Bracey committed
534
 ]
Kevin Bracey's avatar
Kevin Bracey committed
535
        Pull    "R1,R2,PC"
Kevin Bracey's avatar
Kevin Bracey committed
536 537 538

        MakeErrorBlock CoreNotReadable

Neil Turton's avatar
Neil Turton committed
539
Read
Robert Sprowson's avatar
Robert Sprowson committed
540 541 542 543
        Push    "R1,R2,R14"
        BL      MangleCMOSAddress
        MOVCS   R0, #0                  ; pretend illegal addresses contain 0
        Pull    "R1,R2,PC", CS
Neil Turton's avatar
Neil Turton committed
544
10
Robert Sprowson's avatar
Robert Sprowson committed
545 546
        TEQ     R0, #&40                ; is it Econet station number
        BEQ     %FT15                   ; if so then don't use cache
Kevin Bracey's avatar
Kevin Bracey committed
547 548 549
        CMP     R0, #&10                ; don't cache the clock
  [     E2ROMSupport
        BHS     %FT13
550
        ; If our CMOS is actually inside an RTC, read direct (the cache is nonsense)
Jeffrey Lee's avatar
Jeffrey Lee committed
551
        LDR     R14, =ZeroPage
552 553 554
        LDRB    R14, [R14, #NVRamBase]
        TEQ     R14, #RTCAddressPHI
        BEQ     %FT15
Kevin Bracey's avatar
Kevin Bracey committed
555 556 557
  |
        BLO     %FT15
  ]
Robert Sprowson's avatar
Robert Sprowson committed
558 559 560 561
13      CMP     R0, #&100               ; check small cache limit
        LDRCC   R2, =ZeroPage+CMOSRAMCache ; if in range
        LDRCCB  R0, [R2, R0]            ; read from cache
        Pull    "R1,R2,PC", CC          ; and exit
Neil Turton's avatar
Neil Turton committed
562 563 564
15

; else drop thru into real CMOS reading code
Dan Ellis's avatar
Dan Ellis committed
565 566

  [ HAL
Robert Sprowson's avatar
Robert Sprowson committed
567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590
        Push    "R3,R4,sb,R12"
        MOV     R4, R0                  ; save address
        AddressHAL
        CallHAL HAL_NVMemoryType
        AND     R0, R0, #NVMemoryFlag_Provision
        TEQ     R0, #NVMemoryFlag_None

        ; If there's no NVmemory, pretend addresses contain 0
        Pull    "R3,R4,sb,R12", EQ
        MOVEQ   R0, #0
        Pull    "R1,R2,PC", EQ

        TEQ     R0, #NVMemoryFlag_HAL
        MOV     R0, R4                  ; restore address
        BNE     %FT20

        ; Make the HAL call - we have to provide a buffer.
        SUB     sp, sp, #4              ; make some space on the stack
        MOV     R1, sp
        MOV     R2, #1
        CallHAL HAL_NVMemoryRead
        LDRB    R0, [sp], #4            ; read back from stack and restore
        Pull    "R3,R4,sb,R12"
        Pull    "R1,R2,PC"
Dan Ellis's avatar
Dan Ellis committed
591 592

20
593
        Pull    "R3,R4, sb,R12"
Neil Turton's avatar
Neil Turton committed
594
  ]
Neil Turton's avatar
Neil Turton committed
595

Robert Sprowson's avatar
Robert Sprowson committed
596 597
  [     E2ROMSupport
        BL      GetI2CAddress           ; convert to device address and offset
Neil Turton's avatar
Neil Turton committed
598
  |
Robert Sprowson's avatar
Robert Sprowson committed
599
        MOV     R1, #RTCAddressPHI
Neil Turton's avatar
Neil Turton committed
600
  ]
Neil Turton's avatar
Neil Turton committed
601

602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619
        SUB     R13, R13, #2*12+4
        MOV     R14, R13
        TST     R1, #&100
        MOVNE   R2, R0, LSR #8
        STRNEB  R2, [R14], #1           ; offset (MSB)
        STRB    R0, [R14], #1           ; offset (LSB)
        SUB     R14, R14, R13
        STR     R13, [R13, #8]          ; transfer 1 data
        STR     R14, [R13, #12]         ; transfer 1 length
        AND     R14, R1, #&FF
        ORR     R2, R14, #1:SHL:29      ; retry
        STR     R2, [R13, #4]           ; transfer 1 address
        ORR     R14, R14, #1            ; device address for read
        STR     R14, [R13, #16]         ; transfer 2 address
        ADD     R14, R13, #3
        STR     R14, [R13, #20]         ; transfer 2 data
        MOV     R14, #1
        STR     R14, [R13, #24]         ; transfer 2 length
Kevin Bracey's avatar
Kevin Bracey committed
620 621
        ADD     R0, R13, #4
        MOV     R1, #2
622 623 624
        BL      IIC_OpV
        LDRB    R0, [R13, #3]
        ADD     R13, R13, #2*12+4
Neil Turton's avatar
Neil Turton committed
625

Robert Sprowson's avatar
Robert Sprowson committed
626
        Pull    "R1,R2,PC"
Neil Turton's avatar
Neil Turton committed
627

Kevin Bracey's avatar
Kevin Bracey committed
628 629 630 631 632 633 634 635 636 637 638 639 640 641 642
; *****************************************************************************
;
;       ReadBlock - Read a block of CMOS RAM specified by logical address
;
; in:   R0 = address in CMOS RAM
;       R1 = address to copy to
;       R2 = length
;
; out:  All registers preserved
;


ReadBlock ROUT
        Push    "R0-R3,R14"
  [     E2ROMSupport
Robert Sprowson's avatar
Robert Sprowson committed
643 644
        LDR     R14, =ZeroPage
        LDRB    R14, [R14, #NVRamSize]
Kevin Bracey's avatar
Kevin Bracey committed
645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672
        MOV     R14, R14, LSL #8
  |
        MOV     R14, #240
  ]

        CMP     R0, R14
        BHS     %FT90

        ADDS    R3, R0, R2              ; R3 = end address - check unsigned overflow
        BCS     %FT90
        CMP     R3, R14
        BHI     %FT90

        TEQ     R2, #0
        BEQ     %FT80

10      BL      ReadSubBlock
        BVS     %FT80
        TEQ     R2, #0
        BNE     %BT10
80
        Pull    "R0-R3,PC"

90
        ADD     SP, SP, #4              ; junk stacked R0
        ADR     R0, ErrorBlock_CoreNotReadable
 [ International
        BL      TranslateError
Kevin Bracey's avatar
Kevin Bracey committed
673 674
 |
        SETV
Kevin Bracey's avatar
Kevin Bracey committed
675
 ]
Kevin Bracey's avatar
Kevin Bracey committed
676
        Pull    "R1-R3,PC"
Kevin Bracey's avatar
Kevin Bracey committed
677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721

; *****************************************************************************
;
;       ReadSubBlock - Read a block of CMOS RAM specified by logical address.
;                      Assumes the address is valid, and will only read as much
;                      as it can in a single IIC transaction.
;
; in:   R0 = address in CMOS RAM
;       R1 = address to copy to
;       R2 = length
;
; out:  R0-R2 updated to reflect the amount read.
;
ReadSubBlock ROUT
        Push    "R3-R5,R14"
; establish end of the current contiguous block, and the logical->physical address offset.
        CMP     R0, #1                  ; 00 -> 40 uncached
        MOVLO   R3, #1
        MOVLO   R4, #&40-&00
        BLO     %FT10
        CMP     R0, #&C0                ; [01..C0) -> [41..100) cached
        MOVLO   R3, #&C0
        MOVLO   R4, #&41-&01
        BLO     %FT10
        CMP     R0, #&F0                ; [C0..F0) -> [10..40) cached
        MOVLO   R3, #&F0
        MOVLO   R4, #&10-&C0
        BLO     %FT10
        CMP     R0, #&100               ; [F0..100) -> [00..10) cached
        MOVLO   R3, #&100
        MOVLO   R4, #&00-&F0
        ADDHS   R3, R0, R2              ; [100..) -> [100..) uncached
        MOVHS   R4, #0
; R3 = logical end of current segment (exclusive)
; R4 = offset from logical to physical address for this segment
10
        ADD     R14, R0, R2
        CMP     R3, R14
        MOVHI   R3, R14
; R3 = logical end of this transaction (exclusive)
        TEQ     R0, #0                  ; check it's a cacheable segment
        BEQ     %FT15
        CMP     R0, #&100
        BHS     %FT15

Jeffrey Lee's avatar
Jeffrey Lee committed
722
        LDR     R14, =ZeroPage+CMOSRAMCache
Kevin Bracey's avatar
Kevin Bracey committed
723 724 725 726 727 728 729 730 731 732 733 734
        ADD     R3, R3, R4              ; R3 = physical end address
        ADD     R4, R4, R0              ; R4 = physical address
        ADD     R3, R3, R14             ; R3 = cache end address
        ADD     R4, R4, R14             ; R4 = cache address
        SUB     R14, R3, R4             ; R14 = bytes being read
        ADD     R0, R0, R14             ; update return R0
        SUB     R2, R2, R14             ; update return R2

12      LDRB    R14, [R4], #1
        CMP     R4, R3
        STRB    R14, [R1], #1
        BLO     %BT12
Kevin Bracey's avatar
Kevin Bracey committed
735
        Pull    "R3-R5,PC"              ; V will be clear
Kevin Bracey's avatar
Kevin Bracey committed
736 737
15
        Push    "R0-R2"
738 739
        ADD     R0, R0, R4              ; R0 = physical start address
        ADD     R3, R3, R4              ; R3 = physical end address
Dan Ellis's avatar
Dan Ellis committed
740
  [ HAL
Robert Sprowson's avatar
Robert Sprowson committed
741
        Push    "sb"
742
        SUB     R2, R3, R0
Robert Sprowson's avatar
Robert Sprowson committed
743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763
        MOV     R5, R0                  ; save address
        AddressHAL
        Push    "R1-R3,R12"
        CallHAL HAL_NVMemoryType
        Pull    "R1-R3,R12"
        AND     R0, R0, #NVMemoryFlag_Provision
        TEQ     R0, #NVMemoryFlag_None

        ; If there's no NVmemory, tough - we just return.
        MOVEQ   R2, #0                  ; nothing read
        Pull    "sb", EQ
        Pull    "R3-R5,PC", EQ

        TEQ     R0, #NVMemoryFlag_HAL
        MOV     R0, R5                  ; restore address
        BNE     %FT17                   ; do IIC things.

        ; Make the HAL call
        Push    "R12"
        CallHAL HAL_NVMemoryRead        ; returns bytes read in R0
        Pull    "R12"
764
        MOV     R4, R0
Robert Sprowson's avatar
Robert Sprowson committed
765
        Pull    "sb"
766 767 768 769
        Pull    "R0-R2"
        ADD     R0, R0, R4
        ADD     R1, R1, R4
        SUB     R2, R2, R4
Robert Sprowson's avatar
Robert Sprowson committed
770
        Pull    "R3-R5,PC"
Dan Ellis's avatar
Dan Ellis committed
771 772

17
Robert Sprowson's avatar
Robert Sprowson committed
773
        Pull    "sb"
Dan Ellis's avatar
Dan Ellis committed
774 775
  ]

776 777
        SUB     R5, R3, R0              ; R5 = bytes being read

Robert Sprowson's avatar
Robert Sprowson committed
778 779
  [     E2ROMSupport
        BL      GetI2CAddress           ; convert to device address and offset
Kevin Bracey's avatar
Kevin Bracey committed
780
  |
Robert Sprowson's avatar
Robert Sprowson committed
781
        MOV     R1, #RTCAddressPHI
Kevin Bracey's avatar
Kevin Bracey committed
782 783 784
  ]


785 786 787
        MOV     R2, R0                  ; save the offset
        SUB     R13, R13, #12*2+4
        MOV     R14, R13
Kevin Bracey's avatar
Kevin Bracey committed
788
        TST     R1, #&100               ; 2-byte address?
789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804
        MOVNE   R0, R2, LSR #8
        STRNEB  R0, [R14], #1           ; offset (MSB)
        STRB    R2, [R14], #1           ; offset (LSB)

        SUB     R14, R14, R13
        STR     R14, [R13, #12]         ; transfer 1 length

        AND     R14, R1, #&FF
        ORR     R0, R14, #1:SHL:29      ; retry
        STR     R0, [R13, #4]           ; transfer 1 address
        ORR     R14, R14, #1            ; device address for read
        STR     R14, [R13, #16]         ; transfer 2 address
        STR     R13, [R13, #8]          ; transfer 1 data

        ADD     R14, R13, #12*2+4
        LDMIA   R14, {R0-R2}
Kevin Bracey's avatar
Kevin Bracey committed
805 806
        ADD     R0, R0, R5              ; update return R0
        SUB     R2, R2, R5              ; update return R2
807 808 809 810 811 812 813 814 815 816 817 818 819
        STMIB   R14, {R0,R2}

        STR     R1, [R13, #20]          ; transfer 2 data
        STR     R5, [R13, #24]          ; transfer 2 length
        ADD     R0, R13, #4
        MOV     R1, #2
        BL      IIC_OpV

        LDR     R1, [R13, #20]          ; recover data pointer
        ADD     R1, R1, R5
        ADD     R13, R13, #12*2+4+4

        CLRV
Kevin Bracey's avatar
Kevin Bracey committed
820

Robert Sprowson's avatar
Robert Sprowson committed
821
        Pull    "R0,R2,R3-R5,PC"
Kevin Bracey's avatar
Kevin Bracey committed
822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902

; *****************************************************************************
;
;       ChecksumBlock - Checksum a block of CMOS RAM specified by logical address
;                       Assumes the address is valid.
;
; in:   R0 = address in CMOS RAM
;       R1 = initial checksum
;       R2 = length
;
; out:  R1 incremented by sum of bytes in range
;


ChecksumBlock ROUT
        Push    "R0,R2,R14"

10      BL      ChecksumSubBlock
        BVS     %FT80
        TEQ     R2, #0
        BNE     %BT10
80
        Pull    "R0,R2,PC"

; *****************************************************************************
;
;       ChecksumSubBlock - Checksum a block of CMOS RAM specified by logical address.
;                          Assumes the address is valid, and will only read as much
;                          as it can in a single IIC transaction. Skips over
;                          239 (the checksum byte itself), and 240-255 (OTP area).
;
; in:   R0 = address in CMOS RAM
;       R1 = initial checksum
;       R2 = length
;
; out:  R0-R2 updated to reflect the data read.
;
ChecksumSubBlock ROUT
        Push    "R3-R5,R14"
; establish end of the current contiguous block, and the logical->physical address offset.
        CMP     R0, #1                  ; 00 -> 40 uncached
        MOVLO   R3, #1
        MOVLO   R4, #&40-&00
        BLO     %FT10
        CMP     R0, #&C0                ; [01..C0) -> [41..100) cached
        MOVLO   R3, #&C0
        MOVLO   R4, #&41-&01
        BLO     %FT10
        CMP     R0, #&EF                ; [C0..EF) -> [10..3F) cached
        MOVLO   R3, #&EF
        MOVLO   R4, #&10-&C0
        BLO     %FT10
        CMP     R0, #&100
        ADDHS   R3, R0, R2              ; [100..) -> [100..) uncached
        MOVHS   R4, #0
        BHS     %FT10

;  [EF..100) -> not checksummed
        MOV     R3, #&100
        ADD     R14, R0, R2
        CMP     R3, R14
        MOVHI   R3, R14
        SUB     R14, R3, R0
        ADD     R0, R0, R14
        SUB     R2, R2, R14
        Pull    "R3-R5,PC"


; R3 = logical end of current segment (exclusive)
; R4 = offset from logical to physical address for this segment
10
        ADD     R14, R0, R2
        CMP     R3, R14
        MOVHI   R3, R14
; R3 = logical end of this transaction (exclusive)

        TEQ     R0, #0                  ; check it's a cacheable segment
        BEQ     %FT15
        CMP     R0, #&100
        BHS     %FT15

Jeffrey Lee's avatar
Jeffrey Lee committed
903
        LDR     R14, =ZeroPage+CMOSRAMCache
Kevin Bracey's avatar
Kevin Bracey committed
904 905 906 907 908 909 910 911 912 913 914 915 916 917 918
        ADD     R3, R3, R4              ; R3 = physical end address
        ADD     R4, R4, R0              ; R4 = physical address
        ADD     R3, R3, R14             ; R3 = cache end address
        ADD     R4, R4, R14             ; R4 = cache address
        SUB     R14, R3, R4             ; R14 = bytes being read
        ADD     R0, R0, R14             ; update return R0
        SUB     R2, R2, R14             ; update return R2

12      LDRB    R14, [R4], #1
        CMP     R4, R3
        ADD     R1, R1, R14
        BLO     %BT12
        Pull    "R3-R5,PC"
15
        Push    "R0-R2"
919 920
        ADD     R0, R0, R4              ; R0 = physical start address
        ADD     R3, R3, R4              ; R3 = physical end address
921
  [ HAL
Robert Sprowson's avatar
Robert Sprowson committed
922 923 924 925 926 927 928 929 930
        Push    "sb,R12"
        MOV     R5, R0                  ; save address
        AddressHAL
        Push    "R1-R3"
        CallHAL HAL_NVMemoryType
        Pull    "R1-R3"
        AND     R4, R0, #NVMemoryFlag_Provision
        MOV     R0, R5                  ; restore address
        TEQ     R4, #NVMemoryFlag_None
931 932
        TEQNE   R4, #NVMemoryFlag_HAL
        BNE     %FT17                   ; do IIC things.
933

934 935 936 937 938 939 940
        SUB     R14, R3, R0
        LDR     R1, [R13,#8]
        LDR     R3, [R13,#16]
        ADD     R1, R1, R14
        SUB     R3, R3, R14
        STR     R1, [R13,#8]
        STR     R3, [R13,#16]
941

Robert Sprowson's avatar
Robert Sprowson committed
942 943 944 945
        TEQ     R4, #NVMemoryFlag_None
        ; If there's no NVmemory, tough - we just return.
        Pull    "sb,R12", EQ
        Pull    "R0-R5,PC", EQ
946 947 948

        Push    "R6"
        MOV     R4, #0
949
        ADD     R6, R5, R14
950 951 952 953 954 955 956 957 958 959 960 961
        SUB     R13, R13, #4
16
        MOV     R0, R5
        MOV     R1, sp
        MOV     R2, #1
        CallHAL HAL_NVMemoryRead
        LDRB    R14, [R13]
        ADD     R4, R4, R14
        ADD     R5, R5, #1
        TEQ     R5, R6
        BNE     %BT16
        ADD     R13, R13, #4
962
        Pull    "R6,sb,R12"
963 964 965 966
        Pull    "R0-R2"
        ADD     R1,R1,R4
        Pull    "R3-R5,PC"
17
967
        Pull    "sb,R12"
968
  ]
969
        SUB     R5, R3, R0              ; R5 = bytes being read
Kevin Bracey's avatar
Kevin Bracey committed
970

Robert Sprowson's avatar
Robert Sprowson committed
971 972
  [     E2ROMSupport
        BL      GetI2CAddress           ; convert to device address and offset
Kevin Bracey's avatar
Kevin Bracey committed
973
  |
Robert Sprowson's avatar
Robert Sprowson committed
974
        MOV     R1, #RTCAddressPHI
Kevin Bracey's avatar
Kevin Bracey committed
975 976
  ]

977 978 979
        MOV     R2, R0                  ; save the offset
        SUB     R13, R13, #12*2+4
        MOV     R14, R13
Kevin Bracey's avatar
Kevin Bracey committed
980
        TST     R1, #&100               ; 2-byte address?
981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997
        MOVNE   R0, R2, LSR #8
        STRNEB  R0, [R14], #1           ; offset (MSB)
        STRB    R2, [R14], #1           ; offset (LSB)

        SUB     R14, R14, R13
        STR     R14, [R13, #12]         ; transfer 1 length

        AND     R14, R1, #&FF
        ORR     R0, R14, #1:SHL:29      ; retry
        STR     R0, [R13, #4]           ; transfer 1 address
        ORR     R14, R14, #1            ; device address for read
        ORR     R14, R14, #1:SHL:30     ; checksum only please
        STR     R14, [R13, #16]         ; transfer 2 address
        STR     R13, [R13, #8]          ; transfer 1 data

        ADD     R14, R13, #12*2+4
        LDMIA   R14, {R0-R2}
Kevin Bracey's avatar
Kevin Bracey committed
998 999
        ADD     R0, R0, R5              ; update return R0
        SUB     R2, R2, R5              ; update return R2
1000 1001
        STMIB   R14, {R0,R2}
        MOV     R4, R1                  ; remember checksum
Kevin Bracey's avatar
Kevin Bracey committed
1002

1003 1004 1005 1006 1007
        STR     R5, [R13, #24]          ; transfer 2 length
        ADD     R0, R13, #4
        MOV     R1, #2
        BL      IIC_OpV

1008
        LDR     R1, [R13, #20]          ; read back checksum
1009 1010
        ADD     R1, R1, R4              ; update checksum
        ADD     R13, R13, #12*2+4+4
Kevin Bracey's avatar
Kevin Bracey committed
1011

Robert Sprowson's avatar
Robert Sprowson committed
1012
        Pull    "R0,R2,R3-R5,PC"
Kevin Bracey's avatar
Kevin Bracey committed
1013

Neil Turton's avatar
Neil Turton committed
1014 1015
; *****************************************************************************
;
Robert Sprowson's avatar
Robert Sprowson committed
1016 1017
;       GetI2CAddress - Convert NVRam physical address to i2c device address
;                       and offset
Neil Turton's avatar
Neil Turton committed
1018
;
Robert Sprowson's avatar
Robert Sprowson committed
1019
; in:   R0 = NVRam physical address (&00..size of NVRam)
Neil Turton's avatar
Neil Turton committed
1020
;
Robert Sprowson's avatar
Robert Sprowson committed
1021
; out:  R0 preserved
Neil Turton's avatar
Neil Turton committed
1022
;
Robert Sprowson's avatar
Robert Sprowson committed
1023 1024 1025 1026
;       C=0 => NVRam address is valid
;        R0 = physical address within i2c device
;        R1 = i2c device address for writing. Increment this device address
;             by 1 for reading. Bit 8 is set if device requires 2-byte physical address.
Neil Turton's avatar
Neil Turton committed
1027
;
Robert Sprowson's avatar
Robert Sprowson committed
1028 1029 1030
;       C=1 => NVRam address is out of range of CMOS or E2ROM chips
;        R0 preserved
;        R1 preserved
Neil Turton's avatar
Neil Turton committed
1031

Robert Sprowson's avatar
Robert Sprowson committed
1032
  [     E2ROMSupport
Neil Turton's avatar
Neil Turton committed
1033
GetI2CAddress ROUT
Robert Sprowson's avatar
Robert Sprowson committed
1034 1035 1036 1037 1038 1039
        Push    "R14"
        LDR     R14, =ZeroPage          ; get no 256 byte blocks and calculate end address
        LDRB    R14, [R14, #NVRamSize]
        MOV     R14, R14, LSL #8
        CMP     R0, R14
        Pull    "PC",CS                 ; indicate invalid
Neil Turton's avatar
Neil Turton committed
1040

Kevin Bracey's avatar
Kevin Bracey committed
1041
; address is < end address -> is valid
Robert Sprowson's avatar
Robert Sprowson committed
1042
        LDR     R1, =ZeroPage
1043
        LDRB    R1, [R1, #NVRamBase]
Kevin Bracey's avatar
Kevin Bracey committed
1044 1045 1046 1047

        CMP     R14, #2*1024            ; is the device bigger than 2K? If so, new addressing scheme
        ORRHI   R1, R1, #&100           ; set magic bit => 2 byte address
        BHI     %FT50
Neil Turton's avatar
Neil Turton committed
1048

Robert Sprowson's avatar
Robert Sprowson committed
1049 1050 1051
        MOVS    R14, R0, LSR #8         ; put top bits of physical address into device address
        ORRNE   R1, R1, R14, LSL #1
        ANDNE   R0, R0, #&FF            ; and use address within 256 byte block
Kevin Bracey's avatar
Kevin Bracey committed
1052
50
Kevin Bracey's avatar
Kevin Bracey committed
1053
        CLC
Robert Sprowson's avatar
Robert Sprowson committed
1054
        Pull    "PC"                    ; indicate valid
Kevin Bracey's avatar
Kevin Bracey committed
1055

Neil Turton's avatar
Neil Turton committed
1056
  ]
Neil Turton's avatar
Neil Turton committed
1057 1058

; *****************************************************************************
Neil Turton's avatar
Neil Turton committed
1059
;
Robert Sprowson's avatar
Robert Sprowson committed
1060
;       MangleCMOSAddress - Convert from logical to physical address
Neil Turton's avatar
Neil Turton committed
1061
;
Robert Sprowson's avatar
Robert Sprowson committed
1062
;       Doesn't check if address is larger than the amount of NVRam installed
Neil Turton's avatar
Neil Turton committed
1063
;
Robert Sprowson's avatar
Robert Sprowson committed
1064
; in:   R0 = logical address (&00...)
Neil Turton's avatar
Neil Turton committed
1065
;
Robert Sprowson's avatar
Robert Sprowson committed
1066 1067
; out:  C=0 => valid logical address
;        R0 = physical address (&40..&FF,&10..&3F,&00..0F,&100..)
Neil Turton's avatar
Neil Turton committed
1068
;
Robert Sprowson's avatar
Robert Sprowson committed
1069 1070
;       C=1 => invalid logical address
;        R0 preserved
Neil Turton's avatar
Neil Turton committed
1071
;
Neil Turton's avatar
Neil Turton committed
1072

Neil Turton's avatar
Neil Turton committed
1073
MangleCMOSAddress ROUT
Kevin Bracey's avatar
Kevin Bracey committed
1074
 [ E2ROMSupport
Robert Sprowson's avatar
Robert Sprowson committed
1075 1076 1077 1078 1079 1080 1081 1082 1083
        Push    "R14"
        LDR     R14, =ZeroPage          ; read no 256 byte blocks and calculate end address
        LDRB    R14, [R14, #NVRamSize]
        MOV     R14, R14, LSL #8
        CMP     R0, R14                 ; if >= end address then
        Pull    "R14"
        MOVCS   PC, R14                 ;    invalid (exit C set)

        CMP     R0, #&100               ; if < end address && >= &100 then
Kevin Bracey's avatar
Kevin Bracey committed
1084 1085 1086
        BLO     %FT05
        CLC
        MOV     PC, R14                 ;    valid (no mungeing)
Kevin Bracey's avatar
Kevin Bracey committed
1087
 ]
Kevin Bracey's avatar
Kevin Bracey committed
1088
05
Robert Sprowson's avatar
Robert Sprowson committed
1089
        CMP     R0, #&F0                ; if < &100 && >= &f0 then
Kevin Bracey's avatar
Kevin Bracey committed
1090
        [ E2ROMSupport
Kevin Bracey's avatar
Kevin Bracey committed
1091 1092 1093 1094
        BCC     %FT10
        SUB     R0, R0, #&F0            ;    map &F0->&FF to &00->0F for OTP section
        CLC
        MOV     PC, R14
Kevin Bracey's avatar
Kevin Bracey committed
1095
        |
Kevin Bracey's avatar
Kevin Bracey committed
1096
        MOVCS   PC, R14                 ;    invalid
Kevin Bracey's avatar
Kevin Bracey committed
1097
        ]
Kevin Bracey's avatar
Kevin Bracey committed
1098
10
Robert Sprowson's avatar
Robert Sprowson committed
1099 1100 1101
        ADD     R0, R0, #&40            ; now in range &40..&13F
        CMP     R0, #&100
        SUBCS   R0, R0, #(&100-&10)     ; now in range &40..&FF, &10..&3F
Kevin Bracey's avatar
Kevin Bracey committed
1102 1103
        CLC
        MOV     PC, R14                 ; valid
Neil Turton's avatar
Neil Turton committed
1104 1105 1106

; *****************************************************************************
;
Robert Sprowson's avatar
Robert Sprowson committed
1107
;       ValChecksum - test to see if the CMOS checksum is OK
Neil Turton's avatar
Neil Turton committed
1108
;
Kevin Bracey's avatar
Kevin Bracey committed
1109 1110 1111 1112 1113
;       This routine performs MangleCMOSAddress inherently.
;
;       The checksum does not include physical locations &00->&0F, even
;       if they are OTP section (as this is usually used for a unique id
;       which will be different for every machine and can't be changed).
Neil Turton's avatar
Neil Turton committed
1114
;
Robert Sprowson's avatar
Robert Sprowson committed
1115
; in:   none
Neil Turton's avatar
Neil Turton committed
1116
;
Robert Sprowson's avatar
Robert Sprowson committed
1117 1118 1119
; out:  R0 = calculated checksum
;       Z       set if checksum is valid
;       All other registers preserved
Neil Turton's avatar
Neil Turton committed
1120 1121
;

Neil Turton's avatar
Neil Turton committed
1122
  [ ChecksumCMOS
Neil Turton's avatar
Neil Turton committed
1123

Robert Sprowson's avatar
Robert Sprowson committed
1124
ValChecksum     Entry "R1-R2"
Neil Turton's avatar
Neil Turton committed
1125

Kevin Bracey's avatar
Kevin Bracey committed
1126 1127
        MOV     R0, #0
        MOV     R1, #CMOSxseed
Stewart Brodie's avatar
Stewart Brodie committed
1128
   [ E2ROMSupport
Robert Sprowson's avatar
Robert Sprowson committed
1129 1130 1131
        LDR     R2, =ZeroPage           ; read number of 256 byte blocks and calculate end address
        LDRB    R2, [R2, #NVRamSize]
        MOV     R2, R2, LSL #8
Stewart Brodie's avatar
Stewart Brodie committed
1132
   |
Robert Sprowson's avatar
Robert Sprowson committed
1133
        MOV     R2, #240
Stewart Brodie's avatar
Stewart Brodie committed
1134
   ]
Kevin Bracey's avatar
Kevin Bracey committed
1135
        BL      ChecksumBlock
Neil Turton's avatar
Neil Turton committed
1136 1137

;
Kevin Bracey's avatar
Kevin Bracey committed
1138
; R1 contains the actual checksum. Compare it with the recorded checksum
Neil Turton's avatar
Neil Turton committed
1139
;
Kevin Bracey's avatar
Kevin Bracey committed
1140
40
Robert Sprowson's avatar
Robert Sprowson committed
1141 1142 1143 1144 1145
        MOV     R0, #CheckSumCMOS
        BL      Read
        AND     R2, R0, #&FF            ; value from checksum location
        AND     R0, R1, #&FF            ; calculated value into R0
        CMPS    R0, R2
Neil Turton's avatar
Neil Turton committed
1146

Robert Sprowson's avatar
Robert Sprowson committed
1147
        EXIT
Neil Turton's avatar
Neil Turton committed
1148
  ]
Neil Turton's avatar
Neil Turton committed
1149 1150 1151

; *****************************************************************************
;
Robert Sprowson's avatar
Robert Sprowson committed
1152
;       MakeChecksum - calculate and write a correct checksum
Neil Turton's avatar
Neil Turton committed
1153
;
Robert Sprowson's avatar
Robert Sprowson committed
1154
; in:   none
Neil Turton's avatar
Neil Turton committed
1155
;
Robert Sprowson's avatar
Robert Sprowson committed
1156 1157
; out:  R0 = calculated checksum
;       All other registers preserved
Neil Turton's avatar
Neil Turton committed
1158 1159
;

Robert Sprowson's avatar
Robert Sprowson committed
1160
        [ ChecksumCMOS
Neil Turton's avatar
Neil Turton committed
1161

Robert Sprowson's avatar
Robert Sprowson committed
1162 1163
MakeChecksum    ROUT
        Push    "R1-R2,R14"
Kevin Bracey's avatar
Kevin Bracey committed
1164 1165
        MOV     R0, #0
        MOV     R1, #CMOSxseed
Stewart Brodie's avatar
Stewart Brodie committed
1166
  [ E2ROMSupport
Robert Sprowson's avatar
Robert Sprowson committed
1167 1168 1169
        LDR     R2, =ZeroPage
        LDRB    R2, [R2, #NVRamSize]
        MOV     R2, R2, LSL #8
Stewart Brodie's avatar
Stewart Brodie committed
1170
  |
Robert Sprowson's avatar
Robert Sprowson committed
1171
        MOV     R2, #240
Stewart Brodie's avatar
Stewart Brodie committed
1172
  ]
Kevin Bracey's avatar
Kevin Bracey committed
1173
        BL      ChecksumBlock
Robert Sprowson's avatar
Robert Sprowson committed
1174 1175 1176 1177
        MOV     R0, #CheckSumCMOS
        BL      Write
        Pull    "R1-R2,PC"
        ]
Neil Turton's avatar
Neil Turton committed
1178

Kevin Bracey's avatar
Kevin Bracey committed
1179 1180
        LTORG

Neil Turton's avatar
Neil Turton committed
1181 1182
; *****************************************************************************
;
Robert Sprowson's avatar
Robert Sprowson committed
1183
;       InitCMOSCache - Initialise cache of CMOS RAM
Dan Ellis's avatar
Dan Ellis committed
1184 1185 1186
;  in: -
;
;  out: R0 = 0 for failure
Neil Turton's avatar
Neil Turton committed
1187

Robert Sprowson's avatar
Robert Sprowson committed
1188 1189
InitCMOSCache   Entry "r1-r6, sb,r12"
    [   E2ROMSupport
Neil Turton's avatar
Neil Turton committed
1190

Robert Sprowson's avatar
Robert Sprowson committed
1191 1192 1193 1194
        ; Need to set the slowest speed so we can probe
        LDR     R4, =ZeroPage
        MOV     R3, #10         ; Default speed setting (5s delays)
        STRB    R3, [R4, #NVRamSpeed]
Kevin Bracey's avatar
Kevin Bracey committed
1195

Dan Ellis's avatar
Dan Ellis committed
1196 1197
 [ HAL
        AddressHAL
Robert Sprowson's avatar
Robert Sprowson committed
1198 1199 1200
        CallHAL HAL_NVMemoryType
        MOV     R5, R0
        ANDS    R0, R0, #NVMemoryFlag_Provision
1201
        ASSERT  NVMemoryFlag_None = 0
Kevin Bracey's avatar
Kevin Bracey committed
1202
        BEQ     InitCMOSCache_NoCMOS
Dan Ellis's avatar
Dan Ellis committed
1203

Robert Sprowson's avatar
Robert Sprowson committed
1204 1205 1206
        ; If it's only a maybe, then we probe
        TEQ     R0, #NVMemoryFlag_MaybeIIC
        BEQ     %FT03
Dan Ellis's avatar
Dan Ellis committed
1207

Robert Sprowson's avatar
Robert Sprowson committed
1208
        ; Else we read the size
Dan Ellis's avatar
Dan Ellis committed
1209

Robert Sprowson's avatar
Robert Sprowson committed
1210 1211 1212
        CallHAL HAL_NVMemorySize        ; returns number of bytes but..
        MOV     R0, R0, LSR#8           ; .. expecting no. of 256 blocks
        STRB    R0, [R4, #NVRamSize]
Dan Ellis's avatar
Dan Ellis committed
1213

1214 1215 1216 1217 1218 1219 1220 1221 1222
        TST     R5, #NVMemoryFlag_ProtectAtEnd
        STREQB  R0, [R4, #NVRamWriteSize]
        BEQ     %FT02
        CallHAL HAL_NVMemoryProtectedSize
        LDRB    R1, [R4, #NVRamSize]
        SUB     R0, R1, R0, LSR#8
        STRB    R0, [R4, #NVRamWriteSize]

02
Kevin Bracey's avatar
Kevin Bracey committed
1223 1224 1225 1226 1227 1228 1229 1230 1231
        CallHAL HAL_NVMemoryPageSize    ; returns size in bytes but..
        TEQ     R0, #0                  ; .. expecting power of 2
        MVNEQ   R0, #0
        MOV     R1, #0
22      MOVS    R0, R0, LSR #1
        ADDNE   R1, R1, #1
        BNE     %BT22
        STRB    R1, [R4, #NVRamPageSize]

Robert Sprowson's avatar
Robert Sprowson committed
1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256
        CallHAL HAL_NVMemoryIICAddress
        STRB    R0, [R4, #NVRamBase]

        MOV     R0, #0
        CallHAL HAL_IICType
        MOV     R3, #10
        TST     R0, #IICFlag_Fast
        MOVNE   R3, #3
        TST     R0, #IICFlag_HighSpeed
        MOVNE   R3, #1
        STRB    R3, [R4, #NVRamSpeed]

        ; If we're using IIC then read in the cache manually
        AND     R0, R5, #NVMemoryFlag_Provision
        TEQ     R0, #NVMemoryFlag_IIC
        BEQ     %FT06

        ; Else use HAL routine.
        MOV     R0, #0
        LDR     R1, =ZeroPage+CMOSRAMCache
        MOV     R2, #&100
        CallHAL HAL_NVMemoryRead
        TEQ     R0, #&100
        MOVNE   R0, #0                  ; Failure exit condition
        EXIT
Dan Ellis's avatar
Dan Ellis committed
1257 1258
03
 ]
Kevin Bracey's avatar
Kevin Bracey committed
1259

Robert Sprowson's avatar
Robert Sprowson committed
1260 1261
;       No HAL,so determine what hardware we've got fitted by probing,
;       R4 holds the number of 256 byte blocks that we've found
Dan Ellis's avatar
Dan Ellis committed
1262

Robert Catherall's avatar
Robert Catherall committed
1263
        MOV     R3, #10         ; assume 100kHz to start with
Kevin Bracey's avatar
Kevin Bracey committed
1264
        MOV     R5, #4          ; assume 16 byte page size to start with
1265
        MOV     R6, #0          ; assume not protected
Kevin Bracey's avatar
Kevin Bracey committed
1266

Kevin Bracey's avatar
Kevin Bracey committed
1267
; Have we got a 2K device ?
Kevin Bracey's avatar
Kevin Bracey committed
1268
        MOV     r1, #E2ROMAddress2K
Robert Sprowson's avatar
Robert Sprowson committed
1269 1270 1271
        MOV     r0, #(E2ROMAddress2K+14)
        BL      DummyAccess
        MOVVC   R4, #8
Kevin Bracey's avatar
Kevin Bracey committed
1272
        MOVVC   R3, #3          ; Fast speed setting (1.5s delays)
Robert Sprowson's avatar
Robert Sprowson committed
1273
        BVC     %FT5
Neil Turton's avatar
Neil Turton committed
1274

1275
; Have we got a 16K device ?
Kevin Bracey's avatar
Kevin Bracey committed
1276
        MOV     r1, #E2ROMAddress16K
Robert Sprowson's avatar
Robert Sprowson committed
1277 1278 1279
        MOV     r0, #E2ROMAddress16K
        BL      DummyAccess
        MOVVC   R4, #64
Kevin Bracey's avatar
Kevin Bracey committed
1280 1281
        MOVVC   R5, #6          ; 64 byte page size
        MOVVC   R3, #3          ; Fast speed setting (1.5s delays)
1282 1283
        BVC     %FT5

1284 1285
; Have we got a 4K device?
        MOV     r1, #E2ROMAddress4K
Robert Sprowson's avatar
Robert Sprowson committed
1286 1287 1288
        MOV     r0, #E2ROMAddress4K
        BL      DummyAccess
        MOVVC   R4, #16
1289 1290 1291 1292 1293
        MOVVC   R6, #12         ; Only bottom 3K writable
        MOVVC   R5, #5          ; 32 byte page size
        MOVVC   R3, #3          ; Fast speed setting (1.5s delays)
        BVC     %FT5

1294 1295
; Have we got an 8K device?
        MOV     r1, #E2ROMAddress8K
Robert Sprowson's avatar
Robert Sprowson committed
1296 1297 1298
        MOV     r0, #E2ROMAddress8K
        BL      DummyAccess
        MOVVC   R4, #32
1299 1300 1301 1302 1303 1304
        MOVVC   R5, #5          ; 32 byte page size
        MOVVC   R3, #3          ; Fast speed setting (1.5s delays)
        BVC     %FT5

; Have we got a protected 8K device?
        MOV     r1, #E2ROMAddress8K_prot
Robert Sprowson's avatar
Robert Sprowson committed
1305 1306 1307
        MOV     r0, #E2ROMAddress8K_prot
        BL      DummyAccess
        MOVVC   R4, #32
1308
        MOVVC   R6, #24         ; Only bottom 6K writable
1309 1310
        MOVVC   R5, #5          ; 32 byte page size
        MOVVC   R3, #3          ; Fast speed setting (1.5s delays)
Robert Catherall's avatar
Robert Catherall committed
1311 1312 1313 1314 1315 1316 1317 1318 1319 1320
        BVC     %FT5

; Have we got a 32K device?
        MOV     r1, #E2ROMAddress32K
        MOV     r0, #E2ROMAddress32K
        BL      DummyAccess
        MOVVC   R4, #128        ; 128,120,6,1
        MOVVC   R6, #120        ; Only bottom 30K writable
        MOVVC   R5, #6          ; 64 byte page size
        MOVVC   R3, #1          ; Hyper-fast speed setting (0.5s delays - 1MHz part)
Robert Sprowson's avatar
Robert Sprowson committed
1321
        BVC     %FT5
Robert Catherall's avatar
Robert Catherall committed
1322

1323
; Any storage in the Philips RTC?
Kevin Bracey's avatar
Kevin Bracey committed
1324 1325
        MOV     R1, #RTCAddressPHI
        MOV     R0, #RTCAddressPHI
Robert Sprowson's avatar
Robert Sprowson committed
1326
        BL      DummyAccess
Dan Ellis's avatar
Dan Ellis committed
1327
        MOV     R5, #8          ; 256 byte page size for CMOS
1328
        MOVVC   R4, #1
Robert Sprowson's avatar
Robert Sprowson committed
1329
        BVC     %FT5
Dan Ellis's avatar
Dan Ellis committed
1330 1331

; We ain't got anything!
Kevin Bracey's avatar
Kevin Bracey committed
1332 1333 1334 1335 1336 1337 1338
InitCMOSCache_NoCMOS
        LDR     R2, =ZeroPage
        MOV     R5, #8
        STRB    R5, [R2, #NVRamPageSize]        ; Act as though we have 256 bytes of
        MOV     R1, #1                          ; single page CMOS.
        STRB    R1, [R2, #NVRamSize]
        STRB    R1, [R2, #NVRamWriteSize]
Robert Sprowson's avatar
Robert Sprowson committed
1339 1340
        MOV     R0, #0          ; Exit failure
        EXIT
Kevin Bracey's avatar
Kevin Bracey committed
1341 1342

5
Robert Sprowson's avatar
Robert Sprowson committed
1343
        ; Set the NVRam count
1344
        LDR     R2, =ZeroPage
Robert Sprowson's avatar
Robert Sprowson committed
1345 1346
        STRB    R1, [R2, #NVRamBase]
        STRB    R4, [R2, #NVRamSize]
Kevin Bracey's avatar
Kevin Bracey committed
1347
        STRB    R5, [R2, #NVRamPageSize]
1348 1349 1350
        TEQ     R6, #0
        MOVEQ   R6, R4
        STRB    R6, [R2, #NVRamWriteSize]
Robert Catherall's avatar
Robert Catherall committed
1351 1352 1353

        CMP     R3, #I2Cticks   ; clamp speed to maximum bus speed
        MOVLO   R3, #I2Cticks
Kevin Bracey's avatar
Kevin Bracey committed
1354
        STRB    R3, [R2, #NVRamSpeed]
Dan Ellis's avatar
Dan Ellis committed
1355
06
Robert Sprowson's avatar
Robert Sprowson committed
1356 1357
        ; Initialise the cache
        LDR     R3, =ZeroPage+CMOSRAMCache
Neil Turton's avatar
Neil Turton committed
1358

Kevin Bracey's avatar
Kevin Bracey committed
1359
        TEQ     R4, #8                  ; check for 2K part
Robert Sprowson's avatar
Robert Sprowson committed
1360
        MOVNE   r0, #&00                ; if not, then start at 0 anyway and read non-OTP data into location 0..15
Kevin Bracey's avatar
Kevin Bracey committed
1361
        BNE     %FT07
Robert Sprowson's avatar
Robert Sprowson committed
1362 1363
        BL      ReadOTPArea
        MOV     r0, #&10                ; read rest of it from 16 onwards
Kevin Bracey's avatar
Kevin Bracey committed
1364 1365 1366 1367
07
        BL      GetI2CAddress           ; and convert to device address and offset
        MOV     R2, R0                  ; save the offset
        MOV     R4, #&100               ; stop at &100
Neil Turton's avatar
Neil Turton committed
1368
    |
1369
        ; No E2ROM support, assume just a Philips RTC
Robert Sprowson's avatar
Robert Sprowson committed
1370 1371 1372 1373
        MOV     R1, #RTCAddressPHI
        MOV     R2, #&10
        MOV     R4, #&100               ; stop at address &100
        LDR     R3, =ZeroPage+CMOSRAMCache
Neil Turton's avatar
Neil Turton committed
1374
    ]
1375 1376 1377

        ; Note - R4 MUST be &100 to prevent crossover between 256-byte pages
        ; (for devices with multiple addresses)
Kevin Bracey's avatar
Kevin Bracey committed
1378
09
Neil Turton's avatar
Neil Turton committed
1379

1380 1381 1382 1383 1384
        SUB     R13, R13, #2*12+4
        AND     R0, R1, #&FF
        STR     R0, [R13, #4]           ; transfer 1 address
        ADD     R0, R0, #1              ; read address
        STR     R0, [R13, #16]          ; transfer 2 address
Kevin Bracey's avatar
Kevin Bracey committed
1385
        TST     R1, #&100               ; 2-byte address?
1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404
        MOV     R14, R13
        MOVNE   R0, R2, LSR #8
        STRNEB  R0, [R14], #1           ; memory word address (MSB)
        STRB    R2, [R14], #1           ; memory word address (LSB)
        STR     R13, [R13, #8]          ; transfer 1 data
        SUB     R14, R14, R13
        STR     R14, [R13, #12]         ; transfer 1 length
        ADD     R14, R3, R2
        STR     R14, [R13, #20]         ; transfer 2 data
        SUB     R14, R4, R2
        STR     R14, [R13, #24]         ; transfer 2 length

        ADD     R0, R13, #4
        MOV     R1, #2
        BL      IIC_OpV

        ADD     R13, R13, #2*12+4
        MOV     R0, #1
        EXIT
Kevin Bracey's avatar
Kevin Bracey committed
1405 1406 1407

   [ E2ROMSupport
ReadOTPArea Entry
1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425
        SUB     R13, R13, #2*12+4
        MOV     R0, #0
        STRB    R0, [R13, #0]           ; offset 0
        MOV     R0, #E2ROMAddress2K_OTP
        STR     R0, [R13, #4]           ; transfer 1 address
        STR     R13, [R13, #8]          ; transfer 1 data
        MOV     R0, #1
        STR     R0, [R13, #12]          ; transfer 1 length
        MOV     R0, #E2ROMAddress2K_OTP + 1
        STR     R0, [R13, #16]          ; transfer 2 address
        STR     R3, [R13, #20]          ; transfer 2 data
        MOV     R0, #16
        STR     R0, [R13, #24]          ; transfer 2 length
        ADD     R0, R13, #4
        MOV     R1, #2
        BL      IIC_OpV
        ADD     R13, R13, #2*12+4
        EXIT
Kevin Bracey's avatar
Kevin Bracey committed
1426
   ]
Neil Turton's avatar
Neil Turton committed
1427

Neil Turton's avatar
Neil Turton committed
1428 1429
; *****************************************************************************
;
Robert Sprowson's avatar
Robert Sprowson committed
1430 1431
;       DummyAccess - do a dummy access of the specified device to find out
;                     if it is present
Neil Turton's avatar
Neil Turton committed
1432
;
Robert Sprowson's avatar
Robert Sprowson committed
1433
; in:   R0 = Write address of device
Neil Turton's avatar
Neil Turton committed
1434
;
Robert Sprowson's avatar
Robert Sprowson committed
1435 1436 1437
; out:  All registers preserved
;       V=0 => device is present
;       V=1 => device is not present
Neil Turton's avatar
Neil Turton committed
1438 1439

  [ E2ROMSupport
Kevin Bracey's avatar
Kevin Bracey committed
1440
DummyAccess
1441

Kevin Bracey's avatar
Kevin Bracey committed
1442 1443
 [ {TRUE}
        ; Blooming 80321 HW IIC can't do just START address STOP
Robert Sprowson's avatar
Robert Sprowson committed
1444
        Entry   "R0-R2",4
Kevin Bracey's avatar
Kevin Bracey committed
1445 1446 1447 1448 1449
        ORR     R0, R0, #1
        MOV     R1, R13
        MOV     R2, #1
        BL      IIC_Op
 |
Robert Sprowson's avatar
Robert Sprowson committed
1450
        Entry   "R1,R2"
1451 1452 1453
        MOV     R1, #0
        MOV     R2, #0
        BL      IIC_Op
Kevin Bracey's avatar
Kevin Bracey committed
1454
 ]
Neil Turton's avatar
Neil Turton committed
1455

Robert Sprowson's avatar
Robert Sprowson committed
1456
        EXIT                            ; Exit with V set appropriately
Neil Turton's avatar
Neil Turton committed
1457 1458
  ]

Kevin Bracey's avatar
Kevin Bracey committed
1459 1460 1461 1462 1463 1464 1465
; *****************************************************************************
;
;       SWI OS_NVMemory
;
; in:   R0 = reason code
;

1466
NVMemorySWI     Entry
Kevin Bracey's avatar
Kevin Bracey committed
1467 1468 1469 1470 1471 1472
        BL      NVMemorySub
        PullEnv
        ORRVS   LR, LR, #V_bit
        ExitSWIHandler

NVMemorySub
Robert Sprowson's avatar
Robert Sprowson committed
1473
        CMP     R0, #6
Kevin Bracey's avatar
Kevin Bracey committed
1474 1475 1476 1477 1478 1479 1480
        ADDLS   PC, PC, R0, LSL #2
        B       NVMemory_Unknown
        B       NVMemory_Size
        B       NVMemory_Read
        B       NVMemory_Write
        B       NVMemory_ReadBlock
        B       NVMemory_WriteBlock
Robert Sprowson's avatar
Robert Sprowson committed
1481 1482
        B       NVMemory_Unknown        ; Reserved for Kernel-5_41 divergence
        B       NVMemory_ResetValue
Kevin Bracey's avatar
Kevin Bracey committed
1483 1484 1485

NVMemory_Unknown
        ADRL    R0, ErrorBlock_HeapBadReason
Robert Sprowson's avatar
Robert Sprowson committed
1486
      [ International
Kevin Bracey's avatar
Kevin Bracey committed
1487 1488 1489
        Push    LR
        BL      TranslateError
        Pull    LR
Robert Sprowson's avatar
Robert Sprowson committed
1490
      ]
Kevin Bracey's avatar
Kevin Bracey committed
1491
        RETURNVS
Kevin Bracey's avatar
Kevin Bracey committed
1492 1493 1494 1495 1496 1497 1498 1499 1500

; -----------------------------------------------------------------------------
; OS_NVMemory 0 - find NV memory size
;
; in:   R0 = 0
;
; out:  R1 = NV memory size in bytes
;
NVMemory_Size
Robert Sprowson's avatar
Robert Sprowson committed
1501
    [ E2ROMSupport
Jeffrey Lee's avatar
Jeffrey Lee committed
1502
      [ ZeroPage = 0
Kevin Bracey's avatar
Kevin Bracey committed
1503
        LDRB    R1, [R0, #NVRamSize]
Jeffrey Lee's avatar
Jeffrey Lee committed
1504 1505 1506 1507
      |
        LDR     R1, =ZeroPage
        LDRB    R1, [R1, #NVRamSize]
      ]
Kevin Bracey's avatar
Kevin Bracey committed
1508
        MOV     R1, R1, LSL #8
Robert Sprowson's avatar
Robert Sprowson committed
1509
    |
Kevin Bracey's avatar
Kevin Bracey committed
1510
        MOV     R1, #240
Robert Sprowson's avatar
Robert Sprowson committed
1511
    ]
Kevin Bracey's avatar
Kevin Bracey committed
1512
        MOV     PC, LR
Kevin Bracey's avatar
Kevin Bracey committed
1513 1514 1515 1516 1517 1518 1519 1520 1521 1522

; -----------------------------------------------------------------------------
; OS_NVMemory 1 - read a byte
;
; in:   R0 = 1
;       R1 = location
;
; out:  R2 = value
;
NVMemory_Read
1523 1524
        Entry   "R4"
        MRS     R4, CPSR
Kevin Bracey's avatar
Kevin Bracey committed
1525
        BIC     R0, R4, #I32_bit
1526
        MSR     CPSR_c, R0      ; enable interrupts - this may take some time
Kevin Bracey's avatar
Kevin Bracey committed
1527 1528 1529 1530 1531
        MOV     R0, R1
        BL      ReadWithError
        MOVVC   R2, R0
        MOVVC   R0, #1          ; must preserve R0
        ORRVS   R4, R4, #V_bit
1532
        MSR     CPSR_cf, R4     ; restore interrupt state
Kevin Bracey's avatar
Kevin Bracey committed
1533 1534 1535 1536 1537
        EXIT

; -----------------------------------------------------------------------------
; OS_NVMemory 2 - write a byte
;
Robert Sprowson's avatar
Robert Sprowson committed
1538
; in:   R0 = 2
Kevin Bracey's avatar
Kevin Bracey committed
1539 1540 1541 1542
;       R1 = location
;       R2 = value
;
NVMemory_Write ROUT
Robert Sprowson's avatar
Robert Sprowson committed
1543 1544
      [ ProtectStationID
        TEQ     R1, #NetStnCMOS ; just ignore writes
Kevin Bracey's avatar
Kevin Bracey committed
1545
        MOVEQ   PC, R14
Robert Sprowson's avatar
Robert Sprowson committed
1546
      ]
1547 1548
        Entry   "R1,R4"
        MRS     R4, CPSR
Kevin Bracey's avatar
Kevin Bracey committed
1549
        BIC     R0, R4, #I32_bit
1550
        MSR     CPSR_c, R0      ; enable interrupts - this may take some time
Kevin Bracey's avatar
Kevin Bracey committed
1551 1552 1553 1554 1555
        MOV     R0, R1
        MOV     R1, R2
        BL      WriteWithError
        MOVVC   R0, #2          ; must preserve R0
        ORRVS   R4, R4, #V_bit
1556
        MSR     CPSR_cf, R4     ; restore interrupt state
Kevin Bracey's avatar
Kevin Bracey committed
1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567
        EXIT

; -----------------------------------------------------------------------------
; OS_NVMemory 3 - read a block
;
; in:   R0 = 3
;       R1 = location
;       R2 = buffer
;       R3 = length
;
NVMemory_ReadBlock
1568 1569
        Entry   "R1-R4"
        MRS     R4, CPSR
Kevin Bracey's avatar
Kevin Bracey committed
1570
        BIC     R0, R4, #I32_bit
1571
        MSR     CPSR_c, R0      ; enable interrupts - this may take some time
Kevin Bracey's avatar
Kevin Bracey committed
1572 1573 1574 1575 1576 1577
        MOV     R0, R1
        MOV     R1, R2
        MOV     R2, R3
        BL      ReadBlock
        MOVVC   R0, #3          ; must preserve R0
        ORRVS   R4, R4, #V_bit
1578
        MSR     CPSR_cf, R4     ; restore interrupt state
Kevin Bracey's avatar
Kevin Bracey committed
1579 1580 1581 1582 1583
        EXIT

; -----------------------------------------------------------------------------
; OS_NVMemory 4 - write a block
;
Robert Sprowson's avatar
Robert Sprowson committed
1584
; in:   R0 = 4
Kevin Bracey's avatar
Kevin Bracey committed
1585 1586 1587 1588 1589
;       R1 = location
;       R2 = buffer
;       R3 = length
;
NVMemory_WriteBlock ROUT
1590 1591
        Entry   "R1-R4"
        MRS     R4, CPSR
Kevin Bracey's avatar
Kevin Bracey committed
1592
        BIC     R0, R4, #I32_bit
1593
        MSR     CPSR_c, R0      ; enable interrupts - this may take some time
Robert Sprowson's avatar
Robert Sprowson committed
1594 1595 1596
      [ ProtectStationID
        ASSERT  NetStnCMOS = 0
        TEQ     R1, #NetStnCMOS
Kevin Bracey's avatar
Kevin Bracey committed
1597 1598 1599 1600 1601
        BNE     %FT10
        ADD     R1, R1, #1
        ADD     R2, R2, #1
        TEQ     R3, #0
        SUBNE   R3, R3, #1      ; steer clear of station ID
Robert Sprowson's avatar
Robert Sprowson committed
1602
      ]
Kevin Bracey's avatar
Kevin Bracey committed
1603 1604 1605 1606 1607 1608
10      MOV     R0, R1
        MOV     R1, R2
        MOV     R2, R3
        BL      WriteBlock
        MOVVC   R0, #4          ; must preserve R0
        ORRVS   R4, R4, #V_bit
1609
        MSR     CPSR_cf, R4     ; restore interrupt state
Kevin Bracey's avatar
Kevin Bracey committed
1610 1611
        EXIT

Robert Sprowson's avatar
Robert Sprowson committed
1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634
; -----------------------------------------------------------------------------
; OS_NVMemory 6 - query CMOS value that would be used on a Delete-Power-On reset
;
; in:   R0 = 6
;       R1 = location
;
; out:  R2 = value, or -1 if the value is unknown/untouched
;
NVMemory_ResetValue ROUT
        Entry   "R3"
        MOV     R2, #-1         ; assume outside our remit
        TEQ     R1, #NetStnCMOS
        EXIT    EQ
        ASSERT  CheckSumCMOS = CMOSLimit - 1
        CMP     R1, #CheckSumCMOS
        EXIT    CS

        TEQ     R1, #MouseCMOS
        BEQ     %FT20           ; code driven

        TEQ     R1, #PrintSoundCMOS
        BEQ     %FT30           ; code driven

1635
    [ STB :LAND: :DEF: IOMD_C_PALNTSCType
Robert Sprowson's avatar
Robert Sprowson committed
1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658
        TEQ     R1, #TerritoryCMOS
        BEQ     %FT40           ; code driven
        TEQ     R1, #CountryCMOS
        BEQ     %FT41           ; code driven
        TEQ     R1, #TimeZoneCMOS
        BEQ     %FT42           ; code driven
      [ :DEF: ObsoleteNC1CMOS
        TEQ     R1, #MiscellaneousNCCMOS
        BEQ     %FT43           ; code driven
      ]
    ]
        ADR     R3, DefaultCMOSTable
10
        LDRB    R2, [R3], #2    ; table is of location/value pairs...
        TEQ     R2, #&FF        ; ...terminated by &FF
        MOVEQ   R2, #0          ; not in the table, so must be zero
        EXIT    EQ
        TEQ     R2, R1          ; location match?
        LDREQB  R2, [R3, #-1]
        EXIT    EQ
        B       %BT10
20
    [ HAL
1659
      [ "$Machine"="IOMD"
Robert Sprowson's avatar
Robert Sprowson committed
1660 1661 1662 1663 1664 1665 1666 1667 1668
        Push    "R0-R1,R9,R12"
        AddressHAL
        MOV     R0, #0
        MOV     R1, #&400                    ; SSpace hopefully exists
        CallHAL HAL_ControllerAddress
        LDRB    R1, [R0, #IOMD_ID1]
        LDRB    R0, [R0, #IOMD_ID0]
        ORR     R0, R0, R1, LSL #8
        LDR     R1, =IOMD_Original
1669
        TEQ     R0, R1                       ; Select quadrature or PS2 as appropriate
Robert Sprowson's avatar
Robert Sprowson committed
1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724
        MOVEQ   R2, #PointerDevice_QuadMouse ; Risc PC
        MOVNE   R2, #PointerDevice_PS2Mouse  ; A7000 et al
        Pull    "R0-R1,R9,R12"
      |
        ; Everyone else is on USB
        MOV     R2, #PointerDevice_USB
      ]
    |
        Push    "R0-R1"
        MOV     R3, #IOMD_Base
        LDRB    R1, [R3, #IOMD_ID1]
        LDRB    R0, [R3, #IOMD_ID0]
        ORR     R0, R0, R1, LSL #8
        LDR     R1, =IOMD_Original
        TEQ     R0, R1
        MOVEQ   R2, #PointerDevice_QuadMouse ; Risc PC
        MOVNE   R2, #PointerDevice_PS2Mouse  ; A7000 et al
        Pull    "R0-R1"
    ]
        EXIT
30
    [ HAL
        MOV     R2, #2_10100100
                     ; ^^^       interpolate at low rates, 16 bit DAC, fully programmable rates
                     ;    ^^^^^  tbs chars valid, escape with GSTrans
    |
        Push    "R0-R1"
        MOV     R3, #IOMD_Base
        LDRB    R1, [R3, #IOMD_ID1]
        LDRB    R0, [R3, #IOMD_ID0]
        ORR     R0, R0, R1, LSL #8
        LDR     R1, =IOMD_7500
        TEQ     R0, R1
        LDRNE   R1, =IOMD_7500FE
        TEQNE   R0, R1
      [ STB
        MOVEQ   R2, #2_00000100              ; Cheapskates
      |
        MOVEQ   R2, #2_10100100              ; A7000 et al always have 16 bit sound
      ]
        BEQ     %FT31
        ; on Issue A's the protection bit is only weakly pulled up,
        ; so force it high, then read it back
        LDR     R3, =IOMD_MonitorType
        LDR     R1, [R3]
        ORR     R1, R1, #IOMD_SoundsystemLinkBit
        STR     R1, [R3]
        LDR     R1, [R3]
        TST     R1, #IOMD_SoundsystemLinkBit
        MOVEQ   R2, #2_10100100              ; if zero, must be Rimmer, so assume 16bit sound hardware present
        MOVNE   R2, #2_00000100              ; 8 bit sound on the motherboard (can't detect plugin upgrades)
31
        Pull    "R0-R1"
    ]
        EXIT
1725
    [ STB :LAND: :DEF: IOMD_C_PALNTSCType
Robert Sprowson's avatar
Robert Sprowson committed
1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777
40
        MOV     R2, #0                       ; PAL = territory UK
        MOV     R3, #49                      ; NTSC = territory USA
        B       %FT44
41
        MOV     R2, #1                       ; PAL = country UK
        MOV     R3, #48                      ; NTSC = country USA
        B       %FT44
42
        MOV     R2, #0                       ; PAL = 0 from UTC (GMT)
        MOV     R3, #&E0                     ; NTSC = -8 hours from UTC (USA Pacific)
        B       %FT44
      [ :DEF: ObsoleteNC1CMOS
43
        MOV     R2, #0                       ; PAL = A4 paper size
        MOV     R3, #1                       ; NTSC = US letter paper size
      ]
44
        MOV     R14, #IOMD_Base
        LDRB    R14, [R14, #IOMD_CLINES]
        TST     R14, #IOMD_C_PALNTSCType
        MOVNE   R2, R3                       ; Select NTSC when line high
        EXIT
    ]

 [ ValidateCMOS :LAND: STB
DefaultCMOSTable
        ; Minimalist table
        DCB     KeyDelCMOS,         32
        DCB     KeyRepCMOS,         8
        DCB     MODETVCMOS,         &10                                     ; TV 0,1
        DCB     StartCMOS,          (1:SHL:7):OR:(2:SHL:3)                  ; NONUM, NOCAPS
        DCB     DBTBCMOS,           (1:SHL:4)                               ; Boot
        DCB     YearCMOS+0,         00
        DCB     YearCMOS+1,         20
      [ IOMD_C_MonitorType = 0 :LAND: IOMD_C_PALNTSCType = 0
        ; TV if we don't have a MonitorType auto-detect bit
        DCB     VduCMOS,            Sync_Separate :OR: MonitorType0
      |
        ; auto-detect if we have a MonitorType auto-detect bit
        DCB     VduCMOS,            Sync_Auto :OR: MonitorTypeAuto
      ]
        DCB     CountryCMOS,        1                                       ; UK
        DCB     MouseStepCMOS,      2
        DCB     SystemSpeedCMOS,    (1:SHL:2):OR:(1:SHL:4):OR:(0:SHL:5)
                                    ; Delete-etc reset
                                    ;              WimpMode auto
                                    ;                           Cache on
 |
DefaultCMOSTable
        ; Normal table
        DCB     KeyDelCMOS,         32
1778
    [ "$Machine"="CortexA8" :LOR: "$Machine"="CortexA9"
Robert Sprowson's avatar
Robert Sprowson committed
1779 1780
        DCB     FileLangCMOS,       fsnumber_SCSIFS ; SCSIFS for OMAP3, etc.
    |
1781
      [ "$Machine"="ARM11ZF"
Robert Sprowson's avatar
Robert Sprowson committed
1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814
        DCB     FileLangCMOS,       fsnumber_SDFS   ; SDFS for Pi, etc.
      |
        DCB     FileLangCMOS,       fsnumber_adfs   ; ADFS
      ]
    ]
        DCB     FontCMOS,           64      ; KJB 13-Dec-02: Changed to 256K from 64K
        DCB     PigCMOS,            10
        DCB     KeyRepCMOS,         8
        DCB     RMASizeCMOS,        0
        DCB     SpriteSizeCMOS,     0
        DCB     SysHeapCMOS,        8
        DCB     MODETVCMOS,         &10     ; TV 0,1
        DCB     NetFSIDCMOS,        254
        DCB     NetPSIDCMOS,        235
        DCB     PSITCMOS,           (3:SHL:2) :OR: (1:SHL:5)
                                    ; Baud 3
                                    ;                Print 1

        DCB     DBTBCMOS,           (1:SHL:4) :OR: (4:SHL:5)
                                    ; Boot (changed from NoBoot 01-Sep-93)
                                    ;                Data 4

        DCB     StartCMOS,          (4:SHL:0) :OR: (2:SHL:3) :OR: (1:SHL:6) :OR: (0:SHL:7)
                                    ; ^              ^              ^              ^
                                    ; ADFS DR.4      NOCAPS         NODIR (moot)   NUM
      [ :LNOT: STB
        DCB     NewADFSCMOS+0,      &41     ; floppies=1, ST506=0, IDE=1 (changed 01-Sep-93)
      ]
        DCB     NewADFSCMOS+1,      4_3333  ; step 3 for each drive
        DCB     NewADFSCMOS+2,      1       ; ADFSBuffers 1

        DCB     SoundCMOS,          &F0     ; speaker on, volume 7, channel 1

1815
        DCB     LanguageCMOS,       11      ; typically module number of 'Desktop'
Robert Sprowson's avatar
Robert Sprowson committed
1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875
        DCB     YearCMOS+0,         00
        DCB     YearCMOS+1,         20
        DCB     NetFilerCMOS,       (0:SHL:0) :OR: (1:SHL:1) :OR: (0:SHL:2)
                                    ; FS list order by name
                                    ;                Use $.Arthurlib
                                    ;                               Large icons

        DCB     DesktopCMOS,        2_01000000      ; verbose ON
        DCB     WimpFlagsCMOS,      2_01101111      ; instant effects, drags off screen
        DCB     ProtectionCMOS,     2_01110110      ; allow only peek and user RPC
        DCB     MouseStepCMOS,      2
        DCB     FileSwitchCMOS,     (1:SHL:0) :OR: (1:SHL:1) :OR: (0:SHL:2) :OR: (0:SHL:3) :OR: (0:SHL:6)
                                    ; Truncate names
                                    ;                Use DragASprite (changed 01-Sept-93)
                                    ;                               Interactive file copying
                                    ;                                              Wimp dither colours off
                                    ;                                                             Last shutdown ordinary

        DCB     DesktopFeaturesCMOS,(1:SHL:0) :OR: (8:SHL:1) :OR: (0:SHL:7)
                                    ; 3D look
                                    ;                Homerton.Medium
                                    ;                               Tiled window background

      [ STB
        DCB     SystemSpeedCMOS,    (1:SHL:0):OR:(0:SHL:1):OR:(1:SHL:2):OR:(0:SHL:3):OR:(1:SHL:4):OR:(0:SHL:5):OR:(1:SHL:6):OR:(0:SHL:7)
                                    ; AUN ROMBoot Enabled
                                    ;              AUN auto-station numbering off
                                    ;                           Delete-etc reset
                                    ;                                        Power saving off
                                    ;                                                     WimpMode auto
                                    ;                                                                  Cache on
                                    ;                                                                               Broadcast loader disabled
                                    ;                                                                                            Broadcast loader colours off
      |
        DCB     SystemSpeedCMOS,    (0:SHL:0):OR:(0:SHL:1):OR:(1:SHL:2):OR:(0:SHL:3):OR:(1:SHL:4):OR:(0:SHL:5):OR:(1:SHL:6):OR:(0:SHL:7)
                                    ; AUN BootNet Disabled
                                    ;              AUN auto-station numbering off
                                    ;                           Delete-etc reset
                                    ;                                        Power saving off
                                    ;                                                     WimpMode auto
                                    ;                                                                  Cache on
                                    ;                                                                               Broadcast loader disabled
                                    ;                                                                                            Broadcast loader colours off
      ]

      [ STB
        ;       FontMaxCMOS                     yes, omitting is deliberate!
        DCB     FontMax2CMOS,       &2C       ; 32 point
        DCB     FontMax3CMOS,       &38       ; 32 point
      |
        DCB     FontMaxCMOS,        64        ; 4096k
        DCB     FontMax2CMOS,       36:EOR:12 ; 36 point
        DCB     FontMax3CMOS,       36:EOR:24 ; 36 point
        DCB     FontMax4CMOS,       16        ; 16 point
      ]
        DCB     AlarmAndTimeCMOS,   2_00010000           ; !Alarm autosave on
        DCB     FSLockCMOS+5,       &EA                  ; Checksum for no password
        DCB     SparrowMarker,      FreewayNoAutoAddress ; Stop Freeway assigning addresses to interfaces
        DCB     NetworkFlags,       LanManFStransport    ; LMTransport is NetBIOS over IP
        DCB     WimpDragMoveLimitCMOS, (1:SHL:7)         ; WimpIconiseButton
1876
      [ "$Machine"="CortexA8" :LOR: "$Machine"="CortexA9" :LOR: "$Machine"="ARM11ZF"
Robert Sprowson's avatar
Robert Sprowson committed
1877 1878 1879 1880 1881 1882 1883 1884
        DCB     CDROMFSCMOS,        &C0                  ; drives = 0, buffer size = 256K
      |
        DCB     CDROMFSCMOS,        &C1                  ; drives = 1, buffer size = 256K
      ]
 ]
        DCB     &FF
        ALIGN

Robert Sprowson's avatar
Robert Sprowson committed
1885
        END