6 #include "hw_spc2000.h"
8 #define MSG_(__level__, __vm__, ...) do { ((__vm__) ? ((struct dcpu16 *)(__vm__))->msg_cb_ : dcpu16_msg_)(__level__, __VA_ARGS__); } while (0)
9 #define MSG_INFO(__vm__, ...) MSG_(DCPU16_MSG_INFO, __vm__, __VA_ARGS__)
10 #define MSG_ERROR(__vm__, ...) MSG_(DCPU16_MSG_ERROR, __vm__, __VA_ARGS__)
12 #define MSG_DEBUG(__vm__, ...) MSG_(DCPU16_MSG_DEBUG, __vm__, __VA_ARGS__)
14 #define MSG_DEBUG(__vm__, ...) do { } while (0)
18 DCPU16_WORD skip_unit
;
23 int spc2000_data_init_(struct dcpu16_hw
*hw
, void *data
) {
26 hw
->data
= calloc(1, sizeof(struct spc2000_
));
27 if (hw
->data
== NULL
) {
28 MSG_ERROR(hw
->vm
, "%s():%s", "calloc", strerror(errno
));
35 void spc2000_data_free_(struct dcpu16_hw
*hw
) {
45 void spc2000_reset_(struct dcpu16
*vm
, struct dcpu16_hw
*hw
) {
46 struct spc2000_
*spc2000
= (struct spc2000_
*)hw
->data
;
50 memset(spc2000
, 0, sizeof *spc2000
);
54 void spc2000_cycle_(struct dcpu16
*vm
, struct dcpu16_hw
*hw
) {
55 struct spc2000_
*spc2000
= (struct spc2000_
*)hw
->data
;
62 void spc2000_hwi_(struct dcpu16
*vm
, struct dcpu16_hw
*hw
) {
63 struct spc2000_
*spc2000
= (struct spc2000_
*)hw
->data
;
64 DCPU16_WORD reg_a
= vm
->reg
[DCPU16_REG_A
],
65 reg_b
= vm
->reg
[DCPU16_REG_B
];
69 case 0: /* GET_STATUS */
70 case 2: /* TRIGGER_DEVICE */
72 vm
->reg
[DCPU16_REG_C
] = 0;
73 vm
->reg
[DCPU16_REG_B
] = 0;
75 || vm
->reg
[DCPU16_REG_C
] != 0)
78 MSG_INFO(vm
, "spc2000 triggered\n");
81 case 1: /* SET_UNIT_TO_SKIP */
82 spc2000
->skip
= vm
->ram
[reg_b
];
83 x
= vm
->ram
[reg_b
+ 1];
84 spc2000
->skip
|= x
<< 16;
85 x
= vm
->ram
[reg_b
+ 2];
86 spc2000
->skip
|= x
<< 32;
87 x
= vm
->ram
[reg_b
+ 3];
88 spc2000
->skip
|= x
<< 48;
91 case 3: /* SET_SKIP_UNIT */
92 spc2000
->skip_unit
= reg_b
;
97 struct dcpu16_hw_module dcpu16_hw_module_spc2000
= {
98 .name_
= "SPC2000 - Suspension Chamber 2000",
106 .cycle
= spc2000_cycle_
,
107 .reset
= spc2000_reset_
,
109 .data_init
= spc2000_data_init_
,
110 .data_free
= spc2000_data_free_
,