OpenCores
URL https://opencores.org/ocsvn/light52/light52/trunk

Subversion Repositories light52

[/] [light52/] [trunk/] [test/] [cpu_test/] [src/] [tb51_cpu.a51] - Blame information for rev 22

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 ja_rd
;-------------------------------------------------------------------------------
2
; tb51_cpu.a51 -- MCS51 instruction set test bench.
3
;-------------------------------------------------------------------------------
4
; This program is meant to verify the basic operation of an MCS51 CPU
5
; instruction set implementation.
6
; It is far too weak to rely on it exclusively but it can help detect gross
7
; implementation errors (overclocked CPUs, timing errors in FPGA cores, that
8
; kind of thing).
9
;
10
; The program is not yet ready to run on actual hardware (UART interface).
11
;
12
; For a full verification of the instruction set, an instruction set exerciser
13
; such as 'zexall' for the Z80 would be more suitable. This one is too weak.
14
;
15
; The program is meant to run in actual hardware or on a simulated environment.
16
; In the latter case you can use the co-simulation features of the light52
17
; project to pinpoint bugs.
18
;
19
; FIXME add assembly option to run tests in a (possibly infinite) loop.
20
;-------------------------------------------------------------------------------
21
; Major limitations:
22
;   1.- PSW is not checked for undue changes.
23
;   2.- <#imm> instructions are tested with one imm value only.
24
;   3.-  jumps tested with small values (not near corner values).
25
;   4.-  tested on 1 byte only, on 2 bits only.
26
;
27
; Note there are too many limitations to list. Use this test bench as a first
28
; approximation only. If your CPU fails this test, it must be dead!
29
;-------------------------------------------------------------------------------
30
 
31
        ; Include the definitions for the light52 derivative
32
        $nomod51
33
        $include (light52.mcu)
34
 
35
        ;-- Parameters common to all tests -------------------------------------
36
 
37
dir0    set     060h                ; Address used in direct addressing tests
38
dir1    set     061h                ; Address used in direct addressing tests
39
fail    set     06eh                ; (IDATA) set to 1 upon test failure
40
saved_psw set   070h                ; (IDATA) temp store for PSW value
41
stack0  set     09fh                ; (IDATA) stack addr used for push/pop tests
42
 
43
 
44
        ;-- Macros common to all tests -----------------------------------------
45
 
46
        ; putc: send character to console (UART)
47
        ; If you change this macro, make sure it DOES NOT MODIFY PSW!
48
putc    macro   character
49
        local   putc_loop
50
putc_loop:
51
        ;jnb     SCON.1,putc_loop
52
        ;clr     SCON.1
53
        mov     SBUF,character
54
        endm
55
 
56
        ; put_crlf: send CR+LF to console
57
put_crlf macro
58
        putc    #13
59
        putc    #10
60
        endm
61
 
62
        ;eot char, label: 'end of test' to be used at the end of all tests.
63
        ; If you run into this macro it will print character 'char' and
64
        ; continue.
65
        ; If you jump to label 'label', it will instead print char '?' and
66
        ; will set variable 'fail' to 1, then it will continue.
67
eot     macro   char,label
68
        local   skip
69
        putc    #char
70
        sjmp    skip
71
label:  putc    #'?'
72
        mov     fail,#001h
73
skip:
74
        endm
75
 
76
        ;-- Reset & interrupt vectors ------------------------------------------
77
 
78
        org     00h
79
        ljmp    start               ; We'll assume LJMP works this far...
80
        org     03h
81
        org     0bh
82
        org     13h
83
        org     1bh
84
        org     23h
85
 
86
 
87
        ;-- Main test program --------------------------------------------------
88
        org     30h
89
start:
90
        ; Initialize serial port
91
        ;(leave it with the default configuration: 19200-8-N-1)
92
        ;mov     TMOD,#20h           ; C/T = 0, Mode = 2
93
        ;mov     TH1,#0fdh           ; 9600 bauds @11.xxx MHz
94
        ;mov     TCON,#40h           ; Enable T1
95
        ;mov     SCON,#52h           ; 8/N/1, TI enabled
96
 
97
        ; Clear failure flag
98
        mov     fail,#000h
99
 
100
        ;-- Test series A ------------------------------------------------------
101
        ; Test the basic opcodes needed in later tests:
102
        ; a.- Serial port initialization is OK
103
        ; a.- Bootstrap instructions work as used
104
        ; b.-  (small positive rel only)
105
        ; c.- ACC can be loaded with direct mode addressing (as an SFR)
106
        ; c.- 
107
        ; d.-  (small positive rel only)
108
        ; e.- 
109
        ; Note that one instance of LJMP has been tested too.
110
 
111
        putc    #'A'                ; start of test series
112
 
113
        ; If we arrive here at all, and you see the chars in the
114
        ; terminal, the A.a test has passed
115
        putc    #'a'
116
 
117
        sjmp    ta_b0               ;  with very small positive rel
118
        putc    #'?'
119
        mov     fail,#001h
120
ta_b0:  putc    #'b'
121
 
122
 
123
ta_c0:  sjmp    ta_c1
124
ta_c3:  putc    #'c'
125
        sjmp    ta_c4
126
ta_c1:  mov     0e0h,#5ah           ; load A as SFR
127
        cjne    a,#5ah,ta_c3        ; test cjne with == args...
128
        cjne    a,#7ah,ta_c2        ; ...with != args, rel>0...
129
        putc    #'?'
130
        mov     fail,#001h
131
ta_c2:  cjne    a,#7ah,ta_c3        ; ...and with != args, rel<0
132
        putc    #'?'
133
        mov     fail,#001h
134
ta_c4:
135
 
136
        mov     dir0,#02h
137
        djnz    dir0,ta_d1
138
        putc    #'?'
139
        mov     fail,#001h
140
ta_d1:  djnz    dir0,ta_d2
141
 
142
        eot     'd',ta_d2
143
 
144
        mov     dir0,#0a5h          ; test mov a,dir
145
        mov     a,dir0
146
        cjne    a,#0a5h,ta_e1
147
 
148
        eot     'e',ta_e1
149
 
150
        put_crlf                    ; end of test series
151
 
152
        ;-- Test series B ------------------------------------------------------
153
        ; Test CJNE plus a few aux opcodes
154
        ; a.- 
155
        ; a.- 
156
        ; b.- , 
157
        ; c.- 
158
        ; d.- , , 
159
        ; e.- 
160
        ; f.- 
161
        ; g.- 
162 15 ja_rd
        ; h.-  with SFR direct address
163 3 ja_rd
 
164
        putc    #'B'                ; start of test series
165
 
166
tb_ma   macro   reg,val
167
        mov     reg,val
168
        mov     a,reg
169
        cjne    a,val,tb_a1
170
        endm
171
 
172
        tb_ma   r0,#081h
173
        tb_ma   r1,#043h
174
        tb_ma   r2,#027h
175
        tb_ma   r3,#0c2h
176
        tb_ma   r4,#0f1h
177
        tb_ma   r5,#004h
178
        tb_ma   r6,#092h
179
        tb_ma   r7,#01fh
180
 
181
        eot     'a',tb_a1
182
 
183
        mov     PSW,#80h            ; , 
184
        jc      tb_b0
185
        putc    #'?'
186
        mov     fail,#001h
187
tb_b0:  jnc     tb_b1
188
        mov     PSW,#00h
189
        jc      tb_b1
190
        jnc     tb_b2
191
tb_b1:  putc    #'?'
192
        mov     fail,#001h
193
tb_b2:  putc    #'b'
194
 
195
tb_mc   macro   reg,val
196
        local   tb_mc0
197
        local   tb_mc1
198
        mov     reg,val+1
199
        cjne    reg,val,tb_mc0
200
        putc    #'?'
201
        mov     fail,#001h
202
tb_mc1: mov     reg,val
203
tb_mc0: cjne    reg,val,tb_mc1
204
        endm
205
 
206
        tb_mc   r0,#091h            ; first test the jumps for all Rn regs
207
        tb_mc   r1,#0a2h
208
        tb_mc   r2,#0b3h
209
        tb_mc   r3,#0c4h
210
        tb_mc   r4,#0d5h
211
        tb_mc   r5,#0e6h
212
        tb_mc   r6,#0f7h
213
        tb_mc   r7,#008h
214
 
215
tb_c0:  mov     PSW,#00h            ; now test the C flag with a single Rn reg
216
        mov     r0,#034h
217
        cjne    r0,#035h,tb_c1
218
tb_c1:  jnc     tb_c2
219
        cjne    r0,#034h,tb_c3
220
tb_c3:  jc      tb_c2
221
        cjne    r0,#033h,tb_c4
222
tb_c4:  jc      tb_c2
223
 
224
        eot     'c',tb_c2
225
 
226
        mov     PSW,#80h            ; test C set, reset and complement
227
        clr     c
228
        jc      tb_d0
229
        setb    c
230
        jnc     tb_d0
231
        cpl     c
232
        jc      tb_d0
233
 
234
        eot     'd',tb_d0
235
 
236
tb_me   macro   reg
237
        mov     reg,#dir0
238
        mov     dir0,#12h
239
        mov     a,dir0
240
        cjne    a,#012h,tb_e0
241
        mov     @reg,#0f5h
242
        mov     a,dir0
243
        cjne    a,#0f5h,tb_e0
244
        endm
245
 
246
        tb_me   r0                  ; test  with both regs
247
        tb_me   r1
248
 
249
        eot     'e',tb_e0
250
 
251
tb_mf   macro   reg,val
252
        local   tb_mf0
253
        local   tb_mf1
254
        mov     reg,#30h
255
        mov     @reg,val+1
256
        cjne    @reg,val,tb_mf0
257
        putc    #'?'
258
        mov     fail,#001h
259
tb_mf1: mov     @reg,val
260
tb_mf0: cjne    @reg,val,tb_mf1
261
        endm
262
 
263
        tb_mf   r0,#12h
264
        tb_mf   r1,#34h
265
 
266
tb_f0:  mov     r0,#30h             ; now test the C flag with a single Rn reg
267
        clr     c
268
        mov     @r0,#034h
269
        cjne    @r0,#035h,tb_f1
270
tb_f1:  jnc     tb_f2
271
        cjne    @r0,#034h,tb_f3
272
tb_f3:  jc      tb_f2
273
        cjne    @r0,#033h,tb_f4
274
tb_f4:  jc      tb_f2
275
 
276
        eot     'f',tb_f2
277
 
278 15 ja_rd
        mov     dir0,#0c0h          ; CJNE A,dir,rel targetting an IRAM location
279 3 ja_rd
        mov     031h,#0c1h
280
        mov     032h,#0c2h
281
        clr     c
282
        mov     a,#0c1h
283
        cjne    a,031h,tb_g0
284
        jc      tb_g0
285
        cjne    a,032h,tb_g1
286
        putc    #'?'
287
        mov     fail,#001h
288
tb_g1:  jnc     tb_g0
289
        cjne    a,dir0,tb_g2
290
        putc    #'$'
291
        mov     fail,#001h
292
tb_g2:  jc      tb_g0
293
 
294
        eot     'g',tb_g0
295
 
296 15 ja_rd
        mov     dir0,#0c0h          ; CJNE A,dir,rel targetting an SFR location
297
        mov     B,#0c1h
298
        mov     032h,#0c2h
299
        clr     c
300
        mov     a,#0c1h
301
        mov     r0,#42h
302
        cjne    a,B,tb_h0
303
        jc      tb_h0
304
        cjne    a,032h,tb_h1
305
        putc    #'?'
306
        mov     fail,#001h
307
tb_h1:  jnc     tb_h0
308
        cjne    a,dir0,tb_h2
309
        putc    #'$'
310
        mov     fail,#001h
311
tb_h2:  jc      tb_h0
312
 
313
        eot     'h',tb_h0
314
 
315 3 ja_rd
        put_crlf                    ; end of test series
316
 
317
 
318
        ;-- Test series C ------------------------------------------------------
319
        ; Bit operations and the rest of the conditional rel jumps
320
        ; The following tests will use a bit address within the IRAM
321
        ; a.- , 
322
        ; b.- 
323
        ; c.- , 
324
        ; d.- , 
325
        ; e.- , 
326
        ; e.- , 
327
        ; f.- , 
328
        ; g.- 
329
        ; h.- 
330
        ; The following tests are the same as above except a bit address within
331
        ; SFR B is used.
332
        ; i.- , 
333
        ; j.- , 
334
        ; k.- , 
335
        ; k.- , 
336
        ; l.- , 
337
        ; m.- 
338
        ; n.- 
339
 
340
        putc    #'C'                ; start of test series
341
 
342
        mov     02fh,#80h           ; We'll be testing bits 2F.7 and 2F.6
343
        sjmp    tc_a0
344
tc_a1:  jnb     07fh,tc_a3          ; JNB jumps not on bit set
345
        jnb     07eh,tc_a2          ; JNB jumps on bit clear
346
        putc    #'?'
347
        mov     fail,#001h
348
        sjmp    tc_a3
349
tc_a0:  jb      07fh,tc_a1          ; JB jumps on bit set
350
        putc    #'!'
351
        mov     fail,#001h
352
tc_a2:  jb      07eh,tc_a3          ; JB jumps not on bit clear
353
 
354
        eot     'a',tc_a3
355
 
356
        mov     0e0h,#079h          ; init acc (as sfr) with some data
357
        cjne    a,#079h,tc_b1
358
        mov     a,#05ah             ; now load a with imm data...
359
        cjne    a,#05ah,tc_b1       ; ...and make sure a got the data
360
 
361
        eot     'b',tc_b1
362
 
363
        mov     a,#80h
364
        sjmp    tc_c0
365
tc_c1:  jz      tc_c3               ; JZ jumps not on acc!=0
366
        mov     a,#00h
367
        jz      tc_c2               ; JZ jumps on acc==0
368
        putc    #'?'
369
        mov     fail,#001h
370
        sjmp    tc_c3
371
tc_c0:  jnz     tc_c1               ; JNZ jumps on acc!=0
372
        putc    #'!'
373
        mov     fail,#001h
374
tc_c2:  jnz     tc_c3               ; JNZ jumps not on acc==0
375
 
376
        eot     'c',tc_c3
377
 
378
 
379
        mov     02fh,#80h           ; We'll be testing bit 2F.7
380
        jb      07fh,tc_d1
381
        sjmp    tc_d0
382
tc_d1:  clr     07fh
383
        jb      07fh,tc_d0
384
        cpl     07fh
385
        jnb     07fh,tc_d0
386
 
387
        eot     'd',tc_d0
388
 
389
        mov     02eh,#08h           ; We'll be testing bits 2E.3 and 2E.2
390
        clr     c
391
        anl     c,073h              ; Test ANL in all 4 input combinations
392
        jc      tc_e0
393
        setb    c
394
        anl     c,073h
395
        jnc     tc_e0
396
        anl     c,/072h
397
        jnc     tc_e0
398
                                    ; CY == 1
399
        orl     c,073h              ; ORL-ing with 1 should give 1
400
        jnc     tc_e0
401
        orl     c,072h
402
        jnc     tc_e0
403
        clr     c                   ; CY == 0
404
        orl     c,073h              ; Now ORL c, 'bit' should give 'bit'
405
        jnc     tc_e0
406
        orl     c,/072h
407
        jnc     tc_e0
408
 
409
        eot     'e',tc_e0
410
 
411
        mov     02eh,#08h           ; We'll be testing bits 2E.3 and 2E.2
412
        clr     c
413
        mov     c,073h
414
        jnc     tc_f0
415
        mov     c,072h
416
        jc      tc_f0
417
        clr     c
418
        mov     071h,c
419
        jb      071h,tc_f0
420
        setb    c
421
        mov     071h,c
422
        jnb     071h,tc_f0
423
 
424
        eot     'f',tc_f0
425
 
426
        mov     02eh,#00h           ; We'll be testing bits 2E.3 and 2E.2
427
        setb    073h
428
        mov     c,073h
429
        jnc     tc_g0
430
        setb    072h
431
        mov     c,072h
432
        jnc     tc_g0
433
 
434
        eot     'g',tc_g0
435
 
436
        ; (better read the following code in execution order)
437
        mov     02eh,#08h           ; We'll be testing bits 2E.3 and 2E.2
438
        sjmp    tc_h1               ; jump forward so we can test jump backwards
439
tc_h2:  mov     c,073h              ; make sure the target bit is clear
440
        jc      tc_h0
441
        jbc     072h,tc_h0          ; JBC jumps not when target bit clear
442
        sjmp    tc_h3
443
tc_h1:  jbc     073h,tc_h2          ; JBC jumps when target bit set
444
        sjmp    tc_h0
445
tc_h3:
446
 
447
        eot     'h',tc_h0
448
 
449
        mov     02fh,#00h
450
        mov     B,#80h              ; We'll be testing bits B.7 and B.6
451
        sjmp    tc_i0
452
tc_i1:  jnb     B.7,tc_i3           ; JNB jumps not on bit set
453
        jnb     B.6,tc_i2           ; JNB jumps on bit clear
454
        putc    #'?'
455
        mov     fail,#001h
456
        sjmp    tc_i3
457
tc_i0:  jb      B.7,tc_i1           ; JB jumps on bit set
458
        putc    #'!'
459
        mov     fail,#001h
460
tc_i2:  jb      B.6,tc_i3           ; JB jumps not on bit clear
461
 
462
        eot     'i',tc_i3
463
 
464
        mov     B,#80h              ; We'll be testing bit B.7
465
        jb      B.7,tc_j1
466
        sjmp    tc_j0
467
tc_j1:  clr     B.7
468
        jb      B.7,tc_j0
469
        cpl     B.7
470
        jnb     B.7,tc_j0
471
 
472
        eot     'j',tc_j0
473
 
474
        mov     B,#08h              ; We'll be testing bits B.3 and B.2
475
        clr     c
476
        anl     c,B.3               ; Test ANL in all 4 input combinations
477
        jc      tc_k0
478
        setb    c
479
        anl     c,B.3
480
        jnc     tc_k0
481
        anl     c,/B.2
482
        jnc     tc_k0
483
                                    ; CY == 1
484
        orl     c,B.3               ; ORL-ing with 1 should give 1
485
        jnc     tc_k0
486
        orl     c,B.2
487
        jnc     tc_k0
488
        clr     c                   ; CY == 0
489
        orl     c,B.3               ; Now ORL c, 'bit' should give 'bit'
490
        jnc     tc_k0
491
        orl     c,/B.2
492
        jnc     tc_k0
493
 
494
        eot     'k',tc_k0
495
 
496
        mov     B,#08h              ; We'll be testing bits B.3, B.2 and B.1
497
        clr     c
498
        mov     c,B.3
499
        jnc     tc_L0
500
        mov     c,B.2
501
        jc      tc_L0
502
        clr     c
503
        mov     B.1,c
504
        jb      B.1,tc_L0
505
        setb    c
506
        mov     B.1,c
507
        jnb     B.1,tc_L0
508
 
509
        eot     'l',tc_L0
510
 
511
        mov     02eh,#00h           ; We'll be testing bits B.3 and B.2
512
        setb    B.3
513
        mov     c,B.3
514
        jnc     tc_m0
515
        setb    B.2
516
        mov     c,B.2
517
        jnc     tc_m0
518
 
519
        eot     'm',tc_m0
520
 
521
        ; (better read the following code in execution order)
522
        mov     B,#08h              ; We'll be testing bits B.3 and B.2
523
        sjmp    tc_n1               ; jump forward so we can test jump backwards
524
tc_n2:  mov     c,B.3               ; make sure the target bit is clear
525
        jc      tc_n0
526
        jbc     B.2,tc_n0           ; JBC jumps not when target bit clear
527
        sjmp    tc_n3
528
tc_n1:  jbc     B.3,tc_n2           ; JBC jumps when target bit set
529
        sjmp    tc_n0
530
tc_n3:
531
 
532
        eot     'n',tc_n0
533
 
534
 
535
 
536
        put_crlf                    ; end of test series
537
 
538
        ;-- Test series D ------------------------------------------------------
539
        ;
540
        ; a.- 
541
        ; b.- 
542
        ; c.- 
543
        ; d.- , 
544
        ;
545
        ; This test executes a few NOPs too but does NOT check for unintended
546
        ; side effects; we intersperse the nops between the other tests to at
547
        ; least have a chance to catch buggy behavior but that's all.
548
 
549
 
550
        putc    #'D'                ; start of test series
551
 
552
        mov     a,#085h             ; test XRL A,#imm before using it in
553
        xrl     a,#044h             ; subsequent tests
554
        jz      td_a0
555
        xrl     a,#0c1h
556
        jnz     td_a0
557
 
558
        eot     'a',td_a0
559
 
560
        mov     a,#085h             ; Test RLC effects on ACC, ignore CY for now
561
        nop
562
        clr     c
563
        rlc     a                   ; a = (a << 1) | 0
564
        mov     dir0,a
565
        xrl     a,#00ah             ; We can't use CJNE because it modifies CY
566
        jnz     td_b0               ; check shifted acc
567
        mov     a,dir0
568
        rlc     a                   ; rotate again...
569
        xrl     a,#015h             ; ...and check shifted acc with CY at bit 0
570
        jnz     td_b0
571
 
572
        mov     a,#085h             ; Now check RLC effects on CY
573
        nop
574
        clr     c
575
        rlc     a
576
        jnc     td_b0
577
        rlc     a
578
        jc      td_b0               ; CY==1 moved into ACC.0
579
 
580
        eot     'b',td_b0
581
 
582
        mov     a,#085h             ; Test RRC effects on ACC, ignore CY for now
583
        clr     c
584
        rrc     a                   ; will set CY
585
        mov     dir0,a
586
        nop
587
        xrl     a,#042h             ; We can't use CJNE because it modifies CY
588
        jnz     td_c0               ; check shifted acc
589
        mov     a,dir0
590
        rrc     a                   ; rotate again...
591
        xrl     a,#0a1h             ; ...and check shifted acc with CY at bit 7
592
        jnz     td_c0
593
 
594
        mov     a,#085h             ; Now check RRC effects on CY
595
        clr     c
596
        rrc     a
597
        jnc     td_c0
598
        rrc     a
599
        jc      td_c0               ; CY==1 moved into ACC.0
600
 
601
        eot     'c',td_c0
602
 
603
        mov     a,#085h             ; Test RL effects on ACC, ignore CY for now
604
        clr     c
605
        rl      a                   ; a = (a << 1) | 0
606
        mov     dir0,a
607
        xrl     a,#00bh             ; We can't use CJNE because it modifies CY
608
        jnz     td_d0               ; check shifted acc
609
        mov     a,dir0
610
        setb    c
611
        rl      a                   ; rotate again...
612
        xrl     a,#016h             ; ...and check shifted acc with CY at bit 0
613
        jnz     td_d0
614
 
615
        mov     a,#085h             ; Test RR effects on ACC, ignore CY for now
616
        clr     c
617
        rr      a                   ; will set CY
618
        mov     dir0,a
619
        xrl     a,#0c2h             ; We can't use CJNE because it modifies CY
620
        jnz     td_d0               ; check shifted acc
621
        mov     a,dir0
622
        rr      a                   ; rotate again...
623
        xrl     a,#061h             ; ...and check shifted acc with CY at bit 7
624
        jnz     td_d0
625
 
626
        mov     a,#0ffh             ; Now make sure RL and RR don't touch CY
627
        clr     c
628
        rl      a
629
        jc      td_d0
630
        rr      a
631
        rr      a
632
        jc      td_d0
633
 
634
        eot     'd',td_d0
635
 
636
        put_crlf                    ; end of test series
637
 
638
        ;-- Test series E ------------------------------------------------------
639
        ; Increment
640
        ; a.- 
641
        ; b.- 
642
        ; c.- 
643
        ; d.- 
644
        ; e.- 
645
        ; f.- 
646
        ; g.- 
647
        ; h.- 
648
        ; i.- 
649
 
650
        putc    #'E'                ; start of test series
651
 
652
te_ma   macro   target, error_loc
653
        mov     target,#080h
654
        inc     target
655
        cjne    target,#081h,error_loc
656
        mov     target,#0ffh
657
        clr     c
658
        inc     target
659
        jc      error_loc
660
        cjne    target,#000h,error_loc
661
        endm
662
 
663
        te_ma   a,te_a0             ; Test 
664
 
665
        eot     'a',te_a0
666
 
667
        mov     r0,#066h
668
 
669
        te_ma   r0,te_b0
670
        te_ma   r1,te_b0
671
        te_ma   r2,te_b0
672
        te_ma   r3,te_b0
673
        te_ma   r4,te_b0
674
        te_ma   r5,te_b0
675
        te_ma   r6,te_b0
676
        te_ma   r7,te_b0
677
 
678
        eot     'b',te_b0
679
 
680
        mov     r0,#dir0
681
        mov     r1,#031h
682
 
683
        te_ma   @r0,te_c0
684
        te_ma   @r1,te_c0
685
 
686
        eot     'c',te_c0
687
 
688
        mov     dir0,#034h          ; Test  before using it in
689
        mov     a,dir0              ; subsequent tests
690
        cjne    a,#034h,te_d0
691
 
692
        eot     'd',te_d0
693
 
694 15 ja_rd
        mov     039h,#080h          ; Test  with IRAM address...
695 3 ja_rd
        inc     039h
696
        mov     a,039h
697
        cjne    a,#081h,te_e0
698
        mov     039h,#0ffh
699
        clr     c
700
        inc     039h
701
        jc      te_e0
702
        mov     a,039h
703
        cjne    a,#000h,te_e0
704
 
705 15 ja_rd
        mov     B,#080h             ; ...and  with SFR address
706
        inc     B
707
        mov     a,B
708
        cjne    a,#081h,te_e0
709
        mov     B,#0ffh
710
        clr     c
711
        inc     B
712
        jc      te_e0
713
        mov     a,B
714
        cjne    a,#000h,te_e0
715
 
716
 
717 3 ja_rd
        eot     'e',te_e0
718
 
719
te_mf   macro   target, error_loc
720
        mov     target,#001h
721
        dec     target
722
        cjne    target,#000h,error_loc
723
        clr     c
724
        dec     target
725
        jc      error_loc
726
        cjne    target,#0ffh,error_loc
727
        endm
728
 
729
        te_mf   a,te_f0             ; Test 
730
 
731
        eot     'f',te_f0
732
 
733
        mov     r0,#066h
734
 
735
        te_mf   r0,te_g0
736
        te_mf   r1,te_g0
737
        te_mf   r2,te_g0
738
        te_mf   r3,te_g0
739
        te_mf   r4,te_g0
740
        te_mf   r5,te_g0
741
        te_mf   r6,te_g0
742
        te_mf   r7,te_g0
743
 
744
        eot     'g',te_g0
745
 
746
        mov     r0,#dir0
747
        mov     r1,#031h
748
 
749
        te_mf   @r0,te_h0
750
        te_mf   @r1,te_h0
751
 
752
        eot     'h',te_h0
753
 
754 15 ja_rd
        mov     039h,#001h          ; Test  with IRAM address...
755 3 ja_rd
        dec     039h
756
        mov     a,039h
757
        cjne    a,#00h,te_i0
758
        mov     039h,#000h
759
        clr     c
760
        dec     039h
761
        jc      te_i0
762
        mov     a,039h
763
        cjne    a,#0ffh,te_i0
764
 
765 15 ja_rd
        mov     B,#001h             ; ...and  with SFR address
766
        dec     B
767
        mov     a,B
768
        cjne    a,#00h,te_i0
769
        mov     B,#000h
770
        clr     c
771
        dec     B
772
        jc      te_i0
773
        mov     a,B
774
        cjne    a,#0ffh,te_i0
775
 
776 3 ja_rd
        eot     'i',te_i0
777
 
778
        put_crlf                    ; end of test series
779
 
780
 
781
        ;-- Test series F ------------------------------------------------------
782
        ;
783
        ; a.- 
784
        ; b.- 
785
        ; c.- 
786
        ; d.- 
787
        ; e.- 
788
        ; f.- 
789
        ; g.- 
790
        ; h.- 
791
 
792
 
793
        putc    #'F'                ; start of test series
794
 
795
tf_ma   macro   rn, n, error_loc
796
        mov     rn,#(091h+n)
797
        mov     039h,rn
798
        mov     a,039h
799
        cjne    a,#(091h+n),error_loc
800
        endm
801
 
802
        tf_ma   r0,0,tf_a0
803
        tf_ma   r1,1,tf_a0
804
        tf_ma   r2,2,tf_a0
805
        tf_ma   r3,3,tf_a0
806
        tf_ma   r4,4,tf_a0
807
        tf_ma   r5,5,tf_a0
808
        tf_ma   r6,6,tf_a0
809
        tf_ma   r7,7,tf_a0
810
 
811
        eot     'a',tf_a0
812
 
813
        tf_ma   @r0,0,tf_b0
814
        tf_ma   @r1,1,tf_b0
815
 
816
        eot     'b',tf_b0
817
 
818 15 ja_rd
        mov     031h,#091h          ; IRAM to IRAM...
819 3 ja_rd
        mov     039h,031h
820
        mov     a,039h
821
        cjne    a,#091h,tf_c0
822
 
823 15 ja_rd
        mov     031h,#091h          ; ...IRAM to SFR...
824
        mov     B,031h
825
        mov     a,B
826
        cjne    a,#091h,tf_c0
827
 
828
        mov     B,#091h          ; ...and SFR to IRAM
829
        mov     031h,B
830
        mov     a,031h
831
        cjne    a,#091h,tf_c0
832
 
833
 
834 3 ja_rd
        eot     'c',tf_c0
835
 
836
tf_md   macro   rn, n, error_loc
837
        mov     039h,#(091h+n)
838
        mov     rn,039h
839
        cjne    rn,#(091h+n),error_loc
840
        endm
841
 
842
        tf_md   r0,0,tf_d0
843
        tf_md   r1,1,tf_d0
844
        tf_md   r2,2,tf_d0
845
        tf_md   r3,3,tf_d0
846
        tf_md   r4,4,tf_d0
847
        tf_md   r5,5,tf_d0
848
        tf_md   r6,6,tf_d0
849
        tf_md   r7,7,tf_d0
850
 
851
        eot     'd',tf_d0
852
 
853
        mov     r0,#dir0
854
        mov     r1,#031h
855
        tf_md   @r0,0,tf_e0
856
        tf_md   @r1,1,tf_e0
857
 
858
        eot     'e',tf_e0
859
 
860
tf_mf   macro   rn, n, error_loc
861
        mov     a,#(091h+n)
862
        mov     rn,a
863
        cjne    rn,#(091h+n),error_loc
864
        endm
865
 
866
        tf_mf   r0,0,tf_f0
867
        tf_mf   r1,1,tf_f0
868
        tf_mf   r2,2,tf_f0
869
        tf_mf   r3,3,tf_f0
870
        tf_mf   r4,4,tf_f0
871
        tf_mf   r5,5,tf_f0
872
        tf_mf   r6,6,tf_f0
873
        tf_mf   r7,7,tf_f0
874
 
875
        eot     'f',tf_f0
876
 
877
        mov     r0,#dir0
878
        mov     r1,#031h
879
        tf_mf   @r0,0,tf_g0
880
        tf_mf   @r1,1,tf_g0
881
 
882
        eot     'g',tf_g0
883
 
884
        mov     dir0,#079h
885
        mov     r0,#000h
886
        mov     a,#34h
887
        mov     dir0,a
888
        mov     r0,dir0
889
        cjne    r0,#034h,tf_h0
890
 
891
        eot     'h',tf_h0
892
 
893
        mov     a,#000h
894
 
895
        mov     r1,#031h
896
        mov     031h,#056h
897
        mov     r0,#dir0
898
        mov     dir0,#034h
899
        mov     a,@r0
900
        cjne    a,#034h,tf_i0
901
        mov     a,@r1
902
        cjne    a,#056h,tf_i0
903
 
904
        eot     'i',tf_i0
905
 
906
        put_crlf                    ; end of test series
907
 
908
 
909
        ;-- Test series G ------------------------------------------------------
910
        ; Note the XCG tests are specially lame even within this context.
911
        ; a.- , , 
912
        ; b.- 
913
        ; c.- 
914
        ; d.- 
915
        ; e.- 
916
 
917
        putc    #'G'                ; start of test series
918
 
919
        mov     a,#055h
920
        clr     a
921
        jnz     tg_a0
922
 
923
        mov     a,#055h
924
        cpl     a
925
        cjne    a,#0aah,tg_a0
926
 
927
        mov     a,#097h
928
        swap    a
929
        cjne    a,#079h,tg_a0
930
 
931
        eot     'a',tg_a0
932
 
933
        mov     DPH,#012h
934
        mov     DPL,#0fdh
935
        inc     dptr
936
        mov     a,DPH
937
        cjne    a,#012h,tg_b0
938
        mov     a,DPL
939
        cjne    a,#0feh,tg_b0
940
        inc     dptr
941
        mov     a,DPH
942
        cjne    a,#012h,tg_b0
943
        mov     a,DPL
944
        cjne    a,#0ffh,tg_b0
945
        inc     dptr
946
        mov     a,DPH
947
        cjne    a,#013h,tg_b0
948
        mov     a,DPL
949
        cjne    a,#000h,tg_b0
950
 
951
        eot     'b',tg_b0
952
 
953
        ; c.- 
954 15 ja_rd
        mov     a,#34h              ; IRAM address...
955 3 ja_rd
        mov     13h,#57h
956
        xch     a,13h
957
        cjne    a,#57h,tg_c0
958
        mov     a,13h
959
        cjne    a,#34h,tg_c0
960
 
961 15 ja_rd
        mov     a,#34h              ; ...and SFR address
962
        mov     B,#57h
963
        xch     a,B
964
        cjne    a,#57h,tg_c0
965
        mov     a,B
966
        cjne    a,#34h,tg_c0
967
 
968 3 ja_rd
        eot     'c',tg_c0
969
 
970
        ; d.- 
971
        mov     a,#91h
972
        mov     29h,#78h
973
        mov     r0,#29h
974
        xch     a,@r0
975
        cjne    a,#78h,tg_d0
976
        mov     a,29h
977
        cjne    a,#91h,tg_d0
978
 
979
        mov     a,#92h
980
        mov     2ah,#78h
981
        mov     r1,#2ah
982
        xch     a,@r1
983
        cjne    a,#78h,tg_d0
984
        mov     a,2ah
985
        cjne    a,#92h,tg_d0
986
 
987
        eot     'd',tg_d0
988
 
989
        ; e.- 
990
 
991
tg_ma   macro   rn, n, error_loc
992
        mov     a,#(0c1h+n)
993
        mov     rn,#(042h+n)
994
        xch     a,rn
995
        cjne    rn,#(0c1h+n),error_loc
996
        cjne    a,#(042h+n),error_loc
997
        endm
998
 
999
        tg_ma   r0, 19, tg_e0
1000
        tg_ma   r1, 18, tg_e0
1001
        tg_ma   r2, 17, tg_e0
1002
        tg_ma   r3, 16, tg_e0
1003
        tg_ma   r4, 15, tg_e0
1004
        tg_ma   r5, 14, tg_e0
1005
        tg_ma   r6, 13, tg_e0
1006
        tg_ma   r7, 12, tg_e0
1007
 
1008
        eot     'e',tg_e0
1009
 
1010
 
1011
        put_crlf                    ; end of test series
1012
 
1013
 
1014
        ;-- ALU opcode block test ----------------------------------------------
1015
        ; This set of macros is used to test families of opcodes, such as ORL,
1016
        ; ANL, ADD, etc. with all their addressing modes.
1017
        ;
1018
        ; a.- , ,  (n=0,1)
1019
        ; b.-  (n=2,3)
1020
        ; c.-  (n=4,5)
1021
        ; d.-  (n=6,7)
1022
        ; e.- 
1023
        ; f.- 
1024
        ; g.- 
1025
 
1026
        ;store psw away for later comparison
1027
save_psw macro
1028
        mov     saved_psw,PSW
1029
        endm
1030
 
1031
        ; compare flags CY, AC and OV with expected values in 
1032
tst_psw macro   flags,error_loc
1033
        mov     a,saved_psw
1034
        anl     a,#0c4h
1035
        xrl     a,#flags
1036
        anl     a,#0feh
1037
        jnz     error_loc
1038
        endm
1039
 
1040
        ; Set the CY flag to the value of the lsb of argument 
1041
set_cy  macro   flags
1042
        local   cy_val
1043
cy_val  set     (flags and 1)
1044
        if      cy_val eq 1
1045
        setb    c
1046
        else
1047
        clr     c
1048
        endif
1049
        endm
1050
 
1051
        ; Test instruction  A, src
1052
        ;
1053
        ; flags = ( & 0xfe) | 
1054
        ; (P flag result is not tested)
1055
top_ma  macro   op,src,error_loc,flags
1056
        mov     src,#arg0
1057
        mov     a,#arg1
1058
        ifnb    
1059
        set_cy  flags
1060
        endif
1061
        op      a,src
1062
        ifnb    
1063
        save_psw
1064
        endif
1065
        cjne    a,#res,error_loc
1066
        ifnb    
1067
        tst_psw ,error_loc
1068
        endif
1069
        endm
1070
 
1071
        ; Test instruction  dst, #arg0
1072
        ; ( same as top_ma)
1073
top_mb  macro   op,dst,error_loc,flags
1074
        mov     dst,#arg1
1075
        ifnb    
1076
        set_cy  flags
1077
        endif
1078
        op      dst,#arg0
1079
        ifnb    
1080
        save_psw
1081
        endif
1082
        mov     ACC,dst
1083
        cjne    a,#res,error_loc
1084
        ifnb    
1085
        tst_psw ,error_loc
1086
        endif
1087
        endm
1088
 
1089
        ; Test instruction  dir, A
1090
        ; ( same as top_ma)
1091
top_mc  macro   op,error_loc,flags
1092
        mov     dir0,#arg0
1093
        mov     a,#arg1
1094
        ifnb    
1095
        set_cy  flags
1096
        endif
1097
        op      dir0,a
1098
        ifnb    
1099
        save_psw
1100
        endif
1101
        mov     a,dir0
1102
        cjne    a,#res,error_loc
1103
        ifnb    
1104
        tst_psw ,error_loc
1105
        endif
1106
        endm
1107
 
1108
        ; Test ALU instruction with all addressing modes.
1109
        ; FIXME  A, #imm not tested!
1110
        ; op : Opcode to be tested
1111
        ; a0, a1 : Values used as 1st and 2nd args in all addressing modes
1112
        ; r : Expected result
1113
        ; am :
1114
        ; flags : &0xfe | 
1115
        ; (if the parameter is unused, the macro skips the flag check)
1116
tst_alu macro   op,a0,a1,r,am,flags
1117
        local   tall_0d
1118
        local   tall_0a
1119
        local   tall_0b
1120
        local   tall_0c
1121
        local   tall_1
1122
        local   tall_2
1123
        local   tall_3
1124
        ; Put the argument and result data into variables for easier access
1125
        arg0    set a0
1126
        arg1    set a1
1127
        res     set r
1128
 
1129
        ; Test  A, dir
1130
        top_ma  op,dir0,tall_0a,
1131
        ; Test  A, @R0
1132
        mov     r0,#dir0
1133
        top_ma  op,@r0,tall_0a,
1134
        ; Test  A, @R1
1135
        mov     r1,#031h
1136
        top_ma  op,@r1,tall_0a,
1137
 
1138
        ; Now test  A, Rn for n in 0..7
1139
        top_ma  op,r0,tall_0a,
1140
        top_ma  op,r1,tall_0a,
1141
 
1142
        eot     'a',tall_0a
1143
 
1144
        top_ma  op,r2,tall_0b,
1145
        top_ma  op,r3,tall_0b,
1146
 
1147
        eot     'b',tall_0b
1148
 
1149
        top_ma  op,r4,tall_0c,
1150
        top_ma  op,r5,tall_0c,
1151
 
1152
        eot     'c',tall_0c
1153
 
1154
        top_ma  op,r6,tall_0d,
1155
        top_ma  op,r7,tall_0d,
1156
 
1157
        eot     'd',tall_0d
1158
        ; Ok,  A, {dir | @Ri | Rn} done.
1159
 
1160
        ; Optionally test immediate addressing modes.
1161
 
1162
        if      (am and 1) ne 0
1163
        ; Test  A, #arg1...
1164
        top_mb  op,a,tall_1,
1165
        eot     'e',tall_1
1166
        endif
1167
 
1168
        if      (am and 2) ne 0
1169
        ; ...and  dir, #arg1
1170
        top_mb  op,dir0,tall_2,
1171 15 ja_rd
        top_mb  op,B,tall_2,
1172 3 ja_rd
        eot     'f',tall_2
1173
        endif
1174
 
1175
        ; Optionally test  dir, A
1176
        if      (am and 4) ne 0
1177
        top_mc  op,tall_3,
1178
        eot     'g',tall_3
1179
        endif
1180
 
1181
        endm
1182
 
1183
 
1184
        ;-- Test series H ------------------------------------------------------
1185
        ; ANL
1186
        ; (See comments for 'ALU opcode block test')
1187
 
1188
        putc    #'H'                ; start of test series
1189
 
1190
        tst_alu anl,03ch,099h,018h,07h,
1191
 
1192
        put_crlf                    ; end of test series
1193
 
1194
 
1195
        ;-- Test series I ------------------------------------------------------
1196
        ; ORL
1197
        ; (See comments for 'ALU opcode block test')
1198
 
1199
        putc    #'I'                ; start of test series
1200
 
1201
        tst_alu orl,051h,092h,0d3h,07h,
1202
 
1203
        put_crlf                    ; end of test series
1204
 
1205
        ;-- Test series J ------------------------------------------------------
1206
        ; XRL
1207
        ; (See comments for 'ALU opcode block test')
1208
 
1209
 
1210
        putc    #'J'                ; start of test series
1211
 
1212
        tst_alu xrl,051h,033h,062h,07h,
1213
 
1214
        put_crlf                    ; end of test series
1215
 
1216
        ;-- Test series K ------------------------------------------------------
1217
        ; DJNZ
1218
        ; a.- ,  tested only with small negative rels
1219
 
1220
        putc    #'K'                ; start of test series
1221
 
1222
        ;tk_ma: test DJNZ with parametrizable addressing mode
1223
tk_ma   macro   dst,error_loc
1224
        local   tk_ma0
1225
nloops  set     3
1226
        mov     dst,#nloops         ; We'll perform a fixed no. of iterations
1227
        mov     a,#(nloops+1)       ; A will or our control counter
1228
tk_ma0: dec     a
1229
        jz      error_loc           ; Break loop after nloops iterations
1230
        djnz    dst,tk_ma0          ; Test DJNZ instruction
1231
        cjne    a,#001,error_loc    ; Verify number of iterations is ok
1232
        endm
1233
 
1234 13 ja_rd
        tk_ma   dir0,tk_a0          ;  with IRAM operand
1235
        tk_ma   B,tk_a0             ;  with SFR operand
1236 3 ja_rd
 
1237
        eot     'a',tk_a0
1238
 
1239
        tk_ma   r0,tk_b0            ; 
1240
        tk_ma   r1,tk_b0
1241
        tk_ma   r2,tk_b0
1242
        tk_ma   r3,tk_b0
1243
        tk_ma   r4,tk_b0
1244
        tk_ma   r5,tk_b0
1245
        tk_ma   r6,tk_b0
1246
        tk_ma   r7,tk_b0
1247
 
1248
        eot     'b',tk_b0
1249
 
1250
        put_crlf                    ; end of test series
1251
 
1252
 
1253
        ;-- Test series L ------------------------------------------------------
1254
        ; ADD
1255
        ; (See comments for 'ALU opcode block test')
1256
 
1257
 
1258
        putc    #'L'                ; start of test series
1259
 
1260
        putc    #'0'
1261
        tst_alu add,051h,033h,084h,01h,004h     ; /CY /AC  OV
1262
        putc    #'1'
1263
        tst_alu add,081h,093h,014h,01h,084h     ;  CY /AC  OV
1264
        putc    #'2'
1265
        tst_alu add,088h,098h,020h,01h,0c4h     ;  CY  AC  OV
1266
        putc    #'3'
1267
        tst_alu add,043h,0fbh,03eh,01h,080h     ;  CY /AC /OV
1268
 
1269
        put_crlf                    ; end of test series
1270
 
1271
 
1272
        ;-- Test series M ------------------------------------------------------
1273
        ; ADDC
1274
        ; (See comments for 'ALU opcode block test')
1275
        ; Note the test runs 4 times for different values of operands
1276
 
1277
        putc    #'M'                ; start of test series
1278
 
1279
        putc    #'0'
1280
        tst_alu addc,051h,033h,084h,01h,004h     ; /CY /AC  OV
1281
        putc    #'1'
1282
        tst_alu addc,081h,093h,014h,01h,084h     ;  CY /AC  OV
1283
        putc    #'2'
1284
        tst_alu addc,088h,098h,020h,01h,0c4h     ;  CY  AC  OV
1285
        putc    #'3'
1286
        tst_alu addc,088h,098h,021h,01h,0c5h     ;  CY  AC  OV (CY input)
1287
        putc    #'4'
1288
        tst_alu addc,043h,0fbh,03fh,01h,081h     ;  CY /AC /OV (CY input)
1289
 
1290
 
1291
        put_crlf                    ; end of test series
1292
 
1293
 
1294
        ;-- Test series N ------------------------------------------------------
1295
        ; SUBB
1296
        ; (See comments for 'ALU opcode block test')
1297
        ; Note the test runs 4 times for different values of operands
1298
 
1299
        putc    #'N'                ; start of test series
1300
 
1301
        putc    #'0'
1302
        tst_alu subb,070h,073h,003h,01h,000h     ; /CY /AC /OV
1303
        putc    #'1'
1304
        tst_alu subb,070h,073h,002h,01h,001h     ; /CY /AC /OV (CY input)
1305
        putc    #'2'
1306
        tst_alu subb,0c3h,0c5h,002h,01h,000h     ; /CY  AC /OV
1307
        putc    #'3'
1308
        tst_alu subb,0c3h,0c5h,001h,01h,001h     ; /CY  AC  OV (CY input)
1309
 
1310
        ; FIXME subb tests are specially weak
1311
 
1312
        put_crlf                    ; end of test series
1313
 
1314
 
1315
        ;-- Test series O ------------------------------------------------------
1316
        ; PUSH and POP
1317
        ; a.- 
1318
        ; b.- 
1319
        ; c.- 
1320
        ; d.- 
1321
 
1322
        putc    #'O'                ; start of test series
1323
 
1324
        ; 
1325
        mov     SP,#stack0          ; prepare SP...
1326
        mov     dir0,#012h          ; ...and data to be pushed
1327
        mov     r0,#(stack0+1)      ; r0->stack so we can verify data is pushed
1328
        mov     @r0,#000h           ; clear target stack location
1329
        push    dir0                ; 
1330
        mov     a,@r0               ; verify data has been pushed
1331
        cjne    a,#012h,to_a0
1332
        mov     a,SP                ; verify SP has been incremented
1333
        cjne    a,#(stack0+1),to_a0
1334
 
1335
        eot     'a',to_a0
1336
 
1337
        ;  We'll use the data that was pushed previously
1338
        mov     dir1,#000h          ; clear POP target
1339
        clr     a
1340
        pop     dir1                ; 
1341
        mov     r1,#dir1            ; verify data has been popped
1342
        mov     a,@r1
1343
        cjne    a,#012h,to_b0
1344
        mov     a,SP                ; verify SP has been decremented
1345
        cjne    a,#stack0,to_b0
1346
 
1347
        eot     'b',to_b0
1348
 
1349
        ; 
1350
        mov     SP,#stack0          ; prepare SP...
1351
        mov     B,#042h             ; ...and data to be pushed
1352
        mov     r0,#(stack0+1)      ; r0->stack so we can verify data is pushed
1353
        mov     @r0,#000h           ; clear target stack location
1354
        push    B                   ; 
1355
        mov     a,@r0               ; verify data has been pushed
1356
        cjne    a,#042h,to_c0
1357
        mov     a,SP                ; verify SP has been incremented
1358
        cjne    a,#(stack0+1),to_c0
1359
 
1360
        eot     'c',to_c0
1361
 
1362
        ;  We'll use the data that was pushed previously
1363
        mov     B,#000h             ; clear POP target
1364
        clr     a
1365
        pop     B                   ; 
1366
        mov     a,B                 ; verify data has been popped
1367
        cjne    a,#042h,to_d0
1368
        mov     a,SP                ; verify SP has been decremented
1369
        cjne    a,#stack0,to_d0
1370
 
1371
        eot     'd',to_d0
1372
 
1373
        put_crlf                    ; end of test series
1374
 
1375
        ;-- Test series P ------------------------------------------------------
1376
        ; Access to XRAM -- note that current tests are bare-bone minimal!
1377
        ; a.- 
1378
        ; b.- , 
1379
        ; c.- 
1380
        ; d.- 
1381
 
1382
        putc    #'P'                ; start of test series
1383
 
1384
        ; a.- 
1385
        mov     DPH,#065h           ; initialize DPTR with known value...
1386
        mov     DPL,#043h
1387
 
1388
        mov     DPTR,#0123h         ; ...then load it through MOV...
1389
        mov     a,DPH               ; ...and verify the load
1390
        cjne    a,#01h,tp_a0
1391
        mov     a,DPL
1392
        cjne    a,#23h,tp_a0
1393
 
1394
        eot     'a',tp_a0
1395
 
1396
 
1397
        ; b.- , 
1398
        ; We have no independent means to verify XRAM writes or reads, other
1399
        ; than the very instructions we're testing. So we should store a data
1400
        ; pattern on XRAM that is difficult to get back 'by chance'.
1401
        ; Ideally we would try all areas of XRAM, back-to-back operations, etc.
1402
        ; For the time being a simple word store will suffice.
1403
        mov     DPTR,#0013h         ; Store 55h, aah at XRAM[0013h]...
1404
        mov     A,#55h
1405
        movx    @DPTR,a
1406
        inc     DPTR
1407
        cpl     a
1408
        movx    @DPTR,a
1409
 
1410
        mov     DPTR,#0013h         ; ...then verify the store
1411
        movx    a,@DPTR
1412
        cjne    a,#55h,tp_b0
1413
        inc     DPTR
1414
        movx    a,@DPTR
1415
        cjne    a,#0aah,tp_b0
1416
 
1417
        eot     'b',tp_b0
1418
 
1419
        ; c.- 
1420
        mov     a,#79h              ; Let [0013h] = 79h and [0014h] = 97h
1421
        mov     dptr,#0013h
1422
        mov     r0,#13h             ;
1423
        mov     r1,#14h             ; Write using @Ri...
1424
        movx    @r0,a
1425
        dec     a
1426
        movx    a,@DPTR             ; ...verify using DPTR
1427
        cjne    a,#79h,tp_c0
1428
        inc     DPTR
1429
        mov     a,#97h
1430
        movx    @r1,a
1431
        movx    a,@DPTR
1432
        cjne    a,#097h,tp_c0
1433
 
1434
        eot     'c',tp_c0
1435
 
1436
        ; d.- 
1437
        mov     a,#79h              ; Let [0013h] = 79h and [0014h] = 97h
1438
        mov     dptr,#0013h
1439
        mov     r0,#13h
1440
        mov     r1,#14h
1441
        movx    @DPTR,a             ; Write using DPTR...
1442
        dec a
1443
        movx    a,@r0               ; ... verify using @Ri
1444
        cjne    a,#79h,tp_d0
1445
        mov     a,#97h
1446
        inc     DPTR
1447
        movx    @DPTR,a
1448
        dec a
1449
        movx    a,@r1
1450
        cjne    a,#097h,tp_d0
1451
 
1452
        eot     'd',tp_d0
1453
 
1454
        put_crlf                    ; end of test series
1455
 
1456
        ;-- Test series Q ------------------------------------------------------
1457
        ; MOVC instructions
1458
        ; a.- 
1459
        ; b.- 
1460
 
1461
        putc    #'Q'                ; start of test series
1462
 
1463
        ; a.- 
1464
        mov     a,#03h              ; we'll read the 4th byte in the table...
1465
        add     a,#02h              ; ...and must account for intervening sjmp
1466
        movc    a,@a+PC
1467
        sjmp    tq0
1468
 
1469
tq1:    db      07h, 13h, 19h, 21h
1470
tq0:    cjne    a,#21h,tq_a0
1471
 
1472
        eot     'a',tq_a0
1473
 
1474
        ; b.- 
1475
        mov   DPTR,#tq1
1476
 
1477
        mov   a,#00h
1478
        movc  a,@a+DPTR
1479
        cjne  a,#07h,tq_b0
1480
 
1481
        mov   a,#01h
1482
        movc  a,@a+DPTR
1483
        cjne  a,#13h,tq_b0
1484
 
1485
        mov   a,#02h
1486
        movc  a,@a+DPTR
1487
        cjne  a,#19h,tq_b0
1488
 
1489
        mov   a,#03h
1490
        movc  a,@a+DPTR
1491
        cjne  a,#21h,tq_b0
1492
 
1493
        eot     'b',tq_b0
1494
 
1495
        put_crlf                    ; end of test series
1496
 
1497
 
1498
        ;-- Test series R ------------------------------------------------------
1499
        ; ACALL, LCALL, JMP @A+DPTR, LJMP, AJMP instructions
1500
        ; a.-      <-- uses LJMP too
1501
        ; b.-     <-- uses LJMP too
1502
        ; c.- 
1503
        ; d.- 
1504
        ; e.- 
1505
        ;
1506
        ; Biggest limitations:
1507
        ; .- Jumps to same page (== H addr byte) tested only at one page.
1508
        ;
1509
        ; Note RET is NOT tested here! we don't return from these calls, just
1510
        ; use them as jumps.
1511
        ;
1512
 
1513
        putc    #'R'                ; start of test series
1514
 
1515
        mov     SP,#4fh             ; Initialize SP...
1516
        mov     50h,#00h            ; ...and clear stack area
1517
        mov     51h,#00h
1518
        mov     52h,#00h
1519
        mov     53h,#00h
1520
 
1521
        ; a.- 
1522
        ; We should test all code pages eventually...
1523
        acall   tr_sub0             ; Do the call...
1524
tr_rv0: sjmp    tr_a0
1525
tr_sub0:
1526
        mov     A,SP
1527
        cjne    A,#51h,tr_a0       ; ...verify the SP value...
1528
        mov     A,50h
1529
        cjne    A,#LOW(tr_rv0),tr_a0 ; ...and verify the pushed ret address
1530
        mov     A,51h
1531
        cjne    A,#HIGH(tr_rv0),tr_a0
1532
 
1533
        eot     'a',tr_a0
1534
 
1535
        ; b.- 
1536
        lcall   tr_sub1             ; Do the call...
1537
tr_rv1: sjmp    tr_b0
1538
tr_rv2: nop
1539
        eot     'b',tr_b0
1540
 
1541
 
1542
        ; c.- 
1543
        ; Note that tr_sub2 is at 8000h so that we test the A+DPTR carry
1544
        ; propagation. Any address xx00h would do.
1545
        mov     DPTR,#(tr_sub2-33h) ; Prepare DPTR and A so that their sum
1546
        mov     a,#33h              ; gives the target address.
1547
        jmp     @a+DPTR
1548
        jmp     tr_c0
1549
        nop
1550
        nop
1551
tr_rv3: mov     a,#00h
1552
        mov     a,#00h
1553
        mov     a,#00h
1554
        mov     a,#00h
1555
 
1556
        eot     'c',tr_c0
1557
 
1558
        ; d.- 
1559
        ljmp    tr_sub3
1560
        jmp     tr_d0
1561
        nop
1562
        nop
1563
tr_rv4: nop
1564
        nop
1565
        eot     'd',tr_d0
1566
 
1567
        ; e.- 
1568
        ; We should test all code pages eventually...
1569
        mov     a,#00h
1570
        ajmp    tr_ajmp0            ; Do the jump...
1571
        sjmp    tr_rv5
1572
tr_ajmp0:
1573
        mov     a,#042h
1574
tr_rv5:
1575
        cjne    A,#42h,tr_e0       ; ...and make sure we've actually been there
1576
        nop
1577
 
1578
        eot     'e',tr_e0
1579
 
1580
        put_crlf                    ; end of test series
1581
 
1582
 
1583
        ;-- Test series S ------------------------------------------------------
1584
        ; RET, RETI instructions
1585
        ; a.- 
1586
        ; b.- 
1587
        ;
1588
        ; RETs to different code pages (!= H addr byte) not tested!
1589
        ; Interrupt flag stuff not tested, only RET functionality
1590
 
1591
        putc    #'S'                ; start of test series
1592
 
1593
 
1594
        ; a.- 
1595
        mov     SP,#4fh             ; Initialize SP...
1596
        mov     4fh,#HIGH(s_sub0)   ; ...and load stack area with return
1597
        mov     4eh,#LOW(s_sub0)    ; addresses to be tested
1598
        mov     4dh,#HIGH(s_sub1)
1599
        mov     4ch,#LOW(s_sub1)
1600
 
1601
        ret                         ; Do the ret...
1602
        sjmp    ts_a0
1603
        mov     A,#00h
1604
s_sub0: mov     A,SP
1605
        cjne    A,#4dh,ts_a0       ; ... and verify the SP value
1606
 
1607
        ret                         ; Do another ret...
1608
        sjmp    ts_a0
1609
        mov     A,#00h
1610
s_sub1: mov     A,SP
1611
        cjne    A,#4bh,ts_a0       ; ... and verify the SP value
1612
 
1613
        eot     'a',ts_a0
1614
 
1615
 
1616
        ; a.- 
1617
        mov     SP,#4fh             ; Initialize SP...
1618
        mov     4fh,#HIGH(s_sub2)   ; ...and load stack area with return
1619
        mov     4eh,#LOW(s_sub2)    ; addresses to be tested
1620
        mov     4dh,#HIGH(s_sub3)
1621
        mov     4ch,#LOW(s_sub3)
1622
 
1623
        ret                         ; Do the ret...
1624
        sjmp    ts_a0
1625
        mov     A,#00h
1626
s_sub2: mov     A,SP
1627
        cjne    A,#4dh,ts_b0       ; ... and verify the SP value
1628
 
1629
        ret                         ; Do another ret...
1630
        sjmp    ts_a0
1631
        mov     A,#00h
1632
s_sub3: mov     A,SP
1633
        cjne    A,#4bh,ts_b0       ; ... and verify the SP value
1634
 
1635
        eot     'b',ts_b0
1636
 
1637
        ; Lots of things can go badly and we wouldn't know with this test...
1638
        put_crlf                    ; end of test series
1639
 
1640
        ;-- Test series T ------------------------------------------------------
1641
        ; MUL, DIV instructions
1642
        ; a.- 
1643
        ; b.- 
1644
        ;
1645
 
1646
        putc    #'T'                ; start of test series
1647
 
1648
        ; a.- 
1649
        mov     B,#07h              ; First of all, make sure B can be read back
1650
        mov     A,#13h
1651
        mov     A,B
1652
        cjne    A,#07h,tt_a0
1653
 
1654
        ; Now do a few representative DIVs using a table. The table has the
1655
        ; following format:
1656
        ; denominator, numerator, overflow, quotient, remainder
1657
        ; Where 'overflow' is 00h or 04h.
1658
 
1659
        ; DPTR will point to the start of the table, r0 will be the current data
1660
        ; byte offset and r1 the number of test cases remaiining.
1661
        mov     DPTR,#tt_a_tab
1662
        mov     r0,#00h
1663
        mov     r1,#((tt_a_tab_end-tt_a_tab)/5)
1664
 
1665
tt_a_loop:
1666
        mov     a,r0
1667
        inc     r0
1668
        movc    a,@a+DPTR
1669
        mov     B,a
1670
        mov     a,r0
1671
        inc     r0
1672
        movc    a,@a+DPTR
1673
        div     ab
1674
        mov     dir0,a
1675
 
1676
        mov     a,r0                ; Get expected OV flag
1677
        inc     r0
1678
        movc    a,@a+DPTR
1679
        jnz     tt_a_divzero        ; If OV expected, skip verification of
1680
        mov     a,PSW               ; quotient and remainder
1681
        anl     a,#04h
1682
        jnz     tt_a0
1683
 
1684
        mov     a,r0                ; Verify quotient...
1685
        inc     r0
1686
        movc    a,@a+DPTR
1687
        cjne    a,dir0,tt_a0
1688
        mov     a,r0                ; ...and verify remainder
1689
        inc     r0
1690
        movc    a,@a+DPTR
1691
        cjne    a,B,tt_a0
1692
        jmp     tt_a_next
1693
 
1694
tt_a_divzero:
1695
        inc     r0
1696
        inc     r0
1697
tt_a_next:
1698
        dec     r1                  ; go for next test vector, if any
1699
        mov     a,r1
1700
        jnz     tt_a_loop
1701
 
1702
        eot     'a',tt_a0
1703
        sjmp    tt_a_tab_end
1704
 
1705
tt_a_tab:
1706
        db      7,19,0,2,5
1707
        db      7,17,0,2,3
1708
        db      7,13,0,1,6
1709
        db      13,17,0,1,4
1710
        db      17,13,0,0,13
1711
        db      0,13,4,0,13
1712
        db      80h,87h,0,1,7
1713
        db      1,255,0,255,0
1714
        db      2,255,0,127,1
1715
tt_a_tab_end:
1716
 
1717
        ; b.- 
1718
 
1719
        ; Do with MUL the same we just did with DIV. The test data table has
1720
        ; the following format:
1721
        ; denominator, numerator, product high byte, product low byte.
1722
 
1723
        ; DPTR will point to the start of the table, r0 will be the current data
1724
        ; byte offset and r1 the number of test cases remaiining.
1725
        mov     DPTR,#tt_b_tab
1726
        mov     r0,#00h
1727
        mov     r1,#((tt_b_tab_end-tt_b_tab)/4)
1728
 
1729
tt_b_loop:
1730
        mov     a,r0                ; Load B with test data...
1731
        inc     r0
1732
        movc    a,@a+DPTR
1733
        mov     B,a
1734
        mov     a,r0                ; ...then load A with test data...
1735
        inc     r0
1736
        movc    a,@a+DPTR
1737
        mul     ab                  ; and do the MUL
1738
        mov     dir0,a              ; Save A for later checks
1739
 
1740
        mov     a,r0                ; Verify product high byte
1741
        ;inc     r0
1742
        movc    a,@a+DPTR
1743
        jz      tt_b_noovf
1744
 
1745
        mov     a,PSW               ; overflow expected
1746
        anl     a,#04h
1747
        jz      tt_b0
1748
        sjmp    tt_b_0
1749
 
1750
tt_b_noovf:
1751
        mov     a,PSW               ; no overflow expected
1752
        anl     a,#04h
1753
        jnz     tt_b0
1754
 
1755
tt_b_0:
1756
        mov     a,r0                ; Verify product high byte
1757
        inc     r0
1758
        movc    a,@a+DPTR
1759
        cjne    a,B,tt_b0
1760
        mov     a,r0                ; ...and verify low byte
1761
        inc     r0
1762
        movc    a,@a+DPTR
1763
        cjne    a,dir0,tt_b0
1764
 
1765
        dec     r1                  ; go for next test vector, if any
1766
        mov     a,r1
1767
        jnz     tt_b_loop
1768
 
1769
        eot     'b',tt_b0
1770
        sjmp    tt_b_tab_end
1771
 
1772
tt_b_tab:
1773
        db      7,19,0,133
1774
        db      7,17,0,119
1775
        db      7,13,0,91
1776
        db      13,17,0,221
1777
        db      17,13,0,221
1778
        db      0,13,0,0
1779
        db      80h,87h,43h,80h
1780
        db      1,255,0,255
1781
        db      2,255,01h,0feh
1782
tt_b_tab_end:
1783
 
1784
        put_crlf                    ; end of test series
1785
 
1786
 
1787
 
1788
        ;-- Test series U ------------------------------------------------------
1789
        ; Register banks
1790
        ; a.- Write to register, read from indirect address.
1791
        ; a.- Write to indirect address, read from register.
1792
        ;
1793
 
1794
        putc    #'U'                ; start of test series
1795
 
1796
 
1797
        mov     PSW,#00h            ; Test bank 0
1798
        mov     a,#00h + 1
1799
        call    tu_a_test
1800
 
1801
        mov     PSW,#08h            ; Test bank 1
1802
        mov     a,#08h + 1
1803
        call    tu_a_test
1804
 
1805
        mov     PSW,#10h            ; Test bank 2
1806
        mov     a,#10h + 1
1807
        call    tu_a_test
1808
 
1809
        mov     PSW,#18h            ; Test bank 3
1810
        mov     a,#18h + 1
1811
        call    tu_a_test
1812
 
1813
        sjmp    tu_a_done
1814
 
1815
tu_a_test:
1816
        mov     r0,a                ; R0 points to R1 in the selected bank.
1817
 
1818
        mov     r1,#12h             ; Write to registers R1 and R7
1819
        mov     r7,#34h
1820
 
1821
        mov     a,@r0               ; Check R1
1822
        cjne    a,#12h,tu_a0
1823
        mov     a,#56h              ; Ok, now write to R1 with reg addressing...
1824
        mov     @r0,a               ; ...and check by reading in indirect.
1825
        cjne    r1,#56h,tu_a0
1826
 
1827
        mov     a,r0                ; Set R0 to point to R7 in selected bank
1828
        add     a,#06h
1829
        mov     r0,a
1830
        mov     a,@r0               ; Check R7
1831
        cjne    a,#34h,tu_a0
1832
 
1833
        mov     a,#78h              ; Ok, now write to R7 with reg addressing...
1834
        mov     @r0,a               ; ...and check by reading in indirect.
1835
        cjne    a,#78h,tu_a0
1836
 
1837
        ret
1838
 
1839
tu_a_done:
1840
        nop
1841
        eot     'a',tu_a0
1842
 
1843
        put_crlf                    ; end of test series
1844
 
1845
 
1846
        ;-- Test series V ------------------------------------------------------
1847
        ; NOP and potentially unimplemented opcodes (DA and XCHD).
1848
        ; In order to make sure an instruction does nothing we would have to
1849
        ; check everything: IRAM, XRAM and SFRs. We will leave that to the
1850
        ; zexall-style tester. In this test we rely on the cosimulation with
1851
        ; software simulator B51.
1852
        ;
1853
        ; a.- Opcode 0A5h
1854
        ; b.- DA
1855
        ; c.- XCHD A, @Ri
1856
 
1857
        putc    #'V'                ; start of test series
1858
 
1859
 
1860
        ; a.- <0A5>
1861
        db      0a5h                ; Put opcode right there...
1862
        nop                         ; and do no check at all -- rely on B51.
1863
        ; we'll catch any unintended side effects by comparing the logs.
1864
        ; Obviously this is no good for any core other then light52...
1865
 
1866
        eot     'a',tv_a0
1867
 
1868
        ; b.- 
1869
        ifdef   BCD
1870
        ; DA implemented in CPU
1871
        mov     psw,#000h           ; Al>9, AC=0
1872
        mov     a,#01ah
1873
        da      a
1874
        mov     saved_psw,psw
1875
        cjne    a,#020h,tv_b0
1876
        mov     a,saved_psw
1877
        cjne    a,#001h,tv_b0
1878
 
1879
        mov     psw,#040h           ; Al<9, AC=1
1880
        mov     a,#012h
1881
        da      a
1882
        mov     saved_psw,psw
1883
        cjne    a,#018h,tv_b0
1884
        mov     a,saved_psw
1885
        cjne    a,#040h,tv_b0
1886
 
1887
        mov     psw,#040h           ; Al>9, AC=1 (hardly possible in BCD)
1888
        mov     a,#01ah
1889
        da      a
1890
        mov     saved_psw,psw
1891
        cjne    a,#020h,tv_b0
1892
        mov     a,saved_psw
1893
        cjne    a,#041h,tv_b0
1894
 
1895
        mov     psw,#0c0h           ; AC=CY=1
1896
        mov     a,#000h
1897
        da      a
1898
        mov     saved_psw,psw
1899
        cjne    a,#066h,tv_b0
1900
        mov     a,saved_psw
1901
        cjne    a,#0c0h,tv_b0
1902
 
1903
        mov     psw,#040h           ; DA generates carry
1904
        mov     a,#0fah
1905
        da      a
1906
        mov     saved_psw,psw
1907
        cjne    a,#060h,tv_b0
1908
        mov     a,saved_psw
1909
        cjne    a,#0c0h,tv_b0
1910
 
1911
        else
1912
        ; DA unimplemented in CPU
1913
        mov     a,#01ah             ; This would be adjusted by DA to 020h...
1914
        da      a                   ; ...make sure it isn't
1915
        cjne    a,#01ah,tv_b0
1916
        nop
1917
        endif
1918
 
1919
        eot     'b',tv_b0
1920
 
1921
        ; c.- XCHD a,@ri
1922
        ifdef   BCD
1923
        ; XCHD implemented in CPU, test opcode.
1924
        mov     r0,#031h
1925
        mov     r1,#032h
1926
        mov     a,#042h
1927
        mov     @r0,a
1928
        inc     a
1929
        mov     @r1,a
1930
        mov     a,#76h
1931
        xchd    a,@r0
1932
        cjne    a,#072h,tv_c0
1933
        mov     a,31h
1934
        cjne    a,#046h,tv_c0
1935
        mov     a,#79h
1936
        xchd    a,@r1
1937
        cjne    a,#073h,tv_c0
1938
        mov     a,32h
1939
        cjne    a,#049h,tv_c0
1940
        else
1941
        ; XCHD unimplemented, make sure the nibbles aren't exchanged.
1942
        mov     r0,#031h
1943
        mov     r1,#032h
1944
        mov     a,#042h
1945
        mov     @r0,a
1946
        mov     @r1,a
1947
        mov     a,#76h
1948
        xchd    a,@r0
1949
        cjne    a,#076h,tv_c0
1950
        mov     a,#76h
1951
        xchd    a,@r1
1952
        cjne    a,#076h,tv_c0
1953
        endif
1954
 
1955
        eot     'c',tv_c0
1956
 
1957
        put_crlf                    ; end of test series
1958
 
1959
 
1960
        ;-- Template for test series -------------------------------------------
1961
 
1962
        ;-- Test series X ------------------------------------------------------
1963
        ;
1964
        ; a.-
1965
 
1966
        ;putc    #'X'                ; start of test series
1967
        ;put_crlf                    ; end of test series
1968
 
1969
        ;-----------------------------------------------------------------------
1970
 
1971
        ; Test cases finished. Now print completion message dependent on the
1972
        ; value of the fail flag.
1973
 
1974
        mov     a,fail
1975
        jnz     test_failed
1976
 
1977
        put_crlf
1978
        putc    #'P'
1979
        putc    #'A'
1980
        putc    #'S'
1981
        putc    #'S'
1982
        put_crlf
1983
        sjmp    quit
1984
 
1985
test_failed:
1986
        put_crlf
1987
        putc    #'F'
1988
        putc    #'A'
1989
        putc    #'I'
1990
        putc    #'L'
1991
        put_crlf
1992
        sjmp    quit
1993
 
1994
        ;-- End of test program, enter single-instruction endless loop
1995
quit:   ajmp    $
1996
 
1997
 
1998
        ; We'll place a few test routines in the 2nd half of the code space so
1999
        ; we can test long jumps and calls onto different code pages.
2000
        org     8000h
2001
 
2002
        ; tr_sub2: part of the JMP @A+DPTR test.
2003
        ; HAS TO BE in 8000h so we can test the A+DPTR carry propagation!
2004
tr_sub2:
2005
        jmp     tr_rv3
2006
        jmp     tr_c0
2007
        ; Make sure the assumption we'll make in the test is actually valid
2008
        if      LOW(tr_sub2) ne 0
2009
        $error("Label 'tr_sub2' must be at an address multiple of 256 to properly test JMP @A+DPTR")
2010
        endif
2011
 
2012
        ; tr_sub3: part of the LJMP test.
2013
tr_sub3:
2014
        jmp     tr_rv4
2015
        jmp     tr_d0
2016
 
2017
        ; tr_sub1: part of the LCALL test.
2018
tr_sub1:
2019
        mov     A,SP
2020
        cjne    A,#53h,tr_sub1_fail ; ...verify the SP value...
2021
        mov     A,52h               ; ...and verify the pushed ret address
2022
        cjne    A,#LOW(tr_rv1),tr_sub1_fail
2023
        mov     A,53h
2024
        cjne    A,#HIGH(tr_rv1),tr_sub1_fail
2025
        ljmp    tr_rv2
2026
tr_sub1_fail:
2027
        ljmp    tr_b0
2028
 
2029
 
2030
        end

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.