qemu/hw/misc/mac_via.c
<<
>>
Prefs
   1/*
   2 * QEMU m68k Macintosh VIA device support
   3 *
   4 * Copyright (c) 2011-2018 Laurent Vivier
   5 * Copyright (c) 2018 Mark Cave-Ayland
   6 *
   7 * Some parts from hw/misc/macio/cuda.c
   8 *
   9 * Copyright (c) 2004-2007 Fabrice Bellard
  10 * Copyright (c) 2007 Jocelyn Mayer
  11 *
  12 * some parts from linux-2.6.29, arch/m68k/include/asm/mac_via.h
  13 *
  14 * This work is licensed under the terms of the GNU GPL, version 2 or later.
  15 * See the COPYING file in the top-level directory.
  16 */
  17
  18#include "qemu/osdep.h"
  19#include "qemu-common.h"
  20#include "migration/vmstate.h"
  21#include "hw/sysbus.h"
  22#include "hw/irq.h"
  23#include "qemu/timer.h"
  24#include "hw/misc/mac_via.h"
  25#include "hw/misc/mos6522.h"
  26#include "hw/input/adb.h"
  27#include "sysemu/runstate.h"
  28#include "qapi/error.h"
  29#include "qemu/cutils.h"
  30#include "hw/qdev-properties.h"
  31#include "sysemu/block-backend.h"
  32#include "trace.h"
  33#include "qemu/log.h"
  34
  35/*
  36 * VIAs: There are two in every machine,
  37 */
  38
  39#define VIA_SIZE (0x2000)
  40
  41/*
  42 * Not all of these are true post MacII I think.
  43 * CSA: probably the ones CHRP marks as 'unused' change purposes
  44 * when the IWM becomes the SWIM.
  45 * http://www.rs6000.ibm.com/resource/technology/chrpio/via5.mak.html
  46 * ftp://ftp.austin.ibm.com/pub/technology/spec/chrp/inwork/CHRP_IORef_1.0.pdf
  47 *
  48 * also, http://developer.apple.com/technotes/hw/hw_09.html claims the
  49 * following changes for IIfx:
  50 * VIA1A_vSccWrReq not available and that VIA1A_vSync has moved to an IOP.
  51 * Also, "All of the functionality of VIA2 has been moved to other chips".
  52 */
  53
  54#define VIA1A_vSccWrReq 0x80   /*
  55                                * SCC write. (input)
  56                                * [CHRP] SCC WREQ: Reflects the state of the
  57                                * Wait/Request pins from the SCC.
  58                                * [Macintosh Family Hardware]
  59                                * as CHRP on SE/30,II,IIx,IIcx,IIci.
  60                                * on IIfx, "0 means an active request"
  61                                */
  62#define VIA1A_vRev8     0x40   /*
  63                                * Revision 8 board ???
  64                                * [CHRP] En WaitReqB: Lets the WaitReq_L
  65                                * signal from port B of the SCC appear on
  66                                * the PA7 input pin. Output.
  67                                * [Macintosh Family] On the SE/30, this
  68                                * is the bit to flip screen buffers.
  69                                * 0=alternate, 1=main.
  70                                * on II,IIx,IIcx,IIci,IIfx this is a bit
  71                                * for Rev ID. 0=II,IIx, 1=IIcx,IIci,IIfx
  72                                */
  73#define VIA1A_vHeadSel  0x20   /*
  74                                * Head select for IWM.
  75                                * [CHRP] unused.
  76                                * [Macintosh Family] "Floppy disk
  77                                * state-control line SEL" on all but IIfx
  78                                */
  79#define VIA1A_vOverlay  0x10   /*
  80                                * [Macintosh Family] On SE/30,II,IIx,IIcx
  81                                * this bit enables the "Overlay" address
  82                                * map in the address decoders as it is on
  83                                * reset for mapping the ROM over the reset
  84                                * vector. 1=use overlay map.
  85                                * On the IIci,IIfx it is another bit of the
  86                                * CPU ID: 0=normal IIci, 1=IIci with parity
  87                                * feature or IIfx.
  88                                * [CHRP] En WaitReqA: Lets the WaitReq_L
  89                                * signal from port A of the SCC appear
  90                                * on the PA7 input pin (CHRP). Output.
  91                                * [MkLinux] "Drive Select"
  92                                *  (with 0x20 being 'disk head select')
  93                                */
  94#define VIA1A_vSync     0x08   /*
  95                                * [CHRP] Sync Modem: modem clock select:
  96                                * 1: select the external serial clock to
  97                                *    drive the SCC's /RTxCA pin.
  98                                * 0: Select the 3.6864MHz clock to drive
  99                                *    the SCC cell.
 100                                * [Macintosh Family] Correct on all but IIfx
 101                                */
 102
 103/*
 104 * Macintosh Family Hardware sez: bits 0-2 of VIA1A are volume control
 105 * on Macs which had the PWM sound hardware.  Reserved on newer models.
 106 * On IIci,IIfx, bits 1-2 are the rest of the CPU ID:
 107 * bit 2: 1=IIci, 0=IIfx
 108 * bit 1: 1 on both IIci and IIfx.
 109 * MkLinux sez bit 0 is 'burnin flag' in this case.
 110 * CHRP sez: VIA1A bits 0-2 and 5 are 'unused': if programmed as
 111 * inputs, these bits will read 0.
 112 */
 113#define VIA1A_vVolume   0x07    /* Audio volume mask for PWM */
 114#define VIA1A_CPUID0    0x02    /* CPU id bit 0 on RBV, others */
 115#define VIA1A_CPUID1    0x04    /* CPU id bit 0 on RBV, others */
 116#define VIA1A_CPUID2    0x10    /* CPU id bit 0 on RBV, others */
 117#define VIA1A_CPUID3    0x40    /* CPU id bit 0 on RBV, others */
 118
 119/*
 120 * Info on VIA1B is from Macintosh Family Hardware & MkLinux.
 121 * CHRP offers no info.
 122 */
 123#define VIA1B_vSound   0x80    /*
 124                                * Sound enable (for compatibility with
 125                                * PWM hardware) 0=enabled.
 126                                * Also, on IIci w/parity, shows parity error
 127                                * 0=error, 1=OK.
 128                                */
 129#define VIA1B_vMystery 0x40    /*
 130                                * On IIci, parity enable. 0=enabled,1=disabled
 131                                * On SE/30, vertical sync interrupt enable.
 132                                * 0=enabled. This vSync interrupt shows up
 133                                * as a slot $E interrupt.
 134                                */
 135#define VIA1B_vADBS2   0x20    /* ADB state input bit 1 (unused on IIfx) */
 136#define VIA1B_vADBS1   0x10    /* ADB state input bit 0 (unused on IIfx) */
 137#define VIA1B_vADBInt  0x08    /* ADB interrupt 0=interrupt (unused on IIfx)*/
 138#define VIA1B_vRTCEnb  0x04    /* Enable Real time clock. 0=enabled. */
 139#define VIA1B_vRTCClk  0x02    /* Real time clock serial-clock line. */
 140#define VIA1B_vRTCData 0x01    /* Real time clock serial-data line. */
 141
 142/*
 143 *    VIA2 A register is the interrupt lines raised off the nubus
 144 *    slots.
 145 *      The below info is from 'Macintosh Family Hardware.'
 146 *      MkLinux calls the 'IIci internal video IRQ' below the 'RBV slot 0 irq.'
 147 *      It also notes that the slot $9 IRQ is the 'Ethernet IRQ' and
 148 *      defines the 'Video IRQ' as 0x40 for the 'EVR' VIA work-alike.
 149 *      Perhaps OSS uses vRAM1 and vRAM2 for ADB.
 150 */
 151
 152#define VIA2A_vRAM1    0x80    /* RAM size bit 1 (IIci: reserved) */
 153#define VIA2A_vRAM0    0x40    /* RAM size bit 0 (IIci: internal video IRQ) */
 154#define VIA2A_vIRQE    0x20    /* IRQ from slot $E */
 155#define VIA2A_vIRQD    0x10    /* IRQ from slot $D */
 156#define VIA2A_vIRQC    0x08    /* IRQ from slot $C */
 157#define VIA2A_vIRQB    0x04    /* IRQ from slot $B */
 158#define VIA2A_vIRQA    0x02    /* IRQ from slot $A */
 159#define VIA2A_vIRQ9    0x01    /* IRQ from slot $9 */
 160
 161/*
 162 * RAM size bits decoded as follows:
 163 * bit1 bit0  size of ICs in bank A
 164 *  0    0    256 kbit
 165 *  0    1    1 Mbit
 166 *  1    0    4 Mbit
 167 *  1    1   16 Mbit
 168 */
 169
 170/*
 171 *    Register B has the fun stuff in it
 172 */
 173
 174#define VIA2B_vVBL    0x80    /*
 175                               * VBL output to VIA1 (60.15Hz) driven by
 176                               * timer T1.
 177                               * on IIci, parity test: 0=test mode.
 178                               * [MkLinux] RBV_PARODD: 1=odd,0=even.
 179                               */
 180#define VIA2B_vSndJck 0x40    /*
 181                               * External sound jack status.
 182                               * 0=plug is inserted.  On SE/30, always 0
 183                               */
 184#define VIA2B_vTfr0   0x20    /* Transfer mode bit 0 ack from NuBus */
 185#define VIA2B_vTfr1   0x10    /* Transfer mode bit 1 ack from NuBus */
 186#define VIA2B_vMode32 0x08    /*
 187                               * 24/32bit switch - doubles as cache flush
 188                               * on II, AMU/PMMU control.
 189                               *   if AMU, 0=24bit to 32bit translation
 190                               *   if PMMU, 1=PMMU is accessing page table.
 191                               * on SE/30 tied low.
 192                               * on IIx,IIcx,IIfx, unused.
 193                               * on IIci/RBV, cache control. 0=flush cache.
 194                               */
 195#define VIA2B_vPower  0x04   /*
 196                              * Power off, 0=shut off power.
 197                              * on SE/30 this signal sent to PDS card.
 198                              */
 199#define VIA2B_vBusLk  0x02   /*
 200                              * Lock NuBus transactions, 0=locked.
 201                              * on SE/30 sent to PDS card.
 202                              */
 203#define VIA2B_vCDis   0x01   /*
 204                              * Cache control. On IIci, 1=disable cache card
 205                              * on others, 0=disable processor's instruction
 206                              * and data caches.
 207                              */
 208
 209/* interrupt flags */
 210
 211#define IRQ_SET         0x80
 212
 213/* common */
 214
 215#define VIA_IRQ_TIMER1      0x40
 216#define VIA_IRQ_TIMER2      0x20
 217
 218/*
 219 * Apple sez: http://developer.apple.com/technotes/ov/ov_04.html
 220 * Another example of a valid function that has no ROM support is the use
 221 * of the alternate video page for page-flipping animation. Since there
 222 * is no ROM call to flip pages, it is necessary to go play with the
 223 * right bit in the VIA chip (6522 Versatile Interface Adapter).
 224 * [CSA: don't know which one this is, but it's one of 'em!]
 225 */
 226
 227/*
 228 *    6522 registers - see databook.
 229 * CSA: Assignments for VIA1 confirmed from CHRP spec.
 230 */
 231
 232/* partial address decode.  0xYYXX : XX part for RBV, YY part for VIA */
 233/* Note: 15 VIA regs, 8 RBV regs */
 234
 235#define vBufB    0x0000  /* [VIA/RBV]  Register B */
 236#define vBufAH   0x0200  /* [VIA only] Buffer A, with handshake. DON'T USE! */
 237#define vDirB    0x0400  /* [VIA only] Data Direction Register B. */
 238#define vDirA    0x0600  /* [VIA only] Data Direction Register A. */
 239#define vT1CL    0x0800  /* [VIA only] Timer one counter low. */
 240#define vT1CH    0x0a00  /* [VIA only] Timer one counter high. */
 241#define vT1LL    0x0c00  /* [VIA only] Timer one latches low. */
 242#define vT1LH    0x0e00  /* [VIA only] Timer one latches high. */
 243#define vT2CL    0x1000  /* [VIA only] Timer two counter low. */
 244#define vT2CH    0x1200  /* [VIA only] Timer two counter high. */
 245#define vSR      0x1400  /* [VIA only] Shift register. */
 246#define vACR     0x1600  /* [VIA only] Auxilary control register. */
 247#define vPCR     0x1800  /* [VIA only] Peripheral control register. */
 248                         /*
 249                          *           CHRP sez never ever to *write* this.
 250                          *            Mac family says never to *change* this.
 251                          * In fact we need to initialize it once at start.
 252                          */
 253#define vIFR     0x1a00  /* [VIA/RBV]  Interrupt flag register. */
 254#define vIER     0x1c00  /* [VIA/RBV]  Interrupt enable register. */
 255#define vBufA    0x1e00  /* [VIA/RBV] register A (no handshake) */
 256
 257/* from linux 2.6 drivers/macintosh/via-macii.c */
 258
 259/* Bits in ACR */
 260
 261#define VIA1ACR_vShiftCtrl         0x1c        /* Shift register control bits */
 262#define VIA1ACR_vShiftExtClk       0x0c        /* Shift on external clock */
 263#define VIA1ACR_vShiftOut          0x10        /* Shift out if 1 */
 264
 265/*
 266 * Apple Macintosh Family Hardware Refenece
 267 * Table 19-10 ADB transaction states
 268 */
 269
 270#define ADB_STATE_NEW       0
 271#define ADB_STATE_EVEN      1
 272#define ADB_STATE_ODD       2
 273#define ADB_STATE_IDLE      3
 274
 275#define VIA1B_vADB_StateMask    (VIA1B_vADBS1 | VIA1B_vADBS2)
 276#define VIA1B_vADB_StateShift   4
 277
 278#define VIA_TIMER_FREQ (783360)
 279#define VIA_ADB_POLL_FREQ 50 /* XXX: not real */
 280
 281/* VIA returns time offset from Jan 1, 1904, not 1970 */
 282#define RTC_OFFSET 2082844800
 283
 284enum {
 285    REG_0,
 286    REG_1,
 287    REG_2,
 288    REG_3,
 289    REG_TEST,
 290    REG_WPROTECT,
 291    REG_PRAM_ADDR,
 292    REG_PRAM_ADDR_LAST = REG_PRAM_ADDR + 19,
 293    REG_PRAM_SECT,
 294    REG_PRAM_SECT_LAST = REG_PRAM_SECT + 7,
 295    REG_INVALID,
 296    REG_EMPTY = 0xff,
 297};
 298
 299static void via1_VBL_update(MOS6522Q800VIA1State *v1s)
 300{
 301    MOS6522State *s = MOS6522(v1s);
 302
 303    /* 60 Hz irq */
 304    v1s->next_VBL = (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + 16630) /
 305                    16630 * 16630;
 306
 307    if (s->ier & VIA1_IRQ_VBLANK) {
 308        timer_mod(v1s->VBL_timer, v1s->next_VBL);
 309    } else {
 310        timer_del(v1s->VBL_timer);
 311    }
 312}
 313
 314static void via1_one_second_update(MOS6522Q800VIA1State *v1s)
 315{
 316    MOS6522State *s = MOS6522(v1s);
 317
 318    v1s->next_second = (qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + 1000) /
 319                       1000 * 1000;
 320    if (s->ier & VIA1_IRQ_ONE_SECOND) {
 321        timer_mod(v1s->one_second_timer, v1s->next_second);
 322    } else {
 323        timer_del(v1s->one_second_timer);
 324    }
 325}
 326
 327static void via1_VBL(void *opaque)
 328{
 329    MOS6522Q800VIA1State *v1s = opaque;
 330    MOS6522State *s = MOS6522(v1s);
 331    MOS6522DeviceClass *mdc = MOS6522_DEVICE_GET_CLASS(s);
 332
 333    s->ifr |= VIA1_IRQ_VBLANK;
 334    mdc->update_irq(s);
 335
 336    via1_VBL_update(v1s);
 337}
 338
 339static void via1_one_second(void *opaque)
 340{
 341    MOS6522Q800VIA1State *v1s = opaque;
 342    MOS6522State *s = MOS6522(v1s);
 343    MOS6522DeviceClass *mdc = MOS6522_DEVICE_GET_CLASS(s);
 344
 345    s->ifr |= VIA1_IRQ_ONE_SECOND;
 346    mdc->update_irq(s);
 347
 348    via1_one_second_update(v1s);
 349}
 350
 351static void via1_irq_request(void *opaque, int irq, int level)
 352{
 353    MOS6522Q800VIA1State *v1s = opaque;
 354    MOS6522State *s = MOS6522(v1s);
 355    MOS6522DeviceClass *mdc = MOS6522_DEVICE_GET_CLASS(s);
 356
 357    if (level) {
 358        s->ifr |= 1 << irq;
 359    } else {
 360        s->ifr &= ~(1 << irq);
 361    }
 362
 363    mdc->update_irq(s);
 364}
 365
 366static void via2_irq_request(void *opaque, int irq, int level)
 367{
 368    MOS6522Q800VIA2State *v2s = opaque;
 369    MOS6522State *s = MOS6522(v2s);
 370    MOS6522DeviceClass *mdc = MOS6522_DEVICE_GET_CLASS(s);
 371
 372    if (level) {
 373        s->ifr |= 1 << irq;
 374    } else {
 375        s->ifr &= ~(1 << irq);
 376    }
 377
 378    mdc->update_irq(s);
 379}
 380
 381
 382static void pram_update(MacVIAState *m)
 383{
 384    if (m->blk) {
 385        if (blk_pwrite(m->blk, 0, m->mos6522_via1.PRAM,
 386                       sizeof(m->mos6522_via1.PRAM), 0) < 0) {
 387            qemu_log("pram_update: cannot write to file\n");
 388        }
 389    }
 390}
 391
 392/*
 393 * RTC Commands
 394 *
 395 * Command byte    Register addressed by the command
 396 *
 397 * z0000001        Seconds register 0 (lowest-order byte)
 398 * z0000101        Seconds register 1
 399 * z0001001        Seconds register 2
 400 * z0001101        Seconds register 3 (highest-order byte)
 401 * 00110001        Test register (write-only)
 402 * 00110101        Write-Protect Register (write-only)
 403 * z010aa01        RAM address 100aa ($10-$13) (first 20 bytes only)
 404 * z1aaaa01        RAM address 0aaaa ($00-$0F) (first 20 bytes only)
 405 * z0111aaa        Extended memory designator and sector number
 406 *
 407 * For a read request, z=1, for a write z=0
 408 * The letter a indicates bits whose value depend on what parameter
 409 * RAM byte you want to address
 410 */
 411static int via1_rtc_compact_cmd(uint8_t value)
 412{
 413    uint8_t read = value & 0x80;
 414
 415    value &= 0x7f;
 416
 417    /* the last 2 bits of a command byte must always be 0b01 ... */
 418    if ((value & 0x78) == 0x38) {
 419        /* except for the extended memory designator */
 420        return read | (REG_PRAM_SECT + (value & 0x07));
 421    }
 422    if ((value & 0x03) == 0x01) {
 423        value >>= 2;
 424        if ((value & 0x1c) == 0) {
 425            /* seconds registers */
 426            return read | (REG_0 + (value & 0x03));
 427        } else if ((value == 0x0c) && !read) {
 428            return REG_TEST;
 429        } else if ((value == 0x0d) && !read) {
 430            return REG_WPROTECT;
 431        } else if ((value & 0x1c) == 0x08) {
 432            /* RAM address 0x10 to 0x13 */
 433            return read | (REG_PRAM_ADDR + 0x10 + (value & 0x03));
 434        } else if ((value & 0x43) == 0x41) {
 435            /* RAM address 0x00 to 0x0f */
 436            return read | (REG_PRAM_ADDR + (value & 0x0f));
 437        }
 438    }
 439    return REG_INVALID;
 440}
 441
 442static void via1_rtc_update(MacVIAState *m)
 443{
 444    MOS6522Q800VIA1State *v1s = &m->mos6522_via1;
 445    MOS6522State *s = MOS6522(v1s);
 446    int cmd, sector, addr;
 447    uint32_t time;
 448
 449    if (s->b & VIA1B_vRTCEnb) {
 450        return;
 451    }
 452
 453    if (s->dirb & VIA1B_vRTCData) {
 454        /* send bits to the RTC */
 455        if (!(v1s->last_b & VIA1B_vRTCClk) && (s->b & VIA1B_vRTCClk)) {
 456            m->data_out <<= 1;
 457            m->data_out |= s->b & VIA1B_vRTCData;
 458            m->data_out_cnt++;
 459        }
 460        trace_via1_rtc_update_data_out(m->data_out_cnt, m->data_out);
 461    } else {
 462        trace_via1_rtc_update_data_in(m->data_in_cnt, m->data_in);
 463        /* receive bits from the RTC */
 464        if ((v1s->last_b & VIA1B_vRTCClk) &&
 465            !(s->b & VIA1B_vRTCClk) &&
 466            m->data_in_cnt) {
 467            s->b = (s->b & ~VIA1B_vRTCData) |
 468                   ((m->data_in >> 7) & VIA1B_vRTCData);
 469            m->data_in <<= 1;
 470            m->data_in_cnt--;
 471        }
 472        return;
 473    }
 474
 475    if (m->data_out_cnt != 8) {
 476        return;
 477    }
 478
 479    m->data_out_cnt = 0;
 480
 481    trace_via1_rtc_internal_status(m->cmd, m->alt, m->data_out);
 482    /* first byte: it's a command */
 483    if (m->cmd == REG_EMPTY) {
 484
 485        cmd = via1_rtc_compact_cmd(m->data_out);
 486        trace_via1_rtc_internal_cmd(cmd);
 487
 488        if (cmd == REG_INVALID) {
 489            trace_via1_rtc_cmd_invalid(m->data_out);
 490            return;
 491        }
 492
 493        if (cmd & 0x80) { /* this is a read command */
 494            switch (cmd & 0x7f) {
 495            case REG_0...REG_3: /* seconds registers */
 496                /*
 497                 * register 0 is lowest-order byte
 498                 * register 3 is highest-order byte
 499                 */
 500
 501                time = m->tick_offset + (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL)
 502                       / NANOSECONDS_PER_SECOND);
 503                trace_via1_rtc_internal_time(time);
 504                m->data_in = (time >> ((cmd & 0x03) << 3)) & 0xff;
 505                m->data_in_cnt = 8;
 506                trace_via1_rtc_cmd_seconds_read((cmd & 0x7f) - REG_0,
 507                                                m->data_in);
 508                break;
 509            case REG_PRAM_ADDR...REG_PRAM_ADDR_LAST:
 510                /* PRAM address 0x00 -> 0x13 */
 511                m->data_in = v1s->PRAM[(cmd & 0x7f) - REG_PRAM_ADDR];
 512                m->data_in_cnt = 8;
 513                trace_via1_rtc_cmd_pram_read((cmd & 0x7f) - REG_PRAM_ADDR,
 514                                             m->data_in);
 515                break;
 516            case REG_PRAM_SECT...REG_PRAM_SECT_LAST:
 517                /*
 518                 * extended memory designator and sector number
 519                 * the only two-byte read command
 520                 */
 521                trace_via1_rtc_internal_set_cmd(cmd);
 522                m->cmd = cmd;
 523                break;
 524            default:
 525                g_assert_not_reached();
 526                break;
 527            }
 528            return;
 529        }
 530
 531        /* this is a write command, needs a parameter */
 532        if (cmd == REG_WPROTECT || !m->wprotect) {
 533            trace_via1_rtc_internal_set_cmd(cmd);
 534            m->cmd = cmd;
 535        } else {
 536            trace_via1_rtc_internal_ignore_cmd(cmd);
 537        }
 538        return;
 539    }
 540
 541    /* second byte: it's a parameter */
 542    if (m->alt == REG_EMPTY) {
 543        switch (m->cmd & 0x7f) {
 544        case REG_0...REG_3: /* seconds register */
 545            /* FIXME */
 546            trace_via1_rtc_cmd_seconds_write(m->cmd - REG_0, m->data_out);
 547            m->cmd = REG_EMPTY;
 548            break;
 549        case REG_TEST:
 550            /* device control: nothing to do */
 551            trace_via1_rtc_cmd_test_write(m->data_out);
 552            m->cmd = REG_EMPTY;
 553            break;
 554        case REG_WPROTECT:
 555            /* Write Protect register */
 556            trace_via1_rtc_cmd_wprotect_write(m->data_out);
 557            m->wprotect = !!(m->data_out & 0x80);
 558            m->cmd = REG_EMPTY;
 559            break;
 560        case REG_PRAM_ADDR...REG_PRAM_ADDR_LAST:
 561            /* PRAM address 0x00 -> 0x13 */
 562            trace_via1_rtc_cmd_pram_write(m->cmd - REG_PRAM_ADDR, m->data_out);
 563            v1s->PRAM[m->cmd - REG_PRAM_ADDR] = m->data_out;
 564            pram_update(m);
 565            m->cmd = REG_EMPTY;
 566            break;
 567        case REG_PRAM_SECT...REG_PRAM_SECT_LAST:
 568            addr = (m->data_out >> 2) & 0x1f;
 569            sector = (m->cmd & 0x7f) - REG_PRAM_SECT;
 570            if (m->cmd & 0x80) {
 571                /* it's a read */
 572                m->data_in = v1s->PRAM[sector * 32 + addr];
 573                m->data_in_cnt = 8;
 574                trace_via1_rtc_cmd_pram_sect_read(sector, addr,
 575                                                  sector * 32 + addr,
 576                                                  m->data_in);
 577                m->cmd = REG_EMPTY;
 578            } else {
 579                /* it's a write, we need one more parameter */
 580                trace_via1_rtc_internal_set_alt(addr, sector, addr);
 581                m->alt = addr;
 582            }
 583            break;
 584        default:
 585            g_assert_not_reached();
 586            break;
 587        }
 588        return;
 589    }
 590
 591    /* third byte: it's the data of a REG_PRAM_SECT write */
 592    g_assert(REG_PRAM_SECT <= m->cmd && m->cmd <= REG_PRAM_SECT_LAST);
 593    sector = m->cmd - REG_PRAM_SECT;
 594    v1s->PRAM[sector * 32 + m->alt] = m->data_out;
 595    pram_update(m);
 596    trace_via1_rtc_cmd_pram_sect_write(sector, m->alt, sector * 32 + m->alt,
 597                                       m->data_out);
 598    m->alt = REG_EMPTY;
 599    m->cmd = REG_EMPTY;
 600}
 601
 602static void adb_via_poll(void *opaque)
 603{
 604    MacVIAState *m = opaque;
 605    MOS6522Q800VIA1State *v1s = MOS6522_Q800_VIA1(&m->mos6522_via1);
 606    MOS6522State *s = MOS6522(v1s);
 607    ADBBusState *adb_bus = &m->adb_bus;
 608    uint8_t obuf[9];
 609    uint8_t *data = &s->sr;
 610    int olen;
 611    uint16_t pending;
 612
 613    /*
 614     * Setting vADBInt below indicates that an autopoll reply has been
 615     * received, however we must block autopoll until the point where
 616     * the entire reply has been read back to the host
 617     */
 618    adb_autopoll_block(adb_bus);
 619
 620    m->adb_data_in_index = 0;
 621    m->adb_data_out_index = 0;
 622    olen = adb_poll(adb_bus, obuf, adb_bus->autopoll_mask);
 623
 624    if (olen > 0) {
 625        /* Autopoll response */
 626        *data = obuf[0];
 627        olen--;
 628        memcpy(m->adb_data_in, &obuf[1], olen);
 629        m->adb_data_in_size = olen;
 630
 631        s->b &= ~VIA1B_vADBInt;
 632        qemu_irq_raise(m->adb_data_ready);
 633    } else if (olen < 0) {
 634        /* Bus timeout (device does not exist) */
 635        *data = 0xff;
 636        s->b |= VIA1B_vADBInt;
 637        adb_autopoll_unblock(adb_bus);
 638    } else {
 639        pending = adb_bus->pending & ~(1 << (m->adb_autopoll_cmd >> 4));
 640
 641        if (pending) {
 642            /*
 643             * Bus timeout (device exists but another device has data). Block
 644             * autopoll so the OS can read out the first EVEN and first ODD
 645             * byte to determine bus timeout and SRQ status
 646             */
 647            *data = m->adb_autopoll_cmd;
 648            s->b &= ~VIA1B_vADBInt;
 649
 650            obuf[0] = 0xff;
 651            obuf[1] = 0xff;
 652            olen = 2;
 653
 654            memcpy(m->adb_data_in, obuf, olen);
 655            m->adb_data_in_size = olen;
 656
 657            qemu_irq_raise(m->adb_data_ready);
 658        } else {
 659            /* Bus timeout (device exists but no other device has data) */
 660            *data = 0;
 661            s->b |= VIA1B_vADBInt;
 662            adb_autopoll_unblock(adb_bus);
 663        }
 664    }
 665
 666    trace_via1_adb_poll(*data, (s->b & VIA1B_vADBInt) ? "+" : "-",
 667                        adb_bus->status, m->adb_data_in_index, olen);
 668}
 669
 670static int adb_via_send_len(uint8_t data)
 671{
 672    /* Determine the send length from the given ADB command */
 673    uint8_t cmd = data & 0xc;
 674    uint8_t reg = data & 0x3;
 675
 676    switch (cmd) {
 677    case 0x8:
 678        /* Listen command */
 679        switch (reg) {
 680        case 2:
 681            /* Register 2 is only used for the keyboard */
 682            return 3;
 683        case 3:
 684            /*
 685             * Fortunately our devices only implement writes
 686             * to register 3 which is fixed at 2 bytes
 687             */
 688            return 3;
 689        default:
 690            qemu_log_mask(LOG_UNIMP, "ADB unknown length for register %d\n",
 691                          reg);
 692            return 1;
 693        }
 694    default:
 695        /* Talk, BusReset */
 696        return 1;
 697    }
 698}
 699
 700static void adb_via_send(MacVIAState *s, int state, uint8_t data)
 701{
 702    MOS6522Q800VIA1State *v1s = MOS6522_Q800_VIA1(&s->mos6522_via1);
 703    MOS6522State *ms = MOS6522(v1s);
 704    ADBBusState *adb_bus = &s->adb_bus;
 705    uint16_t autopoll_mask;
 706
 707    switch (state) {
 708    case ADB_STATE_NEW:
 709        /*
 710         * Command byte: vADBInt tells host autopoll data already present
 711         * in VIA shift register and ADB transceiver
 712         */
 713        adb_autopoll_block(adb_bus);
 714
 715        if (adb_bus->status & ADB_STATUS_POLLREPLY) {
 716            /* Tell the host the existing data is from autopoll */
 717            ms->b &= ~VIA1B_vADBInt;
 718        } else {
 719            ms->b |= VIA1B_vADBInt;
 720            s->adb_data_out_index = 0;
 721            s->adb_data_out[s->adb_data_out_index++] = data;
 722        }
 723
 724        trace_via1_adb_send(" NEW", data, (ms->b & VIA1B_vADBInt) ? "+" : "-");
 725        qemu_irq_raise(s->adb_data_ready);
 726        break;
 727
 728    case ADB_STATE_EVEN:
 729    case ADB_STATE_ODD:
 730        ms->b |= VIA1B_vADBInt;
 731        s->adb_data_out[s->adb_data_out_index++] = data;
 732
 733        trace_via1_adb_send(state == ADB_STATE_EVEN ? "EVEN" : " ODD",
 734                            data, (ms->b & VIA1B_vADBInt) ? "+" : "-");
 735        qemu_irq_raise(s->adb_data_ready);
 736        break;
 737
 738    case ADB_STATE_IDLE:
 739        return;
 740    }
 741
 742    /* If the command is complete, execute it */
 743    if (s->adb_data_out_index == adb_via_send_len(s->adb_data_out[0])) {
 744        s->adb_data_in_size = adb_request(adb_bus, s->adb_data_in,
 745                                          s->adb_data_out,
 746                                          s->adb_data_out_index);
 747        s->adb_data_in_index = 0;
 748
 749        if (adb_bus->status & ADB_STATUS_BUSTIMEOUT) {
 750            /*
 751             * Bus timeout (but allow first EVEN and ODD byte to indicate
 752             * timeout via vADBInt and SRQ status)
 753             */
 754            s->adb_data_in[0] = 0xff;
 755            s->adb_data_in[1] = 0xff;
 756            s->adb_data_in_size = 2;
 757        }
 758
 759        /*
 760         * If last command is TALK, store it for use by autopoll and adjust
 761         * the autopoll mask accordingly
 762         */
 763        if ((s->adb_data_out[0] & 0xc) == 0xc) {
 764            s->adb_autopoll_cmd = s->adb_data_out[0];
 765
 766            autopoll_mask = 1 << (s->adb_autopoll_cmd >> 4);
 767            adb_set_autopoll_mask(adb_bus, autopoll_mask);
 768        }
 769    }
 770}
 771
 772static void adb_via_receive(MacVIAState *s, int state, uint8_t *data)
 773{
 774    MOS6522Q800VIA1State *v1s = MOS6522_Q800_VIA1(&s->mos6522_via1);
 775    MOS6522State *ms = MOS6522(v1s);
 776    ADBBusState *adb_bus = &s->adb_bus;
 777    uint16_t pending;
 778
 779    switch (state) {
 780    case ADB_STATE_NEW:
 781        ms->b |= VIA1B_vADBInt;
 782        return;
 783
 784    case ADB_STATE_IDLE:
 785        /*
 786         * Since adb_request() will have already consumed the data from the
 787         * device, we must detect this extra state change and re-inject the
 788         * reponse as either a "fake" autopoll reply or bus timeout
 789         * accordingly
 790         */
 791        if (s->adb_data_in_index == 0) {
 792            if (adb_bus->status & ADB_STATUS_BUSTIMEOUT) {
 793                *data = 0xff;
 794                ms->b |= VIA1B_vADBInt;
 795                qemu_irq_raise(s->adb_data_ready);
 796            } else if (s->adb_data_in_size > 0) {
 797                adb_bus->status = ADB_STATUS_POLLREPLY;
 798                *data = s->adb_autopoll_cmd;
 799                ms->b &= ~VIA1B_vADBInt;
 800                qemu_irq_raise(s->adb_data_ready);
 801            }
 802        } else {
 803            ms->b |= VIA1B_vADBInt;
 804            adb_autopoll_unblock(adb_bus);
 805        }
 806
 807        trace_via1_adb_receive("IDLE", *data,
 808                        (ms->b & VIA1B_vADBInt) ? "+" : "-", adb_bus->status,
 809                        s->adb_data_in_index, s->adb_data_in_size);
 810
 811        break;
 812
 813    case ADB_STATE_EVEN:
 814    case ADB_STATE_ODD:
 815        switch (s->adb_data_in_index) {
 816        case 0:
 817            /* First EVEN byte: vADBInt indicates bus timeout */
 818            trace_via1_adb_receive(state == ADB_STATE_EVEN ? "EVEN" : " ODD",
 819                                   *data, (ms->b & VIA1B_vADBInt) ? "+" : "-",
 820                                   adb_bus->status, s->adb_data_in_index,
 821                                   s->adb_data_in_size);
 822
 823            *data = s->adb_data_in[s->adb_data_in_index++];
 824            if (adb_bus->status & ADB_STATUS_BUSTIMEOUT) {
 825                ms->b &= ~VIA1B_vADBInt;
 826            } else {
 827                ms->b |= VIA1B_vADBInt;
 828            }
 829            break;
 830
 831        case 1:
 832            /* First ODD byte: vADBInt indicates SRQ */
 833            trace_via1_adb_receive(state == ADB_STATE_EVEN ? "EVEN" : " ODD",
 834                                   *data, (ms->b & VIA1B_vADBInt) ? "+" : "-",
 835                                   adb_bus->status, s->adb_data_in_index,
 836                                   s->adb_data_in_size);
 837
 838            *data = s->adb_data_in[s->adb_data_in_index++];
 839            pending = adb_bus->pending & ~(1 << (s->adb_autopoll_cmd >> 4));
 840            if (pending) {
 841                ms->b &= ~VIA1B_vADBInt;
 842            } else {
 843                ms->b |= VIA1B_vADBInt;
 844            }
 845            break;
 846
 847        default:
 848            /*
 849             * Otherwise vADBInt indicates end of data. Note that Linux
 850             * specifically checks for the sequence 0x0 0xff to confirm the
 851             * end of the poll reply, so provide these extra bytes below to
 852             * keep it happy
 853             */
 854            trace_via1_adb_receive(state == ADB_STATE_EVEN ? "EVEN" : " ODD",
 855                                   *data, (ms->b & VIA1B_vADBInt) ? "+" : "-",
 856                                   adb_bus->status, s->adb_data_in_index,
 857                                   s->adb_data_in_size);
 858
 859            if (s->adb_data_in_index < s->adb_data_in_size) {
 860                /* Next data byte */
 861                *data = s->adb_data_in[s->adb_data_in_index++];
 862                ms->b |= VIA1B_vADBInt;
 863            } else if (s->adb_data_in_index == s->adb_data_in_size) {
 864                if (adb_bus->status & ADB_STATUS_BUSTIMEOUT) {
 865                    /* Bus timeout (no more data) */
 866                    *data = 0xff;
 867                } else {
 868                    /* Return 0x0 after reply */
 869                    *data = 0;
 870                }
 871                s->adb_data_in_index++;
 872                ms->b &= ~VIA1B_vADBInt;
 873            } else {
 874                /* Bus timeout (no more data) */
 875                *data = 0xff;
 876                ms->b &= ~VIA1B_vADBInt;
 877                adb_bus->status = 0;
 878                adb_autopoll_unblock(adb_bus);
 879            }
 880            break;
 881        }
 882
 883        qemu_irq_raise(s->adb_data_ready);
 884        break;
 885    }
 886}
 887
 888static void via1_adb_update(MacVIAState *m)
 889{
 890    MOS6522Q800VIA1State *v1s = MOS6522_Q800_VIA1(&m->mos6522_via1);
 891    MOS6522State *s = MOS6522(v1s);
 892    int oldstate, state;
 893
 894    oldstate = (v1s->last_b & VIA1B_vADB_StateMask) >> VIA1B_vADB_StateShift;
 895    state = (s->b & VIA1B_vADB_StateMask) >> VIA1B_vADB_StateShift;
 896
 897    if (state != oldstate) {
 898        if (s->acr & VIA1ACR_vShiftOut) {
 899            /* output mode */
 900            adb_via_send(m, state, s->sr);
 901        } else {
 902            /* input mode */
 903            adb_via_receive(m, state, &s->sr);
 904        }
 905    }
 906}
 907
 908static uint64_t mos6522_q800_via1_read(void *opaque, hwaddr addr, unsigned size)
 909{
 910    MOS6522Q800VIA1State *s = MOS6522_Q800_VIA1(opaque);
 911    MOS6522State *ms = MOS6522(s);
 912    int64_t now = qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL);
 913
 914    /*
 915     * If IRQs are disabled, timers are disabled, but we need to update
 916     * VIA1_IRQ_VBLANK and VIA1_IRQ_ONE_SECOND bits in the IFR
 917     */
 918
 919    if (now >= s->next_VBL) {
 920        ms->ifr |= VIA1_IRQ_VBLANK;
 921        via1_VBL_update(s);
 922    }
 923    if (now >= s->next_second) {
 924        ms->ifr |= VIA1_IRQ_ONE_SECOND;
 925        via1_one_second_update(s);
 926    }
 927
 928    addr = (addr >> 9) & 0xf;
 929    return mos6522_read(ms, addr, size);
 930}
 931
 932static void mos6522_q800_via1_write(void *opaque, hwaddr addr, uint64_t val,
 933                                    unsigned size)
 934{
 935    MOS6522Q800VIA1State *v1s = MOS6522_Q800_VIA1(opaque);
 936    MacVIAState *m = container_of(v1s, MacVIAState, mos6522_via1);
 937    MOS6522State *ms = MOS6522(v1s);
 938
 939    addr = (addr >> 9) & 0xf;
 940    mos6522_write(ms, addr, val, size);
 941
 942    switch (addr) {
 943    case VIA_REG_B:
 944        via1_rtc_update(m);
 945        via1_adb_update(m);
 946
 947        v1s->last_b = ms->b;
 948        break;
 949    }
 950
 951    via1_one_second_update(v1s);
 952    via1_VBL_update(v1s);
 953}
 954
 955static const MemoryRegionOps mos6522_q800_via1_ops = {
 956    .read = mos6522_q800_via1_read,
 957    .write = mos6522_q800_via1_write,
 958    .endianness = DEVICE_BIG_ENDIAN,
 959    .valid = {
 960        .min_access_size = 1,
 961        .max_access_size = 1,
 962    },
 963};
 964
 965static uint64_t mos6522_q800_via2_read(void *opaque, hwaddr addr, unsigned size)
 966{
 967    MOS6522Q800VIA2State *s = MOS6522_Q800_VIA2(opaque);
 968    MOS6522State *ms = MOS6522(s);
 969
 970    addr = (addr >> 9) & 0xf;
 971    return mos6522_read(ms, addr, size);
 972}
 973
 974static void mos6522_q800_via2_write(void *opaque, hwaddr addr, uint64_t val,
 975                                    unsigned size)
 976{
 977    MOS6522Q800VIA2State *s = MOS6522_Q800_VIA2(opaque);
 978    MOS6522State *ms = MOS6522(s);
 979
 980    addr = (addr >> 9) & 0xf;
 981    mos6522_write(ms, addr, val, size);
 982}
 983
 984static const MemoryRegionOps mos6522_q800_via2_ops = {
 985    .read = mos6522_q800_via2_read,
 986    .write = mos6522_q800_via2_write,
 987    .endianness = DEVICE_BIG_ENDIAN,
 988    .valid = {
 989        .min_access_size = 1,
 990        .max_access_size = 1,
 991    },
 992};
 993
 994static void mac_via_reset(DeviceState *dev)
 995{
 996    MacVIAState *m = MAC_VIA(dev);
 997    MOS6522Q800VIA1State *v1s = &m->mos6522_via1;
 998    ADBBusState *adb_bus = &m->adb_bus;
 999
1000    adb_set_autopoll_enabled(adb_bus, true);
1001
1002    timer_del(v1s->VBL_timer);
1003    v1s->next_VBL = 0;
1004    timer_del(v1s->one_second_timer);
1005    v1s->next_second = 0;
1006
1007    m->cmd = REG_EMPTY;
1008    m->alt = REG_EMPTY;
1009}
1010
1011static void mac_via_realize(DeviceState *dev, Error **errp)
1012{
1013    MacVIAState *m = MAC_VIA(dev);
1014    MOS6522State *ms;
1015    ADBBusState *adb_bus = &m->adb_bus;
1016    struct tm tm;
1017    int ret;
1018
1019    /* Init VIAs 1 and 2 */
1020    object_initialize_child(OBJECT(dev), "via1", &m->mos6522_via1,
1021                            TYPE_MOS6522_Q800_VIA1);
1022
1023    object_initialize_child(OBJECT(dev), "via2", &m->mos6522_via2,
1024                            TYPE_MOS6522_Q800_VIA2);
1025
1026    /* Pass through mos6522 output IRQs */
1027    ms = MOS6522(&m->mos6522_via1);
1028    object_property_add_alias(OBJECT(dev), "irq[0]", OBJECT(ms),
1029                              SYSBUS_DEVICE_GPIO_IRQ "[0]");
1030    ms = MOS6522(&m->mos6522_via2);
1031    object_property_add_alias(OBJECT(dev), "irq[1]", OBJECT(ms),
1032                              SYSBUS_DEVICE_GPIO_IRQ "[0]");
1033
1034    sysbus_realize(SYS_BUS_DEVICE(&m->mos6522_via1), &error_abort);
1035    sysbus_realize(SYS_BUS_DEVICE(&m->mos6522_via2), &error_abort);
1036
1037    /* Pass through mos6522 input IRQs */
1038    qdev_pass_gpios(DEVICE(&m->mos6522_via1), dev, "via1-irq");
1039    qdev_pass_gpios(DEVICE(&m->mos6522_via2), dev, "via2-irq");
1040
1041    /* VIA 1 */
1042    m->mos6522_via1.one_second_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL,
1043                                                     via1_one_second,
1044                                                     &m->mos6522_via1);
1045    m->mos6522_via1.VBL_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, via1_VBL,
1046                                              &m->mos6522_via1);
1047
1048    qemu_get_timedate(&tm, 0);
1049    m->tick_offset = (uint32_t)mktimegm(&tm) + RTC_OFFSET;
1050
1051    adb_register_autopoll_callback(adb_bus, adb_via_poll, m);
1052    m->adb_data_ready = qdev_get_gpio_in_named(dev, "via1-irq",
1053                                               VIA1_IRQ_ADB_READY_BIT);
1054
1055    if (m->blk) {
1056        int64_t len = blk_getlength(m->blk);
1057        if (len < 0) {
1058            error_setg_errno(errp, -len,
1059                             "could not get length of backing image");
1060            return;
1061        }
1062        ret = blk_set_perm(m->blk,
1063                           BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE,
1064                           BLK_PERM_ALL, errp);
1065        if (ret < 0) {
1066            return;
1067        }
1068
1069        len = blk_pread(m->blk, 0, m->mos6522_via1.PRAM,
1070                        sizeof(m->mos6522_via1.PRAM));
1071        if (len != sizeof(m->mos6522_via1.PRAM)) {
1072            error_setg(errp, "can't read PRAM contents");
1073            return;
1074        }
1075    }
1076}
1077
1078static void mac_via_init(Object *obj)
1079{
1080    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
1081    MacVIAState *m = MAC_VIA(obj);
1082
1083    /* MMIO */
1084    memory_region_init(&m->mmio, obj, "mac-via", 2 * VIA_SIZE);
1085    sysbus_init_mmio(sbd, &m->mmio);
1086
1087    memory_region_init_io(&m->via1mem, obj, &mos6522_q800_via1_ops,
1088                          &m->mos6522_via1, "via1", VIA_SIZE);
1089    memory_region_add_subregion(&m->mmio, 0x0, &m->via1mem);
1090
1091    memory_region_init_io(&m->via2mem, obj, &mos6522_q800_via2_ops,
1092                          &m->mos6522_via2, "via2", VIA_SIZE);
1093    memory_region_add_subregion(&m->mmio, VIA_SIZE, &m->via2mem);
1094
1095    /* ADB */
1096    qbus_create_inplace((BusState *)&m->adb_bus, sizeof(m->adb_bus),
1097                        TYPE_ADB_BUS, DEVICE(obj), "adb.0");
1098}
1099
1100static void postload_update_cb(void *opaque, int running, RunState state)
1101{
1102    MacVIAState *m = MAC_VIA(opaque);
1103
1104    qemu_del_vm_change_state_handler(m->vmstate);
1105    m->vmstate = NULL;
1106
1107    pram_update(m);
1108}
1109
1110static int mac_via_post_load(void *opaque, int version_id)
1111{
1112    MacVIAState *m = MAC_VIA(opaque);
1113
1114    if (m->blk) {
1115        m->vmstate = qemu_add_vm_change_state_handler(postload_update_cb,
1116                                                      m);
1117    }
1118
1119    return 0;
1120}
1121
1122static const VMStateDescription vmstate_mac_via = {
1123    .name = "mac-via",
1124    .version_id = 2,
1125    .minimum_version_id = 2,
1126    .post_load = mac_via_post_load,
1127    .fields = (VMStateField[]) {
1128        /* VIAs */
1129        VMSTATE_STRUCT(mos6522_via1.parent_obj, MacVIAState, 0, vmstate_mos6522,
1130                       MOS6522State),
1131        VMSTATE_UINT8(mos6522_via1.last_b, MacVIAState),
1132        VMSTATE_BUFFER(mos6522_via1.PRAM, MacVIAState),
1133        VMSTATE_TIMER_PTR(mos6522_via1.one_second_timer, MacVIAState),
1134        VMSTATE_INT64(mos6522_via1.next_second, MacVIAState),
1135        VMSTATE_TIMER_PTR(mos6522_via1.VBL_timer, MacVIAState),
1136        VMSTATE_INT64(mos6522_via1.next_VBL, MacVIAState),
1137        VMSTATE_STRUCT(mos6522_via2.parent_obj, MacVIAState, 0, vmstate_mos6522,
1138                       MOS6522State),
1139        /* RTC */
1140        VMSTATE_UINT32(tick_offset, MacVIAState),
1141        VMSTATE_UINT8(data_out, MacVIAState),
1142        VMSTATE_INT32(data_out_cnt, MacVIAState),
1143        VMSTATE_UINT8(data_in, MacVIAState),
1144        VMSTATE_UINT8(data_in_cnt, MacVIAState),
1145        VMSTATE_UINT8(cmd, MacVIAState),
1146        VMSTATE_INT32(wprotect, MacVIAState),
1147        VMSTATE_INT32(alt, MacVIAState),
1148        /* ADB */
1149        VMSTATE_INT32(adb_data_in_size, MacVIAState),
1150        VMSTATE_INT32(adb_data_in_index, MacVIAState),
1151        VMSTATE_INT32(adb_data_out_index, MacVIAState),
1152        VMSTATE_BUFFER(adb_data_in, MacVIAState),
1153        VMSTATE_BUFFER(adb_data_out, MacVIAState),
1154        VMSTATE_UINT8(adb_autopoll_cmd, MacVIAState),
1155        VMSTATE_END_OF_LIST()
1156    }
1157};
1158
1159static Property mac_via_properties[] = {
1160    DEFINE_PROP_DRIVE("drive", MacVIAState, blk),
1161    DEFINE_PROP_END_OF_LIST(),
1162};
1163
1164static void mac_via_class_init(ObjectClass *oc, void *data)
1165{
1166    DeviceClass *dc = DEVICE_CLASS(oc);
1167
1168    dc->realize = mac_via_realize;
1169    dc->reset = mac_via_reset;
1170    dc->vmsd = &vmstate_mac_via;
1171    device_class_set_props(dc, mac_via_properties);
1172}
1173
1174static TypeInfo mac_via_info = {
1175    .name = TYPE_MAC_VIA,
1176    .parent = TYPE_SYS_BUS_DEVICE,
1177    .instance_size = sizeof(MacVIAState),
1178    .instance_init = mac_via_init,
1179    .class_init = mac_via_class_init,
1180};
1181
1182/* VIA 1 */
1183static void mos6522_q800_via1_reset(DeviceState *dev)
1184{
1185    MOS6522State *ms = MOS6522(dev);
1186    MOS6522DeviceClass *mdc = MOS6522_DEVICE_GET_CLASS(ms);
1187
1188    mdc->parent_reset(dev);
1189
1190    ms->timers[0].frequency = VIA_TIMER_FREQ;
1191    ms->timers[1].frequency = VIA_TIMER_FREQ;
1192
1193    ms->b = VIA1B_vADB_StateMask | VIA1B_vADBInt | VIA1B_vRTCEnb;
1194}
1195
1196static void mos6522_q800_via1_init(Object *obj)
1197{
1198    qdev_init_gpio_in_named(DEVICE(obj), via1_irq_request, "via1-irq",
1199                            VIA1_IRQ_NB);
1200}
1201
1202static void mos6522_q800_via1_class_init(ObjectClass *oc, void *data)
1203{
1204    DeviceClass *dc = DEVICE_CLASS(oc);
1205
1206    dc->reset = mos6522_q800_via1_reset;
1207}
1208
1209static const TypeInfo mos6522_q800_via1_type_info = {
1210    .name = TYPE_MOS6522_Q800_VIA1,
1211    .parent = TYPE_MOS6522,
1212    .instance_size = sizeof(MOS6522Q800VIA1State),
1213    .instance_init = mos6522_q800_via1_init,
1214    .class_init = mos6522_q800_via1_class_init,
1215};
1216
1217/* VIA 2 */
1218static void mos6522_q800_via2_portB_write(MOS6522State *s)
1219{
1220    if (s->dirb & VIA2B_vPower && (s->b & VIA2B_vPower) == 0) {
1221        /* shutdown */
1222        qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
1223    }
1224}
1225
1226static void mos6522_q800_via2_reset(DeviceState *dev)
1227{
1228    MOS6522State *ms = MOS6522(dev);
1229    MOS6522DeviceClass *mdc = MOS6522_DEVICE_GET_CLASS(ms);
1230
1231    mdc->parent_reset(dev);
1232
1233    ms->timers[0].frequency = VIA_TIMER_FREQ;
1234    ms->timers[1].frequency = VIA_TIMER_FREQ;
1235
1236    ms->dirb = 0;
1237    ms->b = 0;
1238}
1239
1240static void mos6522_q800_via2_init(Object *obj)
1241{
1242    qdev_init_gpio_in_named(DEVICE(obj), via2_irq_request, "via2-irq",
1243                            VIA2_IRQ_NB);
1244}
1245
1246static void mos6522_q800_via2_class_init(ObjectClass *oc, void *data)
1247{
1248    DeviceClass *dc = DEVICE_CLASS(oc);
1249    MOS6522DeviceClass *mdc = MOS6522_DEVICE_CLASS(oc);
1250
1251    dc->reset = mos6522_q800_via2_reset;
1252    mdc->portB_write = mos6522_q800_via2_portB_write;
1253}
1254
1255static const TypeInfo mos6522_q800_via2_type_info = {
1256    .name = TYPE_MOS6522_Q800_VIA2,
1257    .parent = TYPE_MOS6522,
1258    .instance_size = sizeof(MOS6522Q800VIA2State),
1259    .instance_init = mos6522_q800_via2_init,
1260    .class_init = mos6522_q800_via2_class_init,
1261};
1262
1263static void mac_via_register_types(void)
1264{
1265    type_register_static(&mos6522_q800_via1_type_info);
1266    type_register_static(&mos6522_q800_via2_type_info);
1267    type_register_static(&mac_via_info);
1268}
1269
1270type_init(mac_via_register_types);
1271