|
|
1.06a MS-DOS
.386P
vseg equ 0b000h ;video ram segment address
;****************************************************************************
;* *
;* Procedure msout On entry ds:si -> text, terminated with 0. *
;* *
;* Display message on standard output, convert parameters to hex ascii or *
;* decimal ascii for each �n, �n, �n in message where n=number of digits. *
;* Repeat character c for �nc, where n=(number of repetitions plus 30h). *
;* *
;****************************************************************************
litsg equ '�' ;next character is to be output directly
hexsg equ '�' ;hexadecimal conversion signal
decsg equ '�' ;decimal conversion signal
decsgn equ '�' ;decimal conversion, leading spaces suppressed
decsgc equ '�' ;decimal conversion, use commas
repsg equ '�' ;repeat character signal
sgchk equ '�' ;all characters below this value are literals
msout proc near
pushad
push ds
push es
push ax
mov ax,cs
mov ds,ax
mov es,ax
mov di,os iobuf ;output buffer
mov bx,os msval ;parameter list
cld
msorc: lodsb ;read character
cmp al,sgchk
jc short msowc ;not conversion character
cmp al,hexsg
jz short mscvh ;hex conversion character
xor dh,dh ;decimal type flag
cmp al,decsg
jz short mscvd ;decimal conversion
mov dh,40h ;leading space suppress, bit 6
cmp al,decsgn
jz short mscvd ;decimal, suppress leading spaces
shl dh,1 ;include commas, bit 7
cmp al,decsgc
jz short mscvd ;decimal with commas
cmp al,repsg
jnz short msolc ;not repeat character
lodsb ;get number of repeats
sub al,30h ;ascii zero based
movzx cx,al ;count
lodsb ;character to repeat
rep stosb ;expand
jmp short msorc
msolc: cmp al,litsg
jnz short msowc ;not literal signal
lodsb ;no translation on character following
msowc: stosb ;write character to buffer
or al,al
jnz short msorc ;not at end
mov si,os iobuf
sub di,si ;length
dec di
; jz msox ;what?
mov cx,di
pop di ;dest
; mov ah,40h
; mov bx,1 ;stdout
; int 21h ;write line
mov ax,vseg
mov es,ax ;video segment
mov ah,7 ;attr
wrsc: lodsb
stosw
loop wrsc ;write ms to screen
msox: pop es
pop ds
popad
ret
; Binary to Hex Ascii Conversion
; ds:si->source text, es:di->output text, ds:bx->current binary parameter
mscvh: lodsb ;read character after signal
dec al
and al,7 ;number of digits (0-7 for 1-8)
shl al,2 ;times bits per digit
movzx cx,al ;number of bits minus 4
mov eax,[bx] ;get parameter
add bx,4 ;address next parameter
ror eax,cl ;bits 3-0 are ms digit
shr cx,2
inc cx ;number of digits
mshxd: mov dh,al ;save 2 digits
call cvhn ;convert al{3:0}
mov al,dh ;restore 2 digits
rol eax,4 ;pull up next digit
loop mshxd
jmp short msorc ;continue with text
; Convert Binary in al to Hex Ascii at es:[di]+
; Affects: ax, di
cvhb: cld
push ax ;save low digit
shr al,4
call cvhn ;convert high digit
pop ax ;convert low digit
cvhn: and al,0fh
or al,90h ;90-99, 9A-9F
daa ;90-99, 100-105
adc al,40h ;D0-D9, 41-46
daa ;130-139, 41-46
stosb ;store ascii 0-9, A-F
ret
; Binary to Decimal Ascii Conversion
; ds:si->source text, es:di->output text, ds:bx->current binary parameter
; dh = 80h, include commas; dh = 40h, suppress leading spaces
mscvd: lodsb ;read character after signal
xor ecx,ecx ;clear for use as index
cmp al,'w'
jz short msdwp ;16-bit conversion
cmp al,'b'
jnz short msdlp ;32-bit conversion
mov 1[bx],cl ;8-bit conversion, zero high byte of low word
msdwp: mov 2[bx],cx ;zero high word for 8/16-bit
lodsb ;get next source character
msdlp: dec al
and al,0fh
mov cl,al ;number of decimal digits (0-9 for 1-10)
mov ebp,[bx] ;get parameter
add bx,4 ;update current parameter address
push bx
msdsc: sub al,3
jnc short msdsc ;reduce al mod 3
add al,3 ;add remainder
mov bl,al ;number of digits before first comma
push si ;save place in source text
jcxz msd1 ;one digit only
lea si,dcval[ecx*4] ;index into 10� list for number of digits
msdxd: std ;count downward
lodsd ;get 10� where n is current digit
cld ;count upward
mov dl,2fh ;ascii count
msdxi: inc dl
js short msdov ;overflow
sub ebp,eax ;subtract 10� from parameter value
jnc short msdxi
msdov: add ebp,eax ;leave remainder
cmp dl,3ah
jc short msdno ;no overflow
stc
rcr ebp,1 ;make sure it propagates
mov dl,'*' ;overflow character
msdno: or dh,dl ;bits 3-0 are zero if this is a leading zero
test dh,0fh ;check whether all zeros so far
mov al,dl ;current digit
jnz short msdpc ;display non-leading-zero
mov al,' ' ;change leading zero to space
test dh,40h
jnz short msdx ;skip leading spaces and commas
msdpc: stosb ;write digit to output buffer
or dh,dh
jns short msdx ;no commas
dec bl ;decrement comma counter
jns short msdx ;no action until zero
cmp al,' '
jz short msdco ;leave leading space
mov al,','
msdco: stosb ;write comma to output buffer
mov bl,2 ;reload counter
msdx: loop msdxd ;next digit
msd1: mov ax,bp ;last digit
cmp ax,10
jc short msd1n ;no overflow
mov al,1ah ;display *
msd1n: xor al,30h
stosb
pop si ;restore current index in source text
pop bx ;restore current parameter index
jmp msorc ;continue with text
align 4
dcval equ $-4 ;10� table
dd 10,100,1000,10000,100000,1000000
dd 10000000,100000000,1000000000
msval: ;parameter list
mv1: dd 0
mv2: dd 0
mv3: dd 0
mv4: dd 0
mv5: dd 0
mv6: dd 0
mv7: dd 0
mv8: dd 0
iobuf: db 512 dup (99h) ;output buffer
msout endp
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.