X-Git-Url: http://git.squeep.com/?p=dcpu16;a=blobdiff_plain;f=hw_spc2000.c;fp=hw_spc2000.c;h=2fa0c7b3ff8702734681adec556ad7316aed099b;hp=0000000000000000000000000000000000000000;hb=19bb0a4e64c9ab3e62ff4bbd959289704ee5b8f1;hpb=0a6b0889c67675bd71681ec41774d2ea57ce5335 diff --git a/hw_spc2000.c b/hw_spc2000.c new file mode 100644 index 0000000..2fa0c7b --- /dev/null +++ b/hw_spc2000.c @@ -0,0 +1,80 @@ +#include +#include +#include + +#include "dcpu16.h" +#include "hw_spc2000.h" + +static dcpu16_hw_signal_t spc2000_reset_; +static dcpu16_hw_signal_t spc2000_cycle_; +static dcpu16_hw_signal_t spc2000_hwi_; +static struct dcpu16_hw hw_ = { + .name_ = "SPC2000 - Suspension Chamber 2000", + .id_l = 0x1d9d, + .id_h = 0x40e4, + .ver = 0x005e, + .mfg_l = 0x8b36, + .mfg_h = 0x1c6c, + .hwi = spc2000_hwi_, + .cycle = spc2000_cycle_, + .reset = spc2000_reset_, + .data = (struct spc2000_ *)NULL +}; + +struct spc2000_ { + DCPU16_WORD skip_unit; + long long skip; +}; + +static +void spc2000_reset_(struct dcpu16 *vm, void *data) { + struct spc2000_ *spc2000 = (struct spc2000_ *)data; + + (void)vm; + + memset(spc2000, 0, sizeof *spc2000); +} + +static +void spc2000_cycle_(struct dcpu16 *vm, void *data) { + struct spc2000_ *spc2000 = (struct spc2000_ *)data; + + (void)vm; + (void)spc2000; +} + +static +void spc2000_hwi_(struct dcpu16 *vm, void *data) { + struct spc2000_ *spc2000 = (struct spc2000_ *)data; + DCPU16_WORD reg_a = vm->reg[DCPU16_REG_A], + reg_b = vm->reg[DCPU16_REG_B]; + long long x; + + switch (reg_a) { + case 0: /* GET_STATUS */ + case 2: /* TRIGGER_DEVICE */ + /* check status */ + vm->reg[DCPU16_REG_C] = 0; + vm->reg[DCPU16_REG_B] = 0; + if (reg_a == 0 + || vm->reg[DCPU16_REG_C] != 0) + break; + /* trigger */ + vm->warn_cb_("spc2000 triggered\n"); + break; + + case 1: /* SET_UNIT_TO_SKIP */ + spc2000->skip = vm->ram[reg_b]; + x = vm->ram[reg_b + 1]; + spc2000->skip |= x << 16; + x = vm->ram[reg_b + 2]; + spc2000->skip |= x << 32; + x = vm->ram[reg_b + 3]; + spc2000->skip |= x << 48; + break; + + case 3: /* SET_SKIP_UNIT */ + spc2000->skip_unit = reg_b; + break; + } +}