Compare commits

...

21 Commits

Author SHA1 Message Date
Bill Chatfield b13e02601b Screen clipping works when 80-col card is active 2024-02-26 11:29:14 -05:00
Bill Chatfield a6805deddd Use ALTCHAR to determine status of 80-col card 2024-02-26 03:14:58 -05:00
Bill Chatfield 0add3cc9d7 Tried to use CR sub buit it didn't work 2024-02-25 13:53:21 -05:00
Bill Chatfield 8ace07d469 Attempt to fix line clipping 2024-02-24 02:04:14 -05:00
Bill Chatfield fc9eeda779 Attempt line clipping 2024-02-19 01:22:54 -05:00
Bill Chatfield 66afbd8512
Merge pull request #3 from gungwald/merlin-and-sc
Separated code into files for S-C and Merlin
2024-02-17 12:15:26 -05:00
Bill Chatfield e5bb256cbc Separated code into files for S-C and Merlin 2024-02-17 12:14:30 -05:00
Bill Chatfield 5e7e35e72a
Merge pull request #2 from gungwald/merlin-impl
Merlin impl
2024-02-17 12:09:17 -05:00
Bill Chatfield 7b76c77080 Added memory map comments 2024-02-17 12:03:26 -05:00
Bill Chatfield 7291a3bf3d Added copyright & license 2024-02-17 12:03:26 -05:00
Bill Chatfield 7c803937da Add breaks to switch statement 2024-02-17 12:03:26 -05:00
Bill Chatfield 903b810f1b Added error messages 2024-02-17 12:03:26 -05:00
Bill Chatfield d564d8d7dd Fix runtime errors 2024-02-17 12:03:26 -05:00
Bill Chatfield 2d2bae6f96 Finish err handling code 2024-02-17 12:03:26 -05:00
Bill Chatfield 1fbb9f7c5f Improve error handling 2024-02-17 12:03:26 -05:00
Bill Chatfield 0e5401934f More S-C updates 2024-02-01 22:45:55 -05:00
Bill Chatfield 1e6fd72e1e Added > for S-C macro call 2024-02-01 00:17:42 -05:00
Bill Chatfield 678c29acd3 Start to convert to S-C assembler syntax 2024-01-31 23:49:58 -05:00
Bill Chatfield c7ca984275 Back to latest version 2024-01-30 19:12:31 -05:00
Bill Chatfield b0b2510a96 Store older version 2024-01-30 19:11:51 -05:00
Bill Chatfield 4b6d06677b New implementation 2024-01-30 08:59:33 -05:00
9 changed files with 2079 additions and 428 deletions

4
.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
MORE
MORE.dsk
_FileInformation.txt
*.swp

View File

@ -24,9 +24,9 @@ endif
# It is necessary to use this older version of AppleCommander to support
# the PowerBook G4 and iBook G3. This version only requires Java 1.3.
AC=java -jar AppleCommander-1.3.5-ac.jar
SRC=more.s
PGM=more
BASE_DSK=prodos-2.0.3-boot.dsk
SRC=more.merlin.s
PGM=MORE
BASE_DSK=prodos-2.0.3.dsk
VOL=$(PGM)
DSK=$(PGM).dsk
@ -35,12 +35,13 @@ DSK=$(PGM).dsk
# disk instead.
#$(AC) -pro140 $(DSK) $(VOL)
$(DSK): $(PGM)
$(DSK): $(PGM) test.txt
$(COPY) $(BASE_DSK) $(DSK)
$(AC) -p $(DSK) $(PGM) BIN 0x8000 < $(PGM)
$(AC) -p $(DSK) $(PGM) BIN 0x2000 < $(PGM)
cat test.txt | tr '\n' '\r' | $(AC) -p $(DSK) TEST TXT
$(PGM): $(SRC) Makefile
merlin32 --verbose $(SRC)
merlin32 $(SRC)
clean:
$(RM) $(DSK) $(PGM) *.zip _FileInformation.txt $(PGM)_Output.txt

89
more.bas Normal file
View File

@ -0,0 +1,89 @@
10 REM *****************************
15 REM * *
20 REM * MORE - TEXT FILE VIEWER *
30 REM * AUTHOR - BILL CHATFIELD *
35 REM * *
40 REM *****************************
44 :
45 REM TODO:
46 REM CD,PREFIX,PWD,CWD,CHDIR,FASTER OUTPUT
47 REM PREFIX IN PROMPT
48 REM DETAILED HELP FROM "?" COMMAND, FIX FIRST LINE
49 :
50 LET D$ = CHR$ (4)
55 LET BS$ = CHR$ (7)
56 LET CR$ = CHR$ (13)
57 LET PROMPT$ = "[RETURN] NEXT LINE [SPACE] NEXT PAGE [Q] QUIT"
58 LET LINE = 1
59 PRINT "ENTER A FILE NAME, * FOR CATALOG, OR JUST HIT RETURN TO ABORT
."
60 INPUT "FILE:";F$
70 IF RIGHT$ (F$,1) = "*" THEN PRINT D$;"CATALOG "; LEFT$ (F$, LEN (F
$) - 1): GOTO 60
80 IF F$ = "" THEN END
85 IF F$ = "?" THEN 59
110 ONERR GOTO 5050: REM SETUP ERROR HANDLER
125 PRINT D$;"VERIFY ";F$: REM CHECK IF FILE EXISTS, ERROR CODE 6
130 PRINT D$;"OPEN ";F$: REM WILL CREATE FILE IF IT DOES NOT EXIST.
140 PRINT D$;"READ ";F$
150 GET C$
160 PRINT C$;
165 IF C$ = CR$ THEN LINE = LINE + 1
167 IF LINE = 24 THEN INVERSE : PRINT PROMPT$;: NORMAL : PRINT D$: GOSUB
4000: GOSUB 3000: GOTO 140
170 GOTO 150: REM NEXT CHARACTER IN FILE
180 REM END OF MAIN, BUT UNREACHABLE BECAUSE OF CHARACTER LOOP
3000 REM ****************
3005 REM * *
3010 REM * ERASE PROMPT *
3015 REM * *
3020 REM ****************
3025 LET PL = LEN (PROMPT$)
3030 POKE 1403,0: REM BACKUP TO BEGINNING OF LINE
3060 PRINT SPC( PL): REM ERASE PROMPT
3070 POKE 1403,0: REM BACKUP AGAIN
3080 RETURN
4000 REM ***************
4005 REM * *
4010 REM * GET COMMAND *
4015 REM * *
4020 REM ***************
4030 GET CMD$
4040 IF CMD$ = CR$ THEN LINE = 23: GOTO 4060
4050 IF CMD$ = " " THEN LINE = 1: GOTO 4060
4055 IF CMD$ = "Q" OR CMD$ = "q" THEN PRINT D$;"CLOSE": PRINT D$: PRINT
: END
4060 RETURN
5000 REM *****************
5010 REM * *
5020 REM * ERROR HANDLER *
5030 REM * *
5040 REM *****************
5050 POKE 216,0: REM TURNS OFF 'ONERR GOTO' ERROR HANDLING
5060 LET ERRCODE = PEEK (222): REM GETS THE CODE FOR THIS ERROR
5070 PRINT D$;"CLOSE": REM CLOSES ANY OPEN FILES
5080 PRINT D$: REM TURNS OFF FILE I/O SO PRINTS GO TO SCREEN
5090 IF ERRCODE = 5 THEN 5290: REM END-OF-FILE IS NOT AN ERROR
5100 PRINT : PRINT : REM SEPARATES ERR MSG FROM ANY PREVIOUS OUTPUT
5120 REM CHECK FOR DOS/PRODOS ERRORS NOT IN APPLESOFT TABLE
5130 IF ERRCODE = 6 THEN PRINT "ERROR:FILE NOT FOUND:";F$
5140 IF ERRCODE = 11 THEN PRINT "ERROR:INVALID OPTION"
5150 IF ERRCODE = 255 THEN PRINT : PRINT : PRINT "INTERRUPTED BY CTRL-C"
5155 GOTO 5290: REM SKIP TO THE END
5160 REM COPY ERROR MESSAGE FROM APPLESOFT ERROR TABLE
5170 LET BASE = 53856: REM $D260, START OF APPLESOFT ERR TABLE
5180 LET PTR = BASE + ERRCODE: REM POINT TO 1ST BYTE OF ERR MSG
5185 PRINT "ERROR:";: REM PREFIX ALL PRINTED MESSAGES WITH THIS
5190 :
5195 REM LOOP TO PRINT CHARS OF ERR MSG FROM APPLESOFT ERROR TABLE
5200 REM WHILE (THERE ARE MORE CHARS IN MESSAGE) DO
5210 LET BYTE = PEEK (PTR): REM GETS BYTE POINTED TO BY PTR
5220 IF BYTE > = 128 THEN 5280: REM DETECTS LAST BYTE
5230 PRINT CHR$ (BYTE);: REM CNVTS ASCII BYTE TO CHAR, PRINT
5240 LET PTR = PTR + 1: REM ADVANCES POINTER TO NEXT BYTE
5250 GOTO 5210: REM LOOPS BACK TO NEXT BYTE
5260 REM END WHILE
5270 :
5280 PRINT CHR$ (BYTE - 128);: REM SETS HIGH BIT TO 0, PRINT
5290 END : REM THIS IS THE END - JIM MORRISON

20
more.c
View File

@ -1,20 +0,0 @@
/*
* more.c
*
* Created on: Jan 4, 2020
* Author: bill
*/
int main(int argumentCount, char *arguments)
{
int i;
int exitCode;
if (argumentCount == 0)
exitCode = more(askUserForFile());
else
for (i = 1; i < argumentCount; ++i)
exitCode = more(arguments[i]);
return exitCode;
}

971
more.merlin.s Normal file
View File

@ -0,0 +1,971 @@
********************************
* *
* MORE - UN*X MORE COMMAND *
* ASSEMBLES WITH MERLIN *
* *
********************************
* Memory Map
*
* $0000 - $00FF Zero Page
* $0100 - $01FF Stack
* $0200 - $03FF Mostly Free, Input Buffer, Interrupt Vectors
* $0400 - $07FF Lo-res/Text Page1
* $0800 - $0BFF Lo-res/Text Page2 (BASIC programs load here)
* $0C00 - $1FFF Free
* $2000 - $3FFF Hi-res Page1
* $4000 - $5FFF Hi-res Page2
* $6000 - $95FF Free
* $9600 - $BFFF DOS3.3 and Buffers
* $C000 - $CFFF Soft Switches, Expansion Card I/O and ROM
* $D000 - $F7FF BASIC ROM (can be bankswitched later models)
* $F800 - $FFFF Machine Language Monitor ROM (also can be bankswitched)
*
* Branching
*
* CMP,CPX,CPY ->
* Condition N Z C
* Register < Memory 1 0 0
* Register = Memory 0 1 1
* Register > Memory 0 0 1
*
* BPL - BRANCH PLUS (N=0) NOT NEGATIVE
* BMI - BRANCH MINUS (N=1) NEGATIVE
* BEQ - BRANCH EQUAL (Z=1) ZERO FLAG SET
* BNE - BRANCH NOT EQUAL (Z=0) ZERO FLAG NOT SET
* BCC - BRANCH CARRY CLEAR (C=0)
* BCS - BRANCH CARRY SET (C=1)
* BVC - BRANCH OVERVLOW CLEAR (V=0)
* BVS - BRANCH OVERFLOW SET (V=1)
DSK MORE ;WRITE ASSEMBLED FILE TO DISK
TYP $06 ;$FF=SYSTEM, $06=BINARY
ORG $2000 ;ASSEMBLE START ADDRESS
*
* SYSTEM VARIABLES
*
PTR EQU 06 ;ONLY FREE 0-PAGE LOCATION
CH EQU $24 ;40-COL HORZ CURS POSITION
CV EQU $25 ;40-COL VERT CURS POSITION
PROMPT EQU $33 ;PROMPT CHARACTER
ZP_A1L EQU $3C ;MONITOR GENERAL PURPOSE
ZP_A1H EQU $3D ;MONITOR GENERAL PURPOSE
IN EQU $200 ;256-CHAR INPUT BUF
*
* SLOT 3 SCRATCHPAD RAM - TEXT PAGE 0 SCREEN HOLE
* http://yesterbits.com/media/books/apple/heiserman-1983-intermediate-level-apple-ii-handbook.pdf
*
OURCH EQU $057B ;80-COL HORIZ CURSOR POSITION
OURCV EQU $05FB ;VERTICAL CURSOR POSITION
*
* SUBROUTINES IN MONITOR ROM: $F800 - $FFFF
*
CR EQU $FC62 ;CURSOR TO BEG OF NEXT LINE
RDKEY EQU $FD0C ;READS A CHARACTER
GETLN EQU $FD6A ;READS A LINE, WITH PROMPT($33)
GETLN1 EQU $FD6F ;READS A LINE, NO PROMPT
CROUT EQU $FD8E
COUT EQU $FDED
PRBYTE EQU $FDDA
*
* SUBROUTINES IN BASIC.SYSTEM ROM:
*
GETBUFR EQU $BEF5 ;BCC=OKAY & A=HIBYTE OF BUF
;BCS=FAIL & A=ERRCODE
;X & Y ARE DESTROYED
FREEBUFR EQU $BEF8 ;FREE BUFFER
*
* PRODOS ENTRY POINT
*
PRODOS_MLI EQU $BF00 ;MACHINE LANG IFACE (MLI)
*
* MEMORY MAPPED I/O: $C000 - $CFFF
*
KBD EQU $C000 ;KEYBOARD DATA AND STROBE
CXROMOFF EQU $C006 ;SELECT SLOT ROMS
CXROMON EQU $C007 ;SELECT INTERNAL ROM
KBDSTRB EQU $C010 ;CLEAR KEYBOARD STROBE
ALTCHAR EQU $C01E ;CHARACTER SET STATUS
RD80VID EQU $C01F ;<=128->40COL, >128->80COL
INVERT EQU $CEDD ;INVERT CHARACTER ON SCREEN
PICK EQU $CF01 ;PICK CHARACTER OFF SCREEN
*
* PRODOS COMMAND CODES
*
GET_PREFIX EQU $C7
OPEN EQU $C8
READ EQU $CA
CLOSE EQU $CC
*
* PRODOS MLI PARAMETER COUNTS
*
GETPRFXPARMCNT EQU 1
OPENPARMCNT EQU 3
READPARMCNT EQU 4
CLOSEPARMCNT EQU 1
*
* ASCII
*
CR_CHAR EQU $0D ;ASCII CARRIAGE RETURN
CR_HIBIT EQU $8D ;CARRIAGE RET WITH HIGH BIT SET
*
* CONSTANTS
*
EOFERR EQU $4C ;ERROR CODE FOR END-OF-FILE
MAXERCDE EQU $5A ;LARGEST ERROR CODE
BUFSIZE EQU $00FF
SCR_HGHT EQU 24 ;SCREEN HEIGHT
*
* DEBUGGING
*
TRACE EQU 0
********************************
* *
* PUSH Y ONTO THE STACK *
* DESTROYS A *
* *
********************************
PUSHY MAC
TYA
PHA
<<<
********************************
* *
* POP Y FROM THE STACK *
* DESTROYS A *
* *
********************************
POPY MAC
PLA
TAY
<<<
********************************
* *
* COPY IN BUF TO STRING *
* *
* X CONTAINS LENGTH OF "IN" *
* ]1 IS DEST STRING (LEN BYT) *
* A IS DESTROYED *
* *
********************************
CPIN MAC
PUSHY ;SAVE Y
STX ]1 ;COPY LENGTH TO FIRST BYTE OF ]1
LDY #0 ;INIT Y TO ZERO
LOOP CPY ]1 ;COMPARE Y WITH LENGTH BYTE
BEQ ENDLOOP ;DONE IF LENGTH IS REACHED
LDA IN,Y ;LOAD IN[Y] INTO ACCUMULATOR
CMP #CR_CHAR ;COMPARE WITH CARRIAGE RETURN
BEQ ENDLOOP ;STOP AT CARRIAGE RETURN
INY ;DEST STR IS 1 AHEAD OF IN BUF
STA ]1,Y ;COPY CHAR TO DEST STR ]1
JMP LOOP ;LOOP TO NEXT CHAR
ENDLOOP POPY ;RESTORE Y
<<<
********************************
* *
* WRITES A LENGTH PREFIXED *
* STRING TO THE SCREEN *
* A IS DESTROYED *
* *
********************************
PUTS MAC
PUSHY
LDY #0 ;INIT LOOP INDEX
LOOP CPY ]1 ;HAS STR LENGTH BEEN REACHED
BEQ ENDLOOP ;IF SO THEN FINISH
INY ;MOVE TO INDEX OF NEXT CHAR
LDA ]1,Y ;GET THE CHAR TO BE WRITTEN
JSR COUT ;WRITE THE CHARACTER
JMP LOOP ;LOOP
ENDLOOP POPY
<<<
********************************
* *
* SET TO #1 (IMMEDIATE 1) *
* ]1 DESTINATION *
* A IS DESTROYED *
* *
********************************
SET1 MAC
LDA #1
STA ]1
<<<
SET0 MAC
LDA #0
STA ]1
<<<
SET23 MAC
LDA #23
STA ]1
<<<
********************************
* *
* STANDARD ASSEM LANG *
* BACKWARDS COPY OF 1 BYTE *
* A IS DESTROYED *
* ]1 DESTINATION *
* ]2 SOURCE *
* *
********************************
COPY_B MAC
LDA ]2
STA ]1
<<<
********************************
* *
* MAIN PROGRAM *
* *
********************************
MAIN CLD ;CLEAR DECIMAL FLG, AVOID CRASH
SET0 USRQUIT ;INITIALIZE TO "NO"
JSR GET_SCRN_WDTH
*
* GET PREFIX TO SEE IF IT IS SET
*
JSR PRODOS_MLI
DB GET_PREFIX
DA GETPRFXPARMS
BEQ :CHKPREFIX
JSR GETPRFXERR
JMP :END
:CHKPREFIX LDA PREFIX
CMP #0
BNE :GETFILE
JSR CROUT
PUTS WARNING
PUTS NOPREFIXMSG
JSR CROUT
JSR CROUT
*
* GET FILE NAME
*
:GETFILE PUTS INFOLINE
JSR CROUT
:ASKFILE PUTS FILEPROMPT
JSR GETLN1 ;LENGTH IN X, CR AT END
CPX #0 ;IS THE LENGTH ZERO?
BNE :CONT0 ;USER JUST PRESSED RETURN
JMP :END
:CONT0 CPX #1
BNE :CONT1
LDA #"?"
CMP IN
BNE :CONT1
JSR HELPINFO
JMP :ASKFILE
:CONT1 CPIN FILENAME ;COPY "IN" BUF TO FILENAME
DO TRACE
JSR PRSTRBYTES
JSR GETLN
FIN
*
* GET FILE I/O BUFFER FOR OPEN CALL
*
LDA #4 ;FOUR 256 BYTE PAGES = 1KB
JSR GETBUFR ;GET BUF FROM BASIC.SYSTEM
BCC :CONT2 ;CARRY CLEAR MEANS NO ERROR
JSR OBUFERR
JMP :END
:CONT2 STA OBUFADDR+1 ;GETBUFR RETURNS HIBYTE IN A
LDA #0 ;PREPARE
STA OBUFADDR ;LOBYTE IS 0 B/C ADDR OF PAGE
*
* OPEN FILE
*
JSR PRODOS_MLI
DB OPEN
DA OPENPARMS
BEQ :CONT3
JSR OPENERR
JSR FREEBUFR ;CLEAN UP BEFORE TRY AGAIN
JMP :ASKFILE
*
* COPY FILE NUMBER FROM OPEN PARAMETERS TO READ AND CLOSE
*
:CONT3 LDA OPENFNUM
STA READFNUM
STA CLOSFNUM
*
* GET BUFFER FOR READ OPERATION FROM BASIC.SYSTEM
*
LDA #1 ;ONE 256 BYTE BUFFER
JSR GETBUFR ;CALL BASIC.SYSTEM SUB
BCC :CONT4
JSR RBUFERR ;CARRY SET MEANS ERROR
JMP :CLOSFILE
:CONT4 STA RBADDR+1 ;STORE HI-BYTE
STA ZP_A1H ;FOR 0-PAGE INDIRECTION
LDA #0 ;0 FOR LO-BYTE
STA RBADDR ;STORE IT
STA ZP_A1L ;AGAIN, FOR 0-PAGE INDIRECTION
*
* PRINT THE FILE
*
JSR VIEWFILE
*
* CLEANUP
*
JSR FREEBUFR ;FREE READ BUFFER
*
* Close file
*
:CLOSFILE JSR PRODOS_MLI ;CLOSE THE FILE
DB CLOSE
DA CLOSEPARMS
BEQ :FREEOBUF
JSR CLOSERR
:FREEOBUF JSR FREEBUFR ;FREE OPEN I/O BUFFER
:END NOP
RTS
********************************
* *
* END OF MAIN - PROGRAM EXIT *
* *
********************************
********************************
* *
* DETERMINE IF SCREEN IS IN *
* 40 COL OR 80 COL MODE *
* *
********************************
GET_SCRN_WDTH LDA #%10000000 ;USE ALTCHARSET STATUS TO
BIT ALTCHAR ;SEE IF 80-COL CARD TURNED ON
BMI :CARD_ACTIVE ;BIT 7 ON = NEG & CARD ACTIVE
JMP :FORTY_COLUMNS ;INACTIVE CARD IS 40-COL
:CARD_ACTIVE LDA #%10000000 ;SEE IF CARD IS IN 40/80 MODE
BIT RD80VID ;BIT 7 OFF = 0 OR >0 & 40-COL
BMI :EIGHTY_COLUMNS ;BIT 7 ON = NEG & 80-COL MODE
:FORTY_COLUMNS LDA #40
STA SCR_WDTH
JMP :END
:EIGHTY_COLUMNS LDA #80
STA SCR_WDTH
:END
DO TRACE
LDA ALTCHAR
JSR PRBYTE
JSR CROUT
LDA RD80VID
JSR PRBYTE
JSR CROUT
PUTS SCR_WDTH_TXT
LDA SCR_WDTH
JSR PRBYTE
JSR CROUT
FIN
RTS
********************************
* *
* PROGRAM INFO AND HELP *
* *
********************************
HELPINFO JSR CROUT
PUTS INFO0
JSR CROUT
PUTS INFO1
JSR CROUT
PUTS INFO2
JSR CROUT
PUTS INFO3
JSR CROUT
PUTS INFO4
JSR CROUT
JSR CROUT
RTS
********************************
* *
* HANDLE ERROR WHEN GETTING *
* PREFIX *
* *
********************************
GETPRFXERR STA ERRCODE
PUTS GETPRFXERRMSG
LDA #":"
JSR COUT
LDA ERRCODE
JSR ERRPROC
RTS
********************************
* *
* HANDLE ERROR WHEN OPENING *
* FILE *
* *
********************************
OPENERR STA ERRCODE
PUTS OERRMSG
PUTS FILENAME
LDA #":"
JSR COUT
LDA ERRCODE
JSR ERRPROC
RTS
********************************
* *
* HANDLE ERROR WHEN CLOSING *
* FILE *
* *
********************************
CLOSERR STA ERRCODE
PUTS CERRMSG
PUTS FILENAME
LDA #"'"
JSR COUT
LDA #":"
JSR COUT
LDA ERRCODE
JSR ERRPROC
RTS
********************************
* *
* HANDLE ERROR WHEN REQUESTING *
* READ BUFFER *
* *
********************************
RBUFERR STA ERRCODE
PUTS RBERRMSG
LDA #":"
JSR COUT
LDA ERRCODE
JSR ERRPROC
RTS
********************************
* *
* HANDLE ERROR WHEN REQUESTING *
* READ BUFFER *
* *
********************************
OBUFERR STA ERRCODE
PUTS OBERRMSG
LDA #":"
JSR COUT
LDA ERRCODE
JSR ERRPROC
RTS
********************************
* *
* PRINT "IN" BUFFER *
* *
********************************
PRINT_IN
PUSHY
LDA #"X"
JSR COUT
LDA #"="
JSR COUT
TXA
JSR PRBYTE
JSR CROUT
LDY #0
:LOOP CPY #255
BEQ :ENDLOOP
LDA IN,Y
JSR PRBYTE
LDA #" "
JSR COUT
INY
JMP :LOOP
:ENDLOOP JSR CROUT
POPY
RTS
********************************
* *
* PRINT STRING BYTES *
* *
********************************
PRSTRBYTES PUSHY
LDY #0
:LOOP CPY #255
BEQ :ENDLOOP
LDA FILENAME,Y
JSR PRBYTE
LDA #" "
JSR COUT
INY
JMP :LOOP
:ENDLOOP JSR CROUT
POPY
RTS
********************************
* *
* VIEW FILE SUB *
* *
********************************
VIEWFILE
DO TRACE
PUTS ENVIEW
FIN
COPY_B SCRNLINE;#1 ;INIT SCREEN LINE NUMBER
COPY_B LINEIDX;#1 ;POSITION IN LINE
:LOOP JSR PRODOS_MLI ;CALL PRODOS TO READ FILE
DB READ ;SPECIFY PRODOS READ COMMAND
DA READPARMS ;READ PARAMETERS
BNE :READERR
JSR WRITEBUF ;WRITE TO SCREEN WHAT WAS READ
LDA #1 ;PREPARE FOR NEXT OP
CMP USRQUIT ;IF USER WANTS TO QUIT, THEN
BEQ :ENDLOOP ;EXIT THE LOOP
JMP :LOOP ;ELSE, GET THE NEXT BUFFER
:READERR JSR ERRPROC
:ENDLOOP NOP
RTS
********************************
* *
* WRITE BUFFER TO SCREEN *
* *
********************************
WRITEBUF PUSHY
LDY #0 ;INIT CHAR COUNTER VARIABLE
:LOOP CPY READCNT ;COMPARE TO MAX CHARS
BEQ :ENDLOOP
LDA (ZP_A1L),Y ;GET CHAR FROM BUFFER
ORA #%10000000 ;TURN ON HIGH BIT FOR PRINTING
JSR WRITECHAR ;COUT PRESERVES ACCUM
*
* CHECK AT END OF PAGE
*
LDA SCRNLINE ;CURSOR VERTICAL SCREEN LINE
CMP #SCR_HGHT ;AT BOTTOM OF SCREEN?
BNE :CONT ;NO? THEN NEXT CHAR
JSR STATBAR ;YES? THEN SHOW THE STATUS BAR
LDA #1 ;SETUP FOR NEXT LINE
CMP USRQUIT ;DID USER ASK TO QUIT
BEQ :ENDLOOP ;YES? THEN END SUB
:CONT INY ;STATBAR HAS ADJUSTED LINENUM
JMP :LOOP
:ENDLOOP NOP
POPY
DO TRACE
PUTS EXWRITEBUF
FIN
RTS
********************************
* *
* WRITE CHAR TO SCREEN *
* CLIPS TO SCREEN WIDTH *
* *
********************************
WRITECHAR STA CHAR ;DON'T LOOSE THE CHARACTER
CMP #CR_HIBIT ;COMPARE TO CARRIAGE RETURN
BNE :NOT_EOL ;IF NOT END OF LINE, PRINT
JSR DOWN1LINE
JMP :ENDSUB ;NOTHING MORE TO DO FOR EOL
:NOT_EOL LDA LINEIDX ;GET CURSOR HORIZ COL
CMP SCR_WDTH ;COMPARE WITH SCREEN WIDTH
BPL :FORWARD ;DON'T PRINT IF OFF SCREEN
LDA CHAR ;ON SCREEN, SO PRINT IT
JSR COUT
:FORWARD INC LINEIDX
:ENDSUB RTS
********************************
* *
* GO TO BEGINNING OF NEXT LINE *
* *
********************************
DOWN1LINE INC SCRNLINE ;KEEP TRACK OF LINE NUMBER
COPY_B LINEIDX;#1 ;RESET TO BEGINNING OF LINE
;COPY_B OURCH;#0
JSR CROUT ;LINE DOWN & SCROLL IF NEEDED
RTS
********************************
* *
* PRINT ASCII IN HEX *
* *
********************************
PRASCII PHA
LDA #"["
JSR COUT
PLA
JSR PRBYTE
LDA #"]"
JSR COUT
LDA #" "
JSR COUT
RTS
********************************
* *
* DO THE STATUS BAR *
* *
********************************
STATBAR
DO TRACE
PUTS ENSTATB
FIN
PUSHY
PUTS BAR
:LOOP JSR RDKEY ;GET A KEY FROM THE USER
CMP #" " ;CHECK IF SPACE ENTERED
BNE :CHKCR ;IF NOT FORWARD TO NEXT CHECK
SET1 SCRNLINE ;ADVANCE ONE PAGE, STORE 1
JMP :ENDLOOP ;PROCESSED SPACE SO DONE
:CHKCR CMP #CR_HIBIT ;CHECK FOR CARRIAGE RETURN
BNE :CHKQUIT
SET23 SCRNLINE
JMP :ENDLOOP
:CHKQUIT CMP #"Q" ;USER WANTS TO QUIT
BEQ :QUITTING ;NO RECOGNIZED INPUT
CMP #"q"
BEQ :QUITTING
JMP :LOOP
:QUITTING SET1 USRQUIT
:ENDLOOP JSR ERASEBAR
POPY
DO TRACE
PUTS EXSTATB
FIN
RTS
********************************
* *
* ERASE STATUS BAR *
* *
********************************
ERASEBAR
DO TRACE
PUTS ENERASEB
FIN
PUSHY
SET0 OURCH ;RESET CURSOR TO BEG OF LINE
LDY #0 ;INIT COUNTER FOR SPACES
:LOOP CPY BAR ;FIRST BYTE IS LENGTH
BEQ :ENDLOOP ;IF Y=LEN THEN DONE
LDA #" " ;LOAD SPACE
JSR COUT ;WRITE TO SCREEN
INY ;MAKE PROGRESS
JMP :LOOP ;LOOP TO NEXT CHAR
:ENDLOOP SET0 OURCH ;RESET CURSOR TO BEG OF LINE
POPY
DO TRACE
PUTS EXERASEB
FIN
RTS
********************************
* *
* ERROR HANDLER *
* INPUT PARAM: A HOLDS ERRCODE *
* *
********************************
ERRPROC
STA ERRCODE
CMP #0
BNE :EEOF
JMP :END
:EEOF CMP #EOFERR
BNE :E01
JMP :END
:E01 CMP #1
BNE :E04
PUTS E01MSG
JMP :END
:E04 CMP #4
BNE :E25
PUTS E04MSG
JMP :END
:E25 CMP #$25
BNE :E27
PUTS E25MSG
JMP :END
:E27 CMP #$27
BNE :E28
PUTS E27MSG
JMP :END
:E28 CMP #$28
BNE :E2B
PUTS E28MSG
JMP :END
:E2B CMP #$2B
BNE :E2E
PUTS E2BMSG
JMP :END
:E2E CMP #$2E
BNE :E40
PUTS E2EMSG
JMP :END
:E40 CMP #$40
BNE :E42
PUTS E40MSG
JMP :END
:E42 CMP #$42
BNE :E43
PUTS E42MSG
JMP :END
:E43 CMP #$43
BNE :E44
PUTS E43MSG
JMP :END
:E44 CMP #$44
BNE :E45
PUTS E44MSG
JMP :END
:E45 CMP #$45
BNE :E46
PUTS E45MSG
JMP :END
:E46 CMP #$46
BNE :E47
PUTS E46MSG
JMP :END
:E47 CMP #$47
BNE :E48
PUTS E47MSG
JMP :END
:E48 CMP #$48
BNE :E49
PUTS E48MSG
JMP :END
:E49 CMP #$49
BNE :E4A
PUTS E49MSG
JMP :END
:E4A CMP #$4A
BNE :E4B
PUTS E4AMSG
JMP :END
:E4B CMP #$4B
BNE :E4C
PUTS E4BMSG
JMP :END
:E4C CMP #$4C
BNE :E4D
PUTS E4CMSG
JMP :END
:E4D CMP #$4D
BNE :E4E
PUTS E4DMSG
JMP :END
:E4E CMP #$4E
BNE :E50
PUTS E4EMSG
JMP :END
:E50 CMP #$50
BNE :E51
PUTS E50MSG
JMP :END
:E51 CMP #$51
BNE :E52
PUTS E51MSG
JMP :END
:E52 CMP #$52
BNE :E53
PUTS E52MSG
JMP :END
:E53 CMP #$53
BNE :E55
PUTS E53MSG
JMP :END
:E55 CMP #$55
BNE :E56
PUTS E55MSG
JMP :END
:E56 CMP #$56
BNE :E57
PUTS E56MSG
JMP :END
:E57 CMP #$57
BNE :E5A
PUTS E57MSG
JMP :END
:E5A CMP #$5A
BNE :E_UNK
PUTS E5AMSG
JMP :END
:E_UNK PUTS E_UNK_MSG
LDA #":"
JSR COUT
LDA ERRCODE
JSR PRBYTE
:END JSR CROUT
RTS
********************************
* *
* DATA DIVISION HAHA *
* *
********************************
INFOLINE STR "ENTER [?] FOR PROGRAM INFO AND HELP"
INFO0 STR "MORE - PAGES THROUGH TEXT FILE"
INFO1 STR "COPYRIGHT (C) 2024 BILL CHATFIELD"
INFO2 STR "DISTRIBUTED UNDER THE GPL VERSION 3"
INFO3 STR "https://github.com/gungwald/prodos-more"
INFO4 STR "PRESS RETURN TO QUIT"
FILEPROMPT STR "FILE:"
ERRTXT STR "ERROR:"
FILENAME DS $FF
PREFIX DS 64
ERRCODE DS 1
SCRNLINE DS 1
LINEIDX DS 1
CHAR DS 1
BAR STR '[RET] LINE [SPC] PAGE [Q]UIT'
USRQUIT DS 1
BUFCHAR DS 1
USRCHAR DS 1
SCR_WDTH DS 1
SCR_WDTH_TXT STR "SCREEN WIDTH="
PREFIXMSG STR "THE PREFIX IS "
WARNING STR 'WARNING'
NOPREFIXMSG STR ": NO PREFIX IS SET. YOU MUST ENTER THE FULL PATH TO THE FILE."
GETPRFXERRMSG STR "CANNOT GET PREFIX"
OERRMSG STR "CANNOT OPEN "
CERRMSG STR "CANNOT CLOSE "
RBERRMSG STR "CANNOT CREATE READ BUFFER"
OBERRMSG STR "CANNOT CREATE FILE BUFFER"
E00MSG STR "NO ERROR"
E01MSG STR "BAD SYSTEM CALL NUMBER"
E04MSG STR "BAD SYSTEM CALL PARAMETER COUNT"
E25MSG STR "INTERRUPT TABLE FULL"
E27MSG STR "I/O ERROR"
E28MSG STR "NO DEVICE CONNECTED"
E2BMSG STR "DISK WRITE PROTECTED"
E2EMSG STR "DISK SWITCHED"
E40MSG STR "INVALID PATHNAME"
E42MSG STR "MAXIMUM NUMBER OF FILES OPEN"
E43MSG STR "INVALID REFERENCE NUMBER"
E44MSG STR "DIRECTORY NOT FOUND"
E45MSG STR "VOLUME NOT FOUND"
E46MSG STR "FILE NOT FOUND"
E47MSG STR "DUPLICATE FILENAME"
E48MSG STR "VOLUME FULL"
E49MSG STR "VOLUME DIRECTORY FULL"
E4AMSG STR "INCOMPATIBLE FILE FORMAT OR PRODOS DIRECTORY"
E4BMSG STR "UNSUPPORTED STORAGE TYPE"
E4CMSG STR "END OF FILE ENCOUNTERED"
E4DMSG STR "POSITION OUT OF RANGE"
E4EMSG STR "FILE ACCESS ERROR OR FILE LOCKED"
E50MSG STR "FILE IS OPEN"
E51MSG STR "DIRECTORY STRUCTURE DAMAGED"
E52MSG STR "NOT A PRODOS VOLUME"
E53MSG STR "INVALID SYSTEM CALL PARAMETER"
E55MSG STR "VOLUME CONTROL BLOCK TABLE FULL"
E56MSG STR "BAD BUFFER ADDRESS"
E57MSG STR "DUPLICATE VOLUME"
E5AMSG STR "FILE STRUCTURE DAMAGED"
E_UNK_MSG STR "UNKNOWN ERROR CODE"
ENVIEW STR 'ENTERING VIEWFILE'
EXVIEW STR 'EXITING VIEWFILE'
EXWRITEBUF STR 'EXITING WRITEBUF'
ENSTATB STR 'ENTERING STATUSBAR'
EXSTATB STR 'EXITING STATUSBAR'
ENERASEB STR 'ENTERING ERASEBAR'
EXERASEB STR 'EXITING ERASEBAR'
*
* GET_PREFIX PARAMETERS
*
GETPRFXPARMS DB #GETPRFXPARMCNT
PREFIXADDR DA PREFIX
*
* OPEN PARAMETERS
*
OPENPARMS DB #OPENPARMCNT
DA FILENAME
OBUFADDR DS 2
OPENFNUM DS 1
*
* READ PARAMETERS
*
READPARMS DB #READPARMCNT
READFNUM DS 1
RBADDR DS 2
REQCNT DW BUFSIZE
READCNT DS 2
*
* CLOSE PARAMETERS
*
CLOSEPARMS DB #CLOSEPARMCNT
CLOSFNUM DS 1
*
* BUFFERS
*
* CONSUME ALL BYTES UP TO THE NEXT PAGE BOUNDRY
FILLER DS \,$00
* MUST START ON PAGE BOUNDRY
*OPENBUF DS 1024
*READBUF DS BUFSIZE

402
more.s
View File

@ -1,402 +0,0 @@
*
* more - Text viewer
*
* BEQ - Branch if Equal
* Branches if the zero flag (Z) is set to 1. This happens if:
* - A 0 value is loaded into the accumulator via LDA
* - A CMP is done on two equal values
* - A SBC is done on two equal values?
* BCC - Branch if Carry Flag is Clear
* Equivalent to Branch if Less Than (BLT), meaning that the
* accumulator (A) is less than the parameter: A < Param
* BGE - Branch if Accum >= Param is BCS
PROMPT equ $33
BUFF equ $200
* System subroutines stored in Monitor ROM
GETLN equ $fd6a ; Reads a line of input, with prompt from $33
GETLNZ equ $fd67 ; Reads a line of input, CR first
GETLN1 equ $fd6f ; Reads a line of input, no prompt
CROUT equ $fd8e ; Outputs a carriage return
PRBYTE equ $fdda ; Outputs a byte
COUT equ $fded ; Outputs a character
* MLI stands for Machine Language Interface
* It is the ProDOS system call entry point
MLI equ $bf00
* ProDOS system call command codes
OPEN equ $c8
READ equ $ca
CLOSE equ $cc
* Constants
EOF equ $4c ; End of file
PTR equ $06
MAX_EC equ $5a ; The largest error code
CR equ $0d ; Carriage return
BUF_SIZ equ $00ff
WRITE_CHAR mac
if #=]1
lda ]1
else
lda #]1
fin
jsr COUT
eom
WRITE_BYTE mac
lda ]1
jsr PRBYTE
eom
WRITE_ASC mac
tya ; Preserve Y by transferring it to A
pha ; and pushing it onto the stack
ldy #0 ; Prepare loop index
nextch lda ]1,Y ; Load a character into A
beq finish ; Branch if lda loaded a zero value
jsr COUT ; Write the character in A
iny ; Increment Y
jmp nextch ; Go back and load the next character
finish pla ; Restore Y by pulling stack into A
tay ; and transferring it to Y
eom
WRITE_STR mac
tya ; Preserve Y
pha
lda ]1 ; Length byte
sta len
ldy #1 ; Prepare loop index
nextChar tya
cmp len ; Check if beyond end of string
bcc writeChar ; Y is Less than
beq writeChar ; or equal to len
jmp finish
writeChar lda ]1,y ; Load a character
jsr COUT
iny
jmp nextChar
len db 0
finish pla ; Restore Y
tay
eom
COPY_BYTE mac
lda ]1
sta ]2
eom
* Copies a line out of BUFF into ]1.
* Length is in X as is done by GETLN.
COPY_BUFF mac
tya ; Preserve Y register
pha ; by pushing it on the stack
txa ; Transfer X to A for compare
cmp #$ff ; Check if string is too long
bne startCopy ; If not, get started
dex ; If so, shrink to fit with length byte
startCopy stx ]1 ; Store length to target string
ldy #0 ; Initialize loop index
nextChar tya ; Move current position to A
cmp ]1 ; Compare current position with length
beq endCopyLine ; Quit if we've reached the end
lda BUFF,y ; Load current character
iny ; BUFF and ]1 are off by 1 because of len byte
sta ]1,y ; Store character into target string
jmp nextChar ; Continue with next character
endCopyLine pla ; Restore Y by pulling value from stack
tay ; and transferring to Y
eom
WRITE_BUFF mac
tya
pha
stx len
ldy #0
nextByte tya
cmp len
beq done
lda BUFF,y
jsr COUT
iny
jmp nextByte
done pla
tay
eom
* Starting at $9000 because:
* $800 overwrites Applesoft
* $803 is where Applesoft programs start
* $2000 is where the current .SYSTEM program is loaded
mainProgram
org $8000
getFileNam
WRITE_ASC prompt
COPY_BYTE #"?";PROMPT
jsr GETLN1
WRITE_ASC buffText
WRITE_BUFF
jsr CROUT
COPY_BUFF fileName
openFile jsr MLI
db OPEN
da openParams
bne openErrorHandler
readFile COPY_BYTE fileNum;readNum
readNext jsr MLI
db READ
da readParams
cmp #EOF
beq closeFile
cmp #0
bne readErrorHandler
writeScreen
ldy #0
sty lineCount
sty charCount
nextChar lda readIoBuf,y
inc charCount
ora #$80
jsr COUT
cmp $0d
bne continue
inc lineCount
continue cpy #<BUF_SIZ
beq readNext
iny
jmp nextChar
closeFile COPY_BYTE fileNum;closeNum
jsr MLI
db CLOSE
dw closeParams
bne closeErrorHandler
jmp endMain
openErrorHandler
sta errorCode
WRITE_ASC openFailureText
jmp errorHandler
readErrorHandler
sta errorCode
WRITE_ASC readFailureText
jmp errorHandler
closeErrorHandler
sta errorCode
WRITE_ASC closeFailureText
errorHandler
WRITE_STR fileName
WRITE_CHAR ":"
WRITE_CHAR " "
lda errorCode
cmp #MAX_EC ; Compare by A - MAX_EC
bcs unknownError ; Branch if A >= MAX_EC
lda errorCode ; Necessary?
clc ; Prepare for addition
adc errorCode ; Double for indexing addresses
tax
lda errorMessages,x
sta PTR
inx
lda errorMessages,x
sta PTR+1
bne writeError
lda PTR
bne writeError
unknownError
WRITE_ASC unknownErrorCodeText
WRITE_CHAR "$"
WRITE_BYTE errorCode
jsr CROUT
jmp endMain
writeError
WRITE_ASC (PTR)
WRITE_CHAR " "
WRITE_ASC errorCodeText
WRITE_CHAR "$"
WRITE_BYTE errorCode
WRITE_CHAR ")"
jsr CROUT
endMain
COPY_BYTE #"]";PROMPT ; Restore normal prompt
rts
* DAT-uh
openParams db 3 ; Parameter count
oPathPtr da fileName ; Input param - file to open
oBufPtr da openIoBuf ; Input param - I/O buffer
fileNum ds 1 ; Output param - file ref num
readParams db 4
readNum ds 1
da readIoBuf
reqCount dw BUF_SIZ
transCount ds 2
closeParams db 1 ; Parameter count
closeNum db 0 ; Input param - ref num to close
fileName ds $ff ; String starting with length byte
charCount ds 2
lineCount ds 1
len ds 1
buffText asc "BUFF=",00
prompt asc "ENTER FILE NAME: ",00
errorCode db 0
openFailureText asc "FAILED TO OPEN FILE ",00
readFailureText asc "FAILED TO READ FILE ",00
closeFailureText asc "FAILED TO CLOSE FILE ",00
errorCodeText asc "(ERROR CODE ",00
unknownErrorCodeText asc "UNKNOWN ERROR CODE: ",00
em00 asc "NO ERROR",00
em01 asc "BAD SYSTEM CALL NUMBER",00
em03 asc "NO DEVICE CONNECTED",00 ; Bug in AppleWin < 1.26.3.0
em04 asc "BAD SYSTEM CALL PARAMETER COUNT",00
em25 asc "INTERRUPT VECTOR TABLE FULL",00
em27 asc "I/O ERROR",00
em28 asc "DEVICE NOT CONNECTED",00
em2b asc "DISK WRITE PROTECTED",00
em2e asc "DISK SWITCHED WHILE FILE STILL OPEN",00
em40 asc "PATH CONTAINS ILLEGAL CHARACTERS",00
em42 asc "CANNOT EXCEED 8 OPEN FILES",00
em44 asc "PATH NOT FOUND",00
em45 asc "VOLUME DIRECTORY NOT FOUND",00
em46 asc "FILE NOT FOUND",00
em47 asc "DUPLICATE FILENAME",00
em48 asc "DISK IS FULL",00
em49 asc "CANNOT EXCEED 51 DIRECTORY ENTRIES",00
em4a asc "INCOMPATIBLE FILE FORMAT",00
em4b asc "UNSUPPORTED STORAGE TYPE",00
em4c asc "END OF FILE",00
em4d asc "FILE POSITION OUT OF RANGE",00
em4e asc "FILE ATTRIBUTE FORBIDS OPERATION",00
em50 asc "FILE IS OPEN",00
em51 asc "DIRECTORY COUNT ERROR",00
em52 asc "NOT A PRODOS DISK",00
em55 asc "VOLUME CONTROL BLOCK FULL",00
em56 asc "BAD BUFFER ADDRESS",00
em57 asc "DUPLICATE VOLUME",00
em5a asc "BIT MAP DISK ADDRESS IS IMPOSSIBLE",00
*
* ERROR CODE TO MESSAGE TRANSLATION TABLE
*
errorMessages
ec00 da em00
ec01 da em01
ec02 da $0000
ec03 da em03 ; Bug in AppleWin < 1.26.3.0
ec04 da em04
ec05 da $0000
ec06 da $0000
ec07 da $0000
ec08 da $0000
ec09 da $0000
ec0a da $0000
ec0b da $0000
ec0c da $0000
ec0d da $0000
ec0e da $0000
ec0f da $0000
ec10 da $0000
ec11 da $0000
ec12 da $0000
ec13 da $0000
ec14 da $0000
ec15 da $0000
ec16 da $0000
ec17 da $0000
ec18 da $0000
ec19 da $0000
ec1a da $0000
ec1b da $0000
ec1c da $0000
ec1d da $0000
ec1e da $0000
ec1f da $0000
ec20 da $0000
ec21 da $0000
ec22 da $0000
ec23 da $0000
ec24 da $0000
ec25 da $0000
ec26 da $0000
ec27 DA em27
ec28 DA em28
ec29 da $0000
ec2a da $0000
ec2b da $0000
ec2c da $0000
ec2d da $0000
ec2e DA em2e
ec2f da $0000
ec30 da $0000
ec31 da $0000
ec32 da $0000
ec33 da $0000
ec34 da $0000
ec35 da $0000
ec36 da $0000
ec37 da $0000
ec38 da $0000
ec39 da $0000
ec3a da $0000
ec3b da $0000
ec3c da $0000
ec3d da $0000
ec3e da $0000
ec3f da $0000
ec40 da em40
ec41 da $0000
ec42 da em42
ec43 da $0000
ec44 da em44
ec45 da em45
ec46 da em46
ec47 da em47
ec48 da em48
ec49 da em49
ec4a da em4a
ec4b da em4b
ec4c da em4c
ec4d da em4d
ec4e da em4e
ec4f da $0000
ec50 da em50
ec51 da em51
ec52 da em52
ec53 da $0000
ec54 da $0000
ec55 da em55
ec56 da em56
ec57 da em57
ec58 da $0000
ec59 da $0000
ec5a da em5a
*
* Consume all bytes up to next page boundary
*
filler ds \,$00
*
* Must start on page boundary
*
openIoBuf ds 1024
readIoBuf ds BUF_SIZ

813
more.sc.s Normal file
View File

@ -0,0 +1,813 @@
********************************
* *
* MORE - UN*X MORE COMMAND *
* ASSEMBLES WITH S-C *
* *
********************************
* Memory Map
*
* $0000 - $00FF Zero Page
* $0100 - $01FF Stack
* $0200 - $03FF Mostly Free, Input Buffer, Interrupt Vectors
* $0400 - $07FF Lo-res/Text Page1
* $0800 - $0BFF Lo-res/Text Page2 (BASIC programs load here)
* $0C00 - $1FFF Free
* $2000 - $3FFF Hi-res Page1
* $4000 - $5FFF Hi-res Page2
* $6000 - $95FF Free
* $9600 - $BFFF DOS3.3 and Buffers
* $C000 - $CFFF Soft Switches, Expansion Card I/O and ROM
* $D000 - $F7FF BASIC ROM (can be bankswitched later models)
* $F800 - $FFFF Machine Language Monitor ROM (also can be bankswitched)
DSK MORE ;WRITE ASSEMBLED FILE TO DISK
TYP $06 ;$FF=SYSTEM, $06=BINARY
ORG $2000 ;ASSEMBLE START ADDRESS
* SYSTEM VARIABLES
*
IN .EQ $200 ;256-CHAR INPUT BUF
*
* SUBROUTINES IN MONITOR ROM: $F800 - $FFFF
*
RDKEY .EQ $FD0C ;READS A CHARACTER
GETLN .EQ $FD6A ;READS A LINE, WITH PROMPT($33)
GETLN1 .EQ $FD6F ;READS A LINE, NO PROMPT
CROUT .EQ $FD8E
COUT .EQ $FDED
PRBYTE .EQ $FDDA
*
* SUBROUTINES IN BASIC.SYSTEM ROM:
GETBUFR EQU $BEF5 ;BCC=OKAY & A=HIBYTE OF BUF
;BCS=FAIL & A=ERRCODE
;X & Y ARE DESTROYED
FREEBUFR EQU $BEF8 ;FREE BUFFER
* PRODOS ENTRY POINT
PRODOS_MLI EQU $BF00 ;MACHINE LANG IFACE (MLI)
*
* MEMORY MAPPED I/O: $C000 - $CFFF
*
RD80VID EQU $C01F ;<=128->40COL, >128->80COL
*
* SLOT 3 SCRATCHPAD RAM - TEXT PAGE 0 SCREEN HOLE
* http://yesterbits.com/media/books/apple/heiserman-1983-intermediate-level-apple-ii-handbook.pdf
*
OURCH EQU $057B ;80-COL HORIZ CURSOR POSITION
OURCV EQU $05FB ;VERTICAL CURSOR POSITION
* ZERO-PAGE ADDRESSES
*
ZP.A1L .EQ $3C ;MONITOR GENERAL PURPOSE
ZP.A1H .EQ $3D ;MONITOR GENERAL PURPOSE
*
* PRODOS COMMAND CODES
*
OPENCMD .EQ $C8
READCMD .EQ $CA
CLOSCMD .EQ $CC
*
* CONSTANTS
*
EOFERR .EQ $4C ;ERROR CODE FOR END-OF-FILE
PTR .EQ $06 ;ONLY FREE 0-PAGE LOCATION
MAXERCDE .EQ $5A ;LARGEST ERROR CODE
CR .EQ $0D ;ASCII CARRIAGE RETURN
CR.HIBIT .EQ $8D ;CARRIAGE RET WITH HIGH BIT SET
BUFSIZE .EQ $00FF
SCR.HGHT .EQ 24 ;SCREEN HEIGHT
*
* DEBUGGING
TRACE EQU 0
********************************
* *
* PUSH Y ONTO THE STACK *
* DESTROYS A *
* *
********************************
PUSHY .MA
TYA
PHA
.EM
********************************
* *
* POP Y FROM THE STACK *
* DESTROYS A *
* *
********************************
POPY .MA
PLA
TAY
.EM
********************************
* *
* COPY IN BUF TO STRING *
* *
* X CONTAINS LENGTH OF "IN" *
* ]1 IS DEST STRING (LEN BYT) *
* A IS DESTROYED *
* *
********************************
CPIN .MA
PUSHY ;SAVE Y
STX ]1 ;COPY LENGTH TO FIRST BYTE OF ]1
LDY #0 ;INIT Y TO ZERO
:1 CPY ]1 ;COMPARE Y WITH LENGTH BYTE
BEQ :2 ;DONE IF LENGTH IS REACHED
LDA IN,Y ;LOAD IN[Y] INTO ACCUMULATOR
CMP #CR ;COMPARE WITH CARRIAGE RETURN
BEQ :2 ;STOP AT CARRIAGE RETURN
INY ;DEST STR IS 1 AHEAD OF IN BUF
STA ]1,Y ;COPY CHAR TO DEST STR ]1
JMP :1 ;LOOP TO NEXT CHAR
:2 POPY ;RESTORE Y
.EM
********************************
* *
* WRITES A LENGTH PREFIXED *
* STRING TO THE SCREEN *
* A IS DESTROYED *
* *
********************************
PUTS .MA
PUSHY
LDY #0 ;INIT LOOP INDEX
:1 CPY ]1 ;HAS STR LENGTH BEEN REACHED
BEQ :2 ;IF SO THEN FINISH
INY ;MOVE TO INDEX OF NEXT CHAR
LDA ]1,Y ;GET THE CHAR TO BE WRITTEN
JSR COUT ;WRITE THE CHARACTER
JMP :1 ;LOOP
:2 POPY
.EM
********************************
* *
* SET TO #1 (IMMEDIATE 1) *
* ]1 DESTINATION *
* A IS DESTROYED *
* *
********************************
SET1 .MA
LDA #1
STA ]1
.EM
SET0 .MA
LDA #0
STA ]1
.EM
SET23 .MA
LDA #23
STA ]1
.EM
********************************
* *
* MAIN PROGRAM *
* *
********************************
MAIN CLD ;CLEAR DECIMAL FLG, AVOID CRASH
>SET0 USRQUIT ;INITIALIZE TO "NO"
*
* GET FILE NAME
*
PUTS INFOLINE
JSR CROUT
:ASKFILE PUTS PROMPT
JSR GETLN1 ;LENGTH IN X, CR AT END
CPX #0 ;IS THE LENGTH ZERO?
BNE :CONT0 ;USER JUST PRESSED RETURN
JMP :END
:CONT0 CPX #1
BNE :CONT1
LDA #"?"
CMP IN
BNE :CONT1
JSR HELPINFO
JMP :ASKFILE
:CONT1 CPIN FILENAME ;COPY "IN" BUF TO FILENAME
DO TRACE
JSR PRSTRBYTES
JSR GETLN
FIN
*
* GET FILE I/O BUFFER FOR OPEN CALL
*
LDA #4 ;FOUR 256 BYTE PAGES = 1KB
JSR GETBUFR ;GET BUF FROM BASIC.SYSTEM
BCC :CONT2 ;CARRY CLEAR MEANS NO ERROR
JSR OBUFERR
JMP :END
:CONT2 STA OBUFADDR+1 ;GETBUFR RETURNS HIBYTE IN A
LDA #0 ;PREPARE
STA OBUFADDR ;LOBYTE IS 0 B/C ADDR OF PAGE
*
* OPEN FILE
*
JSR PRODOS_MLI
DB OPENCMD
DA OPENPRMS
BEQ :CONT3
JSR OPENERR
JSR FREEBUFR ;CLEAN UP BEFORE TRY AGAIN
JMP :ASKFILE
*
* COPY FILE NUMBER FROM OPEN PARAMETERS TO READ AND CLOSE
*
:CONT3 LDA OPENFNUM
STA READFNUM
STA CLOSFNUM
*
* GET BUFFER FOR READ OPERATION FROM BASIC.SYSTEM
*
LDA #1 ;ONE 256 BYTE BUFFER
JSR GETBUFR ;CALL BASIC.SYSTEM SUB
BCC :CONT4
JSR RBUFERR ;CARRY SET MEANS ERROR
JMP :CLOSFILE
:CONT4 STA RBADDR+1 ;STORE HI-BYTE
STA ZP_A1H ;FOR 0-PAGE INDIRECTION
LDA #0 ;0 FOR LO-BYTE
STA RBADDR ;STORE IT
STA ZP.A1L ;AGAIN, FOR 0-PAGE INDIRECTION
*
* PRINT THE FILE
*
JSR VIEWFILE
*
* CLEANUP
*
JSR FREEBUFR ;FREE READ BUFFER
*
* Close file
*
:CLOSFILE JSR PRODOS_MLI ;CLOSE THE FILE
DB CLOSCMD
DA CLOSPRMS
BEQ :FREEOBUF
JSR CLOSERR
:FREEOBUF JSR FREEBUFR ;FREE OPEN I/O BUFFER
:END NOP
RTS
********************************
* *
* END OF MAIN - PROGRAM EXIT *
* *
********************************
********************************
* *
* PROGRAM INFO AND HELP *
* *
********************************
HELPINFO JSR CROUT
PUTS INFO0
JSR CROUT
PUTS INFO1
JSR CROUT
PUTS INFO2
JSR CROUT
PUTS INFO3
JSR CROUT
PUTS INFO4
JSR CROUT
JSR CROUT
RTS
********************************
* *
* HANDLE ERROR WHEN OPENING *
* FILE *
* *
********************************
OPENERR STA ERRCODE
PUTS OERRMSG
PUTS FILENAME
LDA #":"
JSR COUT
LDA ERRCODE
JSR ERRPROC
RTS
********************************
* *
* HANDLE ERROR WHEN CLOSING *
* FILE *
* *
********************************
CLOSERR STA ERRCODE
PUTS CERRMSG
PUTS FILENAME
LDA #"'"
JSR COUT
LDA #":"
JSR COUT
LDA ERRCODE
JSR ERRPROC
RTS
********************************
* *
* HANDLE ERROR WHEN REQUESTING *
* READ BUFFER *
* *
********************************
RBUFERR STA ERRCODE
PUTS RBERRMSG
LDA #":"
JSR COUT
LDA ERRCODE
JSR ERRPROC
RTS
********************************
* *
* HANDLE ERROR WHEN REQUESTING *
* READ BUFFER *
* *
********************************
OBUFERR STA ERRCODE
PUTS OBERRMSG
LDA #":"
JSR COUT
LDA ERRCODE
JSR ERRPROC
RTS
********************************
* *
* PRINT "IN" BUFFER *
* *
********************************
PRINT_IN
PUSHY
LDA #"X"
JSR COUT
LDA #"="
JSR COUT
TXA
JSR PRBYTE
JSR CROUT
LDY #0
:LOOP CPY #255
BEQ :ENDLOOP
LDA IN,Y
JSR PRBYTE
LDA #" "
JSR COUT
INY
JMP :LOOP
:ENDLOOP JSR CROUT
POPY
RTS
********************************
* *
* PRINT STRING BYTES *
* *
********************************
PRSTRBYTES
PUSHY
LDY #0
:LOOP CPY #255
BEQ :ENDLOOP
LDA FILENAME,Y
JSR PRBYTE
LDA #" "
JSR COUT
INY
JMP :LOOP
:ENDLOOP JSR CROUT
POPY
RTS
********************************
* *
* VIEW FILE SUB *
* *
********************************
VIEWFILE
DO TRACE
>PUTS ENVIEW
FIN
SET1 LINENUM ;INIT LINE NUMBER
:LOOP JSR PRODOS_MLI ;CALL PRODOS TO READ FILE
DB READCMD ;SPECIFY PRODOS READ COMMAND
DA READPRMS ;READ PARAMETERS
BNE :READERR
JSR WRITEBUF ;WRITE TO SCREEN WHAT WAS READ
LDA #1 ;PREPARE FOR NEXT OP
CMP USRQUIT ;IF USER WANTS TO QUIT, THEN
BEQ :ENDLOOP ;EXIT THE LOOP
JMP :LOOP ;ELSE, GET THE NEXT BUFFER
:READERR JSR ERRPROC
:ENDLOOP NOP
RTS
********************************
* *
* WRITE BUFFER TO SCREEN *
* *
********************************
WRITEBUF
>PUSHY
LDY #0 ;INIT CHAR COUNTER VARIABLE
.1 CPY READCNT ;COMPARE TO MAX CHARS
BEQ .3
LDA (ZP.A1L),Y ;GET CHAR FROM BUFFER
ORA #%10000000 ;TURN ON HIGH BIT FOR PRINTING
JSR COUT ;COUT PRESERVES ACCUM
*
* CHECK END OF LINE
*
CMP #CR.HIBIT ;COMPARE TO CARRIAGE RETURN
BNE .2 ;IF NOT END OF LINE, NEXT CHAR
INC LINENUM ;NEXT LINE HAS BEEN REACHED
*
* CHECK AT END OF PAGE
*
LDA LINENUM
CMP #SCR.HGHT ;AT BOTTOM OF SCREEN?
BNE .2 ;NO? THEN NEXT CHAR
JSR STATBAR ;YES? THEN SHOW THE STATUS BAR
LDA #1 ;SETUP FOR NEXT LINE
CMP USRQUIT ;DID USER ASK TO QUIT
BEQ .3 ;YES? THEN END SUB
.2 INY ;STATBAR HAS ADJUSTED LINENUM
JMP .1
.3 >POPY
DO TRACE
PUTS EXWRITEBUF
FIN
RTS
********************************
* *
* PRINT ASCII IN HEX *
* *
********************************
PRASCII PHA
LDA #"["
JSR COUT
PLA
JSR PRBYTE
LDA #"]"
JSR COUT
LDA #" "
JSR COUT
RTS
********************************
* *
* DO THE STATUS BAR *
* *
********************************
STATBAR
DO TRACE
>PUTS ENSTATB
FIN
>PUSHY
>PUTS BAR
.1 JSR RDKEY ;GET A KEY FROM THE USER
CMP #" " ;CHECK IF SPACE ENTERED
BNE .2 ;IF NOT FORWARD TO NEXT CHECK
>SET1 LINENUM ;ADVANCE ONE PAGE, STORE 1
JMP .4 ;PROCESSED SPACE SO DONE
.2 CMP #CR.HIBIT ;CHECK FOR CARRIAGE RETURN
BNE .3
>SET23 LINENUM
JMP .4
.3 CMP #"Q" ;USER WANTS TO QUIT
BNE .1 ;NO RECOGNIZED INPUT
>SET1 USRQUIT
.4 JSR ERASEBAR
>POPY
DO TRACE
>PUTS EXSTATB
FIN
RTS
********************************
* *
* ERASE STATUS BAR *
* *
********************************
ERASEBAR
DO TRACE
>PUTS ENERASEB
FIN
>PUSHY
>SET0 OURCH ;RESET CURSOR TO BEG OF LINE
LDY #0 ;INIT COUNTER FOR SPACES
.1 CPY BAR ;FIRST BYTE IS LENGTH
BEQ .2 ;IF Y=LEN THEN DONE
LDA #" " ;LOAD SPACE
JSR COUT ;WRITE TO SCREEN
INY ;MAKE PROGRESS
JMP .1 ;LOOP TO NEXT CHAR
.2 >SET0 OURCH ;RESET CURSON TO BEG OF LINE
POPY
DO TRACE
>PUTS EXERASEB
FIN
RTS
********************************
* *
* ERROR HANDLER *
* INPUT PARAM: A HOLDS ERRCODE *
* *
********************************
ERRPROC
STA ERRCODE
CMP #0
BNE :EEOF
JMP :END
:EEOF CMP #EOFERR
BNE :E01
JMP :END
:E01 CMP #1
BNE :E04
PUTS E01MSG
JMP :END
:E04 CMP #4
BNE :E25
PUTS E04MSG
JMP :END
:E25 CMP #$25
BNE :E27
PUTS E25MSG
JMP :END
:E27 CMP #$27
BNE :E28
PUTS E27MSG
JMP :END
:E28 CMP #$28
BNE :E2B
PUTS E28MSG
JMP :END
:E2B CMP #$2B
BNE :E2E
PUTS E2BMSG
JMP :END
:E2E CMP #$2E
BNE :E40
PUTS E2EMSG
JMP :END
:E40 CMP #$40
BNE :E42
PUTS E40MSG
JMP :END
:E42 CMP #$42
BNE :E43
PUTS E42MSG
JMP :END
:E43 CMP #$43
BNE :E44
PUTS E43MSG
JMP :END
:E44 CMP #$44
BNE :E45
PUTS E44MSG
JMP :END
:E45 CMP #$45
BNE :E46
PUTS E45MSG
JMP :END
:E46 CMP #$46
BNE :E47
PUTS E46MSG
JMP :END
:E47 CMP #$47
BNE :E48
PUTS E47MSG
JMP :END
:E48 CMP #$48
BNE :E49
PUTS E48MSG
JMP :END
:E49 CMP #$49
BNE :E4A
PUTS E49MSG
JMP :END
:E4A CMP #$4A
BNE :E4B
PUTS E4AMSG
JMP :END
:E4B CMP #$4B
BNE :E4C
PUTS E4BMSG
JMP :END
:E4C CMP #$4C
BNE :E4D
PUTS E4CMSG
JMP :END
:E4D CMP #$4D
BNE :E4E
PUTS E4DMSG
JMP :END
:E4E CMP #$4E
BNE :E50
PUTS E4EMSG
JMP :END
:E50 CMP #$50
BNE :E51
PUTS E50MSG
JMP :END
:E51 CMP #$51
BNE :E52
PUTS E51MSG
JMP :END
:E52 CMP #$52
BNE :E53
PUTS E52MSG
JMP :END
:E53 CMP #$53
BNE :E55
PUTS E53MSG
JMP :END
:E55 CMP #$55
BNE :E56
PUTS E55MSG
JMP :END
:E56 CMP #$56
BNE :E57
PUTS E56MSG
JMP :END
:E57 CMP #$57
BNE :E5A
PUTS E57MSG
JMP :END
:E5A CMP #$5A
BNE :E_UNK
PUTS E5AMSG
JMP :END
:E_UNK PUTS E_UNK_MSG
LDA #":"
JSR COUT
LDA ERRCODE
JSR PRBYTE
:END JSR CROUT
RTS
********************************
* *
* DATA DIVISION HAHA *
* *
********************************
INFOLINE STR "ENTER [?] FOR PROGRAM INFO AND HELP"
INFO0 STR "MORE - PAGES THROUGH TEXT FILE"
INFO1 STR "COPYRIGHT (C) 2024 BILL CHATFIELD"
INFO2 STR "DISTRIBUTED UNDER THE GPL VERSION 3"
INFO3 STR "https://github.com/gungwald/prodos-more"
INFO4 STR "PRESS RETURN TO QUIT"
PROMPT STR "FILE:"
ERRTXT STR "ERROR:"
FILENAME DS $FF
ERRCODE DS 1
LINENUM DS 1
BAR STR '[RET] LINE [SPC] PAGE [Q]UIT'
USRQUIT DS 1
BUFCHAR DS 1
USRCHAR DS 1
OERRMSG STR "CANNOT OPEN "
CERRMSG STR "CANNOT CLOSE "
RBERRMSG STR "CANNOT CREATE READ BUFFER"
OBERRMSG STR "CANNOT CREATE FILE BUFFER"
E00MSG STR "NO ERROR"
E01MSG STR "BAD SYSTEM CALL NUMBER"
E04MSG STR "BAD SYSTEM CALL PARAMETER COUNT"
E25MSG STR "INTERRUPT TABLE FULL"
E27MSG STR "I/O ERROR"
E28MSG STR "NO DEVICE CONNECTED"
E2BMSG STR "DISK WRITE PROTECTED"
E2EMSG STR "DISK SWITCHED"
E40MSG STR "INVALID PATHNAME"
E42MSG STR "MAXIMUM NUMBER OF FILES OPEN"
E43MSG STR "INVALID REFERENCE NUMBER"
E44MSG STR "DIRECTORY NOT FOUND"
E45MSG STR "VOLUME NOT FOUND"
E46MSG STR "FILE NOT FOUND"
E47MSG STR "DUPLICATE FILENAME"
E48MSG STR "VOLUME FULL"
E49MSG STR "VOLUME DIRECTORY FULL"
E4AMSG STR "INCOMPATIBLE FILE FORMAT OR PRODOS DIRECTORY"
E4BMSG STR "UNSUPPORTED STORAGE TYPE"
E4CMSG STR "END OF FILE ENCOUNTERED"
E4DMSG STR "POSITION OUT OF RANGE"
E4EMSG STR "FILE ACCESS ERROR OR FILE LOCKED"
E50MSG STR "FILE IS OPEN"
E51MSG STR "DIRECTORY STRUCTURE DAMAGED"
E52MSG STR "NOT A PRODOS VOLUME"
E53MSG STR "INVALID SYSTEM CALL PARAMETER"
E55MSG STR "VOLUME CONTROL BLOCK TABLE FULL"
E56MSG STR "BAD BUFFER ADDRESS"
E57MSG STR "DUPLICATE VOLUME"
E5AMSG STR "FILE STRUCTURE DAMAGED"
E_UNK_MSG STR "UNKNOWN ERROR CODE"
ENVIEW STR 'ENTERING VIEWFILE'
EXVIEW STR 'EXITING VIEWFILE'
EXWRITEBUF STR 'EXITING WRITEBUF'
ENSTATB STR 'ENTERING STATUSBAR'
EXSTATB STR 'EXITING STATUSBAR'
ENERASEB STR 'ENTERING ERASEBAR'
EXERASEB STR 'EXITING ERASEBAR'
*
* OPEN PARAMETERS
*
OPENPRMS .DA #3
.DA FILENAME
OBUFADDR .BS 2
OPENFNUM .BS 1
*
* READ PARAMETERS
*
READPRMS .DA #4
READFNUM .BS 1
RBADDR .BS 2
REQCNT .DA BUFSIZE
READCNT .BS 2
*
* CLOSE PARAMETERS
*
CLOSPRMS .DA #1
CLOSFNUM .BS 1
*
* BUFFERS
*
* CONSUME ALL BYTES UP TO THE NEXT PAGE BOUNDRY
*FILLER DS \,$00
* MUST START ON PAGE BOUNDRY
*OPENBUF DS 1024
*READBUF DS BUFSIZE

195
test.txt Normal file
View File

@ -0,0 +1,195 @@
MORE(1) User Commands MORE(1)
NAME
more - display the contents of a file in a terminal
SYNOPSIS
more [options] file ...
DESCRIPTION
more is a filter for paging through text one screenful at a time. This
version is especially primitive. Users should realize that less(1)
provides more(1) emulation plus extensive enhancements.
OPTIONS
Options are also taken from the environment variable MORE (make sure to
precede them with a dash (-)) but command-line options will override
those.
-d, --silent
Prompt with "[Press space to continue, 'q' to quit.]", and display
"[Press 'h' for instructions.]" instead of ringing the bell when an
illegal key is pressed.
-l, --logical
Do not pause after any line containing a ^L (form feed).
-e, --exit-on-eof
Exit on End-Of-File, enabled by default if POSIXLY_CORRECT
environment variable is not set or if not executed on terminal.
-f, --no-pause
Count logical lines, rather than screen lines (i.e., long lines are
not folded).
-p, --print-over
Do not scroll. Instead, clear the whole screen and then display the
text. Notice that this option is switched on automatically if the
executable is named page.
-c, --clean-print
Do not scroll. Instead, paint each screen from the top, clearing
the remainder of each line as it is displayed.
-s, --squeeze
Squeeze multiple blank lines into one.
-u, --plain
Suppress underlining. This option is silently ignored as backwards
compatibility.
-n, --lines number
Specify the number of lines per screenful. The number argument is a
positive decimal integer. The --lines option shall override any
values obtained from any other source, such as number of lines
reported by terminal.
-number
A numeric option means the same as --lines option argument.
+number
Start displaying each file at line number.
+/string
The string to be searched in each file before starting to display
it.
-h, --help
Display help text and exit.
-V, --version
Print version and exit.
COMMANDS
Interactive commands for more are based on vi(1). Some commands may be
preceded by a decimal number, called k in the descriptions below. In
the following descriptions, ^X means control-X.
h or ?
Help; display a summary of these commands. If you forget all other
commands, remember this one.
SPACE
Display next k lines of text. Defaults to current screen size.
z
Display next k lines of text. Defaults to current screen size.
Argument becomes new default.
RETURN
Display next k lines of text. Defaults to 1. Argument becomes new
default.
d or ^D
Scroll k lines. Default is current scroll size, initially 11.
Argument becomes new default.
q or Q or INTERRUPT
Exit.
s
Skip forward k lines of text. Defaults to 1.
f
Skip forward k screenfuls of text. Defaults to 1.
b or ^B
Skip backwards k screenfuls of text. Defaults to 1. Only works with
files, not pipes.
'
Go to the place where the last search started.
=
Display current line number.
/pattern
Search for kth occurrence of regular expression. Defaults to 1.
n
Search for kth occurrence of last regular expression. Defaults to
1.
!command or :!command
Execute command in a subshell.
v
Start up an editor at current line. The editor is taken from the
environment variable VISUAL if defined, or EDITOR if VISUAL is not
defined, or defaults to vi(1) if neither VISUAL nor EDITOR is
defined.
^L
Redraw screen.
:n
Go to kth next file. Defaults to 1.
:p
Go to kth previous file. Defaults to 1.
:f
Display current file name and line number.
.
Repeat previous command.
ENVIRONMENT
The more command respects the following environment variables, if they
exist:
MORE
This variable may be set with favored options to more.
SHELL
Current shell in use (normally set by the shell at login time).
TERM
The terminal type used by more to get the terminal characteristics
necessary to manipulate the screen.
VISUAL
The editor the user prefers. Invoked when command key v is pressed.
EDITOR
The editor of choice when VISUAL is not specified.
POSIXLY_CORRECT
Disable exit-on-eof (see option -e for more details).
HISTORY
The more command appeared in 3.0BSD. This man page documents more
version 5.19 (Berkeley 6/29/88), which is currently in use in the Linux
community. Documentation was produced using several other versions of
the man page, and extensive inspection of the source code.
AUTHORS
Eric Shienbrood, UC Berkeley.
Modified by Geoff Peck, UCB to add underlining, single spacing.
Modified by John Foderaro, UCB to add -c and MORE environment variable.
SEE ALSO
less(1), vi(1)
REPORTING BUGS
For bug reports, use the issue tracker at
https://github.com/util-linux/util-linux/issues.
AVAILABILITY
The more command is part of the util-linux package which can be
downloaded from Linux Kernel Archive
<https://www.kernel.org/pub/linux/utils/util-linux/>.
util-linux 2.39.3 2023-11-21 MORE(1)