*================================= * WRITE COMMAND HANDLER. *================================= CMDWRITE JSR COMRDWR ;CALL COMMON READ/WRITE ROUTINE. ;FIND NAMED BUF, ELSE A FREE BUF. ;OPEN FILE IF NOT ALREADY OPEN. ;POS'N FILE PTR IF R- OR B-PARMS ;WERE ISSUED. LDA #5 ;SET CONDITION 5. STA OPUTCOND JMP FINSHCMD ;XIT WITH CONDITION 5 SET SO THAT ;THE NEXT TIME A PRINT STATEMENT ;IS ENCOUNTERED, EXECUTION WILL ;FLOW VIA COUT & THE DOS HKS TO ;SEND CHARS TO THE NAMED FILE. *================================= * READ COMMAND HANDLER. *================================= CMDREAD JSR COMRDWR ;CALL COMMON READ/WRITE ROUTINE. ;FIND NAMED BUF, ELSE FIND A FREE ;BUFFER. OPEN FILE IF NOT ALREADY ;OPEN. POS'N FILE PTR IF R- OR ;B-PARMS WERE ISSUED WITH CMD. LDA #1 ;SET CONDNFLG TO SIGNAL READING. STA CONDNFLG JMP FINSHCMD ;XIT WITH OPUTCOND=0 & CONDNFLG=1 ;EXECUTION EVENTUALLY FLOWS BACK ;INTO APPLESOFT. WHEN APPLESOFT ;PICKS UP A SUBSEQUENT "INPUT" OR ;"GET" STATEMENT, IT PRINTS A ;PROMPT. DOS INTERCEPTS OUTPUT ;VIA OPUTINCP ($9EBD). WHEN THE ;SETTING OF CONDNFLG IS DETECTED, ;THE MACHINE IS DIRECTED TO TAKE ;DATA FROM THE DISK. *================================= * CODE COMMON TO READ/WRITE. *================================= COMRDWR JSR GETBUFF ;LOCATE A DOS BUF WITH SAME NAME, ;ELSE LOCATE A FREE BUF. BCC BUFS4RW ;BRNCH IF MATCHING BUF WAS FOUND. JSR CMDOPEN ;FILE NOT ALREADY OPN, SO OPEN IT JMP CKRBOPTN ;GO CHK IF R- & B-PARMS ISSUED. BUFS4RW JSR BUFS2PRM ;COPY ADDRS OF THE VARIOUS DOS ;BUFFERS TO THE FM PARAMETER LIST * CHK IF R- OR B-PARAMETERS * WERE ISSUED WITH COMMAND. CKRBOPTN LDA CUMLOPTN ;CHK IF R- OR B-PARMS ISSUED. AND #%00000110 ;(R=$04, B=$02.) BEQ RDWRRTN ;NO - SKIP POS'NING OF FILE PTR. * COPY B- & R-PARMS FROM OPTION * PARSED TABLE TO FM PARM LIST. LDX #3 CPYBPARM LDA RECPRSD,X ;GET VALUE OF PARAMETER. STA RECNMBFM,X ;STORE IT IN PARM LIST. DEX ;4 BYTES TO COPY (3 TO 0). BPL CPYBPARM * CALL THE FILEMANAGER * WITH THE POSITION OPCODE. BK2APND LDA #$0A ;OPCODE FOR POSITION. STA OPCODEFM ;PUT IT IN THE FM PARAMETER LIST. JSR FMDRIVER ;CALL FM 2 DO THE POS'N FUNCTION. RDWRRTN RTS *================================= * INIT COMMAND HANDLER. *================================= CMDINIT LDA #%01000000 ;CHK TO SEE IF V(OLUME) OPTION AND CUMLOPTN ;WAS ISSUED WITH INIT COMMAND. BEQ VOL254 ;NO V-PARM ISSUED, SO USE A DFLT ;VOLUME VALUE OF 254. LDA VOLPRSD ;A VOL VAL WAS ISSUED, SO USE IT BNE OTHRVOL ;(BUT ONLY IF IT IS NOT ZERO). VOL254 LDA #254 ;USE VOL 254 AS DEFAULT VALUE. STA VOLPRSD OTHRVOL LDA ADOSTART+1 ;HI BYTE OF DOS LOAD ADDR FROM ;DOS'S MAIN VARIABLE TABLE. STA SUBCODFM LDA #11 ;OPCODE FOR INIT COMMAND. JSR HNDLCMD1 ;CALL FM COMMAND HANDLER TO DO ;THE INIT COMMAND. JMP CMDSAVE ;GO SAVE THE "HELLO" FILE & THEN ;EXIT TO THE CALLER OF THE INIT ;CMD. (NORMALLY RTNS TO AFTRCMD ;($A17D) LOCATED IN THE COMMAND ;PARSING & PROCESSING ROUTINES.) *================================= * CATALOG COMMAND HANDLER. *================================= CMDCATLG LDA #6 ;CATALOG OPCODE. JSR HNDLCMD1 ;CALL CMD HANDLER TO DO CATALOG. LDA VOLFM ;GET VOLUME # FROM FM PARM LIST STA VOLPRSD ;& PUT IT IN THE PARSED TABLE. RTS ;EXIT TO CALLER OF CATALOG CMD. ;(OFTEN RETURNS 2 AFTRCMD ($A17D) ;LOCATED IN THE CMD PARSING AND ;PROCESSING ROUTINES.) *================================= * FP COMMAND HANDLER. *================================= CMDFP LDA #$4C ;(A) = OPCODE FOR "JMP". JSR SETROM ;TEST 2 SEE IF LANGUAGE WANTED IS ;ON CARD OR MOTHERBOARD. BEQ TODOSCLD ;ROM VERSION OF FP WAS PRESENT ON ;EITHER CARD OR MOTHERBOARD SO GO ;DO A COLDSTART. * USING MACHINE WITH INTEGER IN ROM. * * ASSUME USING "SYSTEM MASTER" DISK * SO TRY TO RUN AN INTEGER PRGM * CALLED "APPLESOFT". WHEN RUN, THE * PRGM CALLED "APPLESOFT" LOADS A * RAM OR DISK-BASED VERSION OF FP * BASIC THAT IS CONTAINED IN A BINARY * FILE CALLED "FPBASIC". THIS LATTER * FILE IS ALSO HOUSED ON THE SYSTEM * MASTER DISK. LDA #0 ;SET ACTIVE BASIC FLAG TO DENOTE STA ACTBSFLG ;USING INTEGER. LDY #30 JSR BLNK1RST ;BLANK OUT THE PRIMARY FILE NAME ;BUFFER (30 BYTES LONG). * COPY THE NAME OF THE INTEGER FILE * CALLED "APPLESOFT" INTO THE PRIMARY * FILE NAME BUFFER. LDX #9 ;ONLY 9 CHARS IN NAME "APPLESOFT" CPYAPPLE LDA RUNTRUPT,X ;GET CHARS OF NAME. STA PRIMFNBF-1,X ;STORE THEM IN PRIMARY NAME BUF DEX ;REDUCE COUNTER. BNE CPYAPPLE ;MORE CHARS TO COPY. LDA #$C0 ;SET CONDNFLG TO DESIGNATE USING STA CONDNFLG ;RAM VERSION OF APPLESOFT. JMP CMDRUN ;GO RUN FILE CALLED "APPLESOFT" ;WHICH LOADS A RAM VERSION OF ;FP BASIC CONTAINED IN A BINARY ;FILE CALLED "FPBASIC". *================================= * INT COMMAND HANDLER. *================================= CMDINT LDA #$20 ;OPCODE FOR "JSR". JSR SETROM ;TEST TO SEE IF LANGUAGE WANTED ;IS ON CARD OR MOTHERBOARD. BEQ INTPRSNT ;INTEGER BASIC IS PRESENT (EITHER ;ON CARD OR MOTHERBOARD). * INTEGER BASIC NOT PRESENT * ON CARD OR MOTHERBOARD. NOLNGINT LDA #1 ;SET ERROR CODE FOR LANGUAGE-NOT- JMP ERRHNDLR ;AVAILABLE MSG & GO EXIT. * INTEGER BASIC PRESENT ON DEVICE. INTPRSNT LDA #0 ;CAUSE DESIRED BASIC IS PRESENT, STA RUNTRUPT ;ZERO OUT THE RUN INTERCEPT FLAG ;CAUSE WE WON'T BE LOADING A LANG TODOSCLD JMP DOSCOLD ;GO INTO THE COLDSTART ROUTINE. *================================= * SELECT DESIRED BASIC *================================= * TEST CARD OR MOTHERBOARD TO INSURE * THAT DEVICE CONTAINING THE ROM * VERSION WE WANT IS SELECTED. * BASICCLD ($E000) CONTAINS A "JMP" * OR "JSR" INSTRUCTION IF DEALING * WITH FP OR INTEGER ROM RESPECTIVELY. SETROM CMP BASICCLD ;TEST CARD OR MOTHERBOARD. ;(IE.CHK WHICHEVER DEVICE IS UP.) BEQ DVICERTN ;LANG WNTD ON PRESENT ROM DEVICE. * LANGUAGE WAS NOT ON DEVICE SELECTED * ABOVE, SO SPECIFICALLY TEST CARD * IN SLOT 0. (P.S. COULD CHANGE ADDRS * IF WANT CARD IN DIFFERENT SLOT.) STA $C080 ;READ ENABLE SLOT0. CMP BASICCLD ;CHECK IDENTIFYING BYTE. BEQ DVICERTN ;BRANCH IF ROM WANTED IS ON CARD. * ROM WANTED WAS NOT ON CARD. * WE MAY HAVE JUST TESTED CARD TWICE * SO NOW SPECIFICALLY TEST MOTHERBOARD. STA $C081 ;TEST MOTHERBOARD. CMP BASICCLD ;CHECK IDENTIFYING BYTE. DVICERTN RTS ;EXIT WITH THE SWITCHES POINTING ;AT THE LAST DEVICE TESTED.IF THE ;DESIRED LANGUAGE IS PRESENT, THE ;SWITCHES ARE LEFT WITH THE ;APPROPRIATE DEVICE SELECTED. *================================= * EXEC COMMAND HANDLER. *================================= CMDEXEC JSR CMDOPEN ;GO OPEN THE FILE TO BE EXECED. LDA CURFNADR ;GET ADDR OF CURRENT FILENAME BUF STA EXECBUFF ;& DESIGNATE AS EXEC'S NAME BUF. LDA CURFNADR+1 STA EXECBUFF+1 LDA PRIMFNBF ;SET EXEC FLAG TO A NON-ZERO VAL. STA EXECFLAG ;(USE 1RST CHAR OF FILE NAME.) BNE POSNCHKR ;ALWAYS - GO POS'N FILE PTR IF ;NECESSARY. ;NOTE: ACTUAL EXECING OF STATMNTS ;DOES NOT OCCUR UNTIL AFTER THE ;COMPUTER RETURNS TO BASIC'S ;RESTART ($D43C) ROUTINE. WHEN ;INPUT IS REQUESTED, EXECUTION ;FLOWS VIA DOS HKS INTO OPUTINCP ;($9EBD). HERE THE EXECFLAG IS ;TESTED & DISCOVERED TO BE SET. ;AS RESULT, THE READEXEC ($A682) ;ROUTINE IS USED 2 READ DATA FROM ;THE EXEC FILE. THE STATEMENTS ;ARE INTERPRETED AS IF THEY WERE ;ENCOUNTERED IN THE IMMED MODE. *================================= * POSITION COMMAND HANDLER *================================= CMDPOSN JSR GETBUFF ;LOCATE BUF WITH SAME NAME, ELSE ;LOCATE A FREE BUFFER. BCC BUFS4PSN ;ALREADY OPEN -SKIP NEXT INSTRUC. JSR CMDOPEN ;GO OPEN THE FILE. JMP POSNCHKR ;BYPASS NEXT INSTRUC, CAUSE JUST ;OPENED FILE & PARM LIST ALREADY ;CONTAINS ADRS OF DIF DOS BUFS. BUFS4PSN JSR BUFS2PRM ;GET ADR OF DOS BUFS FROM CHAIN ;BUF & PUT THEM IN FM PARM LIST. POSNCHKR LDA CUMLOPTN ;CHK TO SEE IF A NON-ZERO R-PARM AND #%00000100 ;WAS ISSUED WITH CMD. BEQ DONEPOSN ;R-PARM WAS ZERO, SO GO EXIT ;(IE. DON'T MOVE FILE POINTER). * A NON-ZERO R-PARM WAS ISSUED, SO GO MOVE * THE FILE POINTER FORWARD BY READING * ONE BYTE AT A TIME. WHEN A IS * ENCOUNTERED, REDUCE THE COUNT OF THE * RELATIVE FIELD POSITIONS LEFT TO MOVE. * WHEN THE COUNT EQUALS ZERO, WE ARE * DONE POSITIONING. CKPSNDUN LDA RECPRSD ;CHECK COUNT. BNE POSNMORE LDX RECPRSD+1 BEQ DONEPOSN ;R-PRM HAS BEEN COUNTED DWN TO 0, ;SO WE ARE DONE POSITIONING. DEC RECPRSD+1 ;REDUCE COUNT OF R-PARM (IE. # OF POSNMORE DEC RECPRSD ;FIELDS MOVED FORWARD) FOR NEXT ;TIME AROUND. PSNFIELD JSR RDTXTBYT ;GO READ A TEXT FILE BYTE. BEQ ENDATERR ;IF BYTE JUST READ = $00,THEN RAN ;OUT OF DATA. A ZERO BYTE CAN BE ;OBTAINED FROM AN INCOMPLETELY ;FILLED DATA SECTOR. OR, IF THE ;FILE ENDS ON A SECTOR BOUNDARY, ;A $00 CAN ALSO BE ACQUIRED FROM ;A ZEROED-OUT T/S LINK OR A ;ZEROED-OUT DATA PAIR (TRK/SEC ;VALUES) LISTED IN A T/S LIST. CMP #$8D ;WAS BYT A FIELD-DELIMITING ? BNE PSNFIELD ;NO -GO READ THE NEXT BYTE IN THE ;SAME FIELD. BEQ CKPSNDUN ;YES - GOT END-OF-FIELD MARKER SO ;BRANCH BACK TO REDUCE THE FIELD ;COUNT & SEE IF WE'RE DONE ;POSITIONING YET. DONEPOSN RTS ;EXIT - EITHER DONE POSITIONING, ;ELSE R-PARM WAS 0 TO START WITH ;& THERE4 NO POSITIONING NEEDED. ;EXIT 2 CALLER OF COMMAND. OFTEN ;RETURNS 2 AFTRCMD ($A17D) LOC'D ;IN THE CMD PARSING & PROCESSING ;ROUTINES. *================================= * WRITE-ONE-DATA-BYTE SUBROUTINE. *================================= WRITEXT JSR CKBSCRUN ;CHK IF BASIC IS RUNNING A PRGM. BCS CLOSZERO ;NOT RUNNING, SO GO CLOSE FILE, ;RESET TO CONDITION 0 & THEN DO A ;WARMSTART. (REMEMBER, WRITE CMD ;IS RESTRICTED TO DEFERRED MODE.) LDA ASAVED ;RETRIEVE BYTE TO WRITE. STA ONEIOBUF ;PUT IT IN FM PARM LIST. LDA #4 ;SET PARM LIST TO WRITE ONE BYTE. STA OPCODEFM LDA #1 STA SUBCODFM JMP FMDRIVER ;GO TO FM DRV TO WRITE DATA BYTE. *================================= * ROUTINE TO READ A DATA BYTE. *================================= READTEXT JSR CKBSCRUN ;CHK IF BASIC IS RUNNING A PRGM. BCS CLOSZERO ;BASIC NOT RUNNING SO GO CLOSE ;FILE, RESET 2 CONDITION 0 & DO A ;WARMSTART. (REMEMBER READ CMD ;IS RESTRICTED 2 DEFERRED MODE.) LDA #6 ;SET COND'N6 -IGNORE INPUT PROMPT SETCOND STA OPUTCOND JSR RDTXTBYT ;GO READ TEXT FILE DATA BYTE. BNE NOTEND ;IF BYTE READ <> 0, THEN HAVEN'T ;HIT END-OF-FILE MARKER YET. * RAN OUT OF DATA. PICKED UP A $00 BYTE * EITHER FROM PARTIALLY FULL DATA SECTOR, * A ZEROED-OUT T/S LINK OR A ZEROED-OUT * DATA PAIR (TRK/SEC VALUES LISTED IN A * T/S LIST). JSR CLOSEONE ;RAN OUT OF DATA SO CLOSE FILE. LDA #3 ;USING CONDITION 3? CMP OPUTCOND ;IE. HNDLING AN INPUT STATEMENT? BEQ DONEPOSN ;YES - JUST GO TO AN "RTS". ENDATERR LDA #5 ;NO - THERE4 GOT OUT-OF-DATA ERR. JMP ERRHNDLR ;GO HANDLE ERROR. NOTEND CMP #$E0 ;LOWERCASE? BCC SAVIT ;BRANCH IF UPPERCASE. AND #$7F ;CONVERT LOWER TO UPPER IN ORDER ;2 FOOL CAPTST ROUTINE ($FD7E) ;IN MONITOR ROM. SAVIT STA ASAVED ;SAVE CHAR READ. LDX XSAVED ;GET INDEX TO INPUT BUFFER. BEQ TOEXIT ;BRANCH IF 1RST CHAR. DEX ;TURN HI BIT ON IN PREVIOUS CHAR LDA BUF200,X ;STORED IN BUF200 TO CONVERT TO ORA #$80 ;LOWERCASE IF NECESSARY. STA BUF200,X TOEXIT JMP DOSEXIT ;GO TO DOS'S EXIT ROUTINE. *================================== * CHECK IF BASIC IS RUNNING A PRGM. *================================== CKBSCRUN PHA ;SAVE (A) ON STK. LDA ACTBSFLG ;WHICH BASIC IS UP? BEQ INTBASIC ;BRANCH IF USING INTEGER. * USING APPLESOFT SO NOW CHECK IF * IN IMMEDIATE OR DEFERRED MODE. * (IF LINE NUMBER BYTES ARE * GREATER THAN OR EQUAL TO DECIMAL * 65280 ($FF IN HI BYTE), THEN THE * COMPUTER ASSUMES THAT WE'RE USING * THE IMMEDIATE MODE.) LDX CURLIN+1 ;CHK HI BYTE OF LINE #. INX ;IF $FF --> $00, THEN # > = 65280 BEQ IMEDMODE ;BRANCH IF USING IMMEDIATE MODE. * FP APPEARS TO BE RUNNING A PRGM * BUT, MAYBE CURLIN+1 WAS ZAPPED * (POSSIBLY AS PART OF A PROTECTION * SCHEME) SO BETTER ALSO CHECK THE * PROMPT. LDX PROMPT CPX #"]" ;USING AN APPLESOFT PROMPT? BEQ IMEDMODE ;YES - SO MUST BE IN IMMED MODE. RUNNING PLA ;GET SAVED (A) BACK FROM STK. CLC ;SIGNAL PRGM IS RUNNING. RTS INTBASIC LDA RUNMODE ;CHK INTGR BASIC'S RUN MODE FLG. BMI RUNNING ;IF NEG, INT BASIC IN DEFERRED. IMEDMODE PLA ;GET SAVED (A) BACK FROM STK. SEC ;SIGNAL IN IMMEDIATE MODE. RTS *==================================== * CLOSE FILE, SET CONDITION0, & EXIT. *==================================== CLOSZERO JSR CLOSEONE ;CLOSE OPEN FILE. JSR RESTAT0 ;RESET TO CONDITION 0. JMP DOSEXIT ;GO TO DOS'S EXIT ROUTINE. *================================= * EXEC'S READ DATA ROUTINE. *================================= READEXEC JSR PT2EXEC ;POINT THE A3L/H POINTER AT BUF ;THAT WE'RE EXECING IN. JSR BUFS2PRM ;COPY ADDRS OF THE VARIOUS DOS ;BUFS FROM THE CHAIN BUF & PUT ;THEM IN THE FM PARAMETER LIST. LDA #3 ;SET CONDITION 3 SO PROCESS DATA BNE SETCOND ;INPUT FROM THE DISK. *================================= * READ A TEXT FILE BYTE. *================================= RDTXTBYT LDA #3 ;SET FM PRM LIST 2 READ ONE BYTE. STA OPCODEFM LDA #1 STA SUBCODFM JSR FMDRIVER ;CALL FM DRIVER TO READ A BYTE. LDA ONEIOBUF ;LOAD (A) WITH BYTE JUST READ. RTS *================================= * POINT THE A3L/H POINTER AT * BUFFER THAT WE'RE EXECING IN. *================================= PT2EXEC LDA EXECBUFF+1 ;GET ADR OF DOS BUF USING 2 EXEC. STA A3L+1 ;PUT IT IN POINTER. LDA EXECBUFF STA A3L RTS *================================= * THE FILE MANAGER DRIVER. *================================= FMDRIVER JSR FILEMGR ;CALL FM MANAGER TO DO FUNCTION. * RETURN HERE AFTER DOING THE FUNCTION. * (CAUSE, USE STACK TO GET BACK TO * ORIGINAL CALLER OF FUNCTION.) * IF WE JUST DID A READ FUNCTION & * THE LAST BYTE READ WAS FROM A DATA * SECTOR, THEN ENTER WITH (C)=0. * (NOTE THAT IT MAKES NO DIFFERENCE * IF THAT DATA BYTE WAS A $00 OR NOT.) * HOWEVER, IF WE ARE DEALING WITH A * ZEROED-OUT T/S LINK OR A ZEROED-OUT * DATA-PAIR BYTE FROM A T/S LIST, * THEN ENTER WITH CARRY SET. AFTRFUNC BCC FMDRVRTN ;(C) = 0 = NO ERRORS. LDA RTNCODFM ;GET RETURN CODE FRM FM PARM LIST CMP #5 ;"END-OF-DATA" ERROR? BEQ TOAPPTCH ;YES -NOT HANDLED LIKE OTHER ERRS ;FILE ENDS AT A FULL DATA SEC SO ;WE ENCOUNTERED A ZEROED-OUT T/S ;LINK OR A ZEROED-OUT DATA PAIR ;(TRK/SEC VALUES LISTED IN A T/S ;LIST). JMP OTHRERR ;ONLY TAKE IF GOT AN ERROR OTHER ;THAN AN END-OF-DATA ERROR. TOAPPTCH JMP APNDPTCH ;GO HANDLE END-OF-DATA ERROR. NOP BK2FMDRV JSR CKIFAPND ;<---NOTE: APNDPTCH RETURN HERE!! ;GO CHK IF THE APPEND FLAG IS ON. LDX #0 ;ZERO-OUT THE ONE-DATA-BYTE BUF STX ONEIOBUF ;IN THE FM PARAMETER LIST. (ALSO ;REFERRED TO AS THE LOW BYTE OF ;CURIOBUF.) FMDRVRTN RTS ;RETURN TO CALLER OF FM DRIVER. *================================= * SELECTED ERROR PROCESSING. *================================= * NOTE: PROGRAMMERS WHO ACCESS DOS * FROM ASSEMBLY LANGUAGE PROGRAMS * SHOULD TAKE SPECIAL NOTE OF THE * THE FORMATTED DISASSEMBLY TITLED * "DISASSEMBLY OF ERRORS". SYNTXERR LDA #11 BNE ERRHNDLR ;ALWAYS. NOBUFERR LDA #12 BNE ERRHNDLR ;ALWAYS. TOOLARGE LDA #14 BNE ERRHNDLR ;ALWAYS. TYPMISM LDA #13 *================================= * DOS'S MAIN ERROR-HANDLER ROUTINE *================================= ERRHNDLR STA ASAVED ;SAVE RETURN CODE FOR LATER USE. JSR RESTATIN ;RESET THE FOLLOWING FLAGS TO 0: ; OPUTCOND, CONDNFLG & RUNTRUPT. LDA ACTBSFLG ;CHK IF INT OR FP BASIC ACTIVE. BEQ WASINT ;BRANCH IF USING INTEGER. ;(ONERR FLAG NOT APPLIC TO INT.) LDA ERRFLG ;CHK IF BASIC'S ONERR FLAG IS ON. BMI ONERRACT ;YES - SKIP PRINTING OF ERROR MSG ;CAUSE WE EVENTUALLY WANT 2 GO 2 ;OUR OWN CUSTOMIZED ERROR-HNDLING ;ROUTINE. WASINT LDX #0 ;INITIALIZE INDEX TO TABLE OF ;OFFSETS TO ERRORS. JSR PRDOSERR ;GO PRINT , BELL, . LDX ASAVED ;GET SAVED RETURN CODE. JSR PRDOSERR ;GO PRINT THE ERROR MESSAGE. JSR CRVIADOS ;PRINT A . ONERRACT JSR INITIOHK ;RESET I/O HKS TO POINT TO DOS. JSR CKBSCRUN ;CHK IF BASIC IS RUNNING A PRGM: ; (C) = 0 IF RUNNING. ; (C) = 1 IF IMMEDIATE. LDX ASAVED ;GET SAVED RETURN CODE. LDA #3 ;SET (A) = 3 IN CASE FALL THRU TO ;GO TO BASIC'S ERROR HANDLING ;ROUTINE. THE MAGIC # OF 3 ALLOWS ;BSCERHLR ($D865) TO CONDITION ;(C) = 0 AND (Z) = 1 IN ORDER TO ;COMPLY WITH THE BASIC ROUTINE ;THAT IS RESPONSIBLE FOR PRINTING ;BASIC'S ERROR MESSAGES. BCS DOWRM ;BASIC IS NOT RUNNING. TOBSCERR JMP (ADBSCERR) ;2 BASIC'S ERROR HANDLING ROUTINE ;(BSCERHLR, $D865). DOWRM JMP (TOWRMVEC) ;TO BASIC'S WARMSTART ROUTINE ;(RESTART, $D43C). *================================= * PRINT THE DOS ERROR MESSAGE. *================================= PRDOSERR LDA OFF2ERR,X ;USE ERROR CODE TO GET OFFSET TO ;ERROR MESSAGE. TAX ;(X) = OFFSET INTO THE TABLE ;CONTAINING THE TEXT OF THE DOS ;ERROR MESSAGES. MORERMSG STX TEMPBYT ;SAVE OFFSET INTO TXT TABLE. LDA ERRTXTBL,X ;GET CHAR OF ERROR MESSAGE. PHA ;SAVE IT ON STACK. ORA #$80 ;TURN HI BIT ON 2 SATISFY MONITOR JSR GODSPLY ;GO PRINT VIA TRUE OUTPUT HANDLER LDX TEMPBYT ;RESET OFFSET TO TABLE OF TEXT. INX ;KICK INDEX UP FOR NXT CHR OF MSG PLA ;GET ORIG CHAR BACK IN (A). BPL MORERMSG ;BRANCH IF MORE CHRS IN MSG 2 PRT RTS ;ALL BUT LAST CHR IN MSG ARE POS. *================================= * PUT VOL, DRV, AND SLOT VALUES * PLUS THE ADR OF THE PRIMARY FILE * NAME BUFFER IN FM PARAMETER LIST *================================= CPY2PARM LDA VOLPRSD ;FROM PARSED TABLE. STA VOLFM LDA DRVPRSD ;FROM PARSED TABLE. STA DRVFM LDA SLOTPRSD ;FROM PARSED TABLE. STA SLOTFM LDA ADRPFNBF ;GET THE ADR OF THE PRIMARY FILE STA FNAMBUFM ;NAME BUF FROM THE CONSTANTS TBL LDA ADRPFNBF+1 ;AND PUT IT IN THE FM PARM LIST. STA FNAMBUFM+1 LDA A3L ;SAVE ADR OF CURRENT DOS FILENAME STA CURFNADR ;BUF IN TABLE OF DOS VARIABLES. LDA A3L+1 STA CURFNADR+1 RTS *=================================== * COPY NAME OF FILE FROM THE PRIMARY * FILENAME BUFFER TO THE APPROPRIATE * DOS NAME BUFFER LOCATED IN THE * CHAIN OF DOS BUFFERS. * THIS ASSIGNS (OR RE-ASSIGNS) A DOS * BUFFER TO THE FILE WE WANT TO OPEN. * THE HIGHEST NUMBERED (LOWEST IN * MEMORY) FREE DOS BUFFER IS USED. *=================================== CPYPFN LDY #29 ;30 BYTES TO COPY (0 TO 29). CPYPRIM LDA PRIMFNBF,Y ;GET CHAR FROM PRIMARY. STA (A3L),Y ;STORE IT IN DOS NAME BUF. DEY ;REDUCE COUNTER. BPL CPYPRIM ;MORE CHARS TO COPY. RTS *==================================== * GET THE ADDRS OF THE VARIOUS DOS * BUFS FROM THE CURRENT DOS CHAIN * BUF & PUT THEM IN THE FM PARM LIST. *==================================== BUFS2PRM LDY #30 ;GET ADR OF FM WORK BUF, T/S LIST ADRINPRM LDA (A3L),Y ;BUF, DATA SECTOR BUF & NEXT STA WRKBUFFM-30,Y ;DOS FILE NAME BUF FROM CHAIN INY ;PTRS BUF & PUT IN FM PARM LIST. CPY #38 ;(PS. ADDR OF NEXT DOS FILE NAME BNE ADRINPRM ;BUF IS NOT USED BY DOS.) RTS *================================= * RESET CONDNFLG & OPUTCOND TO 0. *================================= RESTAT0 LDY #0 STY CONDNFLG STY OPUTCOND RTS *================================== * LOCATE BUFFER WITH SAME NAME. * IF THAT FAILS, LOCATE A FREE BUF. *================================== GETBUFF LDA #0 ;DEFAULT HI BYTE OF PTR TO 0. STA A5L+1 ;(IE. ASSUME NO FREE BUFS AVAIL.) JSR GETFNBF1 ;PT A3L/H AT 1RST DOS FILE NAME ;BUFFER IN THE DOS BUFFER CHAIN. JMP FNCHAR1 ;GO GET 1RST CHR OF NAME FRM BUF. GETFNLNK JSR GETNXBUF ;GET ADR OF NXT NAME BUF IN CHAIN ;FROM CHAIN POINTERS BUF(WHICH IS ;OFFSET 37 & 36 BYTES FROM 1RST ;CHAR OF PRESENT FILE NAME BUF). BEQ NOFNMTCH ;LINK ZEROED OUT=END OF BUF CHAIN FNCHAR1 JSR GETFNBY1 ;GET 1RST CHR OF NAME FRM NAM BUF BNE NXFNBUF ;TAKE BRANCH IF BUF NOT FREE. LDA A3L ;BUF WAS FREE, THERE4 POINT THE STA A5L ;A5L/H POINTERS AT THE FREE BUF. LDA A3L+1 STA A5L+1 BNE GETFNLNK ;ALWAYS. NXFNBUF LDY #29 ;BUF WASN'T FREE SO CMP NAME OF CMPFNCHR LDA (A3L),Y ;OWNER WITH NAME OF FILE IN CMP PRIMFNBF,Y ;PRIMARY FILE NAME BUF. (START ;WITH LAST CHAR FIRST.) BNE GETFNLNK ;CHAR DIDN'T MATCH, SO LOOK FOR ;ANOTHER BUF THAT MIGHT HAS SAME ;FILE NAME. DEY ;THAT CHAR MATCHED. HOW ABOUT ;REST OF CHARS IN NAME? BPL CMPFNCHR ;30 CHARS IN NAME (IE. 0 TO 29). CLC ;(C)=0 TO SIGNAL NAMES MATCHED. RTS NOFNMTCH SEC ;LINK ZEROED OUT. RTS *=================================== * POINT THE A3L/H POINTER AT THE * FIRST DOS FILE NAME BUFFER IN * THE DOS BUFFER CHAIN. (IE. LOWEST * NUMBERED BUFFER, BUT HIGHEST IN * MEMORY.) *=================================== GETFNBF1 LDA ADOSFNB1 ;GET 1RST LINK TO CHAIN OF BUFS. LDX ADOSFNB1+1 BNE SETNXPTR ;ALWAYS. *================================= * GET ADR OF NXT FILENAME BUF IN * CHAIN FROM THE CURRENT CHAIN * POINTERS BUF (WHICH IS OFFSET * 37 & 36 BYTES FROM 1RST CHAR * IN PRESENT DOS FILE NAME BUF). *--------------------------------- GETNXBUF LDY #37 ;OFFSET TO CHAIN BUF. LDA (A3L),Y ;PICK UP ADR OF NEXT NAME BUF. BEQ GETNXRTN ;IF HI BYTE=$00, LINK ZEROED OUT. TAX ;SAVE HI BYTE IN (X). DEY ;OFFSET FOR LOW BYTE. LDA (A3L),Y ;PUT ADR OF FILE NAME BUF IN PTR. SETNXPTR STX A3L+1 ;PUT HI BYTE IN POINTER. STA A3L ;PUT LOW BYTE IN POINTER. TXA ;GET HI BYTE BACK IN (A). GETNXRTN RTS *================================= * GET 1RST CHAR OF FILE NAME * FROM DOS FILE NAME BUFFER. *================================= GETFNBY1 LDY #0 ;BUF IS FREE IF 1RST BYTE = $00. LDA (A3L),Y ;ELSE 1RST BYTE = 1RST CHAR OF RTS ;NAME OF FILE WHICH OWNS BUF. *================================= * CHECK IF THE CURRENT FILE NAME * BUFFER BELONGS TO AN EXEC FILE. * (AFTER ALL, WE DON'T WANT TO * PREMATURELY CLOSE A FILE IF WE * ARE USING IT TO EXEC - WOULD BE * LIKE BURYING OURSELVES ALIVE). *================================= CKEXCBUF LDA EXECFLAG ;CHK TO SEE IF EXECING. BEQ NOTEXCBF ;BRANCH IF NOT EXECING. LDA EXECBUFF ;WE ARE EXECING, THERE4 CHK IF BUF CMP A3L ;BELONGS TO THE EXEC FILE. BNE CKEXCRTN ;NO. LDA EXECBUFF+1 ;MAYBE - LOW BYTES MATCHED SO CMP A3L+1 ;CHK HI BYTES OF ADR. BEQ CKEXCRTN ;YES, EXEC BUF = CURRENT BUF. NOTEXCBF DEX ;NOT EXECING, SO REDUCE (X) TO ;MAKE SURE THAT Z-FLAG IS OFF. ;(PS. (X) WAS ORIG CONDITIONED TO ;A LARGE NON-ZERO VAL ON ENTRY ;TO GETFNBF1, THERE4, IF NOW DEX, ;THEN INSURE Z-FLAG OFF.) CKEXCRTN RTS ;EXIT WITH: ; Z-FLAG = 1 IF EXECING. ; = 0 IF NOT EXECING. *====================================== * CHK IF FILE TYPE WANTED = TYPE FOUND. *====================================== CHKFTYPE EOR FILTYPFM ;TYPE FOUND (VIA OPEN FUNCTION). BEQ CKTYPRTN ;BRNCH IF TYPE WANTED=TYPE FOUND. AND #%01111111 ;MAYBE MATCHED-DISREGARD LOCK BIT BEQ CKTYPRTN ;BRANCH IF MATCHED. JSR CMDCLOSE ;NAMED FILE IS WRONG TYPE, SO GO JMP TYPMISM ;CLOSE FILE & EXIT WITH A TYPE- ;MISMATCH ERROR MESSAGE. CKTYPRTN RTS ;TYPE WANTED = TYPE FOUND. *================================= * BUILD THE DOS BUFFERS. *================================= * POINT A3L/H AT FILENAME FIELD * IN THE LOWEST NUMBERD (HIGHEST * IN MEMORY) DOS BUFFER. BILDBUFS SEC ;IRREL, MIGHT AS WELL BE A "NOP". LDA ADOSFNB1 ;GET ADDR OF 1RST FILE NAME FIELD STA A3L ;& PUT IT IN A3L/H POINTER. LDA ADOSFNB1+1 STA A3L+1 * GET # OF MAXFILES WANTED & STORE * IT IN THE COUNTER (TEMPBYT). LDA MXFILVAL STA TEMPBYT * FREE BUFFER BY ZEROING OUT THE * FIRST BYTE OF THE DOS BUFFER'S * FILE NAME FIELD. ZDOSBUFN LDY #0 TYA STA (A3L),Y * POINT LINK IN CHAIN POINTERS BUF * AT FM WORK AREA BUFFER. LDY #30 ;SET (Y) TO INDEX 1RST LINK IN ;CHAIN POINTERS BUFFER. SEC LDA A3L ;SUBT 45 FROM LOW BYTE OF ADDR SBC #45 ;OF NAME BUF TO CALC LOW BYTE OF STA (A3L),Y ;ADDR OF FM WORK BUF & PUT IT IN PHA ;THE CHAIN PTR BUF & ON THE STK. LDA A3L+1 ;SUBT (C) FROM HIGH BYTE OF ADR SBC #0 ;OF NAME BUF TO GET HI BYTE OF ;FM WRK BUF ADR. INY ;KICK UP (Y) TO INDEX ADDR OF HI ;BYTE OF LINK IN CHAIN POINTERS. STA (A3L),Y ;STORE HI BYTE OF ADR OF FM WRK ;BUF IN THE LINK. ;(NOTE: ABOVE CALCS EFFECT (A) ;BUT NOT A3L/H.) * POINT LINK IN CHAIN POINTERS BUFFER * AT T/S LIST SECTOR BUFFER. TAX ;PUT HI BYTE OF ADDR OF FM WRK BUF DEX ;IN (X) & KICK IT DOWN SO IT ;INDEXES HI BYTE OF T/S LIST BUF. ;(T/S LST BUF = $100 BYTES LONG.) PLA ;GET LOW BYTE OF ADDR OF FM WRK PHA ;BACK FROM STK. INY ;KICK UP INDEX TO LINK IN CHAIN ;POINTERS BUFFER. STA (A3L),Y ;PUT LOW BYTE OF FM WRK BUF ADR ;IN LINK BUFFER'S POINTERS. TXA ;GET HI BYTE T/S LIST BUF IN (A). INY ;KICK UP INDEX IN CHAIN BUF. STA (A3L),Y ;PUT HI BYTE OF LINK IN PTRS BUF. * POINT LINK IN CHAIN POINTERS BUF * AT DATA SECTOR BUFFER. TAX ;PUT HI BYTE OF ADDR OF T/S LIST DEX ;BUF IN (X) & KICK IT DOWN TO ;CORRESPOND TO HI BYTE OF ADDR ;OF DATA SEC BUF. PLA ;GET LOW BYTE OF T/S LIST SEC BUF PHA ;FROM STACK & USE IT FOR LOW BYTE ;OF DATA SEC BUF (CAUSE THEY ARE ;EXACTLY 1 PAGE APART). INY ;KICK UP INDEX TO CHAIN BUF. STA (A3L),Y ;PUT LOW BYTE OF DATA SEC BUF ;IN LINK. INY ;KICK UP INDEX TO CHAIN BUF. TXA ;GET HI BYTE OF ADR OF T/S LIST STA (A3L),Y ;BUF & DESIGN8 AS HI BYT OF LINK. * REDUCE COUNTER FOR # OF BUFS TO BUILD. DEC TEMPBYT ;IF COUNTER GOES TO 0, THEN JUST BEQ ZLNK2NXT ;DID LAST BUF & SHOULD 0 OUT LNK. * NOT DONE ALL BUFS YET SO POINT * LINK IN CHAIN POINTERS BUFFER * AT NEXT FILE NAME FIELD. TAX ;SET (X) = LOW BYTE OF ADR OF DATA ;SECTOR BUFFER. PLA ;GET LOW BYTE OF ADDR OF DATA ;SECTOR BUF BACK OFF STK. SEC ;SUBT 38 FROM LOW BYTE OF DATA SEC SBC #38 ;ADR TO INDEX NEXT NAME BUF. INY ;KICK UP INDEX TO CHAIN BUF. STA (A3L),Y ;STORE LOW BYTE OF ADR OF NEXT PHA ;NAME BUF IN LINK & THEN SAVE ;IT ON STK. TXA ;GET HI BYTE OF ADR OF DATA SEC SBC #0 ;BUF FROM (X) & SUBT (C) (IN CASE ;CROSS PAGE BOUNDARY) TO GET ;(A) = HI BYTE OF NEXT NAME BUF. INY ;KICK INDEX UP TO CHAIN PTRS BUF STA (A3L),Y ;& STORE HI BYTE OF NEXT NAME BUF ;IN LINK. * POINT A3L/H AT NEXT NAME BUF. STA A3L+1 PLA STA A3L JMP ZDOSBUFN ;GO BACK TO FREE NEXT NAME BUF ;& BUILD MORE DOS BUFFERS. * NO MORE BUFS TO BUILD SO ZERO OUT * THE LINK THAT WOULD NORMALLY POINT * TO THE NEXT NAME BUFFER. ZLNK2NXT PHA ;SAVE LOW BYTE OF ADR OF DATA BUF ;ON STK. LDA #0 ;ZERO OUT LINK TO NEXT NAME BUF. INY STA (A3L),Y INY STA (A3L),Y * CHK WHICH BASIC IS ACTIVE. LDA ACTBSFLG ;CHK IF ACTV BASIC IS FP OR INT. BEQ SETINTPT ;BRANCH IF INTEGER. * USING APPLESOFT, SO INITIALIZE * MEMSIZ & FRETOP (STRING STORAGE) * TO A VALUE 1 BYTE GREATER THAN * HIGHEST MEMORY LOCATION AVAILABLE * TO BASIC PROGRAM. PLA STA MEMSIZ+1 STA FRETOP+1 PLA STA MEMSIZ STA FRETOP RTS ;EXIT TO CALLER OF MAXFILES CMD. ;(USUALLY EXITS 2 AFTRCMD ($A17D) ;LOCATED IN THE DOS CMD PARSING ;AND PROCESSING ROUTINES.) * USING INTEGER, SO SET HIMEM AND * PROGRAM POINTER (INTPGMST). SETINTPT PLA STA HIMEM+1 STA INTPGMST+1 PLA STA HIMEM STA INTPGMST RTS ;EXIT TO CALLER OF MAXFILES CMD. ;(USUALLY EXITS 2 AFTRCMD ($A17D) ;LOCATED IN THE DOS CMD PARSING ;AND PROCESSING ROUTINES.) O