1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
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
327
328
329
330
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
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
;> MEM4H_SCR
;
; RISC OS 2+ BOOT TEST SOFTWARE.
; MEMORY TEST 4 VERSION H. BRIAN RICE 12-01-90.
; 04-Apr-90 ArtG 0.1 Added ts_count_cams, improved reporting
; 11-Apr-90 ArtG 0.2 Use RISC OS routine BangCams for
; alternate MEMC configurations.
; 17-Apr-90 ArtG 0.3 rationalise page-counting code
;
; This file will be called by MEM6x_SCR for the purposes of assembly.
; This file will perform quick walking bit test on the CAM Entry points.
; The test code for this test was taken from the A680 test code.
;
; The module requires the running of the memory sizing routine used by
; the OS to set up the page size for this module.
;
; This test module was designed to operate on all current and future
; machines. The module is designed to handle up to 512 physical pages
; which is the maximum number of pages in a 16 MByte FOX.
;
; A 16 MB FOX has 4 MEMCs in use, each MEMC is addressed by Bits 7 and
; 12 of the logical to physical address translator. The use of bit 12
; does have a problem in that on machines with 0.5MB of memory this is
; used to define the logical page number. Machine with 1MB or greater bit
; 12 is not used, therefore this test may hit problems on A305's. The
; intention is that A305 owners will upgrade to A310's when upgrading to
; RISC OS 2+.
;
; Because FOX can have up to 4 MEMCs fitted the following addressing is
; used to determine the MEMC accessed, bit 12, bit 7
; 0 0 = Master MEMC = MEMC 0
; 0 1 = Slave MEMC 1 = MEMC 1
; 1 0 = Slave MEMC 2 = MEMC 2
; 1 1 = Slave MEMC 3 = MEMC 3
;
;
; This test will initialise the CAM entries for up to 512 physical pages.
; The physical pages will be mapped to logical page 5. Each page will have
; a copy of test routine vectors and a page marker. The page marker consists
; of the page number and a code to indicate which MEMC was used. The code for
; the MEMC used is as follows :- MEMC 0 0001 1110 = &1E
; MEMC 1 0010 1101 = &2D
; MEMC 2 0100 1011 = &4B
; MEMC 3 1000 0111 = &87
;
; The page marker is arranged as follows &mm5Apppp
; | |
; | \-- Page Number &0000 ‰ &01FF.
; \--------MEMC Code as above.
;
; The patterns are chosen so that if two or more MEMCs are accessed
; together and both RAM outputs get enabled onto the data bus simultaneously,
; then there is a reasonable chance that the data returned will show the
; presence of a fault.
;
; When the CAM entries have been initialised the module will then check that
; all the pages are mapped correctly. A simple walking one pattern is used
; to check that the page is not present anywhere else in the memory area.
; This isn't really sufficient, but keeps the test time low.
;
; The tests are performed with the memory protection level set to 0.
;
; This version uses the "my abort" routine in MEM5x_SCR instead of the
; ts_dab_exp0 .. 5 method as taken from the A680 code.
;
ts_rst_msg = "RST",0
ts_uni_msg = "UDF",0
ts_swi_msg = "SWI",0
ts_pab_msg = "PAB",0
ts_dab_msg = "DAB",0
ts_aex_msg = "ADX",0
ts_irq_msg = "IRQ",0
ts_fiq_msg = "FIQ",0
ts_bxc_msg = &85,"@",&88,&ff,&ff,&ff,&ff,&ff,&ff,&ff,&ff,0
ALIGN
ts_rst ; Unused exception vectors
ADR r4, ts_rst_msg
B ts_bad_exception
ts_uni
ADR r4, ts_uni_msg
B ts_bad_exception
ts_swi
ADR r4, ts_swi_msg
B ts_bad_exception
ts_pab
ADR r4, ts_pab_msg
B ts_bad_exception
ts_dab_unexp
ADR r4, ts_dab_msg
B ts_bad_exception
ts_aex
ADR r4, ts_aex_msg
B ts_bad_exception
ts_irq
ADR r4, ts_irq_msg
B ts_bad_exception
ts_fiq
ADR r4, ts_fiq_msg
B ts_bad_exception
ts_bad_exception
SUBS r8, r14, #8 ; remember aborted instruction
BL ts_SendText
ADR r4, ts_bxc_msg ; display aborted address
BL ts_MoreText
B Reset
;
ts_rom_base * ROM ; Base address of the OS ROMS.
ts_phys_mem * (32*1024*1024) ; Physical Memory area.
ts_pagemark * &005A0000 ; + phys page number + MEMC code.
ts_pmark_pos * 32 ; Position of page mark (avoiding vectors).
ts_cam_base * &3800000 ; Base address of the CAM table in MEMC.
ts_vrest * &5 ; Unused page which all pages are mapped to.
ts_MAX_CAMS * 512 ; Most CAMs ever expected
ts_memc_codes = &1E, &2D, &4B, &87 ; List of the memc_codes to be used.
;
ts_logpages ; List of Logical pages.
& &0001
& &0002
& &0004
& &0008
& &0010
& &0020
& &0040
& &0080
& &0100
& &0200
& &03FF
& &03FE
& &03FD
& &03FB
& &03F7
& &03EF
& &03DF
& &03BF
& &037F
& &02FF
& &01FF
& &0000 ; Terminator for the list.
ts_logpagesend ; End of the list.
;
;
; Exception vectors : copied to start of each page to ensure that they will always
; exist on page zero when arbitrary pages are mapped there.
;
ts_vectors
B (ts_vectors-ts_start)+ts_rom_base+ts_rst
B (ts_vectors-ts_start)+ts_rom_base+ts_uni
B (ts_vectors-ts_start)+ts_rom_base+ts_swi
B (ts_vectors-ts_start)+ts_rom_base+ts_pab
ts_dab_vector
B (ts_vectors-ts_start)+ts_rom_base+ts_dab
B (ts_vectors-ts_start)+ts_rom_base+ts_aex
B (ts_vectors-ts_start)+ts_rom_base+ts_irq
B (ts_vectors-ts_start)+ts_rom_base+ts_fiq
; ***************************************************************************
;
ts_CAM
;
; CAM test (full or partial)
; Start of the CAM test, all physical pages have a copy of the vectors
; so they may be mapped as page 0. Then each page is mapped at a series
; of (walking 1, walking 0) logical pages and tested to be correctly
; mapped. Other pages are set to an unused logical page by set_cam_idle
; to prevent any CAM clashes.
;
; Copy the test vectors and page marker into all the pages.
;
ROUT ; Local Branches.
MOV r13, lr ; Preserve link register in r13.
BL ts_count_CAMs ; get log2 pagesize
MOV r0, #ts_MAX_CAMS ; r0 = last page to test
SUB r0, r0, #1
0 BL ts_copy_vectors ; Gosub ts_vectors.
SUBS r0, r0, #&01 ; bump down to next page
BGE %B0 ; repeatuntil all pages set.
;
; 'C' pseudocode for the test routine.
;
; for (i = &1ff; i >= 0; i--)
; set_cam_idle(i);
;
; find maximum page number.
; if (max_page != ts_count_CAMS)
; report CAM number error
;
; for (phys = &max_page; phys >= 0; phys--) {
; for (logp = &logpages[0]; logp < &logpages[sizof(logpages)]; logp++) {
; if (*logp == 0) {
; set_cam(*logp, phys);
; check_mapped(*logp, phys);
; } else {
; int zphys = (phys + 1) % num_pages;
; set_cam(0, zphys);
; set_cam(*logp, phys);
; check_mapped(*logp, phys);
; set_cam_idle(zphys);
; }
; }
; set_cam_idle(phys);
; }
;
; Idle the pages.
;
ROUT ; Local Branches.
MOV r12, #ts_MAX_CAMS ; always clear all 512 - just in case 4 MEMCs.
SUB r12, r12, #&01 ; Subtract 1 to make max page #.
0 MOV r1, r12 ; r1 = page number.
BL ts_set_cam_idle
SUBS r12, r12, #&01 ; bump to next page downwards
BGE %B0 ; repeatuntil page 0 done
;
; We need to find out what the maximum number of pages is, after running the above routine
; all the pages will have the pagemark programed in to each page. As stated in the intro
; programing the pages from the top down will ensure that, irrespective of the number of
; MEMCs available, that the bottom pages are programed correctly. Therefore if we start
; at the top, read in a page, check it's page number & memc code are correct, if so then
; that is possibly the maximum page number. If not then subtract 1 from the page number and
; try again until a possible good page is found.
;
ROUT ; Local Branches.
BL ts_count_CAMs ; get log2 pagesize to r1
MOV r8, #ts_MAX_CAMS ; r8= max. number of physical pages.
0 SUBS r8, r8, #&01 ; Subtract 1 to make it r8 - 1 Pages.
BEQ ts_bad_CAM_count ; no pages ? - shouldn't hit this!
;
; Calculate the expected page marker, in r4, for the current page, in r8.
;
ADR r4, ts_memc_codes ; r4 = address of table with the memc codes.
LDRB r4, [r4, r8, LSR#7] ; r4 = Loc pointed to by r4 + (r1 >> 7).
ORR r4, r8, r4, LSL #24 ; r4 = page number OR (MEMC code << 24).
ORR r4, r4, #ts_pagemark ; r4 = page id OR magic number
;
; The calculated page marker is now in r4, ref_p_mark.
; Current page in r8 - convert to physical address in r9.
; the pagesize power-of-2 is in r1 (from ts_count_CAMs)
;
MOV r9, r8, LSL r1 ; convert PPN to phys offset
ORR r9, r9, #ts_phys_mem ; add offset to start of phys mem
;
; r9 now has the address of the current page - read the page marker for that page.
;
LDR r9, [r9, #ts_pmark_pos] ; r9 = contents of loc pointed to by
; r9 + ts_pmark_pos.
;
; Check that read_p_mark is valid.
;
; Either the value read is the expected pagemark, junk (no memory) or an
; aliased pagemark - if it's aliased, then either the memory or the MEMC
; isn't decoded that far.
; Bump down and try a bit lower, until it's OK.
;
CMP r4, r9 ; Is page-mark expected value ?
BNE %B0
;
; Found a pagemarker in the proper place. Check that the number of pages that
; appear to be present are the same as the number found by ts_count_CAMs
; (i.e. the memory size / page size).
;
SUB r0, r0, #1 ; convert count -> max page number
CMPS r0, r8
BNE ts_bad_CAM_count
;
; If all is well, we should have the maximum usable page number in r8.
;
; Need to reset page 0 in the CAM entries, currently all pages are mapped to page 5.
; We need to have logical page 0 mapped to physical page 0.
;
MOV r0, #&00 ; r0 = &00, the page to map.
MOV r1, #&00 ; r1 = &00, the page to map to.
MOV r2, #&00 ; r2 = &00, set the protection level.
BL ts_set_camp
;
; Check we can still see the data abort vector at physical page zero
; - no good continuing if we can't.
;
MOV r0, #ts_phys_mem
LDR r0, [r0, #(ts_dab_vector - ts_vectors)]
LDR r1, ts_dab_vector
CMPS r0, r1
BNE ts_bad_dab_vector
;
; Now lets get on with the testing.
;
2 ADRL r10, ts_logpages ; logp = &logpages[0]
3 LDR r0, [r10] ; r0 = page to test
CMP r0, #&00 ; last entry ?
BNE %F4
MOV r1, r8 ; r1 = r8, page under test
BL ts_set_cam ; Gosub ts_set_cam.
LDR r0, [r10] ; r0 current logical test page
MOV r1, r8 ; r1 = current test page
BL ts_check_mapped ; Gosub ts_check_mapped.
B %F5
4 ADD r12, r8, #&01
BL ts_count_CAMs ; get total number of pages
SUB r0,r0,#1 ; make a mask for useable page
AND r0,r0,#&7f ; numbers - min(128, num_pages)
AND r12, r12, r0 ; r12 -> (r12 + 1) masked
MOV r0, #&00 ; to useable page numbers.
MOV r1, r12
BL ts_set_cam ; Setup a page for vectors
LDR r0, [r10] ; r0 = current logical test page.
MOV r1, r8 ; r1 = current physical test page.
BL ts_set_cam ; Setup a page to test
LDR r0, [r10] ; look up logical page again.
MOV r1, r8 ; recall physical page.
BL ts_check_mapped ; check the ts_set_cam worked.
MOV r1, r12 ; unmap the vector page
BL ts_set_cam_idle
5 ADD r10, r10, #&04 ; next entry in test list.
ADRL r0, ts_logpagesend ; r0 = ts_logpagesend.
CMP r10, r0 ; repeat until list of logical
BLO %B3 ; pages all done.
MOV r1, r8 ; unmap the page we just tested
BL ts_set_cam_idle
SUBS r8, r8, #1 ; bump phys page counter down.
ANDS r8,r8,r8
BGE %B2 ; If r8 >= 0 Then branch back to 2.
ANDS r0,r0,#0
MOV pc,r13 ; all done and passed
;
; ****************************************************************************
;
ts_copy_vectors
;
; Copies the vectors to the physical page in r0 (preserved) also copies
; pagemark + phypage.
; Expects r1 (preserved) to hold log2 of pagesize
;
ROUT ; Local Branches.
ADR r2, ts_vectors ; r2 = source address
LDMIA r2, {r4-r11} ; r4 - r11 = loc pointed to by r2, post inc.
MOV r3, r0, LSL r1 ; r3 = r0 * 2**r1 .
ORR r3, r3, #ts_phys_mem ; r3 = r3 OR ts_phys_mem.
STMIA r3, {r4-r11} ; loc pointed to by r3, post inc = r4 to r11.
;
; find out which memc is handling the page (r0), then assign the appropiate memc_code.
; Add in the page number and pagemark, then store into the required position in the
; page in question.
;
ADR r2, ts_memc_codes ; r2 = address of table with the memc codes.
LDRB r2, [r2, r0, LSR#7] ; r2 = memc code for this phys page.
ORR r2, r0, r2, LSL #24 ; OR in phys page number.
ORR r2, r2, #ts_pagemark ; OR in pagemark.
STR r2, [r3, #ts_pmark_pos] ; loc pointed to by r1 + ts_pmark_pos = pagemark.
MOV pc, lr ; Return to caller.
;
; ****************************************************************************
;
ts_set_cam_idle
;
; This module will program the physical page (r1) to the logical page 5, ts_vrest and
; continue onto the next section ts_set_cam.
;
ROUT ; Local Branches.
MOV r0, #ts_vrest ; r0 = ts_vrest, = unused logical page.
;
; ****************************************************************************
;
ts_set_cam
;
; This module will program the physical page (r1) to the logical page (r0) at
; protection mode 0 and continue onto the next section ts_set_camp.
;
MOV r2, #&00 ; r2 = &00, memory prot level 0.
;
; ****************************************************************************
;
ts_set_camp
;
; This module will map a range the physical pages (r1) to the logical page (r0) and
; set the protection mode (r2). This module will return to the location from where
; either itself or ts_set_cam or ts_set_cam_idle were called from.
;
; Corrupts r0,r1,r2,r3,r4,r6,r9,r11
;
; Calls the RISC OS routine BangCam to do the PPNO, LPNO bit switching.
; First, jumble the registers to suit BangCam ..
;
; r2 = CAM entry (PPNO)
; r3 = logical address
; r9 = current MEMC setting (for pagesize)
; r11 = PPL
;
MOV r3,r0 ; logical page number
MOV r11,r2 ; protection level
MOV r2,r1 ; physical page number
MOV_fiq r0, r11_fiq ; MEMC configuration
MOV r9, r0 ; keep a copy in r9
MOV r1, r9, LSR #2
AND r1, r1, #3 ; calculate pagesize shift
ADD r1, r1, #12
MOV r3, r3, LSL r1 ; convert LPN to logaddr
B BangCam ; return thro' BangCam
;
; ****************************************************************************
;
ts_check_mapped
;
; This routine will check that the CAM has been programed correctly and that the required
; page is responding when asked. A quick test is made to check that other pages are not
; responding as well.
;
; logical page in r0,
; physical page in r1,
; test that they are the same.
;
; No return value : reports faults directly and returns thro' r13
;
; Uses (corrupts) r0,r1,r2,r3,r4,r5,r6,r7
;
; Find out which memc is handling the page (r1), then assign the appropiate memc_code.
; Add in the page number and pagemark, then compare that pagemark with those found
; in memory at the expected logical and physical addresses.
;
; This code assumes that any system with multiple MEMCs will always have 32K pages.
;
ROUT ; Local Branches.
MOV r3, r0 ; save the current logical pagenumber.
MOV r5, lr ; Preserve link register in case of Abort.
ADR r2, ts_memc_codes ; r2 = address of table with the memc codes.
LDRB r2, [r2, r1, LSR#7] ; fetch the memc code for this page.
ORR r2, r1, r2, LSL #24 ; build the page number into the pagemark
ORR r2, r2, #ts_pagemark ; build in the pagemark magic number
;
; r2 should now have the page_mark for the current page (r1).
; calculate the shift to convert page number to memory offset.
;
MODE FIQ_mode
MOV r4, r11_fiq, LSR #2 ; pagesize / 4K
MODE SVC_mode
AND r4, r4, #3
ADD r4, r4, #12
;
; if the mapping failed completely, the test might abort
;
MOV r6, #&00 ; r6 = &00, clear expected abort flag.
MOV r7, #&94 ; r7 = &94, set abort expected flag.
;
; make the pointers and test the contents
;
MOV r0, r0, LSL r4 ; r0 = LPN * pagesize.
LDR r0, [r0, #ts_pmark_pos] ; r0 = contents of loc in r0 + ts_pmark_pos.
CMP r6, #94 ; did that fetch abort ?
ADREQ r4, %F14 ; mapping totally failed
BEQ ts_CAM_fail
MOV r1, r1, LSL r4 ; r1 = PPN * pagesize.
ORR r1, r1, #ts_phys_mem ; r1 = r1 ORed with ts_phys_mem.
LDR r1, [r1, #ts_pmark_pos] ; r1 = contents of loc in r1 + ts_pmark_pos.
CMP r0, r1 ; Are the read pagemarks equal ??
ADRNE r4, %F10
BNE ts_CAM_fail ; Failed : mapping not equal.
CMP r0, r2 ;
ADRNE r4, %F11
BNE ts_CAM_fail ; Failed : map equal, but corrupt
;
; test that the page doesn't exist anywhere else
;
MOV r2, #1
0 EOR r0, r2, r3 ; Flip a (walking) bit in the LPN.
CMP r0, #ts_vrest ; Is r0 = ts_vrest ?? Where all the pages are
; mapped to.
BEQ %F1 ; If r0 = ts_vrest then branch forward to 1.
;
; The following instruction should abort.
;
MOV r0, r0, LSL r4 ; r0 = LPN * pagesize.
MOV r6, #&00 ; r6 = &00, clear abort handled flag.
MOV r7, #&94 ; r7 = &94, set abort expected flag.
LDR r0, [r0, #ts_pmark_pos] ; get a possible pagemark from this page.
CMP r6, #&94 ; Did we go thro' the abort handler ?
BEQ %F1 ; If equal then an abort happened, good !
;
; Not aborted - is it page zero, where the vectors live ?
;
TEQS r2, r3
BEQ %F1 ; yes - that SHOULDN'T abort
;
; Fault - is the page mapped there the same as our test page ?
;
CMP r0, r1
ADREQ r4, %F12 ; Failed : phys page also mapped here
ADRNE r4, %F13 ; Failed : page not unmapped
EOR r3, r2, r3 ; remake the duff LPN for the error display
B ts_CAM_fail
; If equal then no abort happened, not good !!
1 MOV r2, r2, LSL#1 ; bump to next-bit-set page number
CMP r2, #(ts_MAX_CAMS :SHL: 1) ; Hit number of logical pages ?
BLT %B0 ; If r2 < maximum number then loop again.
MOV r7, #0 ; no longer expecting aborts
MOV pc, r5 ; Return to caller.
;
; Indicate that CAM mapping test failed (PPN is not at LPN)
; Display r8, the physical page number and r3, the logical page.
;
; ***This error exit returns to the CALLER of check_mapped, thro' r13***
;
10
= "CAM map",&88,&ff,&ff,&ff,".",&ff,&ff,&ff,&ff,0
11
= "CAM pmk",&88,&ff,&ff,&ff,".",&ff,&ff,&ff,&ff,0
12
= "CAM als",&88,&ff,&ff,&ff,".",&ff,&ff,&ff,&ff,0
13
= "CAM unm",&88,&ff,&ff,&ff,".",&ff,&ff,&ff,&ff,0
14
= "CAM abo",&88,&ff,&ff,&ff,".",&ff,&ff,&ff,&ff,0
ALIGN
ts_CAM_fail
MOV r0, r8, LSL #16 ; physical page #
LDR r1, =&ffff
AND r1, r1, r3
ORR r0, r0, r1 ; add logical page #
MOV r8, r0, LSL #4
MOV r6, #0 ; no longer expecting aborts
ORRS r0, r0, #1
MOV pc, r13
;
; **************************************************************************
;
; Routine to return expected number of physical pages in r0.
; Uses memory size determination from r10_fiq and page mode from r11_fiq.
; Returns pagesize as power-of-two in r1, for pagenumber->address calcs.
ts_count_CAMs
MODE FIQ_mode
MOV r0,r10_fiq,LSR #12 ; get values determined
MOV r1,r11_fiq,LSR #2 ; by MemSize
MODE SVC_mode
AND r1,r1,#3 ; memory / pagesize
MOV r0,r0,LSR r1
ADD r1,r1,#12 ; page bit-shift value
MOVS pc,lr
;
; **************************************************************************
;
ROUT
; Indicate that an unexpected number of CAM pages were found.
;
; Display as "CAM ## eee.fff"
;
; where eee is the expected maximum page number (r0), fff is the number
; of of the highest page actually found (r8).
0
= "CAM ##",&89,&ff,&ff,&ff,".",&ff,&ff,&ff,0
ALIGN
ts_bad_CAM_count
ADD r8, r8, r0, LSL #12
MOV r8, r8, LSL #8
ADR r4, %B0
ORRS r0, r0 ,#1
MOV pc, r13
;
; **************************************************************************
;
; Indicate that the DAB vector wasn't visible in physmem
0
= "CAM vec",&88,&ff,&ff,&ff,&ff,&ff,&ff,&ff,&ff,0
ALIGN
ts_bad_dab_vector
ADR r4, %B0
EOR r8,r0,r1 ; indicate which bits are lost
ORRS r0, r0, #1
MOV pc, r13
;
; **************************************************************************
; Routine to indicate that an unexpected abort was found.
0
= "DAB @",&88,&ff,&ff,&ff,&ff,&ff,&ff,&ff,&ff, 0
ALIGN
ts_unxvect
ADR r4, %B0
SUBS r8, r14_svc, #8 ; indicate the aborting instruction
BL ts_SendText
ORRS r0, r0, #1
MOV pc, r13
LTORG
END