AliM1543C_ide.h

Go to the documentation of this file.
00001 /* ES40 emulator.
00002  * Copyright (C) 2007-2008 by the ES40 Emulator Project
00003  *
00004  * WWW    : http://sourceforge.net/projects/es40
00005  * E-mail : camiel@camicom.com
00006  * 
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  * 
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  * 
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00020  * 
00021  * Although this is not required, the author would appreciate being notified of, 
00022  * and receiving any modifications you may make to the source code that might serve
00023  * the general public.
00024  */
00025 
00129 #if !defined(INCLUDED_ALIM1543C_IDE_H_)
00130 #define INCLUDED_ALIM1543C_IDE_H_
00131 
00132 // If DEBUG_IDE is defined, define all IDE debugging flags.
00133 #ifdef DEBUG_IDE
00134 #define DEBUG_IDE_BUSMASTER
00135 #define DEBUG_IDE_COMMAND
00136 #define DEBUG_IDE_DMA
00137 #define DEBUG_IDE_INTERRUPT
00138 #define DEBUG_IDE_REG_COMMAND
00139 #define DEBUG_IDE_REG_CONTROL
00140 #define DEBUG_IDE_PACKET
00141 #define DEBUG_IDE_MULTIPLE
00142 #endif
00143 
00144 #include "DiskController.h"
00145 #include "Configurator.h"
00146 #include "SCSIDevice.h"
00147 #include "SCSIBus.h"
00148 
00149 #define MAX_MULTIPLE_SECTORS  128
00150 
00162 class CAliM1543C_ide : public CDiskController, public CSCSIDevice, public Poco::Runnable
00163 {
00164   public:
00165     CAliM1543C_ide(CConfigurator*  cfg, class CSystem*  c, int pcibus, int pcidev);
00166     virtual       ~CAliM1543C_ide();
00167     virtual void  register_disk(class CDisk* dsk, int bus, int dev);
00168 
00169     virtual void  WriteMem_Legacy(int index, u32 address, int dsize, u32 data);
00170     virtual u32   ReadMem_Legacy(int index, u32 address, int dsize);
00171 
00172     virtual void  WriteMem_Bar(int func, int bar, u32 address, int dsize,
00173                                u32 data);
00174     virtual u32   ReadMem_Bar(int func, int bar, u32 address, int dsize);
00175 
00176     virtual int   SaveState(FILE* f);
00177     virtual int   RestoreState(FILE* f);
00178 
00179     virtual void  check_state();
00180     virtual void  ResetPCI();
00181 
00182     virtual void  run();
00183     virtual void  init();
00184     virtual void  start_threads();
00185     virtual void  stop_threads();
00186   private:
00187 
00188     // IDE controller
00189     u32   ide_command_read(int channel, u32 address, int dsize);
00190     void  ide_command_write(int channel, u32 address, int dsize, u32 data);
00191     u32   ide_control_read(int channel, u32 address);
00192     void  ide_control_write(int channel, u32 address, u32 data);
00193     u32   ide_busmaster_read(int channel, u32 address, int dsize);
00194     void  ide_busmaster_write(int channel, u32 address, u32 data, int dsize);
00195     int   do_dma_transfer(int index, u8* buffer, u32 size, bool direction);
00196 
00197     void  raise_interrupt(int channel);
00198     void  set_signature(int channel, int id);
00199     u8    get_status(int index);
00200     void  command_aborted(int index, u8 command);
00201     void  identify_drive(int index, bool packet);
00202     void  ide_status(int index);
00203 
00204     void  execute(int index);
00205 
00206     Poco::Thread * thrController[2];    // one thread for each controller chip
00207     Poco::Semaphore * semController[2]; // controller start/stop
00208     Poco::Semaphore * semBusMaster[2];  // bus master start/stop
00209     CRWMutex*   mtRegisters[2];         // main registers
00210     CRWMutex*   mtBusMaster[2];         // busmaster registers
00211     bool        StopThread;
00212 
00213     bool        usedma;
00214 
00215     // The state structure contains all elements that need to be saved to the statefile.
00216     struct SAliM1543C_ideState
00217     {
00218       struct SDriveState
00219       {
00220         struct
00221         {
00222           bool  busy;
00223           bool  drive_ready;
00224           bool  fault;
00225           bool  seek_complete;
00226           bool  drq;
00227           bool  bit_2;
00228           bool  index_pulse;
00229           bool  err;
00230           int   index_pulse_count;
00231 
00232           // debugging
00233           u8    debug_last_status;
00234           bool  debug_status_update;
00235 
00236           u8 alt_status; // this is the latched status.
00237         } status;
00238 
00239         struct
00240         {
00241           bool  lba_mode;
00242           int   features;
00243           int   error;
00244           int   sector_count;
00245           int   sector_no;
00246           int   cylinder_no;
00247           int   head_no;
00248           int   command;
00249         } registers;
00250 
00251         struct
00252         {
00253           bool  command_in_progress;
00254           int   current_command;
00255           int   command_cycle;
00256           bool  packet_dma;
00257           int   packet_phase;
00258           u8    packet_command[12];
00259           int   packet_buffersize;
00260           u8    packet_sense;
00261           u8    packet_asc;
00262           u8    packet_ascq;
00263         } command;
00264 
00265         u8  multiple_size;
00266       };
00267 
00268       struct SControllerState
00269       {
00270 
00271         // the attached devices
00272         struct SDriveState  drive[2];
00273 
00274         // control data.
00275         bool                disable_irq;
00276         bool                reset;
00277 
00278         // internal state
00279         bool                reset_in_progress;
00280         int                 selected;
00281 
00282         // dma stuff
00283         u8                  busmaster[8];
00284         u8                  dma_mode;
00285         u8                  bm_status;
00286 
00287         // pio stuff
00288 #define IDE_BUFFER_SIZE 65536           // 64K words = 128K = 256 sectors @ 512 bytes
00289         u16                 data[IDE_BUFFER_SIZE];
00290         int                 data_ptr;
00291         int                 data_size;
00292 
00293         bool                interrupt_pending;
00294       } controller[2];
00295     }
00296     state;
00297 
00298 };
00299 
00301 #define SEL_STATUS(a)            \
00302     state.controller[a].drive[state.controller[a].selected].status
00303 
00305 #define SEL_COMMAND(a)             \
00306     state.controller[a].drive[state.controller[a].selected].command
00307 
00309 #define SEL_REGISTERS(a)               \
00310     state.controller[a].drive[state.controller[a].selected].registers
00311 
00313 #define SEL_DISK(a)       get_disk(a, state.controller[a].selected)
00314 
00316 #define SEL_PER_DRIVE(a)  state.controller[a].drive[state.controller[a].selected]
00317 
00318 // Status for drive b on controller a
00319 #define STATUS(a, b)      state.controller[a].drive[b].status
00320 
00321 // Command for drive b on controller a
00322 #define COMMAND(a, b)     state.controller[a].drive[b].command
00323 
00324 // Registers for drive b on controller a
00325 #define REGISTERS(a, b)   state.controller[a].drive[b].registers
00326 
00327 // Per-drive data for drive b on controller a
00328 #define PER_DRIVE(a, b)   state.controller[a].drive[b]
00329 
00330 // Data for controller a
00331 #define CONTROLLER(a)     state.controller[a]
00332 
00333 // Update alt-status for controller a with locking
00334 #define UPDATE_ALT_STATUS(a)                        \
00335         {                                           \
00336           SCOPED_WRITE_LOCK(mtRegisters[a]);        \
00337           SEL_STATUS(a).alt_status=get_status(a);   \
00338         }
00339 
00340 /* memory region ids */
00341 #define PRI_COMMAND   1
00342 #define PRI_CONTROL   2
00343 #define SEC_COMMAND   3
00344 #define SEC_CONTROL   4
00345 #define PRI_BUSMASTER 5
00346 #define SEC_BUSMASTER 6
00347 
00348 /* bar IDs */
00349 #define BAR_PRI_COMMAND 0
00350 #define BAR_PRI_CONTROL 1
00351 #define BAR_SEC_COMMAND 2
00352 #define BAR_SEC_CONTROL 3
00353 #define BAR_BUSMASTER   4
00354 
00355 /* device registers */
00356 #define REG_COMMAND_DATA          0
00357 #define REG_COMMAND_ERROR         1
00358 #define REG_COMMAND_FEATURES      1
00359 #define REG_COMMAND_SECTOR_COUNT  2
00360 #define REG_COMMAND_SECTOR_NO     3
00361 #define REG_COMMAND_CYL_LOW       4
00362 #define REG_COMMAND_CYL_HI        5
00363 #define REG_COMMAND_DRIVE         6
00364 #define REG_COMMAND_STATUS        7
00365 #define REG_COMMAND_COMMAND       7
00366 
00367 static const char*  register_names[] = {
00368   "DATA",
00369   "ERROR/FEATURES",
00370   "SECTOR_COUNT/PKT REASON",
00371   "SECTOR_NO",
00372   "CYL_LOW/PKT BYTE LOW",
00373   "CYL_HI/PKT BYTE HI",
00374   "DRIVE",
00375   "STATUS/COMMAND",
00376 };
00377 
00378 /* misc constants */
00379 
00380 /* Packet Protocol Aliases */
00381 #define DMRD        fault
00382 #define SERV        seek_complete
00383 #define CHK         err
00384 #define BYTE_COUNT  cylinder_no
00385 #define REASON      sector_count
00386 #define IR_CD       0x01
00387 #define IR_IO       0x02
00388 #define IR_REL      0x04
00389 
00390 /* Packet protocol states */
00391 static const char*  packet_states[] = {
00392   "DP0: Prepare A",
00393   "DP1: Receive Packet",
00394   "DP2: Prepare B",
00395   "DP3/4: Ready INITRQ/Transfer Data",
00396   "DIx: Device Interrupt ",
00397 };
00398 
00399 #define PACKET_NONE 0
00400 #define PACKET_DP0  0
00401 #define PACKET_DP1  1
00402 #define PACKET_DP2  2
00403 #define PACKET_DP34 3
00404 #define PACKET_DI   4
00405 
00406 /* SCSI SENSE Constants */
00407 #define SENSE_NONE            0x00
00408 #define SENSE_RECOVERED_ERROR 0x01
00409 #define SENSE_NOT_READY       0x02
00410 #define SENSE_MEDIUM_ERROR    0x03
00411 #define SENSE_HARDWARE_ERROR  0x04
00412 #define SENSE_ILLEGAL_REQUEST 0x05
00413 #define SENSE_UNIT_ATTENTION  0x06
00414 #define SENSE_DATA_PROTECT    0x07
00415 #define SENSE_BLANK_CHECK     0x08
00416 #define SENSE_ABORT_COMMAND   0x0b
00417 #define SENSE_MISCOMPARE      0x0e
00418 
00419 
00420 extern CAliM1543C_ide*  theIDE;
00421 
00422 #endif

SourceForge.net Logo
Project space on SourceForge.net