2 NEC PC-100 Emulator 'ePC-100'
4 Author : Takeda.Toshiya
13 void CRTC::initialize()
16 memset(vram, 0, sizeof(vram));
20 maskl = maskh = busl = bush = 0;
27 for(int i = 1; i < 16; i++) {
35 register_vline_event(this);
38 void CRTC::event_vline(int v, int clock)
41 d_pic->write_signal(SIG_I8259_IR4, 1, 1);
45 void CRTC::write_io8(uint32_t addr, uint32_t data)
58 vs = (vs & 0xff00) | data;
61 vs = (vs & 0xff) | (data << 8);
79 palette[(addr >> 1) & 0x0f] = (palette[(addr >> 1) & 0x0f] & 0xff00) | data;
80 update_palette((addr >> 1) & 0x0f);
98 palette[(addr >> 1) & 0x0f] = (palette[(addr >> 1) & 0x0f] & 0xff) | (data << 8);
99 update_palette((addr >> 1) & 0x0f);
102 cmd = (cmd & 0xff00) | data;
105 cmd = (cmd & 0xff) | (data << 8);
110 uint32_t CRTC::read_io8(uint32_t addr)
114 switch(addr & 0x3ff) {
120 return regs[sel & 7];
141 return palette[(addr >> 1) & 0x0f] & 0xff;
158 return palette[(addr >> 1) & 0x0f] >> 8;
167 void CRTC::write_memory_mapped_io8(uint32_t addr, uint32_t data)
174 uint32_t bus = busl | (bush << 8) | (busl << 16) | (bush << 24);
178 uint32_t h = (bus >> 8) & 0xff;
179 for(int pl = 0; pl < 4; pl++) {
180 if(write_plane & (1 << pl)) {
181 int ofsh = (addr & 0x1ffff) | (0x20000 * pl);
182 vram[ofsh] = (vram[ofsh] & maskh) | (h & ~maskh);
186 uint32_t l = bus & 0xff;
187 for(int pl = 0; pl < 4; pl++) {
188 if(write_plane & (1 << pl)) {
189 int ofsl = (addr & 0x1ffff) | (0x20000 * pl);
190 vram[ofsl] = (vram[ofsl] & maskl) | (l & ~maskl);
196 uint32_t CRTC::read_memory_mapped_io8(uint32_t addr)
198 return vram[(addr & 0x1ffff) | (0x20000 * read_plane)];
201 void CRTC::write_memory_mapped_io16(uint32_t addr, uint32_t data)
203 busl = (addr & 1) ? (data >> 8) : (data & 0xff);
204 bush = (addr & 1) ? (data & 0xff) : (data >> 8);
205 uint32_t bus = busl | (bush << 8) | (busl << 16) | (bush << 24);
207 uint32_t l = bus & 0xff;
208 uint32_t h = (bus >> 8) & 0xff;
210 for(int pl = 0; pl < 4; pl++) {
211 if(write_plane & (1 << pl)) {
212 int ofsl = ((addr & 1 ? (addr + 1) : addr) & 0x1ffff) | (0x20000 * pl);
213 int ofsh = ((addr & 1 ? addr : (addr + 1)) & 0x1ffff) | (0x20000 * pl);
214 vram[ofsl] = (vram[ofsl] & maskl) | (l & ~maskl);
215 vram[ofsh] = (vram[ofsh] & maskh) | (h & ~maskh);
220 uint32_t CRTC::read_memory_mapped_io16(uint32_t addr)
222 uint32_t val = read_memory_mapped_io8(addr);
223 val |= read_memory_mapped_io8(addr + 1) << 8;
227 void CRTC::write_signal(int id, uint32_t data, uint32_t mask)
229 if(id == SIG_CRTC_BITMASK_LOW) {
232 } else if(id == SIG_CRTC_BITMASK_HIGH) {
235 } else if(id == SIG_CRTC_VRAM_PLANE) {
237 write_plane = data & 0x0f;
238 read_plane = (data >> 4) & 3;
242 void CRTC::draw_screen()
245 int hd = (regs[2] >> 1) & 0x3f;
246 int vd = (regs[6] >> 1) & 0x3f;
247 int hs = (int)(int8_t)((regs[0] & 0x40) ? (regs[0] | 0x80) : (regs[0] & 0x3f));
248 // int hs = (int)(int8_t)regs[0];
249 int vs_tmp = (int)(int16_t)((vs & 0x400) ? (vs | 0xf800) : (vs & 0x3ff));
250 int sa = (hs + hd + 1) * 2 + (vs_tmp + vd) * 0x80;
251 // int sa = (hs + hd + 1) * 2 + ((vs & 0x3ff) + vd) * 0x80;
255 scrntype_t col = RGB_COLOR(255, 255, 255);
256 for(int y = 0; y < 512; y++) {
257 int ptr = sa & 0x1ffff;
259 scrntype_t *dest = emu->get_screen_buffer(y);
261 for(int x = 0; x < 720; x += 8) {
262 uint8_t pat = vram[ptr];
263 ptr = (ptr + 1) & 0x1ffff;
265 dest[x + 0] = pat & 0x01 ? col : 0;
266 dest[x + 1] = pat & 0x02 ? col : 0;
267 dest[x + 2] = pat & 0x04 ? col : 0;
268 dest[x + 3] = pat & 0x08 ? col : 0;
269 dest[x + 4] = pat & 0x10 ? col : 0;
270 dest[x + 5] = pat & 0x20 ? col : 0;
271 dest[x + 6] = pat & 0x40 ? col : 0;
272 dest[x + 7] = pat & 0x80 ? col : 0;
277 for(int y = 0; y < 512; y++) {
278 int ptr = sa & 0x1ffff;
280 scrntype_t *dest = emu->get_screen_buffer(y);
282 for(int x = 0; x < 720; x += 8) {
283 uint8_t p0 = vram[0x00000 | ptr];
284 uint8_t p1 = vram[0x20000 | ptr];
285 uint8_t p2 = vram[0x40000 | ptr];
286 uint8_t p3 = vram[0x60000 | ptr];
287 ptr = (ptr + 1) & 0x1ffff;
289 dest[x + 0] = palette_pc[((p0 & 0x01) << 0) | ((p1 & 0x01) << 1) | ((p2 & 0x01) << 2) | ((p3 & 0x01) << 3)];
290 dest[x + 1] = palette_pc[((p0 & 0x02) >> 1) | ((p1 & 0x02) << 0) | ((p2 & 0x02) << 1) | ((p3 & 0x02) << 2)];
291 dest[x + 2] = palette_pc[((p0 & 0x04) >> 2) | ((p1 & 0x04) >> 1) | ((p2 & 0x04) << 0) | ((p3 & 0x04) << 1)];
292 dest[x + 3] = palette_pc[((p0 & 0x08) >> 3) | ((p1 & 0x08) >> 2) | ((p2 & 0x08) >> 1) | ((p3 & 0x08) << 0)];
293 dest[x + 4] = palette_pc[((p0 & 0x10) >> 4) | ((p1 & 0x10) >> 3) | ((p2 & 0x10) >> 2) | ((p3 & 0x10) >> 1)];
294 dest[x + 5] = palette_pc[((p0 & 0x20) >> 5) | ((p1 & 0x20) >> 4) | ((p2 & 0x20) >> 3) | ((p3 & 0x20) >> 2)];
295 dest[x + 6] = palette_pc[((p0 & 0x40) >> 6) | ((p1 & 0x40) >> 5) | ((p2 & 0x40) >> 4) | ((p3 & 0x40) >> 3)];
296 dest[x + 7] = palette_pc[((p0 & 0x80) >> 7) | ((p1 & 0x80) >> 6) | ((p2 & 0x80) >> 5) | ((p3 & 0x80) >> 4)];
300 emu->screen_skip_line(false);
303 void CRTC::update_palette(int num)
305 int r = (palette[num] >> 0) & 7;
306 int g = (palette[num] >> 3) & 7;
307 int b = (palette[num] >> 6) & 7;
308 palette_pc[num] = RGB_COLOR(r << 5, g << 5, b << 5);
311 #define STATE_VERSION 1
313 bool CRTC::process_state(FILEIO* state_fio, bool loading)
315 if(!state_fio->StateCheckUint32(STATE_VERSION)) {
318 if(!state_fio->StateCheckInt32(this_device_id)) {
321 //state_fio->StateBuffer(palette_pc, sizeof(palette_pc), 1);
322 for(int i = 0; i < (sizeof(palette_pc) / sizeof(scrntype_t)); i++) {
325 r = state_fio->FgetUint8();
326 g = state_fio->FgetUint8();
327 b = state_fio->FgetUint8();
328 palette_pc[i] = RGB_COLOR(r, g, b);
331 r = R_OF_COLOR(palette_pc[i]);
332 g = G_OF_COLOR(palette_pc[i]);
333 b = B_OF_COLOR(palette_pc[i]);
334 state_fio->FputUint8(r);
335 state_fio->FputUint8(g);
336 state_fio->FputUint8(b);
339 //state_fio->StateBuffer(palette, sizeof(palette), 1);
340 for(int i = 0; i < (sizeof(palette) / sizeof(uint16_t)); i++) {
341 state_fio->StateUint16(palette[i]);
343 state_fio->StateUint8(sel);
344 state_fio->StateBuffer(regs, sizeof(regs), 1);
345 state_fio->StateUint16(vs);
346 state_fio->StateUint16(cmd);
347 state_fio->StateBuffer(vram, sizeof(vram), 1);
348 state_fio->StateUint32(shift);
349 state_fio->StateUint32(maskl);
350 state_fio->StateUint32(maskh);
351 state_fio->StateUint32(busl);
352 state_fio->StateUint32(bush);
353 state_fio->StateUint32(write_plane);
354 state_fio->StateUint32(read_plane);