;++
;
; Quicky to convert a 128-byte binary file to a 512-byte (high nibble wasted)
; image of a 23-xxxA9-00 ROM, for the M9312 boot/term board.
;
; By John Wilson.
;
; Only the first 256 locations of the 512x4 PROMs are actually used, and
; they're a bit scrambled.  Every 4 nibbles is assembled on the fly by the
; M9312 to form one 16-bit word, however bits 0 and 8 are swapped, and bits
; 10/11/12 are inverted.  I guess it was convenient for the hardware, whatever.
;
; This program reads a raw binary file on standard input and writes on on
; standard output.  File sizes decide what to do:
;
; in				out
; 128-byte memory image		512-byte ROM image
; 512-byte ROM image		128-byte memory image
;
; 10/24/2000	JMBW	Created.
;
;--
	.radix	8		;natuurlijk
;
code	segment
	assume	cs:code
	org	100h
;
start:	cld			;DF=0
	; read the input file
	mov	dx,offset inbuf	;point at buf
	mov	cx,512d		;max we can read
	xor	bx,bx		;handle=STDIN
	mov	ah,3Fh		;func=read
	int	21h
	jc	error		;error
	mov	si,dx		;init buf ptrs
	mov	di,offset outbuf
	cmp	ax,cx		;512 bytes?
	mov	cx,64d		;[64 words no matter what]
	je	rommem		;yes, go convert
	cmp	ax,128d		;other choice is 128 bytes
	jne	error		;nope
	jmp	short memrom	;convert
;
error:	; some kind of error has ocurred, give a non-helpful message and die
	mov	dx,offset errmsg ;point at msg
	mov	cx,lermsg	;length
	mov	bx,0002h	;handle=STDERR
	mov	ah,40h		;func=write
	int	21h		;(ignore errors, what could we do)
	mov	ax,4C01h	;func=punt
	int	21h
;
rommem:	; convert ROM format to memory image
	lodsw			;get two nybbles
	and	ax,0F0Fh	;make sure isolated
	mov	dx,ax		;copy
	lodsw			;get two more nybbles
	and	ax,0F0Fh	;same deal
	push	cx		;save
	mov	cl,4		;shift count
	shl	ah,cl		;left-justify odd nybbles
	shl	dh,cl
	pop	cx		;restore
	or	ah,al		;combine
	or	dh,dl
	mov	al,dh		;compose word
	call	cvt		;convert it
	stosw			;save
	loop	rommem		;do all 64 words
	jmp	short write
;
memrom:	; convert memory format to ROM image
	lodsw			;read a word
	call	cvt		;convert it
	mov	dl,ah		;copy high byte
	mov	dh,ah
	mov	ah,al		;copy low byte
	push	cx		;save
	mov	cl,4		;shift count
	shr	ah,cl		;right-justify
	shr	dh,cl
	pop	cx		;restore
	and	al,0Fh		;isolate low nybbles
	and	dl,0Fh
	stosw			;save low two nybbles
	mov	ax,dx		;and high two nybbles
	stosw
	loop	memrom		;do all 64 words
	xor	al,al		;load 0
	mov	cx,256d		;pad with 256. bytes of zeros
	rep	stosb		;(2nd half of ROM not used)
;
write:	; write to output file
	mov	dx,offset outbuf ;pt at buf
	mov	cx,di		;get ptr
	sub	cx,dx		;find # bytes to write
	mov	bx,0001h	;handle=STDOUT
	mov	ah,40h		;func=write
	int	21h
	jc	error		;failed
	int	20h		;happy
;+
;
; Convert a word between ROM and memory version.
;
; Exchange bits 0 and 8, and invert bits 10, 11, and 12.
;
; ax	word to convert (returned in AX)
; dx	destroyed, others preserved
;
;-
cvt:	mov	dx,ax		;copy
	and	dx,101h		;isolate bits 0 and 8
	xor	ax,dx		;remove from original
	xchg	dl,dh		;exchange
	or	ax,dx		;insert
	xor	ah,16000/400	;flip bits 10-12
	ret
;
errmsg	db	'?Error',15,12
lermsg=	$-errmsg
;
inbuf	db	512d dup(?)	;input buffer
outbuf	db	512d dup(?)	;output buffer
;
code	ends
	end	start
