OSDN Git Service

[VM][STATE] Use namespace {VMNAME} to separate per VMs.
[csp-qt/common_source_project-fm7.git] / source / src / vm / pc9801 / mouse.cpp
1 /*
2         NEC PC-9801 Emulator 'ePC-9801'
3         NEC PC-9801E/F/M Emulator 'ePC-9801E'
4         NEC PC-9801U Emulator 'ePC-9801U'
5         NEC PC-9801VF Emulator 'ePC-9801VF'
6         NEC PC-9801VM Emulator 'ePC-9801VM'
7         NEC PC-9801VX Emulator 'ePC-9801VX'
8         NEC PC-9801RA Emulator 'ePC-9801RA'
9         NEC PC-98XA Emulator 'ePC-98XA'
10         NEC PC-98XL Emulator 'ePC-98XL'
11         NEC PC-98RL Emulator 'ePC-98RL'
12         NEC PC-98DO Emulator 'ePC-98DO'
13
14         Author : Takeda.Toshiya
15         Date   : 2011.12.27-
16
17         [ mouse ]
18 */
19
20 #include "mouse.h"
21 #include "../i8255.h"
22 #include "../i8259.h"
23
24 #define EVENT_TIMER     0
25
26 namespace PC9801 {
27
28 static const int freq_table[4] = {120, 60, 30, 15};
29
30 void MOUSE::initialize()
31 {
32         status = emu->get_mouse_buffer();
33         
34         ctrlreg = 0xff;
35         freq = cur_freq = 0;
36         
37         register_frame_event(this);
38         register_event(this, EVENT_TIMER, 1000000.0 / freq_table[freq], true, &register_id);
39 }
40
41 void MOUSE::reset()
42 {
43         dx = dy = 0;
44         lx = ly = -1;
45 }
46
47 #if !defined(SUPPORT_HIRESO)
48 void MOUSE::write_io8(uint32_t addr, uint32_t data)
49 {
50         switch(addr) {
51         case 0xbfdb:
52                 if((data & 0xfc) == 0) {
53                         freq = data;
54                 }
55                 break;
56         }
57 }
58
59 uint32_t MOUSE::read_io8(uint32_t addr)
60 {
61         switch(addr) {
62         case 0xbfdb:
63                 return freq;
64         }
65         return 0xff;
66 }
67 #endif
68
69 void MOUSE::event_callback(int event_id, int err)
70 {
71         if(!(ctrlreg & 0x10)) {
72                 d_pic->write_signal(SIG_I8259_CHIP1 | SIG_I8259_IR5, 1, 1);
73         }
74         if(cur_freq != (freq & 3)) {
75                 cancel_event(this, register_id);
76                 register_event(this, EVENT_TIMER, 1000000.0 / freq_table[freq & 3] + err, true, &register_id);
77                 cur_freq = freq & 3;
78         }
79 }
80
81 void MOUSE::event_frame()
82 {
83         dx += status[0];
84         if(dx > 64) {
85                 dx = 64;
86         } else if(dx < -64) {
87                 dx = -64;
88         }
89         dy += status[1];
90         if(dy > 64) {
91                 dy = 64;
92         } else if(dy < -64) {
93                 dy = -64;
94         }
95         update_mouse();
96 }
97
98 void MOUSE::write_signal(int id, uint32_t data, uint32_t mask)
99 {
100         if(!(ctrlreg & 0x80) && (data & 0x80)) {
101                 lx = dx;
102                 ly = dy;
103                 dx = dy = 0;
104         }
105         ctrlreg = data & mask;
106         update_mouse();
107 }
108
109 void MOUSE::update_mouse()
110 {
111         int val = 0;
112         
113         if(!(status[2] & 1)) val |= 0x80;       // left
114         if(!(status[2] & 2)) val |= 0x20;       // right
115         if(!(status[2] & 4)) val |= 0x40;       // center
116         
117         switch(ctrlreg & 0xe0) {
118         case 0x00: val |= (dx >> 0) & 0x0f; break;
119         case 0x20: val |= (dx >> 4) & 0x0f; break;
120         case 0x40: val |= (dy >> 0) & 0x0f; break;
121         case 0x60: val |= (dy >> 4) & 0x0f; break;
122         case 0x80: val |= (lx >> 0) & 0x0f; break;
123         case 0xa0: val |= (lx >> 4) & 0x0f; break;
124         case 0xc0: val |= (ly >> 0) & 0x0f; break;
125         case 0xe0: val |= (ly >> 4) & 0x0f; break;
126         }
127         d_pio->write_signal(SIG_I8255_PORT_A, val, 0xff);
128 }
129
130 #define STATE_VERSION   2
131
132 bool MOUSE::process_state(FILEIO* state_fio, bool loading)
133 {
134         if(!state_fio->StateCheckUint32(STATE_VERSION)) {
135                 return false;
136         }
137         if(!state_fio->StateCheckInt32(this_device_id)) {
138                 return false;
139         }
140         state_fio->StateInt32(ctrlreg);
141         state_fio->StateInt32(freq);
142         state_fio->StateInt32(cur_freq);
143         state_fio->StateInt32(dx);
144         state_fio->StateInt32(dy);
145         state_fio->StateInt32(lx);
146         state_fio->StateInt32(ly);
147         state_fio->StateInt32(register_id);
148         return true;
149 }
150
151 }