OSDN Git Service

7d03df0354be5aa0305accd82914136b7b2e2c87
[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 static const int freq_table[4] = {120, 60, 30, 15};
27
28 void MOUSE::initialize()
29 {
30         status = emu->get_mouse_buffer();
31         
32         ctrlreg = 0xff;
33         freq = cur_freq = 0;
34         
35         register_frame_event(this);
36         register_event(this, EVENT_TIMER, 1000000.0 / freq_table[freq], true, &register_id);
37 }
38
39 void MOUSE::reset()
40 {
41         dx = dy = 0;
42         lx = ly = -1;
43 }
44
45 #if !defined(SUPPORT_HIRESO)
46 void MOUSE::write_io8(uint32_t addr, uint32_t data)
47 {
48         switch(addr) {
49         case 0xbfdb:
50                 if((data & 0xfc) == 0) {
51                         freq = data;
52                 }
53                 break;
54         }
55 }
56
57 uint32_t MOUSE::read_io8(uint32_t addr)
58 {
59         switch(addr) {
60         case 0xbfdb:
61                 return freq;
62         }
63         return 0xff;
64 }
65 #endif
66
67 void MOUSE::event_callback(int event_id, int err)
68 {
69         if(!(ctrlreg & 0x10)) {
70                 d_pic->write_signal(SIG_I8259_CHIP1 | SIG_I8259_IR5, 1, 1);
71         }
72         if(cur_freq != (freq & 3)) {
73                 cancel_event(this, register_id);
74                 register_event(this, EVENT_TIMER, 1000000.0 / freq_table[freq & 3] + err, true, &register_id);
75                 cur_freq = freq & 3;
76         }
77 }
78
79 void MOUSE::event_frame()
80 {
81         dx += status[0];
82         if(dx > 64) {
83                 dx = 64;
84         } else if(dx < -64) {
85                 dx = -64;
86         }
87         dy += status[1];
88         if(dy > 64) {
89                 dy = 64;
90         } else if(dy < -64) {
91                 dy = -64;
92         }
93         update_mouse();
94 }
95
96 void MOUSE::write_signal(int id, uint32_t data, uint32_t mask)
97 {
98         if(!(ctrlreg & 0x80) && (data & 0x80)) {
99                 lx = dx;
100                 ly = dy;
101                 dx = dy = 0;
102         }
103         ctrlreg = data & mask;
104         update_mouse();
105 }
106
107 void MOUSE::update_mouse()
108 {
109         int val = 0;
110         
111         if(!(status[2] & 1)) val |= 0x80;       // left
112         if(!(status[2] & 2)) val |= 0x20;       // right
113         if(!(status[2] & 4)) val |= 0x40;       // center
114         
115         switch(ctrlreg & 0xe0) {
116         case 0x00: val |= (dx >> 0) & 0x0f; break;
117         case 0x20: val |= (dx >> 4) & 0x0f; break;
118         case 0x40: val |= (dy >> 0) & 0x0f; break;
119         case 0x60: val |= (dy >> 4) & 0x0f; break;
120         case 0x80: val |= (lx >> 0) & 0x0f; break;
121         case 0xa0: val |= (lx >> 4) & 0x0f; break;
122         case 0xc0: val |= (ly >> 0) & 0x0f; break;
123         case 0xe0: val |= (ly >> 4) & 0x0f; break;
124         }
125         d_pio->write_signal(SIG_I8255_PORT_A, val, 0xff);
126 }
127
128 #define STATE_VERSION   2
129
130 bool MOUSE::process_state(FILEIO* state_fio, bool loading)
131 {
132         if(!state_fio->StateCheckUint32(STATE_VERSION)) {
133                 return false;
134         }
135         if(!state_fio->StateCheckInt32(this_device_id)) {
136                 return false;
137         }
138         state_fio->StateInt32(ctrlreg);
139         state_fio->StateInt32(freq);
140         state_fio->StateInt32(cur_freq);
141         state_fio->StateInt32(dx);
142         state_fio->StateInt32(dy);
143         state_fio->StateInt32(lx);
144         state_fio->StateInt32(ly);
145         state_fio->StateInt32(register_id);
146         return true;
147 }
148