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/ DEV 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