* CACHE PROGRAM FOR SK*DOS PLUS+ * FOR THE COLOR COMPUTER * COPYRIGHT (C) 1984 BY PETER A. STARK * FOR STAR-K SOFTWARE SYSTEMS CORP. * SK*DOS EQUATES TTYEOL EQU $CC02 MEMEND EQU $CC2B MAXDRV EQU $CC5F WARMST EQU $CD03 PSTRNG EQU $CD1E PCRLF EQU $CD24 NXTCH EQU $CD27 FCS EQU $D406 CACVEC EQU $D432 CACHE VECTOR IN SK*DOS CACFLG EQU $CC60 FLAG = $1234 IF CACHE INIT NONDSL EQU $FFAE NON-DSL MEMORY DSL EQU $FFAF DSL MEMORY DSL0 EQU $FFAC DSL PAGE 0 DSL1 EQU $FFAD DSL PAGE 1 ORG $C100 * CACHE LOADER PROGRAM START BRA START1 FCB 1 VERSION * CHECK IF 128K MEMORY EXISTS START1 JSR PCRLF LBSR IRQOFF TURN OFF INTERRUPTS STS STACK,PCR SAVE SYSTEM STACK LEAS CSTACK,PCR USE OUR STACK INSTEAD LBSR PAGE0 MAKE SURE WE'RE IN RS MEMORY LDY $1000 SAVE MEM CONTENTS LDD #$A5A5 JUST SOME STUFF STD $1000 PUT INTO MEMORY LBSR PAGE1 SWITCH TO DSL MEMORY LDU $1000 TEMP SAVE BUFFER BYTES CLR $1000 ERASE BUFFER ON PAGE 1 LBSR PAGE0 SWITCH BACK TO RS MEM LDS STACK,PCR RESTORE SYSTEM STACK LDD $1000 GET PAGE 0 MEMORY STY $1000 RESTORE OLD PAGE 0 MEMORY CMPD #$A5A5 CHECK IF STILL THERE LBNE DSLMNG IF DSL MEMORY NO GOOD STS STACK,PCR SAVE SYSTEM STACK LEAS CSTACK,PCR USE OUR STACK INSTEAD LBSR PAGE1 SWITCH BACK TO PAGE 1 STU $1000 RESTORE CONTENTS LBSR PAGE0 AND BACK TO MAIN MEMORY LDS STACK,PCR RESTORE SYSTEM STACK * CHECK WHETHER CALL HAD ARGUMENTS JSR NXTCH GET NEXT CHARACTER CMPA #$0D CR? BEQ NOARGS NO ARGUMENTS CMPA TTYEOL EOL? BEQ NOARGS NO SUBA #'0 CONVERT FROM ASCII CMPA MAXDRV VALID DRIVE NUMBER? BHI BADARG * IF A VALID ARGUMENT EXISTS, CHECK IF PREVIOUSLY * INITIALIZED; ERROR IF NOT PSHS A SAVE DRIVE NUMBER LDD CACFLG LOOK AT SK*DOS CACHE FLAG CMPD #$1234 IS IT 1234? PULS A RESTORE DRIVE NUMBER BNE NOTINI IF NOT INITIALIZED ****************************************** * IF CALL WAS 'CACHE N' AND CACHE HAS BEEN * INITIALIZED, THEN ERASE ALL ENTRIES FOR * DRIVE N ****************************************** LDX CACVEC+1 POINT TO BEG OF CACHE PROGRAM PSHS A SAVE DRIVE NUMBER LDD 3,X GET OFFSET TO CACHE MAP LEAX D,X POINT TO THE MAP PULS A RESTORE DRIVE NUMBER CLRB COUNTER = 256 ERASEN CMPA 0,X CHECK IF DRIVE NUMBER MATCHES BNE ERASNO DON'T ERASE IF NO MATCH CLR 3,X ELSE ERASE TIMER ON ENTRY ERASNO LEAX 4,X POINT TO NEXT DECB DECREMENT COUNTER BNE ERASEN * THEN RETURN BACK TO SK*DOS JMP WARMST ******************************************* * IF CALL WAS JUST 'CACHE' W/O ARGUMENTS, * THEN EVERYTHING GETS INITIALIZED. ******************************************* * FIRST, CHECK IF THIS IS INITIAL CACHE CLEAR NOARGS LDD CACFLG CHECK IF ALREADY INITIALIZED CMPD #$1234 IS IT ALREADY INIT? BEQ SECINI MUST BE SECOND INITIALIZATION LDD #$1234 ELSE FLAG IT AS INITIALIZED STD CACFLG * ON FIRST INITIALIZATION, MOVE CACHE PROGRAM INTO * LOWER MEMORY AND SET UP MEMEND VECTOR LDD MEMEND GET CURRENT MEMEND SUBD #CEND ADDD #CSTART SUBTRACT LENGTH OF CACHE PGM ANDB #$F0 MOVE TO NEXT LOWER 16-BYTES TFR D,X MOVE INTO X REGISTER SUBD #1 DECREMENT BY ONE STD MEMEND SET MEMORY END LDA #$7E STA CACVEC SET UP SK*DOS CACHE VECTOR STX CACVEC+1 LDY #CSTART POINT TO CACHE PROGRAM CMOVE LDA 0,Y+ GET A BYTE STA 0,X+ MOVE INTO LOWER MEMORY CMPY #CEND FINISHED? BNE CMOVE NO, MOVE MORE * NOW INITIALIZE THE CACHE MAP TO ALL 0 SECINI LDX CACVEC+1 POINT TO BEG OF CACHE PGM LDD 3,X GET OFFSET TO CACHE MAP LEAX D,X POINT TO THE MAP CLRB COUNTER = 256 ERASE CLR 3,X ERASE TIMER ON ENTRY LEAX 4,X POINT TO NEXT DECB DECREMENT COUNTER BNE ERASE * AND FINALLY RETURN TO SK*DOS JMP WARMST * ERROR PROCESSING DSLMNG LDX #DSLMSG JSR PSTRNG PRINT '128K NOT INSTALLED' JMP WARMST BADARG LDX #BSYMSG JSR PSTRNG PRINT 'BAD COMMAND SYNTAX' JMP WARMST NOTINI LDX #NINMSG JSR PSTRNG PRINT 'CACHE MEMORY NOT INIT' JMP WARMST * STRINGS DSLMSG FCC '128K MEMORY NOT INSTALLED.',4 BSYMSG FCC 'INVALID COMMAND SYNTAX',4 NINMSG FCC 'CACHE MEMORY NOT INITIALIZED',4 FCC 'COPYRIGHT (C) 1984 BY PETER A. STARK ' FCC 'STAR-K SOFTWARE SYSTEMS CORP.' ******************************************* * ACTUAL CACHE PROGRAM FOLLOWS. THIS PGM IS * CALLED FROM SK*DOS ON EACH CALL TO FCS * FUNCTION 9 OR 10; ON ENTRY, X POINTS TO * CURRENT FCB AND Z BIT INDICATES WHETHER * READ (BNE) OR WRITE (BEQ). ******************************************* CSTART LBRA CS1 JUMP TO ACTUAL START FDB CMAP-CSTART OFFSET TO CACHE MAP CS1 BEQ WRITE GO TO WRITE IF BEQ * READ CACHE ROUTINE STX FCB,PCR SAVE FCB POINTER LDA 3,X GET DRIVE NUMBER LDY 30,X GET TRACK AND SECTOR NUMBER LBSR SEARCH SEARCH CACHE MAP FOR SECTOR LBEQ DOFCS NOT IN CACHE * IF IT IS IN CACHE, SET TIMER BIG LDY MAPADD,PCR POINT TO ENTRY IN CACHE MAP LDA #$FF STA 3,Y * NOW READ AND MOVE INTO USER'S FCB LBSR IRQOFF TURN OFF INTERRUPTS STS STACK,PCR SAVE SYSTEM STACK LEAS CSTACK,PCR USE OUR STACK INSTEAD LBSR GETPAG SWITCH TO CORRECT PAGE LDX CACADD,PCR POINT TO ADDRESS IN CACHE LEAY BUFFER,PCR THEN POINT TO BUFFER LBSR MOVE MOVE SECTOR LBSR PAGE0 NOW GO BACK TO PAGE 0 LDS STACK,PCR RESTORE SYSTEM STACK LEAX BUFFER,PCR POINT TO BUFFER LDY FCB,PCR POINT TO USER'S FCB LEAY 64,Y AND THEN DATA AREA LBSR MOVE MOVE SECTOR LBSR DOTIME DECREMENT EVERYBODY'S TIMER LEAS 2,S PULL RTS ADDRESS FROM STACK PULS A,B,X,Y,U,PC AND RETURN TO USER * WRITE CACHE ROUTINE WRITE STX FCB,PCR SAVE FCB POINTER LDA 3,X GET DRIVE NUMBER LDY 30,X GET TRACK AND SECTOR NUMBER LBSR SEARCH SEARCH CACHE MAP FOR SECTOR * FALL THROUGH INTO DOFCS ********************************************** * DOFCS - USES SK*DOS FCS TO READ OR WRITE * SECTOR SPECIFIED IN FCB, THEN COPIES IT FROM * FCB INTO CACHE, UPDATES CACHE MAP, BUMPS ALL * TIMERS, AND EXITS ********************************************* DOFCS LDX 10,S GET ORIG RET ADDR FROM FCS STX RETADD,PCR TEMP SAVE IT LEAX FCSRET,PCR GET ADDR WHERE TO GO STX 10,S PUT BACK ON STACK INSTEAD RTS AND RETURN BACK TO FCS * AT THIS POINT, FCS READS OR WRITES THE REQUESTED * SECTOR AND PUTS IT INTO USER'S FCB. THEN IT * RETURNS TO US RIGHT HERE! * ON RETURN, NOTHING IS ON STACK FROM FCS9 OR 10 FCSRET BEQ NOERR IF THERE WAS NO ERROR JMP [RETADD,PCR] ELSE ON ERROR IMMED RETURN * IF THERE WAS NO ERROR, THEN WE HAVE TO PUT * THE DATA JUST READ OR WRITTEN INTO THE CACHE NOERR PSHS A,B,X,Y,U PUT ALL BACK ON STACK LDX FCB,PCR POINT TO FCB LDB 3,X GET DRIVE NUMBER LDY MAPADD,PCR POINT TO MAP ENTRY STB 0,Y PUT INTO MAP LDD 30,X STD 1,Y TRACK AND SECTOR NUMBER LDB #$FF STB 3,Y TIMER * TRANSFER USER'S DATA INTO BUFFER LEAX 64,X POINT TO USER'S DATA AREA LEAY BUFFER,PCR POINT TO BUFFER LBSR MOVE MOVE SECTOR * NOW TRANSFER FROM BUFFER INTO CACHE LBSR IRQOFF TURN OFF INTERRUPTS STS STACK,PCR SAVE SYSTEM STACK LEAS CSTACK,PCR USE OUR STACK INSTEAD LBSR GETPAG SWITCH TO CORRECT PAGE LDY CACADD,PCR POINT TO SECTOR IN CACHE LEAX BUFFER,PCR POINT TO BUFFER LBSR MOVE MOVE SECTOR LBSR PAGE0 SWITCH BACK TO PAGE 0 LDS STACK,PCR RESTORE SYSTEM STACK LBSR DOTIME DECREMENT EVERYBODY'S TIMER PULS A,B,X,Y,U RESTORE FCS REGISTERS JMP [RETADD,PCR] AND RETURN TO USER *********************************************** * SEARCH ROUTINE - SEARCHES CACHE MAP FOR ENTRY * ON ENTRY: A= DRIVE NO, Y= TRACK & SECTOR * ON EXIT : BNE IF SECTOR ALREADY IS IN CACHE MAP * BEQ IF NOT IN CACHE MAP * EITHER WAY, HOWEVER, * PAGE = PAGE 1 OR 2 * CACADD = ADDRESS IN CACHE * MAPADD = ADDRESS IN CACHE MAP * THESE POINT TO ENTRY IF FOUND, OR TO * EMPTY OR OLDEST ENTRY IN FILE MAP *********************************************** SEARCH LEAX CMAP,PCR POINT TO CACHE MAP CLRB COUNTER = 256 SLOOP TST 3,X CHECK TIMER BEQ NFOUND 0 MEANS EMPTY CMPA 0,X CHECK DRIVE NUMBER BNE NFOUND NOT FOUND CMPY 1,X CHECK TRACK AND SECTOR BEQ FOUND NFOUND LEAX 4,X POINT TO NEXT ENTRY DECB DECREMENT COUNTER BNE SLOOP AND TRY NEXT ENTRY * WHEN ENTRY IS NOT FOUND, THEN FIND * EITHER AN EMPTY ONE OR THE OLDEST LDA #$FF VERY BIG NUMBER LEAX CMAP,PCR POINT BACK TO CACHE MAP ELOOP TST 3,X CHECK IF EMPTY BEQ FOUNDE FOUND AN EMPTY ONE CMPA 3,X ELSE CHECK IF SMALLER BLO NOTSM NOT SMALLER STX MAPADD,PCR YES, WAS SMALLER SO SAVE IT LDA 3,X AND GET THE SMALLER TIMER NOTSM LEAX 4,X NOW POINT TO NEXT ENTRY DECB DECREMENT COUNTER BNE ELOOP LOOK FOR NEXT SMALLER/EMPTY LDX MAPADD,PCR POINT BACK TO SMALLEST * WHEN AN EMPTY OR SMALLEST IS FOUND, FIND * OUT WHERE IT IS FOUNDE BSR FINDIT FIGURE OUT WHERE IT IS CLRA SIGNAL THAT IT WASN'T FOUND RTS AND RETURN * WHEN ENTRY IS FOUND, ALSO FIND IT FOUND BSR FINDIT FIGURE OUT WHERE IT IS LDA #1 SIGNAL THAT IT WAS FOUND RTS AND RETURN * FIND IT ROUTINE FINDS LOCATION OF ENTRY IN CACHE FINDIT STX MAPADD,PCR SAVE CACHE MAP ENTRY ADDRESS CLR PAGE,PCR TEMP SET FOR PAGE 1 TFR X,D MOVE INTO D LEAX CMAP,PCR POINT TO BEGINNING OF MAP STX CACADD,PCR TEMP SAVE IT SUBD CACADD,PCR SUBTRACT BEGINNING RORA RORB DIVIDE OFFSET BY 4 RORA RORB EXG A,B MOVE OFFSET INTO A TSTA CHECK IT BPL USEIT USE AS IS IF PAGE 1 INC PAGE,PCR SWITCH TO PAGE 2 IF MINUS ANDA #$7F AND REMOVE SIGN BIT USEIT STD CACADD,PCR SAVE CACHE ADDRESS RTS AND RETURN ************************************ * DOTIME - DECREMENT EVERYBODY'S * TIMER TO KEEP TRACK OF OLDEST ************************************ DOTIME LEAX CMAP,PCR POINT TO CACHE MAP CLRB COUNTER = 256 DOLOOP LDA 3,X GET NEXT TIMER CMPA #1 IS IT 1 OR 0? BLS NODO YES, SO KEEP AS IS DEC 3,X ELSE DECREMENT IT NODO LEAX 4,X POINT TO NEXT ENTRY DECB DECREMENT COUNTER BNE DOLOOP REPEAT 256 TIMES RTS THEN QUIT ***************************** * MOVE ROUTINE: MOVE A SECTOR * FROM X-> TO Y-> ***************************** MOVE CLRB COUNTER = 256 MOVE1 LDA 0,X+ STA 0,Y+ DECB BNE MOVE1 RTS ********************************* * ROUTINES TO SWITCH MEMORY PAGES ********************************* GETPAG TST PAGE,PCR SELECT CORRECT PAGE BEQ PAGE1 BRA PAGE2 PAGE0 CLR NONDSL GO TO PAGE 0 LDA CCREG,PCR RESTORE CC REGISTER TFR A,CC INTERRUPT CODES RTS AND RETURN IRQOFF PSHS A TFR CC,A TURN OFF INTERRUPTS STA CCREG,PCR SAVE INTERRUPT CODE ORCC #$50 TURN OFF INTERRUPTS PULS A RTS PAGE1 CLR DSL0 CLR DSL SWITCH TO PAGE 1 RTS AND RETURN PAGE2 CLR DSL1 CLR DSL SWITCH TO PAGE 2 RTS AND RETURN * DATA AREA CCREG RMB 1 CC REGISTER STORAGE FCB RMB 2 USER'S FCB ADDRESS PAGE RMB 1 PAGE 1 OR 2 CACADD RMB 2 ADDRESS OF SECTOR ON PAGE MAPADD RMB 2 ADDR OF SECTOR ENTRY IN MAP RETADD RMB 2 RETURN ADDRESS STACK RMB 2 SYSTEM STACK RMB 9 CSTACK RMB 1 OUR STACK BUFFER RMB 256 SECTOR BUFFER CMAP RMB 1024 CACHE MAP 256 SCTRS * 4 CEND EQU * MARKS END OF CACHE PROGRAM END START