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

Subversion Repositories light8080

[/] [light8080/] [trunk/] [sw/] [demos/] [exer/] [8080EXER.MAC] - Rev 87

Compare with Previous | Blame | View Log

        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.
;
;******************************************************************************
;
; Modified to exercise an 8080 by Ian Bartholomew, February 2009
; 
; I have made the following changes -
;
; Converted all mnemonics to 8080 and rewritten any Z80 code used
; in the original exerciser.  Changes are tagged with a #idb in the
; source code listing.
;
; Removed any test descriptors that are not used.
;  
; Changed the macro definitions to work in M80
;
; The machine state snapshot has been changed to remove the IX/IY registers.
; They have been replaced by two more copies of HL to obviate the need
; for major changes in the exerciser code.
;
; Changed flag mask in all tests to 0ffh to reflect that the 8080, unlike the 8085
; and Z80, does define the unused bits in the flag register - [S Z 0 AC 0 P 1 C]
;
;******************************************************************************

MASK_RX_IRQ   equ 20h
MASK_TX_IRQ   equ 10h
MASK_RX_RDY   equ 02h
MASK_TX_RDY   equ 01h

UART_DATA     equ 80h
UART_STATUS   equ 81h
UART_BAUDL    equ 82h
UART_BAUDH    equ 83h
IRQ_ENABLE    equ 88h

P1IN          equ 84h
P2OUT         equ 86h



        .8080
        aseg
  
          org   0H              ; Reset entry point
          jmp   100h            ; Jump to program start
                        
          ;***** Interrupt vectors in area 0008h-0038h *****************
          org   5h              ; BDOS entry point
          jmp   bdos$entry
          
          org   0h+(1*8)        ; interrupt vector 1
          ei
          ret
          org   0h+(2*8)        ; interrupt vector 2
          ei
          ret
          org   0h+(3*8)        ; interrupt vector 3
          ei
          ret
          org   0h+(4*8)        ; interrupt vector 4
          ei
          ret
          org   0h+(5*8)        ; interrupt vector 5
          ei
          ret
          org   0h+(6*8)        ; interrupt vector 6
          ei
          ret
          org   0h+(7*8)        ; interrupt vector 7
        ei
        ret
  
  
  
        org     100h

begin:  jmp     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:  ;lhld   6
        lxi     h,8000 
        sphl
        lxi     d,msg1
        mvi     c,9
        call    bdos

        lxi     h,tests         ; first test case
loop:   mov     a,m             ; end of list ?
        inx     h
        ora     m
        jz      done
        dcx     h
        call    stt
        jmp     loop
        
done:   lxi     d,msg2
        mvi     c,9
        call    bdos
  di
  hlt
        jmp     0                ; warm boot

tests:
        dw      add16
        dw      alu8i
        dw      alu8r
        dw      daa
        dw      inca
        dw      incb
        dw      incbc
        dw      incc
        dw      incd
        dw      incde
        dw      ince
        dw      inch
        dw      inchl
        dw      incl
        dw      incm
        dw      incsp
        dw      ld162
        dw      ld166
        dw      ld16im
        dw      ld8bd
        dw      ld8im
        dw      ld8rr
        dw      lda
        dw      rot8080
        dw      stabd
        dw      0

tstr    macro   insn,memop,hliy,hlix,hl,de,bc,flags,acc,sp
        local   lab
lab:    db      insn
        ds      lab+4-$,0
        dw      memop,hliy,hlix,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

; add hl,<bc,de,hl,sp> (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        014h,047h,04bh,0a6h                                   ; expected crc
        tmsg    'dad <b,d,h,sp>'

; 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        09eh,092h,02fh,09eh                                   ; expected crc
        tmsg    'aluop nn'

; aluop a,<b,c,d,e,h,l,(hl),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        0cfh,076h,02ch,086h                                   ; expected crc
        tmsg    'aluop <b,c,d,e,h,l,m,a>'

; <daa,cpl,scf,ccf>
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        0bbh,03fh,003h,00ch                                   ; expected crc
        tmsg    '<daa,cma,stc,cmc>'

; <inc,dec> 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        0adh,0b6h,046h,00eh                                     ; expected crc
        tmsg    '<inr,dcr> a'

; <inc,dec> 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        083h,0edh,013h,045h                                   ; expected crc
        tmsg    '<inr,dcr> b'

; <inc,dec> 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        0f7h,092h,087h,0cdh                                   ; expected crc
        tmsg    '<inx,dcx> b'

; <inc,dec> 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        0e5h,0f6h,072h,01bh                                   ; expected crc
        tmsg    '<inr,dcr> c'

; <inc,dec> 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        015h,0b5h,057h,09ah                                   ; expected crc
        tmsg    '<inr,dcr> d'

; <inc,dec> 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        07fh,04eh,025h,001h                                   ; expected crc
        tmsg    '<inx,dcx> d'

; <inc,dec> 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        0cfh,02ah,0b3h,096h                                   ; expected crc
        tmsg    '<inr,dcr> e'

; <inc,dec> 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        012h,0b2h,095h,02ch                                   ; expected crc
        tmsg    '<inr,dcr> h'

; <inc,dec> 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        09fh,02bh,023h,0c0h                                   ; expected crc
        tmsg    '<inx,dcx> h'

; <inc,dec> 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        0ffh,057h,0d3h,056h                               ; expected crc
        tmsg    '<inr,dcr> l'

; <inc,dec> (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        092h,0e9h,063h,0bdh                                   ; expected crc
        tmsg    '<inr,dcr> m'

; <inc,dec> 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        0d5h,070h,02fh,0abh                                   ; expected crc
        tmsg    '<inx,dcx> sp'

; 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        0a9h,0c3h,0d5h,0cbh                                     ; expected crc
        tmsg    'lhld 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        0e8h,086h,04fh,026h                                     ; expected crc
        tmsg    'shld nnnn'

; ld <bc,de,hl,sp>,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        0fch,0f4h,06eh,012h                                   ; expected crc
        tmsg    'lxi <b,d,h,sp>,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        02bh,082h,01dh,05fh                                     ; expected crc
        tmsg    'ldax <b,d>'

; ld <b,c,d,e,h,l,(hl),a>,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        0eah,0a7h,020h,044h                                   ; expected crc
        tmsg    'mvi <b,c,d,e,h,l,m,a>,nn'

; ld <b,c,d,e,h,l,a>,<b,c,d,e,h,l,a> (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        010h,0b5h,08ch,0eeh                                   ; expected crc
        tmsg    'mov <bcdehla>,<bcdehla>'

; 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        0edh,057h,0afh,072h                                   ; expected crc
        tmsg    'sta nnnn / lda nnnn'

; <rlca,rrca,rla,rra> (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        0e0h,0d8h,092h,035h                                     ; expected crc
        tmsg    '<rlc,rrc,ral,rar>'

; ld (<bc,de>),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        02bh,004h,071h,0e9h                                   ; expected crc
        tmsg    'stax <b,d>'

; start test pointed to by (hl)
stt:    push    h
        mov     a,m             ; get pointer to test
        inx     h
        mov     h,m
        mov     l,a
        mov     a,m             ; flag mask
        sta     flgmsk+1
        inx     h
        push    h
        lxi     d,20
        dad     d               ; point to incmask
        lxi     d,counter
        call    initmask
        pop     h
        push    h
        lxi     d,20+20
        dad     d               ; point to scanmask
        lxi     d,shifter
        call    initmask
        lxi     h,shifter
        mvi     m,1             ; first bit
        pop     h
        push    h
        lxi     d,iut           ; copy initial instruction under test
        lxi     b,4

;#idb ldir replaced with following code
ldir1:  mov     a,m
        stax    d
        inx     h
        inx     d
        dcx     b
        mov     a,b
        ora     c
        jnz     ldir1
;#idb

        lxi     d,msbt          ; copy initial machine state
        lxi     b,16

;#idb ldir replaced with following code
ldir2:  mov     a,m
        stax    d
        inx     h
        inx     d
        dcx     b
        mov     a,b
        ora     c
        jnz     ldir2
;#idb

        lxi     d,20+20+4       ; skip incmask, scanmask and expcrc
        dad     d
        xchg
        mvi     c,9
        call    bdos            ; show test name
        call    initcrc         ; initialise crc
; test loop
tlp:    lda     iut
        cpi     076h            ; pragmatically avoid halt intructions
        jz      tlp2
        ani     0dfh
        cpi     0ddh
        jnz     tlp1
        lda     iut+1
        cpi     076h
tlp1:   cnz     test            ; execute the test instruction
tlp2:   call    count           ; increment the counter
        cnz     shift           ; shift the scan bit
        pop     h               ; pointer to test case
        jz      tlp3            ; done if shift returned NZ
        lxi     d,20+20+20
        dad     d               ; point to expected crc
        call    cmpcrc
        lxi     d,okmsg
        jz      tlpok
        lxi     d,ermsg1
        mvi     c,9
        call    bdos
        call    phex8
        lxi     d,ermsg2
        mvi     c,9
        call    bdos
        lxi     h,crcval
        call    phex8
        lxi     d,crlf
tlpok:  mvi     c,9
        call    bdos
        pop     h
        inx     h
        inx     h
        ret

tlp3:   push    h
        mvi     a,1             ; initialise count and shift scanners
        sta     cntbit
        sta     shfbit
        lxi     h,counter
        shld    cntbyt
        lxi     h,shifter
        shld    shfbyt

        mvi     b,4             ; bytes in iut field
        pop     h               ; pointer to test case
        push    h
        lxi     d,iut
        call    setup           ; setup iut
        mvi     b,16            ; bytes in machine state
        lxi     d,msbt
        call    setup           ; setup machine state
        jmp     tlp

; setup a field of the test case
; b  = number of bytes
; hl = pointer to base case
; de = destination
setup:  call    subyte
        inx     h
        dcr     b
        jnz     setup
        ret

subyte: push    b
        push    d
        push    h
        mov     c,m             ; get base byte
        lxi     d,20
        dad     d               ; point to incmask
        mov     a,m
        cpi     0
        jz      subshf
        mvi     b,8             ; 8 bits
subclp: rrc
        push    psw
        mvi     a,0
        cc      nxtcbit ; get next counter bit if mask bit was set
        xra     c               ; flip bit if counter bit was set
        rrc
        mov     c,a
        pop     psw
        dcr     b
        jnz     subclp
        mvi     b,8
subshf: lxi     d,20
        dad     d               ; point to shift mask
        mov     a,m
        cpi     0
        jz      substr
        mvi     b,8             ; 8 bits
sbshf1: rrc
        push    psw
        mvi     a,0
        cc      nxtsbit ; get next shifter bit if mask bit was set
        xra     c               ; flip bit if shifter bit was set
        rrc
        mov     c,a
        pop     psw
        dcr     b
        jnz     sbshf1
substr: pop     h
        pop     d
        mov     a,c
        stax    d               ; mangled byte to destination
        inx     d
        pop     b
        ret

; get next counter bit in low bit of a
cntbit: ds      1
cntbyt: ds      2

nxtcbit: push   b
        push    h
        lhld    cntbyt
        mov     b,m
        lxi     h,cntbit
        mov     a,m
        mov     c,a
        rlc
        mov     m,a
        cpi     1
        jnz     ncb1
        lhld    cntbyt
        inx     h
        shld    cntbyt
ncb1:   mov     a,b
        ana     c
        pop     h
        pop     b
        rz
        mvi     a,1
        ret
        
; get next shifter bit in low bit of a
shfbit: ds      1
shfbyt: ds      2

nxtsbit: push   b
        push    h
        lhld    shfbyt
        mov     b,m
        lxi     h,shfbit
        mov     a,m
        mov     c,a
        rlc
        mov     m,a
        cpi     1
        jnz     nsb1
        lhld    shfbyt
        inx     h
        shld    shfbyt
nsb1:   mov     a,b
        ana     c
        pop     h
        pop     b
        rz
        mvi     a,1
        ret
        

; clear memory at hl, bc bytes
clrmem: push    psw
        push    b
        push    d
        push    h
        mvi     m,0
        mov     d,h
        mov     e,l
        inx     d
        dcx     b

;#idb ldir replaced with following code
ldir3:  mov     a,m
        stax    d
        inx     h
        inx     d
        dcx     b
        mov     a,b
        ora     c
        jnz     ldir3
;#idb

        pop     h
        pop     d
        pop     b
        pop     psw
        ret

; initialise counter or shifter
; de = pointer to work area for counter or shifter
; hl = pointer to mask
initmask:
        push    d
        xchg
        lxi     b,20+20
        call    clrmem          ; clear work area
        xchg
        mvi     b,20            ; byte counter
        mvi     c,1             ; first bit
        mvi     d,0             ; bit counter
imlp:   mov     e,m
imlp1:  mov     a,e
        ana     c
        jz      imlp2
        inr     d
imlp2:  mov     a,c
        rlc
        mov     c,a
        cpi     1
        jnz     imlp1
        inx     h
        dcr     b
        jnz     imlp
; got number of 1-bits in mask in reg d
        mov     a,d
        ani     0f8h
        rrc
        rrc
        rrc                     ; divide by 8 (get byte offset)
        mov     l,a
        mvi     h,0
        mov     a,d
        ani     7               ; bit offset
        inr     a
        mov     b,a
        mvi     a,080h
imlp3:  rlc
        dcr     b
        jnz     imlp3
        pop     d
        dad     d
        lxi     d,20
        dad     d
        mov     m,a
        ret

; multi-byte counter
count:  push    b
        push    d
        push    h
        lxi     h,counter       ; 20 byte counter starts here
        lxi     d,20            ; somewhere in here is the stop bit
        xchg
        dad     d
        xchg
cntlp:  inr     m
        mov     a,m
        cpi     0
        jz      cntlp1  ; overflow to next byte
        mov     b,a
        ldax    d
        ana     b               ; test for terminal value
        jz      cntend
        mvi     m,0             ; reset to zero
cntend: pop     b
        pop     d
        pop     h
        ret

cntlp1: inx     h
        inx     d
        jmp     cntlp
        

; multi-byte shifter
shift:  push    b
        push    d
        push    h
        lxi     h,shifter       ; 20 byte shift register starts here
        lxi     d,20            ; somewhere in here is the stop bit
        xchg
        dad     d
        xchg
shflp:  mov     a,m
        ora     a
        jz      shflp1
        mov     b,a
        ldax    d
        ana     b
        jnz     shlpe
        mov     a,b
        rlc
        cpi     1
        jnz     shflp2
        mvi     m,0
        inx     h
        inx     d
shflp2: mov     m,a
        xra     a               ; set Z
shlpe:  pop     h
        pop     d
        pop     b
        ret
shflp1: inx     h
        inx     d
        jmp     shflp

counter: ds     2*20
shifter: ds     2*20

; test harness
test:   push    psw
        push    b
        push    d
        push    h
      if        0
        lxi     d,crlf
        mvi     c,9
        call    bdos
        lxi     h,iut
        mvi     b,4
        call    hexstr
        mvi     e,' '
        mvi     c,2
        call    bdos
        mvi     b,16
        lxi     h,msbt
        call    hexstr
      endif     
        di                      ; disable interrupts

;#idb ld (spsav),sp replaced by following code
;#idb All registers and flages are immediately overwritten so
;#idb no need to preserve any state.
        lxi     h,0             ; save stack pointer
        dad     sp
        shld    spsav
;#idb

        lxi     sp,msbt+2       ; point to test-case machine state

;#idb pop iy    
;#idb pop ix both replaced by following code
;#idb Just dummy out ix/iy with copies of hl
        pop     h               ; and load all regs
        pop     h
;#idb

        pop     h
        pop     d
        pop     b
        pop     psw

;#idb ld sp,(spbt) replaced with the following code
;#idb HL is copied/restored before/after load so no state changed
        shld    temp
        lhld    spbt
        sphl
        lhld    temp
;#idb

iut:    ds      4               ; max 4 byte instruction under test

;#idb ld (spat),sp replaced with the following code
;#idb Must be very careful to preserve registers and flag
;#idb state resulting from the test.  The temptation is to use the
;#idb stack - but that doesn't work because of the way the app
;#idb uses SP as a quick way of pointing to memory.
;#idb Bit of a code smell, but I can't think of an easier way.
        shld    temp
        lxi     h,0
        jc      temp1           ;jump on the state of the C flag set in the test

        dad     sp              ;this code will clear the C flag (0 + nnnn = nc)
        jmp     temp2           ;C flag is same state as before

temp1:  dad     sp              ;this code will clear the C flag (0 + nnnn = nc)
        stc                     ;C flage needs re-setting to preserve state

temp2:  shld    spat
        lhld    temp
;#idb

        lxi     sp,spat
        push    psw             ; save other registers
        push    b
        push    d
        push    h

;#idb push ix
;#idb push iy both replaced by following code
;#idb Must match change made to pops made before test
        push    h
        push    h
;#idb

;#idb ld sp,(spsav) replaced with following code
;#idb No need to preserve state
        lhld    spsav           ; restore stack pointer
        sphl
;#idb

        ei                      ; enable interrupts
        lhld    msbt            ; copy memory operand
        shld    msat
        lxi     h,flgsat        ; flags after test
        mov     a,m
flgmsk: ani     0ffh            ; mask-out irrelevant bits (self-modified code!)
        mov     m,a
        mvi     b,16            ; total of 16 bytes of state
        lxi     d,msat
        lxi     h,crcval
tcrc:   ldax    d
        inx     d
        call    updcrc          ; accumulate crc of this test case
        dcr     b
        jnz     tcrc
      if        0
        mvi     e,' '
        mvi     c,2
        call    bdos
        lxi     h,crcval
        call    phex8
        lxi     d,crlf
        mvi     c,9
        call    bdos
        lxi     h,msat
        mvi     b,16
        call    hexstr
        lxi     d,crlf
        mvi     c,9
        call    bdos
      endif
        pop     h
        pop     d
        pop     b
        pop     psw
        ret

;#idb Added to store HL state
temp:   ds      2
;#idb

; 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: mov     a,m
        call    phex2
        inx     h
        dcr     b
        jnz     hexstr
        ret

; display hex
; display the big-endian 32-bit value pointed to by hl
phex8:  push    psw
        push    b
        push    h
        mvi     b,4
ph8lp:  mov     a,m
        call    phex2
        inx     h
        dcr     b
        jnz     ph8lp
        pop     h
        pop     b
        pop     psw
        ret

; display byte in a
phex2:  push    psw
        rrc
        rrc
        rrc
        rrc
        call    phex1
        pop     psw
; fall through  

; display low nibble in a
phex1:  push    psw
        push    b
        push    d
        push    h
        ani     0fh
        cpi     10
        jc      ph11
        adi     'a'-'9'-1
ph11:   adi     '0'
        mov     e,a
        mvi     c,2
        call    bdos
        pop     h
        pop     d
        pop     b
        pop     psw
        ret

bdos:   push    psw
        push    b
        push    d
        push    h
        call    5
        pop     h
        pop     d
        pop     b
        pop     psw
        ret

msg1:   db      '8080 instruction exerciser',10,13,'$'
msg2:   db      'Tests complete',10,13,'$'
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    b
        push    d
        push    h
        lxi     d,crcval
        mvi     b,4
cclp:   ldax    d
        cmp     m
        jnz     cce
        inx     h
        inx     d
        dcr     b
        jnz     cclp
cce:    pop     h
        pop     d
        pop     b
        ret

; 32-bit crc routine
; entry: a contains next byte, hl points to crc
; exit:  crc updated
updcrc: push    psw
        push    b
        push    d
        push    h
        push    h
        lxi     d,3
        dad     d       ; point to low byte of old crc
        xra     m       ; xor with new byte
        mov     l,a
        mvi     h,0
        dad     h       ; use result as index into table of 4 byte entries
        dad     h
        xchg
        lxi     h,crctab
        dad     d       ; point to selected entry in crctab
        xchg
        pop     h
        lxi     b,4     ; c = byte count, b = accumulator
crclp:  ldax    d
        xra     b
        mov     b,m
        mov     m,a
        inx     d
        inx     h
        dcr     c
        jnz     crclp
      if        0
        lxi     h,crcval
        call    phex8
        lxi     d,crlf
        mvi     c,9
        call    bdos
      endif
        pop     h
        pop     d
        pop     b
        pop     psw
        ret

initcrc:push    psw
        push    b
        push    h
        lxi     h,crcval
        mvi     a,0ffh
        mvi     b,4
icrclp: mov     m,a
        inx     h
        dcr     b
        jnz     icrclp
        pop     h
        pop     b
        pop     psw
        ret

bdos$entry:
          mov   b,a
          mov   a,c
          cpi   9
          jz    print$string
          cpi   2
          jz    print$char
          lxi   d,bdos$error
          call  print$string
          di
          hlt
bdos$error: db  "Invalid BDOS function", 13, 10, '$'
            
;print$char: print character in A to console.
;
print$char:
          mov   c,b
          jmp   print$char$c

   
;print$string: print $-terminated string at DE.
;
print$string:
          ldax  d
          inx   d
          cpi   '$'
          rz
          mov   c,a
          call  print$char$c
          jmp   print$string

print$char$c:
          in    UART_STATUS
          ani   MASK_TX_RDY
          jz    print$char$c
          mov   a,c
          out   UART_DATA
          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

        end

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

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