home *** CD-ROM | disk | FTP | other *** search
/ Piper's Pit BBS/FTP: ibm 0010 - 0019 / ibm0010-0019 / ibm0010.tar / ibm0010 / CDOSDSK5.ZIP / CDOSDSK5.TD0 / XIOS / WINDOWS2.A86 < prev    next >
Encoding:
Text File  |  1989-01-26  |  39.4 KB  |  1,680 lines

  1. ; WINDOWS2.A86
  2. title '2nd Level Window Routines'
  3. pagesize 60+11
  4. ;************************************************
  5. ;*                        *
  6. ;*    INTERMEDIATE VIRTUAL SCREEN ROUTINES    *
  7. ;*    WINDOW MANAGER XIOS CALLS        *
  8. ;*    CDOS 6.0 XIOS                *
  9. ;*    DRI OS ENGR, JMB, GMS            *
  10. ;*                        *
  11. ;************************************************
  12. ; Major mods:
  13. ; 6.x
  14. ;  8 Nov 88 -- io_switch saves VGA/EGA screen when windowing    IJ
  15. ; 18 AUG 88 -- Fix up PIN VC for MGE in io_switch        GMS
  16. ;  3 AUG 88 -- Always turn beeper off on io_switch        GMS
  17. ;  5 Jul 88 -- Keep ROS data in step over screen switch        IJ
  18. ;  7 APR 88 -- Sun River support added                GMS
  19. ; 11 JAN 88 -- io_switch saves and restores PC equipment flag    GMS
  20. ;  7 DEC 87 -- int10_bx entries replaced with int10_entry    GMS
  21. ;  7 DEC 87 -- VS_SCREEN_MODE now uses ROS video mode values    GS
  22. ;  2 DEC 87 -- replaced ega$ with redefined video$        GS
  23. ; 6.0
  24. ; 13 NOV 87 -- reset ega pallette from new_screen_mode        GS/JW
  25. ;  9 NOV 87 -- return error from ww_pointer if serial vc    GMS
  26. ;  7 NOV 87 -- add int10_si@ entry for int 10's w/ BX = param    JW
  27. ;  5 NOV 87 -- check page select on hercules retrace timing    GMS
  28. ;  4 NOV 87 -- set blink toggle for ega mono            GMS
  29. ; 17 JUL 87 -- converted XIOS to small model            JW
  30. ; 22 JUN 87 -- 43 line ega support                GMS
  31. ; 17 JUN 87 -- get cursor position from ROS if switching from graphics GMS
  32. ; 5.2
  33. ; 26 MAY 87 -- set graphics flag at io_switch if process suspended GMS
  34. ;  7 APR 87 -- added support for extra olivetti video modes    GMS
  35. ; 27 FEB 87 -- Reset EGA blink toggle state on io_switch    GMS
  36. ; 5.1
  37. ; 14 JAN 87 -- Do not read hardware cursor if not yet updated    GMS
  38. ; 27 OCT 86 -- Save hercules mode on switch                     PAR
  39. ; 27 OCT 86 -- switch timer vector at io_switch@ - removed    GMS
  40. ; 14 APR 86 -- save cursor on screen switch by reading CRTC
  41. ;  8 JAN 86 -- EGA adjustment
  42. ;  4 DEC 85 -- EGA adjustment
  43. ; 14 JUN 85 -- update 4.1 ASM86 XIOS to RASM86
  44.  
  45. ; include COPYRITE.TXT
  46.  
  47. nolist
  48. include CDOS.EQU
  49. include XIOS.EQU
  50. include PCHW.EQU
  51. include ROSDATA.EQU
  52. if SR
  53. include SR.EQU
  54. endif
  55. list
  56. ; These were included:
  57. ; include CDOS.EQU
  58. ; include XIOS.EQU
  59. ; include PCHW.EQU
  60. ; include ROSDATA.EQU
  61. if SR
  62. ; include SR.EQU
  63. endif
  64.  
  65. CGROUP    group    CODE
  66. DGROUP    group    DATA
  67.  
  68. public    io_switch@
  69. public    ww_pointer@,    ww_im_here@
  70. public    ww_new_window@,    ww_cursor_view@
  71. public    ww_wrap_column@,ww_full_window@
  72. public    ww_switch_display@
  73. public    point_cursor@,    point_vs@,    get_mx@
  74. public  free_all_mxs@,    get_all_mxs@
  75. public    new_pc_window@, do_true_view@,    check_full_top@
  76. public    xlat_priority@, new_monitor@
  77. public    restore_state@,    check_full@,    update_window@
  78. public    update_all@,    set_new_mon@
  79. public    con_scan@
  80. public    leave_until_char@
  81. if 0
  82. public    kbd_vects$
  83. endif
  84. eject
  85.  
  86.     dseg
  87.  
  88. extrn    kbd_imhere$    :byte
  89.  
  90. extrn    nvcns$        :byte                ; in HEADER.A86
  91.  
  92. extrn    key_flag$    :word, switch_key$    :byte    ; in KEYBOARD.A86
  93. extrn    im_here$    :byte, win_sized$    :byte    ; in PUBDATA.A86
  94.  
  95. extrn    vc_priority$    :byte, mono_bits$    :byte    ; in WINDOWS3.A86
  96. extrn    color_bits$    :byte, top_screen$    :byte
  97. extrn    s_lines$    :byte, d_lines$        :byte
  98. extrn    first_vs$    :word, vc_map_seg$    :word
  99. if not SR
  100. extrn    list_next$    :word, list_vc$       :byte
  101. endif
  102. extrn    table_vs$    :word, vc_list$        :word
  103. extrn    top_screen_mode$:byte
  104. extrn    video$:byte                    ; in WINDOWS1.A86
  105.  
  106. extrn   retrace$        :word 
  107. extrn   herc_text$      :word, herc_graph$      :word
  108. extrn    cloneflag$     :byte
  109. if V386
  110. extrn    active_vc$:byte                ; in PCTERM.A86
  111. endif
  112. if SR
  113. extrn    sr_vs_table$    :byte                ; in PUBDATA.A86
  114. extrn    SR_VS_TLEN    :abs
  115. extrn    sr_table_vs$    :word
  116. extrn    first_vs_num$    :byte
  117. extrn    num_vir_cons$    :byte
  118. extrn    ccb_list$    :word
  119. extrn    num_sr_vs_cons$    :byte                ; in SRTERM.A86
  120. endif
  121.  
  122.     cseg
  123. extrn    flagset@    :near                ; in HEADER.A86
  124. extrn    supervisor$    :dword, supif@:near
  125. extrn    check_no_switch@:near                ; in CONIN.A86
  126.  
  127. extrn    i_keyboard@    :near                ; in KEYBOARD.A86
  128. extrn    i_clock@    :near                ; in ISRS.A86
  129. extrn    clear_statline@ :near, switch_statline@    :near    ; in STATLINE.A86
  130. extrn    con_normal@    :near, screen_set_only@ :near    ; in WINDOWS1.A86
  131. extrn    new_cursor_on@    :near, old_cursor_off@    :near
  132. extrn    show_cursor@    :near
  133. extrn    z_set_color@    :near, z_set_mono@    :near
  134. extrn    ros_color@    :near
  135. extrn    save_plane2@    :near, restore_plane2@    :near
  136. extrn    ega_pallette@    :near
  137.  
  138. extrn    erase_crt@    :near, draw_frame@    :near    ; in WINDOWS3.A86
  139. extrn    put_crt_m@    :near
  140. extrn    draw_frame_s@    :near, draw_frame_d@    :near
  141. extrn    copy_full_top@    :near, put_crt_s@    :near
  142.  
  143. extrn    int10_entry@    :near                ; in ROSIF.A86
  144. if SR
  145. extrn    point_pc@    :near,test_srterm@    :near    ; in SRTERM.A86
  146. extrn    sr_ww_im_here@    :near
  147. endif
  148.  
  149. eject
  150.  
  151. ; ***  Console Out Subroutines  ***
  152.  
  153. set_new_mon@:
  154. ;-----------
  155. ; Clear both screens, new xlats, and update all;
  156. ; Called from init, esc x, and esc y;
  157. ; This routine locks up the mx semaphores.
  158.  
  159.     cli                    ;; a little critical section
  160.     mov    VS_MX,0                ;; to keep from blocking
  161. new_monitor@:                    ;; entry from init
  162.     call    get_all_mxs@            ;; lock 'em up
  163.     sti
  164.     mov    si,offset vc_priority$
  165. if SR
  166.     mov    ax,NUM_VIR_CONS            ;; max VS
  167.     mov    cl,num_vir_cons$        ; number of VS this PC
  168.     xor    ch,ch
  169.     sub    ax,cx
  170.     add    si,ax                ; up pointer
  171. else
  172.     mov    cx,NUM_VIR_CONS
  173. endif
  174. new_mon1:
  175.     push    cx
  176.     mov    dl,[si]                ;; get relative vc number
  177.     call    point_vs@            ;; bx -> structure
  178.     call    new_xlat            ;; redo the table
  179.     pop    cx
  180.     inc    si                ;; next vc up
  181.     loop    new_mon1
  182.  
  183.     test    video$,MONO            ;; if no monochrome card
  184.      jz    new_mon2            ;;   then skip erase
  185.  
  186.     mov    dh,mono_bits$            ;; which vc's are mono
  187.     mov    dl,0                ;; no sync
  188.     mov    bx,MONO_SEG
  189.     call    erase_crt@            ;; clear mono screen
  190. new_mon2:
  191.     test    video$,COLOR            ;; if no color card
  192.      jz    new_mon3            ;;   then skip erase
  193.  
  194.     mov    dh,color_bits$            ;; which vc's are color
  195.     mov    dl,SYNC_BIT            ;; retrace sync
  196.     mov    bx,COLOR_SEG 
  197.     call    erase_crt@            ;; clear color screen
  198. new_mon3:
  199.     call    update_all@            ;; new screens all around
  200.     jmp    free_all_mxs@            ; let my semaphores go
  201. eject
  202.  
  203. update_all@:
  204. ;----------
  205. ; Update all windows:
  206. ; Called from new_window, new_monitor@ and screen_set_only@
  207.  
  208.     call    new_vc_list            ; redo the row list
  209.     mov    si,offset vc_priority$
  210. if SR
  211.     mov    ax,NUM_VIR_CONS            ;; max VS
  212.     xor    ch,ch
  213.     mov    cl,num_vir_cons$        ; number of VS this PC
  214.     sub    ax,cx
  215.     add    si,ax                ; up pointer
  216. else
  217.     mov    cx,NUM_VIR_CONS
  218. endif
  219. up_all1:
  220.     push    si
  221.     push    cx
  222.     mov    dl,[si]                ; get vc number
  223.     call    point_vs@            ; bx -> virt structure
  224.     mov    si,offset s_lines$
  225.     cmp    cl,1                ; if not front vc
  226.      jnz    up_all2                ;   then skip
  227.     mov    si,offset d_lines$
  228. up_all2:
  229.     call    draw_frame@            ; frame the window and
  230.     call    update_window@            ;   fill it
  231.     pop    cx
  232.     pop    si
  233.     inc    si                ; next window up
  234.     loop    up_all1                ; NUM_VIR_CONS times
  235.  
  236.     call    release_match            ; if full top, release it
  237.     call    new_cursor_on@            ; turn on the cursor
  238.     jmp    show_cursor@            ; display and done
  239. eject
  240.  
  241. update_window@:
  242. ;-------------
  243. ; Move the vc image to its window unless full on top:
  244. ;  entry:    bx -> vs_
  245.  
  246.     test    VS_MODE,MATCH_BIT
  247.      jz    up_win2            ; skip if full on top
  248.  
  249. if SR                ; THIS IS TEMPORARY TO GET VS GOING
  250.                 ; eventually vc_list needs to implemented
  251.                 ; for SR terminals
  252. ;;    cmp    first_vs_num$,0        ; master console
  253. ;;    jne    update_gr        ; no .. update SunRiver
  254. endif
  255.     test    VS_MODE1,LINE_43_MODE    ; if new mode 43
  256.     jnz    update_gr        ; treat like graphics
  257.     cmp    VS_SCREEN_MODE,04
  258.     jb    update_no_check
  259.     cmp    VS_SCREEN_MODE,07    ; is this console in graphics mode?
  260.      je    update_no_check        ;  N: jump to normal update
  261. update_gr:
  262.     mov    al,top_screen$
  263.     cmp    al,VS_NUMBER        ; is this console on top?
  264.      jne    up_win2            ;  N: skip graphics update
  265.     push    si            ;  Y: blast graphics w/o row check
  266.     push    ds ! push es
  267.     sub    di,di
  268.     mov    si,di
  269.     mov    es,VS_CRT_SEG
  270.     mov    ds,VS_VC_SEG
  271.     mov    ah,OUT_SYNC
  272.     mov    cx,CRT_ROWS_P*CRT_COLS    ; max image size
  273.     call    put_crt_m@
  274.     pop    es ! pop ds
  275.     pop    si
  276.     ret
  277.     
  278. update_no_check:
  279.     call    correct_ptr            ; calc correction
  280.     shl    dx,1                ; word pointer now
  281.     mov    si,VS_LIST_PTR            ; point to row list
  282. up_win1:
  283.     lodsw                    ; get count
  284.     xchg    ax,cx
  285.      jcxz    up_win2                ; done when zero
  286.     lodsw                    ; get pointer
  287.     mov    di,ax                ; point to crt
  288.     sub    ax,dx                ; correct window pos
  289.  
  290.     push    si
  291.     push    ds ! push es
  292.     xchg    ax,si                ; point to vc image
  293.     mov    es,VS_CRT_SEG
  294.     mov    ds,VS_VC_SEG
  295.     mov    ah,OUT_SYNC            ; from image to crt
  296.     call    put_crt_m@            ; move string
  297.     pop    es ! pop ds
  298.     pop    si
  299.     jmps    up_win1                ; do next row
  300. up_win2:
  301.     ret
  302.  
  303. eject
  304.  
  305. release_match:
  306. ; If full screen on top and no sync, reset MATCH_BIT:
  307. ;  entry:    bx -> vs_
  308.  
  309.     or    VS_MODE,MATCH_BIT
  310.     call    check_full_top@
  311.      jnz    release_done
  312.     and    VS_MODE,not MATCH_BIT
  313. release_done:
  314.     ret
  315.  
  316.  
  317. check_full_top@:
  318. ; If full screen on top, set zero flag:
  319. ;  entry:    bx -> vs_
  320.  
  321.     call    check_full@            ; first see if it's full
  322.      jnz    check_ft_done            ; skip if not full
  323.     mov    al,top_screen$
  324.     cmp    VS_NUMBER,al            ; if top, set zf
  325. check_ft_done:
  326.     ret
  327.  
  328.  
  329. check_full@:
  330. ; If full screen, set zero flag:
  331. ;  entry:    bx -> vs_
  332.  
  333.     mov    al,VS_CRT_ROWS
  334.     cmp    VS_ROWSB,al
  335.      jnz    check_f_done            ; skip if not full
  336.     cmp    VS_COLSB,CRT_COLS
  337. check_f_done:
  338.     ret                    ; with flag set
  339. eject
  340.  
  341. get_mx@:
  342. ; Get semaphore for this vc:
  343. ;  entry:    bx -> vs_
  344. ;  exit:    pres. bp
  345.     mov    al,0FFh                ; ownership true
  346.     xchg    al,VS_MX            ; test and set semaphore
  347.     test    al,al                ; if nobody owned it
  348.      jz    got_mx                ; then we're done
  349.  
  350. ; If semaphore is blocked, wait a tick and try again:
  351.     push    bx
  352.     push    cx
  353.     push    dx
  354.     push    es
  355.     push    bp
  356.     mov    cx,P_DELAY
  357.     mov    dx,1                ; wait at least 1 tic
  358.     mov    bx,rlr$                ; ready list root
  359.     mov    es,P_UDA[bx]            ; load the uda
  360.     callf    supervisor$            ; like a bdos int
  361.     pop    bp
  362.     pop    es
  363.     pop    dx
  364.     pop    cx
  365.     pop    bx
  366.     jmps    get_mx@                ; back and try again
  367. got_mx:
  368.     ret
  369.  
  370. get_all_mxs@:
  371. ; Get semaphore queues for all vc's:
  372.     push    bx
  373.     push    cx
  374.     xor    bx,bx
  375.     mov    cx,NUM_VIR_CONS
  376. get_all1:
  377.     push    bx
  378.     mov    bx,table_vs$[bx]
  379.     call    get_mx@                ; get one at a time
  380.     pop    bx
  381.     add    bx,2                ; next VC
  382.     loop    get_all1            ; for each vc
  383. if SR
  384.     mov    cl,num_sr_vs_cons$        ; total number of SR VS_
  385.     cmp    cl,0
  386.     je    get_alldone
  387.     mov    bx,offset sr_table_vs$
  388. get_all2:
  389.     push    bx
  390.     mov    bx,[bx]                ; get VS pointer
  391.     call    get_mx@
  392.     pop    bx
  393.     inc bx ! inc bx
  394.     loop    get_all2
  395. endif
  396. get_alldone:
  397.     pop    cx
  398.     pop    bx
  399.     ret
  400.  
  401. free_all_mxs@:
  402. ; Release semaphores for all vc's:
  403.     push    bx
  404.     push    cx
  405.     xor    bx,bx
  406.     mov    cx,NUM_VIR_CONS
  407. free_all1:
  408.     push    bx
  409.     mov    bx,table_vs$[bx]
  410.     mov    VS_MX,0                ; free the semaphore
  411.     pop    bx
  412.     add    bx,2                ; next VC
  413.     loop    free_all1            ; for each vc
  414. if SR
  415.     mov    cl,num_sr_vs_cons$        ; total number of SR VS_
  416.     cmp    cl,0
  417.     je    free_all_done
  418.     push    si
  419.     mov    si,offset sr_table_vs$
  420. free_all2:
  421.     mov    bx,[si]                ; get VS pointer
  422.     mov    VS_MX,0                ; free the semaphore
  423.     inc si ! inc si
  424.     loop    free_all2
  425.     pop    si
  426. endif
  427. free_all_done:
  428.     pop    cx
  429.     pop    bx
  430.     ret
  431.  
  432.  
  433. correct_ptr:
  434. ; Calculate window position offset correction:
  435.     cmp    VS_CUR_TRACK,0            ; if no tracking,
  436.      jz    cor_ptr2            ;   then skip
  437.     mov    ah,VS_CUR_ROW            ; this corrects for
  438.     mov    al,VS_TRUE_ROW            ;   a scrolling screen
  439.     cmp    al,ah                ; if cursor above view
  440.      ja    cor_ptr1            ;   then move view up
  441.     sub    ah,VS_ROWSB            ; if within a window
  442.      js    cor_ptr2            ;   of top, skip
  443.     cmp    al,ah                ; if cursor within view
  444.      ja    cor_ptr2            ;   then also skip
  445.     inc    ah                ; cursor at window bottom
  446. cor_ptr1:
  447.     mov    VS_TRUE_ROW,ah
  448. cor_ptr2:
  449.     mov    dx,VS_TOP_LEFT
  450.     call    point_cursor@            ; static correction
  451.     xchg    ax,dx                ; save in dx
  452.  
  453.     mov    al,CRT_COLS
  454.     mul    VS_TRUE_ROW
  455.     sub    dx,ax                ; correct for row
  456.     mov    al,VS_TRUE_COL
  457.     cbw
  458.     sub    dx,ax                ; and column
  459.     mov    VS_CORRECT,dx            ; save for char out
  460.     ret
  461. eject
  462.  
  463. new_priority:
  464. ; Update vc priority list and xlat table:
  465. ;  entry:    bl -> vs_
  466. ;        dl = vc number
  467.  
  468.     push    es
  469.     push    ds ! pop es            ; local es
  470.     mov    di,offset vc_priority$
  471. if SR
  472.     mov    ax,NUM_VIR_CONS            ;; max VS
  473.     xor    ch,ch
  474.     mov    cl,num_vir_cons$        ; number of VS this PC
  475.     sub    ax,cx
  476.     add    di,ax                ; up pointer
  477. else
  478.     mov    cx,NUM_VIR_CONS
  479. endif
  480.     mov    al,dl                ; this vc
  481.     repnz    scasb                ; find ours
  482.     pop    es
  483.      jcxz    new_xlat            ; done if on top
  484.     dec    di                ; for overscan
  485. new_prior1:
  486.     mov    al,1[di]            ; get the one above
  487.     mov    [di],al                ;   and move it down
  488.     inc    di
  489.     loop    new_prior1            ; to top of list
  490.     mov    [di],dl                ; put us on top
  491.     jmps    new_xlat            ; fall through
  492.  
  493.  
  494. new_screen_mode:
  495. ; Change screen mode if necessary:
  496. ;  entry:    bx -> vs_
  497. ;        ax = ega bits of old screen
  498.  
  499.     test    al,LINE_43_MODE            ; test if old mode was 43 lines
  500.     mov    al,VS_SCREEN_MODE        ; 
  501.     jnz    do_screen_mode            ; 
  502.     cmp    al,top_screen_mode$        ;  if modes staying the same,
  503.     jz    new_screen_done            ;  then quit
  504. do_screen_mode:
  505.     test    video$,EGA+VGA+MCGA
  506.     jnz    is_ega
  507.     cmp    VS_SCREEN_MODE,07        ; if we're not switching
  508.      je    new_screen_fini            ;  to color, then quit
  509. is_ega:
  510.     mov    cl,al                ; cl = new screen mode
  511.     or    cl,80h                ; set no clear bit for ega/vga
  512. is_ega_alpha:
  513.     call    screen_set_only@        ; and ret
  514.     jmps    new_screen_fini
  515. new_screen_done:
  516.     mov    dx,COLOR_PORT
  517.     call    ros_color@            ; need to set new pallette
  518. new_screen_fini:
  519.     mov    dl,VS_CONMODE            ; is new process suspended
  520.     or    dl,dl
  521.      jz    new_screen_exit            ; on screen_set mode
  522.     xor    dh,dh
  523.     push    bx
  524.     call    flagset@            ; set flag to restart process
  525.     pop    bx
  526. new_screen_exit:
  527.     test    video$,EGA+VGA
  528.     jz    new_screen_ret
  529.     call    ega_pallette@            ; make sure we reset those 
  530. new_screen_ret:                    ; pallettes correctly
  531.     ret    
  532. eject
  533.  
  534. new_xlat:
  535. ; Update vc_xlat table:
  536.     mov    di,VS_XLAT
  537.     mov    al,VS_BIT            ; bit position = vc
  538.     mov    ah,0                ; count
  539.     mov    cx,1 shl NUM_VIR_CONS        ; bytes per vc_xlat
  540. new_xlat1:
  541.     test    ah,al                ; is this ours?
  542.      jz    new_xlat2            ; if not, skip
  543.     mov    [di],dl                ; if so, take it over
  544. new_xlat2:
  545.     inc    ah                ; next number
  546.     inc    di                ; next table byte
  547.     loop    new_xlat1            ; through xlat table
  548.     ret
  549. eject
  550. if SR
  551. new_vc_list:
  552. ; Make a new vc_list for switch or new_window:
  553.     push    bp
  554.     push    es
  555.     push    bx                ; save vs_ pointer
  556.     mov    dl,first_vs_num$
  557.     call    point_pc@            ; point to PC_ structure
  558.     mov    bp,si                ; pointer to BP
  559.     mov    es,vc_map_seg$            ; base of vc_map
  560.     mov     si,ds:PC_VC_LIST[bp]
  561.     mov    dl,num_vir_cons$
  562.     dec    dl
  563.     mov    ds:PC_LIST_VC[bp],dl
  564.  
  565. new_list1:
  566.     mov    dl,ds:PC_LIST_VC[bp]        ; get vc number
  567.     add    dl,first_vs_num$        ; 
  568.     call    point_vs@            ; bx -> vs_
  569.     mov    ds:PC_LIST_NEXT[bp],-1        ; impossible value
  570.     mov    VS_LIST_PTR,si
  571.     mov    dx,VS_TOP_LEFT
  572.     mov    cx,VS_ROWS            ; rows in window
  573. new_list2:
  574.     push    cx
  575.     push    dx
  576.     call    point_cursor@            ; ax -> vc_map pos
  577.     xchg    ax,di
  578.     mov    cx,VS_COLS            ; columns in window
  579. new_list3:
  580.     mov    al,es:[di]            ; 1st vc_map code
  581.     push    ax
  582.     call    xlat_priority@            ; al = who owns it
  583.     mov    ah,ds:PC_LIST_VC[bp]
  584.     add    ah,first_vs_num$
  585.     cmp    al,ah                ; if it's us
  586.     pop    ax
  587.      jz    new_list4            ;   then skip
  588.  
  589.     repz    scasb                ; if not, just scan
  590.      jz    new_list8            ; skip if end of line
  591.  
  592.     dec    di                ; else, correct for
  593.     inc    cx                ;   over scan
  594.     jmps    new_list3
  595.  
  596. new_list4:
  597.     mov    dx,di                ; save first pointer
  598.     repz    scasb                ; scan through our own
  599.      jz    new_list5            ; skip if line end
  600.  
  601.     dec    di                ; else, correct for
  602.     inc    cx                ;   over scan
  603. new_list5:
  604.     mov    ax,di
  605.     sub    ax,dx                ; ax = scan count
  606.     cmp    dx,ds:PC_LIST_NEXT[bp]        ; if string contiguous
  607.     jz    new_list6            ;   then add to count
  608.  
  609.     mov    [si],ax                ; if not, save count
  610.     inc    si
  611.     inc    si
  612.     mov    [si],dx                ;    and pointer
  613.     add    [si],dx                ; vc_ptr = 2*map_ptr
  614.     inc    si
  615.     inc    si
  616.     jmps    new_list7            ; and carry on
  617.  
  618. new_list6:
  619.     add    NEG4[si],ax            ; add to last count
  620. new_list7:
  621.     add    ax,dx                ; pointer plus count
  622.     mov    ds:PC_LIST_NEXT[bp],ax        ; update next pointer
  623.     test    cx,cx                ; if scan not done
  624.      jnz    new_list3            ;   then continue
  625. new_list8:
  626.     pop    dx
  627.     pop    cx
  628.     inc    dh                ; next row down
  629.     cmp    dh,VS_BOTTOM
  630.      jbe    new_list2            ; do all rows
  631.  
  632.     mov    word ptr [si],0            ; list end flag
  633.     inc    si
  634.     inc    si                ; to next vc's list
  635.     dec    ds:PC_LIST_VC[bp]
  636.      jns    new_list1            ; do all vc's
  637.     pop    bx                ; restore vs_ ptr
  638.     pop    es
  639.     pop     bp
  640.     ret
  641.  
  642. else
  643. new_vc_list:
  644. ; Make a new vc_list for switch or new_window:
  645.     push    es
  646.     push    bx                ; save vs_ pointer
  647.     mov    es,vc_map_seg$            ; base of vc_map
  648.     mov    si,offset vc_list$
  649.     mov    list_vc$,NUM_VIR_CONS-1        ; vc counter
  650.  
  651. new_list1:
  652.     mov    dl,list_vc$            ; get vc number
  653.     call    point_vs@            ; bx -> vs_
  654.     mov    list_next$,-1            ; impossible value
  655.     mov    VS_LIST_PTR,si
  656.     mov    dx,VS_TOP_LEFT
  657.     mov    cx,VS_ROWS            ; rows in window
  658. new_list2:
  659.     push    cx
  660.     push    dx
  661.     call    point_cursor@            ; ax -> vc_map pos
  662.     xchg    ax,di
  663.     mov    cx,VS_COLS            ; columns in window
  664. new_list3:
  665.     mov    al,es:[di]            ; 1st vc_map code
  666.     push    ax
  667.     call    xlat_priority@            ; al = who owns it
  668.     cmp    al,list_vc$            ; if it's us
  669.     pop    ax
  670.      jz    new_list4            ;   then skip
  671.  
  672.     repz    scasb                ; if not, just scan
  673.      jz    new_list8            ; skip if end of line
  674.  
  675.     dec    di                ; else, correct for
  676.     inc    cx                ;   over scan
  677.     jmps    new_list3
  678.  
  679. new_list4:
  680.     mov    dx,di                ; save first pointer
  681.     repz    scasb                ; scan through our own
  682.      jz    new_list5            ; skip if line end
  683.  
  684.     dec    di                ; else, correct for
  685.     inc    cx                ;   over scan
  686. new_list5:
  687.     mov    ax,di
  688.     sub    ax,dx                ; ax = scan count
  689.     cmp    dx,list_next$            ; if string contiguous
  690.     jz    new_list6            ;   then add to count
  691.  
  692.     mov    [si],ax                ; if not, save count
  693.     inc    si
  694.     inc    si
  695.     mov    [si],dx                ;    and pointer
  696.     add    [si],dx                ; vc_ptr = 2*map_ptr
  697.     inc    si
  698.     inc    si
  699.     jmps    new_list7            ; and carry on
  700.  
  701. new_list6:
  702.     add    NEG4[si],ax            ; add to last count
  703. new_list7:
  704.     add    ax,dx                ; pointer plus count
  705.     mov    list_next$,ax            ; update next pointer
  706.     test    cx,cx                ; if scan not done
  707.      jnz    new_list3            ;   then continue
  708. new_list8:
  709.     pop    dx
  710.     pop    cx
  711.     inc    dh                ; next row down
  712.     cmp    dh,VS_BOTTOM
  713.      jbe    new_list2            ; do all rows
  714.  
  715.     mov    word ptr [si],0            ; list end flag
  716.     inc    si
  717.     inc    si                ; to next vc's list
  718.     dec    list_vc$
  719.      jns    new_list1            ; do all vc's
  720.     pop    bx                ; restore vs_ ptr
  721.     pop    es
  722.     ret
  723.  
  724. endif
  725.  
  726.  
  727.  
  728. eject
  729.  
  730.  
  731.  
  732. eject
  733.  
  734. new_count:
  735. ; Update row and column counts:
  736. ;  entry:    bx -> vs_
  737.     mov    al,VS_BOTTOM
  738.     sub    al,VS_TOP            ; rows - 1
  739.     cbw
  740.     inc    ax                ; row count
  741.     mov    VS_ROWS,ax
  742.  
  743.     mov    al,VS_RIGHT
  744.     sub    al,VS_LEFT            ; columns - 1
  745.     cbw
  746.     inc    ax                ; column count
  747.     mov    VS_COLS,ax
  748.     ret
  749.  
  750.  
  751. do_true_view@:
  752. ;------------
  753. ; Correct view point if window is off image:
  754. ;  entry:    bx -> vs_
  755.  
  756.     mov    dx,VS_VIEW_POINT
  757.     mov    al,VS_CRT_ROWS
  758.     sub    al,VS_ROWSB            ; get max view row
  759.     cmp    al,dh
  760.      jae    do_true1            ; skip if ok
  761.     mov    dh,al                ; else replace with max
  762. do_true1:
  763.     mov    al,CRT_COLS
  764.     sub    al,VS_COLSB            ; get max view col
  765.     cmp    al,dl
  766.      jae    do_true2            ; skip if ok
  767.     mov    dl,al                ; else replace with max
  768. do_true2:
  769.     mov    VS_TRUE_VIEW,dx            ; save for correct_ptr
  770.     ret
  771. eject
  772.  
  773. new_vc_map:
  774. ; Update vc_map for change of window:
  775. ;  entry:    bx -> vs_
  776. ;        dl = vc number
  777.  
  778.     push    es
  779.     mov    es,vc_map_seg$
  780.     sub    di,di                ; top left corner
  781.     mov    cx,CRT_ROWS_P * CRT_COLS
  782.     mov    al,VS_BIT            ; get vc bit mask
  783.     not    al
  784. new_map1:
  785.     and    es:[di],al            ; wipe out old window
  786.     inc    di
  787.     loop    new_map1            ; for entire screen
  788.  
  789. ; Then calculate window limits:
  790.     mov    dx,VS_TOP_LEFT
  791.     cmp    dh,0                ; if at crt top
  792.      jz    new_map2            ;   skip top frame
  793.     dec    dh                ; include frame
  794. new_map2:
  795.     cmp    dl,0                ; if at crt left
  796.      jz    new_map3            ;   skip left frame
  797.     dec    dl                ; include frame
  798. new_map3:
  799.     mov    cx,VS_BOT_RIGHT
  800.     cmp    ch,CRT_ROWS_P-1            ; if at the 25th line
  801.      jz    new_map4            ;   skip bottom frame
  802.     inc    ch                ; include frame
  803. new_map4:
  804.     cmp    cl,CRT_COLS-1            ; if at crt right
  805.      jz    new_map5            ;   skip right frame
  806.     inc    cl                ; include frame
  807. new_map5:
  808.     call    point_cursor@            ; ax -> top left
  809.     xchg    ax,di
  810.     sub    cx,dx                ; row & col difference
  811.     add    cx,0101h            ; ch=rows, cl=cols
  812.  
  813. ; Now install the new window:
  814.     mov    al,VS_BIT            ; restore vc bit mask
  815. new_map6:
  816.     push    di
  817.     push    cx
  818. new_map7:
  819.     or    es:[di],al            ; or in vc's bit
  820.     inc    di
  821.     dec    cl                ; column count
  822.      jnz    new_map7
  823.     pop    cx
  824.     pop    di
  825.     add    di,CRT_COLS            ; next row
  826.     dec    ch
  827.      jnz    new_map6
  828.     pop    es
  829.     ret
  830. eject
  831.  
  832. point_vs@:
  833. ;---------
  834. ; Point to virtual console structure:
  835. ;  entry:    dl = device number
  836. ;  exit:    bx -> vs_
  837. ;        bp = preserved
  838.  
  839.  
  840. if SR
  841.     cmp    dl,NUM_VIR_CONS            ; master console ?
  842.     jb    point_vs1
  843.     push di ! push si ! push cx ! push ax
  844.     mov    al,dl
  845.     mov    di,offset sr_vs_table$
  846.     mov    cx,SR_VS_TLEN
  847.     call    con_scan@            ; get pointer to VS_TABLE
  848.     mov    bx,sr_table_vs$[si]        ; get VS_ pointer
  849.     pop ax ! pop cx ! pop si ! pop di
  850.     ret
  851.     
  852. point_vs1:
  853. endif
  854.     mov    al,dl
  855.     cbw
  856.     shl    ax,1                ; ax = 2 * vc number
  857.     xchg    ax,bx
  858.     mov    bx,table_vs$[bx]        ; fetch the pointer
  859.     ret
  860.  
  861.  
  862. point_cursor@:
  863. ;-------------
  864. ; Point to vc image from cursor row,column:
  865. ;  entry:    dx = (row,column)
  866. ;        bx -> vs_
  867. ;  exit:    ax = vs_width*row + column
  868. ;        di = 2*ax
  869. ;        dx = preserved
  870.  
  871.     mov    al,VS_WIDTH
  872.     mul    dh                ; ax = row * (40 or 80)
  873.     add    al,dl                ; add in the column
  874.     adc    ah,0                ;   and handle the carry
  875.     mov    di,ax
  876.     shl    di,1                ; di = 2*ax
  877.     ret
  878.  
  879.  
  880. xlat_priority@:
  881. ; Translate vc_map code to owner number:
  882. ;  entry:    al = vc_map code
  883. ;  exit:    al = owner number
  884.  
  885.     push    bx                ; save vs_
  886.     mov    bx,VS_XLAT
  887.     xlat    bx
  888.     pop    bx
  889.     ret
  890. eject
  891.  
  892. con_scan@:
  893. ;---------
  894. ; Scan character string for match:
  895. ;  entry:    di -> string
  896. ;        cx = count
  897. ;        al = charater
  898. ;  exit:    si = word table index, or just past the end
  899. ;             of the table if character is not found
  900. ;        al,cl = character
  901.  
  902.     push    es
  903.     push    ds ! pop es            ; local extra segment
  904.     mov    si,cx
  905.     repnz    scasb                ; look for match
  906.      jnz    con_scan1            ; if no match, skip
  907.     dec    si                ; correct count
  908. con_scan1:
  909.     sub    si,cx                ; si = char number
  910.     shl    si,1                ; word pointer
  911.     mov    cl,al                ; copy character
  912.     pop    es
  913.     ret
  914.  
  915.  
  916. restore_state@:
  917. ;--------------
  918. ; Restore the state vector to normal:
  919.     and    VS_MODE,not ESC_BIT        ; turn off ESC bit
  920.     mov    VS_VECTOR,offset con_normal@
  921.     ret                    ; that's all
  922.  
  923. leave_until_char@:
  924. ;----------------
  925.     or    VS_MODE,ESC_BIT            ; next char. into state machine
  926.     pop    VS_VECTOR            ; pop return addr into state vector
  927.     ret
  928. eject
  929.  
  930. ;==========
  931. io_switch@:
  932. ;==========
  933. ; XIOS virtual console switch routine:
  934. ;  entry:    dl = vc to switch to
  935.  
  936.  
  937.     call    check_no_switch@        ; in case of back doors
  938.      jmpnz    io_switch_exit            ; skip if no switch
  939.  
  940.     call    get_all_mxs@            ;; block all updates
  941.  
  942.     inc    kbd_imhere$            ; there's a problem 
  943.                         ; occassionally doing graphics switch
  944. if V386    
  945.     mov    bx,rlr$    
  946.     mov    al,P_CONS[bx]            ; get current vc number
  947.     mov    old_vc,al            ; and save for exit
  948.     mov    al,top_screen$            ; make sure top screen is 
  949.     cmp    al,active_vc$            ; mapped in
  950.      je    do_io_switch
  951.     mov    P_CONS[bx],al
  952.     push    dx
  953.     callf    disp_vector$            ; call XIOS dispatch code
  954.     pop    dx                ;  with DS:BX=PD address
  955.  
  956. do_io_switch:
  957. endif
  958.  
  959. ; Draw_frame_s@ reads and saves the regen buff if full-top.  If
  960. ;  the CRT mode is currently EGA graphics, the buffer is at A000, plus
  961. ;  it's 4 planes, etc.  So we save plane 3, which will be overwritten by
  962. ;  fonts, and call save_ega_screen, which quickly switches the EGA back to
  963. ;  color/alpha/80 so we can read it normally.
  964.  
  965.     cmp    cloneflag$,IS_M24
  966.     jne    not_oli
  967.     cmp    top_screen_mode$,40h    ; was old mode olivetti gr?
  968.     jae    not_ega_mode
  969. not_oli:
  970.     cmp    top_screen_mode$,0Dh    ; was the old mode new gr?
  971.      jb    not_ega_mode
  972.  
  973.     push    dx            ; save con number
  974.     call    save_plane2@        ; save the contents of bit plane 3
  975.     pop    dx
  976.     call    save_ega_screen        ; save some ega screen contents too
  977.     jmps    n_e_1            ; returns with bx-> old VS_
  978.  
  979. not_ega_mode:
  980.     call    draw_frame_s@        ; background old frame bx-> old VS
  981.         call    check_herc_card        ; reprog if hercules
  982. n_e_1:
  983.     ; BX -> old vs_
  984.     push    ds
  985.     mov    ax,PC_SEGMENT
  986.     mov    ds,ax
  987.     mov    ax,equip_flag_40    ; get PC equipment word
  988.     pop    ds
  989.     mov    VS_PC_EQUIP,ax        ; and save
  990.  
  991.     cmp    VS_SCREEN_MODE,04
  992.      jb    n_e_2
  993.     cmp    VS_SCREEN_MODE,07    ; was old mode graphics ?
  994.      jne    is_gr            ;  yes
  995.  
  996. n_e_2:
  997.     test    VS_MODE1,LINE_43_MODE    ; or 43 line mode
  998.      jz    not_gr            ; yes
  999. is_gr:
  1000.     push    dx
  1001.     mov    ah,03h            ; then get cursor position
  1002.     push    bx
  1003.     xor    bh,bh
  1004.     call    int10_entry@        ; from ROS and save in VS_
  1005.     pop    bx
  1006.     mov    VS_CURSOR,dx
  1007.     pop    dx            ; console number
  1008.     jmps    read_cur_done
  1009. not_gr:
  1010.     test    VS_MODE,UPDATE_BIT        ; has cursor been moved
  1011.      jnz    read_cur_done            ; hardware cursor not updated
  1012.     call    read_cursor            ;; get cursor from vs_
  1013.     sub    ax,VS_CORRECT            ;; adjust...
  1014.     mov    VS_OFFSET,ax            ;; and store
  1015. read_cur_done:
  1016.     mov    al,VS_MODE1            ;; save current ega bits
  1017.     push    ax
  1018.  
  1019.     call    point_vs@            ;; bx -> new virt structure
  1020.  
  1021.     cli
  1022.     call    new_priority            ;; set priority tables
  1023.  
  1024.     push    bx
  1025.  
  1026. if SR
  1027.     mov    dl,top_screen$        ; make sure PC_ updated
  1028.     call    point_pc@        ; get point to new PC_ structure in SI
  1029.     mov    al,top_screen$
  1030.     mov    PC_TOP_SCREEN,al    ; update screen structure
  1031. endif
  1032. if V386
  1033.     mov    bx,rlr$            ; PIN PD value
  1034.     mov    al,old_vc        ; get original VC#
  1035.     mov    P_CONS[bx],al        ; and restore
  1036.     lea    di,P_NAME[bx]        ; point to process name
  1037.     mov    si,offset PINstr
  1038.     mov    cx,3
  1039.     cld
  1040.     push    es
  1041.     push ds ! pop es
  1042.     repe    cmpsb            ; is it 'PIN'
  1043.     pop    es
  1044.      jne    not_switch        ; no ...
  1045.     mov    al,top_screen$
  1046.     mov    P_CONS[bx],al        ; change PINs' vc number
  1047.                     ; ready for next dispatch
  1048. not_switch:
  1049.     cmp    al,active_vc$
  1050.      je    no_disp            ; .. we're already active
  1051.     callf    disp_vector$        ; call XIOS dispatch code
  1052. no_disp:                ;  with DS:BX=PD address
  1053.                     ; to ensure active_vc= current VC
  1054. endif
  1055.     pop    bx
  1056.     sti
  1057.  
  1058.      call    new_vc_list            ;; make a new list
  1059.  
  1060. ; If new screen mode = an A000 mode, restore the regen now while it is
  1061. ;  still addressed at B800:
  1062.     cmp    VS_CRT_SEG,EGA_SEG    ; special mode?
  1063.      jne    not_ega_mode1
  1064.     call    restore_ega_screen    ; restore what was on EGA screen
  1065. not_ega_mode1:
  1066.  
  1067.     mov    ax,VS_PC_EQUIP            ; get old equipment word
  1068.     push    ds            
  1069.     mov    cx,PC_SEGMENT        
  1070.     mov    ds,cx
  1071.     mov    equip_flag_40,ax        ; update ROS data area
  1072.     pop    ds
  1073.  
  1074.     pop    ax                ;; old screen ega bits in AL
  1075. if V386
  1076.     mov    di,rlr$    
  1077.     mov    cl,top_screen$
  1078.     cmp    P_CONS[di],cl        
  1079.      jmpnz    no_cur
  1080. endif
  1081.  
  1082.     call    new_screen_mode            ;; if switching to color
  1083.  
  1084.     cmp    cloneflag$,IS_M24
  1085.     jne    not_oli2
  1086.     cmp    top_screen_mode$,40h        ;; was old mode olivetti gr?
  1087.     jae    not_ega_mode2
  1088. not_oli2:
  1089.     cmp    top_screen_mode$,0Dh        ;; did we just go into ega gr?
  1090.      jb    not_ega_mode2            ;; jmp if no
  1091.     push    dx                ;; save con number
  1092.     call    restore_plane2@            ;; else restore 3rd bit plane
  1093.     pop    dx                ;; restore con number
  1094.      jmps    y_ega
  1095.     
  1096. not_ega_mode2:
  1097.     call    draw_frame_d@            ;; frame the window
  1098.     call    clear_statline@            ;; erase bg 25th line
  1099.     call    update_window@            ;; update within mx
  1100. y_ega:
  1101.  
  1102.     call    switch_statline@        ;; on/off for pcmode
  1103.     call    release_match            ;; if full top, release it
  1104.  
  1105.     call    new_cursor_type            ;; new cursor type for each
  1106.     call    new_cursor_on@            ;; take the cursor
  1107.  
  1108.     test    video$,EGA+VGA            ;; ega mono or color
  1109.      jz    is_mono
  1110.     push    bx                ;; save VS->
  1111.     mov    bl,VS_MODE1            ;; get current ega blink toggle
  1112.     and    bl,BLINK_TOGGLE            ; mask bit
  1113.     mov    ah,10h                ; int 10h sub function
  1114.     mov     al,3                ; sub sub function - set toggle
  1115.     call    int10_entry@
  1116.     pop    bx                ;; restore VS->    
  1117. is_mono:
  1118.  
  1119.     test    VS_MODE1,LINE_43_MODE        ;; test if 43 line mode
  1120.      jz    not_43
  1121.     push    bx                ;; save VS->
  1122.     mov    ax,1112h            ; int 11h sub function
  1123.     mov    bl,0
  1124.     call    int10_entry@
  1125.     pop    bx
  1126. not_43:
  1127.  
  1128.     push    bx
  1129.     mov    dx,VS_CURSOR        ; get cursor position
  1130.     mov    ah,2            ; and reset
  1131.     xor    bh,bh
  1132.     call    int10_entry@
  1133.     pop    bx            ; restore VS->    
  1134.  
  1135. no_cur:
  1136.     or    VS_MODE,UPDATE_BIT    ; signal cursor has been moved
  1137.     call    free_all_mxs@        ; allow updates
  1138.  
  1139.     mov    bx,rlr$            ; PIN PD value
  1140.     lea    di,P_NAME[bx]        ; point to process name
  1141.     mov    si,offset PINstr
  1142.     mov    cx,3
  1143.     cld
  1144.     push    es
  1145.     push    ds ! pop es
  1146.     repe    cmpsb            ; is it 'PIN'
  1147.     pop    es
  1148.     jne    io_switch_done        ; no ...
  1149.  
  1150.     in    al,PORT_B        ; always silence the beeper
  1151.     and    al,BEEP_OFF
  1152.     jmps    $+2
  1153.     out    PORT_B,al
  1154.  
  1155. io_switch_done:
  1156.     dec    kbd_imhere$
  1157. io_switch_exit:
  1158.     ret
  1159.     
  1160. eject
  1161. ;
  1162. ; Entry:   bx-> VS_      
  1163. ;       dx=  new Vcon
  1164. ;
  1165. ; Check timing of retrace to determine which mode the hercules card 
  1166. ; is in.   If current mode <> new vcon mode, then we re-program
  1167. ; accordingly.
  1168. check_herc_card:
  1169.     cmp    VS_SCREEN_MODE,07    ; check old mode for VGA
  1170.     jne    no_check
  1171.     push    bx            ; save old VS_
  1172.     call    point_vs@        ; get VS_ -> for new console
  1173.     cmp    VS_CRT_SEG,MONO_SEG
  1174.     pop    bx
  1175.     jne    no_check
  1176.     cmp    retrace$,0EEEEh        ; check if hercules
  1177.     jne    check_herc_mode
  1178. no_check:
  1179.     ret
  1180.  
  1181. check_herc_mode:
  1182.     push    di
  1183.     push    bx
  1184.     push    dx            ; save Vcon
  1185.  
  1186.  
  1187. check_herc_again:
  1188.     mov    dx,MONO_PORT+6        ; status port
  1189. check_herc_active:
  1190.     sti                ; interrupt "window"
  1191.     nop
  1192.     cli                ; to here...
  1193.     in    al,dx
  1194.     rol    al,1            ; wait for active (bit 7 set)
  1195.     jnc    check_herc_active        
  1196.     in    al,dx
  1197.     rol    al,1            ; wait for retrace (bit 7 clr)
  1198.     jc    check_herc_active
  1199.     
  1200.             ;read timer at start of retrace
  1201.     mov    al,0
  1202.     out    TIMER_CMND_REG,al    ; latch timer 0
  1203.     in    al,TIMER_0_REG        ; lsb
  1204.     mov    ah,al            
  1205.     in    al,TIMER_0_REG        ; msb
  1206.     xchg    al,ah            ; swap to word value
  1207.     push    ax            ; save value 
  1208.  
  1209. herc_retrace_wait:
  1210.     in    al,dx
  1211.     rol    al,1            ; wait for active ( bit 7 set)
  1212.     jnc     herc_retrace_wait
  1213.  
  1214.             ;read timer at end of retrace
  1215.             
  1216.     mov    al,0
  1217.     out    TIMER_CMND_REG,al    ; latch timer 0
  1218.     in    al,TIMER_0_REG        ; lsb
  1219.     mov    ah,al            
  1220.     in    al,TIMER_0_REG        ; msb
  1221.     xchg    al,ah            ; swap to word value
  1222.     pop    cx            ; [cx] = old value...
  1223.     sub    cx,ax            ; [cx] = time difference
  1224.     sti
  1225.     jc    check_herc_again    ; oops.. looped try again
  1226.     or    ax,ax
  1227.     jz    check_herc_again    ; oops.. timed down to zero
  1228.     
  1229.  
  1230.             ; check vs. min text value
  1231.  
  1232.     mov    al,0            ; 0 = text mode
  1233.     cmp    cx,retrace$        
  1234.     
  1235.     jge    check_herc_set        ; if retrace >= init
  1236.     mov    al,1            ; 1 = graphics mode
  1237.     test    video$,COLOR        ; don't test B800 if color present
  1238.     jnz    check_herc_set
  1239.  
  1240.     mov    ax,COLOR_SEG        ; test if display page 1 selected
  1241.     mov    es,ax
  1242.     mov    ah,es:.0        ; do non destructive read\write test
  1243.     mov    al,ah
  1244.     not    al
  1245.     mov    es:.0,al
  1246.     jmps    $+2
  1247.     cmp    al,es:.0    
  1248.     mov    es:.0,ah        ; restore original value
  1249.     mov    al,1            ; use display page 0
  1250.     jne    check_herc_set
  1251.     mov    al,81h            ; else display page 1 (start B800)
  1252.  
  1253. check_herc_set:
  1254.     mov    VS_HERC_MODE,al        ; save current hercules mode
  1255.     pop    dx            ; get new Vcon
  1256.     push    dx
  1257.     push    ax            ; temp save mode
  1258.     call    point_vs@        ; bx-> new Vcon
  1259.     pop    ax            ; [ax] = old mode
  1260.     cmp    al,VS_HERC_MODE        ; same ??
  1261.     je    check_herc_rexit    ; yes, no more..
  1262.  
  1263. ; change mode graphics/text.
  1264.     mov    di,offset herc_text$    ; assume text param
  1265.     mov    al,0000$1000b        ; and mode 
  1266.     cmp    VS_HERC_MODE,0        ; is it text ?
  1267.     je    check_herc_load        ; yes..
  1268.     mov    di,offset herc_graph$    ; no.. use graphics
  1269.     mov    al,VS_HERC_MODE        ; get mode
  1270.     and    al,1000$0000b        ; mask page select bit
  1271.     or    al,0000$1010b        ; set graphics mode bit
  1272.  
  1273. check_herc_load:    
  1274.     push    ax            ; save mode
  1275.  
  1276.     cli
  1277.     mov    dx,MONO_PORT+4        
  1278.     and    al,1000$0010b        ; mask to text/graphics and page select
  1279.     out    dx,al            ; blank display..
  1280.  
  1281.     mov    ah,0            ; port index 0..11
  1282.     mov    cx,12            ; load/write loop
  1283. check_herc_load_loop:
  1284.     mov    dx,MONO_PORT
  1285.     mov    al,ah
  1286.     out    dx,al            ; set index
  1287.     mov    al,[di]            ; load byte 
  1288.     mov    dx,MONO_PORT+1            
  1289.     out     dx,al            ; send value
  1290.     inc    ah
  1291.     inc    di
  1292.     loop    check_herc_load_loop        
  1293.  
  1294.     mov    dx,MONO_PORT+4
  1295.     pop    ax            ; get mode 
  1296.     out    dx,al            ; and set display..
  1297.     sti
  1298.  
  1299. check_herc_rexit:
  1300.     pop    dx
  1301.     pop    bx
  1302.     pop    di
  1303. check_herc_exit:
  1304.     ret    
  1305.     
  1306. eject
  1307.  
  1308. new_cursor_type:
  1309. ;---------------
  1310. ; Set the cursor type as function of VS_CURTYPE in struct.
  1311. ; Entry: bx --> vs_
  1312.     mov    cx,VS_CUR_TYPE
  1313.     mov    ah,1                ; int 10 function #
  1314.     jmp    int10_entry@
  1315.  
  1316.  
  1317. read_cursor:
  1318. ;-----------
  1319. ; Read physical cursor position from CRTC:
  1320. ; Entry: bx -> vs_
  1321. ; Exit:  ax = CRTC cursor address
  1322.     push    dx
  1323.     mov    dx,MONO_PORT            ; assume mono
  1324.     cmp    VS_SCREEN_MODE,07
  1325.      jz    c_in
  1326.     mov    dx,COLOR_PORT            ; change to color
  1327. c_in:
  1328.     pushf                    ; save current int. state
  1329.     cli
  1330.     mov    ax,0F0Eh            ; CRTC reg #s
  1331.     out    dx,al                ; cursor high first
  1332.     inc    dx
  1333.     jmps    $+2                ; io delay
  1334.     in    al,dx
  1335.     dec    dx
  1336.     xchg    ah,al                ; save curs hi in ah
  1337.     out    dx,al                ; want curs lo
  1338.     inc    dx
  1339.     jmps    $+2
  1340.     in    al,dx
  1341.     popff    iret_op@
  1342.     pop    dx
  1343.     ret
  1344. eject
  1345.  
  1346. ; *** BACK DOOR WINDOW CONTROL ROUTINES: ***
  1347.  
  1348. ;===========
  1349. ww_pointer@:
  1350. ;===========
  1351. ; Return pointers to window relevant information:
  1352. ;  entry:    dl = vc number or 0FFH
  1353. ;  exit:    if dl = vc then
  1354. ;            ax = vc structure pointer
  1355. ;        if dl = 0FFH then
  1356. ;            ax = window data block pointer
  1357. ;         AX = 0ffffh console not supported
  1358.  
  1359.     mov    di,rlr$
  1360. if SR
  1361.     cmp    P_CONS[di],NUM_VIR_CONS        ; is it master console
  1362.     jb    main_vc
  1363.     push    dx
  1364.     mov    dl,P_CONS[di]            ; get VC number
  1365.     call    test_srterm@            ; is it SunRiver VC
  1366.     pop    dx
  1367.     jz    main_vc                ; no...
  1368.     cmp    dl,0ffh
  1369.     jne    ww_point1
  1370.     mov    ax,offset im_here$
  1371.     ret
  1372. main_vc:
  1373. endif
  1374.     cmp    P_CONS[di],NUM_VIR_CONS        ; make sure its master console
  1375.     mov    ax,0ffffh            ; else error return
  1376.     jae    ww_ret1
  1377.     cmp    dl,NUM_VIR_CONS            ; if dl = legal vc
  1378.      jb    ww_point1
  1379.     mov    ax,offset im_here$
  1380. ww_ret1:
  1381.     ret                    ; return window data block
  1382. ww_point1:
  1383.     call    point_vs@            ; if legal vc
  1384.     xchg    ax,bx                ;   return vs_pointer
  1385.     ret
  1386.  
  1387.  
  1388. ;===========
  1389. ww_im_here@:
  1390. ;===========
  1391. ; Set window manager process state:
  1392. ;  entry:    cl = im_here state
  1393. ;             0 => manager not resident
  1394. ;             1 => resident but not active
  1395. ;             2 => resident and active
  1396. ;             3 => leave im_here unchanged
  1397. ;        dl = vc number to switch to top
  1398. ;             if dl = 0FFH, then no switch
  1399.  
  1400. if SR
  1401.     mov    di,rlr$
  1402.     cmp    P_CONS[di],NUM_VIR_CONS        ; is it master console
  1403.     push    dx
  1404.     jb    main_vc1
  1405.     mov    dl,P_CONS[di]            ; get VC number
  1406.     call    test_srterm@            ; is it SunRiver VC
  1407.     jz    main_vc1            ; no...
  1408.     call    point_pc@            ; get PC_ pointer in SI    
  1409.     pop    dx
  1410.     jmp    sr_ww_im_here@
  1411. main_vc1:
  1412.     pop    dx
  1413. endif
  1414.     cmp    cl,3
  1415.      jae    ww_just_switch            ; if cl > 2, just switch
  1416.  
  1417.     mov    im_here$,cl            ; set state variable
  1418.     cmp    cl,2
  1419.      jz    ww_im_here_done            ; if staying resident, skip
  1420.     mov    key_flag$,CI_FLAG         ; switch back to normal
  1421. ww_just_switch:
  1422.            cmp    dl,NUM_VIR_CONS
  1423.      jae    ww_im_here_done            ; if illegal, skip
  1424.  
  1425.     mov    bl,dl                ; to index reg
  1426.     sub    bh,bh
  1427.     mov    bl,scan_switch[bx]
  1428.     mov    switch_key$,bl            ; put it in place for CONIN
  1429.  
  1430.     mov    dx,CI_FLAG            ; now activate conin
  1431.     call    flagset@
  1432.  
  1433.     pushf                    ; fake an interrupt
  1434.     callf    dword ptr dispatcher$
  1435. ww_im_here_done:
  1436.     ret
  1437.  
  1438. scan_switch    db    END_SCAN        ; pad 1 for 1st console
  1439.         db    PAD2_SCAN        ; for 2nd
  1440.         db    PGDN_SCAN        ; pad 3 for 3rd console
  1441.         db    PAD4_SCAN        ; for 4th
  1442. eject
  1443.  
  1444. ;==============
  1445. ww_new_window@:
  1446. ;==============
  1447. ; Create a new window:
  1448. ;  entry:    dl = virtual console number
  1449. ;        cx = top left (row,column)
  1450. ;        ax (bx at entry) = bottom right (row,column)
  1451.  
  1452.     push    ax                ; save bot_right
  1453.     call    point_vs@            ; bx -> virt structure
  1454.     call    get_all_mxs@            ;; lock out the world
  1455.     pop    ax
  1456.     cmp    cx,VS_TOP_LEFT            ;; if new top_left
  1457.      jnz    new_win1            ;;   then skip
  1458.     cmp    ax,VS_BOT_RIGHT            ;; or if new bottom_right
  1459.      jnz    new_win1            ;;   then skip
  1460.                         ;; if same window as before
  1461.     call    update_no_check            ;;   then just update it
  1462.     jmps    new_win3            ;; release and exit
  1463.  
  1464. new_win1:
  1465. if V386
  1466.     mov    win_sized$,01h            ;; signal windows sized (386)
  1467. endif
  1468.     push    ax
  1469.     call    copy_full_top@            ;; save to image if full
  1470.     mov    ax,VS_TOP_LEFT            ;; get current corner
  1471.     mov    VS_OLD_T_L,ax            ;;   and save for full switch
  1472.     mov    ax,VS_BOT_RIGHT            ;; do the same
  1473.     mov    VS_OLD_B_R,ax            ;;   for the other corner
  1474.  
  1475.     mov    VS_TOP_LEFT,cx
  1476.     pop    cx
  1477.     mov    VS_BOT_RIGHT,cx
  1478.  
  1479.  
  1480. new_pc_window@:                    ;; special pc mode entry
  1481. ;--------------
  1482.     mov    al,VS_NUMBER
  1483.     cmp    al,top_screen$            ;; now, if we're the top screen
  1484.      jnz    new_back_window            ;;   then take care of the
  1485.     call    switch_statline@        ;;   status line switch
  1486. new_back_window:
  1487.     call    new_count            ;; calc rows and cols
  1488.     call    do_true_view@            ;; correct view point
  1489.     call    new_vc_map            ;; redo the vc_map
  1490.  
  1491.     mov    dl,VS_MODE            ;; get sync bit
  1492.     mov    dh,mono_bits$            ;; assume monochrome
  1493.     cmp    VS_SCREEN_MODE,07
  1494.     mov    bx,VS_CRT_SEG            ;; vs_ ptr is hammered
  1495.      je    new_win2            ;; skip if mono
  1496.     mov    dh,color_bits$            ;; color if not
  1497. new_win2:
  1498.     call    erase_crt@            ;; clear appropriate screen
  1499.     call    update_all@            ;; and show the windows
  1500. new_win3:
  1501.     jmp    free_all_mxs@            ; release the works
  1502. eject
  1503.  
  1504. ;===============
  1505. ww_cursor_view@:
  1506. ;===============
  1507. ; Set cursor tracking mode and viewpoint:
  1508. ;  entry:    dl = vc number
  1509. ;        dh = cursor tracking mode
  1510. ;             0 => window is fixed on vc image
  1511. ;             1 => window tracks scrolling
  1512. ;        cx = row,column of top,left viewpoint
  1513.  
  1514.     call    point_vs@            ; bx -> structure
  1515.     call    get_mx@                ;; lock this vc
  1516.     mov    VS_CUR_TRACK,dh            ;; save tracking mode
  1517.     mov    VS_VIEW_POINT,cx
  1518.     call    do_true_view@            ;; correct view_point
  1519.     call    update_window@            ;; show the view
  1520.     call    show_cursor@            ;; and update the cursor
  1521.     mov    VS_MX,0                ; release this vc
  1522.     ret
  1523.  
  1524.  
  1525. ;===============
  1526. ww_wrap_column@:
  1527. ;===============
  1528. ; Set virtual console wrap around column:
  1529. ;  entry:    dl = vc number
  1530. ;        cl = wrap column number
  1531.  
  1532.     call    point_vs@
  1533.     mov    VS_WIDTH,cl            ; set warp column
  1534.     ret
  1535.  
  1536.  
  1537. ;==================
  1538. ww_switch_display@:
  1539. ;==================
  1540. ; Switch between monochrome and color monitors:
  1541. ;  entry:    dl = vc number
  1542. ;        cl = monitor code  (0 => mono; 1 => color)
  1543.  
  1544.     call    point_vs@            ; set up bx pointer
  1545.     cmp    cl,01                ; if color
  1546.      jz    ww_sw_disp1            ;   then skip
  1547.     cmp    cl,00                ; if mono
  1548.      jz    ww_sw_disp2            ;   then skip
  1549.     ret                    ; if illegal code, return
  1550. ww_sw_disp1:
  1551.     jmp    z_set_color@            ; jump to routine
  1552. ww_sw_disp2:
  1553.     jmp    z_set_mono@            ; jump to mono set
  1554. eject
  1555.  
  1556. ;===============
  1557. ww_full_window@:
  1558. ;===============
  1559. ; Switch between full screen and small window:
  1560. ;  entry:    dl = vc number
  1561.  
  1562.     call    point_vs@            ; point to structure
  1563.     mov    cx,0                ; top left
  1564.     mov    ah,VS_CRT_ROWS
  1565.     dec    ah
  1566.     mov    al,CRT_COLS-1            ; ax -> bottom right
  1567.     mov    di,ax                ; save the corner
  1568.     cmp    VS_TOP_LEFT,cx            ; if the current top console
  1569.      jnz    w_full1                ;   is not a full screen,
  1570.     cmp    VS_BOT_RIGHT,ax            ;   then make it one.
  1571.      jnz    w_full1
  1572.     mov    cx,VS_OLD_T_L            ; if it is a full screen
  1573.     mov    ax,VS_OLD_B_R            ;   then switch to previous.
  1574.     cmp    cx,0                ; if old window is not
  1575.      jnz    w_full2                ;   a full screen
  1576.     cmp    ax,di                ;   then go ahead.
  1577.      jnz    w_full2
  1578.     ret                    ; if both full, bag it
  1579. w_full1:
  1580.     jmp    ww_new_window@            ; create the window
  1581.  
  1582. w_full2:
  1583.     test    VS_MODE,PCMODE_BIT
  1584.      jz    w_full1                ; if we're leaving a pc full
  1585.     push    bx
  1586.     call    ww_new_window@            ; first create the window
  1587.     pop    bx
  1588.     mov    di,(CRT_ROWS_P-1) * CRT_COLS * 2
  1589.     mov    cx,CRT_COLS            ; clear across
  1590.     mov    ax,0720h            ; spaces
  1591.     jmp    put_crt_s@            ; clear the bottom line
  1592.  
  1593.  
  1594. save_ega_screen:
  1595. ;---------------
  1596. ; Save that portion of the EGA screen which will be overwritten when
  1597. ; we start putting text up on the screen.
  1598.     call    point_vs@        ; bx = new VS_
  1599.     push    es ! push dx
  1600.     mov    cx,PC_SEGMENT        
  1601.     mov    es,cx
  1602.     mov    cx,VS_PC_EQUIP        ; equipment flag for new screen
  1603.     push    es:equip_flag_40    ; save current
  1604.     mov    es:equip_flag_40,cx    ; update ROS data area
  1605.     and    cl,30h            ; is it mono
  1606.     cmp    cl,30h
  1607.     mov    ax,0083h        ; mode switch to alpha/80
  1608.      jne    save_ega1
  1609.     mov    ax,0087h        ; mode switch to alpha/80
  1610. save_ega1:
  1611.     call    int10_entry@
  1612.     pop    es:equip_flag_40    ; restore equip word
  1613.  
  1614. ; The regen buff is now addressed at B800/B000, so it can be read.
  1615.     mov    dl,top_screen$
  1616.     call    point_vs@        ; bx = old VS_
  1617.  
  1618.     cmp    cl,30h            ; test equipment byte if MONO
  1619.     mov    cx,COLOR_SEG        ; assume colour
  1620.      jne    save_ega2
  1621.     mov    cx,MONO_SEG        ; no, it's mono
  1622. save_ega2:
  1623.     push    ds
  1624.     xor    si,si
  1625.     xor    di,di
  1626.     mov    es,VS_VC_SEG        ; image is destination
  1627.     mov    ds,cx            ; screen is source
  1628.     mov    ah,IN_SYNC
  1629.     mov    cx,CRT_ROWS_P*CRT_COLS    ; max image size
  1630.     call    put_crt_m@
  1631.     call    old_cursor_off@        ; for 2 monitor switch
  1632.     pop    ds
  1633.  
  1634.     pop    dx ! pop es
  1635.     or    VS_MODE,MATCH_BIT    ; say VS_ copy matches screen
  1636.     ret
  1637.  
  1638. restore_ega_screen:
  1639. ;------------------
  1640. ; Restore those bits of the EGA screen we have previously saved
  1641. ; when we changed to text mode.
  1642.     push    ds
  1643.     mov    ax,PC_SEGMENT
  1644.     mov    ds,ax
  1645.     mov    ax,equip_flag_40
  1646.     and    al,30h
  1647.     cmp    al,30h            ; is current video mono ?
  1648.     pop    ds
  1649.  
  1650.     push    VS_CRT_SEG        ; save CRT_SEG (so we can fiddle it)
  1651.     mov    VS_CRT_SEG,COLOR_SEG    ; assume colour
  1652.      jne    restore_ega1
  1653.     mov    VS_CRT_SEG,MONO_SEG    ; no, it's mono
  1654. restore_ega1:
  1655.     call    update_window@        ; repaint the window
  1656.     pop    VS_CRT_SEG        ; restore real CRT_SEG
  1657.     ret
  1658.     
  1659.     dseg
  1660.  
  1661. if 0
  1662. ; Entry for each virtual screen:
  1663.  
  1664. kbd_vects$    dw    i_keyboard@,0        ; segment gets setup in init
  1665.         dw    i_keyboard@,0
  1666.         dw    i_keyboard@,0
  1667.         dw    i_keyboard@,0
  1668. endif
  1669.  
  1670. old_vc        rb    1
  1671.  
  1672. PINstr        db    'PIN'            ; pin rsp name
  1673.  
  1674. save_dx        dw    0
  1675. end
  1676.  
  1677. ; END OF WINDOWS2.A86
  1678.  
  1679.  
  1680.