6 #include "hw_spc2000.h"
8 static dcpu16_hw_signal_t spc2000_reset_
;
9 static dcpu16_hw_signal_t spc2000_cycle_
;
10 static dcpu16_hw_signal_t spc2000_hwi_
;
11 static struct dcpu16_hw hw_
= {
12 .name_
= "SPC2000 - Suspension Chamber 2000",
19 .cycle
= spc2000_cycle_
,
20 .reset
= spc2000_reset_
,
21 .data
= (struct spc2000_
*)NULL
25 DCPU16_WORD skip_unit
;
30 void spc2000_reset_(struct dcpu16
*vm
, void *data
) {
31 struct spc2000_
*spc2000
= (struct spc2000_
*)data
;
35 memset(spc2000
, 0, sizeof *spc2000
);
39 void spc2000_cycle_(struct dcpu16
*vm
, void *data
) {
40 struct spc2000_
*spc2000
= (struct spc2000_
*)data
;
47 void spc2000_hwi_(struct dcpu16
*vm
, void *data
) {
48 struct spc2000_
*spc2000
= (struct spc2000_
*)data
;
49 DCPU16_WORD reg_a
= vm
->reg
[DCPU16_REG_A
],
50 reg_b
= vm
->reg
[DCPU16_REG_B
];
54 case 0: /* GET_STATUS */
55 case 2: /* TRIGGER_DEVICE */
57 vm
->reg
[DCPU16_REG_C
] = 0;
58 vm
->reg
[DCPU16_REG_B
] = 0;
60 || vm
->reg
[DCPU16_REG_C
] != 0)
63 vm
->warn_cb_("spc2000 triggered\n");
66 case 1: /* SET_UNIT_TO_SKIP */
67 spc2000
->skip
= vm
->ram
[reg_b
];
68 x
= vm
->ram
[reg_b
+ 1];
69 spc2000
->skip
|= x
<< 16;
70 x
= vm
->ram
[reg_b
+ 2];
71 spc2000
->skip
|= x
<< 32;
72 x
= vm
->ram
[reg_b
+ 3];
73 spc2000
->skip
|= x
<< 48;
76 case 3: /* SET_SKIP_UNIT */
77 spc2000
->skip_unit
= reg_b
;
82 struct dcpu16_hw
*spc2000_new(struct dcpu16
*vm
) {
85 hw
= calloc(1, sizeof *hw
);
87 vm
->warn_cb_("%s():%s", "calloc", strerror(errno
));
91 memcpy(hw
, &hw_
, sizeof *hw
);
93 hw
->data
= calloc(1, sizeof(struct spc2000_
));
94 if (hw
->data
== NULL
) {
95 vm
->warn_cb_("%s():%s", "calloc", strerror(errno
));
105 void spc2000_del(struct dcpu16_hw
**hw
) {