home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS 1992 December
/
simtel1292_SIMTEL_1292_Walnut_Creek.iso
/
msdos
/
asmutl
/
bluebook.arc
/
BCD.ASM
next >
Wrap
Assembly Source File
|
1986-05-08
|
8KB
|
259 lines
COMMENT ~
BCD.ASM -- BCD Conversion Routines
From `BLUEBOOK of ASSEMBLY ROUTINES for the IBM PC & XT'
by Christopher L. Morgan
Copyright (C) 1984 by The Waite Group, Inc.
>>>>> See BCD.DOC for complete descriptions of routines. <<<<<
_____________________________________________________________________________
Contents:
---------
BCDIN -- Convert from ASCII Decimal to BCD
BCDOUT -- Convert from BCD to ASCII Decimal
BCD2I16 -- Convert from BCD to 16-bit Binary
I162BCD -- Convert from 16-bit Binary to BCD
_____________________________________________________________________________
~
EXTRN STDIN:FAR,STDOUT:FAR
;_____________________________________________________________________________
;
DATAS SEGMENT PUBLIC
BCDBUFF DB 18 DUP(?)
DATAS ENDS
;_____________________________________________________________________________
;
CODES SEGMENT
PUBLIC BCDIN,BCDOUT,BCD2I16,I162BCD
ASSUME CS:CODES,DS:DATAS
;______________________________ BCD ROUTINES _________________________________
;Routine to convert from ASCII decimal to internal BCD format.
;
BCDIN PROC FAR
PUSH DS ;Save registers
PUSH DI
PUSH DX
PUSH CX
PUSH AX
;
;Set up data segment
MOV DX,DATAS ;Point to data segment
MOV DS,AX
;
;Clear BCD buffer
LEA DI,BCDBUFF ;Point to BCD buffer
MOV AL,0 ;zero byte
MOV CX,18 ;buffer SIze
BCDIN1:
MOV [DI],AL ;zero the byte
INC DI ;Point to next byte
LOOP BCDIN1
BCDIN2:
;
; get the digit
CALL STDIN ;Digit comes in AL
SUB AL,30H ;Subract 30H
JL BCDIN4 ;Check if too low
CMP AL,9
JG BCDIN4 ;Check if too high
;
;Multiply buffer by 10 and add new digit
LEA DI,BCDBUFF ;Point to BCD buffer
MOV CX,18 ;buffer SIze
BCDIN3:
PUSH CX ;Save counter
MOV DL,AL ;Save previous digit
MOV AL,[DI] ;Pick up byte from buffer
MOV CL,4 ;for a count of 4
SAL AX,CL ;Shift byte left
OR AL,DL ;Combine with previous digit
MOV [DI],AL ;Result goes back
MOV AL,AH ;Prepare for next byte
AND AL,0FH ;Strip to byte
INC DI ;Point to next byte
POP CX ;Restore count
LOOP BCDIN3
JMP BCDIN2
BCDIN4:
POP AX ;Restore registers
POP CX
POP DX
POP DI
POP DS
RET ;Return
BCDIN ENDP
;------------------------------------------------------------------------------
;Routine to convert from internal BCD to ASCII decimal
;
BCDOUT PROC FAR
PUSH DS ;Save registers
PUSH SI
PUSH DX
PUSH CX
PUSH AX
;
;Set up data segment
MOV AX,DATAS ;Point to data segment
MOV DS,AX
MOV CX,18 ;for a count of 18
LEA SI,BCDBUFF ;Point ot BCD buffer
ADD SI,17 ;Point ot end of BCD buffer
MOV DH,0 ;Clear flag for leading zeros
BCDOUT1:
PUSH CX ;Save loop count
MOV AL,[SI] ;get BCD byte
DEC SI ;And point to next
MOV DL,AL ;Save it
;
;Upper digit
MOV CL,4 ;for a count of 4
ROL AL,CL ; rotate byte
AND AL,0FH ;just the digit
OR DH,AL ;Leading zeros
JZ BCDOUT2 ;if so skip digit
ADD AL,30H ;make ASCII
CALL STDOUT ;Send it out
BCDOUT2:
POP CX ;Restore count
CMP CX,1 ;Last digit ?
JNZ BCDOUT3 ;Skip in not
MOV DH,0FFH ; set flag if so
BCDOUT3:
PUSH CX ;Save count
MOV AL,DL ;byte back
;
;Lower digit
AND AL,0FH ;just the digit
OR DH,AL ;Leading zeros ?
JZ BCDOUT4 ;if so skip digit
ADD AL,30H ;make ASCII
CALL STDOUT ;Send it out
BCDOUT4:
POP CX ;Restore loop count
LOOP BCDOUT1
POP AX ;Restore registers
POP CX
POP DX
POP SI
POP DS
RET ;Return
BCDOUT ENDP
;------------------------------------------------------------------------------
;Routine to convert from internal BCD to internal 16-bit binary.
;
BCD2I16 PROC FAR
PUSH DS ;Save registers
PUSH SI
PUSH CX
PUSH AX
;
;Set up data segment
MOV AX,DATAS ;Point of data segment
MOV DS,AX
;
;Set up loop
MOV CX,18 ;initialize counter
LEA SI,BCDBUFF ;Point to buffer
ADD SI,17 ;Point to end of BCD buffer
MOV DX,0 ;Set DX to zero
BCD2I161:
PUSH CX ;Save loop count
MOV AL,[SI] ;get BCD byte
DEC SI ;And point to next
MOV BL,AL ;Save it
;
;Upper digit
MOV CL,4 ;for a count of 4
ROL AL,CL ; rotate byte
AND AL,0FH ;just the digit
CBW
PUSH AX ;Save digit
MOV AX,DX
MOV CX,10 ;multiplier of 10
MUL CX ;multiply
MOV DX,AX ;Result in DX
POP AX ;Restore digit
ADD DX,AX ;Add in digit
MOV AL,BL ;byte back
;
;Lower digit
AND AL,0FH ;just digit
CBW
PUSH AX ;Save digit
MOV AX,DX
MOV CX,10 ;miltiplier of 10
MUL CX ;multiply
MOV DX,AX ;Result in DX
POP AX ;Restore digit
ADD DX,AX ;Add in digit
POP CX ;Restore loop count
LOOP BCD2I161
POP AX ;Restore registers
POP CX
POP SI
POP DS
RET ;Return
BCD2I16 ENDP
;-----------------------------------------------------------------------------
;Routine to convert from internal 16-bit binary to internal BCD.
;
I162BCD PROC FAR
;
;A binary number is in DX
PUSH DS ;Save registers
PUSH DI
PUSH DX
PUSH CX
PUSH AX
;
;Set up data segment
MOV AX,DATAS ;Point to data segment
MOV DS,AX
;
;Clear BCD buffer
LEA DI,BCDBUFF ;Point to buffer
MOV AL,0 ;zero byte
MOV CX,18 ;buffer SIze
I162BCD1:
MOV [DI],AL ;Clear byte
INC DI ;next byte
LOOP I162BCD1
;
;Put the digits in a buffer
LEA DI,BCDBUFF ;Point to buffer
I162BCD2:
MOV AX,DX ;numerator
MOV DX,0 ;Clear upper hALf
MOV CX,10 ;Divisor of 10
DIV CX ;Divide
XCHG AX,DX ;get quotient
MOV BL,AL ;Save digit
MOV AX,DX ;numerator
MOV DX,0 ;Clear upper hALf
MOV CX,10 ;Divisor of 10
DIV CX ;Divide
XCHG AX,DX ;get quotient
MOV CL,4 ;for a count of 4
ROL AL,CL ; rotate digit
AND AL,0F0H ;just the digit
OR AL,BL ;Combine digits
MOV [DI],AL ;Put in buffer
INC DI ;next byte
CMP DX,0 ;done ?
JNZ I162BCD2
POP AX ;Restore registers
POP CX
POP DX
POP DI
POP DS
RET ;Return
I162BCD ENDP
;-----------------------------------------------------------------------------
CODES ENDS
;
END
;_____________________________________________________________________________
;>>>>> Physical EOF BCD.ASM <<<<<