;
;calculate wpm for the game
;
wpm		proc
;		assume	cs:codesg,ds:datasg,es:nothing
		;
		;first get a clock tick
		;
		call	clock
		sub	bx,gamtim[+2]
		mov	gamtim[+2],bx
		sbb	cx,gamtim
		;
		cmp	cx,0		;don't calculate if user has
		je	okwpm		;waited longer than 1 minute to
		mov	ax,0		;get here ... should be impossible,
		jmp	wpm_exit	;... meaning a programming error

okwpm:		cmp	gamtim[+2],0
		je	wpm_exit2

		mov	ax,gamcharcnt	;wpm = 0 if no characters typed
		cmp	ax,0
		je	wpm_exit
		;
		mul	word ptr n1200	;1,200 = ((60 secs/min)
					;	X (100 ticks/sec)
					;	/ (5 chars/word)
under120:	div	word ptr gamtim[+2] ; / 100ths of a second = chars/min
wpm_exit:	mov	gamewpm,ax
wpm_exit2:	mov	gamcharcnt,0
		call	clock
		mov	gamtim[+2],bx
		mov	gamtim,cx
		ret
wpm		endp
;
;evaluate routine follows
;
;include		evaluate.asm
;************************************************************************
;* FUNCTION: XYCalc()							*
;*									*
;* PARAMETERS:								*
;*	Dx - X position on screen. (0..319)				*
;*	Di - Y position on screen. (0..199)				*
;*									*
;* DESCRIPTION: Calculates byte address of X, Y.  Result is in Di, Dx	*
;*		where Di is current line address of RowTable and Dx is	*
;*		the X byte offset.					*
;************************************************************************

XYCalc_ 	PROC	NEAR

	Mov	Es,VideoSeg

	Shr	Dx,1
	Shr	Dx,1
	shr	dx,1	;for 40 col modes

	Shl	Di,1
	Lea	Di,RowTable[Di]
	Ret

XYCalc_ 	ENDP
;************************************************************************
;* FUNCTION: PrintAt  ( X, Y, Str )					*
;*									*
;* PARAMETERS:								*
;*	X   - X position of string.  0..319 is really 0..79.		*
;*	Y   - Y position of string.  0..199				*
;*	Str - Points to the string we are to print.			*
;*									*
;* DESCRIPTION: Prints a string at the given coordinates.		*
;************************************************************************

PrintAt_	PROC  NEAR

;	Mov	Bx,Sp		;Set Bx to base of parms.
;
	shl	dx,1	;<-test
	shl	dx,1	;""
	shl	dx,1	;""
	shl	dx,1
	mul	byte ptr eight ;""

	Push	Si
	jmp	getch
	db	'uku'
;	Mov	Dx,2[Bx]	;Get X
;	Mov	Ax,4[Bx]	;Get Y
;	Mov	Si,6[Bx]	;Get char pointer

GetCh:				;WHILE ( *Pt )
				;   BEGIN
	Xor	Ch,Ch		;   Make sure Ch is 0
	Mov	Cl,[Si] 	;   Acquire the next char to draw
	Jcxz	ExitPrintAt	;   Exit if we've found the null char

;taken out so printat will display $ symbols in game text
;	cmp	cl,'$'          ;   or a $ - for compatability with DOS
;	je	exitprintat	;   string print call.

	Push	Ax
	Push	Dx
	Push	Cx
	Call	APutChar	;   APutChar( Dx, Ax, Cx );
	Pop	Cx
	Pop	Dx
	Pop	Ax

	Inc	Si		;   Pt++;
	Add	Dx,16 ;8		;   X += 8;
;	Cmp	Cx,'~'          ;   IF ( ReturnArrow ) THEN
;	Jne	Norm		;      BEGIN
;	Add	Dx,8		;      X += 8;
;	Inc	Si		;      Pt++;
				;      END
Norm:	Jmp	SHORT GetCh	;   END

ExitPrintAt:
	Pop	Si
	Ret			; Return to the caller.

PrintAt_ ENDP


;************************************************************************
;* FUNCTION: PutChar( X, Y, Ch )					*
;*									*
;* PARAMETERS:								*
;*	X  - X position of Character.  0..319 is really 0..79.		*
;*	Y  - Y position of Character.  0..199				*
;*	Ch - The character we are to put on the screen. 		*
;*									*
;* DESCRIPTION: Puts the given character on screen.			*
;************************************************************************

CharTable	EQU	0FA6EH		;Base of graphics character table
					;NOTE: hardware dependent

PutChar_	PROC	NEAR

	Mov	Bx,Sp		;Set BX to base of parms.

	Mov	Dx,2[Bx]	;Get X
	Mov	Ax,4[Bx]	;Get Y
	Mov	Cx,6[Bx]	;Get Char

APutChar:
;	Cmp	Cx,'~'          ;IF ( ReturnArrow ) THEN
;	Jne	NormCh		;   DrawSpecial( 3 );
;	Mov	Cx,3
;	Call	ADrawSpecial
;	Ret

NormCh: Push	Si		;Save Registers
	Push	Di
	Push	Es
	Push	Bp

	Mov	Di,Ax
	Call	XYCalc_ 	;Get offset at which to draw the Char
	Mov	Bp,Di

	Mov	Si,Cx		;Point Si at the char in table
	Shl	Si,1
	Shl	Si,1
	Shl	Si,1
	Add	Si,CharTable

	Cld			;Direction = forward
	Mov	Cx,8		;8 byte character set

NextCharRow:			;DO

	Mov	Di,ds:[Bp]	;   Get row pointer <-was using ss:!!!
	Add	Di,Dx

	Push	Ds
	Mov	Ax,0F000H	;   Set DS register to the base
	Mov	Ds,Ax		;   of last memory ROM segment.
	Lodsb			;   Acquire a byte(pixel map) of the Char
	Pop	Ds

	Call	StoreByte	;   Put the byte in screen memory

	Add	Bp,2		;   END
	Loop	NextCharRow	;WHILE( --Cx );

	Pop	Bp
	Pop	Es
	Pop	Di		;Save Registers
	Pop	Si

	Ret

PutChar_	ENDP
;************************************************************************
;* FUNCTION: StoreByte							*
;*									*
;* PARAMETERS:								*
;*  Reg Al - The byte we are to store.					*
;*	Es:Di - Points to the screen memory where we are to store byte. *
;*									*
;* DESCRIPTION: Takes the byte in Al, converts it to a 16 bit value and *
;*		then masks the color bits to the current 'ColorMask'.   *
;*		Di is incremented by 2 on exit. 			*
;************************************************************************

StoreByte	PROC	NEAR

	Call	ExpandByte_	;Convert to word
	Xchg	Ah,Al
	And	Ax,ColorMask
	Stosw			;Put the Char into graphics memory
	Ret

StoreByte	ENDP

;************************************************************************
;* FUNCTION: ExpandByte()						*
;*									*
;* PARAMETERS:								*
;*	TheByte - Byte to be expanded in Al register.			*
;*									*
;* DESCRIPTION: Expands a byte into a word.				*
;************************************************************************

ExpandByte_	PROC	NEAR

	Push	Bx
	Lea	Bx,ExpandTable
	Mov	Ah,Al		;Save a copy in Ah
	Shr	Al,1		;a 16 bit character bit map.
	Shr	Al,1
	Shr	Al,1
	Shr	Al,1
	Xlatb			;Take the 8 bit pattern
	Xchg	Ah,Al		;and translate it into
	And	Al,00FH
	Xlatb
	Pop	Bx
	Ret

ExpandByte_	ENDP
plot		proc	near
		;
		;position cursor at locx, locy
		;
		mov	dh,locy
		mov	dl,locx

		cmp	gamevmode,1
		jne	plot_exit

		mov	ah,2
		mov	bh,0
		int	10h		;position on screen

plot_exit:	ret

plot		endp
char_write	proc	near
		;
		;Write char in AL at cursor position for mono
		;or at position held in dx for graphics.
		;Used after call to plot.
		;
		cmp	gamevmode,1
		jne	herc_cga

		mov	ah,9
		mov	bh,0
		mov	bl,att_byte
		mov	cx,1
		int	10h
		ret

herc_cga:	mov	colormask,0ffffh
		mov	cl,al
		mov	al,dh
		cbw
		xor	dh,dh
		xor	ch,ch
		shl	ax,1
		shl	ax,1
		shl	ax,1
		shl	dx,1
		shl	dx,1
		shl	dx,1
		shl	dx,1
		call	aputchar
		ret
char_write	endp
;$PAGE
;************************************************************************
;* FUNCTION: DoHerc()							*
;*									*
;* PARAMETERS:	None							*
;*									*
;* DESCRIPTION: Checks to see if the Hercules mono graphics adapter is	*
;*		there and if it is, it inits it and sets RowTable data	*
;*		table up accordingly.  Uses vertical rettrace check to	*
;*		to insure that a card is there. 			*
;*									*
;* RETURNS:	Carry set if card is not there. 			*
;************************************************************************

DoHerc		PROC	NEAR

	Mov	Dx,03BFH		;Turn on Herc card
	Mov	Al,00000011B
	Out	Dx,Al

	Mov	Bl,OldFlag		;Get OldFlag
	Push	Ds			;Restore old equipment flag
	Mov	Ax,EquipSeg
	Mov	Ds,Ax
	Mov	ds:[EquipFlag],Bl
	Pop	Ds

	Mov	Dx,3BAH 		;Display status port for Herc
	Mov	Bl,10000000B		;Vertical retrace mask bit for Herc card
	;Call	CheckRetrace
	;Jnc	InitHerc

	;Stc
	;Ret

InitHerc:

	Mov	GrAdapterType_,HERCCARD

	Push	Si
	Push	Di

	Mov	Cx,50			;Do 50 groups of 4
	Lea	Bx,RowTable		;Point to table
	Mov	Si,0658H		;Line 0 + 8 byte offset Screen center
	Mov	Di,2658H		;Line 1 + 8 byte offset Screen center
	Mov	Ax,4658H		;Line 2 + 8 byte offset Screen center
	Mov	Dx,6658H		;Line 3 + 8 byte offset Screen center

TLoop1: Mov	[Bx],Si 		;Store 4 words
	Mov	[Bx+2],Di
	Mov	[Bx+4],Ax
	Mov	[Bx+6],Dx

	Add	Si,90			;Add 90 for next line of 4
	Add	Di,90
	Add	Ax,90
	Add	Dx,90

	Add	Bx,8			;Move to next 4 pointers
	Loop	TLoop1			;Loop for all rows

	Call	ClearScreen_

	Lea	Si,GTable		;Ptr to Herc card init table
	Call	SetParams		;Set the Herc card params.

	Mov	Dx,3B8H 		;Set Ctrl Reg for scrn on,
	Mov	Al,10001010B		;Bit 1 - gr mode, Bit 3 - activate scrn
	Out	Dx,Al			;Bit 7 - display page B800H

	Pop	Di
	Pop	Si

	Clc				;Clear carry to show that herc is there
	Ret

SetParams:
	Mov	Dx,3B4H 		;Index register position
	Mov	Cx,12			;Move 12 parameters to data registers
	Xor	Ah,Ah			;Start with register 0
Parms:
	Mov	Al,Ah			;Send reg number to index reg 3B4H
	Out	Dx,Al

	Inc	Dx			;Now send data to data reg 3B5H
	Lodsb
	Out	Dx,Al

	Inc	Ah
	Dec	Dx
	Loop	Parms

	Ret

DoHerc		ENDP
;$PAGE
;************************************************************************
;* FUNCTION: ClearScreen()						*
;*									*
;* PARAMETERS:								*
;*	None -								*
;*									*
;* DESCRIPTION: Clears the graphics screen				*
;************************************************************************

ClearScreen_	PROC	NEAR

	Push	Di
	Push	Es

	Mov	Es,VideoSeg

	Mov	Cx,4000H		;Word count of entire screen
	Mov	Ax,0			;Write null pattern to screen
	Mov	Di,Ax			;Start at screen address 0
	Cld				;Set direction to forward
	Rep	Stosw			;Clear screen a word at a time

	Pop	Es
	Pop	Di
	Ret

ClearScreen_	ENDP
begin	endp
codesg	ends
	end	begin
