summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/drivers/pc6001.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/drivers/pc6001.cpp')
-rw-r--r--src/mame/drivers/pc6001.cpp2476
1 files changed, 2476 insertions, 0 deletions
diff --git a/src/mame/drivers/pc6001.cpp b/src/mame/drivers/pc6001.cpp
new file mode 100644
index 00000000000..aadd261c5b0
--- /dev/null
+++ b/src/mame/drivers/pc6001.cpp
@@ -0,0 +1,2476 @@
+// license:BSD-3-Clause
+// copyright-holders:Angelo Salese
+/*******************************************************************************************************************************************************
+
+ PC-6001 series (c) 1981 NEC
+
+ driver by Angelo Salese
+
+ TODO:
+ - Hook up tape loading, images that are floating around the net are already
+ ADC'ed, so they should be easy to implement (but not exactly faithful)
+ - cassette handling requires a decap of the MCU. It could be possible to
+ do some tight synch between the master CPU and a code simulation,but I think
+ it's not worth the effort...
+ - Identify and hook-up the FDC device, apparently PC-6001 and PC-6601 doesn't even use the same thing;
+ - PC-6601: mon r-0 type games doesn't seem to work at all on this system?
+ - PC-6001SR: get it to boot, also implement MK-2 compatibility mode (it changes the memory map to behave like the older versions)
+ - Currently rewriting the video part without the MC6847 for two reasons:
+ A) the later models have a custom video chip in the place of the MC6847,
+ so this implementation will be used in the end.
+ B) It's easier to me to see what the attribute vram does since I don't
+ have any docs atm.
+
+ TODO (game specific):
+ - (several AX* games, namely Galaxy Mission Part 1/2 and others): inputs doesn't work
+ - AX6 - Demo: When AY-based speech talks, other emus emulates the screen drawing to be a solid green (plain PC-6001) or solid white (Mk2 version),
+ but, according to an original video reference that I've seen, that screen should actually some kind of weird garbage on it ...
+ - AX6 - Powered Knight: doesn't work too well, according to the asm code it asks the player to press either 'B' or 'C' then a number but
+ nothing is shown on screen, other emus behaves the same, bad dump?
+ - Dawn Patrol (cart): presumably too slow;
+ (Mk2 mode 5 games)
+ - 3D Golf Simulation Super Version: gameplay / inputs seems broken
+ - American Truck: Screen is offset at the loading screen, loading bug?
+ - Castle Excellent: copyright text drawing is quite bogus, scans text in vertical instead of horizontal?
+ - Dezeni Land (ALL versions) / Hurry Fox 1/2: asks you to "load something", can't do it with current cassette kludge, also, for Dezeni Land(s) keyboard irqs
+ doesn't seem to work too well with halt opcode execution?
+ - Dezeni Land 1/4: dies after loading of main program
+ - Dezeni Land 2: dies at the "load something" screen with presumably wrong stack opcodes
+ - (MyCom BASIC games with multiple files): most of them refuses to run ... how to load them?
+ - Grobda: when "get ready" speech plays, screen should be full white but instead it's all black, same issue as AX-6 Demo?
+ - Pac-Man / Tiny Xevious 2: gameplay is too fast
+ - Salad no Kunino Tomato-Hime: can't start a play
+ - Space Harrier: inputs doesn't work properly
+ - The Black Onyx: dies when it attempts to save the character, that obviously means saving on the tape
+ - Yakyukyo / Punchball Mario: waits for an irq, check which one;
+
+========================================================================================================================================================
+
+ PC-6001 (1981-09):
+
+ * CPU: Z80A @ 4 MHz
+ * ROM: 16KB + 4KB (chargen) - no kanji
+ * RAM: 16KB, it can be expanded to 32KB
+ * Text Mode: 32x16 and 2 colors
+ * Graphic Modes: 64x48 (9 colors), 128x192 (4 colors), 256x192 (2 colors)
+ * Sound: BEEP + PSG - Optional Voice Synth Cart
+ * Keyboard: JIS Keyboard with 5 function keys, control key, TAB key,
+ HOME/CLR key, INS key, DEL key, GRAPH key, Japanese syllabary
+ key, page key, STOP key, and cursor key (4 directions)
+ * 1 cartslot, optional floppy drive, optional serial 232 port, 2
+ joystick ports
+
+
+ PC-6001 mkII (1983-07):
+
+ * CPU: Z80A @ 4 MHz
+ * ROM: 32KB + 16KB (chargen) + 32KB (kanji) + 16KB (Voice Synth)
+ * RAM: 64KB
+ * Text Mode: same as PC-6001 with N60-BASIC; 40x20 and 15 colors with
+ N60M-BASIC
+ * Graphic Modes: same as PC-6001 with N60-BASIC; 80x40 (15 colors),
+ 160x200 (15 colors), 320x200 (4 colors) with N60M-BASIC
+ * Sound: BEEP + PSG
+ * Keyboard: JIS Keyboard with 5 function keys, control key, TAB key,
+ HOME/CLR key, INS key, DEL key, CAPS key, GRAPH key, Japanese
+ syllabary key, page key, mode key, STOP key, and cursor key (4
+ directions)
+ * 1 cartslot, floppy drive, optional serial 232 port, 2 joystick ports
+
+
+ PC-6001 mkIISR (1984-12):
+
+ * CPU: Z80A @ 3.58 MHz
+ * ROM: 64KB + 16KB (chargen) + 32KB (kanji) + 32KB (Voice Synth)
+ * RAM: 64KB
+ * Text Mode: same as PC-6001/PC-6001mkII with N60-BASIC; 40x20, 40x25,
+ 80x20, 80x25 and 15 colors with N66SR-BASIC
+ * Graphic Modes: same as PC-6001/PC-6001mkII with N60-BASIC; 80x40 (15 colors),
+ 320x200 (15 colors), 640x200 (15 colors) with N66SR-BASIC
+ * Sound: BEEP + PSG + FM
+ * Keyboard: JIS Keyboard with 5 function keys, control key, TAB key,
+ HOME/CLR key, INS key, DEL key, CAPS key, GRAPH key, Japanese
+ syllabary key, page key, mode key, STOP key, and cursor key (4
+ directions)
+ * 1 cartslot, floppy drive, optional serial 232 port, 2 joystick ports
+
+
+ info from http://www.geocities.jp/retro_zzz/machines/nec/6001/spc60.html
+
+==================================================================================
+
+PC-6001 irq table:
+irq vector 0x00: writes 0x00 to [$fa19] ;(unused)
+irq vector 0x02: (A = 0, B = 0) tests ppi port c, does something with ay ports (plus more?) ;keyboard data ready, no kanji lock, no caps lock
+irq vector 0x04: ;uart irq
+irq vector 0x06: operates with $fa28, $fa2e, $fd1b ;timer irq
+irq vector 0x08: tests ppi port c, puts port A to $fa1d,puts 0x02 to [$fa19] ;tape data ready
+irq vector 0x0a: writes 0x00 to [$fa19] ;(unused)
+irq vector 0x0c: writes 0x00 to [$fa19] ;(unused)
+irq vector 0x0e: same as 2, (A = 0x03, B = 0x00) ;keyboard data ready, unknown type
+irq vector 0x10: same as 2, (A = 0x03, B = 0x00) ;(unused)
+irq vector 0x12: writes 0x10 to [$fa19] ;end of tape reached
+irq vector 0x14: same as 2, (A = 0x00, B = 0x01) ;kanji lock enabled
+irq vector 0x16: tests ppi port c, writes the result to $feca. ;joystick
+irq vector 0x18: ;TVR (?)
+irq vector 0x1a: ;Date
+irq vector 0x1c: ;(unused)
+irq vector 0x1e: ;(unused)
+irq vector 0x20: ;voice
+irq vector 0x22: ;VRTC (?)
+irq vector 0x24: ;(unused)
+irq vector 0x26: ;(unused)
+
+
+*******************************************************************************************************************************************************/
+
+#include "emu.h"
+#include "cpu/z80/z80.h"
+#include "machine/i8255.h"
+#include "machine/i8251.h"
+#include "video/mc6847.h"
+#include "sound/ay8910.h"
+#include "sound/upd7752.h"
+#include "sound/wave.h"
+
+#include "imagedev/cassette.h"
+#include "bus/generic/slot.h"
+#include "bus/generic/carts.h"
+#include "formats/p6001_cas.h"
+
+
+class pc6001_state : public driver_device
+{
+public:
+ pc6001_state(const machine_config &mconfig, device_type type, const char *tag)
+ : driver_device(mconfig, type, tag),
+ m_ppi(*this, "ppi8255"),
+ m_ram(*this, "ram"),
+ m_maincpu(*this, "maincpu"),
+ m_cassette(*this, "cassette"),
+ m_cas_hack(*this, "cas_hack"),
+ m_cart(*this, "cartslot"),
+ m_region_maincpu(*this, "maincpu"),
+ m_region_gfx1(*this, "gfx1"),
+ m_io_mode4_dsw(*this, "MODE4_DSW"),
+ m_io_p1(*this, "P1"),
+ m_io_p2(*this, "P2"),
+ m_io_key1(*this, "key1"),
+ m_io_key2(*this, "key2"),
+ m_io_key3(*this, "key3"),
+ m_io_key_modifiers(*this, "key_modifiers"),
+ m_bank1(*this, "bank1"),
+ m_bank2(*this, "bank2"),
+ m_bank3(*this, "bank3"),
+ m_bank4(*this, "bank4"),
+ m_bank5(*this, "bank5"),
+ m_bank6(*this, "bank6"),
+ m_bank7(*this, "bank7"),
+ m_bank8(*this, "bank8"),
+ m_palette(*this, "palette") { }
+
+ required_device<i8255_device> m_ppi;
+
+ optional_shared_ptr<UINT8> m_ram;
+ UINT8 *m_video_ram;
+ UINT8 m_irq_vector;
+ UINT8 m_cas_switch;
+ UINT8 m_sys_latch;
+ UINT8 m_timer_irq_mask;
+ UINT32 m_cas_offset;
+ UINT32 m_cas_maxsize;
+ emu_timer *m_timer_irq_timer;
+ UINT16 m_timer_hz_div;
+ UINT8 m_ex_vram_bank;
+ UINT8 m_bgcol_bank;
+ UINT8 m_exgfx_text_mode;
+ UINT8 m_exgfx_bitmap_mode;
+ UINT8 m_exgfx_2bpp_mode;
+ UINT8 m_bank_r0;
+ UINT8 m_bank_r1;
+ UINT8 m_gfx_bank_on;
+ UINT8 m_bank_w;
+ UINT8 m_bank_opt;
+ UINT8 m_timer_irq_mask2;
+ UINT8 m_timer_irq_vector;
+ UINT32 m_cgrom_bank_addr;
+ UINT8 m_sr_video_mode;
+ UINT8 m_port_c_8255;
+ UINT8 m_cur_keycode;
+ UINT8 m_sr_bank_r[8];
+ UINT8 m_sr_bank_w[8];
+ UINT8 m_kludge;
+ UINT32 m_old_key1;
+ UINT32 m_old_key2;
+ UINT32 m_old_key3;
+ DECLARE_WRITE8_MEMBER(pc6001_system_latch_w);
+ DECLARE_READ8_MEMBER(nec_ppi8255_r);
+ DECLARE_WRITE8_MEMBER(nec_ppi8255_w);
+ DECLARE_WRITE8_MEMBER(pc6001m2_bank_r0_w);
+ DECLARE_WRITE8_MEMBER(pc6001m2_bank_r1_w);
+ DECLARE_WRITE8_MEMBER(pc6001m2_bank_w0_w);
+ DECLARE_WRITE8_MEMBER(pc6001m2_opt_bank_w);
+ DECLARE_WRITE8_MEMBER(work_ram0_w);
+ DECLARE_WRITE8_MEMBER(work_ram1_w);
+ DECLARE_WRITE8_MEMBER(work_ram2_w);
+ DECLARE_WRITE8_MEMBER(work_ram3_w);
+ DECLARE_WRITE8_MEMBER(work_ram4_w);
+ DECLARE_WRITE8_MEMBER(work_ram5_w);
+ DECLARE_WRITE8_MEMBER(work_ram6_w);
+ DECLARE_WRITE8_MEMBER(work_ram7_w);
+ DECLARE_WRITE8_MEMBER(necmk2_ppi8255_w);
+ DECLARE_WRITE8_MEMBER(pc6001m2_system_latch_w);
+ DECLARE_WRITE8_MEMBER(pc6001m2_vram_bank_w);
+ DECLARE_WRITE8_MEMBER(pc6001m2_col_bank_w);
+ DECLARE_WRITE8_MEMBER(pc6001m2_0xf3_w);
+ DECLARE_WRITE8_MEMBER(pc6001m2_timer_adj_w);
+ DECLARE_WRITE8_MEMBER(pc6001m2_timer_irqv_w);
+ DECLARE_READ8_MEMBER(pc6001m2_bank_r0_r);
+ DECLARE_READ8_MEMBER(pc6001m2_bank_r1_r);
+ DECLARE_READ8_MEMBER(pc6001m2_bank_w0_r);
+ DECLARE_READ8_MEMBER(pc6601_fdc_r);
+ DECLARE_WRITE8_MEMBER(pc6601_fdc_w);
+ DECLARE_READ8_MEMBER(pc6001sr_bank_rn_r);
+ DECLARE_WRITE8_MEMBER(pc6001sr_bank_rn_w);
+ DECLARE_READ8_MEMBER(pc6001sr_bank_wn_r);
+ DECLARE_WRITE8_MEMBER(pc6001sr_bank_wn_w);
+ DECLARE_WRITE8_MEMBER(sr_work_ram0_w);
+ DECLARE_WRITE8_MEMBER(sr_work_ram1_w);
+ DECLARE_WRITE8_MEMBER(sr_work_ram2_w);
+ DECLARE_WRITE8_MEMBER(sr_work_ram3_w);
+ DECLARE_WRITE8_MEMBER(sr_work_ram4_w);
+ DECLARE_WRITE8_MEMBER(sr_work_ram5_w);
+ DECLARE_WRITE8_MEMBER(sr_work_ram6_w);
+ DECLARE_WRITE8_MEMBER(sr_work_ram7_w);
+ DECLARE_WRITE8_MEMBER(pc6001sr_mode_w);
+ DECLARE_WRITE8_MEMBER(pc6001sr_vram_bank_w);
+ DECLARE_WRITE8_MEMBER(pc6001sr_system_latch_w);
+ DECLARE_WRITE8_MEMBER(necsr_ppi8255_w);
+ virtual void machine_start();
+ virtual void machine_reset();
+ virtual void video_start();
+ DECLARE_PALETTE_INIT(pc6001);
+ DECLARE_MACHINE_RESET(pc6001m2);
+ DECLARE_PALETTE_INIT(pc6001m2);
+ DECLARE_MACHINE_RESET(pc6001sr);
+ UINT32 screen_update_pc6001(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
+ UINT32 screen_update_pc6001m2(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
+ UINT32 screen_update_pc6001sr(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
+ INTERRUPT_GEN_MEMBER(pc6001_interrupt);
+ INTERRUPT_GEN_MEMBER(pc6001sr_interrupt);
+ TIMER_CALLBACK_MEMBER(audio_callback);
+ TIMER_DEVICE_CALLBACK_MEMBER(cassette_callback);
+ TIMER_DEVICE_CALLBACK_MEMBER(keyboard_callback);
+ DECLARE_READ8_MEMBER(pc6001_8255_porta_r);
+ DECLARE_WRITE8_MEMBER(pc6001_8255_porta_w);
+ DECLARE_READ8_MEMBER(pc6001_8255_portb_r);
+ DECLARE_WRITE8_MEMBER(pc6001_8255_portb_w);
+ DECLARE_WRITE8_MEMBER(pc6001_8255_portc_w);
+ DECLARE_READ8_MEMBER(pc6001_8255_portc_r);
+ IRQ_CALLBACK_MEMBER(pc6001_irq_callback);
+protected:
+ required_device<cpu_device> m_maincpu;
+ optional_device<cassette_image_device> m_cassette;
+ optional_device<generic_slot_device> m_cas_hack;
+ required_device<generic_slot_device> m_cart;
+ required_memory_region m_region_maincpu;
+ required_memory_region m_region_gfx1;
+ required_ioport m_io_mode4_dsw;
+ required_ioport m_io_p1;
+ required_ioport m_io_p2;
+ required_ioport m_io_key1;
+ required_ioport m_io_key2;
+ required_ioport m_io_key3;
+ required_ioport m_io_key_modifiers;
+ required_memory_bank m_bank1;
+ optional_memory_bank m_bank2;
+ optional_memory_bank m_bank3;
+ optional_memory_bank m_bank4;
+ optional_memory_bank m_bank5;
+ optional_memory_bank m_bank6;
+ optional_memory_bank m_bank7;
+ optional_memory_bank m_bank8;
+ required_device<palette_device> m_palette;
+
+ memory_region *m_cart_rom;
+
+ void draw_gfx_mode4(bitmap_ind16 &bitmap,const rectangle &cliprect,int attr);
+ void draw_bitmap_2bpp(bitmap_ind16 &bitmap,const rectangle &cliprect, int attr);
+ void draw_tile_3bpp(bitmap_ind16 &bitmap,const rectangle &cliprect,int x,int y,int tile,int attr);
+ void draw_tile_text(bitmap_ind16 &bitmap,const rectangle &cliprect,int x,int y,int tile,int attr,int has_mc6847);
+ void draw_border(bitmap_ind16 &bitmap,const rectangle &cliprect,int attr,int has_mc6847);
+ void pc6001_screen_draw(bitmap_ind16 &bitmap,const rectangle &cliprect, int has_mc6847);
+ UINT8 check_joy_press();
+ UINT8 check_keyboard_press();
+ void vram_bank_change(UINT8 vram_bank);
+ ATTR_CONST UINT8 pc6001_get_attributes(UINT8 c,int scanline, int pos);
+ const UINT8 *pc6001_get_video_ram(int scanline);
+ UINT8 pc6001_get_char_rom(UINT8 ch, int line);
+};
+
+
+/* PC6001mk2 specific */
+/* PC6001SR specific */
+
+#define IRQ_LOG (0)
+
+void pc6001_state::video_start()
+{
+ #if 0
+ m6847_config cfg;
+
+ memset(&cfg, 0, sizeof(cfg));
+ cfg.type = M6847_VERSION_M6847T1_NTSC;
+ cfg.get_attributes = pc6001_get_attributes;
+ cfg.get_video_ram = pc6001_get_video_ram;
+ cfg.get_char_rom = pc6001_get_char_rom;
+ m6847_init(machine(), &cfg);
+ #endif
+ m_video_ram = auto_alloc_array(machine(), UINT8, 0x4000);
+}
+
+/* this is known as gfx mode 4 */
+void pc6001_state::draw_gfx_mode4(bitmap_ind16 &bitmap,const rectangle &cliprect,int attr)
+{
+ int x,y,xi;
+ int fgcol,color;
+ int col_setting;
+ static const UINT8 pen_gattr[4][4] = {
+ { 0, 1, 6, 2 }, //Red / Blue
+ { 0, 6, 1, 2 }, //Blue / Red
+ { 0, 5, 2, 2 }, //Pink / Green
+ { 0, 2, 5, 2 }, //Green / Pink
+ };
+ static const UINT8 pen_wattr[4][4] = {
+ { 0, 1, 6, 7 }, //Red / Blue
+ { 0, 6, 1, 7 }, //Blue / Red
+ { 0, 5, 2, 7 }, //Pink / Green
+ { 0, 2, 5, 7 }, //Green / Pink
+ };
+ col_setting = m_io_mode4_dsw->read() & 7;
+
+ if((attr & 0x0c) != 0x0c)
+ popmessage("Mode 4 vram attr != 0x0c, contact MESSdev");
+
+ for(y=0;y<192;y++)
+ {
+ for(x=0;x<32;x++)
+ {
+ int tile = m_video_ram[(x+(y*32))+0x200];
+
+ if(col_setting == 0x00) //monochrome
+ {
+ for(xi=0;xi<8;xi++)
+ {
+ fgcol = (attr & 2) ? 7 : 2;
+
+ color = ((tile)>>(7-xi) & 1) ? fgcol : 0;
+
+ bitmap.pix16((y+24), (x*8+xi)+32) = m_palette->pen(color);
+ }
+ }
+ else
+ {
+ for(xi=0;xi<4;xi++)
+ {
+ fgcol = ((tile)>>(6-(xi*2)) & 3);
+
+ color = (attr & 2) ? (pen_wattr[col_setting-1][fgcol]) : (pen_gattr[col_setting-1][fgcol]);
+
+ bitmap.pix16((y+24), ((x*8+xi*2)+0)+32) = m_palette->pen(color);
+ bitmap.pix16((y+24), ((x*8+xi*2)+1)+32) = m_palette->pen(color);
+ }
+ }
+ }
+ }
+}
+
+void pc6001_state::draw_bitmap_2bpp(bitmap_ind16 &bitmap,const rectangle &cliprect, int attr)
+{
+ int color,x,y,xi,yi;
+
+ int shrink_x = 2*4;
+ int shrink_y = (attr & 8) ? 1 : 2;
+ int w = (shrink_x == 8) ? 32 : 16;
+ int col_bank = ((attr & 2)<<1);
+
+ if(attr & 4)
+ {
+ for(y=0;y<(192/shrink_y);y++)
+ {
+ for(x=0;x<w;x++)
+ {
+ int tile = m_video_ram[(x+(y*32))+0x200];
+
+ for(yi=0;yi<shrink_y;yi++)
+ {
+ for(xi=0;xi<shrink_x;xi++)
+ {
+ int i;
+ i = (shrink_x == 8) ? (xi & 0x06) : (xi & 0x0c)>>1;
+ color = ((tile >> i) & 3)+8;
+ color+= col_bank;
+
+ bitmap.pix16(((y*shrink_y+yi)+24), (x*shrink_x+((shrink_x-1)-xi))+32) = m_palette->pen(color);
+ }
+ }
+ }
+ }
+ }
+ else /* TODO: clean this up */
+ {
+ for(y=0;y<(192/shrink_y);y+=3)
+ {
+ for(x=0;x<w;x++)
+ {
+ int tile = m_video_ram[(x+((y/3)*32))+0x200];
+
+ for(yi=0;yi<shrink_y;yi++)
+ {
+ for(xi=0;xi<shrink_x;xi++)
+ {
+ int i;
+ i = (shrink_x == 8) ? (xi & 0x06) : (xi & 0x0c)>>1;
+ color = ((tile >> i) & 3)+8;
+ color+= col_bank;
+
+ bitmap.pix16((((y+0)*shrink_y+yi)+24), (x*shrink_x+((shrink_x-1)-xi))+32) = m_palette->pen(color);
+ bitmap.pix16((((y+1)*shrink_y+yi)+24), (x*shrink_x+((shrink_x-1)-xi))+32) = m_palette->pen(color);
+ bitmap.pix16((((y+2)*shrink_y+yi)+24), (x*shrink_x+((shrink_x-1)-xi))+32) = m_palette->pen(color);
+ }
+ }
+ }
+ }
+ }
+}
+
+void pc6001_state::draw_tile_3bpp(bitmap_ind16 &bitmap,const rectangle &cliprect,int x,int y,int tile,int attr)
+{
+ int color,pen,xi,yi;
+
+ if(attr & 0x10) //2x2 squares on a single cell
+ pen = (tile & 0x70)>>4;
+ else //2x3
+ pen = (tile & 0xc0) >> 6 | (attr & 2)<<1;
+
+ for(yi=0;yi<12;yi++)
+ {
+ for(xi=0;xi<8;xi++)
+ {
+ int i;
+ i = (xi & 4)>>2; //x-axis
+ if(attr & 0x10) //2x2
+ {
+ i+= (yi >= 6) ? 2 : 0; //y-axis
+ }
+ else //2x3
+ {
+ i+= (yi & 4)>>1; //y-axis 1
+ i+= (yi & 8)>>1; //y-axis 2
+ }
+
+ color = ((tile >> i) & 1) ? pen+8 : 0;
+
+ bitmap.pix16(((y*12+(11-yi))+24), (x*8+(7-xi))+32) = m_palette->pen(color);
+ }
+ }
+}
+
+void pc6001_state::draw_tile_text(bitmap_ind16 &bitmap,const rectangle &cliprect,int x,int y,int tile,int attr,int has_mc6847)
+{
+ int xi,yi,pen,fgcol,color;
+ UINT8 *gfx_data = m_region_gfx1->base();
+
+ for(yi=0;yi<12;yi++)
+ {
+ for(xi=0;xi<8;xi++)
+ {
+ pen = gfx_data[(tile*0x10)+yi]>>(7-xi) & 1;
+
+ if(has_mc6847)
+ {
+ fgcol = (attr & 2) ? 0x12 : 0x10;
+
+ if(attr & 1)
+ color = pen ? (fgcol+0) : (fgcol+1);
+ else
+ color = pen ? (fgcol+1) : (fgcol+0);
+
+ }
+ else
+ {
+ fgcol = (attr & 2) ? 2 : 7;
+
+ if(attr & 1)
+ color = pen ? 0 : fgcol;
+ else
+ color = pen ? fgcol : 0;
+ }
+
+ bitmap.pix16(((y*12+yi)+24), (x*8+xi)+32) = m_palette->pen(color);
+ }
+ }
+}
+
+void pc6001_state::draw_border(bitmap_ind16 &bitmap,const rectangle &cliprect,int attr,int has_mc6847)
+{
+ int x,y,color;
+
+ for(y=0;y<240;y++)
+ {
+ for(x=0;x<320;x++)
+ {
+ if(!has_mc6847) //mk2 border color is always black
+ color = 0;
+ else if((attr & 0x90) == 0x80) //2bpp
+ color = ((attr & 2)<<1) + 8;
+ else if((attr & 0x90) == 0x90) //1bpp
+ color = (attr & 2) ? 7 : 2;
+ else
+ color = 0; //FIXME: other modes not yet checked
+
+ bitmap.pix16(y, x) = m_palette->pen(color);
+ }
+ }
+}
+
+void pc6001_state::pc6001_screen_draw(bitmap_ind16 &bitmap,const rectangle &cliprect, int has_mc6847)
+{
+ int x,y;
+ int tile,attr;
+
+ attr = m_video_ram[0];
+
+ draw_border(bitmap,cliprect,attr,has_mc6847);
+
+ if(attr & 0x80) // gfx mode
+ {
+ if(attr & 0x10) // 256x192x1 mode (FIXME: might be a different trigger)
+ {
+ draw_gfx_mode4(bitmap,cliprect,attr);
+ }
+ else // 128x192x2 mode
+ {
+ draw_bitmap_2bpp(bitmap,cliprect,attr);
+ }
+ }
+ else // text mode
+ {
+ for(y=0;y<16;y++)
+ {
+ for(x=0;x<32;x++)
+ {
+ tile = m_video_ram[(x+(y*32))+0x200];
+ attr = m_video_ram[(x+(y*32)) & 0x1ff];
+
+ if(attr & 0x40)
+ {
+ draw_tile_3bpp(bitmap,cliprect,x,y,tile,attr);
+ }
+ else
+ {
+ draw_tile_text(bitmap,cliprect,x,y,tile,attr,has_mc6847);
+ }
+ }
+ }
+ }
+}
+
+UINT32 pc6001_state::screen_update_pc6001(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ pc6001_screen_draw(bitmap,cliprect,1);
+
+ return 0;
+}
+
+UINT32 pc6001_state::screen_update_pc6001m2(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ int x,y,tile,attr;
+
+ /* note: bitmap mode have priority over everything else, check American Truck */
+ if(m_exgfx_bitmap_mode)
+ {
+ int count,color,i;
+
+ count = 0;
+
+ for(y=0;y<200;y++)
+ {
+ for(x=0;x<160;x+=4)
+ {
+ for(i=0;i<4;i++)
+ {
+ int pen[2];
+#if 0
+ /* palette reference: */
+ static const UINT8 pal_num[] = { 0x00, 0x04, 0x01, 0x05,
+ 0x02, 0x06, 0x03, 0x07,
+ 0x08, 0x0c, 0x09, 0x0d,
+ 0x0a, 0x0e, 0x0b, 0x0f };
+
+ color |= pal_num[(pen[0] & 3) | ((pen[1] & 3) << 2)];
+#endif
+
+ pen[0] = m_video_ram[count+0x0000] >> (6-i*2) & 3;
+ pen[1] = m_video_ram[count+0x2000] >> (6-i*2) & 3;
+
+ color = 0x10;
+ color |= ((pen[0] & 1) << 2);
+ color |= ((pen[0] & 2) >> 1);
+ color |= ((pen[1] & 1) << 1);
+ color |= ((pen[1] & 2) << 2);
+
+ if (cliprect.contains((x+i)*2+0, y))
+ bitmap.pix16(y, (x+i)*2+0) = m_palette->pen(color);
+ if (cliprect.contains((x+i)*2+1, y))
+ bitmap.pix16(y, (x+i)*2+1) = m_palette->pen(color);
+ }
+
+ count++;
+ }
+ }
+ }
+ else if(m_exgfx_2bpp_mode)
+ {
+ int count,color,i;
+
+ count = 0;
+
+ for(y=0;y<200;y++)
+ {
+ for(x=0;x<320;x+=8)
+ {
+ for(i=0;i<8;i++)
+ {
+ int pen[2];
+#if 0
+ /* palette reference: */
+ static const UINT8 pal_num[] = { 0x00, 0x04, 0x01, 0x05 };
+
+ color |= pal_num[(pen[0] & 1) | ((pen[1] & 1) << 1)];
+#endif
+
+ pen[0] = m_video_ram[count+0x0000] >> (7-i) & 1;
+ pen[1] = m_video_ram[count+0x2000] >> (7-i) & 1;
+
+ if(m_bgcol_bank & 4) //PC-6001 emulation mode
+ {
+ color = 0x08;
+ color |= (pen[0]) | (pen[1]<<1);
+ color |= (m_bgcol_bank & 1) << 2;
+ }
+ else //Mk-2 mode
+ {
+ color = 0x10;
+ color |= ((pen[0] & 1) << 2);
+ color |= ((pen[1] & 1) >> 0);
+ color |= ((m_bgcol_bank & 1) << 1);
+ color |= ((m_bgcol_bank & 2) << 2);
+ }
+
+ if (cliprect.contains(x+i, y))
+ bitmap.pix16(y, (x+i)) = m_palette->pen(color);
+ }
+
+ count++;
+ }
+ }
+
+ }
+ else if(m_exgfx_text_mode)
+ {
+ int xi,yi,pen,fgcol,bgcol,color;
+ UINT8 *gfx_data = m_region_gfx1->base();
+
+ for(y=0;y<20;y++)
+ {
+ for(x=0;x<40;x++)
+ {
+ /*
+ exgfx attr format:
+ x--- ---- rom bank select
+ -xxx ---- bg color
+ ---- xxxx fg color
+ Note that the exgfx banks a different gfx ROM
+ */
+ tile = m_video_ram[(x+(y*40))+0x400] + 0x200;
+ attr = m_video_ram[(x+(y*40)) & 0x3ff];
+ tile+= ((attr & 0x80) << 1);
+
+ for(yi=0;yi<12;yi++)
+ {
+ for(xi=0;xi<8;xi++)
+ {
+ pen = gfx_data[(tile*0x10)+yi]>>(7-xi) & 1;
+
+ fgcol = (attr & 0x0f) + 0x10;
+ bgcol = ((attr & 0x70) >> 4) + 0x10 + ((m_bgcol_bank & 2) << 2);
+
+ color = pen ? fgcol : bgcol;
+
+ if (cliprect.contains(x*8+xi, y*12+yi))
+ bitmap.pix16(((y*12+yi)), (x*8+xi)) = m_palette->pen(color);
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ attr = m_video_ram[0];
+ pc6001_screen_draw(bitmap,cliprect,0);
+ }
+
+ return 0;
+}
+
+UINT32 pc6001_state::screen_update_pc6001sr(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ int x,y,tile,attr;
+ int xi,yi,pen,fgcol,bgcol,color;
+ UINT8 *gfx_data = m_region_gfx1->base();
+
+
+ if(m_sr_video_mode & 8) // text mode
+ {
+ for(y=0;y<20;y++)
+ {
+ for(x=0;x<40;x++)
+ {
+ tile = m_video_ram[(x+(y*40))*2+0];
+ attr = m_video_ram[(x+(y*40))*2+1];
+ tile+= ((attr & 0x80) << 1);
+
+ for(yi=0;yi<12;yi++)
+ {
+ for(xi=0;xi<8;xi++)
+ {
+ pen = gfx_data[(tile*0x10)+yi]>>(7-xi) & 1;
+
+ fgcol = (attr & 0x0f) + 0x10;
+ bgcol = ((attr & 0x70) >> 4) + 0x10 + ((m_bgcol_bank & 2) << 2);
+
+ color = pen ? fgcol : bgcol;
+
+ if (cliprect.contains(x*8+xi, y*12+yi))
+ bitmap.pix16(((y*12+yi)), (x*8+xi)) = m_palette->pen(color);
+ }
+ }
+ }
+ }
+ }
+ else //4bpp bitmap mode (TODO)
+ {
+ int count;
+
+ count = 0;
+
+ for(y=0;y<200;y+=2)
+ {
+ for(x=0;x<320;x+=4)
+ {
+ color = m_video_ram[count] & 0x0f;
+
+ if (cliprect.contains(x+0, y+0))
+ bitmap.pix16((y+0), (x+0)) = m_palette->pen(color+0x10);
+
+ color = (m_video_ram[count] & 0xf0) >> 4;
+
+ if (cliprect.contains(x+1, y+0))
+ bitmap.pix16((y+0), (x+1)) = m_palette->pen(color+0x10);
+
+ color = m_video_ram[count+1] & 0x0f;
+
+ if (cliprect.contains(x+2, y+0))
+ bitmap.pix16((y+0), (x+2)) = m_palette->pen(color+0x10);
+
+ color = (m_video_ram[count+1] & 0xf0) >> 4;
+
+ if (cliprect.contains(x+3, y+0))
+ bitmap.pix16((y+0), (x+3)) = m_palette->pen(color+0x10);
+
+ color = m_video_ram[count+2] & 0x0f;
+
+ if (cliprect.contains(x+0, y+1))
+ bitmap.pix16((y+1), (x+0)) = m_palette->pen(color+0x10);
+
+ color = (m_video_ram[count+2] & 0xf0) >> 4;
+
+ if (cliprect.contains(x+1, y+1))
+ bitmap.pix16((y+1), (x+1)) = m_palette->pen(color+0x10);
+
+ color = m_video_ram[count+3] & 0x0f;
+
+ if (cliprect.contains(x+2, y+1))
+ bitmap.pix16((y+1), (x+2)) = m_palette->pen(color+0x10);
+
+ color = (m_video_ram[count+3] & 0xf0) >> 4;
+
+ if (cliprect.contains(x+3, y+1))
+ bitmap.pix16((y+1), (x+3)) = m_palette->pen(color+0x10);
+
+
+ count+=4;
+ }
+ }
+ }
+
+ return 0;
+}
+
+WRITE8_MEMBER(pc6001_state::pc6001_system_latch_w)
+{
+ static const UINT16 startaddr[] = {0xC000, 0xE000, 0x8000, 0xA000 };
+
+ m_video_ram = m_ram + startaddr[(data >> 1) & 0x03] - 0x8000;
+
+ if((!(m_sys_latch & 8)) && data & 0x8) //PLAY tape cmd
+ {
+ m_cas_switch = 1;
+ //m_cassette->change_state(CASSETTE_MOTOR_ENABLED,CASSETTE_MASK_MOTOR);
+ //m_cassette->change_state(CASSETTE_PLAY,CASSETTE_MASK_UISTATE);
+ }
+ if((m_sys_latch & 8) && ((data & 0x8) == 0)) //STOP tape cmd
+ {
+ m_cas_switch = 0;
+ //m_cassette->change_state(CASSETTE_MOTOR_DISABLED,CASSETTE_MASK_MOTOR);
+ //m_cassette->change_state(CASSETTE_STOPPED,CASSETTE_MASK_UISTATE);
+ //m_irq_vector = 0x00;
+ //m_maincpu->set_input_line(0, ASSERT_LINE);
+ }
+
+ m_sys_latch = data;
+ m_timer_irq_mask = data & 1;
+ //printf("%02x\n",data);
+}
+
+#if 0
+ATTR_CONST pc6001_state::UINT8 pc6001_get_attributes(UINT8 c,int scanline, int pos)
+{
+ UINT8 result = 0x00;
+ UINT8 val = m_video_ram [(scanline / 12) * 0x20 + pos];
+
+ if (val & 0x01) {
+ result |= M6847_INV;
+ }
+ if (val & 0x40)
+ result |= M6847_AG | M6847_GM1; //TODO
+
+ result |= M6847_INTEXT; // always use external ROM
+ return result;
+}
+
+const pc6001_state::UINT8 *pc6001_get_video_ram(int scanline)
+{
+ return m_video_ram +0x0200+ (scanline / 12) * 0x20;
+}
+
+UINT8 pc6001_state::pc6001_get_char_rom(UINT8 ch, int line)
+{
+ UINT8 *gfx = m_region_gfx1->base();
+ return gfx[ch*16+line];
+}
+#endif
+
+
+READ8_MEMBER(pc6001_state::nec_ppi8255_r)
+{
+ if (offset==2)
+ return m_port_c_8255;
+ else if(offset==0)
+ {
+ UINT8 res;
+ res = m_cur_keycode;
+ //m_cur_keycode = 0;
+ return res;
+ }
+
+ return m_ppi->read(space, offset);
+}
+
+WRITE8_MEMBER(pc6001_state::nec_ppi8255_w)
+{
+ if (offset==3)
+ {
+ if(data & 1)
+ m_port_c_8255 |= 1<<((data>>1)&0x07);
+ else
+ m_port_c_8255 &= ~(1<<((data>>1)&0x07));
+
+ switch(data) {
+ case 0x08: m_port_c_8255 |= 0x88; break;
+ case 0x09: m_port_c_8255 &= 0xf7; break;
+ case 0x0c: m_port_c_8255 |= 0x28; break;
+ case 0x0d: m_port_c_8255 &= 0xf7; break;
+ default: break;
+ }
+
+ m_port_c_8255 |= 0xa8;
+
+ {
+ //printf("%02x\n",data);
+
+ if ((data & 0x0f) == 0x05 && m_cart_rom)
+ m_bank1->set_base(m_cart_rom->base() + 0x2000);
+ if ((data & 0x0f) == 0x04)
+ m_bank1->set_base(m_region_gfx1->base());
+ }
+ }
+ m_ppi->write(space,offset,data);
+}
+
+static ADDRESS_MAP_START(pc6001_map, AS_PROGRAM, 8, pc6001_state )
+ ADDRESS_MAP_UNMAP_HIGH
+ AM_RANGE(0x0000, 0x3fff) AM_ROM AM_WRITENOP
+ //AM_RANGE(0x4000, 0x5fff) // mapped by the cartslot
+ AM_RANGE(0x6000, 0x7fff) AM_ROMBANK("bank1")
+ AM_RANGE(0x8000, 0xffff) AM_RAM AM_SHARE("ram")
+ADDRESS_MAP_END
+
+static ADDRESS_MAP_START( pc6001_io , AS_IO, 8, pc6001_state )
+ ADDRESS_MAP_UNMAP_HIGH
+ ADDRESS_MAP_GLOBAL_MASK(0xff)
+ AM_RANGE(0x80, 0x80) AM_DEVREADWRITE("uart", i8251_device, data_r, data_w)
+ AM_RANGE(0x81, 0x81) AM_DEVREADWRITE("uart", i8251_device, status_r, control_w)
+ AM_RANGE(0x90, 0x93) AM_MIRROR(0x0c) AM_READWRITE(nec_ppi8255_r, nec_ppi8255_w)
+ AM_RANGE(0xa0, 0xa0) AM_MIRROR(0x0c) AM_DEVWRITE("ay8910", ay8910_device, address_w)
+ AM_RANGE(0xa1, 0xa1) AM_MIRROR(0x0c) AM_DEVWRITE("ay8910", ay8910_device, data_w)
+ AM_RANGE(0xa2, 0xa2) AM_MIRROR(0x0c) AM_DEVREAD("ay8910", ay8910_device, data_r)
+ AM_RANGE(0xa3, 0xa3) AM_MIRROR(0x0c) AM_WRITENOP
+ AM_RANGE(0xb0, 0xb0) AM_MIRROR(0x0f) AM_WRITE(pc6001_system_latch_w)
+ AM_RANGE(0xd0, 0xd3) AM_MIRROR(0x0c) AM_NOP // disk device
+ADDRESS_MAP_END
+
+/*
+ ROM_REGION( 0x28000, "maincpu", ROMREGION_ERASEFF )
+ ROM_LOAD( "basicrom.62", 0x10000, 0x8000, CRC(950ac401) SHA1(fbf195ba74a3b0f80b5a756befc96c61c2094182) )
+ ROM_LOAD( "voicerom.62", 0x18000, 0x4000, CRC(49b4f917) SHA1(1a2d18f52ef19dc93da3d65f19d3abbd585628af) )
+ ROM_LOAD( "cgrom60.62", 0x1c000, 0x2000, CRC(81eb5d95) SHA1(53d8ae9599306ff23bf95208d2f6cc8fed3fc39f) )
+ ROM_LOAD( "cgrom60m.62", 0x1e000, 0x2000, CRC(3ce48c33) SHA1(f3b6c63e83a17d80dde63c6e4d86adbc26f84f79) )
+ ROM_LOAD( "kanjirom.62", 0x20000, 0x8000, CRC(20c8f3eb) SHA1(4c9f30f0a2ebbe70aa8e697f94eac74d8241cadd) )
+*/
+
+#define BASICROM(_v_) \
+ 0x10000+0x2000*_v_
+#define VOICEROM(_v_) \
+ 0x18000+0x2000*_v_
+#define TVROM(_v_) \
+ 0x1c000+0x2000*_v_
+#define KANJIROM(_v_) \
+ 0x20000+0x2000*_v_
+#define WRAM(_v_) \
+ 0x28000+0x2000*_v_
+#define EXWRAM(_v_) \
+ 0x38000+0x2000*_v_
+#define EXROM(_v_) \
+ 0x48000+0x2000*_v_
+#define INVALID(_v_) \
+ 0x4c000+0x2000*_v_
+/* FIXME: some comments aren't right */
+static const UINT32 banksw_table_r0[0x10*4][4] = {
+ /* 0 */
+ { INVALID(0), INVALID(0), INVALID(0), INVALID(0) }, //0x00: <invalid setting>
+ { BASICROM(0), BASICROM(1), BASICROM(2), BASICROM(3) }, //0x01: basic rom 0 & 1 / basic rom 2 & 3
+ { TVROM(0), TVROM(1), VOICEROM(0), VOICEROM(1) }, //0x02: tv rom 0 & 1 / voice rom 0 & 1
+ { EXROM(1), EXROM(1), EXROM(1), EXROM(1) }, //0x03: ex rom 1 & 1 / ex rom 1 & 1
+ { EXROM(0), EXROM(0), EXROM(0), EXROM(0) }, //0x04: ex rom 0 & 0 / ex rom 0 & 0
+ { TVROM(1), BASICROM(1), VOICEROM(0), BASICROM(3) }, //0x05: tv rom 1 & basic rom 1 / voice rom 0 & basic 3
+ { BASICROM(0), TVROM(2), BASICROM(2), VOICEROM(1) }, //0x06: basic rom 0 & tv rom 2 / basic rom 2 & voice 1
+ { EXROM(0), EXROM(1), EXROM(0), EXROM(1) }, //0x07: ex rom 0 & ex rom 1 / ex rom 0 & ex rom 1
+ { EXROM(1), EXROM(0), EXROM(1), EXROM(0) }, //0x08: ex rom 1 & ex rom 0 / ex rom 1 & ex rom 0
+ { EXROM(1), BASICROM(1), EXROM(1), BASICROM(3) }, //0x09: ex rom 1 & basic rom 1 / ex rom 1 & basic 3
+ { BASICROM(0), EXROM(1), BASICROM(2), EXROM(1) }, //0x0a: basic rom 0 & ex rom 1 / basic rom 2 & ex rom 1
+ { EXROM(0), TVROM(2), EXROM(0), VOICEROM(1) }, //0x0b: ex rom 0 & tv rom 2 / ex rom 0 & voice 1
+ { TVROM(1), EXROM(0), VOICEROM(0), EXROM(0) }, //0x0c: tv rom 1 & ex rom 0 / voice rom 0 & ex rom 0
+ { WRAM(0), WRAM(1), WRAM(2), WRAM(3) }, //0x0d: ram 0 & 1 / ram 2 & 3
+ { EXWRAM(0), EXWRAM(1), EXWRAM(2), EXWRAM(3) }, //0x0e: exram 0 & 1 / exram 2 & 3
+ { INVALID(0), INVALID(0), INVALID(0), INVALID(0) }, //0x0f: <invalid setting>
+ /* 1 */
+ { INVALID(0), INVALID(0), INVALID(0), INVALID(0) }, //0x00: <invalid setting>
+ { BASICROM(0), BASICROM(1), BASICROM(2), BASICROM(3) }, //0x01: basic rom 0 & 1 / basic rom 2 & 3
+ { KANJIROM(0), KANJIROM(1), KANJIROM(0), KANJIROM(1) }, //0x02: tv rom 0 & 1 / voice rom 0 & 1
+ { EXROM(1), EXROM(1), EXROM(1), EXROM(1) }, //0x03: ex rom 1 & 1 / ex rom 1 & 1
+ { EXROM(0), EXROM(0), EXROM(0), EXROM(0) }, //0x04: ex rom 0 & 0 / ex rom 0 & 0
+ { KANJIROM(0), BASICROM(1), KANJIROM(0), BASICROM(3) }, //0x05: tv rom 1 & basic rom 1 / voice rom 0 & basic 3
+ { BASICROM(0), KANJIROM(1), BASICROM(2), KANJIROM(1) }, //0x06: basic rom 0 & tv rom 2 / basic rom 2 & voice 1
+ { EXROM(0), EXROM(1), EXROM(0), EXROM(1) }, //0x07: ex rom 0 & ex rom 1 / ex rom 0 & ex rom 1
+ { EXROM(1), EXROM(0), EXROM(1), EXROM(0) }, //0x08: ex rom 1 & ex rom 0 / ex rom 1 & ex rom 0
+ { EXROM(1), BASICROM(1), EXROM(1), BASICROM(3) }, //0x09: ex rom 1 & basic rom 1 / ex rom 1 & basic 3
+ { BASICROM(0), EXROM(1), BASICROM(2), EXROM(1) }, //0x0a: basic rom 0 & ex rom 1 / basic rom 2 & ex rom 1
+ { EXROM(0), KANJIROM(1), EXROM(0), KANJIROM(1) }, //0x0b: ex rom 0 & tv rom 2 / ex rom 0 & voice 1
+ { KANJIROM(0), EXROM(0), KANJIROM(0), EXROM(0) }, //0x0c: tv rom 1 & ex rom 0 / voice rom 0 & ex rom 0
+ { WRAM(0), WRAM(1), WRAM(2), WRAM(3) }, //0x0d: ram 0 & 1 / ram 2 & 3
+ { EXWRAM(0), EXWRAM(1), EXWRAM(2), EXWRAM(3) }, //0x0e: exram 0 & 1 / exram 2 & 3
+ { INVALID(0), INVALID(0), INVALID(0), INVALID(0) }, //0x0f: <invalid setting>
+ /* 2 */
+ { INVALID(0), INVALID(0), INVALID(0), INVALID(0) }, //0x00: <invalid setting>
+ { BASICROM(0), BASICROM(1), BASICROM(2), BASICROM(3) }, //0x01: basic rom 0 & 1 / basic rom 2 & 3
+ { TVROM(0), TVROM(1), VOICEROM(0), VOICEROM(1) }, //0x02: tv rom 0 & 1 / voice rom 0 & 1
+ { EXROM(1), EXROM(1), EXROM(1), EXROM(1) }, //0x03: ex rom 1 & 1 / ex rom 1 & 1
+ { EXROM(0), EXROM(0), EXROM(0), EXROM(0) }, //0x04: ex rom 0 & 0 / ex rom 0 & 0
+ { TVROM(1), BASICROM(1), VOICEROM(0), BASICROM(3) }, //0x05: tv rom 1 & basic rom 1 / voice rom 0 & basic 3
+ { BASICROM(0), TVROM(2), BASICROM(2), VOICEROM(1) }, //0x06: basic rom 0 & tv rom 2 / basic rom 2 & voice 1
+ { EXROM(0), EXROM(1), EXROM(0), EXROM(1) }, //0x07: ex rom 0 & ex rom 1 / ex rom 0 & ex rom 1
+ { EXROM(1), EXROM(0), EXROM(1), EXROM(0) }, //0x08: ex rom 1 & ex rom 0 / ex rom 1 & ex rom 0
+ { EXROM(1), BASICROM(1), EXROM(1), BASICROM(3) }, //0x09: ex rom 1 & basic rom 1 / ex rom 1 & basic 3
+ { BASICROM(0), EXROM(1), BASICROM(2), EXROM(1) }, //0x0a: basic rom 0 & ex rom 1 / basic rom 2 & ex rom 1
+ { EXROM(0), TVROM(2), EXROM(0), VOICEROM(1) }, //0x0b: ex rom 0 & tv rom 2 / ex rom 0 & voice 1
+ { TVROM(1), EXROM(0), VOICEROM(0), EXROM(0) }, //0x0c: tv rom 1 & ex rom 0 / voice rom 0 & ex rom 0
+ { WRAM(0), WRAM(1), WRAM(2), WRAM(3) }, //0x0d: ram 0 & 1 / ram 2 & 3
+ { EXWRAM(0), EXWRAM(1), EXWRAM(2), EXWRAM(3) }, //0x0e: exram 0 & 1 / exram 2 & 3
+ { INVALID(0), INVALID(0), INVALID(0), INVALID(0) }, //0x0f: <invalid setting>
+ /* 3 */
+ { INVALID(0), INVALID(0), INVALID(0), INVALID(0) }, //0x00: <invalid setting>
+ { BASICROM(0), BASICROM(1), BASICROM(2), BASICROM(3) }, //0x01: basic rom 0 & 1 / basic rom 2 & 3
+ { KANJIROM(2), KANJIROM(3), KANJIROM(2), KANJIROM(3) }, //0x02: tv rom 0 & 1 / voice rom 0 & 1
+ { EXROM(1), EXROM(1), EXROM(1), EXROM(1) }, //0x03: ex rom 1 & 1 / ex rom 1 & 1
+ { EXROM(0), EXROM(0), EXROM(0), EXROM(0) }, //0x04: ex rom 0 & 0 / ex rom 0 & 0
+ { KANJIROM(2), BASICROM(1), KANJIROM(2), BASICROM(3) }, //0x05: tv rom 1 & basic rom 1 / voice rom 0 & basic 3
+ { BASICROM(0), KANJIROM(3), BASICROM(2), KANJIROM(3) }, //0x06: basic rom 0 & tv rom 2 / basic rom 2 & voice 1
+ { EXROM(0), EXROM(1), EXROM(0), EXROM(1) }, //0x07: ex rom 0 & ex rom 1 / ex rom 0 & ex rom 1
+ { EXROM(1), EXROM(0), EXROM(1), EXROM(0) }, //0x08: ex rom 1 & ex rom 0 / ex rom 1 & ex rom 0
+ { EXROM(1), BASICROM(1), EXROM(1), BASICROM(3) }, //0x09: ex rom 1 & basic rom 1 / ex rom 1 & basic 3
+ { BASICROM(0), EXROM(1), BASICROM(2), EXROM(1) }, //0x0a: basic rom 0 & ex rom 1 / basic rom 2 & ex rom 1
+ { EXROM(0), KANJIROM(3), EXROM(0), KANJIROM(3) }, //0x0b: ex rom 0 & tv rom 2 / ex rom 0 & voice 1
+ { KANJIROM(2), EXROM(0), KANJIROM(2), EXROM(0) }, //0x0c: tv rom 1 & ex rom 0 / voice rom 0 & ex rom 0
+ { WRAM(0), WRAM(1), WRAM(2), WRAM(3) }, //0x0d: ram 0 & 1 / ram 2 & 3
+ { EXWRAM(0), EXWRAM(1), EXWRAM(2), EXWRAM(3) }, //0x0e: exram 0 & 1 / exram 2 & 3
+ { INVALID(0), INVALID(0), INVALID(0), INVALID(0) } //0x0f: <invalid setting>
+};
+
+static const UINT32 banksw_table_r1[0x10*4][4] = {
+ /* 0 */
+ { INVALID(0), INVALID(0), INVALID(0), INVALID(0) }, //0x00: <invalid setting>
+ { BASICROM(0), BASICROM(1), BASICROM(2), BASICROM(3) }, //0x01: basic rom 0 & 1 / basic rom 2 & 3
+ { VOICEROM(0), VOICEROM(1), VOICEROM(0), VOICEROM(1) }, //0x02: voice rom 0 & 1 / voice rom 0 & 1
+ { EXROM(1), EXROM(1), EXROM(1), EXROM(1) }, //0x03: ex rom 1 & 1 / ex rom 1 & 1
+ { EXROM(0), EXROM(0), EXROM(0), EXROM(0) }, //0x04: ex rom 0 & 0 / ex rom 0 & 0
+ { VOICEROM(0), BASICROM(1), VOICEROM(0), BASICROM(3) }, //0x05: voice rom 0 & basic rom 1 / voice rom 0 & basic 3
+ { BASICROM(0), VOICEROM(1), BASICROM(2), VOICEROM(1) }, //0x06: basic rom 0 & voice rom 1 / basic rom 2 & voice 1
+ { EXROM(0), EXROM(1), EXROM(0), EXROM(1) }, //0x07: ex rom 0 & ex rom 1 / ex rom 0 & ex rom 1
+ { EXROM(1), EXROM(0), EXROM(1), EXROM(0) }, //0x08: ex rom 1 & ex rom 0 / ex rom 1 & ex rom 0
+ { EXROM(1), BASICROM(1), EXROM(1), BASICROM(3) }, //0x09: ex rom 1 & basic rom 1 / ex rom 1 & basic 3
+ { BASICROM(0), EXROM(1), BASICROM(2), EXROM(1) }, //0x0a: basic rom 0 & ex rom 1 / basic rom 2 & ex rom 1
+ { EXROM(0), VOICEROM(1), EXROM(0), VOICEROM(1) }, //0x0b: ex rom 0 & voice rom 1 / ex rom 0 & voice 1
+ { VOICEROM(0), EXROM(0), VOICEROM(0), EXROM(0) }, //0x0c: voice rom 1 & ex rom 0 / voice rom 0 & ex rom 0
+ { WRAM(4), WRAM(5), WRAM(6), WRAM(7) }, //0x0d: ram 4 & 5 / ram 6 & 7
+ { EXWRAM(4), EXWRAM(5), EXWRAM(6), EXWRAM(7) }, //0x0e: exram 4 & 5 / exram 6 & 7
+ { INVALID(0), INVALID(0), INVALID(0), INVALID(0) }, //0x0f: <invalid setting>
+ /* 1 */
+ { INVALID(0), INVALID(0), INVALID(0), INVALID(0) }, //0x00: <invalid setting>
+ { BASICROM(0), BASICROM(1), BASICROM(2), BASICROM(3) }, //0x01: basic rom 0 & 1 / basic rom 2 & 3
+ { KANJIROM(0), KANJIROM(1), KANJIROM(0), KANJIROM(1) }, //0x02: kanji rom 0 & 1 / kanji rom 0 & 1
+ { EXROM(1), EXROM(1), EXROM(1), EXROM(1) }, //0x03: ex rom 1 & 1 / ex rom 1 & 1
+ { EXROM(0), EXROM(0), EXROM(0), EXROM(0) }, //0x04: ex rom 0 & 0 / ex rom 0 & 0
+ { KANJIROM(0), BASICROM(1), KANJIROM(0), BASICROM(3) }, //0x05: voice rom 0 & basic rom 1 / voice rom 0 & basic 3
+ { BASICROM(0), KANJIROM(1), BASICROM(2), KANJIROM(1) }, //0x06: basic rom 0 & voice rom 1 / basic rom 2 & voice 1
+ { EXROM(0), EXROM(1), EXROM(0), EXROM(1) }, //0x07: ex rom 0 & ex rom 1 / ex rom 0 & ex rom 1
+ { EXROM(1), EXROM(0), EXROM(1), EXROM(0) }, //0x08: ex rom 1 & ex rom 0 / ex rom 1 & ex rom 0
+ { EXROM(1), BASICROM(1), EXROM(1), BASICROM(3) }, //0x09: ex rom 1 & basic rom 1 / ex rom 1 & basic 3
+ { BASICROM(0), EXROM(1), BASICROM(2), EXROM(1) }, //0x0a: basic rom 0 & ex rom 1 / basic rom 2 & ex rom 1
+ { EXROM(0), KANJIROM(1), EXROM(0), KANJIROM(1) }, //0x0b: ex rom 0 & voice rom 1 / ex rom 0 & voice 1
+ { KANJIROM(0), EXROM(0), KANJIROM(0), EXROM(0) }, //0x0c: voice rom 1 & ex rom 0 / voice rom 0 & ex rom 0
+ { WRAM(4), WRAM(5), WRAM(6), WRAM(7) }, //0x0d: ram 4 & 5 / ram 6 & 7
+ { EXWRAM(4), EXWRAM(5), EXWRAM(6), EXWRAM(7) }, //0x0e: exram 4 & 5 / exram 6 & 7
+ { INVALID(0), INVALID(0), INVALID(0), INVALID(0) }, //0x0f: <invalid setting>
+ /* 2 */
+ { INVALID(0), INVALID(0), INVALID(0), INVALID(0) }, //0x00: <invalid setting>
+ { BASICROM(0), BASICROM(1), BASICROM(2), BASICROM(3) }, //0x01: basic rom 0 & 1 / basic rom 2 & 3
+ { VOICEROM(0), VOICEROM(1), VOICEROM(0), VOICEROM(1) }, //0x02: voice rom 0 & 1 / voice rom 0 & 1
+ { EXROM(1), EXROM(1), EXROM(1), EXROM(1) }, //0x03: ex rom 1 & 1 / ex rom 1 & 1
+ { EXROM(0), EXROM(0), EXROM(0), EXROM(0) }, //0x04: ex rom 0 & 0 / ex rom 0 & 0
+ { VOICEROM(0), BASICROM(1), VOICEROM(0), BASICROM(3) }, //0x05: voice rom 0 & basic rom 1 / voice rom 0 & basic 3
+ { BASICROM(0), VOICEROM(1), BASICROM(2), VOICEROM(1) }, //0x06: basic rom 0 & voice rom 1 / basic rom 2 & voice 1
+ { EXROM(0), EXROM(1), EXROM(0), EXROM(1) }, //0x07: ex rom 0 & ex rom 1 / ex rom 0 & ex rom 1
+ { EXROM(1), EXROM(0), EXROM(1), EXROM(0) }, //0x08: ex rom 1 & ex rom 0 / ex rom 1 & ex rom 0
+ { EXROM(1), BASICROM(1), EXROM(1), BASICROM(3) }, //0x09: ex rom 1 & basic rom 1 / ex rom 1 & basic 3
+ { BASICROM(0), EXROM(1), BASICROM(2), EXROM(1) }, //0x0a: basic rom 0 & ex rom 1 / basic rom 2 & ex rom 1
+ { EXROM(0), VOICEROM(1), EXROM(0), VOICEROM(1) }, //0x0b: ex rom 0 & voice rom 1 / ex rom 0 & voice 1
+ { VOICEROM(0), EXROM(0), VOICEROM(0), EXROM(0) }, //0x0c: voice rom 1 & ex rom 0 / voice rom 0 & ex rom 0
+ { WRAM(4), WRAM(5), WRAM(6), WRAM(7) }, //0x0d: ram 4 & 5 / ram 6 & 7
+ { EXWRAM(4), EXWRAM(5), EXWRAM(6), EXWRAM(7) }, //0x0e: exram 4 & 5 / exram 6 & 7
+ { INVALID(0), INVALID(0), INVALID(0), INVALID(0) }, //0x0f: <invalid setting>
+ /* 3 */
+ { INVALID(0), INVALID(0), INVALID(0), INVALID(0) }, //0x00: <invalid setting>
+ { BASICROM(0), BASICROM(1), BASICROM(2), BASICROM(3) }, //0x01: basic rom 0 & 1 / basic rom 2 & 3
+ { KANJIROM(2), KANJIROM(3), KANJIROM(2), KANJIROM(3) }, //0x02: kanji rom 0 & 1 / kanji rom 0 & 1
+ { EXROM(1), EXROM(1), EXROM(1), EXROM(1) }, //0x03: ex rom 1 & 1 / ex rom 1 & 1
+ { EXROM(0), EXROM(0), EXROM(0), EXROM(0) }, //0x04: ex rom 0 & 0 / ex rom 0 & 0
+ { KANJIROM(2), BASICROM(1), KANJIROM(2), BASICROM(3) }, //0x05: voice rom 0 & basic rom 1 / voice rom 0 & basic 3
+ { BASICROM(0), KANJIROM(3), BASICROM(2), KANJIROM(3) }, //0x06: basic rom 0 & voice rom 1 / basic rom 2 & voice 1
+ { EXROM(0), EXROM(1), EXROM(0), EXROM(1) }, //0x07: ex rom 0 & ex rom 1 / ex rom 0 & ex rom 1
+ { EXROM(1), EXROM(0), EXROM(1), EXROM(0) }, //0x08: ex rom 1 & ex rom 0 / ex rom 1 & ex rom 0
+ { EXROM(1), BASICROM(1), EXROM(1), BASICROM(3) }, //0x09: ex rom 1 & basic rom 1 / ex rom 1 & basic 3
+ { BASICROM(0), EXROM(1), BASICROM(2), EXROM(1) }, //0x0a: basic rom 0 & ex rom 1 / basic rom 2 & ex rom 1
+ { EXROM(0), KANJIROM(3), EXROM(0), KANJIROM(3) }, //0x0b: ex rom 0 & voice rom 1 / ex rom 0 & voice 1
+ { KANJIROM(2), EXROM(0), KANJIROM(2), EXROM(0) }, //0x0c: voice rom 1 & ex rom 0 / voice rom 0 & ex rom 0
+ { WRAM(4), WRAM(5), WRAM(6), WRAM(7) }, //0x0d: ram 4 & 5 / ram 6 & 7
+ { EXWRAM(4), EXWRAM(5), EXWRAM(6), EXWRAM(7) }, //0x0e: exram 4 & 5 / exram 6 & 7
+ { INVALID(0), INVALID(0), INVALID(0), INVALID(0) } //0x0f: <invalid setting>
+};
+
+WRITE8_MEMBER(pc6001_state::pc6001m2_bank_r0_w)
+{
+ UINT8 *ROM = m_region_maincpu->base();
+ UINT8 *gfx_data = m_region_gfx1->base();
+
+// bankaddress = 0x10000 + (0x4000 * ((data & 0x40)>>6));
+// membank(1)->set_base(&ROM[bankaddress]);
+
+ m_bank_r0 = data;
+
+// printf("%02x BANK | %02x\n",data,m_bank_opt);
+ m_bank1->set_base(&ROM[banksw_table_r0[(data & 0xf)+(m_bank_opt*0x10)][0]]);
+ m_bank2->set_base(&ROM[banksw_table_r0[(data & 0xf)+(m_bank_opt*0x10)][1]]);
+ m_bank3->set_base(&ROM[banksw_table_r0[((data & 0xf0)>>4)+(m_bank_opt*0x10)][2]]);
+ if(!m_gfx_bank_on)
+ m_bank4->set_base(&ROM[banksw_table_r0[((m_bank_r0 & 0xf0)>>4)+(m_bank_opt*0x10)][3]]);
+ else
+ m_bank4->set_base(&gfx_data[m_cgrom_bank_addr]);
+}
+
+WRITE8_MEMBER(pc6001_state::pc6001m2_bank_r1_w)
+{
+ UINT8 *ROM = m_region_maincpu->base();
+
+// bankaddress = 0x10000 + (0x4000 * ((data & 0x40)>>6));
+// membank(1)->set_base(&ROM[bankaddress]);
+
+ m_bank_r1 = data;
+
+// printf("%02x BANK\n",data);
+ m_bank5->set_base(&ROM[banksw_table_r1[(data & 0xf)+(m_bank_opt*0x10)][0]]);
+ m_bank6->set_base(&ROM[banksw_table_r1[(data & 0xf)+(m_bank_opt*0x10)][1]]);
+ m_bank7->set_base(&ROM[banksw_table_r1[((data & 0xf0)>>4)+(m_bank_opt*0x10)][2]]);
+ m_bank8->set_base(&ROM[banksw_table_r1[((data & 0xf0)>>4)+(m_bank_opt*0x10)][3]]);
+}
+
+WRITE8_MEMBER(pc6001_state::pc6001m2_bank_w0_w)
+{
+ m_bank_w = data;
+}
+
+WRITE8_MEMBER(pc6001_state::pc6001m2_opt_bank_w)
+{
+ UINT8 *ROM = m_region_maincpu->base();
+ UINT8 *gfx_data = m_region_gfx1->base();
+
+ /*
+ 0 - TVROM / VOICE ROM
+ 1 - KANJI ROM bank 0
+ 2 - KANJI ROM bank 1
+ 3 - TVROM / VOICE ROM
+ */
+ m_bank_opt = data & 3;
+
+ m_bank1->set_base(&ROM[banksw_table_r0[(m_bank_r0 & 0xf)+(m_bank_opt*0x10)][0]]);
+ m_bank2->set_base(&ROM[banksw_table_r0[(m_bank_r0 & 0xf)+(m_bank_opt*0x10)][1]]);
+ m_bank3->set_base(&ROM[banksw_table_r0[((m_bank_r0 & 0xf0)>>4)+(m_bank_opt*0x10)][2]]);
+ if(!m_gfx_bank_on)
+ m_bank4->set_base(&ROM[banksw_table_r0[((m_bank_r0 & 0xf0)>>4)+(m_bank_opt*0x10)][3]]);
+ else
+ m_bank4->set_base(&gfx_data[m_cgrom_bank_addr]);
+ m_bank4->set_base(&ROM[banksw_table_r0[((m_bank_r0 & 0xf0)>>4)+(m_bank_opt*0x10)][3]]);
+ m_bank5->set_base(&ROM[banksw_table_r1[(m_bank_r1 & 0xf)+(m_bank_opt*0x10)][0]]);
+ m_bank6->set_base(&ROM[banksw_table_r1[(m_bank_r1 & 0xf)+(m_bank_opt*0x10)][1]]);
+ m_bank7->set_base(&ROM[banksw_table_r1[((m_bank_r1 & 0xf0)>>4)+(m_bank_opt*0x10)][2]]);
+ m_bank8->set_base(&ROM[banksw_table_r1[((m_bank_r1 & 0xf0)>>4)+(m_bank_opt*0x10)][3]]);
+
+}
+
+WRITE8_MEMBER(pc6001_state::work_ram0_w)
+{
+ UINT8 *ROM = m_region_maincpu->base();
+ ROM[offset+((m_bank_w & 0x01) ? WRAM(0) : EXWRAM(0))] = data;
+}
+
+WRITE8_MEMBER(pc6001_state::work_ram1_w)
+{
+ UINT8 *ROM = m_region_maincpu->base();
+ ROM[offset+((m_bank_w & 0x01) ? WRAM(1) : EXWRAM(1))] = data;
+}
+
+WRITE8_MEMBER(pc6001_state::work_ram2_w)
+{
+ UINT8 *ROM = m_region_maincpu->base();
+ ROM[offset+((m_bank_w & 0x04) ? WRAM(2) : EXWRAM(2))] = data;
+}
+
+WRITE8_MEMBER(pc6001_state::work_ram3_w)
+{
+ UINT8 *ROM = m_region_maincpu->base();
+ ROM[offset+((m_bank_w & 0x04) ? WRAM(3) : EXWRAM(3))] = data;
+}
+
+WRITE8_MEMBER(pc6001_state::work_ram4_w)
+{
+ UINT8 *ROM = m_region_maincpu->base();
+ ROM[offset+((m_bank_w & 0x10) ? WRAM(4) : EXWRAM(4))] = data;
+}
+
+WRITE8_MEMBER(pc6001_state::work_ram5_w)
+{
+ UINT8 *ROM = m_region_maincpu->base();
+ ROM[offset+((m_bank_w & 0x10) ? WRAM(5) : EXWRAM(5))] = data;
+}
+
+WRITE8_MEMBER(pc6001_state::work_ram6_w)
+{
+ UINT8 *ROM = m_region_maincpu->base();
+ ROM[offset+((m_bank_w & 0x40) ? WRAM(6) : EXWRAM(6))] = data;
+}
+
+WRITE8_MEMBER(pc6001_state::work_ram7_w)
+{
+ UINT8 *ROM = m_region_maincpu->base();
+ ROM[offset+((m_bank_w & 0x40) ? WRAM(7) : EXWRAM(7))] = data;
+}
+
+
+WRITE8_MEMBER(pc6001_state::necmk2_ppi8255_w)
+{
+ if (offset==3)
+ {
+ if(data & 1)
+ m_port_c_8255 |= 1<<((data>>1)&0x07);
+ else
+ m_port_c_8255 &= ~(1<<((data>>1)&0x07));
+
+ switch(data) {
+ case 0x08: m_port_c_8255 |= 0x88; break;
+ case 0x09: m_port_c_8255 &= 0xf7; break;
+ case 0x0c: m_port_c_8255 |= 0x28; break;
+ case 0x0d: m_port_c_8255 &= 0xf7; break;
+ default: break;
+ }
+
+ m_port_c_8255 |= 0xa8;
+
+ {
+ UINT8 *ROM = m_region_maincpu->base();
+ UINT8 *gfx_data = m_region_gfx1->base();
+
+ //printf("%02x\n",data);
+
+ if((data & 0x0f) == 0x05)
+ {
+ m_gfx_bank_on = 0;
+ m_bank4->set_base(&ROM[banksw_table_r0[((m_bank_r0 & 0xf0)>>4)+(m_bank_opt*0x10)][3]]);
+ }
+ if((data & 0x0f) == 0x04)
+ {
+ m_gfx_bank_on = 1;
+ m_bank4->set_base(&gfx_data[m_cgrom_bank_addr]);
+ }
+ }
+ }
+ m_ppi->write(space,offset,data);
+}
+
+void pc6001_state::vram_bank_change(UINT8 vram_bank)
+{
+ UINT8 *work_ram = m_region_maincpu->base();
+
+// popmessage("%02x",vram_bank);
+
+ switch(vram_bank & 0x66)
+ {
+ case 0x00: m_video_ram = work_ram + 0x8000 + 0x28000; break; //4 color mode
+ case 0x02: m_video_ram = work_ram + 0xc000 + 0x28000; break;
+ case 0x04: m_video_ram = work_ram + 0x8000 + 0x28000; break;
+ case 0x06: m_video_ram = work_ram + 0xc000 + 0x28000; break;
+ case 0x20: m_video_ram = work_ram + 0xc000 + 0x28000; break; //4 color mode
+ case 0x22: m_video_ram = work_ram + 0xe000 + 0x28000; break;
+ case 0x24: m_video_ram = work_ram + 0xc000 + 0x28000; break;
+ case 0x26: m_video_ram = work_ram + 0xe000 + 0x28000; break;
+ case 0x40: m_video_ram = work_ram + 0x0000 + 0x28000; break; //4 color mode
+ case 0x42: m_video_ram = work_ram + 0x8000 + 0x28000; break;
+ case 0x44: m_video_ram = work_ram + 0x0000 + 0x28000; break;
+ case 0x46: m_video_ram = work_ram + 0x8000 + 0x28000; break;
+ case 0x60: m_video_ram = work_ram + 0x4000 + 0x28000; break; //4 color mode
+ case 0x62: m_video_ram = work_ram + 0xa000 + 0x28000; break;
+ case 0x64: m_video_ram = work_ram + 0x4000 + 0x28000; break;
+ case 0x66: m_video_ram = work_ram + 0xa000 + 0x28000; break;
+ }
+}
+
+WRITE8_MEMBER(pc6001_state::pc6001m2_system_latch_w)
+{
+ if((!(m_sys_latch & 8)) && data & 0x8) //PLAY tape cmd
+ {
+ m_cas_switch = 1;
+ //m_cassette->change_state(CASSETTE_MOTOR_ENABLED,CASSETTE_MASK_MOTOR);
+ //m_cassette->change_state(CASSETTE_PLAY,CASSETTE_MASK_UISTATE);
+ }
+ if((m_sys_latch & 8) && ((data & 0x8) == 0)) //STOP tape cmd
+ {
+ m_cas_switch = 0;
+ //m_cassette->change_state(CASSETTE_MOTOR_DISABLED,CASSETTE_MASK_MOTOR);
+ //m_cassette->change_state(CASSETTE_STOPPED,CASSETTE_MASK_UISTATE);
+ //m_irq_vector = 0x00;
+ //m_maincpu->set_input_line(0, ASSERT_LINE);
+ }
+
+ m_sys_latch = data;
+
+ m_timer_irq_mask = data & 1;
+ vram_bank_change((m_ex_vram_bank & 0x06) | ((m_sys_latch & 0x06) << 4));
+
+ //printf("%02x B0\n",data);
+}
+
+
+WRITE8_MEMBER(pc6001_state::pc6001m2_vram_bank_w)
+{
+ //static const UINT32 startaddr[] = {WRAM(6), WRAM(6), WRAM(0), WRAM(4) };
+
+ m_ex_vram_bank = data;
+ vram_bank_change((m_ex_vram_bank & 0x06) | ((m_sys_latch & 0x06) << 4));
+
+ m_exgfx_text_mode = ((data & 2) == 0);
+ m_cgrom_bank_addr = (data & 2) ? 0x0000 : 0x2000;
+
+ m_exgfx_bitmap_mode = (data & 8);
+ m_exgfx_2bpp_mode = ((data & 6) == 0);
+
+ {
+ /* Apparently bitmap modes changes the screen res to 320 x 200 */
+ {
+ rectangle visarea = machine().first_screen()->visible_area();
+ int y_height;
+
+ y_height = (m_exgfx_bitmap_mode || m_exgfx_2bpp_mode) ? 200 : 240;
+
+ visarea.set(0, (320) - 1, 0, (y_height) - 1);
+
+ machine().first_screen()->configure(320, 240, visarea, machine().first_screen()->frame_period().attoseconds());
+ }
+ }
+
+// popmessage("%02x",data);
+
+// m_video_ram = work_ram + startaddr[(data >> 1) & 0x03];
+}
+
+WRITE8_MEMBER(pc6001_state::pc6001m2_col_bank_w)
+{
+ m_bgcol_bank = (data & 7);
+}
+
+
+WRITE8_MEMBER(pc6001_state::pc6001m2_0xf3_w)
+{
+ /*
+ x--- ---- M1 (?) wait setting
+ -x-- ---- ROM wait setting
+ --x- ---- RAM wait setting
+ ---x ---- custom irq 2 address output
+ ---- x--- custom irq 1 address output
+ ---- -x-- timer irq mask 2 (mirror?)
+ ---- --x- custom irq 2 mask
+ ---- ---x custom irq 1 mask
+ */
+ m_timer_irq_mask2 = data & 4;
+}
+
+TIMER_CALLBACK_MEMBER(pc6001_state::audio_callback)
+{
+ if(m_cas_switch == 0 && ((m_timer_irq_mask == 0) || (m_timer_irq_mask2 == 0)))
+ {
+ if(IRQ_LOG) printf("Timer IRQ called %02x\n",m_timer_irq_vector);
+ m_irq_vector = m_timer_irq_vector;
+ m_maincpu->set_input_line(0, ASSERT_LINE);
+ }
+}
+
+
+WRITE8_MEMBER(pc6001_state::pc6001m2_timer_adj_w)
+{
+ m_timer_hz_div = data;
+ attotime period = attotime::from_hz((487.5*4)/(m_timer_hz_div+1));
+ m_timer_irq_timer->adjust(period, 0, period);
+}
+
+WRITE8_MEMBER(pc6001_state::pc6001m2_timer_irqv_w)
+{
+ m_timer_irq_vector = data;
+}
+
+READ8_MEMBER(pc6001_state::pc6001m2_bank_r0_r)
+{
+ return m_bank_r0;
+}
+
+READ8_MEMBER(pc6001_state::pc6001m2_bank_r1_r)
+{
+ return m_bank_r1;
+}
+
+READ8_MEMBER(pc6001_state::pc6001m2_bank_w0_r)
+{
+ return m_bank_w;
+}
+
+static ADDRESS_MAP_START(pc6001m2_map, AS_PROGRAM, 8, pc6001_state )
+ ADDRESS_MAP_UNMAP_HIGH
+ AM_RANGE(0x0000, 0x1fff) AM_ROMBANK("bank1") AM_WRITE(work_ram0_w)
+ AM_RANGE(0x2000, 0x3fff) AM_ROMBANK("bank2") AM_WRITE(work_ram1_w)
+ AM_RANGE(0x4000, 0x5fff) AM_ROMBANK("bank3") AM_WRITE(work_ram2_w)
+ AM_RANGE(0x6000, 0x7fff) AM_ROMBANK("bank4") AM_WRITE(work_ram3_w)
+ AM_RANGE(0x8000, 0x9fff) AM_ROMBANK("bank5") AM_WRITE(work_ram4_w)
+ AM_RANGE(0xa000, 0xbfff) AM_ROMBANK("bank6") AM_WRITE(work_ram5_w)
+ AM_RANGE(0xc000, 0xdfff) AM_ROMBANK("bank7") AM_WRITE(work_ram6_w)
+ AM_RANGE(0xe000, 0xffff) AM_ROMBANK("bank8") AM_WRITE(work_ram7_w)
+ADDRESS_MAP_END
+
+static ADDRESS_MAP_START( pc6001m2_io , AS_IO, 8, pc6001_state )
+ ADDRESS_MAP_UNMAP_HIGH
+ ADDRESS_MAP_GLOBAL_MASK(0xff)
+ AM_RANGE(0x80, 0x80) AM_DEVREADWRITE("uart", i8251_device, data_r, data_w)
+ AM_RANGE(0x81, 0x81) AM_DEVREADWRITE("uart", i8251_device, status_r, control_w)
+
+ AM_RANGE(0x90, 0x93) AM_MIRROR(0x0c) AM_READWRITE(nec_ppi8255_r, necmk2_ppi8255_w)
+
+ AM_RANGE(0xa0, 0xa0) AM_MIRROR(0x0c) AM_DEVWRITE("ay8910", ay8910_device, address_w)
+ AM_RANGE(0xa1, 0xa1) AM_MIRROR(0x0c) AM_DEVWRITE("ay8910", ay8910_device, data_w)
+ AM_RANGE(0xa2, 0xa2) AM_MIRROR(0x0c) AM_DEVREAD("ay8910", ay8910_device, data_r)
+ AM_RANGE(0xa3, 0xa3) AM_MIRROR(0x0c) AM_NOP
+
+ AM_RANGE(0xb0, 0xb0) AM_MIRROR(0x0f) AM_WRITE(pc6001m2_system_latch_w)
+
+ AM_RANGE(0xc0, 0xc0) AM_WRITE(pc6001m2_col_bank_w)
+ AM_RANGE(0xc1, 0xc1) AM_WRITE(pc6001m2_vram_bank_w)
+ AM_RANGE(0xc2, 0xc2) AM_WRITE(pc6001m2_opt_bank_w)
+
+ AM_RANGE(0xd0, 0xd3) AM_MIRROR(0x0c) AM_NOP // disk device
+
+ AM_RANGE(0xe0, 0xe3) AM_MIRROR(0x0c) AM_DEVREADWRITE("upd7752", upd7752_device, read, write)
+
+ AM_RANGE(0xf0, 0xf0) AM_READWRITE(pc6001m2_bank_r0_r,pc6001m2_bank_r0_w)
+ AM_RANGE(0xf1, 0xf1) AM_READWRITE(pc6001m2_bank_r1_r,pc6001m2_bank_r1_w)
+ AM_RANGE(0xf2, 0xf2) AM_READWRITE(pc6001m2_bank_w0_r,pc6001m2_bank_w0_w)
+ AM_RANGE(0xf3, 0xf3) AM_WRITE(pc6001m2_0xf3_w)
+// AM_RANGE(0xf4
+// AM_RANGE(0xf5
+ AM_RANGE(0xf6, 0xf6) AM_WRITE(pc6001m2_timer_adj_w)
+ AM_RANGE(0xf7, 0xf7) AM_WRITE(pc6001m2_timer_irqv_w)
+ADDRESS_MAP_END
+
+/* disk device placeholder (TODO: identify & hook-up this) */
+READ8_MEMBER(pc6001_state::pc6601_fdc_r)
+{
+ return machine().rand();
+}
+
+WRITE8_MEMBER(pc6001_state::pc6601_fdc_w)
+{
+}
+
+static ADDRESS_MAP_START( pc6601_io , AS_IO, 8, pc6001_state )
+ ADDRESS_MAP_UNMAP_HIGH
+ ADDRESS_MAP_GLOBAL_MASK(0xff)
+ AM_RANGE(0x80, 0x80) AM_DEVREADWRITE("uart", i8251_device, data_r, data_w)
+ AM_RANGE(0x81, 0x81) AM_DEVREADWRITE("uart", i8251_device, status_r, control_w)
+
+ AM_RANGE(0x90, 0x93) AM_MIRROR(0x0c) AM_READWRITE(nec_ppi8255_r, necmk2_ppi8255_w)
+
+ AM_RANGE(0xa0, 0xa0) AM_MIRROR(0x0c) AM_DEVWRITE("ay8910", ay8910_device, address_w)
+ AM_RANGE(0xa1, 0xa1) AM_MIRROR(0x0c) AM_DEVWRITE("ay8910", ay8910_device, data_w)
+ AM_RANGE(0xa2, 0xa2) AM_MIRROR(0x0c) AM_DEVREAD("ay8910", ay8910_device, data_r)
+ AM_RANGE(0xa3, 0xa3) AM_MIRROR(0x0c) AM_NOP
+
+ AM_RANGE(0xb0, 0xb0) AM_WRITE(pc6001m2_system_latch_w)
+ /* these are disk related */
+// AM_RANGE(0xb1
+// AM_RANGE(0xb2
+// AM_RANGE(0xb3
+
+ AM_RANGE(0xc0, 0xc0) AM_WRITE(pc6001m2_col_bank_w)
+ AM_RANGE(0xc1, 0xc1) AM_WRITE(pc6001m2_vram_bank_w)
+ AM_RANGE(0xc2, 0xc2) AM_WRITE(pc6001m2_opt_bank_w)
+
+ AM_RANGE(0xd0, 0xdf) AM_READWRITE(pc6601_fdc_r,pc6601_fdc_w) // disk device
+
+ AM_RANGE(0xe0, 0xe3) AM_MIRROR(0x0c) AM_DEVREADWRITE("upd7752", upd7752_device, read, write)
+
+ AM_RANGE(0xf0, 0xf0) AM_READWRITE(pc6001m2_bank_r0_r,pc6001m2_bank_r0_w)
+ AM_RANGE(0xf1, 0xf1) AM_READWRITE(pc6001m2_bank_r1_r,pc6001m2_bank_r1_w)
+ AM_RANGE(0xf2, 0xf2) AM_READWRITE(pc6001m2_bank_w0_r,pc6001m2_bank_w0_w)
+ AM_RANGE(0xf3, 0xf3) AM_WRITE(pc6001m2_0xf3_w)
+// AM_RANGE(0xf4
+// AM_RANGE(0xf5
+ AM_RANGE(0xf6, 0xf6) AM_WRITE(pc6001m2_timer_adj_w)
+ AM_RANGE(0xf7, 0xf7) AM_WRITE(pc6001m2_timer_irqv_w)
+ADDRESS_MAP_END
+
+/* PC-6001 SR */
+
+#define SR_SYSROM_1(_v_) \
+ 0x10000+(0x1000*_v_)
+#define SR_SYSROM_2(_v_) \
+ 0x20000+(0x1000*_v_)
+#define SR_CGROM1(_v_) \
+ 0x30000+(0x1000*_v_)
+#define SR_EXROM0(_v_) \
+ 0x40000+(0x1000*_v_)
+#define SR_EXROM1(_v_) \
+ 0x50000+(0x1000*_v_)
+#define SR_EXRAM0(_v_) \
+ 0x60000+(0x1000*_v_)
+#define SR_WRAM0(_v_) \
+ 0x70000+(0x1000*_v_)
+#define SR_NULL(_v_) \
+ 0x80000+(0x1000*_v_)
+READ8_MEMBER(pc6001_state::pc6001sr_bank_rn_r)
+{
+ return m_sr_bank_r[offset];
+}
+
+WRITE8_MEMBER(pc6001_state::pc6001sr_bank_rn_w)
+{
+ memory_bank *bank[8] = { m_bank1, m_bank2, m_bank3, m_bank4, m_bank5, m_bank6, m_bank7, m_bank8 };
+ UINT8 *ROM = m_region_maincpu->base();
+ UINT8 bank_num;
+
+ m_sr_bank_r[offset] = data;
+ bank_num = data & 0x0f;
+
+ switch(data & 0xf0)
+ {
+ case 0xf0: bank[offset]->set_base(&ROM[SR_SYSROM_1(bank_num)]); break;
+ case 0xe0: bank[offset]->set_base(&ROM[SR_SYSROM_2(bank_num)]); break;
+ case 0xd0: bank[offset]->set_base(&ROM[SR_CGROM1(bank_num)]); break;
+ case 0xc0: bank[offset]->set_base(&ROM[SR_EXROM0(bank_num)]); break;
+ case 0xb0: bank[offset]->set_base(&ROM[SR_EXROM1(bank_num)]); break;
+ case 0x20: bank[offset]->set_base(&ROM[SR_EXRAM0(bank_num)]); break;
+ case 0x00: bank[offset]->set_base(&ROM[SR_WRAM0(bank_num)]); break;
+ default: bank[offset]->set_base(&ROM[SR_NULL(bank_num)]); break;
+ }
+}
+
+READ8_MEMBER(pc6001_state::pc6001sr_bank_wn_r)
+{
+ return m_sr_bank_w[offset];
+}
+
+WRITE8_MEMBER(pc6001_state::pc6001sr_bank_wn_w)
+{
+ m_sr_bank_w[offset] = data;
+}
+
+#define SR_WRAM_BANK_W(_v_) \
+{ \
+ UINT8 *ROM = m_region_maincpu->base(); \
+ UINT8 bank_num; \
+ bank_num = m_sr_bank_w[_v_] & 0x0f; \
+ if((m_sr_bank_w[_v_] & 0xf0) != 0x20) \
+ ROM[offset+(SR_WRAM0(bank_num))] = data; \
+ else \
+ ROM[offset+(SR_EXRAM0(bank_num))] = data; \
+}
+WRITE8_MEMBER(pc6001_state::sr_work_ram0_w){ SR_WRAM_BANK_W(0); }
+WRITE8_MEMBER(pc6001_state::sr_work_ram1_w){ SR_WRAM_BANK_W(1); }
+WRITE8_MEMBER(pc6001_state::sr_work_ram2_w){ SR_WRAM_BANK_W(2); }
+WRITE8_MEMBER(pc6001_state::sr_work_ram3_w){ SR_WRAM_BANK_W(3); }
+WRITE8_MEMBER(pc6001_state::sr_work_ram4_w){ SR_WRAM_BANK_W(4); }
+WRITE8_MEMBER(pc6001_state::sr_work_ram5_w){ SR_WRAM_BANK_W(5); }
+WRITE8_MEMBER(pc6001_state::sr_work_ram6_w){ SR_WRAM_BANK_W(6); }
+WRITE8_MEMBER(pc6001_state::sr_work_ram7_w){ SR_WRAM_BANK_W(7); }
+
+WRITE8_MEMBER(pc6001_state::pc6001sr_mode_w)
+{
+ m_sr_video_mode = data;
+
+ if(data & 1)
+ assert("PC-6001SR in Mk-2 compatibility mode not yet supported!\n");
+}
+
+WRITE8_MEMBER(pc6001_state::pc6001sr_vram_bank_w)
+{
+ UINT8 *work_ram = m_region_maincpu->base();
+
+ m_video_ram = work_ram + 0x70000 + ((data & 0x0f)*0x1000);
+}
+
+WRITE8_MEMBER(pc6001_state::pc6001sr_system_latch_w)
+{
+ if((!(m_sys_latch & 8)) && data & 0x8) //PLAY tape cmd
+ {
+ m_cas_switch = 1;
+ //m_cassette->change_state(CASSETTE_MOTOR_ENABLED,CASSETTE_MASK_MOTOR);
+ //m_cassette->change_state(CASSETTE_PLAY,CASSETTE_MASK_UISTATE);
+ }
+ if((m_sys_latch & 8) && ((data & 0x8) == 0)) //STOP tape cmd
+ {
+ m_cas_switch = 0;
+ //m_cassette->change_state(CASSETTE_MOTOR_DISABLED,CASSETTE_MASK_MOTOR);
+ //m_cassette->change_state(CASSETTE_STOPPED,CASSETTE_MASK_UISTATE);
+ //m_irq_vector = 0x00;
+ //m_maincpu->set_input_line(0, ASSERT_LINE);
+ }
+
+ m_sys_latch = data;
+
+ m_timer_irq_mask = data & 1;
+ //vram_bank_change((m_ex_vram_bank & 0x06) | ((m_sys_latch & 0x06) << 4));
+
+ //printf("%02x B0\n",data);
+}
+
+WRITE8_MEMBER(pc6001_state::necsr_ppi8255_w)
+{
+ if (offset==3)
+ {
+ if(data & 1)
+ m_port_c_8255 |= 1<<((data>>1)&0x07);
+ else
+ m_port_c_8255 &= ~(1<<((data>>1)&0x07));
+
+ switch(data) {
+ case 0x08: m_port_c_8255 |= 0x88; break;
+ case 0x09: m_port_c_8255 &= 0xf7; break;
+ case 0x0c: m_port_c_8255 |= 0x28; break;
+ case 0x0d: m_port_c_8255 &= 0xf7; break;
+ default: break;
+ }
+
+ m_port_c_8255 |= 0xa8;
+
+ if(0)
+ {
+ //printf("%02x\n",data);
+
+ if ((data & 0x0f) == 0x05 && m_cart_rom)
+ m_bank1->set_base(m_cart_rom->base() + 0x2000);
+ if ((data & 0x0f) == 0x04)
+ m_bank1->set_base(m_region_gfx1->base());
+ }
+ }
+ m_ppi->write(space,offset,data);
+}
+
+
+static ADDRESS_MAP_START(pc6001sr_map, AS_PROGRAM, 8, pc6001_state )
+ ADDRESS_MAP_UNMAP_HIGH
+ AM_RANGE(0x0000, 0x1fff) AM_ROMBANK("bank1") AM_WRITE(sr_work_ram0_w)
+ AM_RANGE(0x2000, 0x3fff) AM_ROMBANK("bank2") AM_WRITE(sr_work_ram1_w)
+ AM_RANGE(0x4000, 0x5fff) AM_ROMBANK("bank3") AM_WRITE(sr_work_ram2_w)
+ AM_RANGE(0x6000, 0x7fff) AM_ROMBANK("bank4") AM_WRITE(sr_work_ram3_w)
+ AM_RANGE(0x8000, 0x9fff) AM_ROMBANK("bank5") AM_WRITE(sr_work_ram4_w)
+ AM_RANGE(0xa000, 0xbfff) AM_ROMBANK("bank6") AM_WRITE(sr_work_ram5_w)
+ AM_RANGE(0xc000, 0xdfff) AM_ROMBANK("bank7") AM_WRITE(sr_work_ram6_w)
+ AM_RANGE(0xe000, 0xffff) AM_ROMBANK("bank8") AM_WRITE(sr_work_ram7_w)
+ADDRESS_MAP_END
+
+static ADDRESS_MAP_START( pc6001sr_io , AS_IO, 8, pc6001_state )
+ ADDRESS_MAP_UNMAP_HIGH
+ ADDRESS_MAP_GLOBAL_MASK(0xff)
+ AM_RANGE(0x60, 0x67) AM_READWRITE(pc6001sr_bank_rn_r,pc6001sr_bank_rn_w)
+ AM_RANGE(0x68, 0x6f) AM_READWRITE(pc6001sr_bank_wn_r,pc6001sr_bank_wn_w)
+ AM_RANGE(0x80, 0x80) AM_DEVREADWRITE("uart", i8251_device, data_r, data_w)
+ AM_RANGE(0x81, 0x81) AM_DEVREADWRITE("uart", i8251_device, status_r, control_w)
+
+ AM_RANGE(0x90, 0x93) AM_MIRROR(0x0c) AM_READWRITE(nec_ppi8255_r, necsr_ppi8255_w)
+
+ AM_RANGE(0xa0, 0xa0) AM_MIRROR(0x0c) AM_DEVWRITE("ay8910", ay8910_device, address_w)
+ AM_RANGE(0xa1, 0xa1) AM_MIRROR(0x0c) AM_DEVWRITE("ay8910", ay8910_device, data_w)
+ AM_RANGE(0xa2, 0xa2) AM_MIRROR(0x0c) AM_DEVREAD("ay8910", ay8910_device, data_r)
+ AM_RANGE(0xa3, 0xa3) AM_MIRROR(0x0c) AM_NOP
+
+ AM_RANGE(0xb0, 0xb0) AM_WRITE(pc6001sr_system_latch_w)
+ /* these are disk related */
+// AM_RANGE(0xb1
+// AM_RANGE(0xb2
+// AM_RANGE(0xb3
+
+// AM_RANGE(0xc0, 0xc0) AM_WRITE(pc6001m2_col_bank_w)
+// AM_RANGE(0xc1, 0xc1) AM_WRITE(pc6001m2_vram_bank_w)
+// AM_RANGE(0xc2, 0xc2) AM_WRITE(pc6001m2_opt_bank_w)
+
+ AM_RANGE(0xc8, 0xc8) AM_WRITE(pc6001sr_mode_w)
+ AM_RANGE(0xc9, 0xc9) AM_WRITE(pc6001sr_vram_bank_w)
+
+ AM_RANGE(0xd0, 0xdf) AM_READWRITE(pc6601_fdc_r,pc6601_fdc_w) // disk device
+
+ AM_RANGE(0xe0, 0xe3) AM_MIRROR(0x0c) AM_DEVREADWRITE("upd7752", upd7752_device, read, write)
+
+// AM_RANGE(0xf0, 0xf0) AM_READWRITE(pc6001m2_bank_r0_r,pc6001m2_bank_r0_w)
+// AM_RANGE(0xf1, 0xf1) AM_READWRITE(pc6001m2_bank_r1_r,pc6001m2_bank_r1_w)
+// AM_RANGE(0xf2, 0xf2) AM_READWRITE(pc6001m2_bank_w0_r,pc6001m2_bank_w0_w)
+ AM_RANGE(0xf3, 0xf3) AM_WRITE(pc6001m2_0xf3_w)
+// AM_RANGE(0xf4
+// AM_RANGE(0xf5
+ AM_RANGE(0xf6, 0xf6) AM_WRITE(pc6001m2_timer_adj_w)
+ AM_RANGE(0xf7, 0xf7) AM_WRITE(pc6001m2_timer_irqv_w)
+ADDRESS_MAP_END
+
+/* Input ports */
+static INPUT_PORTS_START( pc6001 )
+ PORT_START("MODE4_DSW") //TODO: is this really a DSW? bit arrangement is also unknown if so.
+ PORT_DIPNAME( 0x07, 0x00, "Mode 4 GFX colors" )
+ PORT_DIPSETTING( 0x00, "Monochrome" )
+ PORT_DIPSETTING( 0x01, "Red/Blue" )
+ PORT_DIPSETTING( 0x02, "Blue/Red" )
+ PORT_DIPSETTING( 0x03, "Pink/Green" )
+ PORT_DIPSETTING( 0x04, "Green/Pink" )
+ //5-6-7 is presumably invalid
+
+ /* TODO: these two are unchecked */
+ PORT_START("P1")
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 )
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 )
+ PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
+
+ PORT_START("P2")
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(2)
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(2)
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(2)
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(2)
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2)
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2)
+ PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
+
+ PORT_START("key1") //0x00-0x1f
+ PORT_BIT(0x00000001,IP_ACTIVE_HIGH,IPT_UNUSED) //0x00 null
+ PORT_BIT(0x00000002,IP_ACTIVE_HIGH,IPT_UNUSED) //0x01 soh
+ PORT_BIT(0x00000004,IP_ACTIVE_HIGH,IPT_UNUSED) //0x02 stx
+ PORT_BIT(0x00000008,IP_ACTIVE_HIGH,IPT_UNUSED) //0x03 etx
+ PORT_BIT(0x00000010,IP_ACTIVE_HIGH,IPT_UNUSED) //0x04 etx
+ PORT_BIT(0x00000020,IP_ACTIVE_HIGH,IPT_UNUSED) //0x05 eot
+ PORT_BIT(0x00000040,IP_ACTIVE_HIGH,IPT_UNUSED) //0x06 enq
+ PORT_BIT(0x00000080,IP_ACTIVE_HIGH,IPT_UNUSED) //0x07 ack
+ PORT_BIT(0x00000100,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Backspace") PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8)
+ PORT_BIT(0x00000200,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Tab") PORT_CODE(KEYCODE_TAB) PORT_CHAR(9)
+ PORT_BIT(0x00000400,IP_ACTIVE_HIGH,IPT_UNUSED) //0x0a
+ PORT_BIT(0x00000800,IP_ACTIVE_HIGH,IPT_UNUSED) //0x0b lf
+ PORT_BIT(0x00001000,IP_ACTIVE_HIGH,IPT_UNUSED) //0x0c vt
+ PORT_BIT(0x00002000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("RETURN") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(27)
+ PORT_BIT(0x00004000,IP_ACTIVE_HIGH,IPT_UNUSED) //0x0e cr
+ PORT_BIT(0x00008000,IP_ACTIVE_HIGH,IPT_UNUSED) //0x0f so
+
+ PORT_BIT(0x00010000,IP_ACTIVE_HIGH,IPT_UNUSED) //0x10 si
+ PORT_BIT(0x00020000,IP_ACTIVE_HIGH,IPT_UNUSED) //0x11 dle
+ PORT_BIT(0x00040000,IP_ACTIVE_HIGH,IPT_UNUSED) //0x12 dc1
+ PORT_BIT(0x00080000,IP_ACTIVE_HIGH,IPT_UNUSED) //0x13 dc2
+ PORT_BIT(0x00100000,IP_ACTIVE_HIGH,IPT_UNUSED) //0x14 dc3
+ PORT_BIT(0x00200000,IP_ACTIVE_HIGH,IPT_UNUSED) //0x15 dc4
+ PORT_BIT(0x00400000,IP_ACTIVE_HIGH,IPT_UNUSED) //0x16 nak
+ PORT_BIT(0x00800000,IP_ACTIVE_HIGH,IPT_UNUSED) //0x17 syn
+ PORT_BIT(0x01000000,IP_ACTIVE_HIGH,IPT_UNUSED) //0x18 etb
+ PORT_BIT(0x02000000,IP_ACTIVE_HIGH,IPT_UNUSED) //0x19 cancel
+ PORT_BIT(0x04000000,IP_ACTIVE_HIGH,IPT_UNUSED) //0x1a em
+ PORT_BIT(0x08000000,IP_ACTIVE_HIGH,IPT_UNUSED) //0x1b sub
+ PORT_BIT(0x10000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("ESC") PORT_CODE(KEYCODE_TILDE) PORT_CHAR(27)
+ PORT_BIT(0x20000000,IP_ACTIVE_HIGH,IPT_UNUSED) //0x1d fs
+ PORT_BIT(0x40000000,IP_ACTIVE_HIGH,IPT_UNUSED) //0x1e gs
+ PORT_BIT(0x80000000,IP_ACTIVE_HIGH,IPT_UNUSED) //0x1f us
+
+ PORT_START("key2") //0x20-0x3f
+ PORT_BIT(0x00000001,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Space") PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ')
+ PORT_BIT(0x00000002,IP_ACTIVE_HIGH,IPT_UNUSED) //0x21 !
+ PORT_BIT(0x00000004,IP_ACTIVE_HIGH,IPT_UNUSED) //0x22 "
+ PORT_BIT(0x00000008,IP_ACTIVE_HIGH,IPT_UNUSED) //0x23 #
+ PORT_BIT(0x00000010,IP_ACTIVE_HIGH,IPT_UNUSED) //0x24 $
+ PORT_BIT(0x00000020,IP_ACTIVE_HIGH,IPT_UNUSED) //0x25 %
+ PORT_BIT(0x00000040,IP_ACTIVE_HIGH,IPT_UNUSED) //0x26 &
+ PORT_BIT(0x00000080,IP_ACTIVE_HIGH,IPT_UNUSED) //0x27 '
+ PORT_BIT(0x00000100,IP_ACTIVE_HIGH,IPT_UNUSED) //0x28 (
+ PORT_BIT(0x00000200,IP_ACTIVE_HIGH,IPT_UNUSED) //0x29 )
+ PORT_BIT(0x00000400,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("*") PORT_CODE(KEYCODE_ASTERISK) PORT_CHAR('*')
+ PORT_BIT(0x00000800,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("+") PORT_CODE(KEYCODE_PLUS_PAD) PORT_CHAR('+')
+ PORT_BIT(0x00001000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(",") PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') //0x2c
+ PORT_BIT(0x00002000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("-") PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-')
+ PORT_BIT(0x00004000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(".") PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') //0x2e
+ PORT_BIT(0x00008000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("/") PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') //0x2f
+
+ PORT_BIT(0x00010000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("0") PORT_CODE(KEYCODE_0) PORT_CHAR('0')
+ PORT_BIT(0x00020000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("1") PORT_CODE(KEYCODE_1) PORT_CHAR('1')
+ PORT_BIT(0x00040000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("2") PORT_CODE(KEYCODE_2) PORT_CHAR('2')
+ PORT_BIT(0x00080000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("3") PORT_CODE(KEYCODE_3) PORT_CHAR('3')
+ PORT_BIT(0x00100000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("4") PORT_CODE(KEYCODE_4) PORT_CHAR('4')
+ PORT_BIT(0x00200000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("5") PORT_CODE(KEYCODE_5) PORT_CHAR('5')
+ PORT_BIT(0x00400000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("6") PORT_CODE(KEYCODE_6) PORT_CHAR('6')
+ PORT_BIT(0x00800000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("7") PORT_CODE(KEYCODE_7) PORT_CHAR('7')
+ PORT_BIT(0x01000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("8") PORT_CODE(KEYCODE_8) PORT_CHAR('8')
+ PORT_BIT(0x02000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("9") PORT_CODE(KEYCODE_9) PORT_CHAR('9')
+ PORT_BIT(0x04000000,IP_ACTIVE_HIGH,IPT_UNUSED) //0x3a :
+ PORT_BIT(0x08000000,IP_ACTIVE_HIGH,IPT_UNUSED) //0x3b ;
+ PORT_BIT(0x10000000,IP_ACTIVE_HIGH,IPT_UNUSED) //0x3c <
+ PORT_BIT(0x20000000,IP_ACTIVE_HIGH,IPT_UNUSED) //0x3d =
+ PORT_BIT(0x40000000,IP_ACTIVE_HIGH,IPT_UNUSED) //0x3e >
+ PORT_BIT(0x80000000,IP_ACTIVE_HIGH,IPT_UNUSED) //0x3f ?
+
+ PORT_START("key3") //0x40-0x5f
+ PORT_BIT(0x00000001,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("@") PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('@')
+ PORT_BIT(0x00000002,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("A") PORT_CODE(KEYCODE_A) PORT_CHAR('A')
+ PORT_BIT(0x00000004,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("B") PORT_CODE(KEYCODE_B) PORT_CHAR('B')
+ PORT_BIT(0x00000008,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("C") PORT_CODE(KEYCODE_C) PORT_CHAR('C')
+ PORT_BIT(0x00000010,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("D") PORT_CODE(KEYCODE_D) PORT_CHAR('D')
+ PORT_BIT(0x00000020,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("E") PORT_CODE(KEYCODE_E) PORT_CHAR('E')
+ PORT_BIT(0x00000040,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("F") PORT_CODE(KEYCODE_F) PORT_CHAR('F')
+ PORT_BIT(0x00000080,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("G") PORT_CODE(KEYCODE_G) PORT_CHAR('G')
+ PORT_BIT(0x00000100,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("H") PORT_CODE(KEYCODE_H) PORT_CHAR('H')
+ PORT_BIT(0x00000200,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("I") PORT_CODE(KEYCODE_I) PORT_CHAR('I')
+ PORT_BIT(0x00000400,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("J") PORT_CODE(KEYCODE_J) PORT_CHAR('J')
+ PORT_BIT(0x00000800,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("K") PORT_CODE(KEYCODE_K) PORT_CHAR('K')
+ PORT_BIT(0x00001000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("L") PORT_CODE(KEYCODE_L) PORT_CHAR('L')
+ PORT_BIT(0x00002000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("M") PORT_CODE(KEYCODE_M) PORT_CHAR('M')
+ PORT_BIT(0x00004000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("N") PORT_CODE(KEYCODE_N) PORT_CHAR('N')
+ PORT_BIT(0x00008000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("O") PORT_CODE(KEYCODE_O) PORT_CHAR('O')
+ PORT_BIT(0x00010000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("P") PORT_CODE(KEYCODE_P) PORT_CHAR('P')
+ PORT_BIT(0x00020000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Q") PORT_CODE(KEYCODE_Q) PORT_CHAR('Q')
+ PORT_BIT(0x00040000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("R") PORT_CODE(KEYCODE_R) PORT_CHAR('R')
+ PORT_BIT(0x00080000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("S") PORT_CODE(KEYCODE_S) PORT_CHAR('S')
+ PORT_BIT(0x00100000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("T") PORT_CODE(KEYCODE_T) PORT_CHAR('T')
+ PORT_BIT(0x00200000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("U") PORT_CODE(KEYCODE_U) PORT_CHAR('U')
+ PORT_BIT(0x00400000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("V") PORT_CODE(KEYCODE_V) PORT_CHAR('V')
+ PORT_BIT(0x00800000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("W") PORT_CODE(KEYCODE_W) PORT_CHAR('W')
+ PORT_BIT(0x01000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("X") PORT_CODE(KEYCODE_X) PORT_CHAR('X')
+ PORT_BIT(0x02000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Y") PORT_CODE(KEYCODE_Y) PORT_CHAR('Y')
+ PORT_BIT(0x04000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Z") PORT_CODE(KEYCODE_Z) PORT_CHAR('Z')
+ PORT_BIT(0x08000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("[") PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR('[')
+ PORT_BIT(0x10000000,IP_ACTIVE_HIGH,IPT_UNUSED)
+ PORT_BIT(0x20000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("]") PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR(']')
+ PORT_BIT(0x40000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("^") PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('^')
+ PORT_BIT(0x80000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("_")
+
+ PORT_START("key_modifiers")
+ PORT_BIT(0x00000001,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("CTRL") PORT_CODE(KEYCODE_LCONTROL)
+ PORT_BIT(0x00000002,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("SHIFT") PORT_CODE(KEYCODE_LSHIFT)
+ PORT_BIT(0x00000004,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("KANA") PORT_CODE(KEYCODE_RCONTROL) PORT_TOGGLE
+ PORT_BIT(0x00000008,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("CAPS") PORT_CODE(KEYCODE_CAPSLOCK) PORT_TOGGLE
+ PORT_BIT(0x00000010,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("GRPH") PORT_CODE(KEYCODE_LALT)
+ PORT_BIT(0x00000020,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("STOP") PORT_CODE(KEYCODE_ESC)
+INPUT_PORTS_END
+
+INTERRUPT_GEN_MEMBER(pc6001_state::pc6001_interrupt)
+{
+ m_cur_keycode = check_joy_press();
+ if(IRQ_LOG) printf("Stick IRQ called 0x16\n");
+ m_irq_vector = 0x16;
+ device.execute().set_input_line(0, ASSERT_LINE);
+}
+
+INTERRUPT_GEN_MEMBER(pc6001_state::pc6001sr_interrupt)
+{
+ m_kludge^= 1;
+
+ m_cur_keycode = check_joy_press();
+ if(IRQ_LOG) printf("VRTC IRQ called 0x16\n");
+ m_irq_vector = (m_kludge) ? 0x22 : 0x16;
+ device.execute().set_input_line(0, ASSERT_LINE);
+}
+
+IRQ_CALLBACK_MEMBER(pc6001_state::pc6001_irq_callback)
+{
+ device.execute().set_input_line(0, CLEAR_LINE);
+ return m_irq_vector;
+}
+
+READ8_MEMBER(pc6001_state::pc6001_8255_porta_r)
+{
+ return 0;
+}
+
+WRITE8_MEMBER(pc6001_state::pc6001_8255_porta_w)
+{
+// if(data != 0x06)
+// printf("pc6001_8255_porta_w %02x\n",data);
+}
+
+READ8_MEMBER(pc6001_state::pc6001_8255_portb_r)
+{
+ return 0;
+}
+
+WRITE8_MEMBER(pc6001_state::pc6001_8255_portb_w)
+{
+ //printf("pc6001_8255_portb_w %02x\n",data);
+}
+
+WRITE8_MEMBER(pc6001_state::pc6001_8255_portc_w)
+{
+ //printf("pc6001_8255_portc_w %02x\n",data);
+}
+
+READ8_MEMBER(pc6001_state::pc6001_8255_portc_r)
+{
+ return 0x88;
+}
+
+UINT8 pc6001_state::check_keyboard_press()
+{
+ ioport_port *ports[3] = { m_io_key1, m_io_key2, m_io_key3 };
+ int i,port_i,scancode;
+ UINT8 shift_pressed,caps_lock;
+ scancode = 0;
+
+ shift_pressed = (m_io_key_modifiers->read() & 2)>>1;
+ caps_lock = (m_io_key_modifiers->read() & 8)>>3;
+
+ for(port_i=0;port_i<3;port_i++)
+ {
+ for(i=0;i<32;i++)
+ {
+ if((ports[port_i]->read()>>i) & 1)
+ {
+ if((shift_pressed != caps_lock) && scancode >= 0x41 && scancode <= 0x5f)
+ scancode+=0x20;
+
+ if(shift_pressed && scancode >= 0x31 && scancode <= 0x39)
+ scancode-=0x10;
+
+ if(shift_pressed && scancode == 0x30) // '0' / '='
+ scancode = 0x3d;
+
+ if(shift_pressed && scancode == 0x2c) // ',' / ';'
+ scancode = 0x3b;
+
+ if(shift_pressed && scancode == 0x2f) // '/' / '?'
+ scancode = 0x3f;
+
+ if(shift_pressed && scancode == 0x2e) // '.' / ':'
+ scancode = 0x3a;
+
+ return scancode;
+ }
+ scancode++;
+ }
+ }
+
+ return 0;
+}
+
+UINT8 pc6001_state::check_joy_press()
+{
+ UINT8 p1_key = m_io_p1->read() ^ 0xff;
+ UINT8 shift_key = m_io_key_modifiers->read() & 0x02;
+ UINT8 space_key = m_io_key2->read() & 0x01;
+ UINT8 joy_press;
+
+ /*
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 )
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ */
+
+ joy_press = 0;
+
+ switch(p1_key & 0xf)
+ {
+ case 0x01: joy_press = 0x04; break; //up
+ case 0x02: joy_press = 0x08; break; //down
+ case 0x04: joy_press = 0x20; break;
+ case 0x05: joy_press = 0x24; break; //up-left
+ case 0x06: joy_press = 0x28; break; //down-left
+ case 0x08: joy_press = 0x10; break; //right
+ case 0x09: joy_press = 0x14; break; //up-right
+ case 0x0a: joy_press = 0x18; break; //down-right
+ }
+
+ if(p1_key & 0x10 || space_key) { joy_press |= 0x80; } //button 1 (space)
+ if(p1_key & 0x20 || shift_key) { joy_press |= 0x01; } //button 2 (shift)
+
+ return joy_press;
+}
+
+TIMER_DEVICE_CALLBACK_MEMBER(pc6001_state::cassette_callback)
+{
+ if(m_cas_switch == 1)
+ {
+ #if 0
+ static UINT8 cas_data_i = 0x80,cas_data_poll;
+ //m_cur_keycode = gfx_data[m_cas_offset++];
+ if(m_cassette->input() > 0.03)
+ cas_data_poll|= cas_data_i;
+ else
+ cas_data_poll&=~cas_data_i;
+ if(cas_data_i == 1)
+ {
+ m_cur_keycode = cas_data_poll;
+ cas_data_i = 0x80;
+ /* data ready, poll irq */
+ m_irq_vector = 0x08;
+ m_maincpu->set_input_line(0, ASSERT_LINE);
+ }
+ else
+ cas_data_i>>=1;
+ #else
+ address_space &space = m_maincpu->space(AS_PROGRAM);
+ m_cur_keycode = m_cas_hack->read_rom(space, m_cas_offset++);
+ popmessage("%04x %04x", m_cas_offset, m_cas_maxsize);
+ if(m_cas_offset > m_cas_maxsize)
+ {
+ m_cas_offset = 0;
+ m_cas_switch = 0;
+ if(IRQ_LOG) printf("Tape-E IRQ 0x12\n");
+ m_irq_vector = 0x12;
+ m_maincpu->set_input_line(0, ASSERT_LINE);
+ }
+ else
+ {
+ if(IRQ_LOG) printf("Tape-D IRQ 0x08\n");
+ m_irq_vector = 0x08;
+ m_maincpu->set_input_line(0, ASSERT_LINE);
+ }
+ #endif
+ }
+}
+
+TIMER_DEVICE_CALLBACK_MEMBER(pc6001_state::keyboard_callback)
+{
+ UINT32 key1 = m_io_key1->read();
+ UINT32 key2 = m_io_key2->read();
+ UINT32 key3 = m_io_key3->read();
+// UINT8 p1_key = m_io_p1->read();
+
+ if(m_cas_switch == 0)
+ {
+ if((key1 != m_old_key1) || (key2 != m_old_key2) || (key3 != m_old_key3))
+ {
+ m_cur_keycode = check_keyboard_press();
+ if(IRQ_LOG) printf("KEY IRQ 0x02\n");
+ m_irq_vector = 0x02;
+ m_maincpu->set_input_line(0, ASSERT_LINE);
+ m_old_key1 = key1;
+ m_old_key2 = key2;
+ m_old_key3 = key3;
+ }
+ #if 0
+ else /* joypad polling */
+ {
+ m_cur_keycode = check_joy_press();
+ if(m_cur_keycode)
+ {
+ m_irq_vector = 0x16;
+ m_maincpu->set_input_line(0, ASSERT_LINE);
+ }
+ }
+ #endif
+ }
+}
+
+void pc6001_state::machine_start()
+{
+ m_timer_hz_div = 3;
+ {
+ attotime period = attotime::from_hz((487.5*4)/(m_timer_hz_div+1));
+ m_timer_irq_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(pc6001_state::audio_callback),this));
+ m_timer_irq_timer->adjust(period, 0, period);
+ }
+}
+
+void pc6001_state::machine_reset()
+{
+ m_video_ram = m_region_maincpu->base() + 0xc000;
+
+ if (m_cart->exists())
+ m_maincpu->space(AS_PROGRAM).install_read_handler(0x4000, 0x5fff, read8_delegate(FUNC(generic_slot_device::read_rom),(generic_slot_device*)m_cart));
+
+ std::string region_tag;
+ m_cart_rom = memregion(region_tag.assign(m_cart->tag()).append(GENERIC_ROM_REGION_TAG).c_str());
+
+ m_port_c_8255=0;
+
+ m_cas_switch = 0;
+ m_cas_offset = 0;
+ m_cas_maxsize = (m_cas_hack->exists()) ? m_cas_hack->get_rom_size() : 0;
+ m_timer_irq_mask = 1;
+ m_timer_irq_mask2 = 1;
+ m_timer_irq_vector = 0x06; // actually vector is fixed in plain PC-6001
+ m_timer_hz_div = 3;
+}
+
+MACHINE_RESET_MEMBER(pc6001_state,pc6001m2)
+{
+ m_video_ram = m_region_maincpu->base() + 0xc000 + 0x28000;
+
+ std::string region_tag;
+ m_cart_rom = memregion(region_tag.assign(m_cart->tag()).append(GENERIC_ROM_REGION_TAG).c_str());
+ // hackish way to simplify bankswitch handling
+ if (m_cart_rom)
+ memcpy(m_region_maincpu->base() + 0x48000, m_cart_rom->base(), 0x4000);
+
+ m_port_c_8255=0;
+
+ m_cas_switch = 0;
+ m_cas_offset = 0;
+ m_cas_maxsize = (m_cas_hack->exists()) ? m_cas_hack->get_rom_size() : 0;
+
+ /* set default bankswitch */
+ {
+ UINT8 *ROM = m_region_maincpu->base();
+ m_bank_r0 = 0x71;
+ m_bank1->set_base(&ROM[BASICROM(0)]);
+ m_bank2->set_base(&ROM[BASICROM(1)]);
+ m_bank3->set_base(&ROM[EXROM(0)]);
+ m_bank4->set_base(&ROM[EXROM(1)]);
+ m_bank_r1 = 0xdd;
+ m_bank5->set_base(&ROM[WRAM(4)]);
+ m_bank6->set_base(&ROM[WRAM(5)]);
+ m_bank7->set_base(&ROM[WRAM(6)]);
+ m_bank8->set_base(&ROM[WRAM(7)]);
+ m_bank_opt = 0x02; //tv rom
+ m_bank_w = 0x50; //enable write to work ram 4,5,6,7
+ m_gfx_bank_on = 0;
+ }
+
+ m_timer_irq_mask = 1;
+ m_timer_irq_mask2 = 1;
+ m_timer_irq_vector = 0x06;
+}
+
+MACHINE_RESET_MEMBER(pc6001_state,pc6001sr)
+{
+ m_video_ram = m_region_maincpu->base() + 0x70000;
+
+ std::string region_tag;
+ m_cart_rom = memregion(region_tag.assign(m_cart->tag()).append(GENERIC_ROM_REGION_TAG).c_str());
+ // should this be mirrored into the EXROM regions? hard to tell without an actual cart dump...
+
+ m_port_c_8255=0;
+
+ m_cas_switch = 0;
+ m_cas_offset = 0;
+ m_cas_maxsize = (m_cas_hack->exists()) ? m_cas_hack->get_rom_size() : 0;
+
+ /* set default bankswitch */
+ {
+ UINT8 *ROM = m_region_maincpu->base();
+ m_sr_bank_r[0] = 0xf8; m_bank1->set_base(&ROM[SR_SYSROM_1(0x08)]);
+ m_sr_bank_r[1] = 0xfa; m_bank2->set_base(&ROM[SR_SYSROM_1(0x0a)]);
+ m_sr_bank_r[2] = 0xb0; m_bank3->set_base(&ROM[SR_EXROM1(0x00)]);
+ m_sr_bank_r[3] = 0xc0; m_bank4->set_base(&ROM[SR_EXROM0(0x00)]);
+ m_sr_bank_r[4] = 0x08; m_bank5->set_base(&ROM[SR_WRAM0(0x08)]);
+ m_sr_bank_r[5] = 0x0a; m_bank6->set_base(&ROM[SR_WRAM0(0x0a)]);
+ m_sr_bank_r[6] = 0x0c; m_bank7->set_base(&ROM[SR_WRAM0(0x0c)]);
+ m_sr_bank_r[7] = 0x0e; m_bank8->set_base(&ROM[SR_WRAM0(0x0e)]);
+// m_bank_opt = 0x02; //tv rom
+
+ /* enable default work RAM writes */
+ m_sr_bank_w[0] = 0x00;
+ m_sr_bank_w[1] = 0x02;
+ m_sr_bank_w[2] = 0x04;
+ m_sr_bank_w[3] = 0x06;
+ m_sr_bank_w[4] = 0x08;
+ m_sr_bank_w[5] = 0x0a;
+ m_sr_bank_w[6] = 0x0c;
+ m_sr_bank_w[7] = 0x0e;
+
+ m_gfx_bank_on = 0;
+ }
+
+ m_timer_irq_mask = 1;
+ m_timer_irq_mask2 = 1;
+ m_timer_irq_vector = 0x06;
+}
+
+static const rgb_t defcolors[] =
+{
+ rgb_t(0x07, 0xff, 0x00), /* GREEN */
+ rgb_t(0xff, 0xff, 0x00), /* YELLOW */
+ rgb_t(0x3b, 0x08, 0xff), /* BLUE */
+ rgb_t(0xcc, 0x00, 0x3b), /* RED */
+ rgb_t(0xff, 0xff, 0xff), /* BUFF */
+ rgb_t(0x07, 0xe3, 0x99), /* CYAN */
+ rgb_t(0xff, 0x1c, 0xff), /* MAGENTA */
+ rgb_t(0xff, 0x81, 0x00), /* ORANGE */
+
+ /* MC6847 specific */
+ rgb_t(0x00, 0x7c, 0x00), /* ALPHANUMERIC DARK GREEN */
+ rgb_t(0x07, 0xff, 0x00), /* ALPHANUMERIC BRIGHT GREEN */
+ rgb_t(0x91, 0x00, 0x00), /* ALPHANUMERIC DARK ORANGE */
+ rgb_t(0xff, 0x81, 0x00) /* ALPHANUMERIC BRIGHT ORANGE */
+};
+
+static const rgb_t mk2_defcolors[] =
+{
+ rgb_t(0x00, 0x00, 0x00), /* BLACK */
+ rgb_t(0xff, 0xaf, 0x00), /* ORANGE */
+ rgb_t(0x00, 0xff, 0xaf), /* tone of GREEN */
+ rgb_t(0xaf, 0xff, 0x00), /* tone of GREEN */
+ rgb_t(0xaf, 0x00, 0xff), /* VIOLET */
+ rgb_t(0xff, 0x00, 0xaf), /* SCARLET */
+ rgb_t(0x00, 0xaf, 0xff), /* LIGHT BLUE */
+ rgb_t(0xaf, 0xaf, 0xaf), /* GRAY */
+ rgb_t(0x00, 0x00, 0x00), /* BLACK */
+ rgb_t(0xff, 0x00, 0x00), /* RED */
+ rgb_t(0x00, 0xff, 0x00), /* GREEN */
+ rgb_t(0xff, 0xff, 0x00), /* YELLOW */
+ rgb_t(0x00, 0x00, 0xff), /* BLUE */
+ rgb_t(0xff, 0x00, 0xff), /* PINK */
+ rgb_t(0x00, 0xff, 0xff), /* CYAN */
+ rgb_t(0xff, 0xff, 0xff) /* WHITE */
+};
+
+PALETTE_INIT_MEMBER(pc6001_state, pc6001)
+{
+ int i;
+
+ for(i=0;i<8+4;i++)
+ palette.set_pen_color(i+8,defcolors[i]);
+}
+
+PALETTE_INIT_MEMBER(pc6001_state,pc6001m2)
+{
+ int i;
+
+ for(i=0;i<8;i++)
+ palette.set_pen_color(i+8,defcolors[i]);
+
+ for(i=0x10;i<0x20;i++)
+ palette.set_pen_color(i,mk2_defcolors[i-0x10]);
+}
+
+#if 0
+static const cassette_interface pc6001_cassette_interface =
+{
+ pc6001_cassette_formats,
+ NULL,
+ (cassette_state)(CASSETTE_STOPPED | CASSETTE_MOTOR_DISABLED | CASSETTE_SPEAKER_ENABLED),
+ NULL
+};
+#endif
+
+static const gfx_layout char_layout =
+{
+ 8, 16,
+ RGN_FRAC(1,1),
+ 1,
+ { 0 },
+ { 0, 1, 2, 3, 4, 5, 6, 7 },
+ { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8,8*8, 9*8, 10*8, 11*8, 12*8, 13*8, 14*8, 15*8 },
+ 8*16
+};
+
+
+static const gfx_layout kanji_layout =
+{
+ 16, 16,
+ RGN_FRAC(1,2),
+ 1,
+ { 0 },
+ { 0, 1, 2, 3, 4, 5, 6, 7,
+ 0+RGN_FRAC(1,2), 1+RGN_FRAC(1,2), 2+RGN_FRAC(1,2), 3+RGN_FRAC(1,2), 4+RGN_FRAC(1,2), 5+RGN_FRAC(1,2), 6+RGN_FRAC(1,2), 7+RGN_FRAC(1,2) },
+ { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8,8*8, 9*8, 10*8, 11*8, 12*8, 13*8, 14*8, 15*8 },
+ 8*16
+};
+
+static GFXDECODE_START( pc6001m2 )
+ GFXDECODE_ENTRY( "gfx1", 0x0000, char_layout, 2, 1 )
+ GFXDECODE_ENTRY( "gfx2", 0x0000, kanji_layout, 2, 1 )
+GFXDECODE_END
+
+#define PC6001_MAIN_CLOCK 7987200
+
+static MACHINE_CONFIG_START( pc6001, pc6001_state )
+ /* basic machine hardware */
+ MCFG_CPU_ADD("maincpu",Z80, PC6001_MAIN_CLOCK / 2) // ~4 Mhz
+ MCFG_CPU_PROGRAM_MAP(pc6001_map)
+ MCFG_CPU_IO_MAP(pc6001_io)
+ MCFG_CPU_VBLANK_INT_DRIVER("screen", pc6001_state, pc6001_interrupt)
+ MCFG_CPU_IRQ_ACKNOWLEDGE_DRIVER(pc6001_state,pc6001_irq_callback)
+
+// MCFG_CPU_ADD("subcpu", I8049, 7987200)
+
+
+ MCFG_GFXDECODE_ADD("gfxdecode", "palette", pc6001m2)
+
+ /* video hardware */
+ MCFG_SCREEN_ADD("screen", RASTER)
+ MCFG_SCREEN_REFRESH_RATE(60)
+ MCFG_SCREEN_UPDATE_DRIVER(pc6001_state, screen_update_pc6001)
+ MCFG_SCREEN_SIZE(320, 25+192+26)
+ MCFG_SCREEN_VISIBLE_AREA(0, 319, 0, 239)
+ MCFG_SCREEN_PALETTE("palette")
+
+ MCFG_PALETTE_ADD("palette", 16+4)
+ MCFG_PALETTE_INIT_OWNER(pc6001_state, pc6001)
+
+ MCFG_DEVICE_ADD("ppi8255", I8255, 0)
+ MCFG_I8255_IN_PORTA_CB(READ8(pc6001_state, pc6001_8255_porta_r))
+ MCFG_I8255_OUT_PORTA_CB(WRITE8(pc6001_state, pc6001_8255_porta_w))
+ MCFG_I8255_IN_PORTB_CB(READ8(pc6001_state, pc6001_8255_portb_r))
+ MCFG_I8255_OUT_PORTB_CB(WRITE8(pc6001_state, pc6001_8255_portb_w))
+ MCFG_I8255_IN_PORTC_CB(READ8(pc6001_state, pc6001_8255_portc_r))
+ MCFG_I8255_OUT_PORTC_CB(WRITE8(pc6001_state, pc6001_8255_portc_w))
+
+ /* uart */
+ MCFG_DEVICE_ADD("uart", I8251, 0)
+
+ MCFG_GENERIC_CARTSLOT_ADD("cartslot", generic_plain_slot, "pc6001_cart")
+
+// MCFG_CASSETTE_ADD("cassette", pc6001_cassette_interface)
+ MCFG_GENERIC_CARTSLOT_ADD("cas_hack", generic_plain_slot, "pc6001_cass")
+ MCFG_GENERIC_EXTENSIONS("cas,p6")
+
+ MCFG_SPEAKER_STANDARD_MONO("mono")
+ MCFG_SOUND_ADD("ay8910", AY8910, PC6001_MAIN_CLOCK/4)
+ MCFG_AY8910_PORT_A_READ_CB(IOPORT("P1"))
+ MCFG_AY8910_PORT_B_READ_CB(IOPORT("P2"))
+ MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00)
+// MCFG_SOUND_WAVE_ADD(WAVE_TAG, "cassette")
+// MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25)
+
+ /* TODO: accurate timing on this */
+ MCFG_TIMER_DRIVER_ADD_PERIODIC("keyboard_timer", pc6001_state, keyboard_callback, attotime::from_hz(250))
+ MCFG_TIMER_DRIVER_ADD_PERIODIC("cassette_timer", pc6001_state, cassette_callback, attotime::from_hz(1200/12))
+MACHINE_CONFIG_END
+
+
+
+static MACHINE_CONFIG_DERIVED( pc6001m2, pc6001 )
+
+ MCFG_MACHINE_RESET_OVERRIDE(pc6001_state,pc6001m2)
+
+ MCFG_SCREEN_MODIFY("screen")
+ MCFG_SCREEN_UPDATE_DRIVER(pc6001_state, screen_update_pc6001m2)
+
+ MCFG_PALETTE_MODIFY("palette")
+ MCFG_PALETTE_ENTRIES(16+16)
+ MCFG_PALETTE_INIT_OWNER(pc6001_state,pc6001m2)
+
+ /* basic machine hardware */
+ MCFG_CPU_MODIFY("maincpu")
+ MCFG_CPU_PROGRAM_MAP(pc6001m2_map)
+ MCFG_CPU_IO_MAP(pc6001m2_io)
+
+ MCFG_GFXDECODE_MODIFY("gfxdecode", pc6001m2)
+
+ MCFG_SOUND_ADD("upd7752", UPD7752, PC6001_MAIN_CLOCK/4)
+ MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00)
+
+MACHINE_CONFIG_END
+
+static MACHINE_CONFIG_DERIVED( pc6601, pc6001m2 )
+
+ /* basic machine hardware */
+ MCFG_CPU_REPLACE("maincpu", Z80, PC6001_MAIN_CLOCK / 2)
+ MCFG_CPU_PROGRAM_MAP(pc6001m2_map)
+ MCFG_CPU_IO_MAP(pc6601_io)
+ MCFG_CPU_VBLANK_INT_DRIVER("screen", pc6001_state, pc6001_interrupt)
+ MCFG_CPU_IRQ_ACKNOWLEDGE_DRIVER(pc6001_state,pc6001_irq_callback)
+MACHINE_CONFIG_END
+
+static MACHINE_CONFIG_DERIVED( pc6001sr, pc6001m2 )
+
+ MCFG_MACHINE_RESET_OVERRIDE(pc6001_state,pc6001sr)
+
+ MCFG_SCREEN_MODIFY("screen")
+ MCFG_SCREEN_UPDATE_DRIVER(pc6001_state, screen_update_pc6001sr)
+
+ /* basic machine hardware */
+ MCFG_CPU_REPLACE("maincpu", Z80, XTAL_3_579545MHz) //*Yes*, PC-6001 SR Z80 CPU is actually slower than older models
+ MCFG_CPU_PROGRAM_MAP(pc6001sr_map)
+ MCFG_CPU_IO_MAP(pc6001sr_io)
+ MCFG_CPU_VBLANK_INT_DRIVER("screen", pc6001_state, pc6001sr_interrupt)
+ MCFG_CPU_IRQ_ACKNOWLEDGE_DRIVER(pc6001_state,pc6001_irq_callback)
+MACHINE_CONFIG_END
+
+/* ROM definition */
+ROM_START( pc6001 )
+ ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASEFF )
+ ROM_LOAD( "basicrom.60", 0x0000, 0x4000, CRC(54c03109) SHA1(c622fefda3cdc2b87a270138f24c05828b5c41d2) )
+
+ ROM_REGION( 0x1000, "mcu", ROMREGION_ERASEFF )
+ ROM_LOAD( "i8049", 0x0000, 0x1000, NO_DUMP )
+
+ ROM_REGION( 0x2000, "gfx1", 0 )
+ ROM_LOAD( "cgrom60.60", 0x0000, 0x1000, CRC(b0142d32) SHA1(9570495b10af5b1785802681be94b0ea216a1e26) )
+ ROM_RELOAD( 0x1000, 0x1000 )
+
+ ROM_REGION( 0x8000, "gfx2", ROMREGION_ERASEFF )
+ROM_END
+
+ROM_START( pc6001a )
+ ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASEFF )
+ ROM_LOAD( "basicrom.60a", 0x0000, 0x4000, CRC(fa8e88d9) SHA1(c82e30050a837e5c8ffec3e0c8e3702447ffd69c) )
+
+ ROM_REGION( 0x1000, "mcu", ROMREGION_ERASEFF )
+ ROM_LOAD( "i8049", 0x0000, 0x1000, NO_DUMP )
+
+ ROM_REGION( 0x1000, "gfx1", 0 )
+ ROM_LOAD( "cgrom60.60a", 0x0000, 0x1000, CRC(49c21d08) SHA1(9454d6e2066abcbd051bad9a29a5ca27b12ec897) )
+
+ ROM_REGION( 0x8000, "gfx2", ROMREGION_ERASEFF )
+ROM_END
+
+ROM_START( pc6001mk2 )
+ ROM_REGION( 0x50000, "maincpu", ROMREGION_ERASEFF )
+ ROM_LOAD( "basicrom.62", 0x10000, 0x8000, CRC(950ac401) SHA1(fbf195ba74a3b0f80b5a756befc96c61c2094182) )
+ ROM_LOAD( "voicerom.62", 0x18000, 0x4000, CRC(49b4f917) SHA1(1a2d18f52ef19dc93da3d65f19d3abbd585628af) )
+ ROM_LOAD( "cgrom60.62", 0x1c000, 0x2000, CRC(81eb5d95) SHA1(53d8ae9599306ff23bf95208d2f6cc8fed3fc39f) )
+ ROM_LOAD( "cgrom60m.62", 0x1e000, 0x2000, CRC(3ce48c33) SHA1(f3b6c63e83a17d80dde63c6e4d86adbc26f84f79) )
+ ROM_LOAD( "kanjirom.62", 0x20000, 0x8000, CRC(20c8f3eb) SHA1(4c9f30f0a2ebbe70aa8e697f94eac74d8241cadd) )
+ // work ram 0x28000,0x10000
+ // extended work ram 0x38000,0x10000
+ // exrom 0x48000, 0x4000
+ // <invalid> 0x4c000, 0x4000
+
+ ROM_REGION( 0x1000, "mcu", ROMREGION_ERASEFF )
+ ROM_LOAD( "i8049", 0x0000, 0x1000, NO_DUMP )
+
+ ROM_REGION( 0x4000, "gfx1", 0 )
+ ROM_COPY( "maincpu", 0x1c000, 0x00000, 0x4000 )
+
+ ROM_REGION( 0x8000, "gfx2", 0 )
+ ROM_COPY( "maincpu", 0x20000, 0x00000, 0x8000 )
+ROM_END
+
+ROM_START( pc6601 ) /* Variant of pc6001m2 */
+ ROM_REGION( 0x50000, "maincpu", ROMREGION_ERASEFF )
+ ROM_LOAD( "basicrom.66", 0x10000, 0x8000, CRC(c0b01772) SHA1(9240bb6b97fe06f5f07b5d65541c4d2f8758cc2a) )
+ ROM_LOAD( "voicerom.66", 0x18000, 0x4000, CRC(91d078c1) SHA1(6a93bd7723ef67f461394530a9feee57c8caf7b7) )
+ ROM_LOAD( "cgrom60.66", 0x1c000, 0x2000, CRC(d2434f29) SHA1(a56d76f5cbdbcdb8759abe601eab68f01b0a8fe8) )
+ ROM_LOAD( "cgrom66.66", 0x1e000, 0x2000, CRC(3ce48c33) SHA1(f3b6c63e83a17d80dde63c6e4d86adbc26f84f79) )
+ ROM_LOAD( "kanjirom.66", 0x20000, 0x8000, CRC(20c8f3eb) SHA1(4c9f30f0a2ebbe70aa8e697f94eac74d8241cadd) )
+ // exrom 0x48000, 0x4000
+
+ ROM_REGION( 0x1000, "mcu", ROMREGION_ERASEFF )
+ ROM_LOAD( "i8049", 0x0000, 0x1000, NO_DUMP )
+
+ ROM_REGION( 0x4000, "gfx1", 0 )
+ ROM_COPY( "maincpu", 0x1c000, 0x00000, 0x4000 )
+
+ ROM_REGION( 0x8000, "gfx2", 0 )
+ ROM_COPY( "maincpu", 0x20000, 0x00000, 0x8000 )
+ROM_END
+
+ROM_START( pc6001sr )
+ ROM_REGION( 0x90000, "maincpu", ROMREGION_ERASEFF )
+ ROM_LOAD( "systemrom1.64", 0x10000, 0x10000, CRC(b6fc2db2) SHA1(dd48b1eee60aa34780f153359f5da7f590f8dff4) )
+ ROM_LOAD( "systemrom2.64", 0x20000, 0x10000, CRC(55a62a1d) SHA1(3a19855d290fd4ac04e6066fe4a80ecd81dc8dd7) )
+// cgrom 1 0x30000, 0x10000
+// exrom 0 0x40000, 0x10000
+// exrom 1 0x50000, 0x10000
+// exram 0 0x60000, 0x10000
+// work ram 0 0x70000, 0x10000
+// <invalid> 0x80000, 0x10000
+
+ ROM_REGION( 0x1000, "mcu", ROMREGION_ERASEFF )
+ ROM_LOAD( "i8049", 0x0000, 0x1000, NO_DUMP )
+
+ ROM_REGION( 0x4000, "gfx1", 0 )
+ ROM_LOAD( "cgrom68.64", 0x0000, 0x4000, CRC(73bc3256) SHA1(5f80d62a95331dc39b2fb448a380fd10083947eb) )
+
+ ROM_REGION( 0x8000, "gfx2", 0 )
+ ROM_COPY( "maincpu", 0x28000, 0x00000, 0x8000 )
+ROM_END
+
+/* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS */
+COMP( 1981, pc6001, 0, 0, pc6001, pc6001, driver_device, 0, "Nippon Electronic Company", "PC-6001 (Japan)", MACHINE_NOT_WORKING )
+COMP( 1981, pc6001a, pc6001, 0, pc6001, pc6001, driver_device, 0, "Nippon Electronic Company", "PC-6001A (US)", MACHINE_NOT_WORKING ) // This version is also known as the NEC Trek
+COMP( 1983, pc6001mk2,pc6001, 0, pc6001m2, pc6001, driver_device, 0, "Nippon Electronic Company", "PC-6001mkII (Japan)", MACHINE_NOT_WORKING )
+COMP( 1983, pc6601, pc6001, 0, pc6601, pc6001, driver_device, 0, "Nippon Electronic Company", "PC-6601 (Japan)", MACHINE_NOT_WORKING )
+COMP( 1984, pc6001sr, pc6001, 0, pc6001sr, pc6001, driver_device, 0, "Nippon Electronic Company", "PC-6001mkIISR (Japan)", MACHINE_NOT_WORKING )