mirror of https://github.com/wwarthen/RomWBW.git
6 changed files with 1294 additions and 6 deletions
@ -0,0 +1,79 @@ |
|||
; |
|||
;================================================================================================== |
|||
; DECODE 32-BIT VALUES FROM A 5-BIT SHIFT-ENCODED VALUE |
|||
;================================================================================================== |
|||
; |
|||
; Copyright (C) 2014 John R. Coffman. All rights reserved. |
|||
; Provided for hobbyist use on the Z180 SBC Mark IV board. |
|||
; |
|||
; This program is free software: you can redistribute it and/or modify |
|||
; it under the terms of the GNU General Public License as published by |
|||
; the Free Software Foundation, either version 3 of the License, or |
|||
; (at your option) any later version. |
|||
; |
|||
; This program is distributed in the hope that it will be useful, |
|||
; but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
; GNU General Public License for more details. |
|||
; |
|||
; You should have received a copy of the GNU General Public License |
|||
; along with this program. If not, see <http://www.gnu.org/licenses/>. |
|||
; |
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
|||
; |
|||
; THE FUNCTION(S) IN THIS FILE ARE BASED ON LIKE FUNCTIONS CREATED BY JOHN COFFMAN |
|||
; IN HIS UNA BIOS PROJECT. THEY ARE INCLUDED HERE BASED ON GPLV3 PERMISSIBLE USE. |
|||
; |
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
|||
; |
|||
; An encoded value (V) is defined as V = C * 2^X * 3^Y |
|||
; where C is a prearranged constant, X is 0 or 1 and Y 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 |
|||
; |
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
|||
; DECODE |
|||
; |
|||
; Enter with: |
|||
; HL = word to be decoded (5-bits) FXXXX |
|||
; F=extra 3 factor, XXXX=shift factor, reg H must be zero |
|||
; DE = encode divisor OSC_DIV = 3, or BAUD_DIV = 75 |
|||
; |
|||
; Exit with: |
|||
; DE:HL = decoded value |
|||
; A = non-zero on error |
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
|||
; |
|||
decode: |
|||
ld a,h ; set to test |
|||
ld c,$ff ; presume error condition |
|||
or a ; test for zero |
|||
jr nz,decode9 ; not an encoded value |
|||
ld a,l ; get low order 5 bits |
|||
cp 32 ; test for error |
|||
jr nc,decode9 ; error return if not below |
|||
; argument hl is validated |
|||
ld h,d |
|||
ld l,e ; copy to hl |
|||
cp 16 |
|||
jr c,decode2 ; if < 16, no 3 factor |
|||
add hl,de ; introduce factor of 3 |
|||
add hl,de ; ** |
|||
decode2: |
|||
ld de,0 ; zero the high order |
|||
and 15 ; mask to 4 bits |
|||
jr z,decode8 ; good exit |
|||
ld c,b ; save b-reg |
|||
ld b,a ; |
|||
decode3: |
|||
add hl,hl ; shift left by 1, set carry |
|||
rl e |
|||
rl d ; ** |
|||
djnz decode3 |
|||
ld b,c ; restore b-reg |
|||
decode8: |
|||
ld c,0 ; signal good return |
|||
decode9: |
|||
ld a,c ; error code test |
|||
or a ; error code in reg-c and z-flag |
|||
ret |
|||
@ -0,0 +1,75 @@ |
|||
; |
|||
;================================================================================================== |
|||
; 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 |
|||
File diff suppressed because it is too large
@ -0,0 +1,104 @@ |
|||
;; |
|||
;; make a bcd number from a binary number |
|||
;; 32 bit binary number in hl:bc, result stored at (de) |
|||
;; de is preserved, all other regs destroyed |
|||
;; |
|||
;bin2bcd: |
|||
; push ix ; save ix |
|||
; push bc ; move bc |
|||
; pop ix ; ... to ix |
|||
; ld c,32 ; loop for 32 bits of binary dword |
|||
;; |
|||
;bin2bcd0: |
|||
; ; outer loop (once for each bit in binary number) |
|||
; ld b,5 ; loop for 5 bytes of result |
|||
; push de ; save de |
|||
; add ix,ix ; left shift next bit from hl:ix |
|||
; adc hl,hl ; ... into carry |
|||
;; |
|||
;bin2bcd1: |
|||
; ; inner loop (once for each byte of bcd number) |
|||
; ld a,(de) ; get it |
|||
; adc a,a ; double it w/ carry |
|||
; daa ; decimal adjust |
|||
; ld (de),a ; save it |
|||
; inc de ; point to next bcd byte |
|||
; djnz bin2bcd1 ; loop thru all bcd bytes |
|||
;; |
|||
; ; remainder of outer loop |
|||
; pop de ; recover de |
|||
; dec c ; dec bit counter |
|||
; jr nz,bin2bcd0 ; loop till done with all bits |
|||
; pop ix ; restore ix |
|||
; |
|||
; make a bcd number from a binary number |
|||
; 32 bit binary number in de:hl, result stored at (bc) |
|||
; on output hl = bcd buf adr |
|||
; |
|||
bin2bcd: |
|||
push ix ; save ix |
|||
; convert from de:hl -> (bc) to hl:ix -> (de) |
|||
; hl -> ix, de -> hl, bc -> de |
|||
ex de,hl |
|||
push de |
|||
pop ix |
|||
push bc |
|||
pop de |
|||
; |
|||
ld c,32 ; loop for 32 bits of binary dword |
|||
; |
|||
bin2bcd0: |
|||
; outer loop (once for each bit in binary number) |
|||
ld b,5 ; loop for 5 bytes of result |
|||
push de ; save de |
|||
add ix,ix ; left shift next bit from hl:ix |
|||
adc hl,hl ; ... into carry |
|||
; |
|||
bin2bcd1: |
|||
; inner loop (once for each byte of bcd number) |
|||
ld a,(de) ; get it |
|||
adc a,a ; double it w/ carry |
|||
daa ; decimal adjust |
|||
ld (de),a ; save it |
|||
inc de ; point to next bcd byte |
|||
djnz bin2bcd1 ; loop thru all bcd bytes |
|||
; |
|||
; remainder of outer loop |
|||
pop de ; recover de |
|||
dec c ; dec bit counter |
|||
jr nz,bin2bcd0 ; loop till done with all bits |
|||
ex de,hl ; hl -> bcd buf |
|||
pop ix ; restore ix |
|||
ret |
|||
; |
|||
; print contents of 5 byte bcd number at (hl) |
|||
; with leading zero suppression |
|||
; all regs destroyed |
|||
; |
|||
prtbcd: |
|||
inc hl ; bump hl to point to |
|||
inc hl ; ... |
|||
inc hl ; ... |
|||
inc hl ; ... last byte of bcd |
|||
ld b,5 ; loop for 5 bytes |
|||
ld c,0 ; start by suppressing leading zeroes |
|||
; |
|||
prtbcd1: |
|||
; loop to print one bcd byte (two digits) |
|||
xor a ; clear accum |
|||
rld ; rotate first nibble into a |
|||
call prtbcd2 ; print it |
|||
xor a ; clear accum |
|||
rld ; rotate second nibble into a |
|||
call prtbcd2 ; print it |
|||
dec hl ; point to prior byte |
|||
djnz prtbcd1 ; loop till done |
|||
ret ; return |
|||
; |
|||
prtbcd2: |
|||
; subroutine to print a digit in a |
|||
cp c ; compare incoming to c |
|||
ret z ; if equal, suppressing, abort |
|||
dec c ; make c negative to stop suppression |
|||
add a,'0' ; offset to printable value |
|||
jp prtchr ; exit via character out |
|||
Loading…
Reference in new issue