1 // license:BSD-3-Clause 2 // copyright-holders:Gordon Jefferyes, Nigel Barnes 3 /***************************************************************************** 4 * 5 * BBC Model B/B+/Master/Compact 6 * 7 * Driver by Gordon Jefferyes <mess_bbc@romvault.com> 8 * 9 ****************************************************************************/ 10 #ifndef MAME_INCLUDES_BBC_H 11 #define MAME_INCLUDES_BBC_H 12 13 #pragma once 14 15 #include "cpu/m6502/m6502.h" 16 #include "cpu/m6502/m65sc02.h" 17 #include "imagedev/floppy.h" 18 #include "machine/74259.h" 19 #include "machine/6522via.h" 20 #include "machine/6850acia.h" 21 #include "machine/clock.h" 22 #include "machine/mc6854.h" 23 #include "machine/ram.h" 24 #include "machine/wd_fdc.h" 25 #include "machine/upd7002.h" 26 #include "machine/mc146818.h" 27 #include "machine/i2cmem.h" 28 #include "machine/bankdev.h" 29 #include "machine/input_merger.h" 30 #include "video/mc6845.h" 31 #include "video/saa5050.h" 32 #include "sound/sn76496.h" 33 #include "sound/tms5220.h" 34 #include "sound/samples.h" 35 #include "imagedev/cassette.h" 36 37 #include "bus/rs232/rs232.h" 38 #include "bus/centronics/ctronics.h" 39 #include "bus/econet/econet.h" 40 #include "bus/bbc/rom/slot.h" 41 #include "bus/bbc/fdc/fdc.h" 42 #include "bus/bbc/analogue/analogue.h" 43 #include "bus/bbc/1mhzbus/1mhzbus.h" 44 #include "bus/bbc/modem/modem.h" 45 #include "bus/bbc/internal/internal.h" 46 #include "bus/bbc/tube/tube.h" 47 #include "bus/bbc/userport/userport.h" 48 #include "bus/bbc/exp/exp.h" 49 #include "bus/bbc/joyport/joyport.h" 50 #include "bus/bbc/cart/slot.h" 51 52 #include "emupal.h" 53 #include "screen.h" 54 55 56 class bbc_state : public driver_device 57 { 58 public: bbc_state(const machine_config & mconfig,device_type type,const char * tag)59 bbc_state(const machine_config &mconfig, device_type type, const char *tag) 60 : driver_device(mconfig, type, tag) 61 , m_maincpu(*this, "maincpu") 62 , m_ram(*this, RAM_TAG) 63 , m_hd6845(*this, "hd6845") 64 , m_screen(*this, "screen") 65 , m_irqs(*this, "irqs") 66 , m_palette(*this, "palette") 67 , m_adlc(*this, "mc6854") 68 , m_sn(*this, "sn76489") 69 , m_samples(*this, "samples") 70 , m_keyboard(*this, "COL%u", 0) 71 , m_trom(*this, "saa5050") 72 , m_tms(*this, "tms5220") 73 , m_cassette(*this, "cassette") 74 , m_acia(*this, "acia6850") 75 , m_acia_clock(*this, "acia_clock") 76 , m_latch(*this, "latch") 77 , m_rs232(*this, "rs423") 78 , m_via6522_0(*this, "via6522_0") 79 , m_via6522_1(*this, "via6522_1") 80 , m_upd7002(*this, "upd7002") 81 , m_analog(*this, "analogue") 82 , m_joyport(*this, "joyport") 83 , m_tube(*this, "tube") 84 , m_intube(*this, "intube") 85 , m_extube(*this, "extube") 86 , m_1mhzbus(*this, "1mhzbus") 87 , m_modem(*this, "modem") 88 , m_userport(*this, "userport") 89 , m_internal(*this, "internal") 90 , m_exp(*this, "exp") 91 , m_rtc(*this, "rtc") 92 , m_i2cmem(*this, "i2cmem") 93 , m_fdc(*this, "fdc") 94 , m_wd_fdc(*this, "wd_fdc") 95 , m_rom(*this, "romslot%u", 0U) 96 , m_cart(*this, "cartslot%u", 1U) 97 , m_region_mos(*this, "mos") 98 , m_region_swr(*this, "swr") 99 , m_bank1(*this, "bank1") 100 , m_bank2(*this, "bank2") 101 , m_bankdev(*this, "bankdev") 102 , m_bbcconfig(*this, "BBCCONFIG") 103 , m_motor_led(*this, "motor_led") 104 { } 105 106 enum class monitor_type 107 { 108 COLOUR, 109 BLACKWHITE, 110 GREEN, 111 AMBER 112 }; 113 114 DECLARE_FLOPPY_FORMATS(floppy_formats); 115 116 uint8_t bbc_ram_r(offs_t offset); 117 void bbc_ram_w(offs_t offset, uint8_t data); 118 uint8_t bbc_romsel_r(offs_t offset); 119 void bbc_romsel_w(offs_t offset, uint8_t data); 120 uint8_t bbc_paged_r(offs_t offset); 121 void bbc_paged_w(offs_t offset, uint8_t data); 122 uint8_t bbc_mos_r(offs_t offset); 123 void bbc_mos_w(offs_t offset, uint8_t data); 124 uint8_t bbc_fred_r(offs_t offset); 125 void bbc_fred_w(offs_t offset, uint8_t data); 126 uint8_t bbc_jim_r(offs_t offset); 127 void bbc_jim_w(offs_t offset, uint8_t data); 128 uint8_t bbcbp_fetch_r(offs_t offset); 129 void bbcbp_romsel_w(offs_t offset, uint8_t data); 130 uint8_t bbcbp_paged_r(offs_t offset); 131 void bbcbp_paged_w(offs_t offset, uint8_t data); 132 uint8_t bbcm_fetch_r(offs_t offset); 133 uint8_t bbcm_acccon_r(); 134 void bbcm_acccon_w(uint8_t data); 135 void bbcm_romsel_w(offs_t offset, uint8_t data); 136 uint8_t bbcm_paged_r(offs_t offset); 137 void bbcm_paged_w(offs_t offset, uint8_t data); 138 uint8_t bbcm_hazel_r(offs_t offset); 139 void bbcm_hazel_w(offs_t offset, uint8_t data); 140 uint8_t bbcm_tube_r(offs_t offset); 141 void bbcm_tube_w(offs_t offset, uint8_t data); 142 uint8_t bbcmc_paged_r(offs_t offset); 143 void bbcmc_paged_w(offs_t offset, uint8_t data); 144 void bbcbp_drive_control_w(uint8_t data); 145 void bbcm_drive_control_w(uint8_t data); 146 void serial_ula_w(uint8_t data); 147 void video_ula_w(offs_t offset, uint8_t data); bbc_fe_r()148 uint8_t bbc_fe_r() { return 0xfe; }; 149 150 DECLARE_VIDEO_START(bbc); 151 152 INTERRUPT_GEN_MEMBER(bbcb_keyscan); 153 TIMER_CALLBACK_MEMBER(tape_timer_cb); 154 TIMER_CALLBACK_MEMBER(reset_timer_cb); 155 DECLARE_WRITE_LINE_MEMBER(write_acia_clock); 156 DECLARE_WRITE_LINE_MEMBER(adlc_irq_w); 157 DECLARE_WRITE_LINE_MEMBER(bus_nmi_w); 158 DECLARE_WRITE_LINE_MEMBER(snd_enable_w); 159 DECLARE_WRITE_LINE_MEMBER(speech_rsq_w); 160 DECLARE_WRITE_LINE_MEMBER(speech_wsq_w); 161 DECLARE_WRITE_LINE_MEMBER(kbd_enable_w); 162 uint8_t via_system_porta_r(); 163 void via_system_porta_w(uint8_t data); 164 uint8_t via_system_portb_r(); 165 void via_system_portb_w(uint8_t data); 166 DECLARE_WRITE_LINE_MEMBER(lpstb_w); 167 DECLARE_WRITE_LINE_MEMBER(bbc_hsync_changed); 168 DECLARE_WRITE_LINE_MEMBER(bbc_vsync_changed); 169 DECLARE_WRITE_LINE_MEMBER(bbc_de_changed); 170 DECLARE_INPUT_CHANGED_MEMBER(reset_palette); 171 void update_palette(monitor_type monitor_type); 172 173 void update_acia_rxd(); 174 void update_acia_dcd(); 175 void update_acia_cts(); 176 DECLARE_WRITE_LINE_MEMBER(write_rts); 177 DECLARE_WRITE_LINE_MEMBER(write_txd); 178 DECLARE_WRITE_LINE_MEMBER(write_rxd); 179 DECLARE_WRITE_LINE_MEMBER(write_dcd); 180 DECLARE_WRITE_LINE_MEMBER(write_cts); 181 182 DECLARE_INPUT_CHANGED_MEMBER(trigger_reset); 183 DECLARE_WRITE_LINE_MEMBER(fdc_intrq_w); 184 DECLARE_WRITE_LINE_MEMBER(fdc_drq_w); 185 186 int get_analogue_input(int channel_number); 187 void upd7002_eoc(int data); 188 189 std::string get_rom_name(uint8_t* header); 190 void insert_device_rom(memory_region *rom); 191 void setup_device_roms(); 192 193 MC6845_UPDATE_ROW(crtc_update_row); 194 195 void bbca(machine_config &config); 196 void bbcb(machine_config &config); 197 void bbcb_de(machine_config &config); 198 void bbcb_us(machine_config &config); 199 200 void bbca_mem(address_map &map); 201 void bbc_base(address_map &map); 202 void bbcb_mem(address_map &map); 203 204 void init_bbc(); 205 void init_ltmp(); 206 void init_cfa(); 207 208 protected: 209 virtual void machine_start() override; 210 virtual void machine_reset() override; 211 212 virtual void video_start() override; 213 virtual void video_reset() override; 214 215 required_device<cpu_device> m_maincpu; 216 required_device<ram_device> m_ram; 217 required_device<mc6845_device> m_hd6845; 218 required_device<screen_device> m_screen; 219 required_device<input_merger_device> m_irqs; 220 required_device<palette_device> m_palette; 221 optional_device<mc6854_device> m_adlc; 222 optional_device<sn76489a_device> m_sn; 223 optional_device<samples_device> m_samples; 224 required_ioport_array<16> m_keyboard; 225 optional_device<saa5050_device> m_trom; 226 optional_device<tms5220_device> m_tms; 227 optional_device<cassette_image_device> m_cassette; 228 optional_device<acia6850_device> m_acia; 229 optional_device<clock_device> m_acia_clock; 230 required_device<ls259_device> m_latch; 231 optional_device<rs232_port_device> m_rs232; 232 required_device<via6522_device> m_via6522_0; 233 optional_device<via6522_device> m_via6522_1; 234 optional_device<upd7002_device> m_upd7002; 235 optional_device<bbc_analogue_slot_device> m_analog; 236 optional_device<bbc_joyport_slot_device> m_joyport; 237 optional_device<bbc_tube_slot_device> m_tube; 238 optional_device<bbc_tube_slot_device> m_intube; 239 optional_device<bbc_tube_slot_device> m_extube; 240 optional_device<bbc_1mhzbus_slot_device> m_1mhzbus; 241 optional_device<bbc_modem_slot_device> m_modem; 242 optional_device<bbc_userport_slot_device> m_userport; 243 optional_device<bbc_internal_slot_device> m_internal; 244 optional_device<bbc_exp_slot_device> m_exp; 245 optional_device<mc146818_device> m_rtc; 246 optional_device<i2cmem_device> m_i2cmem; 247 optional_device<bbc_fdc_slot_device> m_fdc; 248 optional_device<wd_fdc_digital_device_base> m_wd_fdc; 249 optional_device_array<bbc_romslot_device, 16> m_rom; 250 optional_device_array<bbc_cartslot_device, 2> m_cart; 251 252 required_memory_region m_region_mos; 253 required_memory_region m_region_swr; 254 optional_memory_bank m_bank1; // bbcbp bbcbp128 bbcm 255 optional_memory_bank m_bank2; // bbcbp bbcbp128 bbcm 256 optional_device<address_map_bank_device> m_bankdev; // bbcm 257 optional_ioport m_bbcconfig; 258 259 output_finder<> m_motor_led; 260 261 int m_romsel; // This is the latch that holds the sideways ROM bank to read 262 int m_paged_ram; // BBC B+ memory handling 263 int m_vdusel; // BBC B+ memory handling 264 265 /* 266 ACCCON 267 b7 IRR 1=Causes an IRQ to the processor 268 b6 TST 1=Selects &FC00-&FEFF read from OS-ROM 269 b5 IFJ 1=Internal 1 MHz bus 270 0=External 1MHz bus 271 b4 ITU 1=Internal Tube 272 0=External Tube 273 b3 Y 1=Read/Write HAZEL &C000-&DFFF RAM 274 0=Read/Write ROM &C000-&DFFF OS-ROM 275 b2 X 1=Read/Write LYNNE 276 0=Read/WRITE main memory &3000-&8000 277 b1 E 1=Causes shadow if VDU code 278 0=Main all the time 279 b0 D 1=Display LYNNE as screen 280 0=Display main RAM screen 281 ACCCON is a read/write register 282 */ 283 284 int m_acccon; 285 int m_acccon_irr; 286 int m_acccon_tst; 287 int m_acccon_ifj; 288 int m_acccon_itu; 289 int m_acccon_y; 290 int m_acccon_x; 291 int m_acccon_e; 292 int m_acccon_d; 293 294 void mc146818_set(); 295 int m_mc146818_as; // 6522 port b bit 7 296 int m_mc146818_ce; // 6522 port b bit 6 297 298 int m_via_system_porta; 299 300 // interrupt state 301 int m_adlc_irq; 302 int m_bus_nmi; 303 304 int m_column; // this is a counter in the keyboard circuit 305 306 /*************************************** 307 BBC 2C199 Serial Interface Cassette 308 ****************************************/ 309 310 double m_last_dev_val; 311 int m_wav_len; 312 int m_len0; 313 int m_len1; 314 int m_len2; 315 int m_len3; 316 uint8_t m_serproc_data; 317 int m_rxd_serial; 318 int m_dcd_serial; 319 int m_cts_serial; 320 int m_dcd_cass; 321 int m_rxd_cass; 322 int m_cass_out_enabled; 323 int m_txd; 324 uint32_t m_nr_high_tones; 325 int m_cass_out_samples_to_go; 326 int m_cass_out_bit; 327 int m_cass_out_phase; 328 emu_timer *m_tape_timer; 329 330 331 /************************************** 332 WD1770 disc control 333 ***************************************/ 334 335 int m_fdc_irq; 336 int m_fdc_drq; 337 338 /************************************** 339 Video Code 340 ***************************************/ 341 342 // this is the real location of the start of the BBC's ram in the emulation 343 // it can be changed if shadow ram is being used to point at the upper 32K of RAM 344 uint8_t *m_video_ram; 345 uint8_t m_pixel_bits[256]; 346 int m_hsync; 347 int m_vsync; 348 349 uint8_t m_teletext_latch; 350 uint8_t m_vula_ctrl; 351 352 struct video_nula { 353 uint8_t palette_mode; 354 uint8_t horiz_offset; 355 uint8_t left_blank; 356 uint8_t disable; 357 uint8_t attr_mode; 358 uint8_t attr_text; 359 uint8_t flash[8]; 360 uint8_t palette_byte; 361 uint8_t palette_write; 362 } m_vnula; 363 364 int m_pixels_per_byte; 365 int m_cursor_size; 366 367 uint8_t m_vula_palette[16]; 368 uint8_t m_vula_palette_lookup[16]; 369 370 void setvideoshadow(int vdusel); 371 void set_pixel_lookup(); 372 uint8_t bus_video_data(); 373 int bbc_keyboard(int data); 374 375 void mc6850_receive_clock(int new_clock); 376 void cassette_motor(bool state); 377 void update_nmi(); 378 uint16_t calculate_video_address(uint16_t ma, uint8_t ra); 379 380 private: 381 emu_timer *m_reset_timer; 382 }; 383 384 385 class torch_state : public bbc_state 386 { 387 public: 388 using bbc_state::bbc_state; imperfect_features()389 static constexpr feature_type imperfect_features() { return feature::KEYBOARD; } 390 391 void torchf(machine_config &config); 392 void torchh(machine_config &config); 393 void torch301(machine_config &config); 394 void torch725(machine_config &config); 395 }; 396 397 398 class bbcbp_state : public bbc_state 399 { 400 public: 401 using bbc_state::bbc_state; 402 403 void bbcbp(machine_config &config); 404 void bbcbp128(machine_config &config); 405 void abc110(machine_config &config); 406 void acw443(machine_config &config); 407 void abc310(machine_config &config); 408 void cfa3000bp(machine_config &config); 409 void econx25(machine_config &config); 410 void reutapm(machine_config &config); 411 412 protected: 413 virtual void machine_start() override; 414 virtual void machine_reset() override; 415 416 void bbcbp_mem(address_map &map); 417 void reutapm_mem(address_map &map); 418 void bbcbp_fetch(address_map &map); 419 }; 420 421 422 class bbcm_state : public bbc_state 423 { 424 public: bbcm_state(const machine_config & mconfig,device_type type,const char * tag)425 bbcm_state(const machine_config &mconfig, device_type type, const char *tag) 426 : bbc_state(mconfig, type, tag) 427 , m_power_led(*this, "power_led") 428 { } 429 430 void bbcm(machine_config &config); 431 void bbcmt(machine_config &config); 432 void bbcmet(machine_config &config); 433 void bbcmaiv(machine_config &config); 434 void bbcm512(machine_config &config); 435 void bbcmarm(machine_config &config); 436 void cfa3000(machine_config &config); 437 void daisy(machine_config &config); 438 void discmon(machine_config &config); 439 void discmate(machine_config &config); 440 void mpc800(machine_config& config); 441 void mpc900(machine_config& config); 442 void mpc900gx(machine_config& config); 443 void bbcmc(machine_config &config); 444 void pro128s(machine_config &config); 445 void autoc15(machine_config &config); 446 447 static void mpc_prisma_default(device_t *device); 448 449 protected: 450 virtual void machine_start() override; 451 virtual void machine_reset() override; 452 453 void bbcm_mem(address_map &map); 454 void bbcm_bankdev(address_map &map); 455 void bbcmet_bankdev(address_map &map); 456 void bbcmc_mem(address_map &map); 457 void bbcmc_bankdev(address_map &map); 458 void autoc15_bankdev(address_map &map); 459 void bbcm_fetch(address_map &map); 460 461 output_finder<> m_power_led; 462 }; 463 464 465 #endif // MAME_INCLUDES_BBC_H 466