home *** CD-ROM | disk | FTP | other *** search
/ PC Underground / UNDERGROUND.ISO / share / d86 / hexout.8 < prev   
Text File  |  1987-04-06  |  4KB  |  94 lines

  1. ;---------------
  2. ;   HEXOUT
  3. ;---------------
  4.  
  5. ; (C)1986 Eric Isaacson.  Permission to modify or use this file is granted
  6. ;    to registered A86 and D86 users only.  I grant public domain to the
  7. ;    .COM file that results from assembling this source file.
  8.  
  9. ; HEXOUT is a program that accepts a sequence of hexadecimal numbers in its
  10. ;   invocation line, and outputs the associated binary values to standard
  11. ;   output.  This is useful, for example, to send a sequence of control
  12. ;   codes to your printer.  You could type HEXOUT >PRN followed by the hex
  13. ;   values you want to be sent.
  14.  
  15. ; HEXOUT assumes correct input; it does not support error detection.
  16.  
  17.  
  18. TAIL_BUFF EQU 081   ; we'll read command tail right where MSDOS gives it to us
  19.  
  20. HEXOUT:
  21.   MOV SI,TAIL_BUFF  ; point to the command tail
  22. L1:            ; loop here to fetch every hex byte
  23.   CALL GET_HEX        ; fetch the next value
  24.   JC >L2        ; jump if there were no more values
  25.   CALL OUT_VALUE    ; output the resulting byte
  26.   JMP L1        ; loop for another byte
  27.  
  28. L2:            ; scanning is complete
  29.   MOV AX,04C00        ; MS-DOS function-number for successful exit
  30.   INT 33        ; go back to the operating system
  31.  
  32.  
  33. ; GET_HEX advances SI to the next hex number, and reads that number.  If we
  34. ;   reach the terminating carriage-return before the next hex digit, we
  35. ;   return Carry.  Otherwise, we return NoCarry, with AL set to the value
  36. ;   of the hex number, and SI advanced beyond the number.
  37.  
  38. GET_HEX:
  39.   LODSB         ; fetch the next byte
  40.   CMP AL,0D        ; is it the terminator?
  41.   STC            ; set Carry in case it is
  42.   JE RET        ; return Carry if it is
  43.   CALL HEX_DIGIT?   ; is the byte a hex digit?
  44.   JC GET_HEX        ; loop if not, to find the first hex digit
  45.   MOV AH,AL        ; it is a digit: save the value in AH
  46.   LODSB         ; fetch the next byte
  47.   CALL HEX_DIGIT?   ; is it also a hex digit?
  48.   JC >L1        ; jump if not: 1-digit value
  49.   SHL AH,1        ; two hex digits: pack the values into AL
  50.   SHL AH,1        ; AH * 4
  51.   SHL AH,1        ; AH * 8
  52.   SHL AH,1        ; AH * 16
  53.   OR AL,AH        ; AL = AH * 16 + AL -- values are now packed into AL
  54.   RET            ; NoCarry set by OR signals success
  55.  
  56. L1:            ; the number has a single digit
  57.   DEC SI        ; retreat input pointer back to the following non-digit
  58.   MOV AL,AH         ; fetch the single digit's value
  59.   CLC            ; NoCarry signals success
  60.   RET
  61.  
  62.  
  63. ; HEX_DIGIT? returns NoCarry if AL is an ASCII hex digit; it also transforms
  64. ;   AL into the associated binary value.  Return Carry if AL was not a hex
  65. ;   digit.
  66.  
  67. HEX_DIGIT?:
  68.   SUB AL,'0'        ; reduce decimal digits to their binary values
  69.   JC RET        ; return Carry if AL was below decimal-digit range
  70.   CMP AL,10        ; was the value a decimal digit?
  71.   JB >L1        ; return NoCarry if it was
  72.   ADD AL,'0'        ; restore input AL
  73.   AND AL,0DF        ; coerce letters to upper case
  74.   SUB AL,'A'-10     ; reduce A--F range to 10--15
  75.   CMP AL,10        ; was input below the A--F range?
  76.   JB RET        ; return Carry if it was
  77.   CMP AL,16        ; was input above the A--F range?  NoCarry now set if yes
  78. L1:            ; Carry flag is now the opposite of its return value
  79.   CMC            ; flip it to the correct value
  80.   RET
  81.  
  82.  
  83. ; OUT_VALUE outputs AL to standard output.
  84.  
  85. OUT_VALUE:
  86.   PUSH AX        ; push AL value onto the stack
  87.   MOV DX,SP        ; MS-DOS memory-pointer now points to the AL-value
  88.   MOV CX,1        ; we will output 1 byte
  89.   MOV BX,1        ; open-file handle for standard output is 1
  90.   MOV AH,040        ; function number for MS-DOS write is 040
  91.   INT 33        ; write the AL-value to standard output
  92.   POP AX        ; pop AL back off the stack
  93.   RET
  94.