; CSMDEF.GEN	- Macro definitions for generation of CRL files from GEN


;			ZEM  Z80 Emulator and Monitor
;			Version 1.03   22 May 1986
;
;			(C) 1986 by P. G. Kenny
;				    27 Colwyn Road
;			 	    Northampton
;
;	Permission is hereby granted for all non-commercial
;	reproduction and distribution of this material provided
;	this notice is included.


;  ***	Macros
;
;	dirent	id,str,last		- make directory entry
;	enddir				- end directory
;	module	id			- declare module
;	needf	id,name,str,last	- enter external function needed
;	body	id			- declare start of body
;	rel	id,n			- make last instruction relocatable
;	xcall	id,name,n		- call external function (and reloc)
;	rparam	id			- declare relocatable parameter table
;	rent	id,n			- enter label in reloc table
;	endmod	id			- declare end of module
;	endcode				- declare end of code

; ** POSITION MARKERS **

t$init	equ	0		; position markers
t$dir	equ	1		; used to check that macros called
t$edir	equ	2		; in the correct order
t$mod	equ	3
t$bod	equ	4
t$rpar	equ	5
t$emod	equ	6
t$ecod	equ	7
t$p	defl	t$init

; ** DIRECTORY **

	org	0		; set origin at 0
dircnt	defl	0		; counts directory entries

dirent	macro	@id @name @last	@dummy ; directory entry macro
	if	t$p>t$dir	; check position ok
? ERROR - BADLY PLACED DIRENT
	endc
t$p	defl	t$dir		; mark pos
	defm	"@name"		; name of function except last char
	defb	"@last" + 80h	; set bit 7 of last char
	defw	mod$@id		; label marking start of module
dircnt	defl	dircnt+1	; count
	endm

enddir	macro			; end of directory
	if	.not.(t$p=t$dir) ; check position
? ERROR	- BADLY PLACED ENDDIR
	endc
	defb	80h		; marks end
	defw	mod$next	; next available address
	defs	200h-$		; pad out to 200h
	defb	0		; external data not used for this segment
	defw	0
	defw	0
t$p	defl	t$edir
	endm

; ** FUNCTION MODULES **

module	macro	@id		; marks start of module
	if	.not.((t$p=t$edir) .or. (t$p=t$emod))
? ERROR	- BADLY PLACED MODULE
	endc
mod$@id	equ	$		; offset of module relative to start of file
nfcnt	defl	0		; counts functions needed
rcnt	defl	0		; counts number of relocation parameters
dircnt	defl	dircnt-1	; decrement dir count
t$p	defl	t$mod
	endm

; ** EXTERNAL FUNCTIONS NEEDED **

needf	macro	@id @name @str @last @dummy ; need function macro
	if	.not.(t$p=t$mod)
? ERROR	- BADLY PLACED NEEDF
	endc
	defm	"@str"		; name except last char
	defb	"@last" + 80h	; set bit 7 of last char
nfcnt	defl	nfcnt+1		; count number of functions needed
v$@id$@name equ 3*nfcnt		; make label for vector
	endm

; ** START MODULE BODY **

vectors	macro			; recursive vector filling
	if	nfcnt		; if more than one left
	jp	0		; place empty jump
nfcnt	defl	nfcnt-1		; count backwards
	vectors			; recursive iteration
	endc
	endm

body	macro	@id		; marks start of body
	if .not.(t$p=t$mod)
? ERROR - BADLY PLACED BODY
	endc
	defb	0		; ends list of needed functions
	defw	rel$@id		; length of body (local origin is 0)
mod$off	defl	$		; saves current address offset
	org	0		; local origin at start of body
	jp	3*(nfcnt+1)	; jump over vectors
	vectors			; fill in with vectors
t$p	defl	t$bod
	endm

; ** RELOCATION DIRECTIVE **

rel	macro	@id,@n		; relocate last instruction
	if	.not.(t$p=t$bod)
? ERROR - BADLY PLACED REL
	endc
r$@id$@n equ	$-2		; mark relative address from start of body
rcnt	defl	rcnt+1
	endm

; ** EXTERNAL FUNCTION CALL **

xcall	macro	@id,@name,@n	; calls external function
	if	.not.(t$p=t$bod)
? ERROR - BADLY PLACED XCALL
	endc
	call	v$@id$@name	; via vector
	rel	@id @n		; relocate this
	endm

; ** START RELOCATION PARAMETER TABLE

rparam	macro	@id		; start of reloc params
	if	.not.(t$p=t$bod)
? ERROR - BADLY PLACED RPARAM
	endc
rel$@id	equ	$		; end of body
	defw	rcnt+1		; number of relocation params + 1
	defw	0001		; must include initial jump before vectors
t$p	defl	t$rpar
	endm

; ** RELOCATION TABLE ENTRY **

rent	macro	@id,@n		; stores reloc parameter
	if	.not.(t$p=t$rpar)
? ERROR - BADLY PLACED RENT
	endc
	defw	r$@id$@n
rcnt	defl	rcnt-1		; count back
	endm

; ** END MODULE **

endmod	macro	@id		; end of module
	if	.not.(t$p=t$rpar)
? ERROR - BADLY PLACED ENDMOD
	endc
	if	rcnt		; check all reloc params entered
	? NOT ALL RELOC PARAMS HAVE BEEN ENTERED
	endc
	org	mod$off+$	; restore module offset
t$p	defl	t$emod
	endm

; ** END OF CODE **

endcode	macro			; marks end of code
	if	.not.(t$p=t$emod)
? ERROR - BADLY PLACED ENDCODE
	endc
mod$next equ	$
	if	dircnt		; this should be zero
	? NOT ALL DIRECTORY ENTRIES HAVE CORRESPONDING MODULES
	endc
t$p	defl	t$ecod
	endm

;  **	END OF CSMDEF.GEN DEFINITIONS
	? NOT ALL DIRECTORY 