home *** CD-ROM | disk | FTP | other *** search
- ;BIT manipulation routines to set, reset, and test a
- ; bit in a byte in memory, to set bit (A) in A
-
- ;Module Name: BITMATH
- ;Author: Al Hawley
- ;Date: 10/31/89
-
- ;This module contains the following routines:
- public res_m,set_m,tst_m
- public exp_a,mask8,andm2m,orm2m,xorm2m
- public mirror,mask16
-
- ; (A) means 'the contents of the A register'
- ; 1) set, reset, and test a bit in the byte at HL
- ; SET_M, RES_M, TST_M
- ; 2) set bit (A) in A, reset others. This is the EXP function
- ; EXP_A
- ; 3) Return LOG(A) in A, ignoring all but highest bit.
- ; LOG2_A
- ; 4) set (A) least significant bits in A, others reset.
- ; MASK8 this is equivalent to binary [[LOG(A+1)] -1]
- ; 5) set (A) least significant bits in BC, others reset.
- ; MASK16 Same as MASK8, but returns 16 bit instead of 8.
- ; 6) logical AND, OR, XOR with (HL), result in (HL)
- ; ANDM2M, ORM2M, XORM2M routines
- ; 7) reverse the bit order in the byte at HL. (mirror image)
- ; MIRROR routine
-
- ;=================================================
-
- ;routines to set, reset, or test a bit.
- ;on entry:
- ; a = bit number (0-7)
- ; hl = address of the byte
- ;on exit:
- ; hl, de are preserved
- ; b = 46h(test) or 0c6h(set) or 86h(res)
- ;if z, c = a = 0
- ;if nz, c = a = 0ffh
- ; the z/nz returns are significant only when
- ; the test operation is performed.
-
- ;these routines work by synthesizing the opcode
- ;for a z80 'cb' instruction.
-
- res_m: ;entry point to reset a bit
- ld b,86h
- jr makop
-
- set_m: ;entry point to set a bit
- ld b,0c6h
-
- makop: rlc a ;rotate the bit number
- rlc a ;into the 3-4-5
- rlc a ;position in the accumulator
- or a,b
- ld (opcode),a ;install the opcode
- db 0cbh ;and execute the instruction
- opcode: db 0 ;..to do a bit, res, or set
- ret
-
- tst_m: ;entry point to test a bit
- ld b,46h
- call makop ;do the test
- ld c,0ffh ;adjust regs c and a
- ld a,c
- ret nz
- inc c
- ld a,c
- ret
-
- ;=================================================
-
- exp_a:
- ;set a single bit in reg A, reset all others.
- ;on entry,
- ; a = bit position to set (0-7)
- ;on exit,
- ; a = requested bit set, others 0
- ; flags are undefined
- ;all other registers preserved.
-
- push bc
- ld b,a
- inc b
- xor a
- scf
- expa1: rla
- djnz expa1
- pop bc
- ret
-
- ;=================================================
-
- ;convert a byte with a single bit set to the ordinal
- ;number in binary corresponding to the bit position.
- ;this is a special case of log n, where n= 0...7
- ;on entry the byte to convert is in reg A.
- ;on exit, reg A contains the log of A (bit position)
-
- log2_a: push bc
- ld b,7 ;7 bits to decrement at most
- or a,a ;clear carry
- log2a: rl a ;rotate left through carry
- jr c,log2ax ;done if bit shifted into cy
- djnz log2a ;the 8th dec never occurs
- log2ax: ld a,b
- or a ;reset cy
- pop bc
- ret
-
- ;=================================================
-
- mask16:
- ;set the n least significant bits
- ;in register pair BC according to the
- ;value (0..15) in A. A is not preserved
-
- ld b,a ;save for test of bit 3
- and 7 ;use 3 lsbits
- call mask8 ;return mask in A
- ld c,a
- xor a ;make a zero
- bit 3,b ;high byte?
- ld b,a ;in case not
- ret z ;low byte has the mask
- ld b,c ;mask in high byte
- dec a ;make 0ff for low byte
- ld c,a ;low byte
- ret
-
- ;=================================================
-
- mask8:
- ;set n least significant bits in reg A.
- ;Remaining bits are reset.
- ; n is specified as a number, 0-7 which
- ; defines the highest bit set.
- ;on entry,
- ; a = highest bit to set (0-7)
- ;on exit,
- ; a = filled with 1's from position
- ; 0 up through position specified
- ; all other registers preserved
- push bc
- ld b,a
- inc b
- xor a
- bcmsk1: scf
- rla
- djnz bcmsk1
- pop bc
- or a ;reset cy (=no error)
- ret
-
- ;=================================================
-
- andm2m:
- ;perform the logical and of the byte
- ;in the accumulator with the byte @hl
- ;preserves all registers
- push af
- and a,(hl)
- ld (hl),a
- pop af
- ret
-
- ;=================================================
-
- orm2m:
- ;perform the logical or of the byte
- ;in the accumulator with the byte @hl
- ;preserves all registers
- push af
- or a,(hl)
- ld (hl),a
- pop af
- ret
-
- ;=================================================
-
- xorm2m:
- ;perform the logical xor of the byte
- ;in the accumulator with the byte @hl
- ;preserves all registers
- push af
- xor a,(hl)
- ld (hl),a
- pop af
- ret
-
- ;=================================================
-
- mirror:
- ;invert the order of the bits at (hl)
- ;input: hl = addr of byte to invert
- ;output: mirror image in (hl)
- ; swap bits 0-7,1-6,2-5,3-4
- ; reg a is destroyed
- ;all other registers preserved
-
- ;test for common symetrical cases and
- ;do nothing (it's faster)
- ld a,(hl)
- or a ;00000000b?
- ret z
- cp 0ffh ;11111111b?
- ret z
- ;probably not symetrical. make mirror image.
- push bc
- rra ;lsb->cy, rotate right
- rl c ;cy-lsb, rotate left
- rra ;..repeat 7 more times
- rl c
- rra
- rl c ;this code would be shorter
- rra ;..if done in a loop, but
- rl c ;..also slower
- rra
- rl c
- rra
- rl c
- rra
- rl c
- rra
- rl c ;reversed pattern in c
- ld (hl),c ;store at memory loc
- pop bc
- ret
-
- ;=================================================
-
- end
-