Notes on Apricot Winchester card and modern ATA commands
To use MFM Winchester card:
$ truncate -s $((306*4*16*512)) testhd.dsk
$ chdman createhd -c none -chs 306,4,16 -o testhd.chd -i testhd.dsk
$ mame apricotxi -flop1 dos2.mfi -window -exp:1 winchester -hard1 testhd.chd
B>msd # use Rev007 and Rodime 352
B>format a:apricot /sb:
Apricot Xi retains the data but doesn't boot.
Resources
- WD1010-05 Winchester Disk Controller
- Apricot Service Manual
mame/devices/machine/wd1010.*mame/devices/machine/ata*.*mame/devices/bus/apricot/expansion/winchester.*- ATA PIO Mode
- ATA Command Matrix
Commands
ID WD1010 ATA
0x10 CMD_RESTORE IDE_COMMAND_RECALIBRATE
0x20 CMD_READ_SECTOR IDE_COMMAND_READ_SECTORS
0x30 CMD_WRITE_SECTOR IDE_COMMAND_WRITE_SECTORS
0x40 CMD_SCAN_ID IDE_COMMAND_VERIFY_SECTORS
0x50 CMD_WRITE_FORMAT FORMAT TRACK
0x70 CMD_SEEK IDE_COMMAND_SEEK
Taskfile and DATA PIO
On Apricot located at map(0x0e0, 0x0ef).umask16(0x00ff), i.e. 0,2,4..., on PCAT it is at 0x1F0-0x1F7.
There are three differences:
- register
0is used for DATA PIO in ATA, and is not available on WD1010, it is mapped on0x1f0on Apricot with automatic sequencing; - register
1is used to set features in ATA and to set write precompensation cylinder on WD1010 (it seems to be okay to ignore since it doesn't do anything in ATA if there was no command issued); - SDH register is not wired on WD1010, Apricot is using LS259 for disk/head information (it is unclear if Apricot sets SDH for all operations or not).
Control registers on ATA
Might need to be implemented in Apricot BIOS to
- reset the ATA device: set and clear bit 2 (SRST) in the Control Register 0;
- detect the device mebbe: check for Control Registers 0 and 1.
Bus Addressable Latch LS259 on Apricot
Mapped to map(0x1e0, 0x1ef).umask16(0x00ff), used as follows
NO ADDR FLAG
0 1E0 HEAD0
1 1E2 HEAD1
2 1E4 HEAD2
3 1E6 DRIVE0
4 1E8 XFERD
5 1EA HBCR
6 1EC CLKSEL
7 1EE DRIVE1
As per manual:
HEAD[2..0]andDRIVE[1..0]are selecting one of 8 heads and 2 drives (1 and 2).CLKSELdefines if the system processor or the WD 1010-05 causes the sector pointer to be incremented, 0 allows data access to host, and 1 to WD1010.XFERDis a handshaking protocol informing the WD 1010-05 that data is available. Connected to BDRY.HBCRis used to reset both the sector pointer and the byte pointer to zero. It is controlled by the system processor.
It seems like the Apricot is making the weird dance with BDRQ/BDRY(XFERD) to handle multiple sectors read/write. Unfortunately, MAME doesn't seem to support to continue debugging. Needs validating.
Interrupt
Sends Apricot INT2 and also provides its value at 0x1e0.
Sequences
Test and read bad sectors list
MSD.EXE operations (it will fail at reading the status if the harddrive file is not specified)
writing 00 to 01EC ; CLKSEL host clocks data
writing 01 to 01EA ; HBCR up
writing 00 to 01EA ; HBCR reset counters
writing 55 to 01F0 ; DATA fill buffer
...
writing 00 to 01EC
writing 01 to 01EA
writing 00 to 01EA
reading 55 from 01F0 ; DATA reading from buffer
writing 01 to 01E6 ; DRIVE0
writing 00 to 01EE ; DRIVE1 select drive 1 out of 2
reading 50 from 00EE ; STATUS set irq to 0 and return status
; returns 00 if there is no drive
writing 00 to 01E0 ; HEAD0
writing 00 to 01E2 ; HEAD1
writing 00 to 01E4 ; HEAD2
writing FF to 00E2 ; PRECOMP rwc always low
writing 01 to 00E4 ; SECCOUNT 1 sector
writing 00 to 00E6 ; SECNUM sector 0
writing 00 to 00E8 ; CYLLOW 0
writing 00 to 00EA ; CYLHI 0
writing 20 to 00EC ; SDH 0 01 00 000: EXT=0(CRC is appended), SEC=1(512B), DRIVE=0(should be 1 but wk), HEAD=0
writing 10 to 00EE ; COMMAND READ
reading 50 from 00EE ; STATUS 01010000 RDY SC(Seek Complete
reading 00 from 00E2 ; ERROR
reading 01 from 00E4 ; SECCOUNT
reading 00 from 00E6 ; SECNUM
reading 00 from 00E8 ; CYLLOW
reading 00 from 00EA ; CYLHI
reading 20 from 00EC ; SDH
reading 50 from 00EE ; STATUS
writing 01 to 01E6 ; DRIVE0
writing 00 to 01EE ; DRIVE1
writing 40 to 00EE ; SCAN_ID
reading 50 from 00EE ; STATUS
reading 00 from 00E2 ; ERROR
reading 01 from 00E4 ; SECCOUNT
reading 00 from 00E6 ; SECNUM
reading 00 from 00E8 ; CYLLOW
reading 00 from 00EA ; CYLHI
reading 20 from 00EC ; SDH
reading 50 from 00EE ; STATUS
writing 01 to 01E6 ; DRIVE0
writing 00 to 01EE ; DRIVE1
writing 01 to 01EC ; CLKSEL WD accesses buffer
writing 01 to 01EA ; HBCR
writing 00 to 01EA ; HBCR reset counters
writing 01 to 01E8 ; XFERD READY set?
reading 50 from 00EE ; STATUS
writing 00 to 01E0 ; HEAD0
writing 00 to 01E2 ; HEAD1
writing 00 to 01E4 ; HEAD2
writing FF to 00E2 ; PRECOMP rwc always low
writing 01 to 00E4 ; SECCOUNT 1 sector
writing 00 to 00E6 ; SECNUM sector 0
writing 00 to 00E8 ; CYLLOW 0
writing 00 to 00EA ; CYLHI 0
writing 20 to 00EC ; SDH 0 01 00 000: EXT=0(CRC is appended), SEC=1(512B), DRIVE=0(should be 1 but wk), HEAD=0
writing 2C to 00EE ; COMMAND READ 00101100 Interrupt, Multiple
reading 50 from 00EE ; STATUS
reading 00 from 00E2 ; ERROR
reading 01 from 00E4 ; SECCOUNT
reading 00 from 00E6 ; SECNUM
reading 00 from 00E8 ; CYLLOW
reading 00 from 00EA ; CYLHI
reading 20 from 00EC ; SDH
reading 50 from 00EE ; STATUS
writing 00 to 01E8 ; XFERD READY unset?
writing 00 to 01EC ; CLKSEL host clocks data
writing 01 to 01EA ; HBCR up
writing 00 to 01EA ; HBCR reset counters
reading 00 from 01F0 ; DATA reads from buffer
...