home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / assemblr / library / nor_asm / kbd_io23.asm < prev    next >
Assembly Source File  |  1989-05-17  |  7KB  |  236 lines

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