NAM WINCHESTER DISK DRIVER * FOR SWTPC/6809 ROM ADDRESS $E800 OPT PAGE PAG * WINCHESTER DISK DRIVER FOR WD1002-HD0 CONTROLLER * * COPYRIGHT 1984 PERIPHERAL TECHNOLOGY * ALL RIGHTS RESERVED * * LAST CHANGE 5/25/85 for the WD1002 Origional Code * LAST CHANGE 10/22/21 14:32 * Rewritten 9/1/21 for IDE register layout * Changed 9/7/21 to move boot command code here * Modernized for IDE/SD card used with PT-HDO-IDE adapter. * PT-HDO board converts the pin outs of the WD1002-HDO port to * IDE Pin outs. * for purpose of this driver, the IDE device is put in LBA mode. * This make for faster performance and a simpiler and faster driver. * Drive arangemnet for this rewrite is for 16MB partitions * You may format a smaller size, but the driver works in 16MB blocks * IDE/SD devices use 512 byte sector size and 16 bit transfer per read. * Because devices are cheap and the 6809 and FLEX are 8 bit * devices, half of the data is discarded. Only 8 of the 16 bits * is read/written. The extra complexity of hardware and the extra overhead * of software to block and unblock 512 byte sectors in not worth * the effort for the hardware changes or the loss in performance * to block/unblock 512 byte sectors to 256. * A $4 32GB SD card would support over 2000 16MB partitions. So there is * no reason to be concerned about the loss of half of the data capacity. * Offset is the number of 16MB offsets for the partition being accessed. * DRIVE DESCCRIPTORS - WINCHESTER * Don't delete any of the used space in the descriptor, the size must * be the same as the floppy desctiptor, which needs the extra space. ORG 0 DISK RMB 1 0=FLOPPY <>0 - WINCHESTER DRVNO RMB 1 HARDWARE DRIVE NUMBER - Must be 0 or 1 STEP RMB 1 Not used was STEP RATE INIT RMB 1 0=NOT INITIALIZED SHIFT RMB 1 Not used was <9 NUMBER OF SHIFTS >8 DIV HMASK RMB 1 Not used was HEAD MASK OFFSET RMB 2 Partition OFFSET - number of 16MB offsets DRVSIZ EQU * * ADDRESS DEFINITIONS FOR FLEX LOADER ORG $C000 Address where SECTOR 1 LOADED RMB 5 LTRKNO RMB 2 CYLINDER to load FLEX from LSECNO RMB 1 SECTOR TO LOAD FLEX FROM XFER RMB 2 TRANSFER ADDRESS LDPTR RMB 2 LOAD POINTR ADDRESS PNTR RMB 2 BUFFER NEXT READ POINTER LBUF EQU * LDATA EQU LBUF+4 DATEND EQU LBUF+256 PDATA EQU $F80C PTMON PRINT STRING STACK1 EQU $C6FF START ADDRESS OF STACK * FLOPPY DRIVER EQUATES DRVPTR EQU $DE20 DESCRIPTOR POINTER * PORT DEFINITION * BASADR EQU $E008 BASE ADDRESS PT69-5 BASADR EQU $E050 SLOT 5 SWTPC 6809 DATA EQU BASADR DATA REGISTER ERROR EQU BASADR+1 ERROR REGISTER WPC EQU BASADR+1 WRITE PRECOMP REGISTER SECNT EQU BASADR+2 SECTOR COUNT SECNO EQU BASADR+3 SECTOR NUMBER CYLLO EQU BASADR+4 CYLINDER NUMBER (LSB) CYLHI EQU BASADR+5 CYLINDER NUMBER (MSB) SDH EQU BASADR+6 SIZE/DRIVE/HEAD REGISTER STATUS EQU BASADR+7 STATUS REGISTER COMREG EQU BASADR+7 COMMAND REGISTER * COMMAND DEFINITIONS READCM EQU $20 READ COMMAND WRTCMD EQU $30 WRITE COMMAND PAG * ORG $F000 CONFLICTS WITH DMF2 IN SWTPC ORG $E800 FOR SWTPC * DISK JUMP TABLE READ JMP READ1 WRITE JMP WRITE1 VERIFY JMP VER1 RESTOR JMP REST1 DRVSEL JMP DRVSL1 CDRRDY JMP CDRR1 QDRRDY JMP CDRR1 DCOLDS JMP DCOLD DWARMS JMP RTS IBOOT JMP WBOOT Boot from IDE *********************** * READ SECTOR COMMAND * *********************** * Entry * X - Address to place sector - 256 bytes * A - Sector Number * B - Track Number * Exit * X,A May be destroyed * B - Error Code * Z - 1 if no error * Z - 0 if an error READ1 PSHS Y JSR TSKSET SET UP TASK REGISTERS LDA #READCM GET READ COMMAND STA COMREG ISSUE COMMAND TO WD1002-HD0 READ2 LDA STATUS READ STATUS ASLA WAIT FOR BUSY TO CLEAR BCS READ2 LDY #16 READ3 LDA DATA LDB DATA STD 0,X++ LDA DATA LDB DATA STD 0,X++ LDA DATA LDB DATA STD 0,X++ LDA DATA LDB DATA STD 0,X++ LDA DATA LDB DATA STD 0,X++ LDA DATA LDB DATA STD 0,X++ LDA DATA LDB DATA STD 0,X++ LDA DATA LDB DATA STD 0,X++ LEAY -1,Y BNE READ3 LDA STATUS BITA #1 BEQ READ4 LDB #$10 SEC PULS Y,PC READ4 CLRB PULS Y,PC ***************** * WRITE COMMAND * ***************** * * X - Address of 256 bytes to be written * A - Track Number * B - Sector Number * EXIT * X,A may be destroyed * B - Error Code - 0=None * Z - Z=1 if no error * Z - Z=0 if error WRITE1 PSHS Y JSR TSKSET SET UP TASK REGISTERS LDA #WRTCMD GET WRITE COMMAND STA COMREG ISSUE TO WD1002-HDO WRITE6 LDA STATUS READ STATUS ASLA SHIFT BUSSY BIT TO CARRY BCS WRITE6 LOOP UNTIL NOT BUSY LDY #16 INIT COUNTER WRITE2 LDD 0,X++ STA DATA STB DATA LDD 0,X++ STA DATA STB DATA LDD 0,X++ STA DATA STB DATA LDD 0,X++ STA DATA STB DATA LDD 0,X++ STA DATA STB DATA LDD 0,X++ STA DATA STB DATA LDD 0,X++ STA DATA STB DATA LDD 0,X++ STA DATA STB DATA LEAY -1,Y BNE WRITE2 WRITE3 LDA STATUS BITA #$80 BNE WRITE3 BITA #1 BNE WRITE4 CLRB PULS Y,PC WRITE4 LDB ERROR SEC PULS Y,PC ********************** * VERIFY DISK DRIVER * ********************** * * The sector just written is to be verified. * This routine only called immediately after a write * * Entry * No parameters are given * Exit * X,A may be destroyed * B - Error code - 0=none * warning warning Will Robinson ------------------------------- * ---------- IT PROBABLY DOESN'T WORK ------------------- * UNLESS TO READ COMMAND CAN BE CANCELED THIS ROUTINE * PROBABLY LEAVES THE DRIVE IN A BUSY STATE UNTIL * 256 READS CAN BE PERFORMED ON THE DATA REGISTER VER1 CLRB --------------------------- EXIT - ROUTINE NOT VIABLE RTS LDA #READCM STA COMREG VER2 LDA STATUS BITA #$80 BNE VER2 BITA #1 BNE VER3 CLRB RTS VER3 LDB ERROR SEC RTS RTS *********************** * TASK SET-UP ROUTINE * *********************** * INPUT D=LOGICAL SECTOR NUMBER * * * Driver currently supports only 256 partitions * * OUTPUT IDE registers set * TSKSET STAB SECNO Set LSB of LSN STAA CYLLO Set MSB of LSN LDY DRVPTR point to descriptor LDAA OFFSET+1,Y get parttion number STAA CYLHI LDAA DRVNO,Y Get drive Number LSLA Put in corrent bit position LSLA LSLA LSLA ORA #$E0 Drive number + LBA Mode STAA SDH Select Drive and LBA LDA #1 SET FOR ONE SECTOR READ/WRITE STA SECNT SET IDE REGISTER RTS ******************* * RESTORE COMMAND * ******************* * * Drive in the FCB address (3,X contains drive number) should be selected * before the RESTORE is performed. * * Entry * X - FCB address - 3,X contains drive number * Exit * X,A - may be destroyed * B - Error code - 0=no error * While there is nothing to do for a modern drive, FLEX * expects DRIVE SELECT to be called by this routine. It is therefore * necessary to set the DRVPTR pointer with this routine. REST1 LDA 3,X GET DRIVE NUMBER LDB #DRVSIZ GET DESCRIPTOR SIZE MUL CALCULATE OFFSET LDX #$DE22 DRVBEG ABX STX DRVPTR CLRB No error RTS ******************** * DRIVE READY TEST * ******************** * * Drive number found in the FCB should be checked for ready * * Entry * X - FCB address - 3,X contains drive number * Exit * X,A - may be destroyed * B - Error code - 0=no error CDRR1 LDA STATUS BITA #$40 Drive ready bit BEQ CDRR2 branch for no ready CLRB clear error flag RTS CDRR2 LDB #$80 set not ready error SEC RTS ******************** * COLD START - INIT* ******************** * * Do any driver initialization here when the system is first booted. * * Entry * No parameters are given * Exit * A,B,X,Y,U may be destroyed * No exit code for this routine. Simply issue RTS DCOLD LDA STATUS Get status BITA #$80 Test Busy bit BNE DCOLD loop until ready * This would be a good place to insert time out code * and print a message if no drive plugged in RTS ************************ * DRIVE SELECT ROUTINE * ************************ * * Drive specified is selected * * Entry * X - FCB address - (3,X contains drive number) * Exit * X,A may be destroyed * B - $0F error code for non-existant drive * Z - 1=error 0=no error * C - 0=error 1=error * * For this driver, it means the DRVPTR must be set so * READ/WRITE works on the correct drive. * DRVPTR IS TO BE SET BY "DISK.TXT" DRIVER THAT * IS LOCATED IN SPACE RESERVER FOR FLOPPY DRIVERS * IN FLEX. * * The drive is selected during the Task setup routine * There is nothing to do to the drive here * THIS ENTRY POINT IS MAINTAINED SO THAT * IF AT SOME POINT IN THE FUTURE SOMETHING NEEDS * TO BE DONE, THE ENTRY POINT ALREADY EXISTS. DRVSL1 CLRB CLEAR ERROR CODE RTS *---------------------------------------------------------- * Boot from IDE * * This boot no longer uses a Bootstrap loader in sector 1. * The only information on sector 1 is the link to the OS (FLEX) *********************** * 'W' BOOT WINCHESTER * *********************** WBOOT LDS #STACK1 LDX #DESCRIP STX DRVPTR * JSR DRVSEL * LDA STATUS READ STATUS REGISTER * BITA #$40 CHECK READY BIT * BNE WBOOT2 * LDX #MSGWN1 * JSR [PDATA] *WBOOT1 LDA STATUS * BITA #$40 * BEQ WBOOT1 *WBOOT2 JSR RESTOR LDD #$0001 BOOT SECTOR LDX #$C000 LOAD ADDRESS JSR READ TSTB BEQ WBOOT3 NO ERROR - CHECK FOR LINK PRESENT LDX #MSGWN2 JSR [PDATA] JMP [$F800] * CHECK TO SEE IF DISK IS LINKED WBOOT3 LDD LTRKNO GET LINK ADDRES CMPD #0 0 = NOT LINKED BNE LDFLEX LOAD FLEX LDX #MSGWN3 NOT LINKED MESSAGE JSR [PDATA] JMP [$F800] JUMP TO PTMON MSGWN1 FCB $D,$A,$A FCC /WAITING FOR DISK TO SPIN UP/ FCB 4 MSGWN2 FCB $D,$A FCC /ERROR READING BOOT SECTOR/ FCB $D,$A FCB 4 MSGWN3 FCB $D,$A FCC /NOT LINKED/ FCB $D,$A FCB 4 * DRIVE DESCRIPTOR (FOR BOOT ONLY) DESCRIP FCB 1 WINCHESTER FCB 0 HARDWARE DRIVE NUMBER FCB 0 FCB 0 FCB 0 FCB 0 FDB 0 TRACK OFFSET *--------------------------------------------------------------- * FLEX LOADER * * Load FLEX from the LINK in provided in sector 1 * DRIVE DESCRIPTOR LOADED HERE DESWIN FCB 1 WINCHESTER FCB 0 HARDWARE DRIVE NUMBER FCB 0 FCB 0 FCB 0 FCB 0 FDB 0 TRACK OFFSET * INITIALIZE TEMP STORAGE LDFLEX EQU * LDD #0 STD XFER STD LDPTR STD PNTR BRA START1 REDSEC LDD LTRKNO GET STARTING TRACK AND SECTOR RESEC1 LDX #LBUF JSR READ LBCS FAIL YES : RESTART LDX #LDATA POINT X AT BEGINNING OF DATA STX PNTR SAVE POINTER RTS * GET DATA BYTE AND ADVANCE POINTER READAT LDX PNTR GET POINTER CPX #DATEND END OF DATA? BEQ REDAT1 YES: READ NEXT SECTOR LDA 0,X+ NO: GET NEXT BYTE STX PNTR SAVE POINTER RTS * READ NEXT SECTOR REDAT1 LDX #LBUF LDD 0,X BSR RESEC1 READ NEXT SECTOR BRA READAT START1 LDX #DESWIN STX DRVPTR BSR REDSEC READ FIRST SECTOR LOAD BSR READAT GET DATA CMPA #$02 TEST FOR LOAD RECORD BEQ BINREC LDX #0 CMPX LBUF BNE LOAD * PROCESS TRANSFER RECORD CMPA #$16 TEST FOR TRANSFER RECORD BNE LOAD BSR READAT STA XFER BSR READAT STA XFER+1 LDX XFER JMP 0,X * BINARY FILE LOADER BINREC BSR READAT GET MSB OF ADDRESS STA LDPTR BSR READAT GET LSB OF ADDRESS STA LDPTR+1 BSR READAT GET CHARACTER COUNT TFR A,B TSTB BEQ LOAD LDY LDPTR GET LOAD ADDRESS PSHS B SAVE BYTE COUNT BSR READAT PULS B RESTORE BYTE COUNT BRA BLOAD0 BLOAD LDA 0,X+ BLOAD0 STA 0,Y+ CMPX #DATEND BEQ BLOAD2 BLOAD1 DECB BNE BLOAD STX PNTR BRA LOAD BLOAD2 PSHS B,Y LDX #LBUF LDD 0,X JSR RESEC1 LDX #LDATA PULS B,Y BRA BLOAD1 FAILMSG FCC /LOAD FAILED/ FCB 4 FAIL LDX #FAILMSG JSR [PDATA] JMP [$F800] RESTART PTMON END