		title	'MAKE Utility for CP/M Plus'

; Purpose : emulate a Microsoft-type MAKE for CP/M Plus
; Author  : Wolfgang Muees, Hagenring 22, D-3300 Braunschweig
; Version : April 12, 1989

; Sequence to generate a running MAKE.COM :

; RMAC make.asm $sz pz
; RMAC makersx.asm $sz pz
; ERA make.com
; LINK make[nl,nr]
; LINK makersx[nl,nr,op]
; ERA make.rel
; ERA makersx.rel
; REN makersx.rsx=makersx.prl
; GENCOM make makersx
; ERA makersx.rsx

; Format of make file :

; <object> : <source1> <source2> .... <sourceN>
;          <command line>
;	   <more command lines>
; <empty line>
; <;comment line>

; if the list of sources exceeds a CP/M input line, terminate line with '\'
; and continue list on next line. The command line is send to CCP.
; The empty line is optional.

BDOS		equ	5		; link to BDOS
NAME$OFFSET	equ	10		; start of name - start of code
FCB$OFFSET	equ	21		; start of FCB  - start of code
REMOVE$OFFSET	equ	8		; remove flag   - start of code
WBOOT		equ	0		; return to CCP
PRINTS		equ	9		; print string
RETVER		equ	12		; return version number
OPENF		equ	15		; open file
SETDMA		equ	26		; set DMA address
SETUSR		equ	32		; set/get user number
SETPRC		equ	108		; set program return code
FCB1		equ	5CH		; file control block for make file
COMLINE		equ	80H		; byte count of command line
PARFCB		equ	152		; parse name into FCB

		cseg

TPA:		jmp	start
		db	'CP/M Plus MAKE utility by W.Muees 1989'

start:		mvi	c,RETVER	; test for CP/M Plus
		call	BDOS
		mvi	a,2FH		; must be >= 30H
		cmp	l
		jnc	wrong$version

		lda	COMLINE		; call without parameter ?
		ora	a
		jz	give$help

		lhld	BDOS+1		; get address of RSX
		lxi	d,NAME$OFFSET
		dad	d		; HL -> name field of RSX
		lxi	d,test$name
		mvi	b,8		; test name field
test$loop:	ldax	d
		cmp	m
		jnz	wrong$rsx
		inx	d
		inx	h
		dcr	b
		jnz	test$loop
		
		mvi	c,SETUSR	; get default (ccp) user number
		mvi	e,0FFH
		call	BDOS
		sta	default$user

parse$name:	lxi	h,COMLINE+1	; leading user number ?
		mvi	b,0		; character count

search$colon:	mov	a,m		; colon ?
		cpi	':'
		jz	colon$found
		inx	h
		inr	b
		ora	a		; end of buffer ?
		jnz	search$colon

set$default:	lda	default$user	; file user number = actual user number
		sta	make$user
		lxi	h,COMLINE+1	; parse from beginning
		shld	pfcb
		jmp	parse$file

colon$found:	shld	pfcb		; start parsing at first non-digit char
		dcx	h		; test char before colon
		dcr	b
		jm	set$default	; nothing before colon
		mov	a,m		; digit ?
		sui	'0'
		jc	colon$found
		cpi	10
		jnc	colon$found
		mov	c,a		; store digit in c
		dcx	h		; test char before digit ?
		dcr	b
		jm	store$user	; nothing before this digit
		mov	a,m		; digit ?
		cpi	' '		; space ?
		jz	store$user
		sui	'0'
		jc	open$error	; no: error in filename format
		cpi	10
		jnc	open$error
		add	a		; A := A * 10
		mov	b,a
		add	a
		add	a
		add	b
		add	c		; + c
		mov	c,a

store$user:	lxi	h,make$user	; store user number of tested file
		mov	m,c
		
parse$file:	lhld	pfcb		; skip colon
		mov	a,m
		cpi	':'
		jnz	parse$it
		inx	h
		shld	pfcb

parse$it:	mvi	c,PARFCB	; parse filename
		lxi	d,pfcb		
		call	BDOS

		lxi	d,FCB1+16	; copy password before opening file
		lxi	h,PASSWORD
		mvi	b,8		; length of password
pass$loop:	ldax	d
		mov	m,a
		inx	d
		inx	h
		dcr	b
		jnz	pass$loop
	
		mvi	c,SETDMA	; set DMA address to password
		lhld	PASSWORD
		xchg
		call	BDOS
		
		mvi	c,SETUSR
		lda	make$user
		mov	e,a
		call	BDOS

		mvi	c,OPENF		; open make file
		lxi	d,FCB1
		call	BDOS

		push	psw
		mvi	c,SETUSR
		lda	default$user
		mov	e,a
		call	BDOS
		pop	psw

		ora	a
		jnz	open$error

		lhld	BDOS+1		; copy FCB1 into RSX
		lxi	d,FCB$OFFSET
		dad	d
		lxi	d,FCB1
		mvi	b,36		; length of FCB
move$loop:	ldax	d
		mov	m,a
		inx	d
		inx	h
		dcr	b
		jnz	move$loop

		lda	make$user	; copy user number
		mov	m,a

lock$rsx:	lhld	BDOS+1		; install MAKERSX RSX permanent
		lxi	d,REMOVE$OFFSET
		dad	d
		mvi	m,0

exit:		mvi	c,WBOOT		; exit to CCP
		jmp	BDOS

open$error:	mvi	c,PRINTS	; print error string
		lxi	d,open$msg
		call	BDOS

error$exit:	mvi	c,SETPRC	; set program return code = failed
		lxi	d,0FF00H
		call	BDOS
		jmp	exit

wrong$rsx:	mvi	c,PRINTS	; print error string
		lxi	d,wrong$msg
		call	BDOS
		jmp	error$exit

wrong$version:	mvi	c,PRINTS	; print error string
		lxi	d,version$msg
		call	BDOS
		jmp	error$exit

give$help:	mvi	c,PRINTS	; print help string
		lxi	d,help$msg
		call	BDOS
		jmp	error$exit

		dseg

wrong$msg:	db	'RSX '
test$name:	db	'MAKERSX '	; name of make RSX
		db	' not found',13,10,7,'$'
open$msg:	db	'failed to open make file',13,10,7,'$'
version$msg:	db	'MAKE requires CP/M 3.0 or later',13,10,'$'
help$msg:	db	'MAKE utility by W. Muees 1989',13,10
		db	'USAGE : MAKE <filename>',13,10
		db	'Format of entry in make file :',13,10
		db	'<object> : <source1> <source2> .... <sourceN>',13,10
		db	'   <command line>',13,10
		db	'   <more command lines>',13,10
		db	'<empty lines> until next entry',13,10
		db	'<;comment lines> everywhere',13,10
		db	'If the list of sources exceeds a CP/M input line,',13,10
		db	'terminate line with ''\'' and continue list on next line.',13,10
		db	'The command lines are send to CCP.COM',13,10
		db	'Empty lines are optional, '
		db	'filenames may have user number prefixes.',13,10,'$'

pfcb:		dw	COMLINE+1
		dw	FCB1

make$user:	db	0
default$user:	db	0

PASSWORD:	ds	8

		end	TPA
