summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/devices/bus/coco/coco_t4426.cpp117
-rw-r--r--src/devices/bus/coco/coco_t4426.h3
-rw-r--r--src/devices/bus/vme/vme.cpp193
-rw-r--r--src/devices/bus/vme/vme.h287
-rw-r--r--src/devices/bus/vme/vme_fcisio.cpp409
-rw-r--r--src/devices/bus/vme/vme_fcisio.h49
-rw-r--r--src/devices/bus/vme/vme_fcscsi.cpp539
-rw-r--r--src/devices/bus/vme/vme_fcscsi.h73
-rw-r--r--src/devices/bus/vme/vme_mvme350.c257
-rw-r--r--src/devices/bus/vme/vme_mvme350.cpp (renamed from src/mame/drivers/mvme350.cpp)217
-rw-r--r--src/devices/bus/vme/vme_mvme350.h32
-rw-r--r--src/devices/bus/vme/vme_mzr8105.cpp (renamed from src/mame/bus/vme/mzr8105.cpp)6
-rw-r--r--src/devices/bus/vme/vme_mzr8105.h (renamed from src/mame/bus/vme/mzr8105.h)4
-rw-r--r--src/devices/bus/vme/vme_mzr8300.cpp (renamed from src/mame/machine/mzr8300.cpp)73
-rw-r--r--src/devices/bus/vme/vme_mzr8300.h (renamed from src/mame/bus/vme/mzr8300.h)11
-rw-r--r--src/devices/cpu/amis2000/amis2000.h34
-rw-r--r--src/devices/cpu/e0c6200/e0c6200.h8
-rw-r--r--src/devices/cpu/e0c6200/e0c6s46.cpp2
-rw-r--r--src/devices/cpu/hmcs40/hmcs40.h10
-rw-r--r--src/devices/cpu/i386/i386ops.hxx5
-rw-r--r--src/devices/cpu/m6805/m6805.cpp254
-rw-r--r--src/devices/cpu/m6805/m6805.h91
-rw-r--r--src/devices/cpu/melps4/melps4.h62
-rw-r--r--src/devices/cpu/tms1000/tms0270.h2
-rw-r--r--src/devices/cpu/tms1000/tms0970.cpp2
-rw-r--r--src/devices/cpu/tms1000/tms0980.cpp2
-rw-r--r--src/devices/cpu/tms1000/tms1000.cpp2
-rw-r--r--src/devices/cpu/tms1000/tms1k_base.h6
-rw-r--r--src/devices/cpu/tms1000/tp0320.cpp2
-rw-r--r--src/devices/cpu/ucom4/ucom4.h8
-rw-r--r--src/devices/machine/6821pia.cpp71
-rw-r--r--src/devices/machine/gen_latch.cpp114
-rw-r--r--src/devices/machine/gen_latch.h56
-rw-r--r--src/devices/machine/hd63450.h4
-rw-r--r--src/devices/machine/mc68681.cpp157
-rw-r--r--src/devices/machine/mc68681.h94
-rw-r--r--src/devices/machine/netlist.cpp48
-rw-r--r--src/devices/machine/netlist.h2
-rw-r--r--src/devices/machine/tms6100.h6
-rw-r--r--src/devices/video/tms9927.cpp7
-rw-r--r--src/devices/video/zeus2.cpp379
-rw-r--r--src/devices/video/zeus2.h10
-rw-r--r--src/emu/emuopts.cpp6
-rw-r--r--src/emu/emuopts.h9
-rw-r--r--src/emu/ioport.cpp27
-rw-r--r--src/emu/ioport.h2
-rw-r--r--src/emu/machine.cpp32
-rw-r--r--src/emu/machine.h1
-rw-r--r--src/emu/main.cpp208
-rw-r--r--src/emu/main.h22
-rw-r--r--src/emu/natkeyboard.cpp25
-rw-r--r--src/frontend/mame/clifront.cpp6
-rw-r--r--src/frontend/mame/info.cpp2
-rw-r--r--src/frontend/mame/ui/info.cpp3
-rw-r--r--src/frontend/mame/ui/info.h2
-rw-r--r--src/frontend/mame/ui/ui.cpp10
-rw-r--r--src/lib/formats/pc_dsk.cpp12
-rw-r--r--src/lib/formats/pc_dsk.h2
-rw-r--r--src/lib/formats/upd765_dsk.cpp6
-rw-r--r--src/lib/formats/upd765_dsk.h2
-rw-r--r--src/lib/netlist/analog/nld_bjt.h2
-rw-r--r--src/lib/netlist/analog/nld_fourterm.h2
-rw-r--r--src/lib/netlist/analog/nld_opamps.cpp29
-rw-r--r--src/lib/netlist/analog/nld_opamps.h5
-rw-r--r--src/lib/netlist/analog/nld_twoterm.cpp63
-rw-r--r--src/lib/netlist/analog/nld_twoterm.h63
-rw-r--r--src/lib/netlist/build/makefile5
-rw-r--r--src/lib/netlist/devices/net_lib.cpp199
-rw-r--r--src/lib/netlist/devices/net_lib.h2
-rw-r--r--src/lib/netlist/devices/nld_7448.cpp2
-rw-r--r--src/lib/netlist/devices/nld_7485.cpp2
-rw-r--r--src/lib/netlist/devices/nld_7493.cpp12
-rw-r--r--src/lib/netlist/devices/nld_dm9334.cpp2
-rw-r--r--src/lib/netlist/devices/nld_mm5837.cpp31
-rw-r--r--src/lib/netlist/devices/nld_truthtable.h10
-rw-r--r--src/lib/netlist/devices/nlid_proxy.cpp76
-rw-r--r--src/lib/netlist/devices/nlid_proxy.h105
-rw-r--r--src/lib/netlist/macro/nlm_cd4xxx.cpp4
-rw-r--r--src/lib/netlist/macro/nlm_opamp.cpp34
-rw-r--r--src/lib/netlist/macro/nlm_opamp.h3
-rw-r--r--src/lib/netlist/macro/nlm_ttl74xx.cpp28
-rw-r--r--src/lib/netlist/nl_base.cpp80
-rw-r--r--src/lib/netlist/nl_base.h219
-rw-r--r--src/lib/netlist/nl_config.h10
-rw-r--r--src/lib/netlist/nl_factory.cpp56
-rw-r--r--src/lib/netlist/nl_factory.h85
-rw-r--r--src/lib/netlist/nl_parser.cpp59
-rw-r--r--src/lib/netlist/nl_setup.cpp143
-rw-r--r--src/lib/netlist/nl_setup.h31
-rw-r--r--src/lib/netlist/plib/palloc.cpp38
-rw-r--r--src/lib/netlist/plib/palloc.h54
-rw-r--r--src/lib/netlist/plib/pdynlib.cpp28
-rw-r--r--src/lib/netlist/plib/pexception.cpp143
-rw-r--r--src/lib/netlist/plib/pexception.h126
-rw-r--r--src/lib/netlist/plib/pfmtlog.cpp7
-rw-r--r--src/lib/netlist/plib/pfmtlog.h4
-rw-r--r--src/lib/netlist/plib/poptions.cpp12
-rw-r--r--src/lib/netlist/plib/poptions.h3
-rw-r--r--src/lib/netlist/plib/pparser.cpp10
-rw-r--r--src/lib/netlist/plib/pparser.h6
-rw-r--r--src/lib/netlist/plib/pstate.cpp5
-rw-r--r--src/lib/netlist/plib/pstate.h2
-rw-r--r--src/lib/netlist/plib/pstream.cpp43
-rw-r--r--src/lib/netlist/plib/pstream.h22
-rw-r--r--src/lib/netlist/plib/pstring.cpp22
-rw-r--r--src/lib/netlist/plib/pstring.h6
-rw-r--r--src/lib/netlist/plib/ptypes.h2
-rw-r--r--src/lib/netlist/plib/putil.cpp8
-rw-r--r--src/lib/netlist/plib/putil.h5
-rw-r--r--src/lib/netlist/prg/nltool.cpp87
-rw-r--r--src/lib/netlist/prg/nlwav.cpp4
-rw-r--r--src/lib/netlist/solver/nld_matrix_solver.cpp562
-rw-r--r--src/lib/netlist/solver/nld_matrix_solver.h36
-rw-r--r--src/lib/netlist/solver/nld_ms_w.h4
-rw-r--r--src/lib/netlist/solver/nld_solver.cpp498
-rw-r--r--src/lib/netlist/tools/nl_convert.cpp128
-rw-r--r--src/lib/netlist/tools/nl_convert.h73
-rw-r--r--src/lib/util/base64.hpp167
-rw-r--r--src/lib/util/client_http.hpp438
-rw-r--r--src/lib/util/client_https.hpp152
-rw-r--r--src/lib/util/client_ws.hpp517
-rw-r--r--src/lib/util/client_wss.hpp82
-rw-r--r--src/lib/util/crypto.hpp18
-rw-r--r--src/lib/util/path_to_regex.cpp217
-rw-r--r--src/lib/util/path_to_regex.hpp110
-rw-r--r--src/lib/util/server_http.hpp497
-rw-r--r--src/lib/util/server_https.hpp99
-rw-r--r--src/lib/util/server_ws.hpp714
-rw-r--r--src/lib/util/server_wss.hpp82
-rw-r--r--src/lib/util/sha1.hpp181
-rw-r--r--src/lib/util/unicode.cpp125
-rw-r--r--src/lib/util/unicode.h12
-rw-r--r--src/mame/arcade.flt1
-rw-r--r--src/mame/audio/efo_zsu.cpp275
-rw-r--r--src/mame/audio/efo_zsu.h (renamed from src/mame/machine/cedar_magnet_sound.h)45
-rw-r--r--src/mame/audio/mario.cpp249
-rw-r--r--src/mame/audio/nl_mario.cpp306
-rw-r--r--src/mame/audio/nl_mario.h4
-rw-r--r--src/mame/bus/vme/mzr8300.cpp92
-rw-r--r--src/mame/drivers/40love.cpp16
-rw-r--r--src/mame/drivers/aa310.cpp24
-rw-r--r--src/mame/drivers/aerofgt.cpp74
-rw-r--r--src/mame/drivers/aleisttl.cpp2
-rw-r--r--src/mame/drivers/alpha68k.cpp4
-rw-r--r--src/mame/drivers/arkanoid.cpp48
-rw-r--r--src/mame/drivers/armedf.cpp2
-rw-r--r--src/mame/drivers/ashnojoe.cpp23
-rw-r--r--src/mame/drivers/asuka.cpp27
-rw-r--r--src/mame/drivers/attache.cpp33
-rw-r--r--src/mame/drivers/atvtrack.cpp63
-rw-r--r--src/mame/drivers/bigevglf.cpp52
-rw-r--r--src/mame/drivers/bking.cpp74
-rw-r--r--src/mame/drivers/bublbobl.cpp64
-rw-r--r--src/mame/drivers/buggychl.cpp15
-rw-r--r--src/mame/drivers/cdi.cpp181
-rw-r--r--src/mame/drivers/cedar_magnet.cpp38
-rw-r--r--src/mame/drivers/crospang.cpp10
-rw-r--r--src/mame/drivers/crshrace.cpp14
-rw-r--r--src/mame/drivers/cvs.cpp2
-rw-r--r--src/mame/drivers/dcheese.cpp29
-rw-r--r--src/mame/drivers/ddenlovr.cpp376
-rw-r--r--src/mame/drivers/dec0.cpp26
-rw-r--r--src/mame/drivers/discoboy.cpp12
-rw-r--r--src/mame/drivers/esd16.cpp3
-rw-r--r--src/mame/drivers/expro02.cpp36
-rw-r--r--src/mame/drivers/f1gp.cpp18
-rw-r--r--src/mame/drivers/fccpu30.cpp112
-rw-r--r--src/mame/drivers/fcisio.cpp309
-rw-r--r--src/mame/drivers/fcscsi.cpp435
-rw-r--r--src/mame/drivers/feversoc.cpp75
-rw-r--r--src/mame/drivers/flstory.cpp60
-rw-r--r--src/mame/drivers/fuukifg2.cpp13
-rw-r--r--src/mame/drivers/gaelco.cpp49
-rw-r--r--src/mame/drivers/gkigt.cpp12
-rw-r--r--src/mame/drivers/gsword.cpp459
-rw-r--r--src/mame/drivers/hapyfish.cpp85
-rw-r--r--src/mame/drivers/harddriv.cpp7
-rw-r--r--src/mame/drivers/hh_cop400.cpp12
-rw-r--r--src/mame/drivers/hh_hmcs40.cpp6
-rw-r--r--src/mame/drivers/hh_melps4.cpp6
-rw-r--r--src/mame/drivers/hh_pic16.cpp6
-rw-r--r--src/mame/drivers/hh_sm510.cpp2
-rw-r--r--src/mame/drivers/hh_tms1k.cpp129
-rw-r--r--src/mame/drivers/lkage.cpp80
-rw-r--r--src/mame/drivers/lsasquad.cpp48
-rw-r--r--src/mame/drivers/mvme147.cpp239
-rw-r--r--src/mame/drivers/mzr8105.cpp185
-rw-r--r--src/mame/drivers/namcos2.cpp142
-rw-r--r--src/mame/drivers/namcos21.cpp105
-rw-r--r--src/mame/drivers/neodriv.hxx54
-rw-r--r--src/mame/drivers/novag6502.cpp6
-rw-r--r--src/mame/drivers/nycaptor.cpp51
-rw-r--r--src/mame/drivers/osbexec.cpp38
-rw-r--r--src/mame/drivers/pc.cpp573
-rw-r--r--src/mame/drivers/peyper.cpp16
-rw-r--r--src/mame/drivers/play_3.cpp126
-rw-r--r--src/mame/drivers/rm380z.cpp53
-rw-r--r--src/mame/drivers/rohga.cpp309
-rw-r--r--src/mame/drivers/slapfght.cpp70
-rw-r--r--src/mame/drivers/stv.cpp34
-rw-r--r--src/mame/drivers/vd.cpp143
-rw-r--r--src/mame/drivers/x1.cpp88
-rw-r--r--src/mame/includes/40love.h6
-rw-r--r--src/mame/includes/aerofgt.h15
-rw-r--r--src/mame/includes/apollo.h11
-rw-r--r--src/mame/includes/arkanoid.h34
-rw-r--r--src/mame/includes/ashnojoe.h3
-rw-r--r--src/mame/includes/asuka.h19
-rw-r--r--src/mame/includes/bigevglf.h17
-rw-r--r--src/mame/includes/bking.h15
-rw-r--r--src/mame/includes/bublbobl.h32
-rw-r--r--src/mame/includes/buggychl.h6
-rw-r--r--src/mame/includes/cdi.h17
-rw-r--r--src/mame/includes/crospang.h1
-rw-r--r--src/mame/includes/crshrace.h2
-rw-r--r--src/mame/includes/dcheese.h3
-rw-r--r--src/mame/includes/dec0.h2
-rw-r--r--src/mame/includes/f1gp.h4
-rw-r--r--src/mame/includes/fidelz80.h6
-rw-r--r--src/mame/includes/flstory.h33
-rw-r--r--src/mame/includes/fuukifg2.h2
-rw-r--r--src/mame/includes/gaelco.h6
-rw-r--r--src/mame/includes/gsword.h128
-rw-r--r--src/mame/includes/harddriv.h9
-rw-r--r--src/mame/includes/hh_tms1k.h6
-rw-r--r--src/mame/includes/hh_ucom4.h6
-rw-r--r--src/mame/includes/lkage.h34
-rw-r--r--src/mame/includes/lsasquad.h25
-rw-r--r--src/mame/includes/mario.h4
-rw-r--r--src/mame/includes/msisaac.h4
-rw-r--r--src/mame/includes/mzr8105.h30
-rw-r--r--src/mame/includes/mzr8300.h35
-rw-r--r--src/mame/includes/namcofl.h2
-rw-r--r--src/mame/includes/namconb1.h2
-rw-r--r--src/mame/includes/namcos1.h2
-rw-r--r--src/mame/includes/namcos2.h44
-rw-r--r--src/mame/includes/namcos21.h14
-rw-r--r--src/mame/includes/nycaptor.h32
-rw-r--r--src/mame/includes/rm380z.h14
-rw-r--r--src/mame/includes/rohga.h1
-rw-r--r--src/mame/includes/slapfght.h30
-rw-r--r--src/mame/includes/taito_f3.h1
-rw-r--r--src/mame/includes/xbox.h1
-rw-r--r--src/mame/includes/xbox_nv2a.h33
-rw-r--r--src/mame/layout/cmsport.lay65
-rw-r--r--src/mame/layout/racedrivpan.lay18
-rw-r--r--src/mame/machine/alpha8201.h6
-rw-r--r--src/mame/machine/arkanoid.cpp143
-rw-r--r--src/mame/machine/bigevglf.cpp80
-rw-r--r--src/mame/machine/bublbobl.cpp93
-rw-r--r--src/mame/machine/buggychl.cpp234
-rw-r--r--src/mame/machine/buggychl.h48
-rw-r--r--src/mame/machine/cedar_magnet_board.cpp65
-rw-r--r--src/mame/machine/cedar_magnet_board.h45
-rw-r--r--src/mame/machine/cedar_magnet_plane.cpp6
-rw-r--r--src/mame/machine/cedar_magnet_plane.h5
-rw-r--r--src/mame/machine/cedar_magnet_sound.cpp208
-rw-r--r--src/mame/machine/cedar_magnet_sprite.cpp8
-rw-r--r--src/mame/machine/cedar_magnet_sprite.h2
-rw-r--r--src/mame/machine/flstory.cpp125
-rw-r--r--src/mame/machine/harddriv.cpp51
-rw-r--r--src/mame/machine/lkage.cpp141
-rw-r--r--src/mame/machine/lsasquad.cpp107
-rw-r--r--src/mame/machine/mzr8105.cpp192
-rw-r--r--src/mame/machine/namco_c139.cpp107
-rw-r--r--src/mame/machine/namco_c139.h67
-rw-r--r--src/mame/machine/namco_c148.cpp250
-rw-r--r--src/mame/machine/namco_c148.h143
-rw-r--r--src/mame/machine/namcos2.cpp325
-rw-r--r--src/mame/machine/nl_stuntcyc.cpp19
-rw-r--r--src/mame/machine/nycaptor.cpp94
-rw-r--r--src/mame/machine/rm380z.cpp36
-rw-r--r--src/mame/machine/slapfght.cpp131
-rw-r--r--src/mame/machine/tait8741.cpp180
-rw-r--r--src/mame/machine/tait8741.h77
-rw-r--r--src/mame/machine/taito68705interface.cpp354
-rw-r--r--src/mame/machine/taito68705interface.h86
-rw-r--r--src/mame/machine/xbox.cpp21
-rw-r--r--src/mame/mame.lst30
-rw-r--r--src/mame/mess.flt4
-rw-r--r--src/mame/video/aerofgt.cpp41
-rw-r--r--src/mame/video/battlex.cpp2
-rw-r--r--src/mame/video/gsword.cpp167
-rw-r--r--src/mame/video/namco_c116.cpp (renamed from src/mame/video/c116.cpp)6
-rw-r--r--src/mame/video/namco_c116.h (renamed from src/mame/video/c116.h)0
-rw-r--r--src/mame/video/namcos2.cpp5
-rw-r--r--src/mame/video/namcos21.cpp15
-rw-r--r--src/mame/video/rm380z.cpp39
-rw-r--r--src/mame/video/taito_f3.cpp14
-rw-r--r--src/mame/video/xbox_nv2a.cpp201
-rw-r--r--src/osd/modules/debugger/osx/debugconsole.mm2
-rw-r--r--src/osd/modules/render/bgfx/chainentry.cpp2
-rw-r--r--src/osd/modules/render/bgfx/chainmanager.cpp5
-rw-r--r--src/osd/modules/render/bgfx/effectmanager.cpp6
-rw-r--r--src/osd/modules/render/bgfx/shadermanager.cpp8
-rw-r--r--src/osd/modules/render/drawbgfx.cpp11
-rw-r--r--src/tools/imgtool/imgtool.cpp37
-rw-r--r--src/tools/imgtool/imgtool.h1
-rw-r--r--src/tools/imgtool/main.cpp140
-rw-r--r--src/tools/imgtool/modules/rsdos.cpp215
300 files changed, 13771 insertions, 8574 deletions
diff --git a/src/devices/bus/coco/coco_t4426.cpp b/src/devices/bus/coco/coco_t4426.cpp
index 601e6887413..b969ac9bcbb 100644
--- a/src/devices/bus/coco/coco_t4426.cpp
+++ b/src/devices/bus/coco/coco_t4426.cpp
@@ -2,7 +2,7 @@
// copyright-holders:Joakim Larsson Edstrom
/***************************************************************************
*
- * coco_t4426.c
+ * coco_t4426.cpp
*
* Terco T4426 CNC Programming Station multi cart
*
@@ -46,14 +46,16 @@
#define LOG_GENERAL 0x01
#define LOG_SETUP 0x02
#define LOG_PRINTF 0x04
+#define LOG_PIA 0x08
-#define VERBOSE 0 // (LOG_PRINTF | LOG_SETUP | LOG_GENERAL)
+#define VERBOSE 0 //(LOG_PIA | LOG_PRINTF | LOG_SETUP | LOG_GENERAL)
#define LOGMASK(mask, ...) do { if (VERBOSE & mask) logerror(__VA_ARGS__); } while (0)
#define LOGLEVEL(mask, level, ...) do { if ((VERBOSE & mask) >= level) logerror(__VA_ARGS__); } while (0)
#define LOG(...) LOGMASK(LOG_GENERAL, __VA_ARGS__)
#define LOGSETUP(...) LOGMASK(LOG_SETUP, __VA_ARGS__)
+#define LOGPIA(...) LOGMASK(LOG_PIA, __VA_ARGS__)
#if VERBOSE & LOG_PRINTF
#define logerror printf
@@ -77,19 +79,34 @@
IMPLEMENTATION
***************************************************************************/
-// TODO: Figure out address mapping for these devices
static MACHINE_CONFIG_FRAGMENT(coco_t4426)
- MCFG_DEVICE_ADD(UART_TAG, ACIA6850, 0)
+ MCFG_DEVICE_ADD(UART_TAG, ACIA6850, 0) // TODO: Figure out address mapping for ACIA
MCFG_DEVICE_ADD(PIA_TAG, PIA6821, 0)
+ MCFG_PIA_WRITEPA_HANDLER(WRITE8(coco_t4426_device, pia_A_w))
MACHINE_CONFIG_END
ROM_START( coco_t4426 )
- ROM_REGION(0x8000, CARTSLOT_TAG, ROMREGION_ERASE00)
- // First of 8 banked ROM:s TODO: Add the banking and the other ROM:s
- ROM_LOAD("tercoED4426-0-8549-5.3.bin", 0x0000, 0x2000, CRC(45665428) SHA1(ff49a79275772c4c4ab1ae29db662c9b10a744a7))
-
+ ROM_REGION(0x1a000, CARTSLOT_TAG, ROMREGION_ERASE00)
+
+ // 8 banked ROM:s TODO: Add the banking and the other ROM:s
+ ROM_LOAD("tercoED4426-0-8549-5.3.bin", 0x00000, 0x2000, CRC(45665428) SHA1(ff49a79275772c4c4ab1ae29db662c9b10a744a7))
+ ROM_LOAD("tercoED4426-1-8549-5.3.bin", 0x03000, 0x2000, CRC(44baba33) SHA1(01cee1b208c158e598e7ecd2189b5e0ffa7f3ab9))
+ ROM_LOAD("tercoPD4426-2-8632-6.4.bin", 0x06000, 0x2000, CRC(258e443a) SHA1(9d8901f3e70ae4f8526dde1b5208b22f066f801f))
+ ROM_LOAD("tercoPD4426-3-8638-6.4.bin", 0x09000, 0x2000, CRC(640d1de4) SHA1(5ae7427cb5729fd3920361855d954ea1f97f6ae5))
+ ROM_LOAD("tercoCA4426-4-8549-3.4.bin", 0x0c000, 0x2000, CRC(df18397b) SHA1(2f9de210c039619c649be223c37a4eff873fa600))
+ ROM_LOAD("tercoCA4426-5-8549-3.4.bin", 0x0f000, 0x2000, CRC(3fcdf92e) SHA1(ec1589f8d62701ca3faf2a85a57ab2e1f61d2137))
+ ROM_LOAD("tercoCA4426-6-8549-3.4.bin", 0x13000, 0x2000, CRC(27652ccf) SHA1(529a6f736666ae6660483e547d076725606b1c1d))
+ ROM_LOAD("tercoCA4426-7-8549-3.4.bin", 0x16000, 0x2000, CRC(f6640569) SHA1(03f70dcc5f7ab60cd908427d45ebd85b6f464b93))
// Main cartridge ROM
ROM_LOAD("tercoPMOS4426-8549-4.31.bin", 0x2000, 0x1000, CRC(bc65c45c) SHA1(e50cfd1d61e29fe05eb795d8bf6303e7b91ed8e5))
+ // Interleaved copies for the fixed ROM for banking to work (nw yet though)
+ ROM_RELOAD(0x05000,0x1000)
+ ROM_RELOAD(0x08000,0x1000)
+ ROM_RELOAD(0x0b000,0x1000)
+ ROM_RELOAD(0x0e000,0x1000)
+ ROM_RELOAD(0x12000,0x1000)
+ ROM_RELOAD(0x15000,0x1000)
+ ROM_RELOAD(0x18000,0x1000)
ROM_END
//**************************************************************************
@@ -111,6 +128,7 @@ coco_t4426_device::coco_t4426_device(const machine_config &mconfig, device_type
,device_cococart_interface( mconfig, *this )
,m_cart(nullptr)
,m_owner(nullptr)
+ ,m_select(0)
,m_autostart(*this, ":" CART_AUTOSTART_TAG)
,m_uart(*this, UART_TAG)
,m_pia(*this, PIA_TAG)
@@ -122,6 +140,7 @@ coco_t4426_device::coco_t4426_device(const machine_config &mconfig, const char *
,device_cococart_interface( mconfig, *this )
,m_cart(nullptr)
,m_owner(nullptr)
+ ,m_select(0)
,m_autostart(*this, ":" CART_AUTOSTART_TAG)
,m_uart(*this, UART_TAG)
,m_pia(*this, PIA_TAG)
@@ -134,6 +153,7 @@ coco_t4426_device::coco_t4426_device(const machine_config &mconfig, const char *
void coco_t4426_device::device_start()
{
+ LOG("%s()\n", FUNCNAME );
m_cart = dynamic_cast<device_image_interface *>(owner());
m_owner = dynamic_cast<cococart_slot_device *>(owner());
}
@@ -145,6 +165,7 @@ void coco_t4426_device::device_start()
machine_config_constructor coco_t4426_device::device_mconfig_additions() const
{
+ LOG("%s()\n", FUNCNAME );
return MACHINE_CONFIG_NAME( coco_t4426 );
}
@@ -154,6 +175,7 @@ machine_config_constructor coco_t4426_device::device_mconfig_additions() const
const tiny_rom_entry *coco_t4426_device::device_rom_region() const
{
+ LOG("%s()\n", FUNCNAME );
return ROM_NAME( coco_t4426 );
}
@@ -163,39 +185,96 @@ const tiny_rom_entry *coco_t4426_device::device_rom_region() const
void coco_t4426_device::device_reset()
{
+ LOG("%s()\n", FUNCNAME );
auto cart_line = cococart_slot_device::line_value::Q;
m_owner->cart_set_line(cococart_slot_device::line::CART, cart_line);
}
/*-------------------------------------------------
- get_cart_base
--------------------------------------------------*/
-
-uint8_t* coco_t4426_device::get_cart_base()
-{
- return memregion(CARTSLOT_TAG)->base();
-}
-
-/*-------------------------------------------------
read
+ The 4426 cartridge PIA is located at ff44-ff47
-------------------------------------------------*/
READ8_MEMBER(coco_t4426_device::read)
{
uint8_t result = 0x00;
- LOG("%s()\n", FUNCNAME);
- LOGSETUP(" * Offs:%02x -> %02x\n", offset, result);
+ LOG("%s", FUNCNAME);
+ if ((offset >= 0x04) && (offset <= 0x07))
+ result = m_pia->read(space, offset - 0x04);
+
+ LOG(" - Offs:%04x Data:%02x\n", offset, result);
return result;
}
/*-------------------------------------------------
write
+ The 4426 cartridge PIA is located at ff44-ff47
-------------------------------------------------*/
WRITE8_MEMBER(coco_t4426_device::write)
{
LOG("%s(%02x)\n", FUNCNAME, data);
LOGSETUP(" * Offs:%02x <- %02x\n", offset, data);
+
+ if ((offset >= 0x04) && (offset <= 0x07))
+ m_pia->write(space, offset - 0x04, data);
+}
+
+/*----------------------------------------------------
+ pia_A_w - PIA port A write
+
+ The T4426 cartridge PIA Port A is connected to
+ the CE* input of each 2764 ROM and used for banking
+ in the correct BASIC module at C000-DFFF
+ The main cartridge ROM at E000-FF00 is fixed however
+-----------------------------------------------------*/
+#define ROM0 (~0x01 & 0xff)
+#define ROM1 (~0x02 & 0xff)
+#define ROM2 (~0x04 & 0xff)
+#define ROM3 (~0x08 & 0xff)
+#define ROM4 (~0x10 & 0xff)
+#define ROM5 (~0x20 & 0xff)
+#define ROM6 (~0x40 & 0xff)
+#define ROM7 (~0x80 & 0xff)
+
+WRITE8_MEMBER( coco_t4426_device::pia_A_w )
+{
+ LOGPIA("%s(%02x)\n", FUNCNAME, data);
+ m_select = data;
+ cart_base_changed();
+}
+
+/*-------------------------------------------------
+ get_cart_base
+-------------------------------------------------*/
+
+uint8_t* coco_t4426_device::get_cart_base()
+{
+ LOG("%s - m_select %02x -> %02x\n", FUNCNAME, m_select, ~m_select & 0xff );
+ uint8_t *base = memregion(CARTSLOT_TAG)->base();
+
+ switch (m_select)
+ {
+ case 0:
+ case ROM0: base = (uint8_t *) (base + 0x00000); break;
+ case ROM1: base = (uint8_t *) (base + 0x03000); break;
+ case ROM2: base = (uint8_t *) (base + 0x06000); break;
+ case ROM3: base = (uint8_t *) (base + 0x09000); break;
+ case ROM4: base = (uint8_t *) (base + 0x0c000); break;
+ case ROM5: base = (uint8_t *) (base + 0x0f000); break;
+ case ROM6: base = (uint8_t *) (base + 0x13000); break;
+ case ROM7: base = (uint8_t *) (base + 0x16000); break;
+ }
+
+#if 0 // Print the beginning of the selected ROM bank, seems to be correct but is not mapped in correctly via coco12.cpp m_sam->read yet
+ printf("\n");
+ for (int i = 0; i < 48; i++) printf("%02x ", *((uint8_t *)(base + i)));
+ printf("\n");
+ for (int i = 0; i < 48; i++) printf("'%c'", *((uint8_t *)(base + i)));
+ printf("\n");
+#endif
+
+ return base;
}
diff --git a/src/devices/bus/coco/coco_t4426.h b/src/devices/bus/coco/coco_t4426.h
index 72cd86a811d..a0ec0532142 100644
--- a/src/devices/bus/coco/coco_t4426.h
+++ b/src/devices/bus/coco/coco_t4426.h
@@ -30,6 +30,8 @@ public:
virtual const tiny_rom_entry *device_rom_region() const override;
virtual uint8_t* get_cart_base() override;
+ DECLARE_WRITE8_MEMBER( pia_A_w );
+
protected:
// device-level overrides
virtual void device_start() override;
@@ -38,6 +40,7 @@ protected:
// internal state
device_image_interface *m_cart;
cococart_slot_device *m_owner;
+ uint8_t m_select;
optional_ioport m_autostart;
diff --git a/src/devices/bus/vme/vme.cpp b/src/devices/bus/vme/vme.cpp
index 381b7e3075e..79e6d5a8687 100644
--- a/src/devices/bus/vme/vme.cpp
+++ b/src/devices/bus/vme/vme.cpp
@@ -68,8 +68,11 @@
#include "emu.h"
#include "vme.h"
-#include "bus/vme/mzr8105.h"
-#include "bus/vme/mzr8300.h"
+//#include "bus/vme/vme_mzr8105.h"
+#include "bus/vme/vme_mzr8300.h"
+#include "bus/vme/vme_mvme350.h"
+#include "bus/vme/vme_fcisio.h"
+#include "bus/vme/vme_fcscsi.h"
#define LOG_GENERAL 0x01
#define LOG_SETUP 0x02
@@ -95,26 +98,25 @@
// GLOBAL VARIABLES
//**************************************************************************
-const device_type VME_P1_SLOT = &device_creator<vme_p1_slot_device>;
+const device_type VME_SLOT = &device_creator<vme_slot_device>;
//-------------------------------------------------
-// vme_p1_slot_device - constructor
+// vme_slot_device - constructor
//-------------------------------------------------
-vme_p1_slot_device::vme_p1_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
- device_t(mconfig, VME_P1_SLOT, "VME_P1_SLOT", tag, owner, clock, "vme_p1_slot", __FILE__)
+vme_slot_device::vme_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
+ device_t(mconfig, VME_SLOT, "VME_SLOT", tag, owner, clock, "vme_slot", __FILE__)
,device_slot_interface(mconfig, *this)
- ,m_vme_p1_tag(nullptr)
- ,m_vme_p1_slottag(nullptr)
+ ,m_vme_tag(nullptr)
+ ,m_vme_slottag(nullptr)
,m_vme_j1_callback(*this)
{
- LOG("%s %s\n", tag, FUNCNAME);
}
-vme_p1_slot_device::vme_p1_slot_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, uint32_t clock, const char *shortname, const char *source) :
+vme_slot_device::vme_slot_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, uint32_t clock, const char *shortname, const char *source) :
device_t(mconfig, type, name, tag, owner, clock, shortname, source),
device_slot_interface(mconfig, *this)
- ,m_vme_p1_tag(nullptr)
- ,m_vme_p1_slottag(nullptr)
+ ,m_vme_tag(nullptr)
+ ,m_vme_slottag(nullptr)
,m_vme_j1_callback(*this)
{
}
@@ -122,24 +124,27 @@ vme_p1_slot_device::vme_p1_slot_device(const machine_config &mconfig, device_typ
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
-void vme_p1_slot_device::static_set_vme_p1_slot(device_t &device, const char *tag, const char *slottag)
+void vme_slot_device::static_set_vme_slot(device_t &device, const char *tag, const char *slottag)
{
LOG("%s %s - %s\n", FUNCNAME, tag, slottag);
- vme_p1_slot_device &vme_card = dynamic_cast<vme_p1_slot_device&>(device);
- vme_card.m_vme_p1_tag = tag;
- vme_card.m_vme_p1_slottag = slottag;
+ vme_slot_device &vme_card = dynamic_cast<vme_slot_device&>(device);
+ vme_card.m_vme_tag = tag;
+ vme_card.m_vme_slottag = slottag;
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
-void vme_p1_slot_device::device_start()
+void vme_slot_device::device_start()
{
- device_vme_p1_card_interface *dev = dynamic_cast<device_vme_p1_card_interface *>(get_card_device());
- LOG("%s %s - %s:%s\n", tag(), FUNCNAME, m_vme_p1_tag, m_vme_p1_slottag);
- if (dev) device_vme_p1_card_interface::static_set_vme_p1_tag(*dev, m_vme_p1_tag, m_vme_p1_slottag);
+ device_vme_card_interface *dev = dynamic_cast<device_vme_card_interface *>(get_card_device());
+ LOG("%s %s - %s:%s\n", tag(), FUNCNAME, m_vme_tag, m_vme_slottag);
+ if (dev)
+ {
+ device_vme_card_interface::static_set_vme_tag(*dev, m_vme_tag, m_vme_slottag);
+ }
- // m_card = dynamic_cast<device_vme_p1_card_interface *>(get_card_device());
+ // m_card = dynamic_cast<device_vme_card_interface *>(get_card_device());
}
//-------------------------------------------------
@@ -147,7 +152,7 @@ void vme_p1_slot_device::device_start()
// operations now that the configuration is
// complete
//-------------------------------------------------
-void vme_p1_slot_device::device_config_complete()
+void vme_slot_device::device_config_complete()
{
LOG("%s %s\n", tag(), FUNCNAME);
}
@@ -155,7 +160,7 @@ void vme_p1_slot_device::device_config_complete()
//-------------------------------------------------
// P1 D8 read
//-------------------------------------------------
-READ8_MEMBER(vme_p1_slot_device::read8)
+READ8_MEMBER(vme_slot_device::read8)
{
uint16_t result = 0x00;
LOG("%s %s\n", tag(), FUNCNAME);
@@ -167,57 +172,65 @@ READ8_MEMBER(vme_p1_slot_device::read8)
//-------------------------------------------------
// P1 D8 write
//-------------------------------------------------
-WRITE8_MEMBER(vme_p1_slot_device::write8)
+WRITE8_MEMBER(vme_slot_device::write8)
{
LOG("%s %s\n", tag(), FUNCNAME);
// printf("%s %s\n", tag(), FUNCNAME);
// if (m_card) m_card->write8(space, offset, data);
}
-SLOT_INTERFACE_START( vme_p1_slot1 )
- SLOT_INTERFACE("mzr8105", VME_MZR8105)
+#if 0 // Disabled until we know how to make a board driver also a slot device
+/* The following two slot collections be combined once we intriduce capabilities for each board */
+/* Usually a VME firmware supports only a few boards so it will have its own slot collection defined */
+// Controller capable boards that can go into slot1 ( or has an embedded VME bus )
+SLOT_INTERFACE_START( vme_slot1 )
+// SLOT_INTERFACE("mzr8105", VME_MZR8105)
SLOT_INTERFACE_END
+#endif
-SLOT_INTERFACE_START( vme_p1_slots )
- SLOT_INTERFACE("mzr8105", VME_MZR8105)
+// All boards that can be non-controller boards, eg not driving the VME CLK etc
+SLOT_INTERFACE_START( vme_slots )
SLOT_INTERFACE("mzr8300", VME_MZR8300)
+ SLOT_INTERFACE("mvme350", VME_MVME350)
+ SLOT_INTERFACE("fcisio1", VME_FCISIO1)
+ SLOT_INTERFACE("fcscsi1", VME_FCSCSI1)
SLOT_INTERFACE_END
//
// VME device P1
//
-const device_type VME_P1 = &device_creator<vme_p1_device>;
+const device_type VME = &device_creator<vme_device>;
-vme_p1_device::vme_p1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
- device_t(mconfig, VME_P1, "VME_P1", tag, owner, clock, "vme_p1", __FILE__)
+vme_device::vme_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
+ device_t(mconfig, VME, "VME", tag, owner, clock, "vme", __FILE__)
{
}
-vme_p1_device::vme_p1_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, uint32_t clock, const char *shortname, const char *source) :
+vme_device::vme_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, uint32_t clock, const char *shortname, const char *source) :
device_t(mconfig, type, name, tag, owner, clock, shortname, source)
{
}
-vme_p1_device::~vme_p1_device()
+vme_device::~vme_device()
{
m_device_list.detach_all();
}
-void vme_p1_device::device_start()
+void vme_device::device_start()
{
}
-void vme_p1_device::device_reset()
+void vme_device::device_reset()
{
}
-void vme_p1_device::add_vme_p1_card(device_vme_p1_card_interface *card)
+void vme_device::add_vme_card(device_vme_card_interface *card)
{
m_device_list.append(*card);
}
-void vme_p1_device::install_device(offs_t start, offs_t end, read8_delegate rhandler, write8_delegate whandler, uint32_t mask)
+void vme_device::install_device(offs_t start, offs_t end, read8_delegate rhandler, write8_delegate whandler, uint32_t mask)
{
cpu_device *m_maincpu = machine().device<cpu_device>("maincpu");
@@ -226,7 +239,7 @@ void vme_p1_device::install_device(offs_t start, offs_t end, read8_delegate rhan
switch(buswidth)
{
case 32:
- logerror("A32:D8 handler requires a P2 connector - not implemented yet\n");
+ m_maincpu->space(AS_PROGRAM).install_readwrite_handler(start, end, rhandler, whandler, mask);
break;
case 24:
m_maincpu->space(AS_PROGRAM).install_readwrite_handler(start, end, rhandler, whandler, mask);
@@ -235,11 +248,11 @@ void vme_p1_device::install_device(offs_t start, offs_t end, read8_delegate rhan
m_maincpu->space(AS_PROGRAM).install_readwrite_handler(start, end, rhandler, whandler, (uint16_t)(mask & 0xffff));
break;
default:
- fatalerror("VME_P1 D8: Bus width %d not supported\n", buswidth);
+ fatalerror("VME D8: Bus width %d not supported\n", buswidth);
}
}
-void vme_p1_device::install_device(offs_t start, offs_t end, read16_delegate rhandler, write16_delegate whandler, uint32_t mask)
+void vme_device::install_device(offs_t start, offs_t end, read16_delegate rhandler, write16_delegate whandler, uint32_t mask)
{
cpu_device *m_maincpu = machine().device<cpu_device>("maincpu");
int buswidth = m_maincpu->space_config(AS_PROGRAM)->m_databus_width;
@@ -247,7 +260,7 @@ void vme_p1_device::install_device(offs_t start, offs_t end, read16_delegate rha
switch(buswidth)
{
case 32:
- logerror("A32:D16 handler requires a P2 connector - not implemented yet\n");
+ m_maincpu->space(AS_PROGRAM).install_readwrite_handler(start, end, rhandler, whandler, mask);
break;
case 24:
m_maincpu->space(AS_PROGRAM).install_readwrite_handler(start, end, rhandler, whandler, mask);
@@ -256,11 +269,11 @@ void vme_p1_device::install_device(offs_t start, offs_t end, read16_delegate rha
m_maincpu->space(AS_PROGRAM).install_readwrite_handler(start, end, rhandler, whandler, (uint16_t)(mask & 0xffff));
break;
default:
- fatalerror("VME_P1 D16: Bus width %d not supported\n", buswidth);
+ fatalerror("VME D16: Bus width %d not supported\n", buswidth);
}
}
-void vme_p1_device::install_device(offs_t start, offs_t end, read32_delegate rhandler, write32_delegate whandler, uint32_t mask)
+void vme_device::install_device(offs_t start, offs_t end, read32_delegate rhandler, write32_delegate whandler, uint32_t mask)
{
cpu_device *m_maincpu = machine().device<cpu_device>("maincpu");
int buswidth = m_maincpu->space_config(AS_PROGRAM)->m_databus_width;
@@ -268,29 +281,27 @@ void vme_p1_device::install_device(offs_t start, offs_t end, read32_delegate rha
switch(buswidth)
{
case 32:
- logerror("A32:D32 handler requires a P2 connector - not implemented yet\n");
+ m_maincpu->space(AS_PROGRAM).install_readwrite_handler(start, end, rhandler, whandler, mask);
break;
case 24:
- logerror("A24:D32 handler requires a P2 connector - not implemented yet\n");
- // m_maincpu->space(AS_PROGRAM).install_readwrite_handler(start, end, rhandler, whandler, mask);
+ m_maincpu->space(AS_PROGRAM).install_readwrite_handler(start, end, rhandler, whandler, mask);
break;
case 16:
- logerror("A16:D32 handler requires a P2 connector - not implemented yet\n");
- // m_maincpu->space(AS_PROGRAM).install_readwrite_handler(start, end, rhandler, whandler, (uint16_t)(mask & 0xffff));
+ m_maincpu->space(AS_PROGRAM).install_readwrite_handler(start, end, rhandler, whandler, (uint16_t)(mask & 0xffff));
break;
default:
- fatalerror("VME_P1 D32: Bus width %d not supported\n", buswidth);
+ fatalerror("VME D32: Bus width %d not supported\n", buswidth);
}
}
//
// Card interface
//
-device_vme_p1_card_interface::device_vme_p1_card_interface(const machine_config &mconfig, device_t &device)
+device_vme_card_interface::device_vme_card_interface(const machine_config &mconfig, device_t &device)
: device_slot_card_interface(mconfig, device)
- ,m_vme_p1(nullptr)
- ,m_vme_p1_tag(nullptr)
- ,m_vme_p1_slottag(nullptr)
+ ,m_vme(nullptr)
+ ,m_vme_tag(nullptr)
+ ,m_vme_slottag(nullptr)
,m_slot(0)
,m_next(nullptr)
{
@@ -298,41 +309,40 @@ device_vme_p1_card_interface::device_vme_p1_card_interface(const machine_config
LOG("%s %s\n", m_device->tag(), FUNCNAME);
}
-device_vme_p1_card_interface::~device_vme_p1_card_interface()
+device_vme_card_interface::~device_vme_card_interface()
{
LOG("%s %s\n", m_device->tag(), FUNCNAME);
}
-void device_vme_p1_card_interface::static_set_vme_p1_tag(device_t &device, const char *tag, const char *slottag)
+void device_vme_card_interface::static_set_vme_tag(device_t &device, const char *tag, const char *slottag)
{
- device_vme_p1_card_interface &vme_p1_card = dynamic_cast<device_vme_p1_card_interface &>(device);
- vme_p1_card.m_vme_p1_tag = tag;
- vme_p1_card.m_vme_p1_slottag = slottag;
+ device_vme_card_interface &vme_card = dynamic_cast<device_vme_card_interface &>(device);
+ vme_card.m_vme_tag = tag;
+ vme_card.m_vme_slottag = slottag;
}
-void device_vme_p1_card_interface::set_vme_p1_device()
+void device_vme_card_interface::set_vme_device()
{
LOG("%s %s\n", m_device->tag(), FUNCNAME);
- m_vme_p1 = dynamic_cast<vme_p1_device *>(device().machine().device(m_vme_p1_tag));
- // printf("*** %s %sfound\n", m_vme_p1_tag, m_vme_p1 ? "" : "not ");
- if (m_vme_p1) m_vme_p1->add_vme_p1_card(this);
+ m_vme = dynamic_cast<vme_device *>(device().machine().device(m_vme_tag));
+ // printf("*** %s %sfound\n", m_vme_tag, m_vme ? "" : "not ");
+ if (m_vme) m_vme->add_vme_card(this);
}
/* VME D8 accesses */
-READ8_MEMBER(device_vme_p1_card_interface::read8)
+READ8_MEMBER(device_vme_card_interface::read8)
{
uint8_t result = 0x00;
LOG("%s %s Offset:%08x\n", m_device->tag(), FUNCNAME, offset);
return result;
}
-WRITE8_MEMBER(device_vme_p1_card_interface::write8)
+WRITE8_MEMBER(device_vme_card_interface::write8)
{
LOG("%s %s Offset:%08x\n", m_device->tag(), FUNCNAME, offset);
}
//--------------- P2 connector below--------------------------
-#if 0
/*
The VME P2 connector only specifies the mid row B of the connector
and leaves row A and C to be system specific. This has resulted in
@@ -356,56 +366,3 @@ http://www.interfacebus.com/Design_Connector_VME_P2_Buses.html
TODO: Figure out a good way to let all these variants coexist and interconnect in a VME system
*/
-//**************************************************************************
-// GLOBAL VARIABLES
-//**************************************************************************
-
-const device_type VME_P2_SLOT = &device_creator<vme_p2_slot_device>;
-
-//-------------------------------------------------
-// vme_p2_slot_device - constructor
-//-------------------------------------------------
-vme_p2_slot_device::vme_p2_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
- device_t(mconfig, VME_P2_SLOT, "VME P2 connector", tag, owner, clock, "vme_p2_connector", __FILE__),
- device_slot_interface(mconfig, *this),
- m_vme_j2_callback(*this)
-{
-}
-
-void vme_p2_slot_device::device_start()
-{
- m_vme_p2 = dynamic_cast<device_vme_p2_interface *>(get_card_device());
-}
-
-//-------------------------------------------------
-// device_config_complete - perform any
-// operations now that the configuration is
-// complete
-//-------------------------------------------------
-
-void vme_p2_slot_device::device_config_complete()
-{
- // set brief and instance name
- update_names();
-}
-
-//-------------------------------------------------
-// P2 read
-//-------------------------------------------------
-READ32_MEMBER(vme_p2_slot_device::write32)
-{
- uint8_t result = 0x00;
- if (m_vme_p2)
- result = m_vme_p2->read32(space, offset);
- return result;
-}
-
-//-------------------------------------------------
-// P2 write
-//-------------------------------------------------
-WRITE32_MEMBER(vme_p2_slot_device::read32)
-{
- if (m_vme_p2)
- m_vme_p2->write32(space, offset, data);
-}
-#endif
diff --git a/src/devices/bus/vme/vme.h b/src/devices/bus/vme/vme.h
index 8c22c828ae5..6103379a4ac 100644
--- a/src/devices/bus/vme/vme.h
+++ b/src/devices/bus/vme/vme.h
@@ -60,14 +60,14 @@
// Callbacks to the board from the VME bus comes through here
#define MCFG_VME_J1_CB(_devcb) \
- devcb = &vme_p1_slot_device::static_set_vme_j1_callback(*device, DEVCB_##_devcb);
+ devcb = &vme_slot_device::static_set_vme_j1_callback(*device, DEVCB_##_devcb);
-SLOT_INTERFACE_EXTERN(vme_p1_slot1);
-SLOT_INTERFACE_EXTERN(vme_p1_slots);
+//SLOT_INTERFACE_EXTERN(vme_slot1); // Disabled until we know how to combine a board driver and a slot device.
+SLOT_INTERFACE_EXTERN(vme_slots);
-class device_vme_p1_card_interface; // This interface is standardized
+class device_vme_card_interface; // This interface is standardized
-class vme_p1_slot_device : public device_t,
+class vme_slot_device : public device_t,
public device_slot_interface
{
public:
@@ -90,44 +90,44 @@ public:
};
// construction/destruction
- vme_p1_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ vme_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
- vme_p1_slot_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, uint32_t clock, const char *shortname, const char *source);
+ vme_slot_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, uint32_t clock, const char *shortname, const char *source);
- template<class _Object> static devcb_base &static_set_vme_j1_callback(device_t &device, _Object object) { return downcast<vme_p1_slot_device &>(device).m_vme_j1_callback.set_callback(object); }
+ template<class _Object> static devcb_base &static_set_vme_j1_callback(device_t &device, _Object object) { return downcast<vme_slot_device &>(device).m_vme_j1_callback.set_callback(object); }
// device-level overrides
virtual void device_start() override;
virtual void device_config_complete() override;
- static void static_set_vme_p1_slot(device_t &device, const char *tag, const char *slottag);
+ static void static_set_vme_slot(device_t &device, const char *tag, const char *slottag);
// configuration
- const char *m_vme_p1_tag, *m_vme_p1_slottag;
+ const char *m_vme_tag, *m_vme_slottag;
virtual DECLARE_READ8_MEMBER(read8);
virtual DECLARE_WRITE8_MEMBER(write8);
// callbacks
devcb_write_line m_vme_j1_callback;
- device_vme_p1_card_interface *m_card;
+ device_vme_card_interface *m_card;
private:
};
-extern const device_type VME_P1;
+extern const device_type VME;
-#define MCFG_VME_P1_DEVICE_ADD(_tag) \
- MCFG_DEVICE_ADD(_tag, VME_P1, 0)
+#define MCFG_VME_DEVICE_ADD(_tag) \
+ MCFG_DEVICE_ADD(_tag, VME, 0)
-class vme_p1_card_interface;
+class vme_card_interface;
-class vme_p1_device : public device_t
+class vme_device : public device_t
{
public:
- vme_p1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
- vme_p1_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, uint32_t clock, const char *shortname, const char *source);
- ~vme_p1_device();
+ vme_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ vme_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, uint32_t clock, const char *shortname, const char *source);
+ ~vme_device();
- void add_vme_p1_card(device_vme_p1_card_interface *card);
+ void add_vme_card(device_vme_card_interface *card);
void install_device(offs_t start, offs_t end, read8_delegate rhandler, write8_delegate whandler, uint32_t mask);
void install_device(offs_t start, offs_t end, read16_delegate rhandler, write16_delegate whandler, uint32_t mask);
void install_device(offs_t start, offs_t end, read32_delegate rhandler, write32_delegate whandler, uint32_t mask);
@@ -135,32 +135,32 @@ protected:
// device-level overrides
virtual void device_start() override;
virtual void device_reset() override;
- simple_list<device_vme_p1_card_interface> m_device_list;
+ simple_list<device_vme_card_interface> m_device_list;
};
// device type definition
-extern const device_type VME_P1_SLOT;
+extern const device_type VME_SLOT;
-class device_vme_p1_card_interface : public device_slot_card_interface
+class device_vme_card_interface : public device_slot_card_interface
{
public:
// construction/destruction
- device_vme_p1_card_interface(const machine_config &mconfig, device_t &device);
- virtual ~device_vme_p1_card_interface();
- void set_vme_p1_device();
+ device_vme_card_interface(const machine_config &mconfig, device_t &device);
+ virtual ~device_vme_card_interface();
+ void set_vme_device();
virtual DECLARE_READ8_MEMBER(read8);
virtual DECLARE_WRITE8_MEMBER(write8);
device_t *m_device;
// inline configuration
- static void static_set_vme_p1_tag(device_t &device, const char *tag, const char *slottag);
- vme_p1_device *m_vme_p1;
- const char *m_vme_p1_tag, *m_vme_p1_slottag;
+ static void static_set_vme_tag(device_t &device, const char *tag, const char *slottag);
+ vme_device *m_vme;
+ const char *m_vme_tag, *m_vme_slottag;
int m_slot;
- device_vme_p1_card_interface *m_next;
+ device_vme_card_interface *m_next;
//
// Address Modifiers
@@ -196,231 +196,12 @@ public:
};
};
-SLOT_INTERFACE_EXTERN(vme_p1_slot1);
-
-#define MCFG_VME_P1_SLOT_ADD(_tag, _slot_tag, _slot_intf,_def_slot) \
- MCFG_DEVICE_ADD(_slot_tag, VME_P1_SLOT, 0) \
+#define MCFG_VME_SLOT_ADD(_tag, _slot_tag, _slot_intf,_def_slot) \
+ MCFG_DEVICE_ADD(_slot_tag, VME_SLOT, 0) \
MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, false) \
- vme_p1_slot_device::static_set_vme_p1_slot(*device, _tag, _slot_tag);
-
-#define MCFG_VME_P1_SLOT_REMOVE(_tag) \
- MCFG_DEVICE_REMOVE(_tag)
-
-
-#if 0
-// Callbacks to the board from the VME bus comes through here
-#define MCFG_VME_J2_CB(_devcb) \
- devcb = &vme_p2_slot_device::static_set_j2_callback(*device, DEVCB_##_devcb);
-
-class device_vme_p2_interface; // This interface often has custom/propritary A and C rows
-
-class vme_p2_slot_device : public device_t,
- public device_slot_interface
-{
-public:
-
- // construction/destruction
- vme_p2_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
-
- template<class _Object> static devcb_base &static_set_vme_j2_callback(device_t &device, _Object object) { return downcast<vme_p2_slot_device &>(device).m_vme_j2_callback.set_callback(object); }
-
- // device-level overrides
- virtual void device_start() override;
-
- // callbacks
- devcb_write_line m_vme_j2_callback;
-private:
- device_vme_p2_interface *m_vme_p2;
-};
-
-// device type definition
-extern const device_type VME_P2_SLOT;
-
-class device_vme_p2_interface : public device_slot_card_interface
-{
-public:
- // construction/destruction
- device_vme_p2_interface(const machine_config &mconfig, device_t &device);
- virtual ~device_vme_p2_interface();
+ vme_slot_device::static_set_vme_slot(*device, _tag, _slot_tag);
- virtual DECLARE_READ32_MEMBER(read32);
- virtual DECLARE_WRITE32_MEMBER(write32);
-};
-
-#define MCFG_VME_P2_ADD(_tag,_slot_intf,_def_slot) \
- MCFG_DEVICE_ADD(_tag, VME_P2_SLOT, 0) \
- MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, false)
-
-#define MCFG_VME_P2_REMOVE(_tag) \
+#define MCFG_VME_SLOT_REMOVE(_tag) \
MCFG_DEVICE_REMOVE(_tag)
-#endif
-#if 0
-//**************************************************************************
-// INTERFACE CONFIGURATION MACROS
-//**************************************************************************
-
-#define MCFG_VME16_SLOT_ADD(_vmetag, _tag, _slot_intf, _def_slot, _fixed) \
- MCFG_DEVICE_ADD(_tag, VME16_SLOT, 0) \
- MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, _fixed) \
- vme16_slot_device::static_set_vme16_slot(*device, _vmetag, _tag);
-
-//**************************************************************************
-// TYPE DEFINITIONS
-//**************************************************************************
-
-class device_vme16_card_interface;
-
-//
-// The VME device
-//
-class vme_device : public device_t
-,public device_memory_interface
-{
-public:
- // construction/destruction
- vme_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
- vme_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, uint32_t clock, const char *shortname, const char *source);
-
- // inline configuration
- static void static_set_cputag(device_t &device, const char *tag);
-
- void install_device(offs_t start, offs_t end, offs_t mask, offs_t mirror, read8_delegate rhandler, write8_delegate whandler);
- void install_device(offs_t start, offs_t end, offs_t mask, offs_t mirror, read16_delegate rhandler, write16_delegate whandler);
- void install_device(offs_t start, offs_t end, offs_t mask, offs_t mirror, read32_delegate rhandler, write32_delegate whandler);
- void install_bank(offs_t start, offs_t end, offs_t mask, offs_t mirror, const char *tag, uint8_t *data);
- void unmap_bank(offs_t start, offs_t end, offs_t mask, offs_t mirror);
- void install_rom(device_t *dev, offs_t start, offs_t end, offs_t mask, offs_t mirror, const char *tag, const char *region);
- void install_memory(offs_t start, offs_t end, offs_t mask, offs_t mirror, read8_delegate rhandler, write8_delegate whandler);
- void set_irq_line(int slot, int state);
-protected:
- void install_space(address_spacenum spacenum, offs_t start, offs_t end, offs_t mask, offs_t mirror, read8_delegate rhandler, write8_delegate whandler);
-
- // address spaces
- address_space *m_prgspace;
- int m_prgwidth;
- bool m_allocspaces;
-
- // device-level overrides
- virtual void device_start() override;
- virtual void device_reset() override;
-
- // internal state
- cpu_device *m_maincpu;
- const address_space_config m_program16_config;
- const address_space_config m_program24_config;
- const address_space_config m_program32_config;
-};
-
-class vme16_device : public vme_device
-{
- public:
- vme16_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
- vme16_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, uint32_t clock, const char *shortname, const char *source);
-
- virtual const address_space_config *memory_space_config(address_spacenum spacenum) const override;
-
- DECLARE_READ16_MEMBER ( vme_r );
- DECLARE_WRITE16_MEMBER( vme_w );
-
- void add_vme16_card(device_vme16_card_interface *card);
-};
-
-class vme24_device : public vme_device
-{
- public:
- vme24_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
- vme24_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, uint32_t clock, const char *shortname, const char *source);
-
- virtual const address_space_config *memory_space_config(address_spacenum spacenum) const override;
-
- DECLARE_READ16_MEMBER ( vme_r );
- DECLARE_WRITE16_MEMBER( vme_w );
-
- void add_vme24_card(device_vme16_card_interface *card);
-};
-
-class vme32_device : public vme_device
-{
- public:
- vme32_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
- vme32_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, uint32_t clock, const char *shortname, const char *source);
-
- virtual const address_space_config *memory_space_config(address_spacenum spacenum) const override;
-
- DECLARE_READ32_MEMBER ( vme_r );
- DECLARE_WRITE32_MEMBER( vme_w );
-
- // void add_vme32_card(device_vme16_card_interface *card);
-};
-
-//
-// The SLOT device
-//
-class vme16_slot_device : public device_t,
- public device_slot_interface
-{
-public:
- // construction/destruction
- vme16_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
- vme16_slot_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, uint32_t clock, const char *shortname, const char *source);
- virtual ~vme16_slot_device();
-
- //template<class _Object> static devcb_base &set_out_irq2_callback(device_t &device, _Object object) { return downcast<vme16_slot_device &>(device).m_out_irq2_cb.set_callback(object); }
-
- //DECLARE_WRITE_LINE_MEMBER( irq2_w );
-
- // inline configuration
- static void static_set_vme16_slot(device_t &device, const char *tag, const char *slottag);
-
- // device-level overrides
- virtual void device_start() override;
- virtual void device_reset() override;
-
-protected:
-
- // configuration
- const char *m_vme16_tag, *m_vme16_slottag;
-
- device_vme16_card_interface *m_slot;
-};
-
-
-// device type definition
-extern const device_type VME16_SLOT;
-extern const device_type VME16;
-extern const device_type VME24;
-extern const device_type VME32;
-
-//
-// The CARD device
-//
-class device_vme16_card_interface : public device_slot_card_interface
-{
- friend class vme16_device;
-public:
- // construction/destruction
- device_vme16_card_interface(const machine_config &mconfig, device_t &device);
- virtual ~device_vme16_card_interface();
-
- device_vme16_card_interface *next() const { return m_next; }
-
- void set_vme_device();
-
- // inline configuration
- static void static_set_vmebus(device_t &device, device_t *vme_device);
-public:
- vme16_device *m_vme;
- device_t *m_vme_dev;
- device_vme16_card_interface *m_next;
-};
-
-#if 0
- // reset
- virtual void vme16_reset_w() { };
-
-};
-#endif
-#endif
-
#endif /* VME_H_ */
diff --git a/src/devices/bus/vme/vme_fcisio.cpp b/src/devices/bus/vme/vme_fcisio.cpp
new file mode 100644
index 00000000000..cdbcf13908c
--- /dev/null
+++ b/src/devices/bus/vme/vme_fcisio.cpp
@@ -0,0 +1,409 @@
+// license:BSD-3-Clause
+// copyright-holders:Joakim Larsson Edstrom
+/***************************************************************************
+ *
+ * 10/06/2016
+ * The ISIO board is a VME slave board that reads command and returns results through dual ported RAM to the VME bus.
+ *
+ * ISIO-1: page 385 http://bitsavers.informatik.uni-stuttgart.de/pdf/forceComputers/1988_Force_VMEbus_Products.pdf
+ * ISIO-2: page 395 http://bitsavers.informatik.uni-stuttgart.de/pdf/forceComputers/1988_Force_VMEbus_Products.pdf
+ *
+ * ||
+ * || ||
+ * ||||--||
+ * ||||--||
+ * || ||__________________________________________________________ ___
+ * || |_| |
+ * || | | |
+ * || | | |
+ * || | | |
+ * || | | |
+ * || | | |
+ * || | |VME|
+ * || | | |
+ * || | |P1 |
+ * || | | |
+ * || | | |
+ * || | | |
+ * || | | |
+ * || | | |
+ * || | | |
+ * || |_| |
+ * || |___|
+ * || |
+ * || |
+ * || |
+ * || |
+ * || |
+ * || |
+ * || |
+ * || |
+ * || |___
+ * || _| |
+ * || | | |
+ * || | | |
+ * || | | |
+ * || | | |
+ * || | |VME|
+ * || | | |
+ * || | |P2 |
+ * || | | |
+ * || | | |
+ * || | | |
+ * || | | |
+ * || | | |
+ * || | | |
+ * || | | |
+ * || | | |
+ * || |_| |
+ * || |___|
+ * || ||------------------------------------------------------------+-+
+ * ||||--||
+ * ||||--||
+ * ||
+ *
+ * History of Force Computers
+ *------------------------------------------------------------------------
+ * See fccpu30.cpp
+ *
+ * Description from datasheet etc
+ * ------------------------------
+ * ISIO-1/1A ISIO-2/2A Intelligent Serial I/O Boards
+ * - 68010 for local handling and control
+ * - 8 Channel, multi-protocol serial I/O controller board
+ * - Onboard RS-232 tranceiver. ISIO-2x: optional RS-422 transiever
+ * - ISIO-x: 128Kb ISIO-xA: 512Kb - No Wait State Dual Ported RAM
+ * - 4 fully software programmable VME bus interrupt channels
+ * - Powerful handling firmware(!)
+ * - VMEbus IEEE 1014 compatibility: A24:D16, D8, SYSFAIL (jumper)
+ * - Local watchdog timer
+ *
+ * Local address map - guessed/rev-enged
+ * ----------------------------------------------------------
+ * Address Range Description
+ * ----------------------------------------------------------
+ * 000000 - 000007 Initialisation vectors from system EPROM
+ * 000008 - 01FFFF Local SRAM
+ * E00000 - E001FF DUSCC0
+ * E20000 - E001FF DUSCC0
+ * E40000 - E001FF DUSCC0
+ * E60000 - E001FF DUSCC0
+ * E80000 - E80DFF PI/T
+ * f00000 - F70000 EPROMs
+ * ----------------------------------------------------------
+ *
+ * VME side A24 address map - Dual ported RAM
+ * ----------------------------------------------------------
+ * Offset Range Description
+ * ----------------------------------------------------------
+ * 000000 - 0007FF BIM
+ * 000800 - 000FFF Status registers
+ * 001000 - 0017FF Read generates local interrupt
+ * 001800 - 001FFF Read generates local reset
+ * 002000 - 007FFF Reserved for local CPU
+ * 008000 - 0080FF 16 command channels for 4 x DUSCC Rx/Tx (A/B)
+ * 008100 - 01FFFF 16 data arrays for the I/O channels
+ * ----------------------------------------------------------
+ *
+ * Interrupt sources
+ * ----------------------------------------------------------
+ * Description Device Lvl IRQ VME board
+ * /Board Vector Address
+ * ----------------------------------------------------------
+ * On board Sources
+ * ----------------------------------------------------------
+ *
+ * TODO:
+ * - add PIT and DUSCC interrupts
+ * - add port mapping to self test jumper
+ * - add VME bus driver
+ * - write and map a 68153 device (accessable from VME side)
+ *
+ * Status: passes Self test and get stuck on no ticks for the scheduler.
+ * Schematics of the IRQ routing needed or a good trace of how the
+ * PIT and DUSCCs are hooked up to the BIM to get further.
+ *
+ ****************************************************************************/
+#define TODO "Driver for 68153 BIM device needed\n"
+
+#include "emu.h"
+#include "cpu/m68000/m68000.h"
+#include "machine/scnxx562.h"
+#include "machine/68230pit.h"
+#include "bus/rs232/rs232.h"
+#include "machine/clock.h"
+#include "vme_fcisio.h"
+
+#define LOG_GENERAL 0x01
+#define LOG_SETUP 0x02
+#define LOG_PRINTF 0x04
+
+#define VERBOSE 0 //(LOG_PRINTF | LOG_SETUP | LOG_GENERAL)
+
+#define LOGMASK(mask, ...) do { if (VERBOSE & mask) logerror(__VA_ARGS__); } while (0)
+#define LOGLEVEL(mask, level, ...) do { if ((VERBOSE & mask) >= level) logerror(__VA_ARGS__); } while (0)
+
+#define LOG(...) LOGMASK(LOG_GENERAL, __VA_ARGS__)
+#define LOGSETUP(...) LOGMASK(LOG_SETUP, __VA_ARGS__)
+
+#if VERBOSE & LOG_PRINTF
+#define logerror printf
+#endif
+
+#ifdef _MSC_VER
+#define FUNCNAME __func__
+#else
+#define FUNCNAME __PRETTY_FUNCTION__
+#endif
+
+//**************************************************************************
+// GLOBAL VARIABLES
+//**************************************************************************
+
+const device_type VME_FCISIO1 = &device_creator<vme_fcisio1_card_device>;
+
+#define CPU_CLOCK XTAL_20MHz /* HCJ */
+#define DUSCC_CLOCK XTAL_14_7456MHz /* HCJ */
+
+static ADDRESS_MAP_START (fcisio1_mem, AS_PROGRAM, 16, vme_fcisio1_card_device)
+ ADDRESS_MAP_UNMAP_HIGH
+ AM_RANGE (0x000000, 0x000007) AM_ROM AM_READ (bootvect_r) /* Vectors mapped from System EPROM */
+ AM_RANGE (0x000000, 0x01ffff) AM_RAM /* SRAM */
+ AM_RANGE (0xe00000, 0xe001ff) AM_DEVREADWRITE8("duscc0", duscc68562_device, read, write, 0x00ff)
+ AM_RANGE (0xe20000, 0xe201ff) AM_DEVREADWRITE8("duscc1", duscc68562_device, read, write, 0x00ff)
+ AM_RANGE (0xe40000, 0xe401ff) AM_DEVREADWRITE8("duscc2", duscc68562_device, read, write, 0x00ff)
+ AM_RANGE (0xe60000, 0xe601ff) AM_DEVREADWRITE8("duscc3", duscc68562_device, read, write, 0x00ff)
+ AM_RANGE (0xe80000, 0xe80dff) AM_DEVREADWRITE8("pit", pit68230_device, read, write, 0x00ff)
+ AM_RANGE (0xf00000, 0xf7ffff) AM_ROM /* System EPROM Area 32Kb DEBUGGER supplied */
+// AM_RANGE (0xc40000, 0xc800ff) AM_READWRITE8 (not_implemented_r, not_implemented_w, 0xffff) /* Dummy mapping af address area to display message */
+ADDRESS_MAP_END
+
+/*
+ * Machine configuration
+ */
+static MACHINE_CONFIG_FRAGMENT (fcisio1)
+ /* basic machine hardware */
+ MCFG_CPU_ADD ("maincpu", M68010, CPU_CLOCK / 2)
+ MCFG_CPU_PROGRAM_MAP (fcisio1_mem)
+
+ MCFG_DUSCC68562_ADD("duscc0", DUSCC_CLOCK, 0, 0, 0, 0 )
+ MCFG_DUSCC_OUT_TXDA_CB(DEVWRITELINE("rs232trm", rs232_port_device, write_txd))
+ MCFG_DUSCC_OUT_DTRA_CB(DEVWRITELINE("rs232trm", rs232_port_device, write_dtr))
+ MCFG_DUSCC_OUT_RTSA_CB(DEVWRITELINE("rs232trm", rs232_port_device, write_rts))
+
+ MCFG_RS232_PORT_ADD ("rs232trm", default_rs232_devices, "terminal")
+ MCFG_RS232_RXD_HANDLER (DEVWRITELINE ("duscc0", duscc68562_device, rxa_w))
+ MCFG_RS232_CTS_HANDLER (DEVWRITELINE ("duscc0", duscc68562_device, ctsa_w))
+// MCFG_DEVICE_CARD_DEVICE_INPUT_DEFAULTS("terminal", fcisio_terminal)
+
+ MCFG_DUSCC68562_ADD("duscc1", DUSCC_CLOCK, 0, 0, 0, 0 )
+ MCFG_DUSCC68562_ADD("duscc2", DUSCC_CLOCK, 0, 0, 0, 0 )
+ MCFG_DUSCC68562_ADD("duscc3", DUSCC_CLOCK, 0, 0, 0, 0 )
+
+ MCFG_DEVICE_ADD ("pit", PIT68230, XTAL_20MHz / 2)
+ MCFG_PIT68230_PB_INPUT_CB(READ8(vme_fcisio1_card_device, config_rd))
+MACHINE_CONFIG_END
+
+/* ROM definitions */
+ROM_START (fcisio1)
+ ROM_REGION (0x1000000, "maincpu", 0)
+
+/* ISIO ROM:s v2.1 information
+ * PIT setup sequence
+ * 00 -> REG_PGCR
+ * 18 -> REG_PSRR
+ * 0f -> Reg PADDR
+ * 0f -> REG_PBDDR
+ * fa -> REG_PACR
+ * 0f -> REG_PADDR
+ * fa -> REG_PBCR
+ * ff -> REG_PBDR
+ * 0f -> REG_PBDDR
+ * 10 -> REG_PGCR
+ * ff -> REG_PCDR
+ * 17 -> REG_PCDDR
+ * 40 -> Reg PIVR
+ * 00 -> REG_TCR - timer disabled, all C pins, use preload, CLK and prescaler are used
+ * a0 -> REG_TCR - timer disabled, The dual-function pin PC3/TOUT carries the TOUTfunction and is used as a timer interrupt request
+ * output. The timer interrupt is enabled ; thus, the pin is low when the timer ZDS status bit is one. The dual-function
+ * pin PC7/TIACK carries the TIACK function and is used as a timer interrupt acknowledge input.
+ * 00 -> Reg 0x12
+ * 00 -> REG_CPRH
+ * 09 -> REG_CPRM
+ * 00 -> REG_CPRL
+ * 00 -> Reg 0x16
+ * 00 -> Reg 0x17
+ * 09 -> Reg 0x18
+ * 00 -> Reg 0x19
+ * 1d -> Reg TIVR
+ * 0f <- REG_PBDR
+ * 0e -> REG_PBDR
+ * 0f <- REG_PBDR
+ * 0f <- REG_PBDR
+ * 0d -> REG_PDBR
+ * 0f <- REG_PBDR
+ * 0f <- REG_PBDR
+ * 0f <- REG_PBDR
+ * 0f <- REG_PBDR
+ * 0f <- REG_PBDR
+ * 0f <- REG_PBDR
+ * 0f <- REG_PBDR
+ * 0f <- REG_PBDR
+ * 0f <- REG_PBDR
+ * 0f -> REG_PBDR
+ * 0f <- REG_PBDR
+ * 0b -> REG_PBDR
+ * 0f <- REG_PBDR
+ * 0f <- REG_PBDR
+ * 0f -> REG_PBDR
+ * 0f <- REG_PBDR
+ * 0f -> REG_PBDR
+ * 0f <- REG_PBDR
+ * 00 <- REG_PCDR
+ * 00 -> REG_PCDR
+ * ------- repeated 16 times -------------------
+ * a1 -> REG_TCR - timer enabled, The dual-function pin PC3/TOUT carries the TOUTfunction and is used as a timer interrupt request
+ * output. The timer interrupt is enabled ; thus, the pin is low when the timer ZDS status bit is one. The dual-function
+ * pin PC7/TIACK carries the TIACK function and is used as a timer interrupt acknowledge input.
+ * ?? <- Reg 0x0c
+ * ---------------------------------------------
+ *
+ * DUSCC0 channel A setup sequence
+ * 0f 00 -> REG_CCR - Reset Tx
+ * 0f 40 -> REG_CCR - Reset Rx
+ * 00 07 -> REG_CMR1 - Async mode
+ * 01 38 -> REG_CMR2 - Normal polled or interrupt mode, no DMA
+ * 02 00 -> REG_S1R - SYN1, Secondary Address 1 Register, 0 = no sync
+ * 03 00 -> REG_S2R - SYN2, only used in COP dual Sync mode but alao 0 = no sync
+ * 04 7F -> REG_TPR - Tx 8 bits, CTS and RTS, 1 STOP bit
+ * 05 3d -> REG_TTR - Tx BRG 9600 (assuming a 14.7456 crystal)
+ * 06 1b -> REG_RPR - Rx RTS, 8 bits, no DCD, no parity
+ * 07 2d -> REG_RTR - Rx BRG 9600 (assuming a 14.7456 crystal)
+ * 0b e1 -> REG_OMR - RTS high, OUT1 = OUT2 = high, RxRdy asserted for each character,
+ * TxRdy asserted on threshold, Same Tx Residual Character Length as for REG_TPR
+ * 0a 00 -> REG_CTCR - Counter/Timer control register 00 = Zero Det Int: disabled, Zero Det Control: preset,
+ * Output Control: square, Prescaler: 1, Clock Source: RTxC pin
+ * 09 00 -> REG_CTPRL - Counter/Timer Prescaler Register Low = 0
+ * 08 00 -> REG_CTPRH - Counter/Timer Prescaler Register High = 0
+ * 0f 00 -> REG_CCR - Reset Tx
+ * 0f 02 -> REG_CCR - Enable Tx
+ * 0f 40 -> REG_CCR - Reset Rx
+ * 0f 42 -> REG_CCR - Enable Rx
+ * 0f 02 -> REG_CCR - Enable Tx
+ * 0f 42 -> REG_CCR - Enable Rx
+ * 0e 27 -> REG_PCR - TRxC = RxCLK 1x, RTxC is input, RTS, GPO2, crystal oscillator connected to X2
+ * 1c 10 -> REG_IER - Interrupt Enable Register: RxRdy generates interrupt
+ * ... chan B setup with same data....
+ * ---- DUSCC0 to DUSCC3, setup with same data except at the end of each setup:
+ * 1e 1c -> DUSCC0 REG_IVR -
+ * 1e 1b -> DUSCC1 REG_IVR
+ * 1e 1a -> DUSCC2 REG_IVR
+ * 1e 19 -> DUSCC3 REG_IVR
+ */
+ ROM_LOAD16_BYTE ("ISIO-1_V2.1_L.BIN", 0xf00001, 0x4000, CRC (0d47d80f) SHA1 (541b55966f464c1cf686e36998650720950a2242))
+ ROM_LOAD16_BYTE ("ISIO-1_V2.1_U.BIN", 0xf00000, 0x4000, CRC (67986768) SHA1 (215f7ff90d9dbe2bea54510e3722fb33d4e54193))
+ROM_END
+
+machine_config_constructor vme_fcisio1_card_device::device_mconfig_additions() const
+{
+ LOG("%s %s\n", tag(), FUNCNAME);
+ return MACHINE_CONFIG_NAME( fcisio1 );
+}
+
+const tiny_rom_entry *vme_fcisio1_card_device::device_rom_region() const
+{
+ LOG("%s\n", FUNCNAME);
+ return ROM_NAME( fcisio1 );
+}
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+vme_fcisio1_card_device::vme_fcisio1_card_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, uint32_t clock, const char *shortname, const char *source) :
+ device_t(mconfig, type, name, tag, owner, clock, shortname, source)
+ ,device_vme_card_interface(mconfig, *this)
+ ,m_maincpu (*this, "maincpu")
+ ,m_duscc0(*this, "duscc0")
+ ,m_duscc1(*this, "duscc1")
+ ,m_duscc2(*this, "duscc2")
+ ,m_duscc3(*this, "duscc3")
+ ,m_pit (*this, "pit")
+{
+ LOG("%s\n", FUNCNAME);
+}
+
+vme_fcisio1_card_device::vme_fcisio1_card_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
+ device_t(mconfig, VME_FCISIO1, "Force Computer SYS68K/ISIO-1/2 Intelligent Serial I/O Board", tag, owner, clock, "fcisio1", __FILE__)
+ ,device_vme_card_interface(mconfig, *this)
+ ,m_maincpu(*this, "maincpu")
+ ,m_duscc0(*this, "duscc0")
+ ,m_duscc1(*this, "duscc1")
+ ,m_duscc2(*this, "duscc2")
+ ,m_duscc3(*this, "duscc3")
+ ,m_pit (*this, "pit")
+{
+ LOG("%s %s\n", tag, FUNCNAME);
+}
+
+/* Start it up */
+void vme_fcisio1_card_device::device_start()
+{
+ LOG("%s\n", FUNCNAME);
+ set_vme_device();
+
+ /* Setup pointer to bootvector in ROM for bootvector handler bootvect_r */
+ m_sysrom = (uint16_t*)(memregion ("maincpu")->base () + 0xf00000);
+
+#if 0 // TODO: Setup VME access handlers for shared memory area
+ uint32_t base = 0xFFFF5000;
+ m_vme->install_device(base + 0, base + 1, // Channel B - Data
+ read8_delegate(FUNC(z80sio_device::db_r), subdevice<z80sio_device>("pit")), write8_delegate(FUNC(z80sio_device::db_w), subdevice<z80sio_device>("pit")), 0x00ff);
+ m_vme->install_device(base + 2, base + 3, // Channel B - Control
+ read8_delegate(FUNC(z80sio_device::cb_r), subdevice<z80sio_device>("pit")), write8_delegate(FUNC(z80sio_device::cb_w), subdevice<z80sio_device>("pit")), 0x00ff);
+#endif
+
+}
+
+void vme_fcisio1_card_device::device_reset()
+{
+ LOG("%s\n", FUNCNAME);
+}
+
+/* Boot vector handler, the PCB hardwires the first 8 bytes from 0x80000 to 0x0 */
+READ16_MEMBER (vme_fcisio1_card_device::bootvect_r){
+ return m_sysrom [offset];
+}
+
+READ8_MEMBER (vme_fcisio1_card_device::not_implemented_r){
+ static int been_here = 0;
+ if (!been_here++){
+ logerror(TODO);
+ printf(TODO);
+ }
+ return (uint8_t) 0;
+}
+
+WRITE8_MEMBER (vme_fcisio1_card_device::not_implemented_w){
+ static int been_here = 0;
+ if (!been_here++){
+ logerror(TODO);
+ printf(TODO);
+ }
+ return;
+}
+
+// TODO: Get a manual to understand the config options for real
+READ8_MEMBER (vme_fcisio1_card_device::config_rd){
+ uint8_t ret = 0;
+ LOG("%s\n", FUNCNAME);
+
+ // Port B bit #7, 0x80 Self test bit, choose either of these two lines
+ ret &= ~0x80; // 0 = selftest
+ // ret |= 0x80; // 1 = no selftest
+
+ return ret;
+}
+
+// This info isn't kept in a card driver atm so storing it as a comment for later use
+// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS
+//COMP( 1986, fcisio1, 0, 0, fcisio1, fcisio1, driver_device, 0, "Force Computers Gmbh", "SYS68K/ISIO-1", MACHINE_NOT_WORKING | MACHINE_NO_SOUND_HW | MACHINE_TYPE_COMPUTER )
diff --git a/src/devices/bus/vme/vme_fcisio.h b/src/devices/bus/vme/vme_fcisio.h
new file mode 100644
index 00000000000..1a29283a860
--- /dev/null
+++ b/src/devices/bus/vme/vme_fcisio.h
@@ -0,0 +1,49 @@
+// license:BSD-3-Clause
+// copyright-holders:Joakim Larsson Edstrom
+#ifndef VME_FCISIO_H
+#define VME_FCISIO_H
+#pragma once
+
+#include "machine/scnxx562.h"
+#include "machine/68230pit.h"
+#include "bus/vme/vme.h"
+
+extern const device_type VME_FCISIO1;
+
+class vme_fcisio1_card_device :
+ public device_t
+ ,public device_vme_card_interface
+{
+public:
+ vme_fcisio1_card_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, uint32_t clock, const char *shortname, const char *source);
+ vme_fcisio1_card_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+ // optional information overrides
+ virtual machine_config_constructor device_mconfig_additions() const override;
+ virtual const tiny_rom_entry *device_rom_region() const override;
+
+ DECLARE_READ16_MEMBER (bootvect_r);
+ DECLARE_READ8_MEMBER (config_rd);
+
+ /* Dummy driver routines */
+ DECLARE_READ8_MEMBER (not_implemented_r);
+ DECLARE_WRITE8_MEMBER (not_implemented_w);
+
+protected:
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+private:
+ required_device<cpu_device> m_maincpu;
+ required_device<duscc68562_device> m_duscc0;
+ required_device<duscc68562_device> m_duscc1;
+ required_device<duscc68562_device> m_duscc2;
+ required_device<duscc68562_device> m_duscc3;
+
+ required_device<pit68230_device> m_pit;
+
+ // Pointer to System ROMs needed by bootvect_r
+ uint16_t *m_sysrom;
+};
+
+#endif // VME_FCISIO_H
diff --git a/src/devices/bus/vme/vme_fcscsi.cpp b/src/devices/bus/vme/vme_fcscsi.cpp
new file mode 100644
index 00000000000..3dcf7c17117
--- /dev/null
+++ b/src/devices/bus/vme/vme_fcscsi.cpp
@@ -0,0 +1,539 @@
+// license:BSD-3-Clause
+// copyright-holders:Joakim Larsson Edstrom
+/***************************************************************************
+ * Interrupt scheme and dmac hookup shamelessly based on esq5505.cpp
+ *
+ * 11/04/2016
+ * Force SYS68K ISCSI-1 driver - This driver will be converted into a slot device once the VME bus driver exists.
+ * The ISCSI-1 board is a VME slave board that reads command and returns results through dual ported RAM to the VME bus.
+ *
+ * http://bitsavers.trailing-edge.com/pdf/forceComputers/800114_Force_Introduction_to_the_SYS68K_ISCSI-1_Oct86.pdf
+ *
+ * ||
+ * || ||
+ * ||||--||
+ * ||||--||
+ * || ||__________________________________________________________ ___
+ * || |_| |
+ * || | | |
+ * || | | |
+ * || | | |
+ * || | | |
+ * || | | |
+ * || | |VME|
+ * || | | |
+ * || | |P1 |
+ * || | | |
+ * || | | |
+ * || | | |
+ * || | | |
+ * || | | |
+ * || | | |
+ * || |_| |
+ * || |___|
+ * || |
+ * || |
+ * || |
+ * || |
+ * || |
+ * || |
+ * || |
+ * || |
+ * || |___
+ * || _| |
+ * || | | |
+ * || | | |
+ * || | | |
+ * || | | |
+ * || | |VME|
+ * || | | |
+ * || | |P2 |
+ * || | | |
+ * || | | |
+ * || | | |
+ * || | | |
+ * || | | |
+ * || | | |
+ * || | | |
+ * || | | |
+ * || |_| |
+ * || |___|
+ * || ||------------------------------------------------------------+-+
+ * ||||--||
+ * ||||--||
+ * ||
+ *
+ * History of Force Computers
+ *------------------------------------------------------------------------
+ * See fccpu30.cpp
+ *
+ * Description from datasheet etc
+ * ------------------------------
+ * - 68010 CPU for local control (10MHz)
+ * - 68450 DMA Controller for local transfers (10MHz)
+ * - Dual Ported l28Kbyte 0 wait state static RAM between the VMEbus and the local CPU
+ * - SCSlbus interface built with the NCR 5386S SCSlbus controller.
+ * o Programmable as an initiator or target
+ * o Transfer rate up to 1.5Mbyte/s
+ * - SHUGART compatible floppy interface with the WD1772 FDC. Up to 4 floppy drives can be
+ * controlled independent of the SCSlbus
+ * - All I/O signals available on P2 connector 4 different interrupt request signals to the VMEbus. Each
+ * channel contains a software programmable IRQ level (1 to 7) and vector
+ * - Local parallel interface for controlling and monitoring board functions
+ * - VMEbus Rev.C/IEEE P10l4 compatible interface A24:D16, D8, SYSFAIL (jumper)
+ * - Watchdog timer controlling correct functions of on-board hard and software
+ * - Status and control LEDs for monitoring local activities
+ * - High level handling firmware for communication, self test, data caching/hashing and control
+ *
+ * Address Map
+ * ----------------------------------------------------------
+ * Address Range Description
+ * ----------------------------------------------------------
+ * 000000 - 000007 Initialisation vectors from system EPROM
+ * 000008 - 001FFF Local SRAM
+ * 002000 - 01FFFF Dynamic Dual Port RAM VME bus accessable
+ * C40000 - C4001F SCSIbus controller
+ * C80000 - C800FF DMAC
+ * CC0000 - CC0007 FDC
+ * CC0009 - CC0009 Control Register
+ * D00000 - D0003F PI/T
+ * E00000 - E70000 EPROMs
+ * ----------------------------------------------------------
+ *
+ * VME side A24 address map - Dual ported RAM
+ * ----------------------------------------------------------
+ * Default Range Description
+ * ----------------------------------------------------------
+ * A00000 - A00000 Status word Bits 8:RESET 9:HALT 10:WD
+ * A00001 - A0000F BIM - See below
+ * A01001 - A01001 Read generates local interrupt
+ * A01801 - A01801 Read generates local reset
+ * A02000 - A1FFFF Dynamic Dual Port RAM
+ * ----------------------------------------------------------
+ *
+ * BIM Ctrl Vect Req Toggle PI/T Status PI/T
+ * ch adr adr pin write pin rea
+ * ----------------------------------------------------------
+ * 0 A00001 A00009 PA0 PA4
+ * 1 A00003 A0000B PA1 PA5
+ * 2 A00005 A0000D PA2 PA6
+ * 3 A00007 A0000F PA3 PA7
+ * ----------------------------------------------------------
+ *
+ * Interrupt sources
+ * ----------------------------------------------------------
+ * Description Device Lvl IRQ VME board
+ * /Board Vector Address
+ * ----------------------------------------------------------
+ * On board Sources
+ * ABORT P3 p13 1 AV1
+ * DMA controller 68450 2 DMAC/AV2
+ * SCSI bus controller NCR 5386S 3 AV3
+ * Floppy Disk controller WD 1772 4 AV4
+ * Parallel interface and timer 68230 5 PIT timer
+ * --- 6 ---
+ * Parallel interface and timer 68230 7 PIT port
+ * ----------------------------------------------------------
+ *
+ * TODO:
+ * - Write and attach a NCR5386S SCSI device
+ * - Find a floppy image and present it to the WD1772 floppy controller
+ * - Add VME bus driver
+ * - Let a controller CPU board (eg CPU-1 or CPU-30) boot from floppy or SCSI disk
+ *
+ ****************************************************************************/
+#define TODO "Driver for SCSI NCR5386s device needed\n"
+
+#include "emu.h"
+#include "cpu/m68000/m68000.h"
+#include "machine/68230pit.h"
+#include "machine/wd_fdc.h"
+#include "machine/hd63450.h" // compatible with MC68450
+#include "machine/clock.h"
+#include "formats/pc_dsk.h"
+#include "vme_fcscsi.h"
+
+#define LOG_GENERAL 0x01
+#define LOG_SETUP 0x02
+#define LOG_PRINTF 0x04
+
+#define VERBOSE 0 //(LOG_PRINTF | LOG_SETUP | LOG_GENERAL)
+
+#define LOGMASK(mask, ...) do { if (VERBOSE & mask) logerror(__VA_ARGS__); } while (0)
+#define LOGLEVEL(mask, level, ...) do { if ((VERBOSE & mask) >= level) logerror(__VA_ARGS__); } while (0)
+
+#define LOG(...) LOGMASK(LOG_GENERAL, __VA_ARGS__)
+#define LOGSETUP(...) LOGMASK(LOG_SETUP, __VA_ARGS__)
+
+#if VERBOSE & LOG_PRINTF
+#define logerror printf
+#endif
+
+#ifdef _MSC_VER
+#define FUNCNAME __func__
+#else
+#define FUNCNAME __PRETTY_FUNCTION__
+#endif
+
+//**************************************************************************
+// GLOBAL VARIABLES
+//**************************************************************************
+
+const device_type VME_FCSCSI1 = &device_creator<vme_fcscsi1_card_device>;
+
+#define CPU_CRYSTAL XTAL_20MHz /* Jauch */
+#define PIT_CRYSTAL XTAL_16MHz /* Jauch */
+
+static ADDRESS_MAP_START (fcscsi1_mem, AS_PROGRAM, 16, vme_fcscsi1_card_device)
+ ADDRESS_MAP_UNMAP_HIGH
+ AM_RANGE (0x000000, 0x000007) AM_ROM AM_READ (bootvect_r) /* Vectors mapped from System EPROM */
+ AM_RANGE (0x000008, 0x001fff) AM_RAM /* SRAM */
+ AM_RANGE (0x002000, 0x01ffff) AM_RAM /* Dual Ported RAM */
+ AM_RANGE (0xe00000, 0xe7ffff) AM_ROM /* System EPROM Area 32Kb DEBUGGER supplied */
+ AM_RANGE (0xd00000, 0xd0003f) AM_DEVREADWRITE8 ("pit", pit68230_device, read, write, 0x00ff)
+// AM_RANGE (0xc40000, 0xc4001f) AM_DEVREADWRITE8("scsi", ncr5386_device, read, write, 0x00ff) /* SCSI Controller interface - device support not yet available*/
+ AM_RANGE (0xc40000, 0xc4001f) AM_READWRITE8 (scsi_r, scsi_w, 0x00ff)
+ AM_RANGE (0xc80000, 0xc800ff) AM_DEVREADWRITE("mc68450", hd63450_device, read, write) /* DMA Controller interface */
+ AM_RANGE (0xcc0000, 0xcc0007) AM_DEVREADWRITE8("fdc", wd1772_t, read, write, 0x00ff) /* Floppy Controller interface */
+ AM_RANGE (0xcc0008, 0xcc0009) AM_READWRITE8 (tcr_r, tcr_w, 0x00ff) /* The Control Register, SCSI ID and FD drive select bits */
+ADDRESS_MAP_END
+
+
+FLOPPY_FORMATS_MEMBER( vme_fcscsi1_card_device::floppy_formats )
+ FLOPPY_PC_FORMAT
+FLOPPY_FORMATS_END
+
+static SLOT_INTERFACE_START( fcscsi_floppies )
+ SLOT_INTERFACE( "525qd", FLOPPY_525_QD )
+SLOT_INTERFACE_END
+
+/*
+ * Machine configuration
+ */
+static MACHINE_CONFIG_FRAGMENT (fcscsi1)
+ /* basic machine hardware */
+ MCFG_CPU_ADD ("maincpu", M68010, CPU_CRYSTAL / 2) /* 7474 based frequency divide by 2 */
+ MCFG_CPU_PROGRAM_MAP (fcscsi1_mem)
+ MCFG_CPU_IRQ_ACKNOWLEDGE_DRIVER(vme_fcscsi1_card_device, maincpu_irq_acknowledge_callback)
+
+ /* FDC */
+ MCFG_WD1772_ADD("fdc", PIT_CRYSTAL / 2)
+ MCFG_WD_FDC_INTRQ_CALLBACK(WRITE8(vme_fcscsi1_card_device, fdc_irq))
+ MCFG_WD_FDC_DRQ_CALLBACK(DEVWRITELINE("mc68450", hd63450_device, drq1_w))
+ MCFG_FLOPPY_DRIVE_ADD("fdc:0", fcscsi_floppies, "525qd", vme_fcscsi1_card_device::floppy_formats)
+ MCFG_FLOPPY_DRIVE_ADD("fdc:1", fcscsi_floppies, "525qd", vme_fcscsi1_card_device::floppy_formats)
+ MCFG_FLOPPY_DRIVE_ADD("fdc:2", fcscsi_floppies, "525qd", vme_fcscsi1_card_device::floppy_formats)
+ MCFG_FLOPPY_DRIVE_ADD("fdc:3", fcscsi_floppies, "525qd", vme_fcscsi1_card_device::floppy_formats)
+
+ /* PIT Parallel Interface and Timer device */
+ MCFG_DEVICE_ADD ("pit", PIT68230, PIT_CRYSTAL / 2) /* 7474 based frequency divide by 2 */
+ MCFG_PIT68230_PB_OUTPUT_CB(WRITE8(vme_fcscsi1_card_device, led_w))
+
+ /* DMAC it is really a M68450 but the HD63850 is upwards compatible */
+ MCFG_DEVICE_ADD("mc68450", HD63450, 0) // MC68450 compatible
+ MCFG_HD63450_CPU("maincpu") // CPU - 68010
+ MCFG_HD63450_CLOCKS(attotime::from_usec(32), attotime::from_nsec(450), attotime::from_usec(4), attotime::from_hz(15625/2))
+ MCFG_HD63450_BURST_CLOCKS(attotime::from_usec(32), attotime::from_nsec(450), attotime::from_nsec(50), attotime::from_nsec(50))
+ MCFG_HD63450_DMA_END_CB(WRITE8(vme_fcscsi1_card_device, dma_end))
+ MCFG_HD63450_DMA_ERROR_CB(WRITE8(vme_fcscsi1_card_device, dma_error))
+ //MCFG_HD63450_DMA_READ_0_CB(READ8(vme_fcscsi1_card_device, scsi_read_byte)) // ch 0 = SCSI
+ //MCFG_HD63450_DMA_WRITE_0_CB(WRITE8(vme_fcscsi1_card_device, scsi_write_byte))
+ MCFG_HD63450_DMA_READ_1_CB(READ8(vme_fcscsi1_card_device, fdc_read_byte)) // ch 1 = fdc
+ MCFG_HD63450_DMA_WRITE_1_CB(WRITE8(vme_fcscsi1_card_device, fdc_write_byte))
+MACHINE_CONFIG_END
+
+/* ROM definitions */
+ROM_START (fcscsi1)
+ ROM_REGION (0x1000000, "maincpu", 0)
+
+ /* Besta ROM:s - apparantly patched Force ROM:s */
+ ROM_SYSTEM_BIOS(0, "Besta 88", "Besta 88")
+ ROMX_LOAD ("besta88_scsi_lower.ROM", 0xe00001, 0x4000, CRC (fb3ab364) SHA1 (d79112100f1c4beaf358e006efd4dde5e300b0ba), ROM_SKIP(1) | ROM_BIOS(1))
+ ROMX_LOAD ("besta88_scsi_upper.ROM", 0xe00000, 0x4000, CRC (41f9cdf4) SHA1 (66b998bbf9459f0a613718260e05e97749532073), ROM_SKIP(1) | ROM_BIOS(1))
+
+ /* Force ROM:s */
+ ROM_SYSTEM_BIOS(1, "ISCSI-1 v3.7", "Force Computer SYS68K/ISCSI-1 firmware v3.7")
+ ROMX_LOAD ("ISCSI-1_V3.7_L.BIN", 0xe00001, 0x4000, CRC (83d95ab7) SHA1 (bf249910bcb6cb0b04dda2a95a38a0f90b553352), ROM_SKIP(1) | ROM_BIOS(2))
+ ROMX_LOAD ("ISCSI-1_V3.7_U.BIN", 0xe00000, 0x4000, CRC (58815831) SHA1 (074085ef96e1fe2a551938bdeee6a9cab40ff09c), ROM_SKIP(1) | ROM_BIOS(2))
+
+ROM_END
+
+
+machine_config_constructor vme_fcscsi1_card_device::device_mconfig_additions() const
+{
+ LOG("%s %s\n", tag(), FUNCNAME);
+ return MACHINE_CONFIG_NAME( fcscsi1 );
+}
+
+const tiny_rom_entry *vme_fcscsi1_card_device::device_rom_region() const
+{
+ LOG("%s\n", FUNCNAME);
+ return ROM_NAME( fcscsi1 );
+}
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+vme_fcscsi1_card_device::vme_fcscsi1_card_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, uint32_t clock, const char *shortname, const char *source) :
+ device_t(mconfig, type, name, tag, owner, clock, shortname, source)
+ ,device_vme_card_interface(mconfig, *this)
+ ,m_maincpu (*this, "maincpu")
+ ,m_fdc (*this, "fdc")
+ ,m_pit (*this, "pit")
+ ,m_dmac(*this, "mc68450")
+ ,m_tcr (0)
+{
+ LOG("%s\n", FUNCNAME);
+}
+
+vme_fcscsi1_card_device::vme_fcscsi1_card_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
+ device_t(mconfig, VME_FCSCSI1, "Force Computer SYS68K/ISCSI-1 Intelligent Mass Storage Controller Board", tag, owner, clock, "fcscsi1", __FILE__)
+ ,device_vme_card_interface(mconfig, *this)
+ ,m_maincpu(*this, "maincpu")
+ ,m_fdc(*this, "fdc")
+ ,m_pit(*this, "pit")
+ ,m_dmac(*this, "mc68450")
+ ,m_tcr(0)
+{
+ LOG("%s\n", FUNCNAME);
+}
+
+/* Start it up */
+void vme_fcscsi1_card_device::device_start()
+{
+ LOG("%s\n", FUNCNAME);
+ set_vme_device();
+
+ /* Setup pointer to bootvector in ROM for bootvector handler bootvect_r */
+ m_sysrom = (uint16_t*)(memregion ("maincpu")->base () + 0xe00000);
+
+#if 0 // TODO: Setup VME access handlers for shared memory area
+ uint32_t base = 0x00A00000;
+ m_vme->install_device(base + 0, base + 1, // Channel B - Data
+ read8_delegate(FUNC(z80sio_device::db_r), subdevice<z80sio_device>("pit")), write8_delegate(FUNC(z80sio_device::db_w), subdevice<z80sio_device>("pit")), 0x00ff);
+ m_vme->install_device(base + 2, base + 3, // Channel B - Control
+ read8_delegate(FUNC(z80sio_device::cb_r), subdevice<z80sio_device>("pit")), write8_delegate(FUNC(z80sio_device::cb_w), subdevice<z80sio_device>("pit")), 0x00ff);
+#endif
+
+}
+
+void vme_fcscsi1_card_device::device_reset()
+{
+ LOG("%s\n", FUNCNAME);
+}
+
+/* Boot vector handler, the PCB hardwires the first 8 bytes from 0x80000 to 0x0 */
+READ16_MEMBER (vme_fcscsi1_card_device::bootvect_r){
+ return m_sysrom [offset];
+}
+
+/* The Control Register - discretely implemented on the PCB
+Bit #: 7 6 5 4 3 2 1 0
+ \ \ \ \ \ \ \ \ Floppy Disk Side Select
+ \ \ \ \ \ \ \ Floppy Disk Drive Select 0
+ \ \ \ \ \ \ Floppy Disk Drive Select 1
+ \ \ \ \ \ Floppy Disk Drive Select 2
+ \ \ \ \ Floppy Disk Drive Select 3
+ \ \ \ ISCSI-l I.D. Bit #0
+ \ \ ISCSI-l I.D. Bit #1
+ \ ISCSI-l 1.D. Bit #2
+*/
+
+READ8_MEMBER (vme_fcscsi1_card_device::tcr_r){
+ LOG("%s\n", FUNCNAME);
+ return (uint8_t) m_tcr;
+}
+
+WRITE8_MEMBER (vme_fcscsi1_card_device::tcr_w){
+ floppy_image_device *floppy0 = m_fdc->subdevice<floppy_connector>("0")->get_device();
+ floppy_image_device *floppy1 = m_fdc->subdevice<floppy_connector>("1")->get_device();
+ floppy_image_device *floppy2 = m_fdc->subdevice<floppy_connector>("2")->get_device();
+ floppy_image_device *floppy3 = m_fdc->subdevice<floppy_connector>("3")->get_device();
+ floppy_image_device *floppy = nullptr;
+
+ if (!BIT(data, 1)) floppy = floppy0;
+ else
+ if (!BIT(data, 2)) floppy = floppy1;
+ else
+ if (!BIT(data, 3)) floppy = floppy2;
+ else
+ if (!BIT(data, 4)) floppy = floppy3;
+
+ if (floppy) {
+ m_fdc->set_floppy(floppy);
+ floppy->ss_w(!BIT(data, 0));
+ floppy->mon_w(0);
+ } else {
+ floppy0->mon_w(1);
+ floppy1->mon_w(1);
+ floppy2->mon_w(1);
+ floppy3->mon_w(1);
+ }
+
+ LOG("%s [%02x]\n", FUNCNAME, data);
+ m_tcr = data;
+ return;
+}
+
+WRITE8_MEMBER (vme_fcscsi1_card_device::led_w){
+ LOG("%s [%02x]\n", FUNCNAME, data);
+
+ m_fdc->dden_w(BIT(data, 7));
+
+ return;
+}
+
+WRITE8_MEMBER(vme_fcscsi1_card_device::dma_end)
+{
+ if (data != 0)
+ {
+ dmac_irq_state = 1;
+ dmac_irq_vector = m_dmac->get_vector(offset);
+ }
+ else
+ {
+ dmac_irq_state = 0;
+ }
+
+ update_irq_to_maincpu();
+}
+
+WRITE8_MEMBER(vme_fcscsi1_card_device::dma_error)
+{
+ if(data != 0)
+ {
+ logerror("DMAC error, vector = %x\n", m_dmac->get_error_vector(offset));
+ dmac_irq_state = 1;
+ dmac_irq_vector = m_dmac->get_vector(offset);
+ }
+ else
+ {
+ dmac_irq_state = 0;
+ }
+
+ update_irq_to_maincpu();
+}
+
+WRITE8_MEMBER(vme_fcscsi1_card_device::fdc_irq)
+{
+ if (data != 0)
+ {
+ fdc_irq_state = 1;
+ }
+ else
+ {
+ fdc_irq_state = 0;
+ }
+ update_irq_to_maincpu();
+}
+
+READ8_MEMBER(vme_fcscsi1_card_device::fdc_read_byte)
+{
+ return m_fdc->data_r();
+}
+
+WRITE8_MEMBER(vme_fcscsi1_card_device::fdc_write_byte)
+{
+ m_fdc->data_w(data & 0xff);
+}
+
+READ8_MEMBER(vme_fcscsi1_card_device::scsi_r)
+{
+ uint8_t data = 0;
+
+ // fake diag status
+ if (offset == 9)
+ data = 0x80;
+
+ LOG("scsi R %02x == %02x\n", offset, data);
+
+ return data;
+}
+
+WRITE8_MEMBER(vme_fcscsi1_card_device::scsi_w)
+{
+ LOG("scsi W %02x <- %02x\n", offset, data);
+}
+
+READ8_MEMBER (vme_fcscsi1_card_device::not_implemented_r){
+ static int been_here = 0;
+ if (!been_here++){
+ logerror(TODO);
+ printf(TODO);
+ }
+ return (uint8_t) 0;
+}
+
+WRITE8_MEMBER (vme_fcscsi1_card_device::not_implemented_w){
+ static int been_here = 0;
+ if (!been_here++){
+ logerror(TODO);
+ printf(TODO);
+ }
+ return;
+}
+
+/*
+----------------------------------------------------
+ IRQ IRQ
+Level Source B4l inserted B4l removed (Def)
+-----------------------------------------------------
+ 1 P3 Pin #13 AV1 Autovector AV1 Autovector
+ 2 DMAC DMAC AV2 Autovector
+ 3 SCSIBC AV3 Autovector AV3 Autovector
+ 4 FDC AV4 Autovector AV4 Autovector
+ 5 PI/T Timer PI/T Timer Vect PI/T Timer Vect
+ 6 -- -- --
+ 7 PI/T Port PI/T Port Vect PI/T Port Vect
+------------------------------------------------------
+Default configuration: B41 jumper removed
+
+The PI/T port interrupt can be used under software control to
+cause non-maskable (Level 7) interrupts if the watchdog timer
+elapses and/or if the VMEbus interrupt trigger call occurs.
+*/
+
+/* TODO: Add configurable B41 jumper */
+#define B41 0
+
+void vme_fcscsi1_card_device::update_irq_to_maincpu() {
+ if (fdc_irq_state) {
+ m_maincpu->set_input_line(M68K_IRQ_3, ASSERT_LINE);
+ m_maincpu->set_input_line(M68K_IRQ_2, CLEAR_LINE);
+ m_maincpu->set_input_line(M68K_IRQ_1, CLEAR_LINE);
+ } else if (dmac_irq_state) {
+ m_maincpu->set_input_line(M68K_IRQ_3, CLEAR_LINE);
+ m_maincpu->set_input_line(M68K_IRQ_1, CLEAR_LINE);
+#if B41 == 1
+ m_maincpu->set_input_line_and_vector(M68K_IRQ_2, ASSERT_LINE, dmac_irq_vector);
+#else
+ m_maincpu->set_input_line(M68K_IRQ_2, ASSERT_LINE);
+#endif
+ } else {
+ m_maincpu->set_input_line(M68K_IRQ_3, CLEAR_LINE);
+ m_maincpu->set_input_line(M68K_IRQ_2, CLEAR_LINE);
+ m_maincpu->set_input_line(M68K_IRQ_1, CLEAR_LINE);
+ }
+}
+
+IRQ_CALLBACK_MEMBER(vme_fcscsi1_card_device::maincpu_irq_acknowledge_callback)
+{
+ // We immediately update the interrupt presented to the CPU, so that it doesn't
+ // end up retrying the same interrupt over and over. We then return the appropriate vector.
+ int vector = 0;
+ switch(irqline) {
+ case 2:
+ dmac_irq_state = 0;
+ vector = dmac_irq_vector;
+ break;
+ default:
+ logerror("\nUnexpected IRQ ACK Callback: IRQ %d\n", irqline);
+ return 0;
+ }
+ update_irq_to_maincpu();
+ return vector;
+}
+
+// This info isn't kept in a card driver atm so storing it as a comment for later use
+// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS
+//COMP( 1986, fcscsi1, 0, 0, fcscsi1, fcscsi1, driver_device, 0, "Force Computers Gmbh", "SYS68K/SCSI-1", MACHINE_IS_SKELETON )
diff --git a/src/devices/bus/vme/vme_fcscsi.h b/src/devices/bus/vme/vme_fcscsi.h
new file mode 100644
index 00000000000..719f12df5b6
--- /dev/null
+++ b/src/devices/bus/vme/vme_fcscsi.h
@@ -0,0 +1,73 @@
+// license:BSD-3-Clause
+// copyright-holders:Joakim Larsson Edstrom
+#ifndef VME_FCSCSI_H
+#define VME_FCSCSI_H
+#pragma once
+
+#include "machine/68230pit.h"
+#include "machine/wd_fdc.h"
+#include "machine/hd63450.h" // compatible with MC68450
+#include "bus/vme/vme.h"
+
+extern const device_type VME_FCSCSI1;
+
+class vme_fcscsi1_card_device :
+ public device_t
+ ,public device_vme_card_interface
+{
+public:
+ vme_fcscsi1_card_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, uint32_t clock, const char *shortname, const char *source);
+ vme_fcscsi1_card_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+ // optional information overrides
+ virtual machine_config_constructor device_mconfig_additions() const override;
+ virtual const tiny_rom_entry *device_rom_region() const override;
+
+ DECLARE_READ16_MEMBER (bootvect_r);
+ DECLARE_READ8_MEMBER (tcr_r);
+ DECLARE_WRITE8_MEMBER (tcr_w);
+ DECLARE_WRITE8_MEMBER (led_w);
+
+ IRQ_CALLBACK_MEMBER(maincpu_irq_acknowledge_callback);
+
+ //dmac
+ DECLARE_WRITE8_MEMBER(dma_end);
+ DECLARE_WRITE8_MEMBER(dma_error);
+
+ //fdc
+ DECLARE_WRITE8_MEMBER(fdc_irq);
+ DECLARE_READ8_MEMBER(fdc_read_byte);
+ DECLARE_WRITE8_MEMBER(fdc_write_byte);
+ DECLARE_FLOPPY_FORMATS(floppy_formats);
+
+ /* Dummy driver routines */
+ DECLARE_READ8_MEMBER (not_implemented_r);
+ DECLARE_WRITE8_MEMBER (not_implemented_w);
+
+ DECLARE_READ8_MEMBER (scsi_r);
+ DECLARE_WRITE8_MEMBER (scsi_w);
+
+ uint8_t fdc_irq_state;
+ uint8_t dmac_irq_state;
+ int dmac_irq_vector;
+
+ void update_irq_to_maincpu();
+
+protected:
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+private:
+ required_device<cpu_device> m_maincpu;
+ required_device<wd1772_t> m_fdc;
+ required_device<pit68230_device> m_pit;
+ required_device<hd63450_device> m_dmac;
+
+ uint8_t m_tcr;
+
+ // Pointer to System ROMs needed by bootvect_r
+ uint16_t *m_sysrom;
+};
+
+#endif // VME_FCSCSI_H
+
diff --git a/src/devices/bus/vme/vme_mvme350.c b/src/devices/bus/vme/vme_mvme350.c
deleted file mode 100644
index 69bbbe618d7..00000000000
--- a/src/devices/bus/vme/vme_mvme350.c
+++ /dev/null
@@ -1,257 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Joakim Larsson Edstrom
-/***************************************************************************
- *
- * Motorola MVME-350 6U Intelligent Tape Controller driver, initially derived
- * from hk68v10.c
- *
- * 31/08/2015
- *
- * I baught this board from http://www.retrotechnology.com without documentation.
- * It has a Motorola 68010 CPU @ 10MHz, 128 Mb RAM and two 2764 EPROMS with
- * QIC-02 tape controller firmware. The board also populates a 68230 PIT and loads
- * of descrete TTL components.
- *
- *
- * ||
- * || ||
- * ||||--||
- * ||||--||
- * || ||__________________________________________________________ ___
- * ||_______________________________________________________ |_| |
- * || |74F74 | xxxxx | xxxxx | 74LS245 | 74ALS645| | | |
- * || |______|________|_________|___________| ________| | | |
- * || |74F74 | xxxxx | xxxxx | 74LS245 | 74ALS645| | | |
- * || |______|________|_________|___________| ________| | | |
- * || |74LS02| 74LS08||Am25LS251| 74S38 |74LS20|Jumpers | | |
- * || |______|_______||_________|_______|______|______| | |VME|
- * || |74F04 | 74LS32||74LS374 | 74LS374 |74S244 | | | |
- * ||+---+ |______|_______||_________|___________|_________| | |P1 |
- * |||CON| |74F04 | 74LS85||74S244 | 74S240 |PAL | | | |
- * ||| | |______|_______||_________|___________|_________| | | |
- * ||| | |74LS04| | |74S244 | | | |
- * ||| | |______| | PIT |_________| | | |
- * ||| | |74LS125 | MC68230L10 |74LS145 | | | |
- * ||| | |______| __|_______________________|---------| | | |
- * ||| | |74LS74| |25LS251 | | RAM |74S244 | |_| |
- * ||+---+ ---------- |---------- | HM6264P-12 |---------| |___|
- * || | PAL | | 74245 | |______________|74S244 | |
- * || +--------- |_________| | U40 27128 |---------| |
- * || | 74F32 | | || System ROM |74LS682 | |
- * Red || +-------- | CPU || |-+-------| |
- * FAIL ||LED | 74F138| | MC68010 |+--------------+ |DIPSW__| |
- * Red || +-------- | || RAM | |74S38 | |
- * HALT ||LED | 74F32 | |__________|| HM6264P-12 | |______ | |
- * Green || +-------+ |74245 |+--------------+ |74F08 | |
- * RUN ||LED |XTAL | |__________|| U47 27128 | |______ | |___
- * ||+---+|20MHz | |74244 || System ROM | |74F00 | _| |
- * |||CON|--------+___|__________|+--------------+_|_______| | | |
- * ||| |74LS08 |74F74 |74LS148| |PAL | | PAL | | | |
- * ||| |________|________|_______| |________|_|_________| | | |
- * ||| | 74LS138|74F32 | PAL | |74F74 |Am29823 | | | |
- * ||| |________|________|_______| |________|-+---------| | |VME|
- * ||| | 74LS11 |74F04 |74LS374| |74LS374 | |74S240 | | | |
- * ||| |________|________|_______| |________|_|---------| | |P2 |
- * ||| | 74F138 |BLANK |74LS374| |74LS374 |74S240 | | | |
- * ||| |________|________|_______| +----------+---------| | | |
- * ||| | 74LS08 |74F32 |74LS11|74LS393|74LS393|resistors | | |
- * ||| |________|________|______|______ |_______|________| | | |
- * ||| |DM2585 |74F74 |DM2230| 74LS00| 74F02 |74F32 | | | |
- * ||+---+--------+--------+------+-------+---------+------| | | |
- * || |74LS74 |74F20 |74S260| 74S74 | 74F08 |74LS02| | | |
- * || +------------------------------------------+------| | | |
- * || |DM2353 |74F10 |74F32 | 74LS32| 74F08 |DM2353| |_| |
- * || +------------------------------------------+------+-+ |___|
- * || ||------------------------------------------------------------+-+
- * ||||--||
- * ||||--||
- * ||
- *
- * History of Motorola VME division (https://en.wikipedia.org/wiki/VMEbus)
- *---------------------------------
- * When Motorola released the 68000 processor 1979 the ambition of the deisgners
- * was also to standardize a versatile CPU bus to be able to build computer
- * systems without constructing PCB:s from scratch. This become VersaBus but the
- * boards was really too big and the computer world already saw the systems shrink
- * in size. Motorola's design center in Munich proposed to use the smaller and
- * already used Euroboard form factor and call it Versabus-E. This later became
- * VME which was standardized in the VITA organization 1981
- *
- * Misc links about Motorola VME division and this board:
- * http://bitsavers.trailing-edge.com/pdf/motorola/_dataBooks/1987_Microcomputer_Systems_and_Components.pdf
- *
- * Description
- * ------------
- * Streaming Tape Controller released 1984 with the following feature set
- *
- * - Double High (6U) VMEmodule
- * - QIC-02 Streaming Tape Interface
- * - Supports One 01C-02 compatible 1/4-inch Streaming Tape Drive
- * - Standard VMEbus Interface
- * - Supports 24- or 32-bit DMA Addressing/16-bit Data
- * - Generates Seven Levels of VMEbus Interrupts with Programmable Interrupt Vector
- * - 10 MHz MC68010 Microprocessor
- * - 90Kb/s Continuous Transfer Rate for QIC-02 Interface, 200Kb/s Burst rate
- * - Controls Tape Cartridges Offering 20Mb, 45Mb and 60Mb of Formatted Data Storage
- * - MC68230 PIT-based Timer
- * - 16Kb of Static RAM Provides Buffer Storage and CPU Workspace
- * - Multitasking Kernel-based Firmware Package
- * - Buffered Pipe Communication Protocol Allows Multiple Hosts to Oueue Commands Without Interlock
- * - High Level Command/Status Packets offer efficient Operating System Support
- * - Permits Chaining of Host Command
- *
- * Address Map
- * --------------------------------------------------------------------------
- * Local to VME Decscription
- * --------------------------------------------------------------------------
- * 0x000000 Up to 128Kb System ROM with RESET vector
- * 0x020000 RAM with vectors
- * 0x020500 RAM Top of stack
- * 0x040000 PIT device?
- * 0x060000 RAM?
- * 0x080000 PIT device?
- * --------------------------------------------------------------------------
- *
- * Interrupt sources MVME
- * ----------------------------------------------------------
- * Description Device Lvl IRQ VME board
- * /Board Vector Address
- * ----------------------------------------------------------
- * On board Sources
- *
- * Off board Sources (other VME boards)
- *
- * ----------------------------------------------------------
- *
- * DMAC Channel Assignments
- * ----------------------------------------------------------
- * Channel M10 V10
- * ----------------------------------------------------------
- *
- *
- * TODO:
- * - Dump the ROMs (DONE)
- * - Setup a working address map (STARTED)
- * - Get documentation for VME interface
- * - Add VME bus driver
- * - Hook up a CPU board that supports boot from tape (ie MVME-162, MVME 147)
- * - Get a tape file with a bootable data on it.
- *
- ****************************************************************************/
-
-#include "emu.h"
-#include "cpu/m68000/m68000.h"
-#include "machine/68230pit.h"
-
-#define LOG(x) x
-
-class mvme350_state : public driver_device
-{
-public:
-mvme350_state(const machine_config &mconfig, device_type type, const char *tag) :
- driver_device (mconfig, type, tag),
- m_maincpu (*this, "maincpu"),
- m_pit(*this, "pit")
-{
-}
-
-DECLARE_READ16_MEMBER (vme_a24_r);
-DECLARE_WRITE16_MEMBER (vme_a24_w);
-DECLARE_READ16_MEMBER (vme_a16_r);
-DECLARE_WRITE16_MEMBER (vme_a16_w);
-virtual void machine_start ();
-virtual void machine_reset ();
-protected:
-
-private:
- required_device<cpu_device> m_maincpu;
- required_device<pit68230_device> m_pit;
-
-};
-
-static ADDRESS_MAP_START (mvme350_mem, AS_PROGRAM, 16, mvme350_state)
-ADDRESS_MAP_UNMAP_HIGH
- AM_RANGE (0x000000, 0x01ffff) AM_ROM /* 128 Mb ROM */
- AM_RANGE (0x020000, 0x03ffff) AM_RAM /* 128 Mb RAM */
-#if 1
- AM_RANGE(0x040000, 0x040035) AM_DEVREADWRITE8("pit", pit68230_device, read, write, 0x00ff) /* PIT ?*/
- AM_RANGE(0x060000, 0x06001f) AM_RAM /* Area is cleared on start */
- AM_RANGE(0x080000, 0x080035) AM_DEVREADWRITE8("pit", pit68230_device, read, write, 0x00ff) /* PIT ?*/
-#endif
-//AM_RANGE(0x100000, 0xfeffff) AM_READWRITE(vme_a24_r, vme_a24_w) /* VMEbus Rev B addresses (24 bits) - not verified */
-//AM_RANGE(0xff0000, 0xffffff) AM_READWRITE(vme_a16_r, vme_a16_w) /* VMEbus Rev B addresses (16 bits) - not verified */
-ADDRESS_MAP_END
-
-/* Input ports */
-static INPUT_PORTS_START (mvme350)
-INPUT_PORTS_END
-
-/* Start it up */
-void mvme350_state::machine_start ()
-{
- LOG (logerror ("machine_start\n"));
-}
-
-void mvme350_state::machine_reset ()
-{
- LOG (logerror ("machine_reset\n"));
-}
-
-#if 0
-/* Dummy VME access methods until the VME bus device is ready for use */
-READ16_MEMBER (mvme350_state::vme_a24_r){
- LOG (logerror ("vme_a24_r\n"));
- return (uint16_t) 0;
-}
-
-WRITE16_MEMBER (mvme350_state::vme_a24_w){
- LOG (logerror ("vme_a24_w\n"));
-}
-
-READ16_MEMBER (mvme350_state::vme_a16_r){
- LOG (logerror ("vme_16_r\n"));
- return (uint16_t) 0;
-}
-
-WRITE16_MEMBER (mvme350_state::vme_a16_w){
- LOG (logerror ("vme_a16_w\n"));
-}
-#endif
-
-/*
- * Machine configuration
- */
-static MACHINE_CONFIG_START (mvme350, mvme350_state)
- /* basic machine hardware */
- MCFG_CPU_ADD ("maincpu", M68010, XTAL_10MHz)
- MCFG_CPU_PROGRAM_MAP (mvme350_mem)
- /* PIT Parallel Interface and Timer device, assuming strapped for on board clock */
- MCFG_DEVICE_ADD("pit", PIT68230, XTAL_16MHz / 2)
-
-MACHINE_CONFIG_END
-
-/* ROM definitions */
-ROM_START (mvme350)
-ROM_REGION (0x1000000, "maincpu", 0)
-
-ROM_LOAD16_BYTE ("mvme350U40v2.3.bin", 0x0000, 0x4000, CRC (bcef82ef) SHA1 (e6fdf26e4714cbaeb3e97d7b5acf02d64d8ad744))
-ROM_LOAD16_BYTE ("mvme350U47v2.3.bin", 0x0001, 0x4000, CRC (582ce095) SHA1 (d0929dbfeb0cfda63df6b5bc29ee27fbf665def7))
-
-/*
- * System ROM information
- *
- * The ROMs known commands from different sources:
- *
- * It communicates with the master through data buffers in shared memory and VME bus interrupts
- * as desribed in
- * http://bitsavers.trailing-edge.com/pdf/motorola/_dataBooks/1987_Microcomputer_Systems_and_Components.pdf
- *
- * The board is pretty boring as stand alone, it initializes everything and then executes a STOP instruction
- * awaiting a CPU on the VME bus to request its services. However, it enables boot from tape devices, we just
- * need a MVME-131 and a dump of a VersaDOS or Motorola UNIX System V system tape and some work.
- */
-ROM_END
-
-/* Driver */
-/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */
-COMP (1984, mvme350, 0, 0, mvme350, mvme350, driver_device, 0, "Motorola", "MVME-350", MACHINE_NO_SOUND_HW | MACHINE_TYPE_COMPUTER )
diff --git a/src/mame/drivers/mvme350.cpp b/src/devices/bus/vme/vme_mvme350.cpp
index 624cdad5d00..69afff9490a 100644
--- a/src/mame/drivers/mvme350.cpp
+++ b/src/devices/bus/vme/vme_mvme350.cpp
@@ -2,8 +2,7 @@
// copyright-holders:Joakim Larsson Edstrom
/***************************************************************************
*
- * Motorola MVME-350 6U Intelligent Tape Controller driver, initially derived
- * from hk68v10.c
+ * Motorola MVME-350 6U Intelligent Tape Controller driver
*
* 31/08/2015
*
@@ -68,17 +67,8 @@
* ||
*
* History of Motorola VME division (https://en.wikipedia.org/wiki/VMEbus)
- *---------------------------------
- * When Motorola released the 68000 processor 1979 the ambition of the deisgners
- * was also to standardize a versatile CPU bus to be able to build computer
- * systems without constructing PCB:s from scratch. This become VersaBus but the
- * boards was really too big and the computer world already saw the systems shrink
- * in size. Motorola's design center in Munich proposed to use the smaller and
- * already used Euroboard form factor and call it Versabus-E. This later became
- * VME which was standardized in the VITA organization 1981
- *
- * Misc links about Motorola VME division and this board:
- * http://bitsavers.trailing-edge.com/pdf/motorola/_dataBooks/1987_Microcomputer_Systems_and_Components.pdf
+ *------------------------------------------------------------------------
+ * See mvme147.cpp
*
* Description
* ------------
@@ -110,6 +100,8 @@
* 0x040000 PIT device?
* 0x060000 RAM?
* 0x080000 PIT device?
+ * 0xffff5000 MVME350 - Streaming Tape Controller CLUN $04 - From MVME-166 installation manual
+ * 0xffff5100 MVME350 - Streaming Tape Controller CLUN $05 probably base of shared RAM
* --------------------------------------------------------------------------
*
* Interrupt sources MVME
@@ -123,17 +115,13 @@
*
* ----------------------------------------------------------
*
- * DMAC Channel Assignments
- * ----------------------------------------------------------
- * Channel M10 V10
- * ----------------------------------------------------------
- *
- *
* TODO:
* - Dump the ROMs (DONE)
* - Setup a working address map (STARTED)
* - Get documentation for VME interface
* - Add VME bus driver
+ * - Hook up the PITs correctly
+ * - Add a configurable shared memory window between local CPU and the VME bus
* - Hook up a CPU board that supports boot from tape (ie MVME-162, MVME 147)
* - Get a tape file with a bootable data on it.
*
@@ -142,116 +130,139 @@
#include "emu.h"
#include "cpu/m68000/m68000.h"
#include "machine/68230pit.h"
+#include "vme_mvme350.h"
-#define LOG(x) x
+#define LOG_GENERAL 0x01
+#define LOG_SETUP 0x02
+#define LOG_PRINTF 0x04
-class mvme350_state : public driver_device
-{
-public:
-mvme350_state(const machine_config &mconfig, device_type type, const char *tag) :
- driver_device (mconfig, type, tag),
- m_maincpu (*this, "maincpu"),
- m_pit(*this, "pit")
-{
-}
+#define VERBOSE 0 //(LOG_PRINTF | LOG_SETUP | LOG_GENERAL)
+
+#define LOGMASK(mask, ...) do { if (VERBOSE & mask) logerror(__VA_ARGS__); } while (0)
+#define LOGLEVEL(mask, level, ...) do { if ((VERBOSE & mask) >= level) logerror(__VA_ARGS__); } while (0)
+
+#define LOG(...) LOGMASK(LOG_GENERAL, __VA_ARGS__)
+#define LOGSETUP(...) LOGMASK(LOG_SETUP, __VA_ARGS__)
+
+#if VERBOSE & LOG_PRINTF
+#define logerror printf
+#endif
+
+#ifdef _MSC_VER
+#define FUNCNAME __func__
+#else
+#define FUNCNAME __PRETTY_FUNCTION__
+#endif
-//DECLARE_READ16_MEMBER (vme_a24_r);
-//DECLARE_WRITE16_MEMBER (vme_a24_w);
-//DECLARE_READ16_MEMBER (vme_a16_r);
-//DECLARE_WRITE16_MEMBER (vme_a16_w);
-virtual void machine_start () override;
-virtual void machine_reset () override;
-protected:
+//**************************************************************************
+// GLOBAL VARIABLES
+//**************************************************************************
-private:
- required_device<cpu_device> m_maincpu;
- required_device<pit68230_device> m_pit;
+const device_type VME_MVME350 = &device_creator<vme_mvme350_card_device>;
-};
+#define MVME350_CPU_TAG "mvme350_cpu"
+#define MVME350_ROM "mvme350_rom"
-static ADDRESS_MAP_START (mvme350_mem, AS_PROGRAM, 16, mvme350_state)
-ADDRESS_MAP_UNMAP_HIGH
- AM_RANGE (0x000000, 0x01ffff) AM_ROM /* 128 Mb ROM */
- AM_RANGE (0x020000, 0x03ffff) AM_RAM /* 128 Mb RAM */
-#if 1
- AM_RANGE(0x040000, 0x040035) AM_DEVREADWRITE8("pit", pit68230_device, read, write, 0x00ff) /* PIT ?*/
- AM_RANGE(0x060000, 0x06001f) AM_RAM /* Area is cleared on start */
- AM_RANGE(0x080000, 0x080035) AM_DEVREADWRITE8("pit", pit68230_device, read, write, 0x00ff) /* PIT ?*/
+static ADDRESS_MAP_START( mvme350_mem, AS_PROGRAM, 16, vme_mvme350_card_device )
+ ADDRESS_MAP_UNMAP_HIGH
+ AM_RANGE(0x000000, 0x01ffff) AM_ROM AM_REGION(MVME350_ROM, 0)
+ AM_RANGE(0x020000, 0x03ffff) AM_RAM
+
+#if 0
+ AM_RANGE(0x040000, 0x040035) AM_DEVREADWRITE8("pit", pit68230_device, read, write, 0x00ff) /* PIT ?*/
+ AM_RANGE(0x060000, 0x06001f) AM_RAM /* Area is cleared on start */
+ AM_RANGE(0x080000, 0x080035) AM_DEVREADWRITE8("pit", pit68230_device, read, write, 0x00ff) /* PIT ?*/
#endif
//AM_RANGE(0x100000, 0xfeffff) AM_READWRITE(vme_a24_r, vme_a24_w) /* VMEbus Rev B addresses (24 bits) - not verified */
//AM_RANGE(0xff0000, 0xffffff) AM_READWRITE(vme_a16_r, vme_a16_w) /* VMEbus Rev B addresses (16 bits) - not verified */
ADDRESS_MAP_END
-/* Input ports */
-static INPUT_PORTS_START (mvme350)
-INPUT_PORTS_END
+//-------------------------------------------------
+// machine_config_additions - device-specific
+// machine configurations
+//-------------------------------------------------
-/* Start it up */
-void mvme350_state::machine_start ()
+MACHINE_CONFIG_FRAGMENT( mvme350 )
+ /* basic machine hardware */
+ MCFG_CPU_ADD (MVME350_CPU_TAG, M68010, XTAL_10MHz)
+ MCFG_CPU_PROGRAM_MAP (mvme350_mem)
+ /* PIT Parallel Interface and Timer device, assuming strapped for on board clock */
+ MCFG_DEVICE_ADD("pit", PIT68230, XTAL_16MHz / 2)
+MACHINE_CONFIG_END
+
+ROM_START( mvme350 )
+ ROM_REGION (0x20000, MVME350_ROM, 0)
+ ROM_LOAD16_BYTE ("mvme350U40v2.3.bin", 0x0001, 0x4000, CRC (bcef82ef) SHA1 (e6fdf26e4714cbaeb3e97d7b5acf02d64d8ad744))
+ ROM_LOAD16_BYTE ("mvme350U47v2.3.bin", 0x0000, 0x4000, CRC (582ce095) SHA1 (d0929dbfeb0cfda63df6b5bc29ee27fbf665def7))
+ROM_END
+
+machine_config_constructor vme_mvme350_card_device::device_mconfig_additions() const
{
- LOG (logerror ("machine_start\n"));
+ LOG("%s %s\n", tag(), FUNCNAME);
+ return MACHINE_CONFIG_NAME( mvme350 );
}
-void mvme350_state::machine_reset ()
+const tiny_rom_entry *vme_mvme350_card_device::device_rom_region() const
{
- LOG (logerror ("machine_reset\n"));
+ LOG("%s\n", FUNCNAME);
+ return ROM_NAME( mvme350 );
}
-#if 0
-/* Dummy VME access methods until the VME bus device is ready for use */
-READ16_MEMBER (mvme350_state::vme_a24_r){
- LOG (logerror ("vme_a24_r\n"));
- return (uint16_t) 0;
-}
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
-WRITE16_MEMBER (mvme350_state::vme_a24_w){
- LOG (logerror ("vme_a24_w\n"));
+vme_mvme350_card_device::vme_mvme350_card_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, uint32_t clock, const char *shortname, const char *source) :
+ device_t(mconfig, type, name, tag, owner, clock, shortname, source),
+ device_vme_card_interface(mconfig, *this)
+{
+ LOG("%s %s\n", tag, FUNCNAME);
}
-READ16_MEMBER (mvme350_state::vme_a16_r){
- LOG (logerror ("vme_16_r\n"));
- return (uint16_t) 0;
+vme_mvme350_card_device::vme_mvme350_card_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
+ device_t(mconfig, VME_MVME350, "Motorola MVME-350 Intelligent Tape Controller", tag, owner, clock, "mvme350", __FILE__),
+ device_vme_card_interface(mconfig, *this)
+{
+ LOG("%s %s\n", tag, FUNCNAME);
}
-WRITE16_MEMBER (mvme350_state::vme_a16_w){
- LOG (logerror ("vme_a16_w\n"));
-}
-#endif
+void vme_mvme350_card_device::device_start()
+{
+ LOG("%s %s\n", tag(), FUNCNAME);
+ set_vme_device();
-/*
- * Machine configuration
- */
-static MACHINE_CONFIG_START (mvme350, mvme350_state)
- /* basic machine hardware */
- MCFG_CPU_ADD ("maincpu", M68010, XTAL_10MHz)
- MCFG_CPU_PROGRAM_MAP (mvme350_mem)
- /* PIT Parallel Interface and Timer device, assuming strapped for on board clock */
- MCFG_DEVICE_ADD("pit", PIT68230, XTAL_16MHz / 2)
+ /* Setup r/w handlers for shared memory area */
+#if 0
+ /* From MVME166 Single Board Computer Installation Guide:
-MACHINE_CONFIG_END
+ Controller Type First board Second board
+ CLUN Address CLUN Address
+ ---------------------------------------------------
+ MVME350 - Streaming $04 $FFFF5000 $05 $FFFF5100
+ Tape Controller
+ ---------------------------------------------------
+ */
+ uint32_t base = 0xFFFF5000;
+ m_vme->install_device(base + 0, base + 1, // Channel B - Data
+ read8_delegate(FUNC(z80sio_device::db_r), subdevice<z80sio_device>("pit")), write8_delegate(FUNC(z80sio_device::db_w), subdevice<z80sio_device>("pit")), 0x00ff);
+ m_vme->install_device(base + 2, base + 3, // Channel B - Control
+ read8_delegate(FUNC(z80sio_device::cb_r), subdevice<z80sio_device>("pit")), write8_delegate(FUNC(z80sio_device::cb_w), subdevice<z80sio_device>("pit")), 0x00ff);
+#endif
-/* ROM definitions */
-ROM_START (mvme350)
-ROM_REGION (0x1000000, "maincpu", 0)
+}
-ROM_LOAD16_BYTE ("mvme350U40v2.3.bin", 0x0000, 0x4000, CRC (bcef82ef) SHA1 (e6fdf26e4714cbaeb3e97d7b5acf02d64d8ad744))
-ROM_LOAD16_BYTE ("mvme350U47v2.3.bin", 0x0001, 0x4000, CRC (582ce095) SHA1 (d0929dbfeb0cfda63df6b5bc29ee27fbf665def7))
+void vme_mvme350_card_device::device_reset()
+{
+ LOG("%s %s\n", tag(), FUNCNAME);
+}
-/*
- * System ROM information
- *
- * The ROMs known commands from different sources:
- *
- * It communicates with the master through data buffers in shared memory and VME bus interrupts
- * as desribed in
- * http://bitsavers.trailing-edge.com/pdf/motorola/_dataBooks/1987_Microcomputer_Systems_and_Components.pdf
- *
- * The board is pretty boring as stand alone, it initializes everything and then executes a STOP instruction
- * awaiting a CPU on the VME bus to request its services. However, it enables boot from tape devices, we just
- * need a MVME-131 and a dump of a VersaDOS or Motorola UNIX System V system tape and some work.
- */
-ROM_END
+#if 0
+READ16_MEMBER (vme_mvme350_card_device::read16){
+ LOG("%s()\n", FUNCNAME);
+ return (uint8_t) 0;
+}
-/* Driver */
-/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */
-COMP (1984, mvme350, 0, 0, mvme350, mvme350, driver_device, 0, "Motorola", "MVME-350", MACHINE_NO_SOUND_HW | MACHINE_TYPE_COMPUTER )
+WRITE16_MEMBER (vme_mvme350_card_device::write16){
+ LOG("%s()\n", FUNCNAME);
+}
+#endif
diff --git a/src/devices/bus/vme/vme_mvme350.h b/src/devices/bus/vme/vme_mvme350.h
new file mode 100644
index 00000000000..5d79fa3d306
--- /dev/null
+++ b/src/devices/bus/vme/vme_mvme350.h
@@ -0,0 +1,32 @@
+// license:BSD-3-Clause
+// copyright-holders:Joakim Larsson Edstrom
+#ifndef VME_MVME350_H
+#define VME_MVME350_H
+#pragma once
+
+#include "bus/vme/vme.h"
+
+extern const device_type VME_MVME350;
+
+class vme_mvme350_card_device :
+ public device_t
+ ,public device_vme_card_interface
+{
+public:
+ vme_mvme350_card_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ vme_mvme350_card_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, uint32_t clock, const char *shortname, const char *source);
+
+ // optional information overrides
+ virtual machine_config_constructor device_mconfig_additions() const override;
+ virtual const tiny_rom_entry *device_rom_region() const override;
+
+ // Shared memory methods to be exported to the VME bus
+// virtual DECLARE_READ16_MEMBER (read16) override;
+// virtual DECLARE_WRITE16_MEMBER (write16) override;
+protected:
+ virtual void device_start() override;
+ virtual void device_reset() override;
+private:
+};
+
+#endif // VME_MVME350_H
diff --git a/src/mame/bus/vme/mzr8105.cpp b/src/devices/bus/vme/vme_mzr8105.cpp
index e0a722ab0eb..8239c0992f1 100644
--- a/src/mame/bus/vme/mzr8105.cpp
+++ b/src/devices/bus/vme/vme_mzr8105.cpp
@@ -2,7 +2,7 @@
// copyright-holders:Joakim Larsson Edstrom
#include "emu.h"
-#include "mzr8105.h"
+#include "vme_mzr8105.h"
#define LOG_GENERAL 0x01
#define LOG_SETUP 0x02
@@ -47,7 +47,7 @@ machine_config_constructor vme_mzr8105_card_device::device_mconfig_additions() c
vme_mzr8105_card_device::vme_mzr8105_card_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
device_t(mconfig, VME_MZR8105, "Mizar 8105 68K CPU board", tag, owner, clock, "mzr8105", __FILE__),
- device_vme_p1_card_interface(mconfig, *this)
+ device_vme_card_interface(mconfig, *this)
{
m_slot = 1;
LOG("%s %s\n", tag, FUNCNAME);
@@ -55,7 +55,7 @@ vme_mzr8105_card_device::vme_mzr8105_card_device(const machine_config &mconfig,
vme_mzr8105_card_device::vme_mzr8105_card_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, uint32_t clock, const char *shortname, const char *source) :
device_t(mconfig, type, name, tag, owner, clock, shortname, source),
- device_vme_p1_card_interface(mconfig, *this)
+ device_vme_card_interface(mconfig, *this)
{
LOG("%s %s\n", tag, FUNCNAME);
}
diff --git a/src/mame/bus/vme/mzr8105.h b/src/devices/bus/vme/vme_mzr8105.h
index 50041eac7fe..525cf691408 100644
--- a/src/mame/bus/vme/mzr8105.h
+++ b/src/devices/bus/vme/vme_mzr8105.h
@@ -5,13 +5,11 @@
#pragma once
#include "bus/vme/vme.h"
-//#include "includes/mzr8105.h"
-#include "bus/vme/mzr8105.h"
extern const device_type VME_MZR8105;
class vme_mzr8105_card_device : public device_t
- ,public device_vme_p1_card_interface
+ ,public device_vme_card_interface
{
public:
vme_mzr8105_card_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
diff --git a/src/mame/machine/mzr8300.cpp b/src/devices/bus/vme/vme_mzr8300.cpp
index 9d1541a05ee..04ddd02636e 100644
--- a/src/mame/machine/mzr8300.cpp
+++ b/src/devices/bus/vme/vme_mzr8300.cpp
@@ -80,8 +80,9 @@
* - Get terminal working through this device over the VME interface
*
****************************************************************************/
+
#include "emu.h"
-#include "includes/mzr8300.h"
+#include "vme_mzr8300.h"
#include "machine/z80sio.h"
#include "bus/rs232/rs232.h"
#include "machine/clock.h"
@@ -108,6 +109,12 @@
#define FUNCNAME __PRETTY_FUNCTION__
#endif
+//**************************************************************************
+// GLOBAL VARIABLES
+//**************************************************************************
+
+const device_type VME_MZR8300 = &device_creator<vme_mzr8300_card_device>;
+
/* These values are borrowed just to get the terminal going and should be replaced
* once a proper serial board hardware (ie MZ 8300) is found and emulated. */
#define BAUDGEN_CLOCK XTAL_19_6608MHz /* fake */
@@ -127,39 +134,65 @@ MACHINE_CONFIG_FRAGMENT( mzr8300 )
MCFG_Z80SIO_ADD("sio1", XTAL_4MHz, 0, 0, 0, 0 )
MACHINE_CONFIG_END
-const device_type VME_P1_MZR8300 = &device_creator<vme_p1_mzr8300_device>;
+//-------------------------------------------------
+// machine_config_additions - device-specific
+// machine configurations
+//-------------------------------------------------
+
-machine_config_constructor vme_p1_mzr8300_device::device_mconfig_additions() const
+machine_config_constructor vme_mzr8300_card_device::device_mconfig_additions() const
{
+ LOG("%s %s\n", tag(), FUNCNAME);
return MACHINE_CONFIG_NAME( mzr8300 );
}
-vme_p1_mzr8300_device::vme_p1_mzr8300_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
- device_t(mconfig, VME_P1_MZR8300, "Mizar 8300 quad channel SIO board", tag, owner, clock, "vme_mzr8300", __FILE__)
- ,device_vme_p1_card_interface(mconfig, *this)
- ,m_sio0(*this, "sio0")
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+vme_mzr8300_card_device::vme_mzr8300_card_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, uint32_t clock, const char *shortname, const char *source) :
+ device_t(mconfig, type, name, tag, owner, clock, shortname, source),
+ device_vme_card_interface(mconfig, *this)
{
+ LOG("%s %s\n", tag, FUNCNAME);
}
-vme_p1_mzr8300_device::vme_p1_mzr8300_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, uint32_t clock, const char *shortname, const char *source) :
- device_t(mconfig, type, name, tag, owner, clock, shortname, source)
- ,device_vme_p1_card_interface(mconfig, *this)
- ,m_sio0(*this, "sio0")
+vme_mzr8300_card_device::vme_mzr8300_card_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
+ device_t(mconfig, VME_MZR8300, "Mizar 8300 SIO serial board", tag, owner, clock, "mzr8300", __FILE__),
+ device_vme_card_interface(mconfig, *this)
{
+ LOG("%s %s\n", tag, FUNCNAME);
}
-//-------------------------------------------------
-// device_start - device-specific startup
-//-------------------------------------------------
+void vme_mzr8300_card_device::device_start()
+{
+ LOG("%s %s\n", tag(), FUNCNAME);
+ set_vme_device();
+
+ /* Setup r/w handlers for first SIO in A16 */
+ uint32_t base = 0xFF0000;
+ m_vme->install_device(base + 0, base + 1, // Channel B - Data
+ read8_delegate(FUNC(z80sio_device::db_r), subdevice<z80sio_device>("sio0")), write8_delegate(FUNC(z80sio_device::db_w), subdevice<z80sio_device>("sio0")), 0x00ff);
+ m_vme->install_device(base + 2, base + 3, // Channel B - Control
+ read8_delegate(FUNC(z80sio_device::cb_r), subdevice<z80sio_device>("sio0")), write8_delegate(FUNC(z80sio_device::cb_w), subdevice<z80sio_device>("sio0")), 0x00ff);
+ m_vme->install_device(base + 4, base + 5, // Channel A - Data
+ read8_delegate(FUNC(z80sio_device::da_r), subdevice<z80sio_device>("sio0")), write8_delegate(FUNC(z80sio_device::da_w), subdevice<z80sio_device>("sio0")), 0x00ff);
+ m_vme->install_device(base + 6, base + 7, // Channel A - Control
+ read8_delegate(FUNC(z80sio_device::ca_r), subdevice<z80sio_device>("sio0")), write8_delegate(FUNC(z80sio_device::ca_w), subdevice<z80sio_device>("sio0")), 0x00ff);
+}
-void vme_p1_mzr8300_device::device_start()
+void vme_mzr8300_card_device::device_reset()
{
+ LOG("%s %s\n", tag(), FUNCNAME);
}
-//-------------------------------------------------
-// device_reset - device-specific reset
-//-------------------------------------------------
+#if 0
+READ8_MEMBER (vme_mzr8300_card_device::read8){
+ LOG("%s()\n", FUNCNAME);
+ return (uint8_t) 0;
+}
-void vme_p1_mzr8300_device::device_reset()
-{
+WRITE8_MEMBER (vme_mzr8300_card_device::write8){
+ LOG("%s()\n", FUNCNAME);
}
+#endif
diff --git a/src/mame/bus/vme/mzr8300.h b/src/devices/bus/vme/vme_mzr8300.h
index 009e47c8dd6..73482cb5b77 100644
--- a/src/mame/bus/vme/mzr8300.h
+++ b/src/devices/bus/vme/vme_mzr8300.h
@@ -5,23 +5,22 @@
#pragma once
#include "bus/vme/vme.h"
-//#include "includes/mzr8300.h"
-#include "bus/vme/mzr8300.h"
extern const device_type VME_MZR8300;
class vme_mzr8300_card_device :
public device_t
- ,public device_vme_p1_card_interface
+ ,public device_vme_card_interface
{
public:
vme_mzr8300_card_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
vme_mzr8300_card_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, uint32_t clock, const char *shortname, const char *source);
- // optional information overrides
+ // optional information overrides
virtual machine_config_constructor device_mconfig_additions() const override;
- virtual DECLARE_READ8_MEMBER (read8) override;
- virtual DECLARE_WRITE8_MEMBER (write8) override;
+
+// virtual DECLARE_READ8_MEMBER (read8) override;
+// virtual DECLARE_WRITE8_MEMBER (write8) override;
protected:
virtual void device_start() override;
virtual void device_reset() override;
diff --git a/src/devices/cpu/amis2000/amis2000.h b/src/devices/cpu/amis2000/amis2000.h
index 68fd87ee0ae..76190cb3090 100644
--- a/src/devices/cpu/amis2000/amis2000.h
+++ b/src/devices/cpu/amis2000/amis2000.h
@@ -100,28 +100,28 @@ protected:
uint8_t m_bu_bits;
uint16_t m_bu_mask;
- uint8_t m_callstack_bits; // number of program counter bits held in callstack
+ uint8_t m_callstack_bits; // number of program counter bits held in callstack
uint16_t m_callstack_mask;
- uint8_t m_callstack_depth; // callstack levels: 3 on 2000/2150, 5 on 2200/2400
- uint16_t m_callstack[5]; // max 5
+ uint8_t m_callstack_depth; // callstack levels: 3 on 2000/2150, 5 on 2200/2400
+ uint16_t m_callstack[5]; // max 5
int m_icount;
- uint16_t m_pc; // 13-bit program counter
- uint8_t m_ppr; // prepared page register (PP 1)
- uint8_t m_pbr; // prepared bank register (PP 2)
+ uint16_t m_pc; // 13-bit program counter
+ uint8_t m_ppr; // prepared page register (PP 1)
+ uint8_t m_pbr; // prepared bank register (PP 2)
bool m_skip; // skip next opcode, including PP prefixes
uint8_t m_op;
- uint8_t m_prev_op; // previous opcode, needed for PP, LAI, LB*
- uint8_t m_f; // generic flags: 2 on 2000/2150, 6 on 2200/2400
- uint8_t m_carry; // carry flag
- uint8_t m_bl; // 4-bit ram index x
- uint8_t m_bu; // 2/3-bit ram index y
- uint8_t m_acc; // 4-bit accumulator
- uint8_t m_e; // 4-bit generic register
- uint8_t m_ki_mask; // 4-bit k/i-pins select latch
- uint8_t m_d; // 8-bit d-pins latch
+ uint8_t m_prev_op; // previous opcode, needed for PP, LAI, LB*
+ uint8_t m_f; // generic flags: 2 on 2000/2150, 6 on 2200/2400
+ uint8_t m_carry; // carry flag
+ uint8_t m_bl; // 4-bit ram index x
+ uint8_t m_bu; // 2/3-bit ram index y
+ uint8_t m_acc; // 4-bit accumulator
+ uint8_t m_e; // 4-bit generic register
+ uint8_t m_ki_mask; // 4-bit k/i-pins select latch
+ uint8_t m_d; // 8-bit d-pins latch
bool m_d_active; // d-pins available for direct i/o(floating), or outputting d-latch
- uint8_t m_d_polarity; // invert d-latch output
- uint16_t m_a; // 13-bit a-pins latch (master strobe latch)
+ uint8_t m_d_polarity; // invert d-latch output
+ uint16_t m_a; // 13-bit a-pins latch (master strobe latch)
// i/o handlers
const uint8_t *m_7seg_table;
diff --git a/src/devices/cpu/e0c6200/e0c6200.h b/src/devices/cpu/e0c6200/e0c6200.h
index e1b95d0381c..bf43c80ad2b 100644
--- a/src/devices/cpu/e0c6200/e0c6200.h
+++ b/src/devices/cpu/e0c6200/e0c6200.h
@@ -54,10 +54,10 @@ protected:
uint16_t m_op;
uint16_t m_prev_op;
uint8_t m_irq_vector; // low 4 bits for new programcounter after interrupt
- int m_irq_id; // for standard_irq_callback(id)
- bool m_possible_irq; // indicates interrupts need to be re-checked
- bool m_halt; // cpu halt state
- bool m_sleep; // cpu sleep state
+ int m_irq_id; // for standard_irq_callback(id)
+ bool m_possible_irq; // indicates interrupts need to be re-checked
+ bool m_halt; // cpu halt state
+ bool m_sleep; // cpu sleep state
int m_icount;
uint16_t m_pc; // 13-bit programcounter: 1-bit bank, 4-bit page, 8-bit 'step'
diff --git a/src/devices/cpu/e0c6200/e0c6s46.cpp b/src/devices/cpu/e0c6200/e0c6s46.cpp
index 7563f4bc4a3..4feed3f4e32 100644
--- a/src/devices/cpu/e0c6200/e0c6s46.cpp
+++ b/src/devices/cpu/e0c6200/e0c6s46.cpp
@@ -49,7 +49,7 @@ e0c6s46_device::e0c6s46_device(const machine_config &mconfig, const char *tag, d
: e0c6200_cpu_device(mconfig, E0C6S46, "E0C6S46", tag, owner, clock, ADDRESS_MAP_NAME(e0c6s46_program), ADDRESS_MAP_NAME(e0c6s46_data), "e0c6s46", __FILE__)
, m_vram1(*this, "vram1")
, m_vram2(*this, "vram2"), m_osc(0), m_svd(0), m_lcd_control(0), m_lcd_contrast(0)
- , m_pixel_update_handler(nullptr)
+ , m_pixel_update_handler(nullptr)
, m_write_r0(*this), m_write_r1(*this), m_write_r2(*this), m_write_r3(*this), m_write_r4(*this)
, m_read_p0(*this), m_read_p1(*this), m_read_p2(*this), m_read_p3(*this)
, m_write_p0(*this), m_write_p1(*this), m_write_p2(*this), m_write_p3(*this), m_r_dir(0), m_p_dir(0), m_p_pullup(0), m_dfk0(0), m_256_src_pulse(0), m_core_256_handle(nullptr),
diff --git a/src/devices/cpu/hmcs40/hmcs40.h b/src/devices/cpu/hmcs40/hmcs40.h
index 73ae6308940..38a6d20169d 100644
--- a/src/devices/cpu/hmcs40/hmcs40.h
+++ b/src/devices/cpu/hmcs40/hmcs40.h
@@ -182,22 +182,22 @@ protected:
address_space *m_program;
address_space *m_data;
- int m_pcwidth; // Program Counter bit-width
+ int m_pcwidth; // Program Counter bit-width
int m_prgwidth;
int m_datawidth;
int m_pcmask;
int m_prgmask;
int m_datamask;
- int m_family; // MCU family (42-47)
+ int m_family; // MCU family (42-47)
uint16_t m_polarity; // i/o polarity (pmos vs cmos)
- int m_stack_levels; // number of callstack levels
+ int m_stack_levels; // number of callstack levels
uint16_t m_stack[4]; // max 4
uint16_t m_op; // current opcode
uint16_t m_prev_op;
uint8_t m_i; // 4-bit immediate opcode param
- int m_eint_line; // which input_line caused an interrupt
+ int m_eint_line; // which input_line caused an interrupt
emu_timer *m_timer;
- int m_halt; // internal HLT state
+ int m_halt; // internal HLT state
attotime m_timer_halted_remain;
int m_icount;
diff --git a/src/devices/cpu/i386/i386ops.hxx b/src/devices/cpu/i386/i386ops.hxx
index e27bb4a13bc..1d00ac21566 100644
--- a/src/devices/cpu/i386/i386ops.hxx
+++ b/src/devices/cpu/i386/i386ops.hxx
@@ -1224,8 +1224,9 @@ void i386_device::i386_repeat(int invert_flag)
return;
default:
- fatalerror("i386: Invalid REP/opcode %02X combination\n",opcode);
- break;
+ logerror("i386: Invalid REP/opcode %02X combination at %08x\n",opcode, m_pc - 2);
+ m_pc--;
+ return;
}
if( m_address_size ) {
diff --git a/src/devices/cpu/m6805/m6805.cpp b/src/devices/cpu/m6805/m6805.cpp
index 278505b8c1e..7a8a3a43a97 100644
--- a/src/devices/cpu/m6805/m6805.cpp
+++ b/src/devices/cpu/m6805/m6805.cpp
@@ -415,7 +415,7 @@ m6805_base_device::m6805_base_device(const machine_config &mconfig, const char *
{
}
-m6805_base_device::m6805_base_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, const device_type type, const char *name, uint32_t addr_width, address_map_constructor internal_map, const char *shortname, const char *source)
+m6805_base_device::m6805_base_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, const device_type type, const char *name, uint32_t addr_width, address_map_delegate internal_map, const char *shortname, const char *source)
: cpu_device(mconfig, type, name, tag, owner, clock, shortname, source),
m_program_config("program", ENDIANNESS_BIG, 8, addr_width, 0, internal_map)
{
@@ -965,65 +965,228 @@ void m68705_device::execute_set_input(int inputnum, int state)
/* ddr - direction registers */
-WRITE8_MEMBER(m68705_new_device::mc68705_ddrA_w)
+WRITE8_MEMBER(m68705_new_device::internal_ddrA_w)
{
+ const u8 ddr_old = m_ddrA;
m_ddrA = data;
+
+ // update outputs if lines switched to output
+ if ((m_ddrA & ~ddr_old) != 0)
+ update_portA_state();
}
-WRITE8_MEMBER(m68705_new_device::mc68705_ddrB_w)
+WRITE8_MEMBER(m68705_new_device::internal_ddrB_w)
{
+ const u8 ddr_old = m_ddrB;
m_ddrB = data;
+
+ // update outputs if lines switched to output
+ if ((m_ddrB & ~ddr_old) != 0)
+ update_portB_state();
}
-WRITE8_MEMBER(m68705_new_device::mc68705_ddrC_w)
+WRITE8_MEMBER(m68705_new_device::internal_ddrC_w)
{
+ const u8 ddr_old = m_ddrC;
m_ddrC = data;
+
+ // update outputs if lines switched to output
+ if ((m_ddrC & ~ddr_old) != 0)
+ update_portC_state();
}
/* read ports */
-READ8_MEMBER(m68705_new_device::mc68705_portA_r)
+READ8_MEMBER(m68705_new_device::internal_portA_r)
{
- m_portA_in = m_portA_cb_r(0, ~m_ddrA); // pass the direction register as mem_mask so that externally we know which lines were actually pulled
- uint8_t res = (m_portA_out & m_ddrA) | (m_portA_in & ~m_ddrA);
+ if (!m_portA_cb_r.isnull())
+ m_portA_in = m_portA_cb_r(space, 0, ~m_ddrA); // pass the direction register as mem_mask so that externally we know which lines were actually pulled
+ u8 res = (m_portA_out & m_ddrA) | (m_portA_in & ~m_ddrA);
return res;
-
}
-READ8_MEMBER(m68705_new_device::mc68705_portB_r)
+READ8_MEMBER(m68705_new_device::internal_portB_r)
{
- m_portB_in = m_portB_cb_r(0, ~m_ddrB);
- uint8_t res = (m_portB_out & m_ddrB) | (m_portB_in & ~m_ddrB);
+ if (!m_portB_cb_r.isnull())
+ m_portB_in = m_portB_cb_r(space, 0, ~m_ddrB);
+ u8 res = (m_portB_out & m_ddrB) | (m_portB_in & ~m_ddrB);
return res;
}
-READ8_MEMBER(m68705_new_device::mc68705_portC_r)
+READ8_MEMBER(m68705_new_device::internal_portC_r)
{
- m_portC_in = m_portC_cb_r(0, ~m_ddrC);
- uint8_t res = (m_portC_out & m_ddrC) | (m_portC_in & ~m_ddrC);
+ if (!m_portC_cb_r.isnull())
+ m_portC_in = m_portC_cb_r(space, 0, ~m_ddrC);
+ u8 res = (m_portC_out & m_ddrC) | (m_portC_in & ~m_ddrC);
return res;
}
/* write ports */
-WRITE8_MEMBER(m68705_new_device::mc68705_portA_w)
+WRITE8_MEMBER(m68705_new_device::internal_portA_w)
{
- m_portA_cb_w(0, data, m_ddrA); // pass the direction register as mem_mask so that externally we know which lines were actually pushed
+ // load the output latch
m_portA_out = data;
+
+ // update the output lines
+ update_portA_state();
}
-WRITE8_MEMBER(m68705_new_device::mc68705_portB_w)
+void m68705_new_device::update_portA_state()
{
- m_portB_cb_w(0, data, m_ddrB);
+ // pass bits through DDR output mask
+ m_portA_in = (m_portA_out & m_ddrA) | (m_portA_in & ~m_ddrA);
+
+ // pass the direction register as mem_mask as mem_mask so that externally we know which lines were actually pushed
+ m_portA_cb_w(space(AS_PROGRAM), 0, m_portA_in, m_ddrA);
+}
+
+WRITE8_MEMBER(m68705_new_device::internal_portB_w)
+{
+ // load the output latch
m_portB_out = data;
+
+ // update the output lines
+ update_portB_state();
}
-WRITE8_MEMBER(m68705_new_device::mc68705_portC_w)
+void m68705_new_device::update_portB_state()
{
- m_portC_cb_w(0, data, m_ddrC);
+ // pass bits through DDR output mask
+ m_portB_in = (m_portB_out & m_ddrB) | (m_portB_in & ~m_ddrB);
+
+ // pass the direction register as mem_mask as mem_mask so that externally we know which lines were actually pushed
+ m_portB_cb_w(space(AS_PROGRAM), 0, m_portB_in, m_ddrB);
+}
+
+WRITE8_MEMBER(m68705_new_device::internal_portC_w)
+{
+ // load the output latch
m_portC_out = data;
+
+ // update the output lines
+ update_portC_state();
+}
+
+void m68705_new_device::update_portC_state()
+{
+ // pass bits through DDR output mask
+ m_portC_in = (m_portC_out & m_ddrC) | (m_portC_in & ~m_ddrC);
+
+ // pass the direction register as mem_mask as mem_mask so that externally we know which lines were actually pushed
+ m_portC_cb_w(space(AS_PROGRAM), 0, m_portC_in, m_ddrC);
+}
+
+READ8_MEMBER(m68705_new_device::pa_r)
+{
+ return m_portA_in;
+}
+
+READ8_MEMBER(m68705_new_device::pb_r)
+{
+ return m_portB_in;
+}
+
+READ8_MEMBER(m68705_new_device::pc_r)
+{
+ return m_portC_in;
+}
+
+WRITE8_MEMBER(m68705_new_device::pa_w)
+{
+ COMBINE_DATA(&m_portA_in);
+}
+
+WRITE8_MEMBER(m68705_new_device::pb_w)
+{
+ COMBINE_DATA(&m_portB_in);
+}
+
+WRITE8_MEMBER(m68705_new_device::pc_w)
+{
+ COMBINE_DATA(&m_portC_in);
}
+
+READ8_MEMBER(m68705_new_device::internal_68705_tdr_r)
+{
+ //logerror("internal_68705 TDR read, returning %02X\n", m_tdr);
+ return m_tdr;
+}
+
+WRITE8_MEMBER(m68705_new_device::internal_68705_tdr_w)
+{
+ //logerror("internal_68705 TDR written with %02X, was %02X\n", data, m_tdr);
+ m_tdr = data;
+}
+
+
+READ8_MEMBER(m68705_new_device::internal_68705_tcr_r)
+{
+ //logerror("internal_68705 TCR read, returning %02X\n", (m_tcr&0xF7));
+ return (m_tcr & 0xF7);
+}
+
+WRITE8_MEMBER(m68705_new_device::internal_68705_tcr_w)
+{
+/*
+ logerror("internal_68705 TCR written with %02X\n", data);
+ if (data&0x80) logerror(" TIR=1, Timer Interrupt state is set\n"); else logerror(" TIR=0; Timer Interrupt state is cleared\n");
+ if (data&0x40) logerror(" TIM=1, Timer Interrupt is now masked\n"); else logerror(" TIM=0, Timer Interrupt is now unmasked\n");
+ if (data&0x20) logerror(" TIN=1, Timer Clock source is set to external\n"); else logerror(" TIN=0, Timer Clock source is set to internal\n");
+ if (data&0x10) logerror(" TIE=1, Timer External pin is enabled\n"); else logerror(" TIE=0, Timer External pin is disabled\n");
+ if (data&0x08) logerror(" PSC=1, Prescaler counter cleared\n"); else logerror(" PSC=0, Prescaler counter left alone\n");
+ logerror(" Prescaler: %d\n", (1<<(data&0x7)));
+*/
+ // if timer was enabled but now isn't, shut it off.
+ // below is a hack assuming the TIMER pin isn't going anywhere except tied to +5v, so basically TIN is acting as an active-low timer enable, and TIE is ignored even in the case where TIE=1, the timer will end up being 5v ANDED against the internal timer clock which == the internal timer clock.
+ // Note this hack is incorrect; the timer pin actually does connect somewhere (vblank or maybe one of the V counter bits?), but the game never actually uses the timer pin in external clock mode, so the TIMER connection must be left over from development. We can apparently safely ignore it.
+ if ((m_tcr^data)&0x20)// check if TIN state changed
+ {
+ /* logerror("timer enable state changed!\n"); */
+ if (data&0x20) m_68705_timer->adjust(attotime::never, TIMER_68705_PRESCALER_EXPIRED);
+ else m_68705_timer->adjust(attotime::from_hz(((clock())/4)/(1<<(data&0x7))), TIMER_68705_PRESCALER_EXPIRED);
+ }
+ // prescaler check: if timer prescaler has changed, or the PSC bit is set, adjust the timer length for the prescaler expired timer, but only if the timer would be running
+ if ( (((m_tcr&0x07)!=(data&0x07))||(data&0x08)) && ((data&0x20)==0) )
+ {
+ /* logerror("timer reset due to PSC or prescaler change!\n"); */
+ m_68705_timer->adjust(attotime::from_hz(((clock())/4)/(1<<(data&0x7))), TIMER_68705_PRESCALER_EXPIRED);
+ }
+ m_tcr = data;
+ // if int state is set, and TIM is unmasked, assert an interrupt. otherwise clear it.
+ if ((m_tcr&0xC0) == 0x80)
+ set_input_line(M68705_INT_TIMER, ASSERT_LINE);
+ else
+ set_input_line(M68705_INT_TIMER, CLEAR_LINE);
+
+}
+
+void m68705_new_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
+{
+ switch (id)
+ {
+ case TIMER_68705_PRESCALER_EXPIRED:
+ timer_68705_increment(ptr, param);
+ break;
+ default:
+ assert_always(false, "Unknown id in m68705_new_device::device_timer");
+ }
+}
+
+TIMER_CALLBACK_MEMBER(m68705_new_device::timer_68705_increment)
+{
+ m_tdr++;
+ if (m_tdr == 0x00) m_tcr |= 0x80; // if we overflowed, set the int bit
+ if ((m_tcr&0xC0) == 0x80)
+ set_input_line(M68705_INT_TIMER, ASSERT_LINE);
+ else
+ set_input_line(M68705_INT_TIMER, CLEAR_LINE);
+ m_68705_timer->adjust(attotime::from_hz(((clock())/4)/(1<<(m_tcr&0x7))), TIMER_68705_PRESCALER_EXPIRED);
+}
+
+
+
/*
The 68(7)05 peripheral memory map:
@@ -1079,13 +1242,17 @@ selftest rom at similar area; selftest roms differ between the U2 and U3 version
*/
-ADDRESS_MAP_START( m68705_internal_map, AS_PROGRAM, 8, m68705_new_device )
- AM_RANGE(0x000, 0x000) AM_READWRITE(mc68705_portA_r, mc68705_portA_w)
- AM_RANGE(0x001, 0x001) AM_READWRITE(mc68705_portB_r, mc68705_portB_w)
- AM_RANGE(0x002, 0x002) AM_READWRITE(mc68705_portC_r, mc68705_portC_w)
- AM_RANGE(0x004, 0x004) AM_WRITE(mc68705_ddrA_w)
- AM_RANGE(0x005, 0x005) AM_WRITE(mc68705_ddrB_w)
- AM_RANGE(0x006, 0x006) AM_WRITE(mc68705_ddrC_w)
+DEVICE_ADDRESS_MAP_START( internal_map, 8, m68705_new_device )
+ AM_RANGE(0x000, 0x000) AM_READWRITE(internal_portA_r, internal_portA_w)
+ AM_RANGE(0x001, 0x001) AM_READWRITE(internal_portB_r, internal_portB_w)
+ AM_RANGE(0x002, 0x002) AM_READWRITE(internal_portC_r, internal_portC_w)
+ AM_RANGE(0x004, 0x004) AM_WRITE(internal_ddrA_w)
+ AM_RANGE(0x005, 0x005) AM_WRITE(internal_ddrB_w)
+ AM_RANGE(0x006, 0x006) AM_WRITE(internal_ddrC_w)
+
+ AM_RANGE(0x008, 0x008) AM_READWRITE(internal_68705_tdr_r, internal_68705_tdr_w)
+ AM_RANGE(0x009, 0x009) AM_READWRITE(internal_68705_tcr_r, internal_68705_tcr_w)
+
AM_RANGE(0x010, 0x07f) AM_RAM
AM_RANGE(0x080, 0x7ff) AM_ROM
@@ -1111,10 +1278,37 @@ void m68705_new_device::device_start()
m_portB_cb_w.resolve_safe();
m_portC_cb_w.resolve_safe();
- m_portA_cb_r.resolve_safe(0xff);
- m_portB_cb_r.resolve_safe(0xff);
- m_portC_cb_r.resolve_safe(0xff);
+ m_portA_cb_r.resolve();
+ m_portB_cb_r.resolve();
+ m_portC_cb_r.resolve();
+
+ m_portA_in = 0xff;
+ m_portB_in = 0xff;
+ m_portC_in = 0xff;
+
+ // allocate the MCU timer, and set it to fire NEVER.
+ m_68705_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(m68705_new_device::timer_68705_increment),this));
+ m_68705_timer->adjust(attotime::never);
+
+ save_item(NAME(m_tdr));
+ save_item(NAME(m_tcr));
+
+}
+
+void m68705_new_device::device_reset()
+{
+ m68705_device::device_reset();
+
+ // all bits of ports A, B and C revert to inputs on reset
+ m_ddrA = 0;
+ m_ddrB = 0;
+ m_ddrC = 0;
+
+ m_tdr = 0xFF;
+ m_tcr = 0x7F;
+ //set_input_line(M68705_IRQ_LINE, CLEAR_LINE);
+ m_68705_timer->adjust(attotime::from_hz(((clock())/4)/(1<<7)));
}
/****************************************************************************
diff --git a/src/devices/cpu/m6805/m6805.h b/src/devices/cpu/m6805/m6805.h
index 24b75f57158..34e7d9a6ba6 100644
--- a/src/devices/cpu/m6805/m6805.h
+++ b/src/devices/cpu/m6805/m6805.h
@@ -28,7 +28,7 @@ class m6805_base_device : public cpu_device
public:
// construction/destruction
m6805_base_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, const device_type type, const char *name, uint32_t addr_width, const char *shortname, const char *source);
- m6805_base_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, const device_type type, const char *name, uint32_t addr_width, address_map_constructor internal_map, const char *shortname, const char *source);
+ m6805_base_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, const device_type type, const char *name, uint32_t addr_width, address_map_delegate internal_map, const char *shortname, const char *source);
protected:
// device-level overrides
@@ -330,7 +330,7 @@ public:
m68705_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: m6805_base_device(mconfig, tag, owner, clock, M68705, "M68705", 12, "m68705", __FILE__) { }
- m68705_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, const device_type type, const char *name, uint32_t addr_width, address_map_constructor internal_map, const char *shortname, const char *source)
+ m68705_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, const device_type type, const char *name, uint32_t addr_width, address_map_delegate internal_map, const char *shortname, const char *source)
: m6805_base_device(mconfig, tag, owner, clock, type, name, addr_width, internal_map, shortname, source) { }
@@ -345,26 +345,24 @@ protected:
// ======================> m68705_new_device
-ADDRESS_MAP_EXTERN(m68705_internal_map, 8);
-
#define MCFG_M68705_PORTA_W_CB(_devcb) \
- m68705_new_device::set_portA_cb_w(*device, DEVCB_##_devcb);
+ devcb = &m68705_new_device::set_portA_cb_w(*device, DEVCB_##_devcb);
#define MCFG_M68705_PORTB_W_CB(_devcb) \
- m68705_new_device::set_portB_cb_w(*device, DEVCB_##_devcb);
+ devcb = &m68705_new_device::set_portB_cb_w(*device, DEVCB_##_devcb);
#define MCFG_M68705_PORTC_W_CB(_devcb) \
- m68705_new_device::set_portC_cb_w(*device, DEVCB_##_devcb);
+ devcb = &m68705_new_device::set_portC_cb_w(*device, DEVCB_##_devcb);
#define MCFG_M68705_PORTA_R_CB(_devcb) \
- m68705_new_device::set_portA_cb_r(*device, DEVCB_##_devcb);
+ devcb = &m68705_new_device::set_portA_cb_r(*device, DEVCB_##_devcb);
#define MCFG_M68705_PORTB_R_CB(_devcb) \
- m68705_new_device::set_portB_cb_r(*device, DEVCB_##_devcb);
+ devcb = &m68705_new_device::set_portB_cb_r(*device, DEVCB_##_devcb);
#define MCFG_M68705_PORTC_R_CB(_devcb) \
- m68705_new_device::set_portC_cb_r(*device, DEVCB_##_devcb);
+ devcb = &m68705_new_device::set_portC_cb_r(*device, DEVCB_##_devcb);
class m68705_new_device : public m68705_device
@@ -372,7 +370,7 @@ class m68705_new_device : public m68705_device
public:
// construction/destruction
m68705_new_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : m68705_device(mconfig, tag, owner, clock, M68705_NEW, "M68705 (NEW)", 11, ADDRESS_MAP_NAME( m68705_internal_map ), "m68705_new", __FILE__),
+ : m68705_device(mconfig, tag, owner, clock, M68705_NEW, "M68705 (NEW)", 11, address_map_delegate(FUNC(m68705_new_device::internal_map), this), "m68705_new", __FILE__),
m_portA_in(0),
m_portB_in(0),
m_portC_in(0),
@@ -399,31 +397,57 @@ public:
template<class _Object> static devcb_base &set_portB_cb_r(device_t &device, _Object object) { return downcast<m68705_new_device &>(device).m_portB_cb_r.set_callback(object); }
template<class _Object> static devcb_base &set_portC_cb_r(device_t &device, _Object object) { return downcast<m68705_new_device &>(device).m_portC_cb_r.set_callback(object); }
- DECLARE_READ8_MEMBER(mc68705_portA_r);
- DECLARE_READ8_MEMBER(mc68705_portB_r);
- DECLARE_READ8_MEMBER(mc68705_portC_r);
-
- DECLARE_WRITE8_MEMBER(mc68705_portA_w);
- DECLARE_WRITE8_MEMBER(mc68705_portB_w);
- DECLARE_WRITE8_MEMBER(mc68705_portC_w);
+ DECLARE_READ8_MEMBER(pa_r);
+ DECLARE_READ8_MEMBER(pb_r);
+ DECLARE_READ8_MEMBER(pc_r);
- DECLARE_WRITE8_MEMBER(mc68705_ddrA_w);
- DECLARE_WRITE8_MEMBER(mc68705_ddrB_w);
- DECLARE_WRITE8_MEMBER(mc68705_ddrC_w);
+ DECLARE_WRITE8_MEMBER(pa_w);
+ DECLARE_WRITE8_MEMBER(pb_w);
+ DECLARE_WRITE8_MEMBER(pc_w);
protected:
+ enum
+ {
+ TIMER_68705_PRESCALER_EXPIRED,
+ };
+
+ DECLARE_ADDRESS_MAP(internal_map, 8);
+
+ DECLARE_READ8_MEMBER(internal_portA_r);
+ DECLARE_READ8_MEMBER(internal_portB_r);
+ DECLARE_READ8_MEMBER(internal_portC_r);
+
+ DECLARE_WRITE8_MEMBER(internal_portA_w);
+ DECLARE_WRITE8_MEMBER(internal_portB_w);
+ DECLARE_WRITE8_MEMBER(internal_portC_w);
+
+ DECLARE_WRITE8_MEMBER(internal_ddrA_w);
+ DECLARE_WRITE8_MEMBER(internal_ddrB_w);
+ DECLARE_WRITE8_MEMBER(internal_ddrC_w);
- uint8_t m_portA_in;
- uint8_t m_portB_in;
- uint8_t m_portC_in;
+ DECLARE_READ8_MEMBER(internal_68705_tdr_r);
+ DECLARE_WRITE8_MEMBER(internal_68705_tdr_w);
+ DECLARE_READ8_MEMBER(internal_68705_tcr_r);
+ DECLARE_WRITE8_MEMBER(internal_68705_tcr_w);
- uint8_t m_portA_out;
- uint8_t m_portB_out;
- uint8_t m_portC_out;
+ void update_portA_state();
+ void update_portB_state();
+ void update_portC_state();
- uint8_t m_ddrA;
- uint8_t m_ddrB;
- uint8_t m_ddrC;
+ u8 m_portA_in;
+ u8 m_portB_in;
+ u8 m_portC_in;
+
+ u8 m_portA_out;
+ u8 m_portB_out;
+ u8 m_portC_out;
+
+ u8 m_ddrA;
+ u8 m_ddrB;
+ u8 m_ddrC;
+
+ u8 m_tdr;
+ u8 m_tcr;
/* Callbacks */
devcb_write8 m_portA_cb_w;
@@ -434,9 +458,16 @@ protected:
devcb_read8 m_portB_cb_r;
devcb_read8 m_portC_cb_r;
+ /* Timers */
+ emu_timer *m_68705_timer;
+
+ TIMER_CALLBACK_MEMBER(timer_68705_increment);
+
+ virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
// device-level overrides
virtual void device_start() override;
+ virtual void device_reset() override;
// virtual void execute_set_input(int inputnum, int state) override;
diff --git a/src/devices/cpu/melps4/melps4.h b/src/devices/cpu/melps4/melps4.h
index d7668d35fb6..d3b84a01aa5 100644
--- a/src/devices/cpu/melps4/melps4.h
+++ b/src/devices/cpu/melps4/melps4.h
@@ -177,32 +177,32 @@ protected:
int m_d_pins; // number of D port pins and bitmask: 11 on '40,'41,'42,'44, 8 on '43, 12 on '45,'46, 16 on '47
int m_d_mask; // "
- uint8_t m_sm_page; // subroutine default page: 14 on '40 to '44, 2 on '45,'46, 0 on '47
- uint8_t m_int_page; // interrupt routine page: 12 on '40 to '44, 1 on '45,'46, 2 on '47
- uint8_t m_xami_mask; // mask option for XAMI opcode on '40,'41,'45 (0xf for others)
- uint16_t m_sp_mask; // SP opcode location(middle 4 bits): 7 on '40 to '46, 3 on '47
- uint16_t m_ba_op; // BA opcode location: 1 on '40 to '46, N/A on '47
- uint8_t m_stack_levels; // 3 levels on MELPS 4, 12 levels on MELPS 41/42
+ uint8_t m_sm_page; // subroutine default page: 14 on '40 to '44, 2 on '45,'46, 0 on '47
+ uint8_t m_int_page; // interrupt routine page: 12 on '40 to '44, 1 on '45,'46, 2 on '47
+ uint8_t m_xami_mask; // mask option for XAMI opcode on '40,'41,'45 (0xf for others)
+ uint16_t m_sp_mask; // SP opcode location(middle 4 bits): 7 on '40 to '46, 3 on '47
+ uint16_t m_ba_op; // BA opcode location: 1 on '40 to '46, N/A on '47
+ uint8_t m_stack_levels; // 3 levels on MELPS 4, 12 levels on MELPS 41/42
// internal state, misc regs
- uint16_t m_pc; // program counter (11 or 10-bit)
+ uint16_t m_pc; // program counter (11 or 10-bit)
uint16_t m_prev_pc;
- uint16_t m_stack[12]; // callstack (SK0-SKx, same size as PC)
+ uint16_t m_stack[12]; // callstack (SK0-SKx, same size as PC)
uint16_t m_op;
uint16_t m_prev_op;
- uint8_t m_bitmask; // opcode bit argument
+ uint8_t m_bitmask; // opcode bit argument
- uint16_t m_port_d; // last written port data
- uint8_t m_port_s; // "
- uint8_t m_port_f; // "
- uint8_t m_port_t; // "
+ uint16_t m_port_d; // last written port data
+ uint8_t m_port_s; // "
+ uint8_t m_port_f; // "
+ uint8_t m_port_t; // "
bool m_sm, m_sms; // subroutine mode flag + irq stack
bool m_ba_flag; // temp flag indicates BA opcode was executed
- uint8_t m_sp_param; // temp register holding SP opcode parameter
- uint8_t m_cps; // DP,CY or DP',CY' selected
+ uint8_t m_sp_param; // temp register holding SP opcode parameter
+ uint8_t m_cps; // DP,CY or DP',CY' selected
bool m_skip; // skip next opcode
- uint8_t m_inte; // interrupt enable flag
+ uint8_t m_inte; // interrupt enable flag
int m_intp; // external interrupt polarity ('40 to '44)
bool m_irqflag[3]; // irq flags: exf, 1f, 2f (external, timer 1, timer 2)
int m_int_state; // INT pin state
@@ -210,24 +210,24 @@ protected:
bool m_prohibit_irq; // interrupt is prohibited during certain opcodes
bool m_possible_irq; // indicate that irq needs to be rechecked
- uint8_t m_tmr_count[2]; // timer active count
- uint8_t m_tmr_reload; // timer(2) auto reload
+ uint8_t m_tmr_count[2]; // timer active count
+ uint8_t m_tmr_reload; // timer(2) auto reload
bool m_tmr_irq_enabled[2];
// work registers (unless specified, each is 4-bit)
- uint8_t m_a; // accumulator
- uint8_t m_b; // generic
- uint8_t m_e; // 8-bit register, hold data for S output
- uint8_t m_y, m_y2; // RAM index Y, Y' (Z.XX.YYYY is DP aka Data Pointer)
- uint8_t m_x, m_x2; // RAM index X, X', 2-bit
- uint8_t m_z, m_z2; // RAM index Z, Z', 1-bit, optional
- uint8_t m_cy, m_cy2; // carry flag(s)
-
- uint8_t m_h; // A/D converter H or generic
- uint8_t m_l; // A/D converter L or generic
- uint8_t m_c; // A/D converter counter
- uint8_t m_v; // timer control V
- uint8_t m_w; // timer control W
+ uint8_t m_a; // accumulator
+ uint8_t m_b; // generic
+ uint8_t m_e; // 8-bit register, hold data for S output
+ uint8_t m_y, m_y2; // RAM index Y, Y' (Z.XX.YYYY is DP aka Data Pointer)
+ uint8_t m_x, m_x2; // RAM index X, X', 2-bit
+ uint8_t m_z, m_z2; // RAM index Z, Z', 1-bit, optional
+ uint8_t m_cy, m_cy2; // carry flag(s)
+
+ uint8_t m_h; // A/D converter H or generic
+ uint8_t m_l; // A/D converter L or generic
+ uint8_t m_c; // A/D converter counter
+ uint8_t m_v; // timer control V
+ uint8_t m_w; // timer control W
// i/o handlers
devcb_read16 m_read_k;
diff --git a/src/devices/cpu/tms1000/tms0270.h b/src/devices/cpu/tms1000/tms0270.h
index 76bbd2f859b..77f596cda84 100644
--- a/src/devices/cpu/tms1000/tms0270.h
+++ b/src/devices/cpu/tms1000/tms0270.h
@@ -54,7 +54,7 @@ private:
uint8_t m_chipsel;
uint8_t m_ctl_out;
uint8_t m_ctl_dir;
- int m_pdc;
+ int m_pdc;
uint8_t m_o_latch_low;
uint8_t m_o_latch;
diff --git a/src/devices/cpu/tms1000/tms0970.cpp b/src/devices/cpu/tms1000/tms0970.cpp
index 96c60fe5183..b24f1ba6774 100644
--- a/src/devices/cpu/tms1000/tms0970.cpp
+++ b/src/devices/cpu/tms1000/tms0970.cpp
@@ -119,7 +119,7 @@ void tms0970_cpu_device::device_reset()
uint32_t mmask = m_mpla->read(msel);
mmask ^= 0x09fe; // invert active-negative
- // _____ _____ _____ _____ ______ _____ ______ _____ _____
+ // _____ _____ _____ _____ ______ _____ ______ _____ _____
const uint32_t md[15] = { M_CKM, M_CKP, M_YTP, M_MTP, M_ATN, M_NATN, M_MTN, M_15TN, M_CKN, M_NE, M_C8, M_CIN, M_AUTA, M_AUTY, M_STO };
for (int bit = 0; bit < 15; bit++)
diff --git a/src/devices/cpu/tms1000/tms0980.cpp b/src/devices/cpu/tms1000/tms0980.cpp
index b3678165d4a..5e9ea00d178 100644
--- a/src/devices/cpu/tms1000/tms0980.cpp
+++ b/src/devices/cpu/tms1000/tms0980.cpp
@@ -122,7 +122,7 @@ uint32_t tms0980_cpu_device::decode_micro(uint8_t sel)
// M_RSTR is specific to TMS02x0/TMS1980, it redirects to F_RSTR
// M_UNK1 is specific to TMS0270, unknown/unused yet and apparently not connected on every TMS0270
- // _______ ______ _____ _____ _____ _____ ______ _____ ______ _____ _____
+ // _______ ______ _____ _____ _____ _____ ______ _____ ______ _____ _____
const uint32_t md[22] = { M_NDMTP, M_DMTP, M_AUTY, M_AUTA, M_CKM, M_SSE, M_CKP, M_YTP, M_MTP, M_ATN, M_NATN, M_MTN, M_15TN, M_CKN, M_NE, M_C8, M_SSS, M_CME, M_CIN, M_STO, M_RSTR, M_UNK1 };
for (int bit = 0; bit < 22 && bit < m_mpla->outputs(); bit++)
diff --git a/src/devices/cpu/tms1000/tms1000.cpp b/src/devices/cpu/tms1000/tms1000.cpp
index 40add17105c..05ff12e03c6 100644
--- a/src/devices/cpu/tms1000/tms1000.cpp
+++ b/src/devices/cpu/tms1000/tms1000.cpp
@@ -114,7 +114,7 @@ void tms1000_cpu_device::device_reset()
for (int op = 0; op < 0x100; op++)
{
- // _____ _____ ______ _____ ______ _____ _____ _____ _____
+ // _____ _____ ______ _____ ______ _____ _____ _____ _____
const uint32_t md[16] = { M_STSL, M_AUTY, M_AUTA, M_CIN, M_C8, M_NE, M_CKN, M_15TN, M_MTN, M_NATN, M_ATN, M_MTP, M_YTP, M_CKP, M_CKM, M_STO };
uint16_t mask = m_mpla->read(op);
mask ^= 0x3fc8; // invert active-negative
diff --git a/src/devices/cpu/tms1000/tms1k_base.h b/src/devices/cpu/tms1000/tms1k_base.h
index c4fdb99f933..39ccbf31ea1 100644
--- a/src/devices/cpu/tms1000/tms1k_base.h
+++ b/src/devices/cpu/tms1000/tms1k_base.h
@@ -261,14 +261,14 @@ protected:
uint8_t m_ram_in;
uint8_t m_dam_in;
- int m_ram_out; // signed!
+ int m_ram_out; // signed!
uint8_t m_ram_address;
uint16_t m_rom_address;
uint16_t m_opcode;
uint32_t m_fixed;
uint32_t m_micro;
- int m_subcycle;
- int m_icount;
+ int m_subcycle;
+ int m_icount;
uint8_t m_o_index;
uint8_t m_o_pins; // how many O pins
diff --git a/src/devices/cpu/tms1000/tp0320.cpp b/src/devices/cpu/tms1000/tp0320.cpp
index 243ef3bb8e3..cf427cda589 100644
--- a/src/devices/cpu/tms1000/tp0320.cpp
+++ b/src/devices/cpu/tms1000/tp0320.cpp
@@ -74,7 +74,7 @@ uint32_t tp0320_cpu_device::decode_micro(uint8_t sel)
uint32_t mask = m_mpla->read(sel);
mask ^= 0x0bff0; // invert active-negative
- // _____ _______ ______ _____ _____ ______ _____ _____ ______ _____ _____
+ // _____ _______ ______ _____ _____ ______ _____ _____ ______ _____ _____
const uint32_t md[22] = { M_AUTA, M_AUTY, M_SSS, M_STO, M_YTP, M_NDMTP, M_DMTP, M_MTP, M_CKP, M_15TN, M_CKN, M_MTN, M_NATN, M_ATN, M_CME, M_CIN, M_SSE, M_CKM, M_NE, M_C8, M_SETR, M_RSTR };
for (int bit = 0; bit < 22 && bit < m_mpla->outputs(); bit++)
diff --git a/src/devices/cpu/ucom4/ucom4.h b/src/devices/cpu/ucom4/ucom4.h
index be7905f5065..ca0701734fb 100644
--- a/src/devices/cpu/ucom4/ucom4.h
+++ b/src/devices/cpu/ucom4/ucom4.h
@@ -169,15 +169,15 @@ protected:
int m_datawidth;
int m_prgmask;
int m_datamask;
- int m_family; // MCU family (43/44/45)
- int m_stack_levels; // number of callstack levels
+ int m_family; // MCU family (43/44/45)
+ int m_stack_levels; // number of callstack levels
uint16_t m_stack[3]; // max 3
uint8_t m_port_out[0x10]; // last value written to output port
uint8_t m_op;
uint8_t m_prev_op; // previous opcode
uint8_t m_arg; // opcode argument for 2-byte opcodes
uint8_t m_bitmask; // opcode bit argument
- bool m_skip; // skip next opcode
+ bool m_skip; // skip next opcode
int m_icount;
emu_timer *m_timer;
@@ -192,7 +192,7 @@ protected:
uint8_t m_timer_f; // timer out flag
uint8_t m_int_f; // interrupt flag
uint8_t m_inte_f; // interrupt enable flag
- int m_int_line; // interrupt pin state
+ int m_int_line; // interrupt pin state
// i/o handlers
devcb_read8 m_read_a;
diff --git a/src/devices/machine/6821pia.cpp b/src/devices/machine/6821pia.cpp
index d47e7ffe1cb..1951beee11b 100644
--- a/src/devices/machine/6821pia.cpp
+++ b/src/devices/machine/6821pia.cpp
@@ -9,14 +9,27 @@
#include "emu.h"
#include "6821pia.h"
-
//**************************************************************************
// MACROS
//**************************************************************************
-#define VERBOSE 0
+#define LOG_GENERAL 0x01
+#define LOG_SETUP 0x02
+#define LOG_PRINTF 0x04
+#define LOG_CA1 0x08
+
+#define VERBOSE 0 //(LOG_PRINTF | LOG_SETUP | LOG_GENERAL)
+
+#define LOGMASK(mask, ...) do { if (VERBOSE & mask) logerror(__VA_ARGS__); } while (0)
+#define LOGLEVEL(mask, level, ...) do { if ((VERBOSE & mask) >= level) logerror(__VA_ARGS__); } while (0)
+
+#define LOG(...) LOGMASK(LOG_GENERAL, __VA_ARGS__)
+#define LOGSETUP(...) LOGMASK(LOG_SETUP, __VA_ARGS__)
+#define LOGCA1(...) LOGMASK(LOG_CA1, __VA_ARGS__)
-#define LOG(x) do { if (VERBOSE) logerror x; } while (0)
+#if VERBOSE & LOG_PRINTF
+#define logerror printf
+#endif
#define PIA_IRQ1 (0x80)
#define PIA_IRQ2 (0x40)
@@ -426,7 +439,7 @@ uint8_t pia6821_device::port_a_r()
}
}
- LOG(("PIA #%s: port A read = %02X\n", tag(), ret));
+ LOG("PIA #%s: port A read = %02X\n", tag(), ret);
return ret;
}
@@ -440,7 +453,7 @@ uint8_t pia6821_device::ddr_a_r()
{
uint8_t ret = m_ddr_a;
- LOG(("PIA #%s: DDR A read = %02X\n", tag(), ret));
+ LOG("PIA #%s: DDR A read = %02X\n", tag(), ret);
return ret;
}
@@ -468,7 +481,7 @@ uint8_t pia6821_device::port_b_r()
m_irq_b2 = false;
update_interrupts();
- LOG(("PIA #%s: port B read = %02X\n", tag(), ret));
+ LOG("PIA #%s: port B read = %02X\n", tag(), ret);
return ret;
}
@@ -482,7 +495,7 @@ uint8_t pia6821_device::ddr_b_r()
{
uint8_t ret = m_ddr_b;
- LOG(("PIA #%s: DDR B read = %02X\n", tag(), ret));
+ LOG("PIA #%s: DDR B read = %02X\n", tag(), ret);
return ret;
}
@@ -531,7 +544,7 @@ uint8_t pia6821_device::control_a_r()
ret |= PIA_IRQ2;
}
- LOG(("PIA #%s: control A read = %02X\n", tag(), ret));
+ LOG("PIA #%s: control A read = %02X\n", tag(), ret);
return ret;
}
@@ -576,7 +589,7 @@ uint8_t pia6821_device::control_b_r()
ret |= PIA_IRQ2;
}
- LOG(("PIA #%s: control B read = %02X\n", tag(), ret));
+ LOG("PIA #%s: control B read = %02X\n", tag(), ret);
return ret;
}
@@ -638,7 +651,7 @@ void pia6821_device::send_to_out_a_func(const char* message)
// input pins are pulled high
uint8_t data = get_out_a_value();
- LOG(("PIA #%s: %s = %02X\n", tag(), message, data));
+ LOG("PIA #%s: %s = %02X\n", tag(), message, data);
if(!m_out_a_handler.isnull())
{
@@ -665,7 +678,7 @@ void pia6821_device::send_to_out_b_func(const char* message)
// input pins are high-impedance - we just send them as zeros for backwards compatibility
uint8_t data = get_out_b_value();
- LOG(("PIA #%s: %s = %02X\n", tag(), message, data));
+ LOG("PIA #%s: %s = %02X\n", tag(), message, data);
if(!m_out_b_handler.isnull())
{
@@ -704,15 +717,15 @@ void pia6821_device::ddr_a_w(uint8_t data)
{
if(data == 0x00)
{
- LOG(("PIA #%s: DDR A write = %02X (input mode)\n", tag(), data));
+ LOG("PIA #%s: DDR A write = %02X (input mode)\n", tag(), data);
}
else if(data == 0xff)
{
- LOG(("PIA #%s: DDR A write = %02X (output mode)\n", tag(), data));
+ LOG("PIA #%s: DDR A write = %02X (output mode)\n", tag(), data);
}
else
{
- LOG(("PIA #%s: DDR A write = %02X (mixed mode)\n", tag(), data));
+ LOG("PIA #%s: DDR A write = %02X (mixed mode)\n", tag(), data);
}
if(m_ddr_a != data)
@@ -759,15 +772,15 @@ void pia6821_device::ddr_b_w(uint8_t data)
{
if (data == 0x00)
{
- LOG(("PIA #%s: DDR B write = %02X (input mode)\n", tag(), data));
+ LOG("PIA #%s: DDR B write = %02X (input mode)\n", tag(), data);
}
else if (data == 0xff)
{
- LOG(("PIA #%s: DDR B write = %02X (output mode)\n", tag(), data));
+ LOG("PIA #%s: DDR B write = %02X (output mode)\n", tag(), data);
}
else
{
- LOG(("PIA #%s: DDR B write = %02X (mixed mode)\n", tag(), data));
+ LOG("PIA #%s: DDR B write = %02X (mixed mode)\n", tag(), data);
}
if(m_ddr_b != data)
@@ -789,7 +802,7 @@ void pia6821_device::control_a_w(uint8_t data)
// bit 7 and 6 are read only
data &= 0x3f;
- LOG(("PIA #%s: control A write = %02X\n", tag(), data));
+ LOG("PIA #%s: control A write = %02X\n", tag(), data);
// update the control register
m_ctl_a = data;
@@ -829,7 +842,7 @@ void pia6821_device::control_b_w(uint8_t data)
// bit 7 and 6 are read only
data &= 0x3f;
- LOG(("PIA #%s: control B write = %02X\n", tag(), data));
+ LOG("PIA #%s: control B write = %02X\n", tag(), data);
// update the control register
m_ctl_b = data;
@@ -902,7 +915,7 @@ void pia6821_device::set_a_input(uint8_t data, uint8_t z_mask)
{
assert_always(m_in_a_handler.isnull(), "pia6821_porta_w() called when in_a_func implemented");
- LOG(("PIA #%s: set input port A = %02X\n", tag(), data));
+ LOG("PIA #%s: set input port A = %02X\n", tag(), data);
m_in_a = data;
m_port_a_z_mask = z_mask;
@@ -938,12 +951,12 @@ uint8_t pia6821_device::a_output()
WRITE_LINE_MEMBER( pia6821_device::ca1_w )
{
- LOG(("PIA #%s: set input CA1 = %d\n", tag(), state));
+ LOGCA1("PIA #%s: set input CA1 = %d\n", tag(), state);
// the new state has caused a transition
if((m_in_ca1 != state) && ((state && C1_LOW_TO_HIGH(m_ctl_a)) || (!state && C1_HIGH_TO_LOW(m_ctl_a))))
{
- LOG(("PIA #%s: CA1 triggering\n", tag()));
+ LOGCA1("PIA #%s: CA1 triggering\n", tag());
// mark the IRQ
m_irq_a1 = true;
@@ -970,12 +983,12 @@ WRITE_LINE_MEMBER( pia6821_device::ca1_w )
WRITE_LINE_MEMBER( pia6821_device::ca2_w )
{
- LOG(("PIA #%s: set input CA2 = %d\n", tag(), state));
+ LOG("PIA #%s: set input CA2 = %d\n", tag(), state);
// if input mode and the new state has caused a transition
if(C2_INPUT(m_ctl_a) && (m_in_ca2 != state) && ((state && C2_LOW_TO_HIGH(m_ctl_a)) || (!state && C2_HIGH_TO_LOW(m_ctl_a))))
{
- LOG(("PIA #%s: CA2 triggering\n", tag()));
+ LOG("PIA #%s: CA2 triggering\n", tag());
// mark the IRQ
m_irq_a2 = true;
@@ -1025,7 +1038,7 @@ void pia6821_device::portb_w(uint8_t data)
{
assert_always(m_in_b_handler.isnull(), "pia_set_input_b() called when in_b_func implemented");
- LOG(("PIA #%s: set input port B = %02X\n", tag(), data));
+ LOG("PIA #%s: set input port B = %02X\n", tag(), data);
m_in_b = data;
m_in_b_pushed = true;
@@ -1050,12 +1063,12 @@ uint8_t pia6821_device::b_output()
WRITE_LINE_MEMBER( pia6821_device::cb1_w )
{
- LOG(("PIA #%s: set input CB1 = %d\n", tag(), state));
+ LOG("PIA #%s: set input CB1 = %d\n", tag(), state);
// the new state has caused a transition
if((m_in_cb1 != state) && ((state && C1_LOW_TO_HIGH(m_ctl_b)) || (!state && C1_HIGH_TO_LOW(m_ctl_b))))
{
- LOG(("PIA #%s: CB1 triggering\n", tag()));
+ LOG("PIA #%s: CB1 triggering\n", tag());
// mark the IRQ
m_irq_b1 = 1;
@@ -1081,14 +1094,14 @@ WRITE_LINE_MEMBER( pia6821_device::cb1_w )
WRITE_LINE_MEMBER( pia6821_device::cb2_w )
{
- LOG(("PIA #%s: set input CB2 = %d\n", tag(), state));
+ LOG("PIA #%s: set input CB2 = %d\n", tag(), state);
// if input mode and the new state has caused a transition
if (C2_INPUT(m_ctl_b) &&
(m_in_cb2 != state) &&
((state && C2_LOW_TO_HIGH(m_ctl_b)) || (!state && C2_HIGH_TO_LOW(m_ctl_b))))
{
- LOG(("PIA #%s: CB2 triggering\n", tag()));
+ LOG("PIA #%s: CB2 triggering\n", tag());
// mark the IRQ
m_irq_b2 = 1;
diff --git a/src/devices/machine/gen_latch.cpp b/src/devices/machine/gen_latch.cpp
index f7848abfaee..f41f6df5fca 100644
--- a/src/devices/machine/gen_latch.cpp
+++ b/src/devices/machine/gen_latch.cpp
@@ -5,6 +5,7 @@
Generic 8bit and 16 bit latch devices
***************************************************************************/
+
#include "emu.h"
#include "gen_latch.h"
@@ -13,26 +14,79 @@
//**************************************************************************
const device_type GENERIC_LATCH_8 = &device_creator<generic_latch_8_device>;
-
+const device_type GENERIC_LATCH_16 = &device_creator<generic_latch_16_device>;
//**************************************************************************
// LIVE DEVICE
//**************************************************************************
//-------------------------------------------------
+// generic_latch_base_device - constructor
+//-------------------------------------------------
+
+generic_latch_base_device::generic_latch_base_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, u32 clock, const char *shortname, const char *source) :
+ device_t(mconfig, type, name, tag, owner, clock, shortname, source),
+ m_latch_written(false),
+ m_data_pending_cb(*this)
+{
+}
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void generic_latch_base_device::device_start()
+{
+ m_data_pending_cb.resolve_safe();
+ save_item(NAME(m_latch_written));
+}
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void generic_latch_base_device::device_reset()
+{
+ m_latch_written = false;
+}
+
+//-------------------------------------------------
+// pending_r - tell whether the latch is waiting
+// to be read
+//-------------------------------------------------
+
+READ_LINE_MEMBER(generic_latch_base_device::pending_r)
+{
+ return m_latch_written ? 1 : 0;
+}
+
+//-------------------------------------------------
+// set_latch_written - helper to signal that latch
+// has been written or has been read
+//-------------------------------------------------
+
+void generic_latch_base_device::set_latch_written(bool latch_written)
+{
+ if (m_latch_written != latch_written)
+ {
+ m_latch_written = latch_written;
+ m_data_pending_cb(latch_written ? 1 : 0);
+ }
+}
+
+//-------------------------------------------------
// generic_latch_8_device - constructor
//-------------------------------------------------
-generic_latch_8_device::generic_latch_8_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
- device_t(mconfig, GENERIC_LATCH_8, "Generic 8-bit latch", tag, owner, clock, "generic_latch_8", __FILE__),
- m_latched_value(0),
- m_latch_read(0)
+generic_latch_8_device::generic_latch_8_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
+ generic_latch_base_device(mconfig, GENERIC_LATCH_8, "Generic 8-bit latch", tag, owner, clock, "generic_latch_8", __FILE__),
+ m_latched_value(0)
{
}
READ8_MEMBER( generic_latch_8_device::read )
{
- m_latch_read = 1;
+ set_latch_written(false);
return m_latched_value;
}
@@ -66,17 +120,17 @@ WRITE_LINE_MEMBER( generic_latch_8_device::clear_w )
// callback to set a latch value
//-------------------------------------------------
-void generic_latch_8_device::sync_callback(void *ptr, int32_t param)
+void generic_latch_8_device::sync_callback(void *ptr, s32 param)
{
- uint8_t value = param;
+ u8 value = param;
- // if the latch hasn't been read and the value is changed, log a warning
- if (!m_latch_read && m_latched_value != value)
- logerror("Warning: latch %s written before being read. Previous: %02x, new: %02x\n", tag(), m_latched_value, value);
+ // if the latch has been written and the value is changed, log a warning
+ if (is_latch_written() && m_latched_value != value)
+ logerror("Warning: latch written before being read. Previous: %02x, new: %02x\n", m_latched_value, value);
// store the new value and mark it not read
m_latched_value = value;
- m_latch_read = 0;
+ set_latch_written(true);
}
//-------------------------------------------------
@@ -86,35 +140,23 @@ void generic_latch_8_device::sync_callback(void *ptr, int32_t param)
void generic_latch_8_device::device_start()
{
// register for state saving
+ generic_latch_base_device::device_start();
save_item(NAME(m_latched_value));
- save_item(NAME(m_latch_read));
}
-//**************************************************************************
-// DEVICE DEFINITIONS
-//**************************************************************************
-
-const device_type GENERIC_LATCH_16 = &device_creator<generic_latch_16_device>;
-
-
-//**************************************************************************
-// LIVE DEVICE
-//**************************************************************************
-
//-------------------------------------------------
// generic_latch_16_device - constructor
//-------------------------------------------------
-generic_latch_16_device::generic_latch_16_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
- device_t(mconfig, GENERIC_LATCH_16, "Generic 16-bit latch", tag, owner, clock, "generic_latch_16", __FILE__),
- m_latched_value(0),
- m_latch_read(0)
+generic_latch_16_device::generic_latch_16_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
+ generic_latch_base_device(mconfig, GENERIC_LATCH_16, "Generic 16-bit latch", tag, owner, clock, "generic_latch_16", __FILE__),
+ m_latched_value(0)
{
}
READ16_MEMBER( generic_latch_16_device::read )
{
- m_latch_read = 1;
+ set_latch_written(false);
return m_latched_value;
}
@@ -148,17 +190,17 @@ WRITE_LINE_MEMBER( generic_latch_16_device::clear_w )
// callback to set a latch value
//-------------------------------------------------
-void generic_latch_16_device::sync_callback(void *ptr, int32_t param)
+void generic_latch_16_device::sync_callback(void *ptr, s32 param)
{
- uint16_t value = param;
+ u16 value = param;
- // if the latch hasn't been read and the value is changed, log a warning
- if (!m_latch_read && m_latched_value != value)
- logerror("Warning: latch %s written before being read. Previous: %02x, new: %02x\n", tag(), m_latched_value, value);
+ // if the latch has been written and the value is changed, log a warning
+ if (is_latch_written() && m_latched_value != value)
+ logerror("Warning: latch written before being read. Previous: %02x, new: %02x\n", m_latched_value, value);
// store the new value and mark it not read
m_latched_value = value;
- m_latch_read = 0;
+ set_latch_written(true);
}
//-------------------------------------------------
@@ -168,6 +210,6 @@ void generic_latch_16_device::sync_callback(void *ptr, int32_t param)
void generic_latch_16_device::device_start()
{
// register for state saving
+ generic_latch_base_device::device_start();
save_item(NAME(m_latched_value));
- save_item(NAME(m_latch_read));
}
diff --git a/src/devices/machine/gen_latch.h b/src/devices/machine/gen_latch.h
index 8076f8c7b14..2c000d2fce7 100644
--- a/src/devices/machine/gen_latch.h
+++ b/src/devices/machine/gen_latch.h
@@ -11,6 +11,8 @@
#ifndef __GEN_LATCH_H__
#define __GEN_LATCH_H__
+#include "emu.h"
+
//**************************************************************************
// INTERFACE CONFIGURATION MACROS
//**************************************************************************
@@ -21,17 +23,47 @@
#define MCFG_GENERIC_LATCH_16_ADD(_tag) \
MCFG_DEVICE_ADD(_tag, GENERIC_LATCH_16, 0)
+#define MCFG_GENERIC_LATCH_DATA_PENDING_CB(_devcb) \
+ devcb = &generic_latch_base_device::set_data_pending_callback(*device, DEVCB_##_devcb);
+
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
+// ======================> generic_latch_base_device
+
+class generic_latch_base_device : public device_t
+{
+protected:
+ // construction/destruction
+ generic_latch_base_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, u32 clock, const char *shortname, const char *source);
+
+public:
+ // static configuration
+ template<class _Object> static devcb_base &set_data_pending_callback(device_t &device, _Object object) { return downcast<generic_latch_base_device &>(device).m_data_pending_cb.set_callback(object); }
+
+ DECLARE_READ_LINE_MEMBER(pending_r);
+
+protected:
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+ bool is_latch_written() const { return m_latch_written; }
+ void set_latch_written(bool latch_written);
+
+private:
+ bool m_latch_written;
+ devcb_write_line m_data_pending_cb;
+};
+
+
// ======================> generic_latch_8_device
-class generic_latch_8_device : public device_t
+class generic_latch_8_device : public generic_latch_base_device
{
public:
// construction/destruction
- generic_latch_8_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ generic_latch_8_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
DECLARE_READ8_MEMBER( read );
DECLARE_WRITE8_MEMBER( write );
@@ -41,15 +73,15 @@ public:
DECLARE_WRITE_LINE_MEMBER( preset_w );
DECLARE_WRITE_LINE_MEMBER( clear_w );
- void preset_w(uint16_t value) { m_latched_value = value; }
+ void preset_w(u8 value) { m_latched_value = value; }
protected:
virtual void device_start() override;
- void sync_callback(void *ptr, int32_t param);
+ void sync_callback(void *ptr, s32 param);
+
private:
- uint16_t m_latched_value;
- uint8_t m_latch_read;
+ u8 m_latched_value;
};
// device type definition
@@ -58,11 +90,11 @@ extern const device_type GENERIC_LATCH_8;
// ======================> generic_latch_16_device
-class generic_latch_16_device : public device_t
+class generic_latch_16_device : public generic_latch_base_device
{
public:
// construction/destruction
- generic_latch_16_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ generic_latch_16_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
DECLARE_READ16_MEMBER( read );
DECLARE_WRITE16_MEMBER( write );
@@ -72,13 +104,15 @@ public:
DECLARE_WRITE_LINE_MEMBER( preset_w );
DECLARE_WRITE_LINE_MEMBER( clear_w );
+ void preset_w(u16 value) { m_latched_value = value; }
+
protected:
virtual void device_start() override;
- void sync_callback(void *ptr, int32_t param);
+ void sync_callback(void *ptr, s32 param);
+
private:
- uint16_t m_latched_value;
- uint8_t m_latch_read;
+ u16 m_latched_value;
};
// device type definition
diff --git a/src/devices/machine/hd63450.h b/src/devices/machine/hd63450.h
index 5cee35500fc..76e9da87b66 100644
--- a/src/devices/machine/hd63450.h
+++ b/src/devices/machine/hd63450.h
@@ -3,6 +3,9 @@
/*
Hitachi HD63450 DMA Controller
*/
+#ifndef HD63450_H
+#define HD63450_H
+#pragma once
#include "emu.h"
@@ -153,3 +156,4 @@ private:
};
extern const device_type HD63450;
+#endif // HD63450_H
diff --git a/src/devices/machine/mc68681.cpp b/src/devices/machine/mc68681.cpp
index 577b9355c39..2f79b82da1b 100644
--- a/src/devices/machine/mc68681.cpp
+++ b/src/devices/machine/mc68681.cpp
@@ -1,7 +1,9 @@
// license:BSD-3-Clause
// copyright-holders:Mariusz Wojcieszek, R. Belmont
/*
+ 2681 DUART
68681 DUART
+ 28C94 QUART
Written by Mariusz Wojcieszek
Updated by Jonathan Gevaryahu AKA Lord Nightmare
@@ -50,9 +52,12 @@ static const int baud_rate_ACR_1[] = { 75, 110, 134, 150, 300, 600, 1200, 2000,
#define CHANA_TAG "cha"
#define CHANB_TAG "chb"
+#define CHANC_TAG "chc"
+#define CHAND_TAG "chd"
// device type definition
const device_type MC68681 = &device_creator<mc68681_device>;
+const device_type SC28C94 = &device_creator<sc28c94_device>;
const device_type MC68681_CHANNEL = &device_creator<mc68681_channel>;
MACHINE_CONFIG_FRAGMENT( duart68681 )
@@ -60,17 +65,28 @@ MACHINE_CONFIG_FRAGMENT( duart68681 )
MCFG_DEVICE_ADD(CHANB_TAG, MC68681_CHANNEL, 0)
MACHINE_CONFIG_END
+MACHINE_CONFIG_FRAGMENT( quart28c94 )
+ MCFG_DEVICE_ADD(CHANA_TAG, MC68681_CHANNEL, 0)
+ MCFG_DEVICE_ADD(CHANB_TAG, MC68681_CHANNEL, 0)
+ MCFG_DEVICE_ADD(CHANC_TAG, MC68681_CHANNEL, 0)
+ MCFG_DEVICE_ADD(CHAND_TAG, MC68681_CHANNEL, 0)
+MACHINE_CONFIG_END
+
//**************************************************************************
// LIVE DEVICE
//**************************************************************************
-mc68681_device::mc68681_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : device_t(mconfig, MC68681, "MC68681 DUART", tag, owner, clock, "mc68681", __FILE__),
+mc68681_base_device::mc68681_base_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, uint32_t clock, const char *shortname, const char *source)
+ : device_t(mconfig, type, name, tag, owner, clock, shortname, source),
m_chanA(*this, CHANA_TAG),
m_chanB(*this, CHANB_TAG),
+ m_chanC(*this, CHANC_TAG),
+ m_chanD(*this, CHAND_TAG),
write_irq(*this),
write_a_tx(*this),
write_b_tx(*this),
+ write_c_tx(*this),
+ write_d_tx(*this),
read_inport(*this),
write_outport(*this),
ip3clk(0),
@@ -83,14 +99,24 @@ mc68681_device::mc68681_device(const machine_config &mconfig, const char *tag, d
{
}
+mc68681_device::mc68681_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : mc68681_base_device(mconfig, MC68681, "MC68681 DUART", tag, owner, clock, "mc68681", __FILE__)
+{
+}
+
+sc28c94_device::sc28c94_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : mc68681_base_device(mconfig, SC28C94, "SC28C94 QUART", tag, owner, clock, "sc28c94", __FILE__)
+{
+}
+
//-------------------------------------------------
// static_set_clocks - configuration helper to set
// the external clocks
//-------------------------------------------------
-void mc68681_device::static_set_clocks(device_t &device, int clk3, int clk4, int clk5, int clk6)
+void mc68681_base_device::static_set_clocks(device_t &device, int clk3, int clk4, int clk5, int clk6)
{
- mc68681_device &duart = downcast<mc68681_device &>(device);
+ mc68681_base_device &duart = downcast<mc68681_base_device &>(device);
duart.ip3clk = clk3;
duart.ip4clk = clk4;
duart.ip5clk = clk5;
@@ -101,15 +127,17 @@ void mc68681_device::static_set_clocks(device_t &device, int clk3, int clk4, int
device start callback
-------------------------------------------------*/
-void mc68681_device::device_start()
+void mc68681_base_device::device_start()
{
write_irq.resolve_safe();
write_a_tx.resolve_safe();
write_b_tx.resolve_safe();
+ write_c_tx.resolve_safe();
+ write_d_tx.resolve_safe();
read_inport.resolve();
write_outport.resolve_safe();
- duart_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(mc68681_device::duart_timer_callback),this), nullptr);
+ duart_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(mc68681_base_device::duart_timer_callback),this), nullptr);
save_item(NAME(ACR));
save_item(NAME(IMR));
@@ -125,7 +153,7 @@ void mc68681_device::device_start()
device reset callback
-------------------------------------------------*/
-void mc68681_device::device_reset()
+void mc68681_base_device::device_reset()
{
ACR = 0; /* Interrupt Vector Register */
IVR = 0x0f; /* Interrupt Vector Register */
@@ -141,12 +169,17 @@ void mc68681_device::device_reset()
write_outport(OPR ^ 0xff);
}
-machine_config_constructor mc68681_device::device_mconfig_additions() const
+machine_config_constructor mc68681_base_device::device_mconfig_additions() const
{
return MACHINE_CONFIG_NAME( duart68681 );
}
-void mc68681_device::update_interrupts()
+machine_config_constructor sc28c94_device::device_mconfig_additions() const
+{
+ return MACHINE_CONFIG_NAME( quart28c94 );
+}
+
+void mc68681_base_device::update_interrupts()
{
/* update SR state and update interrupt ISR state for the following bits:
SRn: bits 7-4: handled elsewhere.
@@ -208,7 +241,7 @@ void mc68681_device::update_interrupts()
}
}
-double mc68681_device::duart68681_get_ct_rate()
+double mc68681_base_device::duart68681_get_ct_rate()
{
double rate = 0.0f;
@@ -250,19 +283,19 @@ double mc68681_device::duart68681_get_ct_rate()
return rate;
}
-uint16_t mc68681_device::duart68681_get_ct_count()
+uint16_t mc68681_base_device::duart68681_get_ct_count()
{
double clock = duart68681_get_ct_rate();
return (duart_timer->remaining() * clock).as_double();
}
-void mc68681_device::duart68681_start_ct(int count)
+void mc68681_base_device::duart68681_start_ct(int count)
{
double clock = duart68681_get_ct_rate();
duart_timer->adjust(attotime::from_hz(clock) * count, 0);
}
-TIMER_CALLBACK_MEMBER( mc68681_device::duart_timer_callback )
+TIMER_CALLBACK_MEMBER( mc68681_base_device::duart_timer_callback )
{
if (ACR & 0x40)
{
@@ -320,13 +353,41 @@ TIMER_CALLBACK_MEMBER( mc68681_device::duart_timer_callback )
}
-READ8_MEMBER( mc68681_device::read )
+READ8_MEMBER( sc28c94_device::read )
+{
+ uint8_t r = 0;
+ offset &= 0x1f;
+
+ if (offset < 0x10)
+ {
+ return mc68681_base_device::read(space, offset, mem_mask);
+ }
+
+ switch (offset)
+ {
+ case 0x10: /* MR1A/MR2C */
+ case 0x11: /* SRC */
+ case 0x13: /* Rx Holding Register C */
+ r = m_chanC->read_chan_reg(offset & 3);
+ break;
+
+ case 0x18: /* MR1D/MR2D */
+ case 0x19: /* SRD */
+ case 0x1b: /* RHRD */
+ r = m_chanD->read_chan_reg(offset & 3);
+ break;
+ }
+
+ return r;
+}
+
+READ8_MEMBER( mc68681_base_device::read )
{
uint8_t r = 0xff;
offset &= 0xf;
- LOG(( "Reading 68681 (%s) reg %x (%s) ", tag(), offset, duart68681_reg_read_names[offset] ));
+ LOG(( "Reading 68681 (%s) reg %x (%s)\n", tag(), offset, duart68681_reg_read_names[offset] ));
switch (offset)
{
@@ -424,7 +485,34 @@ READ8_MEMBER( mc68681_device::read )
return r;
}
-WRITE8_MEMBER( mc68681_device::write )
+WRITE8_MEMBER( sc28c94_device::write )
+{
+ offset &= 0x1f;
+
+ if (offset < 0x10)
+ {
+ mc68681_base_device::write(space, offset, data, mem_mask);
+ }
+
+ switch(offset)
+ {
+ case 0x10: /* MRC */
+ case 0x11: /* CSRC */
+ case 0x12: /* CRC */
+ case 0x13: /* THRC */
+ m_chanC->write_chan_reg(offset&3, data);
+ break;
+
+ case 0x18: /* MRC */
+ case 0x19: /* CSRC */
+ case 0x1a: /* CRC */
+ case 0x1b: /* THRC */
+ m_chanD->write_chan_reg(offset&3, data);
+ break;
+ }
+}
+
+WRITE8_MEMBER( mc68681_base_device::write )
{
offset &= 0x0f;
LOG(( "Writing 68681 (%s) reg %x (%s) with %04x\n", tag(), offset, duart68681_reg_write_names[offset], data ));
@@ -516,7 +604,7 @@ WRITE8_MEMBER( mc68681_device::write )
}
}
-WRITE_LINE_MEMBER( mc68681_device::ip0_w )
+WRITE_LINE_MEMBER( mc68681_base_device::ip0_w )
{
uint8_t newIP = (IP_last_state & ~0x01) | ((state == ASSERT_LINE) ? 1 : 0);
@@ -536,7 +624,7 @@ WRITE_LINE_MEMBER( mc68681_device::ip0_w )
IP_last_state = newIP;
}
-WRITE_LINE_MEMBER( mc68681_device::ip1_w )
+WRITE_LINE_MEMBER( mc68681_base_device::ip1_w )
{
uint8_t newIP = (IP_last_state & ~0x02) | ((state == ASSERT_LINE) ? 2 : 0);
@@ -556,7 +644,7 @@ WRITE_LINE_MEMBER( mc68681_device::ip1_w )
IP_last_state = newIP;
}
-WRITE_LINE_MEMBER( mc68681_device::ip2_w )
+WRITE_LINE_MEMBER( mc68681_base_device::ip2_w )
{
uint8_t newIP = (IP_last_state & ~0x04) | ((state == ASSERT_LINE) ? 4 : 0);
@@ -576,7 +664,7 @@ WRITE_LINE_MEMBER( mc68681_device::ip2_w )
IP_last_state = newIP;
}
-WRITE_LINE_MEMBER( mc68681_device::ip3_w )
+WRITE_LINE_MEMBER( mc68681_base_device::ip3_w )
{
uint8_t newIP = (IP_last_state & ~0x08) | ((state == ASSERT_LINE) ? 8 : 0);
@@ -596,21 +684,21 @@ WRITE_LINE_MEMBER( mc68681_device::ip3_w )
IP_last_state = newIP;
}
-WRITE_LINE_MEMBER( mc68681_device::ip4_w )
+WRITE_LINE_MEMBER( mc68681_base_device::ip4_w )
{
uint8_t newIP = (IP_last_state & ~0x10) | ((state == ASSERT_LINE) ? 0x10 : 0);
// TODO: special mode for ip4 (Ch. A Rx clock)
IP_last_state = newIP;
}
-WRITE_LINE_MEMBER( mc68681_device::ip5_w )
+WRITE_LINE_MEMBER( mc68681_base_device::ip5_w )
{
uint8_t newIP = (IP_last_state & ~0x20) | ((state == ASSERT_LINE) ? 0x20 : 0);
// TODO: special mode for ip5 (Ch. B Tx clock)
IP_last_state = newIP;
}
-mc68681_channel *mc68681_device::get_channel(int chan)
+mc68681_channel *mc68681_base_device::get_channel(int chan)
{
if (chan == 0)
{
@@ -620,7 +708,7 @@ mc68681_channel *mc68681_device::get_channel(int chan)
return m_chanB;
}
-int mc68681_device::calc_baud(int ch, uint8_t data)
+int mc68681_base_device::calc_baud(int ch, uint8_t data)
{
int baud_rate;
@@ -661,15 +749,16 @@ int mc68681_device::calc_baud(int ch, uint8_t data)
LOG(( "Unsupported transmitter clock: channel %d, clock select = %02x\n", ch, data ));
}
+ //printf("%s ch %d setting baud to %d\n", tag(), ch, baud_rate);
return baud_rate;
}
-void mc68681_device::clear_ISR_bits(int mask)
+void mc68681_base_device::clear_ISR_bits(int mask)
{
ISR &= ~mask;
}
-void mc68681_device::set_ISR_bits(int mask)
+void mc68681_base_device::set_ISR_bits(int mask)
{
ISR |= mask;
}
@@ -690,7 +779,7 @@ mc68681_channel::mc68681_channel(const machine_config &mconfig, const char *tag,
void mc68681_channel::device_start()
{
- m_uart = downcast<mc68681_device *>(owner());
+ m_uart = downcast<mc68681_base_device *>(owner());
m_ch = m_uart->get_ch(this); // get our channel number
save_item(NAME(CR));
@@ -793,15 +882,23 @@ void mc68681_channel::tra_callback()
if ((MR2&0xC0) != 0x80)
{
int bit = transmit_register_get_data_bit();
-// printf("%s ch %d transmit %d\n", tag(), m_ch, bit);
+ //printf("%s ch %d transmit %d\n", tag(), m_ch, bit);
if (m_ch == 0)
{
m_uart->write_a_tx(bit);
}
- else
+ else if (m_ch == 1)
{
m_uart->write_b_tx(bit);
}
+ else if (m_ch == 2)
+ {
+ m_uart->write_c_tx(bit);
+ }
+ else if (m_ch == 3)
+ {
+ m_uart->write_d_tx(bit);
+ }
}
else // must call this to advance the transmitter
{
@@ -1157,7 +1254,7 @@ void mc68681_channel::write_TX(uint8_t data)
printf("Write %02x to TX when TX not ready!\n", data);
}*/
-// printf("%s ch %d Tx %02x\n", tag(), m_ch, data);
+ //printf("%s ch %d Tx %02x\n", tag(), m_ch, data);
tx_ready = 0;
SR &= ~STATUS_TRANSMITTER_READY;
diff --git a/src/devices/machine/mc68681.h b/src/devices/machine/mc68681.h
index f2093fc66cc..b502a33db12 100644
--- a/src/devices/machine/mc68681.h
+++ b/src/devices/machine/mc68681.h
@@ -11,28 +11,38 @@
MCFG_DEVICE_REPLACE(_tag, MC68681, _clock)
#define MCFG_MC68681_IRQ_CALLBACK(_cb) \
- devcb = &mc68681_device::set_irq_cb(*device, DEVCB_##_cb);
+ devcb = &mc68681_base_device::set_irq_cb(*device, DEVCB_##_cb);
#define MCFG_MC68681_A_TX_CALLBACK(_cb) \
- devcb = &mc68681_device::set_a_tx_cb(*device, DEVCB_##_cb);
+ devcb = &mc68681_base_device::set_a_tx_cb(*device, DEVCB_##_cb);
#define MCFG_MC68681_B_TX_CALLBACK(_cb) \
- devcb = &mc68681_device::set_b_tx_cb(*device, DEVCB_##_cb);
+ devcb = &mc68681_base_device::set_b_tx_cb(*device, DEVCB_##_cb);
// deprecated: use ipX_w() instead
#define MCFG_MC68681_INPORT_CALLBACK(_cb) \
- devcb = &mc68681_device::set_inport_cb(*device, DEVCB_##_cb);
+ devcb = &mc68681_base_device::set_inport_cb(*device, DEVCB_##_cb);
#define MCFG_MC68681_OUTPORT_CALLBACK(_cb) \
- devcb = &mc68681_device::set_outport_cb(*device, DEVCB_##_cb);
+ devcb = &mc68681_base_device::set_outport_cb(*device, DEVCB_##_cb);
#define MCFG_MC68681_SET_EXTERNAL_CLOCKS(_a, _b, _c, _d) \
- mc68681_device::static_set_clocks(*device, _a, _b, _c, _d);
+ mc68681_base_device::static_set_clocks(*device, _a, _b, _c, _d);
+
+// SC28C94 specific callbacks
+#define MCFG_SC28C94_ADD(_tag, _clock) \
+ MCFG_DEVICE_ADD(_tag, SC28C94, _clock)
+
+#define MCFG_SC28C94_C_TX_CALLBACK(_cb) \
+ devcb = &sc28c94_device::set_c_tx_cb(*device, DEVCB_##_cb);
+
+#define MCFG_SC28C94_D_TX_CALLBACK(_cb) \
+ devcb = &sc28c94_device::set_d_tx_cb(*device, DEVCB_##_cb);
#define MC68681_RX_FIFO_SIZE 3
// forward declaration
-class mc68681_device;
+class mc68681_base_device;
// mc68681_channel class
class mc68681_channel : public device_t, public device_serial_interface
@@ -86,7 +96,7 @@ private:
uint8_t tx_data;
uint8_t tx_ready;
- mc68681_device *m_uart;
+ mc68681_base_device *m_uart;
void write_MR(uint8_t data);
void write_CR(uint8_t data);
@@ -94,34 +104,36 @@ private:
void recalc_framing();
};
-class mc68681_device : public device_t
+class mc68681_base_device : public device_t
{
friend class mc68681_channel;
public:
- mc68681_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ mc68681_base_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, uint32_t clock, const char *shortname, const char *source);
required_device<mc68681_channel> m_chanA;
required_device<mc68681_channel> m_chanB;
+ optional_device<mc68681_channel> m_chanC;
+ optional_device<mc68681_channel> m_chanD;
// inline configuration helpers
static void static_set_clocks(device_t &device, int clk3, int clk4, int clk5, int clk6);
// API
- DECLARE_READ8_MEMBER(read);
- DECLARE_WRITE8_MEMBER(write);
+ virtual DECLARE_READ8_MEMBER(read);
+ virtual DECLARE_WRITE8_MEMBER(write);
uint8_t get_irq_vector() { m_read_vector = true; return IVR; }
DECLARE_WRITE_LINE_MEMBER( rx_a_w ) { m_chanA->device_serial_interface::rx_w((uint8_t)state); }
DECLARE_WRITE_LINE_MEMBER( rx_b_w ) { m_chanB->device_serial_interface::rx_w((uint8_t)state); }
- template<class _Object> static devcb_base &set_irq_cb(device_t &device, _Object object) { return downcast<mc68681_device &>(device).write_irq.set_callback(object); }
- template<class _Object> static devcb_base &set_a_tx_cb(device_t &device, _Object object) { return downcast<mc68681_device &>(device).write_a_tx.set_callback(object); }
- template<class _Object> static devcb_base &set_b_tx_cb(device_t &device, _Object object) { return downcast<mc68681_device &>(device).write_b_tx.set_callback(object); }
- template<class _Object> static devcb_base &set_inport_cb(device_t &device, _Object object) { return downcast<mc68681_device &>(device).read_inport.set_callback(object); }
- template<class _Object> static devcb_base &set_outport_cb(device_t &device, _Object object) { return downcast<mc68681_device &>(device).write_outport.set_callback(object); }
+ template<class _Object> static devcb_base &set_irq_cb(device_t &device, _Object object) { return downcast<mc68681_base_device &>(device).write_irq.set_callback(object); }
+ template<class _Object> static devcb_base &set_a_tx_cb(device_t &device, _Object object) { return downcast<mc68681_base_device &>(device).write_a_tx.set_callback(object); }
+ template<class _Object> static devcb_base &set_b_tx_cb(device_t &device, _Object object) { return downcast<mc68681_base_device &>(device).write_b_tx.set_callback(object); }
+ template<class _Object> static devcb_base &set_inport_cb(device_t &device, _Object object) { return downcast<mc68681_base_device &>(device).read_inport.set_callback(object); }
+ template<class _Object> static devcb_base &set_outport_cb(device_t &device, _Object object) { return downcast<mc68681_base_device &>(device).write_outport.set_callback(object); }
- devcb_write_line write_irq, write_a_tx, write_b_tx;
+ devcb_write_line write_irq, write_a_tx, write_b_tx, write_c_tx, write_d_tx;
devcb_read8 read_inport;
devcb_write8 write_outport;
int32_t ip3clk, ip4clk, ip5clk, ip6clk;
@@ -166,15 +178,59 @@ private:
uint16_t duart68681_get_ct_count();
void duart68681_start_ct(int count);
int calc_baud(int ch, uint8_t data);
- int get_ch(mc68681_channel *ch) { return (ch == m_chanA) ? 0 : 1; }
void clear_ISR_bits(int mask);
void set_ISR_bits(int mask);
void update_interrupts();
+ int get_ch(mc68681_channel *ch)
+ {
+ if (ch == m_chanA)
+ {
+ return 0;
+ }
+ else if (ch == m_chanB)
+ {
+ return 1;
+ }
+ else if (ch == m_chanC)
+ {
+ return 2;
+ }
+
+ return 3;
+ }
+
mc68681_channel *get_channel(int chan);
};
+class mc68681_device : public mc68681_base_device
+{
+public:
+ mc68681_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+};
+
+class sc28c94_device : public mc68681_base_device
+{
+public:
+ sc28c94_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+ template<class _Object> static devcb_base &set_c_tx_cb(device_t &device, _Object object) { return downcast<mc68681_base_device &>(device).write_c_tx.set_callback(object); }
+ template<class _Object> static devcb_base &set_d_tx_cb(device_t &device, _Object object) { return downcast<mc68681_base_device &>(device).write_d_tx.set_callback(object); }
+
+ DECLARE_WRITE_LINE_MEMBER( rx_c_w ) { m_chanC->device_serial_interface::rx_w((uint8_t)state); }
+ DECLARE_WRITE_LINE_MEMBER( rx_d_w ) { m_chanD->device_serial_interface::rx_w((uint8_t)state); }
+
+ virtual DECLARE_READ8_MEMBER(read) override;
+ virtual DECLARE_WRITE8_MEMBER(write) override;
+
+protected:
+ virtual machine_config_constructor device_mconfig_additions() const override;
+
+private:
+};
+
extern const device_type MC68681;
+extern const device_type SC28C94;
extern const device_type MC68681_CHANNEL;
#endif //_N68681_H
diff --git a/src/devices/machine/netlist.cpp b/src/devices/machine/netlist.cpp
index 7ba29e26fb7..90cf78d6315 100644
--- a/src/devices/machine/netlist.cpp
+++ b/src/devices/machine/netlist.cpp
@@ -72,7 +72,7 @@ void netlist_mame_analog_input_t::device_start()
m_param = dynamic_cast<netlist::param_double_t *>(p);
if (m_param == nullptr)
{
- fatalerror("device %s wrong parameter type for %s\n", basetag(), m_param_name.cstr());
+ fatalerror("device %s wrong parameter type for %s\n", basetag(), m_param_name.c_str());
}
if (m_mult != 1.0 || m_offset != 0.0)
{
@@ -183,7 +183,7 @@ void netlist_mame_int_input_t::device_start()
m_param = dynamic_cast<netlist::param_int_t *>(p);
if (m_param == nullptr)
{
- fatalerror("device %s wrong parameter type for %s\n", basetag(), m_param_name.cstr());
+ fatalerror("device %s wrong parameter type for %s\n", basetag(), m_param_name.c_str());
}
}
@@ -215,7 +215,7 @@ void netlist_mame_logic_input_t::device_start()
m_param = dynamic_cast<netlist::param_logic_t *>(p);
if (m_param == nullptr)
{
- fatalerror("device %s wrong parameter type for %s\n", basetag(), m_param_name.cstr());
+ fatalerror("device %s wrong parameter type for %s\n", basetag(), m_param_name.c_str());
}
}
@@ -282,7 +282,7 @@ void netlist_ram_pointer_t::device_start()
m_param = dynamic_cast<netlist::param_ptr_t *>(p);
if (m_param == nullptr)
{
- fatalerror("device %s wrong parameter type for %s\n", basetag(), m_param_name.cstr());
+ fatalerror("device %s wrong parameter type for %s\n", basetag(), m_param_name.c_str());
}
m_data = (*m_param)();
@@ -375,22 +375,22 @@ void netlist_mame_t::vlog(const plib::plog_level &l, const pstring &ls) const
switch (l)
{
case plib::plog_level::DEBUG:
- m_parent.logerror("netlist DEBUG: %s\n", errstr.cstr());
+ m_parent.logerror("netlist DEBUG: %s\n", errstr.c_str());
break;
case plib::plog_level::INFO:
- m_parent.logerror("netlist INFO: %s\n", errstr.cstr());
+ m_parent.logerror("netlist INFO: %s\n", errstr.c_str());
break;
case plib::plog_level::VERBOSE:
- m_parent.logerror("netlist VERBOSE: %s\n", errstr.cstr());
+ m_parent.logerror("netlist VERBOSE: %s\n", errstr.c_str());
break;
case plib::plog_level::WARNING:
- m_parent.logerror("netlist WARNING: %s\n", errstr.cstr());
+ m_parent.logerror("netlist WARNING: %s\n", errstr.c_str());
break;
case plib::plog_level::ERROR:
- m_parent.logerror("netlist ERROR: %s\n", errstr.cstr());
+ m_parent.logerror("netlist ERROR: %s\n", errstr.c_str());
break;
case plib::plog_level::FATAL:
- emu_fatalerror error("netlist ERROR: %s\n", errstr.cstr());
+ emu_fatalerror error("netlist ERROR: %s\n", errstr.c_str());
throw error;
}
}
@@ -554,38 +554,38 @@ ATTR_COLD void netlist_mame_device_t::save_state()
{
for (auto const & s : netlist().state().save_list())
{
- netlist().log().debug("saving state for {1}\n", s->m_name.cstr());
+ netlist().log().debug("saving state for {1}\n", s->m_name.c_str());
if (s->m_dt.is_float)
{
if (s->m_dt.size == sizeof(double))
{
double *td = s->resolved<double>();
- if (td != nullptr) save_pointer(td, s->m_name.cstr(), s->m_count);
+ if (td != nullptr) save_pointer(td, s->m_name.c_str(), s->m_count);
}
else if (s->m_dt.size == sizeof(float))
{
float *td = s->resolved<float>();
- if (td != nullptr) save_pointer(td, s->m_name.cstr(), s->m_count);
+ if (td != nullptr) save_pointer(td, s->m_name.c_str(), s->m_count);
}
else
- netlist().log().fatal("Unknown floating type for {1}\n", s->m_name.cstr());
+ netlist().log().fatal("Unknown floating type for {1}\n", s->m_name.c_str());
}
else if (s->m_dt.is_integral)
{
if (s->m_dt.size == sizeof(int64_t))
- save_pointer((int64_t *) s->m_ptr, s->m_name.cstr(), s->m_count);
+ save_pointer((int64_t *) s->m_ptr, s->m_name.c_str(), s->m_count);
else if (s->m_dt.size == sizeof(int32_t))
- save_pointer((int32_t *) s->m_ptr, s->m_name.cstr(), s->m_count);
+ save_pointer((int32_t *) s->m_ptr, s->m_name.c_str(), s->m_count);
else if (s->m_dt.size == sizeof(int16_t))
- save_pointer((int16_t *) s->m_ptr, s->m_name.cstr(), s->m_count);
+ save_pointer((int16_t *) s->m_ptr, s->m_name.c_str(), s->m_count);
else if (s->m_dt.size == sizeof(int8_t))
- save_pointer((int8_t *) s->m_ptr, s->m_name.cstr(), s->m_count);
+ save_pointer((int8_t *) s->m_ptr, s->m_name.c_str(), s->m_count);
#if (PHAS_INT128)
else if (s->m_dt.size == sizeof(INT128))
- save_pointer((int64_t *) s->m_ptr, s->m_name.cstr(), s->m_count * 2);
+ save_pointer((int64_t *) s->m_ptr, s->m_name.c_str(), s->m_count * 2);
#endif
else
- netlist().log().fatal("Unknown integral type size {1} for {2}\n", s->m_dt.size, s->m_name.cstr());
+ netlist().log().fatal("Unknown integral type size {1} for {2}\n", s->m_dt.size, s->m_name.c_str());
}
else if (s->m_dt.is_custom)
{
@@ -627,11 +627,11 @@ void netlist_mame_cpu_device_t::device_start()
netlist::detail::net_t *n = netlist().m_nets[i].get();
if (n->is_logic())
{
- state_add(i*2, n->name().cstr(), downcast<netlist::logic_net_t *>(n)->Q_state_ptr());
+ state_add(i*2, n->name().c_str(), downcast<netlist::logic_net_t *>(n)->Q_state_ptr());
}
else
{
- state_add(i*2+1, n->name().cstr(), downcast<netlist::analog_net_t *>(n)->Q_Analog_state_ptr()).formatstr("%20s");
+ state_add(i*2+1, n->name().c_str(), downcast<netlist::analog_net_t *>(n)->Q_Analog_state_ptr()).formatstr("%20s");
}
}
@@ -664,7 +664,7 @@ ATTR_COLD offs_t netlist_mame_cpu_device_t::disasm_disassemble(std::ostream &str
{
int dpc = netlist().queue().size() - relpc - 1;
// FIXME: 50 below fixes crash in mame-debugger. It's based on try on error.
- util::stream_format(stream, "%c %s @%10.7f", (relpc == 0) ? '*' : ' ', netlist().queue()[dpc].m_object->name().cstr(),
+ util::stream_format(stream, "%c %s @%10.7f", (relpc == 0) ? '*' : ' ', netlist().queue()[dpc].m_object->name().c_str(),
netlist().queue()[dpc].m_exec_time.as_double());
}
@@ -795,7 +795,7 @@ void netlist_mame_sound_device_t::sound_stream_update(sound_stream &stream, stre
std::unique_ptr<plib::pistream> netlist_source_memregion_t::stream(const pstring &name)
{
- memory_region *mem = downcast<netlist_mame_t &>(setup().netlist()).machine().root_device().memregion(m_name.cstr());
+ memory_region *mem = downcast<netlist_mame_t &>(setup().netlist()).machine().root_device().memregion(m_name.c_str());
return plib::make_unique_base<plib::pistream, plib::pimemstream>(mem->base(), mem->bytes());
}
diff --git a/src/devices/machine/netlist.h b/src/devices/machine/netlist.h
index 9428da5d348..8466c39e070 100644
--- a/src/devices/machine/netlist.h
+++ b/src/devices/machine/netlist.h
@@ -797,7 +797,7 @@ public:
{
int pos = (upto - m_last_buffer) / m_sample;
if (pos >= BUFSIZE)
- netlist().log().fatal("sound {1}: exceeded BUFSIZE\n", name().cstr());
+ netlist().log().fatal("sound {1}: exceeded BUFSIZE\n", name().c_str());
while (m_last_pos < pos )
{
m_buffer[m_last_pos++] = (stream_sample_t) m_cur;
diff --git a/src/devices/machine/tms6100.h b/src/devices/machine/tms6100.h
index 0749424b0d7..93a4f06826f 100644
--- a/src/devices/machine/tms6100.h
+++ b/src/devices/machine/tms6100.h
@@ -131,9 +131,9 @@ protected:
uint8_t m_data; // ADD/DATA pins output
int m_m0;
int m_m1;
- int m_cs; // chipselect pin
- int m_clk; // CLK pin
- int m_rck; // RCK pin (mask/gate to CLK?)
+ int m_cs; // chipselect pin
+ int m_clk; // CLK pin
+ int m_rck; // RCK pin (mask/gate to CLK?)
};
diff --git a/src/devices/video/tms9927.cpp b/src/devices/video/tms9927.cpp
index 4c5d038be70..2f77efb875a 100644
--- a/src/devices/video/tms9927.cpp
+++ b/src/devices/video/tms9927.cpp
@@ -21,7 +21,7 @@ static const uint8_t skew_bits_value[4] = { 0, 1, 2, 2 };
#define SCANS_PER_DATA_ROW (((m_reg[2] >> 3) & 0x0f) + 1)
#define CHARS_PER_DATA_ROW (chars_per_row_value[(m_reg[2] >> 0) & 0x07])
#define SKEW_BITS (skew_bits_value[(m_reg[3] >> 6) & 0x03])
-#define DATA_ROWS_PER_FRAME (((m_reg[3] >> 0) & 0x3f) + 1)
+#define DATA_ROWS_PER_FRAME ((m_reg[3] & 0x3f) + 1)
#define SCAN_LINES_PER_FRAME ((m_reg[4] * 2) + 256 + (((m_reg[1] >> 7) & 0x01) * 257))
#define VERTICAL_DATA_START (m_reg[5])
#define LAST_DISP_DATA_ROW (m_reg[6] & 0x3f)
@@ -179,7 +179,6 @@ void tms9927_device::generic_access(address_space &space, offs_t offset)
break;
case 0x0b: /* Up scroll */
-osd_printf_debug("Up scroll\n");
m_screen->update_now();
m_start_datarow = (m_start_datarow + 1) % DATA_ROWS_PER_FRAME;
break;
@@ -215,7 +214,9 @@ WRITE8_MEMBER( tms9927_device::write )
case 0x0d: /* LOAD CURSOR ROW ADDRESS */
osd_printf_debug("Cursor address changed\n");
m_reg[offset - 0x0c + 7] = data;
- recompute_parameters(false);
+ /* Recomputing parameters here will break the scrollup on the Attachè
+ and probably other machines due to m_start_datarow being reset ! */
+ //recompute_parameters(false);
break;
default:
diff --git a/src/devices/video/zeus2.cpp b/src/devices/video/zeus2.cpp
index c606405c643..2ce5214e463 100644
--- a/src/devices/video/zeus2.cpp
+++ b/src/devices/video/zeus2.cpp
@@ -279,8 +279,9 @@ uint32_t zeus2_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap
READ32_MEMBER( zeus2_device::zeus2_r )
{
int logit = (offset != 0x00 && offset != 0x01 &&
- offset != 0x48 && offset != 0x49 &&
- offset != 0x54 && offset != 0x58 && offset != 0x59 && offset != 0x5a);
+ offset != 0x48 && offset != 0x49
+ && offset != 0x54 && offset != 0x58 && offset != 0x59 && offset != 0x5a
+ );
logit &= LOG_REGS;
uint32_t result = m_zeusbase[offset];
#if TRACK_REG_USAGE
@@ -331,8 +332,8 @@ WRITE32_MEMBER( zeus2_device::zeus2_w )
{
int logit = (offset != 0x08 &&
(offset != 0x20 || data != 0) &&
- offset != 0x40 && offset != 0x41 && offset != 0x48 && offset != 0x49 && offset != 0x4e &&
- offset != 0x50 && offset != 0x51 && offset != 0x57 && offset != 0x58 && offset != 0x59 && offset != 0x5a && offset != 0x5e
+ offset != 0x40 && offset != 0x41 && offset != 0x48 && offset != 0x49 && offset != 0x4e
+ && offset != 0x50 && offset != 0x51 && offset != 0x57 && offset != 0x58 && offset != 0x59 && offset != 0x5a && offset != 0x5e
);
logit &= LOG_REGS;
if (logit)
@@ -461,7 +462,7 @@ void zeus2_device::zeus2_register_update(offs_t offset, uint32_t oldval, int log
break;
case 0x2a:
- // 0x000000c0 = bilenear off
+ // 0x000000c0 = bilinear off
if (logit) logerror("\tRend Force Off");
break;
@@ -665,11 +666,29 @@ void zeus2_device::zeus2_register_update(offs_t offset, uint32_t oldval, int log
logerror("\t[40]=%08X [4E]=%08X\n", m_zeusbase[0x40], m_zeusbase[0x4e]);
break;
- case 0x50:
- {
+ case 0x50: case 0x51: case 0x58: case 0x59: case 0x5a: case 0x5b: case 0x5e:
+ // m_zeusbase[0x5e]:
+ // bits 3:0 select which offset triggers an access
+ // bit 4: clear error
+ // bit 5: 24 bit (1) / 32 bit mode (0)
+ // bit 6: enable autoincrement wave address
+ // bit 7 autoincrement desination address?
+ // bit 8 autoincrement row/col address by 1 (0) or 2 (1)
+ if ((offset & 0xf) == (m_zeusbase[0x5e] & 0xf)) {
+
int code = (m_zeusbase[0x50] >> 16) & 0xf;
- if (code == 0x1) {
+ // If the address is auto-increment then don't load new value
+ // In reality address is latched by a write to 0x50
+ if (offset == 0x51 && (m_zeusbase[0x5e] & 0x40)) {
+ m_zeusbase[0x51] = oldval;
+ }
+
+ switch (code) {
+ case 0:
+ // NOP
+ break;
+ case 1:
// SGRAM Special Mode Register Write
if (m_zeusbase[0x51] == 0x00200000) {
// SGRAM Mask Register
@@ -684,106 +703,39 @@ void zeus2_device::zeus2_register_update(offs_t offset, uint32_t oldval, int log
if (m_zeusbase[0x58] != m_zeusbase[0x59])
logerror("zeus2_register_update: Warning! Different fill colors are set.\n");
}
- }
- else if (code == 0x8) {
- // Fast fill
- // Unknown what the exact bit fields are, this is a just a guess
- // Atlantis: 0x00983FFF => clear entire frame buffer, 0x00981FFF => clear one frame
- // crusnexo: 0x007831FF => clear one frame
- // thegrid: 0x008831FF => clear one frame
- // thegrid: 0x0079FFFF => clear entire frame buffer at 51=0 then 51=00800000, only seen at initial tests in thegrid
- uint32_t addr = frame_addr_from_phys_addr(m_zeusbase[0x51]);
- uint32_t numBytes = (m_zeusbase[0x50] & 0xffff) + 1;
- numBytes *= 0x40;
- if (m_zeusbase[0x50] & 0x10000) {
- addr = 0x0;
- numBytes = WAVERAM1_WIDTH * WAVERAM1_HEIGHT * 8;
- //printf("Clearing buffer: numBytes: %08X addr: %08X reg50: %08X\n", numBytes, addr, m_zeusbase[0x50]);
- }
- if (logit)
- logerror(" -- Clearing buffer: numBytes: %08X addr: %08X reg51: %08X", numBytes, addr, m_zeusbase[0x51]);
- memset(&m_frameColor[addr], m_fill_color, numBytes);
- memset(&m_frameDepth[addr], m_fill_depth, numBytes);
- }
- else if ((m_zeusbase[0x5e] >> 16) != 0xf208 && !(m_zeusbase[0x5e] & 0xffff)) {
- /* If 0x5e==0xf20a0000 (atlantis) or 0xf20d0000 (the grid) then process the read/write now */
- /*
- m_zeusbase[0x5e]:
- bit 0-1: which register triggers write through
- bit 3: enable write through via these registers
- bit 4: seems to be set during reads, when 0x51 is used for latching
- bit 5: unknown, currently used to specify ordering, but this is suspect
- bit 6: enable autoincrement on write through
- */
- if (code == 0x9)
+ break;
+ case 0x2:
+ frame_read();
+ break;
+ case 0x8:
{
- frame_write();
- }
- else if (code == 0x2) {
- /* Do the read */
- frame_read();
+ // Fast fill
+ // Atlantis: 0x00983FFF => clear entire frame buffer, 0x00981FFF => clear one frame
+ // crusnexo: 0x007831FF => clear one frame
+ // thegrid: 0x008831FF => clear one frame
+ // thegrid: 0x0079FFFF => clear entire frame buffer at 51=0 then 51=00800000, only seen at initial tests in thegrid
+ uint32_t addr = frame_addr_from_phys_addr(m_zeusbase[0x51]);
+ uint32_t numBytes = (m_zeusbase[0x50] & 0xffff) + 1;
+ numBytes *= 0x40;
+ if (m_zeusbase[0x50] & 0x10000) {
+ addr = 0x0;
+ numBytes = WAVERAM1_WIDTH * WAVERAM1_HEIGHT * 8;
+ //printf("Clearing buffer: numBytes: %08X addr: %08X reg50: %08X\n", numBytes, addr, m_zeusbase[0x50]);
+ }
+ if (logit)
+ logerror(" -- Clearing buffer: numBytes: %08X addr: %08X reg51: %08X", numBytes, addr, m_zeusbase[0x51]);
+ memset(&m_frameColor[addr], m_fill_color, numBytes);
+ memset(&m_frameDepth[addr], m_fill_depth, numBytes);
}
- /* make sure we log anything else */
- //else if (logit || m_zeusbase[0x50] != 0x0)
- // logerror("\tw[50]=%08X [5E]=%08X\n", m_zeusbase[0x50], m_zeusbase[0x5e]);
- }
- }
- break;
- case 0x51:
- // Set rendering location
- /* in this mode, crusnexo expects the reads to immediately latch */
- //if ((m_zeusbase[0x50] == 0x00a20000) || (m_zeusbase[0x50] == 0x00720000))
- if (m_zeusbase[0x50] == 0x00a20000)
- oldval = m_zeusbase[0x51];
-
- /* this is the address, except in read mode, where it latches values */
- if ((m_zeusbase[0x5e] & 0x10) || (m_zeusbase[0x50] == 0x00a20000))
- {
- m_zeusbase[0x51] = oldval;
- frame_read();
- }
- break;
-
- case 0x57:
- /* thegrid uses this to write either left or right halves of pixels */
- //if (m_zeusbase[0x50] == 0x00e90000)
- //{
- // uint32_t addr = frame_addr_from_reg51();
- // if (m_zeusbase[0x57] & 1)
- // m_frameColor[addr] = m_zeusbase[0x58];
- // if (m_zeusbase[0x57] & 4)
- // m_frameColor[addr+1] = m_zeusbase[0x59];
- //}
-
- ///* make sure we log anything else */
- //else if (logit)
- // logerror("\t[50]=%08X [5E]=%08X\n", m_zeusbase[0x50], m_zeusbase[0x5e]);
- break;
-
- case 0x58:
- case 0x59:
- case 0x5a:
- /* if we're in write mode, process it */
- if (m_zeusbase[0x50] == 0x00890000)
- {
- /*
- m_zeusbase[0x5e]:
- bit 0-1: which register triggers write through
- bit 3: enable write through via these registers
- bit 4: seems to be set during reads, when 0x51 is used for latching
- bit 5: unknown, currently used to specify ordering, but this is suspect
- bit 6: enable autoincrement on write through
- */
- if ((m_zeusbase[0x5e] & 0x08) && (offset & 3) == (m_zeusbase[0x5e] & 3))
- {
+ break;
+ case 0x9:
frame_write();
+ break;
+ default:
+ logerror("unknown code = %x offset = %x", code, offset);
+ break;
}
}
-
- /* make sure we log anything else */
- else if ((m_zeusbase[0x5e] >> 16) == 0xf208)
- if (logit)
- logerror("\t[50]=%08X [5E]=%08X", m_zeusbase[0x50], m_zeusbase[0x5e]);
break;
// 0x60, 0x61, 0x62 Translation matrix, set using fifo command
@@ -1025,7 +977,7 @@ if (subregdata_count[which] < 256)
break;
case 0x0b:
- if (logit) logerror("\t(R%02X) = %4i Pixel ALU IntB", which, value);
+ if (logit) logerror("\t(R%02X) = %4i Pixel ALU IntB (Obj Light Color)", which, value);
break;
case 0x0c:
@@ -1365,7 +1317,7 @@ void zeus2_device::zeus2_draw_model(uint32_t baseaddr, uint16_t count, int logit
logerror("texdata\n");
}
else if (logit)
- logerror("unknown offset\n");
+ logerror("unknown offset %08X %08X\n", databuffer[0], databuffer[1]);
break;
case 0x31: /* thegrid */
@@ -1469,9 +1421,14 @@ void zeus2_renderer::zeus2_draw_quad(const uint32_t *databuffer, uint32_t texdat
// int16_t normal[3];
// int32_t rotnormal[3];
- if (logit)
- m_state->logerror("quad %d\n", m_state->zeus_quad_size);
-
+ if (logit) {
+ m_state->logerror("quad %d", m_state->zeus_quad_size);
+#if PRINT_TEX_INFO
+ m_state->logerror(" %s\n", m_state->tex_info());
+#else
+ m_state->logerror("\n");
+#endif
+ }
//if (machine().input().code_pressed(KEYCODE_Q) && (m_state->m_renderRegs[0x5] != 0x1fdf00)) return;
//if (machine().input().code_pressed(KEYCODE_E) && (m_state->m_renderRegs[0x5] != 0x07f540)) return;
//if (machine().input().code_pressed(KEYCODE_R) && (m_state->m_renderRegs[0x5] != 0x081580)) return;
@@ -1640,48 +1597,51 @@ void zeus2_renderer::zeus2_draw_quad(const uint32_t *databuffer, uint32_t texdat
y *= fScale;
z *= fScale;
}
+#if PRINT_TEX_INFO
+ if (logit && i == 0) {
+ m_state->check_tex(texdata, z, m_state->zeus_matrix[2][2], m_state->zeus_point[2]);
+ }
+#endif
vert[i].x = x * m_state->zeus_matrix[0][0] + y * m_state->zeus_matrix[0][1] + z * m_state->zeus_matrix[0][2];
vert[i].y = x * m_state->zeus_matrix[1][0] + y * m_state->zeus_matrix[1][1] + z * m_state->zeus_matrix[1][2];
vert[i].p[0] = x * m_state->zeus_matrix[2][0] + y * m_state->zeus_matrix[2][1] + z * m_state->zeus_matrix[2][2];
- if (1 || !(m_state->m_renderRegs[0x14] & 0x000001)) {
+ if (1) {
vert[i].x += m_state->zeus_point[0];
vert[i].y += m_state->zeus_point[1];
vert[i].p[0] += m_state->zeus_point[2];
}
- //if (0)
- // //vert[i].p[0] += m_state->zbase;
- // vert[i].p[0] += reinterpret_cast<float&>(m_state->m_zeusbase[0x63]);
- //else {
+
+ if (0) {
int shift;
shift = 1024 >> m_state->m_zeusbase[0x6c];
vert[i].p[0] += shift;
- // //float zScale = reinterpret_cast<float&>(m_state->m_zeusbase[0x63]);
- // //vert[i].p[0] += zScale;
- //}
+ }
vert[i].p[2] += (texdata >> 16) << 2;
vert[i].p[1] *= 256.0f / 4.0f;
vert[i].p[2] *= 256.0f / 4.0f;
// back face cull using polygon normal and first vertex
- if (1 && i == 0)
+ if (0 && i == 0)
{
- int8_t normal[3];
float rotnormal[3];
+ int8_t normal[3];
normal[0] = databuffer[0] >> 0;
normal[1] = databuffer[0] >> 8;
normal[2] = databuffer[0] >> 16;
+ //m_state->logerror("norm: %i %i %i\n", normal[0], normal[1], normal[2]);
+ if (normal[2] != -128) {
+ rotnormal[0] = normal[0] * m_state->zeus_matrix[0][0] + normal[1] * m_state->zeus_matrix[0][1] + normal[2] * m_state->zeus_matrix[0][2];
+ rotnormal[1] = normal[0] * m_state->zeus_matrix[1][0] + normal[1] * m_state->zeus_matrix[1][1] + normal[2] * m_state->zeus_matrix[1][2];
+ rotnormal[2] = normal[0] * m_state->zeus_matrix[2][0] + normal[1] * m_state->zeus_matrix[2][1] + normal[2] * m_state->zeus_matrix[2][2];
- rotnormal[0] = normal[0] * m_state->zeus_matrix[0][0] + normal[1] * m_state->zeus_matrix[0][1] + normal[2] * m_state->zeus_matrix[0][2];
- rotnormal[1] = normal[0] * m_state->zeus_matrix[1][0] + normal[1] * m_state->zeus_matrix[1][1] + normal[2] * m_state->zeus_matrix[1][2];
- rotnormal[2] = normal[0] * m_state->zeus_matrix[2][0] + normal[1] * m_state->zeus_matrix[2][1] + normal[2] * m_state->zeus_matrix[2][2];
-
- float dot = rotnormal[0] * vert[0].x + rotnormal[1] * vert[0].y + rotnormal[2] * vert[0].p[0];
+ float dot = rotnormal[0] * vert[0].x + rotnormal[1] * vert[0].y + rotnormal[2] * vert[0].p[0];
- if (dot >= 0)
- return;
+ if (dot >= 0)
+ return;
+ }
}
@@ -1697,13 +1657,21 @@ void zeus2_renderer::zeus2_draw_quad(const uint32_t *databuffer, uint32_t texdat
unknown[0], unknown[1], unknown[2], unknown[3], unknown[4], unknown[5], unknown[6], unknown[7],
unknownFloat[0], unknownFloat[1], unknownFloat[2], unknownFloat[3]);
}
- bool enable_perspective = true; // !(m_state->m_renderRegs[0x14] & 0x2);
- float clipVal = enable_perspective ? 1.0f / 512.0f / 4.0f : 0.0f;
- //float clipVal = m_state->m_zbufmin / 4096.0f;
- numverts = this->zclip_if_less(4, &vert[0], &clipvert[0], 4, clipVal);
- if (numverts < 3)
- return;
-
+ //bool enable_perspective = true; // !(m_state->m_renderRegs[0x14] & 0x2);
+ //float clipVal = enable_perspective ? 1.0f / 512.0f / 4.0f : 0.0f;
+ float clipVal = m_state->m_zbufmin / 4096.0f;
+ if (1) {
+ numverts = this->zclip_if_less(4, &vert[0], &clipvert[0], 4, clipVal);
+ if (numverts < 3)
+ return;
+ }
+ else {
+ numverts = 4;
+ clipvert[0] = vert[0];
+ clipvert[1] = vert[1];
+ clipvert[2] = vert[2];
+ clipvert[3] = vert[3];
+ }
float xOrigin = reinterpret_cast<float&>(m_state->m_zeusbase[0x6a]);
float yOrigin = reinterpret_cast<float&>(m_state->m_zeusbase[0x6b]);
@@ -1712,31 +1680,38 @@ void zeus2_renderer::zeus2_draw_quad(const uint32_t *databuffer, uint32_t texdat
maxx = maxy = -1000.0f;
for (i = 0; i < numverts; i++)
{
+ if (0 && (m_state->m_renderRegs[0x14] & 0x1)) {
+ clipvert[i].p[0] += reinterpret_cast<float&>(m_state->m_zeusbase[0x63]);
+ }
// mwskinsa has R14=0x40a1 for tips box which has z=0
//if (!(m_state->m_renderRegs[0x14] & 0x1)) {
- if (enable_perspective) {
+ //if (enable_perspective) {
// 412.0f here works for crusnexo
// 1024.0f works for mwskinsa
- float ooz = oozBase / clipvert[i].p[0];
+ float ooz = oozBase / (clipvert[i].p[0] + (1024 >> m_state->m_zeusbase[0x6c]));
+ //ooz = oozBase / (oozBase - clipvert[i].p[0]);
//float ooz = 1024.0f / clipvert[i].p[0];
//float ooz = float(1 << m_state->m_zeusbase[0x6c]) / clipvert[i].p[0];
clipvert[i].x *= ooz;
clipvert[i].y *= ooz;
- }
+ //}
if (1) {
//clipvert[i].x += 256.5f / 1.0f;
//clipvert[i].y += 200.5f / 1.0f;
clipvert[i].x += xOrigin;
clipvert[i].y += yOrigin;
+ //clipvert[i].p[0] += reinterpret_cast<float&>(m_state->m_zeusbase[0x63]);
+ //clipvert[i].p[0] *= -1.0f;
}
- clipvert[i].p[0] *= 65536.0f * 16.0f;
+ //clipvert[i].p[0] *= 65536.0f * 16.0f;
+ clipvert[i].p[0] *= 4096.0f;
maxx = std::max(maxx, clipvert[i].x);
maxy = std::max(maxy, clipvert[i].y);
if (logextra & logit)
- m_state->logerror("\t\t\tTranslated=(%f,%f)\n", (double)clipvert[i].x, (double)clipvert[i].y);
+ m_state->logerror("\t\t\tTranslated=(%f,%f, %f) scale = %f\n", (double)clipvert[i].x, (double)clipvert[i].y, (double)clipvert[i].p[0], ooz);
}
for (i = 0; i < numverts; i++)
{
@@ -1807,7 +1782,7 @@ void zeus2_renderer::zeus2_draw_quad(const uint32_t *databuffer, uint32_t texdat
extra.solidcolor = 0;//m_zeusbase[0x00] & 0x7fff;
extra.zbufmin = m_state->m_zbufmin;
extra.alpha = 0;//m_zeusbase[0x4e];
- extra.transcolor = 0x100; // (texmode & 0x100) ? 0 : 0x100;
+ extra.transcolor = 0; // (texmode & 0x100) ? 0 : 0x100;
extra.texbase = WAVERAM_BLOCK0_EXT(m_state->zeus_texbase);
extra.palbase = m_state->waveram0_ptr_from_expanded_addr(m_state->m_zeusbase[0x41]);
//extra.depth_test_enable = !(m_state->m_renderRegs[0x40] & 0x020000);
@@ -1817,7 +1792,7 @@ void zeus2_renderer::zeus2_draw_quad(const uint32_t *databuffer, uint32_t texdat
//extra.depth_test_enable = !(m_state->m_renderRegs[0x40] & 0x000002);
//extra.depth_test_enable = true; // (texmode & 0x0010);
extra.depth_write_enable = true;
- extra.get_texel = (m_state->m_palSize==256) ? m_state->get_texel_8bit : m_state->get_texel_4bit;
+ extra.get_texel = ((texmode & 0x3) == 0) ? m_state->get_texel_4bit : m_state->get_texel_8bit;
// Note: Before being converted to the "poly.h" interface, this used to call the polylgcy function
// poly_render_quad_fan. The behavior seems to be the same as it once was after a few short
// tests, but the (numverts == 5) statement below may actually be a quad fan instead of a 5-sided
@@ -1872,12 +1847,14 @@ void zeus2_renderer::render_poly_8bit(int32_t scanline, const extent_t& extent,
int u1 = (u0 + 1);
int v1 = (v0 + 1);
uint8_t texel0 = object.get_texel(texbase, v0, u0, texwidth);
- if (texel0 == transcolor)
- continue;
+ //if (texel0 == transcolor)
+ // continue;
uint8_t texel1 = object.get_texel(texbase, v0, u1, texwidth);
uint8_t texel2 = object.get_texel(texbase, v1, u0, texwidth);
uint8_t texel3 = object.get_texel(texbase, v1, u1, texwidth);
//if (texel0 != transcolor)
+ if ((texel0 != transcolor) && (texel1 != transcolor) && (texel2 != transcolor) && (texel3 != transcolor))
+ //if (1)
{
uint32_t color0 = m_state->m_pal_table[texel0];
uint32_t color1 = m_state->m_pal_table[texel1];
@@ -1929,3 +1906,123 @@ void zeus2_device::log_render_info(uint32_t texdata)
logerror(" %02X=%08X", i, m_zeusbase[i]);
logerror("\n");
}
+
+#if PRINT_TEX_INFO
+#include <iomanip>
+
+void zeus2_device::check_tex(uint32_t &texmode, float &zObj, float &zMat, float &zOff)
+{
+ if (tex_map.count(zeus_texbase) == 0) {
+ std::string infoStr;
+ std::stringstream infoStream;
+ infoStream << "tex=0x" << std::setw(8) << std::setfill('0') << std::hex << zeus_texbase << " ";
+ infoStream << "pal=0x" << std::setw(4) << std::setfill('0') << (m_curPalTableSrc>>16) << ", 0x" << std::setw(4) << (m_curPalTableSrc & 0xffff) << " ";
+ infoStream << "texdata=" << std::setw(8) << std::hex << texmode << " ";
+ infoStream << "(6c)=" << m_zeusbase[0x6c] << " ";
+ infoStream << "(63)=" << std::dec << reinterpret_cast<float&>(m_zeusbase[0x63]) << " ";
+ infoStream << "zObj=" << std::dec << zObj << " ";
+ infoStream << "zMat=" << std::dec << zMat << " ";
+ infoStream << "zOff=" << std::dec << zOff << " ";
+ infoStream << "R40=" << std::setw(6) << std::hex << m_renderRegs[0x40] << " ";
+ infoStream << "R14=" << m_renderRegs[0x14] << " ";
+ infoStream << "R0C=" << std::setw(3) << m_renderRegs[0x0c] << " ";
+ infoStream << "R0D=" << std::setw(3) << m_renderRegs[0x0d] << " ";
+ infoStr += infoStream.str();
+ infoStr += tex_info();
+
+ tex_map.insert(std::pair<uint32_t, std::string>(zeus_texbase, infoStr));
+ osd_printf_info("%s\n", infoStr.c_str());
+ }
+}
+
+std::string zeus2_device::tex_info(void)
+{
+ std::string retVal;
+ switch (zeus_texbase) {
+ // crusnexo
+ case 0x01fc00: retVal = "credits / insert coin"; break;
+ case 0x1dc000: retVal = "copywrite text"; break;
+ case 0x0e7400: retVal = "tire"; break;
+ case 0x0e8800: retVal = "star behind tire"; break;
+ case 0x0e6800: retVal = "crusn exotica text"; break;
+ case 0x02a400: retVal = "Yellow Letters / Numbers"; break;
+ case 0x1fd000: retVal = "Star burst in license plate screen"; break;
+ case 0x1e9800: retVal = "Red Letter in license plate screen"; break;
+ case 0x0c1c00: retVal = "Car parts"; break;
+ case 0x0006f000: retVal = "license plate background"; break;
+ case 0x0006f400: retVal = "blue on white license plate names"; break;
+ case 0x00047800: retVal = "baby body"; break;
+ case 0x000e7000: retVal = "crusn exotica yellow glow"; break;
+ case 0x0002b000: retVal = "blue crusn stencil behind leader list"; break;
+ case 0x001f4800: retVal = "number keypad"; break;
+ case 0x001e7800: retVal = "register now logo"; break;
+ case 0x001e5000: retVal = "blue start game / enter code / earn miles"; break;
+ case 0x0001c800: retVal = "black letters silver back track select / crusn"; break;
+ case 0x001df400: retVal = "first place / free race logo"; break;
+ case 0x001ddc00: retVal = "secret car logo"; break;
+ case 0x0006e800: retVal = "???"; break;
+ case 0x001f1c00: retVal = "black 0-9 on silver background"; break;
+ case 0x001ec800: retVal = "black on silver holland/amazon/sahara"; break;
+ case 0x001f7800: retVal = "license plate background white"; break;
+ case 0x001f7000: retVal = "red Hot Times writing"; break;
+ case 0x001eb000: retVal = "black numbers 0-10 on silver background"; break;
+ case 0x00100800: retVal = "sunset and stars sky background"; break;
+ case 0x00108c00: retVal = "asphalt surface"; break;
+ case 0x0010c000: retVal = "wood surface?"; break;
+ case 0x0010e400: retVal = "palm tree"; break;
+ case 0x00118c00: retVal = "highway green signs"; break;
+ case 0x000f6400: retVal = "glowing feather?"; break;
+ case 0x00112c00: retVal = "fancy street lamps"; break;
+ case 0x00032400: retVal = "lady driver body"; break;
+ case 0x000b5400: retVal = "blue firebird car"; break;
+ case 0x00089c00: retVal = "brown hummer car"; break;
+ case 0x00110c00: retVal = "oak tree"; break;
+ case 0x00115400: retVal = "welcome to las vegas sign"; break;
+ case 0x000f3c00: retVal = "star or headlight?"; break;
+ case 0x00127400: retVal = "another (lod) star or headlight?"; break;
+
+
+ // mwskinsa
+ case 0x1fdf00: retVal = "Skins Tip Box, s=256"; break;
+ case 0x07f540: retVal = "Left main intro"; break;
+ case 0x081580: retVal = "Right main intro"; break;
+ case 0x14db00: retVal = "silver letter b, s=64"; break;
+ case 0x14d880: retVal = "letter a"; break;
+ case 0x14e000: retVal = "letter d"; break;
+ case 0x0014dd80: retVal = "silver letter c, s=64"; break;
+ case 0x0014fb80: retVal = "silver letter o, s=64"; break;
+ case 0x0014ec80: retVal = "silver letter i, s=64"; break;
+ case 0x0014f900: retVal = "silver letter n, s=64"; break;
+ case 0x00150580: retVal = "silver letter s, s=64"; break;
+ case 0x00150800: retVal = "silver letter t, s=64"; break;
+ case 0x00150300: retVal = "silver letter r, s=64"; break;
+ case 0x0014e780: retVal = "silver letter g, s=64"; break;
+ case 0x00153280: retVal = "silver letter C, s=64"; break;
+ case 0x0014e280: retVal = "silver letter e, s=64"; break;
+ case 0x0014b800: retVal = "silver letter O, s=64"; break;
+ case 0x00152d80: retVal = "silver letter A, s=64"; break;
+ case 0x0014f680: retVal = "silver letter m, s=64"; break;
+ case 0x00142b40: retVal = "black screen?"; break;
+ case 0x00004740: retVal = "picture bridge over water, s=256"; break;
+ case 0x00005c80: retVal = "picture water shore, s=256"; break;
+ case 0x000030c0: retVal = "left leaderboard background graphics, s=256"; break;
+ case 0x00003c00: retVal = "right leaderboard background graphics, s=256"; break;
+ case 0x00040bc0: retVal = "extreme mode, s=256"; break;
+ case 0x00091630: retVal = "photo wild eye guy, s=64"; break;
+ case 0x00159d80: retVal = "white M s=32, t=4"; break;
+ case 0x0015a080: retVal = "white 9 s=32, t=4"; break;
+ case 0x00159f00: retVal = "white P s=32, t=4"; break;
+ case 0x00145a40: retVal = "white crossbar? s=32, t=4"; break;
+ case 0x00145c40: retVal = "white crossbar2? s=32, t=4"; break;
+ case 0x00159300: retVal = "white _ s=32, t=4"; break;
+ case 0x00158d00: retVal = "white 1 s=32, t=4"; break;
+ case 0x00158e80: retVal = "white 4 s=32, t=4"; break;
+ case 0x0001c080: retVal = "maybe checkboard"; break;
+
+ // thegrid
+ //case 0x0001c080: retVal = "maybe checkboard"; break;
+ default: retVal = "Unknown"; break;
+ }
+ return retVal;
+}
+#endif
diff --git a/src/devices/video/zeus2.h b/src/devices/video/zeus2.h
index 960eefbd8c6..4c53d5b2dbe 100644
--- a/src/devices/video/zeus2.h
+++ b/src/devices/video/zeus2.h
@@ -22,6 +22,7 @@
#define DUMP_WAVE_RAM 0
#define TRACK_REG_USAGE 0
+#define PRINT_TEX_INFO 0
#define WAVERAM0_WIDTH 1024
#define WAVERAM0_HEIGHT 2048
@@ -154,6 +155,10 @@ public:
enum { THEGRID, CRUSNEXO, MWSKINS };
int m_system;
+#if PRINT_TEX_INFO
+ void check_tex(uint32_t &texmode, float &zObj, float &zMat, float &zOff);
+ std::string tex_info(void);
+#endif
protected:
// device-level overrides
@@ -173,6 +178,7 @@ private:
void log_fifo_command(const uint32_t *data, int numwords, const char *suffix);
void print_fifo_command(const uint32_t *data, int numwords, const char *suffix);
void log_render_info(uint32_t texdata);
+
/*************************************
* Member variables
*************************************/
@@ -186,6 +192,10 @@ private:
int m_yScale;
+#if PRINT_TEX_INFO
+ std::map<uint32_t, std::string> tex_map;
+#endif
+
#if TRACK_REG_USAGE
struct reg_info
{
diff --git a/src/emu/emuopts.cpp b/src/emu/emuopts.cpp
index 0e5305f33d1..b6463a99f9d 100644
--- a/src/emu/emuopts.cpp
+++ b/src/emu/emuopts.cpp
@@ -203,6 +203,12 @@ const options_entry emu_options::s_option_entries[] =
{ OPTION_PLUGIN, nullptr, OPTION_STRING, "list of plugins to enable" },
{ OPTION_NO_PLUGIN, nullptr, OPTION_STRING, "list of plugins to disable" },
{ OPTION_LANGUAGE ";lang", "English", OPTION_STRING, "display language" },
+
+ { nullptr, nullptr, OPTION_HEADER, "HTTP SERVER OPTIONS" },
+ { OPTION_HTTP, "0", OPTION_BOOLEAN, "HTTP server enable" },
+ { OPTION_HTTP_PORT, "8080", OPTION_INTEGER, "HTTP server port" },
+ { OPTION_HTTP_ROOT, "web", OPTION_STRING, "HTTP server document root" },
+
{ nullptr }
};
diff --git a/src/emu/emuopts.h b/src/emu/emuopts.h
index d8983101a3a..99b5463f540 100644
--- a/src/emu/emuopts.h
+++ b/src/emu/emuopts.h
@@ -190,6 +190,10 @@
#define OPTION_LANGUAGE "language"
+#define OPTION_HTTP "http"
+#define OPTION_HTTP_PORT "http_port"
+#define OPTION_HTTP_ROOT "http_root"
+
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
@@ -381,6 +385,11 @@ public:
const char *language() const { return value(OPTION_LANGUAGE); }
+ // Web server specific optopns
+ bool http() const { return bool_value(OPTION_HTTP); }
+ short http_port() const { return int_value(OPTION_HTTP_PORT); }
+ const char *http_root() const { return value(OPTION_HTTP_ROOT); }
+
// cache frequently used options in members
void update_cached_options();
diff --git a/src/emu/ioport.cpp b/src/emu/ioport.cpp
index 6f751a28dad..4d106912d7b 100644
--- a/src/emu/ioport.cpp
+++ b/src/emu/ioport.cpp
@@ -634,6 +634,8 @@ ioport_field::ioport_field(ioport_port &port, ioport_type type, ioport_value def
if (device().subtag(def->tag) == fulltag && def->mask == m_mask)
m_defvalue = def->defvalue & m_mask;
}
+
+ m_flags |= FIELD_FLAG_TOGGLE;
}
}
@@ -707,6 +709,24 @@ const input_seq &ioport_field::defseq(input_seq_type seqtype) const
//-------------------------------------------------
+// set_defseq - dynamically alter the default
+// input sequence for the given input field
+//-------------------------------------------------
+
+void ioport_field::set_defseq(input_seq_type seqtype, const input_seq &newseq)
+{
+ const bool was_changed = seq(seqtype) != defseq(seqtype);
+
+ // set the new sequence
+ m_seq[seqtype] = newseq;
+
+ // also update live state unless previously customized
+ if (m_live != nullptr && !was_changed)
+ m_live->seq[seqtype] = newseq;
+}
+
+
+//-------------------------------------------------
// type_class - return the type class for this
// field
//-------------------------------------------------
@@ -3112,13 +3132,6 @@ ioport_configurer& ioport_configurer::onoff_alloc(const char *name, ioport_value
// allocate a field normally
field_alloc(IPT_DIPSWITCH, defval, mask, name);
- // special case service mode
- if (name == DEF_STR(Service_Mode))
- {
- field_set_toggle();
- m_curfield->m_seq[SEQ_TYPE_STANDARD].set(KEYCODE_F2);
- }
-
// expand the diplocation
if (diplocation != nullptr)
field_set_diplocation(diplocation);
diff --git a/src/emu/ioport.h b/src/emu/ioport.h
index a9a4d49b0c4..a5169e08c21 100644
--- a/src/emu/ioport.h
+++ b/src/emu/ioport.h
@@ -1058,6 +1058,8 @@ public:
const input_seq &seq(input_seq_type seqtype = SEQ_TYPE_STANDARD) const;
const input_seq &defseq(input_seq_type seqtype = SEQ_TYPE_STANDARD) const;
const input_seq &defseq_unresolved(input_seq_type seqtype = SEQ_TYPE_STANDARD) const { return m_seq[seqtype]; }
+ void set_defseq(const input_seq &newseq) { set_defseq(SEQ_TYPE_STANDARD, newseq); }
+ void set_defseq(input_seq_type seqtype, const input_seq &newseq);
bool has_dynamic_read() const { return !m_read.isnull(); }
bool has_dynamic_write() const { return !m_write.isnull(); }
diff --git a/src/emu/machine.cpp b/src/emu/machine.cpp
index 91999a8307e..d528d9afd40 100644
--- a/src/emu/machine.cpp
+++ b/src/emu/machine.cpp
@@ -84,6 +84,9 @@
#include "network.h"
#include "ui/uimain.h"
#include <time.h>
+#include "server_http.hpp"
+#include "rapidjson/include/rapidjson/writer.h"
+#include "rapidjson/include/rapidjson/stringbuffer.h"
#if defined(EMSCRIPTEN)
#include <emscripten.h>
@@ -332,6 +335,8 @@ int running_machine::run(bool quiet)
if (m_saveload_schedule != SLS_NONE)
handle_saveload();
+ export_http_api();
+
// run the CPUs until a reset or exit
m_hard_reset_pending = false;
while ((!m_hard_reset_pending && !m_exit_pending) || m_saveload_schedule != SLS_NONE)
@@ -1176,7 +1181,32 @@ running_machine::logerror_callback_item::logerror_callback_item(logerror_callbac
{
}
-
+void running_machine::export_http_api()
+{
+ if (!options().http()) return;
+
+ m_manager.http_server()->on_get("/api/machine", [this](auto response, auto request)
+ {
+ rapidjson::StringBuffer s;
+ rapidjson::Writer<rapidjson::StringBuffer> writer(s);
+ writer.StartObject();
+ writer.Key("name");
+ writer.String(m_basename.c_str());
+
+ writer.Key("devices");
+ writer.StartArray();
+
+ device_iterator iter(this->root_device());
+ for (device_t &device : iter)
+ writer.String(device.tag());
+
+ writer.EndArray();
+ writer.EndObject();
+
+ response->type("application/json");
+ response->status(200).send(s.GetString());
+ });
+}
//**************************************************************************
// SYSTEM TIME
diff --git a/src/emu/machine.h b/src/emu/machine.h
index cac9a3f38b6..2b14edfcd64 100644
--- a/src/emu/machine.h
+++ b/src/emu/machine.h
@@ -239,6 +239,7 @@ public:
void add_logerror_callback(logerror_callback callback);
void set_ui_active(bool active) { m_ui_active = active; }
void debug_break();
+ void export_http_api();
// TODO: Do saves and loads still require scheduling?
void immediate_save(const char *filename);
diff --git a/src/emu/main.cpp b/src/emu/main.cpp
new file mode 100644
index 00000000000..e8e07ea52b1
--- /dev/null
+++ b/src/emu/main.cpp
@@ -0,0 +1,208 @@
+// license:BSD-3-Clause
+// copyright-holders:Nicola Salmoria, Aaron Giles
+/***************************************************************************
+
+main.cpp
+
+Controls execution of the core MAME system.
+
+***************************************************************************/
+
+#include "emu.h"
+#include "emuopts.h"
+#include "main.h"
+#include "server_ws.hpp"
+#include "server_http.hpp"
+#include <fstream>
+
+const static struct mapping
+{
+ const char* extension;
+ const char* mime_type;
+} mappings[] =
+{
+ { "aac", "audio/aac" },
+ { "aat", "application/font-sfnt" },
+ { "aif", "audio/x-aif" },
+ { "arj", "application/x-arj-compressed" },
+ { "asf", "video/x-ms-asf" },
+ { "avi", "video/x-msvideo" },
+ { "bmp", "image/bmp" },
+ { "cff", "application/font-sfnt" },
+ { "css", "text/css" },
+ { "csv", "text/csv" },
+ { "doc", "application/msword" },
+ { "eps", "application/postscript" },
+ { "exe", "application/octet-stream" },
+ { "gif", "image/gif" },
+ { "gz", "application/x-gunzip" },
+ { "htm", "text/html" },
+ { "html", "text/html" },
+ { "ico", "image/x-icon" },
+ { "ief", "image/ief" },
+ { "jpeg", "image/jpeg" },
+ { "jpg", "image/jpeg" },
+ { "jpm", "image/jpm" },
+ { "jpx", "image/jpx" },
+ { "js", "application/javascript" },
+ { "json", "application/json" },
+ { "m3u", "audio/x-mpegurl" },
+ { "m4v", "video/x-m4v" },
+ { "mid", "audio/x-midi" },
+ { "mov", "video/quicktime" },
+ { "mp3", "audio/mpeg" },
+ { "mp4", "video/mp4" },
+ { "mpeg", "video/mpeg" },
+ { "mpg", "video/mpeg" },
+ { "oga", "audio/ogg" },
+ { "ogg", "audio/ogg" },
+ { "ogv", "video/ogg" },
+ { "otf", "application/font-sfnt" },
+ { "pct", "image/x-pct" },
+ { "pdf", "application/pdf" },
+ { "pfr", "application/font-tdpfr" },
+ { "pict", "image/pict" },
+ { "png", "image/png" },
+ { "ppt", "application/x-mspowerpoint" },
+ { "ps", "application/postscript" },
+ { "qt", "video/quicktime" },
+ { "ra", "audio/x-pn-realaudio" },
+ { "ram", "audio/x-pn-realaudio" },
+ { "rar", "application/x-arj-compressed" },
+ { "rgb", "image/x-rgb" },
+ { "rtf", "application/rtf" },
+ { "sgm", "text/sgml" },
+ { "shtm", "text/html" },
+ { "shtml", "text/html" },
+ { "sil", "application/font-sfnt" },
+ { "svg", "image/svg+xml" },
+ { "swf", "application/x-shockwave-flash" },
+ { "tar", "application/x-tar" },
+ { "tgz", "application/x-tar-gz" },
+ { "tif", "image/tiff" },
+ { "tiff", "image/tiff" },
+ { "torrent", "application/x-bittorrent" },
+ { "ttf", "application/font-sfnt" },
+ { "txt", "text/plain" },
+ { "wav", "audio/x-wav" },
+ { "webm", "video/webm" },
+ { "woff", "application/font-woff" },
+ { "wrl", "model/vrml" },
+ { "xhtml", "application/xhtml+xml" },
+ { "xls", "application/x-msexcel" },
+ { "xml", "text/xml" },
+ { "xsl", "application/xml" },
+ { "xslt", "application/xml" },
+ { "zip", "application/x-zip-compressed" }
+};
+
+static std::string extension_to_type(const std::string& extension)
+{
+ for (mapping m : mappings)
+ {
+ if (m.extension == extension)
+ {
+ return m.mime_type;
+ }
+ }
+
+ return "text/plain";
+}
+
+machine_manager::machine_manager(emu_options& options, osd_interface& osd)
+ : m_osd(osd),
+ m_options(options),
+ m_machine(nullptr),
+ m_io_context(std::make_shared<asio::io_context>())
+{
+}
+
+machine_manager::~machine_manager()
+{
+ if (options().http())
+ {
+ m_server->stop();
+ }
+ m_server_thread.join();
+}
+
+void machine_manager::start_http_server()
+{
+ if (options().http())
+ {
+ m_server = std::make_unique<webpp::http_server>();
+ m_server->m_config.port = options().http_port();
+ m_server->set_io_context(m_io_context);
+ m_wsserver = std::make_unique<webpp::ws_server>();
+
+ auto& endpoint = m_wsserver->endpoint["/"];
+
+ m_server->on_get([this](auto response, auto request) {
+ std::string doc_root = this->options().http_root();
+
+ std::string path = request->path;
+ // If path ends in slash (i.e. is a directory) then add "index.html".
+ if (path[path.size() - 1] == '/')
+ {
+ path += "index.html";
+ }
+
+ std::size_t last_qmark_pos = path.find_last_of("?");
+ if (last_qmark_pos != std::string::npos)
+ path = path.substr(0, last_qmark_pos - 1);
+
+ // Determine the file extension.
+ std::size_t last_slash_pos = path.find_last_of("/");
+ std::size_t last_dot_pos = path.find_last_of(".");
+ std::string extension;
+ if (last_dot_pos != std::string::npos && last_dot_pos > last_slash_pos)
+ {
+ extension = path.substr(last_dot_pos + 1);
+ }
+
+ // Open the file to send back.
+ std::string full_path = doc_root + path;
+ std::ifstream is(full_path.c_str(), std::ios::in | std::ios::binary);
+ if (!is)
+ {
+ response->status(400).send("Error");
+ }
+
+ // Fill out the reply to be sent to the client.
+ std::string content;
+ char buf[512];
+ while (is.read(buf, sizeof(buf)).gcount() > 0)
+ content.append(buf, size_t(is.gcount()));
+
+ response->type(extension_to_type(extension));
+ response->status(200).send(content);
+
+ });
+
+ endpoint.on_open = [&](auto connection) {
+ auto send_stream = std::make_shared<webpp::ws_server::SendStream>();
+ *send_stream << "update_machine";
+ m_wsserver->send(connection, send_stream, [](const std::error_code& ec) { });
+ };
+
+ m_server->on_upgrade = [this](auto socket, auto request) {
+ auto connection = std::make_shared<webpp::ws_server::Connection>(socket);
+ connection->method = std::move(request->method);
+ connection->path = std::move(request->path);
+ connection->http_version = std::move(request->http_version);
+ connection->header = std::move(request->header);
+ connection->remote_endpoint_address = std::move(request->remote_endpoint_address);
+ connection->remote_endpoint_port = request->remote_endpoint_port;
+ m_wsserver->upgrade(connection);
+ };
+ m_server->start();
+ }
+}
+
+void machine_manager::start_context()
+{
+ m_server_thread = std::thread([this]() {
+ m_io_context->run();
+ });
+}
+
diff --git a/src/emu/main.h b/src/emu/main.h
index 12f0f1a9462..3a5f5a5c689 100644
--- a/src/emu/main.h
+++ b/src/emu/main.h
@@ -16,6 +16,7 @@
#ifndef MAME_EMU_MAIN_H
#define MAME_EMU_MAIN_H
+#include <thread>
#include <time.h>
//**************************************************************************
@@ -65,15 +66,24 @@ public:
// ======================> machine_manager
class ui_manager;
+namespace asio
+{
+ class io_context;
+}
+namespace webpp
+{
+ class http_server;
+ class ws_server;
+}
class machine_manager
{
DISABLE_COPYING(machine_manager);
protected:
// construction/destruction
- machine_manager(emu_options &options, osd_interface &osd) : m_osd(osd), m_options(options), m_machine(nullptr) { }
+ machine_manager(emu_options& options, osd_interface& osd);
public:
- virtual ~machine_manager() { }
+ virtual ~machine_manager();
osd_interface &osd() const { return m_osd; }
emu_options &options() const { return m_options; }
@@ -87,10 +97,18 @@ public:
virtual void ui_initialize(running_machine& machine) { }
virtual void update_machine() { }
+
+ void start_http_server();
+ void start_context();
+ webpp::http_server* http_server() const { return m_server.get(); }
protected:
osd_interface & m_osd; // reference to OSD system
emu_options & m_options; // reference to options
running_machine * m_machine;
+ std::shared_ptr<asio::io_context> m_io_context;
+ std::unique_ptr<webpp::http_server> m_server;
+ std::unique_ptr<webpp::ws_server> m_wsserver;
+ std::thread m_server_thread;
};
diff --git a/src/emu/natkeyboard.cpp b/src/emu/natkeyboard.cpp
index fd39bc7b5e0..a5d856a20e9 100644
--- a/src/emu/natkeyboard.cpp
+++ b/src/emu/natkeyboard.cpp
@@ -372,7 +372,13 @@ void natural_keyboard::set_in_use(bool usage)
for (auto &port : machine().ioport().ports())
for (ioport_field &field : port.second->fields())
if (field.type() == IPT_KEYBOARD)
+ {
field.live().lockout = usage;
+
+ // clear pressed status when going out of use
+ if (!usage)
+ field.set_value(0);
+ }
}
}
@@ -722,8 +728,23 @@ void natural_keyboard::timer(void *ptr, int param)
const bool new_keydown = !m_status_keydown;
const keycode_map_entry *const code = find_code(m_buffer[m_bufbegin]);
if (code != nullptr)
- for (int fieldnum = 0; fieldnum < ARRAY_LENGTH(code->field) && code->field[fieldnum] != nullptr; fieldnum++)
- code->field[fieldnum]->set_value(new_keydown);
+ {
+ for (int fieldnum = 0; fieldnum < ARRAY_LENGTH(code->field); fieldnum++)
+ {
+ ioport_field *const field = code->field[fieldnum];
+ if (field == nullptr)
+ break;
+
+ // special handling for toggle fields
+ if (field->live().toggle)
+ {
+ if (new_keydown)
+ field->set_value(!field->digital_value());
+ }
+ else
+ field->set_value(new_keydown);
+ }
+ }
// proceed to next character when keydown expires
if (!new_keydown)
diff --git a/src/frontend/mame/clifront.cpp b/src/frontend/mame/clifront.cpp
index ff7e371c438..fd785ef8139 100644
--- a/src/frontend/mame/clifront.cpp
+++ b/src/frontend/mame/clifront.cpp
@@ -309,9 +309,13 @@ int cli_frontend::execute(int argc, char **argv)
load_translation(m_options);
+ manager->start_http_server();
+
manager->start_luaengine();
- start_execution(manager, argc, argv, option_errors);
+ manager->start_context();
+
+ start_execution(manager, argc, argv, option_errors);
}
// handle exceptions of various types
catch (emu_fatalerror &fatal)
diff --git a/src/frontend/mame/info.cpp b/src/frontend/mame/info.cpp
index 0889dd7bd39..1479978ceb9 100644
--- a/src/frontend/mame/info.cpp
+++ b/src/frontend/mame/info.cpp
@@ -603,7 +603,7 @@ void info_xml_creator::output_rom(device_t &device)
if (bios_name[0] != 0)
util::stream_format(output, " bios=\"%s\"", util::xml::normalize_string(bios_name));
if (!is_disk)
- util::stream_format(output, " size=\"%d\"", rom_file_size(rom));
+ util::stream_format(output, " size=\"%u\"", rom_file_size(rom));
// dump checksum information only if there is a known dump
if (!hashes.flag(util::hash_collection::FLAG_NO_DUMP))
diff --git a/src/frontend/mame/ui/info.cpp b/src/frontend/mame/ui/info.cpp
index 9de81cef6ec..18a2039e5d4 100644
--- a/src/frontend/mame/ui/info.cpp
+++ b/src/frontend/mame/ui/info.cpp
@@ -30,6 +30,7 @@ machine_info::machine_info(running_machine &machine)
m_has_dips = false;
m_has_bioses = false;
m_has_keyboard = false;
+ m_has_test_switch = false;
// scan the input port array to see what options we need to enable
for (auto &port : machine.ioport().ports())
@@ -43,6 +44,8 @@ machine_info::machine_info(running_machine &machine)
m_has_analog = true;
if (field.type() == IPT_KEYBOARD)
m_has_keyboard = true;
+ if (field.type() == IPT_SERVICE)
+ m_has_test_switch = true;
}
for (device_t &device : device_iterator(machine.root_device()))
diff --git a/src/frontend/mame/ui/info.h b/src/frontend/mame/ui/info.h
index 21d920e4131..b718c2acf64 100644
--- a/src/frontend/mame/ui/info.h
+++ b/src/frontend/mame/ui/info.h
@@ -29,6 +29,7 @@ public:
bool has_dips() const { return m_has_dips; }
bool has_bioses() const { return m_has_bioses; }
bool has_keyboard() const { return m_has_keyboard; }
+ bool has_test_switch() const { return m_has_test_switch; }
// text generators
std::string warnings_string();
@@ -46,6 +47,7 @@ private:
bool m_has_dips;
bool m_has_bioses;
bool m_has_keyboard;
+ bool m_has_test_switch;
};
class menu_game_info : public menu
diff --git a/src/frontend/mame/ui/ui.cpp b/src/frontend/mame/ui/ui.cpp
index d7bf97a6562..bda9bdcf3be 100644
--- a/src/frontend/mame/ui/ui.cpp
+++ b/src/frontend/mame/ui/ui.cpp
@@ -256,6 +256,16 @@ void mame_ui_manager::initialize(running_machine &machine)
{
slider_current = nullptr;
}
+
+ // if no test switch found, assign its input sequence to a service mode DIP
+ if (!m_machine_info->has_test_switch() && m_machine_info->has_dips())
+ {
+ const char *const service_mode_dipname = ioport_configurer::string_from_token(DEF_STR(Service_Mode));
+ for (auto &port : machine.ioport().ports())
+ for (ioport_field &field : port.second->fields())
+ if (field.type() == IPT_DIPSWITCH && strcmp(field.name(), service_mode_dipname) == 0)
+ field.set_defseq(machine.ioport().type_seq(IPT_SERVICE));
+ }
}
diff --git a/src/lib/formats/pc_dsk.cpp b/src/lib/formats/pc_dsk.cpp
index 73ef727cdaf..32b6f079bbb 100644
--- a/src/lib/formats/pc_dsk.cpp
+++ b/src/lib/formats/pc_dsk.cpp
@@ -159,6 +159,18 @@ const char *pc_format::extensions() const
return "dsk,ima,img,ufi,360";
}
+int pc_format::identify(io_generic *io, uint32_t form_factor)
+{
+ uint64_t size = io_generic_size(io);
+
+ /* some 360K images have a 512-byte header */
+ if (size == 368640 + 0x200) {
+ file_header_skip_bytes = 0x200;
+ }
+
+ return upd765_format::identify(io, form_factor);
+}
+
const pc_format::format pc_format::formats[] = {
{ /* 160K 5 1/4 inch double density single sided */
floppy_image::FF_525, floppy_image::SSDD, floppy_image::MFM,
diff --git a/src/lib/formats/pc_dsk.h b/src/lib/formats/pc_dsk.h
index 381ad49e99a..02b3aa2468b 100644
--- a/src/lib/formats/pc_dsk.h
+++ b/src/lib/formats/pc_dsk.h
@@ -24,6 +24,8 @@ class pc_format : public upd765_format
public:
pc_format();
+ virtual int identify(io_generic *io, uint32_t form_factor) override;
+
virtual const char *name() const override;
virtual const char *description() const override;
virtual const char *extensions() const override;
diff --git a/src/lib/formats/upd765_dsk.cpp b/src/lib/formats/upd765_dsk.cpp
index a7e5febc3d7..72e11257b89 100644
--- a/src/lib/formats/upd765_dsk.cpp
+++ b/src/lib/formats/upd765_dsk.cpp
@@ -11,7 +11,7 @@
#include "emu.h" // emu_fatalerror
#include "formats/upd765_dsk.h"
-upd765_format::upd765_format(const format *_formats)
+upd765_format::upd765_format(const format *_formats) : file_header_skip_bytes(0)
{
formats = _formats;
}
@@ -24,7 +24,7 @@ int upd765_format::find_size(io_generic *io, uint32_t form_factor) const
if(form_factor != floppy_image::FF_UNKNOWN && form_factor != f.form_factor)
continue;
- if(size == (uint64_t) compute_track_size(f) * f.track_count * f.head_count)
+ if(size == file_header_skip_bytes + (uint64_t) compute_track_size(f) * f.track_count * f.head_count)
return i;
}
return -1;
@@ -220,7 +220,7 @@ bool upd765_format::load(io_generic *io, uint32_t form_factor, floppy_image *ima
for(int track=0; track < f.track_count; track++)
for(int head=0; head < f.head_count; head++) {
build_sector_description(f, sectdata, sectors, track, head);
- io_generic_read(io, sectdata, (track*f.head_count + head)*track_size, track_size);
+ io_generic_read(io, sectdata, file_header_skip_bytes + (track*f.head_count + head)*track_size, track_size);
generate_track(desc, track, head, sectors, f.sector_count, total_size, image);
}
diff --git a/src/lib/formats/upd765_dsk.h b/src/lib/formats/upd765_dsk.h
index 5bd675de9e8..980d21a396e 100644
--- a/src/lib/formats/upd765_dsk.h
+++ b/src/lib/formats/upd765_dsk.h
@@ -44,6 +44,8 @@ public:
virtual bool supports_save() const override;
protected:
+ uint64_t file_header_skip_bytes;
+
floppy_image_format_t::desc_e* get_desc_fm(const format &f, int &current_size, int &end_gap_index);
floppy_image_format_t::desc_e* get_desc_mfm(const format &f, int &current_size, int &end_gap_index);
int find_size(io_generic *io, uint32_t form_factor) const;
diff --git a/src/lib/netlist/analog/nld_bjt.h b/src/lib/netlist/analog/nld_bjt.h
index e2da1bd529f..0c91d58bdb6 100644
--- a/src/lib/netlist/analog/nld_bjt.h
+++ b/src/lib/netlist/analog/nld_bjt.h
@@ -48,7 +48,7 @@ public:
{
}
- NETLIB_DYNAMIC()
+ NETLIB_IS_DYNAMIC()
//NETLIB_RESETI();
NETLIB_UPDATEI();
diff --git a/src/lib/netlist/analog/nld_fourterm.h b/src/lib/netlist/analog/nld_fourterm.h
index 7792607cf7a..723eccf77f5 100644
--- a/src/lib/netlist/analog/nld_fourterm.h
+++ b/src/lib/netlist/analog/nld_fourterm.h
@@ -115,7 +115,7 @@ public:
{
}
- NETLIB_DYNAMIC()
+ NETLIB_IS_DYNAMIC()
param_double_t m_cur_limit; /* current limit */
diff --git a/src/lib/netlist/analog/nld_opamps.cpp b/src/lib/netlist/analog/nld_opamps.cpp
index d587f691e56..3dc6711c406 100644
--- a/src/lib/netlist/analog/nld_opamps.cpp
+++ b/src/lib/netlist/analog/nld_opamps.cpp
@@ -8,35 +8,6 @@
#include "nld_opamps.h"
#include "devices/net_lib.h"
-NETLIST_START(opamp_lm3900)
-
- /*
- * Fast norton opamp model without bandwidth
- */
-
- /* Terminal definitions for calling netlists */
-
- ALIAS(PLUS, R1.1) // Positive input
- ALIAS(MINUS, R2.1) // Negative input
- ALIAS(OUT, G1.OP) // Opamp output ...
- ALIAS(VM, G1.ON) // V- terminal
- ALIAS(VP, DUMMY.I) // V+ terminal
-
- DUMMY_INPUT(DUMMY)
-
- /* The opamp model */
-
- RES(R1, 1)
- RES(R2, 1)
- NET_C(R1.1, G1.IP)
- NET_C(R2.1, G1.IN)
- NET_C(R1.2, R2.2, G1.ON)
- VCVS(G1)
- PARAM(G1.G, 10000000)
- //PARAM(G1.RI, 1)
- PARAM(G1.RO, RES_K(8))
-
-NETLIST_END()
namespace netlist
{
diff --git a/src/lib/netlist/analog/nld_opamps.h b/src/lib/netlist/analog/nld_opamps.h
index 5d9825d4b21..95060dfdbd3 100644
--- a/src/lib/netlist/analog/nld_opamps.h
+++ b/src/lib/netlist/analog/nld_opamps.h
@@ -23,15 +23,10 @@
NET_REGISTER_DEV(OPAMP, name) \
NETDEV_PARAMI(name, MODEL, model)
-#define LM3900(name) \
- SUBMODEL(opamp_lm3900, name)
-
// ----------------------------------------------------------------------------------------
// Devices ...
// ----------------------------------------------------------------------------------------
-NETLIST_EXTERNAL(opamp_lm3900)
-
namespace netlist
{
namespace devices
diff --git a/src/lib/netlist/analog/nld_twoterm.cpp b/src/lib/netlist/analog/nld_twoterm.cpp
index 089b11f8607..9818ea9f86f 100644
--- a/src/lib/netlist/analog/nld_twoterm.cpp
+++ b/src/lib/netlist/analog/nld_twoterm.cpp
@@ -45,6 +45,44 @@ void generic_diode::set_param(const nl_double Is, const nl_double n, nl_double g
m_VtInv = 1.0 / m_Vt;
}
+void generic_diode::update_diode(const nl_double nVd)
+{
+#if 1
+ if (nVd < NL_FCONST(-5.0) * m_Vt)
+ {
+ m_Vd = nVd;
+ m_G = m_gmin;
+ m_Id = - m_Is;
+ }
+ else if (nVd < m_Vcrit)
+ {
+ m_Vd = nVd;
+ //m_Vd = m_Vd + 10.0 * m_Vt * std::tanh((nVd - m_Vd) / 10.0 / m_Vt);
+ const nl_double eVDVt = std::exp(m_Vd * m_VtInv);
+ m_Id = m_Is * (eVDVt - NL_FCONST(1.0));
+ m_G = m_Is * m_VtInv * eVDVt + m_gmin;
+ }
+ else
+ {
+#if 1
+ const nl_double a = std::max((nVd - m_Vd) * m_VtInv, NL_FCONST(-0.99));
+ m_Vd = m_Vd + std::log1p(a) * m_Vt;
+#else
+ m_Vd = m_Vd + 10.0 * m_Vt * std::tanh((nVd - m_Vd) / 10.0 / m_Vt);
+#endif
+ const nl_double eVDVt = std::exp(m_Vd * m_VtInv);
+ m_Id = m_Is * (eVDVt - NL_FCONST(1.0));
+
+ m_G = m_Is * m_VtInv * eVDVt + m_gmin;
+ }
+#else
+ m_Vd = m_Vd + 20.0 * m_Vt * std::tanh((nVd - m_Vd) / 20.0 / m_Vt);
+ const nl_double eVDVt = std::exp(m_Vd * m_VtInv);
+ m_Id = m_Is * (eVDVt - NL_FCONST(1.0));
+ m_G = m_Is * m_VtInv * eVDVt + m_gmin;
+#endif
+}
+
// ----------------------------------------------------------------------------------------
// nld_twoterm
// ----------------------------------------------------------------------------------------
@@ -101,14 +139,14 @@ NETLIB_UPDATE_PARAM(POT2)
NETLIB_RESET(C)
{
+ // FIXME: Startup conditions
set(netlist().gmin(), 0.0, -5.0 / netlist().gmin());
- //set(1.0/NETLIST_GMIN, 0.0, -5.0 * NETLIST_GMIN);
+ //set(netlist().gmin(), 0.0, 0.0);
}
NETLIB_UPDATE_PARAM(C)
{
- //step_time(1.0/48000.0);
- m_GParallel = netlist().gmin() * m_C();
+ m_GParallel = netlist().gmin();
}
NETLIB_UPDATE(C)
@@ -116,6 +154,14 @@ NETLIB_UPDATE(C)
NETLIB_NAME(twoterm)::update();
}
+NETLIB_TIMESTEP(C)
+{
+ /* Gpar should support convergence */
+ const nl_double G = m_C() / step + m_GParallel;
+ const nl_double I = -G * deltaV();
+ set(G, 0.0, I);
+}
+
// ----------------------------------------------------------------------------------------
// nld_L
// ----------------------------------------------------------------------------------------
@@ -128,8 +174,7 @@ NETLIB_RESET(L)
NETLIB_UPDATE_PARAM(L)
{
- //step_time(1.0/48000.0);
- //m_GParallel = netlist().gmin() / m_L();
+ m_GParallel = netlist().gmin();
}
NETLIB_UPDATE(L)
@@ -137,6 +182,14 @@ NETLIB_UPDATE(L)
NETLIB_NAME(twoterm)::update();
}
+NETLIB_TIMESTEP(L)
+{
+ /* Gpar should support convergence */
+ m_I += m_I + m_G * deltaV();
+ m_G = step / m_L() + m_GParallel;
+ set(m_G, 0.0, m_I);
+}
+
// ----------------------------------------------------------------------------------------
// nld_D
// ----------------------------------------------------------------------------------------
diff --git a/src/lib/netlist/analog/nld_twoterm.h b/src/lib/netlist/analog/nld_twoterm.h
index f59b9e62594..2ff6db1e2c3 100644
--- a/src/lib/netlist/analog/nld_twoterm.h
+++ b/src/lib/netlist/analog/nld_twoterm.h
@@ -137,7 +137,9 @@ public:
return m_P.net().Q_Analog() - m_N.net().Q_Analog();
}
- void set_mat(nl_double a11, nl_double a12, nl_double a21, nl_double a22, nl_double r1, nl_double r2)
+ void set_mat(const nl_double a11, const nl_double a12,
+ const nl_double a21, const nl_double a22,
+ const nl_double r1, const nl_double r2)
{
/* GO, GT, I */
m_P.set(-a12, a11, -r1);
@@ -286,14 +288,8 @@ public:
//register_term("2", m_N);
}
- NETLIB_TIMESTEP()
- {
- /* Gpar should support convergence */
- const nl_double G = m_C() / step + m_GParallel;
- const nl_double I = -G * deltaV();
- set(G, 0.0, I);
- }
-
+ NETLIB_IS_TIMESTEP()
+ NETLIB_TIMESTEPI();
param_double_t m_C;
@@ -324,13 +320,8 @@ public:
//register_term("2", m_N);
}
- NETLIB_TIMESTEP()
- {
- /* Gpar should support convergence */
- m_I = m_I + m_G * deltaV();
- m_G = step / m_L() + m_GParallel;
- set(m_G, 0.0, m_I);
- }
+ NETLIB_IS_TIMESTEP()
+ NETLIB_TIMESTEPI();
param_double_t m_L;
@@ -354,43 +345,7 @@ class generic_diode
public:
generic_diode(device_t &dev, pstring name);
- inline void update_diode(const nl_double nVd)
- {
-#if 1
- if (nVd < NL_FCONST(-5.0) * m_Vt)
- {
- m_Vd = nVd;
- m_G = m_gmin;
- m_Id = - m_Is;
- }
- else if (nVd < m_Vcrit)
- {
- m_Vd = nVd;
- //m_Vd = m_Vd + 10.0 * m_Vt * std::tanh((nVd - m_Vd) / 10.0 / m_Vt);
- const nl_double eVDVt = std::exp(m_Vd * m_VtInv);
- m_Id = m_Is * (eVDVt - NL_FCONST(1.0));
- m_G = m_Is * m_VtInv * eVDVt + m_gmin;
- }
- else
- {
-#if 1
- const nl_double a = std::max((nVd - m_Vd) * m_VtInv, NL_FCONST(0.5) - NL_FCONST(1.0));
- m_Vd = m_Vd + std::log1p(a) * m_Vt;
-#else
- m_Vd = m_Vd + 10.0 * m_Vt * std::tanh((nVd - m_Vd) / 10.0 / m_Vt);
-#endif
- const nl_double eVDVt = std::exp(m_Vd * m_VtInv);
- m_Id = m_Is * (eVDVt - NL_FCONST(1.0));
-
- m_G = m_Is * m_VtInv * eVDVt + m_gmin;
- }
-#else
- m_Vd = m_Vd + 20.0 * m_Vt * std::tanh((nVd - m_Vd) / 20.0 / m_Vt);
- const nl_double eVDVt = std::exp(m_Vd * m_VtInv);
- m_Id = m_Is * (eVDVt - NL_FCONST(1.0));
- m_G = m_Is * m_VtInv * eVDVt + m_gmin;
-#endif
- }
+ void update_diode(const nl_double nVd);
void set_param(const nl_double Is, const nl_double n, nl_double gmin);
@@ -430,7 +385,7 @@ public:
register_subalias("K", m_N);
}
- NETLIB_DYNAMIC()
+ NETLIB_IS_DYNAMIC()
NETLIB_UPDATE_TERMINALSI();
diff --git a/src/lib/netlist/build/makefile b/src/lib/netlist/build/makefile
index 171ba4cf5bb..81883053776 100644
--- a/src/lib/netlist/build/makefile
+++ b/src/lib/netlist/build/makefile
@@ -49,6 +49,7 @@ POBJS := \
$(POBJ)/palloc.o \
$(POBJ)/pchrono.o \
$(POBJ)/pdynlib.o \
+ $(POBJ)/pexception.o \
$(POBJ)/pfmtlog.o \
$(POBJ)/poptions.o \
$(POBJ)/pparser.o \
@@ -166,9 +167,9 @@ maketree: $(sort $(OBJDIRS))
.PHONY: clang mingw doc
clang:
- $(MAKE) CC=clang++ LD=clang++ CEXTRAFLAGS="-Weverything -Werror -Wno-padded -Wno-weak-vtables -Wno-missing-variable-declarations -Wconversion -Wno-c++98-compat -Wno-float-equal -Wno-cast-align -Wno-global-constructors -Wno-c++98-compat-pedantic -Wno-exit-time-destructors -Wno-format-nonliteral -Wno-weak-template-vtables"
+ $(MAKE) CC=clang++ LD=clang++ CEXTRAFLAGS="-Weverything -Werror -Wno-padded -Wno-missing-variable-declarations -Wconversion -Wno-c++98-compat -Wno-float-equal -Wno-cast-align -Wno-global-constructors -Wno-c++98-compat-pedantic -Wno-exit-time-destructors -Wno-format-nonliteral -Wno-weak-template-vtables"
-#
+#-Wno-weak-vtables
# FIXME: -Wno-weak-vtables -Wno-missing-variable-declarations -Wno-conversion -Wno-exit-time-destructors
#
diff --git a/src/lib/netlist/devices/net_lib.cpp b/src/lib/netlist/devices/net_lib.cpp
index 5250135feb8..9f23283ac6b 100644
--- a/src/lib/netlist/devices/net_lib.cpp
+++ b/src/lib/netlist/devices/net_lib.cpp
@@ -63,7 +63,7 @@ NETLIST_END()
#define ENTRY1(nic, name, defparam) factory.register_device<nic>( # name, xstr(nic), defparam );
#define ENTRY(nic, name, defparam) ENTRY1(NETLIB_NAME(nic), name, defparam)
-#define NETLIB_DEVICE_DECL(chip) extern factory_creator_ptr_t decl_ ## chip;
+#define NETLIB_DEVICE_DECL(chip) extern factory::constructor_ptr_t decl_ ## chip;
#define ENTRYX1(nic, name, defparam, decl) factory.register_device( decl (# name, xstr(nic), defparam) );
#define ENTRYX(nic, name, defparam) { NETLIB_DEVICE_DECL(nic) ENTRYX1(NETLIB_NAME(nic), name, defparam, decl_ ## nic) }
@@ -72,7 +72,7 @@ namespace netlist
{
namespace devices
{
-static void initialize_factory(factory_list_t &factory)
+static void initialize_factory(factory::list_t &factory)
{
ENTRY(R, RES, "R")
ENTRY(POT, POT, "R")
@@ -80,15 +80,15 @@ static void initialize_factory(factory_list_t &factory)
ENTRY(C, CAP, "C")
ENTRY(L, IND, "L")
ENTRY(D, DIODE, "MODEL")
- ENTRY(VCVS, VCVS, "-")
- ENTRY(VCCS, VCCS, "-")
- ENTRY(CCCS, CCCS, "-")
- ENTRY(LVCCS, LVCCS, "-")
+ ENTRY(VCVS, VCVS, "")
+ ENTRY(VCCS, VCCS, "")
+ ENTRY(CCCS, CCCS, "")
+ ENTRY(LVCCS, LVCCS, "")
ENTRY(VS, VS, "V")
ENTRY(CS, CS, "I")
ENTRY(OPAMP, OPAMP, "MODEL")
- ENTRYX(dummy_input, DUMMY_INPUT, "-")
- ENTRYX(frontier, FRONTIER_DEV, "+I,G,Q") // not intended to be used directly
+ ENTRYX(dummy_input, DUMMY_INPUT, "")
+ ENTRYX(frontier, FRONTIER_DEV, "+I,+G,+Q") // not intended to be used directly
ENTRYX(function, AFUNC, "N,FUNC") // only for macro devices - NO FEEDBACK loops
ENTRY(QBJT_EB, QBJT_EB, "MODEL")
ENTRY(QBJT_switch, QBJT_SW, "MODEL")
@@ -96,106 +96,107 @@ static void initialize_factory(factory_list_t &factory)
ENTRYX(logic_input, LOGIC_INPUT, "IN,FAMILY")
ENTRYX(analog_input, ANALOG_INPUT, "IN")
ENTRYX(log, LOG, "+I")
- ENTRYX(logD, LOGD, "+I,I2")
+ ENTRYX(logD, LOGD, "+I,+I2")
ENTRYX(clock, CLOCK, "FREQ")
ENTRYX(extclock, EXTCLOCK, "FREQ")
ENTRYX(mainclock, MAINCLOCK, "FREQ")
- ENTRYX(gnd, GND, "-")
- ENTRYX(netlistparams, PARAMETER, "-")
+ ENTRYX(gnd, GND, "")
+ ENTRYX(netlistparams, PARAMETER, "")
ENTRY(solver, SOLVER, "FREQ")
- ENTRYX(res_sw, RES_SWITCH, "+IN,P1,P2")
- ENTRY(switch1, SWITCH, "-")
- ENTRY(switch2, SWITCH2, "-")
- ENTRYX(nicRSFF, NETDEV_RSFF, "+S,R")
- ENTRYX(nicDelay, NETDEV_DELAY, "-")
- ENTRYX(2716, EPROM_2716, "+GQ,EPQ,A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10")
- ENTRYX(2102A, RAM_2102A, "+CEQ,A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,RWQ,DI")
- ENTRYX(7450, TTL_7450_ANDORINVERT, "+A,B,C,D")
- ENTRYX(7448, TTL_7448, "+A,B,C,D,LTQ,BIQ,RBIQ")
- ENTRYX(7473, TTL_7473, "+CLK,J,K,CLRQ")
- ENTRYX(7473A, TTL_7473A, "+CLK,J,K,CLRQ")
- ENTRYX(7474, TTL_7474, "+CLK,D,CLRQ,PREQ")
- ENTRYX(7475, TTL_7475, "-")
- ENTRYX(7477, TTL_7477, "-")
- ENTRYX(7483, TTL_7483, "+A1,A2,A3,A4,B1,B2,B3,B4,C0")
- ENTRYX(7485, TTL_7485, "+A0,A1,A2,A3,B0,B1,B2,B3,LTIN,EQIN,GTIN")
- ENTRYX(7490, TTL_7490, "+A,B,R1,R2,R91,R92")
- ENTRYX(7493, TTL_7493, "+CLKA,CLKB,R1,R2")
- ENTRYX(74107, TTL_74107, "+CLK,J,K,CLRQ")
- ENTRYX(74107A, TTL_74107A, "+CLK,J,K,CLRQ")
- ENTRYX(74123, TTL_74123, "-")
- ENTRYX(74153, TTL_74153, "+C0,C1,C2,C3,A,B,G")
- ENTRYX(74161, TTL_74161, "+A,B,C,D,CLRQ,LOADQ,CLK,ENABLEP,ENABLET")
- ENTRYX(74165, TTL_74165, "+CLK,CLKINH,SH_LDQ,SER,A,B,C,D,E,F,G,H")
- ENTRYX(74166, TTL_74166, "+CLK,CLKINH,SH_LDQ,SER,A,B,C,D,E,F,G,H,CLRQ")
- ENTRYX(74174, TTL_74174, "+CLK,D1,D2,D3,D4,D5,D6,CLRQ")
- ENTRYX(74175, TTL_74175, "+CLK,D1,D2,D3,D4,CLRQ")
- ENTRYX(74192, TTL_74192, "+A,B,C,D,CLEAR,LOADQ,CU,CD")
- ENTRYX(74193, TTL_74193, "+A,B,C,D,CLEAR,LOADQ,CU,CD")
- ENTRYX(74194, TTL_74194, "+CLK,S0,S1,SRIN,A,B,C,D,SLIN,CLRQ")
- ENTRYX(74365, TTL_74365, "+G1Q,G2Q,A1,A2,A3,A4,A5,A6")
- //ENTRY(74279, TTL_74279, "-") // only dip available
+ ENTRYX(res_sw, RES_SWITCH, "+IN,+P1,+P2")
+ ENTRY(switch1, SWITCH, "")
+ ENTRY(switch2, SWITCH2, "")
+ ENTRYX(nicRSFF, NETDEV_RSFF, "+S,+R")
+ ENTRYX(nicDelay, NETDEV_DELAY, "")
+ ENTRYX(2716, EPROM_2716, "+GQ,+EPQ,+A0,+A1,+A2,+A3,+A4,+A5,+A6,+A7,+A8,+A9,+A10")
+ ENTRYX(2102A, RAM_2102A, "+CEQ,+A0,+A1,+A2,+A3,+A4,+A5,+A6,+A7,+A8,+A9,+RWQ,+DI")
+ ENTRYX(7450, TTL_7450_ANDORINVERT, "+A,+B,+C,+D")
+ ENTRYX(7448, TTL_7448, "+A,+B,+C,+D,+LTQ,+BIQ,+RBIQ")
+ ENTRYX(7473, TTL_7473, "+CLK,+J,+K,+CLRQ")
+ ENTRYX(7473A, TTL_7473A, "+CLK,+J,+K,+CLRQ")
+ ENTRYX(7474, TTL_7474, "+CLK,+D,+CLRQ,+PREQ")
+ ENTRYX(7475, TTL_7475, "")
+ ENTRYX(7477, TTL_7477, "")
+ ENTRYX(7483, TTL_7483, "+A1,+A2,+A3,+A4,+B1,+B2,+B3,+B4,+C0")
+ ENTRYX(7485, TTL_7485, "+A0,+A1,+A2,+A3,+B0,+B1,+B2,+B3,+LTIN,+EQIN,+GTIN")
+ ENTRYX(7490, TTL_7490, "+A,+B,+R1,+R2,+R91,+R92")
+ ENTRYX(7493, TTL_7493, "+CLKA,+CLKB,+R1,+R2")
+ ENTRYX(74107, TTL_74107, "+CLK,+J,+K,+CLRQ")
+ ENTRYX(74107A, TTL_74107A, "+CLK,+J,+K,+CLRQ")
+ ENTRYX(74123, TTL_74123, "")
+ ENTRYX(74153, TTL_74153, "+C0,+C1,+C2,+C3,+A,+B,+G")
+ ENTRYX(74161, TTL_74161, "+A,+B,+C,+D,+CLRQ,+LOADQ,+CLK,+ENABLEP,+ENABLET")
+ ENTRYX(74165, TTL_74165, "+CLK,+CLKINH,+SH_LDQ,+SER,+A,+B,+C,+D,+E,+F,+G,+H")
+ ENTRYX(74166, TTL_74166, "+CLK,+CLKINH,+SH_LDQ,+SER,+A,+B,+C,+D,+E,+F,+G,+H,+CLRQ")
+ ENTRYX(74174, TTL_74174, "+CLK,+D1,+D2,+D3,+D4,+D5,+D6,+CLRQ")
+ ENTRYX(74175, TTL_74175, "+CLK,+D1,+D2,+D3,+D4,+CLRQ")
+ ENTRYX(74192, TTL_74192, "+A,+B,+C,+D,+CLEAR,+LOADQ,+CU,+CD")
+ ENTRYX(74193, TTL_74193, "+A,+B,+C,+D,+CLEAR,+LOADQ,+CU,+CD")
+ ENTRYX(74194, TTL_74194, "+CLK,+S0,+S1,+SRIN,+A,+B,+C,+D,+SLIN,+CLRQ")
+ ENTRYX(74365, TTL_74365, "+G1Q,+G2Q,+A1,+A2,+A3,+A4,+A5,+A6")
+ //ENTRY(74279, TTL_74279, "") // only dip available
ENTRYX(SN74LS629, SN74LS629, "CAP")
- ENTRYX(82S16, TTL_82S16, "-")
- ENTRYX(82S115, PROM_82S115, "+CE1Q,CE2,A0,A1,A2,A3,A4,A5,A6,A7,A8,STROBE")
- ENTRYX(82S123, PROM_82S123, "+CEQ,A0,A1,A2,A3,A4")
- ENTRYX(82S126, PROM_82S126, "+CE1Q,CE2Q,A0,A1,A2,A3,A4,A5,A6,A7")
- ENTRYX(9310, TTL_9310, "-")
- ENTRYX(9312, TTL_9312, "+A,B,C,D0,D1,D2,D3,D4,D5,D6,D7,G")
- ENTRYX(9316, TTL_9316, "+CLK,ENP,ENT,CLRQ,LOADQ,A,B,C,D")
- ENTRYX(9322, TTL_9322, "+SELECT,A1,B1,A2,B2,A3,B3,A4,B4,STROBE")
- ENTRYX(9334, TTL_9334, "+CQ,EQ,D,A0,A1,A2")
- ENTRYX(AM2847, TTL_AM2847, "+CP,INA,INB,INC,IND,RCA,RCB,RCC,RCD")
+ ENTRYX(82S16, TTL_82S16, "")
+ ENTRYX(82S115, PROM_82S115, "+CE1Q,+CE2,+A0,+A1,+A2,+A3,+A4,+A5,+A6,+A7,+A8,+STROBE")
+ ENTRYX(82S123, PROM_82S123, "+CEQ,+A0,+A1,+A2,+A3,+A4")
+ ENTRYX(82S126, PROM_82S126, "+CE1Q,+CE2Q,+A0,+A1,+A2,+A3,+A4,+A5,+A6,+A7")
+ ENTRYX(9310, TTL_9310, "")
+ ENTRYX(9312, TTL_9312, "+A,+B,+C,+D0,+D1,+D2,+D3,+D4,+D5,+D6,+D7,+G")
+ ENTRYX(9316, TTL_9316, "+CLK,+ENP,+ENT,+CLRQ,+LOADQ,+A,+B,+C,+D")
+ ENTRYX(9322, TTL_9322, "+SELECT,+A1,+B1,+A2,+B2,+A3,+B3,+A4,+B4,+STROBE")
+ ENTRYX(9334, TTL_9334, "+CQ,+EQ,+D,+A0,+A1,+A2")
+ ENTRYX(AM2847, TTL_AM2847, "+CP,+INA,+INB,+INC,+IND,+RCA,+RCB,+RCC,+RCD")
ENTRYX(CD4020, CD4020, "")
ENTRYX(CD4066_GATE, CD4066_GATE, "")
+ ENTRYX(CD4316_GATE, CD4316_GATE, "")
/* entries with suffix WI are legacy only */
- ENTRYX(CD4020, CD4020_WI, "+IP,RESET,VDD,VSS")
+ ENTRYX(CD4020, CD4020_WI, "+IP,+RESET,+VDD,+VSS")
//ENTRY(4066, CD_4066, "+A,B")
- ENTRYX(NE555, NE555, "-")
- ENTRYX(r2r_dac, R2R_DAC, "+VIN,R,N")
- ENTRYX(tristate, TTL_TRISTATE, "+CEQ1,D1,CEQ2,D2")
- ENTRYX(tristate3, TTL_TRISTATE3, "-")
- ENTRYX(2102A_dip, RAM_2102A_DIP, "-")
- ENTRYX(2716_dip, EPROM_2716_DIP, "-")
- ENTRYX(4538_dip, CD4538_DIP, "-")
- ENTRYX(7448_dip, TTL_7448_DIP, "-")
- ENTRYX(7450_dip, TTL_7450_DIP, "-")
- ENTRYX(7473_dip, TTL_7473_DIP, "-")
- ENTRYX(7473A_dip, TTL_7473A_DIP, "-")
- ENTRYX(7474_dip, TTL_7474_DIP, "-")
- ENTRYX(7475_dip, TTL_7475_DIP, "-")
- ENTRYX(7477_dip, TTL_7477_DIP, "-")
- ENTRYX(7483_dip, TTL_7483_DIP, "-")
- ENTRYX(7485_dip, TTL_7485_DIP, "-")
- ENTRYX(7490_dip, TTL_7490_DIP, "-")
- ENTRYX(7493_dip, TTL_7493_DIP, "-")
- ENTRYX(74107_dip, TTL_74107_DIP, "-")
- ENTRYX(74123_dip, TTL_74123_DIP, "-")
- ENTRYX(74153_dip, TTL_74153_DIP, "-")
- ENTRYX(74161_dip, TTL_74161_DIP, "-")
- ENTRYX(74165_dip, TTL_74165_DIP, "-")
- ENTRYX(74166_dip, TTL_74166_DIP, "-")
- ENTRYX(74174_dip, TTL_74174_DIP, "-")
- ENTRYX(74175_dip, TTL_74175_DIP, "-")
- ENTRYX(74192_dip, TTL_74192_DIP, "-")
- ENTRYX(74193_dip, TTL_74193_DIP, "-")
- ENTRYX(74194_dip, TTL_74194_DIP, "-")
- ENTRYX(74279_dip, TTL_74279_DIP, "-")
- ENTRYX(74365_dip, TTL_74365_DIP, "-")
- ENTRYX(82S16_dip, TTL_82S16_DIP, "-")
- ENTRYX(82S115_dip, PROM_82S115_DIP, "-")
- ENTRYX(82S123_dip, PROM_82S123_DIP, "-")
- ENTRYX(82S126_dip, PROM_82S126_DIP, "-")
- ENTRYX(9602_dip, TTL_9602_DIP, "-")
- ENTRYX(9310_dip, TTL_9310_DIP, "-")
- ENTRYX(9312_dip, TTL_9312_DIP, "-")
- ENTRYX(9316_dip, TTL_9316_DIP, "-")
- ENTRYX(9322_dip, TTL_9322_DIP, "-")
- ENTRYX(9334_dip, TTL_9334_DIP, "-")
- ENTRYX(AM2847_dip, TTL_AM2847_DIP, "-")
+ ENTRYX(NE555, NE555, "")
+ ENTRYX(r2r_dac, R2R_DAC, "VIN,R,N")
+ ENTRYX(tristate, TTL_TRISTATE, "+CEQ1,+D1,+CEQ2,+D2")
+ ENTRYX(tristate3, TTL_TRISTATE3, "")
+ ENTRYX(2102A_dip, RAM_2102A_DIP, "")
+ ENTRYX(2716_dip, EPROM_2716_DIP, "")
+ ENTRYX(4538_dip, CD4538_DIP, "")
+ ENTRYX(7448_dip, TTL_7448_DIP, "")
+ ENTRYX(7450_dip, TTL_7450_DIP, "")
+ ENTRYX(7473_dip, TTL_7473_DIP, "")
+ ENTRYX(7473A_dip, TTL_7473A_DIP, "")
+ ENTRYX(7474_dip, TTL_7474_DIP, "")
+ ENTRYX(7475_dip, TTL_7475_DIP, "")
+ ENTRYX(7477_dip, TTL_7477_DIP, "")
+ ENTRYX(7483_dip, TTL_7483_DIP, "")
+ ENTRYX(7485_dip, TTL_7485_DIP, "")
+ ENTRYX(7490_dip, TTL_7490_DIP, "")
+ ENTRYX(7493_dip, TTL_7493_DIP, "")
+ ENTRYX(74107_dip, TTL_74107_DIP, "")
+ ENTRYX(74123_dip, TTL_74123_DIP, "")
+ ENTRYX(74153_dip, TTL_74153_DIP, "")
+ ENTRYX(74161_dip, TTL_74161_DIP, "")
+ ENTRYX(74165_dip, TTL_74165_DIP, "")
+ ENTRYX(74166_dip, TTL_74166_DIP, "")
+ ENTRYX(74174_dip, TTL_74174_DIP, "")
+ ENTRYX(74175_dip, TTL_74175_DIP, "")
+ ENTRYX(74192_dip, TTL_74192_DIP, "")
+ ENTRYX(74193_dip, TTL_74193_DIP, "")
+ ENTRYX(74194_dip, TTL_74194_DIP, "")
+ ENTRYX(74279_dip, TTL_74279_DIP, "")
+ ENTRYX(74365_dip, TTL_74365_DIP, "")
+ ENTRYX(82S16_dip, TTL_82S16_DIP, "")
+ ENTRYX(82S115_dip, PROM_82S115_DIP, "")
+ ENTRYX(82S123_dip, PROM_82S123_DIP, "")
+ ENTRYX(82S126_dip, PROM_82S126_DIP, "")
+ ENTRYX(9602_dip, TTL_9602_DIP, "")
+ ENTRYX(9310_dip, TTL_9310_DIP, "")
+ ENTRYX(9312_dip, TTL_9312_DIP, "")
+ ENTRYX(9316_dip, TTL_9316_DIP, "")
+ ENTRYX(9322_dip, TTL_9322_DIP, "")
+ ENTRYX(9334_dip, TTL_9334_DIP, "")
+ ENTRYX(AM2847_dip, TTL_AM2847_DIP, "")
ENTRYX(SN74LS629_dip, SN74LS629_DIP, "1.CAP1,2.CAP2")
- ENTRYX(NE555_dip, NE555_DIP, "-")
- ENTRYX(MM5837_dip, MM5837_DIP, "-")
+ ENTRYX(NE555_dip, NE555_DIP, "")
+ ENTRYX(MM5837_dip, MM5837_DIP, "")
}
} //namespace devices
@@ -203,7 +204,7 @@ static void initialize_factory(factory_list_t &factory)
namespace netlist
{
- void initialize_factory(factory_list_t &factory)
+ void initialize_factory(factory::list_t &factory)
{
devices::initialize_factory(factory);
}
diff --git a/src/lib/netlist/devices/net_lib.h b/src/lib/netlist/devices/net_lib.h
index c9c0b6b3917..585df6aa369 100644
--- a/src/lib/netlist/devices/net_lib.h
+++ b/src/lib/netlist/devices/net_lib.h
@@ -81,7 +81,7 @@ NETLIST_EXTERNAL(bjt_models)
NETLIST_EXTERNAL(family_models)
namespace netlist {
- void initialize_factory(netlist::factory_list_t &factory);
+ void initialize_factory(factory::list_t &factory);
}
#endif
diff --git a/src/lib/netlist/devices/nld_7448.cpp b/src/lib/netlist/devices/nld_7448.cpp
index 56b322dbc2f..8b4d11c374b 100644
--- a/src/lib/netlist/devices/nld_7448.cpp
+++ b/src/lib/netlist/devices/nld_7448.cpp
@@ -62,7 +62,7 @@ namespace netlist
register_subalias("2", m_C);
register_subalias("3", m_LTQ);
register_subalias("4", m_BIQ);
- register_subalias("5",m_RBIQ);
+ register_subalias("5", m_RBIQ);
register_subalias("6", m_D);
register_subalias("7", m_A);
diff --git a/src/lib/netlist/devices/nld_7485.cpp b/src/lib/netlist/devices/nld_7485.cpp
index ba51756cac1..9012b8064c3 100644
--- a/src/lib/netlist/devices/nld_7485.cpp
+++ b/src/lib/netlist/devices/nld_7485.cpp
@@ -73,7 +73,7 @@ namespace netlist
// FIXME: Timing
NETLIB_UPDATE(7485)
{
- for (std::int_fast32_t i = 3; i >= 0; i--)
+ for (std::size_t i = 3; i-- > 0; )
{
if (m_A[i]() > m_B[i]())
{
diff --git a/src/lib/netlist/devices/nld_7493.cpp b/src/lib/netlist/devices/nld_7493.cpp
index 6e96facabae..a87aada2cd6 100644
--- a/src/lib/netlist/devices/nld_7493.cpp
+++ b/src/lib/netlist/devices/nld_7493.cpp
@@ -71,7 +71,7 @@ namespace netlist
{
NETLIB_CONSTRUCTOR_DERIVED(7493_dip, 7493)
{
- register_subalias("1", B.m_I);
+ register_subalias("1", "CLKB");
register_subalias("2", m_R1);
register_subalias("3", m_R2);
@@ -80,13 +80,13 @@ namespace netlist
// register_subalias("6", ); --> NC
// register_subalias("7", ); --> NC
- register_subalias("8", C.m_Q);
- register_subalias("9", B.m_Q);
+ register_subalias("8", "QC");
+ register_subalias("9", "QB");
// register_subalias("10", ); -. GND
- register_subalias("11", D.m_Q);
- register_subalias("12", A.m_Q);
+ register_subalias("11", "QD");
+ register_subalias("12", "QA");
// register_subalias("13", ); -. NC
- register_subalias("14", A.m_I);
+ register_subalias("14", "CLKA");
}
};
diff --git a/src/lib/netlist/devices/nld_dm9334.cpp b/src/lib/netlist/devices/nld_dm9334.cpp
index c65a05d2014..091f08f00a8 100644
--- a/src/lib/netlist/devices/nld_dm9334.cpp
+++ b/src/lib/netlist/devices/nld_dm9334.cpp
@@ -113,7 +113,7 @@ namespace netlist
}
}
- uint_fast8_t q = m_last_Q;
+ unsigned q = m_last_Q;
if (!m_CQ())
{
diff --git a/src/lib/netlist/devices/nld_mm5837.cpp b/src/lib/netlist/devices/nld_mm5837.cpp
index 41d2fea9e34..a6146b7cf00 100644
--- a/src/lib/netlist/devices/nld_mm5837.cpp
+++ b/src/lib/netlist/devices/nld_mm5837.cpp
@@ -19,15 +19,15 @@ namespace netlist
NETLIB_OBJECT(MM5837_dip)
{
NETLIB_CONSTRUCTOR(MM5837_dip)
- , m_RV(*this, "RV")
+ , m_RV(*this, "_RV")
, m_VDD(*this, "1")
, m_VGG(*this, "2")
, m_VSS(*this, "4")
- , m_V0(*this, "_Q")
+ , m_FREQ(*this, "FREQ", 24000)
/* clock */
- , m_feedback(*this, "FB")
- , m_Q(*this, "Q")
- , m_inc(netlist_time::from_hz(56000))
+ , m_feedback(*this, "_FB")
+ , m_Q(*this, "_Q")
+ , m_inc(netlist_time::from_hz(24000))
, m_shift(*this, "m_shift", 0)
, m_is_timestep(false)
{
@@ -36,7 +36,7 @@ namespace netlist
/* output */
//register_term("_RV1", m_RV.m_P);
//register_term("_RV2", m_RV.m_N);
- connect_late(m_RV.m_N, m_V0);
+ connect_late(m_RV.m_N, m_VDD);
/* device */
register_subalias("3", m_RV.m_P);
@@ -44,20 +44,19 @@ namespace netlist
NETLIB_RESETI();
NETLIB_UPDATEI();
+ NETLIB_UPDATE_PARAMI();
protected:
NETLIB_SUB(twoterm) m_RV;
analog_input_t m_VDD;
analog_input_t m_VGG;
analog_input_t m_VSS;
-
- /* output stage */
- analog_output_t m_V0; /* could be gnd as well */
+ param_double_t m_FREQ;
/* clock stage */
logic_input_t m_feedback;
logic_output_t m_Q;
- const netlist_time m_inc;
+ netlist_time m_inc;
/* state */
state_var_u32 m_shift;
@@ -71,14 +70,24 @@ namespace netlist
//m_V0.initial(0.0);
//m_RV.do_reset();
m_RV.set(NL_FCONST(1.0) / R_LOW, 0.0, 0.0);
+ m_inc = netlist_time::from_double(1.0 / m_FREQ());
+ if (m_FREQ() < 24000 || m_FREQ() > 56000)
+ netlist().log().warning("MM5837: Frequency outside of specs.", m_FREQ());
m_shift = 0x1ffff;
m_is_timestep = m_RV.m_P.net().solver()->is_timestep();
}
+ NETLIB_UPDATE_PARAM(MM5837_dip)
+ {
+ m_inc = netlist_time::from_double(1.0 / m_FREQ());
+ if (m_FREQ() < 24000 || m_FREQ() > 56000)
+ netlist().log().warning("MM5837: Frequency outside of specs.", m_FREQ());
+ }
+
NETLIB_UPDATE(MM5837_dip)
{
- m_Q.push(!m_Q.net().new_Q(), m_inc);
+ m_Q.push(!m_feedback.Q(), m_inc);
/* shift register
*
diff --git a/src/lib/netlist/devices/nld_truthtable.h b/src/lib/netlist/devices/nld_truthtable.h
index 6fcd746578f..564699cd89b 100644
--- a/src/lib/netlist/devices/nld_truthtable.h
+++ b/src/lib/netlist/devices/nld_truthtable.h
@@ -235,7 +235,7 @@ namespace netlist
desc.setup(m_desc, disabled_ignore * 0);
#if 0
- printf("%s\n", name().cstr());
+ printf("%s\n", name().c_str());
for (int j=0; j < m_size; j++)
printf("%05x %04x %04x %04x\n", j, m_ttp->m_outs[j] & ((1 << m_NO)-1),
m_ttp->m_outs[j] >> m_NO, m_ttp->m_timing[j * m_NO + 0]);
@@ -261,7 +261,7 @@ namespace netlist
}
public:
- void inc_active() noexcept override
+ void inc_active() NL_NOEXCEPT override
{
if (m_NI > 1)
if (++m_active == 1)
@@ -270,7 +270,7 @@ namespace netlist
}
}
- void dec_active() noexcept override
+ void dec_active() NL_NOEXCEPT override
{
/* FIXME:
* Based on current measurements there is no point to disable
@@ -366,13 +366,13 @@ namespace netlist
plib::pstring_vector_t m_desc;
};
- class netlist_base_factory_truthtable_t : public base_factory_t
+ class netlist_base_factory_truthtable_t : public factory::element_t
{
P_PREVENT_COPYING(netlist_base_factory_truthtable_t)
public:
netlist_base_factory_truthtable_t(const pstring &name, const pstring &classname,
const pstring &def_param)
- : base_factory_t(name, classname, def_param), m_family(family_TTL())
+ : factory::element_t(name, classname, def_param), m_family(family_TTL())
{}
virtual ~netlist_base_factory_truthtable_t()
diff --git a/src/lib/netlist/devices/nlid_proxy.cpp b/src/lib/netlist/devices/nlid_proxy.cpp
index 6ecad8656a2..6b6da2176cf 100644
--- a/src/lib/netlist/devices/nlid_proxy.cpp
+++ b/src/lib/netlist/devices/nlid_proxy.cpp
@@ -17,10 +17,82 @@ namespace netlist
namespace devices
{
+ // -----------------------------------------------------------------------------
+ // nld_base_proxy
+ // -----------------------------------------------------------------------------
+
+ nld_base_proxy::nld_base_proxy(netlist_t &anetlist, const pstring &name,
+ logic_t *inout_proxied, detail::core_terminal_t *proxy_inout)
+ : device_t(anetlist, name)
+ {
+ m_logic_family = inout_proxied->logic_family();
+ m_term_proxied = inout_proxied;
+ m_proxy_term = proxy_inout;
+ }
+
+ nld_base_proxy::~nld_base_proxy()
+ {
+ }
+
+ // ----------------------------------------------------------------------------------------
+ // nld_a_to_d_proxy
+ // ----------------------------------------------------------------------------------------
+
+ nld_base_a_to_d_proxy::nld_base_a_to_d_proxy(netlist_t &anetlist, const pstring &name,
+ logic_input_t *in_proxied, detail::core_terminal_t *in_proxy)
+ : nld_base_proxy(anetlist, name, in_proxied, in_proxy)
+ , m_Q(*this, "Q")
+ {
+ }
+
+ nld_base_a_to_d_proxy::~nld_base_a_to_d_proxy() {}
+
+ nld_a_to_d_proxy::nld_a_to_d_proxy(netlist_t &anetlist, const pstring &name, logic_input_t *in_proxied)
+ : nld_base_a_to_d_proxy(anetlist, name, in_proxied, &m_I)
+ , m_I(*this, "I")
+ {
+ }
+
+ nld_a_to_d_proxy::~nld_a_to_d_proxy()
+ {
+ }
+
+ NETLIB_RESET(a_to_d_proxy)
+ {
+ }
+
+ NETLIB_UPDATE(a_to_d_proxy)
+ {
+ nl_assert(m_logic_family != nullptr);
+ // FIXME: Variable supply voltage!
+ double supply_V = logic_family().fixed_V();
+ if (supply_V == 0.0) supply_V = 5.0;
+
+ if (m_I.Q_Analog() > logic_family().high_thresh_V(0.0, supply_V))
+ out().push(1, NLTIME_FROM_NS(1));
+ else if (m_I.Q_Analog() < logic_family().low_thresh_V(0.0, supply_V))
+ out().push(0, NLTIME_FROM_NS(1));
+ else
+ {
+ // do nothing
+ }
+ }
+
// ----------------------------------------------------------------------------------------
// nld_d_to_a_proxy
// ----------------------------------------------------------------------------------------
+ nld_base_d_to_a_proxy::nld_base_d_to_a_proxy(netlist_t &anetlist, const pstring &name,
+ logic_output_t *out_proxied, detail::core_terminal_t &proxy_out)
+ : nld_base_proxy(anetlist, name, out_proxied, &proxy_out)
+ , m_I(*this, "I")
+ {
+ }
+
+ nld_base_d_to_a_proxy::~nld_base_d_to_a_proxy()
+ {
+ }
+
nld_d_to_a_proxy::nld_d_to_a_proxy(netlist_t &anetlist, const pstring &name, logic_output_t *out_proxied)
: nld_base_d_to_a_proxy(anetlist, name, out_proxied, m_RV.m_P)
, m_GNDHack(*this, "_Q")
@@ -53,9 +125,9 @@ namespace netlist
else
netlist().log().warning("D/A Proxy: Found power terminals on device {1}", out_proxied->device().name());
#if (0)
- printf("%s %s\n", out_proxied->name().cstr(), out_proxied->device().name().cstr());
+ printf("%s %s\n", out_proxied->name().c_str(), out_proxied->device().name().c_str());
auto x = netlist().setup().find_terminal(out_proxied->name(), detail::device_object_t::type_t::OUTPUT, false);
- if (x) printf("==> %s\n", x->name().cstr());
+ if (x) printf("==> %s\n", x->name().c_str());
#endif
}
diff --git a/src/lib/netlist/devices/nlid_proxy.h b/src/lib/netlist/devices/nlid_proxy.h
index bcda8fa4e2a..eced07f8356 100644
--- a/src/lib/netlist/devices/nlid_proxy.h
+++ b/src/lib/netlist/devices/nlid_proxy.h
@@ -31,15 +31,9 @@ namespace netlist
{
public:
nld_base_proxy(netlist_t &anetlist, const pstring &name,
- logic_t *inout_proxied, detail::core_terminal_t *proxy_inout)
- : device_t(anetlist, name)
- {
- m_logic_family = inout_proxied->logic_family();
- m_term_proxied = inout_proxied;
- m_proxy_term = proxy_inout;
- }
+ logic_t *inout_proxied, detail::core_terminal_t *proxy_inout);
- virtual ~nld_base_proxy() {}
+ virtual ~nld_base_proxy();
logic_t &term_proxied() const { return *m_term_proxied; }
detail::core_terminal_t &proxy_term() const { return *m_proxy_term; }
@@ -61,41 +55,39 @@ namespace netlist
// nld_a_to_d_proxy
// -----------------------------------------------------------------------------
- NETLIB_OBJECT_DERIVED(a_to_d_proxy, base_proxy)
+ NETLIB_OBJECT_DERIVED(base_a_to_d_proxy, base_proxy)
{
public:
- nld_a_to_d_proxy(netlist_t &anetlist, const pstring &name, logic_input_t *in_proxied)
- : nld_base_proxy(anetlist, name, in_proxied, &m_I)
- , m_I(*this, "I")
- , m_Q(*this, "Q")
- {
- }
- virtual ~nld_a_to_d_proxy() {}
+ virtual ~nld_base_a_to_d_proxy();
+
+ virtual logic_output_t &out() { return m_Q; }
+
+ protected:
+
+ nld_base_a_to_d_proxy(netlist_t &anetlist, const pstring &name,
+ logic_input_t *in_proxied, detail::core_terminal_t *in_proxy);
+
+ private:
- analog_input_t m_I;
logic_output_t m_Q;
+ };
+
+ NETLIB_OBJECT_DERIVED(a_to_d_proxy, base_a_to_d_proxy)
+ {
+ public:
+ nld_a_to_d_proxy(netlist_t &anetlist, const pstring &name, logic_input_t *in_proxied);
+
+ virtual ~nld_a_to_d_proxy();
+
+ analog_input_t m_I;
+
protected:
- NETLIB_RESETI() { }
+ NETLIB_RESETI();
+ NETLIB_UPDATEI();
- NETLIB_UPDATEI()
- {
- nl_assert(m_logic_family != nullptr);
- // FIXME: Variable supply voltage!
- double supply_V = logic_family().fixed_V();
- if (supply_V == 0.0) supply_V = 5.0;
-
- if (m_I.Q_Analog() > logic_family().high_thresh_V(0.0, supply_V))
- m_Q.push(1, NLTIME_FROM_NS(1));
- else if (m_I.Q_Analog() < logic_family().low_thresh_V(0.0, supply_V))
- m_Q.push(0, NLTIME_FROM_NS(1));
- else
- {
- // do nothing
- }
- }
private:
};
@@ -106,17 +98,13 @@ namespace netlist
NETLIB_OBJECT_DERIVED(base_d_to_a_proxy, base_proxy)
{
public:
- virtual ~nld_base_d_to_a_proxy() {}
+ virtual ~nld_base_d_to_a_proxy();
virtual logic_input_t &in() { return m_I; }
protected:
nld_base_d_to_a_proxy(netlist_t &anetlist, const pstring &name,
- logic_output_t *out_proxied, detail::core_terminal_t &proxy_out)
- : nld_base_proxy(anetlist, name, out_proxied, &proxy_out)
- , m_I(*this, "I")
- {
- }
+ logic_output_t *out_proxied, detail::core_terminal_t &proxy_out);
logic_input_t m_I;
@@ -141,43 +129,6 @@ namespace netlist
bool m_is_timestep;
};
-
- class factory_lib_entry_t : public base_factory_t
- {
- P_PREVENT_COPYING(factory_lib_entry_t)
- public:
-
- factory_lib_entry_t(setup_t &setup, const pstring &name, const pstring &classname,
- const pstring &def_param)
- : base_factory_t(name, classname, def_param), m_setup(setup) { }
-
- class wrapper : public device_t
- {
- public:
- wrapper(const pstring &devname, netlist_t &anetlist, const pstring &name)
- : device_t(anetlist, name), m_devname(devname)
- {
- anetlist.setup().namespace_push(name);
- anetlist.setup().include(m_devname);
- anetlist.setup().namespace_pop();
- }
- protected:
- NETLIB_RESETI() { }
- NETLIB_UPDATEI() { }
-
- pstring m_devname;
- };
-
- plib::owned_ptr<device_t> Create(netlist_t &anetlist, const pstring &name) override
- {
- return plib::owned_ptr<device_t>::Create<wrapper>(this->name(), anetlist, name);
- }
-
- private:
- setup_t &m_setup;
- };
-
-
} //namespace devices
} // namespace netlist
diff --git a/src/lib/netlist/macro/nlm_cd4xxx.cpp b/src/lib/netlist/macro/nlm_cd4xxx.cpp
index d169e2790f5..469ff13b954 100644
--- a/src/lib/netlist/macro/nlm_cd4xxx.cpp
+++ b/src/lib/netlist/macro/nlm_cd4xxx.cpp
@@ -33,13 +33,13 @@ static NETLIST_START(CD4001_DIP)
DUMMY_INPUT(VDD)
DIPPINS( /* +--------------+ */
- s1.A, /* A1 |1 ++ 14| VCC */ VSS.I,
+ s1.A, /* A1 |1 ++ 14| VCC */ VDD.I,
s1.B, /* B1 |2 13| A6 */ s4.B,
s1.Q, /* A2 |3 12| Y6 */ s4.A,
s2.Q, /* Y2 |4 4001 11| A5 */ s4.Q,
s2.A, /* A3 |5 10| Y5 */ s3.Q,
s2.B, /* Y3 |6 9| A4 */ s3.B,
- VDD.I, /* GND |7 8| Y4 */ s3.A
+ VSS.I, /* GND |7 8| Y4 */ s3.A
/* +--------------+ */
)
diff --git a/src/lib/netlist/macro/nlm_opamp.cpp b/src/lib/netlist/macro/nlm_opamp.cpp
index 08dc5f60b27..146f95b72b4 100644
--- a/src/lib/netlist/macro/nlm_opamp.cpp
+++ b/src/lib/netlist/macro/nlm_opamp.cpp
@@ -52,7 +52,7 @@ static NETLIST_START(opamp_layout_2_13_9_4)
A.GND, /* |4 11| */ NC,
B.N1, /* |5 10| */ B.OUT,
B.PLUS, /* |6 9| */ B.VCC,
- B.MINUS /* |7 8| */ B.N2
+ B.MINUS, /* |7 8| */ B.N2
/* +--------------+ */
)
NET_C(A.GND, B.GND)
@@ -186,6 +186,37 @@ static NETLIST_START(LM747A_DIP)
NETLIST_END()
+static NETLIST_START(LM3900)
+
+ /*
+ * Fast norton opamp model without bandwidth
+ */
+
+ /* Terminal definitions for calling netlists */
+
+ ALIAS(PLUS, R1.1) // Positive input
+ ALIAS(MINUS, R2.1) // Negative input
+ ALIAS(OUT, G1.OP) // Opamp output ...
+ ALIAS(VM, G1.ON) // V- terminal
+ ALIAS(VP, DUMMY.I) // V+ terminal
+
+ DUMMY_INPUT(DUMMY)
+
+ /* The opamp model */
+
+ RES(R1, 1)
+ RES(R2, 1)
+ NET_C(R1.1, G1.IP)
+ NET_C(R2.1, G1.IN)
+ NET_C(R1.2, R2.2, G1.ON)
+ VCVS(G1)
+ PARAM(G1.G, 10000000)
+ //PARAM(G1.RI, 1)
+ PARAM(G1.RO, RES_K(8))
+
+NETLIST_END()
+
+
NETLIST_START(OPAMP_lib)
LOCAL_LIB_ENTRY(opamp_layout_4_4_11)
LOCAL_LIB_ENTRY(opamp_layout_2_8_4)
@@ -209,5 +240,6 @@ NETLIST_START(OPAMP_lib)
LOCAL_LIB_ENTRY(UA741_DIP14)
LOCAL_LIB_ENTRY(LM747_DIP)
LOCAL_LIB_ENTRY(LM747A_DIP)
+ LOCAL_LIB_ENTRY(LM3900)
NETLIST_END()
diff --git a/src/lib/netlist/macro/nlm_opamp.h b/src/lib/netlist/macro/nlm_opamp.h
index f349f11911c..6e3c1f615e7 100644
--- a/src/lib/netlist/macro/nlm_opamp.h
+++ b/src/lib/netlist/macro/nlm_opamp.h
@@ -20,6 +20,9 @@
#define LM358_DIP(name) \
NET_REGISTER_DEV(LM358_DIP, name)
+#define LM3900(name) \
+ NET_REGISTER_DEV(LM3900, name)
+
/* ----------------------------------------------------------------------------
* External declarations
* ---------------------------------------------------------------------------*/
diff --git a/src/lib/netlist/macro/nlm_ttl74xx.cpp b/src/lib/netlist/macro/nlm_ttl74xx.cpp
index 2120d88eb3f..c66314366d2 100644
--- a/src/lib/netlist/macro/nlm_ttl74xx.cpp
+++ b/src/lib/netlist/macro/nlm_ttl74xx.cpp
@@ -588,7 +588,7 @@ NETLIST_START(TTL74XX_lib)
TT_FAMILY("74XX")
TRUTHTABLE_END()
- TRUTHTABLE_START(TTL_7400_NAND, 2, 1, "A,B")
+ TRUTHTABLE_START(TTL_7400_NAND, 2, 1, "+A,+B")
TT_HEAD("A,B|Q ")
TT_LINE("0,X|1|22")
TT_LINE("X,0|1|22")
@@ -604,7 +604,7 @@ NETLIST_START(TTL74XX_lib)
TT_FAMILY("74XX")
TRUTHTABLE_END()
- TRUTHTABLE_START(TTL_7402_NOR, 2, 1, "A,B")
+ TRUTHTABLE_START(TTL_7402_NOR, 2, 1, "+A,+B")
TT_HEAD("A,B|Q ")
TT_LINE("0,0|1|22")
TT_LINE("X,1|0|15")
@@ -619,7 +619,7 @@ NETLIST_START(TTL74XX_lib)
TT_FAMILY("74XX")
TRUTHTABLE_END()
- TRUTHTABLE_START(TTL_7404_INVERT, 1, 1, "A")
+ TRUTHTABLE_START(TTL_7404_INVERT, 1, 1, "+A")
TT_HEAD(" A | Q ")
TT_LINE(" 0 | 1 |22")
TT_LINE(" 1 | 0 |15")
@@ -634,7 +634,7 @@ NETLIST_START(TTL74XX_lib)
TT_FAMILY("74XX")
TRUTHTABLE_END()
- TRUTHTABLE_START(TTL_7408_AND, 2, 1, "A,B")
+ TRUTHTABLE_START(TTL_7408_AND, 2, 1, "+A,+B")
TT_HEAD("A,B|Q ")
TT_LINE("0,X|0|15")
TT_LINE("X,0|0|15")
@@ -642,7 +642,7 @@ NETLIST_START(TTL74XX_lib)
TT_FAMILY("74XX")
TRUTHTABLE_END()
- TRUTHTABLE_START(TTL_7410_NAND, 3, 1, "A,B,C")
+ TRUTHTABLE_START(TTL_7410_NAND, 3, 1, "+A,+B,+C")
TT_HEAD("A,B,C|Q ")
TT_LINE("0,X,X|1|22")
TT_LINE("X,0,X|1|22")
@@ -660,7 +660,7 @@ NETLIST_START(TTL74XX_lib)
TT_FAMILY("74XX")
TRUTHTABLE_END()
- TRUTHTABLE_START(TTL_7411_AND, 3, 1, "A,B,C")
+ TRUTHTABLE_START(TTL_7411_AND, 3, 1, "+A,+B,+C")
TT_HEAD("A,B,C|Q ")
TT_LINE("0,X,X|0|15")
TT_LINE("X,0,X|0|15")
@@ -696,7 +696,7 @@ NETLIST_START(TTL74XX_lib)
TT_FAMILY("74XX")
TRUTHTABLE_END()
- TRUTHTABLE_START(TTL_7420_NAND, 4, 1, "A,B,C,D")
+ TRUTHTABLE_START(TTL_7420_NAND, 4, 1, "+A,+B,+C,+D")
TT_HEAD("A,B,C,D|Q ")
TT_LINE("0,X,X,X|1|22")
TT_LINE("X,0,X,X|1|22")
@@ -716,7 +716,7 @@ NETLIST_START(TTL74XX_lib)
TT_FAMILY("74XX")
TRUTHTABLE_END()
- TRUTHTABLE_START(TTL_7425_NOR, 4, 1, "A,B,C,D")
+ TRUTHTABLE_START(TTL_7425_NOR, 4, 1, "+A,+B,+C,+D")
TT_HEAD("A,B,C,D|Q ")
TT_LINE("1,X,X,X|0|15")
TT_LINE("X,1,X,X|0|15")
@@ -735,7 +735,7 @@ NETLIST_START(TTL74XX_lib)
TT_FAMILY("74XX")
TRUTHTABLE_END()
- TRUTHTABLE_START(TTL_7427_NOR, 3, 1, "A,B,C")
+ TRUTHTABLE_START(TTL_7427_NOR, 3, 1, "+A,+B,+C")
TT_HEAD("A,B,C|Q ")
TT_LINE("1,X,X|0|15")
TT_LINE("X,1,X|0|15")
@@ -758,7 +758,7 @@ NETLIST_START(TTL74XX_lib)
TT_FAMILY("74XX")
TRUTHTABLE_END()
- TRUTHTABLE_START(TTL_7430_NAND, 8, 1, "A,B,C,D,E,F,G,H")
+ TRUTHTABLE_START(TTL_7430_NAND, 8, 1, "+A,+B,+C,+D,+E,+F,+G,+H")
TT_HEAD("A,B,C,D,E,F,G,H|Q ")
TT_LINE("0,X,X,X,X,X,X,X|1|22")
TT_LINE("X,0,X,X,X,X,X,X|1|22")
@@ -780,7 +780,7 @@ NETLIST_START(TTL74XX_lib)
TT_FAMILY("74XX")
TRUTHTABLE_END()
- TRUTHTABLE_START(TTL_7432_OR, 2, 1, "A,B")
+ TRUTHTABLE_START(TTL_7432_OR, 2, 1, "+A,+B")
TT_HEAD("A,B|Q ")
TT_LINE("1,X|1|22")
TT_LINE("X,1|1|22")
@@ -800,7 +800,7 @@ NETLIST_START(TTL74XX_lib)
TT_FAMILY("74XX")
TRUTHTABLE_END()
- TRUTHTABLE_START(TTL_7437_NAND, 2, 1, "A,B")
+ TRUTHTABLE_START(TTL_7437_NAND, 2, 1, "+A,+B")
TT_HEAD("A,B|Q ")
TT_LINE("0,X|1|22")
TT_LINE("X,0|1|22")
@@ -817,7 +817,7 @@ NETLIST_START(TTL74XX_lib)
TT_FAMILY("74XX")
TRUTHTABLE_END()
- TRUTHTABLE_START(TTL_7486_XOR, 2, 1, "A,B")
+ TRUTHTABLE_START(TTL_7486_XOR, 2, 1, "+A,+B")
TT_HEAD("A,B|Q ")
TT_LINE("0,0|0|15")
TT_LINE("0,1|1|22")
@@ -837,7 +837,7 @@ NETLIST_START(TTL74XX_lib)
TT_FAMILY("74XX")
TRUTHTABLE_END()
- TRUTHTABLE_START(TTL_74260_NOR, 5, 1, "A,B,C,D,E")
+ TRUTHTABLE_START(TTL_74260_NOR, 5, 1, "+A,+B,+C,+D,+E")
TT_HEAD("A,B,C,D,E|Q ")
TT_LINE("0,0,0,0,0|1|10")
TT_LINE("X,X,X,X,1|0|12")
diff --git a/src/lib/netlist/nl_base.cpp b/src/lib/netlist/nl_base.cpp
index 76ce59db5ac..ab643f1ee87 100644
--- a/src/lib/netlist/nl_base.cpp
+++ b/src/lib/netlist/nl_base.cpp
@@ -49,10 +49,24 @@ void object_t::operator delete (void * mem)
}
+nl_exception::~nl_exception()
+{
+}
+
+
// ----------------------------------------------------------------------------------------
// logic_family_ttl_t
// ----------------------------------------------------------------------------------------
+logic_family_desc_t::logic_family_desc_t()
+{
+}
+
+logic_family_desc_t::~logic_family_desc_t()
+{
+}
+
+
class logic_family_ttl_t : public logic_family_desc_t
{
public:
@@ -71,6 +85,10 @@ public:
{
return plib::owned_ptr<devices::nld_base_d_to_a_proxy>::Create<devices::nld_d_to_a_proxy>(anetlist, name, proxied);
}
+ virtual plib::owned_ptr<devices::nld_base_a_to_d_proxy> create_a_d_proxy(netlist_t &anetlist, const pstring &name, logic_input_t *proxied) const override
+ {
+ return plib::owned_ptr<devices::nld_base_a_to_d_proxy>::Create<devices::nld_a_to_d_proxy>(anetlist, name, proxied);
+ }
};
class logic_family_cd4xxx_t : public logic_family_desc_t
@@ -91,6 +109,10 @@ public:
{
return plib::owned_ptr<devices::nld_base_d_to_a_proxy>::Create<devices::nld_d_to_a_proxy>(anetlist, name, proxied);
}
+ virtual plib::owned_ptr<devices::nld_base_a_to_d_proxy> create_a_d_proxy(netlist_t &anetlist, const pstring &name, logic_input_t *proxied) const override
+ {
+ return plib::owned_ptr<devices::nld_base_a_to_d_proxy>::Create<devices::nld_a_to_d_proxy>(anetlist, name, proxied);
+ }
};
const logic_family_desc_t *family_TTL()
@@ -138,7 +160,7 @@ void detail::queue_t::on_pre_save()
pstring p = this->listptr()[i].m_object->name();
std::size_t n = p.len();
if (n > 63) n = 63;
- std::strncpy(m_names[i].m_buf, p.cstr(), n);
+ std::strncpy(m_names[i].m_buf, p.c_str(), n);
m_names[i].m_buf[n] = 0;
}
}
@@ -722,8 +744,12 @@ void detail::net_t::reset()
m_active++;
}
-void detail::net_t::register_con(detail::core_terminal_t &terminal)
+void detail::net_t::add_terminal(detail::core_terminal_t &terminal)
{
+ for (auto t : m_core_terms)
+ if (t == &terminal)
+ netlist().log().fatal("net {1}: duplicate terminal {2}", name(), t->name());
+
terminal.set_net(this);
m_core_terms.push_back(&terminal);
@@ -735,7 +761,7 @@ void detail::net_t::register_con(detail::core_terminal_t &terminal)
void detail::net_t::move_connections(detail::net_t &dest_net)
{
for (auto &ct : m_core_terms)
- dest_net.register_con(*ct);
+ dest_net.add_terminal(*ct);
m_core_terms.clear();
m_active = 0;
}
@@ -749,6 +775,9 @@ logic_net_t::logic_net_t(netlist_t &nl, const pstring &aname, detail::core_termi
{
}
+logic_net_t::~logic_net_t()
+{
+}
// ----------------------------------------------------------------------------------------
// analog_net_t
@@ -760,6 +789,10 @@ analog_net_t::analog_net_t(netlist_t &nl, const pstring &aname, detail::core_ter
{
}
+analog_net_t::~analog_net_t()
+{
+}
+
// ----------------------------------------------------------------------------------------
// core_terminal_t
// ----------------------------------------------------------------------------------------
@@ -773,6 +806,10 @@ detail::core_terminal_t::core_terminal_t(core_device_t &dev, const pstring &anam
{
}
+detail::core_terminal_t::~core_terminal_t()
+{
+}
+
void detail::core_terminal_t::reset()
{
if (is_type(OUTPUT))
@@ -791,6 +828,13 @@ void detail::core_terminal_t::set_net(net_t *anet)
m_net = nullptr;
}
+analog_t::~analog_t()
+{
+}
+
+logic_t::~logic_t()
+{
+}
// ----------------------------------------------------------------------------------------
// terminal_t
@@ -842,6 +886,11 @@ logic_output_t::logic_output_t(core_device_t &dev, const pstring &aname)
netlist().setup().register_term(*this);
}
+logic_output_t::~logic_output_t()
+{
+}
+
+
void logic_output_t::initial(const netlist_sig_t val)
{
net().initial(val);
@@ -871,6 +920,10 @@ analog_output_t::analog_output_t(core_device_t &dev, const pstring &aname)
netlist().setup().register_term(*this);
}
+analog_output_t::~analog_output_t()
+{
+}
+
void analog_output_t::initial(const nl_double val)
{
net().m_cur_Analog = val;
@@ -887,6 +940,10 @@ logic_input_t::logic_input_t(core_device_t &dev, const pstring &aname)
netlist().setup().register_term(*this);
}
+logic_input_t::~logic_input_t()
+{
+}
+
// ----------------------------------------------------------------------------------------
// Parameters ...
// ----------------------------------------------------------------------------------------
@@ -898,6 +955,10 @@ param_t::param_t(const param_type_t atype, device_t &device, const pstring &name
device.setup().register_param(this->name(), *this);
}
+param_t::~param_t()
+{
+}
+
void param_t::update_param()
{
device().update_param();
@@ -946,6 +1007,15 @@ param_ptr_t::param_ptr_t(device_t &device, const pstring name, uint8_t * val)
//netlist().save(*this, m_param, "m_param");
}
+void param_str_t::changed()
+{
+}
+
+void param_model_t::changed()
+{
+ m_map.clear();
+}
+
const pstring param_model_t::model_value_str(const pstring &entity)
{
if (m_map.size() == 0)
@@ -960,6 +1030,10 @@ nl_double param_model_t::model_value(const pstring &entity)
return netlist().setup().model_value(m_map, entity);
}
+void param_data_t::changed()
+{
+}
+
std::unique_ptr<plib::pistream> param_data_t::stream()
{
return device().netlist().setup().get_data_stream(Value());
diff --git a/src/lib/netlist/nl_base.h b/src/lib/netlist/nl_base.h
index f72665c62bc..e85a891aaaf 100644
--- a/src/lib/netlist/nl_base.h
+++ b/src/lib/netlist/nl_base.h
@@ -22,6 +22,7 @@
#include "plib/pstate.h"
#include "plib/pfmtlog.h"
#include "plib/pstream.h"
+#include "plib/pexception.h"
// ----------------------------------------------------------------------------------------
// Type definitions
@@ -88,29 +89,35 @@ class NETLIB_NAME(name) : public device_t
* dynamic device, i.e. #NETLIB_UPDATE_TERMINALSI is called on a each step
* of the Newton-Raphson step of solving the linear equations.
*/
-#define NETLIB_DYNAMIC() \
+#define NETLIB_IS_DYNAMIC() \
public: virtual bool is_dynamic() const override { return true; }
- /*! Add this to a device definition to mark the device as a time-stepping device
- * and add code.
- * If this is added to device definition the device is treated as an analog
- * time-stepping device. Currently, only the capacitor device uses this. An other
- * example would be an inductor device.
- *
- * Example:
- *
- * NETLIB_TIMESTEP()
- * {
- * // Gpar should support convergence
- * const nl_double G = m_C.Value() / step + m_GParallel;
- * const nl_double I = -G * deltaV();
- * set(G, 0.0, I);
- * }
- *
- */
-#define NETLIB_TIMESTEP() \
- public: virtual bool is_timestep() const override { return true; } \
- public: virtual void step_time(const nl_double step) override
+ /*! Add this to a device definition to mark the device as a time-stepping device.
+ *
+ * You have to implement NETLIB_TIMESTEP in this case as well. Currently, only
+ * the capacitor and inductor devices uses this.
+ *
+ * Example:
+ *
+ * NETLIB_TIMESTEP_IS_TIMESTEP()
+ * NETLIB_TIMESTEPI()
+ * {
+ * // Gpar should support convergence
+ * const nl_double G = m_C.Value() / step + m_GParallel;
+ * const nl_double I = -G * deltaV();
+ * set(G, 0.0, I);
+ * }
+ *
+ */
+#define NETLIB_IS_TIMESTEP() \
+ public: virtual bool is_timestep() const override { return true; }
+
+ /*! Used to implement the time stepping code.
+ *
+ * Please see NETLIB_IS_TIMESTEP for an example.
+ */
+#define NETLIB_TIMESTEPI() \
+ public: virtual void timestep(const nl_double step) override
#define NETLIB_UPDATE_AFTER_PARAM_CHANGE() \
public: virtual bool needs_update_after_param_change() const override { return true; }
@@ -122,6 +129,8 @@ class NETLIB_NAME(name) : public device_t
#define NETLIB_UPDATE_PARAMI() public: virtual void update_param() override
#define NETLIB_RESETI() protected: virtual void reset() override
+#define NETLIB_TIMESTEP(chip) void NETLIB_NAME(chip) :: timestep(const nl_double step)
+
#define NETLIB_SUB(chip) nld_ ## chip
#define NETLIB_SUBXX(chip) std::unique_ptr< nld_ ## chip >
@@ -169,6 +178,7 @@ namespace netlist
class NETLIB_NAME(netlistparams);
class NETLIB_NAME(base_proxy);
class NETLIB_NAME(base_d_to_a_proxy);
+ class NETLIB_NAME(base_a_to_d_proxy);
}
namespace detail {
@@ -199,10 +209,11 @@ namespace netlist
: plib::pexception(text) { }
/*! Copy constructor. */
nl_exception(const nl_exception &e) : plib::pexception(e) { }
- virtual ~nl_exception() {}
+ virtual ~nl_exception();
};
class logic_output_t;
+ class logic_input_t;
class analog_net_t;
class logic_net_t;
class net_t;
@@ -223,10 +234,13 @@ namespace netlist
class logic_family_desc_t
{
public:
- logic_family_desc_t() {}
- virtual ~logic_family_desc_t() {}
+ logic_family_desc_t();
+ virtual ~logic_family_desc_t();
+
virtual plib::owned_ptr<devices::nld_base_d_to_a_proxy> create_d_a_proxy(netlist_t &anetlist, const pstring &name,
logic_output_t *proxied) const = 0;
+ virtual plib::owned_ptr<devices::nld_base_a_to_d_proxy> create_a_d_proxy(netlist_t &anetlist, const pstring &name,
+ logic_input_t *proxied) const = 0;
double fixed_V() const { return m_fixed_V; }
double low_thresh_V(const double VN, const double VP) const { return VN + (VP - VN) * m_low_thresh_PCNT; }
@@ -297,9 +311,9 @@ namespace netlist
const T &value //!< Initial value after construction
);
//! Copy Constructor.
- state_var(const state_var &rhs) noexcept = default;
+ state_var(const state_var &rhs) NL_NOEXCEPT = default;
//! Move Constructor.
- state_var(state_var &&rhs) noexcept = default;
+ state_var(state_var &&rhs) NL_NOEXCEPT = default;
//! Assignment operator to assign value of a state var.
state_var &operator=(state_var rhs) { std::swap(rhs.m_value, this->m_value); return *this; }
//! Assignment operator to assign value of type T.
@@ -327,8 +341,8 @@ namespace netlist
{
public:
state_var(device_t &dev, const pstring name, const T & value);
- state_var(const state_var &rhs) noexcept = default;
- state_var(state_var &&rhs) noexcept = default;
+ state_var(const state_var &rhs) NL_NOEXCEPT = default;
+ state_var(state_var &&rhs) NL_NOEXCEPT = default;
state_var &operator=(const state_var rhs) { m_value = rhs.m_value; return *this; }
state_var &operator=(const T rhs) { m_value = rhs; return *this; }
T & operator[](const std::size_t i) { return m_value[i]; }
@@ -482,7 +496,7 @@ namespace netlist
core_terminal_t(core_device_t &dev, const pstring &aname,
const type_t type, const state_e state);
- virtual ~core_terminal_t() { }
+ virtual ~core_terminal_t();
void set_net(net_t *anet);
void clear_net();
@@ -491,8 +505,8 @@ namespace netlist
const net_t & net() const { return *m_net;}
net_t & net() { return *m_net;}
- bool is_logic() const noexcept;
- bool is_analog() const noexcept;
+ bool is_logic() const NL_NOEXCEPT;
+ bool is_analog() const NL_NOEXCEPT;
bool is_state(const state_e astate) const { return (m_state == astate); }
state_e state() const { return m_state; }
@@ -518,9 +532,10 @@ namespace netlist
: core_terminal_t(dev, aname, type, state)
{
}
+ virtual ~analog_t();
- const analog_net_t & net() const noexcept;
- analog_net_t & net() noexcept;
+ const analog_net_t & net() const NL_NOEXCEPT;
+ analog_net_t & net() NL_NOEXCEPT;
};
// -----------------------------------------------------------------------------
@@ -599,13 +614,14 @@ namespace netlist
, m_proxy(nullptr)
{
}
+ virtual ~logic_t();
bool has_proxy() const { return (m_proxy != nullptr); }
devices::nld_base_proxy *get_proxy() const { return m_proxy; }
void set_proxy(devices::nld_base_proxy *proxy) { m_proxy = proxy; }
- logic_net_t & net() noexcept;
- const logic_net_t & net() const noexcept;
+ logic_net_t & net() NL_NOEXCEPT;
+ const logic_net_t & net() const NL_NOEXCEPT;
protected:
@@ -621,8 +637,9 @@ namespace netlist
{
public:
logic_input_t(core_device_t &dev, const pstring &aname);
+ virtual ~logic_input_t();
- netlist_sig_t Q() const noexcept;
+ netlist_sig_t Q() const NL_NOEXCEPT;
netlist_sig_t operator()() const NL_NOEXCEPT
{
@@ -662,7 +679,7 @@ namespace netlist
/*! returns voltage at terminal.
* \returns voltage at terminal.
*/
- nl_double Q_Analog() const noexcept;
+ nl_double Q_Analog() const NL_NOEXCEPT;
};
@@ -682,16 +699,16 @@ namespace netlist
void reset();
- void register_con(core_terminal_t &terminal);
+ void add_terminal(core_terminal_t &terminal);
- bool is_logic() const noexcept;
- bool is_analog() const noexcept;
+ bool is_logic() const NL_NOEXCEPT;
+ bool is_analog() const NL_NOEXCEPT;
void toggle_new_Q() { m_new_Q ^= 1; }
void force_queue_execution() { m_new_Q = (m_cur_Q ^ 1); }
- void push_to_queue(const netlist_time delay) noexcept;
- void reschedule_in_queue(const netlist_time delay) noexcept;
+ void push_to_queue(const netlist_time delay) NL_NOEXCEPT;
+ void reschedule_in_queue(const netlist_time delay) NL_NOEXCEPT;
bool is_queued() const { return m_in_queue == 1; }
void update_devs() NL_NOEXCEPT;
@@ -702,7 +719,7 @@ namespace netlist
bool isRailNet() const { return !(m_railterminal == nullptr); }
core_terminal_t & railterminal() const { return *m_railterminal; }
- std::size_t num_cons() const noexcept { return m_core_terms.size(); }
+ std::size_t num_cons() const NL_NOEXCEPT { return m_core_terms.size(); }
void inc_active(core_terminal_t &term) NL_NOEXCEPT;
void dec_active(core_terminal_t &term) NL_NOEXCEPT;
@@ -736,13 +753,13 @@ namespace netlist
public:
logic_net_t(netlist_t &nl, const pstring &aname, detail::core_terminal_t *mr = nullptr);
- virtual ~logic_net_t() { }
+ virtual ~logic_net_t();
netlist_sig_t Q() const { return m_cur_Q; }
netlist_sig_t new_Q() const { return m_new_Q; }
void initial(const netlist_sig_t val) { m_cur_Q = m_new_Q = val; }
- void set_Q(const netlist_sig_t newQ, const netlist_time delay) noexcept
+ void set_Q(const netlist_sig_t newQ, const netlist_time delay) NL_NOEXCEPT
{
if (newQ != m_new_Q)
{
@@ -751,7 +768,7 @@ namespace netlist
}
}
- void set_Q_time(const netlist_sig_t newQ, const netlist_time at) noexcept
+ void set_Q_time(const netlist_sig_t newQ, const netlist_time at) NL_NOEXCEPT
{
if (newQ != m_new_Q)
{
@@ -780,7 +797,7 @@ namespace netlist
analog_net_t(netlist_t &nl, const pstring &aname, detail::core_terminal_t *mr = nullptr);
- virtual ~analog_net_t() { }
+ virtual ~analog_net_t();
nl_double Q_Analog() const { return m_cur_Analog; }
nl_double &Q_Analog_state_ptr() { return m_cur_Analog; }
@@ -803,10 +820,11 @@ namespace netlist
public:
logic_output_t(core_device_t &dev, const pstring &aname);
+ virtual ~logic_output_t();
void initial(const netlist_sig_t val);
- void push(const netlist_sig_t newQ, const netlist_time delay) noexcept
+ void push(const netlist_sig_t newQ, const netlist_time delay) NL_NOEXCEPT
{
m_my_net.set_Q(newQ, delay); // take the shortcut
}
@@ -820,12 +838,13 @@ namespace netlist
P_PREVENT_COPYING(analog_output_t)
public:
analog_output_t(core_device_t &dev, const pstring &aname);
+ virtual ~analog_output_t();
- void push(const nl_double val) noexcept { set_Q(val); }
+ void push(const nl_double val) NL_NOEXCEPT { set_Q(val); }
void initial(const nl_double val);
private:
- void set_Q(const nl_double newQ) noexcept;
+ void set_Q(const nl_double newQ) NL_NOEXCEPT;
analog_net_t m_my_net;
};
@@ -847,7 +866,7 @@ namespace netlist
};
param_t(const param_type_t atype, device_t &device, const pstring &name);
- virtual ~param_t() {}
+ virtual ~param_t();
param_type_t param_type() const { return m_param_type; }
@@ -923,7 +942,7 @@ namespace netlist
}
}
protected:
- virtual void changed() { }
+ virtual void changed();
pstring Value() const { return m_param; }
private:
pstring m_param;
@@ -940,7 +959,7 @@ namespace netlist
const pstring model_value_str(const pstring &entity);
const pstring model_type();
protected:
- virtual void changed() override { m_map.clear(); }
+ virtual void changed() override;
private:
model_map_t m_map;
};
@@ -952,29 +971,7 @@ namespace netlist
: param_str_t(device, name, "") { }
std::unique_ptr<plib::pistream> stream();
protected:
- virtual void changed() override { }
- };
-
- template <typename ST, std::size_t AW, std::size_t DW>
- class param_rom_t final: public param_data_t
- {
- public:
-
- param_rom_t(device_t &device, const pstring name)
- : param_data_t(device, name)
- {
- stream()->read(&m_data[0],1<<AW);
- }
-
- const ST & operator[] (std::size_t n) { return m_data[n]; }
-
- protected:
- virtual void changed() override
- {
- stream()->read(&m_data[0],1<<AW);
- }
- private:
- ST m_data[1 << AW];
+ virtual void changed() override;
};
// -----------------------------------------------------------------------------
@@ -1014,7 +1011,7 @@ namespace netlist
void set_delegate_pointer();
void stop_dev();
- void do_inc_active() noexcept
+ void do_inc_active() NL_NOEXCEPT
{
if (m_hint_deactivate)
{
@@ -1023,7 +1020,7 @@ namespace netlist
}
}
- void do_dec_active() noexcept
+ void do_dec_active() NL_NOEXCEPT
{
if (m_hint_deactivate)
dec_active();
@@ -1039,13 +1036,13 @@ namespace netlist
protected:
virtual void update() NL_NOEXCEPT { }
- virtual void inc_active() noexcept { }
- virtual void dec_active() noexcept { }
+ virtual void inc_active() NL_NOEXCEPT { }
+ virtual void dec_active() NL_NOEXCEPT { }
virtual void stop() { }
virtual void reset() { }
public:
- virtual void step_time(ATTR_UNUSED const nl_double st) { }
+ virtual void timestep(ATTR_UNUSED const nl_double st) { }
virtual void update_terminals() { }
virtual void update_param() {}
@@ -1177,7 +1174,7 @@ namespace netlist
devices::NETLIB_NAME(gnd) *gnd() const { return m_gnd; }
nl_double gmin() const;
- void push_to_queue(detail::net_t &out, const netlist_time attime) noexcept;
+ void push_to_queue(detail::net_t &out, const netlist_time attime) NL_NOEXCEPT;
void remove_from_queue(detail::net_t &out) NL_NOEXCEPT;
void process_queue(const netlist_time &delta);
@@ -1294,25 +1291,55 @@ namespace netlist
};
// -----------------------------------------------------------------------------
+ // rom parameter
+ // -----------------------------------------------------------------------------
+
+ template <typename ST, std::size_t AW, std::size_t DW>
+ class param_rom_t final: public param_data_t
+ {
+ public:
+
+ param_rom_t(device_t &device, const pstring name)
+ : param_data_t(device, name)
+ {
+ auto f = stream();
+ if (f != nullptr)
+ f->read(&m_data[0],1<<AW);
+ else
+ device.netlist().log().warning("Rom {1} not found", Value());
+ }
+
+ const ST & operator[] (std::size_t n) { return m_data[n]; }
+
+ protected:
+ virtual void changed() override
+ {
+ stream()->read(&m_data[0],1<<AW);
+ }
+ private:
+ ST m_data[1 << AW];
+ };
+
+ // -----------------------------------------------------------------------------
// inline implementations
// -----------------------------------------------------------------------------
- inline bool detail::core_terminal_t::is_logic() const noexcept
+ inline bool detail::core_terminal_t::is_logic() const NL_NOEXCEPT
{
return dynamic_cast<const logic_t *>(this) != nullptr;
}
- inline bool detail::core_terminal_t::is_analog() const noexcept
+ inline bool detail::core_terminal_t::is_analog() const NL_NOEXCEPT
{
return dynamic_cast<const analog_t *>(this) != nullptr;
}
- inline bool detail::net_t::is_logic() const noexcept
+ inline bool detail::net_t::is_logic() const NL_NOEXCEPT
{
return dynamic_cast<const logic_net_t *>(this) != nullptr;
}
- inline bool detail::net_t::is_analog() const noexcept
+ inline bool detail::net_t::is_analog() const NL_NOEXCEPT
{
return dynamic_cast<const analog_net_t *>(this) != nullptr;
}
@@ -1353,7 +1380,7 @@ namespace netlist
}
}
- inline void detail::net_t::push_to_queue(const netlist_time delay) noexcept
+ inline void detail::net_t::push_to_queue(const netlist_time delay) NL_NOEXCEPT
{
if (!is_queued() && (num_cons() != 0))
{
@@ -1366,7 +1393,7 @@ namespace netlist
}
}
- inline void detail::net_t::reschedule_in_queue(const netlist_time delay) noexcept
+ inline void detail::net_t::reschedule_in_queue(const netlist_time delay) NL_NOEXCEPT
{
if (is_queued())
netlist().remove_from_queue(*this);
@@ -1379,39 +1406,39 @@ namespace netlist
}
}
- inline const analog_net_t & analog_t::net() const noexcept
+ inline const analog_net_t & analog_t::net() const NL_NOEXCEPT
{
return static_cast<const analog_net_t &>(core_terminal_t::net());
}
- inline analog_net_t & analog_t::net() noexcept
+ inline analog_net_t & analog_t::net() NL_NOEXCEPT
{
return static_cast<analog_net_t &>(core_terminal_t::net());
}
inline nl_double terminal_t::operator ()() const { return net().Q_Analog(); }
- inline logic_net_t & logic_t::net() noexcept
+ inline logic_net_t & logic_t::net() NL_NOEXCEPT
{
return *static_cast<logic_net_t *>(&core_terminal_t::net());
}
- inline const logic_net_t & logic_t::net() const noexcept
+ inline const logic_net_t & logic_t::net() const NL_NOEXCEPT
{
return static_cast<const logic_net_t &>(core_terminal_t::net());
}
- inline netlist_sig_t logic_input_t::Q() const noexcept
+ inline netlist_sig_t logic_input_t::Q() const NL_NOEXCEPT
{
return net().Q();
}
- inline nl_double analog_input_t::Q_Analog() const noexcept
+ inline nl_double analog_input_t::Q_Analog() const NL_NOEXCEPT
{
return net().Q_Analog();
}
- inline void analog_output_t::set_Q(const nl_double newQ) noexcept
+ inline void analog_output_t::set_Q(const nl_double newQ) NL_NOEXCEPT
{
if (newQ != net().Q_Analog())
{
@@ -1421,7 +1448,7 @@ namespace netlist
}
}
- inline void netlist_t::push_to_queue(detail::net_t &out, const netlist_time attime) noexcept
+ inline void netlist_t::push_to_queue(detail::net_t &out, const netlist_time attime) NL_NOEXCEPT
{
m_queue.push(attime, &out);
}
diff --git a/src/lib/netlist/nl_config.h b/src/lib/netlist/nl_config.h
index 14598d2dccf..3181e486dde 100644
--- a/src/lib/netlist/nl_config.h
+++ b/src/lib/netlist/nl_config.h
@@ -51,7 +51,7 @@
*/
// This will be autodetected
-//#define NL_PMF_TYPE 0
+// #define NL_PMF_TYPE 0
#define NL_PMF_TYPE_VIRTUAL 0
#define NL_PMF_TYPE_GNUC_PMF 1
@@ -82,16 +82,16 @@
* linear memory pool. This is based of the assumption that
* due to enhanced locality there will be less cache misses.
* Your mileage may vary.
+ * This will cause crashes on OSX and thus is ignored on OSX.
*
*/
-#define USE_MEMPOOL (1)
+#define USE_MEMPOOL (0)
#define USE_TRUTHTABLE (1)
//============================================================
// Solver defines
//============================================================
-#define USE_MATRIX_GS (0)
#define USE_GABS (1)
// savings are eaten up by effort
// FIXME: Convert into solver parameter
@@ -165,5 +165,9 @@ using nl_double = double;
#endif
#endif
+#ifdef __APPLE__
+#undef USE_MEMPOOL
+#define USE_MEMPOOL (0)
+#endif
#endif /* NLCONFIG_H_ */
diff --git a/src/lib/netlist/nl_factory.cpp b/src/lib/netlist/nl_factory.cpp
index f1d3281aa81..33fc532331b 100644
--- a/src/lib/netlist/nl_factory.cpp
+++ b/src/lib/netlist/nl_factory.cpp
@@ -12,45 +12,40 @@
#include "nl_setup.h"
#include "plib/putil.h"
-namespace netlist
+namespace netlist { namespace factory
{
-// ----------------------------------------------------------------------------------------
-// net_device_t_base_factory
-// ----------------------------------------------------------------------------------------
-const plib::pstring_vector_t base_factory_t::term_param_list()
+element_t::element_t(const pstring &name, const pstring &classname,
+ const pstring &def_param)
+ : m_name(name), m_classname(classname), m_def_param(def_param)
{
- if (m_def_param.startsWith("+"))
- return plib::pstring_vector_t(m_def_param.substr(1), ",");
- else
- return plib::pstring_vector_t();
}
-const plib::pstring_vector_t base_factory_t::def_params()
+element_t::~element_t()
{
- if (m_def_param.startsWith("+") || m_def_param.equals("-"))
- return plib::pstring_vector_t();
- else
- return plib::pstring_vector_t(m_def_param, ",");
}
-factory_list_t::factory_list_t( setup_t &setup)
+// ----------------------------------------------------------------------------------------
+// net_device_t_base_factory
+// ----------------------------------------------------------------------------------------
+
+list_t::list_t( setup_t &setup)
: m_setup(setup)
{
}
-factory_list_t::~factory_list_t()
+list_t::~list_t()
{
clear();
}
-void factory_list_t::error(const pstring &s)
+void list_t::error(const pstring &s)
{
m_setup.log().fatal("{1}", s);
}
-base_factory_t * factory_list_t::factory_by_name(const pstring &devname)
+factory::element_t * list_t::factory_by_name(const pstring &devname)
{
for (auto & e : *this)
{
@@ -62,4 +57,29 @@ base_factory_t * factory_list_t::factory_by_name(const pstring &devname)
return nullptr; // appease code analysis
}
+// -----------------------------------------------------------------------------
+// factory_lib_entry_t: factory class to wrap macro based chips/elements
+// -----------------------------------------------------------------------------
+
+plib::owned_ptr<device_t> library_element_t::Create(netlist_t &anetlist, const pstring &name)
+{
+ return plib::owned_ptr<device_t>::Create<NETLIB_NAME(wrapper)>(anetlist, name);
+}
+
+void library_element_t::macro_actions(netlist_t &anetlist, const pstring &name)
+{
+ anetlist.setup().namespace_push(name);
+ anetlist.setup().include(this->name());
+ anetlist.setup().namespace_pop();
+}
+
+NETLIB_RESET(wrapper)
+{
+}
+
+NETLIB_UPDATE(wrapper)
+{
}
+
+
+} }
diff --git a/src/lib/netlist/nl_factory.h b/src/lib/netlist/nl_factory.h
index 6a53797d0d8..0f4a1344e38 100644
--- a/src/lib/netlist/nl_factory.h
+++ b/src/lib/netlist/nl_factory.h
@@ -17,32 +17,28 @@
#include "plib/putil.h"
#include "nl_base.h"
-#define NETLIB_DEVICE_IMPL(chip) factory_creator_ptr_t decl_ ## chip = factory_creator_t< NETLIB_NAME(chip) >;
+#define NETLIB_DEVICE_IMPL(chip) factory::constructor_ptr_t decl_ ## chip = factory::constructor_t< NETLIB_NAME(chip) >;
-namespace netlist
+namespace netlist { namespace factory
{
// -----------------------------------------------------------------------------
// net_dev class factory
// -----------------------------------------------------------------------------
- class base_factory_t
+ class element_t
{
- P_PREVENT_COPYING(base_factory_t)
+ P_PREVENT_COPYING(element_t)
public:
- base_factory_t(const pstring &name, const pstring &classname,
- const pstring &def_param)
- : m_name(name), m_classname(classname), m_def_param(def_param)
- {}
-
- virtual ~base_factory_t() {}
+ element_t(const pstring &name, const pstring &classname,
+ const pstring &def_param);
+ virtual ~element_t();
virtual plib::owned_ptr<device_t> Create(netlist_t &anetlist, const pstring &name) = 0;
+ virtual void macro_actions(netlist_t &anetlist, const pstring &name) {}
const pstring &name() const { return m_name; }
const pstring &classname() const { return m_classname; }
const pstring &param_desc() const { return m_def_param; }
- const plib::pstring_vector_t term_param_list();
- const plib::pstring_vector_t def_params();
protected:
pstring m_name; /* device name */
@@ -51,13 +47,13 @@ namespace netlist
};
template <class C>
- class factory_t : public base_factory_t
+ class device_element_t : public element_t
{
- P_PREVENT_COPYING(factory_t)
+ P_PREVENT_COPYING(device_element_t)
public:
- factory_t(const pstring &name, const pstring &classname,
+ device_element_t(const pstring &name, const pstring &classname,
const pstring &def_param)
- : base_factory_t(name, classname, def_param) { }
+ : element_t(name, classname, def_param) { }
plib::owned_ptr<device_t> Create(netlist_t &anetlist, const pstring &name) override
{
@@ -65,20 +61,20 @@ namespace netlist
}
};
- class factory_list_t : public std::vector<std::unique_ptr<base_factory_t>>
+ class list_t : public std::vector<std::unique_ptr<element_t>>
{
public:
- factory_list_t(setup_t &m_setup);
- ~factory_list_t();
+ list_t(setup_t &m_setup);
+ ~list_t();
template<class device_class>
void register_device(const pstring &name, const pstring &classname,
const pstring &def_param)
{
- register_device(std::unique_ptr<base_factory_t>(new factory_t<device_class>(name, classname, def_param)));
+ register_device(std::unique_ptr<element_t>(new device_element_t<device_class>(name, classname, def_param)));
}
- void register_device(std::unique_ptr<base_factory_t> factory)
+ void register_device(std::unique_ptr<element_t> factory)
{
for (auto & e : *this)
if (e->name() == factory->name())
@@ -86,12 +82,12 @@ namespace netlist
push_back(std::move(factory));
}
- base_factory_t * factory_by_name(const pstring &devname);
+ element_t * factory_by_name(const pstring &devname);
template <class C>
- bool is_class(base_factory_t *f)
+ bool is_class(element_t *f)
{
- return dynamic_cast<factory_t<C> *>(f) != nullptr;
+ return dynamic_cast<device_element_t<C> *>(f) != nullptr;
}
private:
@@ -104,16 +100,49 @@ namespace netlist
// factory_creator_ptr_t
// -----------------------------------------------------------------------------
- using factory_creator_ptr_t = std::unique_ptr<base_factory_t> (*)(const pstring &name, const pstring &classname,
+ using constructor_ptr_t = std::unique_ptr<element_t> (*)(const pstring &name, const pstring &classname,
const pstring &def_param);
template <typename T>
- std::unique_ptr<base_factory_t> factory_creator_t(const pstring &name, const pstring &classname,
+ std::unique_ptr<element_t> constructor_t(const pstring &name, const pstring &classname,
const pstring &def_param)
{
- return std::unique_ptr<base_factory_t>(new factory_t<T>(name, classname, def_param));
+ return std::unique_ptr<element_t>(new device_element_t<T>(name, classname, def_param));
}
-}
+ // -----------------------------------------------------------------------------
+ // factory_lib_entry_t: factory class to wrap macro based chips/elements
+ // -----------------------------------------------------------------------------
+
+ class NETLIB_NAME(wrapper) : public device_t
+ {
+ public:
+ NETLIB_NAME(wrapper)(netlist_t &anetlist, const pstring &name)
+ : device_t(anetlist, name)
+ {
+ }
+ protected:
+ NETLIB_RESETI();
+ NETLIB_UPDATEI();
+ };
+
+ class library_element_t : public element_t
+ {
+ P_PREVENT_COPYING(library_element_t)
+ public:
+
+ library_element_t(setup_t &setup, const pstring &name, const pstring &classname,
+ const pstring &def_param)
+ : element_t(name, classname, def_param), m_setup(setup) { }
+
+ plib::owned_ptr<device_t> Create(netlist_t &anetlist, const pstring &name) override;
+
+ void macro_actions(netlist_t &anetlist, const pstring &name) override;
+
+ private:
+ setup_t &m_setup;
+ };
+
+} }
#endif /* NLFACTORY_H_ */
diff --git a/src/lib/netlist/nl_parser.cpp b/src/lib/netlist/nl_parser.cpp
index 6760873a4af..6dee211ce56 100644
--- a/src/lib/netlist/nl_parser.cpp
+++ b/src/lib/netlist/nl_parser.cpp
@@ -316,7 +316,7 @@ void parser_t::dippins()
error(plib::pfmt("expected a comma, found <{1}>")(n.str()) );
}
if ((pins.size() % 2) == 1)
- error("You must pass an equal number of pins to DIPPINS");
+ error(plib::pfmt("You must pass an equal number of pins to DIPPINS, first pin is {}")(pins[0]));
std::size_t n = pins.size();
for (std::size_t i = 0; i < n / 2; i++)
{
@@ -356,35 +356,29 @@ void parser_t::netdev_hint()
void parser_t::device(const pstring &dev_type)
{
- if (m_setup.is_library_item(dev_type))
- {
- pstring devname = get_identifier();
- m_setup.namespace_push(devname);
- m_setup.include(dev_type);
- m_setup.namespace_pop();
- require_token(m_tok_param_right);
- }
- else
- {
- base_factory_t *f = m_setup.factory().factory_by_name(dev_type);
- plib::pstring_vector_t termlist = f->term_param_list();
- plib::pstring_vector_t def_params = f->def_params();
+ factory::element_t *f = m_setup.factory().factory_by_name(dev_type);
+ auto paramlist = plib::pstring_vector_t(f->param_desc(), ",");
- std::size_t cnt;
+ pstring devname = get_identifier();
- pstring devname = get_identifier();
+ m_setup.register_dev(dev_type, devname);
+ m_setup.log().debug("Parser: IC: {1}\n", devname);
- m_setup.register_dev(dev_type, m_setup.build_fqn(devname));
-
- m_setup.log().debug("Parser: IC: {1}\n", devname);
+ for (pstring tp : paramlist)
+ {
+ require_token(m_tok_comma);
+ if (tp.startsWith("+"))
+ {
+ pstring output_name = get_identifier();
+ m_setup.log().debug("Link: {1} {2}\n", tp, output_name);
- cnt = 0;
- while (cnt < def_params.size())
+ m_setup.register_link(devname + "." + tp.substr(1), output_name);
+ }
+ else
{
- pstring paramfq = devname + "." + def_params[cnt];
+ pstring paramfq = devname + "." + tp;
m_setup.log().debug("Defparam: {1}\n", paramfq);
- require_token(m_tok_comma);
token_t tok = get_token();
if (tok.is_type(STRING))
{
@@ -395,24 +389,11 @@ void parser_t::device(const pstring &dev_type)
nl_double val = eval_param(tok);
m_setup.register_param(paramfq, val);
}
- cnt++;
}
-
- token_t tok = get_token();
- cnt = 0;
- while (tok.is(m_tok_comma) && cnt < termlist.size())
- {
- pstring output_name = get_identifier();
-
- m_setup.register_link(devname + "." + termlist[cnt], output_name);
-
- cnt++;
- tok = get_token();
- }
- if (cnt != termlist.size())
- error(plib::pfmt("Input count mismatch for {1} - expected {2} found {3}")(devname)(termlist.size())(cnt));
- require_token(tok, m_tok_param_right);
}
+
+ // error(plib::pfmt("Input count mismatch for {1} - expected {2} found {3}")(devname)(termlist.size())(cnt));
+ require_token(m_tok_param_right);
}
diff --git a/src/lib/netlist/nl_setup.cpp b/src/lib/netlist/nl_setup.cpp
index 06cef2a0947..39d85e5be1d 100644
--- a/src/lib/netlist/nl_setup.cpp
+++ b/src/lib/netlist/nl_setup.cpp
@@ -103,27 +103,17 @@ void setup_t::namespace_pop()
void setup_t::register_lib_entry(const pstring &name)
{
- if (plib::container::contains(m_lib, name))
- log().warning("Lib entry collection already contains {1}. IGNORED", name);
- else
- m_lib.push_back(name);
+ factory().register_device(plib::make_unique_base<factory::element_t, factory::library_element_t>(*this, name, name, ""));
}
void setup_t::register_dev(const pstring &classname, const pstring &name)
{
- if (plib::container::contains(m_lib, classname))
- {
- namespace_push(name);
- include(classname);
- namespace_pop();
- }
- else
- {
- auto f = factory().factory_by_name(classname);
- if (f == nullptr)
- log().fatal("Class {1} not found!\n", classname);
- m_device_factory.push_back(std::pair<pstring, base_factory_t *>(build_fqn(name), f));
- }
+ auto f = factory().factory_by_name(classname);
+ if (f == nullptr)
+ log().fatal("Class {1} not found!\n", classname);
+ /* make sure we parse macro library entries */
+ f->macro_actions(netlist(), name);
+ m_device_factory.push_back(std::pair<pstring, factory::element_t *>(build_fqn(name), f));
}
bool setup_t::device_exists(const pstring name) const
@@ -165,7 +155,7 @@ void setup_t::register_dippins_arr(const pstring &terms)
{
plib::pstring_vector_t list(terms,", ");
if (list.size() == 0 || (list.size() % 2) == 1)
- log().fatal("You must pass an equal number of pins to DIPPINS");
+ log().fatal("You must pass an equal number of pins to DIPPINS {1}" , build_fqn(""));
std::size_t n = list.size();
for (std::size_t i = 0; i < n / 2; i++)
{
@@ -207,7 +197,7 @@ double setup_t::get_initial_param_val(const pstring name, const double def)
if (i != m_param_values.end())
{
double vald = 0;
- if (sscanf(i->second.cstr(), "%lf", &vald) != 1)
+ if (sscanf(i->second.c_str(), "%lf", &vald) != 1)
log().fatal("Invalid number conversion {1} : {2}\n", name, i->second);
return vald;
}
@@ -221,7 +211,7 @@ int setup_t::get_initial_param_val(const pstring name, const int def)
if (i != m_param_values.end())
{
double vald = 0;
- if (sscanf(i->second.cstr(), "%lf", &vald) != 1)
+ if (sscanf(i->second.c_str(), "%lf", &vald) != 1)
log().fatal("Invalid number conversion {1} : {2}\n", name, i->second);
return static_cast<int>(vald);
}
@@ -349,7 +339,7 @@ const pstring setup_t::resolve_alias(const pstring &name) const
ret = temp;
auto p = m_alias.find(ret);
temp = (p != m_alias.end() ? p->second : "");
- } while (temp != "");
+ } while (temp != "" && temp != ret);
log().debug("{1}==>{2}\n", name, ret);
return ret;
@@ -445,7 +435,7 @@ devices::nld_base_proxy *setup_t::get_d_a_proxy(detail::core_terminal_t &out)
}
out.net().m_core_terms.clear(); // clear the list
- out.net().register_con(new_proxy->in());
+ out.net().add_terminal(new_proxy->in());
out_cast.set_proxy(proxy);
proxy = new_proxy.get();
@@ -455,6 +445,52 @@ devices::nld_base_proxy *setup_t::get_d_a_proxy(detail::core_terminal_t &out)
return proxy;
}
+devices::nld_base_proxy *setup_t::get_a_d_proxy(detail::core_terminal_t &inp)
+{
+ nl_assert(inp.is_analog());
+
+ logic_input_t &incast = dynamic_cast<logic_input_t &>(inp);
+ devices::nld_base_proxy *proxy = incast.get_proxy();
+
+ if (proxy != nullptr)
+ return proxy;
+ else
+ {
+ log().debug("connect_terminal_input: connecting proxy\n");
+ pstring x = plib::pfmt("proxy_ad_{1}_{2}")(inp.name())(m_proxy_cnt);
+ auto new_proxy = incast.logic_family()->create_a_d_proxy(netlist(), x, &incast);
+ //auto new_proxy = plib::owned_ptr<devices::nld_a_to_d_proxy>::Create(netlist(), x, &incast);
+ incast.set_proxy(new_proxy.get());
+ m_proxy_cnt++;
+
+ auto ret = new_proxy.get();
+
+#if 1
+ /* connect all existing terminals to new net */
+
+ if (inp.has_net())
+ {
+ for (auto & p : inp.net().m_core_terms)
+ {
+ p->clear_net(); // de-link from all nets ...
+ if (!connect(ret->proxy_term(), *p))
+ log().fatal("Error connecting {1} to {2}\n", ret->proxy_term().name(), (*p).name());
+ }
+ inp.net().m_core_terms.clear(); // clear the list
+ }
+ ret->out().net().add_terminal(inp);
+#else
+ if (inp.has_net())
+ //fatalerror("logic inputs can only belong to one net!\n");
+ merge_nets(ret->out().net(), inp.net());
+ else
+ ret->out().net().add_terminal(inp);
+#endif
+ netlist().register_dev(std::move(new_proxy));
+ return ret;
+ }
+}
+
void setup_t::merge_nets(detail::net_t &thisnet, detail::net_t &othernet)
{
netlist().log().debug("merging nets ...\n");
@@ -484,17 +520,16 @@ void setup_t::connect_input_output(detail::core_terminal_t &in, detail::core_ter
{
if (out.is_analog() && in.is_logic())
{
+#if 0
logic_input_t &incast = dynamic_cast<logic_input_t &>(in);
pstring x = plib::pfmt("proxy_ad_{1}_{2}")(in.name())( m_proxy_cnt);
auto proxy = plib::owned_ptr<devices::nld_a_to_d_proxy>::Create(netlist(), x, &incast);
incast.set_proxy(proxy.get());
m_proxy_cnt++;
+#endif
+ auto proxy = get_a_d_proxy(in);
- proxy->m_Q.net().register_con(in);
- out.net().register_con(proxy->m_I);
-
- netlist().register_dev(std::move(proxy));
-
+ out.net().add_terminal(proxy->proxy_term());
}
else if (out.is_logic() && in.is_analog())
{
@@ -508,7 +543,7 @@ void setup_t::connect_input_output(detail::core_terminal_t &in, detail::core_ter
if (in.has_net())
merge_nets(out.net(), in.net());
else
- out.net().register_con(in);
+ out.net().add_terminal(in);
}
}
@@ -522,22 +557,19 @@ void setup_t::connect_terminal_input(terminal_t &term, detail::core_terminal_t &
else if (inp.is_logic())
{
netlist().log().verbose("connect terminal {1} (in, {2}) to {3}\n", inp.name(), pstring(inp.is_analog() ? "analog" : inp.is_logic() ? "logic" : "?"), term.name());
+#if 0
logic_input_t &incast = dynamic_cast<logic_input_t &>(inp);
log().debug("connect_terminal_input: connecting proxy\n");
pstring x = plib::pfmt("proxy_ad_{1}_{2}")(inp.name())(m_proxy_cnt);
auto proxy = plib::owned_ptr<devices::nld_a_to_d_proxy>::Create(netlist(), x, &incast);
incast.set_proxy(proxy.get());
m_proxy_cnt++;
+#endif
+ auto proxy = get_a_d_proxy(inp);
- connect_terminals(term, proxy->m_I);
-
- if (inp.has_net())
- //fatalerror("logic inputs can only belong to one net!\n");
- merge_nets(proxy->m_Q.net(), inp.net());
- else
- proxy->m_Q.net().register_con(inp);
+ //out.net().register_con(proxy->proxy_term());
+ connect_terminals(term, proxy->proxy_term());
- netlist().register_dev(std::move(proxy));
}
else
{
@@ -554,7 +586,7 @@ void setup_t::connect_terminal_output(terminal_t &in, detail::core_terminal_t &o
if (in.has_net())
merge_nets(out.net(), in.net());
else
- out.net().register_con(in);
+ out.net().add_terminal(in);
}
else if (out.is_logic())
{
@@ -579,12 +611,12 @@ void setup_t::connect_terminals(detail::core_terminal_t &t1, detail::core_termin
else if (t2.has_net())
{
log().debug("T2 has net\n");
- t2.net().register_con(t1);
+ t2.net().add_terminal(t1);
}
else if (t1.has_net())
{
log().debug("T1 has net\n");
- t1.net().register_con(t2);
+ t1.net().add_terminal(t2);
}
else
{
@@ -592,8 +624,8 @@ void setup_t::connect_terminals(detail::core_terminal_t &t1, detail::core_termin
// FIXME: Nets should have a unique name
auto anet = plib::palloc<analog_net_t>(netlist(),"net." + t1.name());
t1.set_net(anet);
- anet->register_con(t2);
- anet->register_con(t1);
+ anet->add_terminal(t2);
+ anet->add_terminal(t1);
}
}
@@ -836,6 +868,10 @@ public:
{
return plib::owned_ptr<devices::nld_base_d_to_a_proxy>::Create<devices::nld_d_to_a_proxy>(anetlist, name, proxied);
}
+ virtual plib::owned_ptr<devices::nld_base_a_to_d_proxy> create_a_d_proxy(netlist_t &anetlist, const pstring &name, logic_input_t *proxied) const override
+ {
+ return plib::owned_ptr<devices::nld_base_a_to_d_proxy>::Create<devices::nld_a_to_d_proxy>(anetlist, name, proxied);
+ }
};
const logic_family_desc_t *setup_t::family_from_model(const pstring &model)
@@ -994,7 +1030,8 @@ std::unique_ptr<plib::pistream> setup_t::get_data_stream(const pstring name)
return strm;
}
}
- log().fatal("unable to find data named {1} in source collection", name);
+ //log().fatal("unable to find data named {1} in source collection", name);
+ log().warning("unable to find data named {1} in source collection", name);
return std::unique_ptr<plib::pistream>(nullptr);
}
@@ -1030,12 +1067,12 @@ bool source_t::parse(const pstring &name)
std::unique_ptr<plib::pistream> source_string_t::stream(const pstring &name)
{
- return plib::make_unique_base<plib::pistream, plib::pimemstream>(m_str.cstr(), m_str.len());
+ return plib::make_unique_base<plib::pistream, plib::pimemstream>(m_str.c_str(), m_str.len());
}
std::unique_ptr<plib::pistream> source_mem_t::stream(const pstring &name)
{
- return plib::make_unique_base<plib::pistream, plib::pimemstream>(m_str.cstr(), m_str.len());
+ return plib::make_unique_base<plib::pistream, plib::pimemstream>(m_str.c_str(), m_str.len());
}
std::unique_ptr<plib::pistream> source_file_t::stream(const pstring &name)
@@ -1043,4 +1080,22 @@ std::unique_ptr<plib::pistream> source_file_t::stream(const pstring &name)
return plib::make_unique_base<plib::pistream, plib::pifilestream>(m_filename);
}
+bool source_proc_t::parse(const pstring &name)
+{
+ if (name == m_setup_func_name)
+ {
+ m_setup_func(setup());
+ return true;
+ }
+ else
+ return false;
+}
+
+std::unique_ptr<plib::pistream> source_proc_t::stream(const pstring &name)
+{
+ std::unique_ptr<plib::pistream> p(nullptr);
+ return p;
+}
+
}
+
diff --git a/src/lib/netlist/nl_setup.h b/src/lib/netlist/nl_setup.h
index e560a3b9f79..66745504c74 100644
--- a/src/lib/netlist/nl_setup.h
+++ b/src/lib/netlist/nl_setup.h
@@ -92,7 +92,7 @@ void NETLIST_NAME(name)(netlist::setup_t &setup) \
desc.classname = #cname ; \
desc.ni = in; \
desc.no = out; \
- desc.def_param = pstring("+") + def_params; \
+ desc.def_param = def_params; \
desc.family = "";
#define TT_HEAD(x) \
@@ -252,10 +252,8 @@ namespace netlist
void register_define(pstring def, pstring val) { m_defines.push_back(plib::ppreprocessor::define_t(def, val)); }
void register_define(pstring defstr);
- factory_list_t &factory() { return m_factory; }
- const factory_list_t &factory() const { return m_factory; }
-
- bool is_library_item(const pstring &name) const { return plib::container::contains(m_lib, name); }
+ factory::list_t &factory() { return m_factory; }
+ const factory::list_t &factory() const { return m_factory; }
/* model / family related */
@@ -275,7 +273,7 @@ namespace netlist
plib::plog_base<NL_DEBUG> &log();
const plib::plog_base<NL_DEBUG> &log() const;
- std::vector<std::pair<pstring, base_factory_t *>> m_device_factory;
+ std::vector<std::pair<pstring, factory::element_t *>> m_device_factory;
std::unordered_map<pstring, pstring> m_alias;
std::unordered_map<pstring, pstring> m_param_values;
@@ -300,17 +298,17 @@ namespace netlist
pstring objtype_as_str(detail::device_object_t &in) const;
devices::nld_base_proxy *get_d_a_proxy(detail::core_terminal_t &out);
+ devices::nld_base_proxy *get_a_d_proxy(detail::core_terminal_t &inp);
netlist_t &m_netlist;
std::unordered_map<pstring, param_ref_t> m_params;
std::vector<link_t> m_links;
- factory_list_t m_factory;
+ factory::list_t m_factory;
std::unordered_map<pstring, pstring> m_models;
std::stack<pstring> m_namespace_stack;
source_t::list_t m_sources;
std::vector<plib::ppreprocessor::define_t> m_defines;
- std::vector<pstring> m_lib;
unsigned m_proxy_cnt;
unsigned m_frontier_cnt;
@@ -375,22 +373,9 @@ namespace netlist
{
}
- virtual bool parse(const pstring &name) override
- {
- if (name == m_setup_func_name)
- {
- m_setup_func(setup());
- return true;
- }
- else
- return false;
- }
+ virtual bool parse(const pstring &name) override;
+ virtual std::unique_ptr<plib::pistream> stream(const pstring &name) override;
- virtual std::unique_ptr<plib::pistream> stream(const pstring &name) override
- {
- std::unique_ptr<plib::pistream> p(nullptr);
- return p;
- }
private:
void (*m_setup_func)(setup_t &);
pstring m_setup_func_name;
diff --git a/src/lib/netlist/plib/palloc.cpp b/src/lib/netlist/plib/palloc.cpp
index b90960f953e..2f1131601da 100644
--- a/src/lib/netlist/plib/palloc.cpp
+++ b/src/lib/netlist/plib/palloc.cpp
@@ -12,44 +12,6 @@
#include "pfmtlog.h"
namespace plib {
-//============================================================
-// Exceptions
-//============================================================
-
-pexception::pexception(const pstring text)
-{
- m_text = text;
-}
-
-file_e::file_e(const pstring fmt, const pstring &filename)
- : pexception(pfmt(fmt)(filename))
-{
-}
-
-file_open_e::file_open_e(const pstring &filename)
- : file_e("File open failed: {}", filename)
-{
-}
-
-file_read_e::file_read_e(const pstring &filename)
- : file_e("File read failed: {}", filename)
-{
-}
-
-file_write_e::file_write_e(const pstring &filename)
- : file_e("File write failed: {}", filename)
-{
-}
-
-null_argument_e::null_argument_e(const pstring &argument)
- : pexception(pfmt("Null argument passed: {}")(argument))
-{
-}
-
-out_of_mem_e::out_of_mem_e(const pstring &location)
- : pexception(pfmt("Out of memory: {}")(location))
-{
-}
//============================================================
// Memory pool
diff --git a/src/lib/netlist/plib/palloc.h b/src/lib/netlist/plib/palloc.h
index a12595e0027..1f4a5b083d9 100644
--- a/src/lib/netlist/plib/palloc.h
+++ b/src/lib/netlist/plib/palloc.h
@@ -8,7 +8,6 @@
#ifndef PALLOC_H_
#define PALLOC_H_
-#include <exception>
#include <vector>
#include <memory>
#include <utility>
@@ -17,59 +16,6 @@
#include "pstring.h"
namespace plib {
-//============================================================
-// exception base
-//============================================================
-
-class pexception : public std::exception
-{
-public:
- pexception(const pstring text);
- pexception(const pexception &e) : std::exception(e) { m_text = e.m_text; }
-
- virtual ~pexception() noexcept {}
-
- const pstring &text() { return m_text; }
-
-private:
- pstring m_text;
-};
-
-class file_e : public plib::pexception
-{
-public:
- explicit file_e(const pstring fmt, const pstring &filename);
-};
-
-class file_open_e : public file_e
-{
-public:
- explicit file_open_e(const pstring &filename);
-};
-
-class file_read_e : public file_e
-{
-public:
- explicit file_read_e(const pstring &filename);
-};
-
-class file_write_e : public file_e
-{
-public:
- explicit file_write_e(const pstring &filename);
-};
-
-class null_argument_e : public plib::pexception
-{
-public:
- explicit null_argument_e(const pstring &argument);
-};
-
-class out_of_mem_e : public plib::pexception
-{
-public:
- explicit out_of_mem_e(const pstring &location);
-};
//============================================================
// Memory allocation
diff --git a/src/lib/netlist/plib/pdynlib.cpp b/src/lib/netlist/plib/pdynlib.cpp
index 0ed2ca3a620..92f79f27702 100644
--- a/src/lib/netlist/plib/pdynlib.cpp
+++ b/src/lib/netlist/plib/pdynlib.cpp
@@ -62,8 +62,8 @@ dynlib::dynlib(const pstring libname)
: m_isLoaded(false), m_lib(nullptr)
{
#ifdef _WIN32
- //fprintf(stderr, "win: loading <%s>\n", libname.cstr());
- TCHAR *buffer = tstring_from_utf8(libname.cstr());
+ //fprintf(stderr, "win: loading <%s>\n", libname.c_str());
+ TCHAR *buffer = tstring_from_utf8(libname.c_str());
if (libname != "")
m_lib = LoadLibrary(buffer);
else
@@ -71,27 +71,27 @@ dynlib::dynlib(const pstring libname)
if (m_lib != nullptr)
m_isLoaded = true;
//else
- // fprintf(stderr, "win: library <%s> not found!\n", libname.cstr());
+ // fprintf(stderr, "win: library <%s> not found!\n", libname.c_str());
pfree_array(buffer);
#else
- //printf("loading <%s>\n", libname.cstr());
+ //printf("loading <%s>\n", libname.c_str());
if (libname != "")
- m_lib = dlopen(libname.cstr(), RTLD_LAZY);
+ m_lib = dlopen(libname.c_str(), RTLD_LAZY);
else
m_lib = dlopen(nullptr, RTLD_LAZY);
if (m_lib != nullptr)
m_isLoaded = true;
//else
- // printf("library <%s> not found: %s\n", libname.cstr(), dlerror());
+ // printf("library <%s> not found: %s\n", libname.c_str(), dlerror());
#endif
}
dynlib::dynlib(const pstring path, const pstring libname)
: m_isLoaded(false), m_lib(nullptr)
{
- // printf("win: loading <%s>\n", libname.cstr());
+ // printf("win: loading <%s>\n", libname.c_str());
#ifdef _WIN32
- TCHAR *buffer = tstring_from_utf8(libname.cstr());
+ TCHAR *buffer = tstring_from_utf8(libname.c_str());
if (libname != "")
m_lib = LoadLibrary(buffer);
else
@@ -100,20 +100,20 @@ dynlib::dynlib(const pstring path, const pstring libname)
m_isLoaded = true;
else
{
- //printf("win: library <%s> not found!\n", libname.cstr());
+ //printf("win: library <%s> not found!\n", libname.c_str());
}
pfree_array(buffer);
#else
- //printf("loading <%s>\n", libname.cstr());
+ //printf("loading <%s>\n", libname.c_str());
if (libname != "")
- m_lib = dlopen(libname.cstr(), RTLD_LAZY);
+ m_lib = dlopen(libname.c_str(), RTLD_LAZY);
else
m_lib = dlopen(nullptr, RTLD_LAZY);
if (m_lib != nullptr)
m_isLoaded = true;
else
{
- //printf("library <%s> not found!\n", libname.cstr());
+ //printf("library <%s> not found!\n", libname.c_str());
}
#endif
}
@@ -138,9 +138,9 @@ bool dynlib::isLoaded() const
void *dynlib::getsym_p(const pstring name)
{
#ifdef _WIN32
- return (void *) GetProcAddress((HMODULE) m_lib, name.cstr());
+ return (void *) GetProcAddress((HMODULE) m_lib, name.c_str());
#else
- return dlsym(m_lib, name.cstr());
+ return dlsym(m_lib, name.c_str());
#endif
}
diff --git a/src/lib/netlist/plib/pexception.cpp b/src/lib/netlist/plib/pexception.cpp
new file mode 100644
index 00000000000..2eedd6f9d16
--- /dev/null
+++ b/src/lib/netlist/plib/pexception.cpp
@@ -0,0 +1,143 @@
+// license:GPL-2.0+
+// copyright-holders:Couriersud
+/*
+ * palloc.c
+ *
+ */
+
+#include <cfenv>
+
+#include "pexception.h"
+#include "pfmtlog.h"
+
+#if (defined(__x86_64__) || defined(__i386__)) && defined(__linux__)
+#define HAS_FEENABLE_EXCEPT (1)
+#else
+#define HAS_FEENABLE_EXCEPT (0)
+#endif
+
+namespace plib {
+//============================================================
+// Exceptions
+//============================================================
+
+pexception::pexception(const pstring text)
+{
+ m_text = text;
+}
+
+pexception::~pexception() noexcept
+{
+}
+
+file_e::file_e(const pstring fmt, const pstring &filename)
+ : pexception(pfmt(fmt)(filename))
+{
+}
+
+file_e::~file_e() noexcept
+{
+}
+
+file_open_e::file_open_e(const pstring &filename)
+ : file_e("File open failed: {}", filename)
+{
+}
+
+file_open_e::~file_open_e() noexcept
+{
+
+}
+
+file_read_e::file_read_e(const pstring &filename)
+ : file_e("File read failed: {}", filename)
+{
+}
+
+file_read_e::~file_read_e() noexcept
+{
+
+}
+
+file_write_e::file_write_e(const pstring &filename)
+ : file_e("File write failed: {}", filename)
+{
+}
+
+file_write_e::~file_write_e() noexcept
+{
+}
+
+null_argument_e::null_argument_e(const pstring &argument)
+ : pexception(pfmt("Null argument passed: {}")(argument))
+{
+}
+
+null_argument_e::~null_argument_e() noexcept
+{
+}
+
+out_of_mem_e::out_of_mem_e(const pstring &location)
+ : pexception(pfmt("Out of memory: {}")(location))
+{
+}
+
+out_of_mem_e::~out_of_mem_e() noexcept
+{
+}
+
+fpexception_e::fpexception_e(const pstring &text)
+ : pexception(pfmt("Out of memory: {}")(text))
+{
+}
+
+fpexception_e::~fpexception_e() noexcept
+{
+}
+
+bool fpsignalenabler::m_enable = false;
+
+fpsignalenabler::fpsignalenabler(unsigned fpexceptions)
+{
+#if HAS_FEENABLE_EXCEPT
+ if (m_enable)
+ {
+ int b = 0;
+ if (fpexceptions & plib::FP_INEXACT) b = b | FE_INEXACT;
+ if (fpexceptions & plib::FP_DIVBYZERO) b = b | FE_DIVBYZERO;
+ if (fpexceptions & plib::FP_UNDERFLOW) b = b | FE_UNDERFLOW;
+ if (fpexceptions & plib::FP_OVERFLOW) b = b | FE_OVERFLOW;
+ if (fpexceptions & plib::FP_INVALID) b = b | FE_INVALID;
+ m_last_enabled = feenableexcept(b);
+ }
+#else
+ m_last_enabled = 0;
+#endif
+}
+
+
+fpsignalenabler::~fpsignalenabler()
+{
+#if HAS_FEENABLE_EXCEPT
+ if (m_enable)
+ {
+ fedisableexcept(FE_ALL_EXCEPT); // Enable all floating point exceptions but FE_INEXACT
+ feenableexcept(m_last_enabled); // Enable all floating point exceptions but FE_INEXACT
+ }
+#endif
+}
+
+bool fpsignalenabler::supported()
+{
+ return true;
+}
+
+bool fpsignalenabler::global_enable(bool enable)
+{
+ bool old = m_enable;
+ m_enable = enable;
+ return old;
+}
+
+
+}
diff --git a/src/lib/netlist/plib/pexception.h b/src/lib/netlist/plib/pexception.h
new file mode 100644
index 00000000000..a4d3b3c498f
--- /dev/null
+++ b/src/lib/netlist/plib/pexception.h
@@ -0,0 +1,126 @@
+// license:GPL-2.0+
+// copyright-holders:Couriersud
+/*
+ * palloc.h
+ *
+ */
+
+#ifndef PEXCEPTION_H_
+#define PEXCEPTION_H_
+
+#include <exception>
+
+#include "pconfig.h"
+#include "pstring.h"
+
+namespace plib {
+//============================================================
+// exception base
+//============================================================
+
+class pexception : public std::exception
+{
+public:
+ explicit pexception(const pstring text);
+ pexception(const pexception &e) : std::exception(e) { m_text = e.m_text; }
+
+ virtual ~pexception() noexcept;
+
+ const pstring &text() { return m_text; }
+
+private:
+ pstring m_text;
+};
+
+class file_e : public plib::pexception
+{
+public:
+ explicit file_e(const pstring fmt, const pstring &filename);
+ file_e(const file_e &e) : pexception(e) { }
+ virtual ~file_e() noexcept;
+};
+
+class file_open_e : public file_e
+{
+public:
+ explicit file_open_e(const pstring &filename);
+ file_open_e(const file_open_e &e) : file_e(e) { }
+ virtual ~file_open_e() noexcept;
+};
+
+class file_read_e : public file_e
+{
+public:
+ explicit file_read_e(const pstring &filename);
+ file_read_e(const file_read_e &e) : file_e(e) { }
+ virtual ~file_read_e() noexcept;
+};
+
+class file_write_e : public file_e
+{
+public:
+ explicit file_write_e(const pstring &filename);
+ file_write_e(const file_write_e &e) : file_e(e) { }
+ virtual ~file_write_e() noexcept;
+};
+
+class null_argument_e : public plib::pexception
+{
+public:
+ explicit null_argument_e(const pstring &argument);
+ null_argument_e(const null_argument_e &e) : pexception(e) { }
+ virtual ~null_argument_e() noexcept;
+};
+
+class out_of_mem_e : public plib::pexception
+{
+public:
+ explicit out_of_mem_e(const pstring &location);
+ out_of_mem_e(const out_of_mem_e &e) : pexception(e) { }
+ virtual ~out_of_mem_e() noexcept;
+};
+
+/* FIXME: currently only a stub for later use. More use could be added by
+ * using “-fnon-call-exceptions" and sigaction to enable c++ exception supported.
+ */
+
+class fpexception_e : public pexception
+{
+public:
+ fpexception_e(const pstring &text);
+ fpexception_e(const fpexception_e &e) : pexception(e) { }
+ virtual ~fpexception_e() noexcept;
+};
+
+static const unsigned FP_INEXACT = 0x0001;
+static const unsigned FP_DIVBYZERO = 0x0002;
+static const unsigned FP_UNDERFLOW = 0x0004;
+static const unsigned FP_OVERFLOW = 0x0008;
+static const unsigned FP_INVALID = 0x00010;
+static const unsigned FP_ALL = 0x0001f;
+
+/*
+ * Catch SIGFPE on linux for debugging purposes.
+ */
+
+class fpsignalenabler
+{
+public:
+ fpsignalenabler(unsigned fpexceptions);
+ ~fpsignalenabler();
+
+ /* is the functionality supported ? */
+ static bool supported();
+ /* returns last global enable state */
+ static bool global_enable(bool enable);
+
+private:
+ int m_last_enabled;
+
+ static bool m_enable;
+};
+
+
+}
+
+#endif /* PEXCEPTION_H_ */
diff --git a/src/lib/netlist/plib/pfmtlog.cpp b/src/lib/netlist/plib/pfmtlog.cpp
index 770a53af49d..48b0f1544c1 100644
--- a/src/lib/netlist/plib/pfmtlog.cpp
+++ b/src/lib/netlist/plib/pfmtlog.cpp
@@ -17,6 +17,11 @@
#include "palloc.h"
namespace plib {
+
+plog_dispatch_intf::~plog_dispatch_intf()
+{
+}
+
pfmt::pfmt(const pstring &fmt)
: m_str(m_str_buf), m_allocated(0), m_arg(0)
{
@@ -26,7 +31,7 @@ pfmt::pfmt(const pstring &fmt)
m_allocated = 2 * l;
m_str = palloc_array<char>(2 * l);
}
- memcpy(m_str, fmt.cstr(), l);
+ memcpy(m_str, fmt.c_str(), l);
}
pfmt::pfmt(const char *fmt)
diff --git a/src/lib/netlist/plib/pfmtlog.h b/src/lib/netlist/plib/pfmtlog.h
index 0e8b7f46946..c5369109b81 100644
--- a/src/lib/netlist/plib/pfmtlog.h
+++ b/src/lib/netlist/plib/pfmtlog.h
@@ -122,7 +122,7 @@ public:
P &operator ()(const char *x, const char *f = "") { format_element(f, "", "s", x); return static_cast<P &>(*this); }
P &operator ()(char *x, const char *f = "") { format_element(f, "", "s", x); return static_cast<P &>(*this); }
P &operator ()(const void *x, const char *f = "") { format_element(f, "", "p", x); return static_cast<P &>(*this); }
- P &operator ()(const pstring &x, const char *f = "") { format_element(f, "", "s", x.cstr() ); return static_cast<P &>(*this); }
+ P &operator ()(const pstring &x, const char *f = "") { format_element(f, "", "s", x.c_str() ); return static_cast<P &>(*this); }
template<typename T>
P &operator ()(const T x, const char *f = "")
@@ -263,7 +263,7 @@ class plog_dispatch_intf
template<plog_level::e, bool> friend class plog_channel;
public:
- virtual ~plog_dispatch_intf() { }
+ virtual ~plog_dispatch_intf();
protected:
virtual void vlog(const plog_level &l, const pstring &ls) const = 0;
};
diff --git a/src/lib/netlist/plib/poptions.cpp b/src/lib/netlist/plib/poptions.cpp
index 2060e8ec46c..a14d4ae93e7 100644
--- a/src/lib/netlist/plib/poptions.cpp
+++ b/src/lib/netlist/plib/poptions.cpp
@@ -22,11 +22,23 @@ namespace plib {
{
}
+ option_group::~option_group()
+ {
+ }
+
+ option_example::~option_example()
+ {
+ }
+
option::option(options &parent, pstring ashort, pstring along, pstring help, bool has_argument)
: option_base(parent, help), m_short(ashort), m_long(along), m_has_argument(has_argument)
{
}
+ option::~option()
+ {
+ }
+
int option_str::parse(pstring argument)
{
m_val = argument;
diff --git a/src/lib/netlist/plib/poptions.h b/src/lib/netlist/plib/poptions.h
index 3fac79b58ef..aa5ce07cbc8 100644
--- a/src/lib/netlist/plib/poptions.h
+++ b/src/lib/netlist/plib/poptions.h
@@ -39,6 +39,7 @@ class option_group : public option_base
public:
option_group(options &parent, pstring group, pstring help)
: option_base(parent, help), m_group(group) { }
+ ~option_group();
pstring group() { return m_group; }
private:
@@ -50,6 +51,7 @@ class option_example : public option_base
public:
option_example(options &parent, pstring group, pstring help)
: option_base(parent, help), m_example(group) { }
+ ~option_example();
pstring example() { return m_example; }
private:
@@ -61,6 +63,7 @@ class option : public option_base
{
public:
option(options &parent, pstring ashort, pstring along, pstring help, bool has_argument);
+ ~option();
/* no_argument options will be called with "" argument */
diff --git a/src/lib/netlist/plib/pparser.cpp b/src/lib/netlist/plib/pparser.cpp
index 0a19685316d..35629aacdee 100644
--- a/src/lib/netlist/plib/pparser.cpp
+++ b/src/lib/netlist/plib/pparser.cpp
@@ -15,6 +15,16 @@ namespace plib {
// A simple tokenizer
// ----------------------------------------------------------------------------------------
+ptokenizer::ptokenizer(pistream &strm)
+: m_strm(strm), m_lineno(0), m_cur_line(""), m_px(m_cur_line.begin()), m_unget(0), m_string('"')
+{
+}
+
+ptokenizer::~ptokenizer()
+{
+}
+
+
pstring ptokenizer::currentline_str()
{
return m_cur_line;
diff --git a/src/lib/netlist/plib/pparser.h b/src/lib/netlist/plib/pparser.h
index 301a4fc30a2..db88299d85c 100644
--- a/src/lib/netlist/plib/pparser.h
+++ b/src/lib/netlist/plib/pparser.h
@@ -22,11 +22,9 @@ class ptokenizer
{
P_PREVENT_COPYING(ptokenizer)
public:
- virtual ~ptokenizer() {}
+ explicit ptokenizer(pistream &strm);
- explicit ptokenizer(pistream &strm)
- : m_strm(strm), m_lineno(0), m_cur_line(""), m_px(m_cur_line.begin()), m_unget(0), m_string('"')
- {}
+ virtual ~ptokenizer();
enum token_type
{
diff --git a/src/lib/netlist/plib/pstate.cpp b/src/lib/netlist/plib/pstate.cpp
index ddfe0a37bc8..91869c26ba7 100644
--- a/src/lib/netlist/plib/pstate.cpp
+++ b/src/lib/netlist/plib/pstate.cpp
@@ -60,4 +60,9 @@ template<> void state_manager_t::save_item(const void *owner, callback_t &state,
state.register_state(*this, stname);
}
+state_manager_t::callback_t::~callback_t()
+{
+}
+
+
}
diff --git a/src/lib/netlist/plib/pstate.h b/src/lib/netlist/plib/pstate.h
index cd6c8efe38b..48420825164 100644
--- a/src/lib/netlist/plib/pstate.h
+++ b/src/lib/netlist/plib/pstate.h
@@ -62,7 +62,7 @@ public:
public:
using list_t = std::vector<callback_t *>;
- virtual ~callback_t() { }
+ virtual ~callback_t();
virtual void register_state(state_manager_t &manager, const pstring &module) = 0;
virtual void on_pre_save() = 0;
diff --git a/src/lib/netlist/plib/pstream.cpp b/src/lib/netlist/plib/pstream.cpp
index ad2010213f9..b05d86d7bc5 100644
--- a/src/lib/netlist/plib/pstream.cpp
+++ b/src/lib/netlist/plib/pstream.cpp
@@ -14,10 +14,19 @@
#include "palloc.h"
namespace plib {
+
+pstream::~pstream()
+{
+}
+
// -----------------------------------------------------------------------------
// pistream: input stream
// -----------------------------------------------------------------------------
+pistream::~pistream()
+{
+}
+
bool pistream::readline(pstring &line)
{
char c = 0;
@@ -44,6 +53,10 @@ bool pistream::readline(pstring &line)
// postream: output stream
// -----------------------------------------------------------------------------
+postream::~postream()
+{
+}
+
void postream::write(pistream &strm)
{
char buf[1024];
@@ -58,7 +71,7 @@ void postream::write(pistream &strm)
pifilestream::pifilestream(const pstring &fname)
: pistream(0)
-, m_file(fopen(fname.cstr(), "rb"))
+, m_file(fopen(fname.c_str(), "rb"))
, m_pos(0)
, m_actually_close(true)
, m_filename(fname)
@@ -142,12 +155,16 @@ pstdin::pstdin()
/* nothing to do */
}
+pstdin::~pstdin()
+{
+}
+
// -----------------------------------------------------------------------------
// Output file stream
// -----------------------------------------------------------------------------
pofilestream::pofilestream(const pstring &fname)
-: postream(0), m_file(fopen(fname.cstr(), "wb")), m_pos(0), m_actually_close(true), m_filename(fname)
+: postream(0), m_file(fopen(fname.c_str(), "wb")), m_pos(0), m_actually_close(true), m_filename(fname)
{
if (m_file == nullptr)
throw file_open_e(m_filename);
@@ -209,6 +226,11 @@ pstream::pos_type pofilestream::vtell()
return static_cast<pos_type>(ret);
}
+postringstream::~postringstream()
+{
+}
+
+
// -----------------------------------------------------------------------------
// pstderr: write to stderr
// -----------------------------------------------------------------------------
@@ -218,6 +240,10 @@ pstderr::pstderr()
{
}
+pstderr::~pstderr()
+{
+}
+
// -----------------------------------------------------------------------------
// pstdout: write to stdout
// -----------------------------------------------------------------------------
@@ -227,6 +253,10 @@ pstdout::pstdout()
{
}
+pstdout::~pstdout()
+{
+}
+
// -----------------------------------------------------------------------------
// Memory stream
// -----------------------------------------------------------------------------
@@ -273,6 +303,10 @@ pimemstream::pos_type pimemstream::vtell()
return m_pos;
}
+pistringstream::~pistringstream()
+{
+}
+
// -----------------------------------------------------------------------------
// Output memory stream
// -----------------------------------------------------------------------------
@@ -333,4 +367,9 @@ pstream::pos_type pomemstream::vtell()
return m_pos;
}
+pstream_fmt_writer_t::~pstream_fmt_writer_t()
+{
+}
+
+
}
diff --git a/src/lib/netlist/plib/pstream.h b/src/lib/netlist/plib/pstream.h
index 20aaab83a3a..6d02c4d1551 100644
--- a/src/lib/netlist/plib/pstream.h
+++ b/src/lib/netlist/plib/pstream.h
@@ -13,6 +13,7 @@
#include "pconfig.h"
#include "pstring.h"
#include "pfmtlog.h"
+#include "pexception.h"
namespace plib {
// -----------------------------------------------------------------------------
@@ -31,9 +32,7 @@ public:
explicit pstream(const unsigned flags) : m_flags(flags)
{
}
- virtual ~pstream()
- {
- }
+ virtual ~pstream();
bool seekable() const { return ((m_flags & FLAG_SEEKABLE) != 0); }
@@ -78,7 +77,7 @@ class pistream : public pstream
public:
explicit pistream(const unsigned flags) : pstream(flags) {}
- virtual ~pistream() {}
+ virtual ~pistream();
bool eof() const { return ((flags() & FLAG_EOF) != 0); }
@@ -114,7 +113,7 @@ class postream : public pstream
public:
explicit postream(unsigned flags) : pstream(flags) {}
- virtual ~postream() {}
+ virtual ~postream();
/* this digests linux & dos/windows text files */
@@ -126,7 +125,7 @@ public:
void write(const pstring &text)
{
- write(text.cstr(), text.blen());
+ write(text.c_str(), text.blen());
}
void write(const char c)
@@ -183,7 +182,7 @@ class postringstream : public postream
public:
postringstream() : postream(0) { }
- virtual ~postringstream() { }
+ virtual ~postringstream();
const pstringbuffer &str() { return m_buf; }
@@ -237,6 +236,7 @@ class pstderr : public pofilestream
P_PREVENT_COPYING(pstderr)
public:
pstderr();
+ virtual ~pstderr();
};
// -----------------------------------------------------------------------------
@@ -248,6 +248,7 @@ class pstdout : public pofilestream
P_PREVENT_COPYING(pstdout)
public:
pstdout();
+ virtual ~pstdout();
};
// -----------------------------------------------------------------------------
@@ -289,6 +290,7 @@ class pstdin : public pifilestream
public:
pstdin();
+ virtual ~pstdin();
};
// -----------------------------------------------------------------------------
@@ -324,8 +326,8 @@ class pistringstream : public pimemstream
{
P_PREVENT_COPYING(pistringstream)
public:
-
- pistringstream(const pstring &str) : pimemstream(str.cstr(), str.len()), m_str(str) { }
+ pistringstream(const pstring &str) : pimemstream(str.c_str(), str.len()), m_str(str) { }
+ virtual ~pistringstream();
private:
/* only needed for a reference till destruction */
@@ -342,7 +344,7 @@ class pstream_fmt_writer_t : public plib::pfmt_writer_t<>
public:
explicit pstream_fmt_writer_t(postream &strm) : m_strm(strm) {}
- virtual ~pstream_fmt_writer_t() { }
+ virtual ~pstream_fmt_writer_t();
protected:
virtual void vdowrite(const pstring &ls) const override
diff --git a/src/lib/netlist/plib/pstring.cpp b/src/lib/netlist/plib/pstring.cpp
index d42ef6f4400..2506357c9a5 100644
--- a/src/lib/netlist/plib/pstring.cpp
+++ b/src/lib/netlist/plib/pstring.cpp
@@ -46,7 +46,7 @@ void pstring_t<F>::pcat(const pstring_t &s)
if (m_ptr->len() > 0)
std::memcpy(n->str(), m_ptr->str(), m_ptr->len());
if (slen > 0)
- std::memcpy(n->str() + m_ptr->len(), s.cstr(), slen);
+ std::memcpy(n->str() + m_ptr->len(), s.c_str(), slen);
*(n->str() + n->len()) = 0;
sfree(m_ptr);
m_ptr = n;
@@ -65,7 +65,7 @@ int pstring_t<F>::pcmp(const pstring_t &right) const
else
return -1;
}
- int ret = memcmp(m_ptr->str(), right.cstr(), l);
+ int ret = memcmp(m_ptr->str(), right.c_str(), l);
if (ret == 0)
{
if (this->blen() > right.blen())
@@ -102,7 +102,7 @@ template<typename F>
const pstring_t<F> pstring_t<F>::ucase() const
{
pstring_t ret = *this;
- ret.pcopy(cstr(), blen());
+ ret.pcopy(c_str(), blen());
for (std::size_t i=0; i<ret.len(); i++)
ret.m_ptr->str()[i] = static_cast<char>(toupper(static_cast<int>(ret.m_ptr->str()[i])));
return ret;
@@ -230,7 +230,7 @@ double pstring_t<F>::as_double(bool *error) const
if (error != nullptr)
*error = false;
- ret = strtod(cstr(), &e);
+ ret = strtod(c_str(), &e);
if (*e != 0)
if (error != nullptr)
*error = true;
@@ -246,9 +246,9 @@ long pstring_t<F>::as_long(bool *error) const
if (error != nullptr)
*error = false;
if (startsWith("0x"))
- ret = strtol(substr(2).cstr(), &e, 16);
+ ret = strtol(substr(2).c_str(), &e, 16);
else
- ret = strtol(cstr(), &e, 10);
+ ret = strtol(c_str(), &e, 10);
if (*e != 0)
if (error != nullptr)
*error = true;
@@ -279,7 +279,7 @@ bool pstring_t<F>::startsWith(const pstring_t &arg) const
if (arg.blen() > blen())
return false;
else
- return (memcmp(arg.cstr(), cstr(), arg.blen()) == 0);
+ return (memcmp(arg.c_str(), c_str(), arg.blen()) == 0);
}
template<typename F>
@@ -288,7 +288,7 @@ bool pstring_t<F>::endsWith(const pstring_t &arg) const
if (arg.blen() > blen())
return false;
else
- return (memcmp(cstr()+this->blen()-arg.blen(), arg.cstr(), arg.blen()) == 0);
+ return (memcmp(c_str()+this->blen()-arg.blen(), arg.c_str(), arg.blen()) == 0);
}
@@ -299,7 +299,7 @@ bool pstring_t<F>::startsWith(const mem_t *arg) const
if (alen > blen())
return false;
else
- return (memcmp(arg, cstr(), alen) == 0);
+ return (memcmp(arg, c_str(), alen) == 0);
}
template<typename F>
@@ -351,7 +351,7 @@ void pstringbuffer::pcopy(const pstring &from)
{
std::size_t nl = from.blen() + 1;
resize(nl);
- std::memcpy(m_ptr, from.cstr(), nl);
+ std::memcpy(m_ptr, from.c_str(), nl);
}
void pstringbuffer::pcat(const char *s)
@@ -377,7 +377,7 @@ void pstringbuffer::pcat(const pstring &s)
const std::size_t slen = s.blen();
const std::size_t nl = m_len + slen + 1;
resize(nl);
- std::memcpy(m_ptr + m_len, s.cstr(), slen);
+ std::memcpy(m_ptr + m_len, s.c_str(), slen);
m_len += slen;
m_ptr[m_len] = 0;
}
diff --git a/src/lib/netlist/plib/pstring.h b/src/lib/netlist/plib/pstring.h
index 17132a5bf31..16bf61b08ee 100644
--- a/src/lib/netlist/plib/pstring.h
+++ b/src/lib/netlist/plib/pstring.h
@@ -90,7 +90,7 @@ public:
iterator end() const { return iterator(m_ptr->str() + blen()); }
// C string conversion helpers
- const mem_t *cstr() const { return m_ptr->str(); }
+ const mem_t *c_str() const { return m_ptr->str(); }
// concatenation operators
pstring_t& operator+=(const pstring_t &string) { pcat(string); return *this; }
@@ -356,7 +356,7 @@ public:
pstringbuffer &operator=(const pstringbuffer &string) { pcopy(string); return *this; }
// C string conversion helpers
- const char *cstr() const { return m_ptr; }
+ const char *c_str() const { return m_ptr; }
operator pstring() const { return pstring(m_ptr); }
@@ -405,7 +405,7 @@ namespace std
typedef std::size_t result_type;
result_type operator()(argument_type const& s) const
{
- const pstring::mem_t *string = s.cstr();
+ const pstring::mem_t *string = s.c_str();
result_type result = 5381;
for (pstring::mem_t c = *string; c != 0; c = *string++)
result = ((result << 5) + result ) ^ (result >> (32 - 5)) ^ static_cast<result_type>(c);
diff --git a/src/lib/netlist/plib/ptypes.h b/src/lib/netlist/plib/ptypes.h
index 2e2d19994e4..9c477f71944 100644
--- a/src/lib/netlist/plib/ptypes.h
+++ b/src/lib/netlist/plib/ptypes.h
@@ -57,7 +57,7 @@ namespace plib
ename (e v) : m_v(v) { } \
bool set_from_string (const pstring &s) { \
static const char *strings = # __VA_ARGS__; \
- int f = from_string_int(strings, s.cstr()); \
+ int f = from_string_int(strings, s.c_str()); \
if (f>=0) { m_v = static_cast<e>(f); return true; } else { return false; } \
} \
operator e() const {return m_v;} \
diff --git a/src/lib/netlist/plib/putil.cpp b/src/lib/netlist/plib/putil.cpp
index ad340017bc4..39e1b444f33 100644
--- a/src/lib/netlist/plib/putil.cpp
+++ b/src/lib/netlist/plib/putil.cpp
@@ -33,10 +33,10 @@ namespace plib
const pstring environment(const pstring &var, const pstring &default_val)
{
- if (getenv(var.cstr()) == nullptr)
+ if (getenv(var.c_str()) == nullptr)
return default_val;
else
- return pstring(getenv(var.cstr()));
+ return pstring(getenv(var.c_str()));
}
}
@@ -73,7 +73,7 @@ namespace plib
std::size_t p = static_cast<std::size_t>(-1);
for (std::size_t j=0; j < onstrl.size(); j++)
{
- if (std::memcmp(onstrl[j].cstr(), &(str.cstr()[i]), onstrl[j].blen())==0)
+ if (std::memcmp(onstrl[j].c_str(), &(str.c_str()[i]), onstrl[j].blen())==0)
{
p = j;
break;
@@ -90,7 +90,7 @@ namespace plib
}
else
{
- pstring::traits::code_t c = pstring::traits::code(str.cstr() + i);
+ pstring::traits::code_t c = pstring::traits::code(str.c_str() + i);
col += c;
i+=pstring::traits::codelen(c);
}
diff --git a/src/lib/netlist/plib/putil.h b/src/lib/netlist/plib/putil.h
index cc388cd3393..9e79e958927 100644
--- a/src/lib/netlist/plib/putil.h
+++ b/src/lib/netlist/plib/putil.h
@@ -45,6 +45,11 @@ namespace plib
con.insert(con.begin() + static_cast<std::ptrdiff_t>(index), elem);
}
+ template <class C>
+ void remove(C &con, const typename C::value_type &elem)
+ {
+ con.erase(std::remove(con.begin(), con.end(), elem), con.end());
+ }
}
template <class C>
diff --git a/src/lib/netlist/prg/nltool.cpp b/src/lib/netlist/prg/nltool.cpp
index fbfa3a50c5c..f96fd423530 100644
--- a/src/lib/netlist/prg/nltool.cpp
+++ b/src/lib/netlist/prg/nltool.cpp
@@ -15,12 +15,15 @@
#include "plib/pstring.h"
#include "plib/plists.h"
#include "plib/ptypes.h"
+#include "plib/pexception.h"
#include "nl_setup.h"
#include "nl_factory.h"
#include "nl_parser.h"
#include "devices/net_lib.h"
#include "tools/nl_convert.h"
+#include <cfenv>
+
class tool_options_t : public plib::options
{
public:
@@ -99,25 +102,26 @@ public:
{
}
- virtual std::unique_ptr<plib::pistream> stream(const pstring &file) override
- {
- pstring name = m_folder + "/" + file;
- try
- {
- auto strm = plib::make_unique_base<plib::pistream, plib::pifilestream>(name);
- return strm;
- }
- catch (plib::pexception e)
- {
-
- }
- return std::unique_ptr<plib::pistream>(nullptr);
- }
+ virtual std::unique_ptr<plib::pistream> stream(const pstring &file) override;
private:
pstring m_folder;
};
+std::unique_ptr<plib::pistream> netlist_data_folder_t::stream(const pstring &file)
+{
+ pstring name = m_folder + "/" + file;
+ try
+ {
+ auto strm = plib::make_unique_base<plib::pistream, plib::pifilestream>(name);
+ return strm;
+ }
+ catch (plib::pexception e)
+ {
+
+ }
+ return std::unique_ptr<plib::pistream>(nullptr);
+}
class netlist_tool_t : public netlist::netlist_t
{
@@ -179,18 +183,20 @@ public:
protected:
- void vlog(const plib::plog_level &l, const pstring &ls) const override
- {
- pstring err = plib::pfmt("{}: {}\n")(l.name())(ls.cstr());
- pout("{}", err);
- if (l == plib::plog_level::FATAL)
- throw netlist::nl_exception(err);
- }
+ void vlog(const plib::plog_level &l, const pstring &ls) const override;
private:
netlist::setup_t *m_setup;
};
+void netlist_tool_t::vlog(const plib::plog_level &l, const pstring &ls) const
+{
+ pstring err = plib::pfmt("{}: {}\n")(l.name())(ls.c_str());
+ pout("{}", err);
+ if (l == plib::plog_level::FATAL)
+ throw netlist::nl_exception(err);
+}
+
// FIXME: usage should go elsewhere
void usage(tool_options_t &opts);
@@ -199,7 +205,7 @@ void usage(tool_options_t &opts)
{
pout("{}\n", opts.help(
"nltool serves as the Swiss Army knife to run, test and convert netlists.",
- "nltool [options]").cstr());
+ "nltool [options]").c_str());
}
struct input_t
@@ -214,7 +220,7 @@ struct input_t
{
char buf[400];
double t;
- int e = sscanf(line.cstr(), "%lf,%[^,],%lf", &t, buf, &m_value);
+ int e = sscanf(line.c_str(), "%lf,%[^,],%lf", &t, buf, &m_value);
if ( e!= 3)
throw netlist::nl_exception(plib::pfmt("error {1} scanning line {2}\n")(e)(line));
m_time = netlist::netlist_time::from_double(t);
@@ -346,7 +352,7 @@ static void listdevices(tool_options_t &opts)
if (opts.opt_quiet())
nt.log().warning.set_enabled(false);
- netlist::factory_list_t &list = nt.setup().factory();
+ netlist::factory::list_t &list = nt.setup().factory();
nt.setup().register_source(plib::make_unique_base<netlist::source_t,
netlist::source_proc_t>(nt.setup(), "dummy", &netlist_dummy));
@@ -363,6 +369,7 @@ static void listdevices(tool_options_t &opts)
pstring out = plib::pfmt("{1} {2}(<id>")(f->classname(),"-20")(f->name());
std::vector<pstring> terms;
+ f->macro_actions(nt.setup().netlist(), f->name() + "_lc");
auto d = f->Create(nt.setup().netlist(), f->name() + "_lc");
// get the list of terminals ...
@@ -381,10 +388,12 @@ static void listdevices(tool_options_t &opts)
if (t.first.startsWith(d->name()))
{
pstring tn(t.first.substr(d->name().len()+1));
+ //printf("\t%s %s %s\n", t.first.c_str(), t.second.c_str(), tn.c_str());
if (tn.find(".") == tn.end())
{
terms.push_back(tn);
pstring resolved = nt.setup().resolve_alias(t.first);
+ //printf("\t%s %s %s\n", t.first.c_str(), t.second.c_str(), resolved.c_str());
if (resolved != t.first)
{
auto found = std::find(terms.begin(), terms.end(), resolved.substr(d->name().len()+1));
@@ -395,27 +404,22 @@ static void listdevices(tool_options_t &opts)
}
}
- if (f->param_desc().startsWith("+"))
- {
- out += "," + f->param_desc().substr(1);
- terms.clear();
- }
- else if (f->param_desc() == "-")
- {
- /* no params at all */
- }
- else
+ out += "," + f->param_desc();
+ for (auto p : plib::pstring_vector_t(f->param_desc(),",") )
{
- out += "," + f->param_desc();
+ if (p.startsWith("+"))
+ {
+ plib::container::remove(terms, p.substr(1));
+ }
}
out += ")";
- printf("%s\n", out.cstr());
+ printf("%s\n", out.c_str());
if (terms.size() > 0)
{
pstring t = "";
for (auto & j : terms)
t += "," + j;
- printf("Terminals: %s\n", t.substr(1).cstr());
+ printf("\tTerminals: %s\n", t.substr(1).c_str());
}
devs.push_back(std::move(d));
}
@@ -442,8 +446,13 @@ int main(int argc, char *argv[])
tool_options_t opts;
int ret;
+ /* make SIGFPE actually deliver signals on supoorted platforms */
+ plib::fpsignalenabler::global_enable(true);
+ plib::fpsignalenabler sigen(plib::FP_ALL & ~plib::FP_INEXACT & ~plib::FP_UNDERFLOW);
+
//perr("{}", "WARNING: This is Work In Progress! - It may fail anytime\n");
//perr("Update dispatching using method {}\n", pmf_verbose[NL_PMF_TYPE]);
+ //printf("test2 %f\n", std::exp(-14362.38064713));
if ((ret = opts.parse(argc, argv)) != argc)
{
perr("Error parsing {}\n", argv[ret]);
@@ -514,11 +523,11 @@ int main(int argc, char *argv[])
result = c.result();
}
/* present result */
- pout_strm.write(result.cstr());
+ pout_strm.write(result.c_str());
}
else
{
- perr("Unknown command {}\n", cmd.cstr());
+ perr("Unknown command {}\n", cmd.c_str());
usage(opts);
return 1;
}
diff --git a/src/lib/netlist/prg/nlwav.cpp b/src/lib/netlist/prg/nlwav.cpp
index ea5fc450f2b..32ca8c6e173 100644
--- a/src/lib/netlist/prg/nlwav.cpp
+++ b/src/lib/netlist/prg/nlwav.cpp
@@ -148,7 +148,7 @@ static void convert(nlwav_options_t &opts)
{
#if 1
double t = 0.0; double v = 0.0;
- sscanf(line.cstr(), "%lf %lf", &t, &v);
+ sscanf(line.c_str(), "%lf %lf", &t, &v);
while (t >= ct)
{
outsam += (ct - lt) * cursam;
@@ -203,7 +203,7 @@ static void convert(nlwav_options_t &opts)
static void usage(plib::pstream_fmt_writer_t &fw, nlwav_options_t &opts)
{
fw("{}\n", opts.help("Convert netlist log files into wav files.\n",
- "nltool [options]").cstr());
+ "nltool [options]").c_str());
}
diff --git a/src/lib/netlist/solver/nld_matrix_solver.cpp b/src/lib/netlist/solver/nld_matrix_solver.cpp
new file mode 100644
index 00000000000..d6032e65912
--- /dev/null
+++ b/src/lib/netlist/solver/nld_matrix_solver.cpp
@@ -0,0 +1,562 @@
+// license:GPL-2.0+
+// copyright-holders:Couriersud
+/*
+ * nld_matrix_solver.cpp
+ *
+ */
+
+#include "nld_matrix_solver.h"
+#include "plib/putil.h"
+
+namespace netlist
+{
+ namespace devices
+ {
+
+proxied_analog_output_t::~proxied_analog_output_t()
+{
+}
+
+terms_t::terms_t()
+ : m_railstart(0)
+ , m_last_V(0.0)
+ , m_DD_n_m_1(0.0)
+ , m_h_n_m_1(1e-9)
+{
+}
+
+void terms_t::clear()
+{
+ m_term.clear();
+ m_net_other.clear();
+ m_gt.clear();
+ m_go.clear();
+ m_Idr.clear();
+ m_other_curanalog.clear();
+}
+
+void terms_t::add(terminal_t *term, int net_other, bool sorted)
+{
+ if (sorted)
+ for (unsigned i=0; i < m_net_other.size(); i++)
+ {
+ if (m_net_other[i] > net_other)
+ {
+ plib::container::insert_at(m_term, i, term);
+ plib::container::insert_at(m_net_other, i, net_other);
+ plib::container::insert_at(m_gt, i, 0.0);
+ plib::container::insert_at(m_go, i, 0.0);
+ plib::container::insert_at(m_Idr, i, 0.0);
+ plib::container::insert_at(m_other_curanalog, i, nullptr);
+ return;
+ }
+ }
+ m_term.push_back(term);
+ m_net_other.push_back(net_other);
+ m_gt.push_back(0.0);
+ m_go.push_back(0.0);
+ m_Idr.push_back(0.0);
+ m_other_curanalog.push_back(nullptr);
+}
+
+void terms_t::set_pointers()
+{
+ for (unsigned i = 0; i < count(); i++)
+ {
+ m_term[i]->set_ptrs(&m_gt[i], &m_go[i], &m_Idr[i]);
+ m_other_curanalog[i] = m_term[i]->m_otherterm->net().m_cur_Analog.ptr();
+ }
+}
+
+// ----------------------------------------------------------------------------------------
+// matrix_solver
+// ----------------------------------------------------------------------------------------
+
+matrix_solver_t::matrix_solver_t(netlist_t &anetlist, const pstring &name,
+ const eSortType sort, const solver_parameters_t *params)
+ : device_t(anetlist, name)
+ , m_params(*params)
+ , m_stat_calculations(*this, "m_stat_calculations", 0)
+ , m_stat_newton_raphson(*this, "m_stat_newton_raphson", 0)
+ , m_stat_vsolver_calls(*this, "m_stat_vsolver_calls", 0)
+ , m_iterative_fail(*this, "m_iterative_fail", 0)
+ , m_iterative_total(*this, "m_iterative_total", 0)
+ , m_last_step(*this, "m_last_step", netlist_time::zero())
+ , m_fb_sync(*this, "FB_sync")
+ , m_Q_sync(*this, "Q_sync")
+ , m_sort(sort)
+{
+ connect_post_start(m_fb_sync, m_Q_sync);
+}
+
+matrix_solver_t::~matrix_solver_t()
+{
+ for (unsigned k = 0; k < m_terms.size(); k++)
+ {
+ plib::pfree(m_terms[k]);
+ }
+
+}
+
+void matrix_solver_t::setup_base(analog_net_t::list_t &nets)
+{
+ log().debug("New solver setup\n");
+
+ m_nets.clear();
+ m_terms.clear();
+
+ for (auto & net : nets)
+ {
+ m_nets.push_back(net);
+ m_terms.push_back(plib::palloc<terms_t>());
+ m_rails_temp.push_back(plib::palloc<terms_t>());
+ }
+
+ for (std::size_t k = 0; k < nets.size(); k++)
+ {
+ analog_net_t *net = nets[k];
+
+ log().debug("setting up net\n");
+
+ net->set_solver(this);
+
+ for (auto &p : net->m_core_terms)
+ {
+ log().debug("{1} {2} {3}\n", p->name(), net->name(), net->isRailNet());
+ switch (p->type())
+ {
+ case terminal_t::TERMINAL:
+ if (p->device().is_timestep())
+ if (!plib::container::contains(m_step_devices, &p->device()))
+ m_step_devices.push_back(&p->device());
+ if (p->device().is_dynamic())
+ if (!plib::container::contains(m_dynamic_devices, &p->device()))
+ m_dynamic_devices.push_back(&p->device());
+ {
+ terminal_t *pterm = dynamic_cast<terminal_t *>(p);
+ add_term(k, pterm);
+ }
+ log().debug("Added terminal {1}\n", p->name());
+ break;
+ case terminal_t::INPUT:
+ {
+ proxied_analog_output_t *net_proxy_output = nullptr;
+ for (auto & input : m_inps)
+ if (input->m_proxied_net == &p->net())
+ {
+ net_proxy_output = input.get();
+ break;
+ }
+
+ if (net_proxy_output == nullptr)
+ {
+ auto net_proxy_output_u = plib::make_unique<proxied_analog_output_t>(*this, this->name() + "." + plib::pfmt("m{1}")(m_inps.size()));
+ net_proxy_output = net_proxy_output_u.get();
+ m_inps.push_back(std::move(net_proxy_output_u));
+ nl_assert(p->net().is_analog());
+ net_proxy_output->m_proxied_net = static_cast<analog_net_t *>(&p->net());
+ }
+ net_proxy_output->net().add_terminal(*p);
+ // FIXME: repeated
+ net_proxy_output->net().rebuild_list();
+ log().debug("Added input\n");
+ }
+ break;
+ case terminal_t::OUTPUT:
+ case terminal_t::PARAM:
+ log().fatal("unhandled element found\n");
+ break;
+ }
+ }
+ log().debug("added net with {1} populated connections\n", net->m_core_terms.size());
+ }
+
+ /* now setup the matrix */
+ setup_matrix();
+}
+
+void matrix_solver_t::setup_matrix()
+{
+ const std::size_t iN = m_nets.size();
+
+ for (std::size_t k = 0; k < iN; k++)
+ {
+ m_terms[k]->m_railstart = m_terms[k]->count();
+ for (std::size_t i = 0; i < m_rails_temp[k]->count(); i++)
+ this->m_terms[k]->add(m_rails_temp[k]->terms()[i], m_rails_temp[k]->net_other()[i], false);
+
+ m_rails_temp[k]->clear(); // no longer needed
+ m_terms[k]->set_pointers();
+ }
+
+ for (unsigned k = 0; k < iN; k++)
+ plib::pfree(m_rails_temp[k]); // no longer needed
+
+ m_rails_temp.clear();
+
+ /* Sort in descending order by number of connected matrix voltages.
+ * The idea is, that for Gauss-Seidel algo the first voltage computed
+ * depends on the greatest number of previous voltages thus taking into
+ * account the maximum amout of information.
+ *
+ * This actually improves performance on popeye slightly. Average
+ * GS computations reduce from 2.509 to 2.370
+ *
+ * Smallest to largest : 2.613
+ * Unsorted : 2.509
+ * Largest to smallest : 2.370
+ *
+ * Sorting as a general matrix pre-conditioning is mentioned in
+ * literature but I have found no articles about Gauss Seidel.
+ *
+ * For Gaussian Elimination however increasing order is better suited.
+ * FIXME: Even better would be to sort on elements right of the matrix diagonal.
+ *
+ */
+
+ if (m_sort != NOSORT)
+ {
+ int sort_order = (m_sort == DESCENDING ? 1 : -1);
+
+ for (unsigned k = 0; k < iN - 1; k++)
+ for (unsigned i = k+1; i < iN; i++)
+ {
+ if ((static_cast<int>(m_terms[k]->m_railstart) - static_cast<int>(m_terms[i]->m_railstart)) * sort_order < 0)
+ {
+ std::swap(m_terms[i], m_terms[k]);
+ std::swap(m_nets[i], m_nets[k]);
+ }
+ }
+
+ for (unsigned k = 0; k < iN; k++)
+ {
+ int *other = m_terms[k]->net_other();
+ for (unsigned i = 0; i < m_terms[k]->count(); i++)
+ if (other[i] != -1)
+ other[i] = get_net_idx(&m_terms[k]->terms()[i]->m_otherterm->net());
+ }
+ }
+
+ /* create a list of non zero elements. */
+ for (unsigned k = 0; k < iN; k++)
+ {
+ terms_t * t = m_terms[k];
+ /* pretty brutal */
+ int *other = t->net_other();
+
+ t->m_nz.clear();
+
+ for (unsigned i = 0; i < t->m_railstart; i++)
+ if (!plib::container::contains(t->m_nz, static_cast<unsigned>(other[i])))
+ t->m_nz.push_back(static_cast<unsigned>(other[i]));
+
+ t->m_nz.push_back(k); // add diagonal
+
+ /* and sort */
+ std::sort(t->m_nz.begin(), t->m_nz.end());
+ }
+
+ /* create a list of non zero elements right of the diagonal
+ * These list anticipate the population of array elements by
+ * Gaussian elimination.
+ */
+ for (unsigned k = 0; k < iN; k++)
+ {
+ terms_t * t = m_terms[k];
+ /* pretty brutal */
+ int *other = t->net_other();
+
+ if (k==0)
+ t->m_nzrd.clear();
+ else
+ {
+ t->m_nzrd = m_terms[k-1]->m_nzrd;
+ for (auto j = t->m_nzrd.begin(); j != t->m_nzrd.end(); )
+ {
+ if (*j < k + 1)
+ j = t->m_nzrd.erase(j);
+ else
+ ++j;
+ }
+ }
+
+ for (unsigned i = 0; i < t->m_railstart; i++)
+ if (!plib::container::contains(t->m_nzrd, static_cast<unsigned>(other[i])) && other[i] >= static_cast<int>(k + 1))
+ t->m_nzrd.push_back(static_cast<unsigned>(other[i]));
+
+ /* and sort */
+ std::sort(t->m_nzrd.begin(), t->m_nzrd.end());
+ }
+
+ /* create a list of non zero elements below diagonal k
+ * This should reduce cache misses ...
+ */
+
+ bool **touched = new bool*[iN];
+ for (unsigned k=0; k<iN; k++)
+ touched[k] = new bool[iN];
+
+ for (unsigned k = 0; k < iN; k++)
+ {
+ for (unsigned j = 0; j < iN; j++)
+ touched[k][j] = false;
+ for (unsigned j = 0; j < m_terms[k]->m_nz.size(); j++)
+ touched[k][m_terms[k]->m_nz[j]] = true;
+ }
+
+ unsigned ops = 0;
+ for (unsigned k = 0; k < iN; k++)
+ {
+ ops++; // 1/A(k,k)
+ for (unsigned row = k + 1; row < iN; row++)
+ {
+ if (touched[row][k])
+ {
+ ops++;
+ if (!plib::container::contains(m_terms[k]->m_nzbd, row))
+ m_terms[k]->m_nzbd.push_back(row);
+ for (unsigned col = k + 1; col < iN; col++)
+ if (touched[k][col])
+ {
+ touched[row][col] = true;
+ ops += 2;
+ }
+ }
+ }
+ }
+ log().verbose("Number of mults/adds for {1}: {2}", name(), ops);
+
+ if ((0))
+ for (unsigned k = 0; k < iN; k++)
+ {
+ pstring line = plib::pfmt("{1}")(k, "3");
+ for (unsigned j = 0; j < m_terms[k]->m_nzrd.size(); j++)
+ line += plib::pfmt(" {1}")(m_terms[k]->m_nzrd[j], "3");
+ log().verbose("{1}", line);
+ }
+
+ /*
+ * save states
+ */
+ for (unsigned k = 0; k < iN; k++)
+ {
+ pstring num = plib::pfmt("{1}")(k);
+
+ netlist().save(*this, m_terms[k]->m_last_V, "lastV." + num);
+ netlist().save(*this, m_terms[k]->m_DD_n_m_1, "m_DD_n_m_1." + num);
+ netlist().save(*this, m_terms[k]->m_h_n_m_1, "m_h_n_m_1." + num);
+
+ netlist().save(*this, m_terms[k]->go(),"GO" + num, m_terms[k]->count());
+ netlist().save(*this, m_terms[k]->gt(),"GT" + num, m_terms[k]->count());
+ netlist().save(*this, m_terms[k]->Idr(),"IDR" + num , m_terms[k]->count());
+ }
+
+ for (unsigned k=0; k<iN; k++)
+ delete [] touched[k];
+ delete [] touched;
+}
+
+void matrix_solver_t::update_inputs()
+{
+ // avoid recursive calls. Inputs are updated outside this call
+ for (auto &inp : m_inps)
+ inp->push(inp->m_proxied_net->Q_Analog());
+}
+
+void matrix_solver_t::update_dynamic()
+{
+ /* update all non-linear devices */
+ for (auto &dyn : m_dynamic_devices)
+ dyn->update_terminals();
+}
+
+void matrix_solver_t::reset()
+{
+ m_last_step = netlist_time::zero();
+}
+
+void matrix_solver_t::update() NL_NOEXCEPT
+{
+ const netlist_time new_timestep = solve();
+
+ if (m_params.m_dynamic && has_timestep_devices() && new_timestep > netlist_time::zero())
+ {
+ m_Q_sync.net().force_queue_execution();
+ m_Q_sync.net().reschedule_in_queue(new_timestep);
+ }
+}
+
+void matrix_solver_t::update_forced()
+{
+ ATTR_UNUSED const netlist_time new_timestep = solve();
+
+ if (m_params.m_dynamic && has_timestep_devices())
+ {
+ m_Q_sync.net().force_queue_execution();
+ m_Q_sync.net().reschedule_in_queue(netlist_time::from_double(m_params.m_min_timestep));
+ }
+}
+
+void matrix_solver_t::step(const netlist_time &delta)
+{
+ const nl_double dd = delta.as_double();
+ for (std::size_t k=0; k < m_step_devices.size(); k++)
+ m_step_devices[k]->timestep(dd);
+}
+
+void matrix_solver_t::solve_base()
+{
+ m_stat_vsolver_calls++;
+ if (has_dynamic_devices())
+ {
+ unsigned this_resched;
+ unsigned newton_loops = 0;
+ do
+ {
+ update_dynamic();
+ // Gauss-Seidel will revert to Gaussian elemination if steps exceeded.
+ this_resched = this->vsolve_non_dynamic(true);
+ newton_loops++;
+ } while (this_resched > 1 && newton_loops < m_params.m_nr_loops);
+
+ m_stat_newton_raphson += newton_loops;
+ // reschedule ....
+ if (this_resched > 1 && !m_Q_sync.net().is_queued())
+ {
+ log().warning("NEWTON_LOOPS exceeded on net {1}... reschedule", this->name());
+ m_Q_sync.net().toggle_new_Q();
+ m_Q_sync.net().reschedule_in_queue(m_params.m_nt_sync_delay);
+ }
+ }
+ else
+ {
+ this->vsolve_non_dynamic(false);
+ }
+}
+
+const netlist_time matrix_solver_t::solve()
+{
+ const netlist_time now = netlist().time();
+ const netlist_time delta = now - m_last_step;
+
+ // We are already up to date. Avoid oscillations.
+ // FIXME: Make this a parameter!
+ if (delta < netlist_time::quantum())
+ return netlist_time::zero();
+
+ /* update all terminals for new time step */
+ m_last_step = now;
+ step(delta);
+ solve_base();
+ const netlist_time next_time_step = compute_next_timestep(delta.as_double());
+
+ update_inputs();
+
+ return next_time_step;
+}
+
+int matrix_solver_t::get_net_idx(detail::net_t *net)
+{
+ for (std::size_t k = 0; k < m_nets.size(); k++)
+ if (m_nets[k] == net)
+ return static_cast<int>(k);
+ return -1;
+}
+
+void matrix_solver_t::add_term(std::size_t k, terminal_t *term)
+{
+ if (term->m_otherterm->net().isRailNet())
+ {
+ m_rails_temp[k]->add(term, -1, false);
+ }
+ else
+ {
+ int ot = get_net_idx(&term->m_otherterm->net());
+ if (ot>=0)
+ {
+ m_terms[k]->add(term, ot, true);
+ }
+ /* Should this be allowed ? */
+ else // if (ot<0)
+ {
+ m_rails_temp[k]->add(term, ot, true);
+ log().fatal("found term with missing othernet {1}\n", term->name());
+ }
+ }
+}
+
+netlist_time matrix_solver_t::compute_next_timestep(const double cur_ts)
+{
+ nl_double new_solver_timestep = m_params.m_max_timestep;
+
+ if (m_params.m_dynamic)
+ {
+ /*
+ * FIXME: We should extend the logic to use either all nets or
+ * only output nets.
+ */
+ for (std::size_t k = 0, iN=m_terms.size(); k < iN; k++)
+ {
+ analog_net_t *n = m_nets[k];
+ terms_t *t = m_terms[k];
+
+ const nl_double DD_n = (n->Q_Analog() - t->m_last_V);
+ const nl_double hn = cur_ts;
+
+ //printf("%f %f %f %f\n", DD_n, t->m_DD_n_m_1, hn, t->m_h_n_m_1);
+ nl_double DD2 = (DD_n / hn - t->m_DD_n_m_1 / t->m_h_n_m_1) / (hn + t->m_h_n_m_1);
+ nl_double new_net_timestep;
+
+ t->m_h_n_m_1 = hn;
+ t->m_DD_n_m_1 = DD_n;
+ if (std::fabs(DD2) > NL_FCONST(1e-60)) // avoid div-by-zero
+ new_net_timestep = std::sqrt(m_params.m_lte / std::fabs(NL_FCONST(0.5)*DD2));
+ else
+ new_net_timestep = m_params.m_max_timestep;
+
+ if (new_net_timestep < new_solver_timestep)
+ new_solver_timestep = new_net_timestep;
+
+ t->m_last_V = n->Q_Analog();
+ }
+ if (new_solver_timestep < m_params.m_min_timestep)
+ {
+ //log().warning("Dynamic timestep below min timestep. Consider decreasing MIN_TIMESTEP: {1} us", new_solver_timestep*1.0e6);
+ new_solver_timestep = m_params.m_min_timestep;
+ }
+ }
+ //if (new_solver_timestep > 10.0 * hn)
+ // new_solver_timestep = 10.0 * hn;
+ /*
+ * FIXME: Factor 2 below is important. Without, we get timing issues. This must be a bug elsewhere.
+ */
+ return std::max(netlist_time::from_double(new_solver_timestep), netlist_time::quantum() * 2);
+}
+
+
+
+void matrix_solver_t::log_stats()
+{
+ if (this->m_stat_calculations != 0 && this->m_stat_vsolver_calls && this->m_params.m_log_stats)
+ {
+ log().verbose("==============================================");
+ log().verbose("Solver {1}", this->name());
+ log().verbose(" ==> {1} nets", this->m_nets.size()); //, (*(*groups[i].first())->m_core_terms.first())->name());
+ log().verbose(" has {1} elements", this->has_dynamic_devices() ? "dynamic" : "no dynamic");
+ log().verbose(" has {1} elements", this->has_timestep_devices() ? "timestep" : "no timestep");
+ log().verbose(" {1:6.3} average newton raphson loops",
+ static_cast<double>(this->m_stat_newton_raphson) / static_cast<double>(this->m_stat_vsolver_calls));
+ log().verbose(" {1:10} invocations ({2:6.0} Hz) {3:10} gs fails ({4:6.2} %) {5:6.3} average",
+ this->m_stat_calculations(),
+ static_cast<double>(this->m_stat_calculations()) / this->netlist().time().as_double(),
+ this->m_iterative_fail(),
+ 100.0 * static_cast<double>(this->m_iterative_fail())
+ / static_cast<double>(this->m_stat_calculations()),
+ static_cast<double>(this->m_iterative_total()) / static_cast<double>(this->m_stat_calculations()));
+ }
+}
+
+
+ } //namespace devices
+} // namespace netlist
+
diff --git a/src/lib/netlist/solver/nld_matrix_solver.h b/src/lib/netlist/solver/nld_matrix_solver.h
index 36e39462c17..aa3f7e86bfa 100644
--- a/src/lib/netlist/solver/nld_matrix_solver.h
+++ b/src/lib/netlist/solver/nld_matrix_solver.h
@@ -41,22 +41,9 @@ class terms_t
P_PREVENT_COPYING(terms_t)
public:
- terms_t()
- : m_railstart(0)
- , m_last_V(0.0)
- , m_DD_n_m_1(0.0)
- , m_h_n_m_1(1e-6)
- {}
-
- void clear()
- {
- m_term.clear();
- m_net_other.clear();
- m_gt.clear();
- m_go.clear();
- m_Idr.clear();
- m_other_curanalog.clear();
- }
+ terms_t();
+
+ void clear();
void add(terminal_t *term, int net_other, bool sorted);
@@ -100,6 +87,7 @@ public:
: analog_output_t(dev, aname)
, m_proxied_net(nullptr)
{ }
+ virtual ~proxied_analog_output_t();
analog_net_t *m_proxied_net; // only for proxy nets in analog input logic
};
@@ -118,21 +106,7 @@ public:
};
matrix_solver_t(netlist_t &anetlist, const pstring &name,
- const eSortType sort, const solver_parameters_t *params)
- : device_t(anetlist, name)
- , m_params(*params)
- , m_stat_calculations(*this, "m_stat_calculations", 0)
- , m_stat_newton_raphson(*this, "m_stat_newton_raphson", 0)
- , m_stat_vsolver_calls(*this, "m_stat_vsolver_calls", 0)
- , m_iterative_fail(*this, "m_iterative_fail", 0)
- , m_iterative_total(*this, "m_iterative_total", 0)
- , m_last_step(*this, "m_last_step", netlist_time::zero())
- , m_fb_sync(*this, "FB_sync")
- , m_Q_sync(*this, "Q_sync")
- , m_sort(sort)
- {
- connect_post_start(m_fb_sync, m_Q_sync);
- }
+ const eSortType sort, const solver_parameters_t *params);
virtual ~matrix_solver_t();
diff --git a/src/lib/netlist/solver/nld_ms_w.h b/src/lib/netlist/solver/nld_ms_w.h
index 55d9d630224..e644ce40085 100644
--- a/src/lib/netlist/solver/nld_ms_w.h
+++ b/src/lib/netlist/solver/nld_ms_w.h
@@ -300,7 +300,7 @@ unsigned matrix_solver_w_t<m_N, storage_N>::solve_non_dynamic(const bool newton_
for (unsigned i = 0; i < rowcount; i++)
{
if (H[i][i] == 0.0)
- printf("%s H singular\n", this->name().cstr());
+ printf("%s H singular\n", this->name().c_str());
const nl_double f = 1.0 / H[i][i];
for (unsigned j = i+1; j < rowcount; j++)
{
@@ -355,7 +355,7 @@ unsigned matrix_solver_w_t<m_N, storage_N>::solve_non_dynamic(const bool newton_
tmp += A(i,j) * new_V[j];
}
if (std::abs(tmp-RHS(i)) > 1e-6)
- printf("%s failed on row %d: %f RHS: %f\n", this->name().cstr(), i, std::abs(tmp-RHS(i)), RHS(i));
+ printf("%s failed on row %d: %f RHS: %f\n", this->name().c_str(), i, std::abs(tmp-RHS(i)), RHS(i));
}
if (newton_raphson)
{
diff --git a/src/lib/netlist/solver/nld_solver.cpp b/src/lib/netlist/solver/nld_solver.cpp
index b9c69884382..25b32401620 100644
--- a/src/lib/netlist/solver/nld_solver.cpp
+++ b/src/lib/netlist/solver/nld_solver.cpp
@@ -59,505 +59,7 @@ namespace netlist
{
namespace devices
{
-void terms_t::add(terminal_t *term, int net_other, bool sorted)
-{
- if (sorted)
- for (unsigned i=0; i < m_net_other.size(); i++)
- {
- if (m_net_other[i] > net_other)
- {
- plib::container::insert_at(m_term, i, term);
- plib::container::insert_at(m_net_other, i, net_other);
- plib::container::insert_at(m_gt, i, 0.0);
- plib::container::insert_at(m_go, i, 0.0);
- plib::container::insert_at(m_Idr, i, 0.0);
- plib::container::insert_at(m_other_curanalog, i, nullptr);
- return;
- }
- }
- m_term.push_back(term);
- m_net_other.push_back(net_other);
- m_gt.push_back(0.0);
- m_go.push_back(0.0);
- m_Idr.push_back(0.0);
- m_other_curanalog.push_back(nullptr);
-}
-
-void terms_t::set_pointers()
-{
- for (unsigned i = 0; i < count(); i++)
- {
- m_term[i]->set_ptrs(&m_gt[i], &m_go[i], &m_Idr[i]);
- m_other_curanalog[i] = m_term[i]->m_otherterm->net().m_cur_Analog.ptr();
- }
-}
-
-// ----------------------------------------------------------------------------------------
-// matrix_solver
-// ----------------------------------------------------------------------------------------
-
-matrix_solver_t::~matrix_solver_t()
-{
- for (unsigned k = 0; k < m_terms.size(); k++)
- {
- plib::pfree(m_terms[k]);
- }
-
-}
-
-void matrix_solver_t::setup_base(analog_net_t::list_t &nets)
-{
- log().debug("New solver setup\n");
-
- m_nets.clear();
- m_terms.clear();
-
- for (auto & net : nets)
- {
- m_nets.push_back(net);
- m_terms.push_back(plib::palloc<terms_t>());
- m_rails_temp.push_back(plib::palloc<terms_t>());
- }
-
- for (std::size_t k = 0; k < nets.size(); k++)
- {
- analog_net_t *net = nets[k];
-
- log().debug("setting up net\n");
-
- net->set_solver(this);
-
- for (auto &p : net->m_core_terms)
- {
- log().debug("{1} {2} {3}\n", p->name(), net->name(), net->isRailNet());
- switch (p->type())
- {
- case terminal_t::TERMINAL:
- if (p->device().is_timestep())
- if (!plib::container::contains(m_step_devices, &p->device()))
- m_step_devices.push_back(&p->device());
- if (p->device().is_dynamic())
- if (!plib::container::contains(m_dynamic_devices, &p->device()))
- m_dynamic_devices.push_back(&p->device());
- {
- terminal_t *pterm = dynamic_cast<terminal_t *>(p);
- add_term(k, pterm);
- }
- log().debug("Added terminal {1}\n", p->name());
- break;
- case terminal_t::INPUT:
- {
- proxied_analog_output_t *net_proxy_output = nullptr;
- for (auto & input : m_inps)
- if (input->m_proxied_net == &p->net())
- {
- net_proxy_output = input.get();
- break;
- }
-
- if (net_proxy_output == nullptr)
- {
- auto net_proxy_output_u = plib::make_unique<proxied_analog_output_t>(*this, this->name() + "." + plib::pfmt("m{1}")(m_inps.size()));
- net_proxy_output = net_proxy_output_u.get();
- m_inps.push_back(std::move(net_proxy_output_u));
- nl_assert(p->net().is_analog());
- net_proxy_output->m_proxied_net = static_cast<analog_net_t *>(&p->net());
- }
- net_proxy_output->net().register_con(*p);
- // FIXME: repeated
- net_proxy_output->net().rebuild_list();
- log().debug("Added input\n");
- }
- break;
- case terminal_t::OUTPUT:
- case terminal_t::PARAM:
- log().fatal("unhandled element found\n");
- break;
- }
- }
- log().debug("added net with {1} populated connections\n", net->m_core_terms.size());
- }
-
- /* now setup the matrix */
- setup_matrix();
-}
-
-void matrix_solver_t::setup_matrix()
-{
- const std::size_t iN = m_nets.size();
-
- for (std::size_t k = 0; k < iN; k++)
- {
- m_terms[k]->m_railstart = m_terms[k]->count();
- for (std::size_t i = 0; i < m_rails_temp[k]->count(); i++)
- this->m_terms[k]->add(m_rails_temp[k]->terms()[i], m_rails_temp[k]->net_other()[i], false);
-
- m_rails_temp[k]->clear(); // no longer needed
- m_terms[k]->set_pointers();
- }
-
- for (unsigned k = 0; k < iN; k++)
- plib::pfree(m_rails_temp[k]); // no longer needed
-
- m_rails_temp.clear();
-
- /* Sort in descending order by number of connected matrix voltages.
- * The idea is, that for Gauss-Seidel algo the first voltage computed
- * depends on the greatest number of previous voltages thus taking into
- * account the maximum amout of information.
- *
- * This actually improves performance on popeye slightly. Average
- * GS computations reduce from 2.509 to 2.370
- *
- * Smallest to largest : 2.613
- * Unsorted : 2.509
- * Largest to smallest : 2.370
- *
- * Sorting as a general matrix pre-conditioning is mentioned in
- * literature but I have found no articles about Gauss Seidel.
- *
- * For Gaussian Elimination however increasing order is better suited.
- * FIXME: Even better would be to sort on elements right of the matrix diagonal.
- *
- */
-
- if (m_sort != NOSORT)
- {
- int sort_order = (m_sort == DESCENDING ? 1 : -1);
-
- for (unsigned k = 0; k < iN - 1; k++)
- for (unsigned i = k+1; i < iN; i++)
- {
- if ((static_cast<int>(m_terms[k]->m_railstart) - static_cast<int>(m_terms[i]->m_railstart)) * sort_order < 0)
- {
- std::swap(m_terms[i], m_terms[k]);
- std::swap(m_nets[i], m_nets[k]);
- }
- }
-
- for (unsigned k = 0; k < iN; k++)
- {
- int *other = m_terms[k]->net_other();
- for (unsigned i = 0; i < m_terms[k]->count(); i++)
- if (other[i] != -1)
- other[i] = get_net_idx(&m_terms[k]->terms()[i]->m_otherterm->net());
- }
- }
-
- /* create a list of non zero elements. */
- for (unsigned k = 0; k < iN; k++)
- {
- terms_t * t = m_terms[k];
- /* pretty brutal */
- int *other = t->net_other();
-
- t->m_nz.clear();
-
- for (unsigned i = 0; i < t->m_railstart; i++)
- if (!plib::container::contains(t->m_nz, static_cast<unsigned>(other[i])))
- t->m_nz.push_back(static_cast<unsigned>(other[i]));
-
- t->m_nz.push_back(k); // add diagonal
-
- /* and sort */
- std::sort(t->m_nz.begin(), t->m_nz.end());
- }
-
- /* create a list of non zero elements right of the diagonal
- * These list anticipate the population of array elements by
- * Gaussian elimination.
- */
- for (unsigned k = 0; k < iN; k++)
- {
- terms_t * t = m_terms[k];
- /* pretty brutal */
- int *other = t->net_other();
-
- if (k==0)
- t->m_nzrd.clear();
- else
- {
- t->m_nzrd = m_terms[k-1]->m_nzrd;
- for (auto j = t->m_nzrd.begin(); j != t->m_nzrd.end(); )
- {
- if (*j < k + 1)
- j = t->m_nzrd.erase(j);
- else
- ++j;
- }
- }
-
- for (unsigned i = 0; i < t->m_railstart; i++)
- if (!plib::container::contains(t->m_nzrd, static_cast<unsigned>(other[i])) && other[i] >= static_cast<int>(k + 1))
- t->m_nzrd.push_back(static_cast<unsigned>(other[i]));
-
- /* and sort */
- std::sort(t->m_nzrd.begin(), t->m_nzrd.end());
- }
-
- /* create a list of non zero elements below diagonal k
- * This should reduce cache misses ...
- */
-
- bool **touched = new bool*[iN];
- for (unsigned k=0; k<iN; k++)
- touched[k] = new bool[iN];
-
- for (unsigned k = 0; k < iN; k++)
- {
- for (unsigned j = 0; j < iN; j++)
- touched[k][j] = false;
- for (unsigned j = 0; j < m_terms[k]->m_nz.size(); j++)
- touched[k][m_terms[k]->m_nz[j]] = true;
- }
-
- unsigned ops = 0;
- for (unsigned k = 0; k < iN; k++)
- {
- ops++; // 1/A(k,k)
- for (unsigned row = k + 1; row < iN; row++)
- {
- if (touched[row][k])
- {
- ops++;
- if (!plib::container::contains(m_terms[k]->m_nzbd, row))
- m_terms[k]->m_nzbd.push_back(row);
- for (unsigned col = k + 1; col < iN; col++)
- if (touched[k][col])
- {
- touched[row][col] = true;
- ops += 2;
- }
- }
- }
- }
- log().verbose("Number of mults/adds for {1}: {2}", name(), ops);
-
- if ((0))
- for (unsigned k = 0; k < iN; k++)
- {
- pstring line = plib::pfmt("{1}")(k, "3");
- for (unsigned j = 0; j < m_terms[k]->m_nzrd.size(); j++)
- line += plib::pfmt(" {1}")(m_terms[k]->m_nzrd[j], "3");
- log().verbose("{1}", line);
- }
-
- /*
- * save states
- */
- for (unsigned k = 0; k < iN; k++)
- {
- pstring num = plib::pfmt("{1}")(k);
-
- netlist().save(*this, m_terms[k]->m_last_V, "lastV." + num);
- netlist().save(*this, m_terms[k]->m_DD_n_m_1, "m_DD_n_m_1." + num);
- netlist().save(*this, m_terms[k]->m_h_n_m_1, "m_h_n_m_1." + num);
-
- netlist().save(*this, m_terms[k]->go(),"GO" + num, m_terms[k]->count());
- netlist().save(*this, m_terms[k]->gt(),"GT" + num, m_terms[k]->count());
- netlist().save(*this, m_terms[k]->Idr(),"IDR" + num , m_terms[k]->count());
- }
-
- for (unsigned k=0; k<iN; k++)
- delete [] touched[k];
- delete [] touched;
-}
-
-void matrix_solver_t::update_inputs()
-{
- // avoid recursive calls. Inputs are updated outside this call
- for (auto &inp : m_inps)
- inp->push(inp->m_proxied_net->Q_Analog());
-}
-
-void matrix_solver_t::update_dynamic()
-{
- /* update all non-linear devices */
- for (auto &dyn : m_dynamic_devices)
- dyn->update_terminals();
-}
-
-void matrix_solver_t::reset()
-{
- m_last_step = netlist_time::zero();
-}
-
-void matrix_solver_t::update() NL_NOEXCEPT
-{
- const netlist_time new_timestep = solve();
-
- if (m_params.m_dynamic && has_timestep_devices() && new_timestep > netlist_time::zero())
- {
- m_Q_sync.net().force_queue_execution();
- m_Q_sync.net().reschedule_in_queue(new_timestep);
- }
-}
-
-void matrix_solver_t::update_forced()
-{
- ATTR_UNUSED const netlist_time new_timestep = solve();
-
- if (m_params.m_dynamic && has_timestep_devices())
- {
- m_Q_sync.net().force_queue_execution();
- m_Q_sync.net().reschedule_in_queue(netlist_time::from_double(m_params.m_min_timestep));
- }
-}
-
-void matrix_solver_t::step(const netlist_time &delta)
-{
- const nl_double dd = delta.as_double();
- for (std::size_t k=0; k < m_step_devices.size(); k++)
- m_step_devices[k]->step_time(dd);
-}
-
-void matrix_solver_t::solve_base()
-{
- m_stat_vsolver_calls++;
- if (has_dynamic_devices())
- {
- unsigned this_resched;
- unsigned newton_loops = 0;
- do
- {
- update_dynamic();
- // Gauss-Seidel will revert to Gaussian elemination if steps exceeded.
- this_resched = this->vsolve_non_dynamic(true);
- newton_loops++;
- } while (this_resched > 1 && newton_loops < m_params.m_nr_loops);
-
- m_stat_newton_raphson += newton_loops;
- // reschedule ....
- if (this_resched > 1 && !m_Q_sync.net().is_queued())
- {
- log().warning("NEWTON_LOOPS exceeded on net {1}... reschedule", this->name());
- m_Q_sync.net().toggle_new_Q();
- m_Q_sync.net().reschedule_in_queue(m_params.m_nt_sync_delay);
- }
- }
- else
- {
- this->vsolve_non_dynamic(false);
- }
-}
-const netlist_time matrix_solver_t::solve()
-{
- const netlist_time now = netlist().time();
- const netlist_time delta = now - m_last_step;
-
- // We are already up to date. Avoid oscillations.
- // FIXME: Make this a parameter!
- if (delta < netlist_time::quantum())
- return netlist_time::zero();
-
- /* update all terminals for new time step */
- m_last_step = now;
- step(delta);
- solve_base();
- const netlist_time next_time_step = compute_next_timestep(delta.as_double());
-
- update_inputs();
-
- return next_time_step;
-}
-
-int matrix_solver_t::get_net_idx(detail::net_t *net)
-{
- for (std::size_t k = 0; k < m_nets.size(); k++)
- if (m_nets[k] == net)
- return static_cast<int>(k);
- return -1;
-}
-
-void matrix_solver_t::add_term(std::size_t k, terminal_t *term)
-{
- if (term->m_otherterm->net().isRailNet())
- {
- m_rails_temp[k]->add(term, -1, false);
- }
- else
- {
- int ot = get_net_idx(&term->m_otherterm->net());
- if (ot>=0)
- {
- m_terms[k]->add(term, ot, true);
- }
- /* Should this be allowed ? */
- else // if (ot<0)
- {
- m_rails_temp[k]->add(term, ot, true);
- log().fatal("found term with missing othernet {1}\n", term->name());
- }
- }
-}
-
-netlist_time matrix_solver_t::compute_next_timestep(const double cur_ts)
-{
- nl_double new_solver_timestep = m_params.m_max_timestep;
-
- if (m_params.m_dynamic)
- {
- /*
- * FIXME: We should extend the logic to use either all nets or
- * only output nets.
- */
- for (std::size_t k = 0, iN=m_terms.size(); k < iN; k++)
- {
- analog_net_t *n = m_nets[k];
- terms_t *t = m_terms[k];
-
- const nl_double DD_n = (n->Q_Analog() - t->m_last_V);
- const nl_double hn = cur_ts;
-
- nl_double DD2 = (DD_n / hn - t->m_DD_n_m_1 / t->m_h_n_m_1) / (hn + t->m_h_n_m_1);
- nl_double new_net_timestep;
-
- t->m_h_n_m_1 = hn;
- t->m_DD_n_m_1 = DD_n;
- if (std::fabs(DD2) > NL_FCONST(1e-60)) // avoid div-by-zero
- new_net_timestep = std::sqrt(m_params.m_lte / std::fabs(NL_FCONST(0.5)*DD2));
- else
- new_net_timestep = m_params.m_max_timestep;
-
- if (new_net_timestep < new_solver_timestep)
- new_solver_timestep = new_net_timestep;
-
- t->m_last_V = n->Q_Analog();
- }
- if (new_solver_timestep < m_params.m_min_timestep)
- new_solver_timestep = m_params.m_min_timestep;
- }
- //if (new_solver_timestep > 10.0 * hn)
- // new_solver_timestep = 10.0 * hn;
- /*
- * FIXME: Factor 2 below is important. Without, we get timing issues. This must be a bug elsewhere.
- */
- return std::max(netlist_time::from_double(new_solver_timestep), netlist_time::quantum() * 2);
-}
-
-
-
-void matrix_solver_t::log_stats()
-{
- if (this->m_stat_calculations != 0 && this->m_stat_vsolver_calls && this->m_params.m_log_stats)
- {
- log().verbose("==============================================");
- log().verbose("Solver {1}", this->name());
- log().verbose(" ==> {1} nets", this->m_nets.size()); //, (*(*groups[i].first())->m_core_terms.first())->name());
- log().verbose(" has {1} elements", this->has_dynamic_devices() ? "dynamic" : "no dynamic");
- log().verbose(" has {1} elements", this->has_timestep_devices() ? "timestep" : "no timestep");
- log().verbose(" {1:6.3} average newton raphson loops",
- static_cast<double>(this->m_stat_newton_raphson) / static_cast<double>(this->m_stat_vsolver_calls));
- log().verbose(" {1:10} invocations ({2:6.0} Hz) {3:10} gs fails ({4:6.2} %) {5:6.3} average",
- this->m_stat_calculations(),
- static_cast<double>(this->m_stat_calculations()) / this->netlist().time().as_double(),
- this->m_iterative_fail(),
- 100.0 * static_cast<double>(this->m_iterative_fail())
- / static_cast<double>(this->m_stat_calculations()),
- static_cast<double>(this->m_iterative_total()) / static_cast<double>(this->m_stat_calculations()));
- }
-}
// ----------------------------------------------------------------------------------------
diff --git a/src/lib/netlist/tools/nl_convert.cpp b/src/lib/netlist/tools/nl_convert.cpp
index db1fb5bb3c9..9523febf06a 100644
--- a/src/lib/netlist/tools/nl_convert.cpp
+++ b/src/lib/netlist/tools/nl_convert.cpp
@@ -58,6 +58,19 @@ static lib_map_t read_lib_map(const pstring lm)
convert - convert a spice netlist
-------------------------------------------------*/
+nl_convert_base_t::nl_convert_base_t()
+ : out(m_buf)
+ , m_numberchars("0123456789-+e.")
+{
+}
+
+nl_convert_base_t::~nl_convert_base_t()
+{
+ m_nets.clear();
+ m_devs.clear();
+ m_pins.clear();
+}
+
void nl_convert_base_t::add_pin_alias(const pstring &devname, const pstring &name, const pstring &alias)
{
pstring pname = devname + "." + name;
@@ -121,7 +134,7 @@ void nl_convert_base_t::dump_nl()
{
net_t *net = m_nets[m_ext_alias[i]].get();
// use the first terminal ...
- out("ALIAS({}, {})\n", m_ext_alias[i].cstr(), net->terminals()[0].cstr());
+ out("ALIAS({}, {})\n", m_ext_alias[i].c_str(), net->terminals()[0].c_str());
// if the aliased net only has this one terminal connected ==> don't dump
if (net->terminals().size() == 1)
net->set_no_export();
@@ -138,14 +151,14 @@ void nl_convert_base_t::dump_nl()
std::size_t j = sorted[i];
if (m_devs[j]->has_value())
- out("{}({}, {})\n", m_devs[j]->type().cstr(),
- m_devs[j]->name().cstr(), get_nl_val(m_devs[j]->value()).cstr());
+ out("{}({}, {})\n", m_devs[j]->type().c_str(),
+ m_devs[j]->name().c_str(), get_nl_val(m_devs[j]->value()).c_str());
else if (m_devs[j]->has_model())
- out("{}({}, \"{}\")\n", m_devs[j]->type().cstr(),
- m_devs[j]->name().cstr(), m_devs[j]->model().cstr());
+ out("{}({}, \"{}\")\n", m_devs[j]->type().c_str(),
+ m_devs[j]->name().c_str(), m_devs[j]->model().c_str());
else
- out("{}({})\n", m_devs[j]->type().cstr(),
- m_devs[j]->name().cstr());
+ out("{}({})\n", m_devs[j]->type().c_str(),
+ m_devs[j]->name().c_str());
}
// print nets
for (auto & i : m_nets)
@@ -153,11 +166,11 @@ void nl_convert_base_t::dump_nl()
net_t * net = i.second.get();
if (!net->is_no_export())
{
- //printf("Net {}\n", net->name().cstr());
- out("NET_C({}", net->terminals()[0].cstr() );
+ //printf("Net {}\n", net->name().c_str());
+ out("NET_C({}", net->terminals()[0].c_str() );
for (std::size_t j=1; j<net->terminals().size(); j++)
{
- out(", {}", net->terminals()[j].cstr() );
+ out(", {}", net->terminals()[j].c_str() );
}
out(")\n");
}
@@ -178,7 +191,7 @@ const pstring nl_convert_base_t::get_nl_val(const double val)
break;
i++;
}
- return plib::pfmt(m_units[i].m_func.cstr())(val / m_units[i].m_mult);
+ return plib::pfmt(m_units[i].m_func.c_str())(val / m_units[i].m_mult);
}
}
double nl_convert_base_t::get_sp_unit(const pstring &unit)
@@ -190,7 +203,7 @@ double nl_convert_base_t::get_sp_unit(const pstring &unit)
return m_units[i].m_mult;
i++;
}
- fprintf(stderr, "Unit %s unknown\n", unit.cstr());
+ fprintf(stderr, "Unit %s unknown\n", unit.c_str());
return 0.0;
}
@@ -269,12 +282,12 @@ void nl_convert_spice_t::process_line(const pstring &line)
out("// {}\n", line.substr(1));
break;
case '*':
- out("// {}\n", line.substr(1).cstr());
+ out("// {}\n", line.substr(1).c_str());
break;
case '.':
if (tt[0].equals(".SUBCKT"))
{
- out("NETLIST_START({})\n", tt[1].cstr());
+ out("NETLIST_START({})\n", tt[1].c_str());
for (std::size_t i=2; i<tt.size(); i++)
add_ext_alias(tt[i]);
}
@@ -284,7 +297,7 @@ void nl_convert_spice_t::process_line(const pstring &line)
out("NETLIST_END()\n");
}
else
- out("// {}\n", line.cstr());
+ out("// {}\n", line.c_str());
break;
case 'Q':
{
@@ -304,7 +317,7 @@ void nl_convert_spice_t::process_line(const pstring &line)
if (m.size() == 2)
{
if (m[1].len() != 4)
- fprintf(stderr, "error with model desc %s\n", model.cstr());
+ fprintf(stderr, "error with model desc %s\n", model.c_str());
pins = m[1].left(m[1].begin() + 3);
}
add_device("QBJT_EB", tt[0], m[0]);
@@ -346,7 +359,7 @@ void nl_convert_spice_t::process_line(const pstring &line)
//add_term(tt[2], tt[0] + ".2");
}
else
- fprintf(stderr, "Voltage Source %s not connected to GND\n", tt[0].cstr());
+ fprintf(stderr, "Voltage Source %s not connected to GND\n", tt[0].c_str());
break;
case 'I': // Input pin special notation
{
@@ -379,24 +392,58 @@ void nl_convert_spice_t::process_line(const pstring &line)
break;
}
default:
- out("// IGNORED {}: {}\n", tt[0].cstr(), line.cstr());
+ out("// IGNORED {}: {}\n", tt[0].c_str(), line.c_str());
}
}
}
+/*-------------------------------------------------
+ Eagle converter
+-------------------------------------------------*/
+
+nl_convert_eagle_t::tokenizer::tokenizer(nl_convert_eagle_t &convert, plib::pistream &strm)
+ : plib::ptokenizer(strm)
+ , m_convert(convert)
+{
+ set_identifier_chars("abcdefghijklmnopqrstuvwvxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890_.-");
+ set_number_chars(".0123456789", "0123456789eE-."); //FIXME: processing of numbers
+ char ws[5];
+ ws[0] = ' ';
+ ws[1] = 9;
+ ws[2] = 10;
+ ws[3] = 13;
+ ws[4] = 0;
+ set_whitespace(ws);
+ /* FIXME: gnetlist doesn't print comments */
+ set_comment("/*", "*/", "//");
+ set_string_char('\'');
+ m_tok_ADD = register_token("ADD");
+ m_tok_VALUE = register_token("VALUE");
+ m_tok_SIGNAL = register_token("SIGNAL");
+ m_tok_SEMICOLON = register_token(";");
+ /* currently not used, but required for parsing */
+ register_token(")");
+ register_token("(");
+}
+
+void nl_convert_eagle_t::tokenizer::verror(const pstring &msg, int line_num, const pstring &line)
+{
+ m_convert.out("{} (line {}): {}\n", msg.c_str(), line_num, line.c_str());
+}
+
//FIXME: should accept a stream as well
void nl_convert_eagle_t::convert(const pstring &contents)
{
plib::pistringstream istrm(contents);
- eagle_tokenizer tok(*this, istrm);
+ tokenizer tok(*this, istrm);
out("NETLIST_START(dummy)\n");
add_term("GND", "GND");
add_term("VCC", "VCC");
- eagle_tokenizer::token_t token = tok.get_token();
+ tokenizer::token_t token = tok.get_token();
while (true)
{
- if (token.is_type(eagle_tokenizer::ENDOFFILE))
+ if (token.is_type(tokenizer::ENDOFFILE))
{
dump_nl();
// FIXME: Parameter
@@ -485,13 +532,49 @@ void nl_convert_eagle_t::convert(const pstring &contents)
}
else
{
- out("Unexpected {}\n", token.str().cstr());
+ out("Unexpected {}\n", token.str().c_str());
return;
}
}
}
+/*-------------------------------------------------
+ RINF converter
+-------------------------------------------------*/
+
+nl_convert_rinf_t::tokenizer::tokenizer(nl_convert_rinf_t &convert, plib::pistream &strm)
+ : plib::ptokenizer(strm)
+ , m_convert(convert)
+{
+ set_identifier_chars(".abcdefghijklmnopqrstuvwvxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890_-");
+ set_number_chars("0123456789", "0123456789eE-."); //FIXME: processing of numbers
+ char ws[5];
+ ws[0] = ' ';
+ ws[1] = 9;
+ ws[2] = 10;
+ ws[3] = 13;
+ ws[4] = 0;
+ set_whitespace(ws);
+ /* FIXME: gnetlist doesn't print comments */
+ set_comment("","","//"); // FIXME:needs to be confirmed
+ set_string_char('"');
+ m_tok_HEA = register_token(".HEA");
+ m_tok_APP = register_token(".APP");
+ m_tok_TIM = register_token(".TIM");
+ m_tok_TYP = register_token(".TYP");
+ m_tok_ADDC = register_token(".ADD_COM");
+ m_tok_ATTC = register_token(".ATT_COM");
+ m_tok_NET = register_token(".ADD_TER");
+ m_tok_TER = register_token(".TER");
+ m_tok_END = register_token(".END");
+}
+
+void nl_convert_rinf_t::tokenizer::verror(const pstring &msg, int line_num, const pstring &line)
+{
+ m_convert.out("{} (line {}): {}\n", msg.c_str(), line_num, line.c_str());
+}
+
/* token_id_t m_tok_HFA;
token_id_t m_tok_APP;
token_id_t m_tok_TIM;
@@ -502,6 +585,7 @@ void nl_convert_eagle_t::convert(const pstring &contents)
token_id_t m_tok_TER;
*
*/
+
void nl_convert_rinf_t::convert(const pstring &contents)
{
plib::pistringstream istrm(contents);
diff --git a/src/lib/netlist/tools/nl_convert.h b/src/lib/netlist/tools/nl_convert.h
index fa496a092d7..3536488c766 100644
--- a/src/lib/netlist/tools/nl_convert.h
+++ b/src/lib/netlist/tools/nl_convert.h
@@ -23,13 +23,8 @@ class nl_convert_base_t
{
public:
- nl_convert_base_t() : out(m_buf), m_numberchars("0123456789-+e.") {}
- virtual ~nl_convert_base_t()
- {
- m_nets.clear();
- m_devs.clear();
- m_pins.clear();
- }
+ nl_convert_base_t();
+ virtual ~nl_convert_base_t();
const pstringbuffer &result() { return m_buf.str(); }
@@ -168,32 +163,10 @@ public:
{
}
- class eagle_tokenizer : public plib::ptokenizer
+ class tokenizer : public plib::ptokenizer
{
public:
- eagle_tokenizer(nl_convert_eagle_t &convert, plib::pistream &strm)
- : plib::ptokenizer(strm), m_convert(convert)
- {
- set_identifier_chars("abcdefghijklmnopqrstuvwvxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890_.-");
- set_number_chars(".0123456789", "0123456789eE-."); //FIXME: processing of numbers
- char ws[5];
- ws[0] = ' ';
- ws[1] = 9;
- ws[2] = 10;
- ws[3] = 13;
- ws[4] = 0;
- set_whitespace(ws);
- /* FIXME: gnetlist doesn't print comments */
- set_comment("/*", "*/", "//");
- set_string_char('\'');
- m_tok_ADD = register_token("ADD");
- m_tok_VALUE = register_token("VALUE");
- m_tok_SIGNAL = register_token("SIGNAL");
- m_tok_SEMICOLON = register_token(";");
- /* currently not used, but required for parsing */
- register_token(")");
- register_token("(");
- }
+ tokenizer(nl_convert_eagle_t &convert, plib::pistream &strm);
token_id_t m_tok_ADD;
token_id_t m_tok_VALUE;
@@ -202,11 +175,7 @@ public:
protected:
- void verror(const pstring &msg, int line_num, const pstring &line) override
- {
- m_convert.out("{} (line {}): {}\n", msg.cstr(), line_num, line.cstr());
- }
-
+ virtual void verror(const pstring &msg, int line_num, const pstring &line) override;
private:
nl_convert_eagle_t &m_convert;
@@ -233,31 +202,7 @@ public:
class tokenizer : public plib::ptokenizer
{
public:
- tokenizer(nl_convert_rinf_t &convert, plib::pistream &strm)
- : plib::ptokenizer(strm), m_convert(convert)
- {
- set_identifier_chars(".abcdefghijklmnopqrstuvwvxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890_-");
- set_number_chars("0123456789", "0123456789eE-."); //FIXME: processing of numbers
- char ws[5];
- ws[0] = ' ';
- ws[1] = 9;
- ws[2] = 10;
- ws[3] = 13;
- ws[4] = 0;
- set_whitespace(ws);
- /* FIXME: gnetlist doesn't print comments */
- set_comment("","","//"); // FIXME:needs to be confirmed
- set_string_char('"');
- m_tok_HEA = register_token(".HEA");
- m_tok_APP = register_token(".APP");
- m_tok_TIM = register_token(".TIM");
- m_tok_TYP = register_token(".TYP");
- m_tok_ADDC = register_token(".ADD_COM");
- m_tok_ATTC = register_token(".ATT_COM");
- m_tok_NET = register_token(".ADD_TER");
- m_tok_TER = register_token(".TER");
- m_tok_END = register_token(".END");
- }
+ tokenizer(nl_convert_rinf_t &convert, plib::pistream &strm);
token_id_t m_tok_HEA;
token_id_t m_tok_APP;
@@ -271,11 +216,7 @@ public:
protected:
- void verror(const pstring &msg, int line_num, const pstring &line) override
- {
- m_convert.out("{} (line {}): {}\n", msg.cstr(), line_num, line.cstr());
- }
-
+ virtual void verror(const pstring &msg, int line_num, const pstring &line) override;
private:
nl_convert_rinf_t &m_convert;
diff --git a/src/lib/util/base64.hpp b/src/lib/util/base64.hpp
new file mode 100644
index 00000000000..dc8f69335dc
--- /dev/null
+++ b/src/lib/util/base64.hpp
@@ -0,0 +1,167 @@
+// license:BSD-3-Clause
+// copyright-holders:René Nyffenegger
+/*
+ base64.cpp and base64.h
+
+ Copyright (C) 2004-2008 René Nyffenegger
+
+ This source code is provided 'as-is', without any express or implied
+ warranty. In no event will the author be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this source code must not be misrepresented; you must not
+ claim that you wrote the original source code. If you use this source code
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original source code.
+
+ 3. This notice may not be removed or altered from any source distribution.
+
+ René Nyffenegger rene.nyffenegger@adp-gmbh.ch
+
+*/
+
+#ifndef _BASE64_HPP_
+#define _BASE64_HPP_
+
+#include <string>
+
+static std::string const base64_chars =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz"
+ "0123456789+/";
+
+/// Test whether a character is a valid base64 character
+/**
+ * @param c The character to test
+ * @return true if c is a valid base64 character
+ */
+static inline bool is_base64(unsigned char c) {
+ return (c == 43 || // +
+ (c >= 47 && c <= 57) || // /-9
+ (c >= 65 && c <= 90) || // A-Z
+ (c >= 97 && c <= 122)); // a-z
+}
+
+/// Encode a char buffer into a base64 string
+/**
+ * @param input The input data
+ * @param len The length of input in bytes
+ * @return A base64 encoded string representing input
+ */
+inline std::string base64_encode(unsigned char const * input, size_t len) {
+ std::string ret;
+ int i = 0;
+ int j;
+ unsigned char char_array_3[3];
+ unsigned char char_array_4[4];
+
+ while (len--) {
+ char_array_3[i++] = *(input++);
+ if (i == 3) {
+ char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
+ char_array_4[1] = ((char_array_3[0] & 0x03) << 4) +
+ ((char_array_3[1] & 0xf0) >> 4);
+ char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) +
+ ((char_array_3[2] & 0xc0) >> 6);
+ char_array_4[3] = char_array_3[2] & 0x3f;
+
+ for(i = 0; (i <4) ; i++) {
+ ret += base64_chars[char_array_4[i]];
+ }
+ i = 0;
+ }
+ }
+
+ if (i) {
+ for(j = i; j < 3; j++) {
+ char_array_3[j] = '\0';
+ }
+
+ char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
+ char_array_4[1] = ((char_array_3[0] & 0x03) << 4) +
+ ((char_array_3[1] & 0xf0) >> 4);
+ char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) +
+ ((char_array_3[2] & 0xc0) >> 6);
+ char_array_4[3] = char_array_3[2] & 0x3f;
+
+ for (j = 0; (j < i + 1); j++) {
+ ret += base64_chars[char_array_4[j]];
+ }
+
+ while((i++ < 3)) {
+ ret += '=';
+ }
+ }
+
+ return ret;
+}
+
+/// Encode a string into a base64 string
+/**
+ * @param input The input data
+ * @return A base64 encoded string representing input
+ */
+inline std::string base64_encode(std::string const & input) {
+ return base64_encode(
+ reinterpret_cast<const unsigned char *>(input.data()),
+ input.size()
+ );
+}
+
+/// Decode a base64 encoded string into a string of raw bytes
+/**
+ * @param input The base64 encoded input data
+ * @return A string representing the decoded raw bytes
+ */
+inline std::string base64_decode(std::string const & input) {
+ size_t in_len = input.size();
+ int i = 0;
+ int j;
+ int in_ = 0;
+ unsigned char char_array_4[4], char_array_3[3];
+ std::string ret;
+
+ while (in_len-- && ( input[in_] != '=') && is_base64(input[in_])) {
+ char_array_4[i++] = input[in_]; in_++;
+ if (i ==4) {
+ for (i = 0; i <4; i++) {
+ char_array_4[i] = static_cast<unsigned char>(base64_chars.find(char_array_4[i]));
+ }
+
+ char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
+ char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
+ char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
+
+ for (i = 0; (i < 3); i++) {
+ ret += char_array_3[i];
+ }
+ i = 0;
+ }
+ }
+
+ if (i) {
+ for (j = i; j <4; j++)
+ char_array_4[j] = 0;
+
+ for (j = 0; j <4; j++)
+ char_array_4[j] = static_cast<unsigned char>(base64_chars.find(char_array_4[j]));
+
+ char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
+ char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
+ char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
+
+ for (j = 0; (j < i - 1); j++) {
+ ret += static_cast<std::string::value_type>(char_array_3[j]);
+ }
+ }
+
+ return ret;
+}
+#endif // _BASE64_HPP_
diff --git a/src/lib/util/client_http.hpp b/src/lib/util/client_http.hpp
new file mode 100644
index 00000000000..df188090f87
--- /dev/null
+++ b/src/lib/util/client_http.hpp
@@ -0,0 +1,438 @@
+// license:MIT
+// copyright-holders:Ole Christian Eidheim, Miodrag Milanovic
+#ifndef CLIENT_HTTP_HPP
+#define CLIENT_HTTP_HPP
+
+#if defined(_MSC_VER)
+#pragma warning(disable:4503)
+#endif
+
+#include "asio.h"
+
+#include <unordered_map>
+#include <map>
+#include <random>
+#include <mutex>
+
+#ifndef CASE_INSENSITIVE_EQUALS_AND_HASH
+#define CASE_INSENSITIVE_EQUALS_AND_HASH
+class case_insensitive_equals {
+public:
+ bool operator()(const std::string &key1, const std::string &key2) const {
+ return key1.size() == key2.size()
+ && equal(key1.cbegin(), key1.cend(), key2.cbegin(),
+ [](std::string::value_type key1v, std::string::value_type key2v)
+ { return tolower(key1v) == tolower(key2v); });
+ }
+};
+class case_insensitive_hash {
+public:
+ size_t operator()(const std::string &key) const {
+ size_t seed = 0;
+ for (auto &c : key) {
+ std::hash<char> hasher;
+ seed ^= hasher(std::tolower(c)) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
+ }
+ return seed;
+ }
+};
+#endif
+
+namespace webpp {
+ template <class socket_type>
+ class Client;
+
+ template <class socket_type>
+ class ClientBase {
+ public:
+ virtual ~ClientBase() {}
+
+ class Response {
+ friend class ClientBase<socket_type>;
+ friend class Client<socket_type>;
+ public:
+ std::string http_version, status_code;
+
+ std::istream content;
+
+ std::unordered_multimap<std::string, std::string, case_insensitive_hash, case_insensitive_equals> header;
+
+ private:
+ asio::streambuf content_buffer;
+
+ Response(): content(&content_buffer) {}
+ };
+
+ class Config {
+ friend class ClientBase<socket_type>;
+ private:
+ Config() {}
+ public:
+ /// Set timeout on requests in seconds. Default value: 0 (no timeout).
+ size_t timeout = 0;
+ /// Set proxy server (server:port)
+ std::string proxy_server;
+ };
+
+ /// Set before calling request
+ Config config;
+
+ std::shared_ptr<Response> request(const std::string& request_type, const std::string& path="/", const std::string content="",
+ const std::map<std::string, std::string>& header=std::map<std::string, std::string>()) {
+ auto corrected_path=path;
+ if(corrected_path=="")
+ corrected_path="/";
+ if (!config.proxy_server.empty() && std::is_same<socket_type, asio::ip::tcp::socket>::value)
+ corrected_path = "http://" + host + ':' + std::to_string(port) + corrected_path;
+
+ asio::streambuf write_buffer;
+ std::ostream write_stream(&write_buffer);
+ write_stream << request_type << " " << corrected_path << " HTTP/1.1\r\n";
+ write_stream << "Host: " << host << "\r\n";
+ for(auto& h: header) {
+ write_stream << h.first << ": " << h.second << "\r\n";
+ }
+ if(content.size()>0)
+ write_stream << "Content-Length: " << content.size() << "\r\n";
+ write_stream << "\r\n";
+
+ connect();
+
+ auto timer = get_timeout_timer();
+ asio::async_write(*socket, write_buffer,
+ [this, &content, timer](const std::error_code &ec, size_t /*bytes_transferred*/) {
+ if (timer)
+ timer->cancel();
+ if (!ec) {
+ if (!content.empty()) {
+ auto timer2 = get_timeout_timer();
+ asio::async_write(*socket, asio::buffer(content.data(), content.size()),
+ [this,timer2](const std::error_code &ec, size_t /*bytes_transferred*/) {
+ if (timer2)
+ timer2->cancel();
+ if (ec) {
+ std::lock_guard<std::mutex> lock(socket_mutex);
+ socket = nullptr;
+ throw std::system_error(ec);
+ }
+ });
+ }
+ }
+ else {
+ std::lock_guard<std::mutex> lock(socket_mutex);
+ socket = nullptr;
+ throw std::system_error(ec);
+ }
+ });
+ io_context.reset();
+ io_context.run();
+ return request_read();
+ }
+
+ std::shared_ptr<Response> request(const std::string& request_type, const std::string& path, std::iostream& content,
+ const std::map<std::string, std::string>& header=std::map<std::string, std::string>()) {
+ auto corrected_path=path;
+ if(corrected_path=="")
+ corrected_path="/";
+ if (!config.proxy_server.empty() && std::is_same<socket_type, asio::ip::tcp::socket>::value)
+ corrected_path = "http://" + host + ':' + std::to_string(port) + corrected_path;
+
+ content.seekp(0, std::ios::end);
+ auto content_length=content.tellp();
+ content.seekp(0, std::ios::beg);
+
+ asio::streambuf write_buffer;
+ std::ostream write_stream(&write_buffer);
+ write_stream << request_type << " " << corrected_path << " HTTP/1.1\r\n";
+ write_stream << "Host: " << host << "\r\n";
+ for(auto& h: header) {
+ write_stream << h.first << ": " << h.second << "\r\n";
+ }
+ if(content_length>0)
+ write_stream << "Content-Length: " << content_length << "\r\n";
+ write_stream << "\r\n";
+ if(content_length>0)
+ write_stream << content.rdbuf();
+
+ connect();
+
+ auto timer = get_timeout_timer();
+ asio::async_write(*socket, write_buffer,
+ [this,timer](const std::error_code &ec, size_t /*bytes_transferred*/) {
+ if (timer)
+ timer->cancel();
+ if (ec) {
+ std::lock_guard<std::mutex> lock(socket_mutex);
+ socket = nullptr;
+ throw std::system_error(ec);
+ }
+ });
+ io_context.reset();
+ io_context.run();
+
+ return request_read();
+ }
+ void close() {
+ std::lock_guard<std::mutex> lock(socket_mutex);
+ if (socket) {
+ std::error_code ec;
+ socket->lowest_layer().shutdown(asio::ip::tcp::socket::shutdown_both, ec);
+ socket->lowest_layer().close();
+ }
+ }
+ protected:
+ asio::io_context io_context;
+ asio::ip::tcp::resolver resolver;
+
+ std::unique_ptr<socket_type> socket;
+ std::mutex socket_mutex;
+
+ std::string host;
+ unsigned short port;
+
+ ClientBase(const std::string& host_port, unsigned short default_port) : resolver(io_context) {
+ auto parsed_host_port = parse_host_port(host_port, default_port);
+ host = parsed_host_port.first;
+ port = parsed_host_port.second;
+ }
+
+ std::pair<std::string, unsigned short> parse_host_port(const std::string &host_port, unsigned short default_port) const
+ {
+ std::pair<std::string, unsigned short> parsed_host_port;
+ size_t host_end=host_port.find(':');
+ if(host_end==std::string::npos) {
+ parsed_host_port.first =host_port;
+ parsed_host_port.second =default_port;
+ }
+ else {
+ parsed_host_port.first =host_port.substr(0, host_end);
+ parsed_host_port.second =static_cast<unsigned short>(stoul(host_port.substr(host_end+1)));
+ }
+ return parsed_host_port;
+ }
+
+ virtual void connect()=0;
+
+ std::shared_ptr<asio::system_timer> get_timeout_timer() {
+ if (config.timeout == 0)
+ return nullptr;
+
+ auto timer = std::make_shared<asio::system_timer>(io_context);
+ timer->expires_from_now(std::chrono::seconds(config.timeout));
+ timer->async_wait([this](const std::error_code& ec) {
+ if (!ec) {
+ close();
+ }
+ });
+ return timer;
+ }
+
+ void parse_response_header(const std::shared_ptr<Response> &response) const {
+ std::string line;
+ getline(response->content, line);
+ size_t version_end=line.find(' ');
+ if(version_end!=std::string::npos) {
+ if(5<line.size())
+ response->http_version=line.substr(5, version_end-5);
+ if((version_end+1)<line.size())
+ response->status_code=line.substr(version_end+1, line.size()-(version_end+1)-1);
+
+ getline(response->content, line);
+ size_t param_end;
+ while((param_end=line.find(':'))!=std::string::npos) {
+ size_t value_start=param_end+1;
+ if((value_start)<line.size()) {
+ if(line[value_start]==' ')
+ value_start++;
+ if(value_start<line.size())
+ response->header.insert(std::make_pair(line.substr(0, param_end), line.substr(value_start, line.size()-value_start-1)));
+ }
+
+ getline(response->content, line);
+ }
+ }
+ }
+
+ std::shared_ptr<Response> request_read() {
+ std::shared_ptr<Response> response(new Response());
+
+ asio::streambuf chunked_streambuf;
+
+ auto timer = get_timeout_timer();
+ asio::async_read_until(*socket, response->content_buffer, "\r\n\r\n",
+ [this, &response, &chunked_streambuf,timer](const std::error_code& ec, size_t bytes_transferred) {
+ if (timer)
+ timer->cancel();
+ if (!ec) {
+ size_t num_additional_bytes = response->content_buffer.size() - bytes_transferred;
+
+ parse_response_header(response);
+
+ auto header_it = response->header.find("Content-Length");
+ if (header_it != response->header.end()) {
+ auto content_length = stoull(header_it->second);
+ if (content_length>num_additional_bytes) {
+ auto timer2 = get_timeout_timer();
+ asio::async_read(*socket, response->content_buffer,
+ asio::transfer_exactly(size_t(content_length) - num_additional_bytes),
+ [this,timer2](const std::error_code& ec, size_t /*bytes_transferred*/) {
+ if (timer2)
+ timer2->cancel();
+ if (ec) {
+ std::lock_guard<std::mutex> lock(socket_mutex);
+ socket = nullptr;
+ throw std::system_error(ec);
+ }
+ });
+ }
+ }
+ else if ((header_it = response->header.find("Transfer-Encoding")) != response->header.end() && header_it->second == "chunked") {
+ request_read_chunked(response, chunked_streambuf);
+ }
+ }
+ else {
+ std::lock_guard<std::mutex> lock(socket_mutex);
+ socket = nullptr;
+ throw std::system_error(ec);
+ }
+ });
+ io_context.reset();
+ io_context.run();
+
+ return response;
+ }
+
+ void request_read_chunked(const std::shared_ptr<Response> &response, asio::streambuf &streambuf) {
+ auto timer = get_timeout_timer();
+ asio::async_read_until(*socket, response->content_buffer, "\r\n",
+ [this, &response, &streambuf,timer](const std::error_code& ec, size_t bytes_transferred) {
+ if (timer)
+ timer->cancel();
+ if (!ec) {
+ std::string line;
+ getline(response->content, line);
+ bytes_transferred -= line.size() + 1;
+ line.pop_back();
+ std::streamsize length = stol(line, nullptr, 16);
+
+ auto num_additional_bytes = static_cast<std::streamsize>(response->content_buffer.size() - bytes_transferred);
+
+ auto post_process = [this, &response, &streambuf, length] {
+ std::ostream stream(&streambuf);
+ if (length > 0) {
+ std::vector<char> buffer(static_cast<size_t>(length));
+ response->content.read(&buffer[0], length);
+ stream.write(&buffer[0], length);
+ }
+
+ //Remove "\r\n"
+ response->content.get();
+ response->content.get();
+
+ if (length>0)
+ request_read_chunked(response, streambuf);
+ else {
+ std::ostream response_stream(&response->content_buffer);
+ response_stream << stream.rdbuf();
+ }
+ };
+
+ if ((2 + length)>num_additional_bytes) {
+ auto timer2 = get_timeout_timer();
+ asio::async_read(*socket, response->content_buffer,
+ asio::transfer_exactly(size_t(2 + length) - size_t(num_additional_bytes)),
+ [this, post_process, timer2](const std::error_code& ec, size_t /*bytes_transferred*/) {
+ if (timer2)
+ timer2->cancel();
+ if (!ec) {
+ post_process();
+ }
+ else {
+ std::lock_guard<std::mutex> lock(socket_mutex);
+ socket = nullptr;
+ throw std::system_error(ec);
+ }
+ });
+ }
+ else
+ post_process();
+ }
+ else {
+ std::lock_guard<std::mutex> lock(socket_mutex);
+ socket = nullptr;
+ throw std::system_error(ec);
+ }
+ });
+ }
+ };
+
+ template<class socket_type>
+ class Client : public ClientBase<socket_type> {
+ public:
+ Client(const std::string& host_port, unsigned short default_port)
+ : ClientBase<socket_type>(host_port, default_port)
+ {
+ }
+ };
+
+ using HTTP = asio::ip::tcp::socket;
+
+ template<>
+ class Client<HTTP> : public ClientBase<HTTP> {
+ public:
+ explicit Client(const std::string& server_port_path) : ClientBase(server_port_path, 80) { }
+
+ protected:
+ void connect() override {
+ if(!socket || !socket->is_open()) {
+ std::unique_ptr<asio::ip::tcp::resolver::query> query;
+ if (config.proxy_server.empty())
+ query = std::make_unique<asio::ip::tcp::resolver::query>(host, std::to_string(port));
+ else {
+ auto proxy_host_port = parse_host_port(config.proxy_server, 8080);
+ query = std::make_unique<asio::ip::tcp::resolver::query>(proxy_host_port.first, std::to_string(proxy_host_port.second));
+
+ }
+ resolver.async_resolve(*query, [this](const std::error_code &ec,
+ asio::ip::tcp::resolver::iterator it){
+ if(!ec) {
+ {
+ std::lock_guard<std::mutex> lock(socket_mutex);
+ socket = std::make_unique<HTTP>(io_context);
+ }
+
+ auto timer = get_timeout_timer();
+ asio::async_connect(*socket, it, [this,timer]
+ (const std::error_code &ec, asio::ip::tcp::resolver::iterator /*it*/){
+ if (timer)
+ timer->cancel();
+ if(!ec) {
+ asio::ip::tcp::no_delay option(true);
+ socket->set_option(option);
+ }
+ else {
+ std::lock_guard<std::mutex> lock(socket_mutex);
+ socket=nullptr;
+ throw std::system_error(ec);
+ }
+ });
+ }
+ else {
+ std::lock_guard<std::mutex> lock(socket_mutex);
+ socket=nullptr;
+ throw std::system_error(ec);
+ }
+ });
+ io_context.reset();
+ io_context.run();
+ }
+ }
+ };
+
+ class http_client : public Client<HTTP> {
+ public:
+ explicit http_client(const std::string& server_port_path) : Client<HTTP>::Client(server_port_path) {}
+ };
+}
+
+#endif /* CLIENT_HTTP_HPP */
diff --git a/src/lib/util/client_https.hpp b/src/lib/util/client_https.hpp
new file mode 100644
index 00000000000..fc1f12bb075
--- /dev/null
+++ b/src/lib/util/client_https.hpp
@@ -0,0 +1,152 @@
+// license:MIT
+// copyright-holders:Ole Christian Eidheim, Miodrag Milanovic
+#ifndef CLIENT_HTTPS_HPP
+#define CLIENT_HTTPS_HPP
+
+#include "client_http.hpp"
+#include "asio/ssl.hpp"
+
+namespace webpp {
+ using HTTPS = asio::ssl::stream<asio::ip::tcp::socket>;
+
+ template<>
+ class Client<HTTPS> : public ClientBase<HTTPS> {
+ public:
+ explicit Client(const std::string& server_port_path, bool verify_certificate=true,
+ const std::string& cert_file=std::string(), const std::string& private_key_file=std::string(),
+ const std::string& verify_file=std::string()) :
+ ClientBase(server_port_path, 443), m_context(asio::ssl::context::tlsv12) {
+ if(cert_file.size()>0 && private_key_file.size()>0) {
+ m_context.use_certificate_chain_file(cert_file);
+ m_context.use_private_key_file(private_key_file, asio::ssl::context::pem);
+ }
+
+ if(verify_certificate)
+ m_context.set_verify_callback(asio::ssl::rfc2818_verification(host));
+
+ if(verify_file.size()>0)
+ m_context.load_verify_file(verify_file);
+ else
+ m_context.set_default_verify_paths();
+
+ if(verify_file.size()>0 || verify_certificate)
+ m_context.set_verify_mode(asio::ssl::verify_peer);
+ else
+ m_context.set_verify_mode(asio::ssl::verify_none);
+ }
+
+ protected:
+ asio::ssl::context m_context;
+
+ void connect() override {
+ if(!socket || !socket->lowest_layer().is_open()) {
+ std::unique_ptr<asio::ip::tcp::resolver::query> query;
+ if (config.proxy_server.empty()) {
+ query = std::make_unique<asio::ip::tcp::resolver::query>(host, std::to_string(port));
+ }
+ else {
+ auto proxy_host_port = parse_host_port(config.proxy_server, 8080);
+ query = std::make_unique<asio::ip::tcp::resolver::query>(proxy_host_port.first, std::to_string(proxy_host_port.second));
+ }
+ resolver.async_resolve(*query, [this]
+ (const std::error_code &ec, asio::ip::tcp::resolver::iterator it) {
+ if (!ec) {
+ {
+ std::lock_guard<std::mutex> lock(socket_mutex);
+ socket = std::make_unique<HTTPS>(io_context, m_context);
+ }
+
+ auto timer = get_timeout_timer();
+ asio::async_connect(socket->lowest_layer(), it, [this, timer]
+ (const std::error_code &ec, asio::ip::tcp::resolver::iterator /*it*/) {
+ if (timer)
+ timer->cancel();
+ if (!ec) {
+ asio::ip::tcp::no_delay option(true);
+ socket->lowest_layer().set_option(option);
+ }
+ else {
+ std::lock_guard<std::mutex> lock(socket_mutex);
+ socket = nullptr;
+ throw std::system_error(ec);
+ }
+ });
+ }
+ else {
+ std::lock_guard<std::mutex> lock(socket_mutex);
+ socket = nullptr;
+ throw std::system_error(ec);
+ }
+ });
+ io_context.reset();
+ io_context.run();
+
+ if (!config.proxy_server.empty()) {
+ asio::streambuf write_buffer;
+ std::ostream write_stream(&write_buffer);
+ auto host_port = host + ':' + std::to_string(port);
+ write_stream << "CONNECT " + host_port + " HTTP/1.1\r\n" << "Host: " << host_port << "\r\n\r\n";
+ auto timer = get_timeout_timer();
+ asio::async_write(socket->next_layer(), write_buffer,
+ [this, timer](const std::error_code &ec, size_t /*bytes_transferred*/) {
+ if (timer)
+ timer->cancel();
+ if (ec) {
+ std::lock_guard<std::mutex> lock(socket_mutex);
+ socket = nullptr;
+ throw std::system_error(ec);
+ }
+ });
+ io_context.reset();
+ io_context.run();
+
+ std::shared_ptr<Response> response(new Response());
+ timer=get_timeout_timer();
+ asio::async_read_until(socket->next_layer(), response->content_buffer, "\r\n\r\n",
+ [this, timer](const std::error_code& ec, size_t /*bytes_transferred*/) {
+ if(timer)
+ timer->cancel();
+ if(ec) {
+ std::lock_guard<std::mutex> lock(socket_mutex);
+ socket=nullptr;
+ throw std::system_error(ec);
+ }
+ });
+ io_context.reset();
+ io_context.run();
+ parse_response_header(response);
+
+ if (response->status_code.size()>0 && response->status_code.compare(0, 3, "200") != 0) {
+ std::lock_guard<std::mutex> lock(socket_mutex);
+ socket = nullptr;
+ throw std::system_error(std::error_code(int(std::errc::permission_denied), std::generic_category()));
+ }
+ }
+
+ auto timer = get_timeout_timer();
+ this->socket->async_handshake(asio::ssl::stream_base::client,
+ [this, timer](const std::error_code& ec) {
+ if (timer)
+ timer->cancel();
+ if (ec) {
+ std::lock_guard<std::mutex> lock(socket_mutex);
+ socket = nullptr;
+ throw std::system_error(ec);
+ }
+ });
+ io_context.reset();
+ io_context.run();
+ }
+ }
+ };
+
+ class https_client : public Client<HTTPS> {
+ public:
+ explicit https_client(const std::string& server_port_path, bool verify_certificate = true,
+ const std::string& cert_file = std::string(), const std::string& private_key_file = std::string(),
+ const std::string& verify_file = std::string()) : Client<HTTPS>::Client(server_port_path, verify_certificate, cert_file, private_key_file, verify_file) {}
+ };
+
+}
+
+#endif /* CLIENT_HTTPS_HPP */
diff --git a/src/lib/util/client_ws.hpp b/src/lib/util/client_ws.hpp
new file mode 100644
index 00000000000..f3c4ded6bb2
--- /dev/null
+++ b/src/lib/util/client_ws.hpp
@@ -0,0 +1,517 @@
+// license:MIT
+// copyright-holders:Ole Christian Eidheim, Miodrag Milanovic
+#ifndef CLIENT_WS_HPP
+#define CLIENT_WS_HPP
+
+#include "asio.h"
+
+#include <unordered_map>
+#include <iostream>
+#include <random>
+#include <atomic>
+#include <list>
+#include "crypto.hpp"
+
+#ifndef CASE_INSENSITIVE_EQUALS_AND_HASH
+#define CASE_INSENSITIVE_EQUALS_AND_HASH
+class case_insensitive_equals {
+public:
+ bool operator()(const std::string &key1, const std::string &key2) const {
+ return key1.size() == key2.size()
+ && equal(key1.cbegin(), key1.cend(), key2.cbegin(),
+ [](std::string::value_type key1v, std::string::value_type key2v)
+ { return tolower(key1v) == tolower(key2v); });
+ }
+};
+class case_insensitive_hash {
+public:
+ size_t operator()(const std::string &key) const {
+ size_t seed = 0;
+ for (auto &c : key) {
+ std::hash<char> hasher;
+ seed ^= hasher(std::tolower(c)) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
+ }
+ return seed;
+ }
+};
+#endif
+
+namespace webpp {
+ template <class socket_type>
+ class SocketClient;
+
+ template <class socket_type>
+ class SocketClientBase {
+ public:
+ virtual ~SocketClientBase() { connection.reset(); }
+
+ class SendStream : public std::iostream {
+ friend class SocketClientBase<socket_type>;
+ asio::streambuf streambuf;
+ public:
+ SendStream(): std::iostream(&streambuf) {}
+ size_t size() const {
+ return streambuf.size();
+ }
+ };
+
+ class Connection {
+ friend class SocketClientBase<socket_type>;
+ friend class SocketClient<socket_type>;
+
+ public:
+ std::unordered_multimap<std::string, std::string, case_insensitive_hash, case_insensitive_equals> header;
+ std::string remote_endpoint_address;
+ unsigned short remote_endpoint_port;
+
+ private:
+ explicit Connection(socket_type* socket): remote_endpoint_port(0), socket(socket), strand(socket->get_io_context()), closed(false) { }
+
+ class SendData {
+ public:
+ SendData(const std::shared_ptr<SendStream> &send_stream, const std::function<void(const std::error_code)> &callback) :
+ send_stream(send_stream), callback(callback) {}
+ std::shared_ptr<SendStream> send_stream;
+ std::function<void(const std::error_code)> callback;
+ };
+
+ std::unique_ptr<socket_type> socket;
+
+ asio::io_context::strand strand;
+
+ std::list<SendData> send_queue;
+
+ void send_from_queue() {
+ strand.post([this]() {
+ asio::async_write(*socket, send_queue.begin()->send_stream->streambuf,
+ strand.wrap([this](const std::error_code& ec, size_t /*bytes_transferred*/) {
+ auto send_queued=send_queue.begin();
+ if(send_queued->callback)
+ send_queued->callback(ec);
+ if(!ec) {
+ send_queue.erase(send_queued);
+ if(send_queue.size()>0)
+ send_from_queue();
+ }
+ else
+ send_queue.clear();
+ }));
+ });
+ }
+
+ std::atomic<bool> closed;
+
+ void read_remote_endpoint_data() {
+ try {
+ remote_endpoint_address=socket->lowest_layer().remote_endpoint().address().to_string();
+ remote_endpoint_port=socket->lowest_layer().remote_endpoint().port();
+ }
+ catch(const std::exception& e) {
+ std::cerr << e.what() << std::endl;
+ }
+ }
+ };
+
+ std::shared_ptr<Connection> connection;
+
+ class Message : public std::istream {
+ friend class SocketClientBase<socket_type>;
+
+ public:
+ unsigned char fin_rsv_opcode;
+ size_t size() const {
+ return length;
+ }
+ std::string string() const {
+ std::stringstream ss;
+ ss << rdbuf();
+ return ss.str();
+ }
+ private:
+ Message(): std::istream(&streambuf), fin_rsv_opcode(0), length(0) { }
+
+ size_t length;
+ asio::streambuf streambuf;
+ };
+
+ std::function<void()> on_open;
+ std::function<void(std::shared_ptr<Message>)> on_message;
+ std::function<void(int, const std::string&)> on_close;
+ std::function<void(const std::error_code&)> on_error;
+
+ void start() {
+ if(!io_context) {
+ io_context=std::make_shared<asio::io_context>();
+ internal_io_context=true;
+ }
+
+ if(io_context->stopped())
+ io_context->reset();
+
+ if(!resolver)
+ resolver= std::make_unique<asio::ip::tcp::resolver>(*io_context);
+
+ connect();
+
+ if(internal_io_context)
+ io_context->run();
+ }
+
+ void stop() const {
+ resolver->cancel();
+ if(internal_io_context)
+ io_context->stop();
+ }
+
+ ///fin_rsv_opcode: 129=one fragment, text, 130=one fragment, binary, 136=close connection.
+ ///See http://tools.ietf.org/html/rfc6455#section-5.2 for more information
+ void send(const std::shared_ptr<SendStream> &message_stream, const std::function<void(const std::error_code&)>& callback=nullptr,
+ unsigned char fin_rsv_opcode=129) {
+ //Create mask
+ std::vector<unsigned char> mask;
+ mask.resize(4);
+ std::uniform_int_distribution<unsigned short> dist(0,255);
+ std::random_device rd;
+ for(int c=0;c<4;c++) {
+ mask[c]=static_cast<unsigned char>(dist(rd));
+ }
+
+ auto send_stream = std::make_shared<SendStream>();
+
+ size_t length=message_stream->size();
+
+ send_stream->put(fin_rsv_opcode);
+ //masked (first length byte>=128)
+ if(length>=126) {
+ int num_bytes;
+ if(length>0xffff) {
+ num_bytes=8;
+ send_stream->put(static_cast<unsigned char>(127+128));
+ }
+ else {
+ num_bytes=2;
+ send_stream->put(static_cast<unsigned char>(126+128));
+ }
+
+ for(int c=num_bytes-1;c>=0;c--) {
+ send_stream->put((static_cast<unsigned long long>(length) >> (8 * c)) % 256);
+ }
+ }
+ else
+ send_stream->put(static_cast<unsigned char>(length+128));
+
+ for(int c=0;c<4;c++) {
+ send_stream->put(mask[c]);
+ }
+
+ for(size_t c=0;c<length;c++) {
+ send_stream->put(message_stream->get()^mask[c%4]);
+ }
+
+ connection->strand.post([this, send_stream, callback]() {
+ connection->send_queue.emplace_back(send_stream, callback);
+ if(connection->send_queue.size()==1)
+ connection->send_from_queue();
+ });
+ }
+
+ void send_close(int status, const std::string& reason="", const std::function<void(const std::error_code&)>& callback=nullptr) {
+ //Send close only once (in case close is initiated by client)
+ if(connection->closed)
+ return;
+ connection->closed=true;
+
+ auto send_stream=std::make_shared<SendStream>();
+
+ send_stream->put(status>>8);
+ send_stream->put(status%256);
+
+ *send_stream << reason;
+
+ //fin_rsv_opcode=136: message close
+ send(send_stream, callback, 136);
+ }
+
+ /// If you have your own asio::io_context, store its pointer here before running start().
+ std::shared_ptr<asio::io_context> io_context;
+ protected:
+ const std::string ws_magic_string="258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
+
+ bool internal_io_context=false;
+ std::unique_ptr<asio::ip::tcp::resolver> resolver;
+
+ std::string host;
+ unsigned short port;
+ std::string path;
+
+ SocketClientBase(const std::string& host_port_path, unsigned short default_port) {
+ size_t host_end=host_port_path.find(':');
+ size_t host_port_end=host_port_path.find('/');
+ if(host_end==std::string::npos) {
+ host_end=host_port_end;
+ port=default_port;
+ }
+ else {
+ if(host_port_end==std::string::npos)
+ port=static_cast<unsigned short>(stoul(host_port_path.substr(host_end + 1)));
+ else
+ port=static_cast<unsigned short>(stoul(host_port_path.substr(host_end + 1, host_port_end - (host_end + 1))));
+ }
+ if(host_port_end==std::string::npos)
+ path="/";
+ else
+ path=host_port_path.substr(host_port_end);
+ if(host_end==std::string::npos)
+ host=host_port_path;
+ else
+ host=host_port_path.substr(0, host_end);
+ }
+
+ virtual void connect()=0;
+
+ void handshake() {
+ connection->read_remote_endpoint_data();
+
+ auto write_buffer = std::make_shared<asio::streambuf>();
+
+ std::ostream request(write_buffer.get());
+
+ request << "GET " << path << " HTTP/1.1" << "\r\n";
+ request << "Host: " << host << "\r\n";
+ request << "Upgrade: websocket\r\n";
+ request << "Connection: Upgrade\r\n";
+
+ //Make random 16-byte nonce
+ std::string nonce;
+ nonce.resize(16);
+ std::uniform_int_distribution<unsigned short> dist(0,255);
+ std::random_device rd;
+ for(int c=0;c<16;c++)
+ nonce[c]=static_cast<unsigned char>(dist(rd));
+
+ auto nonce_base64 = std::make_shared<std::string>(base64_encode(nonce));
+ request << "Sec-WebSocket-Key: " << *nonce_base64 << "\r\n";
+ request << "Sec-WebSocket-Version: 13\r\n";
+ request << "\r\n";
+
+ asio::async_write(*connection->socket, *write_buffer,
+ [this, write_buffer, nonce_base64]
+ (const std::error_code& ec, size_t /*bytes_transferred*/) {
+ if(!ec) {
+ std::shared_ptr<Message> message(new Message());
+
+ asio::async_read_until(*connection->socket, message->streambuf, "\r\n\r\n",
+ [this, message, nonce_base64]
+ (const std::error_code& ec, size_t /*bytes_transferred*/) {
+ if(!ec) {
+ parse_handshake(*message);
+ auto header_it = connection->header.find("Sec-WebSocket-Accept");
+ if (header_it != connection->header.end() &&
+ base64_decode(header_it->second) == sha1_encode(*nonce_base64 + ws_magic_string)) {
+ if(on_open)
+ on_open();
+ read_message(message);
+ }
+ else if(on_error)
+ on_error(std::error_code(int(std::errc::protocol_error), std::generic_category()));
+ }
+ else if(on_error)
+ on_error(ec);
+ });
+ }
+ else if(on_error)
+ on_error(ec);
+ });
+ }
+
+ void parse_handshake(std::istream& stream) const {
+ std::string line;
+ getline(stream, line);
+ //Not parsing the first line
+
+ getline(stream, line);
+ size_t param_end;
+ while((param_end=line.find(':'))!=std::string::npos) {
+ size_t value_start=param_end+1;
+ if((value_start)<line.size()) {
+ if(line[value_start]==' ')
+ value_start++;
+ if(value_start<line.size())
+ connection->header.emplace(line.substr(0, param_end), line.substr(value_start, line.size()-value_start-1));
+ }
+
+ getline(stream, line);
+ }
+ }
+
+ void read_message(const std::shared_ptr<Message> &message) {
+ asio::async_read(*connection->socket, message->streambuf, asio::transfer_exactly(2),
+ [this, message](const std::error_code& ec, size_t bytes_transferred) {
+ if(!ec) {
+ if(bytes_transferred==0) { //TODO: This might happen on server at least, might also happen here
+ read_message(message);
+ return;
+ }
+ std::vector<unsigned char> first_bytes;
+ first_bytes.resize(2);
+ message->read(reinterpret_cast<char*>(&first_bytes[0]), 2);
+
+ message->fin_rsv_opcode=first_bytes[0];
+
+ //Close connection if masked message from server (protocol error)
+ if(first_bytes[1]>=128) {
+ const std::string reason("message from server masked");
+ auto kept_connection=connection;
+ send_close(1002, reason, [this, kept_connection](const std::error_code& /*ec*/) {});
+ if(on_close)
+ on_close(1002, reason);
+ return;
+ }
+
+ size_t length=(first_bytes[1]&127);
+
+ if(length==126) {
+ //2 next bytes is the size of content
+ asio::async_read(*connection->socket, message->streambuf, asio::transfer_exactly(2),
+ [this, message]
+ (const std::error_code& ec, size_t /*bytes_transferred*/) {
+ if(!ec) {
+ std::vector<unsigned char> length_bytes;
+ length_bytes.resize(2);
+ message->read(reinterpret_cast<char*>(&length_bytes[0]), 2);
+
+ size_t length=0;
+ int num_bytes=2;
+ for(int c=0;c<num_bytes;c++)
+ length+=length_bytes[c]<<(8*(num_bytes-1-c));
+
+ message->length=length;
+ read_message_content(message);
+ }
+ else if(on_error)
+ on_error(ec);
+ });
+ }
+ else if(length==127) {
+ //8 next bytes is the size of content
+ asio::async_read(*connection->socket, message->streambuf, asio::transfer_exactly(8),
+ [this, message]
+ (const std::error_code& ec, size_t /*bytes_transferred*/) {
+ if(!ec) {
+ std::vector<unsigned char> length_bytes;
+ length_bytes.resize(8);
+ message->read(reinterpret_cast<char*>(&length_bytes[0]), 8);
+
+ size_t length=0;
+ int num_bytes=8;
+ for(int c=0;c<num_bytes;c++)
+ length+=length_bytes[c]<<(8*(num_bytes-1-c));
+
+ message->length=length;
+ read_message_content(message);
+ }
+ else if(on_error)
+ on_error(ec);
+ });
+ }
+ else {
+ message->length=length;
+ read_message_content(message);
+ }
+ }
+ else if(on_error)
+ on_error(ec);
+ });
+ }
+
+ void read_message_content(const std::shared_ptr<Message> &message) {
+ asio::async_read(*connection->socket, message->streambuf, asio::transfer_exactly(message->length),
+ [this, message]
+ (const std::error_code& ec, size_t /*bytes_transferred*/) {
+ if(!ec) {
+ //If connection close
+ if((message->fin_rsv_opcode&0x0f)==8) {
+ int status=0;
+ if(message->length>=2) {
+ unsigned char byte1=message->get();
+ unsigned char byte2=message->get();
+ status=(byte1<<8)+byte2;
+ }
+
+ auto reason=message->string();
+ auto kept_connection=connection;
+ send_close(status, reason, [this, kept_connection](const std::error_code& /*ec*/) {});
+ if(on_close)
+ on_close(status, reason);
+ return;
+ }
+ //If ping
+ else if((message->fin_rsv_opcode&0x0f)==9) {
+ //send pong
+ auto empty_send_stream=std::make_shared<SendStream>();
+ send(empty_send_stream, nullptr, message->fin_rsv_opcode+1);
+ }
+ else if(on_message) {
+ on_message(message);
+ }
+
+ //Next message
+ std::shared_ptr<Message> next_message(new Message());
+ read_message(next_message);
+ }
+ else if(on_error)
+ on_error(ec);
+ });
+ }
+ };
+
+ template<class socket_type>
+ class SocketClient : public SocketClientBase<socket_type> {
+ public:
+ SocketClient(const std::string& host_port_path, unsigned short default_port)
+ : SocketClientBase<socket_type>(host_port_path, default_port)
+ {
+ }
+ };
+
+ using WS = asio::ip::tcp::socket;
+
+ template<>
+ class SocketClient<WS> : public SocketClientBase<WS> {
+ public:
+ explicit SocketClient(const std::string& server_port_path) : SocketClientBase(server_port_path, 80) {};
+
+ protected:
+ void connect() override {
+ asio::ip::tcp::resolver::query query(host, std::to_string(port));
+
+ resolver->async_resolve(query, [this]
+ (const std::error_code &ec, asio::ip::tcp::resolver::iterator it){
+ if(!ec) {
+ connection=std::shared_ptr<Connection>(new Connection(new WS(*io_context)));
+
+ asio::async_connect(*connection->socket, it, [this]
+ (const std::error_code &ec, asio::ip::tcp::resolver::iterator /*it*/){
+ if(!ec) {
+ asio::ip::tcp::no_delay option(true);
+ connection->socket->set_option(option);
+
+ handshake();
+ }
+ else if(on_error)
+ on_error(ec);
+ });
+ }
+ else if(on_error)
+ on_error(ec);
+ });
+ }
+ };
+
+ class ws_client : public SocketClient<WS> {
+ public:
+ explicit ws_client(const std::string& server_port_path) : SocketClient<WS>::SocketClient(server_port_path) {}
+ };
+}
+
+#endif /* CLIENT_WS_HPP */
diff --git a/src/lib/util/client_wss.hpp b/src/lib/util/client_wss.hpp
new file mode 100644
index 00000000000..ef30b459607
--- /dev/null
+++ b/src/lib/util/client_wss.hpp
@@ -0,0 +1,82 @@
+// license:MIT
+// copyright-holders:Ole Christian Eidheim, Miodrag Milanovic
+#ifndef CLIENT_WSS_HPP
+#define CLIENT_WSS_HPP
+
+#include "client_ws.hpp"
+#include "asio/ssl.hpp"
+
+namespace webpp {
+ using WSS = asio::ssl::stream<asio::ip::tcp::socket>;
+
+ template<>
+ class SocketClient<WSS> : public SocketClientBase<WSS> {
+ public:
+ explicit SocketClient(const std::string& server_port_path, bool verify_certificate=true,
+ const std::string& cert_file=std::string(), const std::string& private_key_file=std::string(),
+ const std::string& verify_file=std::string()) :
+ SocketClientBase(server_port_path, 443),
+ context(asio::ssl::context::tlsv12) {
+ if(cert_file.size()>0 && private_key_file.size()>0) {
+ context.use_certificate_chain_file(cert_file);
+ context.use_private_key_file(private_key_file, asio::ssl::context::pem);
+ }
+
+ if (verify_certificate)
+ context.set_verify_callback(asio::ssl::rfc2818_verification(host));
+
+ if (verify_file.size() > 0)
+ context.load_verify_file(verify_file);
+ else
+ context.set_default_verify_paths();
+
+ if (verify_file.size()>0 || verify_certificate)
+ context.set_verify_mode(asio::ssl::verify_peer);
+ else
+ context.set_verify_mode(asio::ssl::verify_none);
+ };
+
+ protected:
+ asio::ssl::context context;
+
+ void connect() override {
+ asio::ip::tcp::resolver::query query(host, std::to_string(port));
+
+ resolver->async_resolve(query, [this]
+ (const std::error_code &ec, asio::ip::tcp::resolver::iterator it){
+ if(!ec) {
+ connection=std::shared_ptr<Connection>(new Connection(new WSS(*io_context, context)));
+
+ asio::async_connect(connection->socket->lowest_layer(), it, [this]
+ (const std::error_code &ec, asio::ip::tcp::resolver::iterator /*it*/){
+ if(!ec) {
+ asio::ip::tcp::no_delay option(true);
+ connection->socket->lowest_layer().set_option(option);
+
+ connection->socket->async_handshake(asio::ssl::stream_base::client,
+ [this](const std::error_code& ec) {
+ if(!ec)
+ handshake();
+ else if(on_error)
+ on_error(ec);
+ });
+ }
+ else if(on_error)
+ on_error(ec);
+ });
+ }
+ else if(on_error)
+ on_error(ec);
+ });
+ }
+ };
+
+ class wss_client : public SocketClient<WSS> {
+ public:
+ explicit wss_client(const std::string& server_port_path, bool verify_certificate = true,
+ const std::string& cert_file = std::string(), const std::string& private_key_file = std::string(),
+ const std::string& verify_file = std::string()) : SocketClient<WSS>::SocketClient(server_port_path, verify_certificate, cert_file, private_key_file, verify_file) {}
+ };
+}
+
+#endif /* CLIENT_WSS_HPP */
diff --git a/src/lib/util/crypto.hpp b/src/lib/util/crypto.hpp
new file mode 100644
index 00000000000..705aad6a375
--- /dev/null
+++ b/src/lib/util/crypto.hpp
@@ -0,0 +1,18 @@
+// license:MIT
+// copyright-holders:Miodrag Milanovic
+#ifndef CRYPTO_HPP
+#define CRYPTO_HPP
+
+#include "base64.hpp"
+#include "sha1.hpp"
+
+inline std::string sha1_encode(const std::string& input)
+{
+ char message_digest[20];
+ sha1::calc(input.c_str(),input.length(),reinterpret_cast<unsigned char*>(message_digest));
+
+ return std::string(message_digest, sizeof(message_digest));
+
+}
+#endif /* CRYPTO_HPP */
+
diff --git a/src/lib/util/path_to_regex.cpp b/src/lib/util/path_to_regex.cpp
new file mode 100644
index 00000000000..927ababbb8a
--- /dev/null
+++ b/src/lib/util/path_to_regex.cpp
@@ -0,0 +1,217 @@
+// license:MIT
+// copyright-holders:Alfred Bratterud
+// NOTE: Author allowed MAME project to distribute this file under MIT
+// license. Other projects need to do it under Apache 2 license
+//
+// This file is a part of the IncludeOS unikernel - www.includeos.org
+//
+// Copyright 2015-2016 Oslo and Akershus University College of Applied Sciences
+// and Alfred Bratterud
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// https://github.com/pillarjs/path-to-regexp/blob/master/index.js
+
+#include "path_to_regex.hpp"
+
+namespace path2regex {
+
+const std::regex PATH_REGEXP =
+ std::regex{"((\\\\.)|(([\\/.])?(?:(?:\\:(\\w+)(?:\\(((?:\\\\.|[^\\\\()])+)\\))?|\\(((?:\\\\.|[^\\\\()])+)\\))([+*?])?|(\\*))))"};
+
+std::regex path_to_regex(const std::string& path, Keys& keys, const Options& options) {
+ Tokens all_tokens = parse(path);
+ tokens_to_keys(all_tokens, keys); // fill keys with relevant tokens
+ return tokens_to_regex(all_tokens, options);
+}
+
+std::regex path_to_regex(const std::string& path, const Options& options) {
+ return tokens_to_regex(parse(path), options);
+}
+
+// Parse a string for the raw tokens
+std::vector<Token> parse(const std::string& str) {
+ if (str.empty())
+ return {};
+
+ Tokens tokens;
+ int key = 0;
+ int index = 0;
+ std::string path = "";
+ std::smatch res;
+
+ for (std::sregex_iterator i = std::sregex_iterator{str.begin(), str.end(), PATH_REGEXP};
+ i != std::sregex_iterator{}; ++i) {
+
+ res = *i;
+
+ std::string m = res[0]; // the parameter, f.ex. /:test
+ std::string escaped = res[2];
+ int offset = res.position();
+
+ // JS: path += str.slice(index, offset); from and included index to and included offset-1
+ path += str.substr(index, (offset - index)); // from index, number of chars: offset - index
+
+ index = offset + m.size();
+
+ if (!escaped.empty()) {
+ path += escaped[1]; // if escaped == \a, escaped[1] == a (if str is "/\\a" f.ex.)
+ continue;
+ }
+
+ std::string next = (size_t(index) < str.size()) ? std::string{str.at(index)} : "";
+
+ std::string prefix = res[4]; // f.ex. /
+ std::string name = res[5]; // f.ex. test
+ std::string capture = res[6]; // f.ex. \d+
+ std::string group = res[7]; // f.ex. (users|admins)
+ std::string modifier = res[8]; // f.ex. ?
+ std::string asterisk = res[9]; // * if path is /*
+
+ // Push the current path onto the tokens
+ if (!path.empty()) {
+ Token stringToken;
+ stringToken.set_string_token(path);
+ tokens.push_back(stringToken);
+ path = "";
+ }
+
+ bool partial = (!prefix.empty()) && (!next.empty()) && (next != prefix);
+ bool repeat = (modifier == "+") || (modifier == "*");
+ bool optional = (modifier == "?") || (modifier == "*");
+ std::string delimiter = (!prefix.empty()) ? prefix : "/";
+ std::string pattern;
+
+ if (!capture.empty())
+ pattern = capture;
+ else if (!group.empty())
+ pattern = group;
+ else
+ pattern = (!asterisk.empty()) ? ".*" : ("[^" + delimiter + "]+?");
+
+ Token t;
+ t.name = (!name.empty()) ? name : std::to_string(key++);
+ t.prefix = prefix;
+ t.delimiter = delimiter;
+ t.optional = optional;
+ t.repeat = repeat;
+ t.partial = partial;
+ t.asterisk = (asterisk == "*");
+ t.pattern = pattern;
+ t.is_string = false;
+ tokens.push_back(t);
+ }
+
+ // Match any characters still remaining
+ if (size_t(index) < str.size())
+ path += str.substr(index);
+
+ // If the path exists, push it onto the end
+ if (!path.empty()) {
+ Token stringToken;
+ stringToken.set_string_token(path);
+ tokens.push_back(stringToken);
+ }
+
+ return tokens;
+}
+
+// Creates a regex based on the given tokens and options (optional)
+std::regex tokens_to_regex(const Tokens& tokens, const Options& options) {
+ if (tokens.empty())
+ return std::regex{""};
+
+ // Set default values for options:
+ bool strict = false;
+ bool sensitive = false;
+ bool end = true;
+
+ if (!options.empty()) {
+ auto it = options.find("strict");
+ strict = (it != options.end()) ? options.find("strict")->second : false;
+
+ it = options.find("sensitive");
+ sensitive = (it != options.end()) ? options.find("sensitive")->second : false;
+
+ it = options.find("end");
+ end = (it != options.end()) ? options.find("end")->second : true;
+ }
+
+ std::string route = "";
+ Token lastToken = tokens[tokens.size() - 1];
+ std::regex re{"(.*\\/$)"};
+ bool endsWithSlash = lastToken.is_string && std::regex_match(lastToken.name, re);
+ // endsWithSlash if the last char in lastToken's name is a slash
+
+ // Iterate over the tokens and create our regexp string
+ for (size_t i = 0; i < tokens.size(); i++) {
+ Token token = tokens[i];
+
+ if (token.is_string) {
+ route += token.name;
+ } else {
+ std::string prefix = token.prefix;
+ std::string capture = "(?:" + token.pattern + ")";
+
+ if (token.repeat)
+ capture += "(?:" + prefix + capture + ")*";
+
+ if (token.optional) {
+
+ if (!token.partial)
+ capture = "(?:" + prefix + "(" + capture + "))?";
+ else
+ capture = prefix + "(" + capture + ")?";
+
+ } else {
+ capture = prefix + "(" + capture + ")";
+ }
+
+ route += capture;
+ }
+ }
+
+ // In non-strict mode we allow a slash at the end of match. If the path to
+ // match already ends with a slash, we remove it for consistency. The slash
+ // is valid at the end of a path match, not in the middle. This is important
+ // in non-ending mode, where "/test/" shouldn't match "/test//route".
+
+ if (!strict) {
+ if (endsWithSlash)
+ route = route.substr(0, (route.size() - 1));
+
+ route += "(?:\\/(?=$))?";
+ }
+
+ if (end) {
+ route += "$";
+ } else {
+ // In non-ending mode, we need the capturing groups to match as much as
+ // possible by using a positive lookahead to the end or next path segment
+ if (!(strict && endsWithSlash))
+ route += "(?=\\/|$)";
+ }
+
+ if (sensitive)
+ return std::regex{"^" + route};
+
+ return std::regex{"^" + route, std::regex_constants::ECMAScript | std::regex_constants::icase};
+}
+
+void tokens_to_keys(const Tokens& tokens, Keys& keys) {
+ for (const auto& token : tokens)
+ if (!token.is_string)
+ keys.push_back(token);
+}
+
+} //< namespace route
diff --git a/src/lib/util/path_to_regex.hpp b/src/lib/util/path_to_regex.hpp
new file mode 100644
index 00000000000..7608d77bb5d
--- /dev/null
+++ b/src/lib/util/path_to_regex.hpp
@@ -0,0 +1,110 @@
+// license:MIT
+// copyright-holders:Alfred Bratterud
+// NOTE: Author allowed MAME project to distribute this file under MIT
+// license. Other projects need to do it under Apache 2 license
+//
+// This file is a part of the IncludeOS unikernel - www.includeos.org
+//
+// Copyright 2015-2016 Oslo and Akershus University College of Applied Sciences
+// and Alfred Bratterud
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// https://github.com/pillarjs/path-to-regexp/blob/master/index.js
+
+#ifndef PATH_TO_REGEX_HPP
+#define PATH_TO_REGEX_HPP
+
+#include <map>
+#include <regex>
+#include <vector>
+
+namespace path2regex {
+
+struct Token {
+ std::string name {}; // can be a string or an int (index)
+ std::string prefix {};
+ std::string delimiter {};
+ std::string pattern {};
+ bool optional {false};
+ bool repeat {false};
+ bool partial {false};
+ bool asterisk {false};
+ bool is_string {false}; // If it is a string we only put/have a string in the name-attribute (path in parse-method)
+ // So if this is true, we can ignore all attributes except name
+
+ void set_string_token(const std::string& name_) {
+ name = name_;
+ is_string = true;
+ }
+}; //< struct Token
+
+using Keys = std::vector<Token>;
+using Tokens = std::vector<Token>;
+using Options = std::map<std::string, bool>;
+
+ /**
+ * Creates a path-regex from string input (path)
+ * Updates keys-vector (empty input parameter)
+ *
+ * Calls parse-method and then tokens_to_regex-method based on the tokens returned from parse-method
+ * Puts the tokens that are keys (not string-tokens) into keys-vector
+ *
+ * std::vector<Token> keys (empty)
+ * Is created outside the class and sent in as parameter
+ * One Token-object in the keys-vector per parameter found in the path
+ *
+ * std::map<std::string, bool> options (optional)
+ * Can contain bool-values for the keys "sensitive", "strict" and/or "end"
+ * Default:
+ * strict = false
+ * sensitive = false
+ * end = true
+ */
+ std::regex path_to_regex(const std::string& path, Keys& keys, const Options& options = Options{});
+
+ /**
+ * Creates a path-regex from string input (path)
+ *
+ * Calls parse-method and then tokens_to_regex-method based on the tokens returned from parse-method
+ *
+ * std::map<std::string, bool> options (optional)
+ * Can contain bool-values for the keys "sensitive", "strict" and/or "end"
+ * Default:
+ * strict = false
+ * sensitive = false
+ * end = true
+ */
+ std::regex path_to_regex(const std::string& path, const Options& options = Options{});
+
+ /**
+ * Creates vector of tokens based on the given string (this vector of tokens can be sent as
+ * input to tokens_to_regex-method and includes tokens that are strings, not only tokens
+ * that are parameters in str)
+ */
+ Tokens parse(const std::string& str);
+
+ /**
+ * Creates a regex based on the tokens and options (optional) given
+ */
+ std::regex tokens_to_regex(const Tokens& tokens, const Options& options = Options{});
+
+ /**
+ * Goes through the tokens-vector and push all tokens that are not string-tokens
+ * onto keys-vector
+ */
+ void tokens_to_keys(const Tokens& tokens, Keys& keys);
+
+} //< namespace path2regex
+
+#endif //< PATH_TO_REGEX_HPP
diff --git a/src/lib/util/server_http.hpp b/src/lib/util/server_http.hpp
new file mode 100644
index 00000000000..57fd57e6993
--- /dev/null
+++ b/src/lib/util/server_http.hpp
@@ -0,0 +1,497 @@
+// license:MIT
+// copyright-holders:Ole Christian Eidheim, Miodrag Milanovic
+#ifndef SERVER_HTTP_HPP
+#define SERVER_HTTP_HPP
+
+#if defined(_MSC_VER)
+#pragma warning(disable:4503)
+#endif
+
+#include "asio.h"
+#include "asio/system_timer.hpp"
+#include "path_to_regex.hpp"
+
+#include <map>
+#include <unordered_map>
+#include <thread>
+#include <functional>
+#include <iostream>
+#include <sstream>
+#include <regex>
+
+#ifndef CASE_INSENSITIVE_EQUALS_AND_HASH
+#define CASE_INSENSITIVE_EQUALS_AND_HASH
+class case_insensitive_equals {
+public:
+ bool operator()(const std::string &key1, const std::string &key2) const {
+ return key1.size() == key2.size()
+ && equal(key1.cbegin(), key1.cend(), key2.cbegin(),
+ [](std::string::value_type key1v, std::string::value_type key2v)
+ { return tolower(key1v) == tolower(key2v); });
+ }
+};
+class case_insensitive_hash {
+public:
+ size_t operator()(const std::string &key) const {
+ size_t seed = 0;
+ for (auto &c : key) {
+ std::hash<char> hasher;
+ seed ^= hasher(std::tolower(c)) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
+ }
+ return seed;
+ }
+};
+#endif
+namespace webpp {
+ template <class socket_type>
+ class Server;
+
+ template <class socket_type>
+ class ServerBase {
+ public:
+ virtual ~ServerBase() {}
+
+ class Response {
+ friend class ServerBase<socket_type>;
+
+ asio::streambuf m_streambuf;
+
+ std::shared_ptr<socket_type> m_socket;
+ std::ostream m_ostream;
+ std::stringstream m_header;
+ explicit Response(const std::shared_ptr<socket_type> &socket) : m_socket(socket), m_ostream(&m_streambuf) {}
+
+ static std::string statusToString(int status)
+ {
+ switch (status) {
+ default:
+ case 200: return "HTTP/1.0 200 OK\r\n";
+ case 201: return "HTTP/1.0 201 Created\r\n";
+ case 202: return "HTTP/1.0 202 Accepted\r\n";
+ case 204: return "HTTP/1.0 204 No Content\r\n";
+ case 300: return "HTTP/1.0 300 Multiple Choices\r\n";
+ case 301: return "HTTP/1.0 301 Moved Permanently\r\n";
+ case 302: return "HTTP/1.0 302 Moved Temporarily\r\n";
+ case 304: return "HTTP/1.0 304 Not Modified\r\n";
+ case 400: return "HTTP/1.0 400 Bad Request\r\n";
+ case 401: return "HTTP/1.0 401 Unauthorized\r\n";
+ case 403: return "HTTP/1.0 403 Forbidden\r\n";
+ case 404: return "HTTP/1.0 404 Not Found\r\n";
+ case 500: return "HTTP/1.0 500 Internal Server Error\r\n";
+ case 501: return "HTTP/1.0 501 Not Implemented\r\n";
+ case 502: return "HTTP/1.0 502 Bad Gateway\r\n";
+ case 504: return "HTTP/1.0 503 Service Unavailable\r\n";
+ }
+ }
+ public:
+ Response& status(int number) { m_ostream << statusToString(number); return *this; }
+ void type(std::string str) { m_header << "Content-Type: "<< str << "\r\n"; }
+ void send(std::string str) { m_ostream << m_header.str() << "Content-Length: " << str.length() << "\r\n\r\n" << str; }
+ size_t size() const { return m_streambuf.size(); }
+ std::shared_ptr<socket_type> socket() { return m_socket; }
+ };
+
+ class Content : public std::istream {
+ friend class ServerBase<socket_type>;
+ public:
+ size_t size() const {
+ return streambuf.size();
+ }
+ std::string string() const {
+ std::stringstream ss;
+ ss << rdbuf();
+ return ss.str();
+ }
+ private:
+ asio::streambuf &streambuf;
+ explicit Content(asio::streambuf &streambuf): std::istream(&streambuf), streambuf(streambuf) {}
+ };
+
+ class Request {
+ friend class ServerBase<socket_type>;
+ friend class Server<socket_type>;
+ public:
+ std::string method, path, http_version;
+
+ Content content;
+
+ std::unordered_multimap<std::string, std::string, case_insensitive_hash, case_insensitive_equals> header;
+
+ path2regex::Keys keys;
+ std::map<std::string, std::string> params;
+
+ std::string remote_endpoint_address;
+ unsigned short remote_endpoint_port;
+
+ private:
+ Request(const socket_type &socket): content(streambuf) {
+ try {
+ remote_endpoint_address=socket.lowest_layer().remote_endpoint().address().to_string();
+ remote_endpoint_port=socket.lowest_layer().remote_endpoint().port();
+ }
+ catch(...) {}
+ }
+ asio::streambuf streambuf;
+ };
+
+ class Config {
+ friend class ServerBase<socket_type>;
+
+ Config(unsigned short port) : port(port) {}
+ public:
+ /// Port number to use. Defaults to 80 for HTTP and 443 for HTTPS.
+ unsigned short port;
+ /// Number of threads that the server will use when start() is called. Defaults to 1 thread.
+ size_t thread_pool_size=1;
+ /// Timeout on request handling. Defaults to 5 seconds.
+ size_t timeout_request=5;
+ /// Timeout on content handling. Defaults to 300 seconds.
+ size_t timeout_content=300;
+ /// IPv4 address in dotted decimal form or IPv6 address in hexadecimal notation.
+ /// If empty, the address will be any address.
+ std::string address;
+ /// Set to false to avoid binding the socket to an address that is already in use. Defaults to true.
+ bool reuse_address=true;
+ };
+ ///Set before calling start().
+ Config m_config;
+ private:
+ class regex_orderable : public std::regex {
+ std::string str;
+ public:
+ regex_orderable(std::regex reg, const std::string &regex_str) : std::regex(reg), str(regex_str) {}
+ bool operator<(const regex_orderable &rhs) const {
+ return str<rhs.str;
+ }
+ std::string getstr() const { return str; }
+ };
+ using http_handler = std::function<void(std::shared_ptr<Response>, std::shared_ptr<Request>)>;
+
+ public:
+ template<class T> void on_get(std::string regex, T&& func) { std::lock_guard<std::mutex> lock(m_resource_mutex); path2regex::Keys keys; auto reg = path2regex::path_to_regex(regex, keys); m_resource[regex_orderable(reg,regex)]["GET"] = std::make_tuple(std::move(keys), func); }
+ template<class T> void on_get(T&& func) { std::lock_guard<std::mutex> lock(m_resource_mutex); m_default_resource["GET"] = func; }
+ template<class T> void on_post(std::string regex, T&& func) { std::lock_guard<std::mutex> lock(m_resource_mutex); path2regex::Keys keys; auto reg = path2regex::path_to_regex(regex, keys); m_resource[regex_orderable(reg, regex)]["POST"] = std::make_tuple(std::move(keys), func); }
+ template<class T> void on_post(T&& func) { std::lock_guard<std::mutex> lock(m_resource_mutex); m_default_resource["POST"] = func; }
+ template<class T> void on_put(std::string regex, T&& func) { std::lock_guard<std::mutex> lock(m_resource_mutex); path2regex::Keys keys; auto reg = path2regex::path_to_regex(regex, keys); m_resource[regex_orderable(reg, regex)]["PUT"] = std::make_tuple(std::move(keys), func); }
+ template<class T> void on_put(T&& func) { std::lock_guard<std::mutex> lock(m_resource_mutex); m_default_resource["PUT"] = func; }
+ template<class T> void on_patch(std::string regex, T&& func) { std::lock_guard<std::mutex> lock(m_resource_mutex); path2regex::Keys keys; auto reg = path2regex::path_to_regex(regex, keys); m_resource[regex_orderable(reg, regex)]["PATCH"] = std::make_tuple(std::move(keys), func); }
+ template<class T> void on_patch(T&& func) { std::lock_guard<std::mutex> lock(m_resource_mutex); m_default_resource["PATCH"] = func; }
+ template<class T> void on_delete(std::string regex, T&& func) { std::lock_guard<std::mutex> lock(m_resource_mutex); path2regex::Keys keys; auto reg = path2regex::path_to_regex(regex, keys); m_resource[regex_orderable(reg, regex)]["DELETE"] = std::make_tuple(std::move(keys), func); }
+ template<class T> void on_delete(T&& func) { std::lock_guard<std::mutex> lock(m_resource_mutex); m_default_resource["DELETE"] = func; }
+
+ void remove_handler(std::string regex)
+ {
+ std::lock_guard<std::mutex> lock(m_resource_mutex);
+ for (auto &it = m_resource.begin(); it != m_resource.end(); ++it)
+ {
+ if (it->first.getstr() == regex)
+ {
+ m_resource.erase(it);
+ break;
+ }
+ }
+ }
+
+ std::function<void(std::shared_ptr<typename ServerBase<socket_type>::Request>, const std::error_code&)> on_error;
+
+ std::function<void(std::shared_ptr<socket_type> socket, std::shared_ptr<typename ServerBase<socket_type>::Request>)> on_upgrade;
+ private:
+ /// Warning: do not add or remove resources after start() is called
+ std::map<regex_orderable, std::map<std::string, std::tuple<path2regex::Keys, http_handler>>> m_resource;
+
+ std::map<std::string, http_handler> m_default_resource;
+
+ std::mutex m_resource_mutex;
+ public:
+ virtual void start() {
+ if(!m_io_context)
+ m_io_context=std::make_shared<asio::io_context>();
+
+ if(m_io_context->stopped())
+ m_io_context.reset();
+
+ asio::ip::tcp::endpoint endpoint;
+ if(m_config.address.size()>0)
+ endpoint=asio::ip::tcp::endpoint(asio::ip::make_address(m_config.address), m_config.port);
+ else
+ endpoint=asio::ip::tcp::endpoint(asio::ip::tcp::v4(), m_config.port);
+
+ if(!acceptor)
+ acceptor= std::make_unique<asio::ip::tcp::acceptor>(*m_io_context);
+ acceptor->open(endpoint.protocol());
+ acceptor->set_option(asio::socket_base::reuse_address(m_config.reuse_address));
+ acceptor->bind(endpoint);
+ acceptor->listen();
+
+ accept();
+
+ if (!m_external_context)
+ m_io_context->run();
+ }
+
+ void stop() const
+ {
+ acceptor->close();
+ if (!m_external_context)
+ m_io_context->stop();
+ }
+
+ ///Use this function if you need to recursively send parts of a longer message
+ void send(const std::shared_ptr<Response> &response, const std::function<void(const std::error_code&)>& callback=nullptr) const {
+ asio::async_write(*response->socket(), response->m_streambuf, [this, response, callback](const std::error_code& ec, size_t /*bytes_transferred*/) {
+ if(callback)
+ callback(ec);
+ });
+ }
+
+ void set_io_context(std::shared_ptr<asio::io_context> new_io_context)
+ {
+ m_io_context = new_io_context;
+ m_external_context = true;
+ }
+ protected:
+ std::shared_ptr<asio::io_context> m_io_context;
+ bool m_external_context;
+ std::unique_ptr<asio::ip::tcp::acceptor> acceptor;
+ std::vector<std::thread> threads;
+
+ ServerBase(unsigned short port) : m_config(port), m_external_context(false) {}
+
+ virtual void accept()=0;
+
+ std::shared_ptr<asio::system_timer> get_timeout_timer(const std::shared_ptr<socket_type> &socket, long seconds) {
+ if(seconds==0)
+ return nullptr;
+ auto timer = std::make_shared<asio::system_timer>(*m_io_context);
+ timer->expires_at(std::chrono::system_clock::now() + std::chrono::seconds(seconds));
+ timer->async_wait([socket](const std::error_code& ec){
+ if(!ec) {
+ std::error_code newec = ec;
+ socket->lowest_layer().shutdown(asio::ip::tcp::socket::shutdown_both, newec);
+ socket->lowest_layer().close();
+ }
+ });
+ return timer;
+ }
+
+ void read_request_and_content(const std::shared_ptr<socket_type> &socket) {
+ //Create new streambuf (Request::streambuf) for async_read_until()
+ //shared_ptr is used to pass temporary objects to the asynchronous functions
+ std::shared_ptr<Request> request(new Request(*socket));
+
+ //Set timeout on the following asio::async-read or write function
+ auto timer = get_timeout_timer(socket, m_config.timeout_request);
+
+ asio::async_read_until(*socket, request->streambuf, "\r\n\r\n",
+ [this, socket, request, timer](const std::error_code& ec, size_t bytes_transferred) {
+ if(timer)
+ timer->cancel();
+ if(!ec) {
+ //request->streambuf.size() is not necessarily the same as bytes_transferred, from Boost-docs:
+ //"After a successful async_read_until operation, the streambuf may contain additional data beyond the delimiter"
+ //The chosen solution is to extract lines from the stream directly when parsing the header. What is left of the
+ //streambuf (maybe some bytes of the content) is appended to in the async_read-function below (for retrieving content).
+ size_t num_additional_bytes=request->streambuf.size()-bytes_transferred;
+
+ if (!parse_request(request))
+ return;
+
+ //If content, read that as well
+ auto it = request->header.find("Content-Length");
+ if (it != request->header.end()) {
+ unsigned long long content_length;
+ try {
+ content_length = stoull(it->second);
+ }
+ catch (const std::exception &) {
+ if (on_error)
+ on_error(request, std::error_code(EPROTO, std::generic_category()));
+ return;
+ }
+ if (content_length > num_additional_bytes) {
+ //Set timeout on the following asio::async-read or write function
+ auto timer2 = get_timeout_timer(socket, m_config.timeout_content);
+ asio::async_read(*socket, request->streambuf,
+ asio::transfer_exactly(size_t(content_length) - num_additional_bytes),
+ [this, socket, request, timer2]
+ (const std::error_code& ec, size_t /*bytes_transferred*/) {
+ if (timer2)
+ timer2->cancel();
+ if (!ec)
+ find_resource(socket, request);
+ else if (on_error)
+ on_error(request, ec);
+ });
+ }
+ else {
+ find_resource(socket, request);
+ }
+ }
+ else {
+ find_resource(socket, request);
+ }
+ }
+ else if (on_error)
+ on_error(request, ec);
+ });
+ }
+
+ bool parse_request(const std::shared_ptr<Request> &request) const {
+ std::string line;
+ getline(request->content, line);
+ size_t method_end;
+ if((method_end=line.find(' '))!=std::string::npos) {
+ size_t path_end;
+ if((path_end=line.find(' ', method_end+1))!=std::string::npos) {
+ request->method=line.substr(0, method_end);
+ request->path=line.substr(method_end+1, path_end-method_end-1);
+
+ size_t protocol_end;
+ if((protocol_end=line.find('/', path_end+1))!=std::string::npos) {
+ if(line.compare(path_end+1, protocol_end-path_end-1, "HTTP")!=0)
+ return false;
+ request->http_version=line.substr(protocol_end+1, line.size()-protocol_end-2);
+ }
+ else
+ return false;
+
+ getline(request->content, line);
+ size_t param_end;
+ while((param_end=line.find(':'))!=std::string::npos) {
+ size_t value_start=param_end+1;
+ if((value_start)<line.size()) {
+ if(line[value_start]==' ')
+ value_start++;
+ if(value_start<line.size())
+ request->header.emplace(line.substr(0, param_end), line.substr(value_start, line.size() - value_start - 1));
+ }
+
+ getline(request->content, line);
+ }
+ }
+ else
+ return false;
+ }
+ else
+ return false;
+ return true;
+ }
+
+ void find_resource(const std::shared_ptr<socket_type> &socket, const std::shared_ptr<Request> &request) {
+ std::lock_guard<std::mutex> lock(m_resource_mutex);
+ //Upgrade connection
+ if(on_upgrade) {
+ auto it=request->header.find("Upgrade");
+ if(it!=request->header.end()) {
+ on_upgrade(socket, request);
+ return;
+ }
+ }
+ //Find path- and method-match, and call write_response
+ for(auto& regex_method : m_resource) {
+ auto it = regex_method.second.find(request->method);
+ if (it != regex_method.second.end()) {
+ std::smatch sm_res;
+ if (std::regex_match(request->path, sm_res, regex_method.first)) {
+ request->keys = std::get<0>(it->second);
+ for (size_t i = 0; i < request->keys.size(); i++) {
+ request->params.insert(std::pair<std::string, std::string>(request->keys[i].name, sm_res[i + 1]));
+ }
+ write_response(socket, request, std::get<1>(it->second));
+ return;
+ }
+ }
+ }
+ auto it=m_default_resource.find(request->method);
+ if(it!=m_default_resource.end()) {
+ write_response(socket, request, it->second);
+ }
+ }
+
+ void write_response(const std::shared_ptr<socket_type> &socket, const std::shared_ptr<Request> &request, http_handler& resource_function) {
+ //Set timeout on the following asio::async-read or write function
+ auto timer = get_timeout_timer(socket, m_config.timeout_content);
+
+ auto response=std::shared_ptr<Response>(new Response(socket), [this, request, timer](Response *response_ptr) {
+ auto response=std::shared_ptr<Response>(response_ptr);
+ send(response, [this, response, request, timer](const std::error_code& ec) {
+ if (timer)
+ timer->cancel();
+ if (!ec) {
+ float http_version;
+ try {
+ http_version = stof(request->http_version);
+ }
+ catch (const std::exception &) {
+ if (on_error)
+ on_error(request, std::error_code(EPROTO, std::generic_category()));
+ return;
+ }
+
+ auto range = request->header.equal_range("Connection");
+ case_insensitive_equals check;
+ for (auto it = range.first; it != range.second; ++it) {
+ if (check(it->second, "close"))
+ return;
+ }
+ if (http_version > 1.05)
+ read_request_and_content(response->socket());
+ }
+ else if (on_error)
+ on_error(request, ec);
+ });
+ });
+
+ try {
+ resource_function(response, request);
+ }
+ catch(const std::exception &) {
+ if (on_error)
+ on_error(request, std::error_code(EPROTO, std::generic_category()));
+ }
+ }
+ };
+
+ template<class socket_type>
+ class Server : public ServerBase<socket_type> {
+ public:
+ Server(unsigned short port, size_t num_threads, long timeout_request, long timeout_send_or_receive)
+ : ServerBase<socket_type>(port, num_threads, timeout_request, timeout_send_or_receive)
+ {
+ }
+ };
+
+ using HTTP = asio::ip::tcp::socket;
+
+ template<>
+ class Server<HTTP> : public ServerBase<HTTP> {
+ public:
+ Server() : ServerBase<HTTP>::ServerBase(80) {}
+ protected:
+ void accept() override {
+ //Create new socket for this connection
+ //Shared_ptr is used to pass temporary objects to the asynchronous functions
+ auto socket = std::make_shared<HTTP>(*m_io_context);
+
+ acceptor->async_accept(*socket, [this, socket](const std::error_code& ec){
+ //Immediately start accepting a new connection (if io_context hasn't been stopped)
+ if (ec != asio::error::operation_aborted)
+ accept();
+
+ if(!ec) {
+ asio::ip::tcp::no_delay option(true);
+ socket->set_option(option);
+
+ read_request_and_content(socket);
+ } else if (on_error)
+ on_error(std::shared_ptr<Request>(new Request(*socket)), ec);
+ });
+ }
+ };
+
+ class http_server : public Server<HTTP> {
+ public:
+ http_server() : Server<HTTP>::Server() {}
+ };
+}
+#endif /* SERVER_HTTP_HPP */
diff --git a/src/lib/util/server_https.hpp b/src/lib/util/server_https.hpp
new file mode 100644
index 00000000000..e721cbb3e25
--- /dev/null
+++ b/src/lib/util/server_https.hpp
@@ -0,0 +1,99 @@
+// license:MIT
+// copyright-holders:Ole Christian Eidheim, Miodrag Milanovic
+#ifndef SERVER_HTTPS_HPP
+#define SERVER_HTTPS_HPP
+
+#include "server_http.hpp"
+#include "asio/ssl.hpp"
+#include <openssl/ssl.h>
+#include <algorithm>
+
+namespace webpp {
+ using HTTPS = asio::ssl::stream<asio::ip::tcp::socket>;
+
+ template<>
+ class Server<HTTPS> : public ServerBase<HTTPS> {
+ std::string session_id_context;
+ bool set_session_id_context = false;
+ public:
+ Server(unsigned short port, size_t thread_pool_size, const std::string& cert_file, const std::string& private_key_file,
+ long timeout_request = 5, long timeout_content = 300,
+ const std::string& verify_file = std::string()) :
+ Server(cert_file, private_key_file, verify_file) {
+ m_config.port=port;
+ m_config.thread_pool_size= thread_pool_size;
+ m_config.timeout_request=timeout_request;
+ m_config.timeout_content=timeout_content;
+ }
+
+ Server(const std::string& cert_file, const std::string& private_key_file, const std::string& verify_file = std::string()) :
+ ServerBase<HTTPS>::ServerBase(443), context(asio::ssl::context::tlsv12) {
+
+ context.use_certificate_chain_file(cert_file);
+ context.use_private_key_file(private_key_file, asio::ssl::context::pem);
+
+ if (verify_file.size() > 0) {
+ context.load_verify_file(verify_file);
+ context.set_verify_mode(asio::ssl::verify_peer | asio::ssl::verify_fail_if_no_peer_cert |
+ asio::ssl::verify_client_once);
+ set_session_id_context = true;
+ }
+ }
+ void start() override {
+ if (set_session_id_context) {
+ // Creating session_id_context from address:port but reversed due to small SSL_MAX_SSL_SESSION_ID_LENGTH
+ session_id_context = std::to_string(m_config.port) + ':';
+ session_id_context.append(m_config.address.rbegin(), m_config.address.rend());
+ SSL_CTX_set_session_id_context(context.native_handle(), reinterpret_cast<const unsigned char*>(session_id_context.data()),
+ std::min<size_t>(session_id_context.size(), SSL_MAX_SSL_SESSION_ID_LENGTH));
+
+ }
+ ServerBase::start();
+ }
+
+ protected:
+ asio::ssl::context context;
+
+ void accept() override {
+ //Create new socket for this connection
+ //Shared_ptr is used to pass temporary objects to the asynchronous functions
+ auto socket = std::make_shared<HTTPS>(*m_io_context, context);
+
+ acceptor->async_accept((*socket).lowest_layer(), [this, socket](const std::error_code& ec) {
+ //Immediately start accepting a new connection (if io_context hasn't been stopped)
+ if (ec != asio::error::operation_aborted)
+ accept();
+
+
+ if(!ec) {
+ asio::ip::tcp::no_delay option(true);
+ socket->lowest_layer().set_option(option);
+
+ //Set timeout on the following asio::ssl::stream::async_handshake
+ auto timer = get_timeout_timer(socket, m_config.timeout_request);
+ socket->async_handshake(asio::ssl::stream_base::server, [this, socket, timer]
+ (const std::error_code& ec) {
+ if(timer)
+ timer->cancel();
+ if(!ec)
+ read_request_and_content(socket);
+ else if(on_error)
+ on_error(std::shared_ptr<Request>(new Request(*socket)), ec);
+ });
+ }
+ else if(on_error)
+ on_error(std::shared_ptr<Request>(new Request(*socket)), ec);
+ });
+ }
+ };
+
+ class https_server : public Server<HTTPS> {
+ public:
+ explicit https_server(const std::string& cert_file, const std::string& private_key_file, const std::string& verify_file = std::string()) : Server<HTTPS>::Server(cert_file, private_key_file, verify_file) {}
+ };
+
+}
+
+
+#endif /* SERVER_HTTPS_HPP */
+
diff --git a/src/lib/util/server_ws.hpp b/src/lib/util/server_ws.hpp
new file mode 100644
index 00000000000..170dc31ae63
--- /dev/null
+++ b/src/lib/util/server_ws.hpp
@@ -0,0 +1,714 @@
+// license:MIT
+// copyright-holders:Ole Christian Eidheim, Miodrag Milanovic
+#ifndef SERVER_WS_HPP
+#define SERVER_WS_HPP
+#include "path_to_regex.hpp"
+#include "crypto.hpp"
+
+#include "asio.h"
+#include "asio/system_timer.hpp"
+
+#include <unordered_map>
+#include <thread>
+#include <mutex>
+#include <unordered_set>
+#include <list>
+#include <memory>
+#include <atomic>
+#include <iostream>
+#include <map>
+#include <chrono>
+#include <regex>
+
+#ifndef CASE_INSENSITIVE_EQUALS_AND_HASH
+#define CASE_INSENSITIVE_EQUALS_AND_HASH
+class case_insensitive_equals {
+public:
+ bool operator()(const std::string &key1, const std::string &key2) const {
+ return key1.size() == key2.size()
+ && equal(key1.cbegin(), key1.cend(), key2.cbegin(),
+ [](std::string::value_type key1v, std::string::value_type key2v)
+ { return tolower(key1v) == tolower(key2v); });
+ }
+};
+class case_insensitive_hash {
+public:
+ size_t operator()(const std::string &key) const {
+ size_t seed = 0;
+ for (auto &c : key) {
+ std::hash<char> hasher;
+ seed ^= hasher(std::tolower(c)) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
+ }
+ return seed;
+ }
+};
+#endif
+
+namespace webpp {
+ template <class socket_type>
+ class SocketServer;
+
+ template <class socket_type>
+ class SocketServerBase {
+ public:
+ virtual ~SocketServerBase() {}
+
+ class SendStream : public std::ostream {
+ friend class SocketServerBase<socket_type>;
+
+ asio::streambuf streambuf;
+ public:
+ SendStream(): std::ostream(&streambuf) {}
+ size_t size() const {
+ return streambuf.size();
+ }
+ };
+
+
+ class Connection {
+ friend class SocketServerBase<socket_type>;
+ friend class SocketServer<socket_type>;
+
+ public:
+ explicit Connection(const std::shared_ptr<socket_type> &socket) : remote_endpoint_port(0), socket(socket), strand(socket->get_io_service()), closed(false) { }
+
+ std::string method, path, http_version;
+
+ std::unordered_multimap<std::string, std::string, case_insensitive_hash, case_insensitive_equals> header;
+
+ std::smatch path_match;
+
+ std::string remote_endpoint_address;
+ unsigned short remote_endpoint_port;
+
+ private:
+ explicit Connection(socket_type *socket): remote_endpoint_port(0), socket(socket), strand(socket->get_io_service()), closed(false) { }
+
+ class SendData {
+ public:
+ SendData(const std::shared_ptr<SendStream> &header_stream, const std::shared_ptr<SendStream> &message_stream,
+ const std::function<void(const std::error_code)> &callback) :
+ header_stream(header_stream), message_stream(message_stream), callback(callback) {}
+ std::shared_ptr<SendStream> header_stream;
+ std::shared_ptr<SendStream> message_stream;
+ std::function<void(const std::error_code)> callback;
+ };
+
+ std::shared_ptr<socket_type> socket;
+
+ asio::io_context::strand strand;
+
+ std::list<SendData> send_queue;
+
+ void send_from_queue(const std::shared_ptr<Connection> &connection) {
+ strand.post([this, connection]() {
+ asio::async_write(*socket, send_queue.begin()->header_stream->streambuf,
+ strand.wrap([this, connection](const std::error_code& ec, size_t /*bytes_transferred*/) {
+ if(!ec) {
+ asio::async_write(*socket, send_queue.begin()->message_stream->streambuf,
+ strand.wrap([this, connection]
+ (const std::error_code& ec, size_t /*bytes_transferred*/) {
+ auto send_queued=send_queue.begin();
+ if(send_queued->callback)
+ send_queued->callback(ec);
+ if(!ec) {
+ send_queue.erase(send_queued);
+ if(send_queue.size()>0)
+ send_from_queue(connection);
+ }
+ else
+ send_queue.clear();
+ }));
+ }
+ else {
+ auto send_queued=send_queue.begin();
+ if(send_queued->callback)
+ send_queued->callback(ec);
+ send_queue.clear();
+ }
+ }));
+ });
+ }
+
+ std::atomic<bool> closed;
+
+ std::unique_ptr<asio::system_timer> timer_idle;
+
+ void read_remote_endpoint_data() {
+ try {
+ remote_endpoint_address=socket->lowest_layer().remote_endpoint().address().to_string();
+ remote_endpoint_port=socket->lowest_layer().remote_endpoint().port();
+ }
+ catch (...) {}
+ }
+ };
+
+ class Message : public std::istream {
+ friend class SocketServerBase<socket_type>;
+
+ public:
+ unsigned char fin_rsv_opcode;
+ size_t size() const {
+ return length;
+ }
+ std::string string() const {
+ std::stringstream ss;
+ ss << rdbuf();
+ return ss.str();
+ }
+ private:
+ Message(): std::istream(&streambuf), fin_rsv_opcode(0), length(0) {}
+
+ size_t length;
+ asio::streambuf streambuf;
+ };
+
+ class Endpoint {
+ friend class SocketServerBase<socket_type>;
+ std::unordered_set<std::shared_ptr<Connection> > connections;
+ std::mutex connections_mutex;
+
+ public:
+ std::function<void(std::shared_ptr<Connection>)> on_open;
+ std::function<void(std::shared_ptr<Connection>, std::shared_ptr<Message>)> on_message;
+ std::function<void(std::shared_ptr<Connection>, int, const std::string&)> on_close;
+ std::function<void(std::shared_ptr<Connection>, const std::error_code&)> on_error;
+
+ std::unordered_set<std::shared_ptr<Connection> > get_connections() {
+ std::lock_guard<std::mutex> lock(connections_mutex);
+ auto copy=connections;
+ return copy;
+ }
+ };
+
+ class Config {
+ friend class SocketServerBase<socket_type>;
+
+ Config(unsigned short port) : port(port) {}
+ public:
+ /// Port number to use. Defaults to 80 for HTTP and 443 for HTTPS.
+ unsigned short port;
+ /// Number of threads that the server will use when start() is called. Defaults to 1 thread.
+ size_t thread_pool_size=1;
+ /// Timeout on request handling. Defaults to 5 seconds.
+ size_t timeout_request=5;
+ /// Idle timeout. Defaults to no timeout.
+ size_t timeout_idle=0;
+ /// IPv4 address in dotted decimal form or IPv6 address in hexadecimal notation.
+ /// If empty, the address will be any address.
+ std::string address;
+ /// Set to false to avoid binding the socket to an address that is already in use. Defaults to true.
+ bool reuse_address=true;
+ };
+ ///Set before calling start().
+ Config config;
+
+ private:
+ class regex_orderable : public std::regex {
+ std::string str;
+ path2regex::Keys keys;
+ public:
+ regex_orderable(const char *regex_cstr) : std::regex(path2regex::path_to_regex(regex_cstr, keys)), str(regex_cstr) {}
+ regex_orderable(const std::string &regex_cstr) : std::regex(path2regex::path_to_regex(regex_cstr, keys)), str(regex_cstr) {}
+ bool operator<(const regex_orderable &rhs) const {
+ return str<rhs.str;
+ }
+ };
+ public:
+ /// Warning: do not add or remove endpoints after start() is called
+ std::map<regex_orderable, Endpoint> endpoint;
+
+ virtual void start() {
+ if(!io_context)
+ io_context=std::make_shared<asio::io_context>();
+
+ if(io_context->stopped())
+ io_context->reset();
+
+ asio::ip::tcp::endpoint endpoint;
+ if(config.address.size()>0)
+ endpoint=asio::ip::tcp::endpoint(asio::ip::address::from_string(config.address), config.port);
+ else
+ endpoint=asio::ip::tcp::endpoint(asio::ip::tcp::v4(), config.port);
+
+ if(!acceptor)
+ acceptor= std::make_unique<asio::ip::tcp::acceptor>(*io_context);
+ acceptor->open(endpoint.protocol());
+ acceptor->set_option(asio::socket_base::reuse_address(config.reuse_address));
+ acceptor->bind(endpoint);
+ acceptor->listen();
+
+ accept();
+
+ io_context->run();
+ }
+
+ void stop() {
+ acceptor->close();
+ io_context->stop();
+
+ for(auto& p: endpoint)
+ p.second.connections.clear();
+ }
+
+ ///fin_rsv_opcode: 129=one fragment, text, 130=one fragment, binary, 136=close connection.
+ ///See http://tools.ietf.org/html/rfc6455#section-5.2 for more information
+ void send(const std::shared_ptr<Connection> &connection, const std::shared_ptr<SendStream> &message_stream,
+ const std::function<void(const std::error_code&)>& callback=nullptr,
+ unsigned char fin_rsv_opcode=129) const {
+ if(fin_rsv_opcode!=136)
+ timer_idle_reset(connection);
+
+ auto header_stream = std::make_shared<SendStream>();
+
+ size_t length=message_stream->size();
+
+ header_stream->put(fin_rsv_opcode);
+ //unmasked (first length byte<128)
+ if(length>=126) {
+ int num_bytes;
+ if(length>0xffff) {
+ num_bytes=8;
+ header_stream->put(127);
+ }
+ else {
+ num_bytes=2;
+ header_stream->put(126);
+ }
+
+ for(int c=num_bytes-1;c>=0;c--) {
+ header_stream->put((static_cast<unsigned long long>(length) >> (8 * c)) % 256);
+ }
+ }
+ else
+ header_stream->put(static_cast<unsigned char>(length));
+
+ connection->strand.post([this, connection, header_stream, message_stream, callback]() {
+ connection->send_queue.emplace_back(header_stream, message_stream, callback);
+ if(connection->send_queue.size()==1)
+ connection->send_from_queue(connection);
+ });
+ }
+
+ void send_close(const std::shared_ptr<Connection> &connection, int status, const std::string& reason="",
+ const std::function<void(const std::error_code&)>& callback=nullptr) const {
+ //Send close only once (in case close is initiated by server)
+ if(connection->closed)
+ return;
+ connection->closed=true;
+
+ auto send_stream=std::make_shared<SendStream>();
+
+ send_stream->put(status>>8);
+ send_stream->put(status%256);
+
+ *send_stream << reason;
+
+ //fin_rsv_opcode=136: message close
+ send(connection, send_stream, callback, 136);
+ }
+
+ std::unordered_set<std::shared_ptr<Connection> > get_connections() {
+ std::unordered_set<std::shared_ptr<Connection> > all_connections;
+ for(auto& e: endpoint) {
+ std::lock_guard<std::mutex> lock(e.second.connections_mutex);
+ all_connections.insert(e.second.connections.begin(), e.second.connections.end());
+ }
+ return all_connections;
+ }
+
+ /**
+ * Upgrades a request, from for instance Simple-Web-Server, to a WebSocket connection.
+ * The parameters are moved to the Connection object.
+ * See also Server::on_upgrade in the Simple-Web-Server project.
+ * The socket's io_service is used, thus running start() is not needed.
+ *
+ * Example use:
+ * server.on_upgrade=[&socket_server] (auto socket, auto request) {
+ * auto connection=std::make_shared<SimpleWeb::SocketServer<SimpleWeb::WS>::Connection>(socket);
+ * connection->method=std::move(request->method);
+ * connection->path=std::move(request->path);
+ * connection->http_version=std::move(request->http_version);
+ * connection->header=std::move(request->header);
+ * connection->remote_endpoint_address=std::move(request->remote_endpoint_address);
+ * connection->remote_endpoint_port=request->remote_endpoint_port;
+ * socket_server.upgrade(connection);
+ * }
+ */
+ void upgrade(const std::shared_ptr<Connection> &connection) {
+ auto read_buffer=std::make_shared<asio::streambuf>();
+ write_handshake(connection, read_buffer);
+ }
+
+ /// If you have your own asio::io_context, store its pointer here before running start().
+ /// You might also want to set config.num_threads to 0.
+ std::shared_ptr<asio::io_context> io_context;
+ protected:
+ const std::string ws_magic_string="258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
+
+ std::unique_ptr<asio::ip::tcp::acceptor> acceptor;
+
+ std::vector<std::thread> threads;
+
+ SocketServerBase(unsigned short port) :
+ config(port) {}
+
+ virtual void accept()=0;
+
+ std::shared_ptr<asio::system_timer> get_timeout_timer(const std::shared_ptr<Connection> &connection, size_t seconds) {
+ if (seconds == 0)
+ return nullptr;
+ auto timer = std::make_shared<asio::system_timer>(connection->socket->get_io_service());
+ timer->expires_at(std::chrono::system_clock::now() + std::chrono::seconds(static_cast<long>(seconds)));
+ timer->async_wait([connection](const std::error_code& ec){
+ if(!ec) {
+ connection->socket->lowest_layer().shutdown(asio::ip::tcp::socket::shutdown_both);
+ connection->socket->lowest_layer().close();
+ }
+ });
+ return timer;
+ }
+
+ void read_handshake(const std::shared_ptr<Connection> &connection) {
+ connection->read_remote_endpoint_data();
+
+ //Create new read_buffer for async_read_until()
+ //Shared_ptr is used to pass temporary objects to the asynchronous functions
+ auto read_buffer = std::make_shared<asio::streambuf>();
+
+ //Set timeout on the following asio::async-read or write function
+ auto timer = get_timeout_timer(connection, config.timeout_request);
+
+ asio::async_read_until(*connection->socket, *read_buffer, "\r\n\r\n",
+ [this, connection, read_buffer, timer]
+ (const std::error_code& ec, size_t /*bytes_transferred*/) {
+ if(timer)
+ timer->cancel();
+ if(!ec) {
+ //Convert to istream to extract string-lines
+ std::istream stream(read_buffer.get());
+
+ parse_handshake(connection, stream);
+
+ write_handshake(connection, read_buffer);
+ }
+ });
+ }
+
+ void parse_handshake(const std::shared_ptr<Connection> &connection, std::istream& stream) const {
+ std::string line;
+ getline(stream, line);
+ size_t method_end;
+ if((method_end=line.find(' '))!=std::string::npos) {
+ size_t path_end;
+ if((path_end=line.find(' ', method_end+1))!=std::string::npos) {
+ connection->method=line.substr(0, method_end);
+ connection->path=line.substr(method_end+1, path_end-method_end-1);
+ if((path_end+6)<line.size())
+ connection->http_version=line.substr(path_end+6, line.size()-(path_end+6)-1);
+ else
+ connection->http_version="1.1";
+
+ getline(stream, line);
+ size_t param_end;
+ while((param_end=line.find(':'))!=std::string::npos) {
+ size_t value_start=param_end+1;
+ if((value_start)<line.size()) {
+ if(line[value_start]==' ')
+ value_start++;
+ if(value_start<line.size())
+ connection->header.emplace(line.substr(0, param_end), line.substr(value_start, line.size()-value_start-1));
+ }
+
+ getline(stream, line);
+ }
+ }
+ }
+ }
+
+ void write_handshake(const std::shared_ptr<Connection> &connection, const std::shared_ptr<asio::streambuf> &read_buffer) {
+ //Find path- and method-match, and generate response
+ for (auto &regex_endpoint : endpoint) {
+ std::smatch path_match;
+ if(std::regex_match(connection->path, path_match, regex_endpoint.first)) {
+ auto write_buffer = std::make_shared<asio::streambuf>();
+ std::ostream handshake(write_buffer.get());
+
+ if(generate_handshake(connection, handshake)) {
+ connection->path_match=std::move(path_match);
+ //Capture write_buffer in lambda so it is not destroyed before async_write is finished
+ asio::async_write(*connection->socket, *write_buffer,
+ [this, connection, write_buffer, read_buffer, &regex_endpoint]
+ (const std::error_code& ec, size_t /*bytes_transferred*/) {
+ if(!ec) {
+ connection_open(connection, regex_endpoint.second);
+ read_message(connection, read_buffer, regex_endpoint.second);
+ }
+ else
+ connection_error(connection, regex_endpoint.second, ec);
+ });
+ }
+ return;
+ }
+ }
+ }
+
+ bool generate_handshake(const std::shared_ptr<Connection> &connection, std::ostream& handshake) const {
+ auto header_it = connection->header.find("Sec-WebSocket-Key");
+ if (header_it == connection->header.end())
+ return false;
+
+ auto sha1=sha1_encode(header_it->second + ws_magic_string);
+
+ handshake << "HTTP/1.1 101 Web Socket Protocol Handshake\r\n";
+ handshake << "Upgrade: websocket\r\n";
+ handshake << "Connection: Upgrade\r\n";
+ handshake << "Sec-WebSocket-Accept: " << base64_encode(sha1) << "\r\n";
+ handshake << "\r\n";
+
+ return true;
+ }
+
+ void read_message(const std::shared_ptr<Connection> &connection,
+ const std::shared_ptr<asio::streambuf> &read_buffer, Endpoint& endpoint) const {
+ asio::async_read(*connection->socket, *read_buffer, asio::transfer_exactly(2),
+ [this, connection, read_buffer, &endpoint]
+ (const std::error_code& ec, size_t bytes_transferred) {
+ if(!ec) {
+ if(bytes_transferred==0) { //TODO: why does this happen sometimes?
+ read_message(connection, read_buffer, endpoint);
+ return;
+ }
+ std::istream stream(read_buffer.get());
+
+ std::vector<unsigned char> first_bytes;
+ first_bytes.resize(2);
+ stream.read(reinterpret_cast<char*>(&first_bytes[0]), 2);
+
+ unsigned char fin_rsv_opcode=first_bytes[0];
+
+ //Close connection if unmasked message from client (protocol error)
+ if(first_bytes[1]<128) {
+ const std::string reason("message from client not masked");
+ send_close(connection, 1002, reason, [this, connection](const std::error_code& /*ec*/) {});
+ connection_close(connection, endpoint, 1002, reason);
+ return;
+ }
+
+ size_t length=(first_bytes[1]&127);
+
+ if(length==126) {
+ //2 next bytes is the size of content
+ asio::async_read(*connection->socket, *read_buffer, asio::transfer_exactly(2),
+ [this, connection, read_buffer, &endpoint, fin_rsv_opcode]
+ (const std::error_code& ec, size_t /*bytes_transferred*/) {
+ if(!ec) {
+ std::istream stream(read_buffer.get());
+
+ std::vector<unsigned char> length_bytes;
+ length_bytes.resize(2);
+ stream.read(reinterpret_cast<char*>(&length_bytes[0]), 2);
+
+ size_t length=0;
+ int num_bytes=2;
+ for(int c=0;c<num_bytes;c++)
+ length+=length_bytes[c]<<(8*(num_bytes-1-c));
+
+ read_message_content(connection, read_buffer, length, endpoint, fin_rsv_opcode);
+ }
+ else
+ connection_error(connection, endpoint, ec);
+ });
+ }
+ else if(length==127) {
+ //8 next bytes is the size of content
+ asio::async_read(*connection->socket, *read_buffer, asio::transfer_exactly(8),
+ [this, connection, read_buffer, &endpoint, fin_rsv_opcode]
+ (const std::error_code& ec, size_t /*bytes_transferred*/) {
+ if(!ec) {
+ std::istream stream(read_buffer.get());
+
+ std::vector<unsigned char> length_bytes;
+ length_bytes.resize(8);
+ stream.read(reinterpret_cast<char*>(&length_bytes[0]), 8);
+
+ size_t length=0;
+ int num_bytes=8;
+ for(int c=0;c<num_bytes;c++)
+ length+=length_bytes[c]<<(8*(num_bytes-1-c));
+
+ read_message_content(connection, read_buffer, length, endpoint, fin_rsv_opcode);
+ }
+ else
+ connection_error(connection, endpoint, ec);
+ });
+ }
+ else
+ read_message_content(connection, read_buffer, length, endpoint, fin_rsv_opcode);
+ }
+ else
+ connection_error(connection, endpoint, ec);
+ });
+ }
+
+ void read_message_content(const std::shared_ptr<Connection> &connection, const std::shared_ptr<asio::streambuf> &read_buffer,
+ size_t length, Endpoint& endpoint, unsigned char fin_rsv_opcode) const {
+ asio::async_read(*connection->socket, *read_buffer, asio::transfer_exactly(4+length),
+ [this, connection, read_buffer, length, &endpoint, fin_rsv_opcode]
+ (const std::error_code& ec, size_t /*bytes_transferred*/) {
+ if(!ec) {
+ std::istream raw_message_data(read_buffer.get());
+
+ //Read mask
+ std::vector<unsigned char> mask;
+ mask.resize(4);
+ raw_message_data.read(reinterpret_cast<char*>(&mask[0]), 4);
+
+ std::shared_ptr<Message> message(new Message());
+ message->length=length;
+ message->fin_rsv_opcode=fin_rsv_opcode;
+
+ std::ostream message_data_out_stream(&message->streambuf);
+ for(size_t c=0;c<length;c++) {
+ message_data_out_stream.put(raw_message_data.get()^mask[c%4]);
+ }
+
+ //If connection close
+ if((fin_rsv_opcode&0x0f)==8) {
+ int status=0;
+ if(length>=2) {
+ unsigned char byte1=message->get();
+ unsigned char byte2=message->get();
+ status=(byte1<<8)+byte2;
+ }
+
+ auto reason=message->string();
+ send_close(connection, status, reason, [this, connection](const std::error_code& /*ec*/) {});
+ connection_close(connection, endpoint, status, reason);
+ return;
+ }
+ else {
+ //If ping
+ if((fin_rsv_opcode&0x0f)==9) {
+ //send pong
+ auto empty_send_stream=std::make_shared<SendStream>();
+ send(connection, empty_send_stream, nullptr, fin_rsv_opcode+1);
+ }
+ else if(endpoint.on_message) {
+ timer_idle_reset(connection);
+ endpoint.on_message(connection, message);
+ }
+
+ //Next message
+ read_message(connection, read_buffer, endpoint);
+ }
+ }
+ else
+ connection_error(connection, endpoint, ec);
+ });
+ }
+
+ void connection_open(const std::shared_ptr<Connection> &connection, Endpoint& endpoint) {
+ timer_idle_init(connection);
+
+ {
+ std::lock_guard<std::mutex> lock(endpoint.connections_mutex);
+ endpoint.connections.insert(connection);
+ }
+
+ if(endpoint.on_open)
+ endpoint.on_open(connection);
+ }
+
+ void connection_close(const std::shared_ptr<Connection> &connection, Endpoint& endpoint, int status, const std::string& reason) const {
+ timer_idle_cancel(connection);
+
+ {
+ std::lock_guard<std::mutex> lock(endpoint.connections_mutex);
+ endpoint.connections.erase(connection);
+ }
+
+ if(endpoint.on_close)
+ endpoint.on_close(connection, status, reason);
+ }
+
+ void connection_error(const std::shared_ptr<Connection> &connection, Endpoint& endpoint, const std::error_code& ec) const {
+ timer_idle_cancel(connection);
+
+ {
+ std::lock_guard<std::mutex> lock(endpoint.connections_mutex);
+ endpoint.connections.erase(connection);
+ }
+
+ if(endpoint.on_error) {
+ std::error_code ec_tmp=ec;
+ endpoint.on_error(connection, ec_tmp);
+ }
+ }
+
+ void timer_idle_init(const std::shared_ptr<Connection> &connection) {
+ if(config.timeout_idle>0) {
+ connection->timer_idle= std::make_unique<asio::system_timer>(connection->socket->get_io_service());
+ connection->timer_idle->expires_from_now(std::chrono::seconds(static_cast<unsigned long>(config.timeout_idle)));
+ timer_idle_expired_function(connection);
+ }
+ }
+ void timer_idle_reset(const std::shared_ptr<Connection> &connection) const {
+ if(config.timeout_idle>0 && connection->timer_idle->expires_from_now(std::chrono::seconds(static_cast<unsigned long>(config.timeout_idle)))>0)
+ timer_idle_expired_function(connection);
+ }
+ void timer_idle_cancel(const std::shared_ptr<Connection> &connection) const {
+ if(config.timeout_idle>0)
+ connection->timer_idle->cancel();
+ }
+
+ void timer_idle_expired_function(const std::shared_ptr<Connection> &connection) const {
+ connection->timer_idle->async_wait([this, connection](const std::error_code& ec){
+ if(!ec)
+ send_close(connection, 1000, "idle timeout"); //1000=normal closure
+ });
+ }
+ };
+
+ template<class socket_type>
+ class SocketServer : public SocketServerBase<socket_type> {
+ public:
+ SocketServer(unsigned short port, size_t timeout_request, size_t timeout_idle)
+ : SocketServerBase<socket_type>(port, timeout_request, timeout_idle)
+ {
+ }
+ };
+
+ using WS = asio::ip::tcp::socket;
+
+ template<>
+ class SocketServer<WS> : public SocketServerBase<WS> {
+ public:
+ SocketServer() : SocketServerBase<WS>(80) {}
+ protected:
+ void accept() override {
+ //Create new socket for this connection (stored in Connection::socket)
+ //Shared_ptr is used to pass temporary objects to the asynchronous functions
+ std::shared_ptr<Connection> connection(new Connection(new WS(*io_context)));
+
+ acceptor->async_accept(*connection->socket, [this, connection](const std::error_code& ec) {
+ //Immediately start accepting a new connection (if io_context hasn't been stopped)
+ if (ec != asio::error::operation_aborted)
+ accept();
+
+ if(!ec) {
+ asio::ip::tcp::no_delay option(true);
+ connection->socket->set_option(option);
+
+ read_handshake(connection);
+ }
+ });
+ }
+ };
+
+ class ws_server : public SocketServer<WS> {
+ public:
+ ws_server() : SocketServer<WS>::SocketServer() {}
+ };
+}
+#endif /* SERVER_WS_HPP */
diff --git a/src/lib/util/server_wss.hpp b/src/lib/util/server_wss.hpp
new file mode 100644
index 00000000000..ecf46fb1524
--- /dev/null
+++ b/src/lib/util/server_wss.hpp
@@ -0,0 +1,82 @@
+// license:MIT
+// copyright-holders:Ole Christian Eidheim, Miodrag Milanovic
+#ifndef SERVER_WSS_HPP
+#define SERVER_WSS_HPP
+
+#include "server_ws.hpp"
+#include "asio/ssl.hpp"
+#include <openssl/ssl.h>
+#include <algorithm>
+
+namespace webpp {
+ using WSS = asio::ssl::stream<asio::ip::tcp::socket>;
+
+ template<>
+ class SocketServer<WSS> : public SocketServerBase<WSS> {
+ std::string session_id_context;
+ bool set_session_id_context = false;
+ public:
+ SocketServer(const std::string& cert_file, const std::string& private_key_file,
+ const std::string& verify_file=std::string()) : SocketServerBase<WSS>(443), context(asio::ssl::context::tlsv12) {
+
+ context.use_certificate_chain_file(cert_file);
+ context.use_private_key_file(private_key_file, asio::ssl::context::pem);
+
+ if (verify_file.size() > 0) {
+ context.load_verify_file(verify_file);
+ context.set_verify_mode(asio::ssl::verify_peer | asio::ssl::verify_fail_if_no_peer_cert |
+ asio::ssl::verify_client_once);
+ set_session_id_context=true;
+ }
+ }
+
+ void start() override {
+ if(set_session_id_context) {
+ // Creating session_id_context from address:port but reversed due to small SSL_MAX_SSL_SESSION_ID_LENGTH
+ session_id_context=std::to_string(config.port)+':';
+ session_id_context.append(config.address.rbegin(), config.address.rend());
+ SSL_CTX_set_session_id_context(context.native_handle(), reinterpret_cast<const unsigned char*>(session_id_context.data()),
+ std::min<size_t>(session_id_context.size(), SSL_MAX_SSL_SESSION_ID_LENGTH));
+ }
+ SocketServerBase::start();
+ }
+ protected:
+ asio::ssl::context context;
+
+ void accept() override {
+ //Create new socket for this connection (stored in Connection::socket)
+ //Shared_ptr is used to pass temporary objects to the asynchronous functions
+ std::shared_ptr<Connection> connection(new Connection(new WSS(*io_context, context)));
+
+ acceptor->async_accept(connection->socket->lowest_layer(), [this, connection](const std::error_code& ec) {
+ //Immediately start accepting a new connection (if io_context hasn't been stopped)
+ if (ec != asio::error::operation_aborted)
+ accept();
+
+ if(!ec) {
+ asio::ip::tcp::no_delay option(true);
+ connection->socket->lowest_layer().set_option(option);
+
+ //Set timeout on the following asio::ssl::stream::async_handshake
+ auto timer = get_timeout_timer(connection, config.timeout_request);
+ connection->socket->async_handshake(asio::ssl::stream_base::server,
+ [this, connection, timer](const std::error_code& ec) {
+ if(timer)
+ timer->cancel();
+ if(!ec)
+ read_handshake(connection);
+ });
+ }
+ });
+ }
+ };
+
+ class wss_server : public SocketServer<WSS> {
+ public:
+ wss_server(const std::string& cert_file, const std::string& private_key_file,const std::string& verify_file = std::string()) : SocketServer<WSS>::SocketServer(cert_file, private_key_file, verify_file) {}
+ };
+}
+
+
+#endif /* SERVER_WSS_HPP */
+
diff --git a/src/lib/util/sha1.hpp b/src/lib/util/sha1.hpp
new file mode 100644
index 00000000000..7befbd326f0
--- /dev/null
+++ b/src/lib/util/sha1.hpp
@@ -0,0 +1,181 @@
+// license:BSD-3-Clause
+// copyright-holders:Micael Hildenborg
+/*
+ Copyright (c) 2011, Micael Hildenborg
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of Micael Hildenborg nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY Micael Hildenborg ''AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL Micael Hildenborg BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SHA1_DEFINED
+#define SHA1_DEFINED
+
+namespace sha1 {
+
+namespace { // local
+
+// Rotate an integer value to left.
+inline unsigned int rol(unsigned int value, unsigned int steps) {
+ return ((value << steps) | (value >> (32 - steps)));
+}
+
+// Sets the first 16 integers in the buffert to zero.
+// Used for clearing the W buffert.
+inline void clearWBuffert(unsigned int * buffert)
+{
+ for (int pos = 16; --pos >= 0;)
+ {
+ buffert[pos] = 0;
+ }
+}
+
+inline void innerHash(unsigned int * result, unsigned int * w)
+{
+ unsigned int a = result[0];
+ unsigned int b = result[1];
+ unsigned int c = result[2];
+ unsigned int d = result[3];
+ unsigned int e = result[4];
+
+ int round = 0;
+
+ #define sha1macro(func,val) \
+ { \
+ const unsigned int t = rol(a, 5) + (func) + e + val + w[round]; \
+ e = d; \
+ d = c; \
+ c = rol(b, 30); \
+ b = a; \
+ a = t; \
+ }
+
+ while (round < 16)
+ {
+ sha1macro((b & c) | (~b & d), 0x5a827999)
+ ++round;
+ }
+ while (round < 20)
+ {
+ w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
+ sha1macro((b & c) | (~b & d), 0x5a827999)
+ ++round;
+ }
+ while (round < 40)
+ {
+ w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
+ sha1macro(b ^ c ^ d, 0x6ed9eba1)
+ ++round;
+ }
+ while (round < 60)
+ {
+ w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
+ sha1macro((b & c) | (b & d) | (c & d), 0x8f1bbcdc)
+ ++round;
+ }
+ while (round < 80)
+ {
+ w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
+ sha1macro(b ^ c ^ d, 0xca62c1d6)
+ ++round;
+ }
+
+ #undef sha1macro
+
+ result[0] += a;
+ result[1] += b;
+ result[2] += c;
+ result[3] += d;
+ result[4] += e;
+}
+
+} // namespace
+
+/// Calculate a SHA1 hash
+/**
+ * @param src points to any kind of data to be hashed.
+ * @param bytelength the number of bytes to hash from the src pointer.
+ * @param hash should point to a buffer of at least 20 bytes of size for storing
+ * the sha1 result in.
+ */
+inline void calc(void const * src, size_t bytelength, unsigned char * hash) {
+ // Init the result array.
+ unsigned int result[5] = { 0x67452301, 0xefcdab89, 0x98badcfe,
+ 0x10325476, 0xc3d2e1f0 };
+
+ // Cast the void src pointer to be the byte array we can work with.
+ unsigned char const * sarray = static_cast<unsigned char const *>(src);
+
+ // The reusable round buffer
+ unsigned int w[80];
+
+ // Loop through all complete 64byte blocks.
+
+ size_t endCurrentBlock;
+ size_t currentBlock = 0;
+
+ if (bytelength >= 64) {
+ size_t const endOfFullBlocks = bytelength - 64;
+
+ while (currentBlock <= endOfFullBlocks) {
+ endCurrentBlock = currentBlock + 64;
+
+ // Init the round buffer with the 64 byte block data.
+ for (int roundPos = 0; currentBlock < endCurrentBlock; currentBlock += 4)
+ {
+ // This line will swap endian on big endian and keep endian on
+ // little endian.
+ w[roundPos++] = static_cast<unsigned int>(sarray[currentBlock + 3])
+ | (static_cast<unsigned int>(sarray[currentBlock + 2]) << 8)
+ | (static_cast<unsigned int>(sarray[currentBlock + 1]) << 16)
+ | (static_cast<unsigned int>(sarray[currentBlock]) << 24);
+ }
+ innerHash(result, w);
+ }
+ }
+
+ // Handle the last and not full 64 byte block if existing.
+ endCurrentBlock = bytelength - currentBlock;
+ clearWBuffert(w);
+ size_t lastBlockBytes = 0;
+ for (;lastBlockBytes < endCurrentBlock; ++lastBlockBytes) {
+ w[lastBlockBytes >> 2] |= static_cast<unsigned int>(sarray[lastBlockBytes + currentBlock]) << ((3 - (lastBlockBytes & 3)) << 3);
+ }
+
+ w[lastBlockBytes >> 2] |= 0x80 << ((3 - (lastBlockBytes & 3)) << 3);
+ if (endCurrentBlock >= 56) {
+ innerHash(result, w);
+ clearWBuffert(w);
+ }
+ w[15] = bytelength << 3;
+ innerHash(result, w);
+
+ // Store hash in result pointer, and make sure we get in in the correct
+ // order on both endian models.
+ for (int hashByte = 20; --hashByte >= 0;) {
+ hash[hashByte] = (result[hashByte >> 2] >> (((3 - hashByte) & 0x3) << 3)) & 0xff;
+ }
+}
+
+} // namespace sha1
+
+#endif // SHA1_DEFINED
diff --git a/src/lib/util/unicode.cpp b/src/lib/util/unicode.cpp
index a6c5515fbf6..5849abb8d73 100644
--- a/src/lib/util/unicode.cpp
+++ b/src/lib/util/unicode.cpp
@@ -2,7 +2,7 @@
// copyright-holders:Aaron Giles
/*********************************************************************
- unicode.c
+ unicode.cpp
Unicode related functions
@@ -10,6 +10,16 @@
#include "unicode.h"
+#ifdef _WIN32
+#include "strconv.h"
+#define UTF8PROC_DLLEXPORT
+#endif
+
+#include "utf8proc/utf8proc.h"
+
+#include <codecvt>
+#include <locale>
+
//-------------------------------------------------
// uchar_isvalid - return true if a given
@@ -346,6 +356,119 @@ int utf16f_from_uchar(char16_t *utf16string, size_t count, char32_t uchar)
//-------------------------------------------------
+// wstring_from_utf8
+//-------------------------------------------------
+
+std::wstring wstring_from_utf8(const std::string &utf8string)
+{
+#ifdef WIN32
+ // for some reason, using codecvt yields bad results on MinGW (but not MSVC)
+ return osd::text::to_wstring(utf8string);
+#else
+ std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
+ return converter.from_bytes(utf8string);
+#endif
+}
+
+
+//-------------------------------------------------
+// utf8_from_wstring
+//-------------------------------------------------
+
+std::string utf8_from_wstring(const std::wstring &string)
+{
+#ifdef WIN32
+ // for some reason, using codecvt yields bad results on MinGW (but not MSVC)
+ return osd::text::from_wstring(string);
+#else
+ std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
+ return converter.to_bytes(string);
+#endif
+}
+
+
+//-------------------------------------------------
+// internal_normalize_unicode - uses utf8proc to
+// normalize unicode
+//-------------------------------------------------
+
+static std::string internal_normalize_unicode(const char *s, size_t length, unicode_normalization_form normalization_form, bool null_terminated)
+{
+ // convert the normalization form
+ int options;
+ switch (normalization_form)
+ {
+ case unicode_normalization_form::C:
+ options = UTF8PROC_STABLE | UTF8PROC_COMPOSE;
+ break;
+ case unicode_normalization_form::D:
+ options = UTF8PROC_STABLE | UTF8PROC_DECOMPOSE;
+ break;
+ case unicode_normalization_form::KC:
+ options = UTF8PROC_STABLE | UTF8PROC_COMPOSE | UTF8PROC_COMPAT;
+ break;
+ case unicode_normalization_form::KD:
+ options = UTF8PROC_STABLE | UTF8PROC_DECOMPOSE | UTF8PROC_COMPAT;
+ break;
+ default:
+ throw false;
+ }
+
+ // was this null terminated?
+ if (null_terminated)
+ options |= UTF8PROC_NULLTERM;
+
+ // invoke utf8proc
+ utf8proc_uint8_t *utf8proc_result;
+ utf8proc_ssize_t utf8proc_result_length = utf8proc_map((utf8proc_uint8_t *) s, length, &utf8proc_result, (utf8proc_option_t)options);
+
+ // conver the result
+ std::string result;
+ if (utf8proc_result)
+ {
+ if (utf8proc_result_length > 0)
+ result = std::string((const char *)utf8proc_result, utf8proc_result_length);
+ free(utf8proc_result);
+ }
+
+ return result;
+}
+
+
+//-------------------------------------------------
+// normalize_unicode - uses utf8proc to normalize
+// unicode
+//-------------------------------------------------
+
+std::string normalize_unicode(const std::string &s, unicode_normalization_form normalization_form)
+{
+ return internal_normalize_unicode(s.c_str(), s.length(), normalization_form, false);
+}
+
+
+//-------------------------------------------------
+// normalize_unicode - uses utf8proc to normalize
+// unicode
+//-------------------------------------------------
+
+std::string normalize_unicode(const char *s, unicode_normalization_form normalization_form)
+{
+ return internal_normalize_unicode(s, 0, normalization_form, true);
+}
+
+
+//-------------------------------------------------
+// normalize_unicode - uses utf8proc to normalize
+// unicode
+//-------------------------------------------------
+
+std::string normalize_unicode(const char *s, size_t length, unicode_normalization_form normalization_form)
+{
+ return internal_normalize_unicode(s, length, normalization_form, false);
+}
+
+
+//-------------------------------------------------
// utf8_previous_char - return a pointer to the
// previous character in a string
//-------------------------------------------------
diff --git a/src/lib/util/unicode.h b/src/lib/util/unicode.h
index 5cc6db383ee..189aa877d29 100644
--- a/src/lib/util/unicode.h
+++ b/src/lib/util/unicode.h
@@ -72,6 +72,9 @@
#define UTF8_UP "\xe2\x86\x91" /* cursor up */
#define UTF8_DOWN "\xe2\x86\x93" /* cursor down */
+enum class unicode_normalization_form { C, D, KC, KD };
+
+
/***************************************************************************
FUNCTION PROTOTYPES
@@ -97,6 +100,15 @@ std::string utf8_from_uchar(char32_t uchar);
int utf16_from_uchar(char16_t *utf16string, size_t count, char32_t uchar);
int utf16f_from_uchar(char16_t *utf16string, size_t count, char32_t uchar);
+// converting UTF-8 strings to/from "wide" strings
+std::wstring wstring_from_utf8(const std::string &utf8string);
+std::string utf8_from_wstring(const std::wstring &string);
+
+// unicode normalization
+std::string normalize_unicode(const std::string &s, unicode_normalization_form normalization_form);
+std::string normalize_unicode(const char *s, unicode_normalization_form normalization_form);
+std::string normalize_unicode(const char *s, size_t length, unicode_normalization_form normalization_form);
+
// misc UTF-8 helpers
const char *utf8_previous_char(const char *utf8string);
bool utf8_is_valid_string(const char *utf8string);
diff --git a/src/mame/arcade.flt b/src/mame/arcade.flt
index 5fdab2a318f..d1a207b97e0 100644
--- a/src/mame/arcade.flt
+++ b/src/mame/arcade.flt
@@ -479,6 +479,7 @@ gyruss.cpp
halleys.cpp
hanaawas.cpp
hankin.cpp
+hapyfish.cpp
harddriv.cpp
hazelgr.cpp
hcastle.cpp
diff --git a/src/mame/audio/efo_zsu.cpp b/src/mame/audio/efo_zsu.cpp
new file mode 100644
index 00000000000..7fe7744e69b
--- /dev/null
+++ b/src/mame/audio/efo_zsu.cpp
@@ -0,0 +1,275 @@
+// license:BSD-3-Clause
+// copyright-holders:David Haywood,AJR
+
+/***************************************************************************
+
+ ZSU Sound Control Unit (Proyectado 21/4/86 J. Gamell)
+ ZSU1 Sound Control Unit (Proyectado 12/6/86 J. Gamell)
+ Cedar Magnet Sound Board
+
+ The ZSU board is a component of the Z-Pinball hardware developed by
+ E.F.O. (Electrónica Funcional Operativa) S.A. of Barcelona, Spain. Its
+ sound generators are 2 AY-3-8910As and 1 OKI MSM5205, and 2 MF10s and
+ 1 HC4066 are used to mix their outputs. The timing circuits are rather
+ intricate, using Z80-CTCs, HC74s and HC393s and various other gates to
+ drive both the 5205 and the SGS HCF40105BE through which its samples
+ are funneled.
+
+ There are no available schematics for the Cedar Magnet video game
+ system (also designed by E.F.O.), but its sound board is believed to be
+ a close analogue of ZSU, since it includes all of the aforementioned
+ devices. The main known difference is that the Cedar Magnet sound
+ code and data are externally loaded into 64K of RAM (2xTMM41464P-15),
+ whereas ZSU's memory map consists primarily of a bank of up to 5 27256
+ EPROMs switched from two output lines of the first 8910, overlaid with
+ a mere 2K of RAM.
+
+ irq vectors
+
+ 0xe6 - from ctc0 channel 3 (vector = E0) used to drive MSM5205 through FIFO
+ 0xee - from ctc0 channel 3 (vector = E8) ^^
+ 0xf6 - drive AY (once per frame?) triggered by ctc1 channel 3 (vector = F0)
+ 0xff - read sound latch (triggered by write from master board; default vector set by 5K/+5 pullups on D0-D7)
+
+***************************************************************************/
+
+#include "emu.h"
+#include "audio/efo_zsu.h"
+
+#include "machine/clock.h"
+#include "machine/input_merger.h"
+
+
+extern const device_type EFO_ZSU = &device_creator<efo_zsu_device>;
+extern const device_type EFO_ZSU1 = &device_creator<efo_zsu1_device>;
+extern const device_type CEDAR_MAGNET_SOUND = &device_creator<cedar_magnet_sound_device>;
+
+
+efo_zsu_device::efo_zsu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, u32 clock, const char *shortname, const char *source)
+ : device_t(mconfig, type, name, tag, owner, clock, shortname, source),
+ m_ctc0(*this, "ctc0"),
+ m_ctc1(*this, "ctc1"),
+ m_soundlatch(*this, "soundlatch"),
+ m_fifo(*this, "fifo"),
+ m_adpcm(*this, "adpcm")
+{
+}
+
+
+efo_zsu_device::efo_zsu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : efo_zsu_device(mconfig, EFO_ZSU, "ZSU Sound Control Unit", tag, owner, clock, "efo_zsu", __FILE__)
+{
+}
+
+
+efo_zsu1_device::efo_zsu1_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : efo_zsu_device(mconfig, EFO_ZSU1, "ZSU1 Sound Control Unit", tag, owner, clock, "efo_zsu1", __FILE__)
+{
+}
+
+
+cedar_magnet_sound_device::cedar_magnet_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : efo_zsu_device(mconfig, CEDAR_MAGNET_SOUND, "Cedar Sound", tag, owner, clock, "cedmag_sound", __FILE__),
+ cedar_magnet_board_interface(mconfig, *this, "soundcpu", "ram")
+{
+}
+
+
+WRITE8_MEMBER(efo_zsu_device::sound_command_w)
+{
+ m_soundlatch->write(space, 0, data);
+}
+
+
+
+static ADDRESS_MAP_START( zsu_map, AS_PROGRAM, 8, efo_zsu_device )
+ AM_RANGE(0x0000, 0x6fff) AM_ROM
+ AM_RANGE(0x7000, 0x77ff) AM_MIRROR(0x0800) AM_RAM
+ AM_RANGE(0x8000, 0xffff) AM_ROMBANK("rombank")
+ADDRESS_MAP_END
+
+static ADDRESS_MAP_START( cedar_magnet_sound_map, AS_PROGRAM, 8, cedar_magnet_sound_device )
+ AM_RANGE(0x0000, 0xffff) AM_RAM AM_SHARE("ram")
+ADDRESS_MAP_END
+
+static ADDRESS_MAP_START( zsu_io, AS_IO, 8, efo_zsu_device )
+ ADDRESS_MAP_GLOBAL_MASK(0xff)
+ ADDRESS_MAP_UNMAP_HIGH
+
+ AM_RANGE(0x00, 0x03) AM_DEVREADWRITE("ctc0", z80ctc_device, read, write)
+ AM_RANGE(0x04, 0x07) AM_DEVREADWRITE("ctc1", z80ctc_device, read, write)
+
+ AM_RANGE(0x08, 0x08) AM_WRITE(adpcm_fifo_w)
+
+ AM_RANGE(0x0c, 0x0c) AM_DEVWRITE("aysnd0", ay8910_device, address_w)
+ AM_RANGE(0x0d, 0x0d) AM_DEVWRITE("aysnd0", ay8910_device, data_w)
+
+ AM_RANGE(0x10, 0x10) AM_DEVWRITE("aysnd1", ay8910_device, address_w)
+ AM_RANGE(0x11, 0x11) AM_DEVWRITE("aysnd1", ay8910_device, data_w)
+
+ AM_RANGE(0x14, 0x14) AM_DEVREAD("soundlatch", generic_latch_8_device, read)
+
+ADDRESS_MAP_END
+
+WRITE8_MEMBER(efo_zsu_device::adpcm_fifo_w)
+{
+ // Z80 code first unpacks 8 bytes of ADPCM sample data into nibbles
+ // and, upon receiving interrupt vector E6, fills FIFO at once using OTIR
+ // 4-bit data is shifted out of the FIFO to the MSM5205 by another timer
+ m_fifo->write(data & 0x0f); // only low nibble is used here
+ m_fifo->si_w(1);
+ m_fifo->si_w(0);
+}
+
+WRITE8_MEMBER(cedar_magnet_sound_device::ay0_porta_w)
+{
+ // unknown (not in ZSU schematic); 0x80 written on reset
+}
+
+WRITE8_MEMBER(efo_zsu_device::ay1_porta_w)
+{
+ m_adpcm->reset_w(data & 1);
+ if (data & 1)
+ m_fifo->reset();
+ // D4-D6 likely used to select clock for ctc0 channel 2
+ // other bits probably used to modulate analog sound output
+}
+
+WRITE_LINE_MEMBER(efo_zsu_device::ctc0_z0_w)
+{
+// printf("USED ctc0_z0_w %d\n", state);
+}
+
+WRITE_LINE_MEMBER(efo_zsu_device::ctc0_z1_w)
+{
+// printf("USED ctc0_z1_w %d\n", state);
+}
+
+WRITE_LINE_MEMBER(efo_zsu_device::ctc1_z0_w)
+{
+ printf("ctc1_z0_w %d\n", state);
+}
+
+WRITE_LINE_MEMBER(efo_zsu_device::ctc1_z1_w)
+{
+ printf("ctc1_z1_w %d\n", state);
+}
+
+WRITE_LINE_MEMBER(efo_zsu_device::ctc1_z2_w)
+{
+ printf("ctc1_z2_w %d\n", state);
+}
+
+WRITE_LINE_MEMBER(efo_zsu_device::ctc0_z2_w)
+{
+ printf("ctc0_z2_w %d\n", state);
+}
+
+WRITE_LINE_MEMBER(efo_zsu_device::fifo_dor_w)
+{
+ // combined with a clock signal and used to drive ctc0 channel 3
+}
+
+static const z80_daisy_config daisy_chain[] =
+{
+ { "ctc1" },
+ { "ctc0" },
+ { nullptr }
+};
+
+TIMER_CALLBACK_MEMBER(cedar_magnet_sound_device::reset_assert_callback)
+{
+ cedar_magnet_board_interface::reset_assert_callback(ptr,param);
+ // reset lines go to the ctc as well?
+ m_ctc0->reset();
+ m_ctc1->reset();
+}
+
+
+
+static MACHINE_CONFIG_FRAGMENT( efo_zsu )
+ MCFG_CPU_ADD("soundcpu", Z80, 4000000)
+ MCFG_CPU_PROGRAM_MAP(zsu_map)
+ MCFG_CPU_IO_MAP(zsu_io)
+ MCFG_Z80_DAISY_CHAIN(daisy_chain)
+
+ MCFG_DEVICE_ADD("ctc0", Z80CTC, 4000000)
+ MCFG_Z80CTC_INTR_CB(DEVWRITELINE("soundirq", input_merger_device, in0_w))
+ MCFG_Z80CTC_ZC0_CB(WRITELINE(efo_zsu_device, ctc0_z0_w))
+ MCFG_Z80CTC_ZC1_CB(WRITELINE(efo_zsu_device, ctc0_z1_w))
+ MCFG_Z80CTC_ZC2_CB(WRITELINE(efo_zsu_device, ctc0_z2_w))
+
+ MCFG_DEVICE_ADD("ctc1", Z80CTC, 4000000)
+ MCFG_Z80CTC_INTR_CB(DEVWRITELINE("soundirq", input_merger_device, in0_w))
+ MCFG_Z80CTC_ZC0_CB(WRITELINE(efo_zsu_device, ctc1_z0_w))
+ MCFG_Z80CTC_ZC1_CB(WRITELINE(efo_zsu_device, ctc1_z1_w))
+ MCFG_Z80CTC_ZC2_CB(WRITELINE(efo_zsu_device, ctc1_z2_w))
+
+#if 0 // does nothing useful now
+ MCFG_DEVICE_ADD("ck1mhz", CLOCK, 4000000/4)
+ MCFG_CLOCK_SIGNAL_HANDLER(DEVWRITELINE("ctc1", z80ctc_device, trg0))
+ MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("ctc1", z80ctc_device, trg1))
+ MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("ctc1", z80ctc_device, trg2))
+#endif
+
+ MCFG_GENERIC_LATCH_8_ADD("soundlatch")
+ MCFG_GENERIC_LATCH_DATA_PENDING_CB(DEVWRITELINE("soundirq", input_merger_device, in1_w))
+
+ MCFG_INPUT_MERGER_ACTIVE_HIGH("soundirq") // 74HC03 NAND gate
+ MCFG_INPUT_MERGER_OUTPUT_HANDLER(INPUTLINE("soundcpu", INPUT_LINE_IRQ0))
+
+ MCFG_SPEAKER_STANDARD_MONO("mono")
+
+ MCFG_SOUND_ADD("aysnd0", AY8910, 4000000/2)
+ MCFG_AY8910_PORT_A_WRITE_CB(MEMBANK("rombank")) MCFG_DEVCB_MASK(0x03)
+ MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.5)
+
+ MCFG_SOUND_ADD("aysnd1", AY8910, 4000000/2)
+ MCFG_AY8910_PORT_A_WRITE_CB(WRITE8(efo_zsu_device, ay1_porta_w))
+ MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.5)
+
+ MCFG_DEVICE_ADD("fifo", HC40105, 0)
+ MCFG_40105_DATA_OUT_READY_CB(WRITELINE(efo_zsu_device, fifo_dor_w))
+ MCFG_40105_DATA_OUT_CB(DEVWRITELINE("adpcm", msm5205_device, data_w))
+
+ MCFG_SOUND_ADD("adpcm", MSM5205, 4000000/8)
+ MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50)
+MACHINE_CONFIG_END
+
+static MACHINE_CONFIG_FRAGMENT( cedar_magnet_sound )
+ MCFG_FRAGMENT_ADD(efo_zsu)
+
+ MCFG_CPU_MODIFY("soundcpu")
+ MCFG_CPU_PROGRAM_MAP(cedar_magnet_sound_map)
+
+ MCFG_SOUND_MODIFY("aysnd0")
+ MCFG_AY8910_PORT_A_WRITE_CB(WRITE8(cedar_magnet_sound_device, ay0_porta_w))
+MACHINE_CONFIG_END
+
+machine_config_constructor efo_zsu_device::device_mconfig_additions() const
+{
+ return MACHINE_CONFIG_NAME( efo_zsu );
+}
+
+machine_config_constructor cedar_magnet_sound_device::device_mconfig_additions() const
+{
+ return MACHINE_CONFIG_NAME( cedar_magnet_sound );
+}
+
+void efo_zsu_device::device_start()
+{
+ memory_bank *rombank = membank("rombank");
+ rombank->configure_entries(0, 4, &static_cast<u8 *>(memregion("soundcpu")->base())[0x8000], 0x8000);
+ rombank->set_entry(0); // 10K/GND pulldowns on banking lines
+}
+
+void efo_zsu1_device::device_start()
+{
+ memory_bank *rombank = membank("rombank");
+ rombank->configure_entries(0, 4, &static_cast<u8 *>(memregion("soundcpu")->base())[0x8000], 0x8000);
+ rombank->set_entry(3); // 10K/+5 pullups on banking lines
+}
+
+void cedar_magnet_sound_device::device_start()
+{
+}
diff --git a/src/mame/machine/cedar_magnet_sound.h b/src/mame/audio/efo_zsu.h
index 0d1a5d0226b..928f7800a8e 100644
--- a/src/mame/machine/cedar_magnet_sound.h
+++ b/src/mame/audio/efo_zsu.h
@@ -1,5 +1,5 @@
// license:BSD-3-Clause
-// copyright-holders:David Haywood
+// copyright-holders:David Haywood,AJR
#pragma once
@@ -9,36 +9,37 @@
#include "cpu/z80/z80.h"
#include "cpu/z80/z80daisy.h"
#include "machine/z80ctc.h"
+#include "machine/gen_latch.h"
#include "machine/40105.h"
#include "sound/ay8910.h"
#include "sound/msm5205.h"
#include "machine/cedar_magnet_board.h"
+extern const device_type EFO_ZSU;
+extern const device_type EFO_ZSU1;
extern const device_type CEDAR_MAGNET_SOUND;
#define MCFG_CEDAR_MAGNET_SOUND_ADD(_tag) \
MCFG_DEVICE_ADD(_tag, CEDAR_MAGNET_SOUND, 0)
-class cedar_magnet_sound_device : public cedar_magnet_board_device
+class efo_zsu_device : public device_t
{
public:
// construction/destruction
- cedar_magnet_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ efo_zsu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, u32 clock, const char *shortname, const char *source);
+ efo_zsu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
required_device<z80ctc_device> m_ctc0;
required_device<z80ctc_device> m_ctc1;
+ required_device<generic_latch_8_device> m_soundlatch;
required_device<cmos_40105_device> m_fifo;
required_device<msm5205_device> m_adpcm;
- DECLARE_READ8_MEMBER(soundlatch_r);
+ DECLARE_WRITE8_MEMBER(sound_command_w);
DECLARE_WRITE8_MEMBER(adpcm_fifo_w);
- DECLARE_WRITE8_MEMBER(ay0_porta_w);
DECLARE_WRITE8_MEMBER(ay1_porta_w);
- void write_command(uint8_t data);
- uint8_t m_command;
-
DECLARE_WRITE_LINE_MEMBER(ctc1_z0_w);
DECLARE_WRITE_LINE_MEMBER(ctc1_z1_w);
DECLARE_WRITE_LINE_MEMBER(ctc1_z2_w);
@@ -47,12 +48,38 @@ public:
DECLARE_WRITE_LINE_MEMBER(ctc0_z2_w);
DECLARE_WRITE_LINE_MEMBER(fifo_dor_w);
+protected:
+ virtual machine_config_constructor device_mconfig_additions() const override;
+ virtual void device_start() override;
+
+private:
+};
+
+
+class efo_zsu1_device : public efo_zsu_device
+{
+public:
+ // construction/destruction
+ efo_zsu1_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+protected:
+ virtual void device_start() override;
+};
+
+
+class cedar_magnet_sound_device : public efo_zsu_device, public cedar_magnet_board_interface
+{
+public:
+ // construction/destruction
+ cedar_magnet_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+ DECLARE_WRITE8_MEMBER(ay0_porta_w);
+
TIMER_CALLBACK_MEMBER(reset_assert_callback) override;
protected:
virtual machine_config_constructor device_mconfig_additions() const override;
virtual void device_start() override;
- virtual void device_reset() override;
private:
};
diff --git a/src/mame/audio/mario.cpp b/src/mame/audio/mario.cpp
index 7ef691acc68..c7fd9b96292 100644
--- a/src/mame/audio/mario.cpp
+++ b/src/mame/audio/mario.cpp
@@ -6,7 +6,7 @@
#include "sound/ay8910.h"
#include "includes/mario.h"
-
+#include "audio/nl_mario.h"
/****************************************************************
*
@@ -14,9 +14,6 @@
*
****************************************************************/
-/* FIXME: Capacitor aging - only in for calibration now */
-/* Adjustments are needed to bring this close to recordings */
-
#define RUN_VCO_VOLTAGE (0.0) /* 5 in schematics */
#define USE_8039 (0) /* set to 1 to try 8039 hack */
@@ -43,243 +40,6 @@
#if !OLD_SOUND
-/* ---------------------------------------------------------------------- */
-/* mario sound */
-/* ---------------------------------------------------------------------- */
-static NETLIST_START(nl_mario_snd0)
-
- RES(R17, RES_K(27)) /* 20 according to parts list */
- /* 27 verified, 30K in schematics */
- CAP(C14, CAP_U(4.7)) /* verified */
-
- TTL_74123(2H_A)
- NET_C(2H_A.VCC, V5)
- NET_C(2H_A.GND, GND)
- NET_C(SOUND0.Q, 2H_A.B)
- NET_C(GND, 2H_A.A)
- NET_C(2H_A.CLRQ, ttlhigh) /* NOT IN SCHEMATICS */
- DIODE(D1, "1N4148") /* FIXME: try to identify */
- TTL_7404_INVERT(1H_A, 2H_A.QQ)
- NET_C(R17.1, V5)
- NET_C(R17.2, D1.A, C14.1)
- NET_C(D1.K, 2H_A.RC)
- NET_C(C14.2, 2H_A.C)
-
- RES(R6, RES_K(4.7)) /* verified */
- CAP(C3, CAP_U(10)) /* verified */
-
- NET_C(1H_A.Q, R6.1)
- NET_C(R6.2, C3.1, 1J_A.FC)
- NET_C(R6.2, 2J_A.FC)
- NET_C(C3.2, GND)
-
- //#define MR_C6 CAP_N(3.9) /* verified */
-
- SN74LS629(1J_A, CAP_N(3.9))
- NET_C(1J_A.RNG, V5)
- NET_C(1J_A.ENQ, ttllow)
- NET_C(GND, 1J_A.GND)
-
- //#define MR_C17 CAP_N(22) /* verified */
-
- SN74LS629(2J_A, CAP_N(22))
- NET_C(2J_A.RNG, V5)
- NET_C(2J_A.ENQ, ttllow)
- NET_C(GND, 2J_A.GND)
-
- TTL_7486_XOR(1K_A, 1J_A.Y, 2J_A.Y)
- TTL_7408_AND(2K_A, 2H_A.Q, 1K_A)
-NETLIST_END()
-
-/* ---------------------------------------------------------------------- */
-/* skid sound */
-/* ---------------------------------------------------------------------- */
-
-// FIXME: Diodes are 1S953
-static NETLIST_START(nl_mario_snd7)
-
- RES(R61, RES_K(47))
- CAP(C41, CAP_U(4.7)) /* verified */
-
- TTL_74123(4L_A)
- NET_C(4L_A.VCC, V5)
- NET_C(4L_A.GND, GND)
- NET_C(SOUND7.Q, 4L_A.B)
- NET_C(GND, 4L_A.A)
- NET_C(4L_A.CLRQ, ttlhigh) /* NOT IN SCHEMATICS */
- DIODE(D10, "1N4148") /* FIXME: try to identify */
- TTL_7404_INVERT(4J_A, 4L_A.Q)
- NET_C(R61.1, V5)
- NET_C(R61.2, D10.A, C41.1)
- NET_C(D10.K, 4L_A.RC)
- NET_C(C41.2, 4L_A.C)
-
- RES(R65, RES_K(10))
- CAP(C44, CAP_U(3.3)) /* verified */
-
- SN74LS629(4K_A, CAP_U(0.022))
- NET_C(4K_A.RNG, V5)
- NET_C(4K_A.ENQ, ttllow)
- NET_C(GND, 4K_A.GND)
- NET_C(R65.1, 4J_A.Q)
- NET_C(R65.2, 4K_A.FC, C44.1)
- NET_C(C44.2, GND)
-
- CD4020_WI(3H, 4K_B.Y, ttllow, V5, GND)
- TTL_7404_INVERT(4J_B, 3H.Q12)
-
- RES(R64, RES_K(20))
- CAP(C43, CAP_U(3.3)) /* verified */
-
- SN74LS629(4K_B, CAP_U(0.0047))
- NET_C(4K_B.RNG, V5)
- NET_C(4K_B.ENQ, ttllow)
- NET_C(GND, 4K_B.GND)
- NET_C(R64.1, 4J_B.Q)
- NET_C(R64.2, 4K_B.FC, C43.1)
- NET_C(C43.2, GND)
-
- TTL_7486_XOR(1K_C, 3H.Q4, 4K_A.Y)
- TTL_7408_AND(2K_C, 4L_A.Q, 1K_C)
-
-NETLIST_END()
-
-/* ---------------------------------------------------------------------- */
-/* DAC sound */
-/* ---------------------------------------------------------------------- */
-static NETLIST_START(nl_mario_dac)
- RES(R34, RES_M(2))
- RES(R35, RES_M(1))
- RES(R36, RES_M(1.8))
- LM3900(3M_1)
- NET_C(3M_1.VM, GND)
- NET_C(3M_1.VP, V5)
-
- NET_C(DAC.VOUT, R34.1)
- NET_C(3M_1.MINUS, R34.2, R35.2)
- NET_C(3M_1.OUT, R35.1)
- NET_C(3M_1.PLUS, R36.1)
- NET_C(R36.2, GND)
-
- RES(R21, RES_M(1.8))
- RES(R23, RES_K(10))
- RES(R25, RES_K(10))
- RES(R37, RES_K(750))
- RES(R38, RES_K(360))
- RES(R39, RES_K(750))
-
- CAP(C18, CAP_P(100))
- CAP(C19, CAP_U(10))
- CAP(C20, CAP_U(1))
- CAP(C30, CAP_P(100))
-
- LM3900(3M_2)
- NET_C(3M_2.VM, GND)
- NET_C(3M_2.VP, V5)
-
- NET_C(R35.1, C20.1)
- NET_C(C20.2, R37.1)
- NET_C(R37.2, R38.2, C18.1, R39.2)
-
- NET_C(C18.2, GND)
- NET_C(R38.1, C30.2, 3M_2.MINUS)
- NET_C(3M_2.OUT, R39.1, C30.1)
-
- NET_C(R21.1, 3M_2.PLUS)
- NET_C(R21.2, C19.1, R25.2, R23.1)
- NET_C(C19.2, R23.2, GND)
- NET_C(R25.1, V5)
-NETLIST_END()
-
-static NETLIST_START(nl_mario)
-
- LOCAL_SOURCE(nl_mario_snd0)
- LOCAL_SOURCE(nl_mario_snd7)
- LOCAL_SOURCE(nl_mario_dac)
-
- SOLVER(Solver, 48000)
- PARAM(Solver.ACCURACY, 1e-6)
- PARAM(Solver.SOR_FACTOR, 1.0)
- PARAM(Solver.GS_THRESHOLD, 5)
- PARAM(Solver.GS_LOOPS, 1)
- //PARAM(Solver.LTE, 5e-2)
- PARAM(Solver.DYNAMIC_TS, 0)
- ANALOG_INPUT(V5, 5)
-
- TTL_INPUT(SOUND0, 1)
- INCLUDE(nl_mario_snd0)
-
- TTL_INPUT(SOUND7, 1)
- INCLUDE(nl_mario_snd7)
-
- R2R_DAC(DAC, 3.4, 10000.0, 8)
- NET_C(DAC.VGND, GND)
-
- INCLUDE(nl_mario_dac)
-
- /* ---------------------------------------------------------------------- */
- /* mixing */
- /* ---------------------------------------------------------------------- */
-
- RES(R20, RES_K(22)) /* verified */
- RES(R19, RES_K(22)) /* verified */
- RES(R40, RES_K(22)) /* verified */
- RES(R41, RES_K(100)) /* verified */
- CAP(C31, CAP_U(0.022)) /* */
-
- NET_C(2K_A.Q, R20.1)
- NET_C(GND, R19.1) //FIXME
- NET_C(2K_C.Q, R41.1)
-
- NET_C(R39.1, R40.1)
-
- NET_C(R20.2, R19.2, R40.2, R41.2, C31.1)
- NET_C(C31.2, GND)
-
- CAP(C32, CAP_U(1)) /* verified */
- RES(R42, RES_K(43)) /* verified */
- RES(R43, RES_K(100)) /* verified */
-
- NET_C(C31.1, C32.1)
- NET_C(C32.2, R42.1, R43.2, Q10.B)
- //NET_C(C32.2, R42.1, R43.2)
- NET_C(R43.1, V5)
- NET_C(R42.2, GND)
-#if 1
- RES(R63, RES_K(1)) /* */
- RES(R62, 150) /* */
-
- QBJT_EB(Q10, "2SC1815")
-
- NET_C(R62.2, GND)
- NET_C(R62.1, Q10.E)
-
- NET_C(R63.1, V5)
- NET_C(R63.2, Q10.C)
-
- CAP(C42, CAP_U(0.1))
- CAP(C47, CAP_U(4.7))
- RES(VR1, RES_K(10))
-
- NET_C(C42.1, C47.1, R62.1)
- NET_C(C42.2, GND)
- NET_C(C47.2, VR1.1)
- NET_C(VR1.2, GND)
-#endif
- /* ---------------------------------------------------------------------- */
- /* Output */
- /* ---------------------------------------------------------------------- */
-
- RES(ROUT, 1000000)
-
- //NET_C(Q10.C, ROUT.1)
- //NET_C(R43.2, ROUT.1)
- NET_C(VR1.1, ROUT.1)
-
- NET_C(GND, ROUT.2)
-
- OPTIMIZE_FRONTIER(R40.1, RES_K(22), 50)
-NETLIST_END()
#else
/****************************************************************
@@ -687,7 +447,7 @@ void mario_state::sound_reset()
address_space &space = machine().device("audiocpu")->memory().space(AS_PROGRAM);
#if USE_8039
- set_ea(machine, 1);
+ set_ea(space, 1);
#endif
/* FIXME: convert to latch8 */
@@ -797,6 +557,8 @@ WRITE8_MEMBER(mario_state::mario_sh2_w)
{
#if OLD_SOUND
m_discrete->write(space, DS_SOUND1_INP, 0);
+#else
+ m_audio_snd1->write(data);
#endif
}
@@ -895,10 +657,11 @@ MACHINE_CONFIG_FRAGMENT( mario_audio )
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1)
#else
MCFG_SOUND_ADD("snd_nl", NETLIST_SOUND, 48000)
- MCFG_NETLIST_SETUP(nl_mario)
+ MCFG_NETLIST_SETUP(mario)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0)
MCFG_NETLIST_LOGIC_INPUT("snd_nl", "snd0", "SOUND0.IN", 0)
+ MCFG_NETLIST_LOGIC_INPUT("snd_nl", "snd1", "SOUND1.IN", 0)
MCFG_NETLIST_LOGIC_INPUT("snd_nl", "snd7", "SOUND7.IN", 0)
MCFG_NETLIST_INT_INPUT("snd_nl", "dac", "DAC.VAL", 0, 255)
diff --git a/src/mame/audio/nl_mario.cpp b/src/mame/audio/nl_mario.cpp
new file mode 100644
index 00000000000..1f6c2fb4ab6
--- /dev/null
+++ b/src/mame/audio/nl_mario.cpp
@@ -0,0 +1,306 @@
+// license:BSD-3-Clause
+// copyright-holders:Couriersud
+#include "netlist/devices/net_lib.h"
+
+/* ----------------------------------------------------------------------------
+ * Library section header START
+ * ---------------------------------------------------------------------------*/
+
+#ifndef __PLIB_PREPROCESSOR__
+
+#endif
+
+/* ----------------------------------------------------------------------------
+ * Library section header END
+ * ---------------------------------------------------------------------------*/
+
+/* ----------------------------------------------------------------------------
+ * Mario schematics
+ * ---------------------------------------------------------------------------*/
+
+/* ---------------------------------------------------------------------- */
+/* mario sound */
+/* ---------------------------------------------------------------------- */
+static NETLIST_START(nl_mario_snd0)
+
+ RES(R17, RES_K(27)) /* 20 according to parts list */
+ /* 27 verified, 30K in schematics */
+ CAP(C14, CAP_U(4.7)) /* verified */
+
+ TTL_74123(2H_A)
+ NET_C(2H_A.VCC, V5)
+ NET_C(2H_A.GND, GND)
+ NET_C(SOUND0.Q, 2H_A.B)
+ NET_C(GND, 2H_A.A)
+ NET_C(2H_A.CLRQ, ttlhigh) /* NOT IN SCHEMATICS */
+ DIODE(D1, "1N4148") /* FIXME: try to identify */
+ TTL_7404_INVERT(1H_A, 2H_A.QQ)
+ NET_C(R17.1, V5)
+ NET_C(R17.2, D1.A, C14.1)
+ NET_C(D1.K, 2H_A.RC)
+ NET_C(C14.2, 2H_A.C)
+
+ RES(R6, RES_K(4.7)) /* verified */
+ CAP(C3, CAP_U(10)) /* verified */
+
+ NET_C(1H_A.Q, R6.1)
+ NET_C(R6.2, C3.1, 1J_A.FC)
+ NET_C(R6.2, 2J_A.FC)
+ NET_C(C3.2, GND)
+
+ // #define MR_C6 CAP_N(3.9) /* verified */
+
+ SN74LS629(1J_A, CAP_N(3.9))
+ NET_C(1J_A.RNG, V5)
+ NET_C(1J_A.ENQ, ttllow)
+ NET_C(GND, 1J_A.GND)
+
+ // #define MR_C17 CAP_N(22) /* verified */
+
+ SN74LS629(2J_A, CAP_N(22))
+ NET_C(2J_A.RNG, V5)
+ NET_C(2J_A.ENQ, ttllow)
+ NET_C(GND, 2J_A.GND)
+
+ TTL_7486_XOR(1K_A, 1J_A.Y, 2J_A.Y)
+ TTL_7408_AND(2K_A, 2H_A.Q, 1K_A)
+NETLIST_END()
+
+/* ---------------------------------------------------------------------- */
+/* luigi sound */
+/* ---------------------------------------------------------------------- */
+static NETLIST_START(nl_mario_snd1)
+
+ RES(R18, RES_K(30)) /* 20 according to parts list */
+ /* 27 verified, 30K in schematics */
+ CAP(C15, CAP_U(4.7)) /* verified */
+
+ TTL_74123(2H_B)
+ NET_C(2H_B.VCC, V5)
+ NET_C(2H_B.GND, GND)
+ NET_C(SOUND1.Q, 2H_B.B)
+ NET_C(GND, 2H_B.A)
+ NET_C(2H_B.CLRQ, ttlhigh) /* NOT IN SCHEMATICS */
+ DIODE(D8, "1N4148") /* FIXME: try to identify */
+ TTL_7404_INVERT(1H_B, 2H_B.QQ)
+ NET_C(R18.1, V5)
+ NET_C(R18.2, D8.A, C15.1)
+ NET_C(D8.K, 2H_B.RC)
+ NET_C(C15.2, 2H_B.C)
+
+ RES(R7, RES_K(4.7)) /* verified */
+ CAP(C4, CAP_U(4.7)) /* verified */
+
+ NET_C(1H_B.Q, R7.1)
+ NET_C(R7.2, C4.1, 1J_B.FC)
+ NET_C(R7.2, 2J_B.FC)
+ NET_C(C4.2, GND)
+
+ SN74LS629(1J_B, CAP_N(39)) /* C5 */
+ NET_C(1J_B.RNG, V5)
+ NET_C(1J_B.ENQ, ttllow)
+ NET_C(GND, 1J_B.GND)
+
+ SN74LS629(2J_B, CAP_N(6.8)) /* C16 */
+ NET_C(2J_B.RNG, V5)
+ NET_C(2J_B.ENQ, ttllow)
+ NET_C(GND, 2J_B.GND)
+
+ TTL_7486_XOR(1K_B, 1J_B.Y, 2J_B.Y)
+ TTL_7408_AND(2K_B, 2H_B.Q, 1K_B)
+NETLIST_END()
+
+/* ---------------------------------------------------------------------- */
+/* skid sound */
+/* ---------------------------------------------------------------------- */
+
+// FIXME: Diodes are 1S953
+static NETLIST_START(nl_mario_snd7)
+
+ RES(R61, RES_K(47))
+ CAP(C41, CAP_U(4.7)) /* verified */
+
+ TTL_74123(4L_A)
+ NET_C(4L_A.VCC, V5)
+ NET_C(4L_A.GND, GND)
+ NET_C(SOUND7.Q, 4L_A.B)
+ NET_C(GND, 4L_A.A)
+ NET_C(4L_A.CLRQ, ttlhigh) /* NOT IN SCHEMATICS */
+ DIODE(D10, "1N4148") /* FIXME: try to identify */
+ TTL_7404_INVERT(4J_A, 4L_A.Q)
+ NET_C(R61.1, V5)
+ NET_C(R61.2, D10.A, C41.1)
+ NET_C(D10.K, 4L_A.RC)
+ NET_C(C41.2, 4L_A.C)
+
+ RES(R65, RES_K(10))
+ CAP(C44, CAP_U(3.3)) /* verified */
+
+ SN74LS629(4K_A, CAP_U(0.022))
+ NET_C(4K_A.RNG, V5)
+ NET_C(4K_A.ENQ, ttllow)
+ NET_C(GND, 4K_A.GND)
+ NET_C(R65.1, 4J_A.Q)
+ NET_C(R65.2, 4K_A.FC, C44.1)
+ NET_C(C44.2, GND)
+
+ CD4020_WI(3H, 4K_B.Y, ttllow, V5, GND)
+ TTL_7404_INVERT(4J_B, 3H.Q12)
+
+ RES(R64, RES_K(20))
+ CAP(C43, CAP_U(3.3)) /* verified */
+
+ SN74LS629(4K_B, CAP_U(0.0047))
+ NET_C(4K_B.RNG, V5)
+ NET_C(4K_B.ENQ, ttllow)
+ NET_C(GND, 4K_B.GND)
+ NET_C(R64.1, 4J_B.Q)
+ NET_C(R64.2, 4K_B.FC, C43.1)
+ NET_C(C43.2, GND)
+
+ TTL_7486_XOR(1K_C, 3H.Q4, 4K_A.Y)
+ TTL_7408_AND(2K_C, 4L_A.Q, 1K_C)
+
+NETLIST_END()
+
+/* ---------------------------------------------------------------------- */
+/* DAC sound */
+/* ---------------------------------------------------------------------- */
+static NETLIST_START(nl_mario_dac)
+ RES(R34, RES_M(2))
+ RES(R35, RES_M(1))
+ RES(R36, RES_M(1.8))
+ LM3900(3M_1)
+ NET_C(3M_1.VM, GND)
+ NET_C(3M_1.VP, V5)
+
+ NET_C(DAC.VOUT, R34.1)
+ NET_C(3M_1.MINUS, R34.2, R35.2)
+ NET_C(3M_1.OUT, R35.1)
+ NET_C(3M_1.PLUS, R36.1)
+ NET_C(R36.2, GND)
+
+ RES(R21, RES_M(1.8))
+ RES(R23, RES_K(10))
+ RES(R25, RES_K(10))
+ RES(R37, RES_K(750))
+ RES(R38, RES_K(360))
+ RES(R39, RES_K(750))
+
+ CAP(C18, CAP_P(100))
+ CAP(C19, CAP_U(10))
+ CAP(C20, CAP_U(1))
+ CAP(C30, CAP_P(100))
+
+ LM3900(3M_2)
+ NET_C(3M_2.VM, GND)
+ NET_C(3M_2.VP, V5)
+
+ NET_C(R35.1, C20.1)
+ NET_C(C20.2, R37.1)
+ NET_C(R37.2, R38.2, C18.1, R39.2)
+
+ NET_C(C18.2, GND)
+ NET_C(R38.1, C30.2, 3M_2.MINUS)
+ NET_C(3M_2.OUT, R39.1, C30.1)
+
+ NET_C(R21.1, 3M_2.PLUS)
+ NET_C(R21.2, C19.1, R25.2, R23.1)
+ NET_C(C19.2, R23.2, GND)
+ NET_C(R25.1, V5)
+NETLIST_END()
+
+NETLIST_START(mario)
+
+ LOCAL_SOURCE(nl_mario_snd0)
+ LOCAL_SOURCE(nl_mario_snd1)
+ LOCAL_SOURCE(nl_mario_snd7)
+ LOCAL_SOURCE(nl_mario_dac)
+
+ SOLVER(Solver, 48000)
+ PARAM(Solver.ACCURACY, 1e-6)
+ PARAM(Solver.SOR_FACTOR, 1.0)
+ PARAM(Solver.GS_THRESHOLD, 5)
+ PARAM(Solver.GS_LOOPS, 1)
+ /* Dynamic timestepping avoids excessive newton loops on startup */
+ PARAM(Solver.DYNAMIC_LTE, 5e-2)
+ PARAM(Solver.DYNAMIC_TS, 1)
+ ANALOG_INPUT(V5, 5)
+
+ TTL_INPUT(SOUND0, 1)
+ INCLUDE(nl_mario_snd0)
+
+ TTL_INPUT(SOUND1, 1)
+ INCLUDE(nl_mario_snd1)
+
+ TTL_INPUT(SOUND7, 1)
+ INCLUDE(nl_mario_snd7)
+
+ R2R_DAC(DAC, 3.4, 10000.0, 8)
+ NET_C(DAC.VGND, GND)
+
+ INCLUDE(nl_mario_dac)
+
+ /* ---------------------------------------------------------------------- */
+ /* mixing */
+ /* ---------------------------------------------------------------------- */
+
+ RES(R20, RES_K(22)) /* verified */
+ RES(R19, RES_K(22)) /* verified */
+ RES(R40, RES_K(22)) /* verified */
+ RES(R41, RES_K(100)) /* verified */
+ CAP(C31, CAP_U(0.022)) /* */
+
+ NET_C(2K_A.Q, R20.1)
+ NET_C(2K_B.Q, R19.1)
+ NET_C(2K_C.Q, R41.1)
+
+ NET_C(R39.1, R40.1)
+
+ NET_C(R20.2, R19.2, R40.2, R41.2, C31.1)
+ NET_C(C31.2, GND)
+
+ CAP(C32, CAP_U(1)) /* verified */
+ RES(R42, RES_K(43)) /* verified */
+ RES(R43, RES_K(100)) /* verified */
+
+ NET_C(C31.1, C32.1)
+ NET_C(C32.2, R42.1, R43.2, Q10.B)
+ //NET_C(C32.2, R42.1, R43.2)
+ NET_C(R43.1, V5)
+ NET_C(R42.2, GND)
+#if 1
+ RES(R63, RES_K(1)) /* */
+ RES(R62, 150) /* */
+
+ QBJT_EB(Q10, "2SC1815")
+
+ NET_C(R62.2, GND)
+ NET_C(R62.1, Q10.E)
+
+ NET_C(R63.1, V5)
+ NET_C(R63.2, Q10.C)
+
+ CAP(C42, CAP_U(0.1))
+ CAP(C47, CAP_U(4.7))
+ RES(VR1, RES_K(10))
+
+ NET_C(C42.1, C47.1, R62.1)
+ NET_C(C42.2, GND)
+ NET_C(C47.2, VR1.1)
+ NET_C(VR1.2, GND)
+#endif
+ /* ---------------------------------------------------------------------- */
+ /* Output */
+ /* ---------------------------------------------------------------------- */
+
+ RES(ROUT, 1000000)
+
+ //NET_C(Q10.C, ROUT.1)
+ //NET_C(R43.2, ROUT.1)
+ NET_C(VR1.1, ROUT.1)
+
+ NET_C(GND, ROUT.2)
+
+ OPTIMIZE_FRONTIER(R40.1, RES_K(22), 50)
+NETLIST_END()
diff --git a/src/mame/audio/nl_mario.h b/src/mame/audio/nl_mario.h
new file mode 100644
index 00000000000..f974efed7e1
--- /dev/null
+++ b/src/mame/audio/nl_mario.h
@@ -0,0 +1,4 @@
+// license:BSD-3-Clause
+// copyright-holders:Andrew Gardner, Couriersud
+
+NETLIST_EXTERNAL(mario)
diff --git a/src/mame/bus/vme/mzr8300.cpp b/src/mame/bus/vme/mzr8300.cpp
deleted file mode 100644
index 669f1579b28..00000000000
--- a/src/mame/bus/vme/mzr8300.cpp
+++ /dev/null
@@ -1,92 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Joakim Larsson Edstrom
-
-#include "emu.h"
-#include "mzr8300.h"
-#include "machine/z80sio.h"
-
-#define LOG_GENERAL 0x01
-#define LOG_SETUP 0x02
-#define LOG_PRINTF 0x04
-
-#define VERBOSE 0 // (LOG_PRINTF | LOG_SETUP | LOG_GENERAL)
-
-#define LOGMASK(mask, ...) do { if (VERBOSE & mask) logerror(__VA_ARGS__); } while (0)
-#define LOGLEVEL(mask, level, ...) do { if ((VERBOSE & mask) >= level) logerror(__VA_ARGS__); } while (0)
-
-#define LOG(...) LOGMASK(LOG_GENERAL, __VA_ARGS__)
-#define LOGSETUP(...) LOGMASK(LOG_SETUP, __VA_ARGS__)
-
-#if VERBOSE & LOG_PRINTF
-#define logerror printf
-#endif
-
-#ifdef _MSC_VER
-#define FUNCNAME __func__
-#else
-#define FUNCNAME __PRETTY_FUNCTION__
-#endif
-
-//**************************************************************************
-// GLOBAL VARIABLES
-//**************************************************************************
-
-const device_type VME_MZR8300 = &device_creator<vme_mzr8300_card_device>;
-
-vme_mzr8300_card_device::vme_mzr8300_card_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
- device_t(mconfig, VME_MZR8300, "Mizar 8300 SIO serial board", tag, owner, clock, "mzr8300", __FILE__),
- device_vme_p1_card_interface(mconfig, *this)
-{
- LOG("%s %s\n", tag, FUNCNAME);
-}
-
-vme_mzr8300_card_device::vme_mzr8300_card_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, uint32_t clock, const char *shortname, const char *source) :
- device_t(mconfig, type, name, tag, owner, clock, shortname, source),
- device_vme_p1_card_interface(mconfig, *this)
-{
- LOG("%s %s\n", tag, FUNCNAME);
-}
-
-void vme_mzr8300_card_device::device_start()
-{
- LOG("%s %s\n", tag(), FUNCNAME);
- set_vme_p1_device();
-
- /* Setup r/w handlers for first SIO in A16 */
- uint32_t base = 0xFF0000;
- m_vme_p1->install_device(base + 0, base + 1, // Channel B - Data
- read8_delegate(FUNC(z80sio_device::db_r), subdevice<z80sio_device>("sio0")), write8_delegate(FUNC(z80sio_device::db_w), subdevice<z80sio_device>("sio0")), 0x00ff);
- m_vme_p1->install_device(base + 2, base + 3, // Channel B - Control
- read8_delegate(FUNC(z80sio_device::cb_r), subdevice<z80sio_device>("sio0")), write8_delegate(FUNC(z80sio_device::cb_w), subdevice<z80sio_device>("sio0")), 0x00ff);
- m_vme_p1->install_device(base + 4, base + 5, // Channel A - Data
- read8_delegate(FUNC(z80sio_device::da_r), subdevice<z80sio_device>("sio0")), write8_delegate(FUNC(z80sio_device::da_w), subdevice<z80sio_device>("sio0")), 0x00ff);
- m_vme_p1->install_device(base + 6, base + 7, // Channel A - Control
- read8_delegate(FUNC(z80sio_device::ca_r), subdevice<z80sio_device>("sio0")), write8_delegate(FUNC(z80sio_device::ca_w), subdevice<z80sio_device>("sio0")), 0x00ff);
-}
-
-void vme_mzr8300_card_device::device_reset()
-{
- LOG("%s %s\n", tag(), FUNCNAME);
-}
-
-//-------------------------------------------------
-// machine_config_additions - device-specific
-// machine configurations
-//-------------------------------------------------
-
-MACHINE_CONFIG_EXTERN( mzr8300 );
-
-machine_config_constructor vme_mzr8300_card_device::device_mconfig_additions() const
-{
- LOG("%s %s\n", tag(), FUNCNAME);
- return MACHINE_CONFIG_NAME( mzr8300 );
-}
-
-READ8_MEMBER (vme_mzr8300_card_device::read8){
- LOG("%s()\n", FUNCNAME);
- return (uint8_t) 0;
-}
-
-WRITE8_MEMBER (vme_mzr8300_card_device::write8){
- LOG("%s()\n", FUNCNAME);
-}
diff --git a/src/mame/drivers/40love.cpp b/src/mame/drivers/40love.cpp
index 27fcab8b205..004d9b0b6a3 100644
--- a/src/mame/drivers/40love.cpp
+++ b/src/mame/drivers/40love.cpp
@@ -628,8 +628,8 @@ WRITE8_MEMBER(fortyl_state::to_main_w)
static ADDRESS_MAP_START( 40love_map, AS_PROGRAM, 8, fortyl_state )
AM_RANGE(0x0000, 0x7fff) AM_ROM
AM_RANGE(0x8000, 0x87ff) AM_RAM /* M5517P on main board */
- AM_RANGE(0x8800, 0x8800) AM_DEVREADWRITE("bmcu", buggychl_mcu_device, buggychl_mcu_r, buggychl_mcu_w)
- AM_RANGE(0x8801, 0x8801) AM_DEVREAD("bmcu", buggychl_mcu_device, buggychl_mcu_status_r) AM_WRITE(pix1_mcu_w) //pixel layer related
+ AM_RANGE(0x8800, 0x8800) AM_DEVREADWRITE("bmcu", taito68705_mcu_device, mcu_r, mcu_w)
+ AM_RANGE(0x8801, 0x8801) AM_DEVREAD("bmcu", taito68705_mcu_device, mcu_status_r) AM_WRITE(pix1_mcu_w) //pixel layer related
AM_RANGE(0x8802, 0x8802) AM_WRITE(bank_select_w)
AM_RANGE(0x8803, 0x8803) AM_READWRITE(pix2_r, pix2_w) //pixel layer related
AM_RANGE(0x8804, 0x8804) AM_READWRITE(from_snd_r, sound_command_w)
@@ -1011,8 +1011,6 @@ MACHINE_RESET_MEMBER(fortyl_state,common)
MACHINE_RESET_MEMBER(fortyl_state,40love)
{
- m_mcu->set_input_line(0, CLEAR_LINE);
-
MACHINE_RESET_CALL_MEMBER(common);
}
@@ -1046,9 +1044,7 @@ static MACHINE_CONFIG_START( 40love, fortyl_state )
MCFG_CPU_PROGRAM_MAP(sound_map)
MCFG_CPU_PERIODIC_INT_DRIVER(fortyl_state, irq0_line_hold, 2*60) /* source/number of IRQs is unknown */
- MCFG_CPU_ADD("mcu",M68705,18432000/6) /* OK */
- MCFG_CPU_PROGRAM_MAP(buggychl_mcu_map)
- MCFG_DEVICE_ADD("bmcu", BUGGYCHL_MCU, 0)
+ MCFG_DEVICE_ADD("bmcu", TAITO68705_MCU, 18432000/6) /* OK */
MCFG_QUANTUM_TIME(attotime::from_hz(6000)) /* high interleave to ensure proper synchronization of CPUs */
MCFG_MACHINE_START_OVERRIDE(fortyl_state,40love)
@@ -1107,9 +1103,7 @@ static MACHINE_CONFIG_START( undoukai, fortyl_state )
MCFG_CPU_PROGRAM_MAP(sound_map)
MCFG_CPU_PERIODIC_INT_DRIVER(fortyl_state, irq0_line_hold, 2*60) /* source/number of IRQs is unknown */
-// MCFG_CPU_ADD("mcu",M68705,18432000/6)
-// MCFG_CPU_PROGRAM_MAP(buggychl_mcu_map)
-// MCFG_DEVICE_ADD("bmcu", BUGGYCHL_MCU, 0)
+// MCFG_DEVICE_ADD("bmcu", TAITO68705_MCU, 18432000/6)
MCFG_MACHINE_START_OVERRIDE(fortyl_state,undoukai)
MCFG_MACHINE_RESET_OVERRIDE(fortyl_state,undoukai) /* init machine */
@@ -1175,7 +1169,7 @@ ROM_START( 40love )
ROM_LOAD( "a30-12.u38", 0x8000, 0x2000, CRC(f7afd475) SHA1(dd09d5ca7fec5e0454f9efb8ebc722561010f124) )
ROM_LOAD( "a30-13.u39", 0xa000, 0x2000, CRC(e806630f) SHA1(09022aae88ea0171a0aacf3260fa3a95e8faeb21) )
- ROM_REGION( 0x0800, "mcu", 0 ) /* 2k for the microcontroller */
+ ROM_REGION( 0x0800, "bmcu:mcu", 0 ) /* 2k for the microcontroller */
ROM_LOAD( "a30-14" , 0x0000, 0x0800, CRC(c4690279) SHA1(60bc77e03b9be434bb97a374a2fedeb8d049a660) )
ROM_REGION( 0x8000, "gfx1", 0 )
diff --git a/src/mame/drivers/aa310.cpp b/src/mame/drivers/aa310.cpp
index 6a3aa2f042f..f62ebc51a4b 100644
--- a/src/mame/drivers/aa310.cpp
+++ b/src/mame/drivers/aa310.cpp
@@ -38,7 +38,6 @@
* Then reboot / reset the machine, and use cat to (attempt) to load a floppy contents.
*
* TODO:
- * - Make floppies to work;
* - RISC OS Alarm app crash the whole OS
* - RISC OS Draw app uses unimplemented copro instructions
*
@@ -125,9 +124,7 @@ protected:
WRITE_LINE_MEMBER(aa310_state::aa310_wd177x_intrq_w)
{
if (state)
- {
archimedes_request_fiq(ARCHIMEDES_FIQ_FLOPPY);
- }
else
archimedes_clear_fiq(ARCHIMEDES_FIQ_FLOPPY);
}
@@ -135,9 +132,7 @@ WRITE_LINE_MEMBER(aa310_state::aa310_wd177x_intrq_w)
WRITE_LINE_MEMBER(aa310_state::aa310_wd177x_drq_w)
{
if (state)
- {
archimedes_request_fiq(ARCHIMEDES_FIQ_FLOPPY_DRQ);
- }
else
archimedes_clear_fiq(ARCHIMEDES_FIQ_FLOPPY_DRQ);
}
@@ -352,12 +347,6 @@ static INPUT_PORTS_START( aa310 )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_JOYSTICK_UP) PORT_4WAY
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT) PORT_4WAY
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN) PORT_4WAY
-
- PORT_START("tape")/* tape control */
- PORT_BIT(0x01, 0x00, IPT_KEYBOARD) PORT_NAME("TAPE STOP") PORT_CODE(KEYCODE_F5)
- PORT_BIT(0x02, 0x00, IPT_KEYBOARD) PORT_NAME("TAPE PLAY") PORT_CODE(KEYCODE_F6)
- PORT_BIT(0x04, 0x00, IPT_KEYBOARD) PORT_NAME("TAPE REW") PORT_CODE(KEYCODE_F7)
- PORT_BIT (0xf8, 0x80, IPT_UNUSED)
INPUT_PORTS_END
FLOPPY_FORMATS_MEMBER( aa310_state::floppy_formats )
@@ -415,7 +404,7 @@ static MACHINE_CONFIG_START( aa310, aa310_state )
MCFG_WD_FDC_DRQ_CALLBACK(WRITELINE(aa310_state, aa310_wd177x_drq_w))
MCFG_FLOPPY_DRIVE_ADD("fdc:0", aa310_floppies, "35dd", aa310_state::floppy_formats)
MCFG_FLOPPY_DRIVE_SOUND(true)
- MCFG_FLOPPY_DRIVE_ADD("fdc:1", aa310_floppies, "35dd", aa310_state::floppy_formats)
+ MCFG_FLOPPY_DRIVE_ADD("fdc:1", aa310_floppies, nullptr, aa310_state::floppy_formats) // rarely had 2nd FDD installed, space was used for HDD
MCFG_FLOPPY_DRIVE_SOUND(true)
MCFG_SOFTWARE_LIST_ADD("flop_list", "archimedes")
@@ -521,6 +510,10 @@ static MACHINE_CONFIG_DERIVED( aa4, aa5000 )
MCFG_CPU_MODIFY("maincpu") // ARM3
MCFG_CPU_CLOCK(XTAL_24MHz)
+ /* video hardware */
+ MCFG_SCREEN_MODIFY("screen")
+ MCFG_SCREEN_TYPE(LCD)
+
/* 765 FDC */
/* 60MB HDD */
@@ -586,6 +579,11 @@ ROM_START( aa305 )
ROMX_LOAD( "0296,044-02.ic27", 0x180000, 0x80000, CRC(707b0c6c) SHA1(345199a33fed23996374b9db8170a52ab63f0380), ROM_BIOS(7) )
ROM_SYSTEM_BIOS( 7, "319", "RISC OS 3.19 (09 Jun 1993)" ) /* Parts 0296,241-01, 0296,242-01, 0296,243-01, 0296,244-01, */
ROMX_LOAD( "riscos319.bin", 0x000000, 0x200000, CRC(00c7a3d3) SHA1(be7a8cba5d6c6c0e1c4838712524056cf4b8c8cb), ROM_BIOS(8) )
+ ROM_SYSTEM_BIOS( 8, "test", "Diagnostic Test ROMs" ) /* Usage described in Archimedes 300 Series Service Manual */
+ ROMX_LOAD( "0276,146-01.ic24", 0x000000, 0x10000, CRC(9c45283c) SHA1(9eb5bd7ad0958f194a3416d79d7e01e4c45741e1), ROM_BIOS(9) | ROM_SKIP(3) )
+ ROMX_LOAD( "0276,147-01.ic25", 0x000001, 0x10000, CRC(ad94e17f) SHA1(1c8e39c69d4ae1b674e0f732aaa62a4403998f41), ROM_BIOS(9) | ROM_SKIP(3) )
+ ROMX_LOAD( "0276,148-01.ic26", 0x000002, 0x10000, CRC(1ab02f2d) SHA1(dd7d216967524e64d1a03076a6081461ec8528c3), ROM_BIOS(9) | ROM_SKIP(3) )
+ ROMX_LOAD( "0276,149-01.ic27", 0x000003, 0x10000, CRC(5fd6a406) SHA1(790af8a4c74d0f6714d528f7502443ce5898a618), ROM_BIOS(9) | ROM_SKIP(3) )
ROM_REGION( 0x200000, "vram", ROMREGION_ERASE00 )
ROM_REGION( 0x400000, "extension", ROMREGION_ERASE00 )
@@ -710,7 +708,7 @@ ROM_END
COMP( 1987, aa305, aa310, 0, aa305, aa310, aa310_state, aa310, "Acorn", "Archimedes 305", MACHINE_NOT_WORKING)
COMP( 1987, aa310, 0, 0, aa310, aa310, aa310_state, aa310, "Acorn", "Archimedes 310", MACHINE_NOT_WORKING)
COMP( 1987, aa440, aa310, 0, aa440, aa310, aa310_state, aa310, "Acorn", "Archimedes 440", MACHINE_NOT_WORKING)
-COMP( 1989, aa3000, aa310, 0, aa3000, aa310, aa310_state, aa310, "Acorn", "Archimedes 3000", MACHINE_NOT_WORKING)
+COMP( 1989, aa3000, aa310, 0, aa3000, aa310, aa310_state, aa310, "Acorn", "BBC A3000", MACHINE_NOT_WORKING)
COMP( 1989, aa4101, aa310, 0, aa4101, aa310, aa310_state, aa310, "Acorn", "Archimedes 410/1", MACHINE_NOT_WORKING)
COMP( 1989, aa4201, aa310, 0, aa4201, aa310, aa310_state, aa310, "Acorn", "Archimedes 420/1", MACHINE_NOT_WORKING)
COMP( 1989, aa4401, aa310, 0, aa4401, aa310, aa310_state, aa310, "Acorn", "Archimedes 440/1", MACHINE_NOT_WORKING)
diff --git a/src/mame/drivers/aerofgt.cpp b/src/mame/drivers/aerofgt.cpp
index 9846b97e08a..3fd5d2b8953 100644
--- a/src/mame/drivers/aerofgt.cpp
+++ b/src/mame/drivers/aerofgt.cpp
@@ -67,36 +67,21 @@ Verification still needed for the other PCBs.
#include "sound/3812intf.h"
#include "includes/aerofgt.h"
-WRITE16_MEMBER(aerofgt_state::sound_command_w)
-{
- if (ACCESSING_BITS_0_7)
- {
- m_pending_command = 1;
- m_soundlatch->write(space, offset, data & 0xff);
- m_audiocpu->set_input_line(INPUT_LINE_NMI, PULSE_LINE);
- }
-}
-WRITE16_MEMBER(aerofgt_state::turbofrc_sound_command_w)
+WRITE8_MEMBER(aerofgt_state::sound_command_w)
{
- if (ACCESSING_BITS_8_15)
- {
- m_pending_command = 1;
- m_soundlatch->write(space, offset, (data >> 8) & 0xff);
- m_audiocpu->set_input_line(INPUT_LINE_NMI, PULSE_LINE);
- }
+ m_pending_command = 1;
+ m_soundlatch->write(space, 0, data);
+ m_audiocpu->set_input_line(INPUT_LINE_NMI, PULSE_LINE);
}
-WRITE16_MEMBER(aerofgt_state::aerfboot_soundlatch_w)
+WRITE8_MEMBER(aerofgt_state::aerfboot_soundlatch_w)
{
- if(ACCESSING_BITS_8_15)
- {
- m_soundlatch->write(space, 0, (data >> 8) & 0xff);
- m_audiocpu->set_input_line(INPUT_LINE_NMI, PULSE_LINE);
- }
+ m_soundlatch->write(space, 0, data);
+ m_audiocpu->set_input_line(INPUT_LINE_NMI, PULSE_LINE);
}
-READ16_MEMBER(aerofgt_state::pending_command_r)
+READ8_MEMBER(aerofgt_state::pending_command_r)
{
return m_pending_command;
}
@@ -111,7 +96,6 @@ WRITE8_MEMBER(aerofgt_state::aerofgt_sh_bankswitch_w)
membank("bank1")->set_entry(data & 0x03);
}
-
WRITE16_MEMBER(aerofgt_state::pspikesb_oki_banking_w)
{
m_oki->set_rom_bank(data & 3);
@@ -153,10 +137,10 @@ static ADDRESS_MAP_START( pspikes_map, AS_PROGRAM, 16, aerofgt_state )
AM_RANGE(0xffc000, 0xffc3ff) AM_WRITEONLY AM_SHARE("spriteram3")
AM_RANGE(0xffd000, 0xffdfff) AM_RAM AM_SHARE("rasterram") /* bg1 scroll registers */
AM_RANGE(0xffe000, 0xffefff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette")
- AM_RANGE(0xfff000, 0xfff001) AM_READ_PORT("IN0") AM_WRITE(pspikes_palette_bank_w)
- AM_RANGE(0xfff002, 0xfff003) AM_READ_PORT("IN1") AM_WRITE(pspikes_gfxbank_w)
+ AM_RANGE(0xfff000, 0xfff001) AM_READ_PORT("IN0") AM_WRITE8(pspikes_palette_bank_w, 0x00ff)
+ AM_RANGE(0xfff002, 0xfff003) AM_READ_PORT("IN1") AM_WRITE8(pspikes_gfxbank_w, 0x00ff)
AM_RANGE(0xfff004, 0xfff005) AM_READ_PORT("DSW") AM_WRITE(aerofgt_bg1scrolly_w)
- AM_RANGE(0xfff006, 0xfff007) AM_READWRITE(pending_command_r, sound_command_w)
+ AM_RANGE(0xfff006, 0xfff007) AM_READWRITE8(pending_command_r, sound_command_w, 0x00ff)
ADDRESS_MAP_END
static ADDRESS_MAP_START( pspikesb_map, AS_PROGRAM, 16, aerofgt_state )
@@ -190,7 +174,7 @@ static ADDRESS_MAP_START( spikes91_map, AS_PROGRAM, 16, aerofgt_state )
AM_RANGE(0xffd000, 0xffdfff) AM_RAM AM_SHARE("rasterram") /* bg1 scroll registers */
AM_RANGE(0xffe000, 0xffefff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette")
AM_RANGE(0xfff000, 0xfff001) AM_READ_PORT("IN0")
- AM_RANGE(0xfff002, 0xfff003) AM_READ_PORT("IN1") AM_WRITE(pspikes_gfxbank_w)
+ AM_RANGE(0xfff002, 0xfff003) AM_READ_PORT("IN1") AM_WRITE8(pspikes_gfxbank_w, 0x00ff)
AM_RANGE(0xfff004, 0xfff005) AM_READ_PORT("DSW") AM_WRITE(aerofgt_bg1scrolly_w)
AM_RANGE(0xfff006, 0xfff007) AM_NOP
AM_RANGE(0xfff008, 0xfff009) AM_WRITE(spikes91_lookup_w)
@@ -204,8 +188,8 @@ static ADDRESS_MAP_START( pspikesc_map, AS_PROGRAM, 16, aerofgt_state )
AM_RANGE(0xffc000, 0xffcbff) AM_RAM AM_SHARE("spriteram3")
AM_RANGE(0xffd000, 0xffdfff) AM_RAM AM_SHARE("rasterram") /* bg1 scroll registers */
AM_RANGE(0xffe000, 0xffefff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette")
- AM_RANGE(0xfff000, 0xfff001) AM_READ_PORT("IN0") AM_WRITE(pspikes_palette_bank_w)
- AM_RANGE(0xfff002, 0xfff003) AM_READ_PORT("IN1") AM_WRITE(pspikes_gfxbank_w)
+ AM_RANGE(0xfff000, 0xfff001) AM_READ_PORT("IN0") AM_WRITE8(pspikes_palette_bank_w, 0x00ff)
+ AM_RANGE(0xfff002, 0xfff003) AM_READ_PORT("IN1") AM_WRITE8(pspikes_gfxbank_w, 0x00ff)
AM_RANGE(0xfff004, 0xfff005) AM_READ_PORT("DSW")
AM_RANGE(0xfff004, 0xfff005) AM_WRITE(aerofgt_bg1scrolly_w)
AM_RANGE(0xfff006, 0xfff007) AM_DEVREADWRITE8("oki", okim6295_device, read, write, 0x00ff)
@@ -223,11 +207,11 @@ static ADDRESS_MAP_START( karatblz_map, AS_PROGRAM, 16, aerofgt_state )
AM_RANGE(0x0fc000, 0x0fc7ff) AM_RAM AM_SHARE("spriteram3")
AM_RANGE(0x0fe000, 0x0fe7ff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette")
AM_RANGE(0x0ff000, 0x0ff001) AM_READ_PORT("IN0")
- AM_RANGE(0x0ff002, 0x0ff003) AM_READ_PORT("IN1") AM_WRITE(karatblz_gfxbank_w)
+ AM_RANGE(0x0ff002, 0x0ff003) AM_READ_PORT("IN1") AM_WRITE8(karatblz_gfxbank_w, 0xff00)
AM_RANGE(0x0ff004, 0x0ff005) AM_READ_PORT("IN2")
- AM_RANGE(0x0ff006, 0x0ff007) AM_READ_PORT("IN3") AM_WRITE(sound_command_w)
+ AM_RANGE(0x0ff006, 0x0ff007) AM_READ_PORT("IN3") AM_WRITE8(sound_command_w, 0x00ff)
AM_RANGE(0x0ff008, 0x0ff009) AM_READ_PORT("DSW") AM_WRITE(aerofgt_bg1scrollx_w)
- AM_RANGE(0x0ff00a, 0x0ff00b) AM_READ(pending_command_r) AM_WRITE(aerofgt_bg1scrolly_w)
+ AM_RANGE(0x0ff00a, 0x0ff00b) AM_READ8(pending_command_r, 0x00ff) AM_WRITE(aerofgt_bg1scrolly_w)
AM_RANGE(0x0ff00c, 0x0ff00d) AM_WRITE(aerofgt_bg2scrollx_w)
AM_RANGE(0x0ff00e, 0x0ff00f) AM_WRITE(aerofgt_bg2scrolly_w)
ADDRESS_MAP_END
@@ -240,10 +224,10 @@ static ADDRESS_MAP_START( spinlbrk_map, AS_PROGRAM, 16, aerofgt_state )
AM_RANGE(0xffc000, 0xffc7ff) AM_RAM AM_SHARE("spriteram3")
AM_RANGE(0xffd000, 0xffd1ff) AM_RAM AM_SHARE("rasterram") /* bg1 scroll registers */
AM_RANGE(0xffe000, 0xffe7ff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette")
- AM_RANGE(0xfff000, 0xfff001) AM_READ_PORT("IN0") AM_WRITE(spinlbrk_gfxbank_w)
+ AM_RANGE(0xfff000, 0xfff001) AM_READ_PORT("IN0") AM_WRITE8(spinlbrk_gfxbank_w, 0x00ff)
AM_RANGE(0xfff002, 0xfff003) AM_READ_PORT("IN1") AM_WRITE(aerofgt_bg2scrollx_w)
AM_RANGE(0xfff004, 0xfff005) AM_READ_PORT("DSW")
- AM_RANGE(0xfff006, 0xfff007) AM_WRITE(sound_command_w)
+ AM_RANGE(0xfff006, 0xfff007) AM_WRITE8(sound_command_w, 0x00ff)
// AM_RANGE(0xfff008, 0xfff009) - read when analog inputs are enabled
// AM_RANGE(0xfff00a, 0xfff00b) /
ADDRESS_MAP_END
@@ -263,11 +247,11 @@ static ADDRESS_MAP_START( turbofrc_map, AS_PROGRAM, 16, aerofgt_state )
AM_RANGE(0x0ff000, 0x0ff001) AM_READ_PORT("IN0")
AM_RANGE(0x0ff002, 0x0ff003) AM_READ_PORT("IN1") AM_WRITE(aerofgt_bg1scrolly_w)
AM_RANGE(0x0ff004, 0x0ff005) AM_READ_PORT("DSW") AM_WRITE(aerofgt_bg2scrollx_w)
- AM_RANGE(0x0ff006, 0x0ff007) AM_READ(pending_command_r) AM_WRITE(aerofgt_bg2scrolly_w)
+ AM_RANGE(0x0ff006, 0x0ff007) AM_READ8(pending_command_r, 0x00ff) AM_WRITE(aerofgt_bg2scrolly_w)
AM_RANGE(0x0ff008, 0x0ff009) AM_READ_PORT("IN2")
AM_RANGE(0x0ff008, 0x0ff00b) AM_WRITE(turbofrc_gfxbank_w)
AM_RANGE(0x0ff00c, 0x0ff00d) AM_WRITENOP /* related to bg2 (written together with the scroll registers) */
- AM_RANGE(0x0ff00e, 0x0ff00f) AM_WRITE(turbofrc_sound_command_w)
+ AM_RANGE(0x0ff00e, 0x0ff00f) AM_WRITE8(sound_command_w, 0xff00)
ADDRESS_MAP_END
static ADDRESS_MAP_START( aerofgtb_map, AS_PROGRAM, 16, aerofgt_state )
@@ -283,10 +267,10 @@ static ADDRESS_MAP_START( aerofgtb_map, AS_PROGRAM, 16, aerofgt_state )
AM_RANGE(0x0fe000, 0x0fe001) AM_READ_PORT("IN0")
AM_RANGE(0x0fe002, 0x0fe003) AM_READ_PORT("IN1") AM_WRITE(aerofgt_bg1scrolly_w)
AM_RANGE(0x0fe004, 0x0fe005) AM_READ_PORT("DSW1") AM_WRITE(aerofgt_bg2scrollx_w)
- AM_RANGE(0x0fe006, 0x0fe007) AM_READ(pending_command_r) AM_WRITE(aerofgt_bg2scrolly_w)
+ AM_RANGE(0x0fe006, 0x0fe007) AM_READ8(pending_command_r, 0x00ff) AM_WRITE(aerofgt_bg2scrolly_w)
AM_RANGE(0x0fe008, 0x0fe009) AM_READ_PORT("DSW2")
AM_RANGE(0x0fe008, 0x0fe00b) AM_WRITE(turbofrc_gfxbank_w)
- AM_RANGE(0x0fe00e, 0x0fe00f) AM_WRITE(turbofrc_sound_command_w)
+ AM_RANGE(0x0fe00e, 0x0fe00f) AM_WRITE8(sound_command_w, 0xff00)
AM_RANGE(0x0ff000, 0x0fffff) AM_RAM AM_SHARE("rasterram") /* used only for the scroll registers */
ADDRESS_MAP_END
@@ -309,9 +293,9 @@ static ADDRESS_MAP_START( aerofgt_map, AS_PROGRAM, 16, aerofgt_state )
AM_RANGE(0xffffa4, 0xffffa5) AM_READ_PORT("SYSTEM")
AM_RANGE(0xffffa6, 0xffffa7) AM_READ_PORT("DSW1")
AM_RANGE(0xffffa8, 0xffffa9) AM_READ_PORT("DSW2")
- AM_RANGE(0xffffac, 0xffffad) AM_READ(pending_command_r) AM_WRITENOP /* ??? */
+ AM_RANGE(0xffffac, 0xffffad) AM_READ8(pending_command_r, 0x00ff) AM_WRITENOP /* ??? */
AM_RANGE(0xffffae, 0xffffaf) AM_READ_PORT("DSW3")
- AM_RANGE(0xffffc0, 0xffffc1) AM_WRITE(sound_command_w)
+ AM_RANGE(0xffffc0, 0xffffc1) AM_WRITE8(sound_command_w, 0x00ff)
ADDRESS_MAP_END
static ADDRESS_MAP_START( aerfboot_map, AS_PROGRAM, 16, aerofgt_state )
@@ -332,7 +316,7 @@ static ADDRESS_MAP_START( aerfboot_map, AS_PROGRAM, 16, aerofgt_state )
AM_RANGE(0x0fe004, 0x0fe005) AM_WRITE(aerofgt_bg2scrollx_w)
AM_RANGE(0x0fe006, 0x0fe007) AM_WRITE(aerofgt_bg2scrolly_w)
AM_RANGE(0x0fe008, 0x0fe00b) AM_WRITE(turbofrc_gfxbank_w)
- AM_RANGE(0x0fe00e, 0x0fe00f) AM_WRITE(aerfboot_soundlatch_w)
+ AM_RANGE(0x0fe00e, 0x0fe00f) AM_WRITE8(aerfboot_soundlatch_w, 0xff00)
AM_RANGE(0x0fe010, 0x0fe011) AM_WRITENOP
AM_RANGE(0x0fe012, 0x0fe013) AM_WRITENOP
AM_RANGE(0x0fe400, 0x0fe401) AM_WRITENOP
@@ -380,10 +364,10 @@ static ADDRESS_MAP_START( wbbc97_map, AS_PROGRAM, 16, aerofgt_state )
AM_RANGE(0xffc000, 0xffc3ff) AM_WRITEONLY AM_SHARE("spriteram3")
AM_RANGE(0xffd000, 0xffdfff) AM_RAM AM_SHARE("rasterram") /* bg1 scroll registers */
AM_RANGE(0xffe000, 0xffefff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette")
- AM_RANGE(0xfff000, 0xfff001) AM_READ_PORT("IN0") AM_WRITE(pspikes_palette_bank_w)
- AM_RANGE(0xfff002, 0xfff003) AM_READ_PORT("IN1") AM_WRITE(pspikes_gfxbank_w)
+ AM_RANGE(0xfff000, 0xfff001) AM_READ_PORT("IN0") AM_WRITE8(pspikes_palette_bank_w, 0x00ff)
+ AM_RANGE(0xfff002, 0xfff003) AM_READ_PORT("IN1") AM_WRITE8(pspikes_gfxbank_w, 0x00ff)
AM_RANGE(0xfff004, 0xfff005) AM_READ_PORT("DSW") AM_WRITE(aerofgt_bg1scrolly_w)
- AM_RANGE(0xfff006, 0xfff007) AM_READNOP AM_WRITE(sound_command_w)
+ AM_RANGE(0xfff006, 0xfff007) AM_READNOP AM_WRITE8(sound_command_w, 0x00ff)
AM_RANGE(0xfff00e, 0xfff00f) AM_WRITE(wbbc97_bitmap_enable_w)
ADDRESS_MAP_END
diff --git a/src/mame/drivers/aleisttl.cpp b/src/mame/drivers/aleisttl.cpp
index 75021c37dda..df43a588445 100644
--- a/src/mame/drivers/aleisttl.cpp
+++ b/src/mame/drivers/aleisttl.cpp
@@ -7,7 +7,7 @@
Chase (aka Chase1) (1976)
Deluxe Soccer (1973)
Fire Power (1975) EG-1020-2
- F??tsball (1975)
+ Fütsball (1975)
Galaxy Raider (1974)
Hesitation (1974) AL-6500?
Hockey, Soccer, Tennis (1974)
diff --git a/src/mame/drivers/alpha68k.cpp b/src/mame/drivers/alpha68k.cpp
index 18ab41042a8..df37a9da3f3 100644
--- a/src/mame/drivers/alpha68k.cpp
+++ b/src/mame/drivers/alpha68k.cpp
@@ -1304,10 +1304,10 @@ INPUT_PORTS_END
static INPUT_PORTS_START( skyadvnt )
PORT_START("IN0")
- ALPHA68K_PLAYER_INPUT_LSB( 1, IPT_UNKNOWN, IPT_START1, IP_ACTIVE_LOW )
+ ALPHA68K_PLAYER_INPUT_LSB( 1, IPT_BUTTON3, IPT_START1, IP_ACTIVE_LOW )
PORT_START("IN1")
- ALPHA68K_PLAYER_INPUT_LSB( 2, IPT_UNKNOWN, IPT_START2, IP_ACTIVE_LOW )
+ ALPHA68K_PLAYER_INPUT_LSB( 2, IPT_BUTTON3, IPT_START2, IP_ACTIVE_LOW )
ALPHA68K_MCU
diff --git a/src/mame/drivers/arkanoid.cpp b/src/mame/drivers/arkanoid.cpp
index 7612ece6051..544131bb412 100644
--- a/src/mame/drivers/arkanoid.cpp
+++ b/src/mame/drivers/arkanoid.cpp
@@ -896,19 +896,6 @@ static ADDRESS_MAP_START( brixian_map, AS_PROGRAM, 8, arkanoid_state )
ADDRESS_MAP_END
-static ADDRESS_MAP_START( mcu_map, AS_PROGRAM, 8, arkanoid_state )
- ADDRESS_MAP_GLOBAL_MASK(0x7ff)
- ADDRESS_MAP_UNMAP_HIGH
- AM_RANGE(0x0000, 0x0000) AM_READWRITE(arkanoid_68705_port_a_r, arkanoid_68705_port_a_w)
- AM_RANGE(0x0001, 0x0001) AM_READ_PORT("MUX")
- AM_RANGE(0x0002, 0x0002) AM_READWRITE(arkanoid_68705_port_c_r, arkanoid_68705_port_c_w)
- AM_RANGE(0x0004, 0x0004) AM_WRITE(arkanoid_68705_ddr_a_w)
- AM_RANGE(0x0006, 0x0006) AM_WRITE(arkanoid_68705_ddr_c_w)
- AM_RANGE(0x0008, 0x0008) AM_READWRITE(arkanoid_68705_tdr_r, arkanoid_68705_tdr_w)
- AM_RANGE(0x0009, 0x0009) AM_READWRITE(arkanoid_68705_tcr_r, arkanoid_68705_tcr_w)
- AM_RANGE(0x0010, 0x007f) AM_RAM
- AM_RANGE(0x0080, 0x07ff) AM_ROM
-ADDRESS_MAP_END
/* MCU Hookup based on 'Arkanoid_TAITO_(Japan 1986) PCB.rar' from Taro and others at http://zx-pk.ru forums
NOTE and TODO: these comments have not been significantly updated since the real taito arkanoid schematics were found. beware of mistakes!
@@ -1271,9 +1258,6 @@ GFXDECODE_END
void arkanoid_state::machine_start()
{
- // allocate the MCU timer, even if we have no MCU, and set it to fire NEVER.
- m_68705_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(arkanoid_state::timer_68705_increment),this));
- m_68705_timer->adjust(attotime::never);
save_item(NAME(m_gfxbank));
save_item(NAME(m_palettebank));
@@ -1290,12 +1274,9 @@ void arkanoid_state::machine_start()
save_item(NAME(m_portA_in));
save_item(NAME(m_portA_out));
- save_item(NAME(m_ddrA));
- save_item(NAME(m_portC_internal));
- save_item(NAME(m_portC_out));
- save_item(NAME(m_ddrC));
- save_item(NAME(m_tdr));
- save_item(NAME(m_tcr));
+ save_item(NAME(m_old_portC_out));
+
+
}
void arkanoid_state::machine_reset()
@@ -1313,17 +1294,12 @@ void arkanoid_state::machine_reset()
// the following 3 are all part of the 74ls74 at ic26 and are cleared on reset
m_Z80HasWritten = 0;
m_MCUHasWritten = 0;
- if (m_mcu.found()) m_mcu->set_input_line(M68705_IRQ_LINE, CLEAR_LINE);
- if (m_mcu.found()) m_68705_timer->adjust(attotime::from_hz(((XTAL_12MHz/4)/4)/(1<<7)));
m_portA_in = 0;
m_portA_out = 0;
- m_ddrA = 0;
- m_portC_internal = 0;
- m_portC_out = 0;
- m_ddrC = 0;
- m_tdr = 0xFF;
- m_tcr = 0x7F;
+ m_old_portC_out = 0;
+
+ if (m_mcu.found()) m_mcu->set_input_line(M68705_IRQ_LINE, CLEAR_LINE);
}
/*
@@ -1346,8 +1322,13 @@ static MACHINE_CONFIG_START( arkanoid, arkanoid_state )
MCFG_WATCHDOG_ADD("watchdog")
- MCFG_CPU_ADD("mcu", M68705, XTAL_12MHz/4) /* verified on pcb */
- MCFG_CPU_PROGRAM_MAP(mcu_map)
+ MCFG_CPU_ADD("mcu", M68705_NEW, XTAL_12MHz/4) /* verified on pcb */
+ MCFG_M68705_PORTA_R_CB(READ8(arkanoid_state, mcu_porta_r))
+ MCFG_M68705_PORTA_W_CB(WRITE8(arkanoid_state, mcu_porta_w))
+ MCFG_M68705_PORTB_R_CB(READ8(arkanoid_state, mcu_portb_r))
+ MCFG_M68705_PORTC_R_CB(READ8(arkanoid_state, mcu_portc_r))
+ MCFG_M68705_PORTC_W_CB(WRITE8(arkanoid_state, mcu_portc_w))
+
MCFG_QUANTUM_TIME(attotime::from_hz(6000)) // 100 CPU slices per second to synchronize between the MCU and the main CPU
@@ -1463,7 +1444,7 @@ MACHINE_CONFIG_END
/* ROMs */
/* rom numbering, with guesses for version numbers and missing roms:
- A75 01 = Z80 code 1/2 v1.0 Japan (NOT DUMPED)
+ A75 01 = Z80 code 1/2 v1.0 Japan (NOT DUMPED, arkatayt and arkangc and maybe arkanoidjbl may actually be bootlegs of this undumped version, so it might be possible to 'restore' this version by 'de-bootlegging' those sets?)
A75 01-1 = Z80 code 1/2 v1.1 Japan and USA/Romstar and World
A75 02 = Z80 code 2/2 v1.0 Japan (has 'Notice: This game is for use in Japan only' screen)
A75 03 = GFX 1/3
@@ -2158,6 +2139,7 @@ DRIVER_INIT_MEMBER(arkanoid_state,brixian)
/* Game Drivers */
// original sets of Arkanoid
+// YEAR, NAME, PARENT, MACHINE, INPUT, STATE, INIT, MONITOR,COMPANY,FULLNAME,FLAGS
GAME( 1986, arkanoid, 0, arkanoid, arkanoid, driver_device, 0, ROT90, "Taito Corporation Japan", "Arkanoid (World, older)", MACHINE_SUPPORTS_SAVE )
GAME( 1986, arkanoidu, arkanoid, arkanoid, arkanoid, driver_device, 0, ROT90, "Taito America Corporation (Romstar license)", "Arkanoid (US, newer)", MACHINE_SUPPORTS_SAVE )
GAME( 1986, arkanoiduo, arkanoid, arkanoid, arkanoid, driver_device, 0, ROT90, "Taito America Corporation (Romstar license)", "Arkanoid (US, older)", MACHINE_SUPPORTS_SAVE )
diff --git a/src/mame/drivers/armedf.cpp b/src/mame/drivers/armedf.cpp
index bcde88bf37b..d33b0a3b4c2 100644
--- a/src/mame/drivers/armedf.cpp
+++ b/src/mame/drivers/armedf.cpp
@@ -1568,7 +1568,7 @@ static MACHINE_CONFIG_START( bigfghtr, bigfghtr_state )
MCFG_CPU_IO_MAP(sound_portmap)
MCFG_CPU_PERIODIC_INT_DRIVER(armedf_state, irq0_line_hold, XTAL_8MHz/2/512) // ?
- MCFG_CPU_ADD("mcu", I8751, XTAL_16MHz/4) // i8741 disguised as i8751h? Former doesn't match address map, clock unknown.
+ MCFG_CPU_ADD("mcu", I8751, XTAL_16MHz/4)
MCFG_CPU_PROGRAM_MAP(bigfghtr_mcu_map)
MCFG_CPU_IO_MAP(bigfghtr_mcu_io_map)
diff --git a/src/mame/drivers/ashnojoe.cpp b/src/mame/drivers/ashnojoe.cpp
index 74328538f48..3bab957d1fc 100644
--- a/src/mame/drivers/ashnojoe.cpp
+++ b/src/mame/drivers/ashnojoe.cpp
@@ -87,15 +87,6 @@ READ16_MEMBER(ashnojoe_state::fake_4a00a_r)
return 0;
}
-WRITE16_MEMBER(ashnojoe_state::ashnojoe_soundlatch_w)
-{
- if (ACCESSING_BITS_0_7)
- {
- m_soundlatch_status = 1;
- m_soundlatch->write(space, 0, data & 0xff);
- }
-}
-
static ADDRESS_MAP_START( ashnojoe_map, AS_PROGRAM, 16, ashnojoe_state )
AM_RANGE(0x000000, 0x01ffff) AM_ROM
AM_RANGE(0x040000, 0x041fff) AM_RAM_WRITE(ashnojoe_tileram3_w) AM_SHARE("tileram_3")
@@ -110,7 +101,7 @@ static ADDRESS_MAP_START( ashnojoe_map, AS_PROGRAM, 16, ashnojoe_state )
AM_RANGE(0x04a002, 0x04a003) AM_READ_PORT("P2")
AM_RANGE(0x04a004, 0x04a005) AM_READ_PORT("DSW")
AM_RANGE(0x04a006, 0x04a007) AM_WRITEONLY AM_SHARE("tilemap_reg")
- AM_RANGE(0x04a008, 0x04a009) AM_WRITE(ashnojoe_soundlatch_w)
+ AM_RANGE(0x04a008, 0x04a009) AM_DEVWRITE8("soundlatch", generic_latch_8_device, write, 0x00ff)
AM_RANGE(0x04a00a, 0x04a00b) AM_READ(fake_4a00a_r) // ??
AM_RANGE(0x04a010, 0x04a019) AM_WRITE(joe_tilemaps_xscroll_w)
AM_RANGE(0x04a020, 0x04a029) AM_WRITE(joe_tilemaps_yscroll_w)
@@ -124,15 +115,9 @@ WRITE8_MEMBER(ashnojoe_state::adpcm_w)
m_adpcm_byte = data;
}
-READ8_MEMBER(ashnojoe_state::sound_latch_r)
-{
- m_soundlatch_status = 0;
- return m_soundlatch->read(space, 0);
-}
-
READ8_MEMBER(ashnojoe_state::sound_latch_status_r)
{
- return m_soundlatch_status;
+ return m_soundlatch->pending_r();
}
static ADDRESS_MAP_START( sound_map, AS_PROGRAM, 8, ashnojoe_state )
@@ -145,7 +130,7 @@ static ADDRESS_MAP_START( sound_portmap, AS_IO, 8, ashnojoe_state )
ADDRESS_MAP_GLOBAL_MASK(0xff)
AM_RANGE(0x00, 0x01) AM_DEVREADWRITE("ymsnd", ym2203_device, read, write)
AM_RANGE(0x02, 0x02) AM_WRITE(adpcm_w)
- AM_RANGE(0x04, 0x04) AM_READ(sound_latch_r)
+ AM_RANGE(0x04, 0x04) AM_DEVREAD("soundlatch", generic_latch_8_device, read)
AM_RANGE(0x06, 0x06) AM_READ(sound_latch_status_r)
ADDRESS_MAP_END
@@ -302,14 +287,12 @@ WRITE_LINE_MEMBER(ashnojoe_state::ashnojoe_vclk_cb)
void ashnojoe_state::machine_start()
{
save_item(NAME(m_adpcm_byte));
- save_item(NAME(m_soundlatch_status));
save_item(NAME(m_msm5205_vclk_toggle));
}
void ashnojoe_state::machine_reset()
{
m_adpcm_byte = 0;
- m_soundlatch_status = 0;
m_msm5205_vclk_toggle = 0;
}
diff --git a/src/mame/drivers/asuka.cpp b/src/mame/drivers/asuka.cpp
index 2c1b34d6724..77144702d7a 100644
--- a/src/mame/drivers/asuka.cpp
+++ b/src/mame/drivers/asuka.cpp
@@ -271,16 +271,16 @@ WRITE8_MEMBER(asuka_state::sound_bankswitch_2151_w)
WRITE_LINE_MEMBER(asuka_state::asuka_msm5205_vck)
{
- if (m_adpcm_data != -1)
- {
- m_msm->data_w(m_adpcm_data & 0x0f);
- m_adpcm_data = -1;
- }
- else
+ if (!state)
+ return;
+
+ m_adpcm_ff = !m_adpcm_ff;
+ m_adpcm_select->select_w(m_adpcm_ff);
+
+ if (m_adpcm_ff)
{
- m_adpcm_data = memregion("ymsnd")->base()[m_adpcm_pos];
+ m_adpcm_select->ba_w(m_sound_data[m_adpcm_pos]);
m_adpcm_pos = (m_adpcm_pos + 1) & 0xffff;
- m_msm->data_w(m_adpcm_data >> 4);
}
}
@@ -292,6 +292,7 @@ WRITE8_MEMBER(asuka_state::asuka_msm5205_address_w)
WRITE8_MEMBER(asuka_state::asuka_msm5205_start_w)
{
m_msm->reset_w(0);
+ m_adpcm_ff = false;
}
WRITE8_MEMBER(asuka_state::asuka_msm5205_stop_w)
@@ -778,7 +779,7 @@ void asuka_state::machine_start()
membank("audiobank")->configure_entries(0, 4, memregion("audiocpu")->base(), 0x04000);
save_item(NAME(m_adpcm_pos));
- save_item(NAME(m_adpcm_data));
+ save_item(NAME(m_adpcm_ff));
save_item(NAME(m_current_round));
save_item(NAME(m_current_bank));
@@ -792,7 +793,7 @@ void asuka_state::machine_start()
void asuka_state::machine_reset()
{
m_adpcm_pos = 0;
- m_adpcm_data = -1;
+ m_adpcm_ff = false;
m_current_round = 0;
m_current_bank = 0;
m_video_ctrl = 0;
@@ -930,6 +931,9 @@ static MACHINE_CONFIG_START( asuka, asuka_state )
MCFG_MSM5205_PRESCALER_SELECTOR(MSM5205_S48_4B) /* 8 kHz */
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0)
+ MCFG_DEVICE_ADD("adpcm_select", LS157, 0)
+ MCFG_74157_OUT_CB(DEVWRITE8("msm", msm5205_device, data_w))
+
MCFG_DEVICE_ADD("tc0140syt", TC0140SYT, 0)
MCFG_TC0140SYT_MASTER_CPU("maincpu")
MCFG_TC0140SYT_SLAVE_CPU("audiocpu")
@@ -1064,6 +1068,9 @@ static MACHINE_CONFIG_START( mofflott, asuka_state )
MCFG_MSM5205_PRESCALER_SELECTOR(MSM5205_S48_4B) /* 8 kHz */
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0)
+ MCFG_DEVICE_ADD("adpcm_select", LS157, 0)
+ MCFG_74157_OUT_CB(DEVWRITE8("msm", msm5205_device, data_w))
+
MCFG_DEVICE_ADD("tc0140syt", TC0140SYT, 0)
MCFG_TC0140SYT_MASTER_CPU("maincpu")
MCFG_TC0140SYT_SLAVE_CPU("audiocpu")
diff --git a/src/mame/drivers/attache.cpp b/src/mame/drivers/attache.cpp
index deb7495b6af..8172815e861 100644
--- a/src/mame/drivers/attache.cpp
+++ b/src/mame/drivers/attache.cpp
@@ -222,7 +222,7 @@ private:
// bit 7 = subscript (superscript and subscript combined produces strikethrough)
uint32_t attache_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
- uint8_t x,y,bit,scan,data;
+ uint8_t x,y,vy,start,bit,scan,data;
uint8_t dbl_mode = 0; // detemines which half of character to display when using double size attribute,
// as it can start on either odd or even character cells.
@@ -261,16 +261,20 @@ uint32_t attache_state::screen_update(screen_device &screen, bitmap_rgb32 &bitma
}
else
bitmap.fill(0);
-
+
// Text output
for(y=0;y<(bitmap.height()-1)/10;y++) // lines
{
+ start = m_crtc->upscroll_offset();
+ vy = (start + y) % 24;
+
for(x=0;x<(bitmap.width()-1)/8;x++) // columns
{
assert(((y*128)+x) >= 0 && ((y*128)+x) < ARRAY_LENGTH(m_char_ram));
- uint8_t ch = m_char_ram[(y*128)+x];
- pen_t fg = m_palette->pen(m_attr_ram[(y*128)+x] & 0x08 ? 2 : 1); // brightness
- if(m_attr_ram[(y*128)+x] & 0x10) // double-size
+ assert(((vy*128)+x) >= 0 && ((vy*128)+x) < ARRAY_LENGTH(m_char_ram));
+ uint8_t ch = m_char_ram[(vy*128)+x];
+ pen_t fg = m_palette->pen(m_attr_ram[(vy*128)+x] & 0x08 ? 2 : 1); // brightness
+ if(m_attr_ram[(vy*128)+x] & 0x10) // double-size
dbl_mode++;
else
dbl_mode = 0;
@@ -278,16 +282,16 @@ uint32_t attache_state::screen_update(screen_device &screen, bitmap_rgb32 &bitma
for(scan=0;scan<10;scan++) // 10 scanlines per line
{
data = m_char_rom->base()[ch*16+scan];
- if((m_attr_ram[(y*128)+x] & 0xc0) != 0xc0) // if not strikethrough
+ if((m_attr_ram[(vy*128)+x] & 0xc0) != 0xc0) // if not strikethrough
{
- if(m_attr_ram[(y*128)+x] & 0x40) // superscript
+ if(m_attr_ram[(vy*128)+x] & 0x40) // superscript
{
if(scan >= 5)
data = 0;
else
data = m_char_rom->base()[ch*16+(scan*2)+1];
}
- if(m_attr_ram[(y*128)+x] & 0x80) // subscript
+ if(m_attr_ram[(vy*128)+x] & 0x80) // subscript
{
if(scan < 5)
data = 0;
@@ -295,13 +299,13 @@ uint32_t attache_state::screen_update(screen_device &screen, bitmap_rgb32 &bitma
data = m_char_rom->base()[ch*16+((scan-5)*2)+1];
}
}
- if((m_attr_ram[(y*128)+x] & 0x20) && scan == 9) // underline
+ if((m_attr_ram[(vy*128)+x] & 0x20) && scan == 9) // underline
data = 0xff;
- if((m_attr_ram[(y*128)+x] & 0xc0) == 0xc0 && scan == 3) // strikethrough
+ if((m_attr_ram[(vy*128)+x] & 0xc0) == 0xc0 && scan == 3) // strikethrough
data = 0xff;
- if(m_attr_ram[(y*128)+x] & 0x04) // reverse
+ if(m_attr_ram[(vy*128)+x] & 0x04) // reverse
data = ~data;
- if(m_attr_ram[(y*128)+x] & 0x10) // double-size
+ if(m_attr_ram[(vy*128)+x] & 0x10) // double-size
{
uint8_t newdata = 0;
if(dbl_mode & 1)
@@ -630,6 +634,7 @@ WRITE8_MEMBER(attache_state::display_data_w)
break;
case DISP_CRTC:
m_crtc->write(space, m_crtc_reg_select, data);
+ //logerror("CRTC: write reg %02x, data %02x\n",m_crtc_reg_select,data);
break;
case DISP_ATTR:
m_attr_ram[(m_attr_line*128)+(param & 0x7f)] = data;
@@ -754,7 +759,7 @@ static ADDRESS_MAP_START( attache_io , AS_IO, 8, attache_state)
AM_RANGE(0xe0, 0xed) AM_DEVREADWRITE("dma",am9517a_device,read,write) AM_MIRROR(0xff00)
AM_RANGE(0xee, 0xee) AM_WRITE(display_command_w) AM_MIRROR(0xff00)
AM_RANGE(0xef, 0xef) AM_READWRITE(dma_mask_r, dma_mask_w) AM_MIRROR(0xff00)
- AM_RANGE(0xf0, 0xf3) AM_DEVREADWRITE("sio",z80sio0_device,ba_cd_r, ba_cd_w) AM_MIRROR(0xff00)
+ AM_RANGE(0xe6, 0xe7) AM_DEVREADWRITE("sio",z80sio0_device,ba_cd_r, ba_cd_w) AM_MIRROR(0xff00)
AM_RANGE(0xf4, 0xf7) AM_DEVREADWRITE("ctc",z80ctc_device,read,write) AM_MIRROR(0xff00)
AM_RANGE(0xf8, 0xfb) AM_DEVREADWRITE("pio",z80pio_device,read_alt,write_alt) AM_MIRROR(0xff00)
AM_RANGE(0xfc, 0xfd) AM_DEVICE("fdc",upd765a_device,map) AM_MIRROR(0xff00)
@@ -993,4 +998,4 @@ ROM_START( attache )
ROM_END
/* YEAR NAME PARENT COMPAT MACHINE INPUT DEVICE INIT COMPANY FULLNAME FLAGS */
-COMP( 1982, attache, 0, 0, attache, attache, driver_device, 0, "Otrona", "Attach\xC3\xA9", MACHINE_IMPERFECT_GRAPHICS|MACHINE_NOT_WORKING)
+COMP( 1982, attache, 0, 0, attache, attache, driver_device, 0, "Otrona", "Attach\xC3\xA9", MACHINE_IMPERFECT_GRAPHICS)
diff --git a/src/mame/drivers/atvtrack.cpp b/src/mame/drivers/atvtrack.cpp
index 398200c7fff..e7b08f6e31c 100644
--- a/src/mame/drivers/atvtrack.cpp
+++ b/src/mame/drivers/atvtrack.cpp
@@ -384,30 +384,54 @@ uint32_t atvtrack_state::screen_update_atvtrack(screen_device &screen, bitmap_rg
return 0;
}
-void atvtrack_state::machine_start()
+void get_altera10ke_eab(u8* dst, u8 *pof, int eab)
{
- uint8_t *src, *dst;
+ // extract Altera FLEX 10KE 4kbit Embedded Array Block (EAB)
+ u32 startbit = 0x45b * 8 + 1 + (0x25e6 * 8) * eab; // base ofsset actually depends on POF header size, however this EPC1PC8 dump havent it (bad dumper software?)
+
+ for (u32 bit = 0; bit < 4096; bit++)
+ {
+ u32 tbit = BITSWAP16(bit, 15, 14, 13, 12,
+ 9, 8, 7, 6, 5, 4, 3,
+ 11, 10,
+ 2, 1, 0);
+ tbit ^= 0x0fc0;
+ u32 pofbit = startbit + (tbit & 0x1f) + (((tbit >> 5) & 1) * 63) + (((tbit >> 6) & 0x3f) * 0x4D * 8);
+ dst[bit / 8] &= ~(1 << (bit & 7));
+ dst[bit / 8] |= ((pof[pofbit / 8] >> (pofbit & 7)) & 1) << (bit & 7);
+ }
+}
+void atvtrack_state::machine_start()
+{
m_nandaddressstep = 0;
m_nandregion = memregion("maincpu");
- address_space &as = m_maincpu->space(AS_PROGRAM);
- dst = (uint8_t *)(as.get_write_ptr(0x0c7f0000));
- src = m_nandregion->base()+0x10;
- // copy 0x10000 bytes from region "maincpu" offset 0x10 to 0x0c7f0000
- memcpy(dst, src, 0x10000);
}
void atvtrack_state::machine_reset()
{
- // Probably just after reset the cpu executes some bootsrtap routine from a memory inside the fpga.
- // The routine initializes the cpu, copies the boot program from the flash memories into the cpu sdram
- // and finally executes it.
- // Here there is the setup of the cpu, the boot program is copied in machine_start
- address_space &as = m_maincpu->space(AS_PROGRAM);
- // set cpu PC register to 0x0c7f0000
- m_maincpu->set_pc(0x0c7f0000);
- // set BCR2 to 1
- m_maincpu->sh4_internal_w(as, 0x3001, 1, 0xffffffff);
+ std::vector<u8> tdata(1024);
+ u8 *pof = memregion("fpga")->base();
+
+ // first 2 Altera's EABs is 2xSH4s shared RAM, its initial content is boot loader
+ // extract EABs 0 and 1 from POF
+ get_altera10ke_eab(&tdata[0], pof, 0);
+ get_altera10ke_eab(&tdata[512], pof, 1);
+
+ // deshuffle data bits and put it to shared RAM
+ u8 *dst = (u8*)(m_maincpu->space(AS_PROGRAM).get_write_ptr(0));
+ for (u32 i = 0; i < 256; i++)
+ {
+ u16 lword = tdata[i * 2 + 512] | (tdata[i * 2 + 513] << 8);
+ u16 hword = tdata[i * 2] | (tdata[i * 2 + 1] << 8);
+ lword = BITSWAP16(lword, 7, 9, 0, 10, 3, 11, 4, 12, 2, 15, 1, 13, 6, 8, 5, 14);
+ hword = BITSWAP16(hword, 5, 10, 7, 9, 6, 13, 3, 15, 2, 11, 1, 8, 0, 12, 4, 14);
+ dst[i * 4 + 0] = lword & 0xff;
+ dst[i * 4 + 1] = lword >> 8;
+ dst[i * 4 + 2] = hword & 0xff;
+ dst[i * 4 + 3] = hword >> 8;
+ }
+
m_subcpu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE);
}
@@ -533,8 +557,8 @@ ROM_START( atvtrack )
ROM_LOAD32_BYTE("14.bin", 0x0000002, 0x1080000, CRC(67983453) SHA1(05389a0ffc1a1bae9bac16a53a97d78b6eccc626) )
ROM_LOAD32_BYTE("19.bin", 0x0000003, 0x1080000, CRC(9fc5c579) SHA1(8829329ef229564952aea2108ef1750dc226cbac) )
- ROM_REGION( 0x20000, "eeprom", ROMREGION_ERASEFF)
- ROM_LOAD("epc1pc8.ic23", 0x0000000, 0x1ff01, CRC(752444c7) SHA1(c77e8fcfcbe15b53eda25553763bdac45f0ef7df) ) // contains configuration data for the fpga, maybe used for some form of protection
+ ROM_REGION( 0x20000, "fpga", ROMREGION_ERASEFF)
+ ROM_LOAD("epc1pc8.ic23", 0x0000000, 0x1ff01, CRC(752444c7) SHA1(c77e8fcfcbe15b53eda25553763bdac45f0ef7df) ) // contains configuration data for the fpga
ROM_END
ROM_START( atvtracka )
@@ -543,6 +567,9 @@ ROM_START( atvtracka )
ROM_LOAD32_BYTE("k9f2808u0b.ic20", 0x0000001, 0x1080000, CRC(b0c34433) SHA1(852c79bb3d7082cd2c056140071ae7d71679ec1d) )
ROM_LOAD32_BYTE("k9f2808u0b.ic14", 0x0000002, 0x1080000, CRC(02a12085) SHA1(acb112c9c7b29d92610465fb92268ce787ca06f4) )
ROM_LOAD32_BYTE("k9f2808u0b.ic19", 0x0000003, 0x1080000, CRC(856c1e6a) SHA1(a6b2839120d61811c36cc6b4095de9cefceb394b) )
+
+ ROM_REGION( 0x20000, "fpga", ROMREGION_ERASEFF)
+ ROM_LOAD("epc1pc8.ic23", 0x0000000, 0x1ff01, CRC(752444c7) SHA1(c77e8fcfcbe15b53eda25553763bdac45f0ef7df) ) // contains configuration data for the fpga
ROM_END
/*
diff --git a/src/mame/drivers/bigevglf.cpp b/src/mame/drivers/bigevglf.cpp
index e93c9ac3ca4..6309831483b 100644
--- a/src/mame/drivers/bigevglf.cpp
+++ b/src/mame/drivers/bigevglf.cpp
@@ -346,8 +346,8 @@ static ADDRESS_MAP_START( bigevglf_sub_portmap, AS_IO, 8, bigevglf_state )
AM_RANGE(0x06, 0x06) AM_READ_PORT("DSW2")
AM_RANGE(0x07, 0x07) AM_READNOP
AM_RANGE(0x08, 0x08) AM_WRITE(beg_port08_w) /* muxed port select + other unknown stuff */
- AM_RANGE(0x0b, 0x0b) AM_READ(bigevglf_mcu_r)
- AM_RANGE(0x0c, 0x0c) AM_WRITE(bigevglf_mcu_w)
+ AM_RANGE(0x0b, 0x0b) AM_DEVREAD("bmcu", taito68705_mcu_device, mcu_r)
+ AM_RANGE(0x0c, 0x0c) AM_DEVWRITE("bmcu", taito68705_mcu_device, mcu_w)
AM_RANGE(0x0e, 0x0e) AM_WRITENOP /* 0-enable MCU, 1-keep reset line ASSERTED; D0 goes to the input of ls74 and the /Q of this ls74 goes to reset line on 68705 */
AM_RANGE(0x10, 0x17) AM_WRITE(beg13_a_clr_w)
AM_RANGE(0x18, 0x1f) AM_WRITE(beg13_b_set_w)
@@ -376,20 +376,6 @@ static ADDRESS_MAP_START( sound_map, AS_PROGRAM, 8, bigevglf_state )
ADDRESS_MAP_END
-/*********************************************************************************/
-/* MCU */
-
-static ADDRESS_MAP_START( m68705_map, AS_PROGRAM, 8, bigevglf_state )
- ADDRESS_MAP_GLOBAL_MASK(0x7ff)
- AM_RANGE(0x0000, 0x0000) AM_READWRITE(bigevglf_68705_port_a_r, bigevglf_68705_port_a_w)
- AM_RANGE(0x0001, 0x0001) AM_READWRITE(bigevglf_68705_port_b_r, bigevglf_68705_port_b_w)
- AM_RANGE(0x0002, 0x0002) AM_READWRITE(bigevglf_68705_port_c_r, bigevglf_68705_port_c_w)
- AM_RANGE(0x0004, 0x0004) AM_WRITE(bigevglf_68705_ddr_a_w)
- AM_RANGE(0x0005, 0x0005) AM_WRITE(bigevglf_68705_ddr_b_w)
- AM_RANGE(0x0006, 0x0006) AM_WRITE(bigevglf_68705_ddr_c_w)
- AM_RANGE(0x0010, 0x007f) AM_RAM
- AM_RANGE(0x0080, 0x07ff) AM_ROM
-ADDRESS_MAP_END
static const gfx_layout gfxlayout =
@@ -424,20 +410,10 @@ void bigevglf_state::machine_start()
save_item(NAME(m_from_sound));
save_item(NAME(m_sound_state));
- save_item(NAME(m_main_sent));
- save_item(NAME(m_mcu_sent));
+
save_item(NAME(m_mcu_coin_bit5));
- save_item(NAME(m_port_a_in));
- save_item(NAME(m_port_a_out));
- save_item(NAME(m_ddr_a));
- save_item(NAME(m_port_b_in));
- save_item(NAME(m_port_b_out));
- save_item(NAME(m_ddr_b));
- save_item(NAME(m_port_c_in));
- save_item(NAME(m_port_c_out));
- save_item(NAME(m_ddr_c));
- save_item(NAME(m_from_mcu));
+
}
void bigevglf_state::machine_reset()
@@ -457,20 +433,7 @@ void bigevglf_state::machine_reset()
m_from_sound = 0;
m_sound_state = 0;
- m_main_sent = 0;
- m_mcu_sent = 0;
m_mcu_coin_bit5 = 0;
-
- m_port_a_in = 0;
- m_port_a_out = 0;
- m_ddr_a = 0;
- m_port_b_in = 0;
- m_port_b_out = 0;
- m_ddr_b = 0;
- m_port_c_in = 0;
- m_port_c_out = 0;
- m_ddr_c = 0;
- m_from_mcu = 0;
}
@@ -493,8 +456,7 @@ static MACHINE_CONFIG_START( bigevglf, bigevglf_state )
2 irqs/frame give good music tempo but also SOUND ERROR in test mode,
4 irqs/frame give SOUND OK in test mode but music seems to be running too fast */
- MCFG_CPU_ADD("mcu", M68705,2000000) /* ??? */
- MCFG_CPU_PROGRAM_MAP(m68705_map)
+ MCFG_DEVICE_ADD("bmcu", TAITO68705_MCU_BEG, 2000000) /* ??? */
MCFG_QUANTUM_TIME(attotime::from_hz(600)) /* 10 CPU slices per frame - interleaving is forced on the fly */
@@ -559,7 +521,7 @@ ROM_START( bigevglf )
ROM_LOAD( "a67-17", 0x4000, 0x4000, CRC(9f57deae) SHA1(dbdb3d77c3de0113ef6671aec854e4e44ee162ef))
ROM_LOAD( "a67-18", 0x8000, 0x4000, CRC(40d54fed) SHA1(bfa0922809bffafec15d3ef59ac8b8ad653860a1))
- ROM_REGION( 0x0800, "mcu", 0 )
+ ROM_REGION( 0x0800, "bmcu:mcu", 0 )
ROM_LOAD( "a67_19-1", 0x0000, 0x0800, CRC(25691658) SHA1(aabf47abac43abe2ffed18ead1cb94e587149e6e))
ROM_REGION( 0x20000, "gfx1", 0 )
@@ -590,7 +552,7 @@ ROM_START( bigevglfj )
ROM_LOAD( "a67-17", 0x4000, 0x4000, CRC(9f57deae) SHA1(dbdb3d77c3de0113ef6671aec854e4e44ee162ef))
ROM_LOAD( "a67-18", 0x8000, 0x4000, CRC(40d54fed) SHA1(bfa0922809bffafec15d3ef59ac8b8ad653860a1))
- ROM_REGION( 0x0800, "mcu", 0 )
+ ROM_REGION( 0x0800, "bmcu:mcu", 0 )
ROM_LOAD( "a67_19-1", 0x0000, 0x0800, CRC(25691658) SHA1(aabf47abac43abe2ffed18ead1cb94e587149e6e))
ROM_REGION( 0x20000, "gfx1", 0 )
diff --git a/src/mame/drivers/bking.cpp b/src/mame/drivers/bking.cpp
index 44b0adfa450..b4305d2351f 100644
--- a/src/mame/drivers/bking.cpp
+++ b/src/mame/drivers/bking.cpp
@@ -120,8 +120,8 @@ static ADDRESS_MAP_START( bking3_io_map, AS_IO, 8, bking_state )
// AM_RANGE(0x0c, 0x0c) AM_WRITE(bking_eport2_w) this is not shown to be connected anywhere
AM_RANGE(0x0d, 0x0d) AM_WRITE(bking_hitclr_w)
AM_RANGE(0x07, 0x1f) AM_READ(bking_pos_r)
- AM_RANGE(0x2f, 0x2f) AM_DEVREADWRITE("bmcu", buggychl_mcu_device, buggychl_mcu_r, buggychl_mcu_w)
- AM_RANGE(0x4f, 0x4f) AM_DEVREAD("bmcu", buggychl_mcu_device, buggychl_mcu_status_r) AM_WRITE(unk_w)
+ AM_RANGE(0x2f, 0x2f) AM_DEVREADWRITE("bmcu", taito68705_mcu_device, mcu_r, mcu_w)
+ AM_RANGE(0x4f, 0x4f) AM_DEVREAD("bmcu", taito68705_mcu_device, mcu_status_r) AM_WRITE(unk_w)
AM_RANGE(0x60, 0x60) AM_READ(bking3_extrarom_r)
AM_RANGE(0x6f, 0x6f) AM_READWRITE(bking3_ext_check_r, bking3_addr_h_w)
AM_RANGE(0x8f, 0x8f) AM_WRITE(bking3_addr_l_w)
@@ -140,68 +140,6 @@ static ADDRESS_MAP_START( bking_audio_map, AS_PROGRAM, 8, bking_state )
AM_RANGE(0xe000, 0xefff) AM_ROM /* Space for diagnostic ROM */
ADDRESS_MAP_END
-#if 0
-READ8_MEMBER(bking_state::bking3_68705_port_a_r)
-{
- //printf("port_a_r = %02X\n",(m_port_a_out & m_ddr_a) | (m_port_a_in & ~m_ddr_a));
- return (m_port_a_out & m_ddr_a) | (m_port_a_in & ~m_ddr_a);
-}
-
-WRITE8_MEMBER(bking_state::bking3_68705_port_a_w)
-{
- m_port_a_out = data;
-// printf("port_a_out = %02X\n",data);
-}
-
-WRITE8_MEMBER(bking_state::bking3_68705_ddr_a_w)
-{
- m_ddr_a = data;
-}
-
-READ8_MEMBER(bking_state::bking3_68705_port_b_r)
-{
- return (m_port_b_out & m_ddr_b) | (m_port_b_in & ~m_ddr_b);
-}
-
-WRITE8_MEMBER(bking_state::bking3_68705_port_b_w)
-{
-// if(data != 0xff)
-// printf("port_b_out = %02X\n",data);
-
- if (~data & 0x02)
- {
- m_port_a_in = from_main;
- if (main_sent) m_mcu->set_input_line(0, CLEAR_LINE);
- main_sent = 0;
- }
-
- if (~data & 0x04)
- {
- /* 68705 is writing data for the Z80 */
- from_mcu = m_port_a_out;
- mcu_sent = 1;
- }
-
- if(data != 0xff && data != 0xfb && data != 0xfd)
- printf("port_b_w = %X\n",data);
-
- m_port_b_out = data;
-}
-
-WRITE8_MEMBER(bking_state::bking3_68705_ddr_b_w)
-{
- m_ddr_b = data;
-}
-
-READ8_MEMBER(bking_state::bking3_68705_port_c_r)
-{
- int port_c_in = 0;
- if (main_sent) port_c_in |= 0x01;
- if (!mcu_sent) port_c_in |= 0x02;
-//logerror("%04x: 68705 port C read %02x\n",space.device().safe_pc(),port_c_in);
- return port_c_in;
-}
-#endif
static INPUT_PORTS_START( bking )
PORT_START("IN0")
@@ -440,8 +378,6 @@ void bking_state::machine_reset()
MACHINE_RESET_MEMBER(bking_state,bking3)
{
- m_mcu->set_input_line(0, CLEAR_LINE);
-
bking_state::machine_reset();
/* misc */
@@ -505,9 +441,7 @@ static MACHINE_CONFIG_DERIVED( bking3, bking )
MCFG_CPU_MODIFY("main_cpu")
MCFG_CPU_IO_MAP(bking3_io_map)
- MCFG_CPU_ADD("mcu", M68705, XTAL_3MHz) /* xtal is 3MHz, divided by 4 internally */
- MCFG_CPU_PROGRAM_MAP(buggychl_mcu_map)
- MCFG_DEVICE_ADD("bmcu", BUGGYCHL_MCU, 0)
+ MCFG_DEVICE_ADD("bmcu", TAITO68705_MCU, XTAL_3MHz) /* xtal is 3MHz, divided by 4 internally */
MCFG_MACHINE_START_OVERRIDE(bking_state,bking3)
MCFG_MACHINE_RESET_OVERRIDE(bking_state,bking3)
@@ -774,7 +708,7 @@ ROM_START( bking3 )
ROM_LOAD( "a24-19.4d", 0x1000, 0x1000, CRC(817f9c2a) SHA1(7365ecf2700e1fd13016408f5493f8d51aab5bbd) )
ROM_LOAD( "a24-20.4b", 0x2000, 0x1000, CRC(0e9e16d6) SHA1(43c69602a8d9c34c527ce54472db84168acc4ef4) )
- ROM_REGION( 0x0800, "mcu", 0 ) /* 2k for the microcontroller */
+ ROM_REGION( 0x0800, "bmcu:mcu", 0 ) /* 2k for the microcontroller */
ROM_LOAD( "a24_22.ic17", 0x000000, 0x000800, CRC(27c497d5) SHA1(c6c72bbf0537da53148fa0a56d412ab46129d29c) ) //M68705P5S uC 3MHz xtal
ROM_REGION( 0x6000, "gfx1", 0 ) /* Tiles */
diff --git a/src/mame/drivers/bublbobl.cpp b/src/mame/drivers/bublbobl.cpp
index 434cc015df9..63ea6bf6330 100644
--- a/src/mame/drivers/bublbobl.cpp
+++ b/src/mame/drivers/bublbobl.cpp
@@ -389,9 +389,19 @@ static ADDRESS_MAP_START( tokio_map, AS_PROGRAM, 8, bublbobl_state )
AM_RANGE(0xfb00, 0xfb00) AM_WRITE(tokio_videoctrl_w)
AM_RANGE(0xfb80, 0xfb80) AM_WRITE(bublbobl_nmitrigger_w)
AM_RANGE(0xfc00, 0xfc00) AM_READWRITE(bublbobl_sound_status_r, bublbobl_sound_command_w)
- AM_RANGE(0xfe00, 0xfe00) AM_READWRITE(tokio_mcu_r, tokio_mcu_w)
ADDRESS_MAP_END
+static ADDRESS_MAP_START( tokio_map_mcu, AS_PROGRAM, 8, bublbobl_state )
+ AM_IMPORT_FROM(tokio_map)
+ AM_RANGE(0xfe00, 0xfe00) AM_DEVREADWRITE("bmcu", taito68705_mcu_device, mcu_r, mcu_w)
+ADDRESS_MAP_END
+
+static ADDRESS_MAP_START( tokio_map_bootleg, AS_PROGRAM, 8, bublbobl_state )
+ AM_IMPORT_FROM(tokio_map)
+ AM_RANGE(0xfe00, 0xfe00) AM_READ( tokiob_mcu_r )
+ADDRESS_MAP_END
+
+
static ADDRESS_MAP_START( tokio_slave_map, AS_PROGRAM, 8, bublbobl_state )
AM_RANGE(0x0000, 0x7fff) AM_ROM
AM_RANGE(0x8000, 0x97ff) AM_RAM AM_SHARE("share1")
@@ -619,7 +629,7 @@ static INPUT_PORTS_START( dland )
PORT_DIPSETTING( 0x20, "100 (Cheat)")
INPUT_PORTS_END
-static INPUT_PORTS_START( tokio )
+static INPUT_PORTS_START( tokio_base )
PORT_START("DSW0")
PORT_DIPNAME( 0x01, 0x00, DEF_STR( Cabinet ) ) PORT_DIPLOCATION("SW A:1")
PORT_DIPSETTING( 0x00, DEF_STR( Upright ) )
@@ -669,8 +679,8 @@ static INPUT_PORTS_START( tokio )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_SERVICE1 )
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_COIN1 ) PORT_IMPULSE(1)
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_COIN2 ) PORT_IMPULSE(1)
- PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, bublbobl_state,tokio_main_sent_r, nullptr)
- PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, bublbobl_state,tokio_mcu_sent_r, nullptr)
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_SPECIAL ) // see INPUT_PORTS_START( tokio )
+ PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_SPECIAL ) // see INPUT_PORTS_START( tokio )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
@@ -695,7 +705,13 @@ static INPUT_PORTS_START( tokio )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
INPUT_PORTS_END
+static INPUT_PORTS_START( tokio )
+ PORT_INCLUDE( tokio_base )
+ PORT_MODIFY("IN0")
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_SPECIAL ) PORT_CUSTOM_MEMBER("bmcu", taito68705_mcu_device, main_sent_r, nullptr)
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_SPECIAL ) PORT_CUSTOM_MEMBER("bmcu", taito68705_mcu_device, mcu_sent_r, nullptr)
+INPUT_PORTS_END
/*************************************
*
@@ -744,15 +760,6 @@ MACHINE_RESET_MEMBER(bublbobl_state,common)
MACHINE_START_MEMBER(bublbobl_state,tokio)
{
MACHINE_START_CALL_MEMBER(common);
-
-
- save_item(NAME(m_mcu_sent));
- save_item(NAME(m_main_sent));
- save_item(NAME(m_from_main));
- save_item(NAME(m_from_mcu));
- save_item(NAME(m_from_mcu_latch));
- save_item(NAME(m_to_mcu_latch));
- save_item(NAME(m_old_portB));
}
@@ -767,7 +774,7 @@ static MACHINE_CONFIG_START( tokio, bublbobl_state )
/* basic machine hardware */
MCFG_CPU_ADD("maincpu", Z80, MAIN_XTAL/4) // 6 MHz
- MCFG_CPU_PROGRAM_MAP(tokio_map)
+ MCFG_CPU_PROGRAM_MAP(tokio_map_mcu)
MCFG_CPU_VBLANK_INT_DRIVER("screen", bublbobl_state, irq0_line_hold)
MCFG_CPU_ADD("slave", Z80, MAIN_XTAL/4) // 6 MHz
@@ -777,12 +784,7 @@ static MACHINE_CONFIG_START( tokio, bublbobl_state )
MCFG_CPU_ADD("audiocpu", Z80, MAIN_XTAL/8) // 3 MHz
MCFG_CPU_PROGRAM_MAP(tokio_sound_map) // NMIs are triggered by the main CPU, IRQs are triggered by the YM2203
- MCFG_CPU_ADD("mcu", M68705_NEW, MAIN_XTAL/8) // 3 Mhz
- MCFG_M68705_PORTA_R_CB(READ8(bublbobl_state, tokio_mcu_porta_r))
- MCFG_M68705_PORTA_W_CB(WRITE8(bublbobl_state, tokio_mcu_porta_w))
- MCFG_M68705_PORTB_W_CB(WRITE8(bublbobl_state, tokio_mcu_portb_w))
- MCFG_M68705_PORTC_R_CB(READ8(bublbobl_state, tokio_mcu_portc_r))
-
+ MCFG_DEVICE_ADD("bmcu", TAITO68705_MCU, MAIN_XTAL/8) // 3 Mhz
MCFG_QUANTUM_PERFECT_CPU("maincpu")
@@ -816,9 +818,16 @@ static MACHINE_CONFIG_START( tokio, bublbobl_state )
MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( tokiob, tokio )
- MCFG_DEVICE_REMOVE("mcu")
+
+ MCFG_DEVICE_REMOVE("maincpu")
+ MCFG_DEVICE_REMOVE("bmcu")
+
+ MCFG_CPU_ADD("maincpu", Z80, MAIN_XTAL/4) // 6 MHz
+ MCFG_CPU_PROGRAM_MAP(tokio_map_bootleg)
+ MCFG_CPU_VBLANK_INT_DRIVER("screen", bublbobl_state, irq0_line_hold)
MACHINE_CONFIG_END
+
MACHINE_START_MEMBER(bublbobl_state,bublbobl)
{
MACHINE_START_CALL_MEMBER(common);
@@ -999,7 +1008,7 @@ ROM_START( tokio ) // newer japan set, has -1 revision of roms 02, 03 and 06
ROM_REGION( 0x10000, "audiocpu", 0 ) /* audio CPU */
ROM_LOAD( "a71-07.ic10", 0x0000, 0x08000, CRC(f298cc7b) SHA1(ebf5c804aa07b7f198ec3e1f8d1e111cd89ebdf3) )
- ROM_REGION( 0x0800, "mcu", 0 ) /* 2k for the microcontroller (68705P5) */
+ ROM_REGION( 0x0800, "bmcu:mcu", 0 ) /* 2k for the microcontroller (68705P5) */
ROM_LOAD( "a71__24.ic57", 0x0000, 0x0800, CRC(0f4b25de) SHA1(e2d82aa8d8cc6a86aaf5715ef9cb62f526fd5b11) )
ROM_REGION( 0x80000, "gfx1", ROMREGION_INVERT ) /* gfx roms, on gfx board */
@@ -1042,7 +1051,7 @@ ROM_START( tokioo ) // older japan set, has older roms 02, 03, 06
ROM_REGION( 0x10000, "audiocpu", 0 ) /* audio CPU */
ROM_LOAD( "a71-07.ic10", 0x0000, 0x08000, CRC(f298cc7b) SHA1(ebf5c804aa07b7f198ec3e1f8d1e111cd89ebdf3) )
- ROM_REGION( 0x0800, "mcu", 0 ) /* 2k for the microcontroller (68705P5) */
+ ROM_REGION( 0x0800, "bmcu:mcu", 0 ) /* 2k for the microcontroller (68705P5) */
ROM_LOAD( "a71__24.ic57", 0x0000, 0x0800, CRC(0f4b25de) SHA1(e2d82aa8d8cc6a86aaf5715ef9cb62f526fd5b11) )
ROM_REGION( 0x80000, "gfx1", ROMREGION_INVERT ) /* gfx roms, on gfx board */
@@ -1085,7 +1094,7 @@ ROM_START( tokiou )
ROM_REGION( 0x10000, "audiocpu", 0 ) /* audio CPU */
ROM_LOAD( "a71-07.ic10", 0x0000, 0x08000, CRC(f298cc7b) SHA1(ebf5c804aa07b7f198ec3e1f8d1e111cd89ebdf3) )
- ROM_REGION( 0x0800, "mcu", 0 ) /* 2k for the microcontroller (68705P5) */
+ ROM_REGION( 0x0800, "bmcu:mcu", 0 ) /* 2k for the microcontroller (68705P5) */
ROM_LOAD( "a71__24.ic57", 0x0000, 0x0800, CRC(0f4b25de) SHA1(e2d82aa8d8cc6a86aaf5715ef9cb62f526fd5b11) )
ROM_REGION( 0x80000, "gfx1", ROMREGION_INVERT ) /* gfx roms, on gfx board */
@@ -1871,12 +1880,7 @@ DRIVER_INIT_MEMBER(bublbobl_state,tokio)
m_video_enable = 1;
}
-DRIVER_INIT_MEMBER(bublbobl_state,tokiob)
-{
- DRIVER_INIT_CALL(tokio);
- m_maincpu->space(AS_PROGRAM).install_read_handler(0xfe00, 0xfe00, read8_delegate(FUNC(bublbobl_state::tokiob_mcu_r),this) );
-}
DRIVER_INIT_MEMBER(bublbobl_state,dland)
{
@@ -1902,7 +1906,7 @@ DRIVER_INIT_MEMBER(bublbobl_state,dland)
GAME( 1986, tokio, 0, tokio, tokio, bublbobl_state, tokio, ROT90, "Taito Corporation", "Tokio / Scramble Formation (newer)", MACHINE_SUPPORTS_SAVE )
GAME( 1986, tokioo, tokio, tokio, tokio, bublbobl_state, tokio, ROT90, "Taito Corporation", "Tokio / Scramble Formation (older)", MACHINE_SUPPORTS_SAVE )
GAME( 1986, tokiou, tokio, tokio, tokio, bublbobl_state, tokio, ROT90, "Taito America Corporation (Romstar license)", "Tokio / Scramble Formation (US)", MACHINE_SUPPORTS_SAVE )
-GAME( 1986, tokiob, tokio, tokiob, tokio, bublbobl_state, tokiob, ROT90, "bootleg", "Tokio / Scramble Formation (bootleg)", MACHINE_SUPPORTS_SAVE )
+GAME( 1986, tokiob, tokio, tokiob, tokio_base, bublbobl_state, tokio, ROT90, "bootleg", "Tokio / Scramble Formation (bootleg)", MACHINE_SUPPORTS_SAVE )
GAME( 1986, bublbobl, 0, bublbobl, bublbobl, bublbobl_state, bublbobl, ROT0, "Taito Corporation", "Bubble Bobble (Japan, Ver 0.1)", MACHINE_SUPPORTS_SAVE )
GAME( 1986, bublbobl1, bublbobl, bublbobl, bublbobl, bublbobl_state, bublbobl, ROT0, "Taito Corporation", "Bubble Bobble (Japan, Ver 0.0)", MACHINE_SUPPORTS_SAVE )
diff --git a/src/mame/drivers/buggychl.cpp b/src/mame/drivers/buggychl.cpp
index 1ee00ce3b4e..9c802071125 100644
--- a/src/mame/drivers/buggychl.cpp
+++ b/src/mame/drivers/buggychl.cpp
@@ -140,8 +140,8 @@ static ADDRESS_MAP_START( buggychl_map, AS_PROGRAM, 8, buggychl_state )
AM_RANGE(0xd200, 0xd200) AM_WRITE(bankswitch_w)
AM_RANGE(0xd300, 0xd300) AM_DEVWRITE("watchdog", watchdog_timer_device, reset_w)
AM_RANGE(0xd303, 0xd303) AM_WRITE(buggychl_sprite_lookup_bank_w)
- AM_RANGE(0xd400, 0xd400) AM_DEVREADWRITE("bmcu", buggychl_mcu_device, buggychl_mcu_r, buggychl_mcu_w)
- AM_RANGE(0xd401, 0xd401) AM_DEVREAD("bmcu", buggychl_mcu_device, buggychl_mcu_status_r)
+ AM_RANGE(0xd400, 0xd400) AM_DEVREADWRITE("bmcu", taito68705_mcu_device, mcu_r, mcu_w)
+ AM_RANGE(0xd401, 0xd401) AM_DEVREAD("bmcu", taito68705_mcu_device, mcu_status_r)
AM_RANGE(0xd500, 0xd57f) AM_WRITEONLY AM_SHARE("spriteram")
AM_RANGE(0xd600, 0xd600) AM_READ_PORT("DSW1")
AM_RANGE(0xd601, 0xd601) AM_READ_PORT("DSW2")
@@ -347,8 +347,6 @@ void buggychl_state::machine_start()
void buggychl_state::machine_reset()
{
- m_mcu->set_input_line(0, CLEAR_LINE);
-
m_sound_nmi_enable = 0;
m_pending_nmi = 0;
m_sl_bank = 0;
@@ -370,9 +368,8 @@ static MACHINE_CONFIG_START( buggychl, buggychl_state )
MCFG_CPU_PERIODIC_INT_DRIVER(buggychl_state, irq0_line_hold, 60*60) /* irq is timed, tied to the cpu clock and not to vblank */
/* nmi is caused by the main cpu */
- MCFG_CPU_ADD("mcu", M68705,8000000/2) /* 4 MHz */
- MCFG_CPU_PROGRAM_MAP(buggychl_mcu_map)
- MCFG_DEVICE_ADD("bmcu", BUGGYCHL_MCU, 0)
+ MCFG_DEVICE_ADD("bmcu", TAITO68705_MCU,8000000/2) /* 4 MHz */
+
MCFG_WATCHDOG_ADD("watchdog")
@@ -438,7 +435,7 @@ ROM_START( buggychl )
ROM_REGION( 0x10000, "audiocpu", 0 ) /* sound Z80 */
ROM_LOAD( "a22-24.28", 0x00000, 0x4000, CRC(1e7f841f) SHA1(2dc0787b08d32acb78291b689c02dbb83d04d08c) )
- ROM_REGION( 0x0800, "mcu", 0 ) /* 8k for the microcontroller */
+ ROM_REGION( 0x0800, "bmcu:mcu", 0 ) /* 8k for the microcontroller */
ROM_LOAD( "a22-19.31", 0x00000, 0x0800, CRC(06a71df0) SHA1(28183e6769e1471e7f28dc2a9f5b54e14b7ef339) )
ROM_REGION( 0x20000, "gfx1", 0 ) /* sprites */
@@ -468,7 +465,7 @@ ROM_START( buggychlt )
ROM_REGION( 0x10000, "audiocpu", 0 ) /* sound Z80 */
ROM_LOAD( "a22-24.28", 0x00000, 0x4000, CRC(1e7f841f) SHA1(2dc0787b08d32acb78291b689c02dbb83d04d08c) )
- ROM_REGION( 0x0800, "mcu", 0 ) /* 8k for the microcontroller */
+ ROM_REGION( 0x0800, "bmcu:mcu", 0 ) /* 8k for the microcontroller */
ROM_LOAD( "a22-19.31", 0x00000, 0x0800, CRC(06a71df0) SHA1(28183e6769e1471e7f28dc2a9f5b54e14b7ef339) )
ROM_REGION( 0x20000, "gfx1", 0 ) /* sprites */
diff --git a/src/mame/drivers/cdi.cpp b/src/mame/drivers/cdi.cpp
index 0b2e23a1031..a2c70c94c23 100644
--- a/src/mame/drivers/cdi.cpp
+++ b/src/mame/drivers/cdi.cpp
@@ -317,7 +317,7 @@ MACHINE_RESET_MEMBER( cdi_state, cdimono2 )
m_dmadac[1] = machine().device<dmadac_sound_device>("dac2");
}
-MACHINE_RESET_MEMBER( cdi_state, quizard12 )
+MACHINE_RESET_MEMBER( cdi_state, quizard1 )
{
MACHINE_RESET_CALL_MEMBER( cdimono1 );
@@ -325,37 +325,7 @@ MACHINE_RESET_MEMBER( cdi_state, quizard12 )
m_scc->set_quizard_mcu_ack(0x5a);
}
-MACHINE_RESET_MEMBER( cdi_state, quizard17 )
-{
- MACHINE_RESET_CALL_MEMBER( cdimono1 );
-
- m_scc->set_quizard_mcu_value(0x021f);
- m_scc->set_quizard_mcu_ack(0x5a);
-}
-
-/* Untested - copied from quizard17 */
-MACHINE_RESET_MEMBER( cdi_state, quizard18 )
-{
- MACHINE_RESET_CALL_MEMBER( cdimono1 );
-
- m_scc->set_quizard_mcu_value(0x021f);
- m_scc->set_quizard_mcu_ack(0x5a);
-}
-
-MACHINE_RESET_MEMBER( cdi_state, quizard22 )
-{
- MACHINE_RESET_CALL_MEMBER( cdimono1 );
-
- // 0x2b1: Italian
- // 0x001: French
- // 0x188: German
-
- m_scc->set_quizard_mcu_value(0x188);
- m_scc->set_quizard_mcu_ack(0x59);
-}
-
-/* Untested - copied from quizard22 */
-MACHINE_RESET_MEMBER( cdi_state, quizard23 )
+MACHINE_RESET_MEMBER( cdi_state, quizard2 )
{
MACHINE_RESET_CALL_MEMBER( cdimono1 );
@@ -367,16 +337,9 @@ MACHINE_RESET_MEMBER( cdi_state, quizard23 )
m_scc->set_quizard_mcu_ack(0x59);
}
-MACHINE_RESET_MEMBER( cdi_state, quizard32 )
-{
- MACHINE_RESET_CALL_MEMBER( cdimono1 );
- m_scc->set_quizard_mcu_value(0x00ae);
- m_scc->set_quizard_mcu_ack(0x58);
-}
-/* Untested - copied from quizard32 */
-MACHINE_RESET_MEMBER( cdi_state, quizard34 )
+MACHINE_RESET_MEMBER( cdi_state, quizard3 )
{
MACHINE_RESET_CALL_MEMBER( cdimono1 );
@@ -384,8 +347,7 @@ MACHINE_RESET_MEMBER( cdi_state, quizard34 )
m_scc->set_quizard_mcu_ack(0x58);
}
-/* Untested - copied from quizard4r41 */
-MACHINE_RESET_MEMBER( cdi_state, quizard4r40 )
+MACHINE_RESET_MEMBER( cdi_state, quizard4 )
{
MACHINE_RESET_CALL_MEMBER( cdimono1 );
@@ -394,22 +356,7 @@ MACHINE_RESET_MEMBER( cdi_state, quizard4r40 )
m_scc->set_quizard_mcu_ack(0x57);
}
-MACHINE_RESET_MEMBER( cdi_state, quizard4r41 )
-{
- MACHINE_RESET_CALL_MEMBER( cdimono1 );
- //m_scc->set_quizard_mcu_value(0x0139);
- m_scc->set_quizard_mcu_value(0x011f);
- m_scc->set_quizard_mcu_ack(0x57);
-}
-
-MACHINE_RESET_MEMBER( cdi_state, quizard4r42 )
-{
- MACHINE_RESET_CALL_MEMBER( cdimono1 );
-
- m_scc->set_quizard_mcu_value(0x01ae);
- m_scc->set_quizard_mcu_ack(0x57);
-}
/**************************
* 68HC05 Handlers *
@@ -987,49 +934,47 @@ static MACHINE_CONFIG_DERIVED( quizard, cdimono1_base )
MCFG_CPU_VBLANK_INT_DRIVER("screen", cdi_state, mcu_frame)
MACHINE_CONFIG_END
-static MACHINE_CONFIG_DERIVED( quizard12, quizard )
- MCFG_MACHINE_RESET_OVERRIDE(cdi_state, quizard12 )
-MACHINE_CONFIG_END
-static MACHINE_CONFIG_DERIVED( quizard17, quizard )
- MCFG_MACHINE_RESET_OVERRIDE(cdi_state, quizard17 )
-MACHINE_CONFIG_END
+READ8_MEMBER( cdi_state::quizard_mcu_p1_r )
+{
+ return rand();
+}
-static MACHINE_CONFIG_DERIVED( quizard18, quizard )
- MCFG_MACHINE_RESET_OVERRIDE(cdi_state, quizard18 )
-MACHINE_CONFIG_END
+static ADDRESS_MAP_START( mcu_io_map, AS_IO, 8, cdi_state )
+ ADDRESS_MAP_UNMAP_HIGH
+ AM_RANGE(MCS51_PORT_P1, MCS51_PORT_P1) AM_READ(quizard_mcu_p1_r)
+ADDRESS_MAP_END
-static MACHINE_CONFIG_DERIVED( quizard22, quizard )
- MCFG_MACHINE_RESET_OVERRIDE(cdi_state, quizard22 )
-MACHINE_CONFIG_END
+static MACHINE_CONFIG_DERIVED( quizard1, quizard )
+ MCFG_MACHINE_RESET_OVERRIDE(cdi_state, quizard1 )
+
+ MCFG_CPU_ADD("mcu", I8751, 8000000)
+ MCFG_CPU_IO_MAP(mcu_io_map)
+// MCFG_DEVICE_VBLANK_INT_DRIVER("screen", cdi_state, irq0_line_pulse)
-static MACHINE_CONFIG_DERIVED( quizard23, quizard )
- MCFG_MACHINE_RESET_OVERRIDE(cdi_state, quizard23 )
MACHINE_CONFIG_END
-static MACHINE_CONFIG_DERIVED( quizard32, quizard )
- MCFG_MACHINE_RESET_OVERRIDE(cdi_state, quizard32 )
+static MACHINE_CONFIG_DERIVED( quizard2, quizard )
+ MCFG_MACHINE_RESET_OVERRIDE(cdi_state, quizard2 )
MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( quizard3, quizard )
- MCFG_MACHINE_RESET_OVERRIDE(cdi_state, quizard34 )
+ MCFG_MACHINE_RESET_OVERRIDE(cdi_state, quizard3 )
MACHINE_CONFIG_END
-static MACHINE_CONFIG_DERIVED( quizard4r40, quizard )
- MCFG_MACHINE_RESET_OVERRIDE(cdi_state, quizard4r40 )
-MACHINE_CONFIG_END
+static MACHINE_CONFIG_DERIVED( quizard4, quizard )
+ MCFG_MACHINE_RESET_OVERRIDE(cdi_state, quizard4 )
-static MACHINE_CONFIG_DERIVED( quizard4r41, quizard )
- MCFG_MACHINE_RESET_OVERRIDE(cdi_state, quizard4r41 )
-MACHINE_CONFIG_END
+ MCFG_CPU_ADD("mcu", I8751, 8000000)
+ MCFG_CPU_IO_MAP(mcu_io_map)
+// MCFG_DEVICE_VBLANK_INT_DRIVER("screen", cdi_state, irq0_line_pulse)
-static MACHINE_CONFIG_DERIVED( quizard4r42, quizard )
- MCFG_MACHINE_RESET_OVERRIDE(cdi_state, quizard4r42 )
MACHINE_CONFIG_END
+
/*************************
* Rom Load *
*************************/
@@ -1111,7 +1056,19 @@ ROM_START( cdibios ) // for the quizard sets
ROM_LOAD( "slave.bin", 0x0000, 0x2000, NO_DUMP ) // Undumped 68HC05 microcontroller, might need decapping
ROM_END
-// Quizard
+/* Quizard notes
+
+ The MCU controls the protection sequence, which in turn controls the game display language.
+ Each Quizard game (1,2,3,4) requires it's own MCU, you can upgrade between revisions by changing
+ just the CD, but not between games as a new MCU is required.
+
+ The only dumped MCUs are German region ones for Quizard 1 and 4.
+ A Czech Quizard 4 MCU was located but it was an 89c51 type instead
+
+*/
+
+
+// Quizard (1)
ROM_START( quizard ) /* CD-ROM printed ??/?? */
ROM_REGION(0x80000, "maincpu", 0)
@@ -1125,8 +1082,12 @@ ROM_START( quizard ) /* CD-ROM printed ??/?? */
DISK_REGION( "cdrom" )
DISK_IMAGE_READONLY( "quizard18", 0, BAD_DUMP SHA1(ede873b22957f2a707bbd3039e962ef2ca5aedbd) )
+
+ ROM_REGION(0x1000, "mcu", 0)
+ ROM_LOAD( "quizard1_german_d8751.bin", 0x0000, 0x1000, CRC(95f45b6b) SHA1(51b34956539b1e2cf0306f243a970750f1e18d01) )
ROM_END
+
ROM_START( quizard_17 )
ROM_REGION(0x80000, "maincpu", 0)
ROM_LOAD( "cdi220b.rom", 0x000000, 0x80000, CRC(279683ca) SHA1(53360a1f21ddac952e95306ced64186a3fc0b93e) )
@@ -1139,6 +1100,9 @@ ROM_START( quizard_17 )
DISK_REGION( "cdrom" )
DISK_IMAGE_READONLY( "quizard17", 0, BAD_DUMP SHA1(4bd698f076505b4e17be978481bce027eb47123b) )
+
+ ROM_REGION(0x1000, "mcu", 0)
+ ROM_LOAD( "quizard1_german_d8751.bin", 0x0000, 0x1000, CRC(95f45b6b) SHA1(51b34956539b1e2cf0306f243a970750f1e18d01) )
ROM_END
ROM_START( quizard_12 ) /* CD-ROM printed 01/95 */
@@ -1153,6 +1117,9 @@ ROM_START( quizard_12 ) /* CD-ROM printed 01/95 */
DISK_REGION( "cdrom" )
DISK_IMAGE_READONLY( "quizard12", 0, BAD_DUMP SHA1(6e41683b96b74e903040842aeb18437ad7813c82) )
+
+ ROM_REGION(0x1000, "mcu", 0)
+ ROM_LOAD( "quizard1_german_d8751.bin", 0x0000, 0x1000, CRC(95f45b6b) SHA1(51b34956539b1e2cf0306f243a970750f1e18d01) )
ROM_END
ROM_START( quizard_10 )
@@ -1170,6 +1137,9 @@ ROM_START( quizard_10 )
// Drive: TS-L633R
DISK_REGION( "cdrom" )
DISK_IMAGE_READONLY( "quizard10", 0, SHA1(5715db50f0d5ffe06f47c0943f4bf0481ab6048e) )
+
+ ROM_REGION(0x1000, "mcu", 0)
+ ROM_LOAD( "quizard1_german_d8751.bin", 0x0000, 0x1000, CRC(95f45b6b) SHA1(51b34956539b1e2cf0306f243a970750f1e18d01) )
ROM_END
@@ -1187,6 +1157,9 @@ ROM_START( quizard2 ) /* CD-ROM printed ??/?? */
DISK_REGION( "cdrom" )
DISK_IMAGE_READONLY( "quizard23", 0, BAD_DUMP SHA1(cd909d9a54275d6f2d36e03e83eea996e781b4d3) )
+
+ ROM_REGION(0x1000, "mcu", 0)
+ ROM_LOAD( "quizard2_d8751.bin", 0x0000, 0x1000, NO_DUMP )
ROM_END
ROM_START( quizard2_22 )
@@ -1201,6 +1174,9 @@ ROM_START( quizard2_22 )
DISK_REGION( "cdrom" )
DISK_IMAGE_READONLY( "quizard22", 0, BAD_DUMP SHA1(03c8fdcf27ead6e221691111e8c679b551099543) )
+
+ ROM_REGION(0x1000, "mcu", 0)
+ ROM_LOAD( "quizard2_d8751.bin", 0x0000, 0x1000, NO_DUMP )
ROM_END
// Quizard 3
@@ -1217,6 +1193,9 @@ ROM_START( quizard3 ) /* CD-ROM printed ??/?? */
DISK_REGION( "cdrom" )
DISK_IMAGE_READONLY( "quizard34", 0, BAD_DUMP SHA1(37ad49b72b5175afbb87141d57bc8604347fe032) )
+
+ ROM_REGION(0x1000, "mcu", 0)
+ ROM_LOAD( "quizard3_d8751.bin", 0x0000, 0x1000, NO_DUMP )
ROM_END
ROM_START( quizard3_32 )
@@ -1231,6 +1210,9 @@ ROM_START( quizard3_32 )
DISK_REGION( "cdrom" )
DISK_IMAGE_READONLY( "quizard32", 0, BAD_DUMP SHA1(31e9fa2169aa44d799c37170b238134ab738e1a1) )
+
+ ROM_REGION(0x1000, "mcu", 0)
+ ROM_LOAD( "quizard3_d8751.bin", 0x0000, 0x1000, NO_DUMP )
ROM_END
@@ -1246,6 +1228,9 @@ ROM_START( quizard4 ) /* CD-ROM printed 09/98 */
DISK_REGION( "cdrom" )
DISK_IMAGE_READONLY( "quizard4r42", 0, BAD_DUMP SHA1(a5d5c8950b4650b8753f9119dc7f1ccaa2aa5442) )
+
+ ROM_REGION(0x1000, "mcu", 0)
+ ROM_LOAD( "quizard4_german_d8751.bin", 0x0000, 0x1000, CRC(77be0b40) SHA1(113b5c239480a2259f55e411ba8fb3972e6d4301) )
ROM_END
ROM_START( quizard4_41 )
@@ -1260,6 +1245,9 @@ ROM_START( quizard4_41 )
DISK_REGION( "cdrom" )
DISK_IMAGE_READONLY( "quizard4r41", 0, BAD_DUMP SHA1(2c0484c6545aac8e00b318328c6edce6f5dde43d) )
+
+ ROM_REGION(0x1000, "mcu", 0)
+ ROM_LOAD( "quizard4_german_d8751.bin", 0x0000, 0x1000, CRC(77be0b40) SHA1(113b5c239480a2259f55e411ba8fb3972e6d4301) )
ROM_END
ROM_START( quizard4_40 ) /* CD-ROM printed 07/97 */
@@ -1274,6 +1262,9 @@ ROM_START( quizard4_40 ) /* CD-ROM printed 07/97 */
DISK_REGION( "cdrom" )
DISK_IMAGE_READONLY( "quizard4r40", 0, BAD_DUMP SHA1(288cc37a994e4f1cbd47aa8c92342879c6fc0b87) )
+
+ ROM_REGION(0x1000, "mcu", 0)
+ ROM_LOAD( "quizard4_german_d8751.bin", 0x0000, 0x1000, CRC(77be0b40) SHA1(113b5c239480a2259f55e411ba8fb3972e6d4301) )
ROM_END
@@ -1293,17 +1284,19 @@ CONS( 1991, cdi490a, 0, 0, cdimono1, cdi, driver_device, 0,
GAME( 1995, cdibios, 0, cdimono1_base, quizard, driver_device, 0, ROT0, "Philips", "CD-i (Mono-I) (PAL) BIOS", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_IS_BIOS_ROOT )
-GAME( 1995, quizard, cdibios, quizard18, quizard, driver_device, 0, ROT0, "TAB Austria", "Quizard (v1.8)", MACHINE_IMPERFECT_SOUND | MACHINE_UNEMULATED_PROTECTION )
-GAME( 1995, quizard_17, quizard, quizard17, quizard, driver_device, 0, ROT0, "TAB Austria", "Quizard (v1.7)", MACHINE_IMPERFECT_SOUND | MACHINE_UNEMULATED_PROTECTION )
-GAME( 1995, quizard_12, quizard, quizard12, quizard, driver_device, 0, ROT0, "TAB Austria", "Quizard (v1.2)", MACHINE_IMPERFECT_SOUND | MACHINE_UNEMULATED_PROTECTION )
-GAME( 1995, quizard_10, quizard, quizard12, quizard, driver_device, 0, ROT0, "TAB Austria", "Quizard (v1.0)", MACHINE_IMPERFECT_SOUND | MACHINE_UNEMULATED_PROTECTION )
+GAME( 1995, quizard, cdibios, quizard1, quizard, driver_device, 0, ROT0, "TAB Austria", "Quizard (v1.8)", MACHINE_IMPERFECT_SOUND | MACHINE_UNEMULATED_PROTECTION )
+GAME( 1995, quizard_17, quizard, quizard1, quizard, driver_device, 0, ROT0, "TAB Austria", "Quizard (v1.7)", MACHINE_IMPERFECT_SOUND | MACHINE_UNEMULATED_PROTECTION )
+GAME( 1995, quizard_12, quizard, quizard1, quizard, driver_device, 0, ROT0, "TAB Austria", "Quizard (v1.2)", MACHINE_IMPERFECT_SOUND | MACHINE_UNEMULATED_PROTECTION )
+GAME( 1995, quizard_10, quizard, quizard1, quizard, driver_device, 0, ROT0, "TAB Austria", "Quizard (v1.0)", MACHINE_IMPERFECT_SOUND | MACHINE_UNEMULATED_PROTECTION )
+
+GAME( 1995, quizard2, cdibios, quizard2, quizard, driver_device, 0, ROT0, "TAB Austria", "Quizard 2 (v2.3)", MACHINE_IMPERFECT_SOUND | MACHINE_UNEMULATED_PROTECTION )
+GAME( 1995, quizard2_22, quizard2, quizard2, quizard, driver_device, 0, ROT0, "TAB Austria", "Quizard 2 (v2.2)", MACHINE_IMPERFECT_SOUND | MACHINE_UNEMULATED_PROTECTION )
-GAME( 1995, quizard2, cdibios, quizard23, quizard, driver_device, 0, ROT0, "TAB Austria", "Quizard 2 (v2.3)", MACHINE_IMPERFECT_SOUND | MACHINE_UNEMULATED_PROTECTION )
-GAME( 1995, quizard2_22, quizard2, quizard22, quizard, driver_device, 0, ROT0, "TAB Austria", "Quizard 2 (v2.2)", MACHINE_IMPERFECT_SOUND | MACHINE_UNEMULATED_PROTECTION )
+// Quizard 3 and 4 will hang after inserting a coin (incomplete protection sims?)
-GAME( 1995, quizard3, cdibios, quizard3, quizard, driver_device, 0, ROT0, "TAB Austria", "Quizard 3 (v3.4)", MACHINE_IMPERFECT_SOUND | MACHINE_UNEMULATED_PROTECTION )
-GAME( 1996, quizard3_32, quizard3, quizard32, quizard, driver_device, 0, ROT0, "TAB Austria", "Quizard 3 (v3.2)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND | MACHINE_UNEMULATED_PROTECTION )
+GAME( 1995, quizard3, cdibios, quizard3, quizard, driver_device, 0, ROT0, "TAB Austria", "Quizard 3 (v3.4)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND | MACHINE_UNEMULATED_PROTECTION )
+GAME( 1996, quizard3_32, quizard3, quizard3, quizard, driver_device, 0, ROT0, "TAB Austria", "Quizard 3 (v3.2)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND | MACHINE_UNEMULATED_PROTECTION )
-GAME( 1998, quizard4, cdibios, quizard4r42, quizard, driver_device, 0, ROT0, "TAB Austria", "Quizard 4 Rainbow (v4.2)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND | MACHINE_UNEMULATED_PROTECTION ) // doesn't boot
-GAME( 1998, quizard4_41, quizard4, quizard4r41, quizard, driver_device, 0, ROT0, "TAB Austria", "Quizard 4 Rainbow (v4.1)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND | MACHINE_UNEMULATED_PROTECTION )
-GAME( 1997, quizard4_40, quizard4, quizard4r40, quizard, driver_device, 0, ROT0, "TAB Austria", "Quizard 4 Rainbow (v4.0)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND | MACHINE_UNEMULATED_PROTECTION )
+GAME( 1998, quizard4, cdibios, quizard4, quizard, driver_device, 0, ROT0, "TAB Austria", "Quizard 4 Rainbow (v4.2)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND | MACHINE_UNEMULATED_PROTECTION )
+GAME( 1998, quizard4_41, quizard4, quizard4, quizard, driver_device, 0, ROT0, "TAB Austria", "Quizard 4 Rainbow (v4.1)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND | MACHINE_UNEMULATED_PROTECTION )
+GAME( 1997, quizard4_40, quizard4, quizard4, quizard, driver_device, 0, ROT0, "TAB Austria", "Quizard 4 Rainbow (v4.0)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND | MACHINE_UNEMULATED_PROTECTION )
diff --git a/src/mame/drivers/cedar_magnet.cpp b/src/mame/drivers/cedar_magnet.cpp
index 1b972602df0..09d91496f82 100644
--- a/src/mame/drivers/cedar_magnet.cpp
+++ b/src/mame/drivers/cedar_magnet.cpp
@@ -110,7 +110,7 @@ I suspect the additional memory was an afterthought.
#include "machine/z80ctc.h"
#include "sound/ay8910.h"
-#include "machine/cedar_magnet_sound.h"
+#include "audio/efo_zsu.h"
#include "machine/cedar_magnet_plane.h"
#include "machine/cedar_magnet_sprite.h"
#include "machine/cedar_magnet_flop.h"
@@ -185,8 +185,6 @@ public:
DECLARE_READ8_MEMBER(port7c_r);
// other ports
- DECLARE_WRITE8_MEMBER(soundlatch_w);
- uint8_t portff_data;
DECLARE_READ8_MEMBER(other_cpu_r);
DECLARE_WRITE8_MEMBER(other_cpu_w);
@@ -203,7 +201,7 @@ public:
DECLARE_WRITE8_MEMBER(palette_g_w);
DECLARE_WRITE8_MEMBER(palette_b_w);
- void handle_sub_board_cpu_lines(cedar_magnet_board_device* dev, int old_data, int data);
+ void handle_sub_board_cpu_lines(cedar_magnet_board_interface &dev, int old_data, int data);
INTERRUPT_GEN_MEMBER(irq);
void(*m_prothack)(cedar_magnet_state*);
@@ -271,7 +269,7 @@ static ADDRESS_MAP_START( cedar_magnet_io, AS_IO, 8, cedar_magnet_state )
AM_RANGE(0x78, 0x78) AM_READWRITE(watchdog_r, paladdr_w)
AM_RANGE(0x7c, 0x7c) AM_READ(port7c_r) // protection??
- AM_RANGE(0xff, 0xff) AM_WRITE(soundlatch_w)
+ AM_RANGE(0xff, 0xff) AM_DEVWRITE("cedtop", cedar_magnet_sound_device, sound_command_w)
ADDRESS_MAP_END
static ADDRESS_MAP_START( cedar_bank0, AS_PROGRAM, 8, cedar_magnet_state )
@@ -441,13 +439,6 @@ void cedar_magnet_state::video_start()
***********************/
-WRITE8_MEMBER(cedar_magnet_state::soundlatch_w)
-{
-// printf("%s: writing soundlatch_w! %02x\n", machine().describe_context(), data);
- portff_data = data;
- m_cedsound->write_command(data);
-}
-
READ8_MEMBER(cedar_magnet_state::other_cpu_r)
{
int bankbit0 = (m_ic48_pio_pa_val & 0x60) >> 5;
@@ -544,19 +535,19 @@ WRITE8_MEMBER(cedar_magnet_state::other_cpu_w)
}
-void cedar_magnet_state::handle_sub_board_cpu_lines(cedar_magnet_board_device* dev, int old_data, int data)
+void cedar_magnet_state::handle_sub_board_cpu_lines(cedar_magnet_board_interface &dev, int old_data, int data)
{
if (old_data != data)
{
if (data & 0x04)
- dev->reset_assert();
+ dev.reset_assert();
else
- dev->reset_clear();
+ dev.reset_clear();
if (data & 0x02)
- dev->halt_clear();
+ dev.halt_clear();
else
- dev->halt_assert();
+ dev.halt_assert();
}
}
@@ -605,7 +596,7 @@ WRITE8_MEMBER( cedar_magnet_state::ic48_pio_pa_w ) // 0x20
int plane0select = (m_ic48_pio_pa_val & 0x07) >> 0;
- handle_sub_board_cpu_lines(m_cedplane0, oldplane0select, plane0select);
+ handle_sub_board_cpu_lines(*m_cedplane0, oldplane0select, plane0select);
}
@@ -644,8 +635,8 @@ WRITE8_MEMBER(cedar_magnet_state::ic48_pio_pb_w) // 0x22
int plane1select = (m_ic48_pio_pb_val & 0x07) >> 0;
int spriteselect = (m_ic48_pio_pb_val & 0x70) >> 4;
- handle_sub_board_cpu_lines(m_cedplane1, oldplane1select, plane1select);
- handle_sub_board_cpu_lines(m_cedsprite, oldspriteselect, spriteselect);
+ handle_sub_board_cpu_lines(*m_cedplane1, oldplane1select, plane1select);
+ handle_sub_board_cpu_lines(*m_cedsprite, oldspriteselect, spriteselect);
}
/***********************
@@ -688,7 +679,7 @@ WRITE8_MEMBER( cedar_magnet_state::ic49_pio_pb_w ) // 0x42
int soundselect = (m_ic49_pio_pb_val & 0x70) >> 4;
- handle_sub_board_cpu_lines(m_cedsound, oldsoundselect, soundselect);
+ handle_sub_board_cpu_lines(*m_cedsound, oldsoundselect, soundselect);
}
/***********************
@@ -705,7 +696,6 @@ void cedar_magnet_state::machine_start()
void cedar_magnet_state::machine_reset()
{
m_ic48_pio_pa_val = 0xff;
- portff_data = 0x00;
int bankbit0 = (m_ic48_pio_pa_val & 0x60) >> 5;
m_bank0->set_bank(bankbit0);
@@ -752,7 +742,9 @@ INTERRUPT_GEN_MEMBER(cedar_magnet_state::irq)
m_prothack(this);
m_maincpu->set_input_line(0, HOLD_LINE);
- // maybe generate the irqs for the other PCBs here?
+ m_cedplane0->irq_hold();
+ m_cedplane1->irq_hold();
+ m_cedsprite->irq_hold();
}
static MACHINE_CONFIG_START( cedar_magnet, cedar_magnet_state )
diff --git a/src/mame/drivers/crospang.cpp b/src/mame/drivers/crospang.cpp
index eb9a7f9d1bd..b2702b871ca 100644
--- a/src/mame/drivers/crospang.cpp
+++ b/src/mame/drivers/crospang.cpp
@@ -40,14 +40,6 @@
#include "includes/crospang.h"
-WRITE16_MEMBER(crospang_state::crospang_soundlatch_w)
-{
- if(ACCESSING_BITS_0_7)
- {
- m_soundlatch->write(space, 0, data & 0xff);
- }
-}
-
/* main cpu */
static ADDRESS_MAP_START( crospang_base_map, AS_PROGRAM, 16, crospang_state )
@@ -57,7 +49,7 @@ static ADDRESS_MAP_START( crospang_base_map, AS_PROGRAM, 16, crospang_state )
AM_RANGE(0x122000, 0x1227ff) AM_RAM_WRITE(crospang_bg_videoram_w) AM_SHARE("bg_videoram")
AM_RANGE(0x200000, 0x2005ff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette")
AM_RANGE(0x210000, 0x2107ff) AM_RAM AM_SHARE("spriteram")
- AM_RANGE(0x270000, 0x270001) AM_WRITE(crospang_soundlatch_w)
+ AM_RANGE(0x270000, 0x270001) AM_DEVWRITE8("soundlatch", generic_latch_8_device, write, 0x00ff)
AM_RANGE(0x270004, 0x270007) AM_WRITENOP // ??
AM_RANGE(0x280000, 0x280001) AM_READ_PORT("P1_P2")
AM_RANGE(0x280002, 0x280003) AM_READ_PORT("COIN")
diff --git a/src/mame/drivers/crshrace.cpp b/src/mame/drivers/crshrace.cpp
index f56cc5643f2..b4ad32f78c0 100644
--- a/src/mame/drivers/crshrace.cpp
+++ b/src/mame/drivers/crshrace.cpp
@@ -143,14 +143,11 @@ WRITE8_MEMBER(crshrace_state::crshrace_sh_bankswitch_w)
m_z80bank->set_entry(data & 0x03);
}
-WRITE16_MEMBER(crshrace_state::sound_command_w)
+WRITE8_MEMBER(crshrace_state::sound_command_w)
{
- if (ACCESSING_BITS_0_7)
- {
- m_pending_command = 1;
- m_soundlatch->write(space, offset, data & 0xff);
- m_audiocpu->set_input_line(INPUT_LINE_NMI, PULSE_LINE);
- }
+ m_pending_command = 1;
+ m_soundlatch->write(space, offset, data & 0xff);
+ m_audiocpu->set_input_line(INPUT_LINE_NMI, PULSE_LINE);
}
CUSTOM_INPUT_MEMBER(crshrace_state::country_sndpending_r)
@@ -164,7 +161,6 @@ WRITE8_MEMBER(crshrace_state::pending_command_clear_w)
}
-
static ADDRESS_MAP_START( crshrace_map, AS_PROGRAM, 16, crshrace_state )
AM_RANGE(0x000000, 0x07ffff) AM_ROM
AM_RANGE(0x300000, 0x3fffff) AM_ROM AM_REGION("user1", 0)
@@ -180,7 +176,7 @@ static ADDRESS_MAP_START( crshrace_map, AS_PROGRAM, 16, crshrace_state )
AM_RANGE(0xfff002, 0xfff003) AM_READ_PORT("P2")
AM_RANGE(0xfff004, 0xfff005) AM_READ_PORT("DSW0")
AM_RANGE(0xfff006, 0xfff007) AM_READ_PORT("DSW2")
- AM_RANGE(0xfff008, 0xfff009) AM_WRITE(sound_command_w)
+ AM_RANGE(0xfff008, 0xfff009) AM_WRITE8(sound_command_w, 0x00ff)
AM_RANGE(0xfff00a, 0xfff00b) AM_READ_PORT("DSW1")
AM_RANGE(0xfff00e, 0xfff00f) AM_READ_PORT("P3")
AM_RANGE(0xfff020, 0xfff03f) AM_DEVWRITE("k053936", k053936_device, ctrl_w)
diff --git a/src/mame/drivers/cvs.cpp b/src/mame/drivers/cvs.cpp
index 6427f13f64f..d331ed50507 100644
--- a/src/mame/drivers/cvs.cpp
+++ b/src/mame/drivers/cvs.cpp
@@ -347,7 +347,7 @@ WRITE8_MEMBER(cvs_state::cvs_unknown_w)
if (data != m_dac3_state[offset])
{
- if (offset != 2)
+ if (VERBOSE && offset != 2)
popmessage("Unknown: %02x %02x\n", offset, data);
m_dac3_state[offset] = data;
}
diff --git a/src/mame/drivers/dcheese.cpp b/src/mame/drivers/dcheese.cpp
index 2aad3a511de..59d07364a06 100644
--- a/src/mame/drivers/dcheese.cpp
+++ b/src/mame/drivers/dcheese.cpp
@@ -92,7 +92,6 @@ INTERRUPT_GEN_MEMBER(dcheese_state::dcheese_vblank)
void dcheese_state::machine_start()
{
save_item(NAME(m_irq_state));
- save_item(NAME(m_soundlatch_full));
save_item(NAME(m_sound_control));
save_item(NAME(m_sound_msb_latch));
}
@@ -107,7 +106,7 @@ void dcheese_state::machine_start()
CUSTOM_INPUT_MEMBER(dcheese_state::sound_latch_state_r)
{
- return m_soundlatch_full;
+ return m_soundlatch->pending_r();
}
@@ -123,18 +122,6 @@ WRITE16_MEMBER(dcheese_state::eeprom_control_w)
}
-WRITE16_MEMBER(dcheese_state::sound_command_w)
-{
- if (ACCESSING_BITS_0_7)
- {
- /* write the latch and set the IRQ */
- m_soundlatch_full = 1;
- m_audiocpu->set_input_line(0, ASSERT_LINE);
- m_soundlatch->write(space, 0, data & 0xff);
- }
-}
-
-
/*************************************
*
@@ -142,15 +129,6 @@ WRITE16_MEMBER(dcheese_state::sound_command_w)
*
*************************************/
-READ8_MEMBER(dcheese_state::sound_command_r)
-{
- /* read the latch and clear the IRQ */
- m_soundlatch_full = 0;
- m_audiocpu->set_input_line(0, CLEAR_LINE);
- return m_soundlatch->read(space, 0);
-}
-
-
READ8_MEMBER(dcheese_state::sound_status_r)
{
/* seems to be ready signal on BSMT or latching hardware */
@@ -202,7 +180,7 @@ static ADDRESS_MAP_START( main_cpu_map, AS_PROGRAM, 16, dcheese_state )
AM_RANGE(0x260000, 0x26001f) AM_WRITE(madmax_blitter_xparam_w)
AM_RANGE(0x280000, 0x28001f) AM_WRITE(madmax_blitter_yparam_w)
AM_RANGE(0x2a0000, 0x2a003f) AM_READWRITE(madmax_blitter_vidparam_r, madmax_blitter_vidparam_w)
- AM_RANGE(0x2e0000, 0x2e0001) AM_WRITE(sound_command_w)
+ AM_RANGE(0x2e0000, 0x2e0001) AM_DEVWRITE8("soundlatch", generic_latch_8_device, write, 0x00ff)
AM_RANGE(0x300000, 0x300001) AM_WRITE(madmax_blitter_unknown_w)
ADDRESS_MAP_END
@@ -217,7 +195,7 @@ ADDRESS_MAP_END
static ADDRESS_MAP_START( sound_cpu_map, AS_PROGRAM, 8, dcheese_state )
ADDRESS_MAP_UNMAP_HIGH
AM_RANGE(0x0000, 0x07ff) AM_READWRITE(sound_status_r, sound_control_w)
- AM_RANGE(0x0800, 0x0fff) AM_READ(sound_command_r)
+ AM_RANGE(0x0800, 0x0fff) AM_DEVREAD("soundlatch", generic_latch_8_device, read)
AM_RANGE(0x1000, 0x10ff) AM_MIRROR(0x0700) AM_WRITE(bsmt_data_w)
AM_RANGE(0x1800, 0x1fff) AM_RAM
AM_RANGE(0x2000, 0xffff) AM_ROM
@@ -421,6 +399,7 @@ static MACHINE_CONFIG_START( dcheese, dcheese_state )
MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
MCFG_GENERIC_LATCH_8_ADD("soundlatch")
+ MCFG_GENERIC_LATCH_DATA_PENDING_CB(INPUTLINE("audiocpu", 0))
MCFG_BSMT2000_ADD("bsmt", SOUND_OSC)
MCFG_SOUND_ROUTE(0, "lspeaker", 1.2)
diff --git a/src/mame/drivers/ddenlovr.cpp b/src/mame/drivers/ddenlovr.cpp
index 61a0a227402..96f7bdead39 100644
--- a/src/mame/drivers/ddenlovr.cpp
+++ b/src/mame/drivers/ddenlovr.cpp
@@ -265,24 +265,20 @@ public:
DECLARE_CUSTOM_INPUT_MEMBER(mjflove_blitter_r);
DECLARE_WRITE8_MEMBER(ddenlovr_bgcolor_w);
DECLARE_WRITE8_MEMBER(ddenlovr_bgcolor2_w);
- DECLARE_WRITE16_MEMBER(ddenlovr16_bgcolor_w);
DECLARE_WRITE8_MEMBER(ddenlovr_priority_w);
DECLARE_WRITE8_MEMBER(ddenlovr_priority2_w);
- DECLARE_WRITE16_MEMBER(ddenlovr16_priority_w);
DECLARE_WRITE8_MEMBER(ddenlovr_layer_enable_w);
DECLARE_WRITE8_MEMBER(ddenlovr_layer_enable2_w);
- DECLARE_WRITE16_MEMBER(ddenlovr16_layer_enable_w);
DECLARE_WRITE8_MEMBER(hanakanz_blitter_reg_w);
DECLARE_WRITE8_MEMBER(hanakanz_blitter_data_w);
DECLARE_WRITE8_MEMBER(rongrong_blitter_w);
- DECLARE_WRITE16_MEMBER(ddenlovr_blitter_w);
- DECLARE_WRITE16_MEMBER(ddenlovr_blitter_irq_ack_w);
+ DECLARE_WRITE8_MEMBER(ddenlovr_blitter_w);
+ DECLARE_WRITE8_MEMBER(ddenlovr_blitter_irq_ack_w);
DECLARE_READ8_MEMBER(rongrong_gfxrom_r);
DECLARE_READ16_MEMBER(ddenlovr_gfxrom_r);
- DECLARE_WRITE16_MEMBER(ddenlovr_coincounter_0_w);
- DECLARE_WRITE16_MEMBER(ddenlovr_coincounter_1_w);
+ DECLARE_WRITE8_MEMBER(ddenlovr_coincounter_0_w);
+ DECLARE_WRITE8_MEMBER(ddenlovr_coincounter_1_w);
DECLARE_WRITE8_MEMBER(rongrong_palette_w);
- DECLARE_WRITE16_MEMBER(ddenlovr_palette_w);
DECLARE_WRITE8_MEMBER(ddenlovr_palette_base_w);
DECLARE_WRITE8_MEMBER(ddenlovr_palette_base2_w);
DECLARE_WRITE8_MEMBER(ddenlovr_palette_mask_w);
@@ -291,30 +287,24 @@ public:
DECLARE_WRITE8_MEMBER(ddenlovr_transparency_pen2_w);
DECLARE_WRITE8_MEMBER(ddenlovr_transparency_mask_w);
DECLARE_WRITE8_MEMBER(ddenlovr_transparency_mask2_w);
- DECLARE_WRITE16_MEMBER(ddenlovr16_palette_base_w);
- DECLARE_WRITE16_MEMBER(ddenlovr16_palette_mask_w);
- DECLARE_WRITE16_MEMBER(ddenlovr16_transparency_pen_w);
- DECLARE_WRITE16_MEMBER(ddenlovr16_transparency_mask_w);
DECLARE_READ8_MEMBER(unk_r);
DECLARE_READ16_MEMBER(unk16_r);
- DECLARE_WRITE16_MEMBER(ddenlovr_select_16_w);
DECLARE_WRITE8_MEMBER(ddenlovr_select2_w);
- DECLARE_WRITE16_MEMBER(ddenlovr_select2_16_w);
DECLARE_READ8_MEMBER(rongrong_input2_r);
DECLARE_READ16_MEMBER(quiz365_input2_r);
DECLARE_WRITE8_MEMBER(rongrong_blitter_busy_w);
DECLARE_READ8_MEMBER(rongrong_blitter_busy_r);
- DECLARE_WRITE16_MEMBER(quiz365_coincounter_w);
+ DECLARE_WRITE8_MEMBER(quiz365_coincounter_w);
DECLARE_READ16_MEMBER(quiz365_protection_r);
DECLARE_WRITE16_MEMBER(quiz365_protection_w);
DECLARE_READ16_MEMBER(ddenlovj_dsw_r);
- DECLARE_WRITE16_MEMBER(ddenlovj_coincounter_w);
+ DECLARE_WRITE8_MEMBER(ddenlovj_coincounter_w);
DECLARE_READ16_MEMBER(ddenlovrk_protection1_r);
DECLARE_READ16_MEMBER(ddenlovrk_protection2_r);
DECLARE_WRITE16_MEMBER(ddenlovrk_protection2_w);
DECLARE_READ16_MEMBER(nettoqc_input_r);
DECLARE_READ16_MEMBER(nettoqc_protection1_r);
- DECLARE_WRITE16_MEMBER(nettoqc_coincounter_w);
+ DECLARE_WRITE8_MEMBER(nettoqc_coincounter_w);
DECLARE_READ16_MEMBER(ultrchmp_protection2_r);
DECLARE_WRITE16_MEMBER(ultrchmp_protection2_w);
DECLARE_READ8_MEMBER(rongrong_input_r);
@@ -425,12 +415,12 @@ public:
DECLARE_WRITE8_MEMBER(htengoku_dsw_w);
DECLARE_READ8_MEMBER(htengoku_dsw_r);
DECLARE_WRITE8_MEMBER( quizchq_oki_bank_w );
- DECLARE_WRITE16_MEMBER( ddenlovr_oki_bank_w );
- DECLARE_WRITE16_MEMBER( quiz365_oki_bank1_w );
- DECLARE_WRITE16_MEMBER( quiz365_oki_bank2_w );
+ DECLARE_WRITE8_MEMBER( ddenlovr_oki_bank_w );
+ DECLARE_WRITE8_MEMBER( quiz365_oki_bank1_w );
+ DECLARE_WRITE8_MEMBER( quiz365_oki_bank2_w );
DECLARE_WRITE8_MEMBER( ddenlovr_select_w );
DECLARE_READ8_MEMBER( quiz365_input_r );
- DECLARE_WRITE16_MEMBER( nettoqc_oki_bank_w );
+ DECLARE_WRITE8_MEMBER( nettoqc_oki_bank_w );
DECLARE_WRITE8_MEMBER( hanakanz_oki_bank_w );
DECLARE_WRITE8_MEMBER( mjchuuka_oki_bank_w );
DECLARE_READ8_MEMBER( hginga_dsw_r );
@@ -605,13 +595,6 @@ WRITE8_MEMBER(ddenlovr_state::ddenlovr_bgcolor2_w)
m_ddenlovr_bgcolor2 = data;
}
-WRITE16_MEMBER(ddenlovr_state::ddenlovr16_bgcolor_w)
-{
- if (ACCESSING_BITS_0_7)
- ddenlovr_bgcolor_w(space, offset, data);
-}
-
-
WRITE8_MEMBER(ddenlovr_state::ddenlovr_priority_w)
{
m_ddenlovr_priority = data;
@@ -622,13 +605,6 @@ WRITE8_MEMBER(ddenlovr_state::ddenlovr_priority2_w)
m_ddenlovr_priority2 = data;
}
-WRITE16_MEMBER(ddenlovr_state::ddenlovr16_priority_w)
-{
- if (ACCESSING_BITS_0_7)
- ddenlovr_priority_w(space, offset, data);
-}
-
-
WRITE8_MEMBER(ddenlovr_state::ddenlovr_layer_enable_w)
{
m_ddenlovr_layer_enable = data;
@@ -640,14 +616,6 @@ WRITE8_MEMBER(ddenlovr_state::ddenlovr_layer_enable2_w)
}
-WRITE16_MEMBER(ddenlovr_state::ddenlovr16_layer_enable_w)
-{
- if (ACCESSING_BITS_0_7)
- ddenlovr_layer_enable_w(space, offset, data);
-}
-
-
-
void ddenlovr_state::do_plot( int x, int y, int pen )
{
int addr, temp;
@@ -1511,26 +1479,22 @@ WRITE8_MEMBER(ddenlovr_state::rongrong_blitter_w)
blitter_w(space, 0, offset, data, 0xf8);
}
-WRITE16_MEMBER(ddenlovr_state::ddenlovr_blitter_w)
+WRITE8_MEMBER(ddenlovr_state::ddenlovr_blitter_w)
{
- if (ACCESSING_BITS_0_7)
- blitter_w(space, 0, offset, data & 0xff, 0);
+ blitter_w(space, 0, offset, data, 0);
}
-WRITE16_MEMBER(ddenlovr_state::ddenlovr_blitter_irq_ack_w)
+WRITE8_MEMBER(ddenlovr_state::ddenlovr_blitter_irq_ack_w)
{
- if (ACCESSING_BITS_0_7)
+ if (data & 1)
{
- if (data & 1)
- {
- m_ddenlovr_blitter_irq_enable = 1;
- }
- else
- {
- m_ddenlovr_blitter_irq_enable = 0;
- m_ddenlovr_blitter_irq_flag = 0;
- }
+ m_ddenlovr_blitter_irq_enable = 1;
+ }
+ else
+ {
+ m_ddenlovr_blitter_irq_enable = 0;
+ m_ddenlovr_blitter_irq_flag = 0;
}
}
@@ -1701,15 +1665,14 @@ CUSTOM_INPUT_MEMBER(ddenlovr_state::ddenlovr_blitter_irq_r)
return m_ddenlovr_blitter_irq_flag;
}
-WRITE16_MEMBER(ddenlovr_state::ddenlovr_coincounter_0_w)
+WRITE8_MEMBER(ddenlovr_state::ddenlovr_coincounter_0_w)
{
- if (ACCESSING_BITS_0_7)
- machine().bookkeeping().coin_counter_w(0, data & 1);
+ machine().bookkeeping().coin_counter_w(0, data & 1);
}
-WRITE16_MEMBER(ddenlovr_state::ddenlovr_coincounter_1_w)
+
+WRITE8_MEMBER(ddenlovr_state::ddenlovr_coincounter_1_w)
{
- if (ACCESSING_BITS_0_7)
- machine().bookkeeping().coin_counter_w(1, data & 1);
+ machine().bookkeeping().coin_counter_w(1, data & 1);
}
@@ -1731,13 +1694,6 @@ WRITE8_MEMBER(ddenlovr_state::rongrong_palette_w)
m_palette->set_pen_color(indx, pal5bit(r), pal5bit(g), pal5bit(b));
}
-WRITE16_MEMBER(ddenlovr_state::ddenlovr_palette_w)
-{
- if (ACCESSING_BITS_0_7)
- rongrong_palette_w(space, offset, data & 0xff);
-}
-
-
WRITE8_MEMBER(ddenlovr_state::ddenlovr_palette_base_w)
{
m_ddenlovr_palette_base[offset] = data;
@@ -1781,62 +1737,26 @@ WRITE8_MEMBER(ddenlovr_state::ddenlovr_transparency_mask2_w)
}
-WRITE16_MEMBER(ddenlovr_state::ddenlovr16_palette_base_w)
-{
- if (ACCESSING_BITS_0_7)
- m_ddenlovr_palette_base[offset] = data & 0xff;
-}
-
-WRITE16_MEMBER(ddenlovr_state::ddenlovr16_palette_mask_w)
-{
- if (ACCESSING_BITS_0_7)
- m_ddenlovr_palette_mask[offset] = data & 0xff;
-}
-
-WRITE16_MEMBER(ddenlovr_state::ddenlovr16_transparency_pen_w)
-{
- if (ACCESSING_BITS_0_7)
- m_ddenlovr_transparency_pen[offset] = data & 0xff;
-}
-
-WRITE16_MEMBER(ddenlovr_state::ddenlovr16_transparency_mask_w)
-{
- if (ACCESSING_BITS_0_7)
- m_ddenlovr_transparency_mask[offset] = data & 0xff;
-}
-
-
WRITE8_MEMBER(ddenlovr_state::quizchq_oki_bank_w )
{
m_oki->set_rom_bank(data & 1);
}
-WRITE16_MEMBER(ddenlovr_state::ddenlovr_oki_bank_w )
+WRITE8_MEMBER(ddenlovr_state::ddenlovr_oki_bank_w )
{
- if (ACCESSING_BITS_0_7)
- {
- m_oki->set_rom_bank(data & 7);
- }
+ m_oki->set_rom_bank(data & 7);
}
-
-
-WRITE16_MEMBER(ddenlovr_state::quiz365_oki_bank1_w )
+WRITE8_MEMBER(ddenlovr_state::quiz365_oki_bank1_w )
{
- if (ACCESSING_BITS_0_7)
- {
- m_okibank = (m_okibank & 2) | (data & 1);
- m_oki->set_rom_bank(m_okibank);
- }
+ m_okibank = (m_okibank & 2) | (data & 1);
+ m_oki->set_rom_bank(m_okibank);
}
-WRITE16_MEMBER(ddenlovr_state::quiz365_oki_bank2_w )
+WRITE8_MEMBER(ddenlovr_state::quiz365_oki_bank2_w )
{
- if (ACCESSING_BITS_0_7)
- {
- m_okibank = (m_okibank & 1) | ((data & 1) << 1);
- m_oki->set_rom_bank(m_okibank);
- }
+ m_okibank = (m_okibank & 1) | ((data & 1) << 1);
+ m_oki->set_rom_bank(m_okibank);
}
@@ -1857,23 +1777,11 @@ WRITE8_MEMBER(ddenlovr_state::ddenlovr_select_w )
m_dsw_sel = data;
}
-WRITE16_MEMBER(ddenlovr_state::ddenlovr_select_16_w)
-{
- if (ACCESSING_BITS_0_7)
- m_dsw_sel = data;
-}
-
WRITE8_MEMBER(ddenlovr_state::ddenlovr_select2_w)
{
m_input_sel = data;
}
-WRITE16_MEMBER(ddenlovr_state::ddenlovr_select2_16_w)
-{
- if (ACCESSING_BITS_0_7)
- m_input_sel = data;
-}
-
READ8_MEMBER(ddenlovr_state::rongrong_input2_r)
{
// logerror("%04x: input2_r offset %d select %x\n", space.device().safe_pc(), offset, m_input_sel);
@@ -1933,15 +1841,12 @@ READ8_MEMBER(ddenlovr_state::rongrong_blitter_busy_r)
}
-WRITE16_MEMBER(ddenlovr_state::quiz365_coincounter_w)
+WRITE8_MEMBER(ddenlovr_state::quiz365_coincounter_w)
{
- if (ACCESSING_BITS_0_7)
+ if (m_input_sel == 0x1c)
{
- if (m_input_sel == 0x1c)
- {
- machine().bookkeeping().coin_counter_w(0, ~data & 1);
- machine().bookkeeping().coin_counter_w(1, ~data & 4);
- }
+ machine().bookkeeping().coin_counter_w(0, ~data & 1);
+ machine().bookkeeping().coin_counter_w(1, ~data & 4);
}
}
@@ -1968,25 +1873,25 @@ WRITE16_MEMBER(ddenlovr_state::quiz365_protection_w)
static ADDRESS_MAP_START( quiz365_map, AS_PROGRAM, 16, ddenlovr_state )
AM_RANGE(0x000000, 0x17ffff) AM_ROM // ROM
- AM_RANGE(0x200000, 0x2003ff) AM_WRITE(ddenlovr_palette_w) // Palette
+ AM_RANGE(0x200000, 0x2003ff) AM_WRITE8(rongrong_palette_w, 0x00ff)
AM_RANGE(0x200c02, 0x200c03) AM_READ(quiz365_protection_r) // Protection
AM_RANGE(0x200e0a, 0x200e0d) AM_WRITE(quiz365_protection_w) // Protection
// AM_RANGE(0x201000, 0x2017ff) AM_WRITEONLY // ?
- AM_RANGE(0x300200, 0x300201) AM_WRITE(ddenlovr_select2_16_w)
- AM_RANGE(0x300202, 0x300203) AM_WRITE(quiz365_coincounter_w) // Coin Counters + more stuff written on startup
+ AM_RANGE(0x300200, 0x300201) AM_WRITE8(ddenlovr_select2_w, 0x00ff)
+ AM_RANGE(0x300202, 0x300203) AM_WRITE8(quiz365_coincounter_w, 0x00ff) // Coin Counters + more stuff written on startup
AM_RANGE(0x300204, 0x300207) AM_READ(quiz365_input2_r) //
- AM_RANGE(0x300240, 0x300247) AM_WRITE(ddenlovr16_palette_base_w)
- AM_RANGE(0x300248, 0x30024f) AM_WRITE(ddenlovr16_palette_mask_w)
- AM_RANGE(0x300250, 0x300257) AM_WRITE(ddenlovr16_transparency_pen_w)
- AM_RANGE(0x300258, 0x30025f) AM_WRITE(ddenlovr16_transparency_mask_w)
- AM_RANGE(0x300268, 0x300269) AM_WRITE(ddenlovr16_bgcolor_w)
- AM_RANGE(0x30026a, 0x30026b) AM_WRITE(ddenlovr16_priority_w)
- AM_RANGE(0x30026c, 0x30026d) AM_WRITE(ddenlovr16_layer_enable_w)
+ AM_RANGE(0x300240, 0x300247) AM_WRITE8(ddenlovr_palette_base_w, 0x00ff)
+ AM_RANGE(0x300248, 0x30024f) AM_WRITE8(ddenlovr_palette_mask_w, 0x00ff)
+ AM_RANGE(0x300250, 0x300257) AM_WRITE8(ddenlovr_transparency_pen_w, 0x00ff)
+ AM_RANGE(0x300258, 0x30025f) AM_WRITE8(ddenlovr_transparency_mask_w, 0x00ff)
+ AM_RANGE(0x300268, 0x300269) AM_WRITE8(ddenlovr_bgcolor_w, 0x00ff)
+ AM_RANGE(0x30026a, 0x30026b) AM_WRITE8(ddenlovr_priority_w, 0x00ff)
+ AM_RANGE(0x30026c, 0x30026d) AM_WRITE8(ddenlovr_layer_enable_w, 0x00ff)
AM_RANGE(0x300270, 0x300271) AM_READ(unk16_r) // ? must be 78 on startup (not necessary in ddlover)
- AM_RANGE(0x300280, 0x300283) AM_WRITE(ddenlovr_blitter_w)
+ AM_RANGE(0x300280, 0x300283) AM_WRITE8(ddenlovr_blitter_w, 0x00ff)
AM_RANGE(0x300286, 0x300287) AM_READ(ddenlovr_gfxrom_r) // Video Chip
AM_RANGE(0x3002c0, 0x3002c1) AM_DEVREADWRITE8("oki", okim6295_device, read, write, 0x00ff)// Sound
@@ -1994,9 +1899,9 @@ static ADDRESS_MAP_START( quiz365_map, AS_PROGRAM, 16, ddenlovr_state )
AM_RANGE(0x300340, 0x30035f) AM_DEVREADWRITE8("rtc", msm6242_device, read, write,0x00ff)
AM_RANGE(0x300380, 0x300383) AM_DEVWRITE8("aysnd", ay8910_device, address_data_w, 0x00ff)
AM_RANGE(0x300384, 0x300385) AM_DEVREAD8("aysnd", ay8910_device, data_r, 0x00ff)
- AM_RANGE(0x3003c2, 0x3003c3) AM_WRITE(quiz365_oki_bank1_w)
- AM_RANGE(0x3003ca, 0x3003cb) AM_WRITE(ddenlovr_blitter_irq_ack_w) // Blitter irq acknowledge
- AM_RANGE(0x3003cc, 0x3003cd) AM_WRITE(quiz365_oki_bank2_w)
+ AM_RANGE(0x3003c2, 0x3003c3) AM_WRITE8(quiz365_oki_bank1_w, 0x00ff)
+ AM_RANGE(0x3003ca, 0x3003cb) AM_WRITE8(ddenlovr_blitter_irq_ack_w, 0x00ff)
+ AM_RANGE(0x3003cc, 0x3003cd) AM_WRITE8(quiz365_oki_bank2_w, 0x00ff)
AM_RANGE(0xff0000, 0xffffff) AM_RAM // RAM
ADDRESS_MAP_END
@@ -2011,14 +1916,11 @@ READ16_MEMBER(ddenlovr_state::ddenlovj_dsw_r)
return dsw;
}
-WRITE16_MEMBER(ddenlovr_state::ddenlovj_coincounter_w)
+WRITE8_MEMBER(ddenlovr_state::ddenlovj_coincounter_w)
{
- if (ACCESSING_BITS_0_7)
- {
- machine().bookkeeping().coin_counter_w(0, data & 0x01);
- machine().bookkeeping().coin_counter_w(1, data & 0x04);
- // data & 0x80 ?
- }
+ machine().bookkeeping().coin_counter_w(0, data & 0x01);
+ machine().bookkeeping().coin_counter_w(1, data & 0x04);
+ // data & 0x80 ?
}
CUSTOM_INPUT_MEMBER(ddenlovr_state::ddenlovj_blitter_r)
@@ -2029,18 +1931,18 @@ CUSTOM_INPUT_MEMBER(ddenlovr_state::ddenlovj_blitter_r)
static ADDRESS_MAP_START( ddenlovj_map, AS_PROGRAM, 16, ddenlovr_state )
AM_RANGE(0x000000, 0x07ffff) AM_ROM // ROM
- AM_RANGE(0x200000, 0x2003ff) AM_WRITE(ddenlovr_palette_w) // Palette
+ AM_RANGE(0x200000, 0x2003ff) AM_WRITE8(rongrong_palette_w, 0x00ff)
// AM_RANGE(0x201000, 0x2017ff) AM_WRITEONLY // ? B0 on startup, then 00
- AM_RANGE(0x300040, 0x300047) AM_WRITE(ddenlovr16_palette_base_w)
- AM_RANGE(0x300048, 0x30004f) AM_WRITE(ddenlovr16_palette_mask_w)
- AM_RANGE(0x300050, 0x300057) AM_WRITE(ddenlovr16_transparency_pen_w)
- AM_RANGE(0x300058, 0x30005f) AM_WRITE(ddenlovr16_transparency_mask_w)
- AM_RANGE(0x300068, 0x300069) AM_WRITE(ddenlovr16_bgcolor_w)
- AM_RANGE(0x30006a, 0x30006b) AM_WRITE(ddenlovr16_priority_w)
- AM_RANGE(0x30006c, 0x30006d) AM_WRITE(ddenlovr16_layer_enable_w)
+ AM_RANGE(0x300040, 0x300047) AM_WRITE8(ddenlovr_palette_base_w, 0x00ff)
+ AM_RANGE(0x300048, 0x30004f) AM_WRITE8(ddenlovr_palette_mask_w, 0x00ff)
+ AM_RANGE(0x300050, 0x300057) AM_WRITE8(ddenlovr_transparency_pen_w, 0x00ff)
+ AM_RANGE(0x300058, 0x30005f) AM_WRITE8(ddenlovr_transparency_mask_w, 0x00ff)
+ AM_RANGE(0x300068, 0x300069) AM_WRITE8(ddenlovr_bgcolor_w, 0x00ff)
+ AM_RANGE(0x30006a, 0x30006b) AM_WRITE8(ddenlovr_priority_w, 0x00ff)
+ AM_RANGE(0x30006c, 0x30006d) AM_WRITE8(ddenlovr_layer_enable_w, 0x00ff)
AM_RANGE(0x300070, 0x300071) AM_READ(unk16_r) // ? must be 78 on startup (not necessary in ddlover)
- AM_RANGE(0x300080, 0x300083) AM_WRITE(ddenlovr_blitter_w)
+ AM_RANGE(0x300080, 0x300083) AM_WRITE8(ddenlovr_blitter_w, 0x00ff)
AM_RANGE(0x300086, 0x300087) AM_READ(ddenlovr_gfxrom_r) // Video Chip
AM_RANGE(0x3000c0, 0x3000c3) AM_DEVWRITE8("ym2413", ym2413_device, write, 0x00ff)
AM_RANGE(0x300100, 0x30011f) AM_DEVREADWRITE8("rtc", msm6242_device, read, write,0x00ff)
@@ -2049,10 +1951,10 @@ static ADDRESS_MAP_START( ddenlovj_map, AS_PROGRAM, 16, ddenlovr_state )
AM_RANGE(0x300182, 0x300183) AM_READ_PORT("P2")
AM_RANGE(0x300184, 0x300185) AM_READ_PORT("SYSTEM")
AM_RANGE(0x300186, 0x300187) AM_READ(ddenlovj_dsw_r) // DSW
- AM_RANGE(0x300188, 0x300189) AM_WRITE(ddenlovj_coincounter_w) // Coin Counters
+ AM_RANGE(0x300188, 0x300189) AM_WRITE8(ddenlovj_coincounter_w, 0x00ff)
AM_RANGE(0x30018a, 0x30018b) AM_WRITEONLY AM_SHARE("dsw_sel16") // DSW select
- AM_RANGE(0x30018c, 0x30018d) AM_WRITE(ddenlovr_oki_bank_w)
- AM_RANGE(0x3001ca, 0x3001cb) AM_WRITE(ddenlovr_blitter_irq_ack_w) // Blitter irq acknowledge
+ AM_RANGE(0x30018c, 0x30018d) AM_WRITE8(ddenlovr_oki_bank_w, 0x00ff)
+ AM_RANGE(0x3001ca, 0x3001cb) AM_WRITE8(ddenlovr_blitter_irq_ack_w, 0x00ff)
AM_RANGE(0x300240, 0x300241) AM_DEVREADWRITE8("oki", okim6295_device, read, write, 0x00ff)// Sound
AM_RANGE(0xff0000, 0xffffff) AM_RAM // RAM
ADDRESS_MAP_END
@@ -2087,27 +1989,27 @@ static ADDRESS_MAP_START( ddenlovrk_map, AS_PROGRAM, 16, ddenlovr_state )
AM_RANGE(0x100000, 0x100001) AM_RAM_READ(ddenlovrk_protection1_r) AM_SHARE("protection1")
AM_RANGE(0x200000, 0x200001) AM_READWRITE(ddenlovrk_protection2_r, ddenlovrk_protection2_w) AM_SHARE("protection2")
- AM_RANGE(0xd00000, 0xd003ff) AM_WRITE(ddenlovr_palette_w) // Palette
+ AM_RANGE(0xd00000, 0xd003ff) AM_WRITE8(rongrong_palette_w, 0x00ff)
// AM_RANGE(0xd01000, 0xd017ff) AM_RAM // ? B0 on startup, then 00
- AM_RANGE(0xe00040, 0xe00047) AM_WRITE(ddenlovr16_palette_base_w)
- AM_RANGE(0xe00048, 0xe0004f) AM_WRITE(ddenlovr16_palette_mask_w)
- AM_RANGE(0xe00050, 0xe00057) AM_WRITE(ddenlovr16_transparency_pen_w)
- AM_RANGE(0xe00058, 0xe0005f) AM_WRITE(ddenlovr16_transparency_mask_w)
- AM_RANGE(0xe00068, 0xe00069) AM_WRITE(ddenlovr16_bgcolor_w)
- AM_RANGE(0xe0006a, 0xe0006b) AM_WRITE(ddenlovr16_priority_w)
- AM_RANGE(0xe0006c, 0xe0006d) AM_WRITE(ddenlovr16_layer_enable_w)
+ AM_RANGE(0xe00040, 0xe00047) AM_WRITE8(ddenlovr_palette_base_w, 0x00ff)
+ AM_RANGE(0xe00048, 0xe0004f) AM_WRITE8(ddenlovr_palette_mask_w, 0x00ff)
+ AM_RANGE(0xe00050, 0xe00057) AM_WRITE8(ddenlovr_transparency_pen_w, 0x00ff)
+ AM_RANGE(0xe00058, 0xe0005f) AM_WRITE8(ddenlovr_transparency_mask_w, 0x00ff)
+ AM_RANGE(0xe00068, 0xe00069) AM_WRITE8(ddenlovr_bgcolor_w, 0x00ff)
+ AM_RANGE(0xe0006a, 0xe0006b) AM_WRITE8(ddenlovr_priority_w, 0x00ff)
+ AM_RANGE(0xe0006c, 0xe0006d) AM_WRITE8(ddenlovr_layer_enable_w, 0x00ff)
AM_RANGE(0xe00070, 0xe00071) AM_READNOP
- AM_RANGE(0xe00080, 0xe00083) AM_WRITE(ddenlovr_blitter_w)
+ AM_RANGE(0xe00080, 0xe00083) AM_WRITE8(ddenlovr_blitter_w, 0x00ff)
AM_RANGE(0xe00086, 0xe00087) AM_READ(ddenlovr_gfxrom_r) // Video Chip
AM_RANGE(0xe00100, 0xe00101) AM_READ_PORT("P1")
AM_RANGE(0xe00102, 0xe00103) AM_READ_PORT("P2")
AM_RANGE(0xe00104, 0xe00105) AM_READ_PORT("SYSTEM")
AM_RANGE(0xe00200, 0xe00201) AM_READ_PORT("DSW")
- AM_RANGE(0xe00302, 0xe00303) AM_WRITE(ddenlovr_blitter_irq_ack_w) // Blitter irq acknowledge
- AM_RANGE(0xe00308, 0xe00309) AM_WRITE(ddenlovr_coincounter_0_w) // Coin Counters
- AM_RANGE(0xe0030c, 0xe0030d) AM_WRITE(ddenlovr_coincounter_1_w) //
+ AM_RANGE(0xe00302, 0xe00303) AM_WRITE8(ddenlovr_blitter_irq_ack_w, 0x00ff)
+ AM_RANGE(0xe00308, 0xe00309) AM_WRITE8(ddenlovr_coincounter_0_w, 0x00ff)
+ AM_RANGE(0xe0030c, 0xe0030d) AM_WRITE8(ddenlovr_coincounter_1_w, 0x00ff)
AM_RANGE(0xe00400, 0xe00403) AM_DEVWRITE8("ym2413", ym2413_device, write, 0x00ff)
AM_RANGE(0xe00500, 0xe0051f) AM_DEVREADWRITE8("rtc", msm6242_device, read, write,0x00ff)
@@ -2123,29 +2025,29 @@ ADDRESS_MAP_END
static ADDRESS_MAP_START( ddenlovr_map, AS_PROGRAM, 16, ddenlovr_state )
AM_RANGE(0x000000, 0x07ffff) AM_ROM // ROM
- AM_RANGE(0x300000, 0x300001) AM_WRITE( ddenlovr_oki_bank_w)
+ AM_RANGE(0x300000, 0x300001) AM_WRITE8(ddenlovr_oki_bank_w, 0x00ff)
- AM_RANGE(0xd00000, 0xd003ff) AM_WRITE(ddenlovr_palette_w) // Palette
+ AM_RANGE(0xd00000, 0xd003ff) AM_WRITE8(rongrong_palette_w, 0x00ff)
// AM_RANGE(0xd01000, 0xd017ff) AM_RAM // ? B0 on startup, then 00
- AM_RANGE(0xe00040, 0xe00047) AM_WRITE(ddenlovr16_palette_base_w)
- AM_RANGE(0xe00048, 0xe0004f) AM_WRITE(ddenlovr16_palette_mask_w)
- AM_RANGE(0xe00050, 0xe00057) AM_WRITE(ddenlovr16_transparency_pen_w)
- AM_RANGE(0xe00058, 0xe0005f) AM_WRITE(ddenlovr16_transparency_mask_w)
- AM_RANGE(0xe00068, 0xe00069) AM_WRITE(ddenlovr16_bgcolor_w)
- AM_RANGE(0xe0006a, 0xe0006b) AM_WRITE(ddenlovr16_priority_w)
- AM_RANGE(0xe0006c, 0xe0006d) AM_WRITE(ddenlovr16_layer_enable_w)
+ AM_RANGE(0xe00040, 0xe00047) AM_WRITE8(ddenlovr_palette_base_w, 0x00ff)
+ AM_RANGE(0xe00048, 0xe0004f) AM_WRITE8(ddenlovr_palette_mask_w, 0x00ff)
+ AM_RANGE(0xe00050, 0xe00057) AM_WRITE8(ddenlovr_transparency_pen_w, 0x00ff)
+ AM_RANGE(0xe00058, 0xe0005f) AM_WRITE8(ddenlovr_transparency_mask_w, 0x00ff)
+ AM_RANGE(0xe00068, 0xe00069) AM_WRITE8(ddenlovr_bgcolor_w, 0x00ff)
+ AM_RANGE(0xe0006a, 0xe0006b) AM_WRITE8(ddenlovr_priority_w, 0x00ff)
+ AM_RANGE(0xe0006c, 0xe0006d) AM_WRITE8(ddenlovr_layer_enable_w, 0x00ff)
AM_RANGE(0xe00070, 0xe00071) AM_READ(unk16_r) // ? must be 78 on startup (not necessary in ddlover)
- AM_RANGE(0xe00080, 0xe00083) AM_WRITE(ddenlovr_blitter_w)
+ AM_RANGE(0xe00080, 0xe00083) AM_WRITE8(ddenlovr_blitter_w, 0x00ff)
AM_RANGE(0xe00086, 0xe00087) AM_READ(ddenlovr_gfxrom_r) // Video Chip
AM_RANGE(0xe00100, 0xe00101) AM_READ_PORT("P1")
AM_RANGE(0xe00102, 0xe00103) AM_READ_PORT("P2")
AM_RANGE(0xe00104, 0xe00105) AM_READ_PORT("SYSTEM")
AM_RANGE(0xe00200, 0xe00201) AM_READ_PORT("DSW")
- AM_RANGE(0xe00302, 0xe00303) AM_WRITE(ddenlovr_blitter_irq_ack_w) // Blitter irq acknowledge
- AM_RANGE(0xe00308, 0xe00309) AM_WRITE(ddenlovr_coincounter_0_w) // Coin Counters
- AM_RANGE(0xe0030c, 0xe0030d) AM_WRITE(ddenlovr_coincounter_1_w) //
+ AM_RANGE(0xe00302, 0xe00303) AM_WRITE8(ddenlovr_blitter_irq_ack_w, 0x00ff)
+ AM_RANGE(0xe00308, 0xe00309) AM_WRITE8(ddenlovr_coincounter_0_w, 0x00ff)
+ AM_RANGE(0xe0030c, 0xe0030d) AM_WRITE8(ddenlovr_coincounter_1_w, 0x00ff)
AM_RANGE(0xe00400, 0xe00403) AM_DEVWRITE8("ym2413", ym2413_device, write, 0x00ff)
AM_RANGE(0xe00500, 0xe0051f) AM_DEVREADWRITE8("rtc", msm6242_device, read, write,0x00ff)
@@ -2185,41 +2087,35 @@ READ16_MEMBER(ddenlovr_state::nettoqc_protection1_r)
}
}
-WRITE16_MEMBER(ddenlovr_state::nettoqc_coincounter_w)
+WRITE8_MEMBER(ddenlovr_state::nettoqc_coincounter_w)
{
- if (ACCESSING_BITS_0_7)
- {
- machine().bookkeeping().coin_counter_w(0, data & 0x01);
- machine().bookkeeping().coin_counter_w(1, data & 0x04);
- // data & 0x80 ?
- }
+ machine().bookkeeping().coin_counter_w(0, data & 0x01);
+ machine().bookkeeping().coin_counter_w(1, data & 0x04);
+ // data & 0x80 ?
}
-WRITE16_MEMBER(ddenlovr_state::nettoqc_oki_bank_w )
+WRITE8_MEMBER(ddenlovr_state::nettoqc_oki_bank_w )
{
- if (ACCESSING_BITS_0_7)
- {
- m_oki->set_rom_bank(data & 3);
- }
+ m_oki->set_rom_bank(data & 3);
}
static ADDRESS_MAP_START( nettoqc_map, AS_PROGRAM, 16, ddenlovr_state )
AM_RANGE(0x000000, 0x17ffff) AM_ROM // ROM
- AM_RANGE(0x200000, 0x2003ff) AM_WRITE(ddenlovr_palette_w) // Palette
+ AM_RANGE(0x200000, 0x2003ff) AM_WRITE8(rongrong_palette_w, 0x00ff)
AM_RANGE(0x200c02, 0x200c03) AM_READ(nettoqc_protection1_r) // Protection 1
AM_RANGE(0x200e0a, 0x200e0d) AM_WRITEONLY AM_SHARE("protection1") // ""
AM_RANGE(0x201000, 0x2017ff) AM_WRITEONLY // ?
- AM_RANGE(0x300040, 0x300047) AM_WRITE(ddenlovr16_palette_base_w)
- AM_RANGE(0x300048, 0x30004f) AM_WRITE(ddenlovr16_palette_mask_w)
- AM_RANGE(0x300050, 0x300057) AM_WRITE(ddenlovr16_transparency_pen_w)
- AM_RANGE(0x300058, 0x30005f) AM_WRITE(ddenlovr16_transparency_mask_w)
- AM_RANGE(0x300068, 0x300069) AM_WRITE(ddenlovr16_bgcolor_w)
- AM_RANGE(0x30006a, 0x30006b) AM_WRITE(ddenlovr16_priority_w)
- AM_RANGE(0x30006c, 0x30006d) AM_WRITE(ddenlovr16_layer_enable_w)
+ AM_RANGE(0x300040, 0x300047) AM_WRITE8(ddenlovr_palette_base_w, 0x00ff)
+ AM_RANGE(0x300048, 0x30004f) AM_WRITE8(ddenlovr_palette_mask_w, 0x00ff)
+ AM_RANGE(0x300050, 0x300057) AM_WRITE8(ddenlovr_transparency_pen_w, 0x00ff)
+ AM_RANGE(0x300058, 0x30005f) AM_WRITE8(ddenlovr_transparency_mask_w, 0x00ff)
+ AM_RANGE(0x300068, 0x300069) AM_WRITE8(ddenlovr_bgcolor_w, 0x00ff)
+ AM_RANGE(0x30006a, 0x30006b) AM_WRITE8(ddenlovr_priority_w, 0x00ff)
+ AM_RANGE(0x30006c, 0x30006d) AM_WRITE8(ddenlovr_layer_enable_w, 0x00ff)
AM_RANGE(0x300070, 0x300071) AM_READ(unk16_r) // ? must be 78 on startup (not necessary in ddlover)
- AM_RANGE(0x300080, 0x300083) AM_WRITE(ddenlovr_blitter_w)
+ AM_RANGE(0x300080, 0x300083) AM_WRITE8(ddenlovr_blitter_w, 0x00ff)
AM_RANGE(0x300086, 0x300087) AM_READ(ddenlovr_gfxrom_r) // Video Chip
AM_RANGE(0x3000c0, 0x3000c3) AM_DEVWRITE8("ym2413", ym2413_device, write, 0x00ff)
AM_RANGE(0x300100, 0x30011f) AM_DEVREADWRITE8("rtc", msm6242_device, read, write,0x00ff)
@@ -2228,10 +2124,10 @@ static ADDRESS_MAP_START( nettoqc_map, AS_PROGRAM, 16, ddenlovr_state )
AM_RANGE(0x300182, 0x300183) AM_READ_PORT("P2")
AM_RANGE(0x300184, 0x300185) AM_READ_PORT("SYSTEM")
AM_RANGE(0x300186, 0x300187) AM_READ(nettoqc_input_r) // DSW's
- AM_RANGE(0x300188, 0x300189) AM_WRITE(nettoqc_coincounter_w) // Coin Counters
- AM_RANGE(0x30018a, 0x30018b) AM_WRITE(ddenlovr_select_16_w) //
- AM_RANGE(0x30018c, 0x30018d) AM_WRITE(nettoqc_oki_bank_w)
- AM_RANGE(0x3001ca, 0x3001cb) AM_WRITE(ddenlovr_blitter_irq_ack_w) // Blitter irq acknowledge
+ AM_RANGE(0x300188, 0x300189) AM_WRITE8(nettoqc_coincounter_w, 0x00ff)
+ AM_RANGE(0x30018a, 0x30018b) AM_WRITE8(ddenlovr_select_w, 0x00ff)
+ AM_RANGE(0x30018c, 0x30018d) AM_WRITE8(nettoqc_oki_bank_w, 0x00ff)
+ AM_RANGE(0x3001ca, 0x3001cb) AM_WRITE8(ddenlovr_blitter_irq_ack_w, 0x00ff)
AM_RANGE(0x300240, 0x300241) AM_DEVREADWRITE8("oki", okim6295_device, read, write, 0x00ff) // Sound
AM_RANGE(0xff0000, 0xffffff) AM_RAM // RAM
ADDRESS_MAP_END
@@ -2258,31 +2154,31 @@ static ADDRESS_MAP_START( ultrchmp_map, AS_PROGRAM, 16, ddenlovr_state )
AM_RANGE(0x224680, 0x224681) AM_RAM_READ(ultrchmp_protection2_r) AM_SHARE("protection2") // Protection 2
AM_RANGE(0x313570, 0x313571) AM_WRITE(ultrchmp_protection2_w) // "" + OKI bank
- AM_RANGE(0xd00000, 0xd003ff) AM_WRITE(ddenlovr_palette_w) // Palette
+ AM_RANGE(0xd00000, 0xd003ff) AM_WRITE8(rongrong_palette_w, 0x00ff)
AM_RANGE(0xd00c02, 0xd00c03) AM_READ(nettoqc_protection1_r) // Protection 1
AM_RANGE(0xd00e0a, 0xd00e0d) AM_WRITEONLY AM_SHARE("protection1") // ""
AM_RANGE(0xd01000, 0xd017ff) AM_WRITEONLY // ?
- AM_RANGE(0xe00040, 0xe00047) AM_WRITE(ddenlovr16_palette_base_w)
- AM_RANGE(0xe00048, 0xe0004f) AM_WRITE(ddenlovr16_palette_mask_w)
- AM_RANGE(0xe00050, 0xe00057) AM_WRITE(ddenlovr16_transparency_pen_w)
- AM_RANGE(0xe00058, 0xe0005f) AM_WRITE(ddenlovr16_transparency_mask_w)
- AM_RANGE(0xe00068, 0xe00069) AM_WRITE(ddenlovr16_bgcolor_w)
- AM_RANGE(0xe0006a, 0xe0006b) AM_WRITE(ddenlovr16_priority_w)
- AM_RANGE(0xe0006c, 0xe0006d) AM_WRITE(ddenlovr16_layer_enable_w)
+ AM_RANGE(0xe00040, 0xe00047) AM_WRITE8(ddenlovr_palette_base_w, 0x00ff)
+ AM_RANGE(0xe00048, 0xe0004f) AM_WRITE8(ddenlovr_palette_mask_w, 0x00ff)
+ AM_RANGE(0xe00050, 0xe00057) AM_WRITE8(ddenlovr_transparency_pen_w, 0x00ff)
+ AM_RANGE(0xe00058, 0xe0005f) AM_WRITE8(ddenlovr_transparency_mask_w, 0x00ff)
+ AM_RANGE(0xe00068, 0xe00069) AM_WRITE8(ddenlovr_bgcolor_w, 0x00ff)
+ AM_RANGE(0xe0006a, 0xe0006b) AM_WRITE8(ddenlovr_priority_w, 0x00ff)
+ AM_RANGE(0xe0006c, 0xe0006d) AM_WRITE8(ddenlovr_layer_enable_w, 0x00ff)
AM_RANGE(0xe00070, 0xe00071) AM_READNOP
- AM_RANGE(0xe00080, 0xe00083) AM_WRITE(ddenlovr_blitter_w)
+ AM_RANGE(0xe00080, 0xe00083) AM_WRITE8(ddenlovr_blitter_w, 0x00ff)
AM_RANGE(0xe00086, 0xe00087) AM_READ(ddenlovr_gfxrom_r) // Video Chip
AM_RANGE(0xe00100, 0xe00101) AM_READ_PORT("P1")
AM_RANGE(0xe00102, 0xe00103) AM_READ_PORT("P2")
AM_RANGE(0xe00104, 0xe00105) AM_READ_PORT("SYSTEM")
AM_RANGE(0xe00200, 0xe00201) AM_READ_PORT("DSW")
- AM_RANGE(0xe00302, 0xe00303) AM_WRITE(ddenlovr_blitter_irq_ack_w) // Blitter irq acknowledge
- AM_RANGE(0xe00308, 0xe00309) AM_WRITE(ddenlovr_coincounter_0_w) // Coin Counters
- AM_RANGE(0xe0030c, 0xe0030d) AM_WRITE(ddenlovr_coincounter_1_w) //
+ AM_RANGE(0xe00302, 0xe00303) AM_WRITE8(ddenlovr_blitter_irq_ack_w, 0x00ff)
+ AM_RANGE(0xe00308, 0xe00309) AM_WRITE8(ddenlovr_coincounter_0_w, 0x00ff)
+ AM_RANGE(0xe0030c, 0xe0030d) AM_WRITE8(ddenlovr_coincounter_1_w, 0x00ff)
AM_RANGE(0xe00400, 0xe00403) AM_DEVWRITE8("ym2413", ym2413_device, write, 0x00ff)
AM_RANGE(0xe00500, 0xe0051f) AM_DEVREADWRITE8("rtc", msm6242_device, read, write,0x00ff)
@@ -3749,18 +3645,18 @@ static ADDRESS_MAP_START( akamaru_map, AS_PROGRAM, 16, ddenlovr_state )
AM_RANGE(0x213570, 0x213571) AM_WRITE(akamaru_protection1_w) // OKI bank
AM_RANGE(0x624680, 0x624681) AM_READ(akamaru_protection1_r)
- AM_RANGE(0xd00000, 0xd003ff) AM_WRITE(ddenlovr_palette_w) // Palette
+ AM_RANGE(0xd00000, 0xd003ff) AM_WRITE8(rongrong_palette_w, 0x00ff)
// AM_RANGE(0xd01000, 0xd017ff) AM_WRITEONLY // 0
- AM_RANGE(0xe00040, 0xe00047) AM_WRITE(ddenlovr16_palette_base_w)
- AM_RANGE(0xe00048, 0xe0004f) AM_WRITE(ddenlovr16_palette_mask_w)
- AM_RANGE(0xe00050, 0xe00057) AM_WRITE(ddenlovr16_transparency_pen_w)
- AM_RANGE(0xe00058, 0xe0005f) AM_WRITE(ddenlovr16_transparency_mask_w)
- AM_RANGE(0xe00068, 0xe00069) AM_WRITE(ddenlovr16_bgcolor_w)
- AM_RANGE(0xe0006a, 0xe0006b) AM_WRITE(ddenlovr16_priority_w)
- AM_RANGE(0xe0006c, 0xe0006d) AM_WRITE(ddenlovr16_layer_enable_w)
+ AM_RANGE(0xe00040, 0xe00047) AM_WRITE8(ddenlovr_palette_base_w, 0x00ff)
+ AM_RANGE(0xe00048, 0xe0004f) AM_WRITE8(ddenlovr_palette_mask_w, 0x00ff)
+ AM_RANGE(0xe00050, 0xe00057) AM_WRITE8(ddenlovr_transparency_pen_w, 0x00ff)
+ AM_RANGE(0xe00058, 0xe0005f) AM_WRITE8(ddenlovr_transparency_mask_w, 0x00ff)
+ AM_RANGE(0xe00068, 0xe00069) AM_WRITE8(ddenlovr_bgcolor_w, 0x00ff)
+ AM_RANGE(0xe0006a, 0xe0006b) AM_WRITE8(ddenlovr_priority_w, 0x00ff)
+ AM_RANGE(0xe0006c, 0xe0006d) AM_WRITE8(ddenlovr_bgcolor_w, 0x00ff)
AM_RANGE(0xe00070, 0xe00071) AM_READ(unk16_r) // ? must be 78 on startup (not necessary in ddlover)
- AM_RANGE(0xe00080, 0xe00083) AM_WRITE(ddenlovr_blitter_w)
+ AM_RANGE(0xe00080, 0xe00083) AM_WRITE8(ddenlovr_blitter_w, 0x00ff)
AM_RANGE(0xe00086, 0xe00087) AM_READ(ddenlovr_gfxrom_r) // Video Chip
AM_RANGE(0xe00100, 0xe00101) AM_READ_PORT("P1")
@@ -3774,11 +3670,11 @@ static ADDRESS_MAP_START( akamaru_map, AS_PROGRAM, 16, ddenlovr_state )
AM_RANGE(0xe00200, 0xe00201) AM_READ(akamaru_dsw_r) // DSW
AM_RANGE(0xe00204, 0xe00205) AM_READ(akamaru_blitter_r) // Blitter Busy & IRQ
- AM_RANGE(0xe00302, 0xe00303) AM_WRITE(ddenlovr_blitter_irq_ack_w) // Blitter irq acknowledge
+ AM_RANGE(0xe00302, 0xe00303) AM_WRITE8(ddenlovr_blitter_irq_ack_w, 0x00ff)
AM_RANGE(0xe00304, 0xe00307) AM_WRITEONLY AM_SHARE("dsw_sel16") // DSW select
- AM_RANGE(0xe00308, 0xe00309) AM_WRITE(ddenlovr_coincounter_0_w) // Coin Counters
- AM_RANGE(0xe0030c, 0xe0030d) AM_WRITE(ddenlovr_coincounter_1_w) //
+ AM_RANGE(0xe00308, 0xe00309) AM_WRITE8(ddenlovr_coincounter_0_w, 0x00ff)
+ AM_RANGE(0xe0030c, 0xe0030d) AM_WRITE8(ddenlovr_coincounter_1_w, 0x00ff)
AM_RANGE(0xe00400, 0xe00403) AM_DEVWRITE8("ym2413", ym2413_device, write, 0x00ff)
AM_RANGE(0xe00500, 0xe0051f) AM_DEVREADWRITE8("rtc", msm6242_device, read, write, 0x00ff)
diff --git a/src/mame/drivers/dec0.cpp b/src/mame/drivers/dec0.cpp
index cc797e27313..11b387ccca6 100644
--- a/src/mame/drivers/dec0.cpp
+++ b/src/mame/drivers/dec0.cpp
@@ -229,10 +229,7 @@ WRITE16_MEMBER(dec0_automat_state::automat_control_w)
{
case 0xe: /* z80 sound cpu */
if (ACCESSING_BITS_0_7)
- {
m_soundlatch->write(space, 0, data & 0xff);
- m_audiocpu->set_input_line(0, HOLD_LINE);
- }
break;
case 12: /* DMA flag */
@@ -282,15 +279,6 @@ WRITE16_MEMBER(dec0_state::midres_sound_w)
}
}
-WRITE16_MEMBER(dec0_automat_state::secretab_sound_w)
-{
- if (ACCESSING_BITS_0_7)
- {
- m_soundlatch->write(space, 0, data & 0xff);
- m_audiocpu->set_input_line(0, HOLD_LINE);
- }
-}
-
/******************************************************************************/
static ADDRESS_MAP_START( dec0_map, AS_PROGRAM, 16, dec0_state )
@@ -621,7 +609,7 @@ static ADDRESS_MAP_START( secretab_map, AS_PROGRAM, 16, dec0_automat_state )
// AM_RANGE(0x340400, 0x3407ff) AM_DEVREADWRITE("tilegen1", deco_bac06_device, pf_rowscroll_r, pf_rowscroll_w)
AM_RANGE(0x314008, 0x31400f) AM_READ(slyspy_controls_r)
- AM_RANGE(0x314000, 0x314001) AM_WRITE(secretab_sound_w)
+ AM_RANGE(0x314000, 0x314001) AM_DEVWRITE8("soundlatch", generic_latch_8_device, write, 0x00ff)
AM_RANGE(0x300000, 0x300007) AM_RAM
AM_RANGE(0x300010, 0x300017) AM_RAM
@@ -640,7 +628,7 @@ static ADDRESS_MAP_START( automat_s_map, AS_PROGRAM, 8, dec0_automat_state )
AM_RANGE(0xc000, 0xc7ff) AM_RAM
AM_RANGE(0xc800, 0xc801) AM_DEVREADWRITE("2203a", ym2203_device, read, write)
AM_RANGE(0xd000, 0xd001) AM_DEVREADWRITE("2203b", ym2203_device, read, write)
- AM_RANGE(0xd800, 0xd800) AM_READ(sound_command_r)
+ AM_RANGE(0xd800, 0xd800) AM_DEVREAD("soundlatch", generic_latch_8_device, read)
AM_RANGE(0xe000, 0xe000) AM_DEVWRITE("adpcm_select2", ls157_device, ba_w)
AM_RANGE(0xe800, 0xe800) AM_WRITE(sound_bankswitch_w)
AM_RANGE(0xf000, 0xf000) AM_DEVWRITE("adpcm_select1", ls157_device, ba_w)
@@ -652,7 +640,7 @@ static ADDRESS_MAP_START( secretab_s_map, AS_PROGRAM, 8, dec0_automat_state )
AM_RANGE(0xc000, 0xc7ff) AM_RAM
AM_RANGE(0xc800, 0xc801) AM_DEVREADWRITE("2203a", ym2203_device, read, write)
AM_RANGE(0xd000, 0xd001) AM_DEVREADWRITE("ym3812", ym3812_device, read, write)
- AM_RANGE(0xd800, 0xd800) AM_READ(sound_command_r)
+ AM_RANGE(0xd800, 0xd800) AM_DEVREAD("soundlatch", generic_latch_8_device, read)
AM_RANGE(0xe000, 0xe000) AM_DEVWRITE("adpcm_select2", ls157_device, ba_w)
AM_RANGE(0xe800, 0xe800) AM_WRITE(sound_bankswitch_w)
AM_RANGE(0xf000, 0xf000) AM_DEVWRITE("adpcm_select1", ls157_device, ba_w)
@@ -1385,12 +1373,6 @@ static MACHINE_CONFIG_DERIVED( dec1, dec0_base )
MACHINE_CONFIG_END
-READ8_MEMBER(dec0_automat_state::sound_command_r)
-{
- m_audiocpu->set_input_line(0, CLEAR_LINE);
- return m_soundlatch->read(space, 0);
-}
-
WRITE8_MEMBER(dec0_automat_state::sound_bankswitch_w)
{
m_msm1->reset_w(BIT(data, 3));
@@ -1462,6 +1444,7 @@ static MACHINE_CONFIG_START( automat, dec0_automat_state )
MCFG_SPEAKER_STANDARD_MONO("mono")
MCFG_GENERIC_LATCH_8_ADD("soundlatch")
+ MCFG_GENERIC_LATCH_DATA_PENDING_CB(INPUTLINE("audiocpu", 0))
MCFG_SOUND_ADD("2203a", YM2203, 1250000)
MCFG_SOUND_ROUTE(0, "mono", 0.90)
@@ -1536,6 +1519,7 @@ static MACHINE_CONFIG_START( secretab, dec0_automat_state )
MCFG_SPEAKER_STANDARD_MONO("mono")
MCFG_GENERIC_LATCH_8_ADD("soundlatch")
+ MCFG_GENERIC_LATCH_DATA_PENDING_CB(INPUTLINE("audiocpu", 0))
MCFG_SOUND_ADD("2203a", YM2203, 1250000)
MCFG_SOUND_ROUTE(0, "mono", 0.90)
diff --git a/src/mame/drivers/discoboy.cpp b/src/mame/drivers/discoboy.cpp
index 094f359a805..afbf0c69d10 100644
--- a/src/mame/drivers/discoboy.cpp
+++ b/src/mame/drivers/discoboy.cpp
@@ -88,7 +88,6 @@ public:
DECLARE_WRITE8_MEMBER(rambank_select_w);
DECLARE_WRITE8_MEMBER(discoboy_port_00_w);
DECLARE_WRITE8_MEMBER(discoboy_port_01_w);
- DECLARE_WRITE8_MEMBER(discoboy_port_03_w);
DECLARE_WRITE8_MEMBER(discoboy_port_06_w);
DECLARE_WRITE8_MEMBER(rambank_w);
DECLARE_READ8_MEMBER(rambank_r);
@@ -249,14 +248,6 @@ WRITE8_MEMBER(discoboy_state::discoboy_port_01_w)
membank("bank1")->set_entry(data & 0x07);
}
-WRITE8_MEMBER(discoboy_state::discoboy_port_03_w)// sfx? (to sound cpu)
-{
- // printf("unk discoboy_port_03_w %02x\n", data);
- // m_audiocpu->set_input_line(INPUT_LINE_NMI, HOLD_LINE);
- m_soundlatch->write(space, 0, data);
- m_audiocpu->set_input_line(0, HOLD_LINE);
-}
-
WRITE8_MEMBER(discoboy_state::discoboy_port_06_w)
{
//printf("unk discoboy_port_06_w %02x\n",data);
@@ -333,7 +324,7 @@ static ADDRESS_MAP_START( io_map, AS_IO, 8, discoboy_state )
AM_RANGE(0x00, 0x00) AM_READ_PORT("DSWA") AM_WRITE(discoboy_port_00_w)
AM_RANGE(0x01, 0x01) AM_READ_PORT("SYSTEM") AM_WRITE(discoboy_port_01_w)
AM_RANGE(0x02, 0x02) AM_READ_PORT("P1")
- AM_RANGE(0x03, 0x03) AM_READ_PORT("P2") AM_WRITE(discoboy_port_03_w)
+ AM_RANGE(0x03, 0x03) AM_READ_PORT("P2") AM_DEVWRITE("soundlatch", generic_latch_8_device, write)
AM_RANGE(0x04, 0x04) AM_READ_PORT("DSWB")
AM_RANGE(0x06, 0x06) AM_READWRITE(discoboy_port_06_r, discoboy_port_06_w) // ???
AM_RANGE(0x07, 0x07) AM_WRITE(rambank_select_w) // 0x20 is palette bank bit.. others?
@@ -512,6 +503,7 @@ static MACHINE_CONFIG_START( discoboy, discoboy_state )
MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
MCFG_GENERIC_LATCH_8_ADD("soundlatch")
+ MCFG_GENERIC_LATCH_DATA_PENDING_CB(INPUTLINE("audiocpu", 0))
MCFG_SOUND_ADD("ymsnd", YM3812, XTAL_10MHz/4) /* 2.5 MHz? */
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 0.6)
diff --git a/src/mame/drivers/esd16.cpp b/src/mame/drivers/esd16.cpp
index 8fc6444b932..75483cb0372 100644
--- a/src/mame/drivers/esd16.cpp
+++ b/src/mame/drivers/esd16.cpp
@@ -1367,6 +1367,9 @@ ROM_START( tangtang )
ROM_REGION( 0x40000, "oki", 0 ) /* Samples */
ROM_LOAD( "esd4.su10", 0x00000, 0x20000, CRC(f2dfb02d) SHA1(04001488697aad3e5b2d15c9f5a81dc2b7d0952c) )
+
+ ROM_REGION16_BE( 0x80, "eeprom", ROMREGION_ERASE00 ) // default settings because game doesn't init them properly otherwise
+ ROM_LOAD16_WORD_SWAP( "eeprom", 0x0000, 0x0080, CRC(00514989) SHA1(86cdca86ed48962e3bda13f9e6f8e573e176dec0) )
ROM_END
/*
diff --git a/src/mame/drivers/expro02.cpp b/src/mame/drivers/expro02.cpp
index 34911eceb95..71fb2139dc9 100644
--- a/src/mame/drivers/expro02.cpp
+++ b/src/mame/drivers/expro02.cpp
@@ -240,7 +240,7 @@ public:
required_device<kaneko16_sprite_device> m_kaneko_spr;
required_shared_ptr<uint16_t> m_spriteram;
- DECLARE_WRITE16_MEMBER(expro02_6295_bankswitch_w);
+ DECLARE_WRITE8_MEMBER(expro02_6295_bankswitch_w);
DECLARE_DRIVER_INIT(expro02);
virtual void machine_start() override;
@@ -254,7 +254,6 @@ public:
// comad
READ16_MEMBER(comad_timer_r);
READ8_MEMBER(comad_okim6295_r);
- WRITE16_MEMBER(galpanica_6295_bankswitch_w);
};
@@ -617,18 +616,16 @@ static INPUT_PORTS_START( zipzap )
SYSTEM_NO_TILT
INPUT_PORTS_END
+
/*************************************
*
* Sound handlers
*
*************************************/
-WRITE16_MEMBER(expro02_state::expro02_6295_bankswitch_w)
+WRITE8_MEMBER( expro02_state::expro02_6295_bankswitch_w )
{
- if (ACCESSING_BITS_8_15)
- {
- membank("okibank")->set_entry((data >> 8) & 0x0f);
- }
+ membank("okibank")->set_entry(data & 0x0f);
}
@@ -672,7 +669,7 @@ static ADDRESS_MAP_START( expro02_map, AS_PROGRAM, 16, expro02_state )
AM_RANGE(0x800000, 0x800001) AM_READ_PORT("DSW1")
AM_RANGE(0x800002, 0x800003) AM_READ_PORT("DSW2")
AM_RANGE(0x800004, 0x800005) AM_READ_PORT("SYSTEM")
- AM_RANGE(0x900000, 0x900001) AM_WRITE(expro02_6295_bankswitch_w)
+ AM_RANGE(0x900000, 0x900001) AM_WRITE8(expro02_6295_bankswitch_w, 0xff00)
AM_RANGE(0xa00000, 0xa00001) AM_WRITENOP /* ??? */
AM_RANGE(0xc80000, 0xc8ffff) AM_RAM
AM_RANGE(0xe00000, 0xe00015) AM_DEVREADWRITE("calc1_mcu", kaneko_hit_device, kaneko_hit_r,kaneko_hit_w)
@@ -687,7 +684,7 @@ static ADDRESS_MAP_START( fantasia_map, AS_PROGRAM, 16, expro02_state )
AM_RANGE(0x800002, 0x800003) AM_READ_PORT("DSW2")
AM_RANGE(0x800004, 0x800005) AM_READ_PORT("SYSTEM")
AM_RANGE(0x800006, 0x800007) AM_NOP // ? used ?
- AM_RANGE(0x900000, 0x900001) AM_WRITE(expro02_6295_bankswitch_w)
+ AM_RANGE(0x900000, 0x900001) AM_WRITE8(expro02_6295_bankswitch_w, 0xff00)
AM_RANGE(0xa00000, 0xa00001) AM_WRITENOP /* ??? */
AM_RANGE(0xc80000, 0xc8ffff) AM_RAM
AM_RANGE(0xf00000, 0xf00001) AM_DEVREADWRITE8("oki", okim6295_device, read, write, 0xff00)
@@ -704,7 +701,7 @@ static ADDRESS_MAP_START( comad_map, AS_PROGRAM, 16, expro02_state )
// AM_RANGE(0x800006, 0x800007) ??
AM_RANGE(0x80000a, 0x80000b) AM_READ(comad_timer_r) /* bits 8-a = timer? palette update code waits for them to be 111 */
AM_RANGE(0x80000c, 0x80000d) AM_READ(comad_timer_r) /* missw96 bits 8-a = timer? palette update code waits for them to be 111 */
- AM_RANGE(0x900000, 0x900001) AM_WRITE(galpanica_6295_bankswitch_w) /* not sure */
+ AM_RANGE(0x900000, 0x900001) AM_WRITE8(expro02_6295_bankswitch_w, 0xff00) /* not sure */
AM_RANGE(0xc00000, 0xc0ffff) AM_RAM
AM_RANGE(0xc80000, 0xc8ffff) AM_RAM
AM_RANGE(0xf00000, 0xf00001) AM_READ8(comad_okim6295_r, 0xff00) AM_DEVWRITE8("oki", okim6295_device, write, 0xff00) /* fantasia, missw96 */
@@ -719,7 +716,7 @@ static ADDRESS_MAP_START( fantsia2_map, AS_PROGRAM, 16, expro02_state )
AM_RANGE(0x800004, 0x800005) AM_READ_PORT("SYSTEM")
// AM_RANGE(0x800006, 0x800007) ??
AM_RANGE(0x800008, 0x800009) AM_READ(comad_timer_r) /* bits 8-a = timer? palette update code waits for them to be 111 */
- AM_RANGE(0x900000, 0x900001) AM_WRITE(galpanica_6295_bankswitch_w) /* not sure */
+ AM_RANGE(0x900000, 0x900001) AM_WRITE8(expro02_6295_bankswitch_w, 0xff00) /* not sure */
AM_RANGE(0xa00000, 0xa00001) AM_WRITENOP /* coin counters, + ? */
AM_RANGE(0xc80000, 0xc80001) AM_READ8(comad_okim6295_r, 0xff00) AM_DEVWRITE8("oki", okim6295_device, write, 0xff00)
AM_RANGE(0xf80000, 0xf8ffff) AM_RAM
@@ -735,7 +732,7 @@ static ADDRESS_MAP_START( galhustl_map, AS_PROGRAM, 16, expro02_state )
AM_RANGE(0x800000, 0x800001) AM_READ_PORT("DSW1")
AM_RANGE(0x800002, 0x800003) AM_READ_PORT("DSW2")
AM_RANGE(0x800004, 0x800005) AM_READ_PORT("SYSTEM")
- AM_RANGE(0x900000, 0x900001) AM_WRITE(galpanica_6295_bankswitch_w)
+ AM_RANGE(0x900000, 0x900001) AM_WRITE8(expro02_6295_bankswitch_w, 0xff00)
AM_RANGE(0xa00000, 0xa00001) AM_WRITENOP // ?
AM_RANGE(0xd00000, 0xd00001) AM_DEVREADWRITE8("oki", okim6295_device, read, write, 0xff00)
AM_RANGE(0xe80000, 0xe8ffff) AM_RAM
@@ -752,7 +749,7 @@ static ADDRESS_MAP_START( zipzap_map, AS_PROGRAM, 16, expro02_state )
AM_RANGE(0x800000, 0x800001) AM_READ_PORT("DSW1")
AM_RANGE(0x800002, 0x800003) AM_READ_PORT("DSW2")
AM_RANGE(0x800004, 0x800005) AM_READ_PORT("SYSTEM")
- AM_RANGE(0x900000, 0x900001) AM_WRITE(galpanica_6295_bankswitch_w)
+ AM_RANGE(0x900000, 0x900001) AM_WRITE8(expro02_6295_bankswitch_w, 0xff00)
AM_RANGE(0xc00000, 0xc00001) AM_READ8(comad_okim6295_r, 0xff00) AM_DEVWRITE8("oki", okim6295_device, write, 0xff00) /* fantasia, missw96 */
AM_RANGE(0xc80000, 0xc8ffff) AM_RAM // main ram
@@ -770,7 +767,7 @@ static ADDRESS_MAP_START( supmodel_map, AS_PROGRAM, 16, expro02_state )
AM_RANGE(0x800004, 0x800005) AM_READ_PORT("SYSTEM")
AM_RANGE(0x800006, 0x800007) AM_READ(comad_timer_r)
AM_RANGE(0x800008, 0x800009) AM_READ(comad_timer_r)
- AM_RANGE(0x900000, 0x900001) AM_WRITE(galpanica_6295_bankswitch_w) /* not sure */
+ AM_RANGE(0x900000, 0x900001) AM_WRITE8(expro02_6295_bankswitch_w, 0xff00) /* not sure */
AM_RANGE(0xa00000, 0xa00001) AM_WRITENOP
AM_RANGE(0xc80000, 0xc8ffff) AM_RAM
AM_RANGE(0xd80000, 0xd80001) AM_WRITENOP
@@ -788,7 +785,7 @@ static ADDRESS_MAP_START( smissw_map, AS_PROGRAM, 16, expro02_state )
AM_RANGE(0x800004, 0x800005) AM_READ_PORT("SYSTEM")
AM_RANGE(0x800006, 0x800007) AM_READ(comad_timer_r)
AM_RANGE(0x80000e, 0x80000f) AM_READ(comad_timer_r)
- AM_RANGE(0x900000, 0x900001) AM_WRITE(galpanica_6295_bankswitch_w) /* not sure */
+ AM_RANGE(0x900000, 0x900001) AM_WRITE8(expro02_6295_bankswitch_w, 0xff00) /* not sure */
AM_RANGE(0xa00000, 0xa00001) AM_WRITENOP
AM_RANGE(0xc00000, 0xc0ffff) AM_RAM
AM_RANGE(0xd80000, 0xd80001) AM_WRITENOP
@@ -840,15 +837,6 @@ READ8_MEMBER(expro02_state::comad_okim6295_r)
return retvalue;
}
-WRITE16_MEMBER(expro02_state::galpanica_6295_bankswitch_w)
-{
- if (ACCESSING_BITS_8_15)
- {
- membank("okibank")->set_entry((data >> 8) & 0x0f);
- }
-}
-
-
/*************************************
diff --git a/src/mame/drivers/f1gp.cpp b/src/mame/drivers/f1gp.cpp
index dbea85bf3c5..869630702fe 100644
--- a/src/mame/drivers/f1gp.cpp
+++ b/src/mame/drivers/f1gp.cpp
@@ -39,17 +39,14 @@ WRITE8_MEMBER(f1gp_state::f1gp_sh_bankswitch_w)
}
-WRITE16_MEMBER(f1gp_state::sound_command_w)
+WRITE8_MEMBER(f1gp_state::sound_command_w)
{
- if (ACCESSING_BITS_0_7)
- {
- m_pending_command = 1;
- m_soundlatch->write(space, offset, data & 0xff);
- m_audiocpu->set_input_line(INPUT_LINE_NMI, PULSE_LINE);
- }
+ m_pending_command = 1;
+ m_soundlatch->write(space, offset, data & 0xff);
+ m_audiocpu->set_input_line(INPUT_LINE_NMI, PULSE_LINE);
}
-READ16_MEMBER(f1gp_state::command_pending_r)
+READ8_MEMBER(f1gp_state::command_pending_r)
{
return (m_pending_command ? 0xff : 0);
}
@@ -83,8 +80,7 @@ static ADDRESS_MAP_START( f1gp_cpu1_map, AS_PROGRAM, 16, f1gp_state )
AM_RANGE(0xfff004, 0xfff005) AM_READ_PORT("DSW1")
AM_RANGE(0xfff002, 0xfff005) AM_WRITE(f1gp_fgscroll_w)
AM_RANGE(0xfff006, 0xfff007) AM_READ_PORT("DSW2")
- AM_RANGE(0xfff008, 0xfff009) AM_READ(command_pending_r)
- AM_RANGE(0xfff008, 0xfff009) AM_WRITE(sound_command_w)
+ AM_RANGE(0xfff008, 0xfff009) AM_READWRITE8(command_pending_r, sound_command_w, 0x00ff)
AM_RANGE(0xfff040, 0xfff05f) AM_DEVWRITE("k053936", k053936_device, ctrl_w)
AM_RANGE(0xfff050, 0xfff051) AM_READ_PORT("DSW3")
ADDRESS_MAP_END
@@ -103,7 +99,7 @@ static ADDRESS_MAP_START( f1gp2_cpu1_map, AS_PROGRAM, 16, f1gp_state )
// AM_RANGE(0xfff002, 0xfff003) analog wheel?
AM_RANGE(0xfff004, 0xfff005) AM_READ_PORT("DSW1")
AM_RANGE(0xfff006, 0xfff007) AM_READ_PORT("DSW2")
- AM_RANGE(0xfff008, 0xfff009) AM_READWRITE(command_pending_r, sound_command_w)
+ AM_RANGE(0xfff008, 0xfff009) AM_READWRITE8(command_pending_r, sound_command_w, 0x00ff)
AM_RANGE(0xfff00a, 0xfff00b) AM_READ_PORT("DSW3")
AM_RANGE(0xfff020, 0xfff03f) AM_DEVWRITE("k053936", k053936_device, ctrl_w)
AM_RANGE(0xfff044, 0xfff047) AM_WRITE(f1gp_fgscroll_w)
diff --git a/src/mame/drivers/fccpu30.cpp b/src/mame/drivers/fccpu30.cpp
index f07e9e0a5b9..33ea2d70ce7 100644
--- a/src/mame/drivers/fccpu30.cpp
+++ b/src/mame/drivers/fccpu30.cpp
@@ -188,6 +188,9 @@
#include "emu.h"
#include "cpu/m68000/m68000.h"
+#include "bus/vme/vme.h"
+#include "bus/vme/vme_fcisio.h"
+#include "bus/vme/vme_fcscsi.h"
#include "machine/msm6242.h"
#include "machine/ram.h" // For variants that only differs in amount of RAM
#include "machine/scnxx562.h"
@@ -198,15 +201,25 @@
#include "machine/clock.h"
//#include "machine/timekpr.h"
-#define VERBOSE 0
+#define LOG_GENERAL 0x01
+#define LOG_SETUP 0x02
+#define LOG_PRINTF 0x04
+#define LOG_INIT 0x08
+#define LOG_READ 0x10
+#define LOG_INT 0x20
-#define LOGPRINT(x) { do { if (VERBOSE) logerror x; } while (0); }
-#define LOG(x) {} LOGPRINT(x)
-#define LOGINIT(x) {} LOGPRINT(x)
-#define LOGR(x) {}
-#define LOGSETUP(x) {}
-#define LOGINT(x) {}
-#if VERBOSE >= 2
+#define VERBOSE 0 // (LOG_PRINTF | LOG_SETUP | LOG_GENERAL)
+
+#define LOGMASK(mask, ...) do { if (VERBOSE & mask) logerror(__VA_ARGS__); } while (0)
+#define LOGLEVEL(mask, level, ...) do { if ((VERBOSE & mask) >= level) logerror(__VA_ARGS__); } while (0)
+
+#define LOG(...) LOGMASK(LOG_GENERAL, __VA_ARGS__)
+#define LOGSETUP(...) LOGMASK(LOG_SETUP, __VA_ARGS__)
+#define LOGINIT(...) LOGMASK(LOG_INIT, __VA_ARGS__)
+#define LOGR(...) LOGMASK(LOG_READ, __VA_ARGS__)
+#define LOGINT(...) LOGMASK(LOG_INT, __VA_ARGS__)
+
+#if VERBOSE & LOG_PRINTF
#define logerror printf
#endif
@@ -333,7 +346,7 @@ INPUT_PORTS_END
/* Start it up */
void cpu30_state::machine_start ()
{
- LOGINIT(("%s\n", FUNCNAME));
+ LOGINIT("%s\n", FUNCNAME);
save_pointer (NAME (m_sysrom), sizeof(m_sysrom));
save_pointer (NAME (m_sysram), sizeof(m_sysram));
@@ -347,7 +360,7 @@ void cpu30_state::machine_start ()
void cpu30_state::machine_reset ()
{
- LOGINIT(("%s\n", FUNCNAME));
+ LOGINIT("%s\n", FUNCNAME);
/* Reset pointer to bootvector in ROM for bootvector handler bootvect_r */
if (m_sysrom == &m_sysram[0]) /* Condition needed because memory map is not setup first time */
@@ -355,50 +368,50 @@ void cpu30_state::machine_reset ()
}
/* setup board ID */
-DRIVER_INIT_MEMBER( cpu30_state, cpu30x ) { LOGINIT(("%s\n", FUNCNAME)); m_board_id = 0x50; }
-DRIVER_INIT_MEMBER( cpu30_state, cpu30xa ) { LOGINIT(("%s\n", FUNCNAME)); m_board_id = 0x50; }
-DRIVER_INIT_MEMBER( cpu30_state, cpu30za ) { LOGINIT(("%s\n", FUNCNAME)); m_board_id = 0x50; }
-DRIVER_INIT_MEMBER( cpu30_state, cpu30zbe ) { LOGINIT(("%s\n", FUNCNAME)); m_board_id = 0x50; }
-DRIVER_INIT_MEMBER( cpu30_state, cpu30be8 ) { LOGINIT(("%s\n", FUNCNAME)); m_board_id = 0x50; }
-DRIVER_INIT_MEMBER( cpu30_state, cpu30be16 ) { LOGINIT(("%s\n", FUNCNAME)); m_board_id = 0x50; }
-DRIVER_INIT_MEMBER( cpu30_state, cpu30lite4 ) { LOGINIT(("%s\n", FUNCNAME)); m_board_id = 0x50; }
-DRIVER_INIT_MEMBER( cpu30_state, cpu30lite8 ) { LOGINIT(("%s\n", FUNCNAME)); m_board_id = 0x50; }
-DRIVER_INIT_MEMBER( cpu30_state, cpu33 ) { LOGINIT(("%s\n", FUNCNAME)); m_board_id = 0x68; } // 0x60 skips FGA prompt
+DRIVER_INIT_MEMBER( cpu30_state, cpu30x ) { LOGINIT("%s\n", FUNCNAME); m_board_id = 0x50; }
+DRIVER_INIT_MEMBER( cpu30_state, cpu30xa ) { LOGINIT("%s\n", FUNCNAME); m_board_id = 0x50; }
+DRIVER_INIT_MEMBER( cpu30_state, cpu30za ) { LOGINIT("%s\n", FUNCNAME); m_board_id = 0x50; }
+DRIVER_INIT_MEMBER( cpu30_state, cpu30zbe ) { LOGINIT("%s\n", FUNCNAME); m_board_id = 0x50; }
+DRIVER_INIT_MEMBER( cpu30_state, cpu30be8 ) { LOGINIT("%s\n", FUNCNAME); m_board_id = 0x50; }
+DRIVER_INIT_MEMBER( cpu30_state, cpu30be16 ) { LOGINIT("%s\n", FUNCNAME); m_board_id = 0x50; }
+DRIVER_INIT_MEMBER( cpu30_state, cpu30lite4 ) { LOGINIT("%s\n", FUNCNAME); m_board_id = 0x50; }
+DRIVER_INIT_MEMBER( cpu30_state, cpu30lite8 ) { LOGINIT("%s\n", FUNCNAME); m_board_id = 0x50; }
+DRIVER_INIT_MEMBER( cpu30_state, cpu33 ) { LOGINIT("%s\n", FUNCNAME); m_board_id = 0x68; } // 0x60 skips FGA prompt
/* Mock FDC driver */
READ8_MEMBER (cpu30_state::fdc_r){
- LOG(("%s\n * FDC read Offset: %04x\n", FUNCNAME, offset));
+ LOG("%s\n * FDC read Offset: %04x\n", FUNCNAME, offset);
return 1;
}
WRITE8_MEMBER (cpu30_state::fdc_w){
- LOG(("%s\n * FDC write Offset: %04x Data: %02x\n", FUNCNAME, offset, data));
+ LOG("%s\n * FDC write Offset: %04x Data: %02x\n", FUNCNAME, offset, data);
}
/* Mock SCSI driver */
READ8_MEMBER (cpu30_state::scsi_r){
- LOG(("%s\n * SCSI read Offset: %04x\n", FUNCNAME, offset));
+ LOG("%s\n * SCSI read Offset: %04x\n", FUNCNAME, offset);
return 1;
}
WRITE8_MEMBER (cpu30_state::scsi_w){
- LOG(("%s\n * SCSI write Offset: %04x Data: %02x\n", FUNCNAME, offset, data));
+ LOG("%s\n * SCSI write Offset: %04x Data: %02x\n", FUNCNAME, offset, data);
}
/* 1 = board is in slot 1, 0 = board is NOT in slot 1 */
READ8_MEMBER (cpu30_state::slot1_status_r){
- LOG(("%s\n", FUNCNAME));
+ LOG("%s\n", FUNCNAME);
return 1;
}
/* Boot vector handler, the PCB hardwires the first 8 bytes from 0xff800000 to 0x0 at reset*/
READ32_MEMBER (cpu30_state::bootvect_r){
- LOG(("%s\n", FUNCNAME));
+ LOG("%s\n", FUNCNAME);
return m_sysrom[offset];
}
WRITE32_MEMBER (cpu30_state::bootvect_w){
- LOG(("%s\n", FUNCNAME));
+ LOG("%s\n", FUNCNAME);
m_sysram[offset % sizeof(m_sysram)] &= ~mem_mask;
m_sysram[offset % sizeof(m_sysram)] |= (data & mem_mask);
m_sysrom = &m_sysram[0]; // redirect all upcomming accesses to masking RAM until reset.
@@ -459,42 +472,42 @@ WRITE32_MEMBER (cpu30_state::bootvect_w){
* "To start VMEPROM, the rotary switches must both be set to 'F':" Hmm...
*/
READ8_MEMBER (cpu30_state::rotary_rd){
- LOG(("%s\n", FUNCNAME));
+ LOG("%s\n", FUNCNAME);
return 0xff; // TODO: make this configurable from commandline or artwork
}
// PIT#1 Port B TODO: implement floppy and dma control
READ8_MEMBER (cpu30_state::flop_dmac_r){
- LOG(("%s\n", FUNCNAME));
+ LOG("%s\n", FUNCNAME);
return 0xff;
}
WRITE8_MEMBER (cpu30_state::flop_dmac_w){
- LOG(("%s(%02x)\n", FUNCNAME, data));
+ LOG("%s(%02x)\n", FUNCNAME, data);
}
#define FPCP_SENSE 0x40 /* Port C bit 6 is low if a Floating Point Co Processor is installed */
// PIT#1 Port C TODO: implement timer+port interrupts
// TODO: Connect PC0, PC1, PC4 and PC7 to B5 and/or P2 connector
READ8_MEMBER (cpu30_state::pit1c_r){
- LOG(("%s\n", FUNCNAME));
+ LOG("%s\n", FUNCNAME);
m_maincpu->set_fpu_enable(1); // Lets assume the FPCP is always installed ( which is default for 68030 atm )
return 0xff & ~FPCP_SENSE; // Should really be command line for the edge cases...
}
WRITE8_MEMBER (cpu30_state::pit1c_w){
- LOG(("%s(%02x)\n", FUNCNAME, data));
+ LOG("%s(%02x)\n", FUNCNAME, data);
}
// PIT#2 Port A TODO: Connect to B5 and /or P2 connector
READ8_MEMBER (cpu30_state::pit2a_r){
- LOG(("%s\n", FUNCNAME));
+ LOG("%s\n", FUNCNAME);
logerror("Unsupported user i/o on PIT2 port A detected\n");
return 0xff;
}
WRITE8_MEMBER (cpu30_state::pit2a_w){
- LOG(("%s(%02x)\n", FUNCNAME, data));
+ LOG("%s(%02x)\n", FUNCNAME, data);
logerror("Unsupported user i/o on PIT2 port A detected\n");
}
@@ -519,7 +532,7 @@ WRITE8_MEMBER (cpu30_state::pit2a_w){
READ8_MEMBER (cpu30_state::board_mem_id_rd)
{
int sz;
- LOG(("%s\n", FUNCNAME));
+ LOG("%s\n", FUNCNAME);
switch (m_ram->size())
{
case (1024 * 1024 * 32): sz = 0; break;
@@ -557,56 +570,56 @@ READ8_MEMBER (cpu30_state::board_mem_id_rd)
// return 0x10 + sz;// CPU-22 p4
// return 0x20 + sz;// p1: Wait until hard disk is up to speed
// printf("SIZE:%02x\n", sz);
- LOG(("- Board ID:%02x Size:%02x\n", m_board_id, sz));
+ LOG("- Board ID:%02x Size:%02x\n", m_board_id, sz);
return m_board_id + sz;
}
// PIT#2 Port C TODO: implement timer interrupt, DMA i/o, memory control and Hardware ID
READ8_MEMBER (cpu30_state::pit2c_r){
- LOG(("%s\n", FUNCNAME));
+ LOG("%s\n", FUNCNAME);
return 0xfe;
}
WRITE8_MEMBER (cpu30_state::pit2c_w){
- LOG(("%s(%02x)\n", FUNCNAME, data));
+ LOG("%s(%02x)\n", FUNCNAME, data);
}
#if 0
/* Dummy VME access methods until the VME bus device is ready for use */
READ16_MEMBER (cpu30_state::vme_a24_r){
- LOG (logerror ("vme_a24_r\n"));
+ LOG("%s\n", FUNCNAME);
return (uint16_t) 0;
}
WRITE16_MEMBER (cpu30_state::vme_a24_w){
- LOG (logerror ("vme_a24_w\n"));
+ LOG("%s(%02x)\n", FUNCNAME, data);
}
READ16_MEMBER (cpu30_state::vme_a16_r){
- LOG (logerror ("vme_16_r\n"));
+ LOG("%s\n", FUNCNAME);
return (uint16_t) 0;
}
WRITE16_MEMBER (cpu30_state::vme_a16_w){
- LOG (logerror ("vme_a16_w\n"));
+ LOG("%s(%02x)\n", FUNCNAME, data);
}
#endif
WRITE_LINE_MEMBER(cpu30_state::fga_irq_callback)
{
- LOGINT(("%s(%02x)\n", FUNCNAME, state));
+ LOGINT("%s(%02x)\n", FUNCNAME, state);
fga_irq_state = state;
fga_irq_level = m_fga002->get_irq_level();
- LOGINT((" - FGA irq level %02x\n", fga_irq_level));
+ LOGINT(" - FGA irq level %02x\n", fga_irq_level);
update_irq_to_maincpu();
}
void cpu30_state::update_irq_to_maincpu()
{
- LOGINT(("%s()\n", FUNCNAME));
- LOGINT((" - fga_irq_level: %02x\n", fga_irq_level));
- LOGINT((" - fga_irq_state: %02x\n", fga_irq_state));
+ LOGINT("%s()\n", FUNCNAME);
+ LOGINT(" - fga_irq_level: %02x\n", fga_irq_level);
+ LOGINT(" - fga_irq_state: %02x\n", fga_irq_state);
switch (fga_irq_level & 0x07)
{
case 1: m_maincpu->set_input_line(M68K_IRQ_1, fga_irq_state); break;
@@ -620,6 +633,11 @@ void cpu30_state::update_irq_to_maincpu()
}
}
+static SLOT_INTERFACE_START(fccpu30_vme_cards)
+ SLOT_INTERFACE("fcisio", VME_FCISIO1)
+ SLOT_INTERFACE("fcscsi", VME_FCSCSI1)
+SLOT_INTERFACE_END
+
/*
* Machine configuration
*/
@@ -630,6 +648,8 @@ static MACHINE_CONFIG_START (cpu30, cpu30_state)
MCFG_CPU_IRQ_ACKNOWLEDGE_DEVICE("fga002", fga002_device, iack)
MCFG_NVRAM_ADD_0FILL("nvram")
+ MCFG_VME_DEVICE_ADD("vme")
+ MCFG_VME_SLOT_ADD ("vme", "slot1", fccpu30_vme_cards, nullptr)
/* Terminal Port config */
/* Force CPU30 series of boards has up to four serial ports, p1-p4, the FGA boot uses p4 as console and subsequent
firmware uses p1 as console and in an operating system environment there may be user login shells on the other.
diff --git a/src/mame/drivers/fcisio.cpp b/src/mame/drivers/fcisio.cpp
deleted file mode 100644
index 150eba2fe0c..00000000000
--- a/src/mame/drivers/fcisio.cpp
+++ /dev/null
@@ -1,309 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Joakim Larsson Edstrom
-/***************************************************************************
- *
- * 10/06/2016
- * Force SYS68K ISIO-1/2 driver - This driver will be converted into a slot device once the VME bus driver exists.
- * The ISIO board is a VME slave board that reads command and returns results through dual ported RAM to the VME bus.
- *
- * ISIO-1: page 385 http://bitsavers.informatik.uni-stuttgart.de/pdf/forceComputers/1988_Force_VMEbus_Products.pdf
- * ISIO-2: page 395 http://bitsavers.informatik.uni-stuttgart.de/pdf/forceComputers/1988_Force_VMEbus_Products.pdf
- *
- * Address Map - guessed/revenged no tech doc available
- * ----------------------------------------------------------
- * Address Range Description LOCAL
- * ----------------------------------------------------------
- * 00 0000 - 00 0007 Initialisation vectors from system EPROM
- * 00 0008 - 01 FFFF Local SRAM
- * E0 0000 - E0 01FF DUSCC0
- * E2 0000 - E0 01FF DUSCC0
- * E4 0000 - E0 01FF DUSCC0
- * E6 0000 - E0 01FF DUSCC0
- * E8 0000 - E8 0DFF PI/T
- * f0 0000 - F7 0000 EPROMs
- * ----------------------------------------------------------
- * Address Range Description LOCAL
- * ----------------------------------------------------------
- *
- * Interrupt sources
- * ----------------------------------------------------------
- * Description Device Lvl IRQ VME board
- * /Board Vector Address
- * ----------------------------------------------------------
- * On board Sources
- * ----------------------------------------------------------
- *
- * TODO:
- * - add PIT and DUSCC interrupts
- * - add port mapping to self test jumper
- * - add VME bus driver
- * - write and map a 68153 device (accessable from VME side)
- *
- * Status: passes Self test and get stuck on no ticks for the scheduler.
- * Schematics of the IRQ routing needed or a good trace of how the
- * PIT and DUSCCs are hooked up to the BIM to get further.
- *
- ****************************************************************************/
-#define TODO "Driver for 68153 BIM device needed\n"
-
-#include "emu.h"
-#include "cpu/m68000/m68000.h"
-#include "machine/scnxx562.h"
-#include "machine/68230pit.h"
-#include "bus/rs232/rs232.h"
-#include "machine/clock.h"
-
-#define VERBOSE 0
-
-#define LOG(x) do { if (VERBOSE) logerror x; } while (0)
-#if VERBOSE == 2
-#define logerror printf
-#endif
-
-#ifdef _MSC_VER
-#define FUNCNAME __func__
-#define LLFORMAT "%I64%"
-#else
-#define FUNCNAME __PRETTY_FUNCTION__
-#define LLFORMAT "%lld"
-#endif
-
-#define CPU_CLOCK XTAL_20MHz /* HCJ */
-#define DUSCC_CLOCK XTAL_14_7456MHz /* HCJ */
-
-class fcisio1_state : public driver_device
-{
-public:
-fcisio1_state(const machine_config &mconfig, device_type type, const char *tag) :
- driver_device (mconfig, type, tag),
- m_maincpu (*this, "maincpu")
- ,m_duscc0(*this, "duscc0")
- ,m_duscc1(*this, "duscc1")
- ,m_duscc2(*this, "duscc2")
- ,m_duscc3(*this, "duscc3")
- ,m_pit (*this, "pit")
-{
-}
- DECLARE_READ16_MEMBER (bootvect_r);
- DECLARE_READ8_MEMBER (config_rd);
-
- /* Dummy driver routines */
- DECLARE_READ8_MEMBER (not_implemented_r);
- DECLARE_WRITE8_MEMBER (not_implemented_w);
-
- virtual void machine_start () override;
-
-protected:
-
-private:
- required_device<cpu_device> m_maincpu;
- required_device<duscc68562_device> m_duscc0;
- required_device<duscc68562_device> m_duscc1;
- required_device<duscc68562_device> m_duscc2;
- required_device<duscc68562_device> m_duscc3;
-
- required_device<pit68230_device> m_pit;
-
- // Pointer to System ROMs needed by bootvect_r
- uint16_t *m_sysrom;
-};
-
-static ADDRESS_MAP_START (fcisio1_mem, AS_PROGRAM, 16, fcisio1_state)
- ADDRESS_MAP_UNMAP_HIGH
- AM_RANGE (0x000000, 0x000007) AM_ROM AM_READ (bootvect_r) /* Vectors mapped from System EPROM */
- AM_RANGE (0x000000, 0x01ffff) AM_RAM /* SRAM */
- AM_RANGE (0xe00000, 0xe001ff) AM_DEVREADWRITE8("duscc0", duscc68562_device, read, write, 0x00ff)
- AM_RANGE (0xe20000, 0xe201ff) AM_DEVREADWRITE8("duscc1", duscc68562_device, read, write, 0x00ff)
- AM_RANGE (0xe40000, 0xe401ff) AM_DEVREADWRITE8("duscc2", duscc68562_device, read, write, 0x00ff)
- AM_RANGE (0xe60000, 0xe601ff) AM_DEVREADWRITE8("duscc3", duscc68562_device, read, write, 0x00ff)
- AM_RANGE (0xe80000, 0xe80dff) AM_DEVREADWRITE8("pit", pit68230_device, read, write, 0x00ff)
- AM_RANGE (0xf00000, 0xf7ffff) AM_ROM /* System EPROM Area 32Kb DEBUGGER supplied */
-// AM_RANGE (0xc40000, 0xc800ff) AM_READWRITE8 (not_implemented_r, not_implemented_w, 0xffff) /* Dummy mapping af address area to display message */
-ADDRESS_MAP_END
-
-/* Start it up */
-void fcisio1_state::machine_start ()
-{
- LOG (("machine_start\n"));
-
- /* Setup pointer to bootvector in ROM for bootvector handler bootvect_r */
- m_sysrom = (uint16_t*)(memregion ("maincpu")->base () + 0xf00000);
-}
-
-/* Boot vector handler, the PCB hardwires the first 8 bytes from 0x80000 to 0x0 */
-READ16_MEMBER (fcisio1_state::bootvect_r){
- return m_sysrom [offset];
-}
-
-READ8_MEMBER (fcisio1_state::not_implemented_r){
- static int been_here = 0;
- if (!been_here++){
- logerror(TODO);
- printf(TODO);
- }
- return (uint8_t) 0;
-}
-
-WRITE8_MEMBER (fcisio1_state::not_implemented_w){
- static int been_here = 0;
- if (!been_here++){
- logerror(TODO);
- printf(TODO);
- }
- return;
-}
-
-// TODO: Get a manual to understand the config options for real
-READ8_MEMBER (fcisio1_state::config_rd){
- uint8_t ret = 0;
- LOG(("%s\n", FUNCNAME));
-
- // Port B bit #7, 0x80 Self test bit, choose either of these two lines
- ret &= ~0x80; // 0 = selftest
- // ret |= 0x80; // 1 = no selftest
-
- return ret;
-}
-
-/* Input ports */
-static INPUT_PORTS_START (fcisio1)
-INPUT_PORTS_END
-
-static DEVICE_INPUT_DEFAULTS_START( fcisio_terminal )
- DEVICE_INPUT_DEFAULTS( "RS232_TXBAUD", 0xff, RS232_BAUD_9600 )
- DEVICE_INPUT_DEFAULTS( "RS232_RXBAUD", 0xff, RS232_BAUD_9600 )
- DEVICE_INPUT_DEFAULTS( "RS232_STARTBITS", 0xff, RS232_STARTBITS_1 )
- DEVICE_INPUT_DEFAULTS( "RS232_DATABITS", 0xff, RS232_DATABITS_8 )
- DEVICE_INPUT_DEFAULTS( "RS232_PARITY", 0xff, RS232_PARITY_NONE )
- DEVICE_INPUT_DEFAULTS( "RS232_STOPBITS", 0xff, RS232_STOPBITS_1 )
-DEVICE_INPUT_DEFAULTS_END
-
-/*
- * Machine configuration
- */
-static MACHINE_CONFIG_START (fcisio1, fcisio1_state)
- /* basic machine hardware */
- MCFG_CPU_ADD ("maincpu", M68010, CPU_CLOCK / 2)
- MCFG_CPU_PROGRAM_MAP (fcisio1_mem)
-
- MCFG_DUSCC68562_ADD("duscc0", DUSCC_CLOCK, 0, 0, 0, 0 )
- MCFG_DUSCC_OUT_TXDA_CB(DEVWRITELINE("rs232trm", rs232_port_device, write_txd))
- MCFG_DUSCC_OUT_DTRA_CB(DEVWRITELINE("rs232trm", rs232_port_device, write_dtr))
- MCFG_DUSCC_OUT_RTSA_CB(DEVWRITELINE("rs232trm", rs232_port_device, write_rts))
-
- MCFG_RS232_PORT_ADD ("rs232trm", default_rs232_devices, "terminal")
- MCFG_RS232_RXD_HANDLER (DEVWRITELINE ("duscc0", duscc68562_device, rxa_w))
- MCFG_RS232_CTS_HANDLER (DEVWRITELINE ("duscc0", duscc68562_device, ctsa_w))
- MCFG_DEVICE_CARD_DEVICE_INPUT_DEFAULTS("terminal", fcisio_terminal)
-
- MCFG_DUSCC68562_ADD("duscc1", DUSCC_CLOCK, 0, 0, 0, 0 )
- MCFG_DUSCC68562_ADD("duscc2", DUSCC_CLOCK, 0, 0, 0, 0 )
- MCFG_DUSCC68562_ADD("duscc3", DUSCC_CLOCK, 0, 0, 0, 0 )
-
- MCFG_DEVICE_ADD ("pit", PIT68230, XTAL_20MHz / 2)
- MCFG_PIT68230_PB_INPUT_CB(READ8(fcisio1_state, config_rd))
-MACHINE_CONFIG_END
-
-/* ROM definitions */
-ROM_START (fcisio1)
- ROM_REGION (0x1000000, "maincpu", 0)
-
-/* ISIO ROM:s v2.1 information
- * PIT setup sequence
- * 00 -> REG_PGCR
- * 18 -> REG_PSRR
- * 0f -> Reg PADDR
- * 0f -> REG_PBDDR
- * fa -> REG_PACR
- * 0f -> REG_PADDR
- * fa -> REG_PBCR
- * ff -> REG_PBDR
- * 0f -> REG_PBDDR
- * 10 -> REG_PGCR
- * ff -> REG_PCDR
- * 17 -> REG_PCDDR
- * 40 -> Reg PIVR
- * 00 -> REG_TCR - timer disabled, all C pins, use preload, CLK and prescaler are used
- * a0 -> REG_TCR - timer disabled, The dual-function pin PC3/TOUT carries the TOUTfunction and is used as a timer interrupt request
- * output. The timer interrupt is enabled ; thus, the pin is low when the timer ZDS status bit is one. The dual-function
- * pin PC7/TIACK carries the TIACK function and is used as a timer interrupt acknowledge input.
- * 00 -> Reg 0x12
- * 00 -> REG_CPRH
- * 09 -> REG_CPRM
- * 00 -> REG_CPRL
- * 00 -> Reg 0x16
- * 00 -> Reg 0x17
- * 09 -> Reg 0x18
- * 00 -> Reg 0x19
- * 1d -> Reg TIVR
- * 0f <- REG_PBDR
- * 0e -> REG_PBDR
- * 0f <- REG_PBDR
- * 0f <- REG_PBDR
- * 0d -> REG_PDBR
- * 0f <- REG_PBDR
- * 0f <- REG_PBDR
- * 0f <- REG_PBDR
- * 0f <- REG_PBDR
- * 0f <- REG_PBDR
- * 0f <- REG_PBDR
- * 0f <- REG_PBDR
- * 0f <- REG_PBDR
- * 0f <- REG_PBDR
- * 0f -> REG_PBDR
- * 0f <- REG_PBDR
- * 0b -> REG_PBDR
- * 0f <- REG_PBDR
- * 0f <- REG_PBDR
- * 0f -> REG_PBDR
- * 0f <- REG_PBDR
- * 0f -> REG_PBDR
- * 0f <- REG_PBDR
- * 00 <- REG_PCDR
- * 00 -> REG_PCDR
- * ------- repeated 16 times -------------------
- * a1 -> REG_TCR - timer enabled, The dual-function pin PC3/TOUT carries the TOUTfunction and is used as a timer interrupt request
- * output. The timer interrupt is enabled ; thus, the pin is low when the timer ZDS status bit is one. The dual-function
- * pin PC7/TIACK carries the TIACK function and is used as a timer interrupt acknowledge input.
- * ?? <- Reg 0x0c
- * ---------------------------------------------
- *
- * DUSCC0 channel A setup sequence
- * 0f 00 -> REG_CCR - Reset Tx
- * 0f 40 -> REG_CCR - Reset Rx
- * 00 07 -> REG_CMR1 - Async mode
- * 01 38 -> REG_CMR2 - Normal polled or interrupt mode, no DMA
- * 02 00 -> REG_S1R - SYN1, Secondary Address 1 Register, 0 = no sync
- * 03 00 -> REG_S2R - SYN2, only used in COP dual Sync mode but alao 0 = no sync
- * 04 7F -> REG_TPR - Tx 8 bits, CTS and RTS, 1 STOP bit
- * 05 3d -> REG_TTR - Tx BRG 9600 (assuming a 14.7456 crystal)
- * 06 1b -> REG_RPR - Rx RTS, 8 bits, no DCD, no parity
- * 07 2d -> REG_RTR - Rx BRG 9600 (assuming a 14.7456 crystal)
- * 0b e1 -> REG_OMR - RTS high, OUT1 = OUT2 = high, RxRdy asserted for each character,
- * TxRdy asserted on threshold, Same Tx Residual Character Length as for REG_TPR
- * 0a 00 -> REG_CTCR - Counter/Timer control register 00 = Zero Det Int: disabled, Zero Det Control: preset,
- * Output Control: square, Prescaler: 1, Clock Source: RTxC pin
- * 09 00 -> REG_CTPRL - Counter/Timer Prescaler Register Low = 0
- * 08 00 -> REG_CTPRH - Counter/Timer Prescaler Register High = 0
- * 0f 00 -> REG_CCR - Reset Tx
- * 0f 02 -> REG_CCR - Enable Tx
- * 0f 40 -> REG_CCR - Reset Rx
- * 0f 42 -> REG_CCR - Enable Rx
- * 0f 02 -> REG_CCR - Enable Tx
- * 0f 42 -> REG_CCR - Enable Rx
- * 0e 27 -> REG_PCR - TRxC = RxCLK 1x, RTxC is input, RTS, GPO2, crystal oscillator connected to X2
- * 1c 10 -> REG_IER - Interrupt Enable Register: RxRdy generates interrupt
- * ... chan B setup with same data....
- * ---- DUSCC0 to DUSCC3, setup with same data except at the end of each setup:
- * 1e 1c -> DUSCC0 REG_IVR -
- * 1e 1b -> DUSCC1 REG_IVR
- * 1e 1a -> DUSCC2 REG_IVR
- * 1e 19 -> DUSCC3 REG_IVR
- */
- ROM_LOAD16_BYTE ("ISIO-1_V2.1_L.BIN", 0xf00001, 0x4000, CRC (0d47d80f) SHA1 (541b55966f464c1cf686e36998650720950a2242))
- ROM_LOAD16_BYTE ("ISIO-1_V2.1_U.BIN", 0xf00000, 0x4000, CRC (67986768) SHA1 (215f7ff90d9dbe2bea54510e3722fb33d4e54193))
-ROM_END
-
-/* Driver */
-/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */
-COMP( 1986, fcisio1, 0, 0, fcisio1, fcisio1, driver_device, 0, "Force Computers Gmbh", "SYS68K/ISIO-1", MACHINE_NOT_WORKING | MACHINE_NO_SOUND_HW | MACHINE_TYPE_COMPUTER )
diff --git a/src/mame/drivers/fcscsi.cpp b/src/mame/drivers/fcscsi.cpp
deleted file mode 100644
index 580911f9962..00000000000
--- a/src/mame/drivers/fcscsi.cpp
+++ /dev/null
@@ -1,435 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Joakim Larsson Edstrom
-/***************************************************************************
- * Interrupt scheme and dmac hookup shamelessly based on esq5505.cpp
- *
- * 11/04/2016
- * Force SYS68K ISCSI-1 driver - This driver will be converted into a slot device once the VME bus driver exists.
- * The ISCSI-1 board is a VME slave board that reads command and returns results through dual ported RAM to the VME bus.
- *
- * http://bitsavers.trailing-edge.com/pdf/forceComputers/800114_Force_Introduction_to_the_SYS68K_ISCSI-1_Oct86.pdf
- *
- * Address Map
- * ----------------------------------------------------------
- * Address Range Description
- * ----------------------------------------------------------
- * 00 0000 - 00 0007 Initialisation vectors from system EPROM
- * 00 0008 - 00 1FFF Local SRAM
- * 00 2000 - 01 FFFF Dynamic Dual Port RAM
- * C4 0000 - C4 001F SCSIbus controller
- * C8 0000 - C8 00FF DMAC
- * CC 0000 - CC 0007 FDC
- * CC 0009 - CC 0009 Control Register
- * D0 0000 - D0 003F PI/T
- * E0 0000 - E7 0000 EPROMs
- * ----------------------------------------------------------
- *
- * Interrupt sources
- * ----------------------------------------------------------
- * Description Device Lvl IRQ VME board
- * /Board Vector Address
- * ----------------------------------------------------------
- * On board Sources
- * ABORT P3 p13 1 AV1
- * DMA controller 68450 2 DMAC/AV2
- * SCSI bus controller NCR 5386S 3 AV3
- * Floppy Disk controller WD 1772 4 AV4
- * Parallel interface and timer 68230 5 PIT timer
- * --- 6 ---
- * Parallel interface and timer 65230 7 PIT port
- * ----------------------------------------------------------
- *
- * TODO:
- * - Write and attach a NCR5386S SCSI device
- * - Find a floppy image and present it to the WD1772 floppy controller
- * - Add VME bus driver
- * - Let a controller CPU board (eg CPU-1 or CPU-30) boot from floppy or SCSI disk
- *
- ****************************************************************************/
-#define TODO "Driver for SCSI NCR5386s device needed\n"
-
-#include "emu.h"
-#include "cpu/m68000/m68000.h"
-#include "machine/68230pit.h"
-#include "machine/wd_fdc.h"
-#include "machine/hd63450.h" // compatible with MC68450
-#include "machine/clock.h"
-#include "formats/pc_dsk.h"
-
-#define VERBOSE 0
-
-#define LOG(x) do { if (VERBOSE) logerror x; } while (0)
-#if VERBOSE == 2
-#define logerror printf
-#endif
-
-#ifdef _MSC_VER
-#define FUNCNAME __func__
-#define LLFORMAT "%I64%"
-#else
-#define FUNCNAME __PRETTY_FUNCTION__
-#define LLFORMAT "%lld"
-#endif
-
-#define CPU_CRYSTAL XTAL_20MHz /* Jauch */
-#define PIT_CRYSTAL XTAL_16MHz /* Jauch */
-
-class fcscsi1_state : public driver_device
-{
-public:
-fcscsi1_state(const machine_config &mconfig, device_type type, const char *tag) :
- driver_device (mconfig, type, tag),
- m_maincpu (*this, "maincpu")
- ,m_fdc (*this, "fdc")
- ,m_pit (*this, "pit")
- ,m_dmac(*this, "mc68450")
- ,m_tcr (0)
-{
-}
- DECLARE_READ16_MEMBER (bootvect_r);
- DECLARE_READ8_MEMBER (tcr_r);
- DECLARE_WRITE8_MEMBER (tcr_w);
- DECLARE_WRITE8_MEMBER (led_w);
-
- IRQ_CALLBACK_MEMBER(maincpu_irq_acknowledge_callback);
-
- //dmac
- DECLARE_WRITE8_MEMBER(dma_end);
- DECLARE_WRITE8_MEMBER(dma_error);
-
- //fdc
- DECLARE_WRITE8_MEMBER(fdc_irq);
- DECLARE_READ8_MEMBER(fdc_read_byte);
- DECLARE_WRITE8_MEMBER(fdc_write_byte);
- DECLARE_FLOPPY_FORMATS(floppy_formats);
-
- /* Dummy driver routines */
- DECLARE_READ8_MEMBER (not_implemented_r);
- DECLARE_WRITE8_MEMBER (not_implemented_w);
-
- DECLARE_READ8_MEMBER (scsi_r);
- DECLARE_WRITE8_MEMBER (scsi_w);
-
- uint8_t fdc_irq_state;
- uint8_t dmac_irq_state;
- int dmac_irq_vector;
-
- virtual void machine_start () override;
- void update_irq_to_maincpu();
-
-protected:
-
-private:
- required_device<cpu_device> m_maincpu;
- required_device<wd1772_t> m_fdc;
- required_device<pit68230_device> m_pit;
- required_device<hd63450_device> m_dmac;
-
- uint8_t m_tcr;
-
- // Pointer to System ROMs needed by bootvect_r
- uint16_t *m_sysrom;
-};
-
-static ADDRESS_MAP_START (fcscsi1_mem, AS_PROGRAM, 16, fcscsi1_state)
- ADDRESS_MAP_UNMAP_HIGH
- AM_RANGE (0x000000, 0x000007) AM_ROM AM_READ (bootvect_r) /* Vectors mapped from System EPROM */
- AM_RANGE (0x000008, 0x001fff) AM_RAM /* SRAM */
- AM_RANGE (0x002000, 0x01ffff) AM_RAM /* Dual Ported RAM */
- AM_RANGE (0xe00000, 0xe7ffff) AM_ROM /* System EPROM Area 32Kb DEBUGGER supplied */
- AM_RANGE (0xd00000, 0xd0003f) AM_DEVREADWRITE8 ("pit", pit68230_device, read, write, 0x00ff)
-// AM_RANGE (0xc40000, 0xc4001f) AM_DEVREADWRITE8("scsi", ncr5386_device, read, write, 0x00ff) /* SCSI Controller interface - device support not yet available*/
- AM_RANGE (0xc40000, 0xc4001f) AM_READWRITE8 (scsi_r, scsi_w, 0x00ff)
- AM_RANGE (0xc80000, 0xc800ff) AM_DEVREADWRITE("mc68450", hd63450_device, read, write) /* DMA Controller interface */
- AM_RANGE (0xcc0000, 0xcc0007) AM_DEVREADWRITE8("fdc", wd1772_t, read, write, 0x00ff) /* Floppy Controller interface */
- AM_RANGE (0xcc0008, 0xcc0009) AM_READWRITE8 (tcr_r, tcr_w, 0x00ff) /* The Control Register, SCSI ID and FD drive select bits */
-ADDRESS_MAP_END
-
-/* Input ports */
-static INPUT_PORTS_START (fcscsi1)
-INPUT_PORTS_END
-
-/* Start it up */
-void fcscsi1_state::machine_start ()
-{
- LOG (("machine_start\n"));
-
- /* Setup pointer to bootvector in ROM for bootvector handler bootvect_r */
- m_sysrom = (uint16_t*)(memregion ("maincpu")->base () + 0xe00000);
-
-}
-
-/* Boot vector handler, the PCB hardwires the first 8 bytes from 0x80000 to 0x0 */
-READ16_MEMBER (fcscsi1_state::bootvect_r){
- return m_sysrom [offset];
-}
-
-/* The Control Register - discretely implemented on the PCB
-Bit #: 7 6 5 4 3 2 1 0
- \ \ \ \ \ \ \ \ Floppy Disk Side Select
- \ \ \ \ \ \ \ Floppy Disk Drive Select 0
- \ \ \ \ \ \ Floppy Disk Drive Select 1
- \ \ \ \ \ Floppy Disk Drive Select 2
- \ \ \ \ Floppy Disk Drive Select 3
- \ \ \ ISCSI-l I.D. Bit #0
- \ \ ISCSI-l I.D. Bit #1
- \ ISCSI-l 1.D. Bit #2
-*/
-
-READ8_MEMBER (fcscsi1_state::tcr_r){
- LOG(("%s\n", FUNCNAME));
- return (uint8_t) m_tcr;
-}
-
-WRITE8_MEMBER (fcscsi1_state::tcr_w){
- floppy_image_device *floppy0 = m_fdc->subdevice<floppy_connector>("0")->get_device();
- floppy_image_device *floppy1 = m_fdc->subdevice<floppy_connector>("1")->get_device();
- floppy_image_device *floppy2 = m_fdc->subdevice<floppy_connector>("2")->get_device();
- floppy_image_device *floppy3 = m_fdc->subdevice<floppy_connector>("3")->get_device();
- floppy_image_device *floppy = nullptr;
-
- if (!BIT(data, 1)) floppy = floppy0;
- else
- if (!BIT(data, 2)) floppy = floppy1;
- else
- if (!BIT(data, 3)) floppy = floppy2;
- else
- if (!BIT(data, 4)) floppy = floppy3;
-
- if (floppy) {
- m_fdc->set_floppy(floppy);
- floppy->ss_w(!BIT(data, 0));
- floppy->mon_w(0);
- } else {
- floppy0->mon_w(1);
- floppy1->mon_w(1);
- floppy2->mon_w(1);
- floppy3->mon_w(1);
- }
-
- LOG(("%s [%02x]\n", FUNCNAME, data));
- m_tcr = data;
- return;
-}
-
-WRITE8_MEMBER (fcscsi1_state::led_w){
- LOG(("%s [%02x]\n", FUNCNAME, data));
-
- m_fdc->dden_w(BIT(data, 7));
-
- return;
-}
-
-WRITE8_MEMBER(fcscsi1_state::dma_end)
-{
- if (data != 0)
- {
- dmac_irq_state = 1;
- dmac_irq_vector = m_dmac->get_vector(offset);
- }
- else
- {
- dmac_irq_state = 0;
- }
-
- update_irq_to_maincpu();
-}
-
-WRITE8_MEMBER(fcscsi1_state::dma_error)
-{
- if(data != 0)
- {
- logerror("DMAC error, vector = %x\n", m_dmac->get_error_vector(offset));
- dmac_irq_state = 1;
- dmac_irq_vector = m_dmac->get_vector(offset);
- }
- else
- {
- dmac_irq_state = 0;
- }
-
- update_irq_to_maincpu();
-}
-
-WRITE8_MEMBER(fcscsi1_state::fdc_irq)
-{
- if (data != 0)
- {
- fdc_irq_state = 1;
- }
- else
- {
- fdc_irq_state = 0;
- }
- update_irq_to_maincpu();
-}
-
-READ8_MEMBER(fcscsi1_state::fdc_read_byte)
-{
- return m_fdc->data_r();
-}
-
-WRITE8_MEMBER(fcscsi1_state::fdc_write_byte)
-{
- m_fdc->data_w(data & 0xff);
-}
-
-READ8_MEMBER(fcscsi1_state::scsi_r)
-{
- uint8_t data = 0;
-
- // fake diag status
- if (offset == 9)
- data = 0x80;
-
- LOG(("scsi R %02x == %02x\n", offset, data));
-
- return data;
-}
-
-WRITE8_MEMBER(fcscsi1_state::scsi_w)
-{
- LOG(("scsi W %02x <- %02x\n", offset, data));
-}
-
-READ8_MEMBER (fcscsi1_state::not_implemented_r){
- static int been_here = 0;
- if (!been_here++){
- logerror(TODO);
- printf(TODO);
- }
- return (uint8_t) 0;
-}
-
-WRITE8_MEMBER (fcscsi1_state::not_implemented_w){
- static int been_here = 0;
- if (!been_here++){
- logerror(TODO);
- printf(TODO);
- }
- return;
-}
-
-/*
-----------------------------------------------------
- IRQ IRQ
-Level Source B4l inserted B4l removed (Def)
------------------------------------------------------
- 1 P3 Pin #13 AV1 Autovector AV1 Autovector
- 2 DMAC DMAC AV2 Autovector
- 3 SCSIBC AV3 Autovector AV3 Autovector
- 4 FDC AV4 Autovector AV4 Autovector
- 5 PI/T Timer PI/T Timer Vect PI/T Timer Vect
- 6 -- -- --
- 7 PI/T Port PI/T Port Vect PI/T Port Vect
-------------------------------------------------------
-Default configuration: B41 jumper removed
-
-The PI/T port interrupt can be used under software control to
-cause non-maskable (Level 7) interrupts if the watchdog timer
-elapses and/or if the VMEbus interrupt trigger call occurs.
-*/
-
-/* TODO: Add configurable B41 jumper */
-#define B41 0
-
-void fcscsi1_state::update_irq_to_maincpu() {
- if (fdc_irq_state) {
- m_maincpu->set_input_line(M68K_IRQ_3, ASSERT_LINE);
- m_maincpu->set_input_line(M68K_IRQ_2, CLEAR_LINE);
- m_maincpu->set_input_line(M68K_IRQ_1, CLEAR_LINE);
- } else if (dmac_irq_state) {
- m_maincpu->set_input_line(M68K_IRQ_3, CLEAR_LINE);
- m_maincpu->set_input_line(M68K_IRQ_1, CLEAR_LINE);
-#if B41 == 1
- m_maincpu->set_input_line_and_vector(M68K_IRQ_2, ASSERT_LINE, dmac_irq_vector);
-#else
- m_maincpu->set_input_line(M68K_IRQ_2, ASSERT_LINE);
-#endif
- } else {
- m_maincpu->set_input_line(M68K_IRQ_3, CLEAR_LINE);
- m_maincpu->set_input_line(M68K_IRQ_2, CLEAR_LINE);
- m_maincpu->set_input_line(M68K_IRQ_1, CLEAR_LINE);
- }
-}
-
-IRQ_CALLBACK_MEMBER(fcscsi1_state::maincpu_irq_acknowledge_callback)
-{
- // We immediately update the interrupt presented to the CPU, so that it doesn't
- // end up retrying the same interrupt over and over. We then return the appropriate vector.
- int vector = 0;
- switch(irqline) {
- case 2:
- dmac_irq_state = 0;
- vector = dmac_irq_vector;
- break;
- default:
- logerror("\nUnexpected IRQ ACK Callback: IRQ %d\n", irqline);
- return 0;
- }
- update_irq_to_maincpu();
- return vector;
-}
-
-FLOPPY_FORMATS_MEMBER( fcscsi1_state::floppy_formats )
- FLOPPY_PC_FORMAT
-FLOPPY_FORMATS_END
-
-static SLOT_INTERFACE_START( fcscsi_floppies )
- SLOT_INTERFACE( "525qd", FLOPPY_525_QD )
-SLOT_INTERFACE_END
-
-/*
- * Machine configuration
- */
-static MACHINE_CONFIG_START (fcscsi1, fcscsi1_state)
- /* basic machine hardware */
- MCFG_CPU_ADD ("maincpu", M68010, CPU_CRYSTAL / 2) /* 7474 based frequency divide by 2 */
- MCFG_CPU_PROGRAM_MAP (fcscsi1_mem)
- MCFG_CPU_IRQ_ACKNOWLEDGE_DRIVER(fcscsi1_state, maincpu_irq_acknowledge_callback)
-
- /* FDC */
- MCFG_WD1772_ADD("fdc", PIT_CRYSTAL / 2)
- MCFG_WD_FDC_INTRQ_CALLBACK(WRITE8(fcscsi1_state, fdc_irq))
- MCFG_WD_FDC_DRQ_CALLBACK(DEVWRITELINE("mc68450", hd63450_device, drq1_w))
- MCFG_FLOPPY_DRIVE_ADD("fdc:0", fcscsi_floppies, "525qd", fcscsi1_state::floppy_formats)
- MCFG_FLOPPY_DRIVE_ADD("fdc:1", fcscsi_floppies, "525qd", fcscsi1_state::floppy_formats)
- MCFG_FLOPPY_DRIVE_ADD("fdc:2", fcscsi_floppies, "525qd", fcscsi1_state::floppy_formats)
- MCFG_FLOPPY_DRIVE_ADD("fdc:3", fcscsi_floppies, "525qd", fcscsi1_state::floppy_formats)
-
- /* PIT Parallel Interface and Timer device */
- MCFG_DEVICE_ADD ("pit", PIT68230, PIT_CRYSTAL / 2) /* 7474 based frequency divide by 2 */
- MCFG_PIT68230_PB_OUTPUT_CB(WRITE8(fcscsi1_state, led_w))
-
- /* DMAC it is really a M68450 but the HD63850 is upwards compatible */
- MCFG_DEVICE_ADD("mc68450", HD63450, 0) // MC68450 compatible
- MCFG_HD63450_CPU("maincpu") // CPU - 68010
- MCFG_HD63450_CLOCKS(attotime::from_usec(32), attotime::from_nsec(450), attotime::from_usec(4), attotime::from_hz(15625/2))
- MCFG_HD63450_BURST_CLOCKS(attotime::from_usec(32), attotime::from_nsec(450), attotime::from_nsec(50), attotime::from_nsec(50))
- MCFG_HD63450_DMA_END_CB(WRITE8(fcscsi1_state, dma_end))
- MCFG_HD63450_DMA_ERROR_CB(WRITE8(fcscsi1_state, dma_error))
- //MCFG_HD63450_DMA_READ_0_CB(READ8(fcscsi1_state, scsi_read_byte)) // ch 0 = SCSI
- //MCFG_HD63450_DMA_WRITE_0_CB(WRITE8(fcscsi1_state, scsi_write_byte))
- MCFG_HD63450_DMA_READ_1_CB(READ8(fcscsi1_state, fdc_read_byte)) // ch 1 = fdc
- MCFG_HD63450_DMA_WRITE_1_CB(WRITE8(fcscsi1_state, fdc_write_byte))
-MACHINE_CONFIG_END
-
-/* ROM definitions */
-ROM_START (fcscsi1)
- ROM_REGION (0x1000000, "maincpu", 0)
-
- /* Besta ROM:s - apparantly patched Force ROM:s */
- ROM_SYSTEM_BIOS(0, "Besta 88", "Besta 88")
- ROMX_LOAD ("besta88_scsi_lower.ROM", 0xe00001, 0x4000, CRC (fb3ab364) SHA1 (d79112100f1c4beaf358e006efd4dde5e300b0ba), ROM_SKIP(1) | ROM_BIOS(1))
- ROMX_LOAD ("besta88_scsi_upper.ROM", 0xe00000, 0x4000, CRC (41f9cdf4) SHA1 (66b998bbf9459f0a613718260e05e97749532073), ROM_SKIP(1) | ROM_BIOS(1))
-
- /* Force ROM:s */
- ROM_SYSTEM_BIOS(1, "ISCSI-1 v3.7", "Force Computer SYS68K/ISCSI-1 firmware v3.7")
- ROMX_LOAD ("ISCSI-1_V3.7_L.BIN", 0xe00001, 0x4000, CRC (83d95ab7) SHA1 (bf249910bcb6cb0b04dda2a95a38a0f90b553352), ROM_SKIP(1) | ROM_BIOS(2))
- ROMX_LOAD ("ISCSI-1_V3.7_U.BIN", 0xe00000, 0x4000, CRC (58815831) SHA1 (074085ef96e1fe2a551938bdeee6a9cab40ff09c), ROM_SKIP(1) | ROM_BIOS(2))
-
-ROM_END
-
-/* Driver */
-/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */
-COMP( 1986, fcscsi1, 0, 0, fcscsi1, fcscsi1, driver_device, 0, "Force Computers Gmbh", "SYS68K/SCSI-1", MACHINE_IS_SKELETON )
diff --git a/src/mame/drivers/feversoc.cpp b/src/mame/drivers/feversoc.cpp
index db15bca192b..96edff09053 100644
--- a/src/mame/drivers/feversoc.cpp
+++ b/src/mame/drivers/feversoc.cpp
@@ -95,9 +95,9 @@ public:
required_shared_ptr<uint32_t> m_nvram;
required_shared_ptr<uint32_t> m_spriteram;
DECLARE_READ32_MEMBER(in0_r);
- DECLARE_WRITE32_MEMBER(output_w);
+ DECLARE_WRITE16_MEMBER(output_w);
+ DECLARE_WRITE16_MEMBER(output2_w);
DECLARE_DRIVER_INIT(feversoc);
- virtual void video_start() override;
uint32_t screen_update_feversoc(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
INTERRUPT_GEN_MEMBER(feversoc_irq);
required_device<sh2_device> m_maincpu;
@@ -111,9 +111,6 @@ public:
#define MASTER_CLOCK XTAL_28_63636MHz
-void feversoc_state::video_start()
-{
-}
uint32_t feversoc_state::screen_update_feversoc(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
@@ -153,49 +150,49 @@ READ32_MEMBER(feversoc_state::in0_r)
return io0 | io1;
}
-WRITE32_MEMBER(feversoc_state::output_w)
+WRITE16_MEMBER( feversoc_state::output_w )
{
- if(ACCESSING_BITS_16_31)
- {
- machine().bookkeeping().coin_lockout_w(0,~data>>16 & 0x40);
- machine().bookkeeping().coin_lockout_w(1,~data>>16 & 0x40);
- machine().bookkeeping().coin_counter_w(0,data>>16 & 1);
- //data>>16 & 2 coin out
- machine().bookkeeping().coin_counter_w(1,data>>16 & 4);
- //data>>16 & 8 coin hopper
- m_oki->set_rom_bank(((data>>16) & 0x20)>>5);
-
- m_eeprom->di_write((data & 0x80000000) ? 1 : 0);
- m_eeprom->clk_write((data & 0x40000000) ? ASSERT_LINE : CLEAR_LINE);
- m_eeprom->cs_write((data & 0x20000000) ? ASSERT_LINE : CLEAR_LINE);
-
- m_rtc->data_w((data & 0x08000000) ? 1 : 0);
- m_rtc->wr_w((data & 0x04000000) ? ASSERT_LINE : CLEAR_LINE);
- m_rtc->clk_w((data & 0x02000000) ? ASSERT_LINE : CLEAR_LINE);
- m_rtc->ce_w((data & 0x01000000) ? ASSERT_LINE : CLEAR_LINE);
- }
- if(ACCESSING_BITS_0_15)
- {
- machine().output().set_lamp_value(1, BIT(data, 0)); // LAMP1
- machine().output().set_lamp_value(2, BIT(data, 1)); // LAMP2
- machine().output().set_lamp_value(3, BIT(data, 2)); // LAMP3
- machine().output().set_lamp_value(4, BIT(data, 3)); // LAMP4
- machine().output().set_lamp_value(5, BIT(data, 4)); // LAMP5
- machine().output().set_lamp_value(6, BIT(data, 5)); // LAMP6
- machine().output().set_lamp_value(7, BIT(data, 6)); // LAMP7
-
- machine().bookkeeping().coin_counter_w(2,data & 0x2000); //key in
- //data & 0x4000 key out
- }
+ machine().bookkeeping().coin_lockout_w(0, ~data & 0x40);
+ machine().bookkeeping().coin_lockout_w(1, ~data & 0x40);
+ machine().bookkeeping().coin_counter_w(0, data & 1);
+ // data & 2 coin out
+ machine().bookkeeping().coin_counter_w(1, data & 4);
+ // data & 8 coin hopper
+ m_oki->set_rom_bank((data & 0x20) >> 5);
+
+ m_eeprom->di_write((data & 0x8000) ? 1 : 0);
+ m_eeprom->clk_write((data & 0x4000) ? ASSERT_LINE : CLEAR_LINE);
+ m_eeprom->cs_write((data & 0x2000) ? ASSERT_LINE : CLEAR_LINE);
+
+ m_rtc->data_w((data & 0x0800) ? 1 : 0);
+ m_rtc->wr_w((data & 0x0400) ? ASSERT_LINE : CLEAR_LINE);
+ m_rtc->clk_w((data & 0x0200) ? ASSERT_LINE : CLEAR_LINE);
+ m_rtc->ce_w((data & 0x0100) ? ASSERT_LINE : CLEAR_LINE);
}
+WRITE16_MEMBER( feversoc_state::output2_w )
+{
+ machine().output().set_lamp_value(1, BIT(data, 0)); // LAMP1
+ machine().output().set_lamp_value(2, BIT(data, 1)); // LAMP2
+ machine().output().set_lamp_value(3, BIT(data, 2)); // LAMP3
+ machine().output().set_lamp_value(4, BIT(data, 3)); // LAMP4
+ machine().output().set_lamp_value(5, BIT(data, 4)); // LAMP5
+ machine().output().set_lamp_value(6, BIT(data, 5)); // LAMP6
+ machine().output().set_lamp_value(7, BIT(data, 6)); // LAMP7
+
+ machine().bookkeeping().coin_counter_w(2, data & 0x2000); // key in
+ //data & 0x4000 key out
+}
+
+
static ADDRESS_MAP_START( feversoc_map, AS_PROGRAM, 32, feversoc_state )
AM_RANGE(0x00000000, 0x0003ffff) AM_ROM
AM_RANGE(0x02000000, 0x0202ffff) AM_RAM AM_SHARE("workram1") //work ram
AM_RANGE(0x02030000, 0x0203ffff) AM_RAM AM_SHARE("nvram")
AM_RANGE(0x02034000, 0x0203dfff) AM_RAM AM_SHARE("workram2") //work ram
AM_RANGE(0x0203e000, 0x0203ffff) AM_RAM AM_SHARE("spriteram")
- AM_RANGE(0x06000000, 0x06000003) AM_WRITE(output_w)
+ AM_RANGE(0x06000000, 0x06000003) AM_WRITE16(output_w, 0xffff0000)
+ AM_RANGE(0x06000000, 0x06000003) AM_WRITE16(output2_w, 0x0000ffff)
AM_RANGE(0x06000004, 0x06000007) AM_WRITENOP //???
AM_RANGE(0x06000008, 0x0600000b) AM_READ(in0_r)
AM_RANGE(0x0600000c, 0x0600000f) AM_DEVREADWRITE8("oki", okim6295_device, read, write, 0x00ff0000)
diff --git a/src/mame/drivers/flstory.cpp b/src/mame/drivers/flstory.cpp
index 88505594557..47a3456f29c 100644
--- a/src/mame/drivers/flstory.cpp
+++ b/src/mame/drivers/flstory.cpp
@@ -70,7 +70,7 @@ static ADDRESS_MAP_START( flstory_map, AS_PROGRAM, 8, flstory_state )
AM_RANGE(0x0000, 0xbfff) AM_ROM
AM_RANGE(0xc000, 0xc7ff) AM_RAM_WRITE(flstory_videoram_w) AM_SHARE("videoram")
AM_RANGE(0xc800, 0xcfff) AM_RAM /* unknown */
- AM_RANGE(0xd000, 0xd000) AM_READWRITE(flstory_mcu_r, flstory_mcu_w)
+ AM_RANGE(0xd000, 0xd000) AM_DEVREADWRITE("bmcu", taito68705_mcu_device, mcu_r, mcu_w)
AM_RANGE(0xd001, 0xd001) AM_WRITENOP /* watchdog? */
AM_RANGE(0xd002, 0xd002) AM_WRITENOP /* coin lock out? */
AM_RANGE(0xd400, 0xd400) AM_READWRITE(from_snd_r, sound_command_w)
@@ -81,7 +81,7 @@ static ADDRESS_MAP_START( flstory_map, AS_PROGRAM, 8, flstory_state )
AM_RANGE(0xd802, 0xd802) AM_READ_PORT("DSW2")
AM_RANGE(0xd803, 0xd803) AM_READ_PORT("SYSTEM")
AM_RANGE(0xd804, 0xd804) AM_READ_PORT("P1")
- AM_RANGE(0xd805, 0xd805) AM_READ(flstory_mcu_status_r)
+ AM_RANGE(0xd805, 0xd805) AM_DEVREAD("bmcu", taito68705_mcu_device, mcu_status_r)
AM_RANGE(0xd806, 0xd806) AM_READ_PORT("P2")
// AM_RANGE(0xda00, 0xda00) AM_WRITEONLY
AM_RANGE(0xdc00, 0xdc9f) AM_RAM AM_SHARE("spriteram")
@@ -441,17 +441,6 @@ static ADDRESS_MAP_START( sound_map, AS_PROGRAM, 8, flstory_state )
AM_RANGE(0xe000, 0xefff) AM_ROM /* space for diagnostics ROM */
ADDRESS_MAP_END
-static ADDRESS_MAP_START( flstory_m68705_map, AS_PROGRAM, 8, flstory_state )
- ADDRESS_MAP_GLOBAL_MASK(0x7ff)
- AM_RANGE(0x0000, 0x0000) AM_READWRITE(flstory_68705_port_a_r, flstory_68705_port_a_w)
- AM_RANGE(0x0001, 0x0001) AM_READWRITE(flstory_68705_port_b_r, flstory_68705_port_b_w)
- AM_RANGE(0x0002, 0x0002) AM_READWRITE(flstory_68705_port_c_r, flstory_68705_port_c_w)
- AM_RANGE(0x0004, 0x0004) AM_WRITE(flstory_68705_ddr_a_w)
- AM_RANGE(0x0005, 0x0005) AM_WRITE(flstory_68705_ddr_b_w)
- AM_RANGE(0x0006, 0x0006) AM_WRITE(flstory_68705_ddr_c_w)
- AM_RANGE(0x0010, 0x007f) AM_RAM
- AM_RANGE(0x0080, 0x07ff) AM_ROM
-ADDRESS_MAP_END
@@ -992,22 +981,12 @@ void flstory_state::machine_start()
save_item(NAME(m_snd_ctrl2));
save_item(NAME(m_snd_ctrl3));
/* mcu */
- save_item(NAME(m_from_main));
- save_item(NAME(m_from_mcu));
- save_item(NAME(m_mcu_sent));
- save_item(NAME(m_main_sent));
- save_item(NAME(m_port_a_in));
- save_item(NAME(m_port_a_out));
- save_item(NAME(m_ddr_a));
- save_item(NAME(m_port_b_in));
- save_item(NAME(m_port_b_out));
- save_item(NAME(m_ddr_b));
- save_item(NAME(m_port_c_in));
- save_item(NAME(m_port_c_out));
- save_item(NAME(m_ddr_c));
save_item(NAME(m_mcu_select));
+ save_item(NAME(m_from_mcu));
}
+
+
MACHINE_RESET_MEMBER(flstory_state,flstory)
{
MACHINE_RESET_CALL_MEMBER(ta7630);
@@ -1026,20 +1005,8 @@ MACHINE_RESET_MEMBER(flstory_state,flstory)
m_snd_ctrl2 = 0;
m_snd_ctrl3 = 0;
/* mcu */
- m_from_main = 0;
- m_from_mcu = 0;
- m_mcu_sent = 0;
- m_main_sent = 0;
- m_port_a_in = 0;
- m_port_a_out = 0;
- m_ddr_a = 0;
- m_port_b_in = 0;
- m_port_b_out = 0;
- m_ddr_b = 0;
- m_port_c_in = 0;
- m_port_c_out = 0;
- m_ddr_c = 0;
m_mcu_select = 0;
+ m_from_mcu = 0;
}
static MACHINE_CONFIG_START( flstory, flstory_state )
@@ -1054,8 +1021,7 @@ static MACHINE_CONFIG_START( flstory, flstory_state )
MCFG_CPU_PERIODIC_INT_DRIVER(flstory_state, irq0_line_hold, 2*60) /* IRQ generated by ??? */
/* NMI generated by the main CPU */
- MCFG_CPU_ADD("mcu", M68705, XTAL_18_432MHz/6) /* verified on pcb */
- MCFG_CPU_PROGRAM_MAP(flstory_m68705_map)
+ MCFG_DEVICE_ADD("bmcu", TAITO68705_MCU, XTAL_18_432MHz/6) /* verified on pcb */
MCFG_QUANTUM_TIME(attotime::from_hz(6000)) /* 100 CPU slices per frame - an high value to ensure proper */
/* synchronization of the CPUs */
@@ -1316,7 +1282,7 @@ ROM_START( flstory )
ROM_LOAD( "snd.22", 0x0000, 0x2000, CRC(d58b201d) SHA1(1c9c2936ec95a8fa920d58668bea420c5e15008f) )
ROM_LOAD( "snd.23", 0x2000, 0x2000, CRC(25e7fd9d) SHA1(b9237459e3d8acf8502a693914e50714a37d515e) )
- ROM_REGION( 0x0800, "mcu", 0 ) /* 2k for the microcontroller */
+ ROM_REGION( 0x0800, "bmcu:mcu", 0 ) /* 2k for the microcontroller */
ROM_LOAD( "a45.mcu", 0x0000, 0x0800, CRC(5378253c) SHA1(e1ae1ab01e470b896c1d74ad4088928602a21a1b) )
ROM_REGION( 0x20000, "gfx1", ROMREGION_INVERT )
@@ -1340,7 +1306,7 @@ ROM_START( flstoryj )
ROM_LOAD( "a45_12.8", 0x0000, 0x2000, CRC(d6f593fb) SHA1(8551ef22c2cdd9df8d7949a178883f56ea56a4a2) )
ROM_LOAD( "a45_13.9", 0x2000, 0x2000, CRC(451f92f9) SHA1(f4196e6d3420983b74001303936d086a48b10827) )
- ROM_REGION( 0x0800, "mcu", 0 ) /* 2k for the microcontroller */
+ ROM_REGION( 0x0800, "bmcu:mcu", 0 ) /* 2k for the microcontroller */
ROM_LOAD( "a45.mcu", 0x0000, 0x0800, CRC(5378253c) SHA1(e1ae1ab01e470b896c1d74ad4088928602a21a1b) )
ROM_REGION( 0x20000, "gfx1", ROMREGION_INVERT )
@@ -1367,7 +1333,7 @@ ROM_START( onna34ro )
ROM_LOAD( "a52-15.37s", 0x6000, 0x2000, CRC(5afc21d0) SHA1(317d5fb3a48ce5e13e02c5c6431fa08ada115d27) )
ROM_LOAD( "a52-16.38s", 0x8000, 0x2000, CRC(ccf42aee) SHA1(a6eb01c5384724999631b55700dade430b71ca95) )
- ROM_REGION( 0x0800, "cpu2", 0 ) /* 2k for the microcontroller */
+ ROM_REGION( 0x0800, "bmcu:mcu", 0 ) /* 2k for the microcontroller */
ROM_LOAD( "a52-17.54c", 0x0000, 0x0800, NO_DUMP )
ROM_REGION( 0x20000, "gfx1", ROMREGION_INVERT )
@@ -1394,7 +1360,7 @@ ROM_START( onna34roa )
ROM_LOAD( "a52-15.37s", 0x6000, 0x2000, CRC(5afc21d0) SHA1(317d5fb3a48ce5e13e02c5c6431fa08ada115d27) )
ROM_LOAD( "a52-16.38s", 0x8000, 0x2000, CRC(ccf42aee) SHA1(a6eb01c5384724999631b55700dade430b71ca95) )
- ROM_REGION( 0x0800, "cpu2", 0 ) /* 2k for the microcontroller */
+ ROM_REGION( 0x0800, "bmcu:mcu", 0 ) /* 2k for the microcontroller */
ROM_LOAD( "a52-17.54c", 0x0000, 0x0800, NO_DUMP )
ROM_REGION( 0x20000, "gfx1", ROMREGION_INVERT )
@@ -1509,7 +1475,7 @@ ROM_START( victnine )
ROM_LOAD( "a16-16.38", 0x8000, 0x2000, CRC(9395351b) SHA1(8f97bdf03dec47bcaaa62fb66c545566776116be) )
ROM_LOAD( "a16-17.39", 0xa000, 0x2000, CRC(872270b3) SHA1(2298cb8ced6c3e9afb430faab1b38ba8f2fa93b5) )
- ROM_REGION( 0x0800, "cpu2", 0 ) /* 2k for the microcontroller */
+ ROM_REGION( 0x0800, "bmcu:mcu", 0 ) /* 2k for the microcontroller */
ROM_LOAD( "a16-18.mcu", 0x0000, 0x0800, NO_DUMP )
ROM_REGION( 0x10000, "gfx1", ROMREGION_INVERT )
@@ -1578,7 +1544,7 @@ ROM_START( rumba )
ROM_LOAD( "a23_09.bin", 0x2000, 0x2000, CRC(d0a101d3) SHA1(c92bb1ce67bec394fd8ce303d9e61eac12493b5d) )
ROM_LOAD( "a23_10.bin", 0x4000, 0x2000, CRC(f9447bd4) SHA1(68c02249ca0e5b923cddb4bff8d090963b9c78e4) )
- ROM_REGION( 0x0800, "mcu", 0 ) /* 2k for the microcontroller */
+ ROM_REGION( 0x0800, "bmcu:mcu", 0 ) /* 2k for the microcontroller */
ROM_LOAD( "a23-11.mc68705p5s", 0x0000, 0x0800, NO_DUMP )
ROM_REGION( 0x8000, "gfx1", ROMREGION_INVERT )
diff --git a/src/mame/drivers/fuukifg2.cpp b/src/mame/drivers/fuukifg2.cpp
index e6acae94603..083a8123a56 100644
--- a/src/mame/drivers/fuukifg2.cpp
+++ b/src/mame/drivers/fuukifg2.cpp
@@ -73,15 +73,12 @@ WRITE16_MEMBER(fuuki16_state::vregs_w)
}
}
-WRITE16_MEMBER(fuuki16_state::sound_command_w)
+WRITE8_MEMBER( fuuki16_state::sound_command_w )
{
- if (ACCESSING_BITS_0_7)
- {
- m_soundlatch->write(space,0,data & 0xff);
- m_audiocpu->set_input_line(INPUT_LINE_NMI, PULSE_LINE);
+ m_soundlatch->write(space,0,data & 0xff);
+ m_audiocpu->set_input_line(INPUT_LINE_NMI, PULSE_LINE);
// space.device().execute().spin_until_time(attotime::from_usec(50)); // Allow the other CPU to reply
- machine().scheduler().boost_interleave(attotime::zero, attotime::from_usec(50)); // Fixes glitching in rasters
- }
+ machine().scheduler().boost_interleave(attotime::zero, attotime::from_usec(50)); // Fixes glitching in rasters
}
static ADDRESS_MAP_START( fuuki16_map, AS_PROGRAM, 16, fuuki16_state )
@@ -96,7 +93,7 @@ static ADDRESS_MAP_START( fuuki16_map, AS_PROGRAM, 16, fuuki16_state )
AM_RANGE(0x800000, 0x800001) AM_READ_PORT("SYSTEM")
AM_RANGE(0x810000, 0x810001) AM_READ_PORT("P1_P2")
AM_RANGE(0x880000, 0x880001) AM_READ_PORT("DSW")
- AM_RANGE(0x8a0000, 0x8a0001) AM_WRITE(sound_command_w) // To Sound CPU
+ AM_RANGE(0x8a0000, 0x8a0001) AM_WRITE8(sound_command_w, 0x00ff) // To Sound CPU
AM_RANGE(0x8c0000, 0x8c001f) AM_RAM_WRITE(vregs_w) AM_SHARE("vregs") // Video Registers
AM_RANGE(0x8d0000, 0x8d0003) AM_RAM AM_SHARE("unknown") //
AM_RANGE(0x8e0000, 0x8e0001) AM_RAM AM_SHARE("priority") //
diff --git a/src/mame/drivers/gaelco.cpp b/src/mame/drivers/gaelco.cpp
index 05e49b3370a..d339a03b0d5 100644
--- a/src/mame/drivers/gaelco.cpp
+++ b/src/mame/drivers/gaelco.cpp
@@ -33,39 +33,30 @@ Year Game PCB NOTES
*
*************************************/
-WRITE16_MEMBER(gaelco_state::bigkarnk_sound_command_w)
+WRITE8_MEMBER(gaelco_state::bigkarnk_sound_command_w)
{
- if (ACCESSING_BITS_0_7)
- {
- m_soundlatch->write(space, 0, data & 0xff);
- m_audiocpu->set_input_line(M6809_FIRQ_LINE, HOLD_LINE);
- }
+ m_soundlatch->write(space, 0, data);
+ m_audiocpu->set_input_line(M6809_FIRQ_LINE, HOLD_LINE);
}
-WRITE16_MEMBER(gaelco_state::bigkarnk_coin_w)
+WRITE8_MEMBER(gaelco_state::bigkarnk_coin_w)
{
- if (ACCESSING_BITS_0_7)
+ switch ((offset >> 3))
{
- switch ((offset >> 3))
- {
- case 0x00: /* Coin Lockouts */
- case 0x01:
- machine().bookkeeping().coin_lockout_w((offset >> 3) & 0x01, ~data & 0x01);
- break;
- case 0x02: /* Coin Counters */
- case 0x03:
- machine().bookkeeping().coin_counter_w((offset >> 3) & 0x01, data & 0x01);
- break;
- }
+ case 0x00: /* Coin Lockouts */
+ case 0x01:
+ machine().bookkeeping().coin_lockout_w((offset >> 3) & 0x01, ~data & 0x01);
+ break;
+ case 0x02: /* Coin Counters */
+ case 0x03:
+ machine().bookkeeping().coin_counter_w((offset >> 3) & 0x01, data & 0x01);
+ break;
}
}
-WRITE16_MEMBER(gaelco_state::OKIM6295_bankswitch_w)
+WRITE8_MEMBER(gaelco_state::OKIM6295_bankswitch_w)
{
- if (ACCESSING_BITS_0_7)
- {
- membank("okibank")->set_entry(data & 0x0f);
- }
+ membank("okibank")->set_entry(data & 0x0f);
}
/*********** Squash Encryption Related Code ******************/
@@ -124,8 +115,8 @@ static ADDRESS_MAP_START( bigkarnk_map, AS_PROGRAM, 16, gaelco_state )
AM_RANGE(0x700004, 0x700005) AM_READ_PORT("P1")
AM_RANGE(0x700006, 0x700007) AM_READ_PORT("P2")
AM_RANGE(0x700008, 0x700009) AM_READ_PORT("SERVICE")
- AM_RANGE(0x70000e, 0x70000f) AM_WRITE(bigkarnk_sound_command_w) /* Triggers a FIRQ on the sound CPU */
- AM_RANGE(0x70000a, 0x70003b) AM_WRITE(bigkarnk_coin_w) /* Coin Counters + Coin Lockout */
+ AM_RANGE(0x70000e, 0x70000f) AM_WRITE8(bigkarnk_sound_command_w, 0x00ff) /* Triggers a FIRQ on the sound CPU */
+ AM_RANGE(0x70000a, 0x70003b) AM_WRITE8(bigkarnk_coin_w, 0x00ff) /* Coin Counters + Coin Lockout */
AM_RANGE(0xff8000, 0xffffff) AM_RAM /* Work RAM */
ADDRESS_MAP_END
@@ -150,7 +141,7 @@ static ADDRESS_MAP_START( maniacsq_map, AS_PROGRAM, 16, gaelco_state )
AM_RANGE(0x700002, 0x700003) AM_READ_PORT("DSW1")
AM_RANGE(0x700004, 0x700005) AM_READ_PORT("P1")
AM_RANGE(0x700006, 0x700007) AM_READ_PORT("P2")
- AM_RANGE(0x70000c, 0x70000d) AM_WRITE(OKIM6295_bankswitch_w) /* OKI6295 bankswitch */
+ AM_RANGE(0x70000c, 0x70000d) AM_WRITE8(OKIM6295_bankswitch_w, 0x00ff)
AM_RANGE(0x70000e, 0x70000f) AM_DEVREADWRITE8("oki", okim6295_device, read, write, 0x00ff) /* OKI6295 status register */
AM_RANGE(0xff0000, 0xffffff) AM_RAM /* Work RAM */
ADDRESS_MAP_END
@@ -167,7 +158,7 @@ static ADDRESS_MAP_START( squash_map, AS_PROGRAM, 16, gaelco_state )
AM_RANGE(0x700002, 0x700003) AM_READ_PORT("DSW1")
AM_RANGE(0x700004, 0x700005) AM_READ_PORT("P1")
AM_RANGE(0x700006, 0x700007) AM_READ_PORT("P2")
- AM_RANGE(0x70000c, 0x70000d) AM_WRITE(OKIM6295_bankswitch_w) /* OKI6295 bankswitch */
+ AM_RANGE(0x70000c, 0x70000d) AM_WRITE8(OKIM6295_bankswitch_w, 0x00ff)
AM_RANGE(0x70000e, 0x70000f) AM_DEVREADWRITE8("oki", okim6295_device, read, write, 0x00ff) /* OKI6295 status register */
AM_RANGE(0xff0000, 0xffffff) AM_RAM /* Work RAM */
ADDRESS_MAP_END
@@ -184,7 +175,7 @@ static ADDRESS_MAP_START( thoop_map, AS_PROGRAM, 16, gaelco_state )
AM_RANGE(0x700002, 0x700003) AM_READ_PORT("DSW1")
AM_RANGE(0x700004, 0x700005) AM_READ_PORT("P1")
AM_RANGE(0x700006, 0x700007) AM_READ_PORT("P2")
- AM_RANGE(0x70000c, 0x70000d) AM_WRITE(OKIM6295_bankswitch_w) /* OKI6295 bankswitch */
+ AM_RANGE(0x70000c, 0x70000d) AM_WRITE8(OKIM6295_bankswitch_w, 0x00ff)
AM_RANGE(0x70000e, 0x70000f) AM_DEVREADWRITE8("oki", okim6295_device, read, write, 0x00ff) /* OKI6295 status register */
AM_RANGE(0xff0000, 0xffffff) AM_RAM /* Work RAM */
ADDRESS_MAP_END
diff --git a/src/mame/drivers/gkigt.cpp b/src/mame/drivers/gkigt.cpp
index 9ea66279d0c..451b249cb1c 100644
--- a/src/mame/drivers/gkigt.cpp
+++ b/src/mame/drivers/gkigt.cpp
@@ -86,6 +86,7 @@ More chips (from eBay auction):
#include "emu.h"
#include "cpu/i960/i960.h"
#include "sound/ymz280b.h"
+#include "machine/nvram.h"
class igt_gameking_state : public driver_device
{
@@ -191,7 +192,9 @@ static ADDRESS_MAP_START( igt_gameking_mem, AS_PROGRAM, 32, igt_gameking_state )
AM_RANGE(0x00000000, 0x0007ffff) AM_ROM
AM_RANGE(0x08000000, 0x081fffff) AM_ROM AM_REGION("game", 0)
- AM_RANGE(0x10000000, 0x10ffffff) AM_RAM
+ // it's unclear how much of this is saved and how much total RAM there is.
+ AM_RANGE(0x10000000, 0x1001ffff) AM_RAM AM_SHARE("nvram")
+ AM_RANGE(0x10020000, 0x100fffff) AM_RAM
AM_RANGE(0x18000000, 0x181fffff) AM_RAM // igtsc writes from 18000000 to 1817ffff, ms3 all the way to 181fffff.
@@ -255,6 +258,7 @@ static MACHINE_CONFIG_START( igt_gameking, igt_gameking_state )
MCFG_SOUND_ADD("ymz", YMZ280B, XTAL_16_9344MHz) // enhanced sound on optional Media-Lite sub board
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0)
+ MCFG_NVRAM_ADD_1FILL("nvram")
MACHINE_CONFIG_END
ROM_START( ms3 )
@@ -275,6 +279,9 @@ ROM_START( ms3 )
ROM_REGION( 0x200000, "snd", 0 )
ROM_LOAD( "1h5053xx.u6", 0x000000, 0x080000, CRC(6735c65a) SHA1(198cacec5441aa615c0de63a0b4e47265636bcee) )
+
+ ROM_REGION( 0x20000, "nvram", 0 )
+ ROM_LOAD( "nvram", 0x000000, 0x020000, CRC(acbbc6d9) SHA1(6e86d24ad3793b41f1f23f80f9bdb22767abc3bf) )
ROM_END
ROM_START( ms72c )
@@ -295,6 +302,9 @@ ROM_START( ms72c )
ROM_REGION( 0x200000, "snd", 0 )
ROM_LOAD( "1H5008FA Multistar 7.u6", 0x000000, 0x100000, CRC(69656637) SHA1(28c2cf48856ee4f820146fdbd0f3c7e307892dc6) )
+
+ ROM_REGION( 0x20000, "nvram", 0 )
+ ROM_LOAD( "nvram", 0x000000, 0x020000, CRC(b5e42dbc) SHA1(f6afadb6877bca2cef40725b001c7918f9c99359) )
ROM_END
diff --git a/src/mame/drivers/gsword.cpp b/src/mame/drivers/gsword.cpp
index 3e12a6a93e8..3232cf2eb29 100644
--- a/src/mame/drivers/gsword.cpp
+++ b/src/mame/drivers/gsword.cpp
@@ -1,5 +1,5 @@
// license:BSD-3-Clause
-// copyright-holders:Steve Ellenoff,Jarek Parchanski
+// copyright-holders:Steve Ellenoff,Jarek Parchanski,Vas Crabb
/*
Great Swordsman (Taito) 1984
Joshi Volleyball (Taito) 1983
@@ -9,9 +9,9 @@ TODO:
-joshi volleyball
-The incomplete graphic
-The implementation of DAC sound ?
- -MCU code DUMP and emulation
+ -MCU hookup is incomplete
-The true interrupt circuit of SUB CPU
- -unknown ROM (BANK ROM of sub-cpu ? )
+ -unknown ROM (BANK ROM of sub-cpu ?)
Credits:
- Steve Ellenoff: Original emulation and Mame driver
@@ -144,9 +144,13 @@ reg: 0->1 (main->2nd) / : (1->0) 2nd->main :
******************************************/
#include "emu.h"
+#include "includes/gsword.h"
+
+#include "cpu/mcs48/mcs48.h"
#include "cpu/z80/z80.h"
+#include "machine/i8255.h"
#include "machine/tait8741.h"
-#include "includes/gsword.h"
+
#if 0
@@ -163,20 +167,48 @@ int gsword_state::coins_in(void)
}
#endif
-#include "cpu/z80/z80.h"
+void gsword_state_base::machine_start()
+{
+ save_item(NAME(m_fake8910_0));
+ save_item(NAME(m_fake8910_1));
+}
+
+void gsword_state_base::machine_reset()
+{
+}
+
+WRITE8_MEMBER(gsword_state_base::ay8910_control_port_0_w)
+{
+ m_ay0->address_w(space,offset,data);
+ m_fake8910_0 = data;
+}
+WRITE8_MEMBER(gsword_state_base::ay8910_control_port_1_w)
+{
+ m_ay1->address_w(space,offset,data);
+ m_fake8910_1 = data;
+}
+
+READ8_MEMBER(gsword_state_base::fake_0_r)
+{
+ return m_fake8910_0+1;
+}
+READ8_MEMBER(gsword_state_base::fake_1_r)
+{
+ return m_fake8910_1+1;
+}
/* CPU 2 memory hack */
/* (402E) timeout upcount must be under 0AH */
/* (4004,4005) clear down counter , if (4004,4005)==0 then (402E)=0 */
-READ8_MEMBER(gsword_state::gsword_hack_r)
+READ8_MEMBER(gsword_state::hack_r)
{
- uint8_t data = m_cpu2_ram[offset + 4];
+ u8 const data = m_cpu2_ram[offset + 4];
/*if(offset==1)osd_printf_debug("CNT %02X%02X\n",m_cpu2_ram[5],m_cpu2_ram[4]); */
/* speedup timeout count down */
- if(m_protect_hack)
+ if (m_protect_hack)
{
switch(offset)
{
@@ -187,7 +219,55 @@ READ8_MEMBER(gsword_state::gsword_hack_r)
return data;
}
-READ8_MEMBER(gsword_state::gsword_8741_2_r )
+WRITE8_MEMBER(gsword_state::nmi_set_w)
+{
+/* osd_printf_debug("AY write %02X\n",data);*/
+
+ m_protect_hack = (data & 0x80) ? false : true;
+#if 0
+ /* An actual circuit isn't known. */
+ /* write ff,02,ff,fe, 17 x 0d,0f */
+ m_nmi_enable = ((data>>7) & (data&1) &1) == 0;
+
+
+#else
+ switch(data)
+ {
+ case 0xff:
+ m_nmi_enable = false; /* NMI must be disabled */
+ break;
+ case 0x02:
+ m_nmi_enable = false; /* ANY */
+ break;
+ case 0x0d:
+ m_nmi_enable = true;
+ break;
+ case 0x0f:
+ m_nmi_enable = true; /* NMI must be enabled */
+ break;
+ case 0xfe:
+ m_nmi_enable = true; /* NMI must be enabled */
+ break;
+ }
+ /* bit1= nmi disable , for ram check */
+ logerror("NMI control %02x\n",data);
+#endif
+}
+
+WRITE8_MEMBER(gsword_state::sound_command_w)
+{
+ m_soundlatch->write(space, 0, data);
+ m_audiocpu->set_input_line(INPUT_LINE_NMI, PULSE_LINE);
+}
+
+WRITE8_MEMBER(gsword_state::adpcm_data_w)
+{
+ m_msm->data_w(data & 0x0f); // bit 0..3
+ m_msm->reset_w(BIT(data, 5)); // bit 5
+ m_msm->vclk_w(BIT(data, 4)); // bit 4
+}
+
+READ8_MEMBER(gsword_state::i8741_2_r )
{
switch (offset)
{
@@ -204,7 +284,7 @@ READ8_MEMBER(gsword_state::gsword_8741_2_r )
return 0;
}
-READ8_MEMBER(gsword_state::gsword_8741_3_r )
+READ8_MEMBER(gsword_state::i8741_3_r )
{
switch (offset)
{
@@ -220,99 +300,166 @@ READ8_MEMBER(gsword_state::gsword_8741_3_r )
return 0;
}
+INTERRUPT_GEN_MEMBER(gsword_state::sound_interrupt)
+{
+ if (m_nmi_enable)
+ device.execute().set_input_line(INPUT_LINE_NMI, PULSE_LINE);
+}
+
+DRIVER_INIT_MEMBER(gsword_state, gsword)
+{
+#if 0
+ uint8_t *ROM2 = memregion("sub")->base();
+ ROM2[0x1da] = 0xc3; /* patch for rom self check */
+
+ ROM2[0x71e] = 0; /* patch for sound protection or time out function */
+ ROM2[0x71f] = 0;
+#endif
+#if 1
+ /* hack for sound protection or time out function */
+ m_subcpu->space(AS_PROGRAM).install_read_handler(0x4004, 0x4005, read8_delegate(FUNC(gsword_state::hack_r),this));
+#endif
+}
+
+DRIVER_INIT_MEMBER(gsword_state, gsword2)
+{
+#if 0
+ uint8_t *ROM2 = memregion("sub")->base();
+
+ ROM2[0x1da] = 0xc3; /* patch for rom self check */
+ ROM2[0x726] = 0; /* patch for sound protection or time out function */
+ ROM2[0x727] = 0;
+#endif
+#if 1
+ /* hack for sound protection or time out function */
+ m_subcpu->space(AS_PROGRAM).install_read_handler(0x4004, 0x4005, read8_delegate(FUNC(gsword_state::hack_r),this));
+#endif
+}
+
void gsword_state::machine_start()
{
- save_item(NAME(m_fake8910_0));
- save_item(NAME(m_fake8910_1));
- save_item(NAME(m_nmi_enable));
+ gsword_state_base::machine_start();
+
save_item(NAME(m_protect_hack));
+ save_item(NAME(m_nmi_enable));
}
void gsword_state::machine_reset()
{
- m_coins = 0;
+ gsword_state_base::machine_reset();
- /* snd CPU mask NMI during reset phase */
- m_nmi_enable = 0;
- m_protect_hack = 0;
+ m_protect_hack = false;
+ m_nmi_enable = false;
}
-INTERRUPT_GEN_MEMBER(gsword_state::gsword_snd_interrupt)
+
+READ8_MEMBER(josvolly_state::mcu1_p1_r)
{
- if(m_nmi_enable)
- device.execute().set_input_line(INPUT_LINE_NMI, PULSE_LINE);
+ // the two MCUs appear to have port 1 tied together
+ return m_mcu1_p1 & m_mcu2_p1;
}
-WRITE8_MEMBER(gsword_state::nmi_set_w)
+READ8_MEMBER(josvolly_state::mcu1_p2_r)
{
-/* osd_printf_debug("AY write %02X\n",data);*/
+ // p27 needs to float high for the MCU to start in the right mode
+ // p20 and p21 drive the test inputs of the other MCU
+ // if DIPSW1:8 is allowed to pull p27 low, the game won't even boot to test mode
+ // DIPSW1:1 and DIPSW1:2 are shown in test mode, but switching them on will break comms
+ return 0x80U | ioport("DSW1")->read();
+}
- m_protect_hack = (data&0x80) ? 0 : 1;
-#if 0
- /* An actual circuit isn't known. */
- /* write ff,02,ff,fe, 17 x 0d,0f */
- m_nmi_enable = ((data>>7) & (data&1) &1) == 0;
+READ8_MEMBER(josvolly_state::mcu2_p1_r)
+{
+ // the two MCUs appear to have port 1 tied together
+ return m_mcu1_p1 & m_mcu2_p1;
+}
+READ8_MEMBER(josvolly_state::mcu2_p2_r)
+{
+ // p27 needs to be tied low for the MCU to start in the right mode
+ return 0x7fU & ioport("DSW2")->read();
+}
-#else
- switch(data)
- {
- case 0xff:
- m_nmi_enable = 0; /* NMI must be disabled */
- break;
- case 0x02:
- m_nmi_enable = 0; /* ANY */
- break;
- case 0x0d:
- m_nmi_enable = 1;
- break;
- case 0x0f:
- m_nmi_enable = 1; /* NMI must be enabled */
- break;
- case 0xfe:
- m_nmi_enable = 1; /* NMI must be enabled */
- break;
- }
- /* bit1= nmi disable , for ram check */
- logerror("NMI control %02x\n",data);
-#endif
+READ8_MEMBER(josvolly_state::mcu2_test_r)
+{
+ // TEST0 and TEST1 are driven by P20 and P21 on the other MCU
+ return BIT(m_mcu1_p2, offset);
}
-WRITE8_MEMBER(gsword_state::ay8910_control_port_0_w)
+WRITE8_MEMBER(josvolly_state::cpu2_nmi_enable_w)
{
- m_ay0->address_w(space,offset,data);
- m_fake8910_0 = data;
+ m_cpu2_nmi_enable = true;
}
-WRITE8_MEMBER(gsword_state::ay8910_control_port_1_w)
+
+WRITE8_MEMBER(josvolly_state::cpu2_irq_clear_w)
{
- m_ay1->address_w(space,offset,data);
- m_fake8910_1 = data;
+ m_audiocpu->set_input_line(INPUT_LINE_IRQ0, CLEAR_LINE);
}
-READ8_MEMBER(gsword_state::fake_0_r)
+WRITE8_MEMBER(josvolly_state::mcu1_p1_w)
{
- return m_fake8910_0+1;
+ if (data != m_mcu1_p1)
+ {
+ logerror("mcu1 p1 = 0x%02x\n", data);
+ m_mcu1_p1 = data;
+ }
}
-READ8_MEMBER(gsword_state::fake_1_r)
+
+WRITE8_MEMBER(josvolly_state::mcu1_p2_w)
{
- return m_fake8910_1+1;
+ if (data != m_mcu1_p2)
+ {
+ logerror("mcu1 p2 = 0x%02x\n", data);
+
+ // the second CPU somehow gets an NMI when data is available
+ // it's probably implemented by the logic arrays somehow
+ // this is just a hacky guess at how it works
+ if (m_cpu2_nmi_enable && (data & (data ^ m_mcu1_p2) & 0x01))
+ {
+ m_audiocpu->set_input_line(INPUT_LINE_NMI, PULSE_LINE);
+ m_cpu2_nmi_enable = false;
+ }
+
+ m_mcu1_p2 = data;
+ }
}
-WRITE8_MEMBER(gsword_state::gsword_adpcm_data_w)
+WRITE8_MEMBER(josvolly_state::mcu2_p1_w)
{
- m_msm->data_w (data & 0x0f); /* bit 0..3 */
- m_msm->reset_w(BIT(data, 5)); /* bit 5 */
- m_msm->vclk_w(BIT(data, 4)); /* bit 4 */
+ if (data != m_mcu2_p1)
+ {
+ logerror("mcu2 p1 = 0x%02x\n", data);
+ m_mcu2_p1 = data;
+ }
}
-WRITE8_MEMBER(gsword_state::adpcm_soundcommand_w)
+WRITE8_MEMBER(josvolly_state::mcu2_p2_w)
{
- m_soundlatch->write(space, 0, data);
- m_audiocpu->set_input_line(INPUT_LINE_NMI, PULSE_LINE);
+ logerror("mcu2 p2 = 0x%02x\n", data);
}
+void josvolly_state::machine_start()
+{
+ gsword_state_base::machine_start();
+
+ save_item(NAME(m_cpu2_nmi_enable));
+ save_item(NAME(m_mcu1_p1));
+ save_item(NAME(m_mcu1_p2));
+ save_item(NAME(m_mcu2_p1));
+}
-static ADDRESS_MAP_START( cpu1_map, AS_PROGRAM , 8, gsword_state )
+void josvolly_state::machine_reset()
+{
+ gsword_state_base::machine_reset();
+
+ m_cpu2_nmi_enable = false;
+ m_mcu1_p1 = 0xffU;
+ m_mcu1_p2 = 0xffU;
+ m_mcu2_p1 = 0xffU;
+}
+
+
+static ADDRESS_MAP_START( cpu1_map, AS_PROGRAM , 8, gsword_state_base )
AM_RANGE(0x0000, 0x8fff) AM_ROM
AM_RANGE(0x9000, 0x9fff) AM_RAM
AM_RANGE(0xa000, 0xa37f) AM_RAM
@@ -326,21 +473,16 @@ static ADDRESS_MAP_START( cpu1_map, AS_PROGRAM , 8, gsword_state )
AM_RANGE(0xb000, 0xb7ff) AM_RAM_WRITE(videoram_w) AM_SHARE("videoram")
ADDRESS_MAP_END
+
static ADDRESS_MAP_START( cpu1_io_map, AS_IO, 8, gsword_state )
ADDRESS_MAP_GLOBAL_MASK(0xff)
AM_RANGE(0x7e, 0x7f) AM_DEVREADWRITE("taito8741", taito8741_4pack_device, read_0, write_0)
ADDRESS_MAP_END
-static ADDRESS_MAP_START( josvolly_cpu1_io_map, AS_IO, 8, gsword_state )
- ADDRESS_MAP_GLOBAL_MASK(0xff)
- AM_RANGE(0x7e, 0x7f) AM_DEVREADWRITE("josvolly_8741", josvolly8741_4pack_device, read_0, write_0)
-ADDRESS_MAP_END
-
-//
static ADDRESS_MAP_START( cpu2_map, AS_PROGRAM, 8, gsword_state )
AM_RANGE(0x0000, 0x3fff) AM_ROM
AM_RANGE(0x4000, 0x43ff) AM_RAM AM_SHARE("cpu2_ram")
- AM_RANGE(0x6000, 0x6000) AM_WRITE(adpcm_soundcommand_w)
+ AM_RANGE(0x6000, 0x6000) AM_WRITE(sound_command_w)
ADDRESS_MAP_END
static ADDRESS_MAP_START( cpu2_io_map, AS_IO, 8, gsword_state )
@@ -352,46 +494,58 @@ static ADDRESS_MAP_START( cpu2_io_map, AS_IO, 8, gsword_state )
AM_RANGE(0x61, 0x61) AM_DEVREADWRITE("ay1", ay8910_device, data_r, data_w)
AM_RANGE(0x80, 0x80) AM_READWRITE(fake_1_r, ay8910_control_port_1_w)
AM_RANGE(0x81, 0x81) AM_DEVREADWRITE("ay2", ay8910_device, data_r, data_w)
-//
+
AM_RANGE(0xe0, 0xe0) AM_READNOP /* ?? */
AM_RANGE(0xa0, 0xa0) AM_WRITENOP /* ?? */
- AM_RANGE(0xe0, 0xe0) AM_WRITENOP /* watch dog ?*/
+ AM_RANGE(0xe0, 0xe0) AM_WRITENOP /* watchdog? */
ADDRESS_MAP_END
-//
-
static ADDRESS_MAP_START( cpu3_map, AS_PROGRAM, 8, gsword_state )
AM_RANGE(0x0000, 0x7fff) AM_ROM
- AM_RANGE(0x8000, 0x8000) AM_WRITE(gsword_adpcm_data_w)
+ AM_RANGE(0x8000, 0x8000) AM_WRITE(adpcm_data_w)
AM_RANGE(0xa000, 0xa000) AM_DEVREAD("soundlatch", generic_latch_8_device, read)
ADDRESS_MAP_END
-static ADDRESS_MAP_START( josvolly_cpu2_map, AS_PROGRAM, 8, gsword_state )
+static ADDRESS_MAP_START( josvolly_cpu1_io_map, AS_IO, 8, josvolly_state )
+ ADDRESS_MAP_GLOBAL_MASK(0xff)
+ AM_RANGE(0x7e, 0x7f) AM_DEVREADWRITE("mcu1", upi41_cpu_device, upi41_master_r, upi41_master_w)
+ADDRESS_MAP_END
+
+static ADDRESS_MAP_START( josvolly_cpu2_map, AS_PROGRAM, 8, josvolly_state )
AM_RANGE(0x0000, 0x3fff) AM_ROM
AM_RANGE(0x4000, 0x43ff) AM_RAM AM_SHARE("cpu2_ram")
- /* 8000 to 8003 looks MCU */
- AM_RANGE(0x8000, 0x8000) AM_READ_PORT("IN1") // 1PL
- AM_RANGE(0x8001, 0x8001) AM_READ_PORT("IN2") // 2PL / ACK
- AM_RANGE(0x8002, 0x8002) AM_READ_PORT("IN0") // START
+ /* NEC D8255A with silkscreen removed and replaced with "AA 007" */
+ AM_RANGE(0x8000, 0x8003) AM_DEVREADWRITE("aa_007", i8255_device, read, write)
// AM_RANGE(0x6000, 0x6000) AM_WRITE(adpcm_soundcommand_w)
- AM_RANGE(0xA000, 0xA001) AM_DEVREADWRITE("josvolly_8741", josvolly8741_4pack_device, read_1, write_1)
+ AM_RANGE(0xA000, 0xA001) AM_DEVREADWRITE("mcu2", upi41_cpu_device, upi41_master_r, upi41_master_w)
ADDRESS_MAP_END
-static ADDRESS_MAP_START( josvolly_cpu2_io_map, AS_IO, 8, gsword_state )
+static ADDRESS_MAP_START( josvolly_cpu2_io_map, AS_IO, 8, josvolly_state )
ADDRESS_MAP_GLOBAL_MASK(0xff)
AM_RANGE(0x00, 0x00) AM_READWRITE(fake_0_r, ay8910_control_port_0_w)
AM_RANGE(0x01, 0x01) AM_DEVREADWRITE("ay1", ay8910_device, data_r, data_w)
AM_RANGE(0x40, 0x40) AM_READWRITE(fake_1_r, ay8910_control_port_1_w)
AM_RANGE(0x41, 0x41) AM_DEVREADWRITE("ay2", ay8910_device, data_r, data_w)
- AM_RANGE(0x81, 0x81) AM_DEVWRITE("josvolly_8741", josvolly8741_4pack_device, nmi_enable_w)
- AM_RANGE(0xC1, 0xC1) AM_NOP // irq clear
+ AM_RANGE(0x81, 0x81) AM_WRITE(cpu2_nmi_enable_w);
+ AM_RANGE(0xC1, 0xC1) AM_WRITE(cpu2_irq_clear_w);
+ADDRESS_MAP_END
+
+static ADDRESS_MAP_START( josvolly_mcu1_io_map, AS_IO, 8, josvolly_state )
+ AM_RANGE(MCS48_PORT_P1, MCS48_PORT_P1) AM_READWRITE(mcu1_p1_r, mcu1_p1_w)
+ AM_RANGE(MCS48_PORT_P2, MCS48_PORT_P2) AM_READWRITE(mcu1_p2_r, mcu1_p2_w)
+ADDRESS_MAP_END
+static ADDRESS_MAP_START( josvolly_mcu2_io_map, AS_IO, 8, josvolly_state )
+ AM_RANGE(MCS48_PORT_P1, MCS48_PORT_P1) AM_READWRITE(mcu2_p1_r, mcu2_p1_w)
+ AM_RANGE(MCS48_PORT_P2, MCS48_PORT_P2) AM_READWRITE(mcu2_p2_r, mcu2_p2_w)
+ AM_RANGE(MCS48_PORT_T0, MCS48_PORT_T1) AM_READ(mcu2_test_r)
ADDRESS_MAP_END
+
static INPUT_PORTS_START( gsword )
PORT_START("IN0") /* IN0 (8741-2 port1?) */
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_START1 )
@@ -538,44 +692,55 @@ static INPUT_PORTS_START( josvolly )
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNKNOWN )
PORT_START("DSW1") /* DSW1 */
- PORT_DIPNAME( 0x0c, 0x00, "DIP1-0c(982E)" )
+ PORT_DIPNAME( 0x01, 0x01, DEF_STR( Unused ) ) PORT_DIPLOCATION("DIPSW1:1")
+ PORT_DIPSETTING( 0x01, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x02, 0x02, DEF_STR( Unused ) ) PORT_DIPLOCATION("DIPSW1:2")
+ PORT_DIPSETTING( 0x02, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x0c, 0x0c, "982E" ) PORT_DIPLOCATION("DIPSW1:3,4")
PORT_DIPSETTING( 0x0c, "0" )
PORT_DIPSETTING( 0x08, "1" )
- PORT_DIPSETTING( 0x00, "2" )
- PORT_DIPSETTING( 0x0c, "3" )
- PORT_DIPNAME( 0x30, 0x00, "DIP1-30(982A)" )
- PORT_DIPSETTING( 0x30, "96H" )
- PORT_DIPSETTING( 0x20, "78H" )
- PORT_DIPSETTING( 0x10, "5AH" )
- PORT_DIPSETTING( 0x00, "3CH" )
- PORT_DIPNAME( 0x40, 0x40, "TEST_MODE" )
+ PORT_DIPSETTING( 0x04, "2" )
+ PORT_DIPSETTING( 0x00, "3" )
+ PORT_DIPNAME( 0x30, 0x30, "982A" ) PORT_DIPLOCATION("DIPSW1:5,6")
+ PORT_DIPSETTING( 0x00, "60" )
+ PORT_DIPSETTING( 0x10, "90" )
+ PORT_DIPSETTING( 0x20, "120" )
+ PORT_DIPSETTING( 0x30, "150" )
+ PORT_DIPNAME( 0x40, 0x40, "TEST_MODE" ) PORT_DIPLOCATION("DIPSW1:7")
PORT_DIPSETTING( 0x40, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_DIPNAME( 0x80, 0x80, "DIP1-80(982C)" )
- PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x80, DEF_STR( On ) )
+ PORT_DIPNAME( 0x80, 0x80, DEF_STR( Unused ) ) PORT_DIPLOCATION("DIPSW1:8")
+ PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_START("DSW2") /* DSW2 */
-// PORT_DIPNAME( 0x01, 0x00, "DSW2-0" )
-// PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
-// PORT_DIPSETTING( 0x01, DEF_STR( On ) )
-// PORT_DIPNAME( 0x02, 0x00, "DSW2-1($9831)" )
-// PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
-// PORT_DIPSETTING( 0x02, DEF_STR( On ) )
- PORT_DIPNAME( 0x0C, 0x0C, DEF_STR( Coin_A ) )
+ PORT_DIPNAME( 0x01, 0x01, "982C" ) PORT_DIPLOCATION("DIPSW2:8")
+ PORT_DIPSETTING( 0x01, "0" )
+ PORT_DIPSETTING( 0x00, "1" )
+ PORT_DIPNAME( 0x02, 0x02, DEF_STR( Cabinet ) ) PORT_DIPLOCATION("DIPSW2:7")
+ PORT_DIPSETTING( 0x02, DEF_STR( Upright ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( Cocktail ) )
+ PORT_DIPNAME( 0x0c, 0x0c, DEF_STR( Coin_A ) ) PORT_DIPLOCATION("DIPSW2:6,5")
PORT_DIPSETTING( 0x00, DEF_STR( 5C_1C ) )
PORT_DIPSETTING( 0x08, DEF_STR( 4C_1C ) )
PORT_DIPSETTING( 0x04, DEF_STR( 2C_1C ) )
- PORT_DIPSETTING( 0x0C, DEF_STR( 1C_1C ) )
- PORT_DIPNAME( 0x30, 0x30, DEF_STR( Coin_B ) )
+ PORT_DIPSETTING( 0x0c, DEF_STR( 1C_1C ) )
+ PORT_DIPNAME( 0x30, 0x30, DEF_STR( Coin_B ) ) PORT_DIPLOCATION("DIPSW2:4,3")
PORT_DIPSETTING( 0x30, DEF_STR( 1C_1C ) )
PORT_DIPSETTING( 0x10, DEF_STR( 1C_2C ) )
PORT_DIPSETTING( 0x20, DEF_STR( 1C_4C ) )
PORT_DIPSETTING( 0x00, DEF_STR( 1C_5C ) )
-// PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNKNOWN )
-// PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNKNOWN )
+ PORT_DIPNAME( 0x40, 0x40, "9827" ) PORT_DIPLOCATION("DIPSW2:2")
+ PORT_DIPSETTING( 0x40, "1" )
+ PORT_DIPSETTING( 0x00, "3" )
+ PORT_DIPNAME( 0x80, 0x80, DEF_STR( Unused ) ) PORT_DIPLOCATION("DIPSW2:1")
+ PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
INPUT_PORTS_END
+
static const gfx_layout gsword_text =
{
8,8, /* 8x8 characters */
@@ -635,7 +800,7 @@ static MACHINE_CONFIG_START( gsword, gsword_state )
MCFG_CPU_ADD("sub", Z80, XTAL_18MHz/6) /* verified on pcb */
MCFG_CPU_PROGRAM_MAP(cpu2_map)
MCFG_CPU_IO_MAP(cpu2_io_map)
- MCFG_CPU_PERIODIC_INT_DRIVER(gsword_state, gsword_snd_interrupt, 4*60)
+ MCFG_CPU_PERIODIC_INT_DRIVER(gsword_state, sound_interrupt, 4*60)
MCFG_CPU_ADD("audiocpu", Z80, XTAL_18MHz/6) /* verified on pcb */
MCFG_CPU_PROGRAM_MAP(cpu3_map)
@@ -645,7 +810,7 @@ static MACHINE_CONFIG_START( gsword, gsword_state )
MCFG_TAITO8741_ADD("taito8741")
MCFG_TAITO8741_MODES(TAITO8741_MASTER,TAITO8741_SLAVE,TAITO8741_PORT,TAITO8741_PORT)
MCFG_TAITO8741_CONNECT(1,0,0,0)
- MCFG_TAITO8741_PORT_HANDLERS(IOPORT("DSW2"),IOPORT("DSW1"),READ8(gsword_state,gsword_8741_2_r),READ8(gsword_state,gsword_8741_3_r))
+ MCFG_TAITO8741_PORT_HANDLERS(IOPORT("DSW2"),IOPORT("DSW1"),READ8(gsword_state,i8741_2_r),READ8(gsword_state,i8741_3_r))
#if 1
/* to MCU timeout champbbj */
MCFG_QUANTUM_TIME(attotime::from_hz(6000))
@@ -682,22 +847,32 @@ static MACHINE_CONFIG_START( gsword, gsword_state )
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.60)
MACHINE_CONFIG_END
-static MACHINE_CONFIG_START( josvolly, gsword_state )
+static MACHINE_CONFIG_START( josvolly, josvolly_state )
/* basic machine hardware */
- MCFG_CPU_ADD("maincpu", Z80, 18000000/6) /* ? */
+ MCFG_CPU_ADD("maincpu", Z80, 18000000/4) /* ? */
MCFG_CPU_PROGRAM_MAP(cpu1_map)
MCFG_CPU_IO_MAP(josvolly_cpu1_io_map)
- MCFG_CPU_PERIODIC_INT_DRIVER(gsword_state, irq0_line_hold, 2*60)
+ MCFG_CPU_PERIODIC_INT_DRIVER(josvolly_state, irq0_line_hold, 2*60)
MCFG_CPU_ADD("audiocpu", Z80, 12000000/4) /* ? */
MCFG_CPU_PROGRAM_MAP(josvolly_cpu2_map)
MCFG_CPU_IO_MAP(josvolly_cpu2_io_map)
- MCFG_CPU_VBLANK_INT_DRIVER("screen", gsword_state, irq0_line_hold)
+ MCFG_CPU_VBLANK_INT_DRIVER("screen", josvolly_state, irq0_line_assert)
- MCFG_JOSVOLLY8741_ADD("josvolly_8741")
- MCFG_JOSVOLLY8741_CONNECT(1,0,0,0)
- MCFG_JOSVOLLY8741_PORT_HANDLERS(IOPORT("DSW1"),IOPORT("DSW2"),IOPORT("DSW1"),IOPORT("DSW2"))
+ MCFG_DEVICE_ADD("mcu1", I8741, 18000000/2) /* ? */
+ MCFG_CPU_IO_MAP(josvolly_mcu1_io_map)
+
+ MCFG_DEVICE_ADD("mcu2", I8741, 12000000/2) /* ? */
+ MCFG_CPU_IO_MAP(josvolly_mcu2_io_map)
+
+ MCFG_DEVICE_ADD("aa_007", I8255, 0)
+ MCFG_I8255_IN_PORTA_CB(IOPORT("IN1")) // 1PL
+ MCFG_I8255_IN_PORTB_CB(IOPORT("IN2")) // 2PL / ACK
+ MCFG_I8255_IN_PORTC_CB(IOPORT("IN0")) // START
+
+ // the second MCU polls the first MCU's outputs, so it needs tight sync
+ MCFG_QUANTUM_PERFECT_CPU("mcu2")
/* video hardware */
@@ -706,13 +881,13 @@ static MACHINE_CONFIG_START( josvolly, gsword_state )
MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500) /* not accurate */)
MCFG_SCREEN_SIZE(32*8, 32*8)
MCFG_SCREEN_VISIBLE_AREA(0*8, 32*8-1, 2*8, 30*8-1)
- MCFG_SCREEN_UPDATE_DRIVER(gsword_state, screen_update_gsword)
+ MCFG_SCREEN_UPDATE_DRIVER(josvolly_state, screen_update_gsword)
MCFG_SCREEN_PALETTE("palette")
MCFG_GFXDECODE_ADD("gfxdecode", "palette", gsword)
MCFG_PALETTE_ADD("palette", 64*4+64*4)
MCFG_PALETTE_INDIRECT_ENTRIES(256)
- MCFG_PALETTE_INIT_OWNER(gsword_state,josvolly)
+ MCFG_PALETTE_INIT_OWNER(josvolly_state, josvolly)
/* sound hardware */
MCFG_SPEAKER_STANDARD_MONO("mono")
@@ -721,7 +896,6 @@ static MACHINE_CONFIG_START( josvolly, gsword_state )
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.30)
MCFG_SOUND_ADD("ay2", AY8910, 1500000)
- MCFG_AY8910_PORT_A_WRITE_CB(WRITE8(gsword_state, nmi_set_w)) /* portA write */
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.30)
#if 0
@@ -845,11 +1019,12 @@ ROM_START( josvolly )
ROM_REGION( 0x04000, "user1", 0 ) /* music data and samples - not sure where it's mapped */
ROM_LOAD( "aa0-14.4j", 0x0000, 0x2000, CRC(436fe91f) SHA1(feb29501090c6db911e13ce6e9935ba004b0ce7e) )
- // there are other undumped chips on this, not sure how many
- // not hooked up yet
- ROM_REGION( 0x400, "mcu", 0 )
+ ROM_REGION( 0x400, "mcu1", 0 )
ROM_LOAD( "aa003.bin", 0x0000, 0x400, CRC(68b399d9) SHA1(053482d12c2b714c23fc80ad0589a2afd258a5a6) )
+ ROM_REGION( 0x400, "mcu2", 0 )
+ ROM_LOAD( "aa008.bin", 0x0000, 0x400, CRC(68b399d9) SHA1(053482d12c2b714c23fc80ad0589a2afd258a5a6) BAD_DUMP )
+
ROM_REGION( 0x4000, "gfx1", 0 )
ROM_LOAD( "aa0-10.9n", 0x0000, 0x2000, CRC(207c4f42) SHA1(4cf2922d55cfc9e68cc07c3252ea3b5619b8aca5) ) /* tiles */
ROM_LOAD( "aa1-11.9p", 0x2000, 0x1000, CRC(c130464a) SHA1(9d23577b8aaaffeefff3d8f93668d1b2bd0ba3d9) )
@@ -872,37 +1047,7 @@ ROM_START( josvolly )
ROM_LOAD( "005.3h", 0x0440, 0x0020, CRC(e8d6dec0) SHA1(d15cba9a4b24255d41046b15c2409391ab13ce95) ) /* address decoder? not used */
ROM_END
-DRIVER_INIT_MEMBER(gsword_state,gsword)
-{
-#if 0
- uint8_t *ROM2 = memregion("sub")->base();
- ROM2[0x1da] = 0xc3; /* patch for rom self check */
-
- ROM2[0x71e] = 0; /* patch for sound protection or time out function */
- ROM2[0x71f] = 0;
-#endif
-#if 1
- /* hack for sound protection or time out function */
- m_subcpu->space(AS_PROGRAM).install_read_handler(0x4004, 0x4005, read8_delegate(FUNC(gsword_state::gsword_hack_r),this));
-#endif
-}
-
-DRIVER_INIT_MEMBER(gsword_state,gsword2)
-{
-#if 0
- uint8_t *ROM2 = memregion("sub")->base();
-
- ROM2[0x1da] = 0xc3; /* patch for rom self check */
- ROM2[0x726] = 0; /* patch for sound protection or time out function */
- ROM2[0x727] = 0;
-#endif
-#if 1
- /* hack for sound protection or time out function */
- m_subcpu->space(AS_PROGRAM).install_read_handler(0x4004, 0x4005, read8_delegate(FUNC(gsword_state::gsword_hack_r),this));
-#endif
-}
-
-GAME( 1983, josvolly, 0, josvolly, josvolly, driver_device, 0, ROT90, "Allumer / Taito Corporation", "Joshi Volleyball", MACHINE_UNEMULATED_PROTECTION | MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE )
+GAME( 1983, josvolly, 0, josvolly, josvolly, driver_device, 0, ROT90, "Allumer / Taito Corporation", "Joshi Volleyball", MACHINE_NOT_WORKING | MACHINE_UNEMULATED_PROTECTION | MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE )
GAME( 1984, gsword, 0, gsword, gsword, gsword_state, gsword, ROT0, "Allumer / Taito Corporation", "Great Swordsman (World?)", MACHINE_SUPPORTS_SAVE )
GAME( 1984, gsword2, gsword, gsword, gsword, gsword_state, gsword2, ROT0, "Allumer / Taito Corporation", "Great Swordsman (Japan?)", MACHINE_SUPPORTS_SAVE )
diff --git a/src/mame/drivers/hapyfish.cpp b/src/mame/drivers/hapyfish.cpp
new file mode 100644
index 00000000000..1d57c35c35a
--- /dev/null
+++ b/src/mame/drivers/hapyfish.cpp
@@ -0,0 +1,85 @@
+// license:BSD-3-Clause
+// copyright-holders:David Haywood
+
+/* Happy Fish (xxx-in-1 multigame)
+
+ Primary system components
+
+ SAMSUNG ARM-based Soc
+ 2x SAMSUNG Flash ROMs
+ + a bunch of RAM
+
+ (todo, fill in exact details)
+
+ progress was previously shown with this, booting to the menu at least
+ using (I believe) ghosteo.cpp as a base, but the contributor is no
+ longer active, and that driver was never submitted.
+
+*/
+
+#include "emu.h"
+#include "cpu/arm7/arm7.h"
+#include "cpu/arm7/arm7core.h"
+
+
+class hapyfish_state : public driver_device
+{
+public:
+ hapyfish_state(const machine_config &mconfig, device_type type, const char *tag)
+ : driver_device(mconfig, type, tag),
+ m_maincpu(*this, "maincpu") { }
+
+ virtual void video_start() override;
+ uint32_t screen_update_hapyfish(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
+ required_device<cpu_device> m_maincpu;
+};
+
+static ADDRESS_MAP_START( hapyfish_map, AS_PROGRAM, 32, hapyfish_state )
+ AM_RANGE(0x00000000, 0x00003fff) AM_ROM
+ADDRESS_MAP_END
+
+static INPUT_PORTS_START( hapyfish )
+INPUT_PORTS_END
+
+uint32_t hapyfish_state::screen_update_hapyfish(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
+{
+ return 0;
+}
+
+void hapyfish_state::video_start()
+{
+}
+
+
+
+static MACHINE_CONFIG_START( hapyfish, hapyfish_state )
+
+ /* basic machine hardware */
+ MCFG_CPU_ADD("maincpu", ARM9, 20000000) // ?? ARM baesd CPU
+ MCFG_CPU_PROGRAM_MAP(hapyfish_map)
+ MCFG_DEVICE_DISABLE()
+
+ /* video hardware */
+ MCFG_SCREEN_ADD("screen", RASTER)
+ MCFG_SCREEN_REFRESH_RATE(60)
+ MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0))
+ MCFG_SCREEN_SIZE(64*8, 64*8)
+ MCFG_SCREEN_VISIBLE_AREA(0*8, 56*8-1, 0*8, 28*8-1)
+ MCFG_SCREEN_UPDATE_DRIVER(hapyfish_state, screen_update_hapyfish)
+MACHINE_CONFIG_END
+
+
+
+ROM_START( hapyfsh2 )
+ ROM_REGION( 0x04000, "maincpu", ROMREGION_ERASE00 )
+ // the SoC copies some data from the flash in order to boot
+
+ ROM_REGION( 0x84000000, "flash1", 0 )
+ ROM_LOAD( "flash.u6", 0x00000000, 0x84000000, CRC(3aa364a2) SHA1(fe09f549a937ecaf8f7a859522a6635e272fe714) )
+
+ ROM_REGION( 0x84000000, "flash2", 0 )
+ ROM_LOAD( "flash.u28", 0x00000000, 0x84000000, CRC(f00a25cd) SHA1(9c33f8e26b84cea957d9c37fb83a686b948c6834) )
+ROM_END
+
+ GAME( 201?, hapyfsh2, 0, hapyfish, hapyfish, driver_device, 0, ROT0, "bootleg", "Happy Fish (V2 PCB, 302-in-1)", MACHINE_IS_SKELETON )
+
diff --git a/src/mame/drivers/harddriv.cpp b/src/mame/drivers/harddriv.cpp
index 815cf4f2032..76a0c668f9b 100644
--- a/src/mame/drivers/harddriv.cpp
+++ b/src/mame/drivers/harddriv.cpp
@@ -461,7 +461,8 @@ harddriv_state::harddriv_state(const machine_config &mconfig, const char *tag, d
m_sound_int_state(0),
m_video_int_state(0),
m_palette(*this, "palette"),
- m_slapstic_device(*this, "slapstic")
+ m_slapstic_device(*this, "slapstic"),
+ m_rs232(*this, "rs232")
{
int i;
@@ -1445,6 +1446,10 @@ static MACHINE_CONFIG_FRAGMENT( driver_nomsp )
MCFG_MC68681_ADD("duartn68681", XTAL_3_6864MHz)
MCFG_MC68681_IRQ_CALLBACK(WRITELINE(harddriv_state, harddriv_duart_irq_handler))
+ MCFG_MC68681_A_TX_CALLBACK(DEVWRITELINE ("rs232", rs232_port_device, write_txd))
+
+ MCFG_RS232_PORT_ADD("rs232", default_rs232_devices, nullptr)
+ MCFG_RS232_RXD_HANDLER(DEVWRITELINE ("duartn68681", mc68681_device, rx_a_w))
/* video hardware */
MCFG_PALETTE_ADD("palette", 1024)
diff --git a/src/mame/drivers/hh_cop400.cpp b/src/mame/drivers/hh_cop400.cpp
index 28be622fcbf..1795c35e368 100644
--- a/src/mame/drivers/hh_cop400.cpp
+++ b/src/mame/drivers/hh_cop400.cpp
@@ -19,7 +19,7 @@
#include "bship82.lh" // clickable
#include "ctstein.lh" // clickable
#include "einvaderc.lh" // test-layout(but still playable)
-#include "funjacks.lh"
+#include "funjacks.lh" // clickable
#include "funrlgl.lh"
#include "h2hbaskb.lh"
#include "lightfgt.lh" // clickable
@@ -48,16 +48,16 @@ public:
uint8_t m_l; // MCU port L write data
uint8_t m_g; // MCU port G write data
uint8_t m_d; // MCU port D write data
- int m_so; // MCU SO line state
- int m_sk; // MCU SK line state
+ int m_so; // MCU SO line state
+ int m_sk; // MCU SK line state
uint16_t m_inp_mux; // multiplexed inputs mask
uint16_t read_inputs(int columns);
// display common
- int m_display_wait; // led/lamp off-delay in microseconds (default 33ms)
- int m_display_maxy; // display matrix number of rows
- int m_display_maxx; // display matrix number of columns (max 31 for now)
+ int m_display_wait; // led/lamp off-delay in microseconds (default 33ms)
+ int m_display_maxy; // display matrix number of rows
+ int m_display_maxx; // display matrix number of columns (max 31 for now)
uint32_t m_display_state[0x20]; // display matrix rows data (last bit is used for always-on)
uint16_t m_display_segmask[0x20]; // if not 0, display matrix row is a digit, mask indicates connected segments
diff --git a/src/mame/drivers/hh_hmcs40.cpp b/src/mame/drivers/hh_hmcs40.cpp
index 82d98b65eb8..4cd7736585a 100644
--- a/src/mame/drivers/hh_hmcs40.cpp
+++ b/src/mame/drivers/hh_hmcs40.cpp
@@ -133,9 +133,9 @@ public:
DECLARE_INPUT_CHANGED_MEMBER(single_interrupt_line);
// display common
- int m_display_wait; // led/lamp off-delay in microseconds (default 33ms)
- int m_display_maxy; // display matrix number of rows
- int m_display_maxx; // display matrix number of columns (max 47 for now)
+ int m_display_wait; // led/lamp off-delay in microseconds (default 33ms)
+ int m_display_maxy; // display matrix number of rows
+ int m_display_maxx; // display matrix number of columns (max 47 for now)
uint32_t m_grid; // VFD current row data
uint64_t m_plate; // VFD current column data
diff --git a/src/mame/drivers/hh_melps4.cpp b/src/mame/drivers/hh_melps4.cpp
index aebaef2ff7e..0e557ee6b58 100644
--- a/src/mame/drivers/hh_melps4.cpp
+++ b/src/mame/drivers/hh_melps4.cpp
@@ -40,9 +40,9 @@ public:
DECLARE_INPUT_CHANGED_MEMBER(reset_button);
// display common
- int m_display_wait; // led/lamp off-delay in microseconds (default 33ms)
- int m_display_maxy; // display matrix number of rows
- int m_display_maxx; // display matrix number of columns (max 31 for now)
+ int m_display_wait; // led/lamp off-delay in microseconds (default 33ms)
+ int m_display_maxy; // display matrix number of rows
+ int m_display_maxx; // display matrix number of columns (max 31 for now)
uint32_t m_grid; // VFD current row data
uint32_t m_plate; // VFD current column data
diff --git a/src/mame/drivers/hh_pic16.cpp b/src/mame/drivers/hh_pic16.cpp
index 6bb594cc30e..c8b013ecd12 100644
--- a/src/mame/drivers/hh_pic16.cpp
+++ b/src/mame/drivers/hh_pic16.cpp
@@ -54,9 +54,9 @@ public:
uint8_t m_c; // MCU port C data
// display common
- int m_display_wait; // led/lamp off-delay in microseconds (default 33ms)
- int m_display_maxy; // display matrix number of rows
- int m_display_maxx; // display matrix number of columns (max 31 for now)
+ int m_display_wait; // led/lamp off-delay in microseconds (default 33ms)
+ int m_display_maxy; // display matrix number of rows
+ int m_display_maxx; // display matrix number of columns (max 31 for now)
uint32_t m_display_state[0x20]; // display matrix rows data (last bit is used for always-on)
uint16_t m_display_segmask[0x20]; // if not 0, display matrix row is a digit, mask indicates connected segments
diff --git a/src/mame/drivers/hh_sm510.cpp b/src/mame/drivers/hh_sm510.cpp
index 2d9f21322df..92fc2c56e06 100644
--- a/src/mame/drivers/hh_sm510.cpp
+++ b/src/mame/drivers/hh_sm510.cpp
@@ -34,7 +34,7 @@ public:
optional_device<speaker_sound_device> m_speaker;
// misc common
- uint16_t m_inp_mux; // multiplexed inputs mask
+ uint16_t m_inp_mux; // multiplexed inputs mask
int m_inp_lines; // number of input mux columns
uint8_t m_lcd_output_cache[0x100];
diff --git a/src/mame/drivers/hh_tms1k.cpp b/src/mame/drivers/hh_tms1k.cpp
index d43084098e5..cc319010241 100644
--- a/src/mame/drivers/hh_tms1k.cpp
+++ b/src/mame/drivers/hh_tms1k.cpp
@@ -21,10 +21,11 @@
*MP0057 TMS1000 1978, APH Student Speech+ (same ROM contents as TSI Speech+?)
@MP0158 TMS1000 1979, Entex Soccer (6003)
@MP0163 TMS1000 1979, A-One LSI Match Number/LJN Electronic Concentration
- *MP0168 TMS1000 1979, Conic Basketball/Tandy Sports Arena
+ @MP0168 TMS1000 1979, Conic Multisport/Tandy Sports Arena (model 60-2158)
@MP0170 TMS1000 1979, Conic Football
*MP0230 TMS1000 1980, Entex Blast It (6015)
@MP0271 TMS1000 1982, Tandy Radio Shack Monkey See
+ *MP0907 TMS1000 1979, Conic/Cardinal Basketball
@MP0914 TMS1000 1979, Entex Baseball 1
@MP0915 TMS1000 1979, Bandai System Control Car: Cheetah/The Incredible Brain Buggy
@MP0919 TMS1000 1979, Tiger Copy Cat (model 7-520)
@@ -139,6 +140,7 @@
#include "bcheetah.lh"
#include "bigtrak.lh"
#include "bship.lh" // clickable
+#include "cmsport.lh"
#include "cnfball.lh"
#include "cnfball2.lh"
#include "cnsector.lh" // clickable
@@ -1758,6 +1760,119 @@ MACHINE_CONFIG_END
/***************************************************************************
+ Conic Electronic Multisport
+ * TMS1000 MP0168 (die label same)
+ * PCB label: 101-027(1979), or 101-021 REV A(1980, with DS8871N)
+ * 2 7seg LEDs, 33 other LEDs, 1-bit sound
+
+ This handheld includes 3 games: Basketball, Ice Hockey, Soccer.
+ MAME external artwork is needed for the switchable overlays.
+
+ known releases:
+ - Hong Kong: Electronic Multisport
+ - Hong Kong: Basketball/Ice Hockey/Soccer (3 separate handhelds)
+ - USA(1): Electronic Multisport, distributed by Innocron
+ - USA(2): Sports Arena, distributed by Tandy (model 60-2158)
+
+***************************************************************************/
+
+class cmsport_state : public hh_tms1k_state
+{
+public:
+ cmsport_state(const machine_config &mconfig, device_type type, const char *tag)
+ : hh_tms1k_state(mconfig, type, tag)
+ { }
+
+ void prepare_display();
+ DECLARE_WRITE16_MEMBER(write_r);
+ DECLARE_WRITE16_MEMBER(write_o);
+ DECLARE_READ8_MEMBER(read_k);
+};
+
+// handlers
+
+void cmsport_state::prepare_display()
+{
+ // R5,R6 are 7segs
+ set_display_segmask(0x60, 0x7f);
+ display_matrix(8, 9, m_o, m_r & ~0x80);
+}
+
+WRITE16_MEMBER(cmsport_state::write_r)
+{
+ // R7: speaker out
+ m_speaker->level_w(data >> 7 & 1);
+
+ // R0,R9,R10: input mux
+ m_inp_mux = (data & 1) | (data >> 8 & 6);
+
+ // R0-R6,R8: led select
+ m_r = data;
+ prepare_display();
+}
+
+WRITE16_MEMBER(cmsport_state::write_o)
+{
+ // O0-O7: led data
+ m_o = data;
+ prepare_display();
+}
+
+READ8_MEMBER(cmsport_state::read_k)
+{
+ // K: multiplexed inputs
+ return read_inputs(3);
+}
+
+
+// config
+
+static INPUT_PORTS_START( cmsport )
+ PORT_START("IN.0") // R0
+ PORT_CONFNAME( 0x05, 0x01, "Game Select" )
+ PORT_CONFSETTING( 0x01, "Basketball" )
+ PORT_CONFSETTING( 0x00, "Soccer" )
+ PORT_CONFSETTING( 0x04, "Ice Hockey" )
+ PORT_BIT( 0x0a, IP_ACTIVE_HIGH, IPT_UNUSED )
+
+ PORT_START("IN.1") // R9
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_16WAY
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_16WAY
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_16WAY
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_16WAY
+
+ PORT_START("IN.2") // R10
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("Shoot")
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_START1 ) PORT_NAME("Score")
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_CONFNAME( 0x08, 0x00, "Skill Level" )
+ PORT_CONFSETTING( 0x00, "1" ) // amateur
+ PORT_CONFSETTING( 0x08, "2" ) // professional
+INPUT_PORTS_END
+
+static MACHINE_CONFIG_START( cmsport, cmsport_state )
+
+ /* basic machine hardware */
+ MCFG_CPU_ADD("maincpu", TMS1000, 375000) // approximation - RC osc. R=47K, C=47pf
+ MCFG_TMS1XXX_READ_K_CB(READ8(cmsport_state, read_k))
+ MCFG_TMS1XXX_WRITE_R_CB(WRITE16(cmsport_state, write_r))
+ MCFG_TMS1XXX_WRITE_O_CB(WRITE16(cmsport_state, write_o))
+
+ MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", hh_tms1k_state, display_decay_tick, attotime::from_msec(1))
+ MCFG_DEFAULT_LAYOUT(layout_cmsport)
+
+ /* sound hardware */
+ MCFG_SPEAKER_STANDARD_MONO("mono")
+ MCFG_SOUND_ADD("speaker", SPEAKER_SOUND, 0)
+ MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25)
+MACHINE_CONFIG_END
+
+
+
+
+
+/***************************************************************************
+
Conic Electronic Football
* TMS1000 MP0170 (die label same)
* DS8874N, 3*9 LED array, 7 7seg LEDs, 1-bit sound
@@ -7479,6 +7594,17 @@ ROM_START( tc4 )
ROM_END
+ROM_START( cmsport )
+ ROM_REGION( 0x0400, "maincpu", 0 )
+ ROM_LOAD( "mp0168.u1", 0x0000, 0x0400, CRC(0712a268) SHA1(bd4e23e5c17b28c52e7e769e44773cc9c8839bed) )
+
+ ROM_REGION( 867, "maincpu:mpla", 0 )
+ ROM_LOAD( "tms1000_common2_micro.pla", 0, 867, CRC(d33da3cf) SHA1(13c4ebbca227818db75e6db0d45b66ba5e207776) )
+ ROM_REGION( 365, "maincpu:opla", 0 )
+ ROM_LOAD( "tms1000_cmsport_output.pla", 0, 365, CRC(7defa140) SHA1(477e3cb55e79938d6acaa911e410f6dcb974c218) )
+ROM_END
+
+
ROM_START( cnfball )
ROM_REGION( 0x0400, "maincpu", 0 )
ROM_LOAD( "mp0170", 0x0000, 0x0400, CRC(50e8a44f) SHA1(fea6ae03c4ef329d825f8688e6854df15023d47e) )
@@ -8019,6 +8145,7 @@ CONS( 1980, h2hbaseb, 0, 0, h2hbaseb, h2hbaseb, driver_device, 0, "Col
CONS( 1981, h2hboxing, 0, 0, h2hboxing, h2hboxing, driver_device, 0, "Coleco", "Head to Head Boxing", MACHINE_SUPPORTS_SAVE )
CONS( 1981, tc4, 0, 0, tc4, tc4, driver_device, 0, "Coleco", "Total Control 4", MACHINE_SUPPORTS_SAVE | MACHINE_REQUIRES_ARTWORK )
+CONS( 1979, cmsport, 0, 0, cmsport, cmsport, driver_device, 0, "Conic", "Electronic Multisport", MACHINE_SUPPORTS_SAVE | MACHINE_REQUIRES_ARTWORK )
CONS( 1979, cnfball, 0, 0, cnfball, cnfball, driver_device, 0, "Conic", "Electronic Football (Conic, TMS1000 version)", MACHINE_SUPPORTS_SAVE )
CONS( 1979, cnfball2, 0, 0, cnfball2, cnfball2, driver_device, 0, "Conic", "Electronic Football II (Conic)", MACHINE_SUPPORTS_SAVE )
diff --git a/src/mame/drivers/lkage.cpp b/src/mame/drivers/lkage.cpp
index d8d6a58e181..948f66c048b 100644
--- a/src/mame/drivers/lkage.cpp
+++ b/src/mame/drivers/lkage.cpp
@@ -139,7 +139,6 @@ static ADDRESS_MAP_START( lkage_map, AS_PROGRAM, 8, lkage_state )
AM_RANGE(0xf000, 0xf003) AM_RAM AM_SHARE("vreg") /* video registers */
AM_RANGE(0xf060, 0xf060) AM_WRITE(lkage_sound_command_w)
AM_RANGE(0xf061, 0xf061) AM_WRITENOP AM_READ(sound_status_r)
- AM_RANGE(0xf062, 0xf062) AM_READWRITE(lkage_mcu_r,lkage_mcu_w)
AM_RANGE(0xf063, 0xf063) AM_WRITENOP /* pulsed; nmi on sound cpu? */
AM_RANGE(0xf080, 0xf080) AM_READ_PORT("DSW1")
AM_RANGE(0xf081, 0xf081) AM_READ_PORT("DSW2")
@@ -147,7 +146,6 @@ static ADDRESS_MAP_START( lkage_map, AS_PROGRAM, 8, lkage_state )
AM_RANGE(0xf083, 0xf083) AM_READ_PORT("SYSTEM")
AM_RANGE(0xf084, 0xf084) AM_READ_PORT("P1")
AM_RANGE(0xf086, 0xf086) AM_READ_PORT("P2")
- AM_RANGE(0xf087, 0xf087) AM_READ(lkage_mcu_status_r)
AM_RANGE(0xf0a0, 0xf0a3) AM_RAM /* unknown */
AM_RANGE(0xf0c0, 0xf0c5) AM_RAM AM_SHARE("scroll")
AM_RANGE(0xf0e1, 0xf0e1) AM_WRITENOP /* pulsed */
@@ -156,6 +154,18 @@ static ADDRESS_MAP_START( lkage_map, AS_PROGRAM, 8, lkage_state )
AM_RANGE(0xf400, 0xffff) AM_RAM_WRITE(lkage_videoram_w) AM_SHARE("videoram")
ADDRESS_MAP_END
+static ADDRESS_MAP_START( lkage_map_mcu, AS_PROGRAM, 8, lkage_state )
+ AM_IMPORT_FROM(lkage_map)
+ AM_RANGE(0xf062, 0xf062) AM_DEVREADWRITE("bmcu", taito68705_mcu_device, mcu_r, mcu_w)
+ AM_RANGE(0xf087, 0xf087) AM_DEVREAD("bmcu", taito68705_mcu_device, mcu_status_r)
+ADDRESS_MAP_END
+
+static ADDRESS_MAP_START( lkage_map_boot, AS_PROGRAM, 8, lkage_state )
+ AM_IMPORT_FROM(lkage_map)
+ AM_RANGE(0xf062, 0xf062) AM_READWRITE(fake_mcu_r,fake_mcu_w)
+ AM_RANGE(0xf087, 0xf087) AM_READ(fake_status_r)
+ADDRESS_MAP_END
+
READ8_MEMBER(lkage_state::port_fetch_r)
{
@@ -166,17 +176,6 @@ static ADDRESS_MAP_START( lkage_io_map, AS_IO, 8, lkage_state )
AM_RANGE(0x4000, 0x7fff) AM_READ(port_fetch_r)
ADDRESS_MAP_END
-static ADDRESS_MAP_START( lkage_m68705_map, AS_PROGRAM, 8, lkage_state )
- ADDRESS_MAP_GLOBAL_MASK(0x7ff)
- AM_RANGE(0x0000, 0x0000) AM_READWRITE(lkage_68705_port_a_r,lkage_68705_port_a_w)
- AM_RANGE(0x0001, 0x0001) AM_READWRITE(lkage_68705_port_b_r,lkage_68705_port_b_w)
- AM_RANGE(0x0002, 0x0002) AM_READWRITE(lkage_68705_port_c_r,lkage_68705_port_c_w)
- AM_RANGE(0x0004, 0x0004) AM_WRITE(lkage_68705_ddr_a_w)
- AM_RANGE(0x0005, 0x0005) AM_WRITE(lkage_68705_ddr_b_w)
- AM_RANGE(0x0006, 0x0006) AM_WRITE(lkage_68705_ddr_c_w)
- AM_RANGE(0x0010, 0x007f) AM_RAM
- AM_RANGE(0x0080, 0x07ff) AM_ROM
-ADDRESS_MAP_END
/***************************************************************************/
@@ -489,20 +488,6 @@ void lkage_state::machine_start()
save_item(NAME(m_mcu_val));
save_item(NAME(m_sound_nmi_enable));
save_item(NAME(m_pending_nmi));
-
- save_item(NAME(m_port_a_in));
- save_item(NAME(m_port_a_out));
- save_item(NAME(m_ddr_a));
- save_item(NAME(m_port_b_in));
- save_item(NAME(m_port_b_out));
- save_item(NAME(m_ddr_b));
- save_item(NAME(m_port_c_in));
- save_item(NAME(m_port_c_out));
- save_item(NAME(m_ddr_c));
- save_item(NAME(m_mcu_sent));
- save_item(NAME(m_main_sent));
- save_item(NAME(m_from_main));
- save_item(NAME(m_from_mcu));
}
void lkage_state::machine_reset()
@@ -514,26 +499,13 @@ void lkage_state::machine_reset()
m_sound_nmi_enable = 0;
m_pending_nmi = 0;
- m_port_a_in = 0;
- m_port_a_out = 0;
- m_ddr_a = 0;
- m_port_b_in = 0;
- m_port_b_out = 0;
- m_ddr_b = 0;
- m_port_c_in = 0;
- m_port_c_out = 0;
- m_ddr_c = 0;
- m_mcu_sent = 0;
- m_main_sent = 0;
- m_from_main = 0;
- m_from_mcu = 0;
}
static MACHINE_CONFIG_START( lkage, lkage_state )
/* basic machine hardware */
MCFG_CPU_ADD("maincpu", Z80, MAIN_CPU_CLOCK)
- MCFG_CPU_PROGRAM_MAP(lkage_map)
+ MCFG_CPU_PROGRAM_MAP(lkage_map_mcu)
MCFG_CPU_IO_MAP(lkage_io_map)
MCFG_CPU_VBLANK_INT_DRIVER("screen", lkage_state, irq0_line_hold)
@@ -541,8 +513,7 @@ static MACHINE_CONFIG_START( lkage, lkage_state )
MCFG_CPU_PROGRAM_MAP(lkage_sound_map)
/* IRQs are triggered by the YM2203 */
- MCFG_CPU_ADD("mcu", M68705,MCU_CLOCK)
- MCFG_CPU_PROGRAM_MAP(lkage_m68705_map)
+ MCFG_DEVICE_ADD("bmcu", TAITO68705_MCU,MCU_CLOCK)
/* video hardware */
@@ -583,7 +554,7 @@ static MACHINE_CONFIG_START( lkageb, lkage_state )
/* basic machine hardware */
MCFG_CPU_ADD("maincpu", Z80,MAIN_CPU_CLOCK)
- MCFG_CPU_PROGRAM_MAP(lkage_map)
+ MCFG_CPU_PROGRAM_MAP(lkage_map_boot)
MCFG_CPU_IO_MAP(lkage_io_map)
MCFG_CPU_VBLANK_INT_DRIVER("screen", lkage_state, irq0_line_hold)
@@ -633,7 +604,7 @@ ROM_START( lkage )
ROM_REGION( 0x10000, "audiocpu", 0 ) /* Z80 code (sound CPU) */
ROM_LOAD( "a54-04.54", 0x0000, 0x8000, CRC(541faf9a) SHA1(b142ff3bd198f700697ec06ea92db3109ab5818e) )
- ROM_REGION( 0x10000, "mcu", 0 ) /* 68705 MCU code */
+ ROM_REGION( 0x10000, "bmcu:mcu", 0 ) /* 68705 MCU code */
ROM_LOAD( "a54-09.53", 0x0000, 0x0800, CRC(0e8b8846) SHA1(a4a105462b0127229bb7edfadd2e581c7e40f1cc) )
ROM_REGION( 0x4000, "user1", 0 ) /* data */
@@ -663,7 +634,7 @@ ROM_START( lkageo )
ROM_REGION( 0x10000, "audiocpu", 0 ) /* Z80 code (sound CPU) */
ROM_LOAD( "a54-04.54", 0x0000, 0x8000, CRC(541faf9a) SHA1(b142ff3bd198f700697ec06ea92db3109ab5818e) )
- ROM_REGION( 0x10000, "mcu", 0 ) /* 68705 MCU code */
+ ROM_REGION( 0x10000, "bmcu:mcu", 0 ) /* 68705 MCU code */
ROM_LOAD( "a54-09.53", 0x0000, 0x0800, CRC(0e8b8846) SHA1(a4a105462b0127229bb7edfadd2e581c7e40f1cc) )
ROM_REGION( 0x4000, "user1", 0 ) /* data */
@@ -693,7 +664,7 @@ ROM_START( lkageoo )
ROM_REGION( 0x10000, "audiocpu", 0 ) /* Z80 code (sound CPU) */
ROM_LOAD( "a54-04.54", 0x0000, 0x8000, CRC(541faf9a) SHA1(b142ff3bd198f700697ec06ea92db3109ab5818e) )
- ROM_REGION( 0x10000, "mcu", 0 ) /* 68705 MCU code */
+ ROM_REGION( 0x10000, "bmcu:mcu", 0 ) /* 68705 MCU code */
ROM_LOAD( "a54-09.53", 0x0000, 0x0800, CRC(0e8b8846) SHA1(a4a105462b0127229bb7edfadd2e581c7e40f1cc) )
ROM_REGION( 0x4000, "user1", 0 ) /* data */
@@ -876,7 +847,7 @@ ROM_START( bygone )
ROM_REGION( 0x10000, "audiocpu", 0 ) /* Z80 code (sound CPU) */
ROM_LOAD( "a53_07.ic54", 0x0000, 0x8000, CRC(72f69a77) SHA1(dfc1050a4123b3c83ae733ece1b6fe2836beb901) )
- ROM_REGION( 0x10000, "mcu", 0 ) /* 68705 MCU code */
+ ROM_REGION( 0x10000, "bmcu:mcu", 0 ) /* 68705 MCU code */
ROM_LOAD( "a51_09.ic53", 0x0000, 0x0800, CRC(0e8b8846) SHA1(a4a105462b0127229bb7edfadd2e581c7e40f1cc) ) /* the same as lkage */
ROM_REGION( 0x4000, "user1", 0 ) /* data */
@@ -945,13 +916,6 @@ DRIVER_INIT_MEMBER(lkage_state,lkage)
m_sprite_dx=0;
}
-DRIVER_INIT_MEMBER(lkage_state,lkageb)
-{
- m_maincpu->space(AS_PROGRAM).install_read_handler(0xf062, 0xf062, read8_delegate(FUNC(lkage_state::fake_mcu_r),this));
- m_maincpu->space(AS_PROGRAM).install_read_handler(0xf087, 0xf087, read8_delegate(FUNC(lkage_state::fake_status_r),this));
- m_maincpu->space(AS_PROGRAM).install_write_handler(0xf062, 0xf062, write8_delegate(FUNC(lkage_state::fake_mcu_w),this));
- m_sprite_dx=0;
-}
DRIVER_INIT_MEMBER(lkage_state,bygone)
{
@@ -961,7 +925,7 @@ DRIVER_INIT_MEMBER(lkage_state,bygone)
GAME( 1984, lkage, 0, lkage, lkage, lkage_state, lkage, ROT0, "Taito Corporation", "The Legend of Kage", MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE )
GAME( 1984, lkageo, lkage, lkage, lkage, lkage_state, lkage, ROT0, "Taito Corporation", "The Legend of Kage (older)", MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE )
GAME( 1984, lkageoo, lkage, lkage, lkage, lkage_state, lkage, ROT0, "Taito Corporation", "The Legend of Kage (oldest)", MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE )
-GAME( 1984, lkageb, lkage, lkageb, lkageb, lkage_state, lkageb, ROT0, "bootleg", "The Legend of Kage (bootleg set 1)", MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE )
-GAME( 1984, lkageb2, lkage, lkageb, lkageb, lkage_state, lkageb, ROT0, "bootleg", "The Legend of Kage (bootleg set 2)", MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE )
-GAME( 1984, lkageb3, lkage, lkageb, lkageb, lkage_state, lkageb, ROT0, "bootleg", "The Legend of Kage (bootleg set 3)", MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE )
+GAME( 1984, lkageb, lkage, lkageb, lkageb, lkage_state, lkage, ROT0, "bootleg", "The Legend of Kage (bootleg set 1)", MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE )
+GAME( 1984, lkageb2, lkage, lkageb, lkageb, lkage_state, lkage, ROT0, "bootleg", "The Legend of Kage (bootleg set 2)", MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE )
+GAME( 1984, lkageb3, lkage, lkageb, lkageb, lkage_state, lkage, ROT0, "bootleg", "The Legend of Kage (bootleg set 3)", MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE )
GAME( 1985, bygone, 0, lkage, bygone, lkage_state, bygone, ROT0, "Taito Corporation", "Bygone (prototype)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE )
diff --git a/src/mame/drivers/lsasquad.cpp b/src/mame/drivers/lsasquad.cpp
index 3bcdbb13a74..dd661a45ea5 100644
--- a/src/mame/drivers/lsasquad.cpp
+++ b/src/mame/drivers/lsasquad.cpp
@@ -185,7 +185,7 @@ static ADDRESS_MAP_START( lsasquad_map, AS_PROGRAM, 8, lsasquad_state )
AM_RANGE(0xea00, 0xea00) AM_WRITE(lsasquad_bankswitch_w)
AM_RANGE(0xec00, 0xec00) AM_READWRITE(lsasquad_sound_result_r,lsasquad_sound_command_w)
AM_RANGE(0xec01, 0xec01) AM_READ(lsasquad_sound_status_r)
- AM_RANGE(0xee00, 0xee00) AM_READWRITE(lsasquad_mcu_r,lsasquad_mcu_w)
+ AM_RANGE(0xee00, 0xee00) AM_DEVREADWRITE("bmcu", taito68705_mcu_device, mcu_r, mcu_w)
ADDRESS_MAP_END
static ADDRESS_MAP_START( lsasquad_sound_map, AS_PROGRAM, 8, lsasquad_state )
@@ -200,16 +200,6 @@ static ADDRESS_MAP_START( lsasquad_sound_map, AS_PROGRAM, 8, lsasquad_state )
AM_RANGE(0xe000, 0xefff) AM_ROM /* space for diagnostic ROM? */
ADDRESS_MAP_END
-static ADDRESS_MAP_START( lsasquad_m68705_map, AS_PROGRAM, 8, lsasquad_state )
- ADDRESS_MAP_GLOBAL_MASK(0x7ff)
- AM_RANGE(0x0000, 0x0000) AM_READWRITE(lsasquad_68705_port_a_r,lsasquad_68705_port_a_w)
- AM_RANGE(0x0001, 0x0001) AM_READWRITE(lsasquad_68705_port_b_r,lsasquad_68705_port_b_w)
- AM_RANGE(0x0002, 0x0002) AM_READ(lsasquad_mcu_status_r)
- AM_RANGE(0x0004, 0x0004) AM_WRITE(lsasquad_68705_ddr_a_w)
- AM_RANGE(0x0005, 0x0005) AM_WRITE(lsasquad_68705_ddr_b_w)
- AM_RANGE(0x0010, 0x007f) AM_RAM
- AM_RANGE(0x0080, 0x07ff) AM_ROM
-ADDRESS_MAP_END
static ADDRESS_MAP_START( storming_map, AS_PROGRAM, 8, lsasquad_state )
@@ -392,7 +382,7 @@ static ADDRESS_MAP_START( daikaiju_map, AS_PROGRAM, 8, lsasquad_state )
AM_RANGE(0xea00, 0xea00) AM_WRITE(lsasquad_bankswitch_w)
AM_RANGE(0xec00, 0xec00) AM_WRITE(lsasquad_sound_command_w)
AM_RANGE(0xec01, 0xec01) AM_READ(lsasquad_sound_status_r)
- AM_RANGE(0xee00, 0xee00) AM_READWRITE(lsasquad_mcu_r, lsasquad_mcu_w)
+ AM_RANGE(0xee00, 0xee00) AM_DEVREADWRITE("bmcu", taito68705_mcu_device, mcu_r, mcu_w)
ADDRESS_MAP_END
static ADDRESS_MAP_START( daikaiju_sound_map, AS_PROGRAM, 8, lsasquad_state )
@@ -549,16 +539,6 @@ MACHINE_START_MEMBER(lsasquad_state,lsasquad)
membank("bank1")->configure_entries(0, 8, &ROM[0x10000], 0x2000);
- save_item(NAME(m_port_a_in));
- save_item(NAME(m_port_a_out));
- save_item(NAME(m_ddr_a));
- save_item(NAME(m_port_b_in));
- save_item(NAME(m_port_b_out));
- save_item(NAME(m_ddr_b));
- save_item(NAME(m_mcu_sent));
- save_item(NAME(m_main_sent));
- save_item(NAME(m_from_main));
- save_item(NAME(m_from_mcu));
save_item(NAME(m_sound_pending));
save_item(NAME(m_sound_nmi_enable));
@@ -574,17 +554,6 @@ MACHINE_RESET_MEMBER(lsasquad_state,lsasquad)
m_pending_nmi = 0;
m_sound_cmd = 0;
m_sound_result = 0;
-
- m_port_a_in = 0;
- m_port_a_out = 0;
- m_ddr_a = 0;
- m_port_b_in = 0;
- m_port_b_out = 0;
- m_ddr_b = 0;
- m_mcu_sent = 0;
- m_main_sent = 0;
- m_from_main = 0;
- m_from_mcu = 0;
}
/* Note: lsasquad clock values are not verified */
@@ -598,8 +567,8 @@ static MACHINE_CONFIG_START( lsasquad, lsasquad_state )
MCFG_CPU_ADD("audiocpu", Z80, MASTER_CLOCK / 8)
MCFG_CPU_PROGRAM_MAP(lsasquad_sound_map)
/* IRQs are triggered by the YM2203 */
- MCFG_CPU_ADD("mcu", M68705, MASTER_CLOCK / 8)
- MCFG_CPU_PROGRAM_MAP(lsasquad_m68705_map)
+ MCFG_DEVICE_ADD("bmcu", TAITO68705_MCU, MASTER_CLOCK / 8)
+
MCFG_QUANTUM_TIME(attotime::from_hz(30000)) /* 500 CPU slices per frame - an high value to ensure proper */
/* synchronization of the CPUs */
@@ -641,7 +610,7 @@ static MACHINE_CONFIG_DERIVED( storming, lsasquad )
MCFG_CPU_MODIFY("maincpu")
MCFG_CPU_PROGRAM_MAP(storming_map)
- MCFG_DEVICE_REMOVE("mcu")
+ MCFG_DEVICE_REMOVE("bmcu")
MACHINE_CONFIG_END
static MACHINE_CONFIG_START( daikaiju, lsasquad_state )
@@ -655,8 +624,7 @@ static MACHINE_CONFIG_START( daikaiju, lsasquad_state )
MCFG_CPU_PROGRAM_MAP(daikaiju_sound_map)
/* IRQs are triggered by the YM2203 */
- MCFG_CPU_ADD("mcu", M68705, MASTER_CLOCK / 8)
- MCFG_CPU_PROGRAM_MAP(lsasquad_m68705_map)
+ MCFG_DEVICE_ADD("bmcu", TAITO68705_MCU, MASTER_CLOCK / 8)
MCFG_QUANTUM_TIME(attotime::from_hz(30000)) /* 500 CPU slices per frame - an high value to ensure proper */
/* synchronization of the CPUs */
@@ -710,7 +678,7 @@ ROM_START( lsasquad )
ROM_REGION( 0x10000, "audiocpu", 0 ) /* 64k for the second CPU */
ROM_LOAD( "a64-04.44", 0x0000, 0x8000, CRC(c238406a) SHA1(bb8f9d952c4568edb375328a1f9f6681a1bb5907) )
- ROM_REGION( 0x0800, "mcu", 0 ) /* 2k for the microcontroller */
+ ROM_REGION( 0x0800, "bmcu:mcu", 0 ) /* 2k for the microcontroller */
ROM_LOAD( "a64-05.35", 0x0000, 0x0800, CRC(572677b9) SHA1(e098d5d842bcc81221ba56652a7019505d8be082) )
ROM_REGION( 0x20000, "gfx1", ROMREGION_INVERT )
@@ -787,7 +755,7 @@ ROM_START( daikaiju )
ROM_REGION( 0x10000, "audiocpu", 0 ) /* 64k for the second CPU */
ROM_LOAD( "a74_04.ic44", 0x0000, 0x8000, CRC(98a6a703) SHA1(0c169a7a5f8b26606f67ee7f14bd487951536ac5) )
- ROM_REGION( 0x0800, "mcu", 0 )
+ ROM_REGION( 0x0800, "bmcu:mcu", 0 )
ROM_LOAD( "a74_05.ic35", 0x0000, 0x0800, CRC(d66df06f) SHA1(6a61eb15aef7f3b7a66ec9d87c0bdd731d6cb079) )
ROM_REGION( 0x20000, "gfx1", ROMREGION_INVERT )
diff --git a/src/mame/drivers/mvme147.cpp b/src/mame/drivers/mvme147.cpp
index c513572f57c..9f3568104b2 100644
--- a/src/mame/drivers/mvme147.cpp
+++ b/src/mame/drivers/mvme147.cpp
@@ -154,15 +154,26 @@
#include "emu.h"
#include "cpu/m68000/m68000.h"
+#include "bus/vme/vme.h"
+#include "bus/vme/vme_mvme350.h"
#include "machine/z80scc.h"
#include "bus/rs232/rs232.h"
#include "machine/clock.h"
#include "machine/timekpr.h"
-#define VERBOSE 1
+#define LOG_GENERAL 0x01
+#define LOG_SETUP 0x02
+#define LOG_PRINTF 0x04
-#define LOG(x) do { if (VERBOSE) logerror x; } while (0)
-#if VERBOSE >= 2
+#define VERBOSE 0 // (LOG_PRINTF | LOG_SETUP | LOG_GENERAL)
+
+#define LOGMASK(mask, ...) do { if (VERBOSE & mask) logerror(__VA_ARGS__); } while (0)
+#define LOGLEVEL(mask, level, ...) do { if ((VERBOSE & mask) >= level) logerror(__VA_ARGS__); } while (0)
+
+#define LOG(...) LOGMASK(LOG_GENERAL, __VA_ARGS__)
+#define LOGSETUP(...) LOGMASK(LOG_SETUP, __VA_ARGS__)
+
+#if VERBOSE & LOG_PRINTF
#define logerror printf
#endif
@@ -252,7 +263,7 @@ INPUT_PORTS_END
/* Start it up */
void mvme147_state::machine_start ()
{
- LOG(("--->%s\n", FUNCNAME));
+ LOG("%s\n", FUNCNAME);
/* Setup pointer to bootvector in ROM for bootvector handler bootvect_r */
m_sysrom = (uint32_t*)(memregion ("roms")->base () + 0x800000);
@@ -262,7 +273,7 @@ void mvme147_state::machine_start ()
void mvme147_state::machine_reset ()
{
- LOG(("--->%s\n", FUNCNAME));
+ LOG("%s\n", FUNCNAME);
/* Reset pointer to bootvector in ROM for bootvector handler bootvect_r */
if (m_sysrom == &m_sysram[0]) /* Condition needed because memory map is not setup first time */
@@ -286,21 +297,21 @@ WRITE32_MEMBER (mvme147_state::bootvect_w){
*/
#if 0 /* Doesn't compile atm */
READ32_MEMBER (mvme147_state::pcc32_r){
- LOG(("--->%s[%04x]", FUNCNAME, offset));
+ LOG("%s[%04x]", FUNCNAME, offset);
switch(offset)
{
default:
- LOG(("unsupported register\n"));
+ LOG(" - unsupported register\n");
}
return 0x00;
}
WRITE32_MEMBER (mvme147_state::pcc32_w){
- LOG(("--->%s[%04x]= %08lx", FUNCNAME, offset, data));
+ LOG("%s[%04x]= %08lx", FUNCNAME, offset, data);
switch(offset)
{
default:
- LOG(("unsupported register\n"));
+ LOG("- unsupported register\n");
}
}
#endif
@@ -314,29 +325,29 @@ WRITE32_MEMBER (mvme147_state::pcc32_w){
READ16_MEMBER (mvme147_state::pcc16_r){
uint16_t ret = 0;
- LOG(("Call to %s[%04x]", FUNCNAME, offset));
+ LOG("Call to %s[%04x]", FUNCNAME, offset);
switch(offset)
{
- case P16_TIMER1_PRELOAD - P16BASE : LOG((" -> %02x Timer 1 preload - not implemented\n", ret)); break;
- case P16_TIMER1_COUNT - P16BASE : LOG((" -> %02x Timer 1 count - not implemented\n", ret)); break;
- case P16_TIMER2_PRELOAD - P16BASE : LOG((" -> %02x Timer 2 preload - not implemented\n", ret)); break;
- case P16_TIMER2_COUNT - P16BASE : LOG((" -> %02x Timer 2 count - not implemented\n", ret)); break;
+ case P16_TIMER1_PRELOAD - P16BASE : LOG(" -> %02x Timer 1 preload - not implemented\n", ret); break;
+ case P16_TIMER1_COUNT - P16BASE : LOG(" -> %02x Timer 1 count - not implemented\n", ret); break;
+ case P16_TIMER2_PRELOAD - P16BASE : LOG(" -> %02x Timer 2 preload - not implemented\n", ret); break;
+ case P16_TIMER2_COUNT - P16BASE : LOG(" -> %02x Timer 2 count - not implemented\n", ret); break;
default:
- LOG((" -> %02x unsupported register\n", ret));
+ LOG(" -> %02x unsupported register\n", ret);
}
return ret;
}
WRITE16_MEMBER (mvme147_state::pcc16_w){
- LOG(("Call to %s[%04x] <- %04x - ", FUNCNAME, offset, data));
+ LOG("Call to %s[%04x] <- %04x - ", FUNCNAME, offset, data);
switch(offset)
{
- case P16_TIMER1_PRELOAD - P16BASE : LOG(("Timer 1 preload - not implemented\n")); break;
- case P16_TIMER1_COUNT - P16BASE : LOG(("Timer 1 count - not implemented\n")); break;
- case P16_TIMER2_PRELOAD - P16BASE : LOG(("Timer 2 preload - not implemented\n")); break;
- case P16_TIMER2_COUNT - P16BASE : LOG(("Timer 2 count - not implemented\n")); break;
+ case P16_TIMER1_PRELOAD - P16BASE : LOG("Timer 1 preload - not implemented\n"); break;
+ case P16_TIMER1_COUNT - P16BASE : LOG("Timer 1 count - not implemented\n"); break;
+ case P16_TIMER2_PRELOAD - P16BASE : LOG("Timer 2 preload - not implemented\n"); break;
+ case P16_TIMER2_COUNT - P16BASE : LOG("Timer 2 count - not implemented\n"); break;
default:
- LOG(("unsupported register\n"));
+ LOG("unsupported register\n");
}
}
@@ -371,22 +382,22 @@ WRITE16_MEMBER (mvme147_state::pcc16_w){
READ8_MEMBER (mvme147_state::pcc8_r){
uint8_t ret = 0;
- LOG(("Call to %s[%04x] ", FUNCNAME, offset));
+ LOG("Call to %s[%04x] ", FUNCNAME, offset);
switch(offset + P8BASE)
{
- case P8_TIMER1_INT_CNTL : LOG((" -> %02x - Timer 1 Interrupt Control - not implemented\n", ret)); break;
- case P8_TIMER1_CNTL : LOG((" -> %02x - Timer 1 Control - not implemented\n", ret)); break;
- case P8_TIMER2_INT_CNTL : LOG((" -> %02x - Timer 2 Interrupt Control - not implemented\n", ret)); break;
- case P8_TIMER2_CNTL : LOG((" -> %02x - Timer 2 Control - not implemented\n", ret)); break;
- case P8_ACFAIL_INT_CNTL : LOG((" -> %02x - AC Fail Interrupt Control Register - not implemented\n", ret)); break;
- case P8_WDOG_TIMER_CNTL : LOG((" -> %02x - Watchdog Timer Control Register - not implemented\n", ret)); break;
- case P8_PRINTER_INT_CNTL : LOG((" -> %02x - Printer Interrupt Control Register - not implemented\n", ret)); break;
- case P8_PRINTER_CNTL : LOG((" -> %02x - Printer Control Register - not implemented\n", ret)); break;
- case P8_DMA_INT_CNTL : LOG((" -> %02x - DMA Interrupt Control Register - not implemented\n", ret)); break;
- case P8_DMA_CNTL_STAT : LOG((" -> %02x - DMA Control and Status Register - not implemented\n", ret)); break;
- case P8_BUSERR_CNTL : LOG((" -> %02x - Bus Error Interrupt Control Register - not implemented\n", ret)); break;
- case P8_DMA_STATUS : LOG((" -> %02x - DMA Status Register - not implemented\n", ret)); break;
- case P8_ABORT_INT_CNTL : LOG((" -> %02x - Abort Interrupt Control Register - not fully implemented\n", ret));
+ case P8_TIMER1_INT_CNTL : LOG(" -> %02x - Timer 1 Interrupt Control - not implemented\n", ret); break;
+ case P8_TIMER1_CNTL : LOG(" -> %02x - Timer 1 Control - not implemented\n", ret); break;
+ case P8_TIMER2_INT_CNTL : LOG(" -> %02x - Timer 2 Interrupt Control - not implemented\n", ret); break;
+ case P8_TIMER2_CNTL : LOG(" -> %02x - Timer 2 Control - not implemented\n", ret); break;
+ case P8_ACFAIL_INT_CNTL : LOG(" -> %02x - AC Fail Interrupt Control Register - not implemented\n", ret); break;
+ case P8_WDOG_TIMER_CNTL : LOG(" -> %02x - Watchdog Timer Control Register - not implemented\n", ret); break;
+ case P8_PRINTER_INT_CNTL : LOG(" -> %02x - Printer Interrupt Control Register - not implemented\n", ret); break;
+ case P8_PRINTER_CNTL : LOG(" -> %02x - Printer Control Register - not implemented\n", ret); break;
+ case P8_DMA_INT_CNTL : LOG(" -> %02x - DMA Interrupt Control Register - not implemented\n", ret); break;
+ case P8_DMA_CNTL_STAT : LOG(" -> %02x - DMA Control and Status Register - not implemented\n", ret); break;
+ case P8_BUSERR_CNTL : LOG(" -> %02x - Bus Error Interrupt Control Register - not implemented\n", ret); break;
+ case P8_DMA_STATUS : LOG(" -> %02x - DMA Status Register - not implemented\n", ret); break;
+ case P8_ABORT_INT_CNTL : LOG(" -> %02x - Abort Interrupt Control Register - not fully implemented\n", ret);
/* Bit 3 When this bit is high, the interrupt is enabled. The interrupt is disabled when this bit is low. This bit is cleared by reset.
Bit 6 This bit indicates the current state of the ABORT switch. When this bit is low, the ABORT switch is not pressed. When this bit is
high, the ABORT switch is pressed.
@@ -395,46 +406,46 @@ READ8_MEMBER (mvme147_state::pcc8_r){
it remains cleared until the next leading edge of interrupt enable and abort. This bit is cleared by reset. */
ret = 0; /* Always return reset values for now */
break;
- case P8_TABADD_FC_CNTL : LOG((" -> %02x - Table Address Function Code Register - not implemented\n", ret)); break;
- case P8_SERIAL_INT_CNTL : LOG((" -> %02x - Serial Port Interrupt Control Register - not implemented\n", ret)); break;
- case P8_GEN_PURP_CNTL : LOG((" -> %02x - General Purpose Control Register - not implemented\n", ret)); break;
- case P8_LAN_INT_CNTL : LOG((" -> %02x - LAN Interrupt Control Register - not implemented\n", ret)); break;
- case P8_GEN_PURP_STAT : LOG((" -> %02x - General Purpose Status Register\n", ret));
+ case P8_TABADD_FC_CNTL : LOG(" -> %02x - Table Address Function Code Register - not implemented\n", ret); break;
+ case P8_SERIAL_INT_CNTL : LOG(" -> %02x - Serial Port Interrupt Control Register - not implemented\n", ret); break;
+ case P8_GEN_PURP_CNTL : LOG(" -> %02x - General Purpose Control Register - not implemented\n", ret); break;
+ case P8_LAN_INT_CNTL : LOG(" -> %02x - LAN Interrupt Control Register - not implemented\n", ret); break;
+ case P8_GEN_PURP_STAT : LOG(" -> %02x - General Purpose Status Register\n", ret);
ret = m_genpurp_stat;
break;
- case P8_SCSI_INT_CNTL : LOG((" -> %02x - SCSI Port Interrupt Control Register - not implemented\n", ret)); break;
- case P8_SLAVE_BASE_ADDR : LOG((" -> %02x - Slave Base Address Register - not implemented\n", ret)); break;
- case P8_SWI_1_CNTL : LOG((" -> %02x - Software Interrupt 1 Control Register - not implemented\n", ret)); break;
- case P8_INT_VECT_BASE : LOG((" -> %02x - Interrupt Vector Base - not implemented\n", ret)); break;
- case P8_SWI_2_CNTL : LOG((" -> %02x - Software Interrupt 2 Control Register - not implemented\n", ret)); break;
- case P8_REVISION_LEVEL : LOG((" -> %02x - PCC Revision Level Register - not implemented\n", ret)); break;
- case P8_PRINTER_STATUS : LOG((" -> %02x - Printer Status Register - not implemented\n", ret)); break;
+ case P8_SCSI_INT_CNTL : LOG(" -> %02x - SCSI Port Interrupt Control Register - not implemented\n", ret); break;
+ case P8_SLAVE_BASE_ADDR : LOG(" -> %02x - Slave Base Address Register - not implemented\n", ret); break;
+ case P8_SWI_1_CNTL : LOG(" -> %02x - Software Interrupt 1 Control Register - not implemented\n", ret); break;
+ case P8_INT_VECT_BASE : LOG(" -> %02x - Interrupt Vector Base - not implemented\n", ret); break;
+ case P8_SWI_2_CNTL : LOG(" -> %02x - Software Interrupt 2 Control Register - not implemented\n", ret); break;
+ case P8_REVISION_LEVEL : LOG(" -> %02x - PCC Revision Level Register - not implemented\n", ret); break;
+ case P8_PRINTER_STATUS : LOG(" -> %02x - Printer Status Register - not implemented\n", ret); break;
default:
- LOG((" -> %02x - unsupported register\n", ret));
+ LOG(" -> %02x - unsupported register\n", ret);
}
return ret;
}
WRITE8_MEMBER (mvme147_state::pcc8_w){
- LOG(("Call to %s[%04x] <- %02x - ", FUNCNAME, offset, data));
+ LOG("Call to %s[%04x] <- %02x - ", FUNCNAME, offset, data);
switch(offset + P8BASE)
{
- case P8_TIMER1_INT_CNTL : LOG(("Timer 1 Interrupt Control - not implemented\n")); break;
- case P8_TIMER1_CNTL : LOG(("Timer 1 Control - not implemented\n")); break;
- case P8_TIMER2_INT_CNTL : LOG(("Timer 2 Interrupt Control - not implemented\n")); break;
- case P8_TIMER2_CNTL : LOG(("Timer 2 Control - not implemented\n")); break;
- case P8_ACFAIL_INT_CNTL : LOG(("AC Fail Interrupt Control Register - not implemented\n")); break;
- case P8_WDOG_TIMER_CNTL : LOG(("Watchdog Timer Control Register - not implemented\n")); break;
- case P8_PRINTER_INT_CNTL : LOG(("Printer Interrupt Control Register - not implemented\n")); break;
- case P8_PRINTER_CNTL : LOG(("Printer Control Register - not implemented\n")); break;
- case P8_DMA_INT_CNTL : LOG(("DMA Interrupt Control Register - not implemented\n")); break;
- case P8_DMA_CNTL_STAT : LOG(("DMA Control and Status Register - not implemented\n")); break;
- case P8_BUSERR_CNTL : LOG(("Bus Error Interrupt Control Register - not implemented\n")); break;
- case P8_DMA_STATUS : LOG(("DMA Status Register - not implemented\n")); break;
- case P8_ABORT_INT_CNTL : LOG(("Abort Interrupt Control Register - not implemented\n")); break;
- case P8_TABADD_FC_CNTL : LOG(("Table Address Function Code Register - not implemented\n")); break;
- case P8_SERIAL_INT_CNTL : LOG(("Serial Port Interrupt Control Register - not implemented\n")); break;
- case P8_GEN_PURP_CNTL : LOG(("General Purpose Control Register - not implemented\n"));
+ case P8_TIMER1_INT_CNTL : LOG("Timer 1 Interrupt Control - not implemented\n"); break;
+ case P8_TIMER1_CNTL : LOG("Timer 1 Control - not implemented\n"); break;
+ case P8_TIMER2_INT_CNTL : LOG("Timer 2 Interrupt Control - not implemented\n"); break;
+ case P8_TIMER2_CNTL : LOG("Timer 2 Control - not implemented\n"); break;
+ case P8_ACFAIL_INT_CNTL : LOG("AC Fail Interrupt Control Register - not implemented\n"); break;
+ case P8_WDOG_TIMER_CNTL : LOG("Watchdog Timer Control Register - not implemented\n"); break;
+ case P8_PRINTER_INT_CNTL: LOG("Printer Interrupt Control Register - not implemented\n"); break;
+ case P8_PRINTER_CNTL : LOG("Printer Control Register - not implemented\n"); break;
+ case P8_DMA_INT_CNTL : LOG("DMA Interrupt Control Register - not implemented\n"); break;
+ case P8_DMA_CNTL_STAT : LOG("DMA Control and Status Register - not implemented\n"); break;
+ case P8_BUSERR_CNTL : LOG("Bus Error Interrupt Control Register - not implemented\n"); break;
+ case P8_DMA_STATUS : LOG("DMA Status Register - not implemented\n"); break;
+ case P8_ABORT_INT_CNTL : LOG("Abort Interrupt Control Register - not implemented\n"); break;
+ case P8_TABADD_FC_CNTL : LOG("Table Address Function Code Register - not implemented\n"); break;
+ case P8_SERIAL_INT_CNTL : LOG("Serial Port Interrupt Control Register - not implemented\n"); break;
+ case P8_GEN_PURP_CNTL : LOG("General Purpose Control Register - not implemented\n");
/*Bits 0-1 These bits control local RAM parity checking. These bits should not be enabled on the MVME147-010.
These bits are cleared by reset. x0 = parity disabled, x1 = parity enabled
Bit 2 This bit is used to test the parity generating and checking logic. When this bit is low, correct parity is written to the DRAM;
@@ -449,8 +460,8 @@ WRITE8_MEMBER (mvme147_state::pcc8_w){
TODO: Bit 4-7 needs to be implemented
*/
break;
- case P8_LAN_INT_CNTL : LOG(("LAN Interrupt Control Register - not implemented\n")); break;
- case P8_GEN_PURP_STAT : LOG(("General Purpose Status Register\n"));
+ case P8_LAN_INT_CNTL : LOG("LAN Interrupt Control Register - not implemented\n"); break;
+ case P8_GEN_PURP_STAT : LOG("General Purpose Status Register\n");
/* Bit 0 This bit is set when a parity error occurs while the local processor is accessing RAM. This bit is cleared by writing a 1 to it.
This bit is cleared by reset.
Bit 1 This bit is set when a power-up reset occurs. It is cleared by writing a 1 to it.
@@ -459,15 +470,15 @@ WRITE8_MEMBER (mvme147_state::pcc8_w){
m_genpurp_stat &= ((data & 1) ? ~1 : 0xff); // Check if parity error bit needs to be cleared
m_genpurp_stat &= ((data & 2) ? ~2 : 0xff); // Check if power up reset bit needs to be cleared
break;
- case P8_SCSI_INT_CNTL : LOG(("SCSI Port Interrupt Control Register - not implemented\n")); break;
- case P8_SLAVE_BASE_ADDR : LOG(("Slave Base Address Register - not implemented\n")); break;
- case P8_SWI_1_CNTL : LOG(("Software Interrupt 1 Control Register - not implemented\n")); break;
- case P8_INT_VECT_BASE : LOG(("Interrupt Vector Base - not implemented\n")); break;
- case P8_SWI_2_CNTL : LOG(("Software Interrupt 2 Control Register - not implemented\n")); break;
- case P8_REVISION_LEVEL : LOG(("PCC Revision Level Register - not implemented\n")); break;
- case P8_PRINTER_DATA : LOG(("Printer Data Register - not implemented\n")); break;
+ case P8_SCSI_INT_CNTL : LOG("SCSI Port Interrupt Control Register - not implemented\n"); break;
+ case P8_SLAVE_BASE_ADDR : LOG("Slave Base Address Register - not implemented\n"); break;
+ case P8_SWI_1_CNTL : LOG("Software Interrupt 1 Control Register - not implemented\n"); break;
+ case P8_INT_VECT_BASE : LOG("Interrupt Vector Base - not implemented\n"); break;
+ case P8_SWI_2_CNTL : LOG("Software Interrupt 2 Control Register - not implemented\n"); break;
+ case P8_REVISION_LEVEL : LOG("PCC Revision Level Register - not implemented\n"); break;
+ case P8_PRINTER_DATA : LOG("Printer Data Register - not implemented\n"); break;
default:
- LOG(("unsupported register\n"));
+ LOG("unsupported register\n");
}
}
@@ -494,11 +505,11 @@ WRITE8_MEMBER (mvme147_state::pcc8_w){
READ8_MEMBER (mvme147_state::vmechip_r){
uint8_t ret = 0;
- LOG(("Call to %s[%04x] ", FUNCNAME, offset));
+ LOG("Call to %s[%04x] ", FUNCNAME, offset);
switch(offset * 2 + VCBASE)
{
case VC_SYS_CNTL_CONF :
- LOG((" -> %02x - System Controller Configuration Register - not implemented\n", ret));
+ LOG(" -> %02x - System Controller Configuration Register - not implemented\n", ret);
ret = m_vc_cntl_conf;
break;
case VC_VMEBUS_REQ_CONF :
@@ -531,11 +542,11 @@ READ8_MEMBER (mvme147_state::vmechip_r){
This bit is cleared by any reset.
*/
ret = 1 << 6; /* Let BUG147 think we are bus master. TODO: Implement proper VME bus signalling */
- LOG((" -> %02x - VMEbus Requester Configuration Register - not implemented\n", ret));
+ LOG(" -> %02x - VMEbus Requester Configuration Register - not implemented\n", ret);
break;
- case VC_MASTER_CONF : LOG((" -> %02x - Master Configuration Register - not implemented\n", ret)); break;
- case VC_SLAVE_CONF : LOG((" -> %02x - Slave Configuration Register - not implemented\n", ret)); break;
- case VC_TIMER_CONF : LOG((" -> %02x - Timer Configuration Register - not implemented\n", ret));
+ case VC_MASTER_CONF : LOG(" -> %02x - Master Configuration Register - not implemented\n", ret); break;
+ case VC_SLAVE_CONF : LOG(" -> %02x - Slave Configuration Register - not implemented\n", ret); break;
+ case VC_TIMER_CONF : LOG(" -> %02x - Timer Configuration Register - not implemented\n", ret);
/*Bits 0-1 These two bits configure the local time-out period. They are set to 1 by any reset.
LBTO1 LBTO0 Time-Out Period
0 0 102 microseconds
@@ -563,44 +574,44 @@ READ8_MEMBER (mvme147_state::vmechip_r){
This causes the arbiter to arbitrate any pending requests for the bus. This bit is set to 1 by SYSRESET.
*/
break;
- case VC_SLAVE_ADR_MOD : LOG((" -> %02x - Slave Address Modifier Register - not implemented\n", ret)); break;
- case VC_MASTER_ADR_MOD : LOG((" -> %02x - Master Address Modifier Register - not implemented\n", ret)); break;
- case VC_INT_HNDL_MASK : LOG((" -> %02x - Interrupt Handler Mask Register - not implemented\n", ret)); break;
- case VC_UTIL_INT_MASK : LOG((" -> %02x - Utility Interrupt Mask Register - not implemented\n", ret)); break;
- case VC_UTIL_INT_VECT : LOG((" -> %02x - Utility Interrupt Vector Register - not implemented\n", ret)); break;
- case VC_INT_REQUEST : LOG((" -> %02x - Interrupt Request Register - not implemented\n", ret)); break;
- case VC_VMEBUS_STAT_ID : LOG((" -> %02x - VMEbus Status/ID Register - not implemented\n", ret)); break;
- case VC_BUS_ERR_STATUS : LOG((" -> %02x - Bus Error Status Register - not implemented\n", ret)); break;
- case VC_GCSR_BASE_ADR : LOG((" -> %02x - GCSR Base Address Configuration Register - not implemented\n", ret)); break;
+ case VC_SLAVE_ADR_MOD : LOG(" -> %02x - Slave Address Modifier Register - not implemented\n", ret); break;
+ case VC_MASTER_ADR_MOD : LOG(" -> %02x - Master Address Modifier Register - not implemented\n", ret); break;
+ case VC_INT_HNDL_MASK : LOG(" -> %02x - Interrupt Handler Mask Register - not implemented\n", ret); break;
+ case VC_UTIL_INT_MASK : LOG(" -> %02x - Utility Interrupt Mask Register - not implemented\n", ret); break;
+ case VC_UTIL_INT_VECT : LOG(" -> %02x - Utility Interrupt Vector Register - not implemented\n", ret); break;
+ case VC_INT_REQUEST : LOG(" -> %02x - Interrupt Request Register - not implemented\n", ret); break;
+ case VC_VMEBUS_STAT_ID : LOG(" -> %02x - VMEbus Status/ID Register - not implemented\n", ret); break;
+ case VC_BUS_ERR_STATUS : LOG(" -> %02x - Bus Error Status Register - not implemented\n", ret); break;
+ case VC_GCSR_BASE_ADR : LOG(" -> %02x - GCSR Base Address Configuration Register - not implemented\n", ret); break;
default:
- LOG(("unsupported register"));
+ LOG("unsupported register");
}
return ret;
}
WRITE8_MEMBER (mvme147_state::vmechip_w){
- LOG(("Call to %s[%04x] <- %02x - ", FUNCNAME, offset, data));
+ LOG("Call to %s[%04x] <- %02x - ", FUNCNAME, offset, data);
switch(offset * 2 + VCBASE)
{
case VC_SYS_CNTL_CONF :
- LOG(("System Controller Configuration Register - not implemented\n"));
+ LOG("System Controller Configuration Register - not implemented\n");
m_vc_cntl_conf = data & 0xff;
break;
- case VC_VMEBUS_REQ_CONF : LOG(("VMEbus Requester Configuration Register - not implemented\n")); break;
- case VC_MASTER_CONF : LOG(("Master Configuration Register - not implemented\n")); break;
- case VC_SLAVE_CONF : LOG(("Slave Configuration Register - not implemented\n")); break;
- case VC_TIMER_CONF : LOG(("Timer Configuration Register - not implemented\n")); break;
- case VC_SLAVE_ADR_MOD : LOG(("Slave Address Modifier Register - not implemented\n")); break;
- case VC_MASTER_ADR_MOD : LOG(("Master Address Modifier Register - not implemented\n")); break;
- case VC_INT_HNDL_MASK : LOG(("Interrupt Handler Mask Register - not implemented\n")); break;
- case VC_UTIL_INT_MASK : LOG(("Utility Interrupt Mask Register - not implemented\n")); break;
- case VC_UTIL_INT_VECT : LOG(("Utility Interrupt Vector Register - not implemented\n")); break;
- case VC_INT_REQUEST : LOG(("Interrupt Request Register - not implemented\n")); break;
- case VC_VMEBUS_STAT_ID : LOG(("VMEbus Status/ID Register - not implemented\n")); break;
- case VC_BUS_ERR_STATUS : LOG(("Bus Error Status Register - not implemented\n")); break;
- case VC_GCSR_BASE_ADR : LOG(("GCSR Base Address Configuration Register - not implemented\n")); break;
+ case VC_VMEBUS_REQ_CONF : LOG("VMEbus Requester Configuration Register - not implemented\n"); break;
+ case VC_MASTER_CONF : LOG("Master Configuration Register - not implemented\n"); break;
+ case VC_SLAVE_CONF : LOG("Slave Configuration Register - not implemented\n"); break;
+ case VC_TIMER_CONF : LOG("Timer Configuration Register - not implemented\n"); break;
+ case VC_SLAVE_ADR_MOD : LOG("Slave Address Modifier Register - not implemented\n"); break;
+ case VC_MASTER_ADR_MOD : LOG("Master Address Modifier Register - not implemented\n"); break;
+ case VC_INT_HNDL_MASK : LOG("Interrupt Handler Mask Register - not implemented\n"); break;
+ case VC_UTIL_INT_MASK : LOG("Utility Interrupt Mask Register - not implemented\n"); break;
+ case VC_UTIL_INT_VECT : LOG("Utility Interrupt Vector Register - not implemented\n"); break;
+ case VC_INT_REQUEST : LOG("Interrupt Request Register - not implemented\n"); break;
+ case VC_VMEBUS_STAT_ID : LOG("VMEbus Status/ID Register - not implemented\n"); break;
+ case VC_BUS_ERR_STATUS : LOG("Bus Error Status Register - not implemented\n"); break;
+ case VC_GCSR_BASE_ADR : LOG("GCSR Base Address Configuration Register - not implemented\n"); break;
default:
- LOG(("unsupported register\n"));
+ LOG("unsupported register\n");
}
}
@@ -608,24 +619,28 @@ WRITE8_MEMBER (mvme147_state::vmechip_w){
#if 0
/* Dummy VME access methods until the VME bus device is ready for use */
READ16_MEMBER (mvme147_state::vme_a24_r){
- LOG (logerror ("vme_a24_r\n"));
+ LOG("%s\n", FUNCNAME);
return (uint16_t) 0;
}
WRITE16_MEMBER (mvme147_state::vme_a24_w){
- LOG (logerror ("vme_a24_w\n"));
+ LOG("%s\n", FUNCNAME);
}
READ16_MEMBER (mvme147_state::vme_a16_r){
- LOG (logerror ("vme_16_r\n"));
+ LOG("%s\n", FUNCNAME);
return (uint16_t) 0;
}
WRITE16_MEMBER (mvme147_state::vme_a16_w){
- LOG (logerror ("vme_a16_w\n"));
+ LOG("%s\n", FUNCNAME);
}
#endif
+static SLOT_INTERFACE_START(mvme147_vme_cards)
+ SLOT_INTERFACE("mvme350", VME_MVME350)
+SLOT_INTERFACE_END
+
/*
* Machine configuration
*/
@@ -633,6 +648,8 @@ static MACHINE_CONFIG_START (mvme147, mvme147_state)
/* basic machine hardware */
MCFG_CPU_ADD ("maincpu", M68030, XTAL_16MHz)
MCFG_CPU_PROGRAM_MAP (mvme147_mem)
+ MCFG_VME_DEVICE_ADD("vme")
+ MCFG_VME_SLOT_ADD ("vme", "slot1", mvme147_vme_cards, nullptr)
MCFG_M48T02_ADD("m48t18") /* t08 differs only in accepted voltage levels compared to t18 */
diff --git a/src/mame/drivers/mzr8105.cpp b/src/mame/drivers/mzr8105.cpp
index 129146b6e7e..3eeb35ca1e9 100644
--- a/src/mame/drivers/mzr8105.cpp
+++ b/src/mame/drivers/mzr8105.cpp
@@ -1,12 +1,187 @@
// license:BSD-3-Clause
// copyright-holders:Joakim Larsson Edstrom
-
+/***************************************************************************
+ *
+ * Mizar VME8105 rev D 3U SBC board driver
+ *
+ * 19/08/2015
+ *
+ * I baught this board from http://www.retrotechnology.com without documentation.
+ * It has a Motorola 68000 CPU @ 10MHz and two 27128 EPROMS with OS9 DEBUG labels
+ * and not much more except 16 or so TTLs, 2 PALs and a VME P1 connector. It is a
+ * 2 layered pcb so it shold be possible to trace the schematics quite easily.
+ * There is a date on the P1 Connector: "Feb 20 1987"
+ *
+ * ||
+ * ||
+ * ||
+ * ||
+ * ||____________________________________________________________ ___
+ * || --------------K2|U6-7432|U7-7474|U14-7405|U21-74645 | |_| |
+ * || | 2764 - low |-+-------+-------+--------+-----------+ | | |
+ * || | OS9 DEBUG U4| +---------+ +--------+---------+ | | |
+ * || -------------- | | |U13-7474|U20-74645| | | |
+ * || ______________ | | +--------+---------+ | | |
+ * || | | | | ______________K4____ | | |
+ * || | U3| | | |U12-7438|U19-74244| | |VME|
+ * || -------------- | |+------K6---------K3---+ | | |
+ * || ______________ | ||U11-PAL20L10|U18-74244| | |P1 |
+ * || | 2764 - high | | |+-----021102-+---------+ | | |
+ * || | OS9 DEBUG U2| |MC68000L10+------------+---------+ | | |
+ * || |______________| | ||U10-PAL14L4 |U17-74244| | | |
+ * || | |+-----021001-+---------+ | | |
+ * || -------------- | |+----+_______|U16-74244|+--+| | |
+ * || | | | |XTAL |U9-7410+---------+| || | |
+ * ||K1 | U1| | |FOX100-------+---------+|K5||_| |
+ * || -------------- |_________|10MHz|U8-7404|U15-74148|| || |___|
+ * ||--||--------------------------------+----+-------+---------++--+
+ * ||--||
+ * ||
+ *
+ * PAL:s
+ *------
+ * The board has two PAL:s, a PAL20L10 and a PAL14L4.
+ *
+ * _____ _____
+ * OD/CLK 1 |* \_/ | 20 VCC
+ * CPU A13 I0 2 | | 19 O0/LR A23
+ * U9 7410p12 I1 3 | | 18 O1/A0 A22
+ * CPU *AS I2 4 | | 17 02/A1 U2/U4 2764p22 *OE
+ * GND I3 5 | | 16 03/A2 U11 PAL20L10p6 I4
+ * CPU A14 I4 6 | U10 | 15 A0/O0 U11 PAL20L10p7 I5
+ * CPU A15 I5 7 | PAL14L4 | 14 A1/O1 U19 74LS244p11 I0b
+ * CPU A16 I6 8 | | 13 A2/O2 A18
+ * CPU A17 I7 9 | | 12 LR/O3 A20
+ * GND 10 |_____________| 11 CLK/OD A21
+ *
+ * _____ _____
+ * OD/CLK 1 |* \_/ | 24 VCC
+ * I0 2 | | 23 O0/LR
+ * CPU *AS I1 3 | | 22 O1/A0
+ * U10 PAL14L4p3 I2 4 | | 21 02/A1
+ * I3 5 | | 20 03/A2
+ * U10 PAL14L4p16 I4 6 | U10 | 19 04/NC
+ * U10 PAL14L4p15 I5 7 | PAL20L10 | 18 NC/O0
+ * I6 8 | | 17 A2/O1
+ * I7 9 | | 16 A1/O2
+ * I8 10 | | 15 A0/O3
+ * I9 11 | | 14 LR/O4
+ * GND 12 |_____________| 13 CLK/OD
+ *
+ * Trace is not fully completed and validated.
+ *
+ * History of Mizar
+ *-------------------
+ * Mizar was one of the first companies that released VME boards in 1982-3 together with
+ * Force Computers and Motorola. Their systems was often supported by OS9/68000 from Microware.
+ * In 1993 Mizar discontinued their OS9/CPU board product range and focused entirely on DSP
+ * boards. RTSI was founded by Mizar employees preserving the knowledge in OS9 as consultants.
+ * In 1998 Blue Wave resulted from the merger of Mizar and Loughborough Sound Images.
+ * Not much tech information availabe but I found some quotes about Mizar on the internet:
+ *
+ * From http://archive.org/stream/68micro-vol-11-num-02/V11N02_Feb1989_djvu.txt :
+ *--------------------------------------------------------------------------------
+ * " Mizar provides complete OS-9 solutions for the VMEbus. Mizar's VME CPUs
+ * offer (he functions and performance your application demands. Our single
+ * height (3U) VME processors are uniquely configurable computing engines,
+ * Through Mizar's unique MXbus expansion interface, standard and custom side
+ * modules can be added to basic processors to create double-height (6U) boards
+ * tor specific applications, 3U CPU options include 68010, 66020, and 63030
+ * microprocessors, up to one MB of DRAM, serial I/O, real-time clock, and
+ * mailbox interrupt support. Standard MXbus side modules include additional DRAM.
+ * SRAM, and I/O.
+ *
+ * Mizar's standard double- height (6U) processors provide additional features such
+ * as a high-speed cache to enhance 68030 performance, floating, point coprocessor
+ * support, up to four MB dual ported DRAM, VSB memory interface, Ethernet, and SCSI.
+ *
+ * Mizar also supports OS-9 with completely configured OS9 development systems and
+ * OS-9 application server systems. For more information, call Mizar today
+ *
+ * 800-635-0200 MIZAR 1419 Dunn Drive CarrolHon, TX 75006 214-446-2664"
+ *
+ * Known boards from Mizar:
+ *
+ * MZX 414
+ * MZ 7122
+ * MZ 7132
+ * MZ 7300 Serial I/O Board (Z8530)
+ * EMX 7320 Serial I/O Board
+ * MZ 7400 Disk Controller Board (WD 2010; WD 1772)
+ * MZ 7500 IEEE-488 (GPIB) Interface Board
+ * EMX 7550 Ethernet Controller Board (AMD 7990 Lance) MAC: 00:80:F8 MIZAR, INC.
+ * MZ 7772
+ * MZ 7810 I/O Expansion Module (6681 DUART)
+ * MZ 7831 SCSI Expansion Module (WD 33C93A)
+ * MZ 7850 Ethernet Expansion Module (WD 83C690)
+ * MZ 8000 ??
+ * MZ 8105 3U 68000 CPU board
+ * MZ 8115
+ * MZ 8300 3U serial board, 2 NEC 7201 and 1 AMD CTS9513 5 x 16 bit Counter/Timer
+ * MZ 8310 timing module 2 x AM9513
+ * MZ 8505 IEEE-488 (GPIB) Interface Board"
+ *
+ * From http://www.megalextoria.com/forum2/index.php?t=msg&goto=73945&
+ *--------------------------------------------------------------------
+ * Aug 20 1984 a report by James Jones from the OS/9 conferance in Des Moines:
+ * "...
+ * Mizar: is selling VME bus 68010 boards, running OS-9/68000; they also make
+ * various memory and I/O boards, disk controller boards, and and a NEC 7220-based
+ * graphics controller board...."
+ *
+ * Misc links about Mizar:
+ * http://www.vita.com/History
+ * http://www.verycomputer.com/154_e272024804bbe203_1.htm
+ * https://www.aihitdata.com/company/00814595/RTSI/overview
+ *
+ * Address Map
+ * --------------------------------------------------------------------------
+ * Address Range Description/Assumption
+ * --------------------------------------------------------------------------
+ * 0x000000 0x01ffff ROM because of fixed vectors
+ * 0x020000 0x03ffff RAM because bootvector stack starts at 0x21000
+ * -- VME adresses---
+ * 0xff0000 0xff0003 Bootstrap expects to find a UPD7201 serial device here
+ * --------------------------------------------------------------------------
+ *
+ * Interrupt sources
+ * ----------------------------------------------------------
+ * Description Device Lvl IRQ VME board
+ * /Board Vector Address
+ * ----------------------------------------------------------
+ * On board Sources
+ * TBD
+ * Off board Sources (other VME boards)
+ * TBD
+ * ----------------------------------------------------------
+ *
+ * TODO:
+ * - Dump the ROMs (DONE)
+ * - Setup a working address map (DONE)
+ * - Add VME bus driver (Faked one)
+ * - understand what other device is expected in VME space ff0011-13
+ *
+ ****************************************************************************/
#include "emu.h"
-#include "includes/mzr8105.h"
-#include "bus/vme/mzr8300.h"
+#include "bus/vme/vme.h"
+#include "bus/vme/vme_mzr8300.h"
+#include "bus/vme/vme_mvme350.h"
#include "cpu/m68000/m68000.h"
#include "machine/clock.h"
+class mzr8105_state : public driver_device
+{
+public:
+mzr8105_state(const machine_config &mconfig, device_type type, const char *tag) :
+ driver_device (mconfig, type, tag)
+ ,m_maincpu (*this, "maincpu")
+ {
+ }
+
+private:
+ required_device<cpu_device> m_maincpu;
+};
+
static ADDRESS_MAP_START (mzr8105_mem, AS_PROGRAM, 16, mzr8105_state)
ADDRESS_MAP_UNMAP_HIGH
/* The ROMs contains an OS9 bootloader. It is position independent but reset vector suggests that it sits flat on adress 0 (zero) */
@@ -31,8 +206,8 @@ SLOT_INTERFACE_END
MACHINE_CONFIG_START (mzr8105, mzr8105_state)
MCFG_CPU_ADD ("maincpu", M68000, XTAL_10MHz)
MCFG_CPU_PROGRAM_MAP (mzr8105_mem)
- MCFG_VME_P1_DEVICE_ADD("vme")
- MCFG_VME_P1_SLOT_ADD ("vme", "slot1", mzr8105_vme_cards, nullptr)
+ MCFG_VME_DEVICE_ADD("vme")
+ MCFG_VME_SLOT_ADD ("vme", "slot1", mzr8105_vme_cards, nullptr)
MACHINE_CONFIG_END
/* ROM definitions */
diff --git a/src/mame/drivers/namcos2.cpp b/src/mame/drivers/namcos2.cpp
index b64cbe946d6..5184630ca12 100644
--- a/src/mame/drivers/namcos2.cpp
+++ b/src/mame/drivers/namcos2.cpp
@@ -597,10 +597,9 @@ static ADDRESS_MAP_START( namcos2_68k_default_cpu_board_am, AS_PROGRAM, 16, namc
AM_RANGE(0x400000, 0x41ffff) AM_READWRITE(c123_tilemap_videoram_r,c123_tilemap_videoram_w)
AM_RANGE(0x420000, 0x42003f) AM_READWRITE(c123_tilemap_control_r,c123_tilemap_control_w)
AM_RANGE(0x440000, 0x44ffff) AM_READWRITE(paletteram_word_r,paletteram_word_w) AM_SHARE("paletteram")
- AM_RANGE(0x460000, 0x460fff) AM_READWRITE(dpram_word_r,dpram_word_w)
- AM_RANGE(0x468000, 0x468fff) AM_READWRITE(dpram_word_r,dpram_word_w) /* mirror */
- AM_RANGE(0x480000, 0x483fff) AM_READWRITE(serial_comms_ram_r,serial_comms_ram_w) AM_SHARE("serialram")
- AM_RANGE(0x4a0000, 0x4a000f) AM_READWRITE(serial_comms_ctrl_r,serial_comms_ctrl_w)
+ AM_RANGE(0x460000, 0x460fff) AM_MIRROR(0xf000) AM_READWRITE(dpram_word_r,dpram_word_w)
+ AM_RANGE(0x480000, 0x483fff) AM_DEVREADWRITE("sci", namco_c139_device, ram_r, ram_w)
+ AM_RANGE(0x4a0000, 0x4a000f) AM_DEVICE("sci", namco_c139_device, regs_map)
ADDRESS_MAP_END
/*************************************************************/
@@ -618,14 +617,14 @@ static ADDRESS_MAP_START( master_default_am, AS_PROGRAM, 16, namcos2_state )
AM_RANGE(0x000000, 0x03ffff) AM_ROM
AM_RANGE(0x100000, 0x10ffff) AM_RAMBANK(NAMCOS2_68K_MASTER_RAM)
AM_RANGE(0x180000, 0x183fff) AM_READWRITE8(namcos2_68k_eeprom_r,namcos2_68k_eeprom_w,0x00ff)
- AM_RANGE(0x1c0000, 0x1fffff) AM_READWRITE(namcos2_68k_master_C148_r,namcos2_68k_master_C148_w)
+ AM_RANGE(0x1c0000, 0x1fffff) AM_DEVICE("master_intc", namco_c148_device, map)
AM_IMPORT_FROM( common_default_am )
ADDRESS_MAP_END
static ADDRESS_MAP_START( slave_default_am, AS_PROGRAM, 16, namcos2_state )
AM_RANGE(0x000000, 0x03ffff) AM_ROM
AM_RANGE(0x100000, 0x13ffff) AM_RAMBANK(NAMCOS2_68K_SLAVE_RAM)
- AM_RANGE(0x1c0000, 0x1fffff) AM_READWRITE(namcos2_68k_slave_C148_r,namcos2_68k_slave_C148_w)
+ AM_RANGE(0x1c0000, 0x1fffff) AM_DEVICE("slave_intc", namco_c148_device, map)
AM_IMPORT_FROM( common_default_am )
ADDRESS_MAP_END
@@ -645,14 +644,14 @@ static ADDRESS_MAP_START( master_finallap_am, AS_PROGRAM, 16, namcos2_state )
AM_RANGE(0x000000, 0x03ffff) AM_ROM
AM_RANGE(0x100000, 0x10ffff) AM_RAMBANK(NAMCOS2_68K_MASTER_RAM)
AM_RANGE(0x180000, 0x183fff) AM_READWRITE8(namcos2_68k_eeprom_r,namcos2_68k_eeprom_w,0x00ff)
- AM_RANGE(0x1c0000, 0x1fffff) AM_READWRITE(namcos2_68k_master_C148_r,namcos2_68k_master_C148_w)
+ AM_RANGE(0x1c0000, 0x1fffff) AM_DEVICE("master_intc", namco_c148_device, map)
AM_IMPORT_FROM( common_finallap_am )
ADDRESS_MAP_END
static ADDRESS_MAP_START( slave_finallap_am, AS_PROGRAM, 16, namcos2_state )
AM_RANGE(0x000000, 0x03ffff) AM_ROM
AM_RANGE(0x100000, 0x13ffff) AM_RAMBANK(NAMCOS2_68K_SLAVE_RAM)
- AM_RANGE(0x1c0000, 0x1fffff) AM_READWRITE(namcos2_68k_slave_C148_r,namcos2_68k_slave_C148_w)
+ AM_RANGE(0x1c0000, 0x1fffff) AM_DEVICE("slave_intc", namco_c148_device, map)
AM_IMPORT_FROM( common_finallap_am )
ADDRESS_MAP_END
@@ -669,14 +668,14 @@ static ADDRESS_MAP_START( master_sgunner_am, AS_PROGRAM, 16, namcos2_state )
AM_RANGE(0x000000, 0x03ffff) AM_ROM
AM_RANGE(0x100000, 0x10ffff) AM_RAMBANK(NAMCOS2_68K_MASTER_RAM)
AM_RANGE(0x180000, 0x183fff) AM_READWRITE8(namcos2_68k_eeprom_r,namcos2_68k_eeprom_w,0x00ff)
- AM_RANGE(0x1c0000, 0x1fffff) AM_READWRITE(namcos2_68k_master_C148_r,namcos2_68k_master_C148_w)
+ AM_RANGE(0x1c0000, 0x1fffff) AM_DEVICE("master_intc", namco_c148_device, map)
AM_IMPORT_FROM( common_sgunner_am )
ADDRESS_MAP_END
static ADDRESS_MAP_START( slave_sgunner_am, AS_PROGRAM, 16, namcos2_state )
AM_RANGE(0x000000, 0x03ffff) AM_ROM
AM_RANGE(0x100000, 0x13ffff) AM_RAMBANK(NAMCOS2_68K_SLAVE_RAM)
- AM_RANGE(0x1c0000, 0x1fffff) AM_READWRITE(namcos2_68k_slave_C148_r,namcos2_68k_slave_C148_w)
+ AM_RANGE(0x1c0000, 0x1fffff) AM_DEVICE("slave_intc", namco_c148_device, map)
AM_IMPORT_FROM( common_sgunner_am )
ADDRESS_MAP_END
@@ -694,14 +693,14 @@ static ADDRESS_MAP_START( master_metlhawk_am, AS_PROGRAM, 16, namcos2_state )
AM_RANGE(0x000000, 0x03ffff) AM_ROM
AM_RANGE(0x100000, 0x10ffff) AM_RAMBANK(NAMCOS2_68K_MASTER_RAM)
AM_RANGE(0x180000, 0x183fff) AM_READWRITE8(namcos2_68k_eeprom_r,namcos2_68k_eeprom_w,0x00ff)
- AM_RANGE(0x1c0000, 0x1fffff) AM_READWRITE(namcos2_68k_master_C148_r,namcos2_68k_master_C148_w)
+ AM_RANGE(0x1c0000, 0x1fffff) AM_DEVICE("master_intc", namco_c148_device, map)
AM_IMPORT_FROM( common_metlhawk_am )
ADDRESS_MAP_END
static ADDRESS_MAP_START( slave_metlhawk_am, AS_PROGRAM, 16, namcos2_state )
AM_RANGE(0x000000, 0x03ffff) AM_ROM
AM_RANGE(0x100000, 0x13ffff) AM_RAMBANK(NAMCOS2_68K_SLAVE_RAM)
- AM_RANGE(0x1c0000, 0x1fffff) AM_READWRITE(namcos2_68k_slave_C148_r,namcos2_68k_slave_C148_w)
+ AM_RANGE(0x1c0000, 0x1fffff) AM_DEVICE("slave_intc", namco_c148_device, map)
AM_IMPORT_FROM( common_metlhawk_am )
ADDRESS_MAP_END
@@ -724,14 +723,14 @@ static ADDRESS_MAP_START( master_luckywld_am, AS_PROGRAM, 16, namcos2_state )
AM_RANGE(0x000000, 0x03ffff) AM_ROM
AM_RANGE(0x100000, 0x10ffff) AM_RAMBANK(NAMCOS2_68K_MASTER_RAM)
AM_RANGE(0x180000, 0x183fff) AM_READWRITE8(namcos2_68k_eeprom_r,namcos2_68k_eeprom_w,0x00ff)
- AM_RANGE(0x1c0000, 0x1fffff) AM_READWRITE(namcos2_68k_master_C148_r,namcos2_68k_master_C148_w)
+ AM_RANGE(0x1c0000, 0x1fffff) AM_DEVICE("master_intc", namco_c148_device, map)
AM_IMPORT_FROM( common_luckywld_am )
ADDRESS_MAP_END
static ADDRESS_MAP_START( slave_luckywld_am, AS_PROGRAM, 16, namcos2_state )
AM_RANGE(0x000000, 0x03ffff) AM_ROM
AM_RANGE(0x100000, 0x13ffff) AM_RAMBANK(NAMCOS2_68K_SLAVE_RAM)
- AM_RANGE(0x1c0000, 0x1fffff) AM_READWRITE(namcos2_68k_slave_C148_r,namcos2_68k_slave_C148_w)
+ AM_RANGE(0x1c0000, 0x1fffff) AM_DEVICE("slave_intc", namco_c148_device, map)
AM_IMPORT_FROM( common_luckywld_am )
ADDRESS_MAP_END
@@ -1680,14 +1679,45 @@ via software as INT1
/* */
/*************************************************************/
+static MACHINE_CONFIG_START( configure_c148_standard, namcos2_state )
+ MCFG_NAMCO_C148_ADD("master_intc","maincpu",true)
+ namco_c148_device::link_c148_device(*device,"slave_intc");
+ MCFG_NAMCO_C148_EXT1_CB(WRITE8(namcos2_state, sound_reset_w))
+ MCFG_NAMCO_C148_EXT2_CB(WRITE8(namcos2_state, system_reset_w))
+
+ MCFG_NAMCO_C148_ADD("slave_intc","slave",false)
+ namco_c148_device::link_c148_device(*device,"master_intc");
+
+MACHINE_CONFIG_END
+
+// TODO: temp
+TIMER_DEVICE_CALLBACK_MEMBER(namcos2_state::screen_scanline)
+{
+ int scanline = param;
+ int cur_posirq = get_pos_irq_scanline();
+
+ if(scanline == 240)
+ {
+ m_master_intc->vblank_irq_trigger();
+ m_slave_intc->vblank_irq_trigger();
+ }
+
+ if(scanline == cur_posirq)
+ {
+ m_master_intc->pos_irq_trigger();
+ m_slave_intc->pos_irq_trigger();
+ // TODO: wrong place!
+ m_screen->update_partial(param);
+ }
+}
+
static MACHINE_CONFIG_START( default, namcos2_state )
MCFG_CPU_ADD("maincpu", M68000, M68K_CPU_CLOCK) /* 12.288MHz (49.152MHz OSC/4) */
MCFG_CPU_PROGRAM_MAP(master_default_am)
- MCFG_CPU_VBLANK_INT_DRIVER("screen", namcos2_shared_state, namcos2_68k_master_vblank)
+ MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", namcos2_state, screen_scanline, "screen", 0, 1)
MCFG_CPU_ADD("slave", M68000, M68K_CPU_CLOCK) /* 12.288MHz (49.152MHz OSC/4) */
MCFG_CPU_PROGRAM_MAP(slave_default_am)
- MCFG_CPU_VBLANK_INT_DRIVER("screen", namcos2_shared_state, namcos2_68k_slave_vblank)
MCFG_CPU_ADD("audiocpu", M6809, M68B09_CPU_CLOCK) /* 2.048MHz (49.152MHz OSC/24) - Sound handling */
MCFG_CPU_PROGRAM_MAP(sound_default_am)
@@ -1704,6 +1734,9 @@ static MACHINE_CONFIG_START( default, namcos2_state )
MCFG_MACHINE_RESET_OVERRIDE(namcos2_state,namcos2)
MCFG_NVRAM_ADD_1FILL("nvram")
+ MCFG_FRAGMENT_ADD(configure_c148_standard)
+ MCFG_NAMCO_C139_ADD("sci")
+
MCFG_SCREEN_ADD("screen", RASTER)
MCFG_SCREEN_REFRESH_RATE( (49152000.0 / 8) / (384 * 264) )
MCFG_SCREEN_SIZE(384, 264)
@@ -1758,11 +1791,10 @@ MACHINE_CONFIG_END
static MACHINE_CONFIG_START( gollygho, namcos2_state )
MCFG_CPU_ADD("maincpu", M68000, M68K_CPU_CLOCK) /* 12.288MHz (49.152MHz OSC/4) */
MCFG_CPU_PROGRAM_MAP(master_default_am)
- MCFG_CPU_VBLANK_INT_DRIVER("screen", namcos2_shared_state, namcos2_68k_master_vblank)
+ MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", namcos2_state, screen_scanline, "screen", 0, 1)
MCFG_CPU_ADD("slave", M68000, M68K_CPU_CLOCK) /* 12.288MHz (49.152MHz OSC/4) */
MCFG_CPU_PROGRAM_MAP(slave_default_am)
- MCFG_CPU_VBLANK_INT_DRIVER("screen", namcos2_shared_state, namcos2_68k_slave_vblank)
MCFG_CPU_ADD("audiocpu", M6809, M68B09_CPU_CLOCK) /* 2.048MHz (49.152MHz OSC/24) - Sound handling */
MCFG_CPU_PROGRAM_MAP(sound_default_am)
@@ -1779,6 +1811,9 @@ static MACHINE_CONFIG_START( gollygho, namcos2_state )
MCFG_MACHINE_RESET_OVERRIDE(namcos2_state,namcos2)
MCFG_NVRAM_ADD_1FILL("nvram")
+ MCFG_FRAGMENT_ADD(configure_c148_standard)
+ MCFG_NAMCO_C139_ADD("sci")
+
MCFG_SCREEN_ADD("screen", RASTER)
MCFG_SCREEN_REFRESH_RATE( (49152000.0 / 8) / (384 * 264) )
MCFG_SCREEN_SIZE(384, 264)
@@ -1806,11 +1841,10 @@ MACHINE_CONFIG_END
static MACHINE_CONFIG_START( finallap, namcos2_state )
MCFG_CPU_ADD("maincpu", M68000, M68K_CPU_CLOCK) /* 12.288MHz (49.152MHz OSC/4) */
MCFG_CPU_PROGRAM_MAP(master_finallap_am)
- MCFG_CPU_VBLANK_INT_DRIVER("screen", namcos2_shared_state, namcos2_68k_master_vblank)
+ MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", namcos2_state, screen_scanline, "screen", 0, 1)
MCFG_CPU_ADD("slave", M68000, M68K_CPU_CLOCK) /* 12.288MHz (49.152MHz OSC/4) */
MCFG_CPU_PROGRAM_MAP(slave_finallap_am)
- MCFG_CPU_VBLANK_INT_DRIVER("screen", namcos2_shared_state, namcos2_68k_slave_vblank)
MCFG_CPU_ADD("audiocpu", M6809, M68B09_CPU_CLOCK) /* 2.048MHz (49.152MHz OSC/24) - Sound handling */
MCFG_CPU_PROGRAM_MAP(sound_default_am)
@@ -1827,6 +1861,9 @@ static MACHINE_CONFIG_START( finallap, namcos2_state )
MCFG_MACHINE_RESET_OVERRIDE(namcos2_state,namcos2)
MCFG_NVRAM_ADD_1FILL("nvram")
+ MCFG_FRAGMENT_ADD(configure_c148_standard)
+ MCFG_NAMCO_C139_ADD("sci")
+
MCFG_SCREEN_ADD("screen", RASTER)
MCFG_SCREEN_REFRESH_RATE( (49152000.0 / 8) / (384 * 264) )
MCFG_SCREEN_SIZE(384, 264)
@@ -1859,11 +1896,10 @@ MACHINE_CONFIG_END
static MACHINE_CONFIG_START( sgunner, namcos2_state )
MCFG_CPU_ADD("maincpu", M68000, M68K_CPU_CLOCK) /* 12.288MHz (49.152MHz OSC/4) */
MCFG_CPU_PROGRAM_MAP(master_sgunner_am)
- MCFG_CPU_VBLANK_INT_DRIVER("screen", namcos2_shared_state, namcos2_68k_master_vblank)
+ MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", namcos2_state, screen_scanline, "screen", 0, 1)
MCFG_CPU_ADD("slave", M68000, M68K_CPU_CLOCK) /* 12.288MHz (49.152MHz OSC/4) */
MCFG_CPU_PROGRAM_MAP(slave_sgunner_am)
- MCFG_CPU_VBLANK_INT_DRIVER("screen", namcos2_shared_state, namcos2_68k_slave_vblank)
MCFG_CPU_ADD("audiocpu", M6809, M68B09_CPU_CLOCK) /* 2.048MHz (49.152MHz OSC/24) - Sound handling */
MCFG_CPU_PROGRAM_MAP(sound_default_am)
@@ -1880,6 +1916,9 @@ static MACHINE_CONFIG_START( sgunner, namcos2_state )
MCFG_MACHINE_RESET_OVERRIDE(namcos2_state,namcos2)
MCFG_NVRAM_ADD_1FILL("nvram")
+ MCFG_FRAGMENT_ADD(configure_c148_standard)
+ MCFG_NAMCO_C139_ADD("sci")
+
MCFG_SCREEN_ADD("screen", RASTER)
MCFG_SCREEN_REFRESH_RATE( (49152000.0 / 8) / (384 * 264) )
MCFG_SCREEN_SIZE(384, 264)
@@ -1909,11 +1948,10 @@ MACHINE_CONFIG_END
static MACHINE_CONFIG_START( sgunner2, namcos2_state )
MCFG_CPU_ADD("maincpu", M68000, M68K_CPU_CLOCK) /* 12.288MHz (49.152MHz OSC/4) */
MCFG_CPU_PROGRAM_MAP(master_sgunner_am)
- MCFG_CPU_VBLANK_INT_DRIVER("screen", namcos2_shared_state, namcos2_68k_master_vblank)
+ MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", namcos2_state, screen_scanline, "screen", 0, 1)
MCFG_CPU_ADD("slave", M68000, M68K_CPU_CLOCK) /* 12.288MHz (49.152MHz OSC/4) */
MCFG_CPU_PROGRAM_MAP(slave_sgunner_am)
- MCFG_CPU_VBLANK_INT_DRIVER("screen", namcos2_shared_state, namcos2_68k_slave_vblank)
MCFG_CPU_ADD("audiocpu", M6809, M68B09_CPU_CLOCK) /* 2.048MHz (49.152MHz OSC/24) - Sound handling */
MCFG_CPU_PROGRAM_MAP(sound_default_am)
@@ -1935,6 +1973,9 @@ static MACHINE_CONFIG_START( sgunner2, namcos2_state )
MCFG_MACHINE_RESET_OVERRIDE(namcos2_state,namcos2)
MCFG_NVRAM_ADD_1FILL("nvram")
+ MCFG_FRAGMENT_ADD(configure_c148_standard)
+ MCFG_NAMCO_C139_ADD("sci")
+
MCFG_SCREEN_ADD("screen", RASTER)
MCFG_SCREEN_REFRESH_RATE( (49152000.0 / 8) / (384 * 264) )
MCFG_SCREEN_SIZE(384, 264)
@@ -1964,11 +2005,10 @@ MACHINE_CONFIG_END
static MACHINE_CONFIG_START( luckywld, namcos2_state )
MCFG_CPU_ADD("maincpu", M68000, M68K_CPU_CLOCK) /* 12.288MHz (49.152MHz OSC/4) */
MCFG_CPU_PROGRAM_MAP(master_luckywld_am)
- MCFG_CPU_VBLANK_INT_DRIVER("screen", namcos2_shared_state, namcos2_68k_master_vblank)
+ MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", namcos2_state, screen_scanline, "screen", 0, 1)
MCFG_CPU_ADD("slave", M68000, M68K_CPU_CLOCK) /* 12.288MHz (49.152MHz OSC/4) */
MCFG_CPU_PROGRAM_MAP(slave_luckywld_am)
- MCFG_CPU_VBLANK_INT_DRIVER("screen", namcos2_shared_state, namcos2_68k_slave_vblank)
MCFG_CPU_ADD("audiocpu", M6809, M68B09_CPU_CLOCK) /* 2.048MHz (49.152MHz OSC/24) - Sound handling */
MCFG_CPU_PROGRAM_MAP(sound_default_am)
@@ -1985,6 +2025,9 @@ static MACHINE_CONFIG_START( luckywld, namcos2_state )
MCFG_MACHINE_RESET_OVERRIDE(namcos2_state,namcos2)
MCFG_NVRAM_ADD_1FILL("nvram")
+ MCFG_FRAGMENT_ADD(configure_c148_standard)
+ MCFG_NAMCO_C139_ADD("sci")
+
MCFG_SCREEN_ADD("screen", RASTER)
MCFG_SCREEN_REFRESH_RATE( (49152000.0 / 8) / (384 * 264) )
MCFG_SCREEN_SIZE(384, 264)
@@ -2017,16 +2060,15 @@ MACHINE_CONFIG_END
static MACHINE_CONFIG_START( metlhawk, namcos2_state )
MCFG_CPU_ADD("maincpu", M68000, M68K_CPU_CLOCK) /* 12.288MHz (49.152MHz OSC/4) */
MCFG_CPU_PROGRAM_MAP(master_metlhawk_am)
- MCFG_CPU_VBLANK_INT_DRIVER("screen", namcos2_shared_state, namcos2_68k_master_vblank)
+ MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", namcos2_state, screen_scanline, "screen", 0, 1)
MCFG_CPU_ADD("slave", M68000, M68K_CPU_CLOCK) /* 12.288MHz (49.152MHz OSC/4) */
MCFG_CPU_PROGRAM_MAP(slave_metlhawk_am)
- MCFG_CPU_VBLANK_INT_DRIVER("screen", namcos2_shared_state, namcos2_68k_slave_vblank)
MCFG_CPU_ADD("audiocpu", M6809, M68B09_CPU_CLOCK) /* 2.048MHz (49.152MHz OSC/24) - Sound handling */
MCFG_CPU_PROGRAM_MAP(sound_default_am)
- MCFG_CPU_PERIODIC_INT_DRIVER(namcos2_shared_state, irq0_line_hold, 2*60)
- MCFG_CPU_PERIODIC_INT_DRIVER(namcos2_shared_state, irq1_line_hold, 120)
+ //MCFG_CPU_PERIODIC_INT_DRIVER(namcos2_shared_state, irq0_line_hold, 2*60)
+ //MCFG_CPU_PERIODIC_INT_DRIVER(namcos2_shared_state, irq1_line_hold, 120)
MCFG_CPU_ADD("mcu", HD63705, C65_CPU_CLOCK) /* 2.048MHz (49.152MHz OSC/24) - I/O handling */
MCFG_CPU_PROGRAM_MAP(mcu_default_am)
@@ -2038,6 +2080,9 @@ static MACHINE_CONFIG_START( metlhawk, namcos2_state )
MCFG_MACHINE_RESET_OVERRIDE(namcos2_state,namcos2)
MCFG_NVRAM_ADD_1FILL("nvram")
+ MCFG_FRAGMENT_ADD(configure_c148_standard)
+ MCFG_NAMCO_C139_ADD("sci")
+
MCFG_SCREEN_ADD("screen", RASTER)
MCFG_SCREEN_REFRESH_RATE( (49152000.0 / 8) / (384 * 264) )
MCFG_SCREEN_SIZE(384, 264)
@@ -2060,6 +2105,7 @@ static MACHINE_CONFIG_START( metlhawk, namcos2_state )
MCFG_SOUND_ROUTE(1, "rspeaker", 1.0)
MCFG_YM2151_ADD("ymsnd", YM2151_SOUND_CLOCK) /* 3.579545MHz */
+ MCFG_YM2151_IRQ_HANDLER(INPUTLINE("audiocpu", 1))
MCFG_SOUND_ROUTE(0, "lspeaker", 0.80)
MCFG_SOUND_ROUTE(1, "rspeaker", 0.80)
MACHINE_CONFIG_END
@@ -5687,11 +5733,11 @@ DRIVER_INIT_MEMBER(namcos2_state,luckywld)
/* and metal hawk have the B version and dragon saber has the C version */
/* YEAR, NAME, PARENT, MACHINE, INPUT, STATE, INIT, MONITOR, COMPANY, FULLNAME */
-GAMEL(1987, finallap, 0, finallap, finallap, namcos2_state, finallap, ROT0, "Namco", "Final Lap (Rev E)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND, layout_finallap )
-GAMEL(1987, finallapd, finallap, finallap, finallap, namcos2_state, finallap, ROT0, "Namco", "Final Lap (Rev D)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND, layout_finallap )
-GAMEL(1987, finallapc, finallap, finallap, finallap, namcos2_state, finallap, ROT0, "Namco", "Final Lap (Rev C)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND, layout_finallap )
-GAMEL(1987, finallapjc, finallap, finallap, finallap, namcos2_state, finallap, ROT0, "Namco", "Final Lap (Japan, Rev C)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND, layout_finallap )
-GAMEL(1987, finallapjb, finallap, finallap, finallap, namcos2_state, finallap, ROT0, "Namco", "Final Lap (Japan, Rev B)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND, layout_finallap )
+GAMEL(1987, finallap, 0, finallap, finallap, namcos2_state, finallap, ROT0, "Namco", "Final Lap (Rev E)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_NODEVICE_LAN, layout_finallap )
+GAMEL(1987, finallapd, finallap, finallap, finallap, namcos2_state, finallap, ROT0, "Namco", "Final Lap (Rev D)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_NODEVICE_LAN, layout_finallap )
+GAMEL(1987, finallapc, finallap, finallap, finallap, namcos2_state, finallap, ROT0, "Namco", "Final Lap (Rev C)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_NODEVICE_LAN, layout_finallap )
+GAMEL(1987, finallapjc, finallap, finallap, finallap, namcos2_state, finallap, ROT0, "Namco", "Final Lap (Japan, Rev C)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_NODEVICE_LAN, layout_finallap )
+GAMEL(1987, finallapjb, finallap, finallap, finallap, namcos2_state, finallap, ROT0, "Namco", "Final Lap (Japan, Rev B)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_NODEVICE_LAN, layout_finallap )
GAME( 1988, assault, 0, default2, assault, namcos2_state, assault, ROT90, "Namco", "Assault (Rev B)", 0 )
GAME( 1988, assaultj, assault, default2, assault, namcos2_state, assaultj, ROT90, "Namco", "Assault (Japan)", 0 )
@@ -5708,9 +5754,9 @@ GAME( 1988, mirninja, 0, default, default, namcos2_state, mirninja, R
GAME( 1988, phelios, 0, default2, default, namcos2_state, phelios, ROT90, "Namco", "Phelios", 0)
GAME( 1988, pheliosj, phelios, default2, default, namcos2_state, phelios, ROT90, "Namco", "Phelios (Japan)", 0)
-GAME( 1989, dirtfoxj, 0, default2, dirtfox, namcos2_state, dirtfoxj, ROT90, "Namco", "Dirt Fox (Japan)", 0 )
+GAME( 1989, dirtfoxj, 0, default2, dirtfox, namcos2_state, dirtfoxj, ROT90, "Namco", "Dirt Fox (Japan)", MACHINE_NODEVICE_LAN )
-GAMEL(1989, fourtrax, 0, finallap, fourtrax, namcos2_state, fourtrax, ROT0, "Namco", "Four Trax", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND, layout_finallap )
+GAMEL(1989, fourtrax, 0, finallap, fourtrax, namcos2_state, fourtrax, ROT0, "Namco", "Four Trax", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_NODEVICE_LAN, layout_finallap )
GAME( 1989, valkyrie, 0, default3, default, namcos2_state, valkyrie, ROT90, "Namco", "Valkyrie No Densetsu (Japan)", 0 )
@@ -5729,8 +5775,8 @@ GAME( 1990, dsaber, 0, default3, default, namcos2_state, dsaber, R
GAME( 1990, dsabera, dsaber, default3, default, namcos2_state, dsaber, ROT90, "Namco", "Dragon Saber (World, older?)", 0 )
GAME( 1990, dsaberj, dsaber, default3, default, namcos2_state, dsaberj, ROT90, "Namco", "Dragon Saber (Japan, Rev B)", 0 )
-GAMEL(1990, finalap2, 0, finallap, finallap, namcos2_state, finalap2, ROT0, "Namco", "Final Lap 2", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND, layout_finallap )
-GAMEL(1990, finalap2j, finalap2, finallap, finallap, namcos2_state, finalap2, ROT0, "Namco", "Final Lap 2 (Japan)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND, layout_finallap )
+GAMEL(1990, finalap2, 0, finallap, finallap, namcos2_state, finalap2, ROT0, "Namco", "Final Lap 2", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_NODEVICE_LAN, layout_finallap )
+GAMEL(1990, finalap2j, finalap2, finallap, finallap, namcos2_state, finalap2, ROT0, "Namco", "Final Lap 2 (Japan)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_NODEVICE_LAN, layout_finallap )
GAME( 1990, gollygho, 0, gollygho, gollygho, namcos2_state, gollygho, ROT180, "Namco", "Golly! Ghost!", MACHINE_REQUIRES_ARTWORK )
@@ -5749,24 +5795,24 @@ GAME( 1991, cosmogngj, cosmogng, default, default, namcos2_state, cosmogng, R
GAME( 1992, bubbletr, 0, gollygho, bubbletr, namcos2_state, bubbletr, ROT180, "Namco", "Bubble Trouble (World, Rev B)", MACHINE_REQUIRES_ARTWORK )
GAME( 1992, bubbletrj, bubbletr, gollygho, bubbletr, namcos2_state, bubbletr, ROT180, "Namco", "Bubble Trouble (Japan, Rev C)", MACHINE_REQUIRES_ARTWORK )
-GAMEL(1992, finalap3, 0, finallap, finalap3, namcos2_state, finalap3, ROT0, "Namco", "Final Lap 3 (World, set 1)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND, layout_finallap )
-GAMEL(1992, finalap3a, finalap3, finallap, finalap3, namcos2_state, finalap3, ROT0, "Namco", "Final Lap 3 (World, set 2)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND, layout_finallap )
-GAMEL(1992, finalap3j, finalap3, finallap, finalap3, namcos2_state, finalap3, ROT0, "Namco", "Final Lap 3 (Japan)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND, layout_finallap )
-GAMEL(1992, finalap3jc, finalap3, finallap, finalap3, namcos2_state, finalap3, ROT0, "Namco", "Final Lap 3 (Japan - Rev C)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND, layout_finallap )
-GAMEL(1992, finalap3bl, finalap3, finallap, finalap3, namcos2_state, finalap3, ROT0, "Namco", "Final Lap 3 (bootleg)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND, layout_finallap )
+GAMEL(1992, finalap3, 0, finallap, finalap3, namcos2_state, finalap3, ROT0, "Namco", "Final Lap 3 (World, set 1)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_NODEVICE_LAN, layout_finallap )
+GAMEL(1992, finalap3a, finalap3, finallap, finalap3, namcos2_state, finalap3, ROT0, "Namco", "Final Lap 3 (World, set 2)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_NODEVICE_LAN, layout_finallap )
+GAMEL(1992, finalap3j, finalap3, finallap, finalap3, namcos2_state, finalap3, ROT0, "Namco", "Final Lap 3 (Japan)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_NODEVICE_LAN, layout_finallap )
+GAMEL(1992, finalap3jc, finalap3, finallap, finalap3, namcos2_state, finalap3, ROT0, "Namco", "Final Lap 3 (Japan - Rev C)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_NODEVICE_LAN, layout_finallap )
+GAMEL(1992, finalap3bl, finalap3, finallap, finalap3, namcos2_state, finalap3, ROT0, "Namco", "Final Lap 3 (bootleg)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_NODEVICE_LAN, layout_finallap )
GAME( 1992, luckywld, 0, luckywld, luckywld, namcos2_state, luckywld, ROT0, "Namco", "Lucky & Wild", 0 )
GAME( 1992, luckywldj, luckywld, luckywld, luckywld, namcos2_state, luckywld, ROT0, "Namco", "Lucky & Wild (Japan)", 0 )
-GAME( 1992, suzuka8h, 0, luckywld, suzuka, namcos2_state, suzuka8h, ROT0, "Namco", "Suzuka 8 Hours (World, Rev C)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
-GAME( 1992, suzuka8hj, suzuka8h, luckywld, suzuka, namcos2_state, suzuka8h, ROT0, "Namco", "Suzuka 8 Hours (Japan, Rev B)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
+GAME( 1992, suzuka8h, 0, luckywld, suzuka, namcos2_state, suzuka8h, ROT0, "Namco", "Suzuka 8 Hours (World, Rev C)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_NODEVICE_LAN )
+GAME( 1992, suzuka8hj, suzuka8h, luckywld, suzuka, namcos2_state, suzuka8h, ROT0, "Namco", "Suzuka 8 Hours (Japan, Rev B)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_NODEVICE_LAN )
GAME( 1992, sws, 0, default, default, namcos2_state, sws, ROT0, "Namco", "Super World Stadium (Japan)", 0 )
GAME( 1992, sws92, 0, default, default, namcos2_state, sws92, ROT0, "Namco", "Super World Stadium '92 (Japan)", 0 )
GAME( 1992, sws92g, sws92, default, default, namcos2_state, sws92g, ROT0, "Namco", "Super World Stadium '92 Gekitouban (Japan)", 0 )
-GAME( 1993, suzuk8h2, 0, luckywld, suzuka, namcos2_state, suzuk8h2, ROT0, "Namco", "Suzuka 8 Hours 2 (World, Rev B)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
-GAME( 1993, suzuk8h2j, suzuk8h2, luckywld, suzuka, namcos2_state, suzuk8h2, ROT0, "Namco", "Suzuka 8 Hours 2 (Japan, Rev B)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
+GAME( 1993, suzuk8h2, 0, luckywld, suzuka, namcos2_state, suzuk8h2, ROT0, "Namco", "Suzuka 8 Hours 2 (World, Rev B)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_NODEVICE_LAN )
+GAME( 1993, suzuk8h2j, suzuk8h2, luckywld, suzuka, namcos2_state, suzuk8h2, ROT0, "Namco", "Suzuka 8 Hours 2 (Japan, Rev B)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_NODEVICE_LAN )
GAME( 1993, sws93, 0, default, default, namcos2_state, sws93, ROT0, "Namco", "Super World Stadium '93 (Japan)", 0 )
diff --git a/src/mame/drivers/namcos21.cpp b/src/mame/drivers/namcos21.cpp
index f04b1cd8ba1..1e99e5b9ee3 100644
--- a/src/mame/drivers/namcos21.cpp
+++ b/src/mame/drivers/namcos21.cpp
@@ -67,7 +67,7 @@ STATUS:
- posirq handling broken
Driver's Eyes
- crashes
+ Left and Right screen
TODO: (*) Extract DSP BIOS
@@ -805,6 +805,7 @@ WRITE16_MEMBER(namcos21_state::dspram16_w)
int namcos21_state::init_dsp()
{
+ // TODO: what actually tests this?
uint16_t *pMem = (uint16_t *)memregion("dspmaster")->base();
/**
* DSP BIOS tests "CPU ID" on startup
@@ -1226,12 +1227,6 @@ WRITE8_MEMBER(namcos21_state::namcos2_dualportram_byte_w)
}
/******************************************************************************/
-WRITE16_MEMBER(namcos21_state::NAMCO_C139_SCI_buffer_w){}
-READ16_MEMBER(namcos21_state::NAMCO_C139_SCI_buffer_r){ return 0; }
-
-WRITE16_MEMBER(namcos21_state::NAMCO_C139_SCI_register_w){}
-READ16_MEMBER(namcos21_state::NAMCO_C139_SCI_register_r){ return 0; }
-/******************************************************************************/
/*************************************************************/
/* MASTER 68000 CPU Memory declarations */
@@ -1252,8 +1247,8 @@ static ADDRESS_MAP_START( common_map, AS_PROGRAM, 16, namcos21_state )
AM_RANGE(0x800000, 0x8fffff) AM_ROM AM_REGION("data", 0)
AM_RANGE(0x900000, 0x90ffff) AM_RAM AM_SHARE("sharedram")
AM_RANGE(0xa00000, 0xa00fff) AM_READWRITE(namcos2_68k_dualportram_word_r,namcos2_68k_dualportram_word_w)
- AM_RANGE(0xb00000, 0xb03fff) AM_READWRITE(NAMCO_C139_SCI_buffer_r,NAMCO_C139_SCI_buffer_w)
- AM_RANGE(0xb80000, 0xb8000f) AM_READWRITE(NAMCO_C139_SCI_register_r,NAMCO_C139_SCI_register_w)
+ AM_RANGE(0xb00000, 0xb03fff) AM_DEVREADWRITE("sci", namco_c139_device, ram_r, ram_w)
+ AM_RANGE(0xb80000, 0xb8000f) AM_DEVICE("sci", namco_c139_device, regs_map)
AM_RANGE(0xc00000, 0xcfffff) AM_ROM AM_MIRROR(0x100000) AM_REGION("edata", 0)
ADDRESS_MAP_END
@@ -1261,14 +1256,14 @@ static ADDRESS_MAP_START( master_map, AS_PROGRAM, 16, namcos21_state )
AM_RANGE(0x000000, 0x0fffff) AM_ROM
AM_RANGE(0x100000, 0x10ffff) AM_RAM /* private work RAM */
AM_RANGE(0x180000, 0x183fff) AM_READWRITE8(namcos2_68k_eeprom_r,namcos2_68k_eeprom_w,0x00ff)
- AM_RANGE(0x1c0000, 0x1fffff) AM_READWRITE(namcos2_68k_master_C148_r,namcos2_68k_master_C148_w)
+ AM_RANGE(0x1c0000, 0x1fffff) AM_DEVICE("master_intc", namco_c148_device, map)
AM_IMPORT_FROM( common_map )
ADDRESS_MAP_END
static ADDRESS_MAP_START( slave_map, AS_PROGRAM, 16, namcos21_state )
AM_RANGE(0x000000, 0x07ffff) AM_ROM
AM_RANGE(0x100000, 0x13ffff) AM_RAM /* private work RAM */
- AM_RANGE(0x1c0000, 0x1fffff) AM_READWRITE(namcos2_68k_slave_C148_r,namcos2_68k_slave_C148_w)
+ AM_RANGE(0x1c0000, 0x1fffff) AM_DEVICE("slave_intc", namco_c148_device, map)
AM_IMPORT_FROM( common_map )
ADDRESS_MAP_END
@@ -1469,7 +1464,7 @@ static ADDRESS_MAP_START( winrun_master_map, AS_PROGRAM, 16, namcos21_state )
AM_RANGE(0x000000, 0x03ffff) AM_ROM
AM_RANGE(0x100000, 0x10ffff) AM_RAM /* work RAM */
AM_RANGE(0x180000, 0x183fff) AM_READWRITE8(namcos2_68k_eeprom_r,namcos2_68k_eeprom_w,0x00ff)
- AM_RANGE(0x1c0000, 0x1fffff) AM_READWRITE(namcos2_68k_master_C148_r,namcos2_68k_master_C148_w)
+ AM_RANGE(0x1c0000, 0x1fffff) AM_DEVICE("master_intc", namco_c148_device, map)
AM_RANGE(0x250000, 0x25ffff) AM_RAM AM_SHARE("winrun_polydata")
AM_RANGE(0x260000, 0x26ffff) AM_RAM /* unused? */
AM_RANGE(0x280000, 0x281fff) AM_WRITE(winrun_dspbios_w) AM_SHARE("winrun_dspbios")
@@ -1481,34 +1476,35 @@ static ADDRESS_MAP_START( winrun_master_map, AS_PROGRAM, 16, namcos21_state )
AM_RANGE(0x800000, 0x87ffff) AM_ROM AM_REGION("data", 0)
AM_RANGE(0x900000, 0x90ffff) AM_RAM AM_SHARE("sharedram")
AM_RANGE(0xa00000, 0xa00fff) AM_READWRITE(namcos2_68k_dualportram_word_r,namcos2_68k_dualportram_word_w)
- AM_RANGE(0xb00000, 0xb03fff) AM_READWRITE(NAMCO_C139_SCI_buffer_r,NAMCO_C139_SCI_buffer_w)
- AM_RANGE(0xb80000, 0xb8000f) AM_READWRITE(NAMCO_C139_SCI_register_r,NAMCO_C139_SCI_register_w)
+ AM_RANGE(0xb00000, 0xb03fff) AM_DEVREADWRITE("sci", namco_c139_device, ram_r, ram_w)
+ AM_RANGE(0xb80000, 0xb8000f) AM_DEVICE("sci", namco_c139_device, regs_map)
ADDRESS_MAP_END
static ADDRESS_MAP_START( winrun_slave_map, AS_PROGRAM, 16, namcos21_state )
AM_RANGE(0x000000, 0x03ffff) AM_ROM
AM_RANGE(0x100000, 0x13ffff) AM_RAM
- AM_RANGE(0x1c0000, 0x1fffff) AM_READWRITE(namcos2_68k_slave_C148_r,namcos2_68k_slave_C148_w)
+ AM_RANGE(0x1c0000, 0x1fffff) AM_DEVICE("slave_intc", namco_c148_device, map)
AM_RANGE(0x600000, 0x60ffff) AM_RAM AM_SHARE("gpu_comram")
AM_RANGE(0x800000, 0x87ffff) AM_ROM AM_REGION("data", 0)
AM_RANGE(0x900000, 0x90ffff) AM_RAM AM_SHARE("sharedram")
AM_RANGE(0xa00000, 0xa00fff) AM_READWRITE(namcos2_68k_dualportram_word_r,namcos2_68k_dualportram_word_w)
- AM_RANGE(0xb00000, 0xb03fff) AM_READWRITE(NAMCO_C139_SCI_buffer_r,NAMCO_C139_SCI_buffer_w)
- AM_RANGE(0xb80000, 0xb8000f) AM_READWRITE(NAMCO_C139_SCI_register_r,NAMCO_C139_SCI_register_w)
+ AM_RANGE(0xb00000, 0xb03fff) AM_DEVREADWRITE("sci", namco_c139_device, ram_r, ram_w)
+ AM_RANGE(0xb80000, 0xb8000f) AM_DEVICE("sci", namco_c139_device, regs_map)
ADDRESS_MAP_END
+
static ADDRESS_MAP_START( winrun_gpu_map, AS_PROGRAM, 16, namcos21_state )
AM_RANGE(0x000000, 0x07ffff) AM_ROM
AM_RANGE(0x100000, 0x100001) AM_READWRITE(winrun_gpu_color_r,winrun_gpu_color_w) /* ? */
AM_RANGE(0x180000, 0x19ffff) AM_RAM /* work RAM */
- AM_RANGE(0x1c0000, 0x1fffff) AM_READWRITE(namcos21_68k_gpu_C148_r,namcos21_68k_gpu_C148_w)
+ AM_RANGE(0x1c0000, 0x1fffff) AM_DEVICE("gpu_intc", namco_c148_device, map)
AM_RANGE(0x200000, 0x20ffff) AM_RAM AM_SHARE("gpu_comram")
AM_RANGE(0x400000, 0x40ffff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette")
AM_RANGE(0x410000, 0x41ffff) AM_RAM_DEVWRITE("palette", palette_device, write_ext) AM_SHARE("palette_ext")
AM_RANGE(0x600000, 0x6fffff) AM_ROM AM_REGION("gdata", 0)
AM_RANGE(0xc00000, 0xcfffff) AM_READWRITE(winrun_gpu_videoram_r,winrun_gpu_videoram_w)
AM_RANGE(0xd00000, 0xd0000f) AM_READWRITE(winrun_gpu_register_r,winrun_gpu_register_w)
-// AM_RANGE(0xe0000c, 0xe0000d) POSIRQ
+ AM_RANGE(0xe0000c, 0xe0000d) AM_DEVREADWRITE8("gpu_intc", namco_c148_device, ext_posirq_line_r,ext_posirq_line_w,0x00ff)
ADDRESS_MAP_END
@@ -1572,15 +1568,15 @@ static ADDRESS_MAP_START( driveyes_common_map, AS_PROGRAM, 16, namcos21_state )
AM_RANGE(0x800000, 0x8fffff) AM_ROM AM_REGION("data", 0)
AM_RANGE(0x900000, 0x90ffff) AM_RAM AM_SHARE("sharedram")
AM_RANGE(0xa00000, 0xa00fff) AM_READWRITE(namcos2_68k_dualportram_word_r,namcos2_68k_dualportram_word_w)
- AM_RANGE(0xb00000, 0xb03fff) AM_READWRITE(NAMCO_C139_SCI_buffer_r,NAMCO_C139_SCI_buffer_w)
- AM_RANGE(0xb80000, 0xb8000f) AM_READWRITE(NAMCO_C139_SCI_register_r,NAMCO_C139_SCI_register_w)
+ AM_RANGE(0xb00000, 0xb03fff) AM_DEVREADWRITE("sci", namco_c139_device, ram_r, ram_w)
+ AM_RANGE(0xb80000, 0xb8000f) AM_DEVICE("sci", namco_c139_device, regs_map)
ADDRESS_MAP_END
static ADDRESS_MAP_START( driveyes_master_map, AS_PROGRAM, 16, namcos21_state )
AM_RANGE(0x000000, 0x03ffff) AM_ROM
AM_RANGE(0x100000, 0x10ffff) AM_RAM /* private work RAM */
AM_RANGE(0x180000, 0x183fff) AM_READWRITE8(namcos2_68k_eeprom_r,namcos2_68k_eeprom_w,0x00ff)
- AM_RANGE(0x1c0000, 0x1fffff) AM_READWRITE(namcos2_68k_master_C148_r,namcos2_68k_master_C148_w)
+ AM_RANGE(0x1c0000, 0x1fffff) AM_DEVICE("master_intc", namco_c148_device, map)
AM_RANGE(0x250000, 0x25ffff) AM_RAM AM_SHARE("winrun_polydata")
AM_RANGE(0x280000, 0x281fff) AM_WRITE(winrun_dspbios_w) AM_SHARE("winrun_dspbios")
AM_RANGE(0x380000, 0x38000f) AM_READWRITE(winrun_dspcomram_control_r,winrun_dspcomram_control_w)
@@ -1593,7 +1589,7 @@ ADDRESS_MAP_END
static ADDRESS_MAP_START( driveyes_slave_map, AS_PROGRAM, 16, namcos21_state )
AM_RANGE(0x000000, 0x03ffff) AM_ROM
AM_RANGE(0x100000, 0x10ffff) AM_RAM /* private work RAM */
- AM_RANGE(0x1c0000, 0x1fffff) AM_READWRITE(namcos2_68k_slave_C148_r,namcos2_68k_slave_C148_w)
+ AM_RANGE(0x1c0000, 0x1fffff) AM_DEVICE("slave_intc", namco_c148_device, map)
AM_IMPORT_FROM( driveyes_common_map )
ADDRESS_MAP_END
@@ -1851,15 +1847,44 @@ MACHINE_START_MEMBER(namcos21_state,namcos21)
namcos2_kickstart = namcos21_kickstart;
}
+TIMER_DEVICE_CALLBACK_MEMBER(namcos21_state::screen_scanline)
+{
+ int scanline = param;
+// int cur_posirq = get_posirq_scanline()*2;
+
+ if(scanline == 240*2)
+ {
+ m_master_intc->vblank_irq_trigger();
+ m_slave_intc->vblank_irq_trigger();
+ if(m_gpu_intc)
+ m_gpu_intc->vblank_irq_trigger();
+ }
+
+ if(m_gpu_intc != nullptr)
+ {
+ if(scanline == (0xff-m_gpu_intc->get_posirq_line())*2)
+ m_gpu_intc->pos_irq_trigger();
+ }
+}
+
+static MACHINE_CONFIG_START( configure_c148_standard, namcos21_state )
+ MCFG_NAMCO_C148_ADD("master_intc","maincpu",true)
+ namco_c148_device::link_c148_device(*device,"slave_intc");
+ MCFG_NAMCO_C148_EXT1_CB(WRITE8(namcos21_state, sound_reset_w))
+ MCFG_NAMCO_C148_EXT2_CB(WRITE8(namcos21_state, system_reset_w))
+
+ MCFG_NAMCO_C148_ADD("slave_intc","slave",false)
+ namco_c148_device::link_c148_device(*device,"master_intc");
+
+MACHINE_CONFIG_END
static MACHINE_CONFIG_START( namcos21, namcos21_state )
MCFG_CPU_ADD("maincpu", M68000,12288000) /* Master */
MCFG_CPU_PROGRAM_MAP(master_map)
- MCFG_CPU_VBLANK_INT_DRIVER("screen", namcos21_state, namcos2_68k_master_vblank)
+ MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", namcos21_state, screen_scanline, "screen", 0, 1)
MCFG_CPU_ADD("slave", M68000,12288000) /* Slave */
MCFG_CPU_PROGRAM_MAP(slave_map)
- MCFG_CPU_VBLANK_INT_DRIVER("screen", namcos21_state, namcos2_68k_slave_vblank)
MCFG_CPU_ADD("audiocpu", M6809,3072000) /* Sound */
MCFG_CPU_PROGRAM_MAP(sound_map)
@@ -1898,6 +1923,9 @@ static MACHINE_CONFIG_START( namcos21, namcos21_state )
MCFG_SCREEN_UPDATE_DRIVER(namcos21_state, screen_update_namcos21)
MCFG_SCREEN_PALETTE("palette")
+ MCFG_FRAGMENT_ADD(configure_c148_standard)
+ MCFG_NAMCO_C139_ADD("sci")
+
MCFG_GFXDECODE_ADD("gfxdecode", "palette", namcos21)
MCFG_PALETTE_ADD("palette", NAMCOS21_NUM_COLORS)
MCFG_PALETTE_FORMAT(XBRG)
@@ -1920,11 +1948,10 @@ MACHINE_CONFIG_END
static MACHINE_CONFIG_START( driveyes, namcos21_state )
MCFG_CPU_ADD("maincpu", M68000,12288000) /* Master */
MCFG_CPU_PROGRAM_MAP(driveyes_master_map)
- MCFG_CPU_VBLANK_INT_DRIVER("screen", namcos21_state, namcos2_68k_master_vblank)
+ MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", namcos21_state, screen_scanline, "screen", 0, 1)
MCFG_CPU_ADD("slave", M68000,12288000) /* Slave */
MCFG_CPU_PROGRAM_MAP(driveyes_slave_map)
- MCFG_CPU_VBLANK_INT_DRIVER("screen", namcos21_state, namcos2_68k_slave_vblank)
MCFG_CPU_ADD("audiocpu", M6809,3072000) /* Sound */
MCFG_CPU_PROGRAM_MAP(sound_map)
@@ -1952,6 +1979,9 @@ static MACHINE_CONFIG_START( driveyes, namcos21_state )
MCFG_DEVICE_ADD("gearbox", NAMCOIO_GEARBOX, 0)
+ MCFG_FRAGMENT_ADD(configure_c148_standard)
+ MCFG_NAMCO_C139_ADD("sci")
+
MCFG_SCREEN_ADD("screen", RASTER)
MCFG_SCREEN_RAW_PARAMS_NAMCO480I
MCFG_SCREEN_UPDATE_DRIVER(namcos21_state, screen_update_driveyes)
@@ -1975,15 +2005,13 @@ static MACHINE_CONFIG_START( driveyes, namcos21_state )
MCFG_SOUND_ROUTE(1, "rspeaker", 0.30)
MACHINE_CONFIG_END
-
static MACHINE_CONFIG_START( winrun, namcos21_state )
MCFG_CPU_ADD("maincpu", M68000,12288000) /* Master */
MCFG_CPU_PROGRAM_MAP(winrun_master_map)
- MCFG_CPU_VBLANK_INT_DRIVER("screen", namcos21_state, namcos2_68k_master_vblank)
+ MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", namcos21_state, screen_scanline, "screen", 0, 1)
MCFG_CPU_ADD("slave", M68000,12288000) /* Slave */
MCFG_CPU_PROGRAM_MAP(winrun_slave_map)
- MCFG_CPU_VBLANK_INT_DRIVER("screen", namcos21_state, namcos2_68k_slave_vblank)
MCFG_CPU_ADD("audiocpu", M6809,3072000) /* Sound */
MCFG_CPU_PROGRAM_MAP(sound_map)
@@ -2005,7 +2033,10 @@ static MACHINE_CONFIG_START( winrun, namcos21_state )
MCFG_CPU_ADD("gpu", M68000,12288000) /* graphics coprocessor */
MCFG_CPU_PROGRAM_MAP(winrun_gpu_map)
- MCFG_CPU_VBLANK_INT_DRIVER("screen", namcos21_state, namcos2_68k_gpu_vblank)
+
+ MCFG_FRAGMENT_ADD(configure_c148_standard)
+ MCFG_NAMCO_C148_ADD("gpu_intc","gpu",false)
+ MCFG_NAMCO_C139_ADD("sci")
MCFG_QUANTUM_TIME(attotime::from_hz(6000)) /* 100 CPU slices per frame */
@@ -2726,13 +2757,13 @@ DRIVER_INIT_MEMBER(namcos21_state,driveyes)
/* YEAR, NAME, PARENT, MACHINE, INPUT, INIT, MONITOR, COMPANY, FULLNAME, FLAGS */
GAME( 1988, winrun, 0, winrun, winrun, namcos21_state, winrun, ROT0, "Namco", "Winning Run", MACHINE_IMPERFECT_GRAPHICS )
-GAME( 1989, winrungp, 0, winrun, winrungp, namcos21_state, winrun, ROT0, "Namco", "Winning Run Suzuka Grand Prix (Japan)", MACHINE_IMPERFECT_GRAPHICS )
-GAME( 1991, winrun91, 0, winrun, winrungp, namcos21_state, winrun, ROT0, "Namco", "Winning Run '91 (Japan)", MACHINE_IMPERFECT_GRAPHICS )
-GAME( 1991, driveyes, 0, driveyes, driveyes, namcos21_state, driveyes, ROT0, "Namco", "Driver's Eyes (Japan)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS )
+GAME( 1989, winrungp, 0, winrun, winrungp, namcos21_state, winrun, ROT0, "Namco", "Winning Run Suzuka Grand Prix (Japan)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NODEVICE_LAN )
+GAME( 1991, winrun91, 0, winrun, winrungp, namcos21_state, winrun, ROT0, "Namco", "Winning Run '91 (Japan)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NODEVICE_LAN )
+GAME( 1991, driveyes, 0, driveyes, driveyes, namcos21_state, driveyes, ROT0, "Namco", "Driver's Eyes (Japan)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS | MACHINE_NODEVICE_LAN)
GAME( 1991, solvalou, 0, namcos21, s21default, namcos21_state, solvalou, ROT0, "Namco", "Solvalou (Japan)", MACHINE_IMPERFECT_GRAPHICS )
GAME( 1991, starblad, 0, namcos21, s21default, namcos21_state, starblad, ROT0, "Namco", "Starblade (World)", MACHINE_IMPERFECT_GRAPHICS )
GAME( 1991, starbladj, starblad, namcos21, s21default, namcos21_state, starblad, ROT0, "Namco", "Starblade (Japan)", MACHINE_IMPERFECT_GRAPHICS )
-GAME( 1992, aircomb, 0, namcos21, aircomb, namcos21_state, aircomb, ROT0, "Namco", "Air Combat (US)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS )
+GAME( 1992, aircomb, 0, namcos21, aircomb, namcos21_state, aircomb, ROT0, "Namco", "Air Combat (US)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS ) // There's code for a SCI, is it even possible to play multiplayer?
GAME( 1992, aircombj, aircomb, namcos21, aircomb, namcos21_state, aircomb, ROT0, "Namco", "Air Combat (Japan)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS )
-GAME( 1993, cybsled, 0, namcos21, cybsled, namcos21_state, cybsled, ROT0, "Namco", "Cyber Sled (World)", MACHINE_IMPERFECT_GRAPHICS )
-GAME( 1993, cybsledj, cybsled, namcos21, cybsled, namcos21_state, cybsled, ROT0, "Namco", "Cyber Sled (Japan)", MACHINE_IMPERFECT_GRAPHICS )
+GAME( 1993, cybsled, 0, namcos21, cybsled, namcos21_state, cybsled, ROT0, "Namco", "Cyber Sled (World)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NODEVICE_LAN )
+GAME( 1993, cybsledj, cybsled, namcos21, cybsled, namcos21_state, cybsled, ROT0, "Namco", "Cyber Sled (Japan)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NODEVICE_LAN )
diff --git a/src/mame/drivers/neodriv.hxx b/src/mame/drivers/neodriv.hxx
index 24360853f0f..e635e7e8640 100644
--- a/src/mame/drivers/neodriv.hxx
+++ b/src/mame/drivers/neodriv.hxx
@@ -1657,7 +1657,27 @@ ROM_END
ROM_START( roboarmy )
ROM_REGION( 0x100000, "cslot1:maincpu", ROMREGION_BE|ROMREGION_16BIT )
ROM_LOAD16_WORD_SWAP( "032-p1.p1", 0x000000, 0x080000, CRC(cd11cbd4) SHA1(23163e3da2f07e830a7f4a02aea1cb01a54ccbf3) ) /* TC534200 */
- /* also found AES and MVS set with p1 on eprom on NEO-AEG PROG42G-1 and NEO-MVS PROG42G-COM; correct chip label unknown */
+
+ NEO_SFIX_128K( "032-s1.s1", CRC(ac0daa1b) SHA1(93bae4697dc403fce19422752a514326ccf66a91) ) /* TC531000 */
+
+ NEO_BIOS_AUDIO_128K( "032-m1.m1", CRC(35ec952d) SHA1(8aed30e26d7e2c70dbce5de752df416091066f7b) ) /* TC531001 */
+
+ ROM_REGION( 0x200000, "cslot1:ymsnd", 0 )
+ ROM_LOAD( "032-v1.v1", 0x000000, 0x100000, CRC(63791533) SHA1(4479e9308cdc906b9e03b985303f4ebedd00512f) ) /* TC538200 */
+ ROM_LOAD( "032-v2.v2", 0x100000, 0x100000, CRC(eb95de70) SHA1(b34885201116d2b3bbdee15ec7b5961cf5c069e1) ) /* TC538200 */
+
+ ROM_REGION( 0x300000, "cslot1:sprites", 0 )
+ ROM_LOAD16_BYTE( "032-c1.c1", 0x000000, 0x100000, CRC(97984c6c) SHA1(deea59c0892f05dc7db98cb57b3eb83688dc57f0) ) /* Plane 0,1 */ /* TC538200 */
+ ROM_LOAD16_BYTE( "032-c2.c2", 0x000001, 0x100000, CRC(65773122) SHA1(2c0162a8e971e5e57933e4ae16040bf824ffdefe) ) /* Plane 2,3 */ /* TC538200 */
+ ROM_LOAD16_BYTE( "032-c3.c3", 0x200000, 0x080000, CRC(40adfccd) SHA1(b11f866dd70ba0ed9123424508355cb948b19bdc) ) /* Plane 0,1 */ /* TC534200 */
+ ROM_LOAD16_BYTE( "032-c4.c4", 0x200001, 0x080000, CRC(462571de) SHA1(5c3d610d492f91564423873b3b434dcda700373f) ) /* Plane 2,3 */ /* TC534200 */
+ROM_END
+
+ROM_START( roboarma ) /* MVS AND AES VERSION*/
+ ROM_REGION( 0x100000, "cslot1:maincpu", ROMREGION_BE|ROMREGION_16BIT )
+ ROM_LOAD16_WORD_SWAP( "032-epr.p1", 0x000000, 0x080000, CRC(27c773cb) SHA1(597ca73f142b1129cc7780540bb9cfacd47bc6ce) ) /* D27C4000 */
+ /* Found on legitimate Robo Army MVS and AES Carts. Debug code button which check control a sound test has been patched out because in a multislot situation that code could have been enabled
+ that would stop roboarmy from working, sending it into an infinite loop ; correct chip label unknown */
NEO_SFIX_128K( "032-s1.s1", CRC(ac0daa1b) SHA1(93bae4697dc403fce19422752a514326ccf66a91) ) /* TC531000 */
@@ -2802,6 +2822,34 @@ ROM_START( samsho2k ) /* KOREAN VERSION */
ROM_LOAD16_BYTE( "063-c8.c8", 0xc00001, 0x200000, CRC(1ffc6dfa) SHA1(acea18aca76c072e0bac2a364fc96d49cfc86e77) ) /* Plane 2,3 */ /* TC5316200 */
ROM_END
+ROM_START( samsho2ka ) /* KOREAN VERSION */
+ // This has corrupt text if used with the Japan bios due to the replacement of the s1 rom to contain the new logo
+ ROM_REGION( 0x200000, "cslot1:maincpu", ROMREGION_BE|ROMREGION_16BIT )
+ ROM_LOAD16_WORD_SWAP( "063-p1-kan.p1", 0x100000, 0x100000, CRC(147cc6d7) SHA1(8e22305f41a0688786ff55437c25948e6c8fda58) )
+ ROM_CONTINUE( 0x000000, 0x100000 )
+ // Basically samsho2k without loading ep1 and ep2 over p1-kan ; The game has been confirmed to exist in this state
+
+ NEO_SFIX_128K( "063-s1-kan.s1", CRC(ff08f80b) SHA1(240c6a1c52edebb49cc99ea08484c6a2d61ebf84) )
+
+ NEO_BIOS_AUDIO_128K( "063-m1.m1", CRC(56675098) SHA1(90429fc40d056d480d0e2bbefbc691d9fa260fc4) ) /* TC531001 */
+
+ ROM_REGION( 0x700000, "cslot1:ymsnd", 0 )
+ ROM_LOAD( "063-v1.v1", 0x000000, 0x200000, CRC(37703f91) SHA1(a373ebef4c33ba1d8340e826981a58769aada238) ) /* TC5316200 */
+ ROM_LOAD( "063-v2.v2", 0x200000, 0x200000, CRC(0142bde8) SHA1(0be6c53acac44802bf70b6925452f70289a139d9) ) /* TC5316200 */
+ ROM_LOAD( "063-v3.v3", 0x400000, 0x200000, CRC(d07fa5ca) SHA1(1da7f081f8b8fc86a91feacf900f573218d82676) ) /* TC5316200 */
+ ROM_LOAD( "063-v4.v4", 0x600000, 0x100000, CRC(24aab4bb) SHA1(10ee4c5b3579865b93dcc1e4079963276aa700a6) ) /* TC538200 */
+
+ ROM_REGION( 0x1000000, "cslot1:sprites", 0 )
+ ROM_LOAD16_BYTE( "063-c1.c1", 0x000000, 0x200000, CRC(86cd307c) SHA1(0d04336f7c436d74638d8c1cd8651faf436a6bec) ) /* Plane 0,1 */ /* TC5316200 */
+ ROM_LOAD16_BYTE( "063-c2.c2", 0x000001, 0x200000, CRC(cdfcc4ca) SHA1(179dc81432424d68cefedd20cc1c4b2a95deb891) ) /* Plane 2,3 */ /* TC5316200 */
+ ROM_LOAD16_BYTE( "063-c3.c3", 0x400000, 0x200000, CRC(7a63ccc7) SHA1(49d97c543bc2860d493a353ab0d059088c6fbd21) ) /* Plane 0,1 */ /* TC5316200 */
+ ROM_LOAD16_BYTE( "063-c4.c4", 0x400001, 0x200000, CRC(751025ce) SHA1(e1bbaa7cd67fd04e4aab7f7ea77f63ae1cbc90d0) ) /* Plane 2,3 */ /* TC5316200 */
+ ROM_LOAD16_BYTE( "063-c5.c5", 0x800000, 0x200000, CRC(20d3a475) SHA1(28da44a136bd14c73c62c147c3f6e6bcfa1066de) ) /* Plane 0,1 */ /* TC5316200 */
+ ROM_LOAD16_BYTE( "063-c6.c6", 0x800001, 0x200000, CRC(ae4c0a88) SHA1(cc8a7d11daa3821f83a6fd0942534706f939e576) ) /* Plane 2,3 */ /* TC5316200 */
+ ROM_LOAD16_BYTE( "063-c7.c7", 0xc00000, 0x200000, CRC(2df3cbcf) SHA1(e54f9022359963711451c2025825b862d36c6975) ) /* Plane 0,1 */ /* TC5316200 */
+ ROM_LOAD16_BYTE( "063-c8.c8", 0xc00001, 0x200000, CRC(1ffc6dfa) SHA1(acea18aca76c072e0bac2a364fc96d49cfc86e77) ) /* Plane 2,3 */ /* TC5316200 */
+ROM_END
+
/****************************************
ID-0064
. ADM-007
@@ -8719,6 +8767,7 @@ GAME( 1991, socbrawl, neogeo, neobase, neogeo, neogeo_state, neogeo, R
GAME( 1991, socbrawlh, socbrawl, neobase, neogeo, neogeo_state, neogeo, ROT0, "SNK", "Soccer Brawl (NGH-031)", MACHINE_SUPPORTS_SAVE )
GAME( 1991, fatfury1, neogeo, neobase, neogeo, neogeo_state, neogeo, ROT0, "SNK", "Fatal Fury - King of Fighters / Garou Densetsu - Shukumei no Tatakai (NGM-033 ~ NGH-033)", MACHINE_SUPPORTS_SAVE )
GAME( 1991, roboarmy, neogeo, neobase, neogeo, neogeo_state, neogeo, ROT0, "SNK", "Robo Army", MACHINE_SUPPORTS_SAVE )
+GAME( 1991, roboarma, roboarmy, neobase, neogeo, neogeo_state, neogeo, ROT0, "SNK", "Robo Army (NGM-032 ~ NGH-032)", MACHINE_SUPPORTS_SAVE )
GAME( 1992, fbfrenzy, neogeo, neobase, neogeo, neogeo_state, neogeo, ROT0, "SNK", "Football Frenzy (NGM-034 ~ NGH-034)", MACHINE_SUPPORTS_SAVE )
GAME( 1992, kotm2, neogeo, neobase, neogeo, neogeo_state, neogeo, ROT0, "SNK", "King of the Monsters 2 - The Next Thing (NGM-039 ~ NGH-039)", MACHINE_SUPPORTS_SAVE )
GAME( 1992, kotm2a, kotm2, neobase, neogeo, neogeo_state, neogeo, ROT0, "SNK", "King of the Monsters 2 - The Next Thing (older)", MACHINE_SUPPORTS_SAVE )
@@ -8742,7 +8791,8 @@ GAME( 1993, fatfurspa, fatfursp, neobase, neogeo, neogeo_state, neogeo, R
GAME( 1995, savagere, neogeo, neobase, neogeo, neogeo_state, neogeo, ROT0, "SNK", "Savage Reign / Fu'un Mokushiroku - Kakutou Sousei", MACHINE_SUPPORTS_SAVE )
GAME( 1994, ssideki2, neogeo, neobase, neogeo, neogeo_state, neogeo, ROT0, "SNK", "Super Sidekicks 2 - The World Championship / Tokuten Ou 2 - Real Fight Football (NGM-061 ~ NGH-061)", MACHINE_SUPPORTS_SAVE )
GAME( 1994, samsho2, neogeo, neobase, neogeo, neogeo_state, neogeo, ROT0, "SNK", "Samurai Shodown II / Shin Samurai Spirits - Haohmaru Jigokuhen (NGM-063 ~ NGH-063)", MACHINE_SUPPORTS_SAVE )
-GAME( 1994, samsho2k, samsho2, neobase, neogeo, neogeo_state, neogeo, ROT0, "SNK", "Saulabi Spirits / Jin Saulabi Tu Hon (Korean release of Samurai Shodown II)", MACHINE_SUPPORTS_SAVE ) // official or hack?
+GAME( 1994, samsho2k, samsho2, neobase, neogeo, neogeo_state, neogeo, ROT0, "SNK", "Saulabi Spirits / Jin Saulabi Tu Hon (Korean release of Samurai Shodown II, set 1)", MACHINE_SUPPORTS_SAVE )
+GAME( 1994, samsho2ka, samsho2, neobase, neogeo, neogeo_state, neogeo, ROT0, "SNK", "Saulabi Spirits / Jin Saulabi Tu Hon (Korean release of Samurai Shodown II, set 2)", MACHINE_SUPPORTS_SAVE )
GAME( 1995, fatfury3, neogeo, neobase, neogeo, neogeo_state, neogeo, ROT0, "SNK", "Fatal Fury 3 - Road to the Final Victory / Garou Densetsu 3 - Haruka-naru Tatakai (NGM-069 ~ NGH-069)", MACHINE_SUPPORTS_SAVE )
GAME( 1995, ssideki3, neogeo, neobase, neogeo, neogeo_state, neogeo, ROT0, "SNK", "Super Sidekicks 3 - The Next Glory / Tokuten Ou 3 - Eikou e no Michi", MACHINE_SUPPORTS_SAVE )
GAME( 1995, kof95, neogeo, neobase, neogeo, neogeo_state, neogeo, ROT0, "SNK", "The King of Fighters '95 (NGM-084)", MACHINE_SUPPORTS_SAVE )
diff --git a/src/mame/drivers/novag6502.cpp b/src/mame/drivers/novag6502.cpp
index 4f8f5916447..a8558ddb5bc 100644
--- a/src/mame/drivers/novag6502.cpp
+++ b/src/mame/drivers/novag6502.cpp
@@ -62,9 +62,9 @@ public:
uint16_t read_inputs(int columns);
// display common
- int m_display_wait; // led/lamp off-delay in microseconds (default 33ms)
- int m_display_maxy; // display matrix number of rows
- int m_display_maxx; // display matrix number of columns (max 31 for now)
+ int m_display_wait; // led/lamp off-delay in microseconds (default 33ms)
+ int m_display_maxy; // display matrix number of rows
+ int m_display_maxx; // display matrix number of columns (max 31 for now)
uint32_t m_display_state[0x20]; // display matrix rows data (last bit is used for always-on)
uint16_t m_display_segmask[0x20]; // if not 0, display matrix row is a digit, mask indicates connected segments
diff --git a/src/mame/drivers/nycaptor.cpp b/src/mame/drivers/nycaptor.cpp
index eaff02007c6..e05984c5a80 100644
--- a/src/mame/drivers/nycaptor.cpp
+++ b/src/mame/drivers/nycaptor.cpp
@@ -311,7 +311,7 @@ static ADDRESS_MAP_START( nycaptor_master_map, AS_PROGRAM, 8, nycaptor_state )
AM_RANGE(0x0000, 0x7fff) AM_ROM
AM_RANGE(0x8000, 0xbfff) AM_ROMBANK("bank1")
AM_RANGE(0xc000, 0xc7ff) AM_RAM_WRITE(nycaptor_videoram_w) AM_SHARE("videoram")
- AM_RANGE(0xd000, 0xd000) AM_READWRITE(nycaptor_mcu_r, nycaptor_mcu_w)
+ AM_RANGE(0xd000, 0xd000) AM_DEVREADWRITE("bmcu", taito68705_mcu_device, mcu_r, mcu_w)
AM_RANGE(0xd001, 0xd001) AM_WRITE(sub_cpu_halt_w)
AM_RANGE(0xd002, 0xd002) AM_READWRITE(nycaptor_generic_control_r, nycaptor_generic_control_w) /* bit 3 - memory bank at 0x8000-0xbfff */
AM_RANGE(0xd400, 0xd400) AM_READWRITE(from_snd_r, sound_command_w)
@@ -368,18 +368,6 @@ static ADDRESS_MAP_START( nycaptor_sound_map, AS_PROGRAM, 8, nycaptor_state )
AM_RANGE(0xe000, 0xefff) AM_NOP
ADDRESS_MAP_END
-static ADDRESS_MAP_START( nycaptor_m68705_map, AS_PROGRAM, 8, nycaptor_state )
- ADDRESS_MAP_GLOBAL_MASK(0x7ff)
- AM_RANGE(0x0000, 0x0000) AM_READWRITE(nycaptor_68705_port_a_r, nycaptor_68705_port_a_w)
- AM_RANGE(0x0001, 0x0001) AM_READWRITE(nycaptor_68705_port_b_r, nycaptor_68705_port_b_w)
- AM_RANGE(0x0002, 0x0002) AM_READWRITE(nycaptor_68705_port_c_r, nycaptor_68705_port_c_w)
- AM_RANGE(0x0004, 0x0004) AM_WRITE(nycaptor_68705_ddr_a_w)
- AM_RANGE(0x0005, 0x0005) AM_WRITE(nycaptor_68705_ddr_b_w)
- AM_RANGE(0x0006, 0x0006) AM_WRITE(nycaptor_68705_ddr_c_w)
- AM_RANGE(0x0010, 0x007f) AM_RAM
- AM_RANGE(0x0080, 0x07ff) AM_ROM
-ADDRESS_MAP_END
-
/* Cycle Shooting */
@@ -755,19 +743,7 @@ void nycaptor_state::machine_start()
save_item(NAME(m_palette_bank));
save_item(NAME(m_gfxctrl));
- save_item(NAME(m_port_a_in));
- save_item(NAME(m_port_a_out));
- save_item(NAME(m_ddr_a));
- save_item(NAME(m_port_b_in));
- save_item(NAME(m_port_b_out));
- save_item(NAME(m_ddr_b));
- save_item(NAME(m_port_c_in));
- save_item(NAME(m_port_c_out));
- save_item(NAME(m_ddr_c));
- save_item(NAME(m_mcu_sent));
- save_item(NAME(m_main_sent));
- save_item(NAME(m_from_main));
- save_item(NAME(m_from_mcu));
+
}
void nycaptor_state::machine_reset()
@@ -783,19 +759,6 @@ void nycaptor_state::machine_reset()
m_palette_bank = 0;
m_gfxctrl = 0;
- m_port_a_in = 0;
- m_port_a_out = 0;
- m_ddr_a = 0;
- m_port_b_in = 0;
- m_port_b_out = 0;
- m_ddr_b = 0;
- m_port_c_in = 0;
- m_port_c_out = 0;
- m_ddr_c = 0;
- m_mcu_sent = 0;
- m_main_sent = 0;
- m_from_main = 0;
- m_from_mcu = 0;
memset(m_vol_ctrl, 0, sizeof(m_vol_ctrl));
}
@@ -815,8 +778,7 @@ static MACHINE_CONFIG_START( nycaptor, nycaptor_state )
MCFG_CPU_PROGRAM_MAP(nycaptor_sound_map)
MCFG_CPU_PERIODIC_INT_DRIVER(nycaptor_state, irq0_line_hold, 2*60) /* IRQ generated by ??? */
- MCFG_CPU_ADD("mcu", M68705,2000000)
- MCFG_CPU_PROGRAM_MAP(nycaptor_m68705_map)
+ MCFG_DEVICE_ADD("bmcu", TAITO68705_MCU,2000000)
MCFG_QUANTUM_TIME(attotime::from_hz(6000)) /* 100 CPU slices per frame - an high value to ensure proper synchronization of the CPUs */
@@ -882,8 +844,7 @@ static MACHINE_CONFIG_START( cyclshtg, nycaptor_state )
MCFG_CPU_PERIODIC_INT_DRIVER(nycaptor_state, irq0_line_hold, 2*60)
#ifdef USE_MCU
- MCFG_CPU_ADD("mcu", M68705,2000000)
- MCFG_CPU_PROGRAM_MAP(nycaptor_m68705_map)
+ MCFG_DEVICE_ADD("bmcu", TAITO68705_MCU,2000000)
#endif
MCFG_QUANTUM_TIME(attotime::from_hz(60))
@@ -1018,7 +979,7 @@ ROM_START( nycaptor )
ROM_LOAD( "a50_15", 0x0000, 0x4000, CRC(f8a604e5) SHA1(8fae920fd09584b5e5ccd0db8b8934b393a23d50) )
ROM_LOAD( "a50_16", 0x4000, 0x4000, CRC(fc24e11d) SHA1(ce1a1d7b809fa0f5f5e7a462047374b1b3f621c6) )
- ROM_REGION( 0x0800, "mcu", 0 )
+ ROM_REGION( 0x0800, "bmcu:mcu", 0 )
ROM_LOAD( "a50_17", 0x0000, 0x0800, CRC(69fe08dc) SHA1(9bdac3e835f63bbb8806892169d89f43d447df21) )
ROM_REGION( 0x20000, "gfx1", ROMREGION_INVERT )
@@ -1048,7 +1009,7 @@ ROM_START( cyclshtg )
ROM_LOAD( "a80_16.i26", 0x0000, 0x4000, CRC(ce171a48) SHA1(e5ae9bb22f58c8857737bc6f5317866819a4e4d1) )
ROM_LOAD( "a80_17.i25", 0x4000, 0x4000, CRC(a90b7bbc) SHA1(bd5c96861a59a1f84bb5032775b1c70efdb7066f) )
- ROM_REGION( 0x0800, "cpu3", 0 )
+ ROM_REGION( 0x0800, "bmcu:mcu", 0 )
ROM_LOAD( "a80_18", 0x0000, 0x0800, NO_DUMP ) /* Missing */
ROM_REGION( 0x20000, "gfx1", ROMREGION_INVERT )
diff --git a/src/mame/drivers/osbexec.cpp b/src/mame/drivers/osbexec.cpp
index f2e4b8b3878..28d02a1b624 100644
--- a/src/mame/drivers/osbexec.cpp
+++ b/src/mame/drivers/osbexec.cpp
@@ -15,6 +15,7 @@
#include "machine/z80dart.h"
#include "machine/pit8253.h"
#include "machine/ram.h"
+#include "machine/input_merger.h"
#include "softlist.h"
#define MAIN_CLOCK 23961600
@@ -64,11 +65,9 @@ public:
/* PIA 0 (UD12) */
uint8_t m_pia0_porta;
uint8_t m_pia0_portb;
- int m_pia0_irq_state;
int m_pia0_cb2; /* 60/50 */
/* PIA 1 (UD8) */
- int m_pia1_irq_state;
/* Vblank counter ("RTC") */
uint8_t m_rtc;
@@ -99,13 +98,6 @@ public:
m_ram_c000 = m_vram_region->base();
}
- void update_irq_state()
- {
- if ( m_pia0_irq_state || m_pia1_irq_state )
- m_maincpu->set_input_line(0, ASSERT_LINE );
- else
- m_maincpu->set_input_line(0, CLEAR_LINE );
- }
DECLARE_WRITE8_MEMBER(osbexec_0000_w);
DECLARE_READ8_MEMBER(osbexec_c000_r);
DECLARE_WRITE8_MEMBER(osbexec_c000_w);
@@ -408,20 +400,6 @@ WRITE_LINE_MEMBER(osbexec_state::osbexec_pia0_cb2_w)
}
-WRITE_LINE_MEMBER(osbexec_state::osbexec_pia0_irq)
-{
- m_pia0_irq_state = state;
- update_irq_state();
-}
-
-
-WRITE_LINE_MEMBER(osbexec_state::osbexec_pia1_irq)
-{
- m_pia1_irq_state = state;
- update_irq_state();
-}
-
-
/*
* The Osborne Executive supports the following disc formats: (TODO: Verify)
* - Osborne single density: 40 tracks, 10 sectors per track, 256-byte sectors (100 KByte)
@@ -514,6 +492,9 @@ void osbexec_state::machine_reset()
m_video_timer->adjust( machine().first_screen()->time_until_pos( 0, 0 ) );
m_rtc = 0;
+
+ // D0 cleared on interrupt acknowledge cycle by a few TTL gates
+ m_maincpu->set_input_line_vector(0, 0xfe);
}
@@ -549,12 +530,15 @@ static MACHINE_CONFIG_START( osbexec, osbexec_state )
MCFG_PIA_WRITEPB_HANDLER(WRITE8(osbexec_state, osbexec_pia0_b_w))
MCFG_PIA_CA2_HANDLER(WRITELINE(osbexec_state, osbexec_pia0_ca2_w))
MCFG_PIA_CB2_HANDLER(WRITELINE(osbexec_state, osbexec_pia0_cb2_w))
- MCFG_PIA_IRQA_HANDLER(WRITELINE(osbexec_state, osbexec_pia0_irq))
- MCFG_PIA_IRQB_HANDLER(WRITELINE(osbexec_state, osbexec_pia0_irq))
+ MCFG_PIA_IRQA_HANDLER(DEVWRITELINE("mainirq", input_merger_device, in0_w))
+ MCFG_PIA_IRQB_HANDLER(DEVWRITELINE("mainirq", input_merger_device, in0_w))
MCFG_DEVICE_ADD("pia_1", PIA6821, 0)
- MCFG_PIA_IRQA_HANDLER(WRITELINE(osbexec_state, osbexec_pia1_irq))
- MCFG_PIA_IRQB_HANDLER(WRITELINE(osbexec_state, osbexec_pia1_irq))
+ MCFG_PIA_IRQA_HANDLER(DEVWRITELINE("mainirq", input_merger_device, in1_w))
+ MCFG_PIA_IRQB_HANDLER(DEVWRITELINE("mainirq", input_merger_device, in1_w))
+
+ MCFG_INPUT_MERGER_ACTIVE_HIGH("mainirq")
+ MCFG_INPUT_MERGER_OUTPUT_HANDLER(INPUTLINE("maincpu", 0))
MCFG_Z80SIO2_ADD("sio", MAIN_CLOCK/6, 0, 0, 0, 0)
diff --git a/src/mame/drivers/pc.cpp b/src/mame/drivers/pc.cpp
index b0e4fcfa2c9..c89282b37da 100644
--- a/src/mame/drivers/pc.cpp
+++ b/src/mame/drivers/pc.cpp
@@ -19,12 +19,254 @@ Driver file for IBM PC, IBM PC XT, and related machines.
F0000-FDFFF NOP or ROM Basic + other Extensions
FE000-FFFFF ROM
+Data General One / DG-1
+=======================
+Links: http://www.1000bit.it/ad/bro/datageneral/DG-ONE-PersonalSystem.pdf , http://www.1000bit.it/ad/bro/datageneral/DG-ONE-Interduction-PR.pdf , http://www.oldcomputers.net/data-general-one.html , http://forums.bannister.org/ubbthreads.php?ubb=showflat&Number=30897&page=all
+Info: According to the discussion in the thread, the ROM we have is from the original version. Specs for later permutations can be found on oldcomputers.net
+Form Factor: Laptop
+CPU: 80C88 @ 4 MHz
+RAM: 128K - 256K - 384K - 512K internally
+Bus: no internal slots
+Video: On board, Text mode 80x25 with 8x8 or 8x10 characters, CGA
+Display: non-backlit LCD 640x256 pixels
+Mass storage: 1/2x Floppy 3.5" 720K
+On board Ports: Floppy, RTC, 1x RS232C + 1x RS232C/RS422 via 8251, speaker
+Options: ext. 5.25" Floppy, int. Bell 103A 300 Baud Modem, 8087 FPU
+Expansion: Expansion box, with 5 ISA slots and space for a 5.25" drive and a harddisk; specifically mentioned are the 5.25" drive, color graphics and memory expansion via ISA cards
+
+
+Bondwell BW230 (Pro28 series)
+=============
+Links: http://gallery.fdd5-25.net/details.php?image_id=3463&sessionid=1eaeb42abdf2758a020b16204a2a8e5a ; http://www.zonadepruebas.com/viewtopic.php?t=3696 ; ftp://ftp.whtech.com/emulators/mess/old/Complete%20MESS%20Geneve%20emulation/mess/sysinfo/bondwell.htm
+Info: Info is hard to come by. A BW230 is nowhere to be found, the links about the Pro28 series suggest an XT compatible built around a passive backplane and a slot CPU. This is confirmed by the old MESS info.
+Form Factor: Desktop
+CPU: 8088 @ 4.77 MHz (MESS sysinfo: 3.75)/ 8 MHz
+RAM: 512K / 640K
+Bus: at least 2x ISA: 1) CPU, RAM, Floppy controller
+ 2) Graphics, Game, Parallel
+Video: Hercules/CGA
+Mass storage: 1x 5.25" 360K and 20/30MB Harddisk.
+
+
+Commodore PC-1
+=============
+Links: http://www.amiga-stuff.com/hardware/pc-i.html , http://www.zimmers.net/cbmpics/cpci.html
+Form Factor: Desktop
+CPU: 8088 @ 4.77 MHz
+RAM: 512K / 640K
+Bus: Proprietary expansion slot, carrying almost all ISA signals
+Video: On board, MDA/Hercules/CGA
+Mass storage: 1x 5.25" 360K
+On board ports: Floppy, floppy expansion (for Amiga A1010/1011 (720 KB, 3.5") or A1020 (360 KB, 5.25" drives), speaker (but no speaker fitted), mouse,
+Options: 8087 FPU
+Expansion: Expansion box: 2x ISA
+
+
+Commodore PC-10 III
+=============
+Links: http://dostalgie.de/downloads/pc10III-20III/PC10III_OM_COMMODORE_EN_DE.pdf ; ftp://ftp.zimmers.net/pub/cbm-pc/documents/PC-8088-Information.txt
+Info: PC10-III and PC20-III are the same machines - PC10 has two floppies, PC20 one floppy and one harddisk
+Form Factor: Desktop
+CPU: 8088 @ 4.77 MHz / 7.16 MHz / 9.54 MHz
+RAM: 640K
+Bus: 3x ISA
+Video: On board: MDA/CGA/Hercules/Plantronics
+Mass storage: 1x Floppy 5.25" 360K and (PC10) another 360K or (PC20) 3.5" harddisk
+On board ports: Floppy, XT-IDE Harddisk, Mouse, serial, parallel, RTC, Speaker
+Options: 8087 FPU
+
+
+Zenith SuperSport
+=======================
+Links: http://www.focushacks.com/zenith/myzenith.html , http://retro-computing.blogspot.de/2006/08/zds-supersport-laptop.html , http://www.minuszerodegrees.net/manuals/Zenith%20Data%20Systems/ZDS%20SupersPort%20-%20Service%20Manual.pdf
+ http://www.minuszerodegrees.net/manuals/Zenith%20Data%20Systems/ZDS%20SupersPort%20-%20User%20and%20Technical%20Manual.pdf
+Info: ZWL-184 to distinguish it from the later 80286 based models
+Form Factor: Laptop
+CPU: 80C88 @ 4.77 MHz or 8 MHz
+RAM: 640 KB
+Bus: no internal slots
+Video: CGA
+Display: The second link has a picture of a working SuperSport. This shows the LCD display with a green background and blue text/graphics.
+Mass storage: 1x 3.5" 720K floppy and 1x720K floppy or 20MB harddisk
+On board ports: serial, parallel, ext. keyboard, ext. CGA video, ext. floppy
+Options: 2400 Baud Modem, 8087 FPU
+
+
+Siemens Sicomp PC16-05
+=======================
+Links: http://www.computerwoche.de/a/siemens-erweitert-pc-16-programm,1169752 , http://www.phantom.sannata.ru/museum/siemens_pc_16_05.shtml
+Info: Multitech PC/700 mainboard
+Form Factor: Desktop
+CPU: 8088 @ 4.77MHz / 8 MHz
+RAM: 640KB
+Bus: 6x ISA: 1) MDA/Hercules/CGA and parallel port
+ 2) Floppy, RTC and serial port
+ 3) (optional) MFM harddisk controller
+Video: MDA/Hercules, exchangable via ISA-slot
+Mass storage: 1x 5.25" 360K floppy and 1x 5.25" 360K floppy or MFM hard drive (10MB or 20MB)
+On board ports: parallel, serial, beeper
+Options: 8087 FPU
+
+
+NCR PC4i
+========
+Links: http://www.minuszerodegrees.net/manuals/NCR/NCR%20PC4i%20-%20Technical%20Reference%20Manual%20-%20January%201986.pdf
+Info: The earlier PC4 is not quite IBM compatible, the "i" in PC4i indicates full IBM compatibility.
+ The NCR Graphics card supports a special 640x400 video mode
+Form Factor: All-in-one desktop
+CPU: 8088 @ 4.77 MHz
+RAM: 256K, expandable to 640K
+Bus: 7x ISA: 1) (optional) RAM expansion board
+ 2) empty
+ 3) 32K Video/Graphics board (64K option)
+ 4) (optional) Alpha board
+ 5) empty
+ 6) (optional) MFM harddisk controller
+ 7) empty
+Video: K510: 4KB Alpha for internal monitor; K511: 32KB Graphics for internal monitor; K512: 32KB upgrade for K512; K140: 16KB Graphics for external monitor; K141: 4KB Alpha for external monitor
+Display: Mono or color CRT 640x400 pixel
+Mass storage: 1x 5.25" 360K floppy and 1x 5.25" 360K floppy or 10 MB harddisk
+On board ports: parallel, serial, speaker, floppy
+Options: 8087 FPU, K101 memory upgrade in 64K steps, 1.2MB floppy and controller board
+
+
+Olivetti M15
+============
+Links: http://www.1000bit.it/ad/bro/olivetti/olivettiM15.pdf , http://electrickery.xs4all.nl/comp/m15/ , http://electrickery.xs4all.nl/comp/m15/doc/M15_InstallationAndOperationsGuide.pdf
+ http://www.museotecnologicamente.it/olivetti-m-15-1987/ , http://www.museotecnologicamente.it/wp-content/uploads/M15_Depliant_inglese.pdf
+Info: The info brochure has a picture of a working M15. This shows the LCD display with a green background and blue text/graphics.
+Form Factor: Laptop
+CPU: 80C88 @ 4.77 MHz
+RAM: 256K / 512K
+Bus: no internal slots
+Video: 80x25 text mode, CGA
+Display: LCD
+Mass storage: 2x 3.5" 720K drives
+Ports: serial, parallel, ext. floppy, RTC
+Expansion: External 5.25" 360K floppy drive
+
+
IBM5550
=======
Information can be found at http://homepage3.nifty.com/ibm5550/index-e.html
It's a heavily modified IBM PC-XT machine, with a completely different
video HW too.
+
+Sharp PC-7000
+=============
+Links: http://oldcomputers.net/sharp-pc7000.html , http://curtamania.com/curta/database/brand/sharp/Sharp%20PC-7000/index.html , http://pcmuseum.de/pc7000.html
+Form Factor: Luggable
+CPU: 8086 @ 4.77 MHz or 7.37 MHz
+RAM: 320K / 704K
+Bus: no internal slots
+Video: 80x24 text, 600x200 pixel graphics
+Display: electroluminescent mono backlit (blue) LCD
+Mass storage: 2x 5.25" 360K floppies
+On board ports: serial, parallel
+Options: Modem, color video output
+
+
+Sanyo MBC-16
+============
+Links:
+Info: In the MBC-16 I had, the graphics card had a Sanyo sticker on it, so I assume that was the original graphics card for the machine.
+Form Factor: Desktop
+CPU: 8088 @ 8MHz
+RAM: 640KB
+Bus: 3x ISA: 1) ATI Graphics Solution SR https://sites.google.com/site/atiwonderseriesdatabase/
+Video: MDA/CGA/Plantronics
+Mass storage: 1 or 2 5.25" 360K floppies, MFM harddisk on hardcard or via seperate controller
+On board ports: serial, parallel, floppy
+
+
+Atari PC1
+=========
+Links: http://www.ataripc.net/pc1-8088/ ; http://krap.pl/mirrorz/atari/www.atari-computermuseum.de/pc.htm ; http://www.atari-computermuseum.de/pc1.htm
+Form Factor: Desktop
+CPU: 8088 @ 4.77 MHz / 8 MHz
+RAM: 512K / 640KB
+Bus: ISA signals available on board, no slot
+Video: Hercules/CGA/EGA
+Mass storage: 1 5.25" 360K floppy
+On board ports: floppy, graphics, parallel, serial, mouse, external floppy
+Options: 8087 FPU
+Expansion: Up to two external floppy drives: PCF554, SF314 or SF354
+
+
+Atari PC2
+Links: http://www.binarydinosaurs.co.uk/Museum/atari/pc2.php ; http://www.ataripc.net/pc2-8088/ ; http://www.ataripc.net/components/
+Info: The Atari PC2 mainboard has only one ISA slot, but is expanded via a four slot riser card. BIOS is identical to later PC1 and PC3
+CPU: 8088 @ 4.77 MHz / 8 MHz
+RAM: 512K / 640KB
+Bus: 4x ISA
+Video: Hercules/CGA/EGA
+Mass storage: 1 5.25" 360K floppy and 1 5.25" 360K floppy or 20MB hard drive
+On board ports: floppy, graphics, parallel, serial, mouse
+Expansion: 8087 FPU
+
+Atari PC3
+=========
+Links: http://www.atari-computermuseum.de/pc1.htm , http://trelohra.blogspot.de/2015/06/atari-pc3.html , http://www.ataripc.net/pc3-8088/
+Form Factor: Desktop
+CPU: 8088 @ 4.77 MHz or 8 MHz
+RAM: 640K
+Bus: 5x ISA: 1) Adaptec ACB-2072 RLL Controller Card
+Video: On-board MDA/CGA/Hercules/EGA
+Mass storage: 1x 5.25" 360K floppy + 30MB RLL harddisk
+On board ports: floppy, parallel, serial, mouse, speaker
+Options: 8087 FPU
+
+
+Eagle 1600
+==========
+Links: https://archive.org/details/bitsavers_eagleCompu00Brochure_9975235 , http://www.vcfed.org/forum/showthread.php?49510-Eagle-Computer-model-list , http://bitsavers.trailing-edge.com/pdf/eagleComputer/1600/1600_Series_Training_Notes.pdf
+Info: Eagle 1620 - 8086/128K, 2 Quad density floppy drives, 4 Expansion slots available, ~1983, Eagle 1630 - 8086/128K, 1 Quad density floppy drive, 10MB HD, 3 Expansion Slots available (Same as 1620 with hard drive), ~1983Eagle 1640 - 8086/512K, 1 Quad density floppy drive, 32MB HD, 3 Expansion Slots available, ~1984
+ The native floppy format is 780K, 2 sides, 80 tracks/side, 1024 bytes/sector, 5 sectors per track. Standard 360K disks can be read
+ Holding "T" and resetting starts a system diagnostics test
+Form Factor: Desktop
+CPU: 8086 @ 8 MHz
+RAM: 128K / 512K
+Bus: 8xISA: 1) SASI board, connects to a XEBEC Sl410 SASI => MFM bridge board
+ 2) Floppy controller
+ 3) empty
+ 4) Video/graphics controller board
+ 5) empty
+ 6) empty
+ 7) Serial board: 2x serial, one sync/async, one async only
+ 8) Parallel board
+Video: 80x25 text mode, 720x352 pixel graphics mode
+Mass storage: 1x 5.25" QD 780K floppy and 1x 5.25" QD 820K floppy or 10/30MB MFM harddisk
+Options: 8087 FPU, EagleNet File server, EightPort serial card, High Resolution color board and video, Video Cassette Adapter board for 80MB backup on video cassette
+
+VTech Laser Turbo XT
+=======================
+Links: http://minuszerodegrees.net/manuals.htm#VTech , http://minuszerodegrees.net/manuals/VTech/VTech%20-%20Laser%20Turbo%20XT%20-%20Brochure.pdf
+Form Factor: Desktop
+CPU: 8088 @ 4.77 MHz or 10 MHz
+RAM: 512K / 640K, additionally 512K or 1M EMS on board
+Bus: 8xISA: 1) Monochrome graphics/color graphics card
+ 2) Multi I/O Card (Floppy, 2x serial, parallel, game, RTC)
+ 3) (optional) hard disk controller
+Video: MDA/CGA/Hercules
+Mass storage: 2x 5.25" 360K floppies and 1 or 2 harddisks (20MB / 30MB / 40MB)
+On board ports: speaker
+Options: 8087 FPU
+
+VTech Laser XT/3
+=======================
+Links: http://minuszerodegrees.net/manuals.htm#VTech , http://th99.classic-computing.de/src/v/U-Z/52547.htm
+Form Factor: Desktop
+CPU: 8088 @ 4.77MHz or 10 MHz
+RAM: 512K / 640K, additionally 512K or 1M EMS on board
+Bus: 8x ISA: 1) Monochrome graphics/color graphics card http://th99.classic-computing.de/src/v/U-Z/52547.htm , alternatively an EGA card
+ 2) Multi I/O Card (Floppy, 2x serial, 1x parallel, game, RTC) http://th99.classic-computing.de/src/i/U-Z/52519.htm
+ 3) (optional) hard disk controller
+Video: MDA/Hercules/CGA
+Mass storage: 2x 5.25" 360K or 1x 5.25" 360K and 1x 3.5" 720K, additional harddisk optional
+On board ports: speaker
+Options: 8087 FPU
+
***************************************************************************/
@@ -141,22 +383,11 @@ static INPUT_PORTS_START( pccga )
PORT_BIT( 0x01, 0x01, IPT_UNUSED )
INPUT_PORTS_END
-static INPUT_PORTS_START( bondwell )
- PORT_INCLUDE(pccga)
-
- PORT_MODIFY("DSW2") /* IN3 */
- PORT_DIPNAME( 0x02, 0x02, "Turbo Switch" ) PORT_CHANGED_MEMBER(DEVICE_SELF, pc_state, pc_turbo_callback, 0)
- PORT_DIPSETTING( 0x00, "Off (4.77 MHz)" )
- PORT_DIPSETTING( 0x02, "On (12 MHz)" )
-INPUT_PORTS_END
static DEVICE_INPUT_DEFAULTS_START( pccga )
DEVICE_INPUT_DEFAULTS("DSW0", 0x30, 0x20)
DEVICE_INPUT_DEFAULTS_END
-static DEVICE_INPUT_DEFAULTS_START( siemens )
- DEVICE_INPUT_DEFAULTS("DSW0", 0x30, 0x30)
-DEVICE_INPUT_DEFAULTS_END
#define MCFG_CPU_PC(mem, port, type, clock) \
MCFG_CPU_ADD("maincpu", type, clock) \
@@ -164,6 +395,7 @@ DEVICE_INPUT_DEFAULTS_END
MCFG_CPU_IO_MAP(port##_io) \
MCFG_CPU_IRQ_ACKNOWLEDGE_DEVICE("mb:pic8259", pic8259_device, inta_cb)
+
static MACHINE_CONFIG_START( pccga, pc_state )
/* basic machine hardware */
MCFG_CPU_PC(pc8, pc8, I8088, 4772720) /* 4,77 MHz */
@@ -175,6 +407,7 @@ static MACHINE_CONFIG_START( pccga, pc_state )
MCFG_ISA8_SLOT_ADD("mb:isa", "isa2", pc_isa8_cards, "fdc_xt", false)
MCFG_ISA8_SLOT_ADD("mb:isa", "isa3", pc_isa8_cards, "lpt", false)
MCFG_ISA8_SLOT_ADD("mb:isa", "isa4", pc_isa8_cards, "com", false)
+ MCFG_ISA8_SLOT_ADD("mb:isa", "isa5", pc_isa8_cards, nullptr, false)
/* keyboard */
MCFG_PC_KBDC_SLOT_ADD("mb:pc_kbdc", "kbd", pc_xt_keyboards, STR_KBD_IBM_PC_XT_83)
@@ -187,6 +420,46 @@ static MACHINE_CONFIG_START( pccga, pc_state )
MCFG_SOFTWARE_LIST_ADD("disk_list","ibm5150")
MACHINE_CONFIG_END
+
+static MACHINE_CONFIG_FRAGMENT( cfg_dual_720K )
+ MCFG_DEVICE_MODIFY("fdc:0")
+ MCFG_SLOT_DEFAULT_OPTION("35dd")
+ MCFG_DEVICE_MODIFY("fdc:1")
+ MCFG_SLOT_DEFAULT_OPTION("35dd")
+MACHINE_CONFIG_END
+
+static MACHINE_CONFIG_FRAGMENT( cfg_single_360K )
+ MCFG_DEVICE_MODIFY("fdc:0")
+ MCFG_SLOT_DEFAULT_OPTION("525dd")
+ MCFG_SLOT_FIXED(true)
+ MCFG_DEVICE_REMOVE("fdc:1")
+MACHINE_CONFIG_END
+
+
+//Data General One
+static MACHINE_CONFIG_DERIVED( dgone, pccga )
+ MCFG_DEVICE_MODIFY("isa2")
+ MCFG_SLOT_OPTION_MACHINE_CONFIG("fdc_xt", cfg_dual_720K)
+MACHINE_CONFIG_END
+
+
+// Bondwell BW230
+static INPUT_PORTS_START( bondwell )
+ PORT_INCLUDE(pccga)
+
+ PORT_MODIFY("DSW2") /* IN3 */
+ PORT_DIPNAME( 0x02, 0x02, "Turbo Switch" ) PORT_CHANGED_MEMBER(DEVICE_SELF, pc_state, pc_turbo_callback, 0)
+ PORT_DIPSETTING( 0x00, "Off (4.77 MHz)" )
+ PORT_DIPSETTING( 0x02, "On (12 MHz)" )
+INPUT_PORTS_END
+
+static MACHINE_CONFIG_DERIVED(bondwell, pccga)
+ MCFG_DEVICE_REMOVE("maincpu")
+ MCFG_CPU_PC(pc8, pc8, I8088, 4772720) // turbo?
+MACHINE_CONFIG_END
+
+
+// Schetmash Iskra-3104
static DEVICE_INPUT_DEFAULTS_START( iskr3104 )
DEVICE_INPUT_DEFAULTS("DSW0", 0x30, 0x00)
DEVICE_INPUT_DEFAULTS_END
@@ -214,6 +487,7 @@ static MACHINE_CONFIG_START( iskr3104, pc_state )
MACHINE_CONFIG_END
+//Poisk-2
static MACHINE_CONFIG_START( poisk2, pc_state )
/* basic machine hardware */
MCFG_CPU_PC(pc16, pc16, I8086, 4772720)
@@ -234,6 +508,15 @@ static MACHINE_CONFIG_START( poisk2, pc_state )
MCFG_RAM_EXTRA_OPTIONS("64K, 128K, 256K, 512K")
MACHINE_CONFIG_END
+
+//MK-88
+static MACHINE_CONFIG_DERIVED(mk88, poisk2)
+ MCFG_DEVICE_MODIFY("isa1")
+ MCFG_SLOT_DEFAULT_OPTION("cga_ec1841")
+MACHINE_CONFIG_END
+
+
+// Zenith SuperSport
static MACHINE_CONFIG_START( zenith, pc_state )
/* basic machine hardware */
MCFG_CPU_PC(zenith, pc8, I8088, XTAL_14_31818MHz/3) /* 4,77 MHz */
@@ -243,6 +526,7 @@ static MACHINE_CONFIG_START( zenith, pc_state )
MCFG_ISA8_SLOT_ADD("mb:isa", "isa1", pc_isa8_cards, "cga", false)
MCFG_ISA8_SLOT_ADD("mb:isa", "isa2", pc_isa8_cards, "fdc_xt", false)
+ MCFG_SLOT_OPTION_MACHINE_CONFIG("fdc_xt", cfg_dual_720K)
MCFG_ISA8_SLOT_ADD("mb:isa", "isa3", pc_isa8_cards, "lpt", false)
MCFG_ISA8_SLOT_ADD("mb:isa", "isa4", pc_isa8_cards, "com", false)
@@ -258,6 +542,22 @@ static MACHINE_CONFIG_START( zenith, pc_state )
MACHINE_CONFIG_END
+//NCR PC4i
+static MACHINE_CONFIG_DERIVED ( ncrpc4i, pccga )
+ //MCFG_DEVICE_MODIFY("mb:isa")
+ MCFG_ISA8_SLOT_ADD("mb:isa", "isa6", pc_isa8_cards, nullptr, false)
+ MCFG_ISA8_SLOT_ADD("mb:isa", "isa7", pc_isa8_cards, nullptr, false)
+
+ MCFG_DEVICE_MODIFY(RAM_TAG)
+ MCFG_RAM_DEFAULT_SIZE("640K")
+ MCFG_RAM_EXTRA_OPTIONS("64K, 128K, 256K, 512K")
+MACHINE_CONFIG_END
+
+
+// Siemens Sicomp PC16-05
+static DEVICE_INPUT_DEFAULTS_START( siemens )
+ DEVICE_INPUT_DEFAULTS("DSW0", 0x30, 0x30)
+DEVICE_INPUT_DEFAULTS_END
static MACHINE_CONFIG_START( siemens, pc_state )
/* basic machine hardware */
@@ -282,6 +582,8 @@ static MACHINE_CONFIG_START( siemens, pc_state )
MACHINE_CONFIG_END
+
+// IBM 5550
static MACHINE_CONFIG_START( ibm5550, pc_state )
/* basic machine hardware */
MCFG_CPU_PC(pc16, ibm5550, I8086, 8000000)
@@ -302,21 +604,8 @@ static MACHINE_CONFIG_START( ibm5550, pc_state )
MCFG_RAM_EXTRA_OPTIONS("64K, 128K, 256K, 512K")
MACHINE_CONFIG_END
-static MACHINE_CONFIG_DERIVED(bondwell, pccga)
- MCFG_DEVICE_REMOVE("maincpu")
- MCFG_CPU_PC(pc8, pc8, I8088, 4772720) // turbo?
-MACHINE_CONFIG_END
-
-static MACHINE_CONFIG_DERIVED(mk88, poisk2)
- MCFG_DEVICE_MODIFY("isa1")
- MCFG_SLOT_DEFAULT_OPTION("cga_ec1841")
-MACHINE_CONFIG_END
-
-static MACHINE_CONFIG_DERIVED(eagle1600, pccga)
- MCFG_DEVICE_REMOVE("maincpu")
- MCFG_CPU_PC(pc16, pc16, I8086, 8000000)
-MACHINE_CONFIG_END
+// Olivetti M15
static DEVICE_INPUT_DEFAULTS_START( m15 )
DEVICE_INPUT_DEFAULTS("DSW0", 0x30, 0x20) // TODO: document correct dip settings
DEVICE_INPUT_DEFAULTS("DSW0", 0x01, 0x00)
@@ -325,12 +614,32 @@ DEVICE_INPUT_DEFAULTS_END
static MACHINE_CONFIG_DERIVED(m15, pccga)
MCFG_DEVICE_MODIFY("mb")
MCFG_DEVICE_INPUT_DEFAULTS(m15)
+ MCFG_DEVICE_MODIFY("isa2")
+ MCFG_SLOT_OPTION_MACHINE_CONFIG("fdc_xt", cfg_dual_720K)
MCFG_DEVICE_MODIFY(RAM_TAG)
MCFG_RAM_DEFAULT_SIZE("448K")
MCFG_RAM_EXTRA_OPTIONS("16K, 160K, 304K")
MACHINE_CONFIG_END
-static MACHINE_CONFIG_START( laser_turbo_xt, pc_state )
+
+// Atari PC1
+static MACHINE_CONFIG_DERIVED(ataripc1, pccga)
+ MCFG_DEVICE_MODIFY("isa1")
+ MCFG_SLOT_DEFAULT_OPTION("ega")
+ MCFG_DEVICE_MODIFY("isa2")
+ MCFG_SLOT_OPTION_MACHINE_CONFIG("fdc_xt", cfg_single_360K)
+MACHINE_CONFIG_END
+
+
+//Eagle 1600
+static MACHINE_CONFIG_DERIVED(eagle1600, pccga)
+ MCFG_DEVICE_REMOVE("maincpu")
+ MCFG_CPU_PC(pc16, pc16, I8086, 8000000)
+MACHINE_CONFIG_END
+
+
+//Laser XT/3
+static MACHINE_CONFIG_START( laser_xt3, pc_state )
MCFG_CPU_PC(pc8, pc8, I8088, XTAL_14_31818MHz/3) /* 4,77 MHz */
MCFG_IBM5160_MOTHERBOARD_ADD("mb","maincpu")
@@ -338,7 +647,7 @@ static MACHINE_CONFIG_START( laser_turbo_xt, pc_state )
MCFG_ISA8_SLOT_ADD("mb:isa", "isa1", pc_isa8_cards, "cga", false)
MCFG_ISA8_SLOT_ADD("mb:isa", "isa2", pc_isa8_cards, "com", false) // Multi I/O card (includes FDC)
- MCFG_ISA8_SLOT_ADD("mb:isa", "isa3", pc_isa8_cards, "fdc_xt", false)
+ MCFG_ISA8_SLOT_ADD("mb:isa", "isa3", pc_isa8_cards, "fdc_xt", false) // floppy drive A is 5.25" 360K and B is 3.5" 720K
MCFG_ISA8_SLOT_ADD("mb:isa", "isa4", pc_isa8_cards, nullptr, false)
MCFG_ISA8_SLOT_ADD("mb:isa", "isa5", pc_isa8_cards, nullptr, false)
MCFG_ISA8_SLOT_ADD("mb:isa", "isa6", pc_isa8_cards, nullptr, false)
@@ -351,13 +660,15 @@ static MACHINE_CONFIG_START( laser_turbo_xt, pc_state )
/* internal ram */
MCFG_RAM_ADD(RAM_TAG)
MCFG_RAM_DEFAULT_SIZE("640K")
- MCFG_RAM_EXTRA_OPTIONS("512K,768K,896K,1024K,1408K,1536K,1664K")
+ MCFG_RAM_EXTRA_OPTIONS("512K,1024K,1536K,1664K")
/* software lists */
MCFG_SOFTWARE_LIST_ADD("disk_list","ibm5150")
MACHINE_CONFIG_END
-static MACHINE_CONFIG_START( laser_xt3, pc_state )
+
+//Laser Turbo XT
+static MACHINE_CONFIG_START( laser_turbo_xt, pc_state )
MCFG_CPU_PC(pc8, pc8, I8088, XTAL_14_31818MHz/3) /* 4,77 MHz */
MCFG_IBM5160_MOTHERBOARD_ADD("mb","maincpu")
@@ -365,7 +676,7 @@ static MACHINE_CONFIG_START( laser_xt3, pc_state )
MCFG_ISA8_SLOT_ADD("mb:isa", "isa1", pc_isa8_cards, "cga", false)
MCFG_ISA8_SLOT_ADD("mb:isa", "isa2", pc_isa8_cards, "com", false) // Multi I/O card (includes FDC)
- MCFG_ISA8_SLOT_ADD("mb:isa", "isa3", pc_isa8_cards, "fdc_xt", false) // floppy drive A is 5.25" 360K and B is 3.5" 720K
+ MCFG_ISA8_SLOT_ADD("mb:isa", "isa3", pc_isa8_cards, "fdc_xt", false)
MCFG_ISA8_SLOT_ADD("mb:isa", "isa4", pc_isa8_cards, nullptr, false)
MCFG_ISA8_SLOT_ADD("mb:isa", "isa5", pc_isa8_cards, nullptr, false)
MCFG_ISA8_SLOT_ADD("mb:isa", "isa6", pc_isa8_cards, nullptr, false)
@@ -378,44 +689,63 @@ static MACHINE_CONFIG_START( laser_xt3, pc_state )
/* internal ram */
MCFG_RAM_ADD(RAM_TAG)
MCFG_RAM_DEFAULT_SIZE("640K")
- MCFG_RAM_EXTRA_OPTIONS("512K,1024K,1536K,1664K")
+ MCFG_RAM_EXTRA_OPTIONS("512K,768K,896K,1024K,1408K,1536K,1664K")
/* software lists */
MCFG_SOFTWARE_LIST_ADD("disk_list","ibm5150")
MACHINE_CONFIG_END
-ROM_START( bw230 )
- ROM_REGION(0x10000,"bios", 0)
- ROM_LOAD("bondwell.bin", 0xe000, 0x2000, CRC(d435a405) SHA1(a57c705d1144c7b61940b6f5c05d785c272fc9bb))
-ROM_END
+//**************************************************************************
+// ROM DEFINITIONS
+//**************************************************************************
-ROM_START( sicpc1605 )
+ROM_START( dgone )
ROM_REGION(0x10000,"bios", 0)
- ROM_LOAD("multitech pc-700 3.1.bin", 0xe000, 0x2000, CRC(0ac7a2e1) SHA1(b9c8504e21213d81a068dde9f51f9c973d726e7b))
+ ROM_LOAD( "dgone.bin", 0x8000, 0x08000, CRC(2c38c86e) SHA1(c0f85a000d1d13cd354965689e925d677822549e))
ROM_END
-ROM_START( ncrpc4i )
+ROM_START( bw230 )
ROM_REGION(0x10000,"bios", 0)
- ROM_LOAD( "ncr_pc4i_biosrom_1985.bin",0xc000, 0x4000, CRC(b9732648) SHA1(0d5d96fbc36089ca4d893b0db84faffa8043a5e4))
+ ROM_LOAD("bondwell.bin", 0xe000, 0x2000, CRC(d435a405) SHA1(a57c705d1144c7b61940b6f5c05d785c272fc9bb))
ROM_END
-ROM_START( zdsupers )
- ROM_REGION(0x10000,"bios", 0)
- ROM_SYSTEM_BIOS( 0, "v31d", "v3.1d" )
- ROMX_LOAD( "z184m v3.1d.10d", 0x8000, 0x8000, CRC(44012c3b) SHA1(f2f28979798874386ca8ba3dd3ead24ae7c2aeb4), ROM_BIOS(1))
- ROM_SYSTEM_BIOS( 1, "v29e", "v2.9e" )
- ROMX_LOAD( "z184m v2.9e.10d", 0x8000, 0x8000, CRC(de2f200b) SHA1(ad5ce601669a82351e412fc6c1c70c47779a1e55), ROM_BIOS(2))
+ROM_START( compc1 )
+ ROM_REGION(0x10000, "bios", 0)
+ ROM_LOAD("pc1_bios.bin", 0xc000, 0x4000, CRC(e37367c8) SHA1(9aac9c38b4ebdb9a740e393199c2eff75a0bde03))
+ ROM_REGION(0x8000, "gfx1", 0)
+ ROM_LOAD("pc1_char.bin", 0x0000, 0x4000, CRC(ee6c27f0) SHA1(e769cc3a49a1d708bd74eb4ac85bb6ea67220d38))
ROM_END
-
-ROM_START( dgone )
- ROM_REGION(0x10000,"bios", 0)
- ROM_LOAD( "dgone.bin", 0x8000, 0x08000, CRC(2c38c86e) SHA1(c0f85a000d1d13cd354965689e925d677822549e))
+// Note: Commodore PC20-III, PC10-III and COLT share the same BIOS
+ROM_START( pc10iii )
+ ROM_REGION(0x10000, "bios", 0)
+ ROM_DEFAULT_BIOS("v441")
+ ROM_SYSTEM_BIOS(0, "v435", "v4.35")
+ ROMX_LOAD("318085-01.u201", 0x8000, 0x8000, CRC(be752d1e) SHA1(5e5e63cd6d6269816cd691602e4c4d209fe3df67), ROM_BIOS(1))
+ ROM_SYSTEM_BIOS(1, "v436", "v4.36")
+ ROMX_LOAD("318085-02.u201", 0x8000, 0x8000, NO_DUMP, ROM_BIOS(2))
+ ROM_SYSTEM_BIOS(2, "v436c", "v4.36c")
+ ROMX_LOAD("318085-04.u201", 0x8000, 0x8000, NO_DUMP, ROM_BIOS(3))
+ ROM_SYSTEM_BIOS(3, "v438", "v4.38")
+ ROMX_LOAD("318085-05.u201", 0x8000, 0x8000, CRC(ae9e6a31) SHA1(853ee251cf230818c407a8d13ef060a21c90a8c1), ROM_BIOS(4))
+ ROM_SYSTEM_BIOS(4, "v439", "v4.39")
+ ROMX_LOAD("318085-06.u201", 0x8000, 0x8000, NO_DUMP, ROM_BIOS(5))
+ ROM_SYSTEM_BIOS(5, "v440", "v4.40")
+ ROMX_LOAD("318085-07.u201", 0x8000, 0x8000, NO_DUMP, ROM_BIOS(6))
+ ROM_SYSTEM_BIOS(6, "v441", "v4.41")
+ ROMX_LOAD("318085-08.u201", 0x8000, 0x8000, CRC(7e228dc8) SHA1(958dfdd637bd31c01b949fac729d6973a7e630bc), ROM_BIOS(7))
+ ROM_REGION(0x8000, "gfx1", 0)
+ ROM_LOAD("318086-02.u607", 0x0000, 0x8000, CRC(b406651c) SHA1(856f58353391a74a06ebb8ec9f8333d7d69e5fd6))
+ //ROM_LOAD("5788005.u33", 0x00000, 0x2000, BAD_DUMP CRC(0bf56d70) SHA1(c2a8b10808bf51a3c123ba3eb1e9dd608231916f)) /* temp so you can read the text */
ROM_END
-ROM_START( ssam88s )
- ROM_REGION(0x10000,"bios", 0)
- ROM_LOAD( "samsung_samtron_88s_vers_2.0a.bin", 0x8000, 0x08000, CRC(d1252a91) SHA1(469d15b6ecd7b70234975dc12c6bda4212a66652))
+ROM_START( iskr3104 )
+ ROM_REGION16_LE(0x10000,"bios", 0)
+ ROMX_LOAD( "198.bin", 0xc000, 0x2000, CRC(bcfd8e41) SHA1(e21ddf78839aa51fa5feb23f511ff5e2da31b433),ROM_SKIP(1))
+ ROMX_LOAD( "199.bin", 0xc001, 0x2000, CRC(2da5fe79) SHA1(14d5dccc141a0b3367f7f8a7188306fdf03c2b6c),ROM_SKIP(1))
+ // EGA card from Iskra-3104
+ //ROMX_LOAD( "143-03.bin", 0xc0001, 0x2000, CRC(d0706345) SHA1(e04bb40d944426a4ae2e3a614d3f4953d7132ede),ROM_SKIP(1))
+ //ROMX_LOAD( "143-02.bin", 0xc0000, 0x2000, CRC(c8c18ebb) SHA1(fd6dac76d43ab8b582e70f1d5cc931d679036fb9),ROM_SKIP(1))
ROM_END
ROM_START( mk88 )
@@ -432,15 +762,6 @@ ROM_START( mk88 )
ROMX_LOAD( "b88.bin", 0xe000, 0x2000, CRC(58a418df) SHA1(216398d4e4302ee7efcc2c8f9ff9d8a1161229ea), ROM_BIOS(3))
ROM_END
-ROM_START( iskr3104 )
- ROM_REGION16_LE(0x10000,"bios", 0)
- ROMX_LOAD( "198.bin", 0xc000, 0x2000, CRC(bcfd8e41) SHA1(e21ddf78839aa51fa5feb23f511ff5e2da31b433),ROM_SKIP(1))
- ROMX_LOAD( "199.bin", 0xc001, 0x2000, CRC(2da5fe79) SHA1(14d5dccc141a0b3367f7f8a7188306fdf03c2b6c),ROM_SKIP(1))
- // EGA card from Iskra-3104
- //ROMX_LOAD( "143-03.bin", 0xc0001, 0x2000, CRC(d0706345) SHA1(e04bb40d944426a4ae2e3a614d3f4953d7132ede),ROM_SKIP(1))
- //ROMX_LOAD( "143-02.bin", 0xc0000, 0x2000, CRC(c8c18ebb) SHA1(fd6dac76d43ab8b582e70f1d5cc931d679036fb9),ROM_SKIP(1))
-ROM_END
-
ROM_START( poisk2 )
ROM_REGION16_LE(0x10000,"bios", 0)
ROM_SYSTEM_BIOS(0, "v20", "v2.0")
@@ -470,6 +791,29 @@ ROM_START( mc1702 )
ROM_LOAD( "ba1m_(573rf5).rom", 0x0000, 0x0800, CRC(08d938e8) SHA1(957b6c691dbef75c1c735e8e4e81669d056971e4))
ROM_END
+ROM_START( zdsupers )
+ ROM_REGION(0x10000,"bios", 0)
+ ROM_SYSTEM_BIOS( 0, "v31d", "v3.1d" )
+ ROMX_LOAD( "z184m v3.1d.10d", 0x8000, 0x8000, CRC(44012c3b) SHA1(f2f28979798874386ca8ba3dd3ead24ae7c2aeb4), ROM_BIOS(1))
+ ROM_SYSTEM_BIOS( 1, "v29e", "v2.9e" )
+ ROMX_LOAD( "z184m v2.9e.10d", 0x8000, 0x8000, CRC(de2f200b) SHA1(ad5ce601669a82351e412fc6c1c70c47779a1e55), ROM_BIOS(2))
+ROM_END
+
+ROM_START( sicpc1605 )
+ ROM_REGION(0x10000,"bios", 0)
+ ROM_LOAD("multitech pc-700 3.1.bin", 0xe000, 0x2000, CRC(0ac7a2e1) SHA1(b9c8504e21213d81a068dde9f51f9c973d726e7b))
+ROM_END
+
+ROM_START( ncrpc4i )
+ ROM_REGION(0x10000,"bios", 0)
+ ROM_LOAD( "ncr_pc4i_biosrom_1985.bin",0xc000, 0x4000, CRC(b9732648) SHA1(0d5d96fbc36089ca4d893b0db84faffa8043a5e4))
+ROM_END
+
+ROM_START( olivm15 )
+ ROM_REGION(0x10000,"bios", 0)
+ ROM_LOAD( "oliv_m15.bin",0xc000, 0x04000, CRC(bf2ef795) SHA1(02d497131f5ca2c78f2accd38ab0eab6813e3ebf))
+ROM_END
+
ROM_START( ibm5550 )
ROM_REGION16_LE(0x10000,"bios", 0)
ROM_LOAD( "ipl5550.rom", 0xc000, 0x4000, CRC(40cf34c9) SHA1(d41f77fdfa787b0e97ed311e1c084b8699a5b197))
@@ -481,47 +825,11 @@ ROM_START( pc7000 )
ROMX_LOAD( "mitsubishi-m5l27128k-2.bin", 0x8001, 0x4000, CRC(99b229a4) SHA1(5800c8bafed26873d8cfcc79a05f93a780a31c91), ROM_SKIP(1))
ROM_END
-ROM_START( olivm15 )
- ROM_REGION(0x10000,"bios", 0)
- ROM_LOAD( "oliv_m15.bin",0xc000, 0x04000, CRC(bf2ef795) SHA1(02d497131f5ca2c78f2accd38ab0eab6813e3ebf))
-ROM_END
-
ROM_START( sx16 )
ROM_REGION(0x10000,"bios", 0)
ROM_LOAD( "tmm27128ad.bin",0xc000, 0x4000, CRC(f8543362) SHA1(fef625e260ca89ba02174584bdc12db609f0780e))
ROM_END
-ROM_START( compc1 )
- ROM_REGION(0x10000, "bios", 0)
- ROM_LOAD("pc1_bios.bin", 0xc000, 0x4000, CRC(e37367c8) SHA1(9aac9c38b4ebdb9a740e393199c2eff75a0bde03))
- ROM_REGION(0x8000, "gfx1", 0)
- ROM_LOAD("pc1_char.bin", 0x0000, 0x4000, CRC(ee6c27f0) SHA1(e769cc3a49a1d708bd74eb4ac85bb6ea67220d38))
-ROM_END
-
-
-// Note: Commodore PC20-III, PC10-III and COLT share the same BIOS
-ROM_START( pc10iii )
- ROM_REGION(0x10000, "bios", 0)
- ROM_DEFAULT_BIOS("v441")
- ROM_SYSTEM_BIOS(0, "v435", "v4.35")
- ROMX_LOAD("318085-01.u201", 0x8000, 0x8000, CRC(be752d1e) SHA1(5e5e63cd6d6269816cd691602e4c4d209fe3df67), ROM_BIOS(1))
- ROM_SYSTEM_BIOS(1, "v436", "v4.36")
- ROMX_LOAD("318085-02.u201", 0x8000, 0x8000, NO_DUMP, ROM_BIOS(2))
- ROM_SYSTEM_BIOS(2, "v436c", "v4.36c")
- ROMX_LOAD("318085-04.u201", 0x8000, 0x8000, NO_DUMP, ROM_BIOS(3))
- ROM_SYSTEM_BIOS(3, "v438", "v4.38")
- ROMX_LOAD("318085-05.u201", 0x8000, 0x8000, CRC(ae9e6a31) SHA1(853ee251cf230818c407a8d13ef060a21c90a8c1), ROM_BIOS(4))
- ROM_SYSTEM_BIOS(4, "v439", "v4.39")
- ROMX_LOAD("318085-06.u201", 0x8000, 0x8000, NO_DUMP, ROM_BIOS(5))
- ROM_SYSTEM_BIOS(5, "v440", "v4.40")
- ROMX_LOAD("318085-07.u201", 0x8000, 0x8000, NO_DUMP, ROM_BIOS(6))
- ROM_SYSTEM_BIOS(6, "v441", "v4.41")
- ROMX_LOAD("318085-08.u201", 0x8000, 0x8000, CRC(7e228dc8) SHA1(958dfdd637bd31c01b949fac729d6973a7e630bc), ROM_BIOS(7))
- ROM_REGION(0x8000, "gfx1", 0)
- ROM_LOAD("318086-02.u607", 0x0000, 0x8000, CRC(b406651c) SHA1(856f58353391a74a06ebb8ec9f8333d7d69e5fd6))
- //ROM_LOAD("5788005.u33", 0x00000, 0x2000, BAD_DUMP CRC(0bf56d70) SHA1(c2a8b10808bf51a3c123ba3eb1e9dd608231916f)) /* temp so you can read the text */
-ROM_END
-
ROM_START( mbc16 )
ROM_REGION(0x10000,"bios", 0)
ROM_LOAD( "mbc16.bin", 0xc000, 0x4000, CRC(f3e0934a) SHA1(e4b91c3d395be0414e20f23ad4919b8ac52639b2))
@@ -530,6 +838,14 @@ ROM_START( mbc16 )
ROM_LOAD( "atigssr.bin", 0x0000, 0x2000, CRC(aca81498) SHA1(0d84c89487ee7a6ac4c9e73fdb30c5fd8aa595f8))
ROM_END
+ROM_START ( ataripc1 )
+ ROM_REGION(0x10000,"bios", 0)
+ ROM_SYSTEM_BIOS( 0, "v3.06", "v3.06" )
+ ROMX_LOAD( "award_atari_pc_bios_3.06.bin", 0x8000, 0x8000, CRC(256427ce) SHA1(999f6af64b79f88c1d3492f386d9bee08efb50e7), ROM_BIOS(1))
+ ROM_SYSTEM_BIOS( 1, "v3.08", "v3.08" )
+ ROMX_LOAD( "award_atari_pc_bios_3.08.bin", 0x8000, 0x8000, CRC(929a2443) SHA1(8e98f3c9180c55b1f5521727779c016083d27960), ROM_BIOS(2)) //same as on Atari PC3, also used on Atari PC2
+ROM_END
+
ROM_START( ataripc3 )
ROM_REGION(0x10000,"bios", 0)
ROM_LOAD( "c101701-004 308.u61",0x8000, 0x8000, CRC(929a2443) SHA1(8e98f3c9180c55b1f5521727779c016083d27960))
@@ -541,6 +857,11 @@ ROM_START( ataripc3 )
ROM_LOAD( "c101681 6ffb.u60",0x000, 0x100, NO_DUMP ) // PAL20L10NC
ROM_END
+ROM_START( ssam88s )
+ ROM_REGION(0x10000,"bios", 0)
+ ROM_LOAD( "samsung_samtron_88s_vers_2.0a.bin", 0x8000, 0x08000, CRC(d1252a91) SHA1(469d15b6ecd7b70234975dc12c6bda4212a66652))
+ROM_END
+
ROM_START( eagle1600 )
ROM_REGION(0x10000,"bios", 0)
ROMX_LOAD( "eagle 1600 62-2732-001 rev e u403.bin",0xe000, 0x1000, CRC(3da1e96a) SHA1(77861ba5ebd056da1daf048f5abd459e0528666d), ROM_SKIP(1))
@@ -550,12 +871,12 @@ ROM_START( eagle1600 )
ROM_LOAD("eagle 1600 video char gen u301.bin", 0x00000, 0x1000, CRC(1a7e552f) SHA1(749058783eec9d96a70dc5fdbfccb56196f889dc))
ROM_END
-ROM_START(laser_turbo_xt)
+ROM_START( laser_turbo_xt )
ROM_REGION(0x10000, "bios", 0)
ROM_LOAD("laser_turbo_xt.bin", 0x0e000, 0x02000, CRC(0a6121d3) SHA1(59b1f8dd6fe981ef9a7700adebf6e1adda7cee90)) // version 1.11 - 27c64d
ROM_END
-ROM_START(laser_xt3)
+ROM_START( laser_xt3 )
ROM_REGION(0x10000, "bios", 0)
ROM_LOAD("laser_xt3.bin", 0x0e000, 0x02000, CRC(b45a7dd3) SHA1(62f17c408be0036d00a182e94c5c88b83d46b625)) // version 1.26 - 27c64
ROM_END
@@ -567,34 +888,26 @@ ROM_END
***************************************************************************/
-/* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME */
-COMP( 1984, dgone, ibm5150, 0, pccga, pccga, driver_device, 0, "Data General", "Data General/One" , MACHINE_NOT_WORKING)/* CGA, 2x 3.5" disk drives */
-COMP( 1985, bw230, ibm5150, 0, bondwell, bondwell, pc_state, bondwell, "Bondwell Holding", "BW230 (PRO28 Series)", 0 )
-COMP( 1984, compc1, ibm5150, 0, pccga, pccga, driver_device, 0, "Commodore Business Machines", "Commodore PC-1" , MACHINE_NOT_WORKING)
-COMP( 1987, pc10iii, ibm5150, 0, pccga, pccga, driver_device, 0, "Commodore Business Machines", "Commodore PC-10 III" , MACHINE_NOT_WORKING)
-
-
-COMP( 1992, iskr3104, ibm5150, 0, iskr3104, pccga, driver_device, 0, "Schetmash", "Iskra 3104", MACHINE_NOT_WORKING)
-COMP( 1989, mk88, ibm5150, 0, mk88, pccga, driver_device, 0, "<unknown>", "MK-88", MACHINE_NOT_WORKING)
-COMP( 1991, poisk2, ibm5150, 0, poisk2, pccga, driver_device, 0, "<unknown>", "Poisk-2", MACHINE_NOT_WORKING)
-COMP( 1990, mc1702, ibm5150, 0, pccga, pccga, driver_device, 0, "<unknown>", "Elektronika MC-1702", MACHINE_NOT_WORKING)
-
-COMP( 1987, zdsupers, ibm5150, 0, zenith, pccga, driver_device, 0, "Zenith Data Systems", "SuperSport", 0)
-COMP( 1985, sicpc1605, ibm5150, 0, siemens, pccga, driver_device, 0, "Siemens", "Sicomp PC16-05", MACHINE_NOT_WORKING)
-COMP( 1985, ncrpc4i, ibm5150, 0, pccga, pccga, driver_device, 0, "NCR","PC4i", MACHINE_NOT_WORKING)
-
-COMP( 198?, olivm15, ibm5150, 0, m15, pccga, driver_device, 0, "Olivetti", "M15", 0)
-
-COMP( 1983, ibm5550, ibm5150, 0, ibm5550, pccga, driver_device, 0, "International Business Machines", "IBM 5550", MACHINE_NOT_WORKING)
-
-COMP( 1985, pc7000, ibm5150, 0, pccga, pccga, driver_device, 0, "Sharp", "PC-7000", MACHINE_NOT_WORKING)
-
-COMP( 1988, sx16, ibm5150, 0, pccga, pccga, driver_device, 0, "Sanyo", "SX-16", MACHINE_NOT_WORKING)
-COMP( 198?, mbc16, ibm5150, 0, pccga, pccga, driver_device, 0, "Sanyo", "MBC-16" , MACHINE_NOT_WORKING)
-
-COMP( 198?, ataripc3, ibm5150, 0, pccga, pccga, driver_device, 0, "Atari", "PC-3" , 0)
-COMP( 1989, ssam88s, ibm5150, 0, pccga, pccga, driver_device, 0, "Samsung", "Samtron 88S" , MACHINE_NOT_WORKING)
-COMP( 1983, eagle1600, ibm5150, 0, eagle1600, pccga, driver_device, 0, "Eagle", "1600" , MACHINE_NOT_WORKING)
-
-COMP ( 1988, laser_turbo_xt, ibm5150, 0, laser_turbo_xt, 0, driver_device, 0, "VTech", "Laser Turbo XT" , 0)
-COMP ( 1989, laser_xt3, ibm5150, 0, laser_xt3, 0, driver_device, 0, "VTech", "Laser XT/3" , 0)
+/* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME */
+COMP( 1984, dgone, ibm5150, 0, dgone, pccga, driver_device, 0, "Data General", "Data General/One" , MACHINE_NOT_WORKING)/* CGA, 2x 3.5" disk drives */
+COMP( 1985, bw230, ibm5150, 0, bondwell, bondwell, pc_state, bondwell, "Bondwell Holding", "BW230 (PRO28 Series)", 0 )
+COMP( 1984, compc1, ibm5150, 0, pccga, pccga, driver_device, 0, "Commodore Business Machines", "Commodore PC-1" , MACHINE_NOT_WORKING)
+COMP( 1987, pc10iii, ibm5150, 0, pccga, pccga, driver_device, 0, "Commodore Business Machines", "Commodore PC-10 III" , MACHINE_NOT_WORKING)
+COMP( 1992, iskr3104, ibm5150, 0, iskr3104, pccga, driver_device, 0, "Schetmash", "Iskra 3104", MACHINE_NOT_WORKING)
+COMP( 1989, mk88, ibm5150, 0, mk88, pccga, driver_device, 0, "<unknown>", "MK-88", MACHINE_NOT_WORKING)
+COMP( 1991, poisk2, ibm5150, 0, poisk2, pccga, driver_device, 0, "<unknown>", "Poisk-2", MACHINE_NOT_WORKING)
+COMP( 1990, mc1702, ibm5150, 0, pccga, pccga, driver_device, 0, "<unknown>", "Elektronika MC-1702", MACHINE_NOT_WORKING)
+COMP( 1987, zdsupers, ibm5150, 0, zenith, pccga, driver_device, 0, "Zenith Data Systems", "SuperSport", 0)
+COMP( 1985, sicpc1605, ibm5150, 0, siemens, pccga, driver_device, 0, "Siemens", "Sicomp PC16-05", MACHINE_NOT_WORKING)
+COMP( 1985, ncrpc4i, ibm5150, 0, ncrpc4i, pccga, driver_device, 0, "NCR", "PC4i", MACHINE_NOT_WORKING)
+COMP( 198?, olivm15, ibm5150, 0, m15, pccga, driver_device, 0, "Olivetti", "M15", 0)
+COMP( 1983, ibm5550, ibm5150, 0, ibm5550, pccga, driver_device, 0, "International Business Machines", "IBM 5550", MACHINE_NOT_WORKING)
+COMP( 1985, pc7000, ibm5150, 0, pccga, pccga, driver_device, 0, "Sharp", "PC-7000", MACHINE_NOT_WORKING)
+COMP( 1988, sx16, ibm5150, 0, pccga, pccga, driver_device, 0, "Sanyo", "SX-16", MACHINE_NOT_WORKING)
+COMP( 198?, mbc16, ibm5150, 0, pccga, pccga, driver_device, 0, "Sanyo", "MBC-16" , MACHINE_NOT_WORKING)
+COMP( 1987, ataripc1, ibm5150, 0, ataripc1, pccga, driver_device, 0, "Atari", "PC1" , 0)
+COMP( 1988, ataripc3, ibm5150, 0, pccga, pccga, driver_device, 0, "Atari", "PC3" , 0)
+COMP( 1989, ssam88s, ibm5150, 0, pccga, pccga, driver_device, 0, "Samsung", "Samtron 88S" , MACHINE_NOT_WORKING)
+COMP( 1983, eagle1600, ibm5150, 0, eagle1600, pccga, driver_device, 0, "Eagle", "1600" , MACHINE_NOT_WORKING)
+COMP( 1988, laser_turbo_xt, ibm5150, 0, laser_turbo_xt, 0, driver_device, 0, "VTech", "Laser Turbo XT" , 0)
+COMP( 1989, laser_xt3, ibm5150, 0, laser_xt3, 0, driver_device, 0, "VTech", "Laser XT/3" , 0)
diff --git a/src/mame/drivers/peyper.cpp b/src/mame/drivers/peyper.cpp
index 55729c2df7a..79795c2c192 100644
--- a/src/mame/drivers/peyper.cpp
+++ b/src/mame/drivers/peyper.cpp
@@ -15,6 +15,7 @@
Nemesis (Peyper)
Odisea Paris-Dakar (Peyper)
Hang-On (Sonic)
+ Ator (Videodens)
Others not emulated (need roms):
Night Fever (Sonic)
@@ -200,8 +201,10 @@ static ADDRESS_MAP_START( peyper_io, AS_IO, 8, peyper_state )
ADDRESS_MAP_GLOBAL_MASK(0xff)
AM_RANGE(0x00, 0x01) AM_DEVREADWRITE("i8279", i8279_device, read, write)
AM_RANGE(0x04, 0x04) AM_DEVWRITE("ay1", ay8910_device, address_w)
+ AM_RANGE(0x05, 0x05) AM_DEVREAD("ay1", ay8910_device, data_r) // only read by Ator?
AM_RANGE(0x06, 0x06) AM_DEVWRITE("ay1", ay8910_device, data_w)
AM_RANGE(0x08, 0x08) AM_DEVWRITE("ay2", ay8910_device, address_w)
+ AM_RANGE(0x09, 0x09) AM_DEVREAD("ay2", ay8910_device, data_r) // never actually read?
AM_RANGE(0x0a, 0x0a) AM_DEVWRITE("ay2", ay8910_device, data_w)
AM_RANGE(0x0c, 0x0c) AM_WRITE(sol_w)
AM_RANGE(0x10, 0x18) AM_WRITE(lamp_w)
@@ -831,6 +834,16 @@ ROM_START(wolfman)
ROM_END
/*-------------------------------------------------------------------
+/ Ator (198?)
+/-------------------------------------------------------------------*/
+ROM_START(ator)
+ ROM_REGION(0x6000, "maincpu", 0)
+ ROM_LOAD("1.bin", 0x0000, 0x2000, NO_DUMP)
+ ROM_LOAD("Ator 2 _0xBA29.BIN", 0x2000, 0x2000, CRC(21aad5c4) SHA1(e78da5d80682710db34cbbfeae5af54241c73371))
+ // probably no ROM 3 (PCB photo shows location unpopulated)
+ROM_END
+
+/*-------------------------------------------------------------------
/ Sir Lancelot (1994)
/-------------------------------------------------------------------*/
ROM_START(lancelot)
@@ -855,5 +868,6 @@ GAME( 1987, sonstwr2, sonstwar, peyper, sonstwar, peyper_state, peyper, ROT0
GAME( 1987, wolfman, 0, peyper, wolfman, peyper_state, wolfman, ROT0, "Peyper", "Wolf Man", MACHINE_MECHANICAL | MACHINE_NOT_WORKING )
GAME( 1986, nemesisp, 0, peyper, wolfman, peyper_state, wolfman, ROT0, "Peyper", "Nemesis", MACHINE_MECHANICAL | MACHINE_NOT_WORKING )
GAME( 1987, odisea, 0, peyper, odisea, peyper_state, wolfman, ROT0, "Peyper", "Odisea Paris-Dakar", MACHINE_MECHANICAL | MACHINE_NOT_WORKING )
-GAME( 1988, hangonp, 0, peyper, sonstwar, peyper_state, peyper, ROT0, "Sonic", "Hang-On (Sonic)", MACHINE_MECHANICAL | MACHINE_NOT_WORKING ) // inputs to be checked
+GAME( 1988, hangonp, 0, peyper, sonstwar, peyper_state, peyper, ROT0, "Sonic", "Hang-On (Sonic)", MACHINE_MECHANICAL | MACHINE_NOT_WORKING ) // inputs to be checked
+GAME( 198?, ator, 0, peyper, sonstwar, peyper_state, peyper, ROT0, "Videodens", "Ator", MACHINE_MECHANICAL | MACHINE_NOT_WORKING ) // initial program ROM missing; no manual found
GAME( 1994, lancelot, 0, peyper, sonstwar, driver_device,0, ROT0, "Peyper", "Sir Lancelot", MACHINE_IS_SKELETON_MECHANICAL) // different hardware (see top of file)
diff --git a/src/mame/drivers/play_3.cpp b/src/mame/drivers/play_3.cpp
index fc2a3e7329e..1a6457dabf6 100644
--- a/src/mame/drivers/play_3.cpp
+++ b/src/mame/drivers/play_3.cpp
@@ -11,16 +11,13 @@ Status:
- Lots of loud siren-like noises when there should be silence
- Mechanical sounds to add
- Most games work
--- Spain82: not working (no manual available)
+-- Spain82: not working (no manual available; uses same sound board as Cerberus)
-- Nautilus: sound is broken (runs into the weeds)
--- Skill Flight: not working
+-- Skill Flight, Phantom Ship: not working
+-- Eight Ball Champ, Cobra: not working (different hardware)
-- Miss Disco: not working (no manual available)
--- Phantom Ship: no sound (no manual available)
-- Meg Aaton: Ball number doesn't show
-It looks like Skill Flight and Phantom Ship use a new sound card that contains
-Z80A, 5205, 2x AY-3-8910, 2x Z80CTC, 2x MF10.
-
Note: The input lines INT, EF1-4 are inverted (not true voltage).
First time:
@@ -51,6 +48,7 @@ The manual is not that clear, there's a lot we don't know, this *seems* to work.
#include "machine/clock.h"
#include "machine/7474.h"
#include "sound/ay8910.h"
+#include "audio/efo_zsu.h"
#include "play_3.lh"
@@ -65,6 +63,7 @@ public:
, m_4013b(*this, "4013b")
, m_aysnd1(*this, "aysnd1")
, m_aysnd2(*this, "aysnd2")
+ , m_zsu(*this, "zsu")
, m_keyboard(*this, "X.%u", 0)
{ }
@@ -72,6 +71,7 @@ public:
DECLARE_WRITE8_MEMBER(megaaton_port01_w);
DECLARE_WRITE8_MEMBER(port02_w);
DECLARE_WRITE8_MEMBER(port03_w);
+ DECLARE_WRITE8_MEMBER(sklflite_port03_w);
DECLARE_READ8_MEMBER(port04_r);
DECLARE_READ8_MEMBER(port05_r);
DECLARE_WRITE8_MEMBER(port06_w);
@@ -87,22 +87,24 @@ public:
DECLARE_READ_LINE_MEMBER(clear_a_r);
private:
- uint16_t m_clockcnt;
- uint16_t m_resetcnt;
- uint16_t m_resetcnt_a;
- uint8_t m_soundlatch;
- uint8_t m_a_irqset;
- uint16_t m_a_irqcnt;
- uint8_t m_kbdrow;
- uint8_t m_segment[5];
+ u16 m_clockcnt;
+ u16 m_resetcnt;
+ u16 m_resetcnt_a;
+ u8 m_soundlatch;
+ u8 m_port03_old;
+ u8 m_a_irqset;
+ u16 m_a_irqcnt;
+ u8 m_kbdrow;
+ u8 m_segment[5];
bool m_disp_sw;
virtual void machine_reset() override;
required_device<cosmac_device> m_maincpu;
- required_device<cosmac_device> m_audiocpu;
+ optional_device<cosmac_device> m_audiocpu;
required_device<ttl7474_device> m_4013a;
required_device<ttl7474_device> m_4013b;
- required_device<ay8910_device> m_aysnd1;
- required_device<ay8910_device> m_aysnd2;
+ optional_device<ay8910_device> m_aysnd1;
+ optional_device<ay8910_device> m_aysnd2;
+ optional_device<efo_zsu_device> m_zsu;
required_ioport_array<10> m_keyboard;
};
@@ -124,12 +126,12 @@ ADDRESS_MAP_END
static ADDRESS_MAP_START( megaaton_io, AS_IO, 8, play_3_state )
AM_RANGE(0x01, 0x01) AM_WRITE(megaaton_port01_w) // digits, scan-lines
- AM_RANGE(0x02, 0x02) AM_WRITE(port02_w) // sound code
- AM_RANGE(0x03, 0x03) AM_WRITE(port03_w) //
- AM_RANGE(0x04, 0x04) AM_READ(port04_r) // switches
- AM_RANGE(0x05, 0x05) AM_READ(port05_r) // more switches
- AM_RANGE(0x06, 0x06) AM_WRITE(port06_w) // segments
- AM_RANGE(0x07, 0x07) AM_WRITE(port07_w) // flipflop clear
+ AM_IMPORT_FROM(play_3_io)
+ADDRESS_MAP_END
+
+static ADDRESS_MAP_START( sklflite_io, AS_IO, 8, play_3_state )
+ AM_RANGE(0x03, 0x03) AM_WRITE(sklflite_port03_w) //
+ AM_IMPORT_FROM(play_3_io)
ADDRESS_MAP_END
static ADDRESS_MAP_START( play_3_audio_map, AS_PROGRAM, 8, play_3_state )
@@ -258,6 +260,7 @@ void play_3_state::machine_reset()
m_disp_sw = 0;
for (uint8_t i = 0; i < 5; i++)
m_segment[i] = 0;
+ m_port03_old = 0;
}
WRITE8_MEMBER( play_3_state::port01_w )
@@ -320,6 +323,21 @@ WRITE8_MEMBER( play_3_state::port03_w )
}
+WRITE8_MEMBER( play_3_state::sklflite_port03_w )
+{
+ if (BIT(data, 6) && !BIT(m_port03_old, 6))
+ m_zsu->sound_command_w(space, 0, m_soundlatch);
+ if (BIT(data, 5))
+ {
+ if (m_soundlatch == 11)
+ m_samples->start(0, 5); // outhole
+ //if (m_soundlatch == 13)
+ //m_samples->start(0, 6); // no knocker?
+ }
+
+ m_port03_old = data;
+}
+
READ8_MEMBER( play_3_state::port04_r )
{
if (m_kbdrow & 0x3f)
@@ -405,15 +423,18 @@ WRITE_LINE_MEMBER( play_3_state::clock_w )
if ((m_clockcnt & 0x3ff) == 0)
m_4013b->preset_w(BIT(m_clockcnt, 10)); // Q10 output
- // sound irq
- m_a_irqcnt--;
- if (m_a_irqcnt == 1)
- m_audiocpu->int_w(1); // inverted
- else
- if (m_a_irqcnt == 0)
+ if (m_audiocpu.found())
{
- m_a_irqcnt = (m_a_irqset << 3) | 7;
- m_audiocpu->int_w(0); // inverted
+ // sound irq
+ m_a_irqcnt--;
+ if (m_a_irqcnt == 1)
+ m_audiocpu->int_w(1); // inverted
+ else
+ if (m_a_irqcnt == 0)
+ {
+ m_a_irqcnt = (m_a_irqset << 3) | 7;
+ m_audiocpu->int_w(0); // inverted
+ }
}
}
}
@@ -482,6 +503,19 @@ static MACHINE_CONFIG_DERIVED( megaaton, play_3 )
MCFG_CPU_IO_MAP(megaaton_io)
MACHINE_CONFIG_END
+static MACHINE_CONFIG_DERIVED( sklflite, play_3 )
+ MCFG_CPU_MODIFY("maincpu")
+ MCFG_CPU_IO_MAP(sklflite_io)
+
+ MCFG_DEVICE_REMOVE("audiocpu")
+ MCFG_DEVICE_REMOVE("aysnd1")
+ MCFG_DEVICE_REMOVE("aysnd2")
+ MCFG_DEVICE_REMOVE("lspeaker")
+ MCFG_DEVICE_REMOVE("rspeaker")
+
+ MCFG_DEVICE_ADD("zsu", EFO_ZSU1, 0)
+MACHINE_CONFIG_END
+
/*-------------------------------------------------------------------
/ Spain 82 (10/82)
@@ -642,7 +676,7 @@ ROM_START(sklflite)
ROM_LOAD("skflcpu1.rom", 0x0000, 0x2000, CRC(8f833b55) SHA1(1729203582c22b51d1cc401aa8f270aa5cdadabe))
ROM_LOAD("skflaudiocpu.rom", 0x2000, 0x2000, CRC(ffc497aa) SHA1(3e88539ae1688322b9268f502d8ca41cffb28df3))
- ROM_REGION(0x20000, "audiocpu", 0) // Z80A soundcard
+ ROM_REGION(0x28000, "zsu:soundcpu", 0) // Z80A soundcard
ROM_LOAD("skflsnd.rom", 0x0000, 0x8000, CRC(926a1da9) SHA1(16c762fbfe6a55597f26ff55d380192bb8647ee0))
ROM_END
@@ -654,7 +688,7 @@ ROM_START(phntmshp)
ROM_LOAD("video1.bin", 0x0000, 0x2000, CRC(2b61a8d2) SHA1(1b5cabbab252b2ffb6ed12fb7e4181de7695ed9a))
ROM_LOAD("video2.bin", 0x2000, 0x2000, CRC(50126db1) SHA1(58d89e44131554cb087c4cad62869f90366704ad))
- ROM_REGION(0x20000, "audiocpu", 0) // Z80A soundcard
+ ROM_REGION(0x28000, "zsu:soundcpu", 0) // Z80A soundcard
ROM_LOAD("sonido1.bin", 0x00000, 0x8000, CRC(3294611d) SHA1(5f790b41bcb6d87418c80e61ac8ae69c57864b1d))
ROM_LOAD("sonido2.bin", 0x08000, 0x8000, CRC(c2efc826) SHA1(44ee144b902627745853011968e0d654b35b3b08))
ROM_LOAD("sonido3.bin", 0x10000, 0x8000, CRC(13d50f39) SHA1(70624de2dd8412c83866183a83f16cc5b8bdccb8))
@@ -699,7 +733,7 @@ ROM_START(eballchps)
ROM_REGION(0x8000, "maincpu", 0) // Z80-based
ROM_LOAD("U18-JEB 5A0 - CPU.BIN", 0x0000, 0x8000, CRC(87615a7d) SHA1(b27ca2d863040a2641f88f9bd3143467a83f181b))
- ROM_REGION(0x20000, "audiocpu", 0) // Z80-based
+ ROM_REGION(0x28000, "zsu:soundcpu", 0) // Z80-based
ROM_LOAD("U3-EBE A02 - Sonido.BIN", 0x00000, 0x8000, CRC(34be32ee) SHA1(ce0271540164639f28d617753760ecc479b6b0d0))
ROM_LOAD("U4-EBE B01 - Sonido.BIN", 0x08000, 0x8000, CRC(d696c4e8) SHA1(501e18c258e6d42819d25d72e1907984a6cfeecb))
ROM_LOAD("U5-EBE C01 - Sonido.BIN", 0x10000, 0x8000, CRC(fe78d7ef) SHA1(ed91c51dd230854a007f88446011f786759687ca))
@@ -711,12 +745,25 @@ ROM_START(cobrapb)
ROM_REGION(0x8000, "maincpu", 0) // Z80-based
ROM_LOAD("U18 - JCB 4 A0 - CPU.BIN", 0x0000, 0x8000, CRC(c663910e) SHA1(c38692343f114388259c4e7b7943e5be934189ca))
- ROM_REGION(0x20000, "audiocpu", 0) // Z80-based
+ ROM_REGION(0x28000, "zsu:soundcpu", 0) // Z80-based
ROM_LOAD("U3 - SCB 1 A0 - Sonido.BIN", 0x00000, 0x8000, CRC(d3675770) SHA1(882ce748308f2d78cccd28fc8cd64fe69bd223e3))
ROM_LOAD("U4 - SCB 1 B0 - Sonido.BIN", 0x08000, 0x8000, CRC(e8e1bdbb) SHA1(215bdfab751cb0ea47aa529df0ac30976de4f772))
ROM_LOAD("U5 - SCB 1 C0 - Sonido.BIN", 0x10000, 0x8000, CRC(c36340ab) SHA1(cd662457959de3a929ba02779e2046ed18b797e2))
ROM_END
+#ifdef UNUSED_DEFINITION
+// Come Back (Nondum)
+ROM_START(comeback)
+ ROM_REGION(0x8000, "maincpu", 0)
+ ROM_LOAD("JCO_6a0.u18", 0x0000, 0x8000, NO_DUMP)
+
+ ROM_REGION(0x28000, "zsu:soundcpu", 0)
+ ROM_LOAD("CBS_3a0.u3", 0x00000, 0x8000, NO_DUMP)
+ ROM_LOAD("CBS_3b0.u4", 0x08000, 0x8000, NO_DUMP)
+ ROM_LOAD("CBS_1c0.u5", 0x10000, 0x8000, NO_DUMP)
+ROM_END
+#endif
+
GAME(1982, spain82, 0, play_3, play_3, driver_device, 0, ROT0, "Playmatic", "Spain '82", MACHINE_MECHANICAL | MACHINE_NOT_WORKING | MACHINE_NO_SOUND)
GAME(1983, megaaton, 0, megaaton, megaaton, driver_device, 0, ROT0, "Playmatic", "Meg-Aaton", MACHINE_MECHANICAL | MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND)
GAME(1983, megaatona, megaaton, megaaton, megaaton, driver_device, 0, ROT0, "Playmatic", "Meg-Aaton (alternate set)", MACHINE_MECHANICAL | MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND)
@@ -730,13 +777,14 @@ GAME(1985, starfirpa, starfirp, play_3, play_3, driver_device, 0, ROT0, "Pl
GAME(1985, trailer, 0, play_3, play_3, driver_device, 0, ROT0, "Playmatic", "Trailer", MACHINE_MECHANICAL | MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND)
GAME(1986, fldragon, 0, play_3, play_3, driver_device, 0, ROT0, "Playmatic", "Flash Dragon", MACHINE_MECHANICAL | MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND)
GAME(1986, fldragona, fldragon, play_3, play_3, driver_device, 0, ROT0, "Playmatic", "Flash Dragon (alternate set)", MACHINE_MECHANICAL | MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND)
-GAME(1987, phntmshp, 0, play_3, play_3, driver_device, 0, ROT0, "Playmatic", "Phantom Ship", MACHINE_MECHANICAL | MACHINE_NOT_WORKING | MACHINE_NO_SOUND)
-GAME(1987, sklflite, 0, play_3, play_3, driver_device, 0, ROT0, "Playmatic", "Skill Flight (Playmatic)", MACHINE_MECHANICAL | MACHINE_NOT_WORKING | MACHINE_NO_SOUND)
+GAME(1987, phntmshp, 0, sklflite, play_3, driver_device, 0, ROT0, "Playmatic", "Phantom Ship", MACHINE_MECHANICAL | MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND)
+GAME(1987, sklflite, 0, sklflite, play_3, driver_device, 0, ROT0, "Playmatic", "Skill Flight (Playmatic)", MACHINE_MECHANICAL | MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND)
// not by Playmatic, but same hardware
GAME(1986, ridersrf, 0, play_3, play_3, driver_device, 0, ROT0, "JocMatic", "Rider's Surf", MACHINE_MECHANICAL | MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND)
GAME(1987, ironball, 0, play_3, play_3, driver_device, 0, ROT0, "Stargame", "Iron Balls", MACHINE_MECHANICAL | MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND)
// "Z-Pinball" hardware, Z80 main and sound CPUs - to be split (?)
-GAME(1986, eballchps, eballchp, play_3, play_3, driver_device, 0, ROT0, "Bally (Maibesa license)", "Eight Ball Champ (Spain, Z-Pinball hardware)", MACHINE_MECHANICAL | MACHINE_NOT_WORKING | MACHINE_NO_SOUND)
-GAME(1987, cobrapb, 0, play_3, play_3, driver_device, 0, ROT0, "Playbar", "Cobra (Playbar)", MACHINE_MECHANICAL | MACHINE_NOT_WORKING | MACHINE_NO_SOUND)
+GAME(1986, eballchps, eballchp, sklflite, play_3, driver_device, 0, ROT0, "Bally (Maibesa license)", "Eight Ball Champ (Spain, Z-Pinball hardware)", MACHINE_IS_SKELETON_MECHANICAL)
+GAME(1987, cobrapb, 0, sklflite, play_3, driver_device, 0, ROT0, "Playbar", "Cobra (Playbar)", MACHINE_IS_SKELETON_MECHANICAL)
+//GAME(198?, comeback, 0, sklflite, play_3, driver_device, 0, ROT0, "Nondum", "Come Back", MACHINE_IS_SKELETON_MECHANICAL) // undumped
// bingo hardware, to be split (?)
GAME(1983, msdisco, 0, play_3, play_3, driver_device, 0, ROT0, "Playmatic", "Miss Disco (Bingo)", MACHINE_IS_SKELETON_MECHANICAL)
diff --git a/src/mame/drivers/rm380z.cpp b/src/mame/drivers/rm380z.cpp
index 0604b07cde0..53baa0c3c7c 100644
--- a/src/mame/drivers/rm380z.cpp
+++ b/src/mame/drivers/rm380z.cpp
@@ -8,6 +8,9 @@ Microcomputer produced by Research Machines Limited, Oxford, UK
MESS driver by Wilbert Pol and friol (dantonag (at) gmail.com)
Driver started on 22/12/2011
+Stefano Bodrato, 09/12/2016 - skeleton for cassette support
+True tape samples are needed to continue !
+
===
Memory map from sevice manual:
@@ -146,6 +149,12 @@ static MACHINE_CONFIG_START( rm380z, rm380z_state )
MCFG_PALETTE_ADD_MONOCHROME("palette")
+ /* cassette */
+ MCFG_CASSETTE_ADD( "cassette" )
+// MCFG_CASSETTE_DEFAULT_STATE(CASSETTE_STOPPED | CASSETTE_MOTOR_ENABLED | CASSETTE_SPEAKER_MUTED)
+ MCFG_CASSETTE_DEFAULT_STATE(CASSETTE_PLAY | CASSETTE_MOTOR_ENABLED)
+ //m_cassette->change_state((BIT(data,x)) ? CASSETTE_MOTOR_DISABLED : CASSETTE_MOTOR_ENABLED, CASSETTE_MASK_MOTOR);
+
/* RAM configurations */
MCFG_RAM_ADD(RAM_TAG)
MCFG_RAM_DEFAULT_SIZE("56K")
@@ -161,10 +170,34 @@ static MACHINE_CONFIG_START( rm380z, rm380z_state )
MCFG_GENERIC_KEYBOARD_CB(WRITE8(rm380z_state, keyboard_put))
MACHINE_CONFIG_END
-/* ROM definition */
+static MACHINE_CONFIG_DERIVED( rm480z, rm380z )
+ MCFG_SCREEN_MODIFY("screen")
+ MCFG_SCREEN_SIZE(64*8, 24*11)
+ MCFG_SCREEN_VISIBLE_AREA(0, 64*8-1, 0, 24*11-1)
+ MCFG_SCREEN_UPDATE_DRIVER(rm380z_state, screen_update_rm480z)
+MACHINE_CONFIG_END
+
+
+/* ROM definitions */
+
+ROM_START( rm380z34d )
+ ROM_REGION( 0x10000, RM380Z_MAINCPU_TAG, 0 )
+ ROM_LOAD( "cos34d-f.bin", 0x0000, 0x1000, CRC(eb128b40) SHA1(c46f358fb76459987e41750d052995563f2f7d53))
+ // chargen ROM is undumped, afaik
+ ROM_REGION( 0x1680, "chargen", 0 )
+ ROM_LOAD( "ch3.raw", 0x0000, 0x1680, BAD_DUMP CRC(c223622b) SHA1(185ef24896419d7ff46f71a760ac217de3811684))
+ROM_END
+
+ROM_START( rm380z34e )
+ ROM_REGION( 0x10000, RM380Z_MAINCPU_TAG, 0 )
+ ROM_LOAD( "cos34e-m.bin", 0x0000, 0x1000, CRC(20e2ddf4) SHA1(3177b28793d5a348c94fd0ae6393d74e2e9a8662))
+ // chargen ROM is undumped, afaik
+ ROM_REGION( 0x1680, "chargen", 0 )
+ ROM_LOAD( "ch3.raw", 0x0000, 0x1680, BAD_DUMP CRC(c223622b) SHA1(185ef24896419d7ff46f71a760ac217de3811684))
+ROM_END
+
ROM_START( rm380z )
ROM_REGION( 0x10000, RM380Z_MAINCPU_TAG, 0 )
-// ROM_LOAD( "cos34e-m.bin", 0x0000, 0x1000, CRC(20e2ddf4) SHA1(3177b28793d5a348c94fd0ae6393d74e2e9a8662))
// I'm not sure of how those roms have been dumped. I don't know if those are good dumps or not.
ROM_LOAD( "cos40b-m.bin", 0x0000, 0x1000, BAD_DUMP CRC(1f0b3a5c) SHA1(0b29cb2a3b7eaa3770b34f08c4fd42844f42700f))
ROM_LOAD( "cos40b-m_f600-f9ff.bin", 0x1000, 0x400, BAD_DUMP CRC(e3397d9d) SHA1(490a0c834b0da392daf782edc7d51ca8f0668b1a))
@@ -174,6 +207,20 @@ ROM_START( rm380z )
ROM_LOAD( "ch3.raw", 0x0000, 0x1680, BAD_DUMP CRC(c223622b) SHA1(185ef24896419d7ff46f71a760ac217de3811684))
ROM_END
+ROM_START( rm480z )
+ ROM_REGION( 0x10000, RM380Z_MAINCPU_TAG, 0 )
+ ROM_LOAD( "cos40b-m.bin", 0x0000, 0x1000, CRC(1f0b3a5c) SHA1(0b29cb2a3b7eaa3770b34f08c4fd42844f42700f))
+ ROM_LOAD( "cos40b-m_f600-f9ff.bin", 0x1000, 0x400, CRC(e3397d9d) SHA1(490a0c834b0da392daf782edc7d51ca8f0668b1a))
+ ROM_LOAD( "cos40b-m_1c00-1dff.bin", 0x1400, 0x200, CRC(0f759f44) SHA1(9689c1c1faa62c56def999cbedbbb0c8d928dcff))
+ ROM_REGION( 0x2000, "chargen", 0 )
+ ROM_LOAD( "cg06.bin", 0x0000, 0x2000, CRC(15d40f7e) SHA1(a7266357eb9be849f77a97ff3013b236c0af8289) )
+ROM_END
+
+
/* Driver */
+/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME */
+COMP(1978, rm380z, 0, 0, rm380z, rm380z, rm380z_state, rm380z, "Research Machines", "RM-380Z, COS 4.0B", MACHINE_NO_SOUND_HW)
+COMP(1978, rm380z34d, rm380z, 0, rm380z, rm380z, rm380z_state, rm380z34d, "Research Machines", "RM-380Z, COS 3.4D", MACHINE_BTANB_FLAGS)
+COMP(1978, rm380z34e, rm380z, 0, rm380z, rm380z, rm380z_state, rm380z34e, "Research Machines", "RM-380Z, COS 3.4E", MACHINE_BTANB_FLAGS)
+COMP(1981, rm480z, rm380z, 0, rm480z, rm380z, rm380z_state, rm380z34e, "Research Machines", "LINK RM-480Z", MACHINE_NOT_WORKING | MACHINE_NO_SOUND_HW)
-COMP(1978, rm380z, 0, 0, rm380z, rm380z, driver_device, 0, "Research Machines", "RM-380Z", MACHINE_NO_SOUND_HW)
diff --git a/src/mame/drivers/rohga.cpp b/src/mame/drivers/rohga.cpp
index 8b3d103078b..3cb74af0a69 100644
--- a/src/mame/drivers/rohga.cpp
+++ b/src/mame/drivers/rohga.cpp
@@ -7,6 +7,7 @@
Rogha Armour Attack (c) 1991 Data East Corporation
Wizard Fire (c) 1992 Data East Corporation
Nitro Ball/Gun Ball (c) 1992 Data East Corporation
+ Hangzo (prototype) (c) 1992 Hot-B
Schmeiser Robo (c) 1993 Hot-B
This hardware is capable of alpha-blending on sprites and playfields
@@ -265,7 +266,7 @@ static ADDRESS_MAP_START( nitrobal_map, AS_PROGRAM, 16, rohga_state )
AM_RANGE(0xff8000, 0xffffff) AM_RAM
ADDRESS_MAP_END
-static ADDRESS_MAP_START( schmeisr_map, AS_PROGRAM, 16, rohga_state )
+static ADDRESS_MAP_START( hotb_base_map, AS_PROGRAM, 16, rohga_state )
AM_RANGE(0x000000, 0x0fffff) AM_ROM
AM_RANGE(0x200000, 0x20000f) AM_DEVWRITE("tilegen1", deco16ic_device, pf_control_w)
AM_RANGE(0x240000, 0x24000f) AM_DEVWRITE("tilegen2", deco16ic_device, pf_control_w)
@@ -284,17 +285,27 @@ static ADDRESS_MAP_START( schmeisr_map, AS_PROGRAM, 16, rohga_state )
AM_RANGE(0x3c2000, 0x3c2fff) AM_DEVREADWRITE("tilegen1", deco16ic_device, pf2_data_r, pf2_data_w)
AM_RANGE(0x3c4000, 0x3c4fff) AM_DEVREADWRITE("tilegen2", deco16ic_device, pf1_data_r, pf1_data_w)
AM_RANGE(0x3c6000, 0x3c6fff) AM_DEVREADWRITE("tilegen2", deco16ic_device, pf2_data_r, pf2_data_w)
- AM_RANGE(0x3c8000, 0x3c8fff) AM_MIRROR(0x1000) AM_RAM AM_SHARE("pf1_rowscroll")
+ AM_RANGE(0x3c8000, 0x3c9fff) AM_RAM AM_SHARE("pf1_rowscroll")
AM_RANGE(0x3ca000, 0x3cafff) AM_MIRROR(0x1000) AM_RAM AM_SHARE("pf2_rowscroll")
AM_RANGE(0x3cc000, 0x3ccfff) AM_MIRROR(0x1000) AM_RAM AM_SHARE("pf3_rowscroll")
AM_RANGE(0x3ce000, 0x3cefff) AM_MIRROR(0x1000) AM_RAM AM_SHARE("pf4_rowscroll")
AM_RANGE(0x3d0000, 0x3d07ff) AM_RAM AM_SHARE("spriteram")
AM_RANGE(0x3e0000, 0x3e1fff) AM_MIRROR(0x2000) AM_RAM_DEVWRITE("deco_common", decocomn_device, buffered_palette_w) AM_SHARE("paletteram")
+ADDRESS_MAP_END
+
+static ADDRESS_MAP_START( schmeisr_map, AS_PROGRAM, 16, rohga_state )
+ AM_IMPORT_FROM(hotb_base_map)
AM_RANGE(0xff0000, 0xff7fff) AM_RAM /* Main ram */
ADDRESS_MAP_END
+
+static ADDRESS_MAP_START( hangzo_map, AS_PROGRAM, 16, rohga_state )
+ AM_IMPORT_FROM(hotb_base_map)
+ AM_RANGE(0x3f0000, 0x3f3fff) AM_RAM /* Main ram */
+ADDRESS_MAP_END
+
/******************************************************************************/
static ADDRESS_MAP_START( rohga_sound_map, AS_PROGRAM, 8, rohga_state )
@@ -338,7 +349,7 @@ static INPUT_PORTS_START( rohga )
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_VBLANK("screen")
PORT_START("DSW")
- PORT_DIPNAME( 0x0007, 0x0007, DEF_STR( Coin_A ) )
+ PORT_DIPNAME( 0x0007, 0x0007, DEF_STR( Coin_A ) ) PORT_DIPLOCATION("SW1:1,2,3")
PORT_DIPSETTING( 0x0000, DEF_STR( 3C_1C ) )
PORT_DIPSETTING( 0x0001, DEF_STR( 2C_1C ) )
PORT_DIPSETTING( 0x0007, DEF_STR( 1C_1C ) )
@@ -347,7 +358,7 @@ static INPUT_PORTS_START( rohga )
PORT_DIPSETTING( 0x0004, DEF_STR( 1C_4C ) )
PORT_DIPSETTING( 0x0003, DEF_STR( 1C_5C ) )
PORT_DIPSETTING( 0x0002, DEF_STR( 1C_6C ) )
- PORT_DIPNAME( 0x0038, 0x0038, DEF_STR( Coin_B ) )
+ PORT_DIPNAME( 0x0038, 0x0038, DEF_STR( Coin_B ) ) PORT_DIPLOCATION("SW1:4,5,6")
PORT_DIPSETTING( 0x0000, DEF_STR( 3C_1C ) )
PORT_DIPSETTING( 0x0008, DEF_STR( 2C_1C ) )
PORT_DIPSETTING( 0x0038, DEF_STR( 1C_1C ) )
@@ -356,54 +367,46 @@ static INPUT_PORTS_START( rohga )
PORT_DIPSETTING( 0x0020, DEF_STR( 1C_4C ) )
PORT_DIPSETTING( 0x0018, DEF_STR( 1C_5C ) )
PORT_DIPSETTING( 0x0010, DEF_STR( 1C_6C ) )
- PORT_DIPNAME( 0x0040, 0x0040, DEF_STR( Flip_Screen ) )
+ PORT_DIPNAME( 0x0040, 0x0040, DEF_STR( Flip_Screen ) ) PORT_DIPLOCATION("SW1:7")
PORT_DIPSETTING( 0x0040, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
- PORT_DIPNAME( 0x0080, 0x0080, "2 Credits to Start, 1 to Continue" )
+ PORT_DIPNAME( 0x0080, 0x0080, "2 Credits to Start, 1 to Continue" ) PORT_DIPLOCATION("SW1:8")
PORT_DIPSETTING( 0x0080, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
- PORT_DIPNAME( 0x0100, 0x0100, DEF_STR( Unknown ) )
- PORT_DIPSETTING( 0x0100, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
- PORT_DIPNAME( 0x0200, 0x0200, DEF_STR( Unknown ) )
- PORT_DIPSETTING( 0x0200, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
- PORT_DIPNAME( 0x0400, 0x0400, DEF_STR( Unknown ) )
- PORT_DIPSETTING( 0x0400, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
- PORT_DIPNAME( 0x0800, 0x0800, DEF_STR( Unknown ) )
- PORT_DIPSETTING( 0x0800, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
- PORT_DIPNAME( 0x3000, 0x3000, "Player's Vitality" )
+ PORT_DIPUNUSED_DIPLOC( 0x0100, 0x0100, "SW2:1" ) /* Listed as "Unused" */
+ PORT_DIPUNUSED_DIPLOC( 0x0200, 0x0200, "SW2:2" ) /* Listed as "Unused" */
+ PORT_DIPUNUSED_DIPLOC( 0x0400, 0x0400, "SW2:3" ) /* Listed as "Unused" */
+ PORT_DIPUNUSED_DIPLOC( 0x0800, 0x0800, "SW2:4" ) /* Listed as "Unused" */
+ PORT_DIPNAME( 0x3000, 0x3000, "Player's Vitality" ) PORT_DIPLOCATION("SW2:5,6")
PORT_DIPSETTING( 0x3000, DEF_STR( Normal ) )
PORT_DIPSETTING( 0x2000, DEF_STR( Low ) )
PORT_DIPSETTING( 0x1000, "Lowest" )
PORT_DIPSETTING( 0x0000, DEF_STR( High ) )
- PORT_DIPNAME( 0x4000, 0x4000, DEF_STR( Allow_Continue ) )
+ PORT_DIPNAME( 0x4000, 0x4000, DEF_STR( Allow_Continue ) ) PORT_DIPLOCATION("SW2:7")
PORT_DIPSETTING( 0x4000, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
- PORT_DIPNAME( 0x8000, 0x0000, DEF_STR( Demo_Sounds ) )
+ PORT_DIPNAME( 0x8000, 0x0000, DEF_STR( Demo_Sounds ) ) PORT_DIPLOCATION("SW2:8")
PORT_DIPSETTING( 0x8000, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
PORT_START("DSW3") /* Dip switch bank 3 */
- PORT_DIPNAME( 0x0001, 0x0001, "Stage Clear Bonus" ) /* Life Recovery At stage clear */
+ PORT_DIPNAME( 0x0001, 0x0001, "Stage Clear Bonus" ) PORT_DIPLOCATION("SW3:1") /* Life Recovery At stage clear */
PORT_DIPSETTING( 0x0001, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
- PORT_DIPNAME( 0x0002, 0x0002, DEF_STR( Unknown ) )
+ PORT_DIPNAME( 0x0002, 0x0002, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW3:2")
PORT_DIPSETTING( 0x0002, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
- PORT_DIPNAME( 0x000c, 0x000c, "Enemy's Vitality" )
+ PORT_DIPNAME( 0x000c, 0x000c, "Enemy's Vitality" ) PORT_DIPLOCATION("SW3:3,4")
PORT_DIPSETTING( 0x0008, DEF_STR( Low ) )
PORT_DIPSETTING( 0x000c, DEF_STR( Normal ) )
PORT_DIPSETTING( 0x0004, DEF_STR( High ) )
PORT_DIPSETTING( 0x0000, DEF_STR( Highest ) )
- PORT_DIPNAME( 0x0030, 0x0030, "Enemy Encounter Rate" )
+ PORT_DIPNAME( 0x0030, 0x0030, "Enemy Encounter Rate" ) PORT_DIPLOCATION("SW3:5,6")
PORT_DIPSETTING( 0x0020, DEF_STR( Low ) )
PORT_DIPSETTING( 0x0030, DEF_STR( Normal ) )
PORT_DIPSETTING( 0x0010, DEF_STR( High ) )
PORT_DIPSETTING( 0x0000, DEF_STR( Highest ) )
- PORT_DIPNAME( 0x00c0, 0x00c0, "Enemy's Weapon Speed" )
+ PORT_DIPNAME( 0x00c0, 0x00c0, "Enemy's Weapon Speed" ) PORT_DIPLOCATION("SW3:7,8")
PORT_DIPSETTING( 0x0080, "Slow" )
PORT_DIPSETTING( 0x00c0, DEF_STR( Normal ) )
PORT_DIPSETTING( 0x0040, "Fast" )
@@ -436,7 +439,7 @@ static INPUT_PORTS_START( wizdfire )
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_VBLANK("screen")
PORT_START("DSW")
- PORT_DIPNAME( 0x0007, 0x0007, DEF_STR( Coin_A ) )
+ PORT_DIPNAME( 0x0007, 0x0007, DEF_STR( Coin_A ) ) PORT_DIPLOCATION("SW1:1,2,3")
PORT_DIPSETTING( 0x0000, DEF_STR( 3C_1C ) )
PORT_DIPSETTING( 0x0001, DEF_STR( 2C_1C ) )
PORT_DIPSETTING( 0x0007, DEF_STR( 1C_1C ) )
@@ -445,7 +448,7 @@ static INPUT_PORTS_START( wizdfire )
PORT_DIPSETTING( 0x0004, DEF_STR( 1C_4C ) )
PORT_DIPSETTING( 0x0003, DEF_STR( 1C_5C ) )
PORT_DIPSETTING( 0x0002, DEF_STR( 1C_6C ) )
- PORT_DIPNAME( 0x0038, 0x0038, DEF_STR( Coin_B ) )
+ PORT_DIPNAME( 0x0038, 0x0038, DEF_STR( Coin_B ) ) PORT_DIPLOCATION("SW1:4,5,6")
PORT_DIPSETTING( 0x0000, DEF_STR( 3C_1C ) )
PORT_DIPSETTING( 0x0008, DEF_STR( 2C_1C ) )
PORT_DIPSETTING( 0x0038, DEF_STR( 1C_1C ) )
@@ -454,31 +457,31 @@ static INPUT_PORTS_START( wizdfire )
PORT_DIPSETTING( 0x0020, DEF_STR( 1C_4C ) )
PORT_DIPSETTING( 0x0018, DEF_STR( 1C_5C ) )
PORT_DIPSETTING( 0x0010, DEF_STR( 1C_6C ) )
- PORT_DIPNAME( 0x0040, 0x0040, DEF_STR( Flip_Screen ) )
+ PORT_DIPNAME( 0x0040, 0x0040, DEF_STR( Flip_Screen ) ) PORT_DIPLOCATION("SW1:7")
PORT_DIPSETTING( 0x0040, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
- PORT_DIPNAME( 0x0080, 0x0080, "2 Credits to Start, 1 to Continue" )
+ PORT_DIPNAME( 0x0080, 0x0080, "2 Credits to Start, 1 to Continue" ) PORT_DIPLOCATION("SW1:8")
PORT_DIPSETTING( 0x0080, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
- PORT_DIPNAME( 0x0300, 0x0300, DEF_STR( Lives ) )
+ PORT_DIPNAME( 0x0300, 0x0300, DEF_STR( Lives ) ) PORT_DIPLOCATION("SW2:1,2")
PORT_DIPSETTING( 0x0000, "2" )
PORT_DIPSETTING( 0x0100, "3" )
PORT_DIPSETTING( 0x0300, "4" )
PORT_DIPSETTING( 0x0200, "5" )
- PORT_DIPNAME( 0x0c00, 0x0c00, DEF_STR( Difficulty ) )
+ PORT_DIPNAME( 0x0c00, 0x0c00, DEF_STR( Difficulty ) ) PORT_DIPLOCATION("SW2:3,4")
PORT_DIPSETTING( 0x0800, DEF_STR( Easy ) )
PORT_DIPSETTING( 0x0c00, DEF_STR( Normal ) )
PORT_DIPSETTING( 0x0400, DEF_STR( Hard ) )
PORT_DIPSETTING( 0x0000, DEF_STR( Hardest ) )
- PORT_DIPNAME( 0x3000, 0x3000, "Magic Gauge Speed" )
+ PORT_DIPNAME( 0x3000, 0x3000, "Magic Gauge Speed" ) PORT_DIPLOCATION("SW2:5,6")
PORT_DIPSETTING( 0x0000, "Very Slow" )
PORT_DIPSETTING( 0x1000, "Slow" )
PORT_DIPSETTING( 0x3000, DEF_STR( Normal ) )
PORT_DIPSETTING( 0x2000, "Fast" )
- PORT_DIPNAME( 0x4000, 0x4000, DEF_STR( Unused ) )
+ PORT_DIPNAME( 0x4000, 0x4000, DEF_STR( Unused ) ) PORT_DIPLOCATION("SW2:7")
PORT_DIPSETTING( 0x4000, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
- PORT_DIPNAME( 0x8000, 0x0000, DEF_STR( Demo_Sounds ) )
+ PORT_DIPNAME( 0x8000, 0x0000, DEF_STR( Demo_Sounds ) ) PORT_DIPLOCATION("SW2:8")
PORT_DIPSETTING( 0x8000, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
INPUT_PORTS_END
@@ -509,7 +512,7 @@ static INPUT_PORTS_START( nitrobal )
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_VBLANK("screen")
PORT_START("DSW")
- PORT_DIPNAME( 0x0007, 0x0007, DEF_STR( Coin_A ) )
+ PORT_DIPNAME( 0x0007, 0x0007, DEF_STR( Coin_A ) ) PORT_DIPLOCATION("SW1:1,2,3")
PORT_DIPSETTING( 0x0000, DEF_STR( 3C_1C ) )
PORT_DIPSETTING( 0x0001, DEF_STR( 2C_1C ) )
PORT_DIPSETTING( 0x0007, DEF_STR( 1C_1C ) )
@@ -518,7 +521,7 @@ static INPUT_PORTS_START( nitrobal )
PORT_DIPSETTING( 0x0004, DEF_STR( 1C_4C ) )
PORT_DIPSETTING( 0x0003, DEF_STR( 1C_5C ) )
PORT_DIPSETTING( 0x0002, DEF_STR( 1C_6C ) )
- PORT_DIPNAME( 0x0038, 0x0038, DEF_STR( Coin_B ) )
+ PORT_DIPNAME( 0x0038, 0x0038, DEF_STR( Coin_B ) ) PORT_DIPLOCATION("SW1:4,5,6")
PORT_DIPSETTING( 0x0000, DEF_STR( 3C_1C ) )
PORT_DIPSETTING( 0x0008, DEF_STR( 2C_1C ) )
PORT_DIPSETTING( 0x0038, DEF_STR( 1C_1C ) )
@@ -527,32 +530,32 @@ static INPUT_PORTS_START( nitrobal )
PORT_DIPSETTING( 0x0020, DEF_STR( 1C_4C ) )
PORT_DIPSETTING( 0x0018, DEF_STR( 1C_5C ) )
PORT_DIPSETTING( 0x0010, DEF_STR( 1C_6C ) )
- PORT_DIPNAME( 0x0040, 0x0040, DEF_STR( Flip_Screen ) )
+ PORT_DIPNAME( 0x0040, 0x0040, DEF_STR( Flip_Screen ) ) PORT_DIPLOCATION("SW1:7")
PORT_DIPSETTING( 0x0040, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
- PORT_DIPNAME( 0x0080, 0x0080, "2 Credits to Start, 1 to Continue" )
+ PORT_DIPNAME( 0x0080, 0x0080, "2 Credits to Start, 1 to Continue" ) PORT_DIPLOCATION("SW1:8")
PORT_DIPSETTING( 0x0080, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
- PORT_DIPNAME( 0x0300, 0x0300, DEF_STR( Lives ) )
+ PORT_DIPNAME( 0x0300, 0x0300, DEF_STR( Lives ) ) PORT_DIPLOCATION("SW2:1,2")
PORT_DIPSETTING( 0x0100, "1" )
PORT_DIPSETTING( 0x0000, "2" )
PORT_DIPSETTING( 0x0300, "3" )
PORT_DIPSETTING( 0x0200, "4" )
- PORT_DIPNAME( 0x0c00, 0x0c00, "Difficulty?" )
+ PORT_DIPNAME( 0x0c00, 0x0c00, "Difficulty?" ) PORT_DIPLOCATION("SW2:3,4")
PORT_DIPSETTING( 0x0800, DEF_STR( Easy ) )
PORT_DIPSETTING( 0x0c00, DEF_STR( Normal ) )
PORT_DIPSETTING( 0x0400, DEF_STR( Hard ) )
PORT_DIPSETTING( 0x0000, DEF_STR( Hardest ) )
- PORT_DIPNAME( 0x1000, 0x1000, "Split Coin Chutes" )
+ PORT_DIPNAME( 0x1000, 0x1000, "Split Coin Chutes" ) PORT_DIPLOCATION("SW2:5")
PORT_DIPSETTING( 0x1000, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
- PORT_DIPNAME( 0x2000, 0x2000, DEF_STR( Players) )
+ PORT_DIPNAME( 0x2000, 0x2000, DEF_STR( Players) ) PORT_DIPLOCATION("SW2:6")
PORT_DIPSETTING( 0x2000, "2" )
PORT_DIPSETTING( 0x0000, "3" )
- PORT_DIPNAME( 0x4000, 0x4000, "Shot Button to Start" )
+ PORT_DIPNAME( 0x4000, 0x4000, "Shot Button to Start" ) PORT_DIPLOCATION("SW2:7")
PORT_DIPSETTING( 0x4000, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
- PORT_DIPNAME( 0x8000, 0x0000, DEF_STR( Demo_Sounds ) )
+ PORT_DIPNAME( 0x8000, 0x0000, DEF_STR( Demo_Sounds ) ) PORT_DIPLOCATION("SW2:8")
PORT_DIPSETTING( 0x8000, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
@@ -593,10 +596,10 @@ static INPUT_PORTS_START( schmeisr )
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_VBLANK("screen")
PORT_START("DSW")
- PORT_DIPNAME( 0x0001, 0x0001, DEF_STR( Flip_Screen ) )
+ PORT_DIPNAME( 0x0001, 0x0001, DEF_STR( Flip_Screen ) ) PORT_DIPLOCATION("SW1:1")
PORT_DIPSETTING( 0x0001, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
- PORT_DIPNAME( 0x000e, 0x000e, DEF_STR( Coin_A ) )
+ PORT_DIPNAME( 0x000e, 0x000e, DEF_STR( Coin_A ) ) PORT_DIPLOCATION("SW1:2,3,4")
PORT_DIPSETTING( 0x0000, DEF_STR( 4C_1C ) )
PORT_DIPSETTING( 0x0002, DEF_STR( 3C_1C ) )
PORT_DIPSETTING( 0x0004, DEF_STR( 2C_1C ) )
@@ -605,7 +608,7 @@ static INPUT_PORTS_START( schmeisr )
PORT_DIPSETTING( 0x000a, DEF_STR( 1C_3C ) )
PORT_DIPSETTING( 0x0008, DEF_STR( 1C_4C ) )
PORT_DIPSETTING( 0x0006, DEF_STR( 1C_6C ) )
- PORT_DIPNAME( 0x0070, 0x0070, DEF_STR( Coin_B ) )
+ PORT_DIPNAME( 0x0070, 0x0070, DEF_STR( Coin_B ) ) PORT_DIPLOCATION("SW1:5,6,7")
PORT_DIPSETTING( 0x0000, DEF_STR( 4C_1C ) )
PORT_DIPSETTING( 0x0010, DEF_STR( 3C_1C ) )
PORT_DIPSETTING( 0x0020, DEF_STR( 2C_1C ) )
@@ -614,59 +617,154 @@ static INPUT_PORTS_START( schmeisr )
PORT_DIPSETTING( 0x0050, DEF_STR( 1C_3C ) )
PORT_DIPSETTING( 0x0040, DEF_STR( 1C_4C ) )
PORT_DIPSETTING( 0x0030, DEF_STR( 1C_6C ) )
- PORT_SERVICE( 0x0080, IP_ACTIVE_LOW )
- PORT_DIPNAME( 0x0100, 0x0100, DEF_STR( Unknown ) )
- PORT_DIPSETTING( 0x0100, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
- PORT_DIPNAME( 0x0200, 0x0200, DEF_STR( Unknown ) )
- PORT_DIPSETTING( 0x0200, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
- PORT_DIPNAME( 0x0400, 0x0400, DEF_STR( Demo_Sounds ) )
+ PORT_SERVICE_DIPLOC( 0x0080, IP_ACTIVE_LOW, "SW1:8" )
+ PORT_DIPNAME( 0x0300, 0x0300, DEF_STR( Difficulty ) ) PORT_DIPLOCATION("SW2:1,2")
+ PORT_DIPSETTING( 0x0200, DEF_STR( Easy ) )
+ PORT_DIPSETTING( 0x0300, DEF_STR( Normal ) )
+ PORT_DIPSETTING( 0x0100, DEF_STR( Hard ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( Hardest ) )
+ PORT_DIPNAME( 0x0400, 0x0400, DEF_STR( Demo_Sounds ) ) PORT_DIPLOCATION("SW2:3")
PORT_DIPSETTING( 0x0000, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0400, DEF_STR( On ) )
- PORT_DIPNAME( 0x0800, 0x0800, DEF_STR( Unknown ) )
+ PORT_DIPUNUSED_DIPLOC( 0x0800, 0x0800, "SW2:4" ) /* Listed as "Unused" */
+ PORT_DIPUNUSED_DIPLOC( 0x1000, 0x1000, "SW2:5" ) /* Listed as "Unused" */
+ PORT_DIPUNUSED_DIPLOC( 0x2000, 0x2000, "SW2:6" ) /* Listed as "Unused" */
+ PORT_DIPUNUSED_DIPLOC( 0x4000, 0x4000, "SW2:7" ) /* Listed as "Unused" */
+ PORT_DIPUNUSED_DIPLOC( 0x8000, 0x8000, "SW2:8" ) /* Listed as "Unused" */
+
+ PORT_START("DSW3") /* Dip switch bank 3 - This bank of switches are _NOT_ shown in the test mode screen */
+ PORT_DIPNAME( 0x0001, 0x0001, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW3:1")
+ PORT_DIPSETTING( 0x0001, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x0002, 0x0002, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW3:2")
+ PORT_DIPSETTING( 0x0002, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x0004, 0x0004, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW3:3")
+ PORT_DIPSETTING( 0x0004, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x0008, 0x0008, "Debug Mode" ) PORT_DIPLOCATION("SW3:4")
+ PORT_DIPSETTING( 0x0008, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x0010, 0x0010, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW3:5")
+ PORT_DIPSETTING( 0x0010, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x0020, 0x0020, "Freeze Screen" ) PORT_DIPLOCATION("SW3:6")
+ PORT_DIPSETTING( 0x0020, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x0040, 0x0040, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW3:7")
+ PORT_DIPSETTING( 0x0040, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x0080, 0x0080, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW3:8")
+ PORT_DIPSETTING( 0x0080, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+INPUT_PORTS_END
+
+
+
+static INPUT_PORTS_START( hangzo )
+ PORT_START("INPUTS")
+ PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY
+ PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY
+ PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY
+ PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY
+ PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON1 )
+ PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON2 )
+ PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_BUTTON3 )
+ PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_START1 )
+ PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(2)
+ PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(2)
+ PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(2)
+ PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(2)
+ PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2)
+ PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2)
+ PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(2)
+ PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_START2 )
+
+ PORT_START("SYSTEM")
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN1 )
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_COIN2 )
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_SERVICE1 )
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_VBLANK("screen")
+
+ PORT_START("DSW")
+ PORT_DIPNAME( 0x0007, 0x0007, DEF_STR( Coin_A ) ) PORT_DIPLOCATION("SW1:1,2,3")
+ PORT_DIPSETTING( 0x0000, DEF_STR( 3C_1C ) )
+ PORT_DIPSETTING( 0x0001, DEF_STR( 2C_1C ) )
+ PORT_DIPSETTING( 0x0007, DEF_STR( 1C_1C ) )
+ PORT_DIPSETTING( 0x0006, DEF_STR( 1C_2C ) )
+ PORT_DIPSETTING( 0x0005, DEF_STR( 1C_3C ) )
+ PORT_DIPSETTING( 0x0004, DEF_STR( 1C_4C ) )
+ PORT_DIPSETTING( 0x0003, DEF_STR( 1C_5C ) )
+ PORT_DIPSETTING( 0x0002, DEF_STR( 1C_6C ) )
+ PORT_DIPNAME( 0x0038, 0x0038, DEF_STR( Coin_B ) ) PORT_DIPLOCATION("SW1:4,5,6")
+ PORT_DIPSETTING( 0x0000, DEF_STR( 3C_1C ) )
+ PORT_DIPSETTING( 0x0008, DEF_STR( 2C_1C ) )
+ PORT_DIPSETTING( 0x0038, DEF_STR( 1C_1C ) )
+ PORT_DIPSETTING( 0x0030, DEF_STR( 1C_2C ) )
+ PORT_DIPSETTING( 0x0028, DEF_STR( 1C_3C ) )
+ PORT_DIPSETTING( 0x0020, DEF_STR( 1C_4C ) )
+ PORT_DIPSETTING( 0x0018, DEF_STR( 1C_5C ) )
+ PORT_DIPSETTING( 0x0010, DEF_STR( 1C_6C ) )
+ PORT_DIPNAME( 0x0040, 0x0040, DEF_STR( Flip_Screen ) ) PORT_DIPLOCATION("SW1:7")
+ PORT_DIPSETTING( 0x0040, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x0080, 0x0080, "2 Credits to Start, 1 to Continue" ) PORT_DIPLOCATION("SW1:8")
+ PORT_DIPSETTING( 0x0080, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+
+ PORT_DIPNAME( 0x0300, 0x0300, DEF_STR( Lives ) ) PORT_DIPLOCATION("SW2:1,2")
+ PORT_DIPSETTING( 0x0100, "1" )
+ PORT_DIPSETTING( 0x0000, "2" )
+ PORT_DIPSETTING( 0x0300, "3" )
+ PORT_DIPSETTING( 0x0200, "4" )
+ PORT_DIPNAME( 0x0400, 0x0400, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW2:3") /* Either 3 & 4 are Difficulty */
+ PORT_DIPSETTING( 0x0400, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x0800, 0x0800, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW2:4")
PORT_DIPSETTING( 0x0800, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
- PORT_DIPNAME( 0x1000, 0x1000, DEF_STR( Unknown ) )
+ PORT_DIPNAME( 0x1000, 0x1000, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW2:5") /* or more likely 5 & 6 are Player's Vitality like Rohga (all other dips seem to match Rohga) */
PORT_DIPSETTING( 0x1000, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
- PORT_DIPNAME( 0x2000, 0x2000, DEF_STR( Unknown ) )
+ PORT_DIPNAME( 0x2000, 0x2000, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW2:6")
PORT_DIPSETTING( 0x2000, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
- PORT_DIPNAME( 0x4000, 0x4000, DEF_STR( Unknown ) )
- PORT_DIPSETTING( 0x4000, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
- PORT_DIPNAME( 0x8000, 0x8000, DEF_STR( Unknown ) )
+ PORT_DIPNAME( 0x4000, 0x4000, DEF_STR( Allow_Continue ) ) PORT_DIPLOCATION("SW2:7")
+ PORT_DIPSETTING( 0x0000, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x4000, DEF_STR( On ) )
+ PORT_DIPNAME( 0x8000, 0x0000, DEF_STR( Demo_Sounds ) ) PORT_DIPLOCATION("SW2:8")
PORT_DIPSETTING( 0x8000, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
- PORT_START("DSW3") /* Dip switch bank 3 - This bank of switches are _NOT_ shown in the test mode screen */
- PORT_DIPNAME( 0x0001, 0x0001, DEF_STR( Unknown ) )
+ PORT_START("DSW3")
+ PORT_DIPNAME( 0x0001, 0x0001, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW3:1")
PORT_DIPSETTING( 0x0001, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
- PORT_DIPNAME( 0x0002, 0x0002, DEF_STR( Unknown ) )
+ PORT_DIPNAME( 0x0002, 0x0002, "Freeze Player" ) PORT_DIPLOCATION("SW3:2") /* With on, player will not fall down to playing field and be stuck floating at the top of the screen */
PORT_DIPSETTING( 0x0002, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
- PORT_DIPNAME( 0x0004, 0x0004, DEF_STR( Unknown ) )
+ PORT_DIPNAME( 0x0004, 0x0004, "Freeze Frame" ) PORT_DIPLOCATION("SW3:3") /* P1 starts & stops freeze, when frozen P2 is single step frame */
PORT_DIPSETTING( 0x0004, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
- PORT_DIPNAME( 0x0008, 0x0008, "Debug Mode" )
+ PORT_DIPNAME( 0x0008, 0x0008, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW3:4")
PORT_DIPSETTING( 0x0008, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
- PORT_DIPNAME( 0x0010, 0x0010, DEF_STR( Unknown ) )
+ PORT_DIPNAME( 0x0010, 0x0010, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW3:5")
PORT_DIPSETTING( 0x0010, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
- PORT_DIPNAME( 0x0020, 0x0020, "Freeze Screen" )
+ PORT_DIPNAME( 0x0020, 0x0020, "Freeze Screen" ) PORT_DIPLOCATION("SW3:6")
PORT_DIPSETTING( 0x0020, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
- PORT_DIPNAME( 0x0040, 0x0040, DEF_STR( Unknown ) )
+ PORT_DIPNAME( 0x0040, 0x0040, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW3:7")
PORT_DIPSETTING( 0x0040, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
- PORT_DIPNAME( 0x0080, 0x0080, DEF_STR( Unknown ) )
+ PORT_DIPNAME( 0x0080, 0x0080, "Debug Mode" ) PORT_DIPLOCATION("SW3:8")
PORT_DIPSETTING( 0x0080, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
INPUT_PORTS_END
+
+
/**********************************************************************************/
static const gfx_layout charlayout =
@@ -1090,7 +1188,7 @@ static MACHINE_CONFIG_START( schmeisr, rohga_state )
MCFG_DEVICE_ADD("tilegen1", DECO16IC, 0)
MCFG_DECO16IC_SPLIT(0)
- MCFG_DECO16IC_WIDTH12(1)
+ MCFG_DECO16IC_WIDTH12(1|4)
MCFG_DECO16IC_PF1_TRANS_MASK(0x0f)
MCFG_DECO16IC_PF2_TRANS_MASK(0x0f)
MCFG_DECO16IC_PF1_COL_BANK(0x00)
@@ -1146,6 +1244,16 @@ static MACHINE_CONFIG_START( schmeisr, rohga_state )
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 0.40)
MACHINE_CONFIG_END
+
+
+static MACHINE_CONFIG_DERIVED( hangzo, schmeisr )
+
+ /* basic machine hardware */
+ MCFG_CPU_MODIFY("maincpu")
+ MCFG_CPU_PROGRAM_MAP(hangzo_map)
+MACHINE_CONFIG_END
+
+
/**********************************************************************************/
ROM_START( rohga ) /* Asia/Europe v5.0 */
@@ -1414,6 +1522,7 @@ ROM_START( wolffang ) /* Japan */
ROM_LOAD( "hb-00.11p", 0x00000, 0x200, CRC(b7a7baad) SHA1(39781c3412493b985d3616ac31142fc00bbcddf4) ) /* ? */
ROM_END
+
ROM_START( wizdfire )
ROM_REGION(0x200000, "maincpu", 0 ) /* 68000 code */
ROM_LOAD16_BYTE( "je-01.3d", 0x000000, 0x20000, CRC(b6d62367) SHA1(e9521b28660f62b70e6e33c3e9cf345fc106eff6) ) /* Version 2.1 Over Sea */
@@ -1686,6 +1795,7 @@ ROM_START( gunball )
ROM_LOAD( "jn-00.17l", 0x00000, 0x400, CRC(6ac77b84) SHA1(9e1e2cabdb20b819e592a0f07d15658062227fa4) ) /* Priority (unused) */
ROM_END
+
ROM_START( schmeisr )
ROM_REGION(0x100000, "maincpu", 0 ) /* 68000 code */
ROM_LOAD16_BYTE( "sr001j.8a", 0x000000, 0x80000, CRC(ed31f3ff) SHA1(3e0ae92a07ef94f377730c19069560bda864a64b) )
@@ -1721,6 +1831,49 @@ ROM_START( schmeisr )
ROM_LOAD( "hb-00.11p", 0x00000, 0x200, CRC(b7a7baad) SHA1(39781c3412493b985d3616ac31142fc00bbcddf4) )
ROM_END
+
+ROM_START( hangzo ) /* Found on a Data East DE-0353-3 PCB */
+ ROM_REGION(0x200000, "maincpu", 0 ) /* 68000 code */
+ ROM_LOAD16_BYTE( "Pro0H 12.18.2A.27C1001", 0x000000, 0x20000, CRC(ac8087db) SHA1(518193372cde6024fda96c6ed1862245e0bfb465) )
+ ROM_LOAD16_BYTE( "Pro0H 12.18.2D.27C1001", 0x000001, 0x20000, CRC(a6b7f4f4) SHA1(1b3a00ef124d130317171d9042018fbb30662fec) )
+ ROM_LOAD16_BYTE( "Pro1H 12.10.4A.27C010", 0x040000, 0x20000, CRC(0d04f43d) SHA1(167b595450f6f9b842dc909f6c61a96fa34b7991) )
+ ROM_LOAD16_BYTE( "Pro1L 12.10.4D.27C010", 0x040001, 0x20000, CRC(2e323918) SHA1(f3d9168f395e835b075dfcbb0464770044d350f3) )
+ ROM_LOAD16_BYTE( "Pro2H 12.10.6A.27C010", 0x080000, 0x20000, CRC(bb3185a6) SHA1(fa4ba7b4b53a5b3486c36441463a290b12c2acbe) )
+ ROM_LOAD16_BYTE( "Pro2L 12.10.6D.27C010", 0x080001, 0x20000, CRC(11ce97bb) SHA1(d9c1872762f9acaeed1ebc640a71fa7a4b9d013c) )
+
+ ROM_REGION(0x10000, "audiocpu", 0 ) /* Sound CPU */
+ ROM_LOAD( "SND 12.18.18P.27C512", 0x00000, 0x10000, CRC(97c592dc) SHA1(7a0e08f3ffd42d07d1d0a9db52c7fd85dba28bd8) )
+
+ ROM_REGION( 0x040000, "gfx1", ROMREGION_ERASEFF )
+ /* filled in later */
+
+ ROM_REGION( 0x100000, "gfx2", 0 )
+ ROM_LOAD( "BK1L 12.10.9A.574200", 0x000000, 0x080000, CRC(5199729b) SHA1(1cb8e7b91e5d0b3a699e47b6bbb3e6e9c53c8590) ) /* Encrypted tiles */
+ ROM_LOAD( "BK1H 12.10.11A.574200", 0x080000, 0x080000, CRC(85887bd8) SHA1(6cb6f9c9e6e5824c6b8006ab195f27014031907e) )
+
+ ROM_REGION( 0x200000, "gfx3", 0 )
+ ROM_LOAD( "BK23L 12.10.17D.574200", 0x000000, 0x080000, CRC(ed4e47c6) SHA1(b09ed1a6bf1b42139c7817bae18cd5580c42cf91) ) /* tiles 1 & 2 */
+ ROM_LOAD( "BK23H 12.10.18D.574200", 0x100000, 0x080000, CRC(6a725fb2) SHA1(f4da4da62eb7e3ec2f1a54b57eaf94dc748dec68) )
+
+ ROM_REGION( 0x400000, "gfx4", 0 )
+ ROM_LOAD( "OBJ01L 12.10.19A.27C4000", 0x000000, 0x080000, CRC(c141e310) SHA1(81eb0b977aaf44a110a663416e385ca617de8f28) ) /* 6bpp sprites */
+ ROM_LOAD( "OBJ01H 12.10.20A.27C4000", 0x100000, 0x080000, CRC(6a7b4252) SHA1(4bd588bc96c07cc9367afdeab4976af6f8dcc823) )
+ ROM_LOAD( "OBJ23L 12.10.19D.27C4000", 0x200000, 0x080000, CRC(0db6df6c) SHA1(fe7ef7b5a279656d9e46334c4833ab8911caa5db) )
+ ROM_LOAD( "OBJ23H 12.10.20D.27C4000", 0x300000, 0x080000, CRC(165031a1) SHA1(0e88fe45fd78d352fdbd398c1d98feefe1b43917) )
+
+ ROM_REGION(0x80000, "oki2", 0 ) /* Oki samples */
+ ROM_LOAD( "PCM16K 11.5.14P.574000", 0x00000, 0x80000, CRC(5b95c6c7) SHA1(587e7f87d085af3a5d24f317fffc1716c8027e43) )
+
+ ROM_REGION(0x80000, "oki1", 0 ) /* Oki samples */
+ ROM_LOAD( "PCM8K 11.5.15P.27C020", 0x00000, 0x40000, CRC(02682a9a) SHA1(914ffc7c16e90c1ac28a228df415a956684f8192) )
+
+ ROM_REGION( 512, "proms", ROMREGION_ERASEFF )
+ ROM_LOAD( "hb-00.11p", 0x00000, 0x200, CRC(b7a7baad) SHA1(39781c3412493b985d3616ac31142fc00bbcddf4) ) /* ? */
+ROM_END
+
+
+
+
/**********************************************************************************/
DRIVER_INIT_MEMBER(rohga_state,rohga)
@@ -1755,6 +1908,15 @@ DRIVER_INIT_MEMBER(rohga_state,schmeisr)
deco74_decrypt_gfx(machine(), "gfx2");
}
+DRIVER_INIT_MEMBER(rohga_state,hangzo)
+{
+ const uint8_t *src = memregion("gfx2")->base();
+ uint8_t *dst = memregion("gfx1")->base();
+
+ memcpy(dst, src, 0x20000);
+ memcpy(dst + 0x20000, src + 0x80000, 0x20000);
+}
+
GAME( 1991, rohga, 0, rohga, rohga, rohga_state, rohga, ROT0, "Data East Corporation", "Rohga Armor Force (Asia/Europe v5.0)", MACHINE_SUPPORTS_SAVE )
GAME( 1991, rohga1, rohga, rohga, rohga, rohga_state, rohga, ROT0, "Data East Corporation", "Rohga Armor Force (Asia/Europe v3.0 set 1)", MACHINE_SUPPORTS_SAVE )
GAME( 1991, rohga2, rohga, rohga, rohga, rohga_state, rohga, ROT0, "Data East Corporation", "Rohga Armor Force (Asia/Europe v3.0 set 2)", MACHINE_SUPPORTS_SAVE )
@@ -1771,3 +1933,4 @@ GAME( 1992, nitrobala, nitrobal, nitrobal, nitrobal, rohga_state, nitrobal, ROT2
GAME( 1992, gunball, nitrobal, nitrobal, nitrobal, rohga_state, nitrobal, ROT270, "Data East Corporation", "Gun Ball (Japan)", MACHINE_SUPPORTS_SAVE )
GAME( 1993, schmeisr, 0, schmeisr, schmeisr, rohga_state, schmeisr, ROT0, "Hot-B", "Schmeiser Robo (Japan)", MACHINE_SUPPORTS_SAVE | MACHINE_NO_COCKTAIL )
+GAME( 1992, hangzo, 0, hangzo, hangzo, rohga_state, hangzo, ROT0, "Hot-B", "Hangzo (Japan, prototype)", MACHINE_SUPPORTS_SAVE ) // ROM contains a '(c)1992 Data East Corporation' string, but other sources indicate the game is by Hot-B
diff --git a/src/mame/drivers/slapfght.cpp b/src/mame/drivers/slapfght.cpp
index 65520599436..ee1b1118165 100644
--- a/src/mame/drivers/slapfght.cpp
+++ b/src/mame/drivers/slapfght.cpp
@@ -290,11 +290,15 @@ static ADDRESS_MAP_START( tigerh_map, AS_PROGRAM, 8, slapfght_state )
AM_RANGE(0xe800, 0xe800) AM_WRITE(scrollx_lo_w)
AM_RANGE(0xe801, 0xe801) AM_WRITE(scrollx_hi_w)
AM_RANGE(0xe802, 0xe802) AM_WRITE(scrolly_w)
- AM_RANGE(0xe803, 0xe803) AM_READWRITE(tigerh_mcu_r, tigerh_mcu_w)
AM_RANGE(0xf000, 0xf7ff) AM_RAM_WRITE(fixram_w) AM_SHARE("fixvideoram")
AM_RANGE(0xf800, 0xffff) AM_RAM_WRITE(fixcol_w) AM_SHARE("fixcolorram")
ADDRESS_MAP_END
+static ADDRESS_MAP_START( tigerh_map_mcu, AS_PROGRAM, 8, slapfght_state )
+ AM_RANGE(0xe803, 0xe803) AM_DEVREADWRITE("bmcu", taito68705_mcu_device, mcu_r, mcu_w)
+ AM_IMPORT_FROM( tigerh_map )
+ADDRESS_MAP_END
+
static ADDRESS_MAP_START( tigerhb1_map, AS_PROGRAM, 8, slapfght_state )
AM_RANGE(0xe803, 0xe803) AM_READWRITE(tigerhb1_prot_r, tigerhb1_prot_w)
AM_IMPORT_FROM( tigerh_map )
@@ -317,11 +321,15 @@ static ADDRESS_MAP_START( slapfigh_map, AS_PROGRAM, 8, slapfght_state )
AM_RANGE(0xe800, 0xe800) AM_WRITE(scrollx_lo_w)
AM_RANGE(0xe801, 0xe801) AM_WRITE(scrollx_hi_w)
AM_RANGE(0xe802, 0xe802) AM_WRITE(scrolly_w)
- AM_RANGE(0xe803, 0xe803) AM_READWRITE(tigerh_mcu_r, tigerh_mcu_w)
AM_RANGE(0xf000, 0xf7ff) AM_RAM_WRITE(fixram_w) AM_SHARE("fixvideoram")
AM_RANGE(0xf800, 0xffff) AM_RAM_WRITE(fixcol_w) AM_SHARE("fixcolorram")
ADDRESS_MAP_END
+static ADDRESS_MAP_START( slapfigh_map_mcu, AS_PROGRAM, 8, slapfght_state )
+ AM_RANGE(0xe803, 0xe803) AM_DEVREADWRITE("bmcu", taito68705_mcu_device, mcu_r, mcu_w)
+ AM_IMPORT_FROM( slapfigh_map )
+ADDRESS_MAP_END
+
static ADDRESS_MAP_START( slapfighb1_map, AS_PROGRAM, 8, slapfght_state )
AM_RANGE(0xe803, 0xe803) AM_NOP // no MCU
AM_IMPORT_FROM( slapfigh_map )
@@ -733,13 +741,7 @@ void slapfght_state::machine_start()
m_main_irq_enabled = false;
m_sound_nmi_enabled = false;
- m_mcu_sent = false;
- m_main_sent = false;
- m_from_main = 0;
- m_from_mcu = 0;
- m_from_mcu_latch = 0;
- m_to_mcu_latch = 0;
- m_old_portB = 0;
+
m_getstar_status = 0;
m_getstar_sequence_index = 0;
@@ -758,14 +760,6 @@ void slapfght_state::machine_start()
save_item(NAME(m_main_irq_enabled));
save_item(NAME(m_sound_nmi_enabled));
- save_item(NAME(m_mcu_sent));
- save_item(NAME(m_main_sent));
- save_item(NAME(m_from_main));
- save_item(NAME(m_from_mcu));
-
- save_item(NAME(m_from_mcu_latch));
- save_item(NAME(m_to_mcu_latch));
- save_item(NAME(m_old_portB));
save_item(NAME(m_getstar_status));
save_item(NAME(m_getstar_sequence_index));
@@ -791,7 +785,7 @@ void slapfght_state::machine_reset()
MACHINE_RESET_MEMBER(slapfght_state,getstar)
{
// don't boot the mcu since we don't have a dump yet
- m_mcu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE);
+// m_mcu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE);
machine_reset();
}
@@ -978,7 +972,7 @@ static MACHINE_CONFIG_START( tigerh, slapfght_state )
/* basic machine hardware */
MCFG_CPU_ADD("maincpu", Z80, XTAL_36MHz/6) // 6MHz
- MCFG_CPU_PROGRAM_MAP(tigerh_map)
+ MCFG_CPU_PROGRAM_MAP(tigerh_map_mcu)
MCFG_CPU_IO_MAP(tigerh_io_map)
MCFG_CPU_VBLANK_INT_DRIVER("screen", slapfght_state, vblank_irq)
@@ -986,13 +980,7 @@ static MACHINE_CONFIG_START( tigerh, slapfght_state )
MCFG_CPU_PROGRAM_MAP(tigerh_sound_map)
MCFG_CPU_PERIODIC_INT_DRIVER(slapfght_state, sound_nmi, 360) // music speed, verified with pcb recording
- MCFG_CPU_ADD("mcu", M68705_NEW, XTAL_36MHz/12) // 3MHz
- MCFG_M68705_PORTA_R_CB(READ8(slapfght_state, tigerh_mcu_porta_r))
- MCFG_M68705_PORTA_W_CB(WRITE8(slapfght_state, tigerh_mcu_porta_w))
- MCFG_M68705_PORTB_W_CB(WRITE8(slapfght_state, tigerh_mcu_portb_w))
- MCFG_M68705_PORTC_R_CB(READ8(slapfght_state, tigerh_mcu_portc_r))
-
-
+ MCFG_DEVICE_ADD("bmcu", TAITO68705_MCU_TIGER, XTAL_36MHz/12) // 3MHz
MCFG_QUANTUM_PERFECT_CPU("maincpu")
@@ -1033,7 +1021,7 @@ static MACHINE_CONFIG_DERIVED( tigerhb1, tigerh )
MCFG_CPU_PROGRAM_MAP(tigerhb1_map)
MCFG_CPU_IO_MAP(tigerhb_io_map)
- MCFG_DEVICE_REMOVE("mcu")
+ MCFG_DEVICE_REMOVE("bmcu")
MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( tigerhb2, tigerhb1 )
@@ -1048,7 +1036,7 @@ static MACHINE_CONFIG_START( slapfigh, slapfght_state )
/* basic machine hardware */
MCFG_CPU_ADD("maincpu",Z80, XTAL_36MHz/6) // 6MHz
- MCFG_CPU_PROGRAM_MAP(slapfigh_map)
+ MCFG_CPU_PROGRAM_MAP(slapfigh_map_mcu)
MCFG_CPU_IO_MAP(slapfigh_io_map)
MCFG_CPU_VBLANK_INT_DRIVER("screen", slapfght_state, vblank_irq)
@@ -1056,11 +1044,8 @@ static MACHINE_CONFIG_START( slapfigh, slapfght_state )
MCFG_CPU_PROGRAM_MAP(tigerh_sound_map)
MCFG_CPU_PERIODIC_INT_DRIVER(slapfght_state, sound_nmi, 180)
- MCFG_CPU_ADD("mcu", M68705_NEW, XTAL_36MHz/12) // 3MHz
- MCFG_M68705_PORTA_R_CB(READ8(slapfght_state, tigerh_mcu_porta_r))
- MCFG_M68705_PORTA_W_CB(WRITE8(slapfght_state, tigerh_mcu_porta_w))
- MCFG_M68705_PORTB_W_CB(WRITE8(slapfght_state, slapfght_mcu_portb_w))
- MCFG_M68705_PORTC_R_CB(READ8(slapfght_state, slapfght_mcu_portc_r))
+ MCFG_DEVICE_ADD("bmcu", TAITO68705_MCU_SLAP, XTAL_36MHz/12) // 3MHz
+ MCFG_TAITO_M68705_EXTENSION_CB(WRITE8(slapfght_state, scroll_from_mcu_w))
MCFG_QUANTUM_PERFECT_CPU("maincpu")
@@ -1101,7 +1086,7 @@ static MACHINE_CONFIG_DERIVED( slapfighb1, slapfigh )
MCFG_CPU_PROGRAM_MAP(slapfighb1_map)
MCFG_CPU_IO_MAP(slapfighb1_io_map)
- MCFG_DEVICE_REMOVE("mcu")
+ MCFG_DEVICE_REMOVE("bmcu")
MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( slapfighb2, slapfighb1 )
@@ -1118,6 +1103,9 @@ static MACHINE_CONFIG_DERIVED( getstar, slapfigh )
MCFG_CPU_PROGRAM_MAP(getstar_map)
MCFG_CPU_IO_MAP(getstar_io_map)
+ MCFG_DEVICE_MODIFY("bmcu:mcu")
+ MCFG_DEVICE_DISABLE()
+
MCFG_MACHINE_RESET_OVERRIDE(slapfght_state, getstar)
MACHINE_CONFIG_END
@@ -1302,7 +1290,7 @@ ROM_START( tigerh )
ROM_REGION( 0x10000, "audiocpu", 0 )
ROM_LOAD( "a47_03.12d", 0x0000, 0x2000, CRC(d105260f) SHA1(f6a0e393e29354bb37fb723828f3267d030a45ea) )
- ROM_REGION( 0x0800, "mcu", 0 )
+ ROM_REGION( 0x0800, "bmcu:mcu", 0 )
ROM_LOAD( "a47_14.6a", 0x0000, 0x0800, CRC(4042489f) SHA1(b977e0821b6b1aa5a0a0f349cd78150af1a231df) )
ROM_REGION( 0x04000, "gfx1", 0 )
@@ -1339,7 +1327,7 @@ ROM_START( tigerhj )
ROM_REGION( 0x10000, "audiocpu", 0 )
ROM_LOAD( "a47_03.12d", 0x0000, 0x2000, CRC(d105260f) SHA1(f6a0e393e29354bb37fb723828f3267d030a45ea) )
- ROM_REGION( 0x0800, "mcu", 0 )
+ ROM_REGION( 0x0800, "bmcu:mcu", 0 )
ROM_LOAD( "a47_14.6a", 0x0000, 0x0800, CRC(4042489f) SHA1(b977e0821b6b1aa5a0a0f349cd78150af1a231df) )
ROM_REGION( 0x04000, "gfx1", 0 )
@@ -1561,7 +1549,7 @@ ROM_START( alcon )
ROM_REGION( 0x10000, "audiocpu", 0 )
ROM_LOAD( "a77_02.12d", 0x0000, 0x2000, CRC(87f4705a) SHA1(a90d5644ce268f3321047a4f96df96ac294d2f1b) )
- ROM_REGION( 0x0800, "mcu", 0 )
+ ROM_REGION( 0x0800, "bmcu:mcu", 0 )
ROM_LOAD( "a77_13.6a", 0x0000, 0x0800, CRC(a70c81d9) SHA1(f155ffd25a946b0459216a8f80ded16e6e2f9258) )
ROM_REGION( 0x04000, "gfx1", 0 )
@@ -1595,7 +1583,7 @@ ROM_START( slapfigh )
ROM_REGION( 0x10000, "audiocpu", 0 )
ROM_LOAD( "a77_02.12d", 0x0000, 0x2000, CRC(87f4705a) SHA1(a90d5644ce268f3321047a4f96df96ac294d2f1b) )
- ROM_REGION( 0x0800, "mcu", 0 ) /* 2k for the microcontroller */
+ ROM_REGION( 0x0800, "bmcu:mcu", 0 ) /* 2k for the microcontroller */
ROM_LOAD( "a77_13.6a", 0x0000, 0x0800, CRC(a70c81d9) SHA1(f155ffd25a946b0459216a8f80ded16e6e2f9258) )
ROM_REGION( 0x04000, "gfx1", 0 )
@@ -1637,7 +1625,7 @@ ROM_START( slapfigha )
ROM_REGION( 0x10000, "audiocpu", 0 )
ROM_LOAD( "a76_03.12d", 0x0000, 0x2000, CRC(87f4705a) SHA1(a90d5644ce268f3321047a4f96df96ac294d2f1b) )
- ROM_REGION( 0x0800, "mcu", 0 )
+ ROM_REGION( 0x0800, "bmcu:mcu", 0 )
ROM_LOAD( "a76_14.6a", 0x0000, 0x0800, NO_DUMP ) /* A77 MCU not compatible with this set */
ROM_REGION( 0x04000, "gfx1", 0 )
@@ -1899,7 +1887,7 @@ ROM_START( grdian )
ROM_REGION( 0x10000, "audiocpu", 0 ) /* Region 3 - sound cpu code */
ROM_LOAD( "a68-03.12d", 0x0000, 0x2000, CRC(18daa44c) SHA1(1a3d22a186c591321d1b836ee30d89fba4771122) )
- ROM_REGION( 0x0800, "mcu", 0 ) /* 2k for the microcontroller */
+ ROM_REGION( 0x0800, "bmcu:mcu", 0 ) /* 2k for the microcontroller */
ROM_LOAD( "a68_14.6a", 0x0000, 0x0800, NO_DUMP )
ROM_REGION( 0x04000, "gfx1", 0 ) /* Region 1 - temporary for gfx */
@@ -1933,7 +1921,7 @@ ROM_START( getstarj )
ROM_REGION( 0x10000, "audiocpu", 0 ) /* Region 3 - sound cpu code */
ROM_LOAD( "a68-03.12d", 0x00000, 0x2000, CRC(18daa44c) SHA1(1a3d22a186c591321d1b836ee30d89fba4771122) )
- ROM_REGION( 0x0800, "mcu", 0 ) /* 2k for the microcontroller */
+ ROM_REGION( 0x0800, "bmcu:mcu", 0 ) /* 2k for the microcontroller */
ROM_LOAD( "68705.6a", 0x0000, 0x0800, NO_DUMP )
ROM_REGION( 0x04000, "gfx1", 0 ) /* Region 1 - temporary for gfx */
diff --git a/src/mame/drivers/stv.cpp b/src/mame/drivers/stv.cpp
index 1cffadd6639..30dd4ec6e68 100644
--- a/src/mame/drivers/stv.cpp
+++ b/src/mame/drivers/stv.cpp
@@ -2833,16 +2833,11 @@ ROM_START( choroqhr ) // set to 1p
ROM_LOAD16_WORD_SWAP( "ic28.bin", 0x0800000, 0x200000, CRC(3c949563) SHA1(ab2a9f9ec23071cc236dee945b436a9cd73efb92) )
ROM_LOAD16_WORD_SWAP( "ic30.bin", 0x0a00000, 0x200000, CRC(7e93078d) SHA1(10fa99029a3e741ea0fddcf00ee07b5fd039bf19) )
ROM_LOAD16_WORD_SWAP( "ic32.bin", 0x0c00000, 0x200000, CRC(86cdcbd8) SHA1(90060cde84c75fd4146ebf6b9101f04140408e88) )
- //ROM_LOAD16_WORD_SWAP( "ic32.bad2.bin", 0x000000, 0x200000, CRC(76709d73) SHA1(a7805e956ee1a3701a803d0af082c33c89c26c3a) )
- //ROM_LOAD16_WORD_SWAP( "ic32.bad3.bin", 0x000000, 0x200000, CRC(b873cf3e) SHA1(8ed42a229e416125d7a2359faaea17208324feb0) )
- //ROM_LOAD16_WORD_SWAP( "ic32.bad4.bin", 0x000000, 0x200000, CRC(ed808ad4) SHA1(b00791ec3ee6255bccde171279a1a14e322d0e6d) )
- //ROM_LOAD16_WORD_SWAP( "ic32.bad5.bin", 0x000000, 0x200000, CRC(ed808ad4) SHA1(b00791ec3ee6255bccde171279a1a14e322d0e6d) )
- //ROM_LOAD16_WORD_SWAP( "ic32.bad6.bin", 0x000000, 0x200000, CRC(ed808ad4) SHA1(b00791ec3ee6255bccde171279a1a14e322d0e6d) )
ROM_LOAD16_WORD_SWAP( "ic34.bin", 0x0e00000, 0x200000, CRC(be2ed0a0) SHA1(a9225ba6b78fa0119fc6484828f4d4cc6ea05d8f) )
ROM_LOAD16_WORD_SWAP( "ic36.bin", 0x1000000, 0x200000, CRC(9a4109e5) SHA1(ba59caac5f5a80fc52c507d8a47f322a380aa9a1) )
- ROM_REGION16_BE( 0x80, "eeprom", 0 ) // preconfigured to 1 player
- ROM_LOAD( "choroqhr.nv", 0x0000, 0x0080, CRC(69a71aea) SHA1(08ca9cd70fa3fa6c3156edd966a81244bad5f0c2) )
+ ROM_REGION16_BE( 0x80, "eeprom", ROMREGION_ERASE00 ) // preconfigured to 1 player
+ ROM_LOAD( "choroqhr.nv", 0x0000, 0x0080, CRC(6e89815f) SHA1(4478f614fb61859f4ee7bf55462f737387887e6f) )
ROM_END
ROM_START( pclub2 ) // set to 1p / runs with the USA bios
@@ -3034,7 +3029,7 @@ ROM_START( prc28su ) // set to 1p
ROM_LOAD( "eeprom", 0x0000, 0x0080, CRC(447bb3bd) SHA1(9fefec09849bfa0c14b49e73ff13e2a538dff511) )
ROM_END
-// this is the first one to offer visual display of the frames in the Frame Coun test menu?
+// this is the first one to offer visual display of the frames in the Frame Count test menu?
ROM_START( prc29au ) // set to 1p
STV_BIOS
@@ -3057,19 +3052,19 @@ ROM_END
-ROM_START( prc2ksu ) // set to 1p (this dump is too damaged to even run the ROM tests properly)
+ROM_START( prc2ksu ) // set to 1p
STV_BIOS
ROM_REGION32_BE( 0x3000000, "cart", ROMREGION_ERASE00 ) /* SH2 code */
-
- // NOTE: Game fails IC7 check, might be okay, might not be - supposedly ST-V print carts are known to have bad ROM tests(?)
- ROM_LOAD16_WORD_SWAP( "ic22.bin", 0x0200000, 0x0200000, CRC(4b3de7df) SHA1(869c3840ac2eab263bb8b79ba1430e5789fa5758) )
- ROM_LOAD16_WORD_SWAP( "ic24.bin", 0x0400000, 0x0200000, BAD_DUMP CRC(02da49b7) SHA1(dd19bfd6c21f432b3af011ce43ba38d295c06c6d) ) // (maybe bad, maybe good, consistent read at least)
- ROM_LOAD16_WORD_SWAP( "ic26.bin", 0x0600000, 0x0200000, BAD_DUMP CRC(a431d614) SHA1(75de91d8eff5af7e1b668012a0613884ba660e21) ) // (maybe bad, maybe good, consistent read at least)
- ROM_LOAD16_WORD_SWAP( "ic28.bin", 0x0800000, 0x0200000, CRC(c0fba1a5) SHA1(5f98be1eed5f74e62fe5a3e33fdcf3b827dda1a7) )
- ROM_LOAD16_WORD_SWAP( "ic30.bin", 0x0a00000, 0x0200000, CRC(0811d0e4) SHA1(b4fd9369c80f76141ae2fb38525b405b4c2f391a) )
+ // NOTE: Game fails IC7 check but rom read consistently, might be okay, might not be - supposedly ST-V print carts are known to have bad ROM tests(?)
+ ROM_LOAD16_WORD_SWAP( "ic22.bin", 0x0200000, 0x0200000, CRC(4b3de7df) SHA1(869c3840ac2eab263bb8b79ba1430e5789fa5758) ) // 'BAD' (tested as IC7) (but maybe OK)
+ ROM_LOAD16_WORD_SWAP( "ic24.bin", 0x0400000, 0x0200000, CRC(02da49b7) SHA1(dd19bfd6c21f432b3af011ce43ba38d295c06c6d) ) // OK (tested as IC2)
+ ROM_LOAD16_WORD_SWAP( "ic26.bin", 0x0600000, 0x0200000, CRC(a431d614) SHA1(75de91d8eff5af7e1b668012a0613884ba660e21) ) // OK (tested as IC2)
+ ROM_LOAD16_WORD_SWAP( "ic28.bin", 0x0800000, 0x0200000, CRC(c0fba1a5) SHA1(5f98be1eed5f74e62fe5a3e33fdcf3b827dda1a7) ) // OK (tested as IC3)
+ ROM_LOAD16_WORD_SWAP( "ic30.bin", 0x0a00000, 0x0200000, CRC(0811d0e4) SHA1(b4fd9369c80f76141ae2fb38525b405b4c2f391a) ) // OK (tested as IC3)
ROM_REGION16_BE( 0x80, "eeprom", ROMREGION_ERASE00 ) // preconfigured to 1 player
+ ROM_LOAD( "prc2ksu.nv", 0x0000, 0x0080, CRC(ee7ffdc5) SHA1(4008e37cae306c0202146c5dd79ca925b8d8edd5) )
ROM_END
@@ -3447,16 +3442,15 @@ GAME( 1997, pckobe99, stvbios, stv, stv, stv_state, stv, ROT0
GAME( 1997, pclub26w, stvbios, stv, stv, stv_state, stv, ROT0, "Atlus", "Print Club 2 Vol. 6 Winter (J 961210 V1.000)", MACHINE_NOT_WORKING ) // internal string is 'PURIKURA2 97FUYU' (but in reality it seems to be an end of 96 Winter version)
GAME( 1997, pclub26wa, pclub26w,stv, stv, stv_state, stv, ROT0, "Atlus", "Print Club 2 Vol. 6 Winter (J 970121 V1.200)", MACHINE_NOT_WORKING ) // ^
GAME( 1997, pclub27s, stvbios, stv, stv, stv_state, stv, ROT0, "Atlus", "Print Club 2 Vol. 7 Spring (J 970313 V1.100)", MACHINE_NOT_WORKING )
-GAME( 1997, prc28su, stvbios, stv, stv, stv_state, stv, ROT0, "Atlus", "Print Club 2 Vol. 8 Summer (J 970616 V1.100)", MACHINE_NOT_WORKING ) // internal string 97SUMMER *** BAD DUMP ***
+GAME( 1997, prc28su, stvbios, stv, stv, stv_state, stv, ROT0, "Atlus", "Print Club 2 Vol. 8 Summer (J 970616 V1.100)", MACHINE_NOT_WORKING ) // internal string 97SUMMER
GAME( 1997, prc29au, stvbios, stv, stv, stv_state, stv, ROT0, "Atlus", "Print Club 2 Vol. 9 Autumn (J V1.100)", MACHINE_NOT_WORKING ) // internal string 97AUTUMN, no date code! (all 0)
GAME( 1997, prc297wi, stvbios, stv, stv, stv_state, stv, ROT0, "Atlus", "Print Club 2 '97 Winter Ver (J 971017 V1.100, set 1)", MACHINE_NOT_WORKING ) // internal string is '97WINTER'
GAME( 1997, prc297wia, prc297wi,stv, stv, stv_state, stv, ROT0, "Atlus", "Print Club 2 '97 Winter Ver (J 971017 V1.100, set 2)", MACHINE_NOT_WORKING ) // different program revision, same date code, clearly didn't get updated properly
GAME( 1998, prc298sp, stvbios, stv, stv, stv_state, stv, ROT0, "Atlus", "Print Club 2 '98 Spring Ver (J 971017 V1.100)", MACHINE_NOT_WORKING ) // again, date doesn't appear to have bene updated, this should be early 98
GAME( 1998, prc298su, stvbios, stv, stv, stv_state, stv, ROT0, "Atlus", "Print Club 2 '98 Summer Ver (J 980603 V1.100)", MACHINE_NOT_WORKING ) //
GAME( 1998, prc298au, stvbios, stv, stv, stv_state, stv, ROT0, "Atlus", "Print Club 2 '98 Autumn Ver (J 980827 V1.000)", MACHINE_NOT_WORKING )
-
-GAME( 2000, prc2ksu, stvbios, stv, stv, stv_state, stv, ROT0, "Atlus", "Print Club 2 2000 Summer", MACHINE_NOT_WORKING ) // *** BAD DUMP *** (even internal strings are corrupt)
-
+GAME( 2000, prc2ksu, stvbios, stv, stv, stv_state, stv, ROT0, "Atlus", "Print Club 2 2000 Summer (J 000509 V1.000) ", MACHINE_NOT_WORKING ) // internal string 2000_SUMMER
+
GAME( 1999, pclubor, stvbios, stv, stv, stv_state, stv, ROT0, "Atlus", "Print Club Goukakenran (J 991104 V1.000)", MACHINE_NOT_WORKING )
GAME( 1999, pclubol, stvbios, stv, stv, stv_state, stv, ROT0, "Atlus", "Print Club Olive (J 980717 V1.000)", MACHINE_NOT_WORKING )
diff --git a/src/mame/drivers/vd.cpp b/src/mame/drivers/vd.cpp
index ee0385c6156..84521e20623 100644
--- a/src/mame/drivers/vd.cpp
+++ b/src/mame/drivers/vd.cpp
@@ -5,10 +5,13 @@
PINBALL
Videodens
- PinMAME used as reference (unable to find any info at all on the net).
+ PinMAME used as reference. The Break '86 manual scan available on the net includes
+ a mostly illegible schematic.
Nothing in this driver is confirmed except where noted.
+ Ator runs on different hardware (peyper.cpp).
+
***************************************************************************************/
@@ -25,7 +28,7 @@ public:
m_maincpu(*this, "maincpu")
{ }
- DECLARE_READ8_MEMBER(dsw_r) { return 0; }
+ DECLARE_READ8_MEMBER(ack_r);
DECLARE_WRITE8_MEMBER(col_w);
DECLARE_WRITE8_MEMBER(disp_w);
DECLARE_WRITE8_MEMBER(lamp_w) { };
@@ -44,6 +47,12 @@ private:
};
+READ8_MEMBER(vd_state::ack_r)
+{
+ m_maincpu->set_input_line(INPUT_LINE_IRQ0, CLEAR_LINE); // guess
+ return 0; // this value is not used
+}
+
static ADDRESS_MAP_START( vd_map, AS_PROGRAM, 8, vd_state )
AM_RANGE(0x0000, 0x5fff) AM_ROM
AM_RANGE(0x6000, 0x62ff) AM_RAM
@@ -52,49 +61,68 @@ ADDRESS_MAP_END
static ADDRESS_MAP_START( vd_io, AS_IO, 8, vd_state )
ADDRESS_MAP_GLOBAL_MASK(0xff)
- AM_RANGE(0x00,0x00) AM_READ_PORT("X0")
- AM_RANGE(0x01,0x01) AM_READ_PORT("X1")
- AM_RANGE(0x02,0x02) AM_READ_PORT("X2")
- AM_RANGE(0x03,0x03) AM_READ_PORT("X3")
- AM_RANGE(0x04,0x04) AM_READ_PORT("X4")
- AM_RANGE(0x05,0x05) AM_READ_PORT("X5")
- AM_RANGE(0x20,0x27) AM_WRITE(lamp_w)
- AM_RANGE(0x28,0x28) AM_WRITE(sol_w)
- AM_RANGE(0x40,0x44) AM_WRITE(disp_w)
- AM_RANGE(0x60,0x60) AM_DEVWRITE("ay1", ay8910_device, address_w)
- AM_RANGE(0x61,0x61) AM_READ_PORT("DSW") //AM_READ(dsw_r)
- AM_RANGE(0x62,0x62) AM_DEVWRITE("ay1", ay8910_device, data_w)
- AM_RANGE(0x80,0x80) AM_DEVWRITE("ay2", ay8910_device, address_w)
- AM_RANGE(0x82,0x82) AM_DEVWRITE("ay2", ay8910_device, data_w)
- AM_RANGE(0xa0,0xa0) AM_DEVREAD("ay2", ay8910_device, data_r)
- AM_RANGE(0xc0,0xc0) AM_WRITE(col_w)
+ AM_RANGE(0x00, 0x00) AM_READ_PORT("X0")
+ AM_RANGE(0x01, 0x01) AM_READ_PORT("X1")
+ AM_RANGE(0x02, 0x02) AM_READ_PORT("X2")
+ AM_RANGE(0x03, 0x03) AM_READ_PORT("X3")
+ AM_RANGE(0x04, 0x04) AM_READ_PORT("X4")
+ AM_RANGE(0x05, 0x05) AM_READ_PORT("X5")
+ AM_RANGE(0x20, 0x27) AM_WRITE(lamp_w)
+ AM_RANGE(0x28, 0x28) AM_WRITE(sol_w)
+ AM_RANGE(0x40, 0x44) AM_WRITE(disp_w)
+ AM_RANGE(0x60, 0x60) AM_DEVWRITE("ay1", ay8910_device, address_w)
+ AM_RANGE(0x61, 0x61) AM_DEVREAD("ay1", ay8910_device, data_r)
+ AM_RANGE(0x62, 0x62) AM_DEVWRITE("ay1", ay8910_device, data_w)
+ AM_RANGE(0x80, 0x80) AM_DEVWRITE("ay2", ay8910_device, address_w)
+ AM_RANGE(0x81, 0x81) AM_DEVREAD("ay2", ay8910_device, data_r) // probably never read
+ AM_RANGE(0x82, 0x82) AM_DEVWRITE("ay2", ay8910_device, data_w)
+ AM_RANGE(0xa0, 0xa0) AM_READ(ack_r)
+ AM_RANGE(0xc0, 0xc0) AM_WRITE(col_w)
ADDRESS_MAP_END
-static INPUT_PORTS_START( vd )
- PORT_START("DSW")
- PORT_DIPNAME( 0x0001, 0x0000, "Accounting #1")
- PORT_DIPSETTING(0x0000, DEF_STR(Off))
- PORT_DIPSETTING(0x0001, DEF_STR(On))
- PORT_DIPNAME( 0x0002, 0x0000, "Accounting #2")
- PORT_DIPSETTING(0x0000, DEF_STR(Off))
- PORT_DIPSETTING(0x0002, DEF_STR(On))
- PORT_DIPNAME( 0x0004, 0x0000, "Accounting #3")
- PORT_DIPSETTING(0x0000, DEF_STR(Off))
- PORT_DIPSETTING(0x0004, DEF_STR(On))
- PORT_DIPNAME( 0x0018, 0x0000, "Credits per coin (chute #1/#2)")
- PORT_DIPSETTING(0x0018, "0.5/3" )
- PORT_DIPSETTING(0x0000, "1/5" )
- PORT_DIPSETTING(0x0008, "1/6" )
- PORT_DIPSETTING(0x0010, "2/8" )
- PORT_DIPNAME( 0x0020, 0x0000, "S6")
- PORT_DIPSETTING(0x0000, "0" )
- PORT_DIPSETTING(0x0020, "1" )
- PORT_DIPNAME( 0x0040, 0x0000, "Match feature")
- PORT_DIPSETTING(0x0040, DEF_STR(Off))
- PORT_DIPSETTING(0x0000, DEF_STR(On))
- PORT_DIPNAME( 0x0080, 0x0000, "S8")
- PORT_DIPSETTING(0x0000, "0" )
- PORT_DIPSETTING(0x0080, "1" )
+static INPUT_PORTS_START( break86 )
+ PORT_START("DSW1") // "Micro Swicher Nº 1"
+ PORT_DIPUNKNOWN(0x01, 0x01) PORT_DIPLOCATION("SW1:8") // used but not described in service manual
+ PORT_DIPUNKNOWN(0x02, 0x02) PORT_DIPLOCATION("SW1:7") // used but not described in service manual
+ PORT_DIPUNKNOWN(0x04, 0x04) PORT_DIPLOCATION("SW1:6") // used but not described in service manual
+ PORT_DIPUNUSED(0x08, 0x08) PORT_DIPLOCATION("SW1:5")
+ PORT_DIPNAME(0x30, 0x30, "Power Bumpers") PORT_DIPLOCATION("SW1:4,3") // "Potencia Bu????s" (partly illegible)
+ PORT_DIPSETTING(0x00, "4")
+ PORT_DIPSETTING(0x10, "6")
+ PORT_DIPSETTING(0x20, "8")
+ PORT_DIPSETTING(0x30, "10")
+ PORT_DIPNAME(0xc0, 0xc0, "Bonus Balls") PORT_DIPLOCATION("SW1:2,1") // "Bonos Bola Extra" - "Nº de Bonos"
+ PORT_DIPSETTING(0xc0, "6")
+ PORT_DIPSETTING(0x80, "8")
+ PORT_DIPSETTING(0x40, "10")
+ PORT_DIPSETTING(0x00, "12")
+
+ PORT_START("DSW2") // "Micro Swicher Nº 2"
+ PORT_DIPNAME(0x03, 0x03, "Scoring") PORT_DIPLOCATION("SW2:8,7") // "Tanteo"
+ PORT_DIPSETTING(0x03, "800k / 1.4M / 2.0M / 2.6M") // = "Bola Extra," "1ª Partida," "2ª Partida," "High Score"
+ PORT_DIPSETTING(0x02, "1.0M / 1.6M / 2.2M / 2.8M")
+ PORT_DIPSETTING(0x01, "1.2M / 1.8M / 2.4M / 3.0M")
+ PORT_DIPSETTING(0x00, "1.4M / 2.0M / 2.6M / 3.2M")
+ PORT_DIPNAME(0x04, 0x04, "Balls/Game") PORT_DIPLOCATION("SW2:6") // "Bolas-Partida"
+ PORT_DIPSETTING(0x04, "3")
+ PORT_DIPSETTING(0x00, "5")
+ PORT_DIPNAME(0x18, 0x18, DEF_STR(Coinage)) PORT_DIPLOCATION("SW2:5,4") // "Monederos"
+ PORT_DIPSETTING(0x18, "25 Pts. = 1, 100 Pts. = 5")
+ PORT_DIPSETTING(0x10, "25 Pts. = 1, 100 Pts. = 6")
+ PORT_DIPSETTING(0x08, "25 Pts. = 2, 100 Pts. = 8")
+ PORT_DIPSETTING(0x00, "25 Pts. = 1/2, 100 Pts. = 3")
+ PORT_DIPNAME(0x20, 0x20, "Lottery") PORT_DIPLOCATION("SW2:3") // "Loteria"
+ PORT_DIPSETTING(0x00, DEF_STR(No))
+ PORT_DIPSETTING(0x20, DEF_STR(Yes))
+ PORT_DIPNAME(0x40, 0x40, "Musica-Reclamo") PORT_DIPLOCATION("SW2:2")
+ PORT_DIPSETTING(0x00, DEF_STR(No))
+ PORT_DIPSETTING(0x40, DEF_STR(Yes))
+ PORT_DIPNAME(0x80, 0x80, "Extra Ball/Score") PORT_DIPLOCATION("SW2:1") // "Bola Extra-Tanteo"
+ PORT_DIPSETTING(0x00, DEF_STR(No))
+ PORT_DIPSETTING(0x80, DEF_STR(Yes))
+
+ PORT_START("DSW3")
+ PORT_BIT(0xff, IP_ACTIVE_LOW, IPT_UNUSED) // SW3 not populated
PORT_START("X0")
PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_START1)
@@ -109,6 +137,10 @@ static INPUT_PORTS_START( vd )
PORT_START("X5")
INPUT_PORTS_END
+static INPUT_PORTS_START( papillon )
+ PORT_INCLUDE( break86 ) // differences unknown
+INPUT_PORTS_END
+
TIMER_DEVICE_CALLBACK_MEMBER( vd_state::irq )
{
if (m_t_c > 40)
@@ -120,8 +152,10 @@ TIMER_DEVICE_CALLBACK_MEMBER( vd_state::irq )
WRITE8_MEMBER( vd_state::disp_w )
{
segment[offset] = data;
+#if 0 // probably not how this works
if (!offset)
m_maincpu->set_input_line(INPUT_LINE_IRQ0, CLEAR_LINE);
+#endif
}
WRITE8_MEMBER( vd_state::col_w )
@@ -154,8 +188,11 @@ static MACHINE_CONFIG_START( vd, vd_state )
MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
MCFG_SOUND_ADD("ay1", AY8910, 2000000) //?
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 0.33/3)
+ MCFG_AY8910_PORT_A_READ_CB(IOPORT("DSW2"))
+ MCFG_AY8910_PORT_B_READ_CB(IOPORT("DSW1"))
MCFG_SOUND_ADD("ay2", AY8910, 2000000) //?
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 0.33/3)
+ MCFG_AY8910_PORT_B_READ_CB(IOPORT("DSW3")) //?
/* Video */
MCFG_DEFAULT_LAYOUT(layout_vd)
@@ -163,6 +200,10 @@ MACHINE_CONFIG_END
/*-------------------------------------------------------------------
/ Break '86 (1986)
+/
+/ The title of this game is somewhat uncertain. The backglass says
+/ only "Break," the flyer also calls it "Super Break" and "Super
+/ Break '86", and the service manual's title page has "Modbreak."
/-------------------------------------------------------------------*/
ROM_START(break86)
ROM_REGION(0x10000, "maincpu", 0)
@@ -181,18 +222,6 @@ ROM_START(papillon)
ROM_LOAD("u6.dat", 0x4000, 0x2000, CRC(6b2867b3) SHA1(720fe8a65b447e839b0eb9ea21e0b3cb0e50cf7a))
ROM_END
-#if 0
-/*-------------------------------------------------------------------
-/ Ator (19??)
-/-------------------------------------------------------------------*/
-ROM_START(ator)
- ROM_REGION(0x10000, "maincpu", 0)
- ROM_LOAD("ator.u4", 0x0000, 0x2000, NO_DUMP)
- ROM_LOAD("ator.u5", 0x2000, 0x2000, NO_DUMP)
- ROM_LOAD("ator.u6", 0x4000, 0x2000, CRC(21aad5c4) SHA1(e78da5d80682710db34cbbfeae5af54241c73371))
-ROM_END
-#endif
-//GAME(19??, ator, 0, vd, vd, driver_device, 0, ROT0, "Videodens", "Ator", MACHINE_IS_SKELETON_MECHANICAL)
-GAME(1986, break86, 0, vd, vd, driver_device, 0, ROT0, "Videodens", "Break '86", MACHINE_IS_SKELETON_MECHANICAL)
-GAME(1986, papillon, 0, vd, vd, driver_device, 0, ROT0, "Videodens", "Papillon", MACHINE_IS_SKELETON_MECHANICAL)
+GAME(1986, break86, 0, vd, break86, driver_device, 0, ROT0, "Videodens", "Break '86", MACHINE_IS_SKELETON_MECHANICAL)
+GAME(1986, papillon, 0, vd, papillon, driver_device, 0, ROT0, "Videodens", "Papillon", MACHINE_IS_SKELETON_MECHANICAL)
diff --git a/src/mame/drivers/x1.cpp b/src/mame/drivers/x1.cpp
index 741895f5a5b..cde608c590a 100644
--- a/src/mame/drivers/x1.cpp
+++ b/src/mame/drivers/x1.cpp
@@ -574,6 +574,62 @@ uint16_t x1_state::check_keyboard_press()
uint32_t f_key = ioport("f_keys")->read();
scancode = 0;
+ static const uint8_t kanatable[52][3] = {
+ // normal, kana, kana + shift
+ {0x2c,0xc8,0xa4}, // , / ne / japanese comma
+ {0x2d,0xce,0x00}, // - / ho
+ {0x2e,0xd9,0xa1}, // . / ru / japanese period
+ {0x2f,0xd2,0xa5}, // / / me / nakaguro
+ {0x30,0xdc,0xa6}, // 0 / wa / wo
+ {0x31,0xc7,0x00}, // 1 / nu
+ {0x32,0xcc,0x00}, // 2 / fu
+ {0x33,0xb1,0xa7}, // 3 / a / small a
+ {0x34,0xb3,0xa9}, // 4 / u / small u
+ {0x35,0xb4,0xaa}, // 5 / e / small e
+ {0x36,0xb5,0xab}, // 6 / o / small o
+ {0x37,0xd4,0xac}, // 7 / ya / small ya
+ {0x38,0xd5,0xad}, // 8 / yu / small yu
+ {0x39,0xd6,0xae}, // 9 / yo / small yo
+ {0x3a,0xb9,0x00}, // : / ke
+ {0x3b,0xda,0x00}, // ; / re
+ {0x3c,0x00,0x00},
+ {0x3d,0x00,0x00},
+ {0x3e,0x00,0x00},
+ {0x3f,0x00,0x00},
+ {0x40,0xde,0x00}, // @ / dakuten
+ {0x41,0xc1,0x00}, // A / chi
+ {0x42,0xba,0x00}, // B / ko
+ {0x43,0xbf,0x00}, // C / so
+ {0x44,0xbc,0x00}, // D / shi
+ {0x45,0xb2,0xa8}, // E / i / small i
+ {0x46,0xca,0x00}, // F / ha
+ {0x47,0xb7,0x00}, // G / ki
+ {0x48,0xb8,0x00}, // H / ku
+ {0x49,0xc6,0x00}, // I / ni
+ {0x4a,0xcf,0x00}, // J / ma
+ {0x4b,0xc9,0x00}, // K / no
+ {0x4c,0xd8,0x00}, // L / ri
+ {0x4d,0xd3,0x00}, // M / mo
+ {0x4e,0xd0,0x00}, // N / mi
+ {0x4f,0xd7,0x00}, // O / ra
+ {0x50,0xbe,0x00}, // P / se
+ {0x51,0xc0,0x00}, // Q / ta
+ {0x52,0xbd,0x00}, // R / su
+ {0x53,0xc4,0x00}, // S / to
+ {0x54,0xb6,0x00}, // T / ka
+ {0x55,0xc5,0x00}, // U / na
+ {0x56,0xcb,0x00}, // V / hi
+ {0x57,0xc3,0x00}, // W / te
+ {0x58,0xbb,0x00}, // X / sa
+ {0x59,0xdd,0x00}, // Y / n
+ {0x5a,0xc2,0xaf}, // Z / tsu / small tsu
+ {0x5b,0xdf,0xa2}, // [ / handakuten / opening quotation mark
+ {0x5c,0xb0,0x00}, // yen symbol / long vowel mark
+ {0x5d,0xd1,0xa3}, // ] / mu / closing quotation mark
+ {0x5e,0xcd,0x00}, // ^ / he
+ {0x5f,0xdb,0x00} // _ / ro
+ };
+
for(port_i=0;port_i<3;port_i++)
{
for(i=0;i<32;i++)
@@ -583,11 +639,26 @@ uint16_t x1_state::check_keyboard_press()
//key_flag = 1;
if(keymod & 0x02) // shift not pressed
{
- if(scancode >= 0x41 && scancode < 0x5a)
+ if ((keymod & 0x04) == 0) // kana on
+ {
+ if (scancode >= 0x2c && scancode <= 0x5f)
+ scancode = kanatable[scancode - 0x2c][1];
+ }
+
+ if (scancode >= 0x41 && scancode < 0x5a)
scancode += 0x20; // lowercase
}
else
{
+ if ((keymod & 0x04) == 0) // kana on
+ {
+ if (scancode >= 0x2c && scancode <= 0x5f)
+ {
+ if (kanatable[scancode - 0x2c][2] != 0)
+ scancode = kanatable[scancode - 0x2c][2];
+ }
+ }
+
if(scancode >= 0x31 && scancode < 0x3a)
scancode -= 0x10;
if(scancode == 0x30)
@@ -595,6 +666,9 @@ uint16_t x1_state::check_keyboard_press()
scancode = 0x3d;
}
}
+
+
+
if((keymod & 0x10) == 0) // graph on
scancode |= 0x80;
@@ -2026,10 +2100,10 @@ INPUT_PORTS_START( x1 )
PORT_BIT(0x00000200,IP_ACTIVE_HIGH,IPT_UNUSED) //0x29 )
PORT_BIT(0x00000400,IP_ACTIVE_HIGH,IPT_UNUSED) //0x2a *
PORT_BIT(0x00000800,IP_ACTIVE_HIGH,IPT_UNUSED) //0x2b +
- PORT_BIT(0x00001000,IP_ACTIVE_HIGH,IPT_UNUSED) //0x2c ,
+ PORT_BIT(0x00001000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(",") PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',')
PORT_BIT(0x00002000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("-") PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-')
- PORT_BIT(0x00004000,IP_ACTIVE_HIGH,IPT_UNUSED) //0x2e .
- PORT_BIT(0x00008000,IP_ACTIVE_HIGH,IPT_UNUSED) //0x2f /
+ PORT_BIT(0x00004000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(".") PORT_CODE(KEYCODE_STOP) PORT_CHAR('.')
+ PORT_BIT(0x00008000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("/") PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/')
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')
@@ -2077,7 +2151,7 @@ INPUT_PORTS_START( x1 )
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(0x10000000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("\xc2\xa5") // yen
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("_")
@@ -2108,9 +2182,9 @@ INPUT_PORTS_START( x1 )
PORT_START("key_modifiers")
PORT_BIT(0x00000001,IP_ACTIVE_LOW,IPT_KEYBOARD) PORT_NAME("CTRL") PORT_CODE(KEYCODE_LCONTROL)
PORT_BIT(0x00000002,IP_ACTIVE_LOW,IPT_KEYBOARD) PORT_NAME("SHIFT") PORT_CODE(KEYCODE_LSHIFT)
- PORT_BIT(0x00000004,IP_ACTIVE_LOW,IPT_KEYBOARD) PORT_NAME("KANA") PORT_CODE(KEYCODE_RCONTROL)
+ PORT_BIT(0x00000004,IP_ACTIVE_LOW,IPT_KEYBOARD) PORT_NAME("KANA") PORT_CODE(KEYCODE_RCONTROL) PORT_TOGGLE
PORT_BIT(0x00000008,IP_ACTIVE_LOW,IPT_KEYBOARD) PORT_NAME("CAPS") PORT_CODE(KEYCODE_CAPSLOCK) PORT_TOGGLE
- PORT_BIT(0x00000010,IP_ACTIVE_LOW,IPT_KEYBOARD) PORT_NAME("GRPH") PORT_CODE(KEYCODE_LALT)
+ PORT_BIT(0x00000010,IP_ACTIVE_LOW,IPT_KEYBOARD) PORT_NAME("GRAPH") PORT_CODE(KEYCODE_LALT)
#if 0
PORT_BIT(0x00020000,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(",") PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',')
diff --git a/src/mame/includes/40love.h b/src/mame/includes/40love.h
index 0cd5f127251..c420887828d 100644
--- a/src/mame/includes/40love.h
+++ b/src/mame/includes/40love.h
@@ -1,7 +1,7 @@
// license:GPL-2.0+
// copyright-holders:Jarek Burczynski
-#include "machine/buggychl.h"
+#include "machine/taito68705interface.h"
#include "machine/gen_latch.h"
#include "sound/msm5232.h"
@@ -18,7 +18,6 @@ public:
m_mcu_ram(*this, "mcu_ram"),
m_audiocpu(*this, "audiocpu"),
m_maincpu(*this, "maincpu"),
- m_mcu(*this, "mcu"),
m_bmcu(*this, "bmcu"),
m_msm(*this, "msm"),
m_gfxdecode(*this, "gfxdecode"),
@@ -75,8 +74,7 @@ public:
/* devices */
required_device<cpu_device> m_audiocpu;
required_device<cpu_device> m_maincpu;
- optional_device<cpu_device> m_mcu;
- optional_device<buggychl_mcu_device> m_bmcu;
+ optional_device<taito68705_mcu_device> m_bmcu;
required_device<msm5232_device> m_msm;
required_device<gfxdecode_device> m_gfxdecode;
required_device<palette_device> m_palette;
diff --git a/src/mame/includes/aerofgt.h b/src/mame/includes/aerofgt.h
index 8a7b75f2f07..7404cd3d689 100644
--- a/src/mame/includes/aerofgt.h
+++ b/src/mame/includes/aerofgt.h
@@ -78,27 +78,26 @@ public:
int m_pending_command;
/* handlers */
- DECLARE_WRITE16_MEMBER(sound_command_w);
- DECLARE_WRITE16_MEMBER(turbofrc_sound_command_w);
- DECLARE_WRITE16_MEMBER(aerfboot_soundlatch_w);
- DECLARE_READ16_MEMBER(pending_command_r);
+ DECLARE_WRITE8_MEMBER(sound_command_w);
+ DECLARE_WRITE8_MEMBER(aerfboot_soundlatch_w);
+ DECLARE_READ8_MEMBER(pending_command_r);
DECLARE_WRITE8_MEMBER(pending_command_clear_w);
DECLARE_WRITE8_MEMBER(aerofgt_sh_bankswitch_w);
DECLARE_WRITE8_MEMBER(aerfboot_okim6295_banking_w);
DECLARE_WRITE16_MEMBER(aerofgt_bg1videoram_w);
DECLARE_WRITE16_MEMBER(aerofgt_bg2videoram_w);
- DECLARE_WRITE16_MEMBER(pspikes_gfxbank_w);
+ DECLARE_WRITE8_MEMBER(pspikes_gfxbank_w);
DECLARE_WRITE16_MEMBER(pspikesb_gfxbank_w);
DECLARE_WRITE16_MEMBER(spikes91_lookup_w);
- DECLARE_WRITE16_MEMBER(karatblz_gfxbank_w);
- DECLARE_WRITE16_MEMBER(spinlbrk_gfxbank_w);
+ DECLARE_WRITE8_MEMBER(karatblz_gfxbank_w);
+ DECLARE_WRITE8_MEMBER(spinlbrk_gfxbank_w);
DECLARE_WRITE16_MEMBER(turbofrc_gfxbank_w);
DECLARE_WRITE16_MEMBER(aerofgt_gfxbank_w);
DECLARE_WRITE16_MEMBER(aerofgt_bg1scrollx_w);
DECLARE_WRITE16_MEMBER(aerofgt_bg1scrolly_w);
DECLARE_WRITE16_MEMBER(aerofgt_bg2scrollx_w);
DECLARE_WRITE16_MEMBER(aerofgt_bg2scrolly_w);
- DECLARE_WRITE16_MEMBER(pspikes_palette_bank_w);
+ DECLARE_WRITE8_MEMBER(pspikes_palette_bank_w);
DECLARE_WRITE16_MEMBER(wbbc97_bitmap_enable_w);
DECLARE_WRITE16_MEMBER(pspikesb_oki_banking_w);
DECLARE_WRITE16_MEMBER(aerfboo2_okim6295_banking_w);
diff --git a/src/mame/includes/apollo.h b/src/mame/includes/apollo.h
index f51e422f35f..6bfd8ec7c3f 100644
--- a/src/mame/includes/apollo.h
+++ b/src/mame/includes/apollo.h
@@ -326,18 +326,17 @@ void apollo_csr_set_status_register(uint16_t mask, uint16_t data);
class apollo_sio: public mc68681_device
{
public:
- apollo_sio(const machine_config &mconfig, const char *tag,
- device_t *owner, uint32_t clock);
+ apollo_sio(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
- DECLARE_READ8_MEMBER(read);
- DECLARE_WRITE8_MEMBER(write);
+ virtual DECLARE_READ8_MEMBER(read) override;
+ virtual DECLARE_WRITE8_MEMBER(write) override;
protected:
virtual void device_reset() override;
private:
- uint8_t m_csrb;
- uint8_t m_ip6;
+ uint8_t m_csrb;
+ uint8_t m_ip6;
};
extern const device_type APOLLO_SIO;
diff --git a/src/mame/includes/arkanoid.h b/src/mame/includes/arkanoid.h
index 9acc4a3ef89..aa2895258ee 100644
--- a/src/mame/includes/arkanoid.h
+++ b/src/mame/includes/arkanoid.h
@@ -15,10 +15,7 @@ enum {
class arkanoid_state : public driver_device
{
public:
- enum
- {
- TIMER_68705_PRESCALER_EXPIRED,
- };
+
arkanoid_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag),
@@ -56,13 +53,13 @@ public:
/* mcu internal related */
uint8_t m_portA_in;
uint8_t m_portA_out;
- uint8_t m_ddrA;
- uint8_t m_portC_internal;
- uint8_t m_portC_out;
- uint8_t m_ddrC;
- uint8_t m_tdr;
- uint8_t m_tcr;
- emu_timer *m_68705_timer;
+ uint8_t m_old_portC_out;
+
+ DECLARE_READ8_MEMBER( mcu_porta_r );
+ DECLARE_READ8_MEMBER( mcu_portb_r );
+ DECLARE_READ8_MEMBER( mcu_portc_r );
+ DECLARE_WRITE8_MEMBER( mcu_porta_w );
+ DECLARE_WRITE8_MEMBER( mcu_portc_w );
/* hexaa */
uint8_t m_hexaa_from_main;
@@ -76,16 +73,8 @@ public:
DECLARE_READ8_MEMBER(arkanoid_Z80_mcu_r);
DECLARE_WRITE8_MEMBER(arkanoid_Z80_mcu_w);
- DECLARE_READ8_MEMBER(arkanoid_68705_port_a_r);
- DECLARE_WRITE8_MEMBER(arkanoid_68705_port_a_w);
- DECLARE_WRITE8_MEMBER(arkanoid_68705_ddr_a_w);
- DECLARE_READ8_MEMBER(arkanoid_68705_port_c_r);
- DECLARE_WRITE8_MEMBER(arkanoid_68705_port_c_w);
- DECLARE_WRITE8_MEMBER(arkanoid_68705_ddr_c_w);
- DECLARE_READ8_MEMBER(arkanoid_68705_tdr_r);
- DECLARE_WRITE8_MEMBER(arkanoid_68705_tdr_w);
- DECLARE_READ8_MEMBER(arkanoid_68705_tcr_r);
- DECLARE_WRITE8_MEMBER(arkanoid_68705_tcr_w);
+
+
DECLARE_READ8_MEMBER(arkanoid_bootleg_f000_r);
DECLARE_READ8_MEMBER(arkanoid_bootleg_f002_r);
DECLARE_WRITE8_MEMBER(arkanoid_bootleg_d018_w);
@@ -118,10 +107,7 @@ public:
virtual void video_start() override;
uint32_t screen_update_arkanoid(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
uint32_t screen_update_hexa(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
- TIMER_CALLBACK_MEMBER(timer_68705_increment);
void draw_sprites( bitmap_ind16 &bitmap, const rectangle &cliprect );
void arkanoid_bootleg_init( );
-protected:
- virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
};
diff --git a/src/mame/includes/ashnojoe.h b/src/mame/includes/ashnojoe.h
index 74dbac38522..4735df63f43 100644
--- a/src/mame/includes/ashnojoe.h
+++ b/src/mame/includes/ashnojoe.h
@@ -51,7 +51,6 @@ public:
/* sound-related */
uint8_t m_adpcm_byte;
- int m_soundlatch_status;
int m_msm5205_vclk_toggle;
/* devices */
@@ -62,9 +61,7 @@ public:
required_device<generic_latch_8_device> m_soundlatch;
DECLARE_READ16_MEMBER(fake_4a00a_r);
- DECLARE_WRITE16_MEMBER(ashnojoe_soundlatch_w);
DECLARE_WRITE8_MEMBER(adpcm_w);
- DECLARE_READ8_MEMBER(sound_latch_r);
DECLARE_READ8_MEMBER(sound_latch_status_r);
DECLARE_WRITE16_MEMBER(ashnojoe_tileram_w);
DECLARE_WRITE16_MEMBER(ashnojoe_tileram2_w);
diff --git a/src/mame/includes/asuka.h b/src/mame/includes/asuka.h
index e2503666fc1..8dbd790738e 100644
--- a/src/mame/includes/asuka.h
+++ b/src/mame/includes/asuka.h
@@ -8,6 +8,7 @@
#include "machine/taitoio.h"
#include "sound/msm5205.h"
+#include "machine/74157.h"
#include "video/pc090oj.h"
#include "video/tc0100scn.h"
#include "video/tc0110pcr.h"
@@ -26,26 +27,28 @@ public:
m_maincpu(*this, "maincpu"),
m_audiocpu(*this, "audiocpu"),
m_msm(*this, "msm"),
+ m_adpcm_select(*this, "adpcm_select"),
+ m_sound_data(*this, "ymsnd"),
m_pc090oj(*this, "pc090oj"),
m_tc0100scn(*this, "tc0100scn"),
m_tc0110pcr(*this, "tc0110pcr"),
m_tc0220ioc(*this, "tc0220ioc") { }
/* video-related */
- uint16_t m_video_ctrl;
- uint16_t m_video_mask;
+ u16 m_video_ctrl;
+ u16 m_video_mask;
/* c-chip */
int m_current_round;
int m_current_bank;
- uint8_t m_cval[26];
- uint8_t m_cc_port;
- uint8_t m_restart_status;
+ u8 m_cval[26];
+ u8 m_cc_port;
+ u8 m_restart_status;
/* misc */
- int m_adpcm_pos;
- int m_adpcm_data;
+ u16 m_adpcm_pos;
+ bool m_adpcm_ff;
optional_shared_ptr<uint8_t> m_cadash_shared_ram;
@@ -53,6 +56,8 @@ public:
required_device<cpu_device> m_maincpu;
required_device<cpu_device> m_audiocpu;
optional_device<msm5205_device> m_msm;
+ optional_device<ls157_device> m_adpcm_select;
+ optional_region_ptr<u8> m_sound_data;
required_device<pc090oj_device> m_pc090oj;
required_device<tc0100scn_device> m_tc0100scn;
required_device<tc0110pcr_device> m_tc0110pcr;
diff --git a/src/mame/includes/bigevglf.h b/src/mame/includes/bigevglf.h
index c450bf05c5d..f8cc2b1591e 100644
--- a/src/mame/includes/bigevglf.h
+++ b/src/mame/includes/bigevglf.h
@@ -1,6 +1,7 @@
// license:GPL-2.0+
// copyright-holders:Jarek Burczynski, Tomasz Slanina
#include "sound/msm5232.h"
+#include "machine/taito68705interface.h"
class bigevglf_state : public driver_device
{
@@ -11,7 +12,7 @@ public:
m_spriteram1(*this, "spriteram1"),
m_spriteram2(*this, "spriteram2"),
m_audiocpu(*this, "audiocpu"),
- m_mcu(*this, "mcu"),
+ m_bmcu(*this, "bmcu"),
m_maincpu(*this, "maincpu"),
m_msm(*this, "msm"),
m_gfxdecode(*this, "gfxdecode"),
@@ -38,18 +39,6 @@ public:
uint8_t m_sound_state;
/* MCU related */
- uint8_t m_from_mcu;
- int m_mcu_sent;
- int m_main_sent;
- uint8_t m_port_a_in;
- uint8_t m_port_a_out;
- uint8_t m_ddr_a;
- uint8_t m_port_b_in;
- uint8_t m_port_b_out;
- uint8_t m_ddr_b;
- uint8_t m_port_c_in;
- uint8_t m_port_c_out;
- uint8_t m_ddr_c;
int m_mcu_coin_bit5;
/* misc */
@@ -59,7 +48,7 @@ public:
/* devices */
required_device<cpu_device> m_audiocpu;
- optional_device<cpu_device> m_mcu;
+ optional_device<taito68705_mcu_device> m_bmcu;
DECLARE_WRITE8_MEMBER(beg_banking_w);
DECLARE_WRITE8_MEMBER(beg_fromsound_w);
DECLARE_READ8_MEMBER(beg_fromsound_r);
diff --git a/src/mame/includes/bking.h b/src/mame/includes/bking.h
index 50b8e4467c2..03b13033fe3 100644
--- a/src/mame/includes/bking.h
+++ b/src/mame/includes/bking.h
@@ -1,7 +1,7 @@
// license:BSD-3-Clause
// copyright-holders:Mike Balfour, Zsolt Vasvari
-#include "machine/buggychl.h"
+#include "machine/taito68705interface.h"
#include "machine/gen_latch.h"
class bking_state : public driver_device
@@ -11,7 +11,6 @@ public:
: driver_device(mconfig, type, tag),
m_playfield_ram(*this, "playfield_ram"),
m_audiocpu(*this, "audiocpu"),
- m_mcu(*this, "mcu"),
m_bmcu(*this, "bmcu"),
m_gfxdecode(*this, "gfxdecode"),
m_screen(*this, "screen"),
@@ -51,22 +50,12 @@ public:
/* devices */
required_device<cpu_device> m_audiocpu;
- optional_device<cpu_device> m_mcu;
- optional_device<buggychl_mcu_device> m_bmcu;
+ optional_device<taito68705_mcu_device> m_bmcu;
required_device<gfxdecode_device> m_gfxdecode;
required_device<screen_device> m_screen;
required_device<palette_device> m_palette;
required_device<generic_latch_8_device> m_soundlatch;
-#if 0
- /* 68705 */
- uint8_t m_port_a_in;
- uint8_t m_port_a_out;
- uint8_t m_ddr_a;
- uint8_t m_port_b_in;
- uint8_t m_port_b_out;
- uint8_t m_ddr_b;
-#endif
DECLARE_READ8_MEMBER(bking_sndnmi_disable_r);
DECLARE_WRITE8_MEMBER(bking_sndnmi_enable_w);
DECLARE_WRITE8_MEMBER(bking_soundlatch_w);
diff --git a/src/mame/includes/bublbobl.h b/src/mame/includes/bublbobl.h
index 26168aca158..554508c3a19 100644
--- a/src/mame/includes/bublbobl.h
+++ b/src/mame/includes/bublbobl.h
@@ -2,6 +2,7 @@
// copyright-holders:Chris Moore, Nicola Salmoria
#include "machine/gen_latch.h"
+#include "machine/taito68705interface.h"
class bublbobl_state : public driver_device
{
@@ -17,13 +18,6 @@ public:
m_videoram(*this, "videoram"),
m_objectram(*this, "objectram"),
m_mcu_sharedram(*this, "mcu_sharedram"),
- m_mcu_sent(false),
- m_main_sent(false),
- m_from_main(0),
- m_from_mcu(0),
- m_from_mcu_latch(0),
- m_to_mcu_latch(0),
- m_old_portB(0),
m_maincpu(*this, "maincpu"),
m_mcu(*this, "mcu"),
m_audiocpu(*this, "audiocpu"),
@@ -73,14 +67,6 @@ public:
/* Bobble Bobble */
int m_ic43_a;
int m_ic43_b;
- /* Tokio */
- bool m_mcu_sent;
- bool m_main_sent;
- uint8_t m_from_main;
- uint8_t m_from_mcu;
- uint8_t m_from_mcu_latch;
- uint8_t m_to_mcu_latch;
- uint8_t m_old_portB;
/* devices */
required_device<cpu_device> m_maincpu;
@@ -95,8 +81,6 @@ public:
DECLARE_WRITE8_MEMBER(tokio_bankswitch_w);
DECLARE_WRITE8_MEMBER(tokio_videoctrl_w);
DECLARE_WRITE8_MEMBER(bublbobl_nmitrigger_w);
- DECLARE_READ8_MEMBER(tokio_mcu_r);
- DECLARE_WRITE8_MEMBER(tokio_mcu_w);
DECLARE_READ8_MEMBER(tokiob_mcu_r);
DECLARE_WRITE8_MEMBER(bublbobl_sound_command_w);
@@ -132,20 +116,6 @@ public:
DECLARE_WRITE8_MEMBER(bublbobl_68705_port_b_w);
DECLARE_WRITE8_MEMBER(bublbobl_68705_ddr_b_w);
-
-
-
- DECLARE_CUSTOM_INPUT_MEMBER(tokio_mcu_sent_r);
- DECLARE_CUSTOM_INPUT_MEMBER(tokio_main_sent_r);
-
-
- DECLARE_READ8_MEMBER(tokio_mcu_porta_r);
- DECLARE_READ8_MEMBER(tokio_mcu_portc_r);
- DECLARE_WRITE8_MEMBER(tokio_mcu_porta_w);
- DECLARE_WRITE8_MEMBER(tokio_mcu_portb_w);
-
-
- DECLARE_DRIVER_INIT(tokiob);
DECLARE_DRIVER_INIT(tokio);
DECLARE_DRIVER_INIT(dland);
DECLARE_DRIVER_INIT(bublbobl);
diff --git a/src/mame/includes/buggychl.h b/src/mame/includes/buggychl.h
index 9f9b893bf7d..1941889a646 100644
--- a/src/mame/includes/buggychl.h
+++ b/src/mame/includes/buggychl.h
@@ -4,7 +4,7 @@
buggychl
*/
-#include "machine/buggychl.h"
+#include "machine/taito68705interface.h"
#include "machine/gen_latch.h"
#include "sound/msm5232.h"
@@ -20,7 +20,6 @@ public:
m_scrollh(*this, "scrollh"),
m_audiocpu(*this, "audiocpu"),
m_maincpu(*this, "maincpu"),
- m_mcu(*this, "mcu"),
m_bmcu(*this, "bmcu"),
m_msm(*this, "msm"),
m_gfxdecode(*this, "gfxdecode"),
@@ -53,8 +52,7 @@ public:
/* devices */
required_device<cpu_device> m_audiocpu;
required_device<cpu_device> m_maincpu;
- required_device<cpu_device> m_mcu;
- required_device<buggychl_mcu_device> m_bmcu;
+ required_device<taito68705_mcu_device> m_bmcu;
required_device<msm5232_device> m_msm;
required_device<gfxdecode_device> m_gfxdecode;
required_device<screen_device> m_screen;
diff --git a/src/mame/includes/cdi.h b/src/mame/includes/cdi.h
index 869f3c59355..6b73b21c475 100644
--- a/src/mame/includes/cdi.h
+++ b/src/mame/includes/cdi.h
@@ -8,6 +8,7 @@
#include "machine/cdicdic.h"
#include "sound/dmadac.h"
#include "video/mcd212.h"
+#include "cpu/mcs51/mcs51.h"
/*----------- driver state -----------*/
@@ -106,21 +107,17 @@ public:
DECLARE_MACHINE_RESET(cdimono1);
DECLARE_MACHINE_RESET(cdimono2);
- DECLARE_MACHINE_RESET(quizard12);
- DECLARE_MACHINE_RESET(quizard17);
- DECLARE_MACHINE_RESET(quizard18);
- DECLARE_MACHINE_RESET(quizard22);
- DECLARE_MACHINE_RESET(quizard23);
- DECLARE_MACHINE_RESET(quizard32);
- DECLARE_MACHINE_RESET(quizard34);
- DECLARE_MACHINE_RESET(quizard4r40);
- DECLARE_MACHINE_RESET(quizard4r41);
- DECLARE_MACHINE_RESET(quizard4r42);
+ DECLARE_MACHINE_RESET(quizard1);
+ DECLARE_MACHINE_RESET(quizard2);
+ DECLARE_MACHINE_RESET(quizard3);
+ DECLARE_MACHINE_RESET(quizard4);
DECLARE_READ8_MEMBER(servo_io_r);
DECLARE_WRITE8_MEMBER(servo_io_w);
DECLARE_READ8_MEMBER(slave_io_r);
DECLARE_WRITE8_MEMBER(slave_io_w);
+ DECLARE_READ8_MEMBER(quizard_mcu_p1_r);
+
uint32_t screen_update_cdimono1(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
uint32_t screen_update_cdimono1_lcd(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
};
diff --git a/src/mame/includes/crospang.h b/src/mame/includes/crospang.h
index 2a7b80e0059..0049f726a56 100644
--- a/src/mame/includes/crospang.h
+++ b/src/mame/includes/crospang.h
@@ -38,7 +38,6 @@ public:
required_device<gfxdecode_device> m_gfxdecode;
required_device<generic_latch_8_device> m_soundlatch;
- DECLARE_WRITE16_MEMBER(crospang_soundlatch_w);
DECLARE_WRITE16_MEMBER(bestri_tilebank_w);
DECLARE_WRITE16_MEMBER(bestri_bg_scrolly_w);
DECLARE_WRITE16_MEMBER(bestri_fg_scrolly_w);
diff --git a/src/mame/includes/crshrace.h b/src/mame/includes/crshrace.h
index 36ef377e777..9d1621000d8 100644
--- a/src/mame/includes/crshrace.h
+++ b/src/mame/includes/crshrace.h
@@ -54,7 +54,7 @@ public:
/* devices */
DECLARE_WRITE8_MEMBER(crshrace_sh_bankswitch_w);
- DECLARE_WRITE16_MEMBER(sound_command_w);
+ DECLARE_WRITE8_MEMBER(sound_command_w);
DECLARE_WRITE8_MEMBER(pending_command_clear_w);
DECLARE_WRITE16_MEMBER(crshrace_videoram1_w);
DECLARE_WRITE16_MEMBER(crshrace_videoram2_w);
diff --git a/src/mame/includes/dcheese.h b/src/mame/includes/dcheese.h
index 396cd2fc0db..853a3b46a83 100644
--- a/src/mame/includes/dcheese.h
+++ b/src/mame/includes/dcheese.h
@@ -38,7 +38,6 @@ public:
/* misc */
uint8_t m_irq_state[5];
- uint8_t m_soundlatch_full;
uint8_t m_sound_control;
uint8_t m_sound_msb_latch;
@@ -50,8 +49,6 @@ public:
required_device<generic_latch_8_device> m_soundlatch;
DECLARE_WRITE16_MEMBER(eeprom_control_w);
- DECLARE_WRITE16_MEMBER(sound_command_w);
- DECLARE_READ8_MEMBER(sound_command_r);
DECLARE_READ8_MEMBER(sound_status_r);
DECLARE_WRITE8_MEMBER(sound_control_w);
DECLARE_WRITE8_MEMBER(bsmt_data_w);
diff --git a/src/mame/includes/dec0.h b/src/mame/includes/dec0.h
index fd03153d4db..af3899ff356 100644
--- a/src/mame/includes/dec0.h
+++ b/src/mame/includes/dec0.h
@@ -134,14 +134,12 @@ public:
uint16_t m_automat_scroll_regs[4];
DECLARE_WRITE16_MEMBER(automat_control_w);
- DECLARE_WRITE16_MEMBER(secretab_sound_w);
DECLARE_READ16_MEMBER( automat_palette_r );
DECLARE_WRITE16_MEMBER( automat_palette_w );
DECLARE_WRITE16_MEMBER( automat_scroll_w )
{
COMBINE_DATA(&m_automat_scroll_regs[offset]);
}
- DECLARE_READ8_MEMBER(sound_command_r);
DECLARE_WRITE8_MEMBER(sound_bankswitch_w);
DECLARE_WRITE_LINE_MEMBER(msm1_vclk_cb);
DECLARE_WRITE_LINE_MEMBER(msm2_vclk_cb);
diff --git a/src/mame/includes/f1gp.h b/src/mame/includes/f1gp.h
index 384b02b8b9f..ecc262d27cd 100644
--- a/src/mame/includes/f1gp.h
+++ b/src/mame/includes/f1gp.h
@@ -78,8 +78,8 @@ public:
optional_device<generic_latch_8_device> m_soundlatch; // not f1gpb
DECLARE_WRITE8_MEMBER(f1gp_sh_bankswitch_w);
- DECLARE_WRITE16_MEMBER(sound_command_w);
- DECLARE_READ16_MEMBER(command_pending_r);
+ DECLARE_WRITE8_MEMBER(sound_command_w);
+ DECLARE_READ8_MEMBER(command_pending_r);
DECLARE_WRITE8_MEMBER(pending_command_clear_w);
DECLARE_WRITE16_MEMBER(f1gpb_misc_w);
DECLARE_READ16_MEMBER(f1gp_zoomdata_r);
diff --git a/src/mame/includes/fidelz80.h b/src/mame/includes/fidelz80.h
index 5ce7e1f6c82..1fe4e19cb6b 100644
--- a/src/mame/includes/fidelz80.h
+++ b/src/mame/includes/fidelz80.h
@@ -50,9 +50,9 @@ public:
DECLARE_DEVICE_IMAGE_LOAD_MEMBER(scc_cartridge);
// display common
- int m_display_wait; // led/lamp off-delay in microseconds (default 33ms)
- int m_display_maxy; // display matrix number of rows
- int m_display_maxx; // display matrix number of columns (max 31 for now)
+ int m_display_wait; // led/lamp off-delay in microseconds (default 33ms)
+ int m_display_maxy; // display matrix number of rows
+ int m_display_maxx; // display matrix number of columns (max 31 for now)
uint32_t m_display_state[0x20]; // display matrix rows data (last bit is used for always-on)
uint16_t m_display_segmask[0x20]; // if not 0, display matrix row is a digit, mask indicates connected segments
diff --git a/src/mame/includes/flstory.h b/src/mame/includes/flstory.h
index a64e59db53d..9abe811a42e 100644
--- a/src/mame/includes/flstory.h
+++ b/src/mame/includes/flstory.h
@@ -3,6 +3,7 @@
#include "machine/gen_latch.h"
#include "sound/msm5232.h"
+#include "machine/taito68705interface.h"
class flstory_state : public driver_device
{
@@ -15,7 +16,7 @@ public:
m_workram(*this, "workram"),
m_maincpu(*this, "maincpu"),
m_audiocpu(*this, "audiocpu"),
- m_mcu(*this, "mcu"),
+ m_bmcu(*this, "bmcu"),
m_msm(*this, "msm"),
m_gfxdecode(*this, "gfxdecode"),
m_palette(*this, "palette"),
@@ -46,26 +47,14 @@ public:
uint8_t m_snd_ctrl2;
uint8_t m_snd_ctrl3;
- /* protection */
- uint8_t m_from_main;
- uint8_t m_from_mcu;
- int m_mcu_sent;
- int m_main_sent;
- uint8_t m_port_a_in;
- uint8_t m_port_a_out;
- uint8_t m_ddr_a;
- uint8_t m_port_b_in;
- uint8_t m_port_b_out;
- uint8_t m_ddr_b;
- uint8_t m_port_c_in;
- uint8_t m_port_c_out;
- uint8_t m_ddr_c;
+ /* protection sims */
+ uint8_t m_from_mcu;
int m_mcu_select;
/* devices */
required_device<cpu_device> m_maincpu;
required_device<cpu_device> m_audiocpu;
- optional_device<cpu_device> m_mcu;
+ optional_device<taito68705_mcu_device> m_bmcu;
required_device<msm5232_device> m_msm;
required_device<gfxdecode_device> m_gfxdecode;
required_device<palette_device> m_palette;
@@ -89,18 +78,6 @@ public:
DECLARE_WRITE8_MEMBER(nmi_enable_w);
DECLARE_READ8_MEMBER(rumba_mcu_r);
DECLARE_WRITE8_MEMBER(rumba_mcu_w);
- DECLARE_READ8_MEMBER(flstory_68705_port_a_r);
- DECLARE_WRITE8_MEMBER(flstory_68705_port_a_w);
- DECLARE_WRITE8_MEMBER(flstory_68705_ddr_a_w);
- DECLARE_READ8_MEMBER(flstory_68705_port_b_r);
- DECLARE_WRITE8_MEMBER(flstory_68705_port_b_w);
- DECLARE_WRITE8_MEMBER(flstory_68705_ddr_b_w);
- DECLARE_READ8_MEMBER(flstory_68705_port_c_r);
- DECLARE_WRITE8_MEMBER(flstory_68705_port_c_w);
- DECLARE_WRITE8_MEMBER(flstory_68705_ddr_c_w);
- DECLARE_WRITE8_MEMBER(flstory_mcu_w);
- DECLARE_READ8_MEMBER(flstory_mcu_r);
- DECLARE_READ8_MEMBER(flstory_mcu_status_r);
DECLARE_WRITE8_MEMBER(onna34ro_mcu_w);
DECLARE_READ8_MEMBER(onna34ro_mcu_r);
DECLARE_READ8_MEMBER(onna34ro_mcu_status_r);
diff --git a/src/mame/includes/fuukifg2.h b/src/mame/includes/fuukifg2.h
index daea6190458..58bdc8469d5 100644
--- a/src/mame/includes/fuukifg2.h
+++ b/src/mame/includes/fuukifg2.h
@@ -56,7 +56,7 @@ public:
emu_timer *m_raster_interrupt_timer;
DECLARE_WRITE16_MEMBER(vregs_w);
- DECLARE_WRITE16_MEMBER(sound_command_w);
+ DECLARE_WRITE8_MEMBER(sound_command_w);
DECLARE_WRITE8_MEMBER(sound_rombank_w);
DECLARE_WRITE16_MEMBER(vram_0_w);
DECLARE_WRITE16_MEMBER(vram_1_w);
diff --git a/src/mame/includes/gaelco.h b/src/mame/includes/gaelco.h
index 2f558fe82d3..a87e6a7a33a 100644
--- a/src/mame/includes/gaelco.h
+++ b/src/mame/includes/gaelco.h
@@ -39,9 +39,9 @@ public:
/* video-related */
tilemap_t *m_tilemap[2];
- DECLARE_WRITE16_MEMBER(bigkarnk_sound_command_w);
- DECLARE_WRITE16_MEMBER(bigkarnk_coin_w);
- DECLARE_WRITE16_MEMBER(OKIM6295_bankswitch_w);
+ DECLARE_WRITE8_MEMBER(bigkarnk_sound_command_w);
+ DECLARE_WRITE8_MEMBER(bigkarnk_coin_w);
+ DECLARE_WRITE8_MEMBER(OKIM6295_bankswitch_w);
DECLARE_WRITE16_MEMBER(gaelco_vram_encrypted_w);
DECLARE_WRITE16_MEMBER(gaelco_encrypted_w);
DECLARE_WRITE16_MEMBER(thoop_vram_encrypted_w);
diff --git a/src/mame/includes/gsword.h b/src/mame/includes/gsword.h
index 27496342010..24204bf4ed5 100644
--- a/src/mame/includes/gsword.h
+++ b/src/mame/includes/gsword.h
@@ -5,35 +5,33 @@
#include "sound/ay8910.h"
#include "sound/msm5205.h"
-class gsword_state : public driver_device
+class gsword_state_base : public driver_device
{
public:
- gsword_state(const machine_config &mconfig, device_type type, const char *tag)
- : driver_device(mconfig, type, tag),
- m_maincpu(*this, "maincpu"),
- m_audiocpu(*this, "audiocpu"),
- m_subcpu(*this, "sub"),
- m_ay0(*this, "ay1"),
- m_ay1(*this, "ay2"),
- m_msm(*this, "msm"),
- m_gfxdecode(*this, "gfxdecode"),
- m_palette(*this, "palette"),
- m_soundlatch(*this, "soundlatch"),
- m_spritetile_ram(*this, "spritetile_ram"),
- m_spritexy_ram(*this, "spritexy_ram"),
- m_spriteattrib_ram(*this, "spriteattram"),
- m_videoram(*this, "videoram"),
- m_cpu2_ram(*this, "cpu2_ram") { }
+ gsword_state_base(const machine_config &mconfig, device_type type, const char *tag)
+ : driver_device(mconfig, type, tag)
+ , m_maincpu(*this, "maincpu")
+ , m_audiocpu(*this, "audiocpu")
+ , m_subcpu(*this, "sub")
+ , m_ay0(*this, "ay1")
+ , m_ay1(*this, "ay2")
+ , m_gfxdecode(*this, "gfxdecode")
+ , m_palette(*this, "palette")
+ , m_spritetile_ram(*this, "spritetile_ram")
+ , m_spritexy_ram(*this, "spritexy_ram")
+ , m_spriteattrib_ram(*this, "spriteattram")
+ , m_videoram(*this, "videoram")
+ , m_cpu2_ram(*this, "cpu2_ram")
+ {
+ }
required_device<cpu_device> m_maincpu;
required_device<cpu_device> m_audiocpu;
optional_device<cpu_device> m_subcpu;
required_device<ay8910_device> m_ay0;
required_device<ay8910_device> m_ay1;
- optional_device<msm5205_device> m_msm;
required_device<gfxdecode_device> m_gfxdecode;
required_device<palette_device> m_palette;
- optional_device<generic_latch_8_device> m_soundlatch; // not josvolly
required_shared_ptr<uint8_t> m_spritetile_ram;
required_shared_ptr<uint8_t> m_spritexy_ram;
@@ -41,11 +39,8 @@ public:
required_shared_ptr<uint8_t> m_videoram;
required_shared_ptr<uint8_t> m_cpu2_ram;
- int m_coins; //currently initialized but not used
int m_fake8910_0;
int m_fake8910_1;
- int m_nmi_enable;
- int m_protect_hack;
int m_charbank;
int m_charpalbank;
int m_flipscreen;
@@ -56,30 +51,93 @@ public:
DECLARE_WRITE8_MEMBER(charbank_w);
DECLARE_WRITE8_MEMBER(videoctrl_w);
DECLARE_WRITE8_MEMBER(scroll_w);
- DECLARE_WRITE8_MEMBER(adpcm_soundcommand_w);
- DECLARE_WRITE8_MEMBER(nmi_set_w);
DECLARE_WRITE8_MEMBER(ay8910_control_port_0_w);
DECLARE_WRITE8_MEMBER(ay8910_control_port_1_w);
DECLARE_READ8_MEMBER(fake_0_r);
DECLARE_READ8_MEMBER(fake_1_r);
- // gsword specific
- DECLARE_READ8_MEMBER(gsword_hack_r);
- DECLARE_WRITE8_MEMBER(gsword_adpcm_data_w);
- DECLARE_READ8_MEMBER(gsword_8741_2_r);
- DECLARE_READ8_MEMBER(gsword_8741_3_r);
-
TILE_GET_INFO_MEMBER(get_bg_tile_info);
- DECLARE_DRIVER_INIT(gsword);
- DECLARE_DRIVER_INIT(gsword2);
virtual void machine_start() override;
virtual void machine_reset() override;
virtual void video_start() override;
- DECLARE_PALETTE_INIT(gsword);
- DECLARE_PALETTE_INIT(josvolly);
uint32_t screen_update_gsword(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
- INTERRUPT_GEN_MEMBER(gsword_snd_interrupt);
void draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect);
};
+
+
+class gsword_state : public gsword_state_base
+{
+public:
+ gsword_state(const machine_config &mconfig, device_type type, const char *tag)
+ : gsword_state_base(mconfig, type, tag)
+ , m_soundlatch(*this, "soundlatch")
+ , m_msm(*this, "msm")
+ , m_protect_hack(false)
+ , m_nmi_enable(false)
+ {
+ }
+
+ DECLARE_READ8_MEMBER(hack_r);
+ DECLARE_WRITE8_MEMBER(nmi_set_w);
+ DECLARE_WRITE8_MEMBER(sound_command_w);
+ DECLARE_WRITE8_MEMBER(adpcm_data_w);
+ DECLARE_READ8_MEMBER(i8741_2_r);
+ DECLARE_READ8_MEMBER(i8741_3_r);
+
+ INTERRUPT_GEN_MEMBER(sound_interrupt);
+
+ DECLARE_DRIVER_INIT(gsword);
+ DECLARE_DRIVER_INIT(gsword2);
+
+ DECLARE_PALETTE_INIT(gsword);
+
+ virtual void machine_start() override;
+ virtual void machine_reset() override;
+
+private:
+ required_device<generic_latch_8_device> m_soundlatch;
+ required_device<msm5205_device> m_msm;
+
+ bool m_protect_hack;
+ bool m_nmi_enable;
+};
+
+
+class josvolly_state : public gsword_state_base
+{
+public:
+ josvolly_state(const machine_config &mconfig, device_type type, const char *tag)
+ : gsword_state_base(mconfig, type, tag)
+ , m_cpu2_nmi_enable(false)
+ , m_mcu1_p1(0xffU)
+ , m_mcu1_p2(0xffU)
+ , m_mcu2_p1(0xffU)
+ {
+ }
+
+ DECLARE_READ8_MEMBER(mcu1_p1_r);
+ DECLARE_READ8_MEMBER(mcu1_p2_r);
+ DECLARE_READ8_MEMBER(mcu2_p1_r);
+ DECLARE_READ8_MEMBER(mcu2_p2_r);
+ DECLARE_READ8_MEMBER(mcu2_test_r);
+
+ DECLARE_WRITE8_MEMBER(cpu2_nmi_enable_w);
+ DECLARE_WRITE8_MEMBER(cpu2_irq_clear_w);
+ DECLARE_WRITE8_MEMBER(mcu1_p1_w);
+ DECLARE_WRITE8_MEMBER(mcu1_p2_w);
+ DECLARE_WRITE8_MEMBER(mcu2_p1_w);
+ DECLARE_WRITE8_MEMBER(mcu2_p2_w);
+
+ DECLARE_PALETTE_INIT(josvolly);
+
+ virtual void machine_start() override;
+ virtual void machine_reset() override;
+
+private:
+ bool m_cpu2_nmi_enable;
+ u8 m_mcu1_p1;
+ u8 m_mcu1_p2;
+ u8 m_mcu2_p1;
+};
diff --git a/src/mame/includes/harddriv.h b/src/mame/includes/harddriv.h
index 24797461b21..1ed1894258a 100644
--- a/src/mame/includes/harddriv.h
+++ b/src/mame/includes/harddriv.h
@@ -16,6 +16,7 @@
#include "machine/mc68681.h"
#include "machine/asic65.h"
#include "machine/timekpr.h"
+#include "bus/rs232/rs232.h"
#define HARDDRIV_MASTER_CLOCK XTAL_32MHz
#define HARDDRIV_GSP_CLOCK XTAL_48MHz
@@ -393,6 +394,12 @@ protected:
uint8_t m_st68k_sloop_bank;
offs_t m_st68k_last_alt_sloop_offset;
+ uint8_t m_sel_select;
+ uint8_t m_sel1_data;
+ uint8_t m_sel2_data;
+ uint8_t m_sel3_data;
+ uint8_t m_sel4_data;
+
#define MAX_MSP_SYNC 16
uint32_t * m_dataptr[MAX_MSP_SYNC];
uint32_t m_dataval[MAX_MSP_SYNC];
@@ -447,6 +454,8 @@ protected:
int get_hblank(screen_device &screen) const { return (screen.hpos() > (screen.width() * 9 / 10)); }
optional_device<atari_slapstic_device> m_slapstic_device;
+ optional_device<rs232_port_device> m_rs232;
+
protected:
//virtual machine_config_constructor device_mconfig_additions() const;
virtual void device_start() override;
diff --git a/src/mame/includes/hh_tms1k.h b/src/mame/includes/hh_tms1k.h
index d08aa797a76..b24642aa789 100644
--- a/src/mame/includes/hh_tms1k.h
+++ b/src/mame/includes/hh_tms1k.h
@@ -51,9 +51,9 @@ public:
virtual DECLARE_WRITE_LINE_MEMBER(auto_power_off);
// display common
- int m_display_wait; // led/lamp off-delay in microseconds (default 33ms)
- int m_display_maxy; // display matrix number of rows
- int m_display_maxx; // display matrix number of columns (max 31 for now)
+ int m_display_wait; // led/lamp off-delay in microseconds (default 33ms)
+ int m_display_maxy; // display matrix number of rows
+ int m_display_maxx; // display matrix number of columns (max 31 for now)
uint32_t m_grid; // VFD/LED current row data
uint32_t m_plate; // VFD/LED current column data
diff --git a/src/mame/includes/hh_ucom4.h b/src/mame/includes/hh_ucom4.h
index d71115e3fc4..4a0194e3cb0 100644
--- a/src/mame/includes/hh_ucom4.h
+++ b/src/mame/includes/hh_ucom4.h
@@ -45,9 +45,9 @@ public:
DECLARE_INPUT_CHANGED_MEMBER(single_interrupt_line);
// display common
- int m_display_wait; // led/lamp off-delay in microseconds (default 33ms)
- int m_display_maxy; // display matrix number of rows
- int m_display_maxx; // display matrix number of columns (max 31 for now)
+ int m_display_wait; // led/lamp off-delay in microseconds (default 33ms)
+ int m_display_maxy; // display matrix number of rows
+ int m_display_maxx; // display matrix number of columns (max 31 for now)
uint32_t m_grid; // VFD current row data
uint32_t m_plate; // VFD current column data
diff --git a/src/mame/includes/lkage.h b/src/mame/includes/lkage.h
index e524e974885..913570792ab 100644
--- a/src/mame/includes/lkage.h
+++ b/src/mame/includes/lkage.h
@@ -2,6 +2,7 @@
// copyright-holders:Phil Stroffolino
#include "machine/gen_latch.h"
+#include "machine/taito68705interface.h"
class lkage_state : public driver_device
{
@@ -14,7 +15,7 @@ public:
m_videoram(*this, "videoram"),
m_maincpu(*this, "maincpu"),
m_audiocpu(*this, "audiocpu"),
- m_mcu(*this, "mcu"),
+ m_bmcu(*this, "bmcu"),
m_gfxdecode(*this, "gfxdecode"),
m_palette(*this, "palette"),
m_soundlatch(*this, "soundlatch") { }
@@ -38,21 +39,6 @@ public:
int m_sound_nmi_enable;
int m_pending_nmi;
- /* mcu */
- uint8_t m_from_main;
- uint8_t m_from_mcu;
- int m_mcu_sent;
- int m_main_sent;
- uint8_t m_port_a_in;
- uint8_t m_port_a_out;
- uint8_t m_ddr_a;
- uint8_t m_port_b_in;
- uint8_t m_port_b_out;
- uint8_t m_ddr_b;
- uint8_t m_port_c_in;
- uint8_t m_port_c_out;
- uint8_t m_ddr_c;
-
/* lkageb fake mcu */
uint8_t m_mcu_val;
int m_mcu_ready; /* cpu data/mcu ready status */
@@ -60,7 +46,7 @@ public:
/* devices */
required_device<cpu_device> m_maincpu;
required_device<cpu_device> m_audiocpu;
- optional_device<cpu_device> m_mcu;
+ optional_device<taito68705_mcu_device> m_bmcu;
required_device<gfxdecode_device> m_gfxdecode;
required_device<palette_device> m_palette;
required_device<generic_latch_8_device> m_soundlatch;
@@ -73,22 +59,10 @@ public:
DECLARE_READ8_MEMBER(fake_mcu_r);
DECLARE_WRITE8_MEMBER(fake_mcu_w);
DECLARE_READ8_MEMBER(fake_status_r);
- DECLARE_READ8_MEMBER(lkage_68705_port_a_r);
- DECLARE_WRITE8_MEMBER(lkage_68705_port_a_w);
- DECLARE_WRITE8_MEMBER(lkage_68705_ddr_a_w);
- DECLARE_READ8_MEMBER(lkage_68705_port_b_r);
- DECLARE_WRITE8_MEMBER(lkage_68705_port_b_w);
- DECLARE_WRITE8_MEMBER(lkage_68705_ddr_b_w);
- DECLARE_READ8_MEMBER(lkage_68705_port_c_r);
- DECLARE_WRITE8_MEMBER(lkage_68705_port_c_w);
- DECLARE_WRITE8_MEMBER(lkage_68705_ddr_c_w);
- DECLARE_WRITE8_MEMBER(lkage_mcu_w);
- DECLARE_READ8_MEMBER(lkage_mcu_r);
- DECLARE_READ8_MEMBER(lkage_mcu_status_r);
+
DECLARE_WRITE8_MEMBER(lkage_videoram_w);
DECLARE_DRIVER_INIT(bygone);
DECLARE_DRIVER_INIT(lkage);
- DECLARE_DRIVER_INIT(lkageb);
TILE_GET_INFO_MEMBER(get_bg_tile_info);
TILE_GET_INFO_MEMBER(get_fg_tile_info);
TILE_GET_INFO_MEMBER(get_tx_tile_info);
diff --git a/src/mame/includes/lsasquad.h b/src/mame/includes/lsasquad.h
index 69246e90a14..b25a4cacedb 100644
--- a/src/mame/includes/lsasquad.h
+++ b/src/mame/includes/lsasquad.h
@@ -1,5 +1,6 @@
// license:BSD-3-Clause
// copyright-holders:Nicola Salmoria
+#include "machine/taito68705interface.h"
class lsasquad_state : public driver_device
{
@@ -12,7 +13,7 @@ public:
m_priority_prom(*this, "prio_prom"),
m_maincpu(*this, "maincpu"),
m_audiocpu(*this, "audiocpu"),
- m_mcu(*this, "mcu"),
+ m_bmcu(*this, "bmcu"),
m_gfxdecode(*this, "gfxdecode"),
m_palette(*this, "palette") { }
@@ -29,22 +30,11 @@ public:
int m_sound_cmd;
int m_sound_result;
- /* mcu */
- uint8_t m_from_main;
- uint8_t m_from_mcu;
- int m_mcu_sent;
- int m_main_sent;
- uint8_t m_port_a_in;
- uint8_t m_port_a_out;
- uint8_t m_ddr_a;
- uint8_t m_port_b_in;
- uint8_t m_port_b_out;
- uint8_t m_ddr_b;
/* devices */
required_device<cpu_device> m_maincpu;
required_device<cpu_device> m_audiocpu;
- optional_device<cpu_device> m_mcu;
+ optional_device<taito68705_mcu_device> m_bmcu;
required_device<gfxdecode_device> m_gfxdecode;
required_device<palette_device> m_palette;
@@ -58,14 +48,7 @@ public:
DECLARE_READ8_MEMBER(lsasquad_sound_status_r);
DECLARE_READ8_MEMBER(daikaiju_sh_sound_command_r);
DECLARE_READ8_MEMBER(daikaiju_sound_status_r);
- DECLARE_READ8_MEMBER(lsasquad_68705_port_a_r);
- DECLARE_WRITE8_MEMBER(lsasquad_68705_port_a_w);
- DECLARE_WRITE8_MEMBER(lsasquad_68705_ddr_a_w);
- DECLARE_READ8_MEMBER(lsasquad_68705_port_b_r);
- DECLARE_WRITE8_MEMBER(lsasquad_68705_port_b_w);
- DECLARE_WRITE8_MEMBER(lsasquad_68705_ddr_b_w);
- DECLARE_WRITE8_MEMBER(lsasquad_mcu_w);
- DECLARE_READ8_MEMBER(lsasquad_mcu_r);
+
DECLARE_READ8_MEMBER(lsasquad_mcu_status_r);
DECLARE_READ8_MEMBER(daikaiju_mcu_status_r);
DECLARE_WRITE8_MEMBER(unk);
diff --git a/src/mame/includes/mario.h b/src/mame/includes/mario.h
index 40161d4f187..6201d67bb36 100644
--- a/src/mame/includes/mario.h
+++ b/src/mame/includes/mario.h
@@ -6,7 +6,7 @@
#include "machine/gen_latch.h"
#include "machine/z80dma.h"
-#define OLD_SOUND (1)
+#define OLD_SOUND (0)
#if !OLD_SOUND
#include "machine/netlist.h"
@@ -61,6 +61,7 @@ public:
m_discrete(*this, "discrete"),
#else
m_audio_snd0(*this, "snd_nl:snd0"),
+ m_audio_snd1(*this, "snd_nl:snd1"),
m_audio_snd7(*this, "snd_nl:snd7"),
m_audio_dac(*this, "snd_nl:dac"),
#endif
@@ -82,6 +83,7 @@ public:
optional_device<discrete_device> m_discrete;
#else
optional_device<netlist_mame_logic_input_t> m_audio_snd0;
+ optional_device<netlist_mame_logic_input_t> m_audio_snd1;
optional_device<netlist_mame_logic_input_t> m_audio_snd7;
optional_device<netlist_mame_int_input_t> m_audio_dac;
#endif
diff --git a/src/mame/includes/msisaac.h b/src/mame/includes/msisaac.h
index 2aff0d207a2..7c58a40259f 100644
--- a/src/mame/includes/msisaac.h
+++ b/src/mame/includes/msisaac.h
@@ -1,7 +1,7 @@
// license:GPL-2.0+
// copyright-holders:Jarek Burczynski
-#include "machine/buggychl.h"
+#include "machine/taito68705interface.h"
#include "machine/gen_latch.h"
#include "sound/msm5232.h"
@@ -58,7 +58,7 @@ public:
/* devices */
required_device<cpu_device> m_audiocpu;
required_device<cpu_device> m_maincpu;
- optional_device<buggychl_mcu_device> m_bmcu;
+ optional_device<taito68705_mcu_device> m_bmcu;
required_device<msm5232_device> m_msm;
required_device<gfxdecode_device> m_gfxdecode;
required_device<palette_device> m_palette;
diff --git a/src/mame/includes/mzr8105.h b/src/mame/includes/mzr8105.h
deleted file mode 100644
index 6b597ff4e25..00000000000
--- a/src/mame/includes/mzr8105.h
+++ /dev/null
@@ -1,30 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Joakim Larsson Edstrom
-/********************************************************************************
- *
- * mame/includes/mzr8105
- *
- ********************************************************************************/
-
-#ifndef MZR8105_H
-#define MZR8105_H
-#pragma once
-
-#include "bus/vme/vme.h"
-
-class mzr8105_state : public driver_device
-{
-public:
-mzr8105_state(const machine_config &mconfig, device_type type, const char *tag) :
- driver_device (mconfig, type, tag)
- ,m_maincpu (*this, "maincpu")
- {
- }
-
- virtual void machine_start() override;
-private:
- required_device<cpu_device> m_maincpu;
-};
-
-
-#endif // MZR8105_H
diff --git a/src/mame/includes/mzr8300.h b/src/mame/includes/mzr8300.h
deleted file mode 100644
index 1ae01af38c2..00000000000
--- a/src/mame/includes/mzr8300.h
+++ /dev/null
@@ -1,35 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Joakim Larsson Edstrom
-/********************************************************************************
- *
- * mame/includes/mzr8105
- *
- ********************************************************************************/
-
-#ifndef MZR8300_H
-#define MZR8300_H
-#pragma once
-
-#include "emu.h"
-#include "bus/vme/vme.h"
-#include "machine/z80sio.h"
-
-class vme_p1_mzr8300_device : public device_t, public device_vme_p1_card_interface
-{
-public:
- // construction/destruction
- vme_p1_mzr8300_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
- vme_p1_mzr8300_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, uint32_t clock, const char *shortname, const char *source);
-
- // optional information overrides
- virtual machine_config_constructor device_mconfig_additions() const override;
-
-protected:
- // device-level overrides
- virtual void device_start() override;
- virtual void device_reset() override;
-private:
- required_device<upd7201N_device> m_sio0;
-};
-
-#endif // MZR8300_H
diff --git a/src/mame/includes/namcofl.h b/src/mame/includes/namcofl.h
index e60366963ce..acf2f54cefc 100644
--- a/src/mame/includes/namcofl.h
+++ b/src/mame/includes/namcofl.h
@@ -1,7 +1,7 @@
// license:BSD-3-Clause
// copyright-holders:R. Belmont, ElSemi
#include "namcos2.h"
-#include "video/c116.h"
+#include "video/namco_c116.h"
#define NAMCOFL_HTOTAL (288) /* wrong */
#define NAMCOFL_HBSTART (288)
diff --git a/src/mame/includes/namconb1.h b/src/mame/includes/namconb1.h
index e348f079a74..e484888e9fe 100644
--- a/src/mame/includes/namconb1.h
+++ b/src/mame/includes/namconb1.h
@@ -8,7 +8,7 @@
#include "namcos2.h"
#include "machine/eeprompar.h"
-#include "video/c116.h"
+#include "video/namco_c116.h"
#define NAMCONB1_HTOTAL (288) /* wrong */
#define NAMCONB1_HBSTART (288)
diff --git a/src/mame/includes/namcos1.h b/src/mame/includes/namcos1.h
index ceb5034f539..5b1ea68346c 100644
--- a/src/mame/includes/namcos1.h
+++ b/src/mame/includes/namcos1.h
@@ -3,7 +3,7 @@
#include "machine/c117.h"
#include "sound/dac.h"
#include "sound/namco.h"
-#include "video/c116.h"
+#include "video/namco_c116.h"
class namcos1_state : public driver_device
{
diff --git a/src/mame/includes/namcos2.h b/src/mame/includes/namcos2.h
index 2221ac52119..5ad57bee517 100644
--- a/src/mame/includes/namcos2.h
+++ b/src/mame/includes/namcos2.h
@@ -11,6 +11,8 @@
#include "namcoic.h"
#include "cpu/m6502/m3745x.h"
#include "video/c45.h"
+#include "machine/namco_c148.h"
+#include "machine/namco_c139.h"
/* CPU reference numbers */
@@ -101,6 +103,9 @@ public:
m_dspmaster(*this, "dspmaster"),
m_dspslave(*this, "dspslave"),
m_c68(*this, "c68"),
+ m_master_intc(*this, "master_intc"),
+ m_slave_intc(*this, "slave_intc"),
+ m_sci(*this, "sci"),
m_gpu(*this, "gpu"),
m_gametype(0),
m_c169_roz_videoram(*this, "rozvideoram", 0),
@@ -119,21 +124,26 @@ public:
optional_device<cpu_device> m_dspmaster;
optional_device<cpu_device> m_dspslave;
optional_device<m37450_device> m_c68;
+ optional_device<namco_c148_device> m_master_intc;
+ optional_device<namco_c148_device> m_slave_intc;
+ optional_device<namco_c139_device> m_sci;
optional_device<cpu_device> m_gpu; //to be moved to namco21_state after disentangling
// game type helpers
bool is_system21();
int m_gametype;
- emu_timer *m_posirq_timer;
int m_mcu_analog_ctrl;
int m_mcu_analog_data;
int m_mcu_analog_complete;
std::unique_ptr<uint8_t[]> m_eeprom;
- uint16_t m_68k_master_C148[0x20];
- uint16_t m_68k_slave_C148[0x20];
- uint16_t m_68k_gpu_C148[0x20];
+ DECLARE_WRITE8_MEMBER(sound_reset_w);
+ DECLARE_WRITE8_MEMBER(system_reset_w);
+ void reset_all_subcpus(int state);
+
+ TIMER_DEVICE_CALLBACK_MEMBER(screen_scanline);
+
// C123 Tilemap Emulation
// TODO: merge with namcos1.cpp implementation and convert to device
public:
@@ -218,23 +228,9 @@ public:
// general
void zdrawgfxzoom(screen_device &screen, bitmap_ind16 &dest_bmp, const rectangle &clip, gfx_element *gfx, uint32_t code, uint32_t color, int flipx, int flipy, int sx, int sy, int scalex, int scaley, int zpos);
void zdrawgfxzoom(screen_device &screen, bitmap_rgb32 &dest_bmp, const rectangle &clip, gfx_element *gfx, uint32_t code, uint32_t color, int flipx, int flipy, int sx, int sy, int scalex, int scaley, int zpos);
- INTERRUPT_GEN_MEMBER(namcos2_68k_master_vblank);
- INTERRUPT_GEN_MEMBER(namcos2_68k_slave_vblank);
- INTERRUPT_GEN_MEMBER(namcos2_68k_gpu_vblank);
- TIMER_CALLBACK_MEMBER(namcos2_posirq_tick);
- void adjust_posirq_timer( int scanline );
- void init_c148();
- void reset_all_subcpus(int state);
- uint16_t readwrite_c148( address_space &space, offs_t offset, uint16_t data, int bWrite );
- int get_posirq_scanline();
DECLARE_WRITE8_MEMBER( namcos2_68k_eeprom_w );
DECLARE_READ8_MEMBER( namcos2_68k_eeprom_r );
- DECLARE_WRITE16_MEMBER( namcos2_68k_master_C148_w );
- DECLARE_READ16_MEMBER( namcos2_68k_master_C148_r );
-
- DECLARE_WRITE16_MEMBER( namcos2_68k_slave_C148_w );
- DECLARE_READ16_MEMBER( namcos2_68k_slave_C148_r );
DECLARE_WRITE8_MEMBER( namcos2_mcu_port_d_w );
DECLARE_READ8_MEMBER( namcos2_mcu_port_d_r );
@@ -244,9 +240,6 @@ public:
DECLARE_READ8_MEMBER( namcos2_mcu_analog_port_r );
DECLARE_WRITE8_MEMBER( namcos2_sound_bankselect_w );
- /* TODO: this should belong to namcos21_state */
- DECLARE_WRITE16_MEMBER( namcos21_68k_gpu_C148_w );
- DECLARE_READ16_MEMBER( namcos21_68k_gpu_C148_r );
required_device<cpu_device> m_maincpu;
optional_device<cpu_device> m_audiocpu;
optional_device<cpu_device> m_slave;
@@ -264,7 +257,6 @@ public:
m_dpram(*this, "dpram"),
m_paletteram(*this, "paletteram"),
m_spriteram(*this, "spriteram"),
- m_serial_comms_ram(*this, "serialram"),
m_rozram(*this, "rozram"),
m_roz_ctrl(*this, "rozctrl"),
m_c45_road(*this, "c45_road")
@@ -331,10 +323,6 @@ public:
DECLARE_WRITE16_MEMBER( rozram_word_w );
DECLARE_READ16_MEMBER( gfx_ctrl_r );
DECLARE_WRITE16_MEMBER( gfx_ctrl_w );
- DECLARE_READ16_MEMBER( serial_comms_ram_r );
- DECLARE_WRITE16_MEMBER( serial_comms_ram_w );
- DECLARE_READ16_MEMBER( serial_comms_ctrl_r );
- DECLARE_WRITE16_MEMBER( serial_comms_ctrl_w );
void draw_sprite_init();
void update_palette();
@@ -345,11 +333,11 @@ public:
uint16_t get_palette_register( int which );
int get_pos_irq_scanline() { return (get_palette_register(5) - 32) & 0xff; }
-
+ TIMER_DEVICE_CALLBACK_MEMBER(screen_scanline);
+
required_shared_ptr<uint8_t> m_dpram; /* 2Kx8 */
required_shared_ptr<uint16_t> m_paletteram;
optional_shared_ptr<uint16_t> m_spriteram;
- optional_shared_ptr<uint16_t> m_serial_comms_ram;
optional_shared_ptr<uint16_t> m_rozram;
optional_shared_ptr<uint16_t> m_roz_ctrl;
tilemap_t *m_tilemap_roz;
diff --git a/src/mame/includes/namcos21.h b/src/mame/includes/namcos21.h
index e4e9e4c6adb..0ec60ea94e5 100644
--- a/src/mame/includes/namcos21.h
+++ b/src/mame/includes/namcos21.h
@@ -54,7 +54,8 @@ public:
m_ptrom24(*this,"point24"),
m_ptrom16(*this,"point16"),
m_dsp(*this, "dsp"),
- m_io_gearbox(*this, "gearbox")
+ m_io_gearbox(*this, "gearbox"),
+ m_gpu_intc(*this, "gpu_intc")
{ }
optional_shared_ptr<uint16_t> m_winrun_dspbios;
@@ -68,8 +69,10 @@ public:
optional_device<cpu_device> m_dsp;
optional_device<namcoio_gearbox_device> m_io_gearbox;
+ optional_device<namco_c148_device> m_gpu_intc;
std::unique_ptr<uint8_t[]> m_videoram;
+ std::unique_ptr<uint8_t[]> m_maskram;
std::unique_ptr<uint16_t[]> m_winrun_dspcomram;
uint16_t m_winrun_poly_buf[WINRUN_MAX_POLY_PARAM];
int m_winrun_poly_index;
@@ -134,10 +137,6 @@ public:
DECLARE_WRITE16_MEMBER(namcos2_68k_dualportram_word_w);
DECLARE_READ8_MEMBER(namcos2_dualportram_byte_r);
DECLARE_WRITE8_MEMBER(namcos2_dualportram_byte_w);
- DECLARE_WRITE16_MEMBER(NAMCO_C139_SCI_buffer_w);
- DECLARE_READ16_MEMBER(NAMCO_C139_SCI_buffer_r);
- DECLARE_WRITE16_MEMBER(NAMCO_C139_SCI_register_w);
- DECLARE_READ16_MEMBER(NAMCO_C139_SCI_register_r);
DECLARE_READ16_MEMBER(winrun_dspcomram_r);
DECLARE_WRITE16_MEMBER(winrun_dspcomram_w);
DECLARE_READ16_MEMBER(winrun_cuskey_r);
@@ -159,9 +158,12 @@ public:
DECLARE_WRITE16_MEMBER(winrun_gpu_register_w);
DECLARE_WRITE16_MEMBER(winrun_gpu_videoram_w);
DECLARE_READ16_MEMBER(winrun_gpu_videoram_r);
+
+ TIMER_DEVICE_CALLBACK_MEMBER(screen_scanline);
uint8_t m_gearbox_state;
DECLARE_CUSTOM_INPUT_MEMBER(driveyes_gearbox_r);
+
DECLARE_DRIVER_INIT(driveyes);
DECLARE_DRIVER_INIT(winrun);
DECLARE_DRIVER_INIT(starblad);
@@ -176,6 +178,7 @@ public:
void allocate_poly_framebuffer();
void clear_poly_framebuffer();
void copy_visible_poly_framebuffer(bitmap_ind16 &bitmap, const rectangle &clip, int zlo, int zhi);
+ void winrun_bitmap_draw(bitmap_ind16 &bitmap, const rectangle &cliprect);
void renderscanline_flat(const edge *e1, const edge *e2, int sy, unsigned color, int depthcueenable);
void rendertri(const n21_vertex *v0, const n21_vertex *v1, const n21_vertex *v2, unsigned color, int depthcueenable);
void draw_quad(int sx[4], int sy[4], int zcode[4], int color);
@@ -187,6 +190,5 @@ public:
int init_dsp();
void render_slave_output(uint16_t data);
void winrun_flush_poly();
- void winrun_bitmap_draw(bitmap_ind16 &bitmap, const rectangle &cliprect);
void init(int game_type);
};
diff --git a/src/mame/includes/nycaptor.h b/src/mame/includes/nycaptor.h
index 267d627439a..25a12fdac26 100644
--- a/src/mame/includes/nycaptor.h
+++ b/src/mame/includes/nycaptor.h
@@ -3,6 +3,7 @@
#include "machine/gen_latch.h"
#include "sound/msm5232.h"
+#include "machine/taito68705interface.h"
class nycaptor_state : public driver_device
{
@@ -16,7 +17,7 @@ public:
m_maincpu(*this, "maincpu"),
m_audiocpu(*this, "audiocpu"),
m_subcpu(*this, "sub"),
- m_mcu(*this, "mcu"),
+ m_bmcu(*this, "bmcu"),
m_msm(*this, "msm"),
m_gfxdecode(*this, "gfxdecode"),
m_palette(*this, "palette"),
@@ -36,21 +37,6 @@ public:
uint8_t m_char_bank;
uint8_t m_palette_bank;
- /* mcu */
- uint8_t m_from_main;
- uint8_t m_from_mcu;
- int m_mcu_sent;
- int m_main_sent;
- uint8_t m_port_a_in;
- uint8_t m_port_a_out;
- uint8_t m_ddr_a;
- uint8_t m_port_b_in;
- uint8_t m_port_b_out;
- uint8_t m_ddr_b;
- uint8_t m_port_c_in;
- uint8_t m_port_c_out;
- uint8_t m_ddr_c;
-
/* misc */
int m_generic_control_reg;
int m_sound_nmi_enable;
@@ -64,7 +50,7 @@ public:
required_device<cpu_device> m_maincpu;
required_device<cpu_device> m_audiocpu;
required_device<cpu_device> m_subcpu;
- optional_device<cpu_device> m_mcu;
+ optional_device<taito68705_mcu_device> m_bmcu;
required_device<msm5232_device> m_msm;
required_device<gfxdecode_device> m_gfxdecode;
required_device<palette_device> m_palette;
@@ -88,17 +74,7 @@ public:
DECLARE_READ8_MEMBER(cyclshtg_mcu_status_r1);
DECLARE_WRITE8_MEMBER(cyclshtg_generic_control_w);
DECLARE_READ8_MEMBER(unk_r);
- DECLARE_READ8_MEMBER(nycaptor_68705_port_a_r);
- DECLARE_WRITE8_MEMBER(nycaptor_68705_port_a_w);
- DECLARE_WRITE8_MEMBER(nycaptor_68705_ddr_a_w);
- DECLARE_READ8_MEMBER(nycaptor_68705_port_b_r);
- DECLARE_WRITE8_MEMBER(nycaptor_68705_port_b_w);
- DECLARE_WRITE8_MEMBER(nycaptor_68705_ddr_b_w);
- DECLARE_READ8_MEMBER(nycaptor_68705_port_c_r);
- DECLARE_WRITE8_MEMBER(nycaptor_68705_port_c_w);
- DECLARE_WRITE8_MEMBER(nycaptor_68705_ddr_c_w);
- DECLARE_WRITE8_MEMBER(nycaptor_mcu_w);
- DECLARE_READ8_MEMBER(nycaptor_mcu_r);
+
DECLARE_READ8_MEMBER(nycaptor_mcu_status_r1);
DECLARE_READ8_MEMBER(nycaptor_mcu_status_r2);
DECLARE_WRITE8_MEMBER(nycaptor_videoram_w);
diff --git a/src/mame/includes/rm380z.h b/src/mame/includes/rm380z.h
index 4923fefb018..763eb043117 100644
--- a/src/mame/includes/rm380z.h
+++ b/src/mame/includes/rm380z.h
@@ -12,6 +12,7 @@ Research Machines RM 380Z
#include "emu.h"
#include "cpu/z80/z80.h"
+#include "imagedev/cassette.h"
#include "machine/ram.h"
#include "imagedev/flopdrv.h"
#include "machine/wd_fdc.h"
@@ -59,13 +60,11 @@ private:
int writenum;
-protected:
virtual void machine_reset() override;
virtual void machine_start() override;
-public:
-
uint8_t m_port0;
+ uint8_t m_port0_mask;
uint8_t m_port0_kbd;
uint8_t m_port1;
uint8_t m_fbfd;
@@ -88,14 +87,17 @@ public:
int m_old_videomode;
required_device<cpu_device> m_maincpu;
+ required_device<cassette_image_device> m_cassette;
required_device<ram_device> m_messram;
required_device<fd1771_t> m_fdc;
required_device<floppy_connector> m_floppy0;
required_device<floppy_connector> m_floppy1;
+public:
rm380z_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag),
m_maincpu(*this, RM380Z_MAINCPU_TAG),
+ m_cassette(*this, "cassette"),
m_messram(*this, RAM_TAG),
m_fdc(*this, "wd1771"),
m_floppy0(*this, "wd1771:0"),
@@ -123,10 +125,16 @@ public:
DECLARE_WRITE8_MEMBER(disk_0_control);
DECLARE_WRITE8_MEMBER( keyboard_put );
+
+ DECLARE_DRIVER_INIT(rm380z);
+ DECLARE_DRIVER_INIT(rm380z34d);
+ DECLARE_DRIVER_INIT(rm380z34e);
+ DECLARE_DRIVER_INIT(rm480z);
void config_memory_map();
void update_screen(bitmap_ind16 &bitmap);
uint32_t screen_update_rm380z(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
+ uint32_t screen_update_rm480z(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
TIMER_CALLBACK_MEMBER(static_vblank_timer);
};
diff --git a/src/mame/includes/rohga.h b/src/mame/includes/rohga.h
index 1b36e212313..ed3345f4121 100644
--- a/src/mame/includes/rohga.h
+++ b/src/mame/includes/rohga.h
@@ -70,6 +70,7 @@ public:
DECLARE_DRIVER_INIT(wizdfire);
DECLARE_DRIVER_INIT(nitrobal);
DECLARE_DRIVER_INIT(schmeisr);
+ DECLARE_DRIVER_INIT(hangzo);
DECLARE_DRIVER_INIT(rohga);
DECLARE_VIDEO_START(wizdfire);
uint32_t screen_update_rohga(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
diff --git a/src/mame/includes/slapfght.h b/src/mame/includes/slapfght.h
index 9b3a66f37cf..a370a5e6186 100644
--- a/src/mame/includes/slapfght.h
+++ b/src/mame/includes/slapfght.h
@@ -8,7 +8,7 @@
#include "cpu/z80/z80.h"
#include "video/bufsprite.h"
-
+#include "machine/taito68705interface.h"
class slapfght_state : public driver_device
{
@@ -17,7 +17,7 @@ public:
: driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"),
m_audiocpu(*this, "audiocpu"),
- m_mcu(*this, "mcu"),
+ m_bmcu(*this, "bmcu"),
m_gfxdecode(*this, "gfxdecode"),
m_screen(*this, "screen"),
m_palette(*this, "palette"),
@@ -31,7 +31,7 @@ public:
// devices, memory pointers
required_device<cpu_device> m_maincpu;
required_device<cpu_device> m_audiocpu;
- optional_device<cpu_device> m_mcu;
+ optional_device<taito68705_mcu_device> m_bmcu;
required_device<gfxdecode_device> m_gfxdecode;
required_device<screen_device> m_screen;
required_device<palette_device> m_palette;
@@ -61,15 +61,6 @@ public:
bool m_main_irq_enabled;
bool m_sound_nmi_enabled;
- bool m_mcu_sent;
- bool m_main_sent;
- uint8_t m_from_main;
- uint8_t m_from_mcu;
-
- uint8_t m_from_mcu_latch;
- uint8_t m_to_mcu_latch;
- uint8_t m_old_portB;
-
int m_getstar_status;
int m_getstar_sequence_index;
int m_getstar_status_state;
@@ -79,6 +70,7 @@ public:
uint8_t m_gs_e;
uint8_t m_tigerhb_cmd;
+ DECLARE_READ8_MEMBER(tigerh_mcu_status_r);
DECLARE_WRITE8_MEMBER(sound_reset_w);
DECLARE_WRITE8_MEMBER(irq_enable_w);
DECLARE_WRITE8_MEMBER(prg_bank_w);
@@ -94,19 +86,7 @@ public:
DECLARE_WRITE8_MEMBER(flipscreen_w);
DECLARE_WRITE8_MEMBER(palette_bank_w);
- DECLARE_WRITE8_MEMBER(tigerh_mcu_w);
- DECLARE_READ8_MEMBER(tigerh_mcu_r);
- DECLARE_READ8_MEMBER(tigerh_mcu_status_r);
-
- DECLARE_READ8_MEMBER(tigerh_mcu_porta_r);
- DECLARE_WRITE8_MEMBER(tigerh_mcu_porta_w);
-
- DECLARE_WRITE8_MEMBER(tigerh_mcu_portb_w);
- DECLARE_WRITE8_MEMBER(slapfght_mcu_portb_w);
-
- DECLARE_READ8_MEMBER(tigerh_mcu_portc_r);
- DECLARE_READ8_MEMBER(slapfght_mcu_portc_r);
-
+ DECLARE_WRITE8_MEMBER(scroll_from_mcu_w);
DECLARE_READ8_MEMBER(getstar_mcusim_r);
DECLARE_WRITE8_MEMBER(getstar_mcusim_w);
diff --git a/src/mame/includes/taito_f3.h b/src/mame/includes/taito_f3.h
index 9c09448cfad..77150f6aaeb 100644
--- a/src/mame/includes/taito_f3.h
+++ b/src/mame/includes/taito_f3.h
@@ -315,6 +315,7 @@ public:
protected:
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
+ virtual void device_post_load(void) override;
private:
inline void get_tile_info(tile_data &tileinfo, int tile_index, uint16_t *gfx_base);
diff --git a/src/mame/includes/xbox.h b/src/mame/includes/xbox.h
index 6bd4a9cbac0..38748c224bd 100644
--- a/src/mame/includes/xbox.h
+++ b/src/mame/includes/xbox.h
@@ -132,6 +132,7 @@ private:
void threadlist_command(int ref, int params, const char **param);
void generate_irq_command(int ref, int params, const char **param);
void nv2a_combiners_command(int ref, int params, const char **param);
+ void nv2a_wclipping_command(int ref, int params, const char **param);
void waitvblank_command(int ref, int params, const char **param);
void grab_texture_command(int ref, int params, const char **param);
void grab_vprog_command(int ref, int params, const char **param);
diff --git a/src/mame/includes/xbox_nv2a.h b/src/mame/includes/xbox_nv2a.h
index c8f70948202..8f1f83af0c2 100644
--- a/src/mame/includes/xbox_nv2a.h
+++ b/src/mame/includes/xbox_nv2a.h
@@ -102,13 +102,22 @@ public:
// input vertex
vertex_nv *input;
// input parameters
- union constant {
+ struct constant {
float fv[4];
- unsigned int iv[4];
+ void iv(int idx, uint32_t value)
+ {
+ union
+ {
+ uint32_t i;
+ float f;
+ } cnv;
+
+ cnv.i = value;
+ fv[idx] = cnv.f;
+ }
} c_constant[192];
union temp {
float fv[4];
- unsigned int iv[4];
} r_temp[32];
// output vertex
vertex_nv *output;
@@ -224,11 +233,11 @@ public:
TEX3 = 12
};
enum class NV2A_VTXBUF_TYPE {
- UBYTE2 = 0, // what is the difference with UBYTE ?
+ UBYTE_D3D = 0, // what is the difference with opengl UBYTE ?
FLOAT = 2,
- UBYTE = 4,
+ UBYTE_OGL = 4,
USHORT = 5,
- UNKNOWN_6 = 6 // used for vertex color
+ FLOAT_PACKED = 6 // used for vertex color
};
enum class NV2A_TEX_FORMAT {
L8 = 0x0,
@@ -428,7 +437,8 @@ public:
puller_waiting = 0;
debug_grab_texttype = -1;
debug_grab_textfile = nullptr;
- waitvblank_used = 1;
+ enable_waitvblank = true;
+ enable_clipping_w = false;
memset(vertex_attribute_words, 0, sizeof(vertex_attribute_words));
memset(vertex_attribute_offset, 0, sizeof(vertex_attribute_offset));
memset(&persistvertexattr, 0, sizeof(persistvertexattr));
@@ -479,8 +489,9 @@ public:
uint32_t dilate0(uint32_t value, int bits);
uint32_t dilate1(uint32_t value, int bits);
void computedilated(void);
- int toggle_register_combiners_usage();
- int toggle_wait_vblank_support();
+ bool toggle_register_combiners_usage();
+ bool toggle_wait_vblank_support();
+ bool toggle_clipping_w_support();
void debug_grab_texture(int type, const char *filename);
void debug_grab_vertex_program_slot(int slot, uint32_t *instruction);
void start(address_space *cpu_space);
@@ -488,6 +499,7 @@ public:
void compute_supersample_factors(float &horizontal, float &vertical);
void compute_limits_rendertarget(uint32_t chanel, uint32_t subchannel);
void compute_size_rendertarget(uint32_t chanel, uint32_t subchannel);
+ void extract_packed_float(uint32_t data, float &first, float &second, float &third);
void read_vertex(address_space & space, offs_t address, vertex_nv &vertex, int attrib);
int read_vertices_0x1800(address_space & space, vertex_nv *destination, uint32_t address, int limit);
int read_vertices_0x1808(address_space & space, vertex_nv *destination, uint32_t address, int limit);
@@ -743,5 +755,6 @@ public:
nvidia_object_data *objectdata;
int debug_grab_texttype;
char *debug_grab_textfile;
- int waitvblank_used;
+ bool enable_waitvblank;
+ bool enable_clipping_w;
};
diff --git a/src/mame/layout/cmsport.lay b/src/mame/layout/cmsport.lay
new file mode 100644
index 00000000000..1ad9d012898
--- /dev/null
+++ b/src/mame/layout/cmsport.lay
@@ -0,0 +1,65 @@
+<?xml version="1.0"?>
+<mamelayout version="2">
+
+<!-- define elements -->
+
+ <element name="digit" defstate="0">
+ <led7seg><color red="1.0" green="0.25" blue="0.28" /></led7seg>
+ </element>
+
+ <element name="led" defstate="0">
+ <disk state="0"><color red="0.1" green="0.025" blue="0.028" /></disk>
+ <disk state="1"><color red="1.0" green="0.25" blue="0.28" /></disk>
+ </element>
+
+
+<!-- build screen -->
+
+ <view name="Internal Layout">
+ <bounds left="-1" right="14" top="-1" bottom="21.5" />
+
+ <bezel name="5.7" element="led"><bounds x="0" y="0" width="1" height="1" /></bezel>
+ <bezel name="8.a" element="led"><bounds x="6" y="0" width="1" height="1" /></bezel>
+ <bezel name="6.7" element="led"><bounds x="12" y="0" width="1" height="1" /></bezel>
+
+ <bezel name="0.7" element="led"><bounds x="0" y="2.5" width="1" height="1" /></bezel>
+ <bezel name="1.7" element="led"><bounds x="3" y="2.5" width="1" height="1" /></bezel>
+ <bezel name="2.7" element="led"><bounds x="6" y="2.5" width="1" height="1" /></bezel>
+ <bezel name="3.7" element="led"><bounds x="9" y="2.5" width="1" height="1" /></bezel>
+ <bezel name="4.7" element="led"><bounds x="12" y="2.5" width="1" height="1" /></bezel>
+
+ <bezel name="0.6" element="led"><bounds x="0" y="5" width="1" height="1" /></bezel>
+ <bezel name="1.6" element="led"><bounds x="3" y="5" width="1" height="1" /></bezel>
+ <bezel name="2.6" element="led"><bounds x="6" y="5" width="1" height="1" /></bezel>
+ <bezel name="3.6" element="led"><bounds x="9" y="5" width="1" height="1" /></bezel>
+ <bezel name="4.6" element="led"><bounds x="12" y="5" width="1" height="1" /></bezel>
+
+ <bezel name="0.5" element="led"><bounds x="0" y="7.5" width="1" height="1" /></bezel>
+ <bezel name="1.5" element="led"><bounds x="3" y="7.5" width="1" height="1" /></bezel>
+ <bezel name="2.5" element="led"><bounds x="6" y="7.5" width="1" height="1" /></bezel>
+ <bezel name="3.5" element="led"><bounds x="9" y="7.5" width="1" height="1" /></bezel>
+ <bezel name="4.5" element="led"><bounds x="12" y="7.5" width="1" height="1" /></bezel>
+
+ <bezel name="0.4" element="led"><bounds x="0" y="10" width="1" height="1" /></bezel>
+ <bezel name="1.4" element="led"><bounds x="3" y="10" width="1" height="1" /></bezel>
+ <bezel name="2.4" element="led"><bounds x="6" y="10" width="1" height="1" /></bezel>
+ <bezel name="3.4" element="led"><bounds x="9" y="10" width="1" height="1" /></bezel>
+ <bezel name="4.4" element="led"><bounds x="12" y="10" width="1" height="1" /></bezel>
+
+ <bezel name="0.3" element="led"><bounds x="0" y="12.5" width="1" height="1" /></bezel>
+ <bezel name="1.3" element="led"><bounds x="3" y="12.5" width="1" height="1" /></bezel>
+ <bezel name="2.3" element="led"><bounds x="6" y="12.5" width="1" height="1" /></bezel>
+ <bezel name="3.3" element="led"><bounds x="9" y="12.5" width="1" height="1" /></bezel>
+ <bezel name="4.3" element="led"><bounds x="12" y="12.5" width="1" height="1" /></bezel>
+
+ <bezel name="0.0" element="led"><bounds x="0" y="15" width="1" height="1" /></bezel>
+ <bezel name="1.0" element="led"><bounds x="3" y="15" width="1" height="1" /></bezel>
+ <bezel name="2.0" element="led"><bounds x="6" y="15" width="1" height="1" /></bezel>
+ <bezel name="3.0" element="led"><bounds x="9" y="15" width="1" height="1" /></bezel>
+ <bezel name="4.0" element="led"><bounds x="12" y="15" width="1" height="1" /></bezel>
+
+ <bezel name="digit5" element="digit"><bounds x="4.5" y="17.5" width="2" height="3" /></bezel>
+ <bezel name="digit6" element="digit"><bounds x="6.5" y="17.5" width="2" height="3" /></bezel>
+
+ </view>
+</mamelayout>
diff --git a/src/mame/layout/racedrivpan.lay b/src/mame/layout/racedrivpan.lay
index 3ca77bae895..a3fe28eb987 100644
--- a/src/mame/layout/racedrivpan.lay
+++ b/src/mame/layout/racedrivpan.lay
@@ -13,4 +13,22 @@
</screen>
</view>
+ <view name="Left Screen">
+ <screen index="1">
+ <bounds x="0" y="0" width="4" height="3" />
+ </screen>
+ </view>
+
+ <view name="Center Screen">
+ <screen index="0">
+ <bounds x="0" y="0" width="4" height="3" />
+ </screen>
+ </view>
+
+ <view name="Right Screen">
+ <screen index="2">
+ <bounds x="0" y="0" width="4" height="3" />
+ </screen>
+ </view>
+
</mamelayout>
diff --git a/src/mame/machine/alpha8201.h b/src/mame/machine/alpha8201.h
index fb24349333c..241a6d1c3bb 100644
--- a/src/mame/machine/alpha8201.h
+++ b/src/mame/machine/alpha8201.h
@@ -39,9 +39,9 @@ private:
// internal state
int m_bus; // shared RAM bus direction
- uint16_t m_mcu_address; // MCU side RAM address
- uint16_t m_mcu_d; // MCU D output data
- uint8_t m_mcu_r[4]; // MCU R0-R3 output data
+ uint16_t m_mcu_address; // MCU side RAM address
+ uint16_t m_mcu_d; // MCU D output data
+ uint8_t m_mcu_r[4]; // MCU R0-R3 output data
std::unique_ptr<uint8_t[]> m_shared_ram; // 1KB RAM
void mcu_update_address();
diff --git a/src/mame/machine/arkanoid.cpp b/src/mame/machine/arkanoid.cpp
index 3784267b820..6e57dbc25fa 100644
--- a/src/mame/machine/arkanoid.cpp
+++ b/src/mame/machine/arkanoid.cpp
@@ -32,98 +32,17 @@ WRITE8_MEMBER(arkanoid_state::arkanoid_Z80_mcu_w)
m_mcu->set_input_line(M68705_IRQ_LINE, ASSERT_LINE);
}
-READ8_MEMBER(arkanoid_state::arkanoid_68705_port_a_r)
+READ8_MEMBER(arkanoid_state::mcu_porta_r)
{
- return (m_portA_out & m_ddrA) | (m_portA_in & ~m_ddrA);
+ return m_portA_in;
}
-WRITE8_MEMBER(arkanoid_state::arkanoid_68705_port_a_w)
+WRITE8_MEMBER(arkanoid_state::mcu_porta_w)
{
m_portA_out = data;
}
-WRITE8_MEMBER(arkanoid_state::arkanoid_68705_ddr_a_w)
-{
- m_ddrA = data;
-}
-
-READ8_MEMBER(arkanoid_state::arkanoid_68705_tdr_r)
-{
- //logerror("arkanoid_68705 TDR read, returning %02X\n", m_tdr);
- return m_tdr;
-}
-
-WRITE8_MEMBER(arkanoid_state::arkanoid_68705_tdr_w)
-{
- //logerror("arkanoid_68705 TDR written with %02X, was %02X\n", data, m_tdr);
- m_tdr = data;
-}
-
-READ8_MEMBER(arkanoid_state::arkanoid_68705_tcr_r)
-{
- //logerror("arkanoid_68705 TCR read, returning %02X\n", (m_tcr&0xF7));
- return (m_tcr & 0xF7);
-}
-
-WRITE8_MEMBER(arkanoid_state::arkanoid_68705_tcr_w)
-{
-/*
- logerror("arkanoid_68705 TCR written with %02X\n", data);
- if (data&0x80) logerror(" TIR=1, Timer Interrupt state is set\n"); else logerror(" TIR=0; Timer Interrupt state is cleared\n");
- if (data&0x40) logerror(" TIM=1, Timer Interrupt is now masked\n"); else logerror(" TIM=0, Timer Interrupt is now unmasked\n");
- if (data&0x20) logerror(" TIN=1, Timer Clock source is set to external\n"); else logerror(" TIN=0, Timer Clock source is set to internal\n");
- if (data&0x10) logerror(" TIE=1, Timer External pin is enabled\n"); else logerror(" TIE=0, Timer External pin is disabled\n");
- if (data&0x08) logerror(" PSC=1, Prescaler counter cleared\n"); else logerror(" PSC=0, Prescaler counter left alone\n");
- logerror(" Prescaler: %d\n", (1<<(data&0x7)));
-*/
- // if timer was enabled but now isn't, shut it off.
- // below is a hack assuming the TIMER pin isn't going anywhere except tied to +5v, so basically TIN is acting as an active-low timer enable, and TIE is ignored even in the case where TIE=1, the timer will end up being 5v ANDED against the internal timer clock which == the internal timer clock.
- // Note this hack is incorrect; the timer pin actually does connect somewhere (vblank or maybe one of the V counter bits?), but the game never actually uses the timer pin in external clock mode, so the TIMER connection must be left over from development. We can apparently safely ignore it.
- if ((m_tcr^data)&0x20)// check if TIN state changed
- {
- /* logerror("timer enable state changed!\n"); */
- if (data&0x20) m_68705_timer->adjust(attotime::never, TIMER_68705_PRESCALER_EXPIRED);
- else m_68705_timer->adjust(attotime::from_hz(((XTAL_12MHz/4)/4)/(1<<(data&0x7))), TIMER_68705_PRESCALER_EXPIRED);
- }
- // prescaler check: if timer prescaler has changed, or the PSC bit is set, adjust the timer length for the prescaler expired timer, but only if the timer would be running
- if ( (((m_tcr&0x07)!=(data&0x07))||(data&0x08)) && ((data&0x20)==0) )
- {
- /* logerror("timer reset due to PSC or prescaler change!\n"); */
- m_68705_timer->adjust(attotime::from_hz(((XTAL_12MHz/4)/4)/(1<<(data&0x7))), TIMER_68705_PRESCALER_EXPIRED);
- }
- m_tcr = data;
- // if int state is set, and TIM is unmasked, assert an interrupt. otherwise clear it.
- if ((m_tcr&0xC0) == 0x80)
- m_mcu->set_input_line(M68705_INT_TIMER, ASSERT_LINE);
- else
- m_mcu->set_input_line(M68705_INT_TIMER, CLEAR_LINE);
-
-}
-
-void arkanoid_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
-{
- switch (id)
- {
- case TIMER_68705_PRESCALER_EXPIRED:
- timer_68705_increment(ptr, param);
- break;
- default:
- assert_always(false, "Unknown id in arkanoid_state::device_timer");
- }
-}
-
-TIMER_CALLBACK_MEMBER(arkanoid_state::timer_68705_increment)
-{
- m_tdr++;
- if (m_tdr == 0x00) m_tcr |= 0x80; // if we overflowed, set the int bit
- if ((m_tcr&0xC0) == 0x80)
- m_mcu->set_input_line(M68705_INT_TIMER, ASSERT_LINE);
- else
- m_mcu->set_input_line(M68705_INT_TIMER, CLEAR_LINE);
- m_68705_timer->adjust(attotime::from_hz(((XTAL_12MHz/4)/4)/(1<<(m_tcr&0x7))), TIMER_68705_PRESCALER_EXPIRED);
-}
-
-READ8_MEMBER(arkanoid_state::arkanoid_68705_port_c_r)
+READ8_MEMBER(arkanoid_state::mcu_portc_r)
{
int portC_in = 0;
@@ -138,74 +57,46 @@ READ8_MEMBER(arkanoid_state::arkanoid_68705_port_c_r)
/* bit 2 is an output, to clear latch 1, return whatever state it was set to in m_portC_out */
/* bit 3 is an output, to set latch 2, return whatever state it was set to in m_portC_out */
- return (m_portC_internal & m_ddrC) | (portC_in & ~m_ddrC);
+ return portC_in;
}
-WRITE8_MEMBER(arkanoid_state::arkanoid_68705_port_c_w)
+READ8_MEMBER(arkanoid_state::mcu_portb_r)
{
- m_portC_internal = data|0xF0;
- uint8_t changed_m_portC_out = (m_portC_out^(m_portC_internal|(~m_ddrC)));
- m_portC_out = (m_portC_internal|(~m_ddrC));
+ return ioport("MUX")->read();
+}
+
+WRITE8_MEMBER(arkanoid_state::mcu_portc_w)
+{
/* bits 0 and 1 are inputs, should never be set as outputs here. if they are, ignore them. */
/* bit 2 is an output, to clear latch 1(m_Z80HasWritten) on rising edge, and enable the z80->68705 communication latch on level low */
// if 0x04 rising edge, clear m_Z80HasWritten/latch 1 (and clear the irq line)
- if ((changed_m_portC_out&0x04) && (m_portC_out&0x04))
+ if ((~m_old_portC_out&0x04) && (data&0x04))
{
m_Z80HasWritten = 0;
m_mcu->set_input_line(M68705_IRQ_LINE, CLEAR_LINE);
}
// if 0x04 low, enable the m_portA_in latch, otherwise set the latch value to 0xFF
- if (~m_portC_out&0x04)
+ if (~data&0x04)
m_portA_in = m_fromZ80;
else
m_portA_in = 0xFF;
/* bit 3 is an output, to set latch 2(m_MCUHasWritten) and latch the port_a value into the 68705->z80 latch, on falling edge or low level */
// if 0x08 low, set m_MCUHasWritten/latch 2
- if (~m_portC_out&0x08)
+ if (~data&0x08)
{
/* a write from the 68705 to the Z80; remember its value */
m_MCUHasWritten = 1;
m_fromMCU = m_portA_out;
}
-}
-WRITE8_MEMBER(arkanoid_state::arkanoid_68705_ddr_c_w)
-{
- if ((data|0xF0)^m_ddrC) // if ddr changed, recalculate the port c output
- {
- uint8_t changed_m_portC_out = (m_portC_out^(m_portC_internal|(~(data|0xF0))));
- m_portC_out = (m_portC_internal|(~(data|0xF0)));
-
- /* bits 0 and 1 are inputs, should never be set as outputs here. if they are, ignore them. */
- /* bit 2 is an output, to clear latch 1(m_Z80HasWritten) on rising edge, and enable the z80->68705 communication latch on level low */
- // if 0x04 rising edge, clear m_Z80HasWritten/latch 1 (and clear the irq line)
- if ((changed_m_portC_out&0x04) && (m_portC_out&0x04))
- {
- m_Z80HasWritten = 0;
- m_mcu->set_input_line(M68705_IRQ_LINE, CLEAR_LINE);
- }
-
- // if 0x04 low, enable the m_portA_in latch, otherwise set the latch value to 0xFF
- if (~m_portC_out&0x04)
- m_portA_in = m_fromZ80;
- else
- m_portA_in = 0xFF;
-
- /* bit 3 is an output, to set latch 2(m_MCUHasWritten) and latch the port_a value into the 68705->z80 latch, on falling edge or low level */
- // if 0x08 low, set m_MCUHasWritten/latch 2
- if (~m_portC_out&0x08)
- {
- /* a write from the 68705 to the Z80; remember its value */
- m_MCUHasWritten = 1;
- m_fromMCU = m_portA_out;
- }
- }
- m_ddrC = data|0xF0;
+ m_old_portC_out = data;
}
+
+
CUSTOM_INPUT_MEMBER(arkanoid_state::arkanoid_semaphore_input_r)
{
int res = 0;
diff --git a/src/mame/machine/bigevglf.cpp b/src/mame/machine/bigevglf.cpp
index 0b2c801ecbf..458c1edb648 100644
--- a/src/mame/machine/bigevglf.cpp
+++ b/src/mame/machine/bigevglf.cpp
@@ -13,90 +13,14 @@
#include "includes/bigevglf.h"
-READ8_MEMBER(bigevglf_state::bigevglf_68705_port_a_r)
-{
- return (m_port_a_out & m_ddr_a) | (m_port_a_in & ~m_ddr_a);
-}
-
-WRITE8_MEMBER(bigevglf_state::bigevglf_68705_port_a_w)
-{
- m_port_a_out = data;
-}
-
-WRITE8_MEMBER(bigevglf_state::bigevglf_68705_ddr_a_w)
-{
- m_ddr_a = data;
-}
-
-READ8_MEMBER(bigevglf_state::bigevglf_68705_port_b_r)
-{
- return (m_port_b_out & m_ddr_b) | (m_port_b_in & ~m_ddr_b);
-}
-
-WRITE8_MEMBER(bigevglf_state::bigevglf_68705_port_b_w)
-{
- if ((m_ddr_b & 0x02) && (~m_port_b_out & 0x02) && (data & 0x02)) /* positive going transition of the clock */
- {
- m_mcu->set_input_line(0, CLEAR_LINE);
- m_main_sent = 0;
-
- }
- if ((m_ddr_b & 0x04) && (~m_port_b_out & 0x04) && (data & 0x04) ) /* positive going transition of the clock */
- {
- m_from_mcu = m_port_a_out;
- m_mcu_sent = 0;
- }
-
- m_port_b_out = data;
-}
-
-WRITE8_MEMBER(bigevglf_state::bigevglf_68705_ddr_b_w)
-{
- m_ddr_b = data;
-}
-
-READ8_MEMBER(bigevglf_state::bigevglf_68705_port_c_r)
-{
- m_port_c_in = 0;
- if (m_main_sent)
- m_port_c_in |= 0x01;
- if (m_mcu_sent)
- m_port_c_in |= 0x02;
-
- return (m_port_c_out & m_ddr_c) | (m_port_c_in & ~m_ddr_c);
-}
-
-WRITE8_MEMBER(bigevglf_state::bigevglf_68705_port_c_w)
-{
- m_port_c_out = data;
-}
-
-WRITE8_MEMBER(bigevglf_state::bigevglf_68705_ddr_c_w)
-{
- m_ddr_c = data;
-}
-
-WRITE8_MEMBER(bigevglf_state::bigevglf_mcu_w)
-{
- m_port_a_in = data;
- m_main_sent = 1;
- m_mcu->set_input_line(0, ASSERT_LINE);
-}
-
-
-READ8_MEMBER(bigevglf_state::bigevglf_mcu_r)
-{
- m_mcu_sent = 1;
- return m_from_mcu;
-}
READ8_MEMBER(bigevglf_state::bigevglf_mcu_status_r)
{
int res = 0;
- if (!m_main_sent)
+ if (!m_bmcu->get_main_sent())
res |= 0x08;
- if (!m_mcu_sent)
+ if (m_bmcu->get_mcu_sent())
res |= 0x10;
return res;
diff --git a/src/mame/machine/bublbobl.cpp b/src/mame/machine/bublbobl.cpp
index 76a76af1f4d..1bfa9e97bdc 100644
--- a/src/mame/machine/bublbobl.cpp
+++ b/src/mame/machine/bublbobl.cpp
@@ -58,99 +58,6 @@ WRITE8_MEMBER(bublbobl_state::bublbobl_nmitrigger_w)
-CUSTOM_INPUT_MEMBER(bublbobl_state::tokio_mcu_sent_r)
-{
- if (m_mcu_sent) return 0;
- else return 1;
-}
-
-CUSTOM_INPUT_MEMBER(bublbobl_state::tokio_main_sent_r)
-{
- if (m_main_sent) return 0;
- else return 1;
-}
-
-
-READ8_MEMBER(bublbobl_state::tokio_mcu_r)
-{
- if (!m_mcu)
- return 0x00;
-
- m_mcu_sent = false;
-
-// printf("%s: tokio_mcu_r %02x\n", space.machine().describe_context(), m_from_mcu);
-
- return m_from_mcu;
-}
-
-WRITE8_MEMBER(bublbobl_state::tokio_mcu_w)
-{
- if (!m_mcu)
- return;
-
-// printf("%s: tokio_mcu_w %02x\n", space.machine().describe_context(), data);
-
- m_from_main = data;
- m_main_sent = true;
- m_mcu->set_input_line(0, ASSERT_LINE);
-
-}
-
-
-READ8_MEMBER(bublbobl_state::tokio_mcu_porta_r)
-{
-// printf("tokio_mcu_porta_r\n");
- return m_to_mcu_latch;
-}
-
-WRITE8_MEMBER(bublbobl_state::tokio_mcu_porta_w)
-{
-// printf("tokio_mcu_porta_w %02x\n", data);
- m_from_mcu_latch = data;
-}
-
-
-READ8_MEMBER(bublbobl_state::tokio_mcu_portc_r)
-{
- uint8_t ret = 0;
-
- if (!m_main_sent)
- ret |= 0x01;
- if (m_mcu_sent)
- ret |= 0x02;
-
- ret ^= 0x3; // inverted logic compared to tigerh
-
-// printf("%s: tokio_mcu_portc_r %02x\n", space.machine().describe_context(), ret);
-
- return ret;
-}
-
-
-WRITE8_MEMBER(bublbobl_state::tokio_mcu_portb_w)
-{
-// printf("tokio_mcu_portb_w %02x\n", data);
-
- if ((mem_mask & 0x02) && (~data & 0x02) && (m_old_portB & 0x02))
- {
- if (m_main_sent)
- m_mcu->set_input_line(0, CLEAR_LINE);
-
- m_to_mcu_latch = m_from_main;
- m_main_sent = false;
- }
- if ((mem_mask & 0x04) && (data & 0x04) && (~m_old_portB & 0x04))
- {
- m_from_mcu = m_from_mcu_latch;
- m_mcu_sent = true;
- // printf("sent %02x\n", m_from_mcu);
- }
-
- m_old_portB = data;
-
-}
-
-
diff --git a/src/mame/machine/buggychl.cpp b/src/mame/machine/buggychl.cpp
deleted file mode 100644
index 843113992b5..00000000000
--- a/src/mame/machine/buggychl.cpp
+++ /dev/null
@@ -1,234 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Ernesto Corvi, Nicola Salmoria
-#include "emu.h"
-#include "cpu/z80/z80.h"
-#include "machine/buggychl.h"
-
-
-const device_type BUGGYCHL_MCU = &device_creator<buggychl_mcu_device>;
-
-buggychl_mcu_device::buggychl_mcu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : device_t(mconfig, BUGGYCHL_MCU, "M68705 MCU Simulation (Buggy Challenge)", tag, owner, clock, "buggychl_mcu", __FILE__),
- m_port_a_in(0),
- m_port_a_out(0),
- m_ddr_a(0),
- m_port_b_in(0),
- m_port_b_out(0),
- m_ddr_b(0),
- m_port_c_in(0),
- m_port_c_out(0),
- m_ddr_c(0),
- m_from_main(0),
- m_from_mcu(0),
- m_mcu_sent(0),
- m_main_sent(0)
-{
-}
-
-//-------------------------------------------------
-// device_config_complete - perform any
-// operations now that the configuration is
-// complete
-//-------------------------------------------------
-
-void buggychl_mcu_device::device_config_complete()
-{
-}
-
-//-------------------------------------------------
-// device_start - device-specific startup
-//-------------------------------------------------
-
-void buggychl_mcu_device::device_start()
-{
- m_mcu = machine().device("mcu");
-
- save_item(NAME(m_from_main));
- save_item(NAME(m_from_mcu));
- save_item(NAME(m_mcu_sent));
- save_item(NAME(m_main_sent));
- save_item(NAME(m_port_a_in));
- save_item(NAME(m_port_a_out));
- save_item(NAME(m_ddr_a));
- save_item(NAME(m_port_b_in));
- save_item(NAME(m_port_b_out));
- save_item(NAME(m_ddr_b));
- save_item(NAME(m_port_c_in));
- save_item(NAME(m_port_c_out));
- save_item(NAME(m_ddr_c));
-}
-
-//-------------------------------------------------
-// device_reset - device-specific reset
-//-------------------------------------------------
-
-void buggychl_mcu_device::device_reset()
-{
- m_mcu_sent = 0;
- m_main_sent = 0;
- m_from_main = 0;
- m_from_mcu = 0;
- m_port_a_in = 0;
- m_port_a_out = 0;
- m_ddr_a = 0;
- m_port_b_in = 0;
- m_port_b_out = 0;
- m_ddr_b = 0;
- m_port_c_in = 0;
- m_port_c_out = 0;
- m_ddr_c = 0;
-}
-
-
-/***************************************************************************
-
- Buggy Challenge 68705 protection interface
-
- This is accurate. FairyLand Story seems to be identical.
-
-***************************************************************************/
-
-READ8_MEMBER( buggychl_mcu_device::buggychl_68705_port_a_r )
-{
- //logerror("%04x: 68705 port A read %02x\n", m_mcu->safe_pc(), m_port_a_in);
- return (m_port_a_out & m_ddr_a) | (m_port_a_in & ~m_ddr_a);
-}
-
-WRITE8_MEMBER( buggychl_mcu_device::buggychl_68705_port_a_w )
-{
- //logerror("%04x: 68705 port A write %02x\n", m_mcu->safe_pc(), data);
- m_port_a_out = data;
-}
-
-WRITE8_MEMBER( buggychl_mcu_device::buggychl_68705_ddr_a_w )
-{
- m_ddr_a = data;
-}
-
-
-
-/*
- * Port B connections:
- * parts in [ ] are optional (not used by buggychl)
- *
- * all bits are logical 1 when read (+5V pullup)
- *
- * 0 n.c.
- * 1 W IRQ ack and enable latch which holds data from main Z80 memory
- * 2 W loads latch to Z80
- * 3 W to Z80 BUSRQ (put it on hold?)
- * 4 W n.c.
- * 5 W [selects Z80 memory access direction (0 = write 1 = read)]
- * 6 W [loads the latch which holds the low 8 bits of the address of
- * the main Z80 memory location to access]
- * 7 W [loads the latch which holds the high 8 bits of the address of
- * the main Z80 memory location to access]
- */
-
-
-READ8_MEMBER( buggychl_mcu_device::buggychl_68705_port_b_r )
-{
- return (m_port_b_out & m_ddr_b) | (m_port_b_in & ~m_ddr_b);
-}
-
-WRITE8_MEMBER( buggychl_mcu_device::buggychl_68705_port_b_w )
-{
- logerror("%04x: 68705 port B write %02x\n", m_mcu->safe_pc(), data);
-
- if ((m_ddr_b & 0x02) && (~data & 0x02) && (m_port_b_out & 0x02))
- {
- m_port_a_in = m_from_main;
- if (m_main_sent)
- m_mcu->execute().set_input_line(0, CLEAR_LINE);
- m_main_sent = 0;
- logerror("read command %02x from main cpu\n", m_port_a_in);
- }
- if ((m_ddr_b & 0x04) && (data & 0x04) && (~m_port_b_out & 0x04))
- {
- logerror("send command %02x to main cpu\n", m_port_a_out);
- m_from_mcu = m_port_a_out;
- m_mcu_sent = 1;
- }
-
- m_port_b_out = data;
-}
-
-WRITE8_MEMBER( buggychl_mcu_device::buggychl_68705_ddr_b_w )
-{
- m_ddr_b = data;
-}
-
-
-/*
- * Port C connections:
- *
- * all bits are logical 1 when read (+5V pullup)
- *
- * 0 R 1 when pending command Z80->68705
- * 1 R 0 when pending command 68705->Z80
- */
-
-READ8_MEMBER( buggychl_mcu_device::buggychl_68705_port_c_r )
-{
- m_port_c_in = 0;
- if (m_main_sent)
- m_port_c_in |= 0x01;
- if (!m_mcu_sent)
- m_port_c_in |= 0x02;
- logerror("%04x: 68705 port C read %02x\n", m_mcu->safe_pc(), m_port_c_in);
- return (m_port_c_out & m_ddr_c) | (m_port_c_in & ~m_ddr_c);
-}
-
-WRITE8_MEMBER( buggychl_mcu_device::buggychl_68705_port_c_w )
-{
- logerror("%04x: 68705 port C write %02x\n", m_mcu->safe_pc(), data);
- m_port_c_out = data;
-}
-
-WRITE8_MEMBER( buggychl_mcu_device::buggychl_68705_ddr_c_w )
-{
- m_ddr_c = data;
-}
-
-
-WRITE8_MEMBER( buggychl_mcu_device::buggychl_mcu_w )
-{
- logerror("%04x: mcu_w %02x\n", m_mcu->safe_pc(), data);
- m_from_main = data;
- m_main_sent = 1;
- m_mcu->execute().set_input_line(0, ASSERT_LINE);
-}
-
-READ8_MEMBER( buggychl_mcu_device::buggychl_mcu_r )
-{
- logerror("%04x: mcu_r %02x\n", m_mcu->safe_pc(), m_from_mcu);
- m_mcu_sent = 0;
- return m_from_mcu;
-}
-
-READ8_MEMBER( buggychl_mcu_device::buggychl_mcu_status_r )
-{
- int res = 0;
-
- /* bit 0 = when 1, mcu is ready to receive data from main cpu */
- /* bit 1 = when 1, mcu has sent data to the main cpu */
- //logerror("%04x: mcu_status_r\n",m_mcu->safe_pc());
- if (!m_main_sent)
- res |= 0x01;
- if (m_mcu_sent)
- res |= 0x02;
-
- return res;
-}
-
-ADDRESS_MAP_START( buggychl_mcu_map, AS_PROGRAM, 8, buggychl_mcu_device )
- ADDRESS_MAP_GLOBAL_MASK(0x7ff)
- AM_RANGE(0x0000, 0x0000) AM_DEVREADWRITE("bmcu", buggychl_mcu_device, buggychl_68705_port_a_r, buggychl_68705_port_a_w)
- AM_RANGE(0x0001, 0x0001) AM_DEVREADWRITE("bmcu", buggychl_mcu_device, buggychl_68705_port_b_r, buggychl_68705_port_b_w)
- AM_RANGE(0x0002, 0x0002) AM_DEVREADWRITE("bmcu", buggychl_mcu_device, buggychl_68705_port_c_r, buggychl_68705_port_c_w)
- AM_RANGE(0x0004, 0x0004) AM_DEVWRITE("bmcu", buggychl_mcu_device, buggychl_68705_ddr_a_w)
- AM_RANGE(0x0005, 0x0005) AM_DEVWRITE("bmcu", buggychl_mcu_device, buggychl_68705_ddr_b_w)
- AM_RANGE(0x0006, 0x0006) AM_DEVWRITE("bmcu", buggychl_mcu_device, buggychl_68705_ddr_c_w)
- AM_RANGE(0x0010, 0x007f) AM_RAM
- AM_RANGE(0x0080, 0x07ff) AM_ROM
-ADDRESS_MAP_END
diff --git a/src/mame/machine/buggychl.h b/src/mame/machine/buggychl.h
deleted file mode 100644
index ec76e77e467..00000000000
--- a/src/mame/machine/buggychl.h
+++ /dev/null
@@ -1,48 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Ernesto Corvi, Nicola Salmoria
-class buggychl_mcu_device : public device_t
-{
-public:
- buggychl_mcu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
- ~buggychl_mcu_device() {}
-
- DECLARE_WRITE8_MEMBER( buggychl_mcu_w );
- DECLARE_READ8_MEMBER( buggychl_mcu_r );
- DECLARE_READ8_MEMBER( buggychl_mcu_status_r );
- DECLARE_READ8_MEMBER( buggychl_68705_port_a_r );
- DECLARE_WRITE8_MEMBER( buggychl_68705_port_a_w );
- DECLARE_WRITE8_MEMBER( buggychl_68705_ddr_a_w );
- DECLARE_READ8_MEMBER( buggychl_68705_port_b_r );
- DECLARE_WRITE8_MEMBER( buggychl_68705_port_b_w );
- DECLARE_WRITE8_MEMBER( buggychl_68705_ddr_b_w );
- DECLARE_READ8_MEMBER( buggychl_68705_port_c_r );
- DECLARE_WRITE8_MEMBER( buggychl_68705_port_c_w );
- DECLARE_WRITE8_MEMBER( buggychl_68705_ddr_c_w );
-
-protected:
- // device-level overrides
- virtual void device_config_complete() override;
- virtual void device_start() override;
- virtual void device_reset() override;
-
-private:
- // internal state
- uint8_t m_port_a_in;
- uint8_t m_port_a_out;
- uint8_t m_ddr_a;
- uint8_t m_port_b_in;
- uint8_t m_port_b_out;
- uint8_t m_ddr_b;
- uint8_t m_port_c_in;
- uint8_t m_port_c_out;
- uint8_t m_ddr_c;
- uint8_t m_from_main;
- uint8_t m_from_mcu;
- int m_mcu_sent;
- int m_main_sent;
- device_t *m_mcu;
-};
-
-ADDRESS_MAP_EXTERN( buggychl_mcu_map, 8 );
-
-extern const device_type BUGGYCHL_MCU;
diff --git a/src/mame/machine/cedar_magnet_board.cpp b/src/mame/machine/cedar_magnet_board.cpp
index e56c2ea8067..5ed1364246d 100644
--- a/src/mame/machine/cedar_magnet_board.cpp
+++ b/src/mame/machine/cedar_magnet_board.cpp
@@ -1,90 +1,81 @@
// license:BSD-3-Clause
// copyright-holders:David Haywood
-
#include "emu.h"
-#include "cedar_magnet_plane.h"
-
-
-//const device_type CEDAR_MAGNET_BASE = &device_creator<cedar_magnet_board_device>;
-
-cedar_magnet_board_device::cedar_magnet_board_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, uint32_t clock, const char *shortname, const char *source)
- : device_t(mconfig, type, name, tag, owner, clock, shortname, source)
-// m_ram(*this, "ram")
-{
-}
+#include "cedar_magnet_board.h"
-INTERRUPT_GEN_MEMBER(cedar_magnet_board_device::irq)
+cedar_magnet_board_interface::cedar_magnet_board_interface(const machine_config &mconfig, device_t &device, const char *cputag, const char *ramtag)
+ : device_interface(device, "cedmag_board"),
+ m_cpu(device, cputag),
+ m_ram(device, ramtag)
{
- m_cpu->set_input_line(0, HOLD_LINE);
}
-void cedar_magnet_board_device::device_start()
+void cedar_magnet_board_interface::write_cpu_bus(int offset, u8 data)
{
-}
-
-void cedar_magnet_board_device::write_cpu_bus(int offset, uint8_t data)
-{
- device_t* cpu = m_cpu;
- address_space& ap = cpu->memory().space(AS_PROGRAM);
+ address_space &ap = m_cpu->space(AS_PROGRAM);
ap.write_byte(offset, data);
}
-uint8_t cedar_magnet_board_device::read_cpu_bus(int offset)
+uint8_t cedar_magnet_board_interface::read_cpu_bus(int offset)
{
- device_t* cpu = m_cpu;
- address_space& ap = cpu->memory().space(AS_PROGRAM);
+ address_space &ap = m_cpu->space(AS_PROGRAM);
return ap.read_byte(offset);
}
-bool cedar_magnet_board_device::is_running(void)
+bool cedar_magnet_board_interface::is_running() const
{
return m_is_running;
}
-TIMER_CALLBACK_MEMBER(cedar_magnet_board_device::reset_assert_callback)
+TIMER_CALLBACK_MEMBER(cedar_magnet_board_interface::reset_assert_callback)
{
m_cpu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE);
}
-TIMER_CALLBACK_MEMBER(cedar_magnet_board_device::reset_clear_callback)
+TIMER_CALLBACK_MEMBER(cedar_magnet_board_interface::reset_clear_callback)
{
m_cpu->set_input_line(INPUT_LINE_RESET, CLEAR_LINE);
}
-TIMER_CALLBACK_MEMBER(cedar_magnet_board_device::halt_assert_callback)
+TIMER_CALLBACK_MEMBER(cedar_magnet_board_interface::halt_assert_callback)
{
m_cpu->set_input_line(INPUT_LINE_HALT, ASSERT_LINE);
m_is_running = false;
}
-TIMER_CALLBACK_MEMBER(cedar_magnet_board_device::halt_clear_callback)
+TIMER_CALLBACK_MEMBER(cedar_magnet_board_interface::halt_clear_callback)
{
m_cpu->set_input_line(INPUT_LINE_HALT, CLEAR_LINE);
m_is_running = true;
}
-void cedar_magnet_board_device::halt_assert(void)
+void cedar_magnet_board_interface::irq_hold()
+{
+ m_cpu->set_input_line(INPUT_LINE_IRQ0, HOLD_LINE);
+}
+
+void cedar_magnet_board_interface::halt_assert()
{
- machine().scheduler().timer_set(attotime::from_usec(2), timer_expired_delegate(FUNC(cedar_magnet_board_device::halt_assert_callback),this));
+ device().machine().scheduler().timer_set(attotime::from_usec(2), timer_expired_delegate(FUNC(cedar_magnet_board_interface::halt_assert_callback),this));
}
-void cedar_magnet_board_device::halt_clear(void)
+void cedar_magnet_board_interface::halt_clear()
{
- machine().scheduler().timer_set(attotime::from_usec(2), timer_expired_delegate(FUNC(cedar_magnet_board_device::halt_clear_callback),this));
+ device().machine().scheduler().timer_set(attotime::from_usec(2), timer_expired_delegate(FUNC(cedar_magnet_board_interface::halt_clear_callback),this));
}
-void cedar_magnet_board_device::reset_assert(void)
+void cedar_magnet_board_interface::reset_assert()
{
- machine().scheduler().timer_set(attotime::from_usec(1), timer_expired_delegate(FUNC(cedar_magnet_board_device::reset_assert_callback),this));
+ device().machine().scheduler().timer_set(attotime::from_usec(1), timer_expired_delegate(FUNC(cedar_magnet_board_interface::reset_assert_callback),this));
}
-void cedar_magnet_board_device::reset_clear(void)
+void cedar_magnet_board_interface::reset_clear()
{
- machine().scheduler().timer_set(attotime::from_usec(1), timer_expired_delegate(FUNC(cedar_magnet_board_device::reset_clear_callback),this));
+ device().machine().scheduler().timer_set(attotime::from_usec(1), timer_expired_delegate(FUNC(cedar_magnet_board_interface::reset_clear_callback),this));
}
-void cedar_magnet_board_device::device_reset()
+void cedar_magnet_board_interface::interface_pre_reset()
{
halt_assert();
}
diff --git a/src/mame/machine/cedar_magnet_board.h b/src/mame/machine/cedar_magnet_board.h
index 1672f9e5e76..dbdddbed103 100644
--- a/src/mame/machine/cedar_magnet_board.h
+++ b/src/mame/machine/cedar_magnet_board.h
@@ -1,7 +1,7 @@
// license:BSD-3-Clause
// copyright-holders:David Haywood
-// just a base device to hold some common functions of the EFO / Cedar Magnet System PCBs
+// device interface to hold some common functions of the EFO / Cedar Magnet System PCBs
#pragma once
@@ -10,41 +10,40 @@
#include "cpu/z80/z80.h"
#include "cpu/z80/z80daisy.h"
-#include "machine/z80pio.h"
-extern const device_type CEDAR_MAGNET_PLANE;
-
-class cedar_magnet_board_device : public device_t
+class cedar_magnet_board_interface : public device_interface
{
public:
// construction/destruction
- cedar_magnet_board_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, uint32_t clock, const char *shortname, const char *source);
+ cedar_magnet_board_interface(const machine_config &mconfig, device_t &device, const char *cputag, const char *ramtag);
- uint8_t* m_ram;
- z80_device* m_cpu;
+ z80_device &cpu() { assert(m_cpu != nullptr); return *m_cpu; }
+ u8 *ram() { return &m_ram[0]; }
- virtual uint8_t read_cpu_bus(int offset);
+ virtual u8 read_cpu_bus(int offset);
virtual void write_cpu_bus(int offset, uint8_t data);
- TIMER_CALLBACK_MEMBER(halt_assert_callback);
- TIMER_CALLBACK_MEMBER(halt_clear_callback);
- virtual TIMER_CALLBACK_MEMBER(reset_assert_callback);
- TIMER_CALLBACK_MEMBER(reset_clear_callback);
+ void irq_hold();
+ void halt_assert();
+ void halt_clear();
+ void reset_assert();
+ void reset_clear();
+ bool is_running() const;
+protected:
+ virtual void interface_pre_reset() override;
- void halt_assert(void);
- void halt_clear(void);
- void reset_assert(void);
- void reset_clear(void);
- bool is_running(void);
- bool m_is_running;
+ virtual TIMER_CALLBACK_MEMBER(reset_assert_callback);
- INTERRUPT_GEN_MEMBER(irq);
-protected:
- virtual void device_start() override;
- virtual void device_reset() override;
+ required_device<z80_device> m_cpu;
+ optional_shared_ptr<u8> m_ram;
private:
+ TIMER_CALLBACK_MEMBER(halt_assert_callback);
+ TIMER_CALLBACK_MEMBER(halt_clear_callback);
+ TIMER_CALLBACK_MEMBER(reset_clear_callback);
+
+ bool m_is_running;
};
#endif
diff --git a/src/mame/machine/cedar_magnet_plane.cpp b/src/mame/machine/cedar_magnet_plane.cpp
index 1e696e6cf39..261e3d17ecb 100644
--- a/src/mame/machine/cedar_magnet_plane.cpp
+++ b/src/mame/machine/cedar_magnet_plane.cpp
@@ -10,7 +10,8 @@ extern const device_type CEDAR_MAGNET_PLANE = &device_creator<cedar_magnet_plane
cedar_magnet_plane_device::cedar_magnet_plane_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : cedar_magnet_board_device(mconfig, CEDAR_MAGNET_PLANE, "Cedar Plane", tag, owner, clock, "cedmag_plane", __FILE__)
+ : device_t(mconfig, CEDAR_MAGNET_PLANE, "Cedar Plane", tag, owner, clock, "cedmag_plane", __FILE__),
+ cedar_magnet_board_interface(mconfig, *this, "planecpu", "ram")
{
}
@@ -72,7 +73,6 @@ static MACHINE_CONFIG_FRAGMENT( cedar_magnet_plane )
MCFG_CPU_ADD("planecpu", Z80,4000000)
MCFG_CPU_PROGRAM_MAP(cedar_magnet_plane_map)
MCFG_CPU_IO_MAP(cedar_magnet_plane_io)
- MCFG_CPU_VBLANK_INT_DRIVER(":screen", cedar_magnet_board_device, irq)
MCFG_DEVICE_ADD("z80pio0", Z80PIO, 4000000/2)
// MCFG_Z80PIO_OUT_INT_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0))
@@ -133,8 +133,6 @@ machine_config_constructor cedar_magnet_plane_device::device_mconfig_additions()
void cedar_magnet_plane_device::device_start()
{
- m_cpu = subdevice<z80_device>("planecpu");
- m_ram = (uint8_t*)memshare("ram")->ptr();
save_item(NAME(m_framebuffer));
}
diff --git a/src/mame/machine/cedar_magnet_plane.h b/src/mame/machine/cedar_magnet_plane.h
index 3bd254f1468..a1bafdc74b9 100644
--- a/src/mame/machine/cedar_magnet_plane.h
+++ b/src/mame/machine/cedar_magnet_plane.h
@@ -7,6 +7,7 @@
#define CEDAR_MAGNET_PLANE_DEF
#include "machine/cedar_magnet_board.h"
+#include "machine/z80pio.h"
extern const device_type CEDAR_MAGNET_PLANE;
@@ -14,7 +15,7 @@ extern const device_type CEDAR_MAGNET_PLANE;
MCFG_DEVICE_ADD(_tag, CEDAR_MAGNET_PLANE, 0)
-class cedar_magnet_plane_device : public cedar_magnet_board_device
+class cedar_magnet_plane_device : public device_t, public cedar_magnet_board_interface
{
public:
// construction/destruction
@@ -35,6 +36,8 @@ public:
DECLARE_WRITE8_MEMBER(plane_portce_w);
DECLARE_WRITE8_MEMBER(plane_portcf_w);
+ INTERRUPT_GEN_MEMBER(vblank_irq);
+
uint8_t m_framebuffer[0x10000];
int m_curline;
int m_lineoffset;
diff --git a/src/mame/machine/cedar_magnet_sound.cpp b/src/mame/machine/cedar_magnet_sound.cpp
deleted file mode 100644
index 2ff907658ed..00000000000
--- a/src/mame/machine/cedar_magnet_sound.cpp
+++ /dev/null
@@ -1,208 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:David Haywood
-
-/*
- This is very similar to the ZSU1 Sound Control Unit, also manufactured by
- EFO SA and used in the Playmatic pinballs Skill Flight and Phantom Ship;
- the emulation here is influenced by available schematics for that board.
-
- irq vectors
-
- 0xe6 - from ctc0 channel 3 (vector = E0) used to drive MSM5205 through FIFO
- 0xee - from ctc0 channel 3 (vector = E8) ^^
- 0xf6 - drive AY (once per frame?) triggered by ctc1 channel 3 (vector = F0)
- 0xff - read sound latch (triggered by write from master board; default vector set by 5K/+5 pullups on D0-D7)
-
-*/
-
-#include "emu.h"
-#include "cedar_magnet_sound.h"
-
-#include "machine/clock.h"
-
-
-extern const device_type CEDAR_MAGNET_SOUND = &device_creator<cedar_magnet_sound_device>;
-
-
-cedar_magnet_sound_device::cedar_magnet_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : cedar_magnet_board_device(mconfig, CEDAR_MAGNET_SOUND, "Cedar Sound", tag, owner, clock, "cedmag_sound", __FILE__),
- m_ctc0(*this, "ctc0"),
- m_ctc1(*this, "ctc1"),
- m_fifo(*this, "fifo"),
- m_adpcm(*this, "adpcm")
-{
-}
-
-
-READ8_MEMBER(cedar_magnet_sound_device::soundlatch_r)
-{
- return m_command;
-}
-
-void cedar_magnet_sound_device::write_command(uint8_t data)
-{
- m_command = data;
- // this interrupt causes it to read the soundlatch at 0x14
- m_cpu->set_input_line_and_vector(0, HOLD_LINE, 0xff);
-}
-
-
-
-static ADDRESS_MAP_START( cedar_magnet_sound_map, AS_PROGRAM, 8, cedar_magnet_sound_device )
- AM_RANGE(0x0000, 0xffff) AM_RAM AM_SHARE("ram")
-ADDRESS_MAP_END
-
-static ADDRESS_MAP_START( cedar_magnet_sound_io, AS_IO, 8, cedar_magnet_sound_device )
- ADDRESS_MAP_GLOBAL_MASK(0xff)
- ADDRESS_MAP_UNMAP_HIGH
-
- AM_RANGE(0x00, 0x03) AM_DEVREADWRITE("ctc0", z80ctc_device, read, write)
- AM_RANGE(0x04, 0x07) AM_DEVREADWRITE("ctc1", z80ctc_device, read, write)
-
- AM_RANGE(0x08, 0x08) AM_WRITE(adpcm_fifo_w)
-
- AM_RANGE(0x0c, 0x0c) AM_DEVWRITE("aysnd0", ay8910_device, address_w)
- AM_RANGE(0x0d, 0x0d) AM_DEVWRITE("aysnd0", ay8910_device, data_w)
-
- AM_RANGE(0x10, 0x10) AM_DEVWRITE("aysnd1", ay8910_device, address_w)
- AM_RANGE(0x11, 0x11) AM_DEVWRITE("aysnd1", ay8910_device, data_w)
-
- AM_RANGE(0x14, 0x14) AM_READ(soundlatch_r)
-
-ADDRESS_MAP_END
-
-WRITE8_MEMBER(cedar_magnet_sound_device::adpcm_fifo_w)
-{
- // Z80 code first unpacks 8 bytes of ADPCM sample data into nibbles
- // and, upon receiving interrupt vector E6, fills FIFO at once using OTIR
- // 4-bit data is shifted out of the FIFO to the MSM5205 by another timer
- m_fifo->write(data & 0x0f); // only low nibble is used here
- m_fifo->si_w(1);
- m_fifo->si_w(0);
-}
-
-WRITE8_MEMBER(cedar_magnet_sound_device::ay0_porta_w)
-{
- // unknown; 0x80 written on reset
-}
-
-WRITE8_MEMBER(cedar_magnet_sound_device::ay1_porta_w)
-{
- m_adpcm->reset_w(data & 1);
- if (data & 1)
- m_fifo->reset();
- // D4-D6 likely used to select clock for ctc0 channel 2
- // other bits probably used to modulate analog sound output
-}
-
-WRITE_LINE_MEMBER(cedar_magnet_sound_device::ctc0_z0_w)
-{
-// printf("USED ctc0_z0_w %d\n", state);
-}
-
-WRITE_LINE_MEMBER(cedar_magnet_sound_device::ctc0_z1_w)
-{
-// printf("USED ctc0_z1_w %d\n", state);
-}
-
-WRITE_LINE_MEMBER(cedar_magnet_sound_device::ctc1_z0_w)
-{
- printf("ctc1_z0_w %d\n", state);
-}
-
-WRITE_LINE_MEMBER(cedar_magnet_sound_device::ctc1_z1_w)
-{
- printf("ctc1_z1_w %d\n", state);
-}
-
-WRITE_LINE_MEMBER(cedar_magnet_sound_device::ctc1_z2_w)
-{
- printf("ctc1_z2_w %d\n", state);
-}
-
-WRITE_LINE_MEMBER(cedar_magnet_sound_device::ctc0_z2_w)
-{
- printf("ctc0_z2_w %d\n", state);
-}
-
-WRITE_LINE_MEMBER(cedar_magnet_sound_device::fifo_dor_w)
-{
- // combined with a clock signal and used to drive ctc0 channel 3
-}
-
-static const z80_daisy_config daisy_chain[] =
-{
- { "ctc1" },
- { "ctc0" },
- { nullptr }
-};
-
-TIMER_CALLBACK_MEMBER(cedar_magnet_sound_device::reset_assert_callback)
-{
- cedar_magnet_board_device::reset_assert_callback(ptr,param);
- // reset lines go to the ctc as well?
- m_ctc0->reset();
- m_ctc1->reset();
-}
-
-
-
-static MACHINE_CONFIG_FRAGMENT( cedar_magnet_sound )
- MCFG_CPU_ADD("topcpu", Z80, 4000000)
- MCFG_CPU_PROGRAM_MAP(cedar_magnet_sound_map)
- MCFG_CPU_IO_MAP(cedar_magnet_sound_io)
- MCFG_Z80_DAISY_CHAIN(daisy_chain)
-
- MCFG_DEVICE_ADD("ctc0", Z80CTC, 4000000)
- MCFG_Z80CTC_INTR_CB(INPUTLINE("topcpu", INPUT_LINE_IRQ0))
- MCFG_Z80CTC_ZC0_CB(WRITELINE(cedar_magnet_sound_device, ctc0_z0_w))
- MCFG_Z80CTC_ZC1_CB(WRITELINE(cedar_magnet_sound_device, ctc0_z1_w))
- MCFG_Z80CTC_ZC2_CB(WRITELINE(cedar_magnet_sound_device, ctc0_z2_w))
-
- MCFG_DEVICE_ADD("ctc1", Z80CTC, 4000000)
- MCFG_Z80CTC_INTR_CB(INPUTLINE("topcpu", INPUT_LINE_IRQ0))
- MCFG_Z80CTC_ZC0_CB(WRITELINE(cedar_magnet_sound_device, ctc1_z0_w))
- MCFG_Z80CTC_ZC1_CB(WRITELINE(cedar_magnet_sound_device, ctc1_z1_w))
- MCFG_Z80CTC_ZC2_CB(WRITELINE(cedar_magnet_sound_device, ctc1_z2_w))
-
-#if 0 // does nothing useful now
- MCFG_DEVICE_ADD("ck1mhz", CLOCK, 4000000/4)
- MCFG_CLOCK_SIGNAL_HANDLER(DEVWRITELINE("ctc1", z80ctc_device, trg0))
- MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("ctc1", z80ctc_device, trg1))
- MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("ctc1", z80ctc_device, trg2))
-#endif
-
- MCFG_SPEAKER_STANDARD_MONO("mono")
-
- MCFG_SOUND_ADD("aysnd0", AY8910, 4000000/2)
- MCFG_AY8910_PORT_A_WRITE_CB(WRITE8(cedar_magnet_sound_device, ay0_porta_w))
- MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.5)
-
- MCFG_SOUND_ADD("aysnd1", AY8910, 4000000/2)
- MCFG_AY8910_PORT_A_WRITE_CB(WRITE8(cedar_magnet_sound_device, ay1_porta_w))
- MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.5)
-
- MCFG_DEVICE_ADD("fifo", HC40105, 0) // HCF40105BE at IC13
- MCFG_40105_DATA_OUT_READY_CB(WRITELINE(cedar_magnet_sound_device, fifo_dor_w))
- MCFG_40105_DATA_OUT_CB(DEVWRITELINE("adpcm", msm5205_device, data_w))
-
- MCFG_SOUND_ADD("adpcm", MSM5205, 4000000/8)
- MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50)
-MACHINE_CONFIG_END
-
-machine_config_constructor cedar_magnet_sound_device::device_mconfig_additions() const
-{
- return MACHINE_CONFIG_NAME( cedar_magnet_sound );
-}
-
-void cedar_magnet_sound_device::device_start()
-{
- m_cpu = subdevice<z80_device>("topcpu");
- m_ram = (uint8_t*)memshare("ram")->ptr();
-}
-
-void cedar_magnet_sound_device::device_reset()
-{
- m_command = 0;
- cedar_magnet_board_device::device_reset();
-}
diff --git a/src/mame/machine/cedar_magnet_sprite.cpp b/src/mame/machine/cedar_magnet_sprite.cpp
index 85f8898e997..74b8cedc5c5 100644
--- a/src/mame/machine/cedar_magnet_sprite.cpp
+++ b/src/mame/machine/cedar_magnet_sprite.cpp
@@ -14,7 +14,8 @@ extern const device_type CEDAR_MAGNET_SPRITE = &device_creator<cedar_magnet_spri
cedar_magnet_sprite_device::cedar_magnet_sprite_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : cedar_magnet_board_device(mconfig, CEDAR_MAGNET_SPRITE, "Cedar Sprite", tag, owner, clock, "cedmag_sprite", __FILE__),
+ : device_t(mconfig, CEDAR_MAGNET_SPRITE, "Cedar Sprite", tag, owner, clock, "cedmag_sprite", __FILE__),
+ cedar_magnet_board_interface(mconfig, *this, "spritecpu", "ram"),
m_sprite_ram_bankdev(*this, "sp_sub_ram"),
m_pio0(*this, "z80pio0"),
m_pio1(*this, "z80pio1"),
@@ -202,7 +203,6 @@ static MACHINE_CONFIG_FRAGMENT( cedar_magnet_sprite )
MCFG_CPU_ADD("spritecpu", Z80,4000000)
MCFG_CPU_PROGRAM_MAP(cedar_magnet_sprite_map)
MCFG_CPU_IO_MAP(cedar_magnet_sprite_io)
- MCFG_CPU_VBLANK_INT_DRIVER(":screen", cedar_magnet_board_device, irq)
MCFG_DEVICE_ADD("z80pio0", Z80PIO, 4000000/2)
// MCFG_Z80PIO_OUT_INT_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0))
@@ -291,14 +291,12 @@ machine_config_constructor cedar_magnet_sprite_device::device_mconfig_additions(
return MACHINE_CONFIG_NAME( cedar_magnet_sprite );
}
+
void cedar_magnet_sprite_device::device_start()
{
- m_cpu = subdevice<z80_device>("spritecpu");
- m_ram = (uint8_t*)memshare("ram")->ptr();
}
-
void cedar_magnet_sprite_device::device_reset()
{
halt_assert();
diff --git a/src/mame/machine/cedar_magnet_sprite.h b/src/mame/machine/cedar_magnet_sprite.h
index c2bef5e7d52..f6882e50923 100644
--- a/src/mame/machine/cedar_magnet_sprite.h
+++ b/src/mame/machine/cedar_magnet_sprite.h
@@ -18,7 +18,7 @@ extern const device_type CEDAR_MAGNET_SPRITE;
MCFG_DEVICE_ADD(_tag, CEDAR_MAGNET_SPRITE, 0)
-class cedar_magnet_sprite_device : public cedar_magnet_board_device
+class cedar_magnet_sprite_device : public device_t, public cedar_magnet_board_interface
{
public:
// construction/destruction
diff --git a/src/mame/machine/flstory.cpp b/src/mame/machine/flstory.cpp
index 79f65e86e11..4d71137380e 100644
--- a/src/mame/machine/flstory.cpp
+++ b/src/mame/machine/flstory.cpp
@@ -12,131 +12,6 @@
#include "emu.h"
#include "includes/flstory.h"
-/***************************************************************************
-
- Fairy Land Story 68705 protection interface
-
- The following is ENTIRELY GUESSWORK!!!
-
- It seems, however, to be identical to Buggy Challenge.
-
-***************************************************************************/
-
-READ8_MEMBER(flstory_state::flstory_68705_port_a_r)
-{
- //logerror("%04x: 68705 port A read %02x\n", space.device().safe_pc(), m_port_a_in);
- return (m_port_a_out & m_ddr_a) | (m_port_a_in & ~m_ddr_a);
-}
-
-WRITE8_MEMBER(flstory_state::flstory_68705_port_a_w)
-{
- //logerror("%04x: 68705 port A write %02x\n", space.device().safe_pc(), data);
- m_port_a_out = data;
-}
-
-WRITE8_MEMBER(flstory_state::flstory_68705_ddr_a_w)
-{
- m_ddr_a = data;
-}
-
-
-
-/*
- * Port B connections:
- *
- * all bits are logical 1 when read (+5V pullup)
- *
- * 1 W when 1->0, enables latch which brings the command from main CPU (read from port A)
- * 2 W when 0->1, copies port A to the latch for the main CPU
- */
-
-READ8_MEMBER(flstory_state::flstory_68705_port_b_r)
-{
- return (m_port_b_out & m_ddr_b) | (m_port_b_in & ~m_ddr_b);
-}
-
-WRITE8_MEMBER(flstory_state::flstory_68705_port_b_w)
-{
- //logerror("%04x: 68705 port B write %02x\n",space.device().safe_pc(),data);
-
- if ((m_ddr_b & 0x02) && (~data & 0x02) && (m_port_b_out & 0x02))
- {
- m_port_a_in = m_from_main;
- if (m_main_sent)
- m_mcu->set_input_line(0, CLEAR_LINE);
- m_main_sent = 0;
- logerror("read command %02x from main cpu\n", m_port_a_in);
- }
- if ((m_ddr_b & 0x04) && (data & 0x04) && (~m_port_b_out & 0x04))
- {
- logerror("send command %02x to main cpu\n", m_port_a_out);
- m_from_mcu = m_port_a_out;
- m_mcu_sent = 1;
- }
-
- m_port_b_out = data;
-}
-
-WRITE8_MEMBER(flstory_state::flstory_68705_ddr_b_w)
-{
- m_ddr_b = data;
-}
-
-
-READ8_MEMBER(flstory_state::flstory_68705_port_c_r)
-{
- m_port_c_in = 0;
- if (m_main_sent)
- m_port_c_in |= 0x01;
-
- if (!m_mcu_sent)
- m_port_c_in |= 0x02;
-
- //logerror("%04x: 68705 port C read %02x\n", space.device().safe_pc(), port_c_in);
- return (m_port_c_out & m_ddr_c) | (m_port_c_in & ~m_ddr_c);
-}
-
-WRITE8_MEMBER(flstory_state::flstory_68705_port_c_w)
-{
- logerror("%04x: 68705 port C write %02x\n", space.device().safe_pc(), data);
- m_port_c_out = data;
-}
-
-WRITE8_MEMBER(flstory_state::flstory_68705_ddr_c_w)
-{
- m_ddr_c = data;
-}
-
-WRITE8_MEMBER(flstory_state::flstory_mcu_w)
-{
- logerror("%04x: mcu_w %02x\n", space.device().safe_pc(), data);
- m_from_main = data;
- m_main_sent = 1;
- m_mcu->set_input_line(0, ASSERT_LINE);
-}
-
-READ8_MEMBER(flstory_state::flstory_mcu_r)
-{
- logerror("%04x: mcu_r %02x\n",space.device().safe_pc(), m_from_mcu);
- m_mcu_sent = 0;
- return m_from_mcu;
-}
-
-READ8_MEMBER(flstory_state::flstory_mcu_status_r)
-{
- int res = 0;
-
- /* bit 0 = when 1, mcu is ready to receive data from main cpu */
- /* bit 1 = when 1, mcu has sent data to the main cpu */
- //logerror("%04x: mcu_status_r\n", space.device().safe_pc());
- if (!m_main_sent)
- res |= 0x01;
- if (m_mcu_sent)
- res |= 0x02;
-
- return res;
-}
-
WRITE8_MEMBER(flstory_state::onna34ro_mcu_w)
{
uint16_t score_adr = m_workram[0x29e] * 0x100 + m_workram[0x29d];
diff --git a/src/mame/machine/harddriv.cpp b/src/mame/machine/harddriv.cpp
index 22a50214cf7..9d41af07fe8 100644
--- a/src/mame/machine/harddriv.cpp
+++ b/src/mame/machine/harddriv.cpp
@@ -342,36 +342,70 @@ WRITE16_MEMBER( harddriv_state::hd68k_wr0_write )
/* low 3 bits select the function */
offset &= 7;
+
+ m_sel_select = 0;
+
switch (offset)
{
case 1: /* SEL1 */
case 2: /* SEL2 */
case 3: /* SEL3 */
case 4: /* SEL4 */
- default:
- /* just ignore */
+ m_sel_select = offset;
break;
case 6: /* CC1 */
case 7: /* CC2 */
space.machine().bookkeeping().coin_counter_w(offset - 6, data);
break;
+
+ default:
+ /* just ignore */
+ break;
}
}
WRITE16_MEMBER( harddriv_state::hd68k_wr1_write )
{
- if (offset == 0) { // logerror("Shifter Interface Latch = %02X\n", data);
- } else { logerror("/WR1(%04X)=%02X\n", offset, data);
+ if (offset == 0) {
+ // logerror("Shifter Interface Latch = %02X\n", data);
+ data = data >> 8;
+ switch (m_sel_select)
+ {
+ case 1: /* SEL1 */
+ m_sel1_data = data;
+ machine().output().set_value("SEL1", m_sel1_data);
+ break;
+
+ case 2: /* SEL2 */
+ m_sel2_data = data;
+ machine().output().set_value("SEL2", m_sel2_data);
+ break;
+
+ case 3: /* SEL3 */
+ m_sel3_data = data;
+ machine().output().set_value("SEL3", m_sel3_data);
+ break;
+
+ case 4: /* SEL4 */
+ m_sel4_data = data;
+ machine().output().set_value("SEL4", m_sel4_data);
+ break;
+ }
+ } else {
+ logerror("/WR1(%04X)=%02X\n", offset, data);
}
}
WRITE16_MEMBER( harddriv_state::hd68k_wr2_write )
{
- if (offset == 0) { // logerror("Steering Wheel Latch = %02X\n", data);
- } else { logerror("/WR2(%04X)=%02X\n", offset, data);
+ if (offset == 0) {
+ // logerror("Steering Wheel Latch = %02X\n", data);
+ machine().output().set_value("wheel", data >> 8);
+ } else {
+ logerror("/WR2(%04X)=%02X\n", offset, data);
}
}
@@ -387,11 +421,14 @@ WRITE16_MEMBER( harddriv_state::hd68k_nwr_w )
{
case 0: /* CR2 */
case 1: /* CR1 */
- machine().output().set_led_value(offset, data);
break;
case 2: /* LC1 */
+ // used for seat locking on harddriv
+ machine().output().set_led_value(1, data);
break;
case 3: /* LC2 */
+ // used for "abort" button lamp
+ machine().output().set_led_value(2, data);
break;
case 4: /* ZP1 */
m_m68k_zp1 = data;
diff --git a/src/mame/machine/lkage.cpp b/src/mame/machine/lkage.cpp
deleted file mode 100644
index 3235f08e72c..00000000000
--- a/src/mame/machine/lkage.cpp
+++ /dev/null
@@ -1,141 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Phil Stroffolino
-/***************************************************************************
-
- machine.c
-
- Functions to emulate general aspects of the machine (RAM, ROM, interrupts,
- I/O ports)
-
-***************************************************************************/
-
-#include "emu.h"
-#include "includes/lkage.h"
-
-
-/***************************************************************************
-
- Legend of Kage 68705 protection interface
-
- The following is ENTIRELY GUESSWORK!!!
- And moreover, the game seems to work anyway regardless of what the mcu returns.
-
-***************************************************************************/
-
-READ8_MEMBER(lkage_state::lkage_68705_port_a_r)
-{
- //logerror("%04x: 68705 port A read %02x\n", space.device().safe_pc(), m_port_a_in);
- return (m_port_a_out & m_ddr_a) | (m_port_a_in & ~m_ddr_a);
-}
-
-WRITE8_MEMBER(lkage_state::lkage_68705_port_a_w)
-{
- //logerror("%04x: 68705 port A write %02x\n", space.device().safe_pc(), data);
- m_port_a_out = data;
-}
-
-WRITE8_MEMBER(lkage_state::lkage_68705_ddr_a_w)
-{
- m_ddr_a = data;
-}
-
-
-
-/*
- * Port B connections:
- *
- * all bits are logical 1 when read (+5V pullup)
- *
- * 1 W when 1->0, enables latch which brings the command from main CPU (read from port A)
- * 2 W when 0->1, copies port A to the latch for the main CPU
- */
-
-READ8_MEMBER(lkage_state::lkage_68705_port_b_r)
-{
- return (m_port_b_out & m_ddr_b) | (m_port_b_in & ~m_ddr_b);
-}
-
-WRITE8_MEMBER(lkage_state::lkage_68705_port_b_w)
-{
- //logerror("%04x: 68705 port B write %02x\n", space.device().safe_pc(), data);
-
- if ((m_ddr_b & 0x02) && (~data & 0x02) && (m_port_b_out & 0x02))
- {
- m_port_a_in = m_from_main;
- if (m_main_sent)
- m_mcu->set_input_line(0, CLEAR_LINE);
-
- m_main_sent = 0;
- logerror("read command %02x from main cpu\n", m_port_a_in);
- }
-
- if ((m_ddr_b & 0x04) && (data & 0x04) && (~m_port_b_out & 0x04))
- {
- logerror("send command %02x to main cpu\n", m_port_a_out);
- m_from_mcu = m_port_a_out;
- m_mcu_sent = 1;
- }
-
- m_port_b_out = data;
-}
-
-WRITE8_MEMBER(lkage_state::lkage_68705_ddr_b_w)
-{
- m_ddr_b = data;
-}
-
-
-
-READ8_MEMBER(lkage_state::lkage_68705_port_c_r)
-{
- m_port_c_in = 0;
- if (m_main_sent)
- m_port_c_in |= 0x01;
- if (!m_mcu_sent)
- m_port_c_in |= 0x02;
-
- //logerror("%04x: 68705 port C read %02x\n", space.device().safe_pc(), m_port_c_in);
- return (m_port_c_out & m_ddr_c) | (m_port_c_in & ~m_ddr_c);
-}
-
-WRITE8_MEMBER(lkage_state::lkage_68705_port_c_w)
-{
- logerror("%04x: 68705 port C write %02x\n", space.device().safe_pc(), data);
- m_port_c_out = data;
-}
-
-WRITE8_MEMBER(lkage_state::lkage_68705_ddr_c_w)
-{
- m_ddr_c = data;
-}
-
-
-WRITE8_MEMBER(lkage_state::lkage_mcu_w)
-{
- logerror("%04x: mcu_w %02x\n", space.device().safe_pc(), data);
- m_from_main = data;
- m_main_sent = 1;
- m_mcu->set_input_line(0, ASSERT_LINE);
-}
-
-READ8_MEMBER(lkage_state::lkage_mcu_r)
-{
- logerror("%04x: mcu_r %02x\n", space.device().safe_pc(), m_from_mcu);
- m_mcu_sent = 0;
- return m_from_mcu;
-}
-
-READ8_MEMBER(lkage_state::lkage_mcu_status_r)
-{
- int res = 0;
-
- /* bit 0 = when 1, mcu is ready to receive data from main cpu */
- /* bit 1 = when 1, mcu has sent data to the main cpu */
- //logerror("%04x: mcu_status_r\n", space.device().safe_pc());
- if (!m_main_sent)
- res |= 0x01;
- if (m_mcu_sent)
- res |= 0x02;
-
- return res;
-}
diff --git a/src/mame/machine/lsasquad.cpp b/src/mame/machine/lsasquad.cpp
index ebaecf016ad..b721f71c891 100644
--- a/src/mame/machine/lsasquad.cpp
+++ b/src/mame/machine/lsasquad.cpp
@@ -86,91 +86,6 @@ READ8_MEMBER(lsasquad_state::daikaiju_sound_status_r)
return m_sound_pending ^ 3;
}
-
-/***************************************************************************
-
- LSA Squad 68705 protection interface
-
- The following is ENTIRELY GUESSWORK!!!
-
-***************************************************************************/
-
-READ8_MEMBER(lsasquad_state::lsasquad_68705_port_a_r)
-{
- //logerror("%04x: 68705 port A read %02x\n", space.device().safe_pc(), m_port_a_in);
- return (m_port_a_out & m_ddr_a) | (m_port_a_in & ~m_ddr_a);
-}
-
-WRITE8_MEMBER(lsasquad_state::lsasquad_68705_port_a_w)
-{
- //logerror("%04x: 68705 port A write %02x\n", space.device().safe_pc(), data);
- m_port_a_out = data;
-}
-
-WRITE8_MEMBER(lsasquad_state::lsasquad_68705_ddr_a_w)
-{
- m_ddr_a = data;
-}
-
-
-
-/*
- * Port B connections:
- *
- * all bits are logical 1 when read (+5V pullup)
- *
- * 1 W when 1->0, enables latch which brings the command from main CPU (read from port A)
- * 2 W when 0->1, copies port A to the latch for the main CPU
- */
-
-READ8_MEMBER(lsasquad_state::lsasquad_68705_port_b_r)
-{
- return (m_port_b_out & m_ddr_b) | (m_port_b_in & ~m_ddr_b);
-}
-
-WRITE8_MEMBER(lsasquad_state::lsasquad_68705_port_b_w)
-{
- //logerror("%04x: 68705 port B write %02x\n", space.device().safe_pc(), data);
-
- if ((m_ddr_b & 0x02) && (~data & 0x02) && (m_port_b_out & 0x02))
- {
- m_port_a_in = m_from_main;
- if (m_main_sent)
- m_mcu->set_input_line(0, CLEAR_LINE);
- m_main_sent = 0;
- //logerror("read command %02x from main cpu\n", m_port_a_in);
- }
-
- if ((m_ddr_b & 0x04) && (data & 0x04) && (~m_port_b_out & 0x04))
- {
- //logerror("send command %02x to main cpu\n", m_port_a_out);
- m_from_mcu = m_port_a_out;
- m_mcu_sent = 1;
- }
-
- m_port_b_out = data;
-}
-
-WRITE8_MEMBER(lsasquad_state::lsasquad_68705_ddr_b_w)
-{
- m_ddr_b = data;
-}
-
-WRITE8_MEMBER(lsasquad_state::lsasquad_mcu_w)
-{
- //logerror("%04x: mcu_w %02x\n", space.device().safe_pc(), data);
- m_from_main = data;
- m_main_sent = 1;
- m_mcu->set_input_line(0, ASSERT_LINE);
-}
-
-READ8_MEMBER(lsasquad_state::lsasquad_mcu_r)
-{
- //logerror("%04x: mcu_r %02x\n", space.device().safe_pc(), m_from_mcu);
- m_mcu_sent = 0;
- return m_from_mcu;
-}
-
READ8_MEMBER(lsasquad_state::lsasquad_mcu_status_r)
{
int res = ioport("MCU")->read();
@@ -178,10 +93,13 @@ READ8_MEMBER(lsasquad_state::lsasquad_mcu_status_r)
/* bit 0 = when 1, mcu is ready to receive data from main cpu */
/* bit 1 = when 0, mcu has sent data to the main cpu */
//logerror("%04x: mcu_status_r\n",space.device().safe_pc());
- if (!m_main_sent)
- res |= 0x01;
- if (!m_mcu_sent)
- res |= 0x02;
+ if (m_bmcu)
+ {
+ if (!m_bmcu->get_main_sent())
+ res |= 0x01;
+ if (!m_bmcu->get_mcu_sent())
+ res |= 0x02;
+ }
return res;
}
@@ -193,10 +111,13 @@ READ8_MEMBER(lsasquad_state::daikaiju_mcu_status_r)
/* bit 0 = when 1, mcu is ready to receive data from main cpu */
/* bit 1 = when 0, mcu has sent data to the main cpu */
//logerror("%04x: mcu_status_r\n",space.device().safe_pc());
- if (!m_main_sent)
- res |= 0x01;
- if (!m_mcu_sent)
- res |= 0x02;
+ if (m_bmcu)
+ {
+ if (!m_bmcu->get_main_sent())
+ res |= 0x01;
+ if (!m_bmcu->get_mcu_sent())
+ res |= 0x02;
+ }
res |= ((m_sound_pending & 0x02) ^ 2) << 3; //inverted flag
m_sound_pending &= ~0x02;
diff --git a/src/mame/machine/mzr8105.cpp b/src/mame/machine/mzr8105.cpp
deleted file mode 100644
index 4e645c3acf5..00000000000
--- a/src/mame/machine/mzr8105.cpp
+++ /dev/null
@@ -1,192 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Joakim Larsson Edstrom
-/***************************************************************************
- *
- * Mizar VME8105 rev D 3U SBC board driver
- *
- * 19/08/2015
- *
- * I baught this board from http://www.retrotechnology.com without documentation.
- * It has a Motorola 68000 CPU @ 10MHz and two 27128 EPROMS with OS9 DEBUG labels
- * and not much more except 16 or so TTLs, 2 PALs and a VME P1 connector. It is a
- * 2 layered pcb so it shold be possible to trace the schematics quite easily.
- * There is a date on the P1 Connector: "Feb 20 1987"
- *
- * ||
- * ||
- * ||
- * ||
- * ||____________________________________________________________ ___
- * || --------------K2|U6-7432|U7-7474|U14-7405|U21-74645 | |_| |
- * || | 2764 - low |-+-------+-------+--------+-----------+ | | |
- * || | OS9 DEBUG U4| +---------+ +--------+---------+ | | |
- * || -------------- | | |U13-7474|U20-74645| | | |
- * || ______________ | | +--------+---------+ | | |
- * || | | | | ______________K4____ | | |
- * || | U3| | | |U12-7438|U19-74244| | |VME|
- * || -------------- | |+------K6---------K3---+ | | |
- * || ______________ | ||U11-PAL20L10|U18-74244| | |P1 |
- * || | 2764 - high | | |+-----021102-+---------+ | | |
- * || | OS9 DEBUG U2| |MC68000L10+------------+---------+ | | |
- * || |______________| | ||U10-PAL14L4 |U17-74244| | | |
- * || | |+-----021001-+---------+ | | |
- * || -------------- | |+----+_______|U16-74244|+--+| | |
- * || | | | |XTAL |U9-7410+---------+| || | |
- * ||K1 | U1| | |FOX100-------+---------+|K5||_| |
- * || -------------- |_________|10MHz|U8-7404|U15-74148|| || |___|
- * ||--||--------------------------------+----+-------+---------++--+
- * ||--||
- * ||
- *
- * PAL:s
- *------
- * The board has two PAL:s, a PAL20L10 and a PAL14L4.
- *
- * _____ _____
- * OD/CLK 1 |* \_/ | 20 VCC
- * CPU A13 I0 2 | | 19 O0/LR A23
- * U9 7410p12 I1 3 | | 18 O1/A0 A22
- * CPU *AS I2 4 | | 17 02/A1 U2/U4 2764p22 *OE
- * GND I3 5 | | 16 03/A2 U11 PAL20L10p6 I4
- * CPU A14 I4 6 | U10 | 15 A0/O0 U11 PAL20L10p7 I5
- * CPU A15 I5 7 | PAL14L4 | 14 A1/O1 U19 74LS244p11 I0b
- * CPU A16 I6 8 | | 13 A2/O2 A18
- * CPU A17 I7 9 | | 12 LR/O3 A20
- * GND 10 |_____________| 11 CLK/OD A21
- *
- * _____ _____
- * OD/CLK 1 |* \_/ | 24 VCC
- * I0 2 | | 23 O0/LR
- * CPU *AS I1 3 | | 22 O1/A0
- * U10 PAL14L4p3 I2 4 | | 21 02/A1
- * I3 5 | | 20 03/A2
- * U10 PAL14L4p16 I4 6 | U10 | 19 04/NC
- * U10 PAL14L4p15 I5 7 | PAL20L10 | 18 NC/O0
- * I6 8 | | 17 A2/O1
- * I7 9 | | 16 A1/O2
- * I8 10 | | 15 A0/O3
- * I9 11 | | 14 LR/O4
- * GND 12 |_____________| 13 CLK/OD
- *
- * Trace is not fully completed and validated.
- *
- * History of Mizar
- *-------------------
- * Mizar was one of the first companies that released VME boards in 1982-3 together with
- * Force Computers and Motorola. Their systems was often supported by OS9/68000 from Microware.
- * In 1993 Mizar discontinued their OS9/CPU board product range and focused entirely on DSP
- * boards. RTSI was founded by Mizar employees preserving the knowledge in OS9 as consultants.
- * In 1998 Blue Wave resulted from the merger of Mizar and Loughborough Sound Images.
- * Not much tech information availabe but I found some quotes about Mizar on the internet:
- *
- * From http://archive.org/stream/68micro-vol-11-num-02/V11N02_Feb1989_djvu.txt :
- *--------------------------------------------------------------------------------
- * " Mizar provides complete OS-9 solutions for the VMEbus. Mizar's VME CPUs
- * offer (he functions and performance your application demands. Our single
- * height (3U) VME processors are uniquely configurable computing engines,
- * Through Mizar's unique MXbus expansion interface, standard and custom side
- * modules can be added to basic processors to create double-height (6U) boards
- * tor specific applications, 3U CPU options include 68010, 66020, and 63030
- * microprocessors, up to one MB of DRAM, serial I/O, real-time clock, and
- * mailbox interrupt support. Standard MXbus side modules include additional DRAM.
- * SRAM, and I/O.
- *
- * Mizar's standard double- height (6U) processors provide additional features such
- * as a high-speed cache to enhance 68030 performance, floating, point coprocessor
- * support, up to four MB dual ported DRAM, VSB memory interface, Ethernet, and SCSI.
- *
- * Mizar also supports OS-9 with completely configured OS9 development systems and
- * OS-9 application server systems. For more information, call Mizar today
- *
- * 800-635-0200 MIZAR 1419 Dunn Drive CarrolHon, TX 75006 214-446-2664"
- *
- * Known boards from Mizar:
- *
- * MZX 414
- * MZ 7122
- * MZ 7132
- * MZ 7300 Serial I/O Board (Z8530)
- * EMX 7320 Serial I/O Board
- * MZ 7400 Disk Controller Board (WD 2010; WD 1772)
- * MZ 7500 IEEE-488 (GPIB) Interface Board
- * EMX 7550 Ethernet Controller Board (AMD 7990 Lance) MAC: 00:80:F8 MIZAR, INC.
- * MZ 7772
- * MZ 7810 I/O Expansion Module (6681 DUART)
- * MZ 7831 SCSI Expansion Module (WD 33C93A)
- * MZ 7850 Ethernet Expansion Module (WD 83C690)
- * MZ 8000 ??
- * MZ 8105 3U 68000 CPU board
- * MZ 8115
- * MZ 8300 3U serial board, 2 NEC 7201 and 1 AMD CTS9513 5 x 16 bit Counter/Timer
- * MZ 8310 timing module 2 x AM9513
- * MZ 8505 IEEE-488 (GPIB) Interface Board"
- *
- * From http://www.megalextoria.com/forum2/index.php?t=msg&goto=73945&
- *--------------------------------------------------------------------
- * Aug 20 1984 a report by James Jones from the OS/9 conferance in Des Moines:
- * "...
- * Mizar: is selling VME bus 68010 boards, running OS-9/68000; they also make
- * various memory and I/O boards, disk controller boards, and and a NEC 7220-based
- * graphics controller board...."
- *
- * Misc links about Mizar:
- * http://www.vita.com/History
- * http://www.verycomputer.com/154_e272024804bbe203_1.htm
- * https://www.aihitdata.com/company/00814595/RTSI/overview
- *
- * Address Map
- * --------------------------------------------------------------------------
- * Address Range Description/Assumption
- * --------------------------------------------------------------------------
- * 0x000000 0x01ffff ROM because of fixed vectors
- * 0x020000 0x03ffff RAM because bootvector stack starts at 0x21000
- * -- VME adresses---
- * 0xff0000 0xff0003 Bootstrap expects to find a UPD7201 serial device here
- * --------------------------------------------------------------------------
- *
- * Interrupt sources
- * ----------------------------------------------------------
- * Description Device Lvl IRQ VME board
- * /Board Vector Address
- * ----------------------------------------------------------
- * On board Sources
- * TBD
- * Off board Sources (other VME boards)
- * TBD
- * ----------------------------------------------------------
- *
- * TODO:
- * - Dump the ROMs (DONE)
- * - Setup a working address map (DONE)
- * - Add VME bus driver (Faked one)
- * - understand what other device is expected in VME space ff0011-13
- *
- ****************************************************************************/
-#include "emu.h"
-#include "includes/mzr8105.h"
-#include "cpu/m68000/m68000.h"
-#include "machine/clock.h"
-
-#define VERBOSE 0
-
-#define LOGPRINT(...) do { if (VERBOSE) logerror(__VA_ARGS__); } while (0)
-#define LOG(...) LOGPRINT(__VA_ARGS__)
-
-#if VERBOSE >= 2
-#define logerror printf
-#endif
-
-#ifdef _MSC_VER
-#define LLFORMAT "%I64%"
-#define FUNCNAME __func__
-#else
-#define LLFORMAT "%lld"
-#define FUNCNAME __PRETTY_FUNCTION__
-#endif
-
-/* Start it up */
-void mzr8105_state::machine_start()
-{
- LOG("%s()\n", FUNCNAME);
-}
-
diff --git a/src/mame/machine/namco_c139.cpp b/src/mame/machine/namco_c139.cpp
new file mode 100644
index 00000000000..0e081a7836e
--- /dev/null
+++ b/src/mame/machine/namco_c139.cpp
@@ -0,0 +1,107 @@
+// license:BSD-3-Clause
+// copyright-holders:Angelo Salese
+/***************************************************************************
+
+ Namco C139 - Serial I/F Controller
+
+
+ TODO:
+ - Make this to actually work!
+ - Is RAM shared with a specific CPU other than master/slave?
+
+***************************************************************************/
+
+#include "emu.h"
+#include "namco_c139.h"
+
+
+
+//**************************************************************************
+// GLOBAL VARIABLES
+//**************************************************************************
+
+// device type definition
+const device_type NAMCO_C139 = &device_creator<namco_c139_device>;
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+static ADDRESS_MAP_START( data_map, AS_DATA, 16, namco_c139_device )
+ AM_RANGE(0x0000, 0x3fff) AM_RAM AM_SHARE("sharedram")
+ADDRESS_MAP_END
+
+DEVICE_ADDRESS_MAP_START( regs_map, 16, namco_c139_device )
+ AM_RANGE(0x00, 0x00) AM_READ(status_r) // WRITE clears flags
+ AM_RANGE(0x02, 0x02) AM_NOP // settings?
+// AM_RANGE(0x0a, 0x0a) // WRITE tx_w
+// AM_RANGE(0x0c, 0x0c) // READ rx_r
+// AM_RANGE(0x0e, 0x0e) //
+ADDRESS_MAP_END
+
+//-------------------------------------------------
+// namco_c139_device - constructor
+//-------------------------------------------------
+
+namco_c139_device::namco_c139_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : device_t(mconfig, NAMCO_C139, "namco_c139_longname", tag, owner, clock, "namco_c139", __FILE__),
+ device_memory_interface(mconfig, *this),
+ m_space_config("data", ENDIANNESS_BIG, 16, 14, 0, *ADDRESS_MAP_NAME(data_map))
+{
+}
+
+
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void namco_c139_device::device_start()
+{
+ m_ram = (uint16_t*)memshare("sharedram")->ptr();
+
+}
+
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void namco_c139_device::device_reset()
+{
+}
+
+//-------------------------------------------------
+// memory_space_config - return a description of
+// any address spaces owned by this device
+//-------------------------------------------------
+
+const address_space_config *namco_c139_device::memory_space_config(address_spacenum spacenum) const
+{
+ return (spacenum == AS_DATA) ? &m_space_config : nullptr;
+}
+
+//**************************************************************************
+// READ/WRITE HANDLERS
+//**************************************************************************
+
+READ16_MEMBER(namco_c139_device::ram_r)
+{
+ return m_ram[offset];
+}
+
+WRITE16_MEMBER(namco_c139_device::ram_w)
+{
+ COMBINE_DATA(&m_ram[offset]);
+}
+
+READ16_MEMBER(namco_c139_device::status_r)
+{
+ /*
+ x-- RX READY or irq pending?
+ -x- IRQ direction: 1 RX cause - 0 TX cause
+ */
+ return 4; // STATUS bit?
+}
diff --git a/src/mame/machine/namco_c139.h b/src/mame/machine/namco_c139.h
new file mode 100644
index 00000000000..08a38e74425
--- /dev/null
+++ b/src/mame/machine/namco_c139.h
@@ -0,0 +1,67 @@
+// license:BSD-3-Clause
+// copyright-holders:Angelo Salese
+/***************************************************************************
+
+ Namco C139 - Serial I/F Controller
+
+***************************************************************************/
+
+#pragma once
+
+#ifndef __NAMCO_C139DEV_H__
+#define __NAMCO_C139DEV_H__
+
+
+
+//**************************************************************************
+// INTERFACE CONFIGURATION MACROS
+//**************************************************************************
+
+#define MCFG_NAMCO_C139_ADD(_tag) \
+ MCFG_DEVICE_ADD(_tag, NAMCO_C139, 0)
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> namco_c139_device
+
+class namco_c139_device : public device_t,
+ public device_memory_interface
+{
+public:
+ // construction/destruction
+ namco_c139_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+ // I/O operations
+ DECLARE_ADDRESS_MAP(regs_map, 16);
+
+ DECLARE_READ16_MEMBER(status_r);
+
+ DECLARE_READ16_MEMBER(ram_r);
+ DECLARE_WRITE16_MEMBER(ram_w);
+
+protected:
+ // device-level overrides
+// virtual void device_validity_check(validity_checker &valid) const;
+ virtual void device_start() override;
+ virtual void device_reset() override;
+ virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_DATA) const override;
+private:
+ const address_space_config m_space_config;
+ uint16_t* m_ram;
+};
+
+
+// device type definition
+extern const device_type NAMCO_C139;
+
+
+
+//**************************************************************************
+// GLOBAL VARIABLES
+//**************************************************************************
+
+
+
+#endif
diff --git a/src/mame/machine/namco_c148.cpp b/src/mame/machine/namco_c148.cpp
new file mode 100644
index 00000000000..d09d82c7ff6
--- /dev/null
+++ b/src/mame/machine/namco_c148.cpp
@@ -0,0 +1,250 @@
+// license:BSD-3-Clause
+// copyright-holders:Angelo Salese
+/***************************************************************************
+
+ Namco C148 - CPU Bus Manager
+
+ Does some Memory Decode, Interrupt Handling, 3 bit PIO port, Bus Controller
+
+ Based off implementation from K.Wilkins and Phil Stroffolino
+
+ TODO:
+ - hookup C116 device, @see mame/includes/namcoic.h
+
+=============================================================================
+Interrupt Controller C148 1C0000-1FFFFF R/W D00-D02
+ Bus Controller? 1C0XXX
+ ???????? 1C2XXX
+ ???????? 1C4XXX
+ -x- master priority bit?
+ Master/Slave IRQ level 1C6XXX D00-D02
+ EXIRQ level 1C8XXX D00-D02
+ POSIRQ level 1CAXXX D00-D02
+ SCIRQ level 1CCXXX D00-D02
+ VBLANK IRQ level 1CEXXX D00-D02
+ xxx irq level for specific irq.
+ ???????? 1D0XXX
+ ???????? 1D4000 trigger master/slave INT?
+
+ Acknowlegde Master/Slave IRQ 1D6XXX ack master/slave INT
+ Acknowledge EXIRQ 1D8XXX
+ Acknowledge POSIRQ 1DAXXX
+ Acknowledge SCIRQ 1DCXXX
+ Acknowledge VBLANK IRQ 1DEXXX
+
+ EEPROM Ready status 1E0XXX R D01
+ Sound CPU Reset control 1E2XXX W D01
+ Slave 68000 & IO CPU Reset 1E4XXX W D01
+ xxx PIO ports, per-HW / CPU specific
+ Watchdog reset kicker 1E6XXX W
+ xxx Unknown at current stage if internal or external to the C148
+
+***************************************************************************/
+
+#include "emu.h"
+#include "namco_c148.h"
+
+#define VERBOSE 0
+#define LOG(x) do { if (VERBOSE) printf x; } while (0)
+
+
+
+//**************************************************************************
+// GLOBAL VARIABLES
+//**************************************************************************
+
+// device type definition
+const device_type NAMCO_C148 = &device_creator<namco_c148_device>;
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// namco_c148_device - constructor
+//-------------------------------------------------
+
+namco_c148_device::namco_c148_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : device_t(mconfig, NAMCO_C148, "Namco C148 Interrupt Controller", tag, owner, clock, "namco_c148", __FILE__),
+ m_out_ext1_cb(*this),
+ m_out_ext2_cb(*this),
+ m_hostcpu_tag(nullptr),
+ m_linked_c148_tag(nullptr)
+{
+}
+
+// (*) denotes master CPU only
+DEVICE_ADDRESS_MAP_START( map, 16, namco_c148_device )
+ AM_RANGE(0x04000, 0x05fff) AM_READWRITE8(bus_ctrl_r, bus_ctrl_w, 0x00ff)
+ AM_RANGE(0x06000, 0x07fff) AM_READWRITE8(cpu_irq_level_r,cpu_irq_level_w,0x00ff) // CPUIRQ lv
+ AM_RANGE(0x08000, 0x09fff) AM_READWRITE8(ex_irq_level_r,ex_irq_level_w,0x00ff) // EXIRQ lv
+ AM_RANGE(0x0a000, 0x0bfff) AM_READWRITE8(pos_irq_level_r,pos_irq_level_w,0x00ff) // POSIRQ lv
+ AM_RANGE(0x0c000, 0x0dfff) AM_READWRITE8(sci_irq_level_r,sci_irq_level_w,0x00ff) // SCIRQ lv
+ AM_RANGE(0x0e000, 0x0ffff) AM_READWRITE8(vblank_irq_level_r,vblank_irq_level_w,0x00ff) // VBlank IRQ lv
+
+ AM_RANGE(0x10000, 0x11fff) AM_WRITE(cpu_irq_assert_w)
+ AM_RANGE(0x16000, 0x17fff) AM_READWRITE(cpu_irq_ack_r, cpu_irq_ack_w) // CPUIRQ ack
+ AM_RANGE(0x18000, 0x19fff) AM_READWRITE(ex_irq_ack_r, ex_irq_ack_w) // EXIRQ ack
+ AM_RANGE(0x1a000, 0x1bfff) AM_READWRITE(pos_irq_ack_r, pos_irq_ack_w) // POSIRQ ack
+ AM_RANGE(0x1c000, 0x1dfff) AM_READWRITE(sci_irq_ack_r, sci_irq_ack_w) // SCIRQ ack
+ AM_RANGE(0x1e000, 0x1ffff) AM_READWRITE(vblank_irq_ack_r, vblank_irq_ack_w) // VBlank IRQ ack
+ AM_RANGE(0x20000, 0x21fff) AM_READ8(ext_r,0x00ff) // EEPROM ready status (*)
+ AM_RANGE(0x22000, 0x23fff) AM_READNOP AM_WRITE8(ext1_w,0x00ff) // sound CPU reset (*)
+ AM_RANGE(0x24000, 0x25fff) AM_WRITE8(ext2_w,0x00ff) // slave & i/o reset (*)
+ AM_RANGE(0x26000, 0x27fff) AM_NOP // watchdog
+ADDRESS_MAP_END
+
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void namco_c148_device::device_start()
+{
+ m_hostcpu = machine().device<cpu_device>(m_hostcpu_tag);
+ m_linked_c148 = machine().device<namco_c148_device>(m_linked_c148_tag);
+ assert(m_hostcpu != nullptr);
+
+ m_out_ext1_cb.resolve_safe();
+ m_out_ext2_cb.resolve_safe();
+
+ // TODO: link to SCI, EX and the screen device controller devices
+}
+
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void namco_c148_device::device_reset()
+{
+ m_irqlevel.vblank = 0;
+ m_irqlevel.pos = 0;
+ m_irqlevel.sci = 0;
+ m_irqlevel.ex = 0;
+ m_irqlevel.cpu = 0;
+}
+
+//**************************************************************************
+// IRQ section
+//**************************************************************************
+
+READ8_MEMBER( namco_c148_device::pos_irq_level_r ) { return m_irqlevel.pos & 7; }
+READ8_MEMBER( namco_c148_device::vblank_irq_level_r ) { return m_irqlevel.vblank & 7; }
+READ8_MEMBER( namco_c148_device::cpu_irq_level_r ) { return m_irqlevel.cpu & 7; }
+READ8_MEMBER( namco_c148_device::ex_irq_level_r ) { return m_irqlevel.ex & 7; }
+READ8_MEMBER( namco_c148_device::sci_irq_level_r ) { return m_irqlevel.sci & 7; }
+
+inline void namco_c148_device::flush_irq_acks()
+{
+ // If writing an IRQ priority register, clear any pending IRQs.
+ // Dirt Fox and Winning Run require this behaviour
+ // TODO: literal behaviour, Winning Run GPU doesn't seem to care about irq ack ports at all?
+ for(int i=0;i<8;i++)
+ m_hostcpu->set_input_line(i,CLEAR_LINE);
+}
+
+WRITE8_MEMBER( namco_c148_device::pos_irq_level_w ) { m_irqlevel.pos = data & 7; flush_irq_acks(); if(data != 0) { LOG(("%s: pos IRQ level = %02x\n",this->tag(),data)); } }
+WRITE8_MEMBER( namco_c148_device::vblank_irq_level_w ) { m_irqlevel.vblank = data & 7; flush_irq_acks(); LOG(("%s: vblank IRQ level = %02x\n",this->tag(),data)); }
+WRITE8_MEMBER( namco_c148_device::cpu_irq_level_w ) { m_irqlevel.cpu = data & 7; flush_irq_acks(); LOG(("%s: cpu IRQ level = %02x\n",this->tag(),data)); }
+WRITE8_MEMBER( namco_c148_device::ex_irq_level_w ) { m_irqlevel.ex = data & 7; flush_irq_acks(); LOG(("%s: ex IRQ level = %02x\n",this->tag(),data)); }
+WRITE8_MEMBER( namco_c148_device::sci_irq_level_w ) { m_irqlevel.sci = data & 7; flush_irq_acks(); LOG(("%s: sci IRQ level = %02x\n",this->tag(),data)); }
+
+READ16_MEMBER( namco_c148_device::vblank_irq_ack_r ) { m_hostcpu->set_input_line(m_irqlevel.vblank, CLEAR_LINE); return 0; }
+READ16_MEMBER( namco_c148_device::pos_irq_ack_r ) { m_hostcpu->set_input_line(m_irqlevel.pos, CLEAR_LINE); return 0; }
+READ16_MEMBER( namco_c148_device::cpu_irq_ack_r ) { m_hostcpu->set_input_line(m_irqlevel.cpu, CLEAR_LINE); return 0; }
+READ16_MEMBER( namco_c148_device::ex_irq_ack_r ) { m_hostcpu->set_input_line(m_irqlevel.ex, CLEAR_LINE); return 0; }
+READ16_MEMBER( namco_c148_device::sci_irq_ack_r ) { m_hostcpu->set_input_line(m_irqlevel.sci, CLEAR_LINE); return 0; }
+
+WRITE16_MEMBER( namco_c148_device::vblank_irq_ack_w ) { m_hostcpu->set_input_line(m_irqlevel.vblank, CLEAR_LINE); }
+WRITE16_MEMBER( namco_c148_device::pos_irq_ack_w ) { m_hostcpu->set_input_line(m_irqlevel.pos, CLEAR_LINE); }
+WRITE16_MEMBER( namco_c148_device::cpu_irq_ack_w ) { m_hostcpu->set_input_line(m_irqlevel.cpu, CLEAR_LINE); }
+WRITE16_MEMBER( namco_c148_device::ex_irq_ack_w ) { m_hostcpu->set_input_line(m_irqlevel.ex, CLEAR_LINE); }
+WRITE16_MEMBER( namco_c148_device::sci_irq_ack_w ) { m_hostcpu->set_input_line(m_irqlevel.sci, CLEAR_LINE); }
+
+//**************************************************************************
+// Comm ports
+//**************************************************************************
+
+READ8_MEMBER( namco_c148_device::ext_r )
+{
+ return 0xff; // TODO: bit 0 EEPROM bit ready
+}
+
+WRITE8_MEMBER( namco_c148_device::ext1_w )
+{
+ m_out_ext1_cb(data & 7);
+}
+
+WRITE8_MEMBER( namco_c148_device::ext2_w )
+{
+ m_out_ext2_cb(data & 7);
+ // TODO: bit 1/2 in Winning Run GPU might be irq enable?
+}
+
+READ8_MEMBER( namco_c148_device::bus_ctrl_r )
+{
+ return m_bus_reg;
+}
+
+WRITE8_MEMBER( namco_c148_device::bus_ctrl_w )
+{
+ m_bus_reg = data & 7;
+}
+
+
+WRITE16_MEMBER( namco_c148_device::cpu_irq_assert_w)
+{
+ // TODO: Starblade relies on this for showing large polygons, is it the right place?
+ m_linked_c148->cpu_irq_trigger();
+}
+
+//**************************************************************************
+// GETTERS/SETTERS
+//**************************************************************************
+
+void namco_c148_device::vblank_irq_trigger()
+{
+ // TODO: Phelios doesn't ack the vblank irq at all!
+ m_hostcpu->set_input_line(m_irqlevel.vblank, HOLD_LINE);
+}
+
+void namco_c148_device::pos_irq_trigger()
+{
+ m_hostcpu->set_input_line(m_irqlevel.pos, ASSERT_LINE);
+}
+
+void namco_c148_device::cpu_irq_trigger()
+{
+ m_hostcpu->set_input_line(m_irqlevel.cpu, ASSERT_LINE);
+}
+
+void namco_c148_device::ex_irq_trigger()
+{
+ m_hostcpu->set_input_line(m_irqlevel.ex, ASSERT_LINE);
+}
+
+void namco_c148_device::sci_irq_trigger()
+{
+ m_hostcpu->set_input_line(m_irqlevel.sci, ASSERT_LINE);
+}
+
+// TODO: these doesn't belong here, needs C116 device
+READ8_MEMBER( namco_c148_device::ext_posirq_line_r )
+{
+ // TODO: same as regular register? winrun91 reads here and subs with integer 0x39 for a new posirq that never gets triggered.
+ return (m_posirq_line) & 0xff;
+}
+
+WRITE8_MEMBER( namco_c148_device::ext_posirq_line_w )
+{
+ m_posirq_line = data;
+}
+
+uint8_t namco_c148_device::get_posirq_line()
+{
+ return m_posirq_line;
+}
+
diff --git a/src/mame/machine/namco_c148.h b/src/mame/machine/namco_c148.h
new file mode 100644
index 00000000000..3f53228ebcc
--- /dev/null
+++ b/src/mame/machine/namco_c148.h
@@ -0,0 +1,143 @@
+// license:BSD-3-Clause
+// copyright-holders:Angelo Salese
+/***************************************************************************
+
+ Namco C148 - CPU Bus Manager
+
+***************************************************************************/
+
+#pragma once
+
+#ifndef __NAMCO_C148DEV_H__
+#define __NAMCO_C148DEV_H__
+
+
+
+//**************************************************************************
+// INTERFACE CONFIGURATION MACROS
+//**************************************************************************
+
+#define MCFG_NAMCO_C148_ADD(_tag, _cputag, _cpumaster) \
+ MCFG_DEVICE_ADD(_tag, NAMCO_C148, 0) \
+ namco_c148_device::configure_device(*device, _cputag, _cpumaster);
+
+#define MCFG_NAMCO_C148_EXT1_CB(_cb) \
+ devcb = &namco_c148_device::set_out_ext1_callback(*device, DEVCB_##_cb);
+
+#define MCFG_NAMCO_C148_EXT2_CB(_cb) \
+ devcb = &namco_c148_device::set_out_ext2_callback(*device, DEVCB_##_cb);
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> namco_c148_device
+
+class namco_c148_device : public device_t
+{
+public:
+ // construction/destruction
+ namco_c148_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+ DECLARE_ADDRESS_MAP(map, 16);
+
+ static void configure_device(device_t &device, const char *tag, bool is_master)
+ {
+ namco_c148_device &dev = downcast<namco_c148_device &>(device);
+ dev.m_hostcpu_tag = tag;
+ dev.m_hostcpu_master = is_master;
+ }
+
+ static void link_c148_device(device_t &device, const char *tag)
+ {
+ namco_c148_device &dev = downcast<namco_c148_device &>(device);
+
+ dev.m_linked_c148_tag = tag;
+ }
+
+ template<class _Object> static devcb_base &set_out_ext1_callback(device_t &device, _Object object) { return downcast<namco_c148_device &>(device).m_out_ext1_cb.set_callback(object); }
+ template<class _Object> static devcb_base &set_out_ext2_callback(device_t &device, _Object object) { return downcast<namco_c148_device &>(device).m_out_ext2_cb.set_callback(object); }
+
+ devcb_write8 m_out_ext1_cb;
+ devcb_write8 m_out_ext2_cb;
+
+ DECLARE_READ8_MEMBER( vblank_irq_level_r );
+ DECLARE_WRITE8_MEMBER( vblank_irq_level_w );
+ DECLARE_READ16_MEMBER( vblank_irq_ack_r );
+ DECLARE_WRITE16_MEMBER( vblank_irq_ack_w );
+
+ DECLARE_READ8_MEMBER( pos_irq_level_r );
+ DECLARE_WRITE8_MEMBER( pos_irq_level_w );
+ DECLARE_READ16_MEMBER( pos_irq_ack_r );
+ DECLARE_WRITE16_MEMBER( pos_irq_ack_w );
+
+ DECLARE_READ8_MEMBER( cpu_irq_level_r );
+ DECLARE_WRITE8_MEMBER( cpu_irq_level_w );
+ DECLARE_READ16_MEMBER( cpu_irq_ack_r );
+ DECLARE_WRITE16_MEMBER( cpu_irq_ack_w );
+
+ DECLARE_READ8_MEMBER( ex_irq_level_r );
+ DECLARE_WRITE8_MEMBER( ex_irq_level_w );
+ DECLARE_READ16_MEMBER( ex_irq_ack_r );
+ DECLARE_WRITE16_MEMBER( ex_irq_ack_w );
+
+ DECLARE_READ8_MEMBER( sci_irq_level_r );
+ DECLARE_WRITE8_MEMBER( sci_irq_level_w );
+ DECLARE_READ16_MEMBER( sci_irq_ack_r );
+ DECLARE_WRITE16_MEMBER( sci_irq_ack_w );
+
+ DECLARE_READ8_MEMBER( ext_posirq_line_r );
+ DECLARE_WRITE8_MEMBER( ext_posirq_line_w );
+ DECLARE_WRITE16_MEMBER( cpu_irq_assert_w );
+
+ DECLARE_READ8_MEMBER( bus_ctrl_r );
+ DECLARE_WRITE8_MEMBER( bus_ctrl_w );
+
+ DECLARE_READ8_MEMBER( ext_r );
+ DECLARE_WRITE8_MEMBER( ext1_w );
+ DECLARE_WRITE8_MEMBER( ext2_w );
+ void vblank_irq_trigger();
+ void pos_irq_trigger();
+ void ex_irq_trigger();
+ void sci_irq_trigger();
+ uint8_t get_posirq_line();
+
+protected:
+ void cpu_irq_trigger();
+ // device-level overrides
+// virtual void device_validity_check(validity_checker &valid) const;
+ virtual void device_start() override;
+ virtual void device_reset() override;
+private:
+ cpu_device *m_hostcpu; /**< reference to the host cpu */
+ namco_c148_device *m_linked_c148; /**< reference to linked master/slave c148 */
+ const char *m_hostcpu_tag; /**< host cpu tag name */
+ const char *m_linked_c148_tag; /**< other c148 tag name */
+ bool m_hostcpu_master; /**< define if host cpu is master */
+ struct{
+ uint8_t cpu;
+ uint8_t ex;
+ uint8_t sci;
+ uint8_t pos;
+ uint8_t vblank;
+ }m_irqlevel;
+
+ uint8_t m_posirq_line;
+ uint8_t m_bus_reg;
+ void flush_irq_acks();
+};
+
+
+// device type definition
+extern const device_type NAMCO_C148;
+
+
+
+//**************************************************************************
+// GLOBAL VARIABLES
+//**************************************************************************
+
+
+
+#endif
diff --git a/src/mame/machine/namcos2.cpp b/src/mame/machine/namcos2.cpp
index 993157854aa..d2c23f350ed 100644
--- a/src/mame/machine/namcos2.cpp
+++ b/src/mame/machine/namcos2.cpp
@@ -71,6 +71,44 @@ READ16_MEMBER( namcos2_state::namcos2_finallap_prot_r )
#define m_eeprom_size 0x2000
+WRITE8_MEMBER(namcos2_shared_state::sound_reset_w)
+{
+ address_space &masterspace = m_maincpu->space(AS_PROGRAM);
+
+ if (data & 0x01)
+ {
+ /* Resume execution */
+ m_audiocpu->set_input_line(INPUT_LINE_RESET, CLEAR_LINE);
+ masterspace.device().execute().yield();
+ }
+ else
+ {
+ /* Suspend execution */
+ m_audiocpu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE);
+ }
+
+ if (namcos2_kickstart != nullptr)
+ {
+ //printf( "dspkick=0x%x\n", data );
+ if (data & 0x04)
+ {
+ (*namcos2_kickstart)(space.machine(), 1);
+ }
+ }
+}
+
+// TODO:
+WRITE8_MEMBER(namcos2_shared_state::system_reset_w)
+{
+ reset_all_subcpus(data & 1 ? CLEAR_LINE : ASSERT_LINE);
+
+ if (data & 0x01)
+ {
+ address_space &masterspace = m_maincpu->space(AS_PROGRAM);
+ masterspace.device().execute().yield();
+ }
+}
+
void namcos2_shared_state::reset_all_subcpus(int state)
{
m_slave->set_input_line(INPUT_LINE_RESET, state);
@@ -104,7 +142,6 @@ MACHINE_START_MEMBER(namcos2_shared_state,namcos2)
namcos2_kickstart = nullptr;
m_eeprom = std::make_unique<uint8_t[]>(m_eeprom_size);
machine().device<nvram_device>("nvram")->set_base(m_eeprom.get(), m_eeprom_size);
- m_posirq_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(namcos2_shared_state::namcos2_posirq_tick),this));
}
MACHINE_RESET_MEMBER(namcos2_shared_state, namcos2)
@@ -124,12 +161,6 @@ MACHINE_RESET_MEMBER(namcos2_shared_state, namcos2)
/* Place CPU2 & CPU3 into the reset condition */
reset_all_subcpus(ASSERT_LINE);
- /* Initialise interrupt handlers */
- init_c148();
-
- /* reset POSIRQ timer */
- m_posirq_timer->adjust(attotime::never);
-
m_player_mux = 0;
}
@@ -147,40 +178,6 @@ READ8_MEMBER( namcos2_shared_state::namcos2_68k_eeprom_r )
return m_eeprom[offset];
}
-
-
-/**************************************************************/
-/* 68000 Shared serial communications processor (CPU5?) */
-/**************************************************************/
-
-READ16_MEMBER( namcos2_state::serial_comms_ram_r ){
- return m_serial_comms_ram[offset];
-}
-
-WRITE16_MEMBER( namcos2_state::serial_comms_ram_w ){
- COMBINE_DATA( &m_serial_comms_ram[offset] );
-}
-
-READ16_MEMBER( namcos2_state::serial_comms_ctrl_r )
-{
- uint16_t retval = m_serial_comms_ctrl[offset];
-
- switch(offset){
- case 0x00:
- retval |= 0x0004; /* Set READY? status bit */
- break;
-
- default:
- break;
- }
- return retval;
-}
-
-WRITE16_MEMBER( namcos2_state::serial_comms_ctrl_w )
-{
- COMBINE_DATA( &m_serial_comms_ctrl[offset] );
-}
-
/*************************************************************/
/* 68000 Shared protection/random key generator */
/*************************************************************
@@ -435,252 +432,6 @@ bool namcos2_shared_state::is_system21()
}
}
-void namcos2_shared_state::init_c148()
-{
- for(int loop = 0; loop < 0x20; loop++)
- {
- m_68k_master_C148[loop] = 0;
- m_68k_slave_C148[loop] = 0;
- m_68k_gpu_C148[loop] = 0;
- }
-}
-
-uint16_t namcos2_shared_state::readwrite_c148( address_space &space, offs_t offset, uint16_t data, int bWrite )
-{
- offs_t addr = ((offset * 2) + 0x1c0000) & 0x1fe000;
- device_t *altcpu = nullptr;
- uint16_t *pC148Reg = nullptr;
- uint16_t *pC148RegAlt = nullptr;
- uint16_t result = 0;
-
- if (&space.device() == m_maincpu)
- {
- pC148Reg = m_68k_master_C148;
- altcpu = m_slave;
- pC148RegAlt = m_68k_slave_C148;
- }
- else if (&space.device() == m_slave)
- {
- pC148Reg = m_68k_slave_C148;
- altcpu = m_maincpu;
- pC148RegAlt = m_68k_master_C148;
- }
- else if (&space.device() == m_gpu)
- {
- pC148Reg = m_68k_gpu_C148;
- altcpu = m_maincpu;
- pC148RegAlt = m_68k_master_C148;
- }
-
- if( bWrite )
- {
- int reg = (addr >> 13) & 0x1f;
-
- // If writing an IRQ priority register, clear any pending IRQs.
- // Dirt Fox and Winning Run require this behaviour
- if (reg < 8)
- space.device().execute().set_input_line(pC148Reg[reg], CLEAR_LINE);
-
- pC148Reg[reg] = data & 0x0007;
- }
-
- switch(addr)
- {
- case 0x1c0000: break; /* ? NAMCOS2_C148_0 */
- case 0x1c2000: break; /* ? NAMCOS2_C148_1 */
- case 0x1c4000: break; /* ? NAMCOS2_C148_2 */
-
- /* IRQ level */
- case 0x1c6000: break; /* NAMCOS2_C148_CPUIRQ */
- case 0x1c8000: break; /* NAMCOS2_C148_EXIRQ */
- case 0x1ca000: break; /* NAMCOS2_C148_POSIRQ */
- case 0x1cc000: break; /* NAMCOS2_C148_SERIRQ */
- case 0x1ce000: break; /* NAMCOS2_C148_VBLANKIRQ */
-
- case 0x1d0000: /* ? NAMCOS2_C148_0 */
- if( bWrite )
- {
- // osd_printf_debug( "cpu(%d) RAM[0x%06x] = 0x%x\n", cpu, addr, data );
- /* Dubious to assert IRQ for other CPU here, but Starblade seems to rely on it.
- It fails to show large polygons otherwise. */
- altcpu->execute().set_input_line(pC148RegAlt[NAMCOS2_C148_CPUIRQ], ASSERT_LINE);
- }
- break;
-
- case 0x1d2000: break; /* ? NAMCOS2_C148_1 */
-
- case 0x1d4000: /* ? NAMCOS2_C148_2 */
- if( bWrite )
- {
- // osd_printf_debug( "cpu(%d) RAM[0x%06x] = 0x%x\n", cpu, addr, data );
- /* Dubious to assert IRQ for other CPU here: Rolling Thunder 2 and Fine Hour break. */
- // altcpu->execute().set_input_line(pC148RegAlt[NAMCOS2_C148_CPUIRQ], ASSERT_LINE);
- }
- break;
-
-
- /* IRQ ack */
- case 0x1d6000: /* NAMCOS2_C148_CPUIRQ */
- // if( bWrite ) osd_printf_debug( "cpu(%d) RAM[0x%06x] = 0x%x\n", cpu, addr, data );
- space.device().execute().set_input_line(pC148Reg[NAMCOS2_C148_CPUIRQ], CLEAR_LINE);
- break;
-
- case 0x1d8000: /* NAMCOS2_C148_EXIRQ */
- // if( bWrite ) osd_printf_debug( "cpu(%d) RAM[0x%06x] = 0x%x\n", cpu, addr, data );
- space.device().execute().set_input_line(pC148Reg[NAMCOS2_C148_EXIRQ], CLEAR_LINE);
- break;
-
- case 0x1da000: /* NAMCOS2_C148_POSIRQ */
- // if( bWrite ) osd_printf_debug( "cpu(%d) RAM[0x%06x] = 0x%x\n", cpu, addr, data );
- space.device().execute().set_input_line(pC148Reg[NAMCOS2_C148_POSIRQ], CLEAR_LINE);
- break;
-
- case 0x1dc000: /* NAMCOS2_C148_SERIRQ */
- // if( bWrite ) osd_printf_debug( "cpu(%d) RAM[0x%06x] = 0x%x\n", cpu, addr, data );
- space.device().execute().set_input_line(pC148Reg[NAMCOS2_C148_SERIRQ], CLEAR_LINE);
- break;
-
- case 0x1de000: /* NAMCOS2_C148_VBLANKIRQ */
- space.device().execute().set_input_line(pC148Reg[NAMCOS2_C148_VBLANKIRQ], CLEAR_LINE);
- break;
-
-
- case 0x1e0000: /* EEPROM Status Register */
- result = ~0; /* Only BIT0 used: 1=EEPROM READY 0=EEPROM BUSY */
- break;
-
- case 0x1e2000: /* Sound CPU Reset control */
- if (&space.device() == m_maincpu) /* ? */
- {
- if (data & 0x01)
- {
- /* Resume execution */
- m_audiocpu->set_input_line(INPUT_LINE_RESET, CLEAR_LINE);
- space.device().execute().yield();
- }
- else
- {
- /* Suspend execution */
- m_audiocpu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE);
- }
- if (namcos2_kickstart != nullptr)
- {
- //printf( "dspkick=0x%x\n", data );
- if (data & 0x04)
- {
- (*namcos2_kickstart)(space.machine(), 1);
- }
- }
- }
- break;
-
- case 0x1e4000: /* Alt 68000 & IO CPU Reset */
- if (&space.device() == m_maincpu) /* ? */
- {
- if (data & 0x01)
- { /* Resume execution */
- reset_all_subcpus(CLEAR_LINE);
- /* Give the new CPU an immediate slice of the action */
- space.device().execute().yield();
- }
- else
- { /* Suspend execution */
- reset_all_subcpus(ASSERT_LINE);
- }
- }
- break;
-
- case 0x1e6000: /* Watchdog reset kicker */
- /* watchdog_reset_w(0,0); */
- break;
-
- default:
- break;
- }
- return result;
-}
-
-WRITE16_MEMBER( namcos2_shared_state::namcos2_68k_master_C148_w )
-{
- (void)readwrite_c148(space, offset, data, 1);
-}
-
-READ16_MEMBER( namcos2_shared_state::namcos2_68k_master_C148_r )
-{
- return readwrite_c148(space, offset, 0, 0);
-}
-
-WRITE16_MEMBER( namcos2_shared_state::namcos2_68k_slave_C148_w )
-{
- (void)readwrite_c148(space, offset, data, 1);
-}
-
-READ16_MEMBER( namcos2_shared_state::namcos2_68k_slave_C148_r )
-{
- return readwrite_c148(space, offset, 0, 0);
-}
-
-WRITE16_MEMBER( namcos2_shared_state::namcos21_68k_gpu_C148_w )
-{
- (void)readwrite_c148(space, offset, data, 1);
-}
-
-READ16_MEMBER( namcos2_shared_state::namcos21_68k_gpu_C148_r )
-{
- return readwrite_c148(space, offset, 0, 0);
-}
-
-
-int namcos2_shared_state::get_posirq_scanline()
-{
- if (is_system21()) return 0;
- return downcast<namcos2_state *>(this)->get_pos_irq_scanline();
-}
-
-TIMER_CALLBACK_MEMBER(namcos2_shared_state::namcos2_posirq_tick)
-{
- if (is_system21()) {
- if (m_68k_gpu_C148[NAMCOS2_C148_POSIRQ]) {
- m_screen->update_partial(param);
- m_gpu->set_input_line(m_68k_gpu_C148[NAMCOS2_C148_POSIRQ] , ASSERT_LINE);
- }
- return;
- }
-
- if (m_68k_master_C148[NAMCOS2_C148_POSIRQ]|m_68k_slave_C148[NAMCOS2_C148_POSIRQ]) {
- m_screen->update_partial(param);
- if (m_68k_master_C148[NAMCOS2_C148_POSIRQ]) m_maincpu->set_input_line(m_68k_master_C148[NAMCOS2_C148_POSIRQ] , ASSERT_LINE);
- if (m_68k_slave_C148[NAMCOS2_C148_POSIRQ]) m_slave->set_input_line(m_68k_slave_C148[NAMCOS2_C148_POSIRQ] , ASSERT_LINE);
- }
-}
-
-void namcos2_shared_state::adjust_posirq_timer( int scanline )
-{
- m_posirq_timer->adjust(m_screen->time_until_pos(scanline, 80), scanline);
-}
-
-INTERRUPT_GEN_MEMBER(namcos2_shared_state::namcos2_68k_master_vblank)
-{
- if (!is_system21()) adjust_posirq_timer(get_posirq_scanline());
- device.execute().set_input_line(m_68k_master_C148[NAMCOS2_C148_VBLANKIRQ], HOLD_LINE);
-}
-
-INTERRUPT_GEN_MEMBER(namcos2_shared_state::namcos2_68k_slave_vblank)
-{
- if (!is_system21()) adjust_posirq_timer(get_posirq_scanline());
- device.execute().set_input_line(m_68k_slave_C148[NAMCOS2_C148_VBLANKIRQ], HOLD_LINE);
-}
-
-INTERRUPT_GEN_MEMBER(namcos2_shared_state::namcos2_68k_gpu_vblank)
-{
- /* only used by namcos21 */
- //int scanline = get_posirq_scanline();
- int32_t scanline = 0x50+0x89; /* HACK for Winning Run */
-
- //printf( "namcos2_68k_gpu_vblank(%d)\n",m_68k_gpu_C148[NAMCOS2_C148_POSIRQ] );
- adjust_posirq_timer(scanline);
- device.execute().set_input_line(m_68k_gpu_C148[NAMCOS2_C148_VBLANKIRQ], HOLD_LINE);
-}
/**************************************************************/
/* Sound sub-system */
diff --git a/src/mame/machine/nl_stuntcyc.cpp b/src/mame/machine/nl_stuntcyc.cpp
index ee4227932c8..ccbf4b2906e 100644
--- a/src/mame/machine/nl_stuntcyc.cpp
+++ b/src/mame/machine/nl_stuntcyc.cpp
@@ -77,10 +77,10 @@ NETLIST_START(stuntcyc)
ALIAS(VRESET, M3_2.QQ)
ALIAS(VRESET_Q, M3_2.Q)
- TTL_7402_NOR(J5_2, H6_3.Q, J5_1.Q)
- TTL_7402_NOR(J5_1, 32H, J5_2.Q)
- TTL_7402_NOR(J5_3, 8V, J5_4.Q)
- TTL_7402_NOR(J5_4, VRESET, J5_3.Q)
+ TTL_7402_NOR(J5_2, HSYNC, HRESET)
+ TTL_7402_NOR(J5_1, 32H, HSYNC_Q)
+ TTL_7402_NOR(J5_3, 8V, VSYNC_Q)
+ TTL_7402_NOR(J5_4, VSYNC, VRESET)
ALIAS(HSYNC, J5_1.Q)
ALIAS(HSYNC_Q, J5_2.Q)
ALIAS(VSYNC, J5_3.Q)
@@ -93,18 +93,19 @@ NETLIST_START(stuntcyc)
ALIAS(RAMP_WINDOW_HIT_Q, N5_2.Q)
TTL_7474(N4_1, H_WINDOW, HSYNC, RAMP_WINDOW_HIT_Q, N4_1.QQ)
- TTL_7474(M3_1, N4_1.Q, M3_1.QQ, CYCLE_RESET_Q, P)
+ TTL_7474(M3_1, N4_1.Q, DIRECTION_Q, CYCLE_RESET_Q, P)
ALIAS(DIRECTION, M3_1.Q)
ALIAS(DIRECTION_Q, M3_1.QQ)
TTL_7404_INVERT(N3_3, 32V)
- TTL_7474(J2_2, N3_3.Q, J2_1.Q, P, P)
+ ALIAS(32V_Q, N3_3.Q)
+ TTL_7474(J2_2, 32V_Q, J2_1.Q, P, P)
TTL_7474(J2_1, N4_1.Q, P, J2_2.QQ, P)
TTL_7408_AND(H5_2, 256V_Q, VSYNC_Q)
TTL_9316(K1, HSYNC, P, H5_2.Q, V_COUNTER_RESET_Q, L2_3.Q, Av, Bv, Cv, Dv)
TTL_9316(K2, HSYNC, K1.RC, J2_2.QQ, V_COUNTER_RESET_Q, L2_3.Q, GROUND, GROUND, GROUND, GROUND)
- TTL_7400_NAND(L2_3, K1.RC, K2.RC)
+ TTL_7400_NAND(L2_3, K1.RC, V_WINDOW)
ALIAS(V1, K1.QA)
ALIAS(V2, K1.QB)
ALIAS(V3, K1.QC)
@@ -308,9 +309,9 @@ NETLIST_START(stuntcyc)
TTL_7410_NAND(E3_1, SCORE_1_Q, OBJECTS_Q, E4_3.Q)
ALIAS(WHITE_VIDEO, E3_1.Q)
- TTL_7402_NOR(F4_2, PLAYER_CONTROL, CYCLE)
+ TTL_7400_NAND(F4_2, PLAYER_CONTROL, CYCLE)
TTL_7404_INVERT(D3_1, F4_4.Q)
- TTL_7402_NOR(F4_3, C8_3.Q, D3_1.Q)
+ TTL_7400_NAND(F4_3, C8_3.Q, D3_1.Q)
TTL_7410_NAND(E3_2, F4_2.Q, F4_3.Q, F3_1.Q)
TTL_7400_NAND(F4_1, RAMPS_Q, ROAD_Q)
TTL_7427_NOR(E4_2, F4_1.Q, SCORE_2, E3_2.Q)
diff --git a/src/mame/machine/nycaptor.cpp b/src/mame/machine/nycaptor.cpp
index 8a3f61311bf..4bb6e21a394 100644
--- a/src/mame/machine/nycaptor.cpp
+++ b/src/mame/machine/nycaptor.cpp
@@ -12,105 +12,15 @@
#include "emu.h"
#include "includes/nycaptor.h"
-READ8_MEMBER(nycaptor_state::nycaptor_68705_port_a_r)
-{
- return (m_port_a_out & m_ddr_a) | (m_port_a_in & ~m_ddr_a);
-}
-
-WRITE8_MEMBER(nycaptor_state::nycaptor_68705_port_a_w)
-{
- m_port_a_out = data;
-}
-
-WRITE8_MEMBER(nycaptor_state::nycaptor_68705_ddr_a_w)
-{
- m_ddr_a = data;
-}
-
-/*
- * Port B connections:
- *
- * all bits are logical 1 when read (+5V pullup)
- *
- * 1 W when 1->0, enables latch which brings the command from main CPU (read from port A)
- * 2 W when 0->1, copies port A to the latch for the main CPU
- */
-
-READ8_MEMBER(nycaptor_state::nycaptor_68705_port_b_r)
-{
- return (m_port_b_out & m_ddr_b) | (m_port_b_in & ~m_ddr_b);
-}
-
-WRITE8_MEMBER(nycaptor_state::nycaptor_68705_port_b_w)
-{
- if (BIT(m_ddr_b, 1) && BIT(~data, 1) && BIT(m_port_b_out, 1))
- {
- m_port_a_in = m_from_main;
-
- if (m_main_sent)
- m_mcu->set_input_line(0, CLEAR_LINE);
- m_main_sent = 0;
-
- }
-
- if (BIT(m_ddr_b, 2) && BIT(data, 2) && BIT(~m_port_b_out, 2))
- {
- m_from_mcu = m_port_a_out;
- m_mcu_sent = 1;
- }
-
- m_port_b_out = data;
-}
-
-WRITE8_MEMBER(nycaptor_state::nycaptor_68705_ddr_b_w)
-{
- m_ddr_b = data;
-}
-
-
-READ8_MEMBER(nycaptor_state::nycaptor_68705_port_c_r)
-{
- m_port_c_in = 0;
-
- if (m_main_sent)
- m_port_c_in |= 0x01;
- if (!m_mcu_sent)
- m_port_c_in |= 0x02;
-
- return (m_port_c_out & m_ddr_c) | (m_port_c_in & ~m_ddr_c);
-}
-
-WRITE8_MEMBER(nycaptor_state::nycaptor_68705_port_c_w)
-{
- m_port_c_out = data;
-}
-
-WRITE8_MEMBER(nycaptor_state::nycaptor_68705_ddr_c_w)
-{
- m_ddr_c = data;
-}
-
-WRITE8_MEMBER(nycaptor_state::nycaptor_mcu_w)
-{
- m_from_main = data;
- m_main_sent = 1;
- m_mcu->set_input_line(0, ASSERT_LINE);
-}
-
-READ8_MEMBER(nycaptor_state::nycaptor_mcu_r)
-{
- m_mcu_sent = 0;
- return m_from_mcu;
-}
READ8_MEMBER(nycaptor_state::nycaptor_mcu_status_r1)
{
/* bit 1 = when 1, mcu has sent data to the main cpu */
- return m_mcu_sent ? 2 : 0;
+ return m_bmcu->get_mcu_sent() ? 2 : 0;
}
READ8_MEMBER(nycaptor_state::nycaptor_mcu_status_r2)
{
/* bit 0 = when 1, mcu is ready to receive data from main cpu */
- return m_main_sent ? 0 : 1;
+ return m_bmcu->get_main_sent() ? 0 : 1;
}
diff --git a/src/mame/machine/rm380z.cpp b/src/mame/machine/rm380z.cpp
index 47209eeee98..131bf775be5 100644
--- a/src/mame/machine/rm380z.cpp
+++ b/src/mame/machine/rm380z.cpp
@@ -33,6 +33,9 @@ WRITE8_MEMBER( rm380z_state::port_write )
case 0xFC: // PORT0
//printf("FBFCw[%2.2x] FBFD [%2.2x] FBFE [%2.2x] PC [%4.4x] writenum [%4.4x]\n",data,m_fbfd,m_fbfe,m_maincpu->safe_pc(),writenum);
m_port0 = data;
+
+ m_cassette->output((m_port0 & 0xEF) ? +1.0 : -1.0); // set 2400hz, bit 4
+
if (data&0x01)
{
//printf("WARNING: bit0 of port0 reset\n");
@@ -57,9 +60,11 @@ WRITE8_MEMBER( rm380z_state::port_write )
break;
+ // port 1
case 0xFE: // line on screen to write to divided by 2
//printf("FBFC [%2.2x] FBFD [%2.2x] FBFEw[%2.2x] PC [%4.4x] writenum [%4.4x]\n",m_port0,m_fbfd,data,m_maincpu->safe_pc(),writenum);
m_fbfe=data;
+
break;
case 0xFF: // user I/O port
@@ -92,6 +97,11 @@ READ8_MEMBER( rm380z_state::port_read )
break;
case 0xFE: // PORT1
+ if ((m_cassette)->input() < +0.0)
+ m_port1 &= 0xDF; // bit 5 off
+ else
+ m_port1 |= 0x20; // bit 5 on
+
data = m_port1;
//printf("read of port1 from PC [%x]\n",m_maincpu->safe_pc());
break;
@@ -230,6 +240,28 @@ void rm380z_state::machine_start()
machine().scheduler().timer_pulse(attotime::from_hz(TIMER_SPEED), timer_expired_delegate(FUNC(rm380z_state::static_vblank_timer),this));
}
+DRIVER_INIT_MEMBER( rm380z_state, rm380z )
+{
+ m_videomode=RM380Z_VIDEOMODE_80COL;
+ m_old_videomode=m_videomode;
+ m_port0_mask=0xff;
+}
+
+DRIVER_INIT_MEMBER( rm380z_state, rm380z34d )
+{
+ m_videomode=RM380Z_VIDEOMODE_40COL;
+ m_old_videomode=m_videomode;
+ m_port0_mask=0xdf; // disable 80 column mode
+}
+
+DRIVER_INIT_MEMBER( rm380z_state, rm380z34e )
+{
+ m_videomode=RM380Z_VIDEOMODE_40COL;
+ m_old_videomode=m_videomode;
+ m_port0_mask=0xdf; // disable 80 column mode
+}
+
+
void rm380z_state::machine_reset()
{
m_port0=0x00;
@@ -241,8 +273,8 @@ void rm380z_state::machine_reset()
m_old_old_fbfd=0x00;
writenum=0;
- m_videomode=RM380Z_VIDEOMODE_80COL;
- m_old_videomode=m_videomode;
+// m_videomode=RM380Z_VIDEOMODE_80COL;
+// m_old_videomode=m_videomode;
m_rasterlineCtr=0;
// note: from COS 4.0 videos, screen seems to show garbage at the beginning
diff --git a/src/mame/machine/slapfght.cpp b/src/mame/machine/slapfght.cpp
index c8243414810..d362a1a76c6 100644
--- a/src/mame/machine/slapfght.cpp
+++ b/src/mame/machine/slapfght.cpp
@@ -12,26 +12,6 @@
#include "includes/slapfght.h"
-/***************************************************************************
-
- Tiger Heli MCU
-
-***************************************************************************/
-
-READ8_MEMBER(slapfght_state::tigerh_mcu_r)
-{
- m_mcu_sent = false;
- return m_from_mcu;
-}
-
-WRITE8_MEMBER(slapfght_state::tigerh_mcu_w)
-{
- m_from_main = data;
- m_main_sent = true;
- m_mcu->set_input_line(0, ASSERT_LINE);
-}
-
-
/**************************************************************************/
READ8_MEMBER(slapfght_state::tigerh_mcu_status_r)
@@ -39,115 +19,24 @@ READ8_MEMBER(slapfght_state::tigerh_mcu_status_r)
// d0 is vblank
uint8_t res = m_screen->vblank() ? 1 : 0;
- if (!m_main_sent)
- res |= 0x02;
- if (!m_mcu_sent)
- res |= 0x04;
-
- return res;
-}
-
-
-/***************************************************************************
-
- MCU port handlers (general)
-
-***************************************************************************/
-
-
-READ8_MEMBER(slapfght_state::tigerh_mcu_porta_r)
-{
- return m_to_mcu_latch;
-}
-
-WRITE8_MEMBER(slapfght_state::tigerh_mcu_porta_w)
-{
- m_from_mcu_latch = data;
-}
-
-
-/***************************************************************************
-
- MCU port handlers (Tiger Heli)
-
-***************************************************************************/
-
-WRITE8_MEMBER(slapfght_state::tigerh_mcu_portb_w)
-{
- if ((mem_mask & 0x02) && (~data & 0x02) && (m_old_portB & 0x02))
+ if (m_bmcu)
{
- if (m_main_sent)
- m_mcu->set_input_line(0, CLEAR_LINE);
-
- m_to_mcu_latch = m_from_main;
- m_main_sent = false;
- }
- if ((mem_mask & 0x04) && (data & 0x04) && (~m_old_portB & 0x04))
- {
- m_from_mcu = m_from_mcu_latch;
- m_mcu_sent = true;
+ if (!m_bmcu->get_main_sent())
+ res |= 0x02;
+ if (!m_bmcu->get_mcu_sent())
+ res |= 0x04;
}
- m_old_portB = data;
-}
-
-READ8_MEMBER(slapfght_state::tigerh_mcu_portc_r)
-{
- uint8_t ret = 0;
-
- if (!m_main_sent)
- ret |= 0x01;
- if (m_mcu_sent)
- ret |= 0x02;
-
- return ret;
+ return res;
}
-/***************************************************************************
-
- MCU port handlers (Slap Fight)
-
-***************************************************************************/
-
-WRITE8_MEMBER(slapfght_state::slapfght_mcu_portb_w)
+WRITE8_MEMBER(slapfght_state::scroll_from_mcu_w)
{
- if ((mem_mask & 0x02) && (~data & 0x02) && (m_old_portB & 0x02))
- {
- if (m_main_sent)
- m_mcu->set_input_line(0, CLEAR_LINE);
-
- m_to_mcu_latch = m_from_main;
- m_main_sent = false;
- }
- if ((mem_mask & 0x04) && (data & 0x04) && (~m_old_portB & 0x04))
- {
- m_from_mcu = m_from_mcu_latch;
- m_mcu_sent = true;
- }
- if ((mem_mask & 0x08) && (~data & 0x08) && (m_old_portB & 0x08))
- {
- m_scrollx_lo = m_from_mcu_latch;
- }
- if ((mem_mask & 0x10) && (~data & 0x10) && (m_old_portB & 0x10))
+ switch (offset)
{
- m_scrollx_hi = m_from_mcu_latch;
+ case 0x00: m_scrollx_lo = data; break;
+ case 0x01: m_scrollx_hi = data; break;
}
-
- m_old_portB = data;
-}
-
-READ8_MEMBER(slapfght_state::slapfght_mcu_portc_r)
-{
- uint8_t ret = 0;
-
- if (!m_main_sent)
- ret |= 0x01;
- if (m_mcu_sent)
- ret |= 0x02;
-
- ret ^= 0x3; // inverted logic compared to tigerh
-
- return ret;
}
/***************************************************************************
diff --git a/src/mame/machine/tait8741.cpp b/src/mame/machine/tait8741.cpp
index 612831749f7..3ea6607b1b0 100644
--- a/src/mame/machine/tait8741.cpp
+++ b/src/mame/machine/tait8741.cpp
@@ -332,183 +332,3 @@ uint8_t taito8741_4pack_device::port_read(int num, int offset)
default : return 0;
}
}
-
-/****************************************************************************
-
-joshi Vollyball set.
-
- Only the chip of the communication between MAIN and the SUB.
- For the I/O, there may be I8741 of the addition.
-
- MCU code is not dumped.
- There is some HACK operation because the emulation is imperfect.
-
-****************************************************************************/
-
-const device_type JOSVOLLY8741_4PACK = &device_creator<josvolly8741_4pack_device>;
-
-josvolly8741_4pack_device::josvolly8741_4pack_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : device_t(mconfig, JOSVOLLY8741_4PACK, "I8741 MCU Simulation (Joshi Volleyball)", tag, owner, clock, "josvolly8741_4pack", __FILE__),
- m_port_handler_0_r(*this),
- m_port_handler_1_r(*this),
- m_port_handler_2_r(*this),
- m_port_handler_3_r(*this)
-{
-}
-
-void josvolly8741_4pack_device::device_start()
-{
- m_port_handler_0_r.resolve_safe(0);
- m_port_handler_1_r.resolve_safe(0);
- m_port_handler_2_r.resolve_safe(0);
- m_port_handler_3_r.resolve_safe(0);
-
- for (int i = 0; i < 4; i++)
- {
- save_item(NAME(m_i8741[i].cmd), i);
- save_item(NAME(m_i8741[i].sts), i);
- save_item(NAME(m_i8741[i].txd), i);
- //save_item(NAME(m_i8741[i].outport), i); //currently initialized to 0xff, never changed
- save_item(NAME(m_i8741[i].rxd), i);
- save_item(NAME(m_i8741[i].rst), i);
- };
-
- save_item(NAME(m_nmi_enable));
-}
-
-
-void josvolly8741_4pack_device::device_reset()
-{
- m_nmi_enable = 0;
-
- for(auto & elem : m_i8741)
- {
- elem.cmd = 0;
- elem.sts = 0; // 0xf0; /* init flag */
- elem.txd = 0;
- elem.outport = 0xff;
- elem.rxd = 0;
-
- elem.rst = 1;
- }
-}
-
-/* transmit data finish callback */
-TIMER_CALLBACK_MEMBER( josvolly8741_4pack_device::tx )
-{
- int num = param;
- JV8741 *src = &m_i8741[num];
- JV8741 *dst = &m_i8741[src->connect];
-
- dst->rxd = src->txd;
-
- src->sts &= ~0x02; /* TX full ? */
- dst->sts |= 0x01; /* RX ready ? */
-}
-
-void josvolly8741_4pack_device::update(int num)
-{
- if( (m_i8741[num].sts & 0x02) )
- {
- /* transmit data */
- machine().scheduler().timer_set (attotime::from_usec(1), timer_expired_delegate(FUNC(josvolly8741_4pack_device::tx),this), num);
- }
-}
-
-void josvolly8741_4pack_device::write(int num, int offset, int data)
-{
- JV8741 *mcu = &m_i8741[num];
-
- if(offset==1)
- {
- LOG(("%s:8741[%d] CW %02X\n", machine().describe_context(), num, data));
-
- /* read pointer */
- mcu->cmd = data;
- /* CMD */
- switch(data)
- {
- case 0:
- mcu->txd = data ^ 0x40;
- mcu->sts |= 0x02;
- break;
- case 1:
- mcu->txd = data ^ 0x40;
- mcu->sts |= 0x02;
-#if 1
- /* ?? */
- mcu->rxd = 0; /* SBSTS ( DIAG ) , killed */
- mcu->sts |= 0x01; /* RD ready */
-#endif
- break;
- case 2:
-#if 1
- mcu->rxd = port_read(1);
- mcu->sts |= 0x01; /* RD ready */
-#endif
- break;
- case 3: /* normal mode ? */
- break;
-
- case 0xf0: /* clear main sts ? */
- mcu->txd = data ^ 0x40;
- mcu->sts |= 0x02;
- break;
- }
- }
- else
- {
- /* data */
- LOG(("%s:8741[%d] DW %02X\n", machine().describe_context(), num, data));
-
- mcu->txd = data ^ 0x40; /* parity reverce ? */
- mcu->sts |= 0x02; /* TXD busy */
-#if 1
- /* interrupt ? */
- if(num == 0)
- {
- if(m_nmi_enable)
- {
- machine().device("audiocpu")->execute().set_input_line(INPUT_LINE_NMI, PULSE_LINE);
- m_nmi_enable = 0;
- }
- }
-#endif
- }
- update(num);
-}
-
-uint8_t josvolly8741_4pack_device::read(int num,int offset)
-{
- JV8741 *mcu = &m_i8741[num];
- int ret;
-
- if(offset==1)
- {
- if(mcu->rst)
- mcu->rxd = port_read(num); /* port in */
- ret = mcu->sts;
- LOG(("%s:8741[%d] SR %02X\n",machine().describe_context(),num,ret));
- }
- else
- {
- /* clear status port */
- mcu->sts &= ~0x01; /* RD ready */
- ret = mcu->rxd;
- LOG(("%s:8741[%d] DR %02X\n",machine().describe_context(),num,ret));
- mcu->rst = 0;
- }
- return ret;
-}
-
-uint8_t josvolly8741_4pack_device::port_read(int num)
-{
- switch(num)
- {
- case 0 : return m_port_handler_0_r(0);
- case 1 : return m_port_handler_1_r(0);
- case 2 : return m_port_handler_2_r(0);
- case 3 : return m_port_handler_3_r(0);
- default : return 0;
- }
-}
diff --git a/src/mame/machine/tait8741.h b/src/mame/machine/tait8741.h
index abf87272503..77e2c6338f7 100644
--- a/src/mame/machine/tait8741.h
+++ b/src/mame/machine/tait8741.h
@@ -109,81 +109,4 @@ private:
extern const device_type TAITO8741_4PACK;
-
-/****************************************************************************
- joshi Volleyball set.
-****************************************************************************/
-
-#define MCFG_JOSVOLLY8741_ADD(_tag) \
- MCFG_DEVICE_ADD(_tag, JOSVOLLY8741_4PACK, 0)
-
-#define MCFG_JOSVOLLY8741_PORT_HANDLERS(_devcb0, _devcb1, _devcb2, _devcb3) \
- devcb = &josvolly8741_4pack_device::set_port_handler_0_callback(*device, DEVCB_##_devcb0); \
- devcb = &josvolly8741_4pack_device::set_port_handler_1_callback(*device, DEVCB_##_devcb1); \
- devcb = &josvolly8741_4pack_device::set_port_handler_2_callback(*device, DEVCB_##_devcb2); \
- devcb = &josvolly8741_4pack_device::set_port_handler_3_callback(*device, DEVCB_##_devcb3);
-
-#define MCFG_JOSVOLLY8741_CONNECT(_con0, _con1, _con2, _con3) \
- josvolly8741_4pack_device::static_set_connect(*device, 0, _con0); \
- josvolly8741_4pack_device::static_set_connect(*device, 1, _con1); \
- josvolly8741_4pack_device::static_set_connect(*device, 2, _con2); \
- josvolly8741_4pack_device::static_set_connect(*device, 3, _con3);
-
-
-class josvolly8741_4pack_device : public device_t
-{
- struct JV8741 {
- uint8_t cmd;
- uint8_t sts;
- uint8_t txd;
- uint8_t outport;
- uint8_t rxd;
- uint8_t connect;
- uint8_t rst;
- };
-
-public:
- josvolly8741_4pack_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
- ~josvolly8741_4pack_device() {}
-
- template<class _Object> static devcb_base &set_port_handler_0_callback(device_t &device, _Object object) { return downcast<josvolly8741_4pack_device &>(device).m_port_handler_0_r.set_callback(object); }
- template<class _Object> static devcb_base &set_port_handler_1_callback(device_t &device, _Object object) { return downcast<josvolly8741_4pack_device &>(device).m_port_handler_1_r.set_callback(object); }
- template<class _Object> static devcb_base &set_port_handler_2_callback(device_t &device, _Object object) { return downcast<josvolly8741_4pack_device &>(device).m_port_handler_2_r.set_callback(object); }
- template<class _Object> static devcb_base &set_port_handler_3_callback(device_t &device, _Object object) { return downcast<josvolly8741_4pack_device &>(device).m_port_handler_3_r.set_callback(object); }
-
- static void static_set_connect(device_t &device, int num, int conn) { downcast<josvolly8741_4pack_device &>(device).m_i8741[num].connect = conn; }
-
- DECLARE_READ8_MEMBER( read_0 ) { return read(0,offset); }
- DECLARE_WRITE8_MEMBER( write_0 ) { write(0,offset,data); }
- DECLARE_READ8_MEMBER( read_1 ) { return read(1,offset); }
- DECLARE_WRITE8_MEMBER( write_1 ) { write(1,offset,data); }
-
- DECLARE_WRITE8_MEMBER( nmi_enable_w ) { m_nmi_enable = 1; }
-
- TIMER_CALLBACK_MEMBER( tx );
-protected:
- // device-level overrides
- virtual void device_start() override;
- virtual void device_reset() override;
-
-private:
- void update(int num);
- void write(int num, int offset, int data);
- uint8_t read(int num,int offset);
- uint8_t port_read(int num);
-
- // internal state
- JV8741 m_i8741[4];
- int m_nmi_enable;
-
- devcb_read8 m_port_handler_0_r;
- devcb_read8 m_port_handler_1_r;
- devcb_read8 m_port_handler_2_r;
- devcb_read8 m_port_handler_3_r;
-};
-
-
-extern const device_type JOSVOLLY8741_4PACK;
-
-
#endif
diff --git a/src/mame/machine/taito68705interface.cpp b/src/mame/machine/taito68705interface.cpp
new file mode 100644
index 00000000000..3e2f5701bb8
--- /dev/null
+++ b/src/mame/machine/taito68705interface.cpp
@@ -0,0 +1,354 @@
+// license:BSD-3-Clause
+// copyright-holders:Ernesto Corvi, Nicola Salmoria, David Haywood
+#include "emu.h"
+#include "cpu/z80/z80.h"
+#include "machine/taito68705interface.h"
+
+/*
+ Most Taito 68705s share a similar (often identical) hookup.
+ This file encapsulates that.
+
+ used by:
+ buggychl.cpp - buggychl
+ bking.cpp - bking3
+ 40love.cpp - 40love
+ bublbobl.cpp - tokio
+ flstory.cpp - flstory
+ nycaptor.cpp - nycaptor
+ lsasquad.cpp - lsasquad
+ - daikaiju
+ lkage.cpp - lkage
+
+ and the following with slight changes:
+ slapfght.cpp - tigerh (inverted status bits read on portC)
+ - slapfght (extended outputs for scrolling)
+ bigevglf.cpp - writes to mcu aren't latched(?)f
+
+
+ not hooked up here, but possible (needs investigating)
+ pitnrun.cpp - have more functionality on portB, currently using 'instant timers' for latches
+ taitosj.cpp - ^^
+ changela.cpp - ^^
+ arkanoid.cpp - uses 68705 timers (they need to be moved to the 68705 core) and also some portB differences?
+ xain.cpp - not a Taito game (licensed to Taito?) but MCU hookup looks almost the same
+ renegade.cpp - ^^
+ matmania.cpp - ^^
+
+ 68705 sets in Taito drivers that are NOT suitable for hookup here?
+ bublbobl.cpp - bub68705 - this is a bootleg, not an official Taito hookup
+ mexico86.cpp - knightb, mexico86 - bootleg 68705s
+ retofinv.cpp - the current MCU dump is a bootleg at least
+ sqix.cpp - hotsmash - kaneko hookup, different from Taito ones.
+
+ there are other drivers (and games in existing drivers) that could hookup here, but currently lack MCU dumps.
+
+*/
+
+const device_type TAITO68705_MCU = &device_creator<taito68705_mcu_device>;
+const device_type TAITO68705_MCU_SLAP = &device_creator<taito68705_mcu_slap_device>;
+const device_type TAITO68705_MCU_TIGER = &device_creator<taito68705_mcu_tiger_device>;
+const device_type TAITO68705_MCU_BEG = &device_creator<taito68705_mcu_beg_device>;
+
+taito68705_mcu_device::taito68705_mcu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : device_t(mconfig, TAITO68705_MCU, "Taito M68705 MCU Interface", tag, owner, clock, "taito68705", __FILE__),
+ m_mcu_sent(false),
+ m_main_sent(false),
+ m_from_main(0),
+ m_from_mcu(0),
+ m_from_mcu_latch(0),
+ m_to_mcu_latch(0),
+ m_old_portB(0),
+ m_mcu(*this, "mcu")
+{
+}
+
+taito68705_mcu_device::taito68705_mcu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, u32 clock, const char *shortname, const char *source)
+ : device_t(mconfig, type, name, tag, owner, clock, shortname, source),
+ m_mcu_sent(false),
+ m_main_sent(false),
+ m_from_main(0),
+ m_from_mcu(0),
+ m_from_mcu_latch(0),
+ m_to_mcu_latch(0),
+ m_old_portB(0),
+ m_mcu(*this, "mcu")
+{
+}
+
+
+
+
+static MACHINE_CONFIG_FRAGMENT( taito68705 )
+ MCFG_CPU_ADD("mcu", M68705_NEW, DERIVED_CLOCK(1,1))
+ MCFG_M68705_PORTA_R_CB(READ8(taito68705_mcu_device, mcu_porta_r))
+ MCFG_M68705_PORTA_W_CB(WRITE8(taito68705_mcu_device, mcu_porta_w))
+ MCFG_M68705_PORTB_W_CB(WRITE8(taito68705_mcu_device, mcu_portb_w))
+ MCFG_M68705_PORTC_R_CB(READ8(taito68705_mcu_device, mcu_portc_r))
+MACHINE_CONFIG_END
+
+machine_config_constructor taito68705_mcu_device::device_mconfig_additions() const
+{
+ return MACHINE_CONFIG_NAME( taito68705 );
+}
+
+
+//-------------------------------------------------
+// device_config_complete - perform any
+// operations now that the configuration is
+// complete
+//-------------------------------------------------
+
+void taito68705_mcu_device::device_config_complete()
+{
+}
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void taito68705_mcu_device::device_start()
+{
+ save_item(NAME(m_mcu_sent));
+ save_item(NAME(m_main_sent));
+ save_item(NAME(m_from_main));
+ save_item(NAME(m_from_mcu));
+ save_item(NAME(m_from_mcu_latch));
+ save_item(NAME(m_to_mcu_latch));
+ save_item(NAME(m_old_portB));
+}
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void taito68705_mcu_device::device_reset()
+{
+ m_mcu_sent = false;
+ m_main_sent = false;
+ m_from_main = 0;
+ m_from_mcu = 0;
+ m_from_mcu_latch = 0;
+ m_to_mcu_latch = 0;
+ m_old_portB = 0;
+
+ m_mcu->set_input_line(0, CLEAR_LINE);
+}
+
+
+/***************************************************************************
+
+ Buggy Challenge 68705 protection interface
+
+ This is accurate. FairyLand Story seems to be identical.
+
+***************************************************************************/
+
+
+/*
+ * Port B connections:
+ * parts in [ ] are optional (not used by buggychl)
+ *
+ * all bits are logical 1 when read (+5V pullup)
+ *
+ * 0 n.c.
+ * 1 W IRQ ack and enable latch which holds data from main Z80 memory
+ * 2 W loads latch to Z80
+ * 3 W to Z80 BUSRQ (put it on hold?)
+ * 4 W n.c.
+ * 5 W [selects Z80 memory access direction (0 = write 1 = read)]
+ * 6 W [loads the latch which holds the low 8 bits of the address of
+ * the main Z80 memory location to access]
+ * 7 W [loads the latch which holds the high 8 bits of the address of
+ * the main Z80 memory location to access]
+ */
+
+
+
+
+
+READ8_MEMBER(taito68705_mcu_device::mcu_r)
+{
+ m_mcu_sent = false;
+
+// logerror("%s: mcu_r %02x\n", space.machine().describe_context(), m_from_mcu);
+
+ return m_from_mcu;
+}
+
+WRITE8_MEMBER(taito68705_mcu_device::mcu_w)
+{
+// logerror("%s: mcu_w %02x\n", space.machine().describe_context(), data);
+
+ m_from_main = data;
+ m_main_sent = true;
+ m_mcu->set_input_line(0, ASSERT_LINE);
+
+}
+
+
+READ8_MEMBER(taito68705_mcu_device::mcu_porta_r)
+{
+// logerror("mcu_porta_r\n");
+ return m_to_mcu_latch;
+}
+
+WRITE8_MEMBER(taito68705_mcu_device::mcu_porta_w)
+{
+// logerror("mcu_porta_w %02x\n", data);
+ m_from_mcu_latch = data;
+}
+
+
+READ8_MEMBER(taito68705_mcu_device::mcu_portc_r)
+{
+ uint8_t ret = 0;
+
+ if (m_main_sent)
+ ret |= 0x01;
+ if (!m_mcu_sent)
+ ret |= 0x02;
+
+// logerror("%s: mcu_portc_r %02x\n", space.machine().describe_context(), ret);
+
+ return ret;
+}
+
+
+WRITE8_MEMBER(taito68705_mcu_device::mcu_portb_w)
+{
+// logerror("mcu_portb_w %02x\n", data);
+
+ if ((mem_mask & 0x02) && (~data & 0x02) && (m_old_portB & 0x02))
+ {
+ if (m_main_sent)
+ m_mcu->set_input_line(0, CLEAR_LINE);
+
+ m_to_mcu_latch = m_from_main;
+ m_main_sent = false;
+ }
+ if ((mem_mask & 0x04) && (data & 0x04) && (~m_old_portB & 0x04))
+ {
+ m_from_mcu = m_from_mcu_latch;
+ m_mcu_sent = true;
+ // logerror("sent %02x\n", m_from_mcu);
+ }
+
+ m_old_portB = data;
+
+}
+
+/* Status readbacks for MAIN cpu - these hook up in various ways depending on the host (provide 2 lines instead?) */
+
+READ8_MEMBER( taito68705_mcu_device::mcu_status_r )
+{
+ int res = 0;
+
+ /* bit 0 = when 1, mcu is ready to receive data from main cpu */
+ /* bit 1 = when 1, mcu has sent data to the main cpu */
+ //logerror("%s: mcu_status_r\n",machine().describe_context());
+ if (!m_main_sent)
+ res |= 0x01;
+ if (m_mcu_sent)
+ res |= 0x02;
+
+ return res;
+}
+
+CUSTOM_INPUT_MEMBER(taito68705_mcu_device::mcu_sent_r)
+{
+ if (!m_mcu_sent) return 0;
+ else return 1;
+}
+
+CUSTOM_INPUT_MEMBER(taito68705_mcu_device::main_sent_r)
+{
+ if (!m_main_sent) return 0;
+ else return 1;
+}
+
+/* The Slap Fight interface has some extensions, handle them here */
+
+taito68705_mcu_slap_device::taito68705_mcu_slap_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : taito68705_mcu_device(mconfig, TAITO68705_MCU_SLAP, "Taito M68705 MCU Interface (Slap Fight)", tag, owner, clock, "taito68705slap", __FILE__),
+ m_extension_cb_w(*this)
+{
+}
+
+WRITE8_MEMBER(taito68705_mcu_slap_device::mcu_portb_w)
+{
+ if ((mem_mask & 0x08) && (~data & 0x08) && (m_old_portB & 0x08))
+ {
+ m_extension_cb_w(0,m_from_mcu_latch, 0xff); // m_scrollx_lo
+ }
+ if ((mem_mask & 0x10) && (~data & 0x10) && (m_old_portB & 0x10))
+ {
+ m_extension_cb_w(1,m_from_mcu_latch, 0xff); // m_scrollx_hi
+ }
+
+ taito68705_mcu_device::mcu_portb_w(space,offset,data);
+}
+
+void taito68705_mcu_slap_device::device_start()
+{
+ taito68705_mcu_device::device_start();
+ m_extension_cb_w.resolve_safe();
+}
+
+
+/* The Tiger Heli interface has some extensions, handle them here */
+
+taito68705_mcu_tiger_device::taito68705_mcu_tiger_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : taito68705_mcu_device(mconfig, TAITO68705_MCU_TIGER, "Taito M68705 MCU Interface (Tiger Heli)", tag, owner, clock, "taito68705tiger", __FILE__)
+{
+}
+
+READ8_MEMBER(taito68705_mcu_tiger_device::mcu_portc_r)
+{
+ uint8_t ret = taito68705_mcu_device::mcu_portc_r(space,offset);
+
+ // Tiger Heli has these status bits inverted MCU-side
+ ret ^= 0x3;
+
+ return ret;
+}
+
+
+/* Big Event Golf has some things switched around, handle them here */
+
+taito68705_mcu_beg_device::taito68705_mcu_beg_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : taito68705_mcu_device(mconfig, TAITO68705_MCU_BEG, "Taito M68705 MCU Interface (Big Event Golf)", tag, owner, clock, "taito68705bigevglf", __FILE__)
+{
+}
+
+WRITE8_MEMBER(taito68705_mcu_beg_device::mcu_portb_w)
+{
+ // transitions are reversed
+ if ((mem_mask & 0x02) && (data & 0x02) && (~m_old_portB & 0x02) ) /* positive going transition of the clock */
+ {
+ //if (m_main_sent)
+ m_mcu->set_input_line(0, CLEAR_LINE);
+
+ //m_to_mcu_latch = m_from_main; // this is weird, no latching?!
+ m_main_sent = false;
+ }
+ if ((mem_mask & 0x04) && (data & 0x04) && (~m_old_portB & 0x04) ) /* positive going transition of the clock */
+ {
+ m_from_mcu = m_from_mcu_latch;
+ m_mcu_sent = true;
+ // logerror("sent %02x\n", m_from_mcu);
+ }
+
+ m_old_portB = data;
+}
+
+WRITE8_MEMBER(taito68705_mcu_beg_device::mcu_w)
+{
+// logerror("%s: mcu_w %02x\n", space.machine().describe_context(), data);
+
+ m_to_mcu_latch = data; // this is weird, no latching?!
+ m_main_sent = true;
+ m_mcu->set_input_line(0, ASSERT_LINE);
+
+}
+
+
diff --git a/src/mame/machine/taito68705interface.h b/src/mame/machine/taito68705interface.h
new file mode 100644
index 00000000000..c0ad508ef69
--- /dev/null
+++ b/src/mame/machine/taito68705interface.h
@@ -0,0 +1,86 @@
+// license:BSD-3-Clause
+// copyright-holders:Ernesto Corvi, Nicola Salmoria, David Haywood
+
+#include "cpu/m6805/m6805.h"
+
+class taito68705_mcu_device : public device_t
+{
+public:
+ taito68705_mcu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ taito68705_mcu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, u32 clock, const char *shortname, const char *source);
+
+ ~taito68705_mcu_device() {}
+
+ virtual DECLARE_WRITE8_MEMBER( mcu_w );
+ DECLARE_READ8_MEMBER( mcu_r );
+ DECLARE_READ8_MEMBER( mcu_porta_r );
+ virtual DECLARE_READ8_MEMBER( mcu_portc_r );
+ DECLARE_WRITE8_MEMBER( mcu_porta_w );
+ virtual DECLARE_WRITE8_MEMBER( mcu_portb_w );
+
+ DECLARE_READ8_MEMBER( mcu_status_r );
+ DECLARE_CUSTOM_INPUT_MEMBER( mcu_sent_r );
+ DECLARE_CUSTOM_INPUT_MEMBER( main_sent_r );
+
+ bool get_main_sent() { return m_main_sent; };
+ bool get_mcu_sent() { return m_mcu_sent; };
+
+
+protected:
+ // device-level overrides
+ virtual machine_config_constructor device_mconfig_additions() const override;
+ virtual void device_config_complete() override;
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+ // internal state
+ bool m_mcu_sent;
+ bool m_main_sent;
+ uint8_t m_from_main;
+ uint8_t m_from_mcu;
+ uint8_t m_from_mcu_latch;
+ uint8_t m_to_mcu_latch;
+ uint8_t m_old_portB;
+
+ required_device<cpu_device> m_mcu;
+};
+
+extern const device_type TAITO68705_MCU;
+
+#define MCFG_TAITO_M68705_EXTENSION_CB(_devcb) \
+ taito68705_mcu_slap_device::set_extension_cb(*device, DEVCB_##_devcb);
+
+class taito68705_mcu_slap_device : public taito68705_mcu_device
+{
+public:
+ taito68705_mcu_slap_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ virtual DECLARE_WRITE8_MEMBER( mcu_portb_w ) override;
+
+ template<class _Object> static devcb_base &set_extension_cb(device_t &device, _Object object) { return downcast<taito68705_mcu_slap_device &>(device).m_extension_cb_w.set_callback(object); }
+
+ devcb_write8 m_extension_cb_w;
+
+protected:
+ virtual void device_start() override;
+};
+
+extern const device_type TAITO68705_MCU_SLAP;
+
+class taito68705_mcu_tiger_device : public taito68705_mcu_device
+{
+public:
+ taito68705_mcu_tiger_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ virtual DECLARE_READ8_MEMBER( mcu_portc_r ) override;
+};
+
+extern const device_type TAITO68705_MCU_TIGER;
+
+class taito68705_mcu_beg_device : public taito68705_mcu_device
+{
+public:
+ taito68705_mcu_beg_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ virtual DECLARE_WRITE8_MEMBER(mcu_w) override;
+ virtual DECLARE_WRITE8_MEMBER(mcu_portb_w) override;
+};
+
+extern const device_type TAITO68705_MCU_BEG;
diff --git a/src/mame/machine/xbox.cpp b/src/mame/machine/xbox.cpp
index 4405046c13a..753a1406c77 100644
--- a/src/mame/machine/xbox.cpp
+++ b/src/mame/machine/xbox.cpp
@@ -344,18 +344,28 @@ void xbox_base_state::generate_irq_command(int ref, int params, const char **par
void xbox_base_state::nv2a_combiners_command(int ref, int params, const char **param)
{
debugger_console &con = machine().debugger().console();
- int en = nvidia_nv2a->toggle_register_combiners_usage();
- if (en != 0)
+ bool en = nvidia_nv2a->toggle_register_combiners_usage();
+ if (en == true)
con.printf("Register combiners enabled\n");
else
con.printf("Register combiners disabled\n");
}
+void xbox_base_state::nv2a_wclipping_command(int ref, int params, const char **param)
+{
+ debugger_console &con = machine().debugger().console();
+ bool en = nvidia_nv2a->toggle_clipping_w_support();
+ if (en == true)
+ con.printf("W clipping enabled\n");
+ else
+ con.printf("W clipping disabled\n");
+}
+
void xbox_base_state::waitvblank_command(int ref, int params, const char **param)
{
debugger_console &con = machine().debugger().console();
- int en = nvidia_nv2a->toggle_wait_vblank_support();
- if (en != 0)
+ bool en = nvidia_nv2a->toggle_wait_vblank_support();
+ if (en == true)
con.printf("Vblank method enabled\n");
else
con.printf("Vblank method disabled\n");
@@ -458,6 +468,7 @@ void xbox_base_state::help_command(int ref, int params, const char **param)
con.printf(" xbox threadlist -- list of currently active threads\n");
con.printf(" xbox irq,<number> -- Generate interrupt with irq number 0-15\n");
con.printf(" xbox nv2a_combiners -- Toggle use of register combiners\n");
+ con.printf(" xbox nv2a_wclipping -- Toggle use of negative w vertex clipping\n");
con.printf(" xbox waitvblank -- Toggle support for wait vblank method\n");
con.printf(" xbox grab_texture,<type>,<filename> -- Save to <filename> the next used texture of type <type>\n");
con.printf(" xbox grab_vprog,<filename> -- save current vertex program instruction slots to <filename>\n");
@@ -487,6 +498,8 @@ void xbox_base_state::xbox_debug_commands(int ref, int params, const char **para
generate_irq_command(ref, params - 1, param + 1);
else if (strcmp("nv2a_combiners", param[0]) == 0)
nv2a_combiners_command(ref, params - 1, param + 1);
+ else if (strcmp("nv2a_wclipping", param[0]) == 0)
+ nv2a_wclipping_command(ref, params - 1, param + 1);
else if (strcmp("waitvblank", param[0]) == 0)
waitvblank_command(ref, params - 1, param + 1);
else if (strcmp("grab_texture", param[0]) == 0)
diff --git a/src/mame/mame.lst b/src/mame/mame.lst
index 13670f1e5f0..3b07e490b23 100644
--- a/src/mame/mame.lst
+++ b/src/mame/mame.lst
@@ -12229,15 +12229,6 @@ fccpu30senr
fccpu30senr501
fccpu33
-//@source:fccpu40.cpp
-//fccpu40 //
-
-@source:fcscsi.cpp
-fcscsi1 //
-
-@source:fcisio.cpp
-fcisio1 //
-
@source:fcombat.cpp
fcombat // (c) 1985 Jaleco
@@ -14106,6 +14097,9 @@ howzat //
orbit1 //
shark //
+@source:hapyfish.cpp
+hapyfsh2 // bootleg
+
@source:harddriv.cpp
harddriv // 136052 (c) 1988
harddriv1 // 136052 (c) 1988
@@ -14268,12 +14262,13 @@ bcheetah // Bandai
bigtrak // Milton Bradley
bship // Milton Bradley
bshipb // Milton Bradley
-copycat // Tiger Electronics
-copycatm2 // Tiger Electronics
+cmsport // Conic
cnfball // Conic
cnfball2 // Conic
cnsector // Parker Bros
comp4 // Milton Bradley
+copycat // Tiger Electronics
+copycatm2 // Tiger Electronics
cqback // Coleco
ditto // Tiger Electronics
ebaskb2 // Entex
@@ -27687,9 +27682,6 @@ mustachei // (c) 1987 IG SPA
@source:mvme147.cpp
mvme147 // (c) 1989 Motorola
-@source:mvme350.cpp
-mvme350 //
-
@source:mw18w.cpp
18w // 653 (c) 1979 Midway
18w2 // 653 (c) 1979 Midway
@@ -28880,6 +28872,7 @@ rbffspeck // 0124 (c) 1996 SNK
ridhero // 0006 (c) 1990 SNK
ridheroh // 0006 (c) 1990 SNK
roboarmy // 0032 (c) 1991 SNK
+roboarma // 0032 (c) 1991 SNK
rotd // 0264 (c) 2002 Evoga
rotdh // 0264 (c) 2002 Evoga
s1945p // 0254 (c) 1999 Psikyo
@@ -28889,6 +28882,7 @@ samsh5spho // 0272 (c) 2004 Playmore
samsho // 0045 (c) 1993 SNK
samsho2 // 0063 (c) 1994 SNK
samsho2k // 0063 (c) 1994 SNK (Korean hack)
+samsho2ka // 0063 (c) 1994 SNK (Korean hack)
samsho3 // 0087 (c) 1995 SNK
samsho3h // 0087 (c) 1995 SNK
samsho4 // 0222 (c) 1996 SNK
@@ -29595,7 +29589,8 @@ pbaction4 // (c) 1985 Tehkan
pbaction5 // (c) 1985 Tehkan
@source:pc.cpp
-ataripc3 //
+ataripc1 // Atari PC1
+ataripc3 // Atari PC3
bw230 // 1985 Bondwell (CGA)
compc1 // 1984 Commodore PC-1
dgone // 1984 Data General/One
@@ -30387,6 +30382,7 @@ pet8032 //
superpet //
@source:peyper.cpp
+ator //
gamatros //
hangonp //
lancelot //
@@ -31699,6 +31695,9 @@ rltennis // (c) 1993 TCH
@source:rm380z.cpp
rm380z //
+rm380z34d //
+rm380z34e //
+rm480z //
@source:rmhaihai.cpp
rmhaihai // (c) 1985 Alba
@@ -31738,6 +31737,7 @@ schmeisr // (c) 1993 Hot B
wizdfire // MAS (c) 1992 Data East Corporation (Over Sea)
wizdfireu // MAS (c) 1992 Data East Corporation (US)
wolffang // MAM (c) 1991 Data East Corporation (Japan)
+hangzo
@source:rollerg.cpp
rollerg // GX999 (c) 1991 (US)
diff --git a/src/mame/mess.flt b/src/mame/mess.flt
index e701eea7b43..f939b7aa86b 100644
--- a/src/mame/mess.flt
+++ b/src/mame/mess.flt
@@ -187,9 +187,8 @@ fanucs15.cpp
fanucspmg.cpp
fb01.cpp
fc100.cpp
+fccpu20.cpp
fccpu30.cpp
-fcisio.cpp
-fcscsi.cpp
fidel6502.cpp
fidel68k.cpp
fidelz80.cpp
@@ -372,7 +371,6 @@ mtx.cpp
multi16.cpp
multi8.cpp
mvme147.cpp
-mvme350.cpp
mx2178.cpp
myb3k.cpp
mycom.cpp
diff --git a/src/mame/video/aerofgt.cpp b/src/mame/video/aerofgt.cpp
index 2495eb13481..20da54b7f9b 100644
--- a/src/mame/video/aerofgt.cpp
+++ b/src/mame/video/aerofgt.cpp
@@ -194,32 +194,22 @@ void aerofgt_state::setbank( tilemap_t *tmap, int num, int bank )
}
}
-WRITE16_MEMBER(aerofgt_state::pspikes_gfxbank_w)
+WRITE8_MEMBER(aerofgt_state::pspikes_gfxbank_w)
{
- if (ACCESSING_BITS_0_7)
- {
- setbank(m_bg1_tilemap, 0, (data & 0xf0) >> 4);
- setbank(m_bg1_tilemap, 1, data & 0x0f);
- }
+ setbank(m_bg1_tilemap, 0, (data & 0xf0) >> 4);
+ setbank(m_bg1_tilemap, 1, data & 0x0f);
}
-
-WRITE16_MEMBER(aerofgt_state::karatblz_gfxbank_w)
+WRITE8_MEMBER(aerofgt_state::karatblz_gfxbank_w)
{
- if (ACCESSING_BITS_8_15)
- {
- setbank(m_bg1_tilemap, 0, (data & 0x0100) >> 8);
- setbank(m_bg2_tilemap, 1, (data & 0x0800) >> 11);
- }
+ setbank(m_bg1_tilemap, 0, (data & 0x01));
+ setbank(m_bg2_tilemap, 1, (data & 0x08) >> 3);
}
-WRITE16_MEMBER(aerofgt_state::spinlbrk_gfxbank_w)
+WRITE8_MEMBER(aerofgt_state::spinlbrk_gfxbank_w)
{
- if (ACCESSING_BITS_0_7)
- {
- setbank(m_bg1_tilemap, 0, (data & 0x07));
- setbank(m_bg2_tilemap, 1, (data & 0x38) >> 3);
- }
+ setbank(m_bg1_tilemap, 0, (data & 0x07));
+ setbank(m_bg2_tilemap, 1, (data & 0x38) >> 3);
}
WRITE16_MEMBER(aerofgt_state::turbofrc_gfxbank_w)
@@ -264,16 +254,13 @@ WRITE16_MEMBER(aerofgt_state::aerofgt_bg2scrolly_w)
COMBINE_DATA(&m_bg2scrolly);
}
-WRITE16_MEMBER(aerofgt_state::pspikes_palette_bank_w)
+WRITE8_MEMBER(aerofgt_state::pspikes_palette_bank_w)
{
- if (ACCESSING_BITS_0_7)
+ m_spritepalettebank = data & 0x03;
+ if (m_charpalettebank != (data & 0x1c) >> 2)
{
- m_spritepalettebank = data & 0x03;
- if (m_charpalettebank != (data & 0x1c) >> 2)
- {
- m_charpalettebank = (data & 0x1c) >> 2;
- m_bg1_tilemap->mark_all_dirty();
- }
+ m_charpalettebank = (data & 0x1c) >> 2;
+ m_bg1_tilemap->mark_all_dirty();
}
}
diff --git a/src/mame/video/battlex.cpp b/src/mame/video/battlex.cpp
index ee3bf4d8ff9..1df5f45383f 100644
--- a/src/mame/video/battlex.cpp
+++ b/src/mame/video/battlex.cpp
@@ -95,7 +95,7 @@ uint32_t battlex_state::screen_update_battlex(screen_device &screen, bitmap_ind1
if (!flip_screen())
m_bg_tilemap->set_scrollx(0, m_scroll_lsb | (m_scroll_msb << 8));
else
- m_bg_tilemap->set_scrollx(0, m_scroll_lsb | m_scroll_msb);
+ m_bg_tilemap->set_scrollx(0, m_scroll_lsb | (m_scroll_msb << 3));
m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
draw_sprites(bitmap, cliprect);
diff --git a/src/mame/video/gsword.cpp b/src/mame/video/gsword.cpp
index cd31addb506..46e851c5f4b 100644
--- a/src/mame/video/gsword.cpp
+++ b/src/mame/video/gsword.cpp
@@ -11,91 +11,13 @@
#include "includes/gsword.h"
-PALETTE_INIT_MEMBER(gsword_state,josvolly)
-{
- const uint8_t *color_prom = memregion("proms")->base();
- int i;
-
- /* create a lookup table for the palette */
- for (i = 0; i < 0x100; i++)
- {
- int r = pal4bit(color_prom[i + 0x000]);
- int g = pal4bit(color_prom[i + 0x100]);
- int b = pal4bit(color_prom[i + 0x200]);
-
- palette.set_indirect_color(i, rgb_t(r, g, b));
- }
-
- /* color_prom now points to the beginning of the lookup table */
- color_prom += 0x300;
-
- /* characters */
- for (i = 0; i < 0x100; i++)
- palette.set_pen_indirect(i, i);
-
- /* sprites */
- for (i = 0x100; i < 0x200; i++)
- {
- uint8_t ctabentry = (BITSWAP8(color_prom[i - 0x100],7,6,5,4,0,1,2,3) & 0x0f) | 0x80;
- palette.set_pen_indirect(i, ctabentry);
- }
-}
-
-
-PALETTE_INIT_MEMBER(gsword_state,gsword)
-{
- const uint8_t *color_prom = memregion("proms")->base();
- int i;
-
- /* create a lookup table for the palette */
- for (i = 0; i < 0x100; i++)
- {
- int bit0, bit1, bit2;
- int r, g, b;
-
- /* red component */
- bit0 = (color_prom[i + 0x100] >> 0) & 1;
- bit1 = (color_prom[i + 0x100] >> 1) & 1;
- bit2 = (color_prom[i + 0x100] >> 2) & 1;
- r = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
-
- /* green component */
- bit0 = (color_prom[i + 0x100] >> 3) & 1;
- bit1 = (color_prom[i + 0x000] >> 0) & 1;
- bit2 = (color_prom[i + 0x000] >> 1) & 1;
- g = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
-
- /* blue component */
- bit0 = 0;
- bit1 = (color_prom[i + 0x000] >> 2) & 1;
- bit2 = (color_prom[i + 0x000] >> 3) & 1;
- b = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
-
- palette.set_indirect_color(i, rgb_t(r, g, b));
- }
-
- /* color_prom now points to the beginning of the lookup table */
- color_prom += 0x200;
-
- /* characters */
- for (i = 0; i < 0x100; i++)
- palette.set_pen_indirect(i, i);
-
- /* sprites */
- for (i = 0x100; i < 0x200; i++)
- {
- uint8_t ctabentry = (BITSWAP8(color_prom[i - 0x100],7,6,5,4,0,1,2,3) & 0x0f) | 0x80;
- palette.set_pen_indirect(i, ctabentry);
- }
-}
-
-WRITE8_MEMBER(gsword_state::videoram_w)
+WRITE8_MEMBER(gsword_state_base::videoram_w)
{
m_videoram[offset] = data;
m_bg_tilemap->mark_tile_dirty(offset);
}
-WRITE8_MEMBER(gsword_state::charbank_w)
+WRITE8_MEMBER(gsword_state_base::charbank_w)
{
if (m_charbank != data)
{
@@ -104,7 +26,7 @@ WRITE8_MEMBER(gsword_state::charbank_w)
}
}
-WRITE8_MEMBER(gsword_state::videoctrl_w)
+WRITE8_MEMBER(gsword_state_base::videoctrl_w)
{
if (data & 0x8f)
{
@@ -132,12 +54,12 @@ WRITE8_MEMBER(gsword_state::videoctrl_w)
/* other bits unused */
}
-WRITE8_MEMBER(gsword_state::scroll_w)
+WRITE8_MEMBER(gsword_state_base::scroll_w)
{
m_bg_tilemap->set_scrolly(0, data);
}
-TILE_GET_INFO_MEMBER(gsword_state::get_bg_tile_info)
+TILE_GET_INFO_MEMBER(gsword_state_base::get_bg_tile_info)
{
int code = m_videoram[tile_index] + ((m_charbank & 0x03) << 8);
int color = ((code & 0x3c0) >> 6) + 16 * m_charpalbank;
@@ -146,9 +68,9 @@ TILE_GET_INFO_MEMBER(gsword_state::get_bg_tile_info)
SET_TILE_INFO_MEMBER(0, code, color, flags);
}
-void gsword_state::video_start()
+void gsword_state_base::video_start()
{
- m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(gsword_state::get_bg_tile_info),this), TILEMAP_SCAN_ROWS,
+ m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(gsword_state_base::get_bg_tile_info),this), TILEMAP_SCAN_ROWS,
8, 8, 32, 64);
save_item(NAME(m_charbank));
@@ -156,7 +78,7 @@ void gsword_state::video_start()
save_item(NAME(m_flipscreen));
}
-void gsword_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect)
+void gsword_state_base::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect)
{
for (int offs = 0; offs < m_spritexy_ram.bytes() - 1; offs+=2)
{
@@ -197,9 +119,80 @@ void gsword_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect)
}
}
-uint32_t gsword_state::screen_update_gsword(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
+uint32_t gsword_state_base::screen_update_gsword(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
draw_sprites(bitmap, cliprect);
return 0;
}
+
+
+PALETTE_INIT_MEMBER(gsword_state, gsword)
+{
+ const uint8_t *color_prom = memregion("proms")->base();
+
+ /* create a lookup table for the palette */
+ for (unsigned i = 0; i < 0x100; i++)
+ {
+ int bit0, bit1, bit2;
+ int r, g, b;
+
+ /* red component */
+ bit0 = BIT(color_prom[i + 0x100], 0);
+ bit1 = BIT(color_prom[i + 0x100], 1);
+ bit2 = BIT(color_prom[i + 0x100], 2);
+ r = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
+
+ /* green component */
+ bit0 = BIT(color_prom[i + 0x100], 3);
+ bit1 = BIT(color_prom[i + 0x000], 0);
+ bit2 = BIT(color_prom[i + 0x000], 1);
+ g = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
+
+ /* blue component */
+ bit0 = 0;
+ bit1 = BIT(color_prom[i + 0x000], 2);
+ bit2 = BIT(color_prom[i + 0x000], 3);
+ b = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
+
+ palette.set_indirect_color(i, rgb_t(r, g, b));
+ }
+
+ /* color_prom now points to the beginning of the lookup table */
+ color_prom += 0x200;
+
+ /* characters */
+ for (unsigned i = 0; i < 0x100; i++)
+ palette.set_pen_indirect(i, i);
+
+ /* sprites */
+ for (unsigned i = 0x100; i < 0x200; i++)
+ {
+ uint8_t ctabentry = (BITSWAP8(color_prom[i - 0x100],7,6,5,4,0,1,2,3) & 0x0f) | 0x80;
+ palette.set_pen_indirect(i, ctabentry);
+ }
+}
+
+
+
+PALETTE_INIT_MEMBER(josvolly_state, josvolly)
+{
+ u8 const *const color_prom = memregion("proms")->base();
+
+ // create a lookup table for the palette
+ for (unsigned i = 0; i < 0x100; i++)
+ {
+ u8 const r = pal4bit(color_prom[i + 0x000]);
+ u8 const g = pal4bit(color_prom[i + 0x100]);
+ u8 const b = pal4bit(color_prom[i + 0x200]);
+
+ palette.set_indirect_color(i, rgb_t(r, g, b));
+
+ // characters
+ palette.set_pen_indirect(i, i);
+
+ // sprites
+ u8 const ctabentry = bitswap(color_prom[i + 0x300], 0, 1, 2, 3) | 0x80;
+ palette.set_pen_indirect(i + 0x100, ctabentry);
+ }
+}
diff --git a/src/mame/video/c116.cpp b/src/mame/video/namco_c116.cpp
index 19d76184c11..b2c74a459d5 100644
--- a/src/mame/video/c116.cpp
+++ b/src/mame/video/namco_c116.cpp
@@ -66,8 +66,9 @@ i960 CPU, needs to write its clip and raster values byteswapped.
*/
#include "emu.h"
-#include "video/c116.h"
+#include "video/namco_c116.h"
+const device_type NAMCO_C116 = &device_creator<namco_c116_device>;
//-------------------------------------------------
// namco_c116_device -- constructor
@@ -158,6 +159,3 @@ WRITE8_MEMBER(namco_c116_device::write)
RAM[color] = data;
palette().set_pen_color(color,m_ram_r[color],m_ram_g[color],m_ram_b[color]);
}
-
-
-const device_type NAMCO_C116 = &device_creator<namco_c116_device>;
diff --git a/src/mame/video/c116.h b/src/mame/video/namco_c116.h
index 48d5c46f932..48d5c46f932 100644
--- a/src/mame/video/c116.h
+++ b/src/mame/video/namco_c116.h
diff --git a/src/mame/video/namcos2.cpp b/src/mame/video/namcos2.cpp
index 5a9ce2bd32e..ea036dd33d8 100644
--- a/src/mame/video/namcos2.cpp
+++ b/src/mame/video/namcos2.cpp
@@ -348,10 +348,9 @@ WRITE16_MEMBER( namcos2_state::paletteram_word_w )
/* register 5: POSIRQ scanline (only 8 bits used) */
/*case 0x180a:*/ case 0x180b:
- if (data^m_paletteram[offset]) {
+ //if (data^m_paletteram[offset]) {
m_paletteram[offset] = data;
- adjust_posirq_timer(get_pos_irq_scanline());
- }
+ //}
break;
/* registers 6,7: nothing? */
diff --git a/src/mame/video/namcos21.cpp b/src/mame/video/namcos21.cpp
index b3aed4c0d6a..01865fb2f62 100644
--- a/src/mame/video/namcos21.cpp
+++ b/src/mame/video/namcos21.cpp
@@ -48,11 +48,11 @@ READ16_MEMBER(namcos21_state::winrun_gpu_register_r)
WRITE16_MEMBER(namcos21_state::winrun_gpu_register_w)
{
COMBINE_DATA( &m_winrun_gpu_register[offset] );
+ m_screen->update_partial(m_screen->vpos());
}
WRITE16_MEMBER(namcos21_state::winrun_gpu_videoram_w)
{
- uint8_t *videoram = m_videoram.get();
int color = data>>8;
int mask = data&0xff;
int i;
@@ -60,15 +60,15 @@ WRITE16_MEMBER(namcos21_state::winrun_gpu_videoram_w)
{
if( mask&(0x01<<i) )
{
- videoram[(offset+i)&0x7ffff] = color;
+ m_videoram[(offset+i)&0x7ffff] = color;
+ m_maskram[(offset+i)&0x7ffff] = mask;
}
}
}
READ16_MEMBER(namcos21_state::winrun_gpu_videoram_r)
{
- uint8_t *videoram = m_videoram.get();
- return videoram[offset]<<8;
+ return (m_videoram[offset]<<8) | m_maskram[offset];
}
void namcos21_state::allocate_poly_framebuffer()
@@ -363,6 +363,7 @@ VIDEO_START_MEMBER(namcos21_state,namcos21)
if( m_gametype == NAMCOS21_WINRUN91 )
{
m_videoram = std::make_unique<uint8_t[]>(0x80000);
+ m_maskram = std::make_unique<uint8_t[]>(0x80000);
}
allocate_poly_framebuffer();
c355_obj_init(
@@ -426,7 +427,10 @@ uint32_t namcos21_state::screen_update_driveyes(screen_device &screen, bitmap_in
void namcos21_state::winrun_bitmap_draw(bitmap_ind16 &bitmap, const rectangle &cliprect)
{
uint8_t *videoram = m_videoram.get();
+ //printf("%d %d (%d %d) - %04x %04x %04x|%04x %04x\n",cliprect.min_y,cliprect.max_y,m_screen->vpos(),m_gpu_intc->get_posirq_line(),m_winrun_gpu_register[0],m_winrun_gpu_register[2/2],m_winrun_gpu_register[4/2],m_winrun_gpu_register[0xa/2],m_winrun_gpu_register[0xc/2]);
+
int yscroll = -cliprect.min_y+(int16_t)m_winrun_gpu_register[0x2/2];
+ int xscroll = 0;//m_winrun_gpu_register[0xc/2] >> 7;
int base = 0x1000+0x100*(m_winrun_color&0xf);
int sx,sy;
for( sy=cliprect.min_y; sy<=cliprect.max_y; sy++ )
@@ -435,11 +439,12 @@ void namcos21_state::winrun_bitmap_draw(bitmap_ind16 &bitmap, const rectangle &c
uint16_t *pDest = &bitmap.pix16(sy);
for( sx=cliprect.min_x; sx<=cliprect.max_x; sx++ )
{
- int pen = pSource[sx];
+ int pen = pSource[(sx+xscroll) & 0x1ff];
switch( pen )
{
case 0xff:
break;
+ // TODO: additive blending? winrun car select uses register [0xc] for a xscroll value
case 0x00:
pDest[sx] = (pDest[sx]&0x1fff)+0x4000;
break;
diff --git a/src/mame/video/rm380z.cpp b/src/mame/video/rm380z.cpp
index d5f8b111997..329dcd97ad5 100644
--- a/src/mame/video/rm380z.cpp
+++ b/src/mame/video/rm380z.cpp
@@ -51,7 +51,7 @@ void rm380z_state::init_graphic_chars()
void rm380z_state::config_videomode()
{
- if (m_port0&0x20)
+ if (m_port0&0x20&m_port0_mask)
{
// 80 cols
m_videomode=RM380Z_VIDEOMODE_80COL;
@@ -404,3 +404,40 @@ void rm380z_state::update_screen(bitmap_ind16 &bitmap)
}
}
}
+
+// This needs the attributes etc from above to be added
+uint32_t rm380z_state::screen_update_rm480z(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
+{
+ uint8_t *chargen = memregion("chargen")->base();
+ uint8_t y,ra,chr,gfx;
+ uint16_t sy=0,ma=0,x;
+
+ for (y = 0; y < RM380Z_SCREENROWS; y++)
+ {
+ for (ra = 0; ra < 11; ra++)
+ {
+ uint16_t *p = &bitmap.pix16(sy++);
+
+ for (x = ma; x < ma + 64; x++)
+ {
+ gfx = 0;
+ if (ra < 10)
+ {
+ chr = m_vramchars[x];
+ gfx = chargen[(chr<<4) | ra ];
+ }
+ /* Display a scanline of a character */
+ *p++ = BIT(gfx, 7);
+ *p++ = BIT(gfx, 6);
+ *p++ = BIT(gfx, 5);
+ *p++ = BIT(gfx, 4);
+ *p++ = BIT(gfx, 3);
+ *p++ = BIT(gfx, 2);
+ *p++ = BIT(gfx, 1);
+ *p++ = BIT(gfx, 0);
+ }
+ }
+ ma+=64;
+ }
+ return 0;
+}
diff --git a/src/mame/video/taito_f3.cpp b/src/mame/video/taito_f3.cpp
index 35886e6c7b4..8a3b6442faf 100644
--- a/src/mame/video/taito_f3.cpp
+++ b/src/mame/video/taito_f3.cpp
@@ -322,6 +322,13 @@ pri_alp_bitmap
1111 1111 opaque pixel
*/
+
+void taito_f3_state::device_post_load()
+{
+ /* force a reread of the dynamic tiles in the pixel layer */
+ m_gfxdecode->gfx(3)->mark_all_dirty();
+}
+
/******************************************************************************/
void taito_f3_state::print_debug_info(bitmap_rgb32 &bitmap)
@@ -648,6 +655,13 @@ VIDEO_START_MEMBER(taito_f3_state,f3)
memset(m_spriteram16_buffered.get(),0,0x10000);
memset(m_spriteram.get(),0,0x10000);
+ save_pointer(NAME(m_videoram.get()), 0x2000/2);
+ save_pointer(NAME(m_spriteram.get()), 0x10000/2);
+ save_pointer(NAME(m_f3_vram.get()), 0x2000/2);
+ save_pointer(NAME(m_f3_pf_data.get()), 0xc000/2);
+ save_pointer(NAME(m_f3_line_ram.get()), 0x10000/2);
+ save_pointer(NAME(m_f3_pivot_ram.get()), 0x10000/2);
+
save_item(NAME(m_f3_control_0));
save_item(NAME(m_f3_control_1));
diff --git a/src/mame/video/xbox_nv2a.cpp b/src/mame/video/xbox_nv2a.cpp
index 0d0e2a9d6e1..fd3c3888103 100644
--- a/src/mame/video/xbox_nv2a.cpp
+++ b/src/mame/video/xbox_nv2a.cpp
@@ -2216,6 +2216,103 @@ void dumpcombiners(uint32_t *m)
}
#endif
+void nv2a_renderer::extract_packed_float(uint32_t data, float &first, float &second, float &third)
+{
+ int32_t p1, p2, p3;
+ int32_t e1, e2, e3;
+ int32_t m1, m2, m3;
+ float scale, decimal;
+ union
+ {
+ float f;
+ uint32_t i;
+ } i2f;
+
+ // convert r11g11b10f to 3 float values
+ // each 32 bit words contains 2 11 bit float values and one 10 bit float value
+ p1 = data & 0b11111111111;
+ p2 = (data >> 11) & 0b11111111111;
+ p3 = (data >> 22) & 0b1111111111;
+ // 11 bit values have 6 bits of mantissa and 5 of exponent, 10 bit values have 5 bits of mantissa and 5 of exponent
+ m1 = p1 & 0b111111;
+ e1 = (p1 >> 6) & 0b11111;
+ m2 = p2 & 0b111111;
+ e2 = (p2 >> 6) & 0b11111;
+ m3 = p3 & 0b11111;
+ e3 = (p3 >> 5) & 0b11111;
+ // the fopllowing is based on routine UF11toF32 in appendix G of the "OpenGL Programming Guide 8th edition" book
+ if (e1 == 0) {
+ if (m1 != 0) {
+ scale = 1.0 / (1 << 20);
+ first = scale * m1;
+ }
+ else
+ first = 0;
+ }
+ else if (e1 == 31) {
+ i2f.i = 0x7f800000 | m1;
+ first = i2f.f;
+ }
+ else {
+ e1 -= 15;
+ if (e1 < 0) {
+ scale = 1.0 / (1 << -e1);
+ }
+ else {
+ scale = 1 << e1;
+ }
+ decimal = 1.0 + (float)m1 / 64;
+ first = scale * decimal;
+ }
+ if (e2 == 0) {
+ if (m2 != 0) {
+ scale = 1.0 / (1 << 20);
+ second = scale * m2;
+ }
+ else
+ second = 0;
+ }
+ else if (e2 == 31) {
+ i2f.i = 0x7f800000 | m2;
+ second = i2f.f;
+ }
+ else {
+ e2 -= 15;
+ if (e2 < 0) {
+ scale = 1.0 / (1 << -e2);
+ }
+ else {
+ scale = 1 << e2;
+ }
+ decimal = 1.0 + (float)m2 / 64;
+ second = scale * decimal;
+ }
+ if (e3 == 0) {
+ if (m3 != 0) {
+ scale = 1.0 / (1 << 20);
+ third = scale * m3;
+ }
+ else
+ third = 0;
+ }
+ else if (e3 == 31) {
+ i2f.i = 0x7f800000 | m3;
+ third = i2f.f;
+ }
+ else {
+ e3 -= 15;
+ if (e3 < 0) {
+ scale = 1.0 / (1 << -e3);
+ }
+ else {
+ scale = 1 << e3;
+ }
+ decimal = 1.0 + (float)m3 / 32;
+ third = scale * decimal;
+ }
+}
+
+
void nv2a_renderer::read_vertex(address_space & space, offs_t address, vertex_nv &vertex, int attrib)
{
uint32_t u;
@@ -2233,26 +2330,24 @@ void nv2a_renderer::read_vertex(address_space & space, offs_t address, vertex_nv
d = d + 4;
}
break;
- case NV2A_VTXBUF_TYPE::UBYTE:
+ case NV2A_VTXBUF_TYPE::UBYTE_OGL:
u = space.read_dword(address + 0);
for (c = l-1; c >= 0; c--) {
vertex.attribute[attrib].fv[c] = (u & 0xff) / 255.0;
u = u >> 8;
}
break;
- case NV2A_VTXBUF_TYPE::UBYTE2:
+ case NV2A_VTXBUF_TYPE::UBYTE_D3D:
u = space.read_dword(address + 0);
for (c = 0; c < l; c++) {
vertex.attribute[attrib].fv[c] = (u & 0xff) / 255.0;
u = u >> 8;
}
break;
- case NV2A_VTXBUF_TYPE::UNKNOWN_6: // ???
+ case NV2A_VTXBUF_TYPE::FLOAT_PACKED: // 3 floating point numbers packed into 32 bits
u = space.read_dword(address + 0);
- vertex.attribute[attrib].fv[0] = (u & 0xff) / 255.0; // b
- vertex.attribute[attrib].fv[1] = ((u & 0xff00) >> 8) / 255.0; // g
- vertex.attribute[attrib].fv[2] = ((u & 0xff0000) >> 16) / 255.0; // r
- vertex.attribute[attrib].fv[3] = ((u & 0xff000000) >> 24) / 255.0; // a
+ extract_packed_float(u, vertex.attribute[attrib].fv[0], vertex.attribute[attrib].fv[1], vertex.attribute[attrib].fv[2]);
+ vertex.attribute[attrib].fv[3] = 1.0;
break;
default:
vertex.attribute[attrib].fv[0] = 0;
@@ -2266,24 +2361,13 @@ void nv2a_renderer::read_vertex(address_space & space, offs_t address, vertex_nv
/* Read vertices data from system memory. Method 0x1800 */
int nv2a_renderer::read_vertices_0x1800(address_space & space, vertex_nv *destination, uint32_t address, int limit)
{
- uint32_t data;
- uint32_t m, i, c;
+ uint32_t m;
int a, b;
#ifdef MAME_DEBUG
memset(destination, 0, sizeof(vertex_nv)*limit);
#endif
- c = 0;
for (m = 0; m < limit; m++) {
- if (indexesleft_count == 0) {
- data = space.read_dword(address);
- i = indexesleft_first + indexesleft_count;
- indexesleft[i & 1023] = data & 0xffff;
- indexesleft[(i + 1) & 1023] = (data >> 16) & 0xffff;
- indexesleft_count = indexesleft_count + 2;
- address += 4;
- c++;
- }
memcpy(&destination[m], &persistvertexattr, sizeof(persistvertexattr));
b = enabled_vertex_attributes;
for (a = 0; a < 16; a++) {
@@ -2295,29 +2379,19 @@ int nv2a_renderer::read_vertices_0x1800(address_space & space, vertex_nv *destin
indexesleft_first = (indexesleft_first + 1) & 1023;
indexesleft_count--;
}
- return (int)c;
+ return limit;
}
/* Read vertices data from system memory. Method 0x1808 */
int nv2a_renderer::read_vertices_0x1808(address_space & space, vertex_nv *destination, uint32_t address, int limit)
{
- uint32_t data;
- uint32_t m, i, c;
+ uint32_t m;
int a, b;
#ifdef MAME_DEBUG
memset(destination, 0, sizeof(vertex_nv)*limit);
#endif
- c = 0;
for (m = 0; m < limit; m++) {
- if (indexesleft_count == 0) {
- data = space.read_dword(address);
- i = indexesleft_first + indexesleft_count;
- indexesleft[i & 1023] = data;
- indexesleft_count = indexesleft_count + 1;
- address += 4;
- c++;
- }
memcpy(&destination[m], &persistvertexattr, sizeof(persistvertexattr));
b = enabled_vertex_attributes;
for (a = 0; a < 16; a++) {
@@ -2329,7 +2403,7 @@ int nv2a_renderer::read_vertices_0x1808(address_space & space, vertex_nv *destin
indexesleft_first = (indexesleft_first + 1) & 1023;
indexesleft_count--;
}
- return (int)c;
+ return limit;
}
/* Read vertices data from system memory. Method 0x1810 */
@@ -2753,15 +2827,16 @@ int nv2a_renderer::clip_triangle_w(nv2avertex_t *vi[3], nv2avertex_t *vo)
uint32_t nv2a_renderer::render_triangle_clipping(const rectangle &cliprect, render_delegate callback, int paramcount, nv2avertex_t &_v1, nv2avertex_t &_v2, nv2avertex_t &_v3)
{
-#if 0
nv2avertex_t *vi[3];
- nv2avertex_t vo[16];
+ nv2avertex_t vo[8];
int nv;
-#endif
if ((_v1.w > 0) && (_v2.w > 0) && (_v3.w > 0))
return render_triangle_culling(cliprect, callback, paramcount, _v1, _v2, _v3);
-#if 0
+ if (enable_clipping_w == false)
+ return 0;
+ if ((_v1.w <= 0) && (_v2.w <= 0) && (_v3.w <= 0))
+ return 0;
// assign the elements of the array
vi[0] = &_v1;
vi[1] = &_v2;
@@ -2816,7 +2891,6 @@ uint32_t nv2a_renderer::render_triangle_clipping(const rectangle &cliprect, rend
}
for (int n = 1; n <= (nv - 2); n++)
render_triangle_culling(cliprect, callback, paramcount, vo[0], vo[n], vo[n + 1]);
-#endif
return 0;
}
@@ -2930,6 +3004,7 @@ void nv2a_renderer::assemble_primitive(vertex_nv *source, int count, render_dele
machine().logerror("Unsupported primitive %d\n", int(primitive_type));
vertex_count++;
}
+ source++;
}
primitives_total_count += primitives_count - pc;
}
@@ -3028,20 +3103,6 @@ int nv2a_renderer::geforce_exec_method(address_space & space, uint32_t chanel, u
// vertices are selected from the vertex buffer using an array of indexes
// each dword after 1800 contains two 16 bit index values to select the vartices
// each dword after 1808 contains a 32 bit index value to select the vartices
- while (1) {
- int c;
-
- if ((countlen * mult + indexesleft_count) < 4)
- break;
- if (mult == 1)
- c = read_vertices_0x1808(space, vertex_software + vertex_first, address, 1);
- else
- c = read_vertices_0x1800(space, vertex_software + vertex_first, address, 1);
- address = address + c * 4;
- countlen = countlen - c;
- assemble_primitive(vertex_software + vertex_first, 1, render_spans_callback);
- vertex_first = (vertex_first + 4) & 1023;
- }
while (countlen > 0) {
int n;
@@ -3058,6 +3119,12 @@ int nv2a_renderer::geforce_exec_method(address_space & space, uint32_t chanel, u
}
address += 4;
countlen--;
+ if (mult == 1)
+ read_vertices_0x1808(space, vertex_software + vertex_first, address, 1);
+ else
+ read_vertices_0x1800(space, vertex_software + vertex_first, address, 2);
+ assemble_primitive(vertex_software + vertex_first, mult, render_spans_callback);
+ vertex_first = (vertex_first + mult) & 1023;
}
}
if (maddress == 0x1818) {
@@ -3078,7 +3145,7 @@ int nv2a_renderer::geforce_exec_method(address_space & space, uint32_t chanel, u
}
address = address + c * 4;
assemble_primitive(vertex_software + vertex_first, 1, render_spans_callback);
- vertex_first = (vertex_first + 4) & 1023;
+ vertex_first = (vertex_first + 1) & 1023;
}
}
if ((maddress >= 0x1880) && (maddress < 0x1900))
@@ -3175,19 +3242,19 @@ int nv2a_renderer::geforce_exec_method(address_space & space, uint32_t chanel, u
vertexbuffer_kind[bit] = (NV2A_VTXBUF_TYPE)(data & 15);
vertexbuffer_size[bit] = (data >> 4) & 15;
switch (vertexbuffer_kind[bit]) {
- case NV2A_VTXBUF_TYPE::UBYTE2:
+ case NV2A_VTXBUF_TYPE::UBYTE_D3D:
vertex_attribute_words[bit] = (vertexbuffer_size[bit] * 1) >> 2;
break;
case NV2A_VTXBUF_TYPE::FLOAT:
vertex_attribute_words[bit] = (vertexbuffer_size[bit] * 4) >> 2;
break;
- case NV2A_VTXBUF_TYPE::UBYTE:
+ case NV2A_VTXBUF_TYPE::UBYTE_OGL:
vertex_attribute_words[bit] = (vertexbuffer_size[bit] * 1) >> 2;
break;
case NV2A_VTXBUF_TYPE::USHORT:
vertex_attribute_words[bit] = (vertexbuffer_size[bit] * 2) >> 2;
break;
- case NV2A_VTXBUF_TYPE::UNKNOWN_6:
+ case NV2A_VTXBUF_TYPE::FLOAT_PACKED:
vertex_attribute_words[bit] = (vertexbuffer_size[bit] * 4) >> 2;
break;
default:
@@ -3345,7 +3412,7 @@ int nv2a_renderer::geforce_exec_method(address_space & space, uint32_t chanel, u
}
if (maddress == 0x0130) {
countlen--;
- if (waitvblank_used == 1)
+ if (enable_waitvblank == true)
return 1; // block until next vblank
else
return 0;
@@ -3617,7 +3684,7 @@ int nv2a_renderer::geforce_exec_method(address_space & space, uint32_t chanel, u
maddress = (maddress - 0x0a20) / 4;
*(uint32_t *)(&matrix.translate[maddress]) = data;
// set corresponding vertex shader constant too
- vertexprogram.exec.c_constant[59].iv[maddress] = data; // constant -37
+ vertexprogram.exec.c_constant[59].iv(maddress, data); // constant -37
#ifdef LOG_NV2A
if (maddress == 3)
machine().logerror("viewport translate = {%f %f %f %f}\n", matrix.translate[0], matrix.translate[1], matrix.translate[2], matrix.translate[3]);
@@ -3629,7 +3696,7 @@ int nv2a_renderer::geforce_exec_method(address_space & space, uint32_t chanel, u
maddress = (maddress - 0x0af0) / 4;
*(uint32_t *)(&matrix.scale[maddress]) = data;
// set corresponding vertex shader constant too
- vertexprogram.exec.c_constant[58].iv[maddress] = data; // constant -38
+ vertexprogram.exec.c_constant[58].iv(maddress, data); // constant -38
#ifdef LOG_NV2A
if (maddress == 3)
machine().logerror("viewport scale = {%f %f %f %f}\n", matrix.scale[0], matrix.scale[1], matrix.scale[2], matrix.scale[3]);
@@ -3688,7 +3755,7 @@ int nv2a_renderer::geforce_exec_method(address_space & space, uint32_t chanel, u
if ((maddress >= 0x0b80) && (maddress < 0x0c00)) {
//machine().logerror("VP_UPLOAD_CONST\n");
if (vertexprogram.upload_parameter_index < 192) {
- vertexprogram.exec.c_constant[vertexprogram.upload_parameter_index].iv[vertexprogram.upload_parameter_component] = data;
+ vertexprogram.exec.c_constant[vertexprogram.upload_parameter_index].iv(vertexprogram.upload_parameter_component, data);
}
else
machine().logerror("Need to increase size of vertexprogram.parameter to %d\n\r", vertexprogram.upload_parameter_index);
@@ -3831,16 +3898,22 @@ int nv2a_renderer::geforce_exec_method(address_space & space, uint32_t chanel, u
return 0;
}
-int nv2a_renderer::toggle_register_combiners_usage()
+bool nv2a_renderer::toggle_register_combiners_usage()
{
combiner.used = 1 - combiner.used;
- return combiner.used;
+ return combiner.used != 0;
+}
+
+bool nv2a_renderer::toggle_wait_vblank_support()
+{
+ enable_waitvblank = !enable_waitvblank;
+ return enable_waitvblank;
}
-int nv2a_renderer::toggle_wait_vblank_support()
+bool nv2a_renderer::toggle_clipping_w_support()
{
- waitvblank_used = 1 - waitvblank_used;
- return waitvblank_used;
+ enable_clipping_w = !enable_clipping_w;
+ return enable_clipping_w;
}
void nv2a_renderer::debug_grab_texture(int type, const char *filename)
diff --git a/src/osd/modules/debugger/osx/debugconsole.mm b/src/osd/modules/debugger/osx/debugconsole.mm
index 82d000bbd50..e96d0757ba7 100644
--- a/src/osd/modules/debugger/osx/debugconsole.mm
+++ b/src/osd/modules/debugger/osx/debugconsole.mm
@@ -160,7 +160,7 @@
windowFrame.size.width += adjustment.width;
windowFrame.size.height += adjustment.height; // not used - better to go for fixed height
- windowFrame.size.height = std::min(512.0, available.size.height);
+ windowFrame.size.height = std::min(CGFloat(512.0), available.size.height);
windowFrame.size.width = std::min(windowFrame.size.width, available.size.width);
windowFrame.origin.x = available.origin.x + available.size.width - windowFrame.size.width;
windowFrame.origin.y = available.origin.y;
diff --git a/src/osd/modules/render/bgfx/chainentry.cpp b/src/osd/modules/render/bgfx/chainentry.cpp
index ab18b4029fa..a53ed759940 100644
--- a/src/osd/modules/render/bgfx/chainentry.cpp
+++ b/src/osd/modules/render/bgfx/chainentry.cpp
@@ -270,7 +270,7 @@ bool bgfx_chain_entry::setup_view(int view, uint16_t screen_width, uint16_t scre
void bgfx_chain_entry::put_screen_buffer(render_primitive* prim, bgfx::TransientVertexBuffer* buffer) const
{
- if (bgfx::checkAvailTransientVertexBuffer(6, ScreenVertex::ms_decl))
+ if (6 == bgfx::getAvailTransientVertexBuffer(6, ScreenVertex::ms_decl))
{
bgfx::allocTransientVertexBuffer(buffer, 6, ScreenVertex::ms_decl);
}
diff --git a/src/osd/modules/render/bgfx/chainmanager.cpp b/src/osd/modules/render/bgfx/chainmanager.cpp
index 64e71bd213a..40776bb20ce 100644
--- a/src/osd/modules/render/bgfx/chainmanager.cpp
+++ b/src/osd/modules/render/bgfx/chainmanager.cpp
@@ -9,6 +9,9 @@
//
//============================================================
+#include <bx/readerwriter.h>
+#include <bx/crtimpl.h>
+
#include "emu.h"
#include "../frontend/mame/ui/slider.h"
@@ -18,8 +21,6 @@
#include <rapidjson/document.h>
#include <rapidjson/error/en.h>
-#include <bx/readerwriter.h>
-#include <bx/crtimpl.h>
#include "bgfxutil.h"
#include "chainmanager.h"
diff --git a/src/osd/modules/render/bgfx/effectmanager.cpp b/src/osd/modules/render/bgfx/effectmanager.cpp
index 2b6951e18c8..3affa36f2ec 100644
--- a/src/osd/modules/render/bgfx/effectmanager.cpp
+++ b/src/osd/modules/render/bgfx/effectmanager.cpp
@@ -12,12 +12,12 @@
#include <rapidjson/document.h>
#include <rapidjson/error/en.h>
+#include <bx/readerwriter.h>
+#include <bx/crtimpl.h>
+
#include "emu.h"
-#include <bgfx/bgfxplatform.h>
#include <bgfx/bgfx.h>
-#include <bx/readerwriter.h>
-#include <bx/crtimpl.h>
#include "effectmanager.h"
#include "effectreader.h"
diff --git a/src/osd/modules/render/bgfx/shadermanager.cpp b/src/osd/modules/render/bgfx/shadermanager.cpp
index 6e683b9d14c..e4a665d967c 100644
--- a/src/osd/modules/render/bgfx/shadermanager.cpp
+++ b/src/osd/modules/render/bgfx/shadermanager.cpp
@@ -9,14 +9,14 @@
//
//============================================================
-#include "emu.h"
-
-#include <bgfx/bgfxplatform.h>
-#include <bgfx/bgfx.h>
#include <bx/fpumath.h>
#include <bx/readerwriter.h>
#include <bx/crtimpl.h>
+#include "emu.h"
+
+#include <bgfx/bgfx.h>
+
#include "shadermanager.h"
shader_manager::~shader_manager()
diff --git a/src/osd/modules/render/drawbgfx.cpp b/src/osd/modules/render/drawbgfx.cpp
index f23a5084d9f..2fb0d0b3a1e 100644
--- a/src/osd/modules/render/drawbgfx.cpp
+++ b/src/osd/modules/render/drawbgfx.cpp
@@ -5,6 +5,9 @@
// drawbgfx.cpp - BGFX renderer
//
//============================================================
+#include <bx/fpumath.h>
+#include <bx/readerwriter.h>
+
#if defined(SDLMAME_WIN32) || defined(OSD_WINDOWS) || defined(OSD_UWP)
// standard windows headers
#include <windows.h>
@@ -21,10 +24,8 @@
#include "rendutil.h"
#include "aviwrite.h"
-#include <bgfx/bgfxplatform.h>
#include <bgfx/bgfx.h>
-#include <bx/fpumath.h>
-#include <bx/readerwriter.h>
+#include <bgfx/platform.h>
#include <algorithm>
#include "drawbgfx.h"
@@ -866,7 +867,7 @@ int renderer_bgfx::draw(int update)
void renderer_bgfx::update_recording()
{
- bgfx::blit(s_current_view > 0 ? s_current_view - 1 : 0, m_avi_texture, 0, 0, m_avi_target->target());
+ bgfx::blit(s_current_view > 0 ? s_current_view - 1 : 0, m_avi_texture, 0, 0, bgfx::getTexture(m_avi_target->target()));
bgfx::readTexture(m_avi_texture, m_avi_data);
int i = 0;
@@ -1260,7 +1261,7 @@ void renderer_bgfx::allocate_buffer(render_primitive *prim, uint32_t blend, bgfx
}
}
- if (vertices > 0 && bgfx::checkAvailTransientVertexBuffer(vertices, ScreenVertex::ms_decl))
+ if (vertices > 0 && vertices==bgfx::getAvailTransientVertexBuffer(vertices, ScreenVertex::ms_decl))
{
bgfx::allocTransientVertexBuffer(buffer, vertices, ScreenVertex::ms_decl);
}
diff --git a/src/tools/imgtool/imgtool.cpp b/src/tools/imgtool/imgtool.cpp
index bb7e6c860db..3eb836b6ce3 100644
--- a/src/tools/imgtool/imgtool.cpp
+++ b/src/tools/imgtool/imgtool.cpp
@@ -41,6 +41,11 @@ void CLIB_DECL ATTR_PRINTF(1,2) logerror(const char *format, ...)
Imgtool initialization and basics
***************************************************************************/
+
+//-------------------------------------------------
+// rtrim
+//-------------------------------------------------
+
void rtrim(char *buf)
{
size_t buflen;
@@ -54,6 +59,11 @@ void rtrim(char *buf)
}
}
+
+//-------------------------------------------------
+// strncpyz
+//-------------------------------------------------
+
char *strncpyz(char *dest, const char *source, size_t len)
{
char *s;
@@ -67,6 +77,33 @@ char *strncpyz(char *dest, const char *source, size_t len)
return s;
}
+
+//-------------------------------------------------
+// extract_padded_string
+//-------------------------------------------------
+
+static std::string extract_padded_string(const char *source, size_t len)
+{
+ while ((len > 0) && (source[len - 1] == ' '))
+ len--;
+ return std::string(source, len);
+}
+
+
+//-------------------------------------------------
+// extract_padded_filename - this is a common
+// enough scenario that it is justified to have
+// this in common code
+//-------------------------------------------------
+
+std::string extract_padded_filename(const char *source, size_t filename_length, size_t extension_length)
+{
+ std::string filename = extract_padded_string(source, filename_length);
+ std::string extension = extract_padded_string(source + filename_length, extension_length);
+ return extension.empty() ? filename : filename + "." + extension;
+}
+
+
//-------------------------------------------------
// markerrorsource - marks where an error source
//-------------------------------------------------
diff --git a/src/tools/imgtool/imgtool.h b/src/tools/imgtool/imgtool.h
index eb614a9dabb..5640b3cab12 100644
--- a/src/tools/imgtool/imgtool.h
+++ b/src/tools/imgtool/imgtool.h
@@ -266,5 +266,6 @@ void unknown_partition_get_info(const imgtool_class *imgclass, uint32_t state, u
char *strncpyz(char *dest, const char *source, size_t len);
void rtrim(char *buf);
+std::string extract_padded_filename(const char *source, size_t filename_length, size_t extension_length);
#endif /* IMGTOOL_H */
diff --git a/src/tools/imgtool/main.cpp b/src/tools/imgtool/main.cpp
index 5416b6db435..28029fe0358 100644
--- a/src/tools/imgtool/main.cpp
+++ b/src/tools/imgtool/main.cpp
@@ -8,32 +8,39 @@
***************************************************************************/
+#include "imgtool.h"
+#include "main.h"
+#include "modules.h"
+#include "strformat.h"
+
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <time.h>
+#include <iostream>
-#include "imgtool.h"
-#include "main.h"
-#include "modules.h"
-#include "strformat.h"
+#ifdef _WIN32
+#include <io.h>
+#include <fcntl.h>
+#endif
-/* ---------------------------------------------------------------------- */
+// ----------------------------------------------------------------------
-static void writeusage(FILE *f, int write_word_usage, const struct command *c, char *argv[])
+static void writeusage(std::wostream &output, bool write_word_usage, const struct command *c, char *argv[])
{
std::string cmdname = core_filename_extract_base(argv[0]);
- fprintf(f, "%s %s %s %s\n",
- (write_word_usage ? "Usage:" : " "),
- cmdname.c_str(),
+
+ util::stream_format(output,
+ L"%s %s %s %s\n",
+ (write_word_usage ? L"Usage:" : L" "),
+ wstring_from_utf8(cmdname),
c->name,
- c->usage ? c->usage : "");
+ c->usage ? wstring_from_utf8(c->usage) : std::wstring());
}
-
-/* ----------------------------------------------------------------------- */
+// ----------------------------------------------------------------------
static int parse_options(int argc, char *argv[], int minunnamed, int maxunnamed,
util::option_resolution *resolution, filter_getinfoproc *filter, const char **fork)
@@ -106,15 +113,15 @@ static int parse_options(int argc, char *argv[], int minunnamed, int maxunnamed,
return lastunnamed;
filternotfound:
- fprintf(stderr, "%s: Unknown filter type\n", value);
+ util::stream_format(std::wcerr, L"%s: Unknown filter type\n", wstring_from_utf8(value));
return -1;
optionalreadyspecified:
- fprintf(stderr, "Cannot specify multiple %ss\n", name);
+ util::stream_format(std::wcerr, L"Cannot specify multiple %ss\n", wstring_from_utf8(name));
return -1;
error:
- fprintf(stderr, "%s: Unrecognized option\n", argv[i]);
+ util::stream_format(std::wcerr, L"%s: Unrecognized option\n", wstring_from_utf8(argv[i]));
return -1;
}
@@ -150,7 +157,7 @@ void reporterror(imgtoolerr_t err, const struct command *c, const char *format,
if (!src)
src = c->name;
- fprintf(stderr, "%s: %s\n", src, err_name);
+ util::stream_format(std::wcerr, L"%s: %s\n", wstring_from_utf8(src), wstring_from_utf8(err_name));
}
@@ -166,7 +173,7 @@ static const char *interpret_filename(const char *filename)
-/* ----------------------------------------------------------------------- */
+// ----------------------------------------------------------------------
static int cmd_dir(const struct command *c, int argc, char *argv[])
{
@@ -213,13 +220,13 @@ static int cmd_dir(const struct command *c, int argc, char *argv[])
total_count = 0;
total_size = 0;
- fprintf(stdout, "Contents of %s:%s\n", argv[1], path.c_str());
+ util::stream_format(std::wcout, L"Contents of %s:%s\n", wstring_from_utf8(argv[1]), wstring_from_utf8(path));
info = image->info();
if (!info.empty())
- fprintf(stdout, "%s\n", info.c_str());
+ util::stream_format(std::wcout, L"%s\n", wstring_from_utf8(info));
- fprintf(stdout, "%s\n", separator.c_str());
+ util::stream_format(std::wcout, L"%s\n", wstring_from_utf8(separator));
while (((err = imgenum->get_next(ent)) == 0) && !ent.eof)
{
@@ -234,17 +241,18 @@ static int cmd_dir(const struct command *c, int argc, char *argv[])
if (ent.hardlink)
strcat(ent.filename, " <hl>");
- fprintf(stdout, "%*s %*s %*s %*s\n",
- -columnwidth_filename, ent.filename,
- columnwidth_filesize, filesize_string.c_str(),
+ util::stream_format(std::wcout,
+ L"%*s %*s %*s %*s\n",
+ -columnwidth_filename, wstring_from_utf8(ent.filename),
+ columnwidth_filesize, wstring_from_utf8(filesize_string),
columnwidth_attributes, ent.attr,
- columnwidth_lastmodified, last_modified);
+ columnwidth_lastmodified, wstring_from_utf8(last_modified));
if (ent.softlink && ent.softlink[0] != '\0')
- fprintf(stdout, "-> %s\n", ent.softlink);
+ util::stream_format(std::wcout, L"-> %s\n", wstring_from_utf8(ent.softlink));
if (ent.comment && ent.comment[0] != '\0')
- fprintf(stdout, ": %s\n", ent.comment);
+ util::stream_format(std::wcout, L": %s\n", wstring_from_utf8(ent.comment));
total_count++;
total_size += ent.filesize;
@@ -257,10 +265,10 @@ static int cmd_dir(const struct command *c, int argc, char *argv[])
if (err)
goto done;
- fprintf(stdout, "%s\n", separator.c_str());
- fprintf(stdout, "%8i File(s) %8i bytes\n", total_count, total_size);
+ util::stream_format(std::wcout, L"%s\n", wstring_from_utf8(separator));
+ util::stream_format(std::wcout, L"%8i File(s) %8i bytes", total_count, total_size);
if (!freespace_err)
- fprintf(stdout, " %8u bytes free\n", (unsigned int) freespace);
+ util::stream_format(std::wcout, L" %8u bytes free\n", (unsigned int)freespace);
done:
if (err)
@@ -381,7 +389,7 @@ static int cmd_put(const struct command *c, int argc, char *argv[])
for (i = 0; i < filename_count; i++)
{
filename = filename_list[i];
- printf("Putting file '%s'...\n", filename);
+ util::stream_format(std::wcout, L"Putting file '%s'...\n", wstring_from_utf8(filename));
err = partition->put_file(new_filename, fork, filename, resolution.get(), filter);
if (err)
goto done;
@@ -434,7 +442,7 @@ static int cmd_getall(const struct command *c, int argc, char *argv[])
while (((err = imgenum->get_next(ent)) == 0) && !ent.eof)
{
- fprintf(stdout, "Retrieving %s (%u bytes)\n", ent.filename, (unsigned int) ent.filesize);
+ util::stream_format(std::wcout, L"Retrieving %s (%u bytes)\n", wstring_from_utf8(ent.filename), (unsigned int)ent.filesize);
err = partition->get_file(ent.filename, nullptr, nullptr, filter);
if (err)
@@ -546,7 +554,7 @@ static int cmd_identify(const struct command *c, int argc, char *argv[])
{
for (i = 0; modules[i]; i++)
{
- printf("%.16s %s\n", modules[i]->name, modules[i]->description);
+ util::stream_format(std::wcout, L"%.16s %s\n", wstring_from_utf8(modules[i]->name), wstring_from_utf8(modules[i]->description));
}
return 0;
@@ -679,11 +687,11 @@ done:
static int cmd_listformats(const struct command *c, int argc, char *argv[])
{
- fprintf(stdout, "Image formats supported by imgtool:\n\n");
+ util::stream_format(std::wcout, L"Image formats supported by imgtool:\n\n");
for (const auto &module : imgtool_get_modules())
{
- fprintf(stdout, " %-25s%s\n", module->name, module->description);
+ util::stream_format(std::wcout, L" %-25s%s\n", wstring_from_utf8(module->name), wstring_from_utf8(module->description));
}
return 0;
@@ -695,11 +703,11 @@ static int cmd_listfilters(const struct command *c, int argc, char *argv[])
{
int i;
- fprintf(stdout, "Filters supported by imgtool:\n\n");
+ util::stream_format(std::wcout, L"Filters supported by imgtool:\n\n");
for (i = 0; filters[i]; i++)
{
- fprintf(stdout, " %-11s%s\n",
+ util::stream_format(std::wcout, L" %-11s%s\n",
filter_get_info_string(filters[i], FILTINFO_STR_NAME),
filter_get_info_string(filters[i], FILTINFO_STR_HUMANNAME));
}
@@ -712,8 +720,8 @@ static void listoptions(const util::option_guide &opt_guide, const char *opt_spe
util::option_resolution resolution(opt_guide);
resolution.set_specification(opt_spec);
- fprintf(stdout, "Option Allowed values Description\n");
- fprintf(stdout, "---------------- ------------------------------ -----------\n");
+ util::stream_format(std::wcout, L"Option Allowed values Description\n");
+ util::stream_format(std::wcout, L"---------------- ------------------------------ -----------\n");
for (auto iter = resolution.entries_begin(); iter != resolution.entries_end(); iter++)
{
@@ -760,10 +768,10 @@ static void listoptions(const util::option_guide &opt_guide, const char *opt_spe
break;
}
- fprintf(stdout, "%16s %-30s %s\n",
- opt_name.c_str(),
- description_buffer.str().c_str(),
- opt_desc);
+ util::stream_format(std::wcout, L"%16s %-30s %s\n",
+ wstring_from_utf8(opt_name),
+ wstring_from_utf8(description_buffer.str()),
+ wstring_from_utf8(opt_desc));
}
}
@@ -782,33 +790,33 @@ static int cmd_listdriveroptions(const struct command *c, int argc, char *argv[]
return -1;
}
- fprintf(stdout, "Driver specific options for module '%s':\n\n", argv[0]);
+ util::stream_format(std::wcout, L"Driver specific options for module '%s':\n\n", wstring_from_utf8(argv[0]));
/* list write options */
opt_guide = (const util::option_guide *) imgtool_get_info_ptr(&mod->imgclass, IMGTOOLINFO_PTR_WRITEFILE_OPTGUIDE);
opt_spec = imgtool_get_info_string(&mod->imgclass, IMGTOOLINFO_STR_WRITEFILE_OPTSPEC);
if (opt_guide)
{
- fprintf(stdout, "Image specific file options (usable on the 'put' command):\n\n");
+ util::stream_format(std::wcout, L"Image specific file options (usable on the 'put' command):\n\n");
listoptions(*opt_guide, opt_spec);
- puts("\n");
+ util::stream_format(std::wcout, L"\n");
}
else
{
- fprintf(stdout, "No image specific file options\n\n");
+ util::stream_format(std::wcout, L"No image specific file options\n\n");
}
/* list create options */
opt_guide = mod->createimage_optguide;
if (opt_guide)
{
- fprintf(stdout, "Image specific creation options (usable on the 'create' command):\n\n");
+ util::stream_format(std::wcout, L"Image specific creation options (usable on the 'create' command):\n\n");
listoptions(*opt_guide, mod->createimage_optspec);
- puts("\n");
+ util::stream_format(std::wcout, L"\n");
}
else
{
- fprintf(stdout, "No image specific creation options\n\n");
+ util::stream_format(std::wcout, L"No image specific creation options\n\n");
}
return 0;
@@ -836,7 +844,10 @@ static const struct command cmds[] =
{ "listdriveroptions", cmd_listdriveroptions, "<format>", 1, 1, 0 }
};
-int CLIB_DECL main(int argc, char *argv[])
+
+// ----------------------------------------------------------------------
+
+int main(int argc, char *argv[])
{
int i;
int result;
@@ -844,12 +855,16 @@ int CLIB_DECL main(int argc, char *argv[])
const char *sample_format = "coco_jvc_rsdos";
std::string cmdname = core_filename_extract_base(argv[0]);
+#ifdef _WIN32
+ _setmode(_fileno(stdout), _O_U8TEXT);
+#endif // _WIN32
+
#ifdef MAME_DEBUG
if (imgtool_validitychecks())
return -1;
-#endif /* MAME_DEBUG */
+#endif // MAME_DEBUG
- putchar('\n');
+ util::stream_format(std::wcout, L"\n");
if (argc > 1)
{
@@ -891,25 +906,24 @@ int CLIB_DECL main(int argc, char *argv[])
}
}
- /* Usage */
- fprintf(stderr, "imgtool - Generic image manipulation tool for use with MAME\n\n");
+ // Usage
+ util::stream_format(std::wcerr, L"imgtool - Generic image manipulation tool for use with MAME\n\n");
for (i = 0; i < ARRAY_LENGTH(cmds); i++)
{
- writeusage(stdout, (i == 0), &cmds[i], argv);
+ writeusage(std::wcerr, (i == 0), &cmds[i], argv);
}
+ util::stream_format(std::wcerr, L"\n<format> is the image format, e.g. %s\n", wstring_from_utf8(sample_format));
+ util::stream_format(std::wcerr, L"<imagename> is the image filename; can specify a ZIP file for image name\n");
- fprintf(stderr, "\n<format> is the image format, e.g. %s\n", sample_format);
- fprintf(stderr, "<imagename> is the image filename; can specify a ZIP file for image name\n");
-
- fprintf(stderr, "\nExample usage:\n");
- fprintf(stderr, "\t%s dir %s myimageinazip.zip\n", cmdname.c_str(), sample_format);
- fprintf(stderr, "\t%s get %s myimage.dsk myfile.bin mynewfile.txt\n", cmdname.c_str(), sample_format);
- fprintf(stderr, "\t%s getall %s myimage.dsk\n", cmdname.c_str(), sample_format);
+ util::stream_format(std::wcerr, L"\nExample usage:\n");
+ util::stream_format(std::wcerr, L"\t%s dir %s myimageinazip.zip\n", wstring_from_utf8(cmdname), wstring_from_utf8(sample_format));
+ util::stream_format(std::wcerr, L"\t%s get %s myimage.dsk myfile.bin mynewfile.txt\n", wstring_from_utf8(cmdname), wstring_from_utf8(sample_format));
+ util::stream_format(std::wcerr, L"\t%s getall %s myimage.dsk\n", wstring_from_utf8(cmdname), wstring_from_utf8(sample_format));
result = 0;
goto done;
cmderror:
- writeusage(stdout, 1, &cmds[i], argv);
+ writeusage(std::wcout, 1, &cmds[i], argv);
result = -1;
done:
diff --git a/src/tools/imgtool/modules/rsdos.cpp b/src/tools/imgtool/modules/rsdos.cpp
index 8be6458e45c..9ee8de3cf8c 100644
--- a/src/tools/imgtool/modules/rsdos.cpp
+++ b/src/tools/imgtool/modules/rsdos.cpp
@@ -2,7 +2,7 @@
// copyright-holders:Nathan Woods
/****************************************************************************
- rsdos.c
+ rsdos.cpp
CoCo RS-DOS disk images
@@ -18,8 +18,7 @@
/* this structure mirrors the structure of an RS-DOS directory entry on disk */
struct rsdos_dirent
{
- char fname[8];
- char fext[3];
+ char filename[11];
char ftype;
char asciiflag;
unsigned char first_granule;
@@ -31,7 +30,7 @@ struct rsdos_dirent
struct rsdos_direnum
{
int index;
- int eof;
+ bool eof;
};
#define RSDOS_OPTIONS_FTYPE 'T'
@@ -44,50 +43,51 @@ struct rsdos_direnum
*********************************************************************/
#define MAX_DIRENTS ((18-2)*(256/32))
-static floperr_t get_rsdos_dirent(imgtool::image &f, int index_loc, struct rsdos_dirent *ent)
+#define MAX_GRANULEMAP_SIZE 256
+
+//-------------------------------------------------
+// get_rsdos_dirent
+//-------------------------------------------------
+
+static floperr_t get_rsdos_dirent(imgtool::image &f, int index_loc, rsdos_dirent &ent)
{
- return floppy_read_sector(imgtool_floppy(f), 0, 17, 3, index_loc * 32, (void *) ent, sizeof(*ent));
+ return floppy_read_sector(imgtool_floppy(f), 0, 17, 3, index_loc * 32, (void *) &ent, sizeof(ent));
}
+//-------------------------------------------------
+// put_rsdos_dirent
+//-------------------------------------------------
-static floperr_t put_rsdos_dirent(imgtool::image &f, int index_loc, const struct rsdos_dirent *ent)
+static floperr_t put_rsdos_dirent(imgtool::image &f, int index_loc, const rsdos_dirent &ent)
{
if (index_loc >= MAX_DIRENTS)
return (floperr_t)IMGTOOLERR_FILENOTFOUND;
- return floppy_write_sector(imgtool_floppy(f), 0, 17, 3, index_loc * 32, (void *) ent, sizeof(*ent), 0); /* TODO: pass ddam argument from imgtool */
+ return floppy_write_sector(imgtool_floppy(f), 0, 17, 3, index_loc * 32, (void *) &ent, sizeof(ent), 0); /* TODO: pass ddam argument from imgtool */
}
+//-------------------------------------------------
+// get_dirent_fname
+//-------------------------------------------------
-/* fnamebuf must have at least 13 bytes */
-static void get_dirent_fname(char *fnamebuf, const struct rsdos_dirent *ent)
+static std::string get_dirent_fname(const rsdos_dirent &ent)
{
- char *s;
-
- memset(fnamebuf, 0, 13);
- memcpy(fnamebuf, ent->fname, sizeof(ent->fname));
- rtrim(fnamebuf);
- s = fnamebuf + strlen(fnamebuf);
- *(s++) = '.';
- memcpy(s, ent->fext, sizeof(ent->fext));
- rtrim(s);
-
- /* If no extension, remove period */
- if (*s == '\0')
- s[-1] = '\0';
+ return extract_padded_filename(ent.filename, 8, 3);
}
+//-------------------------------------------------
+// lookup_rsdos_file
+//-------------------------------------------------
-static imgtoolerr_t lookup_rsdos_file(imgtool::image &f, const char *fname, struct rsdos_dirent *ent, int *position)
+static imgtoolerr_t lookup_rsdos_file(imgtool::image &f, const char *fname, rsdos_dirent &ent, int *position = nullptr)
{
int i;
floperr_t ferr;
- char fnamebuf[13];
+ std::string fnamebuf;
i = 0;
- fnamebuf[0] = '\0';
do
{
@@ -97,15 +97,15 @@ static imgtoolerr_t lookup_rsdos_file(imgtool::image &f, const char *fname, stru
if (ferr)
return imgtool_floppy_error(ferr);
}
- while(ent->fname[0] == '\0');
+ while(ent.filename[0] == '\0');
- if (ent->fname[0] != -1)
- get_dirent_fname(fnamebuf, ent);
+ if (ent.filename[0] != -1)
+ fnamebuf = get_dirent_fname(ent);
}
- while((ent->fname[0] != -1) && core_stricmp(fnamebuf, fname));
+ while((ent.filename[0] != -1) && core_stricmp(fnamebuf.c_str(), fname));
- if (ent->fname[0] == -1)
+ if (ent.filename[0] == -1)
return IMGTOOLERR_FILENOTFOUND;
if (position)
@@ -114,6 +114,9 @@ static imgtoolerr_t lookup_rsdos_file(imgtool::image &f, const char *fname, stru
}
+//-------------------------------------------------
+// get_granule_count
+//-------------------------------------------------
static uint8_t get_granule_count(imgtool::image &img)
{
@@ -125,10 +128,12 @@ static uint8_t get_granule_count(imgtool::image &img)
return (granules > 255) ? 255 : (uint8_t) granules;
}
-#define MAX_GRANULEMAP_SIZE 256
-/* granule_map must be an array of MAX_GRANULEMAP_SIZE bytes */
-static floperr_t get_granule_map(imgtool::image &img, uint8_t *granule_map, uint8_t *granule_count)
+//-------------------------------------------------
+// get_granule_map
+//-------------------------------------------------
+
+static floperr_t get_granule_map(imgtool::image &img, uint8_t *granule_map, uint8_t granule_count[MAX_GRANULEMAP_SIZE])
{
uint8_t count;
@@ -140,6 +145,9 @@ static floperr_t get_granule_map(imgtool::image &img, uint8_t *granule_map, uint
}
+//-------------------------------------------------
+// put_granule_map
+//-------------------------------------------------
static floperr_t put_granule_map(imgtool::image &img, const uint8_t *granule_map, uint8_t granule_count)
{
@@ -147,7 +155,9 @@ static floperr_t put_granule_map(imgtool::image &img, const uint8_t *granule_map
}
-
+//-------------------------------------------------
+// transfer_granule
+//-------------------------------------------------
static imgtoolerr_t transfer_granule(imgtool::image &img, uint8_t granule, int length, imgtool::stream &f, imgtoolerr_t (*proc)(imgtool::image &, int, int, int, int, size_t, imgtool::stream &))
{
@@ -166,6 +176,9 @@ static imgtoolerr_t transfer_granule(imgtool::image &img, uint8_t granule, int l
}
+//-------------------------------------------------
+// transfer_from_granule
+//-------------------------------------------------
static imgtoolerr_t transfer_from_granule(imgtool::image &img, uint8_t granule, int length, imgtool::stream &destf)
{
@@ -173,6 +186,9 @@ static imgtoolerr_t transfer_from_granule(imgtool::image &img, uint8_t granule,
}
+//-------------------------------------------------
+// transfer_to_granule
+//-------------------------------------------------
static imgtoolerr_t transfer_to_granule(imgtool::image &img, uint8_t granule, int length, imgtool::stream &sourcef)
{
@@ -180,14 +196,17 @@ static imgtoolerr_t transfer_to_granule(imgtool::image &img, uint8_t granule, in
}
+//-------------------------------------------------
+// process_rsdos_file
+//-------------------------------------------------
-static imgtoolerr_t process_rsdos_file(struct rsdos_dirent *ent, imgtool::image &img, imgtool::stream *destf, size_t *size)
+static imgtoolerr_t process_rsdos_file(struct rsdos_dirent *ent, imgtool::image &img, imgtool::stream *destf, size_t &size)
{
floperr_t ferr;
size_t s, lastgransize;
uint8_t granule_count;
unsigned char i = 0, granule;
- uint8_t usedmap[MAX_GRANULEMAP_SIZE]; /* Used to detect infinite loops */
+ uint8_t usedmap[MAX_GRANULEMAP_SIZE]; // used to detect infinite loops
uint8_t granule_map[MAX_GRANULEMAP_SIZE];
ferr = get_granule_map(img, granule_map, &granule_count);
@@ -221,23 +240,24 @@ static imgtoolerr_t process_rsdos_file(struct rsdos_dirent *ent, imgtool::image
if (destf)
transfer_from_granule(img, granule, lastgransize, *destf);
- if (size)
- *size = s + lastgransize;
+ size = s + lastgransize;
return IMGTOOLERR_SUCCESS;
}
+//-------------------------------------------------
+// prepare_dirent - create a new directory entry
+// with a specified name
+//-------------------------------------------------
-/* create a new directory entry with a specified name */
-static imgtoolerr_t prepare_dirent(struct rsdos_dirent *ent, const char *fname)
+static imgtoolerr_t prepare_dirent(rsdos_dirent &ent, const char *fname)
{
const char *fname_end;
const char *fname_ext;
int fname_ext_len;
- memset(ent, '\0', sizeof(*ent));
- memset(ent->fname, ' ', sizeof(ent->fname));
- memset(ent->fext, ' ', sizeof(ent->fext));
+ memset(&ent, '\0', sizeof(ent));
+ memset(ent.filename, ' ', sizeof(ent.filename));
fname_end = strchr(fname, '.');
if (fname_end)
@@ -247,32 +267,34 @@ static imgtoolerr_t prepare_dirent(struct rsdos_dirent *ent, const char *fname)
fname_ext_len = strlen(fname_ext);
- /* We had better be an 8.3 filename */
+ // we had better be an 8.3 filename
if (((fname_end - fname) > 8) || (fname_ext_len > 3))
return IMGTOOLERR_BADFILENAME;
- memcpy(ent->fname, fname, fname_end - fname);
- memcpy(ent->fext, fname_ext, fname_ext_len);
+ memcpy(&ent.filename[0], fname, fname_end - fname);
+ memcpy(&ent.filename[8], fname_ext, fname_ext_len);
- /* For now, all files are type 2 binary files */
- ent->ftype = 2;
- ent->asciiflag = 0;
+ // for now, all files are type 2 binary files
+ ent.ftype = 2;
+ ent.asciiflag = 0;
return IMGTOOLERR_SUCCESS;
}
+//-------------------------------------------------
+// rsdos_diskimage_nextenum
+//-------------------------------------------------
static imgtoolerr_t rsdos_diskimage_nextenum(imgtool::directory &enumeration, imgtool_dirent &ent)
{
floperr_t ferr;
imgtoolerr_t err;
size_t filesize;
- struct rsdos_direnum *rsenum;
- struct rsdos_dirent rsent;
- char fname[13];
+ rsdos_direnum *rsenum;
+ rsdos_dirent rsent;
imgtool::image &image(enumeration.image());
- rsenum = (struct rsdos_direnum *) enumeration.extra_bytes();
+ rsenum = (rsdos_direnum *) enumeration.extra_bytes();
/* Did we hit the end of file before? */
if (rsenum->eof)
@@ -283,14 +305,14 @@ static imgtoolerr_t rsdos_diskimage_nextenum(imgtool::directory &enumeration, im
if (rsenum->index >= MAX_DIRENTS)
goto eof;
- ferr = get_rsdos_dirent(image, rsenum->index++, &rsent);
+ ferr = get_rsdos_dirent(image, rsenum->index++, rsent);
if (ferr)
return imgtool_floppy_error(ferr);
}
- while(rsent.fname[0] == '\0');
+ while(rsent.filename[0] == '\0');
- /* Now are we at the eof point? */
- if (rsent.fname[0] == -1)
+ // now are we at the eof point?
+ if (rsent.filename[0] == -1)
{
rsenum->eof = 1;
eof:
@@ -299,7 +321,7 @@ eof:
else
{
/* Not the end of file */
- err = process_rsdos_file(&rsent, image, nullptr, &filesize);
+ err = process_rsdos_file(&rsent, image, nullptr, filesize);
if (err)
return err;
@@ -316,15 +338,18 @@ eof:
}
ent.eof = 0;
- get_dirent_fname(fname, &rsent);
+ std::string fname = get_dirent_fname(rsent);
- snprintf(ent.filename, ARRAY_LENGTH(ent.filename), "%s", fname);
+ snprintf(ent.filename, ARRAY_LENGTH(ent.filename), "%s", fname.c_str());
snprintf(ent.attr, ARRAY_LENGTH(ent.attr), "%d %c", (int) rsent.ftype, (char) (rsent.asciiflag + 'B'));
}
return IMGTOOLERR_SUCCESS;
}
+//-------------------------------------------------
+// rsdos_diskimage_freespace
+//-------------------------------------------------
static imgtoolerr_t rsdos_diskimage_freespace(imgtool::partition &partition, uint64_t *size)
{
@@ -349,16 +374,19 @@ static imgtoolerr_t rsdos_diskimage_freespace(imgtool::partition &partition, uin
}
+//-------------------------------------------------
+// delete_entry
+//-------------------------------------------------
-static imgtoolerr_t delete_entry(imgtool::image &img, struct rsdos_dirent *ent, int pos)
+static imgtoolerr_t delete_entry(imgtool::image &img, rsdos_dirent &ent, int pos)
{
floperr_t ferr;
unsigned char g, i;
uint8_t granule_count;
uint8_t granule_map[MAX_GRANULEMAP_SIZE];
- /* Write a NUL in the filename, marking it deleted */
- ent->fname[0] = 0;
+ // write a NUL in the filename, marking it deleted
+ ent.filename[0] = 0;
ferr = put_rsdos_dirent(img, pos, ent);
if (ferr)
return imgtool_floppy_error(ferr);
@@ -367,8 +395,8 @@ static imgtoolerr_t delete_entry(imgtool::image &img, struct rsdos_dirent *ent,
if (ferr)
return imgtool_floppy_error(ferr);
- /* Now free up the granules */
- g = ent->first_granule;
+ // now free up the granules
+ g = ent.first_granule;
while (g < granule_count)
{
i = granule_map[g];
@@ -384,6 +412,9 @@ static imgtoolerr_t delete_entry(imgtool::image &img, struct rsdos_dirent *ent,
}
+//-------------------------------------------------
+// rsdos_diskimage_readfile
+//-------------------------------------------------
static imgtoolerr_t rsdos_diskimage_readfile(imgtool::partition &partition, const char *fname, const char *fork, imgtool::stream &destf)
{
@@ -392,11 +423,11 @@ static imgtoolerr_t rsdos_diskimage_readfile(imgtool::partition &partition, cons
size_t size;
imgtool::image &img(partition.image());
- err = lookup_rsdos_file(img, fname, &ent, NULL);
+ err = lookup_rsdos_file(img, fname, ent);
if (err)
return err;
- err = process_rsdos_file(&ent, img, &destf, &size);
+ err = process_rsdos_file(&ent, img, &destf, size);
if (err)
return err;
@@ -407,6 +438,9 @@ static imgtoolerr_t rsdos_diskimage_readfile(imgtool::partition &partition, cons
}
+//-------------------------------------------------
+// rsdos_diskimage_writefile
+//-------------------------------------------------
static imgtoolerr_t rsdos_diskimage_writefile(imgtool::partition &partition, const char *fname, const char *fork, imgtool::stream &sourcef, util::option_resolution *writeoptions)
{
@@ -422,7 +456,7 @@ static imgtoolerr_t rsdos_diskimage_writefile(imgtool::partition &partition, con
uint8_t granule_count;
uint8_t granule_map[MAX_GRANULEMAP_SIZE];
- /* can we write to this image? */
+ // can we write to this image?
if (floppy_is_read_only(imgtool_floppy(img)))
return IMGTOOLERR_READONLY;
@@ -430,13 +464,13 @@ static imgtoolerr_t rsdos_diskimage_writefile(imgtool::partition &partition, con
if (err)
return err;
- /* is there enough space? */
+ // is there enough space?
sz = sourcef.size();
if (sz > freespace)
return IMGTOOLERR_NOSPACE;
- /* setup our directory entry */
- err = prepare_dirent(&ent, fname);
+ // setup our directory entry
+ err = prepare_dirent(ent, fname);
if (err)
return err;
@@ -458,7 +492,7 @@ static imgtoolerr_t rsdos_diskimage_writefile(imgtool::partition &partition, con
{
g++;
if ((g >= granule_count) || (g == 0))
- return IMGTOOLERR_UNEXPECTED; /* We should have already verified that there is enough space */
+ return IMGTOOLERR_UNEXPECTED; // we should have already verified that there is enough space
}
*gptr = g;
gptr = &granule_map[g];
@@ -471,39 +505,38 @@ static imgtoolerr_t rsdos_diskimage_writefile(imgtool::partition &partition, con
sz -= i;
- /* Go to next granule */
+ // go to next granule
g++;
}
while(sz > 0);
- /* Now that we are done with the file, we need to specify the final entry
- * in the file allocation table
- */
+ // now that we are done with the file, we need to specify the final entry
+ // in the file allocation table
*gptr = 0xc0 + ((i + 255) / 256);
- /* Now we need to find an empty directory entry */
+ // now we need to find an empty directory entry
i = -1;
do
{
- ferr = get_rsdos_dirent(img, ++i, &ent2);
+ ferr = get_rsdos_dirent(img, ++i, ent2);
if (ferr)
return imgtool_floppy_error(ferr);
}
- while((ent2.fname[0] != '\0') && strcmp(ent.fname, ent2.fname) && (ent2.fname[0] != -1));
+ while((ent2.filename[0] != '\0') && strcmp(ent.filename, ent2.filename) && (ent2.filename[0] != -1));
- /* delete file if it already exists */
- if (ent2.fname[0] && (ent2.fname[0] != -1))
+ // delete file if it already exists
+ if (ent2.filename[0] && (ent2.filename[0] != -1))
{
- err = delete_entry(img, &ent2, i);
+ err = delete_entry(img, ent2, i);
if (err)
return err;
}
- ferr = put_rsdos_dirent(img, i, &ent);
+ ferr = put_rsdos_dirent(img, i, ent);
if (ferr)
return imgtool_floppy_error(ferr);
- /* write the granule map back out */
+ // write the granule map back out
ferr = put_granule_map(img, granule_map, granule_count);
if (ferr)
return imgtool_floppy_error(ferr);
@@ -512,6 +545,9 @@ static imgtoolerr_t rsdos_diskimage_writefile(imgtool::partition &partition, con
}
+//-------------------------------------------------
+// rsdos_diskimage_deletefile
+//-------------------------------------------------
static imgtoolerr_t rsdos_diskimage_deletefile(imgtool::partition &partition, const char *fname)
{
@@ -520,14 +556,17 @@ static imgtoolerr_t rsdos_diskimage_deletefile(imgtool::partition &partition, co
int pos;
struct rsdos_dirent ent;
- err = lookup_rsdos_file(image, fname, &ent, &pos);
+ err = lookup_rsdos_file(image, fname, ent, &pos);
if (err)
return err;
- return delete_entry(image, &ent, pos);
+ return delete_entry(image, ent, pos);
}
+//-------------------------------------------------
+// rsdos_diskimage_suggesttransfer
+//-------------------------------------------------
static imgtoolerr_t rsdos_diskimage_suggesttransfer(imgtool::partition &partition, const char *fname, imgtool_transfer_suggestion *suggestions, size_t suggestions_length)
{
@@ -538,7 +577,7 @@ static imgtoolerr_t rsdos_diskimage_suggesttransfer(imgtool::partition &partitio
if (fname)
{
- err = lookup_rsdos_file(image, fname, &ent, &pos);
+ err = lookup_rsdos_file(image, fname, ent, &pos);
if (err)
return err;