*	PRINT A CP/M BLOCK VERSUS TRACK-SECTOR
*	CROSS REFERENCE TABLE FOR ANY SYSTEM
*	CONFIGURATION.		8/4/81
*
*	SET THE DISK PARAMETERS TO MATCH YOUR
*	SYSTEM CONFIGURATION.  IF YOU NEED A
*	DIFFERENT LACE TABLE, IT MUST REPLACE
*	THE ONE AT THE END OF THE PROGRAM.
*	THE PARAMETERS ARE PRESET TO THE 
*	STANDARD VALUES FOR AN 8" DISK.
*
FALSE	EQU	0
TRUE	EQU	NOT FALSE
*
*	DISK PARAMETERS
*
SECTRK	EQU	26	;SECTORS PER TRACK
TRKDSK	EQU	77	;TRACKS PER DISK
SECBLK	EQU	8	;SECTORS PER CP/M BLOCK
SYSTRK	EQU	2	;SYSTEM TRACKS
DIRSIZ	EQU	64	;DIRECTORY SIZE
LACE	EQU	TRUE	;LACE TABLE REQUIRED
FIRST	EQU	1	;FIRST SECTOR NUMBER
*
	ORG	100H
*
*	PRINT HEADING
*
START:	LXI	D,MSG1
	MVI	C,PRSTR
	CALL	BDOS
*
*	PRINT DIRECTORY SUB-HEADING
*
	LXI	D,MSG2
	MVI	C,PRSTR
	CALL	BDOS
*
*	INIT VARIABLES
*
	XRA	A
	STA	BLOCK	;CP/M BLOCK NUMBER
	STA	TRACK	;ACTUAL TRACK NUMBER
	INR	A
	STA	SECTOR	;SEQUENTIAL SECTOR NUMBER
*
*	MAIN LOOP POINT
*
LOOP:	LDA	BLOCK	;GET CURRENT BLOCK NUMBER
	CPI	DIRBLK	;TIME FOR DATA SUB-HEADING?
	JNZ	LOOP1	;NO
*
*	PRINT DATA SUB-HEADING
*
	LXI	D,MSG3	;YES
	MVI	C,PRSTR
	CALL	BDOS	;PRINT DATA SUB-HEADING
LOOP1:	LDA	BLOCK	;GET CURRENT BLOCK NUMBER
	MOV	L,A
	MVI	H,0
	MVI	A,SECBLK	;GET SECTORS/BLOCK
	DCR	A	;CONVERT TO MASK
LOOP2:	DAD	H	;DOUBLE VALUE
	STC		;SET CARRY
	CMC		;CLEAR CARRY
	RAR		;SHIFT MASK
	ORA	A	;SHIFT COMPLETE?
	JNZ	LOOP2	;NO
	PUSH	H	;YES, SAVE BLOCK*SECBLK
	MVI	C,0
	LXI	D,-SECTRK
DIV:	DAD	D
	INR	C
	JC	DIV
	DCR	C
	MOV	A,C
	ADI	SYSTRK
	STA	TRACK	;TRACK NUMBER
	MVI	B,SECTRK
	XRA	A
	INR	C
MUL:	DCR	C
	JZ	MULD
	ADD	B
	JMP	MUL
MULD:	CMA
	MOV	C,A
	MVI	B,0FFH
	INX	B
	POP	H
	DAD	B
	MOV	A,L
	STA	TEMP	;SAVE SEQUENTIAL SECTOR
	CALL	XLATE	;GET ACTUAL SECTOR NUMBER
	PUSH	PSW	;SAVE RESULT
	CALL	SPC2	;PRINT 2 SPACES
	LDA	BLOCK	;GET BLOCK NUMBER
	CALL	HEXPRN	;PRINT IT
	CALL	SPC4	;PRINT 4 SPACES
	LDA	TRACK	;GET TRACK
	CALL	HEXPRN	;PRINT IT
	CALL	DASH	;PRINT A DASH
	POP	PSW	;GET SECTOR
	CALL	HEXPRN	;PRINT IT
	MVI	A,SECBLK-1	;SET COLUMN COUNTER
	STA	COL
COLOP:	LDA	TEMP	;GET SEQUENTIAL
	INR	A
	STA	TEMP
	CPI	SECTRK	;END OF TRACK?
	JNZ	SKIP	;NO
	MVI	A,0	;YES
	STA	TEMP
	LXI	H,TRACK
	INR	M
SKIP:	CALL	SPC2	;PRINT 2 SPACES
	LDA	TRACK
	CALL	HEXPRN	;PRINT TRACK
	CALL	DASH	;PRINT A DASH
	LDA	TEMP	;GET SEQUENTIAL
	CALL	XLATE	;CONVERT TO ACTUAL
	CALL	HEXPRN	;PRINT IT
	LXI	H,COL	;POINT TO COLUMN COUNT
	DCR	M	;DONE?
	JZ	COLDN	;YES
	MOV	A,M	;NO, NEW LINE REQD?
	ANI	7
	JNZ	COLOP	;NO
	LXI	D,CRLF	;YES
	MVI	C,PRSTR
	CALL	BDOS
	CALL	SPC4	;BYPASS BLOCK COLUMN
	CALL	SPC2
	JMP	COLOP
COLDN:	LXI	D,CRLF	;NEW LINE
	MVI	C,PRSTR
	CALL	BDOS
	LDA	BLOCK	;GET CP/M BLOCK
	INR	A
	STA	BLOCK
	CPI	MAXBLK	;END OF DISK?
	JNZ	LOOP	;NO
*
*	PRINT UNUSED SUB-HEADING
*
	LXI	D,MSG4	;YES
	MVI	C,PRSTR
	CALL	BDOS	;PRINT UNUSED SUB-HD
	LXI	H,TEMP
	INR	M
	CALL	SPC2	;PRINT 2 SPACES
	LDA	BLOCK
	CALL	HEXPRN
	CALL	SPC4	;PRINT 4 SPACES
	LDA	TRACK
	CALL	HEXPRN	;PRINT TRACK
	CALL	DASH	;PRINT A DASH
	LDA	TEMP	;GET SEQUENTIAL SECTOR
	CALL	XLATE	;ACTUAL SECTOR
	CALL	HEXPRN	;PRINT IT
	MVI	A,UNUSED-1	;SET COLUMN COUNTER
	STA	COL
COLOP1:	LXI	H,TEMP	;STEP SEQUENTIAL SECTOR
	INR	M
	CALL	SPC2	;PRINT 2 SPACES
	LDA	TRACK
	CALL	HEXPRN	;PRINT TRACK
	CALL	DASH	;PRINT A DASH
	LDA	TEMP	;GET SEQUENTIAL
	CALL	XLATE	;CONVERT TO ACTUAL
	CALL	HEXPRN	;PRINT IT
	LXI	H,COL	;POINT TO COLUMN COUNT
	DCR	M	;DONE?
	JNZ	COLOP1	;NO
	LXI	D,CRLF	;YES, NEW LINE
	MVI	C,PRSTR
	CALL	BDOS
	RET		;BACK TO CCP
*
*	TRANSLATE SEQUENTIAL TO ACTUAL SECTOR
*
	IF	LACE
XLATE:	MOV	E,A
	MVI	D,0
	LXI	H,LACETB	;BASE OF TABLE
	DAD	D	;POINT TO ACTUAL SECTOR
	MOV	A,M	;GET ACTUAL SECTOR
	ENDIF
	IF	NOT LACE
XLATE:	ADI	FIRST
	ENDIF
	RET
*
*	PRINT ACCUMULATOR IN HEX
*
HEXPRN:	PUSH	PSW	;SAVE FOR 2ND DIGIT
	RRC
	RRC
	RRC
	RRC
	CALL	PRDGIT	;PRINT HEX DIGIT
	POP	PSW	;GET 2ND DIGIT
PRDGIT:	ANI	0FH	;HEX VALUE
	ADI	90H	;CONVERT TO ASCII
	DAA
	ACI	40H
	DAA
	MOV	E,A
	MVI	C,PRCHAR
	CALL	BDOS	;PRINT DIGIT
	RET
*
*	PRINT 2 OR 4 SPACES
*
SPC2:	LXI	D,MSG4SP+2	;2 SPACES
	JMP	SPC
SPC4:	LXI	D,MSG4SP	;4 SPACES
SPC:	MVI	C,PRSTR
	JMP	BDOS
*
*	PRINT A DASH
*
DASH:	MVI	E,'-'
	MVI	C,PRCHAR
	JMP	BDOS
*
*	MESSAGES
*
MSG1:	DB	FF,'	CP/M BLOCK NUMBERS VERSUS '
	DB	'TRACK-SECTOR',CR,LF,CR,LF,'$'
MSG2:	DB	CR,LF,' BLOCK  TRACK-SECTOR'
	DB	'      (DIRECTORY)',CR,LF,'$'
MSG3:	DB	CR,LF,' BLOCK  TRACK-SECTOR'
	DB	'      (DATA AREA)',CR,LF,'$'
MSG4:	DB	CR,LF,' BLOCK  TRACK-SECTOR'
	DB	'      (UNUSED)'
CRLF:	DB	CR,LF,'$'
MSG4SP:	DB	'    $'	;4 SPACES
	IF	LACE
*
*	LACE TABLE
*
LACETB:	DB	1,7,13,19,25,5,11,17,23,3,9,15,21
	DB	2,8,14,20,26,6,12,18,24,4,10,16,22
	ENDIF
*
*	EQUATES
*
BDOS	EQU	5	;BDOS ENTRY POINT
PRCHAR	EQU	2	;PRINT CHARACTER
PRSTR	EQU	9	;PRINT STRING FUNCTION
FF	EQU	0CH	;FORM FEED
CR	EQU	0DH	;CARRIAGE RETURN
LF	EQU	0AH	;LINE FEED
MAXBLK	EQU	((TRKDSK-SYSTRK)*SECTRK)/SECBLK
UNUSED	EQU	((TRKDSK-SYSTRK)*SECTRK)-(MAXBLK*SECBLK)
DIRBLK	EQU	DIRSIZ/(SECBLK*4)
*
*	BUFFERS
*
BLOCK:	DS	1	;CURRENT BLOCK NUMBER
TRACK:	DS	1	;CURRENT TRACK
SECTOR:	DS	1	;CURRENT SECTOR (UNTRANSLATED)
COL:	DS	1	;COLUMN COUNTER
TEMP:	DS	1	;TEMPORARY SECTOR
	END	START
RRENT TRACK
SECTO