1 // license:BSD-3-Clause 2 // copyright-holders:Olivier Galibert 3 #ifndef MAME_INCLUDES_MODEL1_H 4 #define MAME_INCLUDES_MODEL1_H 5 6 #pragma once 7 8 #include "audio/dsbz80.h" 9 #include "audio/segam1audio.h" 10 11 #include "cpu/mb86233/mb86233.h" 12 #include "cpu/v60/v60.h" 13 #include "machine/i8251.h" 14 #include "machine/gen_fifo.h" 15 #include "machine/mb8421.h" 16 #include "machine/m1comm.h" 17 #include "machine/timer.h" 18 #include "video/segaic24.h" 19 20 #include "emupal.h" 21 #include "screen.h" 22 23 #include <glm/vec3.hpp> 24 25 #include <functional> 26 27 class model1_state : public driver_device 28 { 29 public: model1_state(const machine_config & mconfig,device_type type,const char * tag)30 model1_state(const machine_config &mconfig, device_type type, const char *tag) 31 : driver_device(mconfig, type, tag) 32 , m_maincpu(*this, "maincpu") 33 , m_dpram(*this, "dpram") 34 , m_m1audio(*this, M1AUDIO_TAG) 35 , m_m1uart(*this, "m1uart") 36 , m_m1comm(*this, "m1comm") 37 , m_dsbz80(*this, DSBZ80_TAG) 38 , m_tgp_copro(*this, "tgp_copro") 39 , m_screen(*this, "screen") 40 , m_copro_fifo_in(*this, "copro_fifo_in") 41 , m_copro_fifo_out(*this, "copro_fifo_out") 42 , m_poly_rom(*this, "polygons") 43 , m_copro_tables(*this, "copro_tables") 44 , m_copro_data(*this, "copro_data") 45 , m_display_list0(*this, "display_list0") 46 , m_display_list1(*this, "display_list1") 47 , m_color_xlat(*this, "color_xlat") 48 , m_paletteram16(*this, "palette") 49 , m_palette(*this, "palette") 50 , m_tiles(*this, "tile") 51 , m_digits(*this, "digit%u", 0U) 52 , m_outs(*this, "out%u", 0U) 53 { 54 } 55 56 void model1(machine_config &config); 57 void vf(machine_config &config); 58 void vr(machine_config &config); 59 void vformula(machine_config &config); 60 void swa(machine_config &config); 61 void wingwar(machine_config &config); 62 void wingwar360(machine_config &config); 63 void netmerc(machine_config &config); 64 65 struct spoint_t 66 { 67 int32_t x = 0, y = 0; 68 }; 69 70 struct point_t 71 { 72 float x = 0, y = 0, z = 0; 73 float xx = 0, yy = 0; 74 spoint_t s; 75 }; 76 77 class quad_t 78 { 79 public: quad_t()80 quad_t() { } quad_t(int ccol,float cz,point_t * p0,point_t * p1,point_t * p2,point_t * p3)81 quad_t(int ccol, float cz, point_t* p0, point_t* p1, point_t* p2, point_t* p3) 82 : p{ p0, p1, p2, p3 } 83 , z(cz) 84 , col(ccol) 85 { 86 } 87 88 int compare(const quad_t* other) const; 89 90 point_t *p[4] = { nullptr, nullptr, nullptr, nullptr }; 91 float z = 0; 92 int col = 0; 93 }; 94 95 private: 96 // Machine 97 virtual void machine_start() override; 98 virtual void machine_reset() override; 99 100 void bank_w(offs_t offset, u16 data, u16 mem_mask = ~0); 101 102 TIMER_DEVICE_CALLBACK_MEMBER(model1_interrupt); 103 IRQ_CALLBACK_MEMBER(irq_callback); 104 105 // TGP 106 u16 fifoin_status_r(); 107 108 u16 v60_copro_fifo_r(offs_t offset); 109 void v60_copro_fifo_w(offs_t offset, u16 data); 110 u16 v60_copro_ram_adr_r(); 111 void v60_copro_ram_adr_w(offs_t offset, u16 data, u16 mem_mask = ~0); 112 u16 v60_copro_ram_r(offs_t offset); 113 void v60_copro_ram_w(offs_t offset, u16 data, u16 mem_mask = ~0); 114 115 void copro_sincos_w(offs_t offset, u32 data, u32 mem_mask = ~0); 116 u32 copro_sincos_r(offs_t offset); 117 void copro_inv_w(offs_t offset, u32 data, u32 mem_mask = ~0); 118 u32 copro_inv_r(offs_t offset); 119 void copro_isqrt_w(offs_t offset, u32 data, u32 mem_mask = ~0); 120 u32 copro_isqrt_r(offs_t offset); 121 void copro_atan_w(offs_t offset, u32 data, u32 mem_mask = ~0); 122 u32 copro_atan_r(); 123 void copro_data_w(offs_t offset, u32 data, u32 mem_mask = ~0); 124 u32 copro_data_r(offs_t offset); 125 void copro_ramadr_w(offs_t offset, u32 data, u32 mem_mask = ~0); 126 u32 copro_ramadr_r(offs_t offset); 127 void copro_ramdata_w(offs_t offset, u32 data, u32 mem_mask = ~0); 128 u32 copro_ramdata_r(offs_t offset); 129 130 void copro_reset(); 131 132 u32 m_copro_sincos_base; 133 u32 m_copro_inv_base; 134 u32 m_copro_isqrt_base; 135 u32 m_copro_atan_base[4]; 136 u32 m_copro_data_base; 137 u32 m_copro_ram_adr[4]; 138 139 uint16_t m_r360_state; 140 uint8_t r360_r(); 141 void r360_w(uint8_t data); 142 143 // Rendering 144 virtual void video_start() override; 145 u16 model1_listctl_r(offs_t offset); 146 void model1_listctl_w(offs_t offset, u16 data, u16 mem_mask = ~0); 147 148 uint32_t screen_update_model1(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); 149 DECLARE_WRITE_LINE_MEMBER(screen_vblank_model1); 150 151 struct lightparam_t 152 { 153 float a = 0; 154 float d = 0; 155 float s = 0; 156 int p = 0; 157 }; 158 159 class view_t 160 { 161 public: view_t()162 view_t() { 163 light.x = 0; 164 light.y = 0; 165 light.z = 0; 166 } 167 168 void init_translation_matrix(); 169 170 void set_viewport(float xcenter, float ycenter, float xl, float xr, float yb, float yt); 171 void set_lightparam(int index, float diffuse, float ambient, float specular, int power); 172 void set_zoom(float x, float y); 173 void set_light_direction(float x, float y, float z); 174 void set_translation_matrix(float* mat); 175 void set_view_translation(float x, float y); 176 177 void project_point(point_t *p) const; 178 void project_point_direct(point_t *p) const; 179 180 void transform_vector(glm::vec3& p) const; 181 void transform_point(point_t *p) const; 182 183 void recompute_frustum(); 184 185 int xc = 0, yc = 0, x1 = 0, y1 = 0, x2 = 0, y2 = 0; 186 float zoomx = 0, zoomy = 0, viewx = 0, viewy = 0; 187 float a_bottom = 0, a_top = 0, a_left = 0, a_right = 0; 188 float vxx = 0, vyy = 0, vzz = 0, ayy = 0, ayyc = 0, ayys = 0; 189 float translation[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 190 glm::vec3 light; 191 lightparam_t lightparams[32]; 192 }; 193 194 void model1_io(address_map &map); 195 void model1_mem(address_map &map); 196 void model1_comm_mem(address_map &map); 197 198 void copro_prog_map(address_map &map); 199 void copro_data_map(address_map &map); 200 void copro_external_map(address_map &map); 201 void copro_io_map(address_map &map); 202 void copro_rf_map(address_map &map); 203 204 void polhemus_map(address_map &map); 205 206 // Machine 207 void irq_raise(int level); 208 void irq_init(); 209 void irq_control_w(u8 data); 210 211 uint8_t m_irq_status; 212 int m_last_irq; 213 214 // Devices 215 required_device<v60_device> m_maincpu; // V60 216 required_device<mb8421_device> m_dpram; 217 required_device<segam1audio_device> m_m1audio; // Model 1 standard sound board 218 required_device<i8251_device> m_m1uart; 219 optional_device<m1comm_device> m_m1comm; // Model 1 communication board 220 optional_device<dsbz80_device> m_dsbz80; // Digital Sound Board 221 optional_device<mb86233_device> m_tgp_copro; 222 required_device<screen_device> m_screen; 223 required_device<generic_fifo_u32_device> m_copro_fifo_in, m_copro_fifo_out; 224 225 required_region_ptr<uint32_t> m_poly_rom; 226 required_region_ptr<uint32_t> m_copro_tables; 227 optional_memory_region m_copro_data; 228 229 required_shared_ptr<uint16_t> m_display_list0; 230 required_shared_ptr<uint16_t> m_display_list1; 231 required_shared_ptr<uint16_t> m_color_xlat; 232 233 // Sound 234 int m_sound_irq; 235 236 // TGP FIFO 237 void fifoout_push(uint32_t data); 238 void fifoout_push_f(float data); 239 uint32_t fifoin_pop(); 240 float fifoin_pop_f(); 241 uint16_t ram_get_i(); 242 float ram_get_f(); 243 u32 m_v60_copro_fifo_r, m_v60_copro_fifo_w; 244 245 // TGP 246 void tgp_reset(); 247 class clipper_t 248 { 249 public: clipper_t()250 clipper_t() 251 : m_isclipped(nullptr) 252 , m_clip(nullptr) 253 { 254 } 255 clipper_t(std::function<bool (view_t *,point_t *)> isclipped,std::function<void (view_t *,point_t *,point_t *,point_t *)> clip)256 clipper_t(std::function<bool(view_t*, point_t*)> isclipped, std::function<void(view_t*, point_t*, point_t*, point_t*)> clip) 257 : m_isclipped(isclipped) 258 , m_clip(clip) 259 { 260 } 261 262 std::function<bool(view_t*, point_t*)> m_isclipped; 263 std::function<void(view_t*, point_t*, point_t*, point_t*)> m_clip; 264 }; 265 266 std::unique_ptr<view_t> m_view; 267 std::unique_ptr<point_t[]> m_pointdb; 268 point_t *m_pointpt; 269 std::unique_ptr<quad_t[]> m_quaddb; 270 quad_t *m_quadpt; 271 std::unique_ptr<quad_t *[]> m_quadind; 272 273 uint16_t m_v60_copro_ram_adr; 274 uint16_t m_v60_copro_ram_latch[2]; 275 std::unique_ptr<uint32_t[]> m_copro_ram_data; 276 uint16_t m_listctl[2]; 277 uint16_t *m_glist; 278 bool m_render_done; 279 280 std::unique_ptr<uint16_t[]> m_tgp_ram; 281 std::unique_ptr<uint32_t[]> m_poly_ram; 282 283 // Rendering helper functions 284 uint32_t readi(int adr) const; 285 int16_t readi16(int adr) const; 286 float readf(int adr) const; 287 void cross_product(point_t* o, const point_t* p, const point_t* q) const; 288 float view_determinant(const point_t *p1, const point_t *p2, const point_t *p3) const; 289 290 static bool fclip_isc_bottom(view_t*, point_t*); 291 static bool fclip_isc_top(view_t*, point_t*); 292 static bool fclip_isc_left(view_t*, point_t*); 293 static bool fclip_isc_right(view_t*, point_t*); 294 static void fclip_clip_bottom(view_t*, point_t*, point_t*, point_t*); 295 static void fclip_clip_top(view_t*, point_t*, point_t*, point_t*); 296 static void fclip_clip_left(view_t*, point_t*, point_t*, point_t*); 297 static void fclip_clip_right(view_t*, point_t*, point_t*, point_t*); 298 299 // Rendering 300 void tgp_render(bitmap_rgb32 &bitmap, const rectangle &cliprect); 301 void tgp_scan(); 302 303 void sort_quads() const; 304 void unsort_quads() const; 305 void draw_quads(bitmap_rgb32 &bitmap, const rectangle &cliprect); 306 static void recompute_frustum(view_t *view); 307 static void draw_hline(bitmap_rgb32 &bitmap, int x1, int x2, int y, int color); 308 static void draw_hline_moired(bitmap_rgb32 &bitmap, int x1, int x2, int y, int color); 309 static void fill_slope(bitmap_rgb32 &bitmap, view_t *view, int color, int32_t x1, int32_t x2, int32_t sl1, int32_t sl2, int32_t y1, int32_t y2, int32_t *nx1, int32_t *nx2); 310 static void fill_line(bitmap_rgb32 &bitmap, view_t *view, int color, int32_t y, int32_t x1, int32_t x2); 311 void fill_quad(bitmap_rgb32 &bitmap, view_t *view, const quad_t& q) const; 312 313 void fclip_push_quad_next(int level, quad_t& q, point_t *p1, point_t *p2, point_t *p3, point_t *p4); 314 void fclip_push_quad(int level, quad_t& q); 315 316 static float min4f(float a, float b, float c, float d); 317 static float max4f(float a, float b, float c, float d); 318 static float compute_specular(glm::vec3& normal, glm::vec3& light, float diffuse,int lmode); 319 320 int push_direct(int list_offset); 321 int draw_direct(bitmap_rgb32 &bitmap, const rectangle &cliprect, int list_offset); 322 int skip_direct(int list_offset) const; 323 void push_object(uint32_t tex_adr, uint32_t poly_adr, uint32_t size); 324 void draw_objects(bitmap_rgb32 &bitmap, const rectangle &cliprect); 325 326 void set_current_render_list(); 327 int get_list_number(); 328 void end_frame(); 329 330 clipper_t m_clipfn[4]; 331 332 // run-time rendering 333 uint16_t* m_display_list_current; 334 335 optional_shared_ptr<uint16_t> m_paletteram16; 336 required_device<palette_device> m_palette; 337 required_device<segas24_tile_device> m_tiles; 338 339 // I/O related 340 output_finder<2> m_digits; 341 output_finder<8> m_outs; 342 u8 dpram_r(offs_t offset); 343 void gen_outputs_w(uint8_t data); 344 void vf_outputs_w(uint8_t data); 345 void vr_outputs_w(uint8_t data); 346 void swa_outputs_w(uint8_t data); 347 void wingwar_outputs_w(uint8_t data); 348 void wingwar360_outputs_w(uint8_t data); 349 void netmerc_outputs_w(uint8_t data); 350 void drive_board_w(uint8_t data); 351 }; 352 353 #endif // MAME_INCLUDES_MODEL1_H 354