OSDN Git Service

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