_DATA   segment word public 'DATA'
        DGROUP   GROUP  _DATA

	deldy	dw	0
	deldx	dw	0
	dels	dw	0
	delp	dw	0
	delsx	dw	0
	delsy	dw	0
	delse	dw	0
	delde	dw	0
        ctable  dw      0003fh,0403fh,0803fh,0c03fh
                dw      000cfh,010cfh,020cfh,030cfh
                dw      000f3h,004f3h,008f3h,00cf3h
                dw      000fch,001fch,002fch,003fch

_DATA   ends

_TEXT   segment word public 'CODE'
        assume CS:_TEXT, DS:DGROUP, SS:DGROUP

; setMod(mode)
;
; Function: Set the display mode using int 10
; Source:   Chesley and Waite, 1987, p 142.
;
        public setMod
        mode = 4

setMod  proc far
	push	bp
	mov	bp,sp
	push	si
	push	di
        mov     es,[bp+8]
        mov     bx,[bp+6]
        mov     al,[bx]
	mov	ah,0
	int	10h
	pop	di
	pop	si
	pop	bp
        ret     4
setMod  endp
;
; _egaDot
;
; Function: Write a color dot to the EGA screen.
;
;
        public _egaDot

_egaDot proc near
	push	ax
	push	bx
	push	cx
	push	dx
	push	ds
	mov	ax,si	;row
	mov	bx,di	;col
	mov	cx,dx	;color
	push	cx
	mov	cx,bx
	and	cl,7
	mov	ch,10000000b
	shr	ch,cl
	mov	dx,80
	mul	dx
	mov	cl,3
	shr	bx,cl
	add	bx,ax
	mov	ax,0a000h
	mov	ds,ax
	mov	dx,3ceh
	mov	ax,0005
	out	dx,ax
	pop	ax
	mov	ah,al
	mov	al,0
	out	dx,ax
	mov	ax,0f01h
	out	dx,ax
	mov	ah,ch
	mov	al,8
	out	dx,ax
	or	[bx],al
	mov	ax,0000
	out	dx,ax
	mov	ax,0001
	out	dx,ax
	mov	ax,0ff08h
	out	dx,ax
	pop	ds
	pop	dx
	pop	cx
	pop	bx
	pop	ax
	ret
_egaDot endp
;
; egaLin (x1,y1,x2,y2,color)
;
; Function: Draw a line on the screen in the 640 x 350 16 color EGA mode
; Reference: Morgan,1984, p 145.
;
        public egaLin

egaLin  proc far
	push	bp
	mov	bp,sp
	push	bx
	push	cx
	push	dx
	push	si
	push	di
	push	ax
	mov	si,1
	mov	di,1
        mov     es,[bp+24]
        mov     bx,es:[bp+14]
        mov     dx,[bx]      ;x2
        mov     bx,es:[bp+22]
        sub     dx,[bx]      ;x1
	jge	storey
	neg	di
	neg	dx
storey:
	mov	deldy,di
        mov     bx,es:[bp+10]
        mov     cx,[bx]     ;y2
        mov     bx,es:[bp+18]
        sub     cx,[bx]      ;y1
	jge	storex
	neg	si
	neg	cx
storex:
	mov	deldx,si
	cmp	cx,dx
	jge	setdiag
	mov	si,0
	xchg	cx,dx
	jmp	storedelsxy
setdiag:
	mov	di,0
storedelsxy:
	mov	dels,cx
	mov	delp,dx
	mov	delsx,si
	mov	delsy,di
        mov     bx,es:[bp+18]
        mov     si,[bx]       ;y1
        mov     bx,es:[bp+22]
        mov     di,[bx]       ;x1
	mov	ax,delp
	sal	ax,1
	mov	delse,ax
	sub	ax,cx
	mov	bx,ax
	sub	ax,cx
	mov	delde,ax
	inc	cx
        push    bx
        mov     bx,es:[bp+6]
        mov     dx,[bx]      ;color
        pop     bx
lineloop:
        call    _egaDot
	cmp	bx,0
	jge	diagonal
straight:
	add	si,delsx
	add	di,delsy
	add	bx,delse
	loop	lineloop
	jmp	lineexit
diagonal:
	add	si,deldx
	add	di,deldy
	add	bx,delde
	loop	lineloop
lineexit:
	pop	ax
	pop	di
	pop	si
	pop	dx
	pop	cx
	pop	bx
	pop	bp
        ret     40
egaLin  endp
;
; _cgaDot
;
; Function: Write a color dot to the CGA screen.
; Reference: Morgan, 1984, p 131.
;
        public _cgaDot

_cgaDot proc near
	push	ax
	push	bx
        push    si
        mov     ax,di   ;col
        mov     ah,al
        and     ax,01feh
        sal     ax,1
        sal     ax,1
        sal     ax,1
        mov     bx,ax
        and     bh,7
        sal     ax,1
        sal     ax,1
        add     bx,ax
        mov     ax,si   ;row
        sar     ax,1
        sar     ax,1
        add     bx,ax
        and     si,3
        sal     si,1
        sal     si,1
        add     si,dx   ;color
        sal     si,1
        mov     ax,ctable[si]
        and     al,es:[bx]
        or      al,ah
        mov     es:[bx],al
        pop     si
        pop     bx
        pop     ax
        ret
_cgaDot endp
;
; cgaLin (x1,y1,x2,y2,color)
;
; Function: Draw a line on the screen in the 320 x 200 4 color CGA mode
; Reference: Morgan,1984, p 145.
;
        public cgaLin

cgaLin  proc far
	push	bp
	mov	bp,sp
	push	bx
	push	cx
	push	dx
	push	si
	push	di
	push	ax
	mov	si,1
	mov	di,1
        mov     es,[bp+24]
        mov     bx,es:[bp+10]
        mov     dx,[bx]      ;y2
        mov     bx,es:[bp+18]
        sub     dx,[bx]      ;y1
        jge     cstorey
	neg	di
	neg	dx
cstorey:
	mov	deldy,di
        mov     bx,es:[bp+14]
        mov     cx,[bx]     ;x2
        mov     bx,es:[bp+22]
        sub     cx,[bx]      ;x1
        jge     cstorex
	neg	si
	neg	cx
cstorex:
	mov	deldx,si
	cmp	cx,dx
        jge     csetdiag
	mov	si,0
	xchg	cx,dx
        jmp     cstoredelsxy
csetdiag:
	mov	di,0
cstoredelsxy:
	mov	dels,cx
	mov	delp,dx
	mov	delsx,si
	mov	delsy,di
        mov     bx,es:[bp+22]
        mov     si,[bx]       ;x1
        mov     bx,es:[bp+18]
        mov     di,[bx]       ;y1
	mov	ax,delp
	sal	ax,1
	mov	delse,ax
	sub	ax,cx
	mov	bx,ax
	sub	ax,cx
	mov	delde,ax
	inc	cx
        push    bx
        mov     bx,es:[bp+6]
        mov     dx,[bx]      ;color
        mov     bx,0b800h
        mov     es,bx
        pop     bx
clineloop:
        call    _cgaDot
	cmp	bx,0
        jge     cdiagonal
cstraight:
	add	si,delsx
	add	di,delsy
	add	bx,delse
        loop    clineloop
        jmp     clineexit
cdiagonal:
	add	si,deldx
	add	di,deldy
	add	bx,delde
        loop    clineloop
clineexit:
	pop	ax
	pop	di
	pop	si
	pop	dx
	pop	cx
	pop	bx
	pop	bp
        ret     40
cgaLin  endp
;
; beep
;
; Function: Sound the PC speaker
; Reference: Bradley,1984, p 232.
;
        public beep
beep    proc far
        mov     al,10110110b
        out     43h,al
        mov     ax,1000
        out     42h,al
        mov     al,ah
        out     42h,al
        in      al,61h
        mov     ah,al
        or      al,3
        out     61h,al
        sub     cx,cx
kill_time:
        loop    kill_time
        mov     al,ah
        out     61h,al
        ret
beep    endp
_TEXT   ends
        end
