home *** CD-ROM | disk | FTP | other *** search
Text File | 1989-01-26 | 53.9 KB | 2,115 lines |
- ; WINDOWS1.A86
- title 'CONOUT Entry, ESC Handlers'
- pagesize 60+11
- ;****************************************
- ;* *
- ;* CONSOLE OUPUT ENTRY *
- ;* ESCAPE HANDLERS *
- ;* CDOS 6.0 XIOS *
- ;* DRI OS ENGR, JMB, GMS *
- ;* *
- ;****************************************
- ; Mods:
- ; 6.x
- ; 12 JAN 89 -- Use VS_CRT_SEG for VC buffer if Background mode set GMS
- ; 22 Nov 88 -- only reset palletes for ega/vga graphics modes GMS
- ; 25 SEP 88 -- add background video support GMS
- ; 9 SEP 88 -- Use global chan_sel value for MGE GMS
- ; 18 AUG 88 -- Suspend background process if switching mode GMS
- ; 5 JUL 88 -- Ros cursor/mode support IJ
- ; 11 APR 88 -- Added Sun River support GS
- ; 4 FEB 88 -- VS_CUR_TYPE_HW updated in trans_cur_type GS
- ; 11 DEC 87 -- get_set_screen@ re-written GS
- ; 7 DEC 87 -- int10_si etc. replaced with int10_entry GS
- ; 4 DEC 87 -- VS_SCREEN_MODE now uses ROS video mode values GS
- ; 4 DEC 87 -- use ROS int 10h to output chars in graphics mode GS
- ; 2 DEC 87 -- replaced ega$ with redefined video$ GS
- ; 6.0
- ; 18 NOV 87 -- re-enable AST color card code GS
- ; 13 NOV 87 -- get EGA pallette after each mode change GS/JW
- ; 12 NOV 87 -- if VGA mono change ROS mode 3 to mode 7 GMS
- ; 7 NOV 87 -- support ESC ! backdoor via string output JW
- ; -- add int10_si@ entry for int 10's w/ BX = param JW
- ; 3 NOV 87 -- reset pallette reg on mode changes GMS
- ; 5 OCT 87 -- setup larger cursor if EGA monochrome GMS
- ; 15 SEP 87 -- change to console numbers for conout_serial GMS
- ; 21 AUG 87 -- set mode with top bit set for EGA's GMS
- ; 21 AUG 87 -- change to 'screen_set' video mode code for ROS compatibilty GMS
- ; 5.2
- ; 17 JUL 87 -- converted XIOS to small model JW
- ; 26 MAY 87 -- if two graphics processes then suspend new process. GMS
- ; 13 APR 87 -- abort serial terminal process if making ROS call GMS
- ; 7 APR 87 -- Olivetti modes 64 and 72 supported
- ; 11 MAR 87 -- Int 10h mode 7 Hercules - hit the hardware GMS
- ; 2 MAR 87 -- colour pallettes restored for every screen switch on ega GMS
- ; 2 MAR 87 -- Disable blinking attribute in VS_ when entering graphics GMS
- ; and reset when entering alpha modes.
- ; 5.1
- ; 14 JAN 87 -- Set cursor moved bit in VS_ structure for switch routine GMS
- ; 9 JAN 87 -- call national translation for 7bit NX if block i/o GMS
- ; 9 JAN 87 -- Bug fix for setting mode on EGA cards in mono GMS
- ; 14 NOV 86 -- Change cursor off for Amstrad GMS
- ; 16 OCT 86 -- Added support for Amstrad initial attribute GMS
- ; 15 OCT 86 -- ANSI escape sequence handling added GMS
- ; 9 OCT 86 -- Added call to NX_conout_xlat for national keyboards GMS
- ; 17 JUL 86 -- remove graphics mode check for get_set_screen
- ; 3 JUN 86 -- support ros cursor-posn field for top screen app.
- ; 18 APR 86 -- support VS_CUR_TYPE_HW field
- ; 10 APR 86 -- set pallette reg. on io_switch only if they've changed. (EGA
- ; interrupt window in functions B and 10h.)
- ; 8 APR 86 -- support for graphics char out in dev_conout
- ; 31 MAR 86 -- ESC seq./no-wrap bug
- ; 19 FEB 86 -- VS_WIDTH for graphics pgms.
- ; 12 FEB 86 -- fix dev_con_serial BP problem
- ; 7 FEB 86 -- fix dev_conout reentrancy bug
- ; 6 JAN 86 -- set pallette regs on screen switch
- ; 3 JAN 86 -- terminate 2nd process entering a graphics mode
- ; 19 DEC 85 -- set VS_CRT_SEG = A000 if ega gr. modes
- ; 17 DEC 85 -- save the 3rd bit plane if doing enhanced graphics
- ; 4 DEC 85 -- shuffle screen mode routines for EGA
- ; 14 NOV 85 -- fix cursor update on io_switch out of a graph. program
- ; 8 NOV 85 -- add AST "Colorgraphplus" support
- ; 12 SEP 85 -- do not update cursor...done only on tick
- ; 28 AUG 85 -- support Enhanced Graphics Adaptor using EGA ROS for mode set
- ; 19 JUL 85 -- add JW/WD virt. conout speedup
- ; 19 JUL 85 -- add io_devio support (block i/o) in dev_conout@
- ; 13 JUN 85 -- update 4.1 ASM86 code to RASM86
-
- ; include COPYRITE.TXT
-
- nolist
- include CDOS.EQU
- include XIOS.EQU
- include ASCII.EQU
- include PCHW.EQU
- include ROSDATA.EQU
- if SR
- include SR.EQU
- endif
- list
- ; These were included:
- ; include CDOS.EQU
- ; include XIOS.EQU
- ; include ASCII.EQU
- ; include PCHW.EQU
- ; include ROSDATA.EQU
- if SR
- ; include SR.EQU
- endif
-
- CGROUP group CODE
- DGROUP group DATA,w1dseg0,w1dseg1
-
- public io_conout@, con_normal@, dev_conout@
- public proc_abort@
- public ser_abort@, gr_abort@
- public set_screen@, erase_pc@, screen_set_only@
- public ega_pallette@
- public show_cursor@, put_cursor@, in_window@
- public new_cursor_on@, old_cursor_off@
- public z_movsw@, z_up@, z_erase_eos@
- public z_erase_bos@, z_erase@, z_erase_eol@
- public z_erase_bol@, z_erase_line@, z_insert_line@
- public z_delete_line@, z_intense_on@, z_fore1@
- public z_blink_on@, z_rev_on@
- public z_save_cursor@, z_restore_cursor@
- public z_set_color@, z_set_mono@, z_set_mode@
- public vc_out@, vc_out_bs@, vc_out_cr@
- public vc_out_lf@, vc_out_bel@
- public set_mono@, set_color@
- public local_ptr$, ast_flag$
- public ast_enhanced$, ros_color@
- public colsel_640$
- public mode_vector$, oli_vector$ ; for INIT
- public bw_640_400@, bw_640_400_t@
- public alpha_str_80$, compaq_str$, mono_table$
- public save_plane2@, restore_plane2@
-
- eject
-
- cseg
- extrn entry@ :near, supif@ :near ; in HEADER.A86
- extrn flagwait@ :near
- extrn sysdat$ :word
- extrn z_prog_pfk@ :near ; in CONIN.A86
- extrn z_pfk_on@ :near, z_pfk_off@ :near
- extrn z_sl_off@ :near, z_sl_mono@ :near ; in STATLINE.A86
- extrn z_sl_color@ :near, z_sl_both@ :near
- extrn z_clk_on@ :near, z_clk_off@ :near
- extrn z_sl_blank@ :near, sl_error_out@ :near
- extrn conout_serial@ :near, io_devio@ :near ; in LISTAUX.A86
- extrn point_vs@ :near, get_mx@ :near ; in WINDOWS2.A86
- extrn con_scan@ :near, restore_state@ :near
- extrn point_cursor@ :near, check_full@ :near
- extrn update_window@ :near, update_all@ :near
- extrn set_new_mon@ :near, leave_until_char@:near
- extrn put_if_ours@ :near ; in WINDOWS3.A86
- extrn put_crt_s@ :near, put_crt_m@ :near
- extrn put_crt_c@ :near, copy_full_top@ :near
- extrn put_crt_dev@ :near, trans_cur_type@ :near
- extrn int10_entry@ :near ; in ROSIF.A86
- extrn poke_ros_cursor@:near ; in PCVIDEO.A86
- extrn update_vs_cursor_from_ros@: near ; in PCVIDEO.A86
- extrn NX_conout_xlat@:near ; in KEYBOARD.A86
- extrn z_ansi@ :near ; in ANSI.A86
-
- if SR
- extrn test_srterm@ :near, point_pc@:near ; in SRTERM.A86
- endif
-
- dseg
- if SR
- extrn beep_ticks$ :byte
- extrn con_basead$ :word, station_on_off$ :byte ; in SRTERM.A86
- extrn chan_sel$ :byte
- endif
- extrn func_tbl$ :word ; in HEADER.A86
- extrn beep_counter$ :byte, last_curs$ :word ; in ISRS.A86
- extrn sl_crt_flag$ :byte ; in STATLINE.A86
- extrn ccb_tab$ :byte, iattrib$ :byte
- extrn cloneflag$ :byte
- ;extrn palette_reg$ :byte ; in WINDOWS3.A86
- extrn mode_reg$ :byte
- extrn vc_map_seg$ :word, top_screen$ :byte
- extrn graphic_bits$ :byte, mono_bits$ :byte
- extrn color_bits$ :byte, top_screen_mode$:byte
- extrn color_xlat$ :byte, mono_xlat$ :byte
- extrn var_cursor$ :word, var_sync$ :byte
- extrn table_vs$ :word
- extrn fatal_gr_msg$ :byte
- extrn FATAL_GR_MSG_LENGTH:abs
- extrn fatal_ser_msg$ :byte
- extrn FATAL_SER_MSG_LENGTH:abs
- ;if BACKG
- extrn mono_params$ :byte, MONO_PARAMS_LEN$:abs
- ;endif
- extrn bit_plane_seg$ :word, video$ :byte ; in PUBDATA.A86
- extrn NX_natnlmode$ :byte ; in NATDATA.A86
-
- eject
-
- cseg
-
- ;==========
- io_conout@:
- ;==========
- ; XIOS console character out routine:
- ; entry: cl = character
- ; dl = device number
-
- cmp dl,NUM_VIR_CONS
- jae io_conout_ser ; skip if not one of the vc's
-
- conout_vc:
- ;---------
- ; Console output to a virtual console:
-
- ; call point_vs@ ; bx -> virt structure
- ; call get_mx@ ;; lock out other entries
-
- mov bl,dl ; save time...do above inline
- xor bh,bh
- shl bx,1
- mov bx,table_vs$[bx]
- conout_vc1: ; dev_conout entry point
- mov al,0ffh
- xchg al,VS_MX
- test al,al ; save jumps
- jnz do_get_mx ; wait if necessary
-
- get_mx_ok: ;; and return here
- mov al,cl ;; copy character to al
- cmp VS_SCREEN_MODE,04 ; if graphics mode, get out...
- jb get_mx_ok1
- cmp VS_SCREEN_MODE,07
- jne gr_conout
- get_mx_ok1:
- call update_vs_cursor_from_ros@ ; make sure VS_CURSOR in step
- mov dx,VS_CURSOR ;; cursor row, column
- push bx ;; in case of back door stuff
- call VS_VECTOR ;; state machine branch
- ;; to con_norm or con_esc's
- pop bx
- mov ax,VS_CURSOR ;; cursor row, column
- call poke_ros_cursor@
- mov VS_MX,0 ; release for other entries
- ret
-
- do_get_mx:
- call get_mx@ ; jump here if MX owned
- jmps get_mx_ok ;;
-
- io_conout_ser:
-
- if SR
-
- ; BEWARE !!!!!
- ; PCTerm sends in the AUX number in DL (+NUM_VIR_CONS-1), so we will screw
- ; up if this coincides with a Sunriver station. We need a better solution
- ; when we combine SR + PCTerm!
-
- call test_srterm@ ; test if SUN RIVER main console
- jz io_conout_ser1 ; no .. must be dumb terminal
- call point_vs@ ; else get VS_ pointer
- jmps conout_vc1 ;
- io_conout_ser1:
- endif
-
- sub dl,NUM_VIR_CONS-1 ; physical console number 1 relative
- cmp dl,NUM_AUX_PORTS ; if this is too big
- ja conout_no_go ; then skip
- jmp conout_serial@ ; handle aux_ports in listaux.a86
-
- conout_no_go:
- ret
-
- gr_conout:
- ; Use int 10h to write characters in graphics mode.
- ; entry: char in AL
- mov ah,0eh ; TTY write char
- push bx ; save VS_
- mov bl,07h ; attribute
- call int10_entry@ ; output char via ROS
- pop bx
- mov VS_MX,0 ; release for other entries
- ret
- eject
-
- con_control:
- ;-----------
- ; Handle kontrol codes:
-
- mov di,offset norm_scan
- mov cx,NORM_COUNT
- call con_scan@ ; scan for special chars
- jmp norm_table[si]
-
- con_normal@:
- ;----------
- ; Normal console vector state:
- ; entry: cl,al = character
- ; bx = VS_ base
- ; dx = cursor
-
- cmp al,' ' ; non-character?
- jb con_control ; try to avoid jumps
-
- vc_out@:
- ;------
- ; Printable character to virtual console ram image:
- ; entry: bx -> VS_
- ; cl = character
- ; dx = cursor
-
- mov al,cl
- call NX_conout_xlat@ ; xlat char for national 7 bit display
- mov cl,al
- push es
- mov di,VS_OFFSET ; point to screen buffer
- shl di,1
- mov ch,VS_ATTRIB
- test VS_MODE,MATCH_BIT
- jz vc_out0 ; skip if full on top
-
- mov es,VS_VC_SEG ; go to the vc image
- mov es:[di],cx ; store char, attrib
-
- ; Now update screen if character belongs:
-
- mov es,vc_map_seg$ ; for ownership check
- mov ax,VS_OFFSET
- add ax,VS_CORRECT
- xchg ax,si ; save for map check
- call in_window@ ; is char in window?
- jc vc_out1 ; skip if not
-
- mov di,si
- shl di,1 ; back to screen coords
- mov ax,cx ; ax = character + attrib
- call put_if_ours@ ; print it if we own it
- jmps vc_out1
- vc_out0:
- mov ax,cx ; char to ax
- call put_crt_c@ ; go right to physical
- vc_out1:
- pop es
- inc dl ; advance cursor
- cmp dl,VS_WIDTH ; if not wrapping around
- jae vc_out2 ; then do cursor
- mov VS_CUR_COL,dl ; update the cursor address
- mov ax,dx
- call poke_ros_cursor@ ; if top screen
- inc VS_OFFSET ; row/col plus index
- or VS_MODE,UPDATE_BIT ; signal cursor has been moved
- ret
- vc_out2:
- test VS_MODE,WRAP_BIT
- jz vc_out3 ; exit if not wrapping
-
- call vc_out_cr@ ; send CR, LF and update
- jmps vc_out_lf@ ; cursor
- vc_out3:
- ret ; don't touch cursor
-
-
- in_window@:
- ;----------
- ; Is the current row,col in the window?
- ; entry: dx = row,col
- ; bx -> VS_
- ; exit: cf set if outside of window (or on frame)
-
- mov ax,VS_TRUE_VIEW ; updated viewpoint
- cmp dl,al
- jb in_window2 ; skip if left
- cmp dh,ah
- jb in_window2 ; skip if high
- add al,VS_COLSB
- add ah,VS_ROWSB ; past bottom right
- cmp dl,al
- jae in_window1 ; skip if right
- cmp dh,ah ; clc if low
- in_window1:
- cmc
- in_window2:
- ret
- eject
-
- put_cursor@:
- ;-----------
- ; Update and display cursor if appropriate:
-
- call point_cursor@
- mov VS_OFFSET,ax
- put_cursor2:
- mov VS_CURSOR,dx
- or VS_MODE,UPDATE_BIT ; signal cursor has been moved
- ; jmps show_cursor2 ; cursor only updated on tick
- ; ret
- mov ax,dx
- jmp poke_ros_cursor@ ; and ret
-
- show_cursor@:
- ;------------
- ; Display the cursor at its current position:
-
- mov dx,VS_CURSOR ; grab the current pos
- ; jmps show_cursor2 ; and fall through
- ; ret ; only done on tick
-
- show_cursor2:
- mov al,VS_NUMBER ; get our vc number
- cmp al,top_screen$ ; if not top, then skip
- jnz show_cur_ret
- test VS_MODE,CURSOR_BIT ; cursor on?
- jz show_cur_ret ; skip if no
- call in_window@ ; if cursor outside, then
- jnc show_cur_out ; just turn it off
- jmp old_cursor_off@
- show_cur_out:
- ; To save time, the below is done on the tick
- ; mov cx,VS_OFFSET ; CX = byte pointer
- ; add cx,VS_CORRECT ; CX = cursor pointer
- ; mov al,CURSOR_HI ; set cursor code
- ; call video_out@ ; set CRT registers
-
- ; mov cx,VS_CUR_TYPE ; if inside window, turn it on
- ; mov ah,1 ; int 10 function #
- ; jmp int10_bx@
- show_cur_ret:
- ret
- eject
-
- vc_out_cr@:
- ;----------
- ; VC carriage return out:
-
- sub dl,dl ; first column
- jmps put_cursor@ ; update and display
-
- vc_out_lf@:
- ;----------
- ; VC line feed out:
-
- mov al,VS_CRT_ROWS ; get our screen size
- dec al ; al = number of last line
- cmp dh,al ; if at the bottom
- jz vc_lf_scroll ; do a scroll
- inc dh ; if not, move down
- mov VS_CURSOR,dx ; save the cursor value
- mov ax,dx
- call poke_ros_cursor@ ; in ros area too
- add VS_OFFSET,CRT_COLS
- or VS_MODE,UPDATE_BIT ; signal cursor has been moved
- call check_full@ ; if the window is full
- jz vc_lf_show ; then just show cursor
- call update_window@ ; if not full, do an update
- vc_lf_show:
- jmps show_cursor@ ; display current cursor
-
- vc_lf_scroll:
- sub ax,ax ; zero offset from
- mov di,ax ; the top left
- mov si,CRT_COLS*2 ; one row down
- jmp z_line ; delete one line to scroll
-
- vc_out_bs@:
- ;----------
- ; VC back space:
-
- dec dl ; back one column
- jns put_cursor@ ; if not at left
- test VS_MODE,WRAP_BIT
- jz vc_bs1 ; if no wrap, done
- mov dl,VS_WIDTH ; if at left, wrap
- sub dx,0101h ; up one, left one
- jns put_cursor@ ; if not at top
- vc_bs1:
- ret ; if top left, bag it
-
- vc_out_bel@:
- ;-----------
- ; VC beep the bell for top screen only:
- push bx
- mov al,VS_NUMBER ; get our vc number
- cmp al,top_screen$
- jnz vc_bel_done ; skip if not top
- inc beep_counter$ ; otherwise, add a beep
- if SR
- out_bel:
- mov bl,beep_ticks$ ; put in reg.
- cmp bl,00 ; is this the first time through
- jnz check_beep_tick ; no the leap around set up
- set_beep_tick:
- mov bl,0Ch ; set up for a beep
- mov al,BEEP_CMND ; set up the beep frequency
- out TIMER_CMND_REG,al ; send the command
- mov ax,TIMER_1000_HZ ; get the constant
- out TIMER_2_REG,al
- xchg ah,al
- out TIMER_2_REG,al
- check_beep_tick:
- dec bl ; are we all done with this beep
- jz check_more_beeps ; yes then leap
- cmp bl,2 ; where are we in the beep cycle
- jb turn_beep_off ; low enough to turn off
- in al,PORT_B ; else turn on the beeper
- or al,BEEP_ON
- out PORT_B,al
- jmps do_beeps_done
-
- ; Beep handler continued:
- check_more_beeps:
- dec beep_counter$ ; count down the beep
- jnz set_beep_tick ; not the last set a new one
- turn_beep_off:
- in al,PORT_B ; else get the bits
- and al,BEEP_OFF
- out PORT_B,al ; silence the beeper
- mov beep_ticks$,bl ; replace
- jmps vc_bel_done
-
- do_beeps_done:
- mov beep_ticks$,bl ; replace
- mov dx,1 ; delay a tick
- mov cl,P_DELAY
- call supif@
- jmps out_bel
- endif
-
- vc_bel_done:
- pop bx
- ret
-
-
- eject
- vc_out_esc:
- ;----------
- call leave_until_char@ ; comes back here:
-
- ; Console escape sequence branch point:
- ; entry: cl,al = character
- ; bx = VS_base
- ; dx = cursor
-
- call restore_state@ ; VS_VECTOR back to normal
- mov di,offset esc_scan$
- mov cx,ESC_COUNT
- call con_scan@ ; scan for escape chars
- jmp esc_table$[si]
-
-
- w1dseg0 dseg word
- ; ESC sequences and special character support:
-
- norm_table dw vc_out_cr@, vc_out_lf@, vc_out_bs@
- dw vc_out_bel@, vc_out_esc, vc_out@
-
- esc_table$ dw z_up@, z_down, z_forward
- dw z_back, z_erase@, z_home
- dw z_rev_index, z_erase_eos@, z_erase_eol@
- dw z_erase_bos@, z_erase_line@, z_erase_bol@
- dw z_insert_line@, z_delete_line@,z_delete_char
- dw z_set_cursor, z_set_fore, z_set_back
- dw z_cursor_on, z_cursor_off, z_save_cursor@
- dw z_restore_cursor@,z_rev_on@, z_rev_off
- dw z_intense_on@, z_blink_on@, z_blink_off
- dw z_intense_off, z_wrap_on, z_wrap_off
- dw z_set_color@, z_set_mono@, z_video_mode
- dw z_prog_pfk@, z_sl_off@, z_sl_mono@
- dw z_sl_color@, z_sl_both@, z_clk_off@
- dw z_clk_on@, z_pfk_off@, z_pfk_on@
- dw z_back_door, z_norm_attr, z_ansi@
- dw vc_out@
-
- norm_scan db CR,LF,BS,BEL,ESC
- NORM_COUNT equ offset $ - offset norm_scan
-
- esc_scan$ db 'ABCDEH'
- db 'IJKdlo'
- db 'LMNYbc'
- db 'efjkpq'
- db 'rstuvw'
- db 'xya:01'
- db '234567'
- db '!z['
- ESC_COUNT equ offset $ - offset esc_scan$
- eject
-
- cseg
- dev_conout@:
- ;-----------
- ; Block console output (subfunction of XIOS function 39).
- ; Entry: 6[bp] = Param. block
- ; CX = character count
- ; DL = device (console) number
-
- cmp dl,NUM_VIR_CONS ; check for serial console
- jae to_dev_con_serial
- dev_conout_vc:
- call point_vs@ ; point bx at vs_ structure
- cmp VS_SCREEN_MODE,04 ; if graphics mode, get out...
- jb not_gr
- cmp VS_SCREEN_MODE,07
- je not_gr
- jmp dev_gr ; do the graphics out
- not_gr:
- call get_mx@ ; get the semaphore
- ; BP OK through above.
- jcxz to_dev_con_done ; if no characters, leave
- wr_nowr:
- mov dl,VS_WIDTH ; screen width
- mov al,VS_CRT_ROWS ; and height
- test VS_MODE,WRAP_BIT ; is this screen wrapping?
- jnz set_max_char ; jump if yes
- mov al,VS_CUR_ROW ; else max char is right marg.
- inc ax ; for count
- set_max_char:
- mul dl ; AX = max_cols * max_rows
- mov VS_SCRATCH,ax ; save it
-
- dev_con_loop:
- les si,DEV_BUF_BP ; get buffer address
- lods es:al ; get character
- cmp NX_natnlmode$, 3 ; 7 bit, nat scn, nat kbd?
- je dev_con_slow ; slow method for translation
-
- test VS_MODE,ESC_BIT or MATCH_BIT
- jnz dev_con_slow ; window or esc seq --> slow
- cmp al,' '
- jae dev_con_fast ; fast write for non-control
-
- dev_con_slow:
- mov DEV_OFF_BP,si ; update the pointer
- mov cl,al ; put the character in place
- mov dx,VS_CURSOR ; load row and column
- push bp ; save frame ptr
- call VS_VECTOR ; branch through state machine
- pop bp ; restore frame ptr
- dec DEV_CNT_BP ; count one character
- jz to_dev_con_done ; don't repeat if no more
- test VS_MODE,WRAP_BIT ; if no wrap, recalc limit
- jz wr_nowr
- jmps dev_con_loop ; else just loop
- to_dev_con_done:
- jmp dev_con_done ; else string done
- to_dev_con_serial:
- if SR
- call test_srterm@ ; test if SUN RIVER main console
- jz do_dev_serial ; DI = CCB ptr
- cli ; protect ourselves
- cmp C_STATE[di],CSM_BACKGROUND ; background ? o.k.
- je go_dev_conout
- mov es,con_basead$ ; base address of control regs
- mov bl,chan_sel$ ; get selected channel
- xor bh,bh
- test byte ptr station_on_off$[bx],ON ; is station ON
- jnz go_dev_conout ; yes...
- push bp
- push cx
- push dx
- mov cl,DEV_FLAGALLOC
- call supif@ ; get flag number
- pop dx ; restore VS number
- push ax ; save flag number
- call point_pc@
- pop ax
- mov PC_TEMP_FLAG,al ; store flag
- sti
- push dx
- push ax
- mov dl,al ; flag number
- call flagwait@ ; wait for PIN to wake us up
- pop dx ; get flag
- mov cl,DEV_FLAGFREE
- call supif@
- pop dx ; restore input params
- call point_pc@
- mov PC_TEMP_FLAG,00h ; clear flag
- pop cx
- pop bp
- jmp dev_conout_vc
-
- go_dev_conout:
- jmp dev_conout_vc
- do_dev_serial:
- endif
- jmp dev_con_serial ; to avoid jmps
-
- dev_con_fast:
- dec si ; point to 1st non-control byte
- mov di,si ; scan for non-controls
- mov cx,DEV_CNT_BP ; count them all
- mov al,' ' ; compare against this
- dev_con_count:
- scasb ; compare al w/ ES:[DI++]
- ja dev_con_move ; break out if control code
- loop dev_con_count ; else keep checking
- inc di ; pretend trailing control code
- dev_con_move:
- dec di ; backup for overscan
- mov cx,di ; point to control char
- sub cx,si ; CX = # of non-control chars
- dev_con_fast_loop:
- mov ax,VS_SCRATCH ; max to write
- mov di,VS_OFFSET
- sub ax,di ; AX = max chars from cur. pos
- shl di,1 ; DI = word position
- mov dx,cx
- sub dx,ax ; DX <= 0 if block fits
- jbe dev_con_call
- mov cx,ax ; too big..CX = max # chars
- dev_con_call:
- mov ah,VS_ATTRIB ; pick up attribute
- push bp ! push cx ! push dx
- call put_crt_dev@ ; write block to screen
- pop dx ! pop cx ! pop bp
- mov ax,VS_OFFSET
- add ax,cx ; update cursor offset
- test VS_MODE,WRAP_BIT ; check for wrap mode
- jnz dev_check_bottom ; jump if wrapping enabled
- or dx,dx ; did the whole block fit?
- js dev_con_next ; y: go save updated cursor off.
- je dev_no_wrap ; just barely...back cursor up
- add cx,dx ; n: pretend we sent the rest of
- dec cx ; the block EXCEPT the last
- mov dx,1 ; 1 more to output
- dev_no_wrap:
- dec ax ; back up cursor to EOL
- jmps dev_con_next
-
- dev_check_bottom:
- cmp ax,VS_SCRATCH ; need to scroll the screen?
- jne dev_con_next ; jmp if no
- sub al,VS_WIDTH ; cursor back to bot. lft.
- sbb ah,0
- push ax ! push cx ! push dx
- ; push bp ??
- call vc_lf_scroll ; do scroll
- ; pop bp ??
- pop dx ! pop cx ! pop ax
-
- dev_con_next:
- mov VS_OFFSET,ax ; update
- div VS_WIDTH ; AL=AL/VS_WIDTH, AH=AL%VS_WIDTH
- xchg al,ah ; AL = col, AH = row
- mov VS_CURSOR,ax ; save new row, col
- or VS_MODE,UPDATE_BIT ; signal cursor has been moved
- add DEV_OFF_BP,cx ; move the string pointer
- sub DEV_CNT_BP,cx ; decrement the count
- jz dev_con_done ; split if we're done
- mov cx,dx
- or cx,cx ; if CX>0, CX == count left
- jg dev_con_fast_loop ; (we had to scroll or nowrap)
- jmp dev_con_loop ; otherwise, go 'round again
-
- dev_con_done:
- mov VS_MX,0 ; release the MX
- mov ax,VS_CURSOR
- call poke_ros_cursor@ ; will do it if top screen
- jmp show_cursor@ ; this will return for us
-
-
- dev_con_serial:
- sub dl,NUM_VIR_CONS-1 ; physical console number 1 relative
- cmp dl,NUM_AUX_PORTS ; do we have enough ports
- ja dev_cser_done ; leave if we don't
-
- dev_cser_loop:
- push bp ; save frame ptr
- push dx
- les si,DEV_BUF_BP ; point to string
- lods es:al ; get char.
- mov DEV_OFF_BP,si ; bump
- mov cl,al ; put in place
- call conout_serial@ ; send it
- pop dx
- pop bp ; restore frame ptr
- dec DEV_CNT_BP
- jnz dev_cser_loop
-
- dev_cser_done:
- ret
-
-
- dev_gr:
- ;------
- push es
- push si
- dev_gr_lp:
- les si,DEV_BUF_BP
- lods es:al ; get char
- mov DEV_OFF_BP,si ; update
- mov cl,al
- mov dl,byte ptr DEV_TYP_BP ; vc number
- push bp
- call conout_vc1 ; send it
- pop bp
- dec DEV_CNT_BP ; drop count
- jnz dev_gr_lp ; if more, loop
- pop si
- pop es
- ret
- eject
-
- cseg
- ;===========
- set_screen@:
- ;===========
- ; Set Screen mode
- ; entry: dl = vc number
- ; cl = ROS mode
- ; top bit set = no clear on ega's
-
- call point_vs@ ; bx -> VS_
- test video$,EGA+VGA+MCGA ; are we EGA or VGA
- jz set_1
- jmp set_ega ; yes..
- set_1:
- cmp cl,07 ; modes greater than 7
- ja screen_not_sup ; only supported on ega/vga
- set_screen1:
- call set_colorsel ; set the default VS_COLORSEL
- cmp cl,02 ; ROS mode 2 ?
- jne test_mono ; no....
- push ds ; else test if mono video
- mov ax,PC_SEGMENT ; and convert mode select 2
- mov ds,ax ; to mode 7 - ?? ROS does this....
- mov ax,equip_flag_40
- and al,30h ; is it mono
- cmp al,30h
- pop ds
- jne test_mono
- mov cl,07 ; lets change to ROS mode 7
- test_mono:
- cmp VS_SCREEN_MODE,07 ; if we're on the mono monitor
- jne screen_set2 ; then just clear screen
- cmp cl,07
- jne mono_card ; if not ROS mode 7
- screen_set2:
- call screen_set_only@ ; change mode
- test ax,ax ; if set is not successful
- jnz screen_set_ret ; then exit here
- cmp VS_SCREEN_MODE,04
- jb screen_alpha_clear ; alpha mode
- cmp VS_SCREEN_MODE,07
- jne screen_graphics_clear
-
- screen_alpha_clear:
- call alpha_clear
- jmps screen_set_ret
-
- screen_graphics_clear:
- sub dx,dx ; zero "cursor"
- call put_cursor@
- call gra_clear
- screen_set_ret:
- ret
-
-
- mono_card:
- ; If on monochrome, just erase the screen:
- call z_erase@ ; erase the screen
- ; jmps screen_not_sup ; and return false
-
- ; Error returns:
- screen_not_sup:
- mov ax,0FFFFh
- ret
-
-
- ; EGA MCGA or VGA mode set function
- ; bx = vs_
- ; cl = ros mode with top bit valid
- ; --------------------------------
- set_ega:
- and VS_MODE1,not LINE_43_MODE ; mode change always reset 43 line mode
- push cx ; save mode
- mov dl,top_screen$
- cmp dl,VS_NUMBER ; if we're not on top
- je set_ega1 ; then do not go to ROS
- and cl,7fh
- cmp VS_SCREEN_MODE,cl ; if background VC but not changing
- jne suspend_backg ; mode then just clear screen
-
- pop cx
- or VS_MODE1,BLINK_TOGGLE ; enable blinking attr. default
-
- ; we are in background, and so since all modes other than 80x25 text are
- ; suspended in background we must be in modes 2,3, or 7. Since we aren't
- ; changing mode we just need to clear the correct CRT Seg.
- test cl,80h ; clear screen ?
- jnz set_ega_backg2 ; no.. return
- mov di,MONO_SEG ; assume mono
- cmp cl,7 ; is it?
- je set_ega_backg1
- mov di,COLOR_SEG ; no, use colour seg
- set_ega_backg1:
- push es
- push cx
- mov es,di ; clear this seg
- xor di,di ; from the begining
- mov cx,CRT_ROWS_P*CRT_COLS ; erase to bottom corner
- mov al,' ' ; erase to blanks
- mov ah,VS_ATTRIB ; of the current attribute
- cld
- rep stosw
- pop cx
- pop es
- set_ega_backg2:
- ret
-
- suspend_backg:
- call process_suspend ; else SUSPEND process until io_switch
- pop cx
- jmps set_ega
-
- set_ega1:
- or cl,80h ; set no clear bit
- call screen_set_only@ ; setup mode variables
-
- call get_pal ; get pallette settings from ega
- mov ah,03h ; make sure cursor position
- push bx ; is current
- xor bh,bh
- call int10_entry@ ; get from ROS and save in VS_
- pop bx
- mov VS_CURSOR,dx
- pop cx
- or VS_MODE1,BLINK_TOGGLE ; enable blinking attr. default
- cmp VS_SCREEN_MODE,04
- jb set_ega_alpha ; is alpha
- cmp VS_SCREEN_MODE,07
- je set_ega_alpha
- and VS_MODE1,not BLINK_TOGGLE ; enable intensify attr. for graphics
- test cl,80h ; clear screen ?
- jnz set_ega_ret
- call gra_clear ; now clear the screen
- jmps set_ega_ret
-
- set_ega_alpha:
- test cl,80h ; clear screen ?
- jnz set_ega_ret ; no.. return
- call alpha_clear
- set_ega_ret:
- ret
-
- ; clear alpha screen
- alpha_clear:
- push bx
- call z_erase@ ; clear an alpha screen
- pop bx
- mov dh,top_screen$ ; if we're not on top
- cmp dh,VS_NUMBER ; then leave
- jne clear_done
- mov dh,sl_crt_flag$
- call z_sl_blank@ ; and status line too
- clear_done:
- ret
-
- ; clear graphics screen
- gra_clear:
-
- mov cx,2000h ; 8k words
- cmp VS_SCREEN_MODE,0dh
- jb cl2
- mov cx, 32*1024/2
- cmp VS_SCREEN_MODE,11h ; mode 0D, 0E, 0F, 10 (200/350)
- jb cl2 ; clear 32k ega modes
- mov cx, (480*80)/2
- cmp VS_SCREEN_MODE,13h ; modes 11h, 12h (480 lines)
- jb cl2
- mov cx, (320*200)/2 ; mode 13h (200*320*256 color)
- cmp VS_SCREEN_MODE,13h
- je cl2
- mov cx,4000h ; clear 16k words must be olivetti modes
- cl2:
- push es ; now erase the screen
- mov ax,VS_CRT_SEG
- mov es,ax ; point to CRT memory
- sub di,di ; top left corner
- sub ax,ax ; ax = 0 for blackness
- cld
- rep stosw ; blast it
- pop es
- ret
-
-
- ; Get updated pallette values which are reset by
- ; EGA ROS after a mode set.
- get_pal:
- test video$,MCGA ; do nothing if MCGA
- jnz get_pal_ret
- push ds
- push ds ! pop es
- lea di,VS_PALLETTE ; point to vs_ save area
- xor si,si
- mov ds,pal_seg ; ega save area
- mov cx,17
- rep movsb
- pop ds
- get_pal_ret:
- ret
-
- eject
-
-
- screen_set_only@:
- ;----------------
- ; This does both graphics and alpha screen mode settings, but does
- ; not clear the screen or its image if not ega/vga unless
- ; top bit set in ch
- ; This is called from IO_SWITCH , SET_SCREEN and INIT (do_video)...
- ; entry: bx -> vs_
- ; cl = ROS screen mode
- ; ega/vga ros mode (top bit valid)
- mov ch,cl
- and cl,7fh
- cmp cl,02
- jb test_gra ; treat 40 column like graphics
- cmp cl,04
- jb screen_set_go
- cmp cl,07
- je screen_set_go ; not graphics
- test_gra:
- mov al,VS_BIT
- not al ; if anybody else is in
- test graphic_bits$,al ; graphics mode, bag it
- jz test_top
-
- push cx ; save ROS mode
- call gr_abort@ ; suspend running process
- pop cx
- mov cl,ch ; restore cl
- jmps screen_set_only@ ; and try again
-
- test_top:
- mov al,top_screen$ ; if we're not on top
- cmp al,VS_NUMBER ; then bag it
- jmpnz screen_not_sup
-
-
- ; Do the mode change
- screen_set_go:
- test video$, EGA+VGA+MCGA ; ega/vga ?
- jz not_ega
- jmp screen_set_ega
- not_ega:
- xor ah,ah
- mov al,cl ; ROS mode into AL
- mov si,ax
- shl si,1
- cmp al,40h
- je oliv1
- cmp al,48h
- je oliv2 ; special olivetti modes
- jmp word ptr mode_vector[si] ; branch to routine
-
- oliv1:
- mov si,offset oli_vector$
- jmp word ptr [si]
- oliv2:
- mov si,offset oli_vector$
- jmp word ptr 2[si]
-
-
- eject
-
- ; ALPHA - NUMERIC SCREEN MODES:
- ; -----------------------------
-
- black_white_40: ; ROS mode 0
- color_40: ; ROS mode 1
- push ax
- mov al,VS_BIT ; set graphics bit
- or graphic_bits$,al
- pop ax
- mov VS_WIDTH,40
- mov si,offset alpha_str_40 ; 40-col. controller string
- jmps color_alpha_init
-
- mono_80: ; ROS mode 7
- mov si,offset mono_table$ ; b/w text mode params
- jmps color_alpha_init_80
-
- black_white_80: ; ROS mode 2
- color_80: ; ROS mode 3
- mov si,alpha_str_80 ; variable for compaq
- color_alpha_init_80:
- mov VS_WIDTH,80
- push ax
- mov al,VS_BIT ; reset graphics bit
- not al
- and graphic_bits$,al
- pop ax
-
- color_alpha_init:
- mov dl,top_screen$ ; if we're not on top
- cmp dl,VS_NUMBER ; then leave hardware alone
- jne set_exit
- push cx ; save ROS mode
- call color_video_init ; do the controller
- pop cx
-
- mov VS_SCREEN_MODE,cl ; save the new mode
- mov VS_CRT_SEG,COLOR_SEG ; set to color screen
- test video$,MONO
- jnz set_mono
- cmp cl,7 ; ROS mode 7 - monochrome
- jne set_color
- set_mono:
- mov VS_CRT_SEG,MONO_SEG ; here if mono screen
-
- set_color:
- mov top_screen_mode$,cl ; only here if we're top screen
- push bx ; save vs_
- call update_all@ ; restore alpha info
- pop bx ; restore vs_
- sub ax,ax ; return success
- set_exit:
- ret
-
-
- eject
-
- ; GRAPHICS SCREEN MODES:
- ; ----------------------
-
- color_320: ; ROS mode 4
- black_white_320: ; ROS mode 5
- mov VS_WIDTH,40
- jmps color_graph_init
-
-
- black_white_640: ; ROS mode 6
-
- bw_640_400@: ; Olivetti 640x400 ROS mode 40h
- ; 640x400, 8x16 cells
-
- bw_640_400_t@: ; Olivetti 640x400 ROS mode 48h
- ; 640x400, 8x8 cells
- mov VS_WIDTH,80
- color_graph_init:
- mov VS_CRT_SEG,COLOR_SEG ; restore proper seg.
- ; jmps color_graph_init_s
-
- color_graph_init_s:
- mov VS_SCREEN_MODE,cl ; save our new mode
- mov top_screen_mode$,cl ; since we're now top
- mov si,offset graph_str ; graphics video init string
- call color_video_init ; switch into color graph mode
- mov al,VS_BIT ; set graphics bit
- or graphic_bits$,al
-
- do_ast:
- ; AST support:
- if not QXM
- test ast_flag$,0ffh ; make sure it is possibly AST
- jz not_ast
- mov dx,AST_ENHANCED_PORT
- mov al,byte ptr ast_enhanced$ ; toggled by i_keyboard
- out dx,al
- not_ast:
- endif
- sub ax,ax ; successful return
- ret
-
-
- eject
-
- ; EGA AND VGA SCREEN MODES :
- ; --------------------------
- ; entry: bx -> vs_
- ; ch = ROS video mode (with top bit set/reset)
- screen_set_ega:
- push bx ; save vs_
- mov al,ch ; mode to al for int 10h
- xor ah,ah ; set mode function #
- call int10_entry@
- mov ah,0fh ; now we get the mode to
- call int10_entry@ ; see what the ROS made of it
- pop bx ; restore vs_
- and al,7fh ; ROS returns top bit set if no clear
- mov top_screen_mode$,al ; save mode we must be top
- mov VS_SCREEN_MODE,al
- mov VS_WIDTH,ah ; number of columns
- cmp al,04 ; test if graphics mode
- jb ega_alpha
- cmp al,07
- jne ega_graphics
- ega_alpha:
- mov cl,VS_BIT ; reset graphics bit
- not cl
- and graphic_bits$,cl
- cmp al,02 ; 40 column
- jae true_alpha
- mov cl,VS_BIT ; treat like graphics
- or graphic_bits$,cl
- true_alpha:
- mov VS_CRT_SEG,COLOR_SEG ; default
- cmp al,07
- je set_ega_mono
- call z_sl_color@ ; color seg status line
- jmps not_ega_mono
- set_ega_mono:
- mov VS_CRT_SEG,MONO_SEG
- call z_sl_mono@ ; mono seg status line
- not_ega_mono:
- push bx ; save vs_
- call update_all@
- pop bx
- jmps ega_set_ret
-
- ega_graphics:
- mov cl,VS_BIT ; set graphics bits
- or graphic_bits$,cl
- mov VS_CRT_SEG,COLOR_SEG ; default seg
- cmp al,0dh ; ega/vga modes
- jb ega_set_ret
- mov VS_CRT_SEG,EGA_SEG ; yes .. set ega seg
- ega_set_ret:
- call ros_color@
- ret
-
- eject
-
- ; For the CGA or mono. card, hit the ports to initialize the mode.
- ; Entry:
- ; cl,al = ROS video mode
- ; si = video init data string
- color_video_init:
- mov dx,MONO_PORT
- cmp al,7 ; is it monochrome text
- je video_init ; yes
- mov dx,COLOR_PORT
-
- video_init:
-
- mov ch,cl
- push bx ; save vs_
- cmp al,64
- je cga_oli_400 ; treat M24 modes like
- cmp al,72 ; IBM mode 6 (640 x 200)
- jne cga_not_oli
- cga_oli_400:
- mov al,6
- cga_not_oli:
- xor ah,ah
- mov bx,ax ; get ROS mode
- shl bx,1 ; word index
- mov ax,mode_color_tbl[bx] ; get mode and color-select
- pop bx ; restore vs_
-
- push ax ; save mode/color
- add dx,4
- and al,3fh ; video off
- out dx,al
- sub dx,4
-
- push cx
- mov cx,16 ; CRTC parameters
- sub ah,ah ; init. port index
- vi_lp:
- mov al,ah
- out dx,al ; port index setup
- inc dx ; to data port
- lodsb ; get data byte
- out dx,al ; send it
- dec dx ; back to addr. port
- inc ah ; next addr. index
- loop vi_lp
- pop cx
- cmp cloneflag$,IS_M24
- jne not_olivetti
-
- ; set mode register #2 for olivetti modes
- add dx,6
- in al,dx ; input status
- and al,010h ; isolate color bit
- shl al,1
- shl al,1
-
- cmp ch,40h ; is it graphics modes 64/72
- jb md_dbl
- inc ax ; yes.. set double scan
- md_dbl:
- add dx,4 ; mode control register 2
- out dx,al
- sub dx,10 ; reset to base
-
- not_olivetti:
- pop ax ; restore mode/color
- add dx,4 ; get to mode-select reg.
- out dx,al
- mov mode_reg$,al ; save it
- mov ah,al
- inc dx
-
- mov al,VS_COLORSEL ; get overscan
- out dx,al ; set overscan
- push ds
- mov dx,PC_SEGMENT
- mov ds,dx
- mov crt_mode_set_40,ah
- mov crt_pallette_40,al
- mov crt_mode_40,ch
- pop ds
-
- ret
-
-
-
- ros_color@:
- ; Set colorsel reg based on VS_COLORSEL in screen structure:
- ; Only used for CGA
- ; Entry: bx = vs_
-
- push bx ; save vs_
- mov bl,VS_COLORSEL
- cmp bl,last_pall ; don't do it if we don't need
- je rc_done ; to...there's a large window
- mov last_pall,bl ; in the EGA ROS where ints
- ; are disabled.
- sub bh,bh
- push bx
-
- and bl,1Fh ; set low 5
- mov ah,11 ; set color
- call int10_entry@
-
- pop bx
- test bl,20h
- jz not_20
- mov bx,0101h
- jmps set_bit_5
- not_20:
- mov bx,0100h
- set_bit_5:
- mov ah,11
- call int10_entry@
- rc_done:
- pop bx ; restore vs_
-
- sub ax,ax ; successful return
- ret
-
-
- ; Entry: CL = ROS mode
- ; BX = vs_
- ; Exit: VS_COLORSEL contains proper value per int 10h, func. 11d
- ; to set the color select ("palette") register.
- ; This is the equivalent on the CGA of 0 - 3Fh, which is
- ; sent to the color-select register.
- set_colorsel:
-
- mov al,30h ; for all modes but 640
- cmp cl,40h ; olivetti mode 64
- je set_col
- cmp cl,48h ; olivetti mode 72
- je set_col
- cmp cl,06 ; 640 graphics, because...
- jne not_640_
- set_col:
- mov al,byte ptr colsel_640$ ; because that's the
- not_640_: ; only different one
- cmp al,VS_COLORSEL
- ; je set_col1
- mov VS_COLORSEL,al
- ; push ds
- ; mov dx,PC_SEGMENT
- ; mov ds,dx
- ; mov dx,addr_6845_40
- ; add dx,5
- ; out dx,al ; output color selection
- ; mov crt_pallette_40,al ; and save in ROS
- ; pop ds
-
- set_col1:
- ret
-
- ; Reset the appropriate palette registers:
- ; Entry : BX = VS->
- ega_pallette@:
- test video$,VGA ; VGA (mono or color)
- jnz ega_pal
- test video$,EGA ; ega
- jz pal_ret ; no, so skip
- test video$,COLOR ; ega color
- jz pal_ret ; no skip it
- ega_pal:
- cmp VS_SCREEN_MODE,6
- jbe pal_ret
- lea dx,VS_PALLETTE
- mov si,dx
- mov byte ptr 10h[si],0 ; clear overscan value - fix bug in
- ; compaq ega ROS
- push es
- push ds ! pop es
- mov ax,1002h ; set all pallette regs + overscan
- call int10_entry@ ; visit ROS (regs preserved)
- pop es
- pal_ret:
- ret
-
-
- save_plane2@:
- ;------------
- ; When switching to an alpha mode on the ega, the ROS writes the character
- ; generator data to bit plane 2. We need to save this space if we're in an
- ;(advanced graphics mode which is using it as a color plane.
-
- ; Set the memory read mode to 0, which means the actual byte in the map
- ; rather than a color compare:
- mov dx,EGA_G12_ADDR
- mov ax,G12_MODE*256 + 0
- call index_out
-
- ; Set the read-map selector for only bit plane 2:
- mov ax,G12_READ_MAP_SLCT * 256 + 2
- call index_out
-
- ; Store 8K bytes:
- mov ax,EGA_SEG ; source
- mov cx,bit_plane_seg$ ; dest
- call move_ega_bytes
-
- ; Now set the read-map selector back to our best guess as to what most
- ; applications will have it set to most of the time:
- mov ax,G12_READ_MAP_SLCT * 256 + 0
- jmps index_out ; and return
- eject
-
- restore_plane2@:
- ;---------------
- ; After getting the video hardware to switch modes back into one of the
- ; enhanced graphics modes on the EGA, restore the data which was saved
- ; before the last switch:
-
- ; This code needs to :
- ; 1. set write mode 0;
- ; 2. enable all bits w/ the bit mask reg;
- ; 3. disable set/reset for all planes;
- ; 4. set rotate register to 0;
- ; 5. set sequencer map mask reg. to disable all planes exc. 2.
- ; Since we've just come back from ROS on a mode set, we can depend on
- ; all of them to be the way we want them except 5. Ergo:
-
- mov dx,EGA_SEQ_ADDR
- mov ax,SEQ_MAP_MASK * 256 + 0100b
- call index_out
-
- ; Now replace the stored bytes in the bit map:
- mov ax,bit_plane_seg ; source
- mov cx,EGA_SEG ; destination
- call move_ega_bytes
-
- ; Restore the sequencer reg:
- mov ax,SEQ_MAP_MASK * 256 + 1111b
- jmps index_out ; and ret
-
- index_out:
- ; Entry: dx = address port, dx+1 = data port
- ; ah = data register index
- ; al = data
-
- xchg ah,al
- out dx,al
- xchg ah,al
- inc dx
- out dx,al
- dec dx
- ret
-
-
- move_ega_bytes:
- ; Entry: ax = source segment
- ; cx = dest. segment
-
- push ds
- push es
- mov es,cx ; dest.
- mov ds,ax ; source
- sub si,si
- mov di,si
- mov cx,PLANE2_LENGTH/2 ; by words
- cld
- rep movsw
- pop es
- pop ds
- ret
-
-
-
- ; Entry to abort process on serial terminal if making ROS calls.
- ser_abort@:
- mov ax,offset fatal_ser_msg$
- mov cx,FATAL_SER_MSG_LENGTH ; msg length.
- jmps proc_abort@ ; fall through
-
- gr_abort@:
- ; Here if somebody else is in a graphics mode. Print message and
- ; suspend the process - wake up at io_switch:
- ; Enter BX -> VS_
- mov ax,offset fatal_gr_msg$
- mov cx,FATAL_GR_MSG_LENGTH ; msg length.
- push bx
- call disp_msg ; display message
- pop bx
- ; jmps suspend_process ; fall through
-
- ; Suspend Process on Flagwait until screen switch
- ; Enter BX = VS_
- process_suspend:
- push bx ; save VS_
- mov cl,DEV_FLAGALLOC
- call supif@ ; get flag number
- pop bx
- mov VS_CONMODE,al ; store flag
- gr_abort1:
- push bx
- mov dl,VS_CONMODE ; flag number
- call flagwait@ ; wait io_switch to wake us up
- pop bx
- mov al,VS_BIT
- not al ; if anybody else is in
- test graphic_bits$,al ; graphics suspend again
- jnz gr_abort1
- push bx
- xor dl,dl
- xchg dl,VS_CONMODE ; get flag and free it
- mov cl,DEV_FLAGFREE
- call supif@
- pop bx
- ret
-
-
- proc_abort@:
- ; public entry to abort a running process.
- ; Entry: ax = offset in SYSDAT of message to print
- ; cx = length of message, or 0 if none
-
- call disp_msg
- mov bx,rlr$
- and P_FLAG[bx],not (PF_KEEP + PF_TEMPKEEP)
- mov cx,P_TERM
- mov dx,0ffffh
- jmp supif@
- ; Process is terminated.
-
- disp_msg:
- jcxz no_msg
-
- mov bx,rlr$
- mov dl,P_CONS[bx] ; get console num.
- mov dh,0 ; console dev. type
-
- push dx ; setup param. block
- push cx
- push ds ; segment
- push ax ; offset
-
- sub sp,4 ; adjust
- ; call io_devio@
-
- mov bx,39*2 ; DEVIO
- call cs:func_tbl$[bx] ; call function
- add sp,12 ; back to normal
- no_msg:
- ret
-
-
-
- eject
-
- w1dseg1 dseg word
-
- mode_vector$ dw black_white_40, color_40 ; 0-1
- dw black_white_80, color_80 ; 2-3
- dw color_320, black_white_320 ; 4-5
- dw black_white_640, mono_80 ; 6-7
- ; dw screen_not_sup, screen_not_sup ; 8-9 not used
- ; dw screen_not_sup, screen_not_sup ; 0ah-0bh not used
- ; dw screen_not_sup ; 0ch not used
- ; dw screen_not_sup, screen_not_sup ; 0dh-0eh ega not used
- ; dw screen_not_sup, screen_not_sup ; 0fh-10h ega not used
- ; dw screen_not_sup ; 11h used for MCGA only
- ; dw screen_not_sup ; 12h vga - not used
- ; dw screen_not_sup ; 13h used for MCGA only
-
- oli_vector$ dw screen_not_sup, screen_not_sup ; olivetti modes
-
-
- ; The additional graphics modes for ega/vga have their vectors established
- ; by INIT if the EGA/VGA is present.
-
- ; 6845 video controller config. data tables, used by get_set_screen:
-
- graph_str db 38h,28h,2Dh,0Ah,7Fh,06h,64h,70h,02h,01h,06h,07h,0,0,0,0
- mono_table$ db 61h,50h,52h,0fh,19h,06h,19h,19h,02h,0dh,2bh,0ch,0,0,0,0
-
- alpha_str_40 db 38h,28h,2Dh,0ah,1fh,06h,19h,1ch,02h,07h,26h,07h,0,0,0,0
-
- alpha_str_80 dw ibm_str
- ibm_str db 71h,50h,5Ah,0ah,1fh,06h,19h,1ch,02h,07h,26h,07h,0,0,0,0
- compaq_str$ db 71h,50h,5ah,0ah,19h,06h,19h,19h,02h,0dh,2bh,0ch,0,0,0,0
-
- ; Mode-select and color-select values indexed by ROS mode number:
- mode_color_tbl dw 002Ch, 0028h, 002Dh, 0029h
- dw 200Ah, 200Eh, 071Eh, 0029h ; #7 for mono adapt.
-
- ; AST "Colorgraphplus" enhancement toggle:
- ast_enhanced$ rw 0
- db AST_ENHANCED_ON ; default
- db AST_ENHANCED_OFF ; if user hits cntl-pad-5
-
- colsel_640$ rw 0
- db 3Fh ; default for colsel register
- db 10h ; for AST hi res
-
- ast_flag$ db 0 ; test for AST color card
- local_ptr$ rw 3 ; ega save pointer data area
- pal_seg rw 1
- rw 12
-
-
- last_pall db 0
-
- eject
-
- cseg
-
- ; *** VC ESCAPE CHARACTER RECEIVED ***
- ; *** CONSOLE ESCAPE ROUTINES FOLLOW: ***
-
- z_up@:
- ; ESC A - cursor up:
- dec dh ; next row up
- jns z_cursor ; if not already on top,
- ret ; then set cursor
-
- z_down:
- ; ESC B - cursor down:
- inc dh ; next row down
- cmp dh,VS_CRT_ROWS ; if not already at bottom,
- jb z_cursor ; then set cursor
- ret
-
- z_forward:
- ; ESC C - cursor forward:
- inc dl ; next column right
- cmp dl,CRT_COLS ; if not already at right,
- jb z_cursor ; then set cursor
- ret
-
- z_back:
- ; ESC D - cursor backward:
- dec dl ; next column left
- jns z_cursor ; if not already at left,
- ret ; then set cursor
-
- z_erase@:
- ; ESC E - erase console:
- call z_home ; get to top left
- sub dx,dx ; top left
- jmps z_erase_eos@ ; erase to end
-
- z_home:
- ; ESC H - home cursor:
- sub dx,dx ; 0,0 = top left corner
- ; jmps z_cursor
-
- z_cursor:
- jmp put_cursor@ ; save and display if visible
-
- z_rev_index:
- ; ESC I - reverse index:
- test dh,dh ; if not on the top row,
- jnz z_up@ ; then just move up
- jmp z_insert_line@ ; else scroll down from top
-
- z_erase_eos@:
- ; ESC J - erase to end of screen:
- mov ch,VS_CRT_ROWS ; erase to bottom corner
- sub cl,cl
- jmps eraser ; common code
-
- z_erase_eol@:
- ; ESC K - erase to end of line:
- mov ch,dh ; this row
- inc ch ; to the next row,
- sub cl,cl ; first column
- jmps eraser ; common code
-
- z_insert_line@:
- ; ESC L - insert a BLANK line:
- mov al,CRT_COLS
- mul VS_CRT_ROWS ; ax = crt size
- dec ax
- mov di,ax
- sub ax,CRT_COLS
- mov si,ax
- shl di,1 ; end of screen
- shl si,1 ; one line up
-
- sub dl,dl ; first column
- mov al,VS_WIDTH ; do point_cursor w/out disturbing di
- mul dh ; AX = count from top
- std ; backwards move
- jmps z_ins_del_line ; shared code
-
-
- z_erase_bos@:
- ; ESC d - erase from beginning of screen:
- mov cx,dx ; current location
- sub dx,dx ; top left corner start
- jmps eraser
-
- z_erase_line@:
- ; ESC l - erase entire line:
- sub dl,dl ; from first column
- mov cx,dx ; to the first column
- inc ch ; of the next row
- jmps eraser
-
- z_erase_bol@:
- ; ESC o - erase from beginning of line:
- mov cx,dx ; erase to cursor
- sub dl,dl ; from first column
- ; jmps eraser
- eject
-
- eraser:
- ; Common erase routine:
- ; entry: dx = start of erase row,column
- ; cx = one past ending row,column
-
- xchg cx,dx ; dx = one past the end
- call point_cursor@ ; ax = end pointer
- xchg cx,dx ; dx = start cursor
- xchg ax,cx ; cx = end pointer
- call point_cursor@ ; ax = start pointer
- sub cx,ax ; cx = erase char count
- jnz erase ; skip if something to erase
- ret ; return if nothing
- erase:
- mov al,' ' ; erase to blanks
- mov ah,VS_ATTRIB ; of the current attribute
- ; jmps erase_pc@
-
-
- erase_pc@:
- ; This is an entry used by the pc mode emulator:
-
- test VS_MODE,MATCH_BIT
- jz erase1 ; skip if full on top
-
- push es
- mov es,VS_VC_SEG ; base of vc image
- rep stosw ; BLANK a bunch
- pop es
- cld ; in case df was set
- jmp update_window@ ; and show it
- erase1:
- jmp put_crt_s@ ; if full top, go to physical
- eject
-
- z_delete_line@:
- ; ESC M - delete one line:
- sub dl,dl
- call point_cursor@ ; di -> line start
- mov si,di
- add si,CRT_COLS*2 ; next row down
- z_ins_del_line:
- push ax
- mov ax,dx
- call poke_ros_cursor@
- pop ax
- xchg VS_CURSOR,dx
- xor dh,dh
- sub VS_OFFSET,dx ; cursor moves to 1st col.
- or VS_MODE,UPDATE_BIT ; signal cursor has been moved
- ; jmps z_line
-
- z_line:
- ; External entry point:
- ; entry: si,di set up for movsw
- ; ax = count from top of screen
- xchg cx,ax ; cx = count
- mov al,CRT_COLS
- mul VS_CRT_ROWS ; ax = crt size
- sub ax,CRT_COLS
- xchg ax,cx
- sub cx,ax ; cx = character count
- jbe z_line1 ; skip if nothing to move
-
- call z_movsw@ ; movsw in vc_segment
- z_line1:
- mov cx,CRT_COLS ; one line's worth
- call erase ; blank one line
- cld ; clear dir. flag (insert)
- jmp show_cursor@
-
-
- z_movsw@:
- ; repeat movsw in current screen segment:
- push es
- push ds ; save around the move
- sub ah,ah ; assume no sync
- mov es,VS_VC_SEG
- test VS_MODE,MATCH_BIT
- jnz z_movsw1 ; skip if not full top
- mov ah,IN_SYNC + OUT_SYNC
- mov es,VS_CRT_SEG ; else move physical
- z_movsw1:
- push es
- pop ds ; move within the seg
- call put_crt_m@ ; like a movsw with sync
- pop ds
- pop es
- ret
- eject
-
- z_delete_char:
- ; ESC N - delete one character:
- mov di,VS_OFFSET
- shl di,1 ; DI -> current char
-
- mov cx,CRT_COLS-1 ; last column
- sub cl,dl ; cx = chars to line end
- jz z_del_ch1 ; skip if at line end
- mov si,di
- inc si ; next char right
- inc si
- call z_movsw@ ; shift left one char
- z_del_ch1:
- mov cx,1 ; erase one last char
- jmp erase
-
- z_set_cursor:
- ; ESC Y - set cursor position:
- call leave_until_char@
- sub cl,' ' ; correct for space offset
- js z_set_col ; if illegal, skip row set
- cmp cl,VS_CRT_ROWS ; check upper bound
- jae z_set_col ; 25 :== 0 through 24 ok
- mov VS_CUR_ROW,cl ; save the row
- z_set_col:
- call leave_until_char@
- sub cl,' ' ; correct for space offset
- js z_set_done ; if illegal, skip col set
- cmp cl,CRT_COLS ; check upper bound
- jae z_set_done ; 80 :== 0 through 79 ok
- mov dl,cl ; dx = new cursor location
- z_set_done:
- call restore_state@ ; back to normal
- ; mov ax,VS_CURSOR ;
- ; call poke_ros_cursor@ ; done below
- jmp put_cursor@ ; update and display new curs.
-
- z_set_fore:
- ; ESC b - set foreground color:
- call leave_until_char@
- z_fore1@: ;ANSI entry point
- mov ah,VS_ATTRIB ; current attribute
- jmps z_fg_bg ; shared code
-
- z_set_back:
- ; ESC c - set background color:
- call leave_until_char@
- mov ah,al ; ah = bg bits
- mov cl,4
- rol ah,cl ; bg bits to ms nibble
- mov al,VS_ATTRIB
- z_fg_bg:
- and al,0fh ; take the 4 lsb's of al
- and ah,0f0h ; and the 4 msb's of ah
- or al,ah ; and mash 'em together
- mov VS_ATTRIB,al ; that's the new attribute
- jmp restore_state@ ; back to normal
- eject
-
- new_cursor_on@:
- ; Entry used by switch to restore cursor:
- test VS_MODE,CURSOR_BIT
- jz z_cursor_off ; skip if cursor off
- ; jmps z_cursor_on ; else turn it on
-
-
- z_cursor_on:
- ; ESC e - enable cursor:
- mov last_curs$,0ffffh ; force update next tick
- or VS_MODE,CURSOR_BIT
- mov cx,VS_CUR_TYPE ; monochrome or color
- mov ah,1 ; int 10 function #
- call int10_entry@
- jmp show_cursor@ ; and return
-
- z_cursor_off:
- ; ESC f - disable cursor:
- and VS_MODE,not CURSOR_BIT
- old_cursor_off@: ; external entry
- mov cx,1f1fh ; HIDE cursor (even on Amstrad)
- cmp cloneflag$,IS_AMSTRAD
- je z_cur1
- mov cx,VS_CUR_TYPE ; monochrome or color
- or ch,20h ; disable bit
- z_cur1:
- mov ah,1 ; int 10 function #
- jmp int10_entry@
-
- z_save_cursor@:
- ; ESC j - save cursor position:
- mov VS_SAVE_CURSOR,dx
- ret ; save for later
-
- z_restore_cursor@:
- ; ESC k - restore cursor position:
- mov dx,VS_SAVE_CURSOR
- jmp put_cursor@ ; back where it was
- eject
-
- z_rev_on@:
- ; ESC p - reverse video on:
- test VS_MODE,REV_BIT ; if already reversed
- jnz z_rev2 ; then forget it
- or VS_MODE,REV_BIT ; remember
- jmps z_rev1 ; to common code
-
- z_rev_off:
- ; ESC q - reverse video off:
- test VS_MODE,REV_BIT ; if already off
- jz z_rev2 ; then forget it
- and VS_MODE,not REV_BIT
- z_rev1: ; shared code
- mov al,VS_ATTRIB ; get current colors
- mov ah,al ; copy for msb's
- and ax,8877h ; mask colors only
- mov cl,4
- rol al,cl ; swap colors
- or al,ah ; restore intense, blink
- mov VS_ATTRIB,al ; new attribute
- z_rev2:
- ret
-
- z_intense_on@:
- ; ESC r - intensity on:
- or VS_ATTRIB,08h ; set the intense bit
- ret
-
- z_intense_off:
- ; ESC u - intensity off:
- and VS_ATTRIB,0f7h ; reset the intense bit
- ret
-
- z_blink_on@:
- ; ESC s - blink on:
- or VS_ATTRIB,80h ; set the blink bit
- ret
-
- z_blink_off:
- ; ESC t - blink off:
- and VS_ATTRIB,7fh ; reset the blink bit
- ret
- eject
-
- z_wrap_on:
- ; ESC v - wrap at line end on:
- or VS_MODE,WRAP_BIT
- ret
-
- z_wrap_off:
- ; ESC w - no wrap at line end:
- and VS_MODE,not WRAP_BIT
- z_return:
- ret
-
- z_set_color@:
- ; ESC x - switch console to color monitor:
-
- test video$,COLOR ; if no color card
- jz z_return ; then do nothing
- ; cmp top_screen_mode$,05h
- cmp graphic_bits$,0 ; set mode instead?
- jnz z_return ; skip if top's not alpha 80
-
- call copy_full_top@ ; if full on top, copy back
- call old_cursor_off@
- call set_color@ ; update VS_ variables
- jmp set_new_mon@ ; redo all windows
-
-
- z_set_mono@:
- ; ESC y - switch console to monochrome monitor:
-
- test video$,MONO ; if no monochrome card
- jz z_return ; then do nothing
- test graphic_bits$,0ffh
- jnz z_return ; skip if anybody's graphic
-
- call copy_full_top@ ; if full on top, copy back
- call old_cursor_off@
- call set_mono@ ; update VS_ variables
- jmp set_new_mon@ ; redo all windows
-
-
- z_norm_attr:
- ; ESC z - restore normal attributes:
-
- mov ah,iattrib$ ; get initial attribute
- mov VS_ATTRIB,ah ; save as current
- and VS_MODE,0FFh-04 ; not reverse video
- or VS_MODE,03h ; wrap and cursor
- jmp z_cursor_on ; display cursor
- eject
-
- set_color@:
- ; Set VS_ variables to color monitor:
- if SR
- cmp VS_NUMBER,NUM_VIR_CONS
- jae is_sr ; VS_XLAT set up in SRTERM
- endif
- mov VS_XLAT,offset color_xlat$
- is_sr:
- mov VS_CRT_SEG,COLOR_SEG
- mov cx,var_cursor$ ; different for compaq
- mov VS_CUR_TYPE,cx
- call trans_cur_type@
- mov al,var_sync$ ; different for COMPAQ, EGA
- or VS_MODE,al
- mov al,VS_BIT
- or color_bits$,al ; add to color vc's
- not al ; and subtract from mono's
- and mono_bits$,al
- mov VS_SCREEN_MODE,03 ; 80x25 color mode
- ret
-
- set_mono@:
- ; Set VS_ variables to monochrome monitor:
- ;if BACKG
- cld
- mov cx,MONO_PARAMS_LEN$
- lea di,VS_CRT_DATA
- mov si,offset mono_params$
- push ds ! pop es
- rep movsb
- ;endif
- mov VS_CRT_SEG,MONO_SEG
- mov VS_XLAT,offset mono_xlat$
- mov cx,MONO_CURSOR
- mov VS_CUR_TYPE,cx
- call trans_cur_type@ ; update VS_CUR_TYPE_HW
- and VS_MODE,not SYNC_BIT ; no retrace wait required
- mov al,VS_BIT
- or mono_bits$,al ; add to mono vc's
- not al ; and remove from color's
- and color_bits$,al
- mov VS_SCREEN_MODE,07 ; 80x25 monochrome mode
- ret
-
-
- z_video_mode:
- ; ESC a - set color graphics card video mode:
-
- call leave_until_char@
- call restore_state@ ; back to con_normal
- z_set_mode@:
- and al,07h ; allow only mode 0-7
- cbw
- mov si,ax ; table index
- mov cl,screen_table[si]
- mov dl,VS_NUMBER ; vc number
- jmp set_screen@ ; just like a back door
-
- screen_table db 00h,00h,02h,03h
- db 04h,05h,06h,00h
- eject
-
- z_back_door:
- ; ESC ! - general XIOS back door entry:
-
- mov VS_BACK_COUNT,0 ; register counter
- call leave_until_char@
- mov al,VS_BACK_COUNT
- cbw ; ax -> which register
- lea di,VS_BACK_AX
- mov si,di ; save for loading
- add di,ax ; point to register
- mov [di],cl ; save register value
- inc ax ; next reg
- mov VS_BACK_COUNT,al
- cmp al,8 ; max 8 bit register
- jb z_back_ret ; stay here for 8
-
- ; Ready to go for it:
- call restore_state@ ; reset conout vector
- push es
- push cs ! pop es ; local es for scan
- mov di,offset legal_func_list
- mov cx,length legal_func_list
- lodsw ; fetch ax (al=func #)
- repnz scasb ; check for legal call
- pop es
- jnz z_back_ret ; if illegal, return
-
- ; A legal function number has been given:
- mov VS_MX,0 ; allow entry
- push bx ; save VS structure
-
- xchg ax,dx ; dx saves ax call value
- lodsw ! xchg ax,bx ; bx call value
- lodsw ! xchg ax,cx ; cx call value
- lodsw ! xchg ax,dx ; dx and ax call value
-
- push cs ; allow for RETF in entry@
- call entry@ ; call XIOS entry again
-
- pop bx ; restore VS structure
- jmp get_mx@ ; get back MX, return
-
- z_back_ret:
- ret
-
- legal_func_list db 7,8,18,19,20,21,22,23,24
-
- end
-