Mercurial > hg > Members > kono > nitros9-code
view 3rdparty/drivers/tccc/tccchd.asm @ 749:ec1909ff0764
Updated Makefile
author | boisy |
---|---|
date | Wed, 08 Jan 2003 05:09:53 +0000 |
parents | d76cc2119c4f |
children |
line wrap: on
line source
* TCCCHD: Hard disk driver/scsi host adapter driver for OS9 * Copyright (C) 1990,1991,1992,1993,1994,1995,1996 Robert E. Brose II * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. opt w131 nam Hard Disk driver, flip-flop & latch version. ttl title page * experimental no DP version 9-11-90 ************************************************************** * T C C C (TC^3) * * H A R D D I S K device driver for CoCo OS9 * * written by Robert E. Brose II * * uses Western digital WD 1002-shd or Xebec 5" controller* * host adapter modeled after example in Xebec manual * * Allows use of 2 different drives with separate offsets * * for partitioning (ms 13 bits of 21 bit sector #) * ************************************************************** * * * physical drive number stored in IT.DNS. * * revision history *------------------------------------ * 2.0 Totally revamped * Controller number gotten from the PD (PD.DNS lower 4 bits). * Avoids use of DP, it's faster without it. * Most subroutines moved to inline code to increase speed * Added time slice release if controller is busy 12/01/90 * set blocks in init instead of doing it on every packet 12/01/90 * 2.1 Added adaptec conditional statements 02-23-92 * Uniform descriptors, params adaptec doesn't need are ignored 02-23-92 * 2.2 init/don't init drive, bit 6 of PD.DNS. 1=don't init 1-15-94 * resets drive in setup routine 1-16-94 * locks scsi packet, elims conflict on multiple drives on the same * host adapter. 1-16-94 * altered format to work with seagate drives. 1-16-94 * 5/6.x changed revisn and versn below to match up with this history 1-19-94 * 5.x 256 byte sectors version. * 6.x 1K HD sectors version. 1-19-94 * 5/6.2 added HOG flag for maximum speed, to hog the cpu * 5/6/7/8.3 Added MEDSEC for 512 byte sectors * 5/6/7/8.4 much 6309 optimisation * 9.x Redid version/revision stuff again. Version is now 9, revision * indicates sector size. 6809: 1=256 by/sec 2=512 by/sec 3=1024 by/sec * Nitros 6309 4=256 by/sec 5=512 by/sec 6=1024 by/sec *10.x Changes to allow >1 drive with large sectors. 11-5-94 * UGH removed for now, flush is too complicated with BIGSEC * changed 6309 block moves to I/O to allow for a gap to service serial * interrupts every 256 moves (affects sector sizes >256 bytes). 3-25-95 *11.x Optimizations from better understanding about when the driver can * be interupted, thanks Alan DeKok. 1-7-96 * Handles inits of several scsi id'd devices. 1-7-96 * Fixed Calcsec, logread and logwrit to handle 512 bytes/sector 1-8-96 *12.x Added DISTO HD II support 3-9-96 * notes: sleep causes the only possible reentrant situation (~HOG) * in this case cmd block and cache buffer must be preserved. * To make multiple drives/driver work for 512 and 1024 (BUFSEC) * cases will require info like drive, lun, offset, etc to be * save for the previous sector so a cache flush can be done. YUK! * Added sector 0 cache because rbf accesses it all the darn time! 6-8-96 H6309 equ 1 if 6309 cpu, 0=on! ttl equates DBHS equ 1 data requires req handshake version 0=ON! (i.e. adaptec) BIGSEC equ 1 use 1024 byte physical sectors (0=ON!) MEDSEC equ 0 use 512 byte physical sectors (0=ON!) HOG equ 1 hog the cpu on waits (speeds up disk access 0=ON!) DISTO equ 1 use HD II ports and status bits (0=ON!) MDRIVES equ 1 can use more than 1 drive / driver in BUFSEC case (0=ON!) MPAK equ 1 includes multipak switching code (needed for DISTO w/ MPAK 0=ON!) CANFORM equ 0 drive formatting allowed (0=ON!) CACHE equ 1 sector 0 cache (0=ON!). * BUFSEC below means a buffer is used when reading/writing physical secs * (0=on) ifeq BIGSEC BUFSEC equ $0 m.smask equ %11111100 m.nsmask equ %00000011 else ifeq MEDSEC BUFSEC equ $0 m.smask equ %11111110 m.nsmask equ %00000001 else BUFSEC equ $1 endc endc ifeq H6309 ifeq BIGSEC revisn equ 6 else ifeq MEDSEC revisn equ 5 else revisn equ 4 endc endc else ifeq BIGSEC revisn equ 3 else ifeq MEDSEC revisn equ 2 else revisn equ 1 endc endc endc verson equ 12 numdrvs equ 4 number of drives supported by driver (logical) * status byte mask m.error equ %00000010 error flag * status register bit masks ifeq DISTO m.req equ %10000000 data request line m.busy equ %00000001 busy status line * broken on disto??? m.msg equ %00000100 end of message status line m.msg equ %00000000 end of message status line m.cmd equ %01000000 command/data status line m.in equ %00100000 input/output status line * broken msg on disto ??? m.nnc equ %11100101 unconnected lines = ignore mask m.nnc equ %11100001 unconnected lines = ignore mask else * normal TCCC defs m.req equ %00000001 data request line m.busy equ %00000010 busy status line m.msg equ %00000100 end of message status line m.cmd equ %00001000 command/data status line m.in equ %00010000 input/output status line endc m.phys equ %00100000 physical drive mask (LUN on Controller) m.init equ %01000000 initialize drive on change flag m.cont equ %00001111 controller address mask m.recal equ %00010000 do a recal (home) on 1st drive access m.format equ %10000000 enable format command ifeq MPAK m.mpscs equ %11110000 Mpak slot select SCS clearing mask mpsel equ $FF7F multipak select latch addr, used for disto. EXTPRM equ 25 extra params in descriptor else EXTPRM equ 24 extra params in descriptor endc * input and output ports offsets for HOST ADAPTER bus ifeq DISTO datapo equ 3 read and write data rstpo equ 1 software reset selpo equ 2 controller select statpo equ 1 read status else * Normal TCCC defines datapo equ 0 read and write data rstpo equ 1 software reset selpo equ 2 controller select selrst equ 3 reset of select (scuzzie adapters) statpo equ 1 read status endc * controller opcodes o.ready equ $00 test for drive ready o.param equ $0c set parameters for the drives o.read equ $08 read sector(s) o.write equ $0a write sector(s) o.formt equ $04 format drive o.recal equ $01 recalibrate drive (head to track 0) ifp1 use defsfile endc ttl data allocation org DRVBEG tables rmb DRVMEM*numdrvs reserve space for system tables * command packet for controller packet equ . opcode rmb 1 command opcode lun rmb 1 logical unit number : ms part of lsn lsn rmb 2 logical sector number blocks rmb 1 interleave or block count control rmb 1 control byte set at packet send time plocked rmb 1 above control block in use, locked blocked rmb 1 buffer sector (caching) in use, locked * extra parameters read in from the descriptor. param rmb 8 physical drive 0 params param1 rmb 8 physical drive 1 params * logical drive offsets offsd1 rmb 2 offsd2 rmb 2 offsd3 rmb 2 offsd4 rmb 2 ifeq MPAK * Multipak latch temp storage and slot. mpslot rmb 1 From descriptor, FF = no mpak endc * end of extra params read in from descriptor ifeq MPAK mpstor rmb 1 Current multipak value outside of this driver. endc didflag rmb 1 read lsn 0 flag lastphy rmb 1 last drive accessed (physical) sec0fl rmb numdrvs (recal (home) completed flag) tempw1 rmb 2 word temp var tempw2 rmb 2 word temp var iniflg rmb numdrvs whether or not the device has been initalized ifeq BUFSEC ifeq BIGSEC secbuf rmb 1024 buffer for physical sector else secbuf rmb 512 buffer for physical sector endc ifeq CACHE sec0 rmb 256*numdrvs optional sector 0 cache endc lastdrv rmb 1 last LOGICAL drive accessed lsech rmb 1 24 bit address, sector in buffer (logical w/o least sig 2 bits) lsecm rmb 1 (part of above) lsecl rmb 1 " physech rmb 1 24 bit address, sector in buffer (physical sector in buffer) physecm rmb 1 (part of above) physecl rmb 1 " cached rmb 1 cache is dirty flag secidx rmb 1 index into physical sector endc endmem equ . ttl module entry mod endmod,name,drivr+objct,reent+verson,xferad,endmem mode fcb $ff mode ifeq DISTO ifeq DBHS name fcs "DIDBHS" else ifeq BIGSEC name fcs "DI1024" else ifeq MEDSEC name fcs "DIS512" else name fcs "DISTHD" endc endc endc else ifeq DBHS name fcs "DBHSHD" else ifeq BIGSEC name fcs "TC1024" else ifeq MEDSEC name fcs "TCC512" else name fcs "TCCCHD" endc endc endc endc fcb revisn * rbf dispatch vectors xferad lbra INIT ifeq BUFSEC lbra LOGREAD else bra READ nop endc ifeq BUFSEC bra LOGWRIT else bra WRITE endc nop lbra GETSTA lbra SETSTA lbra TERM ifeq BUFSEC ttl logical sector write * logwrit * * input: * b = msb of os9 lsn * x = lsbs of os9 lsn * y = path descriptor * u = static storage * * output: * 256 bytes moved from the os9 buffer to the physical buffer. Any * necessary physical sector writing and reading is done also. * LOGWRIT ifne HOG pshs u logwr01 tst blocked,u critical lock on this section beq logwr02 because of the buffer pshs b,x ldx #1 os9 F$Sleep wait a while puls b,x bra logwr01 and check again logwr02 com blocked,u set it endc pshs b save HSB tfr x,d msb and lsb into d for manipulation stb secidx,u save lsb for indexing into phys sec buf later andb #m.smask zero indexing bits cmpd lsecm,u lower part of logical sector puls b get back HSB bne diffwr if compare fails, new sector, need preread cmpb lsech,u compare HSB's ifne MDRIVES beq cpysecw ok, in buffer diffwr else bne diffwr failed new sec need preread lda PD.DRV,y current drive cmpa lastdrv,u = last drive? beq cpysecw if same, log sector is in physical buffer diffwr sta lastdrv,u save logical drive for future compare endc tst cached,u need to flush physical sector? beq cleanw no, skip ahead pshs b,x,y,u save new sector ldb physech,u get current HSB ldx physecm,u get current msb & lsb lbsr WRITE do the physical write puls b,x,y,u restore new sector bcs logwre exit on write error cleanw lbsr calcsec pshs y lbsr READ read the physical sector puls y bcs logwre exit on read error cpysecw ldy PD.BUF,y os9 buffer lda secidx,u index into physical buffer anda #m.nsmask mask upper off leax secbuf,u location of physical buffer ldb #128 cpsw2 tsta done calculating index? beq cpsw2b yup, exit loop abx these 2 ins advance 256 bytes into physical buffer abx deca bra cpsw2 cpsw2b clr cached,u com cached,u set cache dirty flag ifeq H6309 cpsw3 ldw #256 bytes to copy tfm y+,x+ else * 16 bit copy, 128 words from os9 buff to phys buff cpsw3 ldu ,y++ get byte from os9 buffer stu ,x++ to phys sector decb bne cpsw3 endc clrb logwre ifne HOG puls u restore static pointer clr blocked,u clear lock on this section endc rts ttl logical sector read * logread * * input: * b = msb of os9 lsn * x = lsbs of os9 lsn * y = path descriptor * u = static storage * * output: * 256 bytes moved from the physical buffer to the os9 buffer. Any * necessary physical sector writing and reading is done first. * LOGREAD ifne HOG pshs u logre01 tst blocked,u critical lock on this section beq logre02 because of the buffer pshs b,x ldx #1 os9 F$Sleep wait a while puls b,x bra logre01 and check again logre02 com blocked,u set lock endc pshs b save HSB tfr x,d msb and lsb into d for manipulation stb secidx,u save lsb for indexing into phys sec buf later andb #m.smask zero indexing bits cmpd lsecm,u lower part of phys sector puls b get back HSB bne diffrd if compare fails, new sector to read cmpb lsech,u compare HSB's ifne MDRIVES beq cpysecr ok, in buffer diffrd else bne diffrd failed new sec need preread lda PD.DRV,y current drive cmpa lastdrv,u = last drive? beq cpysecr if same, log sector is in physical buffer diffrd sta lastdrv,u save logical drive for future compare endc tst cached,u need to flush physical sector? beq cleanr no, skip ahead pshs b,x,y,u save new sector ldb physech,u get current HSB ldx physecm,u get current msb & lsb lbsr WRITE do the physical write puls b,x,y,u restore new sector bcs logrde exit on write error cleanr bsr calcsec pshs y lbsr READ read the physical sector puls y bcs logrde exit on read error cpysecr ldy PD.BUF,y os9 buffer lda secidx,u index into physical buffer anda #m.nsmask mask upper off leax secbuf,u location of physical buffer ldb #128 cpsr2 tsta done calculating index? beq cpsr3 yup, exit loop abx these 2 ins advance 256 bytes into physical buffer abx deca bra cpsr2 ifeq H6309 cpsr3 ldw #256 tfm x+,y+ else * 16 bit copy, 128 words from phys buff to os9 buff cpsr3 ldu ,x++ get byte from phys sec stu ,y++ to os9 buffer decb bne cpsr3 endc clrb logrde ifne HOG puls u restore static pointer clr blocked,u clear lock on this section endc rts * fast calcsec (see comments in 6809 code below) ifeq H6309 calcsec stb lsech,u tfr x,w tfr f,a anda #m.smask sta lsecl,u ste lsecm,u *aim #m.smask,lsecl,u * 4x (256 x 4 =1k sector) or 2x (256 x 2 = 512 sector) ifeq BIGSEC lsrb rorw endc lsrb rorw stb physech,u tfr w,x stx physecm,u rts else calcsec stb lsech,u save logical sec hsb for next compare stb physech,u and in physec for shifting tfr x,d get msb & lsb into d for shifting andb #m.smask strip lower bits lsb sec # std lsecm,u save it for compare std physecm,u as above for shifting lsr physech,u shift 24 bits right 2 bits, converts to physical sec # (1st 8) ror physecm,u (2nd 8) ror physecl,u (3rd 8) * 4x (256 x 4 =1k sector) or 2x (256 x 2 = 512 sector) ifeq BIGSEC lsr physech,u (1st 8, second time) ror physecm,u (2nd 8, second time) ror physecl,u (3rd 8, second time) endc ldx physecm,u for return value ldb physech,u for return value rts endc (H6309) endc (bufsec) ttl write sector * write * * input: * b = msb of lsn * x = lsb's of lsn * y = path descriptor * u = static storage * * output: * b,x,y,u destroyed * 256 bytes written (512/1024 bufsec version) * otherwise, carry set and b = error code * * WRITE ifeq MPAK pshs u need for restore at end of write routine tst mpslot,u multipak in use? (1xxxxxxxb = no) bmi slotw2 hi bit set, skip lda >mpsel get current value sta mpstor,u save it anda #m.mpscs clear scs bits ora mpslot,u add in scs select sta >mpsel put it to mpak slotw2 endc lda #o.write controller write opcode lbsr setup setup packet, initiate command ifeq BUFSEC leax secbuf,u get address of physical sector buffer clr cached,u clear cache dirty flag else ldx PD.BUF,y get buffer address into x endc ldu V.PORT,u leay statpo,U leau datapo,u u points to data port lda #m.req ifeq HOG W0 bita ,y get req bit beq W0 wait till req else W00 clrb 256 tries W0 bita ,y get req bit bne W0B decb bne W0 keep trying lbsr doslp bra W00 endc ifeq DBHS W0B bra W1 first req got already, skip ahead W0C ldb ,y status port bitb #m.req have req? beq W0C wait till we do bitb #m.cmd finished putting data? bne W2A if so, skip ahead W1 lda ,x+ get a byte from memory sta ,u put it to the drive bra W0C go again else * for 6309, use block transfer fixed size. Not really according to scsi * spec, but FAST! ifeq H6309 W0B ifeq BIGSEC ldw #1024 tfm x+,u else ifeq MEDSEC ldw #512 tfm x+,u else ldw #256 tfm x+,u endc endc else ifeq DISTO W0B bra W2 W1 lda ,X+ sta ,U W2 ldb ,Y andb #m.nnc and out the floating bits cmpb #m.req+m.busy still have data? beq W1 yup go for more else W0B ldb #m.req+m.busy status mask for command/data mode bra W2 W1 lda ,X+ sta ,U W2 cmpb ,Y beq W1 endc * didn't work, don't know why. changed to make disto easier *W0B ldb #m.cmd command mode? * bra W2 *W1 LDA ,X+ * STA ,U *W2 BITB ,Y * BEQ W1 not command mode yet, go for more data endc endc ifeq DISTO W2A ldb ,y get status bits andb #m.nnc strip floating bits cmpb #m.req+m.busy+m.cmd+m.in bne W2A lda ,u status data byte W2C ldb ,y get status bits andb #m.nnc strip floating bits cmpb #m.req+m.busy+m.msg+m.cmd+m.in bne W2C else W2A ldb #m.req+m.busy+m.cmd+m.in W2B cmpb ,y get status bne W2B lda ,u status data byte ldb #m.req+m.busy+m.msg+m.cmd+m.in W2C cmpb ,y bne W2C get term byte endc ldb ,u discard anda #m.error isolate error bit beq w3 if no error comb flag error ldb #E$Write error code for OS9 bra w4 w3 clrb flag no errors w4 ifeq MPAK puls u saved at top of routine pshs a,cc lda mpstor,u sta >mpsel restore old mpak slot value puls a,cc endc rts ttl read sector * read * * input: * b = hsb of lsn * x = lsb's of lsn * y = path descriptor * u = static storage * output: * b,x,y destroyed, u preserved * if no error, 256 bytes into sector buffer * otherwise carry set and b = error * * READ ifeq MPAK tst mpslot,u multipak in use? (1xxxxxxxb = no) bmi slotr2 hi bit set, skip change lda >mpsel get current value sta mpstor,u save it anda #m.mpscs clear scs bits ora mpslot,u add in scs select sta >mpsel put it to mpak slotr2 endc tstb hsb = 0 bne rdnot0 no, skip leax ,x msb & lsb =0? bne rdnot0 ifeq BUFSEC lda secidx,u least 2 bits are in here anda #m.nsmask bne rdnot0 endc * first access to drive (implied) so recal the drive to home heads. pshs d,x leax sec0fl,u get flag for this drive lda PD.DRV,y get drive # tst a,x drive LSN0 already read? bne sec0dn yup, skip it com a,x flag recal done now clr didflag,u com didflag,u set disk id sec flag on lda PD.DNS,y anda #m.recal should this drive be homed? beq sec0dn ldx #0 clear sector # back out (B is still clear) lda #o.recal lbsr setup ifeq DISTO recal0 ldb statpo,x (see comments at W2A) andb #m.nnc cmpb #m.req+m.busy+m.cmd+m.in bne recal0 lda datapo,x recal1 ldb statpo,x andb #m.nnc cmpb #m.req+m.busy+m.msg+m.cmd+m.in bne recal1 else ldb #m.req+m.busy+m.cmd+m.in recal0 cmpb statpo,x bne recal0 lda datapo,x ldb #m.req+m.busy+m.msg+m.cmd+m.in recal1 cmpb statpo,x bne recal1 endc lda datapo,x sec0dn puls d,x rdnot0 lda #o.read opcode for read operation lbsr setup setup packet, initiate command ifeq BUFSEC leax secbuf,u physical buffer location clr cached,u else ldx PD.BUF,y setup buffer loc in x endc pshs Y,U ldu V.PORT,u leay statpo,U leau datapo,u lda #m.req wait for data request ifeq HOG R0 bita ,y beq R0 wait for req else R00 clrb 256 tries for req R0 bita ,y bne R0B decb bne R0 keep trying lbsr doslp bra R00 endc ifeq DBHS R0B bra R1 first time have req, skip forward R0C ldb ,y get status bitb #m.req request bit beq R0C no, go again bitb #m.cmd finished with data? bne R2A yes, skip ahead R1 lda ,u get data from the controller sta ,x+ to memory bra R0C go again else R0B * for 6309, use block transfer fixed size. Not really according to scsi * spec, but FAST! ifeq H6309 ifeq BIGSEC ldw #256 orcc #%01010000 tfm u,x+ andcc #%10101111 ldw #256 orcc #%01010000 tfm u,x+ andcc #%10101111 ldw #256 orcc #%01010000 tfm u,x+ andcc #%10101111 ldw #256 orcc #%01010000 tfm u,x+ andcc #%10101111 else ifeq MEDSEC ldw #256 orcc #%01010000 tfm u,x+ andcc #%10101111 ldw #256 orcc #%01010000 tfm u,x+ andcc #%10101111 else ldw #256 orcc #%01010000 tfm u,x+ andcc #%10101111 endc endc else ifeq DISTO bra R2 R1 lda ,U sta ,X+ R2 ldb ,Y andb #m.nnc and out floating bits cmpb #m.in+m.busy+m.req still more data? beq R1 yes, go for more else ldb #m.in+m.busy+m.req test bit for command/data mode bra R2 R1 lda ,U sta ,X+ R2 cmpb ,Y beq R1 endc endc endc ifeq DISTO R2A ldb ,y get status bits andb #m.nnc strip floating bits cmpb #m.req+m.busy+m.cmd+m.in bne R2A lda ,u status data byte R2C ldb ,y get status bits andb #m.nnc strip floating bits cmpb #m.req+m.busy+m.msg+m.cmd+m.in bne R2C else R2A ldb #m.req+m.busy+m.cmd+m.in R2B cmpb ,y get status bne R2B lda ,u status data byte ldb #m.req+m.busy+m.msg+m.cmd+m.in R2C cmpb ,y bne R2C get term byte endc ldb ,u discard anda #m.error isolate error bit puls Y,U beq r3 if no error detected comb flag error to OS9 ldb #E$Read error code to be returned bra r6 r3 lda didflag,u beq r5 if lsn not 0 clr didflag,u lda PD.DRV,y get drive number ldb #DRVMEM size of each entry mul calculate the offset into the table leax tables,u get base address leax d,x get record address ifeq BUFSEC leay secbuf,u physical sector buffer else ldy PD.BUF,y sector buffer address endc ifeq H6309 ldw #DD.SIZ tfm y+,x+ else ldb #DD.SIZ number of bytes to copy r4 lda ,y+ get a byte from the disk identification sector sta ,x+ put it into the drive table decb count bytes to copy bne r4 endc r5 clrb r6 ifeq MPAK pshs a,cc lda mpstor,u sta >mpsel restore old mpak slot value puls a,cc endc rts ttl device init * init * * input: * y = device descriptor * u = static storage * * output: * carry set if error * b = error code * * y,u preserved. others destroyed INIT pshs y ldx V.PORT,u ifne DISTO sta selrst,x reset select line endc * removed 1-16-94, multiple drives are now imbeded scsi, each has controller * shouldn't do a scsi bus reset * ifne ADAPTEC * sta rstpo,x reset controllers (if more than one device, should be removed) * ldb #m.busy *iniw bitb statpo,x wait till not busy * bne iniw * endc leay $21,y get start of params & offsets in descriptor ldb #EXTPRM bytes to transfer leax param,u start of drive parameters in static storage offload lda ,y+ get drive parameters from descriptor sta ,x+ put into static decb bne offload if not done puls y clr didflag,u sector 0 read flag=cleared lda #$ff will set lastphy to undef sta lastphy,u store it ifeq BUFSEC sta lastdrv,u set last logical read to unknown endc ldb #numdrvs number of drives controller supports stb V.NDRV,u to the manager space leax tables,u lda #$ff fixtab sta DD.TOT,x setup starting info in the tables until the first sector clr V.TRAK,x of the device is read which will fill in the drive tables sta V.TRAK+1,x leax DRVMEM,x decb bne fixtab if not done with both tables lda #1 sta blocks,u set up for normal read/write 1 sector clr blocked,u extended buffer locked flag clr plocked,u param block locked flag ifeq BUFSEC clr cached,u cache dirty flag clr secidx,u index into physical sector ldb #$ff stb lsech,u set begin phy sec number to impossible value to force read stb lsecm,u ldb #m.smask stb lsecl,u endc ldb #numdrvs leax sec0fl,u clean recal flags clnrecal clr ,x+ decb bne clnrecal clrb no errors rts ttl sleep for rest of tick. Switch mpak slot if necessary (during HW Access) * entry conditions: * U = static storage * exit conditions * registers preserved doslp pshs b,x ifeq MPAK tst mpslot,u multipak in use? (1xxxxxxxb = no) bpl doslp2 hi bit clear, do change ldx #1 os9 F$Sleep wait a while bra doslp exit doslp2 ldb mpstor,u get back old mpak sel value stb >mpsel put it to mpak endc ldx #1 os9 F$Sleep wait a while ifeq MPAK ldb >mpsel get current value (could have changed) stb mpstor,u save it again andb #m.mpscs clear scs bits orb mpslot,u add in scs select stb >mpsel put it to mpak endc doslpo puls b,x,pc ttl setup and initiate command * entry conditions: * Y = path descriptor * A = opcode to controller * B = MSB of disk logical sector number * X = LSB's of disk logical sector number * U = static storage * * setup command packet * select controller * initiate command * * exit conditions: * A = destroyed * B = destroyed * X = controller base * U = unchanged (static) * Y = unchanged (PD) * setup set0 ifne HOG tst plocked,u critical lock on this section beq set02 * sleep was inline, now call bsr doslp sleep for a while bra set0 and check again set02 com plocked,u set the lock endc sta opcode,u put controller opcode into command packet stb lun,u stx lsn,u lda PD.DNS,y get physical drive number (0 or 1 supported) and init flag tfr a,b anda #m.phys (bit 5 is physical drive number) andb #m.init beq set25 skip init if not set in desc * changed 4-16-96, always check for init, based on descriptor *was ifne ADAPTEC adaptec handles drive parameter switches internally cmpa lastphy,u current physical drive? beq set25 yes, continue pshs a,y sta lastphy,u ldx V.PORT,u * wait for controller to finish any previous command * needs x set to port base and y set to pd ldb #m.busy busy status bit sel1 bitb statpo,x read status port ifeq HOG bne sel1 wait till not busy else beq sel1b skip if not busy bsr doslp bra sel1 endc sel1b lda PD.DNS,y controller number (lower 4 bits of PD.DNS var) anda #m.cont isolate controller number sta datapo,x latch the controller select sta selpo,x generate a select strobe sel2 bitb statpo,x read status port beq sel2 wait for controller to recognize select ifne DISTO sta selrst,x reset select (scuzzie version) endc lda lastphy,u get drive back leay param,U Point to Drive 0 Params as Default tsta Is it Drive 0? beq setp2 yes, get drive 0 parameters leay param1-param,Y Point to Drive 1 Params setp2 lda #m.req setp3 bita statpo,x get status beq setp3 wait till ready lda #o.param set param command sta datapo,x send it out ldb #5 rest of packet clra pakout sta datapo,x dump em out! decb bne pakout if not done lda #m.req setp4 bita statpo,x beq setp4 ldb #8 # of parameters to send out paramout lda ,y+ get a parameter sta datapo,x send it out decb bne paramout if not done, go again ifeq DISTO setp5 ldb statpo,x get status bits andb #m.nnc strip floating bits cmpb #m.req+m.busy+m.cmd+m.in bne setp5 lda datapo,x status data byte setp6 ldb statpo,x get status bits andb #m.nnc strip floating bits cmpb #m.req+m.busy+m.msg+m.cmd+m.in bne setp6 else ldb #m.req+m.busy+m.cmd+m.in setp5 cmpb statpo,x get status bne setp5 lda datapo,x status data byte ldb #m.req+m.busy+m.msg+m.cmd+m.in setp6 cmpb statpo,x bne setp6 get term byte endc ldb datapo,x discard puls a,Y set25 ora lun,u or in physical drive with sector number top 8 of 24 bits sta lun,u and put it back in place lda PD.STP,y get step and options sta control,u to the packet lda PD.DRV,y drive # from path descriptor lsla byte to word offset leax offsd1,u base of offsets ldd a,x get offset addd lun,u add in top 16 of 24 bit sector number std lun,u ldx V.PORT,u * wait for controller to finish any previous command * needs x set to port base and y set to pd set26 ldb #m.busy busy status bit sel3 bitb statpo,x read status port ifeq HOG bne sel3 wait till not busy else beq sel3b skip ahead if not busy lbsr doslp bra sel3 endc sel3b lda PD.DNS,y controller number (lower 4 bits of PD.DNS var) anda #m.cont isolate controller number sta datapo,x latch the controller select sta selpo,x generate a select strobe sel4 bitb statpo,x read status port beq sel4 wait for controller to recognize select ifne DISTO sta selrst,x reset select (scuzzie version) endc ttl send command packet * sends the command packet to the disk controller * needs x set to V.PORT taskout pshs y leay packet,u address of scsi packet ldb #6 number of bytes to transfer task00 lda #m.req task0 bita statpo,x beq task0 * ifeq H6309 * * orcc #%01010000 * ldw #6 * tfm y+,x * andcc #%10101111 * * else task1 lda ,y+ get a byte from the packet sta datapo,x send it to the controller decb count the bytes ifeq DBHS bne task00 need to check req again else bne task1 endc * endc ifne HOG clr plocked,u clear critical section lock endc puls y,pc ifeq CANFORM ttl format the drive * format * * Called by setstat. Entire drive will be formatted. * FORMAT ldd R$U,X Get Track Number lbne nofrmerr If Not Zero We are Done ldd R$Y,X get sides tsta lbne nofrmerr ifeq MPAK pshs b tst mpslot,u multipak in use? (1xxxxxxxb = no) bmi slotf2 hi bit set, skip change ldb >mpsel get current value stb mpstor,u save it andb #m.mpscs clear scs bits orb mpslot,u add in scs select stb >mpsel put it to mpak slotf2 puls b endc tfr D,X Set LSB's of Track # to Zero lda PD.ILV,y get drive interleave *sta >$ff68 DEBUG sta blocks,u put into packet (in place of blocks, restored below) * deal with the drive offset, needs to be zeroed for unit format pshs y * nitros adj ifeq H6309 lda PD.DRV+2,y else lda PD.DRV,y endc lsla drive to index leax offsd1,u offset table stx tempw1,u save the offset location ldy a,x sty tempw2,u save the offset value ldy #0 sty a,x set the offset temporarily to 0 puls y ifne HOG format0 tst plocked,u beq format1 lbsr doslp bra format0 com plocked,u format1 endc lda #o.formt Get Format Command clrb sector high byte ldx #0 sector low word lbsr setup * restore the original offset pshs x ldx tempw1,u offset loc ldd tempw2,u offset value std ,x put it back in the table puls x lda #1 sta blocks,u put 1 back to blocks ifeq DISTO format2 ldb statpo,x get status bits andb #m.nnc strip floating bits cmpb #m.req+m.busy+m.cmd+m.in beq format2b lbsr doslp bra format2 format2b lda datapo,x status data byte format3 ldb statpo,x get status bits andb #m.nnc strip floating bits cmpb #m.req+m.busy+m.msg+m.cmd+m.in bne format3 else ldb #m.req+m.busy+m.cmd+m.in format2 cmpb statpo,x get status beq format2b lbsr doslp bra format2 format2b lda datapo,x status data byte ldb #m.req+m.busy+m.msg+m.cmd+m.in format3 cmpb statpo,x bne format3 get term byte endc ldb datapo,x discard anda #m.error beq nofrmerr format sucessful comb indicate error ldb #E$Write bra formato endc nofrmerr clrb formato ifeq MPAK pshs a,cc lda mpstor,u sta >mpsel restore old mpak slot value puls a,cc endc ifne HOG clr plocked,u endc rts SETSTA ldx PD.RGS,y find the stacked values cmpb #SS.Reset beq nofrmerr ifeq CANFORM cmpb #SS.WTrk is it the format command? bne noformat * is it ok to format this drive? lda PD.DNS,y anda #m.format lbne format noformat endc GETSTA comb ldb #E$UnkSvc unknown service request rts TERM equ nofrmerr emod endmod equ * end