Assembly Language: Video Character Interface

This section has a set of code examples for writing character data to a PC in 80 character by 25 line mode. The first routine will check the video mode, and if it is a standard mode, the code returns with a no carry condition and starts using the standard video BIOS routines to perform the requested functions. These routines provide many code entry points where other programs may call in. Before using any of the video routines, the program must call the reset_video routine to initialize and make ready the other video calls. Some of the video display routines will respond to video display escape codes. Most of the escape codes deal with standard cursor control functions. There is an example of table selection jumping code.

Most computers use a raster graphics video system. The data is sent to the monitor as rows from left to right that are arranged from top to bottom. The first data bit sent goes to the upper left corner and the last data bit in a frame goes to the lower right corner. When addressing video RAM, the memory may be divided into rows that can be divided into columns. A fundamental understanding of this system is necessary when translating a row and column position into the actual video RAM address for a character or pixel location.

 

;set of video display routines
.MODEL small
  public    reset_video
  public    clear_screen
  public    get_cursor_position, set_cursor_position
    ;write character in AL, use TTY method
  public    write_to_screen
    ;write string indexed by SI using TTY
  public    write_asciiz_string
    ;write character in AL and display control codes
  public    display_character
  public    save_screen, restore_screen
    ;set by program to activate escape code functions
  public    esc_flag
  public    normal_attribute
  public    scroll_screen_up, scroll_screen_down
  public    screen_buffer, cursor_port
.DATA
;video data variables
  even
cursor          dw  0
save_cursor     dw  0
cursor_port     dw  3B4H

screen_buffer   dw  2001 dup(0)
esc_flag        db  0
esc_on_flag     db  0
esc_y_flag      db  0
esc_y_line      db  0
video_hw_mode   db  0
normal_attribute   db  07H

 ;jump table used for ESC codes
esc_jmp_table  db   "A"
      dw   write_esc_a
      db   "B"
      dw   write_esc_b
      db   "C"
      dw   write_esc_c
      db   "D"
      dw   write_esc_d
      db   "H"
      dw   write_esc_h
      db   "I"
      dw   write_esc_i
      db   "J"
      dw   write_esc_j
      db   "K"
      dw   write_esc_k
      db   "Y"
      dw   write_esc_y
      db   0,0,0

.CODE
;******************  $$$$$$$$$$$$$  ******************
reset_video    proc near
;this routine needs to be called before any other video
; function routines to start up the video system
;on exit if carry set then video mode less than 80 columns
     push ax
     push bx
     mov  ah,15
     int  10H                 ;check current video mode
     cmp  ah,80
     jae  reset_video_80_b    ;branch if 80+ columns
       ;video is less than 80 columns
     stc       ;set for error condition on exit
     jmp  short reset_video_exit_b
reset_video_80_b:
     mov  video_hw_mode,0FFH
     mov  normal_attribute,07H
     clc
reset_video_exit_b:
     pop  bx
     pop  ax
     ret
reset_video    endp
;################################################
;  **************  ############  ****************
clear_screen   proc near
  ;clear screen using BIOS calls
     push ax
     push cx
     push dx
     push bx
     mov  ax,600H
     mov  cx,0000H
     mov  dh,24
     mov  dl,79
     mov  bh,normal_attribute
     int  10H
     xor  dx,dx
     call set_cursor_position
     pop  bx
     pop  dx
     pop  cx
     pop  ax
     ret
clear_screen   endp
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
;**************  ^^^^^^^^^^^^  ***************
set_cursor_position proc near
;set cursor with BIOS call
;on entry have DX set for new cursor position
     push ax
     push bx
     push dx
     mov  ah,2
     mov  cursor,dx
     xor  bx,bx
     int  10H
     pop  dx
     pop  bx
     pop  ax
     ret
set_cursor_position endp
;-----------------------------------------
;************  %%%%%%%%%%%%%  ************
get_cursor_position proc near
;on exit DX has current cursor position
     mov  dx,cursor
     ret
get_cursor_position endp
;__________________________________
;*********** -------- *************
write_esc_y_on:
     cmp  esc_y_flag,0FFH
     jne  write_esc_y_on1
     sub  al,20H
     mov  esc_y_line,al
     mov  esc_y_flag,0FH
     jmp  write_to_screen_x
write_esc_y_on1:
     sub  al,20H
     mov  dl,al
     mov  dh,esc_y_line
     cmp  dh,24
     ja   write_esc_y_er
     cmp  dl,79
     ja   write_esc_y_er
     call set_cursor_position
write_esc_y_er:
     mov  esc_y_flag,0
     mov  esc_on_flag,0
     jmp  write_to_screen_x
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
write_esc_data:
     cmp  esc_y_flag,0
     jne  write_esc_y_on
     lea  bx,esc_jmp_table
write_esc_data_l:
     cmp  al,[bx]
     je   write_esc_data_jmp
     add  bx,3
     cmp  byte ptr[bx],0
     jne  write_esc_data_l
     mov  esc_on_flag,0
     jmp  write_to_screen_x
write_esc_data_jmp:
     mov  bx,[bx+1]          ;perform Table Lookup Jump
     jmp  bx
;---------------------------------
;***********  %%%%%%  ************
write_to_screen     proc near
;on entry AL has ASCII character for TTY output
; this code uses the system BIOS calls for display functions
     push ax
     push bx
     push cx
     push dx
     cmp  esc_on_flag,0
     jne  write_esc_data
     mov  bl,normal_attribute
     cmp  al,20H
     jb   write_to_screen_c
write_to_screen_0:
     mov  cx,01
       mov  bh,0
     mov  ah,9
     int  10H
     mov  dx,cursor
     cmp  dl,79
     je   write_to_screen_1
     inc  dl
     call set_cursor_position
     jmp  short write_to_screen_x
write_to_screen_1:
     mov  dl,0
     cmp  dh,24
     je   write_to_screen_2
     inc  dh
     call set_cursor_position
     jmp  short write_to_screen_x
write_to_screen_2:
     call set_cursor_position
     call scroll_screen_up
write_to_screen_x   proc near
     pop  dx
     pop  cx
     pop  bx
     pop  ax
     ret
write_to_screen_x   endp
write_to_screen_c:
;  check for special keyboard control codes
     mov  dx,cursor
     cmp  al,0DH
     je   write_to_screen_cr
     cmp  al,0AH
     je   write_to_screen_lf
     cmp  al,09H
     je   write_to_screen_tab
     cmp  al,0CH
     je   write_to_screen_ff
     cmp  al,08H
     je   write_to_screen_bs
     cmp  al,1BH
     je   write_to_screen_esc
     jmp  write_to_screen_0  ;branch if unknown code
write_to_screen_cr:
     mov  dl,0
     call set_cursor_position
     jmp  write_to_screen_x
write_to_screen_lf:
     cmp  dh,24
     je   write_to_screen_lf1
     inc  dh
     call set_cursor_position
     jmp  write_to_screen_x
write_to_screen_lf1:
     call scroll_screen_up
     jmp  write_to_screen_x
write_to_screen_tab:
     and  dl,0F8H
     add  dl,8
     cmp  dl,80
     je   write_to_screen_tab1
     call set_cursor_position
     jmp  write_to_screen_x
write_to_screen_tab1:
     mov  dl,0
     cmp  dh,24
     je   write_to_screen_tab2
     inc  dh
     call set_cursor_position
     jmp  write_to_screen_x
write_to_screen_tab2:
     call set_cursor_position
     call scroll_screen_up
     jmp  write_to_screen_x
write_to_screen_ff:
     call clear_screen
     jmp  write_to_screen_x
write_to_screen_bs:
     or   dl,dl
     jz   write_to_screen_bsx
     dec  dl
     call set_cursor_position
write_to_screen_bsx:
     jmp  write_to_screen_x
write_to_screen_esc:
     cmp  esc_flag,0
     jne  write_to_screen_esc_1
     mov  esc_on_flag,0FFH
     jmp  write_to_screen_x
write_to_screen_esc_1:
     jmp  write_to_screen_0
write_to_screen     endp
;++++++++++++++++++++++++++++++++++++++++++++
;*************  <<<<<< >>>>>>  **************
  ;the following are for processing escape string functions
write_esc_a    proc near
;move cursor up one line
     mov  dx,cursor
     cmp  dh,0
     je   write_esc_a_0
     dec  dh
     call set_cursor_position
write_esc_a_0:
     mov  esc_on_flag,0
     jmp  write_to_screen_x
write_esc_a    endp
write_esc_b    proc near
;move cursor down one line
     mov  dx,cursor
     cmp  dh,24
     je   write_esc_b_0
     inc  dh
     call set_cursor_position
write_esc_b_0:
     mov  esc_on_flag,0
     jmp  write_to_screen_x
write_esc_b    endp
write_esc_c    proc near
;move cursor right one character
     mov  dx,cursor
     cmp  dl,79
     je   write_esc_c_0
     inc  dl
     call set_cursor_position
write_esc_c_0:
     mov  esc_on_flag,0
     jmp  write_to_screen_x
write_esc_c    endp
write_esc_d    proc near
;move cursor left one character
     mov  dx,cursor
     cmp  dl,0
     je   write_esc_d_0
     dec  dl
     call set_cursor_position
write_esc_d_0:
     mov  esc_on_flag,0
     jmp  write_to_screen_x
write_esc_d    endp
write_esc_h    proc near
;move cursor to top left position
     xor  dx,dx
     call set_cursor_position
     mov  esc_on_flag,0
     jmp  write_to_screen_x
write_esc_h    endp
write_esc_i    proc near
;move cursor up with scroll if on top line
     mov  dx,cursor
     cmp  dh,0
     je   write_esc_i_0
     dec  dh
     call set_cursor_position
     mov  esc_on_flag,0
     jmp  write_to_screen_x
write_esc_i_0:
     call scroll_screen_down
     mov  esc_on_flag,0
     jmp  write_to_screen_x
write_esc_i    endp
write_esc_j    proc near
;erase from cursor to end of screen
     push cx
     push bx
     mov  ax,cursor
     mov  cx,79
     sub  cl,al
write_esc_j2:
     cmp  ah,24
     je   write_esc_j1
     add  cx,80
     inc  ah
     jmp  write_esc_j2
write_esc_j1:
     jcxz write_esc_j3
     mov  bl,normal_attribute
     mov  al,20H
     add  cx,1
     mov  bh,0
     mov  ah,9
     int  10H
write_esc_j3:
     pop  bx
     pop  cx
     mov  esc_on_flag,0
     jmp  write_to_screen_x
write_esc_j    endp
write_esc_k    proc near
;erase from cursor to end of line
     push cx
     push bx
     mov  ax,cursor
     mov  cx,79
     sub  cl,al
     jcxz write_esc_k1
     mov  bl,normal_attribute
     mov  al,20H
     add  cx,1
     mov  bh,0
     mov  ah,9
     int  10H
write_esc_k1:
     pop  bx
     pop  cx
     mov  esc_on_flag,0
     jmp  write_to_screen_x
write_esc_k    endp
write_esc_y    proc near
;set cursor position
     mov  esc_y_flag,0FFH
     jmp  write_to_screen_x
write_esc_y    endp
;_______________________________________________
;************  <<<<<<<<< >>>>>>>>>> ************
display_character   proc near
;on entry AL has character for output using BIOS calls
     push ax
     push bx
     push dx
     push cx
     mov  bl,normal_attribute
     mov  ah,9
     mov  bh,0
     mov  cx,01
     int  10H            ;BIOS call to display
      ;reset cursor position for next character
     mov  dx,cursor
     cmp  dl,79          ;is this end of line ???
       ;branch if end of current line
     je   display_character_1
     inc  dl             ;index next column position
     call set_cursor_position
       ;go to exit subroutine
     jmp  short display_character_x
display_character_1:
     mov  dl,0           ;index start of line
     cmp  dh,24          ;is this last line ????
       ;branch if last line on screen
     je   display_character_2
     inc  dh             ;index next line
     call set_cursor_position
       ;go to exit subroutine
     jmp  short display_character_x
display_character_2:
     call set_cursor_position
      ;scroll screen up one line for a new line
     call scroll_screen_up
display_character_x:
  ;exit subroutine
     pop  cx
     pop  dx
     pop  bx
     pop  ax
     ret
display_character   endp
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
;**************  ^^^^^^^^^^  ***************
write_asciiz_string proc near
;on entry have SI indexing ASCIIZ data
     mov  al,[si]
     or   al,al
     jz   write_asciiz_string_x
     call write_to_screen
     inc  si
     jmp  write_asciiz_string
write_asciiz_string_x:
     ret
write_asciiz_string endp
;|||||||||||||||||||||||||||||||||||||||||||
;***************  #########  ***************
scroll_screen_up    proc near
  ;routine to scroll the video screen up one line
     push ax
     push bx
     push cx
     push dx
     mov  ax,601H
     xor  cx,cx
     mov  dh,24
     mov  dl,79
     mov  bh,normal_attribute
     int  10H
     pop  dx
     pop  cx
     pop  bx
     pop  ax
     ret
scroll_screen_up    endp
;***********  @@@@@@@  ************
scroll_screen_down  proc near
  ;routine to scroll the video screen down one line
   ;use BIOS call to scroll screen down
     push ax
     push bx
     push cx
     push dx
     mov  ax,701H
     xor  cx,cx
     mov  dh,24
     mov  dl,79
     mov  bh,normal_attribute
     int  10H
     pop  dx
     pop  cx
     pop  bx
     pop  ax
     ret
scroll_screen_down  endp
;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
;***********  &&&&&  ***********
save_screen    proc near
  ;routine to save video RAM for later recall
   ;this routine only has one video buffer
    ; and can only save one screen of data
  ;save video buffer with BIOS calls
     push ax
     push bx
     push dx
     push si
     push di
     lea  di,screen_buffer
     mov  si,cursor
     mov  save_cursor,si
     xor  dx,dx
save_screen_loop:
     call set_cursor_position
     mov  ah,8
     mov  bh,0
     int  10H
     cld
     stosw
     inc  dl
     cmp  dl,80
     jb   save_screen_loop
     mov  dl,0
     inc  dh
     cmp  dh,25
     jb   save_screen_loop
     mov  dx,si
     call set_cursor_position
     pop  di
     pop  si
     pop  dx
     pop  bx
     pop  ax
     ret
save_screen    endp
;***********  ////// \\\\  ************
restore_screen proc near
  ;restore video buffer from video save buffer
     push ax
     push bx
     push cx
     push dx
     push si
     lea  si,screen_buffer
     xor  dx,dx
restore_screen_loop:
     call set_cursor_position
     cld
     lodsw
     mov  bl,ah
     mov  ah,9
     mov  bh,0
     mov  cx,1
     int  10H
     inc  dl
     cmp  dl,80
     jb   restore_screen_loop
     mov  dl,0
     inc  dh
     cmp  dh,25
     jb   restore_screen_loop
     mov  dx,save_cursor
     call set_cursor_position
     pop  si
     pop  dx
     pop  cx
     pop  bx
     pop  ax
     ret
restore_screen endp
;+++++++++++++++++++++++++++
;***************************
     end
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s