	TITLE	'SECTOR DISK MAINTENANCE PROGRAM'
;	DERIVED 8/77 W. EARNEST
;	MODIFIED 9/77 FOR EFFICIENCY+LOGIC
;	MODIFIED 4/07/78 FOR MORE FEATURES
;	MODIFIED 1/15/79 FOR CP/M USAGE
;	MODIFIED 7/14/80 FOR CP/M REV 2.X
;
BDOS	EQU	5
BOOT	EQU	0	;BDOS FUNCT CODES
CONIN	EQU	1
CONOU	EQU	2
LIST	EQU	5
PMSG	EQU	9
REVNR	EQU	12
GETDPB	EQU	31
;			BIOS OFFSETS
SDRV	EQU	27
STRK	EQU	30
SSEC	EQU	33
SDMA	EQU	36
READ	EQU	39
WRITE	EQU	42
SECTRN	EQU	48
;
	ORG	100H
BEGIN:	LXI	SP,STACK
	MVI	C,REVNR
	CALL	BDOS	;CHECK SYSTEM REVISION
	MOV	A,L
	ORA	A
	JNZ	CPMOK	;CURRENT SYSTEM
	LXI	D,REVMSG
	CALL	MSGO
	JMP	EXIT	;GIVE UP NOW
;
CPMOK:	LDA	2	;BIOS PAGE BYTE
	STA	SEDMA+2
	STA	FILBF+2
	STA	WRTBF+2
	STA	SESCT+2
	STA	SETRK+2
	STA	SEDRV+2
	STA	SCTRN+2
	LXI	B,BUFFR
SEDMA:	CALL	SDMA
	JMP	START
;
EXIT:	CALL	CRLF
	JMP	BOOT
;
CO:	PUSH	PSW
	PUSH	H
	PUSH	D
	PUSH	B
	MVI	C,CONOU
	MOV	E,A
	CALL	BDOS
	POP	B
	POP	D
	POP	H
	POP	PSW
	RET	
;
CI:	MVI	C,CONIN
	PUSH	H
	PUSH	D
	CALL	BDOS
	POP	D
	POP	H
	ANI	7FH
	CPI	1BH	;ESC CODE
	JZ	ESCCH	;ABORT THIS COMMAND
	CPI	61H	;LOWER  CASE A
	RC
	ANI	5FH	;CONVT TO UPPER
	RET	
;
SO:	JMP	CO	;VARIABLE JUMP FOR PRINT
;
LO:	PUSH	PSW
	PUSH	H
	PUSH	D
	PUSH	B
	MVI	C,LIST
	MOV	E,A
	CALL	BDOS
	POP	B
	POP	D
	POP	H
	POP	PSW
	RET
;
DEFUN:	LXI	D,PRMUN
	CALL	MSGO
UNAGN:	CALL	IN2NR
	MOV	A,L
KPUNT:	STA	NUNIT
DEFTK:	LXI	D,PRMTK
	CALL	MSGO
TKAGN:	CALL	IN2NR
	MOV	A,L
	CPI	77
	JC	KPTRK
	CALL	INERR
	JMP	TKAGN
;
KPTRK:	STA	NTRAK
DEFSC:	LXI	D,PRMSC
	CALL	MSGO
SCAGN:	CALL	IN2NR
	DCR	L	;START W/SCTR 1
	MOV	A,L
KPSCT:	STA	NSCTR
MODBR:	JMP	LDBUF	;CHGS FOR BLOCK MOVE
;
LDBUF:	LDA	BUFLG
	ORA	A
	JNZ	WTBUF
	CALL	SUPRD
	CALL	FILBF
PRINT:	CALL	PRBUF
;
START:	LXI	SP,STACK
	CALL	PRMPT
	CALL	CI
	SUI	'A'	;TABLE START VALUE
	JC	INVLID	;BELOW LEGAL RANGE
	CPI	'Z'-'A'+1 ;END OF TABLE
	JNC	INVLID	;ABOVE LEGAL RANGE
	ADD	A	;DOUBLE
	MOV	E,A
	MVI	D,0
	LXI	H,DOTBL
	DAD	D	;CALCULATE VECTOR
	MOV	A,M
	INX	H
	MOV	H,M
	MOV	L,A
	CALL	CRLF
	PCHL		;GO TO ROUTINE
;
ESCCH:	POP	H
	LXI	D,CANMSG
	JMP	EMSG
;
INVLID:	CALL	CRLF
	LXI	D,INVAL
EMSG:	CALL	MSGO
	JMP	START
;
DOTBL:	DW	TOMEM	;A DISK TO MEMORY
	DW	BLKMV	;B BLOCK MOVE
	DW	CHGBF	;C CHANGE CONTENTS
	DW	DMODE	;D DECIMAL MODE
	DW	EXTTBL	;E EXTRNAL XLATE
	DW	PHSTBL	;F PHYSICAL SECTORS
	DW	GENTBL	;G LOGICAL SECTORS
	DW	HMODE	;H HEXADECIMAL MODE
	DW	START	;I
	DW	START	;J
	DW	EXIT	;K EXIT TO CP/M
	DW	LSET	;L LINE PRINTER OUT
	DW	MOVE	;M MOVE SECTOR
	DW	START	;N
	DW	START	;O
	DW	PRINT	;P PRINT BUFFER
	DW	START	;Q
	DW	START	;R
	DW	DEFSC	;S SET SECTOR
	DW	DEFTK	;T SET TRACK
	DW	DEFUN	;U SET UNIT
	DW	VSET	;V VIDEO OUTPUT
	DW	WTBUF	;W WRITE BUFF TO DISK
	DW	XLATE	;X XLATE BLOCK (INTERLACE)
	DW	START	;Y
	DW	FRMEM	;Z MEMORY TO DISK
;
PHSTBL:	LXI	H,PHMAP
	MVI	A,'F'
	JMP	TBLST
;
GENTBL:	LXI	H,GENMAP
	MVI	A,'G'
;
TBLST:	SHLD	HLDIT
	SHLD	HLDOT
	STA	PRMST
	JMP	START
;
XLATE:	CALL	CI
	LXI	H,PHMAP
	CPI	'F'
	JZ	XLSET
	LXI	H,GENMAP
	CPI	'G'
	JZ	XLSET
	LXI	H,EXMAP
	CPI	'E'
	JZ	XLSET
	JMP	INVLID
;
EXTTBL:	LXI	H,EXTBL	;TABLE FOR EXTRN SKEW
	SHLD	CHGBAS
	LXI	H,EXMAP
	SHLD	HLDIT
	SHLD	HLDOT
	MVI	A,'E'
	STA	PRMST
	MVI	B,0
	PUSH	B
	JMP	CHGLP
;
CHGBF:	LXI	H,BUFFR-1
	SHLD	CHGBAS
	CALL	IN2NR
	MOV	B,L
	PUSH	B
CHGLP:	CALL	IN2NR
	POP	B
	LDA	LSTCH
	CPI	0DH	;CR?
	JZ	CHEND	;YES
	MOV	C,L
	MOV	A,B
	CPI	129
	JNC	RGERR
	LHLD	CHGBAS
	ADD	L
	MOV	L,A
	JNC	NCARY
	INR	H
NCARY:	MOV	M,C
	INR	B
	PUSH	B
	LDA	LSTCH
	CPI	'.'
	JNZ	CHGLP
	POP	B
CHEND:	CALL	CRLF
	JMP	START
;
RGERR:	LXI	D,RNMSG
	JMP	EMSG
;
WTBUF:	CALL	SUPWT
	CALL	WRTBF
	XRA	A
	STA	BUFLG
	JMP	START
;
MOVE:	CALL	CRLF
	LXI	D,ADMSG
	CALL	MSGO
	MVI	A,1
	STA	BUFLG	;MARK TO BE WRITTEN
	CALL	CRLF
	JMP	DEFUN
;
XLSET:	SHLD	HLDOT
BLKMV:	LXI	D,FRMMG
	LXI	H,RDSTU
STUCOM:	SHLD	MODBR+1
	CALL	MSGO
	CALL	CRLF
	JMP	DEFUN
;
RDSTU:	LHLD	NSCTR
	SHLD	RSCTR
	LHLD	NTRAK
	SHLD	RTRAK
	LXI	D,TOMSG
	LXI	H,WTSTU
	JMP	STUCOM
;
WTSTU:	LXI	D,SIZMG
	CALL	MSGO
	CALL	INNRS
	SHLD	SCTCT
	LXI	H,LDBUF
	SHLD	MODBR+1
MORBL:	CALL	SUPBK
	CALL	FILBF
	CALL	SUPWT
	CALL	WRTBF
	LXI	H,NSCTR
	CALL	INCAD
	LXI	H,RSCTR
	CALL	INCAD
	LHLD	SCTCT
	DCX	H
	SHLD	SCTCT
	MOV	A,L
	ORA	H
	JNZ	MORBL
	JMP	START
;
INCAD:	INR	M
	LDA	SPERT
	CMP	M
	JZ	TKEND
	RNC
TKEND:	MVI	M,0
	INX	H
	INX	H
	INR	M
	RET
;
PRMPT	LXI	D,PRMST	;PROMPT STRING
	JMP	MSGO
;
INERR:	LXI	D,ERRMG
MSGO:	MVI	C,PMSG
	JMP	BDOS
;
LMSG:	CALL	PCRLF
LMSGL:	LDAX	D
	CPI	'$'
	RZ
	CALL	SO
	INX	D
	JMP	LMSGL
;
IN2NR:	CALL	INNRS
	MOV	A,H
	ORA	A
	RZ
	LXI	D,LMSG1
	CALL	MSGO
	JMP	IN2NR
;
INNRS:	LXI	H,0
NRSLP:	PUSH	H
	CALL	CI
	STA	LSTCH
	CPI	0DH
	POP	H
	JZ	LINFD
	CPI	','
	RZ	
	CPI	'.'
	RZ	
	CALL	HEXBI
	JNC	NRSLP
	LXI	D,LMSG2
	CALL	MSGO
	JMP	INNRS
;
LINFD:	MVI	A,0AH
	JMP	CO
;
HEXBI:	CPI	'0'
	RC	
	CPI	'9'+1
	JC	CVNUM
	CPI	'A'
	RC	
	CPI	'G'
ALJMP:	JC	CVALP
NRBAD:	STC	
	RET	
;
CVALP:	ADI	9
CVNUM:	ANI	0FH
	PUSH	H
	POP	D
	DAD	H
	RC	
	DAD	H
	RC	
HDCHG:	DAD	H
	RC	
	DAD	H
	RC	
	ADD	L
	MOV	L,A
	RET	
;
DMODE:	MVI	A,'D'
	STA	PRMST+1
	MVI	A,19H	;DAD D
	LXI	H,NRBAD
MDCOM:	STA	HDCHG
	SHLD	ALJMP+1
	JMP	START
;
HMODE:	MVI	A,'H'
	STA	PRMST+1
	MVI	A,29H	;DAD	H
	LXI	H,CVALP
	JMP	MDCOM
;
CRLF:	MVI	A,0DH
	CALL	CO
	MVI	A,0AH
	JMP	CO
;
FILBF:	JMP	READ
;
WRTBF:	JMP	WRITE
;
SUPBK:	LDA	RUNIT
	MOV	C,A
	CALL	SEDRV
	LDA	RTRAK
	ANI	7FH
	MOV	C,A
	CALL	SETRK
	LHLD	RSCTR
	XCHG
	LXI	H,HLDIT
	JMP	GTSEC
;
SUPRD:	LXI	H,HLDIT
SUUTK:	PUSH	H
	LDA	NUNIT
	MOV	C,A
	CALL	SEDRV
	LDA	NTRAK
	ANI	7FH
	MOV	C,A
	CALL	SETRK
	LHLD	NSCTR
	XCHG
	POP	H
	JMP	GTSEC
;
SUPWT:	LXI	H,HLDOT
	JMP	SUUTK
;
SEDRV:	CALL	SDRV
	MOV	A,H
	ORA	L
	JZ	UNIERR
	MOV	E,M
	INX	H
	MOV	D,M
	XCHG
	SHLD	XLTADR
	LXI	H,9
	DAD	D
	MOV	E,M
	INX	H
	MOV	D,M
	XCHG
	MOV	A,M
	STA	SPERT
	RET
;
SETRK:	JMP	STRK
UNIERR:	LXI	D,UNERMG
	JMP	EMSG
;
TOMEM:	LXI	D,MVMSG
	CALL	MSGO
	CALL	INNRS
	LXI	D,BUFFR
MVCOM:	MVI	B,128
MMVLP:	LDAX	D
	MOV	M,A
	INX	D
	INX	H
	DCR	B
	JNZ	MMVLP
	JMP	START
;
FRMEM:	LXI	D,MVMSG
	CALL	MSGO
	CALL	INNRS
	LXI	D,BUFFR
	XCHG
	JMP	MVCOM
;
PRBUF:	LDA	NUNIT
	ORI	'0'
	STA	IDMSG+5
	LDA	NTRAK
	LXI	H,IDMSG+13
	CALL	PBYT
	LDA	NSCTR
	INR	A
	LXI	H,IDMSG+23
	CALL	PBYT
	LXI	D,IDMSG
	CALL	LMSG
	LXI	D,BUFFR
	PUSH	D
	CALL	PCRLF
	MVI	A,1
PRBGN:	STA	PRPTR
	POP	D
PRILP:	PUSH	D
	LDA	PRPTR
	CALL	PRADR
	POP	D
	PUSH	D
	CALL	PRSPC
	CALL	PR4BT
	CALL	PRSPC
	CALL	PR4BT
	CALL	PRSPC
	CALL	PR4BT
	CALL	PRSPC
	CALL	PR4BT
	CALL	PRSPC
	POP	D
	CALL	PRLIT
	PUSH	D
	CALL	PCRLF
	POP	D
	LDA	PRPTR
	ADI	10H
	STA	PRPTR
	CPI	81H
	JNZ	PRILP
	RET	
;
PR4BT:	CALL	PRHWD
	CALL	PRHWD
	RET	
;
PRHWD:	LDAX	D
	INX	D
	MOV	H,A
	LDAX	D
	INX	D
	MOV	L,A
	PUSH	D
	CALL	HEXCH
	POP	D
	RET	
;
PBYT:	PUSH	PSW
	RAR
	RAR
	RAR
	RAR
	CALL	CNIB
	POP	PSW
CNIB:	ANI	0FH
	CPI	10
	JC	NNIB
	ADI	7
NNIB:	ADI	'0'
	MOV	M,A
	INX	H
	RET
;
PRSPC:	MVI	A,' '
	JMP	SO
;
PRLIT:	MVI	A,'*'
	CALL	SO
	MVI	B,10H
LITLP:	LDAX	D
	INX	D
	CPI	' '
	JC	INVIS
	CPI	80H
	JNC	INVIS
LITBR:	CALL	SO
	DCR	B
	JNZ	LITLP
	MVI	A,'*'
	JMP	SO
;
INVIS:	MVI	A,'.'
	JMP	LITBR
;
PRADR:	MOV	L,A
	MVI	H,0
HEXCH:	MVI	D,4
HEXLP:	XRA	A
	DAD	H
	RAL	
	DAD	H
	RAL	
	DAD	H
	RAL	
	DAD	H
	RAL	
	CPI	10
	JC	NTALP
	ADI	7
NTALP:	ADI	'0'
	CALL	SO
	DCR	D
	JNZ	HEXLP
	RET	
;
PCRLF:	MVI	A,0AH
	CALL	SO
	MVI	A,0DH
	JMP	SO
;
LSET:	LXI	H,LO
	MVI	A,'L'
PSET:	SHLD	SO+1
	STA	PRMST+2
	JMP	START
;
VSET:	LXI	H,CO
	MVI	A,'V'
	JMP	PSET
;
GTSEC:	LDA	SPERT
	CMP	E	;NR WANTED
	JZ	SECERR
	JC	SECERR
	MOV	A,M
	INX	H
	MOV	H,M
	MOV	L,A
	PCHL
;
SECERR:	LXI	D,SECERM
	JMP	EMSG
;
PHMAP:	MOV	C,E
	INR	C
SESCT:	JMP	SSEC
;
EXMAP:	LXI	H,EXTBL
	SHLD	XLTADR
;
GENMAP:	MOV	C,E
	MOV	B,D
	LHLD	XLTADR
	XCHG
SCTRN:	CALL	SECTRN
	MOV	C,L
	JMP	SESCT
;
EXTBL:	DB	1,2,3,4,5
	DB	6,7,8,9,10
	DB	11,12,13,14,15
	DB	16,17,18,19,20
	DB	21,22,23,24,25
	DB	26,27,28,29,30
	DB	31,32,33,34,35
	DB	36,37,38,39,40
	DB	41,42,43,44,45
	DB	46,47,48,49,50
	DB	51,52,53,54,55
	DB	56,57,58,59,60
	DB	61,62,63,64
;
REVMSG:	DB	'Not valid CP/M revision!!$'
INVAL:	DB	'Invalid Command:$'
RNMSG:	DB	'Range exceeded:$'
PRMTK:	DB	'Enter Track:$'
PRMSC:	DB	'Enter Sector:$'
PRMUN:	DB	'Enter Unit:$'
FRMMG:	DB	'Enter Sending address:$'
TOMSG:	DB	'Enter Receiving address:$'
SIZMG:	DB	'Enter Number of Sectors to move:$'
ADMSG:	DB	'Enter new address:$'
MVMSG:	DB	'Enter Memory address:$'
IDMSG:	DB	'Unit X,Track XX,Sector XX$'
ERRMG:	DB	'RETYPE:$'
LMSG1:	DB	'2 Hex Digit limit. Retype:$'
LMSG2:	DB	'4 Hex Digit limit. Retype:$'
UNERMG:	DB	'Invalid Unit number',0DH,0AH,'$'
SECERM:	DB	'Invalid Sector number',0DH,0AH,'$'
CANMSG:	DB	'Cancelled',0dh,0ah,'$'
PRMST:	DB	'GHV==>$'
;
;	DONT MOVE THE NEXT 6 ITEMS
NSCTR:	DW	0	;XTRA BYTE FOR TBL CALC PAD	
NTRAK:	DB	0	
NUNIT:	DB	0	
RSCTR:	DW	0
RTRAK:	DB	0
RUNIT:	DB	0
SCTCT:	DW	0
BUFLG:	DB	0
HLDIT:	DW	GENMAP	;CP/M IS DEFAULT
HLDOT:	DW	GENMAP	;CP/M FOR OUT ALSO
CHGBAS:	DW	0	;BASE ADDR FOR BYTE CHANGES
XLTADR:	DW	EXTBL	;POINT AT SOMETHING
SPERT:	DB	26	;SECTORS PER TRACK
LSTCH:	DS	1
PRPTR:	DS	1
	DS	24
STACK:	DS	2
BUFFR:	DS	128
;
	END
