prodos-more/more.c

426 lines
12 KiB
C

********************************
* *
* MORE - UN*X MORE COMMAND *
* ASSEMBLES WITH MERLIN *
* BILL CHATFIELD *
* *
********************************
DSK MORE ;WRITE ASSEMBLED FILE TO DISK
TYP $06 ;$FF=SYSTEM, $06=BINARY
ORG $2000 ;ASSEMBLE START ADDRESS
* SYSTEM VARIABLES
IN EQU $200 ;256-CHAR INPUT BUF
* SUBROUTINES IN MONITOR ROM: $F800 - $FFFF
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
* PRODOS ENTRY POINT
MLI EQU $BF00
* MEMORY LOCATIONS
OURCH EQU $057B ;80-COL HORIZ CURSOR POSITION
OURCV EQU $05FB ;VERTICAL CURSOR POSITION
* PRODOS COMMAND CODES
OPENCMD EQU $C8
READCMD EQU $CA
CLOSCMD EQU $CC
* CONSTANTS
EOFERR EQU $4C ;ERROR CODE FOR END-OF-FILE
PTR EQU $06 ;ONLY FREE 0-PAGE LOCATION
MAXERCDE EQU $5A ;LARGEST ERROR CODE
CR EQU $0D ;ASCII CARRIAGE RETURN
CR_HIBIT EQU $8D ;CARRIAGE RET WITH HIGH BIT SET
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 ;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
<<<
********************************
* *
* MAIN PROGRAM *
* *
********************************
MAIN CLD ;CLEAR DECIMAL FLG, AVOID CRASH
SET0 USRQUIT ;INITIALIZE TO "NO"
*
* GET FILE NAME
*
PUTS PROMPT
JSR GETLN1 ;LENGTH IN X, CR AT END
CPX #0 ;IS THE LENGTH ZERO?
BEQ :END ;USER JUST PRESSED RETURN
CPIN FILENAME ;COPY "IN" BUF TO FILENAME
*
* OPEN FILE
*
JSR MLI
DB OPENCMD
DA OPENPRMS
BNE :ERRFWDR
*
* COPY FILE NUMBER FROM OPEN PARAMETERS TO READ AND CLOSE
*
LDA OPENFNUM
STA READFNUM
STA CLOSFNUM
*
* PRINT THE FILE
*
JSR VIEWFILE ;MUST CLOSE BEFORE ERR HANDLING
*
* CLOSE FILE
*
JSR MLI
DB CLOSCMD
DA CLOSPRMS
STA CLOSERR
*
* CHECK FOR ERRORS
*
LDA READERR ;RELOAD THE READ RESULT CODE
CMP EOFERR ;WAS IT AN EOF "ERROR"
BEQ :END ;EOF IS NOT REALLY AN ERROR
CMP #0
BNE :ERRFWDR
LDA CLOSERR
BNE :ERRFWDR
JMP :END
*
* FINISH
*
:ERRFWDR JSR ERRPROC
:END NOP
RTS
********************************
* *
* VIEW FILE SUB *
* *
********************************
VIEWFILE
DO TRACE
PUTS ENVIEW
FIN
SET1 LINENUM ;INIT LINE NUMBER
:LOOP JSR MLI ;CALL PRODOS TO READ FILE
DB READCMD ;SPECIFY PRODOS READ COMMAND
DA READPRMS ;READ PARAMETERS
STA READERR ;SAVE RESULT OF READ OPERATION
BNE :ENDLOOP ;IF ERROR THEN END SUB
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
:ENDLOOP NOP
RTS
********************************
* *
* WRITE BUFFER TO SCREEN *
* *
********************************
WRITEBUF
LDY #0 ;INIT CHAR COUNTER VARIABLE
:LOOP CPY READCNT ;COMPARE TO MAX CHARS
BEQ :ENDLOOP
LDA READBUF,Y ;GET CHAR FROM BUFFER
ORA #%10000000 ;TURN ON HIGH BIT FOR PRINTING
JSR COUT ;WRITE IT TO THE SCREEN
*
* CHECK END OF LINE
*
LDA READBUF,Y ;LOAD AGAIN, WITHOUT HIBIT
AND #%01111111 ;TURN OFF HIBIT, IF SET
CMP #CR ;COMPARE TO CR WITHOUT HIBIT
BNE :CONT ;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 :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
DO TRACE
PUTS EXVIEW
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
:LOOP JSR RDKEY ;GET A KEY FROM THE USER
CMP #" " ;CHECK IF SPACE ENTERED
BNE :CHKCR ;IF NOT FORWARD TO NEXT CHECK
SET1 LINENUM ;ADVANCE ONE PAGE, STORE 1
JMP :ENDLOOP ;PROCESSED SPACE SO DONE
:CHKCR CMP #CR_HIBIT ;CHECK FOR CARRIAGE RETURN
BNE :CHKQUIT
SET23 LINENUM
JMP :ENDLOOP
:CHKQUIT CMP #"Q" ;USER WANTS TO QUIT
BNE :LOOP ;NO RECOGNIZED INPUT
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 CURSON TO BEG OF LINE
POPY
DO TRACE
PUTS EXERASEB
FIN
RTS
********************************
* *
* ERROR HANDLER *
* *
********************************
ERRPROC STA ERRCODE
PUTS ERRTXT
JSR PRBYTE
JSR CROUT
RTS
********************************
* *
* DATA DIVISION HAHA *
* *
********************************
PROMPT STR "FILE:"
ERRTXT STR "ERROR:"
FILENAME DS $FF
HERE STR "HERE"
HERE2 STR "HERE2"
READRET STR "READRET="
SREADCNT STR "READCNT="
ERRCODE DS 1
READERR DS 1
CLOSERR DS 1
LINENUM DS 1
BAR STR '[RET] NEXT LINE [SPC] NEXT PAGE [Q]UIT'
USRQUIT DS 1
BUFCHAR DS 1
USRCHAR DS 1
I DS 1
ENVIEW STR 'ENTERING VIEWFILE'
EXVIEW STR 'EXITING VIEWFILE'
ENSTATB STR 'ENTERING STATUSBAR'
EXSTATB STR 'EXITING STATUSBAR'
ENERASEB STR 'ENTERING ERASEBAR'
EXERASEB STR 'EXITING ERASEBAR'
* OPEN PARAMETERS
OPENPRMS DB 3
DA FILENAME
DA OPENBUF
OPENFNUM DS 1
* READ PARAMETERS
READPRMS DB 4
READFNUM DS 1
DA READBUF
REQCNT DW BUFSIZE
READCNT DS 2
* CLOSE PARAMETERS
CLOSPRMS DB 1
CLOSFNUM DS 1
* REST GOES HERE
* BUFFERS
* CONSUME ALL BYTES UP TO THE NEXT PAGE BOUNDRY
FILLER DS \,$00
* MUST START ON PAGE BOUNDRY
OPENBUF DS 1024
READBUF DS BUFSIZE
: