1 // license:GPL-2.0+ 2 // copyright-holders:Raphael Nabet 3 /***************************************************************************** 4 * 5 * includes/pdp1.h 6 * 7 ****************************************************************************/ 8 9 #ifndef MAME_INCLUDES_PDP1_H 10 #define MAME_INCLUDES_PDP1_H 11 12 #include "cpu/pdp1/pdp1.h" 13 #include "video/crt.h" 14 #include "emupal.h" 15 16 /* defines for each bit and mask in input port "CSW" */ 17 enum 18 { 19 /* bit numbers */ 20 pdp1_control_bit = 0, 21 22 pdp1_extend_bit = 1, 23 pdp1_start_nobrk_bit= 2, 24 pdp1_start_brk_bit = 3, 25 pdp1_stop_bit = 4, 26 pdp1_continue_bit = 5, 27 pdp1_examine_bit = 6, 28 pdp1_deposit_bit = 7, 29 pdp1_read_in_bit = 8, 30 pdp1_reader_bit = 9, 31 pdp1_tape_feed_bit = 10, 32 pdp1_single_step_bit= 11, 33 pdp1_single_inst_bit= 12, 34 35 /* masks */ 36 pdp1_control = (1 << pdp1_control_bit), 37 pdp1_extend = (1 << pdp1_extend_bit), 38 pdp1_start_nobrk = (1 << pdp1_start_nobrk_bit), 39 pdp1_start_brk = (1 << pdp1_start_brk_bit), 40 pdp1_stop = (1 << pdp1_stop_bit), 41 pdp1_continue = (1 << pdp1_continue_bit), 42 pdp1_examine = (1 << pdp1_examine_bit), 43 pdp1_deposit = (1 << pdp1_deposit_bit), 44 pdp1_read_in = (1 << pdp1_read_in_bit), 45 pdp1_reader = (1 << pdp1_reader_bit), 46 pdp1_tape_feed = (1 << pdp1_tape_feed_bit), 47 pdp1_single_step = (1 << pdp1_single_step_bit), 48 pdp1_single_inst = (1 << pdp1_single_inst_bit) 49 }; 50 51 /* defines for each bit in input port pdp1_spacewar_controllers*/ 52 #define ROTATE_LEFT_PLAYER1 0x01 53 #define ROTATE_RIGHT_PLAYER1 0x02 54 #define THRUST_PLAYER1 0x04 55 #define FIRE_PLAYER1 0x08 56 #define ROTATE_LEFT_PLAYER2 0x10 57 #define ROTATE_RIGHT_PLAYER2 0x20 58 #define THRUST_PLAYER2 0x40 59 #define FIRE_PLAYER2 0x80 60 #define HSPACE_PLAYER1 0x100 61 #define HSPACE_PLAYER2 0x200 62 63 /* defines for each field in input port pdp1_config */ 64 enum 65 { 66 pdp1_config_extend_bit = 0, 67 pdp1_config_extend_mask = 0x3, /* 2 bits */ 68 pdp1_config_hw_mul_div_bit = 2, 69 pdp1_config_hw_mul_div_mask = 0x1, 70 /*pdp1_config_hw_obsolete_bit = 3, 71 pdp1_config_hw_obsolete_mask = 0x1,*/ 72 pdp1_config_type_20_sbs_bit = 4, 73 pdp1_config_type_20_sbs_mask = 0x1, 74 pdp1_config_lightpen_bit = 5, 75 pdp1_config_lightpen_mask = 0x1 76 }; 77 78 /* defines for each field in input port pdp1_lightpen_state */ 79 enum 80 { 81 pdp1_lightpen_down_bit = 0, 82 pdp1_lightpen_smaller_bit = 1, 83 pdp1_lightpen_larger_bit = 2, 84 85 pdp1_lightpen_down = (1 << pdp1_lightpen_down_bit), 86 pdp1_lightpen_smaller = (1 << pdp1_lightpen_smaller_bit), 87 pdp1_lightpen_larger = (1 << pdp1_lightpen_larger_bit) 88 }; 89 90 /* defines for our font */ 91 enum 92 { 93 pdp1_charnum = /*104*/128, /* ASCII set + 8 special characters */ 94 /* for whatever reason, 104 breaks some characters */ 95 96 pdp1_fontdata_size = 8 * pdp1_charnum 97 }; 98 99 enum 100 { 101 /* size and position of crt window */ 102 crt_window_width = 512, 103 crt_window_height = 512, 104 crt_window_offset_x = 0, 105 crt_window_offset_y = 0, 106 /* size and position of operator control panel window */ 107 panel_window_width = 384, 108 panel_window_height = 128, 109 panel_window_offset_x = crt_window_width, 110 panel_window_offset_y = 0, 111 /* size and position of typewriter window */ 112 typewriter_window_width = 640, 113 typewriter_window_height = 160, 114 typewriter_window_offset_x = 0, 115 typewriter_window_offset_y = crt_window_height 116 }; 117 118 enum 119 { 120 total_width = crt_window_width + panel_window_width, 121 total_height = crt_window_height + typewriter_window_height, 122 123 /* respect 4:3 aspect ratio to keep pixels square */ 124 virtual_width_1 = ((total_width+3)/4)*4, 125 virtual_height_1 = ((total_height+2)/3)*3, 126 virtual_width_2 = virtual_height_1*4/3, 127 virtual_height_2 = virtual_width_1*3/4, 128 virtual_width = (virtual_width_1 > virtual_width_2) ? virtual_width_1 : virtual_width_2, 129 virtual_height = (virtual_height_1 > virtual_height_2) ? virtual_height_1 : virtual_height_2 130 }; 131 132 enum 133 { /* refresh rate in Hz: can be changed at will */ 134 refresh_rate = 60 135 }; 136 137 /* Color codes */ 138 enum 139 { 140 /* first pen_crt_num_levels colors used for CRT (with remanence) */ 141 pen_crt_num_levels = 69, 142 pen_crt_max_intensity = pen_crt_num_levels-1, 143 144 /* next colors used for control panel and typewriter */ 145 pen_black = pen_crt_num_levels, 146 pen_white, 147 pen_green, 148 pen_dk_green, 149 pen_red, 150 pen_lt_gray, 151 152 /* color constants for control panel */ 153 pen_panel_bg = pen_black, 154 pen_panel_caption = pen_white, 155 color_panel_caption = 0, 156 pen_switch_nut = pen_lt_gray, 157 pen_switch_button = pen_white, 158 pen_lit_lamp = pen_green, 159 pen_unlit_lamp = pen_dk_green, 160 161 /* color constants for typewriter */ 162 pen_typewriter_bg = pen_white, 163 color_typewriter_black = 1, 164 color_typewriter_red = 2, 165 166 /* color constants used for light pen */ 167 pen_lightpen_nonpressed = pen_red, 168 pen_lightpen_pressed = pen_green 169 }; 170 171 class pdp1_state; 172 173 // tape reader device 174 class pdp1_readtape_image_device : public device_t, 175 public device_image_interface 176 { 177 public: 178 // construction/destruction 179 pdp1_readtape_image_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0U); 180 st_ptr()181 auto st_ptr() { return m_st_ptr.bind(); } 182 183 void iot_rpa(int op2, int nac, int mb, int &io, int ac); 184 void iot_rpb(int op2, int nac, int mb, int &io, int ac); 185 void iot_rrb(int op2, int nac, int mb, int &io, int ac); 186 187 protected: 188 // device-level overrides 189 virtual void device_resolve_objects() override; 190 virtual void device_start() override; 191 192 // image-level overrides image_type()193 virtual iodevice_t image_type() const noexcept override { return IO_PUNCHTAPE; } 194 is_readable()195 virtual bool is_readable() const noexcept override { return true; } is_writeable()196 virtual bool is_writeable() const noexcept override { return false; } is_creatable()197 virtual bool is_creatable() const noexcept override { return false; } must_be_loaded()198 virtual bool must_be_loaded() const noexcept override { return false; } is_reset_on_load()199 virtual bool is_reset_on_load() const noexcept override { return false; } file_extensions()200 virtual const char *file_extensions() const noexcept override { return "tap,rim"; } 201 202 virtual image_init_result call_load() override; 203 virtual void call_unload() override; 204 205 public: 206 TIMER_CALLBACK_MEMBER(reader_callback); 207 208 int tape_read(uint8_t *reply); 209 void begin_tape_read(int binary, int nac); 210 211 required_device<pdp1_device> m_maincpu; 212 213 devcb_write_line m_st_ptr; 214 215 int m_motor_on; // 1-bit reader motor on 216 217 int m_rb; // 18-bit reader buffer 218 int m_rcl; // 1-bit reader clutch 219 int m_rc; // 2-bit reader counter 220 int m_rby; // 1-bit reader binary mode flip-flop 221 int m_rcp; // 1-bit reader "need a completion pulse" flip-flop 222 223 emu_timer *m_timer; // timer to simulate reader timing 224 }; 225 226 227 228 // tape puncher device 229 class pdp1_punchtape_image_device : public device_t, 230 public device_image_interface 231 { 232 public: 233 // construction/destruction 234 pdp1_punchtape_image_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0U); 235 st_ptp()236 auto st_ptp() { return m_st_ptp.bind(); } 237 238 void iot_ppa(int op2, int nac, int mb, int &io, int ac); 239 void iot_ppb(int op2, int nac, int mb, int &io, int ac); 240 241 protected: 242 // device-level overrides 243 virtual void device_resolve_objects() override; 244 virtual void device_start() override; 245 246 // image-level overrides image_type()247 virtual iodevice_t image_type() const noexcept override { return IO_PUNCHTAPE; } 248 is_readable()249 virtual bool is_readable() const noexcept override { return false; } is_writeable()250 virtual bool is_writeable() const noexcept override { return true; } is_creatable()251 virtual bool is_creatable() const noexcept override { return true; } must_be_loaded()252 virtual bool must_be_loaded() const noexcept override { return false; } is_reset_on_load()253 virtual bool is_reset_on_load() const noexcept override { return false; } file_extensions()254 virtual const char *file_extensions() const noexcept override { return "tap,rim"; } 255 256 virtual image_init_result call_load() override; 257 virtual void call_unload() override; 258 259 public: 260 TIMER_CALLBACK_MEMBER(puncher_callback); 261 262 void tape_write(uint8_t data); 263 264 required_device<pdp1_device> m_maincpu; 265 266 devcb_write_line m_st_ptp; 267 268 emu_timer *m_timer; // timer to generate completion pulses 269 }; 270 271 272 273 // typewriter device 274 class pdp1_typewriter_device : public device_t, 275 public device_image_interface 276 { 277 public: 278 // construction/destruction 279 pdp1_typewriter_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0U); 280 st_tyo()281 auto st_tyo() { return m_st_tyo.bind(); } st_tyi()282 auto st_tyi() { return m_st_tyi.bind(); } 283 284 void iot_tyo(int op2, int nac, int mb, int &io, int ac); 285 void iot_tyi(int op2, int nac, int mb, int &io, int ac); 286 287 protected: 288 // device-level overrides 289 virtual void device_resolve_objects() override; 290 virtual void device_start() override; 291 292 // image-level overrides image_type()293 virtual iodevice_t image_type() const noexcept override { return IO_PRINTER; } 294 is_readable()295 virtual bool is_readable() const noexcept override { return false; } is_writeable()296 virtual bool is_writeable() const noexcept override { return true; } is_creatable()297 virtual bool is_creatable() const noexcept override { return true; } must_be_loaded()298 virtual bool must_be_loaded() const noexcept override { return false; } is_reset_on_load()299 virtual bool is_reset_on_load() const noexcept override { return false; } file_extensions()300 virtual const char *file_extensions() const noexcept override { return "typ"; } 301 302 virtual image_init_result call_load() override; 303 virtual void call_unload() override; 304 305 public: 306 TIMER_CALLBACK_MEMBER(tyo_callback); 307 308 void linefeed(); 309 void drawchar(int character); 310 void typewriter_out(uint8_t data); 311 312 void pdp1_keyboard(); 313 314 required_device<pdp1_device> m_maincpu; 315 required_device<pdp1_state> m_driver_state; 316 required_ioport_array<4> m_twr; 317 318 devcb_write_line m_st_tyo; 319 devcb_write_line m_st_tyi; 320 321 int m_tb; // typewriter buffer 322 323 emu_timer *m_tyo_timer; // timer to generate completion pulses 324 325 int m_old_typewriter_keys[4]; 326 int m_color; 327 bitmap_ind16 m_bitmap; 328 int m_pos; 329 int m_case_shift; 330 }; 331 332 // MIT parallel drum (mostly similar to type 23) 333 class pdp1_cylinder_image_device : public device_t, 334 public device_image_interface 335 { 336 public: 337 // construction/destruction 338 pdp1_cylinder_image_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0U); 339 340 void iot_dia(int op2, int nac, int mb, int &io, int ac); 341 void iot_dba(int op2, int nac, int mb, int &io, int ac); 342 void iot_dcc(int op2, int nac, int mb, int &io, int ac); 343 void iot_dra(int op2, int nac, int mb, int &io, int ac); 344 345 protected: 346 // device-level overrides 347 virtual void device_start() override; 348 349 // image-level overrides image_type()350 virtual iodevice_t image_type() const noexcept override { return IO_CYLINDER; } 351 is_readable()352 virtual bool is_readable() const noexcept override { return true; } is_writeable()353 virtual bool is_writeable() const noexcept override { return true; } is_creatable()354 virtual bool is_creatable() const noexcept override { return true; } must_be_loaded()355 virtual bool must_be_loaded() const noexcept override { return false; } is_reset_on_load()356 virtual bool is_reset_on_load() const noexcept override { return false; } file_extensions()357 virtual const char *file_extensions() const noexcept override { return "drm"; } 358 359 virtual image_init_result call_load() override; 360 virtual void call_unload() override; 361 362 public: 363 void set_il(int il); 364 uint32_t drum_read(int field, int position); 365 void drum_write(int field, int position, uint32_t data); 366 367 required_device<pdp1_device> m_maincpu; 368 369 int m_il; // initial location (12-bit) 370 int m_wc; // word counter (12-bit) 371 int m_wcl; // word core location counter (16-bit) 372 int m_rfb; // read field buffer (5-bit) 373 int m_wfb; // write field buffer (5-bit) 374 375 int m_dba; 376 377 emu_timer *m_rotation_timer;// timer called each time dc is 0 378 emu_timer *m_il_timer; // timer called each time dc is il 379 }; 380 381 382 struct lightpen_t 383 { 384 char active; 385 char down; 386 short x, y; 387 short radius; 388 }; 389 390 391 class pdp1_state : public driver_device 392 { 393 public: pdp1_state(const machine_config & mconfig,device_type type,const char * tag)394 pdp1_state(const machine_config &mconfig, device_type type, const char *tag) 395 : driver_device(mconfig, type, tag), 396 m_maincpu(*this, "maincpu"), 397 m_tape_reader(*this, "readt"), 398 m_tape_puncher(*this, "punch"), 399 m_typewriter(*this, "typewriter"), 400 m_parallel_drum(*this, "drum"), 401 m_gfxdecode(*this, "gfxdecode"), 402 m_palette(*this, "palette"), 403 m_crt(*this, "crt"), 404 m_spacewar(*this, "SPACEWAR"), 405 m_csw(*this, "CSW"), 406 m_sense(*this, "SENSE"), 407 m_tstadd(*this, "TSTADD"), 408 m_twdmsb(*this, "TWDMSB"), 409 m_twdlsb(*this, "TWDLSB"), 410 m_cfg(*this, "CFG"), 411 m_io_lightpen(*this, "LIGHTPEN"), 412 m_lightx(*this, "LIGHTX"), 413 m_lighty(*this, "LIGHTY") 414 { } 415 416 required_device<pdp1_device> m_maincpu; 417 required_device<pdp1_readtape_image_device> m_tape_reader; 418 required_device<pdp1_punchtape_image_device> m_tape_puncher; 419 required_device<pdp1_typewriter_device> m_typewriter; 420 required_device<pdp1_cylinder_image_device> m_parallel_drum; 421 int m_io_status; 422 emu_timer *m_dpy_timer; 423 lightpen_t m_lightpen; 424 425 virtual void machine_start() override; 426 virtual void machine_reset() override; 427 virtual void video_start() override; 428 void pdp1_palette(palette_device &palette) const; 429 uint32_t screen_update_pdp1(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); 430 DECLARE_WRITE_LINE_MEMBER(screen_vblank_pdp1); 431 INTERRUPT_GEN_MEMBER(pdp1_interrupt); 432 TIMER_CALLBACK_MEMBER(dpy_callback); 433 void pdp1_machine_stop(); 434 inline void pdp1_plot_pixel(bitmap_ind16 &bitmap, int x, int y, uint32_t color); 435 void pdp1_plot(int x, int y); 436 void pdp1_draw_led(bitmap_ind16 &bitmap, int x, int y, int state); 437 void pdp1_draw_multipleled(bitmap_ind16 &bitmap, int x, int y, int value, int nb_bits); 438 void pdp1_draw_switch(bitmap_ind16 &bitmap, int x, int y, int state); 439 void pdp1_draw_multipleswitch(bitmap_ind16 &bitmap, int x, int y, int value, int nb_bits); 440 void pdp1_draw_char(bitmap_ind16 &bitmap, char character, int x, int y, int color); 441 void pdp1_draw_string(bitmap_ind16 &bitmap, const char *buf, int x, int y, int color); 442 void pdp1_draw_panel_backdrop(bitmap_ind16 &bitmap); 443 void pdp1_draw_panel(bitmap_ind16 &bitmap); 444 void pdp1_update_lightpen_state(const lightpen_t *new_state); 445 void pdp1_draw_circle(bitmap_ind16 &bitmap, int x, int y, int radius, int color_); 446 void pdp1_erase_lightpen(bitmap_ind16 &bitmap); 447 void pdp1_draw_lightpen(bitmap_ind16 &bitmap); 448 void pdp1_lightpen(); 449 450 template <int Mask> DECLARE_WRITE_LINE_MEMBER(io_status_w); 451 452 void pdp1(machine_config &config); 453 void pdp1_map(address_map &map); 454 private: 455 void iot_dpy(int op2, int nac, int mb, int &io, int ac); 456 457 void iot_011(int op2, int nac, int mb, int &io, int ac); 458 459 void iot_cks(int op2, int nac, int mb, int &io, int ac); 460 461 void io_start_clear(); 462 463 pdp1_reset_param_t m_reset_param; 464 int m_old_lightpen; 465 int m_old_control_keys; 466 int m_old_tw_keys; 467 int m_old_ta_keys; 468 bitmap_ind16 m_panel_bitmap; 469 lightpen_t m_lightpen_state; 470 lightpen_t m_previous_lightpen_state; 471 472 public: 473 required_device<gfxdecode_device> m_gfxdecode; 474 required_device<palette_device> m_palette; 475 required_device<crt_device> m_crt; 476 required_ioport m_spacewar; 477 required_ioport m_csw; 478 required_ioport m_sense; 479 required_ioport m_tstadd; 480 required_ioport m_twdmsb; 481 required_ioport m_twdlsb; 482 required_ioport m_cfg; 483 required_ioport m_io_lightpen; 484 required_ioport m_lightx; 485 required_ioport m_lighty; 486 }; 487 488 #endif // MAME_INCLUDES_PDP1_H 489