DataMuseum.dk

Presents historical artifacts from the history of:

Christian Rovsing CR7, CR8 & CR16 CP/M

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about Christian Rovsing CR7, CR8 & CR16 CP/M

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download

⟦68a3f85f4⟧ TextFile

    Length: 37632 (0x9300)
    Types: TextFile
    Names: »TEST.BAK«, »TEST.VS«

Derivation

└─⟦b40121bef⟧ Bits:30005257 CP/M v.2.2   KOPI
    └─ ⟦this⟧ »TEST.BAK« 
    └─ ⟦this⟧ »TEST.VS« 

TextFile

DETTE
;	CP/M 2.0 DISK RE-DEFINITION LIBRARY
;
;	COPYRIGHT (C) 1979
;	DIGITAL RESEARCH
;	BOX 579
;	PACIFIC GROVE, CA
;	93950
;
;	CP/M LOGICAL DISK DRIVES ARE DEFINED USING THE
;	MACROS GIVEN BELOW, WHERE THE SEQUENCE OF CALLS
;	IS:
;
;	DISKS	N
;	DISKDEF	PARAMETER-LIST-0
;	DISKDEF	PARAMETER-LIST-1
;	...
;	DISKDEF	PARAMETER-LIST-N
;	ENDEF
;
;	WHERE N IS THE NUMBER OF LOGICAL DISK DRIVES ATTACHED
;	TO THE CP/M SYSTEM, AND PARAMETER-LIST-I DEFINES THE
;	CHARACTERISTICS OF THE ITH DRIVE (I=0,1,...,N-1)
;
;	EACH PARAMETER-LIST-I TAKES THE FORM
;		DN,FSC,LSC,ÆSKFÅ,BLS,DKS,DIR,CKS,OFS,Æ0Å
;	WHERE
;	DN	IS THE DISK NUMBER 0,1,...,N-1
;	FSC	IS THE FIRST SECTOR NUMBER (USUALLY 0 OR 1)
;	LSC	IS THE LAST SECTOR NUMBER ON A TRACK
;	SKF	IS OPTIONAL "SKEW FACTOR" FOR SECTOR TRANSLATE
;	BLS	IS THE DATA BLOCK SIZE (1024,2048,...,16384)
;	DKS	IS THE DISK SIZE IN BLS INCREMENTS (WORD)
;	DIR	IS THE NUMBER OF DIRECTORY ELEMENTS (WORD)
;	CKS	IS THE NUMBER OF DIR ELEMENTS TO CHECKSUM
;	OFS	IS THE NUMBER OF TRACKS TO SKIP (WORD)
;	Æ0Å	IS AN OPTIONAL 0 WHICH FORCES 16K/DIRECTORY ENTRY
;
;	FOR CONVENIENCE, THE FORM
;		DN,DM
;	DEFINES DISK DN AS HAVING THE SAME CHARACTERISTICS AS
;	A PREVIOUSLY DEFINED DISK DM.
;
;	A STANDARD FOUR DRIVE CP/M SYSTEM IS DEFINED BY
;		DISKS	4
;		DISKDEF	0,1,26,6,1024,243,64,64,2
;	DSK	SET	0
;		REPT	3
;	DSK	SET	DSK+1
;		DISKDEF	%DSK,0
;		ENDM
;		ENDEF
;
;	THE VALUE OF "BEGDAT" AT THE END OF ASSEMBLY DEFINES THE
;	BEGINNING OF THE UNINITIALIZE RAM AREA ABOVE THE BIOS,
;	WHILE THE VALUE OF "ENDDAT" DEFINES THE NEXT LOCATION
;	FOLLOWING THE END OF THE DATA AREA.  THE SIZE OF THIS
;	AREA IS GIVEN BY THE VALUE OF "DATSIZ" AT THE END OF THE
;	ASSEMBLY.  NOTE THAT THE ALLOCATION VECTOR WILL BE QUITE
;	LARGE IF A LARGE DISK SIZE IS DEFINED WITH A SMALL BLOCK
;	SIZE.
;
DSKHDR	MACRO	DN
;;	DEFINE A SINGLE DISK HEADER LIST
DPE&DN:	DW	XLT&DN,0000H	;TRANSLATE TABLE
	DW	0000H,0000H	;SCRATCH AREA
	DW	DIRBUF,DPB&DN	;DIR BUFF,PARM BLOCK
	DW	CSV&DN,ALV&DN	;CHECK, ALLOC VECTORS
	ENDM
;
DISKS	MACRO	ND
;;	DEFINE ND DISKS
NDISKS	SET	ND	;;FOR LATER REFERENCE
DPBASE	EQU	$	;BASE OF DISK PARAMETER BLOCKS
;;	GENERATE THE ND ELEMENTS
DSKNXT	SET	0
	REPT	ND
	DSKHDR	%DSKNXT
DSKNXT	SET	DSKNXT+1
	ENDM
	ENDM
;
DPBHDR	MACRO	DN
DPB&DN	EQU	$		;DISK PARM BLOCK
	ENDM
;
DDB	MACRO	DATA,COMMENT
;;	DEFINE A DB STATEMENT
	DB	DATA		COMMENT
	ENDM
;
DDW	MACRO	DATA,COMMENT
;;	DEFINE A DW STATEMENT
	DW	DATA		COMMENT
	ENDM
;
GCD	MACRO	M,N
;;	GREATEST COMMON DIVISOR OF M,N
;;	PRODUCES VALUE GCDN AS RESULT
;;	(USED IN SECTOR TRANSLATE TABLE GENERATION)
GCDM	SET	M	;;VARIABLE FOR M
GCDN	SET	N	;;VARIABLE FOR N
GCDR	SET	0	;;VARIABLE FOR R
	REPT	65535
GCDX	SET	GCDM/GCDN
GCDR	SET	GCDM - GCDX*GCDN
	IF	GCDR = 0
	EXITM
	ENDIF
GCDM	SET	GCDN
GCDN	SET	GCDR
	ENDM
	ENDM
;
DISKDEF	MACRO	DN,FSC,LSC,SKF,BLS,DKS,DIR,CKS,OFS,K16
;;	GENERATE THE SET STATEMENTS FOR LATER TABLES
	IF	NUL LSC
;;	CURRENT DISK DN SAME AS PREVIOUS FSC
DPB&DN	EQU	DPB&FSC	;EQUIVALENT PARAMETERS
ALS&DN	EQU	ALS&FSC	;SAME ALLOCATION VECTOR SIZE
CSS&DN	EQU	CSS&FSC	;SAME CHECKSUM VECTOR SIZE
XLT&DN	EQU	XLT&FSC	;SAME TRANSLATE TABLE
	ELSE
SECMAX	SET	LSC-(FSC)	;;SECTORS 0...SECMAX
SECTORS	SET	SECMAX+1;;NUMBER OF SECTORS
ALS&DN	SET	(DKS)/8	;;SIZE OF ALLOCATION VECTOR
	IF	((DKS) MOD 8) NE 0
ALS&DN	SET	ALS&DN+1
	ENDIF
CSS&DN	SET	(CKS)/4	;;NUMBER OF CHECKSUM ELEMENTS
;;	GENERATE THE BLOCK SHIFT VALUE
BLKVAL	SET	BLS/128	;;NUMBER OF SECTORS/BLOCK
BLKSHF	SET	0	;;COUNTS RIGHT 0'S IN BLKVAL
BLKMSK	SET	0	;;FILLS WITH 1'S FROM RIGHT
	REPT	16	;;ONCE FOR EACH BIT POSITION
	IF	BLKVAL=1
	EXITM
	ENDIF
;;	OTHERWISE, HIGH ORDER 1 NOT FOUND YET
BLKSHF	SET	BLKSHF+1
BLKMSK	SET	(BLKMSK SHL 1) OR 1
BLKVAL	SET	BLKVAL/2
	ENDM
;;	GENERATE THE EXTENT MASK BYTE
BLKVAL	SET	BLS/1024	;;NUMBER OF KILOBYTES/BLOCK
EXTMSK	SET	0	;;FILL FROM RIGHT WITH 1'S
	REPT	16
	IF	BLKVAL=1
	EXITM
	ENDIF
;;	OTHERWISE MORE TO SHIFT
EXTMSK	SET	(EXTMSK SHL 1) OR 1
BLKVAL	SET	BLKVAL/2
	ENDM
;;	MAY BE DOUBLE BYTE ALLOCATION
	IF	(DKS) > 256
EXTMSK	SET	(EXTMSK SHR 1)
	ENDIF
;;	MAY BE OPTIONAL Æ0Å IN LAST POSITION
	IF	NOT NUL K16
EXTMSK	SET	K16
	ENDIF
;;	NOW GENERATE DIRECTORY RESERVATION BIT VECTOR
DIRREM	SET	DIR	;;# REMAINING TO PROCESS
DIRBKS	SET	BLS/32	;;NUMBER OF ENTRIES PER BLOCK
DIRBLK	SET	0	;;FILL WITH 1'S ON EACH LOOP
	REPT	16
	IF	DIRREM=0
	EXITM
	ENDIF
;;	NOT COMPLETE, ITERATE ONCE AGAIN
;;	SHIFT RIGHT AND ADD 1 HIGH ORDER BIT
DIRBLK	SET	(DIRBLK SHR 1) OR 8000H
	IF	DIRREM > DIRBKS
DIRREM	SET	DIRREM-DIRBKS
	ELSE
DIRREM	SET	0
	ENDIF
	ENDM
	DPBHDR	DN	;;GENERATE EQU $
	DDW	%SECTORS,<;SEC PER TRACK>
	DDB	%BLKSHF,<;BLOCK SHIFT>
	DDB	%BLKMSK,<;BLOCK MASK>
	DDB	%EXTMSK,<;EXTNT MASK>
	DDW	%(DKS)-1,<;DISK SIZE-1>
	DDW	%(DIR)-1,<;DIRECTORY MAX>
	DDB	%DIRBLK SHR 8,<;ALLOC0>
	DDB	%DIRBLK AND 0FFH,<;ALLOC1>
	DDW	%(CKS)/4,<;CHECK SIZE>
	DDW	%OFS,<;OFFSET>
;;	GENERATE THE TRANSLATE TABLE, IF REQUESTED
	IF	NUL SKF
XLT&DN	EQU	0		;NO XLATE TABLE
	ELSE
	IF	SKF = 0
XLT&DN	EQU	0		;NO XLATE TABLE
	ELSE
;;	GENERATE THE TRANSLATE TABLE
NXTSEC	SET	0	;;NEXT SECTOR TO FILL
;	CP/M 2.0 DISK RE-DEFINITION LIBRARY
;
;	COPYRIGHT (C) 1979
;	DIGITAL RESEARCH
;	BOX 579
;	PACIFIC GROVE, CA
;	93950
;
;	CP/M LOGICAL DISK DRIVES ARE DEFINED USING THE
;	MACROS GIVEN BELOW, WHERE THE SEQUENCE OF CALLS
;	IS:
;
;	DISKS	N
;	DISKDEF	PARAMETER-LIST-0
;	DISKDEF	PARAMETER-LIST-1
;	...
;	DISKDEF	PARAMETER-LIST-N
;	ENDEF
;
;	WHERE N IS THE NUMBER OF LOGICAL DISK DRIVES ATTACHED
;	TO THE CP/M SYSTEM, AND PARAMETER-LIST-I DEFINES THE
;	CHARACTERISTICS OF THE ITH DRIVE (I=0,1,...,N-1)
;
;	EACH PARAMETER-LIST-I TAKES THE FORM
;		DN,FSC,LSC,ÆSKFÅ,BLS,DKS,DIR,CKS,OFS,Æ0Å
;	WHERE
;	DN	IS THE DISK NUMBER 0,1,...,N-1
;	FSC	IS THE FIRST SECTOR NUMBER (USUALLY 0 OR 1)
;	LSC	IS THE LAST SECTOR NUMBER ON A TRACK
;	SKF	IS OPTIONAL "SKEW FACTOR" FOR SECTOR TRANSLATE
;	BLS	IS THE DATA BLOCK SIZE (1024,2048,...,16384)
;	DKS	IS THE DISK SIZE IN BLS INCREMENTS (WORD)
;	DIR	IS THE NUMBER OF DIRECTORY ELEMENTS (WORD)
;	CKS	IS THE NUMBER OF DIR ELEMENTS TO CHECKSUM
;	OFS	IS THE NUMBER OF TRACKS TO SKIP (WORD)
;	Æ0Å	IS AN OPTIONAL 0 WHICH FORCES 16K/DIRECTORY ENTRY
;
;	FOR CONVENIENCE, THE FORM
;		DN,DM
;	DEFINES DISK DN AS HAVING THE SAME CHARACTERISTICS AS
;	A PREVIOUSLY DEFINED DISK DM.
;
;	A STANDARD FOUR DRIVE CP/M SYSTEM IS DEFINED BY
;		DISKS	4
;		DISKDEF	0,1,26,6,1024,243,64,64,2
;	DSK	SET	0
;		REPT	3
;	DSK	SET	DSK+1
;		DISKDEF	%DSK,0
;		ENDM
;		ENDEF
;
;	THE VALUE OF "BEGDAT" AT THE END OF ASSEMBLY DEFINES THE
;	BEGINNING OF THE UNINITIALIZE RAM AREA ABOVE THE BIOS,
;	WHILE THE VALUE OF "ENDDAT" DEFINES THE NEXT LOCATION
;	FOLLOWING THE END OF THE DATA AREA.  THE SIZE OF THIS
;	AREA IS GIVEN BY THE VALUE OF "DATSIZ" AT THE END OF THE
;	ASSEMBLY.  NOTE THAT THE ALLOCATION VECTOR WILL BE QUITE
;	LARGE IF A LARGE DISK SIZE IS DEFINED WITH A SMALL BLOCK
;	SIZE.
;
DSKHDR	MACRO	DN
;;	DEFINE A SINGLE DISK HEADER LIST
DPE&DN:	DW	XLT&DN,0000H	;TRANSLATE TABLE
	DW	0000H,0000H	;SCRATCH AREA
	DW	DIRBUF,DPB&DN	;DIR BUFF,PARM BLOCK
	DW	CSV&DN,ALV&DN	;CHECK, ALLOC VECTORS
	ENDM
;
DISKS	MACRO	ND
;;	DEFINE ND DISKS
NDISKS	SET	ND	;;FOR LATER REFERENCE
DPBASE	EQU	$	;BASE OF DISK PARAMETER BLOCKS
;;	GENERATE THE ND ELEMENTS
DSKNXT	SET	0
	REPT	ND
	DSKHDR	%DSKNXT
DSKNXT	SET	DSKNXT+1
	ENDM
	ENDM
;
DPBHDR	MACRO	DN
DPB&DN	EQU	$		;DISK PARM BLOCK
	ENDM
;
DDB	MACRO	DATA,COMMENT
;;	DEFINE A DB STATEMENT
	DB	DATA		COMMENT
	ENDM
;
DDW	MACRO	DATA,COMMENT
;;	DEFINE A DW STATEMENT
	DW	DATA		COMMENT
	ENDM
;
GCD	MACRO	M,N
;;	GREATEST COMMON DIVISOR OF M,N
;;	PRODUCES VALUE GCDN AS RESULT
;;	(USED IN SECTOR TRANSLATE TABLE GENERATION)
GCDM	SET	M	;;VARIABLE FOR M
GCDN	SET	N	;;VARIABLE FOR N
GCDR	SET	0	;;VARIABLE FOR R
	REPT	65535
GCDX	SET	GCDM/GCDN
GCDR	SET	GCDM - GCDX*GCDN
	IF	GCDR = 0
	EXITM
	ENDIF
GCDM	SET	GCDN
GCDN	SET	GCDR
	ENDM
	ENDM
;
DISKDEF	MACRO	DN,FSC,LSC,SKF,BLS,DKS,DIR,CKS,OFS,K16
;;	GENERATE THE SET STATEMENTS FOR LATER TABLES
	IF	NUL LSC
;;	CURRENT DISK DN SAME AS PREVIOUS FSC
DPB&DN	EQU	DPB&FSC	;EQUIVALENT PARAMETERS
ALS&DN	EQU	ALS&FSC	;SAME ALLOCATION VECTOR SIZE
CSS&DN	EQU	CSS&FSC	;SAME CHECKSUM VECTOR SIZE
XLT&DN	EQU	XLT&FSC	;SAME TRANSLATE TABLE
	ELSE
SECMAX	SET	LSC-(FSC)	;;SECTORS 0...SECMAX
SECTORS	SET	SECMAX+1;;NUMBER OF SECTORS
ALS&DN	SET	(DKS)/8	;;SIZE OF ALLOCATION VECTOR
	IF	((DKS) MOD 8) NE 0
ALS&DN	SET	ALS&DN+1
	ENDIF
CSS&DN	SET	(CKS)/4	;;NUMBER OF CHECKSUM ELEMENTS
;;	GENERATE THE BLOCK SHIFT VALUE
BLKVAL	SET	BLS/128	;;NUMBER OF SECTORS/BLOCK
BLKSHF	SET	0	;;COUNTS RIGHT 0'S IN BLKVAL
BLKMSK	SET	0	;;FILLS WITH 1'S FROM RIGHT
	REPT	16	;;ONCE FOR EACH BIT POSITION
	IF	BLKVAL=1
	EXITM
	ENDIF
;;	OTHERWISE, HIGH ORDER 1 NOT FOUND YET
BLKSHF	SET	BLKSHF+1
BLKMSK	SET	(BLKMSK SHL 1) OR 1
BLKVAL	SET	BLKVAL/2
	ENDM
;;	GENERATE THE EXTENT MASK BYTE
BLKVAL	SET	BLS/1024	;;NUMBER OF KILOBYTES/BLOCK
EXTMSK	SET	0	;;FILL FROM RIGHT WITH 1'S
	REPT	16
	IF	BLKVAL=1
	EXITM
	ENDIF
;;	OTHERWISE MORE TO SHIFT
EXTMSK	SET	(EXTMSK SHL 1) OR 1
BLKVAL	SET	BLKVAL/2
	ENDM
;;	MAY BE DOUBLE BYTE ALLOCATION
	IF	(DKS) > 256
EXTMSK	SET	(EXTMSK SHR 1)
	ENDIF
;;	MAY BE OPTIONAL Æ0Å IN LAST POSITION
	IF	NOT NUL K16
EXTMSK	SET	K16
	ENDIF
;;	NOW GENERATE DIRECTORY RESERVATION BIT VECTOR
DIRREM	SET	DIR	;;# REMAINING TO PROCESS
DIRBKS	SET	BLS/32	;;NUMBER OF ENTRIES PER BLOCK
DIRBLK	SET	0	;;FILL WITH 1'S ON EACH LOOP
	REPT	16
	IF	DIRREM=0
	EXITM
	ENDIF
;;	NOT COMPLETE, ITERATE ONCE AGAIN
;;	SHIFT RIGHT AND ADD 1 HIGH ORDER BIT
DIRBLK	SET	(DIRBLK SHR 1) OR 8000H
	IF	DIRREM > DIRBKS
DIRREM	SET	DIRREM-DIRBKS
	ELSE
DIRREM	SET	0
	ENDIF
	ENDM
	DPBHDR	DN	;;GENERATE EQU $
	DDW	%SECTORS,<;SEC PER TRACK>
	DDB	%BLKSHF,<;BLOCK SHIFT>
	DDB	%BLKMSK,<;BLOCK MASK>
	DDB	%EXTMSK,<;EXTNT MASK>
	DDW	%(DKS)-1,<;DISK SIZE-1>
	DDW	%(DIR)-1,<;DIRECTORY MAX>
	DDB	%DIRBLK SHR 8,<;ALLOC0>
	DDB	%DIRBLK AND 0FFH,<;ALLOC1>
	DDW	%(CKS)/4,<;CHECK SIZE>
	DDW	%OFS,<;OFFSET>
;;	GENERATE THE TRANSLATE TABLE, IF REQUESTED
	IF	NUL SKF
XLT&DN	EQU	0		;NO XLATE TABLE
	ELSE
	IF	SKF = 0
XLT&DN	EQU	0		;NO XLATE TABLE
	ELSE
;;	GENERATE THE TRANSLATE TABLE
NXTSEC	SET	0	;;NEXT SECTOR TO FILL
NXTBAS	SET	0	;;MOVES BY ONE ON OVERFLOW
	GCD	%SECTORS,SKF
;	CP/M 2.0 DISK RE-DEFINITION LIBRARY
;
;	COPYRIGHT (C) 1979
;	DIGITAL RESEARCH
;	BOX 579
;	PACIFIC GROVE, CA
;	93950
;
;	CP/M LOGICAL DISK DRIVES ARE DEFINED USING THE
;	MACROS GIVEN BELOW, WHERE THE SEQUENCE OF CALLS
;	IS:
;
;	DISKS	N
;	DISKDEF	PARAMETER-LIST-0
;	DISKDEF	PARAMETER-LIST-1
;	...
;	DISKDEF	PARAMETER-LIST-N
;	ENDEF
;
;	WHERE N IS THE NUMBER OF LOGICAL DISK DRIVES ATTACHED
;	TO THE CP/M SYSTEM, AND PARAMETER-LIST-I DEFINES THE
;	CHARACTERISTICS OF THE ITH DRIVE (I=0,1,...,N-1)
;
;	EACH PARAMETER-LIST-I TAKES THE FORM
;		DN,FSC,LSC,ÆSKFÅ,BLS,DKS,DIR,CKS,OFS,Æ0Å
;	WHERE
;	DN	IS THE DISK NUMBER 0,1,...,N-1
;	FSC	IS THE FIRST SECTOR NUMBER (USUALLY 0 OR 1)
;	LSC	IS THE LAST SECTOR NUMBER ON A TRACK
;	SKF	IS OPTIONAL "SKEW FACTOR" FOR SECTOR TRANSLATE
;	BLS	IS THE DATA BLOCK SIZE (1024,2048,...,16384)
;	DKS	IS THE DISK SIZE IN BLS INCREMENTS (WORD)
;	DIR	IS THE NUMBER OF DIRECTORY ELEMENTS (WORD)
;	CKS	IS THE NUMBER OF DIR ELEMENTS TO CHECKSUM
;	OFS	IS THE NUMBER OF TRACKS TO SKIP (WORD)
;	Æ0Å	IS AN OPTIONAL 0 WHICH FORCES 16K/DIRECTORY ENTRY
;
;	FOR CONVENIENCE, THE FORM
;		DN,DM
;	DEFINES DISK DN AS HAVING THE SAME CHARACTERISTICS AS
;	A PREVIOUSLY DEFINED DISK DM.
;
;	A STANDARD FOUR DRIVE CP/M SYSTEM IS DEFINED BY
;		DISKS	4
;		DISKDEF	0,1,26,6,1024,243,64,64,2
;	DSK	SET	0
;		REPT	3
;	DSK	SET	DSK+1
;		DISKDEF	%DSK,0
;		ENDM
;		ENDEF
;
;	THE VALUE OF "BEGDAT" AT THE END OF ASSEMBLY DEFINES THE
;	BEGINNING OF THE UNINITIALIZE RAM AREA ABOVE THE BIOS,
;	WHILE THE VALUE OF "ENDDAT" DEFINES THE NEXT LOCATION
;	FOLLOWING THE END OF THE DATA AREA.  THE SIZE OF THIS
;	AREA IS GIVEN BY THE VALUE OF "DATSIZ" AT THE END OF THE
;	ASSEMBLY.  NOTE THAT THE ALLOCATION VECTOR WILL BE QUITE
;	LARGE IF A LARGE DISK SIZE IS DEFINED WITH A SMALL BLOCK
;	SIZE.
;
DSKHDR	MACRO	DN
;;	DEFINE A SINGLE DISK HEADER LIST
DPE&DN:	DW	XLT&DN,0000H	;TRANSLATE TABLE
	DW	0000H,0000H	;SCRATCH AREA
	DW	DIRBUF,DPB&DN	;DIR BUFF,PARM BLOCK
	DW	CSV&DN,ALV&DN	;CHECK, ALLOC VECTORS
	ENDM
;
DISKS	MACRO	ND
;;	DEFINE ND DISKS
NDISKS	SET	ND	;;FOR LATER REFERENCE
DPBASE	EQU	$	;BASE OF DISK PARAMETER BLOCKS
;;	GENERATE THE ND ELEMENTS
DSKNXT	SET	0
	REPT	ND
	DSKHDR	%DSKNXT
DSKNXT	SET	DSKNXT+1
	ENDM
	ENDM
;
DPBHDR	MACRO	DN
DPB&DN	EQU	$		;DISK PARM BLOCK
	ENDM
;
DDB	MACRO	DATA,COMMENT
;;	DEFINE A DB STATEMENT
	DB	DATA		COMMENT
	ENDM
;
DDW	MACRO	DATA,COMMENT
;;	DEFINE A DW STATEMENT
	DW	DATA		COMMENT
	ENDM
;
GCD	MACRO	M,N
;;	GREATEST COMMON DIVISOR OF M,N
;;	PRODUCES VALUE GCDN AS RESULT
;;	(USED IN SECTOR TRANSLATE TABLE GENERATION)
GCDM	SET	M	;;VARIABLE FOR M
;	CP/M 2.0 DISK RE-DEFINITION LIBRARY
;
;	COPYRIGHT (C) 1979
;	DIGITAL RESEARCH
;	BOX 579
;	PACIFIC GROVE, CA
;	93950
;
;	CP/M LOGICAL DISK DRIVES ARE DEFINED USING THE
;	MACROS GIVEN BELOW, WHERE THE SEQUENCE OF CALLS
;	IS:
;
;	DISKS	N
;	DISKDEF	PARAMETER-LIST-0
;	DISKDEF	PARAMETER-LIST-1
;	...
;	DISKDEF	PARAMETER-LIST-N
;	ENDEF
;
;	WHERE N IS THE NUMBER OF LOGICAL DISK DRIVES ATTACHED
;	TO THE CP/M SYSTEM, AND PARAMETER-LIST-I DEFINES THE
;	CHARACTERISTICS OF THE ITH DRIVE (I=0,1,...,N-1)
;
;	EACH PARAMETER-LIST-I TAKES THE FORM
;		DN,FSC,LSC,ÆSKFÅ,BLS,DKS,DIR,CKS,OFS,Æ0Å
;	WHERE
;	DN	IS THE DISK NUMBER 0,1,...,N-1
;	FSC	IS THE FIRST SECTOR NUMBER (USUALLY 0 OR 1)
;	LSC	IS THE LAST SECTOR NUMBER ON A TRACK
;	SKF	IS OPTIONAL "SKEW FACTOR" FOR SECTOR TRANSLATE
;	BLS	IS THE DATA BLOCK SIZE (1024,2048,...,16384)
;	DKS	IS THE DISK SIZE IN BLS INCREMENTS (WORD)
;	DIR	IS THE NUMBER OF DIRECTORY ELEMENTS (WORD)
;	CKS	IS THE NUMBER OF DIR ELEMENTS TO CHECKSUM
;	OFS	IS THE NUMBER OF TRACKS TO SKIP (WORD)
;	Æ0Å	IS AN OPTIONAL 0 WHICH FORCES 16K/DIRECTORY ENTRY
;
;	FOR CONVENIENCE, THE FORM
;		DN,DM
;	DEFINES DISK DN AS HAVING THE SAME CHARACTERISTICS AS
;	A PREVIOUSLY DEFINED DISK DM.
;
;	A STANDARD FOUR DRIVE CP/M SYSTEM IS DEFINED BY
;		DISKS	4
;		DISKDEF	0,1,26,6,1024,243,64,64,2
;	DSK	SET	0
;		REPT	3
;	DSK	SET	DSK+1
;		DISKDEF	%DSK,0
;		ENDM
;		ENDEF
;
;	THE VALUE OF "BEGDAT" AT THE END OF ASSEMBLY DEFINES THE
;	BEGINNING OF THE UNINITIALIZE RAM AREA ABOVE THE BIOS,
;	WHILE THE VALUE OF "ENDDAT" DEFINES THE NEXT LOCATION
;	FOLLOWING THE END OF THE DATA AREA.  THE SIZE OF THIS
;	AREA IS GIVEN BY THE VALUE OF "DATSIZ" AT THE END OF THE
;	ASSEMBLY.  NOTE THAT THE ALLOCATION VECTOR WILL BE QUITE
;	LARGE IF A LARGE DISK SIZE IS DEFINED WITH A SMALL BLOCK
;	SIZE.
;
DSKHDR	MACRO	DN
;;	DEFINE A SINGLE DISK HEADER LIST
DPE&DN:	DW	XLT&DN,0000H	;TRANSLATE TABLE
	DW	0000H,0000H	;SCRATCH AREA
	DW	DIRBUF,DPB&DN	;DIR BUFF,PARM BLOCK
	DW	CSV&DN,ALV&DN	;CHECK, ALLOC VECTORS
	ENDM
;
DISKS	MACRO	ND
;;	DEFINE ND DISKS
NDISKS	SET	ND	;;FOR LATER REFERENCE
DPBASE	EQU	$	;BASE OF DISK PARAMETER BLOCKS
;;	GENERATE THE ND ELEMENTS
DSKNXT	SET	0
	REPT	ND
	DSKHDR	%DSKNXT
DSKNXT	SET	DSKNXT+1
	ENDM
	ENDM
;
DPBHDR	MACRO	DN
DPB&DN	EQU	$		;DISK PARM BLOCK
	ENDM
;
DDB	MACRO	DATA,COMMENT
;;	DEFINE A DB STATEMENT
	DB	DATA		COMMENT
	ENDM
;
DDW	MACRO	DATA,COMMENT
;;	DEFINE A DW STATEMENT
	DW	DATA		COMMENT
	ENDM
;
GCD	MACRO	M,N
;;	GREATEST COMMON DIVISOR OF M,N
;;	PRODUCES VALUE GCDN AS RESULT
;;	(USED IN SECTOR TRANSLATE TABLE GENERATION)
GCDM	SET	M	;;VARIABLE FOR M
;	CP/M 2.0 DISK RE-DEFINITION LIBRARY
;
;	COPYRIGHT (C) 1979
;	DIGITAL RESEARCH
;	BOX 579
;	PACIFIC GROVE, CA
;	93950
;
;	CP/M LOGICAL DISK DRIVES ARE DEFINED USING THE
;	MACROS GIVEN BELOW, WHERE THE SEQUENCE OF CALLS
;	IS:
;
;	DISKS	N
;	DISKDEF	PARAMETER-LIST-0
;	DISKDEF	PARAMETER-LIST-1
;	...
;	DISKDEF	PARAMETER-LIST-N
;	ENDEF
;
;	WHERE N IS THE NUMBER OF LOGICAL DISK DRIVES ATTACHED
;	TO THE CP/M SYSTEM, AND PARAMETER-LIST-I DEFINES THE
;	CHARACTERISTICS OF THE ITH DRIVE (I=0,1,...,N-1)
;
;	EACH PARAMETER-LIST-I TAKES THE FORM
;		DN,FSC,LSC,ÆSKFÅ,BLS,DKS,DIR,CKS,OFS,Æ0Å
;	WHERE
;	DN	IS THE DISK NUMBER 0,1,...,N-1
;	FSC	IS THE FIRST SECTOR NUMBER (USUALLY 0 OR 1)
;	LSC	IS THE LAST SECTOR NUMBER ON A TRACK
;	SKF	IS OPTIONAL "SKEW FACTOR" FOR SECTOR TRANSLATE
;	BLS	IS THE DATA BLOCK SIZE (1024,2048,...,16384)
;	DKS	IS THE DISK SIZE IN BLS INCREMENTS (WORD)
;	DIR	IS THE NUMBER OF DIRECTORY ELEMENTS (WORD)
;	CKS	IS THE NUMBER OF DIR ELEMENTS TO CHECKSUM
;	OFS	IS THE NUMBER OF TRACKS TO SKIP (WORD)
;	Æ0Å	IS AN OPTIONAL 0 WHICH FORCES 16K/DIRECTORY ENTRY
;
;	FOR CONVENIENCE, THE FORM
;		DN,DM
;	DEFINES DISK DN AS HAVING THE SAME CHARACTERISTICS AS
;	A PREVIOUSLY DEFINED DISK DM.
;
;	A STANDARD FOUR DRIVE CP/M SYSTEM IS DEFINED BY
;		DISKS	4
;		DISKDEF	0,1,26,6,1024,243,64,64,2
;	DSK	SET	0
;		REPT	3
;	DSK	SET	DSK+1
;		DISKDEF	%DSK,0
;		ENDM
;		ENDEF
;
;	THE VALUE OF "BEGDAT" AT THE END OF ASSEMBLY DEFINES THE
;	BEGINNING OF THE UNINITIALIZE RAM AREA ABOVE THE BIOS,
;	WHILE THE VALUE OF "ENDDAT" DEFINES THE NEXT LOCATION
;	FOLLOWING THE END OF THE DATA AREA.  THE SIZE OF THIS
;	AREA IS GIVEN BY THE VALUE OF "DATSIZ" AT THE END OF THE
;	ASSEMBLY.  NOTE THAT THE ALLOCATION VECTOR WILL BE QUITE
;	LARGE IF A LARGE DISK SIZE IS DEFINED WITH A SMALL BLOCK
;	SIZE.
;
DSKHDR	MACRO	DN
;;	DEFINE A SINGLE DISK HEADER LIST
DPE&DN:	DW	XLT&DN,0000H	;TRANSLATE TABLE
	DW	0000H,0000H	;SCRATCH AREA
	DW	DIRBUF,DPB&DN	;DIR BUFF,PARM BLOCK
	DW	CSV&DN,ALV&DN	;CHECK, ALLOC VECTORS
	ENDM
;
DISKS	MACRO	ND
;;	DEFINE ND DISKS
NDISKS	SET	ND	;;FOR LATER REFERENCE
DPBASE	EQU	$	;BASE OF DISK PARAMETER BLOCKS
;;	GENERATE THE ND ELEMENTS
DSKNXT	SET	0
	REPT	ND
	DSKHDR	%DSKNXT
DSKNXT	SET	DSKNXT+1
	ENDM
	ENDM
;
DPBHDR	MACRO	DN
DPB&DN	EQU	$		;DISK PARM BLOCK
	ENDM
;
DDB	MACRO	DATA,COMMENT
;;	DEFINE A DB STATEMENT
	DB	DATA		COMMENT
	ENDM
;
DDW	MACRO	DATA,COMMENT
;;	DEFINE A DW STATEMENT
	DW	DATA		COMMENT
	ENDM
;
GCD	MACRO	M,N
;;	GREATEST COMMON DIVISOR OF M,N
;;	PRODUCES VALUE GCDN AS RESULT
;;	(USED IN SECTOR TRANSLATE TABLE GENERATION)
GCDM	SET	M	;;VARIABLE FOR M
GCDN	SET	N	;;VARIABLE FOR N
GCDR	SET	0	;;VARIABLE FOR R
	REPT	65535
GCDX	SET	GCDM/GCDN
GCDR	SET	GCDM - GCDX*GCDN
	IF	GCDR = 0
	EXITM
	ENDIF
GCDM	SET	GCDN
GCDN	SET	GCDR
	ENDM
	ENDM
;
DISKDEF	MACRO	DN,FSC,LSC,SKF,BLS,DKS,DIR,CKS,OFS,K16
;;	GENERATE THE SET STATEMENTS FOR LATER TABLES
	IF	NUL LSC
;;	CURRENT DISK DN SAME AS PREVIOUS FSC
DPB&DN	EQU	DPB&FSC	;EQUIVALENT PARAMETERS
ALS&DN	EQU	ALS&FSC	;SAME ALLOCATION VECTOR SIZE
CSS&DN	EQU	CSS&FSC	;SAME CHECKSUM VECTOR SIZE
XLT&DN	EQU	XLT&FSC	;SAME TRANSLATE TABLE
	ELSE
SECMAX	SET	LSC-(FSC)	;;SECTORS 0...SECMAX
SECTORS	SET	SECMAX+1;;NUMBER OF SECTORS
ALS&DN	SET	(DKS)/8	;;SIZE OF ALLOCATION VECTOR
	IF	((DKS) MOD 8) NE 0
ALS&DN	SET	ALS&DN+1
	ENDIF
CSS&DN	SET	(CKS)/4	;;NUMBER OF CHECKSUM ELEMENTS
;;	GENERATE THE BLOCK SHIFT VALUE
BLKVAL	SET	BLS/128	;;NUMBER OF SECTORS/BLOCK
BLKSHF	SET	0	;;COUNTS RIGHT 0'S IN BLKVAL
BLKMSK	SET	0	;;FILLS WITH 1'S FROM RIGHT
	REPT	16	;;ONCE FOR EACH BIT POSITION
	IF	BLKVAL=1
	EXITM
	ENDIF
;;	OTHERWISE, HIGH ORDER 1 NOT FOUND YET
BLKSHF	SET	BLKSHF+1
BLKMSK	SET	(BLKMSK SHL 1) OR 1
BLKVAL	SET	BLKVAL/2
	ENDM
;;	GENERATE THE EXTENT MASK BYTE
BLKVAL	SET	BLS/1024	;;NUMBER OF KILOBYTES/BLOCK
EXTMSK	SET	0	;;FILL FROM RIGHT WITH 1'S
	REPT	16
	IF	BLKVAL=1
	EXITM
	ENDIF
;;	OTHERWISE MORE TO SHIFT
EXTMSK	SET	(EXTMSK SHL 1) OR 1
BLKVAL	SET	BLKVAL/2
	ENDM
;;	MAY BE DOUBLE BYTE ALLOCATION
	IF	(DKS) > 256
EXTMSK	SET	(EXTMSK SHR 1)
	ENDIF
;;	MAY BE OPTIONAL Æ0Å IN LAST POSITION
	IF	NOT NUL K16
EXTMSK	SET	K16
	ENDIF
;;	NOW GENERATE DIRECTORY RESERVATION BIT VECTOR
DIRREM	SET	DIR	;;# REMAINING TO PROCESS
DIRBKS	SET	BLS/32	;;NUMBER OF ENTRIES PER BLOCK
DIRBLK	SET	0	;;FILL WITH 1'S ON EACH LOOP
	REPT	16
	IF	DIRREM=0
	EXITM
	ENDIF
;;	NOT COMPLETE, ITERATE ONCE AGAIN
;;	SHIFT RIGHT AND ADD 1 HIGH ORDER BIT
DIRBLK	SET	(DIRBLK SHR 1) OR 8000H
	IF	DIRREM > DIRBKS
DIRREM	SET	DIRREM-DIRBKS
	ELSE
DIRREM	SET	0
	ENDIF
	ENDM
	DPBHDR	DN	;;GENERATE EQU $
	DDW	%SECTORS,<;SEC PER TRACK>
	DDB	%BLKSHF,<;BLOCK SHIFT>
	DDB	%BLKMSK,<;BLOCK MASK>
	DDB	%EXTMSK,<;EXTNT MASK>
	DDW	%(DKS)-1,<;DISK SIZE-1>
	DDW	%(DIR)-1,<;DIRECTORY MAX>
	DDB	%DIRBLK SHR 8,<;ALLOC0>
	DDB	%DIRBLK AND 0FFH,<;ALLOC1>
	DDW	%(CKS)/4,<;CHECK SIZE>
	DDW	%OFS,<;OFFSET>
;;	GENERATE THE TRANSLATE TABLE, IF REQUESTED
	IF	NUL SKF
XLT&DN	EQU	0		;NO XLATE TABLE
	ELSE
	IF	SKF = 0
XLT&DN	EQU	0		;NO XLATE TABLE
	ELSE
;;	GENERATE THE TRANSLATE TABLE
NXTSEC	SET	0	;;NEXT SECTOR TO FILL
NXTBAS	SET	0	;;MOVES BY ONE ON OVERFLOW
	GCD	%SECTORS,SKF
;	CP/M 2.0 DISK RE-DEFINITION LIBRARY
;
;	COPYRIGHT (C) 1979
;	DIGITAL RESEARCH
;	BOX 579
;	PACIFIC GROVE, CA
;	93950
;
;;;	GCDN = GCD(SECTORS,SKEW)
NELTST	SET	SECTORS/GCDN
;;	NELTST IS NUMBER OF ELEMENTS TO GENERATE
;;	BEFORE WE OVERLAP PREVIOUS ELEMENTS
NELTS	SET	NELTST	;;COUNTER
XLT&DN	EQU	$		;TRANSLATE TABLE
	REPT	SECTORS	;;ONCE FOR EACH SECTOR
	IF	SECTORS < 256
	DDB	%NXTSEC+(FSC)
	ELSE
	DDW	%NXTSEC+(FSC)
	ENDIF
NXTSEC	SET	NXTSEC+(SKF)
	IF	NXTSEC >= SECTORS
NXTSEC	SET	NXTSEC-SECTORS
	ENDIF
NELTS	SET	NELTS-1
	IF	NELTS = 0
NXTBAS	SET	NXTBAS+1
NXTSEC	SET	NXTBAS
NELTS	SET	NELTST
	ENDIF
	ENDM
	ENDIF	;;END OF NUL FAC TEST
	ENDIF	;;END OF NUL BLS TEST
	ENDM
;
DEFDS	MACRO	LAB,SPACE
LAB:	DS	SPACE
	ENDM
;
LDS	MACRO	LB,DN,VAL
	DEFDS	LB&DN,%VAL&DN
	ENDM
;
ENDEF	MACRO
;;	GENERATE THE NECESSARY RAM DATA AREAS
BEGDAT	EQU	$
DIRBUF:	DS	128	;DIRECTORY ACCESS BUFFER
DSKNXT	SET	0
	REPT	NDISKS	;;ONCE FOR EACH DISK
	LDS	ALV,%DSKNXT,ALS
	LDS	CSV,%DSKNXT,CSS
DSKNXT	SET	DSKNXT+1
	ENDM
ENDDAT	EQU	$
DATSIZ	EQU	$-BEGDAT
;;	DB 0 AT THIS POINT FORCES HEX RECORD
	ENDM
;
GCDN	SET	N	;;VARIABLE FOR N
GCDR	SET	0	;;VARIABLE FOR R
	REPT	65535
GCDX	SET	GCDM/GCDN
GCDR	SET	GCDM - GCDX*GCDN
	IF	GCDR = 0
	EXITM
	ENDIF
GCDM	SET	GCDN
GCDN	SET	GCDR
	ENDM
	ENDM
;
DISKDEF	MACRO	DN,FSC,LSC,SKF,BLS,DKS,DIR,CKS,OFS,K16
;;	GENERATE THE SET STATEMENTS FOR LATER TABLES
	IF	NUL LSC
;;	CURRENT DISK DN SAME AS PREVIOUS FSC
DPB&DN	EQU	DPB&FSC	;EQUIVALENT PARAMETERS
ALS&DN	EQU	ALS&FSC	;SAME ALLOCATION VECTOR SIZE
CSS&DN	EQU	CSS&FSC	;SAME CHECKSUM VECTOR SIZE
XLT&DN	EQU	XLT&FSC	;SAME TRANSLATE TABLE
	ELSE
SECMAX	SET	LSC-(FSC)	;;SECTORS 0...SECMAX
SECTORS	SET	SECMAX+1;;NUMBER OF SECTORS
ALS&DN	SET	(DKS)/8	;;SIZE OF ALLOCATION VECTOR
	IF	((DKS) MOD 8) NE 0
ALS&DN	SET	ALS&DN+1
	ENDIF
CSS&DN	SET	(CKS)/4	;;NUMBER OF CHECKSUM ELEMENTS
;;	GENERATE THE BLOCK SHIFT VALUE
BLKVAL	SET	BLS/128	;;NUMBER OF SECTORS/BLOCK
BLKSHF	SET	0	;;COUNTS RIGHT 0'S IN BLKVAL
BLKMSK	SET	0	;;FILLS WITH 1'S FROM RIGHT
	REPT	16	;;ONCE FOR EACH BIT POSITION
	IF	BLKVAL=1
	EXITM
	ENDIF
;;	OTHERWISE, HIGH ORDER 1 NOT FOUND YET
BLKSHF	SET	BLKSHF+1
BLKMSK	SET	(BLKMSK SHL 1) OR 1
BLKVAL	SET	BLKVAL/2
	ENDM
;;	GENERATE THE EXTENT MASK BYTE
BLKVAL	SET	BLS/1024	;;NUMBER OF KILOBYTES/BLOCK
EXTMSK	SET	0	;;FILL FROM RIGHT WITH 1'S
	REPT	16
	IF	BLKVAL=1
	EXITM
	ENDIF
;;	OTHERWISE MORE TO SHIFT
EXTMSK	SET	(EXTMSK SHL 1) OR 1
BLKVAL	SET	BLKVAL/2
	ENDM
;;	MAY BE DOUBLE BYTE ALLOCATION
	IF	(DKS) > 256
EXTMSK	SET	(EXTMSK SHR 1)
	ENDIF
;;	MAY BE OPTIONAL Æ0Å IN LAST POSITION
	IF	NOT NUL K16
EXTMSK	SET	K16
	ENDIF
;;	NOW GENERATE DIRECTORY RESERVATION BIT VECTOR
DIRREM	SET	DIR	;;# REMAINING TO PROCESS
DIRBKS	SET	BLS/32	;;NUMBER OF ENTRIES PER BLOCK
DIRBLK	SET	0	;;FILL WITH 1'S ON EACH LOOP
	REPT	16
	IF	DIRREM=0
	EXITM
	ENDIF
;;	NOT COMPLETE, ITERATE ONCE AGAIN
;;	SHIFT RIGHT AND ADD 1 HIGH ORDER BIT
DIRBLK	SET	(DIRBLK SHR 1) OR 8000H
	IF	DIRREM > DIRBKS
DIRREM	SET	DIRREM-DIRBKS
	ELSE
DIRREM	SET	0
	ENDIF
	ENDM
	DPBHDR	DN	;;GENERATE EQU $
	DDW	%SECTORS,<;SEC PER TRACK>
	DDB	%BLKSHF,<;BLOCK SHIFT>
	DDB	%BLKMSK,<;BLOCK MASK>
	DDB	%EXTMSK,<;EXTNT MASK>
	DDW	%(DKS)-1,<;DISK SIZE-1>
	DDW	%(DIR)-1,<;DIRECTORY MAX>
	DDB	%DIRBLK SHR 8,<;ALLOC0>
	DDB	%DIRBLK AND 0FFH,<;ALLOC1>
	DDW	%(CKS)/4,<;CHECK SIZE>
	DDW	%OFS,<;OFFSET>
;;	GENERATE THE TRANSLATE TABLE, IF REQUESTED
	IF	NUL SKF
XLT&DN	EQU	0		;NO XLATE TABLE
	ELSE
	IF	SKF = 0
XLT&DN	EQU	0		;NO XLATE TABLE
	ELSE
;;	GENERATE THE TRANSLATE TABLE
NXTSEC	SET	0	;;NEXT SECTOR TO FILL
NXTBAS	SET	0	;;MOVES BY ONE ON OVERFLOW
	GCD	%SECTORS,SKF
;;	GCDN = GCD(SECTORS,SKEW)
NELTST	SET	SECTORS/GCDN
;;	NELTST IS NUMBER OF ELEMENTS TO GENERATE
;;	BEFORE WE OVERLAP PREVIOUS ELEMENTS
NELTS	SET	NELTST	;;COUNTER
XLT&DN	EQU	$		;TRANSLATE TABLE
	REPT	SECTORS	;;ONCE FOR EACH SECTOR
	IF	SECTORS < 256
	DDB	%NXTSEC+(FSC)
	ELSE
	DDW	%NXTSEC+(FSC)
	ENDIF
NXTSEC	SET	NXTSEC+(SKF)
	IF	NXTSEC >= SECTORS
NXTSEC	SET	NXTSEC-SECTORS
	ENDIF
NELTS	SET	NELTS-1
	IF	NELTS = 0
NXTBAS	SET	NXTBAS+1
NXTSEC	SET	NXTBAS
NELTS	SET	NELTST
	ENDIF
	ENDM
	ENDIF	;;END OF NUL FAC TEST
	ENDIF	;;END OF NUL BLS TEST
	ENDM
;
DEFDS	MACRO	LAB,SPACE
LAB:	DS	SPACE
	ENDM
;
LDS	MACRO	LB,DN,VAL
	DEFDS	LB&DN,%VAL&DN
	ENDM
;
ENDEF	MACRO
;;	GENERATE THE NECESSARY RAM DATA AREAS
BEGDAT	EQU	$
DIRBUF:	DS	128	;DIRECTORY ACCESS BUFFER
DSKNXT	SET	0
	REPT	NDISKS	;;ONCE FOR EACH DISK
	LDS	ALV,%DSKNXT,ALS
	LDS	CSV,%DSKNXT,CSS
DSKNXT	SET	DSKNXT+1
	ENDM
ENDDAT	EQU	$
DATSIZ	EQU	$-BEGDAT
;;	DB 0 AT THIS POINT FORCES HEX RECORD
	ENDM
;
GCDN	SET	N	;;VARIABLE FOR N
GCDR	SET	0	;;VARIABLE FOR R
	REPT	65535
GCDX	SET	GCDM/GCDN
GCDR	SET	GCDM - GCDX*GCDN
	IF	GCDR = 0
	EXITM
	ENDIF
GCDM	SET	GCDN
GCDN	SET	GCDR
	ENDM
	ENDM
;
DISKDEF	MACRO	DN,FSC,LSC,SKF,BLS,DKS,DIR,CKS,OFS,K16
;;	GENERATE THE SET STATEMENTS FOR LATER TABLES
	IF	NUL LSC
;;	CURRENT DISK DN SAME AS PREVIOUS FSC
DPB&DN	EQU	DPB&FSC	;EQUIVALENT PARAMETERS
ALS&DN	EQU	ALS&FSC	;SAME ALLOCATION VECTOR SIZE
CSS&DN	EQU	CSS&FSC	;SAME CHECKSUM VECTOR SIZE
XLT&DN	EQU	XLT&FSC	;SAME TRANSLATE TABLE
	ELSE
SECMAX	SET	LSC-(FSC)	;;SECTORS 0...SECMAX
SECTORS	SET	SECMAX+1;;NUMBER OF SECTORS
ALS&DN	SET	(DKS)/8	;;SIZE OF ALLOCATION VECTOR
	IF	((DKS) MOD 8) NE 0
ALS&DN	SET	ALS&DN+1
	ENDIF
CSS&DN	SET	(CKS)/4	;;NUMBER OF CHECKSUM ELEMENTS
;;	GENERATE THE BLOCK SHIFT VALUE
BLKVAL	SET	BLS/128	;;NUMBER OF SECTORS/BLOCK
BLKSHF	SET	0	;;COUNTS RIGHT 0'S IN BLKVAL
BLKMSK	SET	0	;;FILLS WITH 1'S FROM RIGHT
	REPT	16	;;ONCE FOR EACH BIT POSITION
	IF	BLKVAL=1
	EXITM
	ENDIF
;;	OTHERWISE, HIGH ORDER 1 NOT FOUND YET
BLKSHF	SET	BLKSHF+1
BLKMSK	SET	(BLKMSK SHL 1) OR 1
BLKVAL	SET	BLKVAL/2
	ENDM
;;	GENERATE THE EXTENT MASK BYTE
BLKVAL	SET	BLS/1024	;;NUMBER OF KILOBYTES/BLOCK
EXTMSK	SET	0	;;FILL FROM RIGHT WITH 1'S
	REPT	16
	IF	BLKVAL=1
	EXITM
	ENDIF
;;	OTHERWISE MORE TO SHIFT
EXTMSK	SET	(EXTMSK SHL 1) OR 1
BLKVAL	SET	BLKVAL/2
	ENDM
;;	MAY BE DOUBLE BYTE ALLOCATION
	IF	(DKS) > 256
EXTMSK	SET	(EXTMSK SHR 1)
	ENDIF
;;	MAY BE OPTIONAL Æ0Å IN LAST POSITION
	IF	NOT NUL K16
EXTMSK	SET	K16
	ENDIF
;;	NOW GENERATE DIRECTORY RESERVATION BIT VECTOR
DIRREM	SET	DIR	;;# REMAINING TO PROCESS
DIRBKS	SET	BLS/32	;;NUMBER OF ENTRIES PER BLOCK
DIRBLK	SET	0	;;FILL WITH 1'S ON EACH LOOP
	REPT	16
	IF	DIRREM=0
	EXITM
	ENDIF
;;	NOT COMPLETE, ITERATE ONCE AGAIN
;;	SHIFT RIGHT AND ADD 1 HIGH ORDER BIT
DIRBLK	SET	(DIRBLK SHR 1) OR 8000H
	IF	DIRREM > DIRBKS
DIRREM	SET	DIRREM-DIRBKS
	ELSE
DIRREM	SET	0
	ENDIF
	ENDM
	DPBHDR	DN	;;GENERATE EQU $
	DDW	%SECTORS,<;SEC PER TRACK>
	DDB	%BLKSHF,<;BLOCK SHIFT>
	DDB	%BLKMSK,<;BLOCK MASK>
	DDB	%EXTMSK,<;EXTNT MASK>
	DDW	%(DKS)-1,<;DISK SIZE-1>
	DDW	%(DIR)-1,<;DIRECTORY MAX>
	DDB	%DIRBLK SHR 8,<;ALLOC0>
	DDB	%DIRBLK AND 0FFH,<;ALLOC1>
	DDW	%(CKS)/4,<;CHECK SIZE>
	DDW	%OFS,<;OFFSET>
;;	GENERATE THE TRANSLATE TABLE, IF REQUESTED
	IF	NUL SKF
XLT&DN	EQU	0		;NO XLATE TABLE
	ELSE
	IF	SKF = 0
XLT&DN	EQU	0		;NO XLATE TABLE
	ELSE
;;	GENERATE THE TRANSLATE TABLE
NXTSEC	SET	0	;;NEXT SECTOR TO FILL
NXTBAS	SET	0	;;MOVES BY ONE ON OVERFLOW
	GCD	%SECTORS,SKF
;;	GCDN = GCD(SECTORS,SKEW)
NELTST	SET	SECTORS/GCDN
;;	NELTST IS NUMBER OF ELEMENTS TO GENERATE
;;	BEFORE WE OVERLAP PREVIOUS ELEMENTS
NELTS	SET	NELTST	;;COUNTER
XLT&DN	EQU	$		;TRANSLATE TABLE
	REPT	SECTORS	;;ONCE FOR EACH SECTOR
	IF	SECTORS < 256
	DDB	%NXTSEC+(FSC)
	ELSE
	DDW	%NXTSEC+(FSC)
	ENDIF
NXTSEC	SET	NXTSEC+(SKF)
	IF	NXTSEC >= SECTORS
NXTSEC	SET	NXTSEC-SECTORS
	ENDIF
NELTS	SET	NELTS-1
	IF	NELTS = 0
NXTBAS	SET	NXTBAS+1
NXTSEC	SET	NXTBAS
NELTS	SET	NELTST
	ENDIF
	ENDM
	ENDIF	;;END OF NUL FAC TEST
	ENDIF	;;END OF NUL BLS TEST
	ENDM
;
DEFDS	MACRO	LAB,SPACE
LAB:	DS	SPACE
	ENDM
;
LDS	MACRO	LB,DN,VAL
	DEFDS	LB&DN,%VAL&DN
	ENDM
;
ENDEF	MACRO
;;	GENERATE THE NECESSARY RAM DATA AREAS
BEGDAT	EQU	$
DIRBUF:	DS	128	;DIRECTORY ACCESS BUFFER
DSKNXT	SET	0
	REPT	NDISKS	;;ONCE FOR EACH DISK
	LDS	ALV,%DSKNXT,ALS
	LDS	CSV,%DSKNXT,CSS
DSKNXT	SET	DSKNXT+1
	ENDM
ENDDAT	EQU	$
DATSIZ	EQU	$-BEGDAT
;;	DB 0 AT THIS POINT FORCES HEX RECORD
	ENDM
;
;;	GCDN = GCD(SECTORS,SKEW)
NELTST	SET	SECTORS/GCDN
;;	NELTST IS NUMBER OF ELEMENTS TO GENERATE
;;	BEFORE WE OVERLAP PREVIOUS ELEMENTS
NELTS	SET	NELTST	;;COUNTER
XLT&DN	EQU	$		;TRANSLATE TABLE
	REPT	SECTORS	;;ONCE FOR EACH SECTOR
	IF	SECTORS < 256
	DDB	%NXTSEC+(FSC)
	ELSE
	DDW	%NXTSEC+(FSC)
	ENDIF
NXTSEC	SET	NXTSEC+(SKF)
	IF	NXTSEC >= SECTORS
NXTSEC	SET	NXTSEC-SECTORS
	ENDIF
NELTS	SET	NELTS-1
	IF	NELTS = 0
NXTBAS	SET	NXTBAS+1
NXTSEC	SET	NXTBAS
NELTS	SET	NELTST
	ENDIF
	ENDM
	ENDIF	;;END OF NUL FAC TEST
	ENDIF	;;END OF NUL BLS TEST
	ENDM
;
DEFDS	MACRO	LAB,SPACE
LAB:	DS	SPACE
	ENDM
;
LDS	MACRO	LB,DN,VAL
	DEFDS	LB&DN,%VAL&DN
	ENDM
;
ENDEF	MACRO
;;	GENERATE THE NECESSARY RAM DATA AREAS
BEGDAT	EQU	$
DIRBUF:	DS	128	;DIRECTORY ACCESS BUFFER
DSKNXT	SET	0
	REPT	NDISKS	;;ONCE FOR EACH DISK
	LDS	ALV,%DSKNXT,ALS
	LDS	CSV,%DSKNXT,CSS
DSKNXT	SET	DSKNXT+1
	ENDM
ENDDAT	EQU	$
DATSIZ	EQU	$-BEGDAT
;;	DB 0 AT THIS POINT FORCES HEX RECORD
	ENDM
;
NXTBAS	SET	0	;;MOVES BY ONE ON OVERFLOW
	GCD	%SECTORS,SKF
;;	GCDN = GCD(SECTORS,SKEW)
NELTST	SET	SECTORS/GCDN
;;	NELTST IS NUMBER OF ELEMENTS TO GENERATE
;;	BEFORE WE OVERLAP PREVIOUS ELEMENTS
NELTS	SET	NELTST	;;COUNTER
XLT&DN	EQU	$		;TRANSLATE TABLE
	REPT	SECTORS	;;ONCE FOR EACH SECTOR
	IF	SECTORS < 256
	DDB	%NXTSEC+(FSC)
	ELSE
	DDW	%NXTSEC+(FSC)
	ENDIF
NXTSEC	SET	NXTSEC+(SKF)
	IF	NXTSEC >= SECTORS
NXTSEC	SET	NXTSEC-SECTORS
	ENDIF
NELTS	SET	NELTS-1
	IF	NELTS = 0
NXTBAS	SET	NXTBAS+1
NXTSEC	SET	NXTBAS
NELTS	SET	NELTST
	ENDIF
	ENDM
	ENDIF	;;END OF NUL FAC TEST
	ENDIF	;;END OF NUL BLS TEST
	ENDM
;
DEFDS	MACRO	LAB,SPACE
LAB:	DS	SPACE
	ENDM
;
LDS	MACRO	LB,DN,VAL
	DEFDS	LB&DN,%VAL&DN
	ENDM
;
ENDEF	MACRO
;;	GENERATE THE NECESSARY RAM DATA AREAS
BEGDAT	EQU	$
DIRBUF:	DS	128	;DIRECTORY ACCESS BUFFER
DSKNXT	SET	0
	REPT	NDISKS	;;ONCE FOR EACH DISK
	LDS	ALV,%DSKNXT,ALS
	LDS	CSV,%DSKNXT,CSS
DSKNXT	SET	DSKNXT+1
	ENDM
ENDDAT	EQU	$
DATSIZ	EQU	$-BEGDAT
;;	DB 0 AT THIS POINT FORCES HEX RECORD
	ENDM
;
ER
;	CP/M 2.0 DISK RE-DEFINITION LIBRARY
;
;	COPYRIGHT (C) 1979
;	DIGITAL RESEARCH
;	BOX 579
;	PACIFIC GROVE, CA
;	93950
;
;	CP/M LOGICAL DISK DRIVES ARE DEFINED USING THE
;	MACROS GIVEN BELOW, WHERE THE SEQUENCE OF CALLS
;	IS:
;
;	DISKS	N
;	DISKDEF	PARAMETER-LIST-0
;	DISKDEF	PARAMETER-LIST-1
;	...
;	DISKDEF	PARAMETER-LIST-N
;	ENDEF
;
;	WHERE N IS THE NUMBER OF LOGICAL DISK DRIVES ATTACHED
;	TO THE CP/M SYSTEM, AND PARAMETER-LIST-I DEFINES THE
;	CHARACTERISTICS OF THE ITH DRIVE (I=0,1,...,N-1)
;
;	EACH PARAMETER-LIST-I TAKES THE FORM
;		DN,FSC,LSC,ÆSKFÅ,BLS,DKS,DIR,CKS,OFS,Æ0Å
;	WHERE
;	DN	IS THE DISK NUMBER 0,1,...,N-1
;	FSC	IS THE FIRST SECTOR NUMBER (USUALLY 0 OR 1)
;	LSC	IS THE LAST SECTOR NUMBER ON A TRACK
;	SKF	IS OPTIONAL "SKEW FACTOR" FOR SECTOR TRANSLATE
;	BLS	IS THE DATA BLOCK SIZE (1024,2048,...,16384)
;	DKS	IS THE DISK SIZE IN BLS INCREMENTS (WORD)
;	DIR	IS THE NUMBER OF DIRECTORY ELEMENTS (WORD)
;	CKS	IS THE NUMBER OF DIR ELEMENTS TO CHECKSUM
;	OFS	IS THE NUMBER OF TRACKS TO SKIP (WORD)
;	Æ0Å	IS AN OPTIONAL 0 WHICH FORCES 16K/DIRECTORY ENTRY
;
;	FOR CONVENIENCE, THE FORM
;		DN,DM
;	DEFINES DISK DN AS HAVING THE SAME CHARACTERISTICS AS
;	A PREVIOUSLY DEFINED DISK DM.
;
;	A STANDARD FOUR DRIVE CP/M SYSTEM IS DEFINED BY
;		DISKS	4
;		DISKDEF	0,1,26,6,1024,243,64,64,2
;	DSK	SET	0
;		REPT	3
;	DSK	SET	DSK+1
;		DISKDEF	%DSK,0
;		ENDM
;		ENDEF
;
;	THE VALUE OF "BEGDAT" AT THE END OF ASSEMBLY DEFINES THE
;	BEGINNING OF THE UNINITIALIZE RAM AREA ABOVE THE BIOS,
;	WHILE THE VALUE OF "ENDDAT" DEFINES THE NEXT LOCATION
;	FOLLOWING THE END OF THE DATA AREA.  THE SIZE OF THIS
;	AREA IS GIVEN BY THE VALUE OF "DATSIZ" AT THE END OF THE
;	ASSEMBLY.  NOTE THAT THE ALLOCATION VECTOR WILL BE QUITE
;	LARGE IF A LARGE DISK SIZE IS DEFINED WITH A SMALL BLOCK
;	SIZE.
;
DSKHDR	MACRO	DN
;;	DEFINE A SINGLE DISK HEADER LIST
DPE&DN:	DW	XLT&DN,0000H	;TRANSLATE TABLE
	DW	0000H,0000H	;SCRATCH AREA
	DW	DIRBUF,DPB&DN	;DIR BUFF,PARM BLOCK
	DW	CSV&DN,ALV&DN	;CHECK, ALLOC VECTORS
	ENDM
;
DISKS	MACRO	ND
;;	DEFINE ND DISKS
NDISKS	SET	ND	;;FOR LATER REFERENCE
DPBASE	EQU	$	;BASE OF DISK PARAMETER BLOCKS
;;	GENERATE THE ND ELEMENTS
DSKNXT	SET	0
	REPT	ND
	DSKHDR	%DSKNXT
DSKNXT	SET	DSKNXT+1
	ENDM
	ENDM
;
DPBHDR	MACRO	DN
DPB&DN	EQU	$		;DISK PARM BLOCK
	ENDM
;
DDB	MACRO	DATA,COMMENT
;;	DEFINE A DB STATEMENT
	DB	DATA		COMMENT
	ENDM
;
DDW	MACRO	DATA,COMMENT
;;	DEFINE A DW STATEMENT
	DW	DATA		COMMENT
	ENDM
;
GCD	MACRO	M,N
;;	GREATEST COMMON DIVISOR OF M,N
;;	PRODUCES VALUE GCDN AS RESULT
;;	(USED IN SECTOR TRANSLATE TABLE GENERATION)
GCDM	SET	M	;;VARIABLE FOR M
GCDN	SET	N	;;VARIABLE FOR N
GCDR	SET	0	;;VARIABLE FOR R
	REPT	65535
GCDX	SET	GCDM/GCDN
GCDR	SET	GCDM - GCDX*GCDN
	IF	GCDR = 0
	EXITM
	ENDIF
GCDM	SET	GCDN
GCDN	SET	GCDR
	ENDM
	ENDM
;
DISKDEF	MACRO	DN,FSC,LSC,SKF,BLS,DKS,DIR,CKS,OFS,K16
;;	GENERATE THE SET STATEMENTS FOR LATER TABLES
	IF	NUL LSC
;;	CURRENT DISK DN SAME AS PREVIOUS FSC
DPB&DN	EQU	DPB&FSC	;EQUIVALENT PARAMETERS
ALS&DN	EQU	ALS&FSC	;SAME ALLOCATION VECTOR SIZE
CSS&DN	EQU	CSS&FSC	;SAME CHECKSUM VECTOR SIZE
XLT&DN	EQU	XLT&FSC	;SAME TRANSLATE TABLE
	ELSE
SECMAX	SET	LSC-(FSC)	;;SECTORS 0...SECMAX
SECTORS	SET	SECMAX+1;;NUMBER OF SECTORS
ALS&DN	SET	(DKS)/8	;;SIZE OF ALLOCATION VECTOR
	IF	((DKS) MOD 8) NE 0
ALS&DN	SET	ALS&DN+1
	ENDIF
CSS&DN	SET	(CKS)/4	;;NUMBER OF CHECKSUM ELEMENTS
;;	GENERATE THE BLOCK SHIFT VALUE
BLKVAL	SET	BLS/128	;;NUMBER OF SECTORS/BLOCK
BLKSHF	SET	0	;;COUNTS RIGHT 0'S IN BLKVAL
BLKMSK	SET	0	;;FILLS WITH 1'S FROM RIGHT
	REPT	16	;;ONCE FOR EACH BIT POSITION
	IF	BLKVAL=1
	EXITM
	ENDIF
;;	OTHERWISE, HIGH ORDER 1 NOT FOUND YET
BLKSHF	SET	BLKSHF+1
BLKMSK	SET	(BLKMSK SHL 1) OR 1
BLKVAL	SET	BLKVAL/2
	ENDM
;;	GENERATE THE EXTENT MASK BYTE
BLKVAL	SET	BLS/1024	;;NUMBER OF KILOBYTES/BLOCK
EXTMSK	SET	0	;;FILL FROM RIGHT WITH 1'S
	REPT	16
	IF	BLKVAL=1
	EXITM
	ENDIF
;;	OTHERWISE MORE TO SHIFT
EXTMSK	SET	(EXTMSK SHL 1) OR 1
BLKVAL	SET	BLKVAL/2
	ENDM
;;	MAY BE DOUBLE BYTE ALLOCATION
	IF	(DKS) > 256
EXTMSK	SET	(EXTMSK SHR 1)
	ENDIF
;;	MAY BE OPTIONAL Æ0Å IN LAST POSITION
	IF	NOT NUL K16
EXTMSK	SET	K16
	ENDIF
;;	NOW GENERATE DIRECTORY RESERVATION BIT VECTOR
DIRREM	SET	DIR	;;# REMAINING TO PROCESS
DIRBKS	SET	BLS/32	;;NUMBER OF ENTRIES PER BLOCK
DIRBLK	SET	0	;;FILL WITH 1'S ON EACH LOOP
	REPT	16
	IF	DIRREM=0
	EXITM
	ENDIF
;;	NOT COMPLETE, ITERATE ONCE AGAIN
;;	SHIFT RIGHT AND ADD 1 HIGH ORDER BIT
DIRBLK	SET	(DIRBLK SHR 1) OR 8000H
	IF	DIRREM > DIRBKS
DIRREM	SET	DIRREM-DIRBKS
	ELSE
DIRREM	SET	0
	ENDIF
	ENDM
	DPBHDR	DN	;;GENERATE EQU $
	DDW	%SECTORS,<;SEC PER TRACK>
	DDB	%BLKSHF,<;BLOCK SHIFT>
	DDB	%BLKMSK,<;BLOCK MASK>
	DDB	%EXTMSK,<;EXTNT MASK>
	DDW	%(DKS)-1,<;DISK SIZE-1>
	DDW	%(DIR)-1,<;DIRECTORY MAX>
	DDB	%DIRBLK SHR 8,<;ALLOC0>
	DDB	%DIRBLK AND 0FFH,<;ALLOC1>
	DDW	%(CKS)/4,<;CHECK SIZE>
	DDW	%OFS,<;OFFSET>
;;	GENERATE THE TRANSLATE TABLE, IF REQUESTED
	IF	NUL SKF
XLT&DN	EQU	0		;NO XLATE TABLE
	ELSE
	IF	SKF = 0
XLT&DN	EQU	0		;NO XLATE TABLE
	ELSE
;;	GENERATE THE TRANSLATE TABLE
NXTSEC	SET	0	;;NEXT SECTOR TO FILL
NXTBAS	SET	0	;;MOVES BY ONE ON OVERFLOW
	GCD	%SECTORS,SKF
;;	GCDN = GCD(SECTORS,SKEW)
NELTST	SET	SECTORS/GCDN
;;	NELTST IS NUMBER OF ELEMENTS TO GENERATE
;;	BEFORE WE OVERLAP PREVIOUS ELEMENTS
NELTS	SET	NELTST	;;COUNTER
XLT&DN	EQU	$		;TRANSLATE TABLE
	REPT	SECTORS	;;ONCE FOR EACH SECTOR
	IF	SECTORS < 256
	DDB	%NXTSEC+(FSC)
	ELSE
	DDW	%NXTSEC+(FSC)
	ENDIF
NXTSEC	SET	NXTSEC+(SKF)
	IF	NXTSEC >= SECTORS
NXTSEC	SET	NXTSEC-SECTORS
	ENDIF
NELTS	SET	NELTS-1
	IF	NELTS = 0
NXTBAS	SET	NXTBAS+1
NXTSEC	SET	NXTBAS
NELTS	SET	NELTST
	ENDIF
	ENDM
	ENDIF	;;END OF NUL FAC TEST
	ENDIF	;;END OF NUL BLS TEST
	ENDM
;
DEFDS	MACRO	LAB,SPACE
LAB:	DS	SPACE
	ENDM
;
LDS	MACRO	LB,DN,VAL
	DEFDS	LB&DN,%VAL&DN
	ENDM
;
ENDEF	MACRO
;;	GENERATE THE NECESSARY RAM DATA AREAS
BEGDAT	EQU	$
DIRBUF:	DS	128	;DIRECTORY ACCESS BUFFER
DSKNXT	SET	0
	REPT	NDISKS	;;ONCE FOR EACH DISK
	LDS	ALV,%DSKNXT,ALS
	LDS	CSV,%DSKNXT,CSS
DSKNXT	SET	DSKNXT+1
	ENDM
ENDDAT	EQU	$
DATSIZ	EQU	$-BEGDAT
;;	DB 0 AT THIS POINT FORCES HEX RECORD
	ENDM
;
EN
TEST TSET
1234567890
SLUT FOR TEST 5
«eof»