		.286c
.xlist
		include	biosdata.asm
.list

;*********************************************************************
;
;               V I D I O   I / O
;
;        
;       These routines provide the video interfice for the Slicer
;       using the the Slicer video board, and are accesed using
;       INT 10H.  Modes 0, 1, 2, 3, 4, 5, and 6  reequire an IBM comptable
;       color graphics board.  The functions provided are:
;
;       AH = 0:   Set video mode in AL
;            AL = 0: 40x25 b&w text
;            AL = 1: 40x25 color text
;            AL = 2: 80x25 b&w text
;            AL = 3: 80x25 color text
;            Graphics modes
;            AL = 4: 320x200 color
;            AL = 5: 320x200 b&w
;            AL = 6: 640x200 b&w 
;            Modes on Slicer pc board
;            AL = 7: 80x25 text
;            AL = 80:640x200 b&w
;	     
;      AH = 1:   Set cursor type
;           CH = Starting line of cursor (bits 0 - 4)
;           CL = Lase line of cursor (bits 0 - 4)
;
;      AH = 2:   Set cursor position
;           DH = Row (0 is the top row)
;           DL = Column (0 is the leftmost)
;           BH = Page number
;
;      AH = 3:   Read cusor position
;           BH = Page number
;           Returns:
;              DH = Row
;              DL = Column
;              CH = Starting line
;              CL = End line
;
;      AH = 4:   Nop
;
;      AH = 5:   Select active display page
;           AL = New page
;
;      AH = 6:   Scroll active page up
;           AL = Number of lines to scroll (0 = Blank entire window)
;           CH, CL = Upper left corner of window
;           DH, DL = Lower right corner of window
;           BH = Attribute of blanked lines
;
;      AH = 7:   Scroll active page down
;           AL = Number of lines to scroll (0 = Blank entire window)
;           CH, CL = Upper left corner of window
;           DH, DL = Lower right corner of window
;           BH = Attribute of blanked lines
;
;      
;       AH = 8:   Read charecter and attribute at cursor
;            BH = Page
;            Returns:
;                 AH = Attrribute
;                 AL = Charecter
;
;       AH = 9:   Write charecter and attribute to cursor
;            BH = Page
;            BL = Attribute
;            AL = Charecter
;            CX = Number of charecters to write
;
;       AH = A:   Write charecter to cursor
;            BH = Page
;            AL = Charecter
;            CX = Number of charecters to write
;
;       AH = B:   Set color palette
;            BH = Pallette id
;               0 = Background
;               1 = Pallette
;            BL = Valus
;
;       AH = C:   Write dot.
;            DX = Row
;            CX = Column
;            AL = Color
;
;       AH = D:   Read dot.
;            AL = Dot read
;
;       AH = E:   Write teletype to current page
;            AL = Charecter to write
;            BL = Forground color in graphics mode
;
;       AH = F:   Return current video state
;            Returns:
;               AL = Mode
;               AH = Number of columns on screen
;               BH = Active page
;---------------------------------------------------------------------
;
;       AH = 80:  Fill window with charecter and attribute
;            AL = Charecter
;            BL = Attribute
;            CH = Upper row
;            CL = Left column
;            DH = Lower row
;            DL = Right column
;
;
;	AH = FB:  Turn on TTY Extended
;	AH = FC:  Turn off TTY Extended
;       AH = FD:  Write TTY Extended
;	AH = FE:  Get video buffer ( returns for now )
;	AH = FF:  Set video buffer ( returns for now )
;
;*********************************************************************
		public	new_video,video_init,set_mode,get_mode,set_page

b		equ	byte ptr
w		equ	word ptr
uart_base	equ	80h
uart_input	equ	uart_base+1ah
use_video	equ	20h

bw_base		equ	03b4h
_data		equ	01h
_control	equ	04h
_status		equ	06h
color_base	equ	03d4h
_color		equ	05h
;
b_space		equ	8
c_return	equ	0dh
l_feed		equ	0ah
bell		equ	7
color_card	equ	2
herc		equ	1
;
;
		
xxx		struc
temp1		dw	?
pointer1	dw	?
pointer2	dw	?
rdi		dw	?
rsi		dw	?
rbp		dw	?
rsp		dw	?
rbx		dw	?
rdx		dw	?
rcx		dw	?
rax		dw	? 
xxx		ends
size_temp_data	equ	rdi		;used to alocate temporary data space
;
;
;

cgroup		group	code

code		segment	public byte 'code'
		assume	cs:cgroup,es:vectors,ds:data
		include	tables.asm

;			     CHANGED 9-5-86 JONATHAN FOR TESTING HURCULESS CARD
card_index	db	1,1,1,1,1,1,1,0		;video board used in each mode
						;1=color card, 0=bw board
param_index	db	0,0,1,1,2,2,2,3		;index into parameter table
						;for each mode
color_reg	db	0h,0h,0h,0h,0h,0h,03fh
control_reg	db	02ch,028h,02dh,029h,02ah,02eh,01eh,029h
columns		db	40,40,80,80,40,40,80,80
p_size		dw	2048,2048,4096,4096,16384,16384,16384,4096

parameters	db	038h,028h,02dh,00ah,01fh,006h,019h
		db	01ch,002h,007h,006h,007h
		db	0,0,0,0
params_len	equ	this byte-parameters

		db	071h,050h,05ah,00ah,01fh,006h,019h
		db	01ch,002h,007h,006h,007h
		db	0,0,0,0

;
		db	038h,028h,02dh,00ah,07fh,006h,064h
		db	070h,002h,001h,006h,007h
		db	0,0,0,0

;
		db	061h,050h,052h,00fh,019h,006h,019h
		db	019h,002h,00dh,0bh,00ch
		db	0h,0h,0,0

;
;
low_table	dw	set_mode
		dw	set_c_type
		dw	set_c_pos
		dw	get_c_pos
		dw	read_lpen
		dw	set_page
		dw	scroll_up
		dw	scroll_down
		dw	read_char
		dw	write_achar
		dw	write_char
		dw	set_pallette
		dw	write_dot
		dw	read_dot
		dw	write_tty
		dw	get_mode
		dw	no_op
;
;
high_table	dw	fill_window
		dw	draw_line
		dw	draw_box
		dw	fill_box
		dw	no_op


set		macro	num,val
		mov	w num,offset val
		mov	w num+2,seg val
		endm



;
;
;
;      Install is called on power up to initialize the interupt vectors,
;      and initialize the video boards.
;
video_init	proc	near
		xor	ax,ax
		mov	es,ax

;						Jonathan 2-24-86
		mov	tty_on,0		;turn off extended tty
		and	bits,not color_card
		and	bits2,not herc
		in	al,uart_input		;install video in new call system
		test	al,40h
		jnz	no_herc
		test	al,10h
		jnz	no_herc
		or  	bits2,herc
no_herc:
		or	equip_flag,30h
		mov	dx,color_base
		mov	ax,550fh		;check to see if color video is present
		out	dx,ax			;by outputting values to register
		out	dx,al			;reading them back and checking if
		inc	dx			;they are the same
		in	al,dx
		dec	dx
		cmp	al,55h
		jne	no_color
		mov	ax,0aa0fh
		out	dx,ax
		out	dx,al
		inc	dx
		in	al,dx
		cmp	al,0aah
		jne	no_color

		or	bits,color_card		;this is in biosdata.asm
		set	vector_10,video_io
		set	vector_1d,parameters
		mov	ax,0003h		;init color board 
		int	10h
		mov	b device_numbers+(2*010h)+1,6
		in	al,uart_input		;install video in new call system
		test	al,use_video
		jz	no_color
		mov	b device_numbers+(2*6)+1,6
						;install video as con output device

no_color:
;no color board test for bw board
;***********************************
	

		mov	dx,bw_base
		mov	ax,550fh		;check to see if video is present
		out	dx,ax			;by outputting values to register
		out	dx,al			;reading them back and checking if
		inc	dx			;they are the same
		in	al,dx
		dec	dx
		cmp	al,55h
		jne	no_video
		mov	ax,0aa0fh
		out	dx,ax
		out	dx,al
		inc	dx
		in	al,dx
		cmp	al,0aah
		jne	no_video
		set	vector_10,video_io
		set	vector_1d,parameters
		mov	ax,0007h		;init bw board.
		int	10h
		test	bits,color_card
		jz	install
		and	equip_flag,0ffefh	;clear color
		mov	ax,3
		int	10h
		mov	cx,607h
		call	set_c_type
install:
		mov	b device_numbers+(2*010h)+1,6
		in	al,uart_input		;install video in new call system
		test	al,use_video
		jz	no_video
		mov	b device_numbers+(2*6)+1,6
						;install video as con output device
no_video:
		push	bx
		mov	bx,offset pport_addr
		test	bits,color_card
		jz	no_lpt1
		mov	[bx],378h		;printer port on color
		add	bx,2
no_lpt1:	test	bits2,herc
		jz	no_lpt
		mov	[bx],3bch		;printer port on herc
no_lpt:		pop	bx
		ret
video_init	endp
		assume	es:nothing
;
;
;       Function dispatcher for int 10h
;       Int 10h is reentrent so that intrupt driven clocks ect. can use it
;
video_io	proc	far
		sti				;intrupts back on
		cld				;string operations forward
		push	es
		push	ds
		pusha
		sub	sp,offset size_temp_data
		mov	bp,sp			;temp data referenced off bp
;
		mov	al,ah
		xor	ah,ah
              
vi1:		cmp	al,80h
vi0:		jae	high_functions 		
;
		mov	si,offset low_table
		cmp	al,15
		jbe	dispatch
		mov	al,16
		jmp	dispatch
high_functions:
		sub	al,80h
		mov	si,offset high_table
		cmp	al,4
		jbe	dispatch
		cmp	al,07ah			;7f	    6/6/86
		jna	vi13   			;jne
		cmp	al,7bh 			;add
		jnz	vi15
		call	extty_on
		jmp	short vi14
vi15:		cmp	al,7ch
		jnz	vi16
		call	extty_off
		jmp	short vi14	     ;end add 6/6/86
vi16:		cmp	al,7dh
		jnz	vi14
		call	terminal_out
		jmp	short vi14
vi13:
		mov	al,5
dispatch:
		shl	ax,1
		add	si,ax			;si has index into jump table
		mov	ax,data
		mov	ds,ax
		call	cs:word ptr[si]
;
vi14:		add	sp,offset size_temp_data
		popa
		pop	ds
		pop	es
		iret
video_io	endp
;----------------------------------------------------------------
;  New video function calls
;
;  input:
;     al = function #
;        1 = output charecters
;           cx = count
;           es:si = buffer
;
;        3 = output status
;   output
;     al = status
;----------------------------------------------------------------
new_video	proc	far
		cmp	al,1		;write charecters
		jne	nv1
		jcxz	nv5
		push	cx
nv4:		lods	b es:[si]
		push	si
		push	cx
		and	tty_on,1
		jnz	nv6
		mov	ah,0eh		;tty output
		jmp	nv7
nv6:		mov	ah,0fdh		;extended tty output
nv7:		int	10h		
		pop	cx
		pop	si
		loop	nv4
		pop	cx
nv5:		mov	al,0
		ret
nv1:		cmp	al,3		;status
		jne	nv2
		mov	al,0
		ret
nv2:		mov	al,1		;bad command
		ret
new_video	endp
;
;
scroll_up	proc	near
		assume	es:vectors		;makes movs work
		mov	cx,rax[bp]
		xor	ch,ch
		cmp	cl,0			;number of rows to scroll in cx
		jne	su1
		mov	cx,rcx[bp]
		mov	dx,rdx[bp]
		mov	ah,080h			;fill window cx,dx with
		mov	al,' '			;spaces and attribute
		mov	bx,rbx[bp]
		mov	bl,bh
		int	10h
		ret

su1:		cmp	crt_mode,7
		je	su_cont
		cmp	crt_mode,4
		jb	su_cont
		jmp	gscroll_up
su_cont:
		mov	ax,page_seg
		mov	es,ax			;es has segment of video buffer
;
		mov	bx,rdx[bp]
		mov	bl,bh
		xor	bh,bh			;ending row to bx
		mov	ax,rcx[bp]
		mov	al,ah
		xor	ah,ah			;starting row to ax
		sub	bx,ax			;number of rows in window to bx
		inc	bx
		sub	bx,cx			;#of rows - rows to scroll=#of
		mov	temp1[bp],bx		;rows to move to temp1
		mov	bx,ax			;starting row to bx also
		mov	dl,num_columns		;words per line of text
		xor	dh,dh
		shl	dx,1			;bytes per line of text
		mul	dl
		mov	pointer2[bp],ax	;address to move first line to
		mov	ax,bx			;restore starting row to ax
		add	ax,cx
		mul	dl
		mov	pointer1[bp],ax	;address to move first line from
 		mov	ax,rcx[bp]
		xor	ah,ah			;starting column of window to ax
		shl	ax,1			;convert to words
		add	pointer1[bp],ax	;increment pointers to to
		add	pointer2[bp],ax	;starting column
		shr	ax,1			;back to columns
		mov	bx,rdx[bp]
		xor	bh,bh
		sub	bx,ax			;width of window to bx
		inc	bx
scroll_up_loop:	mov	cx,bx
		mov	si,pointer1[bp]
		mov	di,pointer2[bp]
		add	pointer1[bp],dx
		add	pointer2[bp],dx	;increment pointers one row
	rep	movs	kludge,kludge1	;move one row up
		dec	temp1[bp]
		jnz	scroll_up_loop		;repeat for all rows
		mov	cx,rcx[bp]
		mov	dx,rdx[bp]
		mov	ch,dh
		mov	ax,rax[bp]
		dec	al			;erases number of lines
		sub	ch,al			;at bottom of window
		mov	ah,080h			;fill window cx,dx with
		mov	al,' '			;spaces and attribute
		mov	bx,rbx[bp]
		mov	bl,bh
		int	10h
		ret
scroll_up	endp
;
;
scroll_down	proc	near
		mov	cx,rax[bp]
		xor	ch,ch
		cmp	cl,0			;number of rows to scroll in cx
		jne	sd1
		mov	cx,rcx[bp]
		mov	dx,rdx[bp]
		mov	ah,080h			;fill window cx,dx with
		mov	al,' '			;spaces and attribute
		mov	bx,rbx[bp]
		mov	bl,bh
		int	10h
		ret

;
sd1:		cmp	crt_mode,7
		je	sd_cont
		cmp	crt_mode,4
		jb	sd_cont
		jmp	gscroll_dn
sd_cont:
		mov	ax,page_seg
		mov	es,ax			;es has segment of video buffer
;
		mov	bx,rdx[bp]
		mov	bl,bh
		xor	bh,bh			;ending row to bx
		mov	dx,bx			;save in dx for now
		mov	ax,rcx[bp]
		mov	al,ah
		xor	ah,ah			;starting row to ax
		sub	bx,ax			;number of rows in window to bx
		inc	bx
		sub	bx,cx			;#of rows - rows to scroll=#of
		mov	temp1[bp],bx		;rows to move to temp1
		mov	ax,dx			;get last row back to ax
		mov	bx,ax			;starting row to bx also
		mov	dl,num_columns		;words per line of text
		xor	dh,dh
		shl	dx,1			;bytes per line of text
		mul	dl
		mov	pointer2[bp],ax	;address to move first line to
		mov	ax,bx			;restore ending row to ax
		sub	ax,cx
		mul	dl
		mov	pointer1[bp],ax	;address to move first line from
 		mov	ax,rcx[bp]
		xor	ah,ah			;starting column of window to ax
		shl	ax,1			;convert to words
		add	pointer1[bp],ax	;increment pointers to to
		add	pointer2[bp],ax	;starting column
		shr	ax,1			;back to columns
		mov	bx,rdx[bp]
		xor	bh,bh
		sub	bx,ax			;width of window to bx
		inc	bx
scroll_dn_loop:	mov	cx,bx
		mov	si,pointer1[bp]
		mov	di,pointer2[bp]
		sub	pointer1[bp],dx
		sub	pointer2[bp],dx	;increment pointers one row
	rep	movs	kludge,kludge1	;move one row down
		dec	temp1[bp]
		jnz	scroll_dn_loop		;repeat for all rows
		mov	cx,rcx[bp]
		mov	dx,rdx[bp]
		mov	dh,ch
		mov	ax,rax[bp]
		dec	al			;erases number of lines
		add	dh,al			;at top of window
		mov	ah,080h			;fill window cx,dx with
		mov	al,' '			;spaces and attribute
		mov	bx,rbx[bp]
		mov	bl,bh
		int	10h
		ret
scroll_down	endp

;
read_char	proc	near
		mov	ax,buffer_seg
		mov	es,ax
		mov	bx,rbx[bp]
		mov	bl,bh			;page to bl
		mov	ax,page_size
		xor	bh,bh
		mul	bx
		mov	si,bx			;si has page # for cursor
		shl	si,1			;address look up
		mov	bx,ax			;base of page into bx
		mov	al,num_columns
		shl	al,1			;mul by 2 for word address
		mov	cx,cursor_posn[si]
		mul	ch
		add	bx,ax			;address of row in bx
		xor	ch,ch
		shl	cl,1			;mul by 2 for word address
 		add	bx,cx			;address of cursor in bx
		mov	ax,es:[bx]		;read char
		mov	rax[bp],ax		;save to be restored to ax
		ret
read_char	endp
;
;
write_achar	proc	near
		cmp	crt_mode,7
		je	wac_cont
		cmp	crt_mode,3
		jbe	wac_cont
		jmp	near ptr graphics_write
wac_cont:

		
		mov	ax,buffer_seg
		mov	es,ax
		mov	bx,rbx[bp]
		mov	bl,bh			;page to bl
		mov	ax,page_size
		xor	bh,bh
		mul	bx
		mov	si,bx			;si has page # for cursor
		shl	si,1			;address look up
		mov	di,ax			;base of page into di
		mov	al,num_columns
		shl	al,1			;mul by 2 for word address
		mov	cx,cursor_posn[si]
		mul	ch
		add	di,ax			;address of row in di
		xor	ch,ch
		shl	cx,1			;mul by 2 for word address
 		add	di,cx			;address of cursor in di
		mov	ax,rax[bp]
		mov	bx,rbx[bp]
		mov	ah,bl			;char, and attribute in ax
		mov	cx,rcx[bp]		;count to write to cx
		rep	stosw			;store to es:di+=2
		ret
write_achar	endp
;
;
write_char	proc	near
		cmp	crt_mode,7
		je	wc_cont
		cmp	crt_mode,3
		jbe	wc_cont
		jmp	near ptr graphics_write
wc_cont:
		mov	ax,buffer_seg
		mov	es,ax
		mov	bx,rbx[bp]
		mov	bl,bh			;page to bl
		mov	ax,page_size
		xor	bh,bh
		mul	bx
		mov	si,bx			;si has page # for cursor
		shl	si,1			;address look up
		mov	di,ax			;base of page into di
		mov	al,num_columns
		shl	al,1			;mul by 2 for word address
		mov	cx,cursor_posn[si]
		mul	ch
		add	di,ax			;address of row in di
		xor	ch,ch
		shl	cx,1			;mul by 2 for word address
 		add	di,cx			;address of cursor in di
		mov	ax,rax[bp]
		mov	cx,rcx[bp]		;count to write to cx
		jcxz	wc_stop
wc_loop:	stosb	
		inc	di			;store to es:di+=2
		loop	wc_loop
wc_stop:	ret
write_char	endp

;
;
fill_window	proc	near
		cmp	crt_mode,7
		je	fw_cont
		cmp	crt_mode,4
		jb	fw_cont
		jmp	gfill_window
fw_cont:
;
		mov	ax,page_seg
		mov	es,ax			;es has segment of video buffer
;
		mov	bx,rdx[bp]
		mov	bl,bh
		xor	bh,bh			;ending row to bx
		mov	ax,rcx[bp]
		mov	al,ah
		xor	ah,ah			;starting row to ax
		sub	bx,ax
		inc	bx			;number of rows in window to bx
		mov	temp1[bp],bx		;rows to clear to temp1
		mov	dl,num_columns		;words per line of text
		xor	dh,dh
		shl	dx,1			;bytes per line of text
		mul	dl
 		mov	bx,rcx[bp]
		xor	bh,bh			;starting column of window to bx
		shl	bx,1			;convert to words
		add	ax,bx
		mov	pointer1[bp],ax	;address of first line to clear
		shr	bx,1			;back to columns
		mov	ax,bx			;starting column to ax
		mov	bx,rdx[bp]
		xor	bh,bh
		sub	bx,ax			;width of window to bx
		inc	bx
		mov	ax,rax[bp]
		mov	cx,rbx[bp]
		mov	ah,cl			;charecter and attribute in ax
fill_loop:	mov	cx,bx
		mov	di,pointer1[bp]
		add	pointer1[bp],dx
		rep	stos word ptr [di]	;move one row up
		dec	temp1[bp]
		jnz	fill_loop		;repeat for all rows
		ret
fill_window	endp
gfill_window	proc	near
		mov	ah,3
		mov	bh,0
		int	10h			;get cursor position
		mov	temp1[bp],dx		;and save it
		mov	dx,rcx[bp]
		mov	ah,2
		int	10h
		mov	cx,rdx[bp]
		mov	bl,ch			;bl has ending column
		sub	cl,dl
		inc	cl
		xor	ch,ch			;cx has count to write
		mov	ax,rax[bp]
gfill_loop:	mov	ah,2
		mov	bh,0
		int	10h			;position cursor
		mov	ah,10
		int	10h			;write cx chars
		inc	dh
		cmp	dh,bl
		jbe	gfill_loop
		mov	dx,temp1[bp]
		mov	ah,2
		int	10h			;restore cursor
		ret
gfill_window	endp
;
set_mode	proc	near
		mov	di,rax[bp]
		and	di,00ffh		;mode into di
		cmp	di,080h
		jb	smcont1
		jmp	extended_mode
smcont1:	cmp	di,8
		jb	smcont2
		jmp	illegal_mode

smcont2:

;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$		Jonathan 2-24-86

		cmp	di,4 			;if mode is 6 or less
		ja	smcont3			;a color board must be
		test	bits,color_card		;installed or default
		jnz	smcont3			;to slicer mode
		mov	di,7
;     		mov	rax[bp],7		;change callers mode
smcont3:

;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$

		mov	si,offset cursor_posn
		xor	ax,ax
		mov	cx,8
cur_zero_loop:	mov	[si],ax			;zero all cursors
		add	si,2
		loop	cur_zero_loop
		mov	dx,bw_base
		mov	buffer_seg,0b000h
		cmp	card_index[di],0
		je	sm1

		test	bits,color_card
		je	sm1				

		mov	dx,color_base
		mov	buffer_seg,0b800h
sm1:		mov	adr_6845,dx		;save 6845 base
		mov	al,params_len
		mul	param_index[di]		;ax has offset to parameters
		xor	cx,cx
		mov	es,cx
		assume	es:vectors
		les	si,vector_1d
		add	si,ax			;si points to 6845 parameters
						;for this mode
		mov	cx,params_len		;number of parameters to set
		mov	al,0
smloop:		
		mov	ah,byte ptr es:[si]	;mov next parameter into ah
		inc	si
		out	dx,ax
		inc	al
		loop	smloop
		mov	dx,adr_6845
		mov	bx,dx
		add	dx,_control		;setup control and color registers
		mov	al,control_reg[di]
		out	dx,al
		mov	dx,bx
		add	dx,_color
		mov	al,color_reg[di]
		out	dx,al
		mov	crt_pallette,al		;Jonathan 1-7-86
		mov	dx,bx
		add	dx,_status
st_check:	in	al,dx			;the quad ram color baord
		test	al,1			;seems to require this
		jz	st_check
		mov	al,columns[di]
		mov	num_columns,al
		shl	di,1
		mov	ax,p_size[di]
		mov	page_size,ax
		mov	cx,rax[bp]
		mov	crt_mode,cl
		mov	ah,5			;must set window before other
		mov	al,0			;operations !!!!!!!!!!!!
						;this sets up the pointer to the
						;page base
		int	10h
;
		mov	cx,0
		mov	dh,24			;(0,0)-(width,24)
		mov	dl,num_columns
		dec	dl
		mov	al,' '
		mov	bl,7
		mov	ah,080h
		int	10h			;fill screen
extended_mode:
illegal_mode:
		ret
		assume	es:nothing
set_mode	endp
;
get_mode	proc	near
		mov	bx,rbx[bp]		;get bx so bl can be preserved
		mov	bh,cur_page		;set approprate registers for
		mov	rbx[bp],bx		;restore with popa
		mov	al,crt_mode
		mov	ah,num_columns
		mov	rax[bp],ax
		ret
get_mode	endp
;
set_c_type	proc	near
		mov	dx,adr_6845
		mov	al,0ah
		mov	ah,ch
		out	dx,ax
		mov	al,0bh
		mov	ah,cl
		out	dx,ax
		mov	cursor_mode,cx
		ret
set_c_type	endp
;
set_c_pos	proc	near
		mov	bx,rbx[bp]
		mov	bl,bh
		xor	bh,bh			;offset into cursor position
		shl	bx,1			;table
		mov	ax,rdx[bp]
		mov	cursor_posn[bx],ax	;save position in table
		shr	bx,1			;back to page #
		cmp	crt_mode,7
		je	scp_cont
		cmp	crt_mode,4
		jae	scp_done		;do nothing for grapics modes
scp_cont:	cmp	bl,cur_page
		jne	scp_done		;need to update actual position?
		mov	cx,ax			;position to cx
		mov	ax,page_size
		shr	ax,1			;div by 2 for 6845
		mul	bx			;base of page into bx
		mov	bx,ax
		mov	al,num_columns
		mul	ch
		add	bx,ax			;address of row in bx
		xor	ch,ch
		add	cx,bx			;address of cursor in cx
		mov	dx,adr_6845
		mov	al,0eh
		mov	ah,ch
		out	dx,ax
		mov	al,0fh
		mov	ah,cl
		out	dx,ax
scp_done:	ret
set_c_pos	endp
;
get_c_pos	proc	near
		mov	bx,rbx[bp]
		mov	bl,bh
		xor	bh,bh
		shl	bx,1				;page in bx
		mov	ax,cursor_posn[bx]		;save cursor_posn, and
		mov	rdx[bp],ax			;curcor_mode so they
		mov	ax,cursor_mode			;will be rewstored with
		mov	rcx[bp],ax			;the popa
		ret
get_c_pos	endp
;
set_page	proc	near
		cmp	crt_mode,7
		je	sp_cont
		cmp	crt_mode,4
		jae	spg_done		;do nothing for grapics modes
sp_cont:	mov	ax,rax[bp]
		mov	cur_page,al
		mov	bl,al
		mov	ax,page_size
		xor	bh,bh
		mul	bx
		mov	si,bx			;si has page # for cursor
		shl	si,1			;address look up
		mov	bx,ax			;base of page into bx
		shr	bx,1			;div by 2 for byte address
		mov	temp1[bp],ax		;save in temp1 also
		mov	al,num_columns
		mov	cx,cursor_posn[si]
		mul	ch
		add	bx,ax			;address of row in bx
		xor	ch,ch
		add	cx,bx			;address of cursor in cx
		mov	dx,adr_6845
						;set cursor address in 6845
		mov	al,0eh
		mov	ah,ch
		out	dx,ax
		mov	al,0fh
		mov	ah,cl
		out	dx,ax
		mov	cx,temp1[bp]		;retrieve base of page
		shr	cx,1			;divide by 2 for 6845 address
		mov	ax,adr_6845
		cmp	ax,bw_base
		jne	sp_around1		;decrement by 1 for 6845 
		test	bits2,herc
		jnz	sp_around1
		dec	cx        		;only if b and w board
sp_around1:	mov	ah,ch			;set base address in 6845
		mov	al,0ch
		out	dx,ax
		mov	al,0dh
		mov	ah,cl
		out	dx,ax
		mov	ax,adr_6845
		cmp	ax,bw_base
		jne	sp_around2		;increment by 1 for 6845 
		test	bits2,herc
		jnz	sp_around2
		inc	cx        		;only if b and w board to
sp_around2:					;counter act the preceeding dec
		shr	cx,3			;segment value of base
						;shift only 3 times because
						;already shifted once above
;
		mov	ax,buffer_seg
		add	ax,cx
		mov	page_seg,ax
spg_done:	ret
set_page	endp
;
graphics_write	proc	near
		mov	ax,cursor_posn
		mov	dl,al
		xor	dh,dh			;dx has column
		mov	al,ah
		shl	ax,1			;mul by 2 for word index
		mov	cl,8
		mul	cl
		mov	bx,ax  			;bx has base row for charecter
		cmp	crt_mode,5
		ja	gw_cont1
		shl	dx,1
gw_cont1:	mov	ax,rax[bp]		;dx has offset for char write
		mul	cl
		mov	si,ax			;si points to char
		lea	si,cs:char_gen[si]
		mov	temp1[bp],8
gw_loop:	lods	cs:char_gen[si]
		cmp	crt_mode,5
		ja	gw_cont4
		mov	cx,8
gw_loop1:	shr	al,1
		rcr	di,1
		sar	di,1
		loop	gw_loop1		;expand into a word
		mov	ax,di
		xchg	al,ah
		mov	cx,rax[bp]
		cmp	ch,9
		jne	gw_cont4		;write with out color
		mov	di,rbx[bp]		;color
		and	di,3
		shl	di,1
		and	ax,cs:color_mask[di]	;and with color mask

gw_cont4:	mov	es,cs:base_table1[bx]
		add	bx,2		        ;inc to next column
		mov	di,dx
		mov	cx,rcx[bp]
		cmp	crt_mode,5
		ja	gw_cont2
		rep	stosw
		jmp	gw_cont3
gw_cont2:	rep	stosb
gw_cont3:	dec	temp1[bp]
		jnz	gw_loop
		ret
graphics_write	endp



gscroll_up	proc	near					;cx has number of rows to scroll
;
		shl	cx,3
		mov	bx,rdx[bp]
		mov	bl,bh
		xor	bh,bh			;multiply by 8
		shl	bx,3			;ending row to bx
		add	bx,7
		mov	ax,rcx[bp]
		mov	al,ah
		xor	ah,ah			;starting row to ax
		shl	ax,3
		sub	bx,ax			;number of rows in window to bx
		inc	bx
		sub	bx,cx			;#of rows - rows to scroll=#of
		mov	temp1[bp],bx		;rows to move to temp1
		mov	bx,ax			;starting row to bx also
		shl	ax,1
		mov	pointer2[bp],ax		;address to move first line to
		mov	ax,bx			;restore starting row to ax
		add	ax,cx
		shl	ax,1
		mov	pointer1[bp],ax		;address to move first line from
 		mov	ax,rcx[bp]
		xor	ah,ah			;starting column of window to ax
		mov	bx,rdx[bp]
		xor	bh,bh
		sub	bx,ax			;width of window to bx
		inc	bx
		xor	dx,dx
		cmp	crt_mode,5
		ja	gscrl_up_loop
		not	dx			;dx is word move flag
		shl	ax,1
gscrl_up_loop:	mov	cx,bx
		mov	si,pointer1[bp]
		mov	di,pointer2[bp]
		mov	ds,cs:base_table1[si]
		mov	es,cs:base_table1[di]
		mov	si,ax
		mov	di,ax
		add	pointer1[bp],2
 		add	pointer2[bp],2		;increment pointers one row
		or	dx,dx
		je	gsu2
		rep	movsw			;move one row up
		jmp	gsu3
gsu2:		rep	movsb
gsu3:		dec	temp1[bp]
		jnz	gscrl_up_loop		;repeat for all rows
		mov	cx,rcx[bp]
		mov	dx,rdx[bp]
		mov	ch,dh
		mov	ax,rax[bp]
		dec	al			;erases number of lines
		sub	ch,al			;at bottom of window
		mov	ah,080h			;fill window cx,dx with
		mov	al,' '			;spaces and attribute
		mov	bx,rbx[bp]
		mov	bl,bh
		int	10h
		ret
gscroll_up	endp

gscroll_dn	proc	near			;cx has number of rows to scroll
;
		shl	cx,3
		mov	bx,rdx[bp]
		mov	bl,bh
		xor	bh,bh			;multiply by 8
		shl	bx,3			;ending row to bx
		add	bx,7
		mov	dx,bx			;save in dx for now
		mov	ax,rcx[bp]
		mov	al,ah
		xor	ah,ah			;starting row to ax
		shl	ax,3
		sub	bx,ax			;number of rows in window to bx
		inc	bx
		sub	bx,cx			;#of rows - rows to scroll=#of
		add	bx,8			;this seems to fix a bug who knows why?????
		mov	temp1[bp],bx		;rows to move to temp1
		mov	ax,dx
		mov	bx,ax			;ending row to bx also
		shl	ax,1
		mov	pointer2[bp],ax		;address to move first line to
		mov	ax,bx			;restore ending row to ax
		add	ax,cx
		shl	ax,1
		mov	pointer1[bp],ax		;address to move first line from
 		mov	ax,rcx[bp]
		xor	ah,ah			;starting column of window to ax
		mov	bx,rdx[bp]
		xor	bh,bh
		sub	bx,ax			;width of window to bx
		inc	bx
		xor	dx,dx
		cmp	crt_mode,5
		ja	gscrl_dn_loop
		not	dx			;dx is word move flag
		shl	ax,1
gscrl_dn_loop:	mov	cx,bx
		mov	si,pointer1[bp]
		mov	di,pointer2[bp]
		mov	ds,cs:base_table1[di]
		mov	es,cs:base_table1[si]
		mov	si,ax
		mov	di,ax
		sub	pointer1[bp],2
		sub	pointer2[bp],2		;increment pointers one row
		or	dx,dx
		je	gsd2
		rep	movsw			;move one row up
		jmp	gsd3
gsd2:		rep	movsb
gsd3:		dec	temp1[bp]
		jnz	gscrl_dn_loop		;repeat for all rows
		mov	cx,rcx[bp]
		mov	dx,rdx[bp]
		mov	dh,ch
		mov	ax,rax[bp]
		dec	al			;erases number of lines
		add	dh,al			;at top of window
		mov	ah,080h			;fill window cx,dx with
		mov	al,' '			;spaces and attribute
		mov	bx,rbx[bp]
		mov	bl,bh
		int	10h
		ret
gscroll_dn	endp


write_dot	proc	near
		cmp	crt_mode,6
		jne	wd1
		jmp	wd_hr
wd1:		mov	ax,rcx[bp]
		mov	bl,4
		div	bl
		mov	bl,ah
		xor	ah,ah
		xor	bh,bh
		mov	si,ax
		mov	al,dot_mask[bx]
		mov	bx,rdx[bp]
		mov	es,base_table1[bx]
		test	rax[bp],80h
		jnz	wdxor
		mov	ah,es:[si]
		not	al
		and	ah,al
		not	al
		mov	bx,rax[bp]
		and	bx,3
		and	al,color_mask1[bx]
		or	ah,al
		mov	es:[si],ah
		ret
wdxor:		mov	bx,rax[bp]
		and	bx,3
		and	al,color_mask1[bx]
		xor	es:[si],al
		ret
wd_hr:
		mov	ax,rcx[bp]
		mov	bl,8
		div	bl
		mov	bl,ah
		xor	ah,ah
		xor	bh,bh
		mov	si,ax
		mov	al,dot_mask1[bx]
		mov	bx,rdx[bp]
		mov	es,base_table1[bx]
		test	rax[bp],80h
		jnz	wdhrxor
		mov	ah,es:[si]
		or	ah,al
		mov	es:[si],ah
		ret
wdhrxor:	mov	bx,rax[bp]
		xor	es:[si],al
		ret
write_dot	endp




read_dot	proc	near
		cmp	crt_mode,6
		jne	rd1
		jmp	rd_hr
rd1:		mov	ax,rcx[bp]
		mov	bl,4
		div	bl
		mov	cl,ah
		mov	bl,ah
		add	cl,cl
		xor	ah,ah
		xor	bh,bh
		mov	si,ax
		mov	al,dot_mask[bx]
		mov	bx,rdx[bp]
		mov	es,base_table1[bx]
		mov	ah,es:[si]
		and	ah,al
		shr	ah,cl
		mov	al,ah
		mov	rax[bp],ax
		ret
rd_hr:
		mov	ax,rcx[bp]
		mov	bl,8
		div	bl
		mov	cl,ah
		mov	bl,ah
		xor	ah,ah
		xor	bh,bh
		mov	si,ax
		mov	al,dot_mask1[bx]
		mov	bx,rdx[bp]
		mov	es,base_table1[bx]
		mov	ah,es:[si]
		and	ah,al
		shr	ah,cl
		mov	al,ah
		mov	rax[bp],ax
		ret
read_dot	endp


set_pallette	proc	near
		cmp	crt_mode,4
		jnz	sp_end
		mov	bx,rbx[bp]
		or	bh,bh
		je	sp1
		mov	al,crt_pallette
		and	al,0e0h
		and	bl,01fh
		or	al,bl
		jmp	short sp2
sp1:		mov	al,crt_pallette
		and	al,not 100000b
		shr	bl,1
		jnc	sp2
		or	al,100000b
sp2:
		mov	crt_pallette,al
		mov	dx,color_base+_color
sp3:		out	dx,al
sp_end:		ret
set_pallette	endp


esc		equ	1bh
f_char		db	'Y'
		db	'A'
		db	'B'
		db	'C'
		db	'D'
		db	'E'
		db	'H'
		db	'I'
		db	'J'
		db	'K'
		db	'd'
		db	'l'
		db	'o'
		db	'L'
		db	'M'
f_char_len	equ	(this byte - f_char)

function	dw	position
		dw	up
		dw	down
		dw	right
		dw	left
		dw	erase_scrn
		dw	home
		dw	reverse_lf
		dw	erase_eos
		dw	erase_eol
		dw	erase_bos
		dw	erase_line
		dw	erase_bol
		dw	insert_line
		dw	delete_line

terminal_out	proc	near
		mov	ax,[bp].rax
		test	esc_flag,1
		jnz	i1			;in esc sequence
		cmp	al,esc
		jne	i99			;send it through
		or	esc_flag,1		;set flag and return
		ret
i99:
		jmp	write_tty

i1:		test	esc_flag,10b		;cursor position flag
		jz	i11
		jmp	position1
i11:		xor	bx,bx
i2:		cmp	al,f_char[bx]
		je	i3
		inc	bx
		cmp	bx,f_char_len
		jbe	i2
		and	esc_flag,not 1		;bad esc seq throw it out
		ret
i3:		shl	bx,1
		jmp	function[bx]		;goto desired function
terminal_out	endp



home		proc	near
		mov	bh,cur_page
		mov	dx,0			;cursor at (0,0)
		mov	ah,2
		int	10h
		and	esc_flag,not 1		;clear esc flag
		ret
home		endp
position	proc	near
		mov	vid_temp,0
		or	esc_flag,10b		;in cursor position
		ret
position	endp
position1	proc	near
		cmp	vid_temp,0
		jne	p1			;already have row
		sub	al,32
		mov	vid_temp,al			;store row
		ret
p1:		mov	bh,cur_page
		mov	dh,vid_temp			;row
		mov	dl,al
		sub	dl,32			;column
		mov	ah,2
		int	10h			;position cursor
		and	esc_flag,(not 11b)
		ret		
position1	endp

erase_scrn	proc	near
		mov	cx,0
		mov	dh,24			;(0,0)-(width,24)
		mov	dl,num_columns
		dec	dl
		mov	al,' '
		mov	bl,7
		mov	ah,080h
		int	10h			;fill screen
		mov	bh,cur_page
		mov	dx,0			;cursor at (0,0)
		mov	ah,2
		int	10h
		and	esc_flag,not 1		;clear esc flag
		ret
erase_scrn	endp

erase_eos	proc	near
		mov	bh,cur_page
		mov	ah,3
		int	10h
		mov	cx,dx
		cmp	ch,24
		jae	erase_eol
		inc	ch
		mov	cl,0
		mov	dh,24
		mov	dl,num_columns
		dec	dl
		mov	al,' '
		mov	bl,7
		mov	ah,80h			;fill box just below cursor
		int	10h			;then erase eol

erase_eol:
		mov	bh,cur_page
		mov	ah,3
		int	10h
		mov	cx,dx
		mov	dl,num_columns
		dec	dl
		mov	al,' '
		mov	bl,7
		mov	ah,80h			;fill box just to end of line
		int	10h
		and	esc_flag,not 1		;clear esc flag
		ret
erase_eos	endp

erase_line	proc	near
		mov	bh,cur_page
		mov	ah,3
		int	10h
		mov	cx,dx
		mov	dl,num_columns
		dec	dl
		mov	cl,0
		mov	al,' '
		mov	bl,7
		mov	ah,80h			;fill just the line
		int	10h
		and	esc_flag,not 1		;clear esc flag
		ret
erase_line	endp


erase_bos	proc	near
		mov	bh,cur_page
		mov	ah,3
		int	10h
		mov	cx,0
		cmp	dh,0
		je	erase_bol
		dec	dh
		mov	dl,num_columns
		dec	dl
		mov	al,' '
		mov	bl,7
		mov	ah,80h			;fill box just below cursor
		int	10h			;then erase eol

erase_bol:
		mov	bh,cur_page
		mov	ah,3
		int	10h
		mov	cx,dx
		mov	cl,0
		mov	al,' '
		mov	bl,7
		mov	ah,80h			;fill box just to end of line
		int	10h
		and	esc_flag,not 1		;clear esc flag
		ret
erase_bos	endp

reverse_lf	proc	near
		mov	bh,cur_page
		mov	ah,3
		int	10h
		cmp	dh,0
		jne	up
		jmp	insert_line
reverse_lf	endp

up		proc	near
		mov	bh,cur_page
		mov	ah,3
		int	10h
		sub	dh,1
		jb	u1
		mov	ah,2
		int	10h
u1:		and	esc_flag,not 1		;clear esc flag
		ret
up		endp
down		proc	near
		mov	bh,cur_page
		mov	ah,3
		int	10h
		inc	dh
		cmp	dh,24
		ja	d1
		mov	ah,2
		int	10h
d1:		and	esc_flag,not 1		;clear esc flag
		ret
down		endp
left		proc	near
		mov	bh,cur_page
		mov	ah,3
		int	10h
		sub	dl,1
		jb	l1
		mov	ah,2
		int	10h
l1:		and	esc_flag,not 1		;clear esc flag
		ret
left		endp
right		proc	near
		mov	bh,cur_page
		mov	ah,3
		int	10h
		inc	dl
		cmp	dl,num_columns
		jae	r1
		mov	ah,2
		int	10h
r1:		and	esc_flag,not 1		;clear esc flag
		ret
right		endp
insert_line	proc	near
		mov	bh,cur_page
		mov	ah,3		;position
		int	10h
		mov	ah,8
		int	10h		;attribute
		mov	cx,dx
		xor	cl,cl		;top corner
		mov	dl,num_columns
		mov	dh,24
		mov	ax,701h
		int	10h		;scroll down
		and	esc_flag,not 1		;clear esc flag
		ret
insert_line	endp
delete_line	proc	near
		mov	bh,cur_page
		mov	ah,3		;position
		int	10h
		mov	ah,8
		int	10h		;attribute
		mov	cx,dx
		xor	cl,cl		;top corner
		mov	dl,num_columns
		mov	dh,24
		mov	ax,601h
		int	10h		;scroll up
		and	esc_flag,not 1		;clear esc flag
		ret
delete_line	endp
;
write_tty	proc	near
		mov	bh,cur_page
		mov	ah,3			;get cursor position for all 
		int	10h			;functions
		mov	ax,rax[bp]		;char into al jump to special
		cmp	al,b_space		;case
		je	wb_space
		cmp	al,c_return
		je	wc_return
		cmp	al,l_feed
		je	wl_feed
		cmp	al,bell
		je	wbell
;
		mov	ah,10			;not special case
		mov	cx,1			;write a charecter to cursor
		int	10h			;on active page bh has page
;
		inc	dl			;move to right one position
		cmp	dl,num_columns		;off screen???
		jb	on_screen
		xor	dl,dl			;set column to 0
		inc	dh			;goto next row
		cmp	dh,24
		jbe	on_screen
		mov	ah,8			;must scroll screen. get
		int	10h			;attribute for fill to bh
		mov	bh,ah			;bh still had page
		mov	ax,0601h		;scroll one line
		mov	cx,0			;upper left = (0,0)
		mov	dl,num_columns
		dec	dl
		mov	dh,24			;lower right = (24,num_columns)
		int	10h
		mov	dx,1800h		;position of cursor 18h=24d
on_screen:	mov	bh,cur_page
		mov	ah,2
		int	10h			;reposition cursor
wbell:		ret				;no op for bell
;
wc_return:	mov	dl,0			;mov to column 0
		mov	ah,2
		int	10h			;set cursor
		ret
;
wl_feed:	cmp	dh,24
		mov	temp1[bp],dx		;save position in temp1
		jb	wl_no_scroll
		mov	ah,8
		int	10h
		mov	bh,ah			;attribute fo fill new line with
		mov	cx,0			;upper left (0, 0)
		mov	dh,24			;lower right (24, num_columns)
		mov	dl,num_columns
		dec	dl
		mov	ax,0601h		;scroll screen up 1 line
		int	10h
		mov	dx,temp1[bp]		;restore cursor position
		mov	dh,23			;incremented to 24 on next line
wl_no_scroll:	inc	dh
		mov	ah,2
		int	10h			;set cursor position
		ret
;
wb_space:	cmp	dl,0
		je	wb_up			;must move up to next line
		dec	dl			;back space
		jmp	wb_writes		;write a space
wb_up:		mov	dl,num_columns
		cmp	dh,0
		je	wb_do_nothing		;already at (0,0) do nothing
		dec	dh
		jmp	wb_writes
wb_do_nothing:	mov	dx,0			;keep at (0, 0)
wb_writes:	mov	ah,2			;set cursor position bh=page
		int	10h
		mov	ax,0a20h		;write a space to cursor
		mov	cx,1
		int	10h
		ret
;
;
no_op:
read_lpen:
draw_line:
draw_box:
fill_box:
		ret
write_tty	endp	
;
extty_on	proc	near
assume		ds:data
		mov	ax,data
		mov	ds,ax
		mov	tty_on,1
		ret
extty_on	endp

extty_off	proc	near
assume		ds:data
		mov	ax,data
		mov	ds,ax
		mov	tty_on,0
		ret
extty_off	endp		
; 
code		ends

		end



