From f43c30e4595d290fb464413652da8bba8c86a65b Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Sat, 28 Mar 2015 16:04:04 +0200 Subject: [PATCH] IDE/SCSI updates. --- a2091.cpp | 59 ++++++++++++++++++++---------------- idecontrollers.cpp | 30 +++++++++++++------ include/a2091.h | 4 ++- include/ide.h | 1 + include/idecontrollers.h | 1 - ncr9x_scsi.cpp | 56 +++++++++++++++++------------------ ncr_scsi.cpp | 64 +++++++++++++++++++++------------------- scsi.cpp | 23 ++++++++++++--- 8 files changed, 138 insertions(+), 100 deletions(-) diff --git a/a2091.cpp b/a2091.cpp index 4c19de71..6181a5ae 100644 --- a/a2091.cpp +++ b/a2091.cpp @@ -264,23 +264,27 @@ static struct wd_state *wd_a2091[MAX_DUPLICATE_EXPANSION_BOARDS]; static struct wd_state *wd_a2090[MAX_DUPLICATE_EXPANSION_BOARDS]; static struct wd_state *wd_a3000; -static struct wd_state *wd_gvp[MAX_DUPLICATE_EXPANSION_BOARDS]; +static struct wd_state *wd_gvps1[MAX_DUPLICATE_EXPANSION_BOARDS]; +static struct wd_state *wd_gvps2[MAX_DUPLICATE_EXPANSION_BOARDS]; struct wd_state *wd_cdtv; static struct wd_state *scsi_units[MAX_SCSI_UNITS + 1]; -static void freescsi(struct wd_state **wd) +static void freencrunit(struct wd_state *wd) { + if (!wd) + return; for (int i = 0; i < MAX_SCSI_UNITS; i++) { - if (scsi_units[i] == *wd) { + if (scsi_units[i] == wd) { scsi_units[i] = NULL; } } - if (*wd) { - scsi_freenative((*wd)->scsis); - xfree(*wd); - } - *wd = NULL; + scsi_freenative(wd->scsis); + xfree (wd->rom); + wd->rom = NULL; + if (wd->self_ptr) + *wd->self_ptr = NULL; + xfree(wd); } static struct wd_state *allocscsi(struct wd_state **wd, struct romconfig *rc, int ch) @@ -288,7 +292,8 @@ static struct wd_state *allocscsi(struct wd_state **wd, struct romconfig *rc, in struct wd_state *scsi; if (ch < 0) { - freescsi(wd); + freencrunit(*wd); + *wd = NULL; } if ((*wd) == NULL) { scsi = xcalloc(struct wd_state, 1); @@ -298,6 +303,7 @@ static struct wd_state *allocscsi(struct wd_state **wd, struct romconfig *rc, in if (rc) rc->unitdata = scsi; scsi->rc = rc; + scsi->self_ptr = wd; *wd = scsi; return scsi; } @@ -1401,7 +1407,8 @@ void scsi_hsync (void) for (int i = 0; i < MAX_DUPLICATE_EXPANSION_BOARDS; i++) { scsi_hsync2_a2091(wd_a2091[i]); scsi_hsync2_a2091(wd_a2090[i]); - scsi_hsync2_gvp(wd_gvp[i]); + scsi_hsync2_gvp(wd_gvps1[i]); + scsi_hsync2_gvp(wd_gvps2[i]); } scsi_hsync2_a2091(wd_a3000); scsi_hsync2_a2091(wd_cdtv); @@ -3327,7 +3334,7 @@ void a3000scsi_free (void) struct wd_state *wd = wd_a3000; if (!wd) return; - scsi_freenative(wd->scsis); + freencrunit(wd); if (wd->scsi_thread_running > 0) { wd->scsi_thread_running = 0; write_comm_pipe_u32 (&wd->requests, 0xffffffff, 1); @@ -3353,21 +3360,25 @@ void a2091_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig add_scsi_device(&wd->scsis[ch], ch, ci, rc); } -void gvp_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc) +void gvp_s1_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc) { - struct wd_state *wd = allocscsi(&wd_gvp[ci->controller_type_unit], rc, ch); + struct wd_state *wd = allocscsi(&wd_gvps1[ci->controller_type_unit], rc, ch); if (!wd || ch < 0) return; add_scsi_device(&wd->scsis[ch], ch, ci, rc); } -void a2091_free_device (struct wd_state *wd) +void gvp_s2_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc) { - if (!wd) + struct wd_state *wd = allocscsi(&wd_gvps2[ci->controller_type_unit], rc, ch); + if (!wd || ch < 0) return; - scsi_freenative(wd->scsis); - xfree (wd->rom); - wd->rom = NULL; + add_scsi_device(&wd->scsis[ch], ch, ci, rc); +} + +void a2091_free_device (struct wd_state *wd) +{ + freencrunit(wd); } void a2091_free (void) @@ -3543,17 +3554,14 @@ addrbank *a2090_init (struct romconfig *rc) void gvp_free_device (struct wd_state *wd) { - if (!wd) - return; - scsi_freenative(wd->scsis); - xfree (wd->rom); - wd->rom = NULL; + freencrunit(wd); } void gvp_free (void) { for (int i = 0; i < MAX_DUPLICATE_EXPANSION_BOARDS; i++) { - gvp_free_device(wd_gvp[i]); + gvp_free_device(wd_gvps1[i]); + gvp_free_device(wd_gvps2[i]); } } @@ -3574,7 +3582,8 @@ static void gvp_reset_device(struct wd_state *wd) void gvp_reset (void) { for (int i = 0; i < MAX_DUPLICATE_EXPANSION_BOARDS; i++) { - gvp_reset_device(wd_gvp[i]); + gvp_reset_device(wd_gvps1[i]); + gvp_reset_device(wd_gvps2[i]); } } diff --git a/idecontrollers.cpp b/idecontrollers.cpp index f9b4069b..7d991e57 100644 --- a/idecontrollers.cpp +++ b/idecontrollers.cpp @@ -95,14 +95,29 @@ static struct ide_thread_state idecontroller_its; static struct ide_board *ide_boards[MAX_IDE_UNITS + 1]; +static void freencrunit(struct ide_board *ide) +{ + if (!ide) + return; + for (int i = 0; i < MAX_IDE_UNITS; i++) { + if (ide_boards[i] == ide) { + ide_boards[i] = NULL; + } + } + remove_ide_unit(&ide->ide, 0); + if (ide->self_ptr) + *ide->self_ptr = NULL; + xfree(ide->rom); + xfree(ide); +} + static struct ide_board *allocide(struct ide_board **idep, struct romconfig *rc, int ch) { struct ide_board *ide; if (ch < 0) { if (*idep) { - remove_ide_unit(&(*idep)->ide, 0); - xfree(*idep); + freencrunit(*idep); *idep = NULL; } ide = xcalloc(struct ide_board, 1); @@ -111,6 +126,7 @@ static struct ide_board *allocide(struct ide_board **idep, struct romconfig *rc, ide_boards[i] = ide; rc->unitdata = ide; ide->rc = rc; + ide->self_ptr = idep; if (idep) *idep = ide; return ide; @@ -223,13 +239,6 @@ void idecontroller_hsync(void) } } -void idecontroller_free_units(void) -{ - for (int i = 0; i < TOTAL_IDE * 2; i++) { - remove_ide_unit(idecontroller_drive, i); - } -} - static void reset_ide(struct ide_board *board) { board->configured = 0; @@ -247,6 +256,9 @@ void idecontroller_reset(void) void idecontroller_free(void) { stop_ide_thread(&idecontroller_its); + for (int i = 0; i < MAX_IDE_UNITS; i++) { + freencrunit(ide_boards[i]); + } } static bool is_gvp2_intreq(uaecptr addr) diff --git a/include/a2091.h b/include/a2091.h index c830ec48..1017daea 100644 --- a/include/a2091.h +++ b/include/a2091.h @@ -80,6 +80,7 @@ struct wd_state { int rom_size, rom_mask; addrbank *bank; struct romconfig *rc; + struct wd_state **self_ptr; smp_comm_pipe requests; volatile int scsi_thread_running; @@ -134,7 +135,8 @@ extern void scsi_hsync (void); extern void a2090_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc); extern void a2091_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc); -extern void gvp_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc); +extern void gvp_s1_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc); +extern void gvp_s2_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc); extern void a3000_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfig *rc); extern int add_wd_scsi_hd (struct wd_state *wd, int ch, struct hd_hardfiledata *hfd, struct uaedev_config_info *ci, int scsi_level); diff --git a/include/ide.h b/include/ide.h index a88b47d8..d27c6d06 100644 --- a/include/ide.h +++ b/include/ide.h @@ -43,6 +43,7 @@ struct ide_board int userdata; int subtype; struct romconfig *rc; + struct ide_board **self_ptr; }; struct ide_hdf diff --git a/include/idecontrollers.h b/include/idecontrollers.h index 977d34fa..5080adc8 100644 --- a/include/idecontrollers.h +++ b/include/idecontrollers.h @@ -1,6 +1,5 @@ // Other IDE controllers -void idecontroller_free_units(void); void idecontroller_free(void); void idecontroller_reset(void); void idecontroller_rethink(void); diff --git a/ncr9x_scsi.cpp b/ncr9x_scsi.cpp index 0dca73a2..8af62c56 100644 --- a/ncr9x_scsi.cpp +++ b/ncr9x_scsi.cpp @@ -101,6 +101,7 @@ struct ncr9x_state int dma_delay_val; uae_u8 states[16]; struct romconfig *rc; + struct ncr9x_state **self_ptr; uae_u8 data; bool data_valid; @@ -168,28 +169,23 @@ static void freescsi(SCSIDevice *scsi) } } -static void ncr9x_free2(struct ncr9x_state *ncr) -{ - if (!ncr) - return; - for (int ch = 0; ch < 8; ch++) { - freescsi(ncr->scsid[ch]); - ncr->scsid[ch] = NULL; - } -} - -static void freencrunit(struct ncr9x_state **ncr) +static void freencrunit(struct ncr9x_state *ncr) { if (!ncr) return; for (int i = 0; i < MAX_NCR9X_UNITS; i++) { - if (ncr_units[i] == *ncr) { + if (ncr_units[i] == ncr) { ncr_units[i] = NULL; } } - ncr9x_free2(*ncr); - xfree(*ncr); - *ncr = NULL; + for (int ch = 0; ch < 8; ch++) { + freescsi(ncr->scsid[ch]); + ncr->scsid[ch] = NULL; + } + xfree(ncr->rom); + if (ncr->self_ptr) + *ncr->self_ptr = NULL; + xfree(ncr); } static struct ncr9x_state *allocscsi(struct ncr9x_state **ncr, struct romconfig *rc, int ch) @@ -197,7 +193,8 @@ static struct ncr9x_state *allocscsi(struct ncr9x_state **ncr, struct romconfig struct ncr9x_state *scsi; if (ch < 0) { - freencrunit(ncr); + freencrunit(*ncr); + *ncr = NULL; } if ((*ncr) == NULL) { scsi = xcalloc(struct ncr9x_state, 1); @@ -207,6 +204,7 @@ static struct ncr9x_state *allocscsi(struct ncr9x_state **ncr, struct romconfig if (rc) rc->unitdata = scsi; scsi->rc = rc; + scsi->self_ptr = ncr; *ncr = scsi; return scsi; } @@ -220,10 +218,8 @@ static struct ncr9x_state *getscsi(struct romconfig *rc) for (int i = 0; i < MAX_NCR9X_UNITS; i++) { if (ncr_units[i]) { struct ncr9x_state *ncr = ncr_units[i]; - if (ncr->rc == rc) { - ncr->rc = NULL; + if (ncr->rc == rc) return ncr; - } } } return NULL; @@ -1487,7 +1483,7 @@ static void ncr9x_esp_scsi_init(struct ncr9x_state *ncr, ESPDMAMemoryReadWriteFu void ncr9x_free(void) { for (int i = 0; ncr_units[i]; i++) { - ncr9x_free2(ncr_units[i]); + freencrunit(ncr_units[i]); } } @@ -1495,6 +1491,14 @@ void ncr9x_init(void) { } +static void allocscsidevice(struct ncr9x_state *ncr, int ch, struct scsi_data *handle) +{ + handle->privdata = ncr; + ncr->scsid[ch] = xcalloc (SCSIDevice, 1); + ncr->scsid[ch]->id = ch; + ncr->scsid[ch]->handle = handle; +} + static void add_ncr_scsi_hd(struct ncr9x_state *ncr, int ch, struct hd_hardfiledata *hfd, struct uaedev_config_info *ci) { struct scsi_data *handle = NULL; @@ -1503,9 +1507,7 @@ static void add_ncr_scsi_hd(struct ncr9x_state *ncr, int ch, struct hd_hardfiled ncr->scsid[ch] = NULL; if (!add_scsi_hd(&handle, ch, hfd, ci)) return; - handle->privdata = ncr; - ncr->scsid[ch] = xcalloc(SCSIDevice, 1); - ncr->scsid[ch]->handle = handle; + allocscsidevice(ncr, ch, handle); ncr->enabled = true; } @@ -1517,9 +1519,7 @@ static void add_ncr_scsi_cd(struct ncr9x_state *ncr, int ch, int unitnum) ncr->scsid[ch] = NULL; if (!add_scsi_cd(&handle, ch, unitnum)) return; - handle->privdata = ncr; - ncr->scsid[ch] = xcalloc(SCSIDevice, 1); - ncr->scsid[ch]->handle = handle; + allocscsidevice(ncr, ch, handle); ncr->enabled = true; } @@ -1531,9 +1531,7 @@ static void add_ncr_scsi_tape(struct ncr9x_state *ncr, int ch, const TCHAR *tape ncr->scsid[ch] = NULL; if (!add_scsi_tape(&handle, ch, tape_directory, readonly)) return; - handle->privdata = ncr; - ncr->scsid[ch] = xcalloc(SCSIDevice, 1); - ncr->scsid[ch]->handle = handle; + allocscsidevice(ncr, ch, handle); ncr->enabled = true; } diff --git a/ncr_scsi.cpp b/ncr_scsi.cpp index c8f68ade..95f8266c 100644 --- a/ncr_scsi.cpp +++ b/ncr_scsi.cpp @@ -73,6 +73,7 @@ struct ncr_state bool irq; void (*irq_func)(int); struct romconfig *rc; + struct ncr_state **self_ptr; }; #define MAX_NCR_UNITS 10 @@ -86,28 +87,23 @@ static void freescsi (SCSIDevice *scsi) } } -static void ncr_free2(struct ncr_state **ncr) -{ - if (*ncr) { - for (int ch = 0; ch < 8; ch++) { - freescsi ((*ncr)->scsid[ch]); - (*ncr)->scsid[ch] = NULL; - } - } - xfree(*ncr); - *ncr = NULL; -} - -static void freencrunit(struct ncr_state **ncr) +static void freencrunit(struct ncr_state *ncr) { if (!ncr) return; for (int i = 0; i < MAX_NCR_UNITS; i++) { - if (ncr_units[i] == *ncr) { + if (ncr_units[i] == ncr) { ncr_units[i] = NULL; } } - ncr_free2(ncr); + for (int ch = 0; ch < 8; ch++) { + freescsi (ncr->scsid[ch]); + ncr->scsid[ch] = NULL; + } + xfree(ncr->rom); + if (ncr->self_ptr) + *ncr->self_ptr = NULL; + xfree(ncr); } static struct ncr_state *allocscsi(struct ncr_state **ncr, struct romconfig *rc, int ch) @@ -115,7 +111,8 @@ static struct ncr_state *allocscsi(struct ncr_state **ncr, struct romconfig *rc, struct ncr_state *scsi; if (ch < 0) { - freencrunit(ncr); + freencrunit(*ncr); + *ncr = NULL; } if ((*ncr) == NULL) { scsi = xcalloc(struct ncr_state, 1); @@ -125,6 +122,7 @@ static struct ncr_state *allocscsi(struct ncr_state **ncr, struct romconfig *rc, if (rc) rc->unitdata = scsi; scsi->rc = rc; + scsi->self_ptr = ncr; *ncr = scsi; return scsi; } @@ -138,10 +136,8 @@ static struct ncr_state *getscsi(struct romconfig *rc) for (int i = 0; i < MAX_NCR_UNITS; i++) { if (ncr_units[i]) { struct ncr_state *ncr = ncr_units[i]; - if (ncr->rc == rc) { - ncr->rc = NULL; + if (ncr->rc == rc) return ncr; - } } } return NULL; @@ -439,8 +435,12 @@ static uae_u32 ncr_bget2 (struct ncr_state *ncr, uaecptr addr) addr &= ncr->board_mask; if (ncr->rom && addr >= ncr->rom_start && addr < ncr->rom_end) return read_rombyte (ncr, addr - ncr->rom_offset); - if (addr == A4091_DIP_OFFSET) - return 0xff; + if (addr == A4091_DIP_OFFSET) { + uae_u8 v = 0; + v |= ncr->rc->device_id; + v ^= 0xff & ~7; + return v; + } if (ncr->io_end && (addr < ncr->io_start || addr >= ncr->io_end)) return v; if (ncr->newncr) @@ -826,7 +826,7 @@ addrbank *ncr710_a4091_autoconfig_init (struct romconfig *rc) void ncr_free(void) { for (int i = 0; i < MAX_NCR_UNITS; i++) { - ncr_free2(&ncr_units[i]); + freencrunit(ncr_units[i]); } } @@ -841,6 +841,14 @@ void ncr_reset(void) } } +static void allocscsidevice(struct ncr_state *ncr, int ch, struct scsi_data *handle) +{ + handle->privdata = ncr; + ncr->scsid[ch] = xcalloc (SCSIDevice, 1); + ncr->scsid[ch]->id = ch; + ncr->scsid[ch]->handle = handle; +} + static void add_ncr_scsi_hd (struct ncr_state *ncr, int ch, struct hd_hardfiledata *hfd, struct uaedev_config_info *ci) { struct scsi_data *handle = NULL; @@ -849,9 +857,7 @@ static void add_ncr_scsi_hd (struct ncr_state *ncr, int ch, struct hd_hardfileda ncr->scsid[ch] = NULL; if (!add_scsi_hd(&handle, ch, hfd, ci)) return; - handle->privdata = ncr; - ncr->scsid[ch] = xcalloc (SCSIDevice, 1); - ncr->scsid[ch]->handle = handle; + allocscsidevice(ncr, ch, handle); ncr->enabled = true; } @@ -863,9 +869,7 @@ static void add_ncr_scsi_cd (struct ncr_state *ncr, int ch, int unitnum) ncr->scsid[ch] = NULL; if (!add_scsi_cd(&handle, ch, unitnum)) return; - handle->privdata = ncr; - ncr->scsid[ch] = xcalloc (SCSIDevice, 1); - ncr->scsid[ch]->handle = handle; + allocscsidevice(ncr, ch, handle); ncr->enabled = true; } @@ -877,9 +881,7 @@ static void add_ncr_scsi_tape (struct ncr_state *ncr, int ch, const TCHAR *tape_ ncr->scsid[ch] = NULL; if (!add_scsi_tape(&handle, ch, tape_directory, readonly)) return; - handle->privdata = ncr; - ncr->scsid[ch] = xcalloc (SCSIDevice, 1); - ncr->scsid[ch]->handle = handle; + allocscsidevice(ncr, ch, handle); ncr->enabled = true; } diff --git a/scsi.cpp b/scsi.cpp index d9ff4762..38fb5327 100644 --- a/scsi.cpp +++ b/scsi.cpp @@ -595,6 +595,7 @@ struct soft_scsi int subtype; int dma_direction; struct romconfig *rc; + struct soft_scsi **self_ptr; int dmac_direction; uaecptr dmac_address; @@ -627,6 +628,9 @@ static void soft_scsi_free_unit(struct soft_scsi *s) rs->device[j] = NULL; } xfree(s->databufferptr); + xfree(s->rom); + if (s->self_ptr) + *s->self_ptr = NULL; xfree(s); } @@ -651,6 +655,7 @@ static struct soft_scsi *allocscsi(struct soft_scsi **ncr, struct romconfig *rc, if (ch < 0) { freescsi(ncr); + *ncr = NULL; } if ((*ncr) == NULL) { scsi = xcalloc(struct soft_scsi, 1); @@ -659,6 +664,7 @@ static struct soft_scsi *allocscsi(struct soft_scsi **ncr, struct romconfig *rc, soft_scsi_devices[i] = scsi; rc->unitdata = scsi; scsi->rc = rc; + scsi->self_ptr = ncr; if (ncr) *ncr = scsi; return scsi; @@ -1637,13 +1643,13 @@ static uae_u32 ncr80_bget2(struct soft_scsi *ncr, uaecptr addr, int size) uae_u8 t = raw_scsi_get_signal_phase(rs); v = 0; // bits 0 to 2: ID (inverted) + v |= (ncr->rc->device_id ^ 7) & 7; // shorter delay before drive detection (8s vs 18s) v |= 1 << 5; if (t & SCSI_IO_REQ) { v |= 1 << 6; v |= 1 << 7; } - activate_debugger(); } @@ -1999,11 +2005,21 @@ addrbank *supra_init(struct romconfig *rc) ew(scsi, i * 4, b); } if (z) { - for (int i = 0; i < 16384; i++) { + int i; + for (i = 0; i < 16384; i++) { uae_u8 b; - zfile_fread(&b, 1, 1, z); + if (!zfile_fread(&b, 1, 1, z)) + break; scsi->rom[i * 2 + 0] = b; } + if (i < 16384) { + int ii = 0; + while (i < 16384) { + scsi->rom[i * 2 + 0] = scsi->rom[ii * 2 + 0]; + i++; + ii++; + } + } zfile_fclose(z); } } @@ -2261,7 +2277,6 @@ void adscsi_add_scsi_unit(int ch, struct uaedev_config_info *ci, struct romconfi } - void soft_scsi_free(void) { for (int i = 0; soft_scsi_devices[i]; i++) { -- 2.47.3