;ah2i.asm
;convert ascii hex number to 16-bit int
;Willard Goosey
;goosey@sdc.org
;7/12/2011

; $Id: ah2i.asm,v 1.7 2012/08/01 02:44:29 goosey Exp goosey $

;requires m100.def -or-uncomment this -or- 
;provide your own upcas
;if not m100
;UPCAS equ 0fe9h

;AH2I -- convert 4 hex digits to 16-bit int
;entry conditions: HL-> null-terimated string of hex 
;                       digits in ascii
;Exit conditions:  DE=16 bit int
;                  carry set on error

;AH2C -- convert 2 hex digitis to 8-bit int
;Entry Conditions: HL-> null-terminated string of hex 
;                       digits in ascii
;Exit Conditions: c=8bit value
;                 carry set on error

;derived from:
;"Mastering CP/M"
;Alan R. Miller, Sybex, 1983

;7/12/2011 started

ah2i   lxi d,0    ;clear de
ah2i2  mov a,m    ;a= *hl
       cpi 00     ;compare with NULL
       jz ah2i3   ;done?
       inx h      ;hl=hl+1
       push h     ;save hl
       push d     ;save de
       call UPCAS ;uppercase the digit in A
       pop h      ;hl=de that was on stack
       pop d      ;de=hl that was on stack
       call nib   ;a from hex to binary
       jc ah2i5   ;error
       dad h      ;hl=hl+hl 
       dad h      ;hl=hl*4
       dad h      ;hl=hl*8 
       dad h      ;hl=hl*16
       ora l      ;a=a or l
       mov l,a    ;l=a
       xchg       ;swap de and hl
       jmp ah2i2  ;next
       
ah2i5  lxi d,0           
ah2i3  ret

nib    sui '0'    ;convert A from ascii to bin
       rc         ;ret <0
       cpi 'F'-'0'+1 
       cmc
       rc         ;return >F
       cpi 10
       cmc
       rnc        ;return if a 0-9
       sui 'A'-'9'-1
       cpi 10
       ret

;;derived from 8080/z80 Assembly Language
;;Alan Miller, John Wiley & Sons, 1981

ah2c   mvi c,0    ;c=0
       mov a,m    ;a= *hl
       cpi 00h    ;compare a to 0
       jz ah2c1   ;done?
       push h     ;save hl
       push b     ;save bc
       call UPCAS ;uppercase A
       pop b      ;restore bc
       pop h      ;restore hl
       call nib   ;ascii hex -> bin 
       jc ah2c2   ;error?
       add a      ;a=a*2
       add a      ;a=a*4
       add a      ;a=a*8
       add a      ;a=a*16
       mov c,a    ;c=a
       inx h      ;hl=hl+1
       mov a,m    ;a= *hl
       cpi 00h    ;compare A to 0
       jz ah2c3   ;single hex digit in input?
       push b     ;save bc
       call UPCAS ;uppercase A
       call nib   ;ascii hex -> bin
       pop b      ;restore bc
       jc ah2c2   ;error?
       ora c      ;a=a | c
       mov c,a    ;c=a
ah2c1  ret

ah2c2  mvi c,0    ;return 0 on error
       stc        ;with carry set
       ret  

;single hex digit, shift C back 4 bits and return
ah2c3  mov a,c    ;a=c
       stc        ;set carry
       cmc        ;complement carry
       rar        ;rotate right arithmatic
       rar
       rar
       rar
       ani 0fh    ;a=a and 0F
       mov c,a
       ret

;;end of ah2i.asm
	
	 
