OSDN Git Service

[VM][General] Merge upstream 2016-03-01. (Pahse 1).
[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 void CMT::save_state(FILEIO* state_fio)
99 {
100         state_fio->FputUint32(STATE_VERSION);
101         state_fio->FputInt32(this_device_id);
102         
103         state_fio->FputBool(play);
104         state_fio->FputBool(rec);
105         state_fio->Fwrite(rec_file_path, sizeof(rec_file_path), 1);
106         if(rec && fio->IsOpened()) {
107                 int length_tmp = (int)fio->Ftell();
108                 fio->Fseek(0, FILEIO_SEEK_SET);
109                 state_fio->FputInt32(length_tmp);
110                 while(length_tmp != 0) {
111                         uint8_t buffer_tmp[1024];
112                         int length_rw = min(length_tmp, (int)sizeof(buffer_tmp));
113                         fio->Fread(buffer_tmp, length_rw, 1);
114                         state_fio->Fwrite(buffer_tmp, length_rw, 1);
115                         length_tmp -= length_rw;
116                 }
117         } else {
118                 state_fio->FputInt32(0);
119         }
120         state_fio->FputInt32(bufcnt);
121         state_fio->Fwrite(buffer, sizeof(buffer), 1);
122 }
123
124 bool CMT::load_state(FILEIO* state_fio)
125 {
126         release_tape();
127         
128         if(state_fio->FgetUint32() != STATE_VERSION) {
129                 return false;
130         }
131         if(state_fio->FgetInt32() != this_device_id) {
132                 return false;
133         }
134         play = state_fio->FgetBool();
135         rec = state_fio->FgetBool();
136         state_fio->Fread(rec_file_path, sizeof(rec_file_path), 1);
137         int length_tmp = state_fio->FgetInt32();
138         if(rec) {
139                 fio->Fopen(rec_file_path, FILEIO_READ_WRITE_NEW_BINARY);
140                 while(length_tmp != 0) {
141                         uint8_t buffer_tmp[1024];
142                         int length_rw = min(length_tmp, (int)sizeof(buffer_tmp));
143                         state_fio->Fread(buffer_tmp, length_rw, 1);
144                         if(fio->IsOpened()) {
145                                 fio->Fwrite(buffer_tmp, length_rw, 1);
146                         }
147                         length_tmp -= length_rw;
148                 }
149         }
150         bufcnt = state_fio->FgetInt32();
151         state_fio->Fread(buffer, sizeof(buffer), 1);
152         return true;
153 }
154