;++
;
; Program to combine even/odd ROM images into one file.
;
; By John Wilson.
;
; 05/27/95	JMBW	Created.
;
;--
	.radix	8
;
lf=	12
cr=	15
;
libuf=	1024d		;length of input buffers
;
punt	macro	txt
	local	a,b
	call	punt1
a	db	b,txt,cr,lf
b=$-a-1
	endm
;
code	segment
	assume	cs:code
	org	100h
;
start:	cld			;DF=0
	cmp	sp,offset stkres ;enough memory for buffers and stack?
	jae	start1		;yes
	punt	'?Insufficient memory'
start1:	mov	si,80h		;point at JCL
	lodsb			;get length
	xor	ah,ah		;ah=0
	mov	cx,ax		;copy
	call	openr		;get source file 1
	jc	usage
	mov	ds:ihand1,ax	;save handle
	call	openr		;get source file 2
	jc	usage
	mov	ds:ihand2,ax	;save handle
	call	getw		;get output filename
	jc	lp1		;none, leave default handle alone
	xor	cx,cx		;mode=0
	mov	ah,3Ch		;func=create
	int	21h
	jc	crterr		;open error
	mov	ds:ohand,ax
	jmp	short lp1	;into loop
usage:	punt	'Usage:  COMBINE infile0 infile1 [outfile]'
crterr:	punt	'?File creation error'
;
lp1:	; read a bufferload from each input file
	mov	dx,offset ibuf1	;point at first buf
	mov	si,dx		;save a copy
	mov	cx,libuf	;length
	mov	bx,ds:ihand1	;handle
	mov	ah,3Fh		;func=read
	int	21h
	jc	rderr		;error
	mov	di,ax		;save actual byte count
	mov	dx,offset ibuf2	;pt at second buf
	mov	cx,libuf	;length
	mov	bx,ds:ihand2	;handle
	mov	ah,3Fh		;func=read
	int	21h
	jc	rderr
	cmp	di,ax		;lengths must match
	jne	badlen
	mov	cx,ax		;copy
	jcxz	eof		;EOF, done
	; combine into output buffer
	mov	di,offset obuf	;point at buf
	mov	dx,di		;with DX too
lp2:	mov	ah,[si+libuf]	;get odd byte
	lodsb			;get even byte
	stosw			;save word
	loop	lp2		;loop
	mov	cx,di		;get new ptr
	sub	cx,dx		;find # bytes written
	mov	bx,ds:ohand	;handle
	mov	ah,40h		;func=write
	int	21h
	jnc	lp1		;loop if successful
	punt	'?Write error'
eof:	int	20h		;let DOS close our files
rderr:	punt	'?Read error'
badlen:	punt	'?Input files are different lengths'
;+
;
; Get filename and open for reading.
;
; si,cx	cmd line descriptor (updated)
;
; On success, returns file handle in AX and CF=0.
; CF=1 if no filename in cmd line, program is aborted if file open error.
;
;-
openr:	call	getw		;get filename
	jc	openr1		;none, return
	mov	ax,3D00h	;func=open /RONLY
	int	21h
	jc	openr2		;error
openr1:	ret
openr2:	punt	'?File open error'
;+
;
; Display in-line string and abort program (called by PUNT macro).
;
;-
punt1:	pop	si		;pt at length
	lodsb			;get length
	cbw			;ah=0
	mov	dx,si		;copy string ptr
	mov	cx,ax		;copy length
	mov	bx,0002h	;STDERR
	mov	ah,40h		;func=write
	int	21h
	mov	ax,4C01h	;func=punt
	int	21h
;+
;
; Get a word from cmd line.
;
; si,cx	cmd line descriptor (updated on return)
;
; On return, CF=1 if no word found, otherwise DX points to .ASCIZ word.
;
;-
getw:	jcxz	getw2		;nothing, skip
getw1:	; skip white space
	lodsb			;get a char
	cmp	al,' '		;blank or ctrl char?
	ja	getw3		;no, start of word
	loop	getw1		;loop
getw2:	stc			;nothing
	ret
getw3:	dec	si		;back up to first char of word
	mov	dx,si		;save ptr
getw4:	; find end of word
	lodsb			;get a char
	cmp	al,' '		;blank or ctrl char?
	jbe	getw5		;yes, end of word
	loop	getw4		;loop
	inc	si		;correct for below
getw5:	dec	si		;un-get final char
	mov	byte ptr [si],0	;mark end (may punch out "CLD" at "START")
	clc			;happy
	ret
;
ohand	dw	1		;default output handle is STDOUT
;
ihand1	dw	1 dup(?)	;first input file handle
ihand2	dw	1 dup(?)	;second input file handle
;
ibuf1	db	libuf dup(?)	;input buffers
ibuf2	db	libuf dup(?)
obuf	db	(libuf*2) dup(?) ;output buffer
;
	dw	100h dup(?)	;reserve at least this much for stack
stkres	label	byte		;initial SP must be here or higher
;
code	ends
	end	start
