diff options
Diffstat (limited to 'src/mame/drivers/myb3k.cpp')
-rw-r--r-- | src/mame/drivers/myb3k.cpp | 844 |
1 files changed, 646 insertions, 198 deletions
diff --git a/src/mame/drivers/myb3k.cpp b/src/mame/drivers/myb3k.cpp index 0a66728c42e..db026731935 100644 --- a/src/mame/drivers/myb3k.cpp +++ b/src/mame/drivers/myb3k.cpp @@ -9,13 +9,11 @@ Slotified and corrected by Joakim Larsson Edstrom based on Step/One service manuals: http://nivelleringslikaren.eu/stepone/ - TODO: - - Finalize the non 8255 based Keyboard interface - - Add more modes to the non standard video controller - - Hook up all interrupts and 8255 Port C signals - - Add printer support on Port A + - Fix proper cursor support + - Fix Hi-Res 640x400 mode when MC6845 supports interlaced mode - Expansion Unit with 6 more ISA8 slots + - Proper waitstate support when 8088 CPU core admits it and remove the workaround in machine_start PC INCOMPATIBILITIES: - COM card lives at io address 0x540 @@ -37,33 +35,49 @@ #include "machine/pit8253.h" #include "machine/i8257.h" #include "sound/spkrdev.h" +#include "softlist.h" #include "speaker.h" +#include "machine/ram.h" #include "machine/wd_fdc.h" #include "bus/isa/isa.h" #include "bus/isa/myb3k_com.h" #include "bus/isa/myb3k_fdc.h" +#include "bus/centronics/ctronics.h" #include "video/mc6845.h" #include "screen.h" -//#define LOG_GENERAL (1U << 0) //defined in logmacro.h already #define LOG_PPI (1U << 1) #define LOG_PIT (1U << 2) #define LOG_PIC (1U << 3) #define LOG_CRT (1U << 4) #define LOG_DMA (1U << 5) #define LOG_KBD (1U << 6) - -//#define VERBOSE (LOG_GENERAL | LOG_CRT) +#define LOG_VMOD (1U << 7) +#define LOG_PIX (1U << 8) +#define LOG_M2 (1U << 9) +#define LOG_M3 (1U << 10) +#define LOG_SCRL (1U << 11) +#define LOG_CENT (1U << 12) +#define LOG_RAM (1U << 13) + +//#define VERBOSE (LOG_VMOD|LOG_RAM) //#define LOG_OUTPUT_STREAM std::cout #include "logmacro.h" -#define LOGPPI(...) LOGMASKED(LOG_PPI, __VA_ARGS__) -#define LOGPIT(...) LOGMASKED(LOG_PIT, __VA_ARGS__) -#define LOGPIC(...) LOGMASKED(LOG_PIC, __VA_ARGS__) -#define LOGCRT(...) LOGMASKED(LOG_CRT, __VA_ARGS__) -#define LOGDMA(...) LOGMASKED(LOG_DMA, __VA_ARGS__) -#define LOGKBD(...) LOGMASKED(LOG_KBD, __VA_ARGS__) +#define LOGPPI(...) LOGMASKED(LOG_PPI, __VA_ARGS__) +#define LOGPIT(...) LOGMASKED(LOG_PIT, __VA_ARGS__) +#define LOGPIC(...) LOGMASKED(LOG_PIC, __VA_ARGS__) +#define LOGCRT(...) LOGMASKED(LOG_CRT, __VA_ARGS__) +#define LOGDMA(...) LOGMASKED(LOG_DMA, __VA_ARGS__) +#define LOGKBD(...) LOGMASKED(LOG_KBD, __VA_ARGS__) +#define LOGVMOD(...) LOGMASKED(LOG_VMOD, __VA_ARGS__) +#define LOGPIX(...) LOGMASKED(LOG_PIX, __VA_ARGS__) +#define LOGM2(...) LOGMASKED(LOG_M2, __VA_ARGS__) +#define LOGM3(...) LOGMASKED(LOG_M3, __VA_ARGS__) +#define LOGSCRL(...) LOGMASKED(LOG_SCRL, __VA_ARGS__) +#define LOGCENT(...) LOGMASKED(LOG_CENT, __VA_ARGS__) +#define LOGRAM(...) LOGMASKED(LOG_RAM, __VA_ARGS__) #ifdef _MSC_VER #define FUNCNAME __func__ @@ -77,6 +91,7 @@ public: myb3k_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag) , m_maincpu(*this, "maincpu") + , m_ram(*this, RAM_TAG) , m_pic8259(*this, "pic") , m_pit8253(*this, "pit") , m_ppi8255(*this, "ppi") @@ -84,50 +99,126 @@ public: , m_speaker(*this, "speaker") , m_kb(*this, "myb3k_keyboard") , m_crtc(*this, "crtc") - , m_p_vram(*this, "p_vram") - , m_palette(*this, "palette") + , m_vram(*this, "vram") , m_isabus(*this, "isa") + , m_centronics(*this, "centronics") + , m_io_dsw1(*this, "DSW1") + , m_io_monitor(*this, "MONITOR") + , m_io_j4(*this, "J4") + , m_io_j5(*this, "J5") + , m_screen(*this, "screen") { } - - DECLARE_READ8_MEMBER(myb3k_kbd_r); - void kbd_set_data_and_interrupt(u8 data); - - DECLARE_WRITE8_MEMBER(myb3k_6845_address_w); - DECLARE_WRITE8_MEMBER(myb3k_6845_data_w); - DECLARE_WRITE8_MEMBER(myb3k_video_mode_w); - DECLARE_WRITE8_MEMBER(myb3k_fdc_output_w); - uint32_t screen_update_myb3k(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); +public: + /* Interrupt controller */ DECLARE_WRITE_LINE_MEMBER( pic_int_w ); - DECLARE_WRITE_LINE_MEMBER( pit_out1_changed ); - DECLARE_WRITE8_MEMBER(ppi_porta_w); + /* Parallel port */ DECLARE_READ8_MEMBER(ppi_portb_r); DECLARE_WRITE8_MEMBER(ppi_portc_w); - DECLARE_READ8_MEMBER( io_dack0_r ){ uint8_t tmp = m_isabus->dack_r(0); LOGDMA("%s: %02x\n", FUNCNAME, tmp); return tmp; } - DECLARE_READ8_MEMBER( io_dack1_r ){ uint8_t tmp = m_isabus->dack_r(1); LOGDMA("%s: %02x\n", FUNCNAME, tmp); return tmp; } - DECLARE_READ8_MEMBER( io_dack2_r ){ uint8_t tmp = m_isabus->dack_r(2); LOGDMA("%s: %02x\n", FUNCNAME, tmp); return tmp; } - DECLARE_READ8_MEMBER( io_dack3_r ){ uint8_t tmp = m_isabus->dack_r(3); LOGDMA("%s: %02x\n", FUNCNAME, tmp); return tmp; } - DECLARE_WRITE8_MEMBER( io_dack0_w ){ LOGDMA("%s: %02x\n", FUNCNAME, data); m_isabus->dack_w(0,data); } - DECLARE_WRITE8_MEMBER( io_dack1_w ){ LOGDMA("%s: %02x\n", FUNCNAME, data); m_isabus->dack_w(1,data); } - DECLARE_WRITE8_MEMBER( io_dack2_w ){ LOGDMA("%s: %02x\n", FUNCNAME, data); m_isabus->dack_w(2,data); } - DECLARE_WRITE8_MEMBER( io_dack3_w ){ LOGDMA("%s: %02x\n", FUNCNAME, data); m_isabus->dack_w(3,data); } - DECLARE_WRITE_LINE_MEMBER( dack0_w ) { LOGDMA("%s: %d\n", FUNCNAME, state); select_dma_channel(0, state); } - DECLARE_WRITE_LINE_MEMBER( dack1_w ) { LOGDMA("%s: %d\n", FUNCNAME, state); select_dma_channel(1, state); } - DECLARE_WRITE_LINE_MEMBER( dack2_w ) { LOGDMA("%s: %d\n", FUNCNAME, state); select_dma_channel(2, state); } - DECLARE_WRITE_LINE_MEMBER( dack3_w ) { LOGDMA("%s: %d\n", FUNCNAME, state); select_dma_channel(3, state); } - DECLARE_READ8_MEMBER(dma_memory_read_byte); - DECLARE_WRITE8_MEMBER(dma_memory_write_byte); - DECLARE_WRITE8_MEMBER(dma_segment_w); + /* DMA controller */ DECLARE_WRITE_LINE_MEMBER( hrq_w ); DECLARE_WRITE_LINE_MEMBER( tc_w ); + DECLARE_WRITE8_MEMBER(dma_segment_w); + DECLARE_READ8_MEMBER(dma_memory_read_byte); + DECLARE_WRITE8_MEMBER(dma_memory_write_byte); + DECLARE_READ8_MEMBER( io_dack0_r ) { uint8_t tmp = m_isabus->dack_r(0); LOGDMA("%s: %02x\n", FUNCNAME, tmp); return tmp; } + DECLARE_READ8_MEMBER( io_dack1_r ) { uint8_t tmp = m_isabus->dack_r(1); LOGDMA("%s: %02x\n", FUNCNAME, tmp); return tmp; } + DECLARE_READ8_MEMBER( io_dack2_r ) { uint8_t tmp = m_isabus->dack_r(2); LOGDMA("%s: %02x\n", FUNCNAME, tmp); return tmp; } + DECLARE_READ8_MEMBER( io_dack3_r ) { uint8_t tmp = m_isabus->dack_r(3); LOGDMA("%s: %02x\n", FUNCNAME, tmp); return tmp; } + DECLARE_WRITE8_MEMBER( io_dack0_w ) { LOGDMA("%s: %02x\n", FUNCNAME, data); m_isabus->dack_w(0,data); } + DECLARE_WRITE8_MEMBER( io_dack1_w ) { LOGDMA("%s: %02x\n", FUNCNAME, data); m_isabus->dack_w(1,data); } + DECLARE_WRITE8_MEMBER( io_dack2_w ) { LOGDMA("%s: %02x\n", FUNCNAME, data); m_isabus->dack_w(2,data); } + DECLARE_WRITE8_MEMBER( io_dack3_w ) { LOGDMA("%s: %02x\n", FUNCNAME, data); m_isabus->dack_w(3,data); } + DECLARE_WRITE_LINE_MEMBER( dack0_w ){ LOGDMA("%s: %d\n", FUNCNAME, state); select_dma_channel(0, state); } + DECLARE_WRITE_LINE_MEMBER( dack1_w ){ LOGDMA("%s: %d\n", FUNCNAME, state); select_dma_channel(1, state); } + DECLARE_WRITE_LINE_MEMBER( dack2_w ){ LOGDMA("%s: %d\n", FUNCNAME, state); select_dma_channel(2, state); } + DECLARE_WRITE_LINE_MEMBER( dack3_w ){ LOGDMA("%s: %d\n", FUNCNAME, state); select_dma_channel(3, state); } + + /* Timer */ + DECLARE_WRITE_LINE_MEMBER( pit_out1_changed ); + + /* Video controller */ + MC6845_UPDATE_ROW(crtc_update_row); + + /* ISA+ Expansion bus */ + DECLARE_WRITE_LINE_MEMBER( isa_irq5_w ); + DECLARE_WRITE_LINE_MEMBER( isa_irq7_w ); + + /* Centronics */ + DECLARE_WRITE_LINE_MEMBER (centronics_ack_w); + DECLARE_WRITE_LINE_MEMBER (centronics_busy_w); + DECLARE_WRITE_LINE_MEMBER (centronics_perror_w); + DECLARE_WRITE_LINE_MEMBER (centronics_select_w); + + /* Keyboard */ + DECLARE_READ8_MEMBER(myb3k_kbd_r); + void kbd_set_data_and_interrupt(u8 data); + + /* Video Controller */ + DECLARE_WRITE8_MEMBER(myb3k_video_mode_w); + + /* Monitor */ + DECLARE_INPUT_CHANGED_MEMBER(monitor_changed); + + /* Status bits */ + DECLARE_READ8_MEMBER(myb3k_io_status_r); + +private: + virtual void machine_start() override; + virtual void machine_reset() override; + + /* Interrupt Controller */ + void pic_ir5_w(int source, int state); + void pic_ir7_w(int source, int state); + + /* Jumper fields J4/J5 */ + enum + { + PPI_PC3 = 0x01, + ISA_IRQ5 = 0x02, + ISA_IRQ7 = 0x04, + CENT_ACK = 0x08 + }; + + /* Paralell port */ + enum + { + PC0_STROBE = 0x01, // Printer interface + PC1_SETPAGE = 0x02, // Graphics circuit + PC2_DISPST = 0x04, // Graphics circuit + PC3_LPENB = 0x08, // Lightpen enable + PC4_CURSR = 0x10, // Cursor Odd/Even + PC5_BUZON = 0x20, // Speaker On/Off + PC6_CMTWRD = 0x40, + PC7_CMTEN = 0x80 // Cassette or Speaker + }; + + /* DMA controller */ void select_dma_channel(int channel, bool state); + /* Timer */ + enum + { + TIMER_ID_KEY_INTERRUPT + }; + void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; + + /* Status bits */ + enum + { + IOSTAT_BUSY = 0x01, + IOSTAT_NONE = 0x02, + IOSTAT_PRPE = 0x04, + IOSTAT_FAULT = 0x08 + }; + void stepone(machine_config &config); void jb3000(machine_config &config); void myb3k(machine_config &config); protected: required_device<cpu_device> m_maincpu; + required_device<ram_device> m_ram; required_device<pic8259_device> m_pic8259; required_device<pit8253_device> m_pit8253; required_device<i8255_device> m_ppi8255; @@ -135,32 +226,41 @@ protected: required_device<speaker_sound_device> m_speaker; required_device<myb3k_keyboard_device> m_kb; required_device<h46505_device> m_crtc; - required_shared_ptr<uint8_t> m_p_vram; - required_device<palette_device> m_palette; + required_shared_ptr<uint8_t> m_vram; required_device<isa8_device> m_isabus; + optional_device<centronics_device> m_centronics; + + required_ioport m_io_dsw1; + required_ioport m_io_monitor; + required_ioport m_io_j4; + required_ioport m_io_j5; + required_device<screen_device> m_screen; + int m_dma_channel; bool m_cur_tc; uint8_t m_kbd_data; // Data inside the 74LS164 serial to parallel converter. - uint8_t m_kbd_second_byte; - uint8_t m_crtc_vreg[0x100],m_crtc_index; uint8_t m_vmode; + rgb_t (*m_pal)[8]; + rgb_t m_cpal[8]; + rgb_t m_mpal[8]; + uint8_t m_portc; uint8_t m_dma_page[4]; // a 74670, 4 x 4 bit storage latch - virtual void machine_start() override; - virtual void machine_reset() override; - virtual void video_start() override; + int8_t m_io_status; }; -void myb3k_state::video_start() +READ8_MEMBER(myb3k_state::myb3k_io_status_r) { - LOG("%s\n", FUNCNAME); + LOGCENT("%s\n", FUNCNAME); + return m_io_status & 0x0f; } READ8_MEMBER( myb3k_state::myb3k_kbd_r ) { LOGKBD("%s: %02x\n", FUNCNAME, m_kbd_data); - // IN from port 0x04 enables a 74LS244 buffer that - // presents to the CPU the parallell bits from the 74LS164 - // serial to parallel converter. + + /* IN from port 0x04 enables a 74LS244 buffer that + presents to the CPU the parallell bits from the 74LS164 + serial to parallel converter.*/ m_pic8259->ir1_w(CLEAR_LINE); return m_kbd_data; } @@ -168,85 +268,266 @@ READ8_MEMBER( myb3k_state::myb3k_kbd_r ) void myb3k_state::kbd_set_data_and_interrupt(u8 data) { LOGKBD("%s: %02x\n", FUNCNAME, data); m_kbd_data = data; - m_pic8259->ir1_w(ASSERT_LINE); -} -#define mc6845_h_char_total (m_crtc_vreg[0]) -#define mc6845_h_display (m_crtc_vreg[1]) -#define mc6845_h_sync_pos (m_crtc_vreg[2]) -#define mc6845_sync_width (m_crtc_vreg[3]) -#define mc6845_v_char_total (m_crtc_vreg[4]) -#define mc6845_v_total_adj (m_crtc_vreg[5]) -#define mc6845_v_display (m_crtc_vreg[6]) -#define mc6845_v_sync_pos (m_crtc_vreg[7]) -#define mc6845_mode_ctrl (m_crtc_vreg[8]) -#define mc6845_tile_height (m_crtc_vreg[9]+1) -#define mc6845_cursor_y_start (m_crtc_vreg[0x0a]) -#define mc6845_cursor_y_end (m_crtc_vreg[0x0b]) -#define mc6845_start_addr (((m_crtc_vreg[0x0c]<<8) & 0x3f00) | (m_crtc_vreg[0x0d] & 0xff)) -#define mc6845_cursor_addr (((m_crtc_vreg[0x0e]<<8) & 0x3f00) | (m_crtc_vreg[0x0f] & 0xff)) -#define mc6845_light_pen_addr (((m_crtc_vreg[0x10]<<8) & 0x3f00) | (m_crtc_vreg[0x11] & 0xff)) -#define mc6845_update_addr (((m_crtc_vreg[0x12]<<8) & 0x3f00) | (m_crtc_vreg[0x13] & 0xff)) - -uint32_t myb3k_state::screen_update_myb3k(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) -{ - int x,y; - int xi,yi; - int dot; - int h_step; + /* The INT7 line is pulled low when a clock is detected from the keyboard. */ + m_pic8259->ir1_w(CLEAR_LINE); - h_step = 64 >> (m_vmode & 3); + /* When the clock stops, the INT7 line goes back high. This triggers the interrupt. + We simulate the time it takes to send the 8 bits over the serial line + here. It should be 0.8ms but is rounded off to 1ms. */ + timer_set(attotime::from_msec(1), TIMER_ID_KEY_INTERRUPT); +} - //popmessage("%02x %d",m_vmode,h_step); +void myb3k_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) +{ + switch (id) + { + case TIMER_ID_KEY_INTERRUPT: + /* The serial transfer of 8 bits is complete. Now trigger INT7. */ + m_pic8259->ir1_w(ASSERT_LINE); + break; + } +} - for(y = 0; y < mc6845_v_display; y++) +MC6845_UPDATE_ROW( myb3k_state::crtc_update_row ) +{ + /* The 6845 is not programmed to get 80 character modes or 400 pixels width but this is managed by external circuitry that selects + the apropriate pixelclock based on the video mode latch at i/o address 0x04. This callback always get x_count set to 40 */ + uint8_t row_length = (m_vmode & 0x02) || (m_vmode == 0 && (m_pal == &m_mpal)) ? x_count * 2 : x_count; + for (int x_pos = 0; x_pos < row_length; x_pos++) { - for(x = 0; x < mc6845_h_display; x++) + uint16_t page = (m_portc & PC1_SETPAGE) ? 0x8000 : 0; + + if ((m_portc & PC2_DISPST) == 0) + { + for (int pxl = 0; pxl < 8; pxl++) + { + bitmap.pix32(y, ( x_pos * 8) + pxl) = rgb_t::black(); + } + } + else { - /* 8x8 grid gfxs, weird format too ... */ - for(yi=0;yi<mc6845_tile_height;yi++) + //uint32_t pdat; + switch (m_vmode) { - for(xi=0;xi<8;xi++) + case 0: + // Color connector doing 320x200, 40x25 characters, 8 grey tones + if ((m_io_monitor->read() & 1) == 0) + { + uint32_t rowstart = (((x_pos + ma) * 32 + ra) & 0x7fff) + page; + uint32_t pdat = ((m_vram[rowstart + 0] & 0xff) << 16); // Green 8 bits + pdat |= ((m_vram[rowstart + 8] & 0xf0) << 8); // Red upper 4 bits + pdat |= ((m_vram[rowstart + 8] & 0x0f) << 4); // Blue upper 4 bits + pdat |= ((m_vram[rowstart + 24] & 0xf0) << 4); // Red lower 4 bits + pdat |= ((m_vram[rowstart + 24] & 0x0f) << 0); // Blue lower 4 bits + for (int pxl = 0; pxl < 8; pxl++) + { + uint16_t pind = 0; + /* Pixeldata for 8 pixels are stored in pdat as GGRRBB */ + pind = (((pdat & (0x800000 >> pxl)) ? 0x04 : 0x00) | + ((pdat & (0x008000 >> pxl)) ? 0x02 : 0x00) | + ((pdat & (0x000080 >> pxl)) ? 0x01 : 0x00) ); + + /* Check if we are in a cursor and create cursor if so */ + pind ^= ((cursor_x != -1 && x_pos == cursor_x && ra == 7) ? 7 : 0); + + /* Create the grey scale */ + bitmap.pix32(y, ( x_pos * 8) + pxl) = rgb_t(m_mpal[pind & 0x07].g(),m_mpal[pind & 0x07].g(),m_mpal[pind & 0x07].g()); + } + } + else // Monochrome connector doing 640x200, 80x25, b&w + { + uint32_t rowstart = (((x_pos + ma * 2) * 16 + ra) & 0x7fff) + page; + uint16_t pdat = m_vram[rowstart]; + for (int pxl = 0; pxl < 8; pxl++) + { + if ((pdat & (0x80 >> pxl)) != 0) + { + //bitmap.pix32(y, ( x_pos * 8) + pxl) = (*m_pal)[0x07]; + bitmap.pix32(y, ( x_pos * 8) + pxl) = m_mpal[0x07]; + } + else + { + bitmap.pix32(y, ( x_pos * 8) + pxl) = rgb_t::black(); + } + } + } + break; + case 1: { - dot = (m_p_vram[(x+y*mc6845_h_display)*h_step+yi+0x8000] >> (7-xi)) & 1; - if((yi & ~7 && (!(m_vmode & 4))) || (yi & ~0xf && (m_vmode & 4))) - dot = 0; + uint32_t pdat; + // Crude fix of 36CH mode + if ((m_io_dsw1->read() & 0x0c) == 0 && ra > 7) + { + // text mode only, 36x25 char, 8 color, discarding raster rows with what appears to be garbish + // needs to be implemented LLE to verify the function of that data, possibly related to Kanji support + pdat = 0x00; // This gets wrong when background color is not black + } + else + { // 320x200, 40x25 char, 8 color + uint32_t rowstart = (((x_pos + ma) * 32 + ra) & 0x7fff) + page; + pdat = ((m_vram[rowstart + 0] & 0xff) << 16); // Green 8 bits + pdat |= ((m_vram[rowstart + 8] & 0xf0) << 8); // Red upper 4 bits + pdat |= ((m_vram[rowstart + 8] & 0x0f) << 4); // Blue upper 4 bits + pdat |= ((m_vram[rowstart + 24] & 0xf0) << 4); // Red lower 4 bits + pdat |= ((m_vram[rowstart + 24] & 0x0f) << 0); // Blue lower 4 bits + if (pdat != 0) + { + LOGPIX(" - PDAT:%06x from offset %04x RA=%d\n", pdat, rowstart + 0, ra); + } + } + + for (int pxl = 0; pxl < 8; pxl++) + { + uint16_t pind = 0; + /* Pixeldata for 8 pixels are stored in pdat as GGRRBB */ + pind = (((pdat & (0x800000 >> pxl)) ? 0x04 : 0x00) | + ((pdat & (0x008000 >> pxl)) ? 0x02 : 0x00) | + ((pdat & (0x000080 >> pxl)) ? 0x01 : 0x00) ); + + /* Check if we are in a cursor and create cursor if so */ + pind ^= ((cursor_x != -1 && x_pos == cursor_x && ra == 7) ? 7 : 0); + + /* Pick up the color */ + bitmap.pix32(y, ( x_pos * 8) + pxl) = (*m_pal)[pind & 0x07]; + } + } + break; - if(y*mc6845_tile_height+yi < 200 && x*8+xi < 320) /* TODO: safety check */ - bitmap.pix16(y*mc6845_tile_height+yi, x*8+xi) = m_palette->pen(dot); + case 6: /* 640x400, 80 char, white on black - fall through to case 2 if monochrome monitor + Mode 6 is an interlaced mode so should induce flicker on the color monitor but be + ok on the monochrome green monitor */ + case 2: /* 640x200, 80 char, white on black */ + { + uint32_t rowstart = (((x_pos + ma * 2) * 16 + ra) & 0x7fff) + page; + uint16_t pdat = m_vram[rowstart]; + //if (pdat16 != 0) + LOGM2(" - PDAT:%06x from offset %04x RA=%d X:%d Y:%d DE:%d HBP:%d VBP:%d\n", pdat, (x_pos * 2 + ma * 2) * 16 + ra + page + 0, ra, x_pos, y, de, hbp, vbp); + + /* Check if we are in a cursor and create cursor if so */ + //pdat ^= ((cursor_x != -1 && x_pos/2 == cursor_x && ra == 7) ? 0xff : 0); + + for (int pxl = 0; pxl < 8; pxl++) + { + if ((pdat & (0x80 >> pxl)) != 0) + { + bitmap.pix32(y, ( x_pos * 8) + pxl) = (*m_pal)[0x07]; + } + else + { + bitmap.pix32(y, ( x_pos * 8) + pxl) = rgb_t::black(); + } + } } + break; + default: + logerror("unimplemented video mode: %02x\n", m_vmode); } } } - - return 0; -} - -WRITE8_MEMBER( myb3k_state::myb3k_6845_address_w ) -{ - LOGCRT("%s: %02x\n", FUNCNAME, data); - - m_crtc_index = data; - m_crtc->address_w(space, offset, data); } -WRITE8_MEMBER( myb3k_state::myb3k_6845_data_w ) -{ - LOGCRT("%s: %02x\n", FUNCNAME, data); - - m_crtc_vreg[m_crtc_index] = data; - m_crtc->register_w(space, offset, data); -} +/* + * Setup of 6845 in different graphics modes from basica command line + * screen chars per row 36/40/80, rows 20/25, mode 0/1/2/3 + * + * chars 36 40 80 80 36 40 80 36 40 + * rows 25 25 25 25 20 20 20 25 25 + * mode 1 1 2 3 0 0 0 0 0 - as per basica "screen x,y,mode" + *---------------------------------------------------------------------------- + * R0 55 55 55 55 55 55 55 55 55 - Horizontal Total + * R1 40 40 40 40 40 40 40 40 40 - Horizontal Displayed + * R2 44 44 44 44 44 44 44 44 44 - Horizontal Sync Position + * R3 132 132 132 52 132 132 132 52 52 - Sync Width + * R4 31 31 31 26 24 24 24 26 26 - Vertical Total + * R5 0 0 0 7 9 9 9 7 7 - Vertical Total Adjust + * R6 25 25 25 25 20 20 20 25 25 - Vertical Displayed + * R7 27 27 27 25 22 22 22 25 25 - Vertical Sync Position + * R8 0 0 0 3 0 0 0 3 3 - Interlace & Skew + * R9 7 7 7 14 9 9 9 14 14 - Maximum Raster Address + * R10 96 96 96 96 96 96 96 96 96 - Cursor Start Address + * R11 7 7 7 15 9 9 9 15 15 - Cursor End Address + * R12 0 0 0 0 0 0 0 0 0 - Start Address (H) + * R13 0 0 0 0 0 0 0 0 0 - Start Address (L) + * --------------------------------------------------------------------------- + * vmode 1 1 2 6 1 1 2 5 5 - as per 3 bits latch at I/O 0x04 + * xres 320 320 640 640 320 320 640 320 320 + * yres 200 200 200 400 200 200 200 400 400 + * char 40 40 80 80 40 40 80 40 40 + */ WRITE8_MEMBER( myb3k_state::myb3k_video_mode_w ) { - LOGCRT("%s: %02x\n", FUNCNAME, data); + LOG("%s: %02x\n", FUNCNAME, data); + LOGVMOD("Video Mode %02x\n", data); /* ---- -x-- interlace mode */ /* ---- --xx horizontal step count (number of offsets of vram RAM data to skip, 64 >> n) */ m_vmode = data; + switch (data & 7) + { + case 0: + if ((m_io_monitor->read() & 1) == 0) + { + LOGVMOD(" - Color display 320x200 on 40x25 8 grey tones\n"); + rectangle rect(0, 320 - 1, 0, 200 - 1); + m_screen->configure(320, 200, rect, HZ_TO_ATTOSECONDS(50)); + break; + } + else // Monochrome connector selected? + { + LOGVMOD(" - Monochrome 640x200 on 80x25 \n"); + rectangle rect(0, 640 - 1, 0, 200 - 1); + m_screen->configure(640, 200, rect, HZ_TO_ATTOSECONDS(50)); + break; + } + + case 1: /* 320x200 */ + { + LOGVMOD(" - 320x200, 40 char, 8 color or 8 tones of green...\n"); + rectangle rect(0, 320 - 1, 0, 200 - 1); + m_screen->configure(320, 200, rect, HZ_TO_ATTOSECONDS(50)); + } + break; + + case 2: /* 640x200 - boots up in this mode */ + { + LOGVMOD(" - 640x200, 80 char, white on black...\n"); + rectangle rect(0, 640 - 1, 0, 200 - 1); + m_screen->configure(640, 200, rect, HZ_TO_ATTOSECONDS(50)); + } + break; + + case 3: /* Fail */ + LOGVMOD(" - bad mode...\n"); + break; + case 4: /* Fail */ + LOGVMOD(" - bad mode...\n"); + break; + + case 5: /* 320x400 */ + { + LOGVMOD("320x400, 40 char, white on black\n"); + rectangle rect(0, 320 - 1, 0, 400 - 1); + m_screen->configure(320, 400, rect, HZ_TO_ATTOSECONDS(50)); + } + break; + + case 6: /* 640x400 */ + { + LOGVMOD("640x400, 80 char, white on black\n"); + rectangle rect(0, 640 - 1, 0, 400 - 1); + m_screen->configure(640, 400, rect, HZ_TO_ATTOSECONDS(50)); + } + break; + + case 7: /* Fail */ + LOGVMOD(" - bad mode...\n"); + break; + default: logerror("Wrong Video Mode %d, contact the maintainer\n", data); + } } /********************************************************** @@ -307,56 +588,68 @@ WRITE8_MEMBER( myb3k_state::myb3k_video_mode_w ) * OFF ON - ? * ON ON - ? **********************************************************/ -#define PC0_STROBE 0x01 // Printer interface -#define PC1_SETPAGE 0x02 // Graphics circuit -#define PC2_DISPST 0x04 // Graphics circuit -#define PC3_LPENB 0x08 // Lightpen enable -#define PC4_CURSR 0x10 // Cursor Odd/Even -#define PC5_BUZON 0x20 // Speaker On/Off -#define PC6_CMTWRD 0x40 -#define PC7_CMTEN 0x80 // Cassette or Speaker - static ADDRESS_MAP_START(myb3k_map, AS_PROGRAM, 8, myb3k_state) ADDRESS_MAP_UNMAP_HIGH - AM_RANGE(0x00000,0x3ffff) AM_RAM // It's either 128Kb or 256Kb RAM + //AM_RANGE(0x00000,0x3ffff) AM_RAM // It's either 128Kb or 256Kb RAM installed by machine_start() AM_RANGE(0x40000,0x7ffff) AM_NOP AM_RANGE(0x80000,0xcffff) AM_NOP // Expansion Unit connected through an ISA8 cable - AM_RANGE(0xd0000,0xdffff) AM_RAM AM_SHARE("p_vram") // Area 6, physical at 30000-3FFFF (128Kb RAM) or 10000-1FFFF (256KB RAM) + AM_RANGE(0xd0000,0xeffff) AM_RAM AM_SHARE("vram") // Area 6, physical at 30000-3FFFF (128Kb RAM) or 10000-1FFFF (256KB RAM) AM_RANGE(0xf0000,0xfffff) AM_ROM AM_REGION("ipl", 0) // Area 7, 8 x 8Kb ADDRESS_MAP_END static ADDRESS_MAP_START(myb3k_io, AS_IO, 8, myb3k_state) ADDRESS_MAP_UNMAP_LOW -// AM_RANGE(0x000,0x7ff) // Main Unit -// 0-3 8255A PPI parallel port + /* Main Unit 0-0x7ff */ + // 0-3 8255A PPI parallel port AM_RANGE(0x00, 0x03) AM_DEVREADWRITE("ppi", i8255_device, read, write) -// Discrete latches + + // Discrete latches AM_RANGE(0x04, 0x04) AM_READ(myb3k_kbd_r) AM_RANGE(0x04, 0x04) AM_WRITE(myb3k_video_mode_w) // b0=40CH, b1=80CH, b2=16 raster -// AM_RANGE(0x05, 0x05) AM_READ(myb3k_io_status_r) + AM_RANGE(0x05, 0x05) AM_READ(myb3k_io_status_r) // printer connector bits: b3=fault b2=paper out b1 or b0=busy AM_RANGE(0x05, 0x05) AM_WRITE(dma_segment_w) // b0-b3=addr, b6=A b7=B AM_RANGE(0x06, 0x06) AM_READ_PORT("DSW2") -// 8-9 8259A interrupt controller + + // 8-9 8259A interrupt controller AM_RANGE(0x08, 0x09) AM_DEVREADWRITE("pic", pic8259_device, read, write) -// c-f 8253 PIT timer + + // c-f 8253 PIT timer AM_RANGE(0x0c, 0x0f) AM_DEVREADWRITE("pit", pit8253_device, read, write) -// 10-18 8257 DMA + + // 10-18 8257 DMA AM_RANGE(0x10, 0x18) AM_DEVREADWRITE("dma", i8257_device, read, write) -// 1c-1d HD46505S CRTC - AM_RANGE(0x1c, 0x1c) AM_WRITE(myb3k_6845_address_w) - AM_RANGE(0x1d, 0x1d) AM_WRITE(myb3k_6845_data_w) -// AM_RANGE(0x800,0xfff) // Expansion Unit + + // 1c-1d HD46505S CRTC + AM_RANGE(0x1c, 0x1c) AM_DEVREADWRITE("crtc", h46505_device, status_r, address_w) + AM_RANGE(0x1d, 0x1d) AM_DEVREADWRITE("crtc", h46505_device, register_r, register_w) + + /* Expansion Unit 0x800 - 0xfff */ ADDRESS_MAP_END /* Input ports - from Step/One service manual */ static INPUT_PORTS_START( myb3k ) + PORT_START("J4") + PORT_CONFNAME( 0x03, 0x01, "IRQ5 source") + PORT_CONFSETTING( 0x01, "ISA IRQ5") + PORT_CONFSETTING( 0x02, "PPI PC3 (Light Pen)") + + PORT_START("J5") + PORT_CONFNAME( 0x0c, 0x08, "IRQ7 source") + PORT_CONFSETTING( 0x04, "ISA IRQ7") + PORT_CONFSETTING( 0x08, "Centronics Ack") + + PORT_START("MONITOR") + PORT_CONFNAME( 0x01, 0x00, "Monitor") PORT_CHANGED_MEMBER(DEVICE_SELF, myb3k_state, monitor_changed, 0) + PORT_CONFSETTING( 0x00, "Color") + PORT_CONFSETTING( 0x01, "Monochrome") + PORT_START("DSW1") PORT_DIPUNUSED_DIPLOC(0x01, 0x01, "SW1:1") PORT_DIPUNUSED_DIPLOC(0x02, 0x02, "SW1:2") - PORT_DIPNAME( 0x0c, 0x08, "Display Mode") PORT_DIPLOCATION("SW1:3,4") + PORT_DIPNAME( 0x0c, 0x00, "Display Mode") PORT_DIPLOCATION("SW1:3,4") PORT_DIPSETTING( 0x0c, "80CH 8 raster" ) - PORT_DIPSETTING( 0x08, "80CH 16 raster" ) - PORT_DIPSETTING( 0x04, "40CH 8 raster" ) + PORT_DIPSETTING( 0x04, "80CH 16 raster" ) + PORT_DIPSETTING( 0x08, "40CH 8 raster" ) PORT_DIPSETTING( 0x00, "36CH 10 raster" ) PORT_DIPNAME( 0x10, 0x10, "Expansion Unit" ) PORT_DIPLOCATION("SW1:5") PORT_DIPSETTING( 0x00, "Attached" ) @@ -369,6 +662,7 @@ static INPUT_PORTS_START( myb3k ) PORT_DIPNAME( 0x80, 0x80, "Flexible Disk Drive type for boot" ) PORT_DIPLOCATION("SW1:8") PORT_DIPSETTING( 0x00, "8-inch Flexible Disk Unit" ) // 0x520-0x524 range PORT_DIPSETTING( 0x80, "5.25-inch Flexible Disk Drive" ) // 0x20-0x24 range + PORT_START("DSW2") PORT_DIPNAME( 0x01, 0x00, "Check mode" ) PORT_DIPLOCATION("SW2:1") // ROM information PORT_DIPSETTING( 0x01, DEF_STR( Off ) ) @@ -389,12 +683,93 @@ static INPUT_PORTS_START( myb3k ) PORT_DIPSETTING( 0x00, "11" ) INPUT_PORTS_END +INPUT_CHANGED_MEMBER(myb3k_state::monitor_changed) +{ + if ((m_io_monitor->read() & 1) == 1) + { + m_pal = &m_mpal; + if ((m_vmode & 7) == 0) + { + LOGVMOD(" - Monochrome 640x200 on 80x25 \n"); + rectangle rect(0, 640 - 1, 0, 200 - 1); + m_screen->configure(640, 200, rect, HZ_TO_ATTOSECONDS(50)); + } + } + else + { + m_pal = &m_cpal; + if ((m_vmode & 7) == 0) + { + m_pal = &m_mpal; + LOGVMOD(" - Color display 320x200 on 40x25 8 grey tones\n"); + rectangle rect(0, 320 - 1, 0, 200 - 1); + m_screen->configure(320, 200, rect, HZ_TO_ATTOSECONDS(50)); + } + } +} void myb3k_state::machine_start() { LOG("%s\n", FUNCNAME); + /* Color palette for use with a RGB color CRT monitor such as the 12" Ericsson DU4720: + 76 degrees deflection, WxHxD: 373x375x428mm, Weight 12.8 Kg, 215x134.4mm display area, + RGB signal with separate syncs */ + m_cpal[0] = rgb_t( 0, 0, 0); // black 0.29v + m_cpal[1] = rgb_t( 0, 0, 255); // blue 0.52v + m_cpal[2] = rgb_t(255, 0, 0); // red 0.58v + m_cpal[3] = rgb_t(255, 0, 255); // magenta 0.63v + m_cpal[4] = rgb_t( 0, 255, 0); // green 0.71v + m_cpal[5] = rgb_t( 0, 255, 255); // cyan 0.80v + m_cpal[6] = rgb_t(255, 255, 0); // yellow 0.90v + m_cpal[7] = rgb_t(255, 255, 255); // white 1.04v + + /* Monochrome offset based on the voltage levels from the Service Manual, relation between colors anc voltage might + not be linear though so may need visual tweaking for a Green P39 phospor CRT such as the 12" Ericsson DU4721 + 90 degrees deflection, WxHxD: 373x370x351mm, Weight 9.3 Kg, 215x134.4mm display area, Composite video signal */ + m_mpal[0] = rgb_t((uint8_t)(( (0.29 - 0.29) / (1.04 - 0.29) ) * 74), (uint8_t)(( (0.29 - 0.29) / (1.04 - 0.29) ) * 255), 0); // 0.29v + m_mpal[1] = rgb_t((uint8_t)(( (0.52 - 0.29) / (1.04 - 0.29) ) * 74), (uint8_t)(( (0.52 - 0.29) / (1.04 - 0.29) ) * 255), 0); // 0.52v + m_mpal[2] = rgb_t((uint8_t)(( (0.58 - 0.29) / (1.04 - 0.29) ) * 74), (uint8_t)(( (0.58 - 0.29) / (1.04 - 0.29) ) * 255), 0); // 0.58v + m_mpal[3] = rgb_t((uint8_t)(( (0.63 - 0.29) / (1.04 - 0.29) ) * 74), (uint8_t)(( (0.63 - 0.29) / (1.04 - 0.29) ) * 255), 0); // 0.63v + m_mpal[4] = rgb_t((uint8_t)(( (0.71 - 0.29) / (1.04 - 0.29) ) * 74), (uint8_t)(( (0.71 - 0.29) / (1.04 - 0.29) ) * 255), 0); // 0.71v + m_mpal[5] = rgb_t((uint8_t)(( (0.80 - 0.29) / (1.04 - 0.29) ) * 74), (uint8_t)(( (0.80 - 0.29) / (1.04 - 0.29) ) * 255), 0); // 0.80v + m_mpal[6] = rgb_t((uint8_t)(( (0.90 - 0.29) / (1.04 - 0.29) ) * 74), (uint8_t)(( (0.90 - 0.29) / (1.04 - 0.29) ) * 255), 0); // 0.90v + m_mpal[7] = rgb_t((uint8_t)(( (1.04 - 0.29) / (1.04 - 0.29) ) * 74), (uint8_t)(( (1.04 - 0.29) / (1.04 - 0.29) ) * 255), 0); // 1.04v + + /* Init a default palette */ + m_pal = &m_mpal; // In case screen starts rendering before machine_reset where we read the settings + + /* CPU can only access RAM 50% of the time and the CRTC the other 50%. This waitstate workaround gives + close enough performance of the DOS 1.25 "basica demo" compared to the real hardware */ + m_maincpu->set_clock_scale(0.5f); + + /* Setup ram - NOTE; video RAM is really a mirror of last 64KB of main memory and not the opposite as indicated below. */ + if (m_ram->size() <= (1024 * 128)) + { + LOGRAM("128KB System\n"); + m_maincpu->space(AS_PROGRAM).install_ram(0, 0xffff, m_ram->pointer()); // Install first 64KB of main memory + m_maincpu->space(AS_PROGRAM).install_ram(0x10000, 0x1ffff, m_vram); // Install mirror of video RAM as the last 64Kb of main memory + } + else + { + LOGRAM("256KB System\n"); + m_maincpu->space(AS_PROGRAM).install_ram(0, 0x2ffff, m_ram->pointer()); // Install 192KB (128KB Storage Module + first 64KB of main memory) + m_maincpu->space(AS_PROGRAM).install_ram(0x30000, 0x3ffff, m_vram); // Install mirror of video RAM as the last 64KB of main memory + } + + /* No key presses allowed yet */ m_kbd_data = 0; + + save_item (NAME (m_dma_channel)); + save_item (NAME (m_cur_tc)); + save_item (NAME (m_kbd_data)); + save_item (NAME (m_vmode)); + save_item (NAME (m_portc)); + save_item (NAME (*m_pal)); + save_pointer(NAME(m_mpal), sizeof(m_mpal)); + save_pointer(NAME(m_cpal), sizeof(m_cpal)); + save_pointer(NAME(m_dma_page), sizeof(m_dma_page)); + save_item (NAME (m_io_status)); } void myb3k_state::machine_reset() @@ -402,7 +777,10 @@ void myb3k_state::machine_reset() LOG("%s\n", FUNCNAME); m_cur_tc = false; m_dma_channel = -1; + m_vmode = 0; + m_portc = 0; memset(m_dma_page, 0, sizeof(m_dma_page)); + m_pal = &m_mpal; } void myb3k_state::select_dma_channel(int channel, bool state) @@ -434,6 +812,22 @@ WRITE_LINE_MEMBER(myb3k_state::pic_int_w) m_maincpu->set_input_line(0, state); } +/* pic_ir5_w - select interrupt source depending on jumper J4 setting, either ISA IRQ5 or PPI PC3 (Light Pen) */ +void myb3k_state::pic_ir5_w(int source, int state) +{ + LOGPIC("%s: %d\n", FUNCNAME, state); + if (!machine().paused() && (source & m_io_j4->read())) + m_pic8259->ir5_w(state); +} + +/* pic_ir7_w - select interrupt source depending on jumper J5 setting, either ISA IRQ7 or Centronics Ack */ +void myb3k_state::pic_ir7_w(int source, int state) +{ + LOGPIC("%s: %d\n", FUNCNAME, state); + if (!machine().paused() && (source & m_io_j5->read())) + m_pic8259->ir7_w(state); +} + WRITE_LINE_MEMBER( myb3k_state::pit_out1_changed ) { LOGPIT("%s: %d\n", FUNCNAME, state); @@ -449,6 +843,7 @@ WRITE8_MEMBER(myb3k_state::dma_segment_w) WRITE_LINE_MEMBER(myb3k_state::hrq_w) { LOGDMA("%s: %d\n", FUNCNAME, state); + // Should connect to hold input clocked by DMA clock but hold isn't emulated m_maincpu->set_input_line(INPUT_LINE_HALT, state); @@ -463,6 +858,7 @@ READ8_MEMBER(myb3k_state::dma_memory_read_byte) address_space& prog_space = m_maincpu->space(AS_PROGRAM); uint8_t tmp = prog_space.read_byte(offset | m_dma_page[m_dma_channel & 3] << 16); LOGDMA("%s: %x:%04x => %02x\n", FUNCNAME, m_dma_channel, offset, tmp); + return tmp; } @@ -472,20 +868,15 @@ WRITE8_MEMBER(myb3k_state::dma_memory_write_byte) address_space& prog_space = m_maincpu->space(AS_PROGRAM); LOGDMA("%s: %x:%04x <= %02x\n", FUNCNAME, m_dma_channel, offset, data); - return prog_space.write_byte(offset | m_dma_page[m_dma_channel & 3] << 16, data); -} - -WRITE8_MEMBER( myb3k_state::ppi_porta_w ) -{ - LOGPPI("%s: %02x\n", FUNCNAME, data); - return; + return prog_space.write_byte(offset | m_dma_page[m_dma_channel & 3] << 16, data); } READ8_MEMBER( myb3k_state::ppi_portb_r ) { LOGPPI("%s\n", FUNCNAME); - return ioport("DSW1")->read(); + + return m_io_dsw1->read(); } WRITE8_MEMBER( myb3k_state::ppi_portc_w ) @@ -501,6 +892,10 @@ WRITE8_MEMBER( myb3k_state::ppi_portc_w ) LOGPPI(" - CMTEN : %d\n", (data & PC7_CMTEN) ? 1 : 0); LOGPPI(" => CMTEN: %d BUZON: %d\n", (data & PC7_CMTEN) ? 1 : 0, (data & PC5_BUZON)? 1 : 0); + /* Centronics strobe signal */ + LOGCENT("Centronics strobe %d\n", (data & PC0_STROBE) ? 1 : 0); + m_centronics->write_strobe((data & PC0_STROBE) ? 1 : 0); + /* * The actual logic around enabling the buzzer is a bit more complicated involving the cassette interface * According to the schematics gate1 is enabled if either @@ -510,23 +905,59 @@ WRITE8_MEMBER( myb3k_state::ppi_portc_w ) */ m_pit8253->write_gate1(!(data & PC5_BUZON) && (data & PC7_CMTEN)? 1 : 0); + /* Update light pen interrupt */ + pic_ir5_w(PPI_PC3, (data & PC3_LPENB) ? 1 : 0); + + m_portc = data; + return; } -static const gfx_layout myb3k_charlayout = +/* ISA IRQ5 handler */ +WRITE_LINE_MEMBER (myb3k_state::isa_irq5_w) { - 8, 8, - 0x400, - 1, - { 0 }, - { STEP8(0,1) }, - { STEP8(0,8) }, - 8*8 -}; + LOGCENT("%s %d\n", FUNCNAME, state); + pic_ir5_w(ISA_IRQ5, state); +} + +/* ISA IRQ7 handler */ +WRITE_LINE_MEMBER (myb3k_state::isa_irq7_w) +{ + LOGCENT("%s %d\n", FUNCNAME, state); + pic_ir7_w(ISA_IRQ7, state); +} + +/* Centronics ACK handler */ +WRITE_LINE_MEMBER (myb3k_state::centronics_ack_w) +{ + LOGCENT("%s %d\n", FUNCNAME, state); + pic_ir7_w(CENT_ACK, state); +} + +/* Centronics BUSY handler + * The busy line is enterring the schematics from the connector but is lost to its way to the status latch + * but there is only two possibilities, either D0 or D1 */ +WRITE_LINE_MEMBER (myb3k_state::centronics_busy_w){ + LOGCENT("%s %d\n", FUNCNAME, state); + if (state == ASSERT_LINE) + m_io_status &= ~IOSTAT_BUSY; + else + m_io_status |= IOSTAT_BUSY; +} -static GFXDECODE_START( myb3k ) - GFXDECODE_ENTRY( "ipl", 0x0000, myb3k_charlayout, 0, 1 ) -GFXDECODE_END +/* Centronics PERROR handler */ +WRITE_LINE_MEMBER (myb3k_state::centronics_perror_w){ + LOGCENT("%s %d\n", FUNCNAME, state); + if (state == ASSERT_LINE) + m_io_status &= ~IOSTAT_FAULT; + else + m_io_status |= IOSTAT_FAULT; +} + +/* Centronics SELECT handler - The centronics select signal is not used by this hardware */ +WRITE_LINE_MEMBER (myb3k_state::centronics_select_w){ + LOGCENT("%s %d - not used by machine\n", FUNCNAME, state); +} static SLOT_INTERFACE_START(stepone_isa_cards) SLOT_INTERFACE("myb3k_com", ISA8_MYB3K_COM) @@ -541,35 +972,22 @@ MACHINE_CONFIG_START(myb3k_state::myb3k) MCFG_CPU_IO_MAP(myb3k_io) MCFG_CPU_IRQ_ACKNOWLEDGE_DEVICE("pic", pic8259_device, inta_cb) - /* Expansion bus */ - MCFG_DEVICE_ADD("isa", ISA8, 0) - MCFG_ISA8_CPU(":maincpu") - MCFG_ISA_OUT_IRQ2_CB(DEVWRITELINE("pic", pic8259_device, ir2_w)) - MCFG_ISA_OUT_IRQ3_CB(DEVWRITELINE("pic", pic8259_device, ir3_w)) - MCFG_ISA_OUT_IRQ4_CB(DEVWRITELINE("pic", pic8259_device, ir4_w)) - MCFG_ISA_OUT_IRQ5_CB(DEVWRITELINE("pic", pic8259_device, ir5_w)) // Jumper J4 selectable - MCFG_ISA_OUT_IRQ6_CB(DEVWRITELINE("pic", pic8259_device, ir6_w)) - MCFG_ISA_OUT_IRQ7_CB(DEVWRITELINE("pic", pic8259_device, ir7_w)) // Jumper J5 selectable -// MCFG_ISA_OUT_DRQ0_CB(DEVWRITELINE("dma", i8257_device, dreq0_w)) // Part of ISA16 but not ISA8 standard but implemented on ISA8 B8 (SRDY) on this motherboard - MCFG_ISA_OUT_DRQ1_CB(DEVWRITELINE("dma", i8257_device, dreq1_w)) - MCFG_ISA_OUT_DRQ2_CB(DEVWRITELINE("dma", i8257_device, dreq2_w)) - MCFG_ISA_OUT_DRQ3_CB(DEVWRITELINE("dma", i8257_device, dreq3_w)) - MCFG_ISA8_SLOT_ADD("isa", "isa1", stepone_isa_cards, "myb3k_fdc4711", false) - MCFG_ISA8_SLOT_ADD("isa", "isa2", stepone_isa_cards, "myb3k_com", false) - MCFG_ISA8_SLOT_ADD("isa", "isa3", stepone_isa_cards, nullptr, false) + /* RAM options */ + MCFG_RAM_ADD(RAM_TAG) + MCFG_RAM_DEFAULT_SIZE("256K") + MCFG_RAM_EXTRA_OPTIONS("128K, 256K") - /* Interrupt Controller TODO: Add trampolin to read jumper J4 and J5 for IRQ sources */ - /* Jumper J4 selects LPSTB or ISA interrupt 5 for IR5 */ - /* Jumper J5 selects PRINT or ISA interrupt 7 for IR7 */ + /* Interrupt controller */ MCFG_DEVICE_ADD("pic", PIC8259, 0) MCFG_PIC8259_OUT_INT_CB(WRITELINE(myb3k_state, pic_int_w)) + /* Parallel port */ MCFG_DEVICE_ADD("ppi", I8255A, 0) - MCFG_I8255_OUT_PORTA_CB(WRITE8(myb3k_state, ppi_porta_w)) + MCFG_I8255_OUT_PORTA_CB(DEVWRITE8("cent_data_out", output_latch_device, write)) MCFG_I8255_IN_PORTB_CB(READ8(myb3k_state, ppi_portb_r)) MCFG_I8255_OUT_PORTC_CB(WRITE8(myb3k_state, ppi_portc_w)) - /* DMA chip */ + /* DMA controller */ MCFG_DEVICE_ADD("dma", I8257, XTAL_14_31818MHz / 6) MCFG_I8257_OUT_HRQ_CB(WRITELINE(myb3k_state, hrq_w)) MCFG_I8257_OUT_TC_CB(WRITELINE(myb3k_state, tc_w)) @@ -588,45 +1006,75 @@ MACHINE_CONFIG_START(myb3k_state::myb3k) MCFG_I8257_OUT_DACK_2_CB(WRITELINE(myb3k_state, dack2_w)) MCFG_I8257_OUT_DACK_3_CB(WRITELINE(myb3k_state, dack3_w)) - /* Timer chip */ + /* Timer */ MCFG_DEVICE_ADD("pit", PIT8253, 0) MCFG_PIT8253_CLK0(XTAL_14_31818MHz / 12.0) /* TIMINT straight into IRQ0 */ MCFG_PIT8253_OUT0_HANDLER(DEVWRITELINE("pic", pic8259_device, ir0_w)) MCFG_PIT8253_CLK1(XTAL_14_31818MHz / 12.0) /* speaker if port c bit 5 is low */ MCFG_PIT8253_OUT1_HANDLER(WRITELINE(myb3k_state, pit_out1_changed)) -// MCFG_PIT8253_CLK2(XTAL_14_31818MHz / 12.0) /* ANDed with port c bit 6 but marked as "not use"*/ -// MCFG_PIT8253_OUT2_HANDLER(WRITELINE(myb3k_state, pit_out2_changed)) + // MCFG_PIT8253_CLK2(XTAL_14_31818MHz / 12.0) /* ANDed with port c bit 6 but marked as "not use"*/ + // MCFG_PIT8253_OUT2_HANDLER(WRITELINE(myb3k_state, pit_out2_changed)) + + /* Video controller */ + MCFG_MC6845_ADD("crtc", H46505, "screen", XTAL_14_31818MHz / 16) /* Main crystal divided by 16 through a 74163 4 bit counter */ + MCFG_MC6845_SHOW_BORDER_AREA(false) + MCFG_MC6845_CHAR_WIDTH(8) + MCFG_MC6845_UPDATE_ROW_CB(myb3k_state, crtc_update_row) + + /* ISA8+ Expansion bus */ + MCFG_DEVICE_ADD("isa", ISA8, 0) + MCFG_ISA8_CPU(":maincpu") + MCFG_ISA_OUT_IRQ2_CB(DEVWRITELINE("pic", pic8259_device, ir2_w)) + MCFG_ISA_OUT_IRQ3_CB(DEVWRITELINE("pic", pic8259_device, ir3_w)) + MCFG_ISA_OUT_IRQ4_CB(DEVWRITELINE("pic", pic8259_device, ir4_w)) + MCFG_ISA_OUT_IRQ5_CB(WRITELINE(myb3k_state, isa_irq5_w)) // Jumper J4 selectable + MCFG_ISA_OUT_IRQ6_CB(DEVWRITELINE("pic", pic8259_device, ir6_w)) + MCFG_ISA_OUT_IRQ7_CB(WRITELINE(myb3k_state, isa_irq7_w)) // Jumper J5 selectable + //MCFG_ISA_OUT_DRQ0_CB(DEVWRITELINE("dma", i8257_device, dreq0_w)) // Part of ISA16 but not ISA8 standard but implemented on ISA8 B8 (SRDY) on this motherboard + MCFG_ISA_OUT_DRQ1_CB(DEVWRITELINE("dma", i8257_device, dreq1_w)) + MCFG_ISA_OUT_DRQ2_CB(DEVWRITELINE("dma", i8257_device, dreq2_w)) + MCFG_ISA_OUT_DRQ3_CB(DEVWRITELINE("dma", i8257_device, dreq3_w)) + MCFG_ISA8_SLOT_ADD("isa", "isa1", stepone_isa_cards, "myb3k_fdc4711", false) + MCFG_ISA8_SLOT_ADD("isa", "isa2", stepone_isa_cards, "myb3k_com", false) + MCFG_ISA8_SLOT_ADD("isa", "isa3", stepone_isa_cards, nullptr, false) + + /* Centronics */ + MCFG_CENTRONICS_ADD ("centronics", centronics_devices, "printer") + MCFG_CENTRONICS_ACK_HANDLER (WRITELINE (myb3k_state, centronics_ack_w)) + MCFG_CENTRONICS_BUSY_HANDLER (WRITELINE (myb3k_state, centronics_busy_w)) + MCFG_CENTRONICS_PERROR_HANDLER (WRITELINE (myb3k_state, centronics_perror_w)) + MCFG_CENTRONICS_SELECT_HANDLER (WRITELINE (myb3k_state, centronics_select_w)) + MCFG_CENTRONICS_OUTPUT_LATCH_ADD ("cent_data_out", "centronics") - /* sound hardware */ + /* Sound */ MCFG_SPEAKER_STANDARD_MONO("mono") MCFG_SOUND_ADD("speaker", SPEAKER_SOUND, 0) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00) + /* Keyboard */ MCFG_DEVICE_ADD("myb3k_keyboard", MYB3K_KEYBOARD, 0) MCFG_MYB3K_KEYBOARD_CB(PUT(myb3k_state, kbd_set_data_and_interrupt)) - /* video hardware */ - MCFG_SCREEN_ADD_MONOCHROME("screen", RASTER, rgb_t::green()) - MCFG_SCREEN_REFRESH_RATE(50) - MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */ - MCFG_SCREEN_SIZE(320, 200) - MCFG_SCREEN_VISIBLE_AREA(0, 320-1, 0, 200-1) - MCFG_SCREEN_UPDATE_DRIVER(myb3k_state, screen_update_myb3k) - MCFG_SCREEN_PALETTE("palette") - - MCFG_GFXDECODE_ADD("gfxdecode", "palette", myb3k) - MCFG_PALETTE_ADD_MONOCHROME("palette") - - /* devices */ - MCFG_MC6845_ADD("crtc", H46505, "screen", XTAL_14_31818MHz / 16) /* Main crystal divided by 16 through a 74163 4 bit counter */ - MCFG_MC6845_SHOW_BORDER_AREA(false) - MCFG_MC6845_CHAR_WIDTH(8) + /* Monitor */ + MCFG_SCREEN_ADD("screen", RASTER) + MCFG_SCREEN_RAW_PARAMS(XTAL_14_31818MHz / 3, 600, 0, 600, 400, 0, 400) + MCFG_SCREEN_UPDATE_DEVICE("crtc", h46505_device, screen_update) MACHINE_CONFIG_END MACHINE_CONFIG_DERIVED(myb3k_state::jb3000, myb3k) + /* Keyboard */ + MCFG_DEVICE_REPLACE("myb3k_keyboard", JB3000_KEYBOARD, 0) + MCFG_MYB3K_KEYBOARD_CB(PUT(myb3k_state, kbd_set_data_and_interrupt)) + MACHINE_CONFIG_END MACHINE_CONFIG_DERIVED(myb3k_state::stepone, myb3k) + /* Keyboard */ + MCFG_DEVICE_REPLACE("myb3k_keyboard", STEPONE_KEYBOARD, 0) + MCFG_MYB3K_KEYBOARD_CB(PUT(myb3k_state, kbd_set_data_and_interrupt)) + + /* software lists */ + MCFG_SOFTWARE_LIST_ADD("stepone_flop_list", "stepone_flop") MACHINE_CONFIG_END /* ROM definitions, ROM area is 8 x 8Kb and can be populated with 2732 mask ROMs or 2764s */ @@ -649,6 +1097,6 @@ ROM_START( stepone ) ROM_END // YEAR NAME PARENT COMPAT MACHINE INPUT STATE INIT COMPANY FULLNAME FLAGS -COMP( 1982, myb3k, 0, 0, myb3k, myb3k, myb3k_state, 0, "Matsushita", "MyBrain 3000", MACHINE_NOT_WORKING | MACHINE_NO_SOUND) -COMP( 1982, jb3000, myb3k, 0, jb3000, myb3k, myb3k_state, 0, "Panasonic", "JB-3000", MACHINE_NOT_WORKING | MACHINE_NO_SOUND) -COMP( 1984, stepone, myb3k, 0, stepone, myb3k, myb3k_state, 0, "Ericsson", "Step/One", MACHINE_NOT_WORKING | MACHINE_NO_SOUND) +COMP( 1982, myb3k, 0, 0, myb3k, myb3k, myb3k_state, 0, "Matsushita", "MyBrain 3000", 0) +COMP( 1982, jb3000, myb3k, 0, jb3000, myb3k, myb3k_state, 0, "Panasonic", "JB-3000", MACHINE_NOT_WORKING) // No rom dump available +COMP( 1984, stepone, myb3k, 0, stepone, myb3k, myb3k_state, 0, "Ericsson", "Step/One", 0) |