h40353
s 00001/00000/00697
d D 1.5 83/03/18 14:22:25 bog 5 4
c Showing filename must turn off high bit of name characters.
e
s 00001/00001/00696
d D 1.4 83/03/17 21:04:52 bog 4 3
c Fix serial number to xxxx-.
e
s 00001/00001/00696
d D 1.3 83/03/17 20:42:54 bog 3 2
c Update date and version to 18 Mar 83 and V1.1
e
s 00046/00029/00651
d D 1.2 83/03/17 20:11:23 bog 2 1
c Avoid Mov Ss,.. Mov Sp,.. window; change "GIOS is xx at yyyy:0000" message.
e
s 00680/00000/00000
d D 1.1 83/03/17 14:37:27 tes 1 0
c date and time created 83/03/17 14:37:27 by tes
e
u
4
U
t
T
I 1
	Pagewidth	96
Bdos_Int	Equ	224		; Int value for Bdos
Gdos_Int	Equ	Bdos_Int	; Int value for Gdos
Gdos_Function	Equ	115		; Cl value for Gdos

Gdos_V	Equ	Gdos_Int*4

Gdos_Vector	Equ	DWord Ptr .Gdos_V	; Gdos interrupt vector

CSeg_Base	Equ	Word Ptr .0003h	; Seg of code bucket base
DSeg_Base	Equ	Word Ptr .0009h	; Seg of data bucket base
ESeg_Base	Equ	Word Ptr .000fh	; Seg of extra bucket base
SSeg_Base	Equ	Word Ptr .0015h	; Seg of stack bucket base

	Include	BStruct.A86

	Eject

; Graphics	Load and initialize GSX-86

Graphics_Code	CSeg	Byte	Public

Graphics:
I 2
	Pushf				; Save flags
	Pop	Si			;  in register
	Cli				; Disable interrupt
E 2
	Mov	Ss,SSeg_Base		; Get base of stack
	Mov	Sp,Offset Top_Stack	;  & offset
I 2
	Push	Si			; Put flags back
	Popf				;  to leave interrupt enable unchanged
E 2

	Mov	Ax,Cs			; Get segbase of this segment
	Add	Ax,Graphics_Paragraphs	; Bump to base of GSX
	Mov	Loaded_GSX_Base,Ax	; Save base of GSX
	Mov	GSX_Seg1,Ax		; Fix up DWord Ptrs
	Mov	GSX_Seg2,Ax
	Mov	GSX_Seg3,Ax
	Mov	GSX_Seg4,Ax
	Mov	GSX_Seg5,Ax

	Mov	Ax,Offset GSX_End+15	; Offset of 1st byte after GSX + round
	Mov	Cl,4
	Shr	Ax,Cl			; Ax <- Number of paragraphs in GSX
	Mov	GSX_Paragraphs,Ax	; Save paragraph count

	Mov	Ax,GSX_Comm_Paragraphs	; Get length of default GSX_Comm
	Mov	Comm_Paragraphs,Ax	;  into variable

	Mov	Cl,00ch			; Bdos "Return Version Number" funct
	Callf	_GSX_Bdos

	And	Bh,00bh			; Turn off CPU nibble & networking bit
	Mov	Word Ptr Version_Number,Bx; Save version number, OS type
	Mov	Bdos_Base,Es		; Save Bdos base (for CP/M-86)

	Mov	Dx,Offset Sign_On	; Point to signon message
	Mov	Cl,009h			; Bdos "Print String" function
	Callf	_GSX_Bdos		; Show signon message

	Eject

; Look for d: or NO here

	Mov	Bx,0			; Start at beginning of cmd line

Skip_Command_Blanks:
	Inc	Bx			; Bump to next character
	Cmp	Bl,Byte Ptr .00080h	; Check against character count
	Ja	Command_Done		; Quit if no command

	Mov	Al,Byte Ptr .00080h[Bx]	; Get next command character

	Cmp	Al,' '			; Blank?
	Je	Skip_Command_Blanks	; Skip if so
	Cmp	Al,8			; Tab?
	Je	Skip_Command_Blanks	; Skip if so

	Cmp	Al,';'			; Comment? i.e. null command?
	Je	Command_Done		; Jump if yes

	Cmp	Al,'A'			; Possible d:?
	Jb	Not_Drive		; Jump if no

	Cmp	Al,'P'			; Still possible d:?
	Ja	Not_Drive		; Jump if no

	Cmp	Byte Ptr .00081h[Bx],':'; Followed by ":"?
	Jne	Not_Drive		; Jump if no

; d: found
	Sub	Al,'@'			; Force 1..16 from A..P
	Mov	Es,Loaded_GSX_Base	; Get seg of GSX as loaded
	Mov	Es:Default_Drive,Al	; Save default drive declared
	Jmps	Command_Done		;  & go load GSX

Not_Drive:
	Cmp	Al,'N'			; "Graphics No"?
	Jne	Command_Syntax_Error	; Jump if error in command

	Mov	No_Load,1		; Set switch so GSX won't load
	Jmps	Command_Done		;  & go kill GSX if present

	Eject

Command_Syntax_Error:
	Mov	Cl,Byte Ptr .00080h	; Get character count
	Mov	Ch,0			; Clear high half
	Sub	Si,Si			; Start with index of zero

Syntax_Error_Loop_0:
	Mov	Dl,Byte Ptr .00081h[Si]	; Get a byte to show
	Inc	Si			; Point to next
	Call	ShowCh			; Show the character
	Loop	Syntax_Error_Loop_0	;  & loop until all shown

	Mov	Dl,13			; Show Cr
	Call	ShowCh
	Mov	Dl,10			;  & Lf
	Call	ShowCh
	Mov	Cx,Bx			; Need to put out (Bx) spaces
	Jcxz	Syntax_Error_Show	; Jump if no spaces

Syntax_Error_Loop_1:
	Mov	Dl,' '			; Show a space
	Call	ShowCh			;  via Bdos
	Loop	Syntax_Error_Loop_1	;  & loop until proper number shown

Syntax_Error_Show:
	Mov	Dx,Offset Command_Error	; Point to "^ syntax error"
	Jmp	Just_Error		; Show the error and quit

	Eject

Command_Done:
	Test	No_Load,0ffh		; New GSX needed?
	Jnz	GSX_Not_Installed	; No -- quit with "not installed" msg

	Push	Bp			; Fake a local frame
	Mov	Bp,Sp
	Sub	Sp,72+BuffStructSize+18	; Room for 2 Fcbs and buff struct

	Callf	_BI_Open_Assign		; Open ASSIGN.SYS
	Jc	Assign_Not_Found	; Jump if ASSIGN.SYS not found

	Callf	_BI_Parse_Line		; Get first line of ASSIGN.SYS
	Jnz	Parse_Error		; Jump if error in ASSIGN.SYS

	Mov	Default_Device,Dx	; Save default device Id

	Push	Ss			; FClose needs Fcb Ptr
	Push	Bx
	Callf	_FClose			; Close ASSIGN.SYS
	Jc	Assign_Not_Closed	; Jump if error in close

	Mov	Sp,Di			; Save driver's Fcb

	Sub	Sp,BuffStructSize	; Make room for driver header

	Push	Di			; Save offset of Fcb

	Push	Ss			; PSize needs FcbPtr
	Push	Di
	Push	Ss			;  & HeaderPtr
	Lea	Si,-BuffStructSize[Di]
	Push	Si
	Callf	_PSize			; Open and find size of driver
	Jnz	Driver_Error		; Quit if error in driver size

	Mov	Driver_Paragraphs,Bx	; Save driver length

	Eject

	Pop	Di			; Point to Fcb again

	Push	Ss			; FClose needs FcbPtr
	Push	Di
	Callf	_FClose			; Close the driver file
	Jnc	Get_Mem			; Jump if no errors so far

					; d:ffffffff.xxx close error
	Mov	Bx,Di			; Error in driver Fcb

Assign_Not_Closed:			; d:ASSIGN  .SYS close error
	Mov	Dx,Offset Close_Error	; Point to " close error"

Error_Die:
D 2
	Push	Dx			; Save pointer to message

	Mov	Dl,Ss:Byte Ptr .0[Bx]	; Get drive
	Or	Dl,Dl			; Default?
	Jz	FOpNDrv			; Jump if no need to show d:

	Add	Dl,'@'			; Make drive a letter
	Call	ShowCh			; Show char in Dl
	Mov	Dl,':'			;  then ":"
	Call	ShowCh			;  for "d:"

FOpNDrv:
	Inc	Bx			; Point to filename
	Mov	Cx,8			; 8 characters of filename
	Call	ShowChs			; Show them
	Mov	Dl,'.'			; "."
	Call	ShowCh			; Show it
	Mov	Cl,3			; 3 characters of extension
	Call	ShowChs			; Show them

	Pop	Dx			; Get pointer to message back

E 2
I 2
	Call	Show_File		; Show the filename with FCB at Ss:[Bx]
E 2
	Eject

Mem_Death:
	Mov	Cl,009h			; Bdos "Print String" function
	Callf	_GSX_Bdos		; Show the error message

GSX_Not_Installed:
	Call	Remove_GSX		; Make sure GSX isn't resident

	Mov	Dx,Offset Not_Installed_Msg; Point to "GSX-86 not installed"

Just_Error:
	Mov	Cl,009h			; Bdos "Print String" function
	Callf	_GSX_Bdos		; Show the status message

	Mov	Cl,0			; Bdos "System Reset" function
	Sub	Dx,Dx			; Free all memory
	Int	Bdos_Int		; Quit with no GSX-86

Assign_Not_Found:			; d:ASSIGN  .SYS not found
	Mov	Dx,Offset Not_Found	; Point to " not found"
	Jmps	Error_Die		; Show error & quit

Parse_Error:				; d:ASSIGN  .SYS syntax error
	Mov	Dx,Offset Syntax_Error	; Point to " syntax error"
	Jmps	Error_Die		; Show error & quit

Driver_Error:
	Mov	Bx,Di			; Error in driver Fcb
	Sub	Al,5			; -,0,+ : 4,5,6
					; d:ffffffff.xxx not found
	Jl	Assign_Not_Found	; Show error & quit

	Mov	Dx,Offset Empty_Mess	; Assume driver empty
					; d:ffffffff.xxx empty
	Jz	Error_Die		; Show error & quit

	Mov	Dx,Offset Abs_Driver	; Point to " contains absolute"
					; d:ffffffff.xxx contains absolute
	Jmps	Error_Die		; Show error & quit

	Eject

Get_Mem:
D 2
	Mov	Sp,Bp			; Restore stack from FCB junk
E 2
I 2
	Mov	Sp,Di			; Leave driver Fcb on stack
E 2
	Call	Remove_GSX		; Remove old GSX if present
; assume cp/m-86

	Mov	Cx,GSX_Paragraphs	; Compute number of paragraphs
	Add	Cx,Comm_Paragraphs	;  required for
	Add	Cx,Driver_Paragraphs	;  new GSX and driver and comm

	Mov	All_Paragraphs,Cx	; Save length of new everything

	Les	Bx,MRT_Ptr		; Get ptr to Bios mem table
	Mov	Di,1			; Start scan at first region

	Mov	Cl,Es:(Byte Ptr 0)[Bx]	; Number of entries in MRT to Cx
	Mov	Ch,0			; High half zero

Find_GSX_Place:
	Mov	Ax,All_Paragraphs	; Get number of paragraphs required
	Cmp	Ax,Es:(Word Ptr 2)[Bx+Di]; Room in this chunk for all?
	Ja	GSX_Place_Not_Found	; Jump if not found

	Mov	Dx,Es:(Word Ptr 0)[Bx+Di]; Get base of MRT entry
	Mov	Moved_GSX_Base,Dx	; Save for possible move
	Cmp	Dx,Old_GSX_Base		; Same place as before?
	Jne	Not_Same_Place		; Jump if a different place

	Add	Dx,Old_GSX_Paragraphs	; If same, start grabbing above old
	Sub	Ax,Old_GSX_Paragraphs	;  for shorter length
	Mov	M_Length,Ax		; Save delta in length
	Jbe	Move_GSX	; Jump if new shorter than old

Not_Same_Place:
	Mov	M_Base,Dx		; New GSX base into MCB
	Mov	M_Length,Ax		; Size required

	Push	Bx			; Preserve registers from Bdos
	Push	Cx
	Push	Di
	Push	Es
	Mov	Dx,Offset M_Base	; Point to MCB
	Mov	Cl,038h			; Bdos "Alloc Abs Mem" function
	Callf	_GSX_Bdos		; Get additional memory just above old
	Pop	Es			; Restore registers from Bdos
	Pop	Di
	Pop	Cx
	Pop	Bx

	Inc	Al			; Successful allocate?
	Jnz	Move_GSX	; Jump if yes

GSX_Place_Not_Found:
	Add	Di,4			; Point to next MRT entry
	Loop	Find_GSX_Place		;  & try it

	Mov	Dx,Offset Death_Mess	; Point to memory error message
	Jmp	Mem_Death		; Could not find a spot for GSX

	Eject

Move_GSX:
	Mov	Ax,All_Paragraphs	; Delta to MRT entry
	Add	Es:(Word Ptr 0)[Bx+Di],Ax; Bump base of MRT entry up
	Sub	Es:(Word Ptr 2)[Bx+Di],Ax;  & length down

	Push	Ds			; Save pointer to my DSeg

	Mov	Es,Moved_GSX_Base	; Point to place to put GSX

	Mov	Si,0			; First word to move
	Mov	Di,0			; Place to put it

	Mov	Cx,All_Paragraphs	; Number of paragraphs in everything
	Sub	Cx,Driver_Paragraphs	; Number of paragraphs in GSX + Comm
	Shl	Cx,1			; *2
	Shl	Cx,1			; *4
	Shl	Cx,1			; *8 is number of words

	Mov	Ds,GSX_Seg1		; Move from GSX code

	Cld				; Increasing address
    Rep Movs	Es:(Word Ptr 0)[Di],Ds:(Word Ptr 0)[Si]; Move GSX-86 (& comm)

	Pop	Ds			; Point back to my DSeg

	Mov	Cx,MAXPROC+1		; Initialize table of 0..MAXPROC
	Mov	Bx,0			; Initial index of 0
	Mov	Dx,Unbound		; Flag for no driver bound

InitLoop:
	Mov	Es:HowBound[Bx],Dl	; No layer is bound
	Mov	Es:ModuleSize[Bx],0	;  nor of any size
	Add	Bx,16			; Bump to next entry
	Loop	InitLoop		; Loop until all entries initialized

	Mov	Es:GSX_Base,Es		; Save base of GSX in GSX

	Mov	Ax,All_Paragraphs	; Get length of GSX+Comm+Driver
	Mov	Es:GSX_Length,Ax	; Save it for later removal

	Mov	Ax,GSX_Paragraphs	; Get length of just GSX
	Add	Ax,Moved_GSX_Base	;  plus base of moved GSX
	Mov	Es:BasePageSegment+16,Ax;  is base of Comm to layer 1

	Mov	Bx,Comm_Paragraphs	; Length of comm
	Mov	Es:ModuleSize+16,Bx	;  to size slot in layer 1

	Add	Ax,Bx			; Ax <- base of driver
	Mov	Es:BasePageSegment,Ax	;  to layer 0

	Mov	Ax,Driver_Paragraphs	; Ax <- size of driver
	Mov	Es:ModuleSize,Ax	;  to layer 0

	Eject

	Push	Ds			; Save my Ds

	Sub	Ax,Ax			; Need access to interrupt vectors
	Mov	Ds,Ax

	Mov	Ax,Word Ptr Gdos_Vector+2; Get old interrupt 224 vector
	Mov	Es:(Word Ptr Old_Vector_0+2),Ax;  into save area

	Mov	Ax,Word Ptr Gdos_Vector+6; Get old interrupt 225 vector
	Mov	Es:(Word Ptr Old_Vector_1+2),Ax;  into save area

	Mov	Word Ptr Gdos_Vector+2,Es; New vector to new GSX
	Mov	Word Ptr Gdos_Vector+6,Es; New vector to new GSX

	Mov	Ax,Word Ptr Gdos_Vector	; Old vector
	Mov	Es:(Word Ptr Old_Vector_0),Ax;  into save area

	Mov	Ax,Word Ptr Gdos_Vector+4; Old vector
	Mov	Es:(Word Ptr Old_Vector_1),Ax;  into save area

	Mov	Word Ptr Gdos_Vector,Offset GSX_Entry_0		; Int 224 vect
	Mov	Word Ptr Gdos_Vector+4,Offset GSX_Entry_1	; Int 225 vect

	Mov	Ds,Es:BasePageSegment+16; Base of Comm in layer 1
	Mov	Dx,Offset GSX_Comm	; Offset in segment

	Mov	Cx,01373h		; Gdos "Bind Layer 1 Direct" function
	Int	Gdos_Int		; Bind the Comm driver to layer 1

	Pop	Ds			; Restore my Ds

	Mov	Dx,Default_Device	; Load default driver
	Mov	Cx,00173h		; Gdos "Bind Layer Indirect" function
	Int	Gdos_Int		; Bind default driver to layer 0

	Jz	GSX_Installed		; If no error, show GSX is installed

	Mov	Dx,Offset Load_Error	; Show "file load error"
I 2
	Mov	Bx,Sp			; Point to FCB
E 2
	Jmp	Error_Die		; Remove GSX, show status & quit

	Eject

GSX_Installed:
	Mov	Dx,Offset Installed_Msg_0; Point to "GSX-86 installed" message
	Mov	Cl,009h			; Bdos "Print String" function
	Callf	_GSX_Bdos		; Show status message

I 2
	Mov	Bx,Sp			; Point to FCB
	Call	Show_File		; Show the filename

	Mov	Dx,Offset Installed_Msg_1; Point to " is "
	Mov	Cl,009h			; Bdos "Print String" function
	Callf	_GSX_Bdos		; Show string

E 2
	Mov	Ax,Driver_Paragraphs	; Number of paragraphs in GIOS
	Mov	Dx,16			;  * 16 for number of bytes
	Mul	Dx			; Dx|Ax <- # bytes in driver
	Call	ShowDecimal		; Show dddddd digits

D 2
	Mov	Dx,Offset Installed_Msg_1; Point to " bytes long at " message
E 2
I 2
	Mov	Dx,Offset Installed_Msg_2; Point to " bytes long at " message
E 2
	Mov	Cl,009h			; Bdos "Print String" function
	Callf	_GSX_Bdos		; Show more of status message

	Mov	Es,Moved_GSX_Base	; Get base of GSX
	Mov	Dx,Es:BasePageSegment	; Get base of GIOS
	Call	ShowHex			; Show xxxx GIOS base address

D 2
	Mov	Dx,Offset Installed_Msg_2; Point to ":0000" message
E 2
I 2
	Mov	Dx,Offset Installed_Msg_3; Point to ":0000" message
E 2
	Mov	Cl,009h			; Bdos "Print String" function
	Callf	_GSX_Bdos		; Show :0000 offset of base page table

	Mov	Cl,000h			; Bdos "System Reset" opcode
	Sub	Dx,Dx			; Force func 58, free all
	Int	Bdos_Int		; Quit, leaving Gdos in

	Eject

; assume cp/m-86
Remove_GSX:
	Mov	Cl,032h			; Bdos "Direct Bios Call" function
	Mov	Dx,Offset Get_Mem_Map	; Point to Bios func and regs
	Callf	_GSX_Bdos		; Get offset of Mem Region Table

	Mov	MRT_Offset,Bx		; Save offset of MRT

	Mov	Cx,00673h		; Gdos "Return Layer 0 Ptr" function
	Int	Gdos_Int		; Try a Gdos call

	Cmp	Bx,Offset HowBound	; Gdos would return Offset HowBound
	Jne	GSX_Not_Here		; Jump if GSX not present

	Mov	Old_GSX_Base,Es		; Save base of old GSX
	Mov	Ax,Es:GSX_Length	; Paragraphs in old GSX
	Mov	Old_GSX_Paragraphs,Ax	;  to saver

	Push	Ds			; Save my Ds

	Sub	Ax,Ax			; Need int vect access
	Mov	Ds,Ax

	Mov	Ax,Es:(Word Ptr Old_Vector_0+2); Restore vectors
	Mov	Ds:(Word Ptr Gdos_Vector+2),Ax
	Mov	Ax,Es:(Word Ptr Old_Vector_0)
	Mov	Ds:(Word Ptr Gdos_Vector),Ax

	Mov	Ax,Es:(Word Ptr Old_Vector_1+2)
	Mov	Ds:(Word Ptr Gdos_Vector+6),Ax
	Mov	Ax,Es:(Word Ptr Old_Vector_1)
	Mov	Ds:(Word Ptr Gdos_Vector+4),Ax

	Pop	Ds			; Restore my Ds

	Mov	Ax,Old_GSX_Base		; Base of old GSX
	Add	Ax,Old_GSX_Paragraphs	; Paragraph AFTER old GSX

	Les	Bx,MRT_Ptr		; Point to Memory Region Table
	Mov	Di,1			; Start at first region
	Mov	Cl,Es:(Byte Ptr 0)[Bx]	; Get number of regions
	Mov	Ch,0			; High byte zero

Search_MRT_Loop:
	Cmp	Ax,Es:(Word Ptr 0)[Bx+Di]; GSX memory stolen from this entry?
	Je	MRT_Entry_Found		; Jump if entry found

	Add	Di,4			; Bump to next MRT entry
	Loop	Search_MRT_Loop		;  & loop until all scanned

	Pop	Dx			; Trash return address
	Mov	Dx,Offset Could_Not_Remove; Point to error message
	Jmp	Mem_Death		; Log message & quit

MRT_Entry_Found:
	Mov	Ax,Old_GSX_Paragraphs	; Get length of old GSX
	Sub	Es:(Word Ptr 0)[Bx+Di],Ax; Bump down base of region
	Add	Es:(Word Ptr 2)[Bx+Di],Ax; Bump up length of region

GSX_Not_Here:
	Ret				; Return to caller

	Eject

ShowCh:	Push	Bx			; Save ptr to Fcb
	Push	Cx			; Save loop count
I 5
	And	Dl,07fh			; Turn off high bit
E 5
	Mov	Cl,002h			; Bdos "Show Character" function
	Callf	_GSX_Bdos		; Show the character
	Pop	Cx			; Restore registers
	Pop	Bx
	Ret				;  & return

ShowChs:
	Mov	Dl,Ss:Byte Ptr .0[Bx]	; Get a byte to show
	Inc	Bx			; Bump ptr
	Call	ShowCh			; Show the byte
	Loop	ShowChs			; Loop until all shown
	Ret				;  & return

ShowHex:
	Call	Show2Hex		; Show left 2 characters

Show2Hex:
	Call	Show1Hex		; Show leftmost character

Show1Hex:
	Mov	Cl,4			; Shift count of 4
	Rol	Dx,Cl			; Top 4 bits of Dx to bottom
	Push	Dx			; Save rotated value

	And	Dl,00fh			; Mask to single digit
	Cmp	Dl,9			; a..f?
	Jbe	NotAF			; Jump if 0..9
	Add	Dl,7			; Bump a..f to 11..15

NotAF:	Add	Dl,'0'			; Make ascii
	Call	ShowCh			; Show it
	Pop	Dx			; Restore rotated value
	Ret				;  & return

; Show Dx:Ax in decimal. Maximum value is 655359.
ShowDecimal:
	Mov	Bx,10			; Decimal is base 10

Show_Left_Digits:
	Div	Bx			; Ax <- Dx:Ax/10, Dx <- rem

	Or	Ax,Ax			; More digits left?
	Jz	ShowDQ			; Jump if not

	Push	Dx			; Save digit
	Mov	Dx,0			; High half zero
	Call	Show_Left_Digits	; Show the remainder first
	Pop	Dx			; Restore digit this recurse found

ShowDQ:	Add	Dl,'0'			; Make it Ascii
	Call	ShowCh			; Show this recurse digit
	Ret				;  then return

I 2
Show_File:
	Push	Dx			; Save pointer to message

	Mov	Dl,Ss:Byte Ptr .0[Bx]	; Get drive
	Or	Dl,Dl			; Default?
	Jz	FOpNDrv			; Jump if no need to show d:

	Add	Dl,'@'			; Make drive a letter
	Call	ShowCh			; Show char in Dl
	Mov	Dl,':'			;  then ":"
	Call	ShowCh			;  for "d:"

FOpNDrv:
	Inc	Bx			; Point to filename
	Mov	Cx,8			; 8 characters of filename
	Call	ShowChs			; Show them
	Mov	Dl,'.'			; "."
	Call	ShowCh			; Show it
	Mov	Cl,3			; 3 characters of extension
	Call	ShowChs			; Show them

	Pop	Dx			; Get pointer to message back
	Ret				;  & return

E 2
Where_I_Am	Equ	(Offset $)-(Offset Graphics)+5	; 5 for Link86's Jmpf
		Rs	15-((Where_I_Am-1) And 0000fh)

Graphics_Paragraphs	Equ	((Offset $)-(Offset Graphics)+5)/16

	Eject

GSX_Code	CSeg	Byte	Public

		Extrn	GSX_Entry_0	:Far
		Extrn	Old_Vector_0	:DWord
		Extrn	GSX_Entry_1	:Far
		Extrn	Old_Vector_1	:DWord
		Extrn	GSX_Bdos	:Far
		Extrn	BI_Open_Assign	:Far
		Extrn	BI_Parse_Line	:Far
		Extrn	PSize		:Far
		Extrn	FClose		:Far

		Extrn	MAXPROC		:Abs

		Extrn	Default_Drive	:Byte
		Extrn	HowBound	:Byte
		Extrn	UnBound		:Abs
		Extrn	BasePageSegment	:Word
		Extrn	ModuleSize	:Word
		Extrn	GSX_Base	:Word
		Extrn	GSX_Length	:Word
		Extrn	GSX_End		:Byte

GSX_Comm_Code	CSeg	Para	Public

		Extrn	GSX_Comm		:Far

		Extrn	GSX_Comm_Paragraphs	:Abs

	Eject

Graphics_Data	DSeg	Para	Public

All_Paragraphs		Dw	0	; Number of paragraphs:  GSX+Comm+Gios

Loaded_GSX_Base		Dw	0	; Seg of GSX as loaded
Moved_GSX_Base		Dw	0	; Seg of GSX after being moved
GSX_Paragraphs		Dw	0	; Paragraphs in GSX only

Old_GSX_Base		Dw	0	; Seg of old GSX removed
Old_GSX_Paragraphs	Dw	0	; Paragraphs in old GSX (complete)

Comm_Paragraphs		Dw	0	; Paragraphs in GSX_Comm

Driver_Paragraphs	Dw	0	; Number of paragraphs in driver

Version_Number	Db	0		; Bdos version number

O_S_Type	Db	0		; 0: CP/M, 1: MP/M, 4: CCP/M

Default_Device	Dw	0		; Device Id from 1st ASSIGN.SYS line

No_Load		Db	0		; 1 if "Graphics No"

; CP/M-86 only
MRT_Ptr		Rd	0		; Ptr to Bios Memory Region Table
MRT_Offset	Dw	0		; Offset in OS of MRT
Bdos_Base	Dw	0		; Seg base of Bdos and Bios

Get_Mem_Map	Db	18		; Get memory map direct bios call
		Dw	0,0

M_Base		Dw	0		; Memory control block for Bdos
M_Length	Dw	0
		Db	0

; Dword ptrs fixed up at run time
_BI_Open_Assign	Rd	0
		Dw	Offset BI_Open_Assign
GSX_Seg1	Dw	0

_BI_Parse_Line	Rd	0
		Dw	Offset BI_Parse_Line
GSX_Seg2	Dw	0

_FClose		Rd	0
		Dw	Offset FClose
GSX_Seg3	Dw	0

_PSize		Rd	0
		Dw	Offset PSize
GSX_Seg4	Dw	0

_GSX_Bdos	Rd	0
		Dw	Offset GSX_Bdos
GSX_Seg5	Dw	0
	
Sign_On	Db	'--------------------------------------------------',13,10
D 3
	Db	'GSX-86  Graphics System Extension  09 Feb 83  V1.0',13,10
E 3
I 3
	Db	'GSX-86  Graphics System Extension  18 Mar 83  V1.1',13,10
E 3
D 4
	Db	'Serial No. G101-0000-654321    All Rights Reserved',13,10
E 4
I 4
	Db	'Serial No. xxxx-0000-654321    All Rights Reserved',13,10
E 4
	Db	'Copyright (c) 1983          Digital Research, Inc.',13,10
	Db	'--------------------------------------------------',13,10
	Db	'$'

Command_Error	Db	'^ syntax error$'

Close_Error	Db	' close error$'

Not_Found	Db	' not found$'

Syntax_Error	Db	' syntax error$'

Empty_Mess	Db	' empty$'

Abs_Driver	Db	' contains absolute segment$'

Death_Mess	Db	'Not enough memory for GSX-86$'

Load_Error	Db	' load error$'

Could_Not_Remove	Db	'Could not remove old GSX-86$'

Not_Installed_Msg	Db	13,10,'GSX-86 not installed$'

D 2
Installed_Msg_0	Db	'GSX-86 installed; GIOS is $'
Installed_Msg_1	Db	' bytes long at $'
Installed_Msg_2	Db	':0000$'
E 2
I 2
Installed_Msg_0	Db	'GSX-86 installed',13,10,'$'
Installed_Msg_1	Db	' is $'
Installed_Msg_2	Db	' bytes long at $'
Installed_Msg_3	Db	':0000$'
E 2

D 2
Stack		SSeg
E 2
I 2
Stack		SSeg	Word
E 2
		Rb	768
Top_Stack	Rb	0

		End
E 1
