NEW
  AUTO 3,1
*--------------------------------------
VolListPtr		.EQ	$65
*
SelectedIndex	.EQ	$67					name counter
filecount 		.EQ	$68					# of displayable files in directory

bInSubDir		.EQ	$6B					directory level
FilenamePtr		.EQ	$6C					filename storage pointer (16 bit)

ScrollIndex		.EQ	$73					index # of top name in display
*--------------------------------------
SEL1.PathBuf	.EQ $280
SEL1.BSPathBuf	.EQ $2C0
*--------------------------------------
SEL1.FileBuf	.EQ	$1800				1k
SEL1.DirBlk		.EQ	$1C00				512b
SEL1.filetypes	.EQ	$1F00
SEL1.Filenames	.EQ $2000
*--------------------------------------
SEL1.START		.PH	$1000

SEL1.START1		cld
				bit IO.RROMBNK2			read ROM

				lda #$A0
				jsr $C300			 	initialize 80 column text card

* set up memory bitmap in global page

				ldx #TBX.MemReset
				jsr GP.TOOLBOX

				stz SEL1.BSPathBuf
*--------------------------------------
				ldx GP.DEVCNT

.1				lda GP.DEVLST,x
				and #$F0
				cmp GP.DEVNUM
				beq SEL1.GetVol

				dex
				bra .1
*--------------------------------------
SEL1.NextVol	ldx VolListPtr			get device list pointer.
				bne .1

				ldx GP.DEVCNT				get device count.
				inx

.1				dex
				lda GP.DEVLST,x			get unit number from list.
*--------------------------------------
SEL1.GetVol		stx VolListPtr
				sta SEL1.OnLineP+1		store unit number for online.
				jsr MLI
				.DA #MLI.ONLINE
				.DA SEL1.OnLineP
				bcs SEL1.NextVol	  	error check.

				stz bInSubDir		 	haven't read root directory yet.
				lda SEL1.PathBuf+1		load description byte.
				and #$0F			 	mask for name length.
				beq SEL1.NextVol	  	if 0, then try next unit.

				tax
				inx					 	add 2 to length.
SEL1.OpenDir1	inx		 				name length in x.

SEL1.OpenDir	stx SEL1.PathBuf		save the name length
				lda #'/'
				sta SEL1.PathBuf+1		slash before and
				sta SEL1.PathBuf,x		after name.

				jsr MLI
			   .DA #MLI.OPEN
			   .DA SEL1.OpenP
				bcc SEL1.EnumDir		good open.

				lda bInSubDir		 	trying to open root directory ?
				beq SEL1.NextVol	  	yes, just move to next volume.

				jsr ROM.BELL1		  	no, generate bell tone
				jsr SEL1.FullPath..		and stay at same level.
				stx SEL1.PathBuf
				jmp SEL1.KeyLoop
*--------------------------------------
SEL1.EnumDir	stz filecount			zero file count.
				
				jsr SEL1.SetFNPtr

				stz SEL1.ReadP+2
				lda /SEL1.DirBlk
				sta SEL1.ReadP+3

				stz SEL1.ReadP+4		512 bytes
				lda #2
				sta SEL1.ReadP+5

SEL1.EnumBlk	jsr MLI
			   .DA #MLI.READ
			   .DA SEL1.ReadP
				bcs SEL1.CloseDir

				lda /SEL1.DirBlk
				ldx #TBX.EnumBlk
				jsr GP.TOOLBOX
				bcs SEL1.CloseDir
				
SEL1.EnumDirNext
				jsr SEL1.SetFNPtr		Y,A = FilenamePtr
				ldx #TBX.EnumNext
				jsr GP.TOOLBOX
				bcs SEL1.EnumBlk

				ldx filecount			get valid files read.
				sta SEL1.filetypes,x

				lda (FilenamePtr)
				eor #SEL1.BS.L
				bne .8
				
				tay						Y = 0
				ldx SEL1.PathBuf
				
.1				iny
				lda SEL1.BS-1,y
				cmp (FilenamePtr),y
				bne .8

				inx
				sta SEL1.BSPathBuf,x
				
				cpy #SEL1.BS.L
				bne .1
				
				stx SEL1.BSPathBuf
				
				ldx SEL1.PathBuf
				
.2				lda SEL1.PathBuf,x
				sta SEL1.BSPathBuf,x
				dex
				bne .2

.8				inc filecount
				bne SEL1.EnumDirNext
*--------------------------------------
SEL1.CloseDir	jsr MLI					close directory file
			   .DA #MLI.CLOSE
			   .DA SEL1.CloseP

				jsr ROM.SETTXT		 	use full screen for windows
				jsr ROM.HOME

				lda #$17			 	cursor at bottom of screen.
				jsr ROM.TABV			set vertical position.

				ldy #SEL1.RetIcon-SEL1.Strings
				jsr SEL1.IconOutY

				ldy #SEL1.Footer-SEL1.Strings
				jsr SEL1.MsgOutY

				lda #$99
				jsr ROM.COUT			cursor to upper/left.

				ldx #$00
				ldy SEL1.PathBuf

.1  			lda SEL1.PathBuf+1,x

				jsr SEL1.COut
				inx
				dey
				bne .1

.2		 		stz	SelectedIndex
				stz ScrollIndex			init top filename index.
				ldx filecount			# of valid files.
				beq SEL1.KeyLoop	  	if no files.

				cpx #21				 	more than what will fit on screen ?
				bcc .3				  	no.

				ldx #20				 	limit to 20 files on the screen.

.3  			lda #2					set window dimensions
				sta ZP.WNDTOP

				lda #22
				sta ZP.WNDBOT

.4  			phx

				jsr SEL1.PrintFN
				inc SelectedIndex

				plx
				dex
				bne .4

				stz SelectedIndex
				beq L5EAA			  	if last file, it needs to be inverse.
*--------------------------------------
SEL1.Up			jsr	SEL1.PrintFN		print old name in normal.
				ldx SelectedIndex
				beq L5EAA			 	if already at the top name

				dec SelectedIndex
				lda ZP.CV		   		current cursor line.
				cmp #2				 	at top line of window ?
				bne L5EAA			  	no, move up normally.

				dec ScrollIndex			fix offset index
				lda #22				 	else sroll windows down a line.
				bne SEL1.Scroll		  	branch always.
*--------------------------------------
SEL1.Down		jsr	SEL1.PrintFN		print old name in normal.
				ldx SelectedIndex
				inx		 				add one.
				cpx filecount
				bcs L5EAA			  	if already at last filename

				stx SelectedIndex
				lda ZP.CV		   		current cursor line.
				cmp #21				 	at bottom line of window ?
				bne L5EAA			  	no, move cursor normally.

				inc ScrollIndex			update offset index
				lda #23				 	else scroll up a line.

SEL1.Scroll		jsr ROM.COUT

L5EAA  			jsr SEL1.PrintFNInv		output last filename.
*--------------------------------------
SEL1.KeyLoop	lda IO.KBD		  		get keyboard input.
				bpl SEL1.KeyLoop	  	loop until key pressed.

				sta IO.KBDSTROBE		clear strobe.

				ldx filecount			are any files displayed ?
				beq .1				  	no, don't accept arrow keys or return.

				cmp #$8D			 	return ?
				beq SEL1.CR			  	then run selected file.

				cmp #$8A			 	down ?
				beq SEL1.Down

				cmp #$8B			 	up ?
				beq SEL1.Up

.1	  			cmp #$89			 	tab ?
				beq L5EED			  	new volume.

				cmp #$9B			 	esc ?
				bne SEL1.KeyLoop	  	no, try again else pop up a directory.

				jsr SEL1.FullPath..		CD ..
				jmp SEL1.OpenDir
*--------------------------------------
L5EED  			jmp SEL1.NextVol		set up new unit number.
*--------------------------------------
SEL1.CR			ldy SelectedIndex
				lda	SEL1.filetypes,y	get file type.

				jsr SEL1.CheckType
				bmi SEL1.KeyLoop

				cmp #S.FI.T.DIR
				bne .1

				jsr SEL1.SetFullPath
				bcs L5EED

				jmp SEL1.OpenDir1

.1				cmp #S.FI.T.SYS
				beq .3

				lda SEL1.BSPathBuf
				beq SEL1.KeyLoop

				lda #SEL1.BSPathBuf
				sta SEL1.OpenP+1		open & read BASIC.SYSTEM

.3				jsr SEL1.SetFullPath
				bcs L5EED

				jsr MLI					open file
			   .DA #MLI.OPEN
			   .DA SEL1.OpenP
				bcs L5EED

				lda #$20
				sta SEL1.ReadP+3		read at $2000

				lda #$9f
				sta SEL1.ReadP+5		max $9F00

				jsr MLI
			   .DA #MLI.READ
			   .DA SEL1.ReadP
				php		 				save possible error.
				jsr MLI					close file. ignore any error from close
			   .DA #MLI.CLOSE
			   .DA SEL1.CloseP
				plp		 				restore status from read.
				bcs L5EED			  	if any errors.

				bit SEL1.OpenP+1
				bvc .8

				ldx SEL1.PathBuf
				
.7				lda SEL1.PathBuf,x
				sta $2006,x
				dex
				bpl .7

.8				jsr ROM.SETTXT		 	reset to full window.
				jsr ROM.HOME		 	makes for no flash.
				lda #$95			 	ctrl-u
				jsr ROM.COUT		 	turn off 80 columns.

				jmp $2000				execute selected system file.
*--------------------------------------
SEL1.PrintFN	lda #$0E
				.HS 2C					BIT ABS
SEL1.PrintFNInv	lda #$0F
				pha

				ldx SelectedIndex
				txa
				sec
				sbc ScrollIndex			calculate line # to display name
				inc
				inc
				jsr ROM.TABV			set vertical position.

				lda #$01
				sta ROM.OURCH

				lda SEL1.filetypes,x	get filetype (x is unchanged by ROM.TABV).
				jsr SEL1.CheckType
				bmi .1

				lda SEL1.ValidIcons,y
				tay
				jsr SEL1.IconOutY

.1  			jsr SEL1.SetFNPtrX		calc name location.

				lda #$05
				sta ROM.OURCH

				pla						normal / inverse
				jsr ROM.COUT

				jsr SEL1.SPOut			output a space.

				ldy #0

.2  			iny
				lda (FilenamePtr),y		get name character.
				jsr SEL1.COut		 	put on screen.
				tya
				cmp (FilenamePtr)		end of name ?
				bcc .2				  	no.

*.3				jsr SEL1.SPOut
*				iny
*				cpy #16
*				bne .3
				
				jsr SEL1.SPOut
				jmp ROM.SETNORM			set normal text mode.
*--------------------------------------
SEL1.SetFullPath
				jsr MLI
			   .DA #MLI.SETPREFIX
			   .DA SEL1.SetPrefixP
				bcs .9

				ldx SelectedIndex
				jsr SEL1.SetFNPtrX

				ldx SEL1.PathBuf	 	get prefix length.
				ldy #0

.1  			iny		 				start at y = 1.
				lda (FilenamePtr),y		get character of name.
				inx
				sta SEL1.PathBuf,x		store in prefix buffer.
				tya
				eor (FilenamePtr)		check length of name.
				bne .1				  	loop until all transferred.

				stx SEL1.PathBuf	 	put prefix length into buffer.

				inc bInSubDir

*				clc

.9				rts
*--------------------------------------
SEL1.FullPath..	ldx SEL1.PathBuf

.1  			dex
				lda SEL1.PathBuf,x
				cmp #'/'
				bne .1

				cpx #$01
				bne .9

				ldx SEL1.PathBuf

.9  			dec bInSubDir

				rts
*--------------------------------------
SEL1.SetFNPtr	ldx filecount
				
SEL1.SetFNPtrX	lda /SEL1.Filenames/16
				sta FilenamePtr+1
				txa

				ldx #4

.1				asl
				rol FilenamePtr+1
				dex
				bne .1

				sta FilenamePtr
				tay
				lda FilenamePtr+1
				
				rts
*--------------------------------------
SEL1.CheckType	ldy #SEL1.ValidTypes.L-1

.1				cmp SEL1.ValidTypes,y
				beq .8

				dey
				bpl .1

.8				rts
*--------------------------------------
SEL1.IconOutY	phx

				ldx #0

.1				lda SEL1.MouseText,x

				jsr ROM.COUT
				inx
				cpx #2
				bne .2

				jsr SEL1.MsgOutY

.2				cpx #4
				bcc .1

				plx
				rts
*--------------------------------------
SEL1.MsgOutY	lda SEL1.Strings,y
				php
				jsr SEL1.COut
				iny
				plp
				bpl SEL1.MsgOutY

.8  			rts
*--------------------------------------
SEL1.SPOut		lda #' '				SPACE

SEL1.COut		ora #$80			 	set high bit.
				jmp ROM.COUT		 	output to screen.
*--------------------------------------
* data area
*--------------------------------------
SEL1.BS			.AS	"BASIC.SYSTEM"
SEL1.BS.L		.EQ *-SEL1.BS
*--------------------------------------
SEL1.ValidTypes	.DA #S.FI.T.DIR
				.DA #S.FI.T.SYS
				.DA #S.FI.T.BIN
				.DA #S.FI.T.BAS
SEL1.ValidTypes.L	.EQ *-SEL1.ValidTypes
*--------------------------------------
SEL1.ValidIcons	.DA #SEL1.DirIcon-SEL1.Strings
				.DA #SEL1.SysIcon-SEL1.Strings
				.DA #SEL1.BinIcon-SEL1.Strings
				.DA #SEL1.BasIcon-SEL1.Strings
*--------------------------------------
SEL1.MouseText 	.HS 0F1B
				.HS 180E
*--------------------------------------
SEL1.Strings
*--------------------------------------
SEL1.Footer		.AT ":Select,TAB:Chg Vol,ESC:Back"
SEL1.DirIcon	.AT "XY"				"XYI"
SEL1.SysIcon	.AT "Z\^_"
SEL1.BinIcon	.AT "Z\\_"
SEL1.BasIcon	.AT "ZVW_"
SEL1.RetIcon	.AT "M"
*--------------------------------------
SEL1.OpenP		.DA #3				  	Param Count
				.DA SEL1.PathBuf		pathname
				.DA SEL1.FileBuf		file buffer
				.HS 01					reference number
*--------------------------------------
SEL1.CloseP		.DA #1			  		Param Count
				.HS 01					reference number
*--------------------------------------
SEL1.OnLineP	.DA #2					Param Count
				.HS 60					unit number, default = s6, d1
				.DA SEL1.PathBuf+1		data buffer
*--------------------------------------
SEL1.SetPrefixP	.DA #1		  			Param Count
				.DA SEL1.PathBuf		pathname
*--------------------------------------
SEL1.ReadP 		.DA #4			  		Param Count
				.HS 01					reference number
*--------------------------------------
				.EP
*--------------------------------------
*				.LIST ON
SEL1.LEN		.EQ *-SEL1.START
				.LIST OFF
*--------------------------------------
				.DUMMY
				.BS 2					MemPtr
				.BS 2					requested length
				.BS 2					read length
				.ED
*--------------------------------------
MAN
SAVE usr/src/prodos.fx/prodos.s.sel1
LOAD usr/src/prodos.fx/prodos.s
ASM
