* SUPER-BOOT FOR DC-4 - TYPE CONTROLLERS * POSITION-INDEPENDENT CODE FOR SK*DOS * (C) 1984 BY PETER A. STARK * EXPLANATION OF DLATCH OPERATION: * ON WRITE: BITS 0 AND 1 SELECT DRIVE 0-3 * BIT 6 SELECTS SIDE (0=SIDE A) * BIT 7 DISABLES DRIVE SELECT IF 1 * ON READ: BIT 6 SAME AS FDC INTRQ OUTPUT PIN * BIT 7 SAME AS FDC DRQ OUTPUT PIN * SUPER BOOT EQUATES DLATCH EQU $E014 DRIVE SELECT LATCH CMDREG EQU $E018 FDC COMMAND REGISTER STAREG EQU CMDREG FDC STATUS REGISTER TRKREG EQU $E019 FDC TRACK REGISTER SECREG EQU $E01A FDC SECTOR REGISTER DATREG EQU $E01B FDC DATA REGISTER INCHE EQU $F806 MONITOR INPUT CHARACTER WITH ECHO MPSTRN EQU $F810 MONITOR PSTRNG ROUTINE MONITR EQU $F814 MONITOR RE-ENTRY POINT BOOT BRA BOOT1 FCC 'DC4' FOR DC-4 CONTROLLER FIRSTS FDB 0 FIRST TRACK-SECTOR OF DOS DIDENS FCB 0 0=SD DISK; OR NO OF SEC ON TRK 2 DUBLFL FCB 0 0=SINGLE-STEPPING DRIVE SECSID FCB 10 SECT PER SIDE (DEF 10 FOR SD) BOOT1 LDS #$C980 SET STACK POINTER CLR DLATCH FORCE DRIVE 0, SS, AND SD LDA #$0B STA CMDREG RESTORE, LOAD HEAD, SLOW STEP LBSR WNBUSY PAUSE AND WAIT FOR NOT BUSY LEAX BOOT+256,PCR STX BUFFAD,PCR SAVE ADDRESS OF 2ND 256 BYTES LDD #$0002 TRACK 0 SECT 2 STD TRSEC,PCR BSR GETSEC READ SECOND HALF OF SUPER BOOT BNE BOOT1 IMMEDIATELY RETRY ON ERROR LDA DIDENS,PCR CHECK DISK DENSITY BEQ DISKSD ZERO MEANS DISK IS SINGLE DENSITY STA SECSID,PCR ELSE UPDATE SECTORS PER SIDE DISKSD LEAX SBBUFF,PCR STX BUFFAD,PCR USE SBBUF FROM NOW ON LDD FIRSTS,PCR FIRST TRACK-SECTOR IS NOW ... STD TRSEC,PCR NEXT TRACK-SECTOR LBEQ LNKERR IF NOT LINKED CLR DATPTR,PCR CLEAR DATA POINTER LDX #$FFFF STX TRADDR,PCR ERASE TRANSFER ADDRESS LBRA MLOOP CONTINUE WITH MAIN LOOP * GET THE NEXT SECTOR GETSEC LDD TRSEC,PCR NEXT TRACK-SECTOR LBEQ DONE NEXT IS 00-00 SO END STB SECREG GIVE SECTOR TO FDC CMPB SECSID,PCR COMPARE WITH SECTORS PER SIDE BLS SIDEA IF SIDE A LDB #$40 STB DLATCH ELSE SWITCH TO SIDE B BRA SIDEOK SIDEA CLR DLATCH IF SIDE A SIDEOK CMPA TRKREG ALREADY ON RIGHT TRACK? BEQ TRKOK YES TST DUBLFL,PCR CHECK IF WE'RE DOUBLE-STEPPING BEQ GOSEEK NO, SEEK NORMALLY ASL TRKREG MAKE BELIEVE FDC ON TRACK * 2 ASLA AND DESIRED TRACK IS ALSO * 2 GOSEEK STA DATREG NO, GIVE TRACK TO FDC LDA #$1B STA CMDREG SEEK, LOAD, SLOW STEP RATE BSR WNBUSY WAIT FOR COMPLETION TST DUBLFL,PCR CHECK IF DOUBLE-STEPPING BEQ TRKOK IF NOT, THEN TRAK REG IS OK LSR TRKREG ELSE UNFOOL FDC TRKOK ORCC #$50 DISABLE INTERRUPTS TST TRSEC,PCR CHECK TRACK NUMBER BEQ READSD READ TRACK 0 AS SINGLE DENSITY TST DIDENS,PCR CHECK REST OF DISK LBNE READDD <>0 MEANS DOUBLE DENSITY * SINGLE DENSITY READ ROUTINE READSD CLRB COUNTER = 256 LDX BUFFAD,PCR POINT TO BUFFER LDA #$8C STA CMDREG READ COMMAND BSR WAIT SDLOOP LDA STAREG BITA #2 DRQ? BNE SDGETD YES, GET THE DATA BITA #1 BUSY? BNE SDLOOP YES, WAIT FOR IT SDFINI BSR WNBUSY WAIT FOR READY BITB #$1C RNF, CRC, LD ERRORS RTS AND QUIT SDGETD LDA DATREG GET DATA STA 0,X+ SAVE IT DECB DECREMENT COUNTER BNE SDLOOP REPEAT UNTIL DONE BRA SDFINI * WAIT LOOP TO STABILIZE COMMAND REGISTER WAIT BSR WAIT1 WAIT1 BSR WAIT2 WAIT2 BSR WAIT3 WAIT3 RTS * WNBUSY - WAIT FOR NOT BUSY WNBUSY BSR WAIT LDB STAREG CHECK STATUS BITB #1 CHECK BUSY FLAG BNE WNBUSY WAIT IF STILL BUSY RTS ELSE RETURN WITH B=STATUS **** PREVIOUS PART MUST BE ON FIRST SECTOR **** * MAIN READ LOOP MLOOP BSR GETBYT GET A BYTE CMPA #2 DATA FOLLOWS? BEQ RDDATA YES, GO READ IT CMPA #$16 ADDRESS FOLLOWS? BEQ RDADDR YES, GO GET IT BRA MLOOP ELSE REPEAT * GETBYT ROUTINE - GET NEXT BYTE FROM FILE GETBYT LDB DATPTR,PCR GET DATA POINTER BNE GETBY1 OK TO CONTINUE IF NOT 0 LBSR GETSEC ELSE GET SECTOR BEQ BYTEOK IF NO ERROR BITB #$10 ON ERROR, CHECK IF REC NOT FOUND LBEQ ERROR ANYTHING ELSE IS AN ERROR COM DUBLFL,PCR COMPLEMENT DOUBLE FLAG LDA #$0B STA CMDREG RESTORE, LOAD HEAD, SLOW STEP BSR WNBUSY WAIT FOR COMPLETION LBSR GETSEC AND TRY AGAIN BNE ERROR QUIT ON ANY ERRORS BYTEOK LDB #4 STB DATPTR,PCR NEXT BYTE IS BYTE 4 GETBY1 LEAX SBBUFF,PCR POINT TO SBBUFF ABX POINT TO BYTE INC DATPTR,PCR BUMP POINTER LDA 0,X GET BYTE RTS RETURN WITH BYTE IN A AND CC SET * RDDATA - READ DATA FROM SECTOR RDDATA BSR GETBYT PSHS A BSR GETBYT TFR A,B PULS A GET LOAD ADDRESS TFR D,Y INTO Y REG BSR GETBYT GET COUNT BEQ ERROR IF COUNT = 0 TFR A,B RDMEM PSHS B SAVE COUNTER BSR GETBYT GET NEXT BYTE PULS B STA 0,Y+ SAVE IT DECB DECREMENT COUNTER BNE RDMEM REPEAT UNTIL DONE BRA MLOOP GO LOOK FOR MORE * RDADDR - READ ADDRESS FROM SECTOR RDADDR BSR GETBYT STA TRADDR,PCR BSR GETBYT STA TRADDR+1,PCR BRA MLOOP GO GET MORE * WHEN DONE, CHECK TRANSFER ADDR AND GO DO IF OK DONE LEAS 4,S REMOVE TWO RETURN ADDR FROM STACK LDX TRADDR,PCR GET TRANSFER ADDRESS CMPX #$FFFF ANYTHING THERE? BEQ ERROR NO JMP 0,X ELSE GO TO PROGRAM * DOUBLE DENSITY READ ROUTINE READDD LDA #$E0 POINT DP TO I/O PAGE TFR A,DP LDX BUFFAD,PCR POINT TO BUFFER CLRB COUNTER = 256 LDA #$8E READ DD COMMAND STA