; ------------------------------------------------
; DMP130.ASM
;
; Version 1.0
;
; Hercules Dump Driver For Tandy DMP130 Printer
;
; Copyright (C) 1993, Geoff Friesen B.Sc.
; All rights reserved.
;
; Developed with: TASM 3.0
;
; Use the following commands to create DMP130.HDD.
; TASM DMP130
; TLINK DMP130
; EXE2BIN DMP130 DMP130.HDD
; ------------------------------------------------

_TEXT		SEGMENT	BYTE PUBLIC 'CODE'
		ASSUME	cs:_TEXT, ds:_TEXT, es:_TEXT, ss:_TEXT
		ORG	0

CR		EQU	13
_ESC		EQU	27
LF		EQU	10
LPT1		EQU	0
VLAST		EQU	VSIZE-VXTRA
VSIZE		EQU	352
VXTRA		EQU	VSIZE MOD 8

begin:
		push	bx
		push	cx
		push	dx
		push	si
		push	di
		push	bp
		push	ds
		push	es

		push	cs
		pop	ds

		push	cs
		pop	es

		call	NEAR PTR hdump

		pop	es
		pop	ds
		pop	bp
		pop	di
		pop	si
		pop	dx
		pop	cx
		pop	bx
		mov	ax, 0

		retf

; ------------
; Data Section
; ------------

buffer		DB	720 DUP (?)
lpt		DW	LPT1
powers		DB	128, 64, 32, 16, 8, 4, 2, 1

; -------------------------------------------
; DUMPLINE: Dump line of graphics to printer.
; -------------------------------------------

dumpline	PROC	NEAR
		mov	al, _ESC	; Set 120 DPI Bit Image mode.
		call	printer

		mov	al, 'L'
		call	printer

		mov	al, 208
		call	printer

		mov	al, 2
		call	printer

		xor	bx, bx		; I = 0.
dumpline1:
		mov	al, buffer [bx]	; Print buffer byte.
		call	printer

		inc	bx		; I = I+1.

		cmp	bx, 720		; I = 720?
		jb	dumpline1	; No, branch.

		mov	al, CR		; Advance to start of next line.
		call	printer

		mov	al, LF
		call	printer

		ret
dumpline	ENDP

; ------------------------------------------------
; HDUMP: Dump hercules graphics screen to printer.
; ------------------------------------------------

hdump		PROC	NEAR
		mov	al, _ESC	; Set 8/72 line spacing
		call	printer

		mov	al, 'A'
		call	printer

		mov	al, 8
		call	printer

		mov	al, _ESC
		call	printer

		mov	al, '2'
		call	printer

		xor	di, di		; ROW = 0.
hdump1:
		xchg	di, bx

		mov	cx, 720		; Zero buffer.
		lea	di, buffer
		mov	al, 0
		rep	stosb

		xchg	di, bx

		xor	si, si		; COL = 0.
hdump2:
		xor	bx, bx		; I = 0.
hdump3:
		add	di, bx		; ROW+I
		call	point		; Get pixel on/off status.
		sub	di, bx		; ROW-I
		and	al, powers [bx]	; Convert it to power of two.
		add	buffer [si], al	; Update pin tally.

		inc	bx		; I = I+1

		cmp	bx, 8		; I = 8?
		jb	hdump3		; No, branch.

		inc	si		; COL=COL+1

		cmp	si, 720		; COL = 720?
		jb	hdump2		; No, branch.

		call	dumpline	; Dump graphics line to printer.

		add	di, 8		; ROW = ROW+8

		cmp	di, VLAST	; ROW = VLAST?
		jb	hdump1		; No, branch.

IF VXTRA NE 0

; -------------------------------------------------------------
; The follow code would only be needed if your Hercules adaptor
; has a maximum of 348 rows instead of 352.
; -------------------------------------------------------------

; -------------------------------
; Dump final four rows (344-347).
; -------------------------------

		xchg	di, bx

		mov	cx, 720		; Zero buffer.
		lea	di, buffer
		mov	al, 0
		rep	stosb

		xchg	di, bx

		xor	si, si		; COL = 0.
hdump4:
		xor	bx, bx		; I = 0.
hdump5:
		add	di, bx		; ROW+I
		call	point		; Get pixel on/off status.
		sub	di, bx		; ROW-I
		and	al, powers [bx]	; Convert it to power of two.
		add	buffer [si], al	; Update pin tally.

		inc	bx		; I = I+1

		cmp	bx, VXTRA	; I = 4?
		jb	hdump5		; No, branch.

		inc	si		; COL=COL+1

		cmp	si, 720		; COL = 720?
		jb	hdump4		; No, branch.

		call	dumpline	; Dump graphics line to printer.

ENDIF

		mov	al, _ESC	; Restore 1/6 " LF pitch.
		call	printer

		mov	al, 'A'
		call	printer

		mov	al, 12
		call	printer

		mov	al, _ESC
		call	printer

		mov	al, '2'
		call	printer

		ret
hdump		ENDP

; -------------------------------
; POINT: Get pixel on/off status.
;
; Entry: SI = X coordinate
;        DI = Y coordinate
;
; Exit:  AL = 255 (pixel on)
;        AL = 0 (pixel off)
; -------------------------------

point		PROC	NEAR
		push	bx
		push	es

		mov	ax, di
		mov	bx, si
		mov	cx, bx
		mov	dx, ax
		shr	ax, 1
		shr	ax, 1
		mov	cl, 90
		mul	cl
		and	dl, 3
		shl	dl, 1
		shl	dl, 1
		shl	dl, 1
		shl	dl, 1
		shl	dl, 1
		add	ah, dl
		mov	dx, bx
		shr	dx, 1
		shr	dx, 1
		shr	dx, 1
		add	dx, ax
		and	bx, 7
		mov	cl, 7
		sub	cl, bl
		mov	al, 1
		shl	al, cl
		mov	bx, dx
		mov	dx, 0b000h
		mov	es, dx
		mov	cl, es:[bx]
		and	cl, al
		mov	al, cl
		or	al, al
		jz	point1

		mov	al, 255
point1:
		pop	es
		pop	bx
		ret
point		ENDP

; --------------------------------------
; PRINTER: Send character to printer.
;
; Entry: AL = character to print.
;
; Printing is accomplished through LPT1.
; --------------------------------------

printer		PROC	NEAR
		push	bx
		push	si
		push	di

		mov	dx, lpt		; Get lpt port.
		mov	ah, 0		; Print byte.
		int	17h		; Use printer BIOS.

		pop	di
		pop	si
		pop	bx
		ret
printer		ENDP

_TEXT		ENDS
		END	begin