OSDN Git Service

[VM][WIP] Apply some devices merging upstream 2018-10-05.This still not build.WIP.
[csp-qt/common_source_project-fm7.git] / source / src / vm / prnfile.cpp
1 /*
2         Skelton for retropc emulator
3
4         Author : Takeda.Toshiya
5         Date   : 2015.12.18-
6
7         [ dummy printer ]
8 */
9
10 #include "prnfile.h"
11
12 #define EVENT_BUSY      0
13 #define EVENT_ACK       1
14
15 void PRNFILE::initialize()
16 {
17         DEVICE::initialize();
18         fio = new FILEIO();
19         
20         value = busy_id = ack_id = wait_frames = -1;
21         _PRINTER_STROBE_RISING_EDGE = osd->check_feature(_T("PRINTER_STROBE_RISING_EDGE"));
22 //#ifdef PRINTER_STROBE_RISING_EDGE
23         if(_PRINTER_STROBE_RISING_EDGE) {
24                 strobe = false;
25         } else {
26 //#else
27         strobe = true;
28         }
29 //#endif
30         res = busy = false;
31         set_busy(false);
32         set_ack(true);
33         
34         register_frame_event(this);
35 }
36
37 void PRNFILE::release()
38 {
39         close_file();
40         delete fio;
41 }
42
43 void PRNFILE::reset()
44 {
45         close_file();
46         
47         busy_id = ack_id = wait_frames = -1;
48         set_busy(false);
49         set_ack(true);
50 }
51
52 void PRNFILE::event_frame()
53 {
54         if(wait_frames > 0 && --wait_frames == 0) {
55                 close_file();
56         }
57 }
58
59 void PRNFILE::write_signal(int id, uint32_t data, uint32_t mask)
60 {
61         if(id == SIG_PRINTER_DATA) {
62                 if(value == -1) {
63                         value = 0;
64                 }
65                 value &= ~mask;
66                 value |= (data & mask);
67         } else if(id == SIG_PRINTER_STROBE) {
68                 bool new_strobe = ((data & mask) != 0);
69 //#ifdef PRINTER_STROBE_RISING_EDGE
70                 bool edge;
71                 if(_PRINTER_STROBE_RISING_EDGE) {
72                         edge = (!strobe && new_strobe);
73                 } else {
74 //#else
75                         edge = (strobe && !new_strobe);
76                 }
77 //#endif
78                 strobe = new_strobe;
79                 
80                 if(edge && value != -1) {
81                         if(!fio->IsOpened()) {
82                                 open_file();
83                         }
84                         fio->Fputc(value);
85                         
86                         // busy 1msec
87                         if(busy_id != -1) {
88                                 cancel_event(this, busy_id);
89                         }
90                         register_event(this, EVENT_BUSY, 10000.0, false, &busy_id);
91                         set_busy(true);
92                         
93                         // wait 1sec and finish printing
94 //#ifdef SUPPORT_VARIABLE_TIMING
95 //                      wait_frames = (int)(vm->get_frame_rate() * 1.0 + 0.5);
96 //#else
97 //                      wait_frames = (int)(FRAMES_PER_SEC * 1.0 + 0.5);
98 //#endif
99                         wait_frames = (int)(osd->vm_frame_rate() * 1.0 + 0.5);
100                 }
101         } else if(id == SIG_PRINTER_RESET) {
102                 bool new_res = ((data & mask) != 0);
103                 if(res && !new_res) {
104                         reset();
105                 }
106                 res = new_res;
107         }
108 }
109
110 uint32_t PRNFILE::read_signal(int ch)
111 {
112         if(ch == SIG_PRINTER_BUSY) {
113                 if(busy) {
114                         if(busy_id != -1) {
115                                 cancel_event(this, busy_id);
116                                 busy_id = -1;
117                         }
118                         set_busy(false);
119                         return 0xffffffff;
120                 }
121         } else if(ch == SIG_PRINTER_ACK) {
122                 if(ack) {
123                         return 0xffffffff;
124                 }
125         }
126         return 0;
127 }
128
129 void PRNFILE::event_callback(int event_id, int err)
130 {
131         if(event_id == EVENT_BUSY) {
132                 busy_id = -1;
133                 set_busy(false);
134         } else if(event_id == EVENT_ACK) {
135                 ack_id = -1;
136                 set_ack(true);
137         }
138 }
139
140 void PRNFILE::set_busy(bool value)
141 {
142         if(busy && !value) {
143                 // ack 10usec
144                 if(ack_id != -1) {
145                         cancel_event(this, ack_id);
146                 }
147                 register_event(this, EVENT_ACK, 10.0, false, &ack_id);
148                 set_ack(false);
149         }
150         busy = value;
151         write_signals(&outputs_busy, busy ? 0xffffffff : 0);
152 }
153
154 void PRNFILE::set_ack(bool value)
155 {
156         ack = value;
157         write_signals(&outputs_ack, ack ? 0xffffffff : 0);
158 }
159
160 void PRNFILE::open_file()
161 {
162         create_date_file_path(file_path, _MAX_PATH, _T("txt"));
163         fio->Fopen(file_path, FILEIO_WRITE_BINARY);
164 }
165
166 void PRNFILE::close_file()
167 {
168         if(fio->IsOpened()) {
169                 // remove if the file size is less than 2 bytes
170                 bool remove = (fio->Ftell() < 2);
171                 fio->Fclose();
172                 if(remove) {
173                         FILEIO::RemoveFile(file_path);
174                 }
175         }
176 }
177
178 #define STATE_VERSION   2
179
180 bool PRNFILE::process_state(FILEIO* state_fio, bool loading)
181 {
182         if(loading) {
183                 //close_file();
184         }
185         
186         if(!state_fio->StateCheckUint32(STATE_VERSION)) {
187                 return false;
188         }
189         if(!state_fio->StateCheckInt32(this_device_id)) {
190                 return false;
191         }
192         state_fio->StateInt32(value);
193         state_fio->StateInt32(busy_id);
194         state_fio->StateInt32(ack_id);
195         state_fio->StateBool(strobe);
196         state_fio->StateBool(res);
197         state_fio->StateBool(busy);
198         state_fio->StateBool(ack);
199         
200         // post process
201         if(loading) {
202                 wait_frames = -1;
203         }
204         return true;
205 }
206