/*
 * 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;
    uint32_t int_mask;
    uint32_t int_status;
    uint8_t scsi_csr_1;
    uint8_t scsi_csr_2;

    qemu_irq scsi_reset;
    qemu_irq scsi_dma;

    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);
            qemu_irq_lower(s->scsi_reset);
        }
        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 {
            /* fprintf(stderr,"SCSICSR CPUDMA disabled\n"); */
            s->int_status &= ~(0x4000000);
            /* qemu_irq_lower(s->scsi_dma); */
        }
        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 interrupt 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 nextdma_write(void *opaque, uint8_t *buf, int size, int type)
{
    uint32_t base_addr;
    int irq = 0;
    uint8_t align = 16;
    NeXTState *next_state = NEXT_MACHINE(qdev_get_machine());

    if (type == NEXTDMA_ENRX || type == NEXTDMA_ENTX) {
        align = 32;
    }
    /* Most DMA is supposedly 16 byte aligned */
    if ((size % align) != 0) {
        size -= size % align;
        size += align;
    }

    /*
     * prom sets the dma start using initbuf while the bootloader uses next
     * so we check to see if initbuf is 0
     */
    if (next_state->dma[type].next_initbuf == 0) {
        base_addr = next_state->dma[type].next;
    } else {
        base_addr = next_state->dma[type].next_initbuf;
    }

    cpu_physical_memory_write(base_addr, buf, size);

    next_state->dma[type].next_initbuf = 0;

    /* saved limit is checked to calculate packet size by both, rom and netbsd */
    next_state->dma[type].saved_limit = (next_state->dma[type].next + size);
    next_state->dma[type].saved_next  = (next_state->dma[type].next);

    /*
     * 32 bytes under savedbase seems to be some kind of register
     * of which the purpose is unknown as of yet
     */
    /* stl_phys(s->rx_dma.base-32,0xFFFFFFFF); */

    if (!(next_state->dma[type].csr & DMA_SUPDATE)) {
        next_state->dma[type].next  = next_state->dma[type].start;
        next_state->dma[type].limit = next_state->dma[type].stop;
    }

    /* Set dma registers and raise an irq */
    next_state->dma[type].csr |= DMA_COMPLETE; /* DON'T CHANGE THIS! */

    switch (type) {
    case NEXTDMA_SCSI:
        irq = NEXT_SCSI_DMA_I;
        break;
    }

    next_irq(opaque, irq, 1);
    next_irq(opaque, irq, 0);
}

static void nextscsi_read(void *opaque, uint8_t *buf, int len)
{
    DPRINTF("SCSI READ: %x\n", len);
    abort();
}

static void nextscsi_write(void *opaque, uint8_t *buf, int size)
{
    DPRINTF("SCSI WRITE: %i\n", size);
    nextdma_write(opaque, buf, size, NEXTDMA_SCSI);
}

static void next_scsi_init(DeviceState *pcdev, M68kCPU *cpu)
{
    struct NeXTPC *next_pc = NEXT_PC(pcdev);
    DeviceState *dev;
    SysBusDevice *sysbusdev;
    SysBusESPState *sysbus_esp;
    ESPState *esp;

    dev = qdev_new(TYPE_SYSBUS_ESP);
    sysbus_esp = SYSBUS_ESP(dev);
    esp = &sysbus_esp->esp;
    esp->dma_memory_read = nextscsi_read;
    esp->dma_memory_write = nextscsi_write;
    esp->dma_opaque = pcdev;
    sysbus_esp->it_shift = 0;
    esp->dma_enabled = 1;
    sysbusdev = SYS_BUS_DEVICE(dev);
    sysbus_realize_and_unref(sysbusdev, &error_fatal);
    sysbus_connect_irq(sysbusdev, 0, qdev_get_gpio_in(pcdev, NEXT_SCSI_I));
    sysbus_mmio_map(sysbusdev, 0, 0x2114000);

    next_pc->scsi_reset = qdev_get_gpio_in(dev, 0);
    next_pc->scsi_dma = qdev_get_gpio_in(dev, 1);

    scsi_bus_legacy_handle_cmdline(&esp->bus);
}

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 *rom2 = 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 *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 */
    sysbus_create_simple(TYPE_NEXTFB, 0x0B000000, NULL);

    /* 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 */
    sysbus_create_simple(TYPE_NEXTKBD, 0x0200e000, NULL);

    /* Load ROM here */
    memory_region_init_rom(rom, NULL, "next.rom", 0x20000, &error_fatal);
    memory_region_add_subregion(sysmem, 0x01000000, rom);
    memory_region_init_alias(rom2, NULL, "next.rom2", rom, 0x0, 0x20000);
    memory_region_add_subregion(sysmem, 0x0, rom2);
    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 */
    next_scsi_init(pcdev, cpu);

    /* 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->block_default_type = IF_SCSI;
    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)
