;
; DOS ALLOCATION ROUTINES
;
;	FREE A SECTOR FOR LATER USE
;
FREE	JSR	RBITMP		;MAKE SURE WE HAVE THE RIGHT MAP
	STA	CHGMAP
FMTFRE	INC	MAPBUF+3	;BUMP LOW BYTE OF FREE SECTOR COUNT
	BNE	FREE0		;IF NO CARRY
	INC	MAPBUF+4
FREE0	JSR	FNDBIT
	PHA
	LDA	TMP2
	BEQ	SBMP1
	STY	TMP2
	CMP	CURMP		;BEFORE FIRST HOLE?
	BCS	SBMP2		;NO, LEAVE UNCHANGED
	STA	CURMP		;YES, NEW FIRST HOLE
SBMP2	JSR	RDNXTM
	LDY	TMP2
	LSR	MAP2MOD		;MARK MAP PAGE2 DIRTY
	PLA
	ORA	MAPBUF+256,Y
	STA	MAPBUF+256,Y
	RTS
;
SBMP1	PLA
	ORA	MAPBUF,Y
	STA	MAPBUF,Y
	RTS
;
;	FIND BIT ASSOCIATED WITH A SECTOR ON THE DISK
;
FNDBIT	LDA	CURSEC,X
	AND	#7	;EXTRACT THE BIT NUMBER
	TAY
	SEC
	LDA	#0
FREE1	ROR	A	;POSITION CARRY TO THE BIT TO FLIP
	DEY
	BPL	FREE1
	PHA		;SAVE THE BIT MASK
;
	LDA	CURSEC,X
	CLC
	ADC	#10*8	;ALLOW FOR 10 BYTE HEADER
	TAY		;SAVE LOW BYTE
	LDA	CURSEC+1,X
	ADC	#0	;PROPOGATE CARRY
	LSR	A
	STA	TMP2
	TYA
	ROR	A
	LSR	TMP2
	ROR	A
	LSR	TMP2
	ROR	A
	TAY
;
	PLA		;RESTORE THE BIT MASK
	RTS
;
;	ALLOCATE AN UNUSED SECTOR TO A FILE
;
ALLOC	JSR	RBITMP
	STA	CHGMAP
	LDY	#10
	LDA	#0
	STA	TMP2
ALL1	CMP	MAPBUF,Y	;ANY BITS LEFT?
	BNE	SECFN1		;IF SO
	INY
	BNE	ALL1
;
	SEC
	LDA	MAPBUF
	SBC	CURMP
	SEC
	SBC	#3
	STA	TMP1
ALLCK	BMI	ALGONE
	LDA	CURMP
	STA	TMP2
	JSR	RDNXTM
	LDA	#0
	TAY
ALL2	CMP	MAPBUF+256,Y
	BNE	SECFN2		;IF FREE SECTOR IN SECOND PART OF MAP
	INY
	BNE	ALL2
	INC	CURMP		;TO NEXT SECTOR OF BIT MAP
	DEC	TMP1
	BPL	ALLCK
;
ALGONE	DEC	CURMP
DFERR	LDA	#162		;DISK FULL ERROR CODE
	JMP	AEXIT		;IF THIS IS IT, ERROR-EXIT
;
SECFN1	SEC
	LDX	#$AF		;I.E., -8*10 - 1
ALL3	ROR	A
	INX
	CMP	MAPBUF,Y
	BCC	ALL4
	CLC
	BNE	ALL3
ALL4	EOR	MAPBUF,Y
	STA	MAPBUF,Y
	BPL	ALL7
;
SECFN2	SEC
	LDX	#$AF		;I.E., -8*10 - 1
ALL5	ROR	A
	INX
	CMP	MAPBUF+256,Y
	BCC	ALL6
	CLC
	BNE	ALL5
ALL6	LSR	MAP2MOD
	EOR	MAPBUF+256,Y
	STA	MAPBUF+256,Y
;
ALL7	TYA
	ASL	A
	ROL	TMP2
	ASL	A
	ROL	TMP2
	ASL	A
	ROL	TMP2
	STA	TMP1
	TXA
	ADC	TMP1
	LDX	CURFCB
	STA	LNKSEC,X
	LDA	TMP2
	ADC	#$FF
	STA	LNKSEC+1,X
DECCNT	LDA	MAPBUF+3
	BNE	NOBOR
	DEC	MAPBUF+4
NOBOR	DEC	MAPBUF+3
	CLC
	RTS
;
;  SIMULATE OLD STYLE BIT FINDER
;
FNDLBIT	JSR	FNDBIT
	PHA			;SAVE MASK
	LDA	TMP2		;FIRST PAGE?
	BEQ	FNDPG0
	STY	TMP2		;SAVE OFFSET IN PAGE
	CMP	DATBYT
	BCS	DFEJMP
	JSR	RDNXTM		;READ IN PROPER PAGE
	LDY	TMP2		;THEN RESTORE A AND Y REGS
	PLA
	SEC			;SET CY (PAGE 1 BUFFER USED)
	RTS
;
FNDPG0	PLA			;RESTORE SAVED MASK
	CLC			;AND CLR CY (SAY PAGE 0)
	RTS
;
DFEJMP	JMP	DFERR
;
DECCSEC	LDA	CURSEC,X
	BNE	ALCPG0
	DEC	CURSEC+1,X
ALCPG0	DEC	CURSEC,X
	RTS
;
INCCSEC	INC	CURSEC,X
	BNE	DELDIN
	INC	CURSEC+1,X
DELDIN	RTS
;
;  DOS MISC. SUBROUTINES
;
;	SET UP STATE VARIABLES ON ENTRY
;
SETUP	LDY	ICDNOZ	;GET UNIT NO.
SETUPW	STX	CURFCB
	TSX
	INX
	INX
	STX	STKPSV	;SAVE POINTER TO RETURN ADDR ON STACK
SETUPD	STY	DUNIT	;COPY UNIT NO. TO DCB
	LDA	#1
	CPY	RAMDKU
	BEQ	UFIXED	;RAMDISK SECTOR SIZE IS ALWAYS 128 BYTES
	LDA	SECSIZ-1,Y
	BEQ	INVUNIT	;IF NOT CURRENTLY VALID UNIT, TEST FOR DENSITY
UFIXED	STA	SECDAT	;OTHERWISE, STORE CORRECT DENSITY DATA
	LSR	A
	ROR	A
	ROR	A
	ORA	#$7D	;UPDATE THE LINK POSITION IN THE DISK SECTOR
	STA	DLINK
;
	LDX	CURFCB
	LDY	BUFNO,X		;GET THE BUFFER NUMBER
	BNE	RSETUP
	LDY	FILES		;IF ONE IS NOT ALLOCATED
	INY
SFORB	DEY
	BEQ	NOSECB		;ALLOCATE ONE, OR ABORT THE OPERATION NOW
	LDA	BUFFLG-1,Y
	BNE	SFORB
	LDA	#$80
	STA	BUFFLG-1,Y
	TYA
	STA	BUFNO,X
RSETUP	LDA	DOSEND	;==SBTABL
	STA	FMSBPT
	LDA	SBTABU-1,Y
	STA	FMSBPT+1
	RTS
;
INVUNIT	JSR	JSTRD
	BNE	UFIXED
;
NOUNIT	LDA	#160	;RETURN ST=160, DRIVE NOT PRESENT
	DB	$AE	;SKIP TO JMP INSTRUCTION
NOSECB	LDA	#161	;RETURN ST=161, NO MORE FILE BUFFERS
	JMP	AEXIT
;
;  REMOVE DOS POINTER FROM BOOT SECTORS
;
TDDOS	JSR	TSTDOS	;MUST WE UPDATE BOOT?
	BNE	NODOSX	;NO, RETURN
;
DELDOS	LDY	#0	;YES, REMOVE DOS POINTER FROM BOOT
	BEQ	UPDBT
;
;  ADD DOS POINTER TO BOOT SECTORS
;
SETDOS	STY	DOSLOC
	STA	DOSLOC+1
	LDY	SECDAT
UPDBT	LDA	DUNIT
	CMP	RAMDKU
	BEQ	TDEXIT
	STY	SECDAT
	LDA	STATE
	PHA
	LDA	DEFAULT
	PHA
	LDA	#$00
	STA	STATE		;NOTHING IS IN MEMORY YET
	LDY	#$FF
	LDA	FCBOTC,X
	BMI	NOAND		;LONG LENGTH FIELD?
	LDY	#$03		;IF NOT, USE ONLY 10 BITS
NOAND	STY	ANDCD+1
	LDA	#HIGH[BOOTFL]
	LDY	#LOW[BOOTFL]
	JSR	BUFSET
	LDY	#0
	STY	DAUX2
;
WSECL	INY
	STY	DAUX1
	LDX	#1
	STX	DEFAULT
	SEC
	JSR	DKIO2
	JSR	STEPBP
	CPY	BOOTL
	BNE	WSECL
;
	PLA
	STA	DEFAULT
	PLA
	STA	STATE
	LDY	ICDNOZ
	STY	DUNIT
	LDA	SECSIZ-1,Y
	STA	SECDAT
NODOSX	RTS
;
;  TEST FOR FILE NAME = 'DOS.SYS'
;
TSTDOS	LDY	#256-11
	LDX	DIRDSP
TDLOOP	LDA	DIRBUF+5,X
	EOR	DOSSYS-256+11,Y
	BNE	TDEXIT
	INX
	INY
	BNE	TDLOOP
TDEXIT	LDX	CURFCB
	TAY
	RTS
;
DOSSYS	DB	'DOS     SYS'
;
;  FIND AT LEAST ONE FILE MATCHING GIVEN NAME
;
LFFILE	JSR	GETFNM	;EXTRACT FILE NAME FROM BUFFER
	STY	TMP2	;SAVE IT FOR -RENAME-
	JSR	SFDIR	;FIND FIRST MATCHING FILE IN DIR
	LDA	#170	;IF NONE, RETURN ERROR 170
	BCS	AEXIT	;ELSE, RETURN
	RTS
;
;  RETURN ERROR IF FILE IS LOCKED
;
TSTLOK	LDA	#$20	;CHECK BIT 5
	JSR	GETFLAG
	BEQ	TDEXIT
	LDA	#167	;FILE LOCKED ERROR = 167
	DB	$AE	;SKIP 2 BYTES
;
;  RETURN WITH NO ERROR
;
DONE	LDA	#1	;NORMAL COMPLETION
;
;  RETURN ERROR CODE IN ACC TO CIO (IN Y)
;
AEXIT	LDX	STKPSV	;RESTORE STACK POINTER
	TXS
	LDX	CURFCB	;RESTORE IOCB OFFSET TO X-REG
	STA	ICSTA,X	;RETURN STATUS IN IOCB
	TAY		;RETURN STATUS IN Y-REG
	LDA	DATBYT
	CPY	#0
	RTS
;
;  RETURN HARDWARE ERRORS TO CIO
;
HWERR
;;;	lda	#0		;fix VTOC updating bug
;;;	sta	CURMAP		;do we really want to do this?????
;;;	sta	CHGMAP		;[Bob Puff]

	LDA	DSTATS
	BNE	AEXIT
;
;  RELEASE FCB AND RETURN NO-ERROR STATUS
;
FREDON	LDX	CURFCB
;
	LDY	BUFNO,X	;FINISHED WITH THE SECTOR BUFFER, RETURN IT
	BEQ	DONE	;IF NONE ALLOCATED, SO WHAT!
	LDA	#0
	STA	BUFNO,X
	STA	BUFFLG-1,Y
	BEQ	DONE
;
;  TEST OR CLEAR A BIT IN THE FLAG BYTE
;
GETFLAG	LDY	DIRDSP
	AND	DIRBUF,Y
	RTS
;
;  SAVE FLAG BYTE AND WRITE BACK TO DIRECTORY
;
SAVFLAG	LDY	DIRDSP
	STA	DIRBUF,Y
	JMP	WDIRBK
