home *** CD-ROM | disk | FTP | other *** search
Text File | 2001-02-09 | 79.4 KB | 2,492 lines |
- ; July 31 1992 v6.00'
-
- ;------------------------------------------------------------------------
- ; :
- ; AHDI Hard Disk Driver for the Atari ST, TT and ST Book :
- ; Copyright 1985-1991 Atari Corp. :
- ; All Rights Reserved :
- ; :
- ;------------------------------------------------------------------------
-
-
- ;+
- ; Conditional Assembly Switches
- ;-
- ospool equ 1 ; increase size of OS pool for ROM
-
-
- ;
- ;+
- ; Edit History
- ;
- ;
- ; 22-May-1989 ml Started this from ahdi 3.00
- ; Files created for this driver:
- ; ACSI.S Low-level driver for ACSI.
- ; CMDBLK.S Builds packets for command blocks.
- ; DOIT.S Sends packets out to SCSI or ACSI.
- ; DRIVER.S This file.
- ; SCSI.S Low-level driver for SCSI.
- ;
- ; 25-May-1989 ml Eliminated pread(), use _ahdi_rw() in physical mode
- ; instead.
- ;
- ; 06-Jun-1989 ml Created INSTALL.S for driver installation.
- ;
- ; 11-Jul-1989 ml Rwabs() now handles DMA to fast RAM on ACSI side
- ; also. If no extra RAM was reserved for fast RAM
- ; transferred, _dskbufp is used for the transfer.
- ; (This is going to be really slow!!!)
- ;
- ; 19-Jul-1989 ml If there is cache on CPU, Rwabs() reads will
- ; flush both the I and D cache.
- ;
- ; 06-Sep-1989 ml Use _FRB (in the cookie jar) for fast RAM transfer,
- ; assuming _FRB WILL be there if there is fast RAM on
- ; the machine.
- ;
- ; 20-Feb-1990 ml 3.64 Fixed bug in return code when doing ACSI odd transfer.
- ; When successful, 0 should be returned.
- ;
- ; 02-Mar-1990 ml 3.65 Took out wait loop for SCSI 0 to be ready.
- ; (modified file: install.s)
- ;
- ; 05-Mar-1990 ml 3.66 Added more checks for I/O to ACSI and SCSI non-
- ; accessible memory. _FRB will be used if it exists.
- ; If _FRB doesn't exist, _dskbuf will used (which
- ; means I/O could be "really" slow). (_do_rw())
- ;
- ; _FRB is being looked for when it's needed for the
- ; first time, not at boot time. (Applications can
- ; add the _FRB when they are executed.)
- ;
- ; 08-Mar-1990 ml Added SCFRDMA flag in defs.h to make SCSI DMA to
- ; fast RAM conditional assembly.
- ; (modified file: driver.s)
- ;
- ; 15-Mar-1990 ml Added DEBUG flag in defs.h to make debugging code
- ; conditional assembly.
- ;
- ; 09-Apr-1990 ml 3.67 Added a "read" from WDL after toggling the ACSI DMA
- ; chip to point the MMU to the correct direction.
- ; (modified file: acsi.s)
- ;
- ; 10-Apr-1990 ml Put up banner at beginning and end of loading driver
- ; (requested by jwt), instead of just at the end.
- ; (Printing of banner moved to install.s)
- ;
- ; 17-Apr-1990 ml Added ODMA flag in defs.h to make the klutch of
- ; making byte counter bigger than # bytes requested
- ; when receiving data from SCSI conditional assembly.
- ; (modified file: scsi.s)
- ;
- ; 20-Apr-1990 ml Added RDWDL flag in defs.h to make the "extra read"
- ; added on 09-Apr-1990 conditional assembly. (When
- ; writing to ACSI, first 32 bytes are always FF's!!
- ; Wondering why...)
- ; (modified file: acsi.s)
- ;
- ; 30-Jul-1990 ml 4.00 Final for TT release.
- ; (Vectored-interrupts code not included)
- ;
- ; 31-Jul-1990 ml Vectored-interrupt code included as conditional
- ; assembly.
- ;
- ; 29-Oct-1990 ml 4.01 BUG!!! Getcookie() module provided by AKP has a
- ; variable declared in the bss. This bss will be
- ; clobbered when the driver adds GEMDOS buffers and
- ; OS pool. When getcookie() was called, and access
- ; the bss, it clobbered whatever was using its space
- ; at the time.
- ; Fixed in cookie.s by changing moving the variable
- ; from the bss to the text segment.
- ; (modified file: cookie.s)
- ;
- ; 26-Nov-1990 ml 4.02 BUG!! From 3.00 through 4.01, when Rwabs() is called
- ; in raw mode, it ignored media change completely.
- ; This created problems with cartridge swapping on the
- ; removable drives. If Getbpb(), on a logical drive
- ; that has not been accessed on the previous cartridge,
- ; is called right after a cartridge swap, Getbpb() will
- ; call Rwabs() in raw mode to read the partition map of
- ; the physical unit concerned. This Rwabs() call will
- ; get the media change error from the controller and
- ; ignores it without setting any mcflg of the physical
- ; unit. Now when Mediach(), on a logical drive that was
- ; accessed on the previous cartridge, is called, the
- ; driver will return media not change!
- ; In version 4.02, Rwabs() still does not return media
- ; change error when called in raw mode, but will
- ; remember it by setting the mcflgs of the physical
- ; unit concerned to maybe changed.
- ;
- ; 02-Apr-1991 ml 4.03 BUG!! At boot time,
- ; move.l #(i_sasi1-i_sasi),tokeep
- ; is used to find number of bytes of code to keep.
- ; In pre-4.00 AHDI, this works just fine because both
- ; i_sasi1 and i_sasi are in the same file. But, since
- ; 3.00, i_sasi1 has been moved to the file INSTALL.S,
- ; thus external. Madmac did not complain that the
- ; expression #(i_sasi1-i_sasi) is not valid anymore.
- ; Instead it assembles the code as
- ; move.l #i_sasi1,tokeep
- ; This is bad, because it depends of where the driver
- ; is being loaded, the driver may end up hogging large
- ; amount of memory that it is not using. This is now
- ; fixed by calculating the amount at run time.
- ; move.l #i_sasi1,tokeep
- ; subi.l #i_sasi,tokeep
- ; (modified file: driver.s)
- ;
- ; 04-Apr-1991 ml Some SCSI drives will recalibrate every so often.
- ; While recalibrating, the drive still accepts the
- ; command block, but delays the transfer of data to
- ; after the recalibration. So, timeout for the data
- ; transfer should include the amount of time spent
- ; on recalibration. The worst case we know of is
- ; the Fujisu drives which takes 4 seconds. So, the
- ; default for recalibration time is set to 4 seconds.
- ; (modified files: driver.s, scsi.s)
- ;
- ; 08-Aug-1991 ml BUG!! When the eject button on the MEGAFILE 44 is
- ; pressed without actually changing the cartridge, the
- ; driver still thinks there is a media change. The
- ; driver complains that the FAT checksum is different
- ; from what's been recorded.
- ;
- ; The cause:
- ; When _ahdi_rw() is called in physical mode, the
- ; variable sizr should not be set. First, it is not
- ; necessary to set it, because the variable is not
- ; used at all when in physical mode. Secondly, the
- ; setting of the variable overwrites its value which
- ; may have been set by the logical mode _ahdi_rw() that
- ; calls _ahdi_rw() recursively in physical mode!
- ; (modified file: driver.s)
- ;
- ; 14-Aug-1991 ml 4.60 Folded v4.59, which handles the IDE drives, into
- ; v4.03.
- ; (added files: ide.s, ide.h, blitter.h)
- ; (modified files: driver.s, install.s, defs.h)
- ;
- ; 19-Aug-1991 ml Modified errcode() so that it returns a BIOS
- ; error code instead of the controller error code.
- ; It now handles error for ACSI, SCSI and IDE drives.
- ;
- ; 20-Aug-1991 ml Optimized code by eliminating as many mulu's
- ; and divu's as possible.
- ; (modified files: driver.s install.s, acsi.s)
- ;
- ; 21-Aug-1991 ml Modified the ACSI-accessible RAM boundary check
- ; in _do_rw(). The boundary is at 4Mb for STs,
- ; at 10Mb for TTs.
- ; (modified files: driver.s, install.s, defs.h)
- ;
- ; 30-Aug-1991 ml Eliminated the requirement that physical units
- ; connected to the system must have consecutive
- ; physical unit numbers. The flag how2scan tells
- ; the driver how to scan the physical units. If set,
- ; the driver will scan the physical units as specified
- ; by the flags to be explained later. If how2scan is
- ; not set, the driver will do the scanning the default
- ; way, which is, consecutively. Acsi2scan, scsi2scan
- ; and ide2scan are flags introduced to tell the driver
- ; which physical units to scan at boot time. Each bit
- ; in the flags corresponds to one physical unit.
- ; acsi2scan: bit 0..7 corresponds to ACSI unit 0..7
- ; scsi2scan: bit 0..7 corresponds to SCSI unit 0..7
- ; ide2scan: bit 0..1 corresponds to IDE unit 0..1
- ; Acsi2scan, scsi2scan and ide2scan are defaulted to
- ; 0xff, which tells the driver to scan all units.
- ; (modified files: driver.s install.s)
- ;
- ; 06-Sep-1991 ml Added boot-time-messages to show information of the
- ; device being scanned.
- ; (modified files: install.s)
- ;
- ; 13-Sep-1991 ml Decision has been made that there will only be ONE
- ; IDE drive connected to the controller at the current
- ; IDE bus address. So, code that was written to take
- ; care of IDE unit 1 was eliminated.
- ; (modified files: driver.s install.s)
- ;
- ; 16-Sep-1991 ml Check if driver is running on ST Book. If so, do
- ; NOT use BLiTTER for IDE hard disk data transfer.
- ; (modified files: driver.s install.s)
- ;
- ; 17-Sep-1991 ml Added a flag, called ideinit, for programs (e.g.
- ; Slavik's POWER.PRG) to set to let the driver know
- ; that it needs to reinitialize the IDE drive.
- ; Initializing the drive involves doing an identify(),
- ; an initparm(), and reset of the drive's internal
- ; spin down counter.
- ; (modified files: driver.s)
- ;
- ; 18-Sep-1991 ml Assuming that an IDE drive will boot up in a mode as
- ; specified by the parameters returned by the Identify
- ; command, there is no need to do the Initparm command
- ; at boot time. There is also no need to reinitialize
- ; the drive after a shut down. So changes added yes-
- ; terday are deleted.
- ; (modified files: driver.s install.s)
- ;
- ; 24-Sep-1991 ml 5.00a Wrapped up driver for ST Book and STE+. To show
- ; info of ACSI devices at boot time, delay must be
- ; added to take care of the slow ones (e.g. laser
- ; printer.)
- ; (modified files: acsi.s driver.s install.s)
- ;
- ; 01-Oct-1991 ml 5.00 First preliminary release for ST Book.
- ;
- ; 07-Oct-1991 ml Changes made to _rcvacsi() in calculating # of
- ; times to send the command. Refer to comments in
- ; acsi.s.
- ; (modified file: acsi.s)
- ;
- ; 11-Oct-1991 ml Special-cased Conner CP2024 in finding current
- ; drive parameters of IDE drives.
- ; (modified files: ide.s install.s)
- ;
- ; 22-Oct-1991 ml Added in check for command line arguements. If
- ; there is any, do NOT print any messages on the
- ; screen.
- ; (modified files: driver.s install.s)
- ;
- ; 25-Nov-1991 ml 5.0a Modified SCSI code to use the ACSI DMA chip. This
- ; limits the number of sectors that can be transferred
- ; per command to the ACSI limit of 254 sectors.
- ; (added files: spscsi.h spscsi.s)
- ; (modified files: driver.s install.s)
- ;
- ; 10-Dec-1991 ml 5.0b Fixed a couple of bugs. Added memory boundary checks
- ; for Sparrow. Changed the way to test for IDE bus,
- ; access 0xf00010 instead of 0xf00000 (for now.)
- ; (modified files: spscsi.s driver.s install.s)
- ;
- ; 12-Feb-1992 ml 5.0c Modified _do_rw() to use the 14-bit counter on the
- ; ACSI DMA chip of the Sparrow.
- ; Modified _rcvspscsi() to utilize the "flush" bit in
- ; the ACSI Mode Register. This is not really needed
- ; because the driver was doing programmed I/O for
- ; transfers fewer than 512 bytes.
- ; (modified files: driver.s spscsi.s)
- ;
- ; 14-Feb-1992 ml Added safety check in _resetspscsi().
- ; (modified file: spscsi.s)
- ;
- ; 26-Feb-1992 ml 5.0d Bug! Modified check_dev() to support non-consecutive
- ; unit numbers.
- ;
- ; 03-Mar-1992 ml Test if an IDE drive exists before sending it a
- ; command (even IDE bus exists.)
- ; (modified file: driver.s ide.s install.s)
- ; 14-Apr-1992 ml Slow down IDE non-BLiT transfers
- ; (modified file: driver.s ide.s install.s)
- ; 31-Jul-1992 ml 6.00 Released version of the Falcon 030 driver.
- ;-
-
-
- .include "defs.h"
- .include "error.h"
- .include "sysvar.h"
- .include "68030.s"
- .include "mfp.h"
- .include "scsi.h"
- .include "spscsi.h"
-
-
- .extern _untrdy
- .extern _rqsense
- .extern _hread
- .extern _hwrite
- .extern _xtdread
- .extern _xtdwrt
- .extern _ideread
- .extern _idewrite
- .extern _awto
- .extern idexst
-
- .extern prnstr
-
- .extern i_sasi1
- .extern _getcookie
- .extern _drvxst
-
- ;
- ;+
- ; Entry points:
- ;
- ; +0 GEMDOS entry point (double-click, or \AUTO folder on floppy)
- ; +4 Boot entry point (from driver file off of C:)
- ; +8 Reserved for future use
- ; +$C $F0AD magic number
- ; +$E version number
- ; +$12 # chunks of ospool to add
- ; +$14 # of sqnpart entries that follows
- ; +$16 first sqnpart entry
- ;
- ; if bootloaded, d0 = # bytes allocated by boot code.
- ;-
- i_sasi: bra gboot ; GEMDOS entry-point
- bra iboot ; Boot entry-point
- bra iboot ; (unused, reserved)
-
-
- ;+
- ; Patchable variables
- ;-
- ; Published since v3.00
- magicnum: dc.w $f0ad ; magic number to signify the
- ; existence of patchable variables
- vernum: dc.w $0500 ; AHDI version number
- numchunks: dc.w 128 ; # chunks of memory to add to ospool
- .globl defbigsect
- defbigsect: dc.w 512 ; default size of a big sector
- numsqnpart: dc.w MAXACSI ; number of sqnpart entries to follow
- .globl defsqnpart ; default # of logical drives
- defsqnpart: dcb.b MAXACSI,1 ; reserved for removable ACSI units
- acsiidle: dc.l 0 ; default idle time limit for ACSI
- ; unit 0 (in # of _hz_200 ticks)
-
- ; Published since v4.00:
- numsqcnpart: dc.w MAXSCSI ; number of sqcnpart entries to follow
- .globl defsqcnpart ; default # of logical drives
- defsqcnpart: dcb.b MAXSCSI,1 ; reserved for removable SCSI units
- .globl scxltmout
- scxltmout: dc.l 12001 ; SCSI extra long-timeout (>1 min)
- .globl slwsclto
- slwsclto: dc.l 5000 ; SCSI stunit() long-timeout (>25s)
- .globl slwscsto
- slwscsto: dc.l 42 ; SCSI stunit() short-timeout (>205ms)
- .globl scltmout
- scltmout: dc.l 201 ; SCSI long-timeout (>1000 ms)
- .globl scstmout
- scstmout: dc.l 51 ; SCSI short-timeout (>500 ms)
-
- ; Published since v4.03:
- .globl rcaltm
- rcaltm: dc.l 801 ; time for drive recalibration (>4s)
-
- ; Published since v5.00:
- .globl ideidle ; default idle time limit for IDE-IDE
- ideidle: dc.w 0 ; unit 0 (in 5 second increments)
- .globl how2scan ; if set, scan physical units as
- how2scan: dc.b 0 ; specified by acsi/scsi/ide2scan
- .globl acsi2scan ; bit mask of ACSI physical units
- acsi2scan: dc.b $ff ; to be scanned at boot time
- .globl scsi2scan ; bit mask of SCSI physical units
- scsi2scan: dc.b $ff ; to be scanned at boot time
- .globl ide2scan ; bit mask of IDE physical units
- ide2scan: dc.b $01 ; to be scanned at boot time
-
- ;+
- ; For Debugging
- .globl badcombo ;
- badcombo: dc.b 1 ; 1: combo is bad, don't use BLiTTER
- ;-
- .even
-
-
- ;+
- ; GEMDOS entry;
- ; find amount of memory availble and store in d0.l
- ;-
- gboot: movea.l 4(sp),a2 ; a2 -> basepage
- move.b $80(a2),silence ; set flag for printing messages
- move.l 4(a2),d0 ; d0 = available memory
- sub.l (a2),d0 ; = p_hitpa - p_lowtpa - basepage
- sub.l #$0100,d0
- bra i_sasi1 ; (continue with normal initialization)
-
-
- ;+
- ; Boot entry;
- ; set "bootloaded", record base address from boot loader,
- ; and continue with normal boot process.
- ;-
- iboot: st bootloaded ; boot entry-point, set flag
- sub.l #$1c,d0 ; memory available -= file header
- move.l a2,baseaddr ; install base address
- ; a2 = beginning addr of this block
- bra i_sasi1 ; (continue with normal initialization)
-
-
- ;
- ;+
- ; Driver State
- ;-
- dc.b 13,'AHDI : July 31 1992 v6.00'
- dc.b 13,10,$bd,'Atari Corp.'
- dc.b ' 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992'
- dc.b 13,10,0,$1A
- .even
-
- ;***** Beginning Of Published Variables *****
-
- .globl puns
- puns: dc.w 0 ; # of physical units on user's system
-
- dummy1: dcb.b 2,-1 ; dummy pun entries for A and B
- .globl pun
- pun: dcb.b MAXLOG,0 ; physical unit table
- .even
-
- dummy2: dcb.l 2,0 ; dummy start entries for A and B
- .globl start
- start: dcb.l MAXLOG,0 ; partition start table
-
- .globl cookie ; *** DON'T CHANGE ***
- cookie: dc.l $41484449 ; cookie = 'AHDI'
-
- .globl cookptr
- cookptr: dc.l 0 ; pointer to cookie
-
- versn: dc.w $0600 ; version number: MMmm
-
- .globl maxssz
- maxssz: dc.w 512 ; maximum sector size allowed
-
- acsisd: dc.l 0 ; idle time limit to spin down ACSI
- ; unit 0 (applicable to STACY ONLY)
- .globl idesd ; idle time limit to spin down
- idesd: dc.w 0 ; IDE unit 0
-
- dcb.w 29,0 ; reserved for future use
-
- ;***** End Of Published Variables *****
-
- .globl numacsi
- numacsi: dc.w 0 ; number of ACSI drives
-
- .globl numscsi
- numscsi: dc.w 0 ; number of SCSI drives
-
- .globl mcflgs
- mcflgs: dcb.b MAXLOG,2 ; media change flag table
- .globl xst
- xst: dcb.b MAXLOG,1 ; drive existence flag table
- .globl idedp
- idedp: dcb.b IDEDPLEN,0 ; IDE drive parameters table
- bpbs: dcb.b BPBLEN,0 ; a bpb
- serno: dcb.b MAXLOG*SERLEN,0 ; serial number table
- .globl sratio
- sratio: dcb.b MAXLOG,1 ; log sect size : phys sect size tbl
- fatsum: dcb.b MAXLOG<<FATLEN,0 ; FAT checksum table
- fatst: dcb.w MAXLOG,0 ; starting sector # of last FAT
- fatend: dcb.w MAXLOG,0 ; ending sector # of last FAT
-
- .globl bootloaded
- bootloaded: dc.w 0 ; nonzero if loaded from boot sector
- .globl memalloc
- memalloc: dc.l 0 ; total memory available if bootloaded
- baseaddr: dc.l 0 ; -> base addr of .PRG file
- tokeep: dc.l 0 ; amount memory to keep
-
- .globl machine ; value of _MCH
- machine: dc.l 0 ; high word is machine type
-
- .globl cpun
- cpun: dc.w 0 ; current physical unit
- .globl npart
- npart: dc.w 0 ; number of partitions found
- bfat: dc.w 0 ; 0: 12-bit FAT; 1: 16-bit FAT
-
- strec: dc.l 0 ; starting sector to read/write
- endrec: dc.l 0 ; last sector to read/write
- stbuf: dc.l 0 ; starting address of buffer
- .globl embscsi
- embscsi: dc.b 0 ; 1: embedded SCSI drive
-
- frbbuf: dc.l 0 ; pointer to _FRB
-
- _retries: dc.w NRETRIES ; number of retries to do
- retrycnt: dc.w 1 ; retry counter
-
- .globl o_bpb
- o_bpb: dc.l 1 ; old bpb vector
- .globl o_rw
- o_rw: dc.l 1 ; old rwabs vector
- .globl o_mediach
- o_mediach: dc.l 1 ; old media change vector
-
- .globl sendata
- sendata: dcb.b 32,0 ; buffer for sense data
-
- lastmdctm: dc.l 0 ; time media change was last called
- .globl pbuf
- pbuf: dc.l 0 ; ptr to start of root sector image
- fsiz: dc.w 0 ; FAT size in sectors
- fatrec: dc.w 0 ; 2nd FAT starting sector
- .globl sizr
- sizr: dc.w 1 ; ratio of log : phys sector size
- cstart: dc.l 0 ; current dev's starting sector
- temp: dc.l 0 ; temporary storage
- .globl savssp
- savssp: dc.l 1 ; (saved SSP)
- .globl _cachexst
- _cachexst: dc.b 0 ; 0: no cache 1: with cache
- .globl _useblit
- _useblit: dc.b 0 ; 0: don't BLiT IDE hard disk data
- .globl ext
- ext: dc.b 0 ; if =0, not processing ext partition
- .globl extrt
- extrt: dc.l 0 ; starting sector of ext DOS partition
- .globl extvol
- extvol: dc.l 0 ; offset wrt ext DOS partition
- pbpb: dc.w 0 ; partition # for dev
- .globl silence
- silence: dc.b 0 ; 0: print messages
- .globl _spscsixst
- _spscsixst: dc.b 0 ; 0: no Sparrow SCSI
- .even
-
-
- ;
- ;+
- ; Front End
- ;-
-
- ;+
- ; Return pointer to BPB (or NULL)
- ;
- ; Synopsis: LONG hbpb(dev)
- ; WORD dev; 4(sp).w
- ;-
- .globl hbpb
- hbpb: move.w 4(sp),d0 ; d0 = devno
- clr d1 ; d1 = 0, physical op not possible
- movea.l o_bpb,a0 ; a0 -> pass-through vector
- lea _sasi_bpb(pc),a1 ; a1 -> our handler
- bra.s check_dev ; do it
-
-
- ;+
- ; Read or write logical sectors
- ;
- ; Synopsis: LONG hrw(rw, buf, count, recno, dev)
- ; WORD rw; $4(sp).w
- ; char *buf; $6(sp).l
- ; WORD count; $a(sp).w
- ; WORD recno; $c(sp).w
- ; WORD dev; $e(sp).w
- ;-
- .globl hrw
- hrw: move.w $e(sp),d0 ; d0 = devno
- move.w 4(sp),d1 ; d1 includes physical device flag
- movea.l o_rw,a0 ; a0 -> pass-through vector
- lea _sasi_rw(pc),a1 ; a1 -> our handler
- bra.s check_dev ; do it
-
-
- ;+
- ; Check for media change
- ;
- ; Synopsis: LONG hmediach(dev)
- ; WORD dev; 4(sp).w
- ;-
- .globl hmediach
- hmediach:
- move.w 4(sp),d0 ; d0 = devno
- clr d1 ; physical operation not possible
- movea.l o_mediach,a0 ; a0 -> pass-through vector
- lea _sasi_mediach(pc),a1 ; a1 -> our handler
-
-
- ;+
- ; check_dev - use handler, or pass vector through
- ;
- ; Passed: d0.w = device#
- ; d1, bit 3 1=physical operation
- ; a0 -> old handler
- ; a1 -> new handler
- ; a5 -> $0000 (zero-page ptr)
- ;
- ; Jumps-to: (a1) if dev in range for this handler
- ; (a0) otherwise
- ;-
- check_dev:
- subq #2,d0 ; lowest device is 2 (unit 0 or C:)
- bmi.s chkd_f ; if lower, not one of ours
-
- btst #3,d1 ; is this a physical unit operation?
- beq.s chkd_a ; if not, go check against pun
- ; else check existence of phys unit
- cmp.w #ACSIUNT,d0 ; an ACSI unit?
- bgt.s chkd_sc ; if not, try SCSI
- tst.w numacsi ; any ACSI unit connected?
- bne.s chkd_s ; if so, it's one of ours
- chkd_sc: ; else
- cmp.w #SCSIUNT,d0 ; an SCSI unit?
- bgt.s chkd_ide ; if not, try IDE
- tst.w numscsi ; any SCSI unit connected?
- bne.s chkd_s ; if so, it's one of ours
- chkd_ide: ; else
- cmp.w #IDEUNT,d0 ; an IDE unit?
- bgt.s chkd_f ; if not, not one of ours
- move.w puns,d1 ; d1.w = number of valid IDE units
- sub.w numacsi,d1 ; = total - #ACSI - #SCSI
- sub.w numscsi,d1
- tst.w d1 ; any IDE unit connected?
- bne.s chkd_s ; if so, it IS one of of ours
- bra.s chkd_f ; else not one of ours
-
- chkd_a:
-
- ;+
- ; Aug-08-91 ml. Added upper bound check for logical device #
- ;
- cmp.w #MAXLOG,d0 ; if logical device # >= MAXLOG
- bge.s chkd_f ; it's not one of ours
- ;-
- lea pun,a2 ; pointer to pun map
- tst.b 0(a2,d0.w) ; must be positive for a real unit
- bmi.s chkd_f
- chkd_s: movea.l a1,a0 ; yes -- follow success vector
- chkd_f: jmp (a0) ; do it
-
-
- ;
- ;+
- ; Medium-Level Driver
- ;-
-
- ;+
- ; Return BPB for logical device
- ;
- ; Synopsis: LONG _sasi_bpb(dev)
- ; WORD dev; $4(sp).w
- ;
- ; Returns: NULL, or a pointer to the BPB buffer
- ;
- ; 10-21-88 ml. I am not making a special case for non-removable
- ; hard disk, because if a program uses Allan's
- ; program to force a media change, the program
- ; should be getting the "Real" AND "New" BPB.
- ; (The old (v1.7 and before) AHDI only index into
- ; the bpbs table and return the pointer, without
- ; actually go and read the boot sector of the dev.)
- ;-
- _sasi_bpb:
- subq.w #2,4(sp) ; dev # excluding drv A and B
- move.w 4(sp),d1 ; d1 = device number
- lea pun,a0 ; a0 -> pun table
- adda.w d1,a0 ; a0 -> pun @ dev's entry
- moveq #0,d2 ; coerce byte to word
- move.b (a0),d2 ; d2.w = pun that dev belongs to
- move.w d2,cpun ; cpun = pun(dev)
-
- lea xst,a1 ; a1 -> drive existence table
- tst.b (a1,d1.w) ; does drive exist?
- bne.s bpbgo ; if it does, go on normally
- ; else, see if it really doesn't exist
- movem.l d1/a0,-(sp) ; save registers
- move.w d2,-(sp) ; physical unit number
- bsr _untrdy ; verify by doing test unit ready
- addq.l #2,sp ; cleanup stack
- movem.l (sp)+,d1/a0 ; restore registers
- tst.w d0 ; return good status?
- beq badbpb ; if yes, ie. medium has not changed
- ; therefore, dev still doesn't exist
- moveq #1,d0 ; else medium may have changed
- bsr s_mc_xst ; set mcflgs and xst flags to 1's
- ; and go try to get BPB
- bpbgo: move.l _dskbufp,pbuf ; pbuf -> 2nd half of 1K disk buf
- add.l #512,pbuf
-
- bpb00: move.l a0,-(sp) ; save ptr to pun(dev)
- move.w cpun,-(sp) ; physical unit number
- addq.w #2,(sp) ; unit # including A: and B:
- clr.w -(sp) ; from sector 0
- move.w #1,-(sp) ; read in 1 sector
- move.l pbuf,-(sp) ; buffer to read into
- move.w #$a,-(sp) ; in phys mode/ignore media change
- bsr _ahdi_rw ; ahdi_rw($a, pbuf, 1, 0, cpun)
- adda #12,sp
- movea.l (sp)+,a0 ; restore ptr to pun(dev)
- tst d0 ; read successful?
- beq.s bpb0 ; if yes, go on normally
- ; else call up error handler
- bpberr: move.l a0,-(sp) ; save ptr to pun(dev)
- move.w 8(sp),d1 ; a0 = drive # excluding A: and B:
- bsr critic ; call up critical error handler
- move.l (sp)+,a0 ; restore ptr to pun(dev)
- cmpi.l #CRITRETRY,d0 ; retry?
- beq.s bpb00 ; if so, go and try again
- bra badbpb ; else return no BPB
-
- bpb0: move.w cpun,d2 ; d2 = physical unit number of dev
- move.w #0,pbpb ; pbpb = partition # dev corresponds
- bpb1: cmp.b -(a0),d2 ; pun that dev belongs to == (a0)?
- bne.s bpb2
- addq.w #1,pbpb
- bra.s bpb1
-
- bpb2: move.w #MAXNPART,d1 ; do #MAXNPART times
- movea.l pbuf,a0 ; a0 -> beginning of root sector
- cmpi.w #SIG,DOSSIG(a0) ; is root sector in DOS format?
- bne.s bpb3 ; if not, assume it's in GEMDOS format
- bsr dosbpb ; else, handle it the DOS way
- bra.s bpb4 ; else, go get the bpb
- bpb3: move.w #1,bfat ; 16 bit FAT always for GEMDOS
- bsr gembpb ; handle it the GEMDOS way
- bpb4: tst.w d0 ; successful?
- beq.s bpbnf ; if =0, no valid BPB found
- bpl.s bpb5 ; if +ive, valid BPB found
- bra.s badbpb ; else no BPB found
- ; partition not found
- bpbnf: lea xst,a0 ; a0 -> drive existence table
- move.w 4(sp),d0 ; d0 = dev number
- clr.b (a0,d0.w) ; dev definitely does not exist
- lea mcflgs,a0 ; a0 -> mcflgs table
- move.b #2,(a0,d0.w) ; set as medium has changed
- bra.s badbpb ; can't find such a partition
-
- bpb5: move.l d1,-(sp) ; start_sector
- move.w 8(sp),-(sp) ; dev number
- bsr getbpb ; getbpb(dev, start_sector)
- addq.l #6,sp ; clean up stack
- tst.l d0 ; getbpb successful?
- bpl.s retbpb ; if so, return ptr to bpb
- badbpb: moveq #0,d0 ; return no bpb found
- retbpb: rts
-
-
- ;
- ;+
- ; dosbpb - find the DOS partition that corresponds to the requested
- ; logical drive
- ; Passed:
- ; a0 = buffer address for root sector
- ; d1 = number of entries in partition map
- ;
- ; Assumed:
- ; pbpbs = partition being looked for
- ;
- ; Returns:
- ; d0.b = 0 if partition not found
- ; = negative # some kind of error
- ; = positive # system indicator of the partition
- ; d1.l = starting sector of the partition (if it is found)
- ;-
- dosbpb: adda.w #DOSPM,a0 ; a0 -> partition map
- dbpb0: movem.l d1/a0,-(sp) ; save count and offset
- sf ext ; not dealing with ext partition
- bsr fdpart ; find a partition
- tst.b d0 ; found any?
- beq.s dbpba ; not a valid partition
- cmpi.b #5,d0 ; extended partition?
- bne.s dbpb1 ; if not, it's a regular partition
- st ext ; else, it's an extended partition
- move.l #0,extvol ; offset from start of partition = 0
- move.l d1,extrt ; starting sector # of ext partition
- dbpbx: bsr fdnxt ; find next logical drive
- tst.b d0 ; found any?
- beq.s dbpba ; no logical drive found
- bmi.s dbpb2 ; error returned
- cmpi.b #5,d0 ; extended volume?
- beq.s dbpbx ; if so, go find next logical drive
- dbpb1: subq.w #1,pbpb ; partition that we want?
- bpl.s dbpb3 ; if not, continue the search
- dbpb2: addq.l #8,sp ; else clean up stack
- move.w #0,bfat ; assume partition has 12-bit fat
- cmpi.b #1,d0 ; 12-bit fat?
- beq.s dbpb22 ; if so, return
- move.w #1,bfat ; else bflag = 1 for 16-bit fat
- dbpb22: bra.s dbpbr ; and return
- dbpb3: tst.b ext ; clun is in ext partition?
- bne.s dbpbx ; if so, go find next ext vol
- dbpba: movem.l (sp)+,d1/a0 ; restore count and offset
- adda #16,a0 ; index to next entry in pmap
- dbra d1,dbpb0
- moveq #0,d0 ; partition not found!
- dbpbr: rts
-
-
- ;+
- ; fdpart - find a DOS partition.
- ;
- ; Passed:
- ; a0 = address to partition entry
- ;
- ; Returns:
- ; d0.b = 0 partition is not valid
- ; = positive # partition is a valid partition
- ; (this is the system indicator of the partition)
- ; d1.l = starting sector # of a valid partition (if d0.b = 1 or 4)
- ; = starting sector # of extended partition (if d0.b = 5)
- ;-
- .globl fdpart
- fdpart: tst.l 12(a0) ; partition's size?
- beq.s fdp0 ; if =0, not valid
-
- move.b 4(a0),d0 ; d0 = system indicator
- beq.s fdpr ; if =0, not valid
-
- cmpi.b #4,d0 ; if =4, valid
- beq.s fdp1
-
- cmpi.b #1,d0 ; if =1, valid
- beq.s fdp1
-
- cmpi.b #5,d0 ; if =5, valid
- beq.s fdp1
-
- fdp0: moveq #0,d0 ; else, not valid
- bra.s fdpr
-
- fdp1: move.l 8(a0),d1 ; d1.l = swapped starting sector #
- ror.w #8,d1 ; swap hi and lo byte of high word
- swap d1 ; swap hi and lo word
- ror.w #8,d1 ; swap hi and lo byte of low word
- fdpr: rts
-
-
- ;+
- ; fdnxt - find a logical drive in the extended DOS partition
- ;
- ; Passed:
- ; d0.b = (= 5 if a new extended volume was found)
- ; (= 0 if nxtdrv was successful for last logical drive found)
- ; d1.l = starting sector # of this extended volume
- ; d2.b = count down for logical drive entries (if d0.b != 5)
- ; a0.l = address of partition entry to be checked (if d0.b != 5)
- ;
- ; Assumes:
- ; cpun = current physical unit #
- ; extrt = starting sector # of extended DOS partition
- ; extvol = offset from start of extended DOS partition (in sectors)
- ;
- ; Returns:
- ; d0.b = 0 no logical drive found
- ; = positive # valid logical drive found
- ; (this is the system indicator of the logical drive)
- ; = negative # error occured
- ; d1.l = starting sector # of the logical drive (if d0.b = 1 or 4)
- ; = starting sector # of next extended volume (if d0.b = 5)
- ;-
- .globl fdnxt
- fdnxt: cmpi.b #5,d0 ; new extended volume found?
- bne.s fdnxt0 ; if not, search for one
- move.l d1,-(sp) ; from beginning of extended volume
- move.w cpun,-(sp) ; physical unit number
- addq.w #2,(sp) ; unit # including A: and B:
- move.w #-1,-(sp) ; using a long sector number
- move.w #1,-(sp) ; read in 1 sector
- move.l _dskbufp,-(sp) ; buffer to read into
- move.w #$a,-(sp) ; read in physical mode/ignore media change
- bsr _ahdi_rw ; ahdi_rw($a, buf, 1, -1, cpun, lsectno)
- adda #16,sp ; cleanup stack
- tst.w d0 ; read successful?
- bne fdnxtr ; if not, return
-
- movea.l _dskbufp,a0 ; else,
- cmpi.w #SIG,DOSSIG(a0) ; boot record valid?
- bne.s fdnxtr ; if not, return no drive found
- ; (d0 already set by ahdi_rw)
- adda.w #DOSPM-16,a0 ; a0 -> 1st entry in log drive map
- move.w #MAXNPART+1,d2 ; d2 = count for # of log drive entries
-
- fdnxt0: subq.w #1,d2 ; more entries to search?
- bmi.s fdnxt1 ; if not, return
-
- adda #16,a0 ; a0 -> entry to be examined
- tst.l 12(a0) ; partition size's?
- beq.s fdnxt0 ; if =0, not valid
-
- move.b 4(a0),d0 ; d0 = system indicator
- beq.s fdnxt0 ; if =0, not valid
-
- move.l 8(a0),d1 ; d1.l = logical start sector of drv or vol
- beq.s fdnxt0 ; if =0, not valid
- ror.w #8,d1 ; swap hi and lo byte of high word
- swap d1 ; swap hi and lo word
- ror.w #8,d1 ; swap hi and lo byte of low word
-
- cmpi.b #4,d0 ; if =4,
- beq.s fdnxt2 ; valid logical drive found
-
- cmpi.b #1,d0 ; if =1,
- beq.s fdnxt2 ; valid logical drive found
-
- cmpi.b #5,d0 ; if =5, valid ptr to next ext volume
- bne.s fdnxt0 ; else, not valid
- move.l d1, extvol ; offset of ext vol from start of ext DOS
- bra.s fdnxt3
-
- fdnxt1: moveq #0,d0 ; return no drive found
- bra.s fdnxtr
-
- fdnxt2: add.l extvol,d1 ; d1 = start sector wrt beginning of ext DOS
- fdnxt3: add.l extrt,d1 ; d1 = start sector wrt beginning of disk
- fdnxtr: rts
-
-
- ;
- ;+
- ; gembpb - find the GEMDOS partition that corresponds to the requested
- ; logical drive.
- ; Passed:
- ; a0 = buffer address for root sector
- ; d1 = number of entries in partition map
- ;
- ; Assumed:
- ; pbpbs = partition being looked for
- ;
- ; Returns:
- ; d0.b = 0 if partition not found
- ; = negative # some kind of error
- ; = positive # system indicator of the partition
- ; d1.l = starting sector of the partition (if it is found)
- ;-
- gembpb: adda.w #HDSIZ,a0 ; a0 -> hard disk size
- tst.l (a0)+ ; size? (a0 -> start of pmap)
- beq.s gbpb4 ; if =0, no drive will exist
- gbpb0: movem.l d1/a0,-(sp) ; save count and offset
- sf ext ; not dealing with ext partition
- bsr fgpart ; find partitions
- tst.b d0 ; found any?
- beq.s gbpba ; not a valid partition
- cmpi.b #'X',d0 ; extended partition?
- bne.s gbpb1 ; if not, it's a regular partition
- st ext ; else, it's an extended partition
- move.l #0,extvol ; offset from start of partition = 0
- move.l d1,extrt ; starting sector # of ext partition
- gbpbx: bsr fgnxt ; find next logical drive
- tst.b d0 ; found any?
- beq.s gbpba ; no logical drive found
- bmi.s gbpb2 ; error returned
- cmpi.b #'X',d0 ; extended volume?
- beq.s gbpbx ; if so, go find next logical drive
- gbpb1: subq.w #1,pbpb ; partition that we want?
- bpl.s gbpb3 ; if not, continue the search
- gbpb2: addq.l #8,sp ; else BINGO! Clean up stack
- bra.s gbpbr ; and return
- gbpb3: tst.b ext ; clun is in ext partition?
- bne.s gbpbx ; if so, go find next ext vol
- gbpba: movem.l (sp)+,d1/a0 ; restore count and offset
- adda #12,a0 ; index to next entry in pmap
- dbra d1,gbpb0
- gbpb4: moveq #0,d0 ; partition not found!
- gbpbr: rts
-
-
- ;+
- ; fgpart - find a GEMDOS partition.
- ;
- ; Passed:
- ; a0 = address to partition entry
- ;
- ; Returns:
- ; d0.b = 0 partition is not valid
- ; = positive # partition is a valid partition
- ; (this is the first byte in p_id of the partition)
- ; d1.l = starting sector # of a valid partition (if d0.b = 'G' or 'B')
- ; = starting sector # of extended partition (if d0.b = 'X')
- ;-
- .globl fgpart
- fgpart: tst.b (a0) ; check the valid partition flag
- beq.s fgp2 ; if =0, not valid
-
- tst.l 8(a0) ; partition's size?
- beq.s fgp2 ; if =0, not valid
-
- cmpi.b #'G',1(a0) ; must find GEM as type
- bne.s fgp0 ; for REGULAR partition
- cmpi.b #'E',2(a0) ; (ie., partition < 16Mb)
- bne.s fgp0
- cmpi.b #'M',3(a0)
- beq.s fgp3
-
- fgp0: cmpi.b #'B',1(a0) ; must find BGM as type
- bne.s fgp1 ; for BIG partition
- cmpi.b #'G',2(a0) ; (ie., partition >= 16Mb)
- bne.s fgp1
- cmpi.b #'M',3(a0)
- beq.s fgp3
-
- fgp1: cmpi.b #'X',1(a0) ; or find XGM as type
- bne.s fgp2 ; for EXTENDED GEMDOS
- cmpi.b #'G',2(a0) ; partition
- bne.s fgp2 ; (ie., partition with
- cmpi.b #'M',3(a0) ; a linked list of
- beq.s fgp3 ; logical drives)
-
- fgp2: moveq #0,d0 ; else, not valid
- bra.s fgpr
-
- fgp3: move.l 4(a0),d1 ; d1.l = starting sector #
- move.b 1(a0),d0 ; d0.b = first byte of p_id
- fgpr: rts
-
-
- ;+
- ; fgnxt - find a logical drive in the extended GEMDOS partition
- ;
- ; Passed:
- ; d0.b = (= 'X' if a new extended volume was found)
- ; (= 0 if nxtdrv was successful for last logical drive found)
- ; d1.l = starting sector # of this extended volume
- ; d2.b = count down for logical drive entries (if d0.b != 'X')
- ; a0.l = address of partition entry to be checked (if d0.b != 'X')
- ;
- ; Assumes:
- ; cpun = current physical unit #
- ; extrt = starting sector # of extended GEMDOS partition
- ; extvol = offset from start of extended GEMDOS partition (in sectors)
- ;
- ; Returns:
- ; d0.b = 0 no logical drive found
- ; = positive # valid logical drive found
- ; (this is the first byte of p_id of the logical drive)
- ; = negative # error occured
- ; d1.l = starting sector # of the logical drive (if d0.b = 'G' or 'B')
- ; = starting sector # of next extended volume (if d0.b = 'X')
- ;-
- .globl fgnxt
- fgnxt: cmpi.b #'X',d0 ; new extended volume found?
- bne.s fgnxt0 ; if not, search for one
- move.l d1,-(sp) ; from beginning of extended volume
- move.w cpun,-(sp) ; physical unit number
- addq.w #2,(sp) ; unit # including A: and B:
- move.w #-1,-(sp) ; using a long sector number
- move.w #1,-(sp) ; read in 1 sector
- move.l _dskbufp,-(sp) ; buffer to read into
- move.w #$a,-(sp) ; read in physical mode/ignore media change
- bsr _ahdi_rw ; ahdi_rw($a, buf, 1, -1, cpun, lsectno)
- adda #16,sp ; cleanup stack
- tst.w d0 ; read successful?
- bne fgnxtr ; if not, return error
-
- movea.l _dskbufp,a0 ; a0 -> partition map
- adda.w #HDSIZ+4-12,a0 ; a0 -> 1st entry in log drive map
- move.w #MAXNPART+1,d2 ; d2 = count for # of log drive entries
-
- fgnxt0: subq.w #1,d2 ; more entries to search?
- bmi.s fgnxt3 ; if not, return
-
- adda #12,a0 ; a0 -> entry to be examined
- tst.l 8(a0) ; partition size's?
- beq.s fgnxt0 ; if =0, not valid. Try next entry
-
- tst.b (a0) ; check the valid partition flag
- beq.s fgnxt0 ; if =0, not valid. Try next entry
-
- move.l 4(a0),d1 ; d1.l = logical start sector of drv or vol
-
- cmpi.b #'G',1(a0) ; must find GEM as type
- bne.s fgnxt1 ; for REGULAR partition
- cmpi.b #'E',2(a0) ; (ie., partition < 16Mb)
- bne.s fgnxt1
- cmpi.b #'M',3(a0)
- beq.s fgnxt4
-
- fgnxt1: cmpi.b #'B',1(a0) ; must find BGM as type
- bne.s fgnxt2 ; for BIG partition
- cmpi.b #'G',2(a0) ; (ie., partition >= 16Mb)
- bne.s fgnxt2
- cmpi.b #'M',3(a0)
- beq.s fgnxt4
-
- fgnxt2: cmpi.b #'X',1(a0) ; or find XGM as type
- bne.s fgnxt3 ; for EXTENDED GEMDOS
- cmpi.b #'G',2(a0) ; partition
- bne.s fgnxt3 ; (ie., partition with
- cmpi.b #'M',3(a0) ; a linked list of
- bne.s fgnxt0 ; logical drives)
-
- move.l d1, extvol ; offset of ext vol from start of ext GEMDOS
- bra.s fgnxt5
-
- fgnxt3: moveq #0,d0 ; return no drive found
- bra.s fgnxtr
-
- fgnxt4: add.l extvol,d1 ; d1 = start sector wrt beginning of ext DOS
- fgnxt5: add.l extrt,d1 ; d1 = start sector wrt beginning of disk
- move.b 1(a0),d0 ; d0.b = first byte of p_id
- fgnxtr: rts
-
-
- ;
- ;+
- ; getbpb(dev, sectorno)
- ; WORD dev; 4(sp).w
- ; LONG sectorno; 6(sp).l
- ;
- ; Assume -
- ; cpun contains physical unit number of dev
- ;-
- getbpb: move.l $6(sp),-(sp) ; sector # of boot sector
- move.w cpun,-(sp) ; physical unit
- addq.w #2,(sp) ; unit # including A: and B:
- move.w #-1,-(sp) ; using a long sector number
- move.w #1,-(sp) ; 1 sector
- move.l _dskbufp,-(sp) ; buffer
- move.w #$a,-(sp) ; read in physical mode/ignore media change
- bsr _ahdi_rw ; ahdi_rw(8, buf, 1, -1, cpun, lsectno)
- adda #16,sp ; clean up stack
- tst.w d0 ; successful?
- beq.s getb0 ; if so, go on normally
- ; else let user retry
- getb9: move.w 4(sp),d1 ; d1 = drive # excluding A: and B:
- bsr critic
- cmpi.l #CRITRETRY,d0 ; retry?
- bne getb7 ; if not, return
- bra.s getbpb ; else read again
-
- getb0: movea.l _dskbufp,a0 ; a0 -> boot sector image
- movea.l #bpbs,a2 ; a2 -> bpb
-
- move.w #$0b,d0
- bsr getlhw
- cmp.w maxssz,d0 ; is sector size too big?
- bhi getb7 ; if it is, can't handle it
- move.w d0,(a2)+ ; =byt/sec
- beq getb7 ; if =0, bad data
- move.w d0,d1 ; d1 = logical sector size
- moveq #9,d2 ; d0.b = (log : phys) sector size ratio
- lsr.w d2,d0 ; = logical sector size / 512
- move.w d0,sizr ; save the ratio
-
- clr.w d0
- move.b $d(a0),d0
- move.w d0,(a2)+ ; = #sectors/cluster
- beq getb7 ; if =0, bad data
-
- mulu d1,d0
- move d0,(a2)+ ; = #bytes/cluster
-
- moveq #$11,d0
- bsr getlhw ; number of directory entries
- tst d0 ; num o' entries ?= 0
- beq getb7 ; if so, bad data
- lsl.l #5,d0 ; size root dir = (32 * num entries) bytes
- divu d1,d0 ; number of sectors required
- move.l d0,d1
- swap d1
- tst d1
- beq.s getb1
- addq #1,d0 ; round up
- getb1: move d0,(a2)+ ; =rdlen
- move d0,d2
-
- move #$16,d0
- bsr getlhw
- move d0,(a2)+ ; =FATsize
- beq getb7 ; if =0, bad data
- move d0,d1
- move d0,fsiz ; save FAT size
-
- move #$e,d0
- bsr getlhw ; number of reserved sectors
- add d1,d0
- move d0,(a2)+ ; =2nd FAT start
- move d0,fatrec ; save 2nd FAT start
-
- add d1,d0 ; plus size of second fat
- add d2,d0 ; plus rdlen
- move d0,(a2)+ ; = data start
- move d0,d2 ; save start of data
-
- move #$13,d0
- bsr getlhw ; number of sectors on media
- sub d2,d0 ; subtract # used by FATs,dir,boot
- beq getb7 ; if =0, bad data
- clr.l d1
- move d0,d1
- clr d0
- move.b $d(a0),d0 ; number of sectors/cluster
- divu d0,d1 ; rounding down
- move d1,(a2)+ ; =number of clusters
- move bfat,(a2) ; =flags, 12 or 16 bit fats
-
- move.w sizr,d2 ; d2 = current sector size ratio
- lea sratio,a1 ; a1 -> sector size ratio table
- move.w 4(sp),d0 ; d0 = drive number
- move.b d2,(a1,d0.w) ; update sector size ratio in table
-
- btst.b #6,cpun+1 ; is unit removable?
- beq getb6 ; if not, can skip the fat checksum
-
- lea serno,a1 ; a1 -> table of serial #s
- mulu.w #SERLEN,d0 ; dev# * SERLEN to index into table
- adda.l d0,a1 ; a1 -> serial # of dev
- move.w #SERLEN-1,d1 ; length of serial # - 1
- getb2: move.b $8(a0,d1.w),(a1,d1.w) ; update serial # of dev
- dbra d1,getb2
-
- lea fatsum,a2 ; a2 -> FAT check sum table
- moveq #0,d0 ; coerce to long
- move.w 4(sp),d0 ; d0 = dev number
- lsl.l #FATLEN,d0 ; d0 << FATLEN = to index into table
- adda.l d0,a2 ; a2 -> FAT check sum tbl of dev
-
- move.w fatrec,d0 ; d0 = log starting sector of 2nd FAT
- mulu d2,d0 ; (in 512-byte sectors)
- movea.l $6(sp),a1 ; a1 = starting sector of drive
- adda.l d0,a1 ; a1 = phys starting sector of 2nd FAT
-
- move.w fsiz,d1 ; d1 = # FAT sectors to read
- subq.l #1,d1 ; = FAT size - 1
-
- getb3: move.w sizr,d2 ; d2 = count per FAT sector
- subq.w #1,d2
- clr.l temp ; initialize the sum
- getb4: movem.l d1-d2/a0-a2,-(sp) ; save registers
- move.l a1,-(sp) ; from sector a1
- move.w cpun,-(sp) ; physical unit
- addq.w #2,(sp) ; unit # including A: and B:
- move.w #-1,-(sp) ; using a long sector number
- move.w #1,-(sp) ; read 1 phys sector
- move.l a0,-(sp) ; buffer (in _dskbufp)
- move.w #$a,-(sp) ; read in physical mode/ignore media change
- bsr _ahdi_rw ; ahdi_rw($a, buf, 1, -1, cpun, lsecno)
- adda #16,sp ; clean up stack
- movem.l (sp)+,d1-d2/a0-a2 ; restore registers
- tst.w d0 ; read successful?
- beq getb5 ; if so, go on normally
- ; else let user retry
- getba: movem.l d1-d2/a0-a2,-(sp) ; save registers
- move.w 24(sp),d1 ; d1 = drive # excluding A: and B:
- bsr critic ; critical error handler
- movem.l (sp)+,d1-d2/a0-a2 ; restore registers
- cmpi.l #CRITRETRY,d0 ; retry?
- beq.s getb4 ; if so, try again
- bra getb7 ; else return
-
- getb5: bsr bsum ; add up values in the sector
- addq #1,a1 ; get ready for next sector
- dbra d2,getb4 ; until one logical FAT sector is done
-
- bsr csum ; find the checksum
- move.b d0,(a2)+ ; update checksum for this FAT sector
- dbra d1,getb3 ; until all sectors are checked
-
- getb6: move.w $4(sp),d0 ; d0 = dev number
- lea mcflgs,a0 ; load address of mcflgs table
- clr.b (a0,d0.w) ; clear mcflg for dev
-
- lea xst,a0 ; a0 -> drive existence table
- move.b #2,(a0,d0.w) ; dev definitely exists
-
- lea fatst,a0 ; a0 -> FAT start sector table
- asl.w #1,d0 ; offset = dev# * 2 (tbl of words)
- move fatrec,(a0,d0.w); update FAT starting sect#
-
- lea fatend,a0 ; a0 -> FAT end sector table
- move.w fatrec,d1 ; d1 = fatend(dev)
- add.w fsiz,d1 ; = fatrec + fsiz - 1
- subq.w #1,d1
- move.w d1,(a0,d0.w) ; fatend(dev) = fatrec + fsiz - 1
-
- lea start,a0 ; a0 -> beginning of start table
- asl.w #1,d0 ; offset = dev# * 2 * 2 (tbl of longs)
- move.l $6(sp),(a0,d0.w); update starting sect# of dev
-
- move.l #bpbs,d0 ; no errors, return ptr to BPB
- bra.s getb8 ; return
-
- getb7: moveq #-1,d0 ; error
- getb8: rts
-
-
- ;+
- ; WORD getlhw(d0=offset)
- ; returns word (low,high) from 0(D0,A0)
- ;-
- .globl getlhw
- getlhw: move d1,-(sp) ; preserve d1
- move.b 1(a0,d0.w),d1
- lsl.w #8,d1
- move.b 0(a0,d0.w),d1
- move d1,d0
- move (sp)+,d1
- rts
-
-
- ;+
- ; bsum
- ;
- ; Passed:
- ; a0 = starting address of buffer to be summed
- ; temp.l = current sum
- ;
- ; Function:
- ; - sum up 512 bytes of a buffer 4 bytes at a time
- ; - save the sum in temp.l
- ;
- ; Algorithm for check summing the FAT:
- ; - add up bytes in the buffer 4 bytes at a time (in bsum)
- ; - if the sum is non-zero, XOR the high word (in csum)
- ; with the low word of the 4-byte result
- ; - now take this 2-byte result, and XOR its high (in csum)
- ; byte with its low byte to get the final 1-byte
- ; result
- ;-
- bsum: movem.l d1/a0,-(sp) ; save d1, a0
- move.l temp,d0 ; d0 = current sum
- move #127,d1 ; count
- bsum0: add.l (a0)+,d0 ; add 4 bytes to sum
- dbra d1,bsum0 ; until all bytes are added
- move.l d0,temp ; temp.l = new sum
- movem.l (sp)+,d1/a0 ; restore d1, a0
- rts
-
-
- ;+
- ; csum
- ; (a) XOR the high word with the low word of temp.l
- ; (b) then XOR the high byte with the low byte of result of (a)
- ;
- ; Returns:
- ; d0.b = checksum
- ;-
- csum: move.w temp+2,d0 ; d0.w = low word of result
- eor.w d0,temp ; exclusive-or low and high word
- move.b temp+1,d0 ; d0.b = low byte of xor-ed result
- eor.b d0,temp ; exclusive-or low and high byte
- move.b temp,d0
- rts ; d0.b = checksum
-
-
- ;
- ;+
- ; Read/Write sectors
- ;
- ; Synopsis: _ahdi_rw(rw, buf, count, recno, dev, lrecno)
- ; WORD rw 4(sp).w ; non-zero -> write
- ; char *buf 6(sp).l
- ; WORD count $a(sp).w
- ; WORD recno $c(sp).w
- ; WORD dev $e(sp).w
- ; LONG lrecno $10(sp).l ; optional
- ;-
-
- ; stack frame offsets
- xrw equ 8
- xbuf equ 10
- xcount equ 14
- xrecno equ 16
- xdev equ 18
- xlrecno equ 20
-
- .globl _sasi_rw
- .globl _ahdi_rw
- _sasi_rw:
- _ahdi_rw:
- link a6,#0 ; create a frame pointer
- subq.w #2,xdev(a6) ; drive # excluding A: and B:
-
- move.w xdev(a6),d0 ; d0 = device number
- btst.b #3,xrw+1(a6) ; is this a physical operation?
- beq.s getcpun ; if not, find physical unit number
- move.w d0,cpun ; else, dev# passed is phys unit #
- ;+
- ; Aug-08-91 ml. The following line trashed the sizr set up
- ; by the logical mode rwabs() which calls the
- ; physical mode rwabs() recursively.
- ; move.w #1,sizr ; sector size ratio = 1
- ;-
-
- bra ahrw1 ; go start the r/w
- getcpun: ; map log -> phys unit number
- lea pun,a0 ; a0 -> pun table
- move.b (a0,d0.w),cpun+1 ; cpun = pun of dev
-
- lea sratio,a0 ; a0 -> sector size ratio table
- move.b (a0,d0.w),sizr+1 ; sizr = current sector size ratio
- ; (coerced to word)
- lea start,a0 ; a0 -> start table
- move.w d0,d1 ; d1 = drive #
- add.w d1,d1 ; d1*2*2 (index into tbl of longs)
- add.w d1,d1
- move.l (a0,d1.w),cstart ; cstart = dev starting sector
-
- btst.b #1,xrw+1(a6) ; ignore media change?
- bne ahrw1 ; if yes, go ahead and do r/w
- ; else check for media change
- lea mcflgs,a0 ; a0 -> mcflgs of drive
- move.b (a0,d0.w),d0 ; d0 = mcflg of dev
- beq ahrw1 ; if media not changed, go do r/w
-
- cmpi.b #2,d0 ; is media definitely changed?
- beq retmc ; if yes, return media has changed
- ; else, check if media has changed
- ; try to read dev's boot sector
- chkmc: move.l cstart,-(sp) ; dev starting sector
- move.w cpun,-(sp) ; physical unit number
- addq.w #2,(sp) ; unit # including A: and B:
- move.w #-1,-(sp) ; using a long sector number
- move.w #1,-(sp) ; 1 sector
- move.l _dskbufp,-(sp) ; buffer
- move.w #$a,-(sp) ; phys mode and no media change error
- bsr _ahdi_rw ; ahdi_rw($a, buf, 1, -1, cpun, sectno)
- adda #16,sp ; clean up stack
- tst.w d0 ; read successful?
- beq.s chkser ; yes, go check serial number
-
- move.w xdev(a6),d1 ; device number
- bsr critic ; call critical error handler
- cmpi.l #CRITRETRY,d0 ; is it the magic RETRY code?
- beq.s chkmc ; if yes, go back and try it
- bra ahrw7 ; else return
-
- chkser: lea serno,a1 ; a1 -> serial #s table
- move.w xdev(a6),d0 ; d0 = dev number
- mulu.w #SERLEN,d0 ; *SERLEN for index into table
- adda.l d0,a1 ; a1 -> serial # of dev
-
- move.l _dskbufp,a2 ; a2 -> boot sector
- addq.w #8,a2 ; a2 -> serial # in boot sector
- move.w #SERLEN-1,d0 ; d0 = count for comparison
- cmpser: cmpm.b (a2)+,(a1)+ ; serial # read ?= serial # recorded
- bne ismc ; if not, media has changed
- dbra d0,cmpser ; compare next byte of serial #
- ; serial # hasn't changed, try FAT
- moveq #0,d1 ; coerce to long
- move.w xdev(a6),d1 ; d0 = dev number
- lea fatsum,a1 ; a1 -> fat checksum table
- lsl.l #FATLEN,d1 ; d1.w = index into table
- adda.l d1,a1 ; a1 -> fat checksum of dev
-
- add.w d0,d0 ; d0*2 = index into table of words
- lea fatst,a2 ; a2 -> FAT start table
- move.w (a2,d0.w),fatrec ; fatrec = fatst(dev)
-
- lea fatend,a2 ; a2 -> FAT end table
- move.w (a2,d0.w),d1 ; d1 = counter to scan FAT table
- sub.w fatrec,d1 ; = fatend(dev) - fatst(dev)
-
- movea.l cstart,a2 ; a2 = start sector of dev
- move.w fatrec,d2 ; d2 = fatst(dev)
- mulu sizr,d2 ; d2 = fatst(dev) in 512-byte sector
- adda.l d2,a2 ; a2 = phys start sector of 2nd FAT
-
- movea.l _dskbufp,a0 ; a0 -> dskbuf
- cmpfat: move.w sizr,d2 ; d2 = # reads per FAT sector
- subq.w #1,d2 ; d2 - 1 = counter
- clr.l temp ; initialize sum
- cfat0: movem.l d1-d2/a0-a2,-(sp) ; save d1, d2, a0, a1, a2
- ; try to read this FAT sector
- move.l a2,-(sp) ; at sector a2
- move.w cpun,-(sp) ; physical unit number
- addq.w #2,(sp) ; unit # including A: and B:
- move.w #-1,-(sp) ; using a long sector number
- move.w #1,-(sp) ; 1 sector
- move.l a0,-(sp) ; buffer
- move.w #$a,-(sp) ; phys mode and no media change error
- bsr _ahdi_rw ; ahdi_rw($a, buf, 1, -1, cpun, sectno)
- adda #16,sp ; clean up stack
- movem.l (sp)+,d1-d2/a0-a2 ; restore d1, d2, a0, a1, a2
- tst.w d0 ; read successful?
- beq.s chkfat ; if yes, go check sum FAT sectors
- ; else assume it's read error
- movem.l d1-d2/a0-a2,-(sp) ; save registers d1, d2, a0, a2
- move.w xdev(a6),d1 ; drive number
- bsr critic
- movem.l (sp)+,d1-d2/a0-a2 ; restore registers d1, d2, a0, a2
- cmpi.l #CRITRETRY,d0 ; is it the magic RETRY code?
- beq.s cfat0 ; if yes, go back and try it
- bra ahrw7 ; else return
-
- chkfat: bsr bsum ; if ok, sum the sector
- addq #1,a2 ; ready for try next sector
- dbra d2,cfat0 ; until one FAT sector is summed
-
- bsr csum ; find the checksum
- cmp.b (a1)+,d0 ; checksum recorded ?= checksum found
- bne ismc ; if not, media has changed
- dbra d1,cmpfat ; until all sectors are checked
-
- lea mcflgs,a0 ; a0 -> mcflgs table
- adda.w xdev(a6),a0 ; a0 -> mcflg of drive
- clr.b (a0) ; clear mcflg for dev
-
- ahrw1: tst.w xcount(a6) ; any sector to r/w?
- beq ahrw6 ; if =0, done
-
- cmpi.w #-1,xrecno(a6) ; does recno = -1?
- bne.s ahrw2 ; if not, we have a word record #
- movea.l xlrecno(a6),a1 ; a1.l = start record #
- bra.s ahrw3
- ahrw2: moveq #0,d0 ; coerce to long
- move.w xrecno(a6),d0 ; d0.l = recno
- movea.l d0,a1 ; a1.l = start record #
-
- ahrw3: move.l a1,strec ; save first sector to r/w
- move.l a1,d1 ; d1.l = starting sector to r/w
- moveq #0,d2 ; coerce to long
- move.w xcount(a6),d2 ; d2.l = #sectors to r/w
- adda.l d2,a1 ; a1.l = last sector to r/w
- subq.l #1,a1 ; = first sector + count - 1
- move.l a1,endrec ; save last sector to r/w
- move.l xbuf(a6),stbuf ; save starting buffer address
-
- btst.b #3,xrw+1(a6) ; physical operation?
- bne.s ahrw4 ; if so, ready to r/w
- ; else log -> phys sector mapping
- mulu sizr,d1 ; d1.l = phys start sector to r/w
- add.l cstart,d1 ; = dev start sect + sect #
- mulu sizr,d2 ; d2.l = # phys 512-byte sects to r/w
-
- ahrw4: move.w xdev(a6),-(sp) ; device # (excluding A: and B:)
- move.l d1,-(sp) ; starting sector
- move.l d2,-(sp) ; count (in sectors)
- move.l xbuf(a6),-(sp) ; buffer
- move.w xrw(a6),-(sp) ; read write flag
- bsr _do_rw ; do the read or write
- adda #16,sp ; clean up stack
- tst.l d0 ; successful?
- beq.s chkwr ; if so, go on to wrap up
-
- cmpi.l #E_CHNG,d0 ; media change detected?
- bne ahrw7 ; if not, give up
- btst.b #3,xrw+1(a6) ; is this a physical operation?
- bne ahrw7 ; if so, return media change error
- bra chkmc ; and go check if media has changed
- ; check if wrote to boot sector
- chkwr: move.w xrw(a6),d0 ; d0 = r/w and flags word
- btst #0,d0 ; read or write?
- beq ahrw6 ; if read, done
- btst.b #6,cpun+1 ; is drive removable?
- beq ahrw6 ; if not, done
- btst #3,d0 ; was it a physical operation?
- bne ahrw6 ; if it was, done
- tst.l strec ; wrote to boot sector?
- bne.s wrfat ; if not, check if wrote to FATs
- lea mcflgs,a0 ; else, a0 -> mcflgs table
- adda.w xdev(a6),a0 ; a0 -> dev's mcflg
- move.b #2,(a0) ; assume medium has changed
- ; check if wrote to FATs
- wrfat: lea fatend,a0 ; a0 -> fatend table
- move.w xdev(a6),d0 ; d0 = device number
- add.w d0,d0 ; d0*2 = index into table of words
- moveq #0,d1 ; coerce to long
- move.w (a0,d0.w),d1 ; d1 = last sector of last FAT
- cmp.l strec,d1 ; wrote beyond the last FAT?
- blt ahrw6 ; if so, done
-
- lea fatst,a0 ; a0 -> fatst table
- moveq #0,d2 ; coerce to long
- move.w (a0,d0.w),d2 ; d2 = first sector of last FAT
- cmp.l endrec,d2 ; wrote before the last FAT?
- bgt ahrw6 ; if so, done
- ; else update FAT sector checksums
- move.l stbuf,a0 ; a0 -> buffer w/ written data
- lea fatsum,a1 ; a1 -> start of fatsum table
- moveq #0,d0 ; coerce to long
- move.w xdev(a6),d0 ; d0 = dev number
- lsl.l #FATLEN,d0 ; d0 = offset to dev's FAT chksum
- adda.l d0,a1 ; a1 -> dev's first FAT chksum
- move.l strec,d0 ; d0 = first sector wrote to
- sub.l d2,d0 ; d0 = strec - start(last FAT)
- beq.s wrfat2 ; if strec = start(last FAT),
- ; no adjustments needed
- blt.s wrfat1 ; if strec < start(last FAT)
- ; begin from start(last FAT)
- move.l strec,d2 ; else begin from strec
- adda.l d0,a1 ; a1 -> fatsum to be updated
- bra.s wrfat2
-
- wrfat1: neg.l d0 ; d0 = index into stbuf
- asl.l #8,d0 ; = (start(last FAT) - strec)*512
- add.l d0,d0
- adda.l d0,a0 ; a0 -> addr of buf for update
-
- wrfat2: cmp.l endrec,d1 ; if end(last FAT) <= endrec
- ble.s wrfat3 ; stop at end(last FAT)
- move.l endrec,d1 ; else stop at endrec
-
- wrfat3: sub d2,d1 ; d1 = # sectors to be processed
- wrfat4: move.w sizr,d2 ; d2 = # phys sect per log sect
- subq.w #1,d2 ; dbra likes one less
- clr.l temp ; initialize sum
- wrfat5: bsr bsum ; sum up one 512-byte sector
- adda.l #512,a0 ; point to next 512 bytes
- dbra d2,wrfat5 ; until one logical sector is done
- bsr csum ; obtain checksum
- move.b d0,(a1)+ ; record new fat checksum
- dbra d1,wrfat4 ; do until all are updated
-
- ahrw6: clr.l d0 ; got here with no errors!
- bra.s ahrw7
-
- ismc: lea mcflgs,a0 ; a0 -> mcflgs table
- adda.w xdev(a6),a0 ; a0 -> dev's mcflg
- move.b #2,(a0) ; set mcflg for dev to has changed
- lea xst,a0 ; a0 -> drive existence table
- adda.w xdev(a6),a0 ; a0 -> xst flag of dev
- move.b #2,(a0) ; assume dev exists
- retmc: move.l #E_CHNG,d0 ; yes, return media change error
-
- ahrw7: btst.b #0,xrw+1(a6) ; read or write?
- bne.s ahrwd ; if write, done
- tst.b _cachexst ; does a cache exist?
- beq.s ahrwd ; if not, done
- ; else dump the cache
- move.l d0,-(sp) ; save the status
- move sr,-(sp) ; go to IPL 7
- ori #$700,sr ; no interrupts right now kudasai
- movecacrd0 ; d0 = (cache control register)
- ori.w #$808,d0 ; dump both the D and I cache
- moved0cacr ; update cache control register
- move (sp)+,sr ; restore interrupt state
- move.l (sp)+,d0 ; restore the return value
-
- ahrwd: unlk a6
- rts
-
-
- ;+
- ; smove() - Copy unaligned sectors (this is *supposed* to be slow!)
- ;
- ; Passed:
- ; d0 = # of sectors to be moved
- ; d1 = size of operation (0 - byte; 2 - long;)
- ; a2 -> source buffer
- ; a1 -> dest buffer
- ;
- ; Trashes: d0, a1, a2
- ;-
- smove: move.w d1,-(sp) ; save size of operation
- neg.w d1 ; d0 = count
- addi.w #9,d1 ; = (# sectors * 512) >> op size
- asl.w d1,d0 ;
- subq.w #1,d0 ; dbra likes one less
- move.w (sp)+,d1 ; restore operation size
- bne.s smove2 ; if non-zero, use move longs
-
- smove1: move.b (a2)+,(a1)+
- dbra d0,smove1
- rts
-
- smove2: move.l (a2)+,(a1)+
- dbra d0,smove2
- rts
-
-
- ;
- ;+
- ; _do_rw - called to read/write no more than 128K to an even boundary
- ;
- ; Passed:
- ; rw 4(sp).w ; non-zero -> write
- ; buf 6(sp).l
- ; count $a(sp).l ; in # phys (512-byte) sectors
- ; recno $e(sp).l ; physical starting sector for r/w
- ; dev $12(sp).w ; log dev # exluding A: and B:
- ;
- ; Assumes:
- ; cpun = current physical unit to r/w
- ; if in logical mode, cstart = physical starting sector # of curr dev
- ;
- ; Mar-05-1990 ml.
- ; All I/O to ACSI and SCSI non-accessible memory will be done by
- ; using the fast ram buffer (if there is one) or the diskbuf as an inter-
- ; mediate stop for the transfer.
- ;
- ; Mar-07-1990 ml.
- ; Do not have to take care of cases when Rwabs() is supplied with
- ; a buffer that would cross different kinds of memory.
- ; ("It's deadly!" said AKP. :) )
- ;
- ; Aug-19-1991 ml.
- ; On the TT, ACSI accessible RAM upper limit is 10Mb instead of
- ; 4Mb.
- ;
- ; ACSI accessible memory: (on ST) $00000000 -> $003fffff
- ; $ff000000 -> $ff3fffff
- ; (on TT) $00000000 -> $009fffff
- ; $ff000000 -> $ff9fffff
- ; SCSI non-accessible memory
- ; on the TT: $c0000000 -> $fcffffff
- ; $fe000000 -> $feffffff
- ;-
- yrw equ $8
- ybuf equ $a
- ycount equ $e
- yrecno equ $12
- ydev equ $16
-
- ; Memory that ACSI _can_ DMA to
- STDUAL equ $003fffff ; upper limit of dual-purpose RAM on an ST
- STCMPIH equ $ff3fffff ; upper limit of compatible image on an ST
- TTDUAL equ $009fffff ; upper limit of dual-purpose RAM on a TT
- TTCMPIH equ $ff9fffff ; upper limit of compatible image on a TT
- SPDUAL equ $00dfffff ; upper limit of dual-purpose RAM on a Sparrow
- SPCMPIH equ $ffdfffff ; upper limit of compatible image on a Sparrow
- CMPIL equ $ff000000 ; lower limit of compatible image for all
-
- ; Memory that SCSI _cannot_ DMA to (non-DW)
- A32D16L equ $c0000000 ; lower limit of A32:D16 Memory/Peripherals
- A32D16H equ $fcffffff ; upper limit of A32:D16 Memory/Peripherals
- VA24D16 equ $fe000000 ; lower limit of VMEbus A24:D16
- VA16D16 equ $feffffff ; upper limit of VMEbus A16:D16
-
- ; Cookies
- _FRB equ $5f465242 ; _FRB
-
- _do_rw: link a6,#0 ; create a frame pointer
- move.l ycount(a6),d2 ; d2.l = # sectors requested to r/w
- movea.l ybuf(a6),a1 ; a1.l = buffer addr to r/w
- btst.b #4,cpun+1 ; talking IDE?
- bne atrw0 ; if yes, go for it
- btst.b #3,cpun+1 ; else talking SCSI?
- beq.s acrw0 ; if not, talking ACSI
- tst.b _spscsixst ; if so, talking Sparrow SCSI?
- beq scrw0 ; if not, it's regular SCSI
- ; else, it's Sparrow SCSI
- cmp.l #MAXSPSECTS,d2 ; more than one DMAful?
- bls.s acrw1 ; if not, go check boundary
- move.l #MAXSPSECTS,d2 ; else set count to r/w only 1 DMAful
- bra.s acrw1
-
- acrw0: cmp.l #MAXACSECTS,d2 ; more than one DMAful?
- bls.s acrw1 ; if not, go check boundary
- move.l #MAXACSECTS,d2 ; else set count to r/w only 1 DMAful
- acrw1: btst.b #0,ybuf+3(a6) ; buffer on odd boundary?
- bne.s itrw0 ; if so, do intermediate transfer
-
- cmpi.l #TT,machine ; is driver running on a TT?
- bne.s acrw2 ; if not, go on
- ; else check against TT limits
- cmpa.l #TTDUAL,a1 ; buf within ACSI accessible memory?
- bls rw1 ; if so, go ahead with the I/O
- cmpa.l #CMPIL,a1 ; else, do intermediate transfer
- bcs.s itrw0
- cmpa.l #TTCMPIH,a1
- bls rw1
- bra itrw0
-
- acrw2: cmpi.l #SPARROW,machine ; is driver running on a Sparrow?
- bne.s acrw3 ; if not, assume it's an ST or STE
-
- cmpa.l #SPDUAL,a1 ; buf within ACSI accessible memory?
- bls rw1 ; if so, go ahead with the I/O
- cmpa.l #CMPIL,a1 ; else, do intermediate transfer
- bcs.s itrw0
- cmpa.l #SPCMPIH,a1
- bls rw1
- bra.s itrw0
- ; driver is running on ST or STE
- acrw3: cmpa.l #STDUAL,a1 ; buf within ACSI accessible memory?
- bls rw1 ; if so, go ahead with the I/O
- cmpa.l #CMPIL,a1 ; else, do intermediate transfer
- bcs.s itrw0
- cmpa.l #STCMPIH,a1
- bls rw1
- ; doing intermediate transfer
- itrw0: moveq #0,d1 ; assume moving 1 byte at a time
- btst.b #0,ybuf+3(a6) ; odd boundary?
- bne.s itrw1 ; if so, assumption ok
- moveq #2,d1 ; else move 1 long at a time
-
- itrw1: tst.l frbbuf ; is there a fast RAM buffer?
- bne.s itrw2 ; if there is one, use it
- ; else look for _FRB
- move.l d1,-(sp) ; save d1
- move.l #frbbuf,-(sp) ; pointer to fast RAM buffer
- move.l #_FRB,-(sp) ; looking for _FRB cookie
- bsr _getcookie ;
- addq.w #8,sp ; clean up stack
- move.l (sp)+,d1 ; restore d1
- tst.w d0 ; found _FRB?
- bne.s itrw2 ; if so, use it
- ; else use dskbuf
- movea.l _dskbufp,a1 ; a1 -> dskbuf
- cmpi.w #2,d2 ; can only do 2 at a time tops
- bls.s itrw3
- move.w #2,d2
- bra.s itrw3
-
- itrw2: movea.l frbbuf,a1 ; use the Fast RAM Buffer
- cmpi.w #RAMRSV,d2 ; can only do RAMRSV at a time tops
- bls.s itrw3
- move.w #RAMRSV,d2
-
- itrw3: btst.b #0,yrw+1(a6) ; is this a read?
- beq.s rw1 ; if so, go fill buffer from disk
- ; else fill buffer here
- move.l a1,-(sp) ; preserve a1 = dest
- movea.l ybuf(a6),a2 ; a2 = source
- move.w d2,d0 ; # sectors to be moved
- bsr smove ; move sectors from a2 to a1
- movea.l (sp)+,a1 ; restore a1.l = dest
- bra.s rw1 ; go do the r/w
-
- scrw0: cmpi.l #MAXSCSECTS,d2 ; more than one SCSI DMAful?
- bls.s scrw1 ; if not, ready to r/w
- move.l #MAXSCSECTS,d2 ; r/w only one SCSI DMAful?
-
- scrw1:
-
- .if SCDMA ; if doing SCSI DMA
- .if !SCFRDMA ; if no SCSI DMA to fast RAM
- cmpi.b #$01,ybuf(a6) ; is destination buffer in fast RAM?
- beq itrw0 ; if so, do intermediate transfer
- .endif ;!SCFRDMA
-
- cmpa.l #A32D16L,a1 ; buf in SCSI non-accessible
- bcs.s rw1 ; memory?
- cmpa.l #A32D16H,a1 ; if so, do intermediate transfer
- bls itrw0 ; else, go ahead with the I/O
- cmpa.l #VA24D16,a1
- bcs.s rw1
- cmpa.l #VA16D16,a1
- bls itrw0
- .endif ;SCDMA
-
- bra.s rw1
-
- atrw0: cmp.l #MAXIDESECTS,d2 ; more than one IDE gulp?
- bls.s atrw1 ; if not, check boundary
- move.l #MAXIDESECTS,d2 ; else, r/w only one IDE gulp
- atrw1: btst.b #0,ybuf+3(a6) ; buffer on odd boundary?
- bne itrw0 ; if so, do intermediate transfer
- ; else ready for r/w
- rw0: movea.l ybuf(a6),a1 ; a1 = buffer address for r/w
- rw1: move.w _retries,retrycnt ; setup retry counter
-
- btst.b #2,yrw+1(a6) ; are retries disabled?
- beq.s rw2 ; no, act normally
- move.w #0,retrycnt ; yes, so set retrycnt to zero
-
- rw2: movem.l d1-d2/a1,-(sp) ; preserve d1, d2 and a1
- move.w cpun,-(sp) ; dev.w
- move.l a1,-(sp) ; buf.l
- move.w d2,-(sp) ; count.w
- move.l yrecno(a6),-(sp) ; sect.L
-
- btst.b #4,cpun+1 ; talking IDE?
- bne.s rwide ; if so, do IDE r/w
- ; else it's ACSI or SCSI
- cmpi.l #MAXACSECTS,d2 ; more than hr/w can handle?
- bhi.s rw4 ; if so, use extended call (SCSI only)
- btst.b #0,yrw+1(a6) ; read or write?
- bne.s rw3 ; (write)
- bsr _hread ; read sectors
- bra rw6
- rw3: bsr _hwrite ; write sectors
- bra.s rw6
- rw4: btst.b #0,yrw+1(a6) ; read or write?
- bne.s rw5 ; (write)
- bsr _xtdread ; read sectors
- bra.s rw6
- rw5: bsr _xtdwrt ; write sectors
- bra.s rw6
-
- rwide: lea idedp,a0 ; a0 -> drive param structure
- move.w 2(a0),-(sp) ; # physical sectors per track
- move.w (a0),-(sp) ; # data heads
- btst.b #0,yrw+1(a6) ; read or write?
- bne.s rwide2 ; (write)
- bsr _ideread ; read sectors
- bra.s rwide3
- rwide2: bsr _idewrite ; write sectors
- rwide3: addq #4,sp ; (cleanup stack)
- rw6: adda #12,sp ; (cleanup stack)
- movem.l (sp)+,d1-d2/a1 ; restore d1, d2 and a1
- tst.l d0 ; errors?
- beq rwf ; no error --> successful
- bmi.s rw9 ; timed out --> retry
-
- movem.l d1-d2/a1,-(sp) ; preserve d1, d2 and a1
- move.w yrw(a6),-(sp) ; rwflag
- bsr errcode ; find error code
- addq #2,sp ; clean up stack
- movem.l (sp)+,d1-d2/a1 ; restore d1, d2 and a1
-
- cmpi.l #E_CHNG,d0 ; media change detected?
- bne.s rw7 ; if not, fine
- ; else record media may be changed
- move.b #1,d0 ; d0.b = 1 (may be changed)
- bsr s_mc_xst ; set mcflgs and xst flags for all dev
-
- btst.b #1,yrw+1(a6) ; ignore media change?
- bne rw2 ; if so, retry operation
- bra rwr ; else return
-
- rw7: cmpi.l #EWRPRO,d0 ; write protect error?
- beq.s rwa ; if so, return error
- cmpi.l #EDRVNR,d0 ; drive not ready?
- beq.s rwa ; if so, return error
-
- rw9: subq.w #1,retrycnt ; drop retry count and retry
- bpl rw2
-
- rwa: btst.b #3,yrw+1(a6) ; is this a physical operation?
- bne rwr ; if so, exit
- ; else call critical error handler
- movem.l d1-d2/a1,-(sp) ; preserve d1, d2 and a1
- move.w ydev(a6),d1 ; d1 = drive number
- rwe: bsr critic
- movem.l (sp)+,d1-d2/a1 ; restore d1, d2 and a1
- cmpi.l #CRITRETRY,d0 ; is it the magic RETRY code?
- beq rw2 ; if yes, go retry
- bra.s rwr ; else, head home
-
- rwf: lea rw0,a0 ; exec of next r/w starts at rw0
- cmpa.l ybuf(a6),a1 ; was alternate buffer used?
- beq.s rw10 ; if not, go on to next r/w
- ; else take care of transfer
- lea itrw3,a0 ; exec of next r/w starts at itrw3
- btst.b #0,yrw+1(a6) ; was it a write?
- bne.s rw10 ; if it was, go on to next write
- ; else move data to supplied buffer
- move.l a1,-(sp) ; save address of alternate buffer
- movea.l a1,a2 ; a2 = address of alternate buffer
- movea.l ybuf(a6),a1 ; a1 = address of supplied buffer
- move.w d2,d0 ; d0 = # of sectors to move
- bsr smove ; move data from alt buf to sup buf
- move.l (sp)+,a1 ; restore address of alternate buffer
-
- rw10: sub.l d2,ycount(a6) ; ycount(a6) = # sects left to be done
- beq.s rwd ; if no more left, done
- ; else get ready for next r/w
- add.l d2,yrecno(a6) ; yrecno(a6) = next starting sector
- move.l d2,d0 ; d0 = # bytes done
- asl.l #8,d0 ; = # sectors done * 512
- add.l d0,d0 ;
- add.l d0,ybuf(a6) ; buf += (sectors_done * sector size)
- cmp.l ycount(a6),d2 ; amount to r/w > amount doable?
- bls.s rw11 ; if so, r/w amount doable
- move.l ycount(a6),d2 ; else r/w all of it
- rw11: jmp (a0) ; go on to next r/w
-
- rwd: moveq #0,d0 ; got here with no errors!
- rwr: unlk a6 ; head home
- rts
-
-
- ;
- ;+
- ; Check for media change on hard disk
- ; Synopsis: _sasi_mediach(dev)
- ; WORD dev; 4(sp).w
- ;
- ; Returns: 0L - media definitely has not changed
- ; 1L - media _may_ have changed
- ; 2L - media definitely has changed
- ;
- ; Uses: d0, d1, a0, a1
- ;
- ; Comments:
- ; Apr-4-1989 ml. Add in grace period between _sasi_mediach()s.
- ; If _sasi_mediach() was called less than 1 s
- ; (200 _hz_200 clock ticks) ago, and medium was
- ; not changed then, assume medium still has not
- ; changed.
- ;-
- _sasi_mediach:
- subq.w #2,4(sp) ; dev # excluding drv A and B
- move.w 4(sp),d1 ; d1 = current drive
- lea mcflgs,a0 ; a0 = pointer to mcflgs
- moveq #0,d0 ; d0 = mcflg for current drive
- move.b (a0,d1.w),d0
- tst.b d0 ; has medium changed?
- bne.s decided ; if yes or maybe, return result
- ; else verify that it has not
- move.l lastmdctm,d2 ; time media change was last called
- cmp.l _hz_200,d2 ; while (_hz_200 <= lastmdctm)
- bcc.s decided ; assume medium not changed
-
- lea pun,a1 ; ptr to beginning of pun table
- move.b (a1,d1.w),cpun+1 ; cpun = pun current drive belongs to
-
- btst.b #6,cpun+1 ; is pun removable?
- beq.s notchngd ; if not, medium has not changed
-
- move.w cpun,-(sp) ; physical unit number
- bsr _untrdy ; verify by doing test unit ready
- addq.l #2,sp
- move.l _hz_200,lastmdctm ; update time for last _sasi_mediach()
- addi.l #200,lastmdctm ;
- tst.w d0 ; return good status?
- beq.s notchngd ; if yes, return medium not changed
- moveq #1,d0 ; else return medium may have changed
- bsr s_mc_xst ; set mcflgs and xst flags to 1's
- bra.s decided
- notchngd:
- moveq #0,d0 ; return medium has not changed
- decided:
- rts
-
-
- ;+
- ; s_mc_xst - set mcflgs and drive existence flags
- ; for drives belonging to the current
- ; physical unit to value passed
- ;
- ; Passed: d0.b - value to set to
- ;-
- s_mc_xst:
- movem.l d1-d2/a0-a2,-(sp) ; save registers
- lea pun,a0 ; a0 -> pun table
- lea mcflgs,a1 ; a1 -> mcflgs table
- lea xst,a2 ; a2 -> drive existence table
- move.w cpun,d1 ; d1 = current physical unit #
- moveq #0,d2 ; d2 = logical drive #; index into tables
- set0: btst.b #7,(a0,d2.w) ; a valid logical drive?
- bne.s setr ; if not, done
- cmp.b (a0,d2.w),d1 ; else, does it belong to this physical unit?
- bne.s set1 ; if not, move on to next logical drive
- move.b d0,(a1,d2.w) ; else change its mcflg to value passed
- move.b d0,(a2,d2.w) ; and change its xst to value passed
- set1: addq.w #1,d2 ; try next one in forward direction
- cmp.w #MAXLOG,d2 ; all units checked?
- blt.s set0 ; if not, go on
- setr: movem.l (sp)+,d1-d2/a0-a2 ; else restore registers
- rts ; and return
-
-
- ;
- ;+
- ; Resident Installer
- ;-
- .globl i_sasi6
- i_sasi6:
- tst.b idexst ; IDE bus exists?
- beq.s calcmem ; if not, go calculate memory size
- cmpi.l #SPARROW,machine ; is driver running on a Sparrow?
- beq.s calcmem
- ; move.b #$10,d0 ; does IDE #0 exists?
- ; bsr _drvxst
- ; beq.s calcmem ; if not, go calculate memory size
- ; else
- move.w ideidle,idesd ; init current IDE spin down timeout
- beq.s calcmem ; if 0, don't set it
- move.w ideidle,-(sp) ; else set default time out
- move.w #$10,-(sp) ; IDE unit #0
- bsr _awto ; set up idle time out
- addq #4,sp ; clean up stack
-
- ;+
- ; 02-Apr-1991 ml. The following is illegal, because i_sasi1 is
- ; external.
- ; move.l #(i_sasi1-i_sasi),tokeep ; at least keep this much
- ;-
- calcmem:
- move.l #i_sasi1,tokeep ; tokeep = amount of code to be kept
- subi.l #i_sasi,tokeep
- cmpi.w #512,maxssz ; maxssz > 512 bytes?
- bls.s nboot1 ; if not, no need to replace GEMDOS buffers
- ; else check if there is enough memory for
- chkmem: bsr chklstmem ; new GEMDOS buffer lists
- tst.l d0 ; enough?
- bpl.s okbig ; if so, build the list
- move.w defbigsect,d0 ; d0 = minimum big sector
- cmp.w maxssz,d0 ; is maxssz >= minimum big sector?
- bcc.s regsect ; if so, give up
- move.w d0,maxssz ; else try minimum big sector
- bra.s chkmem
- regsect:
- move.w #512,maxssz ; will not handle big sectors
- bra.s nboot1
-
- okbig: move.l d1,tokeep ; update amount of memory to be kept
- lea i_sasi1,a0 ; a0 -> beginning of new buffer lists
- moveq #3,d1 ; d1 = count = 4 buffers - 1
- bsr list_init ; initialize the buffer list
- clr.l (a0,d0.w) ; cut 1 list of 4 buffers to 2 lists of 2
- move.l a0,_bufl ; _bufl[0] -> 1st new buffer list
- add.l d0,d0 ; d0 = offset to beginning of 2nd buffer list
- adda.l d0,a0 ; a0 = head of 2nd buffer list
- move.l a0,_bufl+4 ; _bufl[1] -> 2nd new buffer list
-
- nboot1: bsr pool_install ; attempt to install more OS pool
- add.l d0,tokeep ; update amount of memory to be kept
-
- ;+
- ; Aug-15-91 ml. Check for existence of _FRB when needed instead of
- ; at boot time.
- ;
- ; clr.l frbbuf ; assume no _FRB
- ; move.l #frbbuf,-(sp) ; pointer to fast RAM buffer
- ; move.l #$5f465242,-(sp) ; cookie "_FRB"
- ; bsr _getcookie ; try to find _FRB in cookie jar
- ; addq.w #8,sp ; clean up stack
- ;-
-
- move.l _hz_200,lastmdctm ; initialize media change time
- tst.w bootloaded ; if bootloaded, then already in super mode
- bne.s nboot2 ; (already there)
- move.l savssp,-(sp) ; become a mild mannered user process
- move.w #$20,-(sp) ; Super(savssp)
- trap #1
- addq.w #6,sp
-
- ;+
- ; Terminate and stay resident;
- ; installed driver under GEMDOS.
- ;-
- move.l tokeep,d0 ; compute value for Ptermres()
- add.l #$0100,d0 ; for basepage
- move.l d0,-(sp) ; save D0
- movea.l #msg_nbl,a0 ; print not bootloaded message
- bsr prnstr
- move.l (sp)+,d0
- move.w #0,-(sp) ; exit code
- move.l d0,-(sp)
- move.w #$31,-(sp) ; terminate and stay resident
- trap #1 ; should never come back...
- illegal
-
-
- ;+
- ; Return to TOS ROMs
- ; - set default boot device to C:
- ; - Print silly message
- ; - Mshrink() memory that was alloc'd to us
- ; - set magic# in D7 for TOS ROMs
- ; - RTS back to ROMs
- ;-
- nboot2: move.l tokeep,d0 ; compute value for Mshrink
- add.l #$1c,d0 ; for file header
- move.l d0,-(sp) ; save D0
- movea.l #msg_bl,a0 ; print bootloaded message
- bsr prnstr
-
- move.w d4,d1 ; physical unit # in d4.w?
- bpl.s bd0 ; if so, good
- ; else it's in hi 3 bits of d7.b
- move.b d7,d1 ; d1.b = physical unit # boot loaded from
- lsr.b #5,d1 ; = xxx00000 >> 5
- bd0: lea pun,a0 ; a0 -> pun table
- moveq #0,d2 ; d2 = boot dev
- bd1: move.b (a0,d2.w),d0 ; d0.b = unit #
- andi.b #$1f,d0 ; mask out flags
- cmp.b d0,d1 ; d2 belongs to physical unit booted from?
- beq.s bd2 ; if yes, set (d2) as boot device
- addq.w #1,d2 ; else try next logical unit
- bra.s bd1
- bd2: addq.w #2,d2 ; offset for drive A and B
- move.w d2,_bootdev ; set default boot device to (d2)
-
- move.l baseaddr,-(sp)
- clr.w -(sp)
- move.w #$4a,-(sp) ; Mshrink(...)
- trap #1
- adda #12,sp ; (cleanup stack)
-
- move.w _bootdev,-(sp) ; set boot dev as default drive
- move.w #$e,-(sp) ; Dsetdrv(_bootdev)
- trap #1
- addq.w #4,sp ; cleanup stack
-
- move.l #rootpath,-(sp) ; set root as current directory
- move.w #$3b,-(sp) ; Dsetpath('\')
- trap #1
- addq.w #6,sp ; cleanup stack
- ;
- ; move.l _sysbase,a0 ; get the system header address
- ; move.l $18(a0),d0 ; d0.l = MMDDYYYY of ROM date
- ; swap d0 ; d0.l = YYYYMMDD of ROM date
- ; cmp.l #CHKDATE,d0 ; does this version of ROM need bootstop?
- ; bcs.s stopall ; yup, if OS is built before 4/22/87
- ; move.b puns+1,d7 ; else prevent processed units from booting
- ; subq.b #1,d7 ; unit # = # of units - 1
- ; lsl.b #5,d7
- ; rts ; return to TOS ROMs
- ;
- ; Stop ANY subsequent boot after the hard disk boot -- FOR NOW!!
- ;
-
- stopall:
- move.b #$100-$20,d7 ; prevent any other unit from booting
- rts ; return to TOS ROMs
-
- rootpath:
- dc.b '\\',0
- msg_bl:
- dc.b '-----------------------',13,10
- dc.b 'BOOTLOADED',13,10,0
- msg_nbl:
- dc.b '-----------------------',13,10
- dc.b 'NOT Bootloaded',13,10,0
- .even
-
-
- ;+
- ; list_init - Initialize a GEMDOS buffer list (BCBs are contiguous)
- ;
- ; Passed:
- ; a0.l = head of buffer list (not changed)
- ; d0.l = size of each BCB (including data block) (not changed)
- ; d1.w = count
- ; = number of buffers to be installed to the list - 1
- ;
- ; Uses:
- ; d1, a1
- ;-
- list_init:
- move.l a0,-(sp) ; save head of buffer list
- lin0: movea.l a0,a1 ; a1 -> next BCB
- adda.l d0,a1 ; -> curr BCB + size of BCB
- move.l a1,(a0) ; b_link -> next BCB
- move.w #-1,4(a0) ; b_neg1 = -1
- adda.w #BCBLEN,a0 ; a0 -> BCB data block
- move.l a0,-4(a0) ; b_bufr -> b_space
- movea.l a1,a0
- dbra d1,lin0
- suba.l d0,a0 ; a0 -> last BCB
- clr.l (a0) ; lastBCB.b_link = NULL
- move.l (sp)+,a0 ; restore head of buffer list
- rts
-
-
- ;+
- ; chklstmem - check if enough memory is allocated to replace GEMDOS
- ; buffer lists
- ;
- ; Returns:
- ; d0.l = size of each BCB (including data block)
- ; or -1 if not enough memory is allocated
- ; d1.l = new amount of memory to be kept if enough is allocated
- ;
- ; Uses:
- ; d0, d1
- ;-
- chklstmem:
- moveq #BCBLEN,d0 ; d0.l = size of each BCB (inc. data block)
- add.w maxssz,d0 ; = BCB header len + data block size
- move.l d0,d1 ; d1.l = d0.l * 4
- lsl.l #2,d1 ; = total size of buffer lists
- add.l tokeep,d1 ; d1.l = size needed
- cmp.l memalloc,d1 ; enough memory allocated?
- bls.s chk0 ; if so return
- moveq #-1,d0 ; else return error
- chk0: rts
-
-
- ;
- ;+
- ; critic - call up the critical error handler.
- ;
- ; Passed:
- ; d0.w = error code
- ; d1.w = drive # excluding A: and B:
- ;
- ; Uses:
- ; d0, d1, a0
- ;
- ; Returns:
- ; d0.l = whatever returned by the critical handler
- ; (magic RETRY code or something)
- ;-
- critic: addq.w #2,d1 ; drive # including A: and B:
- move.w d1,-(sp) ; drive #
- move.w d0,-(sp) ; error code
- movea.l etv_critic,a0 ; a0 = address of error handler
- jsr (a0) ; critic_handler(error, drive)
- addq.l #4,sp ; clean up stack
- rts ; return
-
-
- ;+
- ; errcode - For ACSI or SCSI drives, find error code for previous
- ; Check Condition Status, and translate controller error
- ; code into BIOS error code.
- ; - For IDE-IDE drives, test for error bits, and translate
- ; error bits into BIOS error code.
- ;
- ; Passed:
- ; d0.b = value of Status register (IDE drive ONLY)
- ; 4(sp).w = rwflag (bit 0 not set -> read; bit 0 set -> write)
- ;
- ; Assumed:
- ; cpun = current physical unit number
- ;
- ; Returns:
- ; d0.l = BIOS error code
- ;
- ; Sep-13-1989 ml. For non-extended request sense, ask for 0 byte.
- ; (0 is default to return 4 bytes.)
- ; Aug-19-1991 ml. Moved translation of controller error code into
- ; BIOS error code from _ahdi_rw() to here.
- ;-
- .globl errcode
- errcode:
- btst.b #4,cpun+1 ; an IDE unit?
- bne.s ideerr ; if so, handle it the IDE way
- ; else it's ACSI or SCSI
- moveq #22,d1 ; assume requesting extended sense
- move.w cpun,d0 ; d0 = physical unit number
- btst #3,d0 ; a SCSI unit?
- bne.s err0 ; if so, ready to request
- andi.w #07,d0 ; else mask off other flags
- btst.b d0,embscsi ; an embedded SCSI unit using ACSI?
- bne.s err0 ; if so, request extended sense
- moveq #0,d1 ; else request non-extended sense
- err0: lea sendata,a0 ; a0 -> sense data buffer
- movem.l d1/a0,-(sp) ; save data len and buffer address
- move.l a0,-(sp) ; sense data buffer
- move.w d1,-(sp) ; data length (in bytes)
- move.w d0,-(sp) ; physical unit number
- bsr _rqsense ; find out error code
- addq.l #8,sp ; clean up stack
- movem.l (sp)+,d1/a0 ; restore d1 and a0
- tst.w d0 ; successful?
- beq.s err1 ; if not, return
- moveq #-1,d0 ; error occurred
- rts
- err1: cmpi.w #4,d1 ; extended or non-extended?
- bgt.s err2 ; if extended, go get code
- move.b (a0),d1 ; else byte 0 = error code
- andi.b #$7f,d1 ; mask off valid bit
- bra.s err3
- err2: move.b 12(a0),d1 ; else byte 12 = error code
-
- err3: cmpi.b #MDMCHGD,d1 ; is it media change detected?
- bne.s err4 ; if not, check further
- move.l #E_CHNG,d0 ; else return media change error
- bra.s errend
-
- err4: cmpi.b #WRTPRTD,d1 ; is it write protect error?
- bne.s err5 ; if not, check further
- move.l #EWRPRO,d0 ; else return write protect error
- bra.s errend
-
- err5: cmpi.b #DRVNRDY,d1 ; is it drive not ready?
- bne.s err7 ; if not, assume read or write fault
- err6: move.l #EDRVNR,d0 ; else return drive not ready error
- bra.s errend
-
- err7: btst.b #0,5(sp) ; read or write?
- bne.s errw ; (write)
- move.l #EREADF,d0 ; return read fault
- bra.s errend
-
- ideerr: btst #DRDY,d0 ; is IDE drive not ready?
- beq.s err6 ; if so, return drive not ready
-
- btst #DWF,d0 ; is it write fault error?
- bne.s err7 ; if not, assume read or write fault
- errw: move.l #EWRITF,d0 ; else return write fault error
- errend: rts
-
-
-
-
- ;
- ;+
- ; OS Pool Expansion
- ;-
-
- .if ospool
- ;+
- ; Wire more pool into various ROM releases.
- ;
- ; Passed: nothing
- ; Returns: D0 = #bytes extra used
- ;-
- pool_install:
- move.l _sysbase,a3 ; a3 -> base of OS
-
- ; make sure we're in ROM,
- ; then get address of RAM location to patch:
-
- cmp.l #$800000,a3 ; better be ROM
- blt notrom
- lea pool_tab(pc),a0 ; a0 -> table to match
- pi_lp: move.l (a0)+,d1 ; d1 = date to match
- beq badrom ; (forget it, end of list)
- move.l (a0)+,a2 ; a2 -> _root address for that date
- cmp.l $18(a3),d1 ; match dates?
- bne.s pi_lp ; (no -- try again)
-
- move.w numchunks,d0 ; d0 = amount of BSS to be used
- mulu #chunksiz,d0 ; = # chunks * size of a chunk
- move.l d0,d1 ; d1 = total memory needed
- add.l tokeep,d1 ; = already keeping + extra OS pool
- cmp.l memalloc,d1 ; enough is allocated?
- bgt.s bdrom2 ; if not, don't add any
- ; else install more OS pool
- movea.l #i_sasi+2,a0 ; a0 -> base of first buffer
- adda.l tokeep,a0 ; = start of file + already keeping
- move.l a0,-(sp) ; save base of first buffer
- move.w numchunks,d1 ; d0 = count-1
- subq.w #1,d1
- pin_1: lea chunksiz(a0),a1 ; a1 -> next buffer
- move.l a1,(a0) ; buffer -> next one
- move.w #chunkno,-2(a0) ; install chunksiz
- move.l a1,a0 ; a0 -> next buffer
- dbra d1,pin_1 ; (do some more)
-
- sub.w #chunksiz,a0 ; a0 -> last block
- move.l chunkno*4(a2),(a0) ; last block -> first in root
- move.l (sp)+,chunkno*4(a2) ; root -> first of ours
- rts ; return OK
-
- ;+
- ; Print warning messages
- ; about bogus versions of the
- ; operating system. Assume that
- ; every OS past 1-May-1986 has the
- ; pool fix installed.
- ;
- ;-
- ok_date = %0000110010100001 ; 1-May-1986
- notrom: lea m_notrom(pc),a0 ; ram-based system (5/29!)
- bra.s bdrom1
- badrom: lea m_badrom(pc),a0 ; illegal ROM system
- bdrom1: cmp.w #ok_date,$1e(a3) ; if ok_date <= os_dosdate(a3)
- bcc bdrom2 ; then don't print anything
-
- move.l a0,-(sp) ; print nasty message
- move.w #9,-(sp)
- trap #1
- addq.l #6,sp
-
- ; print msg and wait for RETURN
- pea keymsg(pc)
- move.w #9,-(sp)
- trap #1
- addq.l #6,sp
-
- bdrom3: move.w #2,-(sp) ; wait for [RETURN]
- move.w #2,-(sp)
- trap #13
- addq.l #4,sp
- cmp.w #13,d0
- bne bdrom3
-
- bdrom2: moveq #0,d0 ; 0 extra bytes used
- rts
-
- keymsg: dc.b 'Hard disk driver not loaded; hit RETURN',13,10
- dc.b 'key to continue:',13,10
- dc.b 0
-
- m_notrom:
- dc.b '*** WARNING ***',13,10,7
- dc.b 'This hard disk driver may not work with',13,10,7
- dc.b 'a disk-based version of TOS; files on',13,10,7
- dc.b 'your hard disk may be damaged.',13,10,7
- dc.b 13,10,7
- dc.b 0
-
- m_badrom:
- dc.b '*** WARNING ***',13,10,7
- dc.b 'You are using an unofficial ROM release',13,10,7
- dc.b 'of the operating system. This driver',13,10,7
- dc.b 'may not work correctly with it. Files',13,10,7
- dc.b 'on your hard disk may be damaged.',13,10,7
- dc.b 13,10,7
- dc.b 0
- even
-
-
- ;+
- ; Table of ROM release dates / _root addresses
- ; update these for new ROM releases that need the patch.
- ;
- ;-
- pool_tab:
- dc.l $11201985,$56fa ; USA and UK, 20-Nov-1985
- dc.l $02061986,$56fa ; Germany, 6-Feb-1986
- dc.l $04241986,$56fa ; France, 24-Apr-1986
- dc.l 0 ; end of list
-
- .endif
-
-
-