From 93f8b62a16bef6f11c656ad006caf83d20f32f96 Mon Sep 17 00:00:00 2001 From: Curt Coder Date: Tue, 21 Feb 2017 09:51:07 +0200 Subject: [PATCH] abc80: Converted to scanline based rendering, partially fixing hiresinv demo. [Curt Coder] --- src/mame/drivers/abc80.cpp | 13 +-- src/mame/includes/abc80.h | 16 ++- src/mame/video/abc80.cpp | 218 ++++++++++++++++++------------------- 3 files changed, 124 insertions(+), 123 deletions(-) diff --git a/src/mame/drivers/abc80.cpp b/src/mame/drivers/abc80.cpp index f03fc92f19b..600fec01c75 100644 --- a/src/mame/drivers/abc80.cpp +++ b/src/mame/drivers/abc80.cpp @@ -65,6 +65,7 @@ Notes: TODO: + - hiresinv graphics artifacts - proper keyboard controller emulation - MyAB TKN80 80-column card - GeJo 80-column card @@ -393,12 +394,6 @@ WRITE8_MEMBER( abc80_state::kbd_w ) timer_set(attotime::from_msec(50), TIMER_ID_FAKE_KEYBOARD_CLEAR); } -/* -DEVICE_INPUT_DEFAULTS_START( abc830_slow ) - DEVICE_INPUT_DEFAULTS("SW1", 0x0f, 0x03) - DEVICE_INPUT_DEFAULTS("S1", 0x01, 0x01) -DEVICE_INPUT_DEFAULTS_END -*/ //************************************************************************** @@ -413,7 +408,9 @@ void abc80_state::device_timer(emu_timer &timer, device_timer_id id, int param, { switch (id) { - case TIMER_ID_PIO: + case TIMER_ID_SCANLINE: + draw_scanline(m_bitmap, m_screen->vpos()); + m_pio_astb = !m_pio_astb; m_pio->strobe_a(m_pio_astb); @@ -628,4 +625,4 @@ ROM_END //************************************************************************** // YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS -COMP( 1978, abc80, 0, 0, abc80, abc80, driver_device, 0, "Luxor Datorer AB", "ABC 80", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_KEYBOARD ) +COMP( 1978, abc80, 0, 0, abc80, abc80, driver_device, 0, "Luxor Datorer AB", "ABC 80", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_KEYBOARD ) diff --git a/src/mame/includes/abc80.h b/src/mame/includes/abc80.h index 38db71c8207..f8ee642eda9 100644 --- a/src/mame/includes/abc80.h +++ b/src/mame/includes/abc80.h @@ -27,9 +27,9 @@ #define ABC80_HTOTAL 384 #define ABC80_HBEND 35 #define ABC80_HBSTART 384 -#define ABC80_VTOTAL 312 +#define ABC80_VTOTAL 313 #define ABC80_VBEND 15 -#define ABC80_VBSTART 312 +#define ABC80_VBSTART 313 #define ABC80_K5_HSYNC 0x01 #define ABC80_K5_DH 0x02 @@ -76,6 +76,7 @@ public: m_ram(*this, RAM_TAG), m_rs232(*this, RS232_TAG), m_palette(*this, "palette"), + m_screen(*this, SCREEN_TAG), m_rom(*this, Z80_TAG), m_mmu_rom(*this, "mmu"), m_char_rom(*this, "chargen"), @@ -98,6 +99,7 @@ public: required_device m_ram; required_device m_rs232; required_device m_palette; + required_device m_screen; required_memory_region m_rom; required_memory_region m_mmu_rom; required_memory_region m_char_rom; @@ -109,7 +111,7 @@ public: enum { - TIMER_ID_PIO, + TIMER_ID_SCANLINE, TIMER_ID_CASSETTE, TIMER_ID_BLINK, TIMER_ID_VSYNC_ON, @@ -131,7 +133,7 @@ public: virtual void video_start() override; uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); - void update_screen(bitmap_rgb32 &bitmap, const rectangle &cliprect); + void draw_scanline(bitmap_rgb32 &bitmap, int y); DECLARE_READ8_MEMBER( read ); DECLARE_WRITE8_MEMBER( write ); @@ -161,8 +163,12 @@ public: int m_pio_astb; // video state + bitmap_rgb32 m_bitmap; uint8_t m_latch; int m_blink; + int m_c; + int m_r; + int m_mode; // cassette state bool m_motor; @@ -170,7 +176,7 @@ public: int m_tape_in_latch; // timers - emu_timer *m_pio_timer; + emu_timer *m_scanline_timer; emu_timer *m_cassette_timer; emu_timer *m_blink_timer; emu_timer *m_vsync_on_timer; diff --git a/src/mame/video/abc80.cpp b/src/mame/video/abc80.cpp index 5808e89729a..c8d8327c2a8 100644 --- a/src/mame/video/abc80.cpp +++ b/src/mame/video/abc80.cpp @@ -37,154 +37,152 @@ static GFXDECODE_START( abc80 ) GFXDECODE_END -//------------------------------------------------- -// update_screen - -//------------------------------------------------- - -void abc80_state::update_screen(bitmap_rgb32 &bitmap, const rectangle &cliprect) +void abc80_state::draw_scanline(bitmap_rgb32 &bitmap, int y) { - int c = 0; - int r = 0; - int mode = 0; + uint8_t vsync_data = m_vsync_prom->base()[y]; + uint8_t l = m_line_prom->base()[y]; + int dv = (vsync_data & ABC80_K2_DV) ? 1 : 0; - for (int y = 0; y < 312; y++) + if (!(vsync_data & ABC80_K2_FRAME_RESET)) { - uint8_t vsync_data = m_vsync_prom->base()[y]; - uint8_t l = m_line_prom->base()[y]; - int dv = (vsync_data & ABC80_K2_DV) ? 1 : 0; + // reset F2 + m_r = 0; + } - if (!(vsync_data & ABC80_K2_FRAME_RESET)) + for (int sx = 0; sx < 64; sx++) + { + uint8_t hsync_data = m_hsync_prom->base()[sx]; + if (!y) logerror("y %u sx %u HSYNC %u HV %u RE %u RR %u\n",y,sx,BIT(hsync_data,0),BIT(hsync_data,1),BIT(hsync_data,2),BIT(hsync_data,3)); + int dh = (hsync_data & ABC80_K5_DH) ? 1 : 0; + uint8_t data = 0; + + if (hsync_data & ABC80_K5_LINE_END) { - // reset F2 - r = 0; + // reset F4 + m_c = 0; + + // reset J5 + m_mode = 0; } - for (int sx = 0; sx < 64; sx++) + /* + + Video RAM Addressing Scheme + + A9 A8 A7 A6 A5 A4 A3 A2 A1 A0 + R2 R1 R0 xx xx xx xx C2 C1 C0 + + A6 A5 A4 A3 = 00 C5 C4 C3 + R4 R3 R4 R3 + + */ + + int a = (m_c >> 3) & 0x07; + int b = ((m_r >> 1) & 0x0c) | ((m_r >> 3) & 0x03); + int s = (a + b) & 0x0f; + uint16_t videoram_addr = ((m_r & 0x07) << 7) | (s << 3) | (m_c & 0x07); + uint8_t videoram_data = m_latch; + uint8_t attr_addr = ((dh & dv) << 7) | (videoram_data & 0x7f); + uint8_t attr_data = m_attr_prom->base()[attr_addr]; + + int blank = (attr_data & ABC80_J3_BLANK) ? 1 : 0; + int j = (attr_data & ABC80_J3_TEXT) ? 1 : 0; + int k = (attr_data & ABC80_J3_GRAPHICS) ? 1 : 0; + int versal = (attr_data & ABC80_J3_VERSAL) ? 1 : 0; + int cursor = (videoram_data & ABC80_CHAR_CURSOR) ? 1 : 0; + + if (!j && k) m_mode = 0; + if (j && !k) m_mode = 1; + if (j && k) m_mode = !m_mode; + + if (m_mode & versal) { - uint8_t hsync_data = m_hsync_prom->base()[sx]; - int dh = (hsync_data & ABC80_K5_DH) ? 1 : 0; - uint8_t data = 0; + // graphics mode + int r0 = 1, r1 = 1, r2 = 1; - if (hsync_data & ABC80_K5_LINE_END) - { - // reset F4 - c = 0; + if (l < 3) r0 = 0; else if (l < 7) r1 = 0; else r2 = 0; - // reset J5 - mode = 0; - } + int c0 = BIT(videoram_data, 0) | r0; + int c1 = BIT(videoram_data, 1) | r0; + int c2 = BIT(videoram_data, 2) | r1; + int c3 = BIT(videoram_data, 3) | r1; + int c4 = BIT(videoram_data, 4) | r2; + int c5 = BIT(videoram_data, 6) | r2; - /* + if (!(c0 & c2 & c4)) data |= 0xe0; + if (!(c1 & c3 & c5)) data |= 0x1c; + } + else + { + // text mode + uint16_t chargen_addr = ((videoram_data & 0x7f) * 10) + l; - Video RAM Addressing Scheme - - A9 A8 A7 A6 A5 A4 A3 A2 A1 A0 - R2 R1 R0 xx xx xx xx C2 C1 C0 - - A6 A5 A4 A3 = 00 C5 C4 C3 + R4 R3 R4 R3 - - */ - - int a = (c >> 3) & 0x07; - int b = ((r >> 1) & 0x0c) | ((r >> 3) & 0x03); - int s = (a + b) & 0x0f; - uint16_t videoram_addr = ((r & 0x07) << 7) | (s << 3) | (c & 0x07); - uint8_t videoram_data = m_latch; - uint8_t attr_addr = ((dh & dv) << 7) | (videoram_data & 0x7f); - uint8_t attr_data = m_attr_prom->base()[attr_addr]; - - int blank = (attr_data & ABC80_J3_BLANK) ? 1 : 0; - int j = (attr_data & ABC80_J3_TEXT) ? 1 : 0; - int k = (attr_data & ABC80_J3_GRAPHICS) ? 1 : 0; - int versal = (attr_data & ABC80_J3_VERSAL) ? 1 : 0; - int cursor = (videoram_data & ABC80_CHAR_CURSOR) ? 1 : 0; - - if (!j && k) mode = 0; - if (j && !k) mode = 1; - if (j && k) mode = !mode; - - if (mode & versal) - { - // graphics mode - int r0 = 1, r1 = 1, r2 = 1; - - if (l < 3) r0 = 0; else if (l < 7) r1 = 0; else r2 = 0; - - int c0 = BIT(videoram_data, 0) | r0; - int c1 = BIT(videoram_data, 1) | r0; - int c2 = BIT(videoram_data, 2) | r1; - int c3 = BIT(videoram_data, 3) | r1; - int c4 = BIT(videoram_data, 4) | r2; - int c5 = BIT(videoram_data, 6) | r2; - - if (!(c0 & c2 & c4)) data |= 0xe0; - if (!(c1 & c3 & c5)) data |= 0x1c; - } - else - { - // text mode - uint16_t chargen_addr = ((videoram_data & 0x7f) * 10) + l; - - data = m_char_rom->base()[chargen_addr]; - } - - // shift out pixels - for (int bit = 0; bit < 6; bit++) - { - int color = BIT(data, 7); - int x = (sx * 6) + bit; - - color ^= (cursor & m_blink); - color &= blank; - - bitmap.pix32(y, x) = m_palette->pen(color); - - data <<= 1; - } - - m_latch = m_video_ram[videoram_addr]; - - if (hsync_data & ABC80_K5_ROW_START) - { - // clock F4 - c++; - } + data = m_char_rom->base()[chargen_addr]; } - if (vsync_data & ABC80_K2_FRAME_END) + // shift out pixels + for (int bit = 0; bit < 6; bit++) { - // clock F2 - r++; + int color = BIT(data, 7); + int x = (sx * 6) + bit; + + color ^= (cursor & m_blink); + color &= blank; + + bitmap.pix32(y, x) = m_palette->pen(color); + + data <<= 1; } + + m_latch = m_video_ram[videoram_addr]; + + if (hsync_data & ABC80_K5_ROW_START) + { + // clock F4 + m_c++; + } + } + + if (vsync_data & ABC80_K2_FRAME_END) + { + // clock F2 + m_r++; } } +//------------------------------------------------- +// video_start - +//------------------------------------------------- + void abc80_state::video_start() { - screen_device *screen = machine().device(SCREEN_TAG); - + m_screen->register_screen_bitmap(m_bitmap); + // start timers - m_pio_timer = timer_alloc(TIMER_ID_PIO); - m_pio_timer->adjust(screen->time_until_pos(0, 0), 0, screen->scan_period()); + m_scanline_timer = timer_alloc(TIMER_ID_SCANLINE); + m_scanline_timer->adjust(m_screen->time_until_pos(0, 0), 0, m_screen->scan_period()); m_blink_timer = timer_alloc(TIMER_ID_BLINK); m_blink_timer->adjust(attotime::from_hz(XTAL_11_9808MHz/2/6/64/312/16), 0, attotime::from_hz(XTAL_11_9808MHz/2/6/64/312/16)); m_vsync_on_timer = timer_alloc(TIMER_ID_VSYNC_ON); - m_vsync_on_timer->adjust(screen->time_until_pos(0, 0), 0, screen->frame_period()); + m_vsync_on_timer->adjust(m_screen->time_until_pos(0, 0), 0, m_screen->frame_period()); m_vsync_off_timer = timer_alloc(TIMER_ID_VSYNC_OFF); - m_vsync_off_timer->adjust(screen->time_until_pos(16, 0), 0, screen->frame_period()); + m_vsync_off_timer->adjust(m_screen->time_until_pos(16, 0), 0, m_screen->frame_period()); // allocate memory m_video_ram.allocate(0x400); } +//------------------------------------------------- +// screen_update - +//------------------------------------------------- + uint32_t abc80_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { - update_screen(bitmap, cliprect); + copybitmap(bitmap, m_bitmap, 0, 0, 0, 0, cliprect); return 0; }