From 24a3ab6a80292c00eef036b520add092f9d952ff Mon Sep 17 00:00:00 2001 From: Astrid Smith Date: Mon, 15 Nov 2010 23:32:59 -0800 Subject: Pattern rule for testbenches added --- testbenches/mine.testbench.z80 | 57 ++ testbenches/mine.z80 | 57 -- testbenches/zexall.testbench.z80 | 1546 ++++++++++++++++++++++++++++++++++++++ testbenches/zexall.z80 | 1546 -------------------------------------- testbenches/zexdoc.testbench.z80 | 1543 +++++++++++++++++++++++++++++++++++++ testbenches/zexdoc.z80 | 1543 ------------------------------------- 6 files changed, 3146 insertions(+), 3146 deletions(-) create mode 100644 testbenches/mine.testbench.z80 delete mode 100644 testbenches/mine.z80 create mode 100644 testbenches/zexall.testbench.z80 delete mode 100644 testbenches/zexall.z80 create mode 100644 testbenches/zexdoc.testbench.z80 delete mode 100644 testbenches/zexdoc.z80 (limited to 'testbenches') diff --git a/testbenches/mine.testbench.z80 b/testbenches/mine.testbench.z80 new file mode 100644 index 0000000..57c6998 --- /dev/null +++ b/testbenches/mine.testbench.z80 @@ -0,0 +1,57 @@ +;;; -*- asm -*- +;;; + +.ORG 4000h + + call cond_jr_no ;cd + halt ;76 + +inc8: + ld bc,data8 ;01 + ;; BC should have &data8 + ld a,(bc) ;0a + inc a ;3c + ld (bc),a ;02 + halt + +dec8: + ld a,0a5h ;3e + dec a ;3d + ret ;c9 + + ;; Test jump-not-taken of JR [C,NC,Z] +cond_jr_no: + ld a,01h ;3e 01 + cp a ;bf + jr nz,wrong ;20 07 + + ccf ;3f + jr c,wrong ;38 + + scf ;37 + jr nc,wrong ;30 + ret ;c9 + +wrong: + jp wrong + + ;; Test jump-taken of JR [C,NC,Z] +cond_jr_yes: + ld a,01h ;3e 01 + ld b,02h ;06 02 + cp b ;b8 + jr nz,right1 ;20 + jp wrong +right1: scf ;37 + jr c,right2 ;38 + jp wrong +right2: ccf ;3f + jr nc,right3 ;30 + jp wrong +right3: ret ;c9 + + +data8: + .db 0a5h +data16: + .dw data8 diff --git a/testbenches/mine.z80 b/testbenches/mine.z80 deleted file mode 100644 index 57c6998..0000000 --- a/testbenches/mine.z80 +++ /dev/null @@ -1,57 +0,0 @@ -;;; -*- asm -*- -;;; - -.ORG 4000h - - call cond_jr_no ;cd - halt ;76 - -inc8: - ld bc,data8 ;01 - ;; BC should have &data8 - ld a,(bc) ;0a - inc a ;3c - ld (bc),a ;02 - halt - -dec8: - ld a,0a5h ;3e - dec a ;3d - ret ;c9 - - ;; Test jump-not-taken of JR [C,NC,Z] -cond_jr_no: - ld a,01h ;3e 01 - cp a ;bf - jr nz,wrong ;20 07 - - ccf ;3f - jr c,wrong ;38 - - scf ;37 - jr nc,wrong ;30 - ret ;c9 - -wrong: - jp wrong - - ;; Test jump-taken of JR [C,NC,Z] -cond_jr_yes: - ld a,01h ;3e 01 - ld b,02h ;06 02 - cp b ;b8 - jr nz,right1 ;20 - jp wrong -right1: scf ;37 - jr c,right2 ;38 - jp wrong -right2: ccf ;3f - jr nc,right3 ;30 - jp wrong -right3: ret ;c9 - - -data8: - .db 0a5h -data16: - .dw data8 diff --git a/testbenches/zexall.testbench.z80 b/testbenches/zexall.testbench.z80 new file mode 100644 index 0000000..586f9ef --- /dev/null +++ b/testbenches/zexall.testbench.z80 @@ -0,0 +1,1546 @@ + .title 'Z80 instruction set exerciser' + +; zexlax.z80 - Z80 instruction set exerciser +; Copyright (C) 1994 Frank D. Cringle +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; as published by the Free Software Foundation; either version 2 +; of the License, or (at your option) any later version. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, write to the Free Software +; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + aseg + org 100h + + jp start + +; machine state before test (needs to be at predictably constant address) +msbt: ds 14 +spbt: ds 2 + +; For the purposes of this test program, the machine state consists of: +; a 2 byte memory operand, followed by +; the registers iy,ix,hl,de,bc,af,sp +; for a total of 16 bytes. + +; The program tests instructions (or groups of similar instructions) +; by cycling through a sequence of machine states, executing the test +; instruction for each one and running a 32-bit crc over the resulting +; machine states. At the end of the sequence the crc is compared to +; an expected value that was found empirically on a real Z80. + +; A test case is defined by a descriptor which consists of: +; a flag mask byte, +; the base case, +; the incement vector, +; the shift vector, +; the expected crc, +; a short descriptive message. +; +; The flag mask byte is used to prevent undefined flag bits from +; influencing the results. Documented flags are as per Mostek Z80 +; Technical Manual. +; +; The next three parts of the descriptor are 20 byte vectors +; corresponding to a 4 byte instruction and a 16 byte machine state. +; The first part is the base case, which is the first test case of +; the sequence. This base is then modified according to the next 2 +; vectors. Each 1 bit in the increment vector specifies a bit to be +; cycled in the form of a binary counter. For instance, if the byte +; corresponding to the accumulator is set to 0ffh in the increment +; vector, the test will be repeated for all 256 values of the +; accumulator. Note that 1 bits don't have to be contiguous. The +; number of test cases 'caused' by the increment vector is equal to +; 2^(number of 1 bits). The shift vector is similar, but specifies a +; set of bits in the test case that are to be successively inverted. +; Thus the shift vector 'causes' a number of test cases equal to the +; number of 1 bits in it. + +; The total number of test cases is the product of those caused by the +; counter and shift vectors and can easily become unweildy. Each +; individual test case can take a few milliseconds to execute, due to +; the overhead of test setup and crc calculation, so test design is a +; compromise between coverage and execution time. + +; This program is designed to detect differences between +; implementations and is not ideal for diagnosing the causes of any +; discrepancies. However, provided a reference implementation (or +; real system) is available, a failing test case can be isolated by +; hand using a binary search of the test space. + + +start: ld hl,(6) + ld sp,hl + ld de,msg1 + ld c,9 + call bdos + + ld hl,tests ; first test case +loop: ld a,(hl) ; end of list ? + inc hl + or (hl) + jp z,done + dec hl + call stt + jp loop + +done: ld de,msg2 + ld c,9 + call bdos + jp 0 ; warm boot + +tests: + dw adc16 + dw add16 + dw add16x + dw add16y + dw alu8i + dw alu8r + dw alu8rx + dw alu8x + dw bitx + dw bitz80 + dw cpd1 + dw cpi1 + dw daa + dw inca + dw incb + dw incbc + dw incc + dw incd + dw incde + dw ince + dw inch + dw inchl + dw incix + dw inciy + dw incl + dw incm + dw incsp + dw incx + dw incxh + dw incxl + dw incyh + dw incyl + dw ld161 + dw ld162 + dw ld163 + dw ld164 + dw ld165 + dw ld166 + dw ld167 + dw ld168 + dw ld16im + dw ld16ix + dw ld8bd + dw ld8im + dw ld8imx + dw ld8ix1 + dw ld8ix2 + dw ld8ix3 + dw ld8ixy + dw ld8rr + dw ld8rrx + dw lda + dw ldd1 + dw ldd2 + dw ldi1 + dw ldi2 + dw neg + dw rld + dw rot8080 + dw rotxy + dw rotz80 + dw srz80 + dw srzx + dw st8ix1 + dw st8ix2 + dw st8ix3 + dw stabd + dw 0 + +tstr: macro insn,memop,iy,ix,hl,de,bc,flags,acc,sp + local lab +&lab: db insn + ds &lab+4-$,0 + dw &memop,&iy,&ix,&hl,&de,&bc + db &flags + db &acc + dw &sp + if $-&lab ne 20 + error 'missing parameter' + endif + endm + +tmsg: macro m + local lab +&lab: db m + if $ ge &lab+30 + error 'message too long' + else + ds &lab+30-$,'.' + endif + db '$' + endm + +; hl, (38,912 cycles) +adc16: db 0ffh ; flag mask + tstr <0edh,042h>,0832ch,04f88h,0f22bh,0b339h,07e1fh,01563h,0d3h,089h,0465eh + tstr <0,038h>,0,0,0,0f821h,0,0,0,0,0 ; (1024 cycles) + tstr 0,0,0,0,-1,-1,-1,0d7h,0,-1 ; (38 cycles) + db 0d4h,08ah,0d5h,019h ; expected crc + tmsg ' hl,' + +; add hl, (19,456 cycles) +add16: db 0ffh ; flag mask + tstr 9,0c4a5h,0c4c7h,0d226h,0a050h,058eah,08566h,0c6h,0deh,09bc9h + tstr 030h,0,0,0,0f821h,0,0,0,0,0 ; (512 cycles) + tstr 0,0,0,0,-1,-1,-1,0d7h,0,-1 ; (38 cycles) + db 0d9h,0a4h,0cah,005h ; expected crc + tmsg 'add hl,' + +; add ix, (19,456 cycles) +add16x: db 0ffh ; flag mask + tstr <0ddh,9>,0ddach,0c294h,0635bh,033d3h,06a76h,0fa20h,094h,068h,036f5h + tstr <0,030h>,0,0,0f821h,0,0,0,0,0,0 ; (512 cycles) + tstr 0,0,0,-1,0,-1,-1,0d7h,0,-1 ; (38 cycles) + db 0b1h,0dfh,08eh,0c0h ; expected crc + tmsg 'add ix,' + +; add iy, (19,456 cycles) +add16y: db 0ffh ; flag mask + tstr <0fdh,9>,0c7c2h,0f407h,051c1h,03e96h,00bf4h,0510fh,092h,01eh,071eah + tstr <0,030h>,0,0f821h,0,0,0,0,0,0,0 ; (512 cycles) + tstr 0,0,-1,0,0,-1,-1,0d7h,0,-1 ; (38 cycles) + db 039h,0c8h,058h,09bh ; expected crc + tmsg 'add iy,' + +; aluop a,nn (28,672 cycles) +alu8i: db 0ffh ; flag mask + tstr 0c6h,09140h,07e3ch,07a67h,0df6dh,05b61h,00b29h,010h,066h,085b2h + tstr 038h,0,0,0,0,0,0,0,-1,0 ; (2048 cycles) + tstr <0,-1>,0,0,0,0,0,0,0d7h,0,0 ; (14 cycles) + db 051h,0c1h,09ch,02eh ; expected crc + tmsg 'aluop a,nn' + +; aluop a, (753,664 cycles) +alu8r: db 0ffh ; flag mask + tstr 080h,0c53eh,0573ah,04c4dh,msbt,0e309h,0a666h,0d0h,03bh,0adbbh + tstr 03fh,0,0,0,0,0,0,0,-1,0 ; (16,384 cycles) + tstr 0,0ffh,0,0,0,-1,-1,0d7h,0,0 ; (46 cycles) + db 006h,0c7h,0aah,08eh ; expected crc + tmsg 'aluop a,' + +; aluop a, (376,832 cycles) +alu8rx: db 0ffh ; flag mask + tstr <0ddh,084h>,0d6f7h,0c76eh,0accfh,02847h,022ddh,0c035h,0c5h,038h,0234bh + tstr <020h,039h>,0,0,0,0,0,0,0,-1,0 ; (8,192 cycles) + tstr 0,0ffh,0,0,0,-1,-1,0d7h,0,0 ; (46 cycles) + db 0a8h,086h,0cch,044h ; expected crc + tmsg 'aluop a,' + +; aluop a,(+1) (229,376 cycles) +alu8x: db 0ffh ; flag mask + tstr <0ddh,086h,1>,090b7h,msbt-1,msbt-1,032fdh,0406eh,0c1dch,045h,06eh,0e5fah + tstr <020h,038h>,0,1,1,0,0,0,0,-1,0 ; (16,384 cycles) + tstr 0,0ffh,0,0,0,0,0,0d7h,0,0 ; (14 cycles) + db 0d3h,0f2h,0d7h,04ah ; expected crc + tmsg 'aluop a,(+1)' + +; bit n,(+1) (2048 cycles) +bitx: db 0ffh ; flag mask + tstr <0ddh,0cbh,1,046h>,02075h,msbt-1,msbt-1,03cfch,0a79ah,03d74h,051h,027h,0ca14h + tstr <020h,0,0,038h>,0,0,0,0,0,0,053h,0,0 ; (256 cycles) + tstr 0,0ffh,0,0,0,0,0,0,0,0 ; (8 cycles) + db 083h,053h,04eh,0e1h ; expected crc + tmsg 'bit n,(+1)' + +; bit n, (49,152 cycles) +bitz80: db 0ffh ; flag mask + tstr <0cbh,040h>,03ef1h,09dfch,07acch,msbt,0be61h,07a86h,050h,024h,01998h + tstr <0,03fh>,0,0,0,0,0,0,053h,0,0 ; (1024 cycles) + tstr 0,0ffh,0,0,0,-1,-1,0,-1,0 ; (48 cycles) + db 05eh,002h,00eh,098h ; expected crc + tmsg 'bit n,' + +; cpd (1) (6144 cycles) +cpd1: db 0ffh ; flag mask + tstr <0edh,0a9h>,0c7b6h,072b4h,018f6h,msbt+17,08dbdh,1,0c0h,030h,094a3h + tstr <0,010h>,0,0,0,0,0,010,0,-1,0 ; (1024 cycles) + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + db 013h,04bh,062h,02dh ; expected crc + tmsg 'cpd' + +; cpi (1) (6144 cycles) +cpi1: db 0ffh ; flag mask + tstr <0edh,0a1h>,04d48h,0af4ah,0906bh,msbt,04e71h,1,093h,06ah,0907ch + tstr <0,010h>,0,0,0,0,0,010,0,-1,0 ; (1024 cycles) + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + db 02dh,0a4h,02dh,019h ; expected crc + tmsg 'cpi' + +; +daa: db 0ffh ; flag mask + tstr 027h,02141h,009fah,01d60h,0a559h,08d5bh,09079h,004h,08eh,0299dh + tstr 018h,0,0,0,0,0,0,0d7h,-1,0 ; (65,536 cycles) + tstr 0,0,0,0,0,0,0,0,0,0 ; (1 cycle) + db 06dh,02dh,0d2h,013h ; expected crc + tmsg '' + +; a (3072 cycles) +inca: db 0ffh ; flag mask + tstr 03ch,04adfh,0d5d8h,0e598h,08a2bh,0a7b0h,0431bh,044h,05ah,0d030h + tstr 001h,0,0,0,0,0,0,0,-1,0 ; (512 cycles) + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + db 081h,0fah,081h,000h ; expected crc + tmsg ' a' + +; b (3072 cycles) +incb: db 0ffh ; flag mask + tstr 004h,0d623h,0432dh,07a61h,08180h,05a86h,01e85h,086h,058h,09bbbh + tstr 001h,0,0,0,0,0,0ff00h,0,0,0 ; (512 cycles) + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + db 077h,0f3h,05ah,073h ; expected crc + tmsg ' b' + +; bc (1536 cycles) +incbc: db 0ffh ; flag mask + tstr 003h,0cd97h,044abh,08dc9h,0e3e3h,011cch,0e8a4h,002h,049h,02a4dh + tstr 008h,0,0,0,0,0,0f821h,0,0,0 ; (256 cycles) + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + db 0d2h,0aeh,03bh,0ech ; expected crc + tmsg ' bc' + +; c (3072 cycles) +incc: db 0ffh ; flag mask + tstr 00ch,0d789h,00935h,0055bh,09f85h,08b27h,0d208h,095h,005h,00660h + tstr 001h,0,0,0,0,0,0ffh,0,0,0 ; (512 cycles) + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + db 01ah,0f6h,012h,0a7h ; expected crc + tmsg ' c' + +; d (3072 cycles) +incd: db 0ffh ; flag mask + tstr 014h,0a0eah,05fbah,065fbh,0981ch,038cch,0debch,043h,05ch,003bdh + tstr 001h,0,0,0,0,0ff00h,0,0,0,0 ; (512 cycles) + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + db 0d1h,046h,0bfh,051h ; expected crc + tmsg ' d' + +; de (1536 cycles) +incde: db 0ffh ; flag mask + tstr 013h,0342eh,0131dh,028c9h,00acah,09967h,03a2eh,092h,0f6h,09d54h + tstr 008h,0,0,0,0,0f821h,0,0,0,0 ; (256 cycles) + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + db 0aeh,0c6h,0d4h,02ch ; expected crc + tmsg ' de' + +; e (3072 cycles) +ince: db 0ffh ; flag mask + tstr 01ch,0602fh,04c0dh,02402h,0e2f5h,0a0f4h,0a10ah,013h,032h,05925h + tstr 001h,0,0,0,0,0ffh,0,0,0,0 ; (512 cycles) + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + db 0cah,08ch,06ah,0c2h ; expected crc + tmsg ' e' + +; h (3072 cycles) +inch: db 0ffh ; flag mask + tstr 024h,01506h,0f2ebh,0e8ddh,0262bh,011a6h,0bc1ah,017h,006h,02818h + tstr 001h,0,0,0,0ff00h,0,0,0,0,0 ; (512 cycles) + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + db 056h,00fh,095h,05eh ; expected crc + tmsg ' h' + +; hl (1536 cycles) +inchl: db 0ffh ; flag mask + tstr 023h,0c3f4h,007a5h,01b6dh,04f04h,0e2c2h,0822ah,057h,0e0h,0c3e1h + tstr 008h,0,0,0,0f821h,0,0,0,0,0 ; (256 cycles) + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + db 0fch,00dh,06dh,04ah ; expected crc + tmsg ' hl' + +; ix (1536 cycles) +incix: db 0ffh ; flag mask + tstr <0ddh,023h>,0bc3ch,00d9bh,0e081h,0adfdh,09a7fh,096e5h,013h,085h,00be2h + tstr <0,8>,0,0,0f821h,0,0,0,0,0,0 ; (256 cycles) + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + db 0a5h,04dh,0beh,031h ; expected crc + tmsg ' ix' + +; iy (1536 cycles) +inciy: db 0ffh ; flag mask + tstr <0fdh,023h>,09402h,0637ah,03182h,0c65ah,0b2e9h,0abb4h,016h,0f2h,06d05h + tstr <0,8>,0,0f821h,0,0,0,0,0,0,0 ; (256 cycles) + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + db 050h,05dh,051h,0a3h ; expected crc + tmsg ' iy' + +; l (3072 cycles) +incl: db 0ffh ; flag mask + tstr 02ch,08031h,0a520h,04356h,0b409h,0f4c1h,0dfa2h,0d1h,03ch,03ea2h + tstr 001h,0,0,0,0ffh,0,0,0,0,0 ; (512 cycles) + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + db 0a0h,0a1h,0b4h,09fh ; expected crc + tmsg ' l' + +; (hl) (3072 cycles) +incm: db 0ffh ; flag mask + tstr 034h,0b856h,00c7ch,0e53eh,msbt,0877eh,0da58h,015h,05ch,01f37h + tstr 001h,0ffh,0,0,0,0,0,0,0,0 ; (512 cycles) + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + db 028h,029h,05eh,0ceh ; expected crc + tmsg ' (hl)' + +; sp (1536 cycles) +incsp: db 0ffh ; flag mask + tstr 033h,0346fh,0d482h,0d169h,0deb6h,0a494h,0f476h,053h,002h,0855bh + tstr 008h,0,0,0,0,0,0,0,0,0f821h ; (256 cycles) + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + db 05dh,0ach,0d5h,027h ; expected crc + tmsg ' sp' + +; (+1) (6144 cycles) +incx: db 0ffh ; flag mask + tstr <0ddh,034h,1>,0fa6eh,msbt-1,msbt-1,02c28h,08894h,05057h,016h,033h,0286fh + tstr <020h,1>,0ffh,0,0,0,0,0,0,0,0 ; (1024 cycles) + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + db 00bh,095h,0a8h,0eah ; expected crc + tmsg ' (+1)' + +; ixh (3072 cycles) +incxh: db 0ffh ; flag mask + tstr <0ddh,024h>,0b838h,0316ch,0c6d4h,03e01h,08358h,015b4h,081h,0deh,04259h + tstr <0,1>,0,0ff00h,0,0,0,0,0,0,0 ; (512 cycles) + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + db 06fh,046h,036h,062h ; expected crc + tmsg ' ixh' + +; ixl (3072 cycles) +incxl: db 0ffh ; flag mask + tstr <0ddh,02ch>,04d14h,07460h,076d4h,006e7h,032a2h,0213ch,0d6h,0d7h,099a5h + tstr <0,1>,0,0ffh,0,0,0,0,0,0,0 ; (512 cycles) + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + db 002h,07bh,0efh,02ch ; expected crc + tmsg ' ixl' + +; iyh (3072 cycles) +incyh: db 0ffh ; flag mask + tstr <0ddh,024h>,02836h,09f6fh,09116h,061b9h,082cbh,0e219h,092h,073h,0a98ch + tstr <0,1>,0ff00h,0,0,0,0,0,0,0,0 ; (512 cycles) + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + db 02dh,096h,06ch,0f3h ; expected crc + tmsg ' iyh' + +; iyl (3072 cycles) +incyl: db 0ffh ; flag mask + tstr <0ddh,02ch>,0d7c6h,062d5h,0a09eh,07039h,03e7eh,09f12h,090h,0d9h,0220fh + tstr <0,1>,0ffh,0,0,0,0,0,0,0,0 ; (512 cycles) + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + db 036h,0c1h,01eh,075h ; expected crc + tmsg ' iyl' + +; ld ,(nnnn) (32 cycles) +ld161: db 0ffh ; flag mask + tstr <0edh,04bh,low msbt,high msbt>,0f9a8h,0f559h,093a4h,0f5edh,06f96h,0d968h,086h,0e6h,04bd8h + tstr <0,010h>,0,0,0,0,0,0,0,0,0 ; (2 cycles) + tstr 0,-1,0,0,0,0,0,0,0,0 ; (16 cycles) + db 04dh,045h,0a9h,0ach ; expected crc + tmsg 'ld ,(nnnn)' + +; ld hl,(nnnn) (16 cycles) +ld162: db 0ffh ; flag mask + tstr <02ah,low msbt,high msbt>,09863h,07830h,02077h,0b1feh,0b9fah,0abb8h,004h,006h,06015h + tstr 0,0,0,0,0,0,0,0,0,0 ; (1 cycle) + tstr 0,-1,0,0,0,0,0,0,0,0 ; (16 cycles) + db 05fh,097h,024h,087h ; expected crc + tmsg 'ld hl,(nnnn)' + +; ld sp,(nnnn) (16 cycles) +ld163: db 0ffh ; flag mask + tstr <0edh,07bh,low msbt,high msbt>,08dfch,057d7h,02161h,0ca18h,0c185h,027dah,083h,01eh,0f460h + tstr 0,0,0,0,0,0,0,0,0,0 ; (1 cycles) + tstr 0,-1,0,0,0,0,0,0,0,0 ; (16 cycles) + db 07ah,0ceh,0a1h,01bh ; expected crc + tmsg 'ld sp,(nnnn)' + +; ld ,(nnnn) (32 cycles) +ld164: db 0ffh ; flag mask + tstr <0ddh,02ah,low msbt,high msbt>,0ded7h,0a6fah,0f780h,0244ch,087deh,0bcc2h,016h,063h,04c96h + tstr 020h,0,0,0,0,0,0,0,0,0 ; (2 cycles) + tstr 0,-1,0,0,0,0,0,0,0,0 ; (16 cycles) + db 085h,08bh,0f1h,06dh ; expected crc + tmsg 'ld ,(nnnn)' + +; ld (nnnn), (64 cycles) +ld165: db 0ffh ; flag mask + tstr <0edh,043h,low msbt,high msbt>,01f98h,0844dh,0e8ach,0c9edh,0c95dh,08f61h,080h,03fh,0c7bfh + tstr <0,010h>,0,0,0,0,0,0,0,0,0 ; (2 cycles) + tstr 0,0,0,0,0,-1,-1,0,0,0 ; (32 cycles) + db 064h,01eh,087h,015h ; expected crc + tmsg 'ld (nnnn),' + +; ld (nnnn),hl (16 cycles) +ld166: db 0ffh ; flag mask + tstr <022h,low msbt,high msbt>,0d003h,07772h,07f53h,03f72h,064eah,0e180h,010h,02dh,035e9h + tstr 0,0,0,0,0,0,0,0,0,0 ; (1 cycle) + tstr 0,0,0,0,-1,0,0,0,0,0 ; (16 cycles) + db 0a3h,060h,08bh,047h ; expected crc + tmsg 'ld (nnnn),hl' + +; ld (nnnn),sp (16 cycles) +ld167: db 0ffh ; flag mask + tstr <0edh,073h,low msbt,high msbt>,0c0dch,0d1d6h,0ed5ah,0f356h,0afdah,06ca7h,044h,09fh,03f0ah + tstr 0,0,0,0,0,0,0,0,0,0 ; (1 cycle) + tstr 0,0,0,0,0,0,0,0,0,-1 ; (16 cycles) + db 016h,058h,05fh,0d7h ; expected crc + tmsg 'ld (nnnn),sp' + +; ld (nnnn), (64 cycles) +ld168: db 0ffh ; flag mask + tstr <0ddh,022h,low msbt,high msbt>,06cc3h,00d91h,06900h,08ef8h,0e3d6h,0c3f7h,0c6h,0d9h,0c2dfh + tstr 020h,0,0,0,0,0,0,0,0,0 ; (2 cycles) + tstr 0,0,-1,-1,0,0,0,0,0,0 ; (32 cycles) + db 0bah,010h,02ah,06bh ; expected crc + tmsg 'ld (nnnn),' + +; ld ,nnnn (64 cycles) +ld16im: db 0ffh ; flag mask + tstr 1,05c1ch,02d46h,08eb9h,06078h,074b1h,0b30eh,046h,0d1h,030cch + tstr 030h,0,0,0,0,0,0,0,0,0 ; (4 cycles) + tstr <0,0ffh,0ffh>,0,0,0,0,0,0,0,0,0 ; (16 cycles) + db 0deh,039h,019h,069h ; expected crc + tmsg 'ld ,nnnn' + +; ld ,nnnn (32 cycles) +ld16ix: db 0ffh ; flag mask + tstr <0ddh,021h>,087e8h,02006h,0bd12h,0b69bh,07253h,0a1e5h,051h,013h,0f1bdh + tstr 020h,0,0,0,0,0,0,0,0,0 ; (2 cycles) + tstr <0,0,0ffh,0ffh>,0,0,0,0,0,0,0,0,0 ; (16 cycles) + db 022h,07dh,0d5h,025h ; expected crc + tmsg 'ld ,nnnn' + +; ld a,<(bc),(de)> (44 cycles) +ld8bd: db 0ffh ; flag mask + tstr 00ah,0b3a8h,01d2ah,07f8eh,042ach,msbt,msbt,0c6h,0b1h,0ef8eh + tstr 010h,0,0,0,0,0,0,0,0,0 ; (2 cycles) + tstr 0,0ffh,0,0,0,0,0,0d7h,-1,0 ; (22 cycles) + db 0b0h,081h,089h,035h ; expected crc + tmsg 'ld a,<(bc),(de)>' + +; ld ,nn (64 cycles) +ld8im: db 0ffh ; flag mask + tstr 6,0c407h,0f49dh,0d13dh,00339h,0de89h,07455h,053h,0c0h,05509h + tstr 038h,0,0,0,0,0,0,0,0,0 ; (8 cycles) + tstr 0,0,0,0,0,0,0,0,-1,0 ; (8 cycles) + db 0f1h,0dah,0b5h,056h ; expected crc + tmsg 'ld ,nn' + +; ld (+1),nn (32 cycles) +ld8imx: db 0ffh ; flag mask + tstr <0ddh,036h,1>,01b45h,msbt-1,msbt-1,0d5c1h,061c7h,0bdc4h,0c0h,085h,0cd16h + tstr 020h,0,0,0,0,0,0,0,0,0 ; (2 cycles) + tstr <0,0,0,-1>,0,0,0,0,0,0,0,-1,0 ; (16 cycles) + db 026h,0dbh,047h,07eh ; expected crc + tmsg 'ld (+1),nn' + +; ld ,(+1) (512 cycles) +ld8ix1: db 0ffh ; flag mask + tstr <0ddh,046h,1>,0d016h,msbt-1,msbt-1,04260h,07f39h,00404h,097h,04ah,0d085h + tstr <020h,018h>,0,1,1,0,0,0,0,0,0 ; (32 cycles) + tstr 0,-1,0,0,0,0,0,0,0,0 ; (16 cycles) + db 0cch,011h,006h,0a8h ; expected crc + tmsg 'ld ,(+1)' + +; ld ,(+1) (256 cycles) +ld8ix2: db 0ffh ; flag mask + tstr <0ddh,066h,1>,084e0h,msbt-1,msbt-1,09c52h,0a799h,049b6h,093h,000h,0eeadh + tstr <020h,008h>,0,1,1,0,0,0,0,0,0 ; (16 cycles) + tstr 0,-1,0,0,0,0,0,0,0,0 ; (16 cycles) + db 0fah,02ah,04dh,003h ; expected crc + tmsg 'ld ,(+1)' + +; ld a,(+1) (128 cycles) +ld8ix3: db 0ffh ; flag mask + tstr <0ddh,07eh,1>,0d8b6h,msbt-1,msbt-1,0c612h,0df07h,09cd0h,043h,0a6h,0a0e5h + tstr 020h,0,1,1,0,0,0,0,0,0 ; (8 cycles) + tstr 0,-1,0,0,0,0,0,0,0,0 ; (16 cycles) + db 0a5h,0e9h,0ach,064h ; expected crc + tmsg 'ld a,(+1)' + +; ld ,nn (32 cycles) +ld8ixy: db 0ffh ; flag mask + tstr <0ddh,026h>,03c53h,04640h,0e179h,07711h,0c107h,01afah,081h,0adh,05d9bh + tstr <020h,8>,0,0,0,0,0,0,0,0,0 ; (4 cycles) + tstr 0,0,0,0,0,0,0,0,-1,0 ; (8 cycles) + db 024h,0e8h,082h,08bh ; expected crc + tmsg 'ld ,nn' + +; ld , (3456 cycles) +ld8rr: db 0ffh ; flag mask + tstr 040h,072a4h,0a024h,061ach,msbt,082c7h,0718fh,097h,08fh,0ef8eh + tstr 03fh,0,0,0,0,0,0,0,0,0 ; (64 cycles) + tstr 0,0ffh,0,0,0,-1,-1,0d7h,-1,0 ; (54 cycles) + db 074h,04bh,001h,018h ; expected crc + tmsg 'ld ,' + +; ld , (6912 cycles) +ld8rrx: db 0ffh ; flag mask + tstr <0ddh,040h>,0bcc5h,msbt,msbt,msbt,02fc2h,098c0h,083h,01fh,03bcdh + tstr <020h,03fh>,0,0,0,0,0,0,0,0,0 ; (128 cycles) + tstr 0,0ffh,0,0,0,-1,-1,0d7h,-1,0 ; (54 cycles) + db 047h,08bh,0a3h,06bh ; expected crc + tmsg 'ld ,' + +; ld a,(nnnn) / ld (nnnn),a (44 cycles) +lda: db 0ffh ; flag mask + tstr <032h,low msbt,high msbt>,0fd68h,0f4ech,044a0h,0b543h,00653h,0cdbah,0d2h,04fh,01fd8h + tstr 008h,0,0,0,0,0,0,0,0,0 ; (2 cycle) + tstr 0,0ffh,0,0,0,0,0,0d7h,-1,0 ; (22 cycles) + db 0c9h,026h,02dh,0e5h ; expected crc + tmsg 'ld a,(nnnn) / ld (nnnn),a' + +; ldd (1) (44 cycles) +ldd1: db 0ffh ; flag mask + tstr <0edh,0a8h>,09852h,068fah,066a1h,msbt+3,msbt+1,1,0c1h,068h,020b7h + tstr <0,010h>,0,0,0,0,0,0,0,0,0 ; (2 cycles) + tstr 0,-1,0,0,0,0,0,0d7h,0,0 ; (22 cycles) + db 094h,0f4h,027h,069h ; expected crc + tmsg 'ldd (1)' + +; ldd (2) (44 cycles) +ldd2: db 0ffh ; flag mask + tstr <0edh,0a8h>,0f12eh,0eb2ah,0d5bah,msbt+3,msbt+1,2,047h,0ffh,0fbe4h + tstr <0,010h>,0,0,0,0,0,0,0,0,0 ; (2 cycles) + tstr 0,-1,0,0,0,0,0,0d7h,0,0 ; (22 cycles) + db 039h,0ddh,03dh,0e1h ; expected crc + tmsg 'ldd (2)' + +; ldi (1) (44 cycles) +ldi1: db 0ffh ; flag mask + tstr <0edh,0a0h>,0fe30h,003cdh,06058h,msbt+2,msbt,1,004h,060h,02688h + tstr <0,010h>,0,0,0,0,0,0,0,0,0 ; (2 cycles) + tstr 0,-1,0,0,0,0,0,0d7h,0,0 ; (22 cycles) + db 0f7h,082h,0b0h,0d1h ; expected crc + tmsg 'ldi (1)' + +; ldi (2) (44 cycles) +ldi2: db 0ffh ; flag mask + tstr <0edh,0a0h>,04aceh,0c26eh,0b188h,msbt+2,msbt,2,014h,02dh,0a39fh + tstr <0,010h>,0,0,0,0,0,0,0,0,0 ; (2 cycles) + tstr 0,-1,0,0,0,0,0,0d7h,0,0 ; (22 cycles) + db 0e9h,0eah,0d0h,0aeh ; expected crc + tmsg 'ldi (2)' + +; neg (16,384 cycles) +neg: db 0ffh ; flag mask + tstr <0edh,044h>,038a2h,05f6bh,0d934h,057e4h,0d2d6h,04642h,043h,05ah,009cch + tstr 0,0,0,0,0,0,0,0d7h,-1,0 ; (16,384 cycles) + tstr 0,0,0,0,0,0,0,0,0,0 ; (1 cycle) + db 0d6h,038h,0ddh,06ah ; expected crc + tmsg 'neg' + +; (7168 cycles) +rld: db 0ffh ; flag mask + tstr <0edh,067h>,091cbh,0c48bh,0fa62h,msbt,0e720h,0b479h,040h,006h,08ae2h + tstr <0,8>,0ffh,0,0,0,0,0,0,0,0 ; (512 cycles) + tstr 0,0,0,0,0,0,0,0d7h,-1,0 ; (14 cycles) + db 0ffh,082h,03eh,077h ; expected crc + tmsg '' + +; (6144 cycles) +rot8080: db 0ffh ; flag mask + tstr 7,0cb92h,06d43h,00a90h,0c284h,00c53h,0f50eh,091h,0ebh,040fch + tstr 018h,0,0,0,0,0,0,0,-1,0 ; (1024 cycles) + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + db 09bh,0a3h,080h,07ch ; expected crc + tmsg '' + +; shift/rotate (+1) (416 cycles) +rotxy: db 0ffh ; flag mask + tstr <0ddh,0cbh,1,6>,0ddafh,msbt-1,msbt-1,0ff3ch,0dbf6h,094f4h,082h,080h,061d9h + tstr <020h,0,0,038h>,0,0,0,0,0,0,080h,0,0 ; (32 cycles) + tstr 0,0ffh,0,0,0,0,0,057h,0,0 ; (13 cycles) + db 071h,000h,034h,0cbh ; expected crc + tmsg 'shf/rot (+1)' + +; shift/rotate (6784 cycles) +rotz80: db 0ffh ; flag mask + tstr 0cbh,0ccebh,05d4ah,0e007h,msbt,01395h,030eeh,043h,078h,03dadh + tstr <0,03fh>,0,0,0,0,0,0,080h,0,0 ; (128 cycles) + tstr 0,0ffh,0,0,0,-1,-1,057h,-1,0 ; (53 cycles) + db 0a4h,025h,058h,033h ; expected crc + tmsg 'shf/rot ' + +; n, (7936 cycles) +srz80: db 0ffh ; flag mask + tstr <0cbh,080h>,02cd5h,097abh,039ffh,msbt,0d14bh,06ab2h,053h,027h,0b538h + tstr <0,07fh>,0,0,0,0,0,0,0,0,0 ; (128 cycles) + tstr 0,0ffh,0,0,0,-1,-1,0d7h,-1,0 ; (62 cycles) + db 08bh,057h,0f0h,008h ; expected crc + tmsg ' n,' + +; n,(+1) (1792 cycles) +srzx: db 0ffh ; flag mask + tstr <0ddh,0cbh,1,086h>,0fb44h,msbt-1,msbt-1,0ba09h,068beh,032d8h,010h,05eh,0a867h + tstr <020h,0,0,078h>,0,0,0,0,0,0,0,0,0 ; (128 cycles) + tstr 0,0ffh,0,0,0,0,0,0d7h,0,0 ;(14 cycles) + db 0cch,063h,0f9h,08ah ; expected crc + tmsg ' n,(+1)' + +; ld (+1), (1024 cycles) +st8ix1: db 0ffh ; flag mask + tstr <0ddh,070h,1>,0270dh,msbt-1,msbt-1,0b73ah,0887bh,099eeh,086h,070h,0ca07h + tstr <020h,003h>,0,1,1,0,0,0,0,0,0 ; (32 cycles) + tstr 0,0,0,0,0,-1,-1,0,0,0 ; (32 cycles) + db 004h,062h,06ah,0bfh ; expected crc + tmsg 'ld (+1),' + +; ld (+1), (256 cycles) +st8ix2: db 0ffh ; flag mask + tstr <0ddh,074h,1>,0b664h,msbt-1,msbt-1,0e8ach,0b5f5h,0aafeh,012h,010h,09566h + tstr <020h,001h>,0,1,1,0,0,0,0,0,0 ; (16 cycles) + tstr 0,0,0,0,-1,0,0,0,0,0 ; (32 cycles) + db 06ah,01ah,088h,031h ; expected crc + tmsg 'ld (+1),' + +; ld (+1),a (64 cycles) +st8ix3: db 0ffh ; flag mask + tstr <0ddh,077h,1>,067afh,msbt-1,msbt-1,04f13h,00644h,0bcd7h,050h,0ach,05fafh + tstr 020h,0,1,1,0,0,0,0,0,0 ; (8 cycles) + tstr 0,0,0,0,0,0,0,0,-1,0 ; (8 cycles) + db 0cch,0beh,05ah,096h ; expected crc + tmsg 'ld (+1),a' + +; ld (),a (96 cycles) +stabd: db 0ffh ; flag mask + tstr 2,00c3bh,0b592h,06cffh,0959eh,msbt,msbt+1,0c1h,021h,0bde7h + tstr 018h,0,0,0,0,0,0,0,0,0 ; (4 cycles) + tstr 0,-1,0,0,0,0,0,0,-1,0 ; (24 cycles) + db 07ah,04ch,011h,04fh ; expected crc + tmsg 'ld (),a' + +; start test pointed to by (hl) +stt: push hl + ld a,(hl) ; get pointer to test + inc hl + ld h,(hl) + ld l,a + ld a,(hl) ; flag mask + ld (flgmsk+1),a + inc hl + push hl + ld de,20 + add hl,de ; point to incmask + ld de,counter + call initmask + pop hl + push hl + ld de,20+20 + add hl,de ; point to scanmask + ld de,shifter + call initmask + ld hl,shifter + ld (hl),1 ; first bit + pop hl + push hl + ld de,iut ; copy initial instruction under test + ld bc,4 + ldir + ld de,msbt ; copy initial machine state + ld bc,16 + ldir + ld de,20+20+4 ; skip incmask, scanmask and expcrc + add hl,de + ex de,hl + ld c,9 + call bdos ; show test name + call initcrc ; initialise crc +; test loop +tlp: ld a,(iut) + cp 076h ; pragmatically avoid halt intructions + jp z,tlp2 + and a,0dfh + cp 0ddh + jp nz,tlp1 + ld a,(iut+1) + cp 076h +tlp1: call nz,test ; execute the test instruction +tlp2: call count ; increment the counter + call nz,shift ; shift the scan bit + pop hl ; pointer to test case + jp z,tlp3 ; done if shift returned NZ + ld de,20+20+20 + add hl,de ; point to expected crc + call cmpcrc + ld de,okmsg + jp z,tlpok + ld de,ermsg1 + ld c,9 + call bdos + call phex8 + ld de,ermsg2 + ld c,9 + call bdos + ld hl,crcval + call phex8 + ld de,crlf +tlpok: ld c,9 + call bdos + pop hl + inc hl + inc hl + ret + +tlp3: push hl + ld a,1 ; initialise count and shift scanners + ld (cntbit),a + ld (shfbit),a + ld hl,counter + ld (cntbyt),hl + ld hl,shifter + ld (shfbyt),hl + + ld b,4 ; bytes in iut field + pop hl ; pointer to test case + push hl + ld de,iut + call setup ; setup iut + ld b,16 ; bytes in machine state + ld de,msbt + call setup ; setup machine state + jp tlp + +; setup a field of the test case +; b = number of bytes +; hl = pointer to base case +; de = destination +setup: call subyte + inc hl + dec b + jp nz,setup + ret + +subyte: push bc + push de + push hl + ld c,(hl) ; get base byte + ld de,20 + add hl,de ; point to incmask + ld a,(hl) + cp 0 + jp z,subshf + ld b,8 ; 8 bits +subclp: rrca + push af + ld a,0 + call c,nxtcbit ; get next counter bit if mask bit was set + xor c ; flip bit if counter bit was set + rrca + ld c,a + pop af + dec b + jp nz,subclp + ld b,8 +subshf: ld de,20 + add hl,de ; point to shift mask + ld a,(hl) + cp 0 + jp z,substr + ld b,8 ; 8 bits +sbshf1: rrca + push af + ld a,0 + call c,nxtsbit ; get next shifter bit if mask bit was set + xor c ; flip bit if shifter bit was set + rrca + ld c,a + pop af + dec b + jp nz,sbshf1 +substr: pop hl + pop de + ld a,c + ld (de),a ; mangled byte to destination + inc de + pop bc + ret + +; get next counter bit in low bit of a +cntbit: ds 1 +cntbyt: ds 2 + +nxtcbit: push bc + push hl + ld hl,(cntbyt) + ld b,(hl) + ld hl,cntbit + ld a,(hl) + ld c,a + rlca + ld (hl),a + cp a,1 + jp nz,ncb1 + ld hl,(cntbyt) + inc hl + ld (cntbyt),hl +ncb1: ld a,b + and c + pop hl + pop bc + ret z + ld a,1 + ret + +; get next shifter bit in low bit of a +shfbit: ds 1 +shfbyt: ds 2 + +nxtsbit: push bc + push hl + ld hl,(shfbyt) + ld b,(hl) + ld hl,shfbit + ld a,(hl) + ld c,a + rlca + ld (hl),a + cp a,1 + jp nz,nsb1 + ld hl,(shfbyt) + inc hl + ld (shfbyt),hl +nsb1: ld a,b + and c + pop hl + pop bc + ret z + ld a,1 + ret + + +; clear memory at hl, bc bytes +clrmem: push af + push bc + push de + push hl + ld (hl),0 + ld d,h + ld e,l + inc de + dec bc + ldir + pop hl + pop de + pop bc + pop af + ret + +; initialise counter or shifter +; de = pointer to work area for counter or shifter +; hl = pointer to mask +initmask: + push de + ex de,hl + ld bc,20+20 + call clrmem ; clear work area + ex de,hl + ld b,20 ; byte counter + ld c,1 ; first bit + ld d,0 ; bit counter +imlp: ld e,(hl) +imlp1: ld a,e + and a,c + jp z,imlp2 + inc d +imlp2: ld a,c + rlca + ld c,a + cp a,1 + jp nz,imlp1 + inc hl + dec b + jp nz,imlp +; got number of 1-bits in mask in reg d + ld a,d + and 0f8h + rrca + rrca + rrca ; divide by 8 (get byte offset) + ld l,a + ld h,0 + ld a,d + and a,7 ; bit offset + inc a + ld b,a + ld a,080h +imlp3: rlca + dec b + jp nz,imlp3 + pop de + add hl,de + ld de,20 + add hl,de + ld (hl),a + ret + +; multi-byte counter +count: push bc + push de + push hl + ld hl,counter ; 20 byte counter starts here + ld de,20 ; somewhere in here is the stop bit + ex de,hl + add hl,de + ex de,hl +cntlp: inc (hl) + ld a,(hl) + cp 0 + jp z,cntlp1 ; overflow to next byte + ld b,a + ld a,(de) + and a,b ; test for terminal value + jp z,cntend + ld (hl),0 ; reset to zero +cntend: pop bc + pop de + pop hl + ret + +cntlp1: inc hl + inc de + jp cntlp + + +; multi-byte shifter +shift: push bc + push de + push hl + ld hl,shifter ; 20 byte shift register starts here + ld de,20 ; somewhere in here is the stop bit + ex de,hl + add hl,de + ex de,hl +shflp: ld a,(hl) + or a + jp z,shflp1 + ld b,a + ld a,(de) + and b + jp nz,shlpe + ld a,b + rlca + cp a,1 + jp nz,shflp2 + ld (hl),0 + inc hl + inc de +shflp2: ld (hl),a + xor a ; set Z +shlpe: pop hl + pop de + pop bc + ret +shflp1: inc hl + inc de + jp shflp + +counter: ds 2*20 +shifter: ds 2*20 + +; test harness +test: push af + push bc + push de + push hl + if 0 + ld de,crlf + ld c,9 + call bdos + ld hl,iut + ld b,4 + call hexstr + ld e,' ' + ld c,2 + call bdos + ld b,16 + ld hl,msbt + call hexstr + endif + di ; disable interrupts + ld (spsav),sp ; save stack pointer + ld sp,msbt+2 ; point to test-case machine state + pop iy ; and load all regs + pop ix + pop hl + pop de + pop bc + pop af + ld sp,(spbt) +iut: ds 4 ; max 4 byte instruction under test + ld (spat),sp ; save stack pointer + ld sp,spat + push af ; save other registers + push bc + push de + push hl + push ix + push iy + ld sp,(spsav) ; restore stack pointer + ei ; enable interrupts + ld hl,(msbt) ; copy memory operand + ld (msat),hl + ld hl,flgsat ; flags after test + ld a,(hl) +flgmsk: and a,0d7h ; mask-out irrelevant bits (self-modified code!) + ld (hl),a + ld b,16 ; total of 16 bytes of state + ld de,msat + ld hl,crcval +tcrc: ld a,(de) + inc de + call updcrc ; accumulate crc of this test case + dec b + jp nz,tcrc + if 0 + ld e,' ' + ld c,2 + call bdos + ld hl,crcval + call phex8 + ld de,crlf + ld c,9 + call bdos + ld hl,msat + ld b,16 + call hexstr + ld de,crlf + ld c,9 + call bdos + endif + pop hl + pop de + pop bc + pop af + ret + +; machine state after test +msat: ds 14 ; memop,iy,ix,hl,de,bc,af +spat: ds 2 ; stack pointer after test +flgsat: equ spat-2 ; flags + +spsav: ds 2 ; saved stack pointer + +; display hex string (pointer in hl, byte count in b) +hexstr: ld a,(hl) + call phex2 + inc hl + dec b + jp nz,hexstr + ret + +; display hex +; display the big-endian 32-bit value pointed to by hl +phex8: push af + push bc + push hl + ld b,4 +ph8lp: ld a,(hl) + call phex2 + inc hl + dec b + jp nz,ph8lp + pop hl + pop bc + pop af + ret + +; display byte in a +phex2: push af + rrca + rrca + rrca + rrca + call phex1 + pop af +; fall through + +; display low nibble in a +phex1: push af + push bc + push de + push hl + and a,0fh + cp a,10 + jp c,ph11 + add a,'a'-'9'-1 +ph11: add a,'0' + ld e,a + ld c,2 + call bdos + pop hl + pop de + pop bc + pop af + ret + +bdos push af + push bc + push de + push hl + call 5 + pop hl + pop de + pop bc + pop af + ret + +msg1: db 'Z80 instruction exerciser',10,13,'$' +msg2: db 'Tests complete$' +okmsg: db ' OK',10,13,'$' +ermsg1: db ' ERROR **** crc expected:$' +ermsg2: db ' found:$' +crlf: db 10,13,'$' + +; compare crc +; hl points to value to compare to crcval +cmpcrc: push bc + push de + push hl + ld de,crcval + ld b,4 +cclp: ld a,(de) + cp a,(hl) + jp nz,cce + inc hl + inc de + dec b + jp nz,cclp +cce: pop hl + pop de + pop bc + ret + +; 32-bit crc routine +; entry: a contains next byte, hl points to crc +; exit: crc updated +updcrc: push af + push bc + push de + push hl + push hl + ld de,3 + add hl,de ; point to low byte of old crc + xor a,(hl) ; xor with new byte + ld l,a + ld h,0 + add hl,hl ; use result as index into table of 4 byte entries + add hl,hl + ex de,hl + ld hl,crctab + add hl,de ; point to selected entry in crctab + ex de,hl + pop hl + ld bc,4 ; c = byte count, b = accumulator +crclp: ld a,(de) + xor a,b + ld b,(hl) + ld (hl),a + inc de + inc hl + dec c + jp nz,crclp + if 0 + ld hl,crcval + call phex8 + ld de,crlf + ld c,9 + call bdos + endif + pop hl + pop de + pop bc + pop af + ret + +initcrc:push af + push bc + push hl + ld hl,crcval + ld a,0ffh + ld b,4 +icrclp: ld (hl),a + inc hl + dec b + jp nz,icrclp + pop hl + pop bc + pop af + ret + +crcval ds 4 + +crctab: db 000h,000h,000h,000h + db 077h,007h,030h,096h + db 0eeh,00eh,061h,02ch + db 099h,009h,051h,0bah + db 007h,06dh,0c4h,019h + db 070h,06ah,0f4h,08fh + db 0e9h,063h,0a5h,035h + db 09eh,064h,095h,0a3h + db 00eh,0dbh,088h,032h + db 079h,0dch,0b8h,0a4h + db 0e0h,0d5h,0e9h,01eh + db 097h,0d2h,0d9h,088h + db 009h,0b6h,04ch,02bh + db 07eh,0b1h,07ch,0bdh + db 0e7h,0b8h,02dh,007h + db 090h,0bfh,01dh,091h + db 01dh,0b7h,010h,064h + db 06ah,0b0h,020h,0f2h + db 0f3h,0b9h,071h,048h + db 084h,0beh,041h,0deh + db 01ah,0dah,0d4h,07dh + db 06dh,0ddh,0e4h,0ebh + db 0f4h,0d4h,0b5h,051h + db 083h,0d3h,085h,0c7h + db 013h,06ch,098h,056h + db 064h,06bh,0a8h,0c0h + db 0fdh,062h,0f9h,07ah + db 08ah,065h,0c9h,0ech + db 014h,001h,05ch,04fh + db 063h,006h,06ch,0d9h + db 0fah,00fh,03dh,063h + db 08dh,008h,00dh,0f5h + db 03bh,06eh,020h,0c8h + db 04ch,069h,010h,05eh + db 0d5h,060h,041h,0e4h + db 0a2h,067h,071h,072h + db 03ch,003h,0e4h,0d1h + db 04bh,004h,0d4h,047h + db 0d2h,00dh,085h,0fdh + db 0a5h,00ah,0b5h,06bh + db 035h,0b5h,0a8h,0fah + db 042h,0b2h,098h,06ch + db 0dbh,0bbh,0c9h,0d6h + db 0ach,0bch,0f9h,040h + db 032h,0d8h,06ch,0e3h + db 045h,0dfh,05ch,075h + db 0dch,0d6h,00dh,0cfh + db 0abh,0d1h,03dh,059h + db 026h,0d9h,030h,0ach + db 051h,0deh,000h,03ah + db 0c8h,0d7h,051h,080h + db 0bfh,0d0h,061h,016h + db 021h,0b4h,0f4h,0b5h + db 056h,0b3h,0c4h,023h + db 0cfh,0bah,095h,099h + db 0b8h,0bdh,0a5h,00fh + db 028h,002h,0b8h,09eh + db 05fh,005h,088h,008h + db 0c6h,00ch,0d9h,0b2h + db 0b1h,00bh,0e9h,024h + db 02fh,06fh,07ch,087h + db 058h,068h,04ch,011h + db 0c1h,061h,01dh,0abh + db 0b6h,066h,02dh,03dh + db 076h,0dch,041h,090h + db 001h,0dbh,071h,006h + db 098h,0d2h,020h,0bch + db 0efh,0d5h,010h,02ah + db 071h,0b1h,085h,089h + db 006h,0b6h,0b5h,01fh + db 09fh,0bfh,0e4h,0a5h + db 0e8h,0b8h,0d4h,033h + db 078h,007h,0c9h,0a2h + db 00fh,000h,0f9h,034h + db 096h,009h,0a8h,08eh + db 0e1h,00eh,098h,018h + db 07fh,06ah,00dh,0bbh + db 008h,06dh,03dh,02dh + db 091h,064h,06ch,097h + db 0e6h,063h,05ch,001h + db 06bh,06bh,051h,0f4h + db 01ch,06ch,061h,062h + db 085h,065h,030h,0d8h + db 0f2h,062h,000h,04eh + db 06ch,006h,095h,0edh + db 01bh,001h,0a5h,07bh + db 082h,008h,0f4h,0c1h + db 0f5h,00fh,0c4h,057h + db 065h,0b0h,0d9h,0c6h + db 012h,0b7h,0e9h,050h + db 08bh,0beh,0b8h,0eah + db 0fch,0b9h,088h,07ch + db 062h,0ddh,01dh,0dfh + db 015h,0dah,02dh,049h + db 08ch,0d3h,07ch,0f3h + db 0fbh,0d4h,04ch,065h + db 04dh,0b2h,061h,058h + db 03ah,0b5h,051h,0ceh + db 0a3h,0bch,000h,074h + db 0d4h,0bbh,030h,0e2h + db 04ah,0dfh,0a5h,041h + db 03dh,0d8h,095h,0d7h + db 0a4h,0d1h,0c4h,06dh + db 0d3h,0d6h,0f4h,0fbh + db 043h,069h,0e9h,06ah + db 034h,06eh,0d9h,0fch + db 0adh,067h,088h,046h + db 0dah,060h,0b8h,0d0h + db 044h,004h,02dh,073h + db 033h,003h,01dh,0e5h + db 0aah,00ah,04ch,05fh + db 0ddh,00dh,07ch,0c9h + db 050h,005h,071h,03ch + db 027h,002h,041h,0aah + db 0beh,00bh,010h,010h + db 0c9h,00ch,020h,086h + db 057h,068h,0b5h,025h + db 020h,06fh,085h,0b3h + db 0b9h,066h,0d4h,009h + db 0ceh,061h,0e4h,09fh + db 05eh,0deh,0f9h,00eh + db 029h,0d9h,0c9h,098h + db 0b0h,0d0h,098h,022h + db 0c7h,0d7h,0a8h,0b4h + db 059h,0b3h,03dh,017h + db 02eh,0b4h,00dh,081h + db 0b7h,0bdh,05ch,03bh + db 0c0h,0bah,06ch,0adh + db 0edh,0b8h,083h,020h + db 09ah,0bfh,0b3h,0b6h + db 003h,0b6h,0e2h,00ch + db 074h,0b1h,0d2h,09ah + db 0eah,0d5h,047h,039h + db 09dh,0d2h,077h,0afh + db 004h,0dbh,026h,015h + db 073h,0dch,016h,083h + db 0e3h,063h,00bh,012h + db 094h,064h,03bh,084h + db 00dh,06dh,06ah,03eh + db 07ah,06ah,05ah,0a8h + db 0e4h,00eh,0cfh,00bh + db 093h,009h,0ffh,09dh + db 00ah,000h,0aeh,027h + db 07dh,007h,09eh,0b1h + db 0f0h,00fh,093h,044h + db 087h,008h,0a3h,0d2h + db 01eh,001h,0f2h,068h + db 069h,006h,0c2h,0feh + db 0f7h,062h,057h,05dh + db 080h,065h,067h,0cbh + db 019h,06ch,036h,071h + db 06eh,06bh,006h,0e7h + db 0feh,0d4h,01bh,076h + db 089h,0d3h,02bh,0e0h + db 010h,0dah,07ah,05ah + db 067h,0ddh,04ah,0cch + db 0f9h,0b9h,0dfh,06fh + db 08eh,0beh,0efh,0f9h + db 017h,0b7h,0beh,043h + db 060h,0b0h,08eh,0d5h + db 0d6h,0d6h,0a3h,0e8h + db 0a1h,0d1h,093h,07eh + db 038h,0d8h,0c2h,0c4h + db 04fh,0dfh,0f2h,052h + db 0d1h,0bbh,067h,0f1h + db 0a6h,0bch,057h,067h + db 03fh,0b5h,006h,0ddh + db 048h,0b2h,036h,04bh + db 0d8h,00dh,02bh,0dah + db 0afh,00ah,01bh,04ch + db 036h,003h,04ah,0f6h + db 041h,004h,07ah,060h + db 0dfh,060h,0efh,0c3h + db 0a8h,067h,0dfh,055h + db 031h,06eh,08eh,0efh + db 046h,069h,0beh,079h + db 0cbh,061h,0b3h,08ch + db 0bch,066h,083h,01ah + db 025h,06fh,0d2h,0a0h + db 052h,068h,0e2h,036h + db 0cch,00ch,077h,095h + db 0bbh,00bh,047h,003h + db 022h,002h,016h,0b9h + db 055h,005h,026h,02fh + db 0c5h,0bah,03bh,0beh + db 0b2h,0bdh,00bh,028h + db 02bh,0b4h,05ah,092h + db 05ch,0b3h,06ah,004h + db 0c2h,0d7h,0ffh,0a7h + db 0b5h,0d0h,0cfh,031h + db 02ch,0d9h,09eh,08bh + db 05bh,0deh,0aeh,01dh + db 09bh,064h,0c2h,0b0h + db 0ech,063h,0f2h,026h + db 075h,06ah,0a3h,09ch + db 002h,06dh,093h,00ah + db 09ch,009h,006h,0a9h + db 0ebh,00eh,036h,03fh + db 072h,007h,067h,085h + db 005h,000h,057h,013h + db 095h,0bfh,04ah,082h + db 0e2h,0b8h,07ah,014h + db 07bh,0b1h,02bh,0aeh + db 00ch,0b6h,01bh,038h + db 092h,0d2h,08eh,09bh + db 0e5h,0d5h,0beh,00dh + db 07ch,0dch,0efh,0b7h + db 00bh,0dbh,0dfh,021h + db 086h,0d3h,0d2h,0d4h + db 0f1h,0d4h,0e2h,042h + db 068h,0ddh,0b3h,0f8h + db 01fh,0dah,083h,06eh + db 081h,0beh,016h,0cdh + db 0f6h,0b9h,026h,05bh + db 06fh,0b0h,077h,0e1h + db 018h,0b7h,047h,077h + db 088h,008h,05ah,0e6h + db 0ffh,00fh,06ah,070h + db 066h,006h,03bh,0cah + db 011h,001h,00bh,05ch + db 08fh,065h,09eh,0ffh + db 0f8h,062h,0aeh,069h + db 061h,06bh,0ffh,0d3h + db 016h,06ch,0cfh,045h + db 0a0h,00ah,0e2h,078h + db 0d7h,00dh,0d2h,0eeh + db 04eh,004h,083h,054h + db 039h,003h,0b3h,0c2h + db 0a7h,067h,026h,061h + db 0d0h,060h,016h,0f7h + db 049h,069h,047h,04dh + db 03eh,06eh,077h,0dbh + db 0aeh,0d1h,06ah,04ah + db 0d9h,0d6h,05ah,0dch + db 040h,0dfh,00bh,066h + db 037h,0d8h,03bh,0f0h + db 0a9h,0bch,0aeh,053h + db 0deh,0bbh,09eh,0c5h + db 047h,0b2h,0cfh,07fh + db 030h,0b5h,0ffh,0e9h + db 0bdh,0bdh,0f2h,01ch + db 0cah,0bah,0c2h,08ah + db 053h,0b3h,093h,030h + db 024h,0b4h,0a3h,0a6h + db 0bah,0d0h,036h,005h + db 0cdh,0d7h,006h,093h + db 054h,0deh,057h,029h + db 023h,0d9h,067h,0bfh + db 0b3h,066h,07ah,02eh + db 0c4h,061h,04ah,0b8h + db 05dh,068h,01bh,002h + db 02ah,06fh,02bh,094h + db 0b4h,00bh,0beh,037h + db 0c3h,00ch,08eh,0a1h + db 05ah,005h,0dfh,01bh + db 02dh,002h,0efh,08dh + diff --git a/testbenches/zexall.z80 b/testbenches/zexall.z80 deleted file mode 100644 index 586f9ef..0000000 --- a/testbenches/zexall.z80 +++ /dev/null @@ -1,1546 +0,0 @@ - .title 'Z80 instruction set exerciser' - -; zexlax.z80 - Z80 instruction set exerciser -; Copyright (C) 1994 Frank D. Cringle -; -; This program is free software; you can redistribute it and/or -; modify it under the terms of the GNU General Public License -; as published by the Free Software Foundation; either version 2 -; of the License, or (at your option) any later version. -; -; This program is distributed in the hope that it will be useful, -; but WITHOUT ANY WARRANTY; without even the implied warranty of -; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -; GNU General Public License for more details. -; -; You should have received a copy of the GNU General Public License -; along with this program; if not, write to the Free Software -; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - aseg - org 100h - - jp start - -; machine state before test (needs to be at predictably constant address) -msbt: ds 14 -spbt: ds 2 - -; For the purposes of this test program, the machine state consists of: -; a 2 byte memory operand, followed by -; the registers iy,ix,hl,de,bc,af,sp -; for a total of 16 bytes. - -; The program tests instructions (or groups of similar instructions) -; by cycling through a sequence of machine states, executing the test -; instruction for each one and running a 32-bit crc over the resulting -; machine states. At the end of the sequence the crc is compared to -; an expected value that was found empirically on a real Z80. - -; A test case is defined by a descriptor which consists of: -; a flag mask byte, -; the base case, -; the incement vector, -; the shift vector, -; the expected crc, -; a short descriptive message. -; -; The flag mask byte is used to prevent undefined flag bits from -; influencing the results. Documented flags are as per Mostek Z80 -; Technical Manual. -; -; The next three parts of the descriptor are 20 byte vectors -; corresponding to a 4 byte instruction and a 16 byte machine state. -; The first part is the base case, which is the first test case of -; the sequence. This base is then modified according to the next 2 -; vectors. Each 1 bit in the increment vector specifies a bit to be -; cycled in the form of a binary counter. For instance, if the byte -; corresponding to the accumulator is set to 0ffh in the increment -; vector, the test will be repeated for all 256 values of the -; accumulator. Note that 1 bits don't have to be contiguous. The -; number of test cases 'caused' by the increment vector is equal to -; 2^(number of 1 bits). The shift vector is similar, but specifies a -; set of bits in the test case that are to be successively inverted. -; Thus the shift vector 'causes' a number of test cases equal to the -; number of 1 bits in it. - -; The total number of test cases is the product of those caused by the -; counter and shift vectors and can easily become unweildy. Each -; individual test case can take a few milliseconds to execute, due to -; the overhead of test setup and crc calculation, so test design is a -; compromise between coverage and execution time. - -; This program is designed to detect differences between -; implementations and is not ideal for diagnosing the causes of any -; discrepancies. However, provided a reference implementation (or -; real system) is available, a failing test case can be isolated by -; hand using a binary search of the test space. - - -start: ld hl,(6) - ld sp,hl - ld de,msg1 - ld c,9 - call bdos - - ld hl,tests ; first test case -loop: ld a,(hl) ; end of list ? - inc hl - or (hl) - jp z,done - dec hl - call stt - jp loop - -done: ld de,msg2 - ld c,9 - call bdos - jp 0 ; warm boot - -tests: - dw adc16 - dw add16 - dw add16x - dw add16y - dw alu8i - dw alu8r - dw alu8rx - dw alu8x - dw bitx - dw bitz80 - dw cpd1 - dw cpi1 - dw daa - dw inca - dw incb - dw incbc - dw incc - dw incd - dw incde - dw ince - dw inch - dw inchl - dw incix - dw inciy - dw incl - dw incm - dw incsp - dw incx - dw incxh - dw incxl - dw incyh - dw incyl - dw ld161 - dw ld162 - dw ld163 - dw ld164 - dw ld165 - dw ld166 - dw ld167 - dw ld168 - dw ld16im - dw ld16ix - dw ld8bd - dw ld8im - dw ld8imx - dw ld8ix1 - dw ld8ix2 - dw ld8ix3 - dw ld8ixy - dw ld8rr - dw ld8rrx - dw lda - dw ldd1 - dw ldd2 - dw ldi1 - dw ldi2 - dw neg - dw rld - dw rot8080 - dw rotxy - dw rotz80 - dw srz80 - dw srzx - dw st8ix1 - dw st8ix2 - dw st8ix3 - dw stabd - dw 0 - -tstr: macro insn,memop,iy,ix,hl,de,bc,flags,acc,sp - local lab -&lab: db insn - ds &lab+4-$,0 - dw &memop,&iy,&ix,&hl,&de,&bc - db &flags - db &acc - dw &sp - if $-&lab ne 20 - error 'missing parameter' - endif - endm - -tmsg: macro m - local lab -&lab: db m - if $ ge &lab+30 - error 'message too long' - else - ds &lab+30-$,'.' - endif - db '$' - endm - -; hl, (38,912 cycles) -adc16: db 0ffh ; flag mask - tstr <0edh,042h>,0832ch,04f88h,0f22bh,0b339h,07e1fh,01563h,0d3h,089h,0465eh - tstr <0,038h>,0,0,0,0f821h,0,0,0,0,0 ; (1024 cycles) - tstr 0,0,0,0,-1,-1,-1,0d7h,0,-1 ; (38 cycles) - db 0d4h,08ah,0d5h,019h ; expected crc - tmsg ' hl,' - -; add hl, (19,456 cycles) -add16: db 0ffh ; flag mask - tstr 9,0c4a5h,0c4c7h,0d226h,0a050h,058eah,08566h,0c6h,0deh,09bc9h - tstr 030h,0,0,0,0f821h,0,0,0,0,0 ; (512 cycles) - tstr 0,0,0,0,-1,-1,-1,0d7h,0,-1 ; (38 cycles) - db 0d9h,0a4h,0cah,005h ; expected crc - tmsg 'add hl,' - -; add ix, (19,456 cycles) -add16x: db 0ffh ; flag mask - tstr <0ddh,9>,0ddach,0c294h,0635bh,033d3h,06a76h,0fa20h,094h,068h,036f5h - tstr <0,030h>,0,0,0f821h,0,0,0,0,0,0 ; (512 cycles) - tstr 0,0,0,-1,0,-1,-1,0d7h,0,-1 ; (38 cycles) - db 0b1h,0dfh,08eh,0c0h ; expected crc - tmsg 'add ix,' - -; add iy, (19,456 cycles) -add16y: db 0ffh ; flag mask - tstr <0fdh,9>,0c7c2h,0f407h,051c1h,03e96h,00bf4h,0510fh,092h,01eh,071eah - tstr <0,030h>,0,0f821h,0,0,0,0,0,0,0 ; (512 cycles) - tstr 0,0,-1,0,0,-1,-1,0d7h,0,-1 ; (38 cycles) - db 039h,0c8h,058h,09bh ; expected crc - tmsg 'add iy,' - -; aluop a,nn (28,672 cycles) -alu8i: db 0ffh ; flag mask - tstr 0c6h,09140h,07e3ch,07a67h,0df6dh,05b61h,00b29h,010h,066h,085b2h - tstr 038h,0,0,0,0,0,0,0,-1,0 ; (2048 cycles) - tstr <0,-1>,0,0,0,0,0,0,0d7h,0,0 ; (14 cycles) - db 051h,0c1h,09ch,02eh ; expected crc - tmsg 'aluop a,nn' - -; aluop a, (753,664 cycles) -alu8r: db 0ffh ; flag mask - tstr 080h,0c53eh,0573ah,04c4dh,msbt,0e309h,0a666h,0d0h,03bh,0adbbh - tstr 03fh,0,0,0,0,0,0,0,-1,0 ; (16,384 cycles) - tstr 0,0ffh,0,0,0,-1,-1,0d7h,0,0 ; (46 cycles) - db 006h,0c7h,0aah,08eh ; expected crc - tmsg 'aluop a,' - -; aluop a, (376,832 cycles) -alu8rx: db 0ffh ; flag mask - tstr <0ddh,084h>,0d6f7h,0c76eh,0accfh,02847h,022ddh,0c035h,0c5h,038h,0234bh - tstr <020h,039h>,0,0,0,0,0,0,0,-1,0 ; (8,192 cycles) - tstr 0,0ffh,0,0,0,-1,-1,0d7h,0,0 ; (46 cycles) - db 0a8h,086h,0cch,044h ; expected crc - tmsg 'aluop a,' - -; aluop a,(+1) (229,376 cycles) -alu8x: db 0ffh ; flag mask - tstr <0ddh,086h,1>,090b7h,msbt-1,msbt-1,032fdh,0406eh,0c1dch,045h,06eh,0e5fah - tstr <020h,038h>,0,1,1,0,0,0,0,-1,0 ; (16,384 cycles) - tstr 0,0ffh,0,0,0,0,0,0d7h,0,0 ; (14 cycles) - db 0d3h,0f2h,0d7h,04ah ; expected crc - tmsg 'aluop a,(+1)' - -; bit n,(+1) (2048 cycles) -bitx: db 0ffh ; flag mask - tstr <0ddh,0cbh,1,046h>,02075h,msbt-1,msbt-1,03cfch,0a79ah,03d74h,051h,027h,0ca14h - tstr <020h,0,0,038h>,0,0,0,0,0,0,053h,0,0 ; (256 cycles) - tstr 0,0ffh,0,0,0,0,0,0,0,0 ; (8 cycles) - db 083h,053h,04eh,0e1h ; expected crc - tmsg 'bit n,(+1)' - -; bit n, (49,152 cycles) -bitz80: db 0ffh ; flag mask - tstr <0cbh,040h>,03ef1h,09dfch,07acch,msbt,0be61h,07a86h,050h,024h,01998h - tstr <0,03fh>,0,0,0,0,0,0,053h,0,0 ; (1024 cycles) - tstr 0,0ffh,0,0,0,-1,-1,0,-1,0 ; (48 cycles) - db 05eh,002h,00eh,098h ; expected crc - tmsg 'bit n,' - -; cpd (1) (6144 cycles) -cpd1: db 0ffh ; flag mask - tstr <0edh,0a9h>,0c7b6h,072b4h,018f6h,msbt+17,08dbdh,1,0c0h,030h,094a3h - tstr <0,010h>,0,0,0,0,0,010,0,-1,0 ; (1024 cycles) - tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) - db 013h,04bh,062h,02dh ; expected crc - tmsg 'cpd' - -; cpi (1) (6144 cycles) -cpi1: db 0ffh ; flag mask - tstr <0edh,0a1h>,04d48h,0af4ah,0906bh,msbt,04e71h,1,093h,06ah,0907ch - tstr <0,010h>,0,0,0,0,0,010,0,-1,0 ; (1024 cycles) - tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) - db 02dh,0a4h,02dh,019h ; expected crc - tmsg 'cpi' - -; -daa: db 0ffh ; flag mask - tstr 027h,02141h,009fah,01d60h,0a559h,08d5bh,09079h,004h,08eh,0299dh - tstr 018h,0,0,0,0,0,0,0d7h,-1,0 ; (65,536 cycles) - tstr 0,0,0,0,0,0,0,0,0,0 ; (1 cycle) - db 06dh,02dh,0d2h,013h ; expected crc - tmsg '' - -; a (3072 cycles) -inca: db 0ffh ; flag mask - tstr 03ch,04adfh,0d5d8h,0e598h,08a2bh,0a7b0h,0431bh,044h,05ah,0d030h - tstr 001h,0,0,0,0,0,0,0,-1,0 ; (512 cycles) - tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) - db 081h,0fah,081h,000h ; expected crc - tmsg ' a' - -; b (3072 cycles) -incb: db 0ffh ; flag mask - tstr 004h,0d623h,0432dh,07a61h,08180h,05a86h,01e85h,086h,058h,09bbbh - tstr 001h,0,0,0,0,0,0ff00h,0,0,0 ; (512 cycles) - tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) - db 077h,0f3h,05ah,073h ; expected crc - tmsg ' b' - -; bc (1536 cycles) -incbc: db 0ffh ; flag mask - tstr 003h,0cd97h,044abh,08dc9h,0e3e3h,011cch,0e8a4h,002h,049h,02a4dh - tstr 008h,0,0,0,0,0,0f821h,0,0,0 ; (256 cycles) - tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) - db 0d2h,0aeh,03bh,0ech ; expected crc - tmsg ' bc' - -; c (3072 cycles) -incc: db 0ffh ; flag mask - tstr 00ch,0d789h,00935h,0055bh,09f85h,08b27h,0d208h,095h,005h,00660h - tstr 001h,0,0,0,0,0,0ffh,0,0,0 ; (512 cycles) - tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) - db 01ah,0f6h,012h,0a7h ; expected crc - tmsg ' c' - -; d (3072 cycles) -incd: db 0ffh ; flag mask - tstr 014h,0a0eah,05fbah,065fbh,0981ch,038cch,0debch,043h,05ch,003bdh - tstr 001h,0,0,0,0,0ff00h,0,0,0,0 ; (512 cycles) - tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) - db 0d1h,046h,0bfh,051h ; expected crc - tmsg ' d' - -; de (1536 cycles) -incde: db 0ffh ; flag mask - tstr 013h,0342eh,0131dh,028c9h,00acah,09967h,03a2eh,092h,0f6h,09d54h - tstr 008h,0,0,0,0,0f821h,0,0,0,0 ; (256 cycles) - tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) - db 0aeh,0c6h,0d4h,02ch ; expected crc - tmsg ' de' - -; e (3072 cycles) -ince: db 0ffh ; flag mask - tstr 01ch,0602fh,04c0dh,02402h,0e2f5h,0a0f4h,0a10ah,013h,032h,05925h - tstr 001h,0,0,0,0,0ffh,0,0,0,0 ; (512 cycles) - tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) - db 0cah,08ch,06ah,0c2h ; expected crc - tmsg ' e' - -; h (3072 cycles) -inch: db 0ffh ; flag mask - tstr 024h,01506h,0f2ebh,0e8ddh,0262bh,011a6h,0bc1ah,017h,006h,02818h - tstr 001h,0,0,0,0ff00h,0,0,0,0,0 ; (512 cycles) - tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) - db 056h,00fh,095h,05eh ; expected crc - tmsg ' h' - -; hl (1536 cycles) -inchl: db 0ffh ; flag mask - tstr 023h,0c3f4h,007a5h,01b6dh,04f04h,0e2c2h,0822ah,057h,0e0h,0c3e1h - tstr 008h,0,0,0,0f821h,0,0,0,0,0 ; (256 cycles) - tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) - db 0fch,00dh,06dh,04ah ; expected crc - tmsg ' hl' - -; ix (1536 cycles) -incix: db 0ffh ; flag mask - tstr <0ddh,023h>,0bc3ch,00d9bh,0e081h,0adfdh,09a7fh,096e5h,013h,085h,00be2h - tstr <0,8>,0,0,0f821h,0,0,0,0,0,0 ; (256 cycles) - tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) - db 0a5h,04dh,0beh,031h ; expected crc - tmsg ' ix' - -; iy (1536 cycles) -inciy: db 0ffh ; flag mask - tstr <0fdh,023h>,09402h,0637ah,03182h,0c65ah,0b2e9h,0abb4h,016h,0f2h,06d05h - tstr <0,8>,0,0f821h,0,0,0,0,0,0,0 ; (256 cycles) - tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) - db 050h,05dh,051h,0a3h ; expected crc - tmsg ' iy' - -; l (3072 cycles) -incl: db 0ffh ; flag mask - tstr 02ch,08031h,0a520h,04356h,0b409h,0f4c1h,0dfa2h,0d1h,03ch,03ea2h - tstr 001h,0,0,0,0ffh,0,0,0,0,0 ; (512 cycles) - tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) - db 0a0h,0a1h,0b4h,09fh ; expected crc - tmsg ' l' - -; (hl) (3072 cycles) -incm: db 0ffh ; flag mask - tstr 034h,0b856h,00c7ch,0e53eh,msbt,0877eh,0da58h,015h,05ch,01f37h - tstr 001h,0ffh,0,0,0,0,0,0,0,0 ; (512 cycles) - tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) - db 028h,029h,05eh,0ceh ; expected crc - tmsg ' (hl)' - -; sp (1536 cycles) -incsp: db 0ffh ; flag mask - tstr 033h,0346fh,0d482h,0d169h,0deb6h,0a494h,0f476h,053h,002h,0855bh - tstr 008h,0,0,0,0,0,0,0,0,0f821h ; (256 cycles) - tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) - db 05dh,0ach,0d5h,027h ; expected crc - tmsg ' sp' - -; (+1) (6144 cycles) -incx: db 0ffh ; flag mask - tstr <0ddh,034h,1>,0fa6eh,msbt-1,msbt-1,02c28h,08894h,05057h,016h,033h,0286fh - tstr <020h,1>,0ffh,0,0,0,0,0,0,0,0 ; (1024 cycles) - tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) - db 00bh,095h,0a8h,0eah ; expected crc - tmsg ' (+1)' - -; ixh (3072 cycles) -incxh: db 0ffh ; flag mask - tstr <0ddh,024h>,0b838h,0316ch,0c6d4h,03e01h,08358h,015b4h,081h,0deh,04259h - tstr <0,1>,0,0ff00h,0,0,0,0,0,0,0 ; (512 cycles) - tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) - db 06fh,046h,036h,062h ; expected crc - tmsg ' ixh' - -; ixl (3072 cycles) -incxl: db 0ffh ; flag mask - tstr <0ddh,02ch>,04d14h,07460h,076d4h,006e7h,032a2h,0213ch,0d6h,0d7h,099a5h - tstr <0,1>,0,0ffh,0,0,0,0,0,0,0 ; (512 cycles) - tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) - db 002h,07bh,0efh,02ch ; expected crc - tmsg ' ixl' - -; iyh (3072 cycles) -incyh: db 0ffh ; flag mask - tstr <0ddh,024h>,02836h,09f6fh,09116h,061b9h,082cbh,0e219h,092h,073h,0a98ch - tstr <0,1>,0ff00h,0,0,0,0,0,0,0,0 ; (512 cycles) - tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) - db 02dh,096h,06ch,0f3h ; expected crc - tmsg ' iyh' - -; iyl (3072 cycles) -incyl: db 0ffh ; flag mask - tstr <0ddh,02ch>,0d7c6h,062d5h,0a09eh,07039h,03e7eh,09f12h,090h,0d9h,0220fh - tstr <0,1>,0ffh,0,0,0,0,0,0,0,0 ; (512 cycles) - tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) - db 036h,0c1h,01eh,075h ; expected crc - tmsg ' iyl' - -; ld ,(nnnn) (32 cycles) -ld161: db 0ffh ; flag mask - tstr <0edh,04bh,low msbt,high msbt>,0f9a8h,0f559h,093a4h,0f5edh,06f96h,0d968h,086h,0e6h,04bd8h - tstr <0,010h>,0,0,0,0,0,0,0,0,0 ; (2 cycles) - tstr 0,-1,0,0,0,0,0,0,0,0 ; (16 cycles) - db 04dh,045h,0a9h,0ach ; expected crc - tmsg 'ld ,(nnnn)' - -; ld hl,(nnnn) (16 cycles) -ld162: db 0ffh ; flag mask - tstr <02ah,low msbt,high msbt>,09863h,07830h,02077h,0b1feh,0b9fah,0abb8h,004h,006h,06015h - tstr 0,0,0,0,0,0,0,0,0,0 ; (1 cycle) - tstr 0,-1,0,0,0,0,0,0,0,0 ; (16 cycles) - db 05fh,097h,024h,087h ; expected crc - tmsg 'ld hl,(nnnn)' - -; ld sp,(nnnn) (16 cycles) -ld163: db 0ffh ; flag mask - tstr <0edh,07bh,low msbt,high msbt>,08dfch,057d7h,02161h,0ca18h,0c185h,027dah,083h,01eh,0f460h - tstr 0,0,0,0,0,0,0,0,0,0 ; (1 cycles) - tstr 0,-1,0,0,0,0,0,0,0,0 ; (16 cycles) - db 07ah,0ceh,0a1h,01bh ; expected crc - tmsg 'ld sp,(nnnn)' - -; ld ,(nnnn) (32 cycles) -ld164: db 0ffh ; flag mask - tstr <0ddh,02ah,low msbt,high msbt>,0ded7h,0a6fah,0f780h,0244ch,087deh,0bcc2h,016h,063h,04c96h - tstr 020h,0,0,0,0,0,0,0,0,0 ; (2 cycles) - tstr 0,-1,0,0,0,0,0,0,0,0 ; (16 cycles) - db 085h,08bh,0f1h,06dh ; expected crc - tmsg 'ld ,(nnnn)' - -; ld (nnnn), (64 cycles) -ld165: db 0ffh ; flag mask - tstr <0edh,043h,low msbt,high msbt>,01f98h,0844dh,0e8ach,0c9edh,0c95dh,08f61h,080h,03fh,0c7bfh - tstr <0,010h>,0,0,0,0,0,0,0,0,0 ; (2 cycles) - tstr 0,0,0,0,0,-1,-1,0,0,0 ; (32 cycles) - db 064h,01eh,087h,015h ; expected crc - tmsg 'ld (nnnn),' - -; ld (nnnn),hl (16 cycles) -ld166: db 0ffh ; flag mask - tstr <022h,low msbt,high msbt>,0d003h,07772h,07f53h,03f72h,064eah,0e180h,010h,02dh,035e9h - tstr 0,0,0,0,0,0,0,0,0,0 ; (1 cycle) - tstr 0,0,0,0,-1,0,0,0,0,0 ; (16 cycles) - db 0a3h,060h,08bh,047h ; expected crc - tmsg 'ld (nnnn),hl' - -; ld (nnnn),sp (16 cycles) -ld167: db 0ffh ; flag mask - tstr <0edh,073h,low msbt,high msbt>,0c0dch,0d1d6h,0ed5ah,0f356h,0afdah,06ca7h,044h,09fh,03f0ah - tstr 0,0,0,0,0,0,0,0,0,0 ; (1 cycle) - tstr 0,0,0,0,0,0,0,0,0,-1 ; (16 cycles) - db 016h,058h,05fh,0d7h ; expected crc - tmsg 'ld (nnnn),sp' - -; ld (nnnn), (64 cycles) -ld168: db 0ffh ; flag mask - tstr <0ddh,022h,low msbt,high msbt>,06cc3h,00d91h,06900h,08ef8h,0e3d6h,0c3f7h,0c6h,0d9h,0c2dfh - tstr 020h,0,0,0,0,0,0,0,0,0 ; (2 cycles) - tstr 0,0,-1,-1,0,0,0,0,0,0 ; (32 cycles) - db 0bah,010h,02ah,06bh ; expected crc - tmsg 'ld (nnnn),' - -; ld ,nnnn (64 cycles) -ld16im: db 0ffh ; flag mask - tstr 1,05c1ch,02d46h,08eb9h,06078h,074b1h,0b30eh,046h,0d1h,030cch - tstr 030h,0,0,0,0,0,0,0,0,0 ; (4 cycles) - tstr <0,0ffh,0ffh>,0,0,0,0,0,0,0,0,0 ; (16 cycles) - db 0deh,039h,019h,069h ; expected crc - tmsg 'ld ,nnnn' - -; ld ,nnnn (32 cycles) -ld16ix: db 0ffh ; flag mask - tstr <0ddh,021h>,087e8h,02006h,0bd12h,0b69bh,07253h,0a1e5h,051h,013h,0f1bdh - tstr 020h,0,0,0,0,0,0,0,0,0 ; (2 cycles) - tstr <0,0,0ffh,0ffh>,0,0,0,0,0,0,0,0,0 ; (16 cycles) - db 022h,07dh,0d5h,025h ; expected crc - tmsg 'ld ,nnnn' - -; ld a,<(bc),(de)> (44 cycles) -ld8bd: db 0ffh ; flag mask - tstr 00ah,0b3a8h,01d2ah,07f8eh,042ach,msbt,msbt,0c6h,0b1h,0ef8eh - tstr 010h,0,0,0,0,0,0,0,0,0 ; (2 cycles) - tstr 0,0ffh,0,0,0,0,0,0d7h,-1,0 ; (22 cycles) - db 0b0h,081h,089h,035h ; expected crc - tmsg 'ld a,<(bc),(de)>' - -; ld ,nn (64 cycles) -ld8im: db 0ffh ; flag mask - tstr 6,0c407h,0f49dh,0d13dh,00339h,0de89h,07455h,053h,0c0h,05509h - tstr 038h,0,0,0,0,0,0,0,0,0 ; (8 cycles) - tstr 0,0,0,0,0,0,0,0,-1,0 ; (8 cycles) - db 0f1h,0dah,0b5h,056h ; expected crc - tmsg 'ld ,nn' - -; ld (+1),nn (32 cycles) -ld8imx: db 0ffh ; flag mask - tstr <0ddh,036h,1>,01b45h,msbt-1,msbt-1,0d5c1h,061c7h,0bdc4h,0c0h,085h,0cd16h - tstr 020h,0,0,0,0,0,0,0,0,0 ; (2 cycles) - tstr <0,0,0,-1>,0,0,0,0,0,0,0,-1,0 ; (16 cycles) - db 026h,0dbh,047h,07eh ; expected crc - tmsg 'ld (+1),nn' - -; ld ,(+1) (512 cycles) -ld8ix1: db 0ffh ; flag mask - tstr <0ddh,046h,1>,0d016h,msbt-1,msbt-1,04260h,07f39h,00404h,097h,04ah,0d085h - tstr <020h,018h>,0,1,1,0,0,0,0,0,0 ; (32 cycles) - tstr 0,-1,0,0,0,0,0,0,0,0 ; (16 cycles) - db 0cch,011h,006h,0a8h ; expected crc - tmsg 'ld ,(+1)' - -; ld ,(+1) (256 cycles) -ld8ix2: db 0ffh ; flag mask - tstr <0ddh,066h,1>,084e0h,msbt-1,msbt-1,09c52h,0a799h,049b6h,093h,000h,0eeadh - tstr <020h,008h>,0,1,1,0,0,0,0,0,0 ; (16 cycles) - tstr 0,-1,0,0,0,0,0,0,0,0 ; (16 cycles) - db 0fah,02ah,04dh,003h ; expected crc - tmsg 'ld ,(+1)' - -; ld a,(+1) (128 cycles) -ld8ix3: db 0ffh ; flag mask - tstr <0ddh,07eh,1>,0d8b6h,msbt-1,msbt-1,0c612h,0df07h,09cd0h,043h,0a6h,0a0e5h - tstr 020h,0,1,1,0,0,0,0,0,0 ; (8 cycles) - tstr 0,-1,0,0,0,0,0,0,0,0 ; (16 cycles) - db 0a5h,0e9h,0ach,064h ; expected crc - tmsg 'ld a,(+1)' - -; ld ,nn (32 cycles) -ld8ixy: db 0ffh ; flag mask - tstr <0ddh,026h>,03c53h,04640h,0e179h,07711h,0c107h,01afah,081h,0adh,05d9bh - tstr <020h,8>,0,0,0,0,0,0,0,0,0 ; (4 cycles) - tstr 0,0,0,0,0,0,0,0,-1,0 ; (8 cycles) - db 024h,0e8h,082h,08bh ; expected crc - tmsg 'ld ,nn' - -; ld , (3456 cycles) -ld8rr: db 0ffh ; flag mask - tstr 040h,072a4h,0a024h,061ach,msbt,082c7h,0718fh,097h,08fh,0ef8eh - tstr 03fh,0,0,0,0,0,0,0,0,0 ; (64 cycles) - tstr 0,0ffh,0,0,0,-1,-1,0d7h,-1,0 ; (54 cycles) - db 074h,04bh,001h,018h ; expected crc - tmsg 'ld ,' - -; ld , (6912 cycles) -ld8rrx: db 0ffh ; flag mask - tstr <0ddh,040h>,0bcc5h,msbt,msbt,msbt,02fc2h,098c0h,083h,01fh,03bcdh - tstr <020h,03fh>,0,0,0,0,0,0,0,0,0 ; (128 cycles) - tstr 0,0ffh,0,0,0,-1,-1,0d7h,-1,0 ; (54 cycles) - db 047h,08bh,0a3h,06bh ; expected crc - tmsg 'ld ,' - -; ld a,(nnnn) / ld (nnnn),a (44 cycles) -lda: db 0ffh ; flag mask - tstr <032h,low msbt,high msbt>,0fd68h,0f4ech,044a0h,0b543h,00653h,0cdbah,0d2h,04fh,01fd8h - tstr 008h,0,0,0,0,0,0,0,0,0 ; (2 cycle) - tstr 0,0ffh,0,0,0,0,0,0d7h,-1,0 ; (22 cycles) - db 0c9h,026h,02dh,0e5h ; expected crc - tmsg 'ld a,(nnnn) / ld (nnnn),a' - -; ldd (1) (44 cycles) -ldd1: db 0ffh ; flag mask - tstr <0edh,0a8h>,09852h,068fah,066a1h,msbt+3,msbt+1,1,0c1h,068h,020b7h - tstr <0,010h>,0,0,0,0,0,0,0,0,0 ; (2 cycles) - tstr 0,-1,0,0,0,0,0,0d7h,0,0 ; (22 cycles) - db 094h,0f4h,027h,069h ; expected crc - tmsg 'ldd (1)' - -; ldd (2) (44 cycles) -ldd2: db 0ffh ; flag mask - tstr <0edh,0a8h>,0f12eh,0eb2ah,0d5bah,msbt+3,msbt+1,2,047h,0ffh,0fbe4h - tstr <0,010h>,0,0,0,0,0,0,0,0,0 ; (2 cycles) - tstr 0,-1,0,0,0,0,0,0d7h,0,0 ; (22 cycles) - db 039h,0ddh,03dh,0e1h ; expected crc - tmsg 'ldd (2)' - -; ldi (1) (44 cycles) -ldi1: db 0ffh ; flag mask - tstr <0edh,0a0h>,0fe30h,003cdh,06058h,msbt+2,msbt,1,004h,060h,02688h - tstr <0,010h>,0,0,0,0,0,0,0,0,0 ; (2 cycles) - tstr 0,-1,0,0,0,0,0,0d7h,0,0 ; (22 cycles) - db 0f7h,082h,0b0h,0d1h ; expected crc - tmsg 'ldi (1)' - -; ldi (2) (44 cycles) -ldi2: db 0ffh ; flag mask - tstr <0edh,0a0h>,04aceh,0c26eh,0b188h,msbt+2,msbt,2,014h,02dh,0a39fh - tstr <0,010h>,0,0,0,0,0,0,0,0,0 ; (2 cycles) - tstr 0,-1,0,0,0,0,0,0d7h,0,0 ; (22 cycles) - db 0e9h,0eah,0d0h,0aeh ; expected crc - tmsg 'ldi (2)' - -; neg (16,384 cycles) -neg: db 0ffh ; flag mask - tstr <0edh,044h>,038a2h,05f6bh,0d934h,057e4h,0d2d6h,04642h,043h,05ah,009cch - tstr 0,0,0,0,0,0,0,0d7h,-1,0 ; (16,384 cycles) - tstr 0,0,0,0,0,0,0,0,0,0 ; (1 cycle) - db 0d6h,038h,0ddh,06ah ; expected crc - tmsg 'neg' - -; (7168 cycles) -rld: db 0ffh ; flag mask - tstr <0edh,067h>,091cbh,0c48bh,0fa62h,msbt,0e720h,0b479h,040h,006h,08ae2h - tstr <0,8>,0ffh,0,0,0,0,0,0,0,0 ; (512 cycles) - tstr 0,0,0,0,0,0,0,0d7h,-1,0 ; (14 cycles) - db 0ffh,082h,03eh,077h ; expected crc - tmsg '' - -; (6144 cycles) -rot8080: db 0ffh ; flag mask - tstr 7,0cb92h,06d43h,00a90h,0c284h,00c53h,0f50eh,091h,0ebh,040fch - tstr 018h,0,0,0,0,0,0,0,-1,0 ; (1024 cycles) - tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) - db 09bh,0a3h,080h,07ch ; expected crc - tmsg '' - -; shift/rotate (+1) (416 cycles) -rotxy: db 0ffh ; flag mask - tstr <0ddh,0cbh,1,6>,0ddafh,msbt-1,msbt-1,0ff3ch,0dbf6h,094f4h,082h,080h,061d9h - tstr <020h,0,0,038h>,0,0,0,0,0,0,080h,0,0 ; (32 cycles) - tstr 0,0ffh,0,0,0,0,0,057h,0,0 ; (13 cycles) - db 071h,000h,034h,0cbh ; expected crc - tmsg 'shf/rot (+1)' - -; shift/rotate (6784 cycles) -rotz80: db 0ffh ; flag mask - tstr 0cbh,0ccebh,05d4ah,0e007h,msbt,01395h,030eeh,043h,078h,03dadh - tstr <0,03fh>,0,0,0,0,0,0,080h,0,0 ; (128 cycles) - tstr 0,0ffh,0,0,0,-1,-1,057h,-1,0 ; (53 cycles) - db 0a4h,025h,058h,033h ; expected crc - tmsg 'shf/rot ' - -; n, (7936 cycles) -srz80: db 0ffh ; flag mask - tstr <0cbh,080h>,02cd5h,097abh,039ffh,msbt,0d14bh,06ab2h,053h,027h,0b538h - tstr <0,07fh>,0,0,0,0,0,0,0,0,0 ; (128 cycles) - tstr 0,0ffh,0,0,0,-1,-1,0d7h,-1,0 ; (62 cycles) - db 08bh,057h,0f0h,008h ; expected crc - tmsg ' n,' - -; n,(+1) (1792 cycles) -srzx: db 0ffh ; flag mask - tstr <0ddh,0cbh,1,086h>,0fb44h,msbt-1,msbt-1,0ba09h,068beh,032d8h,010h,05eh,0a867h - tstr <020h,0,0,078h>,0,0,0,0,0,0,0,0,0 ; (128 cycles) - tstr 0,0ffh,0,0,0,0,0,0d7h,0,0 ;(14 cycles) - db 0cch,063h,0f9h,08ah ; expected crc - tmsg ' n,(+1)' - -; ld (+1), (1024 cycles) -st8ix1: db 0ffh ; flag mask - tstr <0ddh,070h,1>,0270dh,msbt-1,msbt-1,0b73ah,0887bh,099eeh,086h,070h,0ca07h - tstr <020h,003h>,0,1,1,0,0,0,0,0,0 ; (32 cycles) - tstr 0,0,0,0,0,-1,-1,0,0,0 ; (32 cycles) - db 004h,062h,06ah,0bfh ; expected crc - tmsg 'ld (+1),' - -; ld (+1), (256 cycles) -st8ix2: db 0ffh ; flag mask - tstr <0ddh,074h,1>,0b664h,msbt-1,msbt-1,0e8ach,0b5f5h,0aafeh,012h,010h,09566h - tstr <020h,001h>,0,1,1,0,0,0,0,0,0 ; (16 cycles) - tstr 0,0,0,0,-1,0,0,0,0,0 ; (32 cycles) - db 06ah,01ah,088h,031h ; expected crc - tmsg 'ld (+1),' - -; ld (+1),a (64 cycles) -st8ix3: db 0ffh ; flag mask - tstr <0ddh,077h,1>,067afh,msbt-1,msbt-1,04f13h,00644h,0bcd7h,050h,0ach,05fafh - tstr 020h,0,1,1,0,0,0,0,0,0 ; (8 cycles) - tstr 0,0,0,0,0,0,0,0,-1,0 ; (8 cycles) - db 0cch,0beh,05ah,096h ; expected crc - tmsg 'ld (+1),a' - -; ld (),a (96 cycles) -stabd: db 0ffh ; flag mask - tstr 2,00c3bh,0b592h,06cffh,0959eh,msbt,msbt+1,0c1h,021h,0bde7h - tstr 018h,0,0,0,0,0,0,0,0,0 ; (4 cycles) - tstr 0,-1,0,0,0,0,0,0,-1,0 ; (24 cycles) - db 07ah,04ch,011h,04fh ; expected crc - tmsg 'ld (),a' - -; start test pointed to by (hl) -stt: push hl - ld a,(hl) ; get pointer to test - inc hl - ld h,(hl) - ld l,a - ld a,(hl) ; flag mask - ld (flgmsk+1),a - inc hl - push hl - ld de,20 - add hl,de ; point to incmask - ld de,counter - call initmask - pop hl - push hl - ld de,20+20 - add hl,de ; point to scanmask - ld de,shifter - call initmask - ld hl,shifter - ld (hl),1 ; first bit - pop hl - push hl - ld de,iut ; copy initial instruction under test - ld bc,4 - ldir - ld de,msbt ; copy initial machine state - ld bc,16 - ldir - ld de,20+20+4 ; skip incmask, scanmask and expcrc - add hl,de - ex de,hl - ld c,9 - call bdos ; show test name - call initcrc ; initialise crc -; test loop -tlp: ld a,(iut) - cp 076h ; pragmatically avoid halt intructions - jp z,tlp2 - and a,0dfh - cp 0ddh - jp nz,tlp1 - ld a,(iut+1) - cp 076h -tlp1: call nz,test ; execute the test instruction -tlp2: call count ; increment the counter - call nz,shift ; shift the scan bit - pop hl ; pointer to test case - jp z,tlp3 ; done if shift returned NZ - ld de,20+20+20 - add hl,de ; point to expected crc - call cmpcrc - ld de,okmsg - jp z,tlpok - ld de,ermsg1 - ld c,9 - call bdos - call phex8 - ld de,ermsg2 - ld c,9 - call bdos - ld hl,crcval - call phex8 - ld de,crlf -tlpok: ld c,9 - call bdos - pop hl - inc hl - inc hl - ret - -tlp3: push hl - ld a,1 ; initialise count and shift scanners - ld (cntbit),a - ld (shfbit),a - ld hl,counter - ld (cntbyt),hl - ld hl,shifter - ld (shfbyt),hl - - ld b,4 ; bytes in iut field - pop hl ; pointer to test case - push hl - ld de,iut - call setup ; setup iut - ld b,16 ; bytes in machine state - ld de,msbt - call setup ; setup machine state - jp tlp - -; setup a field of the test case -; b = number of bytes -; hl = pointer to base case -; de = destination -setup: call subyte - inc hl - dec b - jp nz,setup - ret - -subyte: push bc - push de - push hl - ld c,(hl) ; get base byte - ld de,20 - add hl,de ; point to incmask - ld a,(hl) - cp 0 - jp z,subshf - ld b,8 ; 8 bits -subclp: rrca - push af - ld a,0 - call c,nxtcbit ; get next counter bit if mask bit was set - xor c ; flip bit if counter bit was set - rrca - ld c,a - pop af - dec b - jp nz,subclp - ld b,8 -subshf: ld de,20 - add hl,de ; point to shift mask - ld a,(hl) - cp 0 - jp z,substr - ld b,8 ; 8 bits -sbshf1: rrca - push af - ld a,0 - call c,nxtsbit ; get next shifter bit if mask bit was set - xor c ; flip bit if shifter bit was set - rrca - ld c,a - pop af - dec b - jp nz,sbshf1 -substr: pop hl - pop de - ld a,c - ld (de),a ; mangled byte to destination - inc de - pop bc - ret - -; get next counter bit in low bit of a -cntbit: ds 1 -cntbyt: ds 2 - -nxtcbit: push bc - push hl - ld hl,(cntbyt) - ld b,(hl) - ld hl,cntbit - ld a,(hl) - ld c,a - rlca - ld (hl),a - cp a,1 - jp nz,ncb1 - ld hl,(cntbyt) - inc hl - ld (cntbyt),hl -ncb1: ld a,b - and c - pop hl - pop bc - ret z - ld a,1 - ret - -; get next shifter bit in low bit of a -shfbit: ds 1 -shfbyt: ds 2 - -nxtsbit: push bc - push hl - ld hl,(shfbyt) - ld b,(hl) - ld hl,shfbit - ld a,(hl) - ld c,a - rlca - ld (hl),a - cp a,1 - jp nz,nsb1 - ld hl,(shfbyt) - inc hl - ld (shfbyt),hl -nsb1: ld a,b - and c - pop hl - pop bc - ret z - ld a,1 - ret - - -; clear memory at hl, bc bytes -clrmem: push af - push bc - push de - push hl - ld (hl),0 - ld d,h - ld e,l - inc de - dec bc - ldir - pop hl - pop de - pop bc - pop af - ret - -; initialise counter or shifter -; de = pointer to work area for counter or shifter -; hl = pointer to mask -initmask: - push de - ex de,hl - ld bc,20+20 - call clrmem ; clear work area - ex de,hl - ld b,20 ; byte counter - ld c,1 ; first bit - ld d,0 ; bit counter -imlp: ld e,(hl) -imlp1: ld a,e - and a,c - jp z,imlp2 - inc d -imlp2: ld a,c - rlca - ld c,a - cp a,1 - jp nz,imlp1 - inc hl - dec b - jp nz,imlp -; got number of 1-bits in mask in reg d - ld a,d - and 0f8h - rrca - rrca - rrca ; divide by 8 (get byte offset) - ld l,a - ld h,0 - ld a,d - and a,7 ; bit offset - inc a - ld b,a - ld a,080h -imlp3: rlca - dec b - jp nz,imlp3 - pop de - add hl,de - ld de,20 - add hl,de - ld (hl),a - ret - -; multi-byte counter -count: push bc - push de - push hl - ld hl,counter ; 20 byte counter starts here - ld de,20 ; somewhere in here is the stop bit - ex de,hl - add hl,de - ex de,hl -cntlp: inc (hl) - ld a,(hl) - cp 0 - jp z,cntlp1 ; overflow to next byte - ld b,a - ld a,(de) - and a,b ; test for terminal value - jp z,cntend - ld (hl),0 ; reset to zero -cntend: pop bc - pop de - pop hl - ret - -cntlp1: inc hl - inc de - jp cntlp - - -; multi-byte shifter -shift: push bc - push de - push hl - ld hl,shifter ; 20 byte shift register starts here - ld de,20 ; somewhere in here is the stop bit - ex de,hl - add hl,de - ex de,hl -shflp: ld a,(hl) - or a - jp z,shflp1 - ld b,a - ld a,(de) - and b - jp nz,shlpe - ld a,b - rlca - cp a,1 - jp nz,shflp2 - ld (hl),0 - inc hl - inc de -shflp2: ld (hl),a - xor a ; set Z -shlpe: pop hl - pop de - pop bc - ret -shflp1: inc hl - inc de - jp shflp - -counter: ds 2*20 -shifter: ds 2*20 - -; test harness -test: push af - push bc - push de - push hl - if 0 - ld de,crlf - ld c,9 - call bdos - ld hl,iut - ld b,4 - call hexstr - ld e,' ' - ld c,2 - call bdos - ld b,16 - ld hl,msbt - call hexstr - endif - di ; disable interrupts - ld (spsav),sp ; save stack pointer - ld sp,msbt+2 ; point to test-case machine state - pop iy ; and load all regs - pop ix - pop hl - pop de - pop bc - pop af - ld sp,(spbt) -iut: ds 4 ; max 4 byte instruction under test - ld (spat),sp ; save stack pointer - ld sp,spat - push af ; save other registers - push bc - push de - push hl - push ix - push iy - ld sp,(spsav) ; restore stack pointer - ei ; enable interrupts - ld hl,(msbt) ; copy memory operand - ld (msat),hl - ld hl,flgsat ; flags after test - ld a,(hl) -flgmsk: and a,0d7h ; mask-out irrelevant bits (self-modified code!) - ld (hl),a - ld b,16 ; total of 16 bytes of state - ld de,msat - ld hl,crcval -tcrc: ld a,(de) - inc de - call updcrc ; accumulate crc of this test case - dec b - jp nz,tcrc - if 0 - ld e,' ' - ld c,2 - call bdos - ld hl,crcval - call phex8 - ld de,crlf - ld c,9 - call bdos - ld hl,msat - ld b,16 - call hexstr - ld de,crlf - ld c,9 - call bdos - endif - pop hl - pop de - pop bc - pop af - ret - -; machine state after test -msat: ds 14 ; memop,iy,ix,hl,de,bc,af -spat: ds 2 ; stack pointer after test -flgsat: equ spat-2 ; flags - -spsav: ds 2 ; saved stack pointer - -; display hex string (pointer in hl, byte count in b) -hexstr: ld a,(hl) - call phex2 - inc hl - dec b - jp nz,hexstr - ret - -; display hex -; display the big-endian 32-bit value pointed to by hl -phex8: push af - push bc - push hl - ld b,4 -ph8lp: ld a,(hl) - call phex2 - inc hl - dec b - jp nz,ph8lp - pop hl - pop bc - pop af - ret - -; display byte in a -phex2: push af - rrca - rrca - rrca - rrca - call phex1 - pop af -; fall through - -; display low nibble in a -phex1: push af - push bc - push de - push hl - and a,0fh - cp a,10 - jp c,ph11 - add a,'a'-'9'-1 -ph11: add a,'0' - ld e,a - ld c,2 - call bdos - pop hl - pop de - pop bc - pop af - ret - -bdos push af - push bc - push de - push hl - call 5 - pop hl - pop de - pop bc - pop af - ret - -msg1: db 'Z80 instruction exerciser',10,13,'$' -msg2: db 'Tests complete$' -okmsg: db ' OK',10,13,'$' -ermsg1: db ' ERROR **** crc expected:$' -ermsg2: db ' found:$' -crlf: db 10,13,'$' - -; compare crc -; hl points to value to compare to crcval -cmpcrc: push bc - push de - push hl - ld de,crcval - ld b,4 -cclp: ld a,(de) - cp a,(hl) - jp nz,cce - inc hl - inc de - dec b - jp nz,cclp -cce: pop hl - pop de - pop bc - ret - -; 32-bit crc routine -; entry: a contains next byte, hl points to crc -; exit: crc updated -updcrc: push af - push bc - push de - push hl - push hl - ld de,3 - add hl,de ; point to low byte of old crc - xor a,(hl) ; xor with new byte - ld l,a - ld h,0 - add hl,hl ; use result as index into table of 4 byte entries - add hl,hl - ex de,hl - ld hl,crctab - add hl,de ; point to selected entry in crctab - ex de,hl - pop hl - ld bc,4 ; c = byte count, b = accumulator -crclp: ld a,(de) - xor a,b - ld b,(hl) - ld (hl),a - inc de - inc hl - dec c - jp nz,crclp - if 0 - ld hl,crcval - call phex8 - ld de,crlf - ld c,9 - call bdos - endif - pop hl - pop de - pop bc - pop af - ret - -initcrc:push af - push bc - push hl - ld hl,crcval - ld a,0ffh - ld b,4 -icrclp: ld (hl),a - inc hl - dec b - jp nz,icrclp - pop hl - pop bc - pop af - ret - -crcval ds 4 - -crctab: db 000h,000h,000h,000h - db 077h,007h,030h,096h - db 0eeh,00eh,061h,02ch - db 099h,009h,051h,0bah - db 007h,06dh,0c4h,019h - db 070h,06ah,0f4h,08fh - db 0e9h,063h,0a5h,035h - db 09eh,064h,095h,0a3h - db 00eh,0dbh,088h,032h - db 079h,0dch,0b8h,0a4h - db 0e0h,0d5h,0e9h,01eh - db 097h,0d2h,0d9h,088h - db 009h,0b6h,04ch,02bh - db 07eh,0b1h,07ch,0bdh - db 0e7h,0b8h,02dh,007h - db 090h,0bfh,01dh,091h - db 01dh,0b7h,010h,064h - db 06ah,0b0h,020h,0f2h - db 0f3h,0b9h,071h,048h - db 084h,0beh,041h,0deh - db 01ah,0dah,0d4h,07dh - db 06dh,0ddh,0e4h,0ebh - db 0f4h,0d4h,0b5h,051h - db 083h,0d3h,085h,0c7h - db 013h,06ch,098h,056h - db 064h,06bh,0a8h,0c0h - db 0fdh,062h,0f9h,07ah - db 08ah,065h,0c9h,0ech - db 014h,001h,05ch,04fh - db 063h,006h,06ch,0d9h - db 0fah,00fh,03dh,063h - db 08dh,008h,00dh,0f5h - db 03bh,06eh,020h,0c8h - db 04ch,069h,010h,05eh - db 0d5h,060h,041h,0e4h - db 0a2h,067h,071h,072h - db 03ch,003h,0e4h,0d1h - db 04bh,004h,0d4h,047h - db 0d2h,00dh,085h,0fdh - db 0a5h,00ah,0b5h,06bh - db 035h,0b5h,0a8h,0fah - db 042h,0b2h,098h,06ch - db 0dbh,0bbh,0c9h,0d6h - db 0ach,0bch,0f9h,040h - db 032h,0d8h,06ch,0e3h - db 045h,0dfh,05ch,075h - db 0dch,0d6h,00dh,0cfh - db 0abh,0d1h,03dh,059h - db 026h,0d9h,030h,0ach - db 051h,0deh,000h,03ah - db 0c8h,0d7h,051h,080h - db 0bfh,0d0h,061h,016h - db 021h,0b4h,0f4h,0b5h - db 056h,0b3h,0c4h,023h - db 0cfh,0bah,095h,099h - db 0b8h,0bdh,0a5h,00fh - db 028h,002h,0b8h,09eh - db 05fh,005h,088h,008h - db 0c6h,00ch,0d9h,0b2h - db 0b1h,00bh,0e9h,024h - db 02fh,06fh,07ch,087h - db 058h,068h,04ch,011h - db 0c1h,061h,01dh,0abh - db 0b6h,066h,02dh,03dh - db 076h,0dch,041h,090h - db 001h,0dbh,071h,006h - db 098h,0d2h,020h,0bch - db 0efh,0d5h,010h,02ah - db 071h,0b1h,085h,089h - db 006h,0b6h,0b5h,01fh - db 09fh,0bfh,0e4h,0a5h - db 0e8h,0b8h,0d4h,033h - db 078h,007h,0c9h,0a2h - db 00fh,000h,0f9h,034h - db 096h,009h,0a8h,08eh - db 0e1h,00eh,098h,018h - db 07fh,06ah,00dh,0bbh - db 008h,06dh,03dh,02dh - db 091h,064h,06ch,097h - db 0e6h,063h,05ch,001h - db 06bh,06bh,051h,0f4h - db 01ch,06ch,061h,062h - db 085h,065h,030h,0d8h - db 0f2h,062h,000h,04eh - db 06ch,006h,095h,0edh - db 01bh,001h,0a5h,07bh - db 082h,008h,0f4h,0c1h - db 0f5h,00fh,0c4h,057h - db 065h,0b0h,0d9h,0c6h - db 012h,0b7h,0e9h,050h - db 08bh,0beh,0b8h,0eah - db 0fch,0b9h,088h,07ch - db 062h,0ddh,01dh,0dfh - db 015h,0dah,02dh,049h - db 08ch,0d3h,07ch,0f3h - db 0fbh,0d4h,04ch,065h - db 04dh,0b2h,061h,058h - db 03ah,0b5h,051h,0ceh - db 0a3h,0bch,000h,074h - db 0d4h,0bbh,030h,0e2h - db 04ah,0dfh,0a5h,041h - db 03dh,0d8h,095h,0d7h - db 0a4h,0d1h,0c4h,06dh - db 0d3h,0d6h,0f4h,0fbh - db 043h,069h,0e9h,06ah - db 034h,06eh,0d9h,0fch - db 0adh,067h,088h,046h - db 0dah,060h,0b8h,0d0h - db 044h,004h,02dh,073h - db 033h,003h,01dh,0e5h - db 0aah,00ah,04ch,05fh - db 0ddh,00dh,07ch,0c9h - db 050h,005h,071h,03ch - db 027h,002h,041h,0aah - db 0beh,00bh,010h,010h - db 0c9h,00ch,020h,086h - db 057h,068h,0b5h,025h - db 020h,06fh,085h,0b3h - db 0b9h,066h,0d4h,009h - db 0ceh,061h,0e4h,09fh - db 05eh,0deh,0f9h,00eh - db 029h,0d9h,0c9h,098h - db 0b0h,0d0h,098h,022h - db 0c7h,0d7h,0a8h,0b4h - db 059h,0b3h,03dh,017h - db 02eh,0b4h,00dh,081h - db 0b7h,0bdh,05ch,03bh - db 0c0h,0bah,06ch,0adh - db 0edh,0b8h,083h,020h - db 09ah,0bfh,0b3h,0b6h - db 003h,0b6h,0e2h,00ch - db 074h,0b1h,0d2h,09ah - db 0eah,0d5h,047h,039h - db 09dh,0d2h,077h,0afh - db 004h,0dbh,026h,015h - db 073h,0dch,016h,083h - db 0e3h,063h,00bh,012h - db 094h,064h,03bh,084h - db 00dh,06dh,06ah,03eh - db 07ah,06ah,05ah,0a8h - db 0e4h,00eh,0cfh,00bh - db 093h,009h,0ffh,09dh - db 00ah,000h,0aeh,027h - db 07dh,007h,09eh,0b1h - db 0f0h,00fh,093h,044h - db 087h,008h,0a3h,0d2h - db 01eh,001h,0f2h,068h - db 069h,006h,0c2h,0feh - db 0f7h,062h,057h,05dh - db 080h,065h,067h,0cbh - db 019h,06ch,036h,071h - db 06eh,06bh,006h,0e7h - db 0feh,0d4h,01bh,076h - db 089h,0d3h,02bh,0e0h - db 010h,0dah,07ah,05ah - db 067h,0ddh,04ah,0cch - db 0f9h,0b9h,0dfh,06fh - db 08eh,0beh,0efh,0f9h - db 017h,0b7h,0beh,043h - db 060h,0b0h,08eh,0d5h - db 0d6h,0d6h,0a3h,0e8h - db 0a1h,0d1h,093h,07eh - db 038h,0d8h,0c2h,0c4h - db 04fh,0dfh,0f2h,052h - db 0d1h,0bbh,067h,0f1h - db 0a6h,0bch,057h,067h - db 03fh,0b5h,006h,0ddh - db 048h,0b2h,036h,04bh - db 0d8h,00dh,02bh,0dah - db 0afh,00ah,01bh,04ch - db 036h,003h,04ah,0f6h - db 041h,004h,07ah,060h - db 0dfh,060h,0efh,0c3h - db 0a8h,067h,0dfh,055h - db 031h,06eh,08eh,0efh - db 046h,069h,0beh,079h - db 0cbh,061h,0b3h,08ch - db 0bch,066h,083h,01ah - db 025h,06fh,0d2h,0a0h - db 052h,068h,0e2h,036h - db 0cch,00ch,077h,095h - db 0bbh,00bh,047h,003h - db 022h,002h,016h,0b9h - db 055h,005h,026h,02fh - db 0c5h,0bah,03bh,0beh - db 0b2h,0bdh,00bh,028h - db 02bh,0b4h,05ah,092h - db 05ch,0b3h,06ah,004h - db 0c2h,0d7h,0ffh,0a7h - db 0b5h,0d0h,0cfh,031h - db 02ch,0d9h,09eh,08bh - db 05bh,0deh,0aeh,01dh - db 09bh,064h,0c2h,0b0h - db 0ech,063h,0f2h,026h - db 075h,06ah,0a3h,09ch - db 002h,06dh,093h,00ah - db 09ch,009h,006h,0a9h - db 0ebh,00eh,036h,03fh - db 072h,007h,067h,085h - db 005h,000h,057h,013h - db 095h,0bfh,04ah,082h - db 0e2h,0b8h,07ah,014h - db 07bh,0b1h,02bh,0aeh - db 00ch,0b6h,01bh,038h - db 092h,0d2h,08eh,09bh - db 0e5h,0d5h,0beh,00dh - db 07ch,0dch,0efh,0b7h - db 00bh,0dbh,0dfh,021h - db 086h,0d3h,0d2h,0d4h - db 0f1h,0d4h,0e2h,042h - db 068h,0ddh,0b3h,0f8h - db 01fh,0dah,083h,06eh - db 081h,0beh,016h,0cdh - db 0f6h,0b9h,026h,05bh - db 06fh,0b0h,077h,0e1h - db 018h,0b7h,047h,077h - db 088h,008h,05ah,0e6h - db 0ffh,00fh,06ah,070h - db 066h,006h,03bh,0cah - db 011h,001h,00bh,05ch - db 08fh,065h,09eh,0ffh - db 0f8h,062h,0aeh,069h - db 061h,06bh,0ffh,0d3h - db 016h,06ch,0cfh,045h - db 0a0h,00ah,0e2h,078h - db 0d7h,00dh,0d2h,0eeh - db 04eh,004h,083h,054h - db 039h,003h,0b3h,0c2h - db 0a7h,067h,026h,061h - db 0d0h,060h,016h,0f7h - db 049h,069h,047h,04dh - db 03eh,06eh,077h,0dbh - db 0aeh,0d1h,06ah,04ah - db 0d9h,0d6h,05ah,0dch - db 040h,0dfh,00bh,066h - db 037h,0d8h,03bh,0f0h - db 0a9h,0bch,0aeh,053h - db 0deh,0bbh,09eh,0c5h - db 047h,0b2h,0cfh,07fh - db 030h,0b5h,0ffh,0e9h - db 0bdh,0bdh,0f2h,01ch - db 0cah,0bah,0c2h,08ah - db 053h,0b3h,093h,030h - db 024h,0b4h,0a3h,0a6h - db 0bah,0d0h,036h,005h - db 0cdh,0d7h,006h,093h - db 054h,0deh,057h,029h - db 023h,0d9h,067h,0bfh - db 0b3h,066h,07ah,02eh - db 0c4h,061h,04ah,0b8h - db 05dh,068h,01bh,002h - db 02ah,06fh,02bh,094h - db 0b4h,00bh,0beh,037h - db 0c3h,00ch,08eh,0a1h - db 05ah,005h,0dfh,01bh - db 02dh,002h,0efh,08dh - diff --git a/testbenches/zexdoc.testbench.z80 b/testbenches/zexdoc.testbench.z80 new file mode 100644 index 0000000..eda26dd --- /dev/null +++ b/testbenches/zexdoc.testbench.z80 @@ -0,0 +1,1543 @@ +; .title 'Z80 instruction set exerciser' + +; zexlax.z80 - Z80 instruction set exerciser +; Copyright (C) 1994 Frank D. Cringle +; +; This program is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; as published by the Free Software Foundation; either version 2 +; of the License, or (at your option) any later version. +; +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, write to the Free Software +; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +; aseg +.ORG 4000h + + jp start + +; machine state before test (needs to be at predictably constant address) +msbt: .fill 14 +spbt: .fill 2 + +; For the purposes of this test program, the machine state consists of: +; a 2 byte memory operand, followed by +; the registers iy,ix,hl,de,bc,af,sp +; for a total of 16 bytes. + +; The program tests instructions (or groups of similar instructions) +; by cycling through a sequence of machine states, executing the test +; instruction for each one and running a 32-bit crc over the resulting +; machine states. At the end of the sequence the crc is compared to +; an expected value that was found empirically on a real Z80. + +; A test case is defined by a descriptor which consists of: +; a flag mask byte, +; the base case, +; the incement vector, +; the shift vector, +; the expected crc, +; a short descriptive message. +; +; The flag mask byte is used to prevent undefined flag bits from +; influencing the results. Documented flags are as per Mostek Z80 +; Technical Manual. +; +; The next three parts of the descriptor are 20 byte vectors +; corresponding to a 4 byte instruction and a 16 byte machine state. +; The first part is the base case, which is the first test case of +; the sequence. This base is then modified according to the next 2 +; vectors. Each 1 bit in the increment vector specifies a bit to be +; cycled in the form of a binary counter. For instance, if the byte +; corresponding to the accumulator is set to 0ffh in the increment +; vector, the test will be repeated for all 256 values of the +; accumulator. Note that 1 bits don't have to be contiguous. The +; number of test cases 'caused' by the increment vector is equal to +; 2^(number of 1 bits). The shift vector is similar, but specifies a +; set of bits in the test case that are to be successively inverted. +; Thus the shift vector 'causes' a number of test cases equal to the +; number of 1 bits in it. + +; The total number of test cases is the product of those caused by the +; counter and shift vectors and can easily become unweildy. Each +; individual test case can take a few milliseconds to execute, due to +; the overhead of test setup and crc calculation, so test design is a +; compromise between coverage and execution time. + +; This program is designed to detect differences between +; implementations and is not ideal for diagnosing the causes of any +; discrepancies. However, provided a reference implementation (or +; real system) is available, a failing test case can be isolated by +; hand using a binary search of the test space. + + +start: ld hl,(6) + ld sp,hl + ld de,msg1 + call writestr + + ld hl,tests ; first test case +loop: ld a,(hl) ; end of list ? + inc hl + or (hl) + jp z,done + dec hl + call stt + jp loop + +done: ld de,msg2 + call writestr + halt + +tests: + .dw adc16 + .dw add16 + .dw add16x + .dw add16y + .dw alu8i + .dw alu8r + .dw alu8rx + .dw alu8x + .dw bitx + .dw bitz80 + .dw cpd1 + .dw cpi1 + .dw daa + .dw inca + .dw incb + .dw incbc + .dw incc + .dw incd + .dw incde + .dw ince + .dw inch + .dw inchl + .dw incix + .dw inciy + .dw incl + .dw incm + .dw incsp + .dw incx + .dw incxh + .dw incxl + .dw incyh + .dw incyl + .dw ld161 + .dw ld162 + .dw ld163 + .dw ld164 + .dw ld165 + .dw ld166 + .dw ld167 + .dw ld168 + .dw ld16im + .dw ld16ix + .dw ld8bd + .dw ld8im + .dw ld8imx + .dw ld8ix1 + .dw ld8ix2 + .dw ld8ix3 + .dw ld8ixy + .dw ld8rr + .dw ld8rrx + .dw lda + .dw ldd1 + .dw ldd2 + .dw ldi1 + .dw ldi2 + .dw neg + .dw rld + .dw rot8080 + .dw rotxy + .dw rotz80 + .dw srz80 + .dw srzx + .dw st8ix1 + .dw st8ix2 + .dw st8ix3 + .dw stabd + .dw 0 + +#macro tstr(insn,memop,iy,ix,hl,de,bc,flags,acc,sp) +_: + .db insn & $FF + .db insn>>8 & $FF + .db insn>>16 & $FF + .dw memop,iy,ix,hl,de,bc + .db flags + .db acc + .dw sp +#if eval($ - -_) != 20 + .error "missing parameter" +#endif +#endmacro + +#macro tmsg(mesg) +_: .db (mesg) + .fill -_+30-$,'.' + .db '$' +#endmacro + +; hl, (38,912 cycles) +adc16: .db 0c7h ; flag mask + tstr <0edh,042h>,0832ch,04f88h,0f22bh,0b339h,07e1fh,01563h,0d3h,089h,0465eh + tstr <0,038h>,0,0,0,0f821h,0,0,0,0,0 ; (1024 cycles) + tstr 0,0,0,0,-1,-1,-1,0d7h,0,-1 ; (38 cycles) + .db 0f8h,0b4h,0eah,0a9h ; expected crc + tmsg " hl," + +; add hl, (19,456 cycles) +add16: .db 0c7h ; flag mask + tstr 9,0c4a5h,0c4c7h,0d226h,0a050h,058eah,08566h,0c6h,0deh,09bc9h + tstr 030h,0,0,0,0f821h,0,0,0,0,0 ; (512 cycles) + tstr 0,0,0,0,-1,-1,-1,0d7h,0,-1 ; (38 cycles) + .db 089h,0fdh,0b6h,035h ; expected crc + tmsg 'add hl,' + +; add ix, (19,456 cycles) +add16x: .db 0c7h ; flag mask + tstr <0ddh,9>,0ddach,0c294h,0635bh,033d3h,06a76h,0fa20h,094h,068h,036f5h + tstr <0,030h>,0,0,0f821h,0,0,0,0,0,0 ; (512 cycles) + tstr 0,0,0,-1,0,-1,-1,0d7h,0,-1 ; (38 cycles) + .db 0c1h,033h,079h,00bh ; expected crc + tmsg 'add ix,' + +; add iy, (19,456 cycles) +add16y: .db 0c7h ; flag mask + tstr <0fdh,9>,0c7c2h,0f407h,051c1h,03e96h,00bf4h,0510fh,092h,01eh,071eah + tstr <0,030h>,0,0f821h,0,0,0,0,0,0,0 ; (512 cycles) + tstr 0,0,-1,0,0,-1,-1,0d7h,0,-1 ; (38 cycles) + .db 0e8h,081h,07bh,09eh ; expected crc + tmsg 'add iy,' + +; aluop a,nn (28,672 cycles) +alu8i: .db 0d7h ; flag mask + tstr 0c6h,09140h,07e3ch,07a67h,0df6dh,05b61h,00b29h,010h,066h,085b2h + tstr 038h,0,0,0,0,0,0,0,-1,0 ; (2048 cycles) + tstr <0,-1>,0,0,0,0,0,0,0d7h,0,0 ; (14 cycles) + .db 048h,079h,093h,060h ; expected crc + tmsg 'aluop a,nn' + +; aluop a, (753,664 cycles) +alu8r: .db 0d7h ; flag mask + tstr 080h,0c53eh,0573ah,04c4dh,msbt,0e309h,0a666h,0d0h,03bh,0adbbh + tstr 03fh,0,0,0,0,0,0,0,-1,0 ; (16,384 cycles) + tstr 0,0ffh,0,0,0,-1,-1,0d7h,0,0 ; (46 cycles) + .db 0feh,043h,0b0h,016h ; expected crc + tmsg 'aluop a,' + +; aluop a, (376,832 cycles) +alu8rx: .db 0d7h ; flag mask + tstr <0ddh,084h>,0d6f7h,0c76eh,0accfh,02847h,022ddh,0c035h,0c5h,038h,0234bh + tstr <020h,039h>,0,0,0,0,0,0,0,-1,0 ; (8,192 cycles) + tstr 0,0ffh,0,0,0,-1,-1,0d7h,0,0 ; (46 cycles) + .db 0a4h,002h,06dh,05ah ; expected crc + tmsg 'aluop a,' + +; aluop a,(+1) (229,376 cycles) +alu8x: .db 0d7h ; flag mask + tstr <0ddh,086h,1>,090b7h,msbt-1,msbt-1,032fdh,0406eh,0c1dch,045h,06eh,0e5fah + tstr <020h,038h>,0,1,1,0,0,0,0,-1,0 ; (16,384 cycles) + tstr 0,0ffh,0,0,0,0,0,0d7h,0,0 ; (14 cycles) + .db 0e8h,049h,067h,06eh ; expected crc + tmsg 'aluop a,(+1)' + +; bit n,(+1) (2048 cycles) +bitx: .db 053h ; flag mask + tstr <0ddh,0cbh,1,046h>,02075h,msbt-1,msbt-1,03cfch,0a79ah,03d74h,051h,027h,0ca14h + tstr <020h,0,0,038h>,0,0,0,0,0,0,053h,0,0 ; (256 cycles) + tstr 0,0ffh,0,0,0,0,0,0,0,0 ; (8 cycles) + .db 0a8h,0eeh,008h,067h ; expected crc + tmsg 'bit n,(+1)' + +; bit n, (49,152 cycles) +bitz80: .db 053h ; flag mask + tstr <0cbh,040h>,03ef1h,09dfch,07acch,msbt,0be61h,07a86h,050h,024h,01998h + tstr <0,03fh>,0,0,0,0,0,0,053h,0,0 ; (1024 cycles) + tstr 0,0ffh,0,0,0,-1,-1,0,-1,0 ; (48 cycles) + .db 07bh,055h,0e6h,0c8h ; expected crc + tmsg 'bit n,' + +; cpd (1) (6144 cycles) +cpd1: .db 0d7h ; flag mask + tstr <0edh,0a9h>,0c7b6h,072b4h,018f6h,msbt+17,08dbdh,1,0c0h,030h,094a3h + tstr <0,010h>,0,0,0,0,0,010,0,-1,0 ; (1024 cycles) + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + .db 0a8h,07eh,06ch,0fah ; expected crc + tmsg 'cpd' + +; cpi (1) (6144 cycles) +cpi1: .db 0d7h ; flag mask + tstr <0edh,0a1h>,04d48h,0af4ah,0906bh,msbt,04e71h,1,093h,06ah,0907ch + tstr <0,010h>,0,0,0,0,0,010,0,-1,0 ; (1024 cycles) + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + .db 006h,0deh,0b3h,056h ; expected crc + tmsg 'cpi' + +; +daa: .db 0d7h ; flag mask + tstr 027h,02141h,009fah,01d60h,0a559h,08d5bh,09079h,004h,08eh,0299dh + tstr 018h,0,0,0,0,0,0,0d7h,-1,0 ; (65,536 cycles) + tstr 0,0,0,0,0,0,0,0,0,0 ; (1 cycle) + .db 09bh,04bh,0a6h,075h ; expected crc + tmsg '' + +; a (3072 cycles) +inca: .db 0d7h ; flag mask + tstr 03ch,04adfh,0d5d8h,0e598h,08a2bh,0a7b0h,0431bh,044h,05ah,0d030h + tstr 001h,0,0,0,0,0,0,0,-1,0 ; (512 cycles) + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + .db 0d1h,088h,015h,0a4h ; expected crc + tmsg ' a' + +; b (3072 cycles) +incb: .db 0d7h ; flag mask + tstr 004h,0d623h,0432dh,07a61h,08180h,05a86h,01e85h,086h,058h,09bbbh + tstr 001h,0,0,0,0,0,0ff00h,0,0,0 ; (512 cycles) + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + .db 05fh,068h,022h,064h ; expected crc + tmsg ' b' + +; bc (1536 cycles) +incbc: .db 0d7h ; flag mask + tstr 003h,0cd97h,044abh,08dc9h,0e3e3h,011cch,0e8a4h,002h,049h,02a4dh + tstr 008h,0,0,0,0,0,0f821h,0,0,0 ; (256 cycles) + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + .db 0d2h,0aeh,03bh,0ech ; expected crc + tmsg ' bc' + +; c (3072 cycles) +incc: .db 0d7h ; flag mask + tstr 00ch,0d789h,00935h,0055bh,09f85h,08b27h,0d208h,095h,005h,00660h + tstr 001h,0,0,0,0,0,0ffh,0,0,0 ; (512 cycles) + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + .db 0c2h,084h,055h,04ch ; expected crc + tmsg ' c' + +; d (3072 cycles) +incd: .db 0d7h ; flag mask + tstr 014h,0a0eah,05fbah,065fbh,0981ch,038cch,0debch,043h,05ch,003bdh + tstr 001h,0,0,0,0,0ff00h,0,0,0,0 ; (512 cycles) + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + .db 045h,023h,0deh,010h ; expected crc + tmsg ' d' + +; de (1536 cycles) +incde: .db 0d7h ; flag mask + tstr 013h,0342eh,0131dh,028c9h,00acah,09967h,03a2eh,092h,0f6h,09d54h + tstr 008h,0,0,0,0,0f821h,0,0,0,0 ; (256 cycles) + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + .db 0aeh,0c6h,0d4h,02ch ; expected crc + tmsg ' de' + +; e (3072 cycles) +ince: .db 0d7h ; flag mask + tstr 01ch,0602fh,04c0dh,02402h,0e2f5h,0a0f4h,0a10ah,013h,032h,05925h + tstr 001h,0,0,0,0,0ffh,0,0,0,0 ; (512 cycles) + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + .db 0e1h,075h,0afh,0cch ; expected crc + tmsg ' e' + +; h (3072 cycles) +inch: .db 0d7h ; flag mask + tstr 024h,01506h,0f2ebh,0e8ddh,0262bh,011a6h,0bc1ah,017h,006h,02818h + tstr 001h,0,0,0,0ff00h,0,0,0,0,0 ; (512 cycles) + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + .db 01ch,0edh,084h,07dh ; expected crc + tmsg ' h' + +; hl (1536 cycles) +inchl: .db 0d7h ; flag mask + tstr 023h,0c3f4h,007a5h,01b6dh,04f04h,0e2c2h,0822ah,057h,0e0h,0c3e1h + tstr 008h,0,0,0,0f821h,0,0,0,0,0 ; (256 cycles) + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + .db 0fch,00dh,06dh,04ah ; expected crc + tmsg ' hl' + +; ix (1536 cycles) +incix: .db 0d7h ; flag mask + tstr <0ddh,023h>,0bc3ch,00d9bh,0e081h,0adfdh,09a7fh,096e5h,013h,085h,00be2h + tstr <0,8>,0,0,0f821h,0,0,0,0,0,0 ; (256 cycles) + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + .db 0a5h,04dh,0beh,031h ; expected crc + tmsg ' ix' + +; iy (1536 cycles) +inciy: .db 0d7h ; flag mask + tstr <0fdh,023h>,09402h,0637ah,03182h,0c65ah,0b2e9h,0abb4h,016h,0f2h,06d05h + tstr <0,8>,0,0f821h,0,0,0,0,0,0,0 ; (256 cycles) + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + .db 050h,05dh,051h,0a3h ; expected crc + tmsg ' iy' + +; l (3072 cycles) +incl: .db 0d7h ; flag mask + tstr 02ch,08031h,0a520h,04356h,0b409h,0f4c1h,0dfa2h,0d1h,03ch,03ea2h + tstr 001h,0,0,0,0ffh,0,0,0,0,0 ; (512 cycles) + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + .db 056h,0cdh,006h,0f3h ; expected crc + tmsg ' l' + +; (hl) (3072 cycles) +incm: .db 0d7h ; flag mask + tstr 034h,0b856h,00c7ch,0e53eh,msbt,0877eh,0da58h,015h,05ch,01f37h + tstr 001h,0ffh,0,0,0,0,0,0,0,0 ; (512 cycles) + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + .db 0b8h,03ah,0dch,0efh ; expected crc + tmsg ' (hl)' + +; sp (1536 cycles) +incsp: .db 0d7h ; flag mask + tstr 033h,0346fh,0d482h,0d169h,0deb6h,0a494h,0f476h,053h,002h,0855bh + tstr 008h,0,0,0,0,0,0,0,0,0f821h ; (256 cycles) + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + .db 05dh,0ach,0d5h,027h ; expected crc + tmsg ' sp' + +; (+1) (6144 cycles) +incx: .db 0d7h ; flag mask + tstr <0ddh,034h,1>,0fa6eh,msbt-1,msbt-1,02c28h,08894h,05057h,016h,033h,0286fh + tstr <020h,1>,0ffh,0,0,0,0,0,0,0,0 ; (1024 cycles) + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + .db 020h,058h,014h,070h ; expected crc + tmsg ' (+1)' + +; ixh (3072 cycles) +incxh: .db 0d7h ; flag mask + tstr <0ddh,024h>,0b838h,0316ch,0c6d4h,03e01h,08358h,015b4h,081h,0deh,04259h + tstr <0,1>,0,0ff00h,0,0,0,0,0,0,0 ; (512 cycles) + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + .db 06fh,046h,036h,062h ; expected crc + tmsg ' ixh' + +; ixl (3072 cycles) +incxl: .db 0d7h ; flag mask + tstr <0ddh,02ch>,04d14h,07460h,076d4h,006e7h,032a2h,0213ch,0d6h,0d7h,099a5h + tstr <0,1>,0,0ffh,0,0,0,0,0,0,0 ; (512 cycles) + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + .db 002h,07bh,0efh,02ch ; expected crc + tmsg ' ixl' + +; iyh (3072 cycles) +incyh: .db 0d7h ; flag mask + tstr <0ddh,024h>,02836h,09f6fh,09116h,061b9h,082cbh,0e219h,092h,073h,0a98ch + tstr <0,1>,0ff00h,0,0,0,0,0,0,0,0 ; (512 cycles) + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + .db 02dh,096h,06ch,0f3h ; expected crc + tmsg ' iyh' + +; iyl (3072 cycles) +incyl: .db 0d7h ; flag mask + tstr <0ddh,02ch>,0d7c6h,062d5h,0a09eh,07039h,03e7eh,09f12h,090h,0d9h,0220fh + tstr <0,1>,0ffh,0,0,0,0,0,0,0,0 ; (512 cycles) + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + .db 0fbh,0cbh,0bah,095h ; expected crc + tmsg ' iyl' + +; ld ,(nnnn) (32 cycles) +ld161: .db 0d7h ; flag mask + tstr <0edh,04bh,low msbt,high msbt>,0f9a8h,0f559h,093a4h,0f5edh,06f96h,0d968h,086h,0e6h,04bd8h + tstr <0,010h>,0,0,0,0,0,0,0,0,0 ; (2 cycles) + tstr 0,-1,0,0,0,0,0,0,0,0 ; (16 cycles) + .db 04dh,045h,0a9h,0ach ; expected crc + tmsg 'ld ,(nnnn)' + +; ld hl,(nnnn) (16 cycles) +ld162: .db 0d7h ; flag mask + tstr <02ah,low msbt,high msbt>,09863h,07830h,02077h,0b1feh,0b9fah,0abb8h,004h,006h,06015h + tstr 0,0,0,0,0,0,0,0,0,0 ; (1 cycle) + tstr 0,-1,0,0,0,0,0,0,0,0 ; (16 cycles) + .db 05fh,097h,024h,087h ; expected crc + tmsg 'ld hl,(nnnn)' + +; ld sp,(nnnn) (16 cycles) +ld163: .db 0d7h ; flag mask + tstr <0edh,07bh,low msbt,high msbt>,08dfch,057d7h,02161h,0ca18h,0c185h,027dah,083h,01eh,0f460h + tstr 0,0,0,0,0,0,0,0,0,0 ; (1 cycles) + tstr 0,-1,0,0,0,0,0,0,0,0 ; (16 cycles) + .db 07ah,0ceh,0a1h,01bh ; expected crc + tmsg 'ld sp,(nnnn)' + +; ld ,(nnnn) (32 cycles) +ld164: .db 0d7h ; flag mask + tstr <0ddh,02ah,low msbt,high msbt>,0ded7h,0a6fah,0f780h,0244ch,087deh,0bcc2h,016h,063h,04c96h + tstr 020h,0,0,0,0,0,0,0,0,0 ; (2 cycles) + tstr 0,-1,0,0,0,0,0,0,0,0 ; (16 cycles) + .db 085h,08bh,0f1h,06dh ; expected crc + tmsg 'ld ,(nnnn)' + +; ld (nnnn), (64 cycles) +ld165: .db 0d7h ; flag mask + tstr <0edh,043h,low msbt,high msbt>,01f98h,0844dh,0e8ach,0c9edh,0c95dh,08f61h,080h,03fh,0c7bfh + tstr <0,010h>,0,0,0,0,0,0,0,0,0 ; (2 cycles) + tstr 0,0,0,0,0,-1,-1,0,0,0 ; (32 cycles) + .db 064h,01eh,087h,015h ; expected crc + tmsg 'ld (nnnn),' + +; ld (nnnn),hl (16 cycles) +ld166: .db 0d7h ; flag mask + tstr <022h,low msbt,high msbt>,0d003h,07772h,07f53h,03f72h,064eah,0e180h,010h,02dh,035e9h + tstr 0,0,0,0,0,0,0,0,0,0 ; (1 cycle) + tstr 0,0,0,0,-1,0,0,0,0,0 ; (16 cycles) + .db 0a3h,060h,08bh,047h ; expected crc + tmsg 'ld (nnnn),hl' + +; ld (nnnn),sp (16 cycles) +ld167: .db 0d7h ; flag mask + tstr <0edh,073h,low msbt,high msbt>,0c0dch,0d1d6h,0ed5ah,0f356h,0afdah,06ca7h,044h,09fh,03f0ah + tstr 0,0,0,0,0,0,0,0,0,0 ; (1 cycle) + tstr 0,0,0,0,0,0,0,0,0,-1 ; (16 cycles) + .db 016h,058h,05fh,0d7h ; expected crc + tmsg 'ld (nnnn),sp' + +; ld (nnnn), (64 cycles) +ld168: .db 0d7h ; flag mask + tstr <0ddh,022h,low msbt,high msbt>,06cc3h,00d91h,06900h,08ef8h,0e3d6h,0c3f7h,0c6h,0d9h,0c2dfh + tstr 020h,0,0,0,0,0,0,0,0,0 ; (2 cycles) + tstr 0,0,-1,-1,0,0,0,0,0,0 ; (32 cycles) + .db 0bah,010h,02ah,06bh ; expected crc + tmsg 'ld (nnnn),' + +; ld ,nnnn (64 cycles) +ld16im: .db 0d7h ; flag mask + tstr 1,05c1ch,02d46h,08eb9h,06078h,074b1h,0b30eh,046h,0d1h,030cch + tstr 030h,0,0,0,0,0,0,0,0,0 ; (4 cycles) + tstr <0,0ffh,0ffh>,0,0,0,0,0,0,0,0,0 ; (16 cycles) + .db 0deh,039h,019h,069h ; expected crc + tmsg 'ld ,nnnn' + +; ld ,nnnn (32 cycles) +ld16ix: .db 0d7h ; flag mask + tstr <0ddh,021h>,087e8h,02006h,0bd12h,0b69bh,07253h,0a1e5h,051h,013h,0f1bdh + tstr 020h,0,0,0,0,0,0,0,0,0 ; (2 cycles) + tstr <0,0,0ffh,0ffh>,0,0,0,0,0,0,0,0,0 ; (16 cycles) + .db 022h,07dh,0d5h,025h ; expected crc + tmsg 'ld ,nnnn' + +; ld a,<(bc),(de)> (44 cycles) +ld8bd: .db 0d7h ; flag mask + tstr 00ah,0b3a8h,01d2ah,07f8eh,042ach,msbt,msbt,0c6h,0b1h,0ef8eh + tstr 010h,0,0,0,0,0,0,0,0,0 ; (2 cycles) + tstr 0,0ffh,0,0,0,0,0,0d7h,-1,0 ; (22 cycles) + .db 0b0h,081h,089h,035h ; expected crc + tmsg 'ld a,<(bc),(de)>' + +; ld ,nn (64 cycles) +ld8im: .db 0d7h ; flag mask + tstr 6,0c407h,0f49dh,0d13dh,00339h,0de89h,07455h,053h,0c0h,05509h + tstr 038h,0,0,0,0,0,0,0,0,0 ; (8 cycles) + tstr 0,0,0,0,0,0,0,0,-1,0 ; (8 cycles) + .db 0f1h,0dah,0b5h,056h ; expected crc + tmsg 'ld ,nn' + +; ld (+1),nn (32 cycles) +ld8imx: .db 0d7h ; flag mask + tstr <0ddh,036h,1>,01b45h,msbt-1,msbt-1,0d5c1h,061c7h,0bdc4h,0c0h,085h,0cd16h + tstr 020h,0,0,0,0,0,0,0,0,0 ; (2 cycles) + tstr <0,0,0,-1>,0,0,0,0,0,0,0,-1,0 ; (16 cycles) + .db 026h,0dbh,047h,07eh ; expected crc + tmsg 'ld (+1),nn' + +; ld ,(+1) (512 cycles) +ld8ix1: .db 0d7h ; flag mask + tstr <0ddh,046h,1>,0d016h,msbt-1,msbt-1,04260h,07f39h,00404h,097h,04ah,0d085h + tstr <020h,018h>,0,1,1,0,0,0,0,0,0 ; (32 cycles) + tstr 0,-1,0,0,0,0,0,0,0,0 ; (16 cycles) + .db 0cch,011h,006h,0a8h ; expected crc + tmsg 'ld ,(+1)' + +; ld ,(+1) (256 cycles) +ld8ix2: .db 0d7h ; flag mask + tstr <0ddh,066h,1>,084e0h,msbt-1,msbt-1,09c52h,0a799h,049b6h,093h,000h,0eeadh + tstr <020h,008h>,0,1,1,0,0,0,0,0,0 ; (16 cycles) + tstr 0,-1,0,0,0,0,0,0,0,0 ; (16 cycles) + .db 0fah,02ah,04dh,003h ; expected crc + tmsg 'ld ,(+1)' + +; ld a,(+1) (128 cycles) +ld8ix3: .db 0d7h ; flag mask + tstr <0ddh,07eh,1>,0d8b6h,msbt-1,msbt-1,0c612h,0df07h,09cd0h,043h,0a6h,0a0e5h + tstr 020h,0,1,1,0,0,0,0,0,0 ; (8 cycles) + tstr 0,-1,0,0,0,0,0,0,0,0 ; (16 cycles) + .db 0a5h,0e9h,0ach,064h ; expected crc + tmsg 'ld a,(+1)' + +; ld ,nn (32 cycles) +ld8ixy: .db 0d7h ; flag mask + tstr <0ddh,026h>,03c53h,04640h,0e179h,07711h,0c107h,01afah,081h,0adh,05d9bh + tstr <020h,8>,0,0,0,0,0,0,0,0,0 ; (4 cycles) + tstr 0,0,0,0,0,0,0,0,-1,0 ; (8 cycles) + .db 024h,0e8h,082h,08bh ; expected crc + tmsg 'ld ,nn' + +; ld , (3456 cycles) +ld8rr: .db 0d7h ; flag mask + tstr 040h,072a4h,0a024h,061ach,msbt,082c7h,0718fh,097h,08fh,0ef8eh + tstr 03fh,0,0,0,0,0,0,0,0,0 ; (64 cycles) + tstr 0,0ffh,0,0,0,-1,-1,0d7h,-1,0 ; (54 cycles) + .db 074h,04bh,001h,018h ; expected crc + tmsg 'ld ,' + +; ld , (6912 cycles) +ld8rrx: .db 0d7h ; flag mask + tstr <0ddh,040h>,0bcc5h,msbt,msbt,msbt,02fc2h,098c0h,083h,01fh,03bcdh + tstr <020h,03fh>,0,0,0,0,0,0,0,0,0 ; (128 cycles) + tstr 0,0ffh,0,0,0,-1,-1,0d7h,-1,0 ; (54 cycles) + .db 047h,08bh,0a3h,06bh ; expected crc + tmsg 'ld ,' + +; ld a,(nnnn) / ld (nnnn),a (44 cycles) +lda: .db 0d7h ; flag mask + tstr <032h,low msbt,high msbt>,0fd68h,0f4ech,044a0h,0b543h,00653h,0cdbah,0d2h,04fh,01fd8h + tstr 008h,0,0,0,0,0,0,0,0,0 ; (2 cycle) + tstr 0,0ffh,0,0,0,0,0,0d7h,-1,0 ; (22 cycles) + .db 0c9h,026h,02dh,0e5h ; expected crc + tmsg 'ld a,(nnnn) / ld (nnnn),a' + +; ldd (1) (44 cycles) +ldd1: .db 0d7h ; flag mask + tstr <0edh,0a8h>,09852h,068fah,066a1h,msbt+3,msbt+1,1,0c1h,068h,020b7h + tstr <0,010h>,0,0,0,0,0,0,0,0,0 ; (2 cycles) + tstr 0,-1,0,0,0,0,0,0d7h,0,0 ; (22 cycles) + .db 094h,0f4h,027h,069h ; expected crc + tmsg 'ldd (1)' + +; ldd (2) (44 cycles) +ldd2: .db 0d7h ; flag mask + tstr <0edh,0a8h>,0f12eh,0eb2ah,0d5bah,msbt+3,msbt+1,2,047h,0ffh,0fbe4h + tstr <0,010h>,0,0,0,0,0,0,0,0,0 ; (2 cycles) + tstr 0,-1,0,0,0,0,0,0d7h,0,0 ; (22 cycles) + .db 05ah,090h,07eh,0d4h ; expected crc + tmsg 'ldd (2)' + +; ldi (1) (44 cycles) +ldi1: .db 0d7h ; flag mask + tstr <0edh,0a0h>,0fe30h,003cdh,06058h,msbt+2,msbt,1,004h,060h,02688h + tstr <0,010h>,0,0,0,0,0,0,0,0,0 ; (2 cycles) + tstr 0,-1,0,0,0,0,0,0d7h,0,0 ; (22 cycles) + .db 09ah,0bdh,0f6h,0b5h ; expected crc + tmsg 'ldi (1)' + +; ldi (2) (44 cycles) +ldi2: .db 0d7h ; flag mask + tstr <0edh,0a0h>,04aceh,0c26eh,0b188h,msbt+2,msbt,2,014h,02dh,0a39fh + tstr <0,010h>,0,0,0,0,0,0,0,0,0 ; (2 cycles) + tstr 0,-1,0,0,0,0,0,0d7h,0,0 ; (22 cycles) + .db 0ebh,059h,089h,01bh ; expected crc + tmsg 'ldi (2)' + +; neg (16,384 cycles) +neg: .db 0d7h ; flag mask + tstr <0edh,044h>,038a2h,05f6bh,0d934h,057e4h,0d2d6h,04642h,043h,05ah,009cch + tstr 0,0,0,0,0,0,0,0d7h,-1,0 ; (16,384 cycles) + tstr 0,0,0,0,0,0,0,0,0,0 ; (1 cycle) + .db 06ah,03ch,03bh,0bdh ; expected crc + tmsg 'neg' + +; (7168 cycles) +rld: .db 0d7h ; flag mask + tstr <0edh,067h>,091cbh,0c48bh,0fa62h,msbt,0e720h,0b479h,040h,006h,08ae2h + tstr <0,8>,0ffh,0,0,0,0,0,0,0,0 ; (512 cycles) + tstr 0,0,0,0,0,0,0,0d7h,-1,0 ; (14 cycles) + .db 095h,05bh,0a3h,026h ; expected crc + tmsg '' + +; (6144 cycles) +rot8080: .db 0d7h ; flag mask + tstr 7,0cb92h,06d43h,00a90h,0c284h,00c53h,0f50eh,091h,0ebh,040fch + tstr 018h,0,0,0,0,0,0,0,-1,0 ; (1024 cycles) + tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) + .db 025h,013h,030h,0aeh ; expected crc + tmsg '' + +; shift/rotate (+1) (416 cycles) +rotxy: .db 0d7h ; flag mask + tstr <0ddh,0cbh,1,6>,0ddafh,msbt-1,msbt-1,0ff3ch,0dbf6h,094f4h,082h,080h,061d9h + tstr <020h,0,0,038h>,0,0,0,0,0,0,080h,0,0 ; (32 cycles) + tstr 0,0ffh,0,0,0,0,0,057h,0,0 ; (13 cycles) + .db 071h,03ah,0cdh,081h ; expected crc + tmsg 'shf/rot (+1)' + +; shift/rotate (6784 cycles) +rotz80: .db 0d7h ; flag mask + tstr 0cbh,0ccebh,05d4ah,0e007h,msbt,01395h,030eeh,043h,078h,03dadh + tstr <0,03fh>,0,0,0,0,0,0,080h,0,0 ; (128 cycles) + tstr 0,0ffh,0,0,0,-1,-1,057h,-1,0 ; (53 cycles) + .db 0ebh,060h,04dh,058h ; expected crc + tmsg 'shf/rot ' + +; n, (7936 cycles) +srz80: .db 0d7h ; flag mask + tstr <0cbh,080h>,02cd5h,097abh,039ffh,msbt,0d14bh,06ab2h,053h,027h,0b538h + tstr <0,07fh>,0,0,0,0,0,0,0,0,0 ; (128 cycles) + tstr 0,0ffh,0,0,0,-1,-1,0d7h,-1,0 ; (62 cycles) + .db 08bh,057h,0f0h,008h ; expected crc + tmsg ' n,' + +; n,(+1) (1792 cycles) +srzx: .db 0d7h ; flag mask + tstr <0ddh,0cbh,1,086h>,0fb44h,msbt-1,msbt-1,0ba09h,068beh,032d8h,010h,05eh,0a867h + tstr <020h,0,0,078h>,0,0,0,0,0,0,0,0,0 ; (128 cycles) + tstr 0,0ffh,0,0,0,0,0,0d7h,0,0 ;(14 cycles) + .db 0cch,063h,0f9h,08ah ; expected crc + tmsg ' n,(+1)' + +; ld (+1), (1024 cycles) +st8ix1: .db 0d7h ; flag mask + tstr <0ddh,070h,1>,0270dh,msbt-1,msbt-1,0b73ah,0887bh,099eeh,086h,070h,0ca07h + tstr <020h,003h>,0,1,1,0,0,0,0,0,0 ; (32 cycles) + tstr 0,0,0,0,0,-1,-1,0,0,0 ; (32 cycles) + .db 004h,062h,06ah,0bfh ; expected crc + tmsg 'ld (+1),' + +; ld (+1), (256 cycles) +st8ix2: .db 0d7h ; flag mask + tstr <0ddh,074h,1>,0b664h,msbt-1,msbt-1,0e8ach,0b5f5h,0aafeh,012h,010h,09566h + tstr <020h,001h>,0,1,1,0,0,0,0,0,0 ; (16 cycles) + tstr 0,0,0,0,-1,0,0,0,0,0 ; (32 cycles) + .db 06ah,01ah,088h,031h ; expected crc + tmsg 'ld (+1),' + +; ld (+1),a (64 cycles) +st8ix3: .db 0d7h ; flag mask + tstr <0ddh,077h,1>,067afh,msbt-1,msbt-1,04f13h,00644h,0bcd7h,050h,0ach,05fafh + tstr 020h,0,1,1,0,0,0,0,0,0 ; (8 cycles) + tstr 0,0,0,0,0,0,0,0,-1,0 ; (8 cycles) + .db 0cch,0beh,05ah,096h ; expected crc + tmsg 'ld (+1),a' + +; ld (),a (96 cycles) +stabd: .db 0d7h ; flag mask + tstr 2,00c3bh,0b592h,06cffh,0959eh,msbt,msbt+1,0c1h,021h,0bde7h + tstr 018h,0,0,0,0,0,0,0,0,0 ; (4 cycles) + tstr 0,-1,0,0,0,0,0,0,-1,0 ; (24 cycles) + .db 07ah,04ch,011h,04fh ; expected crc + tmsg 'ld (),a' + +; start test pointed to by (hl) +stt: push hl + ld a,(hl) ; get pointer to test + inc hl + ld h,(hl) + ld l,a + ld a,(hl) ; flag mask + ld (flgmsk+1),a + inc hl + push hl + ld de,20 + add hl,de ; point to incmask + ld de,counter + call initmask + pop hl + push hl + ld de,20+20 + add hl,de ; point to scanmask + ld de,shifter + call initmask + ld hl,shifter + ld (hl),1 ; first bit + pop hl + push hl + ld de,iut ; copy initial instruction under test + ld bc,4 + ldir + ld de,msbt ; copy initial machine state + ld bc,16 + ldir + ld de,20+20+4 ; skip incmask, scanmask and expcrc + add hl,de + ex de,hl + call writestr ; show test name + call initcrc ; initialise crc +; test loop +tlp: ld a,(iut) + cp 076h ; pragmatically avoid halt intructions + jp z,tlp2 + and 0dfh + cp 0ddh + jp nz,tlp1 + ld a,(iut+1) + cp 076h +tlp1: call nz,test ; execute the test instruction +tlp2: call count ; increment the counter + call nz,shift ; shift the scan bit + pop hl ; pointer to test case + jp z,tlp3 ; done if shift returned NZ + ld de,20+20+20 + add hl,de ; point to expected crc + call cmpcrc + ld de,okmsg + jp z,tlpok + ld de,ermsg1 + call writestr + call phex8 + ld de,ermsg2 + call writestr + ld hl,crcval + call phex8 + ld de,crlf +tlpok: call writestr + pop hl + inc hl + inc hl + ret + +tlp3: push hl + ld a,1 ; initialise count and shift scanners + ld (cntbit),a + ld (shfbit),a + ld hl,counter + ld (cntbyt),hl + ld hl,shifter + ld (shfbyt),hl + + ld b,4 ; bytes in iut field + pop hl ; pointer to test case + push hl + ld de,iut + call setup ; setup iut + ld b,16 ; bytes in machine state + ld de,msbt + call setup ; setup machine state + jp tlp + +; setup a field of the test case +; b = number of bytes +; hl = pointer to base case +; de = destination +setup: call subyte + inc hl + dec b + jp nz,setup + ret + +subyte: push bc + push de + push hl + ld c,(hl) ; get base byte + ld de,20 + add hl,de ; point to incmask + ld a,(hl) + cp 0 + jp z,subshf + ld b,8 ; 8 bits +subclp: rrca + push af + ld a,0 + call c,nxtcbit ; get next counter bit if mask bit was set + xor c ; flip bit if counter bit was set + rrca + ld c,a + pop af + dec b + jp nz,subclp + ld b,8 +subshf: ld de,20 + add hl,de ; point to shift mask + ld a,(hl) + cp 0 + jp z,substr + ld b,8 ; 8 bits +sbshf1: rrca + push af + ld a,0 + call c,nxtsbit ; get next shifter bit if mask bit was set + xor c ; flip bit if shifter bit was set + rrca + ld c,a + pop af + dec b + jp nz,sbshf1 +substr: pop hl + pop de + ld a,c + ld (de),a ; mangled byte to destination + inc de + pop bc + ret + +; get next counter bit in low bit of a +cntbit: .fill 1 +cntbyt: .fill 2 + +nxtcbit: push bc + push hl + ld hl,(cntbyt) + ld b,(hl) + ld hl,cntbit + ld a,(hl) + ld c,a + rlca + ld (hl),a + cp 1 + jp nz,ncb1 + ld hl,(cntbyt) + inc hl + ld (cntbyt),hl +ncb1: ld a,b + and c + pop hl + pop bc + ret z + ld a,1 + ret + +; get next shifter bit in low bit of a +shfbit: .fill 1 +shfbyt: .fill 2 + +nxtsbit: push bc + push hl + ld hl,(shfbyt) + ld b,(hl) + ld hl,shfbit + ld a,(hl) + ld c,a + rlca + ld (hl),a + cp 1 + jp nz,nsb1 + ld hl,(shfbyt) + inc hl + ld (shfbyt),hl +nsb1: ld a,b + and c + pop hl + pop bc + ret z + ld a,1 + ret + + +; clear memory at hl, bc bytes +clrmem: push af + push bc + push de + push hl + ld (hl),0 + ld d,h + ld e,l + inc de + dec bc + ldir + pop hl + pop de + pop bc + pop af + ret + +; initialise counter or shifter +; de = pointer to work area for counter or shifter +; hl = pointer to mask +initmask: + push de + ex de,hl + ld bc,20+20 + call clrmem ; clear work area + ex de,hl + ld b,20 ; byte counter + ld c,1 ; first bit + ld d,0 ; bit counter +imlp: ld e,(hl) +imlp1: ld a,e + and c + jp z,imlp2 + inc d +imlp2: ld a,c + rlca + ld c,a + cp 1 + jp nz,imlp1 + inc hl + dec b + jp nz,imlp +; got number of 1-bits in mask in reg d + ld a,d + and 0f8h + rrca + rrca + rrca ; divide by 8 (get byte offset) + ld l,a + ld h,0 + ld a,d + and 7 ; bit offset + inc a + ld b,a + ld a,080h +imlp3: rlca + dec b + jp nz,imlp3 + pop de + add hl,de + ld de,20 + add hl,de + ld (hl),a + ret + +; multi-byte counter +count: push bc + push de + push hl + ld hl,counter ; 20 byte counter starts here + ld de,20 ; somewhere in here is the stop bit + ex de,hl + add hl,de + ex de,hl +cntlp: inc (hl) + ld a,(hl) + cp 0 + jp z,cntlp1 ; overflow to next byte + ld b,a + ld a,(de) + and b ; test for terminal value + jp z,cntend + ld (hl),0 ; reset to zero +cntend: pop bc + pop de + pop hl + ret + +cntlp1: inc hl + inc de + jp cntlp + + +; multi-byte shifter +shift: push bc + push de + push hl + ld hl,shifter ; 20 byte shift register starts here + ld de,20 ; somewhere in here is the stop bit + ex de,hl + add hl,de + ex de,hl +shflp: ld a,(hl) + or a + jp z,shflp1 + ld b,a + ld a,(de) + and b + jp nz,shlpe + ld a,b + rlca + cp 1 + jp nz,shflp2 + ld (hl),0 + inc hl + inc de +shflp2: ld (hl),a + xor a ; set Z +shlpe: pop hl + pop de + pop bc + ret +shflp1: inc hl + inc de + jp shflp + +counter: .fill 2*20 +shifter: .fill 2*20 + +; test harness +test: push af + push bc + push de + push hl +#if 0 + ld de,crlf + call writestr + ld hl,iut + ld b,4 + call hexstr + ld e,' ' + call writechar + ld b,16 + ld hl,msbt + call hexstr +#endif + di ; disable interrupts + ld (spsav),sp ; save stack pointer + ld sp,msbt+2 ; point to test-case machine state + pop iy ; and load all regs + pop ix + pop hl + pop de + pop bc + pop af + ld sp,(spbt) +iut: .fill 4 ; max 4 byte instruction under test + ld (spat),sp ; save stack pointer + ld sp,spat + push af ; save other registers + push bc + push de + push hl + push ix + push iy + ld sp,(spsav) ; restore stack pointer + ei ; enable interrupts + ld hl,(msbt) ; copy memory operand + ld (msat),hl + ld hl,flgsat ; flags after test + ld a,(hl) +flgmsk: and 0d7h ; mask-out irrelevant bits (self-modified code!) + ld (hl),a + ld b,16 ; total of 16 bytes of state + ld de,msat + ld hl,crcval +tcrc: ld a,(de) + inc de + call updcrc ; accumulate crc of this test case + dec b + jp nz,tcrc +#if 0 + ld e,' ' + call writechar + ld hl,crcval + call phex8 + ld de,crlf + call writestr + ld hl,msat + ld b,16 + call hexstr + ld de,crlf + call writestr +#endif + pop hl + pop de + pop bc + pop af + ret + +; machine state after test +msat: .fill 14 ; memop,iy,ix,hl,de,bc,af +spat: .fill 2 ; stack pointer after test +#define flgsat spat-2 ; flags + +spsav: .fill 2 ; saved stack pointer + +; display hex string (pointer in hl, byte count in b) +hexstr: ld a,(hl) + call phex2 + inc hl + dec b + jp nz,hexstr + ret + +; display hex +; display the big-endian 32-bit value pointed to by hl +phex8: push af + push bc + push hl + ld b,4 +ph8lp: ld a,(hl) + call phex2 + inc hl + dec b + jp nz,ph8lp + pop hl + pop bc + pop af + ret + +; display byte in a +phex2: push af + rrca + rrca + rrca + rrca + call phex1 + pop af +; fall through + +; display low nibble in a +phex1: push af + push bc + push de + push hl + and 0fh + cp 10 + jp c,ph11 + add a,'a'-'9'-1 +ph11: add a,'0' + ld e,a + call writechar + pop hl + pop de + pop bc + pop af + ret + + ;; Output routine. + ;; Print the character in A. +writechar: + out (000h),a + ret + + ;; Print the string in (DE), terminated by '$' (24h) +writestr: + push af + push bc + ld c,'$' +writestr_loop: + ld a,(de) + inc de + out (000h),a + cp c + jp nz,writestr_loop + pop bc + pop af + ret + +msg1: .db 'Z80 instruction exerciser',10,13,'$' +msg2: .db 'Tests complete$' +okmsg: .db ' OK',10,13,'$' +ermsg1: .db ' ERROR **** crc expected:$' +ermsg2: .db ' found:$' +crlf: .db 10,'$' + +; compare crc +; hl points to value to compare to crcval +cmpcrc: push bc + push de + push hl + ld de,crcval + ld b,4 +cclp: ld a,(de) + cp (hl) + jp nz,cce + inc hl + inc de + dec b + jp nz,cclp +cce: pop hl + pop de + pop bc + ret + +; 32-bit crc routine +; entry: a contains next byte, hl points to crc +; exit: crc updated +updcrc: push af + push bc + push de + push hl + push hl + ld de,3 + add hl,de ; point to low byte of old crc + xor (hl) ; xor with new byte + ld l,a + ld h,0 + add hl,hl ; use result as index into table of 4 byte entries + add hl,hl + ex de,hl + ld hl,crctab + add hl,de ; point to selected entry in crctab + ex de,hl + pop hl + ld bc,4 ; c = byte count, b = accumulator +crclp: ld a,(de) + xor b + ld b,(hl) + ld (hl),a + inc de + inc hl + dec c + jp nz,crclp +#if 0 + ld hl,crcval + call phex8 + ld de,crlf + ld c,9 + call bdos +#endif + pop hl + pop de + pop bc + pop af + ret + +initcrc: + push af + push bc + push hl + ld hl,crcval + ld a,0ffh + ld b,4 +icrclp: ld (hl),a + inc hl + dec b + jp nz,icrclp + pop hl + pop bc + pop af + ret + +crcval .fill 4 + +crctab: .db 000h,000h,000h,000h + .db 077h,007h,030h,096h + .db 0eeh,00eh,061h,02ch + .db 099h,009h,051h,0bah + .db 007h,06dh,0c4h,019h + .db 070h,06ah,0f4h,08fh + .db 0e9h,063h,0a5h,035h + .db 09eh,064h,095h,0a3h + .db 00eh,0dbh,088h,032h + .db 079h,0dch,0b8h,0a4h + .db 0e0h,0d5h,0e9h,01eh + .db 097h,0d2h,0d9h,088h + .db 009h,0b6h,04ch,02bh + .db 07eh,0b1h,07ch,0bdh + .db 0e7h,0b8h,02dh,007h + .db 090h,0bfh,01dh,091h + .db 01dh,0b7h,010h,064h + .db 06ah,0b0h,020h,0f2h + .db 0f3h,0b9h,071h,048h + .db 084h,0beh,041h,0deh + .db 01ah,0dah,0d4h,07dh + .db 06dh,0ddh,0e4h,0ebh + .db 0f4h,0d4h,0b5h,051h + .db 083h,0d3h,085h,0c7h + .db 013h,06ch,098h,056h + .db 064h,06bh,0a8h,0c0h + .db 0fdh,062h,0f9h,07ah + .db 08ah,065h,0c9h,0ech + .db 014h,001h,05ch,04fh + .db 063h,006h,06ch,0d9h + .db 0fah,00fh,03dh,063h + .db 08dh,008h,00dh,0f5h + .db 03bh,06eh,020h,0c8h + .db 04ch,069h,010h,05eh + .db 0d5h,060h,041h,0e4h + .db 0a2h,067h,071h,072h + .db 03ch,003h,0e4h,0d1h + .db 04bh,004h,0d4h,047h + .db 0d2h,00dh,085h,0fdh + .db 0a5h,00ah,0b5h,06bh + .db 035h,0b5h,0a8h,0fah + .db 042h,0b2h,098h,06ch + .db 0dbh,0bbh,0c9h,0d6h + .db 0ach,0bch,0f9h,040h + .db 032h,0d8h,06ch,0e3h + .db 045h,0dfh,05ch,075h + .db 0dch,0d6h,00dh,0cfh + .db 0abh,0d1h,03dh,059h + .db 026h,0d9h,030h,0ach + .db 051h,0deh,000h,03ah + .db 0c8h,0d7h,051h,080h + .db 0bfh,0d0h,061h,016h + .db 021h,0b4h,0f4h,0b5h + .db 056h,0b3h,0c4h,023h + .db 0cfh,0bah,095h,099h + .db 0b8h,0bdh,0a5h,00fh + .db 028h,002h,0b8h,09eh + .db 05fh,005h,088h,008h + .db 0c6h,00ch,0d9h,0b2h + .db 0b1h,00bh,0e9h,024h + .db 02fh,06fh,07ch,087h + .db 058h,068h,04ch,011h + .db 0c1h,061h,01dh,0abh + .db 0b6h,066h,02dh,03dh + .db 076h,0dch,041h,090h + .db 001h,0dbh,071h,006h + .db 098h,0d2h,020h,0bch + .db 0efh,0d5h,010h,02ah + .db 071h,0b1h,085h,089h + .db 006h,0b6h,0b5h,01fh + .db 09fh,0bfh,0e4h,0a5h + .db 0e8h,0b8h,0d4h,033h + .db 078h,007h,0c9h,0a2h + .db 00fh,000h,0f9h,034h + .db 096h,009h,0a8h,08eh + .db 0e1h,00eh,098h,018h + .db 07fh,06ah,00dh,0bbh + .db 008h,06dh,03dh,02dh + .db 091h,064h,06ch,097h + .db 0e6h,063h,05ch,001h + .db 06bh,06bh,051h,0f4h + .db 01ch,06ch,061h,062h + .db 085h,065h,030h,0d8h + .db 0f2h,062h,000h,04eh + .db 06ch,006h,095h,0edh + .db 01bh,001h,0a5h,07bh + .db 082h,008h,0f4h,0c1h + .db 0f5h,00fh,0c4h,057h + .db 065h,0b0h,0d9h,0c6h + .db 012h,0b7h,0e9h,050h + .db 08bh,0beh,0b8h,0eah + .db 0fch,0b9h,088h,07ch + .db 062h,0ddh,01dh,0dfh + .db 015h,0dah,02dh,049h + .db 08ch,0d3h,07ch,0f3h + .db 0fbh,0d4h,04ch,065h + .db 04dh,0b2h,061h,058h + .db 03ah,0b5h,051h,0ceh + .db 0a3h,0bch,000h,074h + .db 0d4h,0bbh,030h,0e2h + .db 04ah,0dfh,0a5h,041h + .db 03dh,0d8h,095h,0d7h + .db 0a4h,0d1h,0c4h,06dh + .db 0d3h,0d6h,0f4h,0fbh + .db 043h,069h,0e9h,06ah + .db 034h,06eh,0d9h,0fch + .db 0adh,067h,088h,046h + .db 0dah,060h,0b8h,0d0h + .db 044h,004h,02dh,073h + .db 033h,003h,01dh,0e5h + .db 0aah,00ah,04ch,05fh + .db 0ddh,00dh,07ch,0c9h + .db 050h,005h,071h,03ch + .db 027h,002h,041h,0aah + .db 0beh,00bh,010h,010h + .db 0c9h,00ch,020h,086h + .db 057h,068h,0b5h,025h + .db 020h,06fh,085h,0b3h + .db 0b9h,066h,0d4h,009h + .db 0ceh,061h,0e4h,09fh + .db 05eh,0deh,0f9h,00eh + .db 029h,0d9h,0c9h,098h + .db 0b0h,0d0h,098h,022h + .db 0c7h,0d7h,0a8h,0b4h + .db 059h,0b3h,03dh,017h + .db 02eh,0b4h,00dh,081h + .db 0b7h,0bdh,05ch,03bh + .db 0c0h,0bah,06ch,0adh + .db 0edh,0b8h,083h,020h + .db 09ah,0bfh,0b3h,0b6h + .db 003h,0b6h,0e2h,00ch + .db 074h,0b1h,0d2h,09ah + .db 0eah,0d5h,047h,039h + .db 09dh,0d2h,077h,0afh + .db 004h,0dbh,026h,015h + .db 073h,0dch,016h,083h + .db 0e3h,063h,00bh,012h + .db 094h,064h,03bh,084h + .db 00dh,06dh,06ah,03eh + .db 07ah,06ah,05ah,0a8h + .db 0e4h,00eh,0cfh,00bh + .db 093h,009h,0ffh,09dh + .db 00ah,000h,0aeh,027h + .db 07dh,007h,09eh,0b1h + .db 0f0h,00fh,093h,044h + .db 087h,008h,0a3h,0d2h + .db 01eh,001h,0f2h,068h + .db 069h,006h,0c2h,0feh + .db 0f7h,062h,057h,05dh + .db 080h,065h,067h,0cbh + .db 019h,06ch,036h,071h + .db 06eh,06bh,006h,0e7h + .db 0feh,0d4h,01bh,076h + .db 089h,0d3h,02bh,0e0h + .db 010h,0dah,07ah,05ah + .db 067h,0ddh,04ah,0cch + .db 0f9h,0b9h,0dfh,06fh + .db 08eh,0beh,0efh,0f9h + .db 017h,0b7h,0beh,043h + .db 060h,0b0h,08eh,0d5h + .db 0d6h,0d6h,0a3h,0e8h + .db 0a1h,0d1h,093h,07eh + .db 038h,0d8h,0c2h,0c4h + .db 04fh,0dfh,0f2h,052h + .db 0d1h,0bbh,067h,0f1h + .db 0a6h,0bch,057h,067h + .db 03fh,0b5h,006h,0ddh + .db 048h,0b2h,036h,04bh + .db 0d8h,00dh,02bh,0dah + .db 0afh,00ah,01bh,04ch + .db 036h,003h,04ah,0f6h + .db 041h,004h,07ah,060h + .db 0dfh,060h,0efh,0c3h + .db 0a8h,067h,0dfh,055h + .db 031h,06eh,08eh,0efh + .db 046h,069h,0beh,079h + .db 0cbh,061h,0b3h,08ch + .db 0bch,066h,083h,01ah + .db 025h,06fh,0d2h,0a0h + .db 052h,068h,0e2h,036h + .db 0cch,00ch,077h,095h + .db 0bbh,00bh,047h,003h + .db 022h,002h,016h,0b9h + .db 055h,005h,026h,02fh + .db 0c5h,0bah,03bh,0beh + .db 0b2h,0bdh,00bh,028h + .db 02bh,0b4h,05ah,092h + .db 05ch,0b3h,06ah,004h + .db 0c2h,0d7h,0ffh,0a7h + .db 0b5h,0d0h,0cfh,031h + .db 02ch,0d9h,09eh,08bh + .db 05bh,0deh,0aeh,01dh + .db 09bh,064h,0c2h,0b0h + .db 0ech,063h,0f2h,026h + .db 075h,06ah,0a3h,09ch + .db 002h,06dh,093h,00ah + .db 09ch,009h,006h,0a9h + .db 0ebh,00eh,036h,03fh + .db 072h,007h,067h,085h + .db 005h,000h,057h,013h + .db 095h,0bfh,04ah,082h + .db 0e2h,0b8h,07ah,014h + .db 07bh,0b1h,02bh,0aeh + .db 00ch,0b6h,01bh,038h + .db 092h,0d2h,08eh,09bh + .db 0e5h,0d5h,0beh,00dh + .db 07ch,0dch,0efh,0b7h + .db 00bh,0dbh,0dfh,021h + .db 086h,0d3h,0d2h,0d4h + .db 0f1h,0d4h,0e2h,042h + .db 068h,0ddh,0b3h,0f8h + .db 01fh,0dah,083h,06eh + .db 081h,0beh,016h,0cdh + .db 0f6h,0b9h,026h,05bh + .db 06fh,0b0h,077h,0e1h + .db 018h,0b7h,047h,077h + .db 088h,008h,05ah,0e6h + .db 0ffh,00fh,06ah,070h + .db 066h,006h,03bh,0cah + .db 011h,001h,00bh,05ch + .db 08fh,065h,09eh,0ffh + .db 0f8h,062h,0aeh,069h + .db 061h,06bh,0ffh,0d3h + .db 016h,06ch,0cfh,045h + .db 0a0h,00ah,0e2h,078h + .db 0d7h,00dh,0d2h,0eeh + .db 04eh,004h,083h,054h + .db 039h,003h,0b3h,0c2h + .db 0a7h,067h,026h,061h + .db 0d0h,060h,016h,0f7h + .db 049h,069h,047h,04dh + .db 03eh,06eh,077h,0dbh + .db 0aeh,0d1h,06ah,04ah + .db 0d9h,0d6h,05ah,0dch + .db 040h,0dfh,00bh,066h + .db 037h,0d8h,03bh,0f0h + .db 0a9h,0bch,0aeh,053h + .db 0deh,0bbh,09eh,0c5h + .db 047h,0b2h,0cfh,07fh + .db 030h,0b5h,0ffh,0e9h + .db 0bdh,0bdh,0f2h,01ch + .db 0cah,0bah,0c2h,08ah + .db 053h,0b3h,093h,030h + .db 024h,0b4h,0a3h,0a6h + .db 0bah,0d0h,036h,005h + .db 0cdh,0d7h,006h,093h + .db 054h,0deh,057h,029h + .db 023h,0d9h,067h,0bfh + .db 0b3h,066h,07ah,02eh + .db 0c4h,061h,04ah,0b8h + .db 05dh,068h,01bh,002h + .db 02ah,06fh,02bh,094h + .db 0b4h,00bh,0beh,037h + .db 0c3h,00ch,08eh,0a1h + .db 05ah,005h,0dfh,01bh + .db 02dh,002h,0efh,08dh + + + .end diff --git a/testbenches/zexdoc.z80 b/testbenches/zexdoc.z80 deleted file mode 100644 index eda26dd..0000000 --- a/testbenches/zexdoc.z80 +++ /dev/null @@ -1,1543 +0,0 @@ -; .title 'Z80 instruction set exerciser' - -; zexlax.z80 - Z80 instruction set exerciser -; Copyright (C) 1994 Frank D. Cringle -; -; This program is free software; you can redistribute it and/or -; modify it under the terms of the GNU General Public License -; as published by the Free Software Foundation; either version 2 -; of the License, or (at your option) any later version. -; -; This program is distributed in the hope that it will be useful, -; but WITHOUT ANY WARRANTY; without even the implied warranty of -; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -; GNU General Public License for more details. -; -; You should have received a copy of the GNU General Public License -; along with this program; if not, write to the Free Software -; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -; aseg -.ORG 4000h - - jp start - -; machine state before test (needs to be at predictably constant address) -msbt: .fill 14 -spbt: .fill 2 - -; For the purposes of this test program, the machine state consists of: -; a 2 byte memory operand, followed by -; the registers iy,ix,hl,de,bc,af,sp -; for a total of 16 bytes. - -; The program tests instructions (or groups of similar instructions) -; by cycling through a sequence of machine states, executing the test -; instruction for each one and running a 32-bit crc over the resulting -; machine states. At the end of the sequence the crc is compared to -; an expected value that was found empirically on a real Z80. - -; A test case is defined by a descriptor which consists of: -; a flag mask byte, -; the base case, -; the incement vector, -; the shift vector, -; the expected crc, -; a short descriptive message. -; -; The flag mask byte is used to prevent undefined flag bits from -; influencing the results. Documented flags are as per Mostek Z80 -; Technical Manual. -; -; The next three parts of the descriptor are 20 byte vectors -; corresponding to a 4 byte instruction and a 16 byte machine state. -; The first part is the base case, which is the first test case of -; the sequence. This base is then modified according to the next 2 -; vectors. Each 1 bit in the increment vector specifies a bit to be -; cycled in the form of a binary counter. For instance, if the byte -; corresponding to the accumulator is set to 0ffh in the increment -; vector, the test will be repeated for all 256 values of the -; accumulator. Note that 1 bits don't have to be contiguous. The -; number of test cases 'caused' by the increment vector is equal to -; 2^(number of 1 bits). The shift vector is similar, but specifies a -; set of bits in the test case that are to be successively inverted. -; Thus the shift vector 'causes' a number of test cases equal to the -; number of 1 bits in it. - -; The total number of test cases is the product of those caused by the -; counter and shift vectors and can easily become unweildy. Each -; individual test case can take a few milliseconds to execute, due to -; the overhead of test setup and crc calculation, so test design is a -; compromise between coverage and execution time. - -; This program is designed to detect differences between -; implementations and is not ideal for diagnosing the causes of any -; discrepancies. However, provided a reference implementation (or -; real system) is available, a failing test case can be isolated by -; hand using a binary search of the test space. - - -start: ld hl,(6) - ld sp,hl - ld de,msg1 - call writestr - - ld hl,tests ; first test case -loop: ld a,(hl) ; end of list ? - inc hl - or (hl) - jp z,done - dec hl - call stt - jp loop - -done: ld de,msg2 - call writestr - halt - -tests: - .dw adc16 - .dw add16 - .dw add16x - .dw add16y - .dw alu8i - .dw alu8r - .dw alu8rx - .dw alu8x - .dw bitx - .dw bitz80 - .dw cpd1 - .dw cpi1 - .dw daa - .dw inca - .dw incb - .dw incbc - .dw incc - .dw incd - .dw incde - .dw ince - .dw inch - .dw inchl - .dw incix - .dw inciy - .dw incl - .dw incm - .dw incsp - .dw incx - .dw incxh - .dw incxl - .dw incyh - .dw incyl - .dw ld161 - .dw ld162 - .dw ld163 - .dw ld164 - .dw ld165 - .dw ld166 - .dw ld167 - .dw ld168 - .dw ld16im - .dw ld16ix - .dw ld8bd - .dw ld8im - .dw ld8imx - .dw ld8ix1 - .dw ld8ix2 - .dw ld8ix3 - .dw ld8ixy - .dw ld8rr - .dw ld8rrx - .dw lda - .dw ldd1 - .dw ldd2 - .dw ldi1 - .dw ldi2 - .dw neg - .dw rld - .dw rot8080 - .dw rotxy - .dw rotz80 - .dw srz80 - .dw srzx - .dw st8ix1 - .dw st8ix2 - .dw st8ix3 - .dw stabd - .dw 0 - -#macro tstr(insn,memop,iy,ix,hl,de,bc,flags,acc,sp) -_: - .db insn & $FF - .db insn>>8 & $FF - .db insn>>16 & $FF - .dw memop,iy,ix,hl,de,bc - .db flags - .db acc - .dw sp -#if eval($ - -_) != 20 - .error "missing parameter" -#endif -#endmacro - -#macro tmsg(mesg) -_: .db (mesg) - .fill -_+30-$,'.' - .db '$' -#endmacro - -; hl, (38,912 cycles) -adc16: .db 0c7h ; flag mask - tstr <0edh,042h>,0832ch,04f88h,0f22bh,0b339h,07e1fh,01563h,0d3h,089h,0465eh - tstr <0,038h>,0,0,0,0f821h,0,0,0,0,0 ; (1024 cycles) - tstr 0,0,0,0,-1,-1,-1,0d7h,0,-1 ; (38 cycles) - .db 0f8h,0b4h,0eah,0a9h ; expected crc - tmsg " hl," - -; add hl, (19,456 cycles) -add16: .db 0c7h ; flag mask - tstr 9,0c4a5h,0c4c7h,0d226h,0a050h,058eah,08566h,0c6h,0deh,09bc9h - tstr 030h,0,0,0,0f821h,0,0,0,0,0 ; (512 cycles) - tstr 0,0,0,0,-1,-1,-1,0d7h,0,-1 ; (38 cycles) - .db 089h,0fdh,0b6h,035h ; expected crc - tmsg 'add hl,' - -; add ix, (19,456 cycles) -add16x: .db 0c7h ; flag mask - tstr <0ddh,9>,0ddach,0c294h,0635bh,033d3h,06a76h,0fa20h,094h,068h,036f5h - tstr <0,030h>,0,0,0f821h,0,0,0,0,0,0 ; (512 cycles) - tstr 0,0,0,-1,0,-1,-1,0d7h,0,-1 ; (38 cycles) - .db 0c1h,033h,079h,00bh ; expected crc - tmsg 'add ix,' - -; add iy, (19,456 cycles) -add16y: .db 0c7h ; flag mask - tstr <0fdh,9>,0c7c2h,0f407h,051c1h,03e96h,00bf4h,0510fh,092h,01eh,071eah - tstr <0,030h>,0,0f821h,0,0,0,0,0,0,0 ; (512 cycles) - tstr 0,0,-1,0,0,-1,-1,0d7h,0,-1 ; (38 cycles) - .db 0e8h,081h,07bh,09eh ; expected crc - tmsg 'add iy,' - -; aluop a,nn (28,672 cycles) -alu8i: .db 0d7h ; flag mask - tstr 0c6h,09140h,07e3ch,07a67h,0df6dh,05b61h,00b29h,010h,066h,085b2h - tstr 038h,0,0,0,0,0,0,0,-1,0 ; (2048 cycles) - tstr <0,-1>,0,0,0,0,0,0,0d7h,0,0 ; (14 cycles) - .db 048h,079h,093h,060h ; expected crc - tmsg 'aluop a,nn' - -; aluop a, (753,664 cycles) -alu8r: .db 0d7h ; flag mask - tstr 080h,0c53eh,0573ah,04c4dh,msbt,0e309h,0a666h,0d0h,03bh,0adbbh - tstr 03fh,0,0,0,0,0,0,0,-1,0 ; (16,384 cycles) - tstr 0,0ffh,0,0,0,-1,-1,0d7h,0,0 ; (46 cycles) - .db 0feh,043h,0b0h,016h ; expected crc - tmsg 'aluop a,' - -; aluop a, (376,832 cycles) -alu8rx: .db 0d7h ; flag mask - tstr <0ddh,084h>,0d6f7h,0c76eh,0accfh,02847h,022ddh,0c035h,0c5h,038h,0234bh - tstr <020h,039h>,0,0,0,0,0,0,0,-1,0 ; (8,192 cycles) - tstr 0,0ffh,0,0,0,-1,-1,0d7h,0,0 ; (46 cycles) - .db 0a4h,002h,06dh,05ah ; expected crc - tmsg 'aluop a,' - -; aluop a,(+1) (229,376 cycles) -alu8x: .db 0d7h ; flag mask - tstr <0ddh,086h,1>,090b7h,msbt-1,msbt-1,032fdh,0406eh,0c1dch,045h,06eh,0e5fah - tstr <020h,038h>,0,1,1,0,0,0,0,-1,0 ; (16,384 cycles) - tstr 0,0ffh,0,0,0,0,0,0d7h,0,0 ; (14 cycles) - .db 0e8h,049h,067h,06eh ; expected crc - tmsg 'aluop a,(+1)' - -; bit n,(+1) (2048 cycles) -bitx: .db 053h ; flag mask - tstr <0ddh,0cbh,1,046h>,02075h,msbt-1,msbt-1,03cfch,0a79ah,03d74h,051h,027h,0ca14h - tstr <020h,0,0,038h>,0,0,0,0,0,0,053h,0,0 ; (256 cycles) - tstr 0,0ffh,0,0,0,0,0,0,0,0 ; (8 cycles) - .db 0a8h,0eeh,008h,067h ; expected crc - tmsg 'bit n,(+1)' - -; bit n, (49,152 cycles) -bitz80: .db 053h ; flag mask - tstr <0cbh,040h>,03ef1h,09dfch,07acch,msbt,0be61h,07a86h,050h,024h,01998h - tstr <0,03fh>,0,0,0,0,0,0,053h,0,0 ; (1024 cycles) - tstr 0,0ffh,0,0,0,-1,-1,0,-1,0 ; (48 cycles) - .db 07bh,055h,0e6h,0c8h ; expected crc - tmsg 'bit n,' - -; cpd (1) (6144 cycles) -cpd1: .db 0d7h ; flag mask - tstr <0edh,0a9h>,0c7b6h,072b4h,018f6h,msbt+17,08dbdh,1,0c0h,030h,094a3h - tstr <0,010h>,0,0,0,0,0,010,0,-1,0 ; (1024 cycles) - tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) - .db 0a8h,07eh,06ch,0fah ; expected crc - tmsg 'cpd' - -; cpi (1) (6144 cycles) -cpi1: .db 0d7h ; flag mask - tstr <0edh,0a1h>,04d48h,0af4ah,0906bh,msbt,04e71h,1,093h,06ah,0907ch - tstr <0,010h>,0,0,0,0,0,010,0,-1,0 ; (1024 cycles) - tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) - .db 006h,0deh,0b3h,056h ; expected crc - tmsg 'cpi' - -; -daa: .db 0d7h ; flag mask - tstr 027h,02141h,009fah,01d60h,0a559h,08d5bh,09079h,004h,08eh,0299dh - tstr 018h,0,0,0,0,0,0,0d7h,-1,0 ; (65,536 cycles) - tstr 0,0,0,0,0,0,0,0,0,0 ; (1 cycle) - .db 09bh,04bh,0a6h,075h ; expected crc - tmsg '' - -; a (3072 cycles) -inca: .db 0d7h ; flag mask - tstr 03ch,04adfh,0d5d8h,0e598h,08a2bh,0a7b0h,0431bh,044h,05ah,0d030h - tstr 001h,0,0,0,0,0,0,0,-1,0 ; (512 cycles) - tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) - .db 0d1h,088h,015h,0a4h ; expected crc - tmsg ' a' - -; b (3072 cycles) -incb: .db 0d7h ; flag mask - tstr 004h,0d623h,0432dh,07a61h,08180h,05a86h,01e85h,086h,058h,09bbbh - tstr 001h,0,0,0,0,0,0ff00h,0,0,0 ; (512 cycles) - tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) - .db 05fh,068h,022h,064h ; expected crc - tmsg ' b' - -; bc (1536 cycles) -incbc: .db 0d7h ; flag mask - tstr 003h,0cd97h,044abh,08dc9h,0e3e3h,011cch,0e8a4h,002h,049h,02a4dh - tstr 008h,0,0,0,0,0,0f821h,0,0,0 ; (256 cycles) - tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) - .db 0d2h,0aeh,03bh,0ech ; expected crc - tmsg ' bc' - -; c (3072 cycles) -incc: .db 0d7h ; flag mask - tstr 00ch,0d789h,00935h,0055bh,09f85h,08b27h,0d208h,095h,005h,00660h - tstr 001h,0,0,0,0,0,0ffh,0,0,0 ; (512 cycles) - tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) - .db 0c2h,084h,055h,04ch ; expected crc - tmsg ' c' - -; d (3072 cycles) -incd: .db 0d7h ; flag mask - tstr 014h,0a0eah,05fbah,065fbh,0981ch,038cch,0debch,043h,05ch,003bdh - tstr 001h,0,0,0,0,0ff00h,0,0,0,0 ; (512 cycles) - tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) - .db 045h,023h,0deh,010h ; expected crc - tmsg ' d' - -; de (1536 cycles) -incde: .db 0d7h ; flag mask - tstr 013h,0342eh,0131dh,028c9h,00acah,09967h,03a2eh,092h,0f6h,09d54h - tstr 008h,0,0,0,0,0f821h,0,0,0,0 ; (256 cycles) - tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) - .db 0aeh,0c6h,0d4h,02ch ; expected crc - tmsg ' de' - -; e (3072 cycles) -ince: .db 0d7h ; flag mask - tstr 01ch,0602fh,04c0dh,02402h,0e2f5h,0a0f4h,0a10ah,013h,032h,05925h - tstr 001h,0,0,0,0,0ffh,0,0,0,0 ; (512 cycles) - tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) - .db 0e1h,075h,0afh,0cch ; expected crc - tmsg ' e' - -; h (3072 cycles) -inch: .db 0d7h ; flag mask - tstr 024h,01506h,0f2ebh,0e8ddh,0262bh,011a6h,0bc1ah,017h,006h,02818h - tstr 001h,0,0,0,0ff00h,0,0,0,0,0 ; (512 cycles) - tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) - .db 01ch,0edh,084h,07dh ; expected crc - tmsg ' h' - -; hl (1536 cycles) -inchl: .db 0d7h ; flag mask - tstr 023h,0c3f4h,007a5h,01b6dh,04f04h,0e2c2h,0822ah,057h,0e0h,0c3e1h - tstr 008h,0,0,0,0f821h,0,0,0,0,0 ; (256 cycles) - tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) - .db 0fch,00dh,06dh,04ah ; expected crc - tmsg ' hl' - -; ix (1536 cycles) -incix: .db 0d7h ; flag mask - tstr <0ddh,023h>,0bc3ch,00d9bh,0e081h,0adfdh,09a7fh,096e5h,013h,085h,00be2h - tstr <0,8>,0,0,0f821h,0,0,0,0,0,0 ; (256 cycles) - tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) - .db 0a5h,04dh,0beh,031h ; expected crc - tmsg ' ix' - -; iy (1536 cycles) -inciy: .db 0d7h ; flag mask - tstr <0fdh,023h>,09402h,0637ah,03182h,0c65ah,0b2e9h,0abb4h,016h,0f2h,06d05h - tstr <0,8>,0,0f821h,0,0,0,0,0,0,0 ; (256 cycles) - tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) - .db 050h,05dh,051h,0a3h ; expected crc - tmsg ' iy' - -; l (3072 cycles) -incl: .db 0d7h ; flag mask - tstr 02ch,08031h,0a520h,04356h,0b409h,0f4c1h,0dfa2h,0d1h,03ch,03ea2h - tstr 001h,0,0,0,0ffh,0,0,0,0,0 ; (512 cycles) - tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) - .db 056h,0cdh,006h,0f3h ; expected crc - tmsg ' l' - -; (hl) (3072 cycles) -incm: .db 0d7h ; flag mask - tstr 034h,0b856h,00c7ch,0e53eh,msbt,0877eh,0da58h,015h,05ch,01f37h - tstr 001h,0ffh,0,0,0,0,0,0,0,0 ; (512 cycles) - tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) - .db 0b8h,03ah,0dch,0efh ; expected crc - tmsg ' (hl)' - -; sp (1536 cycles) -incsp: .db 0d7h ; flag mask - tstr 033h,0346fh,0d482h,0d169h,0deb6h,0a494h,0f476h,053h,002h,0855bh - tstr 008h,0,0,0,0,0,0,0,0,0f821h ; (256 cycles) - tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) - .db 05dh,0ach,0d5h,027h ; expected crc - tmsg ' sp' - -; (+1) (6144 cycles) -incx: .db 0d7h ; flag mask - tstr <0ddh,034h,1>,0fa6eh,msbt-1,msbt-1,02c28h,08894h,05057h,016h,033h,0286fh - tstr <020h,1>,0ffh,0,0,0,0,0,0,0,0 ; (1024 cycles) - tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) - .db 020h,058h,014h,070h ; expected crc - tmsg ' (+1)' - -; ixh (3072 cycles) -incxh: .db 0d7h ; flag mask - tstr <0ddh,024h>,0b838h,0316ch,0c6d4h,03e01h,08358h,015b4h,081h,0deh,04259h - tstr <0,1>,0,0ff00h,0,0,0,0,0,0,0 ; (512 cycles) - tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) - .db 06fh,046h,036h,062h ; expected crc - tmsg ' ixh' - -; ixl (3072 cycles) -incxl: .db 0d7h ; flag mask - tstr <0ddh,02ch>,04d14h,07460h,076d4h,006e7h,032a2h,0213ch,0d6h,0d7h,099a5h - tstr <0,1>,0,0ffh,0,0,0,0,0,0,0 ; (512 cycles) - tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) - .db 002h,07bh,0efh,02ch ; expected crc - tmsg ' ixl' - -; iyh (3072 cycles) -incyh: .db 0d7h ; flag mask - tstr <0ddh,024h>,02836h,09f6fh,09116h,061b9h,082cbh,0e219h,092h,073h,0a98ch - tstr <0,1>,0ff00h,0,0,0,0,0,0,0,0 ; (512 cycles) - tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) - .db 02dh,096h,06ch,0f3h ; expected crc - tmsg ' iyh' - -; iyl (3072 cycles) -incyl: .db 0d7h ; flag mask - tstr <0ddh,02ch>,0d7c6h,062d5h,0a09eh,07039h,03e7eh,09f12h,090h,0d9h,0220fh - tstr <0,1>,0ffh,0,0,0,0,0,0,0,0 ; (512 cycles) - tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) - .db 0fbh,0cbh,0bah,095h ; expected crc - tmsg ' iyl' - -; ld ,(nnnn) (32 cycles) -ld161: .db 0d7h ; flag mask - tstr <0edh,04bh,low msbt,high msbt>,0f9a8h,0f559h,093a4h,0f5edh,06f96h,0d968h,086h,0e6h,04bd8h - tstr <0,010h>,0,0,0,0,0,0,0,0,0 ; (2 cycles) - tstr 0,-1,0,0,0,0,0,0,0,0 ; (16 cycles) - .db 04dh,045h,0a9h,0ach ; expected crc - tmsg 'ld ,(nnnn)' - -; ld hl,(nnnn) (16 cycles) -ld162: .db 0d7h ; flag mask - tstr <02ah,low msbt,high msbt>,09863h,07830h,02077h,0b1feh,0b9fah,0abb8h,004h,006h,06015h - tstr 0,0,0,0,0,0,0,0,0,0 ; (1 cycle) - tstr 0,-1,0,0,0,0,0,0,0,0 ; (16 cycles) - .db 05fh,097h,024h,087h ; expected crc - tmsg 'ld hl,(nnnn)' - -; ld sp,(nnnn) (16 cycles) -ld163: .db 0d7h ; flag mask - tstr <0edh,07bh,low msbt,high msbt>,08dfch,057d7h,02161h,0ca18h,0c185h,027dah,083h,01eh,0f460h - tstr 0,0,0,0,0,0,0,0,0,0 ; (1 cycles) - tstr 0,-1,0,0,0,0,0,0,0,0 ; (16 cycles) - .db 07ah,0ceh,0a1h,01bh ; expected crc - tmsg 'ld sp,(nnnn)' - -; ld ,(nnnn) (32 cycles) -ld164: .db 0d7h ; flag mask - tstr <0ddh,02ah,low msbt,high msbt>,0ded7h,0a6fah,0f780h,0244ch,087deh,0bcc2h,016h,063h,04c96h - tstr 020h,0,0,0,0,0,0,0,0,0 ; (2 cycles) - tstr 0,-1,0,0,0,0,0,0,0,0 ; (16 cycles) - .db 085h,08bh,0f1h,06dh ; expected crc - tmsg 'ld ,(nnnn)' - -; ld (nnnn), (64 cycles) -ld165: .db 0d7h ; flag mask - tstr <0edh,043h,low msbt,high msbt>,01f98h,0844dh,0e8ach,0c9edh,0c95dh,08f61h,080h,03fh,0c7bfh - tstr <0,010h>,0,0,0,0,0,0,0,0,0 ; (2 cycles) - tstr 0,0,0,0,0,-1,-1,0,0,0 ; (32 cycles) - .db 064h,01eh,087h,015h ; expected crc - tmsg 'ld (nnnn),' - -; ld (nnnn),hl (16 cycles) -ld166: .db 0d7h ; flag mask - tstr <022h,low msbt,high msbt>,0d003h,07772h,07f53h,03f72h,064eah,0e180h,010h,02dh,035e9h - tstr 0,0,0,0,0,0,0,0,0,0 ; (1 cycle) - tstr 0,0,0,0,-1,0,0,0,0,0 ; (16 cycles) - .db 0a3h,060h,08bh,047h ; expected crc - tmsg 'ld (nnnn),hl' - -; ld (nnnn),sp (16 cycles) -ld167: .db 0d7h ; flag mask - tstr <0edh,073h,low msbt,high msbt>,0c0dch,0d1d6h,0ed5ah,0f356h,0afdah,06ca7h,044h,09fh,03f0ah - tstr 0,0,0,0,0,0,0,0,0,0 ; (1 cycle) - tstr 0,0,0,0,0,0,0,0,0,-1 ; (16 cycles) - .db 016h,058h,05fh,0d7h ; expected crc - tmsg 'ld (nnnn),sp' - -; ld (nnnn), (64 cycles) -ld168: .db 0d7h ; flag mask - tstr <0ddh,022h,low msbt,high msbt>,06cc3h,00d91h,06900h,08ef8h,0e3d6h,0c3f7h,0c6h,0d9h,0c2dfh - tstr 020h,0,0,0,0,0,0,0,0,0 ; (2 cycles) - tstr 0,0,-1,-1,0,0,0,0,0,0 ; (32 cycles) - .db 0bah,010h,02ah,06bh ; expected crc - tmsg 'ld (nnnn),' - -; ld ,nnnn (64 cycles) -ld16im: .db 0d7h ; flag mask - tstr 1,05c1ch,02d46h,08eb9h,06078h,074b1h,0b30eh,046h,0d1h,030cch - tstr 030h,0,0,0,0,0,0,0,0,0 ; (4 cycles) - tstr <0,0ffh,0ffh>,0,0,0,0,0,0,0,0,0 ; (16 cycles) - .db 0deh,039h,019h,069h ; expected crc - tmsg 'ld ,nnnn' - -; ld ,nnnn (32 cycles) -ld16ix: .db 0d7h ; flag mask - tstr <0ddh,021h>,087e8h,02006h,0bd12h,0b69bh,07253h,0a1e5h,051h,013h,0f1bdh - tstr 020h,0,0,0,0,0,0,0,0,0 ; (2 cycles) - tstr <0,0,0ffh,0ffh>,0,0,0,0,0,0,0,0,0 ; (16 cycles) - .db 022h,07dh,0d5h,025h ; expected crc - tmsg 'ld ,nnnn' - -; ld a,<(bc),(de)> (44 cycles) -ld8bd: .db 0d7h ; flag mask - tstr 00ah,0b3a8h,01d2ah,07f8eh,042ach,msbt,msbt,0c6h,0b1h,0ef8eh - tstr 010h,0,0,0,0,0,0,0,0,0 ; (2 cycles) - tstr 0,0ffh,0,0,0,0,0,0d7h,-1,0 ; (22 cycles) - .db 0b0h,081h,089h,035h ; expected crc - tmsg 'ld a,<(bc),(de)>' - -; ld ,nn (64 cycles) -ld8im: .db 0d7h ; flag mask - tstr 6,0c407h,0f49dh,0d13dh,00339h,0de89h,07455h,053h,0c0h,05509h - tstr 038h,0,0,0,0,0,0,0,0,0 ; (8 cycles) - tstr 0,0,0,0,0,0,0,0,-1,0 ; (8 cycles) - .db 0f1h,0dah,0b5h,056h ; expected crc - tmsg 'ld ,nn' - -; ld (+1),nn (32 cycles) -ld8imx: .db 0d7h ; flag mask - tstr <0ddh,036h,1>,01b45h,msbt-1,msbt-1,0d5c1h,061c7h,0bdc4h,0c0h,085h,0cd16h - tstr 020h,0,0,0,0,0,0,0,0,0 ; (2 cycles) - tstr <0,0,0,-1>,0,0,0,0,0,0,0,-1,0 ; (16 cycles) - .db 026h,0dbh,047h,07eh ; expected crc - tmsg 'ld (+1),nn' - -; ld ,(+1) (512 cycles) -ld8ix1: .db 0d7h ; flag mask - tstr <0ddh,046h,1>,0d016h,msbt-1,msbt-1,04260h,07f39h,00404h,097h,04ah,0d085h - tstr <020h,018h>,0,1,1,0,0,0,0,0,0 ; (32 cycles) - tstr 0,-1,0,0,0,0,0,0,0,0 ; (16 cycles) - .db 0cch,011h,006h,0a8h ; expected crc - tmsg 'ld ,(+1)' - -; ld ,(+1) (256 cycles) -ld8ix2: .db 0d7h ; flag mask - tstr <0ddh,066h,1>,084e0h,msbt-1,msbt-1,09c52h,0a799h,049b6h,093h,000h,0eeadh - tstr <020h,008h>,0,1,1,0,0,0,0,0,0 ; (16 cycles) - tstr 0,-1,0,0,0,0,0,0,0,0 ; (16 cycles) - .db 0fah,02ah,04dh,003h ; expected crc - tmsg 'ld ,(+1)' - -; ld a,(+1) (128 cycles) -ld8ix3: .db 0d7h ; flag mask - tstr <0ddh,07eh,1>,0d8b6h,msbt-1,msbt-1,0c612h,0df07h,09cd0h,043h,0a6h,0a0e5h - tstr 020h,0,1,1,0,0,0,0,0,0 ; (8 cycles) - tstr 0,-1,0,0,0,0,0,0,0,0 ; (16 cycles) - .db 0a5h,0e9h,0ach,064h ; expected crc - tmsg 'ld a,(+1)' - -; ld ,nn (32 cycles) -ld8ixy: .db 0d7h ; flag mask - tstr <0ddh,026h>,03c53h,04640h,0e179h,07711h,0c107h,01afah,081h,0adh,05d9bh - tstr <020h,8>,0,0,0,0,0,0,0,0,0 ; (4 cycles) - tstr 0,0,0,0,0,0,0,0,-1,0 ; (8 cycles) - .db 024h,0e8h,082h,08bh ; expected crc - tmsg 'ld ,nn' - -; ld , (3456 cycles) -ld8rr: .db 0d7h ; flag mask - tstr 040h,072a4h,0a024h,061ach,msbt,082c7h,0718fh,097h,08fh,0ef8eh - tstr 03fh,0,0,0,0,0,0,0,0,0 ; (64 cycles) - tstr 0,0ffh,0,0,0,-1,-1,0d7h,-1,0 ; (54 cycles) - .db 074h,04bh,001h,018h ; expected crc - tmsg 'ld ,' - -; ld , (6912 cycles) -ld8rrx: .db 0d7h ; flag mask - tstr <0ddh,040h>,0bcc5h,msbt,msbt,msbt,02fc2h,098c0h,083h,01fh,03bcdh - tstr <020h,03fh>,0,0,0,0,0,0,0,0,0 ; (128 cycles) - tstr 0,0ffh,0,0,0,-1,-1,0d7h,-1,0 ; (54 cycles) - .db 047h,08bh,0a3h,06bh ; expected crc - tmsg 'ld ,' - -; ld a,(nnnn) / ld (nnnn),a (44 cycles) -lda: .db 0d7h ; flag mask - tstr <032h,low msbt,high msbt>,0fd68h,0f4ech,044a0h,0b543h,00653h,0cdbah,0d2h,04fh,01fd8h - tstr 008h,0,0,0,0,0,0,0,0,0 ; (2 cycle) - tstr 0,0ffh,0,0,0,0,0,0d7h,-1,0 ; (22 cycles) - .db 0c9h,026h,02dh,0e5h ; expected crc - tmsg 'ld a,(nnnn) / ld (nnnn),a' - -; ldd (1) (44 cycles) -ldd1: .db 0d7h ; flag mask - tstr <0edh,0a8h>,09852h,068fah,066a1h,msbt+3,msbt+1,1,0c1h,068h,020b7h - tstr <0,010h>,0,0,0,0,0,0,0,0,0 ; (2 cycles) - tstr 0,-1,0,0,0,0,0,0d7h,0,0 ; (22 cycles) - .db 094h,0f4h,027h,069h ; expected crc - tmsg 'ldd (1)' - -; ldd (2) (44 cycles) -ldd2: .db 0d7h ; flag mask - tstr <0edh,0a8h>,0f12eh,0eb2ah,0d5bah,msbt+3,msbt+1,2,047h,0ffh,0fbe4h - tstr <0,010h>,0,0,0,0,0,0,0,0,0 ; (2 cycles) - tstr 0,-1,0,0,0,0,0,0d7h,0,0 ; (22 cycles) - .db 05ah,090h,07eh,0d4h ; expected crc - tmsg 'ldd (2)' - -; ldi (1) (44 cycles) -ldi1: .db 0d7h ; flag mask - tstr <0edh,0a0h>,0fe30h,003cdh,06058h,msbt+2,msbt,1,004h,060h,02688h - tstr <0,010h>,0,0,0,0,0,0,0,0,0 ; (2 cycles) - tstr 0,-1,0,0,0,0,0,0d7h,0,0 ; (22 cycles) - .db 09ah,0bdh,0f6h,0b5h ; expected crc - tmsg 'ldi (1)' - -; ldi (2) (44 cycles) -ldi2: .db 0d7h ; flag mask - tstr <0edh,0a0h>,04aceh,0c26eh,0b188h,msbt+2,msbt,2,014h,02dh,0a39fh - tstr <0,010h>,0,0,0,0,0,0,0,0,0 ; (2 cycles) - tstr 0,-1,0,0,0,0,0,0d7h,0,0 ; (22 cycles) - .db 0ebh,059h,089h,01bh ; expected crc - tmsg 'ldi (2)' - -; neg (16,384 cycles) -neg: .db 0d7h ; flag mask - tstr <0edh,044h>,038a2h,05f6bh,0d934h,057e4h,0d2d6h,04642h,043h,05ah,009cch - tstr 0,0,0,0,0,0,0,0d7h,-1,0 ; (16,384 cycles) - tstr 0,0,0,0,0,0,0,0,0,0 ; (1 cycle) - .db 06ah,03ch,03bh,0bdh ; expected crc - tmsg 'neg' - -; (7168 cycles) -rld: .db 0d7h ; flag mask - tstr <0edh,067h>,091cbh,0c48bh,0fa62h,msbt,0e720h,0b479h,040h,006h,08ae2h - tstr <0,8>,0ffh,0,0,0,0,0,0,0,0 ; (512 cycles) - tstr 0,0,0,0,0,0,0,0d7h,-1,0 ; (14 cycles) - .db 095h,05bh,0a3h,026h ; expected crc - tmsg '' - -; (6144 cycles) -rot8080: .db 0d7h ; flag mask - tstr 7,0cb92h,06d43h,00a90h,0c284h,00c53h,0f50eh,091h,0ebh,040fch - tstr 018h,0,0,0,0,0,0,0,-1,0 ; (1024 cycles) - tstr 0,0,0,0,0,0,0,0d7h,0,0 ; (6 cycles) - .db 025h,013h,030h,0aeh ; expected crc - tmsg '' - -; shift/rotate (+1) (416 cycles) -rotxy: .db 0d7h ; flag mask - tstr <0ddh,0cbh,1,6>,0ddafh,msbt-1,msbt-1,0ff3ch,0dbf6h,094f4h,082h,080h,061d9h - tstr <020h,0,0,038h>,0,0,0,0,0,0,080h,0,0 ; (32 cycles) - tstr 0,0ffh,0,0,0,0,0,057h,0,0 ; (13 cycles) - .db 071h,03ah,0cdh,081h ; expected crc - tmsg 'shf/rot (+1)' - -; shift/rotate (6784 cycles) -rotz80: .db 0d7h ; flag mask - tstr 0cbh,0ccebh,05d4ah,0e007h,msbt,01395h,030eeh,043h,078h,03dadh - tstr <0,03fh>,0,0,0,0,0,0,080h,0,0 ; (128 cycles) - tstr 0,0ffh,0,0,0,-1,-1,057h,-1,0 ; (53 cycles) - .db 0ebh,060h,04dh,058h ; expected crc - tmsg 'shf/rot ' - -; n, (7936 cycles) -srz80: .db 0d7h ; flag mask - tstr <0cbh,080h>,02cd5h,097abh,039ffh,msbt,0d14bh,06ab2h,053h,027h,0b538h - tstr <0,07fh>,0,0,0,0,0,0,0,0,0 ; (128 cycles) - tstr 0,0ffh,0,0,0,-1,-1,0d7h,-1,0 ; (62 cycles) - .db 08bh,057h,0f0h,008h ; expected crc - tmsg ' n,' - -; n,(+1) (1792 cycles) -srzx: .db 0d7h ; flag mask - tstr <0ddh,0cbh,1,086h>,0fb44h,msbt-1,msbt-1,0ba09h,068beh,032d8h,010h,05eh,0a867h - tstr <020h,0,0,078h>,0,0,0,0,0,0,0,0,0 ; (128 cycles) - tstr 0,0ffh,0,0,0,0,0,0d7h,0,0 ;(14 cycles) - .db 0cch,063h,0f9h,08ah ; expected crc - tmsg ' n,(+1)' - -; ld (+1), (1024 cycles) -st8ix1: .db 0d7h ; flag mask - tstr <0ddh,070h,1>,0270dh,msbt-1,msbt-1,0b73ah,0887bh,099eeh,086h,070h,0ca07h - tstr <020h,003h>,0,1,1,0,0,0,0,0,0 ; (32 cycles) - tstr 0,0,0,0,0,-1,-1,0,0,0 ; (32 cycles) - .db 004h,062h,06ah,0bfh ; expected crc - tmsg 'ld (+1),' - -; ld (+1), (256 cycles) -st8ix2: .db 0d7h ; flag mask - tstr <0ddh,074h,1>,0b664h,msbt-1,msbt-1,0e8ach,0b5f5h,0aafeh,012h,010h,09566h - tstr <020h,001h>,0,1,1,0,0,0,0,0,0 ; (16 cycles) - tstr 0,0,0,0,-1,0,0,0,0,0 ; (32 cycles) - .db 06ah,01ah,088h,031h ; expected crc - tmsg 'ld (+1),' - -; ld (+1),a (64 cycles) -st8ix3: .db 0d7h ; flag mask - tstr <0ddh,077h,1>,067afh,msbt-1,msbt-1,04f13h,00644h,0bcd7h,050h,0ach,05fafh - tstr 020h,0,1,1,0,0,0,0,0,0 ; (8 cycles) - tstr 0,0,0,0,0,0,0,0,-1,0 ; (8 cycles) - .db 0cch,0beh,05ah,096h ; expected crc - tmsg 'ld (+1),a' - -; ld (),a (96 cycles) -stabd: .db 0d7h ; flag mask - tstr 2,00c3bh,0b592h,06cffh,0959eh,msbt,msbt+1,0c1h,021h,0bde7h - tstr 018h,0,0,0,0,0,0,0,0,0 ; (4 cycles) - tstr 0,-1,0,0,0,0,0,0,-1,0 ; (24 cycles) - .db 07ah,04ch,011h,04fh ; expected crc - tmsg 'ld (),a' - -; start test pointed to by (hl) -stt: push hl - ld a,(hl) ; get pointer to test - inc hl - ld h,(hl) - ld l,a - ld a,(hl) ; flag mask - ld (flgmsk+1),a - inc hl - push hl - ld de,20 - add hl,de ; point to incmask - ld de,counter - call initmask - pop hl - push hl - ld de,20+20 - add hl,de ; point to scanmask - ld de,shifter - call initmask - ld hl,shifter - ld (hl),1 ; first bit - pop hl - push hl - ld de,iut ; copy initial instruction under test - ld bc,4 - ldir - ld de,msbt ; copy initial machine state - ld bc,16 - ldir - ld de,20+20+4 ; skip incmask, scanmask and expcrc - add hl,de - ex de,hl - call writestr ; show test name - call initcrc ; initialise crc -; test loop -tlp: ld a,(iut) - cp 076h ; pragmatically avoid halt intructions - jp z,tlp2 - and 0dfh - cp 0ddh - jp nz,tlp1 - ld a,(iut+1) - cp 076h -tlp1: call nz,test ; execute the test instruction -tlp2: call count ; increment the counter - call nz,shift ; shift the scan bit - pop hl ; pointer to test case - jp z,tlp3 ; done if shift returned NZ - ld de,20+20+20 - add hl,de ; point to expected crc - call cmpcrc - ld de,okmsg - jp z,tlpok - ld de,ermsg1 - call writestr - call phex8 - ld de,ermsg2 - call writestr - ld hl,crcval - call phex8 - ld de,crlf -tlpok: call writestr - pop hl - inc hl - inc hl - ret - -tlp3: push hl - ld a,1 ; initialise count and shift scanners - ld (cntbit),a - ld (shfbit),a - ld hl,counter - ld (cntbyt),hl - ld hl,shifter - ld (shfbyt),hl - - ld b,4 ; bytes in iut field - pop hl ; pointer to test case - push hl - ld de,iut - call setup ; setup iut - ld b,16 ; bytes in machine state - ld de,msbt - call setup ; setup machine state - jp tlp - -; setup a field of the test case -; b = number of bytes -; hl = pointer to base case -; de = destination -setup: call subyte - inc hl - dec b - jp nz,setup - ret - -subyte: push bc - push de - push hl - ld c,(hl) ; get base byte - ld de,20 - add hl,de ; point to incmask - ld a,(hl) - cp 0 - jp z,subshf - ld b,8 ; 8 bits -subclp: rrca - push af - ld a,0 - call c,nxtcbit ; get next counter bit if mask bit was set - xor c ; flip bit if counter bit was set - rrca - ld c,a - pop af - dec b - jp nz,subclp - ld b,8 -subshf: ld de,20 - add hl,de ; point to shift mask - ld a,(hl) - cp 0 - jp z,substr - ld b,8 ; 8 bits -sbshf1: rrca - push af - ld a,0 - call c,nxtsbit ; get next shifter bit if mask bit was set - xor c ; flip bit if shifter bit was set - rrca - ld c,a - pop af - dec b - jp nz,sbshf1 -substr: pop hl - pop de - ld a,c - ld (de),a ; mangled byte to destination - inc de - pop bc - ret - -; get next counter bit in low bit of a -cntbit: .fill 1 -cntbyt: .fill 2 - -nxtcbit: push bc - push hl - ld hl,(cntbyt) - ld b,(hl) - ld hl,cntbit - ld a,(hl) - ld c,a - rlca - ld (hl),a - cp 1 - jp nz,ncb1 - ld hl,(cntbyt) - inc hl - ld (cntbyt),hl -ncb1: ld a,b - and c - pop hl - pop bc - ret z - ld a,1 - ret - -; get next shifter bit in low bit of a -shfbit: .fill 1 -shfbyt: .fill 2 - -nxtsbit: push bc - push hl - ld hl,(shfbyt) - ld b,(hl) - ld hl,shfbit - ld a,(hl) - ld c,a - rlca - ld (hl),a - cp 1 - jp nz,nsb1 - ld hl,(shfbyt) - inc hl - ld (shfbyt),hl -nsb1: ld a,b - and c - pop hl - pop bc - ret z - ld a,1 - ret - - -; clear memory at hl, bc bytes -clrmem: push af - push bc - push de - push hl - ld (hl),0 - ld d,h - ld e,l - inc de - dec bc - ldir - pop hl - pop de - pop bc - pop af - ret - -; initialise counter or shifter -; de = pointer to work area for counter or shifter -; hl = pointer to mask -initmask: - push de - ex de,hl - ld bc,20+20 - call clrmem ; clear work area - ex de,hl - ld b,20 ; byte counter - ld c,1 ; first bit - ld d,0 ; bit counter -imlp: ld e,(hl) -imlp1: ld a,e - and c - jp z,imlp2 - inc d -imlp2: ld a,c - rlca - ld c,a - cp 1 - jp nz,imlp1 - inc hl - dec b - jp nz,imlp -; got number of 1-bits in mask in reg d - ld a,d - and 0f8h - rrca - rrca - rrca ; divide by 8 (get byte offset) - ld l,a - ld h,0 - ld a,d - and 7 ; bit offset - inc a - ld b,a - ld a,080h -imlp3: rlca - dec b - jp nz,imlp3 - pop de - add hl,de - ld de,20 - add hl,de - ld (hl),a - ret - -; multi-byte counter -count: push bc - push de - push hl - ld hl,counter ; 20 byte counter starts here - ld de,20 ; somewhere in here is the stop bit - ex de,hl - add hl,de - ex de,hl -cntlp: inc (hl) - ld a,(hl) - cp 0 - jp z,cntlp1 ; overflow to next byte - ld b,a - ld a,(de) - and b ; test for terminal value - jp z,cntend - ld (hl),0 ; reset to zero -cntend: pop bc - pop de - pop hl - ret - -cntlp1: inc hl - inc de - jp cntlp - - -; multi-byte shifter -shift: push bc - push de - push hl - ld hl,shifter ; 20 byte shift register starts here - ld de,20 ; somewhere in here is the stop bit - ex de,hl - add hl,de - ex de,hl -shflp: ld a,(hl) - or a - jp z,shflp1 - ld b,a - ld a,(de) - and b - jp nz,shlpe - ld a,b - rlca - cp 1 - jp nz,shflp2 - ld (hl),0 - inc hl - inc de -shflp2: ld (hl),a - xor a ; set Z -shlpe: pop hl - pop de - pop bc - ret -shflp1: inc hl - inc de - jp shflp - -counter: .fill 2*20 -shifter: .fill 2*20 - -; test harness -test: push af - push bc - push de - push hl -#if 0 - ld de,crlf - call writestr - ld hl,iut - ld b,4 - call hexstr - ld e,' ' - call writechar - ld b,16 - ld hl,msbt - call hexstr -#endif - di ; disable interrupts - ld (spsav),sp ; save stack pointer - ld sp,msbt+2 ; point to test-case machine state - pop iy ; and load all regs - pop ix - pop hl - pop de - pop bc - pop af - ld sp,(spbt) -iut: .fill 4 ; max 4 byte instruction under test - ld (spat),sp ; save stack pointer - ld sp,spat - push af ; save other registers - push bc - push de - push hl - push ix - push iy - ld sp,(spsav) ; restore stack pointer - ei ; enable interrupts - ld hl,(msbt) ; copy memory operand - ld (msat),hl - ld hl,flgsat ; flags after test - ld a,(hl) -flgmsk: and 0d7h ; mask-out irrelevant bits (self-modified code!) - ld (hl),a - ld b,16 ; total of 16 bytes of state - ld de,msat - ld hl,crcval -tcrc: ld a,(de) - inc de - call updcrc ; accumulate crc of this test case - dec b - jp nz,tcrc -#if 0 - ld e,' ' - call writechar - ld hl,crcval - call phex8 - ld de,crlf - call writestr - ld hl,msat - ld b,16 - call hexstr - ld de,crlf - call writestr -#endif - pop hl - pop de - pop bc - pop af - ret - -; machine state after test -msat: .fill 14 ; memop,iy,ix,hl,de,bc,af -spat: .fill 2 ; stack pointer after test -#define flgsat spat-2 ; flags - -spsav: .fill 2 ; saved stack pointer - -; display hex string (pointer in hl, byte count in b) -hexstr: ld a,(hl) - call phex2 - inc hl - dec b - jp nz,hexstr - ret - -; display hex -; display the big-endian 32-bit value pointed to by hl -phex8: push af - push bc - push hl - ld b,4 -ph8lp: ld a,(hl) - call phex2 - inc hl - dec b - jp nz,ph8lp - pop hl - pop bc - pop af - ret - -; display byte in a -phex2: push af - rrca - rrca - rrca - rrca - call phex1 - pop af -; fall through - -; display low nibble in a -phex1: push af - push bc - push de - push hl - and 0fh - cp 10 - jp c,ph11 - add a,'a'-'9'-1 -ph11: add a,'0' - ld e,a - call writechar - pop hl - pop de - pop bc - pop af - ret - - ;; Output routine. - ;; Print the character in A. -writechar: - out (000h),a - ret - - ;; Print the string in (DE), terminated by '$' (24h) -writestr: - push af - push bc - ld c,'$' -writestr_loop: - ld a,(de) - inc de - out (000h),a - cp c - jp nz,writestr_loop - pop bc - pop af - ret - -msg1: .db 'Z80 instruction exerciser',10,13,'$' -msg2: .db 'Tests complete$' -okmsg: .db ' OK',10,13,'$' -ermsg1: .db ' ERROR **** crc expected:$' -ermsg2: .db ' found:$' -crlf: .db 10,'$' - -; compare crc -; hl points to value to compare to crcval -cmpcrc: push bc - push de - push hl - ld de,crcval - ld b,4 -cclp: ld a,(de) - cp (hl) - jp nz,cce - inc hl - inc de - dec b - jp nz,cclp -cce: pop hl - pop de - pop bc - ret - -; 32-bit crc routine -; entry: a contains next byte, hl points to crc -; exit: crc updated -updcrc: push af - push bc - push de - push hl - push hl - ld de,3 - add hl,de ; point to low byte of old crc - xor (hl) ; xor with new byte - ld l,a - ld h,0 - add hl,hl ; use result as index into table of 4 byte entries - add hl,hl - ex de,hl - ld hl,crctab - add hl,de ; point to selected entry in crctab - ex de,hl - pop hl - ld bc,4 ; c = byte count, b = accumulator -crclp: ld a,(de) - xor b - ld b,(hl) - ld (hl),a - inc de - inc hl - dec c - jp nz,crclp -#if 0 - ld hl,crcval - call phex8 - ld de,crlf - ld c,9 - call bdos -#endif - pop hl - pop de - pop bc - pop af - ret - -initcrc: - push af - push bc - push hl - ld hl,crcval - ld a,0ffh - ld b,4 -icrclp: ld (hl),a - inc hl - dec b - jp nz,icrclp - pop hl - pop bc - pop af - ret - -crcval .fill 4 - -crctab: .db 000h,000h,000h,000h - .db 077h,007h,030h,096h - .db 0eeh,00eh,061h,02ch - .db 099h,009h,051h,0bah - .db 007h,06dh,0c4h,019h - .db 070h,06ah,0f4h,08fh - .db 0e9h,063h,0a5h,035h - .db 09eh,064h,095h,0a3h - .db 00eh,0dbh,088h,032h - .db 079h,0dch,0b8h,0a4h - .db 0e0h,0d5h,0e9h,01eh - .db 097h,0d2h,0d9h,088h - .db 009h,0b6h,04ch,02bh - .db 07eh,0b1h,07ch,0bdh - .db 0e7h,0b8h,02dh,007h - .db 090h,0bfh,01dh,091h - .db 01dh,0b7h,010h,064h - .db 06ah,0b0h,020h,0f2h - .db 0f3h,0b9h,071h,048h - .db 084h,0beh,041h,0deh - .db 01ah,0dah,0d4h,07dh - .db 06dh,0ddh,0e4h,0ebh - .db 0f4h,0d4h,0b5h,051h - .db 083h,0d3h,085h,0c7h - .db 013h,06ch,098h,056h - .db 064h,06bh,0a8h,0c0h - .db 0fdh,062h,0f9h,07ah - .db 08ah,065h,0c9h,0ech - .db 014h,001h,05ch,04fh - .db 063h,006h,06ch,0d9h - .db 0fah,00fh,03dh,063h - .db 08dh,008h,00dh,0f5h - .db 03bh,06eh,020h,0c8h - .db 04ch,069h,010h,05eh - .db 0d5h,060h,041h,0e4h - .db 0a2h,067h,071h,072h - .db 03ch,003h,0e4h,0d1h - .db 04bh,004h,0d4h,047h - .db 0d2h,00dh,085h,0fdh - .db 0a5h,00ah,0b5h,06bh - .db 035h,0b5h,0a8h,0fah - .db 042h,0b2h,098h,06ch - .db 0dbh,0bbh,0c9h,0d6h - .db 0ach,0bch,0f9h,040h - .db 032h,0d8h,06ch,0e3h - .db 045h,0dfh,05ch,075h - .db 0dch,0d6h,00dh,0cfh - .db 0abh,0d1h,03dh,059h - .db 026h,0d9h,030h,0ach - .db 051h,0deh,000h,03ah - .db 0c8h,0d7h,051h,080h - .db 0bfh,0d0h,061h,016h - .db 021h,0b4h,0f4h,0b5h - .db 056h,0b3h,0c4h,023h - .db 0cfh,0bah,095h,099h - .db 0b8h,0bdh,0a5h,00fh - .db 028h,002h,0b8h,09eh - .db 05fh,005h,088h,008h - .db 0c6h,00ch,0d9h,0b2h - .db 0b1h,00bh,0e9h,024h - .db 02fh,06fh,07ch,087h - .db 058h,068h,04ch,011h - .db 0c1h,061h,01dh,0abh - .db 0b6h,066h,02dh,03dh - .db 076h,0dch,041h,090h - .db 001h,0dbh,071h,006h - .db 098h,0d2h,020h,0bch - .db 0efh,0d5h,010h,02ah - .db 071h,0b1h,085h,089h - .db 006h,0b6h,0b5h,01fh - .db 09fh,0bfh,0e4h,0a5h - .db 0e8h,0b8h,0d4h,033h - .db 078h,007h,0c9h,0a2h - .db 00fh,000h,0f9h,034h - .db 096h,009h,0a8h,08eh - .db 0e1h,00eh,098h,018h - .db 07fh,06ah,00dh,0bbh - .db 008h,06dh,03dh,02dh - .db 091h,064h,06ch,097h - .db 0e6h,063h,05ch,001h - .db 06bh,06bh,051h,0f4h - .db 01ch,06ch,061h,062h - .db 085h,065h,030h,0d8h - .db 0f2h,062h,000h,04eh - .db 06ch,006h,095h,0edh - .db 01bh,001h,0a5h,07bh - .db 082h,008h,0f4h,0c1h - .db 0f5h,00fh,0c4h,057h - .db 065h,0b0h,0d9h,0c6h - .db 012h,0b7h,0e9h,050h - .db 08bh,0beh,0b8h,0eah - .db 0fch,0b9h,088h,07ch - .db 062h,0ddh,01dh,0dfh - .db 015h,0dah,02dh,049h - .db 08ch,0d3h,07ch,0f3h - .db 0fbh,0d4h,04ch,065h - .db 04dh,0b2h,061h,058h - .db 03ah,0b5h,051h,0ceh - .db 0a3h,0bch,000h,074h - .db 0d4h,0bbh,030h,0e2h - .db 04ah,0dfh,0a5h,041h - .db 03dh,0d8h,095h,0d7h - .db 0a4h,0d1h,0c4h,06dh - .db 0d3h,0d6h,0f4h,0fbh - .db 043h,069h,0e9h,06ah - .db 034h,06eh,0d9h,0fch - .db 0adh,067h,088h,046h - .db 0dah,060h,0b8h,0d0h - .db 044h,004h,02dh,073h - .db 033h,003h,01dh,0e5h - .db 0aah,00ah,04ch,05fh - .db 0ddh,00dh,07ch,0c9h - .db 050h,005h,071h,03ch - .db 027h,002h,041h,0aah - .db 0beh,00bh,010h,010h - .db 0c9h,00ch,020h,086h - .db 057h,068h,0b5h,025h - .db 020h,06fh,085h,0b3h - .db 0b9h,066h,0d4h,009h - .db 0ceh,061h,0e4h,09fh - .db 05eh,0deh,0f9h,00eh - .db 029h,0d9h,0c9h,098h - .db 0b0h,0d0h,098h,022h - .db 0c7h,0d7h,0a8h,0b4h - .db 059h,0b3h,03dh,017h - .db 02eh,0b4h,00dh,081h - .db 0b7h,0bdh,05ch,03bh - .db 0c0h,0bah,06ch,0adh - .db 0edh,0b8h,083h,020h - .db 09ah,0bfh,0b3h,0b6h - .db 003h,0b6h,0e2h,00ch - .db 074h,0b1h,0d2h,09ah - .db 0eah,0d5h,047h,039h - .db 09dh,0d2h,077h,0afh - .db 004h,0dbh,026h,015h - .db 073h,0dch,016h,083h - .db 0e3h,063h,00bh,012h - .db 094h,064h,03bh,084h - .db 00dh,06dh,06ah,03eh - .db 07ah,06ah,05ah,0a8h - .db 0e4h,00eh,0cfh,00bh - .db 093h,009h,0ffh,09dh - .db 00ah,000h,0aeh,027h - .db 07dh,007h,09eh,0b1h - .db 0f0h,00fh,093h,044h - .db 087h,008h,0a3h,0d2h - .db 01eh,001h,0f2h,068h - .db 069h,006h,0c2h,0feh - .db 0f7h,062h,057h,05dh - .db 080h,065h,067h,0cbh - .db 019h,06ch,036h,071h - .db 06eh,06bh,006h,0e7h - .db 0feh,0d4h,01bh,076h - .db 089h,0d3h,02bh,0e0h - .db 010h,0dah,07ah,05ah - .db 067h,0ddh,04ah,0cch - .db 0f9h,0b9h,0dfh,06fh - .db 08eh,0beh,0efh,0f9h - .db 017h,0b7h,0beh,043h - .db 060h,0b0h,08eh,0d5h - .db 0d6h,0d6h,0a3h,0e8h - .db 0a1h,0d1h,093h,07eh - .db 038h,0d8h,0c2h,0c4h - .db 04fh,0dfh,0f2h,052h - .db 0d1h,0bbh,067h,0f1h - .db 0a6h,0bch,057h,067h - .db 03fh,0b5h,006h,0ddh - .db 048h,0b2h,036h,04bh - .db 0d8h,00dh,02bh,0dah - .db 0afh,00ah,01bh,04ch - .db 036h,003h,04ah,0f6h - .db 041h,004h,07ah,060h - .db 0dfh,060h,0efh,0c3h - .db 0a8h,067h,0dfh,055h - .db 031h,06eh,08eh,0efh - .db 046h,069h,0beh,079h - .db 0cbh,061h,0b3h,08ch - .db 0bch,066h,083h,01ah - .db 025h,06fh,0d2h,0a0h - .db 052h,068h,0e2h,036h - .db 0cch,00ch,077h,095h - .db 0bbh,00bh,047h,003h - .db 022h,002h,016h,0b9h - .db 055h,005h,026h,02fh - .db 0c5h,0bah,03bh,0beh - .db 0b2h,0bdh,00bh,028h - .db 02bh,0b4h,05ah,092h - .db 05ch,0b3h,06ah,004h - .db 0c2h,0d7h,0ffh,0a7h - .db 0b5h,0d0h,0cfh,031h - .db 02ch,0d9h,09eh,08bh - .db 05bh,0deh,0aeh,01dh - .db 09bh,064h,0c2h,0b0h - .db 0ech,063h,0f2h,026h - .db 075h,06ah,0a3h,09ch - .db 002h,06dh,093h,00ah - .db 09ch,009h,006h,0a9h - .db 0ebh,00eh,036h,03fh - .db 072h,007h,067h,085h - .db 005h,000h,057h,013h - .db 095h,0bfh,04ah,082h - .db 0e2h,0b8h,07ah,014h - .db 07bh,0b1h,02bh,0aeh - .db 00ch,0b6h,01bh,038h - .db 092h,0d2h,08eh,09bh - .db 0e5h,0d5h,0beh,00dh - .db 07ch,0dch,0efh,0b7h - .db 00bh,0dbh,0dfh,021h - .db 086h,0d3h,0d2h,0d4h - .db 0f1h,0d4h,0e2h,042h - .db 068h,0ddh,0b3h,0f8h - .db 01fh,0dah,083h,06eh - .db 081h,0beh,016h,0cdh - .db 0f6h,0b9h,026h,05bh - .db 06fh,0b0h,077h,0e1h - .db 018h,0b7h,047h,077h - .db 088h,008h,05ah,0e6h - .db 0ffh,00fh,06ah,070h - .db 066h,006h,03bh,0cah - .db 011h,001h,00bh,05ch - .db 08fh,065h,09eh,0ffh - .db 0f8h,062h,0aeh,069h - .db 061h,06bh,0ffh,0d3h - .db 016h,06ch,0cfh,045h - .db 0a0h,00ah,0e2h,078h - .db 0d7h,00dh,0d2h,0eeh - .db 04eh,004h,083h,054h - .db 039h,003h,0b3h,0c2h - .db 0a7h,067h,026h,061h - .db 0d0h,060h,016h,0f7h - .db 049h,069h,047h,04dh - .db 03eh,06eh,077h,0dbh - .db 0aeh,0d1h,06ah,04ah - .db 0d9h,0d6h,05ah,0dch - .db 040h,0dfh,00bh,066h - .db 037h,0d8h,03bh,0f0h - .db 0a9h,0bch,0aeh,053h - .db 0deh,0bbh,09eh,0c5h - .db 047h,0b2h,0cfh,07fh - .db 030h,0b5h,0ffh,0e9h - .db 0bdh,0bdh,0f2h,01ch - .db 0cah,0bah,0c2h,08ah - .db 053h,0b3h,093h,030h - .db 024h,0b4h,0a3h,0a6h - .db 0bah,0d0h,036h,005h - .db 0cdh,0d7h,006h,093h - .db 054h,0deh,057h,029h - .db 023h,0d9h,067h,0bfh - .db 0b3h,066h,07ah,02eh - .db 0c4h,061h,04ah,0b8h - .db 05dh,068h,01bh,002h - .db 02ah,06fh,02bh,094h - .db 0b4h,00bh,0beh,037h - .db 0c3h,00ch,08eh,0a1h - .db 05ah,005h,0dfh,01bh - .db 02dh,002h,0efh,08dh - - - .end -- cgit v1.2.3