OSDN Git Service

[General][Qt] Merge upstream 2015-03-15.
[csp-qt/common_source_project-fm7.git] / source / src / vm / pc9801 / cmt.cpp
1 /*
2         NEC PC-9801 Emulator 'ePC-9801'
3         NEC PC-9801E/F/M Emulator 'ePC-9801E'
4
5         Author : Takeda.Toshiya
6         Date   : 2011.04.08-
7
8         [ cmt ]
9 */
10
11 #include "cmt.h"
12 #include "../i8251.h"
13
14 void CMT::initialize()
15 {
16         fio = new FILEIO();
17         play = rec = remote = false;
18         buffer_size = BUFFER_SIZE;
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_io8(uint32 addr, uint32 data)
34 {
35         remote = ((data & 0x20) != 0);
36 }
37
38 void CMT::write_signal(int id, uint32 data, uint32 mask)
39 {
40         if(id == SIG_CMT_OUT) {
41                 if(rec && remote) {
42                         // recv from sio
43                         buffer[bufcnt++] = data & mask;
44                         if(bufcnt >= BUFFER_SIZE) {
45                                 fio->Fwrite(buffer, bufcnt, 1);
46                                 bufcnt = 0;
47                         }
48                 }
49         }
50 }
51
52 void CMT::play_tape(_TCHAR* file_path)
53 {
54         close_tape();
55         
56         if(fio->Fopen(file_path, FILEIO_READ_BINARY)) {
57                 fio->Fseek(0, FILEIO_SEEK_END);
58                 int size = (fio->Ftell() + 9) & (BUFFER_SIZE - 1);
59                 fio->Fseek(0, FILEIO_SEEK_SET);
60                 memset(buffer, 0, sizeof(buffer));
61                 buffer_size = size; 
62                 fio->Fread(buffer, sizeof(buffer), 1);
63                 
64                 // send data to sio
65                 // this implement does not care the sio buffer size... :-(
66                 for(int i = 0; i < size; i++) {
67                         d_sio->write_signal(SIG_I8251_RECV, buffer[i], 0xff);
68                 }
69                 play = true;
70         }
71 }
72
73 void CMT::rec_tape(_TCHAR* file_path)
74 {
75         close_tape();
76         
77         if(fio->Fopen(file_path, FILEIO_WRITE_BINARY)) {
78                 bufcnt = 0;
79                 rec = true;
80         }
81 }
82
83 void CMT::close_tape()
84 {
85         // close file
86         release_tape();
87         buffer_size = BUFFER_SIZE;
88         // clear sio buffer
89         d_sio->write_signal(SIG_I8251_CLEAR, 0, 0);
90 }
91
92 void CMT::release_tape()
93 {
94         // close file
95         if(rec && bufcnt) {
96                 fio->Fwrite(buffer, bufcnt, 1);
97         }
98         if(play || rec) {
99                 fio->Fclose();
100         }
101         play = rec = false;
102 }
103
104 #ifdef DATAREC_SOUND
105 void CMT::mix(int32 *buffer, int cnt)
106 {
107   if(!cmt_mix) return;
108   // Not implemented yet :) 
109 }    
110 #endif
111
112 #define STATE_VERSION   1
113
114 void CMT::save_state(FILEIO* state_fio)
115 {
116         state_fio->FputUint32(STATE_VERSION);
117         state_fio->FputInt32(this_device_id);
118         
119         state_fio->FputInt32(bufcnt);
120         state_fio->Fwrite(buffer, sizeof(buffer), 1);
121         state_fio->FputBool(play);
122         state_fio->FputBool(rec);
123         state_fio->FputBool(remote);
124 }
125
126 bool CMT::load_state(FILEIO* state_fio)
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         bufcnt = state_fio->FgetInt32();
135         state_fio->Fread(buffer, sizeof(buffer), 1);
136         play = state_fio->FgetBool();
137         rec = state_fio->FgetBool();
138         remote = state_fio->FgetBool();
139         return true;
140 }
141