		fname	"GETROM.BIN"

; GETROM.ASM : Z80 assembler source for GETROM.BIN
; originally written for RFASSEM.COM (RF Assembler)
; tniASM 0.4x version

; version 1.1 fixes by Jemo1982
; - when saving to cassette, only the MAIN ROM contents
;   were actually saved

		DB	0FEH
		DW	START,END,START

		ORG	0C000H

MSX1BIOS:	EQU	1
MSX2BIOS:	EQU	2
MSXPBIOS:	EQU	3
MSXRBIOS:	EQU	4
MSX2EXT:	EQU	6
MSXPEXT:	EQU	7
MSXREXT:	EQU	8
MSXBDOS:	EQU	9
ROM8KB:		EQU	10
ROM16KB:	EQU	11
ROM32KB:	EQU	12
ROM8KB2:	EQU	13
ROM16KB2:	EQU	14
MEGA128:	EQU	15
MEGA256:	EQU	16
MEGA512:	EQU	17
BDOS:		EQU	0F37DH

		; first determine page 1
START:		CALL	138H
		RRCA
		RRCA
		RRCA
		RRCA
		AND	3
		LD	C,A
		LD	B,0
		LD	HL,0FCC1H
		ADD	HL,BC
		BIT	7,(HL)
		JR	Z,NOSUB
		INC	HL
		INC	HL
		INC	HL
		INC	HL
		LD	A,(HL)
		RRCA
		RRCA
		AND	0CH
		OR	80H
		OR	C
NOSUB:		LD	(PAGE2RAM),A
		LD	A,40		; screen 0, width 40
		LD	(0F3AEH),A
		XOR	A
		LD	(0F3DEH),A
		LD	A,15
		LD	(0F3E9H),A
		LD	A,4
		LD	(0F3EBH),A
		CALL	6CH
		LD	HL,BEGINMES
		CALL	PRINTCR
		LD	HL,(0F323H)	; error rountines
		LD	(DKHKBKUP),HL
		LD	HL,DSKHKPTR
		LD	(0F323H),HL
		LD	HL,(0F1E6H)
		LD	(ABORTHBK),HL
		LD	HL,ABORTH
		LD	(0F1E6H),HL

		; here it starts...
SAGAIN:		CALL	GETROM
CONTINUE:	CALL	DISPLAY
		CALL	INPUT
		CP	'Q'
		JR	Z,ENDPROG
		CP	'S'
		JR	Z,SAGAIN
		CALL	SAVE
		JR	CONTINUE

ENDPROG:	LD	HL,(DKHKBKUP)
		LD	(0F323H),HL
		LD	HL,(ABORTHBK)
		LD	(0F1E6H),HL
		LD	A,(PAGE2RAM)
		LD	H,80H
		CALL	24H

		; clear memory so no fuzzy basic program is there
		LD	HL,8000H
		LD	B,5
CLEAR:		LD	(HL),0
		INC	HL
		DJNZ	CLEAR
		LD	A,(0FCC1H)
		LD	H,40H
		JP	24H

; end of START proc
; ***************************************************************************
; GETROM proc

GETROM:		LD	A,(2DH)

		; main BIOS
		LD	B,A
		INC	A
		LD	HL,ROMINFO
		LD	(HL),A		; type of ROM
		INC	HL
		LD	A,(0FCC1H)
		LD	(HL),A		; slot : 0-0, by definition
		INC	HL
		LD	A,1
		LD	(NUMROM),A	; one ROM

		LD	A,B		; extended BIOS
		OR	A
		JR	Z,NOEXT
		ADD	A,MSX2EXT-1
		LD	(HL),A		; type of ROM
		INC	HL

		LD	A,(0FAF8H)	; retieve slot EXTENDED BIOS
		LD	(HL),A		; slot of ROM
		INC	HL
		LD	A,2
		LD	(NUMROM),A	; second ROM (only BIOS is before)

		; BDOS
NOEXT:		LD	A,(0FFA7H)
		CP	0C9H
		JR	Z,NOBDOS
		LD	(HL),MSXBDOS	; type of ROM
		INC	HL
		LD	A,(0F348H)
		LD	(HL),A		; slot of ROM
		LD	HL,NUMROM
		INC	(HL)

		; search slots
NOBDOS:		XOR	A
NEXTPRIM:	PUSH	AF
		LD	C,A
		LD	B,0
		LD	HL,0FCC1H
		ADD	HL,BC
		BIT	7,(HL)
		JR	NZ,EXPANDED
		CALL	CHCKSLOT
		JR	NEXTSLOT

EXPANDED:	OR	80H
NEXTSEC:	CALL	CHCKSLOT
		ADD	A,4
		BIT	4,A
		JR	Z,NEXTSEC
NEXTSLOT:	POP	AF
		INC	A
		BIT	2,A
		JR	Z,NEXTPRIM
		RET

; end of GETROM proc
; ***************************************************************************
; proc INFOPTR

INFOPTR:	LD	HL,ROMINFO
		LD	A,(NUMROM)
		SLA	A
		LD	C,A
		LD	B,0
		ADD	HL,BC
		RET

; end of INFOPTR
; ***************************************************************************
; proc CHCKSLOT

CHCKSLOT:	PUSH	AF
		LD	H,80H
		CALL	24H
		EI
		XOR	A
		LD	(08000H),A
		LD	(09000H),A

		LD	HL,(8000H)	; just in case for ram memory
		LD	DE,4241H
		RST	20H
		JP	NZ,PAGE1
		LD	C,1
NEXTMEGA:	LD	A,C
		LD	(8000H),A
		LD	(9000H),A
		LD	HL,(8000H)
		LD	DE,4241H
		RST	20H
		JR	Z,ENDMEGA
		INC	C
		JR	NEXTMEGA

		; size is 8 * A KB
ENDMEGA:	LD	A,C
		CP	1
		JR	Z,NOTMEGA

NXTMG2:		DEC	C		; Ok, countdown...
		LD	A,C
		LD	(8000H),A
		LD	(9000H),A
		LD	HL,08000H
NXTMG:		LD	A,(HL)
		CP	255
		JR	NZ,ENDMEGA2
		INC	HL
		LD	A,H
		CP	0A0H
		JR	NZ,NXTMG
		JR	NXTMG2

ENDMEGA2:	LD	A,C
		INC	A
		PUSH	AF
		CALL	INFOPTR
		POP	AF
		DEC	A
		RRCA
		RRCA
		RRCA
		RRCA
		AND	3
		CP	3
		JR	NZ,NOT512
		DEC	A
NOT512:		ADD	A,MEGA128
		LD	(HL),A
		INC	HL
		POP	AF
		LD	(HL),A
		LD	HL,NUMROM
		INC	(HL)
		RET

NOTMEGA:	LD	HL,0A000H
		LD	A,255
NEXT8KBU:	CP	(HL)
		JR	NZ,NOTFF3
		INC	HL
		LD	A,H
		CP	0C0H
		JR	NZ,NEXT8KBU
MUST8KBU:	CALL	INFOPTR
		LD	A,ROM8KB2
		LD	(HL),A
		INC	HL
		POP	AF
		LD	(HL),A
		LD	HL,NUMROM
		INC	(HL)
		RET

NOT:		POP	AF
		RET

NOTFF3:		LD	HL,8000H
		LD	DE,0A000H
NEXTFF3:	LD	A,(DE)
		CP	(HL)
		JR	NZ,MUST16KU
		INC	HL
		INC	DE
		LD	A,H
		CP	0C0H
		JR	NZ,NEXTFF3
		JR	MUST8KBU

MUST16KU:	CALL	INFOPTR
		LD	A,ROM16KB2
		LD	(HL),A
		INC	HL
		POP	AF
		LD	(HL),A
		LD	HL,NUMROM
		INC	(HL)
		RET

PAGE1:		POP	AF
		PUSH	AF
		LD	B,A
		LD	A,(0FFA7H)
		CP	0C9H
		JR	Z,NOBDOS2
		LD	A,(0F348H)
		CP	B
		JR	NZ,NOBDOS2
		POP	AF
		RET

NOBDOS2:	LD	A,B
		LD	H,40H
		CALL	24H
		EI
		XOR	A
		LD	(4000H),A
		LD	(5000H),A
		LD	HL,(4000H)
		LD	DE,4241H
		RST	20H
		JR	Z,PAGE1YES
		POP	AF
		RET

PAGE1YES:	LD	HL,6000H
NEXT8KB:	LD	A,255
		CP	(HL)
		JR	NZ,NOTFF
		INC	HL
		LD	A,H
		CP	80H
		JR	NZ,NEXT8KB

		; must be 8 kb
MUST8KB:	CALL	INFOPTR
		LD	A,ROM8KB
		LD	(HL),A
		INC	HL
		POP	AF
		LD	(HL),A
		LD	HL,NUMROM
		INC	(HL)
		RET

		; 16 ? 8 ?
NOTFF:		LD	HL,4000H
		LD	DE,6000H
NEXT8KB2:	LD	A,(DE)
		CP	(HL)
		JR	NZ,MUSTN8KB
		INC	DE
		INC	HL
		LD	A,H
		CP	80H
		JR	NZ,NEXT8KB2
		JR	MUST8KB

		; 16 ? 32 ?
MUSTN8KB:	POP	AF
		PUSH	AF
		LD	H,80H
		CALL	24H
		EI
		LD	HL,8000H
NEXT16KB:	LD	A,255
		CP	(HL)
		JR	NZ,NOTFF2
		INC	HL
		LD	A,H
		CP	0C0H
		JR	NZ,NEXT16KB
MUST16KB:	CALL	INFOPTR
		LD	A,ROM16KB
		LD	(HL),A
		INC	HL
		POP	AF
		LD	(HL),A
		LD	HL,NUMROM
		INC	(HL)
		RET
NOTFF2:		LD	DE,8000H
		LD	HL,0A000H
NEXTFF2:	LD	A,(DE)
		CP	(HL)
		JR	NZ,MUST32KB
		INC	DE
		INC	HL
		LD	A,H
		CP	0C0H
		JR	NZ,NEXTFF2
		JR	MUST16KB
MUST32KB:	CALL	INFOPTR
		LD	A,ROM32KB
		LD	(HL),A
		INC	HL
		POP	AF
		LD	(HL),A
		LD	HL,NUMROM
		INC	(HL)
		RET

; end of proc CKCKSLOT
; ***************************************************************************
; DISPLAY proc

DISPLAY:	LD	HL,HEADER
		CALL	PRINTCR
		XOR	A
NEXTNUMB:	PUSH	AF
		CP	9
		JR	NC,TEN
		LD	A,' '
		CALL	0A2H
		POP	AF
		PUSH	AF
		ADD	A,'1'
		CALL	0A2H
		JR	NOTTEN
TEN:		LD	A,'1'
		CALL	0A2H
		POP	AF
		PUSH	AF
		ADD	A,'0'-9
		CALL	0A2H
NOTTEN:		LD	A,' '
		CALL	0A2H
		LD	A,' '
		CALL	0A2H
		POP	AF
		PUSH	AF
		LD	HL,ROMINFO
		SLA	A
		LD	C,A
		LD	B,0
		ADD	HL,BC
		PUSH	HL
		INC	HL
		LD	A,(HL)
		LD	B,A
		AND	3
		ADD	A,'0'
		PUSH	BC
		CALL	0A2H
		LD	A,'-'
		CALL	0A2H
		POP	BC
		LD	A,B
		RRCA
		RRCA
		AND	3
		ADD	A,'0'
		CALL	0A2H
		LD	A,' '
		CALL	0A2H
		LD	A,' '
		CALL	0A2H
		POP	HL
		LD	A,(HL)
		CP	MSXBDOS
		JR	NC,NOTBIOS	; NC=JAE
		PUSH	AF
		DEC	A
		AND	3
		SLA	A
		LD	C,A
		LD	B,0
		LD	HL,MSXTBL
		ADD	HL,BC
		LD	E,(HL)
		INC	HL
		LD	D,(HL)
		EX	DE,HL
		CALL	PRINT
		POP	AF
		CP	MSX2EXT
		LD	HL,EXTBIOS
		JR	NC,EXT		; NC=JAE
		LD	HL,BIOS
EXT:		CALL	PRINTCR
		JR	ENDNUMB
NOTBIOS:	CP	MSXBDOS
		JR	NZ,NOTBDOS
		LD	HL,MSXBDS
		CALL	PRINT
		LD	C,0CH
		CALL	BDOS
		LD	A,L
		RRCA
		RRCA
		RRCA
		RRCA
		AND	3
		ADD	A,'0'
		CALL	0A2H
		LD	A,'.'
		CALL	0A2H
		LD	A,L
		AND	3
		ADD	A,'0'
		CALL	0A2H
		CALL	CRLF
		JR	ENDNUMB
NOTBDOS:	PUSH	AF
		SUB	ROM8KB
		SLA	A
		LD	C,A
		LD	B,0
		LD	HL,SIZETBL
		ADD	HL,BC
		LD	E,(HL)
		INC	HL
		LD	D,(HL)
		EX	DE,HL
		CALL	PRINT
		POP	AF
		CP	MEGA128
		LD	HL,MEGACART
		JR	NC,MEGA
		LD	HL,ROMCART
MEGA:		CALL	PRINTCR
ENDNUMB:	POP	AF
		INC	A
		LD	HL,NUMROM
		CP	(HL)
		JR	NC,ASK
		JP	NEXTNUMB

		; ask for ROM
ASK:		LD	HL,ENTER
		JP	PRINT

; end of DISPLAY proc
; ***************************************************************************
; INPUT proc

INPUT:		CALL	9FH
		CP	'Q'
		JR	Z,QUIT
		CP	'q'
		JR	Z,QUIT
		CP	'S'
		JR	Z,SEARCH
		CP	's'
		JR	Z,SEARCH
		SUB	'1'
		JR	C,INPUT
		LD	HL,NUMROM
		CP	(HL)
		JR	NC,INPUT
		LD	C,A
		ADD	A,'1'
		CALL	0A2H
		LD	A,C
		CP	0
		JP	NZ,CRLF
		LD	A,(NUMROM)
		CP	10
		LD	A,C
		JP	C,CRLF
INPUT2:		CALL	9FH
		SUB	'0'
		JR	C,INPUT2
		LD	B,A
		LD	A,(NUMROM)
		SUB	10
		CP	B
		JR	C,INPUT2
		LD	A,B
		ADD	A,'0'
		CALL	0A2H
		LD	A,B
		ADD	A,10
		JP	CRLF
QUIT:		CALL	0A2H
		LD	A,'Q'
		JP	CRLF
SEARCH:		CALL	0A2H
		LD	A,'S'
		JP	CRLF

; end of INPUT proc
; ***************************************************************************
; SAVE proc

SAVE:		LD	C,A
		SLA	C
		LD	B,0
		LD	HL,ROMINFO
		ADD	HL,BC
		PUSH	HL
		LD	HL,SAVEDEV
		LD	(HL),0
		LD	A,(2DH)
		CP	3
		JR	NC,NOECHO
		LD	(HL),1
		LD	A,(0FFA7H)
		CP	0C9H
		JR	Z,NOECHO
		LD	HL,DEVICE
		CALL	PRINT
IGNORE:		CALL	9FH
		CP	27
		JR	Z,ESC
		LD	HL,SAVEDEV
		LD	(HL),1
		CP	'T'
		JR	Z,ECHO
		CP	't'
		JR	Z,ECHO
		LD	(HL),0
		CP	'D'
		JR	Z,ECHO
		CP	'd'
		JR	Z,ECHO
		JR	IGNORE
ESC:		POP	HL
		CALL	CRLF
		CALL	0C0H
		LD	HL,ABORTED
		JP	PRINTCR
ECHO:		CALL	0A2H
		CALL	CRLF
NOECHO:		POP	HL
		PUSH	HL
		CALL	GETNAME
		JR	C,ESC
		POP	HL
		LD	A,(SAVEDEV)
		OR	A
		JP	NZ,TAPESAVE
		JP	DISKSAVE

; end of SAVE proc
; ***************************************************************************
; GETNAME proc

GETNAME:
		LD	A,(HL)
		CP	ROM8KB
		JR	NC,DOASK
		DEC	A
		SLA	A
		LD	C,A
		LD	B,0
		LD	HL,FMSXTBL
		ADD	HL,BC
		LD	E,(HL)
		INC	HL
		LD	D,(HL)
		LD	HL,FILEBUF
		LD	B,8
NEXTF:		LD	A,(DE)
		CP	'$'
		JR	Z,ENDGET
		LD	(HL),A
		INC	HL
		INC	DE
		DJNZ	NEXTF
		JR	ENDGET
DOASK:		LD	HL,FILENAME
		CALL	PRINT
		LD	B,8
		LD	HL,FILEBUF
NEXTCH:		CALL	9FH
		CP	27
		JR	Z,ESC2
		CP	13
		JR	Z,CR
		CP	8
		JR	Z,BS
		CP	1DH
		JR	Z,BS

		CP	'0'
		JR	C,NEXTCH
		CP	'z'+1
		JR	NC,NEXTCH
		CP	'9'+1
		JR	C,CHOK
		CP	'A'
		JR	C,NEXTCH
		CP	'Z'+1
		JR	C,CHOK
		CP	'a'
		JR	C,NEXTCH

CHOK:		LD	C,A
		LD	A,B
		OR	A
		JR	Z,NEXTCH
		LD	A,C
		CALL	0A2H
		CP	'a'
		JR	C,NOUPPER
		CP	'z'+1
		JR	NC,NOUPPER
		AND	0DFH
NOUPPER:	LD	(HL),A
		INC	HL
		DEC	B
		JR	NEXTCH
ENDGET:		LD	A,B
		OR	A
		JR	Z,NOSPACES
		LD	(HL),' '
		INC	HL
		DJNZ	ENDGET
NOSPACES:	AND	A
		RET
ESC2:		SCF
		RET
CR:		LD	A,B
		CP	8
		JR	Z,NEXTCH
		CALL	CRLF
		JR	ENDGET
BS:		LD	A,B
		CP	8
		JR	Z,NEXTCH
		DEC	HL
		INC	B
		LD	A,8
		CALL	0A2H
		LD	A,' '
		CALL	0A2H
		LD	A,8
		CALL	0A2H
		JR	NEXTCH

; end of GETNAME proc
; ***************************************************************************
; proc PRNSAVE

PRNSAVE:	LD	HL,NOWSAV
		CALL	PRINT
		LD	HL,FILEBUF
		LD	B,8
NEXTFILE:	LD	A,(HL)
		CP	' '
		JR	Z,ENDFILE
		CALL	0A2H
		INC	HL
		DJNZ	NEXTFILE
ENDFILE:	LD	HL,ROMEXT
		JP	PRINTCR

; end of PRNSAV
; ***************************************************************************
; proc DISKSAVE

MEMSHORT:	POP	HL
		LD	HL,NOTMEM
		JP	PRINTCR

DISKSAVE:	PUSH	HL		; memory check
		LD	A,(HL)
		CP	ROM8KB2
		JR	NC,NOCHK
		LD	A,(PAGE2RAM)
		LD	H,080H
		CALL	024H
		LD	HL,08000H
		LD	BC,0100H
NEXTMEM:	XOR	A
		LD	(HL),A
		CP	(HL)
		JR	NZ,MEMSHORT
		CPL
		LD	(HL),A
		CP	(HL)
		JR	NZ,MEMSHORT
		INC	HL
		DEC	BC
		LD	A,C
		OR	B
		JR	NZ,NEXTMEM

		; end of mem check
NOCHK:		POP	HL
		PUSH	HL
		LD	A,(HL)
		CP	ROM8KB
		JR	Z,COMP8KB
		CP	ROM8KB2
		JR	Z,COMP8KB
		JR	NOT8KB
COMP8KB:	LD	HL,COMPMES
		CALL	PRINT
FMSXINP:	CALL	09FH
		LD	HL,FMSXCOMP
		LD	(HL),0
		CP	'N'
		JR	Z,ECHO2
		CP	'n'
		JR	Z,ECHO2
		LD	(HL),1
		CP	'Y'
		JR	Z,ECHO2
		CP	'y'
		JR	Z,ECHO2
		JR	FMSXINP
ECHO2:		CALL	0A2H
		CALL	CRLF
NOT8KB:		CALL	PRNSAVE
		LD	DE,FCB
		LD	C,016H
		LD	(ERRSTACK),SP
		CALL	BDOS
		OR	A
		JR	NZ,FILEERR
		LD	HL,02000H
		LD	(FCB+0EH),HL
		LD	HL,0
		LD	(FCB+021H),HL
		LD	(FCB+023H),HL
		LD	DE,08000H	; check A
		LD	C,01AH
		CALL	BDOS
		POP	HL
		PUSH	HL
		LD	C,(HL)
		LD	B,0
		DEC	C
		SLA	C
		LD	HL,DISKTBL
		ADD	HL,BC
		LD	E,(HL)
		INC	HL
		LD	D,(HL)
		EX	DE,HL
		LD	(DISKCALL),HL
		POP	HL
		INC	HL
		DB	0CDH		; opcode of CALL
DISKCALL:	DW	0
		OR	A
		RET	NZ
		LD	DE,FCB
		LD	C,010H
		LD	(ERRSTACK),SP
		CALL	BDOS
		OR	A
		RET	NZ
		LD	HL,FINSAV
		JP	PRINTCR
FILEERR:	POP	HL
		RET

DISKTBL:	DW	DISKBIOS,DISKBIOS,DISKBIOS,DISKBIOS
		DW	0		; SHOULD NOT BE USED!!!
		DW	DISKEXBS,DISKEXBS,DISKEXBS
		DW	DISK16KB
		DW	DISK8KB,DISK16KB,DISK32KB
		DW	DISK8KBU,DISK16KU,DISK128K,DISK256K,DISK512K

DISKBIOS:	LD	A,(PAGE2RAM)
		LD	H,080H
		CALL	024H
		LD	A,(0FCC1H)
		LD	H,040H
		CALL	024H
		EI
		LD	HL,0
		LD	DE,08000H
		LD	BC,04000H
		LDIR
		LD	DE,FCB
		LD	HL,2
		LD	C,026H
		LD	(ERRSTACK),SP
		CALL	BDOS
		OR	A
		RET	NZ
		LD	HL,04000H
		LD	DE,08000H
		LD	BC,04000H
		LDIR
		LD	DE,FCB
		LD	HL,2
		LD	C,026H
		LD	(ERRSTACK),SP
		JP	BDOS

DISKEXBS:	PUSH	HL
		LD	A,(PAGE2RAM)
		LD	H,080H
		CALL	024H
		DI		; enaslt (024H) does not support mem in page 0. We'll use are own.
		IN	A,(0A8H)
		LD	C,A
		LD	A,(0FFFFH)
		CPL
		LD	B,A
		POP	HL
		LD	A,(HL)
		PUSH	BC
		AND	3
		LD	D,A
		LD	A,C
		AND	0FCH
		OR	D
		OUT	(0A8H),A
		LD	A,(HL)
		RRCA
		RRCA
		AND	3
		LD	E,A
		LD	A,B
		AND	0FCH
		OR	E
		LD	(0FFFFH),A
		LD	HL,0
		LD	DE,08000H
		LD	BC,04000H
		LDIR
		POP	BC
		LD	A,C
		OUT	(0A8H),A
		LD	A,B
		LD	(0FFFFH),A
		EI
		LD	DE,FCB
		LD	HL,2
		LD	C,026H
		LD	(ERRSTACK),SP
		JP	BDOS

DISK8KB:	LD	A,(FMSXCOMP)
		OR	A
		JR	NZ,DISK16KB
		LD	A,(HL)
		LD	H,040H
		CALL	024H
		LD	A,(PAGE2RAM)
		LD	H,080H
		CALL	024H
		EI
		LD	HL,04000H
		LD	DE,08000H
		LD	BC,02000H
		LDIR
		LD	DE,FCB
		LD	HL,1
		LD	C,026H
		LD	(ERRSTACK),SP
		JP	BDOS

DISK16KB:	LD	A,(HL)
		LD	H,040H
		CALL	024H
		LD	A,(PAGE2RAM)
		LD	H,080H
		CALL	024H
		EI
		LD	HL,04000H
		LD	DE,08000H
		LD	BC,04000H
		LDIR
		LD	DE,FCB
		LD	HL,2
		LD	C,026H
		LD	(ERRSTACK),SP
		JP	BDOS

DISK32KB:	PUSH	HL
		LD	A,(HL)
		LD	H,040H
		CALL	024H
		LD	A,(PAGE2RAM)
		LD	H,080H
		CALL	024H
		EI
		LD	HL,04000H
		LD	DE,08000H
		LD	BC,04000H
		LDIR
		LD	DE,FCB
		LD	HL,2
		LD	C,026H
		LD	(ERRSTACK),SP
		CALL	BDOS
		POP	HL
		OR	A
		RET	NZ
		LD	A,(HL)
		LD	H,080H
		CALL	024H
		LD	DE,FCB
		LD	HL,2
		LD	C,026H
		LD	(ERRSTACK),SP
		JP	BDOS

DISK8KBU:	LD	A,(FMSXCOMP)
		OR	A
		JR	NZ,DISK16KU
		LD	A,(HL)
		LD	H,080H
		CALL	024H
		EI
		LD	DE,FCB
		LD	HL,1
		LD	C,026H
		LD	(ERRSTACK),SP
		JP	BDOS

DISK16KU:	LD	A,(HL)
		LD	H,080H
		CALL	024H
		EI
		LD	DE,FCB
		LD	HL,2
		LD	C,026H
		LD	(ERRSTACK),SP
		JP	BDOS

DISK128K:	LD	B,16
		JR	DISKMEGA
DISK256K:	LD	B,32
		JR	DISKMEGA
DISK512K:	LD	B,64
DISKMEGA:	LD	C,0
		PUSH	BC
		LD	A,(HL)
		LD	H,080H
		CALL	024H
		EI
		POP	BC
NEXTDKMG:	PUSH	BC
		LD	A,C
		LD	(08000H),A
		LD	(09000H),A
		LD	DE,FCB
		LD	HL,1
		LD	C,026H
		LD	(ERRSTACK),SP
		CALL	BDOS
		POP	BC
		INC	C
		DJNZ	NEXTDKMG
		RET

; end of DISKSAVE proc
; ***************************************************************************
; proc TAPESAVE

TAPESAVE:	PUSH	HL
		LD	HL,BAUD
		CALL	PRINT
INBAUD:		CALL	09FH
		CP	27		; ESC
		JR	NZ,NOTESC
		POP	HL
		CALL	CRLF
		CALL	0C0H
		LD	HL,ABORTED
		JP	PRINTCR
NOTESC:		CP	'1'
		JR	Z,BD1200
		CP	'2'
		JR	Z,BD2400
		JR	INBAUD
BD1200:		LD	HL,0F3FCH
		JR	BAUD12
BD2400:		LD	HL,0F401H
BAUD12:		LD	DE,0F406H
		LD	BC,5
		LDIR
		CALL	0A2H
		CALL	CRLF
		CALL	PRNSAVE
		LD	A,255		; write header
		CALL	0EAH
		JR	C,HTAPERR 
		LD	B,16
NEXTHEAD:	LD	A,055H
		PUSH	BC
		CALL	0EDH
		POP	BC
		JR	C,HTAPERR
		DJNZ	NEXTHEAD
		LD	HL,FILEBUF
		LD	B,8
NXTHEAD2:	PUSH	HL
		PUSH	BC
		LD	A,(HL)
		CALL	0EDH
		POP	BC
		POP	HL
		INC	HL
		JR	C,HTAPERR
		DJNZ	NXTHEAD2
		CALL	0E7H
		POP	HL
		PUSH	HL		; write actual file
		LD	C,(HL)
		LD	B,0
		DEC	C
		SLA	C
		LD	HL,TAPETBL
		ADD	HL,BC
		LD	E,(HL)
		INC	HL
		LD	D,(HL)
		EX	DE,HL
		LD	(TAPECALL),HL
		POP	HL
		INC	HL
		DB	0CDH		; opcode of CALL
TAPECALL:	DW	0
		LD	HL,FINSAV
		JP	PRINTCR
TAPERR:		POP	BC
HTAPERR:	CALL	0E7H
		CALL	0C0H
		LD	HL,TAPEERR
		JP	PRINTCR

TAPETBL:	DW	TAPEBIOS,TAPEBIOS,TAPEBIOS,TAPEBIOS
		DW	0		; should not be used
		DW	TAPEEXBS,TAPEEXBS,TAPEEXBS
		DW	TAPE16KB
		DW	TAPE8KB,TAPE16KB,TAPE32KB,TAPE8KBU,TAPE16KU,TAPE128K,TAPE256K,TAPE512K

TAPEBIOS:	LD	A,(0FCC1H)
		LD	H,040H
		CALL	024H
		XOR	A
		CALL	0EAH
		JR	C,TAPERR
		LD	A,4
		CALL	0EDH
		JR	C,TAPERR
		LD	HL,0
NXTBIOS:	LD	A,(HL)
		PUSH	HL
		CALL	0EDH
		POP	HL
		JR	C,TAPERR
		INC	HL
		LD	A,H
		CP	080H
		JR	NZ,NXTBIOS
		JP	0E7H

TAPEEXBS:	PUSH	HL
		LD	A,(PAGE2RAM)
		LD	H,080H
		CALL	024H
		DI		; enaslt (024H) does not support mem in page 0. We'll use are own.
		IN	A,(0A8H)
		LD	C,A
		LD	A,(0FFFFH)
		CPL
		LD	B,A
		POP	HL
		LD	A,(HL)
		PUSH	BC
		AND	3
		LD	D,A
		LD	A,C
		AND	0FCH
		OR	D
		OUT	(0A8H),A
		LD	A,(HL)
		RRCA
		RRCA
		AND	3
		LD	E,A
		LD	A,B
		AND	0FCH
		OR	E
		LD	(0FFFFH),A
		LD	HL,0
		LD	DE,08000H
		LD	BC,04000H
		LDIR
		POP	BC
		LD	A,C
		OUT	(0A8H),A
		LD	A,B
		LD	(0FFFFH),A
		EI
		XOR	A
		CALL	0EAH
		JP	C,TAPERR
		LD	A,2
		CALL	0EDH
		JP	C,TAPERR
		LD	HL,08000H
NXTEXBS:	LD	A,(HL)
		PUSH	HL
		CALL	0EDH
		POP	HL
		JP	C,TAPERR
		INC	HL
		LD	A,H
		CP	0C0H
		JR	NZ,NXTEXBS
		JP	0E7H

TAPE8KB:	LD	A,(HL)
		LD	H,040H
		CALL	024H
		LD	A,(PAGE2RAM)
		LD	H,080H
		CALL	024H
		EI
		LD	HL,04000H
		LD	DE,08000H
		LD	BC,02000H
		LDIR
		XOR	A
		CALL	0EAH
		JP	C,TAPERR
		LD	A,1
		CALL	0EDH
		JP	C,TAPERR
		LD	HL,08000H
NXT8KB:		LD	A,(HL)
		PUSH	HL
		CALL	0EDH
		POP	HL
		JP	C,TAPERR
		INC	HL
		LD	A,H
		CP	0A0H
		JR	NZ,NXT8KB
		JP	0E7H

TAPE16KB:	LD	A,(HL)
		LD	H,040H
		CALL	024H
		LD	A,(PAGE2RAM)
		LD	H,080H
		CALL	024H
		EI
		LD	HL,04000H
		LD	DE,08000H
		LD	BC,04000H
		LDIR
		XOR	A
		CALL	0EAH
		JP	C,TAPERR
		LD	A,2
		CALL	0EDH
		JP	C,TAPERR
		LD	HL,08000H
NXT16KB:	LD	A,(HL)
		PUSH	HL
		CALL	0EDH
		POP	HL
		JP	C,TAPERR
		INC	HL
		LD	A,H
		CP	0C0H
		JR	NZ,NXT16KB
		JP	0E7H

TAPE32KB:	LD	A,(HL)
		PUSH	AF
		LD	H,040H
		CALL	024H
		POP	AF
		LD	H,080H
		CALL	024H
		EI
		XOR	A
		CALL	0EAH
		JP	C,TAPERR
		LD	A,4
		CALL	0EDH
		JP	C,TAPERR
		LD	HL,04000H
NXT32KB:	LD	A,(HL)
		PUSH	HL
		CALL	0EDH
		POP	HL
		JP	C,TAPERR
		INC	HL
		LD	A,H
		CP	0C0H
		JR	NZ,NXT32KB
		JP	0E7H

TAPE8KBU:	LD	A,(HL)
		LD	H,080H
		CALL	024H
		EI
		XOR	A
		CALL	0EAH
		JP	C,TAPERR
		LD	A,1
		CALL	0EDH
		JP	C,TAPERR
		LD	HL,08000H
NXT8KBU:	LD	A,(HL)
		PUSH	HL
		CALL	0EDH
		POP	HL
		JP	C,TAPERR
		INC	HL
		LD	A,H
		CP	0A0H
		JR	NZ,NXT8KBU
		JP	0E7H

TAPE16KU:	LD	A,(HL)
		LD	H,080H
		CALL	024H
		EI
		XOR	A
		CALL	0EAH
		JP	C,TAPERR
		LD	A,2
		CALL	0EDH
		JP	C,TAPERR
		LD	HL,08000H
NXT16KU:	LD	A,(HL)
		PUSH	HL
		CALL	0EDH
		POP	HL
		JP	C,TAPERR
		INC	HL
		LD	A,H
		CP	0C0H
		JR	NZ,NXT16KU
		JP	0E7H

TAPE128K:	LD	B,16
		JR	TAPEMEGA
TAPE256K:	LD	B,32
		JR	TAPEMEGA
TAPE512K:	LD	B,64
TAPEMEGA:	LD	C,0
		PUSH	BC
		LD	A,(HL)
		LD	H,080H
		CALL	024H
		POP	BC
		EI
NXT128K:	LD	A,C
		PUSH	BC
		LD	(08000H),A
		LD	(09000H),A
		XOR	A
		CALL	0EAH
		JP	C,TAPERR
		POP	BC
		PUSH	BC
		LD	A,C
		OR	A
		JR	NZ,NOSIZE
		LD	A,B
		CALL	0EDH
		JP	C,TAPERR
NOSIZE:		LD	HL,08000H
NEXT128:	LD	A,(HL)
		PUSH	HL
		CALL	0EDH
		POP	HL
		JP	C,TAPERR
		INC	HL
		LD	A,H
		CP	0A0H
		JR	NZ,NEXT128
		CALL	0E7H
		POP	BC
		INC	C
		DJNZ	NXT128K
		RET

; end of TAPESAVE proc
; ***************************************************************************
; proc PRINTCR

PRINTCR:	LD	A,(HL)
		CP	'$'
		JR	Z,CRLF
		PUSH	HL
		CALL	0A2H
		POP	HL
		INC	HL
		JR	PRINTCR

; end of proc PRINTCR
; ***************************************************************************
; proc CRLF

CRLF:		PUSH	AF
		LD	A,0DH
		CALL	0A2H
		LD	A,0AH
		CALL	0A2H
		POP	AF
		RET

; end of prov CRLF
; ***************************************************************************
; proc PRINT

PRINT:		LD	A,(HL)
		CP	'$'
		RET	Z
		PUSH	HL
		CALL	0A2H
		POP	HL
		INC	HL
		JR	PRINT

; end of proc PRINT
; ***************************************************************************
; proc DISKERHK

DSKHKPTR:	DW	DISKERHK

DISKERHK:	PUSH	AF
		LD	A,C
		AND	0EH
		LD	HL,DISKWRIT
		JR	Z,PRN
		CP	2
		LD	HL,DISKREAD
		JR	Z,PRN
		LD	HL,DISKERR
PRN:		CALL	PRINT
		LD	HL,DISKARI
		CALL	PRINT
INPUT3:		CALL	09FH
		LD	C,0
		CP	'R'
		JR	Z,OK
		CP	'r'
		JR	Z,OK
		LD	C,1
		CP	'I'
		JR	Z,OK
		CP	'i'
		JR	Z,OK
		LD	C,2
		CP	'A'
		JR	Z,OK
		CP	'a'
		JR	Z,OK
		JR	INPUT3
OK:		CALL	0A2H
		CALL	CRLF
		POP	AF
		RET

; end of proc DISKERHK
; ***************************************************************************
; proc ABORTH

ABORTH:		LD	SP,(ERRSTACK)
		RET

; end of proc ABORTH
; ***************************************************************************
; strings 'n variables

BEGINMES:	DB	'GetROM: ROM Saving Utility Version 1.1'
		DB	13,10,'Copyright (C) Sean Young 1996'
		DB	13,10,'All rights Reserved.'
		DB	13,10,13,10,'This program is part of the Virtual MSX'
		DB	13,10,'software package.$'
HEADER:		DB	13,10,'No. Slot Description$'
BIOS:		DB	' BIOS$'
EXTBIOS:	DB	' Extended BIOS$'
MSX1:		DB	'MSX1$'
MSX2:		DB	'MSX2$'
MSX2P:		DB	'MSX2+$'
MSXR:		DB	'MSX turbo R$'
MSXTBL:		DW	MSX1,MSX2,MSX2P,MSXR
MSXBDS:		DB	'BDOS (Disk BIOS) Version $'
ROMCART:	DB	' Kb ROM$'
MEGACART:	DB	' Kb MegaROM$'
S8:		DB	'8$'
S16:		DB	'16$'
S32:		DB	'32$'
S128:		DB	'128$'
S256:		DB	'256$'
S512:		DB	'512$'
SIZETBL:	DW	S8,S16,S32
		DW	S8,S16,S128,S256,S512

ENTER:		DB	'Enter number or <Q> to quit or '
		DB	13,10,'<S> to search again: $'
DEVICE:		DB	13,10,'<T> Tape Save'
		DB	13,10,'<D> Disk Save'
		DB	13,10,'Enter device or <ESC> to go back: $'
FILENAME:	DB	13,10,'Enter filename (max. 8 chars, without '
		DB	13,10,'extension) or <ESC> for back: $'
NOWSAV:		DB	13,10,'Now saving : $'
ROMEXT:		DB	'.ROM$'
FINSAV:		DB	'File saved.$'
FMSX:		DB	'MSX$'
FMSX2:		DB	'MSX2$'
FMSX2P:		DB	'MSX2P$'
FMSXTR:		DB	'MSXTR$'
FMSX2EXT:	DB	'MSX2EXT$'
FMSX2PXT:	DB	'MSX2PEXT$'
FMSXTRXT:	DB	'MSXTREXT$'
FMSXDISK:	DB	'DISK$'
FMSXTBL:	DW	FMSX,FMSX2,FMSX2P,FMSXTR
		DW	0		; ERROR: should not exist
		DW	FMSX2EXT,FMSX2PXT,FMSXTRXT
		DW	FMSXDISK

BAUD:		DB	13,10,'<1> 1200 Baud'
		DB	13,10,'<2> 2400 Baud'
		DB	13,10,'Enter baud rate or <ESC> to go back: $'
TAPEERR:	DB	'Tape Error$'
ABORTED:	DB	'Aborted$'
COMPMES:	DB	13,10,'fMSX does not support 8 Kb ROM images.'
		DB	13,10,'However, Virtual MSX does.'
		DB	13,10,'Save as 16 Kb ROM image (y/n) ? $'
NOTMEM:		DB	13,10,'This operation requires at least '
		DB	13,10,'32 Kb RAM.$'
DISKREAD:	DB	13,10,'Disk offline.$'
DISKWRIT:	DB	13,10,'Disk write protected.$'
DISKERR:	DB	13,10,'Disk error.$'
DISKARI:	DB	13,10,'Abort, retry, ignore (a/r/i) ? $'
FCB:		DB	0
FILEBUF:	DB	'FILENAMEROM'
END:		EQU	$-1
		RB	25
PAGE2RAM:	RB	1
NUMROM:		RB	1
SAVEDEV:	RB	1
FMSXCOMP:	RB	1
DKHKBKUP:	RW	1
ABORTHBK:	RW	1
ERRSTACK:	RW	1
ROMINFO:	;NOP			; END OF PROGRAM
