diff --git a/more.bas b/more.bas new file mode 100644 index 0000000..59c55d8 --- /dev/null +++ b/more.bas @@ -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 + diff --git a/more.c b/more.c deleted file mode 100644 index 35682ab..0000000 --- a/more.c +++ /dev/null @@ -1,425 +0,0 @@ -******************************** -* * -* 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 - -: diff --git a/more.s b/more.s index 8b10af3..35682ab 100644 --- a/more.s +++ b/more.s @@ -1,402 +1,425 @@ +******************************** +* * +* 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" * -* more - Text viewer +* GET FILE NAME * - -* 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 #= 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 + 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 * -* ERROR CODE TO MESSAGE TRANSLATION TABLE +* OPEN FILE * -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 + JSR MLI + DB OPENCMD + DA OPENPRMS + BNE :ERRFWDR * -* Consume all bytes up to next page boundary +* COPY FILE NUMBER FROM OPEN PARAMETERS TO READ AND CLOSE * -filler ds \,$00 + LDA OPENFNUM + STA READFNUM + STA CLOSFNUM * -* Must start on page boundary +* PRINT THE FILE * -openIoBuf ds 1024 -readIoBuf ds BUF_SIZ + 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 + +: