; -----------------------------------------------------------
; uIecSwitchS2: switch disk images on a uIEC (I/O, data)
; -----------------------------------------------------------
.if	Pass1
	.noeqin
	.noglbl
	.include	uIecSwitchSym
	.include	uIecSwitchMac
	.include	uIecSwitch.inc
	.include	cbm.inc
	.glbl
	.eqin
.endif
; -----------------------------------------------------------
; Verify that there is a uIEC or sd2iec on the system. Send "X?", 
; which is specific to these devices, and check for device name 
; in output. Assume that only one of these devices is present.
;	return:	carry clear if uIEC found, set otherwise
; -----------------------------------------------------------
findUiec:	lda	curDrive
	sta	savDrive
	ldy	#8
10$	tya
	pha
	sta	drvUiec
	sta	curDrive
	jsr	ExitTurbo
	jsr	PurgeTurbo
	jsr	ckUiec
	pla
	tay
	bcs	20$	;not found here
	clc		;take first one (in drvUiec)
	rts
20$	iny
	cpy	#11	;try drives, A, B, C
	bne	10$
	sec		;no uIEC found
	rts
; -----------------------------------------------------------
; Check if current device is a uIEC or sd2iec.
;	pass:	curDrive, the drive to check
;	return:	carry clear if found, set otherwise
; -----------------------------------------------------------
ckUiec:	LoadW	r0,xq
	jsr	sendCmd	;calls InitForIO/DoneWithIO
	bcs	60$	;no drive at this address
	ldx	#0
	ldy	#3
10$	lda	uIec,x
	beq	70$
	cmp	msg,y
	bne	20$
	inx
	iny
	bne	10$
;	------------------------------------------------
20$	ldx	#0
	ldy	#3
30$	lda	sd2iec,x
	beq	70$
	cmp	msg,y
	bne	40$
	inx
	iny
	bne	30$
;	------------------------------------------------
;	gh 1.2: some uIECs respond "00, OK,00,00" here!
;	------------------------------------------------
40$	ldx	#0
	ldy	#3
50$	lda	ok,x
	beq	70$
	cmp	msg,y
	bne	60$
	inx
	iny
	bne	50$
60$	sec		;not found
	rts
70$	clc		;found
	rts
; -----------------------------------------------------------
; Read current directory; store names of non-deleted files at fNames.
; -----------------------------------------------------------
readDir:	jsr	InitForIO
	jsr	openDir
	ldx	#2
	jsr	C_CHKIN
	ldy	#254	;skip header block
5$	jsr	C_CHRIN
	dey
	bne	5$
10$	LoadW	a0,fNames
	lda	#0
	sta	fCount	;number of files added to list
	sta	fCount+1
	sta	blkCount	;entry counter for this block
20$	ldy	#0
	jsr	C_CHRIN	;file type
	sta	tmpEntry,y
	iny
	jsr	C_CHRIN	;skip track & sector pointer
	jsr	C_CHRIN
30$	jsr	C_CHRIN	;filename
	sta	tmpEntry,y
	iny
	cpy	#17
	bcc	30$
	jsr	addEntry	;use this entry? (increments fCount)
	ldy	#0
40$	jsr	C_CHRIN	;discard remainder of entry
	lda	$90
	and	#$40	;EOF?
	bne	dirDone
	iny
	lda	blkCount
	cmp	#7	;every 8th entry is shorter
	beq	50$
	cpy	#13
	bcc	40$
	bcs	60$
50$	cpy	#11
	bcc	40$
60$	ldx	blkCount
	cpx	#7
	bcc	70$
	LoadB	blkCount,0
	beq	80$
70$	inc	blkCount
80$	bra	20$
dirDone:	lda	#2
	jsr	C_CLOSE
	jsr	DoneWithIO
	MoveW	a0L,fEnd	;end-of-list marker
	ldx	#0
	stx	topName
	stx	topName+1
	dex
	stx	selName
	rts
; -----------------------------------------------------------
; open directory as a sequential file
; -----------------------------------------------------------
openDir:	lda	#2
	ldx	curDrive
	ldy	#2
	jsr	C_SETLFS
	lda	#1
	ldx	#[dollar
	ldy	#]dollar
	jsr	C_SETNAM
	jsr	C_OPEN
	rts
; -----------------------------------------------------------
; Add filename to list (unless the file is deleted).
; -----------------------------------------------------------
addEntry:	lda	tmpEntry
	beq	20$	;deleted file
	ldy	#16	;add entry to list
10$	lda	tmpEntry,y
	sta	(a0),y
	dey
	bpl	10$
	AddVW	17,a0
	inc	fCount
	bne	20$
	inc	fCount+1
20$	rts
; -----------------------------------------------------------
; Determine whether filename represents a disk image.
;	pass:	pointer to filename in a8
;	return:	carry set if image, clear otherwise
;	preserved:	.Y
;	destroyed:	a9L
; -----------------------------------------------------------
isImage:	tya
	pha
	ldy	#1	;past file type
10$	lda	(a8),y
	cmp	#$a0	;first $a0 is end of filename
	beq	20$
	iny
	cpy	#17
	bne	10$
20$	dey		;back up from end of filename
	sty	a9L
	ldx	#3
30$	lda	(a8),y
	ora	#$20	;case-insensitive
	cmp	d64Ext,x
	bne	40$
	dey
	dex
	bpl	30$
	bmi	110$
40$	ldy	a9L
	ldx	#3
50$	lda	(a8),y
	ora	#$20	;case-insensitive
	cmp	d71Ext,x
	bne	60$
	dey
	dex
	bpl	50$
	bmi	110$
60$	ldy	a9L
	ldx	#3
70$	lda	(a8),y
	ora	#$20	;case-insensitive
	cmp	d81Ext,x
	bne	80$
	dey
	dex
	bpl	70$
	bmi	110$
80$	ldy	a9L
	ldx	#3
90$	lda	(a8),y
	ora	#$20	;case-insensitive
	cmp	dnpExt,x
	bne	100$
	dey
	dex
	bpl	90$
	bmi	110$
100$	clc		;not an image
	bcc	120$
110$	sec		;is an image
120$	pla
	tay
	rts
; -----------------------------------------------------------
; Send disk command and read response (does not open a file).
; -----------------------------------------------------------
sendCmd:	jsr	InitForIO
	LoadB	C_STATUS,0
	lda	drvUiec
	jsr	C_LISTEN
	bit	C_STATUS
	bmi	10$
	lda	#$6f
	jsr	C_SECOND
	bit	C_STATUS
	bpl	20$
10$	jsr	C_UNLSN
	jsr	DoneWithIO
	sec
	rts
20$	ldy	#0
30$	lda	(r0),y
	beq	40$
	jsr	C_CIOUT
	iny
	bne	30$
40$	jsr	C_UNLSN
	lda	drvUiec
	jsr	C_TALK
	bit	C_STATUS
	bmi	50$
	lda	#$6f
	jsr	C_TKSA
	bit	C_STATUS
	bpl	60$
50$	jsr	C_UNTLK
	jsr	DoneWithIO
	sec
	rts
60$	ldy	#0
70$	jsr	C_ACPTR
	cmp	#$0d
	bne	80$
	lda	#0
80$	sta	msg,y
	iny
	bit	C_STATUS	;EOF (#$40)?
	bvc	70$
	lda	#0
	sta	msg,y
	jsr	C_UNTLK
	jsr	DoneWithIO
	clc
	rts
; -----------------------------------------------------------
;	Get string width in pixels (must be < 256 chars).
;	pass:	string address in r0
;	return:	string length in a0
;	destroyed: a1L
; -----------------------------------------------------------
strWidth:	ldy	#0
	sty	a0L
	sty	a0H
10$	lda	(r0),y
	beq	20$
	sty	a1L
	jsr	GetCharWidth
	clc
	adc	a0L
	sta	a0L
	lda	#0
	adc	a0H
	sta	a0H
	ldy	a1L
	iny
	bne	10$	;string must be < 256 chars.
20$	rts
; -----------------------------------------------------------
; Generic beep.
; -----------------------------------------------------------
beep:	php
	sei
	lda	$01
	pha
	and	#$f8
	ora	#$05
	sta	$01
	LoadB	$d400,#$31	;voice 1 frequency low
	LoadB	$d401,#$1c	;voice 1 frequency high
	LoadB	$d405,#$00	;voice 1 attack/decay
	LoadB	$d406,#$f9	;voice 1 sustain/release
	LoadB	$d418,#$0c	;no filters, volume 15
	LoadB	$d404,#$11	;gate on triangle, voice 1
	LoadB	$d404,#$10	;gate off voice 1
	pla
	sta	$01
	plp
	rts
; -----------------------------------------------------------
; main menu
; -----------------------------------------------------------
mainMenu:	.byte	0,14
	.word	0,48
	.byte	HORIZONTAL | 2
	.word	geosText
	.byte	SUB_MENU
	.word	geosMenu
	.word	fileText
	.byte	SUB_MENU
	.word	fileMenu
geosText:	.byte	"geos",0
fileText:	.byte	"file",0
; -----------------------------------------------------------
geosMenu:	.byte	15,30
	.word	0,24
	.byte	VERTICAL | CONSTRAINED | 1
	.word	infoText
	.byte	MENU_ACTION
	.word	doInfo
infoText:	.byte	"info",0
; -----------------------------------------------------------
fileMenu:	.byte	15,30
	.word	28,52
	.byte	VERTICAL | CONSTRAINED | 1
	.word	quitText
	.byte	MENU_ACTION
	.word	doQuit
quitText:	.byte	"quit",0
; -----------------------------------------------------------
icons:	.byte	4	;no. icons
	.word	18	;X position to leave mouse
	.byte	5	;Y position to leave mouse
;	------------------------------------------------
	.word	upArrow	;pointer to icon image
	.byte	23	;X position in cards
	.byte	48	;Y position in pixels
	.byte	1,7	;width (cards), height (pixels)
	.word	doUp	;dispatch routine
;	------------------------------------------------
	.word	dnArrow	;pointer to icon image
	.byte	23	;X position in cards
	.byte	144	;Y position in pixels
	.byte	1,7	;width (cards), height (pixels)
	.word	doDown	;dispatch routine
;	------------------------------------------------
	.word	open	;pointer to icon image
	.byte	25	;X position in cards
	.byte	48	;Y position in pixels
	.byte	6,16	;width (cards), height (pixels)
	.word	doOpen	;dispatch routine
;	------------------------------------------------
	.word	parent	;pointer to icon image
	.byte	25	;X position in cards
	.byte	72	;Y position in pixels
	.byte	6,16	;width (cards), height (pixels)
	.word	doParent	;dispatch routine
; -----------------------------------------------------------
upArrow:
dnArrow:
open:
parent:

; -----------------------------------------------------------
; info dialog
; -----------------------------------------------------------
infoDlg:	.byte	DEF_DB_POS | 1
	.byte	DBTXTSTR,TXT_LN_X,TXT_LN_1_Y
	.word	infoName
	.byte	DBTXTSTR,TXT_LN_X,TXT_LN_2_Y
	.word	code
	.byte	DBTXTSTR,TXT_LN_X,TXT_LN_3_Y
	.word	qa
	.byte	OK,DBI_X_2,DBI_Y_2
	.byte	0	;end of dialog definition
infoName:	.byte	BOLDON,"uIEC Switch 1.2",PLAINTEXT,0
code:	.byte	"code: ShadowM",0
qa:	.byte	"QA: Wizard the Cat",0
; -----------------------------------------------------------
; generic error dialog
; -----------------------------------------------------------
errorDlg:	.byte	DEF_DB_POS | 1
	.byte	DBTXTSTR,TXT_LN_X,TXT_LN_1_Y
errorMsg:	.word	0	;filled in by caller
	.byte	OK,DBI_X_2,DBI_Y_2
	.byte	0	;end of dialog definition
noSelect:	.byte	"Nothing selected.",0
noParent:	.byte	"No parent directory.",0
noEntry:	.byte	"Not a disk image or subdirectory.",0
; -----------------------------------------------------------
uIecDlg:	.byte	DEF_DB_POS | 1
	.byte	DBTXTSTR,TXT_LN_X,TXT_LN_1_Y
	.word	uIecErr
	.byte	OK,DBI_X_2,DBI_Y_2
	.byte	0
uIecErr:	.byte	"No uIEC or sd2iec found.",0
; -----------------------------------------------------------
typeDlg:	.byte	DEF_DB_POS | 1
	.byte	DBTXTSTR,TXT_LN_X,TXT_LN_1_Y
	.word	typeErr1
	.byte	DBTXTSTR,TXT_LN_X,TXT_LN_2_Y
	.word	typeErr2
	.byte	DBTXTSTR,TXT_LN_X,TXT_LN_3_Y
	.word	typeErr3
	.byte	DBTXTSTR,TXT_LN_X,TXT_LN_4_Y
	.word	typeErr4
	.byte	YES,DBI_X_1,DBI_Y_2
	.byte	NO,DBI_X_2,DBI_Y_2
	.byte	0
typeErr1:	.byte	"The partition or disk image selected",0
typeErr2:	.byte	"on your uIEC/sd2iec does not match",0
typeErr3:	.byte	"the GEOS drive type for that device.",0
typeErr4:	.byte	"Are you sure you want to exit?",0
; -----------------------------------------------------------
legend:	.byte	ULINEON,"legend",PLAINTEXT,":"
	.byte	GOTOXY
	.word	200
	.byte	117
	.byte	BOLDON,"DISK IMG.",PLAINTEXT
	.byte	GOTOXY
	.word	200
	.byte	127
	.byte	ITALICON,"DIRECTORY",PLAINTEXT
	.byte	GOTOXY
	.word	200
	.byte	137
	.byte	"OTHER FILES",0
; -----------------------------------------------------------
uIec:	.byte	"UIEC",0
sd2iec:	.byte	"SD2IEC",0
ok:	.byte	" OK",0
xq:	.byte	"X?",0
dollar:	.byte	"$",0
cdImage:	.byte	"CD:"
	.block	17
chDir:	.byte	"CD/"
	.block	17
cdParent:	.byte	"CD",95,0	;95 is back-arrow
gp:	.byte	"G-P",255,0
savDrive:	.byte	0
drvUiec:	.byte	0
d64Ext:	.byte	".d64",0
d71Ext:	.byte	".d71",0
d81Ext:	.byte	".d81",0
dnpExt:	.byte	".dnp",0
title:	.byte	" uIecSwitch 1.2 ",0
fCount:	.word	0
fEnd:	.word	0
blkCount:	.byte	0
topName:	.word	0	;top item (index into filenames)
selName:	.byte	0	;selected item (index into listbox)
thumbSav:	.byte	#$ff	;last top thumb position
thumbHi:	.byte	0	;calculated thumb height
; -----------------------------------------------------------
.ramsect
tmpEntry:	.block	19
msg:	.block	64
fNames:	.block	1024
