home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgLangD.iso / Assembly / KBD_IO23.ASM < prev    next >
Assembly Source File  |  1986-09-25  |  6KB  |  213 lines

  1. CGROUP    GROUP    CODE_SEG, DATA_SEG
  2.     ASSUME    CS:CGROUP, DS:CGROUP
  3.  
  4.  
  5. CODE_SEG    SEGMENT PUBLIC
  6.  
  7.     PUBLIC    STRING_TO_UPPER
  8. ;-----------------------------------------------------------------------;
  9. ; This procedure converts the stinrg, using the DOS format for strings,    ;
  10. ; to all uppercase letters.                        ;
  11. ;                                    ;
  12. ;    DS:DX    Address of string buffer                ;
  13. ;-----------------------------------------------------------------------;
  14. STRING_TO_UPPER        PROC    NEAR
  15.     PUSH    AX
  16.     PUSH    BX
  17.     PUSH    CX
  18.     MOV    BX,DX
  19.     INC    BX            ;Point to character count
  20.     MOV    CL,[BX]            ;Character count in 2nd byte of buffer
  21.     XOR    CH,CH            ;Clear upper byte of count
  22. UPPER_LOOP:
  23.     INC    BX            ;Point to next character in buffer
  24.     MOV    AL,[BX]
  25.     CMP    AL,'a'            ;See if it is a lowercase letter
  26.     JB    NOT_LOWER        ;Nope
  27.     CMP    AL,'z'
  28.     JA    NOT_LOWER
  29.     ADD    AL,'A'-'a'        ;Convert to uppercase letter
  30.     MOV    [BX],AL
  31. NOT_LOWER:
  32.     LOOP    UPPER_LOOP
  33.     POP    CX
  34.     POP    BX
  35.     POP    AX
  36.     RET
  37. STRING_TO_UPPER        ENDP
  38.  
  39. ;-----------------------------------------------------------------------;
  40. ; This procedure converts a character from ASCII (hex) to a nibble (4    ;
  41. ; bits).                                ;
  42. ;                                    ;
  43. ;        AL    Character to convert                ;
  44. ; Returns:    AL    Nibble                        ;
  45. ;        DF    Set for error, cleared otherwise        ;
  46. ;-----------------------------------------------------------------------;
  47. CONVERT_HEX_DIGIT    PROC    NEAR
  48.     CMP    AL,'0'            ;Is it a legal digit?
  49.     JB    BAD_DIGIT        ;Nope
  50.     CMP    AL,'9'            ;Not sure yet
  51.     JA    TRY_HEX            ;Might be hex digit
  52.     SUB    AL,'0'            ;Is decimal digit, convert to nibble
  53.     CLC                ;Clear the carry, no error
  54.     RET
  55. TRY_HEX:
  56.     CMP    AL,'A'            ;Not sure yet
  57.     JB    BAD_DIGIT        ;Not hex
  58.     CMP    AL,'F'            ;Not sure yet
  59.     JA    BAD_DIGIT        ;Not hex
  60.     SUB    AL,'A'-10        ;Is hex, convert to nibble
  61.     CLC                ;Clear the carry, no error
  62.     RET
  63. BAD_DIGIT:
  64.     STC                ;Set the carry, error
  65.     RET
  66. CONVERT_HEX_DIGIT    ENDP
  67.  
  68.     PUBLIC    HEX_TO_BYTE
  69. ;-----------------------------------------------------------------------;
  70. ; This procedure converts the two characters at DS:DX from hex to one    ;
  71. ; byte.                                    ;
  72. ;                                    ;
  73. ;    DS:DX    Address of two characters for hex number        ;
  74. ; Returns:                                ;
  75. ;    AL    Byte                            ;
  76. ;    CF    Set for error, clear if no error            ;
  77. ;-----------------------------------------------------------------------;
  78. HEX_TO_BYTE    PROC    NEAR
  79.     PUSH    BX
  80.     PUSH    CX
  81.     MOV    BX,DX            ;Put address in BX for indirect addr
  82.     MOV    AL,[BX]            ;Get first digit
  83.     CALL    CONVERT_HEX_DIGIT
  84.     JC    BAD_HEX            ;Bad hex digit if carry set
  85.     MOV    CX,4            ;Now multiply by 16
  86.     SHL    AL,CL
  87.     MOV    AH,AL            ;Retain a copy
  88.     INC    BX            ;Get second digit
  89.     MOV    AL,[BX]
  90.     CALL    CONVERT_HEX_DIGIT
  91.     JC    BAD_HEX            ;Bad hex digit if carry set
  92.     OR    AL,AH            ;Combine two nibbles
  93.     CLC                ;Clear carry for no error
  94. DONE_HEX:
  95.     POP    CX
  96.     POP    BX
  97.     RET
  98. BAD_HEX:
  99.     STC                ;Set carry for error
  100.     JMP    DONE_HEX
  101. HEX_TO_BYTE    ENDP
  102.  
  103. ;-----------------------------------------------------------------------;
  104. ; This is a simple version of READ_STRING.                ;
  105. ;                                    ;
  106. ;    DS:DX    Address of string area                    ;
  107. ;-----------------------------------------------------------------------;
  108. READ_STRING    PROC    NEAR
  109.     PUSH    AX
  110.     MOV    AH,0Ah            ;Call for buffered keyboard input
  111.     INT    21h            ;Call DOS function for buffered input
  112.     POP    AX
  113.     RET
  114. READ_STRING    ENDP
  115.  
  116.     PUBLIC    READ_BYTE
  117. ;-----------------------------------------------------------------------;
  118. ; This procedure reads either a single ASCII character or a two-digit    ;
  119. ; hex number.  This is just a test version of READ_BYTE.        ;
  120. ;                                    ;
  121. ; Returns byte in    AL    Character code (unless AH = 0)        ;
  122. ;            AH    1 if read ASCII char            ;
  123. ;                0 if no characters read            ;
  124. ;                -1 if read a special key        ;
  125. ;                                    ;
  126. ; Uses:        HEX_TO_BYTE, STRING_TO_UPPER, READ_STRING        ;
  127. ; Reads:    KEYBOARD_INPUT, etc.                    ;
  128. ; Writes:    KEYBOARD_INPUT, etc.                    ;
  129. ;-----------------------------------------------------------------------;
  130. READ_BYTE    PROC    NEAR
  131.     PUSH    DX
  132.     MOV    CHAR_NUM_LIMIT,3    ;Allow only two characters (plus Enter)
  133.     LEA    DX,KEYBOARD_INPUT
  134.     CALL    READ_STRING
  135.     CMP    NUM_CHARS_READ,1    ;See how many characters
  136.     JE    ASCII_INPUT        ;Just one, treat as ASCII character
  137.     JB    NO_CHARACTERS        ;Only Enter key hit
  138.     CALL    STRING_TO_UPPER        ;No, convert string to uppercase
  139.     LEA    DX,CHARS        ;Address of string to convert
  140.     CALL    HEX_TO_BYTE        ;Convert string from hex to byte
  141.     JC    NO_CHARACTERS        ;Error, so return 'no characters read'
  142.     MOV    AH,1            ;Signal read one character
  143. DONE_READ:
  144.     POP    DX
  145.     RET
  146. NO_CHARACTERS:
  147.     XOR    AH,AH            ;Set to 'no characters read'
  148.     JMP    DONE_READ
  149. ASCII_INPUT:
  150.     MOV    AL,CHARS        ;Load character read
  151.     MOV    AH,1            ;Signal read one character
  152.     JMP    DONE_READ
  153. READ_BYTE    ENDP
  154.  
  155.     PUBLIC    READ_DECIMAL
  156. ;-----------------------------------------------------------------------;
  157. ; This procedure takes the output buffer of READ_STRING and converts    ;
  158. ; the string of decimal digits to a word.                ;
  159. ;                                    ;
  160. ;    AX    Word converted from decimal                ;
  161. ;    CF    Set if error, clear if no error                ;
  162. ;                                    ;
  163. ; Uses:        READ_STRING                        ;
  164. ; Reads:    KEYBOARD_INPUT, etc.                    ;
  165. ; Writes:    KEYBOARD_INPUT, etc.                    ;
  166. ;-----------------------------------------------------------------------;
  167. READ_DECIMAL    PROC    NEAR
  168.     PUSH    BX
  169.     PUSH    CX
  170.     PUSH    DX
  171.     MOV    CHAR_NUM_LIMIT,6    ;Max number is 5 digits (65535)
  172.     LEA    DX,KEYBOARD_INPUT
  173.     CALL    READ_STRING
  174.     MOV    CL,NUM_CHARS_READ    ;Get number of characters read
  175.     XOR    CH,CH            ;Set upper byte of count to 0
  176.     CMP    CL,0            ;Return error if no characters read
  177.     JLE    BAD_DECIMAL_DIGIT    ;No chars read, signal error
  178.     XOR    AX,AX            ;Start with number set to 0
  179.     XOR    BX,BX            ;Start at beginning of string
  180. CONVERT_DIGIT:
  181.     MOV    DX,10            ;Multiply number by 10
  182.     MUL    DX            ;Multiply AX by 10
  183.     JC    BAD_DECIMAL_DIGIT    ;CF set if MUL overflowed one word
  184.     MOV    DL,CHARS[BX]        ;Get the next digit
  185.     SUB    DL,'0'            ;And convert to a nibble (4 bits)
  186.     JS    BAD_DECIMAL_DIGIT    ;Bad digit if < 0
  187.     CMP    DL,9            ;Is this a bad digit?
  188.     JA    BAD_DECIMAL_DIGIT    ;Yes
  189.     ADD    AX,DX            ;No, so add it to number
  190.     INC    BX            ;Point to next character
  191.     LOOP    CONVERT_DIGIT        ;Get the next digit
  192. DONE_DECIMAL:
  193.     POP    DX
  194.     POP    CX
  195.     POP    BX
  196.     RET
  197. BAD_DECIMAL_DIGIT:
  198.     STC                ;Set carry to signal error
  199.     JMP    DONE_DECIMAL
  200. READ_DECIMAL    ENDP
  201.  
  202.  
  203. CODE_SEG    ENDS
  204.  
  205. DATA_SEG    SEGMENT PUBLIC
  206. KEYBOARD_INPUT    LABEL BYTE
  207. CHAR_NUM_LIMIT    DB    0        ;Length of input buffer
  208. NUM_CHARS_READ    DB    0        ;Number of characters read
  209. CHARS        DB    80 DUP (0)    ;A buffer for keyboard input
  210. DATA_SEG    ENDS
  211.  
  212.     END
  213.