******************************** * * * MORE - UN*X MORE COMMAND * * ASSEMBLES WITH S-C * * * ******************************** * DSK MORE ;WRITE ASSEMBLED FILE TO DISK * TYP $06 ;$FF=SYSTEM, $06=BINARY .OR $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 EQU $BF00 ;MACHINE LANG IFACE (MLI) * MEMORY LOCATIONS * OURCH .EQ $057B ;80-COL HORIZ CURSOR POSITION OURCV .EQ $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 .EQ 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 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 * * GET FILE I/O BUFFER FOR OPEN CALL * LDA #4 ;FOUR 256 BYTE PAGES = 1KB JSR GETBUFR ;GET BUF FROM BASIC.SYSTEM BCS :OBUFERR ;CARRY CLEAR MEANS NO ERROR STA OBUFADDR+1 ;GETBUFR RETURNS HIBYTE IN A LDA #0 ;PREPARE STA OBUFADDR ;LOBYTE IS 0 B/C ADDR OF PAGE :OPENFILE JSR PRODOS DB OPENCMD DA OPENPRMS BEQ :OPEN_OK JSR ERRPROC JMP :FREEOBUF * * COPY FILE NUMBER FROM OPEN PARAMETERS TO READ AND CLOSE * :OPEN_OK 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 :RBUF_OK ;CARRY CLR MEANS NO ERROR JSR ERRPROC JMP :CLOSFILE :RBUF_OK STA RBADDR+1 ;STORE HI-BYTE LDA #0 ;0 FOR LO-BYTE STA RBADDR ;STORE IT STA ZP.A1L ;AGAIN, FOR 0-PAGE INDIRECTION * * PRINT THE FILE * JSR VIEWFILE * * CLEANUP * :FREERBUF JSR FREEBUFR ;FREE READ BUFFER :CLOSFILE JSR PRODOS ;CLOSE THE FILE DB CLOSCMD DA CLOSPRMS BCC FREEOBUF :OPENERR JSR ERRPROC :FREEOBUF JSR FREEBUFR ;FREE OPEN I/O BUFFER JMP :END :OBUFERR JSR ERRPROC :END NOP RTS ******************************** * * * VIEW FILE SUB * * * ******************************** VIEWFILE DO TRACE >PUTS ENVIEW FIN SET1 LINENUM ;INIT LINE NUMBER :LOOP JSR PRODOS ;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 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 .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: ERRCODE * * * ******************************** ERRPROC LDA ERRCODE CMP #0 BEQ :NOERR CMP #EOFERR BEQ :NOERR PUTS ERRTXT LDA ERRCODE JSR PRBYTE JSR CROUT :NOERR NOP RTS ******************************** * * * DATA DIVISION HAHA * * * ******************************** PROMPT .DA #5 ;LENGTH BYTE .AS "FILE:" ERRTXT .DA #6 ;LENGTH BYTE .AS "ERROR:" BAR .DA #42 .AS '[RET] NEXT LINE / [SPC] NEXT PAGE / [Q]UIT' FILENAME .BS $FF ERRCODE .BS 1 READERR .BS 1 CLOSERR .BS 1 LINENUM .BS 1 USRQUIT .BS 1 BUFCHAR .BS 1 USRCHAR .BS 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 .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 :