--- trunk/src/devices/dev_bebox.c 2007/10/08 16:19:11 18 +++ trunk/src/devices/dev_bebox.c 2007/10/08 16:19:37 22 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005 Anders Gavare. All rights reserved. + * Copyright (C) 2005-2006 Anders Gavare. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -25,7 +25,7 @@ * SUCH DAMAGE. * * - * $Id: dev_bebox.c,v 1.4 2005/10/26 14:37:03 debug Exp $ + * $Id: dev_bebox.c,v 1.9 2006/02/09 20:02:59 debug Exp $ * * Emulation of BeBox motherboard registers. See the following URL for more * information: @@ -39,27 +39,33 @@ #include "cpu.h" #include "device.h" +#include "devices.h" #include "machine.h" #include "memory.h" #include "misc.h" -struct bebox_data { - /* The 5 motherboard registers: */ - uint32_t cpu0_intmask; - uint32_t cpu1_intmask; - uint32_t int_source; - uint32_t xpi; - uint32_t resets; -}; +/* + * check_cpu_masks(): + * + * BeBox interrupt enable bits are not allowed to be present in + * both CPUs at the same time. + */ +static void check_cpu_masks(struct cpu *cpu, struct bebox_data *d) +{ + d->cpu0_int_mask &= 0x7fffffff; + d->cpu1_int_mask &= 0x7fffffff; + if ((d->cpu0_int_mask | d->cpu1_int_mask) != + (d->cpu0_int_mask ^ d->cpu1_int_mask)) + fatal("check_cpu_masks(): BeBox cpu int masks" + " collide!\n"); +} /* * dev_bebox_access(): */ -int dev_bebox_access(struct cpu *cpu, struct memory *mem, - uint64_t relative_addr, unsigned char *data, size_t len, int writeflag, - void *extra) +DEVICE_ACCESS(bebox) { struct bebox_data *d = extra; uint64_t idata = 0, odata = 0; @@ -68,6 +74,43 @@ idata = memory_readmax64(cpu, data, len); switch (relative_addr) { + + case 0x0f0: + if (writeflag == MEM_READ) + odata = d->cpu0_int_mask; + else { + if (idata & 0x80000000) + d->cpu0_int_mask |= idata; + else + d->cpu0_int_mask &= ~idata; + check_cpu_masks(cpu, d); + } + break; + + case 0x1f0: + if (writeflag == MEM_READ) + odata = d->cpu1_int_mask; + else { + if (idata & 0x80000000) + d->cpu1_int_mask |= idata; + else + d->cpu1_int_mask &= ~idata; + check_cpu_masks(cpu, d); + } + break; + + case 0x2f0: + if (writeflag == MEM_READ) + odata = d->int_status; + else { + if (idata & 0x80000000) + d->int_status |= idata; + else + d->int_status &= ~idata; + d->int_status &= 0x7fffffff; + } + break; + case 0x3f0: if (writeflag == MEM_READ) { odata = d->xpi; @@ -98,10 +141,7 @@ } -/* - * devinit_bebox(): - */ -int devinit_bebox(struct devinit *devinit) +DEVINIT(bebox) { struct bebox_data *d; @@ -113,7 +153,9 @@ memset(d, 0, sizeof(struct bebox_data)); memory_device_register(devinit->machine->memory, devinit->name, - 0x7ffff000, 0x500, dev_bebox_access, d, MEM_DEFAULT, NULL); + 0x7ffff000, 0x500, dev_bebox_access, d, DM_DEFAULT, NULL); + + devinit->return_ptr = d; return 1; }