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 13

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

powered by: WebSVN 2.1.0

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