OSDN Git Service

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