Update from Hauke to resolve some relatively severe performance problems.
This commit is contained in:
parent
b15dc3ed17
commit
5e3349678a
|
@ -1,7 +1,7 @@
|
|||
/* $Id: iwm.s,v 1.1 1999/02/18 07:38:26 scottr Exp $ */
|
||||
/* $NetBSD: iwm.s,v 1.2 1999/03/27 05:45:19 scottr Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996-98 Hauke Fath. All rights reserved.
|
||||
* Copyright (c) 1996-99 Hauke Fath. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
|
@ -46,6 +46,11 @@
|
|||
* would be lost.
|
||||
* The old status register content is stored on the stack.
|
||||
*
|
||||
* o We run at spl4 to give the NMI switch a chance. All currently
|
||||
* supported machines have no interrupt sources > 4 (SSC) -- the
|
||||
* Q700 interrupt levels can be shifted around in A/UX mode,
|
||||
* but we're not there, yet.
|
||||
*
|
||||
* o As a special case iwmReadSectHdr() must run with interrupts disabled
|
||||
* (it transfers data). Depending on the needs of the caller, it
|
||||
* may be necessary to block interrupts after completion of the routine
|
||||
|
@ -60,7 +65,7 @@
|
|||
|
||||
#include <m68k/asm.h>
|
||||
|
||||
#include "iwm_regs.s"
|
||||
#include <mac68k/obio/iwmreg.h>
|
||||
|
||||
#define USE_DELAY 0 /* "1" bombs for unknown reasons */
|
||||
|
||||
|
@ -69,8 +74,8 @@
|
|||
* References to global name space
|
||||
*/
|
||||
.extern _TimeDBRA | in mac68k/macrom.c
|
||||
.extern _IWMBase | in mac68k/machdep.c
|
||||
.extern _VIA1Base |
|
||||
.extern _VIA1Base | in mac68k/machdep.c
|
||||
.extern _IWMBase | in iwm_fd.c
|
||||
|
||||
|
||||
.data
|
||||
|
@ -205,13 +210,8 @@ quDone:
|
|||
ENTRY(iwmReadSectHdr)
|
||||
link a6,#0
|
||||
moveml d1-d5/a0-a4,sp@-
|
||||
movel _IWMBase,a0
|
||||
movel _Via1Base,a1
|
||||
|
||||
movel a6@(0x08),a4 | Get param block address
|
||||
|
||||
bsr readSectHdr
|
||||
|
||||
moveml sp@+,d1-d5/a0-a4
|
||||
unlk a6
|
||||
rts
|
||||
|
@ -251,7 +251,7 @@ ENTRY(iwmInit)
|
|||
tstb a0@(q6H)
|
||||
andb a0@(q7L),d0 | status register
|
||||
tstb a0@(q6L)
|
||||
cmpib #0x17,d0 | all is well??
|
||||
cmpib #iwmMode,d0 | all is well??
|
||||
beq initDone
|
||||
|
||||
/*
|
||||
|
@ -270,9 +270,9 @@ initLp:
|
|||
bclr #5,d0 | Reset bit 5 and set Z flag
|
||||
| according to previous state
|
||||
bne initLp | Loop if drive still on
|
||||
cmpib #0x17,d0
|
||||
cmpib #iwmMode,d0
|
||||
beq initDone
|
||||
moveb #0x17,a0@(q7H) | Init IWM
|
||||
moveb #iwmMode,a0@(q7H) | Init IWM
|
||||
tstb a0@(q7L)
|
||||
bra initLp
|
||||
|
||||
|
@ -644,49 +644,55 @@ stDone:
|
|||
* Add a branch for Verify (compare to buffer)
|
||||
* Understand and document the checksum algorithm!
|
||||
*
|
||||
* XXX make "sizeof cylCache_t" a symbolic constant
|
||||
*
|
||||
* Parameters: fp+08 l Address of sector data buffer (512 bytes)
|
||||
* fp+12 l Address of sector header struct (I/O)
|
||||
* fp+16 l Address of cache buffer ptr array
|
||||
* Returns: d0 result code
|
||||
* Local: fp-2 w CPU status register
|
||||
* fp-3 b side,
|
||||
* fp-4 b track,
|
||||
* fp-5 b sector wanted
|
||||
* fp-6 b retry count
|
||||
* fp-7 b sector read
|
||||
*/
|
||||
ENTRY(iwmReadSector)
|
||||
link a6,#-6
|
||||
link a6,#-8
|
||||
moveml d1-d7/a0-a5,sp@-
|
||||
|
||||
movel _IWMBase,a0
|
||||
movel _Via1Base,a1
|
||||
movel _Via1Base,a1
|
||||
movel a6@(o_hdr),a4 | Addr of sector header struct
|
||||
|
||||
movel a6@(12),a4 | Addr of sector header struct
|
||||
|
||||
moveb a4@(0),a6@(-3) | Save side bit,
|
||||
moveb a4@(1),a6@(-4) | track#,
|
||||
/* moveb a4@(2),a6@(-5) | sector# */
|
||||
moveb a4@+,a6@(-3) | Save side bit,
|
||||
moveb a4@+,a6@(-4) | track#,
|
||||
moveb a4@,a6@(-5) | sector#
|
||||
moveb #2*maxGCRSectors,a6@(-6) | Max. retry count
|
||||
|
||||
movew sr,a6@(-2) | Save CPU status register
|
||||
oriw #0x0700,sr | Block all interrupts
|
||||
oriw #0x0600,sr | Block all interrupts
|
||||
|
||||
rsNextSect:
|
||||
movel a6@(o_hdr),a4 | Addr of sector header struct
|
||||
bsr readSectHdr | Get next available SECTOR header
|
||||
bne rsDone | Return if error
|
||||
|
||||
/*
|
||||
* Is this the right track & side? If not, return with error
|
||||
*/
|
||||
movel a6@(12),a4 | Sector header struct
|
||||
movel a6@(o_hdr),a4 | Sector header struct
|
||||
|
||||
moveb a4@(0),d1 | Get actual side
|
||||
moveb a4@(o_side),d1 | Get actual side
|
||||
lsrb #3,d1 | "Normalize" side bit (to bit 0)
|
||||
andb #1,d1
|
||||
moveb a6@(-3),d2 | Get wanted side
|
||||
eorb d1,d2 | Compare side bits
|
||||
bne rsSeekErr | Should be equal!
|
||||
|
||||
moveb a6@(-4),d1 | Get wanted track#
|
||||
cmpb a4@(1),d1 | Compare to the read header
|
||||
moveb a6@(-4),d1 | Get track# we want
|
||||
cmpb a4@(o_track),d1 | Compare to the header we've read
|
||||
beq rsGetSect
|
||||
|
||||
|
||||
rsSeekErr:
|
||||
moveq #seekErr,d0 | Wrong track or side found
|
||||
bra rsDone
|
||||
|
@ -694,13 +700,14 @@ rsSeekErr:
|
|||
/*
|
||||
* Check for sector data lead-in 'D5 AA AD'
|
||||
* Registers:
|
||||
* a0 points to data register of IWM
|
||||
* a2 points to 'diskTo' translation table
|
||||
* a0 points to data register of IWM as set up by readSectHdr
|
||||
* a2 points to 'diskTo' translation table
|
||||
* a4 points to tags buffer
|
||||
*/
|
||||
rsGetSect:
|
||||
moveb a4@(2),a6@(-7) | save sector number
|
||||
lea a4@(3),a4 | Beginning of tag buffer
|
||||
moveq #50,d3 | Max. retries to seek
|
||||
moveq #50,d3 | Max. retries for sector lookup
|
||||
rsLeadIn:
|
||||
lea dataLeadIn,a3 | Sector data lead-in
|
||||
moveq #0x03,d4 | is 3 bytes long
|
||||
|
@ -716,6 +723,7 @@ rsLI2:
|
|||
bne rsLeadIn | If ne restart scan
|
||||
subqw #1,d4
|
||||
bne rsLI1
|
||||
|
||||
/*
|
||||
* We have found the lead-in. Now get the 12 tag bytes.
|
||||
* (We leave a3 pointing to 'dataLeadOut' for later.)
|
||||
|
@ -775,15 +783,27 @@ rsTagNyb4:
|
|||
|
||||
subqw #3,d4 | Update byte counter (four 6&2 encoded
|
||||
bpl rsTags | disk bytes make three data bytes).
|
||||
|
||||
/*
|
||||
* Jetzt sind wir hier...
|
||||
* ...und Thomas D. hat noch was zu sagen...
|
||||
*
|
||||
* We begin to read in the actual sector data.
|
||||
* Compare sector # to what we wanted: If it matches, read directly
|
||||
* to buffer, else read to track cache.
|
||||
*/
|
||||
movel a6@(8),a4 | Sector data buffer
|
||||
movew #0x01FE,d4 | Loop counter
|
||||
|
||||
moveq #0,d1 | Clear d1.L
|
||||
moveb a6@(-7),d1 | Get sector# we have read
|
||||
cmpb a6@(-5),d1 | Compare to the sector# we want
|
||||
bne rsToCache
|
||||
movel a6@(o_buf),a4 | Sector data buffer
|
||||
bra rsData
|
||||
rsToCache:
|
||||
movel a6@(o_rslots),a4 | Base address of slot array
|
||||
lslw #3,d1 | sizeof cylCacheSlot_t is 8 bytes
|
||||
movel #-1,a4@(o_valid,d1)
|
||||
movel a4@(o_secbuf,d1),a4 | and get its buffer ptr
|
||||
rsData:
|
||||
rsDatNyb1:
|
||||
moveb a0@,d3 | Get 2 bit nibbles
|
||||
|
@ -884,7 +904,6 @@ rsBadDBtSlp:
|
|||
moveq #badDBtSlp,d0 | One of the data mark bit slip
|
||||
bra rsDone | nibbles was incorrect
|
||||
|
||||
|
||||
/*
|
||||
* We have gotten the checksums allright, now look for the
|
||||
* sector data lead-out 'DE AA'
|
||||
|
@ -900,13 +919,36 @@ rsLdOut1:
|
|||
bne rsBadDBtSlp | Fault!
|
||||
dbra d4,rsLdOut1
|
||||
moveq #0,d0 | OK.
|
||||
|
||||
/*
|
||||
* See if we got the sector we wanted. If not, and no error
|
||||
* occurred, mark buffer valid. Else ignore the sector.
|
||||
* Then, read on.
|
||||
*/
|
||||
rsDone:
|
||||
movel a6@(o_hdr),a4 | Addr of sector header struct
|
||||
moveb a4@(o_sector),d1 | Get # of sector we have just read
|
||||
cmpb a6@(-5),d1 | Compare to the sector we want
|
||||
beq rsAllDone
|
||||
|
||||
tstb d0 | Any error? Simply ignore data
|
||||
beq rsBufValid
|
||||
lslw #3,d1 | sizeof cylCacheSlot_t is 8 bytes
|
||||
movel a6@(o_rslots),a4
|
||||
clrl a4@(o_valid,d1) | Mark buffer content "invalid"
|
||||
|
||||
rsBufValid:
|
||||
subqb #1,a6@(-6) | max. retries
|
||||
bne rsNextSect
|
||||
| Sector not found, but
|
||||
tstb d0 | don't set error code if we
|
||||
bne rsAllDone | already have one.
|
||||
moveq #sectNFErr,d0
|
||||
rsAllDone:
|
||||
movew a6@(-2),sr | Restore interrupt mask
|
||||
moveml sp@+,d1-d7/a0-a5
|
||||
unlk a6
|
||||
rts
|
||||
|
||||
|
||||
rts
|
||||
|
||||
|
||||
/*
|
||||
|
@ -915,40 +957,45 @@ rsDone:
|
|||
* TODO: Poll SCC as long as interrupts are disabled (see top comment)
|
||||
* Understand and document the checksum algorithm!
|
||||
*
|
||||
* Parameters: fp+8 l Address of sector data buffer (512 bytes)
|
||||
* fp+12 l Address of sector header struct (I/O)
|
||||
* XXX Use registers more efficiently
|
||||
*
|
||||
* Parameters: fp+8 l Address of sector header struct (I/O)
|
||||
* fp+12 l Address of cache buffer ptr array
|
||||
* Returns: d0 result code
|
||||
*
|
||||
* Local: fp-2 w CPU status register
|
||||
* fp-3 b side,
|
||||
* fp-4 b track,
|
||||
* fp-5 b sector wanted
|
||||
* fp-6 b retry count
|
||||
* fp-10 b current slot
|
||||
*/
|
||||
ENTRY(iwmWriteSector)
|
||||
link a6,#-6
|
||||
link a6,#-10
|
||||
moveml d1-d7/a0-a5,sp@-
|
||||
|
||||
movel _IWMBase,a0
|
||||
movel _Via1Base,a1
|
||||
movel _Via1Base,a1
|
||||
movel a6@(o_hdr),a4 | Addr of sector header struct
|
||||
|
||||
movel a6@(12),a4 | Addr of sector header struct
|
||||
|
||||
moveb a4@(0),a6@(-3) | Save side bit,
|
||||
moveb a4@(1),a6@(-4) | track#,
|
||||
moveb a4@(2),a6@(-5) | sector#
|
||||
moveb a4@+,a6@(-3) | Save side bit,
|
||||
moveb a4@+,a6@(-4) | track#,
|
||||
moveb a4@,a6@(-5) | sector#
|
||||
moveb #maxGCRSectors,a6@(-6) | Max. retry count
|
||||
|
||||
movew sr,a6@(-2) | Save CPU status register
|
||||
oriw #0x0700,sr | Block all interrupts
|
||||
oriw #0x0600,sr | Block all interrupts
|
||||
|
||||
wsNextSect:
|
||||
movel a6@(o_hdr),a4
|
||||
bsr readSectHdr | Get next available sector header
|
||||
bne wsDone | Return if error
|
||||
bne wsAllDone | Return if error
|
||||
|
||||
/*
|
||||
* Is this the right track & side? If not, return with error
|
||||
*/
|
||||
movel a6@(12),a4 | Sector header struct
|
||||
movel a6@(o_hdr),a4 | Sector header struct
|
||||
|
||||
moveb a4@(0),d1 | Get side#
|
||||
moveb a4@(o_side),d1 | Get side#
|
||||
lsrb #3,d1 | "Normalize" side bit...
|
||||
andb #1,d1
|
||||
moveb a6@(-3),d2 | Get wanted side
|
||||
|
@ -956,26 +1003,39 @@ ENTRY(iwmWriteSector)
|
|||
bne wsSeekErr
|
||||
|
||||
moveb a6@(-4),d1 | Get wanted track#
|
||||
cmpb a4@(1),d1 | Compare to the read header
|
||||
cmpb a4@(o_track),d1 | Compare to the read header
|
||||
beq wsCompSect
|
||||
|
||||
wsSeekErr:
|
||||
moveq #seekErr,d0 | Wrong track or side
|
||||
bra wsDone
|
||||
|
||||
bra wsAllDone
|
||||
|
||||
/*
|
||||
* Are we at the right sector? If not, we return with zero flag
|
||||
* cleared, but d0 = 0.
|
||||
* Look up the current sector number in the cache.
|
||||
* If the buffer is dirty ("valid"), write it to disk. If not,
|
||||
* loop over all the slots and return if all of them are clean.
|
||||
*
|
||||
* Alternatively, we could decrement a "dirty sectors" counter here.
|
||||
*/
|
||||
wsCompSect:
|
||||
moveq #0,d1 | Clear register
|
||||
moveb a4@(o_sector),d1 | get the # of header read
|
||||
lslw #3,d1 | sizeof cylCacheSlot_t is 8 bytes
|
||||
movel a6@(o_wslots),a4
|
||||
tstl a4@(o_valid,d1) | Sector dirty?
|
||||
bne wsBufDirty
|
||||
|
||||
moveb a6@(-5),d1 | Get wanted sector#
|
||||
cmpb a4@(2),d1 | Compare to the read header
|
||||
bne wsDone
|
||||
|
||||
moveq #maxGCRSectors-1,d2 | Any dirty sectors left?
|
||||
wsChkDty:
|
||||
movew d2,d1
|
||||
lslw #3,d1 | sizeof cylCacheSlot_t is 8 bytes
|
||||
tstl a4@(o_valid,d1)
|
||||
bne wsNextSect | Sector dirty?
|
||||
dbra d2,wsChkDty
|
||||
|
||||
bra wsAllDone | We are through with this track.
|
||||
|
||||
|
||||
/*
|
||||
* Write sync pattern and sector data lead-in 'D5 AA'. The
|
||||
* missing 'AD' is made up by piping 0x0B through the nibble
|
||||
|
@ -988,15 +1048,19 @@ wsCompSect:
|
|||
* and write subsequent bytes to q6H.
|
||||
*
|
||||
* Registers:
|
||||
* a0 Data register of IWM
|
||||
* a0 IWM base address (later: data register)
|
||||
* a1 Via1Base
|
||||
* a2 IWM handshake register
|
||||
* a3 data (tags buffer, data buffer)
|
||||
* a4 Sync pattern, 'toDisk' translation table
|
||||
* a4 Sync pattern, 'toDisk' translation table
|
||||
*/
|
||||
wsBufDirty:
|
||||
movel _IWMBase,a0
|
||||
lea a4@(0,d1),a3
|
||||
movel a3,a6@(-10) | Save ptr to current slot
|
||||
tstb a0@(q6H) | Enable writing to disk
|
||||
lea a4@(3),a3 | Point a3 to tags buffer
|
||||
movel a6@(o_hdr),a4 | Sector header struct
|
||||
lea a4@(o_Tags),a3 | Point a3 to tags buffer
|
||||
lea syncPattern,a4
|
||||
|
||||
moveb a4@+,a0@(q7H) | Write first sync byte
|
||||
|
@ -1052,8 +1116,9 @@ wsLI2:
|
|||
*
|
||||
* c) adds up three 8 bit checksums, one for each of the bytes written.
|
||||
*/
|
||||
wsSD1:
|
||||
movel a6@(8),a3 | Start of sector data buffer
|
||||
wsSD1:
|
||||
movel a6@(-10),a3 | Get ptr to current slot
|
||||
movel a3@(o_secbuf),a3 | Get start of sector data buffer
|
||||
|
||||
wsData:
|
||||
addxb d2,d7
|
||||
|
@ -1100,6 +1165,7 @@ wsRDY04:
|
|||
tstb a2@ | IWM ready?
|
||||
bpl wsRDY04
|
||||
moveb a4@(0,d2),a0@ | Translate nibble and write
|
||||
|
||||
/*
|
||||
* XXX We have a classic off-by-one error here: the last access
|
||||
* reaches beyond the data buffer which bombs with memory
|
||||
|
@ -1185,6 +1251,22 @@ wsNoErr:
|
|||
tstb a0@(0x0200) | q7L -- Write OFF
|
||||
|
||||
wsDone:
|
||||
tstb d0 | Any error? Simply retry
|
||||
bne wsBufInvalid
|
||||
|
||||
movel a6@(-10),a4 | Else, get ptr to current slot
|
||||
clrl a4@(o_valid) | Mark current buffer "clean"
|
||||
bra wsNextSect
|
||||
|
||||
wsBufInvalid:
|
||||
subqb #1,a6@(-6) | retries
|
||||
bne wsNextSect
|
||||
| Sector not found, but
|
||||
tstb d0 | don't set error code if we
|
||||
bne wsAllDone | already have one.
|
||||
moveq #sectNFErr,d0
|
||||
|
||||
wsAllDone:
|
||||
movew a6@(-2),sr | Restore interrupt mask
|
||||
moveml sp@+,d1-d7/a0-a5
|
||||
unlk a6
|
||||
|
@ -1324,10 +1406,9 @@ driveCmd:
|
|||
*
|
||||
* TODO: Poll SCC as long as interrupts are disabled.
|
||||
*
|
||||
* Parameters: a0 IWMBase
|
||||
* a1 VIABase
|
||||
* a4 sectorHdr_t address
|
||||
* Parameters: a4 sectorHdr_t address
|
||||
* Returns: d0 result code
|
||||
* Uses: d0-d4, a0, a2-a4
|
||||
*/
|
||||
readSectHdr:
|
||||
moveq #3,d4 | Read 3 chars from IWM for sync
|
||||
|
@ -1335,6 +1416,7 @@ readSectHdr:
|
|||
moveq #0,d2 | Clear scratch regs
|
||||
moveq #0,d1
|
||||
moveq #0,d0
|
||||
movel _IWMBase,a0 | IWM base address
|
||||
|
||||
tstb a0@(q7L)
|
||||
lea a0@(q6L),a0 | IWM data register
|
||||
|
@ -1360,7 +1442,7 @@ shLeadIn:
|
|||
moveq #0x03,d4 | is 3 bytes long
|
||||
shLI1:
|
||||
moveb a0@,d2 | Get next byte
|
||||
bpl shLI1
|
||||
bpl shLI1 | No char at IWM, repeat read
|
||||
dbra d3,shLI2
|
||||
moveq #noAdrMkErr,d0 | Can't find an address mark
|
||||
bra shDone
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,4 +1,4 @@
|
|||
/* $Id: iwm_fdvar.h,v 1.2 1999/02/18 07:50:54 scottr Exp $ */
|
||||
/* $NetBSD: iwm_fdvar.h,v 1.3 1999/03/27 05:45:20 scottr Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1997, 1998 Hauke Fath. All rights reserved.
|
||||
|
@ -32,20 +32,20 @@
|
|||
** Constants
|
||||
**/
|
||||
|
||||
/* Number of attachable drives */
|
||||
#define IWM_MAX_DRIVE 2
|
||||
enum {
|
||||
IWM_MAX_DRIVE = 2, /* Attachable drives */
|
||||
IWM_GCR_DISK_ZONES = 5, /* Zones on GCR disk */
|
||||
IWM_MAX_GCR_SECTORS = 12, /* Max. sectors per GCR track */
|
||||
IWM_MAX_FLOPPY_SECT = 50, /* Larger than the highest sector */
|
||||
/* number likely to occur */
|
||||
};
|
||||
|
||||
/* Number of zones on GCR disk */
|
||||
#define IWM_GCR_DISK_ZONES 5
|
||||
|
||||
/* Larger than the highest sector number likely */
|
||||
#define IWM_MAX_FLOPPY_SECT 50
|
||||
|
||||
/* Physical track format codes */
|
||||
enum {
|
||||
IWM_GCR, /* Apple's Group Code Recording format */
|
||||
IWM_MFM_DD, /* Standard MFM on DD disk (250 KBit/s) */
|
||||
IWM_MFM_HD /* Standard MFM on HD disk (500 KBit/s) */
|
||||
IWM_GCR, /* Apple's Group Code Recording format */
|
||||
IWM_MFM_DD, /* Standard MFM on DD disk (250 KBit/s) */
|
||||
IWM_MFM_HD /* Standard MFM on HD disk (500 KBit/s) */
|
||||
};
|
||||
|
||||
/* Drive softc flags */
|
||||
|
@ -61,6 +61,12 @@ enum {
|
|||
IWM_SEEK_VERIFY
|
||||
};
|
||||
|
||||
/* I/O direction */
|
||||
enum {
|
||||
IWM_WRITE = 0,
|
||||
IWM_READ
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
** Data Types
|
||||
|
@ -73,15 +79,15 @@ enum {
|
|||
* tenaciously to the trailing edge of technology...
|
||||
*/
|
||||
struct fdInfo {
|
||||
short heads; /* # of heads the drive has */
|
||||
short tracks; /* # of tracks per side (cyl's) */
|
||||
short sectorSize; /* Bytes per sector */
|
||||
short secPerTrack; /* fake */
|
||||
short secPerCyl; /* fake */
|
||||
short secPerDisk; /* # of sectors per __disk__ */
|
||||
short stepRate; /* in ms (is a software delay) */
|
||||
short interleave; /* Sector interleave */
|
||||
short physFormat; /* GCR, MFM DD, MFM HD */
|
||||
short heads; /* # of heads the drive has */
|
||||
short tracks; /* # of tracks per side (cyl's) */
|
||||
short sectorSize; /* Bytes per sector */
|
||||
short secPerTrack; /* fake */
|
||||
short secPerCyl; /* fake */
|
||||
short secPerDisk; /* # of sectors per __disk__ */
|
||||
short stepRate; /* in ms (is a software delay) */
|
||||
short interleave; /* Sector interleave */
|
||||
short physFormat; /* GCR, MFM DD, MFM HD */
|
||||
char *description;
|
||||
};
|
||||
typedef struct fdInfo fdInfo_t;
|
||||
|
@ -94,7 +100,7 @@ struct diskPosition {
|
|||
short oldTrack;
|
||||
short side;
|
||||
short sector;
|
||||
short maxSect; /* Highest sector # for this track */
|
||||
short maxSect; /* Highest sector # for this track */
|
||||
};
|
||||
typedef struct diskPosition diskPosition_t;
|
||||
|
||||
|
@ -102,7 +108,7 @@ typedef struct diskPosition diskPosition_t;
|
|||
* Zone recording scheme (per disk surface/head)
|
||||
*/
|
||||
struct diskZone {
|
||||
short tracks; /* # of tracks per zone */
|
||||
short tracks; /* # of tracks per zone */
|
||||
short sectPerTrack;
|
||||
short firstBlock;
|
||||
short lastBlock;
|
||||
|
@ -113,8 +119,8 @@ typedef struct diskZone diskZone_t;
|
|||
* Arguments passed between iwmAttach() and the fd probe routines.
|
||||
*/
|
||||
struct iwmAttachArgs {
|
||||
fdInfo_t *driveType; /* Default drive parameters */
|
||||
short unit; /* Current drive # */
|
||||
fdInfo_t *driveType; /* Default drive parameters */
|
||||
short unit; /* Current drive # */
|
||||
};
|
||||
typedef struct iwmAttachArgs iwmAttachArgs_t;
|
||||
|
||||
|
@ -124,25 +130,43 @@ typedef struct iwmAttachArgs iwmAttachArgs_t;
|
|||
*
|
||||
*/
|
||||
struct fd_softc {
|
||||
struct device devInfo; /* generic device info */
|
||||
struct disk diskInfo; /* generic disk info */
|
||||
struct buf bufQueue; /* queue of buf's */
|
||||
struct device devInfo; /* generic device info */
|
||||
struct disk diskInfo; /* generic disk info */
|
||||
struct buf bufQueue; /* queue of buf's */
|
||||
|
||||
/* private stuff here */
|
||||
daddr_t startBlk; /* Starting block # */
|
||||
int bytesLeft; /* Bytes left to transfer */
|
||||
int bytesDone; /* Bytes transferred */
|
||||
/* errors & retries in current I/O job */
|
||||
int iwmErr; /* Last IO error */
|
||||
int ioRetries;
|
||||
int seekRetries;
|
||||
int sectRetries;
|
||||
int verifyRetries;
|
||||
|
||||
/* hardware info */
|
||||
int drvFlags; /* Copy of drive flags */
|
||||
short stepDirection; /* Current step direction */
|
||||
diskPosition_t pos; /* Physical position on disk */
|
||||
|
||||
|
||||
/* drive info */
|
||||
short unit; /* Drive # as seen by IWM */
|
||||
short partition; /* "Partition" info {a,b,c,...} */
|
||||
fdInfo_t *defaultType; /* default floppy format */
|
||||
fdInfo_t *currentType; /* current floppy format */
|
||||
int state; /* XXX */
|
||||
|
||||
int drvFlags; /* Copy of drive flags */
|
||||
short unit; /* Drive # as seen by IWM */
|
||||
short partition; /* "Partition" info {a,b,c,...} */
|
||||
fdInfo_t *defaultType; /* default floppy format */
|
||||
fdInfo_t *currentType; /* current floppy format */
|
||||
int state; /* XXX */
|
||||
void *trackBuf; /* Pointer to track buffer */
|
||||
short stepDirection; /* Current step direction */
|
||||
diskPosition_t pos; /* Physical position on disk */
|
||||
int writeLabel; /* Write access to disklabel? */
|
||||
/* data transfer info */
|
||||
int ioDirection; /* Read/write */
|
||||
daddr_t startBlk; /* Starting block # */
|
||||
int bytesLeft; /* Bytes left to transfer */
|
||||
int bytesDone; /* Bytes transferred */
|
||||
caddr_t current_buffer; /* target of current data transfer */
|
||||
unsigned char *cbuf; /* ptr to cylinder cache */
|
||||
int cachedSide; /* Which head is cached? */
|
||||
cylCacheSlot_t r_slots[IWM_MAX_GCR_SECTORS];
|
||||
cylCacheSlot_t w_slots[IWM_MAX_GCR_SECTORS];
|
||||
int writeLabel; /* Write access to disklabel? */
|
||||
sectorHdr_t sHdr; /* current sector header */
|
||||
};
|
||||
typedef struct fd_softc fd_softc_t;
|
||||
|
||||
|
@ -152,15 +176,15 @@ typedef struct fd_softc fd_softc_t;
|
|||
* SWIM/MFM mode may have some state to keep here.
|
||||
*/
|
||||
struct iwm_softc {
|
||||
struct device devInfo; /* generic device info */
|
||||
int drives; /* # of attached fd's */
|
||||
fd_softc_t *fd[IWM_MAX_DRIVE]; /* ptrs to children */
|
||||
struct device devInfo; /* generic device info */
|
||||
int drives; /* # of attached fd's */
|
||||
fd_softc_t *fd[IWM_MAX_DRIVE]; /* ptrs to children */
|
||||
|
||||
int state; /* make that an enum? */
|
||||
u_char modeReg; /* Copy of IWM mode register */
|
||||
short maxRetries; /* I/O retries */
|
||||
int state; /* make that an enum? */
|
||||
u_char modeReg; /* Copy of IWM mode register */
|
||||
short maxRetries; /* I/O retries */
|
||||
int errors;
|
||||
int underruns; /* data not delivered in time */
|
||||
int underruns; /* data not delivered in time */
|
||||
};
|
||||
typedef struct iwm_softc iwm_softc_t;
|
||||
|
||||
|
@ -193,27 +217,32 @@ dev_type_size(fdsize);
|
|||
dev_type_dump(fddump);
|
||||
|
||||
|
||||
int iwmSelectDrive __P((int drive));
|
||||
int iwmSelectSide __P((int side));
|
||||
int iwmInit __P((void));
|
||||
int iwmCheckDrive __P((int32_t drive));
|
||||
int iwmSelectDrive __P((int32_t drive));
|
||||
int iwmSelectSide __P((int32_t side));
|
||||
int iwmTrack00 __P((void));
|
||||
int iwmSeek __P((int steps));
|
||||
int iwmSeek __P((int32_t steps));
|
||||
|
||||
int iwmReadSector __P((caddr_t buf, sectorHdr_t *hdr));
|
||||
int iwmWriteSector __P((caddr_t buf, sectorHdr_t *hdr));
|
||||
int iwmReadSector __P((sectorHdr_t *hdr, cylCacheSlot_t *r_slots,
|
||||
caddr_t buf));
|
||||
int iwmWriteSector __P((sectorHdr_t *hdr, cylCacheSlot_t *w_slots));
|
||||
|
||||
int iwmDiskEject __P((int drive)); /* drive = [0..1] */
|
||||
int iwmMotor __P((int drive, int onOff)); /* on(1)/off(0) */
|
||||
int iwmDiskEject __P((int32_t drive)); /* drive = [0..1] */
|
||||
int iwmMotor __P((int32_t drive, int32_t onOff)); /* on(1)/off(0) */
|
||||
|
||||
/*
|
||||
* Debugging only
|
||||
*/
|
||||
int iwmQueryDrvFlag __P((int drive, int reg)); /* reg = [0..15] */
|
||||
int iwmQueryDrvFlag __P((int32_t drive, int32_t reg)); /* reg = [0..15] */
|
||||
|
||||
/* Make sure we run at splhigh when calling! */
|
||||
int iwmReadSectHdr __P((sectorHdr_t *hdr));
|
||||
|
||||
int iwmReadRawSector __P((int ID, caddr_t buf));
|
||||
int iwmWriteRawSector __P((int ID, caddr_t buf));
|
||||
int iwmReadRawTrack __P((int mode, caddr_t buf));
|
||||
#if 0 /* XXX not yet */
|
||||
int iwmReadRawSector __P((int32_t ID, caddr_t buf));
|
||||
int iwmWriteRawSector __P((int32_t ID, caddr_t buf));
|
||||
int iwmReadRawTrack __P((int32_t mode, caddr_t buf));
|
||||
#endif
|
||||
|
||||
#endif /* _MAC68K_FDVAR_H */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: iwm_regs.s,v 1.1 1999/02/18 07:38:26 scottr Exp $ */
|
||||
/* $NetBSD: iwm_regs.s,v 1.2 1999/03/27 05:45:20 scottr Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996-98 Hauke Fath. All rights reserved.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* $Id: iwmreg.h,v 1.2 1999/02/18 07:50:54 scottr Exp $ */
|
||||
/* $NetBSD: iwmreg.h,v 1.3 1999/03/27 05:45:20 scottr Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996-98 Hauke Fath. All rights reserved.
|
||||
* Copyright (c) 1996-99 Hauke Fath. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
|
@ -32,13 +32,14 @@
|
|||
* iwmreg.h -- Interface declarations for iwm.
|
||||
*/
|
||||
|
||||
#ifndef _LOCORE
|
||||
|
||||
/*
|
||||
* Configuration
|
||||
*/
|
||||
int iwmInit(void);
|
||||
|
||||
/* Virtual Drive flags register */
|
||||
enum dFlags {
|
||||
enum {
|
||||
IWM_DS_DISK = 0x01,
|
||||
IWM_NO_DISK = 0x02,
|
||||
IWM_MOTOR_OFF = 0x04,
|
||||
|
@ -46,12 +47,12 @@ enum dFlags {
|
|||
IWM_DD_DISK = 0x10,
|
||||
IWM_NO_DRIVE = 0x80000000
|
||||
};
|
||||
int iwmCheckDrive(int drive);
|
||||
|
||||
/*
|
||||
* Access
|
||||
*/
|
||||
enum dErrors {
|
||||
enum {
|
||||
noErr = 0, /* All went well */
|
||||
noDriveErr = -64, /* Drive not installed */
|
||||
offLinErr = -65, /* R/W requested for an offline drive */
|
||||
noNybErr = -66, /* Disk is probably blank */
|
||||
|
@ -79,18 +80,189 @@ enum dErrors {
|
|||
fmt2Err = -83, /* Can't get enough sync */
|
||||
verErr = -84 /* Track failed to verify */
|
||||
};
|
||||
typedef enum dErrors dErrors_t;
|
||||
|
||||
/*
|
||||
* This is byte-aligned (just in case anyone's interested...)
|
||||
*/
|
||||
#define IWM_TAG_SIZE 20 /* That's what "SonyEqu.a" says */
|
||||
|
||||
|
||||
/* Buffer for sector header data */
|
||||
struct sectorHdr {
|
||||
u_int8_t side;
|
||||
u_int8_t track;
|
||||
u_int8_t sector;
|
||||
u_int8_t Tags[13]; /* XXX Looks like it, although IM */
|
||||
/* specifies 12 tag bytes */
|
||||
u_int8_t Tags[IWM_TAG_SIZE];
|
||||
};
|
||||
typedef struct sectorHdr sectorHdr_t;
|
||||
|
||||
/*
|
||||
* Cylinder cache data structure
|
||||
* Cyl buffer is allocated in fdopen() and deallocated in fdclose().
|
||||
*
|
||||
* The "valid" flag is overloaded as "dirty" flag when writing
|
||||
* to disk.
|
||||
*/
|
||||
struct cylCacheSlot {
|
||||
unsigned char *secbuf; /* ptr to one sector buffer */
|
||||
int32_t valid; /* content valid for cur. cylinder? */
|
||||
};
|
||||
typedef struct cylCacheSlot cylCacheSlot_t;
|
||||
|
||||
|
||||
#else /* _LOCORE */
|
||||
|
||||
|
||||
/*
|
||||
* Assembler equates for IWM, kept here to ensure consistency.
|
||||
* Modelled after <sys/disklabel.h>
|
||||
*/
|
||||
|
||||
/*
|
||||
* Offsets into data structures
|
||||
*/
|
||||
/* sectorHdr_t */
|
||||
.equ o_side, 0
|
||||
.equ o_track, 1
|
||||
.equ o_sector, 2
|
||||
.equ o_Tags, 3
|
||||
|
||||
/* cylCacheSlot_t */
|
||||
.equ o_secbuf, 0
|
||||
.equ o_valid, 4
|
||||
|
||||
/*
|
||||
* Parameter (a6) offsets from <mac68k/obio/iwm_fdvar.h>
|
||||
*
|
||||
* int iwmReadSector __P((sectorHdr_t *hdr, cylCacheSlot_t *r_slots,
|
||||
* caddr_t buf))
|
||||
* int iwmWriteSector __P((sectorHdr_t *hdr, cylCacheSlot_t *w_slots))
|
||||
*/
|
||||
.equ o_hdr, 8
|
||||
.equ o_rslots, 12
|
||||
.equ o_wslots, 12
|
||||
.equ o_buf, 16
|
||||
|
||||
|
||||
/*
|
||||
* I/O base addresses
|
||||
*/
|
||||
.global _Via1Base /* in machdep.c */
|
||||
.global _IOBase
|
||||
.global _IWMBase /* in iwm_fd.c */
|
||||
|
||||
/*
|
||||
* Offsets from IWM base address
|
||||
* Lines are set by any memory access to corresponding address (IM III-34/-44).
|
||||
* The SWIM has actual registers at these addresses, so writing to them
|
||||
* in IWM mode is a no-no.
|
||||
*/
|
||||
.equ ph0L, 0x0000 /* CA0 off (0) */
|
||||
.equ ph0H, 0x0200 /* CA0 on (1) */
|
||||
.equ ph1L, 0x0400 /* CA1 off (0) */
|
||||
.equ ph1H, 0x0600 /* CA1 on (1) */
|
||||
.equ ph2L, 0x0800 /* CA2 off (0) */
|
||||
.equ ph2H, 0x0A00 /* CA2 on (1) */
|
||||
.equ ph3L, 0x0C00 /* LSTRB off (low) */
|
||||
.equ ph3H, 0x0E00 /* LSTRB on (high) */
|
||||
.equ mtrOff, 0x1000 /* disk enable off */
|
||||
.equ mtrOn, 0x1200 /* disk enable on */
|
||||
.equ intDrive, 0x1400 /* select internal drive */
|
||||
.equ extDrive, 0x1600 /* select external drive */
|
||||
.equ q6L, 0x1800 /* Q6 off */
|
||||
.equ q6H, 0x1A00 /* Q6 on */
|
||||
.equ q7L, 0x1C00 /* Q7 off */
|
||||
.equ q7H, 0x1E00 /* Q7 on */
|
||||
|
||||
|
||||
/*
|
||||
* VIA Disk SEL line
|
||||
*/
|
||||
.equ vBufA, 0x1E00 /* Offset from vBase to register A */
|
||||
/* (IM III-43) */
|
||||
.equ vHeadSel, 5 /* Multi-purpose line (SEL) */
|
||||
.equ vHeadSelMask, 0x0020 /* Corresponding bit mask */
|
||||
|
||||
|
||||
/*
|
||||
* Disk registers
|
||||
* bit 0 - CA2, bit 1 - SEL, bit 2 - CA0, bit 3 - CA1 IM III name
|
||||
*/
|
||||
|
||||
/* Status */
|
||||
.equ stepDirection, 0x0000 /* Direction of next head step */
|
||||
/* 0 = in, 1 = out (DIRTN) */
|
||||
.equ rdDataFrom0, 0x0001 /* Set up drive to read data from */
|
||||
/* head 0 (RDDATA0) */
|
||||
.equ diskInserted, 0x0002 /* Disk inserted */
|
||||
/* 0 = yes, 1 = no (CSTIN) */
|
||||
.equ rdDataFrom1, 0x0003 /* Set up drive to read data from */
|
||||
/* head 1 (RDDATA1) */
|
||||
.equ stillStepping, 0x0004 /* Drive is still stepping */
|
||||
/* 0 = yes, 1 = no (STEP) */
|
||||
.equ writeProtected, 0x0006 /* Disk is locked */
|
||||
/* 0 = yes, 1 = no (WRTPRT) */
|
||||
.equ drvMotorState, 0x0008 /* Drive motor is on */
|
||||
/* 0 = yes, 1 = no (MOTORON) */
|
||||
.equ singleSided, 0x0009 /* Drive is single-sided */
|
||||
/* 0 = yes, 1 = no (SIDES) */
|
||||
.equ atTrack00, 0x000A /* Head is at track 00 */
|
||||
/* 0 = yes, 1 = no (TK0) */
|
||||
.equ headLoaded, 0x000B /* Head loaded, drive is ready */
|
||||
/* 0 = yes, 1 = no () */
|
||||
.equ drvInstalled, 0x000D /* Disk drive installed */
|
||||
/* 0 = yes, 1 = no () */
|
||||
.equ tachPulse, 0x000E /* Tachometer pulse (60 /rev.) */
|
||||
/* 0 = yes, 1 = no (TACH) */
|
||||
.equ diskIsHD, 0x000F /* HD disk detected */
|
||||
/* 0 = yes, 1 = no (DRVIN) */
|
||||
|
||||
/* Commands */
|
||||
.equ stepInCmd, 0x0000 /* Head step direction in (DIRTN) */
|
||||
.equ stepOutCmd, 0x0001 /* Head step direction out (DIRTN+1) */
|
||||
.equ doStepCmd, 0x0004 /* Step head (STEP) */
|
||||
.equ motorOnCmd, 0x0008 /* Switch drive motor on (MOTORON) */
|
||||
.equ motorOffCmd, 0x0009 /* Switch drive motor off (MOTOROFF) */
|
||||
.equ ejectDiskCmd, 0x000D /* Eject disk from drive (EJECT) */
|
||||
|
||||
|
||||
/*
|
||||
* Low level disk errors
|
||||
* For simplicity, they are given the MacOS names and numbers.
|
||||
*/
|
||||
.equ noErr, 0 /* All went well */
|
||||
.equ noDriveErr, -64 /* Drive not installed */
|
||||
.equ offLinErr, -65 /* R/W requested for an offline drive */
|
||||
.equ noNybErr, -66 /* Disk is probably blank */
|
||||
.equ noAdrMkErr, -67 /* Can't find an address mark */
|
||||
.equ dataVerErr, -68 /* Read verify compare failed */
|
||||
.equ badCkSmErr, -69 /* Bad address mark checksum */
|
||||
.equ badBtSlpErr, -70 /* Bad address mark (no lead-out) */
|
||||
.equ noDtaMkErr, -71 /* Could not find a data mark */
|
||||
.equ badDCkSum, -72 /* Bad data mark checksum */
|
||||
.equ badDBtSlp, -73 /* One of the data mark bit slip */
|
||||
/* nibbles was incorrect. */
|
||||
.equ wrUnderRun, -74 /* Could not write fast enough to */
|
||||
/* keep up with the IWM */
|
||||
.equ cantStepErr, -75 /* Step handshake failed during seek */
|
||||
.equ tk0BadErr, -76 /* Track 00 sensor does not change */
|
||||
/* during head calibration */
|
||||
.equ initIWMErr, -77 /* Unable to initialize IWM */
|
||||
.equ twoSideErr, -78 /* Tried to access a double-sided disk */
|
||||
/* on a single-sided drive (400K drive) */
|
||||
.equ spAdjErr, -79 /* Can't adjust drive speed (400K drive) */
|
||||
.equ seekErr, -80 /* Wrong track number read in a */
|
||||
/* sector's address field */
|
||||
.equ sectNFErr, -81 /* Sector number never found on a track */
|
||||
.equ fmt1Err, -82 /* Can't find sector 0 after */
|
||||
/* track format */
|
||||
.equ fmt2Err, -83 /* Can't get enough sync */
|
||||
.equ verErr, -84 /* Track failed to verify */
|
||||
|
||||
/*
|
||||
* Misc constants
|
||||
*/
|
||||
.equ iwmMode, 0x17 /* SWIM switch */
|
||||
.equ maxGCRSectors, 12 /* Max. sectors per track for GCR */
|
||||
|
||||
|
||||
#endif /* _LOCORE */
|
||||
|
||||
#endif /* _MAC68K_IWMREG_H */
|
||||
|
|
Loading…
Reference in New Issue