home *** CD-ROM | disk | FTP | other *** search
Text File | 1989-01-26 | 39.4 KB | 1,680 lines |
- ; WINDOWS2.A86
- title '2nd Level Window Routines'
- pagesize 60+11
- ;************************************************
- ;* *
- ;* INTERMEDIATE VIRTUAL SCREEN ROUTINES *
- ;* WINDOW MANAGER XIOS CALLS *
- ;* CDOS 6.0 XIOS *
- ;* DRI OS ENGR, JMB, GMS *
- ;* *
- ;************************************************
- ; Major mods:
- ; 6.x
- ; 8 Nov 88 -- io_switch saves VGA/EGA screen when windowing IJ
- ; 18 AUG 88 -- Fix up PIN VC for MGE in io_switch GMS
- ; 3 AUG 88 -- Always turn beeper off on io_switch GMS
- ; 5 Jul 88 -- Keep ROS data in step over screen switch IJ
- ; 7 APR 88 -- Sun River support added GMS
- ; 11 JAN 88 -- io_switch saves and restores PC equipment flag GMS
- ; 7 DEC 87 -- int10_bx entries replaced with int10_entry GMS
- ; 7 DEC 87 -- VS_SCREEN_MODE now uses ROS video mode values GS
- ; 2 DEC 87 -- replaced ega$ with redefined video$ GS
- ; 6.0
- ; 13 NOV 87 -- reset ega pallette from new_screen_mode GS/JW
- ; 9 NOV 87 -- return error from ww_pointer if serial vc GMS
- ; 7 NOV 87 -- add int10_si@ entry for int 10's w/ BX = param JW
- ; 5 NOV 87 -- check page select on hercules retrace timing GMS
- ; 4 NOV 87 -- set blink toggle for ega mono GMS
- ; 17 JUL 87 -- converted XIOS to small model JW
- ; 22 JUN 87 -- 43 line ega support GMS
- ; 17 JUN 87 -- get cursor position from ROS if switching from graphics GMS
- ; 5.2
- ; 26 MAY 87 -- set graphics flag at io_switch if process suspended GMS
- ; 7 APR 87 -- added support for extra olivetti video modes GMS
- ; 27 FEB 87 -- Reset EGA blink toggle state on io_switch GMS
- ; 5.1
- ; 14 JAN 87 -- Do not read hardware cursor if not yet updated GMS
- ; 27 OCT 86 -- Save hercules mode on switch PAR
- ; 27 OCT 86 -- switch timer vector at io_switch@ - removed GMS
- ; 14 APR 86 -- save cursor on screen switch by reading CRTC
- ; 8 JAN 86 -- EGA adjustment
- ; 4 DEC 85 -- EGA adjustment
- ; 14 JUN 85 -- update 4.1 ASM86 XIOS to RASM86
-
- ; include COPYRITE.TXT
-
- nolist
- include CDOS.EQU
- include XIOS.EQU
- include PCHW.EQU
- include ROSDATA.EQU
- if SR
- include SR.EQU
- endif
- list
- ; These were included:
- ; include CDOS.EQU
- ; include XIOS.EQU
- ; include PCHW.EQU
- ; include ROSDATA.EQU
- if SR
- ; include SR.EQU
- endif
-
- CGROUP group CODE
- DGROUP group DATA
-
- public io_switch@
- public ww_pointer@, ww_im_here@
- public ww_new_window@, ww_cursor_view@
- public ww_wrap_column@,ww_full_window@
- public ww_switch_display@
- public point_cursor@, point_vs@, get_mx@
- public free_all_mxs@, get_all_mxs@
- public new_pc_window@, do_true_view@, check_full_top@
- public xlat_priority@, new_monitor@
- public restore_state@, check_full@, update_window@
- public update_all@, set_new_mon@
- public con_scan@
- public leave_until_char@
- if 0
- public kbd_vects$
- endif
- eject
-
- dseg
-
- extrn kbd_imhere$ :byte
-
- extrn nvcns$ :byte ; in HEADER.A86
-
- extrn key_flag$ :word, switch_key$ :byte ; in KEYBOARD.A86
- extrn im_here$ :byte, win_sized$ :byte ; in PUBDATA.A86
-
- extrn vc_priority$ :byte, mono_bits$ :byte ; in WINDOWS3.A86
- extrn color_bits$ :byte, top_screen$ :byte
- extrn s_lines$ :byte, d_lines$ :byte
- extrn first_vs$ :word, vc_map_seg$ :word
- if not SR
- extrn list_next$ :word, list_vc$ :byte
- endif
- extrn table_vs$ :word, vc_list$ :word
- extrn top_screen_mode$:byte
- extrn video$:byte ; in WINDOWS1.A86
-
- extrn retrace$ :word
- extrn herc_text$ :word, herc_graph$ :word
- extrn cloneflag$ :byte
- if V386
- extrn active_vc$:byte ; in PCTERM.A86
- endif
- if SR
- extrn sr_vs_table$ :byte ; in PUBDATA.A86
- extrn SR_VS_TLEN :abs
- extrn sr_table_vs$ :word
- extrn first_vs_num$ :byte
- extrn num_vir_cons$ :byte
- extrn ccb_list$ :word
- extrn num_sr_vs_cons$ :byte ; in SRTERM.A86
- endif
-
- cseg
- extrn flagset@ :near ; in HEADER.A86
- extrn supervisor$ :dword, supif@:near
- extrn check_no_switch@:near ; in CONIN.A86
-
- extrn i_keyboard@ :near ; in KEYBOARD.A86
- extrn i_clock@ :near ; in ISRS.A86
- extrn clear_statline@ :near, switch_statline@ :near ; in STATLINE.A86
- extrn con_normal@ :near, screen_set_only@ :near ; in WINDOWS1.A86
- extrn new_cursor_on@ :near, old_cursor_off@ :near
- extrn show_cursor@ :near
- extrn z_set_color@ :near, z_set_mono@ :near
- extrn ros_color@ :near
- extrn save_plane2@ :near, restore_plane2@ :near
- extrn ega_pallette@ :near
-
- extrn erase_crt@ :near, draw_frame@ :near ; in WINDOWS3.A86
- extrn put_crt_m@ :near
- extrn draw_frame_s@ :near, draw_frame_d@ :near
- extrn copy_full_top@ :near, put_crt_s@ :near
-
- extrn int10_entry@ :near ; in ROSIF.A86
- if SR
- extrn point_pc@ :near,test_srterm@ :near ; in SRTERM.A86
- extrn sr_ww_im_here@ :near
- endif
-
- eject
-
- ; *** Console Out Subroutines ***
-
- set_new_mon@:
- ;-----------
- ; Clear both screens, new xlats, and update all;
- ; Called from init, esc x, and esc y;
- ; This routine locks up the mx semaphores.
-
- cli ;; a little critical section
- mov VS_MX,0 ;; to keep from blocking
- new_monitor@: ;; entry from init
- call get_all_mxs@ ;; lock 'em up
- sti
- mov si,offset vc_priority$
- if SR
- mov ax,NUM_VIR_CONS ;; max VS
- mov cl,num_vir_cons$ ; number of VS this PC
- xor ch,ch
- sub ax,cx
- add si,ax ; up pointer
- else
- mov cx,NUM_VIR_CONS
- endif
- new_mon1:
- push cx
- mov dl,[si] ;; get relative vc number
- call point_vs@ ;; bx -> structure
- call new_xlat ;; redo the table
- pop cx
- inc si ;; next vc up
- loop new_mon1
-
- test video$,MONO ;; if no monochrome card
- jz new_mon2 ;; then skip erase
-
- mov dh,mono_bits$ ;; which vc's are mono
- mov dl,0 ;; no sync
- mov bx,MONO_SEG
- call erase_crt@ ;; clear mono screen
- new_mon2:
- test video$,COLOR ;; if no color card
- jz new_mon3 ;; then skip erase
-
- mov dh,color_bits$ ;; which vc's are color
- mov dl,SYNC_BIT ;; retrace sync
- mov bx,COLOR_SEG
- call erase_crt@ ;; clear color screen
- new_mon3:
- call update_all@ ;; new screens all around
- jmp free_all_mxs@ ; let my semaphores go
- eject
-
- update_all@:
- ;----------
- ; Update all windows:
- ; Called from new_window, new_monitor@ and screen_set_only@
-
- call new_vc_list ; redo the row list
- mov si,offset vc_priority$
- if SR
- mov ax,NUM_VIR_CONS ;; max VS
- xor ch,ch
- mov cl,num_vir_cons$ ; number of VS this PC
- sub ax,cx
- add si,ax ; up pointer
- else
- mov cx,NUM_VIR_CONS
- endif
- up_all1:
- push si
- push cx
- mov dl,[si] ; get vc number
- call point_vs@ ; bx -> virt structure
- mov si,offset s_lines$
- cmp cl,1 ; if not front vc
- jnz up_all2 ; then skip
- mov si,offset d_lines$
- up_all2:
- call draw_frame@ ; frame the window and
- call update_window@ ; fill it
- pop cx
- pop si
- inc si ; next window up
- loop up_all1 ; NUM_VIR_CONS times
-
- call release_match ; if full top, release it
- call new_cursor_on@ ; turn on the cursor
- jmp show_cursor@ ; display and done
- eject
-
- update_window@:
- ;-------------
- ; Move the vc image to its window unless full on top:
- ; entry: bx -> vs_
-
- test VS_MODE,MATCH_BIT
- jz up_win2 ; skip if full on top
-
- if SR ; THIS IS TEMPORARY TO GET VS GOING
- ; eventually vc_list needs to implemented
- ; for SR terminals
- ;; cmp first_vs_num$,0 ; master console
- ;; jne update_gr ; no .. update SunRiver
- endif
- test VS_MODE1,LINE_43_MODE ; if new mode 43
- jnz update_gr ; treat like graphics
- cmp VS_SCREEN_MODE,04
- jb update_no_check
- cmp VS_SCREEN_MODE,07 ; is this console in graphics mode?
- je update_no_check ; N: jump to normal update
- update_gr:
- mov al,top_screen$
- cmp al,VS_NUMBER ; is this console on top?
- jne up_win2 ; N: skip graphics update
- push si ; Y: blast graphics w/o row check
- push ds ! push es
- sub di,di
- mov si,di
- mov es,VS_CRT_SEG
- mov ds,VS_VC_SEG
- mov ah,OUT_SYNC
- mov cx,CRT_ROWS_P*CRT_COLS ; max image size
- call put_crt_m@
- pop es ! pop ds
- pop si
- ret
-
- update_no_check:
- call correct_ptr ; calc correction
- shl dx,1 ; word pointer now
- mov si,VS_LIST_PTR ; point to row list
- up_win1:
- lodsw ; get count
- xchg ax,cx
- jcxz up_win2 ; done when zero
- lodsw ; get pointer
- mov di,ax ; point to crt
- sub ax,dx ; correct window pos
-
- push si
- push ds ! push es
- xchg ax,si ; point to vc image
- mov es,VS_CRT_SEG
- mov ds,VS_VC_SEG
- mov ah,OUT_SYNC ; from image to crt
- call put_crt_m@ ; move string
- pop es ! pop ds
- pop si
- jmps up_win1 ; do next row
- up_win2:
- ret
-
- eject
-
- release_match:
- ; If full screen on top and no sync, reset MATCH_BIT:
- ; entry: bx -> vs_
-
- or VS_MODE,MATCH_BIT
- call check_full_top@
- jnz release_done
- and VS_MODE,not MATCH_BIT
- release_done:
- ret
-
-
- check_full_top@:
- ; If full screen on top, set zero flag:
- ; entry: bx -> vs_
-
- call check_full@ ; first see if it's full
- jnz check_ft_done ; skip if not full
- mov al,top_screen$
- cmp VS_NUMBER,al ; if top, set zf
- check_ft_done:
- ret
-
-
- check_full@:
- ; If full screen, set zero flag:
- ; entry: bx -> vs_
-
- mov al,VS_CRT_ROWS
- cmp VS_ROWSB,al
- jnz check_f_done ; skip if not full
- cmp VS_COLSB,CRT_COLS
- check_f_done:
- ret ; with flag set
- eject
-
- get_mx@:
- ; Get semaphore for this vc:
- ; entry: bx -> vs_
- ; exit: pres. bp
- mov al,0FFh ; ownership true
- xchg al,VS_MX ; test and set semaphore
- test al,al ; if nobody owned it
- jz got_mx ; then we're done
-
- ; If semaphore is blocked, wait a tick and try again:
- push bx
- push cx
- push dx
- push es
- push bp
- mov cx,P_DELAY
- mov dx,1 ; wait at least 1 tic
- mov bx,rlr$ ; ready list root
- mov es,P_UDA[bx] ; load the uda
- callf supervisor$ ; like a bdos int
- pop bp
- pop es
- pop dx
- pop cx
- pop bx
- jmps get_mx@ ; back and try again
- got_mx:
- ret
-
- get_all_mxs@:
- ; Get semaphore queues for all vc's:
- push bx
- push cx
- xor bx,bx
- mov cx,NUM_VIR_CONS
- get_all1:
- push bx
- mov bx,table_vs$[bx]
- call get_mx@ ; get one at a time
- pop bx
- add bx,2 ; next VC
- loop get_all1 ; for each vc
- if SR
- mov cl,num_sr_vs_cons$ ; total number of SR VS_
- cmp cl,0
- je get_alldone
- mov bx,offset sr_table_vs$
- get_all2:
- push bx
- mov bx,[bx] ; get VS pointer
- call get_mx@
- pop bx
- inc bx ! inc bx
- loop get_all2
- endif
- get_alldone:
- pop cx
- pop bx
- ret
-
- free_all_mxs@:
- ; Release semaphores for all vc's:
- push bx
- push cx
- xor bx,bx
- mov cx,NUM_VIR_CONS
- free_all1:
- push bx
- mov bx,table_vs$[bx]
- mov VS_MX,0 ; free the semaphore
- pop bx
- add bx,2 ; next VC
- loop free_all1 ; for each vc
- if SR
- mov cl,num_sr_vs_cons$ ; total number of SR VS_
- cmp cl,0
- je free_all_done
- push si
- mov si,offset sr_table_vs$
- free_all2:
- mov bx,[si] ; get VS pointer
- mov VS_MX,0 ; free the semaphore
- inc si ! inc si
- loop free_all2
- pop si
- endif
- free_all_done:
- pop cx
- pop bx
- ret
-
-
- correct_ptr:
- ; Calculate window position offset correction:
- cmp VS_CUR_TRACK,0 ; if no tracking,
- jz cor_ptr2 ; then skip
- mov ah,VS_CUR_ROW ; this corrects for
- mov al,VS_TRUE_ROW ; a scrolling screen
- cmp al,ah ; if cursor above view
- ja cor_ptr1 ; then move view up
- sub ah,VS_ROWSB ; if within a window
- js cor_ptr2 ; of top, skip
- cmp al,ah ; if cursor within view
- ja cor_ptr2 ; then also skip
- inc ah ; cursor at window bottom
- cor_ptr1:
- mov VS_TRUE_ROW,ah
- cor_ptr2:
- mov dx,VS_TOP_LEFT
- call point_cursor@ ; static correction
- xchg ax,dx ; save in dx
-
- mov al,CRT_COLS
- mul VS_TRUE_ROW
- sub dx,ax ; correct for row
- mov al,VS_TRUE_COL
- cbw
- sub dx,ax ; and column
- mov VS_CORRECT,dx ; save for char out
- ret
- eject
-
- new_priority:
- ; Update vc priority list and xlat table:
- ; entry: bl -> vs_
- ; dl = vc number
-
- push es
- push ds ! pop es ; local es
- mov di,offset vc_priority$
- if SR
- mov ax,NUM_VIR_CONS ;; max VS
- xor ch,ch
- mov cl,num_vir_cons$ ; number of VS this PC
- sub ax,cx
- add di,ax ; up pointer
- else
- mov cx,NUM_VIR_CONS
- endif
- mov al,dl ; this vc
- repnz scasb ; find ours
- pop es
- jcxz new_xlat ; done if on top
- dec di ; for overscan
- new_prior1:
- mov al,1[di] ; get the one above
- mov [di],al ; and move it down
- inc di
- loop new_prior1 ; to top of list
- mov [di],dl ; put us on top
- jmps new_xlat ; fall through
-
-
- new_screen_mode:
- ; Change screen mode if necessary:
- ; entry: bx -> vs_
- ; ax = ega bits of old screen
-
- test al,LINE_43_MODE ; test if old mode was 43 lines
- mov al,VS_SCREEN_MODE ;
- jnz do_screen_mode ;
- cmp al,top_screen_mode$ ; if modes staying the same,
- jz new_screen_done ; then quit
- do_screen_mode:
- test video$,EGA+VGA+MCGA
- jnz is_ega
- cmp VS_SCREEN_MODE,07 ; if we're not switching
- je new_screen_fini ; to color, then quit
- is_ega:
- mov cl,al ; cl = new screen mode
- or cl,80h ; set no clear bit for ega/vga
- is_ega_alpha:
- call screen_set_only@ ; and ret
- jmps new_screen_fini
- new_screen_done:
- mov dx,COLOR_PORT
- call ros_color@ ; need to set new pallette
- new_screen_fini:
- mov dl,VS_CONMODE ; is new process suspended
- or dl,dl
- jz new_screen_exit ; on screen_set mode
- xor dh,dh
- push bx
- call flagset@ ; set flag to restart process
- pop bx
- new_screen_exit:
- test video$,EGA+VGA
- jz new_screen_ret
- call ega_pallette@ ; make sure we reset those
- new_screen_ret: ; pallettes correctly
- ret
- eject
-
- new_xlat:
- ; Update vc_xlat table:
- mov di,VS_XLAT
- mov al,VS_BIT ; bit position = vc
- mov ah,0 ; count
- mov cx,1 shl NUM_VIR_CONS ; bytes per vc_xlat
- new_xlat1:
- test ah,al ; is this ours?
- jz new_xlat2 ; if not, skip
- mov [di],dl ; if so, take it over
- new_xlat2:
- inc ah ; next number
- inc di ; next table byte
- loop new_xlat1 ; through xlat table
- ret
- eject
- if SR
- new_vc_list:
- ; Make a new vc_list for switch or new_window:
- push bp
- push es
- push bx ; save vs_ pointer
- mov dl,first_vs_num$
- call point_pc@ ; point to PC_ structure
- mov bp,si ; pointer to BP
- mov es,vc_map_seg$ ; base of vc_map
- mov si,ds:PC_VC_LIST[bp]
- mov dl,num_vir_cons$
- dec dl
- mov ds:PC_LIST_VC[bp],dl
-
- new_list1:
- mov dl,ds:PC_LIST_VC[bp] ; get vc number
- add dl,first_vs_num$ ;
- call point_vs@ ; bx -> vs_
- mov ds:PC_LIST_NEXT[bp],-1 ; impossible value
- mov VS_LIST_PTR,si
- mov dx,VS_TOP_LEFT
- mov cx,VS_ROWS ; rows in window
- new_list2:
- push cx
- push dx
- call point_cursor@ ; ax -> vc_map pos
- xchg ax,di
- mov cx,VS_COLS ; columns in window
- new_list3:
- mov al,es:[di] ; 1st vc_map code
- push ax
- call xlat_priority@ ; al = who owns it
- mov ah,ds:PC_LIST_VC[bp]
- add ah,first_vs_num$
- cmp al,ah ; if it's us
- pop ax
- jz new_list4 ; then skip
-
- repz scasb ; if not, just scan
- jz new_list8 ; skip if end of line
-
- dec di ; else, correct for
- inc cx ; over scan
- jmps new_list3
-
- new_list4:
- mov dx,di ; save first pointer
- repz scasb ; scan through our own
- jz new_list5 ; skip if line end
-
- dec di ; else, correct for
- inc cx ; over scan
- new_list5:
- mov ax,di
- sub ax,dx ; ax = scan count
- cmp dx,ds:PC_LIST_NEXT[bp] ; if string contiguous
- jz new_list6 ; then add to count
-
- mov [si],ax ; if not, save count
- inc si
- inc si
- mov [si],dx ; and pointer
- add [si],dx ; vc_ptr = 2*map_ptr
- inc si
- inc si
- jmps new_list7 ; and carry on
-
- new_list6:
- add NEG4[si],ax ; add to last count
- new_list7:
- add ax,dx ; pointer plus count
- mov ds:PC_LIST_NEXT[bp],ax ; update next pointer
- test cx,cx ; if scan not done
- jnz new_list3 ; then continue
- new_list8:
- pop dx
- pop cx
- inc dh ; next row down
- cmp dh,VS_BOTTOM
- jbe new_list2 ; do all rows
-
- mov word ptr [si],0 ; list end flag
- inc si
- inc si ; to next vc's list
- dec ds:PC_LIST_VC[bp]
- jns new_list1 ; do all vc's
- pop bx ; restore vs_ ptr
- pop es
- pop bp
- ret
-
- else
- new_vc_list:
- ; Make a new vc_list for switch or new_window:
- push es
- push bx ; save vs_ pointer
- mov es,vc_map_seg$ ; base of vc_map
- mov si,offset vc_list$
- mov list_vc$,NUM_VIR_CONS-1 ; vc counter
-
- new_list1:
- mov dl,list_vc$ ; get vc number
- call point_vs@ ; bx -> vs_
- mov list_next$,-1 ; impossible value
- mov VS_LIST_PTR,si
- mov dx,VS_TOP_LEFT
- mov cx,VS_ROWS ; rows in window
- new_list2:
- push cx
- push dx
- call point_cursor@ ; ax -> vc_map pos
- xchg ax,di
- mov cx,VS_COLS ; columns in window
- new_list3:
- mov al,es:[di] ; 1st vc_map code
- push ax
- call xlat_priority@ ; al = who owns it
- cmp al,list_vc$ ; if it's us
- pop ax
- jz new_list4 ; then skip
-
- repz scasb ; if not, just scan
- jz new_list8 ; skip if end of line
-
- dec di ; else, correct for
- inc cx ; over scan
- jmps new_list3
-
- new_list4:
- mov dx,di ; save first pointer
- repz scasb ; scan through our own
- jz new_list5 ; skip if line end
-
- dec di ; else, correct for
- inc cx ; over scan
- new_list5:
- mov ax,di
- sub ax,dx ; ax = scan count
- cmp dx,list_next$ ; if string contiguous
- jz new_list6 ; then add to count
-
- mov [si],ax ; if not, save count
- inc si
- inc si
- mov [si],dx ; and pointer
- add [si],dx ; vc_ptr = 2*map_ptr
- inc si
- inc si
- jmps new_list7 ; and carry on
-
- new_list6:
- add NEG4[si],ax ; add to last count
- new_list7:
- add ax,dx ; pointer plus count
- mov list_next$,ax ; update next pointer
- test cx,cx ; if scan not done
- jnz new_list3 ; then continue
- new_list8:
- pop dx
- pop cx
- inc dh ; next row down
- cmp dh,VS_BOTTOM
- jbe new_list2 ; do all rows
-
- mov word ptr [si],0 ; list end flag
- inc si
- inc si ; to next vc's list
- dec list_vc$
- jns new_list1 ; do all vc's
- pop bx ; restore vs_ ptr
- pop es
- ret
-
- endif
-
-
-
- eject
-
-
-
- eject
-
- new_count:
- ; Update row and column counts:
- ; entry: bx -> vs_
- mov al,VS_BOTTOM
- sub al,VS_TOP ; rows - 1
- cbw
- inc ax ; row count
- mov VS_ROWS,ax
-
- mov al,VS_RIGHT
- sub al,VS_LEFT ; columns - 1
- cbw
- inc ax ; column count
- mov VS_COLS,ax
- ret
-
-
- do_true_view@:
- ;------------
- ; Correct view point if window is off image:
- ; entry: bx -> vs_
-
- mov dx,VS_VIEW_POINT
- mov al,VS_CRT_ROWS
- sub al,VS_ROWSB ; get max view row
- cmp al,dh
- jae do_true1 ; skip if ok
- mov dh,al ; else replace with max
- do_true1:
- mov al,CRT_COLS
- sub al,VS_COLSB ; get max view col
- cmp al,dl
- jae do_true2 ; skip if ok
- mov dl,al ; else replace with max
- do_true2:
- mov VS_TRUE_VIEW,dx ; save for correct_ptr
- ret
- eject
-
- new_vc_map:
- ; Update vc_map for change of window:
- ; entry: bx -> vs_
- ; dl = vc number
-
- push es
- mov es,vc_map_seg$
- sub di,di ; top left corner
- mov cx,CRT_ROWS_P * CRT_COLS
- mov al,VS_BIT ; get vc bit mask
- not al
- new_map1:
- and es:[di],al ; wipe out old window
- inc di
- loop new_map1 ; for entire screen
-
- ; Then calculate window limits:
- mov dx,VS_TOP_LEFT
- cmp dh,0 ; if at crt top
- jz new_map2 ; skip top frame
- dec dh ; include frame
- new_map2:
- cmp dl,0 ; if at crt left
- jz new_map3 ; skip left frame
- dec dl ; include frame
- new_map3:
- mov cx,VS_BOT_RIGHT
- cmp ch,CRT_ROWS_P-1 ; if at the 25th line
- jz new_map4 ; skip bottom frame
- inc ch ; include frame
- new_map4:
- cmp cl,CRT_COLS-1 ; if at crt right
- jz new_map5 ; skip right frame
- inc cl ; include frame
- new_map5:
- call point_cursor@ ; ax -> top left
- xchg ax,di
- sub cx,dx ; row & col difference
- add cx,0101h ; ch=rows, cl=cols
-
- ; Now install the new window:
- mov al,VS_BIT ; restore vc bit mask
- new_map6:
- push di
- push cx
- new_map7:
- or es:[di],al ; or in vc's bit
- inc di
- dec cl ; column count
- jnz new_map7
- pop cx
- pop di
- add di,CRT_COLS ; next row
- dec ch
- jnz new_map6
- pop es
- ret
- eject
-
- point_vs@:
- ;---------
- ; Point to virtual console structure:
- ; entry: dl = device number
- ; exit: bx -> vs_
- ; bp = preserved
-
-
- if SR
- cmp dl,NUM_VIR_CONS ; master console ?
- jb point_vs1
- push di ! push si ! push cx ! push ax
- mov al,dl
- mov di,offset sr_vs_table$
- mov cx,SR_VS_TLEN
- call con_scan@ ; get pointer to VS_TABLE
- mov bx,sr_table_vs$[si] ; get VS_ pointer
- pop ax ! pop cx ! pop si ! pop di
- ret
-
- point_vs1:
- endif
- mov al,dl
- cbw
- shl ax,1 ; ax = 2 * vc number
- xchg ax,bx
- mov bx,table_vs$[bx] ; fetch the pointer
- ret
-
-
- point_cursor@:
- ;-------------
- ; Point to vc image from cursor row,column:
- ; entry: dx = (row,column)
- ; bx -> vs_
- ; exit: ax = vs_width*row + column
- ; di = 2*ax
- ; dx = preserved
-
- mov al,VS_WIDTH
- mul dh ; ax = row * (40 or 80)
- add al,dl ; add in the column
- adc ah,0 ; and handle the carry
- mov di,ax
- shl di,1 ; di = 2*ax
- ret
-
-
- xlat_priority@:
- ; Translate vc_map code to owner number:
- ; entry: al = vc_map code
- ; exit: al = owner number
-
- push bx ; save vs_
- mov bx,VS_XLAT
- xlat bx
- pop bx
- ret
- eject
-
- con_scan@:
- ;---------
- ; Scan character string for match:
- ; entry: di -> string
- ; cx = count
- ; al = charater
- ; exit: si = word table index, or just past the end
- ; of the table if character is not found
- ; al,cl = character
-
- push es
- push ds ! pop es ; local extra segment
- mov si,cx
- repnz scasb ; look for match
- jnz con_scan1 ; if no match, skip
- dec si ; correct count
- con_scan1:
- sub si,cx ; si = char number
- shl si,1 ; word pointer
- mov cl,al ; copy character
- pop es
- ret
-
-
- restore_state@:
- ;--------------
- ; Restore the state vector to normal:
- and VS_MODE,not ESC_BIT ; turn off ESC bit
- mov VS_VECTOR,offset con_normal@
- ret ; that's all
-
- leave_until_char@:
- ;----------------
- or VS_MODE,ESC_BIT ; next char. into state machine
- pop VS_VECTOR ; pop return addr into state vector
- ret
- eject
-
- ;==========
- io_switch@:
- ;==========
- ; XIOS virtual console switch routine:
- ; entry: dl = vc to switch to
-
-
- call check_no_switch@ ; in case of back doors
- jmpnz io_switch_exit ; skip if no switch
-
- call get_all_mxs@ ;; block all updates
-
- inc kbd_imhere$ ; there's a problem
- ; occassionally doing graphics switch
- if V386
- mov bx,rlr$
- mov al,P_CONS[bx] ; get current vc number
- mov old_vc,al ; and save for exit
- mov al,top_screen$ ; make sure top screen is
- cmp al,active_vc$ ; mapped in
- je do_io_switch
- mov P_CONS[bx],al
- push dx
- callf disp_vector$ ; call XIOS dispatch code
- pop dx ; with DS:BX=PD address
-
- do_io_switch:
- endif
-
- ; Draw_frame_s@ reads and saves the regen buff if full-top. If
- ; the CRT mode is currently EGA graphics, the buffer is at A000, plus
- ; it's 4 planes, etc. So we save plane 3, which will be overwritten by
- ; fonts, and call save_ega_screen, which quickly switches the EGA back to
- ; color/alpha/80 so we can read it normally.
-
- cmp cloneflag$,IS_M24
- jne not_oli
- cmp top_screen_mode$,40h ; was old mode olivetti gr?
- jae not_ega_mode
- not_oli:
- cmp top_screen_mode$,0Dh ; was the old mode new gr?
- jb not_ega_mode
-
- push dx ; save con number
- call save_plane2@ ; save the contents of bit plane 3
- pop dx
- call save_ega_screen ; save some ega screen contents too
- jmps n_e_1 ; returns with bx-> old VS_
-
- not_ega_mode:
- call draw_frame_s@ ; background old frame bx-> old VS
- call check_herc_card ; reprog if hercules
- n_e_1:
- ; BX -> old vs_
- push ds
- mov ax,PC_SEGMENT
- mov ds,ax
- mov ax,equip_flag_40 ; get PC equipment word
- pop ds
- mov VS_PC_EQUIP,ax ; and save
-
- cmp VS_SCREEN_MODE,04
- jb n_e_2
- cmp VS_SCREEN_MODE,07 ; was old mode graphics ?
- jne is_gr ; yes
-
- n_e_2:
- test VS_MODE1,LINE_43_MODE ; or 43 line mode
- jz not_gr ; yes
- is_gr:
- push dx
- mov ah,03h ; then get cursor position
- push bx
- xor bh,bh
- call int10_entry@ ; from ROS and save in VS_
- pop bx
- mov VS_CURSOR,dx
- pop dx ; console number
- jmps read_cur_done
- not_gr:
- test VS_MODE,UPDATE_BIT ; has cursor been moved
- jnz read_cur_done ; hardware cursor not updated
- call read_cursor ;; get cursor from vs_
- sub ax,VS_CORRECT ;; adjust...
- mov VS_OFFSET,ax ;; and store
- read_cur_done:
- mov al,VS_MODE1 ;; save current ega bits
- push ax
-
- call point_vs@ ;; bx -> new virt structure
-
- cli
- call new_priority ;; set priority tables
-
- push bx
-
- if SR
- mov dl,top_screen$ ; make sure PC_ updated
- call point_pc@ ; get point to new PC_ structure in SI
- mov al,top_screen$
- mov PC_TOP_SCREEN,al ; update screen structure
- endif
- if V386
- mov bx,rlr$ ; PIN PD value
- mov al,old_vc ; get original VC#
- mov P_CONS[bx],al ; and restore
- lea di,P_NAME[bx] ; point to process name
- mov si,offset PINstr
- mov cx,3
- cld
- push es
- push ds ! pop es
- repe cmpsb ; is it 'PIN'
- pop es
- jne not_switch ; no ...
- mov al,top_screen$
- mov P_CONS[bx],al ; change PINs' vc number
- ; ready for next dispatch
- not_switch:
- cmp al,active_vc$
- je no_disp ; .. we're already active
- callf disp_vector$ ; call XIOS dispatch code
- no_disp: ; with DS:BX=PD address
- ; to ensure active_vc= current VC
- endif
- pop bx
- sti
-
- call new_vc_list ;; make a new list
-
- ; If new screen mode = an A000 mode, restore the regen now while it is
- ; still addressed at B800:
- cmp VS_CRT_SEG,EGA_SEG ; special mode?
- jne not_ega_mode1
- call restore_ega_screen ; restore what was on EGA screen
- not_ega_mode1:
-
- mov ax,VS_PC_EQUIP ; get old equipment word
- push ds
- mov cx,PC_SEGMENT
- mov ds,cx
- mov equip_flag_40,ax ; update ROS data area
- pop ds
-
- pop ax ;; old screen ega bits in AL
- if V386
- mov di,rlr$
- mov cl,top_screen$
- cmp P_CONS[di],cl
- jmpnz no_cur
- endif
-
- call new_screen_mode ;; if switching to color
-
- cmp cloneflag$,IS_M24
- jne not_oli2
- cmp top_screen_mode$,40h ;; was old mode olivetti gr?
- jae not_ega_mode2
- not_oli2:
- cmp top_screen_mode$,0Dh ;; did we just go into ega gr?
- jb not_ega_mode2 ;; jmp if no
- push dx ;; save con number
- call restore_plane2@ ;; else restore 3rd bit plane
- pop dx ;; restore con number
- jmps y_ega
-
- not_ega_mode2:
- call draw_frame_d@ ;; frame the window
- call clear_statline@ ;; erase bg 25th line
- call update_window@ ;; update within mx
- y_ega:
-
- call switch_statline@ ;; on/off for pcmode
- call release_match ;; if full top, release it
-
- call new_cursor_type ;; new cursor type for each
- call new_cursor_on@ ;; take the cursor
-
- test video$,EGA+VGA ;; ega mono or color
- jz is_mono
- push bx ;; save VS->
- mov bl,VS_MODE1 ;; get current ega blink toggle
- and bl,BLINK_TOGGLE ; mask bit
- mov ah,10h ; int 10h sub function
- mov al,3 ; sub sub function - set toggle
- call int10_entry@
- pop bx ;; restore VS->
- is_mono:
-
- test VS_MODE1,LINE_43_MODE ;; test if 43 line mode
- jz not_43
- push bx ;; save VS->
- mov ax,1112h ; int 11h sub function
- mov bl,0
- call int10_entry@
- pop bx
- not_43:
-
- push bx
- mov dx,VS_CURSOR ; get cursor position
- mov ah,2 ; and reset
- xor bh,bh
- call int10_entry@
- pop bx ; restore VS->
-
- no_cur:
- or VS_MODE,UPDATE_BIT ; signal cursor has been moved
- call free_all_mxs@ ; allow updates
-
- mov bx,rlr$ ; PIN PD value
- lea di,P_NAME[bx] ; point to process name
- mov si,offset PINstr
- mov cx,3
- cld
- push es
- push ds ! pop es
- repe cmpsb ; is it 'PIN'
- pop es
- jne io_switch_done ; no ...
-
- in al,PORT_B ; always silence the beeper
- and al,BEEP_OFF
- jmps $+2
- out PORT_B,al
-
- io_switch_done:
- dec kbd_imhere$
- io_switch_exit:
- ret
-
- eject
- ;
- ; Entry: bx-> VS_
- ; dx= new Vcon
- ;
- ; Check timing of retrace to determine which mode the hercules card
- ; is in. If current mode <> new vcon mode, then we re-program
- ; accordingly.
- check_herc_card:
- cmp VS_SCREEN_MODE,07 ; check old mode for VGA
- jne no_check
- push bx ; save old VS_
- call point_vs@ ; get VS_ -> for new console
- cmp VS_CRT_SEG,MONO_SEG
- pop bx
- jne no_check
- cmp retrace$,0EEEEh ; check if hercules
- jne check_herc_mode
- no_check:
- ret
-
- check_herc_mode:
- push di
- push bx
- push dx ; save Vcon
-
-
- check_herc_again:
- mov dx,MONO_PORT+6 ; status port
- check_herc_active:
- sti ; interrupt "window"
- nop
- cli ; to here...
- in al,dx
- rol al,1 ; wait for active (bit 7 set)
- jnc check_herc_active
- in al,dx
- rol al,1 ; wait for retrace (bit 7 clr)
- jc check_herc_active
-
- ;read timer at start of retrace
- mov al,0
- out TIMER_CMND_REG,al ; latch timer 0
- in al,TIMER_0_REG ; lsb
- mov ah,al
- in al,TIMER_0_REG ; msb
- xchg al,ah ; swap to word value
- push ax ; save value
-
- herc_retrace_wait:
- in al,dx
- rol al,1 ; wait for active ( bit 7 set)
- jnc herc_retrace_wait
-
- ;read timer at end of retrace
-
- mov al,0
- out TIMER_CMND_REG,al ; latch timer 0
- in al,TIMER_0_REG ; lsb
- mov ah,al
- in al,TIMER_0_REG ; msb
- xchg al,ah ; swap to word value
- pop cx ; [cx] = old value...
- sub cx,ax ; [cx] = time difference
- sti
- jc check_herc_again ; oops.. looped try again
- or ax,ax
- jz check_herc_again ; oops.. timed down to zero
-
-
- ; check vs. min text value
-
- mov al,0 ; 0 = text mode
- cmp cx,retrace$
-
- jge check_herc_set ; if retrace >= init
- mov al,1 ; 1 = graphics mode
- test video$,COLOR ; don't test B800 if color present
- jnz check_herc_set
-
- mov ax,COLOR_SEG ; test if display page 1 selected
- mov es,ax
- mov ah,es:.0 ; do non destructive read\write test
- mov al,ah
- not al
- mov es:.0,al
- jmps $+2
- cmp al,es:.0
- mov es:.0,ah ; restore original value
- mov al,1 ; use display page 0
- jne check_herc_set
- mov al,81h ; else display page 1 (start B800)
-
- check_herc_set:
- mov VS_HERC_MODE,al ; save current hercules mode
- pop dx ; get new Vcon
- push dx
- push ax ; temp save mode
- call point_vs@ ; bx-> new Vcon
- pop ax ; [ax] = old mode
- cmp al,VS_HERC_MODE ; same ??
- je check_herc_rexit ; yes, no more..
-
- ; change mode graphics/text.
- mov di,offset herc_text$ ; assume text param
- mov al,0000$1000b ; and mode
- cmp VS_HERC_MODE,0 ; is it text ?
- je check_herc_load ; yes..
- mov di,offset herc_graph$ ; no.. use graphics
- mov al,VS_HERC_MODE ; get mode
- and al,1000$0000b ; mask page select bit
- or al,0000$1010b ; set graphics mode bit
-
- check_herc_load:
- push ax ; save mode
-
- cli
- mov dx,MONO_PORT+4
- and al,1000$0010b ; mask to text/graphics and page select
- out dx,al ; blank display..
-
- mov ah,0 ; port index 0..11
- mov cx,12 ; load/write loop
- check_herc_load_loop:
- mov dx,MONO_PORT
- mov al,ah
- out dx,al ; set index
- mov al,[di] ; load byte
- mov dx,MONO_PORT+1
- out dx,al ; send value
- inc ah
- inc di
- loop check_herc_load_loop
-
- mov dx,MONO_PORT+4
- pop ax ; get mode
- out dx,al ; and set display..
- sti
-
- check_herc_rexit:
- pop dx
- pop bx
- pop di
- check_herc_exit:
- ret
-
- eject
-
- new_cursor_type:
- ;---------------
- ; Set the cursor type as function of VS_CURTYPE in struct.
- ; Entry: bx --> vs_
- mov cx,VS_CUR_TYPE
- mov ah,1 ; int 10 function #
- jmp int10_entry@
-
-
- read_cursor:
- ;-----------
- ; Read physical cursor position from CRTC:
- ; Entry: bx -> vs_
- ; Exit: ax = CRTC cursor address
- push dx
- mov dx,MONO_PORT ; assume mono
- cmp VS_SCREEN_MODE,07
- jz c_in
- mov dx,COLOR_PORT ; change to color
- c_in:
- pushf ; save current int. state
- cli
- mov ax,0F0Eh ; CRTC reg #s
- out dx,al ; cursor high first
- inc dx
- jmps $+2 ; io delay
- in al,dx
- dec dx
- xchg ah,al ; save curs hi in ah
- out dx,al ; want curs lo
- inc dx
- jmps $+2
- in al,dx
- popff iret_op@
- pop dx
- ret
- eject
-
- ; *** BACK DOOR WINDOW CONTROL ROUTINES: ***
-
- ;===========
- ww_pointer@:
- ;===========
- ; Return pointers to window relevant information:
- ; entry: dl = vc number or 0FFH
- ; exit: if dl = vc then
- ; ax = vc structure pointer
- ; if dl = 0FFH then
- ; ax = window data block pointer
- ; AX = 0ffffh console not supported
-
- mov di,rlr$
- if SR
- cmp P_CONS[di],NUM_VIR_CONS ; is it master console
- jb main_vc
- push dx
- mov dl,P_CONS[di] ; get VC number
- call test_srterm@ ; is it SunRiver VC
- pop dx
- jz main_vc ; no...
- cmp dl,0ffh
- jne ww_point1
- mov ax,offset im_here$
- ret
- main_vc:
- endif
- cmp P_CONS[di],NUM_VIR_CONS ; make sure its master console
- mov ax,0ffffh ; else error return
- jae ww_ret1
- cmp dl,NUM_VIR_CONS ; if dl = legal vc
- jb ww_point1
- mov ax,offset im_here$
- ww_ret1:
- ret ; return window data block
- ww_point1:
- call point_vs@ ; if legal vc
- xchg ax,bx ; return vs_pointer
- ret
-
-
- ;===========
- ww_im_here@:
- ;===========
- ; Set window manager process state:
- ; entry: cl = im_here state
- ; 0 => manager not resident
- ; 1 => resident but not active
- ; 2 => resident and active
- ; 3 => leave im_here unchanged
- ; dl = vc number to switch to top
- ; if dl = 0FFH, then no switch
-
- if SR
- mov di,rlr$
- cmp P_CONS[di],NUM_VIR_CONS ; is it master console
- push dx
- jb main_vc1
- mov dl,P_CONS[di] ; get VC number
- call test_srterm@ ; is it SunRiver VC
- jz main_vc1 ; no...
- call point_pc@ ; get PC_ pointer in SI
- pop dx
- jmp sr_ww_im_here@
- main_vc1:
- pop dx
- endif
- cmp cl,3
- jae ww_just_switch ; if cl > 2, just switch
-
- mov im_here$,cl ; set state variable
- cmp cl,2
- jz ww_im_here_done ; if staying resident, skip
- mov key_flag$,CI_FLAG ; switch back to normal
- ww_just_switch:
- cmp dl,NUM_VIR_CONS
- jae ww_im_here_done ; if illegal, skip
-
- mov bl,dl ; to index reg
- sub bh,bh
- mov bl,scan_switch[bx]
- mov switch_key$,bl ; put it in place for CONIN
-
- mov dx,CI_FLAG ; now activate conin
- call flagset@
-
- pushf ; fake an interrupt
- callf dword ptr dispatcher$
- ww_im_here_done:
- ret
-
- scan_switch db END_SCAN ; pad 1 for 1st console
- db PAD2_SCAN ; for 2nd
- db PGDN_SCAN ; pad 3 for 3rd console
- db PAD4_SCAN ; for 4th
- eject
-
- ;==============
- ww_new_window@:
- ;==============
- ; Create a new window:
- ; entry: dl = virtual console number
- ; cx = top left (row,column)
- ; ax (bx at entry) = bottom right (row,column)
-
- push ax ; save bot_right
- call point_vs@ ; bx -> virt structure
- call get_all_mxs@ ;; lock out the world
- pop ax
- cmp cx,VS_TOP_LEFT ;; if new top_left
- jnz new_win1 ;; then skip
- cmp ax,VS_BOT_RIGHT ;; or if new bottom_right
- jnz new_win1 ;; then skip
- ;; if same window as before
- call update_no_check ;; then just update it
- jmps new_win3 ;; release and exit
-
- new_win1:
- if V386
- mov win_sized$,01h ;; signal windows sized (386)
- endif
- push ax
- call copy_full_top@ ;; save to image if full
- mov ax,VS_TOP_LEFT ;; get current corner
- mov VS_OLD_T_L,ax ;; and save for full switch
- mov ax,VS_BOT_RIGHT ;; do the same
- mov VS_OLD_B_R,ax ;; for the other corner
-
- mov VS_TOP_LEFT,cx
- pop cx
- mov VS_BOT_RIGHT,cx
-
-
- new_pc_window@: ;; special pc mode entry
- ;--------------
- mov al,VS_NUMBER
- cmp al,top_screen$ ;; now, if we're the top screen
- jnz new_back_window ;; then take care of the
- call switch_statline@ ;; status line switch
- new_back_window:
- call new_count ;; calc rows and cols
- call do_true_view@ ;; correct view point
- call new_vc_map ;; redo the vc_map
-
- mov dl,VS_MODE ;; get sync bit
- mov dh,mono_bits$ ;; assume monochrome
- cmp VS_SCREEN_MODE,07
- mov bx,VS_CRT_SEG ;; vs_ ptr is hammered
- je new_win2 ;; skip if mono
- mov dh,color_bits$ ;; color if not
- new_win2:
- call erase_crt@ ;; clear appropriate screen
- call update_all@ ;; and show the windows
- new_win3:
- jmp free_all_mxs@ ; release the works
- eject
-
- ;===============
- ww_cursor_view@:
- ;===============
- ; Set cursor tracking mode and viewpoint:
- ; entry: dl = vc number
- ; dh = cursor tracking mode
- ; 0 => window is fixed on vc image
- ; 1 => window tracks scrolling
- ; cx = row,column of top,left viewpoint
-
- call point_vs@ ; bx -> structure
- call get_mx@ ;; lock this vc
- mov VS_CUR_TRACK,dh ;; save tracking mode
- mov VS_VIEW_POINT,cx
- call do_true_view@ ;; correct view_point
- call update_window@ ;; show the view
- call show_cursor@ ;; and update the cursor
- mov VS_MX,0 ; release this vc
- ret
-
-
- ;===============
- ww_wrap_column@:
- ;===============
- ; Set virtual console wrap around column:
- ; entry: dl = vc number
- ; cl = wrap column number
-
- call point_vs@
- mov VS_WIDTH,cl ; set warp column
- ret
-
-
- ;==================
- ww_switch_display@:
- ;==================
- ; Switch between monochrome and color monitors:
- ; entry: dl = vc number
- ; cl = monitor code (0 => mono; 1 => color)
-
- call point_vs@ ; set up bx pointer
- cmp cl,01 ; if color
- jz ww_sw_disp1 ; then skip
- cmp cl,00 ; if mono
- jz ww_sw_disp2 ; then skip
- ret ; if illegal code, return
- ww_sw_disp1:
- jmp z_set_color@ ; jump to routine
- ww_sw_disp2:
- jmp z_set_mono@ ; jump to mono set
- eject
-
- ;===============
- ww_full_window@:
- ;===============
- ; Switch between full screen and small window:
- ; entry: dl = vc number
-
- call point_vs@ ; point to structure
- mov cx,0 ; top left
- mov ah,VS_CRT_ROWS
- dec ah
- mov al,CRT_COLS-1 ; ax -> bottom right
- mov di,ax ; save the corner
- cmp VS_TOP_LEFT,cx ; if the current top console
- jnz w_full1 ; is not a full screen,
- cmp VS_BOT_RIGHT,ax ; then make it one.
- jnz w_full1
- mov cx,VS_OLD_T_L ; if it is a full screen
- mov ax,VS_OLD_B_R ; then switch to previous.
- cmp cx,0 ; if old window is not
- jnz w_full2 ; a full screen
- cmp ax,di ; then go ahead.
- jnz w_full2
- ret ; if both full, bag it
- w_full1:
- jmp ww_new_window@ ; create the window
-
- w_full2:
- test VS_MODE,PCMODE_BIT
- jz w_full1 ; if we're leaving a pc full
- push bx
- call ww_new_window@ ; first create the window
- pop bx
- mov di,(CRT_ROWS_P-1) * CRT_COLS * 2
- mov cx,CRT_COLS ; clear across
- mov ax,0720h ; spaces
- jmp put_crt_s@ ; clear the bottom line
-
-
- save_ega_screen:
- ;---------------
- ; Save that portion of the EGA screen which will be overwritten when
- ; we start putting text up on the screen.
- call point_vs@ ; bx = new VS_
- push es ! push dx
- mov cx,PC_SEGMENT
- mov es,cx
- mov cx,VS_PC_EQUIP ; equipment flag for new screen
- push es:equip_flag_40 ; save current
- mov es:equip_flag_40,cx ; update ROS data area
- and cl,30h ; is it mono
- cmp cl,30h
- mov ax,0083h ; mode switch to alpha/80
- jne save_ega1
- mov ax,0087h ; mode switch to alpha/80
- save_ega1:
- call int10_entry@
- pop es:equip_flag_40 ; restore equip word
-
- ; The regen buff is now addressed at B800/B000, so it can be read.
- mov dl,top_screen$
- call point_vs@ ; bx = old VS_
-
- cmp cl,30h ; test equipment byte if MONO
- mov cx,COLOR_SEG ; assume colour
- jne save_ega2
- mov cx,MONO_SEG ; no, it's mono
- save_ega2:
- push ds
- xor si,si
- xor di,di
- mov es,VS_VC_SEG ; image is destination
- mov ds,cx ; screen is source
- mov ah,IN_SYNC
- mov cx,CRT_ROWS_P*CRT_COLS ; max image size
- call put_crt_m@
- call old_cursor_off@ ; for 2 monitor switch
- pop ds
-
- pop dx ! pop es
- or VS_MODE,MATCH_BIT ; say VS_ copy matches screen
- ret
-
- restore_ega_screen:
- ;------------------
- ; Restore those bits of the EGA screen we have previously saved
- ; when we changed to text mode.
- push ds
- mov ax,PC_SEGMENT
- mov ds,ax
- mov ax,equip_flag_40
- and al,30h
- cmp al,30h ; is current video mono ?
- pop ds
-
- push VS_CRT_SEG ; save CRT_SEG (so we can fiddle it)
- mov VS_CRT_SEG,COLOR_SEG ; assume colour
- jne restore_ega1
- mov VS_CRT_SEG,MONO_SEG ; no, it's mono
- restore_ega1:
- call update_window@ ; repaint the window
- pop VS_CRT_SEG ; restore real CRT_SEG
- ret
-
- dseg
-
- if 0
- ; Entry for each virtual screen:
-
- kbd_vects$ dw i_keyboard@,0 ; segment gets setup in init
- dw i_keyboard@,0
- dw i_keyboard@,0
- dw i_keyboard@,0
- endif
-
- old_vc rb 1
-
- PINstr db 'PIN' ; pin rsp name
-
- save_dx dw 0
- end
-
- ; END OF WINDOWS2.A86
-
-
-