;   FILENAME: DISPLAY.ASM
;

jumps      ; Have TASM automatically resolve out of range jumps

%tabsize 4

ifndef  MDL
    display "Error: This module requires that you provide a memory model"
    display "    definition on the command line. I.E. /dMDL=SMALL."
    err ; Force a fatal error
else

model	MDL,pascal	       ; Define the memory model

ideal

P286

include "globals.inc"

dataseg

OrigMemory	dw	0
CursorType      dw      0
Screen		dw	0B800h
OldMode 	db	0
CurMode 	db	0

kline		db	"Oł xxxk/xxxk",0
kline2		db	"xxxk",0
repstr		db	" ~  ",0

codeseg

proc	HowMuchMemory
	mov	ah,48h
	mov	bx,0FFFFh
	int	21h
        shr     bx,6
	mov	[OrigMemory],bx
	ret
endp    HowMuchMemory

proc    RestoreMode
	xor	ah,ah
	mov	al,[OldMode]
	int	10h
	ret
endp    RestoreMode

proc	SetMode
	xor	ah,ah
	mov	al,[CurMode]
	int	10h
	ret
endp    SetMode

proc    DetermineDisplay
	mov	ax,0f00h
	int	10h
	mov	[OldMode],al
	cmp	al,7			; Are we in monochrome mode?
	jz	@@Monochrome
	mov	[Word Screen],0B800h
	mov	[Word CursorType],0607h
	mov	[Byte CurMode],3
	ret
@@Monochrome:
	mov	[Word Screen],0B000h
	mov	[Word CursorType],0B0Ch
	mov	[Byte CurMode],7
	ret
endp    DetermineDisplay

proc	SetCursor   ScanLines:word
	mov	cx,[ScanLines]
	mov	[CursorType],cx
	mov	ax,0100h
	int	10h
	ret
endp	SetCursor

proc	WriteCol	X:word,Y:word,String:dword
	uses	ds,es,si,di,cx
	mov	ax,@data
	mov	ds,ax
	mov	es,[Screen]
        mov     ax,NumCols * 2           ; NumCols * 2
	mul	[Y]
	add	ax,[X]
	add	ax,[X]
	mov	di,ax

	lds	si,[String]
        mov     ax,bx
	jmp	ActualWritePart
endp	WriteCol

proc    Write   X:word,Y:word,String:dword
	uses	ds,es,si,di,cx
	mov	ax,@data
	mov	ds,ax
	mov	es,[Screen]
        mov     ax,NumCols * 2           ; NumCols * 2
	mul	[Y]
	add	ax,[X]
	add	ax,[X]
	mov	di,ax

	lds	si,[String]
	lodsb
ActualWritePart:
	mov	ah,al
	xor	cx,cx
	xor	dx,dx
; Translate
@@MainLoop:
	lodsb
	cmp	al,0
	jz	@@Done
	cmp	al,'`'
	jnz	@@CheckRepeat
	lodsb
	mov	ah,al
	jmp	@@MainLoop
@@CheckRepeat:
	cmp	al,'~'
	jnz	@@JustStore
	lodsb
	mov	cl,al
	lodsb
	rep	stosw
	add	dx,cx
	jmp	@@MainLoop
@@JustStore:
	inc	dx
	stosw
	jmp	@@MainLoop
@@Done:
	ret
endp    Write

proc	WriteChars	X:word,Y:word,String:dword,MaxLen:word
	uses	ds,si,es,di
	call	WriteCol,[X],[Y],[String]
	push	bx
	mov	cx,[MaxLen]
	sub	cx,dx
	jz	@@Done
	mov	di,offset repstr
	mov	bx,seg repstr
	mov	es,bx
	add	di,2
	mov	ax,cx
	stosb
	mov	ax,[X]
	add	ax,dx
	pop	bx
	call	WriteCol,ax,[Y],seg repstr,offset repstr
@@Done:
	ret
endp	WriteChars

proc	ConvertKtoStr	NumK:word,String:dword,NumDigits:word
	uses	es,di
	les	di,[String]
	mov	ax,[NumK]
	mov	cx,[NumDigits]
	dec	cx
	add	di,cx
	inc	cx
@@NumLoop:
	mov	bl,10
	div	bl
	add	ah,'0'
	mov	[es:di],ah
	dec	di
	xor	ah,ah
	loop	@@NumLoop

@@Done: ret
endp	ConvertKToStr

proc    WriteMemLeft    Row:word
	uses	ds,es
	mov	ax,@data
	mov	ds,ax
	mov	ah,48h
	mov	bx,0FFFFh
	int	21h
	shr	bx,6
	call	ConvertKToStr,[OrigMemory],seg kline,offset kline+8,3
        call    ConvertKToStr,bx,seg kline,offset kline+3,3
	call	Write,68,[Row],seg kline,offset kline
	ret
endp	WriteMemLeft

proc	FillBox X:word,Y:word,SizeX:word,SizeY:word,Color:word
	uses	ds,es,di,cx
	mov	ax,@data
	mov	ds,ax
	mov	es,[Screen]
        mov     ax,NumCols * 2           ; NumCols * 2
	mul	[Y]
	add	ax,[X]
	add	ax,[X]
	mov	di,ax

	mov	ax,[Color]
	mov	bx,[SizeY]
@@TopLoop:
	push	di
	mov	cx,[SizeX]
	rep	stosw
	pop	di
	add	di,NumCols*2
	dec	bx
	jnz	@@TopLoop
	ret
endp	FillBox

endif   ; ifndef MDL

end

