/*
 * NeXT Cube System Driver
 *
 * Copyright (c) 2011 Bryce Lanham
 *
 * This code is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published
 * by the Free Software Foundation; either version 2 of the License,
 * or (at your option) any later version.
 */

#include "qemu/osdep.h"
#include "exec/hwaddr.h"
#include "sysemu/sysemu.h"
#include "sysemu/qtest.h"
#include "hw/irq.h"
#include "hw/m68k/next-cube.h"
#include "hw/boards.h"
#include "hw/loader.h"
#include "hw/scsi/esp.h"
#include "hw/sysbus.h"
#include "qom/object.h"
#include "hw/char/escc.h" /* ZILOG 8530 Serial Emulation */
#include "hw/block/fdc.h"
#include "hw/qdev-properties.h"
#include "qapi/error.h"
#include "qemu/error-report.h"
#include "ui/console.h"
#include "target/m68k/cpu.h"
#include "migration/vmstate.h"

/* #define DEBUG_NEXT */
#ifdef DEBUG_NEXT
#define DPRINTF(fmt, ...) \
    do { printf("NeXT: " fmt , ## __VA_ARGS__); } while (0)
#else
#define DPRINTF(fmt, ...) do { } while (0)
#endif

#define TYPE_NEXT_MACHINE MACHINE_TYPE_NAME("next-cube")
OBJECT_DECLARE_SIMPLE_TYPE(NeXTState, NEXT_MACHINE)

#define ENTRY       0x0100001e
#define RAM_SIZE    0x4000000
#define ROM_FILE    "Rev_2.5_v66.bin"

typedef struct next_dma {
    uint32_t csr;

    uint32_t saved_next;
    uint32_t saved_limit;
    uint32_t saved_start;
    uint32_t saved_stop;

    uint32_t next;
    uint32_t limit;
    uint32_t start;
    uint32_t stop;

    uint32_t next_initbuf;
    uint32_t size;
} next_dma;

typedef struct NextRtc {
    uint8_t ram[32];
    uint8_t command;
    uint8_t value;
    uint8_t status;
    uint8_t control;
    uint8_t retval;
} NextRtc;

struct NeXTState {
    MachineState parent;

    next_dma dma[10];
};

#define TYPE_NEXT_PC "next-pc"
OBJECT_DECLARE_SIMPLE_TYPE(NeXTPC, NEXT_PC)

/* NeXT Peripheral Controller */
struct NeXTPC {
    SysBusDevice parent_obj;

    M68kCPU *cpu;

    MemoryRegion mmiomem;
    MemoryRegion scrmem;

    uint32_t scr1;
    uint32_t scr2;
    uint8_t scsi_csr_1;
    uint8_t scsi_csr_2;
    uint32_t int_mask;
    uint32_t int_status;

    NextRtc rtc;
};

/* Thanks to NeXT forums for this */
/*
static const uint8_t rtc_ram3[32] = {
    0x94, 0x0f, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0xfb, 0x6d, 0x00, 0x00, 0x7B, 0x00,
    0x00, 0x00, 0x65, 0x6e, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x13
};
*/
static const uint8_t rtc_ram2[32] = {
    0x94, 0x0f, 0x40, 0x03, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0xfb, 0x6d, 0x00, 0x00, 0x4b, 0x00,
    0x41, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x7e,
};

#define SCR2_RTCLK 0x2
#define SCR2_RTDATA 0x4
#define SCR2_TOBCD(x) (((x / 10) << 4) + (x % 10))

static void nextscr2_write(NeXTPC *s, uint32_t val, int size)
{
    static int led;
    static int phase;
    static uint8_t old_scr2;
    uint8_t scr2_2;
    NextRtc *rtc = &s->rtc;

    if (size == 4) {
        scr2_2 = (val >> 8) & 0xFF;
    } else {
        scr2_2 = val & 0xFF;
    }

    if (val & 0x1) {
        DPRINTF("fault!\n");
        led++;
        if (led == 10) {
            DPRINTF("LED flashing, possible fault!\n");
            led = 0;
        }
    }

    if (scr2_2 & 0x1) {
        /* DPRINTF("RTC %x phase %i\n", scr2_2, phase); */
        if (phase == -1) {
            phase = 0;
        }
        /* If we are in going down clock... do something */
        if (((old_scr2 & SCR2_RTCLK) != (scr2_2 & SCR2_RTCLK)) &&
                ((scr2_2 & SCR2_RTCLK) == 0)) {
            if (phase < 8) {
                rtc->command = (rtc->command << 1) |
                               ((scr2_2 & SCR2_RTDATA) ? 1 : 0);
            }
            if (phase >= 8 && phase < 16) {
                rtc->value = (rtc->value << 1) |
                             ((scr2_2 & SCR2_RTDATA) ? 1 : 0);

                /* if we read RAM register, output RT_DATA bit */
                if (rtc->command <= 0x1F) {
                    scr2_2 = scr2_2 & (~SCR2_RTDATA);
                    if (rtc->ram[rtc->command] & (0x80 >> (phase - 8))) {
                        scr2_2 |= SCR2_RTDATA;
                    }

                    rtc->retval = (rtc->retval << 1) |
                                  ((scr2_2 & SCR2_RTDATA) ? 1 : 0);
                }
                /* read the status 0x30 */
                if (rtc->command == 0x30) {
                    scr2_2 = scr2_2 & (~SCR2_RTDATA);
                    /* for now status = 0x98 (new rtc + FTU) */
                    if (rtc->status & (0x80 >> (phase - 8))) {
                        scr2_2 |= SCR2_RTDATA;
                    }

                    rtc->retval = (rtc->retval << 1) |
                                  ((scr2_2 & SCR2_RTDATA) ? 1 : 0);
                }
                /* read the status 0x31 */
                if (rtc->command == 0x31) {
                    scr2_2 = scr2_2 & (~SCR2_RTDATA);
                    if (rtc->control & (0x80 >> (phase - 8))) {
                        scr2_2 |= SCR2_RTDATA;
                    }
                    rtc->retval = (rtc->retval << 1) |
                                  ((scr2_2 & SCR2_RTDATA) ? 1 : 0);
                }

                if ((rtc->command >= 0x20) && (rtc->command <= 0x2F)) {
                    scr2_2 = scr2_2 & (~SCR2_RTDATA);
                    /* for now 0x00 */
                    time_t time_h = time(NULL);
                    struct tm *info = localtime(&time_h);
                    int ret = 0;

                    switch (rtc->command) {
                    case 0x20:
                        ret = SCR2_TOBCD(info->tm_sec);
                        break;
                    case 0x21:
                        ret = SCR2_TOBCD(info->tm_min);
                        break;
                    case 0x22:
                        ret = SCR2_TOBCD(info->tm_hour);
                        break;
                    case 0x24:
                        ret = SCR2_TOBCD(info->tm_mday);
                        break;
                    case 0x25:
                        ret = SCR2_TOBCD((info->tm_mon + 1));
                        break;
                    case 0x26:
                        ret = SCR2_TOBCD((info->tm_year - 100));
                        break;

                    }

                    if (ret & (0x80 >> (phase - 8))) {
                        scr2_2 |= SCR2_RTDATA;
                    }
                    rtc->retval = (rtc->retval << 1) |
                                  ((scr2_2 & SCR2_RTDATA) ? 1 : 0);
                }

            }

            phase++;
            if (phase == 16) {
                if (rtc->command >= 0x80 && rtc->command <= 0x9F) {
                    rtc->ram[rtc->command - 0x80] = rtc->value;
                }
                /* write to x30 register */
                if (rtc->command == 0xB1) {
                    /* clear FTU */
                    if (rtc->value & 0x04) {
                        rtc->status = rtc->status & (~0x18);
                        s->int_status = s->int_status & (~0x04);
                    }
                }
            }
        }
    } else {
        /* else end or abort */
        phase = -1;
        rtc->command = 0;
        rtc->value = 0;
    }
    s->scr2 = val & 0xFFFF00FF;
    s->scr2 |= scr2_2 << 8;
    old_scr2 = scr2_2;
}

static uint32_t mmio_readb(NeXTPC *s, hwaddr addr)
{
    switch (addr) {
    case 0xc000:
        return (s->scr1 >> 24) & 0xFF;
    case 0xc001:
        return (s->scr1 >> 16) & 0xFF;
    case 0xc002:
        return (s->scr1 >> 8)  & 0xFF;
    case 0xc003:
        return (s->scr1 >> 0)  & 0xFF;

    case 0xd000:
        return (s->scr2 >> 24) & 0xFF;
    case 0xd001:
        return (s->scr2 >> 16) & 0xFF;
    case 0xd002:
        return (s->scr2 >> 8)  & 0xFF;
    case 0xd003:
        return (s->scr2 >> 0)  & 0xFF;
    case 0x14020:
        DPRINTF("MMIO Read 0x4020\n");
        return 0x7f;

    default:
        DPRINTF("MMIO Read B @ %"HWADDR_PRIx"\n", addr);
        return 0x0;
    }
}

static uint32_t mmio_readw(NeXTPC *s, hwaddr addr)
{
    switch (addr) {
    default:
        DPRINTF("MMIO Read W @ %"HWADDR_PRIx"\n", addr);
        return 0x0;
    }
}

static uint32_t mmio_readl(NeXTPC *s, hwaddr addr)
{
    switch (addr) {
    case 0x7000:
        /* DPRINTF("Read INT status: %x\n", s->int_status); */
        return s->int_status;

    case 0x7800:
        DPRINTF("MMIO Read INT mask: %x\n", s->int_mask);
        return s->int_mask;

    case 0xc000:
        return s->scr1;

    case 0xd000:
        return s->scr2;

    default:
        DPRINTF("MMIO Read L @ %"HWADDR_PRIx"\n", addr);
        return 0x0;
    }
}

static void mmio_writeb(NeXTPC *s, hwaddr addr, uint32_t val)
{
    switch (addr) {
    case 0xd003:
        nextscr2_write(s, val, 1);
        break;
    default:
        DPRINTF("MMIO Write B @ %x with %x\n", (unsigned int)addr, val);
    }

}

static void mmio_writew(NeXTPC *s, hwaddr addr, uint32_t val)
{
    DPRINTF("MMIO Write W\n");
}

static void mmio_writel(NeXTPC *s, hwaddr addr, uint32_t val)
{
    switch (addr) {
    case 0x7000:
        DPRINTF("INT Status old: %x new: %x\n", s->int_status, val);
        s->int_status = val;
        break;
    case 0x7800:
        DPRINTF("INT Mask old: %x new: %x\n", s->int_mask, val);
        s->int_mask  = val;
        break;
    case 0xc000:
        DPRINTF("SCR1 Write: %x\n", val);
        break;
    case 0xd000:
        nextscr2_write(s, val, 4);
        break;

    default:
        DPRINTF("MMIO Write l @ %x with %x\n", (unsigned int)addr, val);
    }
}

static uint64_t mmio_readfn(void *opaque, hwaddr addr, unsigned size)
{
    NeXTPC *s = NEXT_PC(opaque);

    switch (size) {
    case 1:
        return mmio_readb(s, addr);
    case 2:
        return mmio_readw(s, addr);
    case 4:
        return mmio_readl(s, addr);
    default:
        g_assert_not_reached();
    }
}

static void mmio_writefn(void *opaque, hwaddr addr, uint64_t value,
                         unsigned size)
{
    NeXTPC *s = NEXT_PC(opaque);

    switch (size) {
    case 1:
        mmio_writeb(s, addr, value);
        break;
    case 2:
        mmio_writew(s, addr, value);
        break;
    case 4:
        mmio_writel(s, addr, value);
        break;
    default:
        g_assert_not_reached();
    }
}

static const MemoryRegionOps mmio_ops = {
    .read = mmio_readfn,
    .write = mmio_writefn,
    .valid.min_access_size = 1,
    .valid.max_access_size = 4,
    .endianness = DEVICE_NATIVE_ENDIAN,
};

static uint32_t scr_readb(NeXTPC *s, hwaddr addr)
{
    switch (addr) {
    case 0x14108:
        DPRINTF("FD read @ %x\n", (unsigned int)addr);
        return 0x40 | 0x04 | 0x2 | 0x1;
    case 0x14020:
        DPRINTF("SCSI 4020  STATUS READ %X\n", s->scsi_csr_1);
        return s->scsi_csr_1;

    case 0x14021:
        DPRINTF("SCSI 4021 STATUS READ %X\n", s->scsi_csr_2);
        return 0x40;

    /*
     * These 4 registers are the hardware timer, not sure which register
     * is the latch instead of data, but no problems so far
     */
    case 0x1a000:
        return 0xff & (clock() >> 24);
    case 0x1a001:
        return 0xff & (clock() >> 16);
    case 0x1a002:
        return 0xff & (clock() >> 8);
    case 0x1a003:
        /* Hack: We need to have this change consistently to make it work */
        return 0xFF & clock();

    default:
        DPRINTF("BMAP Read B @ %x\n", (unsigned int)addr);
        return 0;
    }
}

static uint32_t scr_readw(NeXTPC *s, hwaddr addr)
{
    DPRINTF("BMAP Read W @ %x\n", (unsigned int)addr);
    return 0;
}

static uint32_t scr_readl(NeXTPC *s, hwaddr addr)
{
    DPRINTF("BMAP Read L @ %x\n", (unsigned int)addr);
    return 0;
}

#define SCSICSR_ENABLE  0x01
#define SCSICSR_RESET   0x02  /* reset scsi dma */
#define SCSICSR_FIFOFL  0x04
#define SCSICSR_DMADIR  0x08  /* if set, scsi to mem */
#define SCSICSR_CPUDMA  0x10  /* if set, dma enabled */
#define SCSICSR_INTMASK 0x20  /* if set, interrupt enabled */

static void scr_writeb(NeXTPC *s, hwaddr addr, uint32_t value)
{
    switch (addr) {
    case 0x14108:
        DPRINTF("FDCSR Write: %x\n", value);

        if (value == 0x0) {
            /* qemu_irq_raise(s->fd_irq[0]); */
        }
        break;
    case 0x14020: /* SCSI Control Register */
        if (value & SCSICSR_FIFOFL) {
            DPRINTF("SCSICSR FIFO Flush\n");
            /* will have to add another irq to the esp if this is needed */
            /* esp_puflush_fifo(esp_g); */
            /* qemu_irq_pulse(s->scsi_dma); */
        }

        if (value & SCSICSR_ENABLE) {
            DPRINTF("SCSICSR Enable\n");
            /*
             * qemu_irq_raise(s->scsi_dma);
             * s->scsi_csr_1 = 0xc0;
             * s->scsi_csr_1 |= 0x1;
             * qemu_irq_pulse(s->scsi_dma);
             */
        }
        /*
         * else
         *     s->scsi_csr_1 &= ~SCSICSR_ENABLE;
         */

        if (value & SCSICSR_RESET) {
            DPRINTF("SCSICSR Reset\n");
            /* I think this should set DMADIR. CPUDMA and INTMASK to 0 */
            /* qemu_irq_raise(s->scsi_reset); */
            /* s->scsi_csr_1 &= ~(SCSICSR_INTMASK |0x80|0x1); */

        }
        if (value & SCSICSR_DMADIR) {
            DPRINTF("SCSICSR DMAdir\n");
        }
        if (value & SCSICSR_CPUDMA) {
            DPRINTF("SCSICSR CPUDMA\n");
            /* qemu_irq_raise(s->scsi_dma); */

            s->int_status |= 0x4000000;
        } else {
            s->int_status &= ~(0x4000000);
        }
        if (value & SCSICSR_INTMASK) {
            DPRINTF("SCSICSR INTMASK\n");
            /*
             * int_mask &= ~0x1000;
             * s->scsi_csr_1 |= value;
             * s->scsi_csr_1 &= ~SCSICSR_INTMASK;
             * if (s->scsi_queued) {
             *     s->scsi_queued = 0;
             *     next_irq(s, NEXT_SCSI_I, level);
             * }
             */
        } else {
            /* int_mask |= 0x1000; */
        }
        if (value & 0x80) {
            /* int_mask |= 0x1000; */
            /* s->scsi_csr_1 |= 0x80; */
        }
        DPRINTF("SCSICSR Write: %x\n", value);
        /* s->scsi_csr_1 = value; */
        return;
    /* Hardware timer latch - not implemented yet */
    case 0x1a000:
    default:
        DPRINTF("BMAP Write B @ %x with %x\n", (unsigned int)addr, value);
    }
}

static void scr_writew(NeXTPC *s, hwaddr addr, uint32_t value)
{
    DPRINTF("BMAP Write W @ %x with %x\n", (unsigned int)addr, value);
}

static void scr_writel(NeXTPC *s, hwaddr addr, uint32_t value)
{
    DPRINTF("BMAP Write L @ %x with %x\n", (unsigned int)addr, value);
}

static uint64_t scr_readfn(void *opaque, hwaddr addr, unsigned size)
{
    NeXTPC *s = NEXT_PC(opaque);

    switch (size) {
    case 1:
        return scr_readb(s, addr);
    case 2:
        return scr_readw(s, addr);
    case 4:
        return scr_readl(s, addr);
    default:
        g_assert_not_reached();
    }
}

static void scr_writefn(void *opaque, hwaddr addr, uint64_t value,
                        unsigned size)
{
    NeXTPC *s = NEXT_PC(opaque);

    switch (size) {
    case 1:
        scr_writeb(s, addr, value);
        break;
    case 2:
        scr_writew(s, addr, value);
        break;
    case 4:
        scr_writel(s, addr, value);
        break;
    default:
        g_assert_not_reached();
    }
}

static const MemoryRegionOps scr_ops = {
    .read = scr_readfn,
    .write = scr_writefn,
    .valid.min_access_size = 1,
    .valid.max_access_size = 4,
    .endianness = DEVICE_NATIVE_ENDIAN,
};

#define NEXTDMA_SCSI(x)      (0x10 + x)
#define NEXTDMA_FD(x)        (0x10 + x)
#define NEXTDMA_ENTX(x)      (0x110 + x)
#define NEXTDMA_ENRX(x)      (0x150 + x)
#define NEXTDMA_CSR          0x0
#define NEXTDMA_NEXT         0x4000
#define NEXTDMA_LIMIT        0x4004
#define NEXTDMA_START        0x4008
#define NEXTDMA_STOP         0x400c
#define NEXTDMA_NEXT_INIT    0x4200
#define NEXTDMA_SIZE         0x4204

static void dma_writel(void *opaque, hwaddr addr, uint64_t value,
                       unsigned int size)
{
    NeXTState *next_state = NEXT_MACHINE(opaque);

    switch (addr) {
    case NEXTDMA_ENRX(NEXTDMA_CSR):
        if (value & DMA_DEV2M) {
            next_state->dma[NEXTDMA_ENRX].csr |= DMA_DEV2M;
        }

        if (value & DMA_SETENABLE) {
            /* DPRINTF("SCSI DMA ENABLE\n"); */
            next_state->dma[NEXTDMA_ENRX].csr |= DMA_ENABLE;
        }
        if (value & DMA_SETSUPDATE) {
            next_state->dma[NEXTDMA_ENRX].csr |= DMA_SUPDATE;
        }
        if (value & DMA_CLRCOMPLETE) {
            next_state->dma[NEXTDMA_ENRX].csr &= ~DMA_COMPLETE;
        }

        if (value & DMA_RESET) {
            next_state->dma[NEXTDMA_ENRX].csr &= ~(DMA_COMPLETE | DMA_SUPDATE |
                                                  DMA_ENABLE | DMA_DEV2M);
        }
        /* DPRINTF("RXCSR \tWrite: %x\n",value); */
        break;
    case NEXTDMA_ENRX(NEXTDMA_NEXT_INIT):
        next_state->dma[NEXTDMA_ENRX].next_initbuf = value;
        break;
    case NEXTDMA_ENRX(NEXTDMA_NEXT):
        next_state->dma[NEXTDMA_ENRX].next = value;
        break;
    case NEXTDMA_ENRX(NEXTDMA_LIMIT):
        next_state->dma[NEXTDMA_ENRX].limit = value;
        break;
    case NEXTDMA_SCSI(NEXTDMA_CSR):
        if (value & DMA_DEV2M) {
            next_state->dma[NEXTDMA_SCSI].csr |= DMA_DEV2M;
        }
        if (value & DMA_SETENABLE) {
            /* DPRINTF("SCSI DMA ENABLE\n"); */
            next_state->dma[NEXTDMA_SCSI].csr |= DMA_ENABLE;
        }
        if (value & DMA_SETSUPDATE) {
            next_state->dma[NEXTDMA_SCSI].csr |= DMA_SUPDATE;
        }
        if (value & DMA_CLRCOMPLETE) {
            next_state->dma[NEXTDMA_SCSI].csr &= ~DMA_COMPLETE;
        }

        if (value & DMA_RESET) {
            next_state->dma[NEXTDMA_SCSI].csr &= ~(DMA_COMPLETE | DMA_SUPDATE |
                                                  DMA_ENABLE | DMA_DEV2M);
            /* DPRINTF("SCSI DMA RESET\n"); */
        }
        /* DPRINTF("RXCSR \tWrite: %x\n",value); */
        break;

    case NEXTDMA_SCSI(NEXTDMA_NEXT):
        next_state->dma[NEXTDMA_SCSI].next = value;
        break;

    case NEXTDMA_SCSI(NEXTDMA_LIMIT):
        next_state->dma[NEXTDMA_SCSI].limit = value;
        break;

    case NEXTDMA_SCSI(NEXTDMA_START):
        next_state->dma[NEXTDMA_SCSI].start = value;
        break;

    case NEXTDMA_SCSI(NEXTDMA_STOP):
        next_state->dma[NEXTDMA_SCSI].stop = value;
        break;

    case NEXTDMA_SCSI(NEXTDMA_NEXT_INIT):
        next_state->dma[NEXTDMA_SCSI].next_initbuf = value;
        break;

    default:
        DPRINTF("DMA write @ %x w/ %x\n", (unsigned)addr, (unsigned)value);
    }
}

static uint64_t dma_readl(void *opaque, hwaddr addr, unsigned int size)
{
    NeXTState *next_state = NEXT_MACHINE(opaque);

    switch (addr) {
    case NEXTDMA_SCSI(NEXTDMA_CSR):
        DPRINTF("SCSI DMA CSR READ\n");
        return next_state->dma[NEXTDMA_SCSI].csr;
    case NEXTDMA_ENRX(NEXTDMA_CSR):
        return next_state->dma[NEXTDMA_ENRX].csr;
    case NEXTDMA_ENRX(NEXTDMA_NEXT_INIT):
        return next_state->dma[NEXTDMA_ENRX].next_initbuf;
    case NEXTDMA_ENRX(NEXTDMA_NEXT):
        return next_state->dma[NEXTDMA_ENRX].next;
    case NEXTDMA_ENRX(NEXTDMA_LIMIT):
        return next_state->dma[NEXTDMA_ENRX].limit;

    case NEXTDMA_SCSI(NEXTDMA_NEXT):
        return next_state->dma[NEXTDMA_SCSI].next;
    case NEXTDMA_SCSI(NEXTDMA_NEXT_INIT):
        return next_state->dma[NEXTDMA_SCSI].next_initbuf;
    case NEXTDMA_SCSI(NEXTDMA_LIMIT):
        return next_state->dma[NEXTDMA_SCSI].limit;
    case NEXTDMA_SCSI(NEXTDMA_START):
        return next_state->dma[NEXTDMA_SCSI].start;
    case NEXTDMA_SCSI(NEXTDMA_STOP):
        return next_state->dma[NEXTDMA_SCSI].stop;

    default:
        DPRINTF("DMA read @ %x\n", (unsigned int)addr);
        return 0;
    }

    /*
     * once the csr's are done, subtract 0x3FEC from the addr, and that will
     * normalize the upper registers
     */
}

static const MemoryRegionOps dma_ops = {
    .read = dma_readl,
    .write = dma_writel,
    .impl.min_access_size = 4,
    .valid.min_access_size = 4,
    .valid.max_access_size = 4,
    .endianness = DEVICE_NATIVE_ENDIAN,
};

static void next_irq(void *opaque, int number, int level)
{
    NeXTPC *s = NEXT_PC(opaque);
    M68kCPU *cpu = s->cpu;
    int shift = 0;

    /* first switch sets interupt status */
    /* DPRINTF("IRQ %i\n",number); */
    switch (number) {
    /* level 3 - floppy, kbd/mouse, power, ether rx/tx, scsi, clock */
    case NEXT_FD_I:
        shift = 7;
        break;
    case NEXT_KBD_I:
        shift = 3;
        break;
    case NEXT_PWR_I:
        shift = 2;
        break;
    case NEXT_ENRX_I:
        shift = 9;
        break;
    case NEXT_ENTX_I:
        shift = 10;
        break;
    case NEXT_SCSI_I:
        shift = 12;
        break;
    case NEXT_CLK_I:
        shift = 5;
        break;

    /* level 5 - scc (serial) */
    case NEXT_SCC_I:
        shift = 17;
        break;

    /* level 6 - audio etherrx/tx dma */
    case NEXT_ENTX_DMA_I:
        shift = 28;
        break;
    case NEXT_ENRX_DMA_I:
        shift = 27;
        break;
    case NEXT_SCSI_DMA_I:
        shift = 26;
        break;
    case NEXT_SND_I:
        shift = 23;
        break;
    case NEXT_SCC_DMA_I:
        shift = 21;
        break;

    }
    /*
     * this HAS to be wrong, the interrupt handlers in mach and together
     * int_status and int_mask and return if there is a hit
     */
    if (s->int_mask & (1 << shift)) {
        DPRINTF("%x interrupt masked @ %x\n", 1 << shift, cpu->env.pc);
        /* return; */
    }

    /* second switch triggers the correct interrupt */
    if (level) {
        s->int_status |= 1 << shift;

        switch (number) {
        /* level 3 - floppy, kbd/mouse, power, ether rx/tx, scsi, clock */
        case NEXT_FD_I:
        case NEXT_KBD_I:
        case NEXT_PWR_I:
        case NEXT_ENRX_I:
        case NEXT_ENTX_I:
        case NEXT_SCSI_I:
        case NEXT_CLK_I:
            m68k_set_irq_level(cpu, 3, 27);
            break;

        /* level 5 - scc (serial) */
        case NEXT_SCC_I:
            m68k_set_irq_level(cpu, 5, 29);
            break;

        /* level 6 - audio etherrx/tx dma */
        case NEXT_ENTX_DMA_I:
        case NEXT_ENRX_DMA_I:
        case NEXT_SCSI_DMA_I:
        case NEXT_SND_I:
        case NEXT_SCC_DMA_I:
            m68k_set_irq_level(cpu, 6, 30);
            break;
        }
    } else {
        s->int_status &= ~(1 << shift);
        cpu_reset_interrupt(CPU(cpu), CPU_INTERRUPT_HARD);
    }
}

static void next_escc_init(DeviceState *pcdev)
{
    DeviceState *dev;
    SysBusDevice *s;

    dev = qdev_new(TYPE_ESCC);
    qdev_prop_set_uint32(dev, "disabled", 0);
    qdev_prop_set_uint32(dev, "frequency", 9600 * 384);
    qdev_prop_set_uint32(dev, "it_shift", 0);
    qdev_prop_set_bit(dev, "bit_swap", true);
    qdev_prop_set_chr(dev, "chrB", serial_hd(1));
    qdev_prop_set_chr(dev, "chrA", serial_hd(0));
    qdev_prop_set_uint32(dev, "chnBtype", escc_serial);
    qdev_prop_set_uint32(dev, "chnAtype", escc_serial);

    s = SYS_BUS_DEVICE(dev);
    sysbus_realize_and_unref(s, &error_fatal);
    sysbus_connect_irq(s, 0, qdev_get_gpio_in(pcdev, NEXT_SCC_I));
    sysbus_connect_irq(s, 1, qdev_get_gpio_in(pcdev, NEXT_SCC_DMA_I));
    sysbus_mmio_map(s, 0, 0x2118000);
}

static void next_pc_reset(DeviceState *dev)
{
    NeXTPC *s = NEXT_PC(dev);

    /* Set internal registers to initial values */
    /*     0x0000XX00 << vital bits */
    s->scr1 = 0x00011102;
    s->scr2 = 0x00ff0c80;

    s->rtc.status = 0x90;

    /* Load RTC RAM - TODO: provide possibility to load contents from file */
    memcpy(s->rtc.ram, rtc_ram2, 32);
}

static void next_pc_realize(DeviceState *dev, Error **errp)
{
    NeXTPC *s = NEXT_PC(dev);
    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);

    qdev_init_gpio_in(dev, next_irq, NEXT_NUM_IRQS);

    memory_region_init_io(&s->mmiomem, OBJECT(s), &mmio_ops, s,
                          "next.mmio", 0xD0000);
    memory_region_init_io(&s->scrmem, OBJECT(s), &scr_ops, s,
                          "next.scr", 0x20000);
    sysbus_init_mmio(sbd, &s->mmiomem);
    sysbus_init_mmio(sbd, &s->scrmem);
}

/*
 * If the m68k CPU implemented its inbound irq lines as GPIO lines
 * rather than via the m68k_set_irq_level() function we would not need
 * this cpu link property and could instead provide outbound IRQ lines
 * that the board could wire up to the CPU.
 */
static Property next_pc_properties[] = {
    DEFINE_PROP_LINK("cpu", NeXTPC, cpu, TYPE_M68K_CPU, M68kCPU *),
    DEFINE_PROP_END_OF_LIST(),
};

static const VMStateDescription next_rtc_vmstate = {
    .name = "next-rtc",
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_UINT8_ARRAY(ram, NextRtc, 32),
        VMSTATE_UINT8(command, NextRtc),
        VMSTATE_UINT8(value, NextRtc),
        VMSTATE_UINT8(status, NextRtc),
        VMSTATE_UINT8(control, NextRtc),
        VMSTATE_UINT8(retval, NextRtc),
        VMSTATE_END_OF_LIST()
    },
};

static const VMStateDescription next_pc_vmstate = {
    .name = "next-pc",
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_UINT32(scr1, NeXTPC),
        VMSTATE_UINT32(scr2, NeXTPC),
        VMSTATE_UINT32(int_mask, NeXTPC),
        VMSTATE_UINT32(int_status, NeXTPC),
        VMSTATE_UINT8(scsi_csr_1, NeXTPC),
        VMSTATE_UINT8(scsi_csr_2, NeXTPC),
        VMSTATE_STRUCT(rtc, NeXTPC, 0, next_rtc_vmstate, NextRtc),
        VMSTATE_END_OF_LIST()
    },
};

static void next_pc_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);

    dc->desc = "NeXT Peripheral Controller";
    dc->realize = next_pc_realize;
    dc->reset = next_pc_reset;
    device_class_set_props(dc, next_pc_properties);
    dc->vmsd = &next_pc_vmstate;
}

static const TypeInfo next_pc_info = {
    .name = TYPE_NEXT_PC,
    .parent = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(NeXTPC),
    .class_init = next_pc_class_init,
};

static void next_cube_init(MachineState *machine)
{
    M68kCPU *cpu;
    CPUM68KState *env;
    MemoryRegion *rom = g_new(MemoryRegion, 1);
    MemoryRegion *dmamem = g_new(MemoryRegion, 1);
    MemoryRegion *bmapm1 = g_new(MemoryRegion, 1);
    MemoryRegion *bmapm2 = g_new(MemoryRegion, 1);
    MemoryRegion *sysmem = get_system_memory();
    const char *bios_name = machine->firmware ?: ROM_FILE;
    DeviceState *dev;
    DeviceState *pcdev;

    /* Initialize the cpu core */
    cpu = M68K_CPU(cpu_create(machine->cpu_type));
    if (!cpu) {
        error_report("Unable to find m68k CPU definition");
        exit(1);
    }
    env = &cpu->env;

    /* Initialize CPU registers.  */
    env->vbr = 0;
    env->sr  = 0x2700;

    /* Peripheral Controller */
    pcdev = qdev_new(TYPE_NEXT_PC);
    object_property_set_link(OBJECT(pcdev), "cpu", OBJECT(cpu), &error_abort);
    sysbus_realize_and_unref(SYS_BUS_DEVICE(pcdev), &error_fatal);

    /* 64MB RAM starting at 0x04000000  */
    memory_region_add_subregion(sysmem, 0x04000000, machine->ram);

    /* Framebuffer */
    dev = qdev_new(TYPE_NEXTFB);
    sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
    sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, 0x0B000000);

    /* MMIO */
    sysbus_mmio_map(SYS_BUS_DEVICE(pcdev), 0, 0x02000000);

    /* BMAP IO - acts as a catch-all for now */
    sysbus_mmio_map(SYS_BUS_DEVICE(pcdev), 1, 0x02100000);

    /* BMAP memory */
    memory_region_init_ram_flags_nomigrate(bmapm1, NULL, "next.bmapmem", 64,
                                           RAM_SHARED, &error_fatal);
    memory_region_add_subregion(sysmem, 0x020c0000, bmapm1);
    /* The Rev_2.5_v66.bin firmware accesses it at 0x820c0020, too */
    memory_region_init_alias(bmapm2, NULL, "next.bmapmem2", bmapm1, 0x0, 64);
    memory_region_add_subregion(sysmem, 0x820c0000, bmapm2);

    /* KBD */
    dev = qdev_new(TYPE_NEXTKBD);
    sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
    sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, 0x0200e000);

    /* Load ROM here */
    /* still not sure if the rom should also be mapped at 0x0*/
    memory_region_init_rom(rom, NULL, "next.rom", 0x20000, &error_fatal);
    memory_region_add_subregion(sysmem, 0x01000000, rom);
    if (load_image_targphys(bios_name, 0x01000000, 0x20000) < 8) {
        if (!qtest_enabled()) {
            error_report("Failed to load firmware '%s'.", bios_name);
        }
    } else {
        uint8_t *ptr;
        /* Initial PC is always at offset 4 in firmware binaries */
        ptr = rom_ptr(0x01000004, 4);
        g_assert(ptr != NULL);
        env->pc = ldl_p(ptr);
        if (env->pc >= 0x01020000) {
            error_report("'%s' does not seem to be a valid firmware image.",
                         bios_name);
            exit(1);
        }
    }

    /* Serial */
    next_escc_init(pcdev);

    /* TODO: */
    /* Network */
    /* SCSI */

    /* DMA */
    memory_region_init_io(dmamem, NULL, &dma_ops, machine, "next.dma", 0x5000);
    memory_region_add_subregion(sysmem, 0x02000000, dmamem);
}

static void next_machine_class_init(ObjectClass *oc, void *data)
{
    MachineClass *mc = MACHINE_CLASS(oc);

    mc->desc = "NeXT Cube";
    mc->init = next_cube_init;
    mc->default_ram_size = RAM_SIZE;
    mc->default_ram_id = "next.ram";
    mc->default_cpu_type = M68K_CPU_TYPE_NAME("m68040");
}

static const TypeInfo next_typeinfo = {
    .name = TYPE_NEXT_MACHINE,
    .parent = TYPE_MACHINE,
    .class_init = next_machine_class_init,
    .instance_size = sizeof(NeXTState),
};

static void next_register_type(void)
{
    type_register_static(&next_typeinfo);
    type_register_static(&next_pc_info);
}

type_init(next_register_type)
