OSDN Git Service

d33d474bffe30d3ad63d3e2b5c0538b5a7fa971f
[csp-qt/common_source_project-fm7.git] / source / src / vm / fmtowns / fontroms.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         [fonts]
8 */
9
10 #include "../../fileio.h"
11 #include "./fontroms.h"
12
13 namespace FMTOWNS {
14         
15 void FONT_ROMS::initialize()
16 {
17         memset(font_kanji16, 0xff, sizeof(font_kanji16));
18 //      memset(ram, 0x00, sizeof(ram));
19         FILEIO* fio = new FILEIO();
20         if(fio->Fopen(create_local_path(_T("FMT_FNT.ROM")), FILEIO_READ_BINARY)) { // FONT
21                 fio->Fread(font_kanji16, sizeof(font_kanji16), 1);
22                 fio->Fclose();
23         }
24
25         delete fio;
26 }
27
28 void FONT_ROMS::reset()
29 {
30 //      dma_is_vram = true;
31         kanji_code.w = 0;
32         kanji_address = 0;
33 }
34
35 uint8_t FONT_ROMS::read_direct_data8(uint32_t addr)
36 {
37         return font_kanji16[addr & 0x3ffff];
38 }
39
40 uint32_t FONT_ROMS::read_memory_mapped_io8(uint32_t addr)
41 {
42         if((addr >= 0xc2100000) && (addr < 0xc2140000)) {
43                 return (uint32_t)(font_kanji16[addr & 0x3ffff]);
44         } /*else if((addr >= 0x000ca000) && (addr < 0x000ca800)) {
45                 return (uint32_t)(font_kanji16[0x3d000 + (addr & 0x7ff)]);
46         } */else if((addr >= 0x000cb000) && (addr < 0x000cc000)) {
47                 return (uint32_t)(font_kanji16[0x3d800 + (addr & 0xfff)]);
48         }
49         return 0xff;
50 }
51
52 void FONT_ROMS::write_memory_mapped_io8(uint32_t addr, uint32_t data)
53 {
54 }
55 // From MAME 0.216
56 void FONT_ROMS::calc_kanji_offset()
57 {
58         uint8_t kanji_bank = (kanji_code.b.h & 0xf0) >> 4;
59         uint32_t low_addr = (uint32_t)(kanji_code.b.l & 0x1f);
60         uint32_t mid_addr = (uint32_t)(kanji_code.b.l - 0x20);
61         uint32_t high_addr = (uint32_t)(kanji_code.b.h);
62         
63         switch(kanji_bank) {
64         case 0:
65         case 1:
66         case 2:
67                 kanji_address =
68                         (low_addr << 4) | ((mid_addr & 0x20) << 8) |
69                         ((mid_addr & 0x40) << 6) | 
70                         ((high_addr & 0x07) << 9);
71 //              kanji_address >>= 1;
72                 break;
73         case 3:
74         case 4:
75         case 5:
76         case 6:
77                 kanji_address =
78                         (low_addr << 5) + 
79                         ((mid_addr & 0x60) << 9) +
80                         ((high_addr & 0x0f) << 10) +
81                         (((high_addr - 0x30) & 0x70) * 0xc00) + 0x8000;
82                 kanji_address >>= 1;
83                 break;
84         default:
85                 kanji_address =
86                         (low_addr << 4) | ((mid_addr & 0x20) << 8) |
87                         ((mid_addr & 0x40) << 6) |
88                         ((high_addr & 0x07) << 9);
89                 kanji_address |= (0x38000 >> 1);
90 //              kanji_address >>= 1;
91                 break;
92         }
93 }               
94
95 void FONT_ROMS::write_io8(uint32_t addr, uint32_t data)
96 {
97         switch(addr & 0xffff) {
98         case 0xff94: // hidden register
99                 kanji_code.b.h = data;
100                 calc_kanji_offset();
101                 break;
102         case 0xff95: // hidden register
103                 kanji_code.b.l = data;
104                 calc_kanji_offset();
105                 break;
106         }
107 }
108
109 uint32_t FONT_ROMS::read_io8(uint32_t addr)
110 {
111         uint32_t val = 0x00;
112         switch(addr) {
113         case 0xff96: // LOW
114                 val = font_kanji16[(kanji_address << 1) + 0];
115                 break;
116         case 0xff97: // High
117                 val = font_kanji16[(kanji_address << 1) + 1];
118                 kanji_address++;
119                 break;
120         }
121         return val;
122 }
123                 
124         
125 void FONT_ROMS::write_signal(int ch, uint32_t data, uint32_t mask)
126 {
127         if(ch == SIG_TOWNS_FONT_KANJI_LOW) { // write CFF15
128                 kanji_code.b.l = data & 0x7f;
129                 calc_kanji_offset();
130         } else if(ch == SIG_TOWNS_FONT_KANJI_HIGH) { // write CFF14
131                 kanji_code.b.h = data & 0x7f;
132                 calc_kanji_offset();
133         } /*else        if(ch == SIG_TOWNS_FONT_DMA_IS_VRAM) { 
134                 dma_is_vram = ((data & mask) != 0);
135         } */else if(ch == SIG_TOWNS_FONT_KANJI_ROW) { // write CFF9E
136                 kanji_address = (kanji_address & 0xfffffff0) | (data & 0x0f);
137         } 
138 }
139
140 uint32_t FONT_ROMS::read_signal(int ch)
141 {
142         /*if(ch == SIG_TOWNS_FONT_DMA_IS_VRAM) { 
143                 return (dma_is_vram) ? 0xffffffff : 0x00000000;
144         } else */
145         if(ch == SIG_TOWNS_FONT_KANJI_DATA_HIGH) { // read CFF97
146                 uint8_t val = font_kanji16[(kanji_address << 1) + 1];
147                 kanji_address++;
148                 return val;
149         } else if(ch == SIG_TOWNS_FONT_KANJI_DATA_LOW) {  // read CFF96
150                 uint8_t val = font_kanji16[(kanji_address << 1) + 0];
151                 return val;
152         } else if(ch == SIG_TOWNS_FONT_KANJI_LOW) { // write CFF94
153                 return kanji_code.b.l;
154         } else if(ch == SIG_TOWNS_FONT_KANJI_HIGH) { // write CFF95
155                 return kanji_code.b.h;
156         } else if(ch == SIG_TOWNS_FONT_KANJI_ROW) { // write CFF9E
157                 return (kanji_address & 0x0f);
158         } else if(ch >= SIG_TOWNS_FONT_PEEK_DATA) {
159                 int offset = ch - SIG_TOWNS_FONT_PEEK_DATA;
160                 if((offset >= 0) && (offset < 0x40000)) {
161                         return font_kanji16[offset];
162                 }
163         }
164         return 0;
165 }
166         
167 #define STATE_VERSION   1
168
169 bool FONT_ROMS::process_state(FILEIO* state_fio, bool loading)
170 {
171         if(!state_fio->StateCheckUint32(STATE_VERSION)) {
172                 return false;
173         }
174         if(!state_fio->StateCheckInt32(this_device_id)) {
175                 return false;
176         }
177 //      state_fio->StateValue(dma_is_vram);
178         state_fio->StateValue(kanji_code);
179         state_fio->StateValue(kanji_address);
180         
181 //      state_fio->StateArray(ram, sizeof(ram), 1);
182         return true;
183 }
184 }