OSDN Git Service

[VM][WIP] Use namespace to devices per VMs.
[csp-qt/common_source_project-fm7.git] / source / src / vm / multi8 / cmt.cpp
1 /*
2         MITSUBISHI Electric MULTI8 Emulator 'EmuLTI8'
3
4         Author : Takeda.Toshiya
5         Date   : 2006.09.16 -
6
7         [ cmt ]
8 */
9
10 #include "cmt.h"
11 #include "../i8251.h"
12
13 namespace MULTI8 {
14
15 void CMT::initialize()
16 {
17         fio = new FILEIO();
18         play = rec = remote = false;
19 }
20
21 void CMT::release()
22 {
23         release_tape();
24         delete fio;
25 }
26
27 void CMT::reset()
28 {
29         close_tape();
30         play = rec = remote = false;
31 }
32
33 void CMT::write_signal(int id, uint32_t data, uint32_t mask)
34 {
35         if(id == SIG_CMT_REMOTE) {
36                 remote = ((data & mask) != 0);
37         } else if(id == SIG_CMT_OUT) {
38                 if(rec && remote) {
39                         // recv from sio
40                         buffer[bufcnt++] = data & mask;
41                         if(bufcnt >= BUFFER_SIZE) {
42                                 fio->Fwrite(buffer, bufcnt, 1);
43                                 bufcnt = 0;
44                         }
45                 }
46         }
47 }
48
49 void CMT::play_tape(const _TCHAR* file_path)
50 {
51         close_tape();
52         
53         if(fio->Fopen(file_path, FILEIO_READ_BINARY)) {
54                 fio->Fseek(0, FILEIO_SEEK_END);
55                 int size = (fio->Ftell() + 9) & (BUFFER_SIZE - 1);
56                 fio->Fseek(0, FILEIO_SEEK_SET);
57                 memset(buffer, 0, sizeof(buffer));
58                 fio->Fread(buffer, sizeof(buffer), 1);
59                 fio->Fclose();
60                 
61                 // send data to sio
62                 // this implement does not care the sio buffer size... :-(
63                 for(int i = 0; i < size; i++) {
64                         d_sio->write_signal(SIG_I8251_RECV, buffer[i], 0xff);
65                 }
66                 play = true;
67         }
68 }
69
70 void CMT::rec_tape(const _TCHAR* file_path)
71 {
72         close_tape();
73         
74         if(fio->Fopen(file_path, FILEIO_READ_WRITE_NEW_BINARY)) {
75                 my_tcscpy_s(rec_file_path, _MAX_PATH, file_path);
76                 bufcnt = 0;
77                 rec = true;
78         }
79 }
80
81 void CMT::close_tape()
82 {
83         // close file
84         release_tape();
85         
86         // clear sio buffer
87         d_sio->write_signal(SIG_I8251_CLEAR, 0, 0);
88 }
89
90 void CMT::release_tape()
91 {
92         // close file
93         if(fio->IsOpened()) {
94                 if(rec && bufcnt) {
95                         fio->Fwrite(buffer, bufcnt, 1);
96                 }
97                 fio->Fclose();
98         }
99         play = rec = false;
100 }
101
102 #define STATE_VERSION   2
103
104 bool CMT::process_state(FILEIO* state_fio, bool loading)
105 {
106         if(!state_fio->StateCheckUint32(STATE_VERSION)) {
107                 return false;
108         }
109         if(!state_fio->StateCheckInt32(this_device_id)) {
110                 return false;
111         }
112         state_fio->StateBool(play);
113         state_fio->StateBool(rec);
114         state_fio->StateBool(remote);
115         state_fio->StateBuffer(rec_file_path, sizeof(rec_file_path), 1);
116         if(loading) {
117                 int length_tmp = state_fio->FgetInt32_LE();
118                 if(rec) {
119                         fio->Fopen(rec_file_path, FILEIO_READ_WRITE_NEW_BINARY);
120                         while(length_tmp != 0) {
121                                 uint8_t buffer_tmp[1024];
122                                 int length_rw = min(length_tmp, (int)sizeof(buffer_tmp));
123                                 state_fio->Fread(buffer_tmp, length_rw, 1);
124                                 if(fio->IsOpened()) {
125                                         fio->Fwrite(buffer_tmp, length_rw, 1);
126                                 }
127                                 length_tmp -= length_rw;
128                         }
129                 }
130         } else {
131                 if(rec && fio->IsOpened()) {
132                         int length_tmp = (int)fio->Ftell();
133                         fio->Fseek(0, FILEIO_SEEK_SET);
134                         state_fio->FputInt32_LE(length_tmp);
135                         while(length_tmp != 0) {
136                                 uint8_t buffer_tmp[1024];
137                                 int length_rw = min(length_tmp, (int)sizeof(buffer_tmp));
138                                 fio->Fread(buffer_tmp, length_rw, 1);
139                                 state_fio->Fwrite(buffer_tmp, length_rw, 1);
140                                 length_tmp -= length_rw;
141                         }
142                 } else {
143                         state_fio->FputInt32_LE(0);
144                 }
145         }
146         state_fio->StateInt32(bufcnt);
147         state_fio->StateBuffer(buffer, sizeof(buffer), 1);
148         return true;
149 }
150
151 }