;------------------------------------------------------------------
;
;EN29F002T	Am29F040
;3C000 16KB	70000 64KB
;3A000  8KB	60000 64KB
;38000  8KB	50000 64KB
;30000 32KB	40000 64KB
;20000 64KB	30000 64KB
;10000 64KB	20000 64KB
;00000 64KB	10000 64KB
;		00000 64KB

;------------------------------------------------------------------
DISKBUF	equ	0E000H		;読み出しバッファ
BUFSIZ	equ	4096		;Disk buffer size (1クラスタ分)

;------------------------------------------------------------------
; Command
;------------------------------------------------------------------
RDRESET	equ	0F0H		;Read/Reset
AUTOSEL	equ	90H		;Autoselect
BPRGM	equ	0A0H		;Byte Program
ERASE	equ	80H		;Erase
CERASE	equ	10H		;Chip Erase
SERASE	equ	30H		;Sector Erase

;------------------------------------------------------------------
; I/O
;------------------------------------------------------------------
ROMBASE	equ	0E00H		;BASIC ROM Base address
ROMHAD	equ	ROMBASE+0	;Address High
ROMMAD	equ	ROMBASE+1	;Address Mid
ROMLAD	equ	ROMBASE+2	;Address Low
ROMDAT	equ	ROMBASE+3	;Data

;------------------------------------------------------------------
; BIOS ROM
;------------------------------------------------------------------
FDCRED	EQU	739DH		;読み出し

;------------------------------------------------------------------
; RAM & WORK
;------------------------------------------------------------------
FDCNO	equ	0FADDH		;デバイスタイプ 5:MEM 6:EMM 7:5.25"FD 9:HD
UNITNO	equ	0FADEH		;ドライブ番号

;------------------------------------------------------------------
;
;------------------------------------------------------------------
	org	0D000H
Entry:
	CP	3		;文字列?
	JR	NZ,TYPMISS
	LD	A,B
	CP	5		;5文字?
	JR	NZ,TYPMISS
	EX	DE,HL		;HL=文字列アドレス
	
	LD	E,(HL)		;+0 
	INC	HL
	LD	D,(HL)		;+1 DE=読み出し開始レコード番号
	INC	HL
	PUSH	HL
	
	LD	A,6		;EMM
	LD	(FDCNO),A
	LD	A,0		;ドライブ
	LD	(UNITNO),A
	
	LD	A,BUFSIZ/256	;ディスク読み出し
	LD	HL,DISKBUF	;読み出しバッファ
	LD	BC,FDCRED
	RST	18H		;BIOS CALL
	
	POP	HL
	LD	E,(HL)		;+2 E=アドレス下位
	INC	HL
	LD	D,(HL)		;+3 D=アドレス中位
	INC	HL
	LD	BC,ROMBASE+100H
	OUTI			;+4 アドレス上位
	
	XOR	A
	LD	(ERRBUF),A
	
	EXX
	LD	HL,DISKBUF	;読み出しバッファ
	LD	BC,BUFSIZ
NextAddr:
	LD	A,(HL)
	EXX
	CALL	Program
	JR	C,ERRPRGM
	INC	DE		;Flash address++
	EXX
	INC	HL		;Buffer address++
	DEC	BC		;Byte counter++
	LD	A,B
	OR	C
	JP	NZ,NextAddr
	EXX
	
	RET

ERRPRGM:
	LD	A,BPRGM
	LD	(ERRBUF),A
	RET

TYPMISS:
	LD	A,13		;Type mismatch
	JP	(IX)

ERRBUF:
	DB	0

;------------------------------------------------------------------
; Byte Program
;
; 入力	A  = データ
;	H  = アドレス High
;	DE = アドレス Mid/Low
; 出力	キャリーフラグ(エラー発生時にセット)
; 破壊	AF,BC,L
;------------------------------------------------------------------
Program:
	LD	L,A
	INC	A		;A=FFH ?
	RET	Z		;書き込み必要無し、即戻り
	
	LD	C,LOW ROMBASE+1	;1st Cycle
	LD	A,55H
	OUT	(C),A		;55H
	INC	C
	OUT	(C),A		;55H
	INC	C
	CPL			;A = AAH
	OUT	(C),A		;AAH
	
	LD	C,LOW ROMBASE+1	;2nd Cycle
	OUT	(C),A		;2AH
	INC	C
	OUT	(C),A		;AAH
	INC	C
	CPL			;A = 55H
	OUT	(C),A		;55H
	
	LD	C,LOW ROMBASE+1	;3rd Cycle
	OUT	(C),A		;55H
	INC	C
	OUT	(C),A		;55H
	INC	C
	LD	A,BPRGM
	OUT	(C),A		;Command
	;
	LD	A,L
	CALL	Polling
	RET	NC
	
	LD	A,BPRGM
	LD	(ERRBUF),A
	RET

;------------------------------------------------------------------
; ポーリング待ち
;
; 入力	A  = データ
;	B  = BASIC ROM ベースアドレス High
;	H  = アドレス High
;	DE = アドレス Mid/Low
; 出力	キャリーフラグ(エラー発生時にセット)
; 破壊	AF,C,L
;------------------------------------------------------------------
Polling:
	LD	C,LOW ROMBASE+1
	OUT	(C),D		;Program address Mid
	INC	C
	OUT	(C),E		;Program address Low
	INC	C
	OUT	(C),A		;Program Data
	AND	10000000B	;Data bit
	LD	L,A
LoopPolling:
	IN	A,(C)
	XOR	L		;最上位ビットの比較
	RET	P		;一致したら動作終了
	AND	00100000B	;エラーの確認
	JP	Z,LoopPolling	;まだ動作中
	;
	IN	A,(C)
	XOR	L		;最上位ビットの比較
	RET	P		;一致したら動作終了
	;
	SCF
	RET

;------------------------------------------------------------------
; Chip Erase
;
; 出力	キャリーフラグ(エラー発生時にセット)
; 破壊	AF,BC,DE,HL
;------------------------------------------------------------------
ChipErase:
	LD	A,ERASE
	CALL	StartCycle
	
	LD	A,CERASE
	CALL	StartCycle
	
	CALL	Toggle
	RET	NC
	
	LD	A,CERASE
	LD	(ERRBUF),A
	RET

;------------------------------------------------------------------
; トグルビット待ち
;
; 入力;	B  = BASIC ROM ベースアドレス High
;	H  = アドレス High
;	DE = アドレス Mid/Low
; 出力	キャリーフラグ(エラー発生時にセット)
; 破壊	AF,C,L
;------------------------------------------------------------------
Toggle:
	IN	A,(C)		;Data
LoopToggle:
	IN	L,(C)		;Data
	XOR	L		;前回と比較
	AND	01000000B	;トグル動作中か?
	RET	Z		;前回と同値ならトグル動作終了
	LD	A,L
	AND	00100000B	;Check Error bit
	LD	A,L
	JP	Z,LoopToggle	;まだトグル動作中
	;
	IN	L,(C)		;再読み込み
	XOR	L		;前回と比較
	AND	01000000B	;トグル動作中か?
	RET	Z		;前回と同値ならトグル動作終了
	;
	SCF
	RET

;------------------------------------------------------------------
; コマンドシーケンス開始処理
;
; 入力	A  = コマンド
; 出力	BC = ROMBASE+3
; 破壊	F,C,DE,L
;------------------------------------------------------------------
StartCycle:
	LD	L,A
	;
	LD	B,HIGH ROMBASE
	LD	DE,5555H
	LD	A,0AAH
	CALL	WrCycle		;1st Cycle
	LD	DE,2AAAH
	CPL
	CALL	WrCycle		;2nd Cycle
	;
	LD	E,A
	LD	D,E
	LD	A,L
				;3rd Cycle
	;
;------------------------------------------------------------------
; Write Cycle 実行
;
; 入力	A  = データ
;	B  = BASIC ROM ベースアドレス High
;	DE = アドレス Mid/Low
; 破壊	C
;------------------------------------------------------------------
WrCycle:
	LD	C,LOW ROMBASE+1
	OUT	(C),D
	INC	C
	OUT	(C),E
	INC	C
	OUT	(C),A
	RET

	end