OSDN Git Service

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