You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

75 lines
2.2 KiB

;
;==================================================================================================
; ENCODE 32-BIT VALUES TO A 5-BIT SHIFT-ENCODED VALUE
;==================================================================================================
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; An encoded value (V) is defined as V = C * 2^X * 3^Y
; where C is a prearranged constant, Y is 0 or 1 and X is 0-15
; The encoded value is stored as 5 bits: YXXXX
; At present, C=75 for baud rate encoding and C=3 for CPU OSC encoding
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ENCODE
;
; Enter with:
; DE:HL = dword value to be encoded
; C = divisor (0 < C < 256)
; encode divisor OSC_DIV = 3, or BAUD_DIV = 75
;
; Exit with:
; C = encoded value
; A = non-zero on error
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
encode:
; incoming value of zero is a failure
call encode5 ; test DE:HL for zero
jr z,encode4 ; if zero, failure return
;
; apply encoding divisor
call div32x8 ; DE:HL / C (remainder in A)
or a ; set flags to test for zero
ret nz ; error if not evenly divisible
;
; test divide by 3 to see if it is possible
push de ; save working
push hl ; ... value
ld c,3 ; divide by 3
call div32x8 ; ... test
pop hl ; restore working
pop de ; ... value
;
; implmement divide by 3 if possible
ld c,$00 ; init result in c w/ div 3 flag clear
or a ; set flags to test for remainder
jr nz,encode2 ; jump if it failed
;
; if divide by 3 worked, do it again for real
ld c,3 ; setup to divide by 3 again
call div32x8 ; do it
ld c,$10 ; init result in c w/ div 3 flag set
;
encode2:
; loop to determine power of 2
ld b,16 ; can only represent up to 2^15
encode3:
srl d ; right shift de:hl into carry
rr e ; ...
rr h ; ...
rr l ; ...
jr c,encode5 ; if carry, then done, c has result
inc c ; bump the result value
djnz encode3 ; keep shifting if possible
encode4:
or $ff ; signal error
ret ; and done
;
encode5:
; test de:hl for zero (sets zf, clobbers a)
ld a,h
or l
or d
or e
ret ; ret w/ Z set if DE:HL == 0