i2cutils 52.2 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 32 33
; ***********************************
; ***    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.
; amg 7/12/96 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 40 41

PhysChecksum	*	(((CheckSumCMOS + &30) :MOD: &F0) + &10)

Kevin Bracey's avatar
Kevin Bracey committed
42 43
PollMax		*	150	; Number of times to poll for an Ack (increase if you clock faster - need to
                                ; allow 5ms for write cycle).
Neil Turton's avatar
Neil Turton committed
44 45

; Device addresses
Kevin Bracey's avatar
Kevin Bracey committed
46 47 48 49
RTCAddress		*	&a0     ; traditional RTC / 240 byte CMOS
E2ROMAddress		*	&a8     ; 24C08 device - 512 byte or 1K
E2ROMAddress2K		*	&e0     ; 24C174 device - 2K
E2ROMAddress2K_OTP	*	&60     ; 24C174 device - OTP section
50 51
E2ROMAddress4K          *       &a4     ; 24C32 device - 4K (top 1K protectable)
E2ROMAddress8K          *       &a2     ; 24C64 device - 8K (top 2K protectable)
Kevin Bracey's avatar
Kevin Bracey committed
52
E2ROMAddress16K         *       &a8     ; 24C128 device - 16K
Robert Catherall's avatar
Robert Catherall committed
53 54 55 56 57 58 59 60 61 62 63 64
E2ROMAddress32K         *       &a6     ; 24CS256 device - 32K (top 2K possibly OTP)

; Choose a lower limit on the number of ticks per clock phase based on the
; MaxI2Cspeed variable defined in Hdr:Machine.<Machine>
  [ MaxI2Cspeed >= 1000
I2Cticks        *       1
  |
  [ MaxI2Cspeed >= 400
I2Cticks        *       3
  |
I2Cticks        *       10
  ]
Neil Turton's avatar
Neil Turton committed
65 66
  ]

Dan Ellis's avatar
Dan Ellis committed
67

Neil Turton's avatar
Neil Turton committed
68 69
; *****************************************************************************
;
Neil Turton's avatar
Neil Turton committed
70
;	HexToBCD - Convert byte in hex to BCD
Neil Turton's avatar
Neil Turton committed
71
;
Neil Turton's avatar
Neil Turton committed
72
; in:	R0 = byte in hex
Neil Turton's avatar
Neil Turton committed
73
;
Neil Turton's avatar
Neil Turton committed
74 75
; 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
76 77 78
;

HexToBCD ROUT
Neil Turton's avatar
Neil Turton committed
79 80 81 82 83
	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
84 85 86

; *****************************************************************************
;
Neil Turton's avatar
Neil Turton committed
87
;	BCDToHex - Convert byte in BCD to hex
Neil Turton's avatar
Neil Turton committed
88
;
Neil Turton's avatar
Neil Turton committed
89
; in:	R0 = byte in BCD (ie x*16 + y)
Neil Turton's avatar
Neil Turton committed
90
;
Neil Turton's avatar
Neil Turton committed
91 92
; out:	R0 = byte in hex (ie x*10 + y)
;	All other registers preserved
Neil Turton's avatar
Neil Turton committed
93 94 95
;

BCDToHex ROUT
Neil Turton's avatar
Neil Turton committed
96 97 98 99 100
	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
101 102 103

; *****************************************************************************
;
Neil Turton's avatar
Neil Turton committed
104
;	SetC1C0 - Set clock and data lines to values in R1 and R0 respectively
Neil Turton's avatar
Neil Turton committed
105
;
106
; out:	ATPCS
Neil Turton's avatar
Neil Turton committed
107 108 109
;

SetC1C0 ROUT
110 111 112 113 114
        Push    "R9,R14"
 [ HAL
        AddressHAL
        MOV     R2, R1
        MOV     R1, R0
Dan Ellis's avatar
Dan Ellis committed
115
        MOV     R0, #0
116
        CallHAL HAL_IICSetLines
Kevin Bracey's avatar
Kevin Bracey committed
117
 |
Neil Turton's avatar
Neil Turton committed
118
	ADD	R0, R0, R1, LSL #1	; R0 := C0 + C1*2
Neil Turton's avatar
Neil Turton committed
119

Neil Turton's avatar
Neil Turton committed
120 121 122 123 124 125 126
	MOV	R2, #0				; prepare to index soft copy
	LDRB	R1, [R2, #IOCControlSoftCopy]	; read soft copy
	BIC	R1, R1, #&03			; clear clock and data
	ORR	R0, R1, R0			; put in new clock and data
	ORR	R0, R0, #&C0			; make sure two test bits are
						; always set to 1 !
	STRB	R0, [R2, #IOCControlSoftCopy]	; store back to soft copy
Neil Turton's avatar
Neil Turton committed
127

Neil Turton's avatar
Neil Turton committed
128 129
	MOV	R2, #IOC
	STRB	R0, [R2, #IOCControl]
130
 ]
Neil Turton's avatar
Neil Turton committed
131

132
      [ E2ROMSupport
Kevin Bracey's avatar
Kevin Bracey committed
133 134 135 136
        MOV	R0, #0
        LDRB	R0, [R0, #NVRamSpeed]
        TEQ     R0, #0
        MOVEQ   R0, #10                         ; default value if speed not checked yet
137 138 139
      |
        MOV     R0, #10                         ; default to slowest value if we have E2ROMSupport is false
      ]
Neil Turton's avatar
Neil Turton committed
140
	BL	DoMicroDelay
Neil Turton's avatar
Neil Turton committed
141

142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
        Pull    "R9,PC"

; *****************************************************************************
;
;	ReadC1C0 - Read clock and data lines to  R1 and R0 respectively
;
; out:	R0, R1 updated - otherwise ATPCS
;

ReadC1C0 ROUT
 [ HAL
        Push    "sb,lr"
        AddressHAL
        CallHAL HAL_IICReadLines
        Pull    "sb,pc"
Kevin Bracey's avatar
Kevin Bracey committed
157
 |
158
        MOV     a3, #IOC
159
        LDRB    a1, [a3, #IOCControl]
160 161 162 163
        MOV     a2, a1, LSR #1
        AND     a1, a1, #1
        AND     a2, a2, #1
        MOV     pc, lr
Kevin Bracey's avatar
Kevin Bracey committed
164
 ]
Neil Turton's avatar
Neil Turton committed
165 166 167

; *****************************************************************************
;
Neil Turton's avatar
Neil Turton committed
168
;	DoMicroDelay - Delay for >= R0/2 microseconds
Neil Turton's avatar
Neil Turton committed
169
;
Neil Turton's avatar
Neil Turton committed
170 171 172
; in:	R0 = time delay in 1/2 microsecond units
;	R2 -> IOC
;	On ARM600, we may or may not be in a 32-bit mode
Neil Turton's avatar
Neil Turton committed
173
;
Neil Turton's avatar
Neil Turton committed
174
; out:	R0,R1 corrupted
Neil Turton's avatar
Neil Turton committed
175 176 177
;

DoMicroDelay ROUT
178 179 180 181 182 183 184 185 186
  [ HAL
        Push    "a3,a4,sb,ip,lr"
        AddressHAL
        MOVS    a1, a1, LSR #1
        ADC     a1, a1, #0
        CallHAL HAL_CounterDelay
        Pull    "a3,a4,sb,ip,pc"
  |
        Push    R14
Neil Turton's avatar
Neil Turton committed
187 188
	STRB	R0, [R2, #Timer0LR]	; copy counter into output latch
	LDRB	R1, [R2, #Timer0CL]	; R1 := low output latch
Neil Turton's avatar
Neil Turton committed
189
10
Neil Turton's avatar
Neil Turton committed
190 191 192 193 194 195 196
	STRB	R0, [R2, #Timer0LR]	; copy counter into output latch
	LDRB	R14, [R2, #Timer0CL]	; R14 := low output latch
	TEQ	R14, R1			; unchanged ?
	BEQ	%BT10			; then loop
	MOV	R1, R14			; copy anyway
	SUBS	R0, R0, #1		; decrement count
	BNE	%BT10			; loop if not finished
Neil Turton's avatar
Neil Turton committed
197

Neil Turton's avatar
Neil Turton committed
198
	Pull	PC
199
  ]
Neil Turton's avatar
Neil Turton committed
200

Neil Turton's avatar
Neil Turton committed
201
	LTORG
Neil Turton's avatar
Neil Turton committed
202 203 204

; *****************************************************************************
;
Neil Turton's avatar
Neil Turton committed
205
;	ClockData - Clock a bit of data down the IIC bus
Neil Turton's avatar
Neil Turton committed
206
;
Neil Turton's avatar
Neil Turton committed
207
; in:	R0 = data bit
Neil Turton's avatar
Neil Turton committed
208
;
Neil Turton's avatar
Neil Turton committed
209
; out:	All registers preserved, including PSR
Neil Turton's avatar
Neil Turton committed
210 211 212
;

ClockData ROUT
Kevin Bracey's avatar
Kevin Bracey committed
213
 [ No26bitCode
214 215
	Push	"R0-R3,R4,R5,R12,R14"
        MRS     R4,CPSR
Kevin Bracey's avatar
Kevin Bracey committed
216
 |
217
	Push	"R0-R3,R5,R12,R14"
Kevin Bracey's avatar
Kevin Bracey committed
218
 ]
219
        MOV     R5, R0
Neil Turton's avatar
Neil Turton committed
220

Neil Turton's avatar
Neil Turton committed
221 222
	MOV	R1, #0			; Clock lo
	BL	SetC1C0
Neil Turton's avatar
Neil Turton committed
223

Kevin Bracey's avatar
Kevin Bracey committed
224
 [ No26bitCode
225
        ORR     R1,R4,#I32_bit
226
        MSR     CPSR_c,R1
Kevin Bracey's avatar
Kevin Bracey committed
227
 |
Neil Turton's avatar
Neil Turton committed
228 229 230
; Disable interrupts to ensure clock hi with data hi is only transient
; This allows BMU to detect idle condition by polling

Neil Turton's avatar
Neil Turton committed
231 232 233
	MOV	R1,PC
	ORR	R1,R1,#I_bit
	TEQP	PC,R1
Neil Turton's avatar
Neil Turton committed
234
 ]
235
        MOV     R0, R5
Neil Turton's avatar
Neil Turton committed
236 237
	MOV	R1, #1			; Clock hi
	BL	SetC1C0
Neil Turton's avatar
Neil Turton committed
238 239 240

; Delay here must be >= 4.0 microsecs

241
        MOV     R0, R5
Neil Turton's avatar
Neil Turton committed
242 243
	MOV	R1, #0			; Clock lo
	BL	SetC1C0
Neil Turton's avatar
Neil Turton committed
244

Kevin Bracey's avatar
Kevin Bracey committed
245
 [ No26bitCode
246 247
        MSR     CPSR_cf,R4              ; Restore interrupts
        Pull    "R0-R3,R4,R5,R12,PC"
Kevin Bracey's avatar
Kevin Bracey committed
248
 |
249
	Pull	"R0-R3,R5,R12,PC",,^
Kevin Bracey's avatar
Kevin Bracey committed
250
 ]
Neil Turton's avatar
Neil Turton committed
251

Neil Turton's avatar
Neil Turton committed
252 253 254
ClockData0 ROUT				; Clock a zero bit
	Push	"R0, R14"
	MOV	R0, #0
Kevin Bracey's avatar
Kevin Bracey committed
255 256
	BL	ClockData               ; preserves PSR
	Pull	"R0, PC"
Neil Turton's avatar
Neil Turton committed
257 258 259

; *****************************************************************************
;
Neil Turton's avatar
Neil Turton committed
260
;	Start - Send the Start signal
Neil Turton's avatar
Neil Turton committed
261
;
Neil Turton's avatar
Neil Turton committed
262
; out:	All registers preserved, including PSR
Neil Turton's avatar
Neil Turton committed
263 264
;

Neil Turton's avatar
Neil Turton committed
265
Start	ROUT
Kevin Bracey's avatar
Kevin Bracey committed
266
 [ No26bitCode
267 268
	Push	"R0-R3,R4,R12,R14"
        MRS     R4, CPSR
Kevin Bracey's avatar
Kevin Bracey committed
269
 |
270
	Push	"R0-R3,R12,R14"
Kevin Bracey's avatar
Kevin Bracey committed
271
 ]
Neil Turton's avatar
Neil Turton committed
272

Neil Turton's avatar
Neil Turton committed
273 274 275
	MOV	R0, #1			; clock HI, data HI
	MOV	R1, #1
	BL	SetC1C0
Neil Turton's avatar
Neil Turton committed
276

Kevin Bracey's avatar
Kevin Bracey committed
277
; Delay here must be >= 4.7 microsecs (1.3 for fast device)
Neil Turton's avatar
Neil Turton committed
278

Neil Turton's avatar
Neil Turton committed
279 280 281
	MOV	R0, #0			; clock HI, data LO
	MOV	R1, #1
	BL	SetC1C0
Neil Turton's avatar
Neil Turton committed
282 283

; Hold start condition for BMU
Dan Ellis's avatar
Dan Ellis committed
284 285
        LDR	R0, =ZeroPage
        LDRB	R0, [R0, #NVRamSpeed]
Neil Turton's avatar
Neil Turton committed
286

Dan Ellis's avatar
Dan Ellis committed
287 288 289 290
    	CMP 	R0, #10
	MOVGE	R2, #IOC
        MOVGE   R0, #10
	BLGE	DoMicroDelay
Neil Turton's avatar
Neil Turton committed
291

Kevin Bracey's avatar
Kevin Bracey committed
292
; Delay here must be >= 4.0 microsecs (0.6 for fast device)
Neil Turton's avatar
Neil Turton committed
293

Neil Turton's avatar
Neil Turton committed
294 295 296
	MOV	R0, #0			; clock LO, data LO
	MOV	R1, #0
	BL	SetC1C0
Neil Turton's avatar
Neil Turton committed
297

Kevin Bracey's avatar
Kevin Bracey committed
298
 [ No26bitCode
299 300
        MSR     CPSR_f, R4
	Pull	"R0-R3,R4,R12,PC"
Kevin Bracey's avatar
Kevin Bracey committed
301
 |
302
	Pull	"R0-R3,R12,PC"
Kevin Bracey's avatar
Kevin Bracey committed
303
 ]
Neil Turton's avatar
Neil Turton committed
304 305 306

; *****************************************************************************
;
Neil Turton's avatar
Neil Turton committed
307
;	Acknowledge - Check acknowledge after transmitting a byte
Neil Turton's avatar
Neil Turton committed
308
;
Neil Turton's avatar
Neil Turton committed
309 310 311
; out:	All registers preserved
;	V=0 => acknowledge received
;	V=1 => no acknowledge received
Neil Turton's avatar
Neil Turton committed
312 313 314
;

Acknowledge ROUT
315
	Push	"R0-R3,R12,R14"
Neil Turton's avatar
Neil Turton committed
316

Neil Turton's avatar
Neil Turton committed
317 318 319
	MOV	R0, #1			; clock LO, data HI
	MOV	R1, #0
	BL	SetC1C0
Neil Turton's avatar
Neil Turton committed
320 321 322 323 324

 [ {TRUE}
; Disable interrupts to ensure clock hi with data hi is only transient
; This allows BMU to detect idle condition by polling

325
        MRS     R1,CPSR
Kevin Bracey's avatar
Kevin Bracey committed
326 327
        Push    "R1"
        ORR     R1,R1,#I32_bit
328
        MSR     CPSR_c,R1
Neil Turton's avatar
Neil Turton committed
329
 ]
Neil Turton's avatar
Neil Turton committed
330 331 332
	MOV	R0, #1			; clock HI, data HI
	MOV	R1, #1
	BL	SetC1C0
Neil Turton's avatar
Neil Turton committed
333

Kevin Bracey's avatar
Kevin Bracey committed
334
; Delay here must be >= 4.0 microsecs (0.6 for fast device)
Neil Turton's avatar
Neil Turton committed
335

336 337
        BL      ReadC1C0
        MOV     R2, R0
Neil Turton's avatar
Neil Turton committed
338

Neil Turton's avatar
Neil Turton committed
339 340 341
	MOV	R0, #0
	MOV	R1, #0			; clock lo
	BL	SetC1C0
Neil Turton's avatar
Neil Turton committed
342 343

 [ {TRUE}
Neil Turton's avatar
Neil Turton committed
344
	Pull	"R1"
345
	MSR     CPSR_c,R1
Neil Turton's avatar
Neil Turton committed
346 347
 ]

Neil Turton's avatar
Neil Turton committed
348
	TST	R2, #1			; should be LO for correct acknowledge
349
        MRS     R2, CPSR
Neil Turton's avatar
Neil Turton committed
350 351
	BICEQ	R2, R2, #V_bit		; clear V if correct acknowledge
	ORRNE	R2, R2, #V_bit		; set V if no acknowledge
352
        MSR     CPSR_f, R2
Neil Turton's avatar
Neil Turton committed
353

354
	Pull	"R0-R3,R12,PC"
Neil Turton's avatar
Neil Turton committed
355 356 357

; *****************************************************************************
;
Neil Turton's avatar
Neil Turton committed
358
;	Stop - Send the Stop signal
Neil Turton's avatar
Neil Turton committed
359
;
Neil Turton's avatar
Neil Turton committed
360
; out:	All registers preserved, including PSR
Neil Turton's avatar
Neil Turton committed
361 362
;

Neil Turton's avatar
Neil Turton committed
363
Stop	ROUT
Kevin Bracey's avatar
Kevin Bracey committed
364
 [ No26bitCode
365 366
	Push	"R0-R3,R4,R12,R14"
        MRS     R4, CPSR
Kevin Bracey's avatar
Kevin Bracey committed
367
 |
368
	Push	"R0-R3,R12,R14"
Kevin Bracey's avatar
Kevin Bracey committed
369
 ]
Neil Turton's avatar
Neil Turton committed
370

Neil Turton's avatar
Neil Turton committed
371 372 373
	MOV	R0, #0			; clock HI, data LO
	MOV	R1, #1
	BL	SetC1C0
Neil Turton's avatar
Neil Turton committed
374

Kevin Bracey's avatar
Kevin Bracey committed
375
; Delay here must be >= 4.0 microsecs (0.6 for fast device)
Neil Turton's avatar
Neil Turton committed
376

Neil Turton's avatar
Neil Turton committed
377 378 379
	MOV	R0, #1			; clock HI, data HI
	MOV	R1, #1
	BL	SetC1C0
Neil Turton's avatar
Neil Turton committed
380

Kevin Bracey's avatar
Kevin Bracey committed
381
 [ No26bitCode
382
        MSR     CPSR_f, R2
383
	Pull	"R0-R3,R4,R12,PC"
Kevin Bracey's avatar
Kevin Bracey committed
384
 |
385
	Pull	"R0-R3,R12,PC",,^
Kevin Bracey's avatar
Kevin Bracey committed
386
 ]
Neil Turton's avatar
Neil Turton committed
387 388 389

; *****************************************************************************
;
Neil Turton's avatar
Neil Turton committed
390
;	TXByte - Transmit a byte
Neil Turton's avatar
Neil Turton committed
391
;
Neil Turton's avatar
Neil Turton committed
392
; in:	R0 = byte to be transmitted
Neil Turton's avatar
Neil Turton committed
393
;
Neil Turton's avatar
Neil Turton committed
394
; out:	All registers preserved, including PSR
Neil Turton's avatar
Neil Turton committed
395 396
;

Neil Turton's avatar
Neil Turton committed
397
TXByte	ROUT
Kevin Bracey's avatar
Kevin Bracey committed
398 399
 [ No26bitCode
	Push	"R0-R3,R14"
400
        MRS     R3, CPSR
Kevin Bracey's avatar
Kevin Bracey committed
401
 |
Neil Turton's avatar
Neil Turton committed
402
	Push	"R0-R2,R14"
Kevin Bracey's avatar
Kevin Bracey committed
403
 ]
Neil Turton's avatar
Neil Turton committed
404
	MOV	R1, #&80		; 2^7 the bit mask
Kevin Bracey's avatar
Kevin Bracey committed
405
	MOV	R2, R0			; byte goes into R2
Neil Turton's avatar
Neil Turton committed
406
10
Neil Turton's avatar
Neil Turton committed
407 408 409 410 411
	ANDS	R0, R2, R1		; zero if bit is zero
	MOVNE	R0, #1
	BL	ClockData		; send the bit
	MOVS	R1, R1, LSR #1
	BNE	%BT10
Kevin Bracey's avatar
Kevin Bracey committed
412
 [ No26bitCode
413
        MSR     CPSR_f, R3
Kevin Bracey's avatar
Kevin Bracey committed
414 415
	Pull	"R0-R3,PC"
 |
Neil Turton's avatar
Neil Turton committed
416
	Pull	"R0-R2,PC",,^
Kevin Bracey's avatar
Kevin Bracey committed
417
 ]
Neil Turton's avatar
Neil Turton committed
418 419 420

; *****************************************************************************
;
Neil Turton's avatar
Neil Turton committed
421 422 423 424 425 426
;	StartTXPollAck - Transmit start and a byte and poll for acknowledge
;
;	This is intended for devices with a slow internal write cycle which
;	don't ack until the write cycle is finished ( eg ATMEL AT24C01A/x )
;
; in:	R0 = byte to be transmitted
Neil Turton's avatar
Neil Turton committed
427
;
Neil Turton's avatar
Neil Turton committed
428
; out:	All registers preserved, including PSR
Neil Turton's avatar
Neil Turton committed
429 430
;

Neil Turton's avatar
Neil Turton committed
431
StartTXPollAck	ROUT
Kevin Bracey's avatar
Kevin Bracey committed
432 433
 [ No26bitCode
	Push	"R1,R3,R14"
434
        MRS     R3, CPSR
Kevin Bracey's avatar
Kevin Bracey committed
435
 |
Neil Turton's avatar
Neil Turton committed
436
	Push	"R1,R14"
Kevin Bracey's avatar
Kevin Bracey committed
437
 ]
Neil Turton's avatar
Neil Turton committed
438 439 440 441 442 443 444 445 446 447 448 449 450
	MOV	R1, #0
10
	INC	R1
	CMP	R1, #PollMax
	Pull	"R1,pc", EQ

	BL	Start
	BL	TXByte
	BL	Acknowledge
	BVS	%BT10
 [	{FALSE}
	BREG	R1, "i2c tries:"
 ]
Kevin Bracey's avatar
Kevin Bracey committed
451
 [ No26bitCode
452
        MSR     CPSR_f, R3
Kevin Bracey's avatar
Kevin Bracey committed
453 454
	Pull	"R1,R3,PC"
 |
Neil Turton's avatar
Neil Turton committed
455
	Pull	"R1,pc",,^
Kevin Bracey's avatar
Kevin Bracey committed
456
 ]
Neil Turton's avatar
Neil Turton committed
457

Neil Turton's avatar
Neil Turton committed
458 459 460 461 462 463 464 465 466
; *****************************************************************************
;
;	RXByte - Receive a byte
;
; out:	R0 = byte received
;	All other registers preserved, including PSR
;

RXByte	ROUT
Kevin Bracey's avatar
Kevin Bracey committed
467
 [ No26bitCode
468
	Push	"R1-R6,R12,R14"
469
        MRS     R5, CPSR
Kevin Bracey's avatar
Kevin Bracey committed
470
 |
471
	Push	"R1-R4, R6, R12, R14"
Kevin Bracey's avatar
Kevin Bracey committed
472
 ]
473
	MOV	R6, #0			; byte:=0
Neil Turton's avatar
Neil Turton committed
474 475 476 477 478
	MOV	R4, #7

	MOV	R0, #1			; clock LO, data HI
	MOV	R1, #0
	BL	SetC1C0
Neil Turton's avatar
Neil Turton committed
479 480 481 482 483
10
 [ {TRUE}
; Disable interrupts to ensure clock hi with data hi is only transient
; This allows BMU to detect idle condition by polling

484
        MRS     R1,CPSR
Kevin Bracey's avatar
Kevin Bracey committed
485 486
        Push    "R1"
        ORR     R1,R1,#I32_bit
487
        MSR     CPSR_c,R1
Neil Turton's avatar
Neil Turton committed
488
 ]
Neil Turton's avatar
Neil Turton committed
489 490 491
	MOV	R0, #1			; pulse clock HI
	MOV	R1, #1
	BL	SetC1C0
Neil Turton's avatar
Neil Turton committed
492

493 494
        BL      ReadC1C0
        ADD     R6, R0, R6, LSL #1      ; byte:=byte*2+ SDA
Neil Turton's avatar
Neil Turton committed
495

Neil Turton's avatar
Neil Turton committed
496 497 498
	MOV	R0, #1			; return clock LO
	MOV	R1, #0
	BL	SetC1C0
Neil Turton's avatar
Neil Turton committed
499 500

 [ {TRUE}
Neil Turton's avatar
Neil Turton committed
501
	Pull	"R1"
502
	MSR     CPSR_c,R1
Neil Turton's avatar
Neil Turton committed
503
 ]
Neil Turton's avatar
Neil Turton committed
504 505 506
	SUBS	R4, R4, #1
	BCS	%BT10

507
	MOV	R0, R6			; return the result in R0
Kevin Bracey's avatar
Kevin Bracey committed
508
 [ No26bitCode
509
        MSR     CPSR_f, R5
510
	Pull	"R1-R6, R12, PC"
Kevin Bracey's avatar
Kevin Bracey committed
511
 |
512
	Pull	"R1-R4, R6, R12, PC",,^
Kevin Bracey's avatar
Kevin Bracey committed
513
 ]
Neil Turton's avatar
Neil Turton committed
514 515 516 517 518 519 520 521

; *****************************************************************************

HTBTA	ROUT
	Push	R14
	BL	HexToBCD
	BL	TXAck
	Pull	PC
Neil Turton's avatar
Neil Turton committed
522

Neil Turton's avatar
Neil Turton committed
523 524 525 526 527 528 529 530 531 532 533 534
TXAck	ROUT
	Push	R14
	BL	TXByte
	BL	Acknowledge
	Pull	PC

CD0RBTH ROUT
	Push	R14
	BL	ClockData0
	BL	RXByte
	BL	BCDToHex
	Pull	PC
Neil Turton's avatar
Neil Turton committed
535 536 537

; *****************************************************************************
;
Neil Turton's avatar
Neil Turton committed
538
;	Write - Write a byte of CMOS RAM specified by logical address
Neil Turton's avatar
Neil Turton committed
539
;
Neil Turton's avatar
Neil Turton committed
540 541
; in:	R0 = address in CMOS RAM
;	R1 = data
Neil Turton's avatar
Neil Turton committed
542
;
Neil Turton's avatar
Neil Turton committed
543
; out:	All registers preserved
Neil Turton's avatar
Neil Turton committed
544 545
;

Kevin Bracey's avatar
Kevin Bracey committed
546 547 548 549 550 551 552 553 554
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
555 556
 |
        SETV
Kevin Bracey's avatar
Kevin Bracey committed
557
 ]
Kevin Bracey's avatar
Kevin Bracey committed
558
        Pull    "R1-R4,PC"
Kevin Bracey's avatar
Kevin Bracey committed
559 560 561

        MakeErrorBlock CoreNotWriteable

Robert Catherall's avatar
Robert Catherall committed
562 563 564 565 566 567 568 569 570 571 572
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
573
Write
Neil Turton's avatar
Neil Turton committed
574 575 576
	Push	"R0-R4, R14"
	BL	MangleCMOSAddress
	Pull	"R0-R4, PC", CS		; if invalid, then exit
Kevin Bracey's avatar
Kevin Bracey committed
577 578 579 580 581
05
  [ E2ROMSupport
        CMP     r0, #&10
        Pull    "R0-R4, PC", CC         ; don't write to OTP section
  ]
Neil Turton's avatar
Neil Turton committed
582

Stewart Brodie's avatar
Stewart Brodie committed
583
  [ E2ROMSupport
584 585
        MOV     R14, #0                 ; don't write to protected section
        LDRB    R14, [R14, #NVRamWriteSize]
586
        CMP     R0, R14, LSL #8         ; (note assumption that NVRamWriteSize is
587
        Pull    "R0-R4, PC", HS         ; outside mangled region).
Stewart Brodie's avatar
Stewart Brodie committed
588
  ]
589

Neil Turton's avatar
Neil Turton committed
590 591
	MOV	R2, R0
	MOV	R3, R1
Robert Catherall's avatar
Robert Catherall committed
592
08
Neil Turton's avatar
Neil Turton committed
593 594 595 596 597 598 599
 [ ChecksumCMOS
	BL	ReadStraight		; calculate new checksum :
	MOV	R4, R0
	MOV	R0, #PhysChecksum
	BL	ReadStraight
	SUB	R0, R0, R4		; = oldsum - oldcontents
	ADD	R4, R0, R3		;          + newcontents
Neil Turton's avatar
Neil Turton committed
600

Neil Turton's avatar
Neil Turton committed
601 602 603 604
	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
605
10
Kevin Bracey's avatar
Kevin Bracey committed
606 607 608
	CMP	r2, #&100		; check small cache limit
	BCS	%FT15
	LDR	R1, =CMOSRAMCache	; update cache, but always write to
Neil Turton's avatar
Neil Turton committed
609
	STRB	R3, [R1, R2]		; real hardware as well
Kevin Bracey's avatar
Kevin Bracey committed
610
15
Dan Ellis's avatar
Dan Ellis committed
611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636

  [ HAL
    	Push	"R12,sb"
    	AddressHAL
    	MOV 	R12, R2
    	CallHAL	HAL_NVMemoryType
    	AND 	R0, R0, #NVMemoryFlag_Provision
    	TEQ 	R0, #NVMemoryFlag_None

    	; If there's no NVmemory, all we have is the internal cache.
    	Pull 	"R12,sb", EQ
	Pull	"R0-R4,PC", EQ

    	TEQ 	R0, #NVMemoryFlag_HAL
    	BNE 	%FT20	    	    	; Go and do IIC stuff.

    	; Make the HAL call - we have to write the data into a buffer.
    	Push	"R3"
    	MOV 	R0, R12
    	MOV 	R1, sp
    	MOV 	R2, #1
    	CallHAL	HAL_NVMemoryWrite
    	Pull	"R3"
    	Pull	"R12,sb"
    	Pull	"R0-R4,PC"
20
637
        Pull    "R12,sb"
Dan Ellis's avatar
Dan Ellis committed
638 639 640
  ]


Neil Turton's avatar
Neil Turton committed
641 642 643 644 645 646
 [ E2ROMSupport
	MOV	R0, R2
	BL	GetI2CAddress		; convert to device address + offset
	MOV	R2, R0			; save the offset
 |
	MOV	R1, #RTCAddress
Neil Turton's avatar
Neil Turton committed
647 648
 ]

Neil Turton's avatar
Neil Turton committed
649 650
	MOV	R0, R1			; device address for write
	BL	StartTXPollAck
Neil Turton's avatar
Neil Turton committed
651

Kevin Bracey's avatar
Kevin Bracey committed
652 653 654 655 656
        TST     R1, #&100               ; 2-byte address?
        MOVNE   R0, R2, LSR #8          ; offset (MSB)
        BLNE    TXAck

	AND	R0, R2, #&FF		; offset (LSB)
Neil Turton's avatar
Neil Turton committed
657
	BL	TXAck
Neil Turton's avatar
Neil Turton committed
658

Neil Turton's avatar
Neil Turton committed
659 660
	MOV	R0, R3			; data
	BL	TXAck
Neil Turton's avatar
Neil Turton committed
661

Neil Turton's avatar
Neil Turton committed
662 663 664 665 666 667 668 669 670
	BL	Stop
	[ 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
671

Kevin Bracey's avatar
Kevin Bracey committed
672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687
; *****************************************************************************
;
;       WriteBlock - Write a block of CMOS RAM specified by logical address
;
; in:   R0 = address in CMOS RAM
;       R1 = address to copy from
;       R2 = length
;
; out:  All registers preserved
;


WriteBlock ROUT
        Push    "R0-R4,R14"
  [     E2ROMSupport
        MOV	R14, #0
688
        LDRB    R4, [R14, #NVRamWriteSize]
Kevin Bracey's avatar
Kevin Bracey committed
689
        LDRB	R14, [R14, #NVRamSize]
690
        MOV     R4, R4, LSL #8
Kevin Bracey's avatar
Kevin Bracey committed
691 692 693
        MOV     R14, R14, LSL #8
  |
        MOV     R14, #240
694
        MOV     R4, R14
Kevin Bracey's avatar
Kevin Bracey committed
695 696 697 698 699 700 701 702 703 704
  ]

        CMP     R0, R14
        BHS     %FT90

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

705 706 707 708 709 710
        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
711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752
        TEQ     R2, #0
        BEQ     %FT80

        CMP     R0, #CheckSumCMOS       ; are we going to write the checksum byte?
        BHI     %FT03
        CMP     R3, #CheckSumCMOS
        BHS     %FT05

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

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

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

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

80
        Pull    "R0-R4,PC"

90
        ADD     SP, SP, #4              ; junk stacked R0
        ADR     R0, ErrorBlock_CoreNotWriteable
 [ International
        BL      TranslateError
Kevin Bracey's avatar
Kevin Bracey committed
753 754
 |
        SETV
Kevin Bracey's avatar
Kevin Bracey committed
755
 ]
Kevin Bracey's avatar
Kevin Bracey committed
756
        Pull    "R1-R4,PC"
Kevin Bracey's avatar
Kevin Bracey committed
757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845

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

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

; R3 = logical end of current segment (exclusive)
; R4 = offset from logical to physical address for this segment
10
        ADD     R14, R0, R2
        CMP     R3, R14
        MOVHI   R3, R14
 [ E2ROMSupport
; R3 = logical end of possible transaction (exclusive). Now check we don't cross page boundaries.
        MOV	R14, #0
        LDRB	R14, [R14, #NVRamPageSize]
        MOV     R5, #1
        MOV     R14, R5, LSL R14        ; R14 = (1<<pagesize)

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

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

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

        LDR     R14, =CMOSRAMCache
        Push    "R3, R4"
        ADD     R3, R3, R4              ; R3 = physical end address
        ADD     R4, R4, R0              ; R4 = physical address
        ADD     R3, R3, R14             ; R3 = cache end address
        ADD     R4, R4, R14             ; R4 = cache address
        SUB     R14, R3, R4             ; R14 = bytes being written
        MOV     R5, R1                  ; remember R1
12      LDRB    R14, [R1], #1           ; update cache copy
        STRB    R14, [R4], #1
        CMP     R4, R3
        BLO     %BT12
        MOV     R1, R5                  ; restore R1, and continue to update real memory
        Pull    "R3, R4"
15
        Push    "R0-R2"
        ADD     R0, R0, R4              ; R0 = physical address
Dan Ellis's avatar
Dan Ellis committed
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
  [ HAL
    	Push	"R12, sb"
    	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 	"R12,sb", EQ
    	Pull	"R0-R2", EQ
    	MOVEQ 	R2, #0	    	    	; nothing written
	Pull	"R3,R5-R6,PC", EQ

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

    	; Make the HAL call
    	CallHAL	HAL_NVMemoryWrite    	; returns bytes wrtten in R0
    	MOV 	R2, R0
    	ADD 	R0, R0, R2  	    	; update return R0
    	ADD 	R4, R4, R2
    	Pull	"R12,sb"
    	Pull	"R0-R2"
    	Pull	"R3,R5-R6,PC"

17
    	Pull	"sb"
  ]

Kevin Bracey's avatar
Kevin Bracey committed
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 903 904
  [	E2ROMSupport
	BL	GetI2CAddress		; convert to device address and offset
  |
	MOV	R1, #RTCAddress
  ]

	MOV	R2, R0			; save the offset
	MOV	R0, R1			; device address for write
	BL	StartTXPollAck

        TST     R1, #&100               ; 2-byte address?
        MOVNE   R0, R2, LSR #8          ; offset (MSB)
        BLNE    TXAck

	AND	R0, R2, #&FF		; offset (LSB)
	BL	TXAck

        Pull    "R0-R2"
        SUB     R5, R3, R0              ; R5 = bytes being written
        ADD     R0, R0, R5              ; update return R0
        SUB     R2, R2, R5              ; update return R2
        Push    "R0,R2"
20
        LDRB    R0, [R1], #1
        ADD     R6, R6, R0              ; update checksum counter
        BL      TXAck
        SUBS    R5, R5, #1
        BNE     %BT20
Kevin Bracey's avatar
Kevin Bracey committed
905 906
                                        ; V clear
	BL	Stop                    ; preserves flags
Kevin Bracey's avatar
Kevin Bracey committed
907 908 909

        MOV     R4, R6

Kevin Bracey's avatar
Kevin Bracey committed
910
	Pull	"R0,R2,R3,R5,R6,PC"
Kevin Bracey's avatar
Kevin Bracey committed
911

Neil Turton's avatar
Neil Turton committed
912 913
; *****************************************************************************
;
Neil Turton's avatar
Neil Turton committed
914 915
;	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
916
;       ReadWithError - Read a byte of CMOS RAM specified by logical address, giving error if out of range
Neil Turton's avatar
Neil Turton committed
917
;
Neil Turton's avatar
Neil Turton committed
918
; in:	R0 = address in CMOS RAM
Neil Turton's avatar
Neil Turton committed
919
;
Kevin Bracey's avatar
Kevin Bracey committed
920
; out:	R0 = data (illegal address return 0, or error for ReadWithError)
Neil Turton's avatar
Neil Turton committed
921
;	All other registers preserved
Neil Turton's avatar
Neil Turton committed
922 923 924
;

ReadStraight ROUT
Neil Turton's avatar
Neil Turton committed
925 926
	Push	"R1,R2,R14"
	B	%FT10
Neil Turton's avatar
Neil Turton committed
927

Kevin Bracey's avatar
Kevin Bracey committed
928 929 930 931 932 933 934
ReadWithError
        Push    "R1,R2,R14"
        BL      MangleCMOSAddress
        BCC     %FT10
        ADR     R0, ErrorBlock_CoreNotReadable
 [ International
        BL      TranslateError
Kevin Bracey's avatar
Kevin Bracey committed
935 936
 |
        SETV
Kevin Bracey's avatar
Kevin Bracey committed
937
 ]
Kevin Bracey's avatar
Kevin Bracey committed
938
        Pull    "R1,R2,PC"
Kevin Bracey's avatar
Kevin Bracey committed
939 940 941

        MakeErrorBlock CoreNotReadable

Neil Turton's avatar
Neil Turton committed
942
Read
Neil Turton's avatar
Neil Turton committed
943 944 945 946
	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
947
10
Neil Turton's avatar
Neil Turton committed
948 949
	TEQ	R0, #&40		; is it Econet station number
	BEQ	%FT15	 		; if so then don't use cache
Kevin Bracey's avatar
Kevin Bracey committed
950 951 952 953 954 955 956 957 958 959 960
        CMP     R0, #&10                ; don't cache the clock
  [     E2ROMSupport
        BHS     %FT13
        MOV     R14, #0
        LDR     R14, [R14, #RTCFitted]
        TEQ     R14, #0
        BNE     %FT15
  |
        BLO     %FT15
  ]
13	CMP	R0, #&100		; check small cache limit
Kevin Bracey's avatar
Kevin Bracey committed
961 962 963
	LDRCC	R2, =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
964 965 966
15

; else drop thru into real CMOS reading code
Dan Ellis's avatar
Dan Ellis committed
967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994

  [ HAL
    	Push	"R4, sb"
    	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 	"R4, sb", 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	"R4, sb"
    	Pull	"R1,R2,PC"

20
995
        Pull    "R4, sb"
Neil Turton's avatar
Neil Turton committed
996
  ]
Neil Turton's avatar
Neil Turton committed
997

Neil Turton's avatar
Neil Turton committed
998 999 1000 1001 1002
  [	E2ROMSupport
	BL	GetI2CAddress		; convert to device address and offset
  |
	MOV	R1, #RTCAddress
  ]
Neil Turton's avatar
Neil Turton committed
1003

Neil Turton's avatar
Neil Turton committed
1004 1005 1006
	MOV	R2, R0			; save the offset
	MOV	R0, R1			; device address for write
	BL	StartTXPollAck
Neil Turton's avatar
Neil Turton committed
1007

Kevin Bracey's avatar
Kevin Bracey committed
1008 1009 1010 1011 1012
        TST     R1, #&100               ; 2-byte address?
        MOVNE   R0, R2, LSR #8          ; offset (MSB)
        BLNE    TXAck

	AND	R0, R2, #&FF		; offset (LSB)
Neil Turton's avatar
Neil Turton committed
1013
	BL	TXAck
Neil Turton's avatar
Neil Turton committed
1014

Neil Turton's avatar
Neil Turton committed
1015
	BL	Start
Neil Turton's avatar
Neil Turton committed
1016

Neil Turton's avatar
Neil Turton committed
1017 1018
	ADD	R0, R1, #1		; device address for read
	BL	TXAck
Neil Turton's avatar
Neil Turton committed
1019

Neil Turton's avatar
Neil Turton committed
1020 1021
	BL	RXByte			; returned in R0
	MOV	R2, R0			; copy to R2 for now
Neil Turton's avatar
Neil Turton committed
1022

Neil Turton's avatar
Neil Turton committed
1023 1024
	MOV	R0, #1
	BL	ClockData
Neil Turton's avatar
Neil Turton committed
1025

Neil Turton's avatar
Neil Turton committed
1026
	BL	Stop
Neil Turton's avatar
Neil Turton committed
1027

Neil Turton's avatar
Neil Turton committed
1028
	MOV	R0, R2			; return the result
Neil Turton's avatar
Neil Turton committed
1029

Neil Turton's avatar
Neil Turton committed
1030
	Pull	"R1,R2,PC"
Neil Turton's avatar
Neil Turton committed
1031

Kevin Bracey's avatar
Kevin Bracey committed
1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077

; *****************************************************************************
;
;       ReadBlock - Read a block of CMOS RAM specified by logical address
;
; in:   R0 = address in CMOS RAM
;       R1 = address to copy to
;       R2 = length
;
; out:  All registers preserved
;


ReadBlock ROUT
        Push    "R0-R3,R14"
  [     E2ROMSupport
        MOV	R14, #0
        LDRB	R14, [R14, #NVRamSize]
        MOV     R14, R14, LSL #8
  |
        MOV     R14, #240
  ]

        CMP     R0, R14
        BHS     %FT90

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

        TEQ     R2, #0
        BEQ     %FT80

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

90
        ADD     SP, SP, #4              ; junk stacked R0
        ADR     R0, ErrorBlock_CoreNotReadable
 [ International
        BL      TranslateError
Kevin Bracey's avatar
Kevin Bracey committed
1078 1079
 |
        SETV
Kevin Bracey's avatar
Kevin Bracey committed
1080
 ]
Kevin Bracey's avatar
Kevin Bracey committed
1081
        Pull    "R1-R3,PC"
Kevin Bracey's avatar
Kevin Bracey committed
1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139

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

        LDR     R14, =CMOSRAMCache
        ADD     R3, R3, R4              ; R3 = physical end address
        ADD     R4, R4, R0              ; R4 = physical address
        ADD     R3, R3, R14             ; R3 = cache end address
        ADD     R4, R4, R14             ; R4 = cache address
        SUB     R14, R3, R4             ; R14 = bytes being read
        ADD     R0, R0, R14             ; update return R0
        SUB     R2, R2, R14             ; update return R2

12      LDRB    R14, [R4], #1
        CMP     R4, R3
        STRB    R14, [R1], #1
        BLO     %BT12
Kevin Bracey's avatar
Kevin Bracey committed
1140
        Pull    "R3-R5,PC"              ; V will be clear
Kevin Bracey's avatar
Kevin Bracey committed
1141 1142 1143
15
        Push    "R0-R2"
        ADD     R0, R0, R4              ; R0 = physical address
Dan Ellis's avatar
Dan Ellis committed
1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175
  [ HAL
    	Push	"sb"
    	MOV 	R5, R0	    	    	; save address
    	AddressHAL
    	Push	"R1-R3,R12"
    	CallHAL	HAL_NVMemoryType
    	Pull	"R1-R3,R12"
    	AND 	R0, R0, #NVMemoryFlag_Provision
    	TEQ 	R0, #NVMemoryFlag_None

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

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

    	; Make the HAL call
    	Push	"R12"
    	CallHAL	HAL_NVMemoryRead    	; returns bytes read in R0
    	Pull	"R12"
    	MOV 	R2, R0
    	ADD 	R0, R0, R1  	    	; update return R0
    	Pull	"sb"
    	Pull	"R3-R5,PC"

17
    	Pull	"sb"
  ]

Kevin Bracey's avatar
Kevin Bracey committed
1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210
  [	E2ROMSupport
	BL	GetI2CAddress		; convert to device address and offset
  |
	MOV	R1, #RTCAddress
  ]

	MOV	R2, R0			; save the offset
	MOV	R0, R1			; device address for write
	BL	StartTXPollAck

        TST     R1, #&100               ; 2-byte address?
        MOVNE   R0, R2, LSR #8          ; offset (MSB)
        BLNE    TXAck

	AND	R0, R2, #&FF		; offset (LSB)
	BL	TXAck

	BL	Start

	ADD	R0, R1, #1		; device address for read
	BL	TXAck

        Pull    "R0-R2"
        SUB     R5, R3, R0              ; R5 = bytes being read
        ADD     R0, R0, R5              ; update return R0
        SUB     R2, R2, R5              ; update return R2
        Push    "R0,R2"
20
        BL      RXByte
        STRB    R0, [R1], #1
        SUBS    R5, R5, #1
        MOVNE   R0, #0                  ; not done - ACK byte
	MOVEQ   R0, #1                  ; done - no ACK
	BL	ClockData
        BNE     %BT20
Kevin Bracey's avatar
Kevin Bracey committed
1211
                                        ; V will be clear
Kevin Bracey's avatar
Kevin Bracey committed
1212 1213
	BL	Stop

Kevin Bracey's avatar
Kevin Bracey committed
1214
	Pull	"R0,R2,R3-R5,PC"
Kevin Bracey's avatar
Kevin Bracey committed
1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 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 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353

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


ChecksumBlock ROUT
        Push    "R0,R2,R14"

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


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

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


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

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

        LDR     R14, =CMOSRAMCache
        ADD     R3, R3, R4              ; R3 = physical end address
        ADD     R4, R4, R0              ; R4 = physical address
        ADD     R3, R3, R14             ; R3 = cache end address
        ADD     R4, R4, R14             ; R4 = cache address
        SUB     R14, R3, R4             ; R14 = bytes being read
        ADD     R0, R0, R14             ; update return R0
        SUB     R2, R2, R14             ; update return R2

12      LDRB    R14, [R4], #1
        CMP     R4, R3
        ADD     R1, R1, R14
        BLO     %BT12
        Pull    "R3-R5,PC"
15
        Push    "R0-R2"
        ADD     R0, R0, R4              ; R0 = physical address
  [	E2ROMSupport
	BL	GetI2CAddress		; convert to device address and offset
  |
	MOV	R1, #RTCAddress
  ]

	MOV	R2, R0			; save the offset
	MOV	R0, R1			; device address for write
	BL	StartTXPollAck

        TST     R1, #&100               ; 2-byte address?
        MOVNE   R0, R2, LSR #8          ; offset (MSB)
        BLNE    TXAck

	AND	R0, R2, #&FF		; offset (LSB)
	BL	TXAck

	BL	Start

	ADD	R0, R1, #1		; device address for read
	BL	TXAck

        Pull    "R0-R2"
        SUB     R5, R3, R0              ; R5 = bytes being read
        ADD     R0, R0, R5              ; update return R0
        SUB     R2, R2, R5              ; update return R2
        Push    "R0,R2"
20
        BL      RXByte
        ADD     R1, R1, R0
        SUBS    R5, R5, #1
        MOVNE   R0, #0                  ; not done - ACK byte
	MOVEQ   R0, #1                  ; done - no ACK
	BL	ClockData
        BNE     %BT20

	BL	Stop

	Pull	"R0,R2,R3-R5,PC"

Neil Turton's avatar
Neil Turton committed
1354 1355
; *****************************************************************************
;
Neil Turton's avatar
Neil Turton committed
1356 1357
;	GetI2CAddress - Convert NVRam physical address to i2c device address
;	                and offset
Neil Turton's avatar
Neil Turton committed
1358
;
Neil Turton's avatar
Neil Turton committed
1359
; in:	R0 = NVRam physical address (&00..size of NVRam)
Neil Turton's avatar
Neil Turton committed
1360
;
Neil Turton's avatar
Neil Turton committed
1361
; out:	R0 preserved
Neil Turton's avatar
Neil Turton committed
1362
;
Neil Turton's avatar
Neil Turton committed
1363 1364 1365
;	C=0 => NVRam address is valid
;	 R0 = physical address within i2c device
;	 R1 = i2c device address for writing. Increment this device address
Kevin Bracey's avatar
Kevin Bracey committed
1366
;	      by 1 for reading. Bit 8 is set if device requires 2-byte physical address.
Neil Turton's avatar
Neil Turton committed
1367
;
Neil Turton's avatar
Neil Turton committed
1368 1369 1370 1371 1372 1373
;	C=1 => NVRam address is out of range of CMOS or E2ROM chips
;	 R0 preserved
;	 R1 preserved

  [	E2ROMSupport
GetI2CAddress ROUT
Kevin Bracey's avatar
Kevin Bracey committed
1374 1375 1376 1377 1378
	Push	"R14"
	MOV	R14, #0			; get no 256 byte blocks and calculate end address
	LDRB	R14, [R14, #NVRamSize]
	MOV	R14, R14, LSL #8
	CMP	R0, R14
Kevin Bracey's avatar
Kevin Bracey committed
1379
	Pull	"PC",CS 		; indicate invalid
Neil Turton's avatar
Neil Turton committed
1380

Kevin Bracey's avatar
Kevin Bracey committed
1381 1382
; address is < end address -> is valid
	MOV	R1, #0
Neil Turton's avatar
Neil Turton committed
1383
	LDRB	R1, [R1, #RTCFitted]
Kevin Bracey's avatar
Kevin Bracey committed
1384 1385 1386 1387 1388 1389 1390
	TEQ	R1, #0
	MOVNE	R1, #RTCAddress
	LDREQB  R1, [R1, #NVRamBase]

        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
1391

Kevin Bracey's avatar
Kevin Bracey committed
1392 1393 1394 1395
	MOVS	R14, R0, LSR #8		; put top bits of physical address into device address
	ORRNE	R1, R1, R14, LSL #1
	ANDNE	R0, R0, #&FF		; and use address within 256 byte block
50
Kevin Bracey's avatar
Kevin Bracey committed
1396 1397
        CLC
	Pull	"PC"           		; indicate valid
Kevin Bracey's avatar
Kevin Bracey committed
1398

Neil Turton's avatar
Neil Turton committed
1399
  ]
Neil Turton's avatar
Neil Turton committed
1400 1401 1402


; *****************************************************************************
Neil Turton's avatar
Neil Turton committed
1403 1404 1405 1406 1407
;
;	MangleCMOSAddress - Convert from logical to physical address
;
;	Doesn't check if address is larger than the amount of NVRam installed
;
Kevin Bracey's avatar
Kevin Bracey committed
1408
; in:	R0 = logical address (&00...)
Neil Turton's avatar
Neil Turton committed
1409
;
Kevin Bracey's avatar
Kevin Bracey committed
1410 1411
; out:	C=0 => valid logical address
;	 R0 = physical address (&40..&FF,&10..&3F,&00..0F,&100..)
Neil Turton's avatar
Neil Turton committed
1412
;
Kevin Bracey's avatar
Kevin Bracey committed
1413
;	C=1 => invalid logical address
Neil Turton's avatar
Neil Turton committed
1414 1415
;	 R0 preserved
;
Neil Turton's avatar
Neil Turton committed
1416

Neil Turton's avatar
Neil Turton committed
1417
MangleCMOSAddress ROUT
Kevin Bracey's avatar
Kevin Bracey committed
1418 1419 1420 1421 1422 1423 1424
 [ E2ROMSupport
	Push	"R14"
	MOV	R14, #0			; read no 256 byte blocks and calculate end address
	LDRB	R14, [R14, #NVRamSize]
	MOV	R14, R14, LSL #8
	CMP	R0, R14			; if >= end address then
	Pull	"R14"
Kevin Bracey's avatar
Kevin Bracey committed
1425
        MOVCS   PC, R14 		;    invalid (exit C set)
Kevin Bracey's avatar
Kevin Bracey committed
1426 1427

	CMP	R0, #&100		; if < end address && >= &100 then
Kevin Bracey's avatar
Kevin Bracey committed
1428 1429 1430
        BLO     %FT05
        CLC
        MOV     PC, R14                 ;    valid (no mungeing)
Kevin Bracey's avatar
Kevin Bracey committed
1431
 ]
Kevin Bracey's avatar
Kevin Bracey committed
1432
05
Kevin Bracey's avatar
Kevin Bracey committed
1433 1434
	CMP	R0, #&F0		; if < &100 && >= &f0 then
        [ E2ROMSupport
Kevin Bracey's avatar
Kevin Bracey committed
1435 1436 1437 1438
        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
1439
        |
Kevin Bracey's avatar
Kevin Bracey committed
1440
        MOVCS   PC, R14                 ;    invalid
Kevin Bracey's avatar
Kevin Bracey committed
1441
        ]
Kevin Bracey's avatar
Kevin Bracey committed
1442
10
Neil Turton's avatar
Neil Turton committed
1443 1444 1445
	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
1446 1447
        CLC
        MOV     PC, R14                 ; valid
Neil Turton's avatar
Neil Turton committed
1448 1449 1450

; *****************************************************************************
;
Neil Turton's avatar
Neil Turton committed
1451 1452
;	ValChecksum - test to see if the CMOS checksum is OK
;
Kevin Bracey's avatar
Kevin Bracey committed
1453 1454 1455 1456 1457
;       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
1458
;
Neil Turton's avatar
Neil Turton committed
1459
; in:	none
Neil Turton's avatar
Neil Turton committed
1460
;
Neil Turton's avatar
Neil Turton committed
1461 1462 1463
; out:	R0 = calculated checksum
;	Z	set if checksum is valid
;	All other registers preserved
Neil Turton's avatar
Neil Turton committed
1464 1465
;

Neil Turton's avatar
Neil Turton committed
1466
  [ ChecksumCMOS
Neil Turton's avatar
Neil Turton committed
1467

1468
ValChecksum	Entry "R1-R2"
Neil Turton's avatar
Neil Turton committed
1469

Kevin Bracey's avatar
Kevin Bracey committed
1470 1471
        MOV     R0, #0
        MOV     R1, #CMOSxseed
Stewart Brodie's avatar
Stewart Brodie committed
1472
   [ E2ROMSupport
Kevin Bracey's avatar
Kevin Bracey committed
1473 1474 1475
	MOV	R2, #0			; 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
1476 1477 1478
   |
	MOV	R2, #240
   ]
Kevin Bracey's avatar
Kevin Bracey committed
1479
        BL      ChecksumBlock
Neil Turton's avatar
Neil Turton committed
1480 1481

;
Kevin Bracey's avatar
Kevin Bracey committed
1482
; R1 contains the actual checksum. Compare it with the recorded checksum
Neil Turton's avatar
Neil Turton committed
1483
;
Kevin Bracey's avatar
Kevin Bracey committed
1484 1485 1486
40
	MOV	R0, #CheckSumCMOS
	BL	Read
Neil Turton's avatar
Neil Turton committed
1487
	AND	R2, R0, #&FF		; value from checksum location
Kevin Bracey's avatar
Kevin Bracey committed
1488
	AND	R0, R1, #&FF		; calculated value into R0
Neil Turton's avatar
Neil Turton committed
1489
	CMPS	R0, R2
Neil Turton's avatar
Neil Turton committed
1490

Neil Turton's avatar
Neil Turton committed
1491 1492
	EXIT
  ]
Neil Turton's avatar
Neil Turton committed
1493 1494 1495

; *****************************************************************************
;
Neil Turton's avatar
Neil Turton committed
1496
;	MakeChecksum - calculate and write a correct checksum
Neil Turton's avatar
Neil Turton committed
1497
;
Neil Turton's avatar
Neil Turton committed
1498
; in:	none
Neil Turton's avatar
Neil Turton committed
1499
;
Neil Turton's avatar
Neil Turton committed
1500 1501
; out:	R0 = calculated checksum
;	All other registers preserved
Neil Turton's avatar
Neil Turton committed
1502 1503
;

Neil Turton's avatar
Neil Turton committed
1504
	[ ChecksumCMOS
Neil Turton's avatar
Neil Turton committed
1505

Neil Turton's avatar
Neil Turton committed
1506
MakeChecksum	ROUT
Kevin Bracey's avatar
Kevin Bracey committed
1507 1508 1509
	Push	"R1-R2,R14"
        MOV     R0, #0
        MOV     R1, #CMOSxseed
Stewart Brodie's avatar
Stewart Brodie committed
1510
  [ E2ROMSupport
Kevin Bracey's avatar
Kevin Bracey committed
1511 1512 1513
	MOV	R2, #0
	LDRB	R2, [R2, #NVRamSize]
	MOV	R2, R2, LSL #8
Stewart Brodie's avatar
Stewart Brodie committed
1514 1515 1516
  |
	MOV	R2, #240
  ]
Kevin Bracey's avatar
Kevin Bracey committed
1517
        BL      ChecksumBlock
Neil Turton's avatar
Neil Turton committed
1518 1519
	MOV	R0, #CheckSumCMOS
	BL	Write
Kevin Bracey's avatar
Kevin Bracey committed
1520
	Pull	"R1-R2,PC"
Neil Turton's avatar
Neil Turton committed
1521
	]
Neil Turton's avatar
Neil Turton committed
1522

Kevin Bracey's avatar
Kevin Bracey committed
1523 1524
        LTORG

Neil Turton's avatar
Neil Turton committed
1525 1526
; *****************************************************************************
;
Neil Turton's avatar
Neil Turton committed
1527
;	SetTime - Write the CMOS clock time and update 5-byte RealTime
Neil Turton's avatar
Neil Turton committed
1528
;
Neil Turton's avatar
Neil Turton committed
1529 1530 1531 1532 1533 1534 1535 1536 1537
; in:	UTC time:
;	R0 = hours
;	R1 = minutes
;	R2 = day of month
;	R3 = month
;	R5 = year (lo)
;	R6 = year (hi)
;	R7 = seconds
;	R8 = centiseconds
Neil Turton's avatar
Neil Turton committed
1538
;
Neil Turton's avatar
Neil Turton committed
1539
;	Any of the above, if -1, will not be written to
Neil Turton's avatar
Neil Turton committed
1540 1541 1542
;

SetTime ROUT
Neil Turton's avatar
Neil Turton committed
1543
	Push	"R4, R14"		; save registers
Neil Turton's avatar
Neil Turton committed
1544

Stewart Brodie's avatar
Stewart Brodie committed
1545
 [ E2ROMSupport
Kevin Bracey's avatar
Kevin Bracey committed
1546 1547 1548 1549 1550 1551 1552 1553 1554
	MOV	R14, #0
	LDRB	R14, [R14, #RTCFitted]

        TEQ     R14, #0
        BNE     %FT20

; no RTC - just set soft copy

        BL      RegToRealTime
Dan Ellis's avatar
Dan Ellis committed
1555

Kevin Bracey's avatar
Kevin Bracey committed
1556
        Pull    "R4, PC"
Stewart Brodie's avatar
Stewart Brodie committed
1557
 ]
Kevin Bracey's avatar
Kevin Bracey committed
1558
20
Neil Turton's avatar
Neil Turton committed
1559 1560
; write year to CMOS RAM

Neil Turton's avatar
Neil Turton committed
1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595
	MOV	R4, R0			; save hours in R4

	Push	"R1"
	MOVS	R1, R5
	MOVPL	R0, #YearCMOS
	BLPL	Write
	MOVS	R1, R6
	MOVPL	R0, #YearCMOS+1
	BLPL	Write

	CMP	R4, #-1			; are we writing time ?
	Pull	"R1",EQ			; [no, then skip]
	BEQ	%FT30

	MOV	R0, #&01		; start at address 1
    [	E2ROMSupport
	BL	GetI2CAddress		; convert to device address and offset
	MOV	R0, R1			; write address
    |
	MOV	R0, #RTCAddress
    ]
	Pull	"R1"
	BL	StartTXPollAck
	MOV	R0, #&01		; offset 1
	BL	TXAck
	MOV	R0, R8			; centiseconds
	BL	HTBTA
	MOV	R0, R7			; seconds
	BL	HTBTA
	MOV	R0, R1			; minutes
	BL	HTBTA
	MOV	R0, R4			; hours
	BL	HTBTA
	BL	Stop

Neil Turton's avatar
Neil Turton committed
1596
30
Neil Turton's avatar
Neil Turton committed
1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616
	CMP	R2, #-1			; are we writing date ?
	BEQ	%FT40			; [no, then skip]

	MOV	R0, #&05		; start at address 5
    [	E2ROMSupport
	BL	GetI2CAddress		; convert to device address and offset
	MOV	R0, R1			; write address
    |
	MOV	R0, #RTCAddress
    ]
	BL	StartTXPollAck
	MOV	R0, #&05		; offset 5
	BL	TXAck
	MOV	R0, R2			; day of month
	BL	HexToBCD
	ORR	R0, R0, R5, LSL #6	; year in bits 6,7; day in bits 0..5
	BL	TXAck
	MOV	R0, R3			; months
	BL	HTBTA
	BL	Stop
Neil Turton's avatar
Neil Turton committed
1617

Neil Turton's avatar
Neil Turton committed
1618 1619 1620
40
	MOV	R0, R4			; put hours back in R0
	BL	RTCToRealTime
Dan Ellis's avatar
Dan Ellis committed
1621

Neil Turton's avatar
Neil Turton committed
1622
	Pull	"R4, PC"
Neil Turton's avatar
Neil Turton committed
1623 1624 1625

; *****************************************************************************
;
Neil Turton's avatar
Neil Turton committed
1626
;	ReadTime - Read the CMOS clock time
Neil Turton's avatar
Neil Turton committed
1627
;
Neil Turton's avatar
Neil Turton committed
1628
; in:	-
Neil Turton's avatar
Neil Turton committed
1629
;
Neil Turton's avatar
Neil Turton committed
1630 1631 1632 1633 1634 1635 1636 1637
; out:	R0 = hours
;	R1 = minutes
;	R2 = days
;	R3 = months
;	R5 = year (lo)
;	R6 = year (hi)
;	R7 = seconds
;	R8 = centiseconds
Neil Turton's avatar
Neil Turton committed
1638 1639 1640
;

ReadTime ROUT
Neil Turton's avatar
Neil Turton committed
1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691
	Push	"R4, R14"

	MOV	R0, #&01		; start at address 1
    [	E2ROMSupport
	BL	GetI2CAddress		; convert to device address and offset
	MOV	R0, R1			; write address
    |
	MOV	R0, #RTCAddress
    ]
	BL	StartTXPollAck
	MOV	R0, #&01		; offset 1
	BL	TXAck
	BL	Start
    [	E2ROMSupport
	ADD	R0, R1, #1		; read address
    |
	MOV	R0, #(RTCAddress+1)	; read address
    ]
	BL	TXAck
	BL	RXByte
	BL	BCDToHex
	MOV	R8, R0			; centiseconds
	BL	CD0RBTH
	MOV	R7, R0			; seconds
	BL	CD0RBTH
	MOV	R1, R0			; minutes
	BL	CD0RBTH
	MOV	R4, R0			; hours
	BL	ClockData0
	BL	RXByte
	AND	R0, R0, #&3F		; day of month (clear year bits)
	BL	BCDToHex
	MOV	R2, R0
	BL	ClockData0
	BL	RXByte
	AND	R0, R0, #&1F		; month (clear day of week bits)
	BL	BCDToHex
	MOV	R3, R0
	MOV	R0, #1
	BL	ClockData
	BL	Stop

	MOV	R0, #YearCMOS
	BL	Read
	MOV	R5, R0			; year (lo)

	MOV	R0, #YearCMOS+1
	BL	Read
	MOV	R6, R0			; year (hi)

	MOV	R0, R4			; put hours in R0
Neil Turton's avatar
Neil Turton committed
1692 1693

; Ensure day/month are non-zero, fixes RTCToRealTime
Neil Turton's avatar
Neil Turton committed
1694 1695 1696 1697 1698
 [ {TRUE}				; LRust, fix RP-0370
	TEQ	R2, #0			; Valid day?
	MOVEQ	R2, #1			; No then force 1st
	TEQ	R3, #0			; Invalid month?
	MOVEQ	R3, #1			; Yes then force Jan
Neil Turton's avatar
Neil Turton committed
1699
 ]
Neil Turton's avatar
Neil Turton committed
1700
	Pull	"R4, PC"
Neil Turton's avatar
Neil Turton committed
1701 1702 1703

; *****************************************************************************
;
Neil Turton's avatar
Neil Turton committed
1704
;	InitCMOSCache - Initialise cache of CMOS RAM
Dan Ellis's avatar
Dan Ellis committed
1705 1706 1707
;  in: -
;
;  out: R0 = 0 for failure
Neil Turton's avatar
Neil Turton committed
1708

Dan Ellis's avatar
Dan Ellis committed
1709
InitCMOSCache	Entry "r1-r6, sb"
Neil Turton's avatar
Neil Turton committed
1710 1711
    [	E2ROMSupport

Kevin Bracey's avatar
Kevin Bracey committed
1712 1713
; Need to set the slowest speed so we can probe

Dan Ellis's avatar
Dan Ellis committed
1714
        LDR     R4, =ZeroPage
Kevin Bracey's avatar
Kevin Bracey committed
1715
        MOV     R3, #10         ; Default speed setting (5s delays)
Dan Ellis's avatar
Dan Ellis committed
1716
        STRB    R3, [R4, #NVRamSpeed]
Kevin Bracey's avatar
Kevin Bracey committed
1717 1718

;	First determine what hardware we've got fitted, R4 holds the number of
Neil Turton's avatar
Neil Turton committed
1719 1720
;	256 byte blocks that we've found

Dan Ellis's avatar
Dan Ellis committed
1721 1722 1723 1724
 [ HAL
        AddressHAL
    	CallHAL	HAL_NVMemoryType
    	ANDS 	R0, R0, #NVMemoryFlag_Provision
Kevin Bracey's avatar
Kevin Bracey committed
1725
        BEQ     InitCMOSCache_NoCMOS
Dan Ellis's avatar
Dan Ellis 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
    	MOV 	R5, R0

    	; If it's only a maybe, then we probe
    	TEQ 	R5, #NVMemoryFlag_MaybeIIC
    	BEQ 	%FT03

    	; Else we read the size

    	CallHAL	HAL_NVMemorySize	; returns number of bytes but..
    	MOV 	R0, R0, LSR#8	    	; .. expecting no. of 256 blocks
    	STRB 	R0, [R4, #NVRamSize]

    	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
    	TEQ 	R0, #NVMemoryFlag_IIC
    	BEQ   	%FT06

    	; Else use HAL routine.
    	MOV 	R0, #0
    	LDR 	R1, =CMOSRAMCache
    	MOV 	R2, #&100
    	CallHAL	HAL_NVMemoryRead
    	TEQ 	R0, #&100
    	MOVNE	R0, #0	    	    	; Failure exit condition
    	EXIT
03
 ]
Neil Turton's avatar
Neil Turton committed
1764 1765
	; Have we got an RTC ?
	MOV	R0, #RTCAddress
Dan Ellis's avatar
Dan Ellis committed
1766
    	LDR 	R2, =ZeroPage
Neil Turton's avatar
Neil Turton committed
1767
	BL	DummyAccess
Kevin Bracey's avatar
Kevin Bracey committed
1768 1769 1770
	MOVVS	R4, #0
	MOVVC	R4, #1
	STRB	R4, [R2, #RTCFitted]
Dan Ellis's avatar
Dan Ellis committed
1771

Robert Catherall's avatar
Robert Catherall committed
1772
        MOV     R3, #10         ; assume 100kHz to start with
Kevin Bracey's avatar
Kevin Bracey committed
1773
        MOV     R5, #4          ; assume 16 byte page size to start with
1774
        MOV     R6, #0          ; assume not protected
Kevin Bracey's avatar
Kevin Bracey committed
1775 1776 1777 1778 1779 1780 1781 1782

; Have we got a 2K E ?
        MOV     r1, #E2ROMAddress2K
	MOV	r0, #(E2ROMAddress2K+14)
	BL	DummyAccess
	MOVVC	R4, #8
        MOVVC   R3, #3          ; Fast speed setting (1.5s delays)
	BVC	%FT5
Neil Turton's avatar
Neil Turton committed
1783 1784

; Have we got a 1K E ?
Kevin Bracey's avatar
Kevin Bracey committed
1785
        MOV     r1, #E2ROMAddress
Neil Turton's avatar
Neil Turton committed
1786 1787
	MOV	r0, #(E2ROMAddress+6)
	BL	DummyAccess
Kevin Bracey's avatar
Kevin Bracey committed
1788
	MOVVC	R4, #4
Neil Turton's avatar
Neil Turton committed
1789 1790 1791 1792 1793
	BVC	%FT5

; Have we got 512 bytes of E ?
	MOV	r0, #(E2ROMAddress+2)
	BL	DummyAccess
Kevin Bracey's avatar
Kevin Bracey committed
1794
	MOVVC	R4, #2
Neil Turton's avatar
Neil Turton committed
1795 1796
	BVC	%FT5

Kevin Bracey's avatar
Kevin Bracey committed
1797 1798 1799
; Have we got a 16K device ? (Note that this probe would make a 24C08 device respond -
; but if we've gotten this far it would have to be a < 512 byte version; we've never
; used such a device).
Neil Turton's avatar
Neil Turton committed
1800

Kevin Bracey's avatar
Kevin Bracey committed
1801 1802 1803 1804 1805 1806
        MOV     r1, #E2ROMAddress16K
	MOV	r0, #E2ROMAddress16K
	BL	DummyAccess
	MOVVC	R4, #64
        MOVVC   R5, #6          ; 64 byte page size
        MOVVC   R3, #3          ; Fast speed setting (1.5s delays)
1807 1808
        BVC     %FT5

1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819
; Have we got a 4K device?

        MOV     r1, #E2ROMAddress4K
	MOV	r0, #E2ROMAddress4K
	BL	DummyAccess
	MOVVC	R4, #16
        MOVVC   R6, #12         ; Only bottom 3K writable
        MOVVC   R5, #5          ; 32 byte page size
        MOVVC   R3, #3          ; Fast speed setting (1.5s delays)
        BVC     %FT5

1820 1821 1822 1823 1824 1825
; Have we got an 8K device?

        MOV     r1, #E2ROMAddress8K
	MOV	r0, #E2ROMAddress8K
	BL	DummyAccess
	MOVVC	R4, #32
1826
        MOVVC   R6, #24         ; Only bottom 6K writable
1827 1828
        MOVVC   R5, #5          ; 32 byte page size
        MOVVC   R3, #3          ; Fast speed setting (1.5s delays)
Robert Catherall's avatar
Robert Catherall committed
1829 1830 1831
        BVC     %FT5

; Have we got a 32K device?
1832

Robert Catherall's avatar
Robert Catherall committed
1833 1834 1835 1836 1837 1838 1839
        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)
Dan Ellis's avatar
Dan Ellis committed
1840
    	BVC 	%FT5
Robert Catherall's avatar
Robert Catherall committed
1841 1842

        MOVVS   R1, #RTCAddress
Dan Ellis's avatar
Dan Ellis committed
1843 1844 1845 1846 1847 1848
        MOVVS   R0, #RTCAddress
    	BL  	DummyAccess
        MOV     R5, #8          ; 256 byte page size for CMOS
    	BVC 	%FT5

; We ain't got anything!
Kevin Bracey's avatar
Kevin Bracey committed
1849 1850 1851 1852 1853 1854 1855
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]
Dan Ellis's avatar
Dan Ellis committed
1856 1857
    	MOV 	R0, #0	    	; Exit failure
    	EXIT
Kevin Bracey's avatar
Kevin Bracey committed
1858 1859

5
Neil Turton's avatar
Neil Turton committed
1860
	; Set the NVRam count
Kevin Bracey's avatar
Kevin Bracey committed
1861 1862 1863
	STRB    R1, [R2, #NVRamBase]
	STRB	R4, [R2, #NVRamSize]
        STRB    R5, [R2, #NVRamPageSize]
1864 1865 1866
        TEQ     R6, #0
        MOVEQ   R6, R4
        STRB    R6, [R2, #NVRamWriteSize]
Robert Catherall's avatar
Robert Catherall committed
1867 1868 1869

        CMP     R3, #I2Cticks   ; clamp speed to maximum bus speed
        MOVLO   R3, #I2Cticks
Kevin Bracey's avatar
Kevin Bracey committed
1870
        STRB    R3, [R2, #NVRamSpeed]
Dan Ellis's avatar
Dan Ellis committed
1871 1872
06
	; Initialise the cache
Kevin Bracey's avatar
Kevin Bracey committed
1873
	LDR	R3, =CMOSRAMCache
Neil Turton's avatar
Neil Turton committed
1874

Kevin Bracey's avatar
Kevin Bracey committed
1875 1876 1877 1878 1879 1880 1881 1882 1883
        TEQ     R4, #8                  ; check for 2K part
	MOVNE	r0, #&00		; if not, then start at 0 anyway and read non-OTP data into location 0..15
        BNE     %FT07
	BL	ReadOTPArea
	MOV	r0, #&10		; read rest of it from 16 onwards
07
        BL      GetI2CAddress           ; and convert to device address and offset
        MOV     R2, R0                  ; save the offset
        MOV     R4, #&100               ; stop at &100
Neil Turton's avatar
Neil Turton committed
1884 1885 1886
    |
	MOV	R1, #RTCAddress
	MOV	R2, #&10
Kevin Bracey's avatar
Kevin Bracey committed
1887 1888
	MOV	R4, #&100		; stop at address &100
	LDR	R3, =CMOSRAMCache
Neil Turton's avatar
Neil Turton committed
1889
    ]
Kevin Bracey's avatar
Kevin Bracey committed
1890
09
Neil Turton's avatar
Neil Turton committed
1891
	BL	Start
Neil Turton's avatar
Neil Turton committed
1892

Neil Turton's avatar
Neil Turton committed
1893 1894
	MOV	R0, R1			; write address
	BL	TXAck
Neil Turton's avatar
Neil Turton committed
1895

Kevin Bracey's avatar
Kevin Bracey committed
1896 1897 1898 1899 1900
        TST     R1, #&100               ; 2-byte address?
        MOVNE   R0, R2, LSR #8          ; memory word address (MSB)
        BLNE    TXAck

	AND	R0, R2, #&FF		; memory word address (LSB)
Neil Turton's avatar
Neil Turton committed
1901
	BL	TXAck
Neil Turton's avatar
Neil Turton committed
1902

Neil Turton's avatar
Neil Turton committed
1903
	BL	Start
Neil Turton's avatar
Neil Turton committed
1904

Kevin Bracey's avatar
Kevin Bracey committed
1905
	ORR	R0, R1, #1		; read address
Neil Turton's avatar
Neil Turton committed
1906
	BL	TXAck
Neil Turton's avatar
Neil Turton committed
1907 1908

10
Neil Turton's avatar
Neil Turton committed
1909 1910 1911
	BL	RXByte			; returned in R0
	STRB	R0, [R3, R2]
	ADD	R2, R2, #1		; increment R2 to phys. address
Kevin Bracey's avatar
Kevin Bracey committed
1912 1913
	CMP	R2, R4			; stop when we hit end address
	BGE	%FT20
Neil Turton's avatar
Neil Turton committed
1914

Kevin Bracey's avatar
Kevin Bracey committed
1915 1916 1917
	TST	R2, #&FF		; still in same 256 byte block?
	MOVNE	R0, #0			; yes => not done .. ACK that byte
	MOVEQ	R0, #1			; no => finish off reading block
Neil Turton's avatar
Neil Turton committed
1918
	BL	ClockData
Kevin Bracey's avatar
Kevin Bracey committed
1919 1920 1921 1922 1923 1924 1925 1926
	BNE	%BT10			; yes => continue reading

   [ E2ROMSupport
	BL	Stop
	MOV	R0, R2			; in next 256 byte block so get device + address
	BL	GetI2CAddress
	B	%BT09			; and start next block
   ]
Neil Turton's avatar
Neil Turton committed
1927
20
Neil Turton's avatar
Neil Turton committed
1928 1929 1930
	MOV	R0, #1			; finish off reading block
	BL	ClockData
	BL	Stop
Kevin Bracey's avatar
Kevin Bracey committed
1931 1932 1933

   [ E2ROMSupport
        TEQ     R4, #&100               ; have we reached the end?
Dan Ellis's avatar
Dan Ellis committed
1934
    	MOV 	R0, #1	    	    	; ensure exit success
Kevin Bracey's avatar
Kevin Bracey committed
1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966
        EXIT    EQ                      ; exit if so

        MOV     R0, R4                  ; start next block from R4
        MOV     R4, #&100               ; stop at &100
        BL      GetI2CAddress           ; convert to device address and offset
        MOV     R2, R0                  ; save the offset
        B       %BT09                   ; and go round again
   |
	EXIT
   ]

   [ E2ROMSupport
ReadOTPArea Entry
	BL	Start
	MOV	r0, #E2ROMAddress2K_OTP
	BL	TXAck
	MOV	r0, #0				; OTP memory word address
	BL	TXAck
	BL	Start
	MOV	r0, #E2ROMAddress2K_OTP + 1	; switch to read
	BL	TXAck
	MOV	r2, #0
10
	BL	RXByte
	STRB	r0, [r3, r2]
	ADD	r2, r2, #1
	TEQ	r2, #16
	MOVNE	r0, #0				; not done, so clock zero
	MOVEQ	r0, #1
	BL	ClockData
	BNE	%BT10
	BL	Stop
Neil Turton's avatar
Neil Turton committed
1967
	EXIT
Kevin Bracey's avatar
Kevin Bracey committed
1968
   ]
Neil Turton's avatar
Neil Turton committed
1969

Neil Turton's avatar
Neil Turton committed
1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983
; *****************************************************************************
;
;	DummyAccess - do a dummy access of the specified device to find out
;	              if it is present
;
; in:	R0 = Write address of device
;
; out:	All registers preserved
;	V=0 => device is present
;	V=1 => device is not present

; Have we got an RTC ? do a read from location 0 to find out

  [ E2ROMSupport
1984
DummyAccess	Entry
Neil Turton's avatar
Neil Turton committed
1985 1986 1987 1988 1989 1990 1991

	BL	Start
	BL	TXAck			; do write and set V if no ack
	BL	Stop			; Doesn't change the PSR
	EXIT				; Exit with V set appropriately
  ]

Kevin Bracey's avatar
Kevin Bracey committed
1992 1993 1994 1995 1996 1997 1998
; *****************************************************************************
;
;       SWI OS_NVMemory
;
; in:   R0 = reason code
;

1999
NVMemorySWI     Entry
Kevin Bracey's avatar
Kevin Bracey committed
2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021
        BL      NVMemorySub
        PullEnv
        ORRVS   LR, LR, #V_bit
        ExitSWIHandler

NVMemorySub
        CMP     R0, #4
        ADDLS   PC, PC, R0, LSL #2
        B       NVMemory_Unknown
        B       NVMemory_Size
        B       NVMemory_Read
        B       NVMemory_Write
        B       NVMemory_ReadBlock
        B       NVMemory_WriteBlock

NVMemory_Unknown
        ADRL    R0, ErrorBlock_HeapBadReason
 [ International
        Push    LR
        BL      TranslateError
        Pull    LR
 ]
Kevin Bracey's avatar
Kevin Bracey committed
2022
        RETURNVS
Kevin Bracey's avatar
Kevin Bracey committed
2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037

; -----------------------------------------------------------------------------
; OS_NVMemory 0 - find NV memory size
;
; in:   R0 = 0
;
; out:  R1 = NV memory size in bytes
;
NVMemory_Size
  [     E2ROMSupport
        LDRB    R1, [R0, #NVRamSize]
        MOV     R1, R1, LSL #8
  |
        MOV     R1, #240
  ]
Kevin Bracey's avatar
Kevin Bracey committed
2038
        MOV     PC, LR
Kevin Bracey's avatar
Kevin Bracey committed
2039 2040 2041 2042 2043 2044 2045 2046 2047 2048

; -----------------------------------------------------------------------------
; OS_NVMemory 1 - read a byte
;
; in:   R0 = 1
;       R1 = location
;
; out:  R2 = value
;
NVMemory_Read
2049 2050
        Entry   "R4"
        MRS     R4, CPSR
Kevin Bracey's avatar
Kevin Bracey committed
2051
        BIC     R0, R4, #I32_bit
2052
        MSR     CPSR_c, R0      ; enable interrupts - this may take some time
Kevin Bracey's avatar
Kevin Bracey committed
2053 2054 2055 2056 2057
        MOV     R0, R1
        BL      ReadWithError
        MOVVC   R2, R0
        MOVVC   R0, #1          ; must preserve R0
        ORRVS   R4, R4, #V_bit
2058
        MSR     CPSR_cf, R4     ; restore interrupt state
Kevin Bracey's avatar
Kevin Bracey committed
2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072
        EXIT

; -----------------------------------------------------------------------------
; OS_NVMemory 2 - write a byte
;
; in:   R0 = 1
;       R1 = location
;       R2 = value
;
NVMemory_Write ROUT
        [ ProtectStationID
        TEQ     R1, #0          ; just ignore writes to byte 0
        MOVEQ   PC, R14
        ]
2073 2074
        Entry   "R1,R4"
        MRS     R4, CPSR
Kevin Bracey's avatar
Kevin Bracey committed
2075
        BIC     R0, R4, #I32_bit
2076
        MSR     CPSR_c, R0      ; enable interrupts - this may take some time
Kevin Bracey's avatar
Kevin Bracey committed
2077 2078 2079 2080 2081
        MOV     R0, R1
        MOV     R1, R2
        BL      WriteWithError
        MOVVC   R0, #2          ; must preserve R0
        ORRVS   R4, R4, #V_bit
2082
        MSR     CPSR_cf, R4     ; restore interrupt state
Kevin Bracey's avatar
Kevin Bracey committed
2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093
        EXIT

; -----------------------------------------------------------------------------
; OS_NVMemory 3 - read a block
;
; in:   R0 = 3
;       R1 = location
;       R2 = buffer
;       R3 = length
;
NVMemory_ReadBlock
2094
        Entry   "R1-R4"
Kevin Bracey's avatar
Kevin Bracey committed
2095
        MOV     R4, PC
2096
        MRS     R4, CPSR
Kevin Bracey's avatar
Kevin Bracey committed
2097
        BIC     R0, R4, #I32_bit
2098
        MSR     CPSR_c, R0      ; enable interrupts - this may take some time
Kevin Bracey's avatar
Kevin Bracey committed
2099 2100 2101 2102 2103 2104
        MOV     R0, R1
        MOV     R1, R2
        MOV     R2, R3
        BL      ReadBlock
        MOVVC   R0, #3          ; must preserve R0
        ORRVS   R4, R4, #V_bit
2105
        MSR     CPSR_cf, R4     ; restore interrupt state
Kevin Bracey's avatar
Kevin Bracey committed
2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116
        EXIT

; -----------------------------------------------------------------------------
; OS_NVMemory 4 - write a block
;
; in:   R0 = 3
;       R1 = location
;       R2 = buffer
;       R3 = length
;
NVMemory_WriteBlock ROUT
2117 2118
        Entry   "R1-R4"
        MRS     R4, CPSR
Kevin Bracey's avatar
Kevin Bracey committed
2119
        BIC     R0, R4, #I32_bit
2120
        MSR     CPSR_c, R0      ; enable interrupts - this may take some time
Kevin Bracey's avatar
Kevin Bracey committed
2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134
        [ ProtectStationID
        TEQ     R1, #0
        BNE     %FT10
        ADD     R1, R1, #1
        ADD     R2, R2, #1
        TEQ     R3, #0
        SUBNE   R3, R3, #1      ; steer clear of station ID
        ]
10      MOV     R0, R1
        MOV     R1, R2
        MOV     R2, R3
        BL      WriteBlock
        MOVVC   R0, #4          ; must preserve R0
        ORRVS   R4, R4, #V_bit
2135
        MSR     CPSR_cf, R4     ; restore interrupt state
Kevin Bracey's avatar
Kevin Bracey committed
2136 2137
        EXIT

Neil Turton's avatar
Neil Turton committed
2138
	END