;ZERO PAGE VARIABLES
	;$06/07 = temp locations for addresses of strings
	;$08 = currently selected file
	;$09 = current command line (changed with More command)
	;$19/1A = blocks available
	;$1B/1C = blocks used
	;$1D/1E = blocks total
	;$CE/$CF = temporary 16-bit value
	;$D7 = number of files
	;$E3 = temporary 8-bit value
	;$EB/EC = input to bin-to-dec routine
	;$ED/EE/EF = output from bin-to-dec routine
	;$FA/FB/FC/FD = date & time for PRDATIME
	;$FE/FF = temporary

	;  MEMORY MAP                                              ~  FILE MAP
	;        +-----------------+          +-----------------+  ~        +-----------------+
	;  $0000 |    Zero Page    |    $1800 | SYS File Loader |  ~  $2000 |  Startup Code   |
	;  $0100 |      Stack      |    $1900 |Text Viewer Buffr|  ~  $2100 | SYS File Loader |
	;  $0200 | Keyboard Buffer |    . . . |Text Viewer Buffr|  ~        +-----------------+
	;  $0300 | Unused / Vectors|    $1F00 |Text Viewer Buffr|  ~  $2200 |  Program Code   |
	;        +-----------------+          +-----------------+  ~  . . . |  Program Code   |
	;  $0400 |    Text Page    |    $2000 |   Data Buffer   |  ~  $3800 |  Program Code   |
	;  $0500 |    Text Page    |    . . . |   and Hi-Res    |  ~        +-----------------+
	;  $0600 |    Text Page    |    $3F00 |    Graphics     |  ~  $3A00 |   Data Tables   |
	;  $0700 |    Text Page    |          +-----------------+  ~  . . . |   Data Tables   |
	;        +-----------------+    $4000 |  Program Code   |  ~  $4100 |   Data Tables   |
	;  $0800 |                 |    . . . |  Program Code   |  ~        +-----------------+
	;  $0900 | Lo-Res Graphics |    $5F00 |  Program Code   |  ~
	;  $0A00 | Loading Buffer  |          +-----------------+  ~
	;  $0B00 |                 |    $6000 |   Data Tables   |  ~
	;        +-----------------+    . . . |   Data Tables   |  ~
	;  $0C00 |  ProDOS Prefix  |    $6700 |   Data Tables   |  ~
	;  $0D00 |  File Clipboard |          +-----------------+  ~
	;  $0E00 |Catalog Extension|    $6800 |     Catalog     |  ~
	;  $0F00 |xxxxxxxxxxxxxxxxx|    . . . |     Catalog     |  ~
	;        +-----------------+    $6E00 |     Catalog     |  ~
	;  $1000 |    I/O Buffer   |    $6F00 |  String Buffer  |  ~
	;  $1100 |    I/O Buffer   |          +-----------------+  ~
	;  $1200 |    I/O Buffer   |                               ~
	;  $1300 |    I/O Buffer   |                               ~
	;        +-----------------+                               ~
	;  $1400 |I/O Buff for Copy|                               ~
	;  $1500 |I/O Buff for Copy|                               ~
	;  $1600 |I/O Buff for Copy|                               ~
	;  $1700 |I/O Buff for Copy|                               ~
	;        +-----------------+                               ~

	;The program itself starts at $4000, since $2000 is used as a buffer
	;and for displaying hi-res graphics with the V command.
	;Data tables are stored in the file at $3000; this startup code
	;will move them to $6000 where they belong. For some reason, if
	;I put them at $6000 in the file, ProDOS fails to load them; apparently
	;it has a limit of 16K on SYS files or something.
	;This code will also do all the one-time setup stuff to get the
	;environment working, and check for an 80-column card before
	;jumping to the main program at $4000.

	; * EQUATES *
	.alias STRADDRL $06
	.alias STRADDRH $07
	.alias CURRSEL $08	;Currently selected file
	.alias CURRCMD $09	;Currently displayed line of command keys
	.alias BLOXAVLL $19
	.alias BLOXAVLH $1A
	.alias BLOXUSDL $1B
	.alias BLOXUSDH $1C
	.alias BLOXTTLL $1D
	.alias BLOXTTLH $1E
	.alias TEMP1L $CE
	.alias TEMP1H $CF
	.alias NUMFILES $D7	;Number of files in catalog
	.alias TEMP2 $E3
	.alias TEMP3 $FE
	.alias TEMP4 $FF
	.alias IOBUFF $1000	;Low-level buffer for OPEN command
	.alias IOBUFF2 $1400
	.alias IOBUFFER $2000	;High-level buffer for READ, WRITE, ONLINE command
	.alias CATALOG $6800	;File catalog
	.alias PATHBFR $6F00	;General buffer for string data
	.alias REALPRFX $C00	;Buffer for ProDOS prefix
	.alias COPYSRC $D00	;Source path for copy routine

	.org $2000

	;START OF SYSTEM FILE CODE

	LDX #$FF	;Set stack pointer
	TXS

	LDA <PFNQUIT	;Set RESET vector
	STA $03F2
	LDA >PFNQUIT
	STA $03F3
	EOR #$A5	;Set power-up byte
	STA $03F4

	LDA #$80	;Set system bit-map
	STA $BF5B	;Protect $1800-$18FF (SYS loader)
	LDA #$FF	;Set system bit-map
	STA $BF60	;Protect $4000-$47FF (program)
	STA $BF61	;Protect $4800-$4FFF (program)
	STA $BF62	;Protect $5000-$57FF (program)
	STA $BF63	;Protect $5800-$5FFF (program)
	STA $BF64	;Protect $6000-$67FF (data)
	STA $BF65	;Protect $6800-$6FFF (catalog, path string)

	LDA #$00
	STA $BFFC	;Set minimum MLI version
	STA $BFFD	;Set minimum MLI version
	STA $D00	;Initialize file clipboard

	JSR CPYDATBL	;Copy data tables to $6000
	JSR CPYLOADR	;Copy SYS file loader to $1800
	JSR CPYPROG	;Copy PFN program to $4000

	LDA $BF98	;Check for 80-column card
	AND #$02
	BEQ NO80COL

	JSR PROTDHR	;Protect DHR
	JMP PFNSTART	;Actual program is at $4000, since $2000 is HGR which PFN will use

NO80COL:	LDX #$01
	LDY #$04
	JSR SETPOS
	LDX #$A2	;"ProDOS File Navigator 3.0"
	LDY #$60
	JSR PRINTSTR
	LDX #$00
	LDY #$05
	JSR SETPOS
	LDX #$9E	;" requires an 80-column card."
	LDY #$63
	JSR PRINTSTR
	LDX #$01
	LDY #$07
	JSR SETPOS
	LDX #$E4	;"Press any key to continue."
	LDY #$61
	JSR PRINTSTR
	JSR GETCHAR
	JMP PFNQUIT

CPYDATBL:	LDX #$3A	;Starting page is $3Axx
	LDY #$00	;Current offset in page should be 0
	STX $07	;Source address is $3A00
	STY $06
	LDX #$60	;Starting page is $60xx
	STX $09	;Destination address is $6000
	STY $08
	LDX #$07	;Number of pages to copy (7)
CDTLOOP:	LDA ($06),Y	;Copy contents of source address to destination address
	STA ($08),Y
	INY	;Add 1 to the address being copied
	BNE CDTLOOP	;If we didn't roll over, loop back to copy the next address
	INC $07	;If we did roll over, increase the high byte of the source address
	INC $09	;Increase the high byte of the destination address
	DEX	;Decrease X (number of pages to copy)
	BNE CDTLOOP	;If it's not zero, we still have more pages to copy; loop back to copy the next page
	RTS	;If it is zero, we're done and can return

CPYLOADR:	LDX #$21	;Starting page is $21xx
	LDY #$00	;Current offset in page should be 0
	STX $07	;Source address is $2100
	STY $06
	LDX #$18	;Starting page is $18xx
	STX $09	;Destination address is $1800
	STY $08
	LDX #$01	;Number of pages to copy (1)
	JMP CDTLOOP	;Use the same copying code as CPYDATBL, just different initial values.

CPYPROG:	LDX #$22	;Starting page is $22xx
	LDY #$00	;Current offset in page should be 0
	STX $07	;Source address is $2200
	STY $06
	LDX #$40	;Starting page is $40xx
	STX $09	;Destination address is $4000
	STY $08
	LDX #$18	;Number of pages to copy (24)
	JMP CDTLOOP	;Use the same copying code as CPYDATBL, just different initial values.

	.advancenop $2100
	.org $1800

	;This here is the SYS file loader; it will be relocated to $1800 by the startup routine
	JSR TXTUNWDW
	JSR CLRSCRN
	JSR A80COLOFF
	JSR DPROTDHR

	LDA #$00	;Set system bit-map
	STA $BF60	;Unprotect $4000-$47FF (program)
	STA $BF61	;Unprotect $4800-$4FFF (program)
	STA $BF62	;Unprotect $5000-$57FF (program)
	STA $BF63	;Unprotect $5800-$5FFF (program)
	STA $BF64	;Unprotect $6000-$67FF (data)
	STA $BF65	;Unprotect $6800-$6FFF (catalog, path string)

	LDX $6F00
	STX $D00
SFLLOOP1:	LDA $6F00,X
	STA $D00,X
	DEX
	BNE SFLLOOP1
	JSR $BF00
	.byte $C8	;OPEN
	.byte <SFLOPEN
	.byte >SFLOPEN
	BCS SFLERROR
	LDX SFLOPREF
	STX SFLNLREF
	STX SFLRDREF
	STX SFLCLREF
	STX SFLGEREF
	JSR $BF00
	.byte $D1	;GET EOF
	.byte <SFLGTEOF
	.byte >SFLGTEOF
	BCS SFLERROR
	LDX SFLEOF
	LDY SFLEOF+1
	STX SFLREQCT
	STY SFLREQCT+1
	JSR $BF00
	.byte $C9	;NEWLINE
	.byte <SFLNEWLN
	.byte >SFLNEWLN
	BCS SFLERROR
	JSR $BF00
	.byte $CA	;READ
	.byte <SFLREAD
	.byte >SFLREAD
	BCS SFLERROR
	JSR $BF00
	.byte $CC	;CLOSE
	.byte <SFLCLOSE
	.byte >SFLCLOSE
	BCS SFLERROR
	LDX #$FF	;Set stack pointer
	TXS
	JMP IOBUFFER	;Transfer control to the next program
SFLERROR:	LDX #$FF	;An error occurred while loading the next program! Start all over!!!
	TXS	;Set stack pointer
	LDA #$FF	;Set system bit-map
	STA $BF5B	;Protect $1800-$1FFF (SYS loader)
	STA $BF60	;Protect $4000-$47FF (program)
	STA $BF61	;Protect $4800-$4FFF (program)
	STA $BF62	;Protect $5000-$57FF (program)
	STA $BF63	;Protect $5800-$5FFF (program)
	STA $BF64	;Protect $6000-$67FF (data)
	STA $BF65	;Protect $6800-$6FFF (catalog, path string)
	JSR PROTDHR	;Protect DHR
	JMP PFNSTART	;Start PFN again

SFLOPEN:	.byte $03
	.byte $00
	.byte $0D
	.byte <IOBUFF
	.byte >IOBUFF
SFLOPREF:	.byte $00
SFLNEWLN:	.byte $03
SFLNLREF:	.byte $00
	.byte $00
	.byte $00
SFLREAD:	.byte $04
SFLRDREF:	.byte $00
	.byte <IOBUFFER
	.byte >IOBUFFER
SFLREQCT:	.byte $00
	.byte $00
	.byte $00
	.byte $00
SFLCLOSE:	.byte $01
SFLCLREF:	.byte $00
SFLGTEOF:	.byte $02
SFLGEREF:	.byte $00
SFLEOF:	.byte $00
	.byte $00
	.byte $00

	.advancenop $1900
	.org $4000

	;HERE IS A PAGE OF JUMP TABLES
	;ProDOS File Navigator can run binary files. While the binary file is running,
	;it has access to all of PFN's routines and data tables. Some of these routines
	;could be very useful to the program in the binary file. Since the locations of
	;the routines will change with every version, we'll put a jump table here that
	;they can use, as well as a version byte it can use to determine which version
	;of PFN it is running under.

	JMP PFNSTART	;$4000 - entry point for entire program
	JMP DISPDIR	;$4003 - reload catalog and wait for next event
	JMP DISPDIRS	;$4006 - reload catalog with same file selected and wait for next event
	JMP DISP	;$4009 - redraw the screen and wait for next event
	JMP DISP0	;$400C - redraw starting with the prefix and wait for next event
	JMP DISPCAT	;$400F - redraw the catalog and wait for next event
	JMP DISPCAT2	;$4012 - redraw the catalog over the existing one and wait for next event
	JMP KBDLOOP	;$4015 - wait for next event
	JMP ISNTUPER	;$4018 - start of keyboard checklist; this is used to patch the keyboard, since each check is exactly 7 bytes long
	JMP READDIR	;$401B - read the current directory into the catalog
	JMP PRINTCAT	;$401E - print the catalog
	JMP DISKSPC	;$4021 - recalculate disk space
	JMP KRSTDISP	;$4024 - completely reload the screen, 80-column mode and all
	JMP A80COLON	;$4027 - turn 80-columns on
	JMP A80COLOFF	;$402A - turn 80-columns off
	JMP TEXT	;$402D - text mode
	JMP LOWRESGR	;$4030 - lo-res mode
	JMP DBLOWRES	;$4033 - double lo-res mode
	JMP HIRESGR	;$4036 - hi-res mode
	JMP DBLHIRES	;$4039 - double hi-res mode
	JMP MAINMEM	;$403C - main memory access
	JMP AUXMEM	;$403F - auxiliary memory access
	JMP NORMAL	;$4042 - normal video
	JMP INVERSE	;$4045 - inverse video
	JMP CLRSCRN	;$4048 - clear screen
	JMP SETPOS	;$404B - set cursor position in X and Y
	JMP TXTUNWDW	;$404E - set text window to whole screen
	JMP TXTWINDW	;$4051 - set text window to inside lines
	JMP TXTPRWDW	;$4054 - set text window to bottom line (prompt line)
	JMP PRINTSTR	;$4057 - print a string with address in X,Y
	JMP PRSTR6F	;$405A - print a string in $6F00
	JMP PRHISTXY	;$405D - print a string with address in X,Y, high or low ascii
	JMP PRHISTR	;$4060 - print a string in $6F00, high or low ascii
	JMP PRINTCR	;$4063 - print carriage return
	JMP BEEP	;$4066 - beep
	JMP SMILE	;$4069 - display a smiley face at the bottom of the screen for two seconds
	JMP XPERIODS	;$406C - print periods; number in X
	JMP PRINTNUM	;$406F - print a number in X,Y
	JMP PRNMDIV2	;$4072 - print a number in X,Y divided by 2; ".5" is printed if the number is odd
	JMP MINIED24	;$4075 - print leftmost two decimal digits of X
	JMP HEXSTRNG	;$4078 - convert string of hex digits in $6F00 to 5-byte big-endian number in $EB-$EF
	JMP STREQU	;$407B - compare Pascal strings, case-sensitive; addresses of strings in $FA-$FD, zero flag set if strings are equal
	JMP STREQI	;$407E - compare Pascal strings, case-insensitive; addresses of strings in $FA-$FD, zero flag set if strings are equal
	JMP PRINTYPE	;$4081 - print ProDOS file type in X
	JMP PRDATIME	;$4084 - print date and time in ProDOS format in $FA-$FD
	JMP PFNPRMPT	;$4087 - ask for user input; address of prompt string in X,Y, number of dots in A, input at $6F00
	JMP GETCHAR	;$408A - get a character; input in A
	JMP GETLINE	;$408D - get a line of keyboard input; input in $200
	JMP GETLN6F	;$4090 - get a line of keyboard input; input in $6F00
	JMP GETFADDR	;$4093 - get the address of a file's catalog entry; file number in X, address returned in $CE-$CF
	JMP GETPRFX	;$4096 - get current prefix in $6F00
	JMP SETPRFX	;$4099 - set current prefix to $6F00
	JMP CHEKPRFX	;$409C - check current prefix; if we're at the ONLINE level, carry is set; current prefix is in $6F00
	JMP GETNAME	;$409F - get name of currently selected file in $6F00
	JMP GETPATH	;$40A2 - get full path to currently selected file in $6F00
	JMP FINDDEVN	;$40A5 - find a volume's device number; path to or name of volume in $6F00, device number returned in A and X
	JMP CLEARPGE	;$40A8 - clear page Y of memory
	JMP CLEARBUF	;$40AB - clear $2000-$3FFF
	JMP CLRBUF2	;$40AE - clear $1900-$3FFF
	JMP XFERFREF	;$40B1 - transfer directory entry to catalog entry; address of dir entry at $06-$07, address of cat entry at $CE-$CF
	JMP XFERGR	;$40B4 - transfer lo-res graphics from $800 to $400 without touching screen holes
	JMP XFERGRA	;$40B7 - transfer lo-res graphics from main $800 to auxiliary $400 without touching screen holes
	JMP XFERAUXH	;$40BA - transfer main $2000-$3FFF to auxiliary $2000-$3FFF
	JMP PROTDHR	;$40BD - protect DHR auxiliary memory from being overwritten by files in RAM disk
	JMP DPROTDHR	;$40C0 - unprotect DHR auxiliary memory
	JMP STDRTS	;$40C3
	JMP STDRTS	;$40C6
	JMP STDRTS	;$40C9
	JMP STDRTS	;$40CC
	JMP STDRTS	;$40CF
	JMP STDRTS	;$40D2
	JMP STDRTS	;$40D5
	JMP STDRTS	;$40D8
	JMP STDRTS	;$40DB
	JMP STDRTS	;$40DE
	JMP STDRTS	;$40E1
	JMP STDRTS	;$40E4
	JMP STDRTS	;$40E7
	JMP STDRTS	;$40EA
	JMP STDRTS	;$40ED
	JMP DBGERR0	;$40F0 - make "Blocks Available" display the current value of A
	JMP DBGERR1	;$40F3 - make "Blocks Used" display the current value of A
	JMP DBGERR2	;$40F6 - make "Blocks Total" display the current value of A
	JMP $1800	;$40F9 - transfer control to SYS file; path in $6F00
	JMP PFNQUIT	;$40FC - quit ProDOS File Navigator
	.byte $30	;$40FF - PFN version number

	;THIS IS THE MAIN LOOP OF THE PROGRAM.
	;This calls routines (not subroutines) that handle each keyboard command.
	;The routines return by jumping back to somewhere inside here.
	;There are several places to jump back to, depending on what the command affected:
	;
	;    DISPDIR	Resets the currently selected file, reloads the catalog, and repaints the whole screen
	;    DISPDIRS	Reloads the catalog and repaints the whole screen without changing the currently selected file
	;    DISP	Repaints the whole screen without reloading anything.
	;    DISP0	Repaints the whole screen except for the "ProDOS File Navigator 3.0 - " at the top
	;    DISPCAT	Clears the main part of the screen (the part not including the header and the menu) and redraws the catalog
	;    DISPCAT2	Redraws the catalog without clearing the screen
	;    KBDLOOP	Don't do anything; just wait for another key to be pressed

PFNSTART:	JSR A80COLON
	LDA #$01
	STA CURRCMD
	JSR DISKSPC
DISPDIR:	LDA #$00
	STA CURRSEL
DISPDIRS:	JSR READDIR	;Read directory
DISP:	JSR TXTUNWDW
	LDX #$00	;First line
	LDY #$00
	JSR SETPOS
	LDX #$A2	;"ProDOS File Navigator 3.0"
	LDY #$60
	JSR PRINTSTR
	LDX #$1D	;" - "
	LDY #$61
	JSR PRINTSTR
DISP0:	JSR CHEKPRFX	;Print the prefix
	BCS DISPDESK
	JSR PRHIST6F
	CLC
	BCC DISP1
DISPDESK:	LDX #$BE
	LDY #$63
	JSR PRINTSTR
DISP1:	JSR A80SPACES
	LDX #$00	;Second line
	LDY #$01
	JSR SETPOS
	LDX #$21	;"Available:"
	LDY #$61
	JSR PRINTSTR
	LDX $19	;K available
	LDY $1A
	JSR PRNMDIV2
	LDX #$F8	;"K"
	LDY #$60
	JSR PRINTSTR
	LDX #$2D	;"Used:"
	LDY #$61
	JSR PRINTSTR
	LDX $1B	;K used
	LDY $1C
	JSR PRNMDIV2
	LDX #$F8	;"K"
	LDY #$60
	JSR PRINTSTR
	LDX #$34	;"Total:"
	LDY #$61
	JSR PRINTSTR
	LDX $1D	;K total
	LDY $1E
	JSR PRNMDIV2
	LDX #$F8	;"K"
	LDY #$60
	JSR PRINTSTR
	JSR A15SPACES
	LDX #$00	;Third line
	LDY #$02
	JSR SETPOS
	JSR A80HYPHEN
	LDX #$00	;Twenty-second line
	LDY #$15
	JSR SETPOS
	JSR A80HYPHEN
	LDX #$00	;Twenty-third line
	LDY #$16
	JSR SETPOS
	LDY #$60	;"(L)ock (U)nlock ..."
	LDA CURRCMD
	CMP #$02
	BEQ CMDLINE2
	LDX #$00
	CLC
	BCC CMDLINE1
CMDLINE2:	LDX #$51
CMDLINE1:	JSR PRINTSTR
	LDX #$00	;Twenty-fourth line
	LDY #$17
	JSR SETPOS
	JSR A78SPACES
	JSR TXTWINDW
DISPCAT:	JSR CLRSCRN
DISPCAT2:	JSR PRINTCAT
KBDLOOP:	JSR GETCHAR
	AND #$7F	;$5F converts high ASCII and/or lowercase to uppercase low ASCII
	CMP #$60	;but it also converts punctuation, numbers, and spaces to control characters
	BCC ISNTUPER	;so instead we use $7F and SBC #$20 if it's over $60.
	SBC #$20
ISNTUPER:	CMP #$41	;A - About
	BNE KBD0
	JMP KABOUT
KBD0:	CMP #$42	;B - Back
	BNE KBD1
	JMP KBACK
KBD1:	CMP #$43	;C - Create
	BNE KBD2
	JMP KCREATE
KBD2:	CMP #$44	;D - Delete
	BNE KBD3
	JMP KDELETE
KBD3:	CMP #$45	;E - Execute
	BNE KBD4
	JMP KEXECUTE
KBD4:	CMP #$46	;F - Refresh
	BNE KBD5
	JMP DISPDIR
KBD5:	CMP #$47	;G -
	BNE KBD6
	JMP KBDLOOP
KBD6:	CMP #$48	;H -
	BNE KBD7
	JMP KBDLOOP
KBD7:	CMP #$49	;I - Info
	BNE KBD8
	JMP KINFO
KBD8:	CMP #$4A	;J -
	BNE KBD9
	JMP KBDLOOP
KBD9:	CMP #$4B	;K -
	BNE KBDA
	JMP KBDLOOP
KBDA:	CMP #$4C	;L - Lock
	BNE KBDB
	JMP KLOCK
KBDB:	CMP #$4D	;M - More
	BNE KBDC
	JMP KMORE
KBDC:	CMP #$4E	;N -
	BNE KBDD
	JMP KBDLOOP
KBDD:	CMP #$4F	;O - Online
	BNE KBDE
	JMP KONLINE
KBDE:	CMP #$50	;P - Prefix
	BNE KBDF
	JMP KPREFIX
KBDF:	CMP #$51	;Q - Quit
	BNE KBDG
	JMP PFNQUIT
KBDG:	CMP #$52	;R - Rename
	BNE KBDH
	JMP KRENAME
KBDH:	CMP #$53	;S - Paste
	BNE KBDI
	JMP KPASTE
KBDI:	CMP #$54	;T - Change Type
	BNE KBDJ
	JMP KCHGTYPE
KBDJ:	CMP #$55	;U - Unlock
	BNE KBDK
	JMP KUNLOCK
KBDK:	CMP #$56	;V - View
	BNE KBDL
	JMP KVIEW
KBDL:	CMP #$57	;W -
	BNE KBDM
	JMP KBDLOOP
KBDM:	CMP #$58	;X -
	BNE KBDN
	JMP KBDLOOP
KBDN:	CMP #$59	;Y - Copy
	BNE KBDO
	JMP KCOPY
KBDO:	CMP #$5A	;Z -
	BNE KBDP
	JMP KBDLOOP
KBDP:	CMP #$0B	;Up
	BNE KBDQ
	JMP KUPP
KBDQ:	CMP #$0A	;Down
	BNE KBDR
	JMP KDOWN
KBDR:	CMP #$08	;Left
	BNE KBDS
	JMP KLEFT
KBDS:	CMP #$15	;Right
	BNE KBDT
	JMP KRIGHT
KBDT:	CMP #$0D	;Return
	BNE KBDU
	JMP KEXEKUTE
KBDU:	CMP #$1B	;Escape
	BNE KBDV
	JMP KBACK
KBDV:	CMP #$20	;Space
	BNE KBDW
	JMP KVIEW
KBDW:	CMP #$21	;!
	BNE KBDX
	JMP KRSTDISP
KBDX:	JMP KBDLOOP	;Wait for another keypress if we didn't understand that one

READDIR:	JSR CLEARBUF	;Read the directory into $6800, read disk space into $19-$1E (avail, used, total)
	JSR CHEKPRFX
	BCS READONLN
	JMP READDIRF
READONLN:	JSR $BF00	;Read list of online disks
	.byte $C5
	.byte <ONLNPARM
	.byte >ONLNPARM
	LDX #$00
	STX NUMFILES	;$D7 is number of disks
	STX $06	;$06/$07 is address in buffer
	STX $CE	;$CE/$CF is address in catalog
	LDX #$20
	STX $07
	LDX #$68
	STX $CF
RDOLLOOP:	LDY #$00
	LDA ($06),Y
	AND #$0F
	BEQ RDOLSKIP
	ORA #$F0
	STA ($CE),Y
	INC NUMFILES
	LDY #$0F
RDOLLP1:	LDA ($06),Y
	STA ($CE),Y
	DEY
	BNE RDOLLP1
	LDY #$10
	LDA #$E3
	STA ($CE),Y
	INY
	LDA #$0E
	STA ($CE),Y
	INY
	LDA #$00
RDOLLP2:	STA ($CE),Y
	INY
	CPY #$20
	BCC RDOLLP2
	LDA $CE
	CLC
	ADC #$20
	STA $CE
	BNE RDOLSKIP
	INC $CF
RDOLSKIP:	LDA $06
	CLC
	ADC #$10
	STA $06
	BNE RDOLLOOP
	LDA #$00
	STA $19
	STA $1A
	STA $1B
	STA $1C
	STA $1D
	STA $1E
	RTS
READDIRF:	LDX #$00	;Read current directory
	STX OPDRREF
	JSR $BF00	;open directory
	.byte $C8
	.byte <OPDRPARM
	.byte >OPDRPARM
	LDX OPDRREF
	STX RDDRREF
	STX CLDRREF
	STX NWLNREF
	LDX #$00
	STX RDDRXFER
	STX RDDRXFR2
	JSR $BF00	;disable newline mode
	.byte $C9
	.byte <NWLNPARM
	.byte >NWLNPARM
	JSR $BF00	;read directory
	.byte $CA
	.byte <RDDRPARM
	.byte >RDDRPARM
	JSR $BF00	;close directory
	.byte $CC
	.byte <CLDRPARM
	.byte >CLDRPARM
	LDX #$00
	STX NUMFILES	;$D7 is number of files
	STX $E3	;$E3 is offset in catalog extension
	STX $CE	;$CE/$CF is address in catalog
	LDX #$68
	STX $CF
	LDX #$2B	;$06/$07 is address in buffer
	STX $06
	LDX #$20
	STX $07
RDDRLOOP:	LDY #$00
	LDA ($06),Y
	AND #$F0
	BEQ RDDRSKIP	;This file has a storage type of zero, which means it's either past the directory's eof or a deleted file
	INC NUMFILES	;increase file count
	JSR XFERFREF	;transfer from buffer to catalog; handy routine does all this for us
	INC $E3
	INC $E3
	INC $E3
	INC $E3
	LDA $CE
	CLC
	ADC #$20
	STA $CE
	BNE RDDRSKIP
	INC $CF
RDDRSKIP:	LDA $06
	CLC
	ADC #$27
	STA $06
	BCC RDDRNOOV	;ReaD DiR NO OVerflow
	INC $07
RDDRNOOV:	LDA $06
	CMP #$FF
	BNE RDDRNONB	;ReaD DiR NO advance to Next Block
	LDA #$04
	STA $06
	INC $07
RDDRNONB:	LDA $07
	CMP #$30
	BCS RDDREXIT	;Exit if we're WAY out there!
	LDA NUMFILES
	CMP #$37
	BCS RDDREXIT	;We have 54 files already; exit.
	BCC RDDRLOOP	;Else go back and get another file.
RDDREXIT:	RTS

DISKSPC:	JSR CHEKPRFX
	BCC DSKSPCOK
DSFIRESC:	LDA #$00	;Disk Space FIRe ESCape!?!?!
	STA $19
	STA $1A
	STA $1B
	STA $1C
	STA $1D
	STA $1E
	RTS
DSKSPCOK:	LDX #$01
DSKSPLP1:	INX
	LDA $6F00,X
	AND #$7F
	CMP #$2F
	BNE DSKSPLP1
	DEX
	STX $6F00
	LDX #$00	;Read current directory
	STX OPDRREF
	JSR $BF00	;open directory
	.byte $C8
	.byte <OPDRPARM
	.byte >OPDRPARM
	LDX OPDRREF
	STX RDDRREF
	STX CLDRREF
	STX NWLNREF
	LDX #$00
	STX RDDRXFER
	STX RDDRXFR2
	JSR $BF00	;disable newline mode
	.byte $C9
	.byte <NWLNPARM
	.byte >NWLNPARM
	JSR $BF00	;read directory
	.byte $CA
	.byte <RDDRPARM
	.byte >RDDRPARM
	JSR $BF00	;close directory
	.byte $CC
	.byte <CLDRPARM
	.byte >CLDRPARM
	LDA #$00
	STA $19
	STA $1A
	STA $1B
	STA $1C
	LDA $2029
	STA $1D
	STA $CE
	LDA $202A
	STA $1E
	STA $CF
	LDA $2027
	STA $06
	LDA $2028
	STA $07	;$06 now contains the block number of the first block of the volume bit map
	LDA #$00
	STA $FE
	LSR $CF
	ROR $CE
	ROR $FE
	LSR $CF
	ROR $CE
	ROR $FE
	LSR $CF
	ROR $CE
	ROR $FE
	LDA $FE
	BEQ NOINCCE
	INC $CE
	BNE NOINCCE
	INC $CF	;$CE now contains the number of bytes in the volume bit map
NOINCCE:	LDA $CF
	LSR
	STA $E3	;$E3 now contains the number of blocks in the volume bit map, minus one
	JSR FINDDEVN
	BNE DEVFOUND
	RTS
DEVFOUND:	STA RDBLKDEV
	LDA $06
	STA RDBLKNUM
	LDA $07
	STA RDBLKNUM+1
	LDA #$00
	STA RDBLKBFR
	LDA #$20
	STA RDBLKBFR+1
DSKSPCLP:	JSR $BF00
	.byte $80
	.byte <RDBLKPRM
	.byte >RDBLKPRM
	INC RDBLKBFR+1
	INC RDBLKBFR+1
	INC RDBLKNUM
	BNE NOINCBLK
	INC RDBLKNUM+1
NOINCBLK:	DEC $E3
	BPL DSKSPCLP
	LDA #$00
	STA $06
	LDA #$20
	STA $07
	LDA $CF
	CLC
	ADC #$20
	STA $CF
	LDY #$00
DSLOOP1:	LDX #$08
	LDA ($06),Y
DSLOOP2:	ASL
	BCC BLKDONE
	INC $19
	BNE BLKDONE
	INC $1A
BLKDONE:	DEX
	BNE DSLOOP2	
	INY
	BNE DSNOINCB
	INC $07
DSNOINCB:	LDA $07
	CMP $CF
	BCC DSLOOP1
	CPY $CE
	BCC DSLOOP1
	SEC
	LDA $1D
	SBC $19
	STA $1B
	LDA $1E
	SBC $1A
	STA $1C
	RTS

FINDDEVN:	LDY #$00	;Find device number of the disk whose name or path appears in $6F00
	STY $FA
	STY $FC
	LDY #$6F
	STY $FB
	LDY #$20
	STY $FD
	LDX $6F00
	LDA $6F00,X
	AND #$7F
	CMP #$2F
	BNE FDEVN0
	DEX
	STX $6F00
FDEVN0:	LDA $6F01
	AND #$7F
	CMP #$2F
	BNE FDEVN1
	LDY $6F00
	DEY
	STY $6F01
	LDY #$01
	STY $FA
FDEVN1:	JSR CLEARBUF
	JSR $BF00
	.byte $C5
	.byte <ONLNPARM
	.byte >ONLNPARM
FDEVNLP:	LDY #$00
	LDA ($FC),Y
	TAX
	AND #$0F
	STA ($FC),Y
	JSR STREQI
	BEQ FDEVDONE
	LDA $FC
	CLC
	ADC #$10
	STA $FC
	BCC FDEVNLP
	LDX #$00
FDEVDONE:	TXA
	RTS

ONLNPARM:	.byte $02
	.byte $00
	.byte <IOBUFFER
	.byte >IOBUFFER
OPDRPARM:	.byte $03
	.byte <PATHBFR
	.byte >PATHBFR
	.byte <IOBUFF
	.byte >IOBUFF
OPDRREF:	.byte $00
RDDRPARM:	.byte $04
RDDRREF:	.byte $00
	.byte <IOBUFFER
	.byte >IOBUFFER
	.byte $00
	.byte $10
RDDRXFER:	.byte $00
RDDRXFR2:	.byte $00
CLDRPARM:	.byte $01
CLDRREF:	.byte $00
RDBLKPRM:	.byte $03
RDBLKDEV:	.byte $00
RDBLKBFR:	.byte $00
	.byte $00
RDBLKNUM:	.byte $00
	.byte $00

PRINTCAT:	LDA NUMFILES	;Print the catalog in $6800
	CMP #$37
	BCC PRCATOK
	LDA #$36
	STA NUMFILES
PRCATOK:	CLC
	LDX NUMFILES
	DEX
	BMI PRCATEND
	LDX #$00
PRCTLOOP:	STX $FE
	JSR PRINTITM
	LDX $FE
	INX
	CPX NUMFILES
	BNE PRCTLOOP
PRCATEND:	RTS

PRINTITM:	STX $E3	;Print a single file name, with index in X (X must be preserved!)
	CPX #$36	;Uses: $E3, $06, $CE, $CF
	BCC PRITMOK
	RTS
PRITMOK:	LDX $E3
	CPX CURRSEL
	BNE NOTSEL
	JSR INVERSE
	CLC
	BCC PRITM2
NOTSEL:	JSR NORMAL
PRITM2:	LDA $E3	;Determine cursor position
	CLC
	JSR DIV18
	CLC
	JSR MUL21
	STA $06
	LDA $E3
	CLC
	JSR MOD18
	CLC
	ADC #$03
	TAY
	LDX $06
	JSR SETPOS
	LDX $E3	;Determine address of file entry
	JSR GETFADDR	;At this point, $CE contains the address of the file's entry in $6800-$6EFF
	LDY #$10
	LDA ($CE),Y
	AND #$02
	BEQ PRCATLKD
	LDA #$A0
	JSR $FDED
	CLC
	BCC PRCATULK
PRCATLKD:	LDA #$AA
	JSR $FDED
PRCATULK:	LDX $CE
	LDY $CF
	JSR PRSTR16
	LDY #$00
	LDA ($CE),Y
	AND #$0F
	TAX
PRILOOP1:	CPX #$10
	BEQ PRILP1XT
	STX $06
	LDA #$A0
	JSR $FDED
	LDX $06
	INX
	CLC
	BCC PRILOOP1
PRILP1XT:	LDY #$11
	LDA ($CE),Y
	TAX
	JSR PRINTYPE
	JSR NORMAL	;If we leave the text inverted, the inversion will go willy-nilly everywhere
	LDX $E3
	RTS

KLOCK:	LDA NUMFILES
	BNE KLOCKOK
	JMP KBDLOOP
KLOCKOK:	JSR CHEKPRFX	;Make sure we're on a disk and not at the ONLINE level
	BCC KLKPFXOK
	JMP KBDLOOP
KLKPFXOK:	JSR GETNAME	;Lock a file
	LDA #$0A	;get file info
	STA FINFPARM
	JSR $BF00
	.byte $C4
	.byte <FINFPARM
	.byte >FINFPARM
	LDA FINFACC	;get access byte
	AND #$3D	;mask out rename, delete, write
	STA FINFACC	;set access byte
	LDA #$07	;set file info
	STA FINFPARM
	JSR $BF00
	.byte $C3
	.byte <FINFPARM
	.byte >FINFPARM
	JMP DISPDIRS

KUNLOCK:	LDA NUMFILES
	BNE KUNLCKOK
	JMP KBDLOOP
KUNLCKOK:	JSR CHEKPRFX	;Make sure we're on a disk and not at the ONLINE level
	BCC KULPFXOK
	JMP KBDLOOP
KULPFXOK:	JSR GETNAME	;Unlock a file
	LDA #$0A	;get file info
	STA FINFPARM
	JSR $BF00
	.byte $C4
	.byte <FINFPARM
	.byte >FINFPARM
	LDA FINFACC	;get access byte
	ORA #$C2	;mask IN rename, delete, write
	STA FINFACC	;set access byte
	LDA #$07	;set file info
	STA FINFPARM
	JSR $BF00
	.byte $C3
	.byte <FINFPARM
	.byte >FINFPARM
	JMP DISPDIRS

KRENAME:	LDA NUMFILES
	BNE KRENAMOK
	JMP KBDLOOP
KRENAMOK:	JSR CHEKPRFX
	BCC KRENOK
	LDX #$3C	;Rename a disk
	LDY #$61	;"New File Name:"
	LDA #$0F	;15 dots
	JSR PFNPRMPT
	LDX $6F00
	BNE KREND2
	JMP KBDLOOP
KREND2:	INX	;move new name from $6F00 to $2000
	STX $2000
	LDA #$2F
	STA $2001
	DEX
KRENDLP:	LDA $6F00,X
	STA $2001,X
	DEX
	BNE KRENDLP
	JSR GETPATH
	JSR $BF00
	.byte $C2
	.byte <KRENPARM
	.byte >KRENPARM
	JMP DISPDIR
KRENOK:	LDX #$3C	;Rename a file
	LDY #$61	;"New File Name:"
	LDA #$0F	;15 dots
	JSR PFNPRMPT
	LDX $6F00
	BNE KREN2
	JMP KBDLOOP
KREN2:	LDX #$12	;move new name from $6F00 to $2000
KRENLOOP:	LDA $6EFF,X
	STA $1FFF,X
	DEX
	BNE KRENLOOP
	JSR GETNAME	;get old name in $6F00
	JSR $BF00
	.byte $C2
	.byte <KRENPARM
	.byte >KRENPARM
	JMP DISPDIRS
KRENPARM:	.byte $02	;MLI parameter template for RENAME call
	.byte $00
	.byte $6F
	.byte $00
	.byte $20

KDELETE:	LDA NUMFILES
	BNE KDELTEOK
	JMP KBDLOOP
KDELTEOK:	JSR CHEKPRFX	;Make sure we're on a disk and not at the ONLINE level
	BCC KDLPFXOK
	JMP KBDLOOP
KDLPFXOK:	LDX #$7D	;Delete a file
	LDY #$61	;"Are you sure? (Y/N):"
	LDA #$00	;No dots
	JSR PFNPRMPT
	LDA $6F01	;6F01 is the first character
	AND #$5F
	CMP #$59
	BEQ KDEL2
	JMP KBDLOOP
KDEL2:	JSR GETNAME	;delete the file
	JSR $BF00
	.byte $C1
	.byte <DELPARM
	.byte >DELPARM
	JSR DISKSPC
	JMP DISPDIR
DELPARM:	.byte $01	;MLI parameter list template for DELETE call
	.byte <PATHBFR
	.byte >PATHBFR

KCREATE:	JSR CHEKPRFX	;Make sure we're on a disk and not at the ONLINE level
	BCC KCRPFXOK
	JMP KBDLOOP
KCRPFXOK:	LDX #$4C	;Create a directory
	LDY #$61	;"Name of New Directory:"
	LDA #$0F	;15 dots
	JSR PFNPRMPT
	LDX $6F00
	BNE KCREA2
	JMP KBDLOOP
KCREA2:	JSR $BF00
	.byte $C0
	.byte <KCREPARM
	.byte >KCREPARM
	JSR DISKSPC
	JMP DISPDIR
KCREPARM:	.byte $07	;MLI parameter template for CREATE call
	.byte $00	;path name
	.byte $6F
	.byte $E3	;access
	.byte $0F	;file type
	.byte $00	;aux type
	.byte $00
	.byte $0D	;storage type
	.byte $00	;create date
	.byte $00
	.byte $00	;create time
	.byte $00

KVIEW:	LDA NUMFILES
	BNE KVIEWOK
	JMP KBDLOOP
KVIEWOK:	JSR CHEKPRFX	;Make sure we're on a disk and not at the ONLINE level
	BCC KVWPFXOK
	JMP KBDLOOP
KVWPFXOK:	LDX CURRSEL	;View a file
	JSR GETFADDR
	LDY #$11
	LDA ($CE),Y
	CMP #$04
	BNE KVWNOTTX
	JMP KVIEWTXT
KVWNOTTX:	CMP #$06
	BNE KVWNOTBI
	JMP KVIEWBIN
KVWNOTBI:	JMP KBDLOOP

KVIEWTXT:	JSR CLRBUF2	;View a TXT file
	LDY #$00
	STY BFLBUFFL
	LDY #$19
	STY BFLBUFFH
	JSR GETPATH
	JSR $BF00
	.byte $C8	;OPEN
	.byte <BFLOPEN
	.byte >BFLOPEN
	LDX BFLOPREF
	STX BFLNLREF
	STX BFLRDREF
	STX BFLCLREF
	STX BFLGEREF
	JSR $BF00
	.byte $D1	;GET EOF
	.byte <BFLGTEOF
	.byte >BFLGTEOF
	LDX BFLEOF
	LDY BFLEOF+1
	CPY #$27
	BCC NOTLONG
	LDX #$FF
	LDY #$26
NOTLONG:	STX BFLREQCT
	STY BFLREQCT+1
	JSR $BF00
	.byte $C9	;NEWLINE
	.byte <BFLNEWLN
	.byte >BFLNEWLN
	JSR $BF00
	.byte $CA	;READ
	.byte <BFLREAD
	.byte >BFLREAD
	JSR $BF00
	.byte $CC	;CLOSE
	.byte <BFLCLOSE
	.byte >BFLCLOSE
	JSR SCANTEXT
	JSR CLRSCRN
	JSR TEXTADDR
	JSR TEXTDISP
TKBDLOOP:	JSR GETCHAR
	AND #$7F
	CMP #$0B
	BNE TKBD1
TKBD0E:	LDA $ED
	BNE TKBD00
	LDA $EC
	BNE TKBD00
	JMP TKBDLOOP
TKBD00:	DEC $EC
	LDA $EC
	CMP #$FF
	BNE TKBD000
	DEC $ED
TKBD000:	LDX #$00
	LDY #$03
	JSR SETPOS
	;JSR CLRSCRN
	JSR TEXTADDR
	JSR TEXTDISP
	JMP TKBDLOOP
TKBD1:	CMP #$0A
	BNE TKBD2
TKBD1E:	LDA $ED
	CMP $EF
	BNE TKBD11
	LDA $EC
	CMP $EE
	BNE TKBD11
	JMP TKBDLOOP
TKBD11:	INC $EC
	LDA $EC
	CMP #$00
	BNE TKBD111
	INC $ED
TKBD111:	LDX #$00
	LDY #$03
	JSR SETPOS
	;JSR CLRSCRN
	JSR TEXTADDR
	JSR TEXTDISP
	JMP TKBDLOOP
TKBD2:	CMP #$08
	BNE TKBD3
	LDA #$00
	STA $EC
	STA $ED
	LDX #$00
	LDY #$03
	JSR SETPOS
	;JSR CLRSCRN
	JSR TEXTADDR
	JSR TEXTDISP
	JMP TKBDLOOP
TKBD3:	CMP #$15
	BNE TKBD4
	LDA $EE
	STA $EC
	LDA $EF
	STA $ED
	LDX #$00
	LDY #$03
	JSR SETPOS
	;JSR CLRSCRN
	JSR TEXTADDR
	JSR TEXTDISP
	JMP TKBDLOOP
TKBD4:	JMP DISP

KVIEWBIN:	JSR GETNAME	;View a BIN file
	LDY #$00
	STY BFLBUFFL
	STY BFLREQCT
	LDY #$16
	LDA ($CE),Y
	BEQ ISGRAF
	JMP KBDLOOP
ISGRAF:	LDY #$15
	LDA ($CE),Y
	CMP #$03
	BEQ QISGR
	CMP #$04
	BEQ QISGR
	CMP #$05
	BEQ QISDGR
	CMP #$06
	BEQ QISDGR
	CMP #$11
	BEQ QISHGR
	CMP #$12
	BEQ QISHGR
	CMP #$21
	BEQ QISDHR
	CMP #$22
	BEQ QISDHR
	JMP KBDLOOP
QISHGR:	STA $C057
	LDY #$20
	STY BFLBUFFH
	STY BFLREQCT+1
	JMP ISHGR
QISDHR:	STA $C057
	LDY #$20
	STY BFLBUFFH
	STY BFLREQCT+1
	JMP ISDHR
QISGR:	STA $C056
	LDY #$08
	STY BFLBUFFH
	LDY #$04
	STY BFLREQCT+1
	JMP ISGR
QISDGR:	STA $C056
	LDY #$08
	STY BFLBUFFH
	LDY #$04
	STY BFLREQCT+1
	JMP ISDGR
ISHGR:	JSR $BF00
	.byte $C8	;OPEN
	.byte <BFLOPEN
	.byte >BFLOPEN
	LDX BFLOPREF
	STX BFLNLREF
	STX BFLRDREF
	STX BFLCLREF
	JSR $BF00
	.byte $C9	;NEWLINE
	.byte <BFLNEWLN
	.byte >BFLNEWLN
	JSR $BF00
	.byte $CA	;READ
	.byte <BFLREAD
	.byte >BFLREAD
	JSR HIRESGR
	JMP GRLOADED
ISGR:	JSR $BF00
	.byte $C8	;OPEN
	.byte <BFLOPEN
	.byte >BFLOPEN
	LDX BFLOPREF
	STX BFLNLREF
	STX BFLRDREF
	STX BFLCLREF
	JSR $BF00
	.byte $C9	;NEWLINE
	.byte <BFLNEWLN
	.byte >BFLNEWLN
	JSR $BF00
	.byte $CA	;READ
	.byte <BFLREAD
	.byte >BFLREAD
	JSR XFERGR
	JSR LOWRESGR
	JMP GRLOADED
ISDHR:	JSR $BF00
	.byte $C8	;OPEN
	.byte <BFLOPEN
	.byte >BFLOPEN
	LDX BFLOPREF
	STX BFLNLREF
	STX BFLRDREF
	STX BFLCLREF
	JSR $BF00
	.byte $C9	;NEWLINE
	.byte <BFLNEWLN
	.byte >BFLNEWLN
	JSR $BF00
	.byte $CA	;READ
	.byte <BFLREAD
	.byte >BFLREAD
	JSR XFERAUXH	;Transfer main $2000 to auxiliary $2000
	JSR $BF00
	.byte $CA	;READ
	.byte <BFLREAD
	.byte >BFLREAD
	LDA #$02
	JSR $FCA8
	JSR DBLHIRES
	JMP GRLOADED
ISDGR:	JSR $BF00
	.byte $C8	;OPEN
	.byte <BFLOPEN
	.byte >BFLOPEN
	LDX BFLOPREF
	STX BFLNLREF
	STX BFLRDREF
	STX BFLCLREF
	JSR $BF00
	.byte $C9	;NEWLINE
	.byte <BFLNEWLN
	.byte >BFLNEWLN
	JSR $BF00
	.byte $CA	;READ
	.byte <BFLREAD
	.byte >BFLREAD
	JSR XFERGRA	;Transfer main $800 to auxiliary $400 (preserving screen holes)
	JSR $BF00
	.byte $CA	;READ
	.byte <BFLREAD
	.byte >BFLREAD
	JSR XFERGR	;Transfer main $800 to main $400 (preserving screen holes)
	LDA #$02
	JSR $FCA8
	JSR DBLOWRES
GRLOADED:	JSR $BF00
	.byte $CC	;CLOSE
	.byte <BFLCLOSE
	.byte >BFLCLOSE
	JSR GETCHAR
	JSR MAINMEM
	JSR TEXT
	JSR TXTUNWDW
	JSR CLRSCRN
	JMP DISP

KEXEKUTE:	LDA NUMFILES	;EXEKUTE is a smaller version of EXECUTE that will only open directories or SYS files.
	BNE KEXEKOK	;It is called by pressing Return. By using EXEKUTE for Return instead of EXECUTE,
	JMP KBDLOOP	;We can be sure we're not inadvertently executing BIN files or other files we don't want.
KEXEKOK:	JSR CHEKPRFX	;EXEKUTE calls the same routines as EXECUTE to actually execute the files.
	BCC KEXEDSK
	JSR GETPATHD
	JSR SETPRFX
	JSR DISKSPC
	JMP DISPDIR
KEXEDSK:	LDX CURRSEL
	JSR GETFADDR
	LDY #$11
	LDA ($CE),Y
	CMP #$0F	;Check for DIR
	BNE KEXENTD
	JMP KEXEDIR
KEXENTD:	CMP #$FF	;Check for SYS
	BNE KEXENTS
	JMP KEXESYS
KEXENTS:	CMP #$66	;Check for NCF (Navigator Command File)
	BNE KEXENTK
	JMP KEXEBIN
KEXENTK:	JMP KBDLOOP

KEXECUTE:	LDA NUMFILES	;EXECUTE will execute a wide variety of files. It is called by pressing E.
	BNE KEXECOK
	JMP KBDLOOP
KEXECOK:	JSR CHEKPRFX	;Check to see if we're at the ONLINE level or on a disk somewhere
	BCC KEXEDISK
	JSR GETPATHD	;Open a disk
	JSR SETPRFX	;Set prefix
	JSR DISKSPC
	JMP DISPDIR
KEXEDISK:	LDX CURRSEL	;Run a file or open a directory
	JSR GETFADDR
	LDY #$11
	LDA ($CE),Y
	CMP #$0F	;Check for DIR
	BNE KEXENOTD
	JMP KEXEDIR
KEXENOTD:	CMP #$FF	;Check for SYS
	BNE KEXENOTS
	JMP KEXESYS
KEXENOTS:	CMP #$06	;Check for BIN
	BNE KEXENOTB
	JMP KEXEBIN
KEXENOTB:	CMP #$66	;Check for NCF (Navigator Command File)
	BNE KEXENOTK
	JMP KEXEBIN
KEXENOTK:	JMP KBDLOOP

KEXEDIR:	JSR GETPATH0	;Open a directory
	LDX $6F00
	INX
	STX $6F00	;Set incremented count byte
	LDA #$2F	;Insert end slash
	STA $6F00,X
	JSR SETPRFX	;Set prefix
	JMP DISPDIR

KEXESYS:	JSR GETPATH	;Run a SYS file
	JMP $1800	;$1800 is SYS file loader

KEXEBIN:	JSR GETFADDR	;Run a BIN file
	LDY #$12
	LDA ($CE),Y
	STA BFLBUFFL
	INY
	LDA ($CE),Y
	STA BFLBUFFH
	JSR GETPATH
	JSR $BF00
	.byte $C8	;OPEN
	.byte <BFLOPEN
	.byte >BFLOPEN
	BCS BFLERROR
	LDX BFLOPREF
	STX BFLNLREF
	STX BFLRDREF
	STX BFLCLREF
	STX BFLGEREF
	JSR $BF00
	.byte $D1	;GET EOF
	.byte <BFLGTEOF
	.byte >BFLGTEOF
	BCS BFLERROR
	LDX BFLEOF
	LDY BFLEOF+1
	STX BFLREQCT
	STY BFLREQCT+1
	JSR $BF00
	.byte $C9	;NEWLINE
	.byte <BFLNEWLN
	.byte >BFLNEWLN
	BCS BFLERROR
	JSR $BF00
	.byte $CA	;READ
	.byte <BFLREAD
	.byte >BFLREAD
	BCS BFLERROR
	JSR $BF00
	.byte $CC	;CLOSE
	.byte <BFLCLOSE
	.byte >BFLCLOSE
	BCS BFLERROR
	JSR BFLPSCTL
	JMP DISP
BFLPSCTL:	JMP (BFLBUFFL)
BFLERROR:	JSR $BF00
	.byte $CC	;CLOSE
	.byte <BFLCLOSE
	.byte >BFLCLOSE
	JMP KBDLOOP

BFLOPEN:	.byte $03
	.byte $00
	.byte $6F
	.byte <IOBUFF
	.byte >IOBUFF
BFLOPREF:	.byte $00
BFLNEWLN:	.byte $03
BFLNLREF:	.byte $00
	.byte $00
	.byte $00
BFLREAD:	.byte $04
BFLRDREF:	.byte $00
BFLBUFFL:	.byte $00
BFLBUFFH:	.byte $00
BFLREQCT:	.byte $00
	.byte $00
	.byte $00
	.byte $00
BFLCLOSE:	.byte $01
BFLCLREF:	.byte $00
BFLGTEOF:	.byte $02
BFLGEREF:	.byte $00
BFLEOF:	.byte $00
	.byte $00
	.byte $00

KINFO:	LDA NUMFILES
	BNE KINFOOK
	JMP KBDLOOP
KINFOOK:	JSR CHEKPRFX
	BCC KINFOOK2
	JMP KBDLOOP
KINFOOK2:	LDX CURRSEL	;View file info
	JSR GETFADDR
	JSR CLRSCRN
	LDX #$93	;"Info for"
	LDY #$61
	JSR PRINTSTR
	LDX $CE	;the file name
	LDY $CF
	JSR PRHISTXY
	JSR PRINTCR
	JSR PRINTCR
	LDX #$9D	;"Locked:"
	LDY #$61
	JSR PRINTSTR
	LDY #$10
	LDA ($CE),Y
	AND #$02
	BEQ KINFOLKD
	LDX #$A6	;"No"
	CLC
	BCC KINFOULK
KINFOLKD:	LDX #$A9	;"Yes"
KINFOULK:	LDY #$61
	JSR PRINTSTR
	JSR PRINTCR
	LDX #$AD	;"File"
	LDY #$61
	JSR PRINTSTR
	LDX #$B6	;"Type:"
	LDY #$61
	JSR PRINTSTR
	LDY #$11	;the file type
	LDA ($CE),Y
	TAX
	JSR PRINTYPE	;"SYS", "BIN", etc.
	LDX #$00
	LDY #$63
	JSR PRINTSTR	;" ("
	LDA $6500
	JSR $FDED	;"$"
	LDY #$11
	LDA ($CE),Y
	JSR $FDDA	;the file type in hex
	LDX #$03
	LDY #$63
	JSR PRINTSTR	;")"
	JSR PRINTCR
	LDX #$B2	;"Aux"
	LDY #$61
	JSR PRINTSTR
	LDX #$B6	;"Type:"
	LDY #$61
	JSR PRINTSTR
	LDA #$A4	;"$"
	JSR $FDED
	LDY #$12	;the aux type
	LDA ($CE),Y
	STA $FE
	LDY #$13
	LDA ($CE),Y
	TAY
	LDX $FE
	JSR $F940
	JSR PRINTCR
	LDX #$BE	;"Blocks:"
	LDY #$61
	JSR PRINTSTR
	LDY #$15	;the number of blocks
	LDA ($CE),Y
	STA $FE
	LDY #$16
	LDA ($CE),Y
	TAY
	LDX $FE
	JSR PRINTNUM
	JSR PRINTCR
	LDX #$DC	;"Bytes:"
	LDY #$61
	JSR PRINTSTR
	LDA CURRSEL
	ASL
	ASL
	TAX
	LDA $0E01,X
	TAY
	LDA $0E00,X
	TAX
	JSR PRINTNUM
	JSR PRINTCR
	LDX #$C7	;"Modified:"
	LDY #$61
	JSR PRINTSTR
	LDY #$17	;Modification date
	LDA ($CE),Y
	STA $FA
	INY
	LDA ($CE),Y
	STA $FB
	INY
	LDA ($CE),Y
	STA $FC
	INY
	LDA ($CE),Y
	STA $FD
	JSR PRDATIME
	JSR PRINTCR
	LDX #$D2	;"Created:"
	LDY #$61
	JSR PRINTSTR
	LDY #$1B	;Creation date
	LDA ($CE),Y
	STA $FA
	INY
	LDA ($CE),Y
	STA $FB
	INY
	LDA ($CE),Y
	STA $FC
	INY
	LDA ($CE),Y
	STA $FD
	JSR PRDATIME
	JSR PRINTCR
	JSR PRINTCR
	LDX #$E4	;"Press any key to continue."
	LDY #$61
	JSR PRINTSTR
	JSR GETCHAR
	JMP DISPCAT

KCHGTYPE:	LDA NUMFILES
	BNE KCHTYPOK
	JMP KBDLOOP
KCHTYPOK:	JSR CHEKPRFX	;Make sure we're on a disk and not at the ONLINE level
	BCC KCTPFXOK
	JMP KBDLOOP
KCTPFXOK:	JSR GETNAME	;Change a file's type
	LDA #$0A	;get file info
	STA FINFPARM
	JSR $BF00
	.byte $C4
	.byte <FINFPARM
	.byte >FINFPARM
	LDA FINFTYPE
	CMP #$0F
	BNE KCTNODIR
	JMP KBDLOOP	;don't allow changing the type if it's a directory
KCTNODIR:	LDX #$0A
	LDY #$66
	LDA #$02
	JSR PFNPRMPT
	LDA $6F00
	BEQ NOCHGFT
	JSR HEXSTRNG
	LDA $EF
	STA FINFTYPE
NOCHGFT:	LDX #$1B
	LDY #$66
	LDA #$04
	JSR PFNPRMPT
	LDA $6F00
	BEQ NOCHGAT
	JSR HEXSTRNG
	LDA $EF
	STA FINFAUX
	LDA $EE
	STA FINFAUX+1
NOCHGAT:	JSR GETNAME	;we need to get the file name again because it was overwritten by PFNPRMPT
	LDA #$07	;set file info
	STA FINFPARM
	JSR $BF00
	.byte $C3
	.byte <FINFPARM
	.byte >FINFPARM
	JMP DISPDIRS

KMORE:	LDA CURRCMD	;Switch to second list of commands
	CMP #$02
	BEQ KMORE2
	LDA #$02
	STA CURRCMD
	CLC
	BCC KMORE3
KMORE2:	LDA #$01
	STA CURRCMD
KMORE3:	JSR TXTUNWDW
	LDX #$00	;Twenty-third line
	LDY #$16
	JSR SETPOS
	LDY #$60	;"(L)ock (U)nlock ..."
	LDA CURRCMD
	CMP #$02
	BEQ KMORE4
	LDX #$00
	CLC
	BCC KMORE5
KMORE4:	LDX #$51
KMORE5:	JSR PRINTSTR
	JSR TXTWINDW
	JMP KBDLOOP

KCOPY:	LDA NUMFILES
	BNE KCOPYOK
	JMP KBDLOOP
KCOPYOK:	JSR CHEKPRFX	;Make sure we're on a disk and not at the ONLINE level
	BCC KCPPFXOK
	JMP KBDLOOP
KCPPFXOK:	LDX CURRSEL	;Copy a file
	JSR GETFADDR
	LDY #$11	;the file type
	LDA ($CE),Y
	CMP #$0F
	BNE KCOPYNDR
	JMP KBDLOOP
KCOPYNDR:	LDY #$1F
KCOPYLP1:	LDA ($CE),Y
	STA $DE0,Y
	DEY
	BPL KCOPYLP1
	JSR GETPATH
	LDX $6F00
	STX $D00
KCOPYLP2:	LDA $6F00,X
	STA $D00,X
	DEX
	BNE KCOPYLP2
	JSR SMILE
	JMP KBDLOOP

KPASTE:	JSR CHEKPRFX	;Make sure we're on a disk and not at the ONLINE level
	BCC KPSPFXOK
	JMP KBDLOOP
KPSPFXOK:	LDA $D00	;Copy a file
	BNE KPASTEOK
	JMP KBDLOOP
KPASTEOK:	JSR GETPRFX
	LDX $6F00	;Get path of pasted file; prefix is already in $6F00
	LDA $6F00,X
	AND #$7F	;Check last char
	CMP #$2F
	BEQ KPASTE1	;If it's a slash, skip this stuff
	LDA #$2F
	INX	;Increment count byte
	STA $6F00,X	;Add slash
	STX $6F00
KPASTE1:	LDY #$01
KPASTELP:	LDX $6F00	;Add it to the end of the prefix
	INX
	STX $6F00
	LDA $0DE0,Y
	STA $6F00,X
	TYA
	LDY #$00
	CMP $0DE0,Y
	BCS KPASTELE	;Branch to the end of the routine if we've reached the end of the file name
	TAY
	INY
	CLC
	BCC KPASTELP
KPASTELE:	LDA $0DF1	;OK, so now our source path is in $D00 and our destination path is in $6F00
	STA CCREFTYP
	LDA $0DF2
	STA CCREATYP
	LDA $0DF3
	STA CCREATYQ
	LDA $0DFB
	STA CCREDAT1
	LDA $0DFC
	STA CCREDAT2
	LDA $0DFD
	STA CCREDAT3
	LDA $0DFE
	STA CCREDAT4
	JSR $BF00
	.byte $C0	;CREATE the destination file
	.byte <COPYCREA
	.byte >COPYCREA
	JSR $BF00
	.byte $C8	;OPEN source file
	.byte <COPYOPEN
	.byte >COPYOPEN
	JSR $BF00
	.byte $C8	;OPEN destination file
	.byte <COPYOPN2
	.byte >COPYOPN2
	LDA COPENREF
	STA CNWLNREF
	JSR $BF00
	.byte $C9	;Reset NEWLINE for source
	.byte <COPYNWLN
	.byte >COPYNWLN
	LDA COPN2REF
	STA CNWLNREF
	STA CEOFREF
	JSR $BF00
	.byte $C9	;Reset NEWLINE for destination
	.byte <COPYNWLN
	.byte >COPYNWLN
	JSR $BF00
	.byte $D2	;SET EOF of destination file to 0
	.byte <COPYEOF
	.byte >COPYEOF
COPYLOOP:	LDA COPENREF
	STA CRWREF
	LDA #$00
	STA CREQCNT1
	LDA #$20
	STA CREQCNT2
	LDA #$00
	STA CXFRCNT1
	STA CXFRCNT2
	JSR $BF00
	.byte $CA	;READ 8K from source file
	.byte <COPYRW
	.byte >COPYRW
	BCS COPYDONE	;If an error occurred, most likely End Of File, close the files and we're done
	LDA COPN2REF
	STA CRWREF
	LDA CXFRCNT1
	STA CREQCNT1
	LDA CXFRCNT2
	STA CREQCNT2
	LDA #$00
	STA CXFRCNT1
	STA CXFRCNT2
	JSR $BF00
	.byte $CB	;WRITE 8K to destination file
	.byte <COPYRW
	.byte >COPYRW
	BCC COPYLOOP
COPYDONE:	LDA COPENREF
	STA CCLOSREF
	JSR $BF00
	.byte $CC	;CLOSE source file
	.byte <COPYCLOS
	.byte >COPYCLOS
	LDA COPN2REF
	STA CCLOSREF
	JSR $BF00
	.byte $CC	;CLOSE destination file
	.byte <COPYCLOS
	.byte >COPYCLOS
	JSR DISKSPC
	JMP DISPDIR
COPYCREA:	.byte $07
	.byte <PATHBFR
	.byte >PATHBFR
	.byte $E3
CCREFTYP:	.byte $00
CCREATYP:	.byte $00
CCREATYQ:	.byte $00
	.byte $01
CCREDAT1:	.byte $00
CCREDAT2:	.byte $00
CCREDAT3:	.byte $00
CCREDAT4:	.byte $00
COPYOPEN:	.byte $03
	.byte <COPYSRC
	.byte >COPYSRC
	.byte <IOBUFF
	.byte >IOBUFF
COPENREF:	.byte $00
COPYOPN2:	.byte $03
	.byte <PATHBFR
	.byte >PATHBFR
	.byte <IOBUFF2
	.byte >IOBUFF2
COPN2REF:	.byte $00
COPYNWLN:	.byte $03
CNWLNREF:	.byte $00
	.byte $00
	.byte $00
COPYEOF:	.byte $02
CEOFREF:	.byte $00
	.byte $00
	.byte $00
	.byte $00
COPYRW:	.byte $04
CRWREF:	.byte $00
	.byte <IOBUFFER
	.byte >IOBUFFER
CREQCNT1:	.byte $00
CREQCNT2:	.byte $20
CXFRCNT1:	.byte $00
CXFRCNT2:	.byte $00
COPYCLOS:	.byte $01
CCLOSREF:	.byte $00

;KFORMAT:	LDX #$0F	;Format a disk
;	LDY #$62	;"Slot:"
;	LDA #$01
;	JSR PFNPRMPT
;	LDA $6F00
;	BNE KFORMAT1
;	JMP KBDLOOP
;KFORMAT1:	LDA $6F01
;	AND #$07
;	STA $FA
;	LDX #$16	;"Drive:"
;	LDY #$62
;	LDA #$01
;	JSR PFNPRMPT
;	LDA $6F00
;	BNE KFORMAT2
;	JMP KBDLOOP
;KFORMAT2:	DEC $6F01
;	LDA $6F01
;	AND #$01
;	STA $FB
;	ASL
;	ASL
;	ASL
;	ORA $FA
;	ASL
;	ASL
;	ASL
;	ASL
;	STA $FC	;$FC contains the unit number
;	LDX #$2B	;"New Disk Name:"
;	LDY #$66
;	LDA #$0F
;	JSR PFNPRMPT
;	LDX $6F00
;	BNE KFORMAT3
;	JMP KBDLOOP
;KFORMAT3:	STX $2000	;move new name from $6F00 to $2000
;KFMTLOOP:	LDA $6F00,X
;	STA $2001,X
;	DEX
;	BNE KFMTLOOP
;	LDX #$7D	;"Are you sure? (Y/N):"
;	LDY #$61
;	LDA #$00
;	JSR PFNPRMPT
;	LDA $6F01	;6F01 is the first character
;	AND #$5F
;	CMP #$59
;	BEQ KFORMAT4
;	JMP KBDLOOP
;KFORMAT4:	nop
;	JMP DISPDIR

KONLINE:	LDX #$01	;Move to the topmost level (the list of disks)
	STX $6F00
	LDX #$2F
	STX $6F01
	JSR SETPRFX
	JMP DISPDIR

KPREFIX:	LDX #$64	;Ask for a prefix
	LDY #$61	;"Prefix:"
	LDA #$00	;No dots
	JSR PFNPRMPT	;get input from prompt
	JSR SETPRFX	;set prefix to input
	JSR DISKSPC
	JMP DISPDIR

KBACK:	JSR GETPRFX	;Go back a level
	LDX $6F00
	BEQ KBACKZRO
KBAKLOOP:	DEX
	BEQ KBACKZRO
	LDA $6F00,X
	CMP #$2F
	BNE KBAKLOOP
	STX $6F00
	JSR SETPRFX
	JMP DISPDIR
KBACKZRO:	JMP KONLINE

KABOUT:	JSR CLRSCRN	;Show PFN copyright and slot contents
	LDX #$A2	;"ProDOS File Navigator 3.0"
	LDY #$60
	JSR PRINTSTR
	JSR PRINTCR
	LDX #$BC	;"(C) 1998..."
	LDY #$60
	JSR PRINTSTR
	JSR PRINTCR
	LDX #$DC	;"http://..."
	LDY #$60
	JSR PRINTSTR
	JSR PRINTCR
	LDX #$00	;"support@..."
	LDY #$61
	JSR PRINTSTR
	JSR PRINTCR
	JSR PRINTCR
	LDX #$1E	;"Running on"
	LDY #$62
	JSR PRINTSTR
	JSR PMACHTYP	;"Apple IIgs ROM 3 (Bernie II the Rescue)"
	JSR PRINTCR
	JSR PRINTCR
	JSR PERIPHCD	;"What peripheral cards are installed?"
	JSR PRINTCR
	LDX #$E4
	LDY #$61	;"Press any key to continue."
	JSR PRINTSTR
	JSR GETCHAR
	JMP DISPCAT

KRSTDISP:	JSR TEXT	;Reset Display
	JSR A80COLOFF
	JSR TXTUNWDW	;If a text file contains a $95, 80-column mode will get deactivated,
	JSR CLRSCRN	;throwing the text display into heck. This routine will get everything
	JSR A80COLON	;back to normal. You just type the exclamation point (!, or Shift-1)
	JMP DISP	;to reset the display.

KUPP:	JSR KUP2	;Decrease S ($08)
	JMP DISPCAT2
KUP2:	LDX CURRSEL
	DEX
	BMI KUP3
	STX CURRSEL
KUP3:	RTS

KDOWN:	JSR KDOWN2	;Increase S ($08)
	JMP DISPCAT2
KDOWN2:	LDX CURRSEL
	INX
	CPX NUMFILES
	BCS KDOWN3
	STX CURRSEL
KDOWN3:	RTS

KLEFT:	LDY #$12	;Decrease S by 18
KLEFT2:	JSR KUP2
	DEY
	BNE KLEFT2
	JMP DISPCAT2

KRIGHT:	LDY #$12	;Increase S by 18
KRIGHT2:	JSR KDOWN2
	DEY
	BNE KRIGHT2
	JMP DISPCAT2

A80COLON:	LDX $36	;save ProDOS output hook
	LDY $37
	STX $06
	STY $07
	JSR $C300	;Turn 80-columns on
	LDX $06	;restore ProDOS output hook
	LDY $07
	STX $36
	STY $37
	LDX #$07	;point ProDOS in the direction of the 80-column firmware
	LDY #$C3
	STX $BE30
	STY $BE31
STDRTS:	RTS

A80COLOFF:	LDA #$95	;Turn 80-columns off
	JMP $FDED

LOWRESGR:	STA $C056	;lo-res
	STA $C052	;full screen
	STA $C05F	;ann 3 on
	STA $C050	;graphics
	RTS

DBLOWRES:	STA $C056	;lo-res
	STA $C052	;full screen
	STA $C05E	;ann 3 off
	STA $C050	;graphics
	RTS

HIRESGR:	STA $C057	;hi-res
	STA $C052	;full screen
	STA $C05F	;ann 3 on
	STA $C050	;graphics
	RTS

DBLHIRES:	STA $C057	;hi-res
	STA $C052	;full screen
	STA $C05E	;ann 3 off
	STA $C050	;graphics
	RTS

TEXT:	STA $C051	;text
	STA $C05F	;ann 3 on
	RTS

MAINMEM:	STA $C054
	RTS

AUXMEM:	STA $C055
	RTS

NORMAL:	JMP $F273
INVERSE:	JMP $F277
CLRSCRN:	JMP $FC58
CLRSCRN2:	LDA #$30
CLRSLOOP:	STA $FF
	LDA #$8D
	JSR $FDED
	LDA $FF
	DEC
	BNE CLRSLOOP
	LDX $20
	LDY $22
SETPOS:	STY $25	;Set text cursor position, in X/Y registers
	STY $05FB
SETXPOS:	STX $24	;Set just the horizontal cursor position, in X register
	STX $057B
	JMP $FC22
SETYPOS:	STX $25	;Set just the vertical cursor position, in X register
	STX $05FB
	JMP $FC22

TXTWINDW:	LDA #$03	;Set a text window that preserves the header and footer
	STA $22
	LDA #$15
	STA $23
	RTS

TXTUNWDW:	LDA #$00	;Reset the text window to normal
	STA $22
	LDA #$18
	STA $23
	RTS

TXTPRWDW:	LDA #$17	;Set a text window just for a prompt
	STA $22
	LDA #$18
	STA $23
	RTS

PRSTR6F:	LDX #$00	;Print Pascal string at $6F00
	LDY #$6F
PRINTSTR:	STX $06	;Print a Pascal string, with address in X/Y registers
	STY $07
PRSTR:	LDY #$00	;Print a Pascal string, with address in $06/$07
	LDA ($06),Y
	TAX
	BEQ PRSTREND
PRSTLOOP:	INY
	LDA ($06),Y
	JSR $FDED
	DEX
	BNE PRSTLOOP
PRSTREND:	RTS

PRHIST6F:	LDX #$00	;Print Pascal string at $6F00, ignoring high/low ASCII
	LDY #$6F
PRHISTXY:	STX $06	;Print a Pascal string, with address in X/Y registers
	STY $07
PRHISTR:	LDY #$00	;Print a Pascal string, with address in $06/$07
	LDA ($06),Y
	TAX
	BEQ PRHSTEND
PHS2LOOP:	INY
	LDA ($06),Y
	ORA #$80
	JSR $FDED
	DEX
	BNE PHS2LOOP
PRHSTEND:	RTS

PRSTR16:	STX $06	;Print a Pascal string of 15 characters or less
	STY $07
PRSTR16M:	LDY #$00
	LDA ($06),Y
	AND #$0F
	STA ($06),Y
	JMP PRHISTR

PRINTCR2:	JSR $FC9C
PRINTCR:	LDA #$8D	;Print a carriage return
	JMP $FDED

BEEP:	LDA #$87	;Print a BEL, making the computer beep
	JMP $FDED

SMILE:	LDA #$BA
	STA $07E3
	LDA #$A9
	STA $07E4
	LDY #$14
SMILOOP:	LDA #$C4
	JSR $FCA8
	DEY
	BNE SMILOOP
	LDA #$A0
	STA $07E3
	STA $07E4
	RTS

A15SPACES:	LDX #$0F	;Print 15 spaces
	CLC
	BCC A80SPLOOP
A78SPACES:	LDX #$4E	;Print 78 spaces
	CLC
	BCC A80SPLOOP
A80SPACES:	LDX #$50	;Print 80 spaces
A80SPLOOP:	LDA #$A0
	JSR $FDED
	DEX
	BNE A80SPLOOP
	RTS
A80HYPHEN:	LDX #$50	;Print 80 hyphens
A80HYLOOP:	LDA #$AD
	JSR $FDED
	DEX
	BNE A80HYLOOP
	RTS

XPERIODS:	CPX #$00	;Print X number of periods
	BEQ XDOTEND
XDOTLOOP:	LDA #$AE
	JSR $FDED
	DEX
	BNE XDOTLOOP
XDOTEND:	RTS

PRNMDIV2:	TYA	;Print an integer in X/Y divided by 2
	CLC
	ROR
	TAY
	TXA
	ROR
	TAX
	BCS PRNMD2HF
PRINTNUM:	TYA	;Print an integer in X/Y
	JMP IDITUFOR
PRNMD2HF:	JSR PRINTNUM
	LDX #$BB
	LDY #$63
	JMP PRINTSTR

STREQU:	LDY #$00	;Compare strings, case-sensitive
	LDA ($FA),Y	;Naturally, the zero flag is used to return if the strings are equal
	CMP ($FC),Y
	BEQ STREQU1
	RTS
STREQU1:	TAY
STREQULP:	LDA ($FC),Y
	AND #$7F
	STA $FF
	LDA ($FA),Y
	AND #$7F
	CMP $FF
	BNE STREQUEX
	DEY
	BNE STREQULP
STREQUEX:	RTS

STREQI:	LDY #$00	;Compare strings, case-insensitive
	LDA ($FA),Y	;Naturally, the zero flag is used to return if the strings are equal
	CMP ($FC),Y
	BEQ STREQI1
	RTS
STREQI1:	TAY
STREQILP:	LDA ($FC),Y
	AND #$7F
	CMP #$7B
	BCS STREQI2
	CMP #$61
	BCC STREQI2
	SBC #$20
STREQI2:	STA $FF
	LDA ($FA),Y
	AND #$7F
	CMP #$7B
	BCS STREQI3
	CMP #$61
	BCC STREQI3
	SBC #$20
STREQI3:	CMP $FF
	BNE STREQIEX
	DEY
	BNE STREQILP
STREQIEX:	RTS

PRINTYPE:	LDA $6400,X	;Print a ProDOS file type, with type in X register
	BEQ UNKTYPE
	TAX
	LDA $6500,X
	JSR $FDED
	INX
	LDA $6500,X
	JSR $FDED
	INX
	LDA $6500,X
	JMP $FDED
UNKTYPE:	LDA $6500
	JSR $FDED
	TXA
	JMP $FDDA

PRDATIME:	LDA $FA	;Print date and time in $FA/FB/FC/FD in MMMDDDDD/YYYYYYYM/minute/hour format
	AND #$1F	;Uses: $FA, $FB, $FC, $FD    ($FA and $FB are destroyed!)
	BNE DAYNOT0
	LDX #$00
	LDY #$66
	JMP PRINTSTR
DAYNOT0:	TAX	;Print day
	LDY #$00
	JSR PRINTNUM
	LDA #$A0	;Print space
	JSR $FDED
	CLC	;Rotate so we can get month and year more easily
	ROR $FB
	ROR $FA
	LDA $FA	;Print month
	AND #$F0
	LSR
	LSR
	LSR
	LSR
	CLC
	STA $FF
	ADC $FF
	ADC $FF
	TAX
	LDA $63C9,X
	JSR $FDED
	LDA $63CA,X
	JSR $FDED
	LDA $63CB,X
	JSR $FDED
	LDA #$A0	;Print space
	JSR $FDED
	LDA $FB	;Print year
	AND #$7F
	TAX
	JSR MINIED24
	LDA #$A0
	JSR $FDED
	LDA #$A0
	JSR $FDED
	LDX #$C6	;Print hour
	STX $FA	;Set initially to AM
	LDA $FD	;Get hour
	CMP #$0C
	BCC HOURNOTPM
	SBC #$0C	;If it's 12:00 noon or after, subtract 12 and set to PM
	LDX #$C9
	STX $FA
HOURNOTPM:	TAX	;Actually dummy command
	BNE HOURNOT0
	LDA #$0C	;If it's 0, put 12 in there
HOURNOT0:	TAX
	LDY #$00
	JSR PRINTNUM
	LDA #$BA	;Print colon
	JSR $FDED
	LDX $FC	;Print minute
	JSR MINIED24
	LDA #$A0	;Print space
	JSR $FDED
	LDX $FA	;Print AM/PM
	LDY #$63
	JSR PRINTSTR
	RTS

PFNPRMPT:	STX $06	;Get some input, prompt address in X/Y, number of dots in A, input returned in $6F00
	STY $07	;Uses: $06, $07, $FF
	STA $FF
	JSR TXTPRWDW
	LDX #$00
	LDY #$17
	JSR SETPOS
	JSR PRSTR
	LDX $FF
	JSR XPERIODS
	LDY #$00
	LDA ($06),Y
	TAX
	LDY #$17
	JSR SETPOS
	JSR GETLN6F
	LDX #$00
	LDY #$17
	JSR SETPOS
	JSR PRINTCR
	LDX #$00
	LDY #$0C
	JSR SETPOS
	JMP TXTWINDW

GETCHAR:	LDA #$00
	STA $C010
GTCHLOOP:	LDA $C000
	BPL GTCHLOOP
	LDY #$00
	STY $C010
	RTS
GETLINE:	LDX #$00
	STX $33
	JMP $FD6A

GETLN6F:	JSR GETLINE
COPYKI:	STX $6F00	;Copy keyboard input ($200, length in X) to $6F00 as Pascal string
	BEQ CPYKIEND
CPYKLOOP:	DEX
	LDA $0200,X
	STA $6F01,X
	CPX #$00
	BNE CPYKLOOP
CPYKIEND:	RTS

DIV18:	LDX #$00	;Divide accumulator by 18
	SEC
DV18LOOP:	SBC #$12
	BCC DIV18END
	INX
	SEC
	BCS DV18LOOP
DIV18END:	TXA
	RTS

MOD18:	SEC	;Modulo accumulator by 18
MD18LOOP:	SBC #$12
	BCC MOD18END
	SEC
	BCS MD18LOOP
MOD18END:	ADC #$12
	RTS

MUL21:	STA $FF	;Multiply accumulator by 21
	LDX #$15
ML21LOOP:	DEX
	BEQ MUL21END
	CLC
	ADC $FF
	CLC
	BCC ML21LOOP
MUL21END:	RTS

GETFADDR:	LDY #$00	;Get the address of a file entry; file # in X, address in $CE/CF
	STX $CE	;Uses: $CE, $CF
	STY $CF
	CLC
	ROL $CE
	ROL $CF
	CLC
	ROL $CE
	ROL $CF
	CLC
	ROL $CE
	ROL $CF
	CLC
	ROL $CE
	ROL $CF
	CLC
	ROL $CE
	ROL $CF
	LDA $CF
	CLC
	ADC #$68
	STA $CF	;At this point, $CE contains the address of the file's entry in $6800-$6EFF
	RTS

PERIPHCD:	LDX #$47	;"What peripheral cards are installed?"
	LDY #$62	;Uses: $FE, $06, $07
	JSR PRINTSTR
	JSR PRINTCR
	JSR PRINTCR
	LDX #$01
PCRDLOOP:	STX $FE
	LDX #$6E	;"Card "
	LDY #$62
	JSR PRINTSTR
	LDA $FE	;Card Number
	ORA #$B0
	JSR $FDED
	LDX #$74	;": "
	LDY #$62
	JSR PRINTSTR
	LDA $FE
	ORA #$C0	;Get card type and display corresponding string
	STA $07
	LDX #$0C
	STX $06
	LDX $C015
	STX $C006
	LDY #$00
	LDA ($06),Y
	LSR
	LSR
	LSR
	LSR
	AND #$0F
	TAY
	TXA
	BPL PROMON
	STX $C007
PROMON:	TYA
	TAX
	LDA $63F0,X
	TAX
	LDY #$62
	JSR PRINTSTR
	JSR PRINTCR
	LDX $FE
	INX
	CPX #$08
	BEQ PCRDEND
	JMP PCRDLOOP
PCRDEND:	RTS

PMACHTYP:	LDX #$2A	;Print type of machine I'm running on
	LDY #$62	;"Apple "
	JSR PRINTSTR
	LDX #$31	;"II"
	LDY #$62
	JSR PRINTSTR
AIICHEK:	LDA $FBB3
	CMP #$38
	BNE AIIPCHEK
	JMP PMTYPSUC	;Original II
AIIPCHEK:	CMP #$EA
	BNE AIIECHEK
	LDA $FB1E
	CMP #$AD
	BNE AIIICHEK
	LDA #$AB	;'+'
	JSR $FDED
	JMP PMTYPSUC	;II+
AIIICHEK:	LDA #$C9	;'I'
	JSR $FDED
	JMP PMTYPSUC	;III
AIIECHEK:	LDA $FBC0
	CMP #$EA
	BNE AIICCHEK
	LDA #$E5	;'e'
	JSR $FDED
	JMP PMTYPSUC	;IIe
AIICCHEK:	CMP #$00
	BNE AIIGCHEK
	LDA #$E3	;'c'
	JSR $FDED
	JMP PMTYPSUC	;IIc
AIIGCHEK:	SEC
	JSR $FE1F
	BCS AIIFCHEK
	STY $FF	;Y contains ROM number
	LDA #$E7	;'g'
	JSR $FDED
	LDA #$F3	;'s'
	JSR $FDED
	LDX #$3B	;" ROM "
	LDY #$62
	JSR PRINTSTR
	LDA $FF	;0, 1, or 3
	AND #$07
	ORA #$B0
	JSR $FDED
	JMP PMTYPSUC	;IIgs
AIIFCHEK:	LDA #$E5	;'e'
	JSR $FDED	;IIe
PMTYPSUC:	RTS

;PEMULTYP:	STA $C04F	;Print type of emulator I'm running on (if any) (WARNING: This makes some emulators, like KEGS, that insist on well-behaved programs, go wakowakowako)
;	LDA $C04F	;$C04F is undocumented emulator identity I/O address thing
;	CMP #$FE	;If it's $FE (F.E. Systems)...
;	BNE ES16CHEK
;	LDX #$00
;	LDY #$63
;	JSR PRINTSTR
;	LDX #$D8
;	LDY #$62
;	JSR PRINTSTR	;Bernie
;	LDX #$03
;	LDY #$63
;	JSR PRINTSTR
;	JMP EMTYPSUC
;ES16CHEK:	CMP #$16	;If it's $16 (Sweet16)...
;	BNE EC02CHEK
;	LDX #$00
;	LDY #$63
;	JSR PRINTSTR
;	LDX #$ED
;	LDY #$62
;	JSR PRINTSTR	;Sweet16
;	LDX #$03
;	LDY #$63
;	JSR PRINTSTR
;	JMP EMTYPSUC
;EC02CHEK:	CMP #$CD	;If it's $CD (Carbon Dioxide)...
;	BNE EMTYPSUC
;	LDX #$00
;	LDY #$63
;	JSR PRINTSTR
;	LDX #$15
;	LDY #$63
;	JSR PRINTSTR	;Carbon Dioxide
;	LDX #$03
;	LDY #$63
;	JSR PRINTSTR
;	JMP EMTYPSUC
;EMTYPSUC:	RTS

GETPRFX:	JSR $BF00	;Get the prefix
	.byte $C7	;A call to GET_PREFIX puts the prefix into the string passed.
	.byte <PRFXPARM	;What they DON'T tell you is that if this string changes, the
	.byte >PRFXPARM	;prefix changes too! I use $6F00 as a general purpose string
	LDX #$00	;buffer for everything, so the stupid piece of crap kept screwing
	LDA REALPRFX,X	;me over. So now I have to put the prefix into $C00 and copy
	STA PATHBFR,X	;it over to $6F00. What a piece of crap.
	TAX
GETPFXLP:	LDA REALPRFX,X
	STA PATHBFR,X
	DEX
	BNE GETPFXLP
	RTS

SETPRFX:	LDX #$00	;Set the prefix
	LDA PATHBFR,X	;A call to SET_PREFIX changes the prefix to the string passed.
	STA REALPRFX,X	;What they DON'T tell you is that if this string changes, the
	TAX	;prefix changes too! I use $6F00 as a general purpose string
SETPFXLP:	LDA PATHBFR,X	;buffer for everything, so the stupid piece of crap kept screwing
	STA REALPRFX,X	;me over. So now I have to copy my prefix from $6F00 over to
	DEX	;$C00. What a piece of crap.
	BNE SETPFXLP
	JSR $BF00	;Call the MLI
	.byte $C6
	.byte <PRFXPARM
	.byte >PRFXPARM
	RTS

CHEKPRFX:	JSR GETPRFX	;Check prefix; carry is set if prefix is null
	LDX $6F00
	BEQ CHKPFXNO
	DEX
	BEQ CHKPFXNO
	CLC
	RTS
CHKPFXNO:	SEC
	RTS
PRFXPARM:	.byte $01	;MLI parameter list template for SET/GET PREFIX call
	.byte <REALPRFX
	.byte >REALPRFX

GETNAME:	LDX CURRSEL	;Get name of selected file; file # in $08, catalog at $6800, name at $6F00
GETNAMEX:	JSR GETFADDR	;Get name of selected file; file # in X, catalog at $6800, name at $6F00
	LDY #$00
	LDA ($CE),Y
	TAY
	STY $6F00	;Copy string to $6F00
	BEQ GETNMEND
GTNMLOOP:	LDA ($CE),Y
	STA $6F00,Y
	DEY
	BNE GTNMLOOP
GETNMEND:	RTS

GETPATH:	JSR CHEKPRFX	;Get path of selected file or disk; file # in $08, catalog at $6800, path at $6F00
	BCC GETPATH0
GETPATHD:	JSR GETNAME	;Get path of selected disk
	LDX $6F00	;Move name over 1 byte
	BEQ GETDPATH
GTDPLOOP:	LDA $6F00,X
	STA $6F01,X
	DEX
	BNE GTDPLOOP
GETDPATH:	LDX $6F00	;Insert end slash
	INX
	INX
	LDA #$2F
	STA $6F00,X
	STX $6F00	;Set incremented count byte
	LDX #$2F	;Insert start slash
	STX $6F01
	RTS
GETPATH0:	LDX $6F00	;Get path of selected file; prefix is already in $6F00
	LDA $6F00,X
	AND #$7F	;Check last char
	CMP #$2F
	BEQ GETPATH1	;If it's a slash, skip this stuff
	LDA #$2F
	INX	;Increment count byte
	STA $6F00,X	;Add slash
	STX $6F00
GETPATH1:	LDX CURRSEL	;Find name of file
	JSR GETFADDR
	LDY #$01
GETPLOOP:	LDX $6F00	;Add it to the end of the prefix
	INX
	STX $6F00
	LDA ($CE),Y
	STA $6F00,X
	TYA
	LDY #$00
	CMP ($CE),Y
	BCS GETPAEND	;Branch to the end of the routine if we've reached the end of the file name
	TAY
	INY
	CLC
	BCC GETPLOOP
GETPAEND:	RTS

PFNQUIT:	JSR $BF00	;Quit ProDOS File Navigator
	.byte $65
	.byte <QUITPARM
	.byte >QUITPARM
	BRK
QUITPARM:	.byte $04	;MLI parameter list template for QUIT call
	.byte $00
	.byte $00
	.byte $00
	.byte $00
	.byte $00
	.byte $00

FINFPARM:	.byte $0A	;MLI parameter list template for SET/GET FILE INFO call
	.byte $00	;path
	.byte $6F
FINFACC:	.byte $00	;access
FINFTYPE:	.byte $00	;filetype
FINFAUX:	.byte $00	;auxtype
	.byte $00
	.byte $00	;storage type
	.byte $00	;blocks
	.byte $00
	.byte $00	;mod date
	.byte $00
	.byte $00	;mod time
	.byte $00
	.byte $00	;crea date
	.byte $00
	.byte $00	;crea time
	.byte $00

NWLNPARM:	.byte $03
NWLNREF:	.byte $00
	.byte $00
	.byte $00

XFERFREF:	LDY #$0F	;Copy directory entry into catalog - the formats are different
XFERFRLP:	LDA ($06),Y	;$06/07 is address of directory entry
	STA ($CE),Y	;$CE/CF is address of catalog
	DEY
	BNE XFERFRLP
	LDY #$00	;Name
	LDA ($06),Y
	STA ($CE),Y
	LDY #$10	;File Type
	LDA ($06),Y
	LDY #$11
	STA ($CE),Y
	LDY #$13	;Block Count Low
	LDA ($06),Y
	LDY #$15
	STA ($CE),Y
	LDY #$14	;Block Count High
	LDA ($06),Y
	LDY #$16
	STA ($CE),Y
	LDY #$15	;Byte Count Low
	LDA ($06),Y
	LDY $E3
	STA $0E00,Y
	LDY #$16	;Byte Count Medium
	LDA ($06),Y
	LDY $E3
	STA $0E01,Y
	LDY #$17	;Byte Count High
	LDA ($06),Y
	LDY $E3
	STA $0E02,Y
	LDY #$00	;Storage Type
	LDA ($06),Y
	LSR
	LSR
	LSR
	LSR
	LDY #$14
	STA ($CE),Y
	LDY #$18	;Creation Date 1
	LDA ($06),Y
	LDY #$1B
	STA ($CE),Y
	LDY #$19	;Creation Date 2
	LDA ($06),Y
	LDY #$1C
	STA ($CE),Y
	LDY #$1A	;Creation Date 3
	LDA ($06),Y
	LDY #$1D
	STA ($CE),Y
	LDY #$1B	;Creation Date 4
	LDA ($06),Y
	LDY #$1E
	STA ($CE),Y
	LDY #$1E	;Access Code
	LDA ($06),Y
	LDY #$10
	STA ($CE),Y
	LDY #$1F	;Aux Type Low
	LDA ($06),Y
	LDY #$12
	STA ($CE),Y
	LDY #$20	;Aux Type High
	LDA ($06),Y
	LDY #$13
	STA ($CE),Y
	LDY #$21	;Modification Date 1
	LDA ($06),Y
	LDY #$17
	STA ($CE),Y
	LDY #$22	;Modification Date 2
	LDA ($06),Y
	LDY #$18
	STA ($CE),Y
	LDY #$23	;Modification Date 3
	LDA ($06),Y
	LDY #$19
	STA ($CE),Y
	LDY #$24	;Modification Date 4
	LDA ($06),Y
	LDY #$1A
	STA ($CE),Y
	LDY #$1D	;High byte of version/minversion as a word
	LDA ($06),Y
	BPL NOCAPS
	STA $EB	;If the high byte was set, change capitalization!
	LDY #$1C
	LDA ($06),Y
	STA $EC
	LDY #$01
	CLC
	ROL $EC
	ROL $EB
CAPSLOOP:	CLC
	ROL $EC
	ROL $EB
	BCC UPERCASE
	LDA ($CE),Y
	ORA #$20
	STA ($CE),Y
UPERCASE:	INY
	CPY #$10
	BCC CAPSLOOP
NOCAPS:	RTS

XFERGR:	LDA #$00	;Transfer low-res graphics from page 2 to page 1, without messing up screen holes
XFGRLP2:	STA $FF
	JSR $FBC1
	LDA $28
	STA $EB
	LDA $29
	CLC
	ADC #$04
	STA $EC
	LDY #$27
XFGRLP1:	LDA ($EB),Y
	STA ($28),Y
	DEY
	BPL XFGRLP1
	LDX $FF
	INX
	TXA
	CMP #$18
	BCC XFGRLP2
	CLC
	RTS

XFERGRA:	LDA #$00	;Transfer low-res graphics from main page 2 to auxiliary page 1, without messing up screen holes
XFGRALP2:	STA $FF
	JSR $FBC1
	LDA $28
	STA $EB
	LDA $29
	CLC
	ADC #$04
	STA $EC
	LDY #$27
XFGRALP1:	JSR MAINMEM
	LDA ($EB),Y
	JSR AUXMEM
	STA ($28),Y
	JSR MAINMEM
	DEY
	BPL XFGRALP1
	LDX $FF
	INX
	TXA
	CMP #$18
	BCC XFGRALP2
	CLC
	RTS

CLEARPGE:	STY $EC	;Clear page Y of memory
	LDY #$00
	STY $EB
	LDA #$00
CLPGLOOP:	STA ($EB),Y
	INY
	BNE CLPGLOOP
	RTS

CLEARBUF:	LDY #$20	;Clear $2000 - $3FFF
CLBFLOOP:	STY $ED
	JSR CLEARPGE
	LDY $ED
	INY
	CPY #$40
	BCC CLBFLOOP
	RTS

CLRBUF2:	LDY #$19	;Clear $1900 - $3FFF
CLB2LOOP:	STY $ED
	JSR CLEARPGE
	LDY $ED
	INY
	CPY #$40
	BCC CLB2LOOP
	RTS

XFERAUXH:	LDX #$20
	LDY #$00
	STX $07
	STY $06
	LDX #$20	;Number of pages to copy (32)
XAHLOOP:	JSR MAINMEM	;Copy contents of source address to destination address
	LDA ($06),Y
	JSR AUXMEM
	STA ($06),Y
	JSR MAINMEM
	INY	;Add 1 to the address being copied
	BNE XAHLOOP	;If we didn't roll over, loop back to copy the next address
	INC $07	;If we did roll over, increase the high byte of the source address
	DEX	;Decrease X (number of pages to copy)
	BNE XAHLOOP	;If it's not zero, we still have more pages to copy; loop back to copy the next page
	RTS	;If it is zero, we're done and can return

PROTDHR:	JSR $BF00
	.byte $C0
	.byte <PDHRCREA
	.byte >PDHRCREA
	BCS PDHRERR
	JSR $BF00
	.byte $C8
	.byte <PDHROPEN
	.byte >PDHROPEN
	BCS PDHRERR
	LDA PDHROREF
	STA PDHRWREF
	STA PDHRCREF
	JSR $BF00
	.byte $CB
	.byte <PDHRWRIT
	.byte >PDHRWRIT
	JSR $BF00
	.byte $CC
	.byte <PDHRCLOS
	.byte >PDHRCLOS
PDHRERR:	RTS
DPROTDHR:	JSR $BF00
	.byte $C1
	.byte <PDHRDEL
	.byte >PDHRDEL
	RTS
PDHRCREA:	.byte $07	;param count
	.byte <PDHRPATH	;path
	.byte >PDHRPATH
	.byte $E3	;access
	.byte $06	;file type
	.byte $00	;aux type
	.byte $20
	.byte $01	;storage
	.byte $00	;mod date
	.byte $00
	.byte $00
	.byte $00
PDHROPEN:	.byte $03	;param count
	.byte <PDHRPATH	;path
	.byte >PDHRPATH
	.byte <IOBUFF2	;io buffer
	.byte >IOBUFF2
PDHROREF:	.byte $00	;ref num
PDHRWRIT:	.byte $04	;param count
PDHRWREF:	.byte $00	;ref num
	.byte $00	;buffer
	.byte $20
	.byte $00	;req count
	.byte $20
	.byte $00	;xfer count
	.byte $00
PDHRCLOS:	.byte $01	;param count
PDHRCREF:	.byte $00	;ref num
PDHRDEL:	.byte $01	;param count
	.byte <PDHRPATH	;path
	.byte >PDHRPATH
PDHRPATH:	.byte $08, $2F, $52, $41, $4D, $2F, $44, $48, $52
	;"/RAM/DHR"

SCANTEXT:	LDA #$19
	STA $07
	LDA #$00
	STA $06
	LDX #$00
	STX $EB	;temp
	STX $EC	;current line
	STX $ED
	STX $EE	;total lines
	STX $EF
	LDY #$00
SCTXTLP:	LDA ($06),Y
	ORA #$80
	CMP #$80
	BEQ SCTEXIT
	CMP #$8D
	BEQ ISRTN
	CMP #$A0
	BCC ISCTRL
	BNE CONTSCTX
	CPX #$50
	BCC NSPC
	LDY $EB
	LDA #$8D
	STA ($06),Y
	LDX #$00
ISRTN:	CPX #$50
	BCC ISRTN0
	STY $FF
	LDY $EB
	LDA #$8D
	STA ($06),Y
	LDY $FF
	LDX #$00
ISRTN0:	INC $EE
	LDA $EE
	BNE ISRTN1
	INC $EF
ISRTN1:	STY $FF
	LDA $06
	CLC
	ADC $FF
	BCC ISRTN2
	INC $07
ISRTN2:	STA $06
	LDX #$00
	LDY #$00
	STY $EB
	JMP CONTSCTX
ISCTRL:	LDA #$7F
	STA ($06),Y
	JMP CONTSCTX
NSPC:	STY $EB
CONTSCTX:	INX
	INY
	JMP SCTXTLP
	CPY #$50	; \/ This crap messes everything up \/
	BCC NOYROLL
	LDA $06
	CLC
	ADC #$50
	BCC NO6ROLL
	INC $07
NO6ROLL:	STA $06
	LDY #$00
	LDX #$00
	STX $EB
NOYROLL:	LDA $07
	CMP #$40
	BNE SCTXTLP
SCTEXIT:	RTS	; /\ This crap messes everything up /\

TEXTADDR:	LDA #$19
	STA $07
	LDA #$00
	STA $06
	LDA $EC
	BNE NOTZRO
	LDA $ED
	BNE NOTZRO
	RTS
NOTZRO:	LDA #$01
	STA $FE
	LDA #$00
	STA $FF
	LDY #$00
TXTADRLP:	LDA ($06),Y
	ORA #$80
	CMP #$80
	BEQ TXADEXIT
	CMP #$8D
	BNE NOTCR
	LDA $EC
	CMP $FE
	BNE NOTOURLN
	LDA $ED
	CMP $FF
	BNE NOTOURLN
	INY
	BNE NOINC77
	INC $07
NOINC77:	STY $06
	RTS
NOTOURLN:	INC $FE
	LDA $FE
	BNE NOTCR
	INC $FF
NOTCR:	INY
	BNE NOINC7
	INC $07
NOINC7:	CLC
	BCC TXTADRLP
TXADEXIT:	RTS

TEXTDISP:	LDX #$12
	LDY #$00
TDISPLP:	LDA ($06),Y
	ORA #$80
	CMP #$80
	BEQ TDISPEXT
	CMP #$8D
	BNE TDNOTCR
	STA $FA
	STX $FB
	STY $FC
	JSR $FC9C
	LDY $FC
	LDX $FB
	LDA $FA
	DEX
	BEQ TDISPEXT
TDNOTCR:	STX $FB
	STY $FC
	JSR $FDED
	LDY $FC
	LDX $FB
	INY
	BNE TDISPLP
	INC $07
	CLC
	BCC TDISPLP
TDISPEXT:	JMP $FC42

	.alias BIN0 $EB
	.alias BIN1 $EC
	.alias BCD0 $ED
	.alias BCD1 $EE
	.alias BCD2 $EF

IDITUFOR:	STA BIN1	;$ED24 supposedly prints the contents of X (low) and A (high) as a decimal number,
	STX BIN0	;but it doesn't appear to be working; all it prints is $7F characters.
	JSR BIN2BCD	;Perhaps it needs some initialization before it can be used?
	JMP PRINTBCD	;Anyway, here's my routine for during the same thing.

BIN2BCD:	SED	;Andrew Jacobs - Feb 28, 2004
	LDA #$00
	STA BCD0
	STA BCD1
	STA BCD2
	LDX #$10	;number of source bits
B2DLOOP:	ASL BIN0
	ROL BIN1
	LDA BCD0
	ADC BCD0
	STA BCD0
	LDA BCD1
	ADC BCD1
	STA BCD1
	LDA BCD2
	ADC BCD2
	STA BCD2
	DEX
	BNE B2DLOOP
	CLD
	RTS

PRINTBCD:	LDA #$00	;$EB keeps track of whether or not we found a nonzero digit
	STA $EB	;If $EB > #$F, meaning we found a nonzero digit, the branch won't happen and the digit will be printed
	LDA BCD2	;If the digit is not zero and $EB is #$0, then the branch won't happen and the digit will be printed
	AND #$0F	;Otherwise, both the digit and $EB are zero, meaning we haven't found a nonzero digit yet, and the branch is taken
	CMP $EB	;Whenever the digit is printed, $EB is filled with a value above #$B0, so all remaining digits will be printed
	BEQ PRBCD0	;The last digit is printed regardless of whether or not we found a nonzero digit.
	ORA #$B0
	STA $EB
	JSR $FDED
PRBCD0:	LDA BCD1	;Get byte 2
	AND #$F0	;Get digit 4
	LSR	;Shift it
	LSR	;down to
	LSR	;lowest
	LSR	;nybble
	CMP $EB
	BEQ PRBCD1
	ORA #$B0
	STA $EB
	JSR $FDED
PRBCD1:	LDA BCD1	;Get byte 2
	AND #$0F	;Get digit 3
	CMP $EB
	BEQ PRBCD2
	ORA #$B0
	STA $EB
	JSR $FDED
PRBCD2:	LDA BCD0	;Get byte 1
	AND #$F0	;Get digit 2
	LSR
	LSR
	LSR
	LSR
	CMP $EB
	BEQ PRBCD3
	ORA #$B0
	STA $EB
	JSR $FDED
PRBCD3:	LDA BCD0	;Get byte 1
	AND #$0F	;Get digit 1
	ORA #$B0	;Print it regardless of whether or not we found a nonzero digit
	JMP $FDED

MINIED24:	STX BIN0
	SED
	LDA #$00
	STA BCD0
	LDX #$08
MNEDLOOP:	ASL BIN0
	LDA BCD0
	ADC BCD0
	STA BCD0
	DEX
	BNE MNEDLOOP
	CLD
	LDA BCD0
	AND #$F0
	LSR
	LSR
	LSR
	LSR
	ORA #$B0
	JSR $FDED
	LDA BCD0
	AND #$0F
	ORA #$B0
	JMP $FDED

HEXDIGIT:	AND #$7F
	CMP #$60
	BCC NOTLOWC
	SBC #$20
NOTLOWC:	CMP #$3A
	BCS NOT0TO9
	CMP #$30
	BCS IS0TO9
	LDA #$00
	RTS
IS0TO9:	SBC #$30
	RTS
NOT0TO9:	CMP #$47
	BCS NOTATOF
	CMP #$41
	BCC NOTATOF
	SBC #$37
	RTS
NOTATOF:	LDA #$00
	RTS

HEXSTRNG:	LDX #$00	;$EB-$EF holds our result
	STX $EB
	STX $EC
	STX $ED
	STX $EE
	STX $EF
HEXSTLP1:	LDY #$04
HEXSTLP2:	ASL $EF
	ROL $EE
	ROL $ED
	ROL $EC
	ROL $EB
	DEY
	BNE HEXSTLP2
	LDA $6F01,X
	JSR HEXDIGIT
	ORA $EF
	STA $EF
	INX
	CPX $6F00
	BNE HEXSTLP1
	RTS

DBGERR0:	STA $19	;Make the "Blocks Available" figure display the accumulator
	CLC
	ADC $19
	STA $19
	BCS DBGERRC0
	LDA #$00
	STA $1A
	RTS
DBGERRC0:	LDA #$01
	STA $1A
	RTS

DBGERR1:	STA $1B	;Make the "Blocks Used" figure display the accumulator
	CLC
	ADC $1B
	STA $1B
	BCS DBGERRC1
	LDA #$00
	STA $1C
	RTS
DBGERRC1:	LDA #$01
	STA $1C
	RTS

DBGERR2:	STA $1D	;Make the "Blocks Total" figure display the accumulator
	CLC
	ADC $1D
	STA $1D
	BCS DBGERRC2
	LDA #$00
	STA $1E
	RTS
DBGERRC2:	LDA #$01
	STA $1E
	RTS

	.advancenop $5800
	.org $6000

DATATBL60:	.byte $50, $A0, $A0, $4C, $EF, $E3, $EB, $A0, $A0, $55, $EE, $EC, $EF, $E3, $EB, $A0 ;$6000
	.byte $A0, $52, $E5, $EE, $E1, $ED, $E5, $A0, $A0, $44, $E5, $EC, $E5, $F4, $E5, $A0 ;$6010
	.byte $A0, $43, $F2, $E5, $E1, $F4, $E5, $A0, $A0, $56, $E9, $E5, $F7, $A0, $A0, $45 ;$6020
	.byte $F8, $E5, $E3, $F5, $F4, $E5, $A0, $A0, $49, $EE, $E6, $EF, $A0, $A0, $C3, $E8 ;$6030
	.byte $E1, $EE, $E7, $E5, $A0, $54, $F9, $F0, $E5, $A0, $A0, $4D, $EF, $F2, $E5, $A0 ;$6040
	.byte $A0, $50, $A0, $A0, $C3, $EF, $F0, $79, $A0, $A0, $D0, $E1, $73, $F4, $E5, $A0 ;$6050
	.byte $A0, $D2, $E5, $66, $F2, $E5, $F3, $E8, $A0, $A0, $4F, $EE, $EC, $E9, $EE, $E5 ;$6060
	.byte $A0, $A0, $50, $F2, $E5, $E6, $E9, $F8, $A0, $A0, $42, $E1, $E3, $EB, $A0, $A0 ;$6070
	.byte $41, $E2, $EF, $F5, $F4, $A0, $A0, $51, $F5, $E9, $F4, $A0, $A0, $A0, $A0, $A0 ;$6080
	.byte $A0, $A0, $A0, $A0, $A0, $A0, $A0, $A0, $A0, $A0, $A0, $A0, $4D, $EF, $F2, $E5 ;$6090
	.byte $A0, $A0, $19, $D0, $F2, $EF, $C4, $CF, $D3, $A0, $C6, $E9, $EC, $E5, $A0, $CE ;$60A0
	.byte $E1, $F6, $E9, $E7, $E1, $F4, $EF, $F2, $A0, $B3, $AE, $B0, $1F, $A8, $C3, $A9 ;$60B0
	.byte $A0, $B1, $B9, $B9, $B8, $AD, $B2, $B0, $B0, $B4, $A0, $CB, $F2, $E5, $E1, $F4 ;$60C0
	.byte $E9, $F6, $E5, $A0, $D3, $EF, $E6, $F4, $F7, $E1, $F2, $E5, $1B, $E8, $F4, $F4 ;$60D0
	.byte $F0, $BA, $AF, $AF, $EB, $F2, $E5, $E1, $F4, $E9, $F6, $E5, $EB, $EF, $F2, $F0 ;$60E0
	.byte $AE, $E3, $EA, $E2, $AE, $EE, $E5, $F4, $06, $CB, $A0, $A0, $A0, $A0, $A0, $00 ;$60F0
DATATBL61:	.byte $1C, $F3, $F5, $F0, $F0, $EF, $F2, $F4, $C0, $EB, $F2, $E5, $E1, $F4, $E9, $F6 ;$6100
	.byte $E5, $EB, $EF, $F2, $F0, $AE, $E3, $EA, $E2, $AE, $EE, $E5, $F4, $03, $A0, $AD ;$6110
	.byte $A0, $0B, $C1, $F6, $E1, $E9, $EC, $E1, $E2, $EC, $E5, $BA, $A0, $06, $D5, $F3 ;$6120
	.byte $E5, $E4, $BA, $A0, $07, $D4, $EF, $F4, $E1, $EC, $BA, $A0, $0F, $CE, $E5, $F7 ;$6130
	.byte $A0, $C6, $E9, $EC, $E5, $A0, $CE, $E1, $ED, $E5, $BA, $A0, $17, $CE, $E1, $ED ;$6140
	.byte $E5, $A0, $EF, $E6, $A0, $CE, $E5, $F7, $A0, $C4, $E9, $F2, $E5, $E3, $F4, $EF ;$6150
	.byte $F2, $F9, $BA, $A0, $08, $D0, $F2, $E5, $E6, $E9, $F8, $BA, $A0, $0F, $AE, $AE ;$6160
	.byte $AE, $AE, $AE, $AE, $AE, $AE, $AE, $AE, $AE, $AE, $AE, $AE, $AE, $15, $C1, $F2 ;$6170
	.byte $E5, $A0, $F9, $EF, $F5, $A0, $F3, $F5, $F2, $E5, $BF, $A0, $A8, $D9, $AF, $CE ;$6180
	.byte $A9, $BA, $A0, $09, $C9, $EE, $E6, $EF, $A0, $E6, $EF, $F2, $A0, $08, $CC, $EF ;$6190
	.byte $E3, $EB, $E5, $E4, $BA, $A0, $02, $CE, $EF, $03, $D9, $E5, $F3, $04, $C6, $E9 ;$61A0
	.byte $EC, $E5, $03, $C1, $F5, $F8, $07, $A0, $D4, $F9, $F0, $E5, $BA, $A0, $08, $C2 ;$61B0
	.byte $EC, $EF, $E3, $EB, $F3, $BA, $A0, $0A, $CD, $EF, $E4, $E9, $E6, $E9, $E5, $E4 ;$61C0
	.byte $BA, $A0, $09, $C3, $F2, $E5, $E1, $F4, $E5, $E4, $BA, $A0, $07, $C2, $F9, $F4 ;$61D0
	.byte $E5, $F3, $BA, $A0, $1A, $D0, $F2, $E5, $F3, $F3, $A0, $E1, $EE, $F9, $A0, $EB ;$61E0
	.byte $E5, $F9, $A0, $F4, $EF, $A0, $E3, $EF, $EE, $F4, $E9, $EE, $F5, $E5, $AE, $00 ;$61F0
DATATBL62:	.byte $04, $CE, $E5, $F7, $A0, $09, $C3, $EF, $F0, $F9, $A0, $F4, $EF, $BA, $A0, $06 ;$6200
	.byte $D3, $EC, $EF, $F4, $BA, $A0, $07, $C4, $F2, $E9, $F6, $E5, $BA, $A0, $0B, $D2 ;$6210
	.byte $F5, $EE, $EE, $E9, $EE, $E7, $A0, $EF, $EE, $A0, $06, $C1, $F0, $F0, $EC, $E5 ;$6220
	.byte $A0, $02, $C9, $C9, $01, $E5, $01, $E3, $02, $E7, $F3, $05, $A0, $D2, $CF, $CD ;$6230
	.byte $A0, $01, $B0, $01, $B1, $01, $B3, $26, $A0, $A0, $D7, $E8, $E1, $F4, $A0, $F0 ;$6240
	.byte $E5, $F2, $E9, $F0, $E8, $E5, $F2, $E1, $EC, $A0, $E3, $E1, $F2, $E4, $F3, $A0 ;$6250
	.byte $E1, $F2, $E5, $A0, $E9, $EE, $F3, $F4, $E1, $EC, $EC, $E5, $E4, $BF, $05, $C3 ;$6260
	.byte $E1, $F2, $E4, $A0, $02, $BA, $A0, $07, $D5, $EE, $EB, $EE, $EF, $F7, $EE, $07 ;$6270
	.byte $D0, $F2, $E9, $EE, $F4, $E5, $F2, $09, $D8, $AD, $D9, $A0, $C9, $EE, $F0, $F5 ;$6280
	.byte $F4, $0F, $D3, $E5, $F2, $E9, $E1, $EC, $AF, $D0, $E1, $F2, $E1, $EC, $EC, $E5 ;$6290
	.byte $EC, $05, $CD, $EF, $E4, $E5, $ED, $05, $D3, $EF, $F5, $EE, $E4, $05, $C3, $EC ;$62A0
	.byte $EF, $E3, $EB, $0A, $C4, $E9, $F3, $EB, $A0, $C4, $F2, $E9, $F6, $E5, $09, $B8 ;$62B0
	.byte $B0, $AD, $C3, $EF, $EC, $F5, $ED, $EE, $07, $CE, $E5, $F4, $F7, $EF, $F2, $EB ;$62C0
	.byte $07, $D3, $F0, $E5, $E3, $E9, $E1, $EC, $14, $C2, $E5, $F2, $EE, $E9, $E5, $A0 ;$62D0
	.byte $C9, $C9, $A0, $F4, $E8, $E5, $A0, $D2, $E5, $F3, $E3, $F5, $E5, $07, $D3, $F7 ;$62E0
	.byte $E5, $E5, $F4, $B1, $B6, $05, $D8, $C7, $D3, $B3, $B2, $03, $C9, $C9, $E5, $00 ;$62F0
DATATBL63:	.byte $02, $A0, $A8, $01, $A9, $06, $CB, $E5, $E7, $F3, $B3, $B2, $03, $D8, $C7, $D3 ;$6300
	.byte $04, $CB, $E5, $E7, $F3, $0E, $C3, $E1, $F2, $E2, $EF, $EE, $A0, $C4, $E9, $EF ;$6310
	.byte $F8, $E9, $E4, $E5, $07, $C3, $E1, $F4, $E1, $EB, $E9, $E7, $07, $C1, $F0, $F0 ;$6320
	.byte $EC, $E5, $D0, $C3, $0B, $C1, $F0, $F0, $EC, $E5, $A0, $CF, $E1, $F3, $E9, $F3 ;$6330
	.byte $10, $D5, $EE, $EB, $EE, $EF, $F7, $EE, $A0, $C5, $ED, $F5, $EC, $E1, $F4, $EF ;$6340
	.byte $F2, $23, $A0, $F7, $E9, $EC, $EC, $A0, $EE, $EF, $F4, $A0, $F2, $F5, $EE, $A0 ;$6350
	.byte $EF, $EE, $A0, $C4, $CF, $D3, $A0, $B3, $AE, $B3, $AE, $A0, $CE, $E9, $E3, $E5 ;$6360
	.byte $A0, $F4, $F2, $F9, $AE, $28, $AA, $A0, $C6, $C1, $C9, $CC, $C5, $C4, $A0, $D4 ;$6370
	.byte $CF, $A0, $CC, $CF, $C1, $C4, $A0, $D0, $D2, $CF, $C4, $CF, $D3, $A0, $C6, $C9 ;$6380
	.byte $CC, $C5, $A0, $CE, $C1, $D6, $C9, $C7, $C1, $D4, $CF, $D2, $A0, $AA, $1C, $A0 ;$6390
	.byte $F2, $E5, $F1, $F5, $E9, $F2, $E5, $F3, $A0, $E1, $EE, $A0, $B8, $B0, $AD, $E3 ;$63A0
	.byte $EF, $EC, $F5, $ED, $EE, $A0, $E3, $E1, $F2, $E4, $AE, $02, $AE, $B5, $07, $C4 ;$63B0
	.byte $E5, $F3, $EB, $F4, $EF, $F0, $02, $C1, $CD, $02, $D0, $CD, $CA, $E1, $EE, $C6 ;$63C0
	.byte $E5, $E2, $CD, $E1, $F2, $C1, $F0, $F2, $CD, $E1, $F9, $CA, $F5, $EE, $CA, $F5 ;$63D0
	.byte $EC, $C1, $F5, $E7, $D3, $E5, $F0, $CF, $E3, $F4, $CE, $EF, $F6, $C4, $E5, $E3 ;$63E0
	.byte $77, $7F, $87, $91, $A1, $A7, $AD, $B3, $BE, $C8, $D0, $77, $77, $77, $77, $77 ;$63F0
DATATBL64:	.byte $C0, $6F, $1D, $10, $11, $37, $6B, $BA, $C6, $CE, $1F, $08, $95, $00, $01, $34 ;$6400
	.byte $36, $9E, $56, $39, $53, $B4, $09, $00, $00, $70, $07, $1B, $00, $00, $00, $00 ;$6410
	.byte $D6, $E2, $29, $00, $00, $00, $00, $00, $00, $21, $B3, $A9, $8A, $B7, $AE, $00 ;$6420
	.byte $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00 ;$6430
	.byte $00, $7D, $D5, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00 ;$6440
	.byte $A5, $DD, $69, $23, $E7, $7A, $BE, $0B, $D1, $3C, $A3, $45, $3E, $4C, $27, $00 ;$6450
	.byte $C9, $00, $00, $00, $00, $00, $A2, $00, $00, $00, $00, $D9, $00, $8D, $C9, $26 ;$6460
	.byte $E4, $C2, $58, $80, $B0, $0C, $DF, $93, $0E, $5B, $BC, $2E, $47, $42, $40, $AC ;$6470
	.byte $5E, $5E, $5E, $5E, $5E, $5E, $5E, $5E, $5E, $5E, $5E, $5E, $5E, $5E, $5E, $5E ;$6480
	.byte $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00 ;$6490
	.byte $A6, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $18, $C4, $EC, $00, $00 ;$64A0
	.byte $59, $AA, $CC, $99, $2D, $4A, $D3, $4E, $51, $1E, $13, $77, $B8, $0A, $00, $7C ;$64B0
	.byte $E9, $9F, $81, $63, $00, $DB, $85, $8C, $EE, $50, $A0, $00, $00, $00, $00, $00 ;$64C0
	.byte $00, $00, $00, $00, $00, $73, $83, $33, $75, $00, $00, $71, $00, $00, $00, $00 ;$64D0
	.byte $2F, $00, $91, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $87, $9C ;$64E0
	.byte $32, $60, $F1, $F4, $F7, $90, $FA, $FD, $16, $66, $6C, $04, $1A, $2B, $CA, $97 ;$64F0
DATATBL65:	.byte $A4, $A0, $A0, $A0, $C9, $D6, $D2, $C1, $D7, $D0, $C6, $D3, $D4, $CE, $CA, $C1 ;$6500
	.byte $D0, $D4, $D8, $D4, $CF, $CC, $D0, $D2, $C7, $D3, $C2, $C1, $D3, $D0, $C3, $C4 ;$6510
	.byte $C1, $B3, $D3, $C4, $D2, $D7, $C8, $C4, $D6, $D5, $D0, $D6, $C1, $D2, $D4, $CC ;$6520
	.byte $C2, $D2, $C3, $CD, $C4, $C9, $D2, $D0, $C4, $C1, $C6, $CD, $C3, $CF, $CD, $D5 ;$6530
	.byte $CD, $CD, $CD, $CC, $D2, $C1, $CE, $CD, $D2, $B7, $C5, $D8, $C5, $CE, $D4, $C9 ;$6540
	.byte $C6, $CE, $C4, $C1, $C6, $D2, $C1, $C6, $C4, $D3, $D2, $C3, $D3, $CC, $C7, $C5 ;$6550
	.byte $CF, $D6, $CC, $D0, $C1, $CC, $D0, $B1, $B6, $C7, $C4, $C2, $C9, $CE, $D4, $C2 ;$6560
	.byte $C1, $C4, $C2, $CD, $D5, $D3, $CE, $C4, $D2, $D6, $C8, $CD, $C4, $CF, $C3, $D2 ;$6570
	.byte $C2, $C1, $CE, $C9, $CE, $D3, $C3, $D2, $B1, $B6, $B8, $C9, $C3, $C4, $D6, $D2 ;$6580
	.byte $C2, $C1, $D4, $CB, $C5, $D3, $CF, $D3, $D9, $D3, $B1, $B6, $D0, $C1, $D2, $D0 ;$6590
	.byte $C9, $C3, $CE, $C3, $C6, $C7, $D7, $D0, $A0, $B8, $CF, $C2, $CA, $C3, $D0, $B8 ;$65A0
	.byte $C3, $C7, $B7, $B8, $D3, $C3, $CC, $B8, $CC, $C4, $C6, $CE, $D4, $CD, $C5, $C4 ;$65B0
	.byte $D5, $CE, $CB, $CD, $D4, $C4, $C6, $CF, $D4, $D0, $D2, $C5, $CC, $C9, $C2, $C1 ;$65C0
	.byte $B3, $C8, $CC, $D0, $C9, $C6, $D4, $C4, $CD, $C2, $C9, $CF, $CF, $C7, $D3, $D3 ;$65D0
	.byte $C1, $B7, $C9, $D0, $D3, $CE, $B2, $C7, $C4, $D0, $CE, $D4, $C2, $C4, $C6, $CF ;$65E0
	.byte $CE, $D5, $C4, $B2, $D5, $C4, $B3, $D5, $C4, $B4, $D5, $C4, $B6, $D5, $C4, $B7 ;$65F0
DATATBL66:	.byte $09, $BC, $CE, $EF, $A0, $C4, $E1, $F4, $E5, $BE, $10, $CE, $E5, $F7, $A0, $C6 ;$6600
	.byte $E9, $EC, $E5, $A0, $D4, $F9, $F0, $E5, $BA, $A0, $A4, $0F, $CE, $E5, $F7, $A0 ;$6610
	.byte $C1, $F5, $F8, $A0, $D4, $F9, $F0, $E5, $BA, $A0, $A4, $0F, $CE, $E5, $F7, $A0 ;$6620
	.byte $C4, $E9, $F3, $EB, $A0, $CE, $E1, $ED, $E5, $BA, $A0