;BACKUP42/ASM - LDOS 6.2 - 12/29/83
;
;	read GAT to determine location of prot sector
;
	IF	@MOD2
GETPSEC	LD	A,(IY+3)	;get dct data
	AND	28H		;bit 5/3
	CP	20H		;8" floppy?
	JR	NZ,SETSYS1	;go if not
	LD	A,(IY+4)	;get dct data
	AND	50H		;bit 6/4
	CP	40H		;DD not alien?
	JR	NZ,SETSYS1	;go if not
;
	LD	DE,0<8+0	;boot sector
	CALL	RDSEC		;read directory
	RET	NZ		;go on disk error
	LD	L,2		;offset to dir cyl
	LD	D,(HL)		;get cyl
	LD	L,0		;reset buffer
	CALL	RDSEC		;read sector
	CP	6		;must be directory!
	RET	NZ		;disk error!
	LD	L,0CDH		;gat data byte
	BIT	7,(HL)		;system disk?
SETSYS1	LD	DE,2		;normal cylinder
	JR	NZ,$+3		;go if normal
	INC	D		;else cyl 1!
	LD	(PROTSEC),DE	;pass track/sector
	LD	A,D		;get cylinder
	LD	(BACKUP0),A	;pass flag for format!
	LD	A,6		;init for error return
	CP	A		;set NO error!
	LD	L,0		;reset buffer
	RET			;done!
BACKUP0	DB	0		;format 0 flag
CKPROT2	DW	0
RESW7	DW	0		;dct +7 saved data
	ENDIF
;
;	mod 2, format/read/write cylinder 0
;
	IF	@MOD2
READ0	LD	HL,RDSEC	;I/O address
	JR	RW0		;go common
WRITE0	LD	HL,WRSEC	;I/O address
RW0	LD	(RWCALL),HL	;save I/O call
;
	LD	A,(IY+3)	;get I/O flags
	LD	(RESW3),A	;save for restore
	AND	10101111B	;single den, single side
	LD	(IY+3),A	;update DCT
	LD	A,(IY+4)	;get flag
	LD	(RESW4),A	;save for restore
	LD	A,(IY+7)	;get current DCT data
	LD	(RESW7),A	;save for reset
	RES	5,(IY+4)	;set single sided!
	LD	DE,0		;init cyl/sector
	LD	HL,(BUFFER$)	;buffer start
READ0L	LD	(IY+7),31	;force long track, 1 head
	CALL	$		;read/write sector
RWCALL	EQU	$-2
	JR	NZ,RWERR	;go on error
	PUSH	BC		;save drive
	LD	BC,80H		;offset to next
	ADD	HL,BC		;HL => next buffer
	POP	BC		;restore drive
	INC	E		;bump sector
	LD	A,E		;get result
	SUB	27		;at end?
	JR	NZ,READ0L	;go for count
	LD	(NEWBFF),HL	;save new buffer
;
RWERR	LD	DE,0		;get config data
RESW3	EQU	$-2
RESW4	EQU	$-1
	LD	(IY+3),E	;update DCT
	LD	(IY+4),D
	LD	DE,(RESW7)	;get entry data
	LD	(IY+7),E	;restore entry condition
	RET			;done
;
;	update GAT table on dest drive
;
UPGAT0	LD	D,(IY+9)	;get dir cyl
	LD	E,0		;GAT table
	LD	HL,BUF3$	;I/O buffer
	CALL	RDSEC		;read the sector
	CP	6		;directory?
	RET	NZ		;go if not!
	LD	(HL),0FFH	;lockout
	LD	L,60H		;offset to lockout
	LD	(HL),0FFH	;lock out cyl 0
	LD	L,0		;reset buffer
	CALL	WRSYS		;write GAT
	RET	NZ		;go on error
	JP	RESTOR		;restore and return
;
;	format cylinder 0
;
FORMAT0	CALL	RESTOR		;restore drive
	RET	NZ		;go on error
;
	LD	A,(IY+3)	;get dct data
	AND	28H		;bit 5/3
	CP	20H		;8" floppy?
	JR	NZ,IGNFMT0	;ignore format if not
	LD	A,(IY+4)	;get dct data
	AND	50H		;bit 6/4
	CP	40H		;DD not alien?
	JR	NZ,IGNFMT0	;ignore if not
;
	LD	A,(IY+3)	;get DCT data
	PUSH	AF		;save on stack
	RES	6,(IY+3)	;force single density
	RES	4,(IY+3)	;set side 0
	LD	HL,$		;get I/O buffer
NEWBFF	EQU	$-2
	CALL	BUILD0		;create track image
	CALL	SELECT		;select drive
	LD	DE,0		;init location
	CALL	FMTCYL		;format it!
	POP	DE		;restore flags
	LD	(IY+3),D	;update
	RET			;return with status
;
IGNFMT0	XOR	A		;set NO error
	RET			;done, exit
;
BUILD0	PUSH	BC		;save drive
	PUSH	HL		;save buffer
;
	PUSH	HL		;save buffer
	LD	HL,SECTBL	;sector table
	EX	(SP),HL		;HL => buffer
	LD	DE,FMTTBL	;format table
	CALL	SETF0		;post index gap
	LD	(TBLPOS),DE	;save table position
	LD	C,27		;secs/cyl 0
BUILDLP	LD	DE,0		;fetch table
TBLPOS	EQU	$-2
	CALL	SETF0		;pre-ID sync
	LD	(HL),0FEH	;ID header
	INC	HL		;bump
	LD	(HL),0		;cylinder #
	INC	HL		;bump
	LD	(HL),0		;side 0
	INC	HL		;bump
	EX	(SP),HL		;get sector table
	LD	A,(HL)		;get sector
	INC	HL		;next sector
	EX	(SP),HL		;leave, get buffer
	LD	(HL),A		;sector
	INC	HL		;bump
	LD	(HL),0		;length = 128
	INC	HL		;bump
	LD	(HL),0F7H	;load CRC bytes
	INC	HL		;bump
;
	CALL	SETF0		;pre data gap
	CALL	SETF0		;pre data sync
	LD	(HL),0FBH	;data header
	INC	HL		;bump
	LD	B,128		;sector length
FILSEC	LD	(HL),0E5H	;data
	INC	HL		;bump
	DJNZ	FILSEC		;go for count
	LD	(HL),0F7H	;CRC
	INC	HL		;bump
	CALL	SETF0		;post data gap
	DEC	C		;less sector/cyl 0
	JR	NZ,BUILDLP	;go for count
	CALL	SETF0		;filler
	CALL	SETF0		;filler
;
	POP	HL		;remove sec table
	POP	HL		;get I/O buffer back
	POP	BC		;restore drive
	RET			;done!
;
;	move table data into buffer
;
SETF0	LD	A,(DE)		;get table entry
	INC	DE		;bump
	LD	B,A		;pass data count
	LD	A,(DE)		;get table entry
	INC	DE		;bump
SET1	LD	(HL),A		;load data to buffer
	INC	HL		;bump buffer
	DJNZ	SET1		;go for data count
	RET			;filled!
;
;	sector order table for cylinder 0
;
SECTBL	DB	0,9,18,1,10,19,2,11,20,3,12,21,4,13
	DB	22,5,14,23,6,15,24,7,16,25,8,17,26
;
;	gap table for single density
;
FMTTBL	DB	32,0FFH		;post index gap
	DB	6,00H		;pre ID sync
	DB	11,0FFH		;pre data gap
	DB	6,00H		;pre data sync
	DB	11,0FFH		;post data gap
	DB	0,0FFH		;filler
	DB	0,0FFH		;filler
	DB	0,0FFH		;filler
	ENDIF
;
