2 Skelton for retropc emulator
4 Origin : Neko Project 2
5 Author : Takeda.Toshiya
18 #define MODE_MIX ((sync[0] & 0x22) == 0x00)
19 #define MODE_GFX ((sync[0] & 0x22) == 0x02)
20 #define MODE_CHR ((sync[0] & 0x22) == 0x20)
23 #define RT_TABLEBIT 12
24 #define RT_TABLEMAX (1 << RT_TABLEBIT)
26 #define SIG_UPD7220_CLOCK_FREQ 1
27 #define SIG_UPD7220_EXT_VSYNC 2
28 #define SIG_UPD7220_WIDTH_BYTES 3
29 #define SIG_UPD7220_HEIGHT 4
30 #define SIG_UPD7220_PITCH 5
31 #define SIG_UPD7220_DISP_HEIGHT 6
32 #define SIG_UPD7220_DISP_WIDTH 7
36 class UPD7220 : public DEVICE
40 outputs_t outputs_drq;
41 outputs_t outputs_vsync;
42 outputs_t outputs_vblank;
48 uint16_t vram_data_mask;
52 bool _UPD7220_MSB_FIRST;
53 bool _UPD7220_UGLY_PC98_HACK;
54 int _UPD7220_FIXED_PITCH;
55 int _UPD7220_HORIZ_FREQ;
56 int _UPD7220_A_VERSION;
65 int vtotal, vfp, vs, vbp, v1, v2, v3, v4;
66 int hfp, hs, hbp, h1, h2, h3, h4;
96 double frames_per_sec;
101 RINGBUFFER *cmd_fifo;
105 uint32_t wrote_bytes;
109 int rt[RT_TABLEMAX + 1];
110 int dx, dy; // from ead, dad
111 int dir, dif, sl, dc, d, d2, d1, dm;
114 const int vectdir[16][4] = {
115 { 0, 1, 1, 0}, { 1, 1, 1,-1}, { 1, 0, 0,-1}, { 1,-1,-1,-1},
116 { 0,-1,-1, 0}, {-1,-1,-1, 1}, {-1, 0, 0, 1}, {-1, 1, 1, 1},
117 { 0, 1, 1, 1}, { 1, 1, 1, 0}, { 1, 0, 1,-1}, { 1,-1, 0,-1},
118 { 0,-1,-1,-1}, {-1,-1,-1, 0}, {-1, 0,-1, 1}, {-1, 1, 0, 1}
120 int horiz_freq, next_horiz_freq;
123 //void process_cmd();
124 uint32_t before_addr;
154 void __FASTCALL cmd_write_sub(uint32_t addr, uint8_t data);
155 void __FASTCALL write_vram(uint32_t addr, uint8_t data);
156 uint8_t __FASTCALL read_vram(uint32_t addr);
160 void __FASTCALL register_event_wait_cmd(uint32_t bytes);
175 inline void __FASTCALL draw_pset(int x, int y);
176 inline void __FASTCALL start_pset();
177 inline void __FASTCALL finish_pset();
178 inline bool __FASTCALL draw_pset_diff(int x, int y);
179 inline void __FASTCALL shift_pattern(int shift);
182 UPD7220(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu)
184 initialize_output_signals(&outputs_drq);
185 initialize_output_signals(&outputs_vsync);
186 initialize_output_signals(&outputs_vblank);
189 vram_data_mask = 0xffff;
192 clock_freq = 2500 * 1000; // Hz
193 set_device_name(_T("uPD7220 GDC"));
201 void __FASTCALL write_dma_io8(uint32_t addr, uint32_t data);
202 uint32_t __FASTCALL read_dma_io8(uint32_t addr);
203 void __FASTCALL write_io8(uint32_t addr, uint32_t data);
204 uint32_t __FASTCALL read_io8(uint32_t addr);
205 void event_pre_frame();
207 void event_vline(int v, int clock);
208 void event_callback(int event_id, int err);
209 void update_timing(int new_clocks, double new_frames_per_sec, int new_lines_per_frame);
211 uint32_t __FASTCALL read_signal(int ch);
212 void __FASTCALL write_signal(int ch, uint32_t data, uint32_t mask);
214 bool process_state(FILEIO* state_fio, bool loading);
218 void set_context_drq(DEVICE* device, int id, uint32_t mask)
220 register_output_signal(&outputs_drq, device, id, mask);
222 void set_context_vsync(DEVICE* device, int id, uint32_t mask)
224 register_output_signal(&outputs_vsync, device, id, mask);
226 void set_context_vblank(DEVICE* device, int id, uint32_t mask)
228 register_output_signal(&outputs_vblank, device, id, mask);
230 void set_vram_ptr(uint8_t* ptr, uint32_t size)
235 void set_vram_ptr(uint8_t* ptr, uint32_t size, uint16_t mask)
237 set_vram_ptr(ptr, size);
238 vram_data_mask = mask;
240 void set_vram_bus_ptr(DEVICE* device, uint32_t size)
245 void set_vram_bus_ptr(DEVICE* device, uint32_t size, uint16_t mask)
247 set_vram_bus_ptr(device, size);
248 vram_data_mask = mask;
250 void set_screen_width(int value)
254 void set_screen_height(int value)
258 void set_clock_freq(uint32_t hz)
286 uint32_t __FASTCALL cursor_addr(uint32_t mask);
287 int __FASTCALL cursor_top();
288 int __FASTCALL cursor_bottom();
289 bool __FASTCALL attr_blink()
291 return (blink_attr < (blink_rate * 3 / 4));
293 void __FASTCALL set_horiz_freq(int freq)
295 next_horiz_freq = freq;
300 inline void UPD7220::draw_pset(int x, int y)
302 uint32_t addr = y * width + (x >> 3);
303 if(_UPD7220_UGLY_PC98_HACK) {
304 // if(addr >= 0x8000) return;
305 // if((y == 409) && (x >= 384)) return;
306 // if(y > 409) return;
307 // if((x < 0) || (y < 0) || (x >= (width << 3))) return;
308 // addr = addr & 0x7fff;
310 if((x < 0) || (y < 0) || (x >= (width << 3)) || (y >= height)) return;
312 uint16_t dot = pattern & 1;
313 pattern = (pattern >> 1) | (dot << 15);
315 if(_UPD7220_MSB_FIRST) {
316 bit = 0x80 >> (x & 7);
320 uint8_t cur = read_vram(addr);
326 write_vram(addr, (cur & ~bit) | (dot ? bit : 0));
328 case 1: // complement
329 write_vram(addr, (cur & ~bit) | ((cur ^ (dot ? 0xff : 0)) & bit));
332 write_vram(addr, cur & (dot ? ~bit : 0xff));
335 write_vram(addr, cur | (dot ? bit : 0));
340 inline void UPD7220::start_pset()
342 before_addr = 0xffffffff;
347 inline void UPD7220::finish_pset()
350 write_vram(before_addr, cache_val);
354 before_addr = 0xffffffff;
358 inline void UPD7220::shift_pattern(int shift)
364 } else if(shift < 0) {
366 bits = (-shift) % 16;
367 if(bits == 0) return;
370 pattern >>= (16 - bits);
371 pattern = (pattern | dot) & 0xffff;
372 } else if(shift > 0) {
375 if(bits == 0) return;
378 pattern <<= (16 - bits);
379 pattern = (pattern | dot) & 0xffff;
384 inline bool UPD7220::draw_pset_diff(int x, int y)
386 uint16_t dot = pattern & 1;
387 pattern = (pattern >> 1) | (dot << 15);
388 uint32_t addr = y * width + (x >> 3);
391 // if(_UPD7220_UGLY_PC98_HACK) {
392 // if(addr >= 0x8000) {
393 // if((y > 409) || ((y == 409) && x >= 384)){
397 // else if((x < 0) || (y < 0) || (x >= (width << 3))) {
401 // } else if((x < 0) || (y < 0) || (x >= (width << 3)) || (y >= height)) {
405 if((first_load) || (addr != before_addr)) {
407 write_vram(before_addr, cache_val);
410 cache_val = read_vram(addr);
418 if(_UPD7220_MSB_FIRST) {
419 bit = 0x80 >> (x & 7);
423 uint8_t cur = cache_val;
424 wrote_bytes++; // OK?
428 cache_val = (cur & ~bit) | (dot ? bit : 0);
430 case 1: // complement
431 cache_val = (cur & ~bit) | ((cur ^ (dot ? 0xff : 0)) & bit);
434 cache_val = cur & (dot ? ~bit : 0xff);
437 cache_val = cur | (dot ? bit : 0);