home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.barnyard.co.uk
/
2015.02.ftp.barnyard.co.uk.tar
/
ftp.barnyard.co.uk
/
cpm
/
DRI-archive
/
roche
/
FLTINPUT.ASM
< prev
next >
Wrap
Assembly Source File
|
2009-12-11
|
7KB
|
339 lines
; FLTINPUT.ASM
; ------------
;
; See FALCONER.WS4 for doc.
;
; (Retyped by Emmanuel ROCHE.)
;
;--------------------------------
; External routines required
;
extrn fdivt,flotd,fmult ; in FLTARITH.ASM
extrn mul10 ; in INTARITH.ASM
;
;--------------------------------
; Entry points allowed
; --------------------
;
; Utility routines
;
entry deblk,jbc,qmax,qnum
;
; Numeric input
;
entry ival,ivalc
;
;--------------------------------
; Macro definitions
;--------------------------------
;
; Execute routine at (BC) [normally get next character]
;
getch macro
call jbc
endm
;
; Change sign of real operand B or D
;
fsign macro reg
if reg*(reg-d)
error "R"
endif
mov a,reg
xri 80H
mov reg,a
endm
;
; Reload (BC.L), stored by PUSH B, PUSH H sequence
;
reload macro reg
bc.l equ b
if reg-b
error "R"
db 0,0,0
endif
if reg-b=0 ; Was IFZ
pop b
mov l,c
pop b
endif
endm
;
; "Return" and check stacl level zero
;
rtn macro
if .lvl
error '0'+.lvl
.lvl set 0
endif
ret
endm
;
; Save (BC.L), to be restored by RELOAD BC.L later
;
save macro reg
bc.l equ b
if reg-b
error 'R'
db 0,0
endif
if reg-b=0 ; Was IFZ
push b
push h
endif
endm
;
;--------------------------------
; Start the code
;--------------------------------
;
; Check (A) to be in range 0-9 (ASCII)
; Return Carry for non-numeric character
; F
;
qnum: cpi '9'+1 ; This first to speed exit
cmc ; for alpha.
rc ; < 0, non-numeric
cpi '0' ;
rtn ;
;
; Check (HL) for value < 6554
; Set Carry if greater
; F
;
qmax: push b ;
mov b,a ;
mov a,l ;
sui 6554 MOD 256 ;
mov a,h ;
sbi 6554/256 ;
cmc ;
mov a,b ;
pop b ;
rtn ;
;
; Transfer control to (BC)
;
jbc: push b ; Set address on stack
.lvl set .lvl-1 ; Compensate for stacked addr
rtn ; Go excute
;
; Input a character, ignoring blanks
; A,F
;
deblk: getch ;
cpi ' ' ;
rnz ;
jmp deblk ; Bypass a blank
;
; Input a floating point value from a char string
; At entry:
; (BC) => character input routine
; At exit:
; (A)=(L) = character following numerical string
; (DE.H) = value
; If error, (A) = error code, (L) = exit char, Carry set
; Carry for overflow or illegal first char
; A,F,D,E,H,L
;
ival: call deblk ; Bypass leading blanks
;
; Alternate entry with first char in (A)
;
ivalc: cpi ' ' ;
jz ival ; Ignore leading spaces
cpi '+' ;
jz ival ; Ignore unary +
call qnum ;
lxi h,0 ; Clear acc
mvi d,40H ; and exponent.
jnc ival6 ; Initial numeric entry
cpi '.' ;
jz ival1 ; Initial decimal point
cpi '-' ;
stc ;
mov l,a ; (A) is illegal char.
rnz ; Error, return 0 and Carry,
call ival ; Recursive unary -
push psw ; Save exit char
fsign d ;
pop psw ;
rtn ;
ival1: getch ; After initial decimal point
call qnum ;
jnc ival4 ; Got the required digit
mov l,a ; Exit char to (L)
stc ;
rtn ; Illegal initial char
ival2: inr d ; Incorporate digit
getch ; Get next digit
call qnum ;
jnc ival2 ; Still digit string
cpi '.' ; Will be ignored
jnz ival8 ; Check for exponent
ival3: getch ; Digits after decimal point
call qnum ;
jc ival8 ; Non-digit
call qmax ;
jc ival3 ; No room, ignore
call mul10 ;
ival4: ani 0FH ; Mask off digit
dcr d ; Modify exponent digits after
add l ; decimal point.
mov l,a ;
mov a,h ;
aci 00H ;
mov h,a ;
jnc ival3 ; No overflow
lxi h,6554 ; Set max
inr d ;
jmp ival3 ;
ival5: call qmax ; Digits to left of decimal point
jc ival2 ; No more digit room
call mul10 ;
ival6: ani 0FH ; Mask off digit
add l ;
mov l,a ;
mov a,h ;
aci 00H ;
mov h,a ; Incorporate digit
jnc ival7 ; No overflow
lxi h,65535 ; Max
ival7: getch ; Get next digit/char
call qnum ;
jnc ival5 ; Digit
cpi '.' ;
jz ival3 ; Decimal point
ival8: cpi 'E' ;
jz ival9 ;
cpi 'e' ; Lower case allowed
ival9: xchg ;
stc ;
cmc ; Clear any Carry
cz rexp ; "E", read exponent
mov l,a ; Exit char
cnc unfix ; Convert format if no overflow yet
rnc ; No overflow
mvi a,80H ; Overflow code
rtn ;
;
; "Fixed" point representation consists of a 16 bit positive
; integer (in the range 0 to 65535), and a 7 bit offset (by
; 40H) integer exponent, which represents a power of ten
; multiplier. The eighth exponent bit represents the sign
; of the mantissa. This representation is used for input/
; output only.
;
; Convert "fixed" format to "real"
; Carry for input out of range
; F,D,E,H
;
unfix: save bc.l ;
push psw ;
mov a,h ;
ani 80H ;
mov b,a ; Sign of result
mov a,h ;
ani 7FH ;
sui 40H ;
mov c,a ; Decimal point
call flotd ;
mov a,h ;
ora a ;
jz unfix4 ; Zero value
mov a,d ;
ora b ;
mov d,a ; Incorporate sign
mov a,c ;
ora a ;
@01 set .lvl ;
unfix1: jz unfix4 ; Reduced to real
jm unfix3 ; Negative exponent
call fmult ; Positive exponent
dcr c ;
jnc unfix1 ; In range
unfix2: pop psw ;
stc ;
jmp unfix5 ;
.lvl set @01 ;
unfix3: call fdivt ; Negative exponent
inr c ;
jnc unfix1 ; Continue
jmp unfix2 ; Underflow
unfix4: pop psw ;
ora a ; Reset Carry, no overflow
unfix5: reload bc.l ;
rtn ;
;
; Read 2 digit signed decimal exponent
; to (A). Return exit character in (D).
; A,F,D,E
;
r2dc: getch ; Get char
call qnum ;
jc r2dc3 ; Not digit
r2dc1: lxi d,0 ;
r2dc2: dcr d ;
inr d ;
stc ;
rnz ; Overflow, 3 digits entered,
mov d,e ; first non-zero.
ani 0FH ;
mov e,a ;
getch ;
call qnum ;
jnc r2dc2 ;
push psw ;
mov a,d ;
add a ;
add a ; 4*
add d ;
add a ; 10*
add e ; Value MOD 100
pop d ;
rtn ;
r2dc3: cpi '+' ;
jz r2dc ; Ignore unary +
cpi '-' ;
jnz r2dc4 ; Not unary -
call r2dc ;
cma ;
inr a ;
rtn ;
r2dc4: mov d,a ;
mvi a,0 ; Return 0, none came
rtn ;
;
; Read exponent and combine with "fixed" value
; Return exit char in (A)
; A,F,D
;
rexp: push d ;
call r2dc ; Get exponent
jc rexp1 ; Overflow
push d ; Save exit char
mov d,a ; Exponent
mov a,h ;
ani 80H ;
mov e,a ; Sign
mov a,h ;
ani 7FH ; Exponent alone
add d ;
jp rexp2 ; No overflow
@01 set .lvl ;
pop psw ; Exit char
rexp1: pop d ;
stc ; Signal overflow
rtn ;
.lvl set @01 ;
rexp2: ora e ; Original sign
mov h,a ; Resultant exponent
pop psw ; Restore exit char
pop d ; Restore mantissa
ora a ; Clear Carry, no overflow
rtn ;
;
;--------------------------------
;
end ; of FLTINPUT.ASM