Humble Bee Buttons
Go Back One
Humble Bee Buttons

 
CoCoZilla's MFM Mass Storage
Presented by: Only On Saturday Night
This is the WDXT slot.Schematic: CoCo to WDXT This is a record of my first attempts at mass storage. I used a WXDT ISA-PC type hard-disk card. This is how I wired the IBM card-edge connector to get the WDXT card to respond. Only connections needed are: A0, A1, /IORD, /IOWR and the 8 data lines, besides the +5v and the +12V (ignore the neg12V connection, WDXT cards don't need it). Signals /IOWR and /IORD need to be address decoded, A0, A1, (the address lines) GD0 to GD7 (the data lines) connect direct.
 
Here's the source code that I used until IDE came along:
 nam 'CCHDisk' 
 ttl OS9/NitrOS-9 Hard Disk Driver MFM
* Date: April 21, 1999
* for: 6809E CPU
*      WDXT-GEN2+
*      WDXT-GEN
*
NDrvs    equ 2      * change to 1 if only single drive wanted
*
Rev      equ 15
*
Card     equ $FF3C  * the base address of the WDXT card
RData    equ card+0 * from $FF3C to ...
WData    equ card+0
Status   equ card+1 * $FF3D
Reset    equ card+1
Config   equ card+2 * $FF3E
Select   equ card+2
IntReg   equ card+3 * $FF3F
*
Fodder   equ $FF
Blocks   equ $01
Interlv  equ $03
*
HdSize   equ 512
Os9Size  equ 256
Mask     equ $0F
AdvMask  equ $3F
Selected equ $0D
CmdByte  equ $0D
WrByte   equ $09
RdByte   equ $0B
CmpByte  equ $0F
ErrBit   equ %00000010
Drv1Bit  equ %00100000
NDrv1Bit equ %11011111
IntBit   equ %00000010
DoTk00   equ $06
SeekStil equ $08
*
* MFM commands:
*
TestCmd  equ $00
RecalCmd equ $01
ReqsCmd  equ $03
FmtCmd   equ $04
VfyCmd   equ $05
ReadCmd  equ $08
WritCmd  equ $0A
SeekCmd  equ $0B
InitCmd  equ $0C
ReadBuf  equ $0E
WritBuf  equ $0F
*
 ifp1
 use /DD/DEFS/DEFSFile
 endc
*
tylg set Drivr+Objct
atrv set ReEnt+Rev
*
 mod pgmend,modnam,tylg,atrv,start,size
*
 fcb %11111111 mode byte
*
 org DrvBeg
H0 rmb DrvMem
 ifeq NDrvs-2
H1 rmb DrvMem
 endc
*
* Init values for each Drive:
*
DiskVar0 rmb 8
 ifeq NDrvs-2
DiskVar1 rmb 8
 endc
*
* Command Block to Drive:
*
Class    rmb 1
Head     rmb 1
SecCyl   rmb 1
Cylindr  rmb 1
BlkCnt   rmb 1
StepSiz  rmb 1
*
* Linear Sector Number Storage:
*
Odd      rmb 1
HiByte   rmb 1
MidByte  rmb 1
LowByte  rmb 1
ZeroFlag rmb 1
*
* Various Buffers:
*
RetStat  rmb 1
ReqBufr  rmb 4
HdBuff   rmb HdSize
Stack    rmb 40
Size     equ .
*
Start
 lbra Init
 bra  ReadSec
 nop
 lbra WriteSec
 lbra Reads3   * GetSta
 lbra SetSta
 lbra Reads3   * Termin
*
ReadSec
 lbsr LSN
 lbsr ChkSeek
 bcs  RdXit
 bsr  Read
 bcc  Reads2
 lbsr Request
 lbcs Test
*
Reads2
 lbsr Blk2Os9
 lda  ZeroFlag,u
 bne  Reads3
 bsr  Lsn0
*
Reads3
 clrb
*
RdXit
 rts
*
Read
 lda  #ReadCmd
 lbsr SendCmd
 leax HdBuff,u
 ldd  #HdSize
*
* D=Count
*
BlkIn
 pshs y
 tfr  d,y
*
Read2
 lda  Status
 lsra
 bcc  Read2
*
 ldb  RData
 stb  ,x+
 leay -1,y
 bne  Read2
*
 puls y
 lbra Complete
*
Lsn0
 lbsr Getable * target
 ldb  #DD.SIZ * length
 pshs y
 ldy  PD.BUF,y * source
*
Read3
 lda  ,y+
 sta  ,x+
 decb
 bne  Read3
 puls y,pc
*
* patch in the appropriate
* OS9 256 byte block into
* the /H0 512 byte sector
*
WriteSec
 bsr  LSN
 lbsr ChkSeek
 bcs  WrErr
 bsr  Read
 bcc  Writes2
 lbsr Request
 bcs  WrErr
*
Writes2
 lbsr Os92Blk
 bsr  Write
 bcc  Writes3
 lbsr Request
 bcs  WrErr
*
Writes3
 tst  PD.VFY,y
 bne  RetNoErr
 bsr  Verify
 bcc  RetNoErr
 comb
 ldb  #E$Write
*
WrErr
 rts
*
RetNoErr
 clrb
 rts
*
Write
 lda #WritCmd
*
Write0
 lbsr SendCmd
 leax HdBuff,u
 ldd  #HdSize

* D=Count
*
BlkOut
 pshs y
 tfr  d,y
*
Data2
 lda  Status
 lsra
 bcc  Data2
*
 ldb  ,x+
 stb  WData
 leay -1,y
 bne  Data2
*
 puls y
 lbra Complete
*
Verify
 lda  #VfyCmd
 lbsr General
 ldb  RetStat,u
 beq  VfyXit
 coma
*
VfyXit
 rts
*
* LSN
* 0000000C:CCCCCCCC:CSSSSHHO
* for up to 20meg drives only.
* for 4 heads only !
* Cylinder-bits, Sector-bits, Head-bits, Odd-bit
* Odd-bit decides which half of the 512-byte sector
* gets read or (read, modify &) write.
*
LSN
 clr  Odd,u
 stb  HiByte,u
 stx  MidByte,u
 orb  MidByte,u
 orb  LowByte,u
 stb  ZeroFlag,u
*
 ldd  MidByte,u * move one cylinder bit
 lslb
 rola
 rol  HiByte,u
 sta  Cylindr,u
*
 lda  HiByte,u * get ls-bit of LSN
 lsra
 rorb
 lsra
 rorb
 rol  Odd,u * save that bit
*
 tfr  b,a
 andb #%11001111
 stb  SecCyl,u
 lsra
 lsra
 lsra
 lsra
 sta  Head,u
 rts
*
Os92Blk
 pshs y
 clrb         * Loop transfer counter
 ldx  PD.BUF,y
 leay HdBuff,u
 tst  Odd,u
 beq  LowHalf
 leay Os9Size,y
*
LowHalf
 lda  ,x+
 sta  ,y+
 decb
 bne  LowHalf
 puls y,pc
*
Blk2Os9
 pshs y
 clrb         * Loop Counter
 leax HdBuff,u * destination
 ldy  PD.BUF,y * source
 tst  Odd,u
 beq  LowHalf
 leax Os9Size,x
 bra  LowHalf
*
TestDrv
 lda  #TestCmd
 bsr  SendCmd
*
Test1
 lda  Status
 anda #Mask
 cmpa  #CmpByte
 bne  Test1
 ldb  WData     * get error bits
 andb #^Drv1Bit * without drive#
 beq  TestXit
 coma         * set error flag
*
TestXit
 rts
*
Sleep
 pshs x
 ldx  #1
 OS9  F$Sleep
 puls x,pc
*
Chk2
 bsr  Sleep
*
ChkSeek
 bsr  TestDrv
 bcc  Exit2
 cmpb #SeekStil
 beq  Chk2
 cmpb #DoTk00
 beq  Chk2
 bra  Request   * some other error
*
Exit2
 rts
*
 ifeq NDrvs-2
GetDrive
  lda  Head,u    * get drive/head variable
  tst  PD.DRV,y * if /H0
  beq  UseH0
  ora  #Drv1Bit * slave, /H1
  bra  Drive
*-
UseH0
  anda #^Drv1Bit * master, /H0
*-
Drive
  sta  Head,u    * update drive-bit
  rts
 endc
*
SendCmd
 sta  Select
 sta  Class,u
 bsr  GetDrive
*
NotRdy
 lda  Status
 anda #Mask
 cmpa #Selected
 bne  NotRdy
 leax Class,u
 ldb  #6

SendData
 lda  Status
 lsra
 bcc  SendData * 1=ready for data
 lda  ,x+
 sta  WData
 decb
 bne  SendData
 rts
*
General
 bsr  SendCmd
*
Complete
 lda  Status
 anda #Mask
 cmpa #CmpByte
 bne  Complete
 ldb  RData
 andb #ErrBit
 stb  RetStat,u
 beq  CompExit
 coma           * set carry bit
*
CompExit
 rts
*
Request
 lda  #ReqsCmd
 bsr  SendCmd
 leax ReqBufr,u
 ldd  #$04      * get request data string
 lbsr BlkIn
 ldb  ReqBufr,u * check the error byte
 andb #AdvMask  * eliminate the ADV-BIT
 bne  Test      * if not=0 then error
 clrb
 rts
*
Test
 cmpb #4
 bne  tst2
 comb
 ldb  #$FA
 rts
*
Tst2
 cmpb #3
 bne  tst3
 comb
 ldb  #$F5
 rts
*
Tst3
 cmpb #2
 bne  Tst4
 comb
 ldb  #$F0
 rts
*
Tst4
 cmpb #$15
 bne  Tst5
 comb
 ldb  #$F7
 rts
*
Tst5
 cmpb #$21
 bne  ErrSet
 comb
 ldb  #$F1
 rts
*
ErrSet
 comb
 ldb  #$CB
 rts
*-
GeTable
 ifeq NDrvs-2
  tst  PD.DRV,y
  bne  Slave
 endc
 leax H0,u
 rts
*-
 ifeq NDrvs-2
Slave
  leax H1,u
  rts
 endc
*
Init
 sta  Reset
 ldb  #NDrvs
 stb  V.NDRV,u
 lda  #$FF
 leax H0,u
*
InitLoop
 sta  DD.TOT+1,x
 sta  V.TRAK,x
 ifeq NDrvs-2
  leax DRVMEM,x
  decb
  bne  InitLoop
 endc
*
 lda  #IntBit
 sta  IntReg  * no interrupts
 sta  Reset   * reset the controller
 ldb  $14,y   * It.Stp dev desc
 orb  #$C0    * step rate bits
 stb  StepSiz,u
 clr  SecCyl,u
 clr  Cylindr,u
 clr  V.BUSY,u
 clr  V.WAKE,u
 lda  #Blocks * sector count
 sta  BlkCnt,u
 leax $20+1,y * IT.SAS+1
 pshs x,y     * Y is on bottom
 bsr  GetVar
 tfr  x,y
 puls x       * Y is still there
 ldb  #$08
*
MoveIt
 lda  ,x+
 sta  ,y+
 decb
 bne  MoveIt
*
 puls y
 lda  #InitCmd
 lbsr SendCmd
 bsr  GetVar * X=pointer
 ldd  #8     * table length
 lbsr BlkOut * send command
 bra  Home
*
GetVar
 leax DiskVar0,u
 ifeq NDrvs-2
  tst  PD.DRV,y
  beq  GetH0
  leax DiskVar1,u
*
GetH0
 endc
 rts
*
SetSta
 cmpb #SS.Reset
 bne  Set2
 bsr  Home
 rts
*
Set2
 cmpb #SS.Wtrk
 bne  SetErr
 bsr  FmtHd * low-level format
 rts
*
SetErr
 comb
 ldb  #E$UnkSvc
*
Exit
 rts
*
* Format a MFM Hard Drive:
*   first:  "dmode /h0 dns=0"
*   second: "format /h0"
*  This allows drive to be low-level formatted.
*  Software then sets dns=1 and quits.
*
FmtHd
 tst  PD.DNS,y
 beq  FmtCont * if =0 then FORMAT & set=1
*
Fmt2
 lda  #Blocks
 sta  PD.DNS,y * formatting is forced OFF
 sta  BlkCnt,u
 clrb
 rts
* First: fill the MDM drive's
*   internal buffer with sector data.
* Second: format the WHOLE drive with that data.
FmtCont
 bsr  Home
 bcs  Exit
 lda  #WritBuf * the fill-buffer command
 lbsr SendCmd
 lda  #Fodder  * the data to fill every sector with
 ldx  #HdSize
*
Loop
 ldb  Status   * send that buffer data
 andb #Mask
 cmpb #WrByte
 bne  Loop
*
 sta  WData
 leax -1,x
 bne  Loop
*
 lbsr Complete
 bcs  Exit
*
 lda  #Interlv * now format the while drive
 sta  BlkCnt,u
 lda  #FmtCmd  * with the MFM-FORMAT command
 lbsr General  * listen to it step ...
 bcs  Exit
 bsr  Fmt2     * same as: dmode /h0 dns=1
*
* and fall into...
*
Home
 lbsr GeTable   * move the drive heads to track=00
 clr  V.TRAK,x
 clr  Cylindr,u
 clr  SecCyl,u
 clr  Head,u
 ifeq NDrvs-2
  lbsr GetDrive  * update drive# bit
 endc
 lda  #RecalCmd * send heads to tk00
 lbsr General
 bcc  Exit
 lbra Request
*
modnam fcs /CCHDisk/
 fcb   Rev
*
 emod
pgmend equ *
 end
Hosted by www.Geocities.ws

1