if (!srt->memory_after)
type |= chainedconfig;
}
- }
- else {
+ } else {
if (erc->memory_mid) {
mid = erc->memory_mid;
pid = erc->memory_pid;
cards[cardno++].map = NULL;
}
+ // add possible non-autoconfig boards
+ add_cpu_expansions(1);
+
bool fastmem_after = false;
if (currprefs.fastmem_autoconfig) {
fastmem_after = add_fastram_after_expansion(2);
}
};
-static const struct expansionsubromtype pcibridge_sub[] = {
- {
- _T("Prometheus"), _T("prometheus"), ROMTYPE_NOT | ROMTYPE_PCIBRIDGE
- },
+static const struct expansionsubromtype mediator_sub[] = {
{
- _T("G-REX"), _T("grex"), ROMTYPE_NOT | ROMTYPE_PCIBRIDGE
+ _T("1200TX"), _T("1200tx"), ROMTYPE_NOT | ROMTYPE_MEDIATOR
},
{
- _T("Mediator 1200TX 4M"), _T("mediator1200tx4m"), ROMTYPE_NOT | ROMTYPE_PCIBRIDGE
+ _T("4000MK2"), _T("4000mkii"), ROMTYPE_NOT | ROMTYPE_MEDIATOR
},
{
- _T("Mediator 1200TX 8M"), _T("mediator1200tx8m"), ROMTYPE_NOT | ROMTYPE_PCIBRIDGE
- },
- {
- _T("Mediator 4000MK2 256M"), _T("mediator4000mkii256m"), ROMTYPE_NOT | ROMTYPE_PCIBRIDGE
- },
+ NULL
+ }
+};
+static const struct expansionboardsettings mediator_settings[] = {
{
- _T("Mediator 4000MK2 512M"), _T("mediator4000mkii512m"), ROMTYPE_NOT | ROMTYPE_PCIBRIDGE
+ _T("Win Size"),
+ _T("winsize")
},
{
- _T("CVision/BVision"), _T("cbvision"), ROMTYPE_NOT | ROMTYPE_PCIBRIDGE
+ _T("Swap Config"),
+ _T("swapconfig")
},
{
NULL
}
};
-
static void fastlane_memory_callback(struct romconfig *rc, uae_u8 *ac, int size)
{
struct zfile *z = read_device_from_romconfig(rc, NULL);
false, EXPANSIONTYPE_SCSI
},
{
- _T("pcibridge"), _T("PCI Bridges"), _T(""),
- pcibridge_init, pcibridge_init2, NULL, ROMTYPE_PCIBRIDGE | ROMTYPE_NONE, 0, 0, 3, false,
- pcibridge_sub, 0,
+ _T("grex"), _T("G-REX"), _T("DCE"),
+ grex_init, NULL, NULL, ROMTYPE_GREX | ROMTYPE_NOT, 0, 0, 1, true,
+ },
+ {
+ _T("prometheus"), _T("Prometheus"), _T("Matay"),
+ prometheus_init, NULL, NULL, ROMTYPE_PROMETHEUS | ROMTYPE_NOT, 0, 0, 3, false,
+ },
+ {
+ _T("mediator"), _T("Mediator"), _T("Elbox"),
+ mediator_init, mediator_init2, NULL, ROMTYPE_MEDIATOR | ROMTYPE_NOT, 0, 0, 3, false,
+ mediator_sub, 0,
false, 0,
+ 0, 0, 0, false, NULL,
+ false,
+ mediator_settings
},
{
_T("a2090a"), _T("A2090a"), _T("Commodore"),
BOARD_MEMORY_HIGHMEM,
128 * 1024 * 1024,
0,
- dkb_wildfire_pci_init, NULL, 2, 0 // fake board
+ dkb_wildfire_pci_init, NULL, 1, 0 // fake board
},
{
NULL
* Hardware information by Radoslaw Kujawa
*
*/
+
+#define PCI_DEBUG_IO 0
+#define PCI_DEBUG_MEMORY 0
+#define PCI_DEBUG_CONFIG 1
+#define PCI_DEBUG_BRIDGE 0
+
#include "sysconfig.h"
#include "sysdeps.h"
#include "pci.h"
#include "ncr_scsi.h"
#include "newcpu.h"
+#include "uae.h"
+#include "rommgr.h"
#include "qemuvga/qemuuaeglue.h"
#include "qemuvga/queue.h"
return NULL;
struct pci_board_state *pcibs = &pcib->boards[idx];
if (!pcibs->board) {
+#if PCI_DEBUG_CONFIG
write_log(_T("- Empty slot %d\n"), idx);
+#endif
return NULL;
}
return pcibs;
return NULL;
}
-static const pci_addrbank *get_pci_io(uaecptr *addrp, struct pci_board_state **pcibsp, int *endianswap)
+static const pci_addrbank *get_pci_io(uaecptr *addrp, struct pci_board_state **pcibsp, int *endianswap, int size)
{
uaecptr addr = *addrp;
int bar;
- write_log(_T("get_pci_io %08x %08x\n"), addr, M68K_GETPC);
struct pci_bridge *pcib = get_pci_bridge(addr);
if (!pcib)
return NULL;
*endianswap = pcib->endian_swap_io;
addr -= pcib->io_offset;
addr &= (pcibs->bar_size[bar] & ~1) - 1;
+#if PCI_DEBUG_IO
+ write_log(_T("get_pci_io %08x=%08x %c:%d PC=%08x\n"), *addrp, addr, size < 0 ? 'W' : 'R', size < 0 ? -size : size, M68K_GETPC);
+#endif
*addrp = addr;
return &pcibs->board->bars[bar];
}
{
uaecptr addr = *addrp;
int bar;
+#if PCI_DEBUG_MEMORY
write_log(_T("get_pci_mem %08x %08x\n"), addr, M68K_GETPC);
+#endif
struct pci_bridge *pcib = get_pci_bridge(addr);
if (!pcib)
return NULL;
static uae_u8 *get_pci_config(uaecptr addr, int size, uae_u32 v, int *endianswap)
{
+#if PCI_DEBUG_CONFIG
if (size < 0) {
size = -size;
write_log(_T("PCI Config Space %s READ %08x PC=%08x\n"),
write_log(_T("PCI Config Space %s WRITE %08x = %08x PC=%08x\n"),
size == 4 ? _T("LONG") : (size == 2 ? _T("WORD") : _T("BYTE")), addr, v, M68K_GETPC);
}
+#endif
struct pci_bridge *pcib = get_pci_bridge(addr);
if (!pcib)
return NULL;
if (!pcibs)
return NULL;
*endianswap = pcib->endian_swap_config;
+#if PCI_DEBUG_CONFIG
write_log(_T("- Board %d (%s)\n"), pcibs->index, pcibs->board->label);
+#endif
create_config_data(pcibs);
return pcibs->config_data;
}
pcibs->bar_end[i] = pcibs->bar_start[i] + (pcibs->bar_size[i] & ~1) - 1;
if (enable && pcibs->bar[i] < 0xffff0000) {
pcibs->bar_enabled[i] = true;
+#if PCI_DEBUG_CONFIG
if (pcibs->bar_old[i] != pcibs->bar_start[i]) {
write_log(_T("Board %d ('%s') BAR%d: %08x-%08x\n"), pcibs->index, pci->label, i, pcibs->bar_start[i], pcibs->bar_end[i]);
}
+#endif
} else {
pcibs->bar_enabled[i] = false;
+#if PCI_DEBUG_CONFIG
if (pcibs->bar_old[i] != pcibs->bar_start[i]) {
write_log(_T("Board %d ('%s') BAR%d: %08x-%08x\n"), pcibs->index, pci->label, i, pcibs->bar_start[i], pcibs->bar_end[i]);
}
+#endif
}
pcibs->bar_old[i] = pcibs->bar_start[i];
}
v |= config[offset + 1] << 8;
v |= config[offset + 0] << 0;
}
+#if PCI_DEBUG_CONFIG
write_log(_T("- %08x\n"), v);
+#endif
}
return v;
}
v = config[(offset ^ (endianswap > 0 ? 2 : 0)) + 1] << 8;
v |= config[(offset ^ (endianswap > 0 ? 2 : 0)) + 0] << 0;
}
+#if PCI_DEBUG_CONFIG
write_log(_T("- %04x\n"), v);
+#endif
}
return v;
}
int endianswap;
uae_u8 *config = get_pci_config(addr, -1, 0, &endianswap);
if (config) {
- uae_u32 v;
uae_u32 offset = addr & 0xff;
if (!endianswap) {
v = config[offset + 0];
} else {
v = config[beswap(endianswap, offset)];
}
+#if PCI_DEBUG_CONFIG
write_log(_T("- %02x\n"), v);
+#endif
}
return v;
}
uae_u32 v = 0xffffffff;
int endianswap;
struct pci_board_state *pcibs;
- const pci_addrbank *a = get_pci_io(&addr, &pcibs, &endianswap);
+ const pci_addrbank *a = get_pci_io(&addr, &pcibs, &endianswap, 4);
if (a && a->lget) {
v = a->lget(pcibs, addr);
if (endianswap)
uae_u32 v = 0xffff;
int endianswap;
struct pci_board_state *pcibs;
- const pci_addrbank *a = get_pci_io(&addr, &pcibs, &endianswap);
+ const pci_addrbank *a = get_pci_io(&addr, &pcibs, &endianswap, 2);
if (a && a->wget) {
if (endianswap) {
v = a->wget(pcibs, addr ^ (endianswap > 0 ? 2 : 0));
uae_u32 v = 0xff;
int endianswap;
struct pci_board_state *pcibs;
- const pci_addrbank *a = get_pci_io(&addr, &pcibs, &endianswap);
+ const pci_addrbank *a = get_pci_io(&addr, &pcibs, &endianswap, 1);
if (a && a->bget) {
if (endianswap) {
v = a->bget(pcibs, beswap(endianswap, addr));
#endif
int endianswap;
struct pci_board_state *pcibs;
- const pci_addrbank *a = get_pci_io(&addr, &pcibs, &endianswap);
+ const pci_addrbank *a = get_pci_io(&addr, &pcibs, &endianswap, -4);
if (a && a->lput) {
if (endianswap)
b = endianswap_long(b);
#endif
int endianswap;
struct pci_board_state *pcibs;
- const pci_addrbank *a = get_pci_io(&addr, &pcibs, &endianswap);
+ const pci_addrbank *a = get_pci_io(&addr, &pcibs, &endianswap, -2);
if (a && a->wput) {
if (endianswap) {
b = endianswap_word(b);
#endif
int endianswap;
struct pci_board_state *pcibs;
- const pci_addrbank *a = get_pci_io(&addr, &pcibs, &endianswap);
+ const pci_addrbank *a = get_pci_io(&addr, &pcibs, &endianswap, -1);
if (a && a->bput) {
if (endianswap) {
a->bput(pcibs, beswap(endianswap, addr), b);
special_mem |= S_READ;
#endif
uae_u32 v = 0;
- write_log(_T("pci_bridge_lget %08x PC=%08x\n"), addr, M68K_GETPC);
struct pci_bridge *pcib = get_pci_bridge(addr);
if (!pcib)
return v;
v |= pcib->config[0];
if (pcib == bridges[PCI_BRIDGE_GREX])
v |= 0x02000000;
+ if (!pcib->irq)
+ v |= 0x80000000;
+ if (!pcib->intena)
+ v |= 0x00000020;
break;
case 1:
v = pcib->intena ? 1 : 0;
break;
}
}
- write_log(_T("=%08x\n"), v);
+#if PCI_DEBUG_BRIDGE
+ write_log(_T("pci_bridge_lget %08x=%08x PC=%08x\n"), addr, v, M68K_GETPC);
+#endif
return v;
}
static uae_u32 REGPARAM2 pci_bridge_wget(uaecptr addr)
special_mem |= S_READ;
#endif
uae_u16 v = 0;
+#if PCI_DEBUG_BRIDGE
write_log(_T("pci_bridge_wget %08x PC=%08x\n"), addr, M68K_GETPC);
+#endif
return v;
}
static uae_u32 REGPARAM2 pci_bridge_bget(uaecptr addr)
int offset = addr & 15;
v = pcib->config[offset / 4];
}
+#if PCI_DEBUG_BRIDGE
write_log(_T("pci_bridge_bget %08x %02x PC=%08x\n"), addr, v, M68K_GETPC);
+#endif
return v;
}
static void REGPARAM2 pci_bridge_lput(uaecptr addr, uae_u32 b)
#ifdef JIT
special_mem |= S_WRITE;
#endif
+#if PCI_DEBUG_BRIDGE
write_log(_T("pci_bridge_lput %08x %08x PC=%08x\n"), addr, b, M68K_GETPC);
+#endif
struct pci_bridge *pcib = get_pci_bridge(addr);
if (!pcib)
return;
switch (reg)
{
case 0:
- pcib->endian_swap_memory = pcib->endian_swap_io = (b & 2) != 0;
+ pcib->endian_swap_memory = pcib->endian_swap_io = (b & 2) != 0 ? -1 : 0;
break;
case 1:
pcib->intena = (b & 1) ? 0xff : 0x00;
break;
case 3:
pcib->config[0] = b & 1;
- pcib->endian_swap_memory = pcib->endian_swap_io = (b & 2) != 0;
+ pcib->endian_swap_memory = pcib->endian_swap_io = (b & 2) != 0 ? -1 : 0;
break;
}
}
}
}
}
+#if PCI_DEBUG_BRIDGE
write_log(_T("pci_bridge_wput %08x %04x PC=%08x\n"), addr, b & 0xffff, M68K_GETPC);
+#endif
}
static void REGPARAM2 pci_bridge_bput(uaecptr addr, uae_u32 b)
{
struct pci_bridge *pcib = get_pci_bridge(addr);
if (!pcib)
return;
+#if PCI_DEBUG_BRIDGE
write_log(_T("pci_bridge_bput %08x %02x PC=%08x\n"), addr, b & 0xff, M68K_GETPC);
+#endif
if (!pcib->configured) {
uaecptr offset = addr & 65535;
if (pcib->bank_zorro == 2) {
pcib->memory_offset = pcib->window << 16;
}
pcib->memory_offset -= pcib->baseaddress;
+#if PCI_DEBUG_BRIDGE
if (pcib->memory_offset != offset) {
write_log(_T("Mediator window: %08x offset: %08x\n"),
pcib->memory_offset + pcib->baseaddress, pcib->memory_offset);
}
+#endif
}
static uae_u32 REGPARAM2 pci_bridge_bget_2(uaecptr addr)
}
}
}
+#if PCI_DEBUG_BRIDGE
write_log(_T("pci_bridge_bget_2 %08x %02x PC=%08x\n"), addr, v, M68K_GETPC);
+#endif
return v;
}
static uae_u32 REGPARAM2 pci_bridge_wget_2(uaecptr addr)
special_mem |= S_READ;
#endif
uae_u16 v = 0;
+#if PCI_DEBUG_BRIDGE
write_log(_T("pci_bridge_wget_2 %08x PC=%08x\n"), addr, M68K_GETPC);
+#endif
struct pci_bridge *pcib = get_pci_bridge_2(addr);
if (!pcib)
return v;
special_mem |= S_READ;
#endif
uae_u32 v = 0;
+#if PCI_DEBUG_BRIDGE
write_log(_T("pci_bridge_lget_2 %08x PC=%08x\n"), addr, M68K_GETPC);
+#endif
struct pci_bridge *pcib = get_pci_bridge_2(addr);
if (!pcib)
return v;
struct pci_bridge *pcib = get_pci_bridge_2(addr);
if (!pcib)
return;
+#if PCI_DEBUG_BRIDGE
write_log(_T("pci_bridge_bput_2 %08x %02x PC=%08x\n"), addr, b & 0xff, M68K_GETPC);
+#endif
if (!pcib->configured_2) {
uaecptr offset = addr & 65535;
if (pcib->bank_2_zorro == 2) {
}
} else if (offset == 11) {
pcib->intena = b >> 4;
+ } else if (offset == 0x40) {
+ // power off
+ uae_quit();
}
}
if (pcib->bank_2_zorro == 3) {
}
}
}
+#if PCI_DEBUG_BRIDGE
write_log(_T("pci_bridge_wput_2 %08x %04x PC=%08x\n"), addr, b & 0xffff, M68K_GETPC);
+#endif
}
static void REGPARAM2 pci_bridge_lput_2(uaecptr addr, uae_u32 b)
{
#ifdef JIT
special_mem |= S_WRITE;
#endif
+#if PCI_DEBUG_BRIDGE
write_log(_T("pci_bridge_lput_2 %08x %08x PC=%08x\n"), addr, b, M68K_GETPC);
+#endif
struct pci_bridge *pcib = get_pci_bridge_2(addr);
if (!pcib)
return;
static void pci_dump_out(const TCHAR *txt, int log)
{
if (log > 0)
- write_log(txt);
+ write_log(_T("%s"), txt);
else if (log == 0)
console_out(txt);
}
struct pci_bridge *pcib = get_pci_bridge(addr);
addr -= pcib->baseaddress;
- if ((addr & 0xffff0000) != 0x000f0000)
+ if ((addr & 0xffff0f00) != 0x000f0000)
return -1;
int slot = (addr & 0xf000) >> 13;
if (slot > 3)
return &expamem_null;
pcib->label = _T("Prometheus");
pcib->endian_swap_config = 1;
- pcib->endian_swap_io = 1;
- pcib->endian_swap_memory = 1;
+ pcib->endian_swap_io = -1;
+ pcib->endian_swap_memory = -1;
pcib->intena = 0xff;
pcib->intreq_mask = 0x0008;
pcib->get_index = prometheus_get_index;
return slot;
}
-static addrbank *mediator_pci_init_1200(struct romconfig *rc)
+static void mediator_pci_init_1200(struct pci_bridge *pcib)
{
- struct pci_bridge *pcib = pci_bridge_alloc_zorro(PCI_BRIDGE_MEDIATOR, rc);
- if (!pcib)
- return &expamem_null;
pcib->label = _T("Mediator 1200");
pcib->endian_swap_config = -1;
pcib->endian_swap_io = -1;
pcib->bank_zorro = 2;
pcib->bank_2_zorro = 2;
mediator_set_window_offset(pcib, 0);
+}
- add_pci_devices(pcib);
-
+static addrbank *mediator_pci_init_1200_1(struct romconfig *rc)
+{
+ struct pci_bridge *pcib;
+ if (!(rc->device_settings & 2)) {
+ // io first
+ pcib = pci_bridge_alloc_zorro(PCI_BRIDGE_MEDIATOR, rc);
+ if (!pcib)
+ return &expamem_null;
+ mediator_pci_init_1200(pcib);
+ add_pci_devices(pcib);
+ } else {
+ pcib = pci_bridge_get_zorro(rc);
+ if (!pcib)
+ return &expamem_null;
+ }
memset(pcib->acmemory_2, 0xff, sizeof pcib->acmemory_2);
for (int i = 0; i < sizeof autoconfig_mediator_1200tx_1; i++) {
ew(pcib->acmemory_2, i * 4, autoconfig_mediator_1200tx_1[i]);
}
return &pci_bridge_bank_2;
}
-static addrbank *mediator_pci_init_1200_2(struct romconfig *rc, int size)
-{
- struct pci_bridge *pcib = pci_bridge_get_zorro(rc);
- if (!pcib)
- return &expamem_null;
+static addrbank *mediator_pci_init_1200_2(struct romconfig *rc)
+{
+ struct pci_bridge *pcib;
+ if (!(rc->device_settings & 2)) {
+ // memory last
+ pcib = pci_bridge_get_zorro(rc);
+ if (!pcib)
+ return &expamem_null;
+ } else {
+ // memory first
+ pcib = pci_bridge_alloc_zorro(PCI_BRIDGE_MEDIATOR, rc);
+ if (!pcib)
+ return &expamem_null;
+ mediator_pci_init_1200(pcib);
+ add_pci_devices(pcib);
+ }
memset(pcib->acmemory, 0xff, sizeof pcib->acmemory);
- const uae_u8 *ac = size ? autoconfig_mediator_1200tx_2_8m : autoconfig_mediator_1200tx_2_4m;
+ const uae_u8 *ac = (rc->device_settings & 1) ? autoconfig_mediator_1200tx_2_8m : autoconfig_mediator_1200tx_2_4m;
for (int i = 0; i < 16; i++) {
ew(pcib->acmemory, i * 4, ac[i]);
}
return &pci_bridge_bank;
}
-static addrbank *mediator_pci_init_4000(struct romconfig *rc, int size)
+static void mediator_pci_init_4000(struct pci_bridge *pcib)
{
- struct pci_bridge *pcib = pci_bridge_alloc_zorro(PCI_BRIDGE_MEDIATOR, rc);
- if (!pcib)
- return &expamem_null;
pcib->label = _T("Mediator 4000");
pcib->endian_swap_config = -1;
pcib->endian_swap_io = -1;
pcib->bank_zorro = 3;
pcib->bank_2_zorro = 3;
mediator_set_window_offset(pcib, 0);
+}
- add_pci_devices(pcib);
-
- memset(pcib->acmemory, 0xff, sizeof pcib->acmemory);
- const uae_u8 *ac = size ? autoconfig_mediator_4000mk2_512m : autoconfig_mediator_4000mk2_256m;
- for (int i = 0; i < 16; i++) {
- ew(pcib->acmemory, i * 4, ac[i]);
+static addrbank *mediator_pci_init_4000_1(struct romconfig *rc)
+{
+ struct pci_bridge *pcib;
+ if (!(rc->device_settings & 2)) {
+ // io first
+ pcib = pci_bridge_alloc_zorro(PCI_BRIDGE_MEDIATOR, rc);
+ if (!pcib)
+ return &expamem_null;
+ mediator_pci_init_4000(pcib);
+ add_pci_devices(pcib);
+ } else {
+ pcib = pci_bridge_get_zorro(rc);
+ if (!pcib)
+ return &expamem_null;
}
- return pcib->bank;
+ memset(pcib->acmemory_2, 0xff, sizeof pcib->acmemory_2);
+ for (int i = 0; i < sizeof autoconfig_mediator_4000mk2_2; i++) {
+ ew(pcib->acmemory_2, i * 4, autoconfig_mediator_4000mk2_2[i]);
+ }
+ return &pci_bridge_bank_2;
}
static addrbank *mediator_pci_init_4000_2(struct romconfig *rc)
{
- struct pci_bridge *pcib = pci_bridge_get_zorro(rc);
- if (!pcib)
- return &expamem_null;
+ struct pci_bridge *pcib;
+ if (!(rc->device_settings & 2)) {
+ // memory last
+ pcib = pci_bridge_get_zorro(rc);
+ if (!pcib)
+ return &expamem_null;
+ } else {
+ // memory first
+ pcib = pci_bridge_alloc_zorro(PCI_BRIDGE_MEDIATOR, rc);
+ if (!pcib)
+ return &expamem_null;
- memset(pcib->acmemory_2, 0xff, sizeof pcib->acmemory_2);
- for (int i = 0; i < sizeof autoconfig_mediator_4000mk2_2; i++) {
- ew(pcib->acmemory_2, i * 4, autoconfig_mediator_4000mk2_2[i]);
+ mediator_pci_init_4000(pcib);
+ add_pci_devices(pcib);
}
- return pcib->bank_2;
+ memset(pcib->acmemory, 0xff, sizeof pcib->acmemory);
+ const uae_u8 *ac = (rc->device_settings & 1) ? autoconfig_mediator_4000mk2_512m : autoconfig_mediator_4000mk2_256m;
+ for (int i = 0; i < 16; i++) {
+ ew(pcib->acmemory, i * 4, ac[i]);
+ }
+ return &pci_bridge_bank;
}
-addrbank *pcibridge_init(struct romconfig *rc)
+addrbank *mediator_init(struct romconfig *rc)
{
switch (rc->subtype)
{
case 0:
- return prometheus_pci_init(rc);
+ if (rc->device_settings & 2)
+ return mediator_pci_init_1200_2(rc);
+ else
+ return mediator_pci_init_1200_1(rc);
case 1:
- return grex_pci_init(rc);
- case 2:
- return mediator_pci_init_1200(rc);
- case 3:
- return mediator_pci_init_1200(rc);
- case 4:
- return mediator_pci_init_4000(rc, 0);
- case 5:
- return mediator_pci_init_4000(rc, 1);
- case 6:
- return cbvision(rc);
+ if (rc->device_settings & 2)
+ return mediator_pci_init_4000_2(rc);
+ else
+ return mediator_pci_init_4000_1(rc);
}
return &expamem_null;
}
-addrbank *pcibridge_init2(struct romconfig *rc)
+
+addrbank *mediator_init2(struct romconfig *rc)
{
switch (rc->subtype)
{
- case 2:
- return mediator_pci_init_1200_2(rc, 0);
- case 3:
- return mediator_pci_init_1200_2(rc, 1);
- case 4:
- return mediator_pci_init_4000_2(rc);
- case 5:
- return mediator_pci_init_4000_2(rc);
+ case 0:
+ if (rc->device_settings & 2)
+ return mediator_pci_init_1200_1(rc);
+ else
+ return mediator_pci_init_1200_2(rc);
+ case 1:
+ if (rc->device_settings & 2)
+ return mediator_pci_init_4000_1(rc);
+ else
+ return mediator_pci_init_4000_2(rc);
}
return &expamem_null;
}
+
+addrbank *prometheus_init(struct romconfig *rc)
+{
+ return prometheus_pci_init(rc);
+}
+
+addrbank *cbvision_init(struct romconfig *rc)
+{
+ return cbvision(rc);
+}
+
+addrbank *grex_init(struct romconfig *rc)
+{
+ return grex_pci_init(rc);
+}
static void *sysdata;
static uae_u8 *transmitbuffer;
static volatile int transmitlen;
-static volatile int transmitnow;
static void ne2000_receive_check(void);
memcpy(d, transmitbuffer, transmitlen);
*len = transmitlen;
transmitlen = 0;
- transmitnow = 1;
return 1;
}
//#include "sysemu/sysemu.h"
/* debug NE2000 card */
-#define DEBUG_NE2000
+//#define DEBUG_NE2000
static NetClientState ncs;
static NE2000State ne2000state;
int offset, page, index;
addr &= 0xf;
+ page = s->cmd >> 6;
+ offset = addr | (page << 4);
+ if (addr == E8390_CMD)
+ page = offset = 0;
#ifdef DEBUG_NE2000
- write_log("NE2000: write addr=0x%x val=0x%02x\n", addr, val);
+ write_log("NE2000: write reg=0x%x val=0x%02x\n", addr, val);
#endif
if (addr == E8390_CMD) {
/* control register */
s->isr &= ~ENISR_RESET;
/* test specific case: zero length transfer */
if ((val & (E8390_RREAD | E8390_RWRITE)) &&
- s->rcnt == 0) {
+ s->tcnt == 0) {
s->isr |= ENISR_RDC;
ne2000_update_irq(s);
}
if (index + s->tcnt <= NE2000_PMEM_END) {
transmitbuffer = s->mem + index;
transmitlen = s->tcnt;
+#ifdef DEBUG_NE2000
+ write_log("NE2000: %d byte transmit\n", s->tcnt);
+#endif
ethernet_trigger(td, sysdata);
#if 0
qemu_send_packet(qemu_get_queue(s->nic), s->mem + index, s->tcnt);
int offset, page, ret;
addr &= 0xf;
- if (addr == E8390_CMD) {
+ page = s->cmd >> 6;
+ offset = addr | (page << 4);
+ if (addr == E8390_CMD) {
ret = s->cmd;
} else {
- page = s->cmd >> 6;
- offset = addr | (page << 4);
switch(offset) {
case EN0_TSR:
ret = s->tsr;
}
ne2000_receive_check();
#ifdef DEBUG_NE2000
- write_log("NE2000: read addr=0x%x val=%02x\n", addr, ret);
+ write_log("NE2000: read reg=0x%x val=0x%02x\n", offset, ret);
#endif
return ret;
}
return;
if (s->dcfg & 0x01) {
/* 16 bit access */
- ne2000_mem_writew(s, s->rsar, val);
+ ne2000_mem_writew(s, s->rsar, val);
ne2000_dma_update(s, 2);
} else {
/* 8 bit access */
uint64_t v;
NE2000State *s = (NE2000State*)opaque;
- if (addr < 0x10 && size == 1) {
- v = ne2000_ioport_read(s, addr);
- } else if (addr == 0x10) {
+ if (addr < 0x10) {
+ if (size == 1) {
+ v = ne2000_ioport_read(s, addr);
+ } else {
+ v = ne2000_ioport_read(s, addr);
+ v |= ne2000_ioport_read(s, addr) << 8;
+ }
+ } else if (addr >= 0x10 && addr <= 0x17) {
if (size <= 2) {
v = ne2000_asic_ioport_read(s, addr);
} else {
v = ne2000_asic_ioport_readl(s, addr);
}
- } else if (addr == 0x1f && size == 1) {
+ } else if (addr >= 0x18 && addr < 0x20) {
v = ne2000_reset_ioport_read(s, addr);
} else {
v = ((uint64_t)1 << (size * 8)) - 1;
}
+#if defined(DEBUG_NE2000)
write_log(_T("NE2000_READ %08x=%08x %d\n"), addr, (uae_u32)v, size);
+#endif
return v;
}
{
NE2000State *s = (NE2000State*)opaque;
+#if defined(DEBUG_NE2000)
write_log(_T("NE2000_WRITE %08x %08x %d\n"), addr, (uae_u32)data, size);
-
- if (addr < 0x10 && size == 1) {
- ne2000_ioport_write(s, addr, data);
- } else if (addr == 0x10) {
- if (size <= 2) {
+#endif
+
+ if (addr < 0x10) {
+ if (size == 1) {
+ ne2000_ioport_write(s, addr, data);
+ } else {
+ ne2000_ioport_write(s, addr, data);
+ ne2000_ioport_write(s, addr + 1, data >> 8);
+ }
+ } else if (addr >= 0x10 && addr <= 0x17) {
+ if (size <= 2) {
ne2000_asic_ioport_write(s, addr, data);
} else {
ne2000_asic_ioport_writel(s, addr, data);
}
- } else if (addr == 0x1f && size == 1) {
+ } else if (addr >= 0x18 && addr < 0x20) {
ne2000_reset_ioport_write(s, addr, data);
}
}
type_init(ne2000_register_types)
#endif
-#define MAX_PACKET_SIZE 2000
-#define RECEIVE_BUFFER_INDEX_MASK 3
+#define MAX_PACKET_SIZE 1600
+#define MAX_RECEIVE_BUFFER_INDEX 256
static int receive_buffer_index;
-static uae_u8 receive_buffer[4][MAX_PACKET_SIZE];
+static uae_u8 *receive_buffer;
static int receive_buffer_read, receive_buffer_write;
-static int receive_buffer_size[4];
+static int receive_buffer_size[MAX_RECEIVE_BUFFER_INDEX];
static void ne2000_receive_check(void)
{
- while (receive_buffer_read != receive_buffer_write) {
- if (receive_buffer_size[receive_buffer_read]) {
- if (ne2000state.isr & (ENISR_RX | ENISR_TX))
- return;
- if (ne2000_receive(&ncs, receive_buffer[receive_buffer_read], receive_buffer_size[receive_buffer_read]) < 0)
- return;
- receive_buffer_size[receive_buffer_read] = 0;
- receive_buffer_read++;
- receive_buffer_read &= RECEIVE_BUFFER_INDEX_MASK;
- }
+ if (receive_buffer_read != receive_buffer_write) {
+ if (ne2000state.isr & ENISR_RX)
+ return;
+ if (ne2000_receive(&ncs, receive_buffer + receive_buffer_read * MAX_PACKET_SIZE, receive_buffer_size[receive_buffer_read]) < 0)
+ return;
+#ifdef DEBUG_NE2000
+ write_log("NE2000: %d byte receive accepted (%d %d)\n", receive_buffer_size[receive_buffer_read], receive_buffer_read, receive_buffer_write);
+#endif
+ receive_buffer_read++;
+ receive_buffer_read &= (MAX_RECEIVE_BUFFER_INDEX - 1);
}
}
static void gotfunc(void *devv, const uae_u8 *databuf, int len)
{
+#ifdef DEBUG_NE2000
+ write_log("NE2000: %d byte received (%d %d)\n", len, receive_buffer_read, receive_buffer_write);
+#endif
ne2000_receive_check();
- if (len > MAX_PACKET_SIZE)
+ if (len > MAX_PACKET_SIZE)
return;
- if (((receive_buffer_write + 1) & RECEIVE_BUFFER_INDEX_MASK) == receive_buffer_read)
+ if (((receive_buffer_write + 1) & (MAX_RECEIVE_BUFFER_INDEX - 1)) == receive_buffer_read) {
+ write_log("NE2000: receive buffer full\n");
return;
- memcpy(receive_buffer[receive_buffer_write], databuf, len);
+ }
+ memcpy(receive_buffer + receive_buffer_write * MAX_PACKET_SIZE, databuf, len);
receive_buffer_size[receive_buffer_write] = len;
receive_buffer_write++;
- receive_buffer_write &= RECEIVE_BUFFER_INDEX_MASK;
+ receive_buffer_write &= (MAX_RECEIVE_BUFFER_INDEX - 1);
ne2000_receive_check();
}
{
ne2000_reset2(&ne2000state);
receive_buffer_read = receive_buffer_write = 0;
- for (int i = 0; i <= RECEIVE_BUFFER_INDEX_MASK; i++)
- receive_buffer_size[i] = 0;
}
static void ne2000_free(struct pci_board_state *pcibs)
xfree(sysdata);
td = NULL;
sysdata = NULL;
+ xfree(receive_buffer);
+ receive_buffer = NULL;
}
static bool ne2000_init(struct pci_board_state *pcibs)
ncs.ne2000state = &ne2000state;
memset(&ne2000state, 0, sizeof ne2000state);
+ if (!receive_buffer) {
+ receive_buffer = xcalloc(uae_u8, MAX_PACKET_SIZE * MAX_RECEIVE_BUFFER_INDEX);
+ }
+
td = NULL;
uae_u8 *m = ncs.ne2000state->c.macaddr.a;
memset(m, 0, 6);