OSDN Git Service

4196372b6d26c509fb0876233a8add0341754223
[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 }
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_io8(uint32_t addr, uint32_t data)
33 {
34         switch(addr) {
35         case 0x0095:
36         case 0x0097:
37                 remote = ((data & 0x20) != 0);
38                 break;
39         }
40 }
41
42 void CMT::write_signal(int id, uint32_t data, uint32_t mask)
43 {
44         if(id == SIG_CMT_OUT) {
45                 if(rec && remote) {
46                         // recv from sio
47                         buffer[bufcnt++] = data & mask;
48                         if(bufcnt >= BUFFER_SIZE) {
49                                 fio->Fwrite(buffer, bufcnt, 1);
50                                 bufcnt = 0;
51                         }
52                 }
53         }
54 }
55
56 void CMT::play_tape(const _TCHAR* file_path)
57 {
58         close_tape();
59         
60         if(fio->Fopen(file_path, FILEIO_READ_BINARY)) {
61                 fio->Fseek(0, FILEIO_SEEK_END);
62                 int size = (fio->Ftell() + 9) & (BUFFER_SIZE - 1);
63                 fio->Fseek(0, FILEIO_SEEK_SET);
64                 memset(buffer, 0, sizeof(buffer));
65                 fio->Fread(buffer, sizeof(buffer), 1);
66                 
67                 // send data to sio
68                 // this implement does not care the sio buffer size... :-(
69                 for(int i = 0; i < size; i++) {
70                         d_sio->write_signal(SIG_I8251_RECV, buffer[i], 0xff);
71                 }
72                 play = true;
73         }
74 }
75
76 void CMT::rec_tape(const _TCHAR* file_path)
77 {
78         close_tape();
79         
80         if(fio->Fopen(file_path, FILEIO_WRITE_BINARY)) {
81                 bufcnt = 0;
82                 rec = true;
83         }
84 }
85
86 void CMT::close_tape()
87 {
88         // close file
89         release_tape();
90         
91         // clear sio buffer
92         d_sio->write_signal(SIG_I8251_CLEAR, 0, 0);
93 }
94
95 void CMT::release_tape()
96 {
97         // close file
98         if(rec && bufcnt) {
99                 fio->Fwrite(buffer, bufcnt, 1);
100         }
101         if(play || rec) {
102                 fio->Fclose();
103         }
104         play = rec = false;
105 }
106
107 #define STATE_VERSION   1
108
109 bool CMT::process_state(FILEIO* state_fio, bool loading)
110 {
111         if(!state_fio->StateCheckUint32(STATE_VERSION)) {
112                 return false;
113         }
114         if(!state_fio->StateCheckInt32(this_device_id)) {
115                 return false;
116         }
117         state_fio->StateInt32(bufcnt);
118         state_fio->StateBuffer(buffer, sizeof(buffer), 1);
119         state_fio->StateBool(play);
120         state_fio->StateBool(rec);
121         state_fio->StateBool(remote);
122         return true;
123 }
124