2 FUJITSU FM Towns Emulator 'eFMTowns'
4 Author : Kyuma.Ohta <whatisthis.sowhat _at_ gmail.com>
10 #include "../../fileio.h"
11 #include "./serialrom.h"
15 // POS=rom bit position, c=data
16 void SERIAL_ROM::store_reversed_byte(uint8_t pos, uint8_t c)
18 int npos = (256 - (uint16_t)pos) >> 3;
19 int bitpos = (256 - (uint16_t)pos) & 7;
21 for(int i = 0; i < 8; i++) {
23 dst = dst | ((c >> i)& 0x01);
32 tmp.b.h = rom[npos + 1];
39 tmp.w = tmp.w & (~mask.w);
45 rom[npos + 1] = tmp.b.h;
51 uint8_t SERIAL_ROM::read_rom_bits(uint8_t pos)
53 return ((rom[pos >> 3] >> (pos & 7)) & 0x01);
56 void SERIAL_ROM::initialize()
64 memset(rom, 0xff, sizeof(rom));
66 memset(tmprom, 0xff, sizeof(tmprom));
68 FILEIO *fio = new FILEIO();
69 if(fio->Fopen(create_local_path(_T("MYTOWNS.ROM")), FILEIO_READ_BINARY)) { // FONT
70 fio->Fread(tmprom, sizeof(tmprom), 1);
73 } else if(fio->Fopen(create_local_path(_T("SERIAL.ROM")), FILEIO_READ_BINARY)) { // FONT
74 fio->Fread(tmprom, sizeof(tmprom), 1);
79 // Q: IS MYTOWNS.ROM reverse bit-order? 20191117 K.O
80 //memcpy(rom, tmprom, sizeof(rom));
81 for(uint8_t i = 0; i < 32; i++) {
82 store_reversed_byte(i << 3, tmprom[i]);
85 rom[255 >> 3] = rom[255 >> 3] & 0x0f; // Clear head of 4 bits.
86 static const _TCHAR signaure[] = _T("FUJITSU");
87 for(int i = 0; i < strlen(signature); i++) {
88 store_reversed_byte((uint8_t)(244 - (i * 8)), signature[i]);
90 // ToDo: Reserved BITs (bit 195 - bit 72)
92 store_reversed_byte(64, 0x01);
93 store_reversed_byte(56, 0x01);
95 static const uint8_t serial_num[5] = {0xbc, 0xde, 0xf0, 0x12, 0x34};
96 uint8_t tmp1 = rom[48 >> 3];
97 uint8_t tmp2 = serial_num[0] & 0x0f;
99 for(int i = 0; i < 4; i++) {
101 dst = dst | (tmp2 & 0x01);
105 rom[48 >> 3] = tmp1 | (dst & 0x0f);
106 for(int i = 1; i < 5; i++) {
107 store_reversed_byte(20 + ((4 - i) << 3), serial_num[i]);
109 // Clear bit 19 - bit0
110 rom[16 >> 3] = rom[16 >> 3] & 0xf0;
116 void SERIAL_ROM::reset()
124 void SERIAL_ROM::write_signal(int ch, uint32_t data, uint32_t mask)
127 case SIG_SERIALROM_CLK:
132 newclk = ((data & mask) != 0);
134 if((oldclk != newclk) && !(reset_reg)) {
138 rom_addr = (rom_addr + 1) & 0xff;
143 case SIG_SERIALROM_CS:
144 cs = ((data & mask) == 0);
146 case SIG_SERIALROM_RESET:
147 reset_reg = ((data & mask) != 0);
149 switch(reset_state) {
151 if(reset_reg) reset_state++;
169 uint32_t SERIAL_ROM::read_signal(int ch)
172 case SIG_SERIALROM_CLK:
173 return ((clk) ? 0xffffffff : 0x00000000);
175 case SIG_SERIALROM_CS:
176 return ((cs) ? 0xffffffff : 0x00000000);;
178 case SIG_SERIALROM_RESET:
179 return ((reset_reg) ? 0xffffffff : 0x00000000);
181 case SIG_SERIALROM_RESET_STATE:
184 case SIG_SERIALROM_DATA:
186 return (read_rom_bits(rom_addr) == 0x00) ? 0x00000000 : 0xffffffff;
195 bool SERIAL_ROM::write_debug_reg(const _TCHAR *reg, uint32_t data)
197 _TCHAR numseg[8] = {'\0'};
199 if((reg[0] == 'R') || (reg[0] == 'r')){
200 if(strlen(reg) < 2) return false;
201 if((reg[1] == 'R') || (reg[1] == 'r')) { // Reversed bit
204 for(int i = 0; i < 2; i++) {
205 if(reg[i + noff + 1] == '\0') break;
206 if((reg[i + noff + 1] < '0') || (reg[i + noff + 1] >'9')) break;
207 numseg[i] = reg[i + noff + 1];
209 if(strlen(numseg) < 1) return false;
210 int pos = atoi(numseg);
211 if((pos < 0) || (pos > 31)) return false;
212 if((reg[1] == 'R') || (reg[1] == 'r')) { // Reversed bit
214 for(int i = 0; i <8; i++) {
216 dst = dst | (data & 0x01);
224 } else if((reg[0] == 'B') || (reg[0] == 'b')){
225 if(strlen(reg) < 2) return false;
226 if((reg[1] == 'R') || (reg[i] == 'r')) { // Reversed bit
229 for(int i = 0; i < 3; i++) {
230 if(reg[i + noff + 1] == '\0') break;
231 if((reg[i + noff + 1] < '0') || (reg[i + noff + 1] >'9')) break;
232 numseg[i] = reg[i + noff + 1];
234 if(strlen(numseg) < 1) return false;
235 int bitpos = atoi(numseg);
236 if((pos < 0) || (pos > 255)) return false;
237 int bytepos = bitpos >> 3;
238 int offs = bitpos & 7;
239 uint8_t dst = rom[bytepos];
240 if((reg[1] == 'R') || (reg[i] == 'r')) { // Reversed bit
243 dst = dst & (~(0x01 << offs));
244 dst = dst | ((data & 0x01) << offs);
251 bool SERIAL_ROM::get_debug_regs_info(_TCHAR *buffer, size_t buffer_len)
253 uint8_t reverse_mem[32];
255 memset(reverse_mem, 0x00, sizeof(reverse_mem));
256 for(int i = 0; i < 32; i++) {
258 uint8_t src = rom[i];
259 for(int j = 0; j < 8; j++) {
264 reverse_mem[i] = dst;
267 my_tcscat_s(buffer, buffer_len, _T("** INFO:\n"));
268 my_tcscat_s(buffer, buffer_len, _T("ROM value is enable to modify, \n"));
269 my_tcscat_s(buffer, buffer_len, _T(" R00-R32 : Overwrite rom raw value by byte\n"));
270 my_tcscat_s(buffer, buffer_len, _T(" RR00-RR32 : Overwrite rom reversed value by byte\n"));
271 my_tcscat_s(buffer, buffer_len, _T(" B000-B256 : Overwrite bit foo to (value != 0) ? 1 : 0\n"));
272 my_tcscat_s(buffer, buffer_len, _T(" BR000-BR256 : Overwrite bit foo to (value != 0) ? 1 : 0 by reversed order.\n\n"));
274 my_tcscat_s(buffer, buffer_len, _T("** STATS:\n"));
275 my_tcscat_s(buffer, buffer_len,
276 create_string(_T(" CS=%s CLK=%d RESET REG=%d RESET STATE=%d\n ROM BIT POSITION=%03d(0x%02X)\n\n"),
277 (cs) ? _T("ON ") : _T("OFF"),
284 my_tcscat_s(buffer, buffer_len, _T("** RAW MEMORY VALUE:\n"));
285 my_tcscat_s(buffer, buffer_len, _T(" +0 +1 +2 +3 +4 +5 +6 +7\n"));
286 my_tcscat_s(buffer, buffer_len, _T(" ------------------------------\n"));
287 for(int n = 0; n < 4; n++) {
288 my_tcscat_s(buffer, buffer_len,
289 create_string(_T("+%02X %02X %02X %02X %02X %02X %02X %02X %02X\n"),
291 rom[n * 4 + 0], rom[n * 4 + 1], rom[n * 4 + 2], rom[n * 4 + 3],
292 rom[n * 4 + 4], rom[n * 4 + 5], rom[n * 4 + 6], rom[n * 4 + 7])
295 my_tcscat_s(buffer, buffer_len, _T("\n"));
296 my_tcscat_s(buffer, buffer_len, _T("** BIT REVERSED VALUE:\n"));
297 my_tcscat_s(buffer, buffer_len, _T(" +0 +1 +2 +3 +4 +5 +6 +7\n"));
298 my_tcscat_s(buffer, buffer_len, _T(" ------------------------------\n"));
299 for(int n = 0; n < 4; n++) {
300 my_tcscat_s(buffer, buffer_len,
301 create_string(_T("+%02X %02X %02X %02X %02X %02X %02X %02X %02X\n"),
303 reverse_mem[n * 4 + 0], reverse_mem[n * 4 + 1], reverse_mem[n * 4 + 2], reverse_mem[n * 4 + 3],
304 reverse_mem[n * 4 + 4], reverse_mem[n * 4 + 5], reverse_mem[n * 4 + 6], reverse_mem[n * 4 + 7])
310 #define STATE_VERSION 1
312 bool SERIAL_ROM::process_state(FILEIO* state_fio, bool loading)
314 if(!state_fio->StateCheckUint32(STATE_VERSION)) {
317 if(!state_fio->StateCheckInt32(this_device_id)) {
320 state_fio->StateValue(cs);
321 state_fio->StateValue(clk);
322 state_fio->StateValue(reset_reg);
323 state_fio->StateValue(reset_state);
324 state_fio->StateValue(rom_addr);
325 state_fio->StateArray(rom, sizeof(rom), 1);