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 / WINDOWS1.A86 < prev    next >
Encoding:
Text File  |  1989-01-26  |  53.9 KB  |  2,115 lines

  1. ; WINDOWS1.A86
  2. title 'CONOUT Entry, ESC Handlers'
  3. pagesize 60+11
  4. ;****************************************
  5. ;*                    *
  6. ;*    CONSOLE OUPUT ENTRY        *
  7. ;*    ESCAPE HANDLERS            *
  8. ;*    CDOS 6.0 XIOS            *
  9. ;*    DRI OS ENGR, JMB, GMS        *
  10. ;*                    *
  11. ;****************************************
  12. ; Mods:
  13. ; 6.x
  14. ; 12 JAN 89 -- Use VS_CRT_SEG for VC buffer if Background mode set    GMS
  15. ; 22 Nov 88 -- only reset palletes for ega/vga graphics modes        GMS
  16. ; 25 SEP 88 -- add background video support                GMS
  17. ;  9 SEP 88 -- Use global chan_sel value for MGE            GMS
  18. ; 18 AUG 88 -- Suspend background process if switching mode        GMS
  19. ;  5 JUL 88 -- Ros cursor/mode support                    IJ
  20. ; 11 APR 88 -- Added Sun River support                    GS
  21. ;  4 FEB 88 -- VS_CUR_TYPE_HW updated in trans_cur_type            GS
  22. ; 11 DEC 87 -- get_set_screen@ re-written                GS
  23. ;  7 DEC 87 -- int10_si etc. replaced with int10_entry            GS
  24. ;  4 DEC 87 -- VS_SCREEN_MODE now uses ROS video mode values        GS
  25. ;  4 DEC 87 -- use ROS int 10h to output chars in graphics mode        GS
  26. ;  2 DEC 87 -- replaced ega$ with redefined video$            GS
  27. ; 6.0
  28. ; 18 NOV 87 -- re-enable AST color card code                GS
  29. ; 13 NOV 87 -- get EGA pallette after each mode change            GS/JW
  30. ; 12 NOV 87 -- if VGA mono change ROS mode 3 to mode 7            GMS
  31. ;  7 NOV 87 -- support ESC ! backdoor via string output            JW
  32. ;        -- add int10_si@ entry for int 10's w/ BX = param        JW
  33. ;  3 NOV 87 -- reset pallette reg on mode changes            GMS
  34. ;  5 OCT 87 -- setup larger cursor if EGA monochrome            GMS
  35. ; 15 SEP 87 -- change to console numbers for conout_serial        GMS
  36. ; 21 AUG 87 -- set mode with top bit set for EGA's            GMS
  37. ; 21 AUG 87 -- change to 'screen_set' video mode code for ROS compatibilty GMS
  38. ; 5.2
  39. ; 17 JUL 87 -- converted XIOS to small model                JW
  40. ; 26 MAY 87 -- if two graphics processes then suspend new process.     GMS
  41. ; 13 APR 87 -- abort serial terminal process if making ROS call        GMS
  42. ;  7 APR 87 -- Olivetti modes 64 and 72 supported
  43. ; 11 MAR 87 -- Int 10h mode 7 Hercules - hit the hardware         GMS
  44. ;  2 MAR 87 -- colour pallettes restored for every screen switch on ega    GMS
  45. ;  2 MAR 87 -- Disable blinking attribute in VS_ when entering graphics GMS
  46. ;        and reset when entering alpha modes.
  47. ; 5.1
  48. ; 14 JAN 87 -- Set cursor moved bit in VS_ structure for switch routine GMS
  49. ;  9 JAN 87 -- call national translation for 7bit NX if block i/o    GMS
  50. ;  9 JAN 87 -- Bug fix for setting mode on EGA cards in mono        GMS
  51. ; 14 NOV 86 -- Change cursor off for Amstrad                GMS
  52. ; 16 OCT 86 -- Added support for Amstrad initial attribute        GMS
  53. ; 15 OCT 86 -- ANSI escape sequence handling added            GMS
  54. ;  9 OCT 86 -- Added call to NX_conout_xlat for national keyboards    GMS
  55. ; 17 JUL 86 -- remove graphics mode check for get_set_screen
  56. ;  3 JUN 86 -- support ros cursor-posn field for top screen app.
  57. ; 18 APR 86 -- support VS_CUR_TYPE_HW field
  58. ; 10 APR 86 -- set pallette reg. on io_switch only if they've changed. (EGA
  59. ;        interrupt window in functions B and 10h.)
  60. ;  8 APR 86 -- support for graphics char out in dev_conout
  61. ; 31 MAR 86 -- ESC seq./no-wrap bug
  62. ; 19 FEB 86 -- VS_WIDTH for graphics pgms.
  63. ; 12 FEB 86 -- fix dev_con_serial BP problem
  64. ;  7 FEB 86 -- fix dev_conout reentrancy bug
  65. ;  6 JAN 86 -- set pallette regs on screen switch
  66. ;  3 JAN 86 -- terminate 2nd process entering a graphics mode
  67. ; 19 DEC 85 -- set VS_CRT_SEG = A000 if ega gr. modes
  68. ; 17 DEC 85 -- save the 3rd bit plane if doing enhanced graphics
  69. ;  4 DEC 85 -- shuffle screen mode routines for EGA
  70. ; 14 NOV 85 -- fix cursor update on io_switch out of a graph. program
  71. ;  8 NOV 85 -- add AST "Colorgraphplus" support
  72. ; 12 SEP 85 -- do not update cursor...done only on tick
  73. ; 28 AUG 85 -- support Enhanced Graphics Adaptor using EGA ROS for mode set
  74. ; 19 JUL 85 -- add JW/WD virt. conout speedup
  75. ; 19 JUL 85 -- add io_devio support (block i/o) in dev_conout@
  76. ; 13 JUN 85 -- update 4.1 ASM86 code to RASM86
  77.  
  78. ; include COPYRITE.TXT
  79.  
  80. nolist
  81. include CDOS.EQU
  82. include XIOS.EQU
  83. include ASCII.EQU
  84. include PCHW.EQU
  85. include ROSDATA.EQU
  86. if SR
  87. include SR.EQU
  88. endif
  89. list
  90. ; These were included:
  91. ; include CDOS.EQU
  92. ; include XIOS.EQU
  93. ; include ASCII.EQU
  94. ; include PCHW.EQU
  95. ; include ROSDATA.EQU
  96. if SR
  97. ; include SR.EQU
  98. endif
  99.  
  100. CGROUP    group    CODE
  101. DGROUP    group    DATA,w1dseg0,w1dseg1
  102.  
  103. public    io_conout@,    con_normal@,    dev_conout@
  104. public    proc_abort@
  105. public    ser_abort@, gr_abort@
  106. public    set_screen@, erase_pc@,    screen_set_only@
  107. public    ega_pallette@
  108. public    show_cursor@,    put_cursor@,    in_window@
  109. public    new_cursor_on@, old_cursor_off@
  110. public    z_movsw@,    z_up@,        z_erase_eos@
  111. public    z_erase_bos@,    z_erase@,    z_erase_eol@
  112. public    z_erase_bol@,    z_erase_line@,     z_insert_line@
  113. public     z_delete_line@,    z_intense_on@,    z_fore1@
  114. public    z_blink_on@,    z_rev_on@
  115. public    z_save_cursor@,    z_restore_cursor@
  116. public    z_set_color@,    z_set_mono@,    z_set_mode@
  117. public    vc_out@,    vc_out_bs@,    vc_out_cr@
  118. public    vc_out_lf@,    vc_out_bel@
  119. public    set_mono@,    set_color@
  120. public    local_ptr$,    ast_flag$
  121. public    ast_enhanced$,    ros_color@
  122. public    colsel_640$
  123. public    mode_vector$,    oli_vector$             ; for INIT
  124. public    bw_640_400@,   bw_640_400_t@
  125. public    alpha_str_80$,    compaq_str$,    mono_table$
  126. public    save_plane2@,    restore_plane2@
  127.  
  128. eject
  129.  
  130.     cseg
  131. extrn    entry@           :near, supif@          :near    ; in HEADER.A86
  132. extrn    flagwait@      :near
  133. extrn    sysdat$           :word
  134. extrn    z_prog_pfk@    :near                ; in CONIN.A86
  135. extrn    z_pfk_on@      :near, z_pfk_off@      :near
  136. extrn    z_sl_off@      :near, z_sl_mono@      :near    ; in STATLINE.A86
  137. extrn    z_sl_color@    :near, z_sl_both@      :near
  138. extrn    z_clk_on@      :near, z_clk_off@      :near
  139. extrn    z_sl_blank@    :near, sl_error_out@   :near
  140. extrn    conout_serial@ :near, io_devio@       :near    ; in LISTAUX.A86
  141. extrn    point_vs@      :near, get_mx@          :near    ; in WINDOWS2.A86
  142. extrn    con_scan@      :near, restore_state@  :near
  143. extrn    point_cursor@  :near, check_full@     :near
  144. extrn    update_window@ :near, update_all@     :near
  145. extrn    set_new_mon@   :near, leave_until_char@:near
  146. extrn    put_if_ours@   :near                ; in WINDOWS3.A86
  147. extrn    put_crt_s@     :near, put_crt_m@      :near
  148. extrn    put_crt_c@     :near, copy_full_top@  :near
  149. extrn    put_crt_dev@   :near, trans_cur_type@ :near
  150. extrn    int10_entry@   :near                ; in ROSIF.A86
  151. extrn    poke_ros_cursor@:near                ; in PCVIDEO.A86
  152. extrn    update_vs_cursor_from_ros@: near        ; in PCVIDEO.A86
  153. extrn    NX_conout_xlat@:near                ; in KEYBOARD.A86
  154. extrn    z_ansi@           :near                ; in ANSI.A86
  155.  
  156. if SR
  157. extrn    test_srterm@   :near, point_pc@:near        ; in SRTERM.A86
  158. endif
  159.  
  160.     dseg
  161. if SR
  162. extrn    beep_ticks$    :byte
  163. extrn    con_basead$    :word, station_on_off$    :byte    ; in SRTERM.A86
  164. extrn    chan_sel$    :byte
  165. endif
  166. extrn    func_tbl$    :word                ; in HEADER.A86
  167. extrn    beep_counter$  :byte, last_curs$      :word    ; in ISRS.A86
  168. extrn    sl_crt_flag$   :byte                ; in STATLINE.A86
  169. extrn    ccb_tab$       :byte, iattrib$          :byte
  170. extrn    cloneflag$     :byte
  171. ;extrn    palette_reg$   :byte                ; in WINDOWS3.A86
  172. extrn    mode_reg$      :byte
  173. extrn    vc_map_seg$    :word, top_screen$     :byte
  174. extrn    graphic_bits$  :byte, mono_bits$      :byte
  175. extrn    color_bits$    :byte, top_screen_mode$:byte
  176. extrn    color_xlat$    :byte, mono_xlat$      :byte
  177. extrn    var_cursor$    :word, var_sync$          :byte
  178. extrn    table_vs$      :word
  179. extrn    fatal_gr_msg$  :byte
  180. extrn    FATAL_GR_MSG_LENGTH:abs
  181. extrn    fatal_ser_msg$  :byte
  182. extrn    FATAL_SER_MSG_LENGTH:abs
  183. ;if BACKG
  184. extrn    mono_params$    :byte, MONO_PARAMS_LEN$:abs
  185. ;endif
  186. extrn    bit_plane_seg$ :word, video$          :byte    ; in PUBDATA.A86
  187. extrn    NX_natnlmode$ :byte                ; in NATDATA.A86
  188.  
  189. eject
  190.  
  191.     cseg
  192.  
  193. ;==========
  194. io_conout@:
  195. ;==========
  196. ; XIOS console character out routine:
  197. ;  entry:    cl = character
  198. ;        dl = device number
  199.  
  200.     cmp    dl,NUM_VIR_CONS
  201.      jae    io_conout_ser            ; skip if not one of the vc's
  202.  
  203. conout_vc:
  204. ;---------
  205. ; Console output to a virtual console:
  206.  
  207. ;    call    point_vs@            ; bx -> virt structure
  208. ;    call    get_mx@                ;; lock out other entries
  209.  
  210.     mov    bl,dl                ; save time...do above inline
  211.     xor    bh,bh
  212.     shl    bx,1
  213.     mov    bx,table_vs$[bx]
  214. conout_vc1:                ; dev_conout entry point
  215.     mov    al,0ffh
  216.     xchg    al,VS_MX
  217.     test    al,al                ; save jumps
  218.      jnz    do_get_mx            ; wait if necessary
  219.  
  220. get_mx_ok:                    ;; and return here
  221.     mov    al,cl                ;; copy character to al
  222.     cmp    VS_SCREEN_MODE,04        ; if graphics mode, get out...
  223.      jb    get_mx_ok1
  224.     cmp    VS_SCREEN_MODE,07
  225.      jne    gr_conout
  226. get_mx_ok1:
  227.     call    update_vs_cursor_from_ros@    ; make sure VS_CURSOR in step
  228.     mov    dx,VS_CURSOR            ;; cursor row, column
  229.     push    bx                ;; in case of back door stuff
  230.     call    VS_VECTOR            ;; state machine branch
  231.                         ;;   to con_norm or con_esc's
  232.     pop    bx
  233.     mov    ax,VS_CURSOR            ;; cursor row, column
  234.     call    poke_ros_cursor@
  235.     mov    VS_MX,0                ; release for other entries
  236.     ret
  237.  
  238. do_get_mx:
  239.     call    get_mx@                ; jump here if MX owned
  240.     jmps    get_mx_ok            ;;
  241.  
  242. io_conout_ser:
  243.  
  244. if SR
  245.  
  246. ; BEWARE !!!!!
  247. ; PCTerm sends in the AUX number in DL (+NUM_VIR_CONS-1), so we will screw
  248. ; up if this coincides with a Sunriver station. We need a better solution
  249. ; when we combine SR + PCTerm!
  250.  
  251.     call    test_srterm@            ; test if SUN RIVER main console
  252.     jz    io_conout_ser1            ; no .. must be dumb terminal
  253.     call    point_vs@            ; else get VS_ pointer
  254.     jmps    conout_vc1            ; 
  255. io_conout_ser1:
  256. endif
  257.  
  258.     sub    dl,NUM_VIR_CONS-1        ; physical console number 1 relative
  259.     cmp    dl,NUM_AUX_PORTS        ; if this is too big
  260.      ja    conout_no_go            ;   then skip
  261.     jmp    conout_serial@            ; handle aux_ports in listaux.a86
  262.  
  263. conout_no_go:
  264.     ret
  265.  
  266. gr_conout:
  267. ; Use int 10h to write characters in graphics mode.
  268. ; entry:  char in AL
  269.     mov    ah,0eh            ; TTY write char
  270.     push    bx            ; save VS_
  271.     mov    bl,07h            ; attribute
  272.     call    int10_entry@        ; output char via ROS
  273.     pop    bx
  274.     mov    VS_MX,0            ; release for other entries
  275.     ret
  276. eject
  277.  
  278. con_control:
  279. ;-----------
  280. ; Handle kontrol codes:
  281.  
  282.     mov    di,offset norm_scan
  283.     mov    cx,NORM_COUNT
  284.     call    con_scan@            ; scan for special chars
  285.     jmp    norm_table[si]
  286.  
  287. con_normal@:
  288. ;----------
  289. ; Normal console vector state:
  290. ;  entry:    cl,al = character
  291. ;        bx = VS_ base
  292. ;        dx = cursor
  293.  
  294.     cmp    al,' '                ; non-character?
  295.      jb    con_control            ; try to avoid jumps 
  296.  
  297. vc_out@:
  298. ;------
  299. ; Printable character to virtual console ram image:
  300. ;  entry:    bx -> VS_
  301. ;        cl = character
  302. ;        dx = cursor
  303.  
  304.     mov    al,cl
  305.     call    NX_conout_xlat@        ; xlat char for national 7 bit display
  306.     mov    cl,al
  307.     push    es
  308.     mov    di,VS_OFFSET            ; point to screen buffer
  309.     shl    di,1
  310.     mov    ch,VS_ATTRIB
  311.     test    VS_MODE,MATCH_BIT
  312.      jz    vc_out0                ; skip if full on top
  313.  
  314.     mov    es,VS_VC_SEG            ; go to the vc image
  315.     mov    es:[di],cx            ; store char, attrib
  316.  
  317. ; Now update screen if character belongs:
  318.  
  319.     mov    es,vc_map_seg$            ; for ownership check
  320.     mov    ax,VS_OFFSET
  321.     add    ax,VS_CORRECT
  322.     xchg    ax,si                ; save for map check
  323.     call    in_window@            ; is char in window?
  324.      jc    vc_out1                ; skip if not
  325.  
  326.     mov    di,si
  327.     shl    di,1                ; back to screen coords
  328.     mov    ax,cx                ; ax = character + attrib
  329.     call    put_if_ours@            ; print it if we own it
  330.     jmps    vc_out1
  331. vc_out0:
  332.     mov    ax,cx                ; char to ax
  333.     call    put_crt_c@            ; go right to physical
  334. vc_out1:
  335.     pop    es
  336.     inc    dl                ; advance cursor
  337.     cmp    dl,VS_WIDTH            ; if not wrapping around
  338.      jae    vc_out2                ;   then do cursor
  339.     mov    VS_CUR_COL,dl            ; update the cursor address
  340.     mov    ax,dx
  341.     call    poke_ros_cursor@        ; if top screen
  342.     inc    VS_OFFSET            ; row/col plus index
  343.     or    VS_MODE,UPDATE_BIT        ; signal cursor has been moved
  344.     ret
  345. vc_out2:
  346.     test    VS_MODE,WRAP_BIT
  347.      jz    vc_out3                ; exit if not wrapping
  348.  
  349.     call    vc_out_cr@            ; send CR, LF and update
  350.     jmps    vc_out_lf@            ; cursor
  351. vc_out3:
  352.     ret                    ; don't touch cursor
  353.  
  354.  
  355. in_window@:
  356. ;----------
  357. ; Is the current row,col in the window?
  358. ;  entry:    dx = row,col
  359. ;        bx -> VS_
  360. ;  exit:    cf set if outside of window (or on frame)
  361.  
  362.     mov    ax,VS_TRUE_VIEW            ; updated viewpoint
  363.     cmp    dl,al
  364.      jb    in_window2            ; skip if left
  365.     cmp    dh,ah
  366.      jb    in_window2            ; skip if high
  367.     add    al,VS_COLSB
  368.     add    ah,VS_ROWSB            ; past bottom right
  369.     cmp    dl,al
  370.      jae    in_window1            ; skip if right
  371.     cmp    dh,ah                ; clc if low
  372. in_window1:
  373.     cmc
  374. in_window2:
  375.     ret
  376. eject
  377.  
  378. put_cursor@:
  379. ;-----------
  380. ; Update and display cursor if appropriate:
  381.  
  382.     call    point_cursor@
  383.     mov    VS_OFFSET,ax
  384. put_cursor2:
  385.     mov    VS_CURSOR,dx
  386.     or    VS_MODE,UPDATE_BIT        ; signal cursor has been moved
  387. ;    jmps    show_cursor2            ; cursor only updated on tick
  388. ;    ret
  389.     mov    ax,dx
  390.     jmp    poke_ros_cursor@        ; and ret
  391.  
  392. show_cursor@:
  393. ;------------
  394. ; Display the cursor at its current position:
  395.  
  396.     mov    dx,VS_CURSOR            ; grab the current pos
  397. ;    jmps    show_cursor2            ; and fall through
  398. ;    ret                    ; only done on tick
  399.  
  400. show_cursor2:
  401.     mov    al,VS_NUMBER            ; get our vc number
  402.     cmp    al,top_screen$            ; if not top, then skip
  403.      jnz    show_cur_ret
  404.     test    VS_MODE,CURSOR_BIT        ; cursor on?
  405.      jz    show_cur_ret            ; skip if no
  406.     call    in_window@            ; if cursor outside, then
  407.      jnc    show_cur_out            ; just turn it off
  408.     jmp    old_cursor_off@
  409. show_cur_out:
  410. ; To save time, the below is done on the tick
  411. ;    mov    cx,VS_OFFSET            ; CX = byte pointer
  412. ;    add    cx,VS_CORRECT            ; CX = cursor pointer
  413. ;    mov    al,CURSOR_HI            ; set cursor code
  414. ;    call    video_out@            ; set CRT registers
  415.  
  416. ;    mov    cx,VS_CUR_TYPE            ; if inside window, turn it on
  417. ;    mov    ah,1                ; int 10 function #
  418. ;    jmp    int10_bx@
  419. show_cur_ret:
  420.     ret
  421. eject
  422.  
  423. vc_out_cr@:
  424. ;----------
  425. ; VC carriage return out:
  426.  
  427.     sub    dl,dl                ; first column
  428.     jmps    put_cursor@            ; update and display
  429.  
  430. vc_out_lf@:
  431. ;----------
  432. ; VC line feed out:
  433.  
  434.     mov    al,VS_CRT_ROWS            ; get our screen size
  435.     dec    al                ; al = number of last line
  436.     cmp    dh,al                ; if at the bottom
  437.      jz    vc_lf_scroll            ;   do a scroll
  438.     inc    dh                ; if not, move down
  439.     mov    VS_CURSOR,dx            ; save the cursor value
  440.     mov    ax,dx
  441.     call    poke_ros_cursor@        ; in ros area too
  442.     add    VS_OFFSET,CRT_COLS
  443.     or    VS_MODE,UPDATE_BIT        ; signal cursor has been moved
  444.     call    check_full@            ; if the window is full
  445.      jz    vc_lf_show            ;   then just show cursor
  446.     call    update_window@            ; if not full, do an update
  447. vc_lf_show:
  448.     jmps    show_cursor@            ; display current cursor
  449.  
  450. vc_lf_scroll:
  451.     sub    ax,ax                ; zero offset from
  452.     mov    di,ax                ;   the top left
  453.     mov    si,CRT_COLS*2            ; one row down
  454.     jmp    z_line                ; delete one line to scroll
  455.  
  456. vc_out_bs@:
  457. ;----------
  458. ; VC back space:
  459.  
  460.     dec    dl                ; back one column
  461.      jns    put_cursor@            ; if not at left
  462.     test    VS_MODE,WRAP_BIT
  463.      jz    vc_bs1                ; if no wrap, done
  464.     mov    dl,VS_WIDTH            ; if at left, wrap
  465.     sub    dx,0101h            ; up one, left one
  466.      jns    put_cursor@            ; if not at top
  467. vc_bs1:
  468.     ret                    ; if top left, bag it
  469.  
  470. vc_out_bel@:
  471. ;-----------
  472. ; VC beep the bell for top screen only:
  473.     push    bx
  474.     mov    al,VS_NUMBER            ; get our vc number
  475.     cmp    al,top_screen$
  476.      jnz    vc_bel_done            ; skip if not top
  477.     inc    beep_counter$            ; otherwise, add a beep
  478. if SR
  479. out_bel:
  480.     mov    bl,beep_ticks$            ; put in reg.
  481.     cmp    bl,00                ; is this the first time through
  482.      jnz    check_beep_tick            ; no the leap around set up
  483. set_beep_tick:
  484.     mov    bl,0Ch                ; set up for a beep
  485.     mov    al,BEEP_CMND            ; set up the beep frequency
  486.     out    TIMER_CMND_REG,al        ; send the command
  487.     mov    ax,TIMER_1000_HZ        ; get the constant
  488.     out    TIMER_2_REG,al
  489.     xchg    ah,al
  490.     out    TIMER_2_REG,al
  491. check_beep_tick:
  492.     dec    bl                ; are we all done with this beep
  493.      jz    check_more_beeps        ; yes then leap
  494.     cmp    bl,2                ; where are we in the beep cycle
  495.      jb    turn_beep_off            ; low enough to turn off
  496.     in    al,PORT_B            ; else turn on the beeper
  497.     or    al,BEEP_ON
  498.     out    PORT_B,al
  499.     jmps    do_beeps_done
  500.  
  501. ; Beep handler continued:
  502. check_more_beeps:
  503.     dec    beep_counter$            ; count down the beep
  504.      jnz    set_beep_tick            ; not the last set a new one
  505. turn_beep_off:
  506.     in    al,PORT_B            ; else get the bits
  507.     and    al,BEEP_OFF
  508.     out    PORT_B,al            ; silence the beeper
  509.     mov    beep_ticks$,bl            ; replace
  510.     jmps    vc_bel_done
  511.     
  512. do_beeps_done:
  513.     mov    beep_ticks$,bl            ; replace
  514.     mov    dx,1                ; delay a tick 
  515.     mov    cl,P_DELAY
  516.     call    supif@
  517.     jmps    out_bel
  518. endif
  519.  
  520. vc_bel_done:
  521.     pop    bx
  522.     ret
  523.  
  524.  
  525. eject
  526. vc_out_esc:
  527. ;----------
  528.     call    leave_until_char@        ; comes back here:
  529.  
  530. ; Console escape sequence branch point:
  531. ;  entry:    cl,al = character
  532. ;        bx = VS_base
  533. ;        dx = cursor
  534.  
  535.     call    restore_state@        ; VS_VECTOR back to normal
  536.     mov    di,offset esc_scan$
  537.     mov    cx,ESC_COUNT
  538.     call    con_scan@        ; scan for escape chars
  539.     jmp    esc_table$[si]
  540.  
  541.  
  542. w1dseg0    dseg    word
  543. ; ESC sequences and special character support:
  544.  
  545. norm_table    dw    vc_out_cr@, vc_out_lf@, vc_out_bs@
  546.         dw    vc_out_bel@, vc_out_esc, vc_out@
  547.  
  548. esc_table$    dw    z_up@,         z_down,       z_forward
  549.         dw    z_back,         z_erase@,      z_home
  550.         dw    z_rev_index,     z_erase_eos@,  z_erase_eol@
  551.         dw    z_erase_bos@,     z_erase_line@, z_erase_bol@
  552.         dw    z_insert_line@,     z_delete_line@,z_delete_char
  553.         dw    z_set_cursor,     z_set_fore,   z_set_back
  554.         dw    z_cursor_on,     z_cursor_off, z_save_cursor@
  555.         dw    z_restore_cursor@,z_rev_on@,     z_rev_off
  556.         dw    z_intense_on@,     z_blink_on@,   z_blink_off
  557.         dw    z_intense_off,     z_wrap_on,    z_wrap_off
  558.         dw    z_set_color@,     z_set_mono@,   z_video_mode
  559.         dw    z_prog_pfk@,     z_sl_off@,    z_sl_mono@
  560.         dw    z_sl_color@,     z_sl_both@,   z_clk_off@
  561.         dw    z_clk_on@,     z_pfk_off@,   z_pfk_on@
  562.         dw    z_back_door,     z_norm_attr,     z_ansi@
  563.         dw    vc_out@
  564.  
  565. norm_scan    db    CR,LF,BS,BEL,ESC
  566. NORM_COUNT    equ    offset $ - offset norm_scan
  567.  
  568. esc_scan$    db    'ABCDEH'
  569.         db    'IJKdlo'
  570.         db    'LMNYbc'
  571.         db    'efjkpq'
  572.         db    'rstuvw'
  573.         db    'xya:01'
  574.         db    '234567'
  575.         db    '!z['
  576. ESC_COUNT    equ    offset $ - offset esc_scan$
  577. eject
  578.  
  579.     cseg    
  580. dev_conout@:
  581. ;-----------
  582. ; Block console output (subfunction of XIOS function 39).
  583. ; Entry:    6[bp] = Param. block
  584. ;        CX = character count
  585. ;        DL = device (console) number
  586.  
  587.     cmp    dl,NUM_VIR_CONS            ; check for serial console
  588.      jae    to_dev_con_serial
  589. dev_conout_vc:
  590.     call    point_vs@            ; point bx at vs_ structure
  591.     cmp    VS_SCREEN_MODE,04        ; if graphics mode, get out...
  592.      jb    not_gr
  593.     cmp    VS_SCREEN_MODE,07
  594.      je    not_gr
  595.     jmp    dev_gr                ; do the graphics out
  596. not_gr:
  597.     call    get_mx@                ; get the semaphore
  598. ; BP OK through above.
  599.     jcxz    to_dev_con_done            ; if no characters, leave
  600. wr_nowr:
  601.     mov    dl,VS_WIDTH            ; screen width
  602.     mov    al,VS_CRT_ROWS            ; and height
  603.     test    VS_MODE,WRAP_BIT        ; is this screen wrapping?
  604.      jnz    set_max_char            ; jump if yes
  605.     mov    al,VS_CUR_ROW            ; else max char is right marg.
  606.     inc    ax                ; for count
  607. set_max_char:
  608.     mul    dl                ; AX = max_cols * max_rows
  609.     mov    VS_SCRATCH,ax            ; save it
  610.  
  611. dev_con_loop:
  612.     les    si,DEV_BUF_BP            ; get buffer address
  613.     lods    es:al                ; get character
  614.     cmp    NX_natnlmode$, 3        ; 7 bit, nat scn, nat kbd?
  615.     je    dev_con_slow            ; slow method for translation
  616.  
  617.     test    VS_MODE,ESC_BIT or MATCH_BIT
  618.      jnz    dev_con_slow            ; window or esc seq --> slow
  619.     cmp    al,' '
  620.      jae    dev_con_fast            ; fast write for non-control
  621.  
  622. dev_con_slow:
  623.     mov    DEV_OFF_BP,si            ; update the pointer
  624.     mov    cl,al                ; put the character in place
  625.     mov    dx,VS_CURSOR            ; load row and column
  626.     push    bp                ; save frame ptr
  627.     call    VS_VECTOR            ; branch through state machine
  628.     pop    bp                ; restore frame ptr
  629.     dec    DEV_CNT_BP            ; count one character
  630.      jz    to_dev_con_done            ; don't repeat if no more
  631.     test    VS_MODE,WRAP_BIT        ; if no wrap, recalc limit
  632.      jz    wr_nowr
  633.     jmps    dev_con_loop            ; else just loop
  634. to_dev_con_done:
  635.     jmp    dev_con_done            ; else string done
  636. to_dev_con_serial:
  637. if SR
  638.     call    test_srterm@            ; test if SUN RIVER main console
  639.     jz    do_dev_serial            ; DI = CCB ptr
  640.     cli                    ; protect ourselves
  641.     cmp    C_STATE[di],CSM_BACKGROUND     ; background ? o.k.
  642.     je    go_dev_conout
  643.     mov    es,con_basead$            ; base address of control regs
  644.     mov    bl,chan_sel$            ; get selected channel
  645.     xor    bh,bh
  646.     test    byte ptr station_on_off$[bx],ON  ; is station ON
  647.     jnz    go_dev_conout            ; yes...
  648.     push    bp
  649.     push     cx
  650.     push    dx
  651.     mov    cl,DEV_FLAGALLOC
  652.     call    supif@                ; get flag number
  653.     pop    dx                ; restore VS number
  654.     push    ax                ; save flag number
  655.     call    point_pc@    
  656.     pop    ax
  657.     mov    PC_TEMP_FLAG,al            ; store flag
  658.     sti
  659.     push    dx
  660.     push    ax
  661.     mov    dl,al                ; flag number
  662.     call    flagwait@            ; wait for PIN to wake us up
  663.     pop    dx                ; get flag
  664.     mov    cl,DEV_FLAGFREE
  665.     call    supif@
  666.     pop    dx                ; restore input params
  667.     call    point_pc@    
  668.     mov    PC_TEMP_FLAG,00h        ; clear flag
  669.     pop    cx
  670.     pop    bp
  671.     jmp    dev_conout_vc
  672.     
  673. go_dev_conout:
  674.     jmp    dev_conout_vc
  675. do_dev_serial:
  676. endif
  677.     jmp    dev_con_serial            ; to avoid jmps
  678.  
  679. dev_con_fast:
  680.     dec    si                ; point to 1st non-control byte
  681.     mov    di,si                ; scan for non-controls
  682.     mov    cx,DEV_CNT_BP            ; count them all
  683.     mov    al,' '                ; compare against this
  684. dev_con_count:
  685.     scasb                    ; compare al w/ ES:[DI++]
  686.      ja    dev_con_move            ; break out if control code
  687.     loop    dev_con_count            ; else keep checking
  688.     inc    di                ; pretend trailing control code
  689. dev_con_move:
  690.     dec    di                ; backup for overscan
  691.     mov    cx,di                ; point to control char
  692.     sub    cx,si                ; CX = # of non-control chars
  693. dev_con_fast_loop:
  694.     mov    ax,VS_SCRATCH            ; max to write
  695.     mov    di,VS_OFFSET
  696.     sub    ax,di                ; AX = max chars from cur. pos
  697.     shl    di,1                ; DI = word position
  698.     mov    dx,cx
  699.     sub    dx,ax                ; DX <= 0 if block fits
  700.      jbe    dev_con_call
  701.     mov    cx,ax                ; too big..CX = max # chars
  702. dev_con_call:
  703.     mov    ah,VS_ATTRIB            ; pick up attribute
  704.     push bp ! push cx ! push dx
  705.     call    put_crt_dev@            ; write block to screen
  706.     pop dx ! pop cx ! pop bp
  707.     mov    ax,VS_OFFSET
  708.     add    ax,cx                ; update cursor offset
  709.     test    VS_MODE,WRAP_BIT        ; check for wrap mode
  710.      jnz    dev_check_bottom        ; jump if wrapping enabled
  711.     or    dx,dx                ; did the whole block fit?
  712.      js    dev_con_next            ; y: go save updated cursor off.
  713.      je    dev_no_wrap            ; just barely...back cursor up
  714.     add    cx,dx                ; n: pretend we sent the rest of
  715.     dec    cx                ;    the block EXCEPT the last
  716.     mov    dx,1                ; 1 more to output
  717. dev_no_wrap:
  718.     dec    ax                ; back up cursor to EOL
  719.     jmps    dev_con_next
  720.  
  721. dev_check_bottom:
  722.     cmp    ax,VS_SCRATCH            ; need to scroll the screen?
  723.      jne    dev_con_next            ; jmp if no
  724.     sub    al,VS_WIDTH            ; cursor back to bot. lft.
  725.     sbb    ah,0
  726.     push ax ! push cx ! push dx
  727. ;    push    bp ??
  728.     call    vc_lf_scroll            ; do scroll
  729. ;    pop    bp ??
  730.     pop dx ! pop cx ! pop ax
  731.  
  732. dev_con_next:
  733.     mov    VS_OFFSET,ax            ; update
  734.     div    VS_WIDTH            ; AL=AL/VS_WIDTH, AH=AL%VS_WIDTH
  735.     xchg    al,ah                ; AL = col, AH = row
  736.     mov    VS_CURSOR,ax            ; save new row, col
  737.     or    VS_MODE,UPDATE_BIT        ; signal cursor has been moved
  738.     add    DEV_OFF_BP,cx            ; move the string pointer
  739.     sub    DEV_CNT_BP,cx            ; decrement the count
  740.      jz    dev_con_done            ; split if we're done
  741.     mov    cx,dx
  742.     or    cx,cx                ; if CX>0, CX == count left
  743.      jg    dev_con_fast_loop        ; (we had to scroll or nowrap)
  744.     jmp    dev_con_loop            ; otherwise, go 'round again
  745.  
  746. dev_con_done:
  747.     mov    VS_MX,0                ; release the MX
  748.     mov    ax,VS_CURSOR
  749.     call    poke_ros_cursor@        ; will do it if top screen
  750.     jmp    show_cursor@            ; this will return for us
  751.  
  752.  
  753. dev_con_serial:
  754.     sub    dl,NUM_VIR_CONS-1        ; physical console number 1 relative
  755.     cmp    dl,NUM_AUX_PORTS        ; do we have enough ports
  756.      ja    dev_cser_done            ; leave if we don't
  757.  
  758. dev_cser_loop:
  759.     push    bp                ; save frame ptr
  760.     push    dx
  761.     les    si,DEV_BUF_BP            ; point to string
  762.     lods    es:al                ; get char.
  763.     mov    DEV_OFF_BP,si            ; bump
  764.     mov    cl,al                ; put in place
  765.     call    conout_serial@            ; send it
  766.     pop    dx
  767.     pop    bp                ; restore frame ptr
  768.     dec    DEV_CNT_BP
  769.      jnz    dev_cser_loop
  770.  
  771. dev_cser_done:
  772.     ret
  773.  
  774.  
  775. dev_gr:
  776. ;------
  777.     push    es
  778.     push    si
  779. dev_gr_lp:
  780.     les    si,DEV_BUF_BP
  781.     lods    es:al                ; get char
  782.     mov    DEV_OFF_BP,si            ; update
  783.     mov    cl,al
  784.     mov    dl,byte ptr DEV_TYP_BP        ; vc number
  785.     push    bp
  786.     call    conout_vc1            ; send it
  787.     pop    bp
  788.     dec    DEV_CNT_BP            ; drop count
  789.      jnz    dev_gr_lp            ; if more, loop
  790.     pop    si
  791.     pop    es
  792.     ret
  793. eject
  794.  
  795.     cseg
  796. ;===========
  797. set_screen@:
  798. ;===========
  799. ; Set Screen mode
  800. ;  entry:    dl = vc number
  801. ;        cl = ROS mode
  802. ;      top bit set = no clear on ega's
  803.  
  804.     call    point_vs@        ; bx -> VS_
  805.     test    video$,EGA+VGA+MCGA    ; are we EGA or VGA
  806.     jz    set_1
  807.     jmp    set_ega            ; yes..
  808. set_1:    
  809.     cmp    cl,07            ; modes greater than 7
  810.     ja    screen_not_sup        ; only supported on ega/vga
  811. set_screen1:    
  812.     call    set_colorsel        ; set the default VS_COLORSEL
  813.     cmp    cl,02            ; ROS mode 2 ?
  814.     jne    test_mono        ; no....
  815.     push    ds            ; else test if mono video 
  816.     mov    ax,PC_SEGMENT        ; and convert mode select 2
  817.     mov    ds,ax            ; to mode 7 - ?? ROS does this....
  818.     mov    ax,equip_flag_40
  819.     and    al,30h            ; is it mono
  820.     cmp    al,30h
  821.     pop    ds
  822.     jne    test_mono
  823.     mov    cl,07            ; lets change to ROS mode 7
  824. test_mono:
  825.     cmp    VS_SCREEN_MODE,07    ; if we're on the mono monitor
  826.      jne    screen_set2        ; then just clear screen 
  827.     cmp    cl,07
  828.      jne    mono_card        ; if not ROS mode 7
  829. screen_set2:
  830.     call    screen_set_only@    ; change mode
  831.     test    ax,ax            ; if set is not successful
  832.      jnz    screen_set_ret        ;  then exit here
  833.     cmp    VS_SCREEN_MODE,04
  834.     jb    screen_alpha_clear    ; alpha mode
  835.     cmp    VS_SCREEN_MODE,07
  836.     jne    screen_graphics_clear
  837.  
  838. screen_alpha_clear:
  839.     call    alpha_clear
  840.     jmps    screen_set_ret
  841.  
  842. screen_graphics_clear:
  843.     sub    dx,dx            ; zero "cursor"
  844.     call    put_cursor@
  845.     call    gra_clear
  846. screen_set_ret:
  847.     ret
  848.  
  849.  
  850. mono_card:
  851. ; If on monochrome, just erase the screen:
  852.     call    z_erase@        ; erase the screen
  853. ;    jmps    screen_not_sup        ; and return false
  854.  
  855. ; Error returns:
  856. screen_not_sup:
  857.     mov    ax,0FFFFh
  858.     ret
  859.  
  860.  
  861. ; EGA MCGA or VGA mode set function
  862. ; bx = vs_
  863. ; cl = ros mode with top bit valid
  864. ; --------------------------------
  865. set_ega:
  866.     and    VS_MODE1,not LINE_43_MODE ; mode change always reset 43 line mode
  867.     push    cx            ; save mode
  868.     mov    dl,top_screen$
  869.     cmp    dl,VS_NUMBER        ; if we're not on top
  870.      je    set_ega1        ;  then do not go to ROS
  871.     and    cl,7fh
  872.     cmp    VS_SCREEN_MODE,cl    ; if background VC but not changing
  873.     jne    suspend_backg        ;  mode then just clear screen
  874.  
  875.     pop    cx
  876.     or    VS_MODE1,BLINK_TOGGLE    ; enable blinking attr. default
  877.  
  878. ; we are in background, and so since all modes other than 80x25 text are
  879. ; suspended in background we must be in modes 2,3, or 7. Since we aren't
  880. ; changing mode we just need to clear the correct CRT Seg.
  881.     test    cl,80h            ; clear screen ?
  882.      jnz    set_ega_backg2        ; no.. return
  883.     mov    di,MONO_SEG        ; assume mono
  884.     cmp    cl,7            ; is it?
  885.      je    set_ega_backg1
  886.     mov    di,COLOR_SEG        ; no, use colour seg
  887. set_ega_backg1:
  888.     push    es
  889.     push    cx
  890.     mov    es,di            ; clear this seg
  891.     xor    di,di            ; from the begining
  892.     mov    cx,CRT_ROWS_P*CRT_COLS    ; erase to bottom corner
  893.     mov    al,' '            ; erase to blanks
  894.     mov    ah,VS_ATTRIB        ;   of the current attribute
  895.     cld
  896.     rep    stosw
  897.     pop    cx
  898.     pop    es
  899. set_ega_backg2:
  900.     ret    
  901.     
  902. suspend_backg:
  903.     call    process_suspend        ; else SUSPEND process until io_switch
  904.     pop    cx
  905.     jmps    set_ega
  906.  
  907. set_ega1:
  908.     or    cl,80h            ; set no clear bit
  909.     call    screen_set_only@    ; setup mode variables
  910.  
  911.     call    get_pal            ; get pallette settings from ega
  912.     mov    ah,03h            ; make sure cursor position
  913.     push    bx            ; is current
  914.     xor    bh,bh
  915.     call    int10_entry@        ; get from ROS and save in VS_
  916.     pop    bx
  917.     mov    VS_CURSOR,dx
  918.     pop    cx
  919.     or    VS_MODE1,BLINK_TOGGLE    ; enable blinking attr. default
  920.     cmp    VS_SCREEN_MODE,04
  921.     jb    set_ega_alpha        ; is alpha
  922.     cmp    VS_SCREEN_MODE,07
  923.     je    set_ega_alpha
  924.     and    VS_MODE1,not BLINK_TOGGLE ; enable intensify attr. for graphics
  925.     test    cl,80h            ; clear screen ?
  926.     jnz    set_ega_ret
  927.     call    gra_clear        ; now clear the screen
  928.     jmps    set_ega_ret
  929.         
  930. set_ega_alpha:
  931.     test    cl,80h            ; clear screen ?
  932.     jnz    set_ega_ret        ; no.. return
  933.     call    alpha_clear        
  934. set_ega_ret:
  935.     ret
  936.  
  937. ; clear alpha screen
  938. alpha_clear:
  939.     push    bx
  940.     call    z_erase@        ; clear an alpha screen
  941.     pop    bx
  942.     mov    dh,top_screen$        ; if we're not on top
  943.     cmp    dh,VS_NUMBER        ;  then leave
  944.     jne    clear_done
  945.     mov    dh,sl_crt_flag$
  946.     call    z_sl_blank@        ; and status line too
  947. clear_done:
  948.     ret
  949.  
  950. ; clear graphics screen
  951. gra_clear:
  952.  
  953.     mov    cx,2000h        ; 8k words
  954.     cmp    VS_SCREEN_MODE,0dh
  955.     jb    cl2
  956.     mov    cx, 32*1024/2
  957.     cmp    VS_SCREEN_MODE,11h    ; mode 0D, 0E, 0F, 10 (200/350)
  958.     jb    cl2            ; clear 32k ega modes
  959.     mov    cx, (480*80)/2
  960.     cmp    VS_SCREEN_MODE,13h    ; modes 11h, 12h (480 lines)
  961.     jb    cl2
  962.     mov    cx, (320*200)/2        ; mode 13h (200*320*256 color)
  963.     cmp    VS_SCREEN_MODE,13h
  964.     je    cl2
  965.     mov    cx,4000h        ; clear 16k words must be olivetti modes
  966. cl2:
  967.     push    es            ; now erase the screen
  968.     mov    ax,VS_CRT_SEG
  969.     mov    es,ax            ; point to CRT memory
  970.     sub    di,di            ; top left corner
  971.     sub    ax,ax            ; ax = 0 for blackness
  972.     cld
  973.     rep     stosw            ; blast it
  974.     pop    es
  975.     ret
  976.  
  977.  
  978. ; Get updated pallette values which are reset by
  979. ; EGA ROS after a mode set.
  980. get_pal:
  981.     test    video$,MCGA        ; do nothing if MCGA
  982.     jnz    get_pal_ret
  983.     push    ds
  984.     push ds ! pop es
  985.     lea    di,VS_PALLETTE        ; point to vs_ save area
  986.     xor    si,si
  987.     mov    ds,pal_seg        ; ega save area
  988.     mov    cx,17
  989.     rep    movsb
  990.     pop    ds
  991. get_pal_ret:
  992.     ret
  993.  
  994. eject
  995.  
  996.  
  997. screen_set_only@:
  998. ;----------------
  999. ; This does both graphics and alpha screen mode settings, but does
  1000. ; not clear the screen or its image if not ega/vga unless
  1001. ; top bit set in ch
  1002. ; This is called from IO_SWITCH , SET_SCREEN and INIT (do_video)...
  1003. ;  entry:    bx -> vs_
  1004. ;        cl = ROS screen mode
  1005. ;             ega/vga ros mode (top bit valid)
  1006.     mov    ch,cl
  1007.     and    cl,7fh
  1008.     cmp    cl,02
  1009.     jb    test_gra            ; treat 40 column like graphics
  1010.     cmp    cl,04
  1011.     jb    screen_set_go
  1012.     cmp    cl,07
  1013.     je    screen_set_go            ; not graphics
  1014. test_gra:
  1015.     mov    al,VS_BIT
  1016.     not    al                ; if anybody else is in
  1017.     test    graphic_bits$,al        ;  graphics mode, bag it
  1018.      jz    test_top
  1019.  
  1020.     push    cx                ; save ROS mode
  1021.      call    gr_abort@            ; suspend running process
  1022.     pop    cx
  1023.     mov    cl,ch                ; restore cl
  1024.     jmps    screen_set_only@        ; and try again
  1025.     
  1026. test_top:
  1027.     mov    al,top_screen$            ; if we're not on top
  1028.     cmp    al,VS_NUMBER            ;  then bag it
  1029.      jmpnz    screen_not_sup
  1030.  
  1031.  
  1032. ; Do the mode change
  1033. screen_set_go:
  1034.     test    video$, EGA+VGA+MCGA        ; ega/vga ?
  1035.      jz    not_ega
  1036.      jmp    screen_set_ega
  1037. not_ega:
  1038.     xor    ah,ah
  1039.     mov    al,cl                ; ROS mode into AL
  1040.     mov    si,ax
  1041.     shl    si,1
  1042.     cmp    al,40h
  1043.     je    oliv1
  1044.     cmp    al,48h
  1045.     je    oliv2                ; special olivetti modes
  1046.     jmp    word ptr mode_vector[si]    ; branch to routine
  1047.  
  1048. oliv1:
  1049.     mov    si,offset oli_vector$
  1050.     jmp    word ptr [si]
  1051. oliv2:
  1052.     mov    si,offset oli_vector$
  1053.     jmp    word ptr 2[si]
  1054.  
  1055.  
  1056. eject
  1057.  
  1058. ; ALPHA - NUMERIC SCREEN MODES:
  1059. ; -----------------------------
  1060.  
  1061. black_white_40:                    ; ROS mode 0
  1062. color_40:                    ; ROS mode 1
  1063.     push    ax
  1064.     mov    al,VS_BIT            ; set graphics bit
  1065.     or    graphic_bits$,al
  1066.     pop    ax
  1067.     mov    VS_WIDTH,40
  1068.     mov    si,offset alpha_str_40        ; 40-col. controller string
  1069.     jmps    color_alpha_init  
  1070.  
  1071. mono_80:                    ; ROS mode 7
  1072.     mov    si,offset mono_table$        ; b/w text mode params
  1073.     jmps    color_alpha_init_80
  1074.     
  1075. black_white_80:                    ; ROS mode 2
  1076. color_80:                    ; ROS mode 3
  1077.     mov    si,alpha_str_80            ; variable for compaq
  1078. color_alpha_init_80:
  1079.     mov    VS_WIDTH,80
  1080.     push    ax
  1081.     mov    al,VS_BIT            ; reset graphics bit
  1082.     not    al
  1083.     and    graphic_bits$,al
  1084.     pop    ax
  1085.  
  1086. color_alpha_init:
  1087.     mov    dl,top_screen$            ; if we're not on top
  1088.     cmp    dl,VS_NUMBER            ;  then leave hardware alone
  1089.     jne    set_exit
  1090.     push    cx                ; save ROS mode
  1091.     call    color_video_init        ; do the controller
  1092.     pop    cx
  1093.  
  1094.     mov    VS_SCREEN_MODE,cl        ; save the new mode
  1095.     mov    VS_CRT_SEG,COLOR_SEG        ;  set to color screen
  1096.     test    video$,MONO
  1097.      jnz    set_mono
  1098.     cmp    cl,7                ; ROS mode 7 - monochrome
  1099.      jne    set_color
  1100. set_mono:
  1101.     mov    VS_CRT_SEG,MONO_SEG        ; here if mono screen
  1102.  
  1103. set_color:
  1104.     mov    top_screen_mode$,cl        ; only here if we're top screen
  1105.     push    bx                ; save vs_
  1106.     call    update_all@            ; restore alpha info
  1107.     pop    bx                ; restore vs_
  1108.     sub    ax,ax                ; return success
  1109. set_exit:
  1110.     ret
  1111.  
  1112.  
  1113. eject
  1114.  
  1115. ; GRAPHICS SCREEN MODES:
  1116. ; ----------------------
  1117.  
  1118. color_320:                    ; ROS mode 4
  1119. black_white_320:                ; ROS mode 5
  1120.     mov    VS_WIDTH,40
  1121.     jmps    color_graph_init
  1122.  
  1123.  
  1124. black_white_640:                ; ROS mode 6
  1125.  
  1126. bw_640_400@:                    ; Olivetti 640x400 ROS mode 40h
  1127.                         ; 640x400, 8x16 cells
  1128.  
  1129. bw_640_400_t@:                    ; Olivetti 640x400 ROS mode 48h
  1130.                         ; 640x400, 8x8 cells
  1131.     mov    VS_WIDTH,80
  1132. color_graph_init:
  1133.     mov    VS_CRT_SEG,COLOR_SEG        ; restore proper seg.
  1134. ;    jmps    color_graph_init_s
  1135.     
  1136. color_graph_init_s:
  1137.     mov    VS_SCREEN_MODE,cl        ; save our new mode
  1138.     mov    top_screen_mode$,cl        ; since we're now top
  1139.     mov    si,offset graph_str        ; graphics video init string
  1140.     call    color_video_init        ; switch into color graph mode
  1141.     mov    al,VS_BIT            ; set graphics bit
  1142.     or    graphic_bits$,al
  1143.  
  1144. do_ast:
  1145. ; AST support:
  1146. if not QXM
  1147.     test    ast_flag$,0ffh            ; make sure it is possibly AST
  1148.     jz    not_ast
  1149.     mov    dx,AST_ENHANCED_PORT
  1150.     mov    al,byte ptr ast_enhanced$    ; toggled by i_keyboard
  1151.     out    dx,al
  1152. not_ast:
  1153. endif
  1154.     sub    ax,ax                ; successful return
  1155.     ret
  1156.  
  1157.  
  1158. eject
  1159.  
  1160. ; EGA AND VGA SCREEN MODES :
  1161. ; --------------------------
  1162. ;  entry:    bx -> vs_
  1163. ;         ch = ROS video mode (with top bit set/reset)
  1164. screen_set_ega:
  1165.     push    bx            ; save vs_
  1166.     mov    al,ch            ; mode to al for int 10h
  1167.     xor    ah,ah            ; set mode function #
  1168.     call    int10_entry@
  1169.     mov    ah,0fh            ; now we get the mode to
  1170.     call    int10_entry@        ; see what the ROS made of it
  1171.     pop    bx            ; restore vs_
  1172.     and    al,7fh            ; ROS returns top bit set if no clear
  1173.     mov    top_screen_mode$,al    ; save mode we must be top
  1174.     mov    VS_SCREEN_MODE,al
  1175.     mov    VS_WIDTH,ah        ; number of columns
  1176.     cmp    al,04            ; test if graphics mode
  1177.      jb    ega_alpha
  1178.     cmp    al,07
  1179.      jne    ega_graphics
  1180. ega_alpha:
  1181.     mov    cl,VS_BIT        ; reset graphics bit
  1182.     not    cl
  1183.     and    graphic_bits$,cl
  1184.     cmp    al,02            ; 40 column
  1185.     jae    true_alpha
  1186.     mov    cl,VS_BIT        ; treat like graphics
  1187.     or    graphic_bits$,cl
  1188. true_alpha:
  1189.     mov    VS_CRT_SEG,COLOR_SEG    ; default
  1190.     cmp    al,07
  1191.     je    set_ega_mono
  1192.     call    z_sl_color@        ; color seg status line
  1193.     jmps    not_ega_mono
  1194. set_ega_mono:
  1195.     mov    VS_CRT_SEG,MONO_SEG
  1196.     call    z_sl_mono@        ; mono seg status line
  1197. not_ega_mono:
  1198.     push    bx            ; save vs_
  1199.     call    update_all@
  1200.     pop    bx
  1201.     jmps    ega_set_ret
  1202.  
  1203. ega_graphics:
  1204.     mov    cl,VS_BIT        ; set graphics bits
  1205.     or    graphic_bits$,cl
  1206.     mov    VS_CRT_SEG,COLOR_SEG    ; default seg
  1207.     cmp    al,0dh            ; ega/vga modes
  1208.     jb    ega_set_ret
  1209.     mov    VS_CRT_SEG,EGA_SEG    ; yes .. set ega seg
  1210. ega_set_ret:
  1211.     call    ros_color@
  1212.     ret    
  1213.  
  1214. eject
  1215.  
  1216. ; For the CGA or mono. card, hit the ports to initialize the mode.
  1217. ; Entry:
  1218. ;    cl,al = ROS video mode
  1219. ;     si = video init data string
  1220. color_video_init:
  1221.     mov    dx,MONO_PORT
  1222.     cmp    al,7            ; is it monochrome text
  1223.      je    video_init        ; yes
  1224.     mov    dx,COLOR_PORT
  1225.  
  1226. video_init:
  1227.  
  1228.     mov    ch,cl
  1229.     push    bx                ; save vs_
  1230.      cmp    al,64
  1231.       je    cga_oli_400            ; treat M24 modes like
  1232.      cmp    al,72                ; IBM mode 6 (640 x 200)
  1233.       jne    cga_not_oli
  1234. cga_oli_400:
  1235.      mov    al,6
  1236. cga_not_oli:
  1237.      xor    ah,ah
  1238.      mov    bx,ax                ; get ROS mode
  1239.      shl    bx,1                ; word index
  1240.      mov    ax,mode_color_tbl[bx]        ; get mode and color-select
  1241.     pop    bx                ; restore vs_
  1242.  
  1243.     push    ax                ; save mode/color
  1244.     add    dx,4
  1245.     and    al,3fh                ; video off
  1246.     out    dx,al
  1247.     sub     dx,4
  1248.  
  1249.     push    cx
  1250.      mov    cx,16                ; CRTC parameters
  1251.      sub    ah,ah                ; init. port index
  1252. vi_lp:
  1253.       mov    al,ah
  1254.       out    dx,al                ; port index setup
  1255.       inc    dx                ; to data port
  1256.       lodsb                    ; get data byte
  1257.       out    dx,al                ; send it
  1258.       dec    dx                ; back to addr. port
  1259.       inc    ah                ; next addr. index
  1260.       loop    vi_lp
  1261.     pop    cx
  1262.     cmp    cloneflag$,IS_M24
  1263.      jne    not_olivetti
  1264.  
  1265. ; set mode register #2 for olivetti modes
  1266.     add    dx,6
  1267.     in    al,dx                ; input status
  1268.     and    al,010h                ; isolate color bit
  1269.     shl    al,1
  1270.     shl    al,1
  1271.     
  1272.     cmp    ch,40h                ; is it graphics modes 64/72
  1273.      jb    md_dbl
  1274.     inc    ax                ; yes.. set double scan
  1275. md_dbl:
  1276.     add    dx,4                ; mode control register 2
  1277.     out    dx,al
  1278.     sub    dx,10                ; reset to base
  1279.  
  1280. not_olivetti:
  1281.     pop    ax                ; restore mode/color
  1282.     add    dx,4                ; get to mode-select reg.
  1283.     out    dx,al
  1284.     mov    mode_reg$,al            ; save it
  1285.     mov    ah,al
  1286.     inc    dx
  1287.  
  1288.     mov    al,VS_COLORSEL        ; get overscan
  1289.     out    dx,al            ; set overscan    
  1290.     push    ds
  1291.      mov    dx,PC_SEGMENT
  1292.      mov    ds,dx
  1293.      mov     crt_mode_set_40,ah
  1294.      mov    crt_pallette_40,al
  1295.      mov     crt_mode_40,ch
  1296.     pop    ds
  1297.  
  1298.     ret
  1299.  
  1300.  
  1301.  
  1302. ros_color@:
  1303. ; Set colorsel reg based on VS_COLORSEL in screen structure:
  1304. ; Only used for CGA
  1305. ; Entry:   bx = vs_
  1306.  
  1307.     push    bx                ; save vs_
  1308.      mov    bl,VS_COLORSEL
  1309.      cmp    bl,last_pall            ; don't do it if we don't need
  1310.       je    rc_done                ;  to...there's a large window
  1311.      mov    last_pall,bl            ;  in the EGA ROS where ints
  1312.                          ;  are disabled.
  1313.      sub    bh,bh
  1314.      push    bx
  1315.  
  1316.       and    bl,1Fh                ; set low 5
  1317.       mov    ah,11                ; set color
  1318.     call    int10_entry@
  1319.  
  1320.      pop    bx
  1321.      test    bl,20h
  1322.       jz    not_20
  1323.      mov    bx,0101h
  1324.      jmps    set_bit_5
  1325. not_20:
  1326.      mov    bx,0100h
  1327. set_bit_5:
  1328.      mov    ah,11
  1329.     call    int10_entry@
  1330. rc_done:
  1331.     pop    bx                ; restore vs_
  1332.  
  1333.     sub    ax,ax                ; successful return
  1334.     ret
  1335.  
  1336.  
  1337. ; Entry: CL = ROS mode
  1338. ;     BX = vs_
  1339. ; Exit:  VS_COLORSEL contains proper value per int 10h, func. 11d
  1340. ;     to set the color select ("palette") register.
  1341. ;     This is the equivalent on the CGA of 0 - 3Fh, which is
  1342. ;     sent to the color-select register.
  1343. set_colorsel:
  1344.  
  1345.     mov    al,30h            ; for all modes but 640
  1346.     cmp    cl,40h            ; olivetti mode 64
  1347.      je    set_col
  1348.     cmp    cl,48h            ; olivetti mode 72
  1349.      je    set_col
  1350.     cmp    cl,06            ; 640 graphics, because...
  1351.      jne    not_640_
  1352. set_col:
  1353.     mov    al,byte ptr colsel_640$    ; because that's the 
  1354. not_640_:                ;  only different one
  1355.     cmp    al,VS_COLORSEL
  1356. ;    je    set_col1
  1357.     mov    VS_COLORSEL,al
  1358. ;    push    ds
  1359. ;     mov    dx,PC_SEGMENT
  1360. ;     mov    ds,dx
  1361. ;     mov    dx,addr_6845_40
  1362. ;    add    dx,5
  1363. ;    out    dx,al            ; output color selection
  1364. ;    mov    crt_pallette_40,al    ; and save in ROS
  1365. ;    pop    ds
  1366.  
  1367. set_col1:
  1368.     ret
  1369.  
  1370. ; Reset the appropriate palette registers:
  1371. ; Entry : BX = VS->
  1372. ega_pallette@:
  1373.     test    video$,VGA        ; VGA (mono or color)
  1374.     jnz    ega_pal
  1375.     test    video$,EGA        ; ega
  1376.      jz    pal_ret            ; no, so skip
  1377.     test    video$,COLOR        ; ega color
  1378.     jz    pal_ret            ; no skip it
  1379. ega_pal:
  1380.     cmp    VS_SCREEN_MODE,6
  1381.     jbe    pal_ret
  1382.     lea    dx,VS_PALLETTE
  1383.     mov    si,dx
  1384.     mov    byte ptr 10h[si],0    ; clear overscan value - fix bug in 
  1385.                     ; compaq ega ROS
  1386.     push    es
  1387.     push ds ! pop es            
  1388.     mov    ax,1002h        ; set all pallette regs + overscan
  1389.     call    int10_entry@        ; visit ROS (regs preserved)
  1390.     pop    es
  1391. pal_ret:
  1392.     ret
  1393.  
  1394.  
  1395. save_plane2@:
  1396. ;------------
  1397. ; When switching to an alpha mode on the ega, the ROS writes the character
  1398. ; generator data to bit plane 2.  We need to save this space if we're in an
  1399. ;(advanced graphics mode which is using it as a color plane.
  1400.  
  1401. ; Set the memory read mode to 0, which means the actual byte in the map
  1402. ;  rather than a color compare:
  1403.     mov    dx,EGA_G12_ADDR
  1404.     mov    ax,G12_MODE*256 + 0
  1405.     call    index_out
  1406.  
  1407. ; Set the read-map selector for only bit plane 2:
  1408.     mov    ax,G12_READ_MAP_SLCT * 256 + 2
  1409.     call    index_out
  1410.  
  1411. ; Store 8K bytes:
  1412.     mov    ax,EGA_SEG            ; source
  1413.     mov    cx,bit_plane_seg$        ; dest
  1414.     call    move_ega_bytes
  1415.  
  1416. ; Now set the read-map selector back to our best guess as to what most
  1417. ; applications will have it set to most of the time:
  1418.     mov    ax,G12_READ_MAP_SLCT * 256 + 0
  1419.     jmps    index_out            ; and return
  1420. eject
  1421.  
  1422. restore_plane2@:
  1423. ;---------------
  1424. ; After getting the video hardware to switch modes back into one of the
  1425. ; enhanced graphics modes on the EGA, restore the data which was saved
  1426. ; before the last switch:
  1427.  
  1428. ; This code needs to :
  1429. ;    1. set write mode 0;
  1430. ;    2. enable all bits w/ the bit mask reg;
  1431. ;    3. disable set/reset for all planes;
  1432. ;    4. set rotate register to 0;
  1433. ;    5. set sequencer map mask reg. to disable all planes exc. 2.
  1434. ; Since we've just come back from ROS on a mode set, we can depend on
  1435. ; all of them to be the way we want them except 5.  Ergo:
  1436.  
  1437.     mov    dx,EGA_SEQ_ADDR
  1438.     mov    ax,SEQ_MAP_MASK * 256 + 0100b
  1439.     call    index_out
  1440.  
  1441. ; Now replace the stored bytes in the bit map:
  1442.     mov    ax,bit_plane_seg        ; source
  1443.     mov    cx,EGA_SEG            ; destination
  1444.     call    move_ega_bytes
  1445.  
  1446. ; Restore the sequencer reg:
  1447.     mov    ax,SEQ_MAP_MASK * 256 + 1111b
  1448.     jmps    index_out            ; and ret
  1449.  
  1450. index_out:
  1451. ; Entry:    dx = address port, dx+1 = data port
  1452. ;        ah = data register index
  1453. ;        al = data
  1454.  
  1455.     xchg    ah,al
  1456.     out    dx,al
  1457.     xchg    ah,al
  1458.     inc    dx
  1459.     out    dx,al
  1460.     dec    dx
  1461.     ret
  1462.  
  1463.  
  1464. move_ega_bytes:
  1465. ; Entry: ax = source segment
  1466. ;     cx = dest. segment
  1467.  
  1468.     push    ds
  1469.     push    es
  1470.     mov    es,cx                ; dest.
  1471.     mov    ds,ax                ; source
  1472.     sub    si,si
  1473.     mov    di,si
  1474.     mov    cx,PLANE2_LENGTH/2        ; by words
  1475.     cld
  1476.     rep    movsw
  1477.     pop    es
  1478.     pop    ds
  1479.     ret
  1480.  
  1481.  
  1482.  
  1483. ; Entry to abort process on serial terminal if making ROS calls.
  1484. ser_abort@:
  1485.     mov    ax,offset fatal_ser_msg$
  1486.     mov    cx,FATAL_SER_MSG_LENGTH            ; msg length.
  1487.     jmps    proc_abort@                ; fall through
  1488.  
  1489. gr_abort@:
  1490. ; Here if somebody else is in a graphics mode.  Print message and 
  1491. ; suspend the process - wake up at io_switch:
  1492. ; Enter BX -> VS_
  1493.     mov    ax,offset fatal_gr_msg$
  1494.     mov    cx,FATAL_GR_MSG_LENGTH        ; msg length.
  1495.     push    bx
  1496.     call    disp_msg            ; display message
  1497.     pop    bx
  1498. ;    jmps    suspend_process        ; fall through
  1499.  
  1500. ; Suspend Process on Flagwait until screen switch
  1501. ; Enter BX = VS_
  1502. process_suspend:
  1503.     push    bx                ; save VS_
  1504.     mov    cl,DEV_FLAGALLOC
  1505.     call    supif@                ; get flag number
  1506.     pop    bx
  1507.     mov    VS_CONMODE,al            ; store flag
  1508. gr_abort1:
  1509.     push    bx
  1510.     mov    dl,VS_CONMODE            ; flag number
  1511.     call    flagwait@            ; wait io_switch to wake us up
  1512.     pop    bx
  1513.     mov    al,VS_BIT
  1514.     not    al                ; if anybody else is in
  1515.     test    graphic_bits$,al        ;  graphics suspend again
  1516.     jnz    gr_abort1
  1517.     push    bx
  1518.     xor    dl,dl
  1519.     xchg    dl,VS_CONMODE            ; get flag and free it
  1520.     mov    cl,DEV_FLAGFREE
  1521.     call    supif@
  1522.     pop    bx
  1523.     ret
  1524.  
  1525.     
  1526. proc_abort@:
  1527. ; public entry to abort a running process.
  1528. ; Entry: ax = offset in SYSDAT of message to print
  1529. ;     cx = length of message, or 0 if none
  1530.  
  1531.     call    disp_msg
  1532.     mov    bx,rlr$
  1533.     and    P_FLAG[bx],not (PF_KEEP + PF_TEMPKEEP)
  1534.     mov    cx,P_TERM
  1535.     mov    dx,0ffffh
  1536.     jmp    supif@
  1537. ; Process is terminated.
  1538.  
  1539. disp_msg:
  1540.     jcxz    no_msg
  1541.  
  1542.     mov    bx,rlr$
  1543.     mov    dl,P_CONS[bx]                ; get console num.
  1544.     mov    dh,0                    ; console dev. type
  1545.  
  1546.     push    dx                    ; setup param. block
  1547.     push    cx
  1548.     push    ds                    ; segment
  1549.     push    ax                    ; offset
  1550.  
  1551.     sub    sp,4                    ; adjust
  1552. ;    call    io_devio@
  1553.     
  1554.     mov    bx,39*2                    ; DEVIO
  1555.     call    cs:func_tbl$[bx]                ; call function
  1556.     add    sp,12                    ; back to normal
  1557. no_msg:
  1558.     ret
  1559.  
  1560.  
  1561.  
  1562. eject
  1563.  
  1564. w1dseg1    dseg word
  1565.  
  1566. mode_vector$    dw    black_white_40,        color_40    ; 0-1
  1567.     dw    black_white_80,        color_80    ; 2-3
  1568.     dw    color_320,        black_white_320    ; 4-5
  1569.     dw    black_white_640,    mono_80        ; 6-7
  1570. ;    dw    screen_not_sup,        screen_not_sup    ; 8-9 not used
  1571. ;    dw    screen_not_sup,        screen_not_sup    ; 0ah-0bh not used
  1572. ;    dw    screen_not_sup                ; 0ch   not used
  1573. ;    dw    screen_not_sup,        screen_not_sup    ; 0dh-0eh ega not used
  1574. ;    dw    screen_not_sup,        screen_not_sup    ; 0fh-10h ega not used
  1575. ;    dw    screen_not_sup                ; 11h used for MCGA only
  1576. ;    dw    screen_not_sup                ; 12h vga - not used
  1577. ;    dw    screen_not_sup                ; 13h used for MCGA only
  1578.  
  1579. oli_vector$    dw    screen_not_sup,        screen_not_sup    ; olivetti modes
  1580.  
  1581.  
  1582. ; The additional graphics modes for ega/vga have their vectors established
  1583. ; by INIT if the EGA/VGA is present.
  1584.  
  1585. ; 6845 video controller config. data tables, used by get_set_screen:
  1586.  
  1587. graph_str    db    38h,28h,2Dh,0Ah,7Fh,06h,64h,70h,02h,01h,06h,07h,0,0,0,0
  1588. mono_table$    db    61h,50h,52h,0fh,19h,06h,19h,19h,02h,0dh,2bh,0ch,0,0,0,0
  1589.  
  1590. alpha_str_40    db    38h,28h,2Dh,0ah,1fh,06h,19h,1ch,02h,07h,26h,07h,0,0,0,0
  1591.  
  1592. alpha_str_80    dw    ibm_str
  1593. ibm_str        db    71h,50h,5Ah,0ah,1fh,06h,19h,1ch,02h,07h,26h,07h,0,0,0,0
  1594. compaq_str$    db    71h,50h,5ah,0ah,19h,06h,19h,19h,02h,0dh,2bh,0ch,0,0,0,0
  1595.  
  1596. ; Mode-select and color-select values indexed by ROS mode number:
  1597. mode_color_tbl    dw    002Ch, 0028h, 002Dh, 0029h
  1598.         dw    200Ah, 200Eh, 071Eh, 0029h    ; #7 for mono adapt.
  1599.  
  1600. ; AST "Colorgraphplus" enhancement toggle:
  1601. ast_enhanced$    rw    0
  1602.         db    AST_ENHANCED_ON        ; default
  1603.         db    AST_ENHANCED_OFF    ; if user hits cntl-pad-5
  1604.  
  1605. colsel_640$    rw    0
  1606.         db    3Fh            ; default for colsel register
  1607.         db    10h            ; for AST hi res
  1608.  
  1609. ast_flag$    db    0            ; test for AST color card
  1610. local_ptr$    rw    3            ; ega save pointer data area
  1611. pal_seg        rw    1
  1612.         rw    12
  1613.  
  1614.  
  1615. last_pall    db    0
  1616.  
  1617. eject
  1618.  
  1619.     cseg
  1620.  
  1621. ; ***  VC ESCAPE CHARACTER RECEIVED    ***
  1622. ; ***  CONSOLE ESCAPE ROUTINES FOLLOW: ***
  1623.  
  1624. z_up@:
  1625. ; ESC A  -  cursor up:
  1626.     dec    dh                ; next row up
  1627.      jns    z_cursor            ; if not already on top,
  1628.     ret                    ;   then set cursor
  1629.  
  1630. z_down:
  1631. ; ESC B  -  cursor down:
  1632.     inc    dh                ; next row down
  1633.     cmp    dh,VS_CRT_ROWS            ; if not already at bottom,
  1634.      jb    z_cursor            ;   then set cursor
  1635.     ret
  1636.  
  1637. z_forward:
  1638. ; ESC C  -  cursor forward:
  1639.     inc    dl                ; next column right
  1640.     cmp    dl,CRT_COLS            ; if not already at right,
  1641.      jb    z_cursor            ;   then set cursor
  1642.     ret
  1643.  
  1644. z_back:
  1645. ; ESC D  -  cursor backward:
  1646.     dec    dl                ; next column left
  1647.      jns    z_cursor            ; if not already at left,
  1648.     ret                    ;   then set cursor
  1649.  
  1650. z_erase@:
  1651. ; ESC E  -  erase console:
  1652.     call    z_home                ; get to top left
  1653.     sub    dx,dx                ; top left
  1654.     jmps    z_erase_eos@            ; erase to end
  1655.  
  1656. z_home:
  1657. ; ESC H  -  home cursor:
  1658.     sub    dx,dx                ; 0,0 = top left corner
  1659. ;    jmps    z_cursor
  1660.  
  1661. z_cursor:
  1662.     jmp    put_cursor@            ; save and display if visible
  1663.  
  1664. z_rev_index:
  1665. ; ESC I  -  reverse index:
  1666.     test    dh,dh                ; if not on the top row,
  1667.      jnz    z_up@                ;   then just move up
  1668.     jmp    z_insert_line@            ; else scroll down from top
  1669.  
  1670. z_erase_eos@:
  1671. ; ESC J  -  erase to end of screen:
  1672.     mov    ch,VS_CRT_ROWS            ; erase to bottom corner
  1673.     sub    cl,cl
  1674.     jmps    eraser                ; common code
  1675.  
  1676. z_erase_eol@:
  1677. ; ESC K  -  erase to end of line:
  1678.     mov    ch,dh                ; this row
  1679.     inc    ch                ; to the next row,
  1680.     sub    cl,cl                ;   first column
  1681.     jmps    eraser                ; common code
  1682.  
  1683. z_insert_line@:
  1684. ; ESC L  -  insert a BLANK line:
  1685.     mov    al,CRT_COLS
  1686.     mul    VS_CRT_ROWS            ; ax = crt size
  1687.     dec    ax
  1688.     mov    di,ax
  1689.     sub    ax,CRT_COLS
  1690.     mov    si,ax
  1691.     shl    di,1                ; end of screen
  1692.     shl    si,1                ; one line up
  1693.  
  1694.     sub    dl,dl                ; first column
  1695.     mov    al,VS_WIDTH            ; do point_cursor w/out disturbing di
  1696.     mul    dh                ; AX = count from top
  1697.     std                    ; backwards move
  1698.     jmps    z_ins_del_line            ; shared code
  1699.  
  1700.  
  1701. z_erase_bos@:
  1702. ; ESC d  -  erase from beginning of screen:
  1703.     mov    cx,dx                ; current location
  1704.     sub    dx,dx                ; top left corner start
  1705.     jmps    eraser
  1706.  
  1707. z_erase_line@:
  1708. ; ESC l  -  erase entire line:
  1709.     sub    dl,dl                ; from first column
  1710.     mov    cx,dx                ; to the first column
  1711.     inc    ch                ;   of the next row
  1712.     jmps    eraser
  1713.  
  1714. z_erase_bol@:
  1715. ; ESC o  -  erase from beginning of line:
  1716.     mov    cx,dx                ; erase to cursor
  1717.     sub    dl,dl                ; from first column
  1718. ;    jmps    eraser
  1719. eject
  1720.  
  1721. eraser:
  1722. ; Common erase routine:
  1723. ;  entry:    dx = start of erase row,column
  1724. ;        cx = one past ending row,column
  1725.  
  1726.     xchg    cx,dx                ; dx = one past the end
  1727.     call    point_cursor@            ; ax = end pointer
  1728.     xchg    cx,dx                ; dx = start cursor
  1729.     xchg    ax,cx                ; cx = end pointer
  1730.     call    point_cursor@            ; ax = start pointer
  1731.     sub    cx,ax                ; cx = erase char count
  1732.      jnz    erase                ; skip if something to erase
  1733.     ret                    ; return if nothing
  1734. erase:
  1735.     mov    al,' '                ; erase to blanks
  1736.     mov    ah,VS_ATTRIB            ;   of the current attribute
  1737. ;    jmps    erase_pc@
  1738.  
  1739.  
  1740. erase_pc@:
  1741. ; This is an entry used by the pc mode emulator:
  1742.  
  1743.     test    VS_MODE,MATCH_BIT
  1744.      jz    erase1                ; skip if full on top
  1745.  
  1746.     push    es
  1747.     mov    es,VS_VC_SEG            ; base of vc image
  1748.     rep    stosw                ; BLANK a bunch
  1749.     pop    es
  1750.     cld                    ; in case df was set
  1751.     jmp    update_window@            ; and show it
  1752. erase1:
  1753.     jmp    put_crt_s@            ; if full top, go to physical
  1754. eject
  1755.  
  1756. z_delete_line@:
  1757. ; ESC M  -  delete one line:
  1758.     sub    dl,dl
  1759.     call    point_cursor@            ; di -> line start
  1760.     mov    si,di
  1761.     add    si,CRT_COLS*2            ; next row down
  1762. z_ins_del_line:
  1763.     push    ax
  1764.     mov    ax,dx
  1765.     call    poke_ros_cursor@
  1766.     pop    ax
  1767.     xchg    VS_CURSOR,dx
  1768.     xor    dh,dh
  1769.     sub    VS_OFFSET,dx            ; cursor moves to 1st col.
  1770.     or    VS_MODE,UPDATE_BIT        ; signal cursor has been moved
  1771. ;    jmps    z_line
  1772.  
  1773. z_line:
  1774. ; External entry point:
  1775. ;  entry:    si,di set up for movsw
  1776. ;        ax = count from top of screen
  1777.     xchg    cx,ax                ; cx = count
  1778.     mov    al,CRT_COLS
  1779.     mul    VS_CRT_ROWS            ; ax = crt size
  1780.     sub    ax,CRT_COLS
  1781.     xchg    ax,cx
  1782.     sub    cx,ax                ; cx = character count
  1783.      jbe    z_line1                ; skip if nothing to move
  1784.  
  1785.     call    z_movsw@            ; movsw in vc_segment
  1786. z_line1:
  1787.     mov    cx,CRT_COLS            ; one line's worth
  1788.     call    erase                ; blank one line
  1789.     cld                    ; clear dir. flag (insert)
  1790.     jmp    show_cursor@
  1791.  
  1792.  
  1793. z_movsw@:
  1794. ; repeat movsw in current screen segment:
  1795.     push    es
  1796.     push    ds                ; save around the move
  1797.     sub    ah,ah                ; assume no sync
  1798.     mov    es,VS_VC_SEG
  1799.     test    VS_MODE,MATCH_BIT
  1800.      jnz    z_movsw1            ; skip if not full top
  1801.     mov    ah,IN_SYNC + OUT_SYNC
  1802.     mov    es,VS_CRT_SEG            ; else move physical
  1803. z_movsw1:
  1804.     push    es
  1805.     pop    ds                ; move within the seg
  1806.     call    put_crt_m@            ; like a movsw with sync
  1807.     pop    ds
  1808.     pop    es
  1809.     ret
  1810. eject
  1811.  
  1812. z_delete_char:
  1813. ; ESC N  -  delete one character:
  1814.     mov    di,VS_OFFSET
  1815.     shl    di,1                ; DI -> current char
  1816.  
  1817.     mov    cx,CRT_COLS-1            ; last column
  1818.     sub    cl,dl                ; cx = chars to line end
  1819.      jz    z_del_ch1            ; skip if at line end
  1820.     mov    si,di
  1821.     inc    si                ; next char right
  1822.     inc    si
  1823.     call    z_movsw@            ; shift left one char
  1824. z_del_ch1:
  1825.     mov    cx,1                ; erase one last char
  1826.     jmp    erase
  1827.  
  1828. z_set_cursor:
  1829. ; ESC Y  -  set cursor position:
  1830.     call    leave_until_char@
  1831.     sub    cl,' '                ; correct for space offset
  1832.      js    z_set_col            ; if illegal, skip row set
  1833.     cmp    cl,VS_CRT_ROWS            ; check upper bound
  1834.      jae    z_set_col            ; 25 :== 0 through 24 ok
  1835.     mov    VS_CUR_ROW,cl            ; save the row
  1836. z_set_col:
  1837.     call    leave_until_char@
  1838.     sub    cl,' '                ; correct for space offset
  1839.      js    z_set_done            ; if illegal, skip col set
  1840.     cmp    cl,CRT_COLS            ; check upper bound
  1841.      jae    z_set_done            ; 80 :== 0 through 79 ok
  1842.     mov    dl,cl                ; dx = new cursor location
  1843. z_set_done:
  1844.     call    restore_state@            ; back to normal
  1845. ;    mov    ax,VS_CURSOR            ;
  1846. ;    call    poke_ros_cursor@        ; done below
  1847.     jmp    put_cursor@            ; update and display new curs.
  1848.  
  1849. z_set_fore:
  1850. ; ESC b  -  set foreground color:
  1851.     call    leave_until_char@
  1852. z_fore1@:                ;ANSI entry point
  1853.     mov    ah,VS_ATTRIB            ; current attribute
  1854.     jmps    z_fg_bg                ; shared code
  1855.  
  1856. z_set_back:
  1857. ; ESC c  -  set background color:
  1858.     call    leave_until_char@
  1859.     mov    ah,al                ; ah = bg bits
  1860.     mov    cl,4
  1861.     rol    ah,cl                ; bg bits to ms nibble
  1862.     mov    al,VS_ATTRIB
  1863. z_fg_bg:
  1864.     and    al,0fh                ; take the 4 lsb's of al
  1865.     and    ah,0f0h                ;   and the 4 msb's of ah
  1866.     or    al,ah                ;   and mash 'em together
  1867.     mov    VS_ATTRIB,al            ; that's the new attribute
  1868.     jmp    restore_state@            ; back to normal
  1869. eject
  1870.  
  1871. new_cursor_on@:
  1872. ; Entry used by switch to restore cursor:
  1873.     test    VS_MODE,CURSOR_BIT
  1874.      jz    z_cursor_off            ; skip if cursor off
  1875. ;    jmps    z_cursor_on            ; else turn it on
  1876.  
  1877.  
  1878. z_cursor_on:
  1879. ; ESC e  -  enable cursor:
  1880.     mov    last_curs$,0ffffh        ; force update next tick
  1881.     or    VS_MODE,CURSOR_BIT
  1882.     mov    cx,VS_CUR_TYPE            ; monochrome or color
  1883.     mov    ah,1                ; int 10 function #
  1884.     call    int10_entry@
  1885.     jmp    show_cursor@            ; and return
  1886.  
  1887. z_cursor_off:
  1888. ; ESC f  -  disable cursor:
  1889.     and    VS_MODE,not CURSOR_BIT
  1890. old_cursor_off@:                ; external entry
  1891.     mov    cx,1f1fh            ; HIDE cursor (even on Amstrad)
  1892.     cmp    cloneflag$,IS_AMSTRAD
  1893.     je    z_cur1
  1894.     mov    cx,VS_CUR_TYPE            ; monochrome or color
  1895.     or    ch,20h                ; disable bit
  1896. z_cur1:
  1897.     mov    ah,1                ; int 10 function #
  1898.     jmp    int10_entry@
  1899.  
  1900. z_save_cursor@:
  1901. ; ESC j - save cursor position:
  1902.     mov    VS_SAVE_CURSOR,dx
  1903.     ret                    ; save for later
  1904.  
  1905. z_restore_cursor@:
  1906. ; ESC k  -  restore cursor position:
  1907.     mov    dx,VS_SAVE_CURSOR
  1908.     jmp    put_cursor@            ; back where it was
  1909. eject
  1910.  
  1911. z_rev_on@:
  1912. ; ESC p  -  reverse video on:
  1913.     test    VS_MODE,REV_BIT            ; if already reversed
  1914.      jnz    z_rev2                ;   then forget it
  1915.     or    VS_MODE,REV_BIT            ; remember
  1916.     jmps    z_rev1                ; to common code
  1917.  
  1918. z_rev_off:
  1919. ; ESC q  -  reverse video off:
  1920.     test    VS_MODE,REV_BIT            ; if already off
  1921.      jz    z_rev2                ;   then forget it
  1922.     and    VS_MODE,not REV_BIT
  1923. z_rev1:                        ; shared code
  1924.     mov    al,VS_ATTRIB            ; get current colors
  1925.     mov    ah,al                ; copy for msb's
  1926.     and    ax,8877h            ; mask colors only
  1927.     mov    cl,4
  1928.     rol    al,cl                ; swap colors
  1929.     or    al,ah                ; restore intense, blink
  1930.     mov    VS_ATTRIB,al            ; new attribute
  1931. z_rev2:
  1932.     ret
  1933.  
  1934. z_intense_on@:
  1935. ; ESC r  -  intensity on:
  1936.     or    VS_ATTRIB,08h            ; set the intense bit
  1937.     ret
  1938.  
  1939. z_intense_off:
  1940. ; ESC u  -  intensity off:
  1941.     and    VS_ATTRIB,0f7h            ; reset the intense bit
  1942.     ret
  1943.  
  1944. z_blink_on@:
  1945. ; ESC s  -  blink on:
  1946.     or    VS_ATTRIB,80h            ; set the blink bit
  1947.     ret
  1948.  
  1949. z_blink_off:
  1950. ; ESC t  -  blink off:
  1951.     and    VS_ATTRIB,7fh            ; reset the blink bit
  1952.     ret
  1953. eject
  1954.  
  1955. z_wrap_on:
  1956. ; ESC v  -  wrap at line end on:
  1957.     or    VS_MODE,WRAP_BIT
  1958.     ret
  1959.  
  1960. z_wrap_off:
  1961. ; ESC w  -  no wrap at line end:
  1962.     and    VS_MODE,not WRAP_BIT
  1963. z_return:
  1964.     ret
  1965.  
  1966. z_set_color@:
  1967. ; ESC x  -  switch console to color monitor:
  1968.  
  1969.     test    video$,COLOR            ; if no color card
  1970.      jz    z_return            ;   then do nothing
  1971. ;    cmp    top_screen_mode$,05h
  1972.     cmp    graphic_bits$,0            ; set mode instead?
  1973.      jnz    z_return            ; skip if top's not alpha 80
  1974.  
  1975.     call    copy_full_top@            ; if full on top, copy back
  1976.     call    old_cursor_off@
  1977.     call    set_color@            ; update VS_ variables
  1978.     jmp    set_new_mon@            ; redo all windows
  1979.  
  1980.  
  1981. z_set_mono@:
  1982. ; ESC y  -  switch console to monochrome monitor:
  1983.  
  1984.     test    video$,MONO            ; if no monochrome card
  1985.      jz    z_return            ;   then do nothing
  1986.     test    graphic_bits$,0ffh
  1987.      jnz    z_return            ; skip if anybody's graphic
  1988.  
  1989.     call    copy_full_top@            ; if full on top, copy back
  1990.     call    old_cursor_off@
  1991.     call    set_mono@            ; update VS_ variables
  1992.     jmp    set_new_mon@            ; redo all windows
  1993.  
  1994.  
  1995. z_norm_attr:
  1996. ; ESC z  -  restore normal attributes:
  1997.  
  1998.     mov    ah,iattrib$            ; get initial attribute
  1999.     mov    VS_ATTRIB,ah            ; save as current
  2000.     and    VS_MODE,0FFh-04            ; not reverse video
  2001.     or    VS_MODE,03h            ; wrap and cursor
  2002.     jmp    z_cursor_on            ; display cursor
  2003. eject
  2004.  
  2005. set_color@:
  2006. ; Set VS_ variables to color monitor:
  2007. if SR
  2008.     cmp    VS_NUMBER,NUM_VIR_CONS
  2009.     jae    is_sr                ; VS_XLAT set up in SRTERM
  2010. endif
  2011.     mov    VS_XLAT,offset color_xlat$
  2012. is_sr:
  2013.     mov    VS_CRT_SEG,COLOR_SEG
  2014.     mov    cx,var_cursor$            ; different for compaq
  2015.     mov    VS_CUR_TYPE,cx
  2016.     call    trans_cur_type@
  2017.     mov    al,var_sync$            ; different for COMPAQ, EGA
  2018.     or    VS_MODE,al
  2019.     mov    al,VS_BIT
  2020.     or    color_bits$,al            ; add to color vc's
  2021.     not    al                ; and subtract from mono's
  2022.     and    mono_bits$,al
  2023.     mov    VS_SCREEN_MODE,03        ; 80x25 color mode
  2024.     ret
  2025.  
  2026. set_mono@:
  2027. ; Set VS_ variables to monochrome monitor:
  2028. ;if BACKG
  2029.     cld
  2030.     mov    cx,MONO_PARAMS_LEN$
  2031.     lea    di,VS_CRT_DATA
  2032.     mov    si,offset mono_params$
  2033.     push ds ! pop es
  2034.     rep     movsb
  2035. ;endif
  2036.     mov    VS_CRT_SEG,MONO_SEG
  2037.     mov    VS_XLAT,offset mono_xlat$
  2038.     mov    cx,MONO_CURSOR
  2039.     mov    VS_CUR_TYPE,cx
  2040.     call    trans_cur_type@            ; update VS_CUR_TYPE_HW
  2041.     and    VS_MODE,not SYNC_BIT        ; no retrace wait required
  2042.     mov    al,VS_BIT
  2043.     or    mono_bits$,al            ; add to mono vc's
  2044.     not    al                ; and remove from color's
  2045.     and    color_bits$,al
  2046.     mov    VS_SCREEN_MODE,07        ; 80x25 monochrome mode
  2047.     ret
  2048.  
  2049.  
  2050. z_video_mode:
  2051. ; ESC a  -  set color graphics card video mode:
  2052.  
  2053.     call    leave_until_char@
  2054.     call    restore_state@            ; back to con_normal
  2055. z_set_mode@:
  2056.     and    al,07h                ; allow only mode 0-7
  2057.     cbw
  2058.     mov    si,ax                ; table index
  2059.     mov    cl,screen_table[si]
  2060.     mov    dl,VS_NUMBER            ; vc number
  2061.     jmp    set_screen@            ; just like a back door
  2062.  
  2063. screen_table    db    00h,00h,02h,03h
  2064.         db    04h,05h,06h,00h
  2065. eject
  2066.  
  2067. z_back_door:
  2068. ; ESC !  -  general XIOS back door entry:
  2069.  
  2070.     mov    VS_BACK_COUNT,0            ; register counter
  2071.     call    leave_until_char@
  2072.     mov    al,VS_BACK_COUNT
  2073.     cbw                    ; ax -> which register
  2074.     lea    di,VS_BACK_AX
  2075.     mov    si,di                ; save for loading
  2076.     add    di,ax                ; point to register
  2077.     mov    [di],cl                ; save register value
  2078.     inc    ax                ; next reg
  2079.     mov    VS_BACK_COUNT,al
  2080.     cmp    al,8                ; max 8 bit register
  2081.      jb    z_back_ret            ; stay here for 8
  2082.  
  2083. ; Ready to go for it:
  2084.     call    restore_state@            ; reset conout vector
  2085.     push    es
  2086.     push    cs ! pop es            ; local es for scan
  2087.     mov    di,offset legal_func_list
  2088.     mov    cx,length legal_func_list
  2089.     lodsw                    ; fetch ax (al=func #)
  2090.     repnz    scasb                ; check for legal call
  2091.     pop    es
  2092.      jnz    z_back_ret            ; if illegal, return
  2093.  
  2094. ; A legal function number has been given:
  2095.     mov    VS_MX,0                ; allow entry
  2096.     push    bx                ; save VS structure
  2097.  
  2098.     xchg    ax,dx                ; dx saves ax call value
  2099.     lodsw ! xchg ax,bx            ; bx call value
  2100.     lodsw ! xchg ax,cx            ; cx call value
  2101.     lodsw ! xchg ax,dx            ; dx and ax call value
  2102.  
  2103.     push    cs                ; allow for RETF in entry@
  2104.     call    entry@                ; call XIOS entry again
  2105.  
  2106.     pop    bx                ; restore VS structure
  2107.     jmp    get_mx@                ; get back MX, return
  2108.  
  2109. z_back_ret:
  2110.     ret
  2111.  
  2112. legal_func_list        db    7,8,18,19,20,21,22,23,24
  2113.  
  2114.     end
  2115.