title    'Virtual Screen Handler '


;******************************************************
;                                                     *
;     This module contains all code necessary for     *
;     full screen buffering on a serial (VT-52)       *
;     terminal.                                       *
;     Note: assumes m_alloc in XIOS header has been   *
;           initialized to reserve space for screen   *
;           images.                                   *
;     Last changed : 2/11/84                          *
;                                                     *
;******************************************************
    

include vscreen.equ
include system.lib
include chrcomm.equ
include serdata.equ

eject

        dseg

extrn   mem_alloc:word
extrn   ocdesctbl:word
public  screen_image_tbl

        cseg

 public vs_init
 public vs_conout
 public default_esc
 public vs_switch
 public set_up_bx
 extrn  conout1:near
 extrn  serial_out:near

;************************************************                                         
;        VIRTUAL   SCREEN   INITIALIZATION      *
;************************************************

;==========
vs_init:
;==========
                                        
    mov ax, mem_alloc                    ; segment address given by GENCCPM
    mov bx, offset scrn_image0           ; get first screen image
    xor ch,ch
    mov cl, nvcons                       ; do init for each virtual console

init_scrn:                               ; init each structure with the segment
    mov vs_screen_seg,ax                 ; address of its char/attrib buffer
    add bx, vs_struc_len
    add ax,((crt_size + 15) shr 4) * 2
    loop init_scrn

    mov ah, vsa_normal                   ; attribute = normal
    mov al, blank                        ; char =  blank
    mov bx, offset scrn_image0           ; with normal attribute byte
    mov cl, nvcons
    push es

clear_scrn:                              ; do one clear for each virtual console
    push cx
    mov es, vs_screen_seg                ; get segment address back
    sub di,di
    mov cx, crt_size                     ; get screen size
    rep stosw                            ; paint screen with blanks
    pop cx
    add bx,vs_struc_len                  ; index to next screen structure
    loop clear_scrn    
    pop es                               ; we're done
    ret


eject
;******************************************************
;                                                     *
;       ENTRY POINT FOR VIRTUAL SCREEN UPDATES        *
;                                                     *
;******************************************************

;===========
vs_conout:
;===========

    mov bx,dx                         ; BL = virtual console #
    shl bx,1
    mov bx,screen_image_tbl[bx]       ; get virtual screen structure
    mov al,cl ! mov ah,dl             ; Set up AX for subroutines
    mov cx,0  ! push ax               ; AH = console #, AL = character 
    call vs_escape_rt                 ; This is the escape handler if in middle 
                                      ; of a sequence. Default is CONOUT01.
    cmp cx,0 ! jne conout01           ; CX = 0    if in escape sequence
                                      ;    = ffff if regular char

other_char:                           ; Either we're in the middle of an 
                                      ; escape sequence or it's a special char.
    pop cx ! mov dl,ch                ; Fall through to physical output.
    xor ch,ch                         ; Virtual update has been done.
     jmp conout1

conout01:
    mov di, offset spec_char_tab      ; check if special char (CR,LF,BS,ESC)
    mov si, offset spec_func_tab      ; if so, co_look_up jmps to corresponding
    call co_look_up                   ; function
      jcxz conout02                   ; else,update image with simple character                 
      jmp other_char                    

conout02:                             ; simple character handling
   pop cx ! mov dl,ch ! xor ch,ch     ; restore console # and char
   mov di,vs_cursor                   ; starting point of single char copy

   push es                            ; BX = virtual screen structure
   mov es,vs_screen_seg               ; ES = segment of virtual screen
   mov ah,vs_attrib                   ; AH -> current attribute

   mov al,cl                          ; CL,AL -> new char
   stosw
   pop es                             ; DI pts to next attribute/char word

   cmp vs_column,crt_col - 1          ; see if we need a CR-LF
     jb inc_col                       ; no, go move cursor one to the right
   test vs_mode,vsm_no_wrap           ; if in wrap mode, don't do CR-LF
     jz conout03                      ; and continue on to physical output
   call carriage_return               ; else update virtual cursor,col & row
   call line_feed

conout03:
   jmp conout1

inc_col:
   call r_right                       ; updates cursor by one (to the right)
     jmp conout1
               


;************************************************
;                                               *
;        SPECIAL CHARACTER OUTPUT ROUTINES      *
;                                               *
;************************************************

;----------------
carriage_return:
;----------------
;        entry: BX = screen structure
;        exit : BX preserved

         push dx
         xor dx,dx
         xchg vs_column,dl               ; set column to zero
         shl dx,1                        ; back up cursor
         sub vs_cursor,dx
         pop dx
         ret
   
;----------------
line_feed:
;----------------
;        entry: BX = screen structure
;        exit : BX preserved

         cmp vs_row, crt_row - 1
         je lf_scroll                  ; are we at bottom of screen?
            jmp d_down                 ; no, move cursor down a line
lf_scroll:
         push dx
         xor dl,dl                     ; yes, adjust top & bottom pointers
         mov dh, crt_row - 1
         call scroll_up
         pop dx
         jmp erase_line

;-----------------
back_space:
;-----------------
;        entry: BX = screen structure
;        exit : BX = preserved

         mov di,vs_cursor    
         test di,di                    ; are we at home position ?
           jz bs_ret                   ; yes, ignore backspace
         cmp vs_column,0               ; are we at the beginning of a line ?
           je bs_row                   ; yes, try previous line
         dec vs_column                 ; else, simple case : dec # cols
           jmps bs_set_cursor
bs_row:
         test vs_mode,vsm_no_wrap      ; if in nowrap mode, don't back up to
           jnz bs_ret                  ; previous line
         dec vs_row                    ; else, dec current row and
         mov vs_column,crt_col - 1     ; show column at end of line
bs_set_cursor:
         sub di,2                      ; DI = cursor
         mov vs_cursor,di
bs_ret:
         ret




;*******************************************************
;
;        ESCAPE SEQUENCE ROUTINES
;
;*******************************************************


;----------
co_look_up:
;----------
;          entry: BX = address of screen structure
;                 AH = device number
;                 AL = char to scan for
;                 DI = ptr to lookup table
;                 SI = function table
;          exit : CX = 0ffffh if special char found
;                      0 if no spec char found
;                 if not spec function, AX & BX preserved

           mov bp,es ! mov dx,ds 
           mov es,dx
           xor cx,cx ! mov cl,[di]    ; first byte of di is length of table
           mov dx,cx ! inc di
           repne scasb                ; cruise through table for match
           mov es,bp                  ; restore ES
            je lookup_func            ; got a match, go get function
               ret                    ; else, return with CX = 0
lookup_func:
           inc cx                     ; CX = number matched on
           sub dx,cx  ! shl dx,1      ; function number
           add si,dx
           call word ptr [si]
           xor cx,cx ! dec cx         ; return with CX = 0ffffh
             ret

;----------
escape_rt:
;----------
;          entry: BX = screen structure
;                 AL = current byte in esc sequence          
;          exit : vs_escape_rt = address of next routine to execute 
;                 in this sequence

           mov vs_escape_rt,offset escape1
             ret                               
escape1:
           mov vs_escape_rt, offset default_esc      ; assume done with escape
           mov di, offset esc_tbl                    ; if more to do, this field
           mov si, offset esc_func_tbl               ; will be set by handler
           push cx                                   ; save CX to show in esc
           call co_look_up                           ; sequence
           pop cx
           ret

;----------
home:                               ; ESC  H
;----------

   xor ax,ax
   mov vs_cursor,ax
   mov vs_column,al
   mov vs_row,al
   ret

;----------
right:                             ; ESC C
;----------

   cmp vs_column,crt_col - 1       ; if at end of screen, ignore it
    jb r_right
      ret
r_right:
   add vs_cursor,2
   inc vs_column        
   ret

;----------
left:                              ; ESC D
;----------

   cmp vs_column,0                 ; if at beginning of screen, ignore it
    ja l_left
      ret   
l_left:
   sub vs_cursor,2
   dec vs_column    
   ret

;----------
down:                              ; ESC B
;----------

   cmp vs_row,crt_row - 1          ; if at bottom of screen, ignore it
    jb d_down
      ret
d_down:
   add vs_cursor,crt_col * 2
   inc vs_row    
   ret

;----------
up:                               ; ESC A
;----------

   cmp vs_row,0                   ; if at top of screen, ignore it
    ja d_up
      ret
d_up:
   sub vs_cursor,crt_col * 2
   dec vs_row    
   ret   
   

;---------------
up_with_scroll:                   ; ESC I
;---------------

   cmp vs_row,0                   ; if not on the top line, mov the cursor
     ja up                        ; to the top only
   push dx
   xor dl,dl                      ; else, scroll it up
   mov dh,crt_row - 1             ; start row = 0, end row = screen bottom
   call scroll_down               ; cursor stays the same
   pop dx
     jmp erase_line             

;----------
save:                             ; ESC j
;----------

   mov ah,vs_row                  ; save row and col in xy
   mov al, vs_column
   mov vs_xy,ax
   mov ax,vs_cursor               ; save cursor
   mov vs_oldcursor,ax
   ret

;----------
restore:                         ; ESC k
;----------

   mov ax,vs_xy
   mov vs_column,al
   mov vs_row,ah
   mov ax,vs_oldcursor
   mov vs_cursor,ax
   ret

;-----------
x_and_y:                        ; ESC Y
;-----------

   mov vs_escape_rt,offset xy_row       ; wait for row
   ret
xy_row:
   sub al,32
   cmp al,crt_row - 1
    jbe row_ok
   mov vs_escape_rt,offset xy_ret    
   ret
row_ok:
   mov vs_row,al
   mov vs_escape_rt,offset xy_col       ; wait for column
   ret
xy_col:
   sub al,32
   cmp al,crt_col - 1
    jbe xy_set_col
      mov al,crt_col - 1
xy_set_col:
   mov vs_column,al                 ; Set the new column #
   push cx ! push dx
   xor ax,ax
   mov al,vs_row                    ; Use new row and column to compute
   mov cx,crt_col * 2               ; new cursor position.
   mul cx
   xor cx,cx
   mov cl,vs_column    
   shl cx,1
   add ax,cx
   mov vs_cursor,ax
   pop dx ! pop cx 
   
xy_ret:
   mov vs_escape_rt, offset default_esc
   ret

;---------------
erase_screen:                       ; ESC E
;---------------

   push es ! push cx
   mov es, vs_screen_seg            ; get virtual screen segment
   mov ax, 0720H                    ; put normal attribute with blank
   mov cx, crt_size                 ; do entire screen
   xor di,di                        ; start at position zero
   rep stosw
   pop cx ! pop es
   ret

;---------------
erase_begin:                        ; ESC B
;---------------

   push es ! push cx
   mov es, vs_screen_seg            ; get virtual screen segment
   mov ax,vs_cursor                 ; get number of words to erase from
   shr ax,1                         ; beginning of screen
   mov cx,ax
   mov ax, 0720h                    ; give them all normal atrributes
   xor di,di                        ; start at top of screen
   rep stosw
   pop cx ! pop es
   ret 

;---------------
erase_end:                          ; ESC J
;---------------

   push es ! push cx
   mov es,vs_screen_seg             ; get virtual screen segment
   mov ax,vs_cursor    
   mov di,ax                        ; erase from cursor to the end
   shr ax,1
   mov cx,crt_size
   sub cx,ax                        ; CX = total # words to erase
   mov ax,0720h                     ; given them all normal attributes
   rep stosw
   pop cx ! pop es
   ret

;---------------
erase_line:                         ; ESC l
;---------------

   push es ! push cx ! push dx
   mov es,vs_screen_seg             ; get virtual screen segment
   xor ax,ax
   mov al,vs_row        
   mov cx,crt_col
   mul cx                           ; get word offset of current row
   shl ax,1                         ; make it a byte offset
   mov di,ax                        ; start erasing here
   mov ax,0720h                     ; give them all normal attributes
   rep stosw
   pop dx ! pop cx ! pop es
   ret

;---------------
erase_bol:                          ; ESC o
;---------------

   push es! push cx ! push dx       ; erase from beginning of line
   mov es,vs_screen_seg    
   xor ax,ax
   mov al,vs_row                    ; current row
   mov cx,crt_col * 2
   mul cx
   mov di,ax                        ; beginning offset - word
   xor cx,cx
   mov cl,vs_column                 ; number of words to erase
   inc cx                           ; on this line
   mov ax,0720h                     ; give them all normal attributes
   rep stosw
   pop dx ! pop cx ! pop es
   ret

;---------------
erase_eol:                          ; ESC K
;---------------

   push es ! push cx                ; erase to end of line
   mov es,vs_screen_seg             ; get virtual screen segment
   mov di,vs_cursor                 ; start to erase here
   mov cx,crt_col
   sub cl,vs_column                 ; number of words to erase on this line
   mov ax,0720h                     ; give them all normal attributes
   rep stosw
   pop cx ! pop es
   ret

;---------------
insert_line:                        ; ESC L
;---------------

   push ax ! push dx
   mov dl,vs_row                    ; start row
   mov dh,crt_row - 1               ; ending row
   call scroll_down                 ; make room for the new line
   call erase_line                  ; erase the old one
   xor ax,ax                        
   xchg al,vs_column                ; set cursor
   shl ax,1
   sub vs_cursor,ax   
   pop dx ! pop ax
   ret

;---------------
delete_line:                        ; ESC M
;---------------
;  
;  ENTRY : BX -> screen structure
;  EXIT  : BX _> same

   push ax ! push dx
   mov dl,vs_row                        ; scroll up first
   mov dh,crt_row - 1
   call scroll_up
   mov vs_row[bx], crt_row - 1
   call erase_line                      ; then erase the line
   call carriage_return
   pop dx ! pop ax
   ret

;---------------
delete_char:                        ; ESC N
;---------------

   push es ! push cx
   mov es,vs_screen_seg             ; get virtual screen segment
   mov di,vs_cursor    
   mov si,di
   add si,2
   xor cx,cx
   mov cl,crt_col - 1
   sub cl,vs_column    
   push ds ! push es ! pop ds
   rep movsw
   mov 0[di],0720h                 ; put a blank in last column
   pop ds ! pop cx ! pop es
   ret

;---------------
enter_reverse:                     ; ESC p
;---------------

   push ax ! push es ! push di
   ;mov es, vs_screen_seg
   mov al, vs_mode
   or al,vsa_reverse 
   mov vs_mode, al   
   ;mov di, vs_cursor
   ;mov ax, es:[di]
   ;mov ah,vsa_reverse
   ;mov es:[di],ax   
   mov al, vsa_reverse   
   mov vs_attrib,al
   pop di ! pop es ! pop ax 
   ret


;---------------
exit_reverse:                      ; ESC q
;---------------

   push ax ! push es ! push di
   ;mov es, vs_screen_seg
   mov al, vs_mode
   and al, not vsa_reverse
   mov vs_mode, al
   ;mov di, vs_cursor
   ;mov ax, es:[di]
   ;mov ah, vsa_normal
   ;mov es:[di],ax
   mov al, vsa_normal
   mov vs_attrib,al
   pop di ! pop es ! pop ax
   ret

;---------------
enter_blink:                       ; ESC s
;---------------

   ret

;---------------
exit_blink:                        ; ESC t
;---------------

   ret

;---------------
enter_bright:                      ; ESC r
;---------------

   ret

;---------------
exit_bright:                       ; ESC u
;---------------

   ret

;---------------
enable_cursor:                     ; ESC e
;---------------

   ret

;---------------
disable_cursor:                    ; ESC f
;---------------

   ret

;---------------
enable_wrap:                       ; ESC v
;---------------

   and vs_mode,not vsm_no_wrap
   ret

;---------------
disable_wrap:                      ; ESC w
;---------------

   or vs_mode,vsm_no_wrap
   ret


;***********************************************************
;
;        SUBROUTINES FOR VIRTUAL SCREEN UPDATES
;
;***********************************************************

;----------
scroll_up:                         ; scroll up in the range given in AX
;----------                           
;          entry: AH = virtual screen #
;                 BX = screen structure
;                 DL = starting row - 0 relative
;                 DH = ending row - 0 relative
;          exit : AX,BX,ES preserved
           
    push es ! push cx ! push dx
    mov es,vs_screen_seg            ; DX = start,end rows  AL = virt. console #
    mov cx,dx                       ; save copy of start,end rows
    xor ax,ax  ! mov al,dl          ; set up SI,DI
    mov dx,crt_col * 2         
    mul dx  ! mov di,ax             ; DX,AX = byte offset starting row 
    add ax,crt_col * 2              
    mov si,ax  ! mov ax,cx          ; SI = first word to copy from
    sub ah,al  ! xor al,al
    xchg al,ah                      ; set up CX for # words to copy
    mov dx,crt_col
    mul dx  ! mov cx,ax
    push ds ! push es! pop ds
    rep movsw
    pop ds ! pop dx ! pop cx ! pop es
    ret

;----------
scroll_down:
;----------
;          entry: AH = virtual console number
;                 BX = screen structure
;                 DL = start row
;                 DH = end row
;          exit : AX,BX,ES preserved

   push ax ! push cx ! push es
   mov es,vs_screen_seg    
   mov cx,dx
   xor ax,ax
   mov al,dh
   inc al
   push dx
   mov dx,crt_col * 2
   mul dx
   sub ax,2
   mov di,ax
   sub ax,crt_col * 2
   mov si,ax
   std
   mov ax,cx
   sub ah,al
   xor al,al
   xchg al,ah
   mov dx,crt_col
   mul dx
   mov cx,ax
   pop dx
   push ds ! push es ! pop ds
   rep movsw
   pop ds ! pop es ! pop cx ! pop ax
   cld
   ret

;----------
default_esc:
;----------
;           entry : CX = 0
;           exit  : CX = ffffh - flag for simple char
;                   CX = 0 for escape or backspace

    dec cx
    ret

eject
;**********************************************************
;                                                         *
;        SCREEN    SWITCH    ROUTINES                     *
;                                                         *
;**********************************************************

;=========
vs_switch:	; Switch Screen with full screen buffering
;=========
;
;	input:	dl = Vcon to switch to
;		dh = Pcon to do the switch on
;               

switch_init:

        mov bx, dx
        xor bh, bh
        shl bx,1 
        mov bx, screen_image_tbl[bx]           ;; BX -> screen structure
        mov es, vs_screen_seg                  ;; ES -> screen image buffer
        
        push word ptr vs_mode
        push word ptr vs_column                ;; save row and col for cursor
        push word ptr vs_row                   ;; restore.

set_up:
        call set_up_bx                         ;; BX -> output Q ctl structure
        call ser_home                          ;; home physical cursor
        call ser_clear                         ;; clear physical screen
        call ser_ex_rev                        ;; just to be safe

        xor di,di                              ;; DI -> our cursor
        xor dh,dh                              ;; DL -> # columns done so far
        mov dl, 0ffh
        mov al, vsa_normal                     ;; AL -> attribute
        xor ah,ah                              ;; Default attribute is normal.

switch_loop:
        mov cx, es:[di]                        ;; CX -> new atrribute, char
        cmp al,ch                              ;; new attribute ?
         je switch_loop1                       ;; no, send the char

send_esc_seq:
        push dx ! push cx 
        test ch, vsa_reverse
         jnz ent_rev
        call ser_ex_rev
          jmp done_esc

ent_rev: 
        call ser_ent_rev

done_esc:
        pop cx ! pop dx
        xor ah,ah
        mov al,ch                              ;; update attribute

switch_loop1:
        push dx ! push ax 
        xor ch,ch
        call serial_out                        ;; send the char
        inc di ! inc di                        ;; DI -> curr char count
        pop ax ! pop dx                        
        inc dl                                 ;; DL -> column count

total_check:
        push di ! dec di ! dec di
        cmp di,(crt_size * 2) - 2              ;; DI -> total chars sent so far
        pop di  
         jae redo_cursor                       

line_check:
        cmp dl, crt_col - 1                    ;; are we at the end of line ?
          jb switch_loop                       ;; no, do total chars check
        call car_ret                           ;; do the CR/LF
        mov dl, 0ffh                           ;; reset col count to 0
          jmps switch_loop                       

redo_cursor:
        pop ax ! pop dx                        ;; AL -> row, DL -> col
        call restore_cursor

chk_wrap:
        pop dx                                 ;; get mode back
        test dl, vsm_no_wrap                   ;; check for wrap-around mode
          jnz dis_wrap
        call ser_en_wrap
          jmps chk_rev
dis_wrap:
        call ser_dis_wrap      

chk_rev:
        test dl, vsa_reverse                   ;; check for inverse video
          jz ex_rev
        call ser_ent_rev 
          jmps curr_vc

ex_rev:
       call ser_ex_rev

curr_vc:
       ret                                     ;; back to switch module
       

;-----------
set_up_bx:
;-----------

	xor bx, bx
	mov bl, dh		               ;; use Pcon to index into the Xmit Q's
	shl bx, 1
	mov bx, ocdesctbl[bx]	               ;; bx -> Xmit Q control
        ret


ser_ent_rev:
;-----------
;   Sends Z-29/19 escape sequence for Enter Reverse Mode
;   
;   Entry : BX -> Xmit Q control structure
;
    mov oesc_cnt[bx], 2
    mov cl, esc
    call serial_out
    mov cl, 'p'
    call serial_out
    ret

ser_ex_rev:
;----------
;  Sends Z-29/19 escape sequence for Exit Reverse Mode
;
;  Entry : BX -> Xmit Q control structure
;
   mov oesc_cnt[bx], 2
   mov cl, esc
   call serial_out
   mov cl, 'q'
   call serial_out
   ret

ser_en_wrap:
;-----------
;  Sends Z-29/19 escape sequence for Enable Wrap Mode
;
;  Entry : BX -> Xmit Q control structure
;
   mov oesc_cnt[bx], 2
   mov cl, esc
   call serial_out
   mov cl, 'v'
   call serial_out
   ret

ser_dis_wrap:
;-----------
;  Sends Z-29/19 escape sequence for Disable Wrap Mode
;
;  Entry: BX -> Xmit Q control structure
;
   mov oesc_cnt[bx], 2
   mov cl, esc
   call serial_out
   mov cl, 'w'
   call serial_out
   ret

ser_home:
;--------
;  Sends Z-29/19 escape sequence for Home Cursor
;
;  Entry : BX -> Xmit Q control structure
;
   mov oesc_cnt[bx], 2
   mov cl, esc
   call serial_out
   mov cl, 'H'
   call serial_out
   ret

ser_clear:
;---------
;  Sends Z-29/19 escape sequence for Clear Screen
;
;  Entry : BX -> Xmit Q control structure
;
   mov oesc_cnt[bx], 2
   mov cl, esc
   call serial_out
   mov cl, 'E'
   call serial_out
   ret


car_ret:
;-----------
;  Sends a carriage return/ linefeed to Z-29/19 .
;
;
  push ax ! push si
  mov cl, 0ah
  call serial_out
  mov cl, 0dh
  call serial_out
  pop si ! pop ax
  ret


restore_cursor:
;--------------
;  Sends Z-29/19 escape sequence to reposition cursor
;
;  Entry : BX -> Xmit Q control structure
;
   push dx ! push ax
   mov oesc_cnt[bx],4
   mov cl, esc
   call serial_out
   mov cl, 'Y'
   call serial_out
   pop ax                                      ;; row #
   add al, 32                                  ;; normalize for terminal
   mov cl,al                                   
   call serial_out
   pop dx                                      ;; col #
   add dl, 32                                  ;; move cursor 1 char past last char                                  
   mov cl,dl                                    
   call serial_out
   ret




         dseg


;***************************************************************
;                                                              *
;                    SPECIAL OUTPUT CHARACTER TABLES           *
;                                                              *
;***************************************************************

   spec_char_tab     db      4
                     db      cr,lf,backsp,escape

   spec_func_tab     dw      carriage_return
                     dw      line_feed
                     dw      back_space
                     dw      escape_rt

;***************************************************************
;                                                              *
;                    ESCAPE SEQUENCE TABLES                    *
;                                                              *
;***************************************************************

  esc_tbl            db       28

                     db       'H','C','D','S','A'
                     db       'I','j','k','Y','E'
                     db       'b','J','l','o','K'
                     db       'L','M','N','p','q'
                     db       'r','u','s','t','a'
                     db       'f','v','w'

esc_func_tbl         dw        home
                     dw        right
                     dw        left 
                     dw        down  
                     dw        up  
                     dw        up_with_scroll    

                     dw        save
                     dw        restore  
                     dw        x_and_y

                     dw        erase_screen
                     dw        erase_begin
                     dw        erase_end
                     dw        erase_line
                     dw        erase_bol
                     dw        erase_eol

                     dw        insert_line
                     dw        delete_line
                     dw        delete_char

                     dw        enter_reverse
                     dw        exit_reverse
                     dw        enter_bright
                     dw        exit_bright
                     dw        enter_blink
                     dw        exit_blink

                     dw        enable_cursor
                     dw        disable_cursor
                     dw        enable_wrap
                     dw        disable_wrap


;*****************************************************************
;                                                                *
;       VIRTUAL   SCREEN   IMAGE TABLE                           *
;                                                                *
;*****************************************************************


screen_image_tbl   dw   scrn_image0
                   dw   scrn_image1
                   dw   scrn_image2
                   dw   scrn_image3
                   dw   scrn_image4
                   dw   scrn_image5
                   dw   scrn_image6
                   dw   scrn_image7

scrn_image0        dw   0,0                   ;cursor, oldcursor
                   db   0,0,2                 ;col, row, mode
                   db   vsa_normal            ;attribute
                   dw   0,0,0                 ;xy, oldxy, screen segment
                   dw   offset default_esc    ;default: first char = reg char

scrn_image1        dw   0,0                   ;cursor, oldcursor
                   db   0,0,2                 ;col, row, mode
                   db   vsa_normal            ;attribute
                   dw   0,0,0                 ;xy, oldxy, screen segment
                   dw   offset default_esc    ;default: first char = reg char

scrn_image2        dw   0,0                   ;cursor, oldcursor
                   db   0,0,2                 ;col, row, mode
                   db   vsa_normal            ;attribute
                   dw   0,0,0                 ;xy, oldxy, screen segment
                   dw   offset default_esc    ;default: first char = reg char

scrn_image3        dw   0,0                   ;cursor, oldcursor
                   db   0,0,2                 ;col, row, mode
                   db   vsa_normal            ;attribute
                   dw   0,0,0                 ;xy, oldxy, screen segment
                   dw   offset default_esc    ;default: first char = reg char

scrn_image4        dw   0,0                   ;cursor, oldcursor
                   db   0,0,2                 ;col, row, mode
                   db   vsa_normal            ;attribute
                   dw   0,0,0                 ;xy, oldxy, screen segment
                   dw   offset default_esc    ;default: first char = reg char

scrn_image5        dw   0,0                   ;cursor, oldcursor
                   db   0,0,2                 ;col, row, mode
                   db   vsa_normal            ;attribute
                   dw   0,0,0                 ;xy, oldxy, screen segment
                   dw   offset default_esc    ;default: first char = reg char

scrn_image6        dw   0,0                   ;cursor, oldcursor
                   db   0,0,2                 ;col, row, mode
                   db   vsa_normal            ;attribute
                   dw   0,0,0                 ;xy, oldxy, screen segment
                   dw   offset default_esc    ;default: first char = reg char

scrn_image7        dw   0,0                   ;cursor, oldcursor
                   db   0,0,2                 ;col, row, mode
                   db   vsa_normal            ;attribute
                   dw   0,0,0                 ;xy, oldxy, screen segment
                   dw   offset default_esc    ;default: first char = reg char

end