;The following BIT manipulation routines are from ARRAYLIB ; which has been separately released for non-profit use. ;Library Name: ARRAYLIB ;Author: Al Hawley ;Date: 31 Mar 1987 ;Version number: 1.0c ;Program Function: ARRAYLIB is a collection of subroutines which ; implement the management of byte arrays in programs written ; for Z80 or HD64180 based computers. This module is one of the ; set, and may require the presence of others. ;*************************************************** ; COPYRIGHT NOTICE ;ARRAYLIB is copyright by A. E. Hawley on March 4, 1987. ;It may be freely distributed, but it must not be sold ;either separately or as part of a package without the ;written consent of the author. The author may be reached ;via electronic mail at the Ladera Z-Node in Los Angeles, ;213-670-9465, or by Voice Phone at: 213-649-3575 ; ;*************************************************** ;This module contains the following routines: public arresbit,arsetbit,artstbit public arrb1msk,arrbcmsk,arrmanda,armemora public armirror public msk16 ;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. arresbit: ;entry point to reset a bit ld b,86h jr makop arsetbit: ;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 artstbit: ;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 ;************************************* arrb1msk: ;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 b1msk1: rla djnz b1msk1 pop bc ret ;************************************* msk16: ;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 arrbcmsk ;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 ;************************************* arrbcmsk: ;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 ;************************************* arrmanda: ;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 ;************************************* armemora: ;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 ;********************************************** armirror: ;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