INPUT_PORTS_END void itt1700_state::itt1700(machine_config &config) { Z80(config, m_maincpu, 17.35_MHz_XTAL / 5); // divider guessed m_maincpu->set_addrmap(AS_PROGRAM, &itt1700_state::mem_map); m_maincpu->set_addrmap(AS_IO, &itt1700_state::io_map); upi41_cpu_device &upi(I8741(config, "upi", 16.6698_MHz_XTAL / 3)); // clock guessed upi.p1_out_cb().set("keyboard", FUNC(itt1700_keyboard_device::clock_w)).bit(0); upi.p1_out_cb().append("keyboard", FUNC(itt1700_keyboard_device::line1_w)).bit(1); upi.p1_out_cb().append("keyboard", FUNC(itt1700_keyboard_device::line2_w)).bit(2); upi.t0_in_cb().set("keyboard", FUNC(itt1700_keyboard_device::sense_r)); ITT1700_KEYBOARD(config, "keyboard"); screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); screen.set_raw(16.6698_MHz_XTAL, 882, 0, 720, 315, 0, 300); screen.set_screen_update("crtc", FUNC(mc6845_device::screen_update)); hd6845s_device &crtc(HD6845S(config, "crtc", 16.6698_MHz_XTAL / 9)); // on video board crtc.set_char_width(9); crtc.set_screen("screen"); crtc.set_show_border_area(false); crtc.set_update_row_callback(FUNC(itt1700_state::update_row), this); }
void goupil_g2_state::goupil_g2(machine_config &config) { base(config); m_maincpu->set_addrmap(AS_PROGRAM, &goupil_g2_state::mem); // "visu 24x80" board RAM(config, m_visu24x80_ram); m_visu24x80_ram->set_default_size("2K"); // visu24x80 2K ram m_screen->set_screen_update("crtc", FUNC(mc6845_device::screen_update)); m_screen->set_size((80*8), (24*(8+4))); m_screen->set_visarea(0, (80*8)-1, 0, (24*(8+4))-1); PALETTE(config, m_palette, 3); m_palette->set_init("palette", FUNC(palette_device::palette_init_monochrome_highlight)); mc6845_device &crtc(MC6845(config, "crtc", 14.318181_MHz_XTAL / 8)); crtc.set_show_border_area(false); crtc.set_char_width(8); crtc.set_update_row_callback(FUNC(goupil_g2_state::crtc_update_row), this); crtc.set_on_update_addr_change_callback(FUNC(goupil_g2_state::crtc_update_addr_changed), this); m_via_video->writepa_handler().set_nop(); m_via_video->writepb_handler().set_nop(); m_via_video->ca2_handler().set_nop(); }
GFXDECODE_END /************************* * Machine Drivers * *************************/ void tmspoker_state::tmspoker(machine_config &config) { // CPU TMS9980A; no line connections TMS9980A(config, m_maincpu, MASTER_CLOCK); m_maincpu->set_addrmap(AS_PROGRAM, &tmspoker_state::tmspoker_map); m_maincpu->set_addrmap(AS_IO, &tmspoker_state::tmspoker_cru_map); m_maincpu->set_vblank_int("screen", FUNC(tmspoker_state::tmspoker_interrupt)); /* video hardware */ screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); screen.set_refresh_hz(60); screen.set_vblank_time(ATTOSECONDS_IN_USEC(0)); screen.set_size(32*8, 32*8); screen.set_visarea(0*8, 32*8-1, 0*8, 32*8-1); screen.set_screen_update(FUNC(tmspoker_state::screen_update_tmspoker)); screen.set_palette("palette"); GFXDECODE(config, m_gfxdecode, "palette", gfx_tmspoker); PALETTE(config, "palette", FUNC(tmspoker_state::tmspoker_palette), 256); mc6845_device &crtc(MC6845(config, "crtc", MASTER_CLOCK/4)); /* guess */ crtc.set_screen("screen"); crtc.set_show_border_area(false); crtc.set_char_width(8); }
void mgg::DRMModeResources::for_each_crtc(std::function<void(DRMModeCrtcUPtr)> const& f) const { for (int i = 0; i < resources->count_crtcs; i++) { auto crtc_ptr = crtc(resources->crtcs[i]); if (!crtc_ptr) continue; f(std::move(crtc_ptr)); } }
void osborne1nv_state::osborne1nv(machine_config &config) { osborne1(config); m_maincpu->set_addrmap(AS_IO, &osborne1nv_state::osborne1nv_io); m_screen->set_palette(finder_base::DUMMY_TAG); m_screen->set_screen_update("crtc", FUNC(mc6845_device::screen_update)); sy6545_1_device &crtc(SY6545_1(config, "crtc", XTAL(12'288'000)/8)); crtc.set_screen(m_screen); crtc.set_show_border_area(false); crtc.set_char_width(8); crtc.set_update_row_callback(FUNC(osborne1nv_state::crtc_update_row), this); crtc.set_on_update_addr_change_callback(FUNC(osborne1nv_state::crtc_update_addr_changed), this); }
GFXDECODE_END /********************************************* * Machine Drivers * *********************************************/ void gluck2_state::gluck2(machine_config &config) { /* basic machine hardware */ M6502(config, m_maincpu, MASTER_CLOCK/16); /* guess */ m_maincpu->set_addrmap(AS_PROGRAM, &gluck2_state::gluck2_map); NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0); /* video hardware */ screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); screen.set_refresh_hz(60); screen.set_vblank_time(ATTOSECONDS_IN_USEC(0)); /* CRTC Register: 00 01 02 03 04 05 06 CRTC Value : 0x27 0x20 0x23 0x03 0x26 0x00 0x20 */ screen.set_size((39+1)*8, (38+1)*8); /* from MC6845 init, registers 00 & 04. (value - 1) */ screen.set_visarea(0*8, 32*8-1, 0*8, 32*8-1); /* from MC6845 init, registers 01 & 06. */ screen.set_screen_update(FUNC(gluck2_state::screen_update)); GFXDECODE(config, m_gfxdecode, "palette", gfx_gluck2); PALETTE(config, "palette", palette_device::RGB_444_PROMS, "proms", 256); mc6845_device &crtc(MC6845(config, "crtc", MASTER_CLOCK/16)); /* guess */ crtc.set_screen("screen"); crtc.set_show_border_area(false); crtc.set_char_width(8); crtc.out_vsync_callback().set_inputline(m_maincpu, INPUT_LINE_NMI); /* sound hardware */ SPEAKER(config, "mono").front_center(); ay8910_device &ay8910(AY8910(config, "ay8910", MASTER_CLOCK/8)); /* guess */ ay8910.port_a_read_callback().set_ioport("SW3"); ay8910.port_b_read_callback().set_ioport("SW2"); /* Output ports have a minimal activity during init. They seems unused (at least for Good Luck II) */ ay8910.add_route(ALL_OUTPUTS, "mono", 1.0); YM2413(config, "ymsnd", SND_CLOCK).add_route(ALL_OUTPUTS, "mono", 1.0); }
void raiden_state::raidenb(machine_config &config) { raiden(config); /* basic machine hardware */ m_maincpu->set_addrmap(AS_PROGRAM, &raiden_state::raidenb_main_map); /* video hardware */ MCFG_VIDEO_START_OVERRIDE(raiden_state,raidenb) seibu_crtc_device &crtc(SEIBU_CRTC(config, "crtc", 0)); crtc.layer_en_callback().set(FUNC(raiden_state::raidenb_layer_enable_w)); crtc.layer_scroll_callback().set(FUNC(raiden_state::raidenb_layer_scroll_w)); subdevice<screen_device>("screen")->set_screen_update(FUNC(raiden_state::screen_update_raidenb)); }
GFXDECODE_END /************************** * Machine Drivers * **************************/ void _4roses_state::_4roses(machine_config &config) { /* basic machine hardware */ M65C02(config, m_maincpu, MASTER_CLOCK/8); /* 2MHz, guess */ m_maincpu->set_addrmap(AS_PROGRAM, &_4roses_state::_4roses_map); m_maincpu->set_addrmap(AS_OPCODES, &_4roses_state::_4roses_opcodes_map); // NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0); /* video hardware */ screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); screen.set_refresh_hz(60); screen.set_vblank_time(ATTOSECONDS_IN_USEC(0)); screen.set_size((124+1)*4, (30+1)*8); /* guess. taken from funworld games */ screen.set_visarea(0*4, 96*4-1, 0*8, 29*8-1); /* guess. taken from funworld games */ screen.set_screen_update(FUNC(_4roses_state::screen_update_funworld)); GFXDECODE(config, m_gfxdecode, "palette", gfx_4roses); PALETTE(config, "palette", FUNC(_4roses_state::funworld_palette), 0x1000); mc6845_device &crtc(MC6845(config, "crtc", MASTER_CLOCK/8)); /* 2MHz, guess */ crtc.set_screen("screen"); crtc.set_show_border_area(false); crtc.set_char_width(4); //crtc.out_vsync_callback().set_inputline(m_maincpu, INPUT_LINE_NMI); /* sound hardware */ SPEAKER(config, "mono").front_center(); AY8910(config, "ay8910", MASTER_CLOCK/8).add_route(ALL_OUTPUTS, "mono", 2.5); /* 2MHz, guess */ }
INPUT_PORTS_END void qvt6800_state::qvt190(machine_config &config) { M6800(config, m_maincpu, XTAL(16'669'800) / 9); m_maincpu->set_addrmap(AS_PROGRAM, &qvt6800_state::qvt190_mem_map); NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0); // V61C16P55L + battery ACIA6850(config, "acia1", 0); ACIA6850(config, "acia2", 0); screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); screen.set_raw(XTAL(16'669'800), 882, 0, 720, 315, 0, 300); screen.set_screen_update("crtc", FUNC(mc6845_device::screen_update)); mc6845_device &crtc(MC6845(config, "crtc", XTAL(16'669'800) / 9)); crtc.set_screen("screen"); crtc.set_char_width(9); crtc.set_update_row_callback(FUNC(qvt6800_state::update_row), this); }
GFXDECODE_END void hitpoker_state::hitpoker(machine_config &config) { MC68HC11(config, m_maincpu, 1000000); m_maincpu->set_addrmap(AS_PROGRAM, &hitpoker_state::hitpoker_map); m_maincpu->set_addrmap(AS_IO, &hitpoker_state::hitpoker_io); m_maincpu->set_config(0, 0x100, 0x01); NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0); /* video hardware */ screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); screen.set_refresh_hz(60); screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500)); // not accurate screen.set_size(648, 480); //setted by the CRTC screen.set_visarea(0, 648-1, 0, 240-1); screen.set_screen_update(FUNC(hitpoker_state::screen_update_hitpoker)); screen.set_palette(m_palette); h46505_device &crtc(H46505(config, "crtc", CRTC_CLOCK/2)); /* hand tuned to get ~60 fps */ crtc.set_screen("screen"); crtc.set_show_border_area(false); crtc.set_char_width(8); crtc.out_vsync_callback().set(FUNC(hitpoker_state::hitpoker_irq)); GFXDECODE(config, m_gfxdecode, m_palette, gfx_hitpoker); PALETTE(config, m_palette).set_entries(0x800); SPEAKER(config, "mono").front_center(); ym2149_device &aysnd(YM2149(config, "aysnd", 1500000)); aysnd.port_a_read_callback().set_ioport("DSW1"); aysnd.port_b_read_callback().set_ioport("DSW2"); aysnd.add_route(ALL_OUTPUTS, "mono", 0.50); }
/* RS232 usage: mame can09t -window -debug -rs232 terminal */ ACIA6850(config, m_acia, 0); m_acia->txd_handler().set("rs232", FUNC(rs232_port_device::write_txd)); m_acia->rts_handler().set("rs232", FUNC(rs232_port_device::write_rts)); rs232_port_device &rs232(RS232_PORT(config, "rs232", default_rs232_devices, "terminal")); rs232.rxd_handler().set(m_acia, FUNC(acia6850_device::write_rxd)); rs232.cts_handler().set(m_acia, FUNC(acia6850_device::write_cts)); CLOCK(config, "acia_clock", CAN09T_ACIA_CLOCK).signal_handler().set(FUNC(can09t_state::write_acia_clock)); } #define CAN09_X1_CLOCK 22.1184_MHz_XTAL /* UKI 22118.40 Khz */ #define CAN09_CPU_CLOCK (CAN09_X1_CLOCK / 16) /* ~1.38MHz Divider needs to be check but is the most likelly */ void can09_state::can09(machine_config &config) { MC6809E(config, m_maincpu, CAN09_CPU_CLOCK); // MC68A09EP m_maincpu->set_addrmap(AS_PROGRAM, &can09_state::can09_map); /* RAM banks */ RAM(config, RAM_TAG).set_default_size("768K"); // CRTC init hd6845s_device &crtc(HD6845S(config, "crtc", CAN09_CPU_CLOCK)); // HD46505SP-1 (HD68A45SP) crtc.set_screen("screen"); crtc.set_show_border_area(false); crtc.set_char_width(8); //crtc.set_update_row_callback(FUNC(can09_state::crtc_update_row), this); // not written yet /* Setup loop from data table in ROM: 0xFFCB 0xE020 (CRTC register number), 0xFFD0 0xE021 (CRTC register value) Reg Value Comment 0x00 0x55 Horizontal Total number of characters, 0x01 0x40 Horizontal Displayed number of characters 0x02 0x43 Horizontal Sync Position, character number 0x03 0x03 Horizontal Sync width, number of charcters 0x04 0x50 Vertical Total number of characters 0x05 0x09 Vertical Total Adjust number of characters 0x06 0x48 Vertical Displayed number of characters 0x07 0x4B Vertical Sync Position, character number 0x08 0x00 Interlace Mode/Scew, Non-Interlaced 0x09 0x03 Max Scan Line Address Register 0x0A 0x00 Cursor Start 0x0B 0x0A Cursor End 0x0C 0x00 Start Address hi 0x0D 0x00 Start Address lo 0x0E 0x00 Cursor hi 0x0F 0x00 Cursor lo Note - no init of Light Pen registers */ /* screen - totally faked value for now */ screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); screen.set_refresh_hz(50); screen.set_raw(4_MHz_XTAL / 2, 512, 0, 512, 576, 0, 576); screen.set_screen_update(FUNC(can09_state::screen_update)); screen.set_palette("palette"); PALETTE(config, "palette", palette_device::MONOCHROME); /* Floppy */ WD1770(config, "wd1770", 8_MHz_XTAL); // TODO: Verify 8MHz UKI crystal assumed to be used #if 0 FLOPPY_CONNECTOR(config, "wd1770:0", candela_floppies, "3dd", floppy_image_device::default_floppy_formats); SOFTWARE_LIST(config, "flop3_list").set_original("candela"); #endif /* --PIA inits----------------------- */ PIA6821(config, m_pia1, 0); // CPU board m_pia1->readpa_handler().set(FUNC(can09_state::pia1_A_r)); m_pia1->writepa_handler().set(FUNC(can09_state::pia1_A_w)); m_pia1->readpb_handler().set(FUNC(can09_state::pia1_B_r)); m_pia1->writepb_handler().set(FUNC(can09_state::pia1_B_w)); m_pia1->cb2_handler().set(FUNC(can09_state::pia1_cb2_w)); /* 0xFF7D 0xE035 (PIA1 Control A) = 0x00 - Channel A IRQ disabled */ /* 0xFF81 0xE037 (PIA1 Control B) = 0x00 - Channel A IRQ disabled */ /* 0xFF85 0xE034 (PIA1 DDR A) = 0x1F - Port A mixed mode */ /* 0xFF89 0xE036 (PIA1 DDR B) = 0x79 - Port B mixed mode */ /* 0xFF8D 0xE035 (PIA1 Control A) = 0x04 - Channel A lock DDR */ /* 0xFF8F 0xE037 (PIA1 Control B) = 0x04 - Channel B lock DDR */ /* 0xFF93 0xE034 (PIA1 Port B) = 0x18 - Write Data on Port B */ #if 1 PIA6821(config, PIA2_TAG, 0); // CPU board ACIA6850(config, "acia1", 0); // CPU board ACIA6850(config, "acia2", 0); // CPU board #endif }
void vga_write_p3d5(Bitu port,Bitu val,Bitu iolen) { // if((crtc(index)!=0xe)&&(crtc(index)!=0xf)) // LOG_MSG("CRTC w #%2x val %2x",crtc(index),val); switch(crtc(index)) { case 0x00: /* Horizontal Total Register */ if (crtc(read_only)) break; crtc(horizontal_total)=val; /* 0-7 Horizontal Total Character Clocks-5 */ break; case 0x01: /* Horizontal Display End Register */ if (crtc(read_only)) break; if (val != crtc(horizontal_display_end)) { crtc(horizontal_display_end)=val; VGA_StartResize(); } /* 0-7 Number of Character Clocks Displayed -1 */ break; case 0x02: /* Start Horizontal Blanking Register */ if (crtc(read_only)) break; crtc(start_horizontal_blanking)=val; /* 0-7 The count at which Horizontal Blanking starts */ break; case 0x03: /* End Horizontal Blanking Register */ if (crtc(read_only)) break; crtc(end_horizontal_blanking)=val; /* 0-4 Horizontal Blanking ends when the last 6 bits of the character counter equals this field. Bit 5 is at 3d4h index 5 bit 7. 5-6 Number of character clocks to delay start of display after Horizontal Total has been reached. 7 Access to Vertical Retrace registers if set. If clear reads to 3d4h index 10h and 11h access the Lightpen read back registers ?? */ break; case 0x04: /* Start Horizontal Retrace Register */ if (crtc(read_only)) break; crtc(start_horizontal_retrace)=val; /* 0-7 Horizontal Retrace starts when the Character Counter reaches this value. */ break; case 0x05: /* End Horizontal Retrace Register */ if (crtc(read_only)) break; crtc(end_horizontal_retrace)=val; /* 0-4 Horizontal Retrace ends when the last 5 bits of the character counter equals this value. 5-6 Number of character clocks to delay start of display after Horizontal Retrace. 7 bit 5 of the End Horizontal Blanking count (See 3d4h index 3 bit 0-4) */ break; case 0x06: /* Vertical Total Register */ if (crtc(read_only)) break; if (val != crtc(vertical_total)) { crtc(vertical_total)=val; VGA_StartResize(); } /* 0-7 Lower 8 bits of the Vertical Total. Bit 8 is found in 3d4h index 7 bit 0. Bit 9 is found in 3d4h index 7 bit 5. Note: For the VGA this value is the number of scan lines in the display -2. */ break; case 0x07: /* Overflow Register */ //Line compare bit ignores read only */ vga.config.line_compare=(vga.config.line_compare & 0x6ff) | (val & 0x10) << 4; if (crtc(read_only)) break; if ((vga.crtc.overflow ^ val) & 0xd6) { crtc(overflow)=val; VGA_StartResize(); } else crtc(overflow)=val; /* 0 Bit 8 of Vertical Total (3d4h index 6) 1 Bit 8 of Vertical Display End (3d4h index 12h) 2 Bit 8 of Vertical Retrace Start (3d4h index 10h) 3 Bit 8 of Start Vertical Blanking (3d4h index 15h) 4 Bit 8 of Line Compare Register (3d4h index 18h) 5 Bit 9 of Vertical Total (3d4h index 6) 6 Bit 9 of Vertical Display End (3d4h index 12h) 7 Bit 9 of Vertical Retrace Start (3d4h index 10h) */ break; case 0x08: /* Preset Row Scan Register */ crtc(preset_row_scan)=val; vga.config.hlines_skip=val&31; if (IS_VGA_ARCH) vga.config.bytes_skip=(val>>5)&3; else vga.config.bytes_skip=0; // LOG_DEBUG("Skip lines %d bytes %d",vga.config.hlines_skip,vga.config.bytes_skip); /* 0-4 Number of lines we have scrolled down in the first character row. Provides Smooth Vertical Scrolling.b 5-6 Number of bytes to skip at the start of scanline. Provides Smooth Horizontal Scrolling together with the Horizontal Panning Register (3C0h index 13h). */ break; case 0x09: /* Maximum Scan Line Register */ { if (IS_VGA_ARCH) { vga.config.line_compare &= 0x5ff; vga.config.line_compare |= (val&0x40)<<3; } else if(machine==MCH_EGA) { val &= 0x7f; // EGA ignores the doublescan bit } Bit8u old = crtc(maximum_scan_line); crtc(maximum_scan_line) = val; if(!vga.draw.doublescan_merging) { if ((old ^ val) & 0x20) VGA_StartResize(); vga.draw.address_line_total = (val &0x1F) + 1; if (val&0x80) vga.draw.address_line_total*=2; } else if ((old ^ val) & 0xbf) VGA_StartResize(); /* 0-4 Number of scan lines in a character row -1. In graphics modes this is the number of times (-1) the line is displayed before passing on to the next line (0: normal, 1: double, 2: triple...). This is independent of bit 7, except in CGA modes which seems to require this field to be 1 and bit 7 to be set to work. 5 Bit 9 of Start Vertical Blanking 6 Bit 9 of Line Compare Register 7 Doubles each scan line if set. I.e. displays 200 lines on a 400 display. */ break; } case 0x0A: /* Cursor Start Register */ crtc(cursor_start)=val; vga.draw.cursor.sline=val&0x1f; if (IS_VGA_ARCH) vga.draw.cursor.enabled=!(val&0x20); else vga.draw.cursor.enabled=true; /* 0-4 First scanline of cursor within character. 5 Turns Cursor off if set */ break; case 0x0B: /* Cursor End Register */ crtc(cursor_end)=val; vga.draw.cursor.eline=val&0x1f; vga.draw.cursor.delay=(val>>5)&0x3; /* 0-4 Last scanline of cursor within character 5-6 Delay of cursor data in character clocks. */ break; case 0x0C: /* Start Address High Register */ crtc(start_address_high)=val; vga.config.display_start=(vga.config.display_start & 0xFF00FF)| (val << 8); /* 0-7 Upper 8 bits of the start address of the display buffer */ page_flip_debug_notify(); break; case 0x0D: /* Start Address Low Register */ crtc(start_address_low)=val; vga.config.display_start=(vga.config.display_start & 0xFFFF00)| val; /* 0-7 Lower 8 bits of the start address of the display buffer */ page_flip_debug_notify(); break; case 0x0E: /*Cursor Location High Register */ crtc(cursor_location_high)=val; vga.config.cursor_start&=0xff00ff; vga.config.cursor_start|=val << 8; /* 0-7 Upper 8 bits of the address of the cursor */ break; case 0x0F: /* Cursor Location Low Register */ //TODO update cursor on screen crtc(cursor_location_low)=val; vga.config.cursor_start&=0xffff00; vga.config.cursor_start|=val; /* 0-7 Lower 8 bits of the address of the cursor */ break; case 0x10: /* Vertical Retrace Start Register */ crtc(vertical_retrace_start)=val; /* 0-7 Lower 8 bits of Vertical Retrace Start. Vertical Retrace starts when the line counter reaches this value. Bit 8 is found in 3d4h index 7 bit 2. Bit 9 is found in 3d4h index 7 bit 7. */ break; case 0x11: /* Vertical Retrace End Register */ crtc(vertical_retrace_end)=val; if (IS_EGAVGA_ARCH && !(val & 0x10)) { vga.draw.vret_triggered=false; if (GCC_UNLIKELY(machine==MCH_EGA)) PIC_DeActivateIRQ(9); } if (IS_VGA_ARCH) crtc(read_only)=(val & 128)>0; else crtc(read_only)=false; /* 0-3 Vertical Retrace ends when the last 4 bits of the line counter equals this value. 4 if clear Clears pending Vertical Interrupts. 5 Vertical Interrupts (IRQ 2) disabled if set. Can usually be left disabled, but some systems (including PS/2) require it to be enabled. 6 If set selects 5 refresh cycles per scanline rather than 3. 7 Disables writing to registers 0-7 if set 3d4h index 7 bit 4 is not affected by this bit. */ break; case 0x12: /* Vertical Display End Register */ if (val!=crtc(vertical_display_end)) { if (abs((Bits)val-(Bits)crtc(vertical_display_end))<3) { // delay small vde changes a bit to avoid screen resizing // if they are reverted in a short timeframe PIC_RemoveEvents(VGA_SetupDrawing); vga.draw.resizing=false; crtc(vertical_display_end)=val; VGA_StartResize(150); } else { crtc(vertical_display_end)=val; VGA_StartResize(); } } /* 0-7 Lower 8 bits of Vertical Display End. The display ends when the line counter reaches this value. Bit 8 is found in 3d4h index 7 bit 1. Bit 9 is found in 3d4h index 7 bit 6. */ break; case 0x13: /* Offset register */ crtc(offset)=val; vga.config.scan_len&=0x300; vga.config.scan_len|=val; VGA_CheckScanLength(); /* 0-7 Number of bytes in a scanline / K. Where K is 2 for byte mode, 4 for word mode and 8 for Double Word mode. */ break; case 0x14: /* Underline Location Register */ crtc(underline_location)=val; if (IS_VGA_ARCH) { //Byte,word,dword mode if ( crtc(underline_location) & 0x40 ) vga.config.addr_shift = 2; else if ( crtc( mode_control) & 0x40 ) vga.config.addr_shift = 0; else vga.config.addr_shift = 1; } else { vga.config.addr_shift = 1; } VGA_CheckScanLength(); /* 0-4 Position of underline within Character cell. 5 If set memory address is only changed every fourth character clock. 6 Double Word mode addressing if set */ break; case 0x15: /* Start Vertical Blank Register */ if (val!=crtc(start_vertical_blanking)) { crtc(start_vertical_blanking)=val; VGA_StartResize(); } /* 0-7 Lower 8 bits of Vertical Blank Start. Vertical blanking starts when the line counter reaches this value. Bit 8 is found in 3d4h index 7 bit 3. */ break; case 0x16: /* End Vertical Blank Register */ if (val!=crtc(end_vertical_blanking)) { crtc(end_vertical_blanking)=val; VGA_StartResize(); } /* 0-6 Vertical blanking stops when the lower 7 bits of the line counter equals this field. Some SVGA chips uses all 8 bits! IBM actually says bits 0-7. */ break; case 0x17: /* Mode Control Register */ crtc(mode_control)=val; vga.tandy.line_mask = (~val) & 3; //Byte,word,dword mode if ( crtc(underline_location) & 0x40 ) vga.config.addr_shift = 2; else if ( crtc( mode_control) & 0x40 ) vga.config.addr_shift = 0; else vga.config.addr_shift = 1; if ( vga.tandy.line_mask ) { vga.tandy.line_shift = 13; vga.tandy.addr_mask = (1 << 13) - 1; } else { vga.tandy.addr_mask = ~0; vga.tandy.line_shift = 0; } VGA_CheckScanLength(); //Should we really need to do a determinemode here? // VGA_DetermineMode(); /* 0 If clear use CGA compatible memory addressing system by substituting character row scan counter bit 0 for address bit 13, thus creating 2 banks for even and odd scan lines. 1 If clear use Hercules compatible memory addressing system by substituting character row scan counter bit 1 for address bit 14, thus creating 4 banks. 2 If set increase scan line counter only every second line. 3 If set increase memory address counter only every other character clock. 5 When in Word Mode bit 15 is rotated to bit 0 if this bit is set else bit 13 is rotated into bit 0. 6 If clear system is in word mode. Addresses are rotated 1 position up bringing either bit 13 or 15 into bit 0. 7 Clearing this bit will reset the display system until the bit is set again. */ break; case 0x18: /* Line Compare Register */ crtc(line_compare)=val; vga.config.line_compare=(vga.config.line_compare & 0x700) | val; /* 0-7 Lower 8 bits of the Line Compare. When the Line counter reaches this value, the display address wraps to 0. Provides Split Screen facilities. Bit 8 is found in 3d4h index 7 bit 4. Bit 9 is found in 3d4h index 9 bit 6. */ break; default: if (svga.write_p3d5) { svga.write_p3d5(crtc(index), val, iolen); } else { LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:CRTC:Write to unknown index %X",crtc(index)); } break; }
Bitu vga_read_p3d4(Bitu port,Bitu iolen) { return crtc(index); }
void vga_write_p3d4(Bitu port,Bitu val,Bitu iolen) { crtc(index)=val; }