CPU-Z80-Disassembler

 view release on metacpan or  search on metacpan

t/data/zx81.asm  view on Meta::CPAN


st_mem_xx:
        push hl                 ; save the result pointer.
        ex de, hl               ; transfer to DE.
        ld hl, (MEM)            ; fetch MEM the base of memory area.
        call LOC_MEM            ; routine LOC-MEM sets HL to the destination.
        ex de, hl               ; swap - HL is start, DE is destination.
        call MOVE_FP            ; routine MOVE-FP.
                                ; note. a short ld bc,5; ldir
                                ; the embedded memory check is not required
                                ; so these instructions would be faster!
        ex de, hl               ; DE = STKEND
        pop hl                  ; restore original result pointer
        ret                     ; return.
                                ; 

; -------------------------
; THE 'EXCHANGE' SUBROUTINE
; -------------------------
; offset $01: 'exchange'
; This routine exchanges the last two values on the calculator stack
; On entry, as always with binary operations,
; HL=first number, DE=second number
; On exit, HL=result, DE=stkend.

;; exchange

exchange:
        ld b, $05               ; there are five bytes to be swapped
                                ; 
; start of loop.

;; SWAP-BYTE

SWAP_BYTE:
        ld a, (de)              ; each byte of second
        ld c, (hl)              ; each byte of first
        ex de, hl               ; swap pointers
        ld (de), a              ; store each byte of first
        ld (hl), c              ; store each byte of second
        inc hl                  ; advance both
        inc de                  ; pointers.
        djnz SWAP_BYTE          ; loop back to SWAP-BYTE until all 5 done.
                                ; 
        ex de, hl               ; even up the exchanges
                                ; so that DE addresses STKEND.
        ret                     ; return.
                                ; 

; ---------------------------------
; THE 'SERIES GENERATOR' SUBROUTINE
; ---------------------------------
; offset $86: 'series-06'
; offset $88: 'series-08'
; offset $8C: 'series-0C'
; The ZX81 uses Chebyshev polynomials to generate approximations for
; SIN, ATN, LN and EXP. These are named after the Russian mathematician
; Pafnuty Chebyshev, born in 1821, who did much pioneering work on numerical
; series. As far as calculators are concerned, Chebyshev polynomials have an
; advantage over other series, for example the Taylor series, as they can
; reach an approximation in just six iterations for SIN, eight for EXP and
; twelve for LN and ATN. The mechanics of the routine are interesting but
; for full treatment of how these are generated with demonstrations in
; Sinclair BASIC see "The Complete Spectrum ROM Disassembly" by Dr Ian Logan
; and Dr Frank O'Hara, published 1983 by Melbourne House.

;; series-xx

series_xx:
        ld b, a                 ; parameter $00 - $1F to B counter
        call GEN_ENT_1          ; routine GEN-ENT-1 is called.
                                ; A recursive call to a special entry point
                                ; in the calculator that puts the B register
                                ; in the system variable BREG. The return
                                ; address is the next location and where
                                ; the calculator will expect its first
                                ; instruction - now pointed to by HL'.
                                ; The previous pointer to the series of
                                ; five-byte numbers goes on the machine stack.
                                ; 
; The initialization phase.

        defb $2D                ; duplicate       x,x
        defb $0F                ; addition        x+x
        defb $C0                ; st-mem-0        x+x
        defb $02                ; delete          .
        defb $A0                ; stk-zero        0
        defb $C2                ; st-mem-2        0
                                ; 
; a loop is now entered to perform the algebraic calculation for each of
; the numbers in the series

;; G-LOOP

G_LOOP:
        defb $2D                ; duplicate       v,v.
        defb $E0                ; get-mem-0       v,v,x+2
        defb $04                ; multiply        v,v*x+2
        defb $E2                ; get-mem-2       v,v*x+2,v
        defb $C1                ; st-mem-1
        defb $03                ; subtract
        defb $34                ; end-calc
                                ; 
; the previous pointer is fetched from the machine stack to H'L' where it
; addresses one of the numbers of the series following the series literal.

        call stk_data           ; routine STK-DATA is called directly to
                                ; push a value and advance H'L'.
        call GEN_ENT_2          ; routine GEN-ENT-2 recursively re-enters
                                ; the calculator without disturbing
                                ; system variable BREG
                                ; H'L' value goes on the machine stack and is
                                ; then loaded as usual with the next address.
                                ; 
        defb $0F                ; addition
        defb $01                ; exchange
        defb $C2                ; st-mem-2
        defb $02                ; delete
                                ; 
        defb $31                ; dec-jr-nz
        defb $EE                ; back to L1A89, G-LOOP



( run in 0.859 second using v1.01-cache-2.11-cpan-71847e10f99 )