;************************************************************************
;*	Super Famicom Disk Operation Sysytem  main routine		*
;*		    Programmed by Y.Nishida				*
;*						[ Aug.21, 1991 ]	*
;************************************************************************

		native
		extend

		include		PPUregs.h
		include		CPUregs.h
		include		sfxdos.h

DOS_main	sect		rel
SFXDOS		group		DOS_main

		dpage		DOS_variable
		dbank		00H

;=============== Cross definition =======================================

sfxdos		equ		0
		global		sfxdos
		global		NMI_Entry
		global		IRQ_Entry

;=============== Cross Reference ========================================

		extern		FDC_Driver
		extern		FDC_Interrupt
		extern		SCC_Interrupt
		extern		CON_Driver_NMI
;------------------------------------------------------------------------
		extern		Init_CON_Driver
		extern		Input_Console
		extern		Output_Console
		extern		Input_String
		extern		Print_String
;------------------------------------------------------------------------
		extern		Init_SCC_Driver		; Initial SCC(Z8530) driver
		extern		Enable_SCC_Int		; Enable SCC interrupt
		extern		Disable_SCC_Int		; Disable SCC interrupt
		extern		Flush_Keyboard		; Flush keyboard buffer
		extern		Input_Keyboard		; Input keyboard
		extern		Output_Keyboard		; Output keyboard
		extern		Sense_Keyboard		; Input sense keyboard
		extern		Reset_RS232C		; Reset RS232C
		extern		Input_RS232C		; Input data from RS232C
		extern		Output_RS232C		; Output data to RS232C
		extern		Sense_RS232C		; Ssense RS232C
;------------------------------------------------------------------------
		extern		Init_PPI_Driver		; Initial PPI(uPD71055) driver
		extern		Sense_Printer		; Sense printer output
		extern		Output_Printer		; Output printer
;------------------------------------------------------------------------
		extern		Init_FDC_Driver		; Initial FDC(uPD72069) driver
		extern		Enable_FDC_Int		; Enable FDC interrupt
		extern		Disable_FDC_Int		; Disable FDC interrupt
		extern		Disk_Format		; Disk format
		extern		Disk_Free		; Disk free
		extern		Files_First		; Search first file
		extern		Files_Next		; Search next file
		extern		Select_Drive		; Select dirve
		extern		Load_File		; Load file
		extern		Save_File		; Save file
		extern		Purge_File		; Purge file
		extern		Rename_File		; Rename file

;************************************************************************
;*	SFXDOS Reset ( SFX initialize )					*
;*									*
;************************************************************************

		mem8
		idx8
DOS_Entry
		sei					; IRQ  disable
		rep		#00001001B		; Set binary mode
		xce					; Set native mode

;===============  Initial DMA & PPU  ====================================
DOS_Entry_10
		sep		#00110000B		; Memory,Index 8 bit mode
		stz		Int_control		; NMI,IRQ disable
		stz		MDMA_start		; M_DMA all enable
		stz		HDMA_switch		; H_DMA all enable
		lda		#10000000B
		sta		Screen_contrast		; Screen blanking
		stz		PPU_control		; Set PPU mode
		stz		4016H			; Controller auto scan

;===============  Inital D reg & SP  ====================================
DOS_Entry_20
		mem16
		rep		#00100000B		; Memory 16 bit mode
;------------------------------------------------------------------------
		lda		#DOS_variable
		tcd					; Set Direct register
		lda		#01FFH
		tcs					; Set stack pointer
;------------------------------------------------------------------------
		lda		#0000H
		pha					; Push user Direct register

;===============  Initial work RAM  =====================================
DOS_Entry_30
		ldx		#00H
		lda		#1E00H
		sta		DRAM_address+0		; Set DRAM address
		stx		DRAM_address+2		; Set DRAM bank
;------------------------------------------------------------------------
		lda		#8008H
		sta		DMA_channel0+0		; Set DMA control & B bus address
		lda		#Clear_data
		sta		DMA_channel0+2		; Set A bus address
		stx		DMA_channel0+4		; Set A bus bank
		lda		#1200H
		sta		DMA_channel0+5		; Set number of bytes
		ldx		#00000001B
		stx		MDMA_start		; Clear all work RAM ( 7E:1E00H - 7E:2FFFH )
;------------------------------------------------------------------------
		lda		IRQ_vector
		sta		IRQ_address		; Set user IRQ routine address
		lda		NMI_vector
		sta		NMI_address		; Set user NMI routine address

;************************************************************************
;*	SFX-DOS initialize						*
;*									*
;************************************************************************

		mem8
		idx8
DOS_initialize
		sep		#00110000B		; Memory,Index 8 bit mode

;=============== Initialize Driver routine ==============================

		jsr		Init_SCC_Driver
		jsr		Init_PPI_Driver
		lda		#00H
		jsr		Init_FDC_Driver
;------------------------------------------------------------------------
		lda		#11111111B
		sta		<DOS_switch
;------------------------------------------------------------------------
		lda		#low Sfxdos_IRQ
		sta		<IRQ_address+0		; Set IRQ vector
		lda		#high Sfxdos_IRQ
		sta		<IRQ_address+1		; Set IRQ vector

;=============== Initialize Driver routine ==============================

		pld					; Pull usr Direct register
		jmp		(Reset_vector)

;************************************************************************
;*	SFX-DOS Reset							*
;*									*
;************************************************************************

		mem8
		idx8
DOS_Reset
		sei
		ldx		#8
		jsr		Enable_SCC_Int		; Enable SCC interrupt
		jsr		Enable_FDC_Int		; Enable SCC interrupt
		lda		#10000000B
		tsb		<DOS_switch		; Enable DOS switch
;------------------------------------------------------------------------
		mem16
		rep		#00100000B		; Memory 16 bit mode
		lda		#Sfxdos_IRQ
		sta		<IRQ_address		; Set IRQ vector
		rts

;************************************************************************
;*	FDC driver off							*
;*									*
;************************************************************************

		mem8
		idx8
DOS_Stop
		sei
		lda		#9
		sta		<Disk_control
		jsr		Disable_SCC_Int		; Disable SCC interrupt
		jsr		Disable_FDC_Int		; Disable FDC interrupt
		stz		<DOS_switch		; Disable DOS switch
;------------------------------------------------------------------------
		mem16
		rep		#00100000B		; Memory 16 bit mode
		lda		IRQ_vector
		sta		<IRQ_address		; Set IRQ vector
		lda		NMI_vector
		sta		<NMI_address		; Set NMI vector
		rts

;************************************************************************
;*	Text VRAM emulation reset					*
;*									*
;************************************************************************

		mem8
		idx8
Text_Reset
		ldx		#00H
		jsr		Init_CON_Driver		; Initialize VRAM emulation
;------------------------------------------------------------------------
		mem16
		rep		#00100000B		; Memory 16 bit mode
		lda		#Sfxdos_NMI
		sta		<NMI_address
		rts

;************************************************************************
;*	Set RS232C							*
;*									*
;************************************************************************

		idx8
Set_RS232C
		sei
		and		#00011110B
		sta		<RS232C_baurate
		xba
		and		#01101111B
		sta		<RS232C_status
		jmp		Reset_RS232C

;************************************************************************
;*	COP routine entry						*
;*									*
;************************************************************************

		mem16
		idx16
COP_Entry
		plp
		php
		rep		#00110000B		; Memory,Index 16 bit mode
		phx					; 4
		phy					; 6
		phd					; 8
		phb					; 10
		pha					; 11
		phk
;------------------------------------------------------------------------
		plb					; Set Data Bank Register
		lda		#DOS_variable
		tcd					; Set Direct Register
;------------------------------------------------------------------------
		lda		11,s
		dec		a
		sta		<work0
		lda		13,s
		sta		<work1
		lda		[work0]			; Get function number
		asl		a
		tax
		pla
		sep		#00110000B		; Memory,Index 8 bit mode
		jsr		(Function_call$,x)
;------------------------------------------------------------------------
		rep		#00110000B		; Memory,Index 16 bit mode
		plb
		pld
		ply
		plx
		rti

;=============== Function call jump table ===============================

Function_call$	word		DOS_Reset		; 00:DOSRST
		word		DOS_Stop		; 01:DOSSTP
		word		Text_Reset		; 02:TXTRST
		word		Sense_Keyboard		; 03:CONSNS
		word		Input_Console		; 04:CONIN
		word		Output_Console		; 05:CONOUT
		word		Flush_Keyboard		; 06:CONRST
		word		Sense_Printer		; 07:PRNSNS
		word		Output_Printer		; 08:PRNOUT
		word		Sense_RS232C		; 09:AUXSNS
		word		Input_RS232C		; 10:AUXIN
		word		Output_RS232C		; 11:AUXOUT
		word		Set_RS232C		; 12:AUXRST
		word		Input_String		; 13:INPUT
		word		Print_String		; 14:PRINT
		word		Init_FDC_Driver		; 15:DSKRST
		word		Disk_Format		; 16:FORMAT
		word		Disk_Free		; 17:DSKFRE
		word		Files_First		; 18:DIRFST
		word		Files_Next		; 19:DIRNXT
		word		Select_Drive		; 20:SELDSK
		word		Load_File		; 21:LOAD
		word		Save_File		; 22:SAVE
		word		Purge_File		; 23:PURGE
		word		Rename_File		; 24:RENAME

;************************************************************************
;*	Break routine entry						*
;*									*
;************************************************************************

BRK_Entry	jmp		(Break_vector)

;************************************************************************
;*	Abort routine entry						*
;*									*
;************************************************************************

ABT_Entry	jmp		(Abort_vector)

;************************************************************************
;*	NMI routine entry						*
;*									*
;************************************************************************

NMI_Entry	equ		$+7E0000H
		jmp		(NMI_address)

;=============== SFX-DOS NMI routine ====================================
Sfxdos_NMI
		mem16
		idx16
		rep		#00110000B		; Memory,Index 16 bit mode
;------------------------------------------------------------------------
		pha
		phx
		phy
		phd
		phb
;------------------------------------------------------------------------
		lda		#0
		pha
		plb
		plb
		lda		#DOS_variable
		tcd
;------------------------------------------------------------------------
		mem8
		idx8
		sep		#00110000B		; Memory,Index 8 bit mode
		lda		NMI_status		; Reset hardware NMI flag
		jsr		CON_Driver_NMI
;------------------------------------------------------------------------
		rep		#00110000B		; Memory,Index 16 bit mode
		plb
		pld
		ply
		plx
		pla
		rti

;************************************************************************
;*	IRQ routine entry						*
;*									*
;************************************************************************

IRQ_Entry	equ		$+7E0000H
		jmp		(IRQ_address)

;=============== SFX-DOS IRQ routine ====================================
Sfxdos_IRQ
		mem16
		idx16
		rep		#00110000B		; Memory,Index 16 bit mode
;------------------------------------------------------------------------
		pha
		phx
		phy
		phd
		phb
;------------------------------------------------------------------------
		lda		#0
		plb
		plb
		lda		#DOS_variable
		tcd
;------------------------------------------------------------------------
		mem8
		idx8
		sep		#00110000B		; Memory,Index 8 bit mode
		stz		<IRQ_status		; Reset IRQ status
		jsr		SCC_Interrupt
		lda		<IRQ_status
		bmi		Exit$
		jsr		FDC_Interrupt
;------------------------------------------------------------------------
Exit$		rep		#00110000B		; Memory,Index 16 bit mode
		plb
		pld
		ply
		plx
		pla
		rti

;************************************************************************
;*	Interrupt vector						*
;*									*
;************************************************************************

Int_Exit	rti
Clear_data	byte		00H

;=============== User interrupt vector ==================================

Break_vector	equ		0DFF6H			; Break
Abort_vector	equ		0DFF8H			; Abort
NMI_vector	equ		0DFFAH			; NMI
Reset_vector	equ		0DFFCH			; Reset
IRQ_vector	equ		0DFFEH			; IRQ

;=============== Native mode vector =====================================

		org		0FFE0H

		word		0FFFFH			; ( dummy )
		word		0FFFFH			; ( dummy )
		word		COP_Entry		; COP
		word		BRK_Entry		; BRK
		word		ABT_Entry		; Abort
		word		110H			; NMI
		word		0FFFFH			; ( Reserved )
		word		114H			; IRQ

;=============== Emulation mode vector ==================================

		word		0FFFFH			; ( dummy )
		word		0FFFFH			; ( dummy )
		word		Int_Exit		; COP
		word		0FFFFH			; ( reserved )
		word		Int_Exit		; Abort
		word		Int_Exit		; NMI
		word		DOS_Entry		; Reset
		word		Int_Exit		; IRQ/BRK

		end
