OSDN Git Service

[VM][FMTOWNS][MEMORY] Fix setup around memory banks by I/O 0404h and 0480h.
[csp-qt/common_source_project-fm7.git] / source / src / vm / fmtowns / serialrom.cpp
1 /*
2         FUJITSU FM Towns Emulator 'eFMTowns'
3
4         Author : Kyuma.Ohta <whatisthis.sowhat _at_ gmail.com>
5         Date   : 2019.01.09 -
6
7         [serial rom]
8 */
9
10 #include "../../fileio.h"
11 #include "./serialrom.h"
12
13 namespace FMTOWNS {
14
15
16 uint8_t SERIAL_ROM::read_rom_bits(uint8_t pos)
17 {
18         uint8_t addr, bit;
19         pos2addr(pos, addr, bit);
20         uint8_t val = ((rom[addr] & (1 << (bit & 7))) != 0) ? 0x01 : 0x00;
21         return val;
22 }
23
24 void SERIAL_ROM::initialize()
25 {
26         bool loaded = false;
27         FILEIO *fio = new FILEIO();
28
29         // Default values are from Tsugaru, physmem.cpp.
30         // -> // Just took from my 2MX.
31         const unsigned char defSerialROM[32]=
32         {
33                 0x04,0x65,0x54,0xA4,0x95,0x45,0x35,0x5F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
34                 0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0x0C,0x02,0x00,0x00,0x00,0x15,0xE0,0x00,0x00,
35         };
36         uint8_t tmprom[32] = { 0xff };
37         cs = true;
38         clk = false;
39         reset_reg = false;
40         rom_addr = 0;
41
42         //memset(rom, 0xff, sizeof(rom));
43         memcpy(rom, defSerialROM, sizeof(rom));
44
45         // Q: Is override machineid? 20200627 K.O
46 //      tmprom[24] = (machine_id >> 8);
47 //      tmprom[25] = (machine_id & 0xf8) | (cpu_id & 0x07);
48
49         if(fio->Fopen(create_local_path(_T("MYTOWNS.ROM")), FILEIO_READ_BINARY)) { // FONT
50                 if(fio->Fread(tmprom, sizeof(tmprom), 1) == 1) {
51                         loaded = true;
52                 }
53                 fio->Fclose();
54         } else if(fio->Fopen(create_local_path(_T("SERIAL.ROM")), FILEIO_READ_BINARY)) { // FONT
55                 if(fio->Fread(tmprom, sizeof(tmprom), 1) == 1) {
56                         loaded = true;
57                 }
58                 fio->Fclose();
59         }
60         if(loaded) {
61                 memcpy(rom, tmprom, sizeof(rom));
62         }
63 }
64
65 void SERIAL_ROM::reset()
66 {
67         reset_reg = false;
68         clk = false;
69         cs = true;
70
71         rom_addr = 0;
72 }
73
74 void SERIAL_ROM::write_signal(int id, uint32_t data, uint32_t mask)
75 {
76         switch(id) {
77         case SIG_SERIALROM_CLK:
78                 if(cs) {
79                         if(!(clk)) {
80                                 if((data & mask) != 0) { // RISE UP
81                                         rom_addr = (rom_addr + 1) & 0xff;
82                                 }
83                         }
84                 }
85                 clk = ((data & mask) != 0) ? true : false;
86                 break;
87         case SIG_SERIALROM_CS:
88                 cs = ((data & mask) == 0) ? true : false;
89                 break;
90         case SIG_SERIALROM_RESET:
91                 reset_reg = ((data & mask) != 0);
92                 if((cs) && (reset_reg)) {
93                         reset();
94                 }
95                 break;
96         }
97 }
98
99 uint32_t SERIAL_ROM::read_signal(int ch)
100 {
101         switch(ch) {
102         case SIG_SERIALROM_CLK:
103                 return ((clk) ? 0xffffffff : 0x00000000);
104                 break;
105         case SIG_SERIALROM_CS:
106                 return ((cs) ? 0xffffffff : 0x00000000);;
107                 break;
108         case SIG_SERIALROM_RESET:
109                 return ((reset_reg) ? 0xffffffff : 0x00000000);
110                 break;
111         case SIG_SERIALROM_DATA:
112                 return (read_rom_bits(rom_addr) == 0x00) ? 0x00000000 : 0xffffffff;
113                 break;
114         }
115         return 0;
116 }
117
118 uint32_t SERIAL_ROM::read_io8(uint32_t addr)
119 {
120         __UNLIKELY_IF(addr != 0) {
121                 return 0xff;
122         }
123         uint8_t val;
124         uint8_t val2;
125         val = ((reset_reg) ? 0x80 : 0x00) | ((clk) ? 0x40 : 0x00);
126         val2 = read_rom_bits(rom_addr);
127         return val | val2;
128 }
129
130 void SERIAL_ROM::write_io8(uint32_t addr, uint32_t data)
131 {
132         __LIKELY_IF(addr == 0) {
133                 if((reset_reg) && ((data & 0x80) == 0) && ((data & 0x20) == 0)) {
134                         // Reset
135                         rom_addr = 0x00;
136                 } else if(((data & 0x80) == 0x00) && ((data & 0x20) == 0x00)) {
137                         // CS DOWN, ADDRESS UP.
138                         if(!(clk) && ((data & 0x40) != 0)) {
139                                 rom_addr = (rom_addr + 1) & 0xff;
140                         }
141                 }
142
143                 cs = ((data & 0x20) == 0) ? true : false;
144                 clk = ((data & 0x40) != 0) ? true : false;
145                 reset_reg = ((data & 0x80) != 0) ? true : false;
146         }
147 }
148
149 bool SERIAL_ROM::write_debug_reg(const _TCHAR *reg, uint32_t data)
150 {
151         _TCHAR numseg[8] = {'\0'};
152         int noff = 0;
153         // ToDo: Implement
154         return false;
155 }
156
157 bool SERIAL_ROM::get_debug_regs_info(_TCHAR *buffer, size_t buffer_len)
158 {
159
160         // Dump raw value
161         my_tcscat_s(buffer, buffer_len, _T("** INFO:\n"));
162         my_tcscat_s(buffer, buffer_len, _T("ROM value is enable to modify, \n"));
163         my_tcscat_s(buffer, buffer_len, _T("  R00-R32 : Overwrite rom raw value by byte\n"));
164         my_tcscat_s(buffer, buffer_len, _T("  B000-B256 : Overwrite bit foo to (value != 0) ? 1 : 0\n"));
165
166         uint8_t nibble, bit;
167         pos2addr(rom_addr, nibble, bit);
168
169         my_tcscat_s(buffer, buffer_len, _T("** STATS:\n"));
170         my_tcscat_s(buffer, buffer_len,
171                                 create_string(_T("    CS=%s CLK=%d RESET REG=%d ROM ADDR=%d\n   ROM BIT POSITION=%02d word + %01d bit\n\n"),
172                                                           (cs) ? _T("ON ") : _T("OFF"),
173                                                           (clk) ? 1 : 0,
174                                                           (reset_reg) ? 1 : 0,
175                                                           rom_addr,
176                                                           nibble, bit)
177                 );
178
179         my_tcscat_s(buffer, buffer_len, _T("** RAW MEMORY VALUE:\n"));
180         my_tcscat_s(buffer, buffer_len, _T("    +0  +1  +2  +3  +4  +5  +6  +7\n"));
181         my_tcscat_s(buffer, buffer_len, _T("    ------------------------------\n"));
182         for(int n = 0; n < 4; n++) {
183                 my_tcscat_s(buffer, buffer_len,
184                                         create_string(_T("+%02X %02X  %02X  %02X  %02X  %02X  %02X  %02X  %02X\n"),
185                                                                   n * 4,
186                                                                   rom[n * 4 + 0], rom[n * 4 + 1], rom[n * 4 + 2], rom[n * 4 + 3],
187                                                                   rom[n * 4 + 4], rom[n * 4 + 5], rom[n * 4 + 6], rom[n * 4 + 7])
188                         );
189         }
190         return true;
191 }
192
193 #define STATE_VERSION   2
194
195 bool SERIAL_ROM::process_state(FILEIO* state_fio, bool loading)
196 {
197         if(!state_fio->StateCheckUint32(STATE_VERSION)) {
198                 return false;
199         }
200         if(!state_fio->StateCheckInt32(this_device_id)) {
201                 return false;
202         }
203         state_fio->StateValue(machine_id);
204         state_fio->StateValue(cpu_id);
205         state_fio->StateValue(cs);
206         state_fio->StateValue(clk);
207         state_fio->StateValue(reset_reg);
208         state_fio->StateValue(rom_addr);
209         state_fio->StateArray(rom, sizeof(rom), 1);
210
211         return true;
212 }
213
214 }