2 Skelton for retropc emulator
4 Author : Kyuma Ohta <whatisthis.sowhat _at_ gmail.com>
8 History: 2016.12.28 Initial from HD46505 .
11 #ifndef _TOWNS_CRTC_H_
12 #define _TOWNS_CRTC_H_
20 * 0440H : Register address (8bit W/O : bit7 to 5 must be '0').
21 * 0442H : Register data LOW (8bit W/O).
22 * 0443H : Register data HIGH (8bit W/O).
25 * Registers description:
26 * Note1: Values are hex, register numbers are decimal.
27 * Note2: Register #00 to #16 ,#18, #22 and #25 to #26 has 11bit.
28 * #17, #19 to #21, #23 to #24 and #27 has 16bit.
29 * #28 has bit 15,14 and 7 to 0.
31 * #31 has bit15 and bit 8 to 0.
33 * #00 / bit 7 - 1 : HSW1 (Bit 10 to 8 and 0 must be '0')
34 * #01 / bit 7 - 1 : HSW2 (Bit 10 to 8 and 0 must be '0')
37 * #04 / bit10 - 1 : HST (Bit 0 bust be '1')
38 * #05 / bit 4 - 0 : VST1 (Bit 10 to 5 must be '0')
39 * #06 / bit 4 - 0 : VST2 (Bit 10 to 5 must be '0')
40 * #07 / bit 4 - 0 : EET (Bit 10 to 5 must be '0')
41 * #08 / bit10 - 0 : VST
42 * #09 / bit10 - 0 : HDS0 (Layer 0)
43 * #10 / bit10 - 0 : HDE0 (Layer 0)
44 * #11 / bit10 - 0 : HDS1 (Layer 1)
45 * #12 / bit10 - 0 : HDE1 (Layer 1)
46 * #13 / bit10 - 0 : VDS0 (Layer 0)
47 * #14 / bit10 - 0 : VDE0 (Layer 0)
48 * #15 / bit10 - 0 : VDS1 (Layer 1)
49 * #16 / bit10 - 0 : VDE1 (Layer 1)
50 * #17 / bit15 - 0 : FA0 (Layer 0)
51 * #18 / bit10 - 0 : HAJ0 (Layer 0)
52 * #19 / bit15 - 0 : FO0 (Layer 0)
53 * #20 / bit15 - 0 : LO0 (Layer 0)
54 * #21 / bit15 - 0 : FA1 (Layer 1)
55 * #22 / bit10 - 0 : HAJ1 (Layer 1)
56 * #23 / bit15 - 0 : FO1 (Layer 1)
57 * #24 / bit15 - 0 : LO1 (Layer 1)
58 * #25 / bit10 - 0 : EHAJ (External horizonal sync adjusting)
59 * #26 / bit10 - 0 : EVAJ (External horizonal sync adjusting)
60 * #27 / bit15 - 0 : bit15-12 : ZV1 / bit11-8 : ZH1 / bit7-4 : ZV0 / bit3-0 : ZH0 (Zooming)
61 * #28 / bit15 : START ('1' = START) / bit14 : ESYN ('0' = Internal)
62 * bit7 : ESM1 ('0'=Impose / '1' = Digitize) / bit 6 : ESM0
63 * bit5 : CEN1 ('1' = Enable) / bit4 : CEN0
64 * bit3-2 : CL1 (Colors : 00 = ND / 01 = 32768x2 / 10 = 32768x1 / 11 = 256x1 or 16x2)
66 * #29 / bit3-2 : SCSEL (Clock divide = 2 * (SCSEL + 1)).
67 * bit1-0 : CLKSEL (00 = 28.6363MHz / 01 = 24.5454MHz / 10 = 25.175MHz / 11 = 21.0525MHz)
68 * #30 / Status register (RO):
69 * bit15 : DSPTV1 / bit14 : DSPTV0 (VDISP = '1')
70 * bit13 : DSPTH1 / bit12 : DSPTH0 (HDISP = '1')
71 * bit11 : FIELD (Field number)
72 * bit10 : VSYNC / bit9 : HSYNC ('1' = ACTIVE)
73 * bit8 : VIN ('1' = EXTERNAL VIDEO has exists)
74 * Dummy register (WO):
75 * bit3 : FR3 ('1' = Halve tone) / bit2 : FR2 ('1' = Using sync generator)
76 * bit1 : VCRDEN ('1' = Video card enable) / bit0 : SCEN ('1' = Sub carry enable)
78 * #31 / bit15 = RETRG ('1' = Re-Trigger) / bit8-0 : PM (Pulse width : Width = PM * Clock).
82 * I/O 044CH : Digital palette modified flags.
83 * I/O 0448H (WO) : Register Address.
84 * I/O 044AH (WO) : Register Data.
86 * #00 : Control registers.
87 * #01 : Priority registers.
89 #define TOWNS_CRTC_MAX_LINES 1024
90 #define TOWNS_CRTC_MAX_PIXELS 1024
94 TOWNS_CRTC_REG_HSW1 = 0,
95 TOWNS_CRTC_REG_HSW2 = 1,
96 TOWNS_CRTC_REG_HST = 4,
101 TOWNS_CRTC_REG_VST, // 8
123 TOWNS_CRTC_REG_DISPMODE, // 28
124 TOWNS_CRTC_REG_CLK, // 29
125 TOWNS_CRTC_REG_DUMMY, // 30
126 TOWNS_CRTC_REG_CTRL, // 31
138 class TOWNS_CRTC : public DEVICE
142 outputs_t outputs_int_vsync; // Connect to int 11.
143 uint16_t regs[32]; // I/O 0442H, 0443H
144 uint8_t ch; // I/O 0440H
145 bool timing_changed[2];
146 bool address_changed[2];
147 bool mode_changed[2];
149 uint8_t display_mode[2];
150 bool display_enabled;
152 double crtc_clock; //
153 // They are not saved.Must be calculate when loading.
154 double horiz_us, next_horiz_us; // (HST + 1) * clock
155 double horiz_width_posi_us, horiz_width_nega_us; // HSW1, HSW2
156 double vert_us, next_vert_us; // (VST +1) * horiz_us / 2.0
158 double vert_sync_pre_us; // VST1 * horiz_us / 2.0
159 double vert_sync_end_us; // VST2 * horiz_us / 2.0
162 double frames_per_sec;
164 uint32_t vstart_addr[2]; // VSTART ADDRESS
165 uint32_t hstart_words[2]; // HSTART ((HDS[01] * clock) : Horizonal offset words (Related by ZH[01]). Maybe 0.
166 uint32_t hend_words[2]; // HEND ((HDE[01] * clock) : Horizonal offset words (Related by ZH[01]). Maybe 0.
167 uint32_t vstart_lines[2]; // VSTART ((VDS[01] * clock) : Horizonal offset words (Related by VH[01]).
168 uint32_t vend_lines[2]; // VEND ((VDE[01] * clock) : Horizonal offset words (Related by VH[01]).
169 uint32_t frame_offset[2]; // FO.
170 uint32_t vram_line[2];
172 uint8_t zoom_factor_vert[2]; // Related display resolutions of two layers and zoom factors.
173 uint8_t zoom_factor_horiz[2]; // Related display resolutions of two layers and zoom factors.
174 uint8_t zoom_count_vert[2];
176 uint32_t line_count[2]; // Separate per layer.
178 int vert_line_count; // Not separate per layer.Total count.
180 int buffer_num; // Frame buffer number.
181 // Note: To display to real screen, use blending of OpenGL/DirectX
182 // from below framebuffers per layer if you can.
183 // And, recommand to use (hardware) shader to rendering (= not to use framebuffer of below) if enabled.
184 // Not recommanded to use draw_screen() type rendering.
185 // Rendering precesses may be heavily to use only CPU (I think). 20170107 K.Ohta.
188 uint8_t layer_colors[2];
189 uint16_t *vram_ptr[2]; // Layer [01] address.
190 uint32_t vram_size[2]; // Layer [01] size [bytes].
191 uint32_t vram_offset[2]; // Layer [01] address offset.
193 uint32_t layer_virtual_width[2];
194 uint32_t layer_virtual_height[2];
195 uint32_t layer_display_width[2];
196 uint32_t layer_display_height[2];
199 bool vdisp, vblank, vsync, hsync, hdisp, frame_in;
201 // Video output controller (I/O 0448H, 044AH)
202 // Register 00 : Display mode.
203 bool display_on[2]; // CL11-CL00 : bit3-0
204 bool one_layer_mode; // PMODE : bit4
205 // Register 11: Priority mode.
206 uint8_t vout_palette_mode;
208 bool video_brightness; // false = high.
209 bool layer1_front; // if false, layer 0 is front.
211 // Video output registers. May be split to separate files?
212 // FMR50 Compatible registers. They are mostly dummy.
217 uint8_t r50_update_mode;
218 // MMIO? 000C:FF82H Not dummy?
219 uint8_t r50_dispmode;
220 // MMIO? 000C:FF83H Not dummy?
222 // MMIO? 000C:FF86H Not dummy?
224 // I/O FDA0H Not Dummy?
225 //uint8_t r50_sub_statreg;
229 uint8_t video_out_reg_addr; // I/O 0448H
230 uint8_t video_out_reg_data; // I/O 044AH
231 uint8_t video_out_regs[2];
239 //int event_id_hsw1; //??
240 //int event_id_hsw2; //??
247 void set_display(bool val);
248 void set_vblank(bool val);
249 void set_vsync(bool val);
250 void set_hsync(bool val);
253 bool render_a_line(int layer, int linenum, int xoffset, uint8_t *vramptr, uint32_t words);
254 void render_line_16(int layer, scrntype_t *framebuffer, uint8_t *vramptr, uint32_t words);
255 void render_line_256(int layer, scrntype_t *framebuffer, uint8_t *vramptr, uint32_t words);
256 void render_line_32768(int layer, scrntype_t *framebuffer, uint8_t *vramptr, uint32_t words);
257 void render_clear(int layer, scrntype_t *framebuffer);
260 TOWNS_CRTC(VM *parent_vm, EMU *parent_emu) : DEVICE(parent_vm, parent_emu)
262 initialize_output_signals(&outputs_int_vsync);
263 set_device_name(_T("FM-Towns CRTC"));
270 void write_signal(int id, uint32_t data, uint32_t mask);
271 uint32_t read_signal(int ch);
273 void write_io8(uint32_t addr, uint32_t data);
274 uint32_t read_io8(uint32_t addr);
276 void write_io16(uint32_t addr, uint32_t data);
277 uint32_t read_io16(uint32_t addr);
279 uint32_t read_data8(uint32_t addr);
280 uint32_t read_data16(uint32_t addr);
281 uint32_t read_data32(uint32_t addr);
283 void write_data8(uint32_t addr, uint32_t data);
284 void write_data16(uint32_t addr, uint32_t data);
285 void write_data32(uint32_t addr, uint32_t data);
286 void event_callback(int event_id, int err);
287 //void update_timing(int new_clocks, double new_frames_per_sec, int new_lines_per_frame);
288 void save_state(FILEIO* state_fio);
289 bool load_state(FILEIO* state_fio);
291 void set_context_vsync(DEVICE* device, int id, uint32_t mask)
293 register_output_signal(&outputs_vsync, device, id, mask);
295 uint16_t* get_regs_ptr()