;	Perlin Production Co. Ltd. May 1994 (c).
;	Macro Library of CP/M functions,  v.2.0.

RAMBASE	EQU	0	; MP/M, etc.

BIOSENT	EQU	RAMBASE+1	; BIOS table vector
IOBYTE	EQU	RAMBASE+3	; address of I/O byte
DRBYTE	EQU	RAMBASE+4	; address of DISK/USER byte
BDOS	EQU	RAMBASE+5	; BDOS functions entry
TPASIZE	EQU	RAMBASE+6	; Max user RAM & BDOS table vector
TPA	EQU	RAMBASE+100h	; Start of Transient Program Area

BDOSERR	EQU	0FFH		; Standard BDOS ERROR code

DOS	macro	_funct, _de, _a
	mvi	c,_funct
	IFNB	<_de>
	 lxi	d,_de	; usually FCB
	EndIF
	IFNB	<_a>
	 mvi	a,_a
	EndIF	
	call BDOS
EndM

; FCB-related stuff

CPM_FCB	EQU	RAMBASE+5CH
SIZ_FCB	EQU	36
CURDRV	EQU	0		; Currently logged drive
MAXDRV	EQU	15		; Maximum CPM2.2 drive

FCB_DR		EQU	0	; Drive letter
FCB_F1		EQU	1	; File name 8 bytes
FCB_T1		EQU	9	; Extension 3 bytes (file type)
FCB_EX		EQU	12	; Current extent 00-31. Init with 0.
FCB_S1		EQU	13	; Reserved
FCB_S2		EQU	14	; Reserved
FCB_RC		EQU	15	; Record count 0-127 in FCB_EX
FCB_D0		EQU	16	; Used by CPM
FCB_CR		EQU	32	; Current sequential I/O record to rd/wrt
FCB_R0		EQU	33	; Optional random record number in the
FCB_R1		EQU	34	; range 0-65535 with overflow to FCB_R2
FCB_R2		EQU	35	; R0,R1 constitute 16 bit value

; DMA-related stuff

CPM_DMA	EQU	RAMBASE+80H
SIZ_DMA	EQU	128
SIZ_REC	EQU	128	; Byte count of a CP/M record
SIZ_EXT	EQU	128	; Records in a extent 1..SIZ_EXT

;	BIOS functions

$BOOT	EQU	0;	Cold reboot
$WBOOT	EQU	1;	Warm reboot
$CONST	EQU	2;	Conin status
$CONIN	EQU	3;	Input from CON:
$CONOUT	EQU	4;	Output to CON:
$LIST	EQU	5;	Output to LST:
$AUXOUT	EQU	6;	Output to AUX:
$AUXIN	EQU	7;	Input from AUX:
$HOME	EQU	8;	Head to track 0
$SELDSK	EQU	9;	Select drive
$SETTRK	EQU	10;	Set track
$SETSEC	EQU	11;	Set sector
$SETDMA	EQU	12;	Set DMA area
$READ	EQU	13;	BIOS sector read
$WRITE	EQU	14;	BIOS sector write
$LISTST	EQU	15;	LST: status
$SECTRN	EQU	16;	Translate sector number Logical -> Physical

;	These functions must be in CPM 3.0 and higher
;	Extended MicroDOS v.3.1 BDOS functions

IFDEF	_CPM30

$CSTAT	EQU	17;	Console status
$AUXIST	EQU	18;	AUXIN status
$AUXOST	EQU	19;	AUXOUT status
$DEVTBL	EQU	20;	Get physical devices tabel (CTBL) address
$DEVINI	EQU	21;	Physical Devices Initialization
$DRVTBL	EQU	22;	Disk Table (DTBL) Address
$MULTIO	EQU	23;	Multisector I/O

;	EQU	24;	NOT DEFINED

$MEMMOV	EQU	25;	Memory <-> Memory
$TIME	EQU	26;	NOT USED

;	Next BIOS functions are called ONLY by BDOS _BIOS function:

$SELMEM	EQU	27;	Select Memory Bank
$SETBNK	EQU	28;	Set Memory Bank
$XMOVE	EQU	29;	Bank <-> Bank
$RSRV1	EQU	30;	RESERVED FOR FUTHER EXTENSION
$RSRV2	EQU	31;	RESERVED FOR FUTHER EXTENSION
$RSRV3	EQU	32;	RESERVED FOR FUTHER EXTENSION

EndIF	; _CPM30


;	BDOS functions	CP/M v 2.2

_RESET	EQU	0;	System reset
_CONIN	EQU	1;	Read symbol from CON:
_CONOUT	EQU	2;	Write symbol to CON:
_RDR	EQU	3;	Read symbol from RDR:
_PUN	EQU	4;	Write symbol to PUN:
_LST	EQU	5;	Print symbol on LST:
_CON	EQU	6;	Directional console I/O
_GIOBTE EQU	7;	Get I/O byte *** Differs to MicroDOS, where these
_SIOBTE EQU	8;	Set I/O byte *** functions control addit. I/O driver
_PUTS	EQU	9;	Put string to the CON:
_GETS	EQU	10;	Get string from the CON:
_CONST	EQU	11;	Console condition status
_CPMVER	EQU	12
_RSTALL	EQU	13;	Reset all registered devices
_SDRIVE	EQU	14
_OPEN	EQU	15
_CLOSE	EQU	16
_FIND	EQU	17;	Find first occurance in directory
_NEXT	EQU	18;	Find next occurance in directory
_DELETE	EQU	19
_READ	EQU	20;	SEQUENTIAL record read
_WRITE	EQU	21;	SEQUENTIAL record write
_CREAT	EQU	22
_RENAME	EQU	23
_DSTATE	EQU	24;	Get registered drives
_GDRIVE	EQU	25;	Get current drive
_SETDMA	EQU	26
_ALV	EQU	27;	Get Drive Allocation Table Vector
_SETRO	EQU	28;	Set current drive to R/O
_PROT	EQU	29;	Get Drive Protection Vector
_ATTRIB	EQU	30;	Set file attributes R/O or R/W , SYSTEM or DIR
_DPB	EQU	31;	Get Disk Parameters Block address
_USER	EQU	32;	Get/Set user code
_RREAD	EQU	33;	RANDOM record read
_RWRITE	EQU	34;	RANDOM record write
_CFS	EQU	35;	Compute file size (CPM 2.0 and higher versions only)
_SRREC	EQU	36;	Set random record number
_SRESET	EQU	37;	Reset selected disk drives

;	EQU	38;	NOT DEFINED
;	EQU	39;	NOT DEFINED

;	These functions must be in CPM 3.0 and higher
;	Extended MicroDOS v.3.1 BDOS functions

IFDEF	_CPM30

_RWRINI	EQU	40;	RANDOM record write with initialization by 0
_WRTVFY	EQU	41;	Verify and write
_LREC	EQU	42;	Lock file record
_RREC	EQU	43;	Release file record
_MULTIO	EQU	44;	Set multisector mode
_ERRLVL	EQU	45;	Set errorlevel for BDOS errorhandler
_DSKSPC	EQU	46;	Get free diskspace
_EXEC	EQU	47;	Execute program file ( change program )
_FLUSH	EQU	48;	Flush buffers on disk
_SCB	EQU	49;	Read / write System Control Block
_BIOS	EQU	50;	Directional BIOS calls

;	51 - 58	;	NOT DEFINED

_LDRSX	EQU	59;	Load User-Defined Resident System Extension
_RSX	EQU	60;	Call to RSX function

;	61 - 97	;	NOT DEFINED

_FUNLOC	EQU	98;	Unlock Files 
_FIXSIZ	EQU	99;	Fix filesize
_SETDM	EQU	100;	*** Set drive mode | directory volume (label)
_GETDM	EQU	101;	*** Get drive modn | directory volume (label)
_XFCB	EQU	102;	Write Extended File Control Block
_XATTR	EQU	103;	Get extended file attributes ( date & password )
_SDATE	EQU	104;	Set date and time
_GDATE	EQU	105;	Get date and time
_PASSW	EQU	106;	Set Default Password
_SRLNMB	EQU	107;	Get System Serial Number
_EXCODE	EQU	108;	Get/Set Program Exitcode
_STCON	EQU	109;	Get/Set console status
_DELIM	EQU	110;	Get/Set Input Data Delimeter
_SETCCB	EQU	111;	*** differs with MicroDOS
_GETCCB	EQU	112;	*** differs with MicroDOS

;	113 - 151 ;	NOT DEFINED

_MKFCB	EQU	152;	Checks Filename and makes FCB


;	Directional BIOS calls via _BIOS BDOS function.

_FILEIO	EQU	129;
_DSKIO	EQU	130;
_FSTDIN	EQU	131;	Set File for STDIN stream
_CSTDIN	EQU	132;	Set CON: for STDIN stream
_INPBUF	EQU	133;	Set input buffer address
_CONFRM	EQU	240;
_PUTFN	EQU	242;
_PUTDEC	EQU	243;

EndIF	; _CPM30


; Standard Monitor entry points

IFDEF _MONITOR

 M_GETC		EQU	0F803H	; In: NONE. Out: <A> - ASCII code
 M_ITAPE	EQU	0F806H	; In: <A> FF (syncsearch) or 08. Out: <A>
 M_PUTC		EQU	0F809H	; In: <C> - ASCII code. Out: NONE 
 M_OTAPE	EQU	0F80CH	; In: <C> - ASCII code. Out: NONE 
 M_PRINT	EQU	0F80FH	; In: <C> - ASCII code. Out: NONE
 M_KSTAT	EQU	0F812H	; In: NONE. Out <A>=FF pressed, <A>=0 no keys
 M_PUTX		EQU	0F815H	; In: <A> - ASCII code. Out: NONE
 M_PUTS		EQU	0F818H	; In: <HL>- start of 0-term string. Out:NONE
 M_INKEY	EQU	0F81BH	; In: NONE. Out: <A> - ASCII or FF (no key)
 M_CURPOS	EQU	0F81EH	; In: ? Out: ?

EndIF	; _MONITOR

IFDEF	_CPM

IF	0	; TODO: make it a function

BIOS	MACRO	_fun
	local	_ret		; Return address from BIOS body to user program
	push	d
	push	b
	lxi	h,_ret
	push	h		; Save return address
	push	d		; Save 16-bit value parameter
	lhld	BIOSENT
	lxi	d,3 * _fun - 3	; Because BIOSTAB is an addres of WARM REBOOT!
	dad	d
	pop	d		; Restore 16-bit value - parameter
	pchl			; jmp BIOS entry with return address on stack
_ret:	pop	b
	pop	d
EndM

EndIF

CPMPrint	MACRO	_str
	local	MESSAGE,AROUND
	push	h
	push	d
	push	b
	push	PSW

	DOS	_PUTS,MESSAGE

	pop	PSW
	pop	b
	pop	d
	pop	h
	jmp	around
MESSAGE:	db	_str,'$'
around:
ENDM

EndIF	; _CPM

; End of CPM.INC
