1 // license:BSD-3-Clause
2 // copyright-holders:Angelo Salese
3 /********************************************************************************************
4 
5     PC-8801 (c) 1981 NEC
6 
7 ********************************************************************************************/
8 #ifndef MAME_INCLUDES_PC8801_H
9 #define MAME_INCLUDES_PC8801_H
10 
11 #pragma once
12 
13 
14 #include "cpu/z80/z80.h"
15 #include "bus/centronics/ctronics.h"
16 #include "imagedev/cassette.h"
17 #include "imagedev/floppy.h"
18 #include "machine/i8214.h"
19 #include "machine/i8251.h"
20 #include "machine/i8255.h"
21 #include "machine/timer.h"
22 #include "machine/upd1990a.h"
23 #include "machine/upd765.h"
24 #include "sound/2203intf.h"
25 #include "sound/2608intf.h"
26 #include "sound/beep.h"
27 #include "emupal.h"
28 #include "screen.h"
29 #include "softlist.h"
30 #include "speaker.h"
31 
32 #define USE_PROPER_I8214 0
33 
34 #define I8214_TAG       "i8214"
35 #define UPD1990A_TAG    "upd1990a"
36 #define I8251_TAG       "i8251"
37 
38 class pc8801_state : public driver_device
39 {
40 public:
pc8801_state(const machine_config & mconfig,device_type type,const char * tag)41 	pc8801_state(const machine_config &mconfig, device_type type, const char *tag)
42 		: driver_device(mconfig, type, tag)
43 		, m_maincpu(*this, "maincpu")
44 		, m_screen(*this, "screen")
45 		, m_fdccpu(*this, "fdccpu")
46 		, m_fdc(*this, "upd765")
47 		, m_fdd(*this, "upd765:%u", 0U)
48 		, m_pic(*this, I8214_TAG)
49 		, m_rtc(*this, UPD1990A_TAG)
50 		, m_cassette(*this, "cassette")
51 		, m_beeper(*this, "beeper")
52 		, m_opna(*this, "opna")
53 		, m_opn(*this, "opn")
54 		, m_palette(*this, "palette")
55 	{ }
56 
57 	void pc8801mc(machine_config &config);
58 	void pc8801fh(machine_config &config);
59 	void pc8801(machine_config &config);
60 	void pc8801ma(machine_config &config);
61 
62 protected:
63 	virtual void video_start() override;
64 	virtual void machine_start() override;
65 	virtual void machine_reset() override;
66 
67 private:
68 	struct crtc_t
69 	{
70 		uint8_t cmd,param_count,cursor_on,status,irq_mask;
71 		uint8_t param[8][5];
72 		uint8_t inverse;
73 	};
74 
75 	struct mouse_t
76 	{
77 		uint8_t phase;
78 		uint8_t x,y;
79 		attotime time;
80 	};
81 
82 	required_device<cpu_device> m_maincpu;
83 	required_device<screen_device> m_screen;
84 	required_device<cpu_device> m_fdccpu;
85 	required_device<upd765a_device> m_fdc;
86 	required_device_array<floppy_connector, 2> m_fdd;
87 	optional_device<i8214_device> m_pic;
88 	required_device<upd1990a_device> m_rtc;
89 	required_device<cassette_image_device> m_cassette;
90 	required_device<beep_device> m_beeper;
91 	required_device<ym2608_device> m_opna;
92 	required_device<ym2203_device> m_opn;
93 	required_device<palette_device> m_palette;
94 
95 	std::unique_ptr<uint8_t[]> m_work_ram;
96 	std::unique_ptr<uint8_t[]> m_hi_work_ram;
97 	std::unique_ptr<uint8_t[]> m_ext_work_ram;
98 	std::unique_ptr<uint8_t[]> m_gvram;
99 	uint8_t *m_n80rom;
100 	uint8_t *m_n88rom;
101 	uint8_t *m_kanji_rom;
102 	uint8_t *m_cg_rom;
103 
104 	uint8_t m_i8255_0_pc;
105 	uint8_t m_i8255_1_pc;
106 	uint8_t m_fdc_irq_opcode;
107 	uint8_t m_ext_rom_bank;
108 	uint8_t m_gfx_ctrl;
109 	uint8_t m_vram_sel;
110 	uint8_t m_misc_ctrl;
111 	uint8_t m_device_ctrl_data;
112 	uint8_t m_window_offset_bank;
113 	uint8_t m_layer_mask;
114 	uint16_t m_dma_counter[4];
115 	uint16_t m_dma_address[4];
116 	uint8_t m_alu_reg[3];
117 	uint8_t m_dmac_mode;
118 	uint8_t m_alu_ctrl1;
119 	uint8_t m_alu_ctrl2;
120 	uint8_t m_extram_mode;
121 	uint8_t m_extram_bank;
122 	uint8_t m_txt_width;
123 	uint8_t m_txt_color;
124 #if USE_PROPER_I8214
125 	uint8_t m_timer_irq_mask;
126 	uint8_t m_vblank_irq_mask;
127 	uint8_t m_sound_irq_mask;
128 	uint8_t m_int_state;
129 #else
130 	uint8_t m_i8214_irq_level;
131 	uint8_t m_vrtc_irq_mask;
132 	uint8_t m_vrtc_irq_latch;
133 	uint8_t m_timer_irq_mask;
134 	uint8_t m_timer_irq_latch;
135 	uint8_t m_sound_irq_mask;
136 	uint8_t m_sound_irq_latch;
137 	uint8_t m_sound_irq_pending;
138 #endif
139 	uint8_t m_has_clock_speed;
140 	uint8_t m_clock_setting;
141 	uint8_t m_baudrate_val;
142 	uint8_t m_has_dictionary;
143 	uint8_t m_dic_ctrl;
144 	uint8_t m_dic_bank;
145 	uint8_t m_has_cdrom;
146 	uint8_t m_cdrom_reg[0x10];
147 	crtc_t m_crtc;
148 	mouse_t m_mouse;
149 	struct { uint8_t r, g, b; } m_palram[8];
150 	uint8_t m_dmac_ff;
151 	uint32_t m_knj_addr[2];
152 	uint32_t m_extram_size;
153 	uint8_t m_has_opna;
154 
155 	uint8_t pc8801_alu_r(offs_t offset);
156 	void pc8801_alu_w(offs_t offset, uint8_t data);
157 	uint8_t pc8801_wram_r(offs_t offset);
158 	void pc8801_wram_w(offs_t offset, uint8_t data);
159 	uint8_t pc8801_ext_wram_r(offs_t offset);
160 	void pc8801_ext_wram_w(offs_t offset, uint8_t data);
161 	uint8_t pc8801_nbasic_rom_r(offs_t offset);
162 	uint8_t pc8801_n88basic_rom_r(offs_t offset);
163 	uint8_t pc8801_gvram_r(offs_t offset);
164 	void pc8801_gvram_w(offs_t offset, uint8_t data);
165 	uint8_t pc8801_high_wram_r(offs_t offset);
166 	void pc8801_high_wram_w(offs_t offset, uint8_t data);
167 	uint8_t pc8801ma_dic_r(offs_t offset);
168 	uint8_t pc8801_cdbios_rom_r(offs_t offset);
169 	uint8_t pc8801_mem_r(offs_t offset);
170 	void pc8801_mem_w(offs_t offset, uint8_t data);
171 	uint8_t pc8801_ctrl_r();
172 	void pc8801_ctrl_w(uint8_t data);
173 	uint8_t pc8801_ext_rom_bank_r();
174 	void pc8801_ext_rom_bank_w(uint8_t data);
175 	void pc8801_gfx_ctrl_w(uint8_t data);
176 	uint8_t pc8801_vram_select_r();
177 	void pc8801_vram_select_w(offs_t offset, uint8_t data);
178 	void pc8801_irq_level_w(uint8_t data);
179 	void pc8801_irq_mask_w(uint8_t data);
180 	uint8_t pc8801_window_bank_r();
181 	void pc8801_window_bank_w(uint8_t data);
182 	void pc8801_window_bank_inc_w(uint8_t data);
183 	uint8_t pc8801_misc_ctrl_r();
184 	void pc8801_misc_ctrl_w(uint8_t data);
185 	void pc8801_bgpal_w(uint8_t data);
186 	void pc8801_palram_w(offs_t offset, uint8_t data);
187 	void pc8801_layer_masking_w(uint8_t data);
188 	uint8_t pc8801_crtc_param_r();
189 	void pc88_crtc_param_w(uint8_t data);
190 	uint8_t pc8801_crtc_status_r();
191 	void pc88_crtc_cmd_w(uint8_t data);
192 	uint8_t pc8801_dmac_r(offs_t offset);
193 	void pc8801_dmac_w(offs_t offset, uint8_t data);
194 	uint8_t pc8801_dmac_status_r();
195 	void pc8801_dmac_mode_w(uint8_t data);
196 	uint8_t pc8801_extram_mode_r();
197 	void pc8801_extram_mode_w(uint8_t data);
198 	uint8_t pc8801_extram_bank_r();
199 	void pc8801_extram_bank_w(uint8_t data);
200 	void pc8801_alu_ctrl1_w(uint8_t data);
201 	void pc8801_alu_ctrl2_w(uint8_t data);
202 	void pc8801_pcg8100_w(offs_t offset, uint8_t data);
203 	void pc8801_txt_cmt_ctrl_w(uint8_t data);
204 	uint8_t pc8801_kanji_r(offs_t offset);
205 	void pc8801_kanji_w(offs_t offset, uint8_t data);
206 	uint8_t pc8801_kanji_lv2_r(offs_t offset);
207 	void pc8801_kanji_lv2_w(offs_t offset, uint8_t data);
208 	void pc8801_dic_bank_w(uint8_t data);
209 	void pc8801_dic_ctrl_w(uint8_t data);
210 	uint8_t pc8801_cdrom_r();
211 	void pc8801_cdrom_w(offs_t offset, uint8_t data);
212 	uint8_t pc8801_cpuclock_r();
213 	uint8_t pc8801_baudrate_r();
214 	void pc8801_baudrate_w(uint8_t data);
215 	void pc8801_rtc_w(uint8_t data);
216 	void upd765_mc_w(uint8_t data);
217 	uint8_t upd765_tc_r();
218 	void fdc_irq_vector_w(uint8_t data);
219 	void fdc_drive_mode_w(uint8_t data);
220 	DECLARE_WRITE_LINE_MEMBER(txdata_callback);
221 	DECLARE_WRITE_LINE_MEMBER(rxrdy_w);
222 	uint8_t pc8801_sound_board_r(offs_t offset);
223 	void pc8801_sound_board_w(offs_t offset, uint8_t data);
224 	uint8_t pc8801_opna_r(offs_t offset);
225 	void pc8801_opna_w(offs_t offset, uint8_t data);
226 	uint8_t pc8801_unk_r();
227 	void pc8801_unk_w(uint8_t data);
228 
229 	uint8_t pc8801_pixel_clock(void);
230 	void pc8801_dynamic_res_change(void);
231 	void draw_bitmap_3bpp(bitmap_ind16 &bitmap,const rectangle &cliprect);
232 	void draw_bitmap_1bpp(bitmap_ind16 &bitmap,const rectangle &cliprect);
233 	uint8_t calc_cursor_pos(int x,int y,int yi);
234 	uint8_t extract_text_attribute(uint32_t address,int x, uint8_t width, uint8_t &non_special);
235 	void pc8801_draw_char(bitmap_ind16 &bitmap,int x,int y,int pal,uint8_t gfx_mode,uint8_t reverse,uint8_t secret,
236 							uint8_t blink,uint8_t upper,uint8_t lower,int y_size,int width, uint8_t non_special);
237 	void draw_text(bitmap_ind16 &bitmap,int y_size, uint8_t width);
238 
239 	uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
240 	void pc8801_palette(palette_device &palette) const;
241 	void pc8801_io(address_map &map);
242 	void pc8801_mem(address_map &map);
243 	void pc8801fdc_io(address_map &map);
244 	void pc8801fdc_mem(address_map &map);
245 	DECLARE_MACHINE_RESET(pc8801_clock_speed);
246 	DECLARE_MACHINE_RESET(pc8801_dic);
247 	DECLARE_MACHINE_RESET(pc8801_cdrom);
248 	INTERRUPT_GEN_MEMBER(pc8801_vrtc_irq);
249 	TIMER_CALLBACK_MEMBER(pc8801fd_upd765_tc_to_zero);
250 	TIMER_DEVICE_CALLBACK_MEMBER(pc8801_rtc_irq);
251 	uint8_t cpu_8255_c_r();
252 	void cpu_8255_c_w(uint8_t data);
253 	uint8_t fdc_8255_c_r();
254 	void fdc_8255_c_w(uint8_t data);
255 	uint8_t opn_porta_r();
256 	uint8_t opn_portb_r();
257 	IRQ_CALLBACK_MEMBER(pc8801_irq_callback);
258 	DECLARE_WRITE_LINE_MEMBER(pc8801_sound_irq);
259 };
260 
261 #endif // MAME_INCLUDES_PC8801_H
262