How to emulate the Dobbertin HD20? ---------------------------------- The Dobbertin HD20 occupies only 5 I/O port addresses. It's emulation is (compared to other devices) relatively simple. ======================= = Physical Properties = ======================= Sectors: 17 (0-16) on each track Heads..: 4 (0-3) Tracks.: 614 (0-613) 0-611 for data 612 is reserved 613 for parking the heads =======> However, it would be great to provide 1024 tracks (0-1023) to have some more space ========= = Ports = ========= &FBE0: Data port (hddata) / Only 3 ports need to be emulated &FBE1: Status register (hdstat) / &FBE2: Select / configuration (hdslct) / &FBE3: DMA / interrupt (hdmask) / These two ports can be ignored &FBE4: Reset (hd_res) / For the emulation ports &FBE0-2 (three ports only) are sufficient! ------------------------------------------------------------------ ==================== = &FBE0: Data port = ==================== This port has four functions: 1. Send command bytes to this port 2. Send data to this port 3. Receive data from this port 4. Receive result bytes from this port When sending / reiceiving data the CPC can send / receive 512 bytes at once. It's not needed to wait, because the controller is very quick. &FBE1: Status register ====================== This I/O address can be read to assess the status of the HD20 hard disc. The significant bits are: - Bit 0: If bit 0 is 0 then you need to wait for the HD20 / Ready bit If bit 0 is 1 then the HD20 is ready to be used / - Bit 1: If bit 1 is 0 then the HD20 does provide data / data flowing from controller to host ############# stimmt das ??? If bit 1 is 1 then the HD20 does expect data /#################################################### oder anders rum? - Bit 2: If bit 2 is 0 then the HD20 is NOT in command state If bit 2 is 1 then the HD20 is in command state - Bit 3: If bit 3 is 0 then the controller is NOT selected - Error!!! / Controller selected bit If bit 3 is 1 then the controller is selected and can be used / If the input from &FBE1 is %xxxx1101 (binary) then the controller is in command state and waits to receive command bytes ================================= = &FBE2: Select / configuration = ================================= This port is used to select the hard disc HD20, subsequently an command can be sent. ========================== = &FBE3: DMA / interrupt = - probable it's not necessary to emualate this port ========================== ------------------------------------------------- This port is used to set the operation mode only. Example: (this is done when XDDOS gets initialized) LD BC,&FBE3 ;BC = &FBE3 (DMA / Interrupts port) LD A,&00 OUT (C),A ;send &00 to DMA/interrupt port ================ = &FBE4: Reset = - probable it's not necessary to emualate this port ================ ------------------------------------------------- This port performs a reset of the HD20 just by writing a byte to it. The content of the byte doesn't matter. Read a sector ============= Write a sector ============== Additonal information ===================== The following information was obtained from Linux/drivers/block/xd.h and MESS pc_hdc.c. Commands for HDC (incomplete list): ------------------------------------------ CMD_TESTREADY &00 test drive ready CMD_RECALIBRATE &01 recalibrate drive ??? &02 Request Syndrome CMD_SENSE &03 request sense CMD_FORMATDRV &04 format drive CMD_VERIFY &05 read verify CMD_FORMATTRK &06 format track CMD_FORMATBAD &07 format bad track CMD_READ &08 read ??? &09 Write Protect Sector CMD_WRITE &0A write CMD_SEEK &0B seek Kommandos &0C bis &1B können in Datei sasi_r0a.pdf nachgelesen werden! Siehe dort! Status (obtained when reading status register): ------------------------------------------------------------- STAT_READY &01 controller is ready STAT_INPUT &02 data flowing from controller to host STAT_COMMAND &04 controller in command phase STAT_SELECT &08 controller is selected STAT_REQUEST &10 controller requesting data STAT_INTERRUPT &20 controller requesting interrupt I/O Ports Lesen Schreiben ----------------------------------------------- &FBE0 Dobbertin Harddisc Data Port &FBE1 Dobbertin Harddisc Status, Reset ---------------------> Lesen &00, &06 (Normalbetrieb an, an & gelesen) &FBE2 Dobbertin Harddisc Select, Configuration -------------> Lesen &01 (wenn eingeschalten) &FBE3 Dobbertin Harddisc DMA, Interrupt &FBE4 Dobbertin Harddisc Reset ================= = Example Codes = ================= ;Wait until the HD20 is ready LD BC,&FBE1 ;HDSTAT -> 'BC' wtctrl IN A,(C) ;Controller Status -> 'A' AND 00001111B ;Mask significant Bits BIT 0,A ;Controller Ready ? RET NZ ;Yes, then RET BIT 3,A ;Controller selected ? JR NZ,wtctrl ;Yes, then wait RET ;Else you should check for errors ;Check for errors ; ------ >>> ERROR CHECKING <<< ------ ; ; RET mit CARRY = 1 und ZERO = 1 => No error ; RET mit CARRY = 0 und ZERO = 0 => error LD BC,&FBE1 ;HDSTAT -> 'BC' = &FBE1 IN A,(C) ;Controller Status -> 'A' AND 00001111B ;Mask significant Bits errchck CP 00001111B ;STATUS State ? JR NZ,hderror ;No, then jump to indicate error DEC C ;HDDATA -> 'BC' = &FBE0 IN A,(C) ;Read Result-Phase byte -> 'A' BIT 1,A ;Error occured ? SCF ;No, then RET with RET Z ; Carry & Zero = 1 ; hderror LD A,0FFH AND A ;RET with Carry & Zero = 0 RET ; if an error occured ;SEND COMMAND LD HL,command sendcmd LD BC,&FBE2 ;HD20 select (hdslct) OUT (C),A ;Select Controller DEC C DEC C ;HDDATA -> 'BC' cmdloop INC C ;BC = &FBE1 (HDSTAT -> 'BC') CALL wtctrl ;Wait Controller Ready (for 'wtcrtl' see before) CP 00001101B ;COMMAND State ? RET NZ ;No, then RET DEC C ;BC = &FBE0 (HDDATA -> 'BC') LD A,(HL) ;Command-Byte -> 'A' OUT (C),A ;Zum Controller senden INC HL JR cmdloop command is either hdrdsec or hdwrsec For read / write: hdrdsec DEFB 08H, xxH,yyH,zzH, 01H,02H ;Read Sector hdwrsec DEFB 0AH, xxH,yyH,zzH, 01H,01H ;Write Sector xx, yy, zz are defined as follows: xx = HL + 1 = Head in bits 1,0 - Head can be 0-3 yy = HL + 2 = MSB Cyl. + Sector / Cylinder (high bits) in bits 7,6 / sector in bits 5,4,3,2,1 - Sector can be 0-16 zz = HL + 3 = LSB Cyl. / Cyliner (low bits) - Cylinder low bits can be 0-255 The hard disc has 614 tracks (from 0 to 613). Tracks 0-612 are data (while track 613 is used for parking the four heads). ;Reset the hard disc and select configuration ; LD BC,&FBE4 ;Reset Port OUT (C),A ;send one byte to reset (content doesn't matter) LD A,&32 ;50 ms waiting time CALL &C964 ;Wait 1x 50 ms, preserve all registers DEC C ;BC = &FBE3 (DMA / Interrupts) LD A,&00 OUT (C),A ;send &00 to DMA/interrupt port DEC C ;BC = &FBE2 (Select / Configuration) IN A,(C) ;read status CP &01 ;compare to 1 RET ;and returen