2 NEC PC-100 Emulator 'ePC-100'
\r
4 Author : Takeda.Toshiya
\r
11 #include "../i8259.h"
\r
12 #include "../../fileio.h"
\r
14 void CRTC::initialize()
\r
17 memset(vram, 0, sizeof(vram));
\r
21 maskl = maskh = busl = bush = 0;
\r
28 for(int i = 1; i < 16; i++) {
\r
36 register_vline_event(this);
\r
39 void CRTC::event_vline(int v, int clock)
\r
42 d_pic->write_signal(SIG_I8259_IR4, 1, 1);
\r
46 void CRTC::write_io8(uint32 addr, uint32 data)
\r
48 switch(addr & 0xff) {
\r
50 shift = data & 0x0f;
\r
56 regs[sel & 7] = data;
\r
59 vs = (vs & 0xff00) | data;
\r
62 vs = (vs & 0xff) | (data << 8);
\r
80 palette[(addr >> 1) & 0x0f] = (palette[(addr >> 1) & 0x0f] & 0xff00) | data;
\r
81 update_palette((addr >> 1) & 0x0f);
\r
99 palette[(addr >> 1) & 0x0f] = (palette[(addr >> 1) & 0x0f] & 0xff) | (data << 8);
\r
100 update_palette((addr >> 1) & 0x0f);
\r
103 cmd = (cmd & 0xff00) | data;
\r
106 cmd = (cmd & 0xff) | (data << 8);
\r
111 uint32 CRTC::read_io8(uint32 addr)
\r
115 switch(addr & 0x3ff) {
\r
121 return regs[sel & 7];
\r
142 return palette[(addr >> 1) & 0x0f] & 0xff;
\r
159 return palette[(addr >> 1) & 0x0f] >> 8;
\r
168 void CRTC::write_memory_mapped_io8(uint32 addr, uint32 data)
\r
175 uint32 bus = busl | (bush << 8) | (busl << 16) | (bush << 24);
\r
179 uint32 h = (bus >> 8) & 0xff;
\r
180 for(int pl = 0; pl < 4; pl++) {
\r
181 if(write_plane & (1 << pl)) {
\r
182 int ofsh = (addr & 0x1ffff) | (0x20000 * pl);
\r
183 vram[ofsh] = (vram[ofsh] & maskh) | (h & ~maskh);
\r
187 uint32 l = bus & 0xff;
\r
188 for(int pl = 0; pl < 4; pl++) {
\r
189 if(write_plane & (1 << pl)) {
\r
190 int ofsl = (addr & 0x1ffff) | (0x20000 * pl);
\r
191 vram[ofsl] = (vram[ofsl] & maskl) | (l & ~maskl);
\r
197 uint32 CRTC::read_memory_mapped_io8(uint32 addr)
\r
199 return vram[(addr & 0x1ffff) | (0x20000 * read_plane)];
\r
202 void CRTC::write_memory_mapped_io16(uint32 addr, uint32 data)
\r
204 busl = (addr & 1) ? (data >> 8) : (data & 0xff);
\r
205 bush = (addr & 1) ? (data & 0xff) : (data >> 8);
\r
206 uint32 bus = busl | (bush << 8) | (busl << 16) | (bush << 24);
\r
208 uint32 l = bus & 0xff;
\r
209 uint32 h = (bus >> 8) & 0xff;
\r
211 for(int pl = 0; pl < 4; pl++) {
\r
212 if(write_plane & (1 << pl)) {
\r
213 int ofsl = ((addr & 1 ? (addr + 1) : addr) & 0x1ffff) | (0x20000 * pl);
\r
214 int ofsh = ((addr & 1 ? addr : (addr + 1)) & 0x1ffff) | (0x20000 * pl);
\r
215 vram[ofsl] = (vram[ofsl] & maskl) | (l & ~maskl);
\r
216 vram[ofsh] = (vram[ofsh] & maskh) | (h & ~maskh);
\r
221 uint32 CRTC::read_memory_mapped_io16(uint32 addr)
\r
223 uint32 val = read_memory_mapped_io8(addr);
\r
224 val |= read_memory_mapped_io8(addr + 1) << 8;
\r
228 void CRTC::write_signal(int id, uint32 data, uint32 mask)
\r
230 if(id == SIG_CRTC_BITMASK_LOW) {
\r
232 maskl = data & 0xff;
\r
233 } else if(id == SIG_CRTC_BITMASK_HIGH) {
\r
235 maskh = data & 0xff;
\r
236 } else if(id == SIG_CRTC_VRAM_PLANE) {
\r
238 write_plane = data & 0x0f;
\r
239 read_plane = (data >> 4) & 3;
\r
243 void CRTC::draw_screen()
\r
246 int hd = (regs[2] >> 1) & 0x3f;
\r
247 int vd = (regs[6] >> 1) & 0x3f;
\r
248 int hs = (int)(int8)((regs[0] & 0x40) ? (regs[0] | 0x80) : (regs[0] & 0x3f));
\r
249 // int hs = (int)(int8)regs[0];
\r
250 int vs_tmp = (int)(int16)((vs & 0x400) ? (vs | 0xf800) : (vs & 0x3ff));
\r
251 int sa = (hs + hd + 1) * 2 + (vs_tmp + vd) * 0x80;
\r
252 // int sa = (hs + hd + 1) * 2 + ((vs & 0x3ff) + vd) * 0x80;
\r
254 if(cmd != 0xffff) {
\r
256 scrntype col = RGB_COLOR(255, 255, 255);
\r
257 for(int y = 0; y < 512; y++) {
\r
258 int ptr = sa & 0x1ffff;
\r
260 scrntype *dest = emu->screen_buffer(y);
\r
262 for(int x = 0; x < 720; x += 8) {
\r
263 uint8 pat = vram[ptr];
\r
264 ptr = (ptr + 1) & 0x1ffff;
\r
266 dest[x + 0] = pat & 0x01 ? col : 0;
\r
267 dest[x + 1] = pat & 0x02 ? col : 0;
\r
268 dest[x + 2] = pat & 0x04 ? col : 0;
\r
269 dest[x + 3] = pat & 0x08 ? col : 0;
\r
270 dest[x + 4] = pat & 0x10 ? col : 0;
\r
271 dest[x + 5] = pat & 0x20 ? col : 0;
\r
272 dest[x + 6] = pat & 0x40 ? col : 0;
\r
273 dest[x + 7] = pat & 0x80 ? col : 0;
\r
278 for(int y = 0; y < 512; y++) {
\r
279 int ptr = sa & 0x1ffff;
\r
281 scrntype *dest = emu->screen_buffer(y);
\r
283 for(int x = 0; x < 720; x += 8) {
\r
284 uint8 p0 = vram[0x00000 | ptr];
\r
285 uint8 p1 = vram[0x20000 | ptr];
\r
286 uint8 p2 = vram[0x40000 | ptr];
\r
287 uint8 p3 = vram[0x60000 | ptr];
\r
288 ptr = (ptr + 1) & 0x1ffff;
\r
290 dest[x + 0] = palette_pc[((p0 & 0x01) << 0) | ((p1 & 0x01) << 1) | ((p2 & 0x01) << 2) | ((p3 & 0x01) << 3)];
\r
291 dest[x + 1] = palette_pc[((p0 & 0x02) >> 1) | ((p1 & 0x02) << 0) | ((p2 & 0x02) << 1) | ((p3 & 0x02) << 2)];
\r
292 dest[x + 2] = palette_pc[((p0 & 0x04) >> 2) | ((p1 & 0x04) >> 1) | ((p2 & 0x04) << 0) | ((p3 & 0x04) << 1)];
\r
293 dest[x + 3] = palette_pc[((p0 & 0x08) >> 3) | ((p1 & 0x08) >> 2) | ((p2 & 0x08) >> 1) | ((p3 & 0x08) << 0)];
\r
294 dest[x + 4] = palette_pc[((p0 & 0x10) >> 4) | ((p1 & 0x10) >> 3) | ((p2 & 0x10) >> 2) | ((p3 & 0x10) >> 1)];
\r
295 dest[x + 5] = palette_pc[((p0 & 0x20) >> 5) | ((p1 & 0x20) >> 4) | ((p2 & 0x20) >> 3) | ((p3 & 0x20) >> 2)];
\r
296 dest[x + 6] = palette_pc[((p0 & 0x40) >> 6) | ((p1 & 0x40) >> 5) | ((p2 & 0x40) >> 4) | ((p3 & 0x40) >> 3)];
\r
297 dest[x + 7] = palette_pc[((p0 & 0x80) >> 7) | ((p1 & 0x80) >> 6) | ((p2 & 0x80) >> 5) | ((p3 & 0x80) >> 4)];
\r
301 emu->screen_skip_line = false;
\r
304 void CRTC::update_palette(int num)
\r
306 int r = (palette[num] >> 0) & 7;
\r
307 int g = (palette[num] >> 3) & 7;
\r
308 int b = (palette[num] >> 6) & 7;
\r
309 palette_pc[num] = RGB_COLOR(r << 5, g << 5, b << 5);
\r
312 #define STATE_VERSION 1
\r
314 void CRTC::save_state(FILEIO* state_fio)
\r
316 state_fio->FputUint32(STATE_VERSION);
\r
317 state_fio->FputInt32(this_device_id);
\r
319 state_fio->Fwrite(palette_pc, sizeof(palette_pc), 1);
\r
320 state_fio->Fwrite(palette, sizeof(palette), 1);
\r
321 state_fio->FputUint8(sel);
\r
322 state_fio->Fwrite(regs, sizeof(regs), 1);
\r
323 state_fio->FputUint16(vs);
\r
324 state_fio->FputUint16(cmd);
\r
325 state_fio->Fwrite(vram, sizeof(vram), 1);
\r
326 state_fio->FputUint32(shift);
\r
327 state_fio->FputUint32(maskl);
\r
328 state_fio->FputUint32(maskh);
\r
329 state_fio->FputUint32(busl);
\r
330 state_fio->FputUint32(bush);
\r
331 state_fio->FputUint32(write_plane);
\r
332 state_fio->FputUint32(read_plane);
\r
335 bool CRTC::load_state(FILEIO* state_fio)
\r
337 if(state_fio->FgetUint32() != STATE_VERSION) {
\r
340 if(state_fio->FgetInt32() != this_device_id) {
\r
343 state_fio->Fread(palette_pc, sizeof(palette_pc), 1);
\r
344 state_fio->Fread(palette, sizeof(palette), 1);
\r
345 sel = state_fio->FgetUint8();
\r
346 state_fio->Fread(regs, sizeof(regs), 1);
\r
347 vs = state_fio->FgetUint16();
\r
348 cmd = state_fio->FgetUint16();
\r
349 state_fio->Fread(vram, sizeof(vram), 1);
\r
350 shift = state_fio->FgetUint32();
\r
351 maskl = state_fio->FgetUint32();
\r
352 maskh = state_fio->FgetUint32();
\r
353 busl = state_fio->FgetUint32();
\r
354 bush = state_fio->FgetUint32();
\r
355 write_plane = state_fio->FgetUint32();
\r
356 read_plane = state_fio->FgetUint32();
\r