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)
struct wd_state *scsi;
if (ch < 0) {
- freescsi(wd);
+ freencrunit(*wd);
+ *wd = NULL;
}
if ((*wd) == NULL) {
scsi = xcalloc(struct wd_state, 1);
if (rc)
rc->unitdata = scsi;
scsi->rc = rc;
+ scsi->self_ptr = wd;
*wd = scsi;
return scsi;
}
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);
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);
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)
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]);
}
}
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]);
}
}
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);
ide_boards[i] = ide;
rc->unitdata = ide;
ide->rc = rc;
+ ide->self_ptr = idep;
if (idep)
*idep = ide;
return ide;
}
}
-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;
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)
int rom_size, rom_mask;
addrbank *bank;
struct romconfig *rc;
+ struct wd_state **self_ptr;
smp_comm_pipe requests;
volatile int scsi_thread_running;
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);
int userdata;
int subtype;
struct romconfig *rc;
+ struct ide_board **self_ptr;
};
struct ide_hdf
// Other IDE controllers
-void idecontroller_free_units(void);
void idecontroller_free(void);
void idecontroller_reset(void);
void idecontroller_rethink(void);
int dma_delay_val;
uae_u8 states[16];
struct romconfig *rc;
+ struct ncr9x_state **self_ptr;
uae_u8 data;
bool data_valid;
}
}
-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)
struct ncr9x_state *scsi;
if (ch < 0) {
- freencrunit(ncr);
+ freencrunit(*ncr);
+ *ncr = NULL;
}
if ((*ncr) == NULL) {
scsi = xcalloc(struct ncr9x_state, 1);
if (rc)
rc->unitdata = scsi;
scsi->rc = rc;
+ scsi->self_ptr = ncr;
*ncr = scsi;
return scsi;
}
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;
void ncr9x_free(void)
{
for (int i = 0; ncr_units[i]; i++) {
- ncr9x_free2(ncr_units[i]);
+ freencrunit(ncr_units[i]);
}
}
{
}
+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;
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;
}
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;
}
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;
}
bool irq;
void (*irq_func)(int);
struct romconfig *rc;
+ struct ncr_state **self_ptr;
};
#define MAX_NCR_UNITS 10
}
}
-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)
struct ncr_state *scsi;
if (ch < 0) {
- freencrunit(ncr);
+ freencrunit(*ncr);
+ *ncr = NULL;
}
if ((*ncr) == NULL) {
scsi = xcalloc(struct ncr_state, 1);
if (rc)
rc->unitdata = scsi;
scsi->rc = rc;
+ scsi->self_ptr = ncr;
*ncr = scsi;
return scsi;
}
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;
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)
void ncr_free(void)
{
for (int i = 0; i < MAX_NCR_UNITS; i++) {
- ncr_free2(&ncr_units[i]);
+ freencrunit(ncr_units[i]);
}
}
}
}
+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;
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;
}
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;
}
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;
}
int subtype;
int dma_direction;
struct romconfig *rc;
+ struct soft_scsi **self_ptr;
int dmac_direction;
uaecptr dmac_address;
rs->device[j] = NULL;
}
xfree(s->databufferptr);
+ xfree(s->rom);
+ if (s->self_ptr)
+ *s->self_ptr = NULL;
xfree(s);
}
if (ch < 0) {
freescsi(ncr);
+ *ncr = NULL;
}
if ((*ncr) == NULL) {
scsi = xcalloc(struct soft_scsi, 1);
soft_scsi_devices[i] = scsi;
rc->unitdata = scsi;
scsi->rc = rc;
+ scsi->self_ptr = ncr;
if (ncr)
*ncr = scsi;
return scsi;
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();
}
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);
}
}
}
-
void soft_scsi_free(void)
{
for (int i = 0; soft_scsi_devices[i]; i++) {