q800 pull request 20210908
mac_via: remove MAC_VIA device and prepare for Nubus IRQs -----BEGIN PGP SIGNATURE----- iQJGBAABCAAwFiEEzS913cjjpNwuT1Fz8ww4vT8vvjwFAmE42CcSHGxhdXJlbnRA dml2aWVyLmV1AAoJEPMMOL0/L748rb0P/Roslh9kkRTrSzVXmbZBtGBd0F5lnQa7 nh/X77oXuPKu4WKpqExIv+urKtIPgwn7OmSIGqhhxpu2Xy8/JGraQoHhCxd7Hefz Pcm51xQNpXgz4u/rkh5kmDxlN3nFM/xrx5Zn2+MxQCNroLtzhlWKmvgbh6eRsPX1 71rT/QyUDZ9HxYJ9i7oDeAVZ6MK86VegzqWRHwZ9AmcKdD1USwCzquYdLt4oXMkK AloTteOBt4K2Ul3X1pt4Wkbbj0wmXKB8QAzSEAhuZD29bCQVPPxudtkOd/paO1AT jPefTbdpIKOMcmIYuzu/hO67enEA870iXcdlBJwL9M3/kGFdSnfgCumHDUPA3F8T xZAPlRvBNUDlKhjUHqgiy4WY0zseDphETEFUcwYquhU6rYRWYc3ehaVNtRrCD5og OGDdNnOjQDXhAEY0GYGtdL7obGKTpGGMJ/1nnZrhbjRG9YnpXz5Pn3QvktgpdSMo dx092ehrqO0nRp3mqwQYy6uwwe6wVgktENH2wWwkiNu+cBfUPBPrm3nPeP8Yfr35 x9Jg+42KzsyFdTZ5ApvHpzK1WUczprX0l+gDZTU98rIYNECu/zQ73C2m0rVVbhQZ Emz0a43IRDSnmgu115nKlT3m6QZa7wYI+eO0opSPTZwz9oBiTpUaY7tcPXJFWWZZ OVAZZsFHab3A =HVcY -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/vivier/tags/q800-pull-request' into staging q800 pull request 20210908 mac_via: remove MAC_VIA device and prepare for Nubus IRQs # gpg: Signature made Wed 08 Sep 2021 16:35:03 BST # gpg: using RSA key CD2F75DDC8E3A4DC2E4F5173F30C38BD3F2FBE3C # gpg: issuer "laurent@vivier.eu" # gpg: Good signature from "Laurent Vivier <lvivier@redhat.com>" [full] # gpg: aka "Laurent Vivier <laurent@vivier.eu>" [full] # gpg: aka "Laurent Vivier (Red Hat) <lvivier@redhat.com>" [full] # Primary key fingerprint: CD2F 75DD C8E3 A4DC 2E4F 5173 F30C 38BD 3F2F BE3C * remotes/vivier/tags/q800-pull-request: mac_via: add qdev gpios for nubus slot interrupts to VIA2 mac_via: rename VIA2_IRQ_SLOT_BIT to VIA2_IRQ_NUBUS_BIT mac_via: remove explicit viaN prefix from VIA IRQ gpios mac_via: remove mac_via device mac_via: move VIA1 realize logic from mac_via_realize() to mos6522_q800_via1_realize() mac_via: move VIA1 reset logic from mac_via_reset() to mos6522_q800_via1_reset() mac_via: move q800 VIA1 timer variables to q800 VIA1 VMStateDescription mac_via: move ADB variables to MOS6522Q800VIA1State mac_via: move PRAM/RTC variables to MOS6522Q800VIA1State mac_via: move PRAM contents and block backend to MOS6522Q800VIA1State mac_via: move last_b variable into q800 VIA1 VMStateDescription mac_via: introduce new VMStateDescription for q800 VIA1 and VIA2 Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
6d1272d3ef
@ -225,7 +225,7 @@ static void q800_init(MachineState *machine)
|
|||||||
hwaddr parameters_base;
|
hwaddr parameters_base;
|
||||||
CPUState *cs;
|
CPUState *cs;
|
||||||
DeviceState *dev;
|
DeviceState *dev;
|
||||||
DeviceState *via_dev;
|
DeviceState *via1_dev, *via2_dev;
|
||||||
DeviceState *escc_orgate;
|
DeviceState *escc_orgate;
|
||||||
SysBusESPState *sysbus_esp;
|
SysBusESPState *sysbus_esp;
|
||||||
ESPState *esp;
|
ESPState *esp;
|
||||||
@ -270,28 +270,30 @@ static void q800_init(MachineState *machine)
|
|||||||
object_property_set_link(OBJECT(glue), "cpu", OBJECT(cpu), &error_abort);
|
object_property_set_link(OBJECT(glue), "cpu", OBJECT(cpu), &error_abort);
|
||||||
sysbus_realize_and_unref(SYS_BUS_DEVICE(glue), &error_fatal);
|
sysbus_realize_and_unref(SYS_BUS_DEVICE(glue), &error_fatal);
|
||||||
|
|
||||||
/* VIA */
|
/* VIA 1 */
|
||||||
|
via1_dev = qdev_new(TYPE_MOS6522_Q800_VIA1);
|
||||||
via_dev = qdev_new(TYPE_MAC_VIA);
|
|
||||||
dinfo = drive_get(IF_MTD, 0, 0);
|
dinfo = drive_get(IF_MTD, 0, 0);
|
||||||
if (dinfo) {
|
if (dinfo) {
|
||||||
qdev_prop_set_drive(via_dev, "drive", blk_by_legacy_dinfo(dinfo));
|
qdev_prop_set_drive(via1_dev, "drive", blk_by_legacy_dinfo(dinfo));
|
||||||
}
|
}
|
||||||
sysbus = SYS_BUS_DEVICE(via_dev);
|
sysbus = SYS_BUS_DEVICE(via1_dev);
|
||||||
sysbus_realize_and_unref(sysbus, &error_fatal);
|
sysbus_realize_and_unref(sysbus, &error_fatal);
|
||||||
sysbus_mmio_map(sysbus, 0, VIA_BASE);
|
sysbus_mmio_map(sysbus, 1, VIA_BASE);
|
||||||
qdev_connect_gpio_out_named(DEVICE(sysbus), "irq", 0,
|
sysbus_connect_irq(sysbus, 0, qdev_get_gpio_in(glue, 0));
|
||||||
qdev_get_gpio_in(glue, 0));
|
|
||||||
qdev_connect_gpio_out_named(DEVICE(sysbus), "irq", 1,
|
|
||||||
qdev_get_gpio_in(glue, 1));
|
|
||||||
|
|
||||||
|
adb_bus = qdev_get_child_bus(via1_dev, "adb.0");
|
||||||
adb_bus = qdev_get_child_bus(via_dev, "adb.0");
|
|
||||||
dev = qdev_new(TYPE_ADB_KEYBOARD);
|
dev = qdev_new(TYPE_ADB_KEYBOARD);
|
||||||
qdev_realize_and_unref(dev, adb_bus, &error_fatal);
|
qdev_realize_and_unref(dev, adb_bus, &error_fatal);
|
||||||
dev = qdev_new(TYPE_ADB_MOUSE);
|
dev = qdev_new(TYPE_ADB_MOUSE);
|
||||||
qdev_realize_and_unref(dev, adb_bus, &error_fatal);
|
qdev_realize_and_unref(dev, adb_bus, &error_fatal);
|
||||||
|
|
||||||
|
/* VIA 2 */
|
||||||
|
via2_dev = qdev_new(TYPE_MOS6522_Q800_VIA2);
|
||||||
|
sysbus = SYS_BUS_DEVICE(via2_dev);
|
||||||
|
sysbus_realize_and_unref(sysbus, &error_fatal);
|
||||||
|
sysbus_mmio_map(sysbus, 1, VIA_BASE + VIA_SIZE);
|
||||||
|
sysbus_connect_irq(sysbus, 0, qdev_get_gpio_in(glue, 1));
|
||||||
|
|
||||||
/* MACSONIC */
|
/* MACSONIC */
|
||||||
|
|
||||||
if (nb_nics > 1) {
|
if (nb_nics > 1) {
|
||||||
@ -375,11 +377,9 @@ static void q800_init(MachineState *machine)
|
|||||||
|
|
||||||
sysbus = SYS_BUS_DEVICE(dev);
|
sysbus = SYS_BUS_DEVICE(dev);
|
||||||
sysbus_realize_and_unref(sysbus, &error_fatal);
|
sysbus_realize_and_unref(sysbus, &error_fatal);
|
||||||
sysbus_connect_irq(sysbus, 0, qdev_get_gpio_in_named(via_dev,
|
sysbus_connect_irq(sysbus, 0, qdev_get_gpio_in(via2_dev,
|
||||||
"via2-irq",
|
|
||||||
VIA2_IRQ_SCSI_BIT));
|
VIA2_IRQ_SCSI_BIT));
|
||||||
sysbus_connect_irq(sysbus, 1,
|
sysbus_connect_irq(sysbus, 1, qdev_get_gpio_in(via2_dev,
|
||||||
qdev_get_gpio_in_named(via_dev, "via2-irq",
|
|
||||||
VIA2_IRQ_SCSI_DATA_BIT));
|
VIA2_IRQ_SCSI_DATA_BIT));
|
||||||
sysbus_mmio_map(sysbus, 0, ESP_BASE);
|
sysbus_mmio_map(sysbus, 0, ESP_BASE);
|
||||||
sysbus_mmio_map(sysbus, 1, ESP_PDMA);
|
sysbus_mmio_map(sysbus, 1, ESP_PDMA);
|
||||||
|
@ -34,11 +34,9 @@
|
|||||||
#include "qemu/log.h"
|
#include "qemu/log.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* VIAs: There are two in every machine,
|
* VIAs: There are two in every machine
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define VIA_SIZE (0x2000)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Not all of these are true post MacII I think.
|
* Not all of these are true post MacII I think.
|
||||||
* CSA: probably the ones CHRP marks as 'unused' change purposes
|
* CSA: probably the ones CHRP marks as 'unused' change purposes
|
||||||
@ -374,11 +372,10 @@ static void via2_irq_request(void *opaque, int irq, int level)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void pram_update(MacVIAState *m)
|
static void pram_update(MOS6522Q800VIA1State *v1s)
|
||||||
{
|
{
|
||||||
if (m->blk) {
|
if (v1s->blk) {
|
||||||
if (blk_pwrite(m->blk, 0, m->mos6522_via1.PRAM,
|
if (blk_pwrite(v1s->blk, 0, v1s->PRAM, sizeof(v1s->PRAM), 0) < 0) {
|
||||||
sizeof(m->mos6522_via1.PRAM), 0) < 0) {
|
|
||||||
qemu_log("pram_update: cannot write to file\n");
|
qemu_log("pram_update: cannot write to file\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -434,9 +431,8 @@ static int via1_rtc_compact_cmd(uint8_t value)
|
|||||||
return REG_INVALID;
|
return REG_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void via1_rtc_update(MacVIAState *m)
|
static void via1_rtc_update(MOS6522Q800VIA1State *v1s)
|
||||||
{
|
{
|
||||||
MOS6522Q800VIA1State *v1s = &m->mos6522_via1;
|
|
||||||
MOS6522State *s = MOS6522(v1s);
|
MOS6522State *s = MOS6522(v1s);
|
||||||
int cmd, sector, addr;
|
int cmd, sector, addr;
|
||||||
uint32_t time;
|
uint32_t time;
|
||||||
@ -448,40 +444,40 @@ static void via1_rtc_update(MacVIAState *m)
|
|||||||
if (s->dirb & VIA1B_vRTCData) {
|
if (s->dirb & VIA1B_vRTCData) {
|
||||||
/* send bits to the RTC */
|
/* send bits to the RTC */
|
||||||
if (!(v1s->last_b & VIA1B_vRTCClk) && (s->b & VIA1B_vRTCClk)) {
|
if (!(v1s->last_b & VIA1B_vRTCClk) && (s->b & VIA1B_vRTCClk)) {
|
||||||
m->data_out <<= 1;
|
v1s->data_out <<= 1;
|
||||||
m->data_out |= s->b & VIA1B_vRTCData;
|
v1s->data_out |= s->b & VIA1B_vRTCData;
|
||||||
m->data_out_cnt++;
|
v1s->data_out_cnt++;
|
||||||
}
|
}
|
||||||
trace_via1_rtc_update_data_out(m->data_out_cnt, m->data_out);
|
trace_via1_rtc_update_data_out(v1s->data_out_cnt, v1s->data_out);
|
||||||
} else {
|
} else {
|
||||||
trace_via1_rtc_update_data_in(m->data_in_cnt, m->data_in);
|
trace_via1_rtc_update_data_in(v1s->data_in_cnt, v1s->data_in);
|
||||||
/* receive bits from the RTC */
|
/* receive bits from the RTC */
|
||||||
if ((v1s->last_b & VIA1B_vRTCClk) &&
|
if ((v1s->last_b & VIA1B_vRTCClk) &&
|
||||||
!(s->b & VIA1B_vRTCClk) &&
|
!(s->b & VIA1B_vRTCClk) &&
|
||||||
m->data_in_cnt) {
|
v1s->data_in_cnt) {
|
||||||
s->b = (s->b & ~VIA1B_vRTCData) |
|
s->b = (s->b & ~VIA1B_vRTCData) |
|
||||||
((m->data_in >> 7) & VIA1B_vRTCData);
|
((v1s->data_in >> 7) & VIA1B_vRTCData);
|
||||||
m->data_in <<= 1;
|
v1s->data_in <<= 1;
|
||||||
m->data_in_cnt--;
|
v1s->data_in_cnt--;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m->data_out_cnt != 8) {
|
if (v1s->data_out_cnt != 8) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m->data_out_cnt = 0;
|
v1s->data_out_cnt = 0;
|
||||||
|
|
||||||
trace_via1_rtc_internal_status(m->cmd, m->alt, m->data_out);
|
trace_via1_rtc_internal_status(v1s->cmd, v1s->alt, v1s->data_out);
|
||||||
/* first byte: it's a command */
|
/* first byte: it's a command */
|
||||||
if (m->cmd == REG_EMPTY) {
|
if (v1s->cmd == REG_EMPTY) {
|
||||||
|
|
||||||
cmd = via1_rtc_compact_cmd(m->data_out);
|
cmd = via1_rtc_compact_cmd(v1s->data_out);
|
||||||
trace_via1_rtc_internal_cmd(cmd);
|
trace_via1_rtc_internal_cmd(cmd);
|
||||||
|
|
||||||
if (cmd == REG_INVALID) {
|
if (cmd == REG_INVALID) {
|
||||||
trace_via1_rtc_cmd_invalid(m->data_out);
|
trace_via1_rtc_cmd_invalid(v1s->data_out);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -493,20 +489,20 @@ static void via1_rtc_update(MacVIAState *m)
|
|||||||
* register 3 is highest-order byte
|
* register 3 is highest-order byte
|
||||||
*/
|
*/
|
||||||
|
|
||||||
time = m->tick_offset + (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL)
|
time = v1s->tick_offset + (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL)
|
||||||
/ NANOSECONDS_PER_SECOND);
|
/ NANOSECONDS_PER_SECOND);
|
||||||
trace_via1_rtc_internal_time(time);
|
trace_via1_rtc_internal_time(time);
|
||||||
m->data_in = (time >> ((cmd & 0x03) << 3)) & 0xff;
|
v1s->data_in = (time >> ((cmd & 0x03) << 3)) & 0xff;
|
||||||
m->data_in_cnt = 8;
|
v1s->data_in_cnt = 8;
|
||||||
trace_via1_rtc_cmd_seconds_read((cmd & 0x7f) - REG_0,
|
trace_via1_rtc_cmd_seconds_read((cmd & 0x7f) - REG_0,
|
||||||
m->data_in);
|
v1s->data_in);
|
||||||
break;
|
break;
|
||||||
case REG_PRAM_ADDR...REG_PRAM_ADDR_LAST:
|
case REG_PRAM_ADDR...REG_PRAM_ADDR_LAST:
|
||||||
/* PRAM address 0x00 -> 0x13 */
|
/* PRAM address 0x00 -> 0x13 */
|
||||||
m->data_in = v1s->PRAM[(cmd & 0x7f) - REG_PRAM_ADDR];
|
v1s->data_in = v1s->PRAM[(cmd & 0x7f) - REG_PRAM_ADDR];
|
||||||
m->data_in_cnt = 8;
|
v1s->data_in_cnt = 8;
|
||||||
trace_via1_rtc_cmd_pram_read((cmd & 0x7f) - REG_PRAM_ADDR,
|
trace_via1_rtc_cmd_pram_read((cmd & 0x7f) - REG_PRAM_ADDR,
|
||||||
m->data_in);
|
v1s->data_in);
|
||||||
break;
|
break;
|
||||||
case REG_PRAM_SECT...REG_PRAM_SECT_LAST:
|
case REG_PRAM_SECT...REG_PRAM_SECT_LAST:
|
||||||
/*
|
/*
|
||||||
@ -514,7 +510,7 @@ static void via1_rtc_update(MacVIAState *m)
|
|||||||
* the only two-byte read command
|
* the only two-byte read command
|
||||||
*/
|
*/
|
||||||
trace_via1_rtc_internal_set_cmd(cmd);
|
trace_via1_rtc_internal_set_cmd(cmd);
|
||||||
m->cmd = cmd;
|
v1s->cmd = cmd;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
g_assert_not_reached();
|
g_assert_not_reached();
|
||||||
@ -524,9 +520,9 @@ static void via1_rtc_update(MacVIAState *m)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* this is a write command, needs a parameter */
|
/* this is a write command, needs a parameter */
|
||||||
if (cmd == REG_WPROTECT || !m->wprotect) {
|
if (cmd == REG_WPROTECT || !v1s->wprotect) {
|
||||||
trace_via1_rtc_internal_set_cmd(cmd);
|
trace_via1_rtc_internal_set_cmd(cmd);
|
||||||
m->cmd = cmd;
|
v1s->cmd = cmd;
|
||||||
} else {
|
} else {
|
||||||
trace_via1_rtc_internal_ignore_cmd(cmd);
|
trace_via1_rtc_internal_ignore_cmd(cmd);
|
||||||
}
|
}
|
||||||
@ -534,46 +530,47 @@ static void via1_rtc_update(MacVIAState *m)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* second byte: it's a parameter */
|
/* second byte: it's a parameter */
|
||||||
if (m->alt == REG_EMPTY) {
|
if (v1s->alt == REG_EMPTY) {
|
||||||
switch (m->cmd & 0x7f) {
|
switch (v1s->cmd & 0x7f) {
|
||||||
case REG_0...REG_3: /* seconds register */
|
case REG_0...REG_3: /* seconds register */
|
||||||
/* FIXME */
|
/* FIXME */
|
||||||
trace_via1_rtc_cmd_seconds_write(m->cmd - REG_0, m->data_out);
|
trace_via1_rtc_cmd_seconds_write(v1s->cmd - REG_0, v1s->data_out);
|
||||||
m->cmd = REG_EMPTY;
|
v1s->cmd = REG_EMPTY;
|
||||||
break;
|
break;
|
||||||
case REG_TEST:
|
case REG_TEST:
|
||||||
/* device control: nothing to do */
|
/* device control: nothing to do */
|
||||||
trace_via1_rtc_cmd_test_write(m->data_out);
|
trace_via1_rtc_cmd_test_write(v1s->data_out);
|
||||||
m->cmd = REG_EMPTY;
|
v1s->cmd = REG_EMPTY;
|
||||||
break;
|
break;
|
||||||
case REG_WPROTECT:
|
case REG_WPROTECT:
|
||||||
/* Write Protect register */
|
/* Write Protect register */
|
||||||
trace_via1_rtc_cmd_wprotect_write(m->data_out);
|
trace_via1_rtc_cmd_wprotect_write(v1s->data_out);
|
||||||
m->wprotect = !!(m->data_out & 0x80);
|
v1s->wprotect = !!(v1s->data_out & 0x80);
|
||||||
m->cmd = REG_EMPTY;
|
v1s->cmd = REG_EMPTY;
|
||||||
break;
|
break;
|
||||||
case REG_PRAM_ADDR...REG_PRAM_ADDR_LAST:
|
case REG_PRAM_ADDR...REG_PRAM_ADDR_LAST:
|
||||||
/* PRAM address 0x00 -> 0x13 */
|
/* PRAM address 0x00 -> 0x13 */
|
||||||
trace_via1_rtc_cmd_pram_write(m->cmd - REG_PRAM_ADDR, m->data_out);
|
trace_via1_rtc_cmd_pram_write(v1s->cmd - REG_PRAM_ADDR,
|
||||||
v1s->PRAM[m->cmd - REG_PRAM_ADDR] = m->data_out;
|
v1s->data_out);
|
||||||
pram_update(m);
|
v1s->PRAM[v1s->cmd - REG_PRAM_ADDR] = v1s->data_out;
|
||||||
m->cmd = REG_EMPTY;
|
pram_update(v1s);
|
||||||
|
v1s->cmd = REG_EMPTY;
|
||||||
break;
|
break;
|
||||||
case REG_PRAM_SECT...REG_PRAM_SECT_LAST:
|
case REG_PRAM_SECT...REG_PRAM_SECT_LAST:
|
||||||
addr = (m->data_out >> 2) & 0x1f;
|
addr = (v1s->data_out >> 2) & 0x1f;
|
||||||
sector = (m->cmd & 0x7f) - REG_PRAM_SECT;
|
sector = (v1s->cmd & 0x7f) - REG_PRAM_SECT;
|
||||||
if (m->cmd & 0x80) {
|
if (v1s->cmd & 0x80) {
|
||||||
/* it's a read */
|
/* it's a read */
|
||||||
m->data_in = v1s->PRAM[sector * 32 + addr];
|
v1s->data_in = v1s->PRAM[sector * 32 + addr];
|
||||||
m->data_in_cnt = 8;
|
v1s->data_in_cnt = 8;
|
||||||
trace_via1_rtc_cmd_pram_sect_read(sector, addr,
|
trace_via1_rtc_cmd_pram_sect_read(sector, addr,
|
||||||
sector * 32 + addr,
|
sector * 32 + addr,
|
||||||
m->data_in);
|
v1s->data_in);
|
||||||
m->cmd = REG_EMPTY;
|
v1s->cmd = REG_EMPTY;
|
||||||
} else {
|
} else {
|
||||||
/* it's a write, we need one more parameter */
|
/* it's a write, we need one more parameter */
|
||||||
trace_via1_rtc_internal_set_alt(addr, sector, addr);
|
trace_via1_rtc_internal_set_alt(addr, sector, addr);
|
||||||
m->alt = addr;
|
v1s->alt = addr;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -584,22 +581,21 @@ static void via1_rtc_update(MacVIAState *m)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* third byte: it's the data of a REG_PRAM_SECT write */
|
/* third byte: it's the data of a REG_PRAM_SECT write */
|
||||||
g_assert(REG_PRAM_SECT <= m->cmd && m->cmd <= REG_PRAM_SECT_LAST);
|
g_assert(REG_PRAM_SECT <= v1s->cmd && v1s->cmd <= REG_PRAM_SECT_LAST);
|
||||||
sector = m->cmd - REG_PRAM_SECT;
|
sector = v1s->cmd - REG_PRAM_SECT;
|
||||||
v1s->PRAM[sector * 32 + m->alt] = m->data_out;
|
v1s->PRAM[sector * 32 + v1s->alt] = v1s->data_out;
|
||||||
pram_update(m);
|
pram_update(v1s);
|
||||||
trace_via1_rtc_cmd_pram_sect_write(sector, m->alt, sector * 32 + m->alt,
|
trace_via1_rtc_cmd_pram_sect_write(sector, v1s->alt, sector * 32 + v1s->alt,
|
||||||
m->data_out);
|
v1s->data_out);
|
||||||
m->alt = REG_EMPTY;
|
v1s->alt = REG_EMPTY;
|
||||||
m->cmd = REG_EMPTY;
|
v1s->cmd = REG_EMPTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void adb_via_poll(void *opaque)
|
static void adb_via_poll(void *opaque)
|
||||||
{
|
{
|
||||||
MacVIAState *m = opaque;
|
MOS6522Q800VIA1State *v1s = MOS6522_Q800_VIA1(opaque);
|
||||||
MOS6522Q800VIA1State *v1s = MOS6522_Q800_VIA1(&m->mos6522_via1);
|
|
||||||
MOS6522State *s = MOS6522(v1s);
|
MOS6522State *s = MOS6522(v1s);
|
||||||
ADBBusState *adb_bus = &m->adb_bus;
|
ADBBusState *adb_bus = &v1s->adb_bus;
|
||||||
uint8_t obuf[9];
|
uint8_t obuf[9];
|
||||||
uint8_t *data = &s->sr;
|
uint8_t *data = &s->sr;
|
||||||
int olen;
|
int olen;
|
||||||
@ -611,50 +607,50 @@ static void adb_via_poll(void *opaque)
|
|||||||
*/
|
*/
|
||||||
adb_autopoll_block(adb_bus);
|
adb_autopoll_block(adb_bus);
|
||||||
|
|
||||||
if (m->adb_data_in_size > 0 && m->adb_data_in_index == 0) {
|
if (v1s->adb_data_in_size > 0 && v1s->adb_data_in_index == 0) {
|
||||||
/*
|
/*
|
||||||
* For older Linux kernels that switch to IDLE mode after sending the
|
* For older Linux kernels that switch to IDLE mode after sending the
|
||||||
* ADB command, detect if there is an existing response and return that
|
* ADB command, detect if there is an existing response and return that
|
||||||
* as a a "fake" autopoll reply or bus timeout accordingly
|
* as a a "fake" autopoll reply or bus timeout accordingly
|
||||||
*/
|
*/
|
||||||
*data = m->adb_data_out[0];
|
*data = v1s->adb_data_out[0];
|
||||||
olen = m->adb_data_in_size;
|
olen = v1s->adb_data_in_size;
|
||||||
|
|
||||||
s->b &= ~VIA1B_vADBInt;
|
s->b &= ~VIA1B_vADBInt;
|
||||||
qemu_irq_raise(m->adb_data_ready);
|
qemu_irq_raise(v1s->adb_data_ready);
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* Otherwise poll as normal
|
* Otherwise poll as normal
|
||||||
*/
|
*/
|
||||||
m->adb_data_in_index = 0;
|
v1s->adb_data_in_index = 0;
|
||||||
m->adb_data_out_index = 0;
|
v1s->adb_data_out_index = 0;
|
||||||
olen = adb_poll(adb_bus, obuf, adb_bus->autopoll_mask);
|
olen = adb_poll(adb_bus, obuf, adb_bus->autopoll_mask);
|
||||||
|
|
||||||
if (olen > 0) {
|
if (olen > 0) {
|
||||||
/* Autopoll response */
|
/* Autopoll response */
|
||||||
*data = obuf[0];
|
*data = obuf[0];
|
||||||
olen--;
|
olen--;
|
||||||
memcpy(m->adb_data_in, &obuf[1], olen);
|
memcpy(v1s->adb_data_in, &obuf[1], olen);
|
||||||
m->adb_data_in_size = olen;
|
v1s->adb_data_in_size = olen;
|
||||||
|
|
||||||
s->b &= ~VIA1B_vADBInt;
|
s->b &= ~VIA1B_vADBInt;
|
||||||
qemu_irq_raise(m->adb_data_ready);
|
qemu_irq_raise(v1s->adb_data_ready);
|
||||||
} else {
|
} else {
|
||||||
*data = m->adb_autopoll_cmd;
|
*data = v1s->adb_autopoll_cmd;
|
||||||
obuf[0] = 0xff;
|
obuf[0] = 0xff;
|
||||||
obuf[1] = 0xff;
|
obuf[1] = 0xff;
|
||||||
olen = 2;
|
olen = 2;
|
||||||
|
|
||||||
memcpy(m->adb_data_in, obuf, olen);
|
memcpy(v1s->adb_data_in, obuf, olen);
|
||||||
m->adb_data_in_size = olen;
|
v1s->adb_data_in_size = olen;
|
||||||
|
|
||||||
s->b &= ~VIA1B_vADBInt;
|
s->b &= ~VIA1B_vADBInt;
|
||||||
qemu_irq_raise(m->adb_data_ready);
|
qemu_irq_raise(v1s->adb_data_ready);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
trace_via1_adb_poll(*data, (s->b & VIA1B_vADBInt) ? "+" : "-",
|
trace_via1_adb_poll(*data, (s->b & VIA1B_vADBInt) ? "+" : "-",
|
||||||
adb_bus->status, m->adb_data_in_index, olen);
|
adb_bus->status, v1s->adb_data_in_index, olen);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int adb_via_send_len(uint8_t data)
|
static int adb_via_send_len(uint8_t data)
|
||||||
@ -687,11 +683,10 @@ static int adb_via_send_len(uint8_t data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void adb_via_send(MacVIAState *s, int state, uint8_t data)
|
static void adb_via_send(MOS6522Q800VIA1State *v1s, int state, uint8_t data)
|
||||||
{
|
{
|
||||||
MOS6522Q800VIA1State *v1s = MOS6522_Q800_VIA1(&s->mos6522_via1);
|
|
||||||
MOS6522State *ms = MOS6522(v1s);
|
MOS6522State *ms = MOS6522(v1s);
|
||||||
ADBBusState *adb_bus = &s->adb_bus;
|
ADBBusState *adb_bus = &v1s->adb_bus;
|
||||||
uint16_t autopoll_mask;
|
uint16_t autopoll_mask;
|
||||||
|
|
||||||
switch (state) {
|
switch (state) {
|
||||||
@ -707,22 +702,22 @@ static void adb_via_send(MacVIAState *s, int state, uint8_t data)
|
|||||||
ms->b &= ~VIA1B_vADBInt;
|
ms->b &= ~VIA1B_vADBInt;
|
||||||
} else {
|
} else {
|
||||||
ms->b |= VIA1B_vADBInt;
|
ms->b |= VIA1B_vADBInt;
|
||||||
s->adb_data_out_index = 0;
|
v1s->adb_data_out_index = 0;
|
||||||
s->adb_data_out[s->adb_data_out_index++] = data;
|
v1s->adb_data_out[v1s->adb_data_out_index++] = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
trace_via1_adb_send(" NEW", data, (ms->b & VIA1B_vADBInt) ? "+" : "-");
|
trace_via1_adb_send(" NEW", data, (ms->b & VIA1B_vADBInt) ? "+" : "-");
|
||||||
qemu_irq_raise(s->adb_data_ready);
|
qemu_irq_raise(v1s->adb_data_ready);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ADB_STATE_EVEN:
|
case ADB_STATE_EVEN:
|
||||||
case ADB_STATE_ODD:
|
case ADB_STATE_ODD:
|
||||||
ms->b |= VIA1B_vADBInt;
|
ms->b |= VIA1B_vADBInt;
|
||||||
s->adb_data_out[s->adb_data_out_index++] = data;
|
v1s->adb_data_out[v1s->adb_data_out_index++] = data;
|
||||||
|
|
||||||
trace_via1_adb_send(state == ADB_STATE_EVEN ? "EVEN" : " ODD",
|
trace_via1_adb_send(state == ADB_STATE_EVEN ? "EVEN" : " ODD",
|
||||||
data, (ms->b & VIA1B_vADBInt) ? "+" : "-");
|
data, (ms->b & VIA1B_vADBInt) ? "+" : "-");
|
||||||
qemu_irq_raise(s->adb_data_ready);
|
qemu_irq_raise(v1s->adb_data_ready);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ADB_STATE_IDLE:
|
case ADB_STATE_IDLE:
|
||||||
@ -730,40 +725,39 @@ static void adb_via_send(MacVIAState *s, int state, uint8_t data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* If the command is complete, execute it */
|
/* If the command is complete, execute it */
|
||||||
if (s->adb_data_out_index == adb_via_send_len(s->adb_data_out[0])) {
|
if (v1s->adb_data_out_index == adb_via_send_len(v1s->adb_data_out[0])) {
|
||||||
s->adb_data_in_size = adb_request(adb_bus, s->adb_data_in,
|
v1s->adb_data_in_size = adb_request(adb_bus, v1s->adb_data_in,
|
||||||
s->adb_data_out,
|
v1s->adb_data_out,
|
||||||
s->adb_data_out_index);
|
v1s->adb_data_out_index);
|
||||||
s->adb_data_in_index = 0;
|
v1s->adb_data_in_index = 0;
|
||||||
|
|
||||||
if (adb_bus->status & ADB_STATUS_BUSTIMEOUT) {
|
if (adb_bus->status & ADB_STATUS_BUSTIMEOUT) {
|
||||||
/*
|
/*
|
||||||
* Bus timeout (but allow first EVEN and ODD byte to indicate
|
* Bus timeout (but allow first EVEN and ODD byte to indicate
|
||||||
* timeout via vADBInt and SRQ status)
|
* timeout via vADBInt and SRQ status)
|
||||||
*/
|
*/
|
||||||
s->adb_data_in[0] = 0xff;
|
v1s->adb_data_in[0] = 0xff;
|
||||||
s->adb_data_in[1] = 0xff;
|
v1s->adb_data_in[1] = 0xff;
|
||||||
s->adb_data_in_size = 2;
|
v1s->adb_data_in_size = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If last command is TALK, store it for use by autopoll and adjust
|
* If last command is TALK, store it for use by autopoll and adjust
|
||||||
* the autopoll mask accordingly
|
* the autopoll mask accordingly
|
||||||
*/
|
*/
|
||||||
if ((s->adb_data_out[0] & 0xc) == 0xc) {
|
if ((v1s->adb_data_out[0] & 0xc) == 0xc) {
|
||||||
s->adb_autopoll_cmd = s->adb_data_out[0];
|
v1s->adb_autopoll_cmd = v1s->adb_data_out[0];
|
||||||
|
|
||||||
autopoll_mask = 1 << (s->adb_autopoll_cmd >> 4);
|
autopoll_mask = 1 << (v1s->adb_autopoll_cmd >> 4);
|
||||||
adb_set_autopoll_mask(adb_bus, autopoll_mask);
|
adb_set_autopoll_mask(adb_bus, autopoll_mask);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void adb_via_receive(MacVIAState *s, int state, uint8_t *data)
|
static void adb_via_receive(MOS6522Q800VIA1State *v1s, int state, uint8_t *data)
|
||||||
{
|
{
|
||||||
MOS6522Q800VIA1State *v1s = MOS6522_Q800_VIA1(&s->mos6522_via1);
|
|
||||||
MOS6522State *ms = MOS6522(v1s);
|
MOS6522State *ms = MOS6522(v1s);
|
||||||
ADBBusState *adb_bus = &s->adb_bus;
|
ADBBusState *adb_bus = &v1s->adb_bus;
|
||||||
uint16_t pending;
|
uint16_t pending;
|
||||||
|
|
||||||
switch (state) {
|
switch (state) {
|
||||||
@ -777,16 +771,16 @@ static void adb_via_receive(MacVIAState *s, int state, uint8_t *data)
|
|||||||
|
|
||||||
trace_via1_adb_receive("IDLE", *data,
|
trace_via1_adb_receive("IDLE", *data,
|
||||||
(ms->b & VIA1B_vADBInt) ? "+" : "-", adb_bus->status,
|
(ms->b & VIA1B_vADBInt) ? "+" : "-", adb_bus->status,
|
||||||
s->adb_data_in_index, s->adb_data_in_size);
|
v1s->adb_data_in_index, v1s->adb_data_in_size);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ADB_STATE_EVEN:
|
case ADB_STATE_EVEN:
|
||||||
case ADB_STATE_ODD:
|
case ADB_STATE_ODD:
|
||||||
switch (s->adb_data_in_index) {
|
switch (v1s->adb_data_in_index) {
|
||||||
case 0:
|
case 0:
|
||||||
/* First EVEN byte: vADBInt indicates bus timeout */
|
/* First EVEN byte: vADBInt indicates bus timeout */
|
||||||
*data = s->adb_data_in[s->adb_data_in_index];
|
*data = v1s->adb_data_in[v1s->adb_data_in_index];
|
||||||
if (adb_bus->status & ADB_STATUS_BUSTIMEOUT) {
|
if (adb_bus->status & ADB_STATUS_BUSTIMEOUT) {
|
||||||
ms->b &= ~VIA1B_vADBInt;
|
ms->b &= ~VIA1B_vADBInt;
|
||||||
} else {
|
} else {
|
||||||
@ -795,16 +789,16 @@ static void adb_via_receive(MacVIAState *s, int state, uint8_t *data)
|
|||||||
|
|
||||||
trace_via1_adb_receive(state == ADB_STATE_EVEN ? "EVEN" : " ODD",
|
trace_via1_adb_receive(state == ADB_STATE_EVEN ? "EVEN" : " ODD",
|
||||||
*data, (ms->b & VIA1B_vADBInt) ? "+" : "-",
|
*data, (ms->b & VIA1B_vADBInt) ? "+" : "-",
|
||||||
adb_bus->status, s->adb_data_in_index,
|
adb_bus->status, v1s->adb_data_in_index,
|
||||||
s->adb_data_in_size);
|
v1s->adb_data_in_size);
|
||||||
|
|
||||||
s->adb_data_in_index++;
|
v1s->adb_data_in_index++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
/* First ODD byte: vADBInt indicates SRQ */
|
/* First ODD byte: vADBInt indicates SRQ */
|
||||||
*data = s->adb_data_in[s->adb_data_in_index];
|
*data = v1s->adb_data_in[v1s->adb_data_in_index];
|
||||||
pending = adb_bus->pending & ~(1 << (s->adb_autopoll_cmd >> 4));
|
pending = adb_bus->pending & ~(1 << (v1s->adb_autopoll_cmd >> 4));
|
||||||
if (pending) {
|
if (pending) {
|
||||||
ms->b &= ~VIA1B_vADBInt;
|
ms->b &= ~VIA1B_vADBInt;
|
||||||
} else {
|
} else {
|
||||||
@ -813,10 +807,10 @@ static void adb_via_receive(MacVIAState *s, int state, uint8_t *data)
|
|||||||
|
|
||||||
trace_via1_adb_receive(state == ADB_STATE_EVEN ? "EVEN" : " ODD",
|
trace_via1_adb_receive(state == ADB_STATE_EVEN ? "EVEN" : " ODD",
|
||||||
*data, (ms->b & VIA1B_vADBInt) ? "+" : "-",
|
*data, (ms->b & VIA1B_vADBInt) ? "+" : "-",
|
||||||
adb_bus->status, s->adb_data_in_index,
|
adb_bus->status, v1s->adb_data_in_index,
|
||||||
s->adb_data_in_size);
|
v1s->adb_data_in_size);
|
||||||
|
|
||||||
s->adb_data_in_index++;
|
v1s->adb_data_in_index++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -826,11 +820,11 @@ static void adb_via_receive(MacVIAState *s, int state, uint8_t *data)
|
|||||||
* end of the poll reply, so provide these extra bytes below to
|
* end of the poll reply, so provide these extra bytes below to
|
||||||
* keep it happy
|
* keep it happy
|
||||||
*/
|
*/
|
||||||
if (s->adb_data_in_index < s->adb_data_in_size) {
|
if (v1s->adb_data_in_index < v1s->adb_data_in_size) {
|
||||||
/* Next data byte */
|
/* Next data byte */
|
||||||
*data = s->adb_data_in[s->adb_data_in_index];
|
*data = v1s->adb_data_in[v1s->adb_data_in_index];
|
||||||
ms->b |= VIA1B_vADBInt;
|
ms->b |= VIA1B_vADBInt;
|
||||||
} else if (s->adb_data_in_index == s->adb_data_in_size) {
|
} else if (v1s->adb_data_in_index == v1s->adb_data_in_size) {
|
||||||
if (adb_bus->status & ADB_STATUS_BUSTIMEOUT) {
|
if (adb_bus->status & ADB_STATUS_BUSTIMEOUT) {
|
||||||
/* Bus timeout (no more data) */
|
/* Bus timeout (no more data) */
|
||||||
*data = 0xff;
|
*data = 0xff;
|
||||||
@ -849,23 +843,22 @@ static void adb_via_receive(MacVIAState *s, int state, uint8_t *data)
|
|||||||
|
|
||||||
trace_via1_adb_receive(state == ADB_STATE_EVEN ? "EVEN" : " ODD",
|
trace_via1_adb_receive(state == ADB_STATE_EVEN ? "EVEN" : " ODD",
|
||||||
*data, (ms->b & VIA1B_vADBInt) ? "+" : "-",
|
*data, (ms->b & VIA1B_vADBInt) ? "+" : "-",
|
||||||
adb_bus->status, s->adb_data_in_index,
|
adb_bus->status, v1s->adb_data_in_index,
|
||||||
s->adb_data_in_size);
|
v1s->adb_data_in_size);
|
||||||
|
|
||||||
if (s->adb_data_in_index <= s->adb_data_in_size) {
|
if (v1s->adb_data_in_index <= v1s->adb_data_in_size) {
|
||||||
s->adb_data_in_index++;
|
v1s->adb_data_in_index++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
qemu_irq_raise(s->adb_data_ready);
|
qemu_irq_raise(v1s->adb_data_ready);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void via1_adb_update(MacVIAState *m)
|
static void via1_adb_update(MOS6522Q800VIA1State *v1s)
|
||||||
{
|
{
|
||||||
MOS6522Q800VIA1State *v1s = MOS6522_Q800_VIA1(&m->mos6522_via1);
|
|
||||||
MOS6522State *s = MOS6522(v1s);
|
MOS6522State *s = MOS6522(v1s);
|
||||||
int oldstate, state;
|
int oldstate, state;
|
||||||
|
|
||||||
@ -875,10 +868,10 @@ static void via1_adb_update(MacVIAState *m)
|
|||||||
if (state != oldstate) {
|
if (state != oldstate) {
|
||||||
if (s->acr & VIA1ACR_vShiftOut) {
|
if (s->acr & VIA1ACR_vShiftOut) {
|
||||||
/* output mode */
|
/* output mode */
|
||||||
adb_via_send(m, state, s->sr);
|
adb_via_send(v1s, state, s->sr);
|
||||||
} else {
|
} else {
|
||||||
/* input mode */
|
/* input mode */
|
||||||
adb_via_receive(m, state, &s->sr);
|
adb_via_receive(v1s, state, &s->sr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -896,7 +889,6 @@ static void mos6522_q800_via1_write(void *opaque, hwaddr addr, uint64_t val,
|
|||||||
unsigned size)
|
unsigned size)
|
||||||
{
|
{
|
||||||
MOS6522Q800VIA1State *v1s = MOS6522_Q800_VIA1(opaque);
|
MOS6522Q800VIA1State *v1s = MOS6522_Q800_VIA1(opaque);
|
||||||
MacVIAState *m = container_of(v1s, MacVIAState, mos6522_via1);
|
|
||||||
MOS6522State *ms = MOS6522(v1s);
|
MOS6522State *ms = MOS6522(v1s);
|
||||||
|
|
||||||
addr = (addr >> 9) & 0xf;
|
addr = (addr >> 9) & 0xf;
|
||||||
@ -904,8 +896,8 @@ static void mos6522_q800_via1_write(void *opaque, hwaddr addr, uint64_t val,
|
|||||||
|
|
||||||
switch (addr) {
|
switch (addr) {
|
||||||
case VIA_REG_B:
|
case VIA_REG_B:
|
||||||
via1_rtc_update(m);
|
via1_rtc_update(v1s);
|
||||||
via1_adb_update(m);
|
via1_adb_update(v1s);
|
||||||
|
|
||||||
v1s->last_b = ms->b;
|
v1s->last_b = ms->b;
|
||||||
break;
|
break;
|
||||||
@ -951,196 +943,35 @@ static const MemoryRegionOps mos6522_q800_via2_ops = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static void mac_via_reset(DeviceState *dev)
|
static void via1_postload_update_cb(void *opaque, bool running, RunState state)
|
||||||
{
|
{
|
||||||
MacVIAState *m = MAC_VIA(dev);
|
MOS6522Q800VIA1State *v1s = MOS6522_Q800_VIA1(opaque);
|
||||||
ADBBusState *adb_bus = &m->adb_bus;
|
|
||||||
|
|
||||||
adb_set_autopoll_enabled(adb_bus, true);
|
qemu_del_vm_change_state_handler(v1s->vmstate);
|
||||||
|
v1s->vmstate = NULL;
|
||||||
|
|
||||||
m->cmd = REG_EMPTY;
|
pram_update(v1s);
|
||||||
m->alt = REG_EMPTY;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mac_via_realize(DeviceState *dev, Error **errp)
|
static int via1_post_load(void *opaque, int version_id)
|
||||||
{
|
{
|
||||||
MacVIAState *m = MAC_VIA(dev);
|
MOS6522Q800VIA1State *v1s = MOS6522_Q800_VIA1(opaque);
|
||||||
MOS6522State *ms;
|
|
||||||
ADBBusState *adb_bus = &m->adb_bus;
|
|
||||||
struct tm tm;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
/* Init VIAs 1 and 2 */
|
if (v1s->blk) {
|
||||||
object_initialize_child(OBJECT(dev), "via1", &m->mos6522_via1,
|
v1s->vmstate = qemu_add_vm_change_state_handler(
|
||||||
TYPE_MOS6522_Q800_VIA1);
|
via1_postload_update_cb, v1s);
|
||||||
|
|
||||||
object_initialize_child(OBJECT(dev), "via2", &m->mos6522_via2,
|
|
||||||
TYPE_MOS6522_Q800_VIA2);
|
|
||||||
|
|
||||||
/* Pass through mos6522 output IRQs */
|
|
||||||
ms = MOS6522(&m->mos6522_via1);
|
|
||||||
object_property_add_alias(OBJECT(dev), "irq[0]", OBJECT(ms),
|
|
||||||
SYSBUS_DEVICE_GPIO_IRQ "[0]");
|
|
||||||
ms = MOS6522(&m->mos6522_via2);
|
|
||||||
object_property_add_alias(OBJECT(dev), "irq[1]", OBJECT(ms),
|
|
||||||
SYSBUS_DEVICE_GPIO_IRQ "[0]");
|
|
||||||
|
|
||||||
sysbus_realize(SYS_BUS_DEVICE(&m->mos6522_via1), &error_abort);
|
|
||||||
sysbus_realize(SYS_BUS_DEVICE(&m->mos6522_via2), &error_abort);
|
|
||||||
|
|
||||||
/* Pass through mos6522 input IRQs */
|
|
||||||
qdev_pass_gpios(DEVICE(&m->mos6522_via1), dev, "via1-irq");
|
|
||||||
qdev_pass_gpios(DEVICE(&m->mos6522_via2), dev, "via2-irq");
|
|
||||||
|
|
||||||
/* VIA 1 */
|
|
||||||
m->mos6522_via1.one_second_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL,
|
|
||||||
via1_one_second,
|
|
||||||
&m->mos6522_via1);
|
|
||||||
via1_one_second_update(&m->mos6522_via1);
|
|
||||||
m->mos6522_via1.sixty_hz_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
|
|
||||||
via1_sixty_hz,
|
|
||||||
&m->mos6522_via1);
|
|
||||||
via1_sixty_hz_update(&m->mos6522_via1);
|
|
||||||
|
|
||||||
qemu_get_timedate(&tm, 0);
|
|
||||||
m->tick_offset = (uint32_t)mktimegm(&tm) + RTC_OFFSET;
|
|
||||||
|
|
||||||
adb_register_autopoll_callback(adb_bus, adb_via_poll, m);
|
|
||||||
m->adb_data_ready = qdev_get_gpio_in_named(dev, "via1-irq",
|
|
||||||
VIA1_IRQ_ADB_READY_BIT);
|
|
||||||
|
|
||||||
if (m->blk) {
|
|
||||||
int64_t len = blk_getlength(m->blk);
|
|
||||||
if (len < 0) {
|
|
||||||
error_setg_errno(errp, -len,
|
|
||||||
"could not get length of backing image");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ret = blk_set_perm(m->blk,
|
|
||||||
BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE,
|
|
||||||
BLK_PERM_ALL, errp);
|
|
||||||
if (ret < 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
len = blk_pread(m->blk, 0, m->mos6522_via1.PRAM,
|
|
||||||
sizeof(m->mos6522_via1.PRAM));
|
|
||||||
if (len != sizeof(m->mos6522_via1.PRAM)) {
|
|
||||||
error_setg(errp, "can't read PRAM contents");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mac_via_init(Object *obj)
|
|
||||||
{
|
|
||||||
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
|
|
||||||
MacVIAState *m = MAC_VIA(obj);
|
|
||||||
|
|
||||||
/* MMIO */
|
|
||||||
memory_region_init(&m->mmio, obj, "mac-via", 2 * VIA_SIZE);
|
|
||||||
sysbus_init_mmio(sbd, &m->mmio);
|
|
||||||
|
|
||||||
memory_region_init_io(&m->via1mem, obj, &mos6522_q800_via1_ops,
|
|
||||||
&m->mos6522_via1, "via1", VIA_SIZE);
|
|
||||||
memory_region_add_subregion(&m->mmio, 0x0, &m->via1mem);
|
|
||||||
|
|
||||||
memory_region_init_io(&m->via2mem, obj, &mos6522_q800_via2_ops,
|
|
||||||
&m->mos6522_via2, "via2", VIA_SIZE);
|
|
||||||
memory_region_add_subregion(&m->mmio, VIA_SIZE, &m->via2mem);
|
|
||||||
|
|
||||||
/* ADB */
|
|
||||||
qbus_create_inplace((BusState *)&m->adb_bus, sizeof(m->adb_bus),
|
|
||||||
TYPE_ADB_BUS, DEVICE(obj), "adb.0");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void postload_update_cb(void *opaque, bool running, RunState state)
|
|
||||||
{
|
|
||||||
MacVIAState *m = MAC_VIA(opaque);
|
|
||||||
|
|
||||||
qemu_del_vm_change_state_handler(m->vmstate);
|
|
||||||
m->vmstate = NULL;
|
|
||||||
|
|
||||||
pram_update(m);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int mac_via_post_load(void *opaque, int version_id)
|
|
||||||
{
|
|
||||||
MacVIAState *m = MAC_VIA(opaque);
|
|
||||||
|
|
||||||
if (m->blk) {
|
|
||||||
m->vmstate = qemu_add_vm_change_state_handler(postload_update_cb,
|
|
||||||
m);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const VMStateDescription vmstate_mac_via = {
|
|
||||||
.name = "mac-via",
|
|
||||||
.version_id = 2,
|
|
||||||
.minimum_version_id = 2,
|
|
||||||
.post_load = mac_via_post_load,
|
|
||||||
.fields = (VMStateField[]) {
|
|
||||||
/* VIAs */
|
|
||||||
VMSTATE_STRUCT(mos6522_via1.parent_obj, MacVIAState, 0, vmstate_mos6522,
|
|
||||||
MOS6522State),
|
|
||||||
VMSTATE_UINT8(mos6522_via1.last_b, MacVIAState),
|
|
||||||
VMSTATE_BUFFER(mos6522_via1.PRAM, MacVIAState),
|
|
||||||
VMSTATE_TIMER_PTR(mos6522_via1.one_second_timer, MacVIAState),
|
|
||||||
VMSTATE_INT64(mos6522_via1.next_second, MacVIAState),
|
|
||||||
VMSTATE_TIMER_PTR(mos6522_via1.sixty_hz_timer, MacVIAState),
|
|
||||||
VMSTATE_INT64(mos6522_via1.next_sixty_hz, MacVIAState),
|
|
||||||
VMSTATE_STRUCT(mos6522_via2.parent_obj, MacVIAState, 0, vmstate_mos6522,
|
|
||||||
MOS6522State),
|
|
||||||
/* RTC */
|
|
||||||
VMSTATE_UINT32(tick_offset, MacVIAState),
|
|
||||||
VMSTATE_UINT8(data_out, MacVIAState),
|
|
||||||
VMSTATE_INT32(data_out_cnt, MacVIAState),
|
|
||||||
VMSTATE_UINT8(data_in, MacVIAState),
|
|
||||||
VMSTATE_UINT8(data_in_cnt, MacVIAState),
|
|
||||||
VMSTATE_UINT8(cmd, MacVIAState),
|
|
||||||
VMSTATE_INT32(wprotect, MacVIAState),
|
|
||||||
VMSTATE_INT32(alt, MacVIAState),
|
|
||||||
/* ADB */
|
|
||||||
VMSTATE_INT32(adb_data_in_size, MacVIAState),
|
|
||||||
VMSTATE_INT32(adb_data_in_index, MacVIAState),
|
|
||||||
VMSTATE_INT32(adb_data_out_index, MacVIAState),
|
|
||||||
VMSTATE_BUFFER(adb_data_in, MacVIAState),
|
|
||||||
VMSTATE_BUFFER(adb_data_out, MacVIAState),
|
|
||||||
VMSTATE_UINT8(adb_autopoll_cmd, MacVIAState),
|
|
||||||
VMSTATE_END_OF_LIST()
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
static Property mac_via_properties[] = {
|
|
||||||
DEFINE_PROP_DRIVE("drive", MacVIAState, blk),
|
|
||||||
DEFINE_PROP_END_OF_LIST(),
|
|
||||||
};
|
|
||||||
|
|
||||||
static void mac_via_class_init(ObjectClass *oc, void *data)
|
|
||||||
{
|
|
||||||
DeviceClass *dc = DEVICE_CLASS(oc);
|
|
||||||
|
|
||||||
dc->realize = mac_via_realize;
|
|
||||||
dc->reset = mac_via_reset;
|
|
||||||
dc->vmsd = &vmstate_mac_via;
|
|
||||||
device_class_set_props(dc, mac_via_properties);
|
|
||||||
}
|
|
||||||
|
|
||||||
static TypeInfo mac_via_info = {
|
|
||||||
.name = TYPE_MAC_VIA,
|
|
||||||
.parent = TYPE_SYS_BUS_DEVICE,
|
|
||||||
.instance_size = sizeof(MacVIAState),
|
|
||||||
.instance_init = mac_via_init,
|
|
||||||
.class_init = mac_via_class_init,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* VIA 1 */
|
/* VIA 1 */
|
||||||
static void mos6522_q800_via1_reset(DeviceState *dev)
|
static void mos6522_q800_via1_reset(DeviceState *dev)
|
||||||
{
|
{
|
||||||
MOS6522State *ms = MOS6522(dev);
|
MOS6522Q800VIA1State *v1s = MOS6522_Q800_VIA1(dev);
|
||||||
|
MOS6522State *ms = MOS6522(v1s);
|
||||||
MOS6522DeviceClass *mdc = MOS6522_GET_CLASS(ms);
|
MOS6522DeviceClass *mdc = MOS6522_GET_CLASS(ms);
|
||||||
|
ADBBusState *adb_bus = &v1s->adb_bus;
|
||||||
|
|
||||||
mdc->parent_reset(dev);
|
mdc->parent_reset(dev);
|
||||||
|
|
||||||
@ -1148,19 +979,119 @@ static void mos6522_q800_via1_reset(DeviceState *dev)
|
|||||||
ms->timers[1].frequency = VIA_TIMER_FREQ;
|
ms->timers[1].frequency = VIA_TIMER_FREQ;
|
||||||
|
|
||||||
ms->b = VIA1B_vADB_StateMask | VIA1B_vADBInt | VIA1B_vRTCEnb;
|
ms->b = VIA1B_vADB_StateMask | VIA1B_vADBInt | VIA1B_vRTCEnb;
|
||||||
|
|
||||||
|
/* ADB/RTC */
|
||||||
|
adb_set_autopoll_enabled(adb_bus, true);
|
||||||
|
v1s->cmd = REG_EMPTY;
|
||||||
|
v1s->alt = REG_EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mos6522_q800_via1_realize(DeviceState *dev, Error **errp)
|
||||||
|
{
|
||||||
|
MOS6522Q800VIA1State *v1s = MOS6522_Q800_VIA1(dev);
|
||||||
|
ADBBusState *adb_bus = &v1s->adb_bus;
|
||||||
|
struct tm tm;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
v1s->one_second_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL, via1_one_second,
|
||||||
|
v1s);
|
||||||
|
via1_one_second_update(v1s);
|
||||||
|
v1s->sixty_hz_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, via1_sixty_hz,
|
||||||
|
v1s);
|
||||||
|
via1_sixty_hz_update(v1s);
|
||||||
|
|
||||||
|
qemu_get_timedate(&tm, 0);
|
||||||
|
v1s->tick_offset = (uint32_t)mktimegm(&tm) + RTC_OFFSET;
|
||||||
|
|
||||||
|
adb_register_autopoll_callback(adb_bus, adb_via_poll, v1s);
|
||||||
|
v1s->adb_data_ready = qdev_get_gpio_in(dev, VIA1_IRQ_ADB_READY_BIT);
|
||||||
|
|
||||||
|
if (v1s->blk) {
|
||||||
|
int64_t len = blk_getlength(v1s->blk);
|
||||||
|
if (len < 0) {
|
||||||
|
error_setg_errno(errp, -len,
|
||||||
|
"could not get length of backing image");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ret = blk_set_perm(v1s->blk,
|
||||||
|
BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE,
|
||||||
|
BLK_PERM_ALL, errp);
|
||||||
|
if (ret < 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = blk_pread(v1s->blk, 0, v1s->PRAM, sizeof(v1s->PRAM));
|
||||||
|
if (len != sizeof(v1s->PRAM)) {
|
||||||
|
error_setg(errp, "can't read PRAM contents");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mos6522_q800_via1_init(Object *obj)
|
static void mos6522_q800_via1_init(Object *obj)
|
||||||
{
|
{
|
||||||
qdev_init_gpio_in_named(DEVICE(obj), via1_irq_request, "via1-irq",
|
MOS6522Q800VIA1State *v1s = MOS6522_Q800_VIA1(obj);
|
||||||
VIA1_IRQ_NB);
|
SysBusDevice *sbd = SYS_BUS_DEVICE(v1s);
|
||||||
|
|
||||||
|
memory_region_init_io(&v1s->via_mem, obj, &mos6522_q800_via1_ops, v1s,
|
||||||
|
"via1", VIA_SIZE);
|
||||||
|
sysbus_init_mmio(sbd, &v1s->via_mem);
|
||||||
|
|
||||||
|
/* ADB */
|
||||||
|
qbus_create_inplace((BusState *)&v1s->adb_bus, sizeof(v1s->adb_bus),
|
||||||
|
TYPE_ADB_BUS, DEVICE(v1s), "adb.0");
|
||||||
|
|
||||||
|
qdev_init_gpio_in(DEVICE(obj), via1_irq_request, VIA1_IRQ_NB);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const VMStateDescription vmstate_q800_via1 = {
|
||||||
|
.name = "q800-via1",
|
||||||
|
.version_id = 0,
|
||||||
|
.minimum_version_id = 0,
|
||||||
|
.post_load = via1_post_load,
|
||||||
|
.fields = (VMStateField[]) {
|
||||||
|
VMSTATE_STRUCT(parent_obj, MOS6522Q800VIA1State, 0, vmstate_mos6522,
|
||||||
|
MOS6522State),
|
||||||
|
VMSTATE_UINT8(last_b, MOS6522Q800VIA1State),
|
||||||
|
/* RTC */
|
||||||
|
VMSTATE_BUFFER(PRAM, MOS6522Q800VIA1State),
|
||||||
|
VMSTATE_UINT32(tick_offset, MOS6522Q800VIA1State),
|
||||||
|
VMSTATE_UINT8(data_out, MOS6522Q800VIA1State),
|
||||||
|
VMSTATE_INT32(data_out_cnt, MOS6522Q800VIA1State),
|
||||||
|
VMSTATE_UINT8(data_in, MOS6522Q800VIA1State),
|
||||||
|
VMSTATE_UINT8(data_in_cnt, MOS6522Q800VIA1State),
|
||||||
|
VMSTATE_UINT8(cmd, MOS6522Q800VIA1State),
|
||||||
|
VMSTATE_INT32(wprotect, MOS6522Q800VIA1State),
|
||||||
|
VMSTATE_INT32(alt, MOS6522Q800VIA1State),
|
||||||
|
/* ADB */
|
||||||
|
VMSTATE_INT32(adb_data_in_size, MOS6522Q800VIA1State),
|
||||||
|
VMSTATE_INT32(adb_data_in_index, MOS6522Q800VIA1State),
|
||||||
|
VMSTATE_INT32(adb_data_out_index, MOS6522Q800VIA1State),
|
||||||
|
VMSTATE_BUFFER(adb_data_in, MOS6522Q800VIA1State),
|
||||||
|
VMSTATE_BUFFER(adb_data_out, MOS6522Q800VIA1State),
|
||||||
|
VMSTATE_UINT8(adb_autopoll_cmd, MOS6522Q800VIA1State),
|
||||||
|
/* Timers */
|
||||||
|
VMSTATE_TIMER_PTR(one_second_timer, MOS6522Q800VIA1State),
|
||||||
|
VMSTATE_INT64(next_second, MOS6522Q800VIA1State),
|
||||||
|
VMSTATE_TIMER_PTR(sixty_hz_timer, MOS6522Q800VIA1State),
|
||||||
|
VMSTATE_INT64(next_sixty_hz, MOS6522Q800VIA1State),
|
||||||
|
VMSTATE_END_OF_LIST()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static Property mos6522_q800_via1_properties[] = {
|
||||||
|
DEFINE_PROP_DRIVE("drive", MOS6522Q800VIA1State, blk),
|
||||||
|
DEFINE_PROP_END_OF_LIST(),
|
||||||
|
};
|
||||||
|
|
||||||
static void mos6522_q800_via1_class_init(ObjectClass *oc, void *data)
|
static void mos6522_q800_via1_class_init(ObjectClass *oc, void *data)
|
||||||
{
|
{
|
||||||
DeviceClass *dc = DEVICE_CLASS(oc);
|
DeviceClass *dc = DEVICE_CLASS(oc);
|
||||||
|
|
||||||
|
dc->realize = mos6522_q800_via1_realize;
|
||||||
dc->reset = mos6522_q800_via1_reset;
|
dc->reset = mos6522_q800_via1_reset;
|
||||||
|
dc->vmsd = &vmstate_q800_via1;
|
||||||
|
device_class_set_props(dc, mos6522_q800_via1_properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const TypeInfo mos6522_q800_via1_type_info = {
|
static const TypeInfo mos6522_q800_via1_type_info = {
|
||||||
@ -1192,20 +1123,61 @@ static void mos6522_q800_via2_reset(DeviceState *dev)
|
|||||||
|
|
||||||
ms->dirb = 0;
|
ms->dirb = 0;
|
||||||
ms->b = 0;
|
ms->b = 0;
|
||||||
|
ms->dira = 0;
|
||||||
|
ms->a = 0x7f;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void via2_nubus_irq_request(void *opaque, int irq, int level)
|
||||||
|
{
|
||||||
|
MOS6522Q800VIA2State *v2s = opaque;
|
||||||
|
MOS6522State *s = MOS6522(v2s);
|
||||||
|
MOS6522DeviceClass *mdc = MOS6522_GET_CLASS(s);
|
||||||
|
|
||||||
|
if (level) {
|
||||||
|
/* Port A nubus IRQ inputs are active LOW */
|
||||||
|
s->a &= ~(1 << irq);
|
||||||
|
s->ifr |= 1 << VIA2_IRQ_NUBUS_BIT;
|
||||||
|
} else {
|
||||||
|
s->a |= (1 << irq);
|
||||||
|
s->ifr &= ~(1 << VIA2_IRQ_NUBUS_BIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
mdc->update_irq(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mos6522_q800_via2_init(Object *obj)
|
static void mos6522_q800_via2_init(Object *obj)
|
||||||
{
|
{
|
||||||
qdev_init_gpio_in_named(DEVICE(obj), via2_irq_request, "via2-irq",
|
MOS6522Q800VIA2State *v2s = MOS6522_Q800_VIA2(obj);
|
||||||
VIA2_IRQ_NB);
|
SysBusDevice *sbd = SYS_BUS_DEVICE(v2s);
|
||||||
|
|
||||||
|
memory_region_init_io(&v2s->via_mem, obj, &mos6522_q800_via2_ops, v2s,
|
||||||
|
"via2", VIA_SIZE);
|
||||||
|
sysbus_init_mmio(sbd, &v2s->via_mem);
|
||||||
|
|
||||||
|
qdev_init_gpio_in(DEVICE(obj), via2_irq_request, VIA2_IRQ_NB);
|
||||||
|
|
||||||
|
qdev_init_gpio_in_named(DEVICE(obj), via2_nubus_irq_request, "nubus-irq",
|
||||||
|
VIA2_NUBUS_IRQ_NB);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const VMStateDescription vmstate_q800_via2 = {
|
||||||
|
.name = "q800-via2",
|
||||||
|
.version_id = 0,
|
||||||
|
.minimum_version_id = 0,
|
||||||
|
.fields = (VMStateField[]) {
|
||||||
|
VMSTATE_STRUCT(parent_obj, MOS6522Q800VIA2State, 0, vmstate_mos6522,
|
||||||
|
MOS6522State),
|
||||||
|
VMSTATE_END_OF_LIST()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
static void mos6522_q800_via2_class_init(ObjectClass *oc, void *data)
|
static void mos6522_q800_via2_class_init(ObjectClass *oc, void *data)
|
||||||
{
|
{
|
||||||
DeviceClass *dc = DEVICE_CLASS(oc);
|
DeviceClass *dc = DEVICE_CLASS(oc);
|
||||||
MOS6522DeviceClass *mdc = MOS6522_CLASS(oc);
|
MOS6522DeviceClass *mdc = MOS6522_CLASS(oc);
|
||||||
|
|
||||||
dc->reset = mos6522_q800_via2_reset;
|
dc->reset = mos6522_q800_via2_reset;
|
||||||
|
dc->vmsd = &vmstate_q800_via2;
|
||||||
mdc->portB_write = mos6522_q800_via2_portB_write;
|
mdc->portB_write = mos6522_q800_via2_portB_write;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1221,7 +1193,6 @@ static void mac_via_register_types(void)
|
|||||||
{
|
{
|
||||||
type_register_static(&mos6522_q800_via1_type_info);
|
type_register_static(&mos6522_q800_via1_type_info);
|
||||||
type_register_static(&mos6522_q800_via2_type_info);
|
type_register_static(&mos6522_q800_via2_type_info);
|
||||||
type_register_static(&mac_via_info);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type_init(mac_via_register_types);
|
type_init(mac_via_register_types);
|
||||||
|
@ -15,6 +15,8 @@
|
|||||||
#include "qom/object.h"
|
#include "qom/object.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define VIA_SIZE 0x2000
|
||||||
|
|
||||||
/* VIA 1 */
|
/* VIA 1 */
|
||||||
#define VIA1_IRQ_ONE_SECOND_BIT 0
|
#define VIA1_IRQ_ONE_SECOND_BIT 0
|
||||||
#define VIA1_IRQ_60HZ_BIT 1
|
#define VIA1_IRQ_60HZ_BIT 1
|
||||||
@ -38,9 +40,35 @@ struct MOS6522Q800VIA1State {
|
|||||||
/*< private >*/
|
/*< private >*/
|
||||||
MOS6522State parent_obj;
|
MOS6522State parent_obj;
|
||||||
|
|
||||||
|
MemoryRegion via_mem;
|
||||||
|
|
||||||
qemu_irq irqs[VIA1_IRQ_NB];
|
qemu_irq irqs[VIA1_IRQ_NB];
|
||||||
uint8_t last_b;
|
uint8_t last_b;
|
||||||
|
|
||||||
|
/* RTC */
|
||||||
uint8_t PRAM[256];
|
uint8_t PRAM[256];
|
||||||
|
BlockBackend *blk;
|
||||||
|
VMChangeStateEntry *vmstate;
|
||||||
|
|
||||||
|
uint32_t tick_offset;
|
||||||
|
|
||||||
|
uint8_t data_out;
|
||||||
|
int data_out_cnt;
|
||||||
|
uint8_t data_in;
|
||||||
|
uint8_t data_in_cnt;
|
||||||
|
uint8_t cmd;
|
||||||
|
int wprotect;
|
||||||
|
int alt;
|
||||||
|
|
||||||
|
/* ADB */
|
||||||
|
ADBBusState adb_bus;
|
||||||
|
qemu_irq adb_data_ready;
|
||||||
|
int adb_data_in_size;
|
||||||
|
int adb_data_in_index;
|
||||||
|
int adb_data_out_index;
|
||||||
|
uint8_t adb_data_in[128];
|
||||||
|
uint8_t adb_data_out[16];
|
||||||
|
uint8_t adb_autopoll_cmd;
|
||||||
|
|
||||||
/* external timers */
|
/* external timers */
|
||||||
QEMUTimer *one_second_timer;
|
QEMUTimer *one_second_timer;
|
||||||
@ -52,7 +80,7 @@ struct MOS6522Q800VIA1State {
|
|||||||
|
|
||||||
/* VIA 2 */
|
/* VIA 2 */
|
||||||
#define VIA2_IRQ_SCSI_DATA_BIT 0
|
#define VIA2_IRQ_SCSI_DATA_BIT 0
|
||||||
#define VIA2_IRQ_SLOT_BIT 1
|
#define VIA2_IRQ_NUBUS_BIT 1
|
||||||
#define VIA2_IRQ_UNUSED_BIT 2
|
#define VIA2_IRQ_UNUSED_BIT 2
|
||||||
#define VIA2_IRQ_SCSI_BIT 3
|
#define VIA2_IRQ_SCSI_BIT 3
|
||||||
#define VIA2_IRQ_ASC_BIT 4
|
#define VIA2_IRQ_ASC_BIT 4
|
||||||
@ -60,58 +88,29 @@ struct MOS6522Q800VIA1State {
|
|||||||
#define VIA2_IRQ_NB 8
|
#define VIA2_IRQ_NB 8
|
||||||
|
|
||||||
#define VIA2_IRQ_SCSI_DATA (1 << VIA2_IRQ_SCSI_DATA_BIT)
|
#define VIA2_IRQ_SCSI_DATA (1 << VIA2_IRQ_SCSI_DATA_BIT)
|
||||||
#define VIA2_IRQ_SLOT (1 << VIA2_IRQ_SLOT_BIT)
|
#define VIA2_IRQ_NUBUS (1 << VIA2_IRQ_NUBUS_BIT)
|
||||||
#define VIA2_IRQ_UNUSED (1 << VIA2_IRQ_SCSI_BIT)
|
#define VIA2_IRQ_UNUSED (1 << VIA2_IRQ_SCSI_BIT)
|
||||||
#define VIA2_IRQ_SCSI (1 << VIA2_IRQ_UNUSED_BIT)
|
#define VIA2_IRQ_SCSI (1 << VIA2_IRQ_UNUSED_BIT)
|
||||||
#define VIA2_IRQ_ASC (1 << VIA2_IRQ_ASC_BIT)
|
#define VIA2_IRQ_ASC (1 << VIA2_IRQ_ASC_BIT)
|
||||||
|
|
||||||
|
#define VIA2_NUBUS_IRQ_NB 7
|
||||||
|
|
||||||
|
#define VIA2_NUBUS_IRQ_9 0
|
||||||
|
#define VIA2_NUBUS_IRQ_A 1
|
||||||
|
#define VIA2_NUBUS_IRQ_B 2
|
||||||
|
#define VIA2_NUBUS_IRQ_C 3
|
||||||
|
#define VIA2_NUBUS_IRQ_D 4
|
||||||
|
#define VIA2_NUBUS_IRQ_E 5
|
||||||
|
#define VIA2_NUBUS_IRQ_INTVIDEO 6
|
||||||
|
|
||||||
#define TYPE_MOS6522_Q800_VIA2 "mos6522-q800-via2"
|
#define TYPE_MOS6522_Q800_VIA2 "mos6522-q800-via2"
|
||||||
OBJECT_DECLARE_SIMPLE_TYPE(MOS6522Q800VIA2State, MOS6522_Q800_VIA2)
|
OBJECT_DECLARE_SIMPLE_TYPE(MOS6522Q800VIA2State, MOS6522_Q800_VIA2)
|
||||||
|
|
||||||
struct MOS6522Q800VIA2State {
|
struct MOS6522Q800VIA2State {
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
MOS6522State parent_obj;
|
MOS6522State parent_obj;
|
||||||
};
|
|
||||||
|
|
||||||
|
MemoryRegion via_mem;
|
||||||
#define TYPE_MAC_VIA "mac_via"
|
|
||||||
OBJECT_DECLARE_SIMPLE_TYPE(MacVIAState, MAC_VIA)
|
|
||||||
|
|
||||||
struct MacVIAState {
|
|
||||||
SysBusDevice busdev;
|
|
||||||
|
|
||||||
VMChangeStateEntry *vmstate;
|
|
||||||
|
|
||||||
/* MMIO */
|
|
||||||
MemoryRegion mmio;
|
|
||||||
MemoryRegion via1mem;
|
|
||||||
MemoryRegion via2mem;
|
|
||||||
|
|
||||||
/* VIAs */
|
|
||||||
MOS6522Q800VIA1State mos6522_via1;
|
|
||||||
MOS6522Q800VIA2State mos6522_via2;
|
|
||||||
|
|
||||||
/* RTC */
|
|
||||||
uint32_t tick_offset;
|
|
||||||
|
|
||||||
uint8_t data_out;
|
|
||||||
int data_out_cnt;
|
|
||||||
uint8_t data_in;
|
|
||||||
uint8_t data_in_cnt;
|
|
||||||
uint8_t cmd;
|
|
||||||
int wprotect;
|
|
||||||
int alt;
|
|
||||||
BlockBackend *blk;
|
|
||||||
|
|
||||||
/* ADB */
|
|
||||||
ADBBusState adb_bus;
|
|
||||||
qemu_irq adb_data_ready;
|
|
||||||
int adb_data_in_size;
|
|
||||||
int adb_data_in_index;
|
|
||||||
int adb_data_out_index;
|
|
||||||
uint8_t adb_data_in[128];
|
|
||||||
uint8_t adb_data_out[16];
|
|
||||||
uint8_t adb_autopoll_cmd;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user