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_
= {
13 .name_
= "SPC2000 - Suspension Chamber 2000",
20 .cycle
= spc2000_cycle_
,
21 .reset
= spc2000_reset_
,
22 .data
= (struct spc2000_
*)NULL
25 static dcpu16_hw_data_init_t spc2000_data_init_
;
26 static dcpu16_hw_data_free_t spc2000_data_free_
;
27 struct dcpu16_hw_module dcpu16_hw_module_spc2000
= {
29 .data_init
= spc2000_data_init_
,
30 .data_free
= spc2000_data_free_
,
34 DCPU16_WORD skip_unit
;
39 int spc2000_data_init_(struct dcpu16_hw
*hw
, void *extra
) {
42 hw
->data
= calloc(1, sizeof(struct spc2000_
));
43 if (hw
->data
== NULL
) {
44 hw
->vm
->warn_cb_("%s():%s", "calloc", strerror(errno
));
51 void spc2000_data_free_(struct dcpu16_hw
*hw
) {
61 void spc2000_reset_(struct dcpu16
*vm
, void *data
) {
62 struct spc2000_
*spc2000
= (struct spc2000_
*)data
;
66 memset(spc2000
, 0, sizeof *spc2000
);
70 void spc2000_cycle_(struct dcpu16
*vm
, void *data
) {
71 struct spc2000_
*spc2000
= (struct spc2000_
*)data
;
78 void spc2000_hwi_(struct dcpu16
*vm
, void *data
) {
79 struct spc2000_
*spc2000
= (struct spc2000_
*)data
;
80 DCPU16_WORD reg_a
= vm
->reg
[DCPU16_REG_A
],
81 reg_b
= vm
->reg
[DCPU16_REG_B
];
85 case 0: /* GET_STATUS */
86 case 2: /* TRIGGER_DEVICE */
88 vm
->reg
[DCPU16_REG_C
] = 0;
89 vm
->reg
[DCPU16_REG_B
] = 0;
91 || vm
->reg
[DCPU16_REG_C
] != 0)
94 vm
->warn_cb_("spc2000 triggered\n");
97 case 1: /* SET_UNIT_TO_SKIP */
98 spc2000
->skip
= vm
->ram
[reg_b
];
99 x
= vm
->ram
[reg_b
+ 1];
100 spc2000
->skip
|= x
<< 16;
101 x
= vm
->ram
[reg_b
+ 2];
102 spc2000
->skip
|= x
<< 32;
103 x
= vm
->ram
[reg_b
+ 3];
104 spc2000
->skip
|= x
<< 48;
107 case 3: /* SET_SKIP_UNIT */
108 spc2000
->skip_unit
= reg_b
;
113 struct dcpu16_hw
*spc2000_new(struct dcpu16
*vm
) {
114 struct dcpu16_hw
*hw
;
116 hw
= calloc(1, sizeof *hw
);
118 vm
->warn_cb_("%s():%s", "calloc", strerror(errno
));
122 memcpy(hw
, &hw_
, sizeof *hw
);
124 hw
->data
= calloc(1, sizeof(struct spc2000_
));
125 if (hw
->data
== NULL
) {
126 vm
->warn_cb_("%s():%s", "calloc", strerror(errno
));
136 void spc2000_del(struct dcpu16_hw
**hw
) {