;-------------------------------------------------------------------------------
|
;-------------------------------------------------------------------------------
|
; 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
|
|
|