*
*
* DPX - DRIVEPAK EXPLORER
* 2016-2020 GUILLAUME MAJOR (guillaume.major@gmail.com)
* BASED ON SIDEKICK BY LUIS ANTONIOSI (retrocanada76@gmail.com)
*

* Version information
VERSION		EQU		'1'
MAJOR		EQU		'1'
MINOR		EQU		'5'

* Flags
DEBUG		SET		0

* Masks
INTMASKS	EQU		%01010000

VIDRAM	 	EQU		$0400			; video RAM
CLRSCH		EQU		80				; clear screen character

KEYUP		EQU		$5E				; UP key
KEYDN		EQU		$0A				; DOWN key
KEYLT		EQU		$08				; LEFT key
KEYRT		EQU		$09				; RIGHT key

KEYSUP		EQU		$5F				; SHIFT-UP keys
KEYSDN		EQU		$5B				; SHIFT-DOWN keys
KEYSRT		EQU		$5D				; SHIFT-RIGHT keys
KEYSLT		EQU		$15				; SHIFT-LEFT keys

KEYESC		EQU		03				; BREAK key
KEYENT		EQU		13				; ENTER key
KEYCLR		EQU		12				; CLEAR key
KEYSPC		EQU		32				; SPACE key

DCOPC		EQU		$00EA			; DSKCON operation
DCDRV		EQU		$00EB			; DSKCON drive
DCTRK		EQU		$00EC			; DSKCON track
DCSEC		EQU		$00ED			; DSKCON sector
DCBPT		EQU		$00EE			; DSKCON buffer
DCSTA		EQU		$00F0			; DSKCON status

DPDSKCON	EQU		$EC08			; DrivePak Disk IO routine
DPREAD		EQU		$EC3A			; DrivePak Read Sector routine
DPWRITE		EQU		$EC9B			; DrivePak Write Sector routine

USD0		EQU		$014D			; DrivePak drive number

POLCAT		EQU		$A000			; read keyboard routine
DSKCON		EQU		$C004			; disk access routine

CURLIN		EQU		$0068			; current BASIC line number
CURPOS		EQU		$0088			; BASIC cursor position
GETNCH		EQU		$009F
CHARAD		EQU		$00A6
KEYBUF		EQU		$0152			; keyboard memory buffer

KEYDELAY1	EQU		20				; key repeat trigger delay
KEYDELAY2	EQU		5				; key repeat delay

CRUNCHLN	EQU		$B821
EXECCMD		EQU		$ADC0
EXECCMD2	EQU		EXECCMD+6
DIRTRACK	EQU		17				; directory track
DIRSECT		EQU		3				; first directory sector
DIRSECTMAX	EQU		11				; max directory sector
DIRENTSIZE	EQU		32				; directory entry size
BOOTTRACK	EQU		34				; boot track
BOOTSECT	EQU		1				; boot sector

ENTRYSIZE	EQU		16
MAXPARTSIZE	EQU		128
MAXPARTSEC	EQU		128

SCRWID		EQU		$20
SCRHEI		EQU		$10

WINHEI		EQU		(SCRHEI-5)
WINWID		EQU		(SCRWID/2-3)

			ORG		$3000

START		LDU		#USRSTK			; set user stack
			STS		SREG			; save system stack

			JSR		INIT

			LDA		#143+CLRSCH		; clear screen
			JSR		CLRSCR

			JSR		DETECTPAK		; detect Drive Pak
			JSR		LOADCFG			; load DXP configuration

			JSR		DREAD			; get selected drive directory


MAINLOOP	JSR		DRAWSCR			; draw screen
			LDA		KEYPRES			; key pressed?
			LBNE	HANDLEKEY		; yes - handle key

MAINLOOP02	JSR		READKEY			; read keyboard
			LBNE	HANDLEKEY

			LDX		KBUFTMR			; get keyboard buffer timer
			BEQ		MAINLOOP02		; loop if timer is zero

			LEAX	-1,X			; decrement keyboard buffer
			STX		KBUFTMR
			BNE		MAINLOOP02

			CLR		KBUFPOS			; clear keyboard buffer
			LDX		#KBUF
			LDD		#0
			STD		,X
			STD		2,X
			STD		4,X

			BRA		MAINLOOP02

**
*  INIT
**
INIT		CLR		CC3
			if		!TEST
			CLR		PARTSIZE
			endif
			CLR		PANEFOCUS
			CLR		KBUFPOS
			CLR		DRVSEL
			CLR		DRVOFF
			CLR		PARTSEL
			CLR		PARTOFF
			LDA		#255			; number of drives
			STA		DRVSIZE
			JSR		CLRVOLARR
			CLR		LASTDRV
			LDA		#$FF
			STA		LASTDIR

			LDD		$F702			; check for Coco 3 string in ROM
			CMPD	#$4D69			; string to check "T."
			BNE		INIT02

			INC		CC3				; set Coco 3 flag

INIT02		RTS

**
*  READKEY
**
READKEY		LDA		#$FF			; clear keyboard roll-over table
			LDB		#8				; 8 characters
			LDX		#KEYBUF			; load POLCAT keyboard buffer

READKEY02	STA		,X+				; store clearing value
			DECB					; decrement buffer counter
			BNE		READKEY02		; loop until done

			JSR		[POLCAT]		; read keyboard
			BNE		READKEY03		; branch if key pressed
			CLR		KEYSTA			; reset key state
			RTS						; exit returning 0 in ACCA

READKEY03	TST		KEYSTA			; test key state
			BNE		READKEY04		; branch if key holded
			INC		KEYSTA			; set key hold flag
			LDX		#KEYDELAY1		; load key repeat trigger delay
			STX		KEYTMR			; store
			RTS						; exit returning key pressed in ACCA

READKEY04	LDX		KEYTMR			; load repeating key timer
			LEAX	-1,X			; decrement
			STX		KEYTMR			; store
			BEQ		READKEY05		; branch if timer = 0
			CLRA					; cancel key press
			RTS						; exit returning 0 in ACCA

READKEY05	LDX		#KEYDELAY2		; load key repeat delay
			STX		KEYTMR			; store
			RTS

**
*  HANDLEKEY
**
HANDLEKEY	STA		KEYPRES			; save key press

			LDA		#$7F			; SHIFT key bit mask
			STA		$FF02			; write keyboard column
			LDA		$FF00			; read keyboard row
			COMA					; invert bits
			ANDA	#$40			; keep SHIFT key bit
			STA		SHIFTKEY		; save SHIFT key state

			LDA		KEYPRES			; restore key press

			CMPA	#KEYCLR			; CLEAR key
			BEQ		ISCLRKEY

			TST		SHIFTKEY		; test SHIFT key
			BEQ		NOSHIFTKEY		; branch if no SHIFT key

			CMPA	#'F'			; SHIFT-F keys
			BEQ		ISFKEY

			CMPA	#'S'			; SHIFT-S keys
			BEQ		ISSKEY

			CMPA	#'H'			; SHIFT-H keys
			BEQ		ISHKEY

			BRA		GOPANE

ISCLRKEY	JSR		BOOTPAK
			BRA		MAINEND

ISFKEY		JSR		FINDFILE
			BRA		MAINEND

ISSKEY		LDB		DIRSORT			; toggle dirsort value
			EORB	#1
			STB		DIRSORT
			BEQ		MAINEND			; DIRSORT > 0?
			LDB		DIRSIZE			; DIRIZE > 0?
			BEQ		MAINEND
			CLRA					; sort directory
			JSR		DSORT
			BRA		MAINEND

ISHKEY		JSR		HELP
			BRA		MAINEND

NOSHIFTKEY	CMPA	#KEYLT
			BEQ		ISLTKEY

			CMPA	#KEYRT
			BEQ		ISRTKEY

			BRA		GOPANE

ISLTKEY		TST		PANEFOCUS
			BNE		CHANGEFOCUS
			BRA		MAINEND

ISRTKEY		TST		PANEFOCUS
			BEQ		CHANGEFOCUS
			BRA		MAINEND

GOPANE		TST		PANEFOCUS
			BEQ		LEFTPANE
			BRA		RIGHTPANE

CHANGEFOCUS	TST		DIRSIZE
			BEQ		CHANGEF02
			LDA		PANEFOCUS
			COMA
			STA		PANEFOCUS
			CLR		KBUFPOS
CHANGEF02	BRA		MAINEND

LEFTPANE	JSR		DSKLISTKEY
			BRA		ISESCKEY

RIGHTPANE	JSR		DIRLISTKEY

ISESCKEY	LDA		KEYPRES
			CMPA	#KEYESC
			LBEQ	EXIT

MAINEND		LBRA	MAINLOOP

**
*  Load DPX configuration
**
LOADCFG
			if		TEST
			RTS						; exit if compiled in TEST mode
			endif

			LDB		#2				; read OP
			LDX		#0				; LSN0
			JSR		RWLSN			; read LSN0
			TSTB					; check status
			BNE		LOADCFG03		; exit on error

			LDX		#SECBUF+$80		; load last partition entry

			LDA		,X				; load partition type
			BEQ		LOADCFG03		; exit if zero
			CMPA	#2				; DOS partition?
			BNE		LOADCFG01		; no - skip

			LDY		#LASTPART		; load last partition string
			LDD		#16				; 16 characters
			JSR		MEMCPY			; copy

LOADCFG01	LDA		32,X			; load last drive selection
			STA		LASTDRV			; store

			LDA		,X				; load partition type
			CMPA	#2				; DOS partition?
			BNE		LOADCFG02		; no - skip

			LDA		33,X			; load last file selection
			STA		LASTDIR

			JSR		CHPART			; change partition

			LDA		LASTDRV
			STA		DRVSEL			; set drive selection
			JSR		SETDRVOFF		; set drive list offset

			BRA		LOADCFG03

LOADCFG02	LDA		LASTDRV
			STA		PARTSEL
			JSR		BOOTPAK			; run partition selection screen

LOADCFG03	RTS

**
*  Save DPX configuration
**
SAVECFG
			if		TEST
			RTS						; exit if compiled in TEST mode
			endif

			LDB		#2				; read OP
			LDX		#0				; LSN0
			JSR		RWLSN			; read LSN0
			TSTB					; check status
			BNE		SAVECFG04		; exit on error

			LDX		#LASTPART		; load last partition entry
			LDY		#SECBUF+$80		; load sector buffer
			LDD		#16				; 16 characters
			JSR		MEMCPY			; copy

			LDA		,X				; load partition type
			CMPA	#2				; DOS partition
			BNE		SAVECFG02		; no - skip

			LDA		DIRSEL			; load directory selection
			STA		33,Y			; save directory selection

			LDA		DRVSEL			; load drive selection
			BRA		SAVECFG03

SAVECFG02	LDA		PARTSEL			; load partition selection

SAVECFG03	STA		32,Y			; save drive/partition selection
			LDB		#3				; write OP
			LDX		#0				; LSN0
			JSR		RWLSN			; write LSN0

SAVECFG04	RTS

**
*  Read or write a sector on the SD card
*    B = OP (2 - read sector, 3 - write sector)
*    X = logical sector number
**
RWLSN		CLRA
			PSHS	U				; save user stack
			LDU		#SECBUF
			ORCC	#INTMASKS		; disable interrupts
			TST		CC3				; check if Coco 3
			BEQ		RWLSN02			; no? - skip
			CLR		$FFDE			; enable rom

RWLSN02		JSR		DPDSKCON		; read LSN0
			TST		CC3				; check if Coco 3
			BEQ		RWLSN03			; no? - skip
			CLR		$FFDF			; disable rom

RWLSN03		ANDCC	#~INTMASKS		; enable interrupts
			PULS	U				; restore user stack
			RTS

**
*  RETURN TO BASIC
**
EXIT		JSR		SAVECFG			; save DPX configuration

			LDX		#EXITCMD		; load exit command
			JMP		RUNBAS			; execute and return to BASIC

**
*  DRAW THE USER INTERFACE
**
DRAWSCR		JSR		DRAWBG			; draw background

			LDD		#$0102			; draw partition window
			LDX		#WINWID+2
			LDY		#WINHEI+2
			JSR		WINDOW

			LDX		#' '
			LDY		#WINWID+1
			LDD		#$0102
			JSR		PRINTSTR

			LDX		#LASTPART+1		; display partition name
			LDY		#STR1
			LDD		#8
			JSR		MEMCPY
			CLR		8,Y
			LDX		#STR1
			JSR		CENTER
			LDD		#$0402
			JSR		PRINTRASC

			LDD		#$1102			; draw disk directroy window
			LDX		#WINWID+2
			LDY		#WINHEI+2
			JSR		WINDOW

			LDX		#DIRLABEL		; display file directory title
			LDD		#$1102
			JSR		PRINTRASC

			JSR		CLRSTATUS		; clear status bar

			LDX		#HELPCMD		; display exit command
			LDD		#$130F
			JSR		PRINTRASC

			JSR		DRVLIST			; display drive list
			JSR		DIRLIST			; display disk directory list

			* IF DISK IS BOOTABLE AND NOT AN OS-9 DISK AND FOCUS IS ON
			* THE DISK BOX, DISPLAY A "PRESS ENTER TO BOOT" STATUS MESSAGE
			
			TST		BOOTABLE		; check if disk is bootable
			BEQ		DRAWSCR02		; no - exit
			TST		PANEFOCUS		; check is focus is on the disk box
			BNE		DRAWSCR02		; no - exit
			TST		OS9DSK			; check if disk is an OS-9 disk
			BNE		DRAWSCR02		; yes - exit
			LDX		#BOOTCMD		; display boot command
			BRA 	DRAWSCR03

DRAWSCR02	LDX		#PARTCMD		; display help command

DRAWSCR03	LDD		#$010F			; update status bar
			JSR		PRINTRASC

			TST		DIRSORT			; check if disk directory is sorted
			BEQ		DRAWSCR04		; no - exit
			LDX		#SORTEDLBL		; display up arrow on the window title
			LDD		#$1D02
			JSR		PRINTRASC

DRAWSCR04	JSR		FLUSHSCR		; update screen
			RTS

**
*  DRAW UI BACKGROUND
**
DRAWBG		LDA		#143+CLRSCH
			JSR		CLRSCR

			LDX		#PRGTITLE
			CLRA
			CLRB
			JSR		PRINTRASC

			RTS

**
*  COPY SCREEN BUFFER TO VIDEO MEMORY
**
FLUSHSCR	PSHU	X,Y,A,B,CC
			LDD		#32*16
			LDX		#SCRBUF
			LDY		#VIDRAM
			JSR		MEMCPY
			PULU	X,Y,A,B,CC
			RTS

**
*  DISPLAY DRIVE LIST DIRECTORY
**
DRVLIST		CLR		KEYPRES
			LDB		DRVSIZE
			SUBB	DRVOFF
			CMPB	#WINHEI
			BLO		DRVLIST02
			LDB		#WINHEI-1
DRVLIST02	INCB
			CLRA
			TFR		D,Y				; NUM REM DRIVES

			LDB		#3
			STB		CURLINE			; START LINE

			LDB		DRVOFF
			CLRA
			STD		CURDRV			; CURR DRIVE

DRVLIST03	TST		KEYPRES
			BNE		DRVLIST04
			JSR		[POLCAT]		; read keyboard
			STA		KEYPRES			; store key pressed

DRVLIST04	LDX		#STR1
			LDA		#' '
			LDB		#14

DRVLIST05	STA		B,X
			DECB
			BNE		DRVLIST05

			LDD		CURDRV
			JSR		ITOA16

			LDA		#' '
			STA		1,X
			STA		5,X

			PSHU	X,Y,B

			LDA		CURDRV+1		; load current drive number
			TST		KEYPRES			; key pressed?
			BNE		DRVLIST06		; yes - skip read
			JSR		READVOL			; read drive volume
			BRA		DRVLIST07

DRVLIST06	JSR		GETVOL

DRVLIST07	LDA		,X				; load first character
			BEQ		DRVLIST08		; no volume flag? - skip

			LDD		#8				; 8 characters
			LDY		#STR1+6
			JSR		MEMCPY

DRVLIST08	PULU	X,Y,B

			CLRA
			STA		15,X

			CMPB	DRVSEL
			BEQ		DRVLIST09

			LDB		CURLINE			; CURR LINE
			LDA		#1
			LEAX	1,X
			JSR		PRINTASC
			BRA		DRVLIST10

DRVLIST09	LDB		CURLINE			; CURR LINE
			LDA		#1
			LEAX	1,X
			JSR		PRINTRASC

DRVLIST10	LDX		CURDRV
			LEAX	1,X
			STX		CURDRV
			LDB		CURLINE
			INCB
			STB		CURLINE

			LEAY	-1,Y
			BNE		DRVLIST03

			RTS

**
*  DISPLAY SELECTED DISK DIRECTORY
**
DIRLIST		TST		DSKERR
			BNE		DIRLISTERR

			TST		OS9DSK
			BNE		DIROS9DSK

			LDB		DIRSIZE
			BEQ		DIRLISTEND
			SUBB	DIROFF
			CMPB	#WINHEI
			BLO		DIRLIST01
			LDB		#WINHEI

DIRLIST01	LDY		#0
			LEAY	B,Y

			LDB		#3
			STB		CURLINE			; start line

			LDB		DIROFF
			JSR		GETDIRADR

DIRLIST02	PSHU	X,Y

			TFR		X,Y
			LDX		#STR1			; get filename
			JSR		FORMATDFN

			LDA		#SCRWID/2+1
			TST		PANEFOCUS		; check if disk directory list has focus
			BEQ		DIRLIST03

			LDB		CURLINE
			SUBB	#3
			ADDB	DIROFF
			CMPB	DIRSEL
			BEQ		DIRLIST04

DIRLIST03	LDB		CURLINE			; load current line
			JSR		PRINTASC		; print standard text
			BRA		DIRLIST05

DIRLIST04	LDB		CURLINE			; load current line
			JSR		PRINTRASC		; print reversed text

DIRLIST05	PULU	X,Y

			LEAX	16,X			; next file
			INC		CURLINE
			LEAY	-1,Y
			BNE		DIRLIST02

DIRLISTEND	RTS

DIRLISTERR	LDB		#4
			LDA		#SCRWID/2+2
			LDX		#DSKERRMSG
			JSR		PRINTASC

			RTS

DIROS9DSK	LDB		#4
			LDA		#SCRWID/2+3
			LDX		#OS9DSKMSG
			JSR		PRINTASC

			TST		BOOTABLE
			BEQ		DIROS9END

			LDB		#6
			LDA		#SCRWID/2+2
			LDX		#OS9BOOTMSG
			JSR		PRINTASC

			LDB		#7
			LDA		#SCRWID/2+4
			LDX		#OS9BOOTMSG2
			JSR		PRINTASC

DIROS9END	RTS

**
*  HANDLE SDC DIRECTORY KEY
**
DSKLISTKEY	LDA		KEYPRES

			CMPA	#KEYUP			; UP key
			BEQ		ISUPKEY

			CMPA	#KEYDN			; DOWN key
			BEQ		ISDNKEY

			CMPA	#KEYSDN			; SHIFT-DOWN keys
			BEQ		ISSDNKEY

			CMPA	#KEYSUP			; SHIFT-UP keys
			BEQ		ISSUPKEY						

			CMPA	#KEYSLT			; SHIFT-LEFT keys
			BEQ		ISSLTKEY

			CMPA	#KEYSRT			; SHIFT-RIGHT keys
			BEQ		ISSRTKEY

			CMPA	#KEYENT			; ENTER key
			BEQ		ISENTKEY

			LBRA	ISNUMBER

ISUPKEY		LDB		DRVSEL
			LBEQ	READEND
			DECB
			STB		DRVSEL

			LDB		DRVOFF
			CMPB	DRVSEL
			LBLS	DREAD

			DECB
			STB		DRVOFF

			JMP		DREAD

ISDNKEY		LDB		DRVSEL
			CMPB	DRVSIZE
			LBEQ	READEND

			INCB
			STB		DRVSEL

			SUBB	DRVOFF
			CMPB	#WINHEI
			LBLO	DREAD
			INC 	DRVOFF

			JMP		DREAD

ISSDNKEY	LDB		DRVSEL
			ADDB	#WINHEI-1
			BCS		ISSDNKEY02
			CMPB	DRVSIZE
			BLO		ISSDNKEY03

ISSDNKEY02	LDB		DRVSIZE

ISSDNKEY03	STB		DRVSEL
			JSR		SETDRVOFF
			JMP		DREAD

ISSUPKEY	LDB		DRVSEL
			CMPB	#WINHEI-1
			BCC		ISSUPKEY02
			LDB		#WINHEI-1

ISSUPKEY02	SUBB	#WINHEI-1
			STB		DRVSEL
			STB		DRVOFF

			JMP		DREAD

ISSLTKEY	LDB		#0
			STB		DRVSEL
			STB		DRVOFF

			JMP		DREAD

ISSRTKEY	LDB		DRVSIZE
			STB		DRVSEL
			JSR		SETDRVOFF

			JMP		DREAD

ISENTKEY	TST		BOOTABLE		; check if disk is bootable
			LBNE	BOOTDSK			; yes - boot disk
			JMP		READEND

ISNUMBER	CMPA	#'0'
			BLO		READEND
			CMPA	#'9'
			BHI		READEND			
			SUBA	#'0'
			LDX		#KBUF

			LDB		1,X
			STB		,X+
			LDB		1,X
			STB		,X+
			STA		,X

			LDD		KBUFDELAY		; keyboard delay
			STD		KBUFTMR

			LDX		#KBUF
			LDA		#10
			LDB		,X+
			MUL
			STB		DRVSEL

			LDA		#10
			LDB		,X+
			ADDB	DRVSEL
			MUL
			STB		DRVSEL

			LDB		,X+
			ADDB	DRVSEL
			STB		DRVSEL

			LDA		DRVSIZE
			SUBA	DRVSEL
			BCC		ISNUMBER02
			LDB		DRVSIZE
			STB		DRVSEL

ISNUMBER02	LDB		DRVSEL
			JSR		SETDRVOFF

DREAD		LDB		DRVSIZE
			BEQ		READEND

			JSR		READDIR

			* SORT DIRECTORY
			TST		DIRSORT
			BEQ		READEND
			LDB		DIRSIZE			; DIRSIZE > 0?
			BEQ		READEND
			CLRA
			JSR		DSORT

READEND		RTS

**
*  SET DRV OFFSET
**
SETDRVOFF	LDB		DRVSIZE
			SUBB	DRVSEL
			CMPB	#WINHEI-1
			BCC		SETDSK02

SETDSK01	LDB		DRVSIZE
			SUBB	#WINHEI-1
			BCS		SETDSK03

			STB		DRVOFF
			RTS

SETDSK02	LDB		DRVSEL
			CMPB	#WINHEI-1
			STB		DRVOFF
			RTS

SETDSK03	LDB		#0
			STB		DRVOFF
			RTS

**
*  HANDLE DISK DIRECTORY LIST KEY
**
DIRLISTKEY	LDA		KEYPRES

			CMPA	#KEYUP			; UP key
			BEQ		#DISUPKEY

			CMPA	#KEYDN			; DOWN key
			BEQ		DISDNKEY

			CMPA	#KEYSDN			; SHIFT-DOWN keys
			BEQ		DISSDNKEY

			CMPA	#KEYSUP			; SHIFT-UP keys
			LBEQ	DISSUPKEY

			CMPA	#KEYSLT			; SHIFT-LEFT keys
			LBEQ	DISSLTKEY			

			CMPA	#KEYSRT			; SHIFT-RIGHT keys
			LBEQ	DISSRTKEY			

			CMPA	#KEYENT
			LBEQ	DISENTKEY		; ENTER key

			CMPA	#'A'			; A-Z keys
			BLO		DISNUM
			CMPA	#'Z'
			LBHI	DREADEND

			LBRA	DISALPHA

DISNUM		CMPA	#'0'			; 0-9 keys
			LBLO	DREADEND
			CMPA	#'9'
			LBHI	DREADEND

			LBRA	DISALPHA

DISUPKEY	LDB		DIRSEL
			LBEQ	DREADEND
			DECB
			STB		DIRSEL

			LDA		DIROFF
			CMPA	DIRSEL
			LBLS	DREADEND

			DECA
			STA		DIROFF

			JMP		DREADEND

DISDNKEY	LDB		DIRSEL
			INCB	
			CMPB	DIRSIZE
			LBEQ	DREADEND

			STB		DIRSEL

			SUBB	DIROFF
			CMPB	#WINHEI
			LBLO	DREADEND
			LDA		DIROFF
			INCA
			STA		DIROFF

			JMP		DREADEND

DISSDNKEY	LDB		DIRSIZE
			SUBB	DIRSEL
			CMPB	#WINHEI
			BCC		DISSDBKEY2

			LDB		DIRSIZE
			DECB
			BRA		DISSDBKEY3

DISSDBKEY2	LDB		DIRSEL
			ADDB	#WINHEI-1

DISSDBKEY3	STB		DIRSEL
			JSR		SETDIROFF
			JMP		READEND	

DISSUPKEY	LDB		DIRSEL
			CMPB	#WINHEI-1
			BCC		DISSUPKEY2
			LDB		#WINHEI-1

DISSUPKEY2	SUBB	#WINHEI-1
			STB		DIRSEL
			STB		DIROFF
			JMP		DREADEND

DISSLTKEY	CLR		DIRSEL
			CLR		DIROFF

			JMP		DREADEND

DISSRTKEY	LDB		DIRSIZE
			DECB
			STB		DIRSEL
			JSR		SETDIROFF

			JMP		DREADEND

DISALPHA	LDB		KBUFPOS			; load number of characters in buffer
			CMPB	#4				; max 4 chars
			LBEQ	DREADEND		; exit if buffer is full

			LDX		#KBUF			; load keyboard buffer			
			CMPA	,X				; compare key with first character in buffer
			BNE		DISALPHA02		; branch if key is different
			CMPB	#1				; check if this is the only character in the buffer
			BEQ		DISALPHA03		; yes - don't add it to the buffer

DISALPHA02	STA		B,X				; store character in buffer
			INCB					; increment number of characters in buffer
			STB		KBUFPOS			; save it

DISALPHA03	LDA		DIRSEL
			CMPB	#1
			BNE		DISALPHA04

			INCA
			CMPA	DIRSIZE			; end of list?
			BNE		DISALPHA04
			CLRA

DISALPHA04	STA		KEYSRCH

			LDD		KBUFDELAY		; keyboard delay
			STD		KBUFTMR
			CLR		SRCHPASS
			
			LDB		KEYSRCH			; get dir entry address
			JSR		GETDIRADR		; dir entry adr in x
			LDY		#KBUF

DISALPHA05	LDB		KBUFPOS
			JSR		STRNCMP			; compare buffer with dir entry
			BEQ		DISALPHA07		; match?

			LDA		KEYSRCH			; next entry
			INCA
			CMPA	DIRSIZE
			BEQ		DISALPHA06		; end of list?

			STA		KEYSRCH
			LEAX	16,X
			BRA		DISALPHA05

DISALPHA06	TST		SRCHPASS
			BNE		DREADEND		; second pass, we're done

			LDA		#1				; start from beginning
			STA		SRCHPASS
			CLR		KEYSRCH
			LDX		#DIRARR
			BRA		DISALPHA05

DISALPHA07	LDA		KEYSRCH
			STA		DIRSEL
			JSR		SETDIROFF
			BRA		DREADEND

DISENTKEY	LDB		DIRSEL			; load selected file
			JSR		GETDIRADR		; get selected file address

			LDA		13,X			; check file type
			BNE		ISLM			; branch if not BASIC

			PSHU	X				; save selected file address

			JSR		SAVECFG			; save configuration
			JSR		LOADSCR			; display loading screen

			LDY		#STR1			; load string buffer
			CLR		,Y				; terminate string

			LDX		#RUNCMD			; load RUN command
			JSR		STRCAT			; append command text

			PULU	X				; restore selected file address
			JSR		STRCAT			; append filename

			LDX		#RUNCMD2		; load RUN command #2
			JSR		STRCAT			; append command text

			BRA		RUN07			; go execute command

ISLM		CMPA	#2				; machine language?
			BNE		DREADEND		; no - exit

			PSHU	X				; save selected file address

			JSR		SAVECFG			; save configuration
			JSR		LOADSCR			; display loading screen

			LDY		#STR1			; load string buffer
			CLR		,Y				; terminate string

			LDX		#RUNMCMD		; load LOADM/EXEC command
			JSR		STRCAT			; append command text

			PULU	X				; restore selected file address
			JSR		STRCAT			; append filename

			LDX		#RUNMCMD2		; load LOADM/EXEC command #2
			JSR		STRCAT			; append command text

RUN07		LDX		#STR1			; load BASIC command
			JMP		RUNBAS			; execute command

DREADEND	RTS

**
*  EXECUTE BASIC COMMAND AND EXIT TO BASIC
*    X=COMMAND
**
RUNBAS		LDS		SREG			; restore system stack
			STX		CHARAD			; set BASIC current execution address
			JSR		CRUNCHLN		; crunch BASIC line
			LDX		#$FFFF			; direct mode value
			STX		CURLIN			; set direct mode
			LDX		#VIDRAM			; load video RAM address
			STX		CURPOS			; set cursor location
			JMP		EXECCMD			; execute BASIC command

**
*  EXECUTE BASIC COMMAND
*    X=COMMAND
**
RUNBAS2		PSHS	U,X,CC			; save registers
			STX		CHARAD			; set BASIC current execution address
			JSR		CRUNCHLN		; crunch BASIC line
RUNBAS2B	JSR		GETNCH			; get next BASIC character
			JSR		EXECCMD2		; execute command
			BNE		RUNBAS2B		; loop until done
			PULS	U,X,CC			; restore registers
			RTS
			
**
*  SET DIRECTORY OFFSET
**		
SETDIROFF	LDA		DIRSIZE
			SUBA	DIRSEL
			CMPA	#WINHEI
			BCC		SETDIR02

			LDA		DIRSIZE
			SUBA	#WINHEI
			BCS		SETDIR03

			STA		DIROFF
			RTS

SETDIR02	LDA		DIRSEL
			STA		DIROFF
			RTS

SETDIR03	CLRA
			STA		DIROFF
			RTS

**
*  READ SELECT DISK DIRECTORY
*  EXIT: 
*    CC set on error
**
READDIR		CLR		DIRSIZE
			CLR		DIRSEL
			CLR		DIROFF
			CLR		OS9DSK
			CLR		BOOTABLE
			CLR		DSKERR

			CLRA
			STA		DCDRV			; drive 0

			LDA		DRVSEL			; load current drive
			STA		USD0			; set DrivePak drive number

			* READ BOOT SECTOR
			LDA		#BOOTTRACK
			LDB		#BOOTSECT
			JSR		READSECT		; disk buffer address returned in x
			BCS		ISOS9DSK		; skip boot check on error

			* CHECK IF DISK IS BOOTABLE
			LDD		,X
			CMPD	#$4F53			; OS
			BNE		ISOS9DSK

			* DISK IS BOOTABLE
			LDA		#1
			STA		BOOTABLE

			* CHECK IF OS-9 DISK

ISOS9DSK	LDD		#$0001			; track 0 sector 1
			JSR		READSECT		; disk buffer address returned in x
			BCS		READDIR02		; skip OS-9 detection on error

			LDD		,X				; number of sectors (DD.TOT)
			CMPD	#$0800			; 128MB
			BHI		READDIR02
			LDA		3,X				; track size in sectors (DD.TKS)
			CMPA	#$12			; 18 sectors
			BNE		READDIR02
			LDD		$11,X			; number of sectors per track (DD.SPT)
			CMPD	#$0012			; 18 sectors
			BNE		READDIR02

			* IT IS AN OS-9 DISK
			LDA		#1
			STA		OS9DSK
			BRA		READDIR05

READDIR02	LDY		#DIRARR
			JSR		FINDFIRST
			BCS		RDIRERR

			LDA		,X				; check for deleted entry
			BEQ		READDIR04		; yes - find next file

			CMPA	#$FF			; check of end of directory
			BEQ		READDIR05		; yes - exit

READDIR03	LDD		#8				; copy filename
			JSR		MEMCPY
			LEAY	D,Y
			LEAX	D,X
			LDB		#'.'			; insert dot
			STB		,Y+
			LDB		#3				; copy extension
			JSR		MEMCPY
			LEAY	3,Y
			CLRB
			STB		,Y+

			LDA		3,X				; get file type
			STA		,Y

			LEAY	(16-13),Y		; point to next file

			INC		DIRSIZE

READDIR04	JSR		FINDNEXT		; find next file
			BCS		RDIRERR

			LDA		,X				; load first character
			BEQ		READDIR04		; find next file if deleted entry

			CMPA	#$FF			; end of directory?
			BNE		READDIR03		; no - loop

READDIR05	TST		DIRSIZE			; at least one file found?
			BEQ		READDIR06		; no - exit
			LDA		LASTDIR			; load last directory index
			CMPA	#$FF			; no index value?
			BEQ		READDIR06		; yes - skip
			STA		DIRSEL			; set directory index
			JSR		SETDIROFF		; set directory offset
			LDA		#$FF			; load no index value
			STA		LASTDIR			; store
			LDA		PANEFOCUS		; focus directory window
			COMA
			STA		PANEFOCUS

READDIR06	ANDCC	#$FE			; clear carrry
			RTS

RDIRERR		LDA		#1
			STA		DSKERR
			RTS

**
*  FIND FIRST DIRECTORY ENTRY
**
FINDFIRST	PSHU	Y,A,B

			CLR		SECPOS
			LDA		#DIRTRACK
			LDB		#DIRSECT
			STB		CURSEC
			JSR		READSECT

			PULU	Y,A,B
			RTS

**
*  FIND NEXT DIRECTORY ENTRY
**
FINDNEXT	PSHU	Y,A,B
			LDB		SECPOS
			CMPB	#$FF-DIRENTSIZE-(256%DIRENTSIZE)
			BLO		_NEXT

			CLR		SECPOS
			LDB		CURSEC
			CMPB	#DIRSECTMAX
			BLO		_NEXTSEC

			ORCC	#1
			PULU	Y,A,B
			RTS

_NEXTSEC	LDA		#DIRTRACK
			INCB					; increment sector
			STB		CURSEC
			JSR		READSECT

			PULU	Y,A,B
			RTS

_NEXT		ADDB	#DIRENTSIZE
			STB		SECPOS
			LDX		#SECBUF
			CLRA
			LEAX	D,X
			ANDCC	#$FE
			PULU	Y,A,B
			RTS

**
*  READ A DISK SECTOR
*    A = TRACK NUMBER
*    B = SECTOR NUMBER
*  EXIT:
*    B = STATUS CODE
*    X = SECTOR BUFFER
**
READSECT	STA		DCTRK			; track number
			STB		DCSEC			; sector number

READSECT02	LDX		#SECBUF
			STX		DCBPT

READSECT03	LDA		#2				; read sector
			STA		DCOPC
			JSR		[DSKCON]
			LDA		DCSTA
			BNE		READERR
			ANDCC	#$FE			; clear CC
			
READSECT04	LDX		#SECBUF			; load sector buffer
			RTS

READERR		ORCC	#1
			BRA		READSECT04

**
*  BOOT THE SELECTED DISK
**
BOOTDSK		LDD		DRVSIZE			; check if a disk is selected
			BEQ		BOOTEND			; no - exit

			LDX		#DOSCMD			; load boot command
			JMP		RUNBAS			; execute

BOOTEND		RTS

**
*  FIND FILE
**
FINDFILE	LDX		#FILESRCH		; copy FILESRCH to FILENAME
			LDY		#FILENAME
			CLR		,Y
			JSR		STRCAT

			LDX		#SEARCHLBL
			JSR		TEXTBOXWIN
			LBCS	INPUTEND

			LDX		#FILENAME		; copy FILENAME to FILESRCH
			LDY		#FILESRCH
			CLR		,Y
			JSR		STRCAT

			LDX		#PATTERN
			LDY		#NORMAL
			CLR		NORMAL
			JSR		STRCAT

			LDX		#FILESRCH
			LDY		#NORMAL
			LDB		#8
NORMNAME	LDA		,X+
			TSTA
			BEQ		NORMEND
			CMPA	#'.'
			BEQ		NORMEXT
			CMPA	#'/'
			BEQ		NORMEXT
			STA		,Y+
			DECB
			BNE		NORMNAME
NORMEXT		LDY		#NORMAL+9
NORMEXT2	LDA		,X+
			TSTA
			BEQ		NORMEND
			CMPA	#'.'
			BEQ		NORMEXT2
			CMPA	#'/'
			BEQ		NORMEXT2
			STA		,Y+
			BRA		NORMEXT2
NORMEND		CLR		,Y

ISBEGIN		TST		RESETSRC
			BEQ		ISBEGIN2

			CLRB
			STB		DRVSEL
			BRA		BEGINSRC

ISBEGIN2	LDB		DRVSEL
			CMPB	SRCDRV
			BEQ		NEXTITEM
			
BEGINSRC	STB		SRCDRV
			CLRA
			LDX		#SEARCHDRV
			JSR		ITOA8
			LDA		#' '
			STA		SEARCHDRV+3
			LDX		#SEARCHSTAT
			LDD		#$000F
			JSR		PRINTRASC
			JSR		FLUSHSCR

			JSR		READDIR
			JMP		FIRSTITEM

NEXTITEM	JSR		[POLCAT]
			BEQ		GETITEM
			CMPA	#KEYESC
			BEQ		SRCEND

GETITEM		LDA		DIRSEL
			INCA
			STA		DIRSEL

FIRSTITEM	LDA		DIRSEL
			CMPA	DIRSIZE
			BHS		NEXTDRV
			STA		DIRSEL

			CLR		RESETSRC

			LDB		#16
			MUL
			LDY		#DIRARR
			LEAY	D,Y
			LDX		#NORMAL
			JSR		STRSTR
			BCC		NEXTITEM

FILEFOUND	LDA		DIRSEL
			JSR		SETDIROFF

			LDA		DRVSEL
			JSR		SETDRVOFF

			LDA		#$FF
			STA		PANEFOCUS

			JMP		INPUTEND

NEXTDRV		LDA		SRCDRV
			CMPA	DRVSIZE
			BHS		SRCEND
			INCA
			STA		DRVSEL
			STA		SRCDRV

			LDX		#SEARCHDRV
			LDB		DRVSEL
			CLRA
			JSR		ITOA8
			LDA		#' '
			STA		SEARCHDRV+3
			LDX		#SEARCHSTAT
			LDD		#$000F
			JSR		PRINTRASC
			JSR		FLUSHSCR

			JSR		READDIR
			JMP		FIRSTITEM

SRCEND		CLR		DRVSEL
			CLR		DRVOFF
			CLR		DIRSEL
			CLR		DIROFF
			CLR		PANEFOCUS
			LDA		#1
			STA		RESETSRC
			CLR		SRCDRV

			JSR		READDIR
			JMP		INPUTEND

INPUTEND	RTS

**
* 
**
STRSTR		PSHU	X,Y,A,B

SRCINI		PSHU	X
SCRNEXT		LDA		,X+
			TSTA
			BEQ		SRCFOUND
			CMPA	#'/'
			BNE		NOTSLASH
			LDA		#'.'
NOTSLASH	TST		,Y
			BEQ		SRCNF		
			CMPA	,Y+
			BEQ		SCRNEXT
			PULU	X
			JMP		SRCINI

SRCNF		ANDCC	#$FE
			PULU	X
			PULU	X,Y,A,B
			RTS

SRCFOUND	ORCC	#1
			PULU	X
			PULU	X,Y,A,B
			RTS

**
*  TEXTBOX WINDOW
*    X = WINDOW TITLE
*  EXIT:
*    X = TEXT ENTERED
*    Carry set on cancel
**
TEXTBOXWIN	LDD		#$0806
			JSR		PRINTRASC

TEXTBOX01	LDD		#$0807
			LDX		#16
			LDY		#4
			JSR		WINDOW

			LDD		#$0908
			LDX		#FILENAME
			JSR		PRINTASC

			LDY		#0
			LDX		#FILENAME
COUNTLEN	LDA		,X+
			LEAY	1,Y
			TSTA
			BNE		COUNTLEN
			LEAX	-1,X
			STX		INPUTPOS
			LEAY	$08,Y
			TFR		Y,D
			TFR		B,A
			LDB		#$08
			LDX		#CURSTR
			JSR		PRINTRASC

			JSR		FLUSHSCR

INPUTKEY2	JSR		[POLCAT]
			BEQ		INPUTKEY2
			CMPA	#KEYESC
			LBEQ	INPUTCANC

			CMPA	#KEYSLT
			BNE		NOSLEFT

			* SHIFT LEFT
			LDX		#FILENAME
			CLR		,X
			STX		INPUTPOS
			
			LDA		#1
			STA		RESETSRC
			
			JMP		NEXTINPUT2

NOSLEFT		CMPA	#KEYLT
			BNE		NOLEFT2

			LDD		#FILENAME
			SUBB	INPUTPOS+1
			SBCA	INPUTPOS
			BEQ		NOLEFT2

			LDX		INPUTPOS
			CLR		-1,X
			
			LDA		#1
			STA		RESETSRC
			
			JMP		NEXTINPUT2
			
NOLEFT2		CMPA	#KEYENT
			BNE		NOENTER2

			* ENTER KEY

			LDD		INPUTPOS		; erase cursor
			SUBD	#FILENAME
			ADDB	#9
			TFR		B,A
			LDB		#$08
			LDX		#CURSTR
			JSR		PRINTASC

			JSR		FLUSHSCR

			LDX		#FILENAME
			CLRB					; clear cc

			JMP		INPUTEND2

NOENTER2	CMPA	#' '
			BLO		NEXTINPUT2
			CMPA	#'_'
			BHI		NEXTINPUT2

			LDX		#INVCHARS
CHKINV		TST		,X
			BEQ		NOENTER3		; char is valid
			CMPA	,X+
			BEQ		NEXTINPUT2		; char is invalid
			BRA		CHKINV

NOENTER3	STA		KEYPRES
			LDD		INPUTPOS
			SUBD	#FILENAME
			CMPB	#8
			BCC		NEXTINPUT2

			LDX		INPUTPOS
			LDA		KEYPRES
			STA		,X+
			CLR		,X
			
			LDA		#1
			STA		RESETSRC

NEXTINPUT2	JMP		TEXTBOX01
INPUTEND2	LEAU	1,U
			RTS

INPUTCANC	ORCC	#1
			BRA		INPUTEND2

**
*  COPY MEMORY
**
MEMCPY		PSHU	X,Y,A,B,CC
			ANDCC	#$AF
			STU		STACKPTR
			TFR		Y,U
			TFR		D,Y
MCLOOP		LDA		,X+
			STA		,U+
			LEAY	-1,Y
			BNE		MCLOOP
			LDU		STACKPTR
			PULU	X,Y,A,B,CC
			RTS

**
*  CLEAR THE SCREEN BUFFER
*    A=CHAR
**
CLRSCR		LDX		#SCRBUF
			LDY		#512
CLS001		STA		,X+
			LEAY	-1,Y
			BNE		CLS001
			CLR		CURPOS
			CLR		CURPOS+1
			RTS

**
*  PRINT ASCII 
*    X=STRING
*    A=COL
*    B=ROW
**
PRINTASC	PSHU	X,Y,A,B,CC
			PSHU	A
			LDA		#32
			MUL
			LDY		#SCRBUF
			LEAY	D,Y
			PULU	A
			LEAY	A,Y
PRAS000		LDA		,X+
			BEQ		PRAS999
			BMI		PRAS002			; semigraphic char
			CMPA	#64
			BGE		PRAS001
			ADDA	#64
			BRA		PRAS002
PRAS001		CMPA	#96
			BLT		PRAS002
			SUBA	#96
PRAS002		STA		,Y+
			BRA		PRAS000
PRAS999		PULU	X,Y,A,B,CC
			RTS

**
*  PRINT REVERSE ASCII
*    X=STRING
*    A=COL
*    B=ROW
**
PRINTRASC	PSHU	X,Y,A,B,CC
			PSHU	A
			LDA		#32
			MUL
			LDY		#SCRBUF
			LEAY	D,Y
			PULU	A
			LEAY	A,Y
PRRA000		LDA		,X+
			BEQ		PRRA999
			BMI		PRRA003			; semi graphic char
			CMPA	#64
			BGE		PRRA001
			BRA		PRRA004
PRRA001		CMPA	#96
			BLT		PRRA002
			SUBA	#96
			BRA		PRRA004
PRRA002		SUBA	#64
			BRA		PRRA004
PRRA003		EORA	#$7F			; invert bits except bit 7
PRRA004		STA		,Y+
			BRA		PRRA000
PRRA999		PULU	X,Y,A,B,CC
			RTS

**
*  CENTER TEXT
*    X=TEXT
**
CENTER 		STX		TMP				; save X

CENTER02	LDA		,X+				; find end of string
			BNE		CENTER02

			LEAX	-1,X			; go back one character
			CLRB					; clear number of spaces

CENTER03	LDA		,-X				; find last non space character
			CMPA	#' '			; is it a space?
			BNE		CENTER04		; no - skip
			INCB					; increment number of spaces
			BRA		CENTER03		; loop

CENTER04	LSRB					; divide B by 2
			TSTB					; test number of characters to shift
			BEQ		CENTER06		; zero - quit

CENTER05	LDA		,X				; load character
			STA		B,X				; store in new position
			LDA		#' '			; load space
			STA		,X				; store in old position
			LEAX	-1,X			; decrement address
			CMPX	TMP				; compare with start address
			BHS		CENTER05		; done? no - loop

CENTER06	LDX		TMP				; restore X
			RTS

**
*  PRINT STRING
*    X=CHAR
*    Y=COUNT
*    A=COL
*    B=ROW
**
PRINTSTR	PSHU	Y,X,A
			LDA		#32
			MUL
			LDY		#SCRBUF
			LEAY	D,Y
			PULU	A
			LEAY	A,Y				; Y set to screen buffer

			LDB		1,U				; get char
			LDA		3,U				; get count
			LEAU	4,U				; adjust stack
			
PRINTS01	BEQ		PRINTS02
			STB		,Y+
			DECA
			BRA		PRINTS01
			
PRINTS02	RTS

**
*  DRAW WINDOW 
*    A=COL
*    B=ROW
*    X=WIDTH
*    Y=HEIGHT
**
WINDOW		PSHU 	X,Y,A,B,CC
			PSHU	A
			LEAX	-1,X
			STX		WWID
			LEAY	-2,Y
			STY		WHEI
			LDA		#32
			MUL
			LDY		#SCRBUF
			LEAY	D,Y
			PULU	A
			LEAY	A,Y
			STY		WADDR
			LDA		#96
WND001		STA		,Y+
			LEAX	-1,X
			BNE		WND001
			LDA		#141+CLRSCH
			STA		,Y+

			LDY		WHEI
			BLE		WND004

WND002		LDY		WADDR
			LEAY	32,Y
			STY		WADDR

			LDX		WWID
			LDA		#96
WND003		STA		,Y+
			LEAX	-1,X
			BNE		WND003

			LDA		#133+CLRSCH
			STA		,Y+

WND004		LDX		WHEI
			LEAX	-1,X
			STX		WHEI
			BGT		WND002

			LDY		WADDR
			LEAY	32,Y
			LDA		#139+CLRSCH
			STA		,Y+
			LDX		WWID
			LDA		#131+CLRSCH
			LEAX	-1,X
WND005		STA		,Y+
			LEAX	-1,X
			BNE		WND005
			LDA		#135+CLRSCH
			STA		,Y+
			PULU	X,Y,A,B,CC
			RTS
WWID		FDB		0
WHEI		FDB		0
WADDR		FDB		0

**
*  CLEAR RECTANGLE
*    A=COL
*    B=ROW
*    X=WIDTH
*    Y=HEIGHT
**
CLEAR		PSHU 	X,Y,A,B,CC
			PSHU	A
			STX		WWID
			LEAY	-1,Y
			STY		WHEI
			LDA		#32
			MUL
			LDY		#SCRBUF
			LEAY	D,Y
			PULU	A
			LEAY	A,Y
			STY		WADDR
			LDA		#96
CLEAR01		STA		,Y+
			LEAX	-1,X
			BNE		CLEAR01

CLEAR02		LDY		WADDR
			LEAY	32,Y
			STY		WADDR

			LDX		WWID
			LDA		#96
CLEAR03		STA		,Y+
			LEAX	-1,X
			BNE		CLEAR03

			LDX		WHEI
			LEAX	-1,X
			STX		WHEI
			BNE		CLEAR02

			PULU	X,Y,A,B,CC
			RTS

**
*  CLEAR STATUS BAR
**
CLRSTATUS	LDD		#$000F
			LDX		#' '
			LDY		#32
			JSR		PRINTSTR
			RTS
			
**
*  CONCATENATE STRING
*    X=SOURCE STRING
*    Y=DESTINATION STRING
**
STRCAT		PSHU	X,Y,A,B
STRCAT02	TST		,Y+
			BNE		STRCAT02
			LEAY	-1,Y
STRCAT03	LDA		,X+
			STA		,Y+
			TSTA
			BNE		STRCAT03
			PULU	X,Y,A,B
			RTS

**
*  CONCATENATE STRING
*    X=SOURCE STRING
*    Y=DESTINATION STRING
*    B=NUMBER OF CHAR TO COPY
**
STRNCAT		PSHU	X,Y,A,B
STRNCAT02	TST		,Y+
			BNE		STRNCAT02
			LEAY	-1,Y
STRNCAT03	LDA		,X+
			STA		,Y+
			BEQ		STRNCAT04
			DECB
			BNE		STRNCAT03
			CLR		,Y
STRNCAT04	PULU	X,Y,A,B
			RTS

**
*  GET STRING LENGTH
*    X=STRING
*  EXIT:
*    A=STRING LENGTH
**
STRLEN		PSHU	X
			CLRA
			
STRLEN02	TST		,X+
			BEQ		STRLEN03
			INCA
			BRA		STRLEN02
			
STRLEN03	PULU	X
			RTS
			
**
*  TRIM STRING
*    X=STRING
**
TRIM		PSHU	X,Y,A,B
			CLRB
TRIM02		TST		,X
			BEQ		TRIM03
			INCB
			LEAX	1,X
			BRA		TRIM02
TRIM03		LDA		,-X
			CMPA	#' '
			BNE		TRIM04
			DECB
			BEQ		TRIMEND
			BRA		TRIM03
TRIM04		CLR		1,X
TRIMEND		PULU	X,Y,A,B
			RTS

**
*  STRNCMP - Compare two strings
*    X = First string to compare
*    Y = Second string to compare
*    B = Number of characters to compare
*  EXIT:
*    B= 0 strings are equals
*    B=-1 first string is lower than second string
*    B= 1 first string is higher than second string
**
STRNCMP		PSHS	X,Y,A

STRNC01		LDA		,X+
			CMPA	,Y+
			BHI		STRNHI
			BLO		STRNLOW
			CMPA	#0
			BEQ		STRNEQU
			DECB
			BEQ		STRNEQU
			BRA		STRNC01

STRNLOW		LDB		#-1
			PULS	X,Y,A
			RTS

STRNHI		LDB		#1
			PULS	X,Y,A
			RTS

STRNEQU		CLRB
			PULS	X,Y,A
			RTS

**
*  ITOA
*    D=NUMBER
*    X=STRING
**			
ITOA8		PSHU	X,Y,A,B,CC
			JSR		ITOA004
			PULU	X,Y,A,B,CC
			RTS
**
*  ITOA
*    D=NUMBER
*    X=STRING
**
ITOA16		PSHU	X,Y,A,B,CC
			JSR		ITOA003
			PULU	X,Y,A,B,CC
			RTS

ITOA003		LDY 	#10000
			JSR		ITOA000
			LDY 	#1000
			JSR		ITOA000
ITOA004		LDY		#100
			JSR		ITOA000
			LDY		#10
			JSR		ITOA000
			LDY		#1
ITOA000		STD		NUMBER
			STY		DIGIT
			LDA		#'0'
			STA		,X
ITOA001		LDD		NUMBER
			SUBD	DIGIT
			BCS		ITOA002
			STD		NUMBER
			LDA		,X
			INCA
			STA		,X
			JMP		ITOA001
ITOA002		CLRA
			LEAX	1,X
			STA		,X
			LDD 	NUMBER
			RTS

NUMBER		FDB		0
DIGIT		FDB		0

**
*  ITOHEX
**
ITOHEX		PSHS	A
			LSRA
			LSRA
			LSRA
			LSRA
			ADDA	#$30
			CMPA	#$39
			BLS		ITOHEX02
			ADDA	#$07
ITOHEX02	STA		,Y+
			PULS	A
			ANDA	#$0F
			ADDA	#$30
			CMPA	#$39
			BLS		ITOHEX03
			ADDA	#$07
ITOHEX03	STA		,Y+
			RTS

DIVIDEND	FDB		0
DIVISOR		FCB		0

**
*  DIVIDE
**
DIVIDE		LDA		#8				; count=8
			STA		CTR
			LDD		DIVIDEND		; get dividend

DIVIDE02	ASLB					; shift dividend, quotient
			ROLA
			CMPA	DIVISOR			; is trial subtraction successful?
			BCS		CHKCNT
			SUBA	DIVISOR			; yes, subtract and set bit in quotient
			INCB
CHKCNT		DEC		CTR
			BNE		DIVIDE02
			RTS						; remainder and quotient in d

**
*  SWAP TWO 16 BYTES ELEMENTS
*    X = FIRST ELEMENT
*    Y = SECOND ELEMENT
**
SWAP		LEAS	-1,S			; reserve 1 byte for counter
			LDB		#16
			STB		,S

SWAP02		LDA		,X				; load char of first string
			LDB		,Y				; load char of second string
			STA		,Y+				; save char in second string
			STB		,X+				; save char in first string
			DEC		,S				; decrement counter
			BNE		SWAP02

			LEAS	1,S				; restore stack
			RTS

**
*  DSORT - Sort directory listing with the Heap Sort algorithm
*    D=Number of elements
**
DSORT		CMPD	#0
			BEQ		DSORTEND

			CMPD	#50				; display message if dirsize >= 50
			BLO		DSORT02

			PSHS	A,B

			JSR		CLRSTATUS		; clear status bar

			LDX		#SORTLBL
			LDD		#$010F
			JSR		PRINTRASC

			JSR		FLUSHSCR

			PULS	A,B

DSORT02		SUBD	#1				; last=dirsize-1
			STD		LAST

			ADDD	#1
			LSRA					; divide D by 2
			RORB

DSORT03		STD		CTR				; ctr=dirsize/2
			STD		PARENT
			JSR		DMAXHEAP
			LDD		CTR				; ctr--
			SUBD	#1
			BPL		DSORT03			; ctr >= 0?
			LDD		LAST			; ctr=dirsize-1
			BEQ		DSORTEND		; ctr == 0?

DSORT04		STD		CTR
			JSR		GETDIRADR		; x=dirarr[i]
			LDY		#DIRARR			; y=dirarr[0]
			JSR		SWAP
			LDD		#0				; parent=0
			STD		PARENT
			LDD		CTR				; last=ctr-1
			SUBD	#1
			STD		LAST
			JSR		DMAXHEAP
			LDD		CTR				; ctr--
			SUBD	#1
			BNE		DSORT04

DSORTEND	RTS

**
*  MAXIMUM HEAP SUBROUTINE FOR DSORT
**
DMAXHEAP	LDD		PARENT
			LSLB					; multiply by 2
			ROLA
			STD		CHILD			; child=2*parent
			CMPD	LAST
			BHI		DMAXHEAP04		; child > last?

DMAXHEAP02	BHS		DMAXHEAP03		; child >= last?
			JSR		GETDIRADR		; x=dirarr[child]
			LEAY	16,X			; y=dirarr[child+1]
			LDB		#12				; 12 characters
			JSR		STRNCMP			; compare filename
			BHS		DMAXHEAP03
			LDD		CHILD			; child++
			ADDD	#1
			STD		CHILD

DMAXHEAP03	LDD		CHILD
			JSR		GETDIRADR		; x=dirarr[child]
			TFR		X,Y
			LDD		PARENT
			JSR		GETDIRADR		; x=dirarr[parent]
			LDB		#12				; 12 characters
			JSR		STRNCMP			; compare filename
			BHS		DMAXHEAP04
			JSR		SWAP			; Swap dirarr[parent] and dirarr[child]
			LDD		CHILD			; parent=child
			STD		PARENT
			LSLB					; multiply by 2
			ROLA
			STD		CHILD			; child=2*parent
			CMPD	LAST
			BLE		DMAXHEAP02		; child <= last?

DMAXHEAP04	RTS

**
*  GET DIR ENTRY ADDRESS
*    B = DIR ENTRY NUMBER
*  EXIT:
*    X = DIR ENTRY ADDRESS
**		
GETDIRADR	LDA		#16
			MUL

			LDX		#DIRARR
			LEAX	D,X

			RTS

**
*  FORMAT DIR FILENAME
*    X = DESTINATION STRING
*    Y = SOURCE STRING
**
FORMATDFN	PSHU	X,Y

			CLR		CTR				; reset backspace flag

			LDA		#' '			; add a space
			STA		,X+

			LDB		#12				; copy filename, dot and extension

FORMATD02	LDA		,Y+				; load source char
			CMPA	#8				; backspace?
			BNE		FORMATD03		; no - skip
			LEAX	-1,X			; go back one character
			INC		CTR				; set backspace flag
			BRA		FORMATD04		; skip

FORMATD03	STA		,X+				; save char to destination

FORMATD04	DECB					; decrement character count
			BNE		FORMATD02		; branch if not done

			LDA		#' '			; add a space
			STA		,X+

			TST		CTR				; test backspace flag
			BEQ		FORMATD05		; not set? skip
			STA		,X+				; insert 2 spaces
			STA		,X+

FORMATD05	CLR		,X				; terminate string

			PULU	X,Y
			RTS

**
*  BOOTPAK
**
BOOTPAK
			if		TEST
			BRA		READOK
			endif

			TST		PARTSIZE
			BNE		BOOTPAK02

			JSR		READPART		; get partition list
			BCC		READOK			; branch if no error

			LDX		#READERRMSG		; load error message
			JSR		SHOWERR			; display error
			JMP		EXIT			; exit application

READOK		JSR		PSORT			; sort partition list

BOOTPAK02	JSR		SETPARTOFF

PMAINLOOP	JSR		PDRAWSCR		; refresh screen
PREADKEY	JSR		READKEY			; read keyboard

			BNE		PHANDLEKEY

			LDX		KBUFTMR
			BEQ		PREADKEY
			LEAX	-1,X
			STX		KBUFTMR
			BNE		PREADKEY

			CLR		KBUFPOS			; reset keyboard buffer timer
			LDX		#KBUF
			LDD		#0
			STD		,X
			STD		2,X
			STD		4,X
			BRA		PREADKEY

PHANDLEKEY	STA		KEYPRES			; save key press

			LDA		#$7F			; SHIFT key bit mask
			STA		$FF02			; write keyboard column
			LDA		$FF00			; read keyboard row
			COMA					; invert bits
			ANDA	#$40			; keep SHIFT key bit
			STA		SHIFTKEY		; save SHIFT key state

			LDA		KEYPRES			; restore key press

PISSHIFTKEY	TST		SHIFTKEY
			BEQ		PARTPANE

PISRKEY		CMPA	#'R'
			BNE		PARTPANE
			JSR		RENPART
			BRA		PMAINEND

PARTPANE	JSR		PARTLISTKEY

PISESCKEY	LDA		KEYPRES
			CMPA	#KEYESC
			BEQ		PEXIT
			CMPA	#KEYCLR
			BEQ		PEXIT
			
PMAINEND	JMP		PMAINLOOP

PEXIT		RTS

DETECTPAK	LDD		$D75F			; detect drivepak
			CMPD	#$7EDF
			if		!TEST
			BNE		ERRNOPAK
			endif
			RTS

ERRNOPAK	LDX		#NOPAKMSG		; DrivePak not present
			JSR		SHOWERR
			JMP		EXIT
**
*  Display an error message
*   X=ERROR MESSAGE
**

SHOWERR		PSHU	X

			LDD		#$0506
			LDX		#23
			LDY		#5
			JSR		WINDOW

			LDX		#DPXLBL
			LDD		#$0506
			JSR		PRINTRASC

			LDD		#$0508
			PULU	X
			JSR		PRINTASC

			JSR		FLUSHSCR

SHOWERR02	JSR		[POLCAT]
			BEQ		SHOWERR02
			RTS


**
*  GETPARTDSK - Get number of disks in partition
*  EXIT:
*    D = Number of disks in partition
**
GETPARTDSK	LDX		PARTADR			; copy part size in CTRLSN
			LDA		13,X
			STA		CTRLSN
			LDD		14,X
			STD		CTRLSN+1

			; divide by 64
			LDX		#CTRLSN

			LSR		,X				; division 1 (2)
			ROR		1,X
			ROR		2,X

			LSR		,X				; division 2 (4)
			ROR		1,X
			ROR		2,X

			LSR		,X				; division 3 (8)
			ROR		1,X
			ROR		2,X

			LSR		,X				; division 4 (16)
			ROR		1,X
			ROR		2,X

			LSR		,X				; division 5 (32)
			ROR		1,X
			ROR		2,X

			LSR		,X				; division 6 (64)
			ROR		1,X
			ROR		2,X

			; divide by 45
			LDD		CTRLSN+1
			CMPD	#$2D00			; 256 disks or more
			BHS		GETPART02
			STD		DIVIDEND
			LDA		#45
			STA		DIVISOR
			JSR		DIVIDE			; quotient in B
			CLRA
			BRA		GETPARTEND

GETPART02	LDD		#$0100			256

GETPARTEND	RTS

**
*  GET PARTITION TYPE LABEL
**
TYPELBL		CMPA	#$03
			BEQ		TYPEOS9
			CMPA	#$04
			BEQ		TYPEOS9
			CMPA	#$02
			BEQ		TYPEDOS

TYPEUSR		LDX		#USRLBL
			RTS

TYPEOS9		LDX		#OS9LBL
			RTS

TYPEDOS		LDX		#DOSLBL
			RTS

**
*  READ PARTITION LIST FROM CARD
**
READPART	PSHU	X,Y,A,B

			JSR		DRAWBG

			LDD		#$0506
			LDX		#23
			LDY		#5
			JSR		WINDOW
			LDX		#DPXLBL
			LDD		#$0506
			JSR		PRINTRASC

			LDD		#$0508
			LDX		#READSDMSG
			JSR		PRINTASC

			JSR		FLUSHSCR

			CLRA
			STA		PARTSIZE
			STA		SECCOUNT

			; read LSN0

			LDB		#2				; read sector OP
			LDX		#$0000			; LSN0
			JSR		RWLSN			; read LSN0
			TSTB
			LBNE	READPERR

			; get drives LSN

			LDA		SECBUF+$15		; DOS
			STA		LSNDOS
			LDX		SECBUF+$16
			STX		LSNDOS+1

			LDB		#4				; U0 TO U3
			LDX		#SECBUF+$1D
			LDY		#LSNU0

READP01		LDA		,X
			STA		,Y
			LDA		1,X
			STA		1,Y
			LDA		2,X
			STA		2,Y
			LEAX	4,X
			LEAY	3,Y
			DECB
			BNE		READP01

			; get partition table LSN

			LDA		SECBUF+$11
			STA		PARTLSN
			LDX		SECBUF+$12
			STX		PARTLSN+1

			;  copy in CTRLSN
			STA		CTRLSN
			STX		CTRLSN+1

			LDY		#PARTARR

READP02		LDB		#2				; read sector OP
			JSR		RWLSN			; read sector
			TSTB
			BNE		READPERR

			LDX		#SECBUF
			LDA		,X
			BMI		READPEND		; >= 128 end of table
			TSTA					; deleted partition
			BEQ		READP03			; skip it

			; X = SECTOR BUFFER
			; Y = PARTITION ARRAY

			; copy type and name
			LDD		#9
			JSR		MEMCPY
			LEAY	9,Y

			LDA		SECCOUNT		; save part index
			STA		,Y+

			; copy start address & size
			LDX		#SECBUF+$20
			LDD		#6
			JSR		MEMCPY
			LEAY	6,Y

			LDA		PARTSIZE
			INCA
			STA		PARTSIZE
			CMPA	#MAXPARTSIZE	; check maximum entries
			BEQ		READPEND

READP03		LDA		SECCOUNT		; check maximum sector count
			INCA
			CMPA	#MAXPARTSEC
			BEQ		READPEND
			STA		SECCOUNT

			LDA		CTRLSN
			LDX		CTRLSN+1
			LEAX 	1,X
			BNE		READP04
			INCA
			STA		CTRLSN
READP04		STX		CTRLSN+1
			BRA		READP02

READP05		ANDCC	#$FE			; clear carry

READPEND	PULU	X,Y,A,B
			RTS

READPERR	ORCC	#$01			; set carry
			BRA		READPEND

**
*  RENAME PARTITION
**
RENPART		LDA		PARTSEL
			JSR		GETPARTADR
			STX		PARTADR
			LEAX	1,X
			LDD		#8
			LDY		#FILENAME
			JSR		MEMCPY
			CLR		FILENAME+8

			LDX		#FILENAME
			JSR		TRIM

			LDX		#RENPARTLBL
			JSR		TEXTBOXWIN
			BCS		RENEND

			LDD		PARTLSN+1		; partition table address
			LDY		PARTADR			; part address
			ADDB	9,Y				; increment PARTLSN+2
			ADCA	#0				; increment PARTLSN+1 if overflow
			TFR		D,X
			LDA		PARTLSN
			ADCA	#0				; increment PARTLSN if overflow

			LDB		#2				; read sector OP
			JSR		RWLSN			; read sector
			TSTB
			BNE		RENRERR

			LDA		#' '
			LDB		#8
			LDX		#SECBUF+1
CLEARFN		STA		,X+
			DECB
			BNE		CLEARFN

			LDX		#FILENAME
			LDY		#SECBUF+1
COPYFN		LDA		,X+
			BEQ		WRITENAME
			STA		,Y+
			BRA		COPYFN

WRITENAME	LDD		PARTLSN+1		; partition table address
			LDY		PARTADR			; part address
			ADDB	9,Y				; increment PARTLSN+2
			ADCA	#0				; increment PARTLSN+1 if overflow
			TFR		D,X
			LDA		PARTLSN
			ADCA	#0

			LDB		#3				; write sector OP
			JSR		RWLSN			; write sector
			TSTB
			BNE		RENWERR

			; update partition entry
			LDD		#8
			LDX		#SECBUF+1
			LDY		PARTADR
			LEAY	1,Y
			JSR		MEMCPY

			JSR		PSORT			; sort partition list

RENEND		RTS

RENRERR		LDX		#READERRMSG		; read error
			JSR		SHOWERR
			BRA		RENEND

RENWERR		LDX		#WRITERRMSG		; write error
			JSR		SHOWERR
			BRA		RENEND

**
*	ASSIGN DRIVE TO PARTITION
**
SETDRV		LDA		PARTSEL
			JSR		GETPARTADR
			STX		PARTADR

			LEAX	10,X
			LDY		#LSNU0
			CLRB					; initialize drive counter

SETDRV02	CMPB	OS9DRVSEL		; check drive number
			BEQ		SETDRV03		; branch if drive to set
			
			LDA		,X				; check for duplicate (byte 1)
			CMPA	,Y
			BNE		SETDRV04

			LDA		1,X				; check for duplicate (byte 2)
			CMPA	1,Y
			BNE		SETDRV04

			LDA		2,X				; check for duplicate (byte 3)
			CMPA	2,Y
			BNE		SETDRV04

			CLR		,Y				; match found - clear drive number
			CLR		1,Y
			CLR		2,Y
			BRA		SETDRV04

SETDRV03	LDA		,X				; copy partition LSN in U0LSN-U3LSN
			STA		,Y
			LDA		1,X
			STA		1,Y
			LDA		2,X
			STA		2,Y

SETDRV04	INCB					; increment drive number
			CMPB	#4				; are we done?
			BEQ		SETDRV05		; yes - exit
			LEAY	3,Y				; go to next drive LSN
			BRA		SETDRV02

SETDRV05	
			if		TEST
			BRA		SETDRVEND
			endif
			LDB		#2				; read sector OP
			LDX		#$0000			; LSN 0
			JSR		RWLSN			; read sector
			TSTB					; check status
			BNE		SETDRVRERR		; branch on error

			LDX		#LSNU0			; LSN of /U0 drive
			LDY		#SECBUF+$1D		; LSN of top of "/U0" OS-9 drive

			LDB		#4

SETDRV06	LDA		,X
			STA		,Y
			LDA		1,X
			STA		1,Y
			LDA		2,X
			STA		2,Y

			LEAX	3,X
			LEAY	4,Y
			DECB
			BNE		SETDRV06

			LDB		#3				; write sector OP
			LDX		#$0000			; LSN 0
			JSR		RWLSN			; write sector
			TSTB					; check status
			BNE		SETDRVWERR		; branch on error

SETDRVEND	RTS

SETDRVRERR	LDX		#READERRMSG		; read error
			JSR		SHOWERR
			BRA		SETDRVEND

SETDRVWERR	LDX		#WRITERRMSG		; write error
			JSR		SHOWERR
			BRA		SETDRVEND

**
*  HANDLE PARTITION LIST KEY
**
PARTLISTKEY	LDA		KEYPRES
			CMPA	#KEYUP
			BNE		PISDNKEY

PISUPKEY	LDB		PARTSEL
			TSTB
			LBEQ	PKEYEND
			DECB
			STB		PARTSEL

			LDA		PARTOFF
			CMPA	PARTSEL
			LBLS	PKEYEND

			DECA
			STA		PARTOFF

			JMP		PKEYEND

PISDNKEY	CMPA	#KEYDN
			BNE		PISSDNKEY

			LDB		PARTSEL
			INCB	
			CMPB	PARTSIZE
			LBEQ	PKEYEND

			STB		PARTSEL

			SUBB	PARTOFF
			CMPB	#WINHEI
			LBLO	PKEYEND
			LDA		PARTOFF
			INCA
			STA		PARTOFF

			JMP		PKEYEND

PISSDNKEY	CMPA	#KEYSDN
			BNE		PISSUPKEY

			LDB		PARTSIZE
			SUBB	PARTSEL
			CMPB	#WINHEI
			BCC		ISLOWER

			LDB		PARTSIZE
			DECB
			STB		PARTSEL

			JMP		STOREPART

ISLOWER		LDB		PARTSEL
			ADDB	#WINHEI-1

STOREPART	STB		PARTSEL
			JSR		SETPARTOFF
			JMP		PKEYEND

PISSUPKEY	CMPA	#KEYSUP
			BNE		PISSLTKEY

			LDB		PARTSEL
			CMPB	#WINHEI-1
			BCC		ISGREATER
			LDB		#WINHEI-1

ISGREATER	SUBB	#WINHEI-1
			STB		PARTSEL
			STB		PARTOFF

			JMP		PKEYEND

PISSLTKEY	CMPA	#KEYSLT
			BNE		PISSRTKEY

			CLR		PARTSEL
			CLR		PARTOFF

			JMP		PKEYEND

PISSRTKEY	CMPA	#KEYSRT
			BNE		PISDIGIT

			LDA		PARTSIZE
			DECA
			STA		PARTSEL
			JSR		SETPARTOFF

			JMP		PKEYEND

PISDIGIT	TST		SHIFTKEY
			LBNE	PKEYEND
			CMPA	#'0'
			BLO		PISALPHA
			CMPA	#'3'
			BHI		PISALPHA
			SUBA	#'0'
			STA		OS9DRVSEL
			JSR		SETDRV

			JMP		PKEYEND

PISALPHA	CMPA	#'A'
			LBLO	PISENTERKEY
			CMPA	#'Z'
			LBHI	PISENTERKEY

PISALPHA01	LDB		KBUFPOS			; load number of characters in buffer
			CMPB	#4				; max 4 chars
			LBEQ	PKEYEND			; exit if buffer is full

			LDX		#KBUF			; load keyboard buffer
			CMPA	,X				; compare key with first character in buffer
			BNE		PISALPHA02		; branch if key is different
			CMPB	#1				; check if this is the only character in the buffer
			BEQ		PISALPHA03		; yes - don't add it to the buffer

PISALPHA02	STA		B,X				; store character in buffer
			INCB					; increment number of characters in buffer
			STB		KBUFPOS			; save it

PISALPHA03	LDA		PARTSEL
			CMPB	#1
			BNE		PISALPHA04

			INCA
			CMPA	PARTSIZE		; end of list?
			BNE		PISALPHA04

			CLRA

PISALPHA04	STA		PARTSRCH

			LDD		KBUFDELAY		; keyboard delay
			STD		KBUFTMR
			CLR		SRCHPASS

			LDA		PARTSRCH
			LDB		#ENTRYSIZE
			MUL

PISALPHA05	LDX		#PARTARR
			LEAX	D,X
			LEAX	1,X				; point to name

PISALPHA06	LDY		#KBUF
			LDB		KBUFPOS
			JSR		STRNCMP
			BEQ		PISALPHA08		; match?

			LDA		PARTSRCH
			INCA
			CMPA	PARTSIZE
			BNE		PISALPHA07		; end of list?

			TST		SRCHPASS
			BNE		PKEYEND			; second pass, we're done

			LDA		#1
			STA		SRCHPASS
			CLRA
			STA		PARTSRCH
			LDX		#PARTARR
			LEAX	1,X				; point to name
			BRA		PISALPHA06

PISALPHA07	STA		PARTSRCH
			LEAX	16,X
			BRA		PISALPHA06

PISALPHA08	LDA		PARTSRCH
			STA		PARTSEL
			JSR		SETPARTOFF
			JMP		PKEYEND

PISENTERKEY	CMPA	#KEYENT
			BNE		PKEYEND

			LDA		PARTSEL			; get selected part
			JSR		GETPARTADR		; get part address

			LDY		#LASTPART		; load last partition string
			LDD		#16				; 16 characters
			JSR		MEMCPY			; copy

			LDA		,X				; get partition type
			CMPA	#2				; DOS partition
			BNE		PRUN01			; no - skip

			JSR		CHPART			; activate partition
			LEAS	2,S				; adjust stack to return to main screen
			BRA		PKEYEND

PRUN01		PSHU	X				; save on stack

			JSR		SAVECFG			; save DPX configuration

			LDY		#STR1			; load string buffer
			LDX		#PBOOTCMD		; load BOOT command
PRUN02		LDA		,X+				; load character from command text
			BEQ		PRUN03			; branch on null character
			STA		,Y+				; save character to string buffer
			BRA		PRUN02			; copy next character

PRUN03		LDB		#8				; copy 8 characters
			PULU	X				; get part name
			LEAX	1,X				; skip partition type
PRUN04		LDA		,X+				; load part name character
			STA		,Y+				; store in buffer
			DECB					; decrement counter
			BNE		PRUN04			; copy next character

			LDX		#PBOOTCMD2		; load BOOT command part 2
PRUN05		LDA		,X+				; load character from command text
			STA		,Y+				; save character to string buffer
			BNE		PRUN05			; copy next character

			LDX		#STR1			; load command string
			JMP		RUNBAS			; run command

PKEYEND		RTS

**
*  ACTIVE PARTITION
*    X=PART ENTRY
**
CHPART		STX		PARTADR			; save partition entry

			LDA		10,X			; load partition LSN
			STA		LSNDOS			; store
			LDD		11,X			; load rest of partition LSN
			STD		LSNDOS+1		; store

			LDY		#STR1			; load string buffer
			LDX		#CHPARTCMD		; load DRIVE# command
CHPART02	LDA		,X+				; load character from command text
			BEQ		CHPART03		; branch on null character
			STA		,Y+				; save character to string buffer
			BRA		CHPART02		; copy next character

CHPART03	LDB		#8				; copy 8 characters
			LDX		PARTADR			; get partition entry
			LEAX	1,X				; skip partition type
CHPART04	LDA		,X+				; load partition name character
			STA		,Y+				; store in buffer
			DECB					; decrement counter
			BNE		CHPART04		; copy next character

			LDX		#CHPARTCMD2		; load DRIVE# command part 2
CHPART05	LDA		,X+				; load character from command text
			STA		,Y+				; save character to string buffer
			BNE		CHPART05		; copy next character

			LDX		#STR1			; load command string
			if		!TEST
			JSR		RUNBAS2			; run command
			endif

			CLR		DRVSEL			; reset drive selection
			CLR		DRVOFF			; reset drive list offset
			CLR		PANEFOCUS		; focus on drive window
			JSR		CLRVOLARR		; clear disk volume array

			LDX		#LASTPART
			JSR		GETPARTDSK		; get number of drives in partition
			SUBD	#1				; substract 1 (drive numbers are zero based)
			STB		DRVSIZE			; save number of drives

			RTS

**
*  DRAW THE SCREEN
**
PDRAWSCR	JSR		DRAWBG			; draw background

			; partition window
			LDD		#$0102
			LDX		#WINWID+2
			LDY		#WINHEI+2
			JSR		WINDOW

			LDX		#PARTLABEL
			LDD		#$0102
			JSR		PRINTRASC

			; drive window
			LDD		#$1104
			LDX		#WINWID+2
			LDY		#6
			JSR		WINDOW

			LDX		#OS9DRVLABEL
			LDD		#$1104
			JSR		PRINTRASC

			CLR		CTR				; clear counter
			LDX		#STR1			; load string buffer

PDRAWSCR02	LDA		#'/'			; slash character
			STA		,X+				; add to buffer
			LDA		#'U'			; U character
			STA		,X+				; add to buffer
			LDA		#'0'			; zero character
			ADDA	CTR				; add counter value
			STA		,X+				; add to buffer
			CLR		,X				; terminate string

			LDX		#STR1			; load string buffer
			LDA		#18				; column
			LDB		#5				; row
			ADDB	CTR				; add counter to row
			JSR		PRINTASC		; print OS-9 drive

			INC		CTR				; increment counter
			LDA		CTR				; load counter
			CMPA	#3				; < 3 ?
			BLS		PDRAWSCR02		; yes - loop

			; total number of partitions

			LDD		#$1102
			LDX		#WINWID+2
			LDY		#1
			JSR		WINDOW

			LDX		#TOTPARTLBL
			LDD		#$1102
			JSR		PRINTRASC

			; info window
			LDD		#$110A
			LDX		#WINWID+2
			LDY		#5
			JSR		WINDOW

			LDX		#INFOLABEL
			LDD		#$110A
			JSR		PRINTRASC

			; partition list
			JSR		PARTLIST

			; drive list
			JSR		OS9DRVLIST

			; part info
			JSR		PARTINFO

			; status bar
			LDX		#STATLABEL
			LDD		#$000F
			JSR		PRINTRASC

			JSR		FLUSHSCR		; update screen
			RTS

***
*  GET PART ADDRESS
*   A = PART NUMBER
*  EXIT:
*   X = PART ADDRESS
***		
GETPARTADR	LDB		#ENTRYSIZE
			MUL
			LDX		#PARTARR
			LEAX	D,X
			RTS

**
*  SET PARTITION OFFSET
**
SETPARTOFF	LDA		PARTSIZE
			SUBA	PARTSEL
			CMPA	#WINHEI
			BCC		SETPART02

			LDA		PARTSIZE
			SUBA	#WINHEI
			BCS		SETPART03

			STA		PARTOFF
			RTS

SETPART02	LDA		PARTSEL
			STA		PARTOFF
			RTS

SETPART03	CLRA
			STA		PARTOFF
			RTS

**
*  SORT PARTITION LIST WITH HEAP SORT
**
PSORT		CLRA
			LDB		PARTSIZE
			DECB					; last=partsize-1
			STD		LAST

			ADDD	#1
			LSRA					; divide D by 2
			RORB
			
PSORT02		STD		CTR				; ctr=partsize/2
			STD		PARENT
			JSR		PMAXHEAP
			LDD		CTR				; ctr--
			SUBD	#1
			BPL		PSORT02			; ctr >= 0?
			LDD		LAST			; ctr=partsize-1
			BEQ		PSORTEND		; ctr == 0?

PSORT03		STD		CTR
			TFR		B,A				; transfer LSB of D in A
			JSR		GETPARTADR		; x=partarr[i]
			LDY		#PARTARR		; y=partarr[0]
			JSR		SWAP
			LDD		#0				; parent=0
			STD		PARENT
			LDD		CTR				; last=ctr-1
			SUBD	#1
			STD		LAST
			JSR		PMAXHEAP
			LDD		CTR				; ctr--
			SUBD	#1
			BNE		PSORT03

PSORTEND	RTS

**
*  PMAXHEAP
**
PMAXHEAP	LDD		PARENT
			LSLB					; multiply by 2
			ROLA
			STD		CHILD			; child=2*parent
			CMPD	LAST
			BHI		PMAXHEAP03		; child > last?

PMAXHEAP01	BHS		PMAXHEAP02		; child >= last?
			TFR		B,A				; transfer LSB of D in A
			JSR		GETPARTADR		; x=partarr[child]
			LEAY	16,X			; y=partarr[child+1]
			JSR		CMPPART
			BHS		PMAXHEAP02
			LDD		CHILD			; child++
			ADDD	#1
			STD		CHILD

PMAXHEAP02	LDA		CHILD+1			; load LSB of CHILD
			JSR		GETPARTADR		; x=partarr[child]
			TFR		X,Y
			LDA		PARENT+1		; load LSB of PARENT
			JSR		GETPARTADR		; x=partarr[parent]
			JSR		CMPPART
			BHS		PMAXHEAP03
			JSR		SWAP			; Swap partarr[parent] and partarr[child]
			LDD		CHILD			; parent=child
			STD		PARENT
			LSLB					; multiply by 2
			ROLA
			STD		CHILD			; child=2*parent
			CMPD	LAST
			BLE		PMAXHEAP01		; child <= last?

PMAXHEAP03	RTS

**
*  CMPPART
*   X = FIRST PART
*   Y = SECOND PART
**
CMPPART		PSHU 	X,Y

			LEAX	1,X				; point to first part name
			LEAY	1,Y				; point to second part name
			LDB		#8				; Compare 8 characters
			JSR		STRNCMP

CMPPART02	PULU	X,Y
			RTS

**
*  DISPLAY PARTITION LIST
**
PARTLIST	LDB		PARTSIZE
			LBEQ	LISTEND
			SUBB	PARTOFF
			CMPB	#WINHEI
			BLO		LIST01
			LDB		#WINHEI

LIST01		CLRA
			LDY		#0
			LEAY	D,Y

			LDB		#3
			STB		CURLINE			; start line

			LDA		PARTOFF
			JSR		GETPARTADR

LIST02		STX		PARTADR
			PSHU	Y

			LDY		#STR1			; load buffer string
			LDA		#' '			; load space character
			STA		,Y+				; add to buffer

			* NAME
			LEAX	1,X				; skip partition type
			LDD		#8				; 8 characters
			JSR		MEMCPY			; copy to buffer
			LEAY	8,Y				; adjust buffer pointer

			* SPACER
			LDA		#' '			; load space character
			STA		,Y+				; add to buffer

			* TYPE
			LDA		-1,X			; get partition type
			JSR		TYPELBL			; get partition type label
			LDD		#3				; 3 characters
			JSR		MEMCPY			; copy to buffer
			LEAY	3,Y				; ajust buffer pointer

			LDA		#' '			; load space character
			STA		,Y+				; add to buffer

			; null terminator
			CLRA
			STA		,Y

			; check if it is the active parition
LIST03		LDX		PARTADR
			LDA		10,X
			CMPA	LSNDOS
			BNE		LIST03B
			LDD		11,X
			CMPD	LSNDOS+1
			BNE		LIST03B

			LDA		SELCHR
			STA		STR1

			LDA		SELCHR+1
			STA		STR1+13

LIST03B		LDB		CURLINE
			SUBB	#3
			ADDB	PARTOFF
			CMPB	PARTSEL
			BEQ		LIST04

			; print line
			LDB		CURLINE			; curr line
			LDA		#1
			LDX		#STR1
			JSR		PRINTASC
			JMP		LIST05

			; print reverse line
LIST04		LDB		CURLINE			; curr line
			LDA		#1
			LDX		#STR1
			JSR		PRINTRASC

LIST05		PULU	Y
			LDX		PARTADR
			LEAX	ENTRYSIZE,X
			INC		CURLINE
			LEAY	-1,Y
			LBNE	LIST02

LISTEND		RTS

**
*  DISPLAY DRIVE LIST
**
OS9DRVLIST	LDB		PARTSIZE		; initialize counter in Y
			LDY		#0
			LEAY	B,Y
			LDX		#PARTARR

OS9DRV02	PSHU	Y
			LDY		#LSNU0
			CLRB

OS9DRV03	LDA		10,X			; compare part start address
			CMPA	,Y
			BNE		OS9DRV04
			LDA		11,X
			CMPA	1,Y
			BNE		OS9DRV04
			LDA		12,X
			CMPA	2,Y
			BNE		OS9DRV04

			; found partition
			JSR		PRINTDRV		; B=drv num, X=part adr

OS9DRV04	INCB
			CMPB	#4
			BEQ		OS9DRV05
			LEAY	3,Y
			BRA		OS9DRV03

OS9DRV05	PULU	Y				; decrement counter in Y
			LEAX	ENTRYSIZE,X
			LEAY	-1,Y
			BNE		OS9DRV02

DRVLISTEND	RTS

**
*  PRINTDRV
*    B = Drive number
*    X = Partition address
**
PRINTDRV	PSHU	X,B
			ADDB	#5
			STB		CURLINE			; line to print

PRINTDRV02	LEAX	1,X				; x=part name
			LDY		#STR1			; y=temp string
			LDD		#8
			JSR		MEMCPY			; copy part name in str1
			LEAY	8,Y
			CLRA
			STA		,Y				; null terminator

			LDA		#22
			LDB		CURLINE
			LDX		#STR1
			JSR		PRINTASC

			PULU	X,B
			RTS

**
*  PARTINFO
**
PARTINFO	LDA		PARTSIZE
			LBEQ	PARTIEND

			LDX		#ADDRLBL
			LDD		#$120B
			JSR		PRINTASC

			LDX		#SIZELBL
			LDD		#$120C
			JSR		PRINTASC

			LDX		#DISKSLBL
			LDD		#$120D
			JSR		PRINTASC

			; part address
			LDA		PARTSEL
			JSR		GETPARTADR
			STX		PARTADR
			LDY		#STR1

			LDA		#'$'
			STA		,Y+

			LDA		10,X
			JSR		ITOHEX
			LDA		11,X
			JSR		ITOHEX
			LDA		12,X
			JSR		ITOHEX
			CLRA
			STA		,Y

			LDX		#STR1
			LDD		#$170B
			JSR		PRINTASC

			; part size
			LDX		PARTADR
			LDY		#STR1

			LDA		#'$'
			STA		,Y+

			LDA		13,X
			JSR		ITOHEX
			LDA		14,X
			JSR		ITOHEX
			LDA		15,X
			JSR		ITOHEX
			CLRA
			STA		,Y

			LDX		#STR1
			LDD		#$170C
			JSR		PRINTASC

			; total number of partitions
			CLRA
			LDB		PARTSIZE
			LDX		#STR1
			JSR		ITOA8

			LDX		#STR1
			LDD		#$1B02
			JSR		PRINTRASC

			LDX		PARTADR
			LDA		,X				; get part type
			CMPA	#2				; check for "DOS" part
			BNE		PARTI02			; no? display "N/A"

			JSR		GETPARTDSK		; D=number of disks in partition
			LDX		#STR1
			JSR		ITOA8
			LDX		#STR1
			BRA		PARTI03

PARTI02		LDX		#NALBL

PARTI03		LDD		#$1B0D
			JSR		PRINTASC

PARTIEND	RTS

**
*  GETVOL
*    A = DRIVE NUMBER
*  EXIT
*    X = DRIVE VOLUME
**
GETVOL		PSHU	A				; save drive number
			LDB		#8
			MUL
			LDX		#VOLARR
			LEAX	D,X				; X = drive volume address
			PULU	A				; restore drive volume
			RTS

**
*  READVOL
*    A = DRIVE NUMBER
*  EXIT
*    X = DRIVE VOLUME
*
**
READVOL		JSR		GETVOL			; get drive volume
			PSHU	X				; save on stack
			LDB		,X				; load first character
			BEQ		READVOL04		; no volume flag? - yes exit
			CMPB	#' '			; is it a space?
			BNE		READVOL04		; no, volume already filled - exit

			STA		USD0
			LDD		#$1111			; track 17 sector 17
			JSR		READSECT		; read sector

			LDA		DRVSEL			; load current drive
			STA		USD0

			LDX		#SECBUF			; load sector buffer
			LDY		,U				; load volume address
			LDA		,X				; load first character
			LDB		#8				; 8 characters

READVOL02	LDA		,X+				; load first character
			BEQ		READVOL04		; null - exit
			CMPA	#$80			; semi graphic character?
			BCC		READVOL03		; yes - set no volume flag
			STA		,Y+				; store character
			DECB					; decrement number of characters
			BNE		READVOL02		; done? - no loop
			BRA		READVOL04

READVOL03	CLRA					; set no volume flag
			STA		,X

READVOL04	PULU	X				; restore volume address
			RTS

**
*  CLRVOLARR
**
CLRVOLARR	LDA		#' '
			LDX		#VOLARR
			LDY		#256*8
CLRVOL02	STA		,X+
			LEAY	-1,Y
			BNE		CLRVOL02
			RTS

**
*  SHOW HELP
**
HELP		JSR		DRAWBG

			LDD		#$0102			; command window
			LDX		#31
			LDY		#6
			JSR		WINDOW

			LDX		#HELPLBL
			LDD		#$0102
			JSR		PRINTRASC

			LDD		#$0203
			LDX		#HELPMSG1
			JSR		PRINTASC

			LDD		#$0204
			LDX		#HELPMSG2
			JSR		PRINTASC

			LDD		#$0205
			LDX		#HELPMSG3
			JSR		PRINTASC

			LDD		#$0206
			LDX		#HELPMSG4
			JSR		PRINTASC

			LDD		#$0108			; navigation keys window
			LDX		#31
			LDY		#5
			JSR		WINDOW

			LDX		#NAVLBL
			LDD		#$0108
			JSR		PRINTRASC

			LDD		#$0209
			LDX		#NAVMSG1
			JSR		PRINTASC

			LDD		#$020A
			LDX		#NAVMSG2
			JSR		PRINTASC

			LDD		#$020B
			LDX		#NAVMSG3
			JSR		PRINTASC

			JSR		CLRSTATUS		; clear status bar

			LDX		#ABOUTCMD		; display about command
			LDD		#$010F
			JSR		PRINTRASC

			JSR		FLUSHSCR

HELPKEY		JSR		[POLCAT]
			BEQ		HELPKEY
			CMPA	#'A'
			BNE		HELPEND
			JSR		ABOUT

HELPEND		RTS

**
*  SHOW ABOUT DIALOG
**
ABOUT		JSR		DRAWBG

			LDD		#$0304
			LDX		#26
			LDY		#10
			JSR		WINDOW

			LDX		#' '				; clear window title
			LDY		#25
			LDD		#$0304
			JSR		PRINTSTR

			LDX		#ABOUTLBL			; display window title
			LDD		#$0D04
			JSR		PRINTRASC

			LDD		#$0506
			LDX		#ABOUTMSG1
			JSR		PRINTASC
			LDD		#$0507
			LDX		#ABOUTMSG2
			JSR		PRINTASC
			LDD		#$0508
			LDX		#ABOUTMSG3
			JSR		PRINTASC

			LDD		#$050A
			LDX		#ABOUTMSG4
			JSR		PRINTASC
			LDD		#$050B
			LDX		#ABOUTMSG5
			JSR		PRINTASC

			JSR		FLUSHSCR

ABOUTKEY	JSR		[POLCAT]
			BEQ		ABOUTKEY
			RTS

**
*  LOADSCR - Displays a loading screen
**
LOADSCR		LDA		#128			; load clear screen character
			JSR		CLRSCR			; clear screen

			LDX		#$A3			; red stripe
			LDY		#32				; 32 characters
			LDD		#$0005			; col 0 row 7
			JSR		PRINTSTR

			LDX		#$83			; green stripe
			LDY		#32				; 32 characters
			LDD		#$0006			; col 0 row 8
			JSR		PRINTSTR

			LDX		#' '+64			; space
			LDY		#32				; 32 characters
			LDD		#$0007			; col 0 row 7
			JSR		PRINTSTR

			LDX		#$8C			; green stripe
			LDY		#32				; 32 characters
			LDD		#$0008			; col 0 row 10
			JSR		PRINTSTR

			LDX		#$AC			; red stripe
			LDY		#32				; 32 characters
			LDD		#$0009			; col 0 row 11
			JSR		PRINTSTR

			LDY		#STR1			; load string buffer
			CLR		,Y				; terminate string

			LDX		#LOADMSG1		; load loading message 1
			JSR		STRCAT			; append

			LDB		DIRSEL			; load selected file
			JSR		GETDIRADR		; get selected file address
			LDY		#DIRFN			; load string buffer
			CLR		,Y				; terminate string
			LDB		#8				; 8 characters
			JSR		STRNCAT			; copy
			LDX		#DIRFN			; load string buffer
			JSR		TRIM			; trim spaces

			LDY		#STR1			; load string buffer
			JSR		STRCAT			; copy

			LDX		#LOADMSG2		; load loading message 2
			JSR		STRCAT			; copy

			LDX		#STR1			; load string buffer
			JSR		STRLEN			; get string length
			LSRA					; divide by 2
			STA		CTR				; store

			LDA		#16				; 32/2 - middle of the screen
			SUBA	CTR				; substract half length of the screen
			LDB		#7				; row 7
			LDX		#STR1			; load string buffer
			JSR		PRINTASC		; print centered string

			JSR		FLUSHSCR		; update screen

			RTS

			if		DEBUG			; for debugging purposes
**
*  PRINTA
*    A=VALUE TO PRINT
**
PRINTA		PSHU	X,Y,A,B,CC		; save registers
			TFR		A,B				; transfer A to B
			CLRA
			LDX		#STR2			; load string buffer
			JSR		ITOA8			; convert to ascii
			JSR		PRINTX02		; print string
			PULU	X,Y,A,B,CC		; restore registers
			RTS

**
*  PRINTD
*    D=VALUE TO PRINT
**
PRINTD		PSHU	X,Y,A,B,CC		; save registers
			LDX		#STR2			; load string buffer
			JSR		ITOA16			; convert to ascii
			JSR		PRINTX02		; print string
			PULU	X,Y,A,B,CC		; restore registers
			RTS

**
*  PRINTX
*    X=NULL TERMINATED STRING
**
PRINTX		PSHU	X,Y,A,B,CC		; save registers
			JSR		PRINTX02		; print string
			PULU	X,Y,A,B,CC		; restore registers
			RTS

PRINTX02	PSHU	X				; save string in X
			LDD		#$0				; clear top line
			LDX		#' '
			LDY		#32
			JSR		PRINTSTR

			PULU	X				; restore string from X
			LDD		#0				; top of the screen
			JSR		PRINTASC		; print value
			JSR		FLUSHSCR		; flush screen

PRINTX03	JSR		[POLCAT]		; read keyboard
			BEQ		PRINTX03		; wait for a key
			RTS

**
*  Dump sector buffer to screen
**
DUMPSEC		PSHU	X,Y,A,B,CC		; save registers
			CLRB
			LDX		#SECBUF
			LDY		#VIDRAM

DUMPSEC02	LDA		,X+
			STA		,Y+
			DECB
			BNE		DUMPSEC02

DUMPSEC03	JSR		[POLCAT]
			BEQ		DUMPSEC03

			PULU	X,Y,A,B,CC		; restore registers

			endif

**
*  STRINGS AND VARIABLES
**
RUNCMD		FCN		/RUN"/
RUNCMD2		FCN		/"/
RUNMCMD		FCN		/LOADM"/
RUNMCMD2	FCN		/":POKE 65494,0:POKE 65496,0:EXEC/
DOSCMD		FCN		"CLS:DRIVE 0:DOS"
EXITCMD		FCN		"CLS"

PBOOTCMD	FCN		/CLS:DOS#"/
PBOOTCMD2	FCN		/"/

CHPARTCMD	FCN		/DRIVE#"/
CHPARTCMD2	FCN		/"/

PRGTITLE	FCC		"  DPX ",VERSION,'.',MAJOR,MINOR
			FCN		" - DRIVEPAK EXPLORER  "
DIRLABEL	FCN		"  DIRECTORY   "
HELPCMD		FCN		"SHIFT-H=HELP"
PARTCMD		FCN		"CLEAR=PARTITIONS"
BOOTCMD		FCN		"ENTER=BOOT"
DSKERRMSG	FCN		"INVALID DISK"
OS9DSKMSG	FCN		"OS-9 DISK"
OS9BOOTMSG	FCN		"PRESS ENTER"
OS9BOOTMSG2 FCN		"TO BOOT"

SEARCHLBL	FCN		"  FIND A FILE  "
SEARCHSTAT	FCC		" SEARCHING DRIVE "
SEARCHDRV	FCN		"000            "

PARTLABEL	FCN		"  PARTITIONS  "
TOTPARTLBL	FCN		" TOTAL        "
OS9DRVLABEL	FCN		" OS-9 DRIVES  "
INFOLABEL	FCN		"  PART INFO   "
STATLABEL	FCN		" SHIFT-R=RENAME   0-3=SET DRIVE "
RENPARTLBL	FCN		"  RENAME PART  "

DPXLBL		FCN		"  DRIVEPAK EXPLORER   "
READSDMSG	FCN		"   READING SD CARD    "
READERRMSG	FCN		"  ERROR READING CARD  "
WRITERRMSG	FCN		"  ERROR WRITING CARD  "
NOPAKMSG	FCN		" DRIVEPAK NOT PRESENT "

DOSLBL		FCN		"DOS"
OS9LBL		FCN		"OS9"
USRLBL		FCN		"USR"

ADDRLBL		FCN		"ADDR:"
SIZELBL		FCN		"SIZE:"
DISKSLBL	FCN		"DISKS:"
NALBL		FCN		"N/A"

SELCHR		FCC		"><"

SORTLBL		FCN		"SORTING DIRECTORY..."
SORTEDLBL	FCN		"^"

LOADMSG1	FCN		"LOADING "
LOADMSG2	FCN		"..."

HELPLBL		FCN		"       COMMAND SUMMARY        "
HELPMSG1	FCN		"CLEAR:   LIST PARTITIONS"
HELPMSG2	FCN		"ENTER:   EXEC PROG/BOOT PART"
HELPMSG3	FCN		"SHIFT-F: FIND FILE"
HELPMSG4	FCN		"SHIFT-S: SORT DIRECTORY"

NAVLBL		FCN		"       NAVIGATION KEYS        "
NAVMSG1		FCN		"SHIFT-UP/DOWN:  PAGE UP/DOWN"
NAVMSG2		FCN		"SHIFT-LEFT/RIGHT:   HOME/END"
NAVMSG3		FCN		"[A-Z][0-9]:  QUICK SELECTION"

ABOUTCMD	FCN		"A=ABOUT"

ABOUTLBL	FCN		"ABOUT"
ABOUTMSG1	FCN		"DRIVEpak EXPLORER"
ABOUTMSG2	FCN		"BY GUILLAUME MAJOR"
ABOUTMSG3	FCN		"2016-2020"
ABOUTMSG4	FCN		"BASED ON SIDEKICK BY"
ABOUTMSG5	FCN		"LUIS ANTONIOSI"

CURLINE		FDB		0
CURDRV		FDB		0
STACKPTR	FDB		0

DRVSIZE		FCB		0
DRVSEL		FCB		0
DRVOFF		FDB		0
LASTDRV		FCB		0
LASTDIR		FCB		0

DIRSIZE		FCB		0
DIRSEL		FCB		0
DIROFF		FCB		0

KEYPRES		FDB		0
SHIFTKEY	FCB		0
PANEFOCUS	FCB		0
CURSEC		FCB		0
SECPOS		FCB		0

OS9DSK		FCB		0
BOOTABLE	FCB		0
DSKERR		FCB		0
DIRSORT		FCB		0

PARENT		FDB		0
CHILD		FDB		0
LAST		FDB		0
CTR			FDB		0

CC3			FCB		0
TMP			FDB		0

SREG		FDB		0

INVCHARS	FCN		"*+,./:;<=>?[\]",'"'

					; default partition entry (DOS) 
LASTPART	FCB		$02,$44,$4F,$53,$20,$20,$20,$20
			FCB		$20,$00,$00,$04,$00,$0B,$40,$00

PATTERN		FCN		"        .   "
FILESRCH	FCB		0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

NORMAL		FCB		0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
SRCDRV		FCB		0
RESETSRC	FCB		0

FILENAME	FCB		0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
CURSTR		FCN		" "
INPUTPOS	FDB		0
KBUF		FCB		0,0,0,0,0,0
KBUFPOS		FCB		0
KBUFTMR		FDB		0
KBUFDELAY	FDB		2048
KEYTMR		FDB		0
KEYSTA		FCB		0
KEYSRCH		FDB		0
PARTSRCH	FCB		0
SRCHPASS	FCB		0

PARTOFF		FCB		0
PARTSEL		FCB		0
PARTLSN		FCB		0,0,0
CTRLSN		FCB		0,0,0
OS9DRVSEL	FCB		0
PARTADR		FDB		0
SECCOUNT	FCB		0

			if		!TEST
LSNDOS		FCB		0,0,0
LSNU0		FCB		0,0,0
LSNU1		FCB		0,0,0
LSNU2		FCB		0,0,0
LSNU3		FCB		0,0,0
			else
LSNDOS		FCB		$00,$20,$00
LSNU0		FCB		$0D,$40,$00
LSNU1		FCB		$34,$B5,$C0
LSNU2		FCB		$26,$CB,$40
LSNU3		FCB		$0F,$20,$00
			endif

			if		!TEST
PARTARR		RMB		(MAXPARTSIZE*ENTRYSIZE)
PARTSIZE	FCB		0
			else
			include "partarr.asm"
PARTSIZE	FCB		(PARTARREND-PARTARR)/16
			endif
			
STR1		RMB		256				; temp string buffer
			if		DEBUG
STR2		RMB		128				; temp string buffer #2
			endif
DIRFN		RMB		12
SECBUF		EQU		$0600			; use Disk Basic disk buffer
SCRBUF		RMB		32*16			; screen buffer
DIRARR		RMB		68*16			; file directory array
VOLARR		RMB		256*8			; disk volume array

STACK		RMB		64
USRSTK		EQU 	*

			END START
