Category : Assembly Language Source Code
Archive   : D86V372.ZIP
Filename : HEXOUT.8

Output of file : HEXOUT.8 contained in archive : D86V372.ZIP

; (C)1986 Eric Isaacson. Permission to modify or use this file is granted
; to registered A86 and D86 users only. I grant public domain to the
; .COM file that results from assembling this source file.

; HEXOUT is a program that accepts a sequence of hexadecimal numbers in its
; invocation line, and outputs the associated binary values to standard
; output. This is useful, for example, to send a sequence of control
; codes to your printer. You could type HEXOUT >PRN followed by the hex
; values you want to be sent.

; HEXOUT assumes correct input; it does not support error detection.

TAIL_BUFF EQU 081 ; we'll read command tail right where MSDOS gives it to us

MOV SI,TAIL_BUFF ; point to the command tail
L1: ; loop here to fetch every hex byte
CALL GET_HEX ; fetch the next value
JC >L2 ; jump if there were no more values
CALL OUT_VALUE ; output the resulting byte
JMP L1 ; loop for another byte

L2: ; scanning is complete
MOV AX,04C00 ; MS-DOS function-number for successful exit
INT 33 ; go back to the operating system

; GET_HEX advances SI to the next hex number, and reads that number. If we
; reach the terminating carriage-return before the next hex digit, we
; return Carry. Otherwise, we return NoCarry, with AL set to the value
; of the hex number, and SI advanced beyond the number.

LODSB ; fetch the next byte
CMP AL,0D ; is it the terminator?
STC ; set Carry in case it is
JE RET ; return Carry if it is
CALL HEX_DIGIT? ; is the byte a hex digit?
JC GET_HEX ; loop if not, to find the first hex digit
MOV AH,AL ; it is a digit: save the value in AH
LODSB ; fetch the next byte
CALL HEX_DIGIT? ; is it also a hex digit?
JC >L1 ; jump if not: 1-digit value
SHL AH,1 ; two hex digits: pack the values into AL
SHL AH,1 ; AH * 4
SHL AH,1 ; AH * 8
SHL AH,1 ; AH * 16
OR AL,AH ; AL = AH * 16 + AL -- values are now packed into AL
RET ; NoCarry set by OR signals success

L1: ; the number has a single digit
DEC SI ; retreat input pointer back to the following non-digit
MOV AL,AH ; fetch the single digit's value
CLC ; NoCarry signals success

; HEX_DIGIT? returns NoCarry if AL is an ASCII hex digit; it also transforms
; AL into the associated binary value. Return Carry if AL was not a hex
; digit.

SUB AL,'0' ; reduce decimal digits to their binary values
JC RET ; return Carry if AL was below decimal-digit range
CMP AL,10 ; was the value a decimal digit?
JB >L1 ; return NoCarry if it was
ADD AL,'0' ; restore input AL
AND AL,0DF ; coerce letters to upper case
SUB AL,'A'-10 ; reduce A--F range to 10--15
CMP AL,10 ; was input below the A--F range?
JB RET ; return Carry if it was
CMP AL,16 ; was input above the A--F range? NoCarry now set if yes
L1: ; Carry flag is now the opposite of its return value
CMC ; flip it to the correct value

; OUT_VALUE outputs AL to standard output.

PUSH AX ; push AL value onto the stack
MOV DX,SP ; MS-DOS memory-pointer now points to the AL-value
MOV CX,1 ; we will output 1 byte
MOV BX,1 ; open-file handle for standard output is 1
MOV AH,040 ; function number for MS-DOS write is 040
INT 33 ; write the AL-value to standard output
POP AX ; pop AL back off the stack

  3 Responses to “Category : Assembly Language Source Code
Archive   : D86V372.ZIP
Filename : HEXOUT.8

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: