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

Subversion Repositories light52

[/] [light52/] [trunk/] [test/] [cpu_test/] [src/] [tb51_cpu.a51] - Diff between revs 13 and 15

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 13 Rev 15
;-------------------------------------------------------------------------------
;-------------------------------------------------------------------------------
; tb51_cpu.a51 -- MCS51 instruction set test bench.
; tb51_cpu.a51 -- MCS51 instruction set test bench.
;-------------------------------------------------------------------------------
;-------------------------------------------------------------------------------
; This program is meant to verify the basic operation of an MCS51 CPU
; This program is meant to verify the basic operation of an MCS51 CPU
; instruction set implementation.
; instruction set implementation.
; It is far too weak to rely on it exclusively but it can help detect gross
; It is far too weak to rely on it exclusively but it can help detect gross
; implementation errors (overclocked CPUs, timing errors in FPGA cores, that
; implementation errors (overclocked CPUs, timing errors in FPGA cores, that
; kind of thing).
; kind of thing).
;
;
; The program is not yet ready to run on actual hardware (UART interface).
; The program is not yet ready to run on actual hardware (UART interface).
;
;
; For a full verification of the instruction set, an instruction set exerciser
; For a full verification of the instruction set, an instruction set exerciser
; such as 'zexall' for the Z80 would be more suitable. This one is too weak.
; such as 'zexall' for the Z80 would be more suitable. This one is too weak.
;
;
; The program is meant to run in actual hardware or on a simulated environment.
; The program is meant to run in actual hardware or on a simulated environment.
; In the latter case you can use the co-simulation features of the light52
; In the latter case you can use the co-simulation features of the light52
; project to pinpoint bugs.
; project to pinpoint bugs.
;
;
; FIXME add assembly option to run tests in a (possibly infinite) loop.
; FIXME add assembly option to run tests in a (possibly infinite) loop.
;-------------------------------------------------------------------------------
;-------------------------------------------------------------------------------
; Major limitations:
; Major limitations:
;   1.- PSW is not checked for undue changes.
;   1.- PSW is not checked for undue changes.
;   2.- <#imm> instructions are tested with one imm value only.
;   2.- <#imm> instructions are tested with one imm value only.
;   3.-  jumps tested with small values (not near corner values).
;   3.-  jumps tested with small values (not near corner values).
;   4.-  tested on 1 byte only, on 2 bits only.
;   4.-  tested on 1 byte only, on 2 bits only.
;
;
; Note there are too many limitations to list. Use this test bench as a first
; Note there are too many limitations to list. Use this test bench as a first
; approximation only. If your CPU fails this test, it must be dead!
; approximation only. If your CPU fails this test, it must be dead!
;-------------------------------------------------------------------------------
;-------------------------------------------------------------------------------
        ; Include the definitions for the light52 derivative
        ; Include the definitions for the light52 derivative
        $nomod51
        $nomod51
        $include (light52.mcu)
        $include (light52.mcu)
        ;-- Parameters common to all tests -------------------------------------
        ;-- Parameters common to all tests -------------------------------------
dir0    set     060h                ; Address used in direct addressing tests
dir0    set     060h                ; Address used in direct addressing tests
dir1    set     061h                ; Address used in direct addressing tests
dir1    set     061h                ; Address used in direct addressing tests
fail    set     06eh                ; (IDATA) set to 1 upon test failure
fail    set     06eh                ; (IDATA) set to 1 upon test failure
saved_psw set   070h                ; (IDATA) temp store for PSW value
saved_psw set   070h                ; (IDATA) temp store for PSW value
stack0  set     09fh                ; (IDATA) stack addr used for push/pop tests
stack0  set     09fh                ; (IDATA) stack addr used for push/pop tests
        ;-- Macros common to all tests -----------------------------------------
        ;-- Macros common to all tests -----------------------------------------
        ; putc: send character to console (UART)
        ; putc: send character to console (UART)
        ; If you change this macro, make sure it DOES NOT MODIFY PSW!
        ; If you change this macro, make sure it DOES NOT MODIFY PSW!
putc    macro   character
putc    macro   character
        local   putc_loop
        local   putc_loop
putc_loop:
putc_loop:
        ;jnb     SCON.1,putc_loop
        ;jnb     SCON.1,putc_loop
        ;clr     SCON.1
        ;clr     SCON.1
        mov     SBUF,character
        mov     SBUF,character
        endm
        endm
        ; put_crlf: send CR+LF to console
        ; put_crlf: send CR+LF to console
put_crlf macro
put_crlf macro
        putc    #13
        putc    #13
        putc    #10
        putc    #10
        endm
        endm
        ;eot char, label: 'end of test' to be used at the end of all tests.
        ;eot char, label: 'end of test' to be used at the end of all tests.
        ; If you run into this macro it will print character 'char' and
        ; If you run into this macro it will print character 'char' and
        ; continue.
        ; continue.
        ; If you jump to label 'label', it will instead print char '?' and
        ; If you jump to label 'label', it will instead print char '?' and
        ; will set variable 'fail' to 1, then it will continue.
        ; will set variable 'fail' to 1, then it will continue.
eot     macro   char,label
eot     macro   char,label
        local   skip
        local   skip
        putc    #char
        putc    #char
        sjmp    skip
        sjmp    skip
label:  putc    #'?'
label:  putc    #'?'
        mov     fail,#001h
        mov     fail,#001h
skip:
skip:
        endm
        endm
        ;-- Reset & interrupt vectors ------------------------------------------
        ;-- Reset & interrupt vectors ------------------------------------------
        org     00h
        org     00h
        ljmp    start               ; We'll assume LJMP works this far...
        ljmp    start               ; We'll assume LJMP works this far...
        org     03h
        org     03h
        org     0bh
        org     0bh
        org     13h
        org     13h
        org     1bh
        org     1bh
        org     23h
        org     23h
        ;-- Main test program --------------------------------------------------
        ;-- Main test program --------------------------------------------------
        org     30h
        org     30h
start:
start:
        ; Initialize serial port
        ; Initialize serial port
        ;(leave it with the default configuration: 19200-8-N-1)
        ;(leave it with the default configuration: 19200-8-N-1)
        ;mov     TMOD,#20h           ; C/T = 0, Mode = 2
        ;mov     TMOD,#20h           ; C/T = 0, Mode = 2
        ;mov     TH1,#0fdh           ; 9600 bauds @11.xxx MHz
        ;mov     TH1,#0fdh           ; 9600 bauds @11.xxx MHz
        ;mov     TCON,#40h           ; Enable T1
        ;mov     TCON,#40h           ; Enable T1
        ;mov     SCON,#52h           ; 8/N/1, TI enabled
        ;mov     SCON,#52h           ; 8/N/1, TI enabled
        ; Clear failure flag
        ; Clear failure flag
        mov     fail,#000h
        mov     fail,#000h
        ;-- Test series A ------------------------------------------------------
        ;-- Test series A ------------------------------------------------------
        ; Test the basic opcodes needed in later tests:
        ; Test the basic opcodes needed in later tests:
        ; a.- Serial port initialization is OK
        ; a.- Serial port initialization is OK
        ; a.- Bootstrap instructions work as used
        ; a.- Bootstrap instructions work as used
        ; b.-  (small positive rel only)
        ; b.-  (small positive rel only)
        ; c.- ACC can be loaded with direct mode addressing (as an SFR)
        ; c.- ACC can be loaded with direct mode addressing (as an SFR)
        ; c.- 
        ; c.- 
        ; d.-  (small positive rel only)
        ; d.-  (small positive rel only)
        ; e.- 
        ; e.- 
        ; Note that one instance of LJMP has been tested too.
        ; Note that one instance of LJMP has been tested too.
        putc    #'A'                ; start of test series
        putc    #'A'                ; start of test series
        ; If we arrive here at all, and you see the chars in the
        ; If we arrive here at all, and you see the chars in the
        ; terminal, the A.a test has passed
        ; terminal, the A.a test has passed
        putc    #'a'
        putc    #'a'
        sjmp    ta_b0               ;  with very small positive rel
        sjmp    ta_b0               ;  with very small positive rel
        putc    #'?'
        putc    #'?'
        mov     fail,#001h
        mov     fail,#001h
ta_b0:  putc    #'b'
ta_b0:  putc    #'b'
ta_c0:  sjmp    ta_c1
ta_c0:  sjmp    ta_c1
ta_c3:  putc    #'c'
ta_c3:  putc    #'c'
        sjmp    ta_c4
        sjmp    ta_c4
ta_c1:  mov     0e0h,#5ah           ; load A as SFR
ta_c1:  mov     0e0h,#5ah           ; load A as SFR
        cjne    a,#5ah,ta_c3        ; test cjne with == args...
        cjne    a,#5ah,ta_c3        ; test cjne with == args...
        cjne    a,#7ah,ta_c2        ; ...with != args, rel>0...
        cjne    a,#7ah,ta_c2        ; ...with != args, rel>0...
        putc    #'?'
        putc    #'?'
        mov     fail,#001h
        mov     fail,#001h
ta_c2:  cjne    a,#7ah,ta_c3        ; ...and with != args, rel<0
ta_c2:  cjne    a,#7ah,ta_c3        ; ...and with != args, rel<0
        putc    #'?'
        putc    #'?'
        mov     fail,#001h
        mov     fail,#001h
ta_c4:
ta_c4:
        mov     dir0,#02h
        mov     dir0,#02h
        djnz    dir0,ta_d1
        djnz    dir0,ta_d1
        putc    #'?'
        putc    #'?'
        mov     fail,#001h
        mov     fail,#001h
ta_d1:  djnz    dir0,ta_d2
ta_d1:  djnz    dir0,ta_d2
        eot     'd',ta_d2
        eot     'd',ta_d2
        mov     dir0,#0a5h          ; test mov a,dir
        mov     dir0,#0a5h          ; test mov a,dir
        mov     a,dir0
        mov     a,dir0
        cjne    a,#0a5h,ta_e1
        cjne    a,#0a5h,ta_e1
        eot     'e',ta_e1
        eot     'e',ta_e1
        put_crlf                    ; end of test series
        put_crlf                    ; end of test series
        ;-- Test series B ------------------------------------------------------
        ;-- Test series B ------------------------------------------------------
        ; Test CJNE plus a few aux opcodes
        ; Test CJNE plus a few aux opcodes
        ; a.- 
        ; a.- 
        ; a.- 
        ; a.- 
        ; b.- , 
        ; b.- , 
        ; c.- 
        ; c.- 
        ; d.- , , 
        ; d.- , , 
        ; e.- 
        ; e.- 
        ; f.- 
        ; f.- 
        ; g.- 
        ; g.- 
 
        ; h.-  with SFR direct address
 
 
        putc    #'B'                ; start of test series
        putc    #'B'                ; start of test series
tb_ma   macro   reg,val
tb_ma   macro   reg,val
        mov     reg,val
        mov     reg,val
        mov     a,reg
        mov     a,reg
        cjne    a,val,tb_a1
        cjne    a,val,tb_a1
        endm
        endm
        tb_ma   r0,#081h
        tb_ma   r0,#081h
        tb_ma   r1,#043h
        tb_ma   r1,#043h
        tb_ma   r2,#027h
        tb_ma   r2,#027h
        tb_ma   r3,#0c2h
        tb_ma   r3,#0c2h
        tb_ma   r4,#0f1h
        tb_ma   r4,#0f1h
        tb_ma   r5,#004h
        tb_ma   r5,#004h
        tb_ma   r6,#092h
        tb_ma   r6,#092h
        tb_ma   r7,#01fh
        tb_ma   r7,#01fh
        eot     'a',tb_a1
        eot     'a',tb_a1
        mov     PSW,#80h            ; , 
        mov     PSW,#80h            ; , 
        jc      tb_b0
        jc      tb_b0
        putc    #'?'
        putc    #'?'
        mov     fail,#001h
        mov     fail,#001h
tb_b0:  jnc     tb_b1
tb_b0:  jnc     tb_b1
        mov     PSW,#00h
        mov     PSW,#00h
        jc      tb_b1
        jc      tb_b1
        jnc     tb_b2
        jnc     tb_b2
tb_b1:  putc    #'?'
tb_b1:  putc    #'?'
        mov     fail,#001h
        mov     fail,#001h
tb_b2:  putc    #'b'
tb_b2:  putc    #'b'
tb_mc   macro   reg,val
tb_mc   macro   reg,val
        local   tb_mc0
        local   tb_mc0
        local   tb_mc1
        local   tb_mc1
        mov     reg,val+1
        mov     reg,val+1
        cjne    reg,val,tb_mc0
        cjne    reg,val,tb_mc0
        putc    #'?'
        putc    #'?'
        mov     fail,#001h
        mov     fail,#001h
tb_mc1: mov     reg,val
tb_mc1: mov     reg,val
tb_mc0: cjne    reg,val,tb_mc1
tb_mc0: cjne    reg,val,tb_mc1
        endm
        endm
        tb_mc   r0,#091h            ; first test the jumps for all Rn regs
        tb_mc   r0,#091h            ; first test the jumps for all Rn regs
        tb_mc   r1,#0a2h
        tb_mc   r1,#0a2h
        tb_mc   r2,#0b3h
        tb_mc   r2,#0b3h
        tb_mc   r3,#0c4h
        tb_mc   r3,#0c4h
        tb_mc   r4,#0d5h
        tb_mc   r4,#0d5h
        tb_mc   r5,#0e6h
        tb_mc   r5,#0e6h
        tb_mc   r6,#0f7h
        tb_mc   r6,#0f7h
        tb_mc   r7,#008h
        tb_mc   r7,#008h
tb_c0:  mov     PSW,#00h            ; now test the C flag with a single Rn reg
tb_c0:  mov     PSW,#00h            ; now test the C flag with a single Rn reg
        mov     r0,#034h
        mov     r0,#034h
        cjne    r0,#035h,tb_c1
        cjne    r0,#035h,tb_c1
tb_c1:  jnc     tb_c2
tb_c1:  jnc     tb_c2
        cjne    r0,#034h,tb_c3
        cjne    r0,#034h,tb_c3
tb_c3:  jc      tb_c2
tb_c3:  jc      tb_c2
        cjne    r0,#033h,tb_c4
        cjne    r0,#033h,tb_c4
tb_c4:  jc      tb_c2
tb_c4:  jc      tb_c2
        eot     'c',tb_c2
        eot     'c',tb_c2
        mov     PSW,#80h            ; test C set, reset and complement
        mov     PSW,#80h            ; test C set, reset and complement
        clr     c
        clr     c
        jc      tb_d0
        jc      tb_d0
        setb    c
        setb    c
        jnc     tb_d0
        jnc     tb_d0
        cpl     c
        cpl     c
        jc      tb_d0
        jc      tb_d0
        eot     'd',tb_d0
        eot     'd',tb_d0
tb_me   macro   reg
tb_me   macro   reg
        mov     reg,#dir0
        mov     reg,#dir0
        mov     dir0,#12h
        mov     dir0,#12h
        mov     a,dir0
        mov     a,dir0
        cjne    a,#012h,tb_e0
        cjne    a,#012h,tb_e0
        mov     @reg,#0f5h
        mov     @reg,#0f5h
        mov     a,dir0
        mov     a,dir0
        cjne    a,#0f5h,tb_e0
        cjne    a,#0f5h,tb_e0
        endm
        endm
        tb_me   r0                  ; test  with both regs
        tb_me   r0                  ; test  with both regs
        tb_me   r1
        tb_me   r1
        eot     'e',tb_e0
        eot     'e',tb_e0
tb_mf   macro   reg,val
tb_mf   macro   reg,val
        local   tb_mf0
        local   tb_mf0
        local   tb_mf1
        local   tb_mf1
        mov     reg,#30h
        mov     reg,#30h
        mov     @reg,val+1
        mov     @reg,val+1
        cjne    @reg,val,tb_mf0
        cjne    @reg,val,tb_mf0
        putc    #'?'
        putc    #'?'
        mov     fail,#001h
        mov     fail,#001h
tb_mf1: mov     @reg,val
tb_mf1: mov     @reg,val
tb_mf0: cjne    @reg,val,tb_mf1
tb_mf0: cjne    @reg,val,tb_mf1
        endm
        endm
        tb_mf   r0,#12h
        tb_mf   r0,#12h
        tb_mf   r1,#34h
        tb_mf   r1,#34h
tb_f0:  mov     r0,#30h             ; now test the C flag with a single Rn reg
tb_f0:  mov     r0,#30h             ; now test the C flag with a single Rn reg
        clr     c
        clr     c
        mov     @r0,#034h
        mov     @r0,#034h
        cjne    @r0,#035h,tb_f1
        cjne    @r0,#035h,tb_f1
tb_f1:  jnc     tb_f2
tb_f1:  jnc     tb_f2
        cjne    @r0,#034h,tb_f3
        cjne    @r0,#034h,tb_f3
tb_f3:  jc      tb_f2
tb_f3:  jc      tb_f2
        cjne    @r0,#033h,tb_f4
        cjne    @r0,#033h,tb_f4
tb_f4:  jc      tb_f2
tb_f4:  jc      tb_f2
        eot     'f',tb_f2
        eot     'f',tb_f2
 
 
        mov     dir0,#0c0h
        mov     dir0,#0c0h          ; CJNE A,dir,rel targetting an IRAM location
        mov     031h,#0c1h
        mov     031h,#0c1h
        mov     032h,#0c2h
        mov     032h,#0c2h
        clr     c
        clr     c
        mov     a,#0c1h
        mov     a,#0c1h
        cjne    a,031h,tb_g0
        cjne    a,031h,tb_g0
        jc      tb_g0
        jc      tb_g0
        cjne    a,032h,tb_g1
        cjne    a,032h,tb_g1
        putc    #'?'
        putc    #'?'
        mov     fail,#001h
        mov     fail,#001h
tb_g1:  jnc     tb_g0
tb_g1:  jnc     tb_g0
        cjne    a,dir0,tb_g2
        cjne    a,dir0,tb_g2
        putc    #'$'
        putc    #'$'
        mov     fail,#001h
        mov     fail,#001h
tb_g2:  jc      tb_g0
tb_g2:  jc      tb_g0
        eot     'g',tb_g0
        eot     'g',tb_g0
 
 
 
        mov     dir0,#0c0h          ; CJNE A,dir,rel targetting an SFR location
 
        mov     B,#0c1h
 
        mov     032h,#0c2h
 
        clr     c
 
        mov     a,#0c1h
 
        mov     r0,#42h
 
        cjne    a,B,tb_h0
 
        jc      tb_h0
 
        cjne    a,032h,tb_h1
 
        putc    #'?'
 
        mov     fail,#001h
 
tb_h1:  jnc     tb_h0
 
        cjne    a,dir0,tb_h2
 
        putc    #'$'
 
        mov     fail,#001h
 
tb_h2:  jc      tb_h0
 
 
 
        eot     'h',tb_h0
 
 
        put_crlf                    ; end of test series
        put_crlf                    ; end of test series
        ;-- Test series C ------------------------------------------------------
        ;-- Test series C ------------------------------------------------------
        ; Bit operations and the rest of the conditional rel jumps
        ; Bit operations and the rest of the conditional rel jumps
        ; The following tests will use a bit address within the IRAM
        ; The following tests will use a bit address within the IRAM
        ; a.- , 
        ; a.- , 
        ; b.- 
        ; b.- 
        ; c.- , 
        ; c.- , 
        ; d.- , 
        ; d.- , 
        ; e.- , 
        ; e.- , 
        ; e.- , 
        ; e.- , 
        ; f.- , 
        ; f.- , 
        ; g.- 
        ; g.- 
        ; h.- 
        ; h.- 
        ; The following tests are the same as above except a bit address within
        ; The following tests are the same as above except a bit address within
        ; SFR B is used.
        ; SFR B is used.
        ; i.- , 
        ; i.- , 
        ; j.- , 
        ; j.- , 
        ; k.- , 
        ; k.- , 
        ; k.- , 
        ; k.- , 
        ; l.- , 
        ; l.- , 
        ; m.- 
        ; m.- 
        ; n.- 
        ; n.- 
        putc    #'C'                ; start of test series
        putc    #'C'                ; start of test series
        mov     02fh,#80h           ; We'll be testing bits 2F.7 and 2F.6
        mov     02fh,#80h           ; We'll be testing bits 2F.7 and 2F.6
        sjmp    tc_a0
        sjmp    tc_a0
tc_a1:  jnb     07fh,tc_a3          ; JNB jumps not on bit set
tc_a1:  jnb     07fh,tc_a3          ; JNB jumps not on bit set
        jnb     07eh,tc_a2          ; JNB jumps on bit clear
        jnb     07eh,tc_a2          ; JNB jumps on bit clear
        putc    #'?'
        putc    #'?'
        mov     fail,#001h
        mov     fail,#001h
        sjmp    tc_a3
        sjmp    tc_a3
tc_a0:  jb      07fh,tc_a1          ; JB jumps on bit set
tc_a0:  jb      07fh,tc_a1          ; JB jumps on bit set
        putc    #'!'
        putc    #'!'
        mov     fail,#001h
        mov     fail,#001h
tc_a2:  jb      07eh,tc_a3          ; JB jumps not on bit clear
tc_a2:  jb      07eh,tc_a3          ; JB jumps not on bit clear
        eot     'a',tc_a3
        eot     'a',tc_a3
        mov     0e0h,#079h          ; init acc (as sfr) with some data
        mov     0e0h,#079h          ; init acc (as sfr) with some data
        cjne    a,#079h,tc_b1
        cjne    a,#079h,tc_b1
        mov     a,#05ah             ; now load a with imm data...
        mov     a,#05ah             ; now load a with imm data...
        cjne    a,#05ah,tc_b1       ; ...and make sure a got the data
        cjne    a,#05ah,tc_b1       ; ...and make sure a got the data
        eot     'b',tc_b1
        eot     'b',tc_b1
        mov     a,#80h
        mov     a,#80h
        sjmp    tc_c0
        sjmp    tc_c0
tc_c1:  jz      tc_c3               ; JZ jumps not on acc!=0
tc_c1:  jz      tc_c3               ; JZ jumps not on acc!=0
        mov     a,#00h
        mov     a,#00h
        jz      tc_c2               ; JZ jumps on acc==0
        jz      tc_c2               ; JZ jumps on acc==0
        putc    #'?'
        putc    #'?'
        mov     fail,#001h
        mov     fail,#001h
        sjmp    tc_c3
        sjmp    tc_c3
tc_c0:  jnz     tc_c1               ; JNZ jumps on acc!=0
tc_c0:  jnz     tc_c1               ; JNZ jumps on acc!=0
        putc    #'!'
        putc    #'!'
        mov     fail,#001h
        mov     fail,#001h
tc_c2:  jnz     tc_c3               ; JNZ jumps not on acc==0
tc_c2:  jnz     tc_c3               ; JNZ jumps not on acc==0
        eot     'c',tc_c3
        eot     'c',tc_c3
        mov     02fh,#80h           ; We'll be testing bit 2F.7
        mov     02fh,#80h           ; We'll be testing bit 2F.7
        jb      07fh,tc_d1
        jb      07fh,tc_d1
        sjmp    tc_d0
        sjmp    tc_d0
tc_d1:  clr     07fh
tc_d1:  clr     07fh
        jb      07fh,tc_d0
        jb      07fh,tc_d0
        cpl     07fh
        cpl     07fh
        jnb     07fh,tc_d0
        jnb     07fh,tc_d0
        eot     'd',tc_d0
        eot     'd',tc_d0
        mov     02eh,#08h           ; We'll be testing bits 2E.3 and 2E.2
        mov     02eh,#08h           ; We'll be testing bits 2E.3 and 2E.2
        clr     c
        clr     c
        anl     c,073h              ; Test ANL in all 4 input combinations
        anl     c,073h              ; Test ANL in all 4 input combinations
        jc      tc_e0
        jc      tc_e0
        setb    c
        setb    c
        anl     c,073h
        anl     c,073h
        jnc     tc_e0
        jnc     tc_e0
        anl     c,/072h
        anl     c,/072h
        jnc     tc_e0
        jnc     tc_e0
                                    ; CY == 1
                                    ; CY == 1
        orl     c,073h              ; ORL-ing with 1 should give 1
        orl     c,073h              ; ORL-ing with 1 should give 1
        jnc     tc_e0
        jnc     tc_e0
        orl     c,072h
        orl     c,072h
        jnc     tc_e0
        jnc     tc_e0
        clr     c                   ; CY == 0
        clr     c                   ; CY == 0
        orl     c,073h              ; Now ORL c, 'bit' should give 'bit'
        orl     c,073h              ; Now ORL c, 'bit' should give 'bit'
        jnc     tc_e0
        jnc     tc_e0
        orl     c,/072h
        orl     c,/072h
        jnc     tc_e0
        jnc     tc_e0
        eot     'e',tc_e0
        eot     'e',tc_e0
        mov     02eh,#08h           ; We'll be testing bits 2E.3 and 2E.2
        mov     02eh,#08h           ; We'll be testing bits 2E.3 and 2E.2
        clr     c
        clr     c
        mov     c,073h
        mov     c,073h
        jnc     tc_f0
        jnc     tc_f0
        mov     c,072h
        mov     c,072h
        jc      tc_f0
        jc      tc_f0
        clr     c
        clr     c
        mov     071h,c
        mov     071h,c
        jb      071h,tc_f0
        jb      071h,tc_f0
        setb    c
        setb    c
        mov     071h,c
        mov     071h,c
        jnb     071h,tc_f0
        jnb     071h,tc_f0
        eot     'f',tc_f0
        eot     'f',tc_f0
        mov     02eh,#00h           ; We'll be testing bits 2E.3 and 2E.2
        mov     02eh,#00h           ; We'll be testing bits 2E.3 and 2E.2
        setb    073h
        setb    073h
        mov     c,073h
        mov     c,073h
        jnc     tc_g0
        jnc     tc_g0
        setb    072h
        setb    072h
        mov     c,072h
        mov     c,072h
        jnc     tc_g0
        jnc     tc_g0
        eot     'g',tc_g0
        eot     'g',tc_g0
        ; (better read the following code in execution order)
        ; (better read the following code in execution order)
        mov     02eh,#08h           ; We'll be testing bits 2E.3 and 2E.2
        mov     02eh,#08h           ; We'll be testing bits 2E.3 and 2E.2
        sjmp    tc_h1               ; jump forward so we can test jump backwards
        sjmp    tc_h1               ; jump forward so we can test jump backwards
tc_h2:  mov     c,073h              ; make sure the target bit is clear
tc_h2:  mov     c,073h              ; make sure the target bit is clear
        jc      tc_h0
        jc      tc_h0
        jbc     072h,tc_h0          ; JBC jumps not when target bit clear
        jbc     072h,tc_h0          ; JBC jumps not when target bit clear
        sjmp    tc_h3
        sjmp    tc_h3
tc_h1:  jbc     073h,tc_h2          ; JBC jumps when target bit set
tc_h1:  jbc     073h,tc_h2          ; JBC jumps when target bit set
        sjmp    tc_h0
        sjmp    tc_h0
tc_h3:
tc_h3:
        eot     'h',tc_h0
        eot     'h',tc_h0
        mov     02fh,#00h
        mov     02fh,#00h
        mov     B,#80h              ; We'll be testing bits B.7 and B.6
        mov     B,#80h              ; We'll be testing bits B.7 and B.6
        sjmp    tc_i0
        sjmp    tc_i0
tc_i1:  jnb     B.7,tc_i3           ; JNB jumps not on bit set
tc_i1:  jnb     B.7,tc_i3           ; JNB jumps not on bit set
        jnb     B.6,tc_i2           ; JNB jumps on bit clear
        jnb     B.6,tc_i2           ; JNB jumps on bit clear
        putc    #'?'
        putc    #'?'
        mov     fail,#001h
        mov     fail,#001h
        sjmp    tc_i3
        sjmp    tc_i3
tc_i0:  jb      B.7,tc_i1           ; JB jumps on bit set
tc_i0:  jb      B.7,tc_i1           ; JB jumps on bit set
        putc    #'!'
        putc    #'!'
        mov     fail,#001h
        mov     fail,#001h
tc_i2:  jb      B.6,tc_i3           ; JB jumps not on bit clear
tc_i2:  jb      B.6,tc_i3           ; JB jumps not on bit clear
        eot     'i',tc_i3
        eot     'i',tc_i3
        mov     B,#80h              ; We'll be testing bit B.7
        mov     B,#80h              ; We'll be testing bit B.7
        jb      B.7,tc_j1
        jb      B.7,tc_j1
        sjmp    tc_j0
        sjmp    tc_j0
tc_j1:  clr     B.7
tc_j1:  clr     B.7
        jb      B.7,tc_j0
        jb      B.7,tc_j0
        cpl     B.7
        cpl     B.7
        jnb     B.7,tc_j0
        jnb     B.7,tc_j0
        eot     'j',tc_j0
        eot     'j',tc_j0
        mov     B,#08h              ; We'll be testing bits B.3 and B.2
        mov     B,#08h              ; We'll be testing bits B.3 and B.2
        clr     c
        clr     c
        anl     c,B.3               ; Test ANL in all 4 input combinations
        anl     c,B.3               ; Test ANL in all 4 input combinations
        jc      tc_k0
        jc      tc_k0
        setb    c
        setb    c
        anl     c,B.3
        anl     c,B.3
        jnc     tc_k0
        jnc     tc_k0
        anl     c,/B.2
        anl     c,/B.2
        jnc     tc_k0
        jnc     tc_k0
                                    ; CY == 1
                                    ; CY == 1
        orl     c,B.3               ; ORL-ing with 1 should give 1
        orl     c,B.3               ; ORL-ing with 1 should give 1
        jnc     tc_k0
        jnc     tc_k0
        orl     c,B.2
        orl     c,B.2
        jnc     tc_k0
        jnc     tc_k0
        clr     c                   ; CY == 0
        clr     c                   ; CY == 0
        orl     c,B.3               ; Now ORL c, 'bit' should give 'bit'
        orl     c,B.3               ; Now ORL c, 'bit' should give 'bit'
        jnc     tc_k0
        jnc     tc_k0
        orl     c,/B.2
        orl     c,/B.2
        jnc     tc_k0
        jnc     tc_k0
        eot     'k',tc_k0
        eot     'k',tc_k0
        mov     B,#08h              ; We'll be testing bits B.3, B.2 and B.1
        mov     B,#08h              ; We'll be testing bits B.3, B.2 and B.1
        clr     c
        clr     c
        mov     c,B.3
        mov     c,B.3
        jnc     tc_L0
        jnc     tc_L0
        mov     c,B.2
        mov     c,B.2
        jc      tc_L0
        jc      tc_L0
        clr     c
        clr     c
        mov     B.1,c
        mov     B.1,c
        jb      B.1,tc_L0
        jb      B.1,tc_L0
        setb    c
        setb    c
        mov     B.1,c
        mov     B.1,c
        jnb     B.1,tc_L0
        jnb     B.1,tc_L0
        eot     'l',tc_L0
        eot     'l',tc_L0
        mov     02eh,#00h           ; We'll be testing bits B.3 and B.2
        mov     02eh,#00h           ; We'll be testing bits B.3 and B.2
        setb    B.3
        setb    B.3
        mov     c,B.3
        mov     c,B.3
        jnc     tc_m0
        jnc     tc_m0
        setb    B.2
        setb    B.2
        mov     c,B.2
        mov     c,B.2
        jnc     tc_m0
        jnc     tc_m0
        eot     'm',tc_m0
        eot     'm',tc_m0
        ; (better read the following code in execution order)
        ; (better read the following code in execution order)
        mov     B,#08h              ; We'll be testing bits B.3 and B.2
        mov     B,#08h              ; We'll be testing bits B.3 and B.2
        sjmp    tc_n1               ; jump forward so we can test jump backwards
        sjmp    tc_n1               ; jump forward so we can test jump backwards
tc_n2:  mov     c,B.3               ; make sure the target bit is clear
tc_n2:  mov     c,B.3               ; make sure the target bit is clear
        jc      tc_n0
        jc      tc_n0
        jbc     B.2,tc_n0           ; JBC jumps not when target bit clear
        jbc     B.2,tc_n0           ; JBC jumps not when target bit clear
        sjmp    tc_n3
        sjmp    tc_n3
tc_n1:  jbc     B.3,tc_n2           ; JBC jumps when target bit set
tc_n1:  jbc     B.3,tc_n2           ; JBC jumps when target bit set
        sjmp    tc_n0
        sjmp    tc_n0
tc_n3:
tc_n3:
        eot     'n',tc_n0
        eot     'n',tc_n0
        put_crlf                    ; end of test series
        put_crlf                    ; end of test series
        ;-- Test series D ------------------------------------------------------
        ;-- Test series D ------------------------------------------------------
        ;
        ;
        ; a.- 
        ; a.- 
        ; b.- 
        ; b.- 
        ; c.- 
        ; c.- 
        ; d.- , 
        ; d.- , 
        ;
        ;
        ; This test executes a few NOPs too but does NOT check for unintended
        ; This test executes a few NOPs too but does NOT check for unintended
        ; side effects; we intersperse the nops between the other tests to at
        ; side effects; we intersperse the nops between the other tests to at
        ; least have a chance to catch buggy behavior but that's all.
        ; least have a chance to catch buggy behavior but that's all.
        putc    #'D'                ; start of test series
        putc    #'D'                ; start of test series
        mov     a,#085h             ; test XRL A,#imm before using it in
        mov     a,#085h             ; test XRL A,#imm before using it in
        xrl     a,#044h             ; subsequent tests
        xrl     a,#044h             ; subsequent tests
        jz      td_a0
        jz      td_a0
        xrl     a,#0c1h
        xrl     a,#0c1h
        jnz     td_a0
        jnz     td_a0
        eot     'a',td_a0
        eot     'a',td_a0
        mov     a,#085h             ; Test RLC effects on ACC, ignore CY for now
        mov     a,#085h             ; Test RLC effects on ACC, ignore CY for now
        nop
        nop
        clr     c
        clr     c
        rlc     a                   ; a = (a << 1) | 0
        rlc     a                   ; a = (a << 1) | 0
        mov     dir0,a
        mov     dir0,a
        xrl     a,#00ah             ; We can't use CJNE because it modifies CY
        xrl     a,#00ah             ; We can't use CJNE because it modifies CY
        jnz     td_b0               ; check shifted acc
        jnz     td_b0               ; check shifted acc
        mov     a,dir0
        mov     a,dir0
        rlc     a                   ; rotate again...
        rlc     a                   ; rotate again...
        xrl     a,#015h             ; ...and check shifted acc with CY at bit 0
        xrl     a,#015h             ; ...and check shifted acc with CY at bit 0
        jnz     td_b0
        jnz     td_b0
        mov     a,#085h             ; Now check RLC effects on CY
        mov     a,#085h             ; Now check RLC effects on CY
        nop
        nop
        clr     c
        clr     c
        rlc     a
        rlc     a
        jnc     td_b0
        jnc     td_b0
        rlc     a
        rlc     a
        jc      td_b0               ; CY==1 moved into ACC.0
        jc      td_b0               ; CY==1 moved into ACC.0
        eot     'b',td_b0
        eot     'b',td_b0
        mov     a,#085h             ; Test RRC effects on ACC, ignore CY for now
        mov     a,#085h             ; Test RRC effects on ACC, ignore CY for now
        clr     c
        clr     c
        rrc     a                   ; will set CY
        rrc     a                   ; will set CY
        mov     dir0,a
        mov     dir0,a
        nop
        nop
        xrl     a,#042h             ; We can't use CJNE because it modifies CY
        xrl     a,#042h             ; We can't use CJNE because it modifies CY
        jnz     td_c0               ; check shifted acc
        jnz     td_c0               ; check shifted acc
        mov     a,dir0
        mov     a,dir0
        rrc     a                   ; rotate again...
        rrc     a                   ; rotate again...
        xrl     a,#0a1h             ; ...and check shifted acc with CY at bit 7
        xrl     a,#0a1h             ; ...and check shifted acc with CY at bit 7
        jnz     td_c0
        jnz     td_c0
        mov     a,#085h             ; Now check RRC effects on CY
        mov     a,#085h             ; Now check RRC effects on CY
        clr     c
        clr     c
        rrc     a
        rrc     a
        jnc     td_c0
        jnc     td_c0
        rrc     a
        rrc     a
        jc      td_c0               ; CY==1 moved into ACC.0
        jc      td_c0               ; CY==1 moved into ACC.0
        eot     'c',td_c0
        eot     'c',td_c0
        mov     a,#085h             ; Test RL effects on ACC, ignore CY for now
        mov     a,#085h             ; Test RL effects on ACC, ignore CY for now
        clr     c
        clr     c
        rl      a                   ; a = (a << 1) | 0
        rl      a                   ; a = (a << 1) | 0
        mov     dir0,a
        mov     dir0,a
        xrl     a,#00bh             ; We can't use CJNE because it modifies CY
        xrl     a,#00bh             ; We can't use CJNE because it modifies CY
        jnz     td_d0               ; check shifted acc
        jnz     td_d0               ; check shifted acc
        mov     a,dir0
        mov     a,dir0
        setb    c
        setb    c
        rl      a                   ; rotate again...
        rl      a                   ; rotate again...
        xrl     a,#016h             ; ...and check shifted acc with CY at bit 0
        xrl     a,#016h             ; ...and check shifted acc with CY at bit 0
        jnz     td_d0
        jnz     td_d0
        mov     a,#085h             ; Test RR effects on ACC, ignore CY for now
        mov     a,#085h             ; Test RR effects on ACC, ignore CY for now
        clr     c
        clr     c
        rr      a                   ; will set CY
        rr      a                   ; will set CY
        mov     dir0,a
        mov     dir0,a
        xrl     a,#0c2h             ; We can't use CJNE because it modifies CY
        xrl     a,#0c2h             ; We can't use CJNE because it modifies CY
        jnz     td_d0               ; check shifted acc
        jnz     td_d0               ; check shifted acc
        mov     a,dir0
        mov     a,dir0
        rr      a                   ; rotate again...
        rr      a                   ; rotate again...
        xrl     a,#061h             ; ...and check shifted acc with CY at bit 7
        xrl     a,#061h             ; ...and check shifted acc with CY at bit 7
        jnz     td_d0
        jnz     td_d0
        mov     a,#0ffh             ; Now make sure RL and RR don't touch CY
        mov     a,#0ffh             ; Now make sure RL and RR don't touch CY
        clr     c
        clr     c
        rl      a
        rl      a
        jc      td_d0
        jc      td_d0
        rr      a
        rr      a
        rr      a
        rr      a
        jc      td_d0
        jc      td_d0
        eot     'd',td_d0
        eot     'd',td_d0
        put_crlf                    ; end of test series
        put_crlf                    ; end of test series
        ;-- Test series E ------------------------------------------------------
        ;-- Test series E ------------------------------------------------------
        ; Increment
        ; Increment
        ; a.- 
        ; a.- 
        ; b.- 
        ; b.- 
        ; c.- 
        ; c.- 
        ; d.- 
        ; d.- 
        ; e.- 
        ; e.- 
        ; f.- 
        ; f.- 
        ; g.- 
        ; g.- 
        ; h.- 
        ; h.- 
        ; i.- 
        ; i.- 
        putc    #'E'                ; start of test series
        putc    #'E'                ; start of test series
te_ma   macro   target, error_loc
te_ma   macro   target, error_loc
        mov     target,#080h
        mov     target,#080h
        inc     target
        inc     target
        cjne    target,#081h,error_loc
        cjne    target,#081h,error_loc
        mov     target,#0ffh
        mov     target,#0ffh
        clr     c
        clr     c
        inc     target
        inc     target
        jc      error_loc
        jc      error_loc
        cjne    target,#000h,error_loc
        cjne    target,#000h,error_loc
        endm
        endm
        te_ma   a,te_a0             ; Test 
        te_ma   a,te_a0             ; Test 
        eot     'a',te_a0
        eot     'a',te_a0
        mov     r0,#066h
        mov     r0,#066h
        te_ma   r0,te_b0
        te_ma   r0,te_b0
        te_ma   r1,te_b0
        te_ma   r1,te_b0
        te_ma   r2,te_b0
        te_ma   r2,te_b0
        te_ma   r3,te_b0
        te_ma   r3,te_b0
        te_ma   r4,te_b0
        te_ma   r4,te_b0
        te_ma   r5,te_b0
        te_ma   r5,te_b0
        te_ma   r6,te_b0
        te_ma   r6,te_b0
        te_ma   r7,te_b0
        te_ma   r7,te_b0
        eot     'b',te_b0
        eot     'b',te_b0
        mov     r0,#dir0
        mov     r0,#dir0
        mov     r1,#031h
        mov     r1,#031h
        te_ma   @r0,te_c0
        te_ma   @r0,te_c0
        te_ma   @r1,te_c0
        te_ma   @r1,te_c0
        eot     'c',te_c0
        eot     'c',te_c0
        mov     dir0,#034h          ; Test  before using it in
        mov     dir0,#034h          ; Test  before using it in
        mov     a,dir0              ; subsequent tests
        mov     a,dir0              ; subsequent tests
        cjne    a,#034h,te_d0
        cjne    a,#034h,te_d0
        eot     'd',te_d0
        eot     'd',te_d0
 
 
        mov     039h,#080h
        mov     039h,#080h          ; Test  with IRAM address...
        inc     039h
        inc     039h
        mov     a,039h
        mov     a,039h
        cjne    a,#081h,te_e0
        cjne    a,#081h,te_e0
        mov     039h,#0ffh
        mov     039h,#0ffh
        clr     c
        clr     c
        inc     039h
        inc     039h
        jc      te_e0
        jc      te_e0
        mov     a,039h
        mov     a,039h
        cjne    a,#000h,te_e0
        cjne    a,#000h,te_e0
 
 
 
        mov     B,#080h             ; ...and  with SFR address
 
        inc     B
 
        mov     a,B
 
        cjne    a,#081h,te_e0
 
        mov     B,#0ffh
 
        clr     c
 
        inc     B
 
        jc      te_e0
 
        mov     a,B
 
        cjne    a,#000h,te_e0
 
 
 
 
        eot     'e',te_e0
        eot     'e',te_e0
te_mf   macro   target, error_loc
te_mf   macro   target, error_loc
        mov     target,#001h
        mov     target,#001h
        dec     target
        dec     target
        cjne    target,#000h,error_loc
        cjne    target,#000h,error_loc
        clr     c
        clr     c
        dec     target
        dec     target
        jc      error_loc
        jc      error_loc
        cjne    target,#0ffh,error_loc
        cjne    target,#0ffh,error_loc
        endm
        endm
        te_mf   a,te_f0             ; Test 
        te_mf   a,te_f0             ; Test 
        eot     'f',te_f0
        eot     'f',te_f0
        mov     r0,#066h
        mov     r0,#066h
        te_mf   r0,te_g0
        te_mf   r0,te_g0
        te_mf   r1,te_g0
        te_mf   r1,te_g0
        te_mf   r2,te_g0
        te_mf   r2,te_g0
        te_mf   r3,te_g0
        te_mf   r3,te_g0
        te_mf   r4,te_g0
        te_mf   r4,te_g0
        te_mf   r5,te_g0
        te_mf   r5,te_g0
        te_mf   r6,te_g0
        te_mf   r6,te_g0
        te_mf   r7,te_g0
        te_mf   r7,te_g0
        eot     'g',te_g0
        eot     'g',te_g0
        mov     r0,#dir0
        mov     r0,#dir0
        mov     r1,#031h
        mov     r1,#031h
        te_mf   @r0,te_h0
        te_mf   @r0,te_h0
        te_mf   @r1,te_h0
        te_mf   @r1,te_h0
        eot     'h',te_h0
        eot     'h',te_h0
 
 
        mov     039h,#001h
        mov     039h,#001h          ; Test  with IRAM address...
        dec     039h
        dec     039h
        mov     a,039h
        mov     a,039h
        cjne    a,#00h,te_i0
        cjne    a,#00h,te_i0
        mov     039h,#000h
        mov     039h,#000h
        clr     c
        clr     c
        dec     039h
        dec     039h
        jc      te_i0
        jc      te_i0
        mov     a,039h
        mov     a,039h
        cjne    a,#0ffh,te_i0
        cjne    a,#0ffh,te_i0
 
 
 
        mov     B,#001h             ; ...and  with SFR address
 
        dec     B
 
        mov     a,B
 
        cjne    a,#00h,te_i0
 
        mov     B,#000h
 
        clr     c
 
        dec     B
 
        jc      te_i0
 
        mov     a,B
 
        cjne    a,#0ffh,te_i0
 
 
        eot     'i',te_i0
        eot     'i',te_i0
        put_crlf                    ; end of test series
        put_crlf                    ; end of test series
        ;-- Test series F ------------------------------------------------------
        ;-- Test series F ------------------------------------------------------
        ;
        ;
        ; a.- 
        ; a.- 
        ; b.- 
        ; b.- 
        ; c.- 
        ; c.- 
        ; d.- 
        ; d.- 
        ; e.- 
        ; e.- 
        ; f.- 
        ; f.- 
        ; g.- 
        ; g.- 
        ; h.- 
        ; h.- 
        putc    #'F'                ; start of test series
        putc    #'F'                ; start of test series
tf_ma   macro   rn, n, error_loc
tf_ma   macro   rn, n, error_loc
        mov     rn,#(091h+n)
        mov     rn,#(091h+n)
        mov     039h,rn
        mov     039h,rn
        mov     a,039h
        mov     a,039h
        cjne    a,#(091h+n),error_loc
        cjne    a,#(091h+n),error_loc
        endm
        endm
        tf_ma   r0,0,tf_a0
        tf_ma   r0,0,tf_a0
        tf_ma   r1,1,tf_a0
        tf_ma   r1,1,tf_a0
        tf_ma   r2,2,tf_a0
        tf_ma   r2,2,tf_a0
        tf_ma   r3,3,tf_a0
        tf_ma   r3,3,tf_a0
        tf_ma   r4,4,tf_a0
        tf_ma   r4,4,tf_a0
        tf_ma   r5,5,tf_a0
        tf_ma   r5,5,tf_a0
        tf_ma   r6,6,tf_a0
        tf_ma   r6,6,tf_a0
        tf_ma   r7,7,tf_a0
        tf_ma   r7,7,tf_a0
        eot     'a',tf_a0
        eot     'a',tf_a0
        tf_ma   @r0,0,tf_b0
        tf_ma   @r0,0,tf_b0
        tf_ma   @r1,1,tf_b0
        tf_ma   @r1,1,tf_b0
        eot     'b',tf_b0
        eot     'b',tf_b0
 
 
        mov     031h,#091h
        mov     031h,#091h          ; IRAM to IRAM...
        mov     039h,031h
        mov     039h,031h
        mov     a,039h
        mov     a,039h
        cjne    a,#091h,tf_c0
        cjne    a,#091h,tf_c0
 
 
 
        mov     031h,#091h          ; ...IRAM to SFR...
 
        mov     B,031h
 
        mov     a,B
 
        cjne    a,#091h,tf_c0
 
 
 
        mov     B,#091h          ; ...and SFR to IRAM
 
        mov     031h,B
 
        mov     a,031h
 
        cjne    a,#091h,tf_c0
 
 
 
 
        eot     'c',tf_c0
        eot     'c',tf_c0
tf_md   macro   rn, n, error_loc
tf_md   macro   rn, n, error_loc
        mov     039h,#(091h+n)
        mov     039h,#(091h+n)
        mov     rn,039h
        mov     rn,039h
        cjne    rn,#(091h+n),error_loc
        cjne    rn,#(091h+n),error_loc
        endm
        endm
        tf_md   r0,0,tf_d0
        tf_md   r0,0,tf_d0
        tf_md   r1,1,tf_d0
        tf_md   r1,1,tf_d0
        tf_md   r2,2,tf_d0
        tf_md   r2,2,tf_d0
        tf_md   r3,3,tf_d0
        tf_md   r3,3,tf_d0
        tf_md   r4,4,tf_d0
        tf_md   r4,4,tf_d0
        tf_md   r5,5,tf_d0
        tf_md   r5,5,tf_d0
        tf_md   r6,6,tf_d0
        tf_md   r6,6,tf_d0
        tf_md   r7,7,tf_d0
        tf_md   r7,7,tf_d0
        eot     'd',tf_d0
        eot     'd',tf_d0
        mov     r0,#dir0
        mov     r0,#dir0
        mov     r1,#031h
        mov     r1,#031h
        tf_md   @r0,0,tf_e0
        tf_md   @r0,0,tf_e0
        tf_md   @r1,1,tf_e0
        tf_md   @r1,1,tf_e0
        eot     'e',tf_e0
        eot     'e',tf_e0
tf_mf   macro   rn, n, error_loc
tf_mf   macro   rn, n, error_loc
        mov     a,#(091h+n)
        mov     a,#(091h+n)
        mov     rn,a
        mov     rn,a
        cjne    rn,#(091h+n),error_loc
        cjne    rn,#(091h+n),error_loc
        endm
        endm
        tf_mf   r0,0,tf_f0
        tf_mf   r0,0,tf_f0
        tf_mf   r1,1,tf_f0
        tf_mf   r1,1,tf_f0
        tf_mf   r2,2,tf_f0
        tf_mf   r2,2,tf_f0
        tf_mf   r3,3,tf_f0
        tf_mf   r3,3,tf_f0
        tf_mf   r4,4,tf_f0
        tf_mf   r4,4,tf_f0
        tf_mf   r5,5,tf_f0
        tf_mf   r5,5,tf_f0
        tf_mf   r6,6,tf_f0
        tf_mf   r6,6,tf_f0
        tf_mf   r7,7,tf_f0
        tf_mf   r7,7,tf_f0
        eot     'f',tf_f0
        eot     'f',tf_f0
        mov     r0,#dir0
        mov     r0,#dir0
        mov     r1,#031h
        mov     r1,#031h
        tf_mf   @r0,0,tf_g0
        tf_mf   @r0,0,tf_g0
        tf_mf   @r1,1,tf_g0
        tf_mf   @r1,1,tf_g0
        eot     'g',tf_g0
        eot     'g',tf_g0
        mov     dir0,#079h
        mov     dir0,#079h
        mov     r0,#000h
        mov     r0,#000h
        mov     a,#34h
        mov     a,#34h
        mov     dir0,a
        mov     dir0,a
        mov     r0,dir0
        mov     r0,dir0
        cjne    r0,#034h,tf_h0
        cjne    r0,#034h,tf_h0
        eot     'h',tf_h0
        eot     'h',tf_h0
        mov     a,#000h
        mov     a,#000h
        mov     r1,#031h
        mov     r1,#031h
        mov     031h,#056h
        mov     031h,#056h
        mov     r0,#dir0
        mov     r0,#dir0
        mov     dir0,#034h
        mov     dir0,#034h
        mov     a,@r0
        mov     a,@r0
        cjne    a,#034h,tf_i0
        cjne    a,#034h,tf_i0
        mov     a,@r1
        mov     a,@r1
        cjne    a,#056h,tf_i0
        cjne    a,#056h,tf_i0
        eot     'i',tf_i0
        eot     'i',tf_i0
        put_crlf                    ; end of test series
        put_crlf                    ; end of test series
        ;-- Test series G ------------------------------------------------------
        ;-- Test series G ------------------------------------------------------
        ; Note the XCG tests are specially lame even within this context.
        ; Note the XCG tests are specially lame even within this context.
        ; a.- , , 
        ; a.- , , 
        ; b.- 
        ; b.- 
        ; c.- 
        ; c.- 
        ; d.- 
        ; d.- 
        ; e.- 
        ; e.- 
        putc    #'G'                ; start of test series
        putc    #'G'                ; start of test series
        mov     a,#055h
        mov     a,#055h
        clr     a
        clr     a
        jnz     tg_a0
        jnz     tg_a0
        mov     a,#055h
        mov     a,#055h
        cpl     a
        cpl     a
        cjne    a,#0aah,tg_a0
        cjne    a,#0aah,tg_a0
        mov     a,#097h
        mov     a,#097h
        swap    a
        swap    a
        cjne    a,#079h,tg_a0
        cjne    a,#079h,tg_a0
        eot     'a',tg_a0
        eot     'a',tg_a0
        mov     DPH,#012h
        mov     DPH,#012h
        mov     DPL,#0fdh
        mov     DPL,#0fdh
        inc     dptr
        inc     dptr
        mov     a,DPH
        mov     a,DPH
        cjne    a,#012h,tg_b0
        cjne    a,#012h,tg_b0
        mov     a,DPL
        mov     a,DPL
        cjne    a,#0feh,tg_b0
        cjne    a,#0feh,tg_b0
        inc     dptr
        inc     dptr
        mov     a,DPH
        mov     a,DPH
        cjne    a,#012h,tg_b0
        cjne    a,#012h,tg_b0
        mov     a,DPL
        mov     a,DPL
        cjne    a,#0ffh,tg_b0
        cjne    a,#0ffh,tg_b0
        inc     dptr
        inc     dptr
        mov     a,DPH
        mov     a,DPH
        cjne    a,#013h,tg_b0
        cjne    a,#013h,tg_b0
        mov     a,DPL
        mov     a,DPL
        cjne    a,#000h,tg_b0
        cjne    a,#000h,tg_b0
        eot     'b',tg_b0
        eot     'b',tg_b0
        ; c.- 
        ; c.- 
        mov     a,#34h
        mov     a,#34h              ; IRAM address...
        mov     13h,#57h
        mov     13h,#57h
        xch     a,13h
        xch     a,13h
        cjne    a,#57h,tg_c0
        cjne    a,#57h,tg_c0
        mov     a,13h
        mov     a,13h
        cjne    a,#34h,tg_c0
        cjne    a,#34h,tg_c0
 
 
 
        mov     a,#34h              ; ...and SFR address
 
        mov     B,#57h
 
        xch     a,B
 
        cjne    a,#57h,tg_c0
 
        mov     a,B
 
        cjne    a,#34h,tg_c0
 
 
        eot     'c',tg_c0
        eot     'c',tg_c0
        ; d.- 
        ; d.- 
        mov     a,#91h
        mov     a,#91h
        mov     29h,#78h
        mov     29h,#78h
        mov     r0,#29h
        mov     r0,#29h
        xch     a,@r0
        xch     a,@r0
        cjne    a,#78h,tg_d0
        cjne    a,#78h,tg_d0
        mov     a,29h
        mov     a,29h
        cjne    a,#91h,tg_d0
        cjne    a,#91h,tg_d0
        mov     a,#92h
        mov     a,#92h
        mov     2ah,#78h
        mov     2ah,#78h
        mov     r1,#2ah
        mov     r1,#2ah
        xch     a,@r1
        xch     a,@r1
        cjne    a,#78h,tg_d0
        cjne    a,#78h,tg_d0
        mov     a,2ah
        mov     a,2ah
        cjne    a,#92h,tg_d0
        cjne    a,#92h,tg_d0
        eot     'd',tg_d0
        eot     'd',tg_d0
        ; e.- 
        ; e.- 
tg_ma   macro   rn, n, error_loc
tg_ma   macro   rn, n, error_loc
        mov     a,#(0c1h+n)
        mov     a,#(0c1h+n)
        mov     rn,#(042h+n)
        mov     rn,#(042h+n)
        xch     a,rn
        xch     a,rn
        cjne    rn,#(0c1h+n),error_loc
        cjne    rn,#(0c1h+n),error_loc
        cjne    a,#(042h+n),error_loc
        cjne    a,#(042h+n),error_loc
        endm
        endm
        tg_ma   r0, 19, tg_e0
        tg_ma   r0, 19, tg_e0
        tg_ma   r1, 18, tg_e0
        tg_ma   r1, 18, tg_e0
        tg_ma   r2, 17, tg_e0
        tg_ma   r2, 17, tg_e0
        tg_ma   r3, 16, tg_e0
        tg_ma   r3, 16, tg_e0
        tg_ma   r4, 15, tg_e0
        tg_ma   r4, 15, tg_e0
        tg_ma   r5, 14, tg_e0
        tg_ma   r5, 14, tg_e0
        tg_ma   r6, 13, tg_e0
        tg_ma   r6, 13, tg_e0
        tg_ma   r7, 12, tg_e0
        tg_ma   r7, 12, tg_e0
        eot     'e',tg_e0
        eot     'e',tg_e0
        put_crlf                    ; end of test series
        put_crlf                    ; end of test series
        ;-- ALU opcode block test ----------------------------------------------
        ;-- ALU opcode block test ----------------------------------------------
        ; This set of macros is used to test families of opcodes, such as ORL,
        ; This set of macros is used to test families of opcodes, such as ORL,
        ; ANL, ADD, etc. with all their addressing modes.
        ; ANL, ADD, etc. with all their addressing modes.
        ;
        ;
        ; a.- , ,  (n=0,1)
        ; a.- , ,  (n=0,1)
        ; b.-  (n=2,3)
        ; b.-  (n=2,3)
        ; c.-  (n=4,5)
        ; c.-  (n=4,5)
        ; d.-  (n=6,7)
        ; d.-  (n=6,7)
        ; e.- 
        ; e.- 
        ; f.- 
        ; f.- 
        ; g.- 
        ; g.- 
        ;store psw away for later comparison
        ;store psw away for later comparison
save_psw macro
save_psw macro
        mov     saved_psw,PSW
        mov     saved_psw,PSW
        endm
        endm
        ; compare flags CY, AC and OV with expected values in 
        ; compare flags CY, AC and OV with expected values in 
tst_psw macro   flags,error_loc
tst_psw macro   flags,error_loc
        mov     a,saved_psw
        mov     a,saved_psw
        anl     a,#0c4h
        anl     a,#0c4h
        xrl     a,#flags
        xrl     a,#flags
        anl     a,#0feh
        anl     a,#0feh
        jnz     error_loc
        jnz     error_loc
        endm
        endm
        ; Set the CY flag to the value of the lsb of argument 
        ; Set the CY flag to the value of the lsb of argument 
set_cy  macro   flags
set_cy  macro   flags
        local   cy_val
        local   cy_val
cy_val  set     (flags and 1)
cy_val  set     (flags and 1)
        if      cy_val eq 1
        if      cy_val eq 1
        setb    c
        setb    c
        else
        else
        clr     c
        clr     c
        endif
        endif
        endm
        endm
        ; Test instruction  A, src
        ; Test instruction  A, src
        ;
        ;
        ; flags = ( & 0xfe) | 
        ; flags = ( & 0xfe) | 
        ; (P flag result is not tested)
        ; (P flag result is not tested)
top_ma  macro   op,src,error_loc,flags
top_ma  macro   op,src,error_loc,flags
        mov     src,#arg0
        mov     src,#arg0
        mov     a,#arg1
        mov     a,#arg1
        ifnb    
        ifnb    
        set_cy  flags
        set_cy  flags
        endif
        endif
        op      a,src
        op      a,src
        ifnb    
        ifnb    
        save_psw
        save_psw
        endif
        endif
        cjne    a,#res,error_loc
        cjne    a,#res,error_loc
        ifnb    
        ifnb    
        tst_psw ,error_loc
        tst_psw ,error_loc
        endif
        endif
        endm
        endm
        ; Test instruction  dst, #arg0
        ; Test instruction  dst, #arg0
        ; ( same as top_ma)
        ; ( same as top_ma)
top_mb  macro   op,dst,error_loc,flags
top_mb  macro   op,dst,error_loc,flags
        mov     dst,#arg1
        mov     dst,#arg1
        ifnb    
        ifnb    
        set_cy  flags
        set_cy  flags
        endif
        endif
        op      dst,#arg0
        op      dst,#arg0
        ifnb    
        ifnb    
        save_psw
        save_psw
        endif
        endif
        mov     ACC,dst
        mov     ACC,dst
        cjne    a,#res,error_loc
        cjne    a,#res,error_loc
        ifnb    
        ifnb    
        tst_psw ,error_loc
        tst_psw ,error_loc
        endif
        endif
        endm
        endm
        ; Test instruction  dir, A
        ; Test instruction  dir, A
        ; ( same as top_ma)
        ; ( same as top_ma)
top_mc  macro   op,error_loc,flags
top_mc  macro   op,error_loc,flags
        mov     dir0,#arg0
        mov     dir0,#arg0
        mov     a,#arg1
        mov     a,#arg1
        ifnb    
        ifnb    
        set_cy  flags
        set_cy  flags
        endif
        endif
        op      dir0,a
        op      dir0,a
        ifnb    
        ifnb    
        save_psw
        save_psw
        endif
        endif
        mov     a,dir0
        mov     a,dir0
        cjne    a,#res,error_loc
        cjne    a,#res,error_loc
        ifnb    
        ifnb    
        tst_psw ,error_loc
        tst_psw ,error_loc
        endif
        endif
        endm
        endm
        ; Test ALU instruction with all addressing modes.
        ; Test ALU instruction with all addressing modes.
        ; FIXME  A, #imm not tested!
        ; FIXME  A, #imm not tested!
        ; op : Opcode to be tested
        ; op : Opcode to be tested
        ; a0, a1 : Values used as 1st and 2nd args in all addressing modes
        ; a0, a1 : Values used as 1st and 2nd args in all addressing modes
        ; r : Expected result
        ; r : Expected result
        ; am :
        ; am :
        ; flags : &0xfe | 
        ; flags : &0xfe | 
        ; (if the parameter is unused, the macro skips the flag check)
        ; (if the parameter is unused, the macro skips the flag check)
tst_alu macro   op,a0,a1,r,am,flags
tst_alu macro   op,a0,a1,r,am,flags
        local   tall_0d
        local   tall_0d
        local   tall_0a
        local   tall_0a
        local   tall_0b
        local   tall_0b
        local   tall_0c
        local   tall_0c
        local   tall_1
        local   tall_1
        local   tall_2
        local   tall_2
        local   tall_3
        local   tall_3
        ; Put the argument and result data into variables for easier access
        ; Put the argument and result data into variables for easier access
        arg0    set a0
        arg0    set a0
        arg1    set a1
        arg1    set a1
        res     set r
        res     set r
        ; Test  A, dir
        ; Test  A, dir
        top_ma  op,dir0,tall_0a,
        top_ma  op,dir0,tall_0a,
        ; Test  A, @R0
        ; Test  A, @R0
        mov     r0,#dir0
        mov     r0,#dir0
        top_ma  op,@r0,tall_0a,
        top_ma  op,@r0,tall_0a,
        ; Test  A, @R1
        ; Test  A, @R1
        mov     r1,#031h
        mov     r1,#031h
        top_ma  op,@r1,tall_0a,
        top_ma  op,@r1,tall_0a,
        ; Now test  A, Rn for n in 0..7
        ; Now test  A, Rn for n in 0..7
        top_ma  op,r0,tall_0a,
        top_ma  op,r0,tall_0a,
        top_ma  op,r1,tall_0a,
        top_ma  op,r1,tall_0a,
        eot     'a',tall_0a
        eot     'a',tall_0a
        top_ma  op,r2,tall_0b,
        top_ma  op,r2,tall_0b,
        top_ma  op,r3,tall_0b,
        top_ma  op,r3,tall_0b,
        eot     'b',tall_0b
        eot     'b',tall_0b
        top_ma  op,r4,tall_0c,
        top_ma  op,r4,tall_0c,
        top_ma  op,r5,tall_0c,
        top_ma  op,r5,tall_0c,
        eot     'c',tall_0c
        eot     'c',tall_0c
        top_ma  op,r6,tall_0d,
        top_ma  op,r6,tall_0d,
        top_ma  op,r7,tall_0d,
        top_ma  op,r7,tall_0d,
        eot     'd',tall_0d
        eot     'd',tall_0d
        ; Ok,  A, {dir | @Ri | Rn} done.
        ; Ok,  A, {dir | @Ri | Rn} done.
        ; Optionally test immediate addressing modes.
        ; Optionally test immediate addressing modes.
        if      (am and 1) ne 0
        if      (am and 1) ne 0
        ; Test  A, #arg1...
        ; Test  A, #arg1...
        top_mb  op,a,tall_1,
        top_mb  op,a,tall_1,
        eot     'e',tall_1
        eot     'e',tall_1
        endif
        endif
        if      (am and 2) ne 0
        if      (am and 2) ne 0
        ; ...and  dir, #arg1
        ; ...and  dir, #arg1
        top_mb  op,dir0,tall_2,
        top_mb  op,dir0,tall_2,
 
        top_mb  op,B,tall_2,
        eot     'f',tall_2
        eot     'f',tall_2
        endif
        endif
        ; Optionally test  dir, A
        ; Optionally test  dir, A
        if      (am and 4) ne 0
        if      (am and 4) ne 0
        top_mc  op,tall_3,
        top_mc  op,tall_3,
        eot     'g',tall_3
        eot     'g',tall_3
        endif
        endif
        endm
        endm
        ;-- Test series H ------------------------------------------------------
        ;-- Test series H ------------------------------------------------------
        ; ANL
        ; ANL
        ; (See comments for 'ALU opcode block test')
        ; (See comments for 'ALU opcode block test')
        putc    #'H'                ; start of test series
        putc    #'H'                ; start of test series
        tst_alu anl,03ch,099h,018h,07h,
        tst_alu anl,03ch,099h,018h,07h,
        put_crlf                    ; end of test series
        put_crlf                    ; end of test series
        ;-- Test series I ------------------------------------------------------
        ;-- Test series I ------------------------------------------------------
        ; ORL
        ; ORL
        ; (See comments for 'ALU opcode block test')
        ; (See comments for 'ALU opcode block test')
        putc    #'I'                ; start of test series
        putc    #'I'                ; start of test series
        tst_alu orl,051h,092h,0d3h,07h,
        tst_alu orl,051h,092h,0d3h,07h,
        put_crlf                    ; end of test series
        put_crlf                    ; end of test series
        ;-- Test series J ------------------------------------------------------
        ;-- Test series J ------------------------------------------------------
        ; XRL
        ; XRL
        ; (See comments for 'ALU opcode block test')
        ; (See comments for 'ALU opcode block test')
        putc    #'J'                ; start of test series
        putc    #'J'                ; start of test series
        tst_alu xrl,051h,033h,062h,07h,
        tst_alu xrl,051h,033h,062h,07h,
        put_crlf                    ; end of test series
        put_crlf                    ; end of test series
        ;-- Test series K ------------------------------------------------------
        ;-- Test series K ------------------------------------------------------
        ; DJNZ
        ; DJNZ
        ; a.- ,  tested only with small negative rels
        ; a.- ,  tested only with small negative rels
        putc    #'K'                ; start of test series
        putc    #'K'                ; start of test series
        ;tk_ma: test DJNZ with parametrizable addressing mode
        ;tk_ma: test DJNZ with parametrizable addressing mode
tk_ma   macro   dst,error_loc
tk_ma   macro   dst,error_loc
        local   tk_ma0
        local   tk_ma0
nloops  set     3
nloops  set     3
        mov     dst,#nloops         ; We'll perform a fixed no. of iterations
        mov     dst,#nloops         ; We'll perform a fixed no. of iterations
        mov     a,#(nloops+1)       ; A will or our control counter
        mov     a,#(nloops+1)       ; A will or our control counter
tk_ma0: dec     a
tk_ma0: dec     a
        jz      error_loc           ; Break loop after nloops iterations
        jz      error_loc           ; Break loop after nloops iterations
        djnz    dst,tk_ma0          ; Test DJNZ instruction
        djnz    dst,tk_ma0          ; Test DJNZ instruction
        cjne    a,#001,error_loc    ; Verify number of iterations is ok
        cjne    a,#001,error_loc    ; Verify number of iterations is ok
        endm
        endm
        tk_ma   dir0,tk_a0          ;  with IRAM operand
        tk_ma   dir0,tk_a0          ;  with IRAM operand
        tk_ma   B,tk_a0             ;  with SFR operand
        tk_ma   B,tk_a0             ;  with SFR operand
        eot     'a',tk_a0
        eot     'a',tk_a0
        tk_ma   r0,tk_b0            ; 
        tk_ma   r0,tk_b0            ; 
        tk_ma   r1,tk_b0
        tk_ma   r1,tk_b0
        tk_ma   r2,tk_b0
        tk_ma   r2,tk_b0
        tk_ma   r3,tk_b0
        tk_ma   r3,tk_b0
        tk_ma   r4,tk_b0
        tk_ma   r4,tk_b0
        tk_ma   r5,tk_b0
        tk_ma   r5,tk_b0
        tk_ma   r6,tk_b0
        tk_ma   r6,tk_b0
        tk_ma   r7,tk_b0
        tk_ma   r7,tk_b0
        eot     'b',tk_b0
        eot     'b',tk_b0
        put_crlf                    ; end of test series
        put_crlf                    ; end of test series
        ;-- Test series L ------------------------------------------------------
        ;-- Test series L ------------------------------------------------------
        ; ADD
        ; ADD
        ; (See comments for 'ALU opcode block test')
        ; (See comments for 'ALU opcode block test')
        putc    #'L'                ; start of test series
        putc    #'L'                ; start of test series
        putc    #'0'
        putc    #'0'
        tst_alu add,051h,033h,084h,01h,004h     ; /CY /AC  OV
        tst_alu add,051h,033h,084h,01h,004h     ; /CY /AC  OV
        putc    #'1'
        putc    #'1'
        tst_alu add,081h,093h,014h,01h,084h     ;  CY /AC  OV
        tst_alu add,081h,093h,014h,01h,084h     ;  CY /AC  OV
        putc    #'2'
        putc    #'2'
        tst_alu add,088h,098h,020h,01h,0c4h     ;  CY  AC  OV
        tst_alu add,088h,098h,020h,01h,0c4h     ;  CY  AC  OV
        putc    #'3'
        putc    #'3'
        tst_alu add,043h,0fbh,03eh,01h,080h     ;  CY /AC /OV
        tst_alu add,043h,0fbh,03eh,01h,080h     ;  CY /AC /OV
        put_crlf                    ; end of test series
        put_crlf                    ; end of test series
        ;-- Test series M ------------------------------------------------------
        ;-- Test series M ------------------------------------------------------
        ; ADDC
        ; ADDC
        ; (See comments for 'ALU opcode block test')
        ; (See comments for 'ALU opcode block test')
        ; Note the test runs 4 times for different values of operands
        ; Note the test runs 4 times for different values of operands
        putc    #'M'                ; start of test series
        putc    #'M'                ; start of test series
        putc    #'0'
        putc    #'0'
        tst_alu addc,051h,033h,084h,01h,004h     ; /CY /AC  OV
        tst_alu addc,051h,033h,084h,01h,004h     ; /CY /AC  OV
        putc    #'1'
        putc    #'1'
        tst_alu addc,081h,093h,014h,01h,084h     ;  CY /AC  OV
        tst_alu addc,081h,093h,014h,01h,084h     ;  CY /AC  OV
        putc    #'2'
        putc    #'2'
        tst_alu addc,088h,098h,020h,01h,0c4h     ;  CY  AC  OV
        tst_alu addc,088h,098h,020h,01h,0c4h     ;  CY  AC  OV
        putc    #'3'
        putc    #'3'
        tst_alu addc,088h,098h,021h,01h,0c5h     ;  CY  AC  OV (CY input)
        tst_alu addc,088h,098h,021h,01h,0c5h     ;  CY  AC  OV (CY input)
        putc    #'4'
        putc    #'4'
        tst_alu addc,043h,0fbh,03fh,01h,081h     ;  CY /AC /OV (CY input)
        tst_alu addc,043h,0fbh,03fh,01h,081h     ;  CY /AC /OV (CY input)
        put_crlf                    ; end of test series
        put_crlf                    ; end of test series
        ;-- Test series N ------------------------------------------------------
        ;-- Test series N ------------------------------------------------------
        ; SUBB
        ; SUBB
        ; (See comments for 'ALU opcode block test')
        ; (See comments for 'ALU opcode block test')
        ; Note the test runs 4 times for different values of operands
        ; Note the test runs 4 times for different values of operands
        putc    #'N'                ; start of test series
        putc    #'N'                ; start of test series
        putc    #'0'
        putc    #'0'
        tst_alu subb,070h,073h,003h,01h,000h     ; /CY /AC /OV
        tst_alu subb,070h,073h,003h,01h,000h     ; /CY /AC /OV
        putc    #'1'
        putc    #'1'
        tst_alu subb,070h,073h,002h,01h,001h     ; /CY /AC /OV (CY input)
        tst_alu subb,070h,073h,002h,01h,001h     ; /CY /AC /OV (CY input)
        putc    #'2'
        putc    #'2'
        tst_alu subb,0c3h,0c5h,002h,01h,000h     ; /CY  AC /OV
        tst_alu subb,0c3h,0c5h,002h,01h,000h     ; /CY  AC /OV
        putc    #'3'
        putc    #'3'
        tst_alu subb,0c3h,0c5h,001h,01h,001h     ; /CY  AC  OV (CY input)
        tst_alu subb,0c3h,0c5h,001h,01h,001h     ; /CY  AC  OV (CY input)
        ; FIXME subb tests are specially weak
        ; FIXME subb tests are specially weak
        put_crlf                    ; end of test series
        put_crlf                    ; end of test series
        ;-- Test series O ------------------------------------------------------
        ;-- Test series O ------------------------------------------------------
        ; PUSH and POP
        ; PUSH and POP
        ; a.- 
        ; a.- 
        ; b.- 
        ; b.- 
        ; c.- 
        ; c.- 
        ; d.- 
        ; d.- 
        putc    #'O'                ; start of test series
        putc    #'O'                ; start of test series
        ; 
        ; 
        mov     SP,#stack0          ; prepare SP...
        mov     SP,#stack0          ; prepare SP...
        mov     dir0,#012h          ; ...and data to be pushed
        mov     dir0,#012h          ; ...and data to be pushed
        mov     r0,#(stack0+1)      ; r0->stack so we can verify data is pushed
        mov     r0,#(stack0+1)      ; r0->stack so we can verify data is pushed
        mov     @r0,#000h           ; clear target stack location
        mov     @r0,#000h           ; clear target stack location
        push    dir0                ; 
        push    dir0                ; 
        mov     a,@r0               ; verify data has been pushed
        mov     a,@r0               ; verify data has been pushed
        cjne    a,#012h,to_a0
        cjne    a,#012h,to_a0
        mov     a,SP                ; verify SP has been incremented
        mov     a,SP                ; verify SP has been incremented
        cjne    a,#(stack0+1),to_a0
        cjne    a,#(stack0+1),to_a0
        eot     'a',to_a0
        eot     'a',to_a0
        ;  We'll use the data that was pushed previously
        ;  We'll use the data that was pushed previously
        mov     dir1,#000h          ; clear POP target
        mov     dir1,#000h          ; clear POP target
        clr     a
        clr     a
        pop     dir1                ; 
        pop     dir1                ; 
        mov     r1,#dir1            ; verify data has been popped
        mov     r1,#dir1            ; verify data has been popped
        mov     a,@r1
        mov     a,@r1
        cjne    a,#012h,to_b0
        cjne    a,#012h,to_b0
        mov     a,SP                ; verify SP has been decremented
        mov     a,SP                ; verify SP has been decremented
        cjne    a,#stack0,to_b0
        cjne    a,#stack0,to_b0
        eot     'b',to_b0
        eot     'b',to_b0
        ; 
        ; 
        mov     SP,#stack0          ; prepare SP...
        mov     SP,#stack0          ; prepare SP...
        mov     B,#042h             ; ...and data to be pushed
        mov     B,#042h             ; ...and data to be pushed
        mov     r0,#(stack0+1)      ; r0->stack so we can verify data is pushed
        mov     r0,#(stack0+1)      ; r0->stack so we can verify data is pushed
        mov     @r0,#000h           ; clear target stack location
        mov     @r0,#000h           ; clear target stack location
        push    B                   ; 
        push    B                   ; 
        mov     a,@r0               ; verify data has been pushed
        mov     a,@r0               ; verify data has been pushed
        cjne    a,#042h,to_c0
        cjne    a,#042h,to_c0
        mov     a,SP                ; verify SP has been incremented
        mov     a,SP                ; verify SP has been incremented
        cjne    a,#(stack0+1),to_c0
        cjne    a,#(stack0+1),to_c0
        eot     'c',to_c0
        eot     'c',to_c0
        ;  We'll use the data that was pushed previously
        ;  We'll use the data that was pushed previously
        mov     B,#000h             ; clear POP target
        mov     B,#000h             ; clear POP target
        clr     a
        clr     a
        pop     B                   ; 
        pop     B                   ; 
        mov     a,B                 ; verify data has been popped
        mov     a,B                 ; verify data has been popped
        cjne    a,#042h,to_d0
        cjne    a,#042h,to_d0
        mov     a,SP                ; verify SP has been decremented
        mov     a,SP                ; verify SP has been decremented
        cjne    a,#stack0,to_d0
        cjne    a,#stack0,to_d0
        eot     'd',to_d0
        eot     'd',to_d0
        put_crlf                    ; end of test series
        put_crlf                    ; end of test series
        ;-- Test series P ------------------------------------------------------
        ;-- Test series P ------------------------------------------------------
        ; Access to XRAM -- note that current tests are bare-bone minimal!
        ; Access to XRAM -- note that current tests are bare-bone minimal!
        ; a.- 
        ; a.- 
        ; b.- , 
        ; b.- , 
        ; c.- 
        ; c.- 
        ; d.- 
        ; d.- 
        putc    #'P'                ; start of test series
        putc    #'P'                ; start of test series
        ; a.- 
        ; a.- 
        mov     DPH,#065h           ; initialize DPTR with known value...
        mov     DPH,#065h           ; initialize DPTR with known value...
        mov     DPL,#043h
        mov     DPL,#043h
        mov     DPTR,#0123h         ; ...then load it through MOV...
        mov     DPTR,#0123h         ; ...then load it through MOV...
        mov     a,DPH               ; ...and verify the load
        mov     a,DPH               ; ...and verify the load
        cjne    a,#01h,tp_a0
        cjne    a,#01h,tp_a0
        mov     a,DPL
        mov     a,DPL
        cjne    a,#23h,tp_a0
        cjne    a,#23h,tp_a0
        eot     'a',tp_a0
        eot     'a',tp_a0
        ; b.- , 
        ; b.- , 
        ; We have no independent means to verify XRAM writes or reads, other
        ; We have no independent means to verify XRAM writes or reads, other
        ; than the very instructions we're testing. So we should store a data
        ; than the very instructions we're testing. So we should store a data
        ; pattern on XRAM that is difficult to get back 'by chance'.
        ; pattern on XRAM that is difficult to get back 'by chance'.
        ; Ideally we would try all areas of XRAM, back-to-back operations, etc.
        ; Ideally we would try all areas of XRAM, back-to-back operations, etc.
        ; For the time being a simple word store will suffice.
        ; For the time being a simple word store will suffice.
        mov     DPTR,#0013h         ; Store 55h, aah at XRAM[0013h]...
        mov     DPTR,#0013h         ; Store 55h, aah at XRAM[0013h]...
        mov     A,#55h
        mov     A,#55h
        movx    @DPTR,a
        movx    @DPTR,a
        inc     DPTR
        inc     DPTR
        cpl     a
        cpl     a
        movx    @DPTR,a
        movx    @DPTR,a
        mov     DPTR,#0013h         ; ...then verify the store
        mov     DPTR,#0013h         ; ...then verify the store
        movx    a,@DPTR
        movx    a,@DPTR
        cjne    a,#55h,tp_b0
        cjne    a,#55h,tp_b0
        inc     DPTR
        inc     DPTR
        movx    a,@DPTR
        movx    a,@DPTR
        cjne    a,#0aah,tp_b0
        cjne    a,#0aah,tp_b0
        eot     'b',tp_b0
        eot     'b',tp_b0
        ; c.- 
        ; c.- 
        mov     a,#79h              ; Let [0013h] = 79h and [0014h] = 97h
        mov     a,#79h              ; Let [0013h] = 79h and [0014h] = 97h
        mov     dptr,#0013h
        mov     dptr,#0013h
        mov     r0,#13h             ;
        mov     r0,#13h             ;
        mov     r1,#14h             ; Write using @Ri...
        mov     r1,#14h             ; Write using @Ri...
        movx    @r0,a
        movx    @r0,a
        dec     a
        dec     a
        movx    a,@DPTR             ; ...verify using DPTR
        movx    a,@DPTR             ; ...verify using DPTR
        cjne    a,#79h,tp_c0
        cjne    a,#79h,tp_c0
        inc     DPTR
        inc     DPTR
        mov     a,#97h
        mov     a,#97h
        movx    @r1,a
        movx    @r1,a
        movx    a,@DPTR
        movx    a,@DPTR
        cjne    a,#097h,tp_c0
        cjne    a,#097h,tp_c0
        eot     'c',tp_c0
        eot     'c',tp_c0
        ; d.- 
        ; d.- 
        mov     a,#79h              ; Let [0013h] = 79h and [0014h] = 97h
        mov     a,#79h              ; Let [0013h] = 79h and [0014h] = 97h
        mov     dptr,#0013h
        mov     dptr,#0013h
        mov     r0,#13h
        mov     r0,#13h
        mov     r1,#14h
        mov     r1,#14h
        movx    @DPTR,a             ; Write using DPTR...
        movx    @DPTR,a             ; Write using DPTR...
        dec a
        dec a
        movx    a,@r0               ; ... verify using @Ri
        movx    a,@r0               ; ... verify using @Ri
        cjne    a,#79h,tp_d0
        cjne    a,#79h,tp_d0
        mov     a,#97h
        mov     a,#97h
        inc     DPTR
        inc     DPTR
        movx    @DPTR,a
        movx    @DPTR,a
        dec a
        dec a
        movx    a,@r1
        movx    a,@r1
        cjne    a,#097h,tp_d0
        cjne    a,#097h,tp_d0
        eot     'd',tp_d0
        eot     'd',tp_d0
        put_crlf                    ; end of test series
        put_crlf                    ; end of test series
        ;-- Test series Q ------------------------------------------------------
        ;-- Test series Q ------------------------------------------------------
        ; MOVC instructions
        ; MOVC instructions
        ; a.- 
        ; a.- 
        ; b.- 
        ; b.- 
        putc    #'Q'                ; start of test series
        putc    #'Q'                ; start of test series
        ; a.- 
        ; a.- 
        mov     a,#03h              ; we'll read the 4th byte in the table...
        mov     a,#03h              ; we'll read the 4th byte in the table...
        add     a,#02h              ; ...and must account for intervening sjmp
        add     a,#02h              ; ...and must account for intervening sjmp
        movc    a,@a+PC
        movc    a,@a+PC
        sjmp    tq0
        sjmp    tq0
tq1:    db      07h, 13h, 19h, 21h
tq1:    db      07h, 13h, 19h, 21h
tq0:    cjne    a,#21h,tq_a0
tq0:    cjne    a,#21h,tq_a0
        eot     'a',tq_a0
        eot     'a',tq_a0
        ; b.- 
        ; b.- 
        mov   DPTR,#tq1
        mov   DPTR,#tq1
        mov   a,#00h
        mov   a,#00h
        movc  a,@a+DPTR
        movc  a,@a+DPTR
        cjne  a,#07h,tq_b0
        cjne  a,#07h,tq_b0
        mov   a,#01h
        mov   a,#01h
        movc  a,@a+DPTR
        movc  a,@a+DPTR
        cjne  a,#13h,tq_b0
        cjne  a,#13h,tq_b0
        mov   a,#02h
        mov   a,#02h
        movc  a,@a+DPTR
        movc  a,@a+DPTR
        cjne  a,#19h,tq_b0
        cjne  a,#19h,tq_b0
        mov   a,#03h
        mov   a,#03h
        movc  a,@a+DPTR
        movc  a,@a+DPTR
        cjne  a,#21h,tq_b0
        cjne  a,#21h,tq_b0
        eot     'b',tq_b0
        eot     'b',tq_b0
        put_crlf                    ; end of test series
        put_crlf                    ; end of test series
        ;-- Test series R ------------------------------------------------------
        ;-- Test series R ------------------------------------------------------
        ; ACALL, LCALL, JMP @A+DPTR, LJMP, AJMP instructions
        ; ACALL, LCALL, JMP @A+DPTR, LJMP, AJMP instructions
        ; a.-      <-- uses LJMP too
        ; a.-      <-- uses LJMP too
        ; b.-     <-- uses LJMP too
        ; b.-     <-- uses LJMP too
        ; c.- 
        ; c.- 
        ; d.- 
        ; d.- 
        ; e.- 
        ; e.- 
        ;
        ;
        ; Biggest limitations:
        ; Biggest limitations:
        ; .- Jumps to same page (== H addr byte) tested only at one page.
        ; .- Jumps to same page (== H addr byte) tested only at one page.
        ;
        ;
        ; Note RET is NOT tested here! we don't return from these calls, just
        ; Note RET is NOT tested here! we don't return from these calls, just
        ; use them as jumps.
        ; use them as jumps.
        ;
        ;
        putc    #'R'                ; start of test series
        putc    #'R'                ; start of test series
        mov     SP,#4fh             ; Initialize SP...
        mov     SP,#4fh             ; Initialize SP...
        mov     50h,#00h            ; ...and clear stack area
        mov     50h,#00h            ; ...and clear stack area
        mov     51h,#00h
        mov     51h,#00h
        mov     52h,#00h
        mov     52h,#00h
        mov     53h,#00h
        mov     53h,#00h
        ; a.- 
        ; a.- 
        ; We should test all code pages eventually...
        ; We should test all code pages eventually...
        acall   tr_sub0             ; Do the call...
        acall   tr_sub0             ; Do the call...
tr_rv0: sjmp    tr_a0
tr_rv0: sjmp    tr_a0
tr_sub0:
tr_sub0:
        mov     A,SP
        mov     A,SP
        cjne    A,#51h,tr_a0       ; ...verify the SP value...
        cjne    A,#51h,tr_a0       ; ...verify the SP value...
        mov     A,50h
        mov     A,50h
        cjne    A,#LOW(tr_rv0),tr_a0 ; ...and verify the pushed ret address
        cjne    A,#LOW(tr_rv0),tr_a0 ; ...and verify the pushed ret address
        mov     A,51h
        mov     A,51h
        cjne    A,#HIGH(tr_rv0),tr_a0
        cjne    A,#HIGH(tr_rv0),tr_a0
        eot     'a',tr_a0
        eot     'a',tr_a0
        ; b.- 
        ; b.- 
        lcall   tr_sub1             ; Do the call...
        lcall   tr_sub1             ; Do the call...
tr_rv1: sjmp    tr_b0
tr_rv1: sjmp    tr_b0
tr_rv2: nop
tr_rv2: nop
        eot     'b',tr_b0
        eot     'b',tr_b0
        ; c.- 
        ; c.- 
        ; Note that tr_sub2 is at 8000h so that we test the A+DPTR carry
        ; Note that tr_sub2 is at 8000h so that we test the A+DPTR carry
        ; propagation. Any address xx00h would do.
        ; propagation. Any address xx00h would do.
        mov     DPTR,#(tr_sub2-33h) ; Prepare DPTR and A so that their sum
        mov     DPTR,#(tr_sub2-33h) ; Prepare DPTR and A so that their sum
        mov     a,#33h              ; gives the target address.
        mov     a,#33h              ; gives the target address.
        jmp     @a+DPTR
        jmp     @a+DPTR
        jmp     tr_c0
        jmp     tr_c0
        nop
        nop
        nop
        nop
tr_rv3: mov     a,#00h
tr_rv3: mov     a,#00h
        mov     a,#00h
        mov     a,#00h
        mov     a,#00h
        mov     a,#00h
        mov     a,#00h
        mov     a,#00h
        eot     'c',tr_c0
        eot     'c',tr_c0
        ; d.- 
        ; d.- 
        ljmp    tr_sub3
        ljmp    tr_sub3
        jmp     tr_d0
        jmp     tr_d0
        nop
        nop
        nop
        nop
tr_rv4: nop
tr_rv4: nop
        nop
        nop
        eot     'd',tr_d0
        eot     'd',tr_d0
        ; e.- 
        ; e.- 
        ; We should test all code pages eventually...
        ; We should test all code pages eventually...
        mov     a,#00h
        mov     a,#00h
        ajmp    tr_ajmp0            ; Do the jump...
        ajmp    tr_ajmp0            ; Do the jump...
        sjmp    tr_rv5
        sjmp    tr_rv5
tr_ajmp0:
tr_ajmp0:
        mov     a,#042h
        mov     a,#042h
tr_rv5:
tr_rv5:
        cjne    A,#42h,tr_e0       ; ...and make sure we've actually been there
        cjne    A,#42h,tr_e0       ; ...and make sure we've actually been there
        nop
        nop
        eot     'e',tr_e0
        eot     'e',tr_e0
        put_crlf                    ; end of test series
        put_crlf                    ; end of test series
        ;-- Test series S ------------------------------------------------------
        ;-- Test series S ------------------------------------------------------
        ; RET, RETI instructions
        ; RET, RETI instructions
        ; a.- 
        ; a.- 
        ; b.- 
        ; b.- 
        ;
        ;
        ; RETs to different code pages (!= H addr byte) not tested!
        ; RETs to different code pages (!= H addr byte) not tested!
        ; Interrupt flag stuff not tested, only RET functionality
        ; Interrupt flag stuff not tested, only RET functionality
        putc    #'S'                ; start of test series
        putc    #'S'                ; start of test series
        ; a.- 
        ; a.- 
        mov     SP,#4fh             ; Initialize SP...
        mov     SP,#4fh             ; Initialize SP...
        mov     4fh,#HIGH(s_sub0)   ; ...and load stack area with return
        mov     4fh,#HIGH(s_sub0)   ; ...and load stack area with return
        mov     4eh,#LOW(s_sub0)    ; addresses to be tested
        mov     4eh,#LOW(s_sub0)    ; addresses to be tested
        mov     4dh,#HIGH(s_sub1)
        mov     4dh,#HIGH(s_sub1)
        mov     4ch,#LOW(s_sub1)
        mov     4ch,#LOW(s_sub1)
        ret                         ; Do the ret...
        ret                         ; Do the ret...
        sjmp    ts_a0
        sjmp    ts_a0
        mov     A,#00h
        mov     A,#00h
s_sub0: mov     A,SP
s_sub0: mov     A,SP
        cjne    A,#4dh,ts_a0       ; ... and verify the SP value
        cjne    A,#4dh,ts_a0       ; ... and verify the SP value
        ret                         ; Do another ret...
        ret                         ; Do another ret...
        sjmp    ts_a0
        sjmp    ts_a0
        mov     A,#00h
        mov     A,#00h
s_sub1: mov     A,SP
s_sub1: mov     A,SP
        cjne    A,#4bh,ts_a0       ; ... and verify the SP value
        cjne    A,#4bh,ts_a0       ; ... and verify the SP value
        eot     'a',ts_a0
        eot     'a',ts_a0
        ; a.- 
        ; a.- 
        mov     SP,#4fh             ; Initialize SP...
        mov     SP,#4fh             ; Initialize SP...
        mov     4fh,#HIGH(s_sub2)   ; ...and load stack area with return
        mov     4fh,#HIGH(s_sub2)   ; ...and load stack area with return
        mov     4eh,#LOW(s_sub2)    ; addresses to be tested
        mov     4eh,#LOW(s_sub2)    ; addresses to be tested
        mov     4dh,#HIGH(s_sub3)
        mov     4dh,#HIGH(s_sub3)
        mov     4ch,#LOW(s_sub3)
        mov     4ch,#LOW(s_sub3)
        ret                         ; Do the ret...
        ret                         ; Do the ret...
        sjmp    ts_a0
        sjmp    ts_a0
        mov     A,#00h
        mov     A,#00h
s_sub2: mov     A,SP
s_sub2: mov     A,SP
        cjne    A,#4dh,ts_b0       ; ... and verify the SP value
        cjne    A,#4dh,ts_b0       ; ... and verify the SP value
        ret                         ; Do another ret...
        ret                         ; Do another ret...
        sjmp    ts_a0
        sjmp    ts_a0
        mov     A,#00h
        mov     A,#00h
s_sub3: mov     A,SP
s_sub3: mov     A,SP
        cjne    A,#4bh,ts_b0       ; ... and verify the SP value
        cjne    A,#4bh,ts_b0       ; ... and verify the SP value
        eot     'b',ts_b0
        eot     'b',ts_b0
        ; Lots of things can go badly and we wouldn't know with this test...
        ; Lots of things can go badly and we wouldn't know with this test...
        put_crlf                    ; end of test series
        put_crlf                    ; end of test series
        ;-- Test series T ------------------------------------------------------
        ;-- Test series T ------------------------------------------------------
        ; MUL, DIV instructions
        ; MUL, DIV instructions
        ; a.- 
        ; a.- 
        ; b.- 
        ; b.- 
        ;
        ;
        putc    #'T'                ; start of test series
        putc    #'T'                ; start of test series
        ; a.- 
        ; a.- 
        mov     B,#07h              ; First of all, make sure B can be read back
        mov     B,#07h              ; First of all, make sure B can be read back
        mov     A,#13h
        mov     A,#13h
        mov     A,B
        mov     A,B
        cjne    A,#07h,tt_a0
        cjne    A,#07h,tt_a0
        ; Now do a few representative DIVs using a table. The table has the
        ; Now do a few representative DIVs using a table. The table has the
        ; following format:
        ; following format:
        ; denominator, numerator, overflow, quotient, remainder
        ; denominator, numerator, overflow, quotient, remainder
        ; Where 'overflow' is 00h or 04h.
        ; Where 'overflow' is 00h or 04h.
        ; DPTR will point to the start of the table, r0 will be the current data
        ; DPTR will point to the start of the table, r0 will be the current data
        ; byte offset and r1 the number of test cases remaiining.
        ; byte offset and r1 the number of test cases remaiining.
        mov     DPTR,#tt_a_tab
        mov     DPTR,#tt_a_tab
        mov     r0,#00h
        mov     r0,#00h
        mov     r1,#((tt_a_tab_end-tt_a_tab)/5)
        mov     r1,#((tt_a_tab_end-tt_a_tab)/5)
tt_a_loop:
tt_a_loop:
        mov     a,r0
        mov     a,r0
        inc     r0
        inc     r0
        movc    a,@a+DPTR
        movc    a,@a+DPTR
        mov     B,a
        mov     B,a
        mov     a,r0
        mov     a,r0
        inc     r0
        inc     r0
        movc    a,@a+DPTR
        movc    a,@a+DPTR
        div     ab
        div     ab
        mov     dir0,a
        mov     dir0,a
        mov     a,r0                ; Get expected OV flag
        mov     a,r0                ; Get expected OV flag
        inc     r0
        inc     r0
        movc    a,@a+DPTR
        movc    a,@a+DPTR
        jnz     tt_a_divzero        ; If OV expected, skip verification of
        jnz     tt_a_divzero        ; If OV expected, skip verification of
        mov     a,PSW               ; quotient and remainder
        mov     a,PSW               ; quotient and remainder
        anl     a,#04h
        anl     a,#04h
        jnz     tt_a0
        jnz     tt_a0
        mov     a,r0                ; Verify quotient...
        mov     a,r0                ; Verify quotient...
        inc     r0
        inc     r0
        movc    a,@a+DPTR
        movc    a,@a+DPTR
        cjne    a,dir0,tt_a0
        cjne    a,dir0,tt_a0
        mov     a,r0                ; ...and verify remainder
        mov     a,r0                ; ...and verify remainder
        inc     r0
        inc     r0
        movc    a,@a+DPTR
        movc    a,@a+DPTR
        cjne    a,B,tt_a0
        cjne    a,B,tt_a0
        jmp     tt_a_next
        jmp     tt_a_next
tt_a_divzero:
tt_a_divzero:
        inc     r0
        inc     r0
        inc     r0
        inc     r0
tt_a_next:
tt_a_next:
        dec     r1                  ; go for next test vector, if any
        dec     r1                  ; go for next test vector, if any
        mov     a,r1
        mov     a,r1
        jnz     tt_a_loop
        jnz     tt_a_loop
        eot     'a',tt_a0
        eot     'a',tt_a0
        sjmp    tt_a_tab_end
        sjmp    tt_a_tab_end
tt_a_tab:
tt_a_tab:
        db      7,19,0,2,5
        db      7,19,0,2,5
        db      7,17,0,2,3
        db      7,17,0,2,3
        db      7,13,0,1,6
        db      7,13,0,1,6
        db      13,17,0,1,4
        db      13,17,0,1,4
        db      17,13,0,0,13
        db      17,13,0,0,13
        db      0,13,4,0,13
        db      0,13,4,0,13
        db      80h,87h,0,1,7
        db      80h,87h,0,1,7
        db      1,255,0,255,0
        db      1,255,0,255,0
        db      2,255,0,127,1
        db      2,255,0,127,1
tt_a_tab_end:
tt_a_tab_end:
        ; b.- 
        ; b.- 
        ; Do with MUL the same we just did with DIV. The test data table has
        ; Do with MUL the same we just did with DIV. The test data table has
        ; the following format:
        ; the following format:
        ; denominator, numerator, product high byte, product low byte.
        ; denominator, numerator, product high byte, product low byte.
        ; DPTR will point to the start of the table, r0 will be the current data
        ; DPTR will point to the start of the table, r0 will be the current data
        ; byte offset and r1 the number of test cases remaiining.
        ; byte offset and r1 the number of test cases remaiining.
        mov     DPTR,#tt_b_tab
        mov     DPTR,#tt_b_tab
        mov     r0,#00h
        mov     r0,#00h
        mov     r1,#((tt_b_tab_end-tt_b_tab)/4)
        mov     r1,#((tt_b_tab_end-tt_b_tab)/4)
tt_b_loop:
tt_b_loop:
        mov     a,r0                ; Load B with test data...
        mov     a,r0                ; Load B with test data...
        inc     r0
        inc     r0
        movc    a,@a+DPTR
        movc    a,@a+DPTR
        mov     B,a
        mov     B,a
        mov     a,r0                ; ...then load A with test data...
        mov     a,r0                ; ...then load A with test data...
        inc     r0
        inc     r0
        movc    a,@a+DPTR
        movc    a,@a+DPTR
        mul     ab                  ; and do the MUL
        mul     ab                  ; and do the MUL
        mov     dir0,a              ; Save A for later checks
        mov     dir0,a              ; Save A for later checks
        mov     a,r0                ; Verify product high byte
        mov     a,r0                ; Verify product high byte
        ;inc     r0
        ;inc     r0
        movc    a,@a+DPTR
        movc    a,@a+DPTR
        jz      tt_b_noovf
        jz      tt_b_noovf
        mov     a,PSW               ; overflow expected
        mov     a,PSW               ; overflow expected
        anl     a,#04h
        anl     a,#04h
        jz      tt_b0
        jz      tt_b0
        sjmp    tt_b_0
        sjmp    tt_b_0
tt_b_noovf:
tt_b_noovf:
        mov     a,PSW               ; no overflow expected
        mov     a,PSW               ; no overflow expected
        anl     a,#04h
        anl     a,#04h
        jnz     tt_b0
        jnz     tt_b0
tt_b_0:
tt_b_0:
        mov     a,r0                ; Verify product high byte
        mov     a,r0                ; Verify product high byte
        inc     r0
        inc     r0
        movc    a,@a+DPTR
        movc    a,@a+DPTR
        cjne    a,B,tt_b0
        cjne    a,B,tt_b0
        mov     a,r0                ; ...and verify low byte
        mov     a,r0                ; ...and verify low byte
        inc     r0
        inc     r0
        movc    a,@a+DPTR
        movc    a,@a+DPTR
        cjne    a,dir0,tt_b0
        cjne    a,dir0,tt_b0
        dec     r1                  ; go for next test vector, if any
        dec     r1                  ; go for next test vector, if any
        mov     a,r1
        mov     a,r1
        jnz     tt_b_loop
        jnz     tt_b_loop
        eot     'b',tt_b0
        eot     'b',tt_b0
        sjmp    tt_b_tab_end
        sjmp    tt_b_tab_end
tt_b_tab:
tt_b_tab:
        db      7,19,0,133
        db      7,19,0,133
        db      7,17,0,119
        db      7,17,0,119
        db      7,13,0,91
        db      7,13,0,91
        db      13,17,0,221
        db      13,17,0,221
        db      17,13,0,221
        db      17,13,0,221
        db      0,13,0,0
        db      0,13,0,0
        db      80h,87h,43h,80h
        db      80h,87h,43h,80h
        db      1,255,0,255
        db      1,255,0,255
        db      2,255,01h,0feh
        db      2,255,01h,0feh
tt_b_tab_end:
tt_b_tab_end:
        put_crlf                    ; end of test series
        put_crlf                    ; end of test series
        ;-- Test series U ------------------------------------------------------
        ;-- Test series U ------------------------------------------------------
        ; Register banks
        ; Register banks
        ; a.- Write to register, read from indirect address.
        ; a.- Write to register, read from indirect address.
        ; a.- Write to indirect address, read from register.
        ; a.- Write to indirect address, read from register.
        ;
        ;
        putc    #'U'                ; start of test series
        putc    #'U'                ; start of test series
        mov     PSW,#00h            ; Test bank 0
        mov     PSW,#00h            ; Test bank 0
        mov     a,#00h + 1
        mov     a,#00h + 1
        call    tu_a_test
        call    tu_a_test
        mov     PSW,#08h            ; Test bank 1
        mov     PSW,#08h            ; Test bank 1
        mov     a,#08h + 1
        mov     a,#08h + 1
        call    tu_a_test
        call    tu_a_test
        mov     PSW,#10h            ; Test bank 2
        mov     PSW,#10h            ; Test bank 2
        mov     a,#10h + 1
        mov     a,#10h + 1
        call    tu_a_test
        call    tu_a_test
        mov     PSW,#18h            ; Test bank 3
        mov     PSW,#18h            ; Test bank 3
        mov     a,#18h + 1
        mov     a,#18h + 1
        call    tu_a_test
        call    tu_a_test
        sjmp    tu_a_done
        sjmp    tu_a_done
tu_a_test:
tu_a_test:
        mov     r0,a                ; R0 points to R1 in the selected bank.
        mov     r0,a                ; R0 points to R1 in the selected bank.
        mov     r1,#12h             ; Write to registers R1 and R7
        mov     r1,#12h             ; Write to registers R1 and R7
        mov     r7,#34h
        mov     r7,#34h
        mov     a,@r0               ; Check R1
        mov     a,@r0               ; Check R1
        cjne    a,#12h,tu_a0
        cjne    a,#12h,tu_a0
        mov     a,#56h              ; Ok, now write to R1 with reg addressing...
        mov     a,#56h              ; Ok, now write to R1 with reg addressing...
        mov     @r0,a               ; ...and check by reading in indirect.
        mov     @r0,a               ; ...and check by reading in indirect.
        cjne    r1,#56h,tu_a0
        cjne    r1,#56h,tu_a0
        mov     a,r0                ; Set R0 to point to R7 in selected bank
        mov     a,r0                ; Set R0 to point to R7 in selected bank
        add     a,#06h
        add     a,#06h
        mov     r0,a
        mov     r0,a
        mov     a,@r0               ; Check R7
        mov     a,@r0               ; Check R7
        cjne    a,#34h,tu_a0
        cjne    a,#34h,tu_a0
        mov     a,#78h              ; Ok, now write to R7 with reg addressing...
        mov     a,#78h              ; Ok, now write to R7 with reg addressing...
        mov     @r0,a               ; ...and check by reading in indirect.
        mov     @r0,a               ; ...and check by reading in indirect.
        cjne    a,#78h,tu_a0
        cjne    a,#78h,tu_a0
        ret
        ret
tu_a_done:
tu_a_done:
        nop
        nop
        eot     'a',tu_a0
        eot     'a',tu_a0
        put_crlf                    ; end of test series
        put_crlf                    ; end of test series
        ;-- Test series V ------------------------------------------------------
        ;-- Test series V ------------------------------------------------------
        ; NOP and potentially unimplemented opcodes (DA and XCHD).
        ; NOP and potentially unimplemented opcodes (DA and XCHD).
        ; In order to make sure an instruction does nothing we would have to
        ; In order to make sure an instruction does nothing we would have to
        ; check everything: IRAM, XRAM and SFRs. We will leave that to the
        ; check everything: IRAM, XRAM and SFRs. We will leave that to the
        ; zexall-style tester. In this test we rely on the cosimulation with
        ; zexall-style tester. In this test we rely on the cosimulation with
        ; software simulator B51.
        ; software simulator B51.
        ;
        ;
        ; a.- Opcode 0A5h
        ; a.- Opcode 0A5h
        ; b.- DA
        ; b.- DA
        ; c.- XCHD A, @Ri
        ; c.- XCHD A, @Ri
        putc    #'V'                ; start of test series
        putc    #'V'                ; start of test series
        ; a.- <0A5>
        ; a.- <0A5>
        db      0a5h                ; Put opcode right there...
        db      0a5h                ; Put opcode right there...
        nop                         ; and do no check at all -- rely on B51.
        nop                         ; and do no check at all -- rely on B51.
        ; we'll catch any unintended side effects by comparing the logs.
        ; we'll catch any unintended side effects by comparing the logs.
        ; Obviously this is no good for any core other then light52...
        ; Obviously this is no good for any core other then light52...
        eot     'a',tv_a0
        eot     'a',tv_a0
        ; b.- 
        ; b.- 
        ifdef   BCD
        ifdef   BCD
        ; DA implemented in CPU
        ; DA implemented in CPU
        mov     psw,#000h           ; Al>9, AC=0
        mov     psw,#000h           ; Al>9, AC=0
        mov     a,#01ah
        mov     a,#01ah
        da      a
        da      a
        mov     saved_psw,psw
        mov     saved_psw,psw
        cjne    a,#020h,tv_b0
        cjne    a,#020h,tv_b0
        mov     a,saved_psw
        mov     a,saved_psw
        cjne    a,#001h,tv_b0
        cjne    a,#001h,tv_b0
        mov     psw,#040h           ; Al<9, AC=1
        mov     psw,#040h           ; Al<9, AC=1
        mov     a,#012h
        mov     a,#012h
        da      a
        da      a
        mov     saved_psw,psw
        mov     saved_psw,psw
        cjne    a,#018h,tv_b0
        cjne    a,#018h,tv_b0
        mov     a,saved_psw
        mov     a,saved_psw
        cjne    a,#040h,tv_b0
        cjne    a,#040h,tv_b0
        mov     psw,#040h           ; Al>9, AC=1 (hardly possible in BCD)
        mov     psw,#040h           ; Al>9, AC=1 (hardly possible in BCD)
        mov     a,#01ah
        mov     a,#01ah
        da      a
        da      a
        mov     saved_psw,psw
        mov     saved_psw,psw
        cjne    a,#020h,tv_b0
        cjne    a,#020h,tv_b0
        mov     a,saved_psw
        mov     a,saved_psw
        cjne    a,#041h,tv_b0
        cjne    a,#041h,tv_b0
        mov     psw,#0c0h           ; AC=CY=1
        mov     psw,#0c0h           ; AC=CY=1
        mov     a,#000h
        mov     a,#000h
        da      a
        da      a
        mov     saved_psw,psw
        mov     saved_psw,psw
        cjne    a,#066h,tv_b0
        cjne    a,#066h,tv_b0
        mov     a,saved_psw
        mov     a,saved_psw
        cjne    a,#0c0h,tv_b0
        cjne    a,#0c0h,tv_b0
        mov     psw,#040h           ; DA generates carry
        mov     psw,#040h           ; DA generates carry
        mov     a,#0fah
        mov     a,#0fah
        da      a
        da      a
        mov     saved_psw,psw
        mov     saved_psw,psw
        cjne    a,#060h,tv_b0
        cjne    a,#060h,tv_b0
        mov     a,saved_psw
        mov     a,saved_psw
        cjne    a,#0c0h,tv_b0
        cjne    a,#0c0h,tv_b0
        else
        else
        ; DA unimplemented in CPU
        ; DA unimplemented in CPU
        mov     a,#01ah             ; This would be adjusted by DA to 020h...
        mov     a,#01ah             ; This would be adjusted by DA to 020h...
        da      a                   ; ...make sure it isn't
        da      a                   ; ...make sure it isn't
        cjne    a,#01ah,tv_b0
        cjne    a,#01ah,tv_b0
        nop
        nop
        endif
        endif
        eot     'b',tv_b0
        eot     'b',tv_b0
        ; c.- XCHD a,@ri
        ; c.- XCHD a,@ri
        ifdef   BCD
        ifdef   BCD
        ; XCHD implemented in CPU, test opcode.
        ; XCHD implemented in CPU, test opcode.
        mov     r0,#031h
        mov     r0,#031h
        mov     r1,#032h
        mov     r1,#032h
        mov     a,#042h
        mov     a,#042h
        mov     @r0,a
        mov     @r0,a
        inc     a
        inc     a
        mov     @r1,a
        mov     @r1,a
        mov     a,#76h
        mov     a,#76h
        xchd    a,@r0
        xchd    a,@r0
        cjne    a,#072h,tv_c0
        cjne    a,#072h,tv_c0
        mov     a,31h
        mov     a,31h
        cjne    a,#046h,tv_c0
        cjne    a,#046h,tv_c0
        mov     a,#79h
        mov     a,#79h
        xchd    a,@r1
        xchd    a,@r1
        cjne    a,#073h,tv_c0
        cjne    a,#073h,tv_c0
        mov     a,32h
        mov     a,32h
        cjne    a,#049h,tv_c0
        cjne    a,#049h,tv_c0
        else
        else
        ; XCHD unimplemented, make sure the nibbles aren't exchanged.
        ; XCHD unimplemented, make sure the nibbles aren't exchanged.
        mov     r0,#031h
        mov     r0,#031h
        mov     r1,#032h
        mov     r1,#032h
        mov     a,#042h
        mov     a,#042h
        mov     @r0,a
        mov     @r0,a
        mov     @r1,a
        mov     @r1,a
        mov     a,#76h
        mov     a,#76h
        xchd    a,@r0
        xchd    a,@r0
        cjne    a,#076h,tv_c0
        cjne    a,#076h,tv_c0
        mov     a,#76h
        mov     a,#76h
        xchd    a,@r1
        xchd    a,@r1
        cjne    a,#076h,tv_c0
        cjne    a,#076h,tv_c0
        endif
        endif
        eot     'c',tv_c0
        eot     'c',tv_c0
        put_crlf                    ; end of test series
        put_crlf                    ; end of test series
        ;-- Template for test series -------------------------------------------
        ;-- Template for test series -------------------------------------------
        ;-- Test series X ------------------------------------------------------
        ;-- Test series X ------------------------------------------------------
        ;
        ;
        ; a.-
        ; a.-
        ;putc    #'X'                ; start of test series
        ;putc    #'X'                ; start of test series
        ;put_crlf                    ; end of test series
        ;put_crlf                    ; end of test series
        ;-----------------------------------------------------------------------
        ;-----------------------------------------------------------------------
        ; Test cases finished. Now print completion message dependent on the
        ; Test cases finished. Now print completion message dependent on the
        ; value of the fail flag.
        ; value of the fail flag.
        mov     a,fail
        mov     a,fail
        jnz     test_failed
        jnz     test_failed
        put_crlf
        put_crlf
        putc    #'P'
        putc    #'P'
        putc    #'A'
        putc    #'A'
        putc    #'S'
        putc    #'S'
        putc    #'S'
        putc    #'S'
        put_crlf
        put_crlf
        sjmp    quit
        sjmp    quit
test_failed:
test_failed:
        put_crlf
        put_crlf
        putc    #'F'
        putc    #'F'
        putc    #'A'
        putc    #'A'
        putc    #'I'
        putc    #'I'
        putc    #'L'
        putc    #'L'
        put_crlf
        put_crlf
        sjmp    quit
        sjmp    quit
        ;-- End of test program, enter single-instruction endless loop
        ;-- End of test program, enter single-instruction endless loop
quit:   ajmp    $
quit:   ajmp    $
        ; We'll place a few test routines in the 2nd half of the code space so
        ; We'll place a few test routines in the 2nd half of the code space so
        ; we can test long jumps and calls onto different code pages.
        ; we can test long jumps and calls onto different code pages.
        org     8000h
        org     8000h
        ; tr_sub2: part of the JMP @A+DPTR test.
        ; tr_sub2: part of the JMP @A+DPTR test.
        ; HAS TO BE in 8000h so we can test the A+DPTR carry propagation!
        ; HAS TO BE in 8000h so we can test the A+DPTR carry propagation!
tr_sub2:
tr_sub2:
        jmp     tr_rv3
        jmp     tr_rv3
        jmp     tr_c0
        jmp     tr_c0
        ; Make sure the assumption we'll make in the test is actually valid
        ; Make sure the assumption we'll make in the test is actually valid
        if      LOW(tr_sub2) ne 0
        if      LOW(tr_sub2) ne 0
        $error("Label 'tr_sub2' must be at an address multiple of 256 to properly test JMP @A+DPTR")
        $error("Label 'tr_sub2' must be at an address multiple of 256 to properly test JMP @A+DPTR")
        endif
        endif
        ; tr_sub3: part of the LJMP test.
        ; tr_sub3: part of the LJMP test.
tr_sub3:
tr_sub3:
        jmp     tr_rv4
        jmp     tr_rv4
        jmp     tr_d0
        jmp     tr_d0
        ; tr_sub1: part of the LCALL test.
        ; tr_sub1: part of the LCALL test.
tr_sub1:
tr_sub1:
        mov     A,SP
        mov     A,SP
        cjne    A,#53h,tr_sub1_fail ; ...verify the SP value...
        cjne    A,#53h,tr_sub1_fail ; ...verify the SP value...
        mov     A,52h               ; ...and verify the pushed ret address
        mov     A,52h               ; ...and verify the pushed ret address
        cjne    A,#LOW(tr_rv1),tr_sub1_fail
        cjne    A,#LOW(tr_rv1),tr_sub1_fail
        mov     A,53h
        mov     A,53h
        cjne    A,#HIGH(tr_rv1),tr_sub1_fail
        cjne    A,#HIGH(tr_rv1),tr_sub1_fail
        ljmp    tr_rv2
        ljmp    tr_rv2
tr_sub1_fail:
tr_sub1_fail:
        ljmp    tr_b0
        ljmp    tr_b0
        end
        end
 
 

powered by: WebSVN 2.1.0

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