home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgLangD.iso / Assembly / VIDEO_IO.ASM < prev   
Assembly Source File  |  1986-10-07  |  13KB  |  417 lines

  1. CGROUP    GROUP    CODE_SEG, DATA_SEG    ;Group together two segments
  2.     ASSUME    CS:CGROUP, DS:CGROUP
  3.  
  4. ;-----------------------------------------------------------------------;
  5. ; This file contains various procedures that write to the screen:    ;
  6. ;                                    ;
  7. ; WRITE_CHAR            Writes a character on the screen    ;
  8. ; WRITE_CHAR_N_TIMES        Writes N copies of one character    ;
  9. ; WRITE_STRING            Writes a string to the screen        ;
  10. ; WRITE_PATTERN            Writes a pattern on the screen        ;
  11. ; WRITE_HEX_DIGIT        Writes a single hexadecimal digit    ;
  12. ; WRITE_HEX            Writes a two-digit hex number        ;
  13. ; WRITE_DECIMAL            Writes a decimal number on the screen    ;
  14. ; WRITE_ATTRIBUTE_N_TIMES    Writes just the attribute to the screen    ;
  15. ;                                    ;
  16. ; WRITE_HEADER            Writes the header on the screen        ;
  17. ; WRITE_PROMPT_LINE        Writes the prompt line to the screen    ;
  18. ; WRITE_EDITOR_PROMPT        Displays the editor prompt        ;
  19. ; WRITE_FUNCTION_KEYS        Display the function key line        ;
  20. ;-----------------------------------------------------------------------;
  21.  
  22.  
  23. CODE_SEG    SEGMENT PUBLIC
  24.  
  25.     PUBLIC    WRITE_CHAR
  26.     EXTRN    CURSOR_RIGHT:NEAR
  27. ;-----------------------------------------------------------------------;
  28. ; This procedure outputs a character to the screen using the ROM BIOS    ;
  29. ; routines so that characters such as backspace, etc., are treated as    ;
  30. ; any other character and displayed.                    ;
  31. ;   This procedure must do a bit of work to update the cursor position.    ;
  32. ;                                    ;
  33. ;    DL    byte to print on screen.                ;
  34. ;                                    ;
  35. ; Uses:        CURSOR_RIGHT                        ;
  36. ;-----------------------------------------------------------------------;
  37. WRITE_CHAR    PROC    NEAR
  38.     PUSH    AX
  39.     PUSH    BX
  40.     PUSH    CX
  41.     PUSH    DX
  42.     MOV    AH,9        ;Call for output of character/attribute
  43.     MOV    BH,0        ;Set to display page 0
  44.     MOV    CX,1        ;Write only one character
  45.     MOV    AL,DL        ;Character to write
  46.     MOV    BL,7        ;Normal attribute
  47.     INT    10H        ;Write character and attribute
  48.     CALL    CURSOR_RIGHT    ;Now move the cursor to the next position
  49.     POP    DX
  50.     POP    CX
  51.     POP    BX
  52.     POP    AX
  53.     RET
  54. WRITE_CHAR    ENDP
  55.  
  56.  
  57.     PUBLIC    WRITE_CHAR_N_TIMES
  58. ;-----------------------------------------------------------------------;
  59. ;  This procedure writes more than one copy of a character        ;
  60. ;                                    ;
  61. ;    DL    Character code                        ;
  62. ;    CX    Number of times to write the character            ;
  63. ;                                    ;
  64. ; Uses:        WRITE_CHAR                        ;
  65. ;-----------------------------------------------------------------------;
  66. WRITE_CHAR_N_TIMES    PROC    NEAR
  67.     PUSH    CX
  68. N_TIMES:
  69.     CALL    WRITE_CHAR        ;Write one copy of the character
  70.     LOOP    N_TIMES            ;Keep writing for N times
  71.     POP    CX
  72.     RET
  73. WRITE_CHAR_N_TIMES    ENDP
  74.  
  75.  
  76.     PUBLIC    WRITE_STRING
  77. ;-----------------------------------------------------------------------;
  78. ;  This procedure writes a string of characters to the screen.  The    ;
  79. ;  string must end with        DB    0                ;
  80. ;                                    ;
  81. ;    DS:DX    address of the string                    ;
  82. ;                                    ;
  83. ; Uses:        WRITE_CHAR                        ;
  84. ;-----------------------------------------------------------------------;
  85. WRITE_STRING    PROC    NEAR
  86.     PUSH    AX
  87.     PUSH    DX
  88.     PUSH    SI
  89.     PUSHF                ;Save direction flag
  90.     CLD                ;Set direction for increment (forward)
  91.     MOV    SI,DX            ;Place address into SI for LODSB
  92. STRING_LOOP:
  93.     LODSB                ;Get a character into the AL register
  94.     OR    AL,AL            ;Have we found the zero yet?
  95.     JZ    END_OF_STRING        ;Yes, we are done writing the string
  96.     MOV    DL,AL            ;No, write character
  97.     CALL    WRITE_CHAR        ;Write the character
  98.     JMP    STRING_LOOP        ;Read in the next character
  99. END_OF_STRING:
  100.     POPF                ;Restore direction flag
  101.     POP    SI
  102.     POP    DX
  103.     POP    AX
  104.     RET
  105. WRITE_STRING    ENDP
  106.  
  107.  
  108.     PUBLIC    WRITE_PATTERN
  109. ;-----------------------------------------------------------------------;
  110. ;  This procedure writes a line to the screen, based on data in the    ;
  111. ;  form                                    ;
  112. ;                                    ;
  113. ;    DB    {character, number of times to write character}, 0    ;
  114. ;  Where '{x}' means that x can be repeated any number of times        ;
  115. ;    DS:DX    address of above data statement                ;
  116. ;                                    ;
  117. ; Uses:        WRITE_CHAR_N_TIMES                    ;
  118. ;-----------------------------------------------------------------------;
  119. WRITE_PATTERN    PROC    NEAR
  120.     PUSH    AX
  121.     PUSH    CX
  122.     PUSH    DX
  123.     PUSH    SI
  124.     PUSHF                ;Save the direction flag
  125.     CLD                ;Set direction flag for increment
  126.     MOV    SI,DX            ;Move offset into SI register for LODSB
  127. PATTERN_LOOP:
  128.     LODSB                ;Get character data into AL
  129.     OR    AL,AL            ;Is it he end of data (0H)?
  130.     JZ    END_PATTERN        ;Yes, return
  131.     MOV    DL,AL            ;No, set up to write character N times
  132.     LODSB                ;Get the repeat count in AL
  133.     MOV    CL,AL            ;And put in CX for WRITE_CHAR_N_TIMES
  134.     XOR    CH,CH            ;Zero upper byte of CX
  135.     CALL    WRITE_CHAR_N_TIMES    ;Write N copies of this character
  136.     JMP    PATTERN_LOOP        ;Get next part of the pattern
  137. END_PATTERN:
  138.     POPF                ;Restore direction flag
  139.     POP    SI
  140.     POP    DX
  141.     POP    CX
  142.     POP    AX
  143.     RET
  144. WRITE_PATTERN    ENDP
  145.  
  146.  
  147.     PUBLIC    WRITE_HEX_DIGIT
  148. ;-----------------------------------------------------------------------;
  149. ; This procedure converts the lower 4 bits of DL to a hex digit and    ;
  150. ; writes it to the screen.                        ;
  151. ;                                    ;
  152. ;    DL    Lower 4 bits contain number to be printed in hex.    ;
  153. ;                                    ;
  154. ; Uses:        WRITE_CHAR                        ;
  155. ;-----------------------------------------------------------------------;
  156. WRITE_HEX_DIGIT    PROC    NEAR
  157.     PUSH    DX            ;Save registers used
  158.     CMP    DL,10            ;Is this nibble <10?
  159.     JAE    HEX_LETTER        ;No, convert to a letter
  160.     ADD    DL,"0"            ;Yes, convert to a digit
  161.     JMP    SHORT WRITE_DIGIT
  162. HEX_LETTER:
  163.     ADD    DL,"A"-10        ;Convert to hex letter
  164. WRITE_DIGIT:
  165.     CALL    WRITE_CHAR
  166.     POP    DX            ;Restore old value of AX
  167.     RET
  168. WRITE_HEX_DIGIT    ENDP
  169.  
  170.  
  171.     PUBLIC    WRITE_HEX
  172. ;-----------------------------------------------------------------------;
  173. ; This procedure converts the byte in the AL register to hex and writes    ;
  174. ; the two hex digits at the current cursor position.            ;
  175. ;                                    ;
  176. ;    DL    byte to be converted to hex.                ;
  177. ;                                    ;
  178. ; Uses:        WRITE_HEX_DIGIT                        ;
  179. ;-----------------------------------------------------------------------;
  180. WRITE_HEX    PROC    NEAR    ;Entry point.
  181.     PUSH    CX        ;Save registers used in this procedure
  182.     PUSH    DX
  183.     MOV    DH,DL        ;Make a copy of byte
  184.     MOV    CX,4        ;Get the upper nibble in DL
  185.     SHR    DL,CL
  186.     CALL    WRITE_HEX_DIGIT    ;Convert the nibble in DL to hex and print
  187.     MOV    DL,DH        ;Get lower nibble into DL
  188.     AND    DL,0FH
  189.     CALL    WRITE_HEX_DIGIT
  190.     POP    DX
  191.     POP    CX
  192.     RET
  193. WRITE_HEX    ENDP
  194.  
  195.  
  196.     PUBLIC    WRITE_DECIMAL
  197. ;-----------------------------------------------------------------------;
  198. ; This procedure writes a 16-bit, unsigned number in decimal notation.    ;
  199. ;                                    ;
  200. ;    DX    N : 16-bit, unsigned number                ;
  201. ;                                    ;
  202. ; Uses:        WRITE_CHAR, WRITE_HEX_DIGIT                ;
  203. ;-----------------------------------------------------------------------;
  204. WRITE_DECIMAL    PROC    NEAR
  205.     PUSH    AX            ;Save registers used here
  206.     PUSH    CX
  207.     PUSH    DX
  208.     PUSH    SI
  209.     MOV    AX,DX            ;Put the number into AX
  210.     MOV    SI,10            ;Will divide by 10 using SI
  211.     XOR    CX,CX            ;Count of digits placed on stack
  212. NON_ZERO:
  213.     XOR    DX,DX            ;Set upper word of N to 0
  214.     DIV    SI            ;Calculate N/10 and (N mod 10)
  215.     PUSH    DX            ;Push one digit onto the stack
  216.     INC    CX            ;One more digit added
  217.     OR    AX,AX            ;N = 0 yet?
  218.     JNE    NON_ZERO        ;Nope, continue
  219. WRITE_DIGIT_LOOP:
  220.     POP    DX            ;Get the digits in reverse order
  221.     CALL    WRITE_HEX_DIGIT        ;Write a single digit
  222.     LOOP    WRITE_DIGIT_LOOP    ;Get the next digit
  223. END_DECIMAL:
  224.     POP    SI
  225.     POP    DX
  226.     POP    CX
  227.     POP    AX
  228.     RET
  229. WRITE_DECIMAL    ENDP
  230.  
  231.  
  232.     PUBLIC    WRITE_ATTRIBUTE_N_TIMES
  233.     EXTRN    CURSOR_RIGHT:NEAR
  234. ;-----------------------------------------------------------------------;
  235. ; This procedure sets the attribute for N characters starting at the    ;
  236. ; current cursor position.                        ;
  237. ;                                    ;
  238. ;    CX    Number of characters to set attribute for        ;
  239. ;    DL    New attribute for characters                ;
  240. ;                                    ;
  241. ; Uses:        CURSOR_RIGHT                        ;
  242. ;-----------------------------------------------------------------------;
  243. WRITE_ATTRIBUTE_N_TIMES        PROC    NEAR
  244.     PUSH    AX
  245.     PUSH    BX
  246.     PUSH    CX
  247.     PUSH    DX
  248.     MOV    BL,DL            ;Set attribute to new attribute
  249.     XOR    BH,BH            ;Set display page to zero
  250.     MOV    DX,CX            ;CX is used by the BIOS routines
  251.     MOV    CX,1            ;Set attribute for one character
  252. ATTR_LOOP:
  253.     MOV    AH,8            ;Read character under cursor
  254.     INT    10H
  255.     MOV    AH,9            ;Write attribute/character
  256.     INT    10H
  257.     CALL    CURSOR_RIGHT
  258.     DEC    DX            ;Set attribute for N characters?
  259.     JNZ    ATTR_LOOP        ;No, continue
  260.     POP    DX
  261.     POP    CX
  262.     POP    BX
  263.     POP    AX
  264.     RET
  265. WRITE_ATTRIBUTE_N_TIMES        ENDP
  266.  
  267.  
  268.  
  269.     PUBLIC    WRITE_HEADER
  270. DATA_SEG    SEGMENT PUBLIC
  271.     EXTRN    HEADER_LINE_NO:BYTE
  272.     EXTRN    HEADER_PART_1:BYTE
  273.     EXTRN    HEADER_PART_2:BYTE
  274.     EXTRN    DISK_DRIVE_NO:BYTE
  275.     EXTRN    CURRENT_SECTOR_NO:WORD
  276.     EXTRN    FILE_FLAG:BYTE
  277.     EXTRN    FILE_HEADER:BYTE
  278.     EXTRN    FILE_NAME:BYTE
  279. DATA_SEG    ENDS
  280.     EXTRN    GOTO_XY:NEAR, CLEAR_TO_END_OF_LINE:NEAR
  281. ;-----------------------------------------------------------------------;
  282. ;  This procedure writes the header with disk drive and sector number.    ;
  283. ;                                    ;
  284. ; Uses:        GOTO_XY, WRITE_STRING, WRITE_CHAR, WRITE_DECIMAL    ;
  285. ;        CLEAR_TO_END_OF_LINE                    ;
  286. ; Reads:    HEADER_LINE_NO, HEADER_PART_1, HEADER_PART_2        ;
  287. ;        DISK_DRIVE_NO, CURRENT_SECTOR_NO, FILE_FLAG        ;
  288. ;        FILE_HEADER, FILE_NAME                    ;
  289. ;-----------------------------------------------------------------------;
  290. WRITE_HEADER    PROC    NEAR
  291.     PUSH    DX
  292.     XOR    DL,DL            ;Move cursor to header line number
  293.     MOV    DH,HEADER_LINE_NO
  294.     CALL    GOTO_XY
  295.  
  296.     CMP    FILE_FLAG,1        ;Are we in file mode?
  297.     JE    WRITE_OFFSET        ;Yes, then don't write drive number
  298.     LEA    DX,HEADER_PART_1    ;Display "Disk "
  299.     CALL    WRITE_STRING
  300.     MOV    DL,DISK_DRIVE_NO    ;Display the disk drive number
  301.     ADD    DL,'A'            ;Print drives A, B, ...
  302.     CALL    WRITE_CHAR
  303. WRITE_OFFSET:
  304.     LEA    DX,HEADER_PART_2    ;Display "     Sector "
  305.     CALL    WRITE_STRING
  306.     MOV    DX,CURRENT_SECTOR_NO    ;Display the sector number
  307.     CALL    WRITE_DECIMAL
  308.     CMP    FILE_FLAG,1        ;Are we in file mode?
  309.     JNE    DONT_WRITE_FILE_HEADER    ;No, then don't write the file header
  310.     LEA    DX,FILE_HEADER        ;Yes, display the file header
  311.     CALL    WRITE_STRING
  312.     LEA    DX,FILE_NAME        ;Write the name of the file
  313.     CALL    WRITE_STRING
  314. DONT_WRITE_FILE_HEADER:
  315.     CALL    CLEAR_TO_END_OF_LINE    ;Clear rest of sector number
  316.     POP    DX
  317.     RET
  318. WRITE_HEADER    ENDP
  319.  
  320.  
  321.     PUBLIC    WRITE_PROMPT_LINE
  322.     EXTRN    CLEAR_TO_END_OF_LINE:NEAR
  323.     EXTRN    GOTO_XY:NEAR
  324. DATA_SEG    SEGMENT PUBLIC
  325.     EXTRN    PROMPT_LINE_NO:BYTE
  326. DATA_SEG    ENDS
  327. ;-----------------------------------------------------------------------;
  328. ; This procedure writes the prompt line to the screen and clears the    ;
  329. ; end of the line.                            ;
  330. ;                                    ;
  331. ;    DS:DX    Address of the prompt-line message            ;
  332. ;                                    ;
  333. ; Uses:        WRITE_STRING, CLEAR_TO_END_OF_LINE, GOTO_XY        ;
  334. ; Reads:    PROMPT_LINE_NO                        ;
  335. ;-----------------------------------------------------------------------;
  336. WRITE_PROMPT_LINE    PROC    NEAR
  337.     PUSH    DX
  338.     XOR    DL,DL            ;Write the prompt line and
  339.     MOV    DH,PROMPT_LINE_NO    ; the cursor there
  340.     CALL    GOTO_XY
  341.     POP    DX
  342.     CALL    WRITE_STRING
  343.     CALL    CLEAR_TO_END_OF_LINE
  344.     RET
  345. WRITE_PROMPT_LINE    ENDP
  346.  
  347.  
  348.     PUBLIC    WRITE_EDITOR_PROMPT
  349. DATA_SEG    SEGMENT PUBLIC
  350.     EXTRN    EDITOR_PROMPT:BYTE
  351. DATA_SEG    ENDS
  352. ;-----------------------------------------------------------------------;
  353. ; This procedure writes the editor prompt line.  We've defined it as    ;
  354. ; a procedure since we need to switch to the Edit prompt in so many    ;
  355. ; places.                                ;
  356. ;                                    ;
  357. ; Uses:        WRITE_PROMPT_LINE                    ;
  358. ; Reads:    EDITOR_PROMPT                        ;
  359. ;-----------------------------------------------------------------------;
  360. WRITE_EDITOR_PROMPT    PROC    NEAR
  361.     PUSH    DX
  362.     LEA    DX,EDITOR_PROMPT
  363.     CALL    WRITE_PROMPT_LINE
  364.     POP    DX
  365.     RET
  366. WRITE_EDITOR_PROMPT    ENDP
  367.  
  368.  
  369. DATA_SEG    SEGMENT PUBLIC
  370.     EXTRN    FUNCTION_KEY_LINE_NO:BYTE
  371.     EXTRN    FUNCTION_KEY_LINE:BYTE
  372. DATA_SEG    ENDS
  373.     EXTRN    GOTO_XY:NEAR, CURSOR_RIGHT:NEAR
  374.     PUBLIC    WRITE_FUNCTION_KEYS
  375. ;-----------------------------------------------------------------------;
  376. ; This procedure writes the function-key line in inverse video, with    ;
  377. ; the key numbers in normal video.                    ;
  378. ;                                    ;
  379. ; Uses:        GOTO_XY, WRITE_STRING, WRITE_ATTRIBUTE_N_TIMES        ;
  380. ;        CURSOR_RIGHT                        ;
  381. ; Reads:    FUNCTION_KEY_LINE                    ;
  382. ;-----------------------------------------------------------------------;
  383. WRITE_FUNCTION_KEYS    PROC    NEAR
  384.     PUSH    AX
  385.     PUSH    BX
  386.     PUSH    CX
  387.     PUSH    DX
  388.     XOR    DL,DL            ;Start a left of screen
  389.     MOV    DH,FUNCTION_KEY_LINE_NO    ;And the bottom
  390.     CALL    GOTO_XY
  391.     PUSH    DX            ;Save start of line
  392.     LEA    DX,FUNCTION_KEY_LINE
  393.     CALL    WRITE_STRING
  394.     POP    DX            ;Restore start of line
  395.     CALL    GOTO_XY            ;Return to the start of this line
  396.     MOV    AX,9            ;Use as a counter
  397.     MOV    DL,70H            ;Attribute for inverse video
  398.     MOV    CX,6            ;Write 6 characters in inverse
  399. FUNCTION_KEY_LOOP:
  400.     CALL    CURSOR_RIGHT        ;Skip over the number
  401.     CALL    WRITE_ATTRIBUTE_N_TIMES    ;Write inverse video for 6 characters
  402.     CALL    CURSOR_RIGHT        ;Skip gap
  403.     DEC    AX            ;Done yet?
  404.     JNZ    FUNCTION_KEY_LOOP    ;No, invert another word
  405.     CALL    CURSOR_RIGHT        ;Skip the last gap
  406.     CALL    WRITE_ATTRIBUTE_N_TIMES    ;Invert the 10th word
  407.     POP    DX
  408.     POP    CX
  409.     POP    BX
  410.     POP    AX
  411.     RET
  412. WRITE_FUNCTION_KEYS    ENDP
  413.  
  414. CODE_SEG    ENDS
  415.  
  416.     END
  417.