%TITLE "Binary-Coded-Decimal (BCD) routines" IDEAL DOSSEG MODEL small ;------ Equates ASCIINull EQU 0 PackedSize EQU 10 UnpackedSize EQU 20 UDATASEG TempUPBCD dt ?, ? CODESEG PUBLIC BCDAdd, BCDSubtract, PackedToUnpacked PUBLIC UnpackedToPacked, BCDToASCII, BCDCopy %NEWPAGE ;------------------------------------------------------------------------ ; BCDAdd - adds two packed BCD numbers ;------------------------------------------------------------------------ ; Input: si = address of source BCD value (10 bytes) ; di = address of destination BCD value (10 bytes) ; Output: destinationBCD <- destinationBCD + sourceBCD ; cf = 0 : NO error ; cf = 1 : OVERFLOW error occurred ; Registers: none ;------------------------------------------------------------------------ PROC BCDAdd push ax push cx push di push si cld clc mov cx, PackedSize @@10: lodsb adc al,[byte di] daa stosb loop @@10 pop si pop di pop cx pop ax ret ENDP BCDAdd %NEWPAGE ;------------------------------------------------------------------------ ; BCDSubtract - subtracts two packed BCD numbers ;------------------------------------------------------------------------ ; Input: si = address of source BCD value (10 bytes) ; di = address of destination BCD value (10 bytes) ; Output: destinationBCD <- destinationBCD - sourceBCD ; cf = 0 : NO error ; cf = 1 : UNDERFLOW error occurred ; Registers: none ;------------------------------------------------------------------------ PROC BCDSubtract push ax push cx push di push si cld clc mov cx, PackedSize @@10: lodsb sbb [byte di],al mov al,[byte di] das stosb loop @@10 pop si pop di pop cx pop ax ret ENDP BCDSubtract %NEWPAGE ;------------------------------------------------------------------------ ; PackedToUnpacked - convert packed BCD to Unpacked BCD ;------------------------------------------------------------------------ ; Input: si = address of source packed BCD value (10 bytes) ; di = address of destination unpacked BCD value (20 bytes) ; Output: destinationBCD <- unpacked(sourceBCD) ; Registers: none ;------------------------------------------------------------------------ PROC PackedToUnpacked push ax push cx push di push si cld mov cx,PackedSize @@10: lodsb mov ah,al shr ah,1 shr ah,1 shr ah,1 shr ah,1 and al,0Fh stosw loop @@10 pop si pop di pop cx pop ax ret ENDP PackedToUnpacked %NEWPAGE ;------------------------------------------------------------------------ ; UnpackedToPacked - convert Unpacked BCD to packed BCD ;------------------------------------------------------------------------ ; Input: si = address of source unpacked BCD value (20 bytes) ; di = address of destination packed BCD value (10 bytes) ; Output: destinationBCD <- packed(sourceBCD) ; Registers: none ;------------------------------------------------------------------------ PROC UnpackedToPacked push ax push cx push di push si cld mov cx,PackedSize @@10: lodsw shr ah,1 shr ah,1 shr ah,1 shr ah,1 or al,ah stosb loop @@10 pop si pop di pop cx pop ax ret ENDP UnpackedToPacked %NEWPAGE ;------------------------------------------------------------------------ ; BCDToASCII - convert packed BCD value to ASCII ;------------------------------------------------------------------------ ; Input: si = address of source packed BCD value (10 bytes) ; di = address of destination ASCIIZ string (21 bytes) ; Output: ASCIIZ <- ASCII(sourceBCD) + null character ; Registers: none ;------------------------------------------------------------------------ PROC BCDToASCII push ax push cx push di push si push di mov di, offset TempUPBCD call PackedToUnpacked pop di mov si,offset TempUPBCD + UnpackedSize - 2 mov cx,PackedSize @@10: std lodsw or ax,03030h xchg ah,al cld stosw loop @@10 mov [byte,di],ASCIINull pop si pop di pop cx pop ax ret ENDP BCDToASCII %NEWPAGE ;------------------------------------------------------------------------ ; BCDCopy - copy a packed BCD value ;------------------------------------------------------------------------ ; Input: si = address of source BCD value (10 bytes) ; di = address of destination BCD value (10 bytes) ; Output: destinationBCD <- sourceBCD ; Registers: none ;------------------------------------------------------------------------ PROC BCDCopy push cx push di push si cld mov cx,PackedSize/2 rep movsw pop si pop di pop cx ret ENDP BCDCopy END