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
131 class TOWNS_CRTC : public DEVICE
135 outputs_t outputs_int_vsync; // Connect to int 11.
136 uint16_t regs[32]; // I/O 0442H, 0443H
137 bool regs_written[32];
138 uint8_t reg_ch; // I/O 0440H
141 // Not include around video input/dizitize features yet.
142 bool line_changed[2][TOWNS_CRTC_MAX_LINES];
144 double crtc_clock; //
145 // They are not saved.Must be calculate when loading.
146 double horiz_us, next_horiz_us; // (HST + 1) * clock
147 double horiz_width_posi_us, horiz_width_nega_us; // HSW1, HSW2
148 double vert_us, next_vert_us; // (VST +1) * horiz_us / 2.0
150 double vert_sync_pre_us; // VST1 * horiz_us / 2.0
151 double vert_sync_end_us; // VST2 * horiz_us / 2.0
154 double frames_per_sec;
156 uint32_t hstart_words[2]; // HSTART ((HDS[01] * clock) : Horizonal offset words (Related by ZH[01]). Maybe 0.
157 uint32_t hend_words[2]; // HEND ((HDE[01] * clock) : Horizonal offset words (Related by ZH[01]). Maybe 0.
158 uint32_t vstart_lines[2]; // VSTART ((VDS[01] * clock) : Horizonal offset words (Related by VH[01]).
159 uint32_t vend_lines[2]; // VEND ((VDE[01] * clock) : Horizonal offset words (Related by VH[01]).
161 uint32_t zoom_factor_vert; // Related display resolutions of two layers and zoom factors. Multiplied by 1024.
162 uint32_t zoom_factor_horiz; // Related display resolutions of two layers and zoom factors. Multiplied by 1024.
164 uint32_t line_count[2]; // Separate per layer.
166 int vert_line_count; // Not separate per layer.Total count.
168 int buffer_num; // Frame buffer number.
169 // Note: To display to real screen, use blending of OpenGL/DirectX
170 // from below framebuffers per layer if you can.
171 // And, recommand to use (hardware) shader to rendering (= not to use framebuffer of below) if enabled.
172 // Not recommanded to use draw_screen() type rendering.
173 // Rendering precesses may be heavily to use only CPU (I think). 20170107 K.Ohta.
176 uint8_t layer_colors[2];
177 uint16_t *vram_ptr[2]; // Layer [01] address.
178 uint32_t vram_size[2]; // Layer [01] size [bytes].
179 uint32_t vram_offset[2]; // Layer [01] address offset.
181 uint32_t layer_virtual_width[2];
182 uint32_t layer_virtual_height[2];
183 uint32_t layer_display_width[2];
184 uint32_t layer_display_height[2];
187 bool vdisp, vblank, vsync, hsync, hdisp, frame_in;
189 // Video output controller (I/O 0448H, 044AH)
190 // Register 00 : Display mode.
191 bool display_on[2]; // CL11-CL00 : bit3-0
192 bool one_layer_mode; // PMODE : bit4
193 // Register 11: Priority mode.
194 uint8_t vout_palette_mode;
196 bool video_brightness; // false = high.
197 bool layer1_front; // if false, layer 0 is front.
199 // Video output registers. May be split to separate files?
200 // FMR50 Compatible registers. They are mostly dummy.
205 uint8_t r50_update_mode;
206 // MMIO? 000C:FF82H Not dummy?
207 uint8_t r50_dispmode;
208 // MMIO? 000C:FF83H Not dummy?
210 // MMIO? 000C:FF86H Not dummy?
212 // I/O FDA0H Not Dummy?
213 //uint8_t r50_sub_statreg;
217 uint8_t video_out_reg_addr; // I/O 0448H
218 uint8_t video_out_reg_data; // I/O 044AH
219 uint8_t video_out_regs[2];
227 //int event_id_hsw1; //??
228 //int event_id_hsw2; //??
235 void set_display(bool val);
236 void set_vblank(bool val);
237 void set_vsync(bool val);
238 void set_hsync(bool val);
241 bool render_a_line(int layer, int linenum, int xoffset, uint8_t *vramptr, uint32_t words);
242 void render_line_16(int layer, scrntype_t *framebuffer, uint8_t *vramptr, uint32_t words);
243 void render_line_256(int layer, scrntype_t *framebuffer, uint8_t *vramptr, uint32_t words);
244 void render_line_32768(int layer, scrntype_t *framebuffer, uint8_t *vramptr, uint32_t words);
245 void render_clear(int layer, scrntype_t *framebuffer);
248 TOWNS_CRTC(VM *parent_vm, EMU *parent_emu) : DEVICE(parent_vm, parent_emu)
250 initialize_output_signals(&outputs_int_vsync);
251 set_device_name(_T("FM-Towns CRTC"));
258 void write_signal(int id, uint32_t data, uint32_t mask);
259 uint32_t read_signal(int ch);
261 void write_io8(uint32_t addr, uint32_t data);
262 uint32_t read_io8(uint32_t addr);
264 void write_io16(uint32_t addr, uint32_t data);
265 uint32_t read_io16(uint32_t addr);
267 uint32_t read_data8(uint32_t addr);
268 uint32_t read_data16(uint32_t addr);
269 uint32_t read_data32(uint32_t addr);
271 void write_data8(uint32_t addr, uint32_t data);
272 void write_data16(uint32_t addr, uint32_t data);
273 void write_data32(uint32_t addr, uint32_t data);
274 void event_callback(int event_id, int err);
275 //void update_timing(int new_clocks, double new_frames_per_sec, int new_lines_per_frame);
276 void save_state(FILEIO* state_fio);
277 bool load_state(FILEIO* state_fio);
279 void set_context_vsync(DEVICE* device, int id, uint32_t mask)
281 register_output_signal(&outputs_vsync, device, id, mask);
283 uint16_t* get_regs_ptr()