summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/devices/bus/a7800/a78_slot.cpp15
-rw-r--r--src/devices/bus/coco/coco_dwsock.cpp33
-rw-r--r--src/devices/bus/coco/coco_dwsock.h2
-rw-r--r--src/devices/bus/gba/gba_slot.cpp12
-rw-r--r--src/devices/bus/iq151/minigraf.cpp4
-rw-r--r--src/devices/bus/iq151/ms151a.cpp4
-rw-r--r--src/devices/bus/isa/isa.cpp2
-rw-r--r--src/devices/bus/isa/sblaster.cpp115
-rw-r--r--src/devices/bus/isa/sblaster.h13
-rw-r--r--src/devices/bus/isa/trident.cpp32
-rw-r--r--src/devices/bus/isa/trident.h15
-rw-r--r--src/devices/bus/nubus/nubus_image.cpp26
-rw-r--r--src/devices/bus/nubus/nubus_image.h2
-rw-r--r--src/devices/bus/pc_joy/pc_joy.cpp2
-rw-r--r--src/devices/bus/sega8/mgear.cpp13
-rw-r--r--src/devices/bus/sms_ctrl/rfu.cpp5
-rw-r--r--src/devices/bus/sms_ctrl/sports.cpp12
-rw-r--r--src/devices/bus/sms_ctrl/sportsjp.cpp2
-rw-r--r--src/devices/bus/sms_ctrl/sportsjp.h5
-rw-r--r--src/devices/bus/sms_exp/gender.cpp7
-rw-r--r--src/devices/bus/svi3x8/expander/expander.cpp151
-rw-r--r--src/devices/bus/svi3x8/expander/expander.h162
-rw-r--r--src/devices/bus/svi3x8/expander/modules.cpp14
-rw-r--r--src/devices/bus/svi3x8/expander/modules.h20
-rw-r--r--src/devices/bus/svi3x8/expander/sv601.cpp83
-rw-r--r--src/devices/bus/svi3x8/expander/sv601.h58
-rw-r--r--src/devices/bus/svi3x8/expander/sv602.cpp77
-rw-r--r--src/devices/bus/svi3x8/expander/sv602.h58
-rw-r--r--src/devices/bus/svi3x8/slot/cards.cpp28
-rw-r--r--src/devices/bus/svi3x8/slot/cards.h25
-rw-r--r--src/devices/bus/svi3x8/slot/slot.cpp284
-rw-r--r--src/devices/bus/svi3x8/slot/slot.h179
-rw-r--r--src/devices/bus/svi3x8/slot/sv801.cpp147
-rw-r--r--src/devices/bus/svi3x8/slot/sv801.h61
-rw-r--r--src/devices/bus/svi3x8/slot/sv802.cpp88
-rw-r--r--src/devices/bus/svi3x8/slot/sv802.h51
-rw-r--r--src/devices/bus/svi3x8/slot/sv803.cpp70
-rw-r--r--src/devices/bus/svi3x8/slot/sv803.h44
-rw-r--r--src/devices/bus/svi3x8/slot/sv805.cpp109
-rw-r--r--src/devices/bus/svi3x8/slot/sv805.h49
-rw-r--r--src/devices/bus/svi3x8/slot/sv806.cpp153
-rw-r--r--src/devices/bus/svi3x8/slot/sv806.h55
-rw-r--r--src/devices/bus/svi3x8/slot/sv807.cpp170
-rw-r--r--src/devices/bus/svi3x8/slot/sv807.h60
-rw-r--r--src/devices/bus/ti99x/gromport.cpp83
-rw-r--r--src/devices/bus/ti99x/gromport.h8
-rw-r--r--src/devices/cpu/tms0980/tms0980.cpp1514
-rw-r--r--src/devices/cpu/tms0980/tms0980.h518
-rw-r--r--src/devices/cpu/tms0980/tms0980d.cpp363
-rw-r--r--src/devices/cpu/tms1000/tms0270.cpp182
-rw-r--r--src/devices/cpu/tms1000/tms0270.h71
-rw-r--r--src/devices/cpu/tms1000/tms0970.cpp161
-rw-r--r--src/devices/cpu/tms1000/tms0970.h57
-rw-r--r--src/devices/cpu/tms1000/tms0980.cpp243
-rw-r--r--src/devices/cpu/tms1000/tms0980.h61
-rw-r--r--src/devices/cpu/tms1000/tms1000.cpp123
-rw-r--r--src/devices/cpu/tms1000/tms1000.h55
-rw-r--r--src/devices/cpu/tms1000/tms1100.cpp87
-rw-r--r--src/devices/cpu/tms1000/tms1100.h56
-rw-r--r--src/devices/cpu/tms1000/tms1400.cpp143
-rw-r--r--src/devices/cpu/tms1000/tms1400.h61
-rw-r--r--src/devices/cpu/tms1000/tms1k_base.cpp635
-rw-r--r--src/devices/cpu/tms1000/tms1k_base.h299
-rw-r--r--src/devices/cpu/tms1000/tms1k_dasm.cpp281
-rw-r--r--src/devices/cpu/tms1000/tp0320.cpp107
-rw-r--r--src/devices/cpu/tms1000/tp0320.h35
-rw-r--r--src/devices/imagedev/diablo.cpp6
-rw-r--r--src/devices/imagedev/floppy.cpp18
-rw-r--r--src/devices/imagedev/harddriv.cpp6
-rw-r--r--src/devices/machine/atapicdr.cpp12
-rw-r--r--src/devices/machine/atapicdr.h1
-rw-r--r--src/devices/machine/gt64xxx.cpp600
-rw-r--r--src/devices/machine/gt64xxx.h259
-rw-r--r--src/devices/machine/ins8250.cpp2
-rw-r--r--src/devices/machine/netlist.cpp4
-rw-r--r--src/devices/sound/ad1848.cpp186
-rw-r--r--src/devices/sound/ad1848.h67
-rw-r--r--src/devices/sound/samples.cpp12
-rw-r--r--src/devices/video/h63484.cpp5
-rw-r--r--src/devices/video/hd63484.cpp2
-rw-r--r--src/devices/video/pc_vga.cpp96
-rw-r--r--src/devices/video/pc_vga.h1
-rw-r--r--src/devices/video/tms9927.cpp13
-rw-r--r--src/emu/attotime.h11
-rw-r--r--src/emu/audit.cpp10
-rw-r--r--src/emu/cheat.cpp8
-rw-r--r--src/emu/clifront.cpp99
-rw-r--r--src/emu/config.cpp16
-rw-r--r--src/emu/debug/debugcmd.cpp7
-rw-r--r--src/emu/debug/debugcpu.cpp8
-rw-r--r--src/emu/debug/dvbpoints.cpp2
-rw-r--r--src/emu/debug/dvdisasm.cpp2
-rw-r--r--src/emu/debug/dvwpoints.cpp2
-rw-r--r--src/emu/diimage.cpp68
-rw-r--r--src/emu/dipty.cpp56
-rw-r--r--src/emu/dipty.h32
-rw-r--r--src/emu/drivers/xtal.h1
-rw-r--r--src/emu/emuopts.cpp4
-rw-r--r--src/emu/fileio.cpp228
-rw-r--r--src/emu/fileio.h53
-rw-r--r--src/emu/hashfile.cpp4
-rw-r--r--src/emu/image.cpp4
-rw-r--r--src/emu/inpttype.h40
-rw-r--r--src/emu/ioport.cpp12
-rw-r--r--src/emu/ioport.h28
-rw-r--r--src/emu/language.cpp2
-rw-r--r--src/emu/luaengine.cpp55
-rw-r--r--src/emu/luaengine.h1
-rw-r--r--src/emu/machine.cpp130
-rw-r--r--src/emu/machine.ipp1
-rw-r--r--src/emu/mame.cpp4
-rw-r--r--src/emu/mconfig.h79
-rw-r--r--src/emu/memory.cpp4
-rw-r--r--src/emu/render.cpp34
-rw-r--r--src/emu/render.h2
-rw-r--r--src/emu/rendfont.cpp50
-rw-r--r--src/emu/rendfont.h6
-rw-r--r--src/emu/rendutil.cpp4
-rw-r--r--src/emu/romload.cpp48
-rw-r--r--src/emu/romload.h8
-rw-r--r--src/emu/screen.cpp4
-rw-r--r--src/emu/softlist.cpp4
-rw-r--r--src/emu/sound.cpp4
-rw-r--r--src/emu/ui/auditmenu.cpp14
-rw-r--r--src/emu/ui/auditmenu.h12
-rw-r--r--src/emu/ui/barcode.cpp2
-rw-r--r--src/emu/ui/cheatopt.cpp2
-rw-r--r--src/emu/ui/cmddata.h4
-rw-r--r--src/emu/ui/cmdrender.h25
-rw-r--r--src/emu/ui/ctrlmenu.cpp6
-rw-r--r--src/emu/ui/ctrlmenu.h2
-rw-r--r--src/emu/ui/custmenu.cpp26
-rw-r--r--src/emu/ui/custmenu.h2
-rw-r--r--src/emu/ui/custui.cpp67
-rw-r--r--src/emu/ui/custui.h31
-rw-r--r--src/emu/ui/datfile.cpp4
-rw-r--r--src/emu/ui/datfile.h2
-rw-r--r--src/emu/ui/datmenu.cpp77
-rw-r--r--src/emu/ui/datmenu.h6
-rw-r--r--src/emu/ui/defimg.h3
-rw-r--r--src/emu/ui/devopt.cpp2
-rw-r--r--src/emu/ui/dirmenu.cpp77
-rw-r--r--src/emu/ui/dirmenu.h2
-rw-r--r--src/emu/ui/dsplmenu.cpp2
-rw-r--r--src/emu/ui/dsplmenu.h2
-rw-r--r--src/emu/ui/filemngr.cpp2
-rw-r--r--src/emu/ui/filesel.cpp22
-rw-r--r--src/emu/ui/icorender.h6
-rw-r--r--src/emu/ui/imgcntrl.cpp16
-rw-r--r--src/emu/ui/info.cpp2
-rw-r--r--src/emu/ui/info_pty.cpp2
-rw-r--r--src/emu/ui/inifile.cpp20
-rw-r--r--src/emu/ui/inifile.h45
-rw-r--r--src/emu/ui/inputmap.cpp2
-rw-r--r--src/emu/ui/mainmenu.cpp2
-rw-r--r--src/emu/ui/menu.cpp161
-rw-r--r--src/emu/ui/miscmenu.cpp28
-rw-r--r--src/emu/ui/moptions.cpp43
-rw-r--r--src/emu/ui/moptions.h4
-rw-r--r--src/emu/ui/optsmenu.cpp43
-rw-r--r--src/emu/ui/selector.cpp35
-rw-r--r--src/emu/ui/selector.h5
-rw-r--r--src/emu/ui/selgame.cpp159
-rw-r--r--src/emu/ui/selgame.h2
-rw-r--r--src/emu/ui/selsoft.cpp84
-rw-r--r--src/emu/ui/selsoft.h22
-rw-r--r--src/emu/ui/sliders.cpp2
-rw-r--r--src/emu/ui/slotopt.cpp2
-rw-r--r--src/emu/ui/sndmenu.cpp2
-rw-r--r--src/emu/ui/sndmenu.h2
-rw-r--r--src/emu/ui/starimg.h3
-rw-r--r--src/emu/ui/swlist.cpp2
-rw-r--r--src/emu/ui/tapectrl.cpp2
-rw-r--r--src/emu/ui/ui.cpp4
-rw-r--r--src/emu/ui/utils.h6
-rw-r--r--src/emu/ui/videoopt.cpp2
-rw-r--r--src/emu/uismall.pngbin1488 -> 0 bytes
-rw-r--r--src/emu/video.cpp55
-rw-r--r--src/emu/video.h16
-rw-r--r--src/ldplayer/ldplayer.cpp4
-rw-r--r--src/lib/formats/ioprocs.cpp40
-rw-r--r--src/lib/formats/ioprocs.h10
-rw-r--r--src/lib/netlist/devices/nld_7404.h4
-rw-r--r--src/lib/netlist/devices/nld_7486.h8
-rw-r--r--src/lib/netlist/devices/nld_82S16.cpp8
-rw-r--r--src/lib/netlist/devices/nld_82S16.h2
-rw-r--r--src/lib/netlist/devices/nld_9312.h14
-rw-r--r--src/lib/netlist/devices/nld_system.cpp6
-rw-r--r--src/lib/netlist/devices/nld_system.h2
-rw-r--r--src/lib/netlist/devices/nld_truthtable.cpp21
-rw-r--r--src/lib/netlist/devices/nld_truthtable.h24
-rw-r--r--src/lib/netlist/nl_base.cpp143
-rw-r--r--src/lib/netlist/nl_base.h40
-rw-r--r--src/lib/netlist/nl_factory.cpp12
-rw-r--r--src/lib/netlist/nl_factory.h4
-rw-r--r--src/lib/netlist/nl_lists.h20
-rw-r--r--src/lib/netlist/nl_parser.cpp14
-rw-r--r--src/lib/netlist/nl_setup.cpp117
-rw-r--r--src/lib/netlist/nl_setup.h11
-rw-r--r--src/lib/netlist/plib/pconfig.h2
-rw-r--r--src/lib/netlist/plib/plists.h488
-rw-r--r--src/lib/netlist/plib/poptions.h8
-rw-r--r--src/lib/netlist/plib/pparser.cpp30
-rw-r--r--src/lib/netlist/plib/pparser.h8
-rw-r--r--src/lib/netlist/plib/pstate.cpp6
-rw-r--r--src/lib/netlist/plib/pstate.h4
-rw-r--r--src/lib/netlist/plib/pstream.cpp16
-rw-r--r--src/lib/netlist/plib/pstring.cpp14
-rw-r--r--src/lib/netlist/prg/nltool.cpp10
-rw-r--r--src/lib/netlist/solver/nld_ms_direct.h12
-rw-r--r--src/lib/netlist/solver/nld_ms_direct_lu.h2
-rw-r--r--src/lib/netlist/solver/nld_ms_gmres.h4
-rw-r--r--src/lib/netlist/solver/nld_solver.cpp68
-rw-r--r--src/lib/netlist/solver/nld_solver.h24
-rw-r--r--src/lib/netlist/tools/nl_convert.cpp62
-rw-r--r--src/lib/netlist/tools/nl_convert.h23
-rw-r--r--src/lib/util/aviio.cpp3369
-rw-r--r--src/lib/util/aviio.h188
-rw-r--r--src/lib/util/cdrom.cpp4
-rw-r--r--src/lib/util/chd.cpp16
-rw-r--r--src/lib/util/chdcd.cpp55
-rw-r--r--src/lib/util/corealloc.h37
-rw-r--r--src/lib/util/corefile.cpp169
-rw-r--r--src/lib/util/corefile.h25
-rw-r--r--src/lib/util/delegate.cpp9
-rw-r--r--src/lib/util/delegate.h2
-rw-r--r--src/lib/util/un7z.cpp703
-rw-r--r--src/lib/util/un7z.h143
-rw-r--r--src/lib/util/unzip.cpp922
-rw-r--r--src/lib/util/unzip.h153
-rw-r--r--src/lib/util/vecstream.h9
-rw-r--r--src/lib/util/zippath.cpp436
-rw-r--r--src/lib/util/zippath.h13
-rw-r--r--src/mame/arcade.flt20
-rw-r--r--src/mame/drivers/android.cpp321
-rw-r--r--src/mame/drivers/angelkds.cpp119
-rw-r--r--src/mame/drivers/apple3.cpp6
-rw-r--r--src/mame/drivers/carjmbre.cpp8
-rw-r--r--src/mame/drivers/cclimber.cpp32
-rw-r--r--src/mame/drivers/fruitpc.cpp23
-rw-r--r--src/mame/drivers/gba.cpp4
-rw-r--r--src/mame/drivers/goldstar.cpp332
-rw-r--r--src/mame/drivers/hh_cop400.cpp4
-rw-r--r--src/mame/drivers/hh_sm510.cpp39
-rw-r--r--src/mame/drivers/hh_tms1k.cpp20
-rw-r--r--src/mame/drivers/hh_ucom4.cpp2
-rw-r--r--src/mame/drivers/himesiki.cpp211
-rw-r--r--src/mame/drivers/igs017.cpp5
-rw-r--r--src/mame/drivers/iteagle.cpp32
-rw-r--r--src/mame/drivers/jaguar.cpp4
-rw-r--r--src/mame/drivers/k28.cpp11
-rw-r--r--src/mame/drivers/lwings.cpp239
-rw-r--r--src/mame/drivers/microvsn.cpp4
-rw-r--r--src/mame/drivers/n64.cpp5
-rw-r--r--src/mame/drivers/namcos21.cpp2
-rw-r--r--src/mame/drivers/neogeo_noslot.cpp107
-rw-r--r--src/mame/drivers/ng_aes.cpp23
-rw-r--r--src/mame/drivers/ngen.cpp2
-rw-r--r--src/mame/drivers/ngp.cpp7
-rw-r--r--src/mame/drivers/notetaker.cpp161
-rw-r--r--src/mame/drivers/pcat_dyn.cpp176
-rw-r--r--src/mame/drivers/r9751.cpp29
-rw-r--r--src/mame/drivers/shanghai.cpp123
-rw-r--r--src/mame/drivers/ssem.cpp1
-rw-r--r--src/mame/drivers/svi318.cpp228
-rw-r--r--src/mame/drivers/svision.cpp5
-rw-r--r--src/mame/drivers/symbolics.cpp270
-rw-r--r--src/mame/drivers/taitogn.cpp11
-rw-r--r--src/mame/drivers/vigilant.cpp82
-rw-r--r--src/mame/drivers/zn.cpp421
-rw-r--r--src/mame/etc/jrcrypt.cpp4
-rw-r--r--src/mame/includes/angelkds.h7
-rw-r--r--src/mame/includes/apple3.h16
-rw-r--r--src/mame/includes/hh_tms1k.h9
-rw-r--r--src/mame/includes/himesiki.h6
-rw-r--r--src/mame/includes/lwings.h6
-rw-r--r--src/mame/includes/neogeo.h66
-rw-r--r--src/mame/includes/xbox.h61
-rw-r--r--src/mame/layout/cnsector.lay235
-rw-r--r--src/mame/layout/hh_sm510_test.lay521
-rw-r--r--src/mame/layout/lostreas.lay206
-rw-r--r--src/mame/layout/starwbc.lay200
-rw-r--r--src/mame/machine/apple3.cpp171
-rw-r--r--src/mame/machine/cat702.cpp11
-rw-r--r--src/mame/machine/cat702.h9
-rw-r--r--src/mame/machine/fddebug.cpp16
-rw-r--r--src/mame/machine/iteagle_fpga.cpp59
-rw-r--r--src/mame/machine/iteagle_fpga.h14
-rw-r--r--src/mame/machine/n64.cpp9
-rw-r--r--src/mame/machine/xbox.cpp219
-rw-r--r--src/mame/mame.lst16
-rw-r--r--src/mame/mess.flt1
-rw-r--r--src/mame/video/angelkds.cpp16
-rw-r--r--src/mame/video/apple3.cpp54
-rw-r--r--src/mame/video/atarirle.cpp2
-rw-r--r--src/mame/video/himesiki.cpp32
-rw-r--r--src/mame/video/lwings.cpp2
-rw-r--r--src/osd/modules/file/posixfile.cpp483
-rw-r--r--src/osd/modules/file/posixfile.h28
-rw-r--r--src/osd/modules/file/posixptty.cpp184
-rw-r--r--src/osd/modules/file/posixsocket.cpp232
-rw-r--r--src/osd/modules/file/stdfile.cpp251
-rw-r--r--src/osd/modules/file/winfile.cpp503
-rw-r--r--src/osd/modules/file/winfile.h34
-rw-r--r--src/osd/modules/file/winptty.cpp111
-rw-r--r--src/osd/modules/file/winsocket.cpp277
-rw-r--r--src/osd/modules/font/font_dwrite.cpp159
-rw-r--r--src/osd/modules/font/font_module.h17
-rw-r--r--src/osd/modules/font/font_none.cpp48
-rw-r--r--src/osd/modules/font/font_osx.cpp141
-rw-r--r--src/osd/modules/font/font_sdl.cpp360
-rw-r--r--src/osd/modules/font/font_windows.cpp116
-rw-r--r--src/osd/modules/input/input_common.cpp10
-rw-r--r--src/osd/modules/input/input_common.h12
-rw-r--r--src/osd/modules/input/input_dinput.cpp158
-rw-r--r--src/osd/modules/input/input_rawinput.cpp364
-rw-r--r--src/osd/modules/input/input_sdl.cpp2
-rw-r--r--src/osd/modules/input/input_sdlcommon.cpp18
-rw-r--r--src/osd/modules/input/input_sdlcommon.h13
-rw-r--r--src/osd/modules/input/input_win32.cpp13
-rw-r--r--src/osd/modules/input/input_windows.cpp18
-rw-r--r--src/osd/modules/input/input_windows.h10
-rw-r--r--src/osd/modules/input/input_x11.cpp2
-rw-r--r--src/osd/modules/input/input_xinput.cpp8
-rw-r--r--src/osd/modules/lib/osdlib_unix.cpp7
-rw-r--r--src/osd/modules/lib/osdobj_common.cpp36
-rw-r--r--src/osd/modules/lib/osdobj_common.h14
-rw-r--r--src/osd/modules/render/d3d/d3dcomm.h23
-rw-r--r--src/osd/modules/render/d3d/d3dhlsl.cpp483
-rw-r--r--src/osd/modules/render/d3d/d3dhlsl.h46
-rw-r--r--src/osd/modules/render/drawbgfx.cpp2
-rw-r--r--src/osd/modules/render/drawd3d.cpp223
-rw-r--r--src/osd/modules/render/drawd3d.h13
-rw-r--r--src/osd/osdcore.h270
-rw-r--r--src/osd/osdepend.h30
-rw-r--r--src/osd/osdmini/minidir.cpp11
-rw-r--r--src/osd/osdmini/minifile.cpp238
-rw-r--r--src/osd/osdmini/minimisc.cpp6
-rw-r--r--src/osd/sdl/osdsdl.h8
-rw-r--r--src/osd/sdl/sdldir.cpp79
-rw-r--r--src/osd/sdl/sdlfile.cpp630
-rw-r--r--src/osd/sdl/sdlfile.h51
-rw-r--r--src/osd/sdl/sdlptty_unix.cpp161
-rw-r--r--src/osd/sdl/sdlptty_win32.cpp12
-rw-r--r--src/osd/sdl/sdlsocket.cpp193
-rw-r--r--src/osd/sdl/video.cpp5
-rw-r--r--src/osd/sdl/window.cpp16
-rw-r--r--src/osd/strconv.h16
-rw-r--r--src/osd/windows/windir.cpp19
-rw-r--r--src/osd/windows/window.cpp27
-rw-r--r--src/osd/windows/winfile.cpp571
-rw-r--r--src/osd/windows/winfile.h56
-rw-r--r--src/osd/windows/winmain.cpp43
-rw-r--r--src/osd/windows/winmain.h12
-rw-r--r--src/osd/windows/winptty.cpp70
-rw-r--r--src/osd/windows/winsocket.cpp204
-rw-r--r--src/osd/windows/winutil.cpp50
-rw-r--r--src/osd/windows/winutil.h9
-rw-r--r--src/tools/chdman.cpp129
-rw-r--r--src/tools/imgtool/stream.cpp35
-rw-r--r--src/tools/ldverify.cpp42
-rw-r--r--src/tools/pngcmp.cpp22
-rw-r--r--src/tools/regrep.cpp26
-rw-r--r--src/tools/romcmp.cpp50
-rw-r--r--src/tools/split.cpp26
-rw-r--r--src/tools/src2html.cpp8
-rw-r--r--src/tools/unidasm.cpp6
367 files changed, 18163 insertions, 13240 deletions
diff --git a/src/devices/bus/a7800/a78_slot.cpp b/src/devices/bus/a7800/a78_slot.cpp
index 53541560fa4..65b32272820 100644
--- a/src/devices/bus/a7800/a78_slot.cpp
+++ b/src/devices/bus/a7800/a78_slot.cpp
@@ -275,7 +275,7 @@ int a78_cart_slot_device::validate_header(int head, bool log)
{
if (log)
{
- osd_printf_info("Unsupported mapper, please contact MESSdevs (Header 0x%X)\n", head);
+ osd_printf_info("Unsupported mapper, please contact MAMEdevs (Header 0x%X)\n", head);
osd_printf_info("Disabling special bits\n");
}
head &= 0x00ff;
@@ -414,7 +414,7 @@ bool a78_cart_slot_device::call_load()
break;
}
- // check if cart has a POKEY at $0450 (typically a VersaBoard variant)!
+ // check if cart has a POKEY at $0450 (typically a VersaBoard variant)
if (mapper & 0x40)
{
if (m_type != A78_TYPE2)
@@ -434,13 +434,13 @@ bool a78_cart_slot_device::call_load()
if (head[58] == 1)
{
- osd_printf_info("This cart support external NVRAM savings, using HSC.\n");
+ osd_printf_info("This cart supports external NVRAM using HSC.\n");
osd_printf_info("Run it with the High Score Cart mounted to exploit this feature.\n");
}
else if (head[58] == 2)
{
- osd_printf_info("This cart support external NVRAM savings, using SaveKey.\n");
- osd_printf_info("This is not supported in MESS currently.\n");
+ osd_printf_info("This cart supports external NVRAM using SaveKey.\n");
+ osd_printf_info("This is not supported in MAME currently.\n");
}
if (head[63])
@@ -714,12 +714,12 @@ WRITE8_MEMBER(a78_cart_slot_device::write_40xx)
bit 3 [0x08] - bank 0 of 144K ROM at $4000
bit 4 [0x10] - bank 6 at $4000
bit 5 [0x20] - banked RAM at $4000
+ bit 6 [0x40] - POKEY at $0450
bit 8-15 - Special values
- 0 = Normal cart
+ 0 = Normal cart // normal compared to what? perhaps this should be 'unused'
1 = Absolute (F18 Hornet)
2 = Activision (Double Dragon & Rampage)
- 3 = POKEY at $0450
-------------------------------------------------*/
@@ -817,6 +817,7 @@ void a78_cart_slot_device::internal_header_logging(UINT8 *header, UINT32 len)
logerror( "\t\tbank0 at $4000: %s\n", BIT(head_mapper, 3) ? "Yes" : "No");
logerror( "\t\tbank6 at $4000: %s\n", BIT(head_mapper, 4) ? "Yes" : "No");
logerror( "\t\tbanked RAM: %s\n", BIT(head_mapper, 5) ? "Yes" : "No");
+ logerror( "\t\tPOKEY at $450: %s\n", BIT(head_mapper, 6) ? "Yes" : "No");
logerror( "\t\tSpecial: %s ", (head_mapper & 0xff00) ? "Yes" : "No");
if (head_mapper & 0xff00)
{
diff --git a/src/devices/bus/coco/coco_dwsock.cpp b/src/devices/bus/coco/coco_dwsock.cpp
index 2750f266998..fb2e18a23fb 100644
--- a/src/devices/bus/coco/coco_dwsock.cpp
+++ b/src/devices/bus/coco/coco_dwsock.cpp
@@ -68,14 +68,13 @@ beckerport_device::beckerport_device(const machine_config &mconfig, const char *
: device_t(mconfig, COCO_DWSOCK, "Virtual Becker Port", tag, owner, clock, "coco_dwsock", __FILE__), m_hostname(nullptr),
m_dwconfigport(*this, DRIVEWIRE_PORT_TAG), m_dwtcpport(0)
{
- m_pSocket = nullptr;
m_head = 0;
m_rx_pending = 0;
}
beckerport_device::~beckerport_device()
{
- if (m_pSocket != nullptr)
+ if (m_pSocket)
beckerport_device::device_stop();
}
@@ -93,8 +92,8 @@ void beckerport_device::device_start(void)
osd_printf_verbose("Connecting to Drivewire server on %s:%d... ", m_hostname, m_dwtcpport);
UINT64 filesize; // unused
- file_error filerr = osd_open(chAddress, 0, &m_pSocket, &filesize);
- if (filerr != FILERR_NONE)
+ osd_file::error filerr = osd_file::open(chAddress, 0, m_pSocket, filesize);
+ if (filerr != osd_file::error::NONE)
{
osd_printf_verbose("Error: osd_open returned error %i!\n", (int) filerr);
return;
@@ -109,11 +108,10 @@ void beckerport_device::device_start(void)
void beckerport_device::device_stop(void)
{
- if (m_pSocket != nullptr)
+ if (m_pSocket)
{
printf("Closing connection to Drivewire server\n");
- osd_close(m_pSocket);
- m_pSocket = nullptr;
+ m_pSocket.reset();
}
}
@@ -135,7 +133,7 @@ READ8_MEMBER(beckerport_device::read)
{
unsigned char data = 0x5a;
- if (m_pSocket == nullptr)
+ if (!m_pSocket)
return data;
switch (offset)
@@ -144,9 +142,9 @@ READ8_MEMBER(beckerport_device::read)
if (!m_rx_pending)
{
/* Try to read from dws */
- file_error filerr = osd_read(m_pSocket, m_buf, 0, sizeof(m_buf), &m_rx_pending);
- if (filerr != FILERR_NONE && filerr != FILERR_FAILURE) // FILERR_FAILURE means no data available, so don't throw error message
- fprintf(stderr, "coco_dwsock.c: beckerport_device::read() socket read operation failed with file_error %i\n", filerr);
+ osd_file::error filerr = m_pSocket->read(m_buf, 0, sizeof(m_buf), m_rx_pending);
+ if (filerr != osd_file::error::NONE && filerr != osd_file::error::FAILURE) // osd_file::error::FAILURE means no data available, so don't throw error message
+ fprintf(stderr, "coco_dwsock.c: beckerport_device::read() socket read operation failed with osd_file::error %i\n", int(filerr));
else
m_head = 0;
}
@@ -175,10 +173,11 @@ READ8_MEMBER(beckerport_device::read)
WRITE8_MEMBER(beckerport_device::write)
{
- char d = (char)data;
- file_error filerr;
+ char d = char(data);
+ osd_file::error filerr;
+ std::uint32_t written;
- if (m_pSocket == nullptr)
+ if (!m_pSocket)
return;
switch (offset)
@@ -187,9 +186,9 @@ WRITE8_MEMBER(beckerport_device::write)
//printf("beckerport_write: error: write (0x%02x) to status register\n", d);
break;
case DWS_DATA:
- filerr = osd_write(m_pSocket, &d, 0, 1, nullptr);
- if (filerr != FILERR_NONE)
- fprintf(stderr, "coco_dwsock.c: beckerport_device::write() socket write operation failed with file_error %i\n", filerr);
+ filerr = m_pSocket->write(&d, 0, 1, written);
+ if (filerr != osd_file::error::NONE)
+ fprintf(stderr, "coco_dwsock.c: beckerport_device::write() socket write operation failed with osd_file::error %i\n", int(filerr));
//printf("beckerport_write: data write one byte (0x%02x)\n", d & 0xff);
break;
default:
diff --git a/src/devices/bus/coco/coco_dwsock.h b/src/devices/bus/coco/coco_dwsock.h
index 1d1fe71c3d3..d3af3fbb525 100644
--- a/src/devices/bus/coco/coco_dwsock.h
+++ b/src/devices/bus/coco/coco_dwsock.h
@@ -57,7 +57,7 @@ private:
required_ioport m_dwconfigport;
int m_dwtcpport;
- osd_file *m_pSocket;
+ osd_file::ptr m_pSocket;
unsigned int m_rx_pending;
unsigned int m_head;
diff --git a/src/devices/bus/gba/gba_slot.cpp b/src/devices/bus/gba/gba_slot.cpp
index 10c5d45a0a8..737ff5fa6ed 100644
--- a/src/devices/bus/gba/gba_slot.cpp
+++ b/src/devices/bus/gba/gba_slot.cpp
@@ -295,17 +295,17 @@ int gba_cart_slot_device::get_cart_type(UINT8 *ROM, UINT32 len)
// first detect nvram type based on strings inside the file
for (int i = 0; i < len; i++)
{
- if (!memcmp(&ROM[i], "EEPROM_V", 8))
+ if ((i<len-8) && !memcmp(&ROM[i], "EEPROM_V", 8))
chip |= GBA_CHIP_EEPROM; // should be either GBA_CHIP_EEPROM_4K or GBA_CHIP_EEPROM_64K, but it is not yet possible to automatically detect which one
- else if ((!memcmp(&ROM[i], "SRAM_V", 6)) || (!memcmp(&ROM[i], "SRAM_F_V", 8))) // || (!memcmp(&data[i], "ADVANCEWARS", 11))) //advance wars 1 & 2 has SRAM, but no "SRAM_" string can be found inside the ROM space
+ else if (((i<len-6) && !memcmp(&ROM[i], "SRAM_V", 6)) || ((i<len-8) && !memcmp(&ROM[i], "SRAM_F_V", 8))) // || ((i<len-11) && !memcmp(&data[i], "ADVANCEWARS", 11))) //advance wars 1 & 2 has SRAM, but no "SRAM_" string can be found inside the ROM space
chip |= GBA_CHIP_SRAM;
- else if (!memcmp(&ROM[i], "FLASH1M_V", 9))
+ else if ((i<len-9) && !memcmp(&ROM[i], "FLASH1M_V", 9))
chip |= GBA_CHIP_FLASH_1M;
- else if (!memcmp(&ROM[i], "FLASH512_V", 10))
+ else if ((i<len-10) && !memcmp(&ROM[i], "FLASH512_V", 10))
chip |= GBA_CHIP_FLASH_512;
- else if (!memcmp(&ROM[i], "FLASH_V", 7))
+ else if ((i<len-7) && !memcmp(&ROM[i], "FLASH_V", 7))
chip |= GBA_CHIP_FLASH;
- else if (!memcmp(&ROM[i], "SIIRTC_V", 8))
+ else if ((i<len-8) && !memcmp(&ROM[i], "SIIRTC_V", 8))
chip |= GBA_CHIP_RTC;
}
osd_printf_info("GBA: Detected (ROM) %s\n", gba_chip_string(chip).c_str());
diff --git a/src/devices/bus/iq151/minigraf.cpp b/src/devices/bus/iq151/minigraf.cpp
index 1a8e9d182a0..14cd9515cf7 100644
--- a/src/devices/bus/iq151/minigraf.cpp
+++ b/src/devices/bus/iq151/minigraf.cpp
@@ -78,9 +78,9 @@ void iq151_minigraf_device::device_stop()
{
#if DUMP_PAPER_INTO_PNG
emu_file file(machine().options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
- file_error filerr = file.open("iq151_minigraf.png");
+ auto const filerr = file.open("iq151_minigraf.png");
- if (filerr == FILERR_NONE)
+ if (filerr == osd_file::error::NONE)
{
static const rgb_t png_palette[] = { rgb_t::white, rgb_t::black };
diff --git a/src/devices/bus/iq151/ms151a.cpp b/src/devices/bus/iq151/ms151a.cpp
index 99da92c6d61..c3aedf5f07d 100644
--- a/src/devices/bus/iq151/ms151a.cpp
+++ b/src/devices/bus/iq151/ms151a.cpp
@@ -77,9 +77,9 @@ void iq151_ms151a_device::device_stop()
{
#if DUMP_PAPER_INTO_PNG
emu_file file(machine().options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
- file_error filerr = file.open("iq151_ms151a.png");
+ osd_file::error filerr = file.open("iq151_ms151a.png");
- if (filerr == FILERR_NONE)
+ if (filerr == osd_file::error::NONE)
{
static const rgb_t png_palette[] = { rgb_t::white, rgb_t::black };
diff --git a/src/devices/bus/isa/isa.cpp b/src/devices/bus/isa/isa.cpp
index 0d8f0c777e1..9b07bdce8e0 100644
--- a/src/devices/bus/isa/isa.cpp
+++ b/src/devices/bus/isa/isa.cpp
@@ -54,7 +54,7 @@ void isa8_slot_device::device_start()
device_isa8_card_interface *dev = dynamic_cast<device_isa8_card_interface *>(get_card_device());
const device_isa16_card_interface *intf;
if (get_card_device()->interface(intf))
- fatalerror("Error ISA16 device in ISA8 slot\n");
+ fatalerror("ISA16 device in ISA8 slot\n");
if (dev) device_isa8_card_interface::static_set_isabus(*dev,m_owner->subdevice(m_isa_tag));
}
diff --git a/src/devices/bus/isa/sblaster.cpp b/src/devices/bus/isa/sblaster.cpp
index 6895716c7af..20dd6c6b2ed 100644
--- a/src/devices/bus/isa/sblaster.cpp
+++ b/src/devices/bus/isa/sblaster.cpp
@@ -1069,6 +1069,118 @@ WRITE8_MEMBER( sb16_device::mixer_w )
return;
}
+void sb8_device::drq_w(int state)
+{
+ switch(m_config->read() & 0x0c)
+ {
+ case 0:
+ default:
+ m_isa->drq1_w(state);
+ break;
+ case 4:
+ m_isa->drq3_w(state);
+ break;
+ }
+}
+
+void sb8_device::irq_w(int state, int source)
+{
+ switch(m_config->read() & 0x03)
+ {
+ case 0:
+ default:
+ m_isa->irq5_w(state);
+ break;
+ case 1:
+ m_isa->irq7_w(state);
+ break;
+ }
+}
+
+// TODO: sb16 irq/drq is software set
+void sb16_device::drq_w(int state)
+{
+ switch(m_config->read() & 0x0c)
+ {
+ case 0:
+ default:
+ m_isa->drq1_w(state);
+ break;
+ case 4:
+ m_isa->drq3_w(state);
+ break;
+ }
+}
+
+void sb16_device::irq_w(int state, int source)
+{
+ if(state)
+ m_dsp.irq_active |= source;
+ else
+ m_dsp.irq_active &= ~source;
+
+ switch(m_config->read() & 0x03)
+ {
+ case 0:
+ default:
+ m_isa->irq5_w(m_dsp.irq_active != 0);
+ break;
+ case 1:
+ m_isa->irq7_w(m_dsp.irq_active != 0);
+ break;
+ }
+}
+
+void sb16_device::drq16_w(int state)
+{
+ switch(m_config->read() & 0xc0)
+ {
+ case 0:
+ default:
+ m_isa->drq5_w(state);
+ break;
+ case 0x40:
+ m_isa->drq6_w(state);
+ break;
+ case 0x80:
+ m_isa->drq7_w(state);
+ break;
+ }
+}
+
+static INPUT_PORTS_START( sb8 )
+ PORT_START("CONFIG")
+ PORT_CONFNAME(0x03, 0x00, "Default IRQ")
+ PORT_CONFSETTING( 0x00, "IRQ5")
+ PORT_CONFSETTING( 0x01, "IRQ7")
+ PORT_CONFNAME(0x0c, 0x00, "Default DMA")
+ PORT_CONFSETTING( 0x00, "DMA1")
+ PORT_CONFSETTING( 0x04, "DMA3")
+ //PORT_CONFNAME(0x30, 0x00, "Default Port Base")
+ //PORT_CONFSETTING( 0x00, "220")
+ //PORT_CONFSETTING( 0x10, "240")
+ //PORT_CONFSETTING( 0x20, "260")
+INPUT_PORTS_END
+
+static INPUT_PORTS_START( sb16 )
+ PORT_INCLUDE(sb8)
+ PORT_MODIFY("CONFIG")
+ PORT_CONFNAME(0xc0, 0x00, "Default DMA16")
+ PORT_CONFSETTING( 0x00, "DMA5")
+ PORT_CONFSETTING( 0x40, "DMA6")
+ PORT_CONFSETTING( 0x80, "DMA7")
+INPUT_PORTS_END
+
+ioport_constructor sb8_device::device_input_ports() const
+{
+ return INPUT_PORTS_NAME(sb8);
+}
+
+ioport_constructor sb16_device::device_input_ports() const
+{
+ return INPUT_PORTS_NAME(sb16);
+}
+
//**************************************************************************
// GLOBAL VARIABLES
//**************************************************************************
@@ -1107,7 +1219,8 @@ sb_device::sb_device(const machine_config &mconfig, device_type type, const char
m_dacl(*this, "sbdacl"),
m_dacr(*this, "sbdacr"),
m_joy(*this, "pc_joy"),
- m_mdout(*this, "mdout"), m_dack_out(0), m_onebyte_midi(false), m_uart_midi(false), m_uart_irq(false), m_mpu_midi(false), m_rx_waiting(0), m_tx_waiting(0), m_xmit_read(0), m_xmit_write(0), m_recv_read(0), m_recv_write(0), m_tx_busy(false), m_timer(nullptr)
+ m_mdout(*this, "mdout"),
+ m_config(*this, "CONFIG"), m_dack_out(0), m_onebyte_midi(false), m_uart_midi(false), m_uart_irq(false), m_mpu_midi(false), m_rx_waiting(0), m_tx_waiting(0), m_xmit_read(0), m_xmit_write(0), m_recv_read(0), m_recv_write(0), m_tx_busy(false), m_timer(nullptr)
{
}
diff --git a/src/devices/bus/isa/sblaster.h b/src/devices/bus/isa/sblaster.h
index 25bdc0f4b56..4481193c6fe 100644
--- a/src/devices/bus/isa/sblaster.h
+++ b/src/devices/bus/isa/sblaster.h
@@ -103,6 +103,7 @@ public:
required_device<dac_device> m_dacr;
required_device<pc_joy_device> m_joy;
required_device<midi_port_device> m_mdout;
+ required_ioport m_config;
void process_fifo(UINT8 cmd);
void queue(UINT8 data);
@@ -162,10 +163,11 @@ public:
DECLARE_READ8_MEMBER(ym3812_16_r);
DECLARE_WRITE8_MEMBER(ym3812_16_w);
+ virtual ioport_constructor device_input_ports() const override;
protected:
virtual void device_start() override;
- virtual void drq_w(int state) override { m_isa->drq1_w(state); }
- virtual void irq_w(int state, int source) override { m_isa->irq5_w(state); }
+ virtual void drq_w(int state) override;
+ virtual void irq_w(int state, int source) override;
virtual UINT8 dack_r(int line) override { return sb_device::dack_r(line); }
virtual void dack_w(int line, UINT8 data) override { sb_device::dack_w(line, data); }
private:
@@ -217,15 +219,16 @@ public:
DECLARE_WRITE8_MEMBER(mpu401_w);
DECLARE_READ8_MEMBER(mixer_r);
DECLARE_WRITE8_MEMBER(mixer_w);
+ virtual ioport_constructor device_input_ports() const override;
protected:
virtual void device_start() override;
virtual UINT16 dack16_r(int line) override;
virtual UINT8 dack_r(int line) override { return sb_device::dack_r(line); }
virtual void dack_w(int line, UINT8 data) override { sb_device::dack_w(line, data); }
virtual void dack16_w(int line, UINT16 data) override;
- virtual void drq16_w(int state) override { m_isa->drq5_w(state); }
- virtual void drq_w(int state) override { m_isa->drq1_w(state); }
- virtual void irq_w(int state, int source) override { (state?m_dsp.irq_active|=source:m_dsp.irq_active&=~source); m_isa->irq5_w(m_dsp.irq_active != 0); }
+ virtual void drq16_w(int state) override;
+ virtual void drq_w(int state) override;
+ virtual void irq_w(int state, int source) override;
virtual void mixer_reset() override;
void mixer_set();
virtual void rcv_complete() override; // Rx completed receiving byte
diff --git a/src/devices/bus/isa/trident.cpp b/src/devices/bus/isa/trident.cpp
index 4f47bdd7212..b97f35abc78 100644
--- a/src/devices/bus/isa/trident.cpp
+++ b/src/devices/bus/isa/trident.cpp
@@ -12,18 +12,31 @@
#include "trident.h"
#include "debugger.h"
-const device_type TRIDENT_VGA = &device_creator<trident_vga_device>;
+const device_type TRIDENT_VGA = &device_creator<tgui9860_device>;
+const device_type TVGA9000_VGA = &device_creator<tvga9000_device>;
#define CRTC_PORT_ADDR ((vga.miscellaneous_output&1)?0x3d0:0x3b0)
#define LOG (1)
#define LOG_ACCEL (1)
-trident_vga_device::trident_vga_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
- : svga_device(mconfig, TRIDENT_VGA, "Trident TGUI9680", tag, owner, clock, "trident_vga", __FILE__)
+trident_vga_device::trident_vga_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source)
+ : svga_device(mconfig, type, name, tag, owner, clock, shortname, source)
{
}
+tgui9860_device::tgui9860_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : trident_vga_device(mconfig, TRIDENT_VGA, "Trident TGUI9680", tag, owner, clock, "trident_vga", __FILE__)
+{
+ m_version = 0xd3; // 0xd3 identifies at TGUI9660XGi (set to 0xe3 to identify at TGUI9440AGi)
+}
+
+tvga9000_device::tvga9000_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : trident_vga_device(mconfig, TVGA9000_VGA, "Trident TVGA9000", tag, owner, clock, "tvga9000_vga", __FILE__)
+{
+ m_version = 0x43;
+}
+
UINT8 trident_vga_device::READPIXEL8(INT16 x, INT16 y)
{
return (vga.memory[((y & 0xfff)*offset() + (x & 0xfff)) % vga.svga_intf.vram_size]);
@@ -174,7 +187,7 @@ void trident_vga_device::device_start()
void trident_vga_device::device_reset()
{
svga_device::device_reset();
- svga.id = 0xd3; // 0xd3 identifies at TGUI9660XGi (set to 0xe3 to identify at TGUI9440AGi)
+ svga.id = m_version;
tri.revision = 0x01; // revision identifies as TGUI9680
tri.new_mode = false; // start up in old mode
tri.dac_active = false;
@@ -191,6 +204,7 @@ void trident_vga_device::device_reset()
// Windows 3.1 TGUI9440AGi drivers do not set the pointer colour registers?
tri.cursor_bg = 0x00000000;
tri.cursor_fg = 0xffffffff;
+ tri.pixel_depth = 0x10; //disable 8bpp mode by default
}
UINT32 trident_vga_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
@@ -376,11 +390,14 @@ void trident_vga_device::trident_define_video_mode()
switch((tri.pixel_depth & 0x0c) >> 2)
{
case 0:
- default: if(!(tri.pixel_depth & 0x10)) svga.rgb8_en = 1; break;
+ default: if(!(tri.pixel_depth & 0x10) || (tri.cr1e & 0x80)) svga.rgb8_en = 1; break;
case 1: if((tri.dac & 0xf0) == 0x30) svga.rgb16_en = 1; else svga.rgb15_en = 1; break;
case 2: svga.rgb32_en = 1; break;
}
+ if((tri.cr1e & 0x80) && (svga.id == 0x43))
+ divisor = 2;
+
recompute_params_clock(divisor, xtal);
}
@@ -443,7 +460,6 @@ void trident_vga_device::trident_seq_reg_write(UINT8 index, UINT8 data)
}
else
{
- if(LOG) logerror("Trident SR%02X: %s mode write %02x\n",index,tri.new_mode ? "new" : "old",data);
switch(index)
{
case 0x0b:
@@ -490,6 +506,7 @@ void trident_vga_device::trident_seq_reg_write(UINT8 index, UINT8 data)
if(!LOG) logerror("Trident: Sequencer index %02x read\n",index);
}
}
+ if(LOG) logerror("Trident SR%02X: %s mode write %02x\n",index,tri.new_mode ? "new" : "old",data);
}
UINT8 trident_vga_device::trident_crtc_reg_read(UINT8 index)
@@ -605,7 +622,6 @@ void trident_vga_device::trident_crtc_reg_write(UINT8 index, UINT8 data)
}
else
{
- if(LOG) logerror("Trident CR%02X: write %02x\n",index,data);
switch(index)
{
case 0x1e: // Module Testing Register
@@ -704,6 +720,7 @@ void trident_vga_device::trident_crtc_reg_write(UINT8 index, UINT8 data)
break;
}
}
+ if(LOG) logerror("Trident CR%02X: write %02x\n",index,data);
}
UINT8 trident_vga_device::trident_gc_reg_read(UINT8 index)
@@ -764,6 +781,7 @@ void trident_vga_device::trident_gc_reg_write(UINT8 index, UINT8 data)
break;
}
}
+ if(LOG) logerror("Trident GC%02X: write %02x\n",index,data);
}
READ8_MEMBER(trident_vga_device::port_03c0_r)
diff --git a/src/devices/bus/isa/trident.h b/src/devices/bus/isa/trident.h
index db470ec2838..47ba8d3f8e4 100644
--- a/src/devices/bus/isa/trident.h
+++ b/src/devices/bus/isa/trident.h
@@ -16,7 +16,7 @@ class trident_vga_device : public svga_device
{
public:
// construction/destruction
- trident_vga_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+ trident_vga_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source);
virtual READ8_MEMBER(port_03c0_r) override;
virtual WRITE8_MEMBER(port_03c0_w) override;
@@ -113,6 +113,7 @@ protected:
INT16 accel_mem_y;
UINT32 accel_transfer;
} tri;
+ UINT8 m_version;
private:
UINT8 trident_seq_reg_read(UINT8 index);
void trident_seq_reg_write(UINT8 index, UINT8 data);
@@ -146,8 +147,20 @@ private:
UINT32 handle_rop(UINT32 src, UINT32 dst);
};
+class tgui9860_device : public trident_vga_device
+{
+public:
+ tgui9860_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+};
+
+class tvga9000_device : public trident_vga_device
+{
+public:
+ tvga9000_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+};
// device type definition
extern const device_type TRIDENT_VGA;
+extern const device_type TVGA9000_VGA;
#endif /* TRIDENT_H_ */
diff --git a/src/devices/bus/nubus/nubus_image.cpp b/src/devices/bus/nubus/nubus_image.cpp
index 412925fc351..d7752e3babc 100644
--- a/src/devices/bus/nubus/nubus_image.cpp
+++ b/src/devices/bus/nubus/nubus_image.cpp
@@ -310,7 +310,7 @@ WRITE32_MEMBER( nubus_image_device::file_cmd_w )
strcpy(fullpath, (const char *)filectx.curdir);
strcat(fullpath, "/");
strcat(fullpath, (const char*)filectx.filename);
- if(osd_open((const char*)fullpath, OPEN_FLAG_READ, &filectx.fd, &filectx.filelen) != FILERR_NONE) printf("Error opening %s\n", fullpath);
+ if(osd_file::open(std::string(fullpath), OPEN_FLAG_READ, filectx.fd, filectx.filelen) != osd_file::error::NONE) printf("Error opening %s\n", fullpath);
filectx.bytecount = 0;
break;
case kFileCmdPutFile:
@@ -318,7 +318,7 @@ WRITE32_MEMBER( nubus_image_device::file_cmd_w )
strcpy(fullpath, (const char *)filectx.curdir);
strcat(fullpath, "/");
strcat(fullpath, (const char*)filectx.filename);
- if(osd_open((const char*)fullpath, OPEN_FLAG_WRITE|OPEN_FLAG_CREATE, &filectx.fd, &filesize) != FILERR_NONE) printf("Error opening %s\n", fullpath);
+ if(osd_file::open(std::string(fullpath), OPEN_FLAG_WRITE|OPEN_FLAG_CREATE, filectx.fd, filesize) != osd_file::error::NONE) printf("Error opening %s\n", fullpath);
filectx.bytecount = 0;
break;
}
@@ -331,33 +331,31 @@ READ32_MEMBER( nubus_image_device::file_cmd_r )
WRITE32_MEMBER( nubus_image_device::file_data_w )
{
- UINT32 count = 4;
- UINT32 actualcount = 0;
+ std::uint32_t count = 4;
+ std::uint32_t actualcount = 0;
data = ((data & 0xff) << 24) | ((data & 0xff00) << 8) | ((data & 0xff0000) >> 8) | ((data & 0xff000000) >> 24);
- if(filectx.fd != nullptr) {
+ if(filectx.fd) {
//data = ni_ntohl(data);
if((filectx.bytecount + count) > filectx.filelen) count = filectx.filelen - filectx.bytecount;
- osd_write(filectx.fd, &data, filectx.bytecount, count, &actualcount);
+ filectx.fd->write(&data, filectx.bytecount, count, actualcount);
filectx.bytecount += actualcount;
if(filectx.bytecount >= filectx.filelen) {
- osd_close(filectx.fd);
- filectx.fd = nullptr;
+ filectx.fd.reset();
}
}
}
READ32_MEMBER( nubus_image_device::file_data_r )
{
- if(filectx.fd != nullptr) {
- UINT32 ret;
- UINT32 actual = 0;
- osd_read(filectx.fd, &ret, filectx.bytecount, sizeof(ret), &actual);
+ if(filectx.fd) {
+ std::uint32_t ret;
+ std::uint32_t actual = 0;
+ filectx.fd->read(&ret, filectx.bytecount, sizeof(ret), actual);
filectx.bytecount += actual;
if(actual < sizeof(ret)) {
- osd_close(filectx.fd);
- filectx.fd = nullptr;
+ filectx.fd.reset();
}
return ni_htonl(ret);
}
diff --git a/src/devices/bus/nubus/nubus_image.h b/src/devices/bus/nubus/nubus_image.h
index d850b3f7735..dda6e55fc02 100644
--- a/src/devices/bus/nubus/nubus_image.h
+++ b/src/devices/bus/nubus/nubus_image.h
@@ -19,7 +19,7 @@ struct nbfilectx {
UINT8 filename[128];
UINT8 curdir[1024];
osd_directory *dirp;
- osd_file *fd;
+ osd_file::ptr fd;
UINT64 filelen;
UINT32 bytecount;
};
diff --git a/src/devices/bus/pc_joy/pc_joy.cpp b/src/devices/bus/pc_joy/pc_joy.cpp
index 14c2b99e8a1..bf530eb6ab5 100644
--- a/src/devices/bus/pc_joy/pc_joy.cpp
+++ b/src/devices/bus/pc_joy/pc_joy.cpp
@@ -33,6 +33,8 @@ READ8_MEMBER ( pc_joy_device::joy_port_r )
WRITE8_MEMBER ( pc_joy_device::joy_port_w )
{
m_stime = machine().time();
+ if(!m_dev)
+ return;
m_dev->port_write();
}
diff --git a/src/devices/bus/sega8/mgear.cpp b/src/devices/bus/sega8/mgear.cpp
index d6b8c91c6cf..83835925198 100644
--- a/src/devices/bus/sega8/mgear.cpp
+++ b/src/devices/bus/sega8/mgear.cpp
@@ -2,14 +2,20 @@
// copyright-holders:Fabio Priuli
/***********************************************************************************************************
- Master Gear Adapter emulation
+ Master Gear Converter emulation
***********************************************************************************************************/
+// The Master Gear Converter, also known as Master Gear, Gear Master Converter
+// or (in Brazil) as Master Gear Adaptor, allows to plug western SMS cartridges
+// on the Game Gear, by enabling the SMS compatibility mode on the Game Gear
+// cartridge slot. Some SMS games have compatibility issues, confirmed on the
+// real hardware, when run on the Game Gear.
+
#include "emu.h"
#include "mgear.h"
-
+#include "softlist.h"
//-------------------------------------------------
// constructors
@@ -18,7 +24,7 @@
const device_type SEGA8_ROM_MGEAR = &device_creator<sega8_mgear_device>;
sega8_mgear_device::sega8_mgear_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
- : sega8_rom_device(mconfig, SEGA8_ROM_MGEAR, "Master Gear Adapter", tag, owner, clock, "sega8_mgear", __FILE__),
+ : sega8_rom_device(mconfig, SEGA8_ROM_MGEAR, "Master Gear Converter", tag, owner, clock, "sega8_mgear", __FILE__),
m_subslot(*this, "subslot")
{
}
@@ -38,6 +44,7 @@ void sega8_mgear_device::device_reset()
static MACHINE_CONFIG_FRAGMENT( sub_slot )
MCFG_SMS_CARTRIDGE_ADD("subslot", sms_cart, nullptr)
+ MCFG_SOFTWARE_LIST_ADD("cart_list","sms")
MACHINE_CONFIG_END
machine_config_constructor sega8_mgear_device::device_mconfig_additions() const
diff --git a/src/devices/bus/sms_ctrl/rfu.cpp b/src/devices/bus/sms_ctrl/rfu.cpp
index 2b43b31a6b8..0ccc5ae4e9c 100644
--- a/src/devices/bus/sms_ctrl/rfu.cpp
+++ b/src/devices/bus/sms_ctrl/rfu.cpp
@@ -6,6 +6,9 @@
**********************************************************************/
+// This emulated device is the version released by Sega. In Brazil, Tec Toy
+// released a version that does not have any switch to turn on/off auto-repeat.
+
#include "rfu.h"
@@ -16,7 +19,7 @@
const device_type SMS_RAPID_FIRE = &device_creator<sms_rapid_fire_device>;
-
+// time interval not verified
#define RAPID_FIRE_INTERVAL attotime::from_hz(10)
diff --git a/src/devices/bus/sms_ctrl/sports.cpp b/src/devices/bus/sms_ctrl/sports.cpp
index 68a2b142eec..77356cec41f 100644
--- a/src/devices/bus/sms_ctrl/sports.cpp
+++ b/src/devices/bus/sms_ctrl/sports.cpp
@@ -7,11 +7,17 @@
**********************************************************************/
// The games designed for the US model of the Sports Pad controller use the
-// TH line of the controller port as output, to select which nibble, of the
-// two axis bytes, will be read at a time. The Japanese cartridge Sports Pad
-// Soccer uses a different mode, because the Sega Mark III lacks TH output, so
+// TH line of the controller port to select which nibble, of the two axis
+// bytes, will be read at a time. The Japanese cartridge Sports Pad Soccer
+// uses a different mode, because the Sega Mark III lacks the TH line, so
// there is a different Sports Pad model released in Japan (see sportsjp.c).
+// The Japanese SMS has the TH line connected, but doesn't report TH input
+// on port 0xDD. However, a magazine raffled the US Sports Pad along with a
+// Great Ice Hockey cartridge, in Japanese format, to owners of that console.
+// So, Great Ice Hockey seems to just need TH pin as output to work, while
+// other games designed for the US Sports Pad don't work on the Japanese SMS.
+
// It was discovered that games designed for the Paddle Controller, released
// in Japan, switch to a mode incompatible with the original Paddle when
// detect the system region as Export. Similar to how the US model of the
diff --git a/src/devices/bus/sms_ctrl/sportsjp.cpp b/src/devices/bus/sms_ctrl/sportsjp.cpp
index 260654c7dac..16c5198721c 100644
--- a/src/devices/bus/sms_ctrl/sportsjp.cpp
+++ b/src/devices/bus/sms_ctrl/sportsjp.cpp
@@ -8,7 +8,7 @@
// The Japanese Sports Pad controller is only required to play the cartridge
// Sports Pad Soccer, released in Japan. It uses a different mode than the
-// used by the US model, due to missing output lines on Sega Mark III
+// used by the US model, due to the missing TH line on Sega Mark III
// controller ports.
#include "sportsjp.h"
diff --git a/src/devices/bus/sms_ctrl/sportsjp.h b/src/devices/bus/sms_ctrl/sportsjp.h
index c20f15bd845..ad438d12bb1 100644
--- a/src/devices/bus/sms_ctrl/sportsjp.h
+++ b/src/devices/bus/sms_ctrl/sportsjp.h
@@ -6,11 +6,6 @@
**********************************************************************/
-// The Japanese Sports Pad controller is only required to play the cartridge
-// Sports Pad Soccer, released in Japan. It uses a different mode than the
-// used by the US model, due to missing output lines on Sega Mark III
-// controller ports.
-
#pragma once
#ifndef __SMS_SPORTS_PAD_JP__
diff --git a/src/devices/bus/sms_exp/gender.cpp b/src/devices/bus/sms_exp/gender.cpp
index 7ca7ff48a47..3de8961050c 100644
--- a/src/devices/bus/sms_exp/gender.cpp
+++ b/src/devices/bus/sms_exp/gender.cpp
@@ -6,6 +6,13 @@
**********************************************************************/
+// The Gender Adapter is not an official Sega product. It is produced by the
+// SMSPower website to permit to plug a cartridge on the expansion slot on any
+// SMS 1 model. This includes the Japanese SMS, which has FM sound, so it is
+// a way to get FM music of western cartridges that have FM code but were not
+// released in Japan. Some games have compatibility issues, confirmed on the
+// real hardware, when run plugged-in to the SMS expansion slot.
+
#include "gender.h"
diff --git a/src/devices/bus/svi3x8/expander/expander.cpp b/src/devices/bus/svi3x8/expander/expander.cpp
new file mode 100644
index 00000000000..faddf3f24ac
--- /dev/null
+++ b/src/devices/bus/svi3x8/expander/expander.cpp
@@ -0,0 +1,151 @@
+// license:GPL-2.0+
+// copyright-holders:Dirk Best
+/***************************************************************************
+
+ SVI 318/328 Expansion Slot
+
+ 50-pin slot
+
+***************************************************************************/
+
+#include "expander.h"
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type SVI_EXPANDER = &device_creator<svi_expander_device>;
+
+
+//**************************************************************************
+// SLOT DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// svi_expander_device - constructor
+//-------------------------------------------------
+
+svi_expander_device::svi_expander_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, SVI_EXPANDER, "SVI 318/328 Expander Bus", tag, owner, clock, "svi_expander", __FILE__),
+ device_slot_interface(mconfig, *this),
+ m_module(nullptr),
+ m_int_handler(*this),
+ m_romdis_handler(*this),
+ m_ramdis_handler(*this),
+ m_ctrl1_handler(*this),
+ m_ctrl2_handler(*this)
+{
+}
+
+//-------------------------------------------------
+// svi_expander_device - destructor
+//-------------------------------------------------
+
+svi_expander_device::~svi_expander_device()
+{
+}
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void svi_expander_device::device_start()
+{
+ // get inserted module
+ m_module = dynamic_cast<device_svi_expander_interface *>(get_card_device());
+
+ // resolve callbacks
+ m_int_handler.resolve_safe();
+ m_romdis_handler.resolve_safe();
+ m_ramdis_handler.resolve_safe();
+ m_ctrl1_handler.resolve_safe();
+ m_ctrl2_handler.resolve_safe();
+}
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void svi_expander_device::device_reset()
+{
+}
+
+//-------------------------------------------------
+// host to module interface
+//-------------------------------------------------
+
+READ8_MEMBER( svi_expander_device::mreq_r )
+{
+ if (m_module)
+ return m_module->mreq_r(space, offset);
+
+ return 0xff;
+}
+
+WRITE8_MEMBER( svi_expander_device::mreq_w )
+{
+ if (m_module)
+ m_module->mreq_w(space, offset, data);
+}
+
+READ8_MEMBER( svi_expander_device::iorq_r )
+{
+ if (m_module)
+ return m_module->iorq_r(space, offset);
+
+ return 0xff;
+}
+
+WRITE8_MEMBER( svi_expander_device::iorq_w )
+{
+ if (m_module)
+ m_module->iorq_w(space, offset, data);
+}
+
+WRITE_LINE_MEMBER( svi_expander_device::bk21_w )
+{
+ if (m_module)
+ m_module->bk21_w(state);
+}
+
+WRITE_LINE_MEMBER( svi_expander_device::bk22_w )
+{
+ if (m_module)
+ m_module->bk22_w(state);
+}
+
+WRITE_LINE_MEMBER( svi_expander_device::bk31_w )
+{
+ if (m_module)
+ m_module->bk31_w(state);
+}
+
+WRITE_LINE_MEMBER( svi_expander_device::bk32_w )
+{
+ if (m_module)
+ m_module->bk32_w(state);
+}
+
+
+//**************************************************************************
+// CARTRIDGE INTERFACE
+//**************************************************************************
+
+//-------------------------------------------------
+// device_svi_expander_interface - constructor
+//-------------------------------------------------
+
+device_svi_expander_interface::device_svi_expander_interface(const machine_config &mconfig, device_t &device) :
+ device_slot_card_interface(mconfig, device)
+{
+ m_expander = dynamic_cast<svi_expander_device *>(device.owner());
+}
+
+//-------------------------------------------------
+// ~device_expansion_interface - destructor
+//-------------------------------------------------
+
+device_svi_expander_interface::~device_svi_expander_interface()
+{
+}
diff --git a/src/devices/bus/svi3x8/expander/expander.h b/src/devices/bus/svi3x8/expander/expander.h
new file mode 100644
index 00000000000..a2bed1f609b
--- /dev/null
+++ b/src/devices/bus/svi3x8/expander/expander.h
@@ -0,0 +1,162 @@
+// license:GPL-2.0+
+// copyright-holders:Dirk Best
+/***************************************************************************
+
+ SVI 318/328 Expander Slot
+
+ 50-pin slot
+
+ 1 +5V 2 /CNTRL2
+ 3 +12V 4 -12V
+ 5 /CNTRL1 6 /WAIT
+ 7 /RST 8 CPUCLK
+ 9 A15 10 A14
+ 11 A13 12 A12
+ 13 A11 14 A10
+ 15 A9 16 A8
+ 17 A7 18 A6
+ 19 A5 20 A4
+ 21 A3 22 A2
+ 23 A1 24 A0
+ 25 /RFSH 26 /EXCSR
+ 27 /M1 28 /EXCSW
+ 29 /WR 30 /MREQ
+ 31 /IORQ 32 /RD
+ 33 D0 34 D1
+ 35 D2 36 D3
+ 37 D4 38 D5
+ 39 D6 40 D7
+ 41 CSOUND 42 /INT
+ 43 /RAMDIS 44 /ROMDIS
+ 45 /BK32 46 /BK31
+ 47 /BK22 48 /BK21
+ 49 GND 50 GND
+
+***************************************************************************/
+
+#pragma once
+
+#ifndef __SVI3X8_EXPANDER_H__
+#define __SVI3X8_EXPANDER_H__
+
+#include "emu.h"
+
+
+//**************************************************************************
+// INTERFACE CONFIGURATION MACROS
+//**************************************************************************
+
+#define MCFG_SVI_EXPANDER_BUS_ADD(_tag) \
+ MCFG_DEVICE_ADD(_tag, SVI_EXPANDER, 0) \
+ MCFG_DEVICE_SLOT_INTERFACE(svi_expander_modules, NULL, false) \
+
+#define MCFG_SVI_EXPANDER_INT_HANDLER(_devcb) \
+ devcb = &svi_expander_device::set_int_handler(*device, DEVCB_##_devcb);
+
+#define MCFG_SVI_EXPANDER_ROMDIS_HANDLER(_devcb) \
+ devcb = &svi_expander_device::set_romdis_handler(*device, DEVCB_##_devcb);
+
+#define MCFG_SVI_EXPANDER_RAMDIS_HANDLER(_devcb) \
+ devcb = &svi_expander_device::set_ramdis_handler(*device, DEVCB_##_devcb);
+
+#define MCFG_SVI_EXPANDER_CTRL1_HANDLER(_devcb) \
+ devcb = &svi_expander_device::set_ctrl1_handler(*device, DEVCB_##_devcb);
+
+#define MCFG_SVI_EXPANDER_CTRL2_HANDLER(_devcb) \
+ devcb = &svi_expander_device::set_ctrl2_handler(*device, DEVCB_##_devcb);
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+class device_svi_expander_interface;
+
+// ======================> svi_expander_device
+
+class svi_expander_device : public device_t, public device_slot_interface
+{
+public:
+ // construction/destruction
+ svi_expander_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+ virtual ~svi_expander_device();
+
+ // callbacks
+ template<class _Object> static devcb_base &set_int_handler(device_t &device, _Object object)
+ { return downcast<svi_expander_device &>(device).m_int_handler.set_callback(object); }
+
+ template<class _Object> static devcb_base &set_romdis_handler(device_t &device, _Object object)
+ { return downcast<svi_expander_device &>(device).m_romdis_handler.set_callback(object); }
+
+ template<class _Object> static devcb_base &set_ramdis_handler(device_t &device, _Object object)
+ { return downcast<svi_expander_device &>(device).m_ramdis_handler.set_callback(object); }
+
+ template<class _Object> static devcb_base &set_ctrl1_handler(device_t &device, _Object object)
+ { return downcast<svi_expander_device &>(device).m_ctrl1_handler.set_callback(object); }
+
+ template<class _Object> static devcb_base &set_ctrl2_handler(device_t &device, _Object object)
+ { return downcast<svi_expander_device &>(device).m_ctrl2_handler.set_callback(object); }
+
+ // called from cart device
+ DECLARE_WRITE_LINE_MEMBER( int_w ) { m_int_handler(state); }
+ DECLARE_WRITE_LINE_MEMBER( romdis_w ) { m_romdis_handler(state); }
+ DECLARE_WRITE_LINE_MEMBER( ramdis_w ) { m_ramdis_handler(state); }
+ DECLARE_WRITE_LINE_MEMBER( ctrl1_w ) { m_ctrl1_handler(state); }
+ DECLARE_WRITE_LINE_MEMBER( ctrl2_w ) { m_ctrl2_handler(state); }
+
+ // called from host
+ DECLARE_READ8_MEMBER( mreq_r );
+ DECLARE_WRITE8_MEMBER( mreq_w );
+ DECLARE_READ8_MEMBER( iorq_r );
+ DECLARE_WRITE8_MEMBER( iorq_w );
+
+ DECLARE_WRITE_LINE_MEMBER( bk21_w );
+ DECLARE_WRITE_LINE_MEMBER( bk22_w );
+ DECLARE_WRITE_LINE_MEMBER( bk31_w );
+ DECLARE_WRITE_LINE_MEMBER( bk32_w );
+
+protected:
+ // device-level overrides
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+private:
+ device_svi_expander_interface *m_module;
+
+ devcb_write_line m_int_handler;
+ devcb_write_line m_romdis_handler;
+ devcb_write_line m_ramdis_handler;
+ devcb_write_line m_ctrl1_handler;
+ devcb_write_line m_ctrl2_handler;
+};
+
+// ======================> device_svi_expander_interface
+
+class device_svi_expander_interface : public device_slot_card_interface
+{
+public:
+ // construction/destruction
+ device_svi_expander_interface(const machine_config &mconfig, device_t &device);
+ virtual ~device_svi_expander_interface();
+
+ virtual DECLARE_READ8_MEMBER( mreq_r ) { return 0xff; };
+ virtual DECLARE_WRITE8_MEMBER( mreq_w ){};
+ virtual DECLARE_READ8_MEMBER( iorq_r ) { return 0xff; };
+ virtual DECLARE_WRITE8_MEMBER( iorq_w ){};
+
+ virtual void bk21_w(int state) {};
+ virtual void bk22_w(int state) {};
+ virtual void bk31_w(int state) {};
+ virtual void bk32_w(int state) {};
+
+protected:
+ svi_expander_device *m_expander;
+};
+
+// device type definition
+extern const device_type SVI_EXPANDER;
+
+// include here so drivers don't need to
+#include "modules.h"
+
+#endif // __SVI3X8_EXPANDER_H__
diff --git a/src/devices/bus/svi3x8/expander/modules.cpp b/src/devices/bus/svi3x8/expander/modules.cpp
new file mode 100644
index 00000000000..f8da88451e4
--- /dev/null
+++ b/src/devices/bus/svi3x8/expander/modules.cpp
@@ -0,0 +1,14 @@
+// license:GPL-2.0+
+// copyright-holders:Dirk Best
+/***************************************************************************
+
+ SVI 318/328 Expander Bus Modules
+
+***************************************************************************/
+
+#include "modules.h"
+
+SLOT_INTERFACE_START( svi_expander_modules )
+ SLOT_INTERFACE("sv601", SV601)
+ SLOT_INTERFACE("sv602", SV602)
+SLOT_INTERFACE_END
diff --git a/src/devices/bus/svi3x8/expander/modules.h b/src/devices/bus/svi3x8/expander/modules.h
new file mode 100644
index 00000000000..a13e146a26e
--- /dev/null
+++ b/src/devices/bus/svi3x8/expander/modules.h
@@ -0,0 +1,20 @@
+// license:GPL-2.0+
+// copyright-holders:Dirk Best
+/***************************************************************************
+
+ SVI 318/328 Expander Bus Modules
+
+***************************************************************************/
+
+#pragma once
+
+#ifndef __SVI_EXPANDER_MODULES_H__
+#define __SVI_EXPANDER_MODULES_H__
+
+#include "emu.h"
+#include "sv601.h"
+#include "sv602.h"
+
+SLOT_INTERFACE_EXTERN( svi_expander_modules );
+
+#endif // __SVI_EXPANDER_MODULES_H__
diff --git a/src/devices/bus/svi3x8/expander/sv601.cpp b/src/devices/bus/svi3x8/expander/sv601.cpp
new file mode 100644
index 00000000000..79538de37ed
--- /dev/null
+++ b/src/devices/bus/svi3x8/expander/sv601.cpp
@@ -0,0 +1,83 @@
+// license:GPL-2.0+
+// copyright-holders:Dirk Best
+/***************************************************************************
+
+ SV-601 Super Expander for SVI-318/328
+
+***************************************************************************/
+
+#include "sv601.h"
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type SV601 = &device_creator<sv601_device>;
+
+//-------------------------------------------------
+// machine_config_additions - device-specific
+// machine configurations
+//-------------------------------------------------
+
+static MACHINE_CONFIG_FRAGMENT( sv601 )
+ MCFG_SVI_SLOT_BUS_ADD
+ MCFG_SVI_SLOT_INT_HANDLER(WRITELINE(sv601_device, int_w))
+ MCFG_SVI_SLOT_ROMDIS_HANDLER(WRITELINE(sv601_device, romdis_w))
+ MCFG_SVI_SLOT_RAMDIS_HANDLER(WRITELINE(sv601_device, ramdis_w))
+ MCFG_SVI_SLOT_ADD("0", svi_slot_cards, NULL)
+ MCFG_SVI_SLOT_ADD("1", svi_slot_cards, NULL)
+ MCFG_SVI_SLOT_ADD("2", svi_slot_cards, NULL)
+ MCFG_SVI_SLOT_ADD("3", svi_slot_cards, NULL)
+ MCFG_SVI_SLOT_ADD("4", svi_slot_cards, NULL)
+ MCFG_SVI_SLOT_ADD("5", svi_slot_cards, NULL)
+ MCFG_SVI_SLOT_ADD("6", svi_slot_cards, NULL)
+MACHINE_CONFIG_END
+
+machine_config_constructor sv601_device::device_mconfig_additions() const
+{
+ return MACHINE_CONFIG_NAME( sv601 );
+}
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// sv601_device - constructor
+//-------------------------------------------------
+
+sv601_device::sv601_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, SV601, "SV-601 Super Expander", tag, owner, clock, "sv601", __FILE__),
+ device_svi_expander_interface(mconfig, *this),
+ m_slotbus(*this, "slotbus")
+{
+}
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void sv601_device::device_start()
+{
+}
+
+
+//**************************************************************************
+// IMPLEMENTATION
+//**************************************************************************
+
+WRITE_LINE_MEMBER( sv601_device::int_w ) { m_expander->int_w(state); }
+WRITE_LINE_MEMBER( sv601_device::romdis_w ) { m_expander->romdis_w(state); }
+WRITE_LINE_MEMBER( sv601_device::ramdis_w ) { m_expander->ramdis_w(state); }
+
+READ8_MEMBER( sv601_device::mreq_r ) { return m_slotbus->mreq_r(space, offset); }
+WRITE8_MEMBER( sv601_device::mreq_w ) { m_slotbus->mreq_w(space, offset, data); }
+READ8_MEMBER( sv601_device::iorq_r ) { return m_slotbus->iorq_r(space, offset); }
+WRITE8_MEMBER( sv601_device::iorq_w ) { m_slotbus->iorq_w(space, offset, data); }
+
+void sv601_device::bk21_w(int state) { m_slotbus->bk21_w(state); }
+void sv601_device::bk22_w(int state) { m_slotbus->bk22_w(state); }
+void sv601_device::bk31_w(int state) { m_slotbus->bk31_w(state); }
+void sv601_device::bk32_w(int state) { m_slotbus->bk32_w(state); }
diff --git a/src/devices/bus/svi3x8/expander/sv601.h b/src/devices/bus/svi3x8/expander/sv601.h
new file mode 100644
index 00000000000..1e0eb86c507
--- /dev/null
+++ b/src/devices/bus/svi3x8/expander/sv601.h
@@ -0,0 +1,58 @@
+// license:GPL-2.0+
+// copyright-holders:Dirk Best
+/***************************************************************************
+
+ SV-601 Super Expander for SVI-318/328
+
+***************************************************************************/
+
+#pragma once
+
+#ifndef __SVI3X8_EXPANDER_SV601_H__
+#define __SVI3X8_EXPANDER_SV601_H__
+
+#include "emu.h"
+#include "expander.h"
+#include "bus/svi3x8/slot/slot.h"
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> sv601_device
+
+class sv601_device : public device_t, public device_svi_expander_interface
+{
+public:
+ // construction/destruction
+ sv601_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // from slots
+ WRITE_LINE_MEMBER( int_w );
+ WRITE_LINE_MEMBER( romdis_w );
+ WRITE_LINE_MEMBER( ramdis_w );
+
+ // from host
+ virtual DECLARE_READ8_MEMBER( mreq_r ) override;
+ virtual DECLARE_WRITE8_MEMBER( mreq_w ) override;
+ virtual DECLARE_READ8_MEMBER( iorq_r ) override;
+ virtual DECLARE_WRITE8_MEMBER( iorq_w ) override;
+
+ virtual void bk21_w(int state) override;
+ virtual void bk22_w(int state) override;
+ virtual void bk31_w(int state) override;
+ virtual void bk32_w(int state) override;
+
+protected:
+ virtual machine_config_constructor device_mconfig_additions() const override;
+ virtual void device_start() override;
+
+private:
+ required_device<svi_slot_bus_device> m_slotbus;
+};
+
+// device type definition
+extern const device_type SV601;
+
+#endif // __SVI3X8_EXPANDER_SV601_H__
diff --git a/src/devices/bus/svi3x8/expander/sv602.cpp b/src/devices/bus/svi3x8/expander/sv602.cpp
new file mode 100644
index 00000000000..f9dbb1bfabe
--- /dev/null
+++ b/src/devices/bus/svi3x8/expander/sv602.cpp
@@ -0,0 +1,77 @@
+// license:GPL-2.0+
+// copyright-holders:Dirk Best
+/***************************************************************************
+
+ SV-602 Single Slot Expander for SVI-318/328
+
+***************************************************************************/
+
+#include "sv602.h"
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type SV602 = &device_creator<sv602_device>;
+
+//-------------------------------------------------
+// machine_config_additions - device-specific
+// machine configurations
+//-------------------------------------------------
+
+static MACHINE_CONFIG_FRAGMENT( sv602 )
+ MCFG_SVI_SLOT_BUS_ADD
+ MCFG_SVI_SLOT_INT_HANDLER(WRITELINE(sv602_device, int_w))
+ MCFG_SVI_SLOT_ROMDIS_HANDLER(WRITELINE(sv602_device, romdis_w))
+ MCFG_SVI_SLOT_RAMDIS_HANDLER(WRITELINE(sv602_device, ramdis_w))
+ MCFG_SVI_SLOT_ADD("0", sv602_slot_cards, NULL)
+MACHINE_CONFIG_END
+
+machine_config_constructor sv602_device::device_mconfig_additions() const
+{
+ return MACHINE_CONFIG_NAME( sv602 );
+}
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// sv602_device - constructor
+//-------------------------------------------------
+
+sv602_device::sv602_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, SV601, "SV-602 Single Slot Expander", tag, owner, clock, "sv602", __FILE__),
+ device_svi_expander_interface(mconfig, *this),
+ m_slotbus(*this, "slotbus")
+{
+}
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void sv602_device::device_start()
+{
+}
+
+
+//**************************************************************************
+// IMPLEMENTATION
+//**************************************************************************
+
+WRITE_LINE_MEMBER( sv602_device::int_w ) { m_expander->int_w(state); }
+WRITE_LINE_MEMBER( sv602_device::romdis_w ) { m_expander->romdis_w(state); }
+WRITE_LINE_MEMBER( sv602_device::ramdis_w ) { m_expander->ramdis_w(state); }
+
+READ8_MEMBER( sv602_device::mreq_r ) { return m_slotbus->mreq_r(space, offset); }
+WRITE8_MEMBER( sv602_device::mreq_w ) { m_slotbus->mreq_w(space, offset, data); }
+READ8_MEMBER( sv602_device::iorq_r ) { return m_slotbus->iorq_r(space, offset); }
+WRITE8_MEMBER( sv602_device::iorq_w ) { m_slotbus->iorq_w(space, offset, data); }
+
+void sv602_device::bk21_w(int state) { m_slotbus->bk21_w(state); }
+void sv602_device::bk22_w(int state) { m_slotbus->bk22_w(state); }
+void sv602_device::bk31_w(int state) { m_slotbus->bk31_w(state); }
+void sv602_device::bk32_w(int state) { m_slotbus->bk32_w(state); }
diff --git a/src/devices/bus/svi3x8/expander/sv602.h b/src/devices/bus/svi3x8/expander/sv602.h
new file mode 100644
index 00000000000..2026302d293
--- /dev/null
+++ b/src/devices/bus/svi3x8/expander/sv602.h
@@ -0,0 +1,58 @@
+// license:GPL-2.0+
+// copyright-holders:Dirk Best
+/***************************************************************************
+
+ SV-602 Single Slot Expander for SVI-318/328
+
+***************************************************************************/
+
+#pragma once
+
+#ifndef __SVI3X8_EXPANDER_SV602_H__
+#define __SVI3X8_EXPANDER_SV602_H__
+
+#include "emu.h"
+#include "expander.h"
+#include "bus/svi3x8/slot/slot.h"
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> sv602_device
+
+class sv602_device : public device_t, public device_svi_expander_interface
+{
+public:
+ // construction/destruction
+ sv602_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // from slots
+ WRITE_LINE_MEMBER( int_w );
+ WRITE_LINE_MEMBER( romdis_w );
+ WRITE_LINE_MEMBER( ramdis_w );
+
+ // from host
+ virtual DECLARE_READ8_MEMBER( mreq_r ) override;
+ virtual DECLARE_WRITE8_MEMBER( mreq_w ) override;
+ virtual DECLARE_READ8_MEMBER( iorq_r ) override;
+ virtual DECLARE_WRITE8_MEMBER( iorq_w ) override;
+
+ virtual void bk21_w(int state) override;
+ virtual void bk22_w(int state) override;
+ virtual void bk31_w(int state) override;
+ virtual void bk32_w(int state) override;
+
+protected:
+ virtual machine_config_constructor device_mconfig_additions() const override;
+ virtual void device_start() override;
+
+private:
+ required_device<svi_slot_bus_device> m_slotbus;
+};
+
+// device type definition
+extern const device_type SV602;
+
+#endif // __SVI3X8_EXPANDER_SV602_H__
diff --git a/src/devices/bus/svi3x8/slot/cards.cpp b/src/devices/bus/svi3x8/slot/cards.cpp
new file mode 100644
index 00000000000..095c2eeaa4e
--- /dev/null
+++ b/src/devices/bus/svi3x8/slot/cards.cpp
@@ -0,0 +1,28 @@
+// license:GPL-2.0+
+// copyright-holders:Dirk Best
+/***************************************************************************
+
+ SVI 318/328 Slot Cards
+
+***************************************************************************/
+
+#include "cards.h"
+
+SLOT_INTERFACE_START( svi_slot_cards )
+ SLOT_INTERFACE("sv801", SV801)
+ SLOT_INTERFACE("sv802", SV802)
+ SLOT_INTERFACE("sv803", SV803)
+ SLOT_INTERFACE("sv805", SV805)
+ SLOT_INTERFACE("sv806", SV806)
+ SLOT_INTERFACE("sv807", SV807)
+SLOT_INTERFACE_END
+
+// The single slot expander doesn't support the disk controller, since
+// it requires its own power supply to power the disk drives
+SLOT_INTERFACE_START( sv602_slot_cards )
+ SLOT_INTERFACE("sv802", SV802)
+ SLOT_INTERFACE("sv803", SV803)
+ SLOT_INTERFACE("sv805", SV805)
+ SLOT_INTERFACE("sv806", SV806)
+ SLOT_INTERFACE("sv807", SV807)
+SLOT_INTERFACE_END
diff --git a/src/devices/bus/svi3x8/slot/cards.h b/src/devices/bus/svi3x8/slot/cards.h
new file mode 100644
index 00000000000..d27469b08a1
--- /dev/null
+++ b/src/devices/bus/svi3x8/slot/cards.h
@@ -0,0 +1,25 @@
+// license:GPL-2.0+
+// copyright-holders:Dirk Best
+/***************************************************************************
+
+ SVI 318/328 Slot Cards
+
+***************************************************************************/
+
+#pragma once
+
+#ifndef __SVI3X8_SLOT_CARDS_H__
+#define __SVI3X8_SLOT_CARDS_H__
+
+#include "emu.h"
+#include "sv801.h"
+#include "sv802.h"
+#include "sv803.h"
+#include "sv805.h"
+#include "sv806.h"
+#include "sv807.h"
+
+SLOT_INTERFACE_EXTERN( svi_slot_cards );
+SLOT_INTERFACE_EXTERN( sv602_slot_cards );
+
+#endif // __SVI3X8_SLOT_CARDS_H__
diff --git a/src/devices/bus/svi3x8/slot/slot.cpp b/src/devices/bus/svi3x8/slot/slot.cpp
new file mode 100644
index 00000000000..5ab951e18f1
--- /dev/null
+++ b/src/devices/bus/svi3x8/slot/slot.cpp
@@ -0,0 +1,284 @@
+// license:GPL-2.0+
+// copyright-holders:Dirk Best
+/***************************************************************************
+
+ SVI 318/328 Expansion Slot
+
+***************************************************************************/
+
+#include "slot.h"
+
+
+//**************************************************************************
+// SLOT BUS DEVICE
+//**************************************************************************
+
+const device_type SVI_SLOT_BUS = &device_creator<svi_slot_bus_device>;
+
+//-------------------------------------------------
+// svi_slot_bus_device - constructor
+//-------------------------------------------------
+
+svi_slot_bus_device::svi_slot_bus_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, SVI_SLOT_BUS, "SVI Slot Bus", tag, owner, clock, "svislotbus", __FILE__),
+ m_int_handler(*this),
+ m_romdis_handler(*this),
+ m_ramdis_handler(*this)
+{
+}
+
+//-------------------------------------------------
+// svi_slot_bus_device - destructor
+//-------------------------------------------------
+
+svi_slot_bus_device::~svi_slot_bus_device()
+{
+ m_dev.detach_all();
+}
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void svi_slot_bus_device::device_start()
+{
+ // resolve callbacks
+ m_int_handler.resolve_safe();
+ m_romdis_handler.resolve_safe();
+ m_ramdis_handler.resolve_safe();
+}
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void svi_slot_bus_device::device_reset()
+{
+}
+
+//-------------------------------------------------
+// add_card - add new card to our bus
+//-------------------------------------------------
+
+void svi_slot_bus_device::add_card(device_svi_slot_interface *card)
+{
+ card->set_bus_device(this);
+ m_dev.append(*card);
+}
+
+//-------------------------------------------------
+// mreq_r - memory read from slot
+//-------------------------------------------------
+
+READ8_MEMBER( svi_slot_bus_device::mreq_r )
+{
+ device_svi_slot_interface *entry = m_dev.first();
+ UINT8 data = 0xff;
+
+ romdis_w(1);
+ ramdis_w(1);
+
+ while (entry)
+ {
+ data &= entry->mreq_r(space, offset);
+ entry = entry->next();
+ }
+
+ return data;
+}
+
+//-------------------------------------------------
+// mreq_w - memory write to slot
+//-------------------------------------------------
+
+WRITE8_MEMBER( svi_slot_bus_device::mreq_w )
+{
+ device_svi_slot_interface *entry = m_dev.first();
+
+ romdis_w(1);
+ ramdis_w(1);
+
+ while (entry)
+ {
+ entry->mreq_w(space, offset, data);
+ entry = entry->next();
+ }
+}
+
+//-------------------------------------------------
+// iorq_r - memory read from slot
+//-------------------------------------------------
+
+READ8_MEMBER( svi_slot_bus_device::iorq_r )
+{
+ device_svi_slot_interface *entry = m_dev.first();
+ UINT8 data = 0xff;
+
+ while (entry)
+ {
+ data &= entry->iorq_r(space, offset);
+ entry = entry->next();
+ }
+
+ return data;
+}
+
+//-------------------------------------------------
+// iorq_w - memory write to slot
+//-------------------------------------------------
+
+WRITE8_MEMBER( svi_slot_bus_device::iorq_w )
+{
+ device_svi_slot_interface *entry = m_dev.first();
+
+ while (entry)
+ {
+ entry->iorq_w(space, offset, data);
+ entry = entry->next();
+ }
+}
+
+//-------------------------------------------------
+// bk21_w - signal from host to slots
+//-------------------------------------------------
+
+WRITE_LINE_MEMBER( svi_slot_bus_device::bk21_w )
+{
+ device_svi_slot_interface *entry = m_dev.first();
+
+ while (entry)
+ {
+ entry->bk21_w(state);
+ entry = entry->next();
+ }
+}
+
+//-------------------------------------------------
+// bk22_w - signal from host to slots
+//-------------------------------------------------
+
+WRITE_LINE_MEMBER( svi_slot_bus_device::bk22_w )
+{
+ device_svi_slot_interface *entry = m_dev.first();
+
+ while (entry)
+ {
+ entry->bk22_w(state);
+ entry = entry->next();
+ }
+}
+
+//-------------------------------------------------
+// bk31_w - signal from host to slots
+//-------------------------------------------------
+
+WRITE_LINE_MEMBER( svi_slot_bus_device::bk31_w )
+{
+ device_svi_slot_interface *entry = m_dev.first();
+
+ while (entry)
+ {
+ entry->bk31_w(state);
+ entry = entry->next();
+ }
+}
+
+//-------------------------------------------------
+// bk32_w - signal from host to slots
+//-------------------------------------------------
+
+WRITE_LINE_MEMBER( svi_slot_bus_device::bk32_w )
+{
+ device_svi_slot_interface *entry = m_dev.first();
+
+ while (entry)
+ {
+ entry->bk32_w(state);
+ entry = entry->next();
+ }
+}
+
+
+//**************************************************************************
+// SVI SLOT DEVICE
+//**************************************************************************
+
+const device_type SVI_SLOT = &device_creator<svi_slot_device>;
+
+//-------------------------------------------------
+// svi_slot_device - constructor
+//-------------------------------------------------
+
+svi_slot_device::svi_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, SVI_SLOT, "SVI Slot", tag, owner, clock, "svislot", __FILE__),
+ device_slot_interface(mconfig, *this),
+ m_bus_tag(nullptr)
+{
+}
+
+//-------------------------------------------------
+// set_bus - set owner bus tag
+//-------------------------------------------------
+
+void svi_slot_device::set_bus(device_t &device, device_t *owner, const char *bus_tag)
+{
+ svi_slot_device &card = dynamic_cast<svi_slot_device &>(device);
+ card.m_owner = owner;
+ card.m_bus_tag = bus_tag;
+}
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void svi_slot_device::device_start()
+{
+ device_svi_slot_interface *dev = dynamic_cast<device_svi_slot_interface *>(get_card_device());
+
+ if (dev)
+ {
+ svi_slot_bus_device *bus = downcast<svi_slot_bus_device *>(m_owner->subdevice(m_bus_tag));
+ bus->add_card(dev);
+ }
+}
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void svi_slot_device::device_reset()
+{
+}
+
+
+//**************************************************************************
+// CARD INTERFACE
+//**************************************************************************
+
+//-------------------------------------------------
+// device_svi_slot_interface - constructor
+//-------------------------------------------------
+
+device_svi_slot_interface::device_svi_slot_interface(const machine_config &mconfig, device_t &device) :
+ device_slot_card_interface(mconfig, device),
+ m_next(nullptr),
+ m_bus(nullptr)
+{
+}
+
+//-------------------------------------------------
+// ~device_svi_slot_interface - destructor
+//-------------------------------------------------
+
+device_svi_slot_interface::~device_svi_slot_interface()
+{
+}
+
+//-------------------------------------------------
+// set_bus_device - set bus we are attached to
+//-------------------------------------------------
+
+void device_svi_slot_interface::set_bus_device(svi_slot_bus_device *bus)
+{
+ m_bus = bus;
+}
diff --git a/src/devices/bus/svi3x8/slot/slot.h b/src/devices/bus/svi3x8/slot/slot.h
new file mode 100644
index 00000000000..f7f2be940ef
--- /dev/null
+++ b/src/devices/bus/svi3x8/slot/slot.h
@@ -0,0 +1,179 @@
+// license:GPL-2.0+
+// copyright-holders:Dirk Best
+/***************************************************************************
+
+ SVI 318/328 Expansion Slot
+
+ 50-pin slot
+
+ 1 +5V 2 +5V
+ 3 +12V 4 -12V
+ 5 GND 6 /WAIT
+ 7 /RST 8 CPUCLK
+ 9 A15 10 A14
+ 11 A13 12 A12
+ 13 A11 14 A10
+ 15 A9 16 A8
+ 17 A7 18 A6
+ 19 A5 20 A4
+ 21 A3 22 A2
+ 23 A1 24 A0
+ 25 /RFSH 26 GND
+ 27 /M1 28 GND
+ 29 /WR 30 /MREQ
+ 31 /IORQ 32 /RD
+ 33 D0 34 D1
+ 35 D2 36 D3
+ 37 D4 38 D5
+ 39 D6 40 D7
+ 41 CSOUND 42 /INT
+ 43 /RAMDIS 44 /ROMDIS
+ 45 /BK32 46 /BK31
+ 47 /BK22 48 /BK21
+ 49 GND 50 GND
+
+***************************************************************************/
+
+#pragma once
+
+#ifndef __SVI3X8_SLOT_H__
+#define __SVI3X8_SLOT_H__
+
+#include "emu.h"
+
+
+//**************************************************************************
+// INTERFACE CONFIGURATION MACROS
+//**************************************************************************
+
+#define MCFG_SVI_SLOT_BUS_ADD \
+ MCFG_DEVICE_ADD("slotbus", SVI_SLOT_BUS, 0)
+
+#define MCFG_SVI_SLOT_ADD(_tag, _slot_intf, _def_slot) \
+ MCFG_DEVICE_ADD(_tag, SVI_SLOT, 0) \
+ MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, false) \
+ svi_slot_device::set_bus(*device, owner, "slotbus");
+
+#define MCFG_SVI_SLOT_INT_HANDLER(_devcb) \
+ devcb = &svi_slot_bus_device::set_int_handler(*device, DEVCB_##_devcb);
+
+#define MCFG_SVI_SLOT_ROMDIS_HANDLER(_devcb) \
+ devcb = &svi_slot_bus_device::set_romdis_handler(*device, DEVCB_##_devcb);
+
+#define MCFG_SVI_SLOT_RAMDIS_HANDLER(_devcb) \
+ devcb = &svi_slot_bus_device::set_ramdis_handler(*device, DEVCB_##_devcb);
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+class device_svi_slot_interface;
+
+// ======================> svi_slot_bus_device
+
+class svi_slot_bus_device : public device_t
+{
+public:
+ // construction/destruction
+ svi_slot_bus_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+ virtual ~svi_slot_bus_device();
+
+ // callbacks
+ template<class _Object> static devcb_base &set_int_handler(device_t &device, _Object object)
+ { return downcast<svi_slot_bus_device &>(device).m_int_handler.set_callback(object); }
+
+ template<class _Object> static devcb_base &set_romdis_handler(device_t &device, _Object object)
+ { return downcast<svi_slot_bus_device &>(device).m_romdis_handler.set_callback(object); }
+
+ template<class _Object> static devcb_base &set_ramdis_handler(device_t &device, _Object object)
+ { return downcast<svi_slot_bus_device &>(device).m_ramdis_handler.set_callback(object); }
+
+ // device-level overrides
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+ void add_card(device_svi_slot_interface *card);
+
+ // from slot
+ DECLARE_WRITE_LINE_MEMBER( int_w ) { m_int_handler(state); };
+ DECLARE_WRITE_LINE_MEMBER( romdis_w ) { m_romdis_handler(state); };
+ DECLARE_WRITE_LINE_MEMBER( ramdis_w ) { m_ramdis_handler(state); };
+
+ // from host
+ DECLARE_READ8_MEMBER( mreq_r );
+ DECLARE_WRITE8_MEMBER( mreq_w );
+ DECLARE_READ8_MEMBER( iorq_r );
+ DECLARE_WRITE8_MEMBER( iorq_w );
+
+ DECLARE_WRITE_LINE_MEMBER( bk21_w );
+ DECLARE_WRITE_LINE_MEMBER( bk22_w );
+ DECLARE_WRITE_LINE_MEMBER( bk31_w );
+ DECLARE_WRITE_LINE_MEMBER( bk32_w );
+
+private:
+ simple_list<device_svi_slot_interface> m_dev;
+
+ devcb_write_line m_int_handler;
+ devcb_write_line m_romdis_handler;
+ devcb_write_line m_ramdis_handler;
+};
+
+// device type definition
+extern const device_type SVI_SLOT_BUS;
+
+// ======================> svi_slot_device
+
+class svi_slot_device : public device_t, public device_slot_interface
+{
+public:
+ // construction/destruction
+ svi_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // inline configuration
+ static void set_bus(device_t &device, device_t *owner, const char *bus_tag);
+
+protected:
+ // device-level overrides
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+ // configuration
+ const char *m_bus_tag;
+};
+
+// device type definition
+extern const device_type SVI_SLOT;
+
+// ======================> svi_slot_device
+
+class device_svi_slot_interface : public device_slot_card_interface
+{
+public:
+ // construction/destruction
+ device_svi_slot_interface(const machine_config &mconfig, device_t &device);
+ virtual ~device_svi_slot_interface();
+
+ void set_bus_device(svi_slot_bus_device *bus);
+
+ device_svi_slot_interface *next() const { return m_next; }
+ device_svi_slot_interface *m_next;
+
+ virtual DECLARE_READ8_MEMBER( mreq_r ) { return 0xff; };
+ virtual DECLARE_WRITE8_MEMBER( mreq_w ) {};
+ virtual DECLARE_READ8_MEMBER( iorq_r ) { return 0xff; };
+ virtual DECLARE_WRITE8_MEMBER( iorq_w ) {};
+
+ virtual DECLARE_WRITE_LINE_MEMBER( bk21_w ) {};
+ virtual DECLARE_WRITE_LINE_MEMBER( bk22_w ) {};
+ virtual DECLARE_WRITE_LINE_MEMBER( bk31_w ) {};
+ virtual DECLARE_WRITE_LINE_MEMBER( bk32_w ) {};
+
+protected:
+ svi_slot_bus_device *m_bus;
+};
+
+// include here so drivers don't need to
+#include "cards.h"
+
+#endif // __SVI3X8_SLOT_H__
diff --git a/src/devices/bus/svi3x8/slot/sv801.cpp b/src/devices/bus/svi3x8/slot/sv801.cpp
new file mode 100644
index 00000000000..bccfd1539eb
--- /dev/null
+++ b/src/devices/bus/svi3x8/slot/sv801.cpp
@@ -0,0 +1,147 @@
+// license:GPL-2.0+
+// copyright-holders:Dirk Best
+/***************************************************************************
+
+ SV-801 Disk Controller
+
+***************************************************************************/
+
+#include "sv801.h"
+#include "softlist.h"
+#include "formats/svi_dsk.h"
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type SV801 = &device_creator<sv801_device>;
+
+//-------------------------------------------------
+// machine_config_additions - device-specific
+// machine configurations
+//-------------------------------------------------
+
+FLOPPY_FORMATS_MEMBER( sv801_device::floppy_formats )
+ FLOPPY_SVI_FORMAT
+FLOPPY_FORMATS_END
+
+static SLOT_INTERFACE_START( svi_floppies )
+ SLOT_INTERFACE("dd", FLOPPY_525_DD)
+SLOT_INTERFACE_END
+
+static MACHINE_CONFIG_FRAGMENT( sv801 )
+ MCFG_FD1793_ADD("fdc", XTAL_8MHz / 8)
+ MCFG_WD_FDC_INTRQ_CALLBACK(WRITELINE(sv801_device, intrq_w))
+ MCFG_WD_FDC_DRQ_CALLBACK(WRITELINE(sv801_device, drq_w))
+
+ MCFG_FLOPPY_DRIVE_ADD("fdc:0", svi_floppies, "dd", sv801_device::floppy_formats)
+ MCFG_FLOPPY_DRIVE_ADD("fdc:1", svi_floppies, "dd", sv801_device::floppy_formats)
+
+ MCFG_SOFTWARE_LIST_ADD("disk_list", "svi318_flop")
+MACHINE_CONFIG_END
+
+machine_config_constructor sv801_device::device_mconfig_additions() const
+{
+ return MACHINE_CONFIG_NAME( sv801 );
+}
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// sv801_device - constructor
+//-------------------------------------------------
+
+sv801_device::sv801_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, SV801, "SV-801 Disk Controller", tag, owner, clock, "sv801", __FILE__),
+ device_svi_slot_interface(mconfig, *this),
+ m_fdc(*this, "fdc"),
+ m_floppy0(*this, "fdc:0"),
+ m_floppy1(*this, "fdc:1"),
+ m_floppy(nullptr),
+ m_irq(0), m_drq(0)
+{
+}
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void sv801_device::device_start()
+{
+ // register for savestates
+ save_item(NAME(m_irq));
+ save_item(NAME(m_drq));
+}
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void sv801_device::device_reset()
+{
+}
+
+
+//**************************************************************************
+// IMPLEMENTATION
+//**************************************************************************
+
+WRITE_LINE_MEMBER( sv801_device::intrq_w )
+{
+ m_irq = state;
+}
+
+WRITE_LINE_MEMBER( sv801_device::drq_w )
+{
+ m_drq = state;
+}
+
+WRITE8_MEMBER( sv801_device::motor_w )
+{
+ m_floppy = nullptr;
+
+ if (BIT(data, 0)) m_floppy = m_floppy0->get_device();
+ if (BIT(data, 1)) m_floppy = m_floppy1->get_device();
+
+ m_fdc->set_floppy(m_floppy);
+
+ if (m_floppy0->get_device())
+ m_floppy0->get_device()->mon_w(!BIT(data, 2));
+ if (m_floppy1->get_device())
+ m_floppy1->get_device()->mon_w(!BIT(data, 3));
+}
+
+READ8_MEMBER( sv801_device::iorq_r )
+{
+ switch (offset)
+ {
+ case 0x30: return m_fdc->status_r(space, 0);
+ case 0x31: return m_fdc->track_r(space, 0);
+ case 0x32: return m_fdc->sector_r(space, 0);
+ case 0x33: return m_fdc->data_r(space, 0);
+ case 0x34: return (m_drq << 6) | (m_irq << 7);
+ }
+
+ return 0xff;
+}
+
+WRITE8_MEMBER( sv801_device::iorq_w )
+{
+ switch (offset)
+ {
+ case 0x30: m_fdc->cmd_w(space, 0, data); break;
+ case 0x31: m_fdc->track_w(space, 0, data); break;
+ case 0x32: m_fdc->sector_w(space, 0, data); break;
+ case 0x33: m_fdc->data_w(space, 0, data); break;
+ case 0x34: motor_w(space, 0, data); break;
+ case 0x38:
+ m_fdc->dden_w(BIT(data, 0));
+ if (m_floppy)
+ m_floppy->ss_w(BIT(data, 1));
+ break;
+ }
+}
diff --git a/src/devices/bus/svi3x8/slot/sv801.h b/src/devices/bus/svi3x8/slot/sv801.h
new file mode 100644
index 00000000000..2f670f05ad1
--- /dev/null
+++ b/src/devices/bus/svi3x8/slot/sv801.h
@@ -0,0 +1,61 @@
+// license:GPL-2.0+
+// copyright-holders:Dirk Best
+/***************************************************************************
+
+ SV-801 Disk Controller
+
+***************************************************************************/
+
+#pragma once
+
+#ifndef __SVI3X8_SLOT_SV801_H__
+#define __SVI3X8_SLOT_SV801_H__
+
+#include "emu.h"
+#include "slot.h"
+#include "machine/wd_fdc.h"
+#include "imagedev/floppy.h"
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> sv801_device
+
+class sv801_device : public device_t, public device_svi_slot_interface
+{
+public:
+ // construction/destruction
+ sv801_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ DECLARE_FLOPPY_FORMATS(floppy_formats);
+
+ virtual DECLARE_READ8_MEMBER( iorq_r ) override;
+ virtual DECLARE_WRITE8_MEMBER( iorq_w ) override;
+
+ DECLARE_WRITE_LINE_MEMBER( intrq_w );
+ DECLARE_WRITE_LINE_MEMBER( drq_w );
+
+protected:
+ virtual machine_config_constructor device_mconfig_additions() const override;
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+private:
+ DECLARE_WRITE8_MEMBER( motor_w );
+
+ required_device<fd1793_t> m_fdc;
+ required_device<floppy_connector> m_floppy0;
+ required_device<floppy_connector> m_floppy1;
+
+ floppy_image_device *m_floppy;
+
+ int m_irq;
+ int m_drq;
+};
+
+// device type definition
+extern const device_type SV801;
+
+#endif // __SVI3X8_SLOT_SV801_H__
diff --git a/src/devices/bus/svi3x8/slot/sv802.cpp b/src/devices/bus/svi3x8/slot/sv802.cpp
new file mode 100644
index 00000000000..adeed63588b
--- /dev/null
+++ b/src/devices/bus/svi3x8/slot/sv802.cpp
@@ -0,0 +1,88 @@
+// license:GPL-2.0+
+// copyright-holders:Dirk Best
+/***************************************************************************
+
+ SV-802 Centronics Printer Interface for SVI-318/328
+
+***************************************************************************/
+
+#include "sv802.h"
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type SV802 = &device_creator<sv802_device>;
+
+//-------------------------------------------------
+// machine_config_additions - device-specific
+// machine configurations
+//-------------------------------------------------
+
+static MACHINE_CONFIG_FRAGMENT( sv802 )
+ MCFG_CENTRONICS_ADD("centronics", centronics_devices, "printer")
+ MCFG_CENTRONICS_BUSY_HANDLER(WRITELINE(sv802_device, busy_w))
+
+ MCFG_CENTRONICS_OUTPUT_LATCH_ADD("cent_data_out", "centronics")
+MACHINE_CONFIG_END
+
+machine_config_constructor sv802_device::device_mconfig_additions() const
+{
+ return MACHINE_CONFIG_NAME( sv802 );
+}
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// sv802_device - constructor
+//-------------------------------------------------
+
+sv802_device::sv802_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, SV805, "SV-802 Centronics Printer Interface", tag, owner, clock, "sv802", __FILE__),
+ device_svi_slot_interface(mconfig, *this),
+ m_centronics(*this, "centronics"),
+ m_cent_data_out(*this, "cent_data_out"),
+ m_busy(0)
+{
+}
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void sv802_device::device_start()
+{
+ // register for savestates
+ save_item(NAME(m_busy));
+}
+
+
+//**************************************************************************
+// IMPLEMENTATION
+//**************************************************************************
+
+READ8_MEMBER( sv802_device::iorq_r )
+{
+ if (offset == 0x12)
+ return 0xfe | m_busy;
+
+ return 0xff;
+}
+
+WRITE8_MEMBER( sv802_device::iorq_w )
+{
+ switch (offset)
+ {
+ case 0x10: m_cent_data_out->write(space, 0, data); break;
+ case 0x11: m_centronics->write_strobe(BIT(data, 0)); break;
+ }
+}
+
+WRITE_LINE_MEMBER( sv802_device::busy_w )
+{
+ m_busy = state;
+}
diff --git a/src/devices/bus/svi3x8/slot/sv802.h b/src/devices/bus/svi3x8/slot/sv802.h
new file mode 100644
index 00000000000..0b363c035ed
--- /dev/null
+++ b/src/devices/bus/svi3x8/slot/sv802.h
@@ -0,0 +1,51 @@
+// license:GPL-2.0+
+// copyright-holders:Dirk Best
+/***************************************************************************
+
+ SV-802 Centronics Printer Interface for SVI-318/328
+
+***************************************************************************/
+
+#pragma once
+
+#ifndef __SVI3X8_SLOT_SV802_H__
+#define __SVI3X8_SLOT_SV802_H__
+
+#include "emu.h"
+#include "slot.h"
+#include "machine/buffer.h"
+#include "bus/centronics/ctronics.h"
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> sv802_device
+
+class sv802_device : public device_t, public device_svi_slot_interface
+{
+public:
+ // construction/destruction
+ sv802_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ virtual DECLARE_READ8_MEMBER( iorq_r ) override;
+ virtual DECLARE_WRITE8_MEMBER( iorq_w ) override;
+
+ DECLARE_WRITE_LINE_MEMBER( busy_w );
+
+protected:
+ virtual machine_config_constructor device_mconfig_additions() const override;
+ virtual void device_start() override;
+
+private:
+ required_device<centronics_device> m_centronics;
+ required_device<output_latch_device> m_cent_data_out;
+
+ int m_busy;
+};
+
+// device type definition
+extern const device_type SV802;
+
+#endif // __SVI3X8_SLOT_SV802_H__
diff --git a/src/devices/bus/svi3x8/slot/sv803.cpp b/src/devices/bus/svi3x8/slot/sv803.cpp
new file mode 100644
index 00000000000..8db3cf1f601
--- /dev/null
+++ b/src/devices/bus/svi3x8/slot/sv803.cpp
@@ -0,0 +1,70 @@
+// license:GPL-2.0+
+// copyright-holders:Dirk Best
+/***************************************************************************
+
+ SV-803 16k memory expansion for SVI-318
+
+***************************************************************************/
+
+#include "sv803.h"
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type SV803 = &device_creator<sv803_device>;
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// sv803_device - constructor
+//-------------------------------------------------
+
+sv803_device::sv803_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, SV803, "SV-803 16k RAM Cartridge", tag, owner, clock, "sv803", __FILE__),
+ device_svi_slot_interface(mconfig, *this)
+{
+ m_ram = std::make_unique<UINT8[]>(0x4000);
+ memset(m_ram.get(), 0xff, 0x4000);
+}
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void sv803_device::device_start()
+{
+ // register for savestates
+ save_pointer(NAME(m_ram.get()), 0x4000);
+}
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void sv803_device::device_reset()
+{
+}
+
+
+//**************************************************************************
+// IMPLEMENTATION
+//**************************************************************************
+
+READ8_MEMBER( sv803_device::mreq_r )
+{
+ if (offset >= 0x8000 && offset <= 0xbfff)
+ return m_ram[offset - 0x8000];
+
+ return 0xff;
+}
+
+WRITE8_MEMBER( sv803_device::mreq_w )
+{
+ if (offset >= 0x8000 && offset <= 0xbfff)
+ m_ram[offset - 0x8000] = data;
+}
diff --git a/src/devices/bus/svi3x8/slot/sv803.h b/src/devices/bus/svi3x8/slot/sv803.h
new file mode 100644
index 00000000000..9dea0ea9180
--- /dev/null
+++ b/src/devices/bus/svi3x8/slot/sv803.h
@@ -0,0 +1,44 @@
+// license:GPL-2.0+
+// copyright-holders:Dirk Best
+/***************************************************************************
+
+ SV-803 16k memory expansion for SVI-318
+
+***************************************************************************/
+
+#pragma once
+
+#ifndef __SVI3X8_SLOT_SV803_H__
+#define __SVI3X8_SLOT_SV803_H__
+
+#include "emu.h"
+#include "slot.h"
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> sv803_device
+
+class sv803_device : public device_t, public device_svi_slot_interface
+{
+public:
+ // construction/destruction
+ sv803_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ virtual DECLARE_READ8_MEMBER( mreq_r ) override;
+ virtual DECLARE_WRITE8_MEMBER( mreq_w ) override;
+
+protected:
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+private:
+ std::unique_ptr<UINT8[]> m_ram;
+};
+
+// device type definition
+extern const device_type SV803;
+
+#endif // __SVI3X8_SLOT_SV803_H__
diff --git a/src/devices/bus/svi3x8/slot/sv805.cpp b/src/devices/bus/svi3x8/slot/sv805.cpp
new file mode 100644
index 00000000000..71ba5b69820
--- /dev/null
+++ b/src/devices/bus/svi3x8/slot/sv805.cpp
@@ -0,0 +1,109 @@
+// license:GPL-2.0+
+// copyright-holders:Dirk Best
+/***************************************************************************
+
+ SV-805 RS-232 Interface for SVI 318/328
+
+***************************************************************************/
+
+#include "sv805.h"
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type SV805 = &device_creator<sv805_device>;
+
+//-------------------------------------------------
+// machine_config_additions - device-specific
+// machine configurations
+//-------------------------------------------------
+
+static MACHINE_CONFIG_FRAGMENT( sv805 )
+ MCFG_DEVICE_ADD("uart", INS8250, XTAL_3_072MHz)
+ MCFG_INS8250_OUT_INT_CB(WRITELINE(sv805_device, uart_intr_w))
+ MCFG_INS8250_OUT_TX_CB(DEVWRITELINE("rs232", rs232_port_device, write_txd))
+ MCFG_INS8250_OUT_DTR_CB(DEVWRITELINE("rs232", rs232_port_device, write_dtr))
+ MCFG_INS8250_OUT_RTS_CB(DEVWRITELINE("rs232", rs232_port_device, write_rts))
+
+ MCFG_RS232_PORT_ADD("rs232", default_rs232_devices, nullptr)
+ MCFG_RS232_RXD_HANDLER(DEVWRITELINE("uart", ins8250_uart_device, rx_w))
+ MCFG_RS232_DCD_HANDLER(DEVWRITELINE("uart", ins8250_uart_device, dcd_w))
+ MCFG_RS232_DSR_HANDLER(DEVWRITELINE("uart", ins8250_uart_device, dsr_w))
+ MCFG_RS232_CTS_HANDLER(DEVWRITELINE("uart", ins8250_uart_device, cts_w))
+MACHINE_CONFIG_END
+
+machine_config_constructor sv805_device::device_mconfig_additions() const
+{
+ return MACHINE_CONFIG_NAME( sv805 );
+}
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// sv805_device - constructor
+//-------------------------------------------------
+
+sv805_device::sv805_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, SV805, "SV-805 RS-232 Interface", tag, owner, clock, "sv805", __FILE__),
+ device_svi_slot_interface(mconfig, *this),
+ m_uart(*this, "uart"),
+ m_rs232(*this, "rs232")
+{
+}
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void sv805_device::device_start()
+{
+}
+
+
+//**************************************************************************
+// IMPLEMENTATION
+//**************************************************************************
+
+READ8_MEMBER( sv805_device::iorq_r )
+{
+ switch (offset)
+ {
+ case 0x28:
+ case 0x29:
+ case 0x2a:
+ case 0x2b:
+ case 0x2c:
+ case 0x2d:
+ case 0x2e:
+ case 0x2f:
+ return m_uart->ins8250_r(space, offset & 0x07);
+ }
+
+ return 0xff;
+}
+
+WRITE8_MEMBER( sv805_device::iorq_w )
+{
+ switch (offset)
+ {
+ case 0x28:
+ case 0x29:
+ case 0x2a:
+ case 0x2b:
+ case 0x2c:
+ case 0x2d:
+ case 0x2e:
+ case 0x2f:
+ m_uart->ins8250_w(space, offset & 0x07, data);
+ }
+}
+
+WRITE_LINE_MEMBER( sv805_device::uart_intr_w )
+{
+ m_bus->int_w(state);
+}
diff --git a/src/devices/bus/svi3x8/slot/sv805.h b/src/devices/bus/svi3x8/slot/sv805.h
new file mode 100644
index 00000000000..6d64ef54256
--- /dev/null
+++ b/src/devices/bus/svi3x8/slot/sv805.h
@@ -0,0 +1,49 @@
+// license:GPL-2.0+
+// copyright-holders:Dirk Best
+/***************************************************************************
+
+ SV-805 RS-232 Interface for SVI 318/328
+
+***************************************************************************/
+
+#pragma once
+
+#ifndef __SVI3X8_SLOT_SV805_H__
+#define __SVI3X8_SLOT_SV805_H__
+
+#include "emu.h"
+#include "slot.h"
+#include "machine/ins8250.h"
+#include "bus/rs232/rs232.h"
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> sv805_device
+
+class sv805_device : public device_t, public device_svi_slot_interface
+{
+public:
+ // construction/destruction
+ sv805_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ virtual DECLARE_READ8_MEMBER( iorq_r ) override;
+ virtual DECLARE_WRITE8_MEMBER( iorq_w ) override;
+
+ DECLARE_WRITE_LINE_MEMBER( uart_intr_w );
+
+protected:
+ virtual machine_config_constructor device_mconfig_additions() const override;
+ virtual void device_start() override;
+
+private:
+ required_device<ins8250_device> m_uart;
+ required_device<rs232_port_device> m_rs232;
+};
+
+// device type definition
+extern const device_type SV805;
+
+#endif // __SVI3X8_SLOT_SV805_H__
diff --git a/src/devices/bus/svi3x8/slot/sv806.cpp b/src/devices/bus/svi3x8/slot/sv806.cpp
new file mode 100644
index 00000000000..4cce2deaec4
--- /dev/null
+++ b/src/devices/bus/svi3x8/slot/sv806.cpp
@@ -0,0 +1,153 @@
+// license:GPL-2.0+
+// copyright-holders:Dirk Best
+/***************************************************************************
+
+ SV-806 80 Column Cartridge for SVI-318/328
+
+***************************************************************************/
+
+#include "sv806.h"
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type SV806 = &device_creator<sv806_device>;
+
+//-------------------------------------------------
+// rom_region - device-specific ROM region
+//-------------------------------------------------
+
+ROM_START( sv806 )
+ ROM_REGION(0x1000, "gfx", 0)
+ ROM_SYSTEM_BIOS(0, "en", "English Character Set")
+ ROMX_LOAD("sv806.ic27", 0x0000, 0x1000, CRC(850bc232) SHA1(ed45cb0e9bd18a9d7bd74f87e620f016a7ae840f), ROM_BIOS(1))
+ ROM_SYSTEM_BIOS(1, "se", "Swedish Character Set")
+ ROMX_LOAD("sv806se.ic27", 0x0000, 0x1000, CRC(daea8956) SHA1(3f16d5513ad35692488ae7d864f660e76c6e8ed3), ROM_BIOS(2))
+ROM_END
+
+const rom_entry *sv806_device::device_rom_region() const
+{
+ return ROM_NAME( sv806 );
+}
+
+//-------------------------------------------------
+// machine_config_additions - device-specific
+// machine configurations
+//-------------------------------------------------
+
+static MACHINE_CONFIG_FRAGMENT( sv806 )
+ MCFG_SCREEN_ADD_MONOCHROME("80col", RASTER, rgb_t::green)
+ MCFG_SCREEN_RAW_PARAMS((XTAL_12MHz / 6) * 8, 864, 0, 640, 317, 0, 192)
+ MCFG_SCREEN_UPDATE_DEVICE("crtc", hd6845_device, screen_update)
+
+ MCFG_PALETTE_ADD_MONOCHROME("palette")
+
+ MCFG_MC6845_ADD("crtc", HD6845, "80col", XTAL_12MHz / 6)
+ MCFG_MC6845_SHOW_BORDER_AREA(false)
+ MCFG_MC6845_CHAR_WIDTH(8)
+ MCFG_MC6845_UPDATE_ROW_CB(sv806_device, crtc_update_row)
+MACHINE_CONFIG_END
+
+machine_config_constructor sv806_device::device_mconfig_additions() const
+{
+ return MACHINE_CONFIG_NAME( sv806 );
+}
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// sv806_device - constructor
+//-------------------------------------------------
+
+sv806_device::sv806_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, SV806, "SV-806 80 Column Cartridge", tag, owner, clock, "sv806", __FILE__),
+ device_svi_slot_interface(mconfig, *this),
+ m_crtc(*this, "crtc"),
+ m_palette(*this, "palette"),
+ m_gfx(*this, "gfx"),
+ m_ram_enabled(0)
+{
+ m_ram = std::make_unique<UINT8[]>(0x800);
+ memset(m_ram.get(), 0xff, 0x800);
+}
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void sv806_device::device_start()
+{
+ // register for savestates
+ save_item(NAME(m_ram_enabled));
+ save_pointer(NAME(m_ram.get()), 0x800);
+}
+
+
+//**************************************************************************
+// IMPLEMENTATION
+//**************************************************************************
+
+MC6845_UPDATE_ROW( sv806_device::crtc_update_row )
+{
+ const pen_t *pen = m_palette->pens();
+
+ for (int i = 0; i < x_count; i++)
+ {
+ UINT8 data = m_gfx->u8((m_ram[(ma + i) & 0x7ff] << 4) | ra);
+
+ if (i == cursor_x)
+ data = 0xff;
+
+ bitmap.pix32(y, i * 8 + 0) = pen[BIT(data, 7)];
+ bitmap.pix32(y, i * 8 + 1) = pen[BIT(data, 6)];
+ bitmap.pix32(y, i * 8 + 2) = pen[BIT(data, 5)];
+ bitmap.pix32(y, i * 8 + 3) = pen[BIT(data, 4)];
+ bitmap.pix32(y, i * 8 + 4) = pen[BIT(data, 3)];
+ bitmap.pix32(y, i * 8 + 5) = pen[BIT(data, 2)];
+ bitmap.pix32(y, i * 8 + 6) = pen[BIT(data, 1)];
+ bitmap.pix32(y, i * 8 + 7) = pen[BIT(data, 0)];
+ }
+}
+
+READ8_MEMBER( sv806_device::mreq_r )
+{
+ if (offset >= 0xf000 && m_ram_enabled)
+ {
+ m_bus->ramdis_w(0);
+ return m_ram[offset & 0x7ff];
+ }
+
+ return 0xff;
+}
+
+WRITE8_MEMBER( sv806_device::mreq_w )
+{
+ if (offset >= 0xf000 && m_ram_enabled)
+ {
+ m_bus->ramdis_w(0);
+ m_ram[offset & 0x7ff] = data;
+ }
+}
+
+READ8_MEMBER( sv806_device::iorq_r )
+{
+ if (offset == 0x51)
+ return m_crtc->register_r(space, 0);
+
+ return 0xff;
+}
+
+WRITE8_MEMBER( sv806_device::iorq_w )
+{
+ switch (offset)
+ {
+ case 0x50: m_crtc->address_w(space, 0, data); break;
+ case 0x51: m_crtc->register_w(space, 0, data); break;
+ case 0x58: m_ram_enabled = data; break;
+ }
+}
diff --git a/src/devices/bus/svi3x8/slot/sv806.h b/src/devices/bus/svi3x8/slot/sv806.h
new file mode 100644
index 00000000000..4782faa4812
--- /dev/null
+++ b/src/devices/bus/svi3x8/slot/sv806.h
@@ -0,0 +1,55 @@
+// license:GPL-2.0+
+// copyright-holders:Dirk Best
+/***************************************************************************
+
+ SV-806 80 column card for SVI-318/328
+
+***************************************************************************/
+
+#pragma once
+
+#ifndef __SVI3X8_SLOT_SV806_H__
+#define __SVI3X8_SLOT_SV806_H__
+
+#include "emu.h"
+#include "slot.h"
+#include "video/mc6845.h"
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> sv806_device
+
+class sv806_device : public device_t, public device_svi_slot_interface
+{
+public:
+ // construction/destruction
+ sv806_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ virtual DECLARE_READ8_MEMBER( mreq_r ) override;
+ virtual DECLARE_WRITE8_MEMBER( mreq_w ) override;
+ virtual DECLARE_READ8_MEMBER( iorq_r ) override;
+ virtual DECLARE_WRITE8_MEMBER( iorq_w ) override;
+
+ MC6845_UPDATE_ROW(crtc_update_row);
+
+protected:
+ virtual const rom_entry *device_rom_region() const override;
+ virtual machine_config_constructor device_mconfig_additions() const override;
+ virtual void device_start() override;
+
+private:
+ required_device<hd6845_device> m_crtc;
+ required_device<palette_device> m_palette;
+ required_memory_region m_gfx;
+
+ std::unique_ptr<UINT8[]> m_ram;
+ int m_ram_enabled;
+};
+
+// device type definition
+extern const device_type SV806;
+
+#endif // __SVI3X8_SLOT_SV806_H__
diff --git a/src/devices/bus/svi3x8/slot/sv807.cpp b/src/devices/bus/svi3x8/slot/sv807.cpp
new file mode 100644
index 00000000000..c111739f039
--- /dev/null
+++ b/src/devices/bus/svi3x8/slot/sv807.cpp
@@ -0,0 +1,170 @@
+// license:GPL-2.0+
+// copyright-holders:Dirk Best
+/***************************************************************************
+
+ SV-807 64k memory expansion for SVI-318/328
+
+ TODO:
+ - Switch S6 (but needs to be off for the SVI anyway)
+
+***************************************************************************/
+
+#include "sv807.h"
+
+
+//**************************************************************************
+// CONSTANTS / MACROS
+//**************************************************************************
+
+#define BK21_ACTIVE ((m_bk21 == 0) && (m_switch->read() & 0x01))
+#define BK22_ACTIVE ((m_bk22 == 0) && (m_switch->read() & 0x02))
+#define BK31_ACTIVE ((m_bk31 == 0) && (m_switch->read() & 0x04))
+#define BK32_ACTIVE ((m_bk32 == 0) && (m_switch->read() & 0x08))
+#define BK02_ACTIVE (m_switch->read() & 0x10)
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+const device_type SV807 = &device_creator<sv807_device>;
+
+//-------------------------------------------------
+// input_ports - device-specific input ports
+//-------------------------------------------------
+
+static INPUT_PORTS_START( sv807_switches )
+ PORT_START("S")
+ PORT_DIPNAME(0x01, 0x00, "Bank/Page 21")
+ PORT_DIPLOCATION("S:1")
+ PORT_DIPSETTING(0x00, "Off")
+ PORT_DIPSETTING(0x01, "On")
+ PORT_DIPNAME(0x02, 0x02, "Bank/Page 22")
+ PORT_DIPLOCATION("S:2")
+ PORT_DIPSETTING(0x00, "Off")
+ PORT_DIPSETTING(0x02, "On")
+ PORT_DIPNAME(0x04, 0x04, "Bank/Page 31")
+ PORT_DIPLOCATION("S:3")
+ PORT_DIPSETTING(0x00, "Off")
+ PORT_DIPSETTING(0x04, "On")
+ PORT_DIPNAME(0x08, 0x00, "Bank/Page 32")
+ PORT_DIPLOCATION("S:4")
+ PORT_DIPSETTING(0x00, "Off")
+ PORT_DIPSETTING(0x08, "On")
+ PORT_DIPNAME(0x10, 0x00, "Bank/Page 02")
+ PORT_DIPLOCATION("S:5")
+ PORT_DIPSETTING(0x00, "Off")
+ PORT_DIPSETTING(0x10, "On")
+ PORT_DIPNAME(0x20, 0x00, "48k/32k")
+ PORT_DIPLOCATION("S:6")
+ PORT_DIPSETTING(0x00, "Off")
+ PORT_DIPSETTING(0x20, "On")
+INPUT_PORTS_END
+
+ioport_constructor sv807_device::device_input_ports() const
+{
+ return INPUT_PORTS_NAME( sv807_switches );
+}
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// sv807_device - constructor
+//-------------------------------------------------
+
+sv807_device::sv807_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, SV803, "SV-807 64k RAM Cartridge", tag, owner, clock, "sv807", __FILE__),
+ device_svi_slot_interface(mconfig, *this),
+ m_switch(*this, "S"),
+ m_bk21(1), m_bk22(1), m_bk31(1), m_bk32(1)
+{
+ m_ram_bank1 = std::make_unique<UINT8[]>(0x8000);
+ m_ram_bank2 = std::make_unique<UINT8[]>(0x8000);
+ memset(m_ram_bank1.get(), 0xff, 0x8000);
+ memset(m_ram_bank2.get(), 0xff, 0x8000);
+}
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void sv807_device::device_start()
+{
+ // register for savestates
+ save_item(NAME(m_bk21));
+ save_item(NAME(m_bk22));
+ save_item(NAME(m_bk31));
+ save_item(NAME(m_bk32));
+ save_pointer(NAME(m_ram_bank1.get()), 0x8000);
+ save_pointer(NAME(m_ram_bank2.get()), 0x8000);
+}
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void sv807_device::device_reset()
+{
+}
+
+
+//**************************************************************************
+// IMPLEMENTATION
+//**************************************************************************
+
+// test setup: S2 = enabled (22), S3 = enabled (31)
+
+READ8_MEMBER( sv807_device::mreq_r )
+{
+ if ((BK21_ACTIVE || BK31_ACTIVE) && offset < 0x8000)
+ {
+ m_bus->romdis_w(0);
+ return m_ram_bank1[offset];
+ }
+
+ if ((BK22_ACTIVE || BK32_ACTIVE || BK02_ACTIVE) && offset >= 0x8000)
+ {
+ m_bus->ramdis_w(0);
+ return m_ram_bank2[offset - 0x8000];
+ }
+
+ return 0xff;
+}
+
+WRITE8_MEMBER( sv807_device::mreq_w )
+{
+ if ((BK21_ACTIVE || BK31_ACTIVE) && offset < 0x8000)
+ {
+ m_bus->romdis_w(0);
+ m_ram_bank1[offset] = data;
+ }
+
+ if ((BK22_ACTIVE || BK32_ACTIVE || BK02_ACTIVE) && offset >= 0x8000)
+ {
+ m_bus->ramdis_w(0);
+ m_ram_bank2[offset - 0x8000] = data;
+ }
+}
+
+void sv807_device::bk21_w(int state)
+{
+ m_bk21 = state;
+}
+
+void sv807_device::bk22_w(int state)
+{
+ m_bk22 = state;
+}
+
+void sv807_device::bk31_w(int state)
+{
+ m_bk31 = state;
+}
+
+void sv807_device::bk32_w(int state)
+{
+ m_bk32 = state;
+}
diff --git a/src/devices/bus/svi3x8/slot/sv807.h b/src/devices/bus/svi3x8/slot/sv807.h
new file mode 100644
index 00000000000..deebb9bf79e
--- /dev/null
+++ b/src/devices/bus/svi3x8/slot/sv807.h
@@ -0,0 +1,60 @@
+// license:GPL-2.0+
+// copyright-holders:Dirk Best
+/***************************************************************************
+
+ SV-807 64k memory expansion for SVI-318/328
+
+***************************************************************************/
+
+#pragma once
+
+#ifndef __SVI3X8_SLOT_SV807_H__
+#define __SVI3X8_SLOT_SV807_H__
+
+#include "emu.h"
+#include "slot.h"
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> sv807_device
+
+class sv807_device : public device_t, public device_svi_slot_interface
+{
+public:
+ // construction/destruction
+ sv807_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // optional information overrides
+ virtual ioport_constructor device_input_ports() const override;
+
+ virtual DECLARE_READ8_MEMBER( mreq_r ) override;
+ virtual DECLARE_WRITE8_MEMBER( mreq_w ) override;
+
+ virtual void bk21_w(int state) override;
+ virtual void bk22_w(int state) override;
+ virtual void bk31_w(int state) override;
+ virtual void bk32_w(int state) override;
+
+protected:
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+private:
+ required_ioport m_switch;
+
+ std::unique_ptr<UINT8[]> m_ram_bank1;
+ std::unique_ptr<UINT8[]> m_ram_bank2;
+
+ int m_bk21;
+ int m_bk22;
+ int m_bk31;
+ int m_bk32;
+};
+
+// device type definition
+extern const device_type SV807;
+
+#endif // __SVI3X8_SLOT_SV807_H__
diff --git a/src/devices/bus/ti99x/gromport.cpp b/src/devices/bus/ti99x/gromport.cpp
index 9e1533cb9a8..baa77932f7e 100644
--- a/src/devices/bus/ti99x/gromport.cpp
+++ b/src/devices/bus/ti99x/gromport.cpp
@@ -148,7 +148,7 @@
static void image_battery_load_by_name(emu_options &options, const char *filename, void *buffer, int length, int fill)
{
- file_error filerr;
+ osd_file::error filerr;
int bytes_read = 0;
assert_always(buffer && (length > 0), "Must specify sensical buffer/length");
@@ -156,7 +156,7 @@ static void image_battery_load_by_name(emu_options &options, const char *filenam
/* try to open the battery file and read it in, if possible */
emu_file file(options.nvram_directory(), OPEN_FLAG_READ);
filerr = file.open(filename);
- if (filerr == FILERR_NONE)
+ if (filerr == osd_file::error::NONE)
bytes_read = file.read(buffer, length);
/* fill remaining bytes (if necessary) */
@@ -174,8 +174,8 @@ static void image_battery_save_by_name(emu_options &options, const char *filenam
/* try to open the battery file and write it out, if possible */
emu_file file(options.nvram_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
- file_error filerr = file.open(filename);
- if (filerr == FILERR_NONE)
+ osd_file::error filerr = file.open(filename);
+ if (filerr == osd_file::error::NONE)
file.write(buffer, length);
}
@@ -2245,43 +2245,46 @@ rpk_socket::rpk_socket(const char* id, int length, UINT8* contents)
/*
Locate a file in the ZIP container
*/
-const zip_file_header* rpk_reader::find_file(zip_file *zip, const char *filename, UINT32 crc)
+int rpk_reader::find_file(util::archive_file &zip, const char *filename, UINT32 crc)
{
- const zip_file_header *header;
- for (header = zip_file_first_file(zip); header != nullptr; header = zip_file_next_file(zip))
+ for (int header = zip.first_file(); header >= 0; header = zip.next_file())
{
- // We don't check for CRC == 0.
- if (crc != 0)
+ // Ignore directories
+ if (!zip.current_is_directory())
{
- // if the CRC and name both match, we're good
- // if the CRC matches and the name doesn't, we're still good
- if (header->crc == crc)
- return header;
- }
- else
- {
- if (core_stricmp(header->filename, filename)==0)
+ // We don't check for CRC == 0.
+ if (crc != 0)
+ {
+ // if the CRC and name both match, we're good
+ // if the CRC matches and the name doesn't, we're still good
+ if (zip.current_crc() == crc)
+ return header;
+ }
+ else
{
- return header;
+ if (core_stricmp(zip.current_name().c_str(), filename) == 0)
+ {
+ return header;
+ }
}
}
}
- return nullptr;
+ return -1;
}
/*
Load a rom resource and put it in a pcb socket instance.
*/
-rpk_socket* rpk_reader::load_rom_resource(zip_file* zip, xml_data_node* rom_resource_node, const char* socketname)
+rpk_socket* rpk_reader::load_rom_resource(util::archive_file &zip, xml_data_node* rom_resource_node, const char* socketname)
{
const char* file;
const char* crcstr;
const char* sha1;
- zip_error ziperr;
+ util::archive_file::error ziperr;
UINT32 crc;
int length;
UINT8* contents;
- const zip_file_header *header;
+ int header;
// find the file attribute (required)
file = xml_get_attribute_string(rom_resource_node, "file", nullptr);
@@ -2301,19 +2304,19 @@ rpk_socket* rpk_reader::load_rom_resource(zip_file* zip, xml_data_node* rom_reso
crc = strtoul(crcstr, nullptr, 16);
header = find_file(zip, file, crc);
}
- if (header == nullptr) throw rpk_exception(RPK_INVALID_FILE_REF, "File not found or CRC check failed");
+ if (header < 0) throw rpk_exception(RPK_INVALID_FILE_REF, "File not found or CRC check failed");
- length = header->uncompressed_length;
+ length = zip.current_uncompressed_length();
// Allocate storage
contents = global_alloc_array_clear<UINT8>(length);
if (contents==nullptr) throw rpk_exception(RPK_OUT_OF_MEMORY);
// and unzip file from the zip file
- ziperr = zip_file_decompress(zip, contents, length);
- if (ziperr != ZIPERR_NONE)
+ ziperr = zip.decompress(contents, length);
+ if (ziperr != util::archive_file::error::NONE)
{
- if (ziperr == ZIPERR_UNSUPPORTED) throw rpk_exception(RPK_ZIP_UNSUPPORTED);
+ if (ziperr == util::archive_file::error::UNSUPPORTED) throw rpk_exception(RPK_ZIP_UNSUPPORTED);
else throw rpk_exception(RPK_ZIP_ERROR);
}
@@ -2414,15 +2417,14 @@ rpk_socket* rpk_reader::load_ram_resource(emu_options &options, xml_data_node* r
rpk* rpk_reader::open(emu_options &options, const char *filename, const char *system_name)
{
- zip_error ziperr;
+ util::archive_file::error ziperr;
- const zip_file_header *header;
const char *pcb_type;
const char *id;
const char *uses_name;
const char *resource_name;
- zip_file* zipfile;
+ util::archive_file::ptr zipfile;
std::vector<char> layout_text;
xml_data_node *layout_xml = nullptr;
@@ -2442,25 +2444,24 @@ rpk* rpk_reader::open(emu_options &options, const char *filename, const char *sy
try
{
/* open the ZIP file */
- ziperr = zip_file_open(filename, &zipfile);
- if (ziperr != ZIPERR_NONE) throw rpk_exception(RPK_NOT_ZIP_FORMAT);
+ ziperr = util::archive_file::open_zip(filename, zipfile);
+ if (ziperr != util::archive_file::error::NONE) throw rpk_exception(RPK_NOT_ZIP_FORMAT);
/* find the layout.xml file */
- header = find_file(zipfile, "layout.xml", 0);
- if (header == nullptr) throw rpk_exception(RPK_MISSING_LAYOUT);
+ if (find_file(*zipfile, "layout.xml", 0) < 0) throw rpk_exception(RPK_MISSING_LAYOUT);
/* reserve space for the layout file contents (+1 for the termination) */
- layout_text.resize(header->uncompressed_length + 1);
+ layout_text.resize(zipfile->current_uncompressed_length() + 1);
/* uncompress the layout text */
- ziperr = zip_file_decompress(zipfile, &layout_text[0], header->uncompressed_length);
- if (ziperr != ZIPERR_NONE)
+ ziperr = zipfile->decompress(&layout_text[0], zipfile->current_uncompressed_length());
+ if (ziperr != util::archive_file::error::NONE)
{
- if (ziperr == ZIPERR_UNSUPPORTED) throw rpk_exception(RPK_ZIP_UNSUPPORTED);
+ if (ziperr == util::archive_file::error::UNSUPPORTED) throw rpk_exception(RPK_ZIP_UNSUPPORTED);
else throw rpk_exception(RPK_ZIP_ERROR);
}
- layout_text[header->uncompressed_length] = '\0'; // Null-terminate
+ layout_text[zipfile->current_uncompressed_length()] = '\0'; // Null-terminate
/* parse the layout text */
layout_xml = xml_string_read(&layout_text[0], nullptr);
@@ -2523,7 +2524,7 @@ rpk* rpk_reader::open(emu_options &options, const char *filename, const char *sy
// found it
if (strcmp(resource_node->name, "rom")==0)
{
- newsock = load_rom_resource(zipfile, resource_node, id);
+ newsock = load_rom_resource(*zipfile, resource_node, id);
newrpk->add_socket(id, newsock);
}
else
@@ -2545,14 +2546,12 @@ rpk* rpk_reader::open(emu_options &options, const char *filename, const char *sy
{
newrpk->close();
if (layout_xml != nullptr) xml_file_free(layout_xml);
- if (zipfile != nullptr) zip_file_close(zipfile);
// rethrow the exception
throw;
}
if (layout_xml != nullptr) xml_file_free(layout_xml);
- if (zipfile != nullptr) zip_file_close(zipfile);
return newrpk;
}
diff --git a/src/devices/bus/ti99x/gromport.h b/src/devices/bus/ti99x/gromport.h
index 7655173b10d..36900c40045 100644
--- a/src/devices/bus/ti99x/gromport.h
+++ b/src/devices/bus/ti99x/gromport.h
@@ -454,10 +454,10 @@ public:
rpk *open(emu_options &options, const char *filename, const char *system_name);
private:
- const zip_file_header* find_file(zip_file *zip, const char *filename, UINT32 crc);
- rpk_socket* load_rom_resource(zip_file* zip, xml_data_node* rom_resource_node, const char* socketname);
- rpk_socket* load_ram_resource(emu_options &options, xml_data_node* ram_resource_node, const char* socketname, const char* system_name);
- const pcb_type* m_types;
+ int find_file(util::archive_file &zip, const char *filename, UINT32 crc);
+ rpk_socket* load_rom_resource(util::archive_file &zip, xml_data_node* rom_resource_node, const char* socketname);
+ rpk_socket* load_ram_resource(emu_options &options, xml_data_node* ram_resource_node, const char* socketname, const char* system_name);
+ const pcb_type* m_types;
};
class rpk
diff --git a/src/devices/cpu/tms0980/tms0980.cpp b/src/devices/cpu/tms0980/tms0980.cpp
deleted file mode 100644
index 3ea3ca918b1..00000000000
--- a/src/devices/cpu/tms0980/tms0980.cpp
+++ /dev/null
@@ -1,1514 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Wilbert Pol, hap
-/*
-
- TMS0980/TMS1000-family MCU cores
-
- TODO:
- - emulate TMS1600 L-pins
- - fix debugger disasm view
-
-
-The TMS0980 and TMS1000-family MCU cores are very similar. The TMS0980 has a
-slightly bigger addressable area and uses 9bit instructions where the TMS1000
-family uses 8bit instruction. The instruction set themselves are very similar
-though.
-
-Each instruction takes 12 cycles to execute in 2 phases: a fetch phase and an
-execution phase. The execution phase takes place at the same time as the fetch
-phase of the next instruction. So, during execution there are both fetch and
-execution operations taking place. The operation can be split up as follows:
-cycle #0
- - Fetch:
- 1. ROM address 0
- - Execute:
- 1. Read RAM
- 2. Clear ALU inputs
- 3. Execute BRANCH/CALL/RETN part #2
- 4. K input valid
-cycle #1
- - Fetch:
- 1. ROM address 1
- - Execute:
- 1. Update ALU inputs
-cycle #2
- - Fetch:
- 1. nothing/wait(?)
- - Execute:
- 1. Perform ALU operation
- 2. Write RAM
-cycle #3
- - Fetch:
- 1. Fetch/Update PC/RAM address #1
- - Execute:
- 1. Register store part #1
-cycle #4
- - Fetch:
- 1. Fetch/Update PC/RAM address #2
- - Execute:
- 1. Register store part #2
-cycle #5
- - Fetch:
- 1. Instruction decode
- - Execute:
- 1. Execute BRANCH/CALL/RETN part #1
-
-*/
-
-#include "tms0980.h"
-#include "debugger.h"
-
-/*
-
-The MCU cores contains a set of fixed instructions and a set of
-instructions created using microinstructions. A subset of the
-instruction set could be defined from the microinstructions by
-TI customers.
-
-cycle #0: 15TN, ATN, CIN, CKN, CKP, DMTP, MTN, MTP, NATN, NDMTP, YTP
-cycle #2: C8(?), CKM, NE(?), STO
-cycle #3,#4: AUTA, AUTY
-
-unknown cycle: CME, SSE, SSS
-
-*/
-
-/* Microinstructions */
-#define M_15TN (1<<0) /* 15 to -ALU */
-#define M_ATN (1<<1) /* ACC to -ALU */
-#define M_AUTA (1<<2) /* ALU to ACC */
-#define M_AUTY (1<<3) /* ALU to Y */
-#define M_C8 (1<<4) /* CARRY8 to STATUS */
-#define M_CIN (1<<5) /* Carry In to ALU */
-#define M_CKM (1<<6) /* CKB to MEM */
-#define M_CKN (1<<7) /* CKB to -ALU */
-#define M_CKP (1<<8) /* CKB to +ALU */
-#define M_MTN (1<<9) /* MEM to -ALU */
-#define M_MTP (1<<10) /* MEM to +ALU */
-#define M_NATN (1<<11) /* ~ACC to -ALU */
-#define M_NE (1<<12) /* COMP to STATUS */
-#define M_STO (1<<13) /* ACC to MEM */
-#define M_STSL (1<<14) /* STATUS to Status Latch */
-#define M_YTP (1<<15) /* Y to +ALU */
-
-#define M_CME (1<<16) /* Conditional Memory Enable */
-#define M_DMTP (1<<17) /* DAM to +ALU */
-#define M_NDMTP (1<<18) /* ~DAM to +ALU */
-#define M_SSE (1<<19) /* Special Status Enable */
-#define M_SSS (1<<20) /* Special Status Sample */
-
-#define M_RSTR (1<<21) /* -> line #36, F_RSTR (TMS02x0 custom) */
-#define M_UNK1 (1<<22) /* -> line #37, F_???? (TMS0270 custom) */
-
-/* Standard/fixed instructions - these are documented more in their specific handlers below */
-#define F_BR (1<<0)
-#define F_CALL (1<<1)
-#define F_CLO (1<<2)
-#define F_COMC (1<<3)
-#define F_COMX (1<<4)
-#define F_COMX8 (1<<5)
-#define F_LDP (1<<6)
-#define F_LDX (1<<7)
-#define F_RBIT (1<<8)
-#define F_RETN (1<<9)
-#define F_RSTR (1<<10)
-#define F_SBIT (1<<11)
-#define F_SETR (1<<12)
-#define F_TDO (1<<13)
-#define F_TPC (1<<14)
-
-#define F_OFF (1<<15)
-#define F_REAC (1<<16)
-#define F_SAL (1<<17)
-#define F_SBL (1<<18)
-#define F_SEAC (1<<19)
-#define F_XDA (1<<20)
-
-
-// supported types:
-// note: dice information assumes the orientation is pictured with RAM at the bottom-left, except where noted
-
-// TMS1000
-// - 64x4bit RAM array at the bottom-left
-// - 1024x8bit ROM array at the bottom-right
-// * FYI, the row-selector to the left of it is laid out as:
-// 3,4,11,12,19,20,27,28,35,36,43,44,51,52,59,60,0,7,8,15,16,23,24,31,32,39,40,47,48,55,56,63,
-// 2,5,10,13,18,21,26,29,34,37,42,45,50,53,58,61,1,6,9,14,17,22,25,30,33,38,41,46,49,54,57,62
-// - 30-term microinstructions PLA(mpla) at the top half, to the right of the midline, supporting 16 microinstructions
-// - 20-term output PLA(opla) at the top-left
-// - the ALU is between the opla and mpla
-const device_type TMS1000 = &device_creator<tms1000_cpu_device>; // 28-pin DIP, 11 R pins
-const device_type TMS1070 = &device_creator<tms1070_cpu_device>; // high voltage version
-const device_type TMS1040 = &device_creator<tms1040_cpu_device>; // same as TMS1070 with just a different pinout?
-const device_type TMS1200 = &device_creator<tms1200_cpu_device>; // 40-pin DIP, 13 R pins
-// TMS1270 has 10 O pins, how does that work?
-
-// TMS1100 is nearly the same as TMS1000, some different opcodes, and with double the RAM and ROM
-const device_type TMS1100 = &device_creator<tms1100_cpu_device>; // 28-pin DIP, 11 R pins
-const device_type TMS1170 = &device_creator<tms1170_cpu_device>; // high voltage version
-const device_type TMS1300 = &device_creator<tms1300_cpu_device>; // 40-pin DIP, 16 R pins
-const device_type TMS1370 = &device_creator<tms1370_cpu_device>; // high voltage version
-
-// TMS1400 follows the TMS1100, it doubles the ROM size again (4 chapters of 16 pages), and adds a 3-level callstack
-// - rotate the view and mirror the OR-mask to get the proper layout of the mpla, the default is identical to tms1100
-// - the opla size is increased from 20 to 32 terms
-const device_type TMS1400 = &device_creator<tms1400_cpu_device>; // 28-pin DIP, 11 R pins (TMS1400CR is same, but with TMS1100 pinout)
-const device_type TMS1470 = &device_creator<tms1470_cpu_device>; // high voltage version, 1 R pin removed for Vdd
-
-// TMS1600 adds more I/O to the TMS1400, input pins are doubled with added L1,2,4,8
-// - rotate the view and mirror the OR-mask to get the proper layout of the mpla, the default is identical to tms1100
-// - the opla size is increased from 20 to 32 terms
-const device_type TMS1600 = &device_creator<tms1600_cpu_device>; // 40-pin DIP, 16 R pins
-const device_type TMS1670 = &device_creator<tms1670_cpu_device>; // high voltage version
-
-// TMS0980
-// - 64x9bit RAM array at the bottom-left (set up as 144x4)
-// - 2048x9bit ROM array at the bottom-left
-// - main instructions PLAs at the top half, to the right of the midline
-// * top section is assumed to be the CKI bus select
-// * middle section is for microinstruction redirection, this part may differ per die
-// * rest is fixed instructions select, from top-to-bottom: SEAC, LDX, COMX, COMX8,
-// TDO, SBIT, RETN, SETR, REAC, XDA, SAL, RBIT, ..., OFF, SBL, LDP, redir(------00- + R0^BL)
-// - 64-term microinstructions PLA between the RAM and ROM, supporting 20 microinstructions
-// - 16-term inverted output PLA and segment PLA above the RAM (rotate opla 90 degrees)
-const device_type TMS0980 = &device_creator<tms0980_cpu_device>; // 28-pin DIP, 9 R pins
-
-// TMS1980 is a TMS0980 with a TMS1x00 style opla
-// - RAM, ROM, and main instructions PLAs is the same as TMS0980
-// - one of the microinstructions redirects to a RSTR instruction, like on TMS0270
-// - 32-term inverted output PLA above the RAM, 7 bits! (rotate opla 270 degrees)
-const device_type TMS1980 = &device_creator<tms1980_cpu_device>; // 28-pin DIP, 7 O pins, 10 R pins, high voltage
-
-// TMS0950 is a TMS1000 with a TMS0980 style opla, it was quickly succeeded by the TMS0970
-// - RAM, ROM, microinstructions is the same as TMS1000
-// - 10-term inverted output PLA and segment PLA on the top-left
-const device_type TMS0950 = &device_creator<tms0950_cpu_device>; // 28-pin DIP, 8 O pins, 11? R pins
-
-// TMS0970 is a stripped-down version of the TMS0980, itself acting more like a TMS1000
-// - RAM and ROM is the same as TMS1000
-// - main instructions PLAs at the top half, to the right of the midline
-// * see TMS0980 notes, except that the fixed instruction list differs:
-// RETN, SETR, RBIT, SBIT, LDX, COMX, TDO, ..., redir(----0-00), LDP
-// - 32-term microinstructions PLA between the RAM and ROM, supporting 15 microinstructions
-// - 16-term inverted output PLA and segment PLA above the RAM (rotate opla 90 degrees)
-const device_type TMS0970 = &device_creator<tms0970_cpu_device>; // 28-pin DIP, 11 R pins (note: pinout may slightly differ from chip to chip)
-const device_type TMS1990 = &device_creator<tms1990_cpu_device>; // 28-pin DIP, ? R pins..
-
-// TMS0270 on the other hand, is a TMS0980 with earrings and a new hat. The new changes look like a quick afterthought, almost hacky
-// - RAM, ROM, and main instructions PLAs is the same as TMS0980
-// - 64-term microinstructions PLA between the RAM and ROM, supporting 20 microinstructions plus optional separate lines for custom opcode handling
-// - 48-term output PLA above the RAM (rotate opla 90 degrees)
-const device_type TMS0270 = &device_creator<tms0270_cpu_device>; // 40-pin DIP, 16 O pins, 8+ R pins (some R pins are internally hooked up to support more I/O)
-// newer TMS0270 chips (eg. Speak & Math) have 42 pins
-// TMS0260 is same or similar?
-
-// TP0320 is TI's first CMOS MCU with integrated LCD controller, the die is still very similar to TMS0980
-// - ROM and main RAM is same as on TMS0980 with different row-select
-// -
-const device_type TP0320 = &device_creator<tp0320_cpu_device>; // 28-pin SDIP, ..
-
-
-// internal memory maps
-static ADDRESS_MAP_START(program_11bit_9, AS_PROGRAM, 16, tms1xxx_cpu_device)
- AM_RANGE(0x000, 0xfff) AM_ROM
-ADDRESS_MAP_END
-
-static ADDRESS_MAP_START(program_10bit_8, AS_PROGRAM, 8, tms1xxx_cpu_device)
- AM_RANGE(0x000, 0x3ff) AM_ROM
-ADDRESS_MAP_END
-
-static ADDRESS_MAP_START(program_11bit_8, AS_PROGRAM, 8, tms1xxx_cpu_device)
- AM_RANGE(0x000, 0x7ff) AM_ROM
-ADDRESS_MAP_END
-
-static ADDRESS_MAP_START(program_12bit_8, AS_PROGRAM, 8, tms1xxx_cpu_device)
- AM_RANGE(0x000, 0xfff) AM_ROM
-ADDRESS_MAP_END
-
-
-static ADDRESS_MAP_START(data_64x4, AS_DATA, 8, tms1xxx_cpu_device)
- AM_RANGE(0x00, 0x3f) AM_RAM
-ADDRESS_MAP_END
-
-static ADDRESS_MAP_START(data_128x4, AS_DATA, 8, tms1xxx_cpu_device)
- AM_RANGE(0x00, 0x7f) AM_RAM
-ADDRESS_MAP_END
-
-static ADDRESS_MAP_START(data_64x9_as4, AS_DATA, 8, tms1xxx_cpu_device)
- AM_RANGE(0x00, 0x7f) AM_RAM
- AM_RANGE(0x80, 0x8f) AM_RAM AM_MIRROR(0x70) // DAM
-ADDRESS_MAP_END
-
-
-// device definitions
-tms1000_cpu_device::tms1000_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
- : tms1xxx_cpu_device(mconfig, TMS1000, "TMS1000", tag, owner, clock, 8 /* o pins */, 11 /* r pins */, 6 /* pc bits */, 8 /* byte width */, 2 /* x width */, 10 /* prg width */, ADDRESS_MAP_NAME(program_10bit_8), 6 /* data width */, ADDRESS_MAP_NAME(data_64x4), "tms1000", __FILE__)
-{ }
-
-tms1000_cpu_device::tms1000_cpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT8 o_pins, UINT8 r_pins, UINT8 pc_bits, UINT8 byte_bits, UINT8 x_bits, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data, const char *shortname, const char *source)
- : tms1xxx_cpu_device(mconfig, type, name, tag, owner, clock, o_pins, r_pins, pc_bits, byte_bits, x_bits, prgwidth, program, datawidth, data, shortname, source)
-{ }
-
-tms1070_cpu_device::tms1070_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
- : tms1000_cpu_device(mconfig, TMS1070, "TMS1070", tag, owner, clock, 8, 11, 6, 8, 2, 10, ADDRESS_MAP_NAME(program_10bit_8), 6, ADDRESS_MAP_NAME(data_64x4), "tms1070", __FILE__)
-{ }
-
-tms1040_cpu_device::tms1040_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
- : tms1000_cpu_device(mconfig, TMS1040, "TMS1040", tag, owner, clock, 8, 11, 6, 8, 2, 10, ADDRESS_MAP_NAME(program_10bit_8), 6, ADDRESS_MAP_NAME(data_64x4), "tms1040", __FILE__)
-{ }
-
-tms1200_cpu_device::tms1200_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
- : tms1000_cpu_device(mconfig, TMS1200, "TMS1200", tag, owner, clock, 8, 13, 6, 8, 2, 10, ADDRESS_MAP_NAME(program_10bit_8), 6, ADDRESS_MAP_NAME(data_64x4), "tms1200", __FILE__)
-{ }
-
-
-tms1100_cpu_device::tms1100_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
- : tms1000_cpu_device(mconfig, TMS1100, "TMS1100", tag, owner, clock, 8, 11, 6, 8, 3, 11, ADDRESS_MAP_NAME(program_11bit_8), 7, ADDRESS_MAP_NAME(data_128x4), "tms1100", __FILE__)
-{ }
-
-tms1100_cpu_device::tms1100_cpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT8 o_pins, UINT8 r_pins, UINT8 pc_bits, UINT8 byte_bits, UINT8 x_bits, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data, const char *shortname, const char *source)
- : tms1000_cpu_device(mconfig, type, name, tag, owner, clock, o_pins, r_pins, pc_bits, byte_bits, x_bits, prgwidth, program, datawidth, data, shortname, source)
-{ }
-
-tms1170_cpu_device::tms1170_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
- : tms1100_cpu_device(mconfig, TMS1170, "TMS1170", tag, owner, clock, 8, 11, 6, 8, 3, 11, ADDRESS_MAP_NAME(program_11bit_8), 7, ADDRESS_MAP_NAME(data_128x4), "tms1170", __FILE__)
-{ }
-
-tms1300_cpu_device::tms1300_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
- : tms1100_cpu_device(mconfig, TMS1300, "TMS1300", tag, owner, clock, 8, 16, 6, 8, 3, 11, ADDRESS_MAP_NAME(program_11bit_8), 7, ADDRESS_MAP_NAME(data_128x4), "tms1300", __FILE__)
-{ }
-
-tms1370_cpu_device::tms1370_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
- : tms1100_cpu_device(mconfig, TMS1370, "TMS1370", tag, owner, clock, 8, 16, 6, 8, 3, 11, ADDRESS_MAP_NAME(program_11bit_8), 7, ADDRESS_MAP_NAME(data_128x4), "tms1370", __FILE__)
-{ }
-
-
-tms1400_cpu_device::tms1400_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
- : tms1100_cpu_device(mconfig, TMS1400, "TMS1400", tag, owner, clock, 8, 11, 6, 8, 3, 12, ADDRESS_MAP_NAME(program_12bit_8), 7, ADDRESS_MAP_NAME(data_128x4), "tms1400", __FILE__)
-{ }
-
-tms1400_cpu_device::tms1400_cpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT8 o_pins, UINT8 r_pins, UINT8 pc_bits, UINT8 byte_bits, UINT8 x_bits, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data, const char *shortname, const char *source)
- : tms1100_cpu_device(mconfig, type, name, tag, owner, clock, o_pins, r_pins, pc_bits, byte_bits, x_bits, prgwidth, program, datawidth, data, shortname, source)
-{ }
-
-tms1470_cpu_device::tms1470_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
- : tms1400_cpu_device(mconfig, TMS1470, "TMS1470", tag, owner, clock, 8, 10, 6, 8, 3, 12, ADDRESS_MAP_NAME(program_12bit_8), 7, ADDRESS_MAP_NAME(data_128x4), "tms1470", __FILE__)
-{ }
-
-
-tms1600_cpu_device::tms1600_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
- : tms1400_cpu_device(mconfig, TMS1600, "TMS1600", tag, owner, clock, 8, 16, 6, 8, 3, 12, ADDRESS_MAP_NAME(program_12bit_8), 7, ADDRESS_MAP_NAME(data_128x4), "tms1600", __FILE__)
-{ }
-
-tms1600_cpu_device::tms1600_cpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT8 o_pins, UINT8 r_pins, UINT8 pc_bits, UINT8 byte_bits, UINT8 x_bits, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data, const char *shortname, const char *source)
- : tms1400_cpu_device(mconfig, type, name, tag, owner, clock, o_pins, r_pins, pc_bits, byte_bits, x_bits, prgwidth, program, datawidth, data, shortname, source)
-{ }
-
-tms1670_cpu_device::tms1670_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
- : tms1600_cpu_device(mconfig, TMS1670, "TMS1670", tag, owner, clock, 8, 16, 6, 8, 3, 12, ADDRESS_MAP_NAME(program_12bit_8), 7, ADDRESS_MAP_NAME(data_128x4), "tms1670", __FILE__)
-{ }
-
-
-tms0970_cpu_device::tms0970_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
- : tms1000_cpu_device(mconfig, TMS0970, "TMS0970", tag, owner, clock, 8, 11, 6, 8, 2, 10, ADDRESS_MAP_NAME(program_10bit_8), 6, ADDRESS_MAP_NAME(data_64x4), "tms0970", __FILE__)
-{ }
-
-tms0970_cpu_device::tms0970_cpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT8 o_pins, UINT8 r_pins, UINT8 pc_bits, UINT8 byte_bits, UINT8 x_bits, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data, const char *shortname, const char *source)
- : tms1000_cpu_device(mconfig, type, name, tag, owner, clock, o_pins, r_pins, pc_bits, byte_bits, x_bits, prgwidth, program, datawidth, data, shortname, source)
-{ }
-
-tms0950_cpu_device::tms0950_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
- : tms0970_cpu_device(mconfig, TMS0950, "TMS0950", tag, owner, clock, 8, 11, 6, 8, 2, 10, ADDRESS_MAP_NAME(program_10bit_8), 6, ADDRESS_MAP_NAME(data_64x4), "tms0950", __FILE__)
-{ }
-
-tms1990_cpu_device::tms1990_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
- : tms0970_cpu_device(mconfig, TMS1990, "TMS1990", tag, owner, clock, 8, 11, 6, 8, 2, 10, ADDRESS_MAP_NAME(program_10bit_8), 6, ADDRESS_MAP_NAME(data_64x4), "tms1990", __FILE__)
-{ }
-
-
-tms0980_cpu_device::tms0980_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
- : tms0970_cpu_device(mconfig, TMS0980, "TMS0980", tag, owner, clock, 8, 9, 7, 9, 4, 12, ADDRESS_MAP_NAME(program_11bit_9), 8, ADDRESS_MAP_NAME(data_64x9_as4), "tms0980", __FILE__)
-{ }
-
-tms0980_cpu_device::tms0980_cpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT8 o_pins, UINT8 r_pins, UINT8 pc_bits, UINT8 byte_bits, UINT8 x_bits, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data, const char *shortname, const char *source)
- : tms0970_cpu_device(mconfig, type, name, tag, owner, clock, o_pins, r_pins, pc_bits, byte_bits, x_bits, prgwidth, program, datawidth, data, shortname, source)
-{ }
-
-tms1980_cpu_device::tms1980_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
- : tms0980_cpu_device(mconfig, TMS1980, "TMS1980", tag, owner, clock, 7, 10, 7, 9, 4, 12, ADDRESS_MAP_NAME(program_11bit_9), 8, ADDRESS_MAP_NAME(data_64x9_as4), "tms1980", __FILE__)
-{ }
-
-
-tms0270_cpu_device::tms0270_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
- : tms0980_cpu_device(mconfig, TMS0270, "TMS0270", tag, owner, clock, 16, 16, 7, 9, 4, 12, ADDRESS_MAP_NAME(program_11bit_9), 8, ADDRESS_MAP_NAME(data_64x9_as4), "tms0270", __FILE__)
- , m_read_ctl(*this)
- , m_write_ctl(*this)
- , m_write_pdc(*this)
-{ }
-
-
-tp0320_cpu_device::tp0320_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
- : tms0980_cpu_device(mconfig, TP0320, "TP0320", tag, owner, clock, 7, 10, 7, 9, 4, 12, ADDRESS_MAP_NAME(program_11bit_9), 8, ADDRESS_MAP_NAME(data_64x9_as4), "tp0320", __FILE__)
-{ }
-
-
-// machine configs
-static MACHINE_CONFIG_FRAGMENT(tms1000)
-
- // microinstructions PLA, output PLA
- MCFG_PLA_ADD("mpla", 8, 16, 30)
- MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
- MCFG_PLA_ADD("opla", 5, 8, 20)
- MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
-MACHINE_CONFIG_END
-
-machine_config_constructor tms1000_cpu_device::device_mconfig_additions() const
-{
- return MACHINE_CONFIG_NAME(tms1000);
-}
-
-
-static MACHINE_CONFIG_FRAGMENT(tms1400)
-
- // microinstructions PLA, output PLA
- MCFG_PLA_ADD("mpla", 8, 16, 30)
- MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
- MCFG_PLA_ADD("opla", 5, 8, 32)
- MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
-MACHINE_CONFIG_END
-
-machine_config_constructor tms1400_cpu_device::device_mconfig_additions() const
-{
- return MACHINE_CONFIG_NAME(tms1400);
-}
-
-
-static MACHINE_CONFIG_FRAGMENT(tms0950)
-
- // microinstructions PLA, output PLA, segment PLA
- MCFG_PLA_ADD("mpla", 8, 16, 30)
- MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
- MCFG_PLA_ADD("opla", 4, 8, 10)
- MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
- MCFG_PLA_ADD("spla", 3, 8, 8)
- MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
-MACHINE_CONFIG_END
-
-machine_config_constructor tms0950_cpu_device::device_mconfig_additions() const
-{
- return MACHINE_CONFIG_NAME(tms0950);
-}
-
-
-static MACHINE_CONFIG_FRAGMENT(tms0970)
-
- // main opcodes PLA, microinstructions PLA, output PLA, segment PLA
- MCFG_PLA_ADD("ipla", 8, 15, 18)
- MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
- MCFG_PLA_ADD("mpla", 5, 15, 32)
- MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
- MCFG_PLA_ADD("opla", 4, 8, 16)
- MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
- MCFG_PLA_ADD("spla", 3, 8, 8)
- MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
-MACHINE_CONFIG_END
-
-machine_config_constructor tms0970_cpu_device::device_mconfig_additions() const
-{
- return MACHINE_CONFIG_NAME(tms0970);
-}
-
-
-static MACHINE_CONFIG_FRAGMENT(tms0980)
-
- // main opcodes PLA, microinstructions PLA, output PLA, segment PLA
- MCFG_PLA_ADD("ipla", 9, 22, 24)
- MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
- MCFG_PLA_ADD("mpla", 6, 20, 64)
- MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
- MCFG_PLA_ADD("opla", 4, 8, 16)
- MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
- MCFG_PLA_ADD("spla", 3, 8, 8)
- MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
-MACHINE_CONFIG_END
-
-machine_config_constructor tms0980_cpu_device::device_mconfig_additions() const
-{
- return MACHINE_CONFIG_NAME(tms0980);
-}
-
-
-static MACHINE_CONFIG_FRAGMENT(tms1980)
-
- // main opcodes PLA, microinstructions PLA, output PLA
- MCFG_PLA_ADD("ipla", 9, 22, 24)
- MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
- MCFG_PLA_ADD("mpla", 6, 22, 64)
- MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
- MCFG_PLA_ADD("opla", 5, 7, 32)
- MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
-MACHINE_CONFIG_END
-
-machine_config_constructor tms1980_cpu_device::device_mconfig_additions() const
-{
- return MACHINE_CONFIG_NAME(tms1980);
-}
-
-
-static MACHINE_CONFIG_FRAGMENT(tms0270)
-
- // main opcodes PLA, microinstructions PLA, output PLA
- MCFG_PLA_ADD("ipla", 9, 22, 24)
- MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
- MCFG_PLA_ADD("mpla", 6, 22, 64)
- MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
- MCFG_PLA_ADD("opla", 6, 16, 48)
- MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
-MACHINE_CONFIG_END
-
-machine_config_constructor tms0270_cpu_device::device_mconfig_additions() const
-{
- return MACHINE_CONFIG_NAME(tms0270);
-}
-
-
-// disasm
-offs_t tms1000_cpu_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options)
-{
- extern CPU_DISASSEMBLE(tms1000);
- return CPU_DISASSEMBLE_NAME(tms1000)(this, buffer, pc, oprom, opram, options);
-}
-
-offs_t tms1100_cpu_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options)
-{
- extern CPU_DISASSEMBLE(tms1100);
- return CPU_DISASSEMBLE_NAME(tms1100)(this, buffer, pc, oprom, opram, options);
-}
-
-offs_t tms0980_cpu_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options)
-{
- extern CPU_DISASSEMBLE(tms0980);
- return CPU_DISASSEMBLE_NAME(tms0980)(this, buffer, pc, oprom, opram, options);
-}
-
-void tms1xxx_cpu_device::state_string_export(const device_state_entry &entry, std::string &str) const
-{
- switch (entry.index())
- {
- case STATE_GENPC:
- str = string_format("%03X", m_rom_address << ((m_byte_bits > 8) ? 1 : 0));
- break;
- }
-}
-
-
-
-//-------------------------------------------------
-// device_start - device-specific startup
-//-------------------------------------------------
-
-enum
-{
- TMS1XXX_PC=1, TMS1XXX_SR, TMS1XXX_PA, TMS1XXX_PB,
- TMS1XXX_A, TMS1XXX_X, TMS1XXX_Y, TMS1XXX_STATUS
-};
-
-void tms1xxx_cpu_device::device_start()
-{
- m_program = &space(AS_PROGRAM);
- m_data = &space(AS_DATA);
-
- m_o_mask = (1 << m_o_pins) - 1;
- m_r_mask = (1 << m_r_pins) - 1;
- m_pc_mask = (1 << m_pc_bits) - 1;
- m_x_mask = (1 << m_x_bits) - 1;
-
- // resolve callbacks
- m_read_k.resolve_safe(0);
- m_write_o.resolve_safe();
- m_write_r.resolve_safe();
- m_power_off.resolve_safe();
-
- // zerofill
- m_pc = 0;
- m_sr = 0;
- m_pa = 0;
- m_pb = 0;
- m_ps = 0;
- m_a = 0;
- m_x = 0;
- m_y = 0;
- m_ca = 0;
- m_cb = 0;
- m_cs = 0;
- m_r = 0;
- m_o = 0;
- m_cki_bus = 0;
- m_c4 = 0;
- m_p = 0;
- m_n = 0;
- m_adder_out = 0;
- m_carry_in = 0;
- m_carry_out = 0;
- m_status = 0;
- m_status_latch = 0;
- m_eac = 0;
- m_clatch = 0;
- m_add = 0;
- m_bl = 0;
-
- m_ram_in = 0;
- m_dam_in = 0;
- m_ram_out = 0;
- m_ram_address = 0;
- m_rom_address = 0;
- m_opcode = 0;
- m_fixed = 0;
- m_micro = 0;
- m_subcycle = 0;
-
- // register for savestates
- save_item(NAME(m_pc));
- save_item(NAME(m_sr));
- save_item(NAME(m_pa));
- save_item(NAME(m_pb));
- save_item(NAME(m_ps));
- save_item(NAME(m_a));
- save_item(NAME(m_x));
- save_item(NAME(m_y));
- save_item(NAME(m_ca));
- save_item(NAME(m_cb));
- save_item(NAME(m_cs));
- save_item(NAME(m_r));
- save_item(NAME(m_o));
- save_item(NAME(m_cki_bus));
- save_item(NAME(m_c4));
- save_item(NAME(m_p));
- save_item(NAME(m_n));
- save_item(NAME(m_adder_out));
- save_item(NAME(m_carry_in));
- save_item(NAME(m_carry_out));
- save_item(NAME(m_status));
- save_item(NAME(m_status_latch));
- save_item(NAME(m_eac));
- save_item(NAME(m_clatch));
- save_item(NAME(m_add));
- save_item(NAME(m_bl));
-
- save_item(NAME(m_ram_in));
- save_item(NAME(m_dam_in));
- save_item(NAME(m_ram_out));
- save_item(NAME(m_ram_address));
- save_item(NAME(m_rom_address));
- save_item(NAME(m_opcode));
- save_item(NAME(m_fixed));
- save_item(NAME(m_micro));
- save_item(NAME(m_subcycle));
-
- // register state for debugger
- state_add(TMS1XXX_PC, "PC", m_pc ).formatstr("%02X");
- state_add(TMS1XXX_SR, "SR", m_sr ).formatstr("%01X");
- state_add(TMS1XXX_PA, "PA", m_pa ).formatstr("%01X");
- state_add(TMS1XXX_PB, "PB", m_pb ).formatstr("%01X");
- state_add(TMS1XXX_A, "A", m_a ).formatstr("%01X");
- state_add(TMS1XXX_X, "X", m_x ).formatstr("%01X");
- state_add(TMS1XXX_Y, "Y", m_y ).formatstr("%01X");
- state_add(TMS1XXX_STATUS, "STATUS", m_status).formatstr("%01X");
-
- state_add(STATE_GENPC, "curpc", m_rom_address).formatstr("%03X").noshow();
- state_add(STATE_GENFLAGS, "GENFLAGS", m_sr).formatstr("%8s").noshow();
-
- m_icountptr = &m_icount;
-}
-
-void tms0270_cpu_device::device_start()
-{
- // common init
- tms1xxx_cpu_device::device_start();
-
- m_read_ctl.resolve_safe(0);
- m_write_ctl.resolve_safe();
- m_write_pdc.resolve_safe();
-
- // zerofill
- m_r_prev = 0;
- m_chipsel = 0;
- m_ctl_dir = 0;
- m_ctl_out = 0;
- m_pdc = -1; // !
-
- m_o_latch_low = 0;
- m_o_latch = 0;
- m_o_latch_prev = 0;
-
- // register for savestates
- save_item(NAME(m_r_prev));
- save_item(NAME(m_chipsel));
- save_item(NAME(m_ctl_dir));
- save_item(NAME(m_ctl_out));
- save_item(NAME(m_pdc));
-
- save_item(NAME(m_o_latch_low));
- save_item(NAME(m_o_latch));
- save_item(NAME(m_o_latch_prev));
-}
-
-
-
-//-------------------------------------------------
-// device_reset - device-specific reset
-//-------------------------------------------------
-
-void tms1xxx_cpu_device::device_reset()
-{
- m_pa = 0xf;
- m_pb = 0xf;
- m_pc = 0;
- m_ca = 0;
- m_cb = 0;
- m_cs = 0;
-
- m_eac = 0;
- m_bl = 0;
- m_add = 0;
-
- m_opcode = 0;
- m_micro = 0;
- m_fixed = 0;
-
- m_subcycle = 0;
-
- // clear outputs
- m_r = 0;
- m_write_r(0, m_r & m_r_mask, 0xffff);
- write_o_output(0);
- m_write_r(0, m_r & m_r_mask, 0xffff);
- m_power_off(0);
-}
-
-
-void tms1000_cpu_device::device_reset()
-{
- // common reset
- tms1xxx_cpu_device::device_reset();
-
- // pre-decode instructionset
- m_fixed_decode.resize(0x100);
- memset(&m_fixed_decode[0], 0, 0x100*sizeof(UINT32));
- m_micro_decode.resize(0x100);
- memset(&m_micro_decode[0], 0, 0x100*sizeof(UINT32));
-
- for (int op = 0; op < 0x100; op++)
- {
- // _____ _____ ______ _____ ______ _____ _____ _____ _____
- const UINT32 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 mask = m_mpla->read(op);
- mask ^= 0x3fc8; // invert active-negative
-
- for (int bit = 0; bit < 16; bit++)
- if (mask & (1 << bit))
- m_micro_decode[op] |= md[bit];
- }
-
- // the fixed instruction set is not programmable
- m_fixed_decode[0x00] = F_COMX;
- m_fixed_decode[0x0a] = F_TDO;
- m_fixed_decode[0x0b] = F_CLO;
- m_fixed_decode[0x0c] = F_RSTR;
- m_fixed_decode[0x0d] = F_SETR;
- m_fixed_decode[0x0f] = F_RETN;
-
- for (int i = 0x10; i < 0x20; i++) m_fixed_decode[i] = F_LDP;
- for (int i = 0x30; i < 0x34; i++) m_fixed_decode[i] = F_SBIT;
- for (int i = 0x34; i < 0x38; i++) m_fixed_decode[i] = F_RBIT;
- for (int i = 0x3c; i < 0x40; i++) m_fixed_decode[i] = F_LDX;
-
- for (int i = 0x80; i < 0xc0; i++) m_fixed_decode[i] = F_BR;
- for (int i = 0xc0; i < 0x100; i++) m_fixed_decode[i] = F_CALL;
-}
-
-void tms1100_cpu_device::device_reset()
-{
- tms1000_cpu_device::device_reset();
-
- // small differences in 00-3f area
- m_fixed_decode[0x00] = 0;
- m_fixed_decode[0x09] = F_COMX8; // !
- m_fixed_decode[0x0b] = F_COMC;
-
- for (int i = 0x28; i < 0x30; i++) m_fixed_decode[i] = F_LDX;
- for (int i = 0x3c; i < 0x40; i++) m_fixed_decode[i] = 0;
-}
-
-void tms1400_cpu_device::device_reset()
-{
- tms1100_cpu_device::device_reset();
-
- // small differences in 00-3f area
- m_fixed_decode[0x0b] = F_TPC;
-}
-
-
-void tms0970_cpu_device::device_reset()
-{
- // common reset
- tms1xxx_cpu_device::device_reset();
-
- // pre-decode instructionset
- m_fixed_decode.resize(0x100);
- memset(&m_fixed_decode[0], 0, 0x100*sizeof(UINT32));
- m_micro_decode.resize(0x100);
- memset(&m_micro_decode[0], 0, 0x100*sizeof(UINT32));
-
- for (int op = 0; op < 0x100; op++)
- {
- // upper half of the opcodes is always branch/call
- if (op & 0x80)
- m_fixed_decode[op] = (op & 0x40) ? F_CALL: F_BR;
-
- // 5 output bits select a microinstruction index
- UINT32 imask = m_ipla->read(op);
- UINT8 msel = imask & 0x1f;
-
- // but if (from bottom to top) term 1 is active and output bit 5 is 0, R2,R4-R7 directly select a microinstruction index
- if (imask & 0x40 && (imask & 0x20) == 0)
- msel = (op & 0xf) | (op >> 1 & 0x10);
-
- msel = BITSWAP8(msel,7,6,5,0,1,2,3,4); // lines are reversed
- UINT32 mmask = m_mpla->read(msel);
- mmask ^= 0x09fe; // invert active-negative
-
- // _____ _____ _____ _____ ______ _____ ______ _____ _____
- const UINT32 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++)
- if (mmask & (1 << bit))
- m_micro_decode[op] |= md[bit];
-
- // the other ipla terms each select a fixed instruction
- const UINT32 id[8] = { F_LDP, F_TDO, F_COMX, F_LDX, F_SBIT, F_RBIT, F_SETR, F_RETN };
-
- for (int bit = 0; bit < 8; bit++)
- if (imask & (0x80 << bit))
- m_fixed_decode[op] |= id[bit];
- }
-}
-
-
-UINT32 tms0980_cpu_device::decode_micro(UINT8 sel)
-{
- UINT32 decode = 0;
-
- sel = BITSWAP8(sel,7,6,0,1,2,3,4,5); // lines are reversed
- UINT32 mask = m_mpla->read(sel);
- mask ^= 0x43fc3; // invert active-negative
-
- // 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 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++)
- if (mask & (1 << bit))
- decode |= md[bit];
-
- return decode;
-}
-
-void tms0980_cpu_device::device_reset()
-{
- // common reset
- tms1xxx_cpu_device::device_reset();
-
- // pre-decode instructionset
- m_fixed_decode.resize(0x200);
- memset(&m_fixed_decode[0], 0, 0x200*sizeof(UINT32));
- m_micro_decode.resize(0x200);
- memset(&m_micro_decode[0], 0, 0x200*sizeof(UINT32));
-
- for (int op = 0; op < 0x200; op++)
- {
- // upper half of the opcodes is always branch/call
- if (op & 0x100)
- m_fixed_decode[op] = (op & 0x80) ? F_CALL: F_BR;
-
- UINT32 imask = m_ipla->read(op);
-
- // 6 output bits select a microinstruction index
- m_micro_decode[op] = decode_micro(imask & 0x3f);
-
- // the other ipla terms each select a fixed instruction
- const UINT32 id[15] = { F_LDP, F_SBL, F_OFF, F_RBIT, F_SAL, F_XDA, F_REAC, F_SETR, F_RETN, F_SBIT, F_TDO, F_COMX8, F_COMX, F_LDX, F_SEAC };
-
- for (int bit = 0; bit < 15; bit++)
- if (imask & (0x80 << bit))
- m_fixed_decode[op] |= id[bit];
- }
-
- // like on TMS0970, one of the terms directly select a microinstruction index (via R4-R8),
- // but it can't be pre-determined when it's active
- m_micro_direct.resize(0x40);
- memset(&m_micro_decode[0], 0, 0x40*sizeof(UINT32));
-
- for (int op = 0; op < 0x40; op++)
- m_micro_direct[op] = decode_micro(op);
-}
-
-void tms0270_cpu_device::device_reset()
-{
- // common reset
- tms0980_cpu_device::device_reset();
-
- m_o_latch_low = 0;
- m_o_latch = 0;
- m_o_latch_prev = 0;
-}
-
-
-
-//-------------------------------------------------
-// program counter/opcode decode
-//-------------------------------------------------
-
-void tms1xxx_cpu_device::next_pc()
-{
- // The program counter is a LFSR. To put it simply, the feedback bit is a XOR of the two highest bits,
- // but it makes an exception when all low bits are set (eg. in TMS1000 case, when PC is 0x1f or 0x3f).
- int high = 1 << (m_pc_bits - 1);
- int fb = (m_pc << 1 & high) == (m_pc & high);
-
- if (m_pc == (m_pc_mask >> 1))
- fb = 1;
- else if (m_pc == m_pc_mask)
- fb = 0;
-
- m_pc = (m_pc << 1 | fb) & m_pc_mask;
-}
-
-void tms1xxx_cpu_device::read_opcode()
-{
- debugger_instruction_hook(this, m_rom_address);
- m_opcode = m_program->read_byte(m_rom_address);
- m_c4 = BITSWAP8(m_opcode,7,6,5,4,0,1,2,3) & 0xf; // opcode operand is bitswapped for most opcodes
-
- m_fixed = m_fixed_decode[m_opcode];
- m_micro = m_micro_decode[m_opcode];
-
- next_pc();
-}
-
-void tms0980_cpu_device::read_opcode()
-{
- debugger_instruction_hook(this, m_rom_address << 1);
- m_opcode = m_program->read_word(m_rom_address << 1) & 0x1ff;
- m_c4 = BITSWAP8(m_opcode,7,6,5,4,0,1,2,3) & 0xf; // opcode operand is bitswapped for most opcodes
-
- m_fixed = m_fixed_decode[m_opcode];
-
- // if ipla term 0 is active, R4-R8 directly select a microinstruction index when R0 or R0^BL is 0
- int r0 = m_opcode >> 8 & 1;
- if (m_ipla->read(m_opcode) & 0x40 && !((r0 & m_bl) ^ r0))
- m_micro = m_micro_direct[m_opcode & 0x3f];
- else
- m_micro = m_micro_decode[m_opcode];
-
- // TMS02x0/TMS1980: RSTR is on the mpla
- if (m_micro & M_RSTR)
- m_fixed |= F_RSTR;
-
- next_pc();
-}
-
-
-
-//-------------------------------------------------
-// i/o handling
-//-------------------------------------------------
-
-void tms1xxx_cpu_device::write_o_output(UINT8 index)
-{
- // a hardcoded table is supported if the output pla is unknown
- m_o = (m_output_pla_table == nullptr) ? m_opla->read(index) : m_output_pla_table[index];
- m_write_o(0, m_o & m_o_mask, 0xffff);
-}
-
-void tms0970_cpu_device::write_o_output(UINT8 index)
-{
- m_o = m_spla->read(index);
- m_write_o(0, m_o & m_o_mask, 0xffff);
-}
-
-
-void tms0270_cpu_device::dynamic_output()
-{
- // R11: TMS5100 CTL port direction (0=read from TMS5100, 1=write to TMS5100)
- m_ctl_dir = m_r >> 11 & 1;
-
- // R12: chip select (off=display via OPLA, on=TMS5100 via ACC/CKB)
- m_chipsel = m_r >> 12 & 1;
-
- if (m_chipsel)
- {
- // ACC via SEG G,B,C,D: TMS5100 CTL pins
- if (m_ctl_dir && m_a != m_ctl_out)
- {
- m_ctl_out = m_a;
- m_write_ctl(0, m_ctl_out, 0xff);
- }
-
- // R10 via SEG E: TMS5100 PDC pin
- if (m_pdc != (m_r >> 10 & 1))
- {
- m_pdc = m_r >> 10 & 1;
- m_write_pdc(m_pdc);
- }
- }
- else
- {
- // standard O-output
- if (m_o_latch != m_o_latch_prev)
- {
- write_o_output(m_o_latch);
- m_o_latch_prev = m_o_latch;
- }
- }
-
- // standard R-output
- if (m_r != m_r_prev)
- {
- m_write_r(0, m_r & m_r_mask, 0xffff);
- m_r_prev = m_r;
- }
-}
-
-
-UINT8 tms1xxx_cpu_device::read_k_input()
-{
- // K1,2,4,8 (KC test pin is not emulated)
- return m_read_k(0, 0xff) & 0xf;
-}
-
-UINT8 tms0980_cpu_device::read_k_input()
-{
- UINT8 k = m_read_k(0, 0xff) & 0x1f;
- UINT8 k3 = (k & 0x10) ? 3: 0; // the TMS0980 K3 line is simply K1|K2
- return (k & 0xf) | k3;
-}
-
-UINT8 tms0270_cpu_device::read_k_input()
-{
- // external: TMS5100 CTL port via SEG G,B,C,D
- if (m_chipsel)
- return (m_ctl_dir) ? m_ctl_out : m_read_ctl(0, 0xff) & 0xf;
-
- // standard K-input otherwise
- UINT8 k = m_read_k(0, 0xff) & 0x1f;
- return (k & 0x10) ? 0xf : k; // the TMS0270 KF line asserts all K-inputs
-}
-
-
-void tms1xxx_cpu_device::set_cki_bus()
-{
- switch (m_opcode & 0xf8)
- {
- // 00001XXX: K-inputs
- case 0x08:
- m_cki_bus = read_k_input();
- break;
-
- // 0011XXXX: select bit
- case 0x30: case 0x38:
- m_cki_bus = 1 << (m_c4 >> 2) ^ 0xf;
- break;
-
- // 01XXXXXX: constant
- case 0x00: // R2,3,4 are NANDed with eachother, and then ORed with R1, making 00000XXX valid too
- case 0x40: case 0x48: case 0x50: case 0x58: case 0x60: case 0x68: case 0x70: case 0x78:
- m_cki_bus = m_c4;
- break;
-
- default:
- m_cki_bus = 0;
- break;
- }
-}
-
-void tms0980_cpu_device::set_cki_bus()
-{
- switch (m_opcode & 0x1f8)
- {
- // 000001XXX: K-inputs
- case 0x008:
- m_cki_bus = read_k_input();
- break;
-
- // 0X0100XXX: select bit
- case 0x020: case 0x0a0:
- m_cki_bus = 1 << (m_c4 >> 2) ^ 0xf;
- break;
-
- // 0X1XXXXXX: constant
- case 0x040: case 0x048: case 0x050: case 0x058: case 0x060: case 0x068: case 0x070: case 0x078:
- case 0x0c0: case 0x0c8: case 0x0d0: case 0x0d8: case 0x0e0: case 0x0e8: case 0x0f0: case 0x0f8:
- m_cki_bus = m_c4;
- break;
-
- default:
- m_cki_bus = 0;
- break;
- }
-}
-
-
-
-//-------------------------------------------------
-// fixed opcode set
-//-------------------------------------------------
-
-// handle branches:
-
-// TMS1000/common
-// note: add(latch) and bl(branch latch) are specific to 0980 series,
-// c(chapter) bits are specific to 1100(and 1400) series
-
-void tms1xxx_cpu_device::op_br()
-{
- // BR/BL: conditional branch
- if (m_status)
- {
- if (m_clatch == 0)
- m_pa = m_pb;
- m_ca = m_cb;
- m_pc = m_opcode & m_pc_mask;
- }
-}
-
-void tms1xxx_cpu_device::op_call()
-{
- // CALL/CALLL: conditional call
- if (m_status)
- {
- UINT8 prev_pa = m_pa;
-
- if (m_clatch == 0)
- {
- m_clatch = 1;
- m_sr = m_pc;
- m_pa = m_pb;
- m_cs = m_ca;
- }
- m_ca = m_cb;
- m_pb = prev_pa;
- m_pc = m_opcode & m_pc_mask;
- }
-}
-
-void tms1xxx_cpu_device::op_retn()
-{
- // RETN: return from subroutine
- if (m_clatch == 1)
- {
- m_clatch = 0;
- m_pc = m_sr;
- m_ca = m_cs;
- }
- m_add = 0;
- m_bl = 0;
- m_pa = m_pb;
-}
-
-
-// TMS1400-specific
-
-void tms1400_cpu_device::op_br()
-{
- // BR/BL: conditional branch
- if (m_status)
- {
- m_pa = m_pb; // don't care about clatch
- m_ca = m_cb;
- m_pc = m_opcode & m_pc_mask;
- }
-}
-
-void tms1400_cpu_device::op_call()
-{
- // CALL/CALLL: conditional call
- if (m_status)
- {
- // 3-level stack, mask clatch 3 bits (no need to mask others)
- m_clatch = (m_clatch << 1 | 1) & 7;
-
- m_sr = m_sr << m_pc_bits | m_pc;
- m_pc = m_opcode & m_pc_mask;
-
- m_ps = m_ps << 4 | m_pa;
- m_pa = m_pb;
-
- m_cs = m_cs << 2 | m_ca;
- m_ca = m_cb;
- }
- else
- {
- m_pb = m_pa;
- m_cb = m_ca;
- }
-}
-
-void tms1400_cpu_device::op_retn()
-{
- // RETN: return from subroutine
- if (m_clatch & 1)
- {
- m_clatch >>= 1;
-
- m_pc = m_sr & m_pc_mask;
- m_sr >>= m_pc_bits;
-
- m_pa = m_pb = m_ps & 0xf;
- m_ps >>= 4;
-
- m_ca = m_cb = m_cs & 3;
- m_cs >>= 2;
- }
-}
-
-
-// handle other:
-
-// TMS1000/common
-
-void tms1xxx_cpu_device::op_sbit()
-{
- // SBIT: set memory bit
- if (m_ram_out == -1)
- m_ram_out = m_ram_in;
- m_ram_out |= (m_cki_bus ^ 0xf);
-}
-
-void tms1xxx_cpu_device::op_rbit()
-{
- // RBIT: reset memory bit
- if (m_ram_out == -1)
- m_ram_out = m_ram_in;
- m_ram_out &= m_cki_bus;
-}
-
-void tms1xxx_cpu_device::op_setr()
-{
- // SETR: set one R-output line
- m_r = m_r | (1 << m_y);
- m_write_r(0, m_r & m_r_mask, 0xffff);
-}
-
-void tms1xxx_cpu_device::op_rstr()
-{
- // RSTR: reset one R-output line
- m_r = m_r & ~(1 << m_y);
- m_write_r(0, m_r & m_r_mask, 0xffff);
-}
-
-void tms1xxx_cpu_device::op_tdo()
-{
- // TDO: transfer accumulator and status latch to O-output
- write_o_output(m_status_latch << 4 | m_a);
-}
-
-void tms1xxx_cpu_device::op_clo()
-{
- // CLO: clear O-output
- write_o_output(0);
-}
-
-void tms1xxx_cpu_device::op_ldx()
-{
- // LDX: load X register with (x_bits) constant
- m_x = m_c4 >> (4-m_x_bits);
-}
-
-void tms1xxx_cpu_device::op_comx()
-{
- // COMX: complement X register
- m_x ^= m_x_mask;
-}
-
-void tms1xxx_cpu_device::op_comx8()
-{
- // COMX8: complement MSB of X register
- // note: on TMS1100, the mnemonic is simply called "COMX"
- m_x ^= 1 << (m_x_bits-1);
-}
-
-void tms1xxx_cpu_device::op_ldp()
-{
- // LDP: load page buffer with constant
- m_pb = m_c4;
-}
-
-
-// TMS1100-specific
-
-void tms1100_cpu_device::op_setr()
-{
- // SETR: same, but X register MSB must be clear
- if (~m_x & (1 << (m_x_bits-1)))
- tms1xxx_cpu_device::op_setr();
-}
-
-void tms1100_cpu_device::op_rstr()
-{
- // RSTR: same, but X register MSB must be clear
- if (~m_x & (1 << (m_x_bits-1)))
- tms1xxx_cpu_device::op_rstr();
-}
-
-void tms1xxx_cpu_device::op_comc()
-{
- // COMC: complement chapter buffer
- m_cb ^= 1;
-}
-
-
-// TMS1400-specific
-
-void tms1xxx_cpu_device::op_tpc()
-{
- // TPC: transfer page buffer to chapter buffer
- m_cb = m_pb & 3;
-}
-
-
-// TMS0970-specific (and possibly child classes)
-
-void tms0970_cpu_device::op_setr()
-{
- // SETR: set output register
- // DDIG line is a coincidence between the selected output pla row(s) and segment pla row(s)
- int ddig = (m_opla->read(m_a) & m_o) ? 1 : 0;
- m_r = (m_r & ~(1 << m_y)) | (ddig << m_y);
-}
-
-void tms0970_cpu_device::op_tdo()
-{
- // TDO: transfer digits to output
- write_o_output(m_a & 0x7);
- m_write_r(0, m_r & m_r_mask, 0xffff);
-}
-
-
-// TMS0980-specific (and possibly child classes)
-
-void tms0980_cpu_device::op_comx()
-{
- // COMX: complement X register, but not the MSB
- m_x ^= (m_x_mask >> 1);
-}
-
-void tms1xxx_cpu_device::op_xda()
-{
- // XDA: exchange DAM and A
- // note: setting A to DAM is done with DMTP and AUTA during this instruction
- m_ram_address |= (0x10 << (m_x_bits-1));
-}
-
-void tms1xxx_cpu_device::op_off()
-{
- // OFF: request auto power-off
- m_power_off(1);
-}
-
-void tms1xxx_cpu_device::op_seac()
-{
- // SEAC: set end around carry
- m_eac = 1;
-}
-
-void tms1xxx_cpu_device::op_reac()
-{
- // REAC: reset end around carry
- m_eac = 0;
-}
-
-void tms1xxx_cpu_device::op_sal()
-{
- // SAL: set add latch (reset is done with RETN)
- m_add = 1;
-}
-
-void tms1xxx_cpu_device::op_sbl()
-{
- // SBL: set branch latch (reset is done with RETN)
- m_bl = 1;
-}
-
-
-// TMS1980-specific
-
-void tms1980_cpu_device::op_tdo()
-{
- // TDO: transfer accumulator and status(not status_latch!) to O-output
- write_o_output(m_status << 4 | m_a);
-}
-
-
-// TMS0270-specific
-
-void tms0270_cpu_device::op_setr()
-{
- // same as default, but handle write to output in dynamic_output
- m_r = m_r | (1 << m_y);
-}
-
-void tms0270_cpu_device::op_rstr()
-{
- // same as default, but handle write to output in dynamic_output
- m_r = m_r & ~(1 << m_y);
-}
-
-void tms0270_cpu_device::op_tdo()
-{
- // TDO: transfer data out
- if (m_status)
- m_o_latch_low = m_a;
- else
- m_o_latch = m_o_latch_low | (m_a << 4 & 0x30);
-
- // write to output is done in dynamic_output
-}
-
-
-
-//-------------------------------------------------
-// execute_run
-//-------------------------------------------------
-
-void tms1xxx_cpu_device::execute_run()
-{
- do
- {
- m_icount--;
- switch (m_subcycle)
- {
- case 0:
- // fetch: rom address 1/2
-
- // execute: br/call 2/2
- if (m_fixed & F_BR) op_br();
- if (m_fixed & F_CALL) op_call();
- if (m_fixed & F_RETN) op_retn();
-
- // execute: k input valid, read ram, clear alu inputs
- dynamic_output();
- set_cki_bus();
- m_ram_in = m_data->read_byte(m_ram_address) & 0xf;
- m_dam_in = m_data->read_byte(m_ram_address | (0x10 << (m_x_bits-1))) & 0xf;
- m_p = 0;
- m_n = 0;
- m_carry_in = 0;
-
- break;
-
- case 1:
- // fetch: rom address 2/2
- m_rom_address = (m_ca << (m_pc_bits+4)) | (m_pa << m_pc_bits) | m_pc;
-
- // execute: update alu inputs
- // N inputs
- if (m_micro & M_15TN) m_n |= 0xf;
- if (m_micro & M_ATN) m_n |= m_a;
- if (m_micro & M_NATN) m_n |= (~m_a & 0xf);
- if (m_micro & M_CKN) m_n |= m_cki_bus;
- if (m_micro & M_MTN) m_n |= m_ram_in;
-
- // P inputs
- if (m_micro & M_CKP) m_p |= m_cki_bus;
- if (m_micro & M_MTP) m_p |= m_ram_in;
- if (m_micro & M_YTP) m_p |= m_y;
- if (m_micro & M_DMTP) m_p |= m_dam_in;
- if (m_micro & M_NDMTP) m_p |= (~m_dam_in & 0xf);
-
- // carry input
- if (m_micro & M_CIN) m_carry_in |= 1;
- if (m_micro & M_SSS) m_carry_in |= m_eac;
-
- break;
-
- case 2:
- {
- // fetch: nothing
-
- // execute: perform alu logic
- // note: officially, only 1 alu operation is allowed per opcode
- m_adder_out = m_p + m_n + m_carry_in;
- int carry_out = m_adder_out >> 4 & 1;
- int status = 1;
- m_ram_out = -1;
-
- if (m_micro & M_C8) status &= carry_out;
- if (m_micro & M_NE) status &= (m_n != m_p); // COMP
- if (m_micro & M_CKM) m_ram_out = m_cki_bus;
-
- // special status circuit
- if (m_micro & M_SSE)
- {
- m_eac = m_carry_out;
- if (m_add)
- m_eac |= carry_out;
- }
- m_carry_out = carry_out;
-
- if (m_micro & M_STO || (m_micro & M_CME && m_eac == m_add))
- m_ram_out = m_a;
-
- // handle the other fixed opcodes here
- if (m_fixed & F_SBIT) op_sbit();
- if (m_fixed & F_RBIT) op_rbit();
- if (m_fixed & F_SETR) op_setr();
- if (m_fixed & F_RSTR) op_rstr();
- if (m_fixed & F_TDO) op_tdo();
- if (m_fixed & F_CLO) op_clo();
- if (m_fixed & F_LDX) op_ldx();
- if (m_fixed & F_COMX) op_comx();
- if (m_fixed & F_COMX8) op_comx8();
- if (m_fixed & F_LDP) op_ldp();
- if (m_fixed & F_COMC) op_comc();
- if (m_fixed & F_TPC) op_tpc();
- if (m_fixed & F_OFF) op_off();
- if (m_fixed & F_SEAC) op_seac();
- if (m_fixed & F_REAC) op_reac();
- if (m_fixed & F_SAL) op_sal();
- if (m_fixed & F_SBL) op_sbl();
- if (m_fixed & F_XDA) op_xda();
-
- // after fixed opcode handling: store status, write ram
- m_status = status;
- if (m_ram_out != -1)
- m_data->write_byte(m_ram_address, m_ram_out);
-
- break;
- }
-
- case 3:
- // fetch: update pc, ram address 1/2
- // execute: register store 1/2
- break;
-
- case 4:
- // execute: register store 2/2
- if (m_micro & M_AUTA) m_a = m_adder_out & 0xf;
- if (m_micro & M_AUTY) m_y = m_adder_out & 0xf;
- if (m_micro & M_STSL) m_status_latch = m_status;
-
- // fetch: update pc, ram address 2/2
- read_opcode();
- m_ram_address = m_x << 4 | m_y;
- break;
-
- case 5:
- // fetch: instruction decode (handled above, before next_pc)
- // execute: br/call 1/2
- break;
- }
- m_subcycle = (m_subcycle + 1) % 6;
- } while (m_icount > 0);
-}
diff --git a/src/devices/cpu/tms0980/tms0980.h b/src/devices/cpu/tms0980/tms0980.h
deleted file mode 100644
index c253d28ee40..00000000000
--- a/src/devices/cpu/tms0980/tms0980.h
+++ /dev/null
@@ -1,518 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Wilbert Pol, hap
-/*
-
- TMS0980/TMS1000-family MCU cores
-
-*/
-
-#ifndef _TMS0980_H_
-#define _TMS0980_H_
-
-#include "emu.h"
-#include "machine/pla.h"
-
-
-// K input pins
-#define MCFG_TMS1XXX_READ_K_CB(_devcb) \
- tms1xxx_cpu_device::set_read_k_callback(*device, DEVCB_##_devcb);
-
-// O/Segment output pins
-#define MCFG_TMS1XXX_WRITE_O_CB(_devcb) \
- tms1xxx_cpu_device::set_write_o_callback(*device, DEVCB_##_devcb);
-
-// Use this if the output PLA is unknown:
-// If the microinstructions (or other) PLA is unknown, try using one from another romset.
-#define MCFG_TMS1XXX_OUTPUT_PLA(_pla) \
- tms1xxx_cpu_device::set_output_pla(*device, _pla);
-
-// R output pins (also called D on some chips)
-#define MCFG_TMS1XXX_WRITE_R_CB(_devcb) \
- tms1xxx_cpu_device::set_write_r_callback(*device, DEVCB_##_devcb);
-
-// OFF request on TMS0980 and up
-#define MCFG_TMS1XXX_POWER_OFF_CB(_devcb) \
- tms1xxx_cpu_device::set_power_off_callback(*device, DEVCB_##_devcb);
-
-
-// TMS0270 was designed to interface with TMS5100, set it up at driver level
-#define MCFG_TMS0270_READ_CTL_CB(_devcb) \
- tms0270_cpu_device::set_read_ctl_callback(*device, DEVCB_##_devcb);
-
-#define MCFG_TMS0270_WRITE_CTL_CB(_devcb) \
- tms0270_cpu_device::set_write_ctl_callback(*device, DEVCB_##_devcb);
-
-#define MCFG_TMS0270_WRITE_PDC_CB(_devcb) \
- tms0270_cpu_device::set_write_pdc_callback(*device, DEVCB_##_devcb);
-
-
-// pinout reference
-
-/*
-
- ____ ____ ____ ____
- R8 1 |* \_/ | 28 R7 R0 1 |* \_/ | 28 Vss
- R9 2 | | 27 R6 R1 2 | | 27 OSC2
- R10 3 | | 26 R5 R2 3 | | 26 OSC1
- Vdd 4 | | 25 R4 R3 4 | | 25 O0
- K1 5 | | 24 R3 R4 5 | | 24 O1
- K2 6 | TMS1000 | 23 R2 R5 6 | | 23 O2
- K4 7 | TMS1070 | 22 R1 R6 7 | TMS1400 | 22 O3
- K8 8 | TMS1100 | 21 R0 R7 8 | | 21 O4
- INIT 9 | TMS1170 | 20 Vss R8 9 | | 20 O5
- O7 10 | | 19 OSC2 R9 10 | | 19 O6
- O6 11 | | 18 OSC1 R10 11 | | 18 O7
- O5 12 | | 17 O0 Vdd 12 | | 17 K8
- O4 13 | | 16 O1 INIT 13 | | 16 K4
- O3 14 |___________| 15 O2 K1 14 |___________| 15 K2
-
-
- ____ ____
- R2 1 |* \_/ | 28 R3
- R1 2 | | 27 R4
- R0 3 | | 26 R5
- ? 4 | | 25 R6
- Vdd 5 | | 24 R7
- K3 6 | | 23 R8
- K8 7 | TMS0980 | 22 ?
- K4 8 | | 21 ?
- K2 9 | | 20 Vss
- K1 10 | | 19 ?
- O7 11 | | 18 O0
- O6 12 | | 17 O1
- O5 13 | | 16 O2
- O4 14 |___________| 15 O3
-
- note: TMS0980 official pin names for R0-R8 is D9-D1, O0-O7 is S(A-G,DP)
-
-*/
-
-
-class tms1xxx_cpu_device : public cpu_device
-{
-public:
- // construction/destruction
- tms1xxx_cpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT8 o_pins, UINT8 r_pins, UINT8 pc_bits, UINT8 byte_bits, UINT8 x_bits, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data, const char *shortname, const char *source)
- : cpu_device(mconfig, type, name, tag, owner, clock, shortname, source)
- , m_program_config("program", ENDIANNESS_BIG, byte_bits > 8 ? 16 : 8, prgwidth, 0, program)
- , m_data_config("data", ENDIANNESS_BIG, 8, datawidth, 0, data)
- , m_mpla(*this, "mpla")
- , m_ipla(*this, "ipla")
- , m_opla(*this, "opla")
- , m_spla(*this, "spla")
- , m_o_pins(o_pins)
- , m_r_pins(r_pins)
- , m_pc_bits(pc_bits)
- , m_byte_bits(byte_bits)
- , m_x_bits(x_bits)
- , m_output_pla_table(nullptr)
- , m_read_k(*this)
- , m_write_o(*this)
- , m_write_r(*this)
- , m_power_off(*this)
- { }
-
- // static configuration helpers
- template<class _Object> static devcb_base &set_read_k_callback(device_t &device, _Object object) { return downcast<tms1xxx_cpu_device &>(device).m_read_k.set_callback(object); }
- template<class _Object> static devcb_base &set_write_o_callback(device_t &device, _Object object) { return downcast<tms1xxx_cpu_device &>(device).m_write_o.set_callback(object); }
- template<class _Object> static devcb_base &set_write_r_callback(device_t &device, _Object object) { return downcast<tms1xxx_cpu_device &>(device).m_write_r.set_callback(object); }
- template<class _Object> static devcb_base &set_power_off_callback(device_t &device, _Object object) { return downcast<tms1xxx_cpu_device &>(device).m_power_off.set_callback(object); }
- static void set_output_pla(device_t &device, const UINT16 *output_pla) { downcast<tms1xxx_cpu_device &>(device).m_output_pla_table = output_pla; }
-
-protected:
- // device-level overrides
- virtual void device_start() override;
- virtual void device_reset() override;
-
- // device_execute_interface overrides
- virtual UINT32 execute_min_cycles() const override { return 1; }
- virtual UINT32 execute_max_cycles() const override { return 6; }
- virtual UINT32 execute_input_lines() const override { return 1; }
- virtual void execute_run() override;
-
- // device_memory_interface overrides
- virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const override { return(spacenum == AS_PROGRAM) ? &m_program_config : ((spacenum == AS_DATA) ? &m_data_config : nullptr); }
-
- // device_disasm_interface overrides
- virtual UINT32 disasm_min_opcode_bytes() const override { return 1; }
- virtual UINT32 disasm_max_opcode_bytes() const override { return 1; }
-
- // device_state_interface overrides
- virtual void state_string_export(const device_state_entry &entry, std::string &str) const override;
-
- void next_pc();
-
- virtual void write_o_output(UINT8 index);
- virtual UINT8 read_k_input();
- virtual void set_cki_bus();
- virtual void dynamic_output() { ; } // not used by default
- virtual void read_opcode();
-
- virtual void op_br();
- virtual void op_call();
- virtual void op_retn();
-
- virtual void op_sbit();
- virtual void op_rbit();
- virtual void op_setr();
- virtual void op_rstr();
- virtual void op_tdo();
- virtual void op_clo();
- virtual void op_ldx();
- virtual void op_comx();
- virtual void op_comx8();
- virtual void op_ldp();
-
- virtual void op_comc();
- virtual void op_tpc();
- virtual void op_xda();
- virtual void op_off();
- virtual void op_seac();
- virtual void op_reac();
- virtual void op_sal();
- virtual void op_sbl();
-
- address_space_config m_program_config;
- address_space_config m_data_config;
-
- optional_device<pla_device> m_mpla;
- optional_device<pla_device> m_ipla;
- optional_device<pla_device> m_opla;
- optional_device<pla_device> m_spla;
-
- UINT8 m_pc; // 6 or 7-bit program counter
- UINT32 m_sr; // 6 or 7-bit subroutine return register(s)
- UINT8 m_pa; // 4-bit page address register
- UINT8 m_pb; // 4-bit page buffer register
- UINT16 m_ps; // 4-bit page subroutine register(s)
- UINT8 m_a; // 4-bit accumulator
- UINT8 m_x; // 2,3,or 4-bit RAM X register
- UINT8 m_y; // 4-bit RAM Y register
- UINT8 m_ca; // chapter address register
- UINT8 m_cb; // chapter buffer register
- UINT16 m_cs; // chapter subroutine register(s)
- UINT16 m_r;
- UINT16 m_o;
- UINT8 m_cki_bus;
- UINT8 m_c4;
- UINT8 m_p; // 4-bit adder p(lus)-input
- UINT8 m_n; // 4-bit adder n(egative)-input
- UINT8 m_adder_out; // adder result
- UINT8 m_carry_in; // adder carry-in bit
- UINT8 m_carry_out; // adder carry-out bit
- UINT8 m_status;
- UINT8 m_status_latch;
- UINT8 m_eac; // end around carry bit
- UINT8 m_clatch; // call latch bit(s)
- UINT8 m_add; // add latch bit
- UINT8 m_bl; // branch latch bit
-
- UINT8 m_ram_in;
- UINT8 m_dam_in;
- int m_ram_out; // signed!
- UINT8 m_ram_address;
- UINT16 m_rom_address;
- UINT16 m_opcode;
- UINT32 m_fixed;
- UINT32 m_micro;
- int m_subcycle;
- int m_icount;
-
- UINT8 m_o_pins; // how many O pins
- UINT8 m_r_pins; // how many R pins
- UINT8 m_pc_bits; // how many program counter bits
- UINT8 m_byte_bits; // how many bits per 'byte'
- UINT8 m_x_bits; // how many X register bits
-
- address_space *m_program;
- address_space *m_data;
-
- const UINT16 *m_output_pla_table;
- devcb_read8 m_read_k;
- devcb_write16 m_write_o;
- devcb_write16 m_write_r;
- devcb_write_line m_power_off;
-
- UINT32 m_o_mask;
- UINT32 m_r_mask;
- UINT32 m_k_mask;
- UINT32 m_pc_mask;
- UINT32 m_x_mask;
-
- // lookup tables
- std::vector<UINT32> m_fixed_decode;
- std::vector<UINT32> m_micro_decode;
- std::vector<UINT32> m_micro_direct;
-};
-
-
-
-class tms1000_cpu_device : public tms1xxx_cpu_device
-{
-public:
- tms1000_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
- tms1000_cpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT8 o_pins, UINT8 r_pins, UINT8 pc_bits, UINT8 byte_bits, UINT8 x_bits, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data, const char *shortname, const char *source);
-
-protected:
- // overrides
- virtual void device_reset() override;
- virtual machine_config_constructor device_mconfig_additions() const override;
-
-
- virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options) override;
-};
-
-class tms1070_cpu_device : public tms1000_cpu_device
-{
-public:
- tms1070_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
-};
-
-class tms1040_cpu_device : public tms1000_cpu_device
-{
-public:
- tms1040_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
-};
-
-
-class tms1200_cpu_device : public tms1000_cpu_device
-{
-public:
- tms1200_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
-};
-
-
-class tms1100_cpu_device : public tms1000_cpu_device
-{
-public:
- tms1100_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
- tms1100_cpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT8 o_pins, UINT8 r_pins, UINT8 pc_bits, UINT8 byte_bits, UINT8 x_bits, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data, const char *shortname, const char *source);
-
-protected:
- // overrides
- virtual void device_reset() override;
-
- virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options) override;
-
- virtual void op_setr() override;
- virtual void op_rstr() override;
-};
-
-class tms1170_cpu_device : public tms1100_cpu_device
-{
-public:
- tms1170_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
-};
-
-class tms1300_cpu_device : public tms1100_cpu_device
-{
-public:
- tms1300_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
-};
-
-class tms1370_cpu_device : public tms1100_cpu_device
-{
-public:
- tms1370_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
-};
-
-
-class tms1400_cpu_device : public tms1100_cpu_device
-{
-public:
- tms1400_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
- tms1400_cpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT8 o_pins, UINT8 r_pins, UINT8 pc_bits, UINT8 byte_bits, UINT8 x_bits, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data, const char *shortname, const char *source);
-
-protected:
- // overrides
- virtual void device_reset() override;
- virtual machine_config_constructor device_mconfig_additions() const override;
-
- virtual void op_br() override;
- virtual void op_call() override;
- virtual void op_retn() override;
-
- virtual void op_setr() override { tms1xxx_cpu_device::op_setr(); } // no anomaly with MSB of X register
- virtual void op_rstr() override { tms1xxx_cpu_device::op_rstr(); } // "
-};
-
-class tms1470_cpu_device : public tms1400_cpu_device
-{
-public:
- tms1470_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
-};
-
-
-class tms1600_cpu_device : public tms1400_cpu_device
-{
-public:
- tms1600_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
- tms1600_cpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT8 o_pins, UINT8 r_pins, UINT8 pc_bits, UINT8 byte_bits, UINT8 x_bits, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data, const char *shortname, const char *source);
-};
-
-class tms1670_cpu_device : public tms1600_cpu_device
-{
-public:
- tms1670_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
-};
-
-
-class tms0970_cpu_device : public tms1000_cpu_device
-{
-public:
- tms0970_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
- tms0970_cpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT8 o_pins, UINT8 r_pins, UINT8 pc_bits, UINT8 byte_bits, UINT8 x_bits, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data, const char *shortname, const char *source);
-
-protected:
- // overrides
- virtual void device_reset() override;
- virtual machine_config_constructor device_mconfig_additions() const override;
-
- virtual void write_o_output(UINT8 index) override;
-
- virtual void op_setr() override;
- virtual void op_tdo() override;
-};
-
-class tms0950_cpu_device : public tms0970_cpu_device
-{
-public:
- tms0950_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
-
-protected:
- // overrides
- virtual void device_reset() override { tms1000_cpu_device::device_reset(); }
- virtual machine_config_constructor device_mconfig_additions() const override;
-
- virtual void op_rstr() override { ; } // assume it has no RSTR or CLO
- virtual void op_clo() override { ; } // "
-};
-
-class tms1990_cpu_device : public tms0970_cpu_device
-{
-public:
- tms1990_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
-};
-
-
-class tms0980_cpu_device : public tms0970_cpu_device
-{
-public:
- tms0980_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
- tms0980_cpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT8 o_pins, UINT8 r_pins, UINT8 pc_bits, UINT8 byte_bits, UINT8 x_bits, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data, const char *shortname, const char *source);
-
-protected:
- // overrides
- virtual void device_reset() override;
-
- virtual machine_config_constructor device_mconfig_additions() const override;
-
- virtual UINT32 disasm_min_opcode_bytes() const override { return 2; }
- virtual UINT32 disasm_max_opcode_bytes() const override { return 2; }
- virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options) override;
-
- virtual UINT8 read_k_input() override;
- virtual void set_cki_bus() override;
- virtual void read_opcode() override;
-
- virtual void op_comx() override;
-
- UINT32 decode_micro(UINT8 sel);
-};
-
-class tms1980_cpu_device : public tms0980_cpu_device
-{
-public:
- tms1980_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
-
-protected:
- // overrides
- virtual machine_config_constructor device_mconfig_additions() const override;
-
- virtual void write_o_output(UINT8 index) override { tms1xxx_cpu_device::write_o_output(index); }
- virtual UINT8 read_k_input() override { return tms1xxx_cpu_device::read_k_input(); }
-
- virtual void op_setr() override { tms1xxx_cpu_device::op_setr(); }
- virtual void op_tdo() override;
-};
-
-
-class tms0270_cpu_device : public tms0980_cpu_device
-{
-public:
- tms0270_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
-
- // static configuration helpers
- template<class _Object> static devcb_base &set_read_ctl_callback(device_t &device, _Object object) { return downcast<tms0270_cpu_device &>(device).m_read_ctl.set_callback(object); }
- template<class _Object> static devcb_base &set_write_ctl_callback(device_t &device, _Object object) { return downcast<tms0270_cpu_device &>(device).m_write_ctl.set_callback(object); }
- template<class _Object> static devcb_base &set_write_pdc_callback(device_t &device, _Object object) { return downcast<tms0270_cpu_device &>(device).m_write_pdc.set_callback(object); }
-
-protected:
- // overrides
- virtual void device_start() override;
- virtual void device_reset() override;
-
- virtual machine_config_constructor device_mconfig_additions() const override;
-
- virtual void write_o_output(UINT8 index) override { tms1xxx_cpu_device::write_o_output(index); }
- virtual UINT8 read_k_input() override;
- virtual void dynamic_output() override;
-
- virtual void op_setr() override;
- virtual void op_rstr() override;
- virtual void op_tdo() override;
-
-private:
- // state specific to interface with TMS5100
- UINT16 m_r_prev;
- UINT8 m_chipsel;
- UINT8 m_ctl_out;
- UINT8 m_ctl_dir;
- int m_pdc;
-
- UINT8 m_o_latch_low;
- UINT8 m_o_latch;
- UINT8 m_o_latch_prev;
-
- devcb_read8 m_read_ctl;
- devcb_write8 m_write_ctl;
- devcb_write_line m_write_pdc;
-};
-
-
-class tp0320_cpu_device : public tms0980_cpu_device
-{
-public:
- tp0320_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
-
-protected:
- // overrides
- //virtual void device_start() override;
- //virtual void device_reset() override;
-
- //virtual machine_config_constructor device_mconfig_additions() const override;
-};
-
-
-extern const device_type TMS1000;
-extern const device_type TMS1070;
-extern const device_type TMS1040;
-extern const device_type TMS1200;
-extern const device_type TMS1100;
-extern const device_type TMS1170;
-extern const device_type TMS1300;
-extern const device_type TMS1370;
-extern const device_type TMS1400;
-extern const device_type TMS1470;
-extern const device_type TMS1600;
-extern const device_type TMS1670;
-extern const device_type TMS0950;
-extern const device_type TMS0970;
-extern const device_type TMS1990;
-extern const device_type TMS0980;
-extern const device_type TMS1980;
-extern const device_type TMS0270;
-extern const device_type TP0320;
-
-
-#endif /* _TMS0980_H_ */
diff --git a/src/devices/cpu/tms0980/tms0980d.cpp b/src/devices/cpu/tms0980/tms0980d.cpp
deleted file mode 100644
index 371047b0a79..00000000000
--- a/src/devices/cpu/tms0980/tms0980d.cpp
+++ /dev/null
@@ -1,363 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Wilbert Pol, hap
-/*
-
- TMS0980/TMS1000-family disassembler
-
-*/
-
-#include "emu.h"
-#include "debugger.h"
-#include "tms0980.h"
-
-
-enum e_mnemonics
-{
- zA10AAC=0, zA6AAC, zA8AAC, zAC1AC, zACACC, zACNAA, zALEC, zALEM, zAMAAC, zBRANCH, zCALL, zCCLA,
- zCLA, zCLO, zCOMC, zCOMX, zCOMX8, zCPAIZ, zCTMDYN, zDAN, zDMAN, zDMEA, zDNAA,
- zDYN, zIA, zIMAC, zIYC, zKNEZ, zLDP, zLDX, zLDX3, zLDX4, zMNEA, zMNEZ,
- zNDMEA, zOFF, zRBIT, zREAC, zRETN, zRSTR, zSAL, zSAMAN, zSBIT,
- zSBL, zSEAC, zSETR, zTAM, zTAMACS, zTAMDYN, zTAMIY, zTAMIYC, zTAMZA,
- zTAY, zTBIT, zTCMIY, zTCY, zTDO, zTKA, zTKM, zTMA,
- zTMY, zTYA, zXDA, zXMA, zYMCY, zYNEA, zYNEC,
- zILL
-};
-
-static const char *const s_mnemonic[] =
-{
- "A10AAC", "A6AAC", "A8AAC", "AC1AC", "ACACC", "ACNAA", "ALEC", "ALEM", "AMAAC", "BRANCH", "CALL", "CCLA",
- "CLA", "CLO", "COMC", "COMX", "COMX8", "CPAIZ", "CTMDYN", "DAN", "DMAN", "DMEA", "DNAA",
- "DYN", "IA", "IMAC", "IYC", "KNEZ", "LDP", "LDX", "LDX", "LDX", "MNEA", "MNEZ",
- "NDMEA", "OFF", "RBIT", "REAC", "RETN", "RSTR", "SAL", "SAMAN", "SBIT",
- "SBL", "SEAC", "SETR", "TAM", "TAMACS", "TAMDYN", "TAMIY", "TAMIYC", "TAMZA",
- "TAY", "TBIT", "TCMIY", "TCY", "TDO", "TKA", "TKM", "TMA",
- "TMY", "TYA", "XDA", "XMA", "YMCY", "YNEA", "YNEC",
- "?"
-};
-
-
-#define _OVER DASMFLAG_STEP_OVER
-#define _OUT DASMFLAG_STEP_OUT
-
-static const UINT32 s_flags[] =
-{
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _OVER, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, _OUT, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0,
- 0
-};
-
-
-enum e_addressing
-{
- zB0=0, zI2, zI3, zI4, zB7
-};
-
-static const UINT8 s_addressing[] =
-{
- zB0, zB0, zB0, zI4, zI4, zI4, zI4, zB0, zB0, zB7, zB7, zB0,
- zB0, zB0, zB0, zB0, zB0, zB0, zB0, zB0, zB0, zB0, zB0,
- zB0, zB0, zB0, zB0, zB0, zI4, zI2, zI3, zI4, zB0, zB0,
- zB0, zB0, zI2, zB0, zB0, zB0, zB0, zB0, zI2,
- zB0, zB0, zB0, zB0, zI4, zB0, zB0, zB0, zB0,
- zB0, zI2, zI4, zI4, zB0, zB0, zB0, zB0,
- zB0, zB0, zB0, zB0, zI4, zB0, zI4,
- zB0
-};
-
-
-static const UINT8 tms0980_i2_value[4] =
-{
- 0, 2, 1, 3
-};
-static const UINT8 tms0980_i3_value[8] =
-{
- 0, 4, 2, 6, 1, 5, 3, 7
-};
-static const UINT8 tms0980_i4_value[16] =
-{
- 0x0, 0x8, 0x4, 0xc, 0x2, 0xa, 0x6, 0xe, 0x1, 0x9, 0x5, 0xd, 0x3, 0xb, 0x7, 0xf
-};
-
-
-
-// opcode luts
-
-static const UINT8 tms0980_mnemonic[512] =
-{
- /* 0x000 */
- zCOMX, zALEM, zYNEA, zXMA, zDYN, zIYC, zCLA, zDMAN,
- zTKA, zMNEA, zTKM, zILL, zILL, zSETR, zKNEZ, zILL,
- /* 0x010 */
- zDMEA, zDNAA, zCCLA, zNDMEA, zILL, zAMAAC, zILL, zILL,
- zCTMDYN, zXDA, zILL, zILL, zILL, zILL, zILL, zILL,
- /* 0x020 */
- zTBIT, zTBIT, zTBIT, zTBIT, zILL, zILL, zILL, zILL,
- zTAY, zTMA, zTMY, zTYA, zTAMDYN, zTAMIYC, zTAMZA, zTAM,
- /* 0x030 */
- zSAMAN, zCPAIZ, zIMAC, zMNEZ, zILL, zILL, zILL, zILL,
- zTCY, zYNEC, zTCMIY, zACACC, zACNAA, zTAMACS, zALEC, zYMCY,
- /* 0x040 */
- zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, zTCY,
- zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, zTCY,
- /* 0x050 */
- zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC,
- zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC,
- /* 0x060 */
- zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY,
- zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY,
- /* 0x070 */
- zACACC, zACACC, zACACC, zACACC, zACACC, zACACC, zACACC, zACACC,
- zACACC, zACACC, zACACC, zACACC, zACACC, zACACC, zACACC, zACACC,
- /* 0x080 */
- zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, zLDP,
- zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, zLDP,
- /* 0x090 */
- zLDX4, zLDX4, zLDX4, zLDX4, zLDX4, zLDX4, zLDX4, zLDX4,
- zLDX4, zLDX4, zLDX4, zLDX4, zLDX4, zLDX4, zLDX4, zLDX4,
- /* 0x0A0 */
- zSBIT, zSBIT, zSBIT, zSBIT, zRBIT, zRBIT, zRBIT, zRBIT,
- zILL, zILL, zILL, zILL, zILL, zILL, zILL, zILL,
- /* 0x0B0 */
- zTDO, zSAL, zCOMX8, zSBL, zREAC, zSEAC, zOFF, zILL,
- zILL, zILL, zILL, zILL, zILL, zILL, zILL, zRETN,
- /* 0x0C0 */
- zACNAA, zACNAA, zACNAA, zACNAA, zACNAA, zACNAA, zACNAA, zACNAA,
- zACNAA, zACNAA, zACNAA, zACNAA, zACNAA, zACNAA, zACNAA, zACNAA,
- /* 0x0D0 */
- zTAMACS, zTAMACS, zTAMACS, zTAMACS, zTAMACS, zTAMACS, zTAMACS, zTAMACS,
- zTAMACS, zTAMACS, zTAMACS, zTAMACS, zTAMACS, zTAMACS, zTAMACS, zTAMACS,
- /* 0x0E0 */
- zALEC, zALEC, zALEC, zALEC, zALEC, zALEC, zALEC, zALEC,
- zALEC, zALEC, zALEC, zALEC, zALEC, zALEC, zALEC, zALEC,
- /* 0x0F0 */
- zYMCY, zYMCY, zYMCY, zYMCY, zYMCY, zYMCY, zYMCY, zYMCY,
- zYMCY, zYMCY, zYMCY, zYMCY, zYMCY, zYMCY, zYMCY, zYMCY,
- /* 0x100 */
- zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH,
- zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH,
- zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH,
- zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH,
- zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH,
- zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH,
- zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH,
- zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH,
- zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH,
- zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH,
- zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH,
- zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH,
- zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH,
- zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH,
- zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH,
- zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH,
- /* 0x180 */
- zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL,
- zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL,
- zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL,
- zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL,
- zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL,
- zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL,
- zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL,
- zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL,
- zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL,
- zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL,
- zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL,
- zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL,
- zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL,
- zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL,
- zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL,
- zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL
-};
-
-
-static const UINT8 tms1000_mnemonic[256] =
-{
- /* 0x00 */
- zCOMX, zA8AAC, zYNEA, zTAM, zTAMZA, zA10AAC, zA6AAC, zDAN,
- zTKA, zKNEZ, zTDO, zCLO, zRSTR, zSETR, zIA, zRETN,
- zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, zLDP,
- zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, zLDP,
- zTAMIY, zTMA, zTMY, zTYA, zTAY, zAMAAC, zMNEZ, zSAMAN,
- zIMAC, zALEM, zDMAN, zIYC, zDYN, zCPAIZ, zXMA, zCLA,
- zSBIT, zSBIT, zSBIT, zSBIT, zRBIT, zRBIT, zRBIT, zRBIT,
- zTBIT, zTBIT, zTBIT, zTBIT, zLDX, zLDX, zLDX, zLDX,
- /* 0x40 */
- zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, zTCY,
- zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, zTCY,
- zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC,
- zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC,
- zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY,
- zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY,
- zALEC, zALEC, zALEC, zALEC, zALEC, zALEC, zALEC, zALEC,
- zALEC, zALEC, zALEC, zALEC, zALEC, zALEC, zALEC, zALEC,
- /* 0x80 */
- zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH,
- zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH,
- zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH,
- zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH,
- zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH,
- zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH,
- zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH,
- zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH,
- /* 0xc0 */
- zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL,
- zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL,
- zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL,
- zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL,
- zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL,
- zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL,
- zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL,
- zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL
-};
-
-
-static const UINT8 tms1100_mnemonic[256] =
-{
- /* 0x00 */
- zMNEA, zALEM, zYNEA, zXMA, zDYN, zIYC, zAMAAC, zDMAN,
- zTKA, zCOMX, zTDO, zCOMC, zRSTR, zSETR, zKNEZ, zRETN,
- zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, zLDP,
- zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, zLDP,
- /* 0x20 */
- zTAY, zTMA, zTMY, zTYA, zTAMDYN, zTAMIYC, zTAMZA, zTAM,
- zLDX3, zLDX3, zLDX3, zLDX3, zLDX3, zLDX3, zLDX3, zLDX3,
- zSBIT, zSBIT, zSBIT, zSBIT, zRBIT, zRBIT, zRBIT, zRBIT,
- zTBIT, zTBIT, zTBIT, zTBIT, zSAMAN, zCPAIZ, zIMAC, zMNEZ,
- /* 0x40 */
- zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, zTCY,
- zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, zTCY,
- zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC,
- zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC,
- /* 0x60 */
- zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY,
- zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY,
- zAC1AC, zAC1AC, zAC1AC, zAC1AC, zAC1AC, zAC1AC, zAC1AC, zAC1AC,
- zAC1AC, zAC1AC, zAC1AC, zAC1AC, zAC1AC, zAC1AC, zAC1AC, zCLA,
- /* 0x80 */
- zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH,
- zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH,
- zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH,
- zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH,
- zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH,
- zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH,
- zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH,
- zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH,
- /* 0xC0 */
- zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL,
- zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL,
- zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL,
- zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL,
- zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL,
- zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL,
- zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL,
- zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL,
-};
-
-
-
-// disasm
-
-CPU_DISASSEMBLE( tms0980 )
-{
- char *dst = buffer;
- UINT16 op, instr;
- int pos = 0;
-
- op = ( ( oprom[pos] << 8 ) | oprom[pos + 1] ) & 0x01FF;
- pos += 2;
-
- instr = tms0980_mnemonic[op];
-
- dst += sprintf( dst, "%-8s ", s_mnemonic[instr] );
-
- switch( s_addressing[instr] )
- {
- default:
- case zB0:
- break;
- case zI2:
- dst += sprintf( dst, "%d", tms0980_i2_value[ op & 0x03 ] );
- break;
- case zI4:
- dst += sprintf( dst, "%d", tms0980_i4_value[ op & 0x0F ] );
- break;
- case zB7:
- dst += sprintf( dst, "$%02X", ( op & 0x7F ) << 1 );
- break;
- }
-
- return pos | s_flags[instr] | DASMFLAG_SUPPORTED;
-}
-
-
-CPU_DISASSEMBLE( tms1000 )
-{
- char *dst = buffer;
- UINT8 op, instr;
- int pos = 0;
-
- op = oprom[pos];
- pos += 1;
-
- instr = tms1000_mnemonic[op];
-
- dst += sprintf( dst, "%-8s ", s_mnemonic[instr] );
-
- switch( s_addressing[instr] )
- {
- default:
- case zB0:
- break;
- case zI2:
- dst += sprintf( dst, "%d", tms0980_i2_value[ op & 0x03 ] );
- break;
- case zI4:
- dst += sprintf( dst, "%d", tms0980_i4_value[ op & 0x0F ] );
- break;
- case zB7:
- dst += sprintf( dst, "$%02X", ( op & 0x3F ) );
- break;
- }
-
- return pos | s_flags[instr] | DASMFLAG_SUPPORTED;
-}
-
-
-CPU_DISASSEMBLE( tms1100 )
-{
- char *dst = buffer;
- UINT8 op, instr;
- int pos = 0;
-
- op = oprom[pos];
- pos += 1;
-
- instr = tms1100_mnemonic[op];
-
- dst += sprintf( dst, "%-8s ", s_mnemonic[instr] );
-
- switch( s_addressing[instr] )
- {
- default:
- case zB0:
- break;
- case zI2:
- dst += sprintf( dst, "%d", tms0980_i2_value[ op & 0x03 ] );
- break;
- case zI3:
- dst += sprintf( dst, "%d", tms0980_i3_value[ op & 0x07 ] );
- break;
- case zI4:
- dst += sprintf( dst, "%d", tms0980_i4_value[ op & 0x0F ] );
- break;
- case zB7:
- dst += sprintf( dst, "$%02X", ( op & 0x3F ) );
- break;
- }
-
- return pos | s_flags[instr] | DASMFLAG_SUPPORTED;
-}
diff --git a/src/devices/cpu/tms1000/tms0270.cpp b/src/devices/cpu/tms1000/tms0270.cpp
new file mode 100644
index 00000000000..b38ce2c13b7
--- /dev/null
+++ b/src/devices/cpu/tms1000/tms0270.cpp
@@ -0,0 +1,182 @@
+// license:BSD-3-Clause
+// copyright-holders:hap
+/*
+
+ TMS1000 family - TMS0270
+
+*/
+
+#include "tms0270.h"
+#include "debugger.h"
+
+// TMS0270 is a TMS0980 with earrings and a new hat. The new changes look like a quick afterthought, almost hacky
+// - RAM, ROM, and main instructions PLAs is the same as TMS0980
+// - 64-term microinstructions PLA between the RAM and ROM, similar to TMS0980,
+// plus optional separate lines for custom opcode handling
+// - 48-term output PLA above the RAM (rotate opla 90 degrees)
+const device_type TMS0270 = &device_creator<tms0270_cpu_device>; // 40-pin DIP, 16 O pins, 8+ R pins (some R pins are internally hooked up to support more I/O)
+// newer TMS0270 chips (eg. Speak & Math) have 42 pins
+
+// TMS0260 is same or similar?
+
+
+// internal memory maps
+static ADDRESS_MAP_START(program_11bit_9, AS_PROGRAM, 16, tms1k_base_device)
+ AM_RANGE(0x000, 0xfff) AM_ROM
+ADDRESS_MAP_END
+
+static ADDRESS_MAP_START(data_144x4, AS_DATA, 8, tms1k_base_device)
+ AM_RANGE(0x00, 0x7f) AM_RAM
+ AM_RANGE(0x80, 0x8f) AM_RAM AM_MIRROR(0x70) // DAM
+ADDRESS_MAP_END
+
+
+// device definitions
+tms0270_cpu_device::tms0270_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : tms0980_cpu_device(mconfig, TMS0270, "TMS0270", tag, owner, clock, 16 /* o pins */, 16 /* r pins */, 7 /* pc bits */, 9 /* byte width */, 4 /* x width */, 12 /* prg width */, ADDRESS_MAP_NAME(program_11bit_9), 8 /* data width */, ADDRESS_MAP_NAME(data_144x4), "tms0270", __FILE__)
+ , m_read_ctl(*this)
+ , m_write_ctl(*this)
+ , m_write_pdc(*this)
+{ }
+
+
+// machine configs
+static MACHINE_CONFIG_FRAGMENT(tms0270)
+
+ // main opcodes PLA, microinstructions PLA, output PLA
+ MCFG_PLA_ADD("ipla", 9, 22, 24)
+ MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
+ MCFG_PLA_ADD("mpla", 6, 22, 64)
+ MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
+ MCFG_PLA_ADD("opla", 6, 16, 48)
+ MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
+MACHINE_CONFIG_END
+
+machine_config_constructor tms0270_cpu_device::device_mconfig_additions() const
+{
+ return MACHINE_CONFIG_NAME(tms0270);
+}
+
+
+// device_start/reset
+void tms0270_cpu_device::device_start()
+{
+ // common init
+ tms1k_base_device::device_start();
+
+ m_read_ctl.resolve_safe(0);
+ m_write_ctl.resolve_safe();
+ m_write_pdc.resolve_safe();
+
+ // zerofill
+ m_r_prev = 0;
+ m_chipsel = 0;
+ m_ctl_dir = 0;
+ m_ctl_out = 0;
+ m_pdc = -1; // !
+
+ m_o_latch_low = 0;
+ m_o_latch = 0;
+ m_o_latch_prev = 0;
+
+ // register for savestates
+ save_item(NAME(m_r_prev));
+ save_item(NAME(m_chipsel));
+ save_item(NAME(m_ctl_dir));
+ save_item(NAME(m_ctl_out));
+ save_item(NAME(m_pdc));
+
+ save_item(NAME(m_o_latch_low));
+ save_item(NAME(m_o_latch));
+ save_item(NAME(m_o_latch_prev));
+}
+
+void tms0270_cpu_device::device_reset()
+{
+ // common reset
+ tms0980_cpu_device::device_reset();
+
+ m_o_latch_low = 0;
+ m_o_latch = 0;
+ m_o_latch_prev = 0;
+}
+
+
+// i/o handling
+void tms0270_cpu_device::dynamic_output()
+{
+ // R11: TMS5100 CTL port direction (0=read from TMS5100, 1=write to TMS5100)
+ m_ctl_dir = m_r >> 11 & 1;
+
+ // R12: chip select (off=display via OPLA, on=TMS5100 via ACC/CKB)
+ m_chipsel = m_r >> 12 & 1;
+
+ if (m_chipsel)
+ {
+ // ACC via SEG G,B,C,D: TMS5100 CTL pins
+ if (m_ctl_dir && m_a != m_ctl_out)
+ {
+ m_ctl_out = m_a;
+ m_write_ctl(0, m_ctl_out, 0xff);
+ }
+
+ // R10 via SEG E: TMS5100 PDC pin
+ if (m_pdc != (m_r >> 10 & 1))
+ {
+ m_pdc = m_r >> 10 & 1;
+ m_write_pdc(m_pdc);
+ }
+ }
+ else
+ {
+ // standard O-output
+ if (m_o_latch != m_o_latch_prev)
+ {
+ write_o_output(m_o_latch);
+ m_o_latch_prev = m_o_latch;
+ }
+ }
+
+ // standard R-output
+ if (m_r != m_r_prev)
+ {
+ m_write_r(0, m_r & m_r_mask, 0xffff);
+ m_r_prev = m_r;
+ }
+}
+
+UINT8 tms0270_cpu_device::read_k_input()
+{
+ // external: TMS5100 CTL port via SEG G,B,C,D
+ if (m_chipsel)
+ return (m_ctl_dir) ? m_ctl_out : m_read_ctl(0, 0xff) & 0xf;
+
+ // standard K-input otherwise
+ UINT8 k = m_read_k(0, 0xff) & 0x1f;
+ return (k & 0x10) ? 0xf : k; // the TMS0270 KF line asserts all K-inputs
+}
+
+
+// opcode deviations
+void tms0270_cpu_device::op_setr()
+{
+ // same as default, but handle write to output in dynamic_output
+ m_r = m_r | (1 << m_y);
+}
+
+void tms0270_cpu_device::op_rstr()
+{
+ // same as default, but handle write to output in dynamic_output
+ m_r = m_r & ~(1 << m_y);
+}
+
+void tms0270_cpu_device::op_tdo()
+{
+ // TDO: transfer data out
+ if (m_status)
+ m_o_latch_low = m_a;
+ else
+ m_o_latch = m_o_latch_low | (m_a << 4 & 0x30);
+
+ // write to output is done in dynamic_output
+}
diff --git a/src/devices/cpu/tms1000/tms0270.h b/src/devices/cpu/tms1000/tms0270.h
new file mode 100644
index 00000000000..5cac8c810ad
--- /dev/null
+++ b/src/devices/cpu/tms1000/tms0270.h
@@ -0,0 +1,71 @@
+// license:BSD-3-Clause
+// copyright-holders:hap
+/*
+
+ TMS1000 family - TMS0270
+
+*/
+
+#ifndef _TMS0270_H_
+#define _TMS0270_H_
+
+#include "tms0980.h"
+
+
+// TMS0270 was designed to interface with TMS5100, set it up at driver level
+#define MCFG_TMS0270_READ_CTL_CB(_devcb) \
+ tms0270_cpu_device::set_read_ctl_callback(*device, DEVCB_##_devcb);
+
+#define MCFG_TMS0270_WRITE_CTL_CB(_devcb) \
+ tms0270_cpu_device::set_write_ctl_callback(*device, DEVCB_##_devcb);
+
+#define MCFG_TMS0270_WRITE_PDC_CB(_devcb) \
+ tms0270_cpu_device::set_write_pdc_callback(*device, DEVCB_##_devcb);
+
+
+class tms0270_cpu_device : public tms0980_cpu_device
+{
+public:
+ tms0270_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // static configuration helpers
+ template<class _Object> static devcb_base &set_read_ctl_callback(device_t &device, _Object object) { return downcast<tms0270_cpu_device &>(device).m_read_ctl.set_callback(object); }
+ template<class _Object> static devcb_base &set_write_ctl_callback(device_t &device, _Object object) { return downcast<tms0270_cpu_device &>(device).m_write_ctl.set_callback(object); }
+ template<class _Object> static devcb_base &set_write_pdc_callback(device_t &device, _Object object) { return downcast<tms0270_cpu_device &>(device).m_write_pdc.set_callback(object); }
+
+protected:
+ // overrides
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+ virtual machine_config_constructor device_mconfig_additions() const override;
+
+ virtual void write_o_output(UINT8 index) override { tms1k_base_device::write_o_output(index); }
+ virtual UINT8 read_k_input() override;
+ virtual void dynamic_output() override;
+
+ virtual void op_setr() override;
+ virtual void op_rstr() override;
+ virtual void op_tdo() override;
+
+private:
+ // state specific to interface with TMS5100
+ UINT16 m_r_prev;
+ UINT8 m_chipsel;
+ UINT8 m_ctl_out;
+ UINT8 m_ctl_dir;
+ int m_pdc;
+
+ UINT8 m_o_latch_low;
+ UINT8 m_o_latch;
+ UINT8 m_o_latch_prev;
+
+ devcb_read8 m_read_ctl;
+ devcb_write8 m_write_ctl;
+ devcb_write_line m_write_pdc;
+};
+
+
+extern const device_type TMS0270;
+
+#endif /* _TMS0270_H_ */
diff --git a/src/devices/cpu/tms1000/tms0970.cpp b/src/devices/cpu/tms1000/tms0970.cpp
new file mode 100644
index 00000000000..88b9a52be39
--- /dev/null
+++ b/src/devices/cpu/tms1000/tms0970.cpp
@@ -0,0 +1,161 @@
+// license:BSD-3-Clause
+// copyright-holders:hap
+/*
+
+ TMS1000 family - TMS0950, TMS0970, TMS1990
+
+*/
+
+#include "tms0970.h"
+#include "debugger.h"
+
+// TMS0950 is a TMS1000 with a TMS0980 style opla, it was quickly succeeded by the TMS0970
+// - RAM, ROM, microinstructions is the same as TMS1000
+// - 10-term inverted output PLA and segment PLA on the top-left
+const device_type TMS0950 = &device_creator<tms0950_cpu_device>; // 28-pin DIP, 8 O pins, 11? R pins
+
+// TMS0970 is a stripped-down version of the TMS0980, itself acting more like a TMS1000
+// - RAM and ROM is the same as TMS1000
+// - main instructions PLAs at the top half, to the right of the midline
+// * see TMS0980 notes, except that the fixed instruction list differs:
+// RETN, SETR, RBIT, SBIT, LDX, COMX, TDO, ..., redir(----0-00), LDP
+// - 32-term microinstructions PLA between the RAM and ROM, supporting 15 microinstructions
+// - 16-term inverted output PLA and segment PLA above the RAM (rotate opla 90 degrees)
+const device_type TMS0970 = &device_creator<tms0970_cpu_device>; // 28-pin DIP, 11 R pins (note: pinout may slightly differ from chip to chip)
+const device_type TMS1990 = &device_creator<tms1990_cpu_device>; // 28-pin DIP, ? R pins..
+
+
+// internal memory maps
+static ADDRESS_MAP_START(program_10bit_8, AS_PROGRAM, 8, tms1k_base_device)
+ AM_RANGE(0x000, 0x3ff) AM_ROM
+ADDRESS_MAP_END
+
+static ADDRESS_MAP_START(data_64x4, AS_DATA, 8, tms1k_base_device)
+ AM_RANGE(0x00, 0x3f) AM_RAM
+ADDRESS_MAP_END
+
+
+// device definitions
+tms0970_cpu_device::tms0970_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : tms1000_cpu_device(mconfig, TMS0970, "TMS0970", tag, owner, clock, 8 /* o pins */, 11 /* r pins */, 6 /* pc bits */, 8 /* byte width */, 2 /* x width */, 10 /* prg width */, ADDRESS_MAP_NAME(program_10bit_8), 6 /* data width */, ADDRESS_MAP_NAME(data_64x4), "tms0970", __FILE__)
+{ }
+
+tms0970_cpu_device::tms0970_cpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT8 o_pins, UINT8 r_pins, UINT8 pc_bits, UINT8 byte_bits, UINT8 x_bits, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data, const char *shortname, const char *source)
+ : tms1000_cpu_device(mconfig, type, name, tag, owner, clock, o_pins, r_pins, pc_bits, byte_bits, x_bits, prgwidth, program, datawidth, data, shortname, source)
+{ }
+
+tms0950_cpu_device::tms0950_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : tms0970_cpu_device(mconfig, TMS0950, "TMS0950", tag, owner, clock, 8, 11, 6, 8, 2, 10, ADDRESS_MAP_NAME(program_10bit_8), 6, ADDRESS_MAP_NAME(data_64x4), "tms0950", __FILE__)
+{ }
+
+tms1990_cpu_device::tms1990_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : tms0970_cpu_device(mconfig, TMS1990, "TMS1990", tag, owner, clock, 8, 11, 6, 8, 2, 10, ADDRESS_MAP_NAME(program_10bit_8), 6, ADDRESS_MAP_NAME(data_64x4), "tms1990", __FILE__)
+{ }
+
+
+// machine configs
+static MACHINE_CONFIG_FRAGMENT(tms0950)
+
+ // microinstructions PLA, output PLA, segment PLA
+ MCFG_PLA_ADD("mpla", 8, 16, 30)
+ MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
+ MCFG_PLA_ADD("opla", 4, 8, 10)
+ MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
+ MCFG_PLA_ADD("spla", 3, 8, 8)
+ MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
+MACHINE_CONFIG_END
+
+machine_config_constructor tms0950_cpu_device::device_mconfig_additions() const
+{
+ return MACHINE_CONFIG_NAME(tms0950);
+}
+
+static MACHINE_CONFIG_FRAGMENT(tms0970)
+
+ // main opcodes PLA, microinstructions PLA, output PLA, segment PLA
+ MCFG_PLA_ADD("ipla", 8, 15, 18)
+ MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
+ MCFG_PLA_ADD("mpla", 5, 15, 32)
+ MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
+ MCFG_PLA_ADD("opla", 4, 8, 16)
+ MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
+ MCFG_PLA_ADD("spla", 3, 8, 8)
+ MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
+MACHINE_CONFIG_END
+
+machine_config_constructor tms0970_cpu_device::device_mconfig_additions() const
+{
+ return MACHINE_CONFIG_NAME(tms0970);
+}
+
+
+// device_reset
+void tms0970_cpu_device::device_reset()
+{
+ // common reset
+ tms1k_base_device::device_reset();
+
+ // pre-decode instructionset
+ m_fixed_decode.resize(0x100);
+ memset(&m_fixed_decode[0], 0, 0x100*sizeof(UINT32));
+ m_micro_decode.resize(0x100);
+ memset(&m_micro_decode[0], 0, 0x100*sizeof(UINT32));
+
+ for (int op = 0; op < 0x100; op++)
+ {
+ // upper half of the opcodes is always branch/call
+ if (op & 0x80)
+ m_fixed_decode[op] = (op & 0x40) ? F_CALL: F_BR;
+
+ // 5 output bits select a microinstruction index
+ UINT32 imask = m_ipla->read(op);
+ UINT8 msel = imask & 0x1f;
+
+ // but if (from bottom to top) term 1 is active and output bit 5 is 0, R2,R4-R7 directly select a microinstruction index
+ if (imask & 0x40 && (imask & 0x20) == 0)
+ msel = (op & 0xf) | (op >> 1 & 0x10);
+
+ msel = BITSWAP8(msel,7,6,5,0,1,2,3,4); // lines are reversed
+ UINT32 mmask = m_mpla->read(msel);
+ mmask ^= 0x09fe; // invert active-negative
+
+ // _____ _____ _____ _____ ______ _____ ______ _____ _____
+ const UINT32 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++)
+ if (mmask & (1 << bit))
+ m_micro_decode[op] |= md[bit];
+
+ // the other ipla terms each select a fixed instruction
+ const UINT32 id[8] = { F_LDP, F_TDO, F_COMX, F_LDX, F_SBIT, F_RBIT, F_SETR, F_RETN };
+
+ for (int bit = 0; bit < 8; bit++)
+ if (imask & (0x80 << bit))
+ m_fixed_decode[op] |= id[bit];
+ }
+}
+
+
+// i/o handling
+void tms0970_cpu_device::write_o_output(UINT8 index)
+{
+ m_o = m_spla->read(index);
+ m_write_o(0, m_o & m_o_mask, 0xffff);
+}
+
+
+// opcode deviations
+void tms0970_cpu_device::op_setr()
+{
+ // SETR: set output register
+ // DDIG line is a coincidence between the selected output pla row(s) and segment pla row(s)
+ int ddig = (m_opla->read(m_a) & m_o) ? 1 : 0;
+ m_r = (m_r & ~(1 << m_y)) | (ddig << m_y);
+}
+
+void tms0970_cpu_device::op_tdo()
+{
+ // TDO: transfer digits to output
+ write_o_output(m_a & 0x7);
+ m_write_r(0, m_r & m_r_mask, 0xffff);
+}
diff --git a/src/devices/cpu/tms1000/tms0970.h b/src/devices/cpu/tms1000/tms0970.h
new file mode 100644
index 00000000000..62cfb57c4e2
--- /dev/null
+++ b/src/devices/cpu/tms1000/tms0970.h
@@ -0,0 +1,57 @@
+// license:BSD-3-Clause
+// copyright-holders:hap
+/*
+
+ TMS1000 family - TMS0950, TMS0970, TMS1990
+
+*/
+
+#ifndef _TMS0970_H_
+#define _TMS0970_H_
+
+#include "tms1000.h"
+
+
+class tms0970_cpu_device : public tms1000_cpu_device
+{
+public:
+ tms0970_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+ tms0970_cpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT8 o_pins, UINT8 r_pins, UINT8 pc_bits, UINT8 byte_bits, UINT8 x_bits, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data, const char *shortname, const char *source);
+
+protected:
+ // overrides
+ virtual void device_reset() override;
+ virtual machine_config_constructor device_mconfig_additions() const override;
+
+ virtual void write_o_output(UINT8 index) override;
+
+ virtual void op_setr() override;
+ virtual void op_tdo() override;
+};
+
+class tms0950_cpu_device : public tms0970_cpu_device
+{
+public:
+ tms0950_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+protected:
+ // overrides
+ virtual void device_reset() override { tms1000_cpu_device::device_reset(); }
+ virtual machine_config_constructor device_mconfig_additions() const override;
+
+ virtual void op_rstr() override { ; } // assume it has no RSTR or CLO
+ virtual void op_clo() override { ; } // "
+};
+
+class tms1990_cpu_device : public tms0970_cpu_device
+{
+public:
+ tms1990_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+};
+
+
+extern const device_type TMS0950;
+extern const device_type TMS0970;
+extern const device_type TMS1990;
+
+#endif /* _TMS0970_H_ */
diff --git a/src/devices/cpu/tms1000/tms0980.cpp b/src/devices/cpu/tms1000/tms0980.cpp
new file mode 100644
index 00000000000..3c1f3caf010
--- /dev/null
+++ b/src/devices/cpu/tms1000/tms0980.cpp
@@ -0,0 +1,243 @@
+// license:BSD-3-Clause
+// copyright-holders:hap
+/*
+
+ TMS1000 family - TMS0980, TMS1980
+
+*/
+
+#include "tms0980.h"
+#include "debugger.h"
+
+// TMS0980
+// - 144x4bit RAM array at the bottom-left (128+16, set up as 8x18x4)
+// - 2048x9bit ROM array at the bottom-left
+// - main instructions PLAs at the top half, to the right of the midline
+// * top section is assumed to be the CKI bus select
+// * middle section is for microinstruction redirection, this part may differ per die
+// * rest is fixed instructions select, from top-to-bottom: SEAC, LDX, COMX, COMX8,
+// TDO, SBIT, RETN, SETR, REAC, XDA, SAL, RBIT, ..., OFF, SBL, LDP, redir(------00- + R0^BL)
+// - 64-term microinstructions PLA between the RAM and ROM, supporting 20 microinstructions
+// - 16-term inverted output PLA and segment PLA above the RAM (rotate opla 90 degrees)
+const device_type TMS0980 = &device_creator<tms0980_cpu_device>; // 28-pin DIP, 9 R pins
+
+// TMS1980 is a TMS0980 with a TMS1x00 style opla
+// - RAM, ROM, and main instructions PLAs is the same as TMS0980
+// - one of the microinstructions redirects to a RSTR instruction, like on TMS0270
+// - 32-term inverted output PLA above the RAM, 7 bits! (rotate opla 270 degrees)
+const device_type TMS1980 = &device_creator<tms1980_cpu_device>; // 28-pin DIP, 7 O pins, 10 R pins, high voltage
+
+
+// internal memory maps
+static ADDRESS_MAP_START(program_11bit_9, AS_PROGRAM, 16, tms1k_base_device)
+ AM_RANGE(0x000, 0xfff) AM_ROM
+ADDRESS_MAP_END
+
+static ADDRESS_MAP_START(data_144x4, AS_DATA, 8, tms1k_base_device)
+ AM_RANGE(0x00, 0x7f) AM_RAM
+ AM_RANGE(0x80, 0x8f) AM_RAM AM_MIRROR(0x70) // DAM
+ADDRESS_MAP_END
+
+
+// device definitions
+tms0980_cpu_device::tms0980_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : tms0970_cpu_device(mconfig, TMS0980, "TMS0980", tag, owner, clock, 8 /* o pins */, 9 /* r pins */, 7 /* pc bits */, 9 /* byte width */, 4 /* x width */, 12 /* prg width */, ADDRESS_MAP_NAME(program_11bit_9), 8 /* data width */, ADDRESS_MAP_NAME(data_144x4), "tms0980", __FILE__)
+{ }
+
+tms0980_cpu_device::tms0980_cpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT8 o_pins, UINT8 r_pins, UINT8 pc_bits, UINT8 byte_bits, UINT8 x_bits, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data, const char *shortname, const char *source)
+ : tms0970_cpu_device(mconfig, type, name, tag, owner, clock, o_pins, r_pins, pc_bits, byte_bits, x_bits, prgwidth, program, datawidth, data, shortname, source)
+{ }
+
+tms1980_cpu_device::tms1980_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : tms0980_cpu_device(mconfig, TMS1980, "TMS1980", tag, owner, clock, 7, 10, 7, 9, 4, 12, ADDRESS_MAP_NAME(program_11bit_9), 8, ADDRESS_MAP_NAME(data_144x4), "tms1980", __FILE__)
+{ }
+
+
+// machine configs
+static MACHINE_CONFIG_FRAGMENT(tms0980)
+
+ // main opcodes PLA, microinstructions PLA, output PLA, segment PLA
+ MCFG_PLA_ADD("ipla", 9, 22, 24)
+ MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
+ MCFG_PLA_ADD("mpla", 6, 20, 64)
+ MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
+ MCFG_PLA_ADD("opla", 4, 8, 16)
+ MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
+ MCFG_PLA_ADD("spla", 3, 8, 8)
+ MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
+MACHINE_CONFIG_END
+
+machine_config_constructor tms0980_cpu_device::device_mconfig_additions() const
+{
+ return MACHINE_CONFIG_NAME(tms0980);
+}
+
+static MACHINE_CONFIG_FRAGMENT(tms1980)
+
+ // main opcodes PLA, microinstructions PLA, output PLA
+ MCFG_PLA_ADD("ipla", 9, 22, 24)
+ MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
+ MCFG_PLA_ADD("mpla", 6, 22, 64)
+ MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
+ MCFG_PLA_ADD("opla", 5, 7, 32)
+ MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
+MACHINE_CONFIG_END
+
+machine_config_constructor tms1980_cpu_device::device_mconfig_additions() const
+{
+ return MACHINE_CONFIG_NAME(tms1980);
+}
+
+
+// disasm
+offs_t tms0980_cpu_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options)
+{
+ extern CPU_DISASSEMBLE(tms0980);
+ return CPU_DISASSEMBLE_NAME(tms0980)(this, buffer, pc, oprom, opram, options);
+}
+
+
+// device_reset
+UINT32 tms0980_cpu_device::decode_fixed(UINT16 op)
+{
+ UINT32 decode = 0;
+ UINT32 mask = m_ipla->read(op);
+
+ // 1 line per PLA row, no OR-mask
+ const UINT32 id[15] = { F_LDP, F_SBL, F_OFF, F_RBIT, F_SAL, F_XDA, F_REAC, F_SETR, F_RETN, F_SBIT, F_TDO, F_COMX8, F_COMX, F_LDX, F_SEAC };
+
+ for (int bit = 0; bit < 15; bit++)
+ if (mask & (0x80 << bit))
+ decode |= id[bit];
+
+ return decode;
+}
+
+UINT32 tms0980_cpu_device::decode_micro(UINT8 sel)
+{
+ UINT32 decode = 0;
+ sel = BITSWAP8(sel,7,6,0,1,2,3,4,5); // lines are reversed
+ UINT32 mask = m_mpla->read(sel);
+ mask ^= 0x43fc3; // invert active-negative
+
+ // 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 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++)
+ if (mask & (1 << bit))
+ decode |= md[bit];
+
+ return decode;
+}
+
+void tms0980_cpu_device::device_reset()
+{
+ // common reset
+ tms1k_base_device::device_reset();
+
+ // pre-decode instructionset
+ m_fixed_decode.resize(0x200);
+ memset(&m_fixed_decode[0], 0, 0x200*sizeof(UINT32));
+ m_micro_decode.resize(0x200);
+ memset(&m_micro_decode[0], 0, 0x200*sizeof(UINT32));
+
+ for (UINT16 op = 0; op < 0x200; op++)
+ {
+ // upper half of the opcodes is always branch/call
+ if (op & 0x100)
+ m_fixed_decode[op] = (op & 0x80) ? F_CALL: F_BR;
+
+ // 6 output bits select a microinstruction index
+ m_micro_decode[op] = decode_micro(m_ipla->read(op) & 0x3f);
+
+ // the other ipla terms each select a fixed instruction
+ m_fixed_decode[op] |= decode_fixed(op);
+ }
+
+ // like on TMS0970, one of the terms directly select a microinstruction index (via R4-R8),
+ // but it can't be pre-determined when it's active
+ m_micro_direct.resize(0x40);
+ memset(&m_micro_decode[0], 0, 0x40*sizeof(UINT32));
+
+ for (int op = 0; op < 0x40; op++)
+ m_micro_direct[op] = decode_micro(op);
+}
+
+
+// program counter/opcode decode
+UINT32 tms0980_cpu_device::read_micro()
+{
+ // if ipla term 0 is active, R4-R8 directly select a microinstruction index when R0 or R0^BL is 0
+ int r0 = m_opcode >> 8 & 1;
+ if (m_ipla->read(m_opcode) & 0x40 && !((r0 & m_bl) ^ r0))
+ return m_micro_direct[m_opcode & 0x3f];
+ else
+ return m_micro_decode[m_opcode];
+}
+
+void tms0980_cpu_device::read_opcode()
+{
+ debugger_instruction_hook(this, m_rom_address << 1);
+ m_opcode = m_program->read_word(m_rom_address << 1) & 0x1ff;
+ m_c4 = BITSWAP8(m_opcode,7,6,5,4,0,1,2,3) & 0xf; // opcode operand is bitswapped for most opcodes
+
+ m_fixed = m_fixed_decode[m_opcode];
+ m_micro = read_micro();
+
+ // redirect mpla fixed instructions
+ if (m_micro & M_RSTR) m_fixed |= F_RSTR;
+ if (m_micro & M_SETR) m_fixed |= F_SETR;
+
+ next_pc();
+}
+
+
+// i/o handling
+UINT8 tms0980_cpu_device::read_k_input()
+{
+ UINT8 k = m_read_k(0, 0xff) & 0x1f;
+ UINT8 k3 = (k & 0x10) ? 3: 0; // the TMS0980 K3 line is simply K1|K2
+ return (k & 0xf) | k3;
+}
+
+void tms0980_cpu_device::set_cki_bus()
+{
+ switch (m_opcode & 0x1f8)
+ {
+ // 000001XXX: K-inputs
+ case 0x008:
+ m_cki_bus = read_k_input();
+ break;
+
+ // 0X0100XXX: select bit
+ case 0x020: case 0x0a0:
+ m_cki_bus = 1 << (m_c4 >> 2) ^ 0xf;
+ break;
+
+ // 0X1XXXXXX: constant
+ case 0x040: case 0x048: case 0x050: case 0x058: case 0x060: case 0x068: case 0x070: case 0x078:
+ case 0x0c0: case 0x0c8: case 0x0d0: case 0x0d8: case 0x0e0: case 0x0e8: case 0x0f0: case 0x0f8:
+ m_cki_bus = m_c4;
+ break;
+
+ default:
+ m_cki_bus = 0;
+ break;
+ }
+}
+
+
+// opcode deviations
+void tms0980_cpu_device::op_comx()
+{
+ // COMX: complement X register, but not the MSB
+ m_x ^= (m_x_mask >> 1);
+}
+
+void tms1980_cpu_device::op_tdo()
+{
+ // TDO: transfer accumulator and status(not status_latch!) to O-output
+ write_o_output(m_status << 4 | m_a);
+}
diff --git a/src/devices/cpu/tms1000/tms0980.h b/src/devices/cpu/tms1000/tms0980.h
new file mode 100644
index 00000000000..baaa24e01a6
--- /dev/null
+++ b/src/devices/cpu/tms1000/tms0980.h
@@ -0,0 +1,61 @@
+// license:BSD-3-Clause
+// copyright-holders:hap
+/*
+
+ TMS1000 family - TMS0980, TMS1980
+
+*/
+
+#ifndef _TMS0980_H_
+#define _TMS0980_H_
+
+#include "tms0970.h"
+
+
+class tms0980_cpu_device : public tms0970_cpu_device
+{
+public:
+ tms0980_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+ tms0980_cpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT8 o_pins, UINT8 r_pins, UINT8 pc_bits, UINT8 byte_bits, UINT8 x_bits, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data, const char *shortname, const char *source);
+
+protected:
+ // overrides
+ virtual UINT32 decode_fixed(UINT16 op);
+ virtual UINT32 decode_micro(UINT8 sel);
+ virtual void device_reset() override;
+
+ virtual machine_config_constructor device_mconfig_additions() const override;
+
+ virtual UINT32 disasm_min_opcode_bytes() const override { return 2; }
+ virtual UINT32 disasm_max_opcode_bytes() const override { return 2; }
+ virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options) override;
+
+ virtual UINT8 read_k_input() override;
+ virtual void set_cki_bus() override;
+ virtual UINT32 read_micro();
+ virtual void read_opcode() override;
+
+ virtual void op_comx() override;
+};
+
+class tms1980_cpu_device : public tms0980_cpu_device
+{
+public:
+ tms1980_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+protected:
+ // overrides
+ virtual machine_config_constructor device_mconfig_additions() const override;
+
+ virtual void write_o_output(UINT8 index) override { tms1k_base_device::write_o_output(index); }
+ virtual UINT8 read_k_input() override { return tms1k_base_device::read_k_input(); }
+
+ virtual void op_setr() override { tms1k_base_device::op_setr(); }
+ virtual void op_tdo() override;
+};
+
+
+extern const device_type TMS0980;
+extern const device_type TMS1980;
+
+#endif /* _TMS0980_H_ */
diff --git a/src/devices/cpu/tms1000/tms1000.cpp b/src/devices/cpu/tms1000/tms1000.cpp
new file mode 100644
index 00000000000..fbe1cb3c299
--- /dev/null
+++ b/src/devices/cpu/tms1000/tms1000.cpp
@@ -0,0 +1,123 @@
+// license:BSD-3-Clause
+// copyright-holders:hap
+/*
+
+ TMS1000 family - TMS1000, TMS1070, TMS1040, TMS1200
+
+*/
+
+#include "tms1000.h"
+#include "debugger.h"
+
+// TMS1000
+// - 64x4bit RAM array at the bottom-left
+// - 1024x8bit ROM array at the bottom-right
+// * FYI, the row-selector to the left of it is laid out as:
+// 3,4,11,12,19,20,27,28,35,36,43,44,51,52,59,60,0,7,8,15,16,23,24,31,32,39,40,47,48,55,56,63,
+// 2,5,10,13,18,21,26,29,34,37,42,45,50,53,58,61,1,6,9,14,17,22,25,30,33,38,41,46,49,54,57,62
+// - 30-term microinstructions PLA(mpla) at the top half, to the right of the midline, supporting 16 microinstructions
+// - 20-term output PLA(opla) at the top-left
+// - the ALU is between the opla and mpla
+const device_type TMS1000 = &device_creator<tms1000_cpu_device>; // 28-pin DIP, 11 R pins
+const device_type TMS1070 = &device_creator<tms1070_cpu_device>; // high voltage version
+const device_type TMS1040 = &device_creator<tms1040_cpu_device>; // same as TMS1070 with just a different pinout?
+const device_type TMS1200 = &device_creator<tms1200_cpu_device>; // 40-pin DIP, 13 R pins
+// TMS1270 has 10 O pins, how does that work?
+
+
+// internal memory maps
+static ADDRESS_MAP_START(program_10bit_8, AS_PROGRAM, 8, tms1k_base_device)
+ AM_RANGE(0x000, 0x3ff) AM_ROM
+ADDRESS_MAP_END
+
+static ADDRESS_MAP_START(data_64x4, AS_DATA, 8, tms1k_base_device)
+ AM_RANGE(0x00, 0x3f) AM_RAM
+ADDRESS_MAP_END
+
+
+// device definitions
+tms1000_cpu_device::tms1000_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : tms1k_base_device(mconfig, TMS1000, "TMS1000", tag, owner, clock, 8 /* o pins */, 11 /* r pins */, 6 /* pc bits */, 8 /* byte width */, 2 /* x width */, 10 /* prg width */, ADDRESS_MAP_NAME(program_10bit_8), 6 /* data width */, ADDRESS_MAP_NAME(data_64x4), "tms1000", __FILE__)
+{ }
+
+tms1000_cpu_device::tms1000_cpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT8 o_pins, UINT8 r_pins, UINT8 pc_bits, UINT8 byte_bits, UINT8 x_bits, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data, const char *shortname, const char *source)
+ : tms1k_base_device(mconfig, type, name, tag, owner, clock, o_pins, r_pins, pc_bits, byte_bits, x_bits, prgwidth, program, datawidth, data, shortname, source)
+{ }
+
+tms1070_cpu_device::tms1070_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : tms1000_cpu_device(mconfig, TMS1070, "TMS1070", tag, owner, clock, 8, 11, 6, 8, 2, 10, ADDRESS_MAP_NAME(program_10bit_8), 6, ADDRESS_MAP_NAME(data_64x4), "tms1070", __FILE__)
+{ }
+
+tms1040_cpu_device::tms1040_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : tms1000_cpu_device(mconfig, TMS1040, "TMS1040", tag, owner, clock, 8, 11, 6, 8, 2, 10, ADDRESS_MAP_NAME(program_10bit_8), 6, ADDRESS_MAP_NAME(data_64x4), "tms1040", __FILE__)
+{ }
+
+tms1200_cpu_device::tms1200_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : tms1000_cpu_device(mconfig, TMS1200, "TMS1200", tag, owner, clock, 8, 13, 6, 8, 2, 10, ADDRESS_MAP_NAME(program_10bit_8), 6, ADDRESS_MAP_NAME(data_64x4), "tms1200", __FILE__)
+{ }
+
+
+// machine configs
+static MACHINE_CONFIG_FRAGMENT(tms1000)
+
+ // microinstructions PLA, output PLA
+ MCFG_PLA_ADD("mpla", 8, 16, 30)
+ MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
+ MCFG_PLA_ADD("opla", 5, 8, 20)
+ MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
+MACHINE_CONFIG_END
+
+machine_config_constructor tms1000_cpu_device::device_mconfig_additions() const
+{
+ return MACHINE_CONFIG_NAME(tms1000);
+}
+
+
+// disasm
+offs_t tms1000_cpu_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options)
+{
+ extern CPU_DISASSEMBLE(tms1000);
+ return CPU_DISASSEMBLE_NAME(tms1000)(this, buffer, pc, oprom, opram, options);
+}
+
+
+// device_reset
+void tms1000_cpu_device::device_reset()
+{
+ // common reset
+ tms1k_base_device::device_reset();
+
+ // pre-decode instructionset
+ m_fixed_decode.resize(0x100);
+ memset(&m_fixed_decode[0], 0, 0x100*sizeof(UINT32));
+ m_micro_decode.resize(0x100);
+ memset(&m_micro_decode[0], 0, 0x100*sizeof(UINT32));
+
+ for (int op = 0; op < 0x100; op++)
+ {
+ // _____ _____ ______ _____ ______ _____ _____ _____ _____
+ const UINT32 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 mask = m_mpla->read(op);
+ mask ^= 0x3fc8; // invert active-negative
+
+ for (int bit = 0; bit < 16; bit++)
+ if (mask & (1 << bit))
+ m_micro_decode[op] |= md[bit];
+ }
+
+ // the fixed instruction set is not programmable
+ m_fixed_decode[0x00] = F_COMX;
+ m_fixed_decode[0x0a] = F_TDO;
+ m_fixed_decode[0x0b] = F_CLO;
+ m_fixed_decode[0x0c] = F_RSTR;
+ m_fixed_decode[0x0d] = F_SETR;
+ m_fixed_decode[0x0f] = F_RETN;
+
+ for (int i = 0x10; i < 0x20; i++) m_fixed_decode[i] = F_LDP;
+ for (int i = 0x30; i < 0x34; i++) m_fixed_decode[i] = F_SBIT;
+ for (int i = 0x34; i < 0x38; i++) m_fixed_decode[i] = F_RBIT;
+ for (int i = 0x3c; i < 0x40; i++) m_fixed_decode[i] = F_LDX;
+
+ for (int i = 0x80; i < 0xc0; i++) m_fixed_decode[i] = F_BR;
+ for (int i = 0xc0; i < 0x100; i++) m_fixed_decode[i] = F_CALL;
+}
diff --git a/src/devices/cpu/tms1000/tms1000.h b/src/devices/cpu/tms1000/tms1000.h
new file mode 100644
index 00000000000..361e4e6fe83
--- /dev/null
+++ b/src/devices/cpu/tms1000/tms1000.h
@@ -0,0 +1,55 @@
+// license:BSD-3-Clause
+// copyright-holders:hap
+/*
+
+ TMS1000 family - TMS1000, TMS1070, TMS1040, TMS1200
+
+*/
+
+#ifndef _TMS1000_H_
+#define _TMS1000_H_
+
+#include "tms1k_base.h"
+
+
+class tms1000_cpu_device : public tms1k_base_device
+{
+public:
+ tms1000_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+ tms1000_cpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT8 o_pins, UINT8 r_pins, UINT8 pc_bits, UINT8 byte_bits, UINT8 x_bits, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data, const char *shortname, const char *source);
+
+protected:
+ // overrides
+ virtual void device_reset() override;
+ virtual machine_config_constructor device_mconfig_additions() const override;
+
+
+ virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options) override;
+};
+
+class tms1070_cpu_device : public tms1000_cpu_device
+{
+public:
+ tms1070_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+};
+
+class tms1040_cpu_device : public tms1000_cpu_device
+{
+public:
+ tms1040_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+};
+
+
+class tms1200_cpu_device : public tms1000_cpu_device
+{
+public:
+ tms1200_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+};
+
+
+extern const device_type TMS1000;
+extern const device_type TMS1070;
+extern const device_type TMS1040;
+extern const device_type TMS1200;
+
+#endif /* _TMS1000_H_ */
diff --git a/src/devices/cpu/tms1000/tms1100.cpp b/src/devices/cpu/tms1000/tms1100.cpp
new file mode 100644
index 00000000000..042a0bcf6bf
--- /dev/null
+++ b/src/devices/cpu/tms1000/tms1100.cpp
@@ -0,0 +1,87 @@
+// license:BSD-3-Clause
+// copyright-holders:hap
+/*
+
+ TMS1000 family - TMS1100, TMS1170, TMS1300, TMS1370
+
+*/
+
+#include "tms1100.h"
+#include "debugger.h"
+
+// TMS1100 is nearly the same as TMS1000, some different opcodes, and with double the RAM and ROM
+const device_type TMS1100 = &device_creator<tms1100_cpu_device>; // 28-pin DIP, 11 R pins
+const device_type TMS1170 = &device_creator<tms1170_cpu_device>; // high voltage version
+const device_type TMS1300 = &device_creator<tms1300_cpu_device>; // 40-pin DIP, 16 R pins
+const device_type TMS1370 = &device_creator<tms1370_cpu_device>; // high voltage version
+
+
+// internal memory maps
+static ADDRESS_MAP_START(program_11bit_8, AS_PROGRAM, 8, tms1k_base_device)
+ AM_RANGE(0x000, 0x7ff) AM_ROM
+ADDRESS_MAP_END
+
+static ADDRESS_MAP_START(data_128x4, AS_DATA, 8, tms1k_base_device)
+ AM_RANGE(0x00, 0x7f) AM_RAM
+ADDRESS_MAP_END
+
+
+// device definitions
+tms1100_cpu_device::tms1100_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : tms1000_cpu_device(mconfig, TMS1100, "TMS1100", tag, owner, clock, 8 /* o pins */, 11 /* r pins */, 6 /* pc bits */, 8 /* byte width */, 3 /* x width */, 11 /* prg width */, ADDRESS_MAP_NAME(program_11bit_8), 7 /* data width */, ADDRESS_MAP_NAME(data_128x4), "tms1100", __FILE__)
+{ }
+
+tms1100_cpu_device::tms1100_cpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT8 o_pins, UINT8 r_pins, UINT8 pc_bits, UINT8 byte_bits, UINT8 x_bits, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data, const char *shortname, const char *source)
+ : tms1000_cpu_device(mconfig, type, name, tag, owner, clock, o_pins, r_pins, pc_bits, byte_bits, x_bits, prgwidth, program, datawidth, data, shortname, source)
+{ }
+
+tms1170_cpu_device::tms1170_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : tms1100_cpu_device(mconfig, TMS1170, "TMS1170", tag, owner, clock, 8, 11, 6, 8, 3, 11, ADDRESS_MAP_NAME(program_11bit_8), 7, ADDRESS_MAP_NAME(data_128x4), "tms1170", __FILE__)
+{ }
+
+tms1300_cpu_device::tms1300_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : tms1100_cpu_device(mconfig, TMS1300, "TMS1300", tag, owner, clock, 8, 16, 6, 8, 3, 11, ADDRESS_MAP_NAME(program_11bit_8), 7, ADDRESS_MAP_NAME(data_128x4), "tms1300", __FILE__)
+{ }
+
+tms1370_cpu_device::tms1370_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : tms1100_cpu_device(mconfig, TMS1370, "TMS1370", tag, owner, clock, 8, 16, 6, 8, 3, 11, ADDRESS_MAP_NAME(program_11bit_8), 7, ADDRESS_MAP_NAME(data_128x4), "tms1370", __FILE__)
+{ }
+
+
+// disasm
+offs_t tms1100_cpu_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options)
+{
+ extern CPU_DISASSEMBLE(tms1100);
+ return CPU_DISASSEMBLE_NAME(tms1100)(this, buffer, pc, oprom, opram, options);
+}
+
+
+// device_reset
+void tms1100_cpu_device::device_reset()
+{
+ tms1000_cpu_device::device_reset();
+
+ // small differences in 00-3f area
+ m_fixed_decode[0x00] = 0;
+ m_fixed_decode[0x09] = F_COMX8; // !
+ m_fixed_decode[0x0b] = F_COMC;
+
+ for (int i = 0x28; i < 0x30; i++) m_fixed_decode[i] = F_LDX;
+ for (int i = 0x3c; i < 0x40; i++) m_fixed_decode[i] = 0;
+}
+
+
+// opcode deviations
+void tms1100_cpu_device::op_setr()
+{
+ // SETR: same, but X register MSB must be clear
+ if (~m_x & (1 << (m_x_bits-1)))
+ tms1k_base_device::op_setr();
+}
+
+void tms1100_cpu_device::op_rstr()
+{
+ // RSTR: same, but X register MSB must be clear
+ if (~m_x & (1 << (m_x_bits-1)))
+ tms1k_base_device::op_rstr();
+}
diff --git a/src/devices/cpu/tms1000/tms1100.h b/src/devices/cpu/tms1000/tms1100.h
new file mode 100644
index 00000000000..2a78af0f283
--- /dev/null
+++ b/src/devices/cpu/tms1000/tms1100.h
@@ -0,0 +1,56 @@
+// license:BSD-3-Clause
+// copyright-holders:hap
+/*
+
+ TMS1000 family - TMS1100, TMS1170, TMS1300, TMS1370
+
+*/
+
+#ifndef _TMS1100_H_
+#define _TMS1100_H_
+
+#include "tms1000.h"
+
+
+class tms1100_cpu_device : public tms1000_cpu_device
+{
+public:
+ tms1100_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+ tms1100_cpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT8 o_pins, UINT8 r_pins, UINT8 pc_bits, UINT8 byte_bits, UINT8 x_bits, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data, const char *shortname, const char *source);
+
+protected:
+ // overrides
+ virtual void device_reset() override;
+
+ virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options) override;
+
+ virtual void op_setr() override;
+ virtual void op_rstr() override;
+};
+
+class tms1170_cpu_device : public tms1100_cpu_device
+{
+public:
+ tms1170_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+};
+
+class tms1300_cpu_device : public tms1100_cpu_device
+{
+public:
+ tms1300_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+};
+
+class tms1370_cpu_device : public tms1100_cpu_device
+{
+public:
+ tms1370_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+};
+
+
+extern const device_type TMS1100;
+extern const device_type TMS1170;
+extern const device_type TMS1300;
+extern const device_type TMS1370;
+
+
+#endif /* _TMS1100_H_ */
diff --git a/src/devices/cpu/tms1000/tms1400.cpp b/src/devices/cpu/tms1000/tms1400.cpp
new file mode 100644
index 00000000000..e9246b18685
--- /dev/null
+++ b/src/devices/cpu/tms1000/tms1400.cpp
@@ -0,0 +1,143 @@
+// license:BSD-3-Clause
+// copyright-holders:hap
+/*
+
+ TMS1000 family - TMS1400, TMS1470, TMS1600, TMS1670
+
+ TODO:
+ - emulate TMS1600 L-pins
+
+*/
+
+#include "tms1400.h"
+#include "debugger.h"
+
+// TMS1400 follows the TMS1100, it doubles the ROM size again (4 chapters of 16 pages), and adds a 3-level callstack
+// - rotate the view and mirror the OR-mask to get the proper layout of the mpla, the default is identical to tms1100
+// - the opla size is increased from 20 to 32 terms
+const device_type TMS1400 = &device_creator<tms1400_cpu_device>; // 28-pin DIP, 11 R pins (TMS1400CR is same, but with TMS1100 pinout)
+const device_type TMS1470 = &device_creator<tms1470_cpu_device>; // high voltage version, 1 R pin removed for Vdd
+
+// TMS1600 adds more I/O to the TMS1400, input pins are doubled with added L1,2,4,8
+// - rotate the view and mirror the OR-mask to get the proper layout of the mpla, the default is identical to tms1100
+// - the opla size is increased from 20 to 32 terms
+const device_type TMS1600 = &device_creator<tms1600_cpu_device>; // 40-pin DIP, 16 R pins
+const device_type TMS1670 = &device_creator<tms1670_cpu_device>; // high voltage version
+
+
+// internal memory maps
+static ADDRESS_MAP_START(program_12bit_8, AS_PROGRAM, 8, tms1k_base_device)
+ AM_RANGE(0x000, 0xfff) AM_ROM
+ADDRESS_MAP_END
+
+static ADDRESS_MAP_START(data_128x4, AS_DATA, 8, tms1k_base_device)
+ AM_RANGE(0x00, 0x7f) AM_RAM
+ADDRESS_MAP_END
+
+
+// device definitions
+tms1400_cpu_device::tms1400_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : tms1100_cpu_device(mconfig, TMS1400, "TMS1400", tag, owner, clock, 8 /* o pins */, 11 /* r pins */, 6 /* pc bits */, 8 /* byte width */, 3 /* x width */, 12 /* prg width */, ADDRESS_MAP_NAME(program_12bit_8), 7 /* data width */, ADDRESS_MAP_NAME(data_128x4), "tms1400", __FILE__)
+{ }
+
+tms1400_cpu_device::tms1400_cpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT8 o_pins, UINT8 r_pins, UINT8 pc_bits, UINT8 byte_bits, UINT8 x_bits, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data, const char *shortname, const char *source)
+ : tms1100_cpu_device(mconfig, type, name, tag, owner, clock, o_pins, r_pins, pc_bits, byte_bits, x_bits, prgwidth, program, datawidth, data, shortname, source)
+{ }
+
+tms1470_cpu_device::tms1470_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : tms1400_cpu_device(mconfig, TMS1470, "TMS1470", tag, owner, clock, 8, 10, 6, 8, 3, 12, ADDRESS_MAP_NAME(program_12bit_8), 7, ADDRESS_MAP_NAME(data_128x4), "tms1470", __FILE__)
+{ }
+
+
+tms1600_cpu_device::tms1600_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : tms1400_cpu_device(mconfig, TMS1600, "TMS1600", tag, owner, clock, 8, 16, 6, 8, 3, 12, ADDRESS_MAP_NAME(program_12bit_8), 7, ADDRESS_MAP_NAME(data_128x4), "tms1600", __FILE__)
+{ }
+
+tms1600_cpu_device::tms1600_cpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT8 o_pins, UINT8 r_pins, UINT8 pc_bits, UINT8 byte_bits, UINT8 x_bits, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data, const char *shortname, const char *source)
+ : tms1400_cpu_device(mconfig, type, name, tag, owner, clock, o_pins, r_pins, pc_bits, byte_bits, x_bits, prgwidth, program, datawidth, data, shortname, source)
+{ }
+
+tms1670_cpu_device::tms1670_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : tms1600_cpu_device(mconfig, TMS1670, "TMS1670", tag, owner, clock, 8, 16, 6, 8, 3, 12, ADDRESS_MAP_NAME(program_12bit_8), 7, ADDRESS_MAP_NAME(data_128x4), "tms1670", __FILE__)
+{ }
+
+
+// machine configs
+static MACHINE_CONFIG_FRAGMENT(tms1400)
+
+ // microinstructions PLA, output PLA
+ MCFG_PLA_ADD("mpla", 8, 16, 30)
+ MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
+ MCFG_PLA_ADD("opla", 5, 8, 32)
+ MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
+MACHINE_CONFIG_END
+
+machine_config_constructor tms1400_cpu_device::device_mconfig_additions() const
+{
+ return MACHINE_CONFIG_NAME(tms1400);
+}
+
+
+// device_reset
+void tms1400_cpu_device::device_reset()
+{
+ tms1100_cpu_device::device_reset();
+
+ // small differences in 00-3f area
+ m_fixed_decode[0x0b] = F_TPC;
+}
+
+
+// opcode deviations
+void tms1400_cpu_device::op_br()
+{
+ // BR/BL: conditional branch
+ if (m_status)
+ {
+ m_pa = m_pb; // don't care about clatch
+ m_ca = m_cb;
+ m_pc = m_opcode & m_pc_mask;
+ }
+}
+
+void tms1400_cpu_device::op_call()
+{
+ // CALL/CALLL: conditional call
+ if (m_status)
+ {
+ // 3-level stack, mask clatch 3 bits (no need to mask others)
+ m_clatch = (m_clatch << 1 | 1) & 7;
+
+ m_sr = m_sr << m_pc_bits | m_pc;
+ m_pc = m_opcode & m_pc_mask;
+
+ m_ps = m_ps << 4 | m_pa;
+ m_pa = m_pb;
+
+ m_cs = m_cs << 2 | m_ca;
+ m_ca = m_cb;
+ }
+ else
+ {
+ m_pb = m_pa;
+ m_cb = m_ca;
+ }
+}
+
+void tms1400_cpu_device::op_retn()
+{
+ // RETN: return from subroutine
+ if (m_clatch & 1)
+ {
+ m_clatch >>= 1;
+
+ m_pc = m_sr & m_pc_mask;
+ m_sr >>= m_pc_bits;
+
+ m_pa = m_pb = m_ps & 0xf;
+ m_ps >>= 4;
+
+ m_ca = m_cb = m_cs & 3;
+ m_cs >>= 2;
+ }
+}
diff --git a/src/devices/cpu/tms1000/tms1400.h b/src/devices/cpu/tms1000/tms1400.h
new file mode 100644
index 00000000000..0b73babc223
--- /dev/null
+++ b/src/devices/cpu/tms1000/tms1400.h
@@ -0,0 +1,61 @@
+// license:BSD-3-Clause
+// copyright-holders:hap
+/*
+
+ TMS1000 family - TMS1400, TMS1470, TMS1600, TMS1670
+
+*/
+
+#ifndef _TMS1400_H_
+#define _TMS1400_H_
+
+#include "tms1100.h"
+
+
+class tms1400_cpu_device : public tms1100_cpu_device
+{
+public:
+ tms1400_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+ tms1400_cpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT8 o_pins, UINT8 r_pins, UINT8 pc_bits, UINT8 byte_bits, UINT8 x_bits, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data, const char *shortname, const char *source);
+
+protected:
+ // overrides
+ virtual void device_reset() override;
+ virtual machine_config_constructor device_mconfig_additions() const override;
+
+ virtual void op_br() override;
+ virtual void op_call() override;
+ virtual void op_retn() override;
+
+ virtual void op_setr() override { tms1k_base_device::op_setr(); } // no anomaly with MSB of X register
+ virtual void op_rstr() override { tms1k_base_device::op_rstr(); } // "
+};
+
+class tms1470_cpu_device : public tms1400_cpu_device
+{
+public:
+ tms1470_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+};
+
+
+class tms1600_cpu_device : public tms1400_cpu_device
+{
+public:
+ tms1600_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+ tms1600_cpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT8 o_pins, UINT8 r_pins, UINT8 pc_bits, UINT8 byte_bits, UINT8 x_bits, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data, const char *shortname, const char *source);
+};
+
+class tms1670_cpu_device : public tms1600_cpu_device
+{
+public:
+ tms1670_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+};
+
+
+extern const device_type TMS1400;
+extern const device_type TMS1470;
+extern const device_type TMS1600;
+extern const device_type TMS1670;
+
+
+#endif /* _TMS1400_H_ */
diff --git a/src/devices/cpu/tms1000/tms1k_base.cpp b/src/devices/cpu/tms1000/tms1k_base.cpp
new file mode 100644
index 00000000000..10e041b5104
--- /dev/null
+++ b/src/devices/cpu/tms1000/tms1k_base.cpp
@@ -0,0 +1,635 @@
+// license:BSD-3-Clause
+// copyright-holders:Wilbert Pol, hap
+/*
+
+ TMS1000 family - base/shared
+
+ TODO:
+ - fix debugger disasm view
+
+
+The TMS0980 and TMS1000-family MCU cores are very similar. The TMS0980 has a
+slightly bigger addressable area and uses 9bit instructions where the TMS1000
+family uses 8bit instruction. The instruction set themselves are very similar
+though.
+
+Each instruction takes 12 cycles to execute in 2 phases: a fetch phase and an
+execution phase. The execution phase takes place at the same time as the fetch
+phase of the next instruction. So, during execution there are both fetch and
+execution operations taking place. The operation can be split up as follows:
+cycle #0
+ - Fetch:
+ 1. ROM address 0
+ - Execute:
+ 1. Read RAM
+ 2. Clear ALU inputs
+ 3. Execute BRANCH/CALL/RETN part #2
+ 4. K input valid
+cycle #1
+ - Fetch:
+ 1. ROM address 1
+ - Execute:
+ 1. Update ALU inputs
+cycle #2
+ - Fetch:
+ 1. nothing/wait(?)
+ - Execute:
+ 1. Perform ALU operation
+ 2. Write RAM
+cycle #3
+ - Fetch:
+ 1. Fetch/Update PC/RAM address #1
+ - Execute:
+ 1. Register store part #1
+cycle #4
+ - Fetch:
+ 1. Fetch/Update PC/RAM address #2
+ - Execute:
+ 1. Register store part #2
+cycle #5
+ - Fetch:
+ 1. Instruction decode
+ - Execute:
+ 1. Execute BRANCH/CALL/RETN part #1
+
+The MCU cores contains a set of fixed instructions and a set of
+instructions created using microinstructions. A subset of the
+instruction set could be defined from the microinstructions by
+TI customers.
+
+cycle #0: 15TN, ATN, CIN, CKN, CKP, DMTP, MTN, MTP, NATN, NDMTP, YTP
+cycle #2: C8(?), CKM, NE(?), STO
+cycle #3,#4: AUTA, AUTY
+
+unknown cycle: CME, SSE, SSS
+
+*/
+
+#include "tms1k_base.h"
+#include "debugger.h"
+
+// disasm
+void tms1k_base_device::state_string_export(const device_state_entry &entry, std::string &str) const
+{
+ switch (entry.index())
+ {
+ case STATE_GENPC:
+ str = string_format("%03X", m_rom_address << ((m_byte_bits > 8) ? 1 : 0));
+ break;
+ }
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+enum
+{
+ TMS1XXX_PC=1, TMS1XXX_SR, TMS1XXX_PA, TMS1XXX_PB,
+ TMS1XXX_A, TMS1XXX_X, TMS1XXX_Y, TMS1XXX_STATUS
+};
+
+void tms1k_base_device::device_start()
+{
+ m_program = &space(AS_PROGRAM);
+ m_data = &space(AS_DATA);
+
+ m_o_mask = (1 << m_o_pins) - 1;
+ m_r_mask = (1 << m_r_pins) - 1;
+ m_pc_mask = (1 << m_pc_bits) - 1;
+ m_x_mask = (1 << m_x_bits) - 1;
+
+ // resolve callbacks
+ m_read_k.resolve_safe(0);
+ m_write_o.resolve_safe();
+ m_write_r.resolve_safe();
+ m_power_off.resolve_safe();
+
+ // zerofill
+ m_pc = 0;
+ m_sr = 0;
+ m_pa = 0;
+ m_pb = 0;
+ m_ps = 0;
+ m_a = 0;
+ m_x = 0;
+ m_y = 0;
+ m_ca = 0;
+ m_cb = 0;
+ m_cs = 0;
+ m_r = 0;
+ m_o = 0;
+ m_cki_bus = 0;
+ m_c4 = 0;
+ m_p = 0;
+ m_n = 0;
+ m_adder_out = 0;
+ m_carry_in = 0;
+ m_carry_out = 0;
+ m_status = 0;
+ m_status_latch = 0;
+ m_eac = 0;
+ m_clatch = 0;
+ m_add = 0;
+ m_bl = 0;
+
+ m_ram_in = 0;
+ m_dam_in = 0;
+ m_ram_out = 0;
+ m_ram_address = 0;
+ m_rom_address = 0;
+ m_opcode = 0;
+ m_fixed = 0;
+ m_micro = 0;
+ m_subcycle = 0;
+
+ // register for savestates
+ save_item(NAME(m_pc));
+ save_item(NAME(m_sr));
+ save_item(NAME(m_pa));
+ save_item(NAME(m_pb));
+ save_item(NAME(m_ps));
+ save_item(NAME(m_a));
+ save_item(NAME(m_x));
+ save_item(NAME(m_y));
+ save_item(NAME(m_ca));
+ save_item(NAME(m_cb));
+ save_item(NAME(m_cs));
+ save_item(NAME(m_r));
+ save_item(NAME(m_o));
+ save_item(NAME(m_cki_bus));
+ save_item(NAME(m_c4));
+ save_item(NAME(m_p));
+ save_item(NAME(m_n));
+ save_item(NAME(m_adder_out));
+ save_item(NAME(m_carry_in));
+ save_item(NAME(m_carry_out));
+ save_item(NAME(m_status));
+ save_item(NAME(m_status_latch));
+ save_item(NAME(m_eac));
+ save_item(NAME(m_clatch));
+ save_item(NAME(m_add));
+ save_item(NAME(m_bl));
+
+ save_item(NAME(m_ram_in));
+ save_item(NAME(m_dam_in));
+ save_item(NAME(m_ram_out));
+ save_item(NAME(m_ram_address));
+ save_item(NAME(m_rom_address));
+ save_item(NAME(m_opcode));
+ save_item(NAME(m_fixed));
+ save_item(NAME(m_micro));
+ save_item(NAME(m_subcycle));
+
+ // register state for debugger
+ state_add(TMS1XXX_PC, "PC", m_pc ).formatstr("%02X");
+ state_add(TMS1XXX_SR, "SR", m_sr ).formatstr("%01X");
+ state_add(TMS1XXX_PA, "PA", m_pa ).formatstr("%01X");
+ state_add(TMS1XXX_PB, "PB", m_pb ).formatstr("%01X");
+ state_add(TMS1XXX_A, "A", m_a ).formatstr("%01X");
+ state_add(TMS1XXX_X, "X", m_x ).formatstr("%01X");
+ state_add(TMS1XXX_Y, "Y", m_y ).formatstr("%01X");
+ state_add(TMS1XXX_STATUS, "STATUS", m_status).formatstr("%01X");
+
+ state_add(STATE_GENPC, "curpc", m_rom_address).formatstr("%03X").noshow();
+ state_add(STATE_GENFLAGS, "GENFLAGS", m_sr).formatstr("%8s").noshow();
+
+ m_icountptr = &m_icount;
+}
+
+
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void tms1k_base_device::device_reset()
+{
+ m_pa = 0xf;
+ m_pb = 0xf;
+ m_pc = 0;
+ m_ca = 0;
+ m_cb = 0;
+ m_cs = 0;
+
+ m_eac = 0;
+ m_bl = 0;
+ m_add = 0;
+
+ m_opcode = 0;
+ m_micro = 0;
+ m_fixed = 0;
+
+ m_subcycle = 0;
+
+ // clear outputs
+ m_r = 0;
+ m_write_r(0, m_r & m_r_mask, 0xffff);
+ write_o_output(0);
+ m_write_r(0, m_r & m_r_mask, 0xffff);
+ m_power_off(0);
+}
+
+
+
+//-------------------------------------------------
+// program counter/opcode decode
+//-------------------------------------------------
+
+void tms1k_base_device::next_pc()
+{
+ // The program counter is a LFSR. To put it simply, the feedback bit is a XOR of the two highest bits,
+ // but it makes an exception when all low bits are set (eg. in TMS1000 case, when PC is 0x1f or 0x3f).
+ int high = 1 << (m_pc_bits - 1);
+ int fb = (m_pc << 1 & high) == (m_pc & high);
+
+ if (m_pc == (m_pc_mask >> 1))
+ fb = 1;
+ else if (m_pc == m_pc_mask)
+ fb = 0;
+
+ m_pc = (m_pc << 1 | fb) & m_pc_mask;
+}
+
+void tms1k_base_device::read_opcode()
+{
+ debugger_instruction_hook(this, m_rom_address);
+ m_opcode = m_program->read_byte(m_rom_address);
+ m_c4 = BITSWAP8(m_opcode,7,6,5,4,0,1,2,3) & 0xf; // opcode operand is bitswapped for most opcodes
+
+ m_fixed = m_fixed_decode[m_opcode];
+ m_micro = m_micro_decode[m_opcode];
+
+ next_pc();
+}
+
+
+
+//-------------------------------------------------
+// i/o handling
+//-------------------------------------------------
+
+void tms1k_base_device::write_o_output(UINT8 index)
+{
+ // a hardcoded table is supported if the output pla is unknown
+ m_o = (m_output_pla_table == nullptr) ? m_opla->read(index) : m_output_pla_table[index];
+ m_write_o(0, m_o & m_o_mask, 0xffff);
+}
+
+UINT8 tms1k_base_device::read_k_input()
+{
+ // K1,2,4,8 (KC test pin is not emulated)
+ return m_read_k(0, 0xff) & 0xf;
+}
+
+void tms1k_base_device::set_cki_bus()
+{
+ switch (m_opcode & 0xf8)
+ {
+ // 00001XXX: K-inputs
+ case 0x08:
+ m_cki_bus = read_k_input();
+ break;
+
+ // 0011XXXX: select bit
+ case 0x30: case 0x38:
+ m_cki_bus = 1 << (m_c4 >> 2) ^ 0xf;
+ break;
+
+ // 01XXXXXX: constant
+ case 0x00: // R2,3,4 are NANDed with eachother, and then ORed with R1, making 00000XXX valid too
+ case 0x40: case 0x48: case 0x50: case 0x58: case 0x60: case 0x68: case 0x70: case 0x78:
+ m_cki_bus = m_c4;
+ break;
+
+ default:
+ m_cki_bus = 0;
+ break;
+ }
+}
+
+
+
+//-------------------------------------------------
+// fixed opcode set
+//-------------------------------------------------
+
+// handle branches:
+
+// TMS1000/common
+// note: add(latch) and bl(branch latch) are specific to 0980 series,
+// c(chapter) bits are specific to 1100(and 1400) series
+
+void tms1k_base_device::op_br()
+{
+ // BR/BL: conditional branch
+ if (m_status)
+ {
+ if (m_clatch == 0)
+ m_pa = m_pb;
+ m_ca = m_cb;
+ m_pc = m_opcode & m_pc_mask;
+ }
+}
+
+void tms1k_base_device::op_call()
+{
+ // CALL/CALLL: conditional call
+ if (m_status)
+ {
+ UINT8 prev_pa = m_pa;
+
+ if (m_clatch == 0)
+ {
+ m_clatch = 1;
+ m_sr = m_pc;
+ m_pa = m_pb;
+ m_cs = m_ca;
+ }
+ m_ca = m_cb;
+ m_pb = prev_pa;
+ m_pc = m_opcode & m_pc_mask;
+ }
+}
+
+void tms1k_base_device::op_retn()
+{
+ // RETN: return from subroutine
+ if (m_clatch == 1)
+ {
+ m_clatch = 0;
+ m_pc = m_sr;
+ m_ca = m_cs;
+ }
+ m_add = 0;
+ m_bl = 0;
+ m_pa = m_pb;
+}
+
+
+// handle other:
+
+// TMS1000/common
+
+void tms1k_base_device::op_sbit()
+{
+ // SBIT: set memory bit
+ if (m_ram_out == -1)
+ m_ram_out = m_ram_in;
+ m_ram_out |= (m_cki_bus ^ 0xf);
+}
+
+void tms1k_base_device::op_rbit()
+{
+ // RBIT: reset memory bit
+ if (m_ram_out == -1)
+ m_ram_out = m_ram_in;
+ m_ram_out &= m_cki_bus;
+}
+
+void tms1k_base_device::op_setr()
+{
+ // SETR: set one R-output line
+ m_r = m_r | (1 << m_y);
+ m_write_r(0, m_r & m_r_mask, 0xffff);
+}
+
+void tms1k_base_device::op_rstr()
+{
+ // RSTR: reset one R-output line
+ m_r = m_r & ~(1 << m_y);
+ m_write_r(0, m_r & m_r_mask, 0xffff);
+}
+
+void tms1k_base_device::op_tdo()
+{
+ // TDO: transfer accumulator and status latch to O-output
+ write_o_output(m_status_latch << 4 | m_a);
+}
+
+void tms1k_base_device::op_clo()
+{
+ // CLO: clear O-output
+ write_o_output(0);
+}
+
+void tms1k_base_device::op_ldx()
+{
+ // LDX: load X register with (x_bits) constant
+ m_x = m_c4 >> (4-m_x_bits);
+}
+
+void tms1k_base_device::op_comx()
+{
+ // COMX: complement X register
+ m_x ^= m_x_mask;
+}
+
+void tms1k_base_device::op_comx8()
+{
+ // COMX8: complement MSB of X register
+ // note: on TMS1100, the mnemonic is simply called "COMX"
+ m_x ^= 1 << (m_x_bits-1);
+}
+
+void tms1k_base_device::op_ldp()
+{
+ // LDP: load page buffer with constant
+ m_pb = m_c4;
+}
+
+
+// TMS1100-specific
+
+void tms1k_base_device::op_comc()
+{
+ // COMC: complement chapter buffer
+ m_cb ^= 1;
+}
+
+
+// TMS1400-specific
+
+void tms1k_base_device::op_tpc()
+{
+ // TPC: transfer page buffer to chapter buffer
+ m_cb = m_pb & 3;
+}
+
+
+// TMS0980-specific (and possibly child classes)
+
+void tms1k_base_device::op_xda()
+{
+ // XDA: exchange DAM and A
+ // note: setting A to DAM is done with DMTP and AUTA during this instruction
+ m_ram_address |= (0x10 << (m_x_bits-1));
+}
+
+void tms1k_base_device::op_off()
+{
+ // OFF: request auto power-off
+ m_power_off(1);
+}
+
+void tms1k_base_device::op_seac()
+{
+ // SEAC: set end around carry
+ m_eac = 1;
+}
+
+void tms1k_base_device::op_reac()
+{
+ // REAC: reset end around carry
+ m_eac = 0;
+}
+
+void tms1k_base_device::op_sal()
+{
+ // SAL: set add latch (reset is done with RETN)
+ m_add = 1;
+}
+
+void tms1k_base_device::op_sbl()
+{
+ // SBL: set branch latch (reset is done with RETN)
+ m_bl = 1;
+}
+
+
+
+//-------------------------------------------------
+// execute_run
+//-------------------------------------------------
+
+void tms1k_base_device::execute_run()
+{
+ do
+ {
+ m_icount--;
+ switch (m_subcycle)
+ {
+ case 0:
+ // fetch: rom address 1/2
+
+ // execute: br/call 2/2
+ if (m_fixed & F_BR) op_br();
+ if (m_fixed & F_CALL) op_call();
+ if (m_fixed & F_RETN) op_retn();
+
+ // execute: k input valid, read ram, clear alu inputs
+ dynamic_output();
+ set_cki_bus();
+ m_ram_in = m_data->read_byte(m_ram_address) & 0xf;
+ m_dam_in = m_data->read_byte(m_ram_address | (0x10 << (m_x_bits-1))) & 0xf;
+ m_p = 0;
+ m_n = 0;
+ m_carry_in = 0;
+
+ break;
+
+ case 1:
+ // fetch: rom address 2/2
+ m_rom_address = (m_ca << (m_pc_bits+4)) | (m_pa << m_pc_bits) | m_pc;
+
+ // execute: update alu inputs
+ // N inputs
+ if (m_micro & M_15TN) m_n |= 0xf;
+ if (m_micro & M_ATN) m_n |= m_a;
+ if (m_micro & M_NATN) m_n |= (~m_a & 0xf);
+ if (m_micro & M_CKN) m_n |= m_cki_bus;
+ if (m_micro & M_MTN) m_n |= m_ram_in;
+
+ // P inputs
+ if (m_micro & M_CKP) m_p |= m_cki_bus;
+ if (m_micro & M_MTP) m_p |= m_ram_in;
+ if (m_micro & M_YTP) m_p |= m_y;
+ if (m_micro & M_DMTP) m_p |= m_dam_in;
+ if (m_micro & M_NDMTP) m_p |= (~m_dam_in & 0xf);
+
+ // carry input
+ if (m_micro & M_CIN) m_carry_in |= 1;
+ if (m_micro & M_SSS) m_carry_in |= m_eac;
+
+ break;
+
+ case 2:
+ {
+ // fetch: nothing
+
+ // execute: perform alu logic
+ // note: officially, only 1 alu operation is allowed per opcode
+ m_adder_out = m_p + m_n + m_carry_in;
+ int carry_out = m_adder_out >> 4 & 1;
+ int status = 1;
+ m_ram_out = -1;
+
+ if (m_micro & M_C8) status &= carry_out;
+ if (m_micro & M_NE) status &= (m_n != m_p); // COMP
+ if (m_micro & M_CKM) m_ram_out = m_cki_bus;
+
+ // special status circuit
+ if (m_micro & M_SSE)
+ {
+ m_eac = m_carry_out;
+ if (m_add)
+ m_eac |= carry_out;
+ }
+ m_carry_out = carry_out;
+
+ if (m_micro & M_STO || (m_micro & M_CME && m_eac == m_add))
+ m_ram_out = m_a;
+
+ // handle the other fixed opcodes here
+ if (m_fixed & F_SBIT) op_sbit();
+ if (m_fixed & F_RBIT) op_rbit();
+ if (m_fixed & F_SETR) op_setr();
+ if (m_fixed & F_RSTR) op_rstr();
+ if (m_fixed & F_TDO) op_tdo();
+ if (m_fixed & F_CLO) op_clo();
+ if (m_fixed & F_LDX) op_ldx();
+ if (m_fixed & F_COMX) op_comx();
+ if (m_fixed & F_COMX8) op_comx8();
+ if (m_fixed & F_LDP) op_ldp();
+ if (m_fixed & F_COMC) op_comc();
+ if (m_fixed & F_TPC) op_tpc();
+ if (m_fixed & F_OFF) op_off();
+ if (m_fixed & F_SEAC) op_seac();
+ if (m_fixed & F_REAC) op_reac();
+ if (m_fixed & F_SAL) op_sal();
+ if (m_fixed & F_SBL) op_sbl();
+ if (m_fixed & F_XDA) op_xda();
+
+ // after fixed opcode handling: store status, write ram
+ m_status = status;
+ if (m_ram_out != -1)
+ m_data->write_byte(m_ram_address, m_ram_out);
+
+ break;
+ }
+
+ case 3:
+ // fetch: update pc, ram address 1/2
+ // execute: register store 1/2
+ break;
+
+ case 4:
+ // execute: register store 2/2
+ if (m_micro & M_AUTA) m_a = m_adder_out & 0xf;
+ if (m_micro & M_AUTY) m_y = m_adder_out & 0xf;
+ if (m_micro & M_STSL) m_status_latch = m_status;
+
+ // fetch: update pc, ram address 2/2
+ read_opcode();
+ m_ram_address = m_x << 4 | m_y;
+ break;
+
+ case 5:
+ // fetch: instruction decode (handled above, before next_pc)
+ // execute: br/call 1/2
+ break;
+ }
+ m_subcycle = (m_subcycle + 1) % 6;
+ } while (m_icount > 0);
+}
diff --git a/src/devices/cpu/tms1000/tms1k_base.h b/src/devices/cpu/tms1000/tms1k_base.h
new file mode 100644
index 00000000000..9ad108b1dca
--- /dev/null
+++ b/src/devices/cpu/tms1000/tms1k_base.h
@@ -0,0 +1,299 @@
+// license:BSD-3-Clause
+// copyright-holders:Wilbert Pol, hap
+/*
+
+ TMS1000 family - base/shared
+
+ Don't include this file, include the specific device header instead,
+ for example tms1000.h
+
+*/
+
+#ifndef _TMS1KBASE_H_
+#define _TMS1KBASE_H_
+
+#include "emu.h"
+#include "machine/pla.h"
+
+
+// K input pins
+#define MCFG_TMS1XXX_READ_K_CB(_devcb) \
+ tms1k_base_device::set_read_k_callback(*device, DEVCB_##_devcb);
+
+// O/Segment output pins
+#define MCFG_TMS1XXX_WRITE_O_CB(_devcb) \
+ tms1k_base_device::set_write_o_callback(*device, DEVCB_##_devcb);
+
+// Use this if the output PLA is unknown:
+// If the microinstructions (or other) PLA is unknown, try using one from another romset.
+#define MCFG_TMS1XXX_OUTPUT_PLA(_pla) \
+ tms1k_base_device::set_output_pla(*device, _pla);
+
+// R output pins (also called D on some chips)
+#define MCFG_TMS1XXX_WRITE_R_CB(_devcb) \
+ tms1k_base_device::set_write_r_callback(*device, DEVCB_##_devcb);
+
+// OFF request on TMS0980 and up
+#define MCFG_TMS1XXX_POWER_OFF_CB(_devcb) \
+ tms1k_base_device::set_power_off_callback(*device, DEVCB_##_devcb);
+
+
+// pinout reference
+
+/*
+
+ ____ ____ ____ ____
+ R8 1 |* \_/ | 28 R7 R0 1 |* \_/ | 28 Vss
+ R9 2 | | 27 R6 R1 2 | | 27 OSC2
+ R10 3 | | 26 R5 R2 3 | | 26 OSC1
+ Vdd 4 | | 25 R4 R3 4 | | 25 O0
+ K1 5 | | 24 R3 R4 5 | | 24 O1
+ K2 6 | TMS1000 | 23 R2 R5 6 | | 23 O2
+ K4 7 | TMS1070 | 22 R1 R6 7 | TMS1400 | 22 O3
+ K8 8 | TMS1100 | 21 R0 R7 8 | | 21 O4
+ INIT 9 | TMS1170 | 20 Vss R8 9 | | 20 O5
+ O7 10 | | 19 OSC2 R9 10 | | 19 O6
+ O6 11 | | 18 OSC1 R10 11 | | 18 O7
+ O5 12 | | 17 O0 Vdd 12 | | 17 K8
+ O4 13 | | 16 O1 INIT 13 | | 16 K4
+ O3 14 |___________| 15 O2 K1 14 |___________| 15 K2
+
+
+ ____ ____
+ R2 1 |* \_/ | 28 R3
+ R1 2 | | 27 R4
+ R0 3 | | 26 R5
+ ? 4 | | 25 R6
+ Vdd 5 | | 24 R7
+ K3 6 | | 23 R8
+ K8 7 | TMS0980 | 22 ?
+ K4 8 | | 21 ?
+ K2 9 | | 20 Vss
+ K1 10 | | 19 ?
+ O7 11 | | 18 O0
+ O6 12 | | 17 O1
+ O5 13 | | 16 O2
+ O4 14 |___________| 15 O3
+
+ note: TMS0980 official pin names for R0-R8 is D9-D1, O0-O7 is S(A-G,DP)
+
+*/
+
+
+class tms1k_base_device : public cpu_device
+{
+public:
+ // construction/destruction
+ tms1k_base_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT8 o_pins, UINT8 r_pins, UINT8 pc_bits, UINT8 byte_bits, UINT8 x_bits, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data, const char *shortname, const char *source)
+ : cpu_device(mconfig, type, name, tag, owner, clock, shortname, source)
+ , m_program_config("program", ENDIANNESS_BIG, byte_bits > 8 ? 16 : 8, prgwidth, 0, program)
+ , m_data_config("data", ENDIANNESS_BIG, 8, datawidth, 0, data)
+ , m_mpla(*this, "mpla")
+ , m_ipla(*this, "ipla")
+ , m_opla(*this, "opla")
+ , m_spla(*this, "spla")
+ , m_o_pins(o_pins)
+ , m_r_pins(r_pins)
+ , m_pc_bits(pc_bits)
+ , m_byte_bits(byte_bits)
+ , m_x_bits(x_bits)
+ , m_output_pla_table(nullptr)
+ , m_read_k(*this)
+ , m_write_o(*this)
+ , m_write_r(*this)
+ , m_power_off(*this)
+ { }
+
+ // static configuration helpers
+ template<class _Object> static devcb_base &set_read_k_callback(device_t &device, _Object object) { return downcast<tms1k_base_device &>(device).m_read_k.set_callback(object); }
+ template<class _Object> static devcb_base &set_write_o_callback(device_t &device, _Object object) { return downcast<tms1k_base_device &>(device).m_write_o.set_callback(object); }
+ template<class _Object> static devcb_base &set_write_r_callback(device_t &device, _Object object) { return downcast<tms1k_base_device &>(device).m_write_r.set_callback(object); }
+ template<class _Object> static devcb_base &set_power_off_callback(device_t &device, _Object object) { return downcast<tms1k_base_device &>(device).m_power_off.set_callback(object); }
+ static void set_output_pla(device_t &device, const UINT16 *output_pla) { downcast<tms1k_base_device &>(device).m_output_pla_table = output_pla; }
+
+ // microinstructions
+ enum
+ {
+ M_15TN = (1<<0), /* 15 to -ALU */
+ M_ATN = (1<<1), /* ACC to -ALU */
+ M_AUTA = (1<<2), /* ALU to ACC */
+ M_AUTY = (1<<3), /* ALU to Y */
+ M_C8 = (1<<4), /* CARRY8 to STATUS */
+ M_CIN = (1<<5), /* Carry In to ALU */
+ M_CKM = (1<<6), /* CKB to MEM */
+ M_CKN = (1<<7), /* CKB to -ALU */
+ M_CKP = (1<<8), /* CKB to +ALU */
+ M_MTN = (1<<9), /* MEM to -ALU */
+ M_MTP = (1<<10), /* MEM to +ALU */
+ M_NATN = (1<<11), /* ~ACC to -ALU */
+ M_NE = (1<<12), /* COMP to STATUS */
+ M_STO = (1<<13), /* ACC to MEM */
+ M_STSL = (1<<14), /* STATUS to Status Latch */
+ M_YTP = (1<<15), /* Y to +ALU */
+
+ M_CME = (1<<16), /* Conditional Memory Enable */
+ M_DMTP = (1<<17), /* DAM to +ALU */
+ M_NDMTP = (1<<18), /* ~DAM to +ALU */
+ M_SSE = (1<<19), /* Special Status Enable */
+ M_SSS = (1<<20), /* Special Status Sample */
+
+ M_SETR = (1<<21), /* -> line #0d, F_SETR (TP0320 custom), */
+ M_RSTR = (1<<22), /* -> line #36, F_RSTR (TMS02x0 custom), */
+ M_UNK1 = (1<<23) /* -> line #37, F_???? (TMS0270 custom), */
+ };
+
+ // standard/fixed instructions - these are documented more in their specific handlers
+ enum
+ {
+ F_BR = (1<<0),
+ F_CALL = (1<<1),
+ F_CLO = (1<<2),
+ F_COMC = (1<<3),
+ F_COMX = (1<<4),
+ F_COMX8 = (1<<5),
+ F_LDP = (1<<6),
+ F_LDX = (1<<7),
+ F_RBIT = (1<<8),
+ F_RETN = (1<<9),
+ F_RSTR = (1<<10),
+ F_SBIT = (1<<11),
+ F_SETR = (1<<12),
+ F_TDO = (1<<13),
+ F_TPC = (1<<14),
+
+ F_OFF = (1<<15),
+ F_REAC = (1<<16),
+ F_SAL = (1<<17),
+ F_SBL = (1<<18),
+ F_SEAC = (1<<19),
+ F_XDA = (1<<20)
+ };
+
+protected:
+ // device-level overrides
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+ // device_execute_interface overrides
+ virtual UINT32 execute_min_cycles() const override { return 1; }
+ virtual UINT32 execute_max_cycles() const override { return 6; }
+ virtual UINT32 execute_input_lines() const override { return 1; }
+ virtual void execute_run() override;
+
+ // device_memory_interface overrides
+ virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const override { return(spacenum == AS_PROGRAM) ? &m_program_config : ((spacenum == AS_DATA) ? &m_data_config : nullptr); }
+
+ // device_disasm_interface overrides
+ virtual UINT32 disasm_min_opcode_bytes() const override { return 1; }
+ virtual UINT32 disasm_max_opcode_bytes() const override { return 1; }
+
+ // device_state_interface overrides
+ virtual void state_string_export(const device_state_entry &entry, std::string &str) const override;
+
+ void next_pc();
+
+ virtual void write_o_output(UINT8 index);
+ virtual UINT8 read_k_input();
+ virtual void set_cki_bus();
+ virtual void dynamic_output() { ; } // not used by default
+ virtual void read_opcode();
+
+ virtual void op_br();
+ virtual void op_call();
+ virtual void op_retn();
+
+ virtual void op_sbit();
+ virtual void op_rbit();
+ virtual void op_setr();
+ virtual void op_rstr();
+ virtual void op_tdo();
+ virtual void op_clo();
+ virtual void op_ldx();
+ virtual void op_comx();
+ virtual void op_comx8();
+ virtual void op_ldp();
+
+ virtual void op_comc();
+ virtual void op_tpc();
+ virtual void op_xda();
+ virtual void op_off();
+ virtual void op_seac();
+ virtual void op_reac();
+ virtual void op_sal();
+ virtual void op_sbl();
+
+ address_space_config m_program_config;
+ address_space_config m_data_config;
+
+ optional_device<pla_device> m_mpla;
+ optional_device<pla_device> m_ipla;
+ optional_device<pla_device> m_opla;
+ optional_device<pla_device> m_spla;
+
+ UINT8 m_pc; // 6 or 7-bit program counter
+ UINT32 m_sr; // 6 or 7-bit subroutine return register(s)
+ UINT8 m_pa; // 4-bit page address register
+ UINT8 m_pb; // 4-bit page buffer register
+ UINT16 m_ps; // 4-bit page subroutine register(s)
+ UINT8 m_a; // 4-bit accumulator
+ UINT8 m_x; // 2,3,or 4-bit RAM X register
+ UINT8 m_y; // 4-bit RAM Y register
+ UINT8 m_ca; // chapter address register
+ UINT8 m_cb; // chapter buffer register
+ UINT16 m_cs; // chapter subroutine register(s)
+ UINT16 m_r;
+ UINT16 m_o;
+ UINT8 m_cki_bus;
+ UINT8 m_c4;
+ UINT8 m_p; // 4-bit adder p(lus)-input
+ UINT8 m_n; // 4-bit adder n(egative)-input
+ UINT8 m_adder_out; // adder result
+ UINT8 m_carry_in; // adder carry-in bit
+ UINT8 m_carry_out; // adder carry-out bit
+ UINT8 m_status;
+ UINT8 m_status_latch;
+ UINT8 m_eac; // end around carry bit
+ UINT8 m_clatch; // call latch bit(s)
+ UINT8 m_add; // add latch bit
+ UINT8 m_bl; // branch latch bit
+
+ UINT8 m_ram_in;
+ UINT8 m_dam_in;
+ int m_ram_out; // signed!
+ UINT8 m_ram_address;
+ UINT16 m_rom_address;
+ UINT16 m_opcode;
+ UINT32 m_fixed;
+ UINT32 m_micro;
+ int m_subcycle;
+ int m_icount;
+
+ UINT8 m_o_pins; // how many O pins
+ UINT8 m_r_pins; // how many R pins
+ UINT8 m_pc_bits; // how many program counter bits
+ UINT8 m_byte_bits; // how many bits per 'byte'
+ UINT8 m_x_bits; // how many X register bits
+
+ address_space *m_program;
+ address_space *m_data;
+
+ const UINT16 *m_output_pla_table;
+ devcb_read8 m_read_k;
+ devcb_write16 m_write_o;
+ devcb_write16 m_write_r;
+ devcb_write_line m_power_off;
+
+ UINT32 m_o_mask;
+ UINT32 m_r_mask;
+ UINT32 m_k_mask;
+ UINT32 m_pc_mask;
+ UINT32 m_x_mask;
+
+ // lookup tables
+ std::vector<UINT32> m_fixed_decode;
+ std::vector<UINT32> m_micro_decode;
+ std::vector<UINT32> m_micro_direct;
+};
+
+
+#endif /* _TMS1KBASE_H_ */
diff --git a/src/devices/cpu/tms1000/tms1k_dasm.cpp b/src/devices/cpu/tms1000/tms1k_dasm.cpp
new file mode 100644
index 00000000000..054d4f09699
--- /dev/null
+++ b/src/devices/cpu/tms1000/tms1k_dasm.cpp
@@ -0,0 +1,281 @@
+// license:BSD-3-Clause
+// copyright-holders:Wilbert Pol, hap
+/*
+
+ TMS0980/TMS1000-family disassembler
+
+*/
+
+#include "emu.h"
+#include "debugger.h"
+#include "tms1k_base.h"
+
+
+enum e_mnemonics
+{
+ zILL = 0,
+ zA10AAC, zA6AAC, zA8AAC, zAC1AC, zACACC, zACNAA, zALEC, zALEM, zAMAAC, zBRANCH, zCALL, zCCLA,
+ zCLA, zCLO, zCOMC, zCOMX, zCOMX8, zCPAIZ, zCTMDYN, zDAN, zDMAN, zDMEA, zDNAA,
+ zDYN, zIA, zIMAC, zIYC, zKNEZ, zLDP, zLDX2, zLDX3, zLDX4, zMNEA, zMNEZ,
+ zNDMEA, zOFF, zRBIT, zREAC, zRETN, zRSTR, zSAL, zSAMAN, zSBIT,
+ zSBL, zSEAC, zSETR, zTAM, zTAMACS, zTAMDYN, zTAMIY, zTAMIYC, zTAMZA,
+ zTAY, zTBIT, zTCMIY, zTCY, zTDO, zTKA, zTKM, zTMA,
+ zTMY, zTYA, zXDA, zXMA, zYMCY, zYNEA, zYNEC
+};
+
+static const char *const s_mnemonic[] =
+{
+ "?",
+ "A10AAC", "A6AAC", "A8AAC", "AC1AC", "ACACC", "ACNAA", "ALEC", "ALEM", "AMAAC", "BRANCH", "CALL", "CCLA",
+ "CLA", "CLO", "COMC", "COMX", "COMX8", "CPAIZ", "CTMDYN", "DAN", "DMAN", "DMEA", "DNAA",
+ "DYN", "IA", "IMAC", "IYC", "KNEZ", "LDP", "LDX", "LDX", "LDX", "MNEA", "MNEZ",
+ "NDMEA", "OFF", "RBIT", "REAC", "RETN", "RSTR", "SAL", "SAMAN", "SBIT",
+ "SBL", "SEAC", "SETR", "TAM", "TAMACS", "TAMDYN", "TAMIY", "TAMIYC", "TAMZA",
+ "TAY", "TBIT", "TCMIY", "TCY", "TDO", "TKA", "TKM", "TMA",
+ "TMY", "TYA", "XDA", "XMA", "YMCY", "YNEA", "YNEC"
+};
+
+
+#define _OVER DASMFLAG_STEP_OVER
+#define _OUT DASMFLAG_STEP_OUT
+
+static const UINT32 s_flags[] =
+{
+ 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _OVER, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, _OUT, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0
+};
+
+
+enum e_addressing
+{
+ zB0 = 0, zI2, zI3, zI4, zB7
+};
+
+static const UINT8 s_addressing[] =
+{
+ zB0,
+ zB0, zB0, zB0, zI4, zI4, zI4, zI4, zB0, zB0, zB7, zB7, zB0,
+ zB0, zB0, zB0, zB0, zB0, zB0, zB0, zB0, zB0, zB0, zB0,
+ zB0, zB0, zB0, zB0, zB0, zI4, zI2, zI3, zI4, zB0, zB0,
+ zB0, zB0, zI2, zB0, zB0, zB0, zB0, zB0, zI2,
+ zB0, zB0, zB0, zB0, zI4, zB0, zB0, zB0, zB0,
+ zB0, zI2, zI4, zI4, zB0, zB0, zB0, zB0,
+ zB0, zB0, zB0, zB0, zI4, zB0, zI4
+};
+
+
+
+// opcode luts
+
+static const UINT8 tms1000_mnemonic[256] =
+{
+/* 0x00 */
+ zCOMX, zA8AAC, zYNEA, zTAM, zTAMZA, zA10AAC, zA6AAC, zDAN, zTKA, zKNEZ, zTDO, zCLO, zRSTR, zSETR, zIA, zRETN, // 0
+ zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, // 1
+ zTAMIY, zTMA, zTMY, zTYA, zTAY, zAMAAC, zMNEZ, zSAMAN, zIMAC, zALEM, zDMAN, zIYC, zDYN, zCPAIZ, zXMA, zCLA, // 2
+ zSBIT, zSBIT, zSBIT, zSBIT, zRBIT, zRBIT, zRBIT, zRBIT, zTBIT, zTBIT, zTBIT, zTBIT, zLDX2, zLDX2, zLDX2, zLDX2, // 3
+ zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, // 4
+ zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, // 5
+ zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, // 6
+ zALEC, zALEC, zALEC, zALEC, zALEC, zALEC, zALEC, zALEC, zALEC, zALEC, zALEC, zALEC, zALEC, zALEC, zALEC, zALEC, // 7
+/* 0x80 */
+ zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, // 8
+ zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, // 9
+ zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, // A
+ zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, // B
+ zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, // C
+ zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, // D
+ zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, // E
+ zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL // F
+/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
+};
+
+
+static const UINT8 tms1100_mnemonic[256] =
+{
+/* 0x00 */
+ zMNEA, zALEM, zYNEA, zXMA, zDYN, zIYC, zAMAAC, zDMAN, zTKA, zCOMX, zTDO, zCOMC, zRSTR, zSETR, zKNEZ, zRETN, // 0
+ zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, // 1
+ zTAY, zTMA, zTMY, zTYA, zTAMDYN, zTAMIYC, zTAMZA, zTAM, zLDX3, zLDX3, zLDX3, zLDX3, zLDX3, zLDX3, zLDX3, zLDX3, // 2
+ zSBIT, zSBIT, zSBIT, zSBIT, zRBIT, zRBIT, zRBIT, zRBIT, zTBIT, zTBIT, zTBIT, zTBIT, zSAMAN, zCPAIZ, zIMAC, zMNEZ, // 3
+ zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, // 4
+ zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, // 5
+ zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, // 6
+ zAC1AC, zAC1AC, zAC1AC, zAC1AC, zAC1AC, zAC1AC, zAC1AC, zAC1AC, zAC1AC, zAC1AC, zAC1AC, zAC1AC, zAC1AC, zAC1AC, zAC1AC, zCLA, // 7
+/* 0x80 */
+ zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, // 8
+ zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, // 9
+ zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, // A
+ zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, // B
+ zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, // C
+ zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, // D
+ zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, // E
+ zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL // F
+/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
+};
+
+
+static const UINT8 tms0980_mnemonic[512] =
+{
+/* 0x000 */
+ zCOMX, zALEM, zYNEA, zXMA, zDYN, zIYC, zCLA, zDMAN, zTKA, zMNEA, zTKM, 0, 0, zSETR, zKNEZ, 0, // 0
+ zDMEA, zDNAA, zCCLA, zNDMEA, 0, zAMAAC, 0, 0, zCTMDYN, zXDA, 0, 0, 0, 0, 0, 0, // 1
+ zTBIT, zTBIT, zTBIT, zTBIT, 0, 0, 0, 0, zTAY, zTMA, zTMY, zTYA, zTAMDYN, zTAMIYC, zTAMZA, zTAM, // 2
+ zSAMAN, zCPAIZ, zIMAC, zMNEZ, 0, 0, 0, 0, zTCY, zYNEC, zTCMIY, zACACC, zACNAA, zTAMACS, zALEC, zYMCY, // 3
+ zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, // 4
+ zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, // 5
+ zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, // 6
+ zACACC, zACACC, zACACC, zACACC, zACACC, zACACC, zACACC, zACACC, zACACC, zACACC, zACACC, zACACC, zACACC, zACACC, zACACC, zACACC, // 7
+/* 0x080 */
+ zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, // 8
+ zLDX4, zLDX4, zLDX4, zLDX4, zLDX4, zLDX4, zLDX4, zLDX4, zLDX4, zLDX4, zLDX4, zLDX4, zLDX4, zLDX4, zLDX4, zLDX4, // 9
+ zSBIT, zSBIT, zSBIT, zSBIT, zRBIT, zRBIT, zRBIT, zRBIT, 0, 0, 0, 0, 0, 0, 0, 0, // A
+ zTDO, zSAL, zCOMX8, zSBL, zREAC, zSEAC, zOFF, 0, 0, 0, 0, 0, 0, 0, 0, zRETN, // B
+ zACNAA, zACNAA, zACNAA, zACNAA, zACNAA, zACNAA, zACNAA, zACNAA, zACNAA, zACNAA, zACNAA, zACNAA, zACNAA, zACNAA, zACNAA, zACNAA, // C
+ zTAMACS, zTAMACS, zTAMACS, zTAMACS, zTAMACS, zTAMACS, zTAMACS, zTAMACS, zTAMACS, zTAMACS, zTAMACS, zTAMACS, zTAMACS, zTAMACS, zTAMACS, zTAMACS, // D
+ zALEC, zALEC, zALEC, zALEC, zALEC, zALEC, zALEC, zALEC, zALEC, zALEC, zALEC, zALEC, zALEC, zALEC, zALEC, zALEC, // E
+ zYMCY, zYMCY, zYMCY, zYMCY, zYMCY, zYMCY, zYMCY, zYMCY, zYMCY, zYMCY, zYMCY, zYMCY, zYMCY, zYMCY, zYMCY, zYMCY, // F
+/* 0x100 */
+ zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, // 0
+ zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, // 1
+ zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, // 2
+ zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, // 3
+ zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, // 4
+ zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, // 5
+ zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, // 6
+ zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, // 7
+/* 0x180 */
+ zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, // 8
+ zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, // 9
+ zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, // A
+ zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, // B
+ zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, // C
+ zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, // D
+ zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, // E
+ zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL // F
+/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
+};
+
+
+static const UINT8 tp0320_mnemonic[512] =
+{
+/* 0x000 */
+ 0, zALEM, zYNEA, zXMA, zDYN, zIYC, zCLA, zDMAN, zTKA, zMNEA, zTKM, 0, 0, zSETR, zKNEZ, 0, // 0
+ zDMEA, zDNAA, zCCLA, zNDMEA, 0, zAMAAC, 0, 0, zCTMDYN, zXDA, 0, 0, 0, 0, 0, 0, // 1
+ zTBIT, zTBIT, zTBIT, zTBIT, 0, 0, 0, 0, zTAY, zTMA, zTMY, zTYA, zTAMDYN, zTAMIYC, zTAMZA, zTAM, // 2
+ zSAMAN, zCPAIZ, zIMAC, zMNEZ, 0, 0, zRSTR, zYMCY, zTCY, zYNEC, zTCMIY, zACACC, zACNAA, zTAMACS, zALEC, 0, // 3
+ zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, zTCY, // 4
+ zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, zYNEC, // 5
+ zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, zTCMIY, // 6
+ zACACC, zACACC, zACACC, zACACC, zACACC, zACACC, zACACC, zACACC, zACACC, zACACC, zACACC, zACACC, zACACC, zACACC, zACACC, zACACC, // 7
+/* 0x080 */
+ zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, zLDP, // 8
+ zLDX4, zLDX4, zLDX4, zLDX4, zLDX4, zLDX4, zLDX4, zLDX4, zLDX4, zLDX4, zLDX4, zLDX4, zLDX4, zLDX4, zLDX4, zLDX4, // 9
+ zSBIT, zSBIT, zSBIT, zSBIT, zRBIT, zRBIT, zRBIT, zRBIT, 0, 0, 0, 0, 0, 0, 0, 0, // A
+ zTDO, zSAL, zCOMX8, zSBL, zREAC, zSEAC, zOFF, 0, 0, 0, 0, 0, 0, 0, 0, zRETN, // B
+ zACNAA, zACNAA, zACNAA, zACNAA, zACNAA, zACNAA, zACNAA, zACNAA, zACNAA, zACNAA, zACNAA, zACNAA, zACNAA, zACNAA, zACNAA, zACNAA, // C
+ zTAMACS, zTAMACS, zTAMACS, zTAMACS, zTAMACS, zTAMACS, zTAMACS, zTAMACS, zTAMACS, zTAMACS, zTAMACS, zTAMACS, zTAMACS, zTAMACS, zTAMACS, zTAMACS, // D
+ zALEC, zALEC, zALEC, zALEC, zALEC, zALEC, zALEC, zALEC, zALEC, zALEC, zALEC, zALEC, zALEC, zALEC, zALEC, zALEC, // E
+ zYMCY, zYMCY, zYMCY, zYMCY, zYMCY, zYMCY, zYMCY, zYMCY, zYMCY, zYMCY, zYMCY, zYMCY, zYMCY, zYMCY, zYMCY, zYMCY, // F
+/* 0x100 */
+ zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, // 0
+ zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, // 1
+ zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, // 2
+ zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, // 3
+ zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, // 4
+ zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, // 5
+ zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, // 6
+ zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, zBRANCH, // 7
+/* 0x180 */
+ zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, // 8
+ zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, // 9
+ zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, // A
+ zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, // B
+ zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, // C
+ zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, // D
+ zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, // E
+ zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL, zCALL // F
+/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
+};
+
+
+
+// disasm
+
+static const UINT8 i2_value[4] =
+{
+ 0, 2, 1, 3
+};
+
+static const UINT8 i3_value[8] =
+{
+ 0, 4, 2, 6, 1, 5, 3, 7
+};
+
+static const UINT8 i4_value[16] =
+{
+ 0x0, 0x8, 0x4, 0xc, 0x2, 0xa, 0x6, 0xe, 0x1, 0x9, 0x5, 0xd, 0x3, 0xb, 0x7, 0xf
+};
+
+static offs_t tms1k_dasm(char *dst, const UINT8 *oprom, const UINT8 *lut_mnemonic, UINT16 opcode_mask)
+{
+ // get current opcode
+ int pos = 0;
+ UINT16 op = oprom[pos++];
+ if (opcode_mask & 0x100)
+ op = (op << 8 | oprom[pos++]) & 0x1ff;
+
+ // convert to mnemonic/param
+ UINT16 instr = lut_mnemonic[op];
+ dst += sprintf(dst, "%-8s ", s_mnemonic[instr]);
+
+ switch( s_addressing[instr] )
+ {
+ case zI2:
+ dst += sprintf(dst, "%d", i2_value[op & 0x03]);
+ break;
+ case zI3:
+ dst += sprintf(dst, "%d", i3_value[op & 0x07]);
+ break;
+ case zI4:
+ dst += sprintf(dst, "%d", i4_value[op & 0x0f]);
+ break;
+ case zB7:
+ if (opcode_mask & 0x100)
+ dst += sprintf(dst, "$%02X", op << 1 & 0xfe);
+ else
+ dst += sprintf(dst, "$%02X", op & 0x3f);
+ break;
+ default:
+ break;
+ }
+
+ return pos | s_flags[instr] | DASMFLAG_SUPPORTED;
+}
+
+
+CPU_DISASSEMBLE(tms1000)
+{
+ return tms1k_dasm(buffer, oprom, tms1000_mnemonic, 0xff);
+}
+
+CPU_DISASSEMBLE(tms1100)
+{
+ return tms1k_dasm(buffer, oprom, tms1100_mnemonic, 0xff);
+}
+
+CPU_DISASSEMBLE(tms0980)
+{
+ return tms1k_dasm(buffer, oprom, tms0980_mnemonic, 0x1ff);
+}
+
+CPU_DISASSEMBLE(tp0320)
+{
+ return tms1k_dasm(buffer, oprom, tp0320_mnemonic, 0x1ff);
+}
diff --git a/src/devices/cpu/tms1000/tp0320.cpp b/src/devices/cpu/tms1000/tp0320.cpp
new file mode 100644
index 00000000000..72dc85ef331
--- /dev/null
+++ b/src/devices/cpu/tms1000/tp0320.cpp
@@ -0,0 +1,107 @@
+// license:BSD-3-Clause
+// copyright-holders:hap
+/*
+
+ TMS1000 family - TP0320
+
+ TODO:
+ - lots
+
+*/
+
+#include "tp0320.h"
+#include "debugger.h"
+
+// TP0320 is TI's first CMOS MCU with integrated LCD controller, the die is still very similar to TMS0980
+// - 2048x9bit ROM, same as on TMS0980 with different row-select
+// - 192x4bit RAM array at the bottom-left (set up as 16x12x4)
+// - 16x4bit LCD RAM, above main RAM array
+// - main instructions PLAs at the same position as TMS0980, fixed opcodes:
+// * LDP, RETN, OFF, bb?, be?, b9?, ba?, RBIT, SBIT, COMX8, bc?, LDX, XDA, TDO, SEAC, REAC, SAL, SBL
+// - 64-term microinstructions PLA between the RAM and ROM, similar to TMS0980,
+// plus separate lines for custom opcode handling like TMS0270, used for SETR and RSTR
+// - 24-term output PLA above LCD RAM
+const device_type TP0320 = &device_creator<tp0320_cpu_device>; // 28-pin SDIP, ..
+
+
+// internal memory maps
+static ADDRESS_MAP_START(program_11bit_9, AS_PROGRAM, 16, tms1k_base_device)
+ AM_RANGE(0x000, 0xfff) AM_ROM
+ADDRESS_MAP_END
+
+static ADDRESS_MAP_START(data_192x4, AS_DATA, 8, tms1k_base_device)
+ AM_RANGE(0x00, 0x7f) AM_RAM
+ AM_RANGE(0x80, 0xbf) AM_RAM AM_MIRROR(0x40) // DAM
+ADDRESS_MAP_END
+
+
+// device definitions
+tp0320_cpu_device::tp0320_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : tms0980_cpu_device(mconfig, TP0320, "TP0320", tag, owner, clock, 7 /* o pins */, 10 /* r pins */, 7 /* pc bits */, 9 /* byte width */, 4 /* x width */, 12 /* prg width */, ADDRESS_MAP_NAME(program_11bit_9), 8 /* data width */, ADDRESS_MAP_NAME(data_192x4), "tp0320", __FILE__)
+{ }
+
+
+// machine configs
+static MACHINE_CONFIG_FRAGMENT(tp0320)
+
+ // main opcodes PLA(partial), microinstructions PLA
+ MCFG_PLA_ADD("ipla", 9, 6, 8)
+ MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
+ MCFG_PLA_ADD("mpla", 6, 22, 64)
+ MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
+MACHINE_CONFIG_END
+
+machine_config_constructor tp0320_cpu_device::device_mconfig_additions() const
+{
+ return MACHINE_CONFIG_NAME(tp0320);
+}
+
+
+// disasm
+offs_t tp0320_cpu_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options)
+{
+ extern CPU_DISASSEMBLE(tp0320);
+ return CPU_DISASSEMBLE_NAME(tp0320)(this, buffer, pc, oprom, opram, options);
+}
+
+
+// device_reset
+UINT32 tp0320_cpu_device::decode_micro(UINT8 sel)
+{
+ UINT32 decode = 0;
+
+ sel = BITSWAP8(sel,7,6,0,1,2,3,4,5); // lines are reversed
+ UINT32 mask = m_mpla->read(sel);
+ mask ^= 0x0bff0; // invert active-negative
+
+ // _____ _______ ______ _____ _____ ______ _____ _____ ______ _____ _____
+ const UINT32 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++)
+ if (mask & (1 << bit))
+ decode |= md[bit];
+
+ return decode;
+}
+
+void tp0320_cpu_device::device_reset()
+{
+ // common reset
+ tms0980_cpu_device::device_reset();
+
+ // fixed instructionset isn't fully understood yet
+ m_fixed_decode[0x19] = F_XDA;
+ m_fixed_decode[0xb0] = F_TDO;
+ m_fixed_decode[0xb1] = F_SAL;
+ m_fixed_decode[0xb2] = F_COMX8;
+ m_fixed_decode[0xb3] = F_SBL;
+ m_fixed_decode[0xb4] = F_REAC;
+ m_fixed_decode[0xb5] = F_SEAC;
+ m_fixed_decode[0xb6] = F_OFF;
+ m_fixed_decode[0xbf] = F_RETN;
+
+ for (int i = 0x80; i < 0x90; i++) m_fixed_decode[i] = F_LDP;
+ for (int i = 0x90; i < 0xa0; i++) m_fixed_decode[i] = F_LDX;
+ for (int i = 0xa0; i < 0xa4; i++) m_fixed_decode[i] = F_SBIT;
+ for (int i = 0xa4; i < 0xa8; i++) m_fixed_decode[i] = F_RBIT;
+}
diff --git a/src/devices/cpu/tms1000/tp0320.h b/src/devices/cpu/tms1000/tp0320.h
new file mode 100644
index 00000000000..517b748927f
--- /dev/null
+++ b/src/devices/cpu/tms1000/tp0320.h
@@ -0,0 +1,35 @@
+// license:BSD-3-Clause
+// copyright-holders:hap
+/*
+
+ TMS1000 family - TP0320
+
+*/
+
+#ifndef _TP0320_H_
+#define _TP0320_H_
+
+#include "tms0980.h"
+
+
+class tp0320_cpu_device : public tms0980_cpu_device
+{
+public:
+ tp0320_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+protected:
+ // overrides
+ //virtual void device_start() override;
+
+ virtual UINT32 decode_fixed(UINT16 op) override { return 0; } // not yet
+ virtual UINT32 decode_micro(UINT8 sel) override;
+ virtual void device_reset() override;
+ virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options) override;
+
+ virtual machine_config_constructor device_mconfig_additions() const override;
+};
+
+
+extern const device_type TP0320;
+
+#endif /* _TP0320_H_ */
diff --git a/src/devices/imagedev/diablo.cpp b/src/devices/imagedev/diablo.cpp
index 6ba6aad5cf2..ba43f09efee 100644
--- a/src/devices/imagedev/diablo.cpp
+++ b/src/devices/imagedev/diablo.cpp
@@ -171,8 +171,8 @@ static chd_error open_disk_diff(emu_options &options, const char *name, chd_file
/* try to open the diff */
//printf("Opening differencing image file: %s\n", fname.c_str());
emu_file diff_file(options.diff_directory(), OPEN_FLAG_READ | OPEN_FLAG_WRITE);
- file_error filerr = diff_file.open(fname.c_str());
- if (filerr == FILERR_NONE)
+ osd_file::error filerr = diff_file.open(fname.c_str());
+ if (filerr == osd_file::error::NONE)
{
std::string fullpath(diff_file.fullpath());
diff_file.close();
@@ -185,7 +185,7 @@ static chd_error open_disk_diff(emu_options &options, const char *name, chd_file
//printf("Creating differencing image: %s\n", fname.c_str());
diff_file.set_openflags(OPEN_FLAG_READ | OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
filerr = diff_file.open(fname.c_str());
- if (filerr == FILERR_NONE)
+ if (filerr == osd_file::error::NONE)
{
std::string fullpath(diff_file.fullpath());
diff_file.close();
diff --git a/src/devices/imagedev/floppy.cpp b/src/devices/imagedev/floppy.cpp
index c4269c944ef..345d6bce3cd 100644
--- a/src/devices/imagedev/floppy.cpp
+++ b/src/devices/imagedev/floppy.cpp
@@ -295,9 +295,9 @@ void floppy_image_device::commit_image()
io.procs = &image_ioprocs;
io.filler = 0xff;
- file_error err = image_core_file().truncate(0);
- if (err != 0)
- popmessage("Error, unable to truncate image: %d", err);
+ osd_file::error err = image_core_file().truncate(0);
+ if (err != osd_file::error::NONE)
+ popmessage("Error, unable to truncate image: %d", int(err));
output_format->save(&io, image);
}
@@ -365,8 +365,8 @@ floppy_image_format_t *floppy_image_device::identify(std::string filename)
util::core_file::ptr fd;
std::string revised_path;
- file_error err = zippath_fopen(filename.c_str(), OPEN_FLAG_READ, fd, revised_path);
- if(err) {
+ osd_file::error err = util::zippath_fopen(filename.c_str(), OPEN_FLAG_READ, fd, revised_path);
+ if(err != osd_file::error::NONE) {
seterror(IMAGE_ERROR_INVALIDIMAGE, "Unable to open the image file");
return nullptr;
}
@@ -1000,12 +1000,12 @@ void ui_menu_control_floppy_image::hook_load(std::string filename, bool softlist
bool can_in_place = input_format->supports_save();
if(can_in_place) {
- file_error filerr;
+ osd_file::error filerr;
std::string tmp_path;
util::core_file::ptr tmp_file;
/* attempt to open the file for writing but *without* create */
- filerr = zippath_fopen(filename.c_str(), OPEN_FLAG_READ | OPEN_FLAG_WRITE, tmp_file, tmp_path);
- if(!filerr)
+ filerr = util::zippath_fopen(filename.c_str(), OPEN_FLAG_READ | OPEN_FLAG_WRITE, tmp_file, tmp_path);
+ if(filerr == osd_file::error::NONE)
tmp_file.reset();
else
can_in_place = false;
@@ -1048,7 +1048,7 @@ void ui_menu_control_floppy_image::handle()
state = START_FILE;
handle();
} else {
- zippath_combine(output_filename, current_directory.c_str(), current_file.c_str());
+ util::zippath_combine(output_filename, current_directory.c_str(), current_file.c_str());
output_format = format_array[submenu_result];
do_load_create();
ui_menu::stack_pop(machine());
diff --git a/src/devices/imagedev/harddriv.cpp b/src/devices/imagedev/harddriv.cpp
index d07852e166f..ff058f837f7 100644
--- a/src/devices/imagedev/harddriv.cpp
+++ b/src/devices/imagedev/harddriv.cpp
@@ -195,8 +195,8 @@ static chd_error open_disk_diff(emu_options &options, const char *name, chd_file
/* try to open the diff */
//printf("Opening differencing image file: %s\n", fname.c_str());
emu_file diff_file(options.diff_directory(), OPEN_FLAG_READ | OPEN_FLAG_WRITE);
- file_error filerr = diff_file.open(fname.c_str());
- if (filerr == FILERR_NONE)
+ osd_file::error filerr = diff_file.open(fname.c_str());
+ if (filerr == osd_file::error::NONE)
{
std::string fullpath(diff_file.fullpath());
diff_file.close();
@@ -209,7 +209,7 @@ static chd_error open_disk_diff(emu_options &options, const char *name, chd_file
//printf("Creating differencing image: %s\n", fname.c_str());
diff_file.set_openflags(OPEN_FLAG_READ | OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
filerr = diff_file.open(fname.c_str());
- if (filerr == FILERR_NONE)
+ if (filerr == osd_file::error::NONE)
{
std::string fullpath(diff_file.fullpath());
diff_file.close();
diff --git a/src/devices/machine/atapicdr.cpp b/src/devices/machine/atapicdr.cpp
index 151d8d1bb10..13fd79570dd 100644
--- a/src/devices/machine/atapicdr.cpp
+++ b/src/devices/machine/atapicdr.cpp
@@ -72,11 +72,15 @@ void atapi_cdrom_device::device_start()
m_identify_buffer[ 49 ] = 0x0600; // Word 49=Capabilities, IORDY may be disabled (bit_10), LBA Supported mandatory (bit_9)
- m_media_change = true;
-
atapi_hle_device::device_start();
}
+void atapi_cdrom_device::device_reset()
+{
+ atapi_hle_device::device_reset();
+ m_media_change = true;
+}
+
void atapi_cdrom_device::process_buffer()
{
if(m_cdrom != m_image->get_cdrom_file())
@@ -130,10 +134,10 @@ void atapi_cdrom_device::ExecCommand()
}
break;
case T10SPC_CMD_INQUIRY:
+ break;
case T10SPC_CMD_REQUEST_SENSE:
+ m_media_change = false;
break;
}
t10mmc::ExecCommand();
- if((command[0] == T10SPC_CMD_REQUEST_SENSE) && m_media_change)
- m_media_change = false;
}
diff --git a/src/devices/machine/atapicdr.h b/src/devices/machine/atapicdr.h
index 2c310113c5c..dc5220c000d 100644
--- a/src/devices/machine/atapicdr.h
+++ b/src/devices/machine/atapicdr.h
@@ -28,6 +28,7 @@ public:
protected:
// device-level overrides
virtual void device_start() override;
+ virtual void device_reset() override;
virtual machine_config_constructor device_mconfig_additions() const override;
virtual void perform_diagnostic() override;
diff --git a/src/devices/machine/gt64xxx.cpp b/src/devices/machine/gt64xxx.cpp
new file mode 100644
index 00000000000..1b4f0a642ef
--- /dev/null
+++ b/src/devices/machine/gt64xxx.cpp
@@ -0,0 +1,600 @@
+// license:BSD-3-Clause
+// copyright-holders: Aaron Giles, Ted Green
+#include "gt64xxx.h"
+
+/*************************************
+ *
+ * Debugging constants
+ *
+ *************************************/
+#define LOG_GALILEO (0)
+#define LOG_REG (0)
+#define LOG_TIMERS (0)
+#define LOG_DMA (0)
+
+const device_type GT64XXX = &device_creator<gt64xxx_device>;
+
+DEVICE_ADDRESS_MAP_START(config_map, 32, gt64xxx_device)
+ AM_INHERIT_FROM(pci_device::config_map)
+ADDRESS_MAP_END
+
+// cpu i/f map
+DEVICE_ADDRESS_MAP_START(cpu_map, 32, gt64xxx_device)
+ AM_RANGE(0x00000000, 0x00000cff) AM_READWRITE( cpu_if_r, cpu_if_w)
+ADDRESS_MAP_END
+
+gt64xxx_device::gt64xxx_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : pci_host_device(mconfig, GT64XXX, "Galileo GT-64XXX System Controller", tag, owner, clock, "gt64xxx", __FILE__),
+ m_be(0), m_autoconfig(0), m_irq_num(-1),
+ m_mem_config("memory_space", ENDIANNESS_LITTLE, 32, 32),
+ m_io_config("io_space", ENDIANNESS_LITTLE, 32, 32)
+{
+}
+
+const address_space_config *gt64xxx_device::memory_space_config(address_spacenum spacenum) const
+{
+ return (spacenum == AS_PROGRAM) ? pci_bridge_device::memory_space_config(spacenum) : (spacenum == AS_DATA) ? &m_mem_config : (spacenum == AS_IO) ? &m_io_config : NULL;
+}
+
+void gt64xxx_device::device_start()
+{
+ pci_host_device::device_start();
+ m_cpu = machine().device<mips3_device>(cpu_tag);
+ m_cpu_space = &m_cpu->space(AS_PROGRAM);
+ memory_space = &space(AS_DATA);
+ io_space = &space(AS_IO);
+
+ memory_window_start = 0;
+ memory_window_end = 0xffffffff;
+ memory_offset = 0;
+ io_window_start = 0;
+ io_window_end = 0xffffffff;
+ io_offset = 0x00000000;
+ status = 0x0;
+
+ // ROM size = 4 MB
+ m_cpu_space->install_rom (0x1fc00000, 0x1fffffff, m_region->base());
+
+ // MIPS drc
+ m_cpu->add_fastram(0x1fc00000, 0x1fffffff, TRUE, m_region->base());
+}
+
+void gt64xxx_device::device_reset()
+{
+ pci_device::device_reset();
+
+ // Configuration register defaults
+ m_reg[GREG_CPU_CONFIG] = m_be ? 0 : (1<<12);
+ m_reg[GREG_RAS_1_0_LO] = 0x0;
+ m_reg[GREG_RAS_1_0_HI] = 0x7;
+ m_reg[GREG_RAS_3_2_LO] = 0x8;
+ m_reg[GREG_RAS_3_2_HI] = 0xf;
+ m_reg[GREG_CS_2_0_LO] = 0xe0;
+ m_reg[GREG_CS_2_0_HI] = 0x70;
+ m_reg[GREG_CS_3_BOOT_LO] = 0xf8;
+ m_reg[GREG_CS_3_BOOT_HI] = 0x7f;
+ m_reg[GREG_PCI_IO_LO] = 0x80;
+ m_reg[GREG_PCI_IO_HI] = 0xf;
+ m_reg[GREG_PCI_MEM0_LO] = 0x90;
+ m_reg[GREG_PCI_MEM0_HI] = 0x1f;
+ m_reg[GREG_INTERNAL_SPACE] = 0xa0;
+ m_reg[GREG_PCI_MEM1_LO] = 0x790;
+ m_reg[GREG_PCI_MEM1_HI] = 0x1f;
+
+ m_reg[GREG_RAS0_LO] = 0x0;
+ m_reg[GREG_RAS0_HI] = 0x7;
+ m_reg[GREG_RAS1_LO] = 0x8;
+ m_reg[GREG_RAS1_HI] = 0xf;
+ m_reg[GREG_RAS2_LO] = 0x10;
+ m_reg[GREG_RAS2_HI] = 0x17;
+ m_reg[GREG_RAS3_LO] = 0x18;
+ m_reg[GREG_RAS3_HI] = 0x1f;
+ m_reg[GREG_CS0_LO] = 0xc0;
+ m_reg[GREG_CS0_HI] = 0xc7;
+ m_reg[GREG_CS1_LO] = 0xc8;
+ m_reg[GREG_CS1_HI] = 0xcf;
+ m_reg[GREG_CS2_LO] = 0xd0;
+ m_reg[GREG_CS2_HI] = 0xdf;
+ m_reg[GREG_CS3_LO] = 0xf0;
+ m_reg[GREG_CS3_HI] = 0xfb;
+ m_reg[GREG_CSBOOT_LO] = 0xfc;
+ m_reg[GREG_CSBOOT_HI] = 0xff;
+
+ m_reg[GREG_PCI_COMMAND] = m_be ? 0 : 1;
+
+ map_cpu_space();
+ regenerate_config_mapping();
+}
+
+void gt64xxx_device::map_cpu_space()
+{
+ UINT32 winStart, winEnd;
+
+ // ROM region starts at 0x1fc00000
+ m_cpu_space->unmap_readwrite(0x00000000, 0x1fbfffff);
+ m_cpu_space->unmap_readwrite(0x20000000, 0xffffffff);
+
+ // Clear fastram regions in cpu after rom
+ m_cpu->clear_fastram(1);
+
+ // CPU Regs
+ winStart = m_reg[GREG_INTERNAL_SPACE]<<21;
+ winEnd = winStart + sizeof(m_reg) - 1;
+ m_cpu_space->install_device(winStart, winEnd, *static_cast<gt64xxx_device *>(this), &gt64xxx_device::cpu_map);
+ if (LOG_GALILEO)
+ logerror("%s: map_cpu_space cpu_reg start: %08X end: %08X\n", tag(), winStart, winEnd);
+
+ // Ras0
+ winStart = (m_reg[GREG_RAS_1_0_LO]<<21) | (m_reg[GREG_RAS0_LO]<<20);
+ winEnd = (m_reg[GREG_RAS_1_0_LO]<<21) | (m_reg[GREG_RAS0_HI]<<20) | 0xfffff;
+ m_ram[0].resize((winEnd+1-winStart)/4);
+ m_cpu_space->install_ram(winStart, winEnd, &m_ram[0][0]);
+ m_cpu->add_fastram(winStart, m_ram[0].size()*sizeof(m_ram[0][0]), FALSE, &m_ram[0][0]);
+ if (LOG_GALILEO)
+ logerror("%s: map_cpu_space ras0 start: %08X end: %08X\n", tag(), winStart, winEnd);
+
+ // PCI IO Window
+ winStart = m_reg[GREG_PCI_IO_LO]<<21;
+ winEnd = (m_reg[GREG_PCI_IO_LO]<<21) | (m_reg[GREG_PCI_IO_HI]<<21) | 0x1fffff;
+ m_cpu_space->install_read_handler(winStart, winEnd, 0, 0, read32_delegate(FUNC(gt64xxx_device::master_io_r), this));
+ m_cpu_space->install_write_handler(winStart, winEnd, 0, 0, write32_delegate(FUNC(gt64xxx_device::master_io_w), this));
+ if (LOG_GALILEO)
+ logerror("%s: map_cpu_space pci_io start: %08X end: %08X\n", tag(), winStart, winEnd);
+
+ // PCI MEM0 Window
+ winStart = m_reg[GREG_PCI_MEM0_LO]<<21;
+ winEnd = (m_reg[GREG_PCI_MEM0_LO]<<21) | (m_reg[GREG_PCI_MEM0_HI]<<21) | 0x1fffff;
+ m_cpu_space->install_read_handler(winStart, winEnd, 0, 0, read32_delegate(FUNC(gt64xxx_device::master_mem0_r), this));
+ m_cpu_space->install_write_handler(winStart, winEnd, 0, 0, write32_delegate(FUNC(gt64xxx_device::master_mem0_w), this));
+ if (LOG_GALILEO)
+ logerror("%s: map_cpu_space pci_mem0 start: %08X end: %08X\n", tag(), winStart, winEnd);
+
+ // PCI MEM1 Window
+ winStart = m_reg[GREG_PCI_MEM1_LO]<<21;
+ winEnd = (m_reg[GREG_PCI_MEM1_LO]<<21) | (m_reg[GREG_PCI_MEM1_HI]<<21) | 0x1fffff;
+ m_cpu_space->install_read_handler(winStart, winEnd, 0, 0, read32_delegate(FUNC(gt64xxx_device::master_mem1_r), this));
+ m_cpu_space->install_write_handler(winStart, winEnd, 0, 0, write32_delegate(FUNC(gt64xxx_device::master_mem1_w), this));
+ if (LOG_GALILEO)
+ logerror("%s: map_cpu_space pci_mem1 start: %08X end: %08X\n", tag(), winStart, winEnd);
+
+}
+
+void gt64xxx_device::map_extra(UINT64 memory_window_start, UINT64 memory_window_end, UINT64 memory_offset, address_space *memory_space,
+ UINT64 io_window_start, UINT64 io_window_end, UINT64 io_offset, address_space *io_space)
+{
+ /*
+ UINT32 winStart, winEnd, winSize;
+
+ // PCI Target Window 1
+ if (m_cpu_regs[NREG_PCITW1]&0x1000) {
+ winStart = m_cpu_regs[NREG_PCITW1]&0xffe00000;
+ winEnd = winStart | (~(0xf0000000 | (((m_cpu_regs[NREG_PCITW1]>>13)&0x7f)<<21)));
+ winSize = winEnd - winStart + 1;
+ memory_space->install_read_handler(winStart, winEnd, 0, 0, read32_delegate(FUNC(gt64xxx_device::target1_r), this));
+ memory_space->install_write_handler(winStart, winEnd, 0, 0, write32_delegate(FUNC(gt64xxx_device::target1_w), this));
+ if (LOG_GALILEO)
+ logerror("%s: map_extra Target Window 1 start=%08X end=%08X size=%08X laddr=%08X\n", tag(), winStart, winEnd, winSize, m_target1_laddr);
+ }
+ */
+}
+
+void gt64xxx_device::reset_all_mappings()
+{
+ pci_device::reset_all_mappings();
+}
+
+// PCI bus control
+READ32_MEMBER (gt64xxx_device::pci_config_r)
+{
+ UINT32 result = 0;
+ if (LOG_GALILEO)
+ logerror("%06X:galileo pci_config_r from offset %02X = %08X & %08X\n", space.device().safe_pc(), offset*4, result, mem_mask);
+ return result;
+}
+WRITE32_MEMBER (gt64xxx_device::pci_config_w)
+{
+ if (LOG_GALILEO)
+ logerror("%06X:galileo pci_config_w to offset %02X = %08X & %08X\n", space.device().safe_pc(), offset*4, data, mem_mask);
+}
+// PCI Master Window 0
+READ32_MEMBER (gt64xxx_device::master_mem0_r)
+{
+ UINT32 result = this->space(AS_DATA).read_dword((m_reg[GREG_PCI_MEM0_LO]<<21) | (offset*4), mem_mask);
+ if (LOG_GALILEO)
+ logerror("%06X:galileo pci mem0 read from offset %08X = %08X & %08X\n", space.device().safe_pc(), (m_reg[GREG_PCI_MEM0_LO]<<21) | (offset*4), result, mem_mask);
+ return result;
+}
+WRITE32_MEMBER (gt64xxx_device::master_mem0_w)
+{
+ this->space(AS_DATA).write_dword((m_reg[GREG_PCI_MEM0_LO]<<21) | (offset*4), data, mem_mask);
+ if (LOG_GALILEO)
+ logerror("%06X:galileo pci mem0 write to offset %08X = %08X & %08X\n", space.device().safe_pc(), (m_reg[GREG_PCI_MEM0_LO]<<21) | (offset*4), data, mem_mask);
+}
+
+// PCI Master Window 1
+READ32_MEMBER (gt64xxx_device::master_mem1_r)
+{
+ UINT32 result = this->space(AS_DATA).read_dword((m_reg[GREG_PCI_MEM1_LO]<<21) | (offset*4), mem_mask);
+ if (LOG_GALILEO)
+ logerror("%06X:galileo pci mem1 read from offset %08X = %08X & %08X\n", space.device().safe_pc(), (m_reg[GREG_PCI_MEM1_LO]<<21) | (offset*4), result, mem_mask);
+ return result;
+}
+WRITE32_MEMBER (gt64xxx_device::master_mem1_w)
+{
+ this->space(AS_DATA).write_dword((m_reg[GREG_PCI_MEM1_LO]<<21) | (offset*4), data, mem_mask);
+ if (LOG_GALILEO)
+ logerror("%06X:galileo pci mem1 write to offset %08X = %08X & %08X\n", space.device().safe_pc(), (m_reg[GREG_PCI_MEM1_LO]<<21) | (offset*4), data, mem_mask);
+}
+
+// PCI Master IO
+READ32_MEMBER (gt64xxx_device::master_io_r)
+{
+ UINT32 result = this->space(AS_IO).read_dword((m_reg[GREG_PCI_IO_LO]<<21) | (offset*4), mem_mask);
+ if (LOG_GALILEO)
+ logerror("%06X:galileo pci io read from offset %08X = %08X & %08X\n", space.device().safe_pc(), (m_reg[GREG_PCI_IO_LO]<<21) | (offset*4), result, mem_mask);
+ return result;
+}
+WRITE32_MEMBER (gt64xxx_device::master_io_w)
+{
+ this->space(AS_IO).write_dword((m_reg[GREG_PCI_IO_LO]<<21) | (offset*4), data, mem_mask);
+ if (LOG_GALILEO)
+ logerror("%06X:galileo pciio write to offset %08X = %08X & %08X\n", space.device().safe_pc(), (m_reg[GREG_PCI_IO_LO]<<21) | (offset*4), data, mem_mask);
+}
+
+
+// CPU I/F
+READ32_MEMBER (gt64xxx_device::cpu_if_r)
+{
+ UINT32 result = m_reg[offset];
+
+ /* switch off the offset for special cases */
+ switch (offset)
+ {
+ case GREG_TIMER0_COUNT:
+ case GREG_TIMER1_COUNT:
+ case GREG_TIMER2_COUNT:
+ case GREG_TIMER3_COUNT:
+ {
+ int which = offset % 4;
+ galileo_timer *timer = &m_timer[which];
+
+ result = timer->count;
+ if (timer->active)
+ {
+ UINT32 elapsed = (timer->timer->elapsed() * m_clock).as_double();
+ result = (result > elapsed) ? (result - elapsed) : 0;
+ }
+
+ /* eat some time for those which poll this register */
+ space.device().execute().eat_cycles(100);
+
+ if (LOG_TIMERS)
+ logerror("%08X:hires_timer_r = %08X\n", space.device().safe_pc(), result);
+ break;
+ }
+
+ case GREG_PCI_COMMAND:
+ // code at 40188 loops until this returns non-zero in bit 0
+ //result = 0x0001;
+ break;
+
+ case GREG_CONFIG_DATA:
+ result = config_data_r(space, offset);
+ break;
+
+ case GREG_CONFIG_ADDRESS:
+ result = config_address_r(space, offset);
+ break;
+
+ case GREG_INT_STATE:
+ case GREG_INT_MASK:
+ case GREG_TIMER_CONTROL:
+// if (LOG_GALILEO)
+// logerror("%08X:Galileo read from offset %03X = %08X\n", space.device().safe_pc(), offset*4, result);
+ break;
+
+ default:
+ logerror("%08X:Galileo read from offset %03X = %08X\n", space.device().safe_pc(), offset*4, result);
+ break;
+ }
+
+ if (m_be) result = FLIPENDIAN_INT32(result);
+
+ return result;
+}
+
+WRITE32_MEMBER(gt64xxx_device::cpu_if_w)
+{
+ if (m_be) {
+ data = FLIPENDIAN_INT32(data);
+ mem_mask = FLIPENDIAN_INT32(mem_mask);
+ }
+
+ UINT32 oldata = m_reg[offset];
+ COMBINE_DATA(&m_reg[offset]);
+
+ /* switch off the offset for special cases */
+ switch (offset)
+ {
+ case GREG_RAS_1_0_LO:
+ case GREG_RAS_1_0_HI:
+ case GREG_RAS_3_2_LO:
+ case GREG_RAS_3_2_HI:
+ case GREG_CS_2_0_LO:
+ case GREG_CS_2_0_HI:
+ case GREG_CS_3_BOOT_LO:
+ case GREG_CS_3_BOOT_HI:
+ case GREG_PCI_IO_LO:
+ case GREG_PCI_IO_HI:
+ case GREG_PCI_MEM0_LO:
+ case GREG_PCI_MEM0_HI:
+ case GREG_INTERNAL_SPACE:
+ case GREG_PCI_MEM1_LO:
+ case GREG_PCI_MEM1_HI:
+ map_cpu_space();
+ if (LOG_GALILEO)
+ logerror("%08X:Galileo Memory Map data write to offset %03X = %08X & %08X\n", space.device().safe_pc(), offset*4, data, mem_mask);
+ break;
+
+ case GREG_DMA0_CONTROL:
+ case GREG_DMA1_CONTROL:
+ case GREG_DMA2_CONTROL:
+ case GREG_DMA3_CONTROL:
+ {
+ int which = offset % 4;
+
+ if (LOG_DMA)
+ logerror("%08X:Galileo write to offset %03X = %08X & %08X\n", space.device().safe_pc(), offset*4, data, mem_mask);
+
+ /* keep the read only activity bit */
+ m_reg[offset] &= ~0x4000;
+ m_reg[offset] |= (oldata & 0x4000);
+
+ /* fetch next record */
+ if (data & 0x2000)
+ dma_fetch_next(space, which);
+ m_reg[offset] &= ~0x2000;
+
+ /* if enabling, start the DMA */
+ if (!(oldata & 0x1000) && (data & 0x1000))
+ perform_dma(space, which);
+ break;
+ }
+
+ case GREG_TIMER0_COUNT:
+ case GREG_TIMER1_COUNT:
+ case GREG_TIMER2_COUNT:
+ case GREG_TIMER3_COUNT:
+ {
+ int which = offset % 4;
+ galileo_timer *timer = &m_timer[which];
+
+ if (which != 0)
+ data &= 0xffffff;
+ if (!timer->active)
+ timer->count = data;
+ if (LOG_TIMERS)
+ logerror("%08X:timer/counter %d count = %08X [start=%08X]\n", space.device().safe_pc(), offset % 4, data, timer->count);
+ break;
+ }
+
+ case GREG_TIMER_CONTROL:
+ {
+ int which, mask;
+
+ if (LOG_TIMERS)
+ logerror("%08X:timer/counter control = %08X\n", space.device().safe_pc(), data);
+ for (which = 0, mask = 0x01; which < 4; which++, mask <<= 2)
+ {
+ galileo_timer *timer = &m_timer[which];
+ if (!timer->active && (data & mask))
+ {
+ timer->active = 1;
+ if (timer->count == 0)
+ {
+ timer->count = m_reg[GREG_TIMER0_COUNT + which];
+ if (which != 0)
+ timer->count &= 0xffffff;
+ }
+ timer->timer->adjust(TIMER_PERIOD * timer->count, which);
+ if (LOG_TIMERS)
+ logerror("Adjusted timer to fire in %f secs\n", (TIMER_PERIOD * timer->count).as_double());
+ }
+ else if (timer->active && !(data & mask))
+ {
+ UINT32 elapsed = (timer->timer->elapsed() * m_clock).as_double();
+ timer->active = 0;
+ timer->count = (timer->count > elapsed) ? (timer->count - elapsed) : 0;
+ timer->timer->adjust(attotime::never, which);
+ if (LOG_TIMERS)
+ logerror("Disabled timer\n");
+ }
+ }
+ break;
+ }
+
+ case GREG_INT_STATE:
+ if (LOG_GALILEO)
+ logerror("%08X:Galileo write to IRQ clear = %08X & %08X\n", offset*4, data, mem_mask);
+ m_reg[offset] = oldata & data;
+ update_irqs();
+ break;
+
+ case GREG_CONFIG_DATA:
+ pci_host_device::config_data_w(space, offset, data);
+ if (LOG_GALILEO)
+ logerror("%08X:Galileo PCI config data write to offset %03X = %08X & %08X\n", space.device().safe_pc(), offset*4, data, mem_mask);
+ break;
+
+ case GREG_CONFIG_ADDRESS:
+ pci_host_device::config_address_w(space, offset, data);
+ if (LOG_GALILEO)
+ logerror("%08X:Galileo PCI config address write to offset %03X = %08X & %08X\n", space.device().safe_pc(), offset*4, data, mem_mask);
+ break;
+
+ case GREG_DMA0_COUNT: case GREG_DMA1_COUNT: case GREG_DMA2_COUNT: case GREG_DMA3_COUNT:
+ case GREG_DMA0_SOURCE: case GREG_DMA1_SOURCE: case GREG_DMA2_SOURCE: case GREG_DMA3_SOURCE:
+ case GREG_DMA0_DEST: case GREG_DMA1_DEST: case GREG_DMA2_DEST: case GREG_DMA3_DEST:
+ case GREG_DMA0_NEXT: case GREG_DMA1_NEXT: case GREG_DMA2_NEXT: case GREG_DMA3_NEXT:
+ case GREG_INT_MASK:
+ if (LOG_GALILEO)
+ logerror("%08X:Galileo write to offset %03X = %08X & %08X\n", space.device().safe_pc(), offset*4, data, mem_mask);
+ break;
+
+ default:
+ logerror("%08X:Galileo write to offset %03X = %08X & %08X\n", space.device().safe_pc(), offset*4, data, mem_mask);
+ break;
+ }
+}
+
+/*************************************
+ *
+ * Galileo timers & interrupts
+ *
+ *************************************/
+
+void gt64xxx_device::update_irqs()
+{
+ int state = CLEAR_LINE;
+
+ /* if any unmasked interrupts are live, we generate */
+ if (m_reg[GREG_INT_STATE] & m_reg[GREG_INT_MASK])
+ state = ASSERT_LINE;
+ if (m_irq_num != -1)
+ m_cpu->set_input_line(m_irq_num, state);
+
+ if (LOG_GALILEO)
+ logerror("Galileo IRQ %s\n", (state == ASSERT_LINE) ? "asserted" : "cleared");
+}
+
+
+TIMER_CALLBACK_MEMBER(gt64xxx_device::timer_callback)
+{
+ int which = param;
+ galileo_timer *timer = &m_timer[which];
+
+ if (LOG_TIMERS)
+ logerror("timer %d fired\n", which);
+
+ /* copy the start value from the registers */
+ timer->count = m_reg[GREG_TIMER0_COUNT + which];
+ if (which != 0)
+ timer->count &= 0xffffff;
+
+ /* if we're a timer, adjust the timer to fire again */
+ if (m_reg[GREG_TIMER_CONTROL] & (2 << (2 * which)))
+ timer->timer->adjust(TIMER_PERIOD * timer->count, which);
+ else
+ timer->active = timer->count = 0;
+
+ /* trigger the interrupt */
+ m_reg[GREG_INT_STATE] |= 1 << (GINT_T0EXP_SHIFT + which);
+ update_irqs();
+}
+
+/*************************************
+ *
+ * Galileo DMA handler
+ *
+ *************************************/
+
+int gt64xxx_device::dma_fetch_next(address_space &space, int which)
+{
+ offs_t address = 0;
+ UINT32 data;
+
+ /* no-op for unchained mode */
+ if (!(m_reg[GREG_DMA0_CONTROL + which] & 0x200))
+ address = m_reg[GREG_DMA0_NEXT + which];
+
+ /* if we hit the end address, signal an interrupt */
+ if (address == 0)
+ {
+ if (m_reg[GREG_DMA0_CONTROL + which] & 0x400)
+ {
+ m_reg[GREG_INT_STATE] |= 1 << (GINT_DMA0COMP_SHIFT + which);
+ update_irqs();
+ }
+ m_reg[GREG_DMA0_CONTROL + which] &= ~0x5000;
+ return 0;
+ }
+
+ /* fetch the byte count */
+ data = space.read_dword(address); address += 4;
+ m_reg[GREG_DMA0_COUNT + which] = data;
+
+ /* fetch the source address */
+ data = space.read_dword(address); address += 4;
+ m_reg[GREG_DMA0_SOURCE + which] = data;
+
+ /* fetch the dest address */
+ data = space.read_dword(address); address += 4;
+ m_reg[GREG_DMA0_DEST + which] = data;
+
+ /* fetch the next record address */
+ data = space.read_dword(address); address += 4;
+ m_reg[GREG_DMA0_NEXT + which] = data;
+ return 1;
+}
+
+
+void gt64xxx_device::perform_dma(address_space &space, int which)
+{
+ do
+ {
+ offs_t srcaddr = m_reg[GREG_DMA0_SOURCE + which];
+ offs_t dstaddr = m_reg[GREG_DMA0_DEST + which];
+ UINT32 bytesleft = m_reg[GREG_DMA0_COUNT + which] & 0xffff;
+ int srcinc, dstinc;
+
+ m_dma_active = which;
+ m_reg[GREG_DMA0_CONTROL + which] |= 0x5000;
+
+ /* determine src/dst inc */
+ switch ((m_reg[GREG_DMA0_CONTROL + which] >> 2) & 3)
+ {
+ default:
+ case 0: srcinc = 1; break;
+ case 1: srcinc = -1; break;
+ case 2: srcinc = 0; break;
+ }
+ switch ((m_reg[GREG_DMA0_CONTROL + which] >> 4) & 3)
+ {
+ default:
+ case 0: dstinc = 1; break;
+ case 1: dstinc = -1; break;
+ case 2: dstinc = 0; break;
+ }
+
+ if (LOG_DMA)
+ logerror("Performing DMA%d: src=%08X dst=%08X bytes=%04X sinc=%d dinc=%d\n", which, srcaddr, dstaddr, bytesleft, srcinc, dstinc);
+
+ /* standard transfer */
+ while (bytesleft > 0)
+ {
+ space.write_byte(dstaddr, space.read_byte(srcaddr));
+ srcaddr += srcinc;
+ dstaddr += dstinc;
+ bytesleft--;
+ }
+
+ /* not verified, but seems logical these should be updated byte the end */
+ m_reg[GREG_DMA0_SOURCE + which] = srcaddr;
+ m_reg[GREG_DMA0_DEST + which] = dstaddr;
+ m_reg[GREG_DMA0_COUNT + which] = (m_reg[GREG_DMA0_COUNT + which] & ~0xffff) | bytesleft;
+ m_dma_active = -1;
+
+ /* if we did not hit zero, punt and return later */
+ if (bytesleft != 0)
+ return;
+
+ /* interrupt? */
+ if (!(m_reg[GREG_DMA0_CONTROL + which] & 0x400))
+ {
+ m_reg[GREG_INT_STATE] |= 1 << (GINT_DMA0COMP_SHIFT + which);
+ update_irqs();
+ }
+ } while (dma_fetch_next(space, which));
+
+ m_reg[GREG_DMA0_CONTROL + which] &= ~0x5000;
+}
diff --git a/src/devices/machine/gt64xxx.h b/src/devices/machine/gt64xxx.h
new file mode 100644
index 00000000000..a31674d59e8
--- /dev/null
+++ b/src/devices/machine/gt64xxx.h
@@ -0,0 +1,259 @@
+// license:BSD-3-Clause
+// copyright-holders: Aaron Giles, Ted Green
+// Galileo GT-64xxx System Controller
+// Skeleton code based off seattle machine driver.
+// TODO:
+// Testing
+// Need PCI to be able to have a target delay a dma transfer
+// Add PCI target maps
+// Add PCI Func 1 calls
+// Configurable byte swapping on cpu and pci busses.
+
+#ifndef GT64XXX_H
+#define GT64XXX_H
+
+#include "pci.h"
+#include "cpu/mips/mips3.h"
+
+// Supports R4600/4650/4700/R5000 CPUs
+#define MCFG_GT64010_ADD(_tag, _cpu_tag, _clock) \
+ MCFG_PCI_HOST_ADD(_tag, GT64XXX, 0x014611ab, 0x03, 0x00000000) \
+ downcast<gt64xxx_device *>(device)->set_cpu_tag(_cpu_tag); \
+ downcast<gt64xxx_device *>(device)->set_clock(_clock);
+
+// Supports the following 32-bit bus CPUs:
+// IDT RC4640 and RC4650 (in 32-bit mode)
+// QED RM523X
+// NEC/Toshiba VR4300
+#define MCFG_GT64111_ADD(_tag, _cpu_tag, _clock) \
+ MCFG_PCI_DEVICE_ADD(_tag, GT64XXX, 0x414611ab, 0x10, 0x058000, 0x00000000) \
+ downcast<gt64xxx_device *>(device)->set_cpu_tag(_cpu_tag); \
+ downcast<gt64xxx_device *>(device)->set_clock(_clock);
+
+#define MCFG_GT64XXX_SET_BE_CPU(_be) \
+ downcast<gt64xxx_device *>(device)->set_be(_be);
+
+#define MCFG_GT64XXX__IRQ_ADD(_irq_num) \
+ downcast<gt64xxx_device *>(device)->set_irq_info(_irq_num);
+
+/*************************************
+ *
+ * Galileo constants
+ *
+ *************************************/
+
+//#define SYSTEM_CLOCK 50000000
+#define TIMER_PERIOD attotime::from_hz(m_clock)
+
+/* Galileo registers - 0x000-0x3ff */
+#define GREG_CPU_CONFIG (0x000/4)
+#define GREG_RAS_1_0_LO (0x008/4)
+#define GREG_RAS_1_0_HI (0x010/4)
+#define GREG_RAS_3_2_LO (0x018/4)
+#define GREG_RAS_3_2_HI (0x020/4)
+#define GREG_CS_2_0_LO (0x028/4)
+#define GREG_CS_2_0_HI (0x030/4)
+#define GREG_CS_3_BOOT_LO (0x038/4)
+#define GREG_CS_3_BOOT_HI (0x040/4)
+#define GREG_PCI_IO_LO (0x048/4)
+#define GREG_PCI_IO_HI (0x050/4)
+#define GREG_PCI_MEM0_LO (0x058/4)
+#define GREG_PCI_MEM0_HI (0x060/4)
+#define GREG_INTERNAL_SPACE (0x068/4)
+#define GREG_BUSERR_LO (0x070/4)
+#define GREG_BUSERR_HI (0x078/4)
+// GT-64111 only
+#define GREG_PCI_MEM1_LO (0x080/4)
+#define GREG_PCI_MEM1_HI (0x088/4)
+
+/* Galileo registers - 0x400-0x7ff */
+#define GREG_RAS0_LO (0x400/4)
+#define GREG_RAS0_HI (0x404/4)
+#define GREG_RAS1_LO (0x408/4)
+#define GREG_RAS1_HI (0x40c/4)
+#define GREG_RAS2_LO (0x410/4)
+#define GREG_RAS2_HI (0x414/4)
+#define GREG_RAS3_LO (0x418/4)
+#define GREG_RAS3_HI (0x41c/4)
+#define GREG_CS0_LO (0x420/4)
+#define GREG_CS0_HI (0x424/4)
+#define GREG_CS1_LO (0x428/4)
+#define GREG_CS1_HI (0x42c/4)
+#define GREG_CS2_LO (0x430/4)
+#define GREG_CS2_HI (0x434/4)
+#define GREG_CS3_LO (0x438/4)
+#define GREG_CS3_HI (0x43c/4)
+#define GREG_CSBOOT_LO (0x440/4)
+#define GREG_CSBOOT_HI (0x444/4)
+#define GREG_DRAM_CONFIG (0x448/4)
+#define GREG_DRAM_BANK0 (0x44c/4)
+#define GREG_DRAM_BANK1 (0x450/4)
+#define GREG_DRAM_BANK2 (0x454/4)
+#define GREG_DRAM_BANK3 (0x458/4)
+#define GREG_DEVICE_BANK0 (0x45c/4)
+#define GREG_DEVICE_BANK1 (0x460/4)
+#define GREG_DEVICE_BANK2 (0x464/4)
+#define GREG_DEVICE_BANK3 (0x468/4)
+#define GREG_DEVICE_BOOT (0x46c/4)
+#define GREG_ADDRESS_ERROR (0x470/4)
+
+/* Galileo registers - 0x800-0xbff */
+#define GREG_DMA0_COUNT (0x800/4)
+#define GREG_DMA1_COUNT (0x804/4)
+#define GREG_DMA2_COUNT (0x808/4)
+#define GREG_DMA3_COUNT (0x80c/4)
+#define GREG_DMA0_SOURCE (0x810/4)
+#define GREG_DMA1_SOURCE (0x814/4)
+#define GREG_DMA2_SOURCE (0x818/4)
+#define GREG_DMA3_SOURCE (0x81c/4)
+#define GREG_DMA0_DEST (0x820/4)
+#define GREG_DMA1_DEST (0x824/4)
+#define GREG_DMA2_DEST (0x828/4)
+#define GREG_DMA3_DEST (0x82c/4)
+#define GREG_DMA0_NEXT (0x830/4)
+#define GREG_DMA1_NEXT (0x834/4)
+#define GREG_DMA2_NEXT (0x838/4)
+#define GREG_DMA3_NEXT (0x83c/4)
+#define GREG_DMA0_CONTROL (0x840/4)
+#define GREG_DMA1_CONTROL (0x844/4)
+#define GREG_DMA2_CONTROL (0x848/4)
+#define GREG_DMA3_CONTROL (0x84c/4)
+#define GREG_TIMER0_COUNT (0x850/4)
+#define GREG_TIMER1_COUNT (0x854/4)
+#define GREG_TIMER2_COUNT (0x858/4)
+#define GREG_TIMER3_COUNT (0x85c/4)
+#define GREG_DMA_ARBITER (0x860/4)
+#define GREG_TIMER_CONTROL (0x864/4)
+
+/* Galileo registers - 0xc00-0xfff */
+#define GREG_PCI_COMMAND (0xc00/4)
+#define GREG_PCI_TIMEOUT (0xc04/4)
+#define GREG_PCI_RAS_1_0 (0xc08/4)
+#define GREG_PCI_RAS_3_2 (0xc0c/4)
+#define GREG_PCI_CS_2_0 (0xc10/4)
+#define GREG_PCI_CS_3_BOOT (0xc14/4)
+#define GREG_INT_STATE (0xc18/4)
+#define GREG_INT_MASK (0xc1c/4)
+#define GREG_PCI_INT_MASK (0xc24/4)
+#define GREG_CONFIG_ADDRESS (0xcf8/4)
+#define GREG_CONFIG_DATA (0xcfc/4)
+
+/* Galileo interrupts */
+#define GINT_SUMMARY_SHIFT (0)
+#define GINT_MEMOUT_SHIFT (1)
+#define GINT_DMAOUT_SHIFT (2)
+#define GINT_CPUOUT_SHIFT (3)
+#define GINT_DMA0COMP_SHIFT (4)
+#define GINT_DMA1COMP_SHIFT (5)
+#define GINT_DMA2COMP_SHIFT (6)
+#define GINT_DMA3COMP_SHIFT (7)
+#define GINT_T0EXP_SHIFT (8)
+#define GINT_T1EXP_SHIFT (9)
+#define GINT_T2EXP_SHIFT (10)
+#define GINT_T3EXP_SHIFT (11)
+#define GINT_MASRDERR_SHIFT (12)
+#define GINT_SLVWRERR_SHIFT (13)
+#define GINT_MASWRERR_SHIFT (14)
+#define GINT_SLVRDERR_SHIFT (15)
+#define GINT_ADDRERR_SHIFT (16)
+#define GINT_MEMERR_SHIFT (17)
+#define GINT_MASABORT_SHIFT (18)
+#define GINT_TARABORT_SHIFT (19)
+#define GINT_RETRYCTR_SHIFT (20)
+
+/*************************************
+ * Structures
+ *************************************/
+struct galileo_timer
+{
+ emu_timer * timer;
+ UINT32 count;
+ UINT8 active;
+};
+
+
+class gt64xxx_device : public pci_host_device {
+public:
+ gt64xxx_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ virtual void reset_all_mappings() override;
+ virtual void map_extra(UINT64 memory_window_start, UINT64 memory_window_end, UINT64 memory_offset, address_space *memory_space,
+ UINT64 io_window_start, UINT64 io_window_end, UINT64 io_offset, address_space *io_space) override;
+
+ void set_cpu_tag(const char *tag) { cpu_tag = tag;}
+ void set_cpu_tag(const UINT32 clock) { m_clock = clock;}
+ void set_clock(const UINT32 clock) {m_clock = clock;}
+ void set_be(const int be) {m_be = be;}
+ void set_autoconfig(const int autoconfig) {m_autoconfig = autoconfig;}
+ void set_irq_info(const int irq_num) {m_irq_num = irq_num;}
+
+ virtual DECLARE_ADDRESS_MAP(config_map, 32) override;
+
+ // pci bus
+ DECLARE_READ32_MEMBER( pci_config_r);
+ DECLARE_WRITE32_MEMBER( pci_config_w);
+
+ // cpu bus
+ DECLARE_READ32_MEMBER (cpu_if_r);
+ DECLARE_WRITE32_MEMBER(cpu_if_w);
+
+ DECLARE_READ32_MEMBER (master_mem0_r);
+ DECLARE_WRITE32_MEMBER(master_mem0_w);
+
+ DECLARE_READ32_MEMBER (master_mem1_r);
+ DECLARE_WRITE32_MEMBER(master_mem1_w);
+
+ DECLARE_READ32_MEMBER (master_io_r);
+ DECLARE_WRITE32_MEMBER(master_io_w);
+
+ // devices
+ DECLARE_READ32_MEMBER (ras_1_0_r);
+ DECLARE_WRITE32_MEMBER(ras_1_0_w);
+ DECLARE_READ32_MEMBER (ras_3_2_r);
+ DECLARE_WRITE32_MEMBER(ras_3_2_w);
+ DECLARE_READ32_MEMBER (cs_2_0_r);
+ DECLARE_WRITE32_MEMBER(cs_2_0_w);
+ DECLARE_READ32_MEMBER (cs_boot_3_r);
+ DECLARE_WRITE32_MEMBER(cs_boot_3_w);
+
+protected:
+ address_space *m_cpu_space;
+ virtual const address_space_config *memory_space_config(address_spacenum spacenum) const override;
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+private:
+ mips3_device *m_cpu;
+ const char *cpu_tag;
+ UINT32 m_clock;
+ int m_be, m_autoconfig;
+ int m_irq_num;
+
+ address_space_config m_mem_config, m_io_config;
+
+ DECLARE_ADDRESS_MAP(cpu_map, 32);
+
+ void map_cpu_space();
+
+ /* raw register data */
+ UINT32 m_reg[0xd00/4];
+
+ /* timer info */
+ galileo_timer m_timer[4];
+
+ /* DMA info */
+ INT8 m_dma_active;
+
+ // Ram
+ std::vector<UINT32> m_ram[4];
+
+ TIMER_CALLBACK_MEMBER(timer_callback);
+ void update_irqs();
+ int dma_fetch_next(address_space &space, int which);
+ void perform_dma(address_space &space, int which);
+
+};
+
+extern const device_type GT64XXX;
+
+#endif
diff --git a/src/devices/machine/ins8250.cpp b/src/devices/machine/ins8250.cpp
index bbd0fee1584..e032039cb7d 100644
--- a/src/devices/machine/ins8250.cpp
+++ b/src/devices/machine/ins8250.cpp
@@ -316,7 +316,7 @@ WRITE8_MEMBER( ins8250_uart_device::ins8250_w )
bits 5 - 0, you could cause an interrupt if the appropriate IER bit
is set.
*/
- m_regs.lsr = (m_regs.lsr & 0x40) | (data & ~0x40);
+ m_regs.lsr = (m_regs.lsr & 0x60) | (data & ~0x60);
tmp = 0;
tmp |= ( m_regs.lsr & 0x01 ) ? COM_INT_PENDING_RECEIVED_DATA_AVAILABLE : 0;
diff --git a/src/devices/machine/netlist.cpp b/src/devices/machine/netlist.cpp
index 1b8c76743bc..d0a06604707 100644
--- a/src/devices/machine/netlist.cpp
+++ b/src/devices/machine/netlist.cpp
@@ -569,7 +569,7 @@ void netlist_mame_sound_device_t::device_start()
// Configure outputs
- plist_t<nld_sound_out *> outdevs = netlist().get_device_list<nld_sound_out>();
+ pvector_t<nld_sound_out *> outdevs = netlist().get_device_list<nld_sound_out>();
if (outdevs.size() == 0)
fatalerror("No output devices");
@@ -595,7 +595,7 @@ void netlist_mame_sound_device_t::device_start()
m_num_inputs = 0;
m_in = nullptr;
- plist_t<nld_sound_in *> indevs = netlist().get_device_list<nld_sound_in>();
+ pvector_t<nld_sound_in *> indevs = netlist().get_device_list<nld_sound_in>();
if (indevs.size() > 1)
fatalerror("A maximum of one input device is allowed!");
if (indevs.size() == 1)
diff --git a/src/devices/sound/ad1848.cpp b/src/devices/sound/ad1848.cpp
new file mode 100644
index 00000000000..4c299be37be
--- /dev/null
+++ b/src/devices/sound/ad1848.cpp
@@ -0,0 +1,186 @@
+// license:BSD-3-Clause
+// copyright-holders:Carl
+
+// Analog Devices AD1848, main codec in Windows Sound System adapters
+
+#include "sound/ad1848.h"
+
+const device_type AD1848 = device_creator<ad1848_device>;
+
+ad1848_device::ad1848_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
+ device_t(mconfig, AD1848, "Analog Devices AD1848", tag, owner, clock, "ad1848", __FILE__),
+ m_irq_cb(*this),
+ m_drq_cb(*this),
+ m_dacl(*this, "dacl"),
+ m_dacr(*this, "dacr")
+{
+}
+
+static MACHINE_CONFIG_FRAGMENT( ad1848_config )
+ MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
+ MCFG_SOUND_ADD("dacl", DAC, 0)
+ MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 1.00)
+ MCFG_SOUND_ADD("dacr", DAC, 0)
+ MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 1.00)
+MACHINE_CONFIG_END
+
+machine_config_constructor ad1848_device::device_mconfig_additions() const
+{
+ return MACHINE_CONFIG_NAME( ad1848_config );
+}
+
+void ad1848_device::device_start()
+{
+ m_timer = timer_alloc(0, nullptr);
+ m_irq_cb.resolve_safe();
+ m_drq_cb.resolve_safe();
+}
+
+void ad1848_device::device_reset()
+{
+ memset(&m_regs.idx[0], '\0', sizeof(m_regs));
+ m_addr = 0;
+ m_stat = 0;
+ m_sam_cnt = 0;
+ m_samples = 0;
+ m_play = false;
+}
+
+READ8_MEMBER(ad1848_device::read)
+{
+ switch(offset)
+ {
+ case 0:
+ return m_addr | (m_mce ? 0x40 : 0) | (m_trd ? 0x20 : 0);
+ case 1:
+ return m_regs.idx[m_addr];
+ case 2:
+ return m_stat;
+ case 3:
+ break; // capture
+ }
+ return 0;
+}
+
+WRITE8_MEMBER(ad1848_device::write)
+{
+ const int div_factor[] = {3072, 1536, 896, 768, 448, 384, 512, 2560};
+ switch(offset)
+ {
+ case 0:
+ m_addr = data & 0xf;
+ m_mce = data & 0x40 ? true : false;
+ m_trd = data & 0x20 ? true : false;
+ break;
+ case 1:
+ if(m_addr == 12)
+ return;
+ m_regs.idx[m_addr] = data;
+ switch(m_addr)
+ {
+ case 8:
+ if(m_mce)
+ return;
+ m_regs.dform &= 0x7f;
+ break;
+ case 9:
+ {
+ m_play = (data & 1) ? true : false;
+ attotime rate = m_play ? attotime::from_hz(((m_regs.dform & 1) ? XTAL_24_576MHz : XTAL_16_9344MHz)
+ / div_factor[(m_regs.dform >> 1) & 7]) : attotime::never;
+ m_timer->adjust(rate, 0 , rate);
+ m_drq_cb(m_play ? ASSERT_LINE : CLEAR_LINE);
+ break;
+ }
+ case 14:
+ m_count = (m_regs.ubase << 8) | m_regs.lbase;
+ break;
+ }
+ break;
+ case 2:
+ m_irq_cb(CLEAR_LINE);
+ if(m_regs.iface & 1)
+ m_play = true;
+ break;
+ case 3:
+ break; // playback
+ }
+}
+
+READ8_MEMBER(ad1848_device::dack_r)
+{
+ m_drq_cb(CLEAR_LINE);
+ return 0; // not implemented
+}
+
+WRITE8_MEMBER(ad1848_device::dack_w)
+{
+ if(!m_play)
+ return;
+ m_samples = (m_samples << 8) | data;
+ m_sam_cnt++;
+ switch(m_regs.dform >> 4)
+ {
+ case 0:
+ case 2:
+ case 6:
+ m_sam_cnt = 0;
+ break;
+ case 1:
+ case 3:
+ case 4:
+ case 7:
+ if(m_sam_cnt == 2)
+ m_sam_cnt = 0;
+ break;
+ case 5:
+ if(m_sam_cnt == 4)
+ m_sam_cnt = 0;
+ break;
+ }
+ if(!m_sam_cnt)
+ m_drq_cb(CLEAR_LINE);
+}
+
+void ad1848_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
+{
+ if(!m_play)
+ return;
+ switch(m_regs.dform >> 4)
+ {
+ case 0: // 8bit mono
+ m_dacl->write_unsigned8(m_samples & 0xff);
+ m_dacr->write_unsigned8(m_samples & 0xff);
+ break;
+ case 1: // 8bit stereo
+ m_dacl->write_unsigned8(m_samples & 0xff);
+ m_dacr->write_unsigned8((m_samples >> 8) & 0xff);
+ break;
+ case 2: // ulaw mono
+ case 3: // ulaw stereo
+ case 6: // alaw mono
+ case 7: // alaw stereo
+ break;
+ case 4: // 16bit mono
+ m_dacl->write(m_samples & 0xffff);
+ m_dacr->write(m_samples & 0xffff);
+ break;
+ case 5: // 16bit stereo
+ m_dacl->write(m_samples & 0xffff);
+ m_dacr->write(m_samples >> 16);
+ break;
+ }
+ if(!m_count)
+ {
+ if(m_regs.pinc & 2)
+ {
+ if(m_trd)
+ m_play = false;
+ m_irq_cb(ASSERT_LINE);
+ }
+ m_count = (m_regs.ubase << 8) | m_regs.lbase;
+ }
+ else
+ m_count--;
+ m_drq_cb(ASSERT_LINE);
+}
diff --git a/src/devices/sound/ad1848.h b/src/devices/sound/ad1848.h
new file mode 100644
index 00000000000..d2c93c57329
--- /dev/null
+++ b/src/devices/sound/ad1848.h
@@ -0,0 +1,67 @@
+// license:BSD-3-Clause
+// copyright-holders:Carl
+#ifndef _AD1848_H_
+#define _AD1848_H_
+
+#include "emu.h"
+#include "sound/dac.h"
+
+#define MCFG_AD1848_IRQ_CALLBACK(_cb) \
+ devcb = &ad1848_device::set_irq_callback(*device, DEVCB_##_cb);
+
+#define MCFG_AD1848_DRQ_CALLBACK(_cb) \
+ devcb = &ad1848_device::set_drq_callback(*device, DEVCB_##_cb);
+
+class ad1848_device : public device_t
+{
+public:
+ ad1848_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+ DECLARE_READ8_MEMBER(read);
+ DECLARE_WRITE8_MEMBER(write);
+ DECLARE_READ8_MEMBER(dack_r);
+ DECLARE_WRITE8_MEMBER(dack_w);
+ template<class _Object> static devcb_base &set_irq_callback(device_t &device, _Object object) { return downcast<ad1848_device &>(device).m_irq_cb.set_callback(object); }
+ template<class _Object> static devcb_base &set_drq_callback(device_t &device, _Object object) { return downcast<ad1848_device &>(device).m_drq_cb.set_callback(object); }
+ virtual machine_config_constructor device_mconfig_additions() const override;
+protected:
+ virtual void device_start() override;
+ virtual void device_reset() override;
+ virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
+private:
+ union {
+ struct {
+ UINT8 linp;
+ UINT8 rinp;
+ UINT8 laux1;
+ UINT8 raux1;
+ UINT8 laux2;
+ UINT8 raux2;
+ UINT8 lout;
+ UINT8 rout;
+ UINT8 dform;
+ UINT8 iface;
+ UINT8 pinc;
+ UINT8 init;
+ UINT8 misc;
+ UINT8 mix;
+ UINT8 ubase;
+ UINT8 lbase;
+ };
+ UINT8 idx[15];
+ } m_regs;
+ UINT8 m_addr;
+ UINT8 m_stat;
+ UINT16 m_count;
+ UINT32 m_samples;
+ UINT8 m_sam_cnt;
+ bool m_play, m_mce, m_trd;
+ devcb_write_line m_irq_cb;
+ devcb_write_line m_drq_cb;
+ required_device<dac_device> m_dacl;
+ required_device<dac_device> m_dacr;
+ emu_timer *m_timer;
+};
+
+extern const device_type AD1848;
+
+#endif
diff --git a/src/devices/sound/samples.cpp b/src/devices/sound/samples.cpp
index 62bd8e02657..0b92b51202d 100644
--- a/src/devices/sound/samples.cpp
+++ b/src/devices/sound/samples.cpp
@@ -618,20 +618,20 @@ bool samples_device::load_samples()
{
// attempt to open as FLAC first
emu_file file(machine().options().sample_path(), OPEN_FLAG_READ);
- file_error filerr = file.open(basename, PATH_SEPARATOR, samplename, ".flac");
- if (filerr != FILERR_NONE && altbasename != nullptr)
+ osd_file::error filerr = file.open(basename, PATH_SEPARATOR, samplename, ".flac");
+ if (filerr != osd_file::error::NONE && altbasename != nullptr)
filerr = file.open(altbasename, PATH_SEPARATOR, samplename, ".flac");
// if not, try as WAV
- if (filerr != FILERR_NONE)
+ if (filerr != osd_file::error::NONE)
filerr = file.open(basename, PATH_SEPARATOR, samplename, ".wav");
- if (filerr != FILERR_NONE && altbasename != nullptr)
+ if (filerr != osd_file::error::NONE && altbasename != nullptr)
filerr = file.open(altbasename, PATH_SEPARATOR, samplename, ".wav");
// if opened, read it
- if (filerr == FILERR_NONE)
+ if (filerr == osd_file::error::NONE)
read_sample(file, m_sample[index]);
- else if (filerr == FILERR_NOT_FOUND)
+ else if (filerr == osd_file::error::NOT_FOUND)
{
logerror("%s: Sample '%s' NOT FOUND\n", tag(), samplename);
ok = false;
diff --git a/src/devices/video/h63484.cpp b/src/devices/video/h63484.cpp
index 1e0d7cbb0d8..07098bfdb10 100644
--- a/src/devices/video/h63484.cpp
+++ b/src/devices/video/h63484.cpp
@@ -29,7 +29,7 @@ ADDRESS_MAP_END
//-------------------------------------------------
h63484_device::h63484_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
- : device_t(mconfig, H63484, "HD63484 CRTC (rewrite)", tag, owner, clock, "h63484", __FILE__),
+ : device_t(mconfig, H63484, "HD63484 CRTC", tag, owner, clock, "hd63484", __FILE__),
device_memory_interface(mconfig, *this),
device_video_interface(mconfig, *this),
m_ar(0),
@@ -1913,7 +1913,8 @@ void h63484_device::video_registers_w(int offset)
READ16_MEMBER( h63484_device::status_r )
{
- return m_sr;
+ // kothello is coded so that upper byte of this should be 0xff (tests with jc opcode). Maybe it's just unconnected?
+ return m_sr | 0xff00;
}
READ16_MEMBER( h63484_device::data_r )
diff --git a/src/devices/video/hd63484.cpp b/src/devices/video/hd63484.cpp
index 9dab25d3669..6dfb998898d 100644
--- a/src/devices/video/hd63484.cpp
+++ b/src/devices/video/hd63484.cpp
@@ -28,7 +28,7 @@
const device_type HD63484 = &device_creator<hd63484_device>;
hd63484_device::hd63484_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
- : device_t(mconfig, HD63484, "HD63484 CRTC", tag, owner, clock, "hd63484", __FILE__),
+ : device_t(mconfig, HD63484, "HD63484 CRTC (Legacy)", tag, owner, clock, "hd63484l", __FILE__),
m_ram(nullptr),
m_fifo_counter(0),
m_readfifo(0),
diff --git a/src/devices/video/pc_vga.cpp b/src/devices/video/pc_vga.cpp
index 7710e3402c3..80cbae9b225 100644
--- a/src/devices/video/pc_vga.cpp
+++ b/src/devices/video/pc_vga.cpp
@@ -224,6 +224,17 @@ TIMER_CALLBACK_MEMBER(vga_device::vblank_timer_cb)
m_vblank_timer->adjust( machine().first_screen()->time_until_pos(vga.crtc.vert_blank_start + vga.crtc.vert_blank_end) );
}
+TIMER_CALLBACK_MEMBER(s3_vga_device::vblank_timer_cb)
+{
+ // not sure if this is correct, but XF86_S3 seems to expect the viewport scrolling to be faster
+ if(s3.memory_config & 0x08)
+ vga.crtc.start_addr = vga.crtc.start_addr_latch << 2;
+ else
+ vga.crtc.start_addr = vga.crtc.start_addr_latch;
+ vga.attribute.pel_shift = vga.attribute.pel_shift_latch;
+ m_vblank_timer->adjust( machine().first_screen()->time_until_pos(vga.crtc.vert_blank_start + vga.crtc.vert_blank_end) );
+}
+
void vga_device::device_start()
{
zero();
@@ -1051,50 +1062,53 @@ UINT32 s3_vga_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap,
// printf("%08x: %02x %02x %02x %02x\n",src+x*4,vga.memory[src+x*4],vga.memory[src+x*4+1],vga.memory[src+x*4+2],vga.memory[src+x*4+3]);
for(y=0;y<64;y++)
{
- dst = &bitmap.pix32(cy + y, cx);
- for(x=0;x<64;x++)
+ if(cy + y < cliprect.max_y && cx < cliprect.max_x)
{
- UINT16 bita = (vga.memory[(src+1) % vga.svga_intf.vram_size] | ((vga.memory[(src+0) % vga.svga_intf.vram_size]) << 8)) >> (15-(x % 16));
- UINT16 bitb = (vga.memory[(src+3) % vga.svga_intf.vram_size] | ((vga.memory[(src+2) % vga.svga_intf.vram_size]) << 8)) >> (15-(x % 16));
- val = ((bita & 0x01) << 1) | (bitb & 0x01);
- if(s3.extended_dac_ctrl & 0x10)
- { // X11 mode
- switch(val)
- {
- case 0x00:
- // no change
- break;
- case 0x01:
- // no change
- break;
- case 0x02:
- dst[x] = bg_col;
- break;
- case 0x03:
- dst[x] = fg_col;
- break;
+ dst = &bitmap.pix32(cy + y, cx);
+ for(x=0;x<64;x++)
+ {
+ UINT16 bita = (vga.memory[(src+1) % vga.svga_intf.vram_size] | ((vga.memory[(src+0) % vga.svga_intf.vram_size]) << 8)) >> (15-(x % 16));
+ UINT16 bitb = (vga.memory[(src+3) % vga.svga_intf.vram_size] | ((vga.memory[(src+2) % vga.svga_intf.vram_size]) << 8)) >> (15-(x % 16));
+ val = ((bita & 0x01) << 1) | (bitb & 0x01);
+ if(s3.extended_dac_ctrl & 0x10)
+ { // X11 mode
+ switch(val)
+ {
+ case 0x00:
+ // no change
+ break;
+ case 0x01:
+ // no change
+ break;
+ case 0x02:
+ dst[x] = bg_col;
+ break;
+ case 0x03:
+ dst[x] = fg_col;
+ break;
+ }
}
- }
- else
- { // Windows mode
- switch(val)
- {
- case 0x00:
- dst[x] = bg_col;
- break;
- case 0x01:
- dst[x] = fg_col;
- break;
- case 0x02: // screen data
- // no change
- break;
- case 0x03: // inverted screen data
- dst[x] = ~(dst[x]);
- break;
+ else
+ { // Windows mode
+ switch(val)
+ {
+ case 0x00:
+ dst[x] = bg_col;
+ break;
+ case 0x01:
+ dst[x] = fg_col;
+ break;
+ case 0x02: // screen data
+ // no change
+ break;
+ case 0x03: // inverted screen data
+ dst[x] = ~(dst[x]);
+ break;
+ }
}
+ if(x % 16 == 15)
+ src+=4;
}
- if(x % 16 == 15)
- src+=4;
}
}
}
@@ -3388,7 +3402,6 @@ void ibm8514a_device::ibm8514_write(UINT32 offset, UINT32 src)
{
int data_size = 8;
UINT32 xfer;
- address_space& space = machine().device("maincpu")->memory().space(AS_PROGRAM);
switch(ibm8514.pixel_control & 0x00c0)
{
@@ -3428,6 +3441,7 @@ void ibm8514a_device::ibm8514_write(UINT32 offset, UINT32 src)
ibm8514.src_x = 0;
break;
case 0x00c0: // use source plane
+ address_space& space = machine().device("maincpu")->memory().space(AS_PROGRAM);
if(m_vga->mem_linear_r(space,src,0xff) != 0x00)
ibm8514_write_fg(offset);
else
diff --git a/src/devices/video/pc_vga.h b/src/devices/video/pc_vga.h
index 9c729ba7a6e..a7f0552ffdb 100644
--- a/src/devices/video/pc_vga.h
+++ b/src/devices/video/pc_vga.h
@@ -568,6 +568,7 @@ public:
virtual UINT32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) override;
virtual machine_config_constructor device_mconfig_additions() const override;
+ virtual TIMER_CALLBACK_MEMBER(vblank_timer_cb) override;
ibm8514a_device* get_8514() { return m_8514; }
protected:
diff --git a/src/devices/video/tms9927.cpp b/src/devices/video/tms9927.cpp
index 4b6f82e18b8..9c45dab00ca 100644
--- a/src/devices/video/tms9927.cpp
+++ b/src/devices/video/tms9927.cpp
@@ -22,7 +22,7 @@ static const UINT8 skew_bits_value[4] = { 0, 1, 2, 2 };
#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 SCAN_LINES_PER_FRAME ((m_reg[4] * 2) + 256)
+#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)
#define CURSOR_CHAR_ADDRESS (m_reg[7])
@@ -79,7 +79,7 @@ crt5057_device::crt5057_device(const machine_config &mconfig, const char *tag, d
void tms9927_device::device_start()
{
assert(clock() > 0);
- assert(m_hpixels_per_column > 0);
+ if (!(m_hpixels_per_column > 0)) fatalerror("TMS9927: number of pixels per column must be explicitly set using MCFG_TMS9927_CHAR_WIDTH()!\n");
/* copy the initial parameters */
m_clock = clock();
@@ -303,12 +303,19 @@ void tms9927_device::recompute_parameters(int postload)
/* see if it all makes sense */
m_valid_config = TRUE;
- if (m_visible_hpix > m_total_hpix || m_visible_vpix > m_total_vpix)
+ if ( (m_visible_hpix > m_total_hpix || m_visible_vpix > m_total_vpix) || (((m_visible_hpix-1)<=0) || ((m_visible_vpix-1)<=0)) || ((m_total_hpix * m_total_vpix) == 0) )
{
m_valid_config = FALSE;
logerror("tms9927: invalid visible size (%dx%d) versus total size (%dx%d)\n", m_visible_hpix, m_visible_vpix, m_total_hpix, m_total_vpix);
}
+ if (m_clock == 0)
+ {
+ m_valid_config = FALSE;
+ // TODO: make the screen refresh never, and disable the vblank and odd/even interrupts here!
+ logerror("tms9927: invalid clock rate of zero defined!\n");
+ }
+
/* update */
if (!m_valid_config)
return;
diff --git a/src/emu/attotime.h b/src/emu/attotime.h
index 0cdaa424ca0..a0915ae07f2 100644
--- a/src/emu/attotime.h
+++ b/src/emu/attotime.h
@@ -117,17 +117,6 @@ public:
UINT64 as_ticks(UINT32 frequency) const;
const char *as_string(int precision = 9) const;
- // Needed by gba.c FIXME: this shouldn't be necessary?
-
- void normalize()
- {
- while (m_attoseconds >= ATTOSECONDS_PER_SECOND)
- {
- m_seconds++;
- m_attoseconds -= ATTOSECONDS_PER_SECOND;
- }
- }
-
attoseconds_t attoseconds() const { return m_attoseconds; }
seconds_t seconds() const { return m_seconds; }
diff --git a/src/emu/audit.cpp b/src/emu/audit.cpp
index 7f371ee56c8..e9e4dee63f2 100644
--- a/src/emu/audit.cpp
+++ b/src/emu/audit.cpp
@@ -296,11 +296,11 @@ media_auditor::summary media_auditor::audit_samples()
while (path.next(curpath, samplename))
{
// attempt to access the file (.flac) or (.wav)
- file_error filerr = file.open(curpath.c_str(), ".flac");
- if (filerr != FILERR_NONE)
+ osd_file::error filerr = file.open(curpath.c_str(), ".flac");
+ if (filerr != osd_file::error::NONE)
filerr = file.open(curpath.c_str(), ".wav");
- if (filerr == FILERR_NONE)
+ if (filerr == osd_file::error::NONE)
{
record.set_status(audit_record::STATUS_GOOD, audit_record::SUBSTATUS_GOOD);
found++;
@@ -433,14 +433,14 @@ audit_record *media_auditor::audit_one_rom(const rom_entry *rom)
while (path.next(curpath, record.name()))
{
// open the file if we can
- file_error filerr;
+ osd_file::error filerr;
if (has_crc)
filerr = file.open(curpath.c_str(), crc);
else
filerr = file.open(curpath.c_str());
// if it worked, get the actual length and hashes, then stop
- if (filerr == FILERR_NONE)
+ if (filerr == osd_file::error::NONE)
{
record.set_actual(file.hashes(m_validation), file.size());
break;
diff --git a/src/emu/cheat.cpp b/src/emu/cheat.cpp
index 0a799ca6f13..f9fe6499d61 100644
--- a/src/emu/cheat.cpp
+++ b/src/emu/cheat.cpp
@@ -1171,10 +1171,10 @@ bool cheat_manager::save_all(const char *filename)
{
// open the file with the proper name
emu_file cheatfile(machine().options().cheat_path(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
- file_error filerr = cheatfile.open(filename, ".xml");
+ osd_file::error filerr = cheatfile.open(filename, ".xml");
// if that failed, return nothing
- if (filerr != FILERR_NONE)
+ if (filerr != osd_file::error::NONE)
return false;
// wrap the rest of catch errors
@@ -1372,10 +1372,10 @@ void cheat_manager::load_cheats(const char *filename)
try
{
// open the file with the proper name
- file_error filerr = cheatfile.open(filename, ".xml");
+ osd_file::error filerr = cheatfile.open(filename, ".xml");
// loop over all instrances of the files found in our search paths
- while (filerr == FILERR_NONE)
+ while (filerr == osd_file::error::NONE)
{
osd_printf_verbose("Loading cheats file from %s\n", cheatfile.fullpath());
diff --git a/src/emu/clifront.cpp b/src/emu/clifront.cpp
index 7c6c974cce7..975c3c8f71b 100644
--- a/src/emu/clifront.cpp
+++ b/src/emu/clifront.cpp
@@ -15,7 +15,6 @@
#include "audit.h"
#include "info.h"
#include "unzip.h"
-#include "un7z.h"
#include "validity.h"
#include "sound/samples.h"
#include "cliopts.h"
@@ -266,7 +265,7 @@ int cli_frontend::execute(int argc, char **argv)
m_result = MAMERR_FATALERROR;
}
- _7z_file_cache_clear();
+ util::archive_file::cache_clear();
global_free(manager);
return m_result;
@@ -1000,7 +999,7 @@ void cli_frontend::verifyroms(const char *gamename)
}
// clear out any cached files
- zip_file_cache_clear();
+ util::archive_file::cache_clear();
// return an error if none found
if (matched == 0)
@@ -1092,7 +1091,7 @@ void cli_frontend::verifysamples(const char *gamename)
}
// clear out any cached files
- zip_file_cache_clear();
+ util::archive_file::cache_clear();
// return an error if none found
if (matched == 0)
@@ -1407,7 +1406,7 @@ void cli_frontend::verifysoftware(const char *gamename)
}
// clear out any cached files
- zip_file_cache_clear();
+ util::archive_file::cache_clear();
// return an error if none found
if (matched == 0)
@@ -1529,7 +1528,7 @@ void cli_frontend::verifysoftlist(const char *gamename)
}
// clear out any cached files
- zip_file_cache_clear();
+ util::archive_file::cache_clear();
// return an error if none found
if (matched == 0)
@@ -1618,7 +1617,7 @@ void cli_frontend::execute_commands(const char *exename)
{
// attempt to open the output file
emu_file file(OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
- if (file.open(emulator_info::get_configname(), ".ini") != FILERR_NONE)
+ if (file.open(emulator_info::get_configname(), ".ini") != osd_file::error::NONE)
throw emu_fatalerror("Unable to create file %s.ini\n",emulator_info::get_configname());
// generate the updated INI
@@ -1626,7 +1625,7 @@ void cli_frontend::execute_commands(const char *exename)
ui_options ui_opts;
emu_file file_ui(OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
- if (file_ui.open("ui.ini") != FILERR_NONE)
+ if (file_ui.open("ui.ini") != osd_file::error::NONE)
throw emu_fatalerror("Unable to create file ui.ini\n");
// generate the updated INI
@@ -1758,71 +1757,45 @@ void media_identifier::identify(const char *filename)
}
// if that failed, and the filename ends with .zip, identify as a ZIP file
- if (core_filename_ends_with(filename, ".7z"))
+ if (core_filename_ends_with(filename, ".7z") || core_filename_ends_with(filename, ".zip"))
{
// first attempt to examine it as a valid _7Z file
- _7z_file *_7z = nullptr;
- _7z_error _7zerr = _7z_file_open(filename, &_7z);
- if (_7zerr == _7ZERR_NONE && _7z != nullptr)
+ util::archive_file::ptr archive;
+ util::archive_file::error err;
+ if (core_filename_ends_with(filename, ".7z"))
+ err = util::archive_file::open_7z(filename, archive);
+ else
+ err = util::archive_file::open_zip(filename, archive);
+ if ((err == util::archive_file::error::NONE) && archive)
{
+ std::vector<std::uint8_t> data;
+
// loop over entries in the .7z, skipping empty files and directories
- for (int i = 0; i < _7z->db.db.NumFiles; i++)
+ for (int i = archive->first_file(); i >= 0; i = archive->next_file())
{
- const CSzFileItem *f = _7z->db.db.Files + i;
- _7z->curr_file_idx = i;
- int namelen = SzArEx_GetFileNameUtf16(&_7z->db, i, nullptr);
- std::vector<UINT16> temp(namelen);
- dynamic_buffer temp2(namelen+1);
- UINT8* temp3 = &temp2[0];
- memset(temp3, 0x00, namelen);
- SzArEx_GetFileNameUtf16(&_7z->db, i, &temp[0]);
- // crude, need real UTF16->UTF8 conversion ideally
- for (int j=0;j<namelen;j++)
- {
- temp3[j] = (UINT8)temp[j];
- }
-
- if (!(f->IsDir) && (f->Size != 0))
+ const std::uint64_t length(archive->current_uncompressed_length());
+ if (!archive->current_is_directory() && (length != 0) && (std::uint32_t(length) == length))
{
// decompress data into RAM and identify it
- dynamic_buffer data(f->Size);
- _7zerr = _7z_file_decompress(_7z, &data[0], f->Size);
- if (_7zerr == _7ZERR_NONE)
- identify_data((const char*)&temp2[0], &data[0], f->Size);
+ try
+ {
+ data.resize(std::size_t(length));
+ err = archive->decompress(&data[0], std::uint32_t(length));
+ if (err == util::archive_file::error::NONE)
+ identify_data(archive->current_name().c_str(), &data[0], length);
+ }
+ catch (...)
+ {
+ // resizing the buffer could cause a bad_alloc if archive contains large files
+ }
+ data.clear();
}
}
-
- // close up
- _7z_file_close(_7z);
- }
-
- // clear out any cached files
- _7z_file_cache_clear();
- }
- else if (core_filename_ends_with(filename, ".zip"))
- {
- // first attempt to examine it as a valid ZIP file
- zip_file *zip = nullptr;
- zip_error ziperr = zip_file_open(filename, &zip);
- if (ziperr == ZIPERR_NONE && zip != nullptr)
- {
- // loop over entries in the ZIP, skipping empty files and directories
- for (const zip_file_header *entry = zip_file_first_file(zip); entry != nullptr; entry = zip_file_next_file(zip))
- if (entry->uncompressed_length != 0)
- {
- // decompress data into RAM and identify it
- dynamic_buffer data(entry->uncompressed_length);
- ziperr = zip_file_decompress(zip, &data[0], entry->uncompressed_length);
- if (ziperr == ZIPERR_NONE)
- identify_data(entry->filename, &data[0], entry->uncompressed_length);
- }
-
- // close up
- zip_file_close(zip);
}
// clear out any cached files
- zip_file_cache_clear();
+ archive.reset();
+ util::archive_file::cache_clear();
}
// otherwise, identify as a raw file
@@ -1880,8 +1853,8 @@ void media_identifier::identify_file(const char *name)
// load the file and process if it opens and has a valid length
UINT32 length;
void *data;
- const file_error filerr = util::core_file::load(name, &data, length);
- if (filerr == FILERR_NONE && length > 0)
+ const osd_file::error filerr = util::core_file::load(name, &data, length);
+ if (filerr == osd_file::error::NONE && length > 0)
{
identify_data(name, reinterpret_cast<UINT8 *>(data), length);
osd_free(data);
diff --git a/src/emu/config.cpp b/src/emu/config.cpp
index 691012a4a41..7402341ad32 100644
--- a/src/emu/config.cpp
+++ b/src/emu/config.cpp
@@ -68,9 +68,9 @@ int configuration_manager::load_settings()
{
/* open the config file */
emu_file file(machine().options().ctrlr_path(), OPEN_FLAG_READ);
- file_error filerr = file.open(controller, ".cfg");
+ osd_file::error filerr = file.open(controller, ".cfg");
- if (filerr != FILERR_NONE)
+ if (filerr != osd_file::error::NONE)
throw emu_fatalerror("Could not load controller file %s.cfg", controller);
/* load the XML */
@@ -80,13 +80,13 @@ int configuration_manager::load_settings()
/* next load the defaults file */
emu_file file(machine().options().cfg_directory(), OPEN_FLAG_READ);
- file_error filerr = file.open("default.cfg");
- if (filerr == FILERR_NONE)
+ osd_file::error filerr = file.open("default.cfg");
+ if (filerr == osd_file::error::NONE)
load_xml(file, config_type::CONFIG_TYPE_DEFAULT);
/* finally, load the game-specific file */
filerr = file.open(machine().basename(), ".cfg");
- if (filerr == FILERR_NONE)
+ if (filerr == osd_file::error::NONE)
loaded = load_xml(file, config_type::CONFIG_TYPE_GAME);
/* loop over all registrants and call their final function */
@@ -107,13 +107,13 @@ void configuration_manager::save_settings()
/* save the defaults file */
emu_file file(machine().options().cfg_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
- file_error filerr = file.open("default.cfg");
- if (filerr == FILERR_NONE)
+ osd_file::error filerr = file.open("default.cfg");
+ if (filerr == osd_file::error::NONE)
save_xml(file, config_type::CONFIG_TYPE_DEFAULT);
/* finally, save the game-specific file */
filerr = file.open(machine().basename(), ".cfg");
- if (filerr == FILERR_NONE)
+ if (filerr == osd_file::error::NONE)
save_xml(file, config_type::CONFIG_TYPE_GAME);
/* loop over all registrants and call their final function */
diff --git a/src/emu/debug/debugcmd.cpp b/src/emu/debug/debugcmd.cpp
index 21ed7860a30..2e10b40356e 100644
--- a/src/emu/debug/debugcmd.cpp
+++ b/src/emu/debug/debugcmd.cpp
@@ -1872,6 +1872,7 @@ static void execute_dump(running_machine &machine, int ref, int params, const ch
for (i = offset; i <= endoffset; i += 16)
{
output.clear();
+ output.rdbuf()->clear();
/* print the address */
util::stream_format(output, "%0*X: ", space->logaddrchars(), (UINT32)space->byte_to_address(i));
@@ -2306,6 +2307,7 @@ static void execute_cheatlist(running_machine &machine, int ref, int params, con
{
active_cheat++;
output.clear();
+ output.rdbuf()->clear();
stream_format(
output,
" <cheat desc=\"Possibility %d : %0*X (%0*X)\">\n"
@@ -2516,6 +2518,7 @@ static void execute_dasm(running_machine &machine, int ref, int params, const ch
offs_t tempaddr;
int numbytes = 0;
output.clear();
+ output.rdbuf()->clear();
/* print the address */
stream_format(output, "%0*X: ", space->logaddrchars(), (UINT32)space->byte_to_address(pcbyte));
@@ -2856,9 +2859,9 @@ static void execute_snap(running_machine &machine, int ref, int params, const ch
if (fname.find(".png") == -1)
fname.append(".png");
emu_file file(machine.options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
- file_error filerr = file.open(fname.c_str());
+ osd_file::error filerr = file.open(fname.c_str());
- if (filerr != FILERR_NONE)
+ if (filerr != osd_file::error::NONE)
{
debug_console_printf(machine, "Error creating file '%s'\n", filename);
return;
diff --git a/src/emu/debug/debugcpu.cpp b/src/emu/debug/debugcpu.cpp
index 2b8595b3c30..4e59ed8a652 100644
--- a/src/emu/debug/debugcpu.cpp
+++ b/src/emu/debug/debugcpu.cpp
@@ -332,8 +332,8 @@ bool debug_comment_save(running_machine &machine)
if (found_comments)
{
emu_file file(machine.options().comment_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
- file_error filerr = file.open(machine.basename(), ".cmt");
- if (filerr == FILERR_NONE)
+ osd_file::error filerr = file.open(machine.basename(), ".cmt");
+ if (filerr == osd_file::error::NONE)
{
xml_file_write(root, file);
comments_saved = true;
@@ -361,10 +361,10 @@ bool debug_comment_load(running_machine &machine)
{
// open the file
emu_file file(machine.options().comment_directory(), OPEN_FLAG_READ);
- file_error filerr = file.open(machine.basename(), ".cmt");
+ osd_file::error filerr = file.open(machine.basename(), ".cmt");
// if an error, just return false
- if (filerr != FILERR_NONE)
+ if (filerr != osd_file::error::NONE)
return false;
// wrap in a try/catch to handle errors
diff --git a/src/emu/debug/dvbpoints.cpp b/src/emu/debug/dvbpoints.cpp
index 463fc4dbe08..7da6ac4c399 100644
--- a/src/emu/debug/dvbpoints.cpp
+++ b/src/emu/debug/dvbpoints.cpp
@@ -240,6 +240,7 @@ void debug_view_breakpoints::view_update()
if (m_visible.y > 0)
{
linebuf.clear();
+ linebuf.rdbuf()->clear();
linebuf << "ID";
if (m_sortType == &cIndexAscending) linebuf.put('\\');
else if (m_sortType == &cIndexDescending) linebuf.put('/');
@@ -282,6 +283,7 @@ void debug_view_breakpoints::view_update()
device_debug::breakpoint *const bp = m_buffer[bpi];
linebuf.clear();
+ linebuf.rdbuf()->clear();
util::stream_format(linebuf, "%2X", bp->index());
pad_ostream_to_length(linebuf, tableBreaks[0]);
linebuf.put(bp->enabled() ? 'X' : 'O');
diff --git a/src/emu/debug/dvdisasm.cpp b/src/emu/debug/dvdisasm.cpp
index 6daca107f86..10cb3e75e64 100644
--- a/src/emu/debug/dvdisasm.cpp
+++ b/src/emu/debug/dvdisasm.cpp
@@ -370,6 +370,7 @@ bool debug_view_disasm::recompute(offs_t pc, int startline, int lines)
// allocate disassembly buffer
const auto total_bytes = m_total.x * m_total.y;
+ m_dasm.clear();
m_dasm.reserve(total_bytes).seekp(total_bytes);
// iterate over lines
@@ -387,6 +388,7 @@ bool debug_view_disasm::recompute(offs_t pc, int startline, int lines)
// convert back and set the address of this instruction
m_byteaddress[instr] = pcbyte;
+ m_dasm.clear();
util::stream_format(m_dasm.seekp(base),
source.m_space.is_octal() ? " %0*o " : " %0*X ",
source.m_space.logaddrchars()/2*char_num, source.m_space.byte_to_address(pcbyte));
diff --git a/src/emu/debug/dvwpoints.cpp b/src/emu/debug/dvwpoints.cpp
index 4720f1dbf3c..8b82a6d3de0 100644
--- a/src/emu/debug/dvwpoints.cpp
+++ b/src/emu/debug/dvwpoints.cpp
@@ -266,6 +266,7 @@ void debug_view_watchpoints::view_update()
if (m_visible.y > 0)
{
linebuf.clear();
+ linebuf.rdbuf()->clear();
linebuf << "ID";
if (m_sortType == &cIndexAscending) linebuf.put('\\');
else if (m_sortType == &cIndexDescending) linebuf.put('/');
@@ -317,6 +318,7 @@ void debug_view_watchpoints::view_update()
device_debug::watchpoint *const wp = m_buffer[wpi];
linebuf.clear();
+ linebuf.rdbuf()->clear();
util::stream_format(linebuf, "%2X", wp->index());
pad_ostream_to_length(linebuf, tableBreaks[0]);
linebuf.put(wp->enabled() ? 'X' : 'O');
diff --git a/src/emu/diimage.cpp b/src/emu/diimage.cpp
index 704f7d987e8..f225f6cd444 100644
--- a/src/emu/diimage.cpp
+++ b/src/emu/diimage.cpp
@@ -158,7 +158,7 @@ void device_image_interface::device_compute_hash(hash_collection &hashes, const
image_error_t device_image_interface::set_image_filename(const char *filename)
{
m_image_name = filename;
- zippath_parent(m_working_directory, filename);
+ util::zippath_parent(m_working_directory, filename);
m_basename.assign(m_image_name);
size_t loc1 = m_image_name.find_last_of('\\');
@@ -319,7 +319,7 @@ bool device_image_interface::try_change_working_directory(const char *subdir)
/* did we successfully identify the directory? */
if (success)
- zippath_combine(m_working_directory, m_working_directory.c_str(), subdir);
+ util::zippath_combine(m_working_directory, m_working_directory.c_str(), subdir);
return success;
}
@@ -330,11 +330,8 @@ bool device_image_interface::try_change_working_directory(const char *subdir)
void device_image_interface::setup_working_directory()
{
- char *dst = nullptr;
-
- osd_get_full_path(&dst,".");
/* first set up the working directory to be the starting directory */
- m_working_directory = dst;
+ osd_get_full_path(m_working_directory, ".");
/* now try browsing down to "software" */
if (try_change_working_directory("software"))
@@ -346,7 +343,6 @@ void device_image_interface::setup_working_directory()
gamedrv = driver_list::compatible_with(gamedrv);
}
}
- osd_free(dst);
}
//-------------------------------------------------
@@ -512,14 +508,14 @@ void device_image_interface::battery_load(void *buffer, int length, int fill)
{
assert_always(buffer && (length > 0), "Must specify sensical buffer/length");
- file_error filerr;
+ osd_file::error filerr;
int bytes_read = 0;
std::string fname = std::string(device().machine().system().name).append(PATH_SEPARATOR).append(m_basename_noext.c_str()).append(".nv");
/* try to open the battery file and read it in, if possible */
emu_file file(device().machine().options().nvram_directory(), OPEN_FLAG_READ);
filerr = file.open(fname.c_str());
- if (filerr == FILERR_NONE)
+ if (filerr == osd_file::error::NONE)
bytes_read = file.read(buffer, length);
/* fill remaining bytes (if necessary) */
@@ -530,14 +526,14 @@ void device_image_interface::battery_load(void *buffer, int length, void *def_bu
{
assert_always(buffer && (length > 0), "Must specify sensical buffer/length");
- file_error filerr;
+ osd_file::error filerr;
int bytes_read = 0;
std::string fname = std::string(device().machine().system().name).append(PATH_SEPARATOR).append(m_basename_noext.c_str()).append(".nv");
/* try to open the battery file and read it in, if possible */
emu_file file(device().machine().options().nvram_directory(), OPEN_FLAG_READ);
filerr = file.open(fname.c_str());
- if (filerr == FILERR_NONE)
+ if (filerr == osd_file::error::NONE)
bytes_read = file.read(buffer, length);
/* if no file was present, copy the default battery */
@@ -558,8 +554,8 @@ void device_image_interface::battery_save(const void *buffer, int length)
/* try to open the battery file and write it out, if possible */
emu_file file(device().machine().options().nvram_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
- file_error filerr = file.open(fname.c_str());
- if (filerr == FILERR_NONE)
+ osd_file::error filerr = file.open(fname.c_str());
+ if (filerr == osd_file::error::NONE)
file.write(buffer, length);
}
@@ -615,37 +611,37 @@ image_error_t device_image_interface::load_image_by_path(UINT32 open_flags, cons
std::string revised_path;
/* attempt to read the file */
- auto const filerr = zippath_fopen(path, open_flags, m_file, revised_path);
+ auto const filerr = util::zippath_fopen(path, open_flags, m_file, revised_path);
/* did the open succeed? */
switch(filerr)
{
- case FILERR_NONE:
+ case osd_file::error::NONE:
/* success! */
m_readonly = (open_flags & OPEN_FLAG_WRITE) ? 0 : 1;
m_created = (open_flags & OPEN_FLAG_CREATE) ? 1 : 0;
err = IMAGE_ERROR_SUCCESS;
break;
- case FILERR_NOT_FOUND:
- case FILERR_ACCESS_DENIED:
+ case osd_file::error::NOT_FOUND:
+ case osd_file::error::ACCESS_DENIED:
/* file not found (or otherwise cannot open); continue */
err = IMAGE_ERROR_FILENOTFOUND;
break;
- case FILERR_OUT_OF_MEMORY:
+ case osd_file::error::OUT_OF_MEMORY:
/* out of memory */
err = IMAGE_ERROR_OUTOFMEMORY;
break;
- case FILERR_ALREADY_OPEN:
+ case osd_file::error::ALREADY_OPEN:
/* this shouldn't happen */
err = IMAGE_ERROR_ALREADYOPEN;
break;
- case FILERR_FAILURE:
- case FILERR_TOO_MANY_FILES:
- case FILERR_INVALID_DATA:
+ case osd_file::error::FAILURE:
+ case osd_file::error::TOO_MANY_FILES:
+ case osd_file::error::INVALID_DATA:
default:
/* other errors */
err = IMAGE_ERROR_INTERNAL;
@@ -653,7 +649,7 @@ image_error_t device_image_interface::load_image_by_path(UINT32 open_flags, cons
}
/* if successful, set the file name */
- if (filerr == FILERR_NONE)
+ if (filerr == osd_file::error::NONE)
set_image_filename(revised_path.c_str());
return err;
@@ -667,37 +663,37 @@ int device_image_interface::reopen_for_write(const char *path)
std::string revised_path;
/* attempt to open the file for writing*/
- auto const filerr = zippath_fopen(path, OPEN_FLAG_READ|OPEN_FLAG_WRITE|OPEN_FLAG_CREATE, m_file, revised_path);
+ auto const filerr = util::zippath_fopen(path, OPEN_FLAG_READ|OPEN_FLAG_WRITE|OPEN_FLAG_CREATE, m_file, revised_path);
/* did the open succeed? */
switch(filerr)
{
- case FILERR_NONE:
+ case osd_file::error::NONE:
/* success! */
m_readonly = 0;
m_created = 1;
err = IMAGE_ERROR_SUCCESS;
break;
- case FILERR_NOT_FOUND:
- case FILERR_ACCESS_DENIED:
+ case osd_file::error::NOT_FOUND:
+ case osd_file::error::ACCESS_DENIED:
/* file not found (or otherwise cannot open); continue */
err = IMAGE_ERROR_FILENOTFOUND;
break;
- case FILERR_OUT_OF_MEMORY:
+ case osd_file::error::OUT_OF_MEMORY:
/* out of memory */
err = IMAGE_ERROR_OUTOFMEMORY;
break;
- case FILERR_ALREADY_OPEN:
+ case osd_file::error::ALREADY_OPEN:
/* this shouldn't happen */
err = IMAGE_ERROR_ALREADYOPEN;
break;
- case FILERR_FAILURE:
- case FILERR_TOO_MANY_FILES:
- case FILERR_INVALID_DATA:
+ case osd_file::error::FAILURE:
+ case osd_file::error::TOO_MANY_FILES:
+ case osd_file::error::INVALID_DATA:
default:
/* other errors */
err = IMAGE_ERROR_INTERNAL;
@@ -705,7 +701,7 @@ int device_image_interface::reopen_for_write(const char *path)
}
/* if successful, set the file name */
- if (filerr == FILERR_NONE)
+ if (filerr == osd_file::error::NONE)
set_image_filename(revised_path.c_str());
return err;
@@ -803,7 +799,7 @@ bool device_image_interface::load_software(software_list_device &swlist, const c
/* handle files */
if (ROMENTRY_ISFILE(romp))
{
- file_error filerr = FILERR_NOT_FOUND;
+ osd_file::error filerr = osd_file::error::NOT_FOUND;
UINT32 crc = 0;
bool has_crc = hash_collection(ROM_GETHASHDATA(romp)).crc(crc);
@@ -872,9 +868,9 @@ bool device_image_interface::load_software(software_list_device &swlist, const c
warningcount += verify_length_and_hash(m_mame_file.get(),ROM_GETNAME(romp),ROM_GETLENGTH(romp),hash_collection(ROM_GETHASHDATA(romp)));
- if (filerr == FILERR_NONE)
+ if (filerr == osd_file::error::NONE)
filerr = util::core_file::open_proxy(*m_mame_file, m_file);
- if (filerr == FILERR_NONE)
+ if (filerr == osd_file::error::NONE)
retVal = TRUE;
break; // load first item for start
diff --git a/src/emu/dipty.cpp b/src/emu/dipty.cpp
index bd1a166322f..a2ada675307 100644
--- a/src/emu/dipty.cpp
+++ b/src/emu/dipty.cpp
@@ -12,10 +12,10 @@
#include "osdcore.h"
device_pty_interface::device_pty_interface(const machine_config &mconfig, device_t &device)
- : device_interface(device, "pty"),
- m_pty_master(nullptr),
- m_slave_name(),
- m_opened(false)
+ : device_interface(device, "pty")
+ , m_pty_master()
+ , m_slave_name()
+ , m_opened(false)
{
}
@@ -23,63 +23,57 @@ device_pty_interface::~device_pty_interface()
{
}
-bool device_pty_interface::open(void)
+bool device_pty_interface::open()
{
- if (!m_opened) {
- char buffer[ 128 ];
-
- if (osd_openpty(&m_pty_master , buffer , sizeof(buffer)) == FILERR_NONE) {
+ if (!m_opened)
+ {
+ if (osd_file::openpty(m_pty_master, m_slave_name) == osd_file::error::NONE)
+ {
m_opened = true;
- m_slave_name.assign(buffer);
- } else {
+ }
+ else
+ {
m_opened = false;
- m_pty_master = nullptr;
+ m_pty_master.reset();
}
}
-
return m_opened;
}
-void device_pty_interface::close(void)
+void device_pty_interface::close()
{
- if (m_opened) {
- osd_close(m_pty_master);
- m_opened = false;
- }
+ m_pty_master.reset();
+ m_opened = false;
}
-bool device_pty_interface::is_open(void) const
+bool device_pty_interface::is_open() const
{
return m_opened;
}
ssize_t device_pty_interface::read(UINT8 *rx_chars , size_t count) const
{
- UINT32 actual_bytes;
-
- if (m_opened && osd_read(m_pty_master, rx_chars, 0, count, &actual_bytes) == FILERR_NONE) {
+ std::uint32_t actual_bytes;
+ if (m_opened && m_pty_master->read(rx_chars, 0, count, actual_bytes) == osd_file::error::NONE)
return actual_bytes;
- } else {
+ else
return -1;
- }
}
void device_pty_interface::write(UINT8 tx_char) const
{
- UINT32 actual_bytes;
-
- if (m_opened) {
- osd_write(m_pty_master, &tx_char, 0, 1, &actual_bytes);
- }
+ std::uint32_t actual_bytes;
+ if (m_opened)
+ m_pty_master->write(&tx_char, 0, 1, actual_bytes);
}
-bool device_pty_interface::is_slave_connected(void) const
+bool device_pty_interface::is_slave_connected() const
{
// TODO: really check for slave status
return m_opened;
}
-const char *device_pty_interface::slave_name(void) const
+const char *device_pty_interface::slave_name() const
{
return m_slave_name.c_str();
}
diff --git a/src/emu/dipty.h b/src/emu/dipty.h
index 4efa39fa702..10549e52ccb 100644
--- a/src/emu/dipty.h
+++ b/src/emu/dipty.h
@@ -14,35 +14,35 @@
#error Dont include this file directly; include emu.h instead.
#endif
-#ifndef __DIPTY_H__
-#define __DIPTY_H__
+#ifndef MAME_EMU_DIPTY_H
+#define MAME_EMU_DIPTY_H
class device_pty_interface : public device_interface
{
public:
- // construction/destruction
- device_pty_interface(const machine_config &mconfig, device_t &device);
- virtual ~device_pty_interface();
+ // construction/destruction
+ device_pty_interface(const machine_config &mconfig, device_t &device);
+ virtual ~device_pty_interface();
- bool open(void);
- void close(void);
+ bool open();
+ void close();
- bool is_open(void) const;
+ bool is_open() const;
- ssize_t read(UINT8 *rx_chars , size_t count) const;
- void write(UINT8 tx_char) const;
+ ssize_t read(UINT8 *rx_chars , size_t count) const;
+ void write(UINT8 tx_char) const;
- bool is_slave_connected(void) const;
+ bool is_slave_connected() const;
- const char *slave_name(void) const;
+ const char *slave_name() const;
protected:
- osd_file *m_pty_master;
- std::string m_slave_name;
- bool m_opened;
+ osd_file::ptr m_pty_master;
+ std::string m_slave_name;
+ bool m_opened;
};
// iterator
typedef device_interface_iterator<device_pty_interface> pty_interface_iterator;
-#endif /* __DIPTY_H__ */
+#endif /* MAME_EMU_DIPTY_H */
diff --git a/src/emu/drivers/xtal.h b/src/emu/drivers/xtal.h
index 476db5e99ab..f9e56c65931 100644
--- a/src/emu/drivers/xtal.h
+++ b/src/emu/drivers/xtal.h
@@ -56,6 +56,7 @@ enum
XTAL_2_4576MHz = 2457600, /* Atari ST MFP, NEC PC-98xx */
XTAL_2_5MHz = 2500000, /* Janken Man units */
XTAL_3MHz = 3000000, /* Probably only used to drive 68705 or similar MCUs on 80's Taito PCBs */
+ XTAL_3_072MHz = 3072000, /* INS 8520 input clock rate */
XTAL_3_12MHz = 3120000, /* SP0250 clock on Gottlieb games */
XTAL_3_5MHz = 3500000, /* Reported by Commodore 65 document, true xtal unchecked on PCB */
XTAL_3_52128MHz = 3521280, /* RCA COSMAC VIP */
diff --git a/src/emu/emuopts.cpp b/src/emu/emuopts.cpp
index 332c9c2d787..f8127e28dbb 100644
--- a/src/emu/emuopts.cpp
+++ b/src/emu/emuopts.cpp
@@ -568,8 +568,8 @@ bool emu_options::parse_one_ini(const char *basename, int priority, std::string
// open the file; if we fail, that's ok
emu_file file(ini_path(), OPEN_FLAG_READ);
- file_error filerr = file.open(basename, ".ini");
- if (filerr != FILERR_NONE)
+ osd_file::error filerr = file.open(basename, ".ini");
+ if (filerr != osd_file::error::NONE)
return false;
// parse the file
diff --git a/src/emu/fileio.cpp b/src/emu/fileio.cpp
index 79bf746fbfa..812f2a7007f 100644
--- a/src/emu/fileio.cpp
+++ b/src/emu/fileio.cpp
@@ -10,7 +10,6 @@
#include "emu.h"
#include "unzip.h"
-#include "un7z.h"
#include "fileio.h"
@@ -146,8 +145,6 @@ emu_file::emu_file(UINT32 openflags)
m_openflags(openflags),
m_zipfile(nullptr),
m_ziplength(0),
- m__7zfile(nullptr),
- m__7zlength(0),
m_remove_on_close(false),
m_restrict_to_mediapath(false)
{
@@ -164,8 +161,6 @@ emu_file::emu_file(const char *searchpath, UINT32 openflags)
m_openflags(openflags),
m_zipfile(nullptr),
m_ziplength(0),
- m__7zfile(nullptr),
- m__7zlength(0),
m_remove_on_close(false),
m_restrict_to_mediapath(false)
{
@@ -228,12 +223,6 @@ hash_collection &emu_file::hashes(const char *types)
return m_hashes;
// if we have ZIP data, just hash that directly
- if (!m__7zdata.empty())
- {
- m_hashes.compute(&m__7zdata[0], m__7zdata.size(), needed.c_str());
- return m_hashes;
- }
-
if (!m_zipdata.empty())
{
m_hashes.compute(&m_zipdata[0], m_zipdata.size(), needed.c_str());
@@ -255,7 +244,7 @@ hash_collection &emu_file::hashes(const char *types)
// open - open a file by searching paths
//-------------------------------------------------
-file_error emu_file::open(const char *name)
+osd_file::error emu_file::open(const char *name)
{
// remember the filename and CRC info
m_filename = name;
@@ -267,28 +256,28 @@ file_error emu_file::open(const char *name)
return open_next();
}
-file_error emu_file::open(const char *name1, const char *name2)
+osd_file::error emu_file::open(const char *name1, const char *name2)
{
// concatenate the strings and do a standard open
std::string name = std::string(name1).append(name2);
return open(name.c_str());
}
-file_error emu_file::open(const char *name1, const char *name2, const char *name3)
+osd_file::error emu_file::open(const char *name1, const char *name2, const char *name3)
{
// concatenate the strings and do a standard open
std::string name = std::string(name1).append(name2).append(name3);
return open(name.c_str());
}
-file_error emu_file::open(const char *name1, const char *name2, const char *name3, const char *name4)
+osd_file::error emu_file::open(const char *name1, const char *name2, const char *name3, const char *name4)
{
// concatenate the strings and do a standard open
std::string name = std::string(name1).append(name2).append(name3).append(name4);
return open(name.c_str());
}
-file_error emu_file::open(const char *name, UINT32 crc)
+osd_file::error emu_file::open(const char *name, UINT32 crc)
{
// remember the filename and CRC info
m_filename = name;
@@ -300,21 +289,21 @@ file_error emu_file::open(const char *name, UINT32 crc)
return open_next();
}
-file_error emu_file::open(const char *name1, const char *name2, UINT32 crc)
+osd_file::error emu_file::open(const char *name1, const char *name2, UINT32 crc)
{
// concatenate the strings and do a standard open
std::string name = std::string(name1).append(name2);
return open(name.c_str(), crc);
}
-file_error emu_file::open(const char *name1, const char *name2, const char *name3, UINT32 crc)
+osd_file::error emu_file::open(const char *name1, const char *name2, const char *name3, UINT32 crc)
{
// concatenate the strings and do a standard open
std::string name = std::string(name1).append(name2).append(name3);
return open(name.c_str(), crc);
}
-file_error emu_file::open(const char *name1, const char *name2, const char *name3, const char *name4, UINT32 crc)
+osd_file::error emu_file::open(const char *name1, const char *name2, const char *name3, const char *name4, UINT32 crc)
{
// concatenate the strings and do a standard open
std::string name = std::string(name1).append(name2).append(name3).append(name4);
@@ -327,19 +316,19 @@ file_error emu_file::open(const char *name1, const char *name2, const char *name
// the filename by iterating over paths
//-------------------------------------------------
-file_error emu_file::open_next()
+osd_file::error emu_file::open_next()
{
// if we're open from a previous attempt, close up now
if (m_file != nullptr)
close();
// loop over paths
- file_error filerr = FILERR_NOT_FOUND;
+ osd_file::error filerr = osd_file::error::NOT_FOUND;
while (m_iterator.next(m_fullpath, m_filename.c_str()))
{
// attempt to open the file directly
- filerr = util::core_file::open(m_fullpath.c_str(), m_openflags, m_file);
- if (filerr == FILERR_NONE)
+ filerr = util::core_file::open(m_fullpath, m_openflags, m_file);
+ if (filerr == osd_file::error::NONE)
break;
// if we're opening for read-only we have other options
@@ -348,13 +337,13 @@ file_error emu_file::open_next()
std::string tempfullpath = m_fullpath;
filerr = attempt_zipped();
- if (filerr == FILERR_NONE)
+ if (filerr == osd_file::error::NONE)
break;
m_fullpath = tempfullpath;
filerr = attempt__7zped();
- if (filerr == FILERR_NONE)
+ if (filerr == osd_file::error::NONE)
break;
}
}
@@ -367,7 +356,7 @@ file_error emu_file::open_next()
// just an array of data in RAM
//-------------------------------------------------
-file_error emu_file::open_ram(const void *data, UINT32 length)
+osd_file::error emu_file::open_ram(const void *data, UINT32 length)
{
// set a fake filename and CRC
m_filename = "RAM";
@@ -386,21 +375,13 @@ file_error emu_file::open_ram(const void *data, UINT32 length)
void emu_file::close()
{
// close files and free memory
- if (m__7zfile != nullptr)
- _7z_file_close(m__7zfile);
- m__7zfile = nullptr;
-
- if (m_zipfile != nullptr)
- zip_file_close(m_zipfile);
- m_zipfile = nullptr;
-
+ m_zipfile.reset();
m_file.reset();
- m__7zdata.clear();
m_zipdata.clear();
if (m_remove_on_close)
- osd_rmfile(m_fullpath.c_str());
+ osd_file::remove(m_fullpath);
m_remove_on_close = false;
// reset our hashes and path as well
@@ -415,7 +396,7 @@ void emu_file::close()
// compression, or up to 9 for max compression
//-------------------------------------------------
-file_error emu_file::compress(int level)
+osd_file::error emu_file::compress(int level)
{
return m_file->compress(level);
}
@@ -429,10 +410,7 @@ file_error emu_file::compress(int level)
bool emu_file::compressed_file_ready(void)
{
// load the ZIP file now if we haven't yet
- if (m__7zfile != nullptr && load__7zped_file() != FILERR_NONE)
- return true;
-
- if (m_zipfile != nullptr && load_zipped_file() != FILERR_NONE)
+ if (m_zipfile && (load_zipped_file() != osd_file::error::NONE))
return true;
return false;
@@ -499,9 +477,6 @@ bool emu_file::eof()
UINT64 emu_file::size()
{
// use the ZIP length if present
- if (m__7zfile != nullptr)
- return m__7zlength;
-
if (m_zipfile != nullptr)
return m_ziplength;
@@ -657,7 +632,7 @@ bool emu_file::part_of_mediapath(std::string path)
// attempt_zipped - attempt to open a ZIPped file
//-------------------------------------------------
-file_error emu_file::attempt_zipped()
+osd_file::error emu_file::attempt_zipped()
{
std::string filename;
@@ -667,11 +642,11 @@ file_error emu_file::attempt_zipped()
// find the final path separator
int dirsep = m_fullpath.find_last_of(PATH_SEPARATOR[0]);
if (dirsep == -1)
- return FILERR_NOT_FOUND;
+ return osd_file::error::NOT_FOUND;
if (restrict_to_mediapath())
if ( !part_of_mediapath(m_fullpath) )
- return FILERR_NOT_FOUND;
+ return osd_file::error::NOT_FOUND;
// insert the part from the right of the separator into the head of the filename
if (filename.length() > 0)
@@ -682,117 +657,51 @@ file_error emu_file::attempt_zipped()
m_fullpath = m_fullpath.substr(0, dirsep).append(".zip");
// attempt to open the ZIP file
- zip_file *zip;
- zip_error ziperr = zip_file_open(m_fullpath.c_str(), &zip);
+ util::archive_file::ptr zip;
+ util::archive_file::error ziperr = util::archive_file::open_zip(m_fullpath, zip);
// chop the .zip back off the filename before continuing
m_fullpath = m_fullpath.substr(0, dirsep);
// if we failed to open this file, continue scanning
- if (ziperr != ZIPERR_NONE)
+ if (ziperr != util::archive_file::error::NONE)
continue;
+ int header = -1;
+
// see if we can find a file with the right name and (if available) crc
- const zip_file_header *header;
- for (header = zip_file_first_file(zip); header != nullptr; header = zip_file_next_file(zip))
- if (zip_filename_match(*header, filename) && (!(m_openflags & OPEN_FLAG_HAS_CRC) || header->crc == m_crc))
- break;
+ if (m_openflags & OPEN_FLAG_HAS_CRC) header = zip->search(m_crc, filename);
// if that failed, look for a file with the right crc, but the wrong filename
- if (header == nullptr && (m_openflags & OPEN_FLAG_HAS_CRC))
- for (header = zip_file_first_file(zip); header != nullptr; header = zip_file_next_file(zip))
- if (header->crc == m_crc && !zip_header_is_path(*header))
- break;
+ if (header < 0 && (m_openflags & OPEN_FLAG_HAS_CRC)) header = zip->search(m_crc);
// if that failed, look for a file with the right name; reporting a bad checksum
// is more helpful and less confusing than reporting "rom not found"
- if (header == nullptr)
- for (header = zip_file_first_file(zip); header != nullptr; header = zip_file_next_file(zip))
- if (zip_filename_match(*header, filename))
- break;
+ if (header < 0) header = zip->search(filename);
// if we got it, read the data
- if (header != nullptr)
+ if (header >= 0)
{
- m_zipfile = zip;
- m_ziplength = header->uncompressed_length;
+ m_zipfile = std::move(zip);
+ m_ziplength = m_zipfile->current_uncompressed_length();
// build a hash with just the CRC
m_hashes.reset();
- m_hashes.add_crc(header->crc);
- return (m_openflags & OPEN_FLAG_NO_PRELOAD) ? FILERR_NONE : load_zipped_file();
+ m_hashes.add_crc(m_zipfile->current_crc());
+ return (m_openflags & OPEN_FLAG_NO_PRELOAD) ? osd_file::error::NONE : load_zipped_file();
}
// close up the ZIP file and try the next level
- zip_file_close(zip);
- }
-}
-
-
-//-------------------------------------------------
-// load_zipped_file - load a ZIPped file
-//-------------------------------------------------
-
-file_error emu_file::load_zipped_file()
-{
- assert(m_file == nullptr);
- assert(m_zipdata.empty());
- assert(m_zipfile != nullptr);
-
- // allocate some memory
- m_zipdata.resize(m_ziplength);
-
- // read the data into our buffer and return
- zip_error ziperr = zip_file_decompress(m_zipfile, &m_zipdata[0], m_zipdata.size());
- if (ziperr != ZIPERR_NONE)
- {
- m_zipdata.clear();
- return FILERR_FAILURE;
- }
-
- // convert to RAM file
- file_error filerr = util::core_file::open_ram(&m_zipdata[0], m_zipdata.size(), m_openflags, m_file);
- if (filerr != FILERR_NONE)
- {
- m_zipdata.clear();
- return FILERR_FAILURE;
+ zip.reset();
}
-
- // close out the ZIP file
- zip_file_close(m_zipfile);
- m_zipfile = nullptr;
- return FILERR_NONE;
-}
-
-
-//-------------------------------------------------
-// zip_filename_match - compare zip filename
-// to expected filename, ignoring any directory
-//-------------------------------------------------
-
-bool emu_file::zip_filename_match(const zip_file_header &header, const std::string &filename)
-{
- const char *zipfile = header.filename + header.filename_length - filename.length();
- return (zipfile >= header.filename && core_stricmp(filename.c_str(),zipfile) == 0 && (zipfile == header.filename || zipfile[-1] == '/'));
}
//-------------------------------------------------
-// zip_header_is_path - check whether filename
-// in header is a path
-//-------------------------------------------------
-
-bool emu_file::zip_header_is_path(const zip_file_header &header)
-{
- const char *zipfile = header.filename + header.filename_length - 1;
- return (zipfile >= header.filename && zipfile[0] == '/');
-}
-
-//-------------------------------------------------
// attempt__7zped - attempt to open a .7z file
//-------------------------------------------------
-file_error emu_file::attempt__7zped()
+osd_file::error emu_file::attempt__7zped()
{
std::string filename;
@@ -802,11 +711,11 @@ file_error emu_file::attempt__7zped()
// find the final path separator
int dirsep = m_fullpath.find_last_of(PATH_SEPARATOR[0]);
if (dirsep == -1)
- return FILERR_NOT_FOUND;
+ return osd_file::error::NOT_FOUND;
if (restrict_to_mediapath())
if ( !part_of_mediapath(m_fullpath) )
- return FILERR_NOT_FOUND;
+ return osd_file::error::NOT_FOUND;
// insert the part from the right of the separator into the head of the filename
if (filename.length() > 0)
@@ -817,78 +726,75 @@ file_error emu_file::attempt__7zped()
m_fullpath = m_fullpath.substr(0, dirsep).append(".7z");
// attempt to open the _7Z file
- _7z_file *_7z;
- _7z_error _7zerr = _7z_file_open(m_fullpath.c_str(), &_7z);
+ util::archive_file::ptr _7z;
+ util::archive_file::error _7zerr = util::archive_file::open_7z(m_fullpath, _7z);
// chop the ._7z back off the filename before continuing
m_fullpath = m_fullpath.substr(0, dirsep);
// if we failed to open this file, continue scanning
- if (_7zerr != _7ZERR_NONE)
+ if (_7zerr != util::archive_file::error::NONE)
continue;
int fileno = -1;
// see if we can find a file with the right name and (if available) crc
- if (m_openflags & OPEN_FLAG_HAS_CRC) fileno = _7z_search_crc_match(_7z, m_crc, filename.c_str(), filename.length(), true, true);
+ if (m_openflags & OPEN_FLAG_HAS_CRC) fileno = _7z->search(m_crc, filename);
// if that failed, look for a file with the right crc, but the wrong filename
- if (fileno==-1)
- if (m_openflags & OPEN_FLAG_HAS_CRC) fileno = _7z_search_crc_match(_7z, m_crc, filename.c_str(), filename.length(), true, false);
+ if ((fileno < 0) && (m_openflags & OPEN_FLAG_HAS_CRC)) fileno = _7z->search(m_crc);
// if that failed, look for a file with the right name; reporting a bad checksum
// is more helpful and less confusing than reporting "rom not found"
- if (fileno==-1)
- fileno = _7z_search_crc_match(_7z, m_crc, filename.c_str(), filename.length(), false, true);
+ if (fileno < 0) fileno = _7z->search(filename);
- if (fileno != -1)
+ if (fileno >= 0)
{
- m__7zfile = _7z;
- m__7zlength = _7z->uncompressed_length;
+ m_zipfile = std::move(_7z);
+ m_ziplength = m_zipfile->current_uncompressed_length();
// build a hash with just the CRC
m_hashes.reset();
- m_hashes.add_crc(_7z->crc);
- return (m_openflags & OPEN_FLAG_NO_PRELOAD) ? FILERR_NONE : load__7zped_file();
+ m_hashes.add_crc(m_zipfile->current_crc());
+ return (m_openflags & OPEN_FLAG_NO_PRELOAD) ? osd_file::error::NONE : load_zipped_file();
}
// close up the _7Z file and try the next level
- _7z_file_close(_7z);
+ _7z.reset();
}
}
//-------------------------------------------------
-// load__7zped_file - load a _7Zped file
+// load_zipped_file - load a ZIPped file
//-------------------------------------------------
-file_error emu_file::load__7zped_file()
+osd_file::error emu_file::load_zipped_file()
{
assert(m_file == nullptr);
- assert(m__7zdata.empty());
- assert(m__7zfile != nullptr);
+ assert(m_zipdata.empty());
+ assert(m_zipfile);
// allocate some memory
- m__7zdata.resize(m__7zlength);
+ m_zipdata.resize(m_ziplength);
// read the data into our buffer and return
- _7z_error _7zerr = _7z_file_decompress(m__7zfile, &m__7zdata[0], m__7zdata.size());
- if (_7zerr != _7ZERR_NONE)
+ auto const ziperr = m_zipfile->decompress(&m_zipdata[0], m_zipdata.size());
+ if (ziperr != util::archive_file::error::NONE)
{
- m__7zdata.clear();
- return FILERR_FAILURE;
+ m_zipdata.clear();
+ return osd_file::error::FAILURE;
}
// convert to RAM file
- file_error filerr = util::core_file::open_ram(&m__7zdata[0], m__7zdata.size(), m_openflags, m_file);
- if (filerr != FILERR_NONE)
+ osd_file::error filerr = util::core_file::open_ram(&m_zipdata[0], m_zipdata.size(), m_openflags, m_file);
+ if (filerr != osd_file::error::NONE)
{
- m__7zdata.clear();
- return FILERR_FAILURE;
+ m_zipdata.clear();
+ return osd_file::error::FAILURE;
}
- // close out the _7Z file
- _7z_file_close(m__7zfile);
- m__7zfile = nullptr;
- return FILERR_NONE;
+ // close out the ZIP file
+ m_zipfile.reset();
+ return osd_file::error::NONE;
}
diff --git a/src/emu/fileio.h b/src/emu/fileio.h
index 22f36f5362e..a29372f071d 100644
--- a/src/emu/fileio.h
+++ b/src/emu/fileio.h
@@ -10,8 +10,8 @@
#pragma once
-#ifndef __FILEIO_H__
-#define __FILEIO_H__
+#ifndef MAME_EMU_FILEIO_H
+#define MAME_EMU_FILEIO_H
#include "corefile.h"
#include "hash.h"
@@ -26,11 +26,7 @@
//**************************************************************************
// forward declarations
-struct zip_file_header;
-struct zip_file;
-
-struct _7z_file_header;
-struct _7z_file;
+namespace util { class archive_file; }
// ======================> path_iterator
@@ -105,20 +101,20 @@ public:
void set_restrict_to_mediapath(bool rtmp = true) { m_restrict_to_mediapath = rtmp; }
// open/close
- file_error open(const char *name);
- file_error open(const char *name1, const char *name2);
- file_error open(const char *name1, const char *name2, const char *name3);
- file_error open(const char *name1, const char *name2, const char *name3, const char *name4);
- file_error open(const char *name, UINT32 crc);
- file_error open(const char *name1, const char *name2, UINT32 crc);
- file_error open(const char *name1, const char *name2, const char *name3, UINT32 crc);
- file_error open(const char *name1, const char *name2, const char *name3, const char *name4, UINT32 crc);
- file_error open_next();
- file_error open_ram(const void *data, UINT32 length);
+ osd_file::error open(const char *name);
+ osd_file::error open(const char *name1, const char *name2);
+ osd_file::error open(const char *name1, const char *name2, const char *name3);
+ osd_file::error open(const char *name1, const char *name2, const char *name3, const char *name4);
+ osd_file::error open(const char *name, UINT32 crc);
+ osd_file::error open(const char *name1, const char *name2, UINT32 crc);
+ osd_file::error open(const char *name1, const char *name2, const char *name3, UINT32 crc);
+ osd_file::error open(const char *name1, const char *name2, const char *name3, const char *name4, UINT32 crc);
+ osd_file::error open_next();
+ osd_file::error open_ram(const void *data, UINT32 length);
void close();
// control
- file_error compress(int compress);
+ osd_file::error compress(int compress);
// position
int seek(INT64 offset, int whence);
@@ -148,13 +144,9 @@ private:
bool compressed_file_ready(void);
// internal helpers
- file_error attempt_zipped();
- file_error load_zipped_file();
- bool zip_filename_match(const zip_file_header &header, const std::string &filename);
- bool zip_header_is_path(const zip_file_header &header);
-
- file_error attempt__7zped();
- file_error load__7zped_file();
+ osd_file::error attempt_zipped();
+ osd_file::error attempt__7zped();
+ osd_file::error load_zipped_file();
// internal state
std::string m_filename; // original filename provided
@@ -166,17 +158,12 @@ private:
UINT32 m_openflags; // flags we used for the open
hash_collection m_hashes; // collection of hashes
- zip_file * m_zipfile; // ZIP file pointer
+ std::unique_ptr<util::archive_file> m_zipfile; // ZIP file pointer
dynamic_buffer m_zipdata; // ZIP file data
UINT64 m_ziplength; // ZIP file length
- _7z_file * m__7zfile; // 7Z file pointer
- dynamic_buffer m__7zdata; // 7Z file data
- UINT64 m__7zlength; // 7Z file length
-
bool m_remove_on_close; // flag: remove the file when closing
- bool m_restrict_to_mediapath; // flag: restrict to paths inside the media-path
+ bool m_restrict_to_mediapath; // flag: restrict to paths inside the media-path
};
-
-#endif /* __FILEIO_H__ */
+#endif // MAME_EMU_FILEIO_H
diff --git a/src/emu/hashfile.cpp b/src/emu/hashfile.cpp
index 557d9c28d5f..ca668e1dfae 100644
--- a/src/emu/hashfile.cpp
+++ b/src/emu/hashfile.cpp
@@ -430,7 +430,7 @@ hash_file *hashfile_open(emu_options &options, const char *sysname, int is_prelo
{
hash_file *hashfile = nullptr;
object_pool *pool = nullptr;
- file_error filerr;
+ osd_file::error filerr;
/* create a pool for this hash file */
pool = pool_alloc_lib(error_proc);
@@ -450,7 +450,7 @@ hash_file *hashfile_open(emu_options &options, const char *sysname, int is_prelo
/* open a file */
hashfile->file = global_alloc(emu_file(options.hash_path(), OPEN_FLAG_READ));
filerr = hashfile->file->open(sysname, ".hsi");
- if (filerr != FILERR_NONE)
+ if (filerr != osd_file::error::NONE)
{
global_free(hashfile->file);
hashfile->file = nullptr;
diff --git a/src/emu/image.cpp b/src/emu/image.cpp
index 76de04714fb..f9f6111a292 100644
--- a/src/emu/image.cpp
+++ b/src/emu/image.cpp
@@ -155,8 +155,8 @@ int image_manager::write_config(emu_options &options, const char *filename, cons
}
emu_file file(options.ini_path(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE);
- file_error filerr = file.open(filename);
- if (filerr == FILERR_NONE)
+ osd_file::error filerr = file.open(filename);
+ if (filerr == osd_file::error::NONE)
{
std::string inistring = options.output_ini();
file.puts(inistring.c_str());
diff --git a/src/emu/inpttype.h b/src/emu/inpttype.h
index e560fc5af6c..ff2ffbc5749 100644
--- a/src/emu/inpttype.h
+++ b/src/emu/inpttype.h
@@ -100,14 +100,14 @@ void construct_core_types_P1_mahjong(simple_list<input_type_entry> &typelist)
void construct_core_types_P1_hanafuda(simple_list<input_type_entry> &typelist)
{
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, HANAFUDA_A, "P1 Hanafuda A / 1", input_seq(KEYCODE_A) )
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, HANAFUDA_B, "P1 Hanafuda B / 2", input_seq(KEYCODE_B) )
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, HANAFUDA_C, "P1 Hanafuda C / 3", input_seq(KEYCODE_C) )
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, HANAFUDA_D, "P1 Hanafuda D / 4", input_seq(KEYCODE_D) )
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, HANAFUDA_E, "P1 Hanafuda E / 5", input_seq(KEYCODE_E) )
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, HANAFUDA_F, "P1 Hanafuda F / 6", input_seq(KEYCODE_F) )
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, HANAFUDA_G, "P1 Hanafuda G / 7", input_seq(KEYCODE_G) )
- INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, HANAFUDA_H, "P1 Hanafuda H / 8", input_seq(KEYCODE_H) )
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, HANAFUDA_A, "P1 Hanafuda A/1", input_seq(KEYCODE_A) )
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, HANAFUDA_B, "P1 Hanafuda B/2", input_seq(KEYCODE_B) )
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, HANAFUDA_C, "P1 Hanafuda C/3", input_seq(KEYCODE_C) )
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, HANAFUDA_D, "P1 Hanafuda D/4", input_seq(KEYCODE_D) )
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, HANAFUDA_E, "P1 Hanafuda E/5", input_seq(KEYCODE_E) )
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, HANAFUDA_F, "P1 Hanafuda F/6", input_seq(KEYCODE_F) )
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, HANAFUDA_G, "P1 Hanafuda G/7", input_seq(KEYCODE_G) )
+ INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, HANAFUDA_H, "P1 Hanafuda H/8", input_seq(KEYCODE_H) )
INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, HANAFUDA_YES, "P1 Hanafuda Yes", input_seq(KEYCODE_M) )
INPUT_PORT_DIGITAL_TYPE( 1, PLAYER1, HANAFUDA_NO, "P1 Hanafuda No", input_seq(KEYCODE_N) )
}
@@ -219,14 +219,14 @@ void construct_core_types_P2_mahjong(simple_list<input_type_entry> &typelist)
void construct_core_types_P2_hanafuda(simple_list<input_type_entry> &typelist)
{
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, HANAFUDA_A, "P2 Hanafuda A / 1", input_seq() )
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, HANAFUDA_B, "P2 Hanafuda B / 2", input_seq() )
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, HANAFUDA_C, "P2 Hanafuda C / 3", input_seq() )
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, HANAFUDA_D, "P2 Hanafuda D / 4", input_seq() )
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, HANAFUDA_E, "P2 Hanafuda E / 5", input_seq() )
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, HANAFUDA_F, "P2 Hanafuda F / 6", input_seq() )
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, HANAFUDA_G, "P2 Hanafuda G / 7", input_seq() )
- INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, HANAFUDA_H, "P2 Hanafuda H / 8", input_seq() )
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, HANAFUDA_A, "P2 Hanafuda A/1", input_seq() )
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, HANAFUDA_B, "P2 Hanafuda B/2", input_seq() )
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, HANAFUDA_C, "P2 Hanafuda C/3", input_seq() )
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, HANAFUDA_D, "P2 Hanafuda D/4", input_seq() )
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, HANAFUDA_E, "P2 Hanafuda E/5", input_seq() )
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, HANAFUDA_F, "P2 Hanafuda F/6", input_seq() )
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, HANAFUDA_G, "P2 Hanafuda G/7", input_seq() )
+ INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, HANAFUDA_H, "P2 Hanafuda H/8", input_seq() )
INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, HANAFUDA_YES, "P2 Hanafuda Yes", input_seq() )
INPUT_PORT_DIGITAL_TYPE( 2, PLAYER2, HANAFUDA_NO, "P2 Hanafuda No", input_seq() )
}
@@ -482,6 +482,8 @@ void construct_core_types_tilt(simple_list<input_type_entry> &typelist)
void construct_core_types_other(simple_list<input_type_entry> &typelist)
{
+ INPUT_PORT_DIGITAL_TYPE( 0, OTHER, POWER_ON, "Power On", input_seq(KEYCODE_F1) )
+ INPUT_PORT_DIGITAL_TYPE( 0, OTHER, POWER_OFF, "Power Off", input_seq(KEYCODE_F2) )
INPUT_PORT_DIGITAL_TYPE( 0, OTHER, SERVICE, "Service", input_seq(KEYCODE_F2) )
INPUT_PORT_DIGITAL_TYPE( 0, OTHER, TILT, "Tilt", input_seq(KEYCODE_T) )
INPUT_PORT_DIGITAL_TYPE( 0, OTHER, INTERLOCK, "Door Interlock", input_seq() )
@@ -718,7 +720,7 @@ void construct_core_types_UI(simple_list<input_type_entry> &typelist)
INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_CONFIGURE, "Config Menu", input_seq(KEYCODE_TAB) )
INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_PAUSE, "Pause", input_seq(KEYCODE_P, input_seq::not_code, KEYCODE_LSHIFT, input_seq::not_code, KEYCODE_RSHIFT) )
INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_PAUSE_SINGLE, "Pause - Single Step", input_seq(KEYCODE_P, KEYCODE_LSHIFT, input_seq::or_code, KEYCODE_P, KEYCODE_RSHIFT) )
- INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_RESET_MACHINE, "Reset Game", input_seq(KEYCODE_F3, KEYCODE_LSHIFT) )
+ INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_RESET_MACHINE, "Reset Machine", input_seq(KEYCODE_F3, KEYCODE_LSHIFT) )
INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_SOFT_RESET, "Soft Reset", input_seq(KEYCODE_F3, input_seq::not_code, KEYCODE_LSHIFT) )
INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_SHOW_GFX, "Show Gfx", input_seq(KEYCODE_F4) )
INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_FRAMESKIP_DEC, "Frameskip Dec", input_seq(KEYCODE_F8) )
@@ -734,7 +736,7 @@ void construct_core_types_UI(simple_list<input_type_entry> &typelist)
INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_UP, "UI Up", input_seq(KEYCODE_UP, input_seq::or_code, JOYCODE_Y_UP_SWITCH_INDEXED(0)) )
INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_DOWN, "UI Down", input_seq(KEYCODE_DOWN, input_seq::or_code, JOYCODE_Y_DOWN_SWITCH_INDEXED(0)) )
INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_LEFT, "UI Left", input_seq(KEYCODE_LEFT, input_seq::or_code, JOYCODE_X_LEFT_SWITCH_INDEXED(0)) )
- INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_RIGHT, "UI Right", input_seq(KEYCODE_RIGHT, input_seq::not_code, KEYCODE_LCONTROL, input_seq::or_code, JOYCODE_X_RIGHT_SWITCH_INDEXED(0), input_seq::not_code, KEYCODE_LCONTROL) )
+ INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_RIGHT, "UI Right", input_seq(KEYCODE_RIGHT, input_seq::or_code, JOYCODE_X_RIGHT_SWITCH_INDEXED(0)) )
INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_HOME, "UI Home", input_seq(KEYCODE_HOME) )
INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_END, "UI End", input_seq(KEYCODE_END) )
INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_PAGE_UP, "UI Page Up", input_seq(KEYCODE_PGUP) )
@@ -764,7 +766,7 @@ void construct_core_types_UI(simple_list<input_type_entry> &typelist)
INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_RIGHT_PANEL, nullptr, input_seq() )
INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_UP_PANEL, nullptr, input_seq() )
INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_DOWN_PANEL, nullptr, input_seq() )
- INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_EXPORT, "UI Export list to xml", input_seq(KEYCODE_LALT, KEYCODE_E) )
+ INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_EXPORT, "UI Export list", input_seq(KEYCODE_LALT, KEYCODE_E) )
INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_AUDIT_FAST, "UI Audit Unavailable", input_seq(KEYCODE_F1, input_seq::not_code, KEYCODE_LSHIFT) )
INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_AUDIT_ALL, "UI Audit All", input_seq(KEYCODE_F1, KEYCODE_LSHIFT) )
}
diff --git a/src/emu/ioport.cpp b/src/emu/ioport.cpp
index 2b00cabb94b..1ca4d477575 100644
--- a/src/emu/ioport.cpp
+++ b/src/emu/ioport.cpp
@@ -3407,8 +3407,8 @@ time_t ioport_manager::playback_init()
return 0;
// open the playback file
- file_error filerr = m_playback_file.open(filename);
- assert_always(filerr == FILERR_NONE, "Failed to open file for playback");
+ osd_file::error filerr = m_playback_file.open(filename);
+ assert_always(filerr == osd_file::error::NONE, "Failed to open file for playback");
// read the header and verify that it is a modern version; if not, print an error
inp_header header;
@@ -3582,8 +3582,8 @@ void ioport_manager::record_init()
return;
// open the record file
- file_error filerr = m_record_file.open(filename);
- assert_always(filerr == FILERR_NONE, "Failed to open file for recording");
+ osd_file::error filerr = m_record_file.open(filename);
+ assert_always(filerr == osd_file::error::NONE, "Failed to open file for recording");
// get the base time
system_time systime;
@@ -3625,8 +3625,8 @@ void ioport_manager::timecode_init() {
filename.append(record_filename).append(".timecode");
osd_printf_info("Record input timecode file: %s\n", record_filename);
- file_error filerr = m_timecode_file.open(filename.c_str());
- assert_always(filerr == FILERR_NONE, "Failed to open file for input timecode recording");
+ osd_file::error filerr = m_timecode_file.open(filename.c_str());
+ assert_always(filerr == osd_file::error::NONE, "Failed to open file for input timecode recording");
m_timecode_file.puts(std::string("# ==========================================\n").c_str());
m_timecode_file.puts(std::string("# TIMECODE FILE FOR VIDEO PREVIEW GENERATION\n").c_str());
diff --git a/src/emu/ioport.h b/src/emu/ioport.h
index 8d16f7e4fa8..c7fbd8ddd79 100644
--- a/src/emu/ioport.h
+++ b/src/emu/ioport.h
@@ -134,15 +134,17 @@ enum ioport_type
IPT_TILT4,
// misc other digital inputs
+ IPT_POWER_ON,
+ IPT_POWER_OFF,
IPT_SERVICE,
IPT_TILT,
IPT_INTERLOCK,
IPT_VOLUME_UP,
IPT_VOLUME_DOWN,
- IPT_START, // MESS only
- IPT_SELECT, // MESS only
- IPT_KEYPAD, // MESS only
- IPT_KEYBOARD, // MESS only
+ IPT_START, // use the numbered start button(s) for coin-ops
+ IPT_SELECT,
+ IPT_KEYPAD,
+ IPT_KEYBOARD,
// digital joystick inputs
IPT_DIGITAL_JOYSTICK_FIRST,
@@ -206,7 +208,7 @@ enum ioport_type
IPT_MAHJONG_KAN,
IPT_MAHJONG_PON,
IPT_MAHJONG_CHI,
- IPT_MAHJONG_REACH, //IPT_MAHJONG_RIICHI, // REACH is Japanglish
+ IPT_MAHJONG_REACH,
IPT_MAHJONG_RON,
IPT_MAHJONG_BET,
IPT_MAHJONG_LAST_CHANCE,
@@ -256,22 +258,6 @@ enum ioport_type
IPT_GAMBLE_STAND, // player
IPT_GAMBLE_BET, // player
IPT_GAMBLE_PAYOUT, // player
- // IPT_GAMBLE_BUTTON1, // player
- // IPT_GAMBLE_BUTTON2, // many many gambling games have multi-games and/or multi-function-buttons
- // IPT_GAMBLE_BUTTON3, // I suggest to eliminate specific names
- // IPT_GAMBLE_BUTTON4,
- // IPT_GAMBLE_BUTTON5,
- // IPT_GAMBLE_BUTTON6,
- // IPT_GAMBLE_BUTTON7,
- // IPT_GAMBLE_BUTTON8,
- // IPT_GAMBLE_BUTTON9,
- // IPT_GAMBLE_BUTTON10,
- // IPT_GAMBLE_BUTTON11,
- // IPT_GAMBLE_BUTTON12,
- // IPT_GAMBLE_BUTTON13,
- // IPT_GAMBLE_BUTTON14,
- // IPT_GAMBLE_BUTTON15,
- // IPT_GAMBLE_BUTTON16,
// poker-specific inputs
IPT_POKER_HOLD1,
diff --git a/src/emu/language.cpp b/src/emu/language.cpp
index b47605f50c8..8d4618c7be3 100644
--- a/src/emu/language.cpp
+++ b/src/emu/language.cpp
@@ -41,7 +41,7 @@ void load_translation(emu_options &m_options)
strreplace(name, " ", "_");
strreplace(name, "(", "");
strreplace(name, ")", "");
- if (file.open(name.c_str(), PATH_SEPARATOR "strings.mo") == FILERR_NONE)
+ if (file.open(name.c_str(), PATH_SEPARATOR "strings.mo") == osd_file::error::NONE)
{
UINT64 size = file.size();
UINT32 *buffer = global_alloc_array(UINT32, size / 4 + 1);
diff --git a/src/emu/luaengine.cpp b/src/emu/luaengine.cpp
index 4ffee509693..cd55b2bde4c 100644
--- a/src/emu/luaengine.cpp
+++ b/src/emu/luaengine.cpp
@@ -838,6 +838,54 @@ int lua_engine::lua_screen::l_width(lua_State *L)
return 1;
}
+
+//-------------------------------------------------
+// screen_orientation - return screen orientation
+// -> manager:machine().screens[":screen"]:orientation()
+// -> rotation_angle (0, 90, 180, 270)
+// -> flipx (true, false)
+// -> flipy (true, false)
+//-------------------------------------------------
+
+int lua_engine::lua_screen::l_orientation(lua_State *L)
+{
+ UINT32 flags = (luaThis->machine().system().flags & ORIENTATION_MASK);
+
+ int rotation_angle = 0;
+ switch (flags)
+ {
+ case ORIENTATION_FLIP_X:
+ rotation_angle = 0;
+ break;
+ case ORIENTATION_SWAP_XY:
+ case ORIENTATION_SWAP_XY|ORIENTATION_FLIP_X:
+ rotation_angle = 90;
+ break;
+ case ORIENTATION_FLIP_Y:
+ case ORIENTATION_FLIP_X|ORIENTATION_FLIP_Y:
+ rotation_angle = 180;
+ break;
+ case ORIENTATION_SWAP_XY|ORIENTATION_FLIP_Y:
+ case ORIENTATION_SWAP_XY|ORIENTATION_FLIP_X|ORIENTATION_FLIP_Y:
+ rotation_angle = 270;
+ break;
+ }
+
+ lua_createtable(L, 2, 2);
+ lua_pushliteral(L, "rotation_angle");
+ lua_pushinteger(L, rotation_angle);
+
+ lua_settable(L, -3);
+ lua_pushliteral(L, "flipx");
+ lua_pushboolean(L, (flags & ORIENTATION_FLIP_X));
+
+ lua_settable(L, -3);
+ lua_pushliteral(L, "flipy");
+ lua_pushboolean(L, (flags & ORIENTATION_FLIP_Y));
+ lua_settable(L, -3);
+ return 1;
+}
+
//-------------------------------------------------
// screen_refresh - return screen refresh rate
// -> manager:machine().screens[":screen"]:refresh()
@@ -870,7 +918,7 @@ int lua_engine::lua_screen::l_snapshot(lua_State *L)
luaL_argcheck(L, lua_isstring(L, 2) || lua_isnone(L, 2), 2, "optional argument: filename, string expected");
emu_file file(sc->machine().options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
- file_error filerr;
+ osd_file::error filerr;
if (!lua_isnone(L, 2)) {
const char *filename = lua_tostring(L, 2);
@@ -884,9 +932,9 @@ int lua_engine::lua_screen::l_snapshot(lua_State *L)
filerr = sc->machine().video().open_next(file, "png");
}
- if (filerr != FILERR_NONE)
+ if (filerr != osd_file::error::NONE)
{
- luaL_error(L, "file_error=%d", filerr);
+ luaL_error(L, "osd_file::error=%d", filerr);
return 0;
}
@@ -1579,6 +1627,7 @@ void lua_engine::initialize()
.addCFunction ("draw_text", &lua_screen::l_draw_text)
.addCFunction ("height", &lua_screen::l_height)
.addCFunction ("width", &lua_screen::l_width)
+ .addCFunction ("orientation", &lua_screen::l_orientation)
.addCFunction ("refresh", &lua_screen::l_refresh)
.addCFunction ("snapshot", &lua_screen::l_snapshot)
.addCFunction ("type", &lua_screen::l_type)
diff --git a/src/emu/luaengine.h b/src/emu/luaengine.h
index 908a82a8f0b..0ec72f501d5 100644
--- a/src/emu/luaengine.h
+++ b/src/emu/luaengine.h
@@ -138,6 +138,7 @@ private:
struct lua_screen {
int l_height(lua_State *L);
int l_width(lua_State *L);
+ int l_orientation(lua_State *L);
int l_refresh(lua_State *L);
int l_type(lua_State *L);
int l_snapshot(lua_State *L);
diff --git a/src/emu/machine.cpp b/src/emu/machine.cpp
index b3ac263473e..7c465be0cd8 100644
--- a/src/emu/machine.cpp
+++ b/src/emu/machine.cpp
@@ -333,8 +333,8 @@ int running_machine::run(bool firstrun)
if (options().log() && &system() != &GAME_NAME(___empty))
{
m_logfile = std::make_unique<emu_file>(OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
- file_error filerr = m_logfile->open("error.log");
- assert_always(filerr == FILERR_NONE, "unable to open log file");
+ osd_file::error filerr = m_logfile->open("error.log");
+ assert_always(filerr == osd_file::error::NONE, "unable to open log file");
add_logerror_callback(logfile_callback);
}
@@ -372,7 +372,7 @@ int running_machine::run(bool firstrun)
g_profiler.start(PROFILER_EXTRA);
#if defined(EMSCRIPTEN)
- //break out to our async javascript loop and halt
+ // break out to our async javascript loop and halt
js_set_main_loop(this);
#endif
@@ -403,7 +403,7 @@ int running_machine::run(bool firstrun)
}
catch (emu_fatalerror &fatal)
{
- osd_printf_error("FATALERROR: %s\n", fatal.string());
+ osd_printf_error("Fatal error: %s\n", fatal.string());
error = MAMERR_FATALERROR;
if (fatal.exitcode() != 0)
error = fatal.exitcode();
@@ -440,7 +440,7 @@ int running_machine::run(bool firstrun)
// call all exit callbacks registered
call_notifiers(MACHINE_NOTIFY_EXIT);
- zip_file_cache_clear();
+ util::archive_file::cache_clear();
// close the logfile
m_logfile.reset();
@@ -761,6 +761,7 @@ void running_machine::add_notifier(machine_notification event, machine_notify_de
void running_machine::add_logerror_callback(logerror_callback callback)
{
assert_always(m_current_phase == MACHINE_PHASE_INIT, "Can only call add_logerror_callback at init time!");
+ m_string_buffer.reserve(1024);
m_logerror_list.push_back(std::make_unique<logerror_callback_item>(callback));
}
@@ -821,76 +822,76 @@ void running_machine::call_notifiers(machine_notification which)
void running_machine::handle_saveload()
{
- UINT32 openflags = (m_saveload_schedule == SLS_LOAD) ? OPEN_FLAG_READ : (OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
- const char *opnamed = (m_saveload_schedule == SLS_LOAD) ? "loaded" : "saved";
- const char *opname = (m_saveload_schedule == SLS_LOAD) ? "load" : "save";
- file_error filerr = FILERR_NONE;
-
// if no name, bail
- emu_file file(m_saveload_searchpath, openflags);
- if (m_saveload_pending_file.empty())
- goto cancel;
-
- // if there are anonymous timers, we can't save just yet, and we can't load yet either
- // because the timers might overwrite data we have loaded
- if (!m_scheduler.can_save())
+ if (!m_saveload_pending_file.empty())
{
- // if more than a second has passed, we're probably screwed
- if ((this->time() - m_saveload_schedule_time) > attotime::from_seconds(1))
+ const char *const opname = (m_saveload_schedule == SLS_LOAD) ? "load" : "save";
+
+ // if there are anonymous timers, we can't save just yet, and we can't load yet either
+ // because the timers might overwrite data we have loaded
+ if (!m_scheduler.can_save())
{
- popmessage("Unable to %s due to pending anonymous timers. See error.log for details.", opname);
- goto cancel;
+ // if more than a second has passed, we're probably screwed
+ if ((this->time() - m_saveload_schedule_time) > attotime::from_seconds(1))
+ popmessage("Unable to %s due to pending anonymous timers. See error.log for details.", opname);
+ else
+ return; // return without cancelling the operation
}
- return;
- }
-
- // open the file
- filerr = file.open(m_saveload_pending_file.c_str());
- if (filerr == FILERR_NONE)
- {
- // read/write the save state
- save_error saverr = (m_saveload_schedule == SLS_LOAD) ? m_save.read_file(file) : m_save.write_file(file);
-
- // handle the result
- switch (saverr)
+ else
{
- case STATERR_ILLEGAL_REGISTRATIONS:
- popmessage("Error: Unable to %s state due to illegal registrations. See error.log for details.", opname);
- break;
-
- case STATERR_INVALID_HEADER:
- popmessage("Error: Unable to %s state due to an invalid header. Make sure the save state is correct for this game.", opname);
- break;
+ UINT32 const openflags = (m_saveload_schedule == SLS_LOAD) ? OPEN_FLAG_READ : (OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
- case STATERR_READ_ERROR:
- popmessage("Error: Unable to %s state due to a read error (file is likely corrupt).", opname);
- break;
+ // open the file
+ emu_file file(m_saveload_searchpath, openflags);
+ auto const filerr = file.open(m_saveload_pending_file.c_str());
+ if (filerr == osd_file::error::NONE)
+ {
+ const char *const opnamed = (m_saveload_schedule == SLS_LOAD) ? "loaded" : "saved";
- case STATERR_WRITE_ERROR:
- popmessage("Error: Unable to %s state due to a write error. Verify there is enough disk space.", opname);
- break;
+ // read/write the save state
+ save_error saverr = (m_saveload_schedule == SLS_LOAD) ? m_save.read_file(file) : m_save.write_file(file);
- case STATERR_NONE:
- if (!(m_system.flags & MACHINE_SUPPORTS_SAVE))
- popmessage("State successfully %s.\nWarning: Save states are not officially supported for this game.", opnamed);
- else
- popmessage("State successfully %s.", opnamed);
- break;
+ // handle the result
+ switch (saverr)
+ {
+ case STATERR_ILLEGAL_REGISTRATIONS:
+ popmessage("Error: Unable to %s state due to illegal registrations. See error.log for details.", opname);
+ break;
+
+ case STATERR_INVALID_HEADER:
+ popmessage("Error: Unable to %s state due to an invalid header. Make sure the save state is correct for this game.", opname);
+ break;
+
+ case STATERR_READ_ERROR:
+ popmessage("Error: Unable to %s state due to a read error (file is likely corrupt).", opname);
+ break;
+
+ case STATERR_WRITE_ERROR:
+ popmessage("Error: Unable to %s state due to a write error. Verify there is enough disk space.", opname);
+ break;
+
+ case STATERR_NONE:
+ if (!(m_system.flags & MACHINE_SUPPORTS_SAVE))
+ popmessage("State successfully %s.\nWarning: Save states are not officially supported for this game.", opnamed);
+ else
+ popmessage("State successfully %s.", opnamed);
+ break;
+
+ default:
+ popmessage("Error: Unknown error during state %s.", opnamed);
+ break;
+ }
- default:
- popmessage("Error: Unknown error during state %s.", opnamed);
- break;
+ // close and perhaps delete the file
+ if (saverr != STATERR_NONE && m_saveload_schedule == SLS_SAVE)
+ file.remove_on_close();
+ }
+ else
+ popmessage("Error: Failed to open file for %s operation.", opname);
}
-
- // close and perhaps delete the file
- if (saverr != STATERR_NONE && m_saveload_schedule == SLS_SAVE)
- file.remove_on_close();
}
- else
- popmessage("Error: Failed to open file for %s operation.", opname);
// unschedule the operation
-cancel:
m_saveload_pending_file.clear();
m_saveload_searchpath = nullptr;
m_saveload_schedule = SLS_NONE;
@@ -1011,7 +1012,6 @@ void running_machine::logfile_callback(const running_machine &machine, const cha
if (machine.m_logfile != nullptr)
{
machine.m_logfile->puts(buffer);
-
machine.m_logfile->flush();
}
}
@@ -1171,7 +1171,7 @@ void running_machine::nvram_load()
for (device_nvram_interface *nvram = iter.first(); nvram != nullptr; nvram = iter.next())
{
emu_file file(options().nvram_directory(), OPEN_FLAG_READ);
- if (file.open(nvram_filename(nvram->device()).c_str()) == FILERR_NONE)
+ if (file.open(nvram_filename(nvram->device()).c_str()) == osd_file::error::NONE)
{
nvram->nvram_load(file);
file.close();
@@ -1192,7 +1192,7 @@ void running_machine::nvram_save()
for (device_nvram_interface *nvram = iter.first(); nvram != nullptr; nvram = iter.next())
{
emu_file file(options().nvram_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
- if (file.open(nvram_filename(nvram->device()).c_str()) == FILERR_NONE)
+ if (file.open(nvram_filename(nvram->device()).c_str()) == osd_file::error::NONE)
{
nvram->nvram_save(file);
file.close();
diff --git a/src/emu/machine.ipp b/src/emu/machine.ipp
index 092c1615d33..44d029fd309 100644
--- a/src/emu/machine.ipp
+++ b/src/emu/machine.ipp
@@ -61,6 +61,7 @@ inline void running_machine::logerror(Format &&fmt, Params &&... args) const
// dump to the buffer
m_string_buffer.clear();
+ m_string_buffer.seekp(0);
util::stream_format(m_string_buffer, std::forward<Format>(fmt), std::forward<Params>(args)...);
m_string_buffer.put('\0');
diff --git a/src/emu/mame.cpp b/src/emu/mame.cpp
index 5e93623498d..2f313dceabb 100644
--- a/src/emu/mame.cpp
+++ b/src/emu/mame.cpp
@@ -158,8 +158,8 @@ void machine_manager::start_luaengine()
m_lua->initialize();
{
emu_file file(options().plugins_path(), OPEN_FLAG_READ);
- file_error filerr = file.open("boot.lua");
- if (filerr == FILERR_NONE)
+ osd_file::error filerr = file.open("boot.lua");
+ if (filerr == osd_file::error::NONE)
{
m_lua->load_script(file.fullpath());
}
diff --git a/src/emu/mconfig.h b/src/emu/mconfig.h
index dc1a2e99b0a..4fb118ca1c5 100644
--- a/src/emu/mconfig.h
+++ b/src/emu/mconfig.h
@@ -1,12 +1,13 @@
// license:BSD-3-Clause
// copyright-holders:Aaron Giles
-/***************************************************************************
+/***************************************************************************/
+/**
+ * @file mconfig.h
+ * @defgroup MACHINE_CONFIG Machine configuration macros and functions
+ * @{
+ */
+/***************************************************************************/
- mconfig.h
-
- Machine configuration macros and functions.
-
-***************************************************************************/
#pragma once
@@ -81,26 +82,52 @@ private:
};
+//*************************************************************************/
+/** @name Machine config start/end macros */
+//*************************************************************************/
-//**************************************************************************
-// MACHINE CONFIG MACROS
-//**************************************************************************
-
-// start/end tags for the machine driver
+/**
+ @def MACHINE_CONFIG_NAME(_name)
+ Returns the internal name for the machine config.
+ @param _name name of desired config
+ @hideinitializer
+ */
#define MACHINE_CONFIG_NAME(_name) construct_machine_config_##_name
+/**
+ @def MACHINE_CONFIG_START(_name, _class)
+ Begins a new machine config.
+ @param _name name of this config
+ @param _class driver_device class for this config
+ @hideinitializer
+ */
#define MACHINE_CONFIG_START(_name, _class) \
ATTR_COLD device_t *MACHINE_CONFIG_NAME(_name)(machine_config &config, device_t *owner, device_t *device) \
{ \
devcb_base *devcb = NULL; \
(void)devcb; \
if (owner == NULL) owner = config.device_add(NULL, "root", &driver_device_creator<_class>, 0);
+
+/**
+ @def MACHINE_CONFIG_FRAGMENT(_name)
+ Begins a partial machine_config that can only be included in another "root" machine_config. This is also used for machine_configs that are specified as part of a device.
+ @param _name name of this config fragment
+ @hideinitializer
+*/
#define MACHINE_CONFIG_FRAGMENT(_name) \
ATTR_COLD device_t *MACHINE_CONFIG_NAME(_name)(machine_config &config, device_t *owner, device_t *device) \
{ \
devcb_base *devcb = NULL; \
(void)devcb; \
assert(owner != NULL);
+
+/**
+ @def MACHINE_CONFIG_DERIVED(_name, _base)
+ Begins a machine_config that is derived from another machine_config.
+ @param _name name of this config
+ @param _base name of the parent config
+ @hideinitializer
+*/
#define MACHINE_CONFIG_DERIVED(_name, _base) \
ATTR_COLD device_t *MACHINE_CONFIG_NAME(_name)(machine_config &config, device_t *owner, device_t *device) \
{ \
@@ -108,6 +135,15 @@ ATTR_COLD device_t *MACHINE_CONFIG_NAME(_name)(machine_config &config, device_t
(void)devcb; \
owner = MACHINE_CONFIG_NAME(_base)(config, owner, device); \
assert(owner != NULL);
+
+/**
+@def MACHINE_CONFIG_DERIVED_CLASS(_name, _base, _class)
+Begins a machine_config that is derived from another machine_config that can specify an alternate driver_device class
+@param _name name of this config
+@param _base name of the parent config
+@param _class name of the alternate driver_device class
+@hideinitializer
+*/
#define MACHINE_CONFIG_DERIVED_CLASS(_name, _base, _class) \
ATTR_COLD device_t *MACHINE_CONFIG_NAME(_name)(machine_config &config, device_t *owner, device_t *device) \
{ \
@@ -115,14 +151,32 @@ ATTR_COLD device_t *MACHINE_CONFIG_NAME(_name)(machine_config &config, device_t
(void)devcb; \
if (owner == NULL) owner = config.device_add(NULL, "root", &driver_device_creator<_class>, 0); \
owner = MACHINE_CONFIG_NAME(_base)(config, owner, device);
+
+/**
+@def MACHINE_CONFIG_END
+Ends a machine_config.
+@hideinitializer
+*/
#define MACHINE_CONFIG_END \
return owner; \
}
-// use this to declare external references to a machine driver
+//*************************************************************************/
+/** @name Standalone machine config macros */
+//*************************************************************************/
+
+/**
+@def MACHINE_CONFIG_EXTERN(_name)
+References an external machine config.
+@param _name Name of the machine config to reference
+@hideinitializer
+*/
#define MACHINE_CONFIG_EXTERN(_name) \
extern device_t *MACHINE_CONFIG_NAME(_name)(machine_config &config, device_t *owner, device_t *device)
+//*************************************************************************/
+/** @name Core machine config options */
+//*************************************************************************/
// importing data from other machine drivers
#define MCFG_FRAGMENT_ADD(_name) \
@@ -160,3 +214,4 @@ ATTR_COLD device_t *MACHINE_CONFIG_NAME(_name)(machine_config &config, device_t
device = config.device_find(owner, _tag);
#endif /* __MCONFIG_H__ */
+ /** @} */
diff --git a/src/emu/memory.cpp b/src/emu/memory.cpp
index 4401cc0d05e..59d1f6d69e2 100644
--- a/src/emu/memory.cpp
+++ b/src/emu/memory.cpp
@@ -1890,11 +1890,11 @@ void address_space::prepare_map()
// find the region
memory_region *region = machine().root_device().memregion(fulltag.c_str());
if (region == nullptr)
- fatalerror("Error: device '%s' %s space memory map entry %X-%X references non-existant region \"%s\"\n", m_device.tag(), m_name, entry->m_addrstart, entry->m_addrend, entry->m_region);
+ fatalerror("device '%s' %s space memory map entry %X-%X references non-existant region \"%s\"\n", m_device.tag(), m_name, entry->m_addrstart, entry->m_addrend, entry->m_region);
// validate the region
if (entry->m_rgnoffs + (entry->m_byteend - entry->m_bytestart + 1) > region->bytes())
- fatalerror("Error: device '%s' %s space memory map entry %X-%X extends beyond region \"%s\" size (%X)\n", m_device.tag(), m_name, entry->m_addrstart, entry->m_addrend, entry->m_region, region->bytes());
+ fatalerror("device '%s' %s space memory map entry %X-%X extends beyond region \"%s\" size (%X)\n", m_device.tag(), m_name, entry->m_addrstart, entry->m_addrend, entry->m_region, region->bytes());
}
// convert any region-relative entries to their memory pointers
diff --git a/src/emu/render.cpp b/src/emu/render.cpp
index 3de791eab52..806921f8981 100644
--- a/src/emu/render.cpp
+++ b/src/emu/render.cpp
@@ -1588,8 +1588,8 @@ bool render_target::load_layout_file(const char *dirname, const char *filename)
// attempt to open the file; bail if we can't
emu_file layoutfile(manager().machine().options().art_path(), OPEN_FLAG_READ);
- file_error filerr = layoutfile.open(fname.c_str());
- if (filerr != FILERR_NONE)
+ osd_file::error filerr = layoutfile.open(fname.c_str());
+ if (filerr != osd_file::error::NONE)
return false;
// read the file
@@ -1756,29 +1756,39 @@ void render_target::add_container_primitives(render_primitive_list &list, const
// set the palette
prim->texture.palette = curitem->texture()->get_adjusted_palette(container);
- // determine UV coordinates and apply clipping
+ // determine UV coordinates
prim->texcoords = oriented_texcoords[finalorient];
+
+ // apply clipping
clipped = render_clip_quad(&prim->bounds, &cliprect, &prim->texcoords);
// apply the final orientation from the quad flags and then build up the final flags
- prim->flags = (curitem->flags() & ~(PRIMFLAG_TEXORIENT_MASK | PRIMFLAG_BLENDMODE_MASK | PRIMFLAG_TEXFORMAT_MASK)) |
- PRIMFLAG_TEXORIENT(finalorient) |
- PRIMFLAG_TEXFORMAT(curitem->texture()->format());
- if (blendmode != -1)
- prim->flags |= PRIMFLAG_BLENDMODE(blendmode);
- else
- prim->flags |= PRIMFLAG_BLENDMODE(PRIMFLAG_GET_BLENDMODE(curitem->flags()));
+ prim->flags = (curitem->flags() & ~(PRIMFLAG_TEXORIENT_MASK | PRIMFLAG_BLENDMODE_MASK | PRIMFLAG_TEXFORMAT_MASK))
+ | PRIMFLAG_TEXORIENT(finalorient)
+ | PRIMFLAG_TEXFORMAT(curitem->texture()->format());
+ prim->flags |= blendmode != -1
+ ? PRIMFLAG_BLENDMODE(blendmode)
+ : PRIMFLAG_BLENDMODE(PRIMFLAG_GET_BLENDMODE(curitem->flags()));
}
else
{
+ if (curitem->flags() & PRIMFLAG_VECTORBUF_MASK)
+ {
+ // determine UV coordinates
+ prim->texcoords = oriented_texcoords[0];
+ }
+
// adjust the color for brightness/contrast/gamma
prim->color.r = container.apply_brightness_contrast_gamma_fp(prim->color.r);
prim->color.g = container.apply_brightness_contrast_gamma_fp(prim->color.g);
prim->color.b = container.apply_brightness_contrast_gamma_fp(prim->color.b);
- // no texture -- set the basic flags
+ // no texture
prim->texture.base = nullptr;
- prim->flags = (curitem->flags() &~ PRIMFLAG_BLENDMODE_MASK) | PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA);
+
+ // set the basic flags
+ prim->flags = (curitem->flags() & ~PRIMFLAG_BLENDMODE_MASK)
+ | PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA);
// apply clipping
clipped = render_clip_quad(&prim->bounds, &cliprect, nullptr);
diff --git a/src/emu/render.h b/src/emu/render.h
index 6d55c75ada9..09fe68282ef 100644
--- a/src/emu/render.h
+++ b/src/emu/render.h
@@ -329,6 +329,8 @@ public:
// getters
render_primitive *next() const { return m_next; }
bool packable(const INT32 pack_size) const { return (flags & PRIMFLAG_PACKABLE) && texture.base != nullptr && texture.width <= pack_size && texture.height <= pack_size; }
+ float get_quad_width() const { return bounds.x1 - bounds.x0; }
+ float get_quad_height() const { return bounds.y1 - bounds.y0; }
// reset to prepare for re-use
void reset();
diff --git a/src/emu/rendfont.cpp b/src/emu/rendfont.cpp
index 89c174c31bf..9a05e5514c5 100644
--- a/src/emu/rendfont.cpp
+++ b/src/emu/rendfont.cpp
@@ -123,7 +123,7 @@ render_font::render_font(render_manager &manager, const char *filename)
m_yoffs(0),
m_scale(1.0f),
m_rawsize(0),
- m_osdfont(nullptr),
+ m_osdfont(),
m_height_cmd(0),
m_yoffs_cmd(0)
{
@@ -132,21 +132,20 @@ render_font::render_font(render_manager &manager, const char *filename)
// if this is an OSD font, we're done
if (filename != nullptr)
- {
+ {
m_osdfont = manager.machine().osd().font_alloc();
- if (m_osdfont != nullptr)
+ if (m_osdfont)
{
if (m_osdfont->open(manager.machine().options().font_path(), filename, m_height))
{
- m_scale = 1.0f / (float)m_height;
- m_format = FF_OSD;
+ m_scale = 1.0f / (float)m_height;
+ m_format = FF_OSD;
- //mamep: allocate command glyph font
- render_font_command_glyph();
- return;
- }
- global_free(m_osdfont);
- m_osdfont = nullptr;
+ //mamep: allocate command glyph font
+ render_font_command_glyph();
+ return;
+ }
+ m_osdfont.reset();
}
}
@@ -157,15 +156,15 @@ render_font::render_font(render_manager &manager, const char *filename)
// attempt to load the cached version of the font first
if (filename != nullptr && load_cached_bdf(filename))
{
- //mamep: allocate command glyph font
- render_font_command_glyph();
- return;
+ //mamep: allocate command glyph font
+ render_font_command_glyph();
+ return;
}
// load the raw data instead
emu_file ramfile(OPEN_FLAG_READ);
- file_error filerr = ramfile.open_ram(font_uismall, sizeof(font_uismall));
- if (filerr == FILERR_NONE)
+ osd_file::error filerr = ramfile.open_ram(font_uismall, sizeof(font_uismall));
+ if (filerr == osd_file::error::NONE)
load_cached(ramfile, 0);
render_font_command_glyph();
}
@@ -199,13 +198,6 @@ render_font::~render_font()
}
delete[] elem;
}
-
- // release the OSD font
- if (m_osdfont != nullptr)
- {
- m_osdfont->close();
- global_free(m_osdfont);
- }
}
@@ -470,8 +462,8 @@ bool render_font::load_cached_bdf(const char *filename)
{
// first try to open the BDF itself
emu_file file(manager().machine().options().font_path(), OPEN_FLAG_READ);
- file_error filerr = file.open(filename);
- if (filerr != FILERR_NONE)
+ osd_file::error filerr = file.open(filename);
+ if (filerr != osd_file::error::NONE)
return false;
// determine the file size and allocate memory
@@ -494,7 +486,7 @@ bool render_font::load_cached_bdf(const char *filename)
{
emu_file cachefile(manager().machine().options().font_path(), OPEN_FLAG_READ);
filerr = cachefile.open(cachedname.c_str());
- if (filerr == FILERR_NONE)
+ if (filerr == osd_file::error::NONE)
{
// if we have a cached version, load it
bool result = load_cached(cachefile, hash);
@@ -667,7 +659,7 @@ bool render_font::load_cached(emu_file &file, UINT32 hash)
// validate the header
if (header[0] != 'f' || header[1] != 'o' || header[2] != 'n' || header[3] != 't')
return false;
- if (header[4] != (UINT8)(hash >> 24) || header[5] != (UINT8)(hash >> 16) || header[6] != (UINT8)(hash >> 8) || header[7] != (UINT8)hash)
+ if (hash && (header[4] != (UINT8)(hash >> 24) || header[5] != (UINT8)(hash >> 16) || header[6] != (UINT8)(hash >> 8) || header[7] != (UINT8)hash))
return false;
m_height = (header[8] << 8) | header[9];
m_scale = 1.0f / (float)m_height;
@@ -730,8 +722,8 @@ bool render_font::save_cached(const char *filename, UINT32 hash)
// attempt to open the file
emu_file file(manager().machine().options().font_path(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE);
- file_error filerr = file.open(filename);
- if (filerr != FILERR_NONE)
+ osd_file::error filerr = file.open(filename);
+ if (filerr != osd_file::error::NONE)
return false;
// determine the number of characters
diff --git a/src/emu/rendfont.h b/src/emu/rendfont.h
index 1f05babd789..b2ec2f12568 100644
--- a/src/emu/rendfont.h
+++ b/src/emu/rendfont.h
@@ -96,14 +96,14 @@ private:
int m_height; // height of the font, from ascent to descent
int m_yoffs; // y offset from baseline to descent
float m_scale; // 1 / height precomputed
- glyph *m_glyphs[256]; // array of glyph subtables
+ glyph *m_glyphs[256]; // array of glyph subtables
std::vector<char> m_rawdata; // pointer to the raw data for the font
UINT64 m_rawsize; // size of the raw font data
- osd_font *m_osdfont; // handle to the OSD font
+ std::unique_ptr<osd_font> m_osdfont; // handle to the OSD font
int m_height_cmd; // height of the font, from ascent to descent
int m_yoffs_cmd; // y offset from baseline to descent
- glyph *m_glyphs_cmd[256]; // array of glyph subtables
+ glyph *m_glyphs_cmd[256]; // array of glyph subtables
std::vector<char> m_rawdata_cmd; // pointer to the raw data for the font
// constants
diff --git a/src/emu/rendutil.cpp b/src/emu/rendutil.cpp
index 6d0bde63adb..4c49c6c8a62 100644
--- a/src/emu/rendutil.cpp
+++ b/src/emu/rendutil.cpp
@@ -540,8 +540,8 @@ bool render_load_png(bitmap_argb32 &bitmap, emu_file &file, const char *dirname,
fname.assign(filename);
else
fname.assign(dirname).append(PATH_SEPARATOR).append(filename);
- file_error filerr = file.open(fname.c_str());
- if (filerr != FILERR_NONE)
+ osd_file::error filerr = file.open(fname.c_str());
+ if (filerr != osd_file::error::NONE)
return false;
// read the PNG data
diff --git a/src/emu/romload.cpp b/src/emu/romload.cpp
index f5f15551ab5..45cbeecbea4 100644
--- a/src/emu/romload.cpp
+++ b/src/emu/romload.cpp
@@ -28,9 +28,9 @@
HELPERS (also used by diimage.cpp)
***************************************************************************/
-static file_error common_process_file(emu_options &options, const char *location, const char *ext, const rom_entry *romp, emu_file &image_file)
+static osd_file::error common_process_file(emu_options &options, const char *location, const char *ext, const rom_entry *romp, emu_file &image_file)
{
- file_error filerr;
+ osd_file::error filerr;
if (location != nullptr && strcmp(location, "") != 0)
filerr = image_file.open(location, PATH_SEPARATOR, ROM_GETNAME(romp), ext);
@@ -40,7 +40,7 @@ static file_error common_process_file(emu_options &options, const char *location
return filerr;
}
-std::unique_ptr<emu_file> common_process_file(emu_options &options, const char *location, bool has_crc, UINT32 crc, const rom_entry *romp, file_error &filerr)
+std::unique_ptr<emu_file> common_process_file(emu_options &options, const char *location, bool has_crc, UINT32 crc, const rom_entry *romp, osd_file::error &filerr)
{
auto image_file = std::make_unique<emu_file>(options.media_path(), OPEN_FLAG_READ);
@@ -49,7 +49,7 @@ std::unique_ptr<emu_file> common_process_file(emu_options &options, const char *
else
filerr = image_file->open(location, PATH_SEPARATOR, ROM_GETNAME(romp));
- if (filerr != FILERR_NONE)
+ if (filerr != osd_file::error::NONE)
{
image_file = nullptr;
}
@@ -549,7 +549,7 @@ void rom_load_manager::region_post_process(const char *rgntag, bool invert)
int rom_load_manager::open_rom_file(const char *regiontag, const rom_entry *romp, std::string &tried_file_names, bool from_list)
{
- file_error filerr = FILERR_NOT_FOUND;
+ osd_file::error filerr = osd_file::error::NOT_FOUND;
UINT32 romsize = rom_file_size(romp);
tried_file_names = "";
@@ -656,7 +656,7 @@ int rom_load_manager::open_rom_file(const char *regiontag, const rom_entry *romp
m_romsloadedsize += romsize;
/* return the result */
- return (filerr == FILERR_NONE);
+ return (filerr == osd_file::error::NONE);
}
@@ -959,19 +959,19 @@ int open_disk_image(emu_options &options, const game_driver *gamedrv, const rom_
{
emu_file image_file(options.media_path(), OPEN_FLAG_READ);
const rom_entry *region, *rom;
- file_error filerr;
+ osd_file::error filerr;
chd_error err;
/* attempt to open the properly named file, scanning up through parent directories */
- filerr = FILERR_NOT_FOUND;
- for (int searchdrv = driver_list::find(*gamedrv); searchdrv != -1 && filerr != FILERR_NONE; searchdrv = driver_list::clone(searchdrv))
+ filerr = osd_file::error::NOT_FOUND;
+ for (int searchdrv = driver_list::find(*gamedrv); searchdrv != -1 && filerr != osd_file::error::NONE; searchdrv = driver_list::clone(searchdrv))
filerr = common_process_file(options, driver_list::driver(searchdrv).name, ".chd", romp, image_file);
- if (filerr != FILERR_NONE)
+ if (filerr != osd_file::error::NONE)
filerr = common_process_file(options, nullptr, ".chd", romp, image_file);
/* look for the disk in the locationtag too */
- if (filerr != FILERR_NONE && locationtag != nullptr)
+ if (filerr != osd_file::error::NONE && locationtag != nullptr)
{
// check if we are dealing with softwarelists. if so, locationtag
// is actually a concatenation of: listname + setname + parentname
@@ -1022,19 +1022,19 @@ int open_disk_image(emu_options &options, const game_driver *gamedrv, const rom_
else
{
// try to load from list/setname
- if ((filerr != FILERR_NONE) && (tag2.c_str() != nullptr))
+ if ((filerr != osd_file::error::NONE) && (tag2.c_str() != nullptr))
filerr = common_process_file(options, tag2.c_str(), ".chd", romp, image_file);
// try to load from list/parentname (if any)
- if ((filerr != FILERR_NONE) && has_parent && (tag3.c_str() != nullptr))
+ if ((filerr != osd_file::error::NONE) && has_parent && (tag3.c_str() != nullptr))
filerr = common_process_file(options, tag3.c_str(), ".chd", romp, image_file);
// try to load from setname
- if ((filerr != FILERR_NONE) && (tag4.c_str() != nullptr))
+ if ((filerr != osd_file::error::NONE) && (tag4.c_str() != nullptr))
filerr = common_process_file(options, tag4.c_str(), ".chd", romp, image_file);
// try to load from parentname (if any)
- if ((filerr != FILERR_NONE) && has_parent && (tag5.c_str() != nullptr))
+ if ((filerr != osd_file::error::NONE) && has_parent && (tag5.c_str() != nullptr))
filerr = common_process_file(options, tag5.c_str(), ".chd", romp, image_file);
// only for CHD we also try to load from list/
- if ((filerr != FILERR_NONE) && (tag1.c_str() != nullptr))
+ if ((filerr != osd_file::error::NONE) && (tag1.c_str() != nullptr))
{
tag1.erase(tag1.length() - 1, 1); // remove the PATH_SEPARATOR
filerr = common_process_file(options, tag1.c_str(), ".chd", romp, image_file);
@@ -1043,7 +1043,7 @@ int open_disk_image(emu_options &options, const game_driver *gamedrv, const rom_
}
/* did the file open succeed? */
- if (filerr == FILERR_NONE)
+ if (filerr == osd_file::error::NONE)
{
std::string fullpath(image_file.fullpath());
image_file.close();
@@ -1073,15 +1073,15 @@ int open_disk_image(emu_options &options, const game_driver *gamedrv, const rom_
romphashes == hash_collection(ROM_GETHASHDATA(rom)))
{
/* attempt to open the properly named file, scanning up through parent directories */
- filerr = FILERR_NOT_FOUND;
- for (int searchdrv = drv; searchdrv != -1 && filerr != FILERR_NONE; searchdrv = driver_list::clone(searchdrv))
+ filerr = osd_file::error::NOT_FOUND;
+ for (int searchdrv = drv; searchdrv != -1 && filerr != osd_file::error::NONE; searchdrv = driver_list::clone(searchdrv))
filerr = common_process_file(options, driver_list::driver(searchdrv).name, ".chd", rom, image_file);
- if (filerr != FILERR_NONE)
+ if (filerr != osd_file::error::NONE)
filerr = common_process_file(options, nullptr, ".chd", rom, image_file);
/* did the file open succeed? */
- if (filerr == FILERR_NONE)
+ if (filerr == osd_file::error::NONE)
{
std::string fullpath(image_file.fullpath());
image_file.close();
@@ -1108,8 +1108,8 @@ chd_error rom_load_manager::open_disk_diff(emu_options &options, const rom_entry
/* try to open the diff */
LOG(("Opening differencing image file: %s\n", fname.c_str()));
emu_file diff_file(options.diff_directory(), OPEN_FLAG_READ | OPEN_FLAG_WRITE);
- file_error filerr = diff_file.open(fname.c_str());
- if (filerr == FILERR_NONE)
+ osd_file::error filerr = diff_file.open(fname.c_str());
+ if (filerr == osd_file::error::NONE)
{
std::string fullpath(diff_file.fullpath());
diff_file.close();
@@ -1122,7 +1122,7 @@ chd_error rom_load_manager::open_disk_diff(emu_options &options, const rom_entry
LOG(("Creating differencing image: %s\n", fname.c_str()));
diff_file.set_openflags(OPEN_FLAG_READ | OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
filerr = diff_file.open(fname.c_str());
- if (filerr == FILERR_NONE)
+ if (filerr == osd_file::error::NONE)
{
std::string fullpath(diff_file.fullpath());
diff_file.close();
diff --git a/src/emu/romload.h b/src/emu/romload.h
index c7c10e49325..fe35bfc3fe2 100644
--- a/src/emu/romload.h
+++ b/src/emu/romload.h
@@ -13,8 +13,8 @@
#error Dont include this file directly; include emu.h instead.
#endif
-#ifndef __ROMLOAD_H__
-#define __ROMLOAD_H__
+#ifndef MAME_EMU_ROMLOAD_H
+#define MAME_EMU_ROMLOAD_H
#include "chd.h"
@@ -350,7 +350,7 @@ private:
/* ----- Helpers ----- */
-std::unique_ptr<emu_file> common_process_file(emu_options &options, const char *location, bool has_crc, UINT32 crc, const rom_entry *romp, file_error &filerr);
+std::unique_ptr<emu_file> common_process_file(emu_options &options, const char *location, bool has_crc, UINT32 crc, const rom_entry *romp, osd_file::error &filerr);
/* return pointer to the first ROM region within a source */
const rom_entry *rom_first_region(const device_t &device);
@@ -386,4 +386,4 @@ std::string rom_parameter_value(const rom_entry *romp);
/* open a disk image, searching up the parent and loading by checksum */
int open_disk_image(emu_options &options, const game_driver *gamedrv, const rom_entry *romp, chd_file &image_chd, const char *locationtag);
-#endif /* __ROMLOAD_H__ */
+#endif // MAME_EMU_ROMLOAD_H
diff --git a/src/emu/screen.cpp b/src/emu/screen.cpp
index c286788ea37..111a1b3232a 100644
--- a/src/emu/screen.cpp
+++ b/src/emu/screen.cpp
@@ -1153,8 +1153,8 @@ void screen_device::finalize_burnin()
// compute the name and create the file
emu_file file(machine().options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
- file_error filerr = file.open(machine().basename(), PATH_SEPARATOR "burnin-", this->tag()+1, ".png") ;
- if (filerr == FILERR_NONE)
+ osd_file::error filerr = file.open(machine().basename(), PATH_SEPARATOR "burnin-", this->tag()+1, ".png") ;
+ if (filerr == osd_file::error::NONE)
{
png_info pnginfo = { nullptr };
// png_error pngerr;
diff --git a/src/emu/softlist.cpp b/src/emu/softlist.cpp
index 05e9c761719..d554b394c21 100644
--- a/src/emu/softlist.cpp
+++ b/src/emu/softlist.cpp
@@ -478,8 +478,8 @@ void software_list_device::parse()
m_errors.clear();
// attempt to open the file
- file_error filerr = m_file.open(m_list_name.c_str(), ".xml");
- if (filerr == FILERR_NONE)
+ osd_file::error filerr = m_file.open(m_list_name.c_str(), ".xml");
+ if (filerr == osd_file::error::NONE)
{
// parse if no error
std::ostringstream errs;
diff --git a/src/emu/sound.cpp b/src/emu/sound.cpp
index 288bb09d9dc..47e7dcc90e8 100644
--- a/src/emu/sound.cpp
+++ b/src/emu/sound.cpp
@@ -231,11 +231,11 @@ void sound_stream::set_input(int index, sound_stream *input_stream, int output_i
// make sure it's a valid input
if (index >= m_input.size())
- fatalerror("Fatal error: stream_set_input attempted to configure non-existant input %d (%d max)\n", index, int(m_input.size()));
+ fatalerror("stream_set_input attempted to configure non-existant input %d (%d max)\n", index, int(m_input.size()));
// make sure it's a valid output
if (input_stream != nullptr && output_index >= input_stream->m_output.size())
- fatalerror("Fatal error: stream_set_input attempted to use a non-existant output %d (%d max)\n", output_index, int(m_output.size()));
+ fatalerror("stream_set_input attempted to use a non-existant output %d (%d max)\n", output_index, int(m_output.size()));
// if this input is already wired, update the dependent info
stream_input &input = m_input[index];
diff --git a/src/emu/ui/auditmenu.cpp b/src/emu/ui/auditmenu.cpp
index 68b3c2d285b..5d6ce8fa8d1 100644
--- a/src/emu/ui/auditmenu.cpp
+++ b/src/emu/ui/auditmenu.cpp
@@ -1,5 +1,5 @@
// license:BSD-3-Clause
-// copyright-holders:Dankan1890
+// copyright-holders:Maurizio Petrarota
/*********************************************************************
ui/auditmenu.cpp
@@ -84,8 +84,12 @@ bool sorted_game_list(const game_driver *x, const game_driver *y)
// ctor / dtor
//-------------------------------------------------
-ui_menu_audit::ui_menu_audit(running_machine &machine, render_container *container, std::vector<const game_driver *> &availablesorted, std::vector<const game_driver *> &unavailablesorted, int _audit_mode)
- : ui_menu(machine, container), m_availablesorted(availablesorted), m_unavailablesorted(unavailablesorted), m_audit_mode(_audit_mode), m_first(true)
+ui_menu_audit::ui_menu_audit(running_machine &machine, render_container *container, vptr_game &availablesorted, vptr_game &unavailablesorted, int _audit_mode)
+ : ui_menu(machine, container)
+ , m_availablesorted(availablesorted)
+ , m_unavailablesorted(unavailablesorted)
+ , m_audit_mode(_audit_mode)
+ , m_first(true)
{
if (m_audit_mode == 2)
{
@@ -115,7 +119,7 @@ void ui_menu_audit::handle()
if (m_audit_mode == 1)
{
- std::vector<const game_driver *>::iterator iter = m_unavailablesorted.begin();
+ vptr_game::iterator iter = m_unavailablesorted.begin();
while (iter != m_unavailablesorted.end())
{
driver_enumerator enumerator(machine().options(), (*iter)->name);
@@ -174,7 +178,7 @@ void ui_menu_audit::save_available_machines()
{
// attempt to open the output file
emu_file file(machine().ui().options().ui_path(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
- if (file.open(emulator_info::get_configname(), "_avail.ini") == FILERR_NONE)
+ if (file.open(emulator_info::get_configname(), "_avail.ini") == osd_file::error::NONE)
{
// generate header
std::ostringstream buffer;
diff --git a/src/emu/ui/auditmenu.h b/src/emu/ui/auditmenu.h
index caad05796a6..b63bbb6507b 100644
--- a/src/emu/ui/auditmenu.h
+++ b/src/emu/ui/auditmenu.h
@@ -1,5 +1,5 @@
// license:BSD-3-Clause
-// copyright-holders:Dankan1890
+// copyright-holders:Maurizio Petrarota
/***************************************************************************
ui/auditmenu.h
@@ -16,22 +16,26 @@
//-------------------------------------------------
// class audit menu
//-------------------------------------------------
+using vptr_game = std::vector<const game_driver *>;
class ui_menu_audit : public ui_menu
{
public:
- ui_menu_audit(running_machine &machine, render_container *container, std::vector<const game_driver *> &availablesorted, std::vector<const game_driver *> &unavailablesorted, int audit_mode);
+ ui_menu_audit(running_machine &machine, render_container *container, vptr_game &availablesorted, vptr_game &unavailablesorted, int audit_mode);
virtual ~ui_menu_audit();
virtual void populate() override;
virtual void handle() override;
private:
- std::vector<const game_driver *> &m_availablesorted;
- std::vector<const game_driver *> &m_unavailablesorted;
+ vptr_game &m_availablesorted;
+ vptr_game &m_unavailablesorted;
int m_audit_mode;
void save_available_machines();
bool m_first;
};
+inline int cs_stricmp(const char *s1, const char *s2);
+bool sorted_game_list(const game_driver *x, const game_driver *y);
+
#endif /* __UI_AUDIT_H__ */
diff --git a/src/emu/ui/barcode.cpp b/src/emu/ui/barcode.cpp
index e9f779737a8..4dc734a2bd2 100644
--- a/src/emu/ui/barcode.cpp
+++ b/src/emu/ui/barcode.cpp
@@ -2,7 +2,7 @@
// copyright-holders:Fabio Priuli
/***************************************************************************
- ui/barcode.c
+ ui/barcode.cpp
"Barcode Reader" control
diff --git a/src/emu/ui/cheatopt.cpp b/src/emu/ui/cheatopt.cpp
index 9c5f91d54bc..ceb2c3301f5 100644
--- a/src/emu/ui/cheatopt.cpp
+++ b/src/emu/ui/cheatopt.cpp
@@ -2,7 +2,7 @@
// copyright-holders:Nicola Salmoria, Aaron Giles, Nathan Woods
/*********************************************************************
- ui/cheatopt.c
+ ui/cheatopt.cpp
Internal menu for the cheat interface.
diff --git a/src/emu/ui/cmddata.h b/src/emu/ui/cmddata.h
index 5fa2658d2cb..31dd8c5ebd8 100644
--- a/src/emu/ui/cmddata.h
+++ b/src/emu/ui/cmddata.h
@@ -1,5 +1,5 @@
// license:BSD-3-Clause
-// copyright-holders:Dankan1890
+// copyright-holders:Maurizio Petrarota
/*********************************************************************
ui/cmddata.h
@@ -143,10 +143,8 @@ static rgb_t color_table[] =
BUTTON_COLOR_SILVER // 8 Player Lever
};
-// for color glyph
#define COLOR_BUTTONS ARRAY_LENGTH(color_table)
-// Follow Varialbe Defined Arraies for Game Command Tag
struct fix_command_t
{
unsigned char glyph_char;
diff --git a/src/emu/ui/cmdrender.h b/src/emu/ui/cmdrender.h
index d9bf466f1e9..130fed0a272 100644
--- a/src/emu/ui/cmdrender.h
+++ b/src/emu/ui/cmdrender.h
@@ -1,10 +1,10 @@
// license:BSD-3-Clause
-// copyright-holders:Dankan1890
+// copyright-holders:Maurizio Petrarota
/***************************************************************************
ui/cmdrender.h
- UI rendfont.
+ UI command render fonts.
***************************************************************************/
@@ -14,7 +14,6 @@
void convert_command_glyph(std::string &str)
{
int j;
- const char *s = str.c_str();
int len = str.length();
int buflen = (len + 2) * 2;
char *d = global_alloc_array(char, buflen);
@@ -23,16 +22,16 @@ void convert_command_glyph(std::string &str)
{
fix_command_t *fixcmd = nullptr;
unicode_char uchar;
- int ucharcount = uchar_from_utf8(&uchar, s + i, len - i);
+ int ucharcount = uchar_from_utf8(&uchar, str.substr(i).c_str(), len - i);
if (ucharcount == -1)
break;
else if (ucharcount != 1)
goto process_next;
- else if (s[i] == '\n')
+ else if (str[i] == '\n')
uchar = '\n';
- else if (s[i] == COMMAND_CONVERT_TEXT)
+ else if (str[i] == COMMAND_CONVERT_TEXT)
{
- if (s[i] == s[i + 1])
+ if (str[i] == str[i + 1])
++i;
else
{
@@ -42,7 +41,7 @@ void convert_command_glyph(std::string &str)
if (!fixtext->glyph_str_len)
fixtext->glyph_str_len = strlen(fixtext->glyph_str);
- if (strncmp(fixtext->glyph_str, s + i + 1, fixtext->glyph_str_len) == 0)
+ if (strncmp(fixtext->glyph_str, str.substr(i + 1).c_str(), fixtext->glyph_str_len) == 0)
{
uchar = fixtext->glyph_code + COMMAND_UNICODE;
i += strlen(fixtext->glyph_str);
@@ -51,19 +50,19 @@ void convert_command_glyph(std::string &str)
}
}
}
- else if (s[i] == COMMAND_DEFAULT_TEXT)
+ else if (str[i] == COMMAND_DEFAULT_TEXT)
fixcmd = default_text;
- else if (s[i] == COMMAND_EXPAND_TEXT)
+ else if (str[i] == COMMAND_EXPAND_TEXT)
fixcmd = expand_text;
if (fixcmd)
{
- if (s[i] == s[i + 1])
+ if (str[i] == str[i + 1])
i++;
else
{
for (; fixcmd->glyph_code; ++fixcmd)
- if (s[i + 1] == fixcmd->glyph_char)
+ if (str[i + 1] == fixcmd->glyph_char)
{
uchar = fixcmd->glyph_code + COMMAND_UNICODE;
++i;
@@ -87,7 +86,7 @@ void render_font::render_font_command_glyph()
{
emu_file ramfile(OPEN_FLAG_READ);
- if (ramfile.open_ram(font_uicmd14, sizeof(font_uicmd14)) == FILERR_NONE)
+ if (ramfile.open_ram(font_uicmd14, sizeof(font_uicmd14)) == osd_file::error::NONE)
load_cached_cmd(ramfile, 0);
}
diff --git a/src/emu/ui/ctrlmenu.cpp b/src/emu/ui/ctrlmenu.cpp
index 9e2f4c2950d..0fc7304a550 100644
--- a/src/emu/ui/ctrlmenu.cpp
+++ b/src/emu/ui/ctrlmenu.cpp
@@ -1,5 +1,5 @@
// license:BSD-3-Clause
-// copyright-holders:Dankan1890
+// copyright-holders:Maurizio Petrarota
/*********************************************************************
ui/ctrlmenu.cpp
@@ -104,7 +104,7 @@ void ui_menu_controller_mapping::custom_render(void *selectedref, float top, flo
ui_manager &mui = machine().ui();
mui.draw_text_full(container, _("Device Mapping"), 0.0f, 0.0f, 1.0f, JUSTIFY_CENTER, WRAP_TRUNCATE,
- DRAW_NONE, ARGB_WHITE, ARGB_BLACK, &width, nullptr);
+ DRAW_NONE, ARGB_WHITE, ARGB_BLACK, &width, nullptr);
width += 2 * UI_BOX_LR_BORDER;
maxwidth = MAX(maxwidth, width);
@@ -124,7 +124,7 @@ void ui_menu_controller_mapping::custom_render(void *selectedref, float top, flo
// draw the text within it
mui.draw_text_full(container, _("Device Mapping"), x1, y1, x2 - x1, JUSTIFY_CENTER, WRAP_TRUNCATE,
- DRAW_NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr);
+ DRAW_NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr);
}
diff --git a/src/emu/ui/ctrlmenu.h b/src/emu/ui/ctrlmenu.h
index 4c1325071d6..0db85ee878a 100644
--- a/src/emu/ui/ctrlmenu.h
+++ b/src/emu/ui/ctrlmenu.h
@@ -1,5 +1,5 @@
// license:BSD-3-Clause
-// copyright-holders:Dankan1890
+// copyright-holders:Maurizio Petrarota
/***************************************************************************
ui/ctrlmenu.h
diff --git a/src/emu/ui/custmenu.cpp b/src/emu/ui/custmenu.cpp
index 2d6083536db..fad9b2d5ea0 100644
--- a/src/emu/ui/custmenu.cpp
+++ b/src/emu/ui/custmenu.cpp
@@ -1,5 +1,5 @@
// license:BSD-3-Clause
-// copyright-holders:Dankan1890
+// copyright-holders:Maurizio Petrarota
/*********************************************************************
ui/custmenu.cpp
@@ -22,10 +22,11 @@
//-------------------------------------------------
// ctor / dtor
//-------------------------------------------------
-ui_menu_custom_filter::ui_menu_custom_filter(running_machine &machine, render_container *container, bool _single_menu) : ui_menu(machine, container)
+ui_menu_custom_filter::ui_menu_custom_filter(running_machine &machine, render_container *container, bool _single_menu)
+ : ui_menu(machine, container)
+ , m_single_menu(_single_menu)
+ , m_added(false)
{
- m_single_menu = _single_menu;
- m_added = false;
}
ui_menu_custom_filter::~ui_menu_custom_filter()
@@ -208,7 +209,7 @@ void ui_menu_custom_filter::custom_render(void *selectedref, float top, float bo
// get the size of the text
mui.draw_text_full(container, _("Select custom filters:"), 0.0f, 0.0f, 1.0f, JUSTIFY_CENTER, WRAP_NEVER,
- DRAW_NONE, ARGB_WHITE, ARGB_BLACK, &width, nullptr);
+ DRAW_NONE, ARGB_WHITE, ARGB_BLACK, &width, nullptr);
width += (2.0f * UI_BOX_LR_BORDER) + 0.01f;
float maxwidth = MAX(width, origx2 - origx1);
@@ -228,7 +229,7 @@ void ui_menu_custom_filter::custom_render(void *selectedref, float top, float bo
// draw the text within it
mui.draw_text_full(container, _("Select custom filters:"), x1, y1, x2 - x1, JUSTIFY_CENTER, WRAP_NEVER,
- DRAW_NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr);
+ DRAW_NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr);
}
//-------------------------------------------------
@@ -239,7 +240,7 @@ void ui_menu_custom_filter::save_custom_filters()
{
// attempt to open the output file
emu_file file(machine().ui().options().ui_path(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
- if (file.open("custom_", emulator_info::get_configname(), "_filter.ini") == FILERR_NONE)
+ if (file.open("custom_", emulator_info::get_configname(), "_filter.ini") == osd_file::error::NONE)
{
// generate custom filters info
std::ostringstream cinfo;
@@ -266,7 +267,10 @@ void ui_menu_custom_filter::save_custom_filters()
// ctor / dtor
//-------------------------------------------------
ui_menu_swcustom_filter::ui_menu_swcustom_filter(running_machine &machine, render_container *container, const game_driver *_driver, s_filter &_filter) :
- ui_menu(machine, container), m_added(false), m_filter(_filter), m_driver(_driver)
+ ui_menu(machine, container)
+ , m_added(false)
+ , m_filter(_filter)
+ , m_driver(_driver)
{
}
@@ -521,7 +525,7 @@ void ui_menu_swcustom_filter::custom_render(void *selectedref, float top, float
// get the size of the text
mui.draw_text_full(container, _("Select custom filters:"), 0.0f, 0.0f, 1.0f, JUSTIFY_CENTER, WRAP_NEVER,
- DRAW_NONE, ARGB_WHITE, ARGB_BLACK, &width, nullptr);
+ DRAW_NONE, ARGB_WHITE, ARGB_BLACK, &width, nullptr);
width += (2.0f * UI_BOX_LR_BORDER) + 0.01f;
float maxwidth = MAX(width, origx2 - origx1);
@@ -541,7 +545,7 @@ void ui_menu_swcustom_filter::custom_render(void *selectedref, float top, float
// draw the text within it
mui.draw_text_full(container, _("Select custom filters:"), x1, y1, x2 - x1, JUSTIFY_CENTER, WRAP_NEVER,
- DRAW_NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr);
+ DRAW_NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr);
}
//-------------------------------------------------
@@ -552,7 +556,7 @@ void ui_menu_swcustom_filter::save_sw_custom_filters()
{
// attempt to open the output file
emu_file file(machine().ui().options().ui_path(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
- if (file.open("custom_", m_driver->name, "_filter.ini") == FILERR_NONE)
+ if (file.open("custom_", m_driver->name, "_filter.ini") == osd_file::error::NONE)
{
// generate custom filters info
std::ostringstream cinfo;
diff --git a/src/emu/ui/custmenu.h b/src/emu/ui/custmenu.h
index d136e911164..338344dcddd 100644
--- a/src/emu/ui/custmenu.h
+++ b/src/emu/ui/custmenu.h
@@ -1,5 +1,5 @@
// license:BSD-3-Clause
-// copyright-holders:Dankan1890
+// copyright-holders:Maurizio Petrarota
/***************************************************************************
ui/custmenu.h
diff --git a/src/emu/ui/custui.cpp b/src/emu/ui/custui.cpp
index a6279ac5b54..816875131dc 100644
--- a/src/emu/ui/custui.cpp
+++ b/src/emu/ui/custui.cpp
@@ -1,5 +1,5 @@
// license:BSD-3-Clause
-// copyright-holders:Dankan1890
+// copyright-holders:Maurizio Petrarota
/*********************************************************************
ui/custui.cpp
@@ -9,14 +9,16 @@
*********************************************************************/
#include "emu.h"
+#include "ui/custui.h"
+
#include "ui/ui.h"
-#include "ui/menu.h"
#include "ui/selector.h"
-#include "ui/custui.h"
#include "ui/utils.h"
+
#include <algorithm>
-const char *ui_menu_custom_ui::hide_status[] = {
+
+const char *const ui_menu_custom_ui::hide_status[] = {
__("Show All"),
__("Hide Filters"),
__("Hide Info/Image"),
@@ -192,24 +194,23 @@ void ui_menu_custom_ui::custom_render(void *selectedref, float top, float bottom
ui_menu_font_ui::ui_menu_font_ui(running_machine &machine, render_container *container) : ui_menu(machine, container)
{
ui_options &moptions = machine.ui().options();
-#ifdef UI_WINDOWS
-
std::string name(machine.options().ui_font());
list();
+#ifdef UI_WINDOWS
m_bold = (strreplace(name, "[B]", "") + strreplace(name, "[b]", "") > 0);
m_italic = (strreplace(name, "[I]", "") + strreplace(name, "[i]", "") > 0);
+#endif
m_actual = 0;
for (size_t index = 0; index < m_fonts.size(); index++)
{
- if (m_fonts[index] == name)
+ if (m_fonts[index].first == name)
{
m_actual = index;
break;
}
}
-#endif
m_info_size = moptions.infos_size();
m_font_size = moptions.font_rows();
@@ -231,43 +232,17 @@ ui_menu_font_ui::ui_menu_font_ui(running_machine &machine, render_container *con
}
-#ifdef UI_WINDOWS
-//-------------------------------------------------
-// fonts enumerator CALLBACK
-//-------------------------------------------------
-
-int CALLBACK ui_menu_font_ui::EnumFontFamiliesExProc(const LOGFONT *lpelfe, const TEXTMETRIC *lpntme, DWORD FontType, LPARAM lParam)
-{
- std::vector<std::string> *lpc = (std::vector<std::string>*)lParam;
- std::string utf((char *)lpelfe->lfFaceName);
- if (utf[0] != '@')
- lpc->push_back(utf);
-
- return 1;
-}
-
//-------------------------------------------------
// create fonts list
//-------------------------------------------------
void ui_menu_font_ui::list()
{
- // create LOGFONT structure
- LOGFONT lf;
- lf.lfCharSet = ANSI_CHARSET;
- lf.lfFaceName[0] = '\0';
-
- HDC hDC = GetDC( nullptr );
- EnumFontFamiliesEx( hDC, &lf, (FONTENUMPROC)EnumFontFamiliesExProc, (LPARAM)&m_fonts, 0 );
- ReleaseDC( nullptr, hDC );
-
- // sort
- std::stable_sort(m_fonts.begin(), m_fonts.end());
+ machine().osd().get_font_families(machine().options().font_path(), m_fonts);
// add default string to the top of array
- m_fonts.insert(m_fonts.begin(), std::string(_("default")));
+ m_fonts.emplace(m_fonts.begin(), std::string("default"), std::string(_("default")));
}
-#endif
//-------------------------------------------------
// dtor
@@ -278,18 +253,18 @@ ui_menu_font_ui::~ui_menu_font_ui()
std::string error_string;
ui_options &moptions = machine().ui().options();
+ std::string name(m_fonts[m_actual].first);
#ifdef UI_WINDOWS
- std::string name(m_fonts[m_actual]);
- if (m_fonts[m_actual] != "default")
+ if (name != "default")
{
if (m_italic)
name.insert(0, "[I]");
if (m_bold)
name.insert(0, "[B]");
}
+#endif
machine().options().set_value(OPTION_UI_FONT, name.c_str(), OPTION_PRIORITY_CMDLINE, error_string);
machine().options().mark_changed(OPTION_UI_FONT);
-#endif
moptions.set_value(OPTION_INFOS_SIZE, m_info_size, OPTION_PRIORITY_CMDLINE, error_string);
moptions.set_value(OPTION_FONT_ROWS, m_font_size, OPTION_PRIORITY_CMDLINE, error_string);
@@ -325,7 +300,6 @@ void ui_menu_font_ui::handle()
}
break;
-#ifdef UI_WINDOWS
case MUI_FNT:
if (m_event->iptkey == IPT_UI_LEFT || m_event->iptkey == IPT_UI_RIGHT)
@@ -335,11 +309,15 @@ void ui_menu_font_ui::handle()
}
else if (m_event->iptkey == IPT_UI_SELECT)
{
- ui_menu::stack_push(global_alloc_clear<ui_menu_selector>(machine(), container, m_fonts, m_actual));
+ std::vector<std::string> display_names;
+ display_names.reserve(m_fonts.size());
+ for (auto const &font : m_fonts) display_names.emplace_back(font.second);
+ ui_menu::stack_push(global_alloc_clear<ui_menu_selector>(machine(), container, std::move(display_names), m_actual));
changed = true;
}
break;
+#ifdef UI_WINDOWS
case MUI_BOLD:
case MUI_ITALIC:
if (m_event->iptkey == IPT_UI_LEFT || m_event->iptkey == IPT_UI_RIGHT || m_event->iptkey == IPT_UI_SELECT)
@@ -364,13 +342,12 @@ void ui_menu_font_ui::populate()
// set filter arrow
UINT32 arrow_flags;
-#ifdef UI_WINDOWS
// add fonts option
arrow_flags = get_arrow_flags(0, m_fonts.size() - 1, m_actual);
- std::string name(m_fonts[m_actual]);
- item_append(_("UI Font"), name.c_str(), arrow_flags, (void *)(FPTR)MUI_FNT);
+ item_append(_("UI Font"), m_fonts[m_actual].second.c_str(), arrow_flags, (void *)(FPTR)MUI_FNT);
- if (name != "default")
+#ifdef UI_WINDOWS
+ if (m_fonts[m_actual].first != "default")
{
item_append(_("Bold"), m_bold ? "On" : "Off", m_bold ? MENU_FLAG_RIGHT_ARROW : MENU_FLAG_LEFT_ARROW, (void *)(FPTR)MUI_BOLD);
item_append(_("Italic"), m_italic ? "On" : "Off", m_italic ? MENU_FLAG_RIGHT_ARROW : MENU_FLAG_LEFT_ARROW, (void *)(FPTR)MUI_ITALIC);
diff --git a/src/emu/ui/custui.h b/src/emu/ui/custui.h
index 2ff13994cb6..0a2e55745c9 100644
--- a/src/emu/ui/custui.h
+++ b/src/emu/ui/custui.h
@@ -1,5 +1,5 @@
// license:BSD-3-Clause
-// copyright-holders:Dankan1890
+// copyright-holders:Maurizio Petrarota
/***************************************************************************
ui/custui.h
@@ -10,13 +10,14 @@
#pragma once
-#ifndef __UI_CUSTUI_H__
-#define __UI_CUSTUI_H__
+#ifndef MAME_EMU_UI_UI_CUSTUI_H
+#define MAME_EMU_UI_UI_CUSTUI_H
+
+#include "ui/menu.h"
+
+#include <vector>
+#include <string>
-#ifdef UI_WINDOWS
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#endif
//-------------------------------------------------
// Custom UI menu
@@ -39,9 +40,9 @@ private:
COLORS_MENU,
HIDE_MENU
};
- static const char *hide_status[];
+ static const char *const hide_status[];
std::vector<std::string> m_lang;
- UINT16 m_currlang;
+ std::uint16_t m_currlang;
};
//-------------------------------------------------
@@ -67,14 +68,12 @@ private:
MUI_ITALIC
};
-#ifdef UI_WINDOWS
- UINT16 m_actual;
- std::vector<std::string> m_fonts;
- bool m_bold, m_italic;
-
void list();
- static int CALLBACK EnumFontFamiliesExProc(const LOGFONT *lpelfe, const TEXTMETRIC *lpntme, DWORD FontType, LPARAM lParam);
+ std::uint16_t m_actual;
+ std::vector<std::pair<std::string, std::string> > m_fonts;
+#ifdef UI_WINDOWS
+ bool m_bold, m_italic;
#endif
float m_info_min, m_info_max, m_info_size;
@@ -182,4 +181,4 @@ private:
rgb_t &m_original;
};
-#endif /* __UI_CUSTUI_H__ */
+#endif // MAME_EMU_UI_UI_CUSTUI_H
diff --git a/src/emu/ui/datfile.cpp b/src/emu/ui/datfile.cpp
index 7a5ebb57e6f..799cdaf3823 100644
--- a/src/emu/ui/datfile.cpp
+++ b/src/emu/ui/datfile.cpp
@@ -1,5 +1,5 @@
// license:BSD-3-Clause
-// copyright-holders:Dankan1890
+// copyright-holders:Maurizio Petrarota
/***************************************************************************
ui/datfile.cpp
@@ -548,7 +548,7 @@ bool datfile_manager::parseopen(const char *filename)
// so it's better and faster use standard C fileio functions.
emu_file file(machine().ui().options().history_path(), OPEN_FLAG_READ);
- if (file.open(filename) != FILERR_NONE)
+ if (file.open(filename) != osd_file::error::NONE)
return false;
m_fullpath = file.fullpath();
diff --git a/src/emu/ui/datfile.h b/src/emu/ui/datfile.h
index 7b38599ba21..fa5f527a635 100644
--- a/src/emu/ui/datfile.h
+++ b/src/emu/ui/datfile.h
@@ -1,5 +1,5 @@
// license:BSD-3-Clause
-// copyright-holders:Dankan1890
+// copyright-holders:Maurizio Petrarota
/***************************************************************************
ui/datfile.h
diff --git a/src/emu/ui/datmenu.cpp b/src/emu/ui/datmenu.cpp
index 93c776f3e51..c623c8d1f2c 100644
--- a/src/emu/ui/datmenu.cpp
+++ b/src/emu/ui/datmenu.cpp
@@ -1,5 +1,5 @@
// license:BSD-3-Clause
-// copyright-holders:Dankan1890
+// copyright-holders:Maurizio Petrarota
/*********************************************************************
ui/datmenu.cpp
@@ -22,7 +22,12 @@
// ctor / dtor
//-------------------------------------------------
-ui_menu_dats_view::ui_menu_dats_view(running_machine &machine, render_container *container, const game_driver *driver) : ui_menu(machine, container)
+ui_menu_dats_view::ui_menu_dats_view(running_machine &machine, render_container *container, const game_driver *driver)
+ : ui_menu(machine, container)
+ , m_actual(0)
+ , m_driver((driver == nullptr) ? &machine.system() : driver)
+ , m_issoft(false)
+
{
image_interface_iterator iter(machine.root_device());
for (device_image_interface *image = iter.first(); image != nullptr; image = iter.next())
@@ -35,7 +40,6 @@ ui_menu_dats_view::ui_menu_dats_view(running_machine &machine, render_container
m_parent = strensure(image->software_entry()->parentname());
}
}
- m_driver = (driver == nullptr) ? &machine.system() : driver;
init_items();
}
@@ -44,17 +48,18 @@ ui_menu_dats_view::ui_menu_dats_view(running_machine &machine, render_container
// ctor
//-------------------------------------------------
-ui_menu_dats_view::ui_menu_dats_view(running_machine &machine, render_container *container, ui_software_info *swinfo, const game_driver *driver) : ui_menu(machine, container)
-{
- m_list = swinfo->listname;
- m_short = swinfo->shortname;
- m_long = swinfo->longname;
- m_parent = swinfo->parentname;
- m_driver = (driver == nullptr) ? &machine.system() : driver;
- m_swinfo = swinfo;
-
- issoft = true;
+ui_menu_dats_view::ui_menu_dats_view(running_machine &machine, render_container *container, ui_software_info *swinfo, const game_driver *driver)
+ : ui_menu(machine, container)
+ , m_actual(0)
+ , m_driver((driver == nullptr) ? &machine.system() : driver)
+ , m_swinfo(swinfo)
+ , m_list(swinfo->listname)
+ , m_short(swinfo->shortname)
+ , m_long(swinfo->longname)
+ , m_parent(swinfo->parentname)
+ , m_issoft(true)
+{
if (machine.datfile().has_software(m_list, m_short, m_parent))
m_items_list.emplace_back(_("Software History"), UI_HISTORY_LOAD, machine.datfile().rev_history());
if (swinfo != nullptr && !swinfo->usage.empty())
@@ -78,15 +83,15 @@ void ui_menu_dats_view::handle()
const ui_menu_event *m_event = process(MENU_FLAG_UI_DATS);
if (m_event != nullptr)
{
- if (m_event->iptkey == IPT_UI_LEFT && actual > 0)
+ if (m_event->iptkey == IPT_UI_LEFT && m_actual > 0)
{
- actual--;
+ m_actual--;
reset(UI_MENU_RESET_SELECT_FIRST);
}
- if (m_event->iptkey == IPT_UI_RIGHT && actual < m_items_list.size() - 1)
+ if (m_event->iptkey == IPT_UI_RIGHT && m_actual < m_items_list.size() - 1)
{
- actual++;
+ m_actual++;
reset(UI_MENU_RESET_SELECT_FIRST);
}
}
@@ -98,13 +103,18 @@ void ui_menu_dats_view::handle()
void ui_menu_dats_view::populate()
{
- machine().pause();
- (issoft == true) ? get_data_sw() : get_data();
+ bool paused = machine().paused();
+ if (!paused)
+ machine().pause();
+
+ (m_issoft == true) ? get_data_sw() : get_data();
item_append(MENU_SEPARATOR_ITEM, nullptr, (MENU_FLAG_UI_DATS | MENU_FLAG_LEFT_ARROW | MENU_FLAG_RIGHT_ARROW), nullptr);
customtop = 2.0f * machine().ui().get_line_height() + 4.0f * UI_BOX_TB_BORDER;
custombottom = machine().ui().get_line_height() + 3.0f * UI_BOX_TB_BORDER;
- machine().resume();
+
+ if (!paused)
+ machine().resume();
}
//-------------------------------------------------
@@ -116,7 +126,7 @@ void ui_menu_dats_view::custom_render(void *selectedref, float top, float bottom
ui_manager &mui = machine().ui();
float maxwidth = origx2 - origx1;
float width;
- std::string driver = (issoft == true) ? m_swinfo->longname : m_driver->description;
+ std::string driver = (m_issoft == true) ? m_swinfo->longname : m_driver->description;
mui.draw_text_full(container, driver.c_str(), 0.0f, 0.0f, 1.0f, JUSTIFY_CENTER, WRAP_TRUNCATE,
DRAW_NONE, ARGB_WHITE, ARGB_BLACK, &width, nullptr);
@@ -168,25 +178,23 @@ void ui_menu_dats_view::custom_render(void *selectedref, float top, float bottom
for (auto & elem : m_items_list)
{
x1 += space;
- rgb_t fcolor = (actual == x) ? rgb_t(0xff, 0xff, 0xff, 0x00) : UI_TEXT_COLOR;
- rgb_t bcolor = (actual == x) ? rgb_t(0xff, 0xff, 0xff, 0xff) : UI_TEXT_BG_COLOR;
- mui.draw_text_full(container, elem.label.c_str(), x1, y1, 1.0f, JUSTIFY_LEFT, WRAP_NEVER,
- DRAW_NONE, fcolor, bcolor, &width, nullptr);
+ rgb_t fcolor = (m_actual == x) ? rgb_t(0xff, 0xff, 0xff, 0x00) : UI_TEXT_COLOR;
+ rgb_t bcolor = (m_actual == x) ? rgb_t(0xff, 0xff, 0xff, 0xff) : UI_TEXT_BG_COLOR;
+ mui.draw_text_full(container, elem.label.c_str(), x1, y1, 1.0f, JUSTIFY_LEFT, WRAP_NEVER, DRAW_NONE, fcolor, bcolor, &width, nullptr);
+
if (bcolor != UI_TEXT_BG_COLOR)
mui.draw_textured_box(container, x1 - (space / 2), y1, x1 + width + (space / 2), y2, bcolor, rgb_t(255, 43, 43, 43),
hilight_main_texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXWRAP(TRUE));
- mui.draw_text_full(container, elem.label.c_str(), x1, y1, 1.0f, JUSTIFY_LEFT, WRAP_NEVER,
- DRAW_NORMAL, fcolor, bcolor, &width, nullptr);
+ mui.draw_text_full(container, elem.label.c_str(), x1, y1, 1.0f, JUSTIFY_LEFT, WRAP_NEVER, DRAW_NORMAL, fcolor, bcolor, &width, nullptr);
x1 += width + space;
++x;
}
// bottom
std::string revision;
- revision.assign(_("Revision: ")).append(m_items_list[actual].revision);
- mui.draw_text_full(container, revision.c_str(), 0.0f, 0.0f, 1.0f, JUSTIFY_CENTER, WRAP_TRUNCATE,
- DRAW_NONE, ARGB_WHITE, ARGB_BLACK, &width, nullptr);
+ revision.assign(_("Revision: ")).append(m_items_list[m_actual].revision);
+ mui.draw_text_full(container, revision.c_str(), 0.0f, 0.0f, 1.0f, JUSTIFY_CENTER, WRAP_TRUNCATE, DRAW_NONE, ARGB_WHITE, ARGB_BLACK, &width, nullptr);
width += 2 * UI_BOX_LR_BORDER;
maxwidth = MAX(origx2 - origx1, width);
@@ -206,7 +214,7 @@ void ui_menu_dats_view::custom_render(void *selectedref, float top, float bottom
// draw the text within it
mui.draw_text_full(container, revision.c_str(), x1, y1, x2 - x1, JUSTIFY_CENTER, WRAP_TRUNCATE,
- DRAW_NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr);
+ DRAW_NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr);
}
//-------------------------------------------------
@@ -219,7 +227,7 @@ void ui_menu_dats_view::get_data()
std::vector<int> xend;
std::string buffer;
std::vector<std::string> m_item;
- if (m_items_list[actual].option == UI_COMMAND_LOAD)
+ if (m_items_list[m_actual].option == UI_COMMAND_LOAD)
{
machine().datfile().command_sub_menu(m_driver, m_item);
if (!m_item.empty())
@@ -236,7 +244,7 @@ void ui_menu_dats_view::get_data()
}
}
else
- machine().datfile().load_data_info(m_driver, buffer, m_items_list[actual].option);
+ machine().datfile().load_data_info(m_driver, buffer, m_items_list[m_actual].option);
int totallines = machine().ui().wrap_text(container, buffer.c_str(), 0.0f, 0.0f, 1.0f - (4.0f * UI_BOX_LR_BORDER), xstart, xend);
for (int x = 0; x < totallines; ++x)
@@ -251,8 +259,7 @@ void ui_menu_dats_view::get_data_sw()
std::vector<int> xstart;
std::vector<int> xend;
std::string buffer;
- std::vector<std::string> m_item;
- if (m_items_list[actual].option == 0)
+ if (m_items_list[m_actual].option == 0)
buffer = m_swinfo->usage;
else
{
diff --git a/src/emu/ui/datmenu.h b/src/emu/ui/datmenu.h
index 0d2ae7d686d..10de3894816 100644
--- a/src/emu/ui/datmenu.h
+++ b/src/emu/ui/datmenu.h
@@ -1,5 +1,5 @@
// license:BSD-3-Clause
-// copyright-holders:Dankan1890
+// copyright-holders:Maurizio Petrarota
/***************************************************************************
ui/datmenu.h
@@ -31,14 +31,14 @@ public:
virtual void custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2) override;
private:
- int actual;
+ int m_actual;
const game_driver *m_driver;
ui_software_info *m_swinfo;
std::string m_list, m_short, m_long, m_parent;
void get_data();
void get_data_sw();
void init_items();
- bool issoft;
+ bool m_issoft;
struct list_items
{
list_items(std::string l, int i, std::string rev) { label = l; option = i; revision = rev; }
diff --git a/src/emu/ui/defimg.h b/src/emu/ui/defimg.h
index 43b334b8f93..bce018449d1 100644
--- a/src/emu/ui/defimg.h
+++ b/src/emu/ui/defimg.h
@@ -1,5 +1,6 @@
// license:BSD-3-Clause
-// copyright-holders:Dankan1890
+// copyright-holders:Maurizio Petrarota
+
static const UINT32 no_avail_bmp[] =
{
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00231f20, 0x00000000, 0x00000000, 0x00000000, 0x01231f20, 0x04231f20, 0x11231f20, 0x2e231f20, 0x62231f20, 0x8e231f20, 0xb4231f20, 0xd4231f20, 0xe5231f20, 0xf2231f20, 0xfd231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xff231f20, 0xfd231f20, 0xf2231f20, 0xe5231f20, 0xd4231f20, 0xb4231f20, 0x8e231f20, 0x62231f20, 0x2e231f20, 0x11231f20, 0x04231f20, 0x01231f20, 0x00000000, 0x00000000, 0x00000000, 0x00231f20, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
diff --git a/src/emu/ui/devopt.cpp b/src/emu/ui/devopt.cpp
index f7c4ea2a88c..bafb8e77114 100644
--- a/src/emu/ui/devopt.cpp
+++ b/src/emu/ui/devopt.cpp
@@ -2,7 +2,7 @@
// copyright-holders:Nathan Woods
/*********************************************************************
- ui/devopt.c
+ ui/devopt.cpp
Internal menu for the device configuration.
diff --git a/src/emu/ui/dirmenu.cpp b/src/emu/ui/dirmenu.cpp
index 8ae0372af30..88c701b67ef 100644
--- a/src/emu/ui/dirmenu.cpp
+++ b/src/emu/ui/dirmenu.cpp
@@ -28,33 +28,34 @@ struct folders_entry
static const folders_entry s_folders[] =
{
- { __("ROMs"), OPTION_MEDIAPATH, ADDING },
- { __("UI"), OPTION_UI_PATH, CHANGE },
- { __("Language"), OPTION_LANGUAGEPATH, CHANGE },
- { __("Samples"), OPTION_SAMPLEPATH, ADDING },
- { __("DATs"), OPTION_HISTORY_PATH, ADDING },
- { __("INIs"), OPTION_INIPATH, ADDING },
- { __("Extra INIs"), OPTION_EXTRAINI_PATH, CHANGE },
- { __("Icons"), OPTION_ICONS_PATH, ADDING },
- { __("Cheats"), OPTION_CHEATPATH, ADDING },
- { __("Snapshots"), OPTION_SNAPSHOT_DIRECTORY, ADDING },
- { __("Cabinets"), OPTION_CABINETS_PATH, ADDING },
- { __("Flyers"), OPTION_FLYERS_PATH, ADDING },
- { __("Titles"), OPTION_TITLES_PATH, ADDING },
- { __("Ends"), OPTION_ENDS_PATH, ADDING },
- { __("PCBs"), OPTION_PCBS_PATH, ADDING },
- { __("Marquees"), OPTION_MARQUEES_PATH, ADDING },
- { __("Controls Panels"), OPTION_CPANELS_PATH, ADDING },
- { __("Crosshairs"), OPTION_CROSSHAIRPATH, ADDING },
- { __("Artworks"), OPTION_ARTPATH, ADDING },
- { __("Bosses"), OPTION_BOSSES_PATH, ADDING },
- { __("Artworks Preview"), OPTION_ARTPREV_PATH, ADDING },
- { __("Select"), OPTION_SELECT_PATH, ADDING },
- { __("GameOver"), OPTION_GAMEOVER_PATH, ADDING },
- { __("HowTo"), OPTION_HOWTO_PATH, ADDING },
- { __("Logos"), OPTION_LOGOS_PATH, ADDING },
- { __("Scores"), OPTION_SCORES_PATH, ADDING },
- { __("Versus"), OPTION_VERSUS_PATH, ADDING },
+ { __("ROMs"), OPTION_MEDIAPATH, ADDING },
+ { __("UI"), OPTION_UI_PATH, CHANGE },
+ { __("Language"), OPTION_LANGUAGEPATH, CHANGE },
+ { __("Samples"), OPTION_SAMPLEPATH, ADDING },
+ { __("DATs"), OPTION_HISTORY_PATH, ADDING },
+ { __("INIs"), OPTION_INIPATH, ADDING },
+ { __("Extra INIs"), OPTION_EXTRAINI_PATH, CHANGE },
+ { __("Icons"), OPTION_ICONS_PATH, ADDING },
+ { __("Cheats"), OPTION_CHEATPATH, ADDING },
+ { __("Snapshots"), OPTION_SNAPSHOT_DIRECTORY, ADDING },
+ { __("Cabinets"), OPTION_CABINETS_PATH, ADDING },
+ { __("Flyers"), OPTION_FLYERS_PATH, ADDING },
+ { __("Titles"), OPTION_TITLES_PATH, ADDING },
+ { __("Ends"), OPTION_ENDS_PATH, ADDING },
+ { __("PCBs"), OPTION_PCBS_PATH, ADDING },
+ { __("Marquees"), OPTION_MARQUEES_PATH, ADDING },
+ { __("Controls Panels"), OPTION_CPANELS_PATH, ADDING },
+ { __("Crosshairs"), OPTION_CROSSHAIRPATH, ADDING },
+ { __("Artworks"), OPTION_ARTPATH, ADDING },
+ { __("Bosses"), OPTION_BOSSES_PATH, ADDING },
+ { __("Artworks Preview"), OPTION_ARTPREV_PATH, ADDING },
+ { __("Select"), OPTION_SELECT_PATH, ADDING },
+ { __("GameOver"), OPTION_GAMEOVER_PATH, ADDING },
+ { __("HowTo"), OPTION_HOWTO_PATH, ADDING },
+ { __("Logos"), OPTION_LOGOS_PATH, ADDING },
+ { __("Scores"), OPTION_SCORES_PATH, ADDING },
+ { __("Versus"), OPTION_VERSUS_PATH, ADDING },
+ { __("Covers"), OPTION_COVER_PATH, ADDING }
};
@@ -95,7 +96,6 @@ void ui_menu_directory::handle()
void ui_menu_directory::populate()
{
-
for (auto & elem : s_folders)
item_append(_(elem.name), nullptr, 0, (void *)(FPTR)elem.action);
@@ -144,7 +144,7 @@ void ui_menu_directory::custom_render(void *selectedref, float top, float bottom
// ctor / dtor
//-------------------------------------------------
-ui_menu_display_actual::ui_menu_display_actual(running_machine &machine, render_container *container, int ref)
+ui_menu_display_actual::ui_menu_display_actual(running_machine &machine, render_container *container, int ref)
: ui_menu(machine, container), m_ref(ref)
{
}
@@ -181,9 +181,9 @@ void ui_menu_display_actual::handle()
void ui_menu_display_actual::populate()
{
m_tempbuf = string_format(_("Current %1$s Folders"), _(s_folders[m_ref].name));
- if (machine().ui().options().exists(s_folders[m_ref].option))
+ if (machine().ui().options().exists(s_folders[m_ref].option))
m_searchpath.assign(machine().ui().options().value(s_folders[m_ref].option));
- else
+ else
m_searchpath.assign(machine().options().value(s_folders[m_ref].option));
path_iterator path(m_searchpath.c_str());
@@ -238,7 +238,7 @@ void ui_menu_display_actual::custom_render(void *selectedref, float top, float b
y1 += UI_BOX_TB_BORDER;
// draw the text within it
- mui.draw_text_full(container, m_tempbuf.c_str(), x1, y1, x2 - x1, JUSTIFY_CENTER, WRAP_TRUNCATE,
+ mui.draw_text_full(container, m_tempbuf.c_str(), x1, y1, x2 - x1, JUSTIFY_CENTER, WRAP_TRUNCATE,
DRAW_NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr);
// compute our bounds
@@ -279,10 +279,7 @@ ui_menu_add_change_folder::ui_menu_add_change_folder(running_machine &machine, r
m_search[0] = '\0';
// configure the starting path
- char *dst = nullptr;
- osd_get_full_path(&dst, ".");
- m_current_path = dst;
- osd_free(dst);
+ osd_get_full_path(m_current_path, ".");
std::string searchpath;
if (machine.ui().options().exists(s_folders[m_ref].option))
@@ -571,9 +568,9 @@ void ui_menu_add_change_folder::custom_render(void *selectedref, float top, floa
ui_menu_remove_folder::ui_menu_remove_folder(running_machine &machine, render_container *container, int ref) : ui_menu(machine, container)
{
m_ref = ref;
- if (machine.ui().options().exists(s_folders[m_ref].option))
+ if (machine.ui().options().exists(s_folders[m_ref].option))
m_searchpath.assign(machine.ui().options().value(s_folders[m_ref].option));
- else
+ else
m_searchpath.assign(machine.options().value(s_folders[m_ref].option));
path_iterator path(m_searchpath.c_str());
@@ -609,7 +606,7 @@ void ui_menu_remove_folder::handle()
machine().ui().options().set_value(s_folders[m_ref].option, tmppath.c_str(), OPTION_PRIORITY_CMDLINE, error_string);
else if (strcmp(machine().options().value(s_folders[m_ref].option),tmppath.c_str())!=0)
{
- machine().options().set_value(s_folders[m_ref].option, tmppath.c_str(), OPTION_PRIORITY_CMDLINE, error_string);
+ machine().options().set_value(s_folders[m_ref].option, tmppath.c_str(), OPTION_PRIORITY_CMDLINE, error_string);
machine().options().mark_changed(s_folders[m_ref].option);
}
@@ -662,6 +659,6 @@ void ui_menu_remove_folder::custom_render(void *selectedref, float top, float bo
y1 += UI_BOX_TB_BORDER;
// draw the text within it
- mui.draw_text_full(container, tempbuf.c_str(), x1, y1, x2 - x1, JUSTIFY_CENTER, WRAP_NEVER, DRAW_NORMAL,
+ mui.draw_text_full(container, tempbuf.c_str(), x1, y1, x2 - x1, JUSTIFY_CENTER, WRAP_NEVER, DRAW_NORMAL,
UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr);
}
diff --git a/src/emu/ui/dirmenu.h b/src/emu/ui/dirmenu.h
index 5c48d9ad696..6b68764b258 100644
--- a/src/emu/ui/dirmenu.h
+++ b/src/emu/ui/dirmenu.h
@@ -1,5 +1,5 @@
// license:BSD-3-Clause
-// copyright-holders:Dankan1890
+// copyright-holders:Maurizio Petrarota
/***************************************************************************
ui/dirmenu.h
diff --git a/src/emu/ui/dsplmenu.cpp b/src/emu/ui/dsplmenu.cpp
index 22cec681670..5c745e40383 100644
--- a/src/emu/ui/dsplmenu.cpp
+++ b/src/emu/ui/dsplmenu.cpp
@@ -1,5 +1,5 @@
// license:BSD-3-Clause
-// copyright-holders:Dankan1890
+// copyright-holders:Maurizio Petrarota
/*********************************************************************
ui/dsplmenu.cpp
diff --git a/src/emu/ui/dsplmenu.h b/src/emu/ui/dsplmenu.h
index 814304ec6bd..69b92e3bbe0 100644
--- a/src/emu/ui/dsplmenu.h
+++ b/src/emu/ui/dsplmenu.h
@@ -1,5 +1,5 @@
// license:BSD-3-Clause
-// copyright-holders:Dankan1890
+// copyright-holders:Maurizio Petrarota
/***************************************************************************
ui/dsplmenu.h
diff --git a/src/emu/ui/filemngr.cpp b/src/emu/ui/filemngr.cpp
index d46199793ce..fa139e1c696 100644
--- a/src/emu/ui/filemngr.cpp
+++ b/src/emu/ui/filemngr.cpp
@@ -2,7 +2,7 @@
// copyright-holders:Nathan Woods
/*********************************************************************
- ui/filemngr.c
+ ui/filemngr.cpp
MESS's clunky built-in file manager
diff --git a/src/emu/ui/filesel.cpp b/src/emu/ui/filesel.cpp
index ec8d4c2ea22..7a8cd32ec94 100644
--- a/src/emu/ui/filesel.cpp
+++ b/src/emu/ui/filesel.cpp
@@ -2,7 +2,7 @@
// copyright-holders:Nathan Woods
/***************************************************************************
- ui/filesel.c
+ ui/filesel.cpp
MESS's clunky built-in file manager
@@ -474,7 +474,7 @@ ui_menu_file_selector::file_selector_entry *ui_menu_file_selector::append_dirent
}
// determine the full path
- zippath_combine(buffer, m_current_directory.c_str(), dirent->name);
+ util::zippath_combine(buffer, m_current_directory.c_str(), dirent->name);
// create the file selector entry
entry = append_entry(
@@ -535,8 +535,8 @@ void ui_menu_file_selector::append_entry_menu_item(const file_selector_entry *en
void ui_menu_file_selector::populate()
{
- zippath_directory *directory = nullptr;
- file_error err;
+ util::zippath_directory *directory = nullptr;
+ osd_file::error err;
const osd_directory_entry *dirent;
const file_selector_entry *entry;
const file_selector_entry *selected_entry = nullptr;
@@ -545,7 +545,7 @@ void ui_menu_file_selector::populate()
const char *path = m_current_directory.c_str();
// open the directory
- err = zippath_opendir(path, &directory);
+ err = util::zippath_opendir(path, &directory);
// clear out the menu entries
m_entrylist = nullptr;
@@ -579,9 +579,9 @@ void ui_menu_file_selector::populate()
}
// build the menu for each item
- if (err == FILERR_NONE)
+ if (err == osd_file::error::NONE)
{
- while((dirent = zippath_readdir(directory)) != nullptr)
+ while((dirent = util::zippath_readdir(directory)) != nullptr)
{
// append a dirent entry
entry = append_dirent_entry(dirent);
@@ -611,7 +611,7 @@ void ui_menu_file_selector::populate()
customtop = machine().ui().get_line_height() + 3.0f * UI_BOX_TB_BORDER;
if (directory != nullptr)
- zippath_closedir(directory);
+ util::zippath_closedir(directory);
}
@@ -621,7 +621,7 @@ void ui_menu_file_selector::populate()
void ui_menu_file_selector::handle()
{
- file_error err;
+ osd_file::error err;
const file_selector_entry *entry;
const file_selector_entry *selected_entry = nullptr;
int bestmatch = 0;
@@ -656,8 +656,8 @@ void ui_menu_file_selector::handle()
case SELECTOR_ENTRY_TYPE_DRIVE:
case SELECTOR_ENTRY_TYPE_DIRECTORY:
// drive/directory - first check the path
- err = zippath_opendir(entry->fullpath, nullptr);
- if (err != FILERR_NONE)
+ err = util::zippath_opendir(entry->fullpath, nullptr);
+ if (err != osd_file::error::NONE)
{
// this path is problematic; present the user with an error and bail
machine().ui().popup_time(1, "Error accessing %s", entry->fullpath);
diff --git a/src/emu/ui/icorender.h b/src/emu/ui/icorender.h
index eec52b7e3ed..ac942ac922e 100644
--- a/src/emu/ui/icorender.h
+++ b/src/emu/ui/icorender.h
@@ -1,5 +1,5 @@
// license:BSD-3-Clause
-// copyright-holders:Dankan1890;Victor Laskin
+// copyright-holders:Maurizio Petrarota, Victor Laskin
/***************************************************************************
ui/icorender.h
@@ -80,9 +80,9 @@ void render_load_ico(bitmap_argb32 &bitmap, emu_file &file, const char *dirname,
else
fname.assign(dirname).append(PATH_SEPARATOR).append(filename);
- file_error filerr = file.open(fname.c_str());
+ osd_file::error filerr = file.open(fname.c_str());
- if (filerr != FILERR_NONE)
+ if (filerr != osd_file::error::NONE)
return;
// allocates a buffer for the image
diff --git a/src/emu/ui/imgcntrl.cpp b/src/emu/ui/imgcntrl.cpp
index 3b96f63971e..0b44f1f8e8c 100644
--- a/src/emu/ui/imgcntrl.cpp
+++ b/src/emu/ui/imgcntrl.cpp
@@ -59,12 +59,12 @@ ui_menu_control_device_image::ui_menu_control_device_image(running_machine &mach
if (image->exists())
{
current_file.assign(image->filename());
- zippath_parent(current_directory, current_file.c_str());
+ util::zippath_parent(current_directory, current_file.c_str());
} else
current_directory.assign(image->working_directory());
/* check to see if the path exists; if not clear it */
- if (zippath_opendir(current_directory.c_str(), nullptr) != FILERR_NONE)
+ if (util::zippath_opendir(current_directory.c_str(), nullptr) != osd_file::error::NONE)
current_directory.clear();
}
}
@@ -90,7 +90,7 @@ void ui_menu_control_device_image::test_create(bool &can_create, bool &need_conf
osd_dir_entry_type file_type;
/* assemble the full path */
- zippath_combine(path, current_directory.c_str(), current_file.c_str());
+ util::zippath_combine(path, current_directory.c_str(), current_file.c_str());
/* does a file or a directory exist at the path */
entry = osd_stat(path.c_str());
@@ -183,11 +183,11 @@ void ui_menu_control_device_image::handle()
case START_FILE: {
bool can_create = false;
if(image->is_creatable()) {
- zippath_directory *directory = nullptr;
- file_error err = zippath_opendir(current_directory.c_str(), &directory);
- can_create = err == FILERR_NONE && !zippath_is_zip(directory);
+ util::zippath_directory *directory = nullptr;
+ osd_file::error err = util::zippath_opendir(current_directory.c_str(), &directory);
+ can_create = err == osd_file::error::NONE && !util::zippath_is_zip(directory);
if(directory)
- zippath_closedir(directory);
+ util::zippath_closedir(directory);
}
submenu_result = -1;
ui_menu::stack_push(global_alloc_clear<ui_menu_file_selector>(machine(), container, image, current_directory, current_file, true, image->image_interface()!=nullptr, can_create, &submenu_result));
@@ -335,7 +335,7 @@ void ui_menu_control_device_image::handle()
case DO_CREATE: {
std::string path;
- zippath_combine(path, current_directory.c_str(), current_file.c_str());
+ util::zippath_combine(path, current_directory.c_str(), current_file.c_str());
int err = image->create(path.c_str(), nullptr, nullptr);
if (err != 0)
machine().popmessage("Error: %s", image->error());
diff --git a/src/emu/ui/info.cpp b/src/emu/ui/info.cpp
index 8c202f77e91..10090c32305 100644
--- a/src/emu/ui/info.cpp
+++ b/src/emu/ui/info.cpp
@@ -2,7 +2,7 @@
// copyright-holders:Nicola Salmoria, Aaron Giles, Nathan Woods
/***************************************************************************
- ui/info.c
+ ui/info.cpp
System and image info screens
diff --git a/src/emu/ui/info_pty.cpp b/src/emu/ui/info_pty.cpp
index 06497b876bb..563b77dbff5 100644
--- a/src/emu/ui/info_pty.cpp
+++ b/src/emu/ui/info_pty.cpp
@@ -2,7 +2,7 @@
// copyright-holders:F.Ulivi
/***************************************************************************
- ui/info_pty.c
+ ui/info_pty.cpp
Information screen on pseudo terminals
diff --git a/src/emu/ui/inifile.cpp b/src/emu/ui/inifile.cpp
index 8958fe4cd3b..33bd433a7f7 100644
--- a/src/emu/ui/inifile.cpp
+++ b/src/emu/ui/inifile.cpp
@@ -1,5 +1,5 @@
// license:BSD-3-Clause
-// copyright-holders:Dankan1890
+// copyright-holders:Maurizio Petrarota
/***************************************************************************
ui/inifile.cpp
@@ -18,8 +18,8 @@
//-------------------------------------------------
// GLOBAL VARIABLES
//-------------------------------------------------
-UINT16 inifile_manager::current_category = 0;
-UINT16 inifile_manager::current_file = 0;
+UINT16 inifile_manager::c_cat = 0;
+UINT16 inifile_manager::c_file = 0;
//-------------------------------------------------
// ctor
@@ -48,10 +48,6 @@ void inifile_manager::directory_scan()
int length = strlen(dir->name);
std::string filename(dir->name);
- // skip ui_favorite file
- if (!core_stricmp("ui_favorite.ini", filename.c_str()))
- continue;
-
// check .ini file ending
if ((length > 4) && dir->name[length - 4] == '.' && tolower((UINT8)dir->name[length - 3]) == 'i' &&
tolower((UINT8)dir->name[length - 2]) == 'n' && tolower((UINT8)dir->name[length - 1]) == 'i')
@@ -103,8 +99,8 @@ void inifile_manager::load_ini_category(std::vector<int> &temp_filter)
return;
bool search_clones = false;
- std::string filename(ini_index[current_file].name);
- long offset = ini_index[current_file].category[current_category].offset;
+ std::string filename(ini_index[c_file].first);
+ long offset = ini_index[c_file].second[c_cat].second;
if (!core_stricmp(filename.c_str(), "category.ini") || !core_stricmp(filename.c_str(), "alltime.ini"))
search_clones = true;
@@ -151,7 +147,7 @@ bool inifile_manager::parseopen(const char *filename)
// so it's better and faster use standard C fileio functions.
emu_file file(machine().ui().options().extraini_path(), OPEN_FLAG_READ);
- if (file.open(filename) != FILERR_NONE)
+ if (file.open(filename) != osd_file::error::NONE)
return false;
m_fullpath = file.fullpath();
@@ -359,7 +355,7 @@ bool favorite_manager::isgame_favorite(ui_software_info &swinfo)
void favorite_manager::parse_favorite()
{
emu_file file(machine().ui().options().ui_path(), OPEN_FLAG_READ);
- if (file.open(favorite_filename) == FILERR_NONE)
+ if (file.open(favorite_filename) == osd_file::error::NONE)
{
char readbuf[1024];
file.gets(readbuf, 1024);
@@ -418,7 +414,7 @@ void favorite_manager::save_favorite_games()
{
// attempt to open the output file
emu_file file(machine().ui().options().ui_path(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
- if (file.open(favorite_filename) == FILERR_NONE)
+ if (file.open(favorite_filename) == osd_file::error::NONE)
{
if (m_list.empty())
{
diff --git a/src/emu/ui/inifile.h b/src/emu/ui/inifile.h
index 5c9e7ebdc65..c16617b25f1 100644
--- a/src/emu/ui/inifile.h
+++ b/src/emu/ui/inifile.h
@@ -1,5 +1,5 @@
// license:BSD-3-Clause
-// copyright-holders:Dankan1890
+// copyright-holders:Maurizio Petrarota
/***************************************************************************
ui/inifile.h
@@ -22,41 +22,36 @@
class inifile_manager
{
public:
- // category structure
- struct IniCategoryIndex
- {
- IniCategoryIndex(std::string _name, long _offset) { name = _name; offset = _offset; }
- std::string name;
- long offset;
- };
-
- using categoryindex = std::vector<IniCategoryIndex>;
-
- // ini file structure
- struct IniFileIndex
- {
- IniFileIndex(std::string _name, categoryindex _category) { name = _name; category = _category; }
- std::string name;
- categoryindex category;
- };
-
// construction/destruction
inifile_manager(running_machine &machine);
// getters
running_machine &machine() const { return m_machine; }
+ std::string get_file(int file = -1) { return ((file == -1) ? ini_index[c_file].first : ini_index[file].first); }
+ std::string get_category(int cat = -1) { return ((cat == -1) ? ini_index[c_file].second[c_cat].first : ini_index[c_file].second[cat].first); }
+ size_t total() { return ini_index.size(); }
+ size_t cat_total() { return ini_index[c_file].second.size(); }
+ UINT16 &cur_file() { return c_file; }
+ UINT16 &cur_cat() { return c_cat; }
// load games from category
void load_ini_category(std::vector<int> &temp_filter);
- // files indices
- std::vector<IniFileIndex> ini_index;
- static UINT16 current_file, current_category;
-
- std::string actual_file() { return ini_index[current_file].name; }
- std::string actual_category() { return ini_index[current_file].category[current_category].name; }
+ // setters
+ void move_file(int d) { c_file += d; c_cat = 0; }
+ void move_cat(int d) { c_cat += d; }
+ void set_cat(int i = -1) { (i == -1) ? c_cat = 0 : c_cat = i; }
+ void set_file(int i = -1) { (i == -1) ? c_file = 0 : c_file = i; }
private:
+
+ // ini file structure
+ using categoryindex = std::vector<std::pair<std::string, long>>;
+
+ // files indices
+ static UINT16 c_file, c_cat;
+ std::vector<std::pair<std::string, categoryindex>> ini_index;
+
// init category index
void init_category(std::string &filename);
diff --git a/src/emu/ui/inputmap.cpp b/src/emu/ui/inputmap.cpp
index 5ecb4546cce..df146fcf3e1 100644
--- a/src/emu/ui/inputmap.cpp
+++ b/src/emu/ui/inputmap.cpp
@@ -2,7 +2,7 @@
// copyright-holders:Nicola Salmoria, Aaron Giles, Nathan Woods
/*********************************************************************
- ui/inputmap.c
+ ui/inputmap.cpp
Internal menus for input mappings.
diff --git a/src/emu/ui/mainmenu.cpp b/src/emu/ui/mainmenu.cpp
index 0cf449e8f84..7fe16d771b0 100644
--- a/src/emu/ui/mainmenu.cpp
+++ b/src/emu/ui/mainmenu.cpp
@@ -2,7 +2,7 @@
// copyright-holders:Nicola Salmoria, Aaron Giles, Nathan Woods
/*********************************************************************
- ui/mainmenu.c
+ ui/mainmenu.cpp
Internal MAME menus for the user interface.
diff --git a/src/emu/ui/menu.cpp b/src/emu/ui/menu.cpp
index ccc73f55002..17153c41b78 100644
--- a/src/emu/ui/menu.cpp
+++ b/src/emu/ui/menu.cpp
@@ -35,27 +35,28 @@
struct ui_arts_info
{
- const char *title, *path, *addpath;
+ const char *title, *path;
};
static const ui_arts_info arts_info[] =
{
- { __("Snapshots"), OPTION_SNAPSHOT_DIRECTORY, "snap" },
- { __("Cabinets"), OPTION_CABINETS_PATH, "cabinets;cabdevs" },
- { __("Control Panels"), OPTION_CPANELS_PATH, "cpanel" },
- { __("PCBs"), OPTION_PCBS_PATH, "pcb" },
- { __("Flyers"), OPTION_FLYERS_PATH, "flyers" },
- { __("Titles"), OPTION_TITLES_PATH, "titles" },
- { __("Ends"), OPTION_ENDS_PATH, "ends" },
- { __("Artwork Preview"), OPTION_ARTPREV_PATH, "artwork preview" },
- { __("Bosses"), OPTION_BOSSES_PATH, "bosses" },
- { __("Logos"), OPTION_LOGOS_PATH, "logo" },
- { __("Versus"), OPTION_VERSUS_PATH, "versus" },
- { __("Game Over"), OPTION_GAMEOVER_PATH, "gameover" },
- { __("HowTo"), OPTION_HOWTO_PATH, "howto" },
- { __("Scores"), OPTION_SCORES_PATH, "scores" },
- { __("Select"), OPTION_SELECT_PATH, "select" },
- { __("Marquees"), OPTION_MARQUEES_PATH, "marquees" },
+ { __("Snapshots"), OPTION_SNAPSHOT_DIRECTORY },
+ { __("Cabinets"), OPTION_CABINETS_PATH },
+ { __("Control Panels"), OPTION_CPANELS_PATH },
+ { __("PCBs"), OPTION_PCBS_PATH },
+ { __("Flyers"), OPTION_FLYERS_PATH },
+ { __("Titles"), OPTION_TITLES_PATH },
+ { __("Ends"), OPTION_ENDS_PATH },
+ { __("Artwork Preview"), OPTION_ARTPREV_PATH },
+ { __("Bosses"), OPTION_BOSSES_PATH },
+ { __("Logos"), OPTION_LOGOS_PATH },
+ { __("Versus"), OPTION_VERSUS_PATH },
+ { __("Game Over"), OPTION_GAMEOVER_PATH },
+ { __("HowTo"), OPTION_HOWTO_PATH },
+ { __("Scores"), OPTION_SCORES_PATH },
+ { __("Select"), OPTION_SELECT_PATH },
+ { __("Marquees"), OPTION_MARQUEES_PATH },
+ { __("Covers"), OPTION_COVER_PATH },
{ nullptr }
};
@@ -1320,7 +1321,7 @@ void ui_menu::init_ui(running_machine &machine)
for (int i = 0; i < MAX_ICONS_RENDER; i++)
{
icons_bitmap[i] = auto_alloc(machine, bitmap_argb32);
- icons_texture[i] = mrender.texture_alloc();
+ icons_texture[i] = mrender.texture_alloc(render_texture::hq_scale);
}
// create a texture for main menu background
@@ -1646,17 +1647,24 @@ void ui_menu::get_title_search(std::string &snaptext, std::string &searchstr)
snaptext.assign(_(arts_info[ui_globals::curimage_view].title));
// get search path
+ std::string addpath;
if (ui_globals::curimage_view == SNAPSHOT_VIEW)
+ {
+ emu_options moptions;
searchstr = machine().options().value(arts_info[ui_globals::curimage_view].path);
+ addpath = moptions.value(arts_info[ui_globals::curimage_view].path);
+ }
else
+ {
+ ui_options moptions;
searchstr = machine().ui().options().value(arts_info[ui_globals::curimage_view].path);
+ addpath = moptions.value(arts_info[ui_globals::curimage_view].path);
+ }
std::string tmp(searchstr);
path_iterator path(tmp.c_str());
- std::string curpath;
-
- path_iterator path_iter(arts_info[ui_globals::curimage_view].addpath);
- std::string c_path;
+ path_iterator path_iter(addpath.c_str());
+ std::string c_path, curpath;
// iterate over path and add path for zipped formats
while (path.next(curpath))
@@ -2090,7 +2098,16 @@ float ui_menu::draw_right_box_title(float x1, float y1, float x2, float y2)
buffer[RP_IMAGES] = _("Images");
buffer[RP_INFOS] = _("Infos");
- for (int cells = RP_IMAGES; cells <= RP_INFOS; cells++)
+ // check size
+ float text_size = 1.0f;
+ for (auto & elem : buffer)
+ {
+ float textlen = mui.get_string_width(elem.c_str()) + 0.01f;
+ float tmp_size = (textlen > midl) ? (midl / textlen) : 1.0f;
+ text_size = MIN(text_size, tmp_size);
+ }
+
+ for (int cells = RP_FIRST; cells <= RP_LAST; ++cells)
{
rgb_t bgcolor = UI_TEXT_BG_COLOR;
rgb_t fgcolor = UI_TEXT_COLOR;
@@ -2126,7 +2143,7 @@ float ui_menu::draw_right_box_title(float x1, float y1, float x2, float y2)
bgcolor, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXWRAP(TRUE));
mui.draw_text_full(container, buffer[cells].c_str(), x1 + UI_LINE_WIDTH, y1, midl - UI_LINE_WIDTH,
- JUSTIFY_CENTER, WRAP_NEVER, DRAW_NORMAL, fgcolor, bgcolor, nullptr, nullptr);
+ JUSTIFY_CENTER, WRAP_NEVER, DRAW_NORMAL, fgcolor, bgcolor, nullptr, nullptr, text_size);
x1 += midl;
}
@@ -2143,6 +2160,7 @@ std::string ui_menu::arts_render_common(float origx1, float origy1, float origx2
float line_height = mui.get_line_height();
std::string snaptext, searchstr;
get_title_search(snaptext, searchstr);
+ float gutter_width = 0.4f * line_height * machine().render().ui_aspect() * 1.3f;
// apply title to right panel
float title_size = 0.0f;
@@ -2166,12 +2184,17 @@ std::string ui_menu::arts_render_common(float origx1, float origy1, float origx2
float middle = origx2 - origx1;
+ // check size
+ float sc = title_size + 2.0f * gutter_width;
+ float tmp_size = (sc > middle) ? ((middle - 2.0f * gutter_width) / sc) : 1.0f;
+ title_size *= tmp_size;
+
if (bgcolor != UI_TEXT_BG_COLOR)
mui.draw_textured_box(container, origx1 + ((middle - title_size) * 0.5f), origy1, origx1 + ((middle + title_size) * 0.5f),
origy1 + line_height, bgcolor, rgb_t(255, 43, 43, 43), hilight_main_texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXWRAP(TRUE));
mui.draw_text_full(container, snaptext.c_str(), origx1, origy1, origx2 - origx1, JUSTIFY_CENTER, WRAP_TRUNCATE,
- DRAW_NORMAL, fgcolor, bgcolor, nullptr, nullptr);
+ DRAW_NORMAL, fgcolor, bgcolor, nullptr, nullptr, tmp_size);
draw_common_arrow(origx1, origy1, origx2, origy2, ui_globals::curimage_view, FIRST_VIEW, LAST_VIEW, title_size);
@@ -2213,16 +2236,15 @@ void ui_menu::draw_toolbar(float x1, float y1, float x2, float y2, bool software
if (t_bitmap[x]->valid())
m_valid++;
- float x_pixel = 1.0f / container->manager().ui_target().width();
- int h_len = mui.get_line_height() * container->manager().ui_target().height();
- h_len = (h_len % 2 == 0) ? h_len : h_len - 1;
- x1 = (x1 + x2) * 0.5f - x_pixel * (m_valid * ((h_len / 2) + 2));
+ float space_x = (y2 - y1) * container->manager().ui_aspect();
+ float total = (m_valid * space_x) + ((m_valid - 1) * 0.01f);
+ x1 = ((x2 - x1) * 0.5f) - (total / 2);
+ x2 = x1 + space_x;
for (int z = 0; z < UI_TOOLBAR_BUTTONS; ++z)
{
if (t_bitmap[z]->valid())
{
- x2 = x1 + x_pixel * h_len;
rgb_t color(0xEFEFEFEF);
if (mouse_hit && x1 <= mouse_x && x2 > mouse_x && y1 <= mouse_y && y2 > mouse_y)
{
@@ -2233,7 +2255,8 @@ void ui_menu::draw_toolbar(float x1, float y1, float x2, float y2, bool software
}
container->add_quad(x1, y1, x2, y2, color, t_texture[z], PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA));
- x1 += x_pixel * (h_len + 2);
+ x1 += space_x + ((z < UI_TOOLBAR_BUTTONS - 1) ? 0.01f : 0.0f);
+ x2 = x1 + space_x;
}
}
}
@@ -2264,6 +2287,11 @@ void ui_menu::arts_render_images(bitmap_argb32 *tmp_bitmap, float origx1, float
float panel_height = origy2 - origy1 - 0.02f - (2.0f * UI_BOX_TB_BORDER) - (2.0f * line_height);
int screen_width = machine().render().ui_target().width();
int screen_height = machine().render().ui_target().height();
+
+ int rot = machine().render().ui_target().orientation();
+ if (rot == ROT90 || rot == ROT270)
+ std::swap(screen_height, screen_width);
+
int panel_width_pixel = panel_width * screen_width;
int panel_height_pixel = panel_height * screen_height;
float ratio = 0.0f;
@@ -2366,13 +2394,13 @@ void ui_menu::draw_common_arrow(float origx1, float origy1, float origx2, float
// apply arrow
if (current == dmin)
- container->add_quad(ar_x0, ar_y0, ar_x1, ar_y1, fgcolor_right, arrow_texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXORIENT(ROT90) | PRIMFLAG_PACKABLE);
+ draw_arrow(container, ar_x0, ar_y0, ar_x1, ar_y1, fgcolor_right, ROT90);
else if (current == dmax)
- container->add_quad(al_x0, al_y0, al_x1, al_y1, fgcolor_left, arrow_texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXORIENT(ROT90 ^ ORIENTATION_FLIP_X) | PRIMFLAG_PACKABLE);
+ draw_arrow(container, al_x0, al_y0, al_x1, al_y1, fgcolor_left, ROT90 ^ ORIENTATION_FLIP_X);
else
{
- container->add_quad(ar_x0, ar_y0, ar_x1, ar_y1, fgcolor_right, arrow_texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXORIENT(ROT90) | PRIMFLAG_PACKABLE);
- container->add_quad(al_x0, al_y0, al_x1, al_y1, fgcolor_left, arrow_texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXORIENT(ROT90 ^ ORIENTATION_FLIP_X) | PRIMFLAG_PACKABLE);
+ draw_arrow(container, ar_x0, ar_y0, ar_x1, ar_y1, fgcolor_right, ROT90);
+ draw_arrow(container, al_x0, al_y0, al_x1, al_y1, fgcolor_left, ROT90 ^ ORIENTATION_FLIP_X);
}
}
@@ -2383,7 +2411,7 @@ void ui_menu::draw_common_arrow(float origx1, float origy1, float origx2, float
void ui_menu::draw_icon(int linenum, void *selectedref, float x0, float y0)
{
static const game_driver *olddriver[MAX_ICONS_RENDER] = { nullptr };
- float x1 = x0 + machine().ui().get_line_height() * container->manager().ui_aspect(container);
+ float x1 = x0 + machine().ui().get_line_height() * container->manager().ui_aspect();
float y1 = y0 + machine().ui().get_line_height();
const game_driver *driver = (const game_driver *)selectedref;
@@ -2409,71 +2437,22 @@ void ui_menu::draw_icon(int linenum, void *selectedref, float x0, float y0)
while (path.next(curpath))
searchstr.append(";").append(curpath.c_str()).append(PATH_SEPARATOR).append("icons");
- bitmap_argb32 *tmp = auto_alloc(machine(), bitmap_argb32);
emu_file snapfile(searchstr.c_str(), OPEN_FLAG_READ);
std::string fullname = std::string(driver->name).append(".ico");
- render_load_ico(*tmp, snapfile, nullptr, fullname.c_str());
+ render_load_ico(*icons_bitmap[linenum], snapfile, nullptr, fullname.c_str());
- if (!tmp->valid() && cloneof)
+ if (!icons_bitmap[linenum]->valid() && cloneof)
{
fullname.assign(driver->parent).append(".ico");
- render_load_ico(*tmp, snapfile, nullptr, fullname.c_str());
+ render_load_ico(*icons_bitmap[linenum], snapfile, nullptr, fullname.c_str());
}
- if (tmp->valid())
+ if (icons_bitmap[linenum]->valid())
{
- float panel_width = x1 - x0;
- float panel_height = y1 - y0;
- int screen_width = machine().render().ui_target().width();
- int screen_height = machine().render().ui_target().height();
- int panel_width_pixel = panel_width * screen_width;
- int panel_height_pixel = panel_height * screen_height;
-
- // Calculate resize ratios for resizing
- float ratioW = (float)panel_width_pixel / tmp->width();
- float ratioH = (float)panel_height_pixel / tmp->height();
- int dest_xPixel = tmp->width();
- int dest_yPixel = tmp->height();
-
- if (ratioW < 1 || ratioH < 1)
- {
- // smaller ratio will ensure that the image fits in the view
- float ratio = MIN(ratioW, ratioH);
- dest_xPixel = tmp->width() * ratio;
- dest_yPixel = tmp->height() * ratio;
- }
-
- bitmap_argb32 *dest_bitmap;
- dest_bitmap = auto_alloc(machine(), bitmap_argb32);
-
- // resample if necessary
- if (dest_xPixel != tmp->width() || dest_yPixel != tmp->height())
- {
- dest_bitmap->allocate(dest_xPixel, dest_yPixel);
- render_color color = { 1.0f, 1.0f, 1.0f, 1.0f };
- render_resample_argb_bitmap_hq(*dest_bitmap, *tmp, color, true);
- }
- else
- dest_bitmap = tmp;
-
- icons_bitmap[linenum]->reset();
- icons_bitmap[linenum]->allocate(panel_width_pixel, panel_height_pixel);
-
- for (int x = 0; x < dest_xPixel; x++)
- for (int y = 0; y < dest_yPixel; y++)
- icons_bitmap[linenum]->pix32(y, x) = dest_bitmap->pix32(y, x);
-
- auto_free(machine(), dest_bitmap);
-
icons_texture[linenum]->set_bitmap(*icons_bitmap[linenum], icons_bitmap[linenum]->cliprect(), TEXFORMAT_ARGB32);
}
- else {
- if (icons_bitmap[linenum] != nullptr)
- {
- icons_bitmap[linenum]->reset();
- }
- }
- auto_free(machine(), tmp);
+ else if (icons_bitmap[linenum] != nullptr)
+ icons_bitmap[linenum]->reset();
}
if (icons_bitmap[linenum] != nullptr && icons_bitmap[linenum]->valid())
diff --git a/src/emu/ui/miscmenu.cpp b/src/emu/ui/miscmenu.cpp
index 2145069bfab..d890f4f4d35 100644
--- a/src/emu/ui/miscmenu.cpp
+++ b/src/emu/ui/miscmenu.cpp
@@ -1,8 +1,8 @@
// license:BSD-3-Clause
-// copyright-holders:Nicola Salmoria, Aaron Giles, Nathan Woods,Dankan1890
+// copyright-holders:Nicola Salmoria, Aaron Giles, Nathan Woods, Maurizio Petrarota
/*********************************************************************
- miscmenu.c
+ ui/miscmenu.cpp
Internal MAME menus for the user interface.
@@ -588,7 +588,7 @@ ui_menu_misc_options::~ui_menu_misc_options()
{
machine().ui().options().set_value(m_options[d].option, m_options[d].status, OPTION_PRIORITY_CMDLINE, error_string);
}
- else
+ else
{
if (machine().options().bool_value(m_options[d].option) != m_options[d].status)
{
@@ -634,7 +634,7 @@ void ui_menu_misc_options::populate()
{
// add options items
for (int opt = 1; opt < ARRAY_LENGTH(m_options); ++opt)
- item_append(_(m_options[opt].description), m_options[opt].status ? "On" : "Off", m_options[opt].status ? MENU_FLAG_RIGHT_ARROW : MENU_FLAG_LEFT_ARROW, (void *)(FPTR)opt);
+ item_append(_(m_options[opt].description), m_options[opt].status ? _("On") : _("Off"), m_options[opt].status ? MENU_FLAG_RIGHT_ARROW : MENU_FLAG_LEFT_ARROW, (void *)(FPTR)opt);
item_append(MENU_SEPARATOR_ITEM, nullptr, 0, nullptr);
customtop = machine().ui().get_line_height() + (3.0f * UI_BOX_TB_BORDER);
@@ -677,7 +677,7 @@ void ui_menu_misc_options::custom_render(void *selectedref, float top, float bot
// ctor / dtor
//-------------------------------------------------
-ui_menu_export::ui_menu_export(running_machine &machine, render_container *container, std::vector<const game_driver *> drvlist)
+ui_menu_export::ui_menu_export(running_machine &machine, render_container *container, std::vector<const game_driver *> drvlist)
: ui_menu(machine, container), m_list(drvlist)
{
}
@@ -705,11 +705,11 @@ void ui_menu_export::handle()
{
std::string filename("exported");
emu_file infile(machine().ui().options().ui_path(), OPEN_FLAG_READ);
- if (infile.open(filename.c_str(), ".xml") == FILERR_NONE)
+ if (infile.open(filename.c_str(), ".xml") == osd_file::error::NONE)
for (int seq = 0; ; ++seq)
{
std::string seqtext = string_format("%s_%04d", filename, seq);
- if (infile.open(seqtext.c_str(), ".xml") != FILERR_NONE)
+ if (infile.open(seqtext.c_str(), ".xml") != osd_file::error::NONE)
{
filename = seqtext;
break;
@@ -718,7 +718,7 @@ void ui_menu_export::handle()
// attempt to open the output file
emu_file file(machine().ui().options().ui_path(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
- if (file.open(filename.c_str(), ".xml") == FILERR_NONE)
+ if (file.open(filename.c_str(), ".xml") == osd_file::error::NONE)
{
FILE *pfile;
std::string fullpath(file.fullpath());
@@ -745,11 +745,11 @@ void ui_menu_export::handle()
{
std::string filename("exported");
emu_file infile(machine().ui().options().ui_path(), OPEN_FLAG_READ);
- if (infile.open(filename.c_str(), ".txt") == FILERR_NONE)
+ if (infile.open(filename.c_str(), ".txt") == osd_file::error::NONE)
for (int seq = 0; ; ++seq)
{
std::string seqtext = string_format("%s_%04d", filename, seq);
- if (infile.open(seqtext.c_str(), ".txt") != FILERR_NONE)
+ if (infile.open(seqtext.c_str(), ".txt") != osd_file::error::NONE)
{
filename = seqtext;
break;
@@ -758,7 +758,7 @@ void ui_menu_export::handle()
// attempt to open the output file
emu_file file(machine().ui().options().ui_path(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
- if (file.open(filename.c_str(), ".txt") == FILERR_NONE)
+ if (file.open(filename.c_str(), ".txt") == osd_file::error::NONE)
{
// print the header
std::ostringstream buffer;
@@ -829,8 +829,8 @@ void ui_menu_machine_configure::handle()
{
std::string filename(m_drv->name);
emu_file file(machine().options().ini_path(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE);
- file_error filerr = file.open(filename.c_str(), ".ini");
- if (filerr == FILERR_NONE)
+ osd_file::error filerr = file.open(filename.c_str(), ".ini");
+ if (filerr == osd_file::error::NONE)
{
std::string inistring = machine().options().output_ini();
file.puts(inistring.c_str());
@@ -889,4 +889,4 @@ void ui_menu_machine_configure::custom_render(void *selectedref, float top, floa
// draw the text within it
mui.draw_text_full(container, m_drv->description, x1, y1, x2 - x1, JUSTIFY_CENTER, WRAP_TRUNCATE,
DRAW_NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr);
-} \ No newline at end of file
+}
diff --git a/src/emu/ui/moptions.cpp b/src/emu/ui/moptions.cpp
index de0b627ee9f..4f41c7fbdac 100644
--- a/src/emu/ui/moptions.cpp
+++ b/src/emu/ui/moptions.cpp
@@ -2,7 +2,7 @@
// copyright-holders:Maurizio Petrarota
/***************************************************************************
- ui/moptions.c
+ ui/moptions.cpp
UI main options manager.
@@ -19,26 +19,27 @@
const options_entry ui_options::s_option_entries[] =
{
// seach path options
- { nullptr, nullptr, OPTION_HEADER, "UI SEARCH PATH OPTIONS" },
- { OPTION_HISTORY_PATH, "history;dats;.", OPTION_STRING, "path to history files" },
- { OPTION_EXTRAINI_PATH, "folders", OPTION_STRING, "path to extra ini files" },
- { OPTION_CABINETS_PATH, "cabinets;cabdevs", OPTION_STRING, "path to cabinets / devices image" },
- { OPTION_CPANELS_PATH, "cpanel", OPTION_STRING, "path to control panel image" },
- { OPTION_PCBS_PATH, "pcb", OPTION_STRING, "path to pcbs image" },
- { OPTION_FLYERS_PATH, "flyers", OPTION_STRING, "path to flyers image" },
- { OPTION_TITLES_PATH, "titles", OPTION_STRING, "path to titles image" },
- { OPTION_ENDS_PATH, "ends", OPTION_STRING, "path to ends image" },
- { OPTION_MARQUEES_PATH, "marquees", OPTION_STRING, "path to marquees image" },
- { OPTION_ARTPREV_PATH, "artwork preview", OPTION_STRING, "path to artwork preview image" },
- { OPTION_BOSSES_PATH, "bosses", OPTION_STRING, "path to bosses image" },
- { OPTION_LOGOS_PATH, "logo", OPTION_STRING, "path to logos image" },
- { OPTION_SCORES_PATH, "scores", OPTION_STRING, "path to scores image" },
- { OPTION_VERSUS_PATH, "versus", OPTION_STRING, "path to versus image" },
- { OPTION_GAMEOVER_PATH, "gameover", OPTION_STRING, "path to gameover image" },
- { OPTION_HOWTO_PATH, "howto", OPTION_STRING, "path to howto image" },
- { OPTION_SELECT_PATH, "select", OPTION_STRING, "path to select image" },
- { OPTION_ICONS_PATH, "icons", OPTION_STRING, "path to ICOns image" },
- { OPTION_UI_PATH, "ui", OPTION_STRING, "path to UI files" },
+ { nullptr, nullptr, OPTION_HEADER, "UI SEARCH PATH OPTIONS" },
+ { OPTION_HISTORY_PATH, "history;dats;.", OPTION_STRING, "path to history files" },
+ { OPTION_EXTRAINI_PATH, "folders", OPTION_STRING, "path to extra ini files" },
+ { OPTION_CABINETS_PATH, "cabinets;cabdevs", OPTION_STRING, "path to cabinets / devices image" },
+ { OPTION_CPANELS_PATH, "cpanel", OPTION_STRING, "path to control panel image" },
+ { OPTION_PCBS_PATH, "pcb", OPTION_STRING, "path to pcbs image" },
+ { OPTION_FLYERS_PATH, "flyers", OPTION_STRING, "path to flyers image" },
+ { OPTION_TITLES_PATH, "titles", OPTION_STRING, "path to titles image" },
+ { OPTION_ENDS_PATH, "ends", OPTION_STRING, "path to ends image" },
+ { OPTION_MARQUEES_PATH, "marquees", OPTION_STRING, "path to marquees image" },
+ { OPTION_ARTPREV_PATH, "artwork preview;artpreview", OPTION_STRING, "path to artwork preview image" },
+ { OPTION_BOSSES_PATH, "bosses", OPTION_STRING, "path to bosses image" },
+ { OPTION_LOGOS_PATH, "logo", OPTION_STRING, "path to logos image" },
+ { OPTION_SCORES_PATH, "scores", OPTION_STRING, "path to scores image" },
+ { OPTION_VERSUS_PATH, "versus", OPTION_STRING, "path to versus image" },
+ { OPTION_GAMEOVER_PATH, "gameover", OPTION_STRING, "path to gameover image" },
+ { OPTION_HOWTO_PATH, "howto", OPTION_STRING, "path to howto image" },
+ { OPTION_SELECT_PATH, "select", OPTION_STRING, "path to select image" },
+ { OPTION_ICONS_PATH, "icons", OPTION_STRING, "path to ICOns image" },
+ { OPTION_COVER_PATH, "covers", OPTION_STRING, "path to software cover image" },
+ { OPTION_UI_PATH, "ui", OPTION_STRING, "path to UI files" },
// misc options
{ nullptr, nullptr, OPTION_HEADER, "UI MISC OPTIONS" },
diff --git a/src/emu/ui/moptions.h b/src/emu/ui/moptions.h
index 9706dcda7f5..55d800651f4 100644
--- a/src/emu/ui/moptions.h
+++ b/src/emu/ui/moptions.h
@@ -1,5 +1,5 @@
// license:BSD-3-Clause
-// copyright-holders:Dankan1890
+// copyright-holders:Maurizio Petrarota
/***************************************************************************
ui/moptions.h
@@ -34,6 +34,7 @@
#define OPTION_HOWTO_PATH "howto_directory"
#define OPTION_SELECT_PATH "select_directory"
#define OPTION_ICONS_PATH "icons_directory"
+#define OPTION_COVER_PATH "covers_directory"
#define OPTION_UI_PATH "ui_path"
// core misc options
@@ -95,6 +96,7 @@ public:
const char *howto_directory() const { return value(OPTION_HOWTO_PATH); }
const char *select_directory() const { return value(OPTION_SELECT_PATH); }
const char *icons_directory() const { return value(OPTION_ICONS_PATH); }
+ const char *covers_directory() const { return value(OPTION_COVER_PATH); }
const char *ui_path() const { return value(OPTION_UI_PATH); }
// Misc options
diff --git a/src/emu/ui/optsmenu.cpp b/src/emu/ui/optsmenu.cpp
index f93bdbf4652..a87de984694 100644
--- a/src/emu/ui/optsmenu.cpp
+++ b/src/emu/ui/optsmenu.cpp
@@ -91,26 +91,24 @@ void ui_menu_game_options::handle()
{
if (m_event->iptkey == IPT_UI_LEFT)
{
- machine().inifile().current_file--;
- machine().inifile().current_category = 0;
+ machine().inifile().move_file(-1);
changed = true;
}
else if (m_event->iptkey == IPT_UI_RIGHT)
{
- machine().inifile().current_file++;
- machine().inifile().current_category = 0;
+ machine().inifile().move_file(1);
changed = true;
}
else if (m_event->iptkey == IPT_UI_SELECT)
{
inifile_manager &ifile = machine().inifile();
- int total = ifile.ini_index.size();
+ int total = ifile.total();
std::vector<std::string> s_sel(total);
- machine().inifile().current_category = 0;
+ machine().inifile().set_cat(0);
for (size_t index = 0; index < total; ++index)
- s_sel[index] = ifile.ini_index[index].name;
+ s_sel[index] = ifile.get_file(index);
- ui_menu::stack_push(global_alloc_clear<ui_menu_selector>(machine(), container, s_sel, ifile.current_file, SELECTOR_INIFILE));
+ ui_menu::stack_push(global_alloc_clear<ui_menu_selector>(machine(), container, s_sel, ifile.cur_file(), SELECTOR_INIFILE));
}
break;
}
@@ -118,24 +116,23 @@ void ui_menu_game_options::handle()
{
if (m_event->iptkey == IPT_UI_LEFT)
{
- machine().inifile().current_category--;
+ machine().inifile().move_cat(-1);
changed = true;
}
else if (m_event->iptkey == IPT_UI_RIGHT)
{
- machine().inifile().current_category++;
+ machine().inifile().move_cat(1);
changed = true;
}
else if (m_event->iptkey == IPT_UI_SELECT)
{
inifile_manager &ifile = machine().inifile();
- int cfile = ifile.current_file;
- int total = ifile.ini_index[cfile].category.size();
+ int total = ifile.cat_total();
std::vector<std::string> s_sel(total);
for (int index = 0; index < total; ++index)
- s_sel[index] = ifile.ini_index[cfile].category[index].name;
+ s_sel[index] = ifile.get_category(index);
- ui_menu::stack_push(global_alloc_clear<ui_menu_selector>(machine(), container, s_sel, ifile.current_category, SELECTOR_CATEGORY));
+ ui_menu::stack_push(global_alloc_clear<ui_menu_selector>(machine(), container, s_sel, ifile.cur_cat(), SELECTOR_CATEGORY));
}
break;
}
@@ -217,20 +214,19 @@ void ui_menu_game_options::populate()
item_append(_("Filter"), main_filters::text[m_main], arrow_flags, (void *)(FPTR)FILTER_MENU);
// add category subitem
- if (m_main == FILTER_CATEGORY && !machine().inifile().ini_index.empty())
+ if (m_main == FILTER_CATEGORY && machine().inifile().total() > 0)
{
inifile_manager &inif = machine().inifile();
- int afile = inif.current_file;
- arrow_flags = get_arrow_flags(0, inif.ini_index.size() - 1, afile);
+ arrow_flags = get_arrow_flags(0, inif.total() - 1, inif.cur_file());
fbuff = _(" ^!File");
convert_command_glyph(fbuff);
- item_append(fbuff.c_str(), inif.actual_file().c_str(), arrow_flags, (void *)(FPTR)FILE_CATEGORY_FILTER);
+ item_append(fbuff.c_str(), inif.get_file().c_str(), arrow_flags, (void *)(FPTR)FILE_CATEGORY_FILTER);
- arrow_flags = get_arrow_flags(0, inif.ini_index[afile].category.size() - 1, inif.current_category);
+ arrow_flags = get_arrow_flags(0, inif.cat_total() - 1, inif.cur_cat());
fbuff = _(" ^!Category");
convert_command_glyph(fbuff);
- item_append(fbuff.c_str(), inif.actual_category().c_str(), arrow_flags, (void *)(FPTR)CATEGORY_FILTER);
+ item_append(fbuff.c_str(), inif.get_category().c_str(), arrow_flags, (void *)(FPTR)CATEGORY_FILTER);
}
// add manufacturer subitem
else if (m_main == FILTER_MANUFACTURER && c_mnfct::ui.size() > 0)
@@ -314,7 +310,7 @@ void save_ui_options(running_machine &machine)
{
// attempt to open the output file
emu_file file(machine.options().ini_path(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
- if (file.open("ui.ini") == FILERR_NONE)
+ if (file.open("ui.ini") == osd_file::error::NONE)
{
// generate the updated INI
std::string initext = machine.ui().options().output_ini();
@@ -339,7 +335,7 @@ void save_main_option(running_machine &machine)
// attempt to open the main ini file
{
emu_file file(machine.options().ini_path(), OPEN_FLAG_READ);
- if (file.open(emulator_info::get_configname(), ".ini") == FILERR_NONE)
+ if (file.open(emulator_info::get_configname(), ".ini") == osd_file::error::NONE)
{
bool result = options.parse_ini_file((util::core_file&)file, OPTION_PRIORITY_MAME_INI, OPTION_PRIORITY_DRIVER_INI, error);
if (!result)
@@ -361,7 +357,7 @@ void save_main_option(running_machine &machine)
// attempt to open the output file
{
emu_file file(machine.options().ini_path(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
- if (file.open(emulator_info::get_configname(), ".ini") == FILERR_NONE)
+ if (file.open(emulator_info::get_configname(), ".ini") == osd_file::error::NONE)
{
// generate the updated INI
std::string initext = options.output_ini();
@@ -375,4 +371,3 @@ void save_main_option(running_machine &machine)
}
machine.ui().popup_time(3, "%s", _("\n Configuration saved \n\n"));
}
-
diff --git a/src/emu/ui/selector.cpp b/src/emu/ui/selector.cpp
index 330694fd497..af199b1cfe8 100644
--- a/src/emu/ui/selector.cpp
+++ b/src/emu/ui/selector.cpp
@@ -1,8 +1,8 @@
// license:BSD-3-Clause
-// copyright-holders:Dankan1890
+// copyright-holders:Maurizio Petrarota
/*********************************************************************
- ui/m_selector.cpp
+ ui/selector.cpp
Internal UI user interface.
@@ -18,13 +18,26 @@
// ctor / dtor
//-------------------------------------------------
-ui_menu_selector::ui_menu_selector(running_machine &machine, render_container *container, std::vector<std::string> s_sel, UINT16 &s_actual, int category, int _hover)
- : ui_menu(machine, container), m_selector(s_actual)
+ui_menu_selector::ui_menu_selector(running_machine &machine, render_container *container, std::vector<std::string> const &s_sel, UINT16 &s_actual, int category, int _hover)
+ : ui_menu(machine, container)
+ , m_selector(s_actual)
+ , m_category(category)
+ , m_hover(_hover)
+ , m_first_pass(true)
+ , m_str_items(s_sel)
+{
+ m_search[0] = '\0';
+ m_searchlist[0] = nullptr;
+}
+
+ui_menu_selector::ui_menu_selector(running_machine &machine, render_container *container, std::vector<std::string> &&s_sel, UINT16 &s_actual, int category, int _hover)
+ : ui_menu(machine, container)
+ , m_selector(s_actual)
+ , m_category(category)
+ , m_hover(_hover)
+ , m_first_pass(true)
+ , m_str_items(std::move(s_sel))
{
- m_category = category;
- m_first_pass = true;
- m_hover = _hover;
- m_str_items = s_sel;
m_search[0] = '\0';
m_searchlist[0] = nullptr;
}
@@ -53,13 +66,13 @@ void ui_menu_selector::handle()
switch (m_category)
{
case SELECTOR_INIFILE:
- machine().inifile().current_file = m_selector;
- machine().inifile().current_category = 0;
+ machine().inifile().set_file(m_selector);
+ machine().inifile().set_cat(0);
ui_menu::menu_stack->parent->reset(UI_MENU_RESET_REMEMBER_REF);
break;
case SELECTOR_CATEGORY:
- machine().inifile().current_category = m_selector;
+ machine().inifile().set_cat(m_selector);
ui_menu::menu_stack->parent->reset(UI_MENU_RESET_REMEMBER_REF);
break;
diff --git a/src/emu/ui/selector.h b/src/emu/ui/selector.h
index 595ca1f578d..6809729396d 100644
--- a/src/emu/ui/selector.h
+++ b/src/emu/ui/selector.h
@@ -1,5 +1,5 @@
// license:BSD-3-Clause
-// copyright-holders:Dankan1890
+// copyright-holders:Maurizio Petrarota
/***************************************************************************
ui/selector.h
@@ -28,7 +28,8 @@ enum
class ui_menu_selector : public ui_menu
{
public:
- ui_menu_selector(running_machine &machine, render_container *container, std::vector<std::string> _sel, UINT16 &_actual, int _category = 0, int _hover = 0);
+ ui_menu_selector(running_machine &machine, render_container *container, std::vector<std::string> const &_sel, UINT16 &_actual, int _category = 0, int _hover = 0);
+ ui_menu_selector(running_machine &machine, render_container *container, std::vector<std::string> &&_sel, UINT16 &_actual, int _category = 0, int _hover = 0);
virtual ~ui_menu_selector();
virtual void populate() override;
virtual void handle() override;
diff --git a/src/emu/ui/selgame.cpp b/src/emu/ui/selgame.cpp
index dcc9e1d2d68..a823635c286 100644
--- a/src/emu/ui/selgame.cpp
+++ b/src/emu/ui/selgame.cpp
@@ -47,70 +47,6 @@ std::vector<const game_driver *> ui_menu_select_game::m_sortedlist;
int ui_menu_select_game::m_isabios = 0;
//-------------------------------------------------
-// sort
-//-------------------------------------------------
-
-inline int c_stricmp(const char *s1, const char *s2)
-{
- for (;;)
- {
- int c1 = tolower((UINT8)*s1++);
- int c2 = tolower((UINT8)*s2++);
- if (c1 == 0 || c1 != c2)
- return c1 - c2;
- }
-}
-
-bool sort_game_list(const game_driver *x, const game_driver *y)
-{
- bool clonex = strcmp(x->parent, "0");
- bool cloney = strcmp(y->parent, "0");
-
- if (!clonex && !cloney)
- return (c_stricmp(x->description, y->description) < 0);
-
- int cx = -1, cy = -1;
- if (clonex)
- {
- cx = driver_list::find(x->parent);
- if (cx == -1 || (driver_list::driver(cx).flags & MACHINE_IS_BIOS_ROOT) != 0)
- clonex = false;
- }
-
- if (cloney)
- {
- cy = driver_list::find(y->parent);
- if (cy == -1 || (driver_list::driver(cy).flags & MACHINE_IS_BIOS_ROOT) != 0)
- cloney = false;
- }
-
- if (!clonex && !cloney)
- return (c_stricmp(x->description, y->description) < 0);
-
- else if (clonex && cloney)
- {
- if (!c_stricmp(x->parent, y->parent))
- return (c_stricmp(x->description, y->description) < 0);
- else
- return (c_stricmp(driver_list::driver(cx).description, driver_list::driver(cy).description) < 0);
- }
- else if (!clonex && cloney)
- {
- if (!c_stricmp(x->name, y->parent))
- return true;
- else
- return (c_stricmp(x->description, driver_list::driver(cy).description) < 0);
- }
- else
- {
- if (!c_stricmp(x->parent, y->name))
- return false;
- else
- return (c_stricmp(driver_list::driver(cx).description, y->description) < 0);
- }
-}
-
-//-------------------------------------------------
// ctor
//-------------------------------------------------
@@ -194,6 +130,7 @@ ui_menu_select_game::ui_menu_select_game(running_machine &machine, render_contai
ui_globals::switch_image = false;
ui_globals::default_image = true;
ui_globals::panels_status = moptions.hide_panels();
+ m_searchlist[0] = nullptr;
}
//-------------------------------------------------
@@ -775,7 +712,7 @@ void ui_menu_select_game::build_available_list()
}
// sort
- std::stable_sort(m_availsortedlist.begin(), m_availsortedlist.end(), sort_game_list);
+ std::stable_sort(m_availsortedlist.begin(), m_availsortedlist.end(), sorted_game_list);
// now build the unavailable list
for (int x = 0; x < m_total; ++x)
@@ -783,7 +720,7 @@ void ui_menu_select_game::build_available_list()
m_unavailsortedlist.push_back(&driver_list::driver(x));
// sort
- std::stable_sort(m_unavailsortedlist.begin(), m_unavailsortedlist.end(), sort_game_list);
+ std::stable_sort(m_unavailsortedlist.begin(), m_unavailsortedlist.end(), sorted_game_list);
}
//-------------------------------------------------
@@ -800,6 +737,7 @@ void ui_menu_select_game::custom_render(void *selectedref, float top, float bott
bool isstar = false;
ui_manager &mui = machine().ui();
float tbarspace = mui.get_line_height();
+ float text_size = 1.0f;
tempbuf[0] = string_format(_("%1$s %2$s ( %3$d / %4$d machines (%5$d BIOS) )"),
emulator_info::get_appname(),
@@ -809,12 +747,12 @@ void ui_menu_select_game::custom_render(void *selectedref, float top, float bott
m_isabios);
std::string filtered;
- if (main_filters::actual == FILTER_CATEGORY && !machine().inifile().ini_index.empty())
+ if (main_filters::actual == FILTER_CATEGORY && machine().inifile().total() > 0)
{
filtered = string_format(_("%1$s (%2$s - %3$s) - "),
main_filters::text[main_filters::actual],
- machine().inifile().actual_file(),
- machine().inifile().actual_category());
+ machine().inifile().get_file(),
+ machine().inifile().get_category());
}
else if (main_filters::actual == FILTER_MANUFACTURER)
{
@@ -839,11 +777,17 @@ void ui_menu_select_game::custom_render(void *selectedref, float top, float bott
for (int line = 0; line < 2; ++line)
{
mui.draw_text_full(container, tempbuf[line].c_str(), 0.0f, 0.0f, 1.0f, JUSTIFY_CENTER, WRAP_NEVER,
- DRAW_NONE, ARGB_WHITE, ARGB_BLACK, &width, nullptr);
+ DRAW_NONE, ARGB_WHITE, ARGB_BLACK, &width, nullptr);
width += 2 * UI_BOX_LR_BORDER;
maxwidth = MAX(width, maxwidth);
}
+ if (maxwidth > origx2 - origx1)
+ {
+ text_size = (origx2 - origx1) / maxwidth;
+ maxwidth = origx2 - origx1;
+ }
+
// compute our bounds
float x1 = 0.5f - 0.5f * maxwidth;
float x2 = x1 + maxwidth;
@@ -862,7 +806,7 @@ void ui_menu_select_game::custom_render(void *selectedref, float top, float bott
for (int line = 0; line < 2; ++line)
{
mui.draw_text_full(container, tempbuf[line].c_str(), x1, y1, x2 - x1, JUSTIFY_CENTER, WRAP_NEVER,
- DRAW_NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr);
+ DRAW_NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr, text_size);
y1 += mui.get_line_height();
}
@@ -992,6 +936,12 @@ void ui_menu_select_game::custom_render(void *selectedref, float top, float bott
maxwidth = MAX(maxwidth, width);
}
+ if (maxwidth > origx2 - origx1)
+ {
+ text_size = (origx2 - origx1) / maxwidth;
+ maxwidth = origx2 - origx1;
+ }
+
// compute our bounds
x1 = 0.5f - 0.5f * maxwidth;
x2 = x1 + maxwidth;
@@ -1014,7 +964,7 @@ void ui_menu_select_game::custom_render(void *selectedref, float top, float bott
for (auto & elem : tempbuf)
{
mui.draw_text_full(container, elem.c_str(), x1, y1, x2 - x1, JUSTIFY_CENTER, WRAP_NEVER,
- DRAW_NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr);
+ DRAW_NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr, text_size);
y1 += mui.get_line_height();
}
}
@@ -1084,7 +1034,7 @@ void ui_menu_select_game::inkey_select(const ui_menu_event *m_event)
}
}
- std::vector<s_bios> biosname;
+ s_bios biosname;
if (!machine().ui().options().skip_bios_menu() && has_multiple_bios(driver, biosname))
ui_menu::stack_push(global_alloc_clear<ui_bios_selection>(machine(), container, biosname, (void *)driver, false, false));
else
@@ -1141,7 +1091,7 @@ void ui_menu_select_game::inkey_select_favorite(const ui_menu_event *m_event)
// if everything looks good, schedule the new driver
if (summary == media_auditor::CORRECT || summary == media_auditor::BEST_AVAILABLE || summary == media_auditor::NONE_NEEDED)
{
- std::vector<s_bios> biosname;
+ s_bios biosname;
if (!mopt.skip_bios_menu() && has_multiple_bios(ui_swinfo->driver, biosname))
ui_menu::stack_push(global_alloc_clear<ui_bios_selection>(machine(), container, biosname, (void *)ui_swinfo->driver, false, false));
else
@@ -1174,7 +1124,7 @@ void ui_menu_select_game::inkey_select_favorite(const ui_menu_event *m_event)
media_auditor::summary summary = auditor.audit_software(swlist->list_name(), swinfo, AUDIT_VALIDATE_FAST);
if (summary == media_auditor::CORRECT || summary == media_auditor::BEST_AVAILABLE || summary == media_auditor::NONE_NEEDED)
{
- std::vector<s_bios> biosname;
+ s_bios biosname;
if (!mopt.skip_bios_menu() && has_multiple_bios(ui_swinfo->driver, biosname))
{
ui_menu::stack_push(global_alloc_clear<ui_bios_selection>(machine(), container, biosname, (void *)ui_swinfo, true, false));
@@ -1182,7 +1132,7 @@ void ui_menu_select_game::inkey_select_favorite(const ui_menu_event *m_event)
}
else if (!mopt.skip_parts_menu() && swinfo->has_multiple_parts(ui_swinfo->interface.c_str()))
{
- std::unordered_map<std::string, std::string> parts;
+ s_parts parts;
for (const software_part *swpart = swinfo->first_part(); swpart != nullptr; swpart = swpart->next())
{
if (swpart->matches_interface(ui_swinfo->interface.c_str()))
@@ -1499,7 +1449,7 @@ void ui_menu_select_game::build_category()
for (auto actual : temp_filter)
m_tmp.push_back(&driver_list::driver(actual));
- std::stable_sort(m_tmp.begin(), m_tmp.end(), sort_game_list);
+ std::stable_sort(m_tmp.begin(), m_tmp.end(), sorted_game_list);
m_displaylist = m_tmp;
}
@@ -1683,7 +1633,7 @@ void ui_menu_select_game::init_sorted_list()
// sort manufacturers - years and driver
std::stable_sort(c_mnfct::ui.begin(), c_mnfct::ui.end());
std::stable_sort(c_year::ui.begin(), c_year::ui.end());
- std::stable_sort(m_sortedlist.begin(), m_sortedlist.end(), sort_game_list);
+ std::stable_sort(m_sortedlist.begin(), m_sortedlist.end(), sorted_game_list);
}
//-------------------------------------------------
@@ -1694,7 +1644,7 @@ bool ui_menu_select_game::load_available_machines()
{
// try to load available drivers from file
emu_file file(machine().ui().options().ui_path(), OPEN_FLAG_READ);
- if (file.open(emulator_info::get_configname(), "_avail.ini") != FILERR_NONE)
+ if (file.open(emulator_info::get_configname(), "_avail.ini") != osd_file::error::NONE)
return false;
std::string readbuf;
@@ -1746,7 +1696,7 @@ void ui_menu_select_game::load_custom_filters()
{
// attempt to open the output file
emu_file file(machine().ui().options().ui_path(), OPEN_FLAG_READ);
- if (file.open("custom_", emulator_info::get_configname(), "_filter.ini") == FILERR_NONE)
+ if (file.open("custom_", emulator_info::get_configname(), "_filter.ini") == osd_file::error::NONE)
{
char buffer[MAX_CHAR_INFO];
@@ -1911,14 +1861,15 @@ float ui_menu_select_game::draw_left_panel(float x1, float y1, float x2, float y
x2 = x1 + 2.0f * UI_BOX_LR_BORDER;
y1 = origy1;
y2 = origy2;
- float lr_arrow_width = 0.4f * line_height * machine().render().ui_aspect();
+ float space = x2 - x1;
+ float lr_arrow_width = 0.4f * space * machine().render().ui_aspect();
rgb_t fgcolor = UI_TEXT_COLOR;
// set left-right arrows dimension
float ar_x0 = 0.5f * (x2 + x1) - 0.5f * lr_arrow_width;
- float ar_y0 = 0.5f * (y2 + y1) + 0.1f * line_height;
+ float ar_y0 = 0.5f * (y2 + y1) + 0.1f * space;
float ar_x1 = ar_x0 + lr_arrow_width;
- float ar_y1 = 0.5f * (y2 + y1) + 0.9f * line_height;
+ float ar_y1 = 0.5f * (y2 + y1) + 0.9f * space;
mui.draw_outlined_box(container, x1, y1, x2, y2, rgb_t(0xEF, 0x12, 0x47, 0x7B));
@@ -1933,14 +1884,15 @@ float ui_menu_select_game::draw_left_panel(float x1, float y1, float x2, float y
}
else
{
- float lr_arrow_width = 0.4f * line_height * machine().render().ui_aspect();
+ float space = x2 - x1;
+ float lr_arrow_width = 0.4f * space * machine().render().ui_aspect();
rgb_t fgcolor = UI_TEXT_COLOR;
// set left-right arrows dimension
float ar_x0 = 0.5f * (x2 + x1) - 0.5f * lr_arrow_width;
- float ar_y0 = 0.5f * (y2 + y1) + 0.1f * line_height;
+ float ar_y0 = 0.5f * (y2 + y1) + 0.1f * space;
float ar_x1 = ar_x0 + lr_arrow_width;
- float ar_y1 = 0.5f * (y2 + y1) + 0.9f * line_height;
+ float ar_y1 = 0.5f * (y2 + y1) + 0.9f * space;
mui.draw_outlined_box(container, x1, y1, x2, y2, rgb_t(0xEF, 0x12, 0x47, 0x7B));
@@ -2006,14 +1958,14 @@ void ui_menu_select_game::infos_render(void *selectedref, float origx1, float or
// apply title to right panel
float title_size = 0.0f;
- float txt_lenght = 0.0f;
+ float txt_length = 0.0f;
for (int x = UI_FIRST_LOAD; x < UI_LAST_LOAD; ++x)
{
mui.draw_text_full(container, _(dats_info[x]), origx1, origy1, origx2 - origx1, JUSTIFY_CENTER,
- WRAP_TRUNCATE, DRAW_NONE, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, &txt_lenght, nullptr);
- txt_lenght += 0.01f;
- title_size = MAX(txt_lenght, title_size);
+ WRAP_NEVER, DRAW_NONE, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, &txt_length, nullptr);
+ txt_length += 0.01f;
+ title_size = (std::max)(txt_length, title_size);
}
rgb_t fgcolor = UI_TEXT_COLOR;
@@ -2026,12 +1978,17 @@ void ui_menu_select_game::infos_render(void *selectedref, float origx1, float or
float middle = origx2 - origx1;
+ // check size
+ float sc = title_size + 2.0f * gutter_width;
+ float tmp_size = (sc > middle) ? ((middle - 2.0f * gutter_width) / sc) : 1.0f;
+ title_size *= tmp_size;
+
if (bgcolor != UI_TEXT_BG_COLOR)
mui.draw_textured_box(container, origx1 + ((middle - title_size) * 0.5f), origy1, origx1 + ((middle + title_size) * 0.5f),
origy1 + line_height, bgcolor, rgb_t(255, 43, 43, 43), hilight_main_texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXWRAP(TRUE));
mui.draw_text_full(container, snaptext.c_str(), origx1, origy1, origx2 - origx1, JUSTIFY_CENTER,
- WRAP_TRUNCATE, DRAW_NORMAL, fgcolor, bgcolor, nullptr, nullptr);
+ WRAP_NEVER, DRAW_NORMAL, fgcolor, bgcolor, nullptr, nullptr, tmp_size);
draw_common_arrow(origx1, origy1, origx2, origy2, ui_globals::curdats_view, UI_FIRST_LOAD, UI_LAST_LOAD, title_size);
@@ -2084,7 +2041,7 @@ void ui_menu_select_game::infos_render(void *selectedref, float origx1, float or
if (topline_datsview + r_visible_lines >= totallines)
topline_datsview = totallines - r_visible_lines;
- float sc = origx2 - origx1 - (2.0f * UI_BOX_LR_BORDER);
+ sc = origx2 - origx1 - (2.0f * UI_BOX_LR_BORDER);
for (int r = 0; r < r_visible_lines; ++r)
{
int itemline = r + topline_datsview;
@@ -2177,17 +2134,17 @@ void ui_menu_select_game::infos_render(void *selectedref, float origx1, float or
else
{
float title_size = 0.0f;
- float txt_lenght = 0.0f;
+ float txt_length = 0.0f;
std::string t_text[2];
t_text[0] = _("History");
t_text[1] = _("Usage");
for (auto & elem: t_text)
{
- mui.draw_text_full(container, elem.c_str(), origx1, origy1, origx2 - origx1, JUSTIFY_CENTER, WRAP_TRUNCATE,
- DRAW_NONE, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, &txt_lenght, nullptr);
- txt_lenght += 0.01f;
- title_size = MAX(txt_lenght, title_size);
+ mui.draw_text_full(container, elem.c_str(), origx1, origy1, origx2 - origx1, JUSTIFY_CENTER, WRAP_TRUNCATE,
+ DRAW_NONE, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, &txt_length, nullptr);
+ txt_length += 0.01f;
+ title_size = (std::max)(txt_length, title_size);
}
rgb_t fgcolor = UI_TEXT_COLOR;
@@ -2272,17 +2229,17 @@ void ui_menu_select_game::infos_render(void *selectedref, float origx1, float or
void ui_menu_select_game::draw_right_panel(void *selectedref, float origx1, float origy1, float origx2, float origy2)
{
ui_manager &mui = machine().ui();
- float line_height = mui.get_line_height();
- float lr_arrow_width = 0.4f * line_height * machine().render().ui_aspect();
rgb_t fgcolor = UI_TEXT_COLOR;
bool hide = (ui_globals::panels_status == HIDE_RIGHT_PANEL || ui_globals::panels_status == HIDE_BOTH);
float x2 = (hide) ? origx2 : origx1 + 2.0f * UI_BOX_LR_BORDER;
+ float space = x2 - origx1;
+ float lr_arrow_width = 0.4f * space * machine().render().ui_aspect();
// set left-right arrows dimension
float ar_x0 = 0.5f * (x2 + origx1) - 0.5f * lr_arrow_width;
- float ar_y0 = 0.5f * (origy2 + origy1) + 0.1f * line_height;
+ float ar_y0 = 0.5f * (origy2 + origy1) + 0.1f * space;
float ar_x1 = ar_x0 + lr_arrow_width;
- float ar_y1 = 0.5f * (origy2 + origy1) + 0.9f * line_height;
+ float ar_y1 = 0.5f * (origy2 + origy1) + 0.9f * space;
//machine().ui().draw_outlined_box(container, origx1, origy1, origx2, origy2, UI_BACKGROUND_COLOR);
mui.draw_outlined_box(container, origx1, origy1, origx2, origy2, rgb_t(0xEF, 0x12, 0x47, 0x7B));
diff --git a/src/emu/ui/selgame.h b/src/emu/ui/selgame.h
index b099f45c796..474aa57ed8a 100644
--- a/src/emu/ui/selgame.h
+++ b/src/emu/ui/selgame.h
@@ -1,5 +1,5 @@
// license:BSD-3-Clause
-// copyright-holders:Dankan1890
+// copyright-holders:Maurizio Petrarota
/***************************************************************************
ui/selgame.h
diff --git a/src/emu/ui/selsoft.cpp b/src/emu/ui/selsoft.cpp
index 3bf2e237553..07172c25306 100644
--- a/src/emu/ui/selsoft.cpp
+++ b/src/emu/ui/selsoft.cpp
@@ -1,5 +1,5 @@
// license:BSD-3-Clause
-// copyright-holders:Dankan1890
+// copyright-holders:Maurizio Petrarota
/***************************************************************************
ui/selsoft.cpp
@@ -86,7 +86,7 @@ bool compare_software(ui_software_info a, ui_software_info b)
// get bios count
//-------------------------------------------------
-bool has_multiple_bios(const game_driver *driver, std::vector<s_bios> &biosname)
+bool has_multiple_bios(const game_driver *driver, s_bios &biosname)
{
if (driver->rom == nullptr)
return 0;
@@ -675,6 +675,7 @@ void ui_menu_select_software::custom_render(void *selectedref, float top, float
rgb_t color = UI_BACKGROUND_COLOR;
bool isstar = false;
float tbarspace = mui.get_line_height();
+ float text_size = 1.0f;
// determine the text for the header
int vis_item = (m_search[0] != 0) ? visible_items : (m_has_empty_start ? visible_items - 1 : visible_items);
@@ -700,11 +701,17 @@ void ui_menu_select_software::custom_render(void *selectedref, float top, float
for (int line = 0; line < 3; ++line)
{
mui.draw_text_full(container, tempbuf[line].c_str(), 0.0f, 0.0f, 1.0f, JUSTIFY_CENTER, WRAP_NEVER,
- DRAW_NONE, ARGB_WHITE, ARGB_BLACK, &width, nullptr);
+ DRAW_NONE, ARGB_WHITE, ARGB_BLACK, &width, nullptr);
width += 2 * UI_BOX_LR_BORDER;
maxwidth = MAX(width, maxwidth);
}
+ if (maxwidth > origx2 - origx1)
+ {
+ text_size = (origx2 - origx1) / maxwidth;
+ maxwidth = origx2 - origx1;
+ }
+
// compute our bounds
float x1 = 0.5f - 0.5f * maxwidth;
float x2 = x1 + maxwidth;
@@ -723,7 +730,7 @@ void ui_menu_select_software::custom_render(void *selectedref, float top, float
for (int line = 0; line < 3; ++line)
{
mui.draw_text_full(container, tempbuf[line].c_str(), x1, y1, x2 - x1, JUSTIFY_CENTER, WRAP_NEVER,
- DRAW_NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr);
+ DRAW_NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr, text_size);
y1 += mui.get_line_height();
}
@@ -773,7 +780,7 @@ void ui_menu_select_software::custom_render(void *selectedref, float top, float
color = UI_GREEN_COLOR;
if ((driver->flags & (MACHINE_IMPERFECT_GRAPHICS | MACHINE_WRONG_COLORS | MACHINE_IMPERFECT_COLORS
- | MACHINE_NO_SOUND | MACHINE_IMPERFECT_SOUND)) != 0)
+ | MACHINE_NO_SOUND | MACHINE_IMPERFECT_SOUND)) != 0)
color = UI_YELLOW_COLOR;
if ((driver->flags & (MACHINE_NOT_WORKING | MACHINE_UNEMULATED_PROTECTION)) != 0)
@@ -845,11 +852,17 @@ void ui_menu_select_software::custom_render(void *selectedref, float top, float
for (auto & elem : tempbuf)
{
mui.draw_text_full(container, elem.c_str(), 0.0f, 0.0f, 1.0f, JUSTIFY_CENTER, WRAP_NEVER,
- DRAW_NONE, ARGB_WHITE, ARGB_BLACK, &width, nullptr);
+ DRAW_NONE, ARGB_WHITE, ARGB_BLACK, &width, nullptr);
width += 2 * UI_BOX_LR_BORDER;
maxwidth = MAX(maxwidth, width);
}
+ if (maxwidth > origx2 - origx1)
+ {
+ text_size = (origx2 - origx1) / maxwidth;
+ maxwidth = origx2 - origx1;
+ }
+
// compute our bounds
x1 = 0.5f - 0.5f * maxwidth;
x2 = x1 + maxwidth;
@@ -872,7 +885,7 @@ void ui_menu_select_software::custom_render(void *selectedref, float top, float
for (auto & elem : tempbuf)
{
mui.draw_text_full(container, elem.c_str(), x1, y1, x2 - x1, JUSTIFY_CENTER, WRAP_NEVER,
- DRAW_NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr);
+ DRAW_NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr, text_size);
y1 += machine().ui().get_line_height();
}
}
@@ -888,7 +901,7 @@ void ui_menu_select_software::inkey_select(const ui_menu_event *m_event)
if (ui_swinfo->startempty == 1)
{
- std::vector<s_bios> biosname;
+ s_bios biosname;
if (!mopt.skip_bios_menu() && has_multiple_bios(ui_swinfo->driver, biosname))
ui_menu::stack_push(global_alloc_clear<ui_bios_selection>(machine(), container, biosname, (void *)ui_swinfo->driver, false, true));
else
@@ -916,7 +929,7 @@ void ui_menu_select_software::inkey_select(const ui_menu_event *m_event)
if (summary == media_auditor::CORRECT || summary == media_auditor::BEST_AVAILABLE || summary == media_auditor::NONE_NEEDED)
{
- std::vector<s_bios> biosname;
+ s_bios biosname;
if (!mopt.skip_bios_menu() && has_multiple_bios(ui_swinfo->driver, biosname))
{
ui_menu::stack_push(global_alloc_clear<ui_bios_selection>(machine(), container, biosname, (void *)ui_swinfo, true, false));
@@ -924,7 +937,7 @@ void ui_menu_select_software::inkey_select(const ui_menu_event *m_event)
}
else if (!mopt.skip_parts_menu() && swinfo->has_multiple_parts(ui_swinfo->interface.c_str()))
{
- std::unordered_map<std::string, std::string> parts;
+ s_parts parts;
for (const software_part *swpart = swinfo->first_part(); swpart != nullptr; swpart = swpart->next())
{
if (swpart->matches_interface(ui_swinfo->interface.c_str()))
@@ -1049,7 +1062,7 @@ void ui_menu_select_software::load_sw_custom_filters()
{
// attempt to open the output file
emu_file file(machine().ui().options().ui_path(), OPEN_FLAG_READ);
- if (file.open("custom_", m_driver->name, "_filter.ini") == FILERR_NONE)
+ if (file.open("custom_", m_driver->name, "_filter.ini") == osd_file::error::NONE)
{
char buffer[MAX_CHAR_INFO];
@@ -1487,15 +1500,15 @@ float ui_menu_select_software::draw_left_panel(float x1, float y1, float x2, flo
x2 = x1 + 2.0f * UI_BOX_LR_BORDER;
y1 = origy1;
y2 = origy2;
- line_height = mui.get_line_height();
- float lr_arrow_width = 0.4f * line_height * machine().render().ui_aspect();
+ float space = x2 - x1;
+ float lr_arrow_width = 0.4f * space * machine().render().ui_aspect();
rgb_t fgcolor = UI_TEXT_COLOR;
// set left-right arrows dimension
float ar_x0 = 0.5f * (x2 + x1) - 0.5f * lr_arrow_width;
- float ar_y0 = 0.5f * (y2 + y1) + 0.1f * line_height;
+ float ar_y0 = 0.5f * (y2 + y1) + 0.1f * space;
float ar_x1 = ar_x0 + lr_arrow_width;
- float ar_y1 = 0.5f * (y2 + y1) + 0.9f * line_height;
+ float ar_y1 = 0.5f * (y2 + y1) + 0.9f * space;
//machine().ui().draw_outlined_box(container, x1, y1, x2, y2, UI_BACKGROUND_COLOR);
mui.draw_outlined_box(container, x1, y1, x2, y2, rgb_t(0xEF, 0x12, 0x47, 0x7B));
@@ -1511,15 +1524,15 @@ float ui_menu_select_software::draw_left_panel(float x1, float y1, float x2, flo
}
else
{
- float line_height = mui.get_line_height();
- float lr_arrow_width = 0.4f * line_height * machine().render().ui_aspect();
+ float space = x2 - x1;
+ float lr_arrow_width = 0.4f * space * machine().render().ui_aspect();
rgb_t fgcolor = UI_TEXT_COLOR;
// set left-right arrows dimension
float ar_x0 = 0.5f * (x2 + x1) - 0.5f * lr_arrow_width;
- float ar_y0 = 0.5f * (y2 + y1) + 0.1f * line_height;
+ float ar_y0 = 0.5f * (y2 + y1) + 0.1f * space;
float ar_x1 = ar_x0 + lr_arrow_width;
- float ar_y1 = 0.5f * (y2 + y1) + 0.9f * line_height;
+ float ar_y1 = 0.5f * (y2 + y1) + 0.9f * space;
//machine().ui().draw_outlined_box(container, x1, y1, x2, y2, UI_BACKGROUND_COLOR);
mui.draw_outlined_box(container, x1, y1, x2, y2, rgb_t(0xEF, 0x12, 0x47, 0x7B));
@@ -1578,7 +1591,7 @@ void ui_menu_select_software::infos_render(void *selectedref, float origx1, floa
mui.draw_textured_box(container, origx1 + ((middle - title_size) * 0.5f), origy1, origx1 + ((middle + title_size) * 0.5f),
origy1 + line_height, bgcolor, rgb_t(255, 43, 43, 43), hilight_main_texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXWRAP(TRUE));
- mui.draw_text_full(container, _("History"), origx1, origy1, origx2 - origx1, JUSTIFY_CENTER, WRAP_TRUNCATE,
+ mui.draw_text_full(container, _("History"), origx1, origy1, origx2 - origx1, JUSTIFY_CENTER, WRAP_NEVER,
DRAW_NORMAL, fgcolor, bgcolor, nullptr, nullptr);
ui_globals::cur_sw_dats_view = 0;
}
@@ -1592,7 +1605,7 @@ void ui_menu_select_software::infos_render(void *selectedref, float origx1, floa
for (auto & elem : t_text)
{
- mui.draw_text_full(container, elem.c_str(), origx1, origy1, origx2 - origx1, JUSTIFY_CENTER, WRAP_TRUNCATE,
+ mui.draw_text_full(container, elem.c_str(), origx1, origy1, origx2 - origx1, JUSTIFY_CENTER, WRAP_NEVER,
DRAW_NONE, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, &txt_lenght, nullptr);
txt_lenght += 0.01f;
title_size = MAX(txt_lenght, title_size);
@@ -1608,12 +1621,17 @@ void ui_menu_select_software::infos_render(void *selectedref, float origx1, floa
float middle = origx2 - origx1;
+ // check size
+ float sc = title_size + 2.0f * gutter_width;
+ float tmp_size = (sc > middle) ? ((middle - 2.0f * gutter_width) / sc) : 1.0f;
+ title_size *= tmp_size;
+
if (bgcolor != UI_TEXT_BG_COLOR)
mui.draw_textured_box(container, origx1 + ((middle - title_size) * 0.5f), origy1, origx1 + ((middle + title_size) * 0.5f),
origy1 + line_height, bgcolor, rgb_t(255, 43, 43, 43), hilight_main_texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXWRAP(TRUE));
mui.draw_text_full(container, t_text[ui_globals::cur_sw_dats_view].c_str(), origx1, origy1, origx2 - origx1,
- JUSTIFY_CENTER, WRAP_TRUNCATE, DRAW_NORMAL, fgcolor, bgcolor, nullptr, nullptr);
+ JUSTIFY_CENTER, WRAP_NEVER, DRAW_NORMAL, fgcolor, bgcolor, nullptr, nullptr, tmp_size);
draw_common_arrow(origx1, origy1, origx2, origy2, ui_globals::cur_sw_dats_view, 0, 1, title_size);
}
@@ -1867,17 +1885,17 @@ void ui_menu_select_software::arts_render(void *selectedref, float origx1, float
void ui_menu_select_software::draw_right_panel(void *selectedref, float origx1, float origy1, float origx2, float origy2)
{
ui_manager &mui = machine().ui();
- float line_height = mui.get_line_height();
- float lr_arrow_width = 0.4f * line_height * machine().render().ui_aspect();
rgb_t fgcolor = UI_TEXT_COLOR;
bool hide = (ui_globals::panels_status == HIDE_RIGHT_PANEL || ui_globals::panels_status == HIDE_BOTH);
float x2 = (hide) ? origx2 : origx1 + 2.0f * UI_BOX_LR_BORDER;
+ float space = x2 - origx1;
+ float lr_arrow_width = 0.4f * space * machine().render().ui_aspect();
// set left-right arrows dimension
float ar_x0 = 0.5f * (x2 + origx1) - 0.5f * lr_arrow_width;
- float ar_y0 = 0.5f * (origy2 + origy1) + 0.1f * line_height;
+ float ar_y0 = 0.5f * (origy2 + origy1) + 0.1f * space;
float ar_x1 = ar_x0 + lr_arrow_width;
- float ar_y1 = 0.5f * (origy2 + origy1) + 0.9f * line_height;
+ float ar_y1 = 0.5f * (origy2 + origy1) + 0.9f * space;
//machine().ui().draw_outlined_box(container, origx1, origy1, origx2, origy2, UI_BACKGROUND_COLOR);
mui.draw_outlined_box(container, origx1, origy1, origx2, origy2, rgb_t(0xEF, 0x12, 0x47, 0x7B));
@@ -1908,7 +1926,7 @@ void ui_menu_select_software::draw_right_panel(void *selectedref, float origx1,
// ctor
//-------------------------------------------------
-ui_software_parts::ui_software_parts(running_machine &machine, render_container *container, std::unordered_map<std::string, std::string> parts, ui_software_info *ui_info) : ui_menu(machine, container)
+ui_software_parts::ui_software_parts(running_machine &machine, render_container *container, s_parts parts, ui_software_info *ui_info) : ui_menu(machine, container)
{
m_parts = parts;
m_uiinfo = ui_info;
@@ -2001,7 +2019,7 @@ void ui_software_parts::custom_render(void *selectedref, float top, float bottom
// ctor
//-------------------------------------------------
-ui_bios_selection::ui_bios_selection(running_machine &machine, render_container *container, std::vector<s_bios> biosname, void *_driver, bool _software, bool _inlist) : ui_menu(machine, container)
+ui_bios_selection::ui_bios_selection(running_machine &machine, render_container *container, s_bios biosname, void *_driver, bool _software, bool _inlist) : ui_menu(machine, container)
{
m_bios = biosname;
m_driver = _driver;
@@ -2024,7 +2042,7 @@ ui_bios_selection::~ui_bios_selection()
void ui_bios_selection::populate()
{
for (auto & elem : m_bios)
- item_append(elem.name.c_str(), nullptr, 0, (void *)&elem.name);
+ item_append(elem.first.c_str(), nullptr, 0, (void *)&elem.first);
item_append(MENU_SEPARATOR_ITEM, nullptr, 0, nullptr);
customtop = machine().ui().get_line_height() + (3.0f * UI_BOX_TB_BORDER);
@@ -2041,7 +2059,7 @@ void ui_bios_selection::handle()
emu_options &moptions = machine().options();
if (event != nullptr && event->iptkey == IPT_UI_SELECT && event->itemref != nullptr)
for (auto & elem : m_bios)
- if ((void*)&elem.name == event->itemref)
+ if ((void*)&elem.first == event->itemref)
{
if (!m_software)
{
@@ -2057,7 +2075,7 @@ void ui_bios_selection::handle()
}
std::string error;
- moptions.set_value("bios", elem.id, OPTION_PRIORITY_CMDLINE, error);
+ moptions.set_value("bios", elem.second, OPTION_PRIORITY_CMDLINE, error);
machine().manager().schedule_new_driver(*s_driver);
machine().schedule_hard_reset();
ui_menu::stack_reset(machine());
@@ -2066,14 +2084,14 @@ void ui_bios_selection::handle()
{
ui_software_info *ui_swinfo = (ui_software_info *)m_driver;
std::string error;
- machine().options().set_value("bios", elem.id, OPTION_PRIORITY_CMDLINE, error);
+ machine().options().set_value("bios", elem.second, OPTION_PRIORITY_CMDLINE, error);
driver_enumerator drivlist(machine().options(), *ui_swinfo->driver);
drivlist.next();
software_list_device *swlist = software_list_device::find_by_name(drivlist.config(), ui_swinfo->listname.c_str());
software_info *swinfo = swlist->find(ui_swinfo->shortname.c_str());
if (!machine().ui().options().skip_parts_menu() && swinfo->has_multiple_parts(ui_swinfo->interface.c_str()))
{
- std::unordered_map<std::string, std::string> parts;
+ s_parts parts;
for (const software_part *swpart = swinfo->first_part(); swpart != nullptr; swpart = swpart->next())
{
if (swpart->matches_interface(ui_swinfo->interface.c_str()))
diff --git a/src/emu/ui/selsoft.h b/src/emu/ui/selsoft.h
index afb28c48134..a3d121f52c7 100644
--- a/src/emu/ui/selsoft.h
+++ b/src/emu/ui/selsoft.h
@@ -14,12 +14,8 @@
#include "ui/custmenu.h"
-struct s_bios
-{
- s_bios(std::string _name, int _id) { name = _name; id = _id; }
- std::string name;
- int id;
-};
+using s_bios = std::vector<std::pair<std::string, int>>;
+using s_parts = std::unordered_map<std::string, std::string>;
// Menu Class
class ui_menu_select_software : public ui_menu
@@ -69,7 +65,7 @@ private:
class ui_software_parts : public ui_menu
{
public:
- ui_software_parts(running_machine &machine, render_container *container, std::unordered_map<std::string, std::string> parts, ui_software_info *ui_info);
+ ui_software_parts(running_machine &machine, render_container *container, s_parts parts, ui_software_info *ui_info);
virtual ~ui_software_parts();
virtual void populate() override;
virtual void handle() override;
@@ -77,13 +73,13 @@ public:
private:
ui_software_info *m_uiinfo;
- std::unordered_map<std::string, std::string> m_parts;
+ s_parts m_parts;
};
class ui_bios_selection : public ui_menu
{
public:
- ui_bios_selection(running_machine &machine, render_container *container, std::vector<s_bios> biosname, void *driver, bool software, bool inlist);
+ ui_bios_selection(running_machine &machine, render_container *container, s_bios biosname, void *driver, bool software, bool inlist);
virtual ~ui_bios_selection();
virtual void populate() override;
virtual void handle() override;
@@ -91,9 +87,9 @@ public:
private:
- void *m_driver;
- bool m_software, m_inlist;
- std::vector<s_bios> m_bios;
+ void *m_driver;
+ bool m_software, m_inlist;
+ s_bios m_bios;
};
struct reselect_last
@@ -108,7 +104,7 @@ private:
};
// Getter
-bool has_multiple_bios(const game_driver *driver, std::vector<s_bios> &biosname);
+bool has_multiple_bios(const game_driver *driver, s_bios &biosname);
#endif /* __UI_SELSOFT_H__ */
diff --git a/src/emu/ui/sliders.cpp b/src/emu/ui/sliders.cpp
index 070bb202a1b..86f85bd0026 100644
--- a/src/emu/ui/sliders.cpp
+++ b/src/emu/ui/sliders.cpp
@@ -2,7 +2,7 @@
// copyright-holders:Nicola Salmoria, Aaron Giles, Nathan Woods
/*********************************************************************
- miscmenu.c
+ ui/sliders.cpp
Internal MAME menus for the user interface.
diff --git a/src/emu/ui/slotopt.cpp b/src/emu/ui/slotopt.cpp
index a67c217c7f1..c4fd58f754f 100644
--- a/src/emu/ui/slotopt.cpp
+++ b/src/emu/ui/slotopt.cpp
@@ -2,7 +2,7 @@
// copyright-holders:Nicola Salmoria, Aaron Giles, Nathan Woods
/*********************************************************************
- ui/slotopt.c
+ ui/slotopt.cpp
Internal menu for the slot options.
diff --git a/src/emu/ui/sndmenu.cpp b/src/emu/ui/sndmenu.cpp
index ab1731e6589..dd3e717d98a 100644
--- a/src/emu/ui/sndmenu.cpp
+++ b/src/emu/ui/sndmenu.cpp
@@ -1,5 +1,5 @@
// license:BSD-3-Clause
-// copyright-holders:Dankan1890
+// copyright-holders:Maurizio Petrarota
/*********************************************************************
ui/sndmenu.cpp
diff --git a/src/emu/ui/sndmenu.h b/src/emu/ui/sndmenu.h
index 8b13b38ea88..24bb0a79277 100644
--- a/src/emu/ui/sndmenu.h
+++ b/src/emu/ui/sndmenu.h
@@ -1,5 +1,5 @@
// license:BSD-3-Clause
-// copyright-holders:Dankan1890
+// copyright-holders:Maurizio Petrarota
/***************************************************************************
ui/sndmenu.h
diff --git a/src/emu/ui/starimg.h b/src/emu/ui/starimg.h
index 2704e486e5b..f57ebb8797f 100644
--- a/src/emu/ui/starimg.h
+++ b/src/emu/ui/starimg.h
@@ -1,5 +1,6 @@
// license:BSD-3-Clause
-// copyright-holders:Dankan1890
+// copyright-holders:Maurizio Petrarota
+
static const UINT32 favorite_star_bmp[] =
{
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
diff --git a/src/emu/ui/swlist.cpp b/src/emu/ui/swlist.cpp
index 2d4891d5673..3c2595389b2 100644
--- a/src/emu/ui/swlist.cpp
+++ b/src/emu/ui/swlist.cpp
@@ -2,7 +2,7 @@
// copyright-holders:Nicola Salmoria, Aaron Giles, Nathan Woods
/*********************************************************************
- ui/swlist.c
+ ui/swlist.cpp
Internal MAME user interface for software list.
diff --git a/src/emu/ui/tapectrl.cpp b/src/emu/ui/tapectrl.cpp
index 0362f0c8a84..510d0eb3fb3 100644
--- a/src/emu/ui/tapectrl.cpp
+++ b/src/emu/ui/tapectrl.cpp
@@ -2,7 +2,7 @@
// copyright-holders:Nicola Salmoria, Aaron Giles, Nathan Woods
/***************************************************************************
- ui/tapectrl.c
+ ui/tapectrl.cpp
Tape control
diff --git a/src/emu/ui/ui.cpp b/src/emu/ui/ui.cpp
index 1c560348755..cc8b18c8154 100644
--- a/src/emu/ui/ui.cpp
+++ b/src/emu/ui/ui.cpp
@@ -2,7 +2,7 @@
// copyright-holders:Nicola Salmoria, Aaron Giles, Nathan Woods
/*********************************************************************
- ui.c
+ ui.cpp
Functions used to handle MAME's user interface.
@@ -169,7 +169,7 @@ static void load_ui_options(running_machine &machine)
std::string error;
// attempt to open the output file
emu_file file(machine.options().ini_path(), OPEN_FLAG_READ);
- if (file.open("ui.ini") == FILERR_NONE)
+ if (file.open("ui.ini") == osd_file::error::NONE)
{
bool result = machine.ui().options().parse_ini_file((util::core_file&)file, OPTION_PRIORITY_MAME_INI, OPTION_PRIORITY_DRIVER_INI, error);
if (!result)
diff --git a/src/emu/ui/utils.h b/src/emu/ui/utils.h
index a2f24a20479..d6087131285 100644
--- a/src/emu/ui/utils.h
+++ b/src/emu/ui/utils.h
@@ -1,5 +1,5 @@
// license:BSD-3-Clause
-// copyright-holders:Dankan1890
+// copyright-holders:Maurizio Petrarota
/***************************************************************************
ui/utils.h
@@ -271,9 +271,9 @@ void render_load_jpeg(_T &bitmap, emu_file &file, const char *dirname, const cha
else
fname.assign(dirname).append(PATH_SEPARATOR).append(filename);
- file_error filerr = file.open(fname.c_str());
+ osd_file::error filerr = file.open(fname.c_str());
- if (filerr != FILERR_NONE)
+ if (filerr != osd_file::error::NONE)
return;
// define standard JPEG structures
diff --git a/src/emu/ui/videoopt.cpp b/src/emu/ui/videoopt.cpp
index 6ba6aa710f3..388ee07981b 100644
--- a/src/emu/ui/videoopt.cpp
+++ b/src/emu/ui/videoopt.cpp
@@ -2,7 +2,7 @@
// copyright-holders:Nicola Salmoria, Aaron Giles, Nathan Woods
/*********************************************************************
- ui/videoopt.c
+ ui/videoopt.cpp
Internal menus for video options
diff --git a/src/emu/uismall.png b/src/emu/uismall.png
deleted file mode 100644
index 5d391640f62..00000000000
--- a/src/emu/uismall.png
+++ /dev/null
Binary files differ
diff --git a/src/emu/video.cpp b/src/emu/video.cpp
index 229553a92b8..c3090bc6096 100644
--- a/src/emu/video.cpp
+++ b/src/emu/video.cpp
@@ -350,8 +350,8 @@ void video_manager::save_active_screen_snapshots()
if (machine().render().is_live(*screen))
{
emu_file file(machine().options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
- file_error filerr = open_next(file, "png");
- if (filerr == FILERR_NONE)
+ osd_file::error filerr = open_next(file, "png");
+ if (filerr == osd_file::error::NONE)
save_snapshot(screen, file);
}
}
@@ -360,8 +360,8 @@ void video_manager::save_active_screen_snapshots()
else
{
emu_file file(machine().options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
- file_error filerr = open_next(file, "png");
- if (filerr == FILERR_NONE)
+ osd_file::error filerr = open_next(file, "png");
+ if (filerr == osd_file::error::NONE)
save_snapshot(nullptr, file);
}
}
@@ -428,7 +428,7 @@ void video_manager::begin_recording(const char *name, movie_format format)
// build up information about this new movie
screen_device *screen = machine().first_screen();
- avi_movie_info info;
+ avi_file::movie_info info;
info.video_format = 0;
info.video_timescale = 1000 * ((screen != nullptr) ? ATTOSECONDS_TO_HZ(screen->frame_period().attoseconds()) : screen_device::DEFAULT_FRAME_RATE);
info.video_sampletime = 1000;
@@ -446,7 +446,7 @@ void video_manager::begin_recording(const char *name, movie_format format)
info.audio_samplerate = machine().sample_rate();
// create a new temporary movie file
- file_error filerr;
+ osd_file::error filerr;
std::string fullpath;
{
emu_file tempfile(machine().options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
@@ -456,20 +456,20 @@ void video_manager::begin_recording(const char *name, movie_format format)
filerr = open_next(tempfile, "avi");
// if we succeeded, make a copy of the name and create the real file over top
- if (filerr == FILERR_NONE)
+ if (filerr == osd_file::error::NONE)
fullpath = tempfile.fullpath();
}
- if (filerr == FILERR_NONE)
+ if (filerr == osd_file::error::NONE)
{
// compute the frame time
m_avi_frame_period = attotime::from_seconds(1000) / info.video_timescale;
// create the file and free the string
- avi_error avierr = avi_create(fullpath.c_str(), &info, &m_avi_file);
- if (avierr != AVIERR_NONE)
+ avi_file::error avierr = avi_file::create(fullpath, info, m_avi_file);
+ if (avierr != avi_file::error::NONE)
{
- osd_printf_error("Error creating AVI: %s\n", avi_error_string(avierr));
+ osd_printf_error("Error creating AVI: %s\n", avi_file::error_string(avierr));
return end_recording(format);
}
}
@@ -487,13 +487,13 @@ void video_manager::begin_recording(const char *name, movie_format format)
// create a new movie file and start recording
m_mng_file = std::make_unique<emu_file>(machine().options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
- file_error filerr;
+ osd_file::error filerr;
if (name != nullptr)
filerr = m_mng_file->open(name);
else
filerr = open_next(*m_mng_file, "mng");
- if (filerr == FILERR_NONE)
+ if (filerr == osd_file::error::NONE)
{
// start the capture
screen_device *screen = machine().first_screen();
@@ -510,7 +510,7 @@ void video_manager::begin_recording(const char *name, movie_format format)
}
else
{
- osd_printf_error("Error creating MNG, file_error=%d\n", filerr);
+ osd_printf_error("Error creating MNG, osd_file::error=%d\n", int(filerr));
m_mng_file.reset();
}
}
@@ -526,10 +526,9 @@ void video_manager::end_recording(movie_format format)
if (format == MF_AVI)
{
// close the file if it exists
- if (m_avi_file != nullptr)
+ if (m_avi_file)
{
- avi_close(m_avi_file);
- m_avi_file = nullptr;
+ m_avi_file.reset();
// reset the state
m_avi_frame = 0;
@@ -563,10 +562,10 @@ void video_manager::add_sound_to_recording(const INT16 *sound, int numsamples)
g_profiler.start(PROFILER_MOVIE_REC);
// write the next frame
- avi_error avierr = avi_append_sound_samples(m_avi_file, 0, sound + 0, numsamples, 1);
- if (avierr == AVIERR_NONE)
- avierr = avi_append_sound_samples(m_avi_file, 1, sound + 1, numsamples, 1);
- if (avierr != AVIERR_NONE)
+ avi_file::error avierr = m_avi_file->append_sound_samples(0, sound + 0, numsamples, 1);
+ if (avierr == avi_file::error::NONE)
+ avierr = m_avi_file->append_sound_samples(1, sound + 1, numsamples, 1);
+ if (avierr != avi_file::error::NONE)
end_recording(MF_AVI);
g_profiler.stop();
@@ -1091,8 +1090,8 @@ void video_manager::recompute_speed(const attotime &emutime)
{
// create a final screenshot
emu_file file(machine().options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
- file_error filerr = file.open(machine().basename(), PATH_SEPARATOR "final.png");
- if (filerr == FILERR_NONE)
+ osd_file::error filerr = file.open(machine().basename(), PATH_SEPARATOR "final.png");
+ if (filerr == osd_file::error::NONE)
save_snapshot(screen, file);
}
//printf("Scheduled exit at %f\n", emutime.as_double());
@@ -1150,7 +1149,7 @@ void video_manager::create_snapshot_bitmap(screen_device *screen)
// scheme
//-------------------------------------------------
-file_error video_manager::open_next(emu_file &file, const char *extension)
+osd_file::error video_manager::open_next(emu_file &file, const char *extension)
{
UINT32 origflags = file.openflags();
@@ -1260,8 +1259,8 @@ file_error video_manager::open_next(emu_file &file, const char *extension)
strreplace(fname, "%i", string_format("%04d", seq).c_str());
// try to open the file; stop when we fail
- file_error filerr = file.open(fname.c_str());
- if (filerr != FILERR_NONE)
+ osd_file::error filerr = file.open(fname.c_str());
+ if (filerr != osd_file::error::NONE)
break;
}
}
@@ -1296,8 +1295,8 @@ void video_manager::record_frame()
while (m_avi_next_frame_time <= curtime)
{
// write the next frame
- avi_error avierr = avi_append_video_frame(m_avi_file, m_snap_bitmap);
- if (avierr != AVIERR_NONE)
+ avi_file::error avierr = m_avi_file->append_video_frame(m_snap_bitmap);
+ if (avierr != avi_file::error::NONE)
{
g_profiler.stop();
end_recording(MF_AVI);
diff --git a/src/emu/video.h b/src/emu/video.h
index 67939d47eaa..019b2b0a472 100644
--- a/src/emu/video.h
+++ b/src/emu/video.h
@@ -14,8 +14,10 @@
#error Dont include this file directly; include emu.h instead.
#endif
-#ifndef __VIDEO_H__
-#define __VIDEO_H__
+#ifndef MAME_EMU_VIDEO_H
+#define MAME_EMU_VIDEO_H
+
+#include "aviio.h"
//**************************************************************************
@@ -35,7 +37,7 @@ const int MAX_FRAMESKIP = FRAMESKIP_LEVELS - 2;
// forward references
class render_target;
class screen_device;
-struct avi_file;
+class avi_file;
@@ -64,7 +66,7 @@ public:
bool throttled() const { return m_throttled; }
float throttle_rate() const { return m_throttle_rate; }
bool fastforward() const { return m_fastforward; }
- bool is_recording() const { return (m_mng_file != nullptr || m_avi_file != nullptr); }
+ bool is_recording() const { return (m_mng_file || m_avi_file); }
// setters
void set_frameskip(int frameskip);
@@ -76,7 +78,7 @@ public:
// misc
void toggle_throttle();
void toggle_record_movie();
- file_error open_next(emu_file &file, const char *extension);
+ osd_file::error open_next(emu_file &file, const char *extension);
// render a frame
void frame_update(bool debug = false);
@@ -184,7 +186,7 @@ private:
UINT32 m_mng_frame; // current movie frame number
// movie recording - AVI
- avi_file * m_avi_file; // handle to the open movie file
+ avi_file::ptr m_avi_file; // handle to the open movie file
attotime m_avi_frame_period; // period of a single movie frame
attotime m_avi_next_frame_time; // time of next frame
UINT32 m_avi_frame; // current movie frame number
@@ -205,4 +207,4 @@ private:
};
-#endif /* __VIDEO_H__ */
+#endif // MAME_EMU_VIDEO_H
diff --git a/src/ldplayer/ldplayer.cpp b/src/ldplayer/ldplayer.cpp
index 4f16ba130b8..5129b334448 100644
--- a/src/ldplayer/ldplayer.cpp
+++ b/src/ldplayer/ldplayer.cpp
@@ -195,8 +195,8 @@ chd_file *ldplayer_state::get_disc()
{
// open the file itself via our search path
emu_file image_file(machine().options().media_path(), OPEN_FLAG_READ);
- file_error filerr = image_file.open(dir->name);
- if (filerr == FILERR_NONE)
+ osd_file::error filerr = image_file.open(dir->name);
+ if (filerr == osd_file::error::NONE)
{
std::string fullpath(image_file.fullpath());
image_file.close();
diff --git a/src/lib/formats/ioprocs.cpp b/src/lib/formats/ioprocs.cpp
index 9f00e3bb9d5..3efb1055e56 100644
--- a/src/lib/formats/ioprocs.cpp
+++ b/src/lib/formats/ioprocs.cpp
@@ -121,49 +121,49 @@ const struct io_procs corefile_ioprocs_noclose =
calls for accessing generic IO
*********************************************************************/
-static void io_generic_seek(struct io_generic *generic, UINT64 offset)
+static void io_generic_seek(struct io_generic *genio, UINT64 offset)
{
- generic->procs->seekproc(generic->file, offset, SEEK_SET);
+ genio->procs->seekproc(genio->file, offset, SEEK_SET);
}
-void io_generic_close(struct io_generic *generic)
+void io_generic_close(struct io_generic *genio)
{
- if (generic->procs->closeproc)
- generic->procs->closeproc(generic->file);
+ if (genio->procs->closeproc)
+ genio->procs->closeproc(genio->file);
}
-void io_generic_read(struct io_generic *generic, void *buffer, UINT64 offset, size_t length)
+void io_generic_read(struct io_generic *genio, void *buffer, UINT64 offset, size_t length)
{
UINT64 size;
size_t bytes_read;
- size = io_generic_size(generic);
+ size = io_generic_size(genio);
if (size <= offset)
{
bytes_read = 0;
}
else
{
- io_generic_seek(generic, offset);
- bytes_read = generic->procs->readproc(generic->file, buffer, length);
+ io_generic_seek(genio, offset);
+ bytes_read = genio->procs->readproc(genio->file, buffer, length);
}
- memset(((UINT8 *) buffer) + bytes_read, generic->filler, length - bytes_read);
+ memset(((UINT8 *) buffer) + bytes_read, genio->filler, length - bytes_read);
}
-void io_generic_write(struct io_generic *generic, const void *buffer, UINT64 offset, size_t length)
+void io_generic_write(struct io_generic *genio, const void *buffer, UINT64 offset, size_t length)
{
UINT64 filler_size = 0;
char filler_buffer[1024];
size_t bytes_to_write;
UINT64 size;
- size = io_generic_size(generic);
+ size = io_generic_size(genio);
if (size < offset)
{
@@ -171,27 +171,27 @@ void io_generic_write(struct io_generic *generic, const void *buffer, UINT64 off
offset = size;
}
- io_generic_seek(generic, offset);
+ io_generic_seek(genio, offset);
if (filler_size)
{
- memset(filler_buffer, generic->filler, sizeof(filler_buffer));
+ memset(filler_buffer, genio->filler, sizeof(filler_buffer));
do
{
bytes_to_write = (filler_size > sizeof(filler_buffer)) ? sizeof(filler_buffer) : (size_t) filler_size;
- generic->procs->writeproc(generic->file, filler_buffer, bytes_to_write);
+ genio->procs->writeproc(genio->file, filler_buffer, bytes_to_write);
filler_size -= bytes_to_write;
}
while(filler_size > 0);
}
if (length > 0)
- generic->procs->writeproc(generic->file, buffer, length);
+ genio->procs->writeproc(genio->file, buffer, length);
}
-void io_generic_write_filler(struct io_generic *generic, UINT8 filler, UINT64 offset, size_t length)
+void io_generic_write_filler(struct io_generic *genio, UINT8 filler, UINT64 offset, size_t length)
{
UINT8 buffer[512];
size_t this_length;
@@ -201,7 +201,7 @@ void io_generic_write_filler(struct io_generic *generic, UINT8 filler, UINT64 of
while(length > 0)
{
this_length = MIN(length, sizeof(buffer));
- io_generic_write(generic, buffer, offset, this_length);
+ io_generic_write(genio, buffer, offset, this_length);
offset += this_length;
length -= this_length;
}
@@ -209,7 +209,7 @@ void io_generic_write_filler(struct io_generic *generic, UINT8 filler, UINT64 of
-UINT64 io_generic_size(struct io_generic *generic)
+UINT64 io_generic_size(struct io_generic *genio)
{
- return generic->procs->filesizeproc(generic->file);
+ return genio->procs->filesizeproc(genio->file);
}
diff --git a/src/lib/formats/ioprocs.h b/src/lib/formats/ioprocs.h
index 824e0d38129..08acbe45295 100644
--- a/src/lib/formats/ioprocs.h
+++ b/src/lib/formats/ioprocs.h
@@ -61,11 +61,11 @@ extern const struct io_procs corefile_ioprocs_noclose;
-void io_generic_close(struct io_generic *generic);
-void io_generic_read(struct io_generic *generic, void *buffer, UINT64 offset, size_t length);
-void io_generic_write(struct io_generic *generic, const void *buffer, UINT64 offset, size_t length);
-void io_generic_write_filler(struct io_generic *generic, UINT8 filler, UINT64 offset, size_t length);
-UINT64 io_generic_size(struct io_generic *generic);
+void io_generic_close(struct io_generic *genio);
+void io_generic_read(struct io_generic *genio, void *buffer, UINT64 offset, size_t length);
+void io_generic_write(struct io_generic *genio, const void *buffer, UINT64 offset, size_t length);
+void io_generic_write_filler(struct io_generic *genio, UINT8 filler, UINT64 offset, size_t length);
+UINT64 io_generic_size(struct io_generic *genio);
diff --git a/src/lib/netlist/devices/nld_7404.h b/src/lib/netlist/devices/nld_7404.h
index 60465f74d9c..18e7fe8087d 100644
--- a/src/lib/netlist/devices/nld_7404.h
+++ b/src/lib/netlist/devices/nld_7404.h
@@ -47,8 +47,8 @@ NETLIB_TRUTHTABLE(7404, 1, 1, 0);
#else
NETLIB_DEVICE(7404,
public:
- netlist_logic_input_t m_I[1];
- netlist_logic_output_t m_Q[1];
+ logic_input_t m_I[1];
+ logic_output_t m_Q[1];
);
#endif
diff --git a/src/lib/netlist/devices/nld_7486.h b/src/lib/netlist/devices/nld_7486.h
index 788b633dfe1..affc57b51ed 100644
--- a/src/lib/netlist/devices/nld_7486.h
+++ b/src/lib/netlist/devices/nld_7486.h
@@ -51,11 +51,11 @@ NETLIB_TRUTHTABLE(7486, 2, 1, 0);
#else
NETLIB_DEVICE(7486,
public:
- netlist_logic_input_t m_I[2];
- netlist_logic_output_t m_Q[1];
+ logic_input_t m_I[2];
+ logic_output_t m_Q[1];
- ATTR_HOT void inc_active();
- ATTR_HOT void dec_active();
+ ATTR_HOT void inc_active() override;
+ ATTR_HOT void dec_active() override;
int m_active;
);
#endif
diff --git a/src/lib/netlist/devices/nld_82S16.cpp b/src/lib/netlist/devices/nld_82S16.cpp
index 07990ffa598..593ea1b0d89 100644
--- a/src/lib/netlist/devices/nld_82S16.cpp
+++ b/src/lib/netlist/devices/nld_82S16.cpp
@@ -22,7 +22,7 @@ NETLIB_UPDATE(82S16)
}
else
{
- int adr = 0;
+ unsigned int adr = 0;
for (int i=0; i<8; i++)
{
//m_A[i].activate();
@@ -31,9 +31,9 @@ NETLIB_UPDATE(82S16)
if (!INPLOGIC(m_WEQ))
{
- m_ram[adr] = INPLOGIC(m_DIN);
+ m_ram[adr >> 6] = (m_ram[adr >> 6] & ~((UINT64) 1 << (adr & 0x3f))) | ((UINT64) INPLOGIC(m_DIN) << (adr & 0x3f));
}
- OUTLOGIC(m_DOUTQ, m_ram[adr] ^ 1, NLTIME_FROM_NS(20));
+ OUTLOGIC(m_DOUTQ, ((m_ram[adr >> 6] >> (adr & 0x3f)) & 1) ^ 1, NLTIME_FROM_NS(20));
}
}
@@ -62,7 +62,7 @@ NETLIB_START(82S16)
NETLIB_RESET(82S16)
{
- for (int i=0; i<256; i++)
+ for (int i=0; i<4; i++)
{
m_ram[i] = 0;
}
diff --git a/src/lib/netlist/devices/nld_82S16.h b/src/lib/netlist/devices/nld_82S16.h
index b6d8f6565d6..bb3f1c873ad 100644
--- a/src/lib/netlist/devices/nld_82S16.h
+++ b/src/lib/netlist/devices/nld_82S16.h
@@ -44,7 +44,7 @@ NETLIB_DEVICE(82S16,
logic_output_t m_DOUTQ;
//netlist_state_t<UINT8[256]> m_ram;
- UINT8 m_ram[256];
+ UINT64 m_ram[4]; // 256 bits
);
NETLIB_DEVICE_DERIVED_PURE(82S16_dip, 82S16);
diff --git a/src/lib/netlist/devices/nld_9312.h b/src/lib/netlist/devices/nld_9312.h
index ab5c0a8f8c9..2d982474377 100644
--- a/src/lib/netlist/devices/nld_9312.h
+++ b/src/lib/netlist/devices/nld_9312.h
@@ -58,13 +58,13 @@ NETLIB_TRUTHTABLE(9312, 12, 2, 0);
NETLIB_DEVICE(9312,
public:
// C, B, A, G,D0,D1,D2,D3,D4,D5,D6,D7| Y,YQ
- netlist_logic_input_t m_A;
- netlist_logic_input_t m_B;
- netlist_logic_input_t m_C;
- netlist_logic_input_t m_G;
- netlist_logic_input_t m_D[8];
- netlist_logic_output_t m_Y;
- netlist_logic_output_t m_YQ;
+ logic_input_t m_A;
+ logic_input_t m_B;
+ logic_input_t m_C;
+ logic_input_t m_G;
+ logic_input_t m_D[8];
+ logic_output_t m_Y;
+ logic_output_t m_YQ;
UINT8 m_last_chan;
UINT8 m_last_G;
diff --git a/src/lib/netlist/devices/nld_system.cpp b/src/lib/netlist/devices/nld_system.cpp
index ca96f776aac..be2ad3718b0 100644
--- a/src/lib/netlist/devices/nld_system.cpp
+++ b/src/lib/netlist/devices/nld_system.cpp
@@ -78,7 +78,7 @@ NETLIB_START(extclock)
connect_late(m_feedback, m_Q);
{
netlist_time base = netlist_time::from_hz(m_freq.Value()*2);
- pstring_list_t pat(m_pattern.Value(),",");
+ pstring_vector_t pat(m_pattern.Value(),",");
m_off = netlist_time::from_double(m_offset.Value());
int pati[256];
@@ -301,7 +301,7 @@ NETLIB_START(function)
for (int i=0; i < m_N; i++)
register_input(pfmt("A{1}")(i), m_I[i]);
- pstring_list_t cmds(m_func.Value(), " ");
+ pstring_vector_t cmds(m_func.Value(), " ");
m_precompiled.clear();
for (std::size_t i=0; i < cmds.size(); i++)
@@ -329,7 +329,7 @@ NETLIB_START(function)
if (err)
netlist().log().fatal("nld_function: unknown/misformatted token <{1}> in <{2}>", cmd, m_func.Value());
}
- m_precompiled.add(rc);
+ m_precompiled.push_back(rc);
}
}
diff --git a/src/lib/netlist/devices/nld_system.h b/src/lib/netlist/devices/nld_system.h
index a50860c3ac4..8ea3640ec14 100644
--- a/src/lib/netlist/devices/nld_system.h
+++ b/src/lib/netlist/devices/nld_system.h
@@ -309,7 +309,7 @@ private:
analog_output_t m_Q;
analog_input_t m_I[10];
- plist_t<rpn_inst> m_precompiled;
+ pvector_t<rpn_inst> m_precompiled;
};
// -----------------------------------------------------------------------------
diff --git a/src/lib/netlist/devices/nld_truthtable.cpp b/src/lib/netlist/devices/nld_truthtable.cpp
index 1f671b23108..9cd2d206664 100644
--- a/src/lib/netlist/devices/nld_truthtable.cpp
+++ b/src/lib/netlist/devices/nld_truthtable.cpp
@@ -99,8 +99,8 @@ UINT32 truthtable_desc_t::get_ignored_extended(UINT32 i)
// desc
// ----------------------------------------------------------------------------------------
-void truthtable_desc_t::help(unsigned cur, pstring_list_t list,
- UINT64 state,UINT16 val, UINT8 *timing_index)
+void truthtable_desc_t::help(unsigned cur, pstring_vector_t list,
+ UINT64 state,UINT16 val, parray_t<UINT8> &timing_index)
{
pstring elem = list[cur].trim();
int start = 0;
@@ -144,7 +144,7 @@ void truthtable_desc_t::help(unsigned cur, pstring_list_t list,
}
}
-void truthtable_desc_t::setup(const pstring_list_t &truthtable, UINT32 disabled_ignore)
+void truthtable_desc_t::setup(const pstring_vector_t &truthtable, UINT32 disabled_ignore)
{
unsigned line = 0;
@@ -164,14 +164,14 @@ void truthtable_desc_t::setup(const pstring_list_t &truthtable, UINT32 disabled_
while (!ttline.equals(""))
{
- pstring_list_t io(ttline,"|");
+ pstring_vector_t io(ttline,"|");
// checks
nl_assert_always(io.size() == 3, "io.count mismatch");
- pstring_list_t inout(io[0], ",");
+ pstring_vector_t inout(io[0], ",");
nl_assert_always(inout.size() == m_num_bits, "number of bits not matching");
- pstring_list_t out(io[1], ",");
+ pstring_vector_t out(io[1], ",");
nl_assert_always(out.size() == m_NO, "output count not matching");
- pstring_list_t times(io[2], ",");
+ pstring_vector_t times(io[2], ",");
nl_assert_always(times.size() == m_NO, "timing count not matching");
UINT16 val = 0;
@@ -192,8 +192,11 @@ void truthtable_desc_t::setup(const pstring_list_t &truthtable, UINT32 disabled_
tindex[j] = k;
}
- help(0, inout, 0 , val, tindex.data());
- ttline = truthtable[line];
+ help(0, inout, 0 , val, tindex);
+ if (line < truthtable.size())
+ ttline = truthtable[line];
+ else
+ ttline = "";
line++;
}
diff --git a/src/lib/netlist/devices/nld_truthtable.h b/src/lib/netlist/devices/nld_truthtable.h
index 47e479a0256..7619987c8f8 100644
--- a/src/lib/netlist/devices/nld_truthtable.h
+++ b/src/lib/netlist/devices/nld_truthtable.h
@@ -30,10 +30,10 @@
# _name, # _name, "+" _def_params);
#define TT_HEAD(_x) \
- ttd->m_desc.add(_x);
+ ttd->m_desc.push_back(_x);
#define TT_LINE(_x) \
- ttd->m_desc.add(_x);
+ ttd->m_desc.push_back(_x);
#define TT_FAMILY(_x) \
ttd->m_family = setup.family_from_model(_x);
@@ -65,11 +65,11 @@ struct truthtable_desc_t
{
}
- void setup(const pstring_list_t &desc, UINT32 disabled_ignore);
+ void setup(const pstring_vector_t &desc, UINT32 disabled_ignore);
private:
- void help(unsigned cur, pstring_list_t list,
- UINT64 state,UINT16 val, UINT8 *timing_index);
+ void help(unsigned cur, pstring_vector_t list,
+ UINT64 state,UINT16 val, parray_t<UINT8> &timing_index);
static unsigned count_bits(UINT32 v);
static UINT32 set_bits(UINT32 v, UINT32 b);
UINT32 get_ignored_simple(UINT32 i);
@@ -114,13 +114,13 @@ public:
{
while (*desc != NULL && **desc != 0 )
{
- m_desc.add(*desc);
+ m_desc.push_back(*desc);
desc++;
}
}
- nld_truthtable_t(truthtable_t *ttbl, const pstring_list_t &desc)
+ nld_truthtable_t(truthtable_t *ttbl, const pstring_vector_t &desc)
: device_t(), m_last_state(0), m_ign(0), m_active(1), m_ttp(ttbl)
{
m_desc = desc;
@@ -130,12 +130,12 @@ public:
{
pstring header = m_desc[0];
- pstring_list_t io(header,"|");
+ pstring_vector_t io(header,"|");
// checks
nl_assert_always(io.size() == 2, "too many '|'");
- pstring_list_t inout(io[0], ",");
+ pstring_vector_t inout(io[0], ",");
nl_assert_always(inout.size() == m_num_bits, "bitcount wrong");
- pstring_list_t out(io[1], ",");
+ pstring_vector_t out(io[1], ",");
nl_assert_always(out.size() == m_NO, "output count wrong");
for (unsigned i=0; i < m_NI; i++)
@@ -289,7 +289,7 @@ private:
INT32 m_active;
truthtable_t *m_ttp;
- pstring_list_t m_desc;
+ pstring_vector_t m_desc;
};
class netlist_base_factory_truthtable_t : public base_factory_t
@@ -307,7 +307,7 @@ public:
pfree(m_family);
}
- pstring_list_t m_desc;
+ pstring_vector_t m_desc;
logic_family_desc_t *m_family;
};
diff --git a/src/lib/netlist/nl_base.cpp b/src/lib/netlist/nl_base.cpp
index f39de181da1..80f635b3f73 100644
--- a/src/lib/netlist/nl_base.cpp
+++ b/src/lib/netlist/nl_base.cpp
@@ -186,16 +186,15 @@ netlist_t::netlist_t()
netlist_t::~netlist_t()
{
- for (std::size_t i=0; i < m_nets.size(); i++)
+ for (net_t *net : m_nets)
{
- if (!m_nets[i]->isRailNet())
+ if (!net->isRailNet())
{
- pfree(m_nets[i]);
+ pfree(net);
}
}
m_nets.clear();
-
m_devices.clear_and_free();
pstring::resetmem();
@@ -237,12 +236,9 @@ ATTR_COLD void netlist_t::start()
m_use_deactivate = (m_params->m_use_deactivate.Value() ? true : false);
log().debug("Initializing devices ...\n");
- for (std::size_t i = 0; i < m_devices.size(); i++)
- {
- device_t *dev = m_devices[i];
+ for (device_t *dev : m_devices)
if (dev != m_solver && dev != m_params)
dev->start_dev();
- }
}
@@ -251,28 +247,23 @@ ATTR_COLD void netlist_t::stop()
/* find the main clock and solver ... */
log().debug("Stopping all devices ...\n");
-
- // Step all devices once !
- for (std::size_t i = 0; i < m_devices.size(); i++)
- {
- m_devices[i]->stop_dev();
- }
+ for (device_t *dev : m_devices)
+ dev->stop_dev();
}
ATTR_COLD net_t *netlist_t::find_net(const pstring &name)
{
- for (std::size_t i = 0; i < m_nets.size(); i++)
- {
- if (m_nets[i]->name() == name)
- return m_nets[i];
- }
+ for (net_t *net : m_nets)
+ if (net->name() == name)
+ return net;
+
return NULL;
}
ATTR_COLD void netlist_t::rebuild_lists()
{
- for (std::size_t i = 0; i < m_nets.size(); i++)
- m_nets[i]->rebuild_list();
+ for (net_t *net : m_nets)
+ net->rebuild_list();
}
@@ -303,9 +294,9 @@ ATTR_COLD void netlist_t::reset()
// FIXME: some const devices rely on this
/* make sure params are set now .. */
- for (std::size_t i = 0; i < m_devices.size(); i++)
+ for (device_t *dev : m_devices)
{
- m_devices[i]->update_param();
+ dev->update_param();
}
}
@@ -318,7 +309,7 @@ ATTR_HOT void netlist_t::process_queue(const netlist_time &delta)
{
while ( (m_time < m_stop) && (m_queue.is_not_empty()))
{
- const queue_t::entry_t e = *m_queue.pop();
+ const queue_t::entry_t &e = m_queue.pop();
m_time = e.exec_time();
e.object()->update_devs();
@@ -336,21 +327,25 @@ ATTR_HOT void netlist_t::process_queue(const netlist_time &delta)
{
if (m_queue.is_not_empty())
{
- while (m_queue.peek()->exec_time() > mc_time)
+ while (m_queue.top().exec_time() > mc_time)
{
m_time = mc_time;
mc_time += inc;
- devices::NETLIB_NAME(mainclock)::mc_update(mc_net);
+ mc_net.toggle_new_Q();
+ mc_net.update_devs();
+ //devices::NETLIB_NAME(mainclock)::mc_update(mc_net);
}
- const queue_t::entry_t e = *m_queue.pop();
+ const queue_t::entry_t &e = m_queue.pop();
m_time = e.exec_time();
e.object()->update_devs();
} else {
m_time = mc_time;
mc_time += inc;
- devices::NETLIB_NAME(mainclock)::mc_update(mc_net);
+ mc_net.toggle_new_Q();
+ mc_net.update_devs();
+ //devices::NETLIB_NAME(mainclock)::mc_update(mc_net);
}
add_to_stat(m_perf_out_processed, 1);
@@ -435,13 +430,13 @@ ATTR_HOT netlist_sig_t core_device_t::INPLOGIC_PASSIVE(logic_input_t &inp)
device_t::device_t()
: core_device_t(GENERIC),
- m_terminals(20)
+ m_terminals()
{
}
device_t::device_t(const family_t afamily)
: core_device_t(afamily),
- m_terminals(20)
+ m_terminals()
{
}
@@ -477,7 +472,7 @@ ATTR_COLD void device_t::register_subalias(const pstring &name, core_terminal_t
setup().register_alias_nofqn(alias, term.name());
if (term.isType(terminal_t::INPUT) || term.isType(terminal_t::TERMINAL))
- m_terminals.add(alias);
+ m_terminals.push_back(alias);
}
ATTR_COLD void device_t::register_subalias(const pstring &name, const pstring &aliased)
@@ -497,7 +492,7 @@ ATTR_COLD void device_t::register_terminal(const pstring &name, terminal_t &port
{
setup().register_object(*this, name, port);
if (port.isType(terminal_t::INPUT) || port.isType(terminal_t::TERMINAL))
- m_terminals.add(port.name());
+ m_terminals.push_back(port.name());
}
ATTR_COLD void device_t::register_output(const pstring &name, logic_output_t &port)
@@ -515,13 +510,13 @@ ATTR_COLD void device_t::register_input(const pstring &name, logic_input_t &inp)
{
inp.set_logic_family(this->logic_family());
setup().register_object(*this, name, inp);
- m_terminals.add(inp.name());
+ m_terminals.push_back(inp.name());
}
ATTR_COLD void device_t::register_input(const pstring &name, analog_input_t &inp)
{
setup().register_object(*this, name, inp);
- m_terminals.add(inp.name());
+ m_terminals.push_back(inp.name());
}
ATTR_COLD void device_t::connect_late(core_terminal_t &t1, core_terminal_t &t2)
@@ -584,7 +579,7 @@ ATTR_COLD net_t::~net_t()
ATTR_COLD void net_t::init_object(netlist_t &nl, const pstring &aname)
{
object_t::init_object(nl, aname);
- nl.m_nets.add(this);
+ nl.m_nets.push_back(this);
}
ATTR_HOT void net_t::inc_active(core_terminal_t &term)
@@ -638,10 +633,10 @@ ATTR_COLD void net_t::rebuild_list()
unsigned cnt = 0;
m_list_active.clear();
- for (std::size_t i=0; i < m_core_terms.size(); i++)
- if (m_core_terms[i]->state() != logic_t::STATE_INP_PASSIVE)
+ for (core_terminal_t *term : m_core_terms)
+ if (term->state() != logic_t::STATE_INP_PASSIVE)
{
- m_list_active.add(*m_core_terms[i]);
+ m_list_active.add(*term);
cnt++;
}
m_active = cnt;
@@ -658,55 +653,23 @@ ATTR_COLD void net_t::save_register()
object_t::save_register();
}
-ATTR_HOT /* inline */ void core_terminal_t::update_dev(const UINT32 mask)
-{
- inc_stat(netdev().stat_call_count);
- if ((state() & mask) != 0)
- {
- device().update_dev();
- }
-}
-
ATTR_HOT /* inline */ void net_t::update_devs()
{
//assert(m_num_cons != 0);
nl_assert(this->isRailNet());
- const UINT32 masks[4] = { 1, 5, 3, 1 };
- const UINT32 mask = masks[ (m_cur_Q << 1) | m_new_Q ];
+ const int masks[4] = { 1, 5, 3, 1 };
+ const int mask = masks[ (m_cur_Q << 1) | m_new_Q ];
m_in_queue = 2; /* mark as taken ... */
m_cur_Q = m_new_Q;
-#if 0
- core_terminal_t * t[256];
- core_terminal_t *p = m_list_active.first();
- int cnt = 0;
- while (p != NULL)
- {
- if ((p->state() & mask) != 0)
- t[cnt++] = p;
- p = m_list_active.next(p);
- }
-
- for (int i=0; i<cnt; i++)
- t[i]->netdev().update_dev();
- core_terminal_t *p = m_list_active.first();
- while (p != NULL)
+ for (core_terminal_t *p = m_list_active.first(); p != NULL; p = p->next())
{
- p->update_dev(mask);
- p = m_list_active.next(p);
- }
-
-#else
- core_terminal_t *p = m_list_active.first();
-
- while (p != NULL)
- {
- p->update_dev(mask);
- p = p->m_next;
+ inc_stat(p->netdev().stat_call_count);
+ if ((p->state() & mask) != 0)
+ p->device().update_dev();
}
-#endif
}
ATTR_COLD void net_t::reset()
@@ -722,14 +685,14 @@ ATTR_COLD void net_t::reset()
/* rebuild m_list */
m_list_active.clear();
- for (std::size_t i=0; i < m_core_terms.size(); i++)
- m_list_active.add(*m_core_terms[i]);
+ for (core_terminal_t *ct : m_core_terms)
+ m_list_active.add(*ct);
- for (std::size_t i=0; i < m_core_terms.size(); i++)
- m_core_terms[i]->do_reset();
+ for (core_terminal_t *ct : m_core_terms)
+ ct->do_reset();
- for (std::size_t i=0; i < m_core_terms.size(); i++)
- if (m_core_terms[i]->state() != logic_t::STATE_INP_PASSIVE)
+ for (core_terminal_t *ct : m_core_terms)
+ if (ct->state() != logic_t::STATE_INP_PASSIVE)
m_active++;
}
@@ -737,7 +700,7 @@ ATTR_COLD void net_t::register_con(core_terminal_t &terminal)
{
terminal.set_net(*this);
- m_core_terms.add(&terminal);
+ m_core_terms.push_back(&terminal);
if (terminal.state() != logic_t::STATE_INP_PASSIVE)
m_active++;
@@ -745,11 +708,8 @@ ATTR_COLD void net_t::register_con(core_terminal_t &terminal)
ATTR_COLD void net_t::move_connections(net_t *dest_net)
{
- for (std::size_t i = 0; i < m_core_terms.size(); i++)
- {
- core_terminal_t *p = m_core_terms[i];
- dest_net->register_con(*p);
- }
+ for (core_terminal_t *ct : m_core_terms)
+ dest_net->register_con(*ct);
m_core_terms.clear();
m_active = 0;
}
@@ -842,10 +802,9 @@ ATTR_COLD void analog_net_t::process_net(list_t *groups, int &cur_group)
if (num_cons() == 0)
return;
/* add the net */
- groups[cur_group].add(this);
- for (std::size_t i = 0; i < m_core_terms.size(); i++)
+ groups[cur_group].push_back(this);
+ for (core_terminal_t *p : m_core_terms)
{
- core_terminal_t *p = m_core_terms[i];
if (p->isType(terminal_t::TERMINAL))
{
terminal_t *pt = static_cast<terminal_t *>(p);
@@ -863,7 +822,7 @@ ATTR_COLD void analog_net_t::process_net(list_t *groups, int &cur_group)
ATTR_COLD core_terminal_t::core_terminal_t(const type_t atype, const family_t afamily)
: device_object_t(atype, afamily)
-, plinkedlist_element_t<core_terminal_t>()
+, plinkedlist_element_t()
, m_net(NULL)
, m_state(STATE_NONEX)
{
diff --git a/src/lib/netlist/nl_base.h b/src/lib/netlist/nl_base.h
index 5289a3171e0..72911c9b25c 100644
--- a/src/lib/netlist/nl_base.h
+++ b/src/lib/netlist/nl_base.h
@@ -155,6 +155,8 @@
#ifndef NLBASE_H_
#define NLBASE_H_
+#include <vector>
+
#include "nl_lists.h"
#include "nl_time.h"
#include "nl_util.h"
@@ -165,7 +167,14 @@
// Type definitions
// ----------------------------------------------------------------------------------------
-typedef UINT8 netlist_sig_t;
+//typedef UINT8 netlist_sig_t;
+
+/*
+ * unsigned int would be a 20% speed increase over UINT8 for pong.
+ * For breakout it causes a slight decrease.
+ *
+ */
+typedef unsigned int netlist_sig_t;
//============================================================
// MACROS / netlist devices
@@ -460,7 +469,7 @@ namespace netlist
P_PREVENT_COPYING(core_terminal_t)
public:
- typedef plist_t<core_terminal_t *> list_t;
+ typedef pvector_t<core_terminal_t *> list_t;
/* needed here ... */
@@ -486,16 +495,13 @@ namespace netlist
ATTR_HOT net_t & net() { return *m_net;}
ATTR_HOT bool is_state(const state_e astate) const { return (m_state == astate); }
- ATTR_HOT state_e state() const { return m_state; }
+ ATTR_HOT const state_e &state() const { return m_state; }
ATTR_HOT void set_state(const state_e astate)
{
nl_assert(astate != STATE_NONEX);
m_state = astate;
}
-
- ATTR_HOT /* inline */ void update_dev(const UINT32 mask);
-
protected:
virtual void save_register() override
{
@@ -513,7 +519,7 @@ namespace netlist
P_PREVENT_COPYING(terminal_t)
public:
- typedef plist_t<terminal_t *> list_t;
+ typedef pvector_t<terminal_t *> list_t;
ATTR_COLD terminal_t();
@@ -664,7 +670,7 @@ namespace netlist
P_PREVENT_COPYING(net_t)
public:
- typedef plist_t<net_t *> list_t;
+ typedef pvector_t<net_t *> list_t;
ATTR_COLD net_t(const family_t afamily);
virtual ~net_t();
@@ -702,7 +708,7 @@ namespace netlist
ATTR_COLD void move_connections(net_t *new_net);
- plist_t<core_terminal_t *> m_core_terms; // save post-start m_list ...
+ pvector_t<core_terminal_t *> m_core_terms; // save post-start m_list ...
ATTR_HOT void set_Q_time(const netlist_sig_t &newQ, const netlist_time &at)
{
@@ -744,7 +750,7 @@ namespace netlist
P_PREVENT_COPYING(logic_net_t)
public:
- typedef plist_t<logic_net_t *> list_t;
+ typedef pvector_t<logic_net_t *> list_t;
ATTR_COLD logic_net_t();
virtual ~logic_net_t() { };
@@ -804,7 +810,7 @@ namespace netlist
P_PREVENT_COPYING(analog_net_t)
public:
- typedef plist_t<analog_net_t *> list_t;
+ typedef pvector_t<analog_net_t *> list_t;
ATTR_COLD analog_net_t();
virtual ~analog_net_t() { };
@@ -990,7 +996,7 @@ namespace netlist
P_PREVENT_COPYING(core_device_t)
public:
- typedef plist_t<core_device_t *> list_t;
+ typedef pvector_t<core_device_t *> list_t;
ATTR_COLD core_device_t(const family_t afamily);
@@ -1106,7 +1112,7 @@ namespace netlist
ATTR_COLD void connect_late(core_terminal_t &t1, core_terminal_t &t2);
ATTR_COLD void connect_direct(core_terminal_t &t1, core_terminal_t &t2);
- plist_t<pstring> m_terminals;
+ pvector_t<pstring> m_terminals;
protected:
@@ -1186,14 +1192,14 @@ namespace netlist
ATTR_COLD net_t *find_net(const pstring &name);
template<class _device_class>
- ATTR_COLD plist_t<_device_class *> get_device_list()
+ ATTR_COLD pvector_t<_device_class *> get_device_list()
{
- plist_t<_device_class *> tmp;
+ pvector_t<_device_class *> tmp;
for (std::size_t i = 0; i < m_devices.size(); i++)
{
_device_class *dev = dynamic_cast<_device_class *>(m_devices[i]);
if (dev != NULL)
- tmp.add(dev);
+ tmp.push_back(dev);
}
return tmp;
}
@@ -1228,7 +1234,7 @@ namespace netlist
return ret;
}
- pnamedlist_t<device_t *> m_devices;
+ pvector_t<device_t *> m_devices;
net_t::list_t m_nets;
#if (NL_KEEP_STATISTICS)
pnamedlist_t<core_device_t *> m_started_devices;
diff --git a/src/lib/netlist/nl_factory.cpp b/src/lib/netlist/nl_factory.cpp
index 5f6762c4d05..45765cb8e30 100644
--- a/src/lib/netlist/nl_factory.cpp
+++ b/src/lib/netlist/nl_factory.cpp
@@ -17,20 +17,20 @@ namespace netlist
// net_device_t_base_factory
// ----------------------------------------------------------------------------------------
-ATTR_COLD const pstring_list_t base_factory_t::term_param_list()
+ATTR_COLD const pstring_vector_t base_factory_t::term_param_list()
{
if (m_def_param.startsWith("+"))
- return pstring_list_t(m_def_param.substr(1), ",");
+ return pstring_vector_t(m_def_param.substr(1), ",");
else
- return pstring_list_t();
+ return pstring_vector_t();
}
-ATTR_COLD const pstring_list_t base_factory_t::def_params()
+ATTR_COLD const pstring_vector_t base_factory_t::def_params()
{
if (m_def_param.startsWith("+") || m_def_param.equals("-"))
- return pstring_list_t();
+ return pstring_vector_t();
else
- return pstring_list_t(m_def_param, ",");
+ return pstring_vector_t(m_def_param, ",");
}
diff --git a/src/lib/netlist/nl_factory.h b/src/lib/netlist/nl_factory.h
index 971912a0d2d..f9977ae414a 100644
--- a/src/lib/netlist/nl_factory.h
+++ b/src/lib/netlist/nl_factory.h
@@ -36,8 +36,8 @@ namespace netlist
ATTR_COLD const pstring &name() const { return m_name; }
ATTR_COLD const pstring &classname() const { return m_classname; }
ATTR_COLD const pstring &param_desc() const { return m_def_param; }
- ATTR_COLD const pstring_list_t term_param_list();
- ATTR_COLD const pstring_list_t def_params();
+ ATTR_COLD const pstring_vector_t term_param_list();
+ ATTR_COLD const pstring_vector_t def_params();
protected:
pstring m_name; /* device name */
diff --git a/src/lib/netlist/nl_lists.h b/src/lib/netlist/nl_lists.h
index b861d1e84e2..ac288fec153 100644
--- a/src/lib/netlist/nl_lists.h
+++ b/src/lib/netlist/nl_lists.h
@@ -64,12 +64,12 @@ namespace netlist
/* Lock */
while (atomic_exchange32(&m_lock, 1)) { }
#endif
- const _Time t = e.exec_time();
+ const _Time &t = e.exec_time();
entry_t * i = m_end++;
- while (t > (i - 1)->exec_time())
+ for (; t > (i - 1)->exec_time(); i--)
{
*(i) = *(i-1);
- i--;
+ //i--;
inc_stat(m_prof_sortmove);
}
*i = e;
@@ -80,14 +80,14 @@ namespace netlist
//nl_assert(m_end - m_list < _Size);
}
- ATTR_HOT const entry_t *pop()
+ ATTR_HOT const entry_t & pop()
{
- return --m_end;
+ return *(--m_end);
}
- ATTR_HOT const entry_t *peek() const
+ ATTR_HOT const entry_t & top() const
{
- return (m_end-1);
+ return *(m_end-1);
}
ATTR_HOT void remove(const _Element &elem)
@@ -96,8 +96,7 @@ namespace netlist
#if HAS_OPENMP && USE_OPENMP
while (atomic_exchange32(&m_lock, 1)) { }
#endif
- entry_t * i = m_end - 1;
- while (i > &m_list[0])
+ for (entry_t * i = m_end - 1; i > &m_list[0]; i--)
{
if (i->object() == elem)
{
@@ -112,7 +111,6 @@ namespace netlist
#endif
return;
}
- i--;
}
#if HAS_OPENMP && USE_OPENMP
m_lock = 0;
@@ -148,9 +146,7 @@ namespace netlist
volatile INT32 m_lock;
#endif
entry_t * m_end;
- //entry_t m_list[_Size];
parray_t<entry_t> m_list;
-
};
}
diff --git a/src/lib/netlist/nl_parser.cpp b/src/lib/netlist/nl_parser.cpp
index 638bbae219a..bcbc788dbce 100644
--- a/src/lib/netlist/nl_parser.cpp
+++ b/src/lib/netlist/nl_parser.cpp
@@ -168,13 +168,13 @@ void parser_t::net_truthtable_start()
if (token.is(m_tok_TT_HEAD))
{
require_token(m_tok_param_left);
- ttd->m_desc.add(get_string());
+ ttd->m_desc.push_back(get_string());
require_token(m_tok_param_right);
}
else if (token.is(m_tok_TT_LINE))
{
require_token(m_tok_param_left);
- ttd->m_desc.add(get_string());
+ ttd->m_desc.push_back(get_string());
require_token(m_tok_param_right);
}
else if (token.is(m_tok_TT_FAMILY))
@@ -294,15 +294,15 @@ void parser_t::net_c()
void parser_t::dippins()
{
- pstring_list_t pins;
+ pstring_vector_t pins;
- pins.add(get_identifier());
+ pins.push_back(get_identifier());
require_token(m_tok_comma);
while (true)
{
pstring t1 = get_identifier();
- pins.add(t1);
+ pins.push_back(t1);
token_t n = get_token();
if (n.is(m_tok_param_right))
break;
@@ -353,8 +353,8 @@ void parser_t::device(const pstring &dev_type)
{
base_factory_t *f = m_setup.factory().factory_by_name(dev_type);
device_t *dev;
- pstring_list_t termlist = f->term_param_list();
- pstring_list_t def_params = f->def_params();
+ pstring_vector_t termlist = f->term_param_list();
+ pstring_vector_t def_params = f->def_params();
std::size_t cnt;
diff --git a/src/lib/netlist/nl_setup.cpp b/src/lib/netlist/nl_setup.cpp
index 99874a0a06d..29bb21cbd66 100644
--- a/src/lib/netlist/nl_setup.cpp
+++ b/src/lib/netlist/nl_setup.cpp
@@ -53,6 +53,7 @@ namespace netlist
setup_t::setup_t(netlist_t *netlist)
: m_netlist(netlist)
, m_proxy_cnt(0)
+ , m_frontier_cnt(0)
{
netlist->set_setup(this);
m_factory = palloc(factory_list_t(*this));
@@ -85,7 +86,7 @@ ATTR_COLD pstring setup_t::build_fqn(const pstring &obj_name) const
if (m_stack.empty())
return netlist().name() + "." + obj_name;
else
- return m_stack.peek() + "." + obj_name;
+ return m_stack.top() + "." + obj_name;
}
void setup_t::namespace_push(const pstring &aname)
@@ -93,7 +94,7 @@ void setup_t::namespace_push(const pstring &aname)
if (m_stack.empty())
m_stack.push(netlist().name() + "." + aname);
else
- m_stack.push(m_stack.peek() + "." + aname);
+ m_stack.push(m_stack.top() + "." + aname);
}
void setup_t::namespace_pop()
@@ -108,8 +109,11 @@ device_t *setup_t::register_dev(device_t *dev, const pstring &name)
dev->init(netlist(), fqn);
- if (!(netlist().m_devices.add(dev, false)==true))
- log().fatal("Error adding {1} to device list\n", name);
+ for (auto & d : netlist().m_devices)
+ if (d->name() == dev->name())
+ log().fatal("Error adding {1} to device list. Duplicate name \n", name);
+
+ netlist().m_devices.push_back(dev);
return dev;
}
@@ -118,7 +122,7 @@ void setup_t::register_lib_entry(const pstring &name)
if (m_lib.contains(name))
log().warning("Lib entry collection already contains {1}. IGNORED", name);
else
- m_lib.add(name);
+ m_lib.push_back(name);
}
device_t *setup_t::register_dev(const pstring &classname, const pstring &name)
@@ -166,7 +170,7 @@ void setup_t::register_alias(const pstring &alias, const pstring &out)
void setup_t::register_dippins_arr(const pstring &terms)
{
- pstring_list_t list(terms,", ");
+ 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");
unsigned n = list.size();
@@ -235,7 +239,6 @@ void setup_t::register_object(device_t &dev, const pstring &name, object_t &obj)
case terminal_t::PARAM:
{
param_t &param = dynamic_cast<param_t &>(obj);
- //printf("name: {1}\n", name);
if (m_params_temp.contains(name))
{
const pstring val = m_params_temp[name];
@@ -291,7 +294,7 @@ void setup_t::register_object(device_t &dev, const pstring &name, object_t &obj)
void setup_t::register_link_arr(const pstring &terms)
{
- pstring_list_t list(terms,", ");
+ pstring_vector_t list(terms,", ");
if (list.size() < 2)
log().fatal("You must pass at least 2 terminals to NET_C");
for (std::size_t i = 1; i < list.size(); i++)
@@ -305,7 +308,7 @@ void setup_t::register_link_fqn(const pstring &sin, const pstring &sout)
{
link_t temp = link_t(sin, sout);
log().debug("link {1} <== {2}\n", sin, sout);
- m_links.add(temp);
+ m_links.push_back(temp);
}
void setup_t::register_link(const pstring &sin, const pstring &sout)
@@ -317,11 +320,13 @@ void setup_t::remove_connections(const pstring pin)
{
pstring pinfn = build_fqn(pin);
bool found = false;
- for (std::size_t i = 0; i < m_links.size(); i++)
+
+ for (int i = m_links.size() - 1; i >= 0; i--)
{
- if ((m_links[i].e1 == pinfn) || (m_links[i].e2 == pinfn))
+ auto &link = m_links[i];
+ if ((link.e1 == pinfn) || (link.e2 == pinfn))
{
- log().verbose("removing connection: {1} <==> {2}\n", m_links[i].e1, m_links[i].e2);
+ log().verbose("removing connection: {1} <==> {2}\n", link.e1, link.e2);
m_links.remove_at(i);
found = true;
}
@@ -333,25 +338,24 @@ void setup_t::remove_connections(const pstring pin)
void setup_t::register_frontier(const pstring attach, const double r_IN, const double r_OUT)
{
- static int frontier_cnt = 0;
- pstring frontier_name = pfmt("frontier_{1}")(frontier_cnt);
- frontier_cnt++;
+ pstring frontier_name = pfmt("frontier_{1}")(m_frontier_cnt);
+ m_frontier_cnt++;
device_t *front = register_dev("FRONTIER_DEV", frontier_name);
register_param(frontier_name + ".RIN", r_IN);
register_param(frontier_name + ".ROUT", r_OUT);
register_link(frontier_name + ".G", "GND");
pstring attfn = build_fqn(attach);
bool found = false;
- for (std::size_t i = 0; i < m_links.size(); i++)
+ for (auto & link : m_links)
{
- if (m_links[i].e1 == attfn)
+ if (link.e1 == attfn)
{
- m_links[i].e1 = front->name() + ".I";
+ link.e1 = front->name() + ".I";
found = true;
}
- else if (m_links[i].e2 == attfn)
+ else if (link.e2 == attfn)
{
- m_links[i].e2 = front->name() + ".I";
+ link.e2 = front->name() + ".I";
found = true;
}
}
@@ -472,7 +476,6 @@ devices::nld_base_proxy *setup_t::get_d_a_proxy(core_terminal_t &out)
{
nl_assert(out.isFamily(terminal_t::LOGIC));
- //printf("proxy for {1}\n", out.name());;
logic_output_t &out_cast = dynamic_cast<logic_output_t &>(out);
devices::nld_base_proxy *proxy = out_cast.get_proxy();
@@ -486,18 +489,16 @@ devices::nld_base_proxy *setup_t::get_d_a_proxy(core_terminal_t &out)
register_dev(new_proxy, x);
new_proxy->start_dev();
-#if 1
/* connect all existing terminals to new net */
- for (std::size_t i = 0; i < out.net().m_core_terms.size(); i++)
+ for (core_terminal_t *p : out.net().m_core_terms)
{
- core_terminal_t *p = out.net().m_core_terms[i];
p->clear_net(); // de-link from all nets ...
if (!connect(new_proxy->proxy_term(), *p))
log().fatal("Error connecting {1} to {2}\n", new_proxy->proxy_term().name(), (*p).name());
}
out.net().m_core_terms.clear(); // clear the list
-#endif
+
out.net().register_con(new_proxy->in());
out_cast.set_proxy(new_proxy);
proxy = new_proxy;
@@ -648,13 +649,11 @@ bool setup_t::connect_input_input(core_terminal_t &t1, core_terminal_t &t2)
ret = connect(t2, t1.net().railterminal());
if (!ret)
{
- for (std::size_t i=0; i<t1.net().m_core_terms.size(); i++)
+ for (core_terminal_t *t : t1.net().m_core_terms)
{
- if (t1.net().m_core_terms[i]->isType(core_terminal_t::TERMINAL)
+ if (t->isType(core_terminal_t::TERMINAL)
/*|| t1.net().m_core_terms[i]->isType(netlist_core_terminal_t::OUTPUT)*/)
- {
- ret = connect(t2, *t1.net().m_core_terms[i]);
- }
+ ret = connect(t2, *t);
if (ret)
break;
}
@@ -666,13 +665,11 @@ bool setup_t::connect_input_input(core_terminal_t &t1, core_terminal_t &t2)
ret = connect(t1, t2.net().railterminal());
if (!ret)
{
- for (std::size_t i=0; i<t2.net().m_core_terms.size(); i++)
+ for (core_terminal_t *t : t2.net().m_core_terms)
{
- if (t2.net().m_core_terms[i]->isType(core_terminal_t::TERMINAL)
+ if (t->isType(core_terminal_t::TERMINAL)
/*|| t2.net().m_core_terms[i]->isType(netlist_core_terminal_t::OUTPUT)*/)
- {
- ret = connect(t1, *t2.net().m_core_terms[i]);
- }
+ ret = connect(t1, *t);
if (ret)
break;
}
@@ -774,24 +771,20 @@ void setup_t::resolve_inputs()
net_t::list_t todelete;
- for (std::size_t i = 0; i<netlist().m_nets.size(); i++)
+ for (net_t *net : netlist().m_nets)
{
- if (netlist().m_nets[i]->num_cons() == 0)
- {
- todelete.add(netlist().m_nets[i]);
- }
+ if (net->num_cons() == 0)
+ todelete.push_back(net);
else
- {
- netlist().m_nets[i]->rebuild_list();
- }
+ net->rebuild_list();
}
- for (std::size_t i=0; i < todelete.size(); i++)
+ for (net_t *net : todelete)
{
- log().verbose("Deleting net {1} ...", todelete[i]->name());
- netlist().m_nets.remove(todelete[i]);
- if (!todelete[i]->isRailNet())
- pfree(todelete[i]);
+ log().verbose("Deleting net {1} ...", net->name());
+ netlist().m_nets.remove(net);
+ if (!net->isRailNet())
+ pfree(net);
}
pstring errstr("");
@@ -819,13 +812,8 @@ void setup_t::resolve_inputs()
{
has_twoterms = true;
if (t->m_N.net().isRailNet() && t->m_P.net().isRailNet())
-#if 0
- netlist().fatal("Found device {1} connected only to railterminals {2}/{3}\n",
- t->name(), t->m_N.net().name(), t->m_P.net().name());
-#else
log().warning("Found device {1} connected only to railterminals {2}/{3}\n",
t->name(), t->m_N.net().name(), t->m_P.net().name());
-#endif
}
}
@@ -848,15 +836,14 @@ void setup_t::start_devices()
if (env != "")
{
log().debug("Creating dynamic logs ...\n");
- pstring_list_t ll(env, ":");
- for (unsigned i=0; i < ll.size(); i++)
+ pstring_vector_t loglist(env, ":");
+ for (pstring ll : loglist)
{
- log().debug("{1}: <{2}>\n",i, ll[i]);
- log().debug("{1}: <{2}>\n",i, ll[i]);
device_t *nc = factory().new_device_by_name("LOG");
- pstring name = "log_" + ll[i];
+ pstring name = "log_" + ll;
register_dev(nc, name);
- register_link(name + ".I", ll[i]);
+ register_link(name + ".I", ll);
+ log().debug(" dynamic link {1}: <{2}>\n",ll, name);
}
}
@@ -957,13 +944,13 @@ void setup_t::model_parse(const pstring &model_in, model_map_t &map)
log().fatal("Model error {1}\n", model);
remainder = remainder.left(remainder.len() - 1);
- pstring_list_t pairs(remainder," ", true);
- for (unsigned i=0; i<pairs.size(); i++)
+ pstring_vector_t pairs(remainder," ", true);
+ for (pstring &pe : pairs)
{
- int pose = pairs[i].find("=");
+ int pose = pe.find("=");
if (pose < 0)
log().fatal("Model error on pair {1}\n", model);
- map[pairs[i].left(pose).ucase()] = pairs[i].substr(pose+1);
+ map[pe.left(pose).ucase()] = pe.substr(pose+1);
}
}
@@ -1012,9 +999,9 @@ nl_double setup_t::model_value(model_map_t &map, const pstring &entity)
void setup_t::include(const pstring &netlist_name)
{
- for (std::size_t i=0; i < m_sources.size(); i++)
+ for (source_t *source : m_sources)
{
- if (m_sources[i]->parse(*this, netlist_name))
+ if (source->parse(*this, netlist_name))
return;
}
log().fatal("unable to find {1} in source collection", netlist_name);
diff --git a/src/lib/netlist/nl_setup.h b/src/lib/netlist/nl_setup.h
index 4dd12b59854..7313ecabcad 100644
--- a/src/lib/netlist/nl_setup.h
+++ b/src/lib/netlist/nl_setup.h
@@ -91,7 +91,7 @@ namespace netlist
class source_t
{
public:
- typedef plist_t<source_t *> list_t;
+ typedef pvector_t<source_t *> list_t;
source_t()
{}
@@ -181,7 +181,7 @@ namespace netlist
/* register a source */
- void register_source(source_t *src) { m_sources.add(src); }
+ void register_source(source_t *src) { m_sources.push_back(src); }
factory_list_t &factory() { return *m_factory; }
const factory_list_t &factory() const { return *m_factory; }
@@ -224,17 +224,18 @@ namespace netlist
phashmap_t<pstring, pstring> m_params_temp;
phashmap_t<pstring, core_terminal_t *> m_terminals;
- plist_t<link_t> m_links;
+ pvector_t<link_t> m_links;
factory_list_t *m_factory;
phashmap_t<pstring, pstring> m_models;
int m_proxy_cnt;
+ int m_frontier_cnt;
- pstack_t<pstring> m_stack;
+ std::stack<pstring> m_stack;
source_t::list_t m_sources;
- plist_t<pstring> m_lib;
+ pvector_t<pstring> m_lib;
};
diff --git a/src/lib/netlist/plib/pconfig.h b/src/lib/netlist/plib/pconfig.h
index 6a96eca52d1..06019dc6d26 100644
--- a/src/lib/netlist/plib/pconfig.h
+++ b/src/lib/netlist/plib/pconfig.h
@@ -12,7 +12,7 @@
#define PSTANDALONE (0)
#endif
-//#define PHAS_INT128 (0)
+#define PHAS_INT128 (0)
#ifndef PHAS_INT128
#define PHAS_INT128 (0)
diff --git a/src/lib/netlist/plib/plists.h b/src/lib/netlist/plib/plists.h
index dd26cfb963b..d63d4fbe898 100644
--- a/src/lib/netlist/plib/plists.h
+++ b/src/lib/netlist/plib/plists.h
@@ -13,6 +13,8 @@
#include <cstring>
#include <algorithm>
#include <cmath>
+#include <stack>
+#include <vector>
#include "palloc.h"
#include "pstring.h"
@@ -55,15 +57,8 @@ public:
m_list = NULL;
}
- /* using the [] operator will not allow gcc to vectorize code because
- * basically a pointer is returned.
- * array works around this.
- */
-
- ATTR_HOT _ListClass *data() { return m_list; }
-
- ATTR_HOT _ListClass& operator[](std::size_t index) { return m_list[index]; }
- ATTR_HOT const _ListClass& operator[](std::size_t index) const { return m_list[index]; }
+ ATTR_HOT _ListClass& operator[](const std::size_t index) { return m_list[index]; }
+ ATTR_HOT const _ListClass& operator[](const std::size_t index) const { return m_list[index]; }
ATTR_HOT std::size_t size() const { return m_capacity; }
@@ -93,385 +88,78 @@ private:
// ----------------------------------------------------------------------------------------
// plist_t: a simple list
// ----------------------------------------------------------------------------------------
-#if 0
-#include <vector>
-//#define plist_t std::vector
-template <typename _ListClass>
-class plist_t : public std::vector<_ListClass>
-{
-public:
- plist_t() : std::vector<_ListClass>() {}
- plist_t(const int numElements) : std::vector<_ListClass>(numElements) {}
-
- void add(const _ListClass &elem) { this->push_back(elem); }
- void clear_and_free()
- {
- for (_ListClass *i = this->data(); i < this->data() + this->size(); i++)
- {
- pfree(*i);
- }
- this->clear();
- }
- bool contains(const _ListClass &elem) const
- {
- for (const _ListClass *i = this->data(); i < this->data() + this->size(); i++)
- {
- if (*i == elem)
- return true;
- }
- return false;
- }
- void remove(const _ListClass &elem)
- {
- for (int i = 0; i < this->size(); i++)
- {
- if (this->at(i) == elem)
- {
- this->erase(this->begin() + i);
- return;
- }
- }
- }
- void remove_at(const int pos)
- {
- this->erase(this->begin() + pos);
- }
-
- int indexof(const _ListClass &elem) const
- {
- for (int i = 0; i < this->size(); i++)
- {
- if (this->at(i) == elem)
- return i;
- }
- return -1;
- }
-
- ATTR_HOT void swap(const int pos1, const int pos2)
- {
- //nl_assert((pos1>=0) && (pos1<m_count));
- //nl_assert((pos2>=0) && (pos2<m_count));
- _ListClass tmp = (*this)[pos1];
- (*this)[pos1] = (*this)[pos2];
- (*this)[pos2] =tmp;
- }
-
-};
-
-#else
template <typename _ListClass>
-class plist_t
+class pvector_t : public std::vector<_ListClass>
{
public:
+ pvector_t() : std::vector<_ListClass>() {}
- ATTR_COLD plist_t(const std::size_t numElements = 0)
- {
- m_capacity = numElements;
- if (m_capacity == 0)
- m_list = NULL;
- else
- m_list = this->alloc(m_capacity);
- m_count = 0;
- }
-
- ATTR_COLD plist_t(const plist_t &rhs)
+ void clear_and_free()
{
- m_capacity = rhs.capacity();
- if (m_capacity == 0)
- m_list = NULL;
- else
- m_list = this->alloc(m_capacity);
- m_count = 0;
- for (std::size_t i=0; i<rhs.size(); i++)
+ for (_ListClass i : *this)
{
- this->add(rhs[i]);
+ pfree(i);
}
- }
-
- ATTR_COLD plist_t &operator=(const plist_t &rhs)
- {
this->clear();
- for (std::size_t i=0; i<rhs.size(); i++)
- {
- this->add(rhs[i]);
- }
- return *this;
}
-
- ~plist_t()
+ bool contains(const _ListClass &elem) const
{
- if (m_list != NULL)
- this->dealloc(m_list);
- m_list = NULL;
+ return (std::find(this->begin(), this->end(), elem) != this->end());
}
- ATTR_HOT _ListClass *data() { return m_list; }
-
- ATTR_HOT _ListClass& operator[](std::size_t index) { return *(m_list + index); }
- ATTR_HOT const _ListClass& operator[](std::size_t index) const { return *(m_list + index); }
-
- ATTR_HOT void add(const _ListClass &elem)
+ void remove(const _ListClass &elem)
{
- if (m_count >= m_capacity){
- std::size_t new_size = m_capacity * 2;
- if (new_size < 32)
- new_size = 32;
- set_capacity(new_size);
- }
-
- m_list[m_count++] = elem;
+ this->erase(std::remove(this->begin(), this->end(), elem), this->end());
}
- ATTR_HOT void insert_at(const _ListClass &elem, const std::size_t index)
+ ATTR_HOT void insert_at(const std::size_t index, const _ListClass &elem)
{
- if (m_count >= m_capacity){
- std::size_t new_size = m_capacity * 2;
- if (new_size < 32)
- new_size = 32;
- set_capacity(new_size);
- }
- for (std::size_t i = m_count; i>index; i--)
- m_list[i] = m_list[i-1];
- m_list[index] = elem;
- m_count++;
- }
-
- ATTR_HOT void remove(const _ListClass &elem)
- {
- for (std::size_t i = 0; i < m_count; i++)
- {
- if (m_list[i] == elem)
- {
- m_count --;
- while (i < m_count)
- {
- m_list[i] = m_list[i+1];
- i++;
- }
- return;
- }
- }
+ this->insert(this->begin() + index, elem);
}
ATTR_HOT void remove_at(const std::size_t pos)
{
- //nl_assert((pos>=0) && (pos<m_count));
- m_count--;
- for (std::size_t i = pos; i < m_count; i++)
- {
- m_list[i] = m_list[i+1];
- }
- }
-
- ATTR_HOT void swap(const std::size_t pos1, const std::size_t pos2)
- {
- //nl_assert((pos1>=0) && (pos1<m_count));
- //nl_assert((pos2>=0) && (pos2<m_count));
- _ListClass tmp = m_list[pos1];
- m_list[pos1] = m_list[pos2];
- m_list[pos2] =tmp;
- }
-
- ATTR_HOT bool contains(const _ListClass &elem) const
- {
- for (_ListClass *i = m_list; i < m_list + m_count; i++)
- {
- if (*i == elem)
- return true;
- }
- return false;
+ this->erase(this->begin() + pos);
}
- ATTR_HOT int indexof(const _ListClass &elem) const
+ int indexof(const _ListClass &elem) const
{
- for (std::size_t i = 0; i < m_count; i++)
+ for (int i = 0; i < this->size(); i++)
{
- if (m_list[i] == elem)
+ if (this->at(i) == elem)
return i;
}
return -1;
}
- ATTR_HOT std::size_t size() const { return m_count; }
- ATTR_HOT bool is_empty() const { return (m_count == 0); }
- ATTR_HOT void clear() { m_count = 0; }
- ATTR_HOT std::size_t capacity() const { return m_capacity; }
-
- ATTR_COLD void clear_and_free()
- {
- for (_ListClass *i = m_list; i < m_list + m_count; i++)
- {
- pfree(*i);
- }
- clear();
- }
-
-private:
- ATTR_COLD void set_capacity(const std::size_t new_capacity)
- {
- std::size_t cnt = size();
- if (new_capacity > 0)
- {
- _ListClass *m_new = this->alloc(new_capacity);
- _ListClass *pd = m_new;
-
- if (cnt > new_capacity)
- cnt = new_capacity;
- if (m_list != NULL)
- {
- for (_ListClass *ps = m_list; ps < m_list + cnt; ps++, pd++)
- *pd = *ps;
- this->dealloc(m_list);
- }
- m_list = m_new;
- m_count = cnt;
- }
- else
- {
- if (m_list != NULL)
- this->dealloc(m_list);
- m_list = NULL;
- m_count = 0;
- }
- m_capacity = new_capacity;
- }
-
- _ListClass *alloc(const std::size_t n)
- {
- return palloc_array(_ListClass, n);
- }
-
- void dealloc(_ListClass *p)
- {
- pfree_array(p);
- }
-
- std::size_t m_count;
- _ListClass * m_list;
- std::size_t m_capacity;
};
-#endif
// ----------------------------------------------------------------------------------------
-// pnamedlist_t: a simple list of elements which have a name() interface
+// plinkedlist_t: a simple linked list
+// the list allows insertions / deletions if used properly
// ----------------------------------------------------------------------------------------
template <class _ListClass>
-class pnamedlist_t : public plist_t<_ListClass>
-{
-public:
- _ListClass find_by_name(const pstring &name) const
- {
- for (std::size_t i=0; i < this->size(); i++)
- if (get_name((*this)[i]) == name)
- return (*this)[i];
- return _ListClass(NULL);
- }
-
- int index_by_name(const pstring &name) const
- {
- for (std::size_t i=0; i < this->size(); i++)
- if (get_name((*this)[i]) == name)
- return (int) i;
- return -1;
- }
-
- void remove_by_name(const pstring &name)
- {
- plist_t<_ListClass>::remove(find_by_name(name));
- }
+class plinkedlist_t;
- bool add(_ListClass dev, bool allow_duplicate)
- {
- if (allow_duplicate)
- plist_t<_ListClass>::add(dev);
- else
- {
- if (!(this->find_by_name(get_name(dev)) == _ListClass(NULL)))
- return false;
- plist_t<_ListClass>::add(dev);
- }
- return true;
- }
-
-private:
- template <typename T> const pstring &get_name(const T *elem) const { return elem->name(); }
- template <typename T> const pstring &get_name(T *elem) const { return elem->name(); }
- template <typename T> const pstring &get_name(const T &elem) const { return elem.name(); }
+#if 1
-};
-
-
-// ----------------------------------------------------------------------------------------
-// pstack_t: a simple stack
-// ----------------------------------------------------------------------------------------
-
-template <class _StackClass>
-class pstack_t
+template <class _ListClass>
+struct plinkedlist_element_t
{
public:
- ATTR_COLD pstack_t(const int numElements = 128)
- : m_list(numElements)
- {
- }
-
- ATTR_COLD pstack_t(const pstack_t &rhs)
- : m_list(rhs.m_list)
- {
- }
+ friend class plinkedlist_t<_ListClass>;
- ATTR_COLD pstack_t &operator=(const pstack_t &rhs)
- {
- m_list = rhs.m_list;
- return *this;
- }
-
-
- ~pstack_t()
- {
- }
-
- ATTR_HOT void push(const _StackClass &elem)
- {
- m_list.add(elem);
- }
-
- ATTR_HOT _StackClass peek() const
- {
- return m_list[m_list.size() - 1];
- }
-
- ATTR_HOT _StackClass pop()
- {
- _StackClass ret = peek();
- m_list.remove_at(m_list.size() - 1);
- return ret;
- }
-
- ATTR_HOT int count() const { return m_list.size(); }
- ATTR_HOT bool empty() const { return (m_list.size() == 0); }
- ATTR_HOT void reset() { m_list.reset(); }
- ATTR_HOT int capacity() const { return m_list.capacity(); }
+ plinkedlist_element_t() : m_next(NULL) {}
+ _ListClass *next() const { return m_next; }
private:
- plist_t<_StackClass> m_list;
-};
-
-template <class _ListClass>
-struct plinkedlist_element_t
-{
- plinkedlist_element_t() : m_next(NULL) {}
_ListClass * m_next;
-
};
-// ----------------------------------------------------------------------------------------
-// plinkedlist_t: a simple linked list
-// ----------------------------------------------------------------------------------------
-
template <class _ListClass>
class plinkedlist_t
{
@@ -499,7 +187,7 @@ public:
}
p = p->m_next;
}
- throw pexception("element not found");
+ //throw pexception("element not found");
}
}
@@ -522,18 +210,14 @@ public:
ATTR_HOT void remove(const _ListClass &elem)
{
- _ListClass **p = &m_head;
- while (*p != &elem)
+ _ListClass **p;
+ for (p = &m_head; *p != &elem; p = &((*p)->m_next))
{
//nl_assert(*p != NULL);
- p = &((*p)->m_next);
}
(*p) = elem.m_next;
}
-
- ATTR_HOT static _ListClass *next(const _ListClass &elem) { return elem.m_next; }
- ATTR_HOT static _ListClass *next(const _ListClass *elem) { return elem->m_next; }
ATTR_HOT _ListClass *first() const { return m_head; }
ATTR_HOT void clear() { m_head = NULL; }
ATTR_HOT bool is_empty() const { return (m_head == NULL); }
@@ -541,18 +225,99 @@ public:
private:
_ListClass *m_head;
};
+#else
+
+template <class _ListClass>
+struct plinkedlist_element_t
+{
+public:
+
+ friend class plinkedlist_t<_ListClass>;
+
+ plinkedlist_element_t() : m_next(NULL), m_prev(NULL) {}
+
+ _ListClass *next() const { return m_next; }
+private:
+ _ListClass * m_next;
+ _ListClass * m_prev;
+};
+
+template <class _ListClass>
+class plinkedlist_t
+{
+public:
+
+ plinkedlist_t() : m_head(NULL), m_tail(NULL) {}
+
+ ATTR_HOT void insert(_ListClass &elem)
+ {
+ if (m_head != NULL)
+ m_head->m_prev = &elem;
+ elem.m_next = m_head;
+ elem.m_prev = NULL;
+ m_head = &elem;
+ if (m_tail == NULL)
+ m_tail = &elem;
+ }
+
+ ATTR_HOT void add(_ListClass &elem)
+ {
+ if (m_tail != NULL)
+ m_tail->m_next = &elem;
+ elem.m_prev = m_tail;
+ m_tail = &elem;
+ elem.m_next = NULL;
+ if (m_head == NULL)
+ m_head = &elem;
+ }
+
+ ATTR_HOT void remove(const _ListClass &elem)
+ {
+ if (prev(elem) == NULL)
+ {
+ m_head = next(elem);
+ if (m_tail == &elem)
+ m_tail = NULL;
+ }
+ else
+ prev(elem)->m_next = next(elem);
+
+ if (next(elem) == NULL)
+ {
+ m_tail = prev(elem);
+ if (m_head == &elem)
+ m_head = NULL;
+ }
+ else
+ next(elem)->m_prev = prev(elem);
+ }
+
+
+ ATTR_HOT static _ListClass *next(const _ListClass &elem) { return static_cast<_ListClass *>(elem.m_next); }
+ ATTR_HOT static _ListClass *next(const _ListClass *elem) { return static_cast<_ListClass *>(elem->m_next); }
+ ATTR_HOT static _ListClass *prev(const _ListClass &elem) { return static_cast<_ListClass *>(elem.m_prev); }
+ ATTR_HOT static _ListClass *prev(const _ListClass *elem) { return static_cast<_ListClass *>(elem->m_prev); }
+ ATTR_HOT _ListClass *first() const { return m_head; }
+ ATTR_HOT void clear() { m_head = m_tail = NULL; }
+ ATTR_HOT bool is_empty() const { return (m_head == NULL); }
+
+private:
+ _ListClass *m_head;
+ _ListClass *m_tail;
+};
+#endif
// ----------------------------------------------------------------------------------------
// string list
// ----------------------------------------------------------------------------------------
-class pstring_list_t : public plist_t<pstring>
+class pstring_vector_t : public pvector_t<pstring>
{
public:
- pstring_list_t() : plist_t<pstring>() { }
+ pstring_vector_t() : pvector_t<pstring>() { }
- pstring_list_t(const pstring &str, const pstring &onstr, bool ignore_empty = false)
- : plist_t<pstring>()
+ pstring_vector_t(const pstring &str, const pstring &onstr, bool ignore_empty = false)
+ : pvector_t<pstring>()
{
int p = 0;
int pn;
@@ -562,7 +327,7 @@ public:
{
pstring t = str.substr(p, pn - p);
if (!ignore_empty || t.len() != 0)
- this->add(t);
+ this->push_back(t);
p = pn + onstr.len();
pn = str.find(onstr, p);
}
@@ -570,13 +335,13 @@ public:
{
pstring t = str.substr(p);
if (!ignore_empty || t.len() != 0)
- this->add(t);
+ this->push_back(t);
}
}
- static pstring_list_t splitexpr(const pstring &str, const pstring_list_t &onstrl)
+ pstring_vector_t(const pstring &str, const pstring_vector_t &onstrl)
+ : pvector_t<pstring>()
{
- pstring_list_t temp;
pstring col = "";
unsigned i = 0;
@@ -594,10 +359,10 @@ public:
if (p>=0)
{
if (col != "")
- temp.add(col);
+ this->push_back(col);
col = "";
- temp.add(onstrl[p]);
+ this->push_back(onstrl[p]);
i += onstrl[p].blen();
}
else
@@ -608,8 +373,7 @@ public:
}
}
if (col != "")
- temp.add(col);
- return temp;
+ this->push_back(col);
}
};
@@ -768,7 +532,7 @@ public:
if (m_hash[pos] == -1)
{
unsigned vpos = m_values.size();
- m_values.add(element_t(key, hash, value));
+ m_values.push_back(element_t(key, hash, value));
m_hash[pos] = vpos;
}
else
@@ -781,7 +545,7 @@ public:
return false; /* duplicate */
}
unsigned vpos = m_values.size();
- m_values.add(element_t(key, hash, value));
+ m_values.push_back(element_t(key, hash, value));
m_values[vpos].m_next = m_hash[pos];
m_hash[pos] = vpos;
}
@@ -828,7 +592,7 @@ private:
}
}
- plist_t<element_t> m_values;
+ pvector_t<element_t> m_values;
parray_t<int> m_hash;
};
diff --git a/src/lib/netlist/plib/poptions.h b/src/lib/netlist/plib/poptions.h
index c6daa3b2596..fe46a25f7a9 100644
--- a/src/lib/netlist/plib/poptions.h
+++ b/src/lib/netlist/plib/poptions.h
@@ -80,7 +80,7 @@ public:
pstring operator ()() { return m_val; }
private:
pstring m_val;
- pstring_list_t m_limit;
+ pstring_vector_t m_limit;
};
class poption_bool : public poption
@@ -127,7 +127,7 @@ public:
int i=0;
while (o[i] != NULL)
{
- m_opts.add(o[i]);
+ m_opts.push_back(o[i]);
i++;
}
}
@@ -139,7 +139,7 @@ public:
void register_option(poption *opt)
{
- m_opts.add(opt);
+ m_opts.push_back(opt);
}
int parse(int argc, char *argv[])
@@ -222,7 +222,7 @@ private:
return NULL;
}
- plist_t<poption *> m_opts;
+ pvector_t<poption *> m_opts;
pstring m_app;
};
diff --git a/src/lib/netlist/plib/pparser.cpp b/src/lib/netlist/plib/pparser.cpp
index 4b5d7995658..9362ba7de0d 100644
--- a/src/lib/netlist/plib/pparser.cpp
+++ b/src/lib/netlist/plib/pparser.cpp
@@ -255,16 +255,16 @@ ATTR_COLD void ptokenizer::error(const pstring &errs)
ppreprocessor::ppreprocessor()
: m_ifflag(0), m_level(0), m_lineno(0)
{
- m_expr_sep.add("!");
- m_expr_sep.add("(");
- m_expr_sep.add(")");
- m_expr_sep.add("+");
- m_expr_sep.add("-");
- m_expr_sep.add("*");
- m_expr_sep.add("/");
- m_expr_sep.add("==");
- m_expr_sep.add(" ");
- m_expr_sep.add("\t");
+ m_expr_sep.push_back("!");
+ m_expr_sep.push_back("(");
+ m_expr_sep.push_back(")");
+ m_expr_sep.push_back("+");
+ m_expr_sep.push_back("-");
+ m_expr_sep.push_back("*");
+ m_expr_sep.push_back("/");
+ m_expr_sep.push_back("==");
+ m_expr_sep.push_back(" ");
+ m_expr_sep.push_back("\t");
m_defines.add("__PLIB_PREPROCESSOR__", define_t("__PLIB_PREPROCESSOR__", "1"));
}
@@ -276,7 +276,7 @@ void ppreprocessor::error(const pstring &err)
-double ppreprocessor::expr(const pstring_list_t &sexpr, std::size_t &start, int prio)
+double ppreprocessor::expr(const pstring_vector_t &sexpr, std::size_t &start, int prio)
{
double val;
pstring tok=sexpr[start];
@@ -357,7 +357,7 @@ ppreprocessor::define_t *ppreprocessor::get_define(const pstring &name)
pstring ppreprocessor::replace_macros(const pstring &line)
{
- pstring_list_t elems = pstring_list_t::splitexpr(line, m_expr_sep);
+ pstring_vector_t elems(line, m_expr_sep);
pstringbuffer ret = "";
for (std::size_t i=0; i<elems.size(); i++)
{
@@ -370,7 +370,7 @@ pstring ppreprocessor::replace_macros(const pstring &line)
return ret;
}
-static pstring catremainder(const pstring_list_t &elems, std::size_t start, pstring sep)
+static pstring catremainder(const pstring_vector_t &elems, std::size_t start, pstring sep)
{
pstringbuffer ret = "";
for (std::size_t i=start; i<elems.size(); i++)
@@ -389,13 +389,13 @@ pstring ppreprocessor::process_line(const pstring &line)
// FIXME ... revise and extend macro handling
if (lt.startsWith("#"))
{
- pstring_list_t lti(lt, " ", true);
+ pstring_vector_t lti(lt, " ", true);
if (lti[0].equals("#if"))
{
m_level++;
std::size_t start = 0;
lt = replace_macros(lt);
- pstring_list_t t = pstring_list_t::splitexpr(lt.substr(3).replace(" ",""), m_expr_sep);
+ pstring_vector_t t(lt.substr(3).replace(" ",""), m_expr_sep);
int val = expr(t, start, 0);
if (val == 0)
m_ifflag |= (1 << m_level);
diff --git a/src/lib/netlist/plib/pparser.h b/src/lib/netlist/plib/pparser.h
index 08294677328..cf122fec7f8 100644
--- a/src/lib/netlist/plib/pparser.h
+++ b/src/lib/netlist/plib/pparser.h
@@ -96,7 +96,7 @@ public:
token_id_t register_token(pstring token)
{
- m_tokens.add(token);
+ m_tokens.push_back(token);
return token_id_t(m_tokens.size() - 1);
}
@@ -136,7 +136,7 @@ private:
pstring m_identifier_chars;
pstring m_number_chars;
pstring m_number_chars_start;
- plist_t<pstring> m_tokens;
+ pvector_t<pstring> m_tokens;
pstring m_whitespace;
pstring::code_t m_string;
@@ -174,7 +174,7 @@ protected:
postream &process_i(pistream &istrm, postream &ostrm);
- double expr(const pstring_list_t &sexpr, std::size_t &start, int prio);
+ double expr(const pstring_vector_t &sexpr, std::size_t &start, int prio);
define_t *get_define(const pstring &name);
@@ -187,7 +187,7 @@ private:
pstring process_line(const pstring &line);
phashmap_t<pstring, define_t> m_defines;
- pstring_list_t m_expr_sep;
+ pstring_vector_t m_expr_sep;
//pstringbuffer m_ret;
UINT32 m_ifflag; // 31 if levels
diff --git a/src/lib/netlist/plib/pstate.cpp b/src/lib/netlist/plib/pstate.cpp
index cf2c863ed11..d6ff433e388 100644
--- a/src/lib/netlist/plib/pstate.cpp
+++ b/src/lib/netlist/plib/pstate.cpp
@@ -37,7 +37,7 @@ ATTR_COLD void pstate_manager_t::save_state_ptr(const pstring &stname, const pst
};
pstate_entry_t *p = palloc(pstate_entry_t(stname, dt, owner, size, count, ptr, is_ptr));
- m_save.add(p);
+ m_save.push_back(p);
}
ATTR_COLD void pstate_manager_t::remove_save_items(const void *owner)
@@ -47,7 +47,7 @@ ATTR_COLD void pstate_manager_t::remove_save_items(const void *owner)
for (std::size_t i=0; i < m_save.size(); i++)
{
if (m_save[i]->m_owner == owner)
- todelete.add(m_save[i]);
+ todelete.push_back(m_save[i]);
}
for (std::size_t i=0; i < todelete.size(); i++)
{
@@ -75,6 +75,6 @@ template<> ATTR_COLD void pstate_manager_t::save_item(pstate_callback_t &state,
//save_state_ptr(stname, DT_CUSTOM, 0, 1, &state);
pstate_callback_t *state_p = &state;
pstate_entry_t *p = palloc(pstate_entry_t(stname, owner, state_p));
- m_save.add(p);
+ m_save.push_back(p);
state.register_state(*this, stname);
}
diff --git a/src/lib/netlist/plib/pstate.h b/src/lib/netlist/plib/pstate.h
index b42d3dac882..91c67ee0e1c 100644
--- a/src/lib/netlist/plib/pstate.h
+++ b/src/lib/netlist/plib/pstate.h
@@ -84,7 +84,7 @@ class pstate_manager_t;
class pstate_callback_t
{
public:
- typedef plist_t<pstate_callback_t *> list_t;
+ typedef pvector_t<pstate_callback_t *> list_t;
virtual ~pstate_callback_t() { };
@@ -96,7 +96,7 @@ protected:
struct pstate_entry_t
{
- typedef plist_t<pstate_entry_t *> list_t;
+ typedef pvector_t<pstate_entry_t *> list_t;
pstate_entry_t(const pstring &stname, const pstate_data_type_e dt, const void *owner,
const int size, const int count, void *ptr, bool is_ptr)
diff --git a/src/lib/netlist/plib/pstream.cpp b/src/lib/netlist/plib/pstream.cpp
index ba7c5c7eda2..9702ab5dab5 100644
--- a/src/lib/netlist/plib/pstream.cpp
+++ b/src/lib/netlist/plib/pstream.cpp
@@ -101,7 +101,7 @@ void pifilestream::close()
}
}
-unsigned pifilestream::vread(void *buf, unsigned n)
+unsigned pifilestream::vread(void *buf, const unsigned n)
{
std::size_t r = fread(buf, 1, n, (FILE *) m_file);
if (r < n)
@@ -115,7 +115,7 @@ unsigned pifilestream::vread(void *buf, unsigned n)
return r;
}
-void pifilestream::vseek(pos_type n)
+void pifilestream::vseek(const pos_type n)
{
check_seekable();
if (fseek((FILE *) m_file, SEEK_SET, n) < 0)
@@ -200,7 +200,7 @@ void pofilestream::close()
}
}
-void pofilestream::vwrite(const void *buf, unsigned n)
+void pofilestream::vwrite(const void *buf, const unsigned n)
{
std::size_t r = fwrite(buf, 1, n, (FILE *) m_file);
if (r < n)
@@ -211,7 +211,7 @@ void pofilestream::vwrite(const void *buf, unsigned n)
m_pos += r;
}
-void pofilestream::vseek(pos_type n)
+void pofilestream::vseek(const pos_type n)
{
check_seekable();
if (fseek((FILE *) m_file, SEEK_SET, n) < 0)
@@ -271,7 +271,7 @@ pimemstream::~pimemstream()
{
}
-unsigned pimemstream::vread(void *buf, unsigned n)
+unsigned pimemstream::vread(void *buf, const unsigned n)
{
unsigned ret = (m_pos + n <= m_len) ? n : m_len - m_pos;
@@ -287,7 +287,7 @@ unsigned pimemstream::vread(void *buf, unsigned n)
return ret;
}
-void pimemstream::vseek(pos_type n)
+void pimemstream::vseek(const pos_type n)
{
m_pos = (n>=m_len) ? m_len : n;
clear_flag(FLAG_EOF);
@@ -314,7 +314,7 @@ pomemstream::~pomemstream()
pfree_array(m_mem);
}
-void pomemstream::vwrite(const void *buf, unsigned n)
+void pomemstream::vwrite(const void *buf, const unsigned n)
{
if (m_pos + n >= m_capacity)
{
@@ -336,7 +336,7 @@ void pomemstream::vwrite(const void *buf, unsigned n)
m_size = std::max(m_pos, m_size);
}
-void pomemstream::vseek(pos_type n)
+void pomemstream::vseek(const pos_type n)
{
m_pos = n;
m_size = std::max(m_pos, m_size);
diff --git a/src/lib/netlist/plib/pstring.cpp b/src/lib/netlist/plib/pstring.cpp
index 8ad86f41f3d..2acf1d789b1 100644
--- a/src/lib/netlist/plib/pstring.cpp
+++ b/src/lib/netlist/plib/pstring.cpp
@@ -314,7 +314,7 @@ long pstring_t<F>::as_long(bool *error) const
#if 1
-static pstack_t<pstr_t *> *stk = NULL;
+static std::stack<pstr_t *> *stk = NULL;
static inline unsigned countleadbits(unsigned x)
{
@@ -373,7 +373,7 @@ template<typename F>
pstr_t *pstring_t<F>::salloc(int n)
{
if (stk == NULL)
- stk = palloc_array(pstack_t<pstr_t *>, 17);
+ stk = palloc_array(std::stack<pstr_t *>, 17);
pstr_t *p;
unsigned sn= ((32 - countleadbits(n)) + 1) / 2;
unsigned size = sizeof(pstr_t) + ((UINT64) 1<<(sn * 2)) + 1;
@@ -381,7 +381,8 @@ pstr_t *pstring_t<F>::salloc(int n)
p = (pstr_t *) palloc_array(char, size);
else
{
- p = stk[sn].pop();
+ p = stk[sn].top();
+ stk[sn].pop();
}
// str_t *p = (str_t *) _mm_malloc(size, 8);
@@ -395,8 +396,11 @@ void pstring_t<F>::resetmem()
{
for (unsigned i=0; i<=16; i++)
{
- for (; stk[i].count() > 0; )
- pfree_array(stk[i].pop());
+ for (; stk[i].size() > 0; )
+ {
+ pfree_array(stk[i].top());
+ stk[i].pop();
+ }
}
pfree_array(stk);
stk = NULL;
diff --git a/src/lib/netlist/prg/nltool.cpp b/src/lib/netlist/prg/nltool.cpp
index 3c7065897e7..ea5211a3c87 100644
--- a/src/lib/netlist/prg/nltool.cpp
+++ b/src/lib/netlist/prg/nltool.cpp
@@ -181,7 +181,7 @@ public:
void log_setup()
{
log().debug("Creating dynamic logs ...\n");
- pstring_list_t ll(m_opts ? m_opts->opt_logs() : "" , ":");
+ pstring_vector_t ll(m_opts ? m_opts->opt_logs() : "" , ":");
for (unsigned i=0; i < ll.size(); i++)
{
pstring name = "log_" + ll[i];
@@ -260,9 +260,9 @@ struct input_t
};
-plist_t<input_t> *read_input(netlist::netlist_t *netlist, pstring fname)
+pvector_t<input_t> *read_input(netlist::netlist_t *netlist, pstring fname)
{
- plist_t<input_t> *ret = palloc(plist_t<input_t>());
+ pvector_t<input_t> *ret = palloc(pvector_t<input_t>());
if (fname != "")
{
pifilestream f(fname);
@@ -272,7 +272,7 @@ plist_t<input_t> *read_input(netlist::netlist_t *netlist, pstring fname)
if (l != "")
{
input_t inp(netlist, l);
- ret->add(inp);
+ ret->push_back(inp);
}
}
}
@@ -294,7 +294,7 @@ static void run(tool_options_t &opts)
nt.read_netlist(opts.opt_file(), opts.opt_name());
- plist_t<input_t> *inps = read_input(&nt, opts.opt_inp());
+ pvector_t<input_t> *inps = read_input(&nt, opts.opt_inp());
double ttr = opts.opt_ttr();
diff --git a/src/lib/netlist/solver/nld_ms_direct.h b/src/lib/netlist/solver/nld_ms_direct.h
index 8bb578ec6cd..ecc3cb19c3d 100644
--- a/src/lib/netlist/solver/nld_ms_direct.h
+++ b/src/lib/netlist/solver/nld_ms_direct.h
@@ -206,8 +206,8 @@ ATTR_COLD void matrix_solver_direct_t<m_N, _storage_N>::vsetup(analog_net_t::lis
{
if ((m_terms[i]->m_railstart - m_terms[i+1]->m_railstart) * sort_order < 0)
{
- std::swap(m_terms[i],m_terms[i+1]);
- m_nets.swap(i, i+1);
+ std::swap(m_terms[i], m_terms[i+1]);
+ std::swap(m_nets[i], m_nets[i+1]);
}
}
@@ -253,14 +253,14 @@ ATTR_COLD void matrix_solver_direct_t<m_N, _storage_N>::vsetup(analog_net_t::lis
for (unsigned i = 0; i < t->m_railstart; i++)
{
if (!t->m_nzrd.contains(other[i]) && other[i] >= (int) (k + 1))
- t->m_nzrd.add(other[i]);
+ t->m_nzrd.push_back(other[i]);
if (!t->m_nz.contains(other[i]))
- t->m_nz.add(other[i]);
+ t->m_nz.push_back(other[i]);
}
}
psort_list(t->m_nzrd);
- t->m_nz.add(k); // add diagonal
+ t->m_nz.push_back(k); // add diagonal
psort_list(t->m_nz);
}
@@ -283,7 +283,7 @@ ATTR_COLD void matrix_solver_direct_t<m_N, _storage_N>::vsetup(analog_net_t::lis
if (touched[row][k])
{
if (!m_terms[k]->m_nzbd.contains(row))
- m_terms[k]->m_nzbd.add(row);
+ m_terms[k]->m_nzbd.push_back(row);
for (unsigned col = k; col < N(); col++)
if (touched[k][col])
touched[row][col] = true;
diff --git a/src/lib/netlist/solver/nld_ms_direct_lu.h b/src/lib/netlist/solver/nld_ms_direct_lu.h
index 877e0b56cd8..5af166cfb84 100644
--- a/src/lib/netlist/solver/nld_ms_direct_lu.h
+++ b/src/lib/netlist/solver/nld_ms_direct_lu.h
@@ -287,7 +287,7 @@ ATTR_COLD void matrix_solver_direct_t<m_N, _storage_N>::vsetup(analog_net_t::lis
if ((m_terms[i]->m_railstart - m_terms[i+1]->m_railstart) * sort_order < 0)
{
std::swap(m_terms[i],m_terms[i+1]);
- m_nets.swap(i, i+1);
+ std::swap(m_nets[i], m_nets[i+1]);
}
}
diff --git a/src/lib/netlist/solver/nld_ms_gmres.h b/src/lib/netlist/solver/nld_ms_gmres.h
index 6124f7e527d..0ae7f5eab56 100644
--- a/src/lib/netlist/solver/nld_ms_gmres.h
+++ b/src/lib/netlist/solver/nld_ms_gmres.h
@@ -62,7 +62,7 @@ private:
int solve_ilu_gmres(nl_double * RESTRICT x, nl_double * RESTRICT rhs, const unsigned restart_max, const unsigned mr, nl_double accuracy);
- plist_t<int> m_term_cr[_storage_N];
+ pvector_t<int> m_term_cr[_storage_N];
bool m_use_iLU_preconditioning;
bool m_use_more_precise_stop_condition;
@@ -114,7 +114,7 @@ void matrix_solver_GMRES_t<m_N, _storage_N>::vsetup(analog_net_t::list_t &nets)
for (unsigned i = mat.ia[k]; i<nz; i++)
if (this->m_terms[k]->net_other()[j] == (int) mat.ja[i])
{
- m_term_cr[k].add(i);
+ m_term_cr[k].push_back(i);
break;
}
nl_assert(m_term_cr[k].size() == this->m_terms[k]->m_railstart);
diff --git a/src/lib/netlist/solver/nld_solver.cpp b/src/lib/netlist/solver/nld_solver.cpp
index b862e031f3d..761e665f68b 100644
--- a/src/lib/netlist/solver/nld_solver.cpp
+++ b/src/lib/netlist/solver/nld_solver.cpp
@@ -11,6 +11,7 @@
#if 0
#pragma GCC optimize "-ffast-math"
+#pragma GCC optimize "-fstrict-aliasing"
//#pragma GCC optimize "-ftree-parallelize-loops=4"
#pragma GCC optimize "-funroll-loops"
#pragma GCC optimize "-funswitch-loops"
@@ -54,21 +55,21 @@ ATTR_COLD void terms_t::add(terminal_t *term, int net_other, bool sorted)
{
if (m_net_other[i] > net_other)
{
- m_term.insert_at(term, i);
- m_net_other.insert_at(net_other, i);
- m_gt.insert_at(0.0, i);
- m_go.insert_at(0.0, i);
- m_Idr.insert_at(0.0, i);
- m_other_curanalog.insert_at(NULL, i);
+ m_term.insert_at(i, term);
+ m_net_other.insert_at(i, net_other);
+ m_gt.insert_at(i, 0.0);
+ m_go.insert_at(i, 0.0);
+ m_Idr.insert_at(i, 0.0);
+ m_other_curanalog.insert_at(i, NULL);
return;
}
}
- m_term.add(term);
- m_net_other.add(net_other);
- m_gt.add(0.0);
- m_go.add(0.0);
- m_Idr.add(0.0);
- m_other_curanalog.add(NULL);
+ 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(NULL);
}
ATTR_COLD void terms_t::set_pointers()
@@ -109,10 +110,8 @@ ATTR_COLD void matrix_solver_t::setup(analog_net_t::list_t &nets)
m_nets.clear();
- for (std::size_t k = 0; k < nets.size(); k++)
- {
- m_nets.add(nets[k]);
- }
+ for (auto & net : nets)
+ m_nets.push_back(net);
for (std::size_t k = 0; k < nets.size(); k++)
{
@@ -122,9 +121,8 @@ ATTR_COLD void matrix_solver_t::setup(analog_net_t::list_t &nets)
net->m_solver = this;
- for (std::size_t i = 0; i < net->m_core_terms.size(); i++)
+ for (core_terminal_t *p : net->m_core_terms)
{
- core_terminal_t *p = net->m_core_terms[i];
log().debug("{1} {2} {3}\n", p->name(), net->name(), (int) net->isRailNet());
switch (p->type())
{
@@ -133,7 +131,7 @@ ATTR_COLD void matrix_solver_t::setup(analog_net_t::list_t &nets)
{
case device_t::CAPACITOR:
if (!m_step_devices.contains(&p->device()))
- m_step_devices.add(&p->device());
+ m_step_devices.push_back(&p->device());
break;
case device_t::BJT_EB:
case device_t::DIODE:
@@ -141,7 +139,7 @@ ATTR_COLD void matrix_solver_t::setup(analog_net_t::list_t &nets)
case device_t::BJT_SWITCH:
log().debug("found BJT/Diode/LVCCS\n");
if (!m_dynamic_devices.contains(&p->device()))
- m_dynamic_devices.add(&p->device());
+ m_dynamic_devices.push_back(&p->device());
break;
default:
break;
@@ -155,10 +153,10 @@ ATTR_COLD void matrix_solver_t::setup(analog_net_t::list_t &nets)
case terminal_t::INPUT:
{
analog_output_t *net_proxy_output = NULL;
- for (std::size_t j = 0; j < m_inps.size(); j++)
- if (m_inps[j]->m_proxied_net == &p->net().as_analog())
+ for (auto & input : m_inps)
+ if (input->m_proxied_net == &p->net().as_analog())
{
- net_proxy_output = m_inps[j];
+ net_proxy_output = input;
break;
}
@@ -166,7 +164,7 @@ ATTR_COLD void matrix_solver_t::setup(analog_net_t::list_t &nets)
{
net_proxy_output = palloc(analog_output_t);
net_proxy_output->init_object(*this, this->name() + "." + pfmt("m{1}")(m_inps.size()));
- m_inps.add(net_proxy_output);
+ m_inps.push_back(net_proxy_output);
net_proxy_output->m_proxied_net = &p->net().as_analog();
}
net_proxy_output->net().register_con(*p);
@@ -399,9 +397,9 @@ NETLIB_UPDATE(solver)
if (m_params.m_dynamic)
return;
- const std::size_t t_cnt = m_mat_solvers.size();
#if HAS_OPENMP && USE_OPENMP
+ const std::size_t t_cnt = m_mat_solvers.size();
if (m_parallel.Value())
{
omp_set_num_threads(3);
@@ -425,14 +423,10 @@ NETLIB_UPDATE(solver)
ATTR_UNUSED const nl_double ts = m_mat_solvers[i]->solve();
}
#else
- for (std::size_t i = 0; i < t_cnt; i++)
- {
- if (m_mat_solvers[i]->is_timestep())
- {
+ for (auto & solver : m_mat_solvers)
+ if (solver->is_timestep())
// Ignore return value
- ATTR_UNUSED const nl_double ts = m_mat_solvers[i]->solve();
- }
- }
+ ATTR_UNUSED const nl_double ts = solver->solve();
#endif
/* step circuit */
@@ -518,13 +512,13 @@ ATTR_COLD void NETLIB_NAME(solver)::post_start()
netlist().log().verbose("Scanning net groups ...");
// determine net groups
- for (std::size_t i=0; i<netlist().m_nets.size(); i++)
+ for (auto & net : netlist().m_nets)
{
- netlist().log().debug("processing {1}\n", netlist().m_nets[i]->name());
- if (!netlist().m_nets[i]->isRailNet())
+ netlist().log().debug("processing {1}\n", net->name());
+ if (!net->isRailNet())
{
netlist().log().debug(" ==> not a rail net\n");
- analog_net_t *n = &netlist().m_nets[i]->as_analog();
+ analog_net_t *n = &net->as_analog();
if (!n->already_processed(groups, cur_group))
{
cur_group++;
@@ -621,7 +615,7 @@ ATTR_COLD void NETLIB_NAME(solver)::post_start()
ms->vsetup(groups[i]);
- m_mat_solvers.add(ms);
+ m_mat_solvers.push_back(ms);
netlist().log().verbose("Solver {1}", ms->name());
netlist().log().verbose(" # {1} ==> {2} nets", i, groups[i].size());
diff --git a/src/lib/netlist/solver/nld_solver.h b/src/lib/netlist/solver/nld_solver.h
index 2de12bb77f1..06a98d063c6 100644
--- a/src/lib/netlist/solver/nld_solver.h
+++ b/src/lib/netlist/solver/nld_solver.h
@@ -81,22 +81,22 @@ class terms_t
unsigned m_railstart;
- plist_t<unsigned> m_nz; /* all non zero for multiplication */
- plist_t<unsigned> m_nzrd; /* non zero right of the diagonal for elimination */
- plist_t<unsigned> m_nzbd; /* non zero below of the diagonal for elimination */
+ pvector_t<unsigned> m_nz; /* all non zero for multiplication */
+ pvector_t<unsigned> m_nzrd; /* non zero right of the diagonal for elimination */
+ pvector_t<unsigned> m_nzbd; /* non zero below of the diagonal for elimination */
private:
- plist_t<terminal_t *> m_term;
- plist_t<int> m_net_other;
- plist_t<nl_double> m_go;
- plist_t<nl_double> m_gt;
- plist_t<nl_double> m_Idr;
- plist_t<nl_double *> m_other_curanalog;
+ pvector_t<terminal_t *> m_term;
+ pvector_t<int> m_net_other;
+ pvector_t<nl_double> m_go;
+ pvector_t<nl_double> m_gt;
+ pvector_t<nl_double> m_Idr;
+ pvector_t<nl_double *> m_other_curanalog;
};
class matrix_solver_t : public device_t
{
public:
- typedef plist_t<matrix_solver_t *> list_t;
+ typedef pvector_t<matrix_solver_t *> list_t;
typedef core_device_t::list_t dev_list_t;
enum eSolverType
@@ -146,8 +146,8 @@ protected:
virtual void add_term(int net_idx, terminal_t *term) = 0;
- plist_t<analog_net_t *> m_nets;
- plist_t<analog_output_t *> m_inps;
+ pvector_t<analog_net_t *> m_nets;
+ pvector_t<analog_output_t *> m_inps;
int m_stat_calculations;
int m_stat_newton_raphson;
diff --git a/src/lib/netlist/tools/nl_convert.cpp b/src/lib/netlist/tools/nl_convert.cpp
index 8157bfffdcd..099f913b307 100644
--- a/src/lib/netlist/tools/nl_convert.cpp
+++ b/src/lib/netlist/tools/nl_convert.cpp
@@ -12,11 +12,11 @@
template<typename Class>
-static plist_t<int> bubble(const pnamedlist_t<Class *> &sl)
+static pvector_t<int> bubble(const pvector_t<Class *> &sl)
{
- plist_t<int> ret(sl.size());
+ pvector_t<int> ret;
for (unsigned i=0; i<sl.size(); i++)
- ret[i] = i;
+ ret.push_back(i);
for(unsigned i=0; i < sl.size(); i++)
{
@@ -37,57 +37,71 @@ static plist_t<int> bubble(const pnamedlist_t<Class *> &sl)
void nl_convert_base_t::add_pin_alias(const pstring &devname, const pstring &name, const pstring &alias)
{
- m_pins.add(palloc(pin_alias_t(devname + "." + name, devname + "." + alias)), false);
+ pstring pname = devname + "." + name;
+ m_pins.add(pname, palloc(pin_alias_t(pname, devname + "." + alias)));
}
void nl_convert_base_t::add_ext_alias(const pstring &alias)
{
- m_ext_alias.add(alias);
+ m_ext_alias.push_back(alias);
+}
+
+void nl_convert_base_t::add_device(dev_t *dev)
+{
+ for (auto & d : m_devs)
+ if (d->name() == dev->name())
+ {
+ out("ERROR: Duplicate device {1} ignored.", dev->name());
+ return;
+ }
+ m_devs.push_back(dev);
}
void nl_convert_base_t::add_device(const pstring &atype, const pstring &aname, const pstring &amodel)
{
- m_devs.add(palloc(dev_t(atype, aname, amodel)), false);
+ add_device(palloc(dev_t(atype, aname, amodel)));
}
void nl_convert_base_t::add_device(const pstring &atype, const pstring &aname, double aval)
{
- m_devs.add(palloc(dev_t(atype, aname, aval)), false);
+ add_device(palloc(dev_t(atype, aname, aval)));
}
void nl_convert_base_t::add_device(const pstring &atype, const pstring &aname)
{
- m_devs.add(palloc(dev_t(atype, aname)), false);
+ add_device(palloc(dev_t(atype, aname)));
}
void nl_convert_base_t::add_term(pstring netname, pstring termname)
{
- net_t * net = m_nets.find_by_name(netname);
- if (net == NULL)
+ net_t * net = NULL;
+ if (m_nets.contains(netname))
+ net = m_nets[netname];
+ else
{
net = palloc(net_t(netname));
- m_nets.add(net, false);
+ m_nets.add(netname, net);
}
/* if there is a pin alias, translate ... */
- pin_alias_t *alias = m_pins.find_by_name(termname);
+ pin_alias_t *alias = m_pins[termname];
if (alias != NULL)
- net->terminals().add(alias->alias());
+ net->terminals().push_back(alias->alias());
else
- net->terminals().add(termname);
+ net->terminals().push_back(termname);
}
void nl_convert_base_t::dump_nl()
{
for (std::size_t i=0; i<m_ext_alias.size(); i++)
{
- net_t *net = m_nets.find_by_name(m_ext_alias[i]);
+ net_t *net = m_nets[m_ext_alias[i]];
// use the first terminal ...
out("ALIAS({}, {})\n", m_ext_alias[i].cstr(), net->terminals()[0].cstr());
// if the aliased net only has this one terminal connected ==> don't dump
if (net->terminals().size() == 1)
net->set_no_export();
}
- plist_t<int> sorted = bubble(m_devs);
+ pvector_t<int> sorted = bubble(m_devs);
for (std::size_t i=0; i<m_devs.size(); i++)
{
std::size_t j = sorted[i];
@@ -105,7 +119,7 @@ void nl_convert_base_t::dump_nl()
// print nets
for (std::size_t i=0; i<m_nets.size(); i++)
{
- net_t * net = m_nets[i];
+ net_t * net = m_nets.value_at(i);
if (!net->is_no_export())
{
//printf("Net {}\n", net->name().cstr());
@@ -118,8 +132,12 @@ void nl_convert_base_t::dump_nl()
}
}
m_devs.clear_and_free();
- m_nets.clear_and_free();
- m_pins.clear_and_free();
+ for (std::size_t i = 0; i < m_nets.size(); i++)
+ pfree(m_nets.value_at(i));
+ m_nets.clear();
+ for (std::size_t i = 0; i < m_pins.size(); i++)
+ pfree(m_pins.value_at(i));
+ m_pins.clear();
m_ext_alias.clear();
}
@@ -184,7 +202,7 @@ nl_convert_base_t::unit_t nl_convert_base_t::m_units[] = {
void nl_convert_spice_t::convert(const pstring &contents)
{
- pstring_list_t spnl(contents, "\n");
+ pstring_vector_t spnl(contents, "\n");
// Add gnd net
@@ -216,7 +234,7 @@ void nl_convert_spice_t::process_line(const pstring &line)
{
if (line != "")
{
- pstring_list_t tt(line, " ", true);
+ pstring_vector_t tt(line, " ", true);
double val = 0.0;
switch (tt[0].code_at(0))
{
@@ -255,7 +273,7 @@ void nl_convert_spice_t::process_line(const pstring &line)
model = tt[5];
else
model = tt[4];
- pstring_list_t m(model,"{");
+ pstring_vector_t m(model,"{");
if (m.size() == 2)
{
if (m[1].len() != 4)
diff --git a/src/lib/netlist/tools/nl_convert.h b/src/lib/netlist/tools/nl_convert.h
index 3b86c5ec1ad..1e51ed3509c 100644
--- a/src/lib/netlist/tools/nl_convert.h
+++ b/src/lib/netlist/tools/nl_convert.h
@@ -25,9 +25,13 @@ public:
nl_convert_base_t() : out(m_buf) {};
virtual ~nl_convert_base_t()
{
- m_nets.clear_and_free();
+ for (std::size_t i = 0; i < m_nets.size(); i++)
+ pfree(m_nets.value_at(i));
+ m_nets.clear();
m_devs.clear_and_free();
- m_pins.clear_and_free();
+ for (std::size_t i = 0; i < m_pins.size(); i++)
+ pfree(m_pins.value_at(i));
+ m_pins.clear();
}
const pstringbuffer &result() { return m_buf.str(); }
@@ -55,6 +59,7 @@ protected:
pstream_fmt_writer_t out;
private:
+
struct net_t
{
public:
@@ -62,14 +67,14 @@ private:
: m_name(aname), m_no_export(false) {}
const pstring &name() { return m_name;}
- pstring_list_t &terminals() { return m_terminals; }
+ pstring_vector_t &terminals() { return m_terminals; }
void set_no_export() { m_no_export = true; }
bool is_no_export() { return m_no_export; }
private:
pstring m_name;
bool m_no_export;
- pstring_list_t m_terminals;
+ pstring_vector_t m_terminals;
};
struct dev_t
@@ -124,12 +129,14 @@ private:
private:
+ void add_device(dev_t *dev);
+
postringstream m_buf;
- pnamedlist_t<dev_t *> m_devs;
- pnamedlist_t<net_t *> m_nets;
- plist_t<pstring> m_ext_alias;
- pnamedlist_t<pin_alias_t *> m_pins;
+ pvector_t<dev_t *> m_devs;
+ phashmap_t<pstring, net_t *> m_nets;
+ pvector_t<pstring> m_ext_alias;
+ phashmap_t<pstring, pin_alias_t *> m_pins;
static unit_t m_units[];
diff --git a/src/lib/util/aviio.cpp b/src/lib/util/aviio.cpp
index a448128070b..339a4de3231 100644
--- a/src/lib/util/aviio.cpp
+++ b/src/lib/util/aviio.cpp
@@ -1,5 +1,5 @@
// license:BSD-3-Clause
-// copyright-holders:Aaron Giles
+// copyright-holders:Aaron Giles, Vas Crabb
/***************************************************************************
aviio.c
@@ -8,8 +8,10 @@
***************************************************************************/
-#include <stdlib.h>
-#include <assert.h>
+#include <array>
+#include <cassert>
+#include <cstdlib>
+#include <cstring>
#include "aviio.h"
@@ -45,7 +47,7 @@
* @brief A macro that defines four gigabytes.
*/
-#define FOUR_GB ((UINT64)1 << 32)
+#define FOUR_GB (std::uint64_t(1) << 32)
/**
* @def MAX_SOUND_CHANNELS
@@ -222,7 +224,7 @@
#define HUFFYUV_PREDICT_DECORR 0x40
-
+namespace {
/***************************************************************************
TYPE DEFINITIONS
***************************************************************************/
@@ -235,14 +237,12 @@
struct avi_chunk
{
- /** @brief The offset. */
- UINT64 offset; /* file offset of chunk header */
- /** @brief The size. */
- UINT64 size; /* size of this chunk */
- /** @brief The type. */
- UINT32 type; /* type of this chunk */
- /** @brief The listtype. */
- UINT32 listtype; /* type of this list (if we are a list) */
+ avi_chunk() : offset(0), size(0), type(0), listtype(0) { }
+
+ std::uint64_t offset; /* file offset of chunk header */
+ std::uint64_t size; /* size of this chunk */
+ std::uint32_t type; /* type of this chunk */
+ std::uint32_t listtype; /* type of this list (if we are a list) */
};
/**
@@ -253,211 +253,297 @@ struct avi_chunk
struct avi_chunk_list
{
- /** @brief The offset. */
- UINT64 offset; /* offset in the file of header */
- /** @brief The length. */
- UINT32 length; /* length of the chunk including header */
+ std::uint64_t offset; /* offset in the file of header */
+ std::uint32_t length; /* length of the chunk including header */
};
/**
- * @struct huffyuv_table
+ * @struct avi_stream
*
- * @brief A huffyuv table.
+ * @brief An avi stream.
*/
-struct huffyuv_table
-{
- /** @brief The shift[ 256]. */
- UINT8 shift[256]; /* bit shift amounts */
- /** @brief The bits[ 256]. */
- UINT32 bits[256]; /* bit match values */
- /** @brief The mask[ 256]. */
- UINT32 mask[256]; /* bit mask values */
- /** @brief The baselookup[ 65536]. */
- UINT16 baselookup[65536]; /* base lookup table */
- /** @brief The extralookup. */
- UINT16 * extralookup; /* extra lookup tables */
-};
+class avi_stream
+{
+public:
+ avi_stream()
+ : m_type(0)
+ , m_format(0)
+ , m_rate(0)
+ , m_scale(0)
+ , m_samples(0)
+ , m_chunks()
+ , m_width(0)
+ , m_height(0)
+ , m_depth(0)
+ , m_interlace(0)
+ , m_huffyuv()
+ , m_channels(0)
+ , m_samplebits(0)
+ , m_samplerate(0)
+ , m_saved_strh_offset(0)
+ , m_saved_indx_offset(0)
+ {
+ }
-/**
- * @struct huffyuv_data
- *
- * @brief A huffyuv data.
- */
+ void initialize_video(avi_file::movie_info const &info)
+ {
+ m_type = STREAMTYPE_VIDS;
+ m_format = info.video_format;
+ m_rate = info.video_timescale;
+ m_scale = info.video_sampletime;
+ m_width = info.video_width;
+ m_height = info.video_height;
+ m_depth = info.video_depth;
+ }
-struct huffyuv_data
-{
- /** @brief The predictor. */
- UINT8 predictor; /* predictor */
- /** @brief The table[ 3]. */
- huffyuv_table table[3]; /* array of tables */
-};
+ void initialize_audio(avi_file::movie_info const &info)
+ {
+ m_type = STREAMTYPE_AUDS;
+ m_format = info.audio_format;
+ m_rate = info.audio_timescale;
+ m_scale = info.audio_sampletime;
+ m_channels = info.audio_channels;
+ m_samplebits = info.audio_samplebits;
+ m_samplerate = info.audio_samplerate;
+ }
-/**
- * @struct avi_stream
- *
- * @brief An avi stream.
- */
+ std::uint32_t type() const { return m_type; }
+ std::uint32_t format() const { return m_format; }
+
+ std::uint32_t rate() const { return m_rate; }
+ std::uint32_t scale() const { return m_scale; }
+ std::uint32_t samples() const { return m_samples; }
+ void set_samples(std::uint32_t value) { m_samples = value; }
+ std::uint32_t add_samples(std::uint32_t value) { return m_samples += value; }
+
+ std::uint32_t chunks() const { return m_chunks.size(); }
+ avi_chunk_list const &chunk(std::uint32_t index) const { assert(index < m_chunks.size()); return m_chunks[index]; }
+ avi_chunk_list &chunk(std::uint32_t index) { assert(index < m_chunks.size()); return m_chunks[index]; }
+ avi_file::error set_chunk_info(std::uint32_t index, std::uint64_t offset, std::uint32_t length);
+ void set_chunks(std::uint32_t count) { assert(count <= m_chunks.size()); m_chunks.resize(count); }
+
+ std::uint32_t width() const { return m_width; }
+ std::uint32_t height() const { return m_height; }
+ std::uint32_t depth() const { return m_depth; }
+
+ std::uint16_t channels() const { return m_channels; }
+ std::uint16_t samplebits() const { return m_samplebits; }
+ std::uint32_t samplerate() const { return m_samplerate; }
+ std::uint32_t bytes_per_sample() const { return (m_samplebits / 8) * m_channels; }
+
+ avi_file::error set_strh_data(std::uint8_t const *data, std::uint32_t size);
+ avi_file::error set_strf_data(std::uint8_t const *data, std::uint32_t size);
+
+ std::uint64_t &saved_strh_offset() { return m_saved_strh_offset; }
+ std::uint64_t &saved_indx_offset() { return m_saved_indx_offset; }
+
+ // RGB helpers
+ avi_file::error rgb32_compress_to_rgb(const bitmap_rgb32 &bitmap, std::uint8_t *data, std::uint32_t numbytes) const;
+
+ // YUY helpers
+ avi_file::error yuv_decompress_to_yuy16(const std::uint8_t *data, std::uint32_t numbytes, bitmap_yuy16 &bitmap) const;
+ avi_file::error yuy16_compress_to_yuy(const bitmap_yuy16 &bitmap, std::uint8_t *data, std::uint32_t numbytes) const;
+
+ // HuffYUV helpers
+ avi_file::error huffyuv_decompress_to_yuy16(const std::uint8_t *data, std::uint32_t numbytes, bitmap_yuy16 &bitmap) const;
+
+private:
+ struct huffyuv_table
+ {
+ std::uint8_t shift[256]; /* bit shift amounts */
+ std::uint32_t bits[256]; /* bit match values */
+ std::uint32_t mask[256]; /* bit mask values */
+ std::uint16_t baselookup[65536]; /* base lookup table */
+ std::vector<std::uint16_t> extralookup; /* extra lookup tables */
+ };
+
+ struct huffyuv_data
+ {
+ std::uint8_t predictor; /* predictor */
+ huffyuv_table table[3]; /* array of tables */
+ };
-struct avi_stream
-{
- /** @brief The type. */
- UINT32 type; /* subtype of stream */
- /** @brief Describes the format to use. */
- UINT32 format; /* format of stream data */
-
- /** @brief The rate. */
- UINT32 rate; /* timescale for stream */
- /** @brief The scale. */
- UINT32 scale; /* duration of one sample in the stream */
- /** @brief The samples. */
- UINT32 samples; /* number of samples */
-
- /** @brief The chunk. */
- avi_chunk_list * chunk; /* list of chunks */
- /** @brief The chunks. */
- UINT32 chunks; /* chunks currently known */
- /** @brief The chunksalloc. */
- UINT32 chunksalloc; /* number of chunks allocated */
-
- /** @brief The width. */
- UINT32 width; /* width of video */
- /** @brief The height. */
- UINT32 height; /* height of video */
- /** @brief The depth. */
- UINT32 depth; /* depth of video */
- /** @brief The interlace. */
- UINT8 interlace; /* interlace parameters */
- /** @brief The huffyuv. */
- huffyuv_data * huffyuv; /* huffyuv decompression data */
-
- /** @brief The channels. */
- UINT16 channels; /* audio channels */
- /** @brief The samplebits. */
- UINT16 samplebits; /* audio bits per sample */
- /** @brief The samplerate. */
- UINT32 samplerate; /* audio sample rate */
+ avi_file::error huffyuv_extract_tables(const std::uint8_t *chunkdata, std::uint32_t size);
+
+ std::uint32_t m_type; /* subtype of stream */
+ std::uint32_t m_format; /* format of stream data */
+
+ std::uint32_t m_rate; /* timescale for stream */
+ std::uint32_t m_scale; /* duration of one sample in the stream */
+ std::uint32_t m_samples; /* number of samples */
+
+ std::vector<avi_chunk_list> m_chunks; /* list of chunks */
+
+ std::uint32_t m_width; /* width of video */
+ std::uint32_t m_height; /* height of video */
+ std::uint32_t m_depth; /* depth of video */
+ std::uint8_t m_interlace; /* interlace parameters */
+ std::unique_ptr<huffyuv_data const> m_huffyuv; /* huffyuv decompression data */
+
+ std::uint16_t m_channels; /* audio channels */
+ std::uint16_t m_samplebits; /* audio bits per sample */
+ std::uint32_t m_samplerate; /* audio sample rate */
/* only used when creating */
- /** @brief The saved strh offset. */
- UINT64 saved_strh_offset; /* writeoffset of strh chunk */
- /** @brief The saved indx offset. */
- UINT64 saved_indx_offset; /* writeoffset of indx chunk */
+ std::uint64_t m_saved_strh_offset; /* writeoffset of strh chunk */
+ std::uint64_t m_saved_indx_offset; /* writeoffset of indx chunk */
};
/**
- * @struct avi_file
+ * @class avi_file_impl
*
* @brief An avi file.
*/
-struct avi_file
+class avi_file_impl : public avi_file
{
- /* shared data */
- /** @brief The file. */
- osd_file * file; /* pointer to open file */
- /** @brief The type. */
- int type; /* type of access (read/create) */
- /** @brief The information. */
- avi_movie_info info; /* movie info structure */
- /** @brief The tempbuffer. */
- UINT8 * tempbuffer; /* temporary buffer */
- /** @brief The tempbuffersize. */
- UINT32 tempbuffersize; /* size of the temporary buffer */
-
- /* only used when reading */
- /** @brief The streams. */
- int streams; /* number of streams */
- /** @brief The stream. */
- avi_stream * stream; /* allocated array of stream information */
- /** @brief The rootchunk. */
- avi_chunk rootchunk; /* dummy root chunk that wraps the whole file */
-
- /* only used when creating */
- /** @brief The writeoffs. */
- UINT64 writeoffs; /* current file write offset */
- /** @brief The riffbase. */
- UINT64 riffbase; /* base of the current RIFF */
-
- /** @brief The chunkstack[ 8]. */
- avi_chunk chunkstack[8]; /* stack of chunks we are writing */
- /** @brief The chunksp. */
- int chunksp; /* stack pointer for the current chunk */
-
- /** @brief The saved movi offset. */
- UINT64 saved_movi_offset; /* writeoffset of movi list */
- /** @brief The saved avih offset. */
- UINT64 saved_avih_offset; /* writeoffset of avih chunk */
-
- /** @brief The soundbuf. */
- INT16 * soundbuf; /* buffer for sound data */
- /** @brief The soundbuf samples. */
- UINT32 soundbuf_samples; /* length of sound buffer in samples */
- /** @brief The soundbuf chansamples[ maximum sound channels]. */
- UINT32 soundbuf_chansamples[MAX_SOUND_CHANNELS]; /* samples in buffer for each channel */
- /** @brief The soundbuf chunks. */
- UINT32 soundbuf_chunks; /* number of chunks completed so far */
- /** @brief The soundbuf frames. */
- UINT32 soundbuf_frames; /* number of frames ahead of the video */
-};
-
+public:
+ avi_file_impl(osd_file::ptr &&file, std::uint64_t length) : avi_file_impl()
+ {
+ m_file = std::move(file);
+ m_type = FILETYPE_READ;
+
+ // make a root atom
+ m_rootchunk.offset = 0;
+ m_rootchunk.size = length;
+ m_rootchunk.type = 0;
+ m_rootchunk.listtype = 0;
+ }
+ avi_file_impl(osd_file::ptr &&file, movie_info const &info) : avi_file_impl()
+ {
+ m_file = std::move(file);
+ m_type = FILETYPE_CREATE;
-/***************************************************************************
- PROTOTYPES
-***************************************************************************/
+ // copy the movie info
+ m_info = info;
+ m_info.video_numsamples = 0;
+ m_info.audio_numsamples = 0;
-/* stream helpers */
+ // initialize the video track
+ m_streams.emplace_back();
+ m_streams.back().initialize_video(m_info);
-/* core chunk read routines */
-static avi_error get_first_chunk(avi_file *file, const avi_chunk *parent, avi_chunk *newchunk);
-static avi_error get_next_chunk(avi_file *file, const avi_chunk *parent, avi_chunk *newchunk);
-static avi_error find_first_chunk(avi_file *file, UINT32 findme, const avi_chunk *container, avi_chunk *result);
-static avi_error find_next_chunk(avi_file *file, UINT32 findme, const avi_chunk *container, avi_chunk *result);
-static avi_error get_next_chunk_internal(avi_file *file, const avi_chunk *parent, avi_chunk *newchunk, UINT64 offset);
-static avi_error read_chunk_data(avi_file *file, const avi_chunk *chunk, UINT8 **buffer);
+ // initialize the audio track
+ if (m_info.audio_channels > 0)
+ {
+ m_streams.emplace_back();
+ m_streams.back().initialize_audio(m_info);
+ }
+ }
-/* chunk read helpers */
-static avi_error read_movie_data(avi_file *file);
-static avi_error extract_movie_info(avi_file *file);
-static avi_error parse_avih_chunk(avi_file *file, avi_chunk *avih);
-static avi_error parse_strh_chunk(avi_file *file, avi_stream *stream, avi_chunk *strh);
-static avi_error parse_strf_chunk(avi_file *file, avi_stream *stream, avi_chunk *strf);
-static avi_error parse_indx_chunk(avi_file *file, avi_stream *stream, avi_chunk *strf);
-static avi_error parse_idx1_chunk(avi_file *file, UINT64 baseoffset, avi_chunk *idx1);
+ virtual ~avi_file_impl() override;
+
+ virtual void printf_chunks() override;
+
+ virtual movie_info const &get_movie_info() const override;
+ virtual std::uint32_t first_sample_in_frame(std::uint32_t framenum) const override;
+
+ virtual error read_video_frame(std::uint32_t framenum, bitmap_yuy16 &bitmap) override;
+ virtual error read_sound_samples(int channel, std::uint32_t firstsample, std::uint32_t numsamples, std::int16_t *output) override;
+
+ virtual error append_video_frame(bitmap_yuy16 &bitmap) override;
+ virtual error append_video_frame(bitmap_rgb32 &bitmap) override;
+ virtual error append_sound_samples(int channel, std::int16_t const *samples, std::uint32_t numsamples, std::uint32_t sampleskip) override;
+
+ error read_movie_data();
+ error write_initial_headers();
+ error soundbuf_initialize();
+
+private:
+ avi_file_impl()
+ : m_file()
+ , m_type(0)
+ , m_info({ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 })
+ , m_tempbuffer()
+ , m_streams()
+ , m_rootchunk()
+ , m_writeoffs(0)
+ , m_riffbase(0)
+ , m_chunkstack()
+ , m_chunksp(0)
+ , m_saved_movi_offset(0)
+ , m_saved_avih_offset(0)
+ , m_soundbuf()
+ , m_soundbuf_samples(0)
+ , m_soundbuf_chunks(0)
+ , m_soundbuf_frames(0)
+ {
+ std::fill(std::begin(m_soundbuf_chansamples), std::end(m_soundbuf_chansamples), 0);
+ }
-/* core chunk write routines */
-static avi_error chunk_open(avi_file *file, UINT32 type, UINT32 listtype, UINT32 estlength);
-static avi_error chunk_close(avi_file *file);
-static avi_error chunk_write(avi_file *file, UINT32 type, const void *data, UINT32 length);
-static avi_error chunk_overwrite(avi_file *file, UINT32 type, const void *data, UINT32 length, UINT64 *offset, int initial_write);
+ avi_stream *get_video_stream();
+ avi_stream *get_audio_stream(int channel, int &offset);
+ std::uint32_t compute_idx1_size() const;
+ std::uint32_t get_chunkid_for_stream(const avi_stream *stream) const;
+ std::uint32_t framenum_to_samplenum(std::uint32_t framenum) const;
+ error expand_tempbuffer(std::uint32_t length);
+
+ // core chunk read routines
+ error get_first_chunk(avi_chunk const *parent, avi_chunk &newchunk);
+ error get_next_chunk(avi_chunk const *parent, avi_chunk &newchunk);
+ error find_first_chunk(std::uint32_t findme, avi_chunk const *container, avi_chunk &result);
+ error find_next_chunk(std::uint32_t findme, avi_chunk const *container, avi_chunk &result);
+ error find_first_list(std::uint32_t findme, avi_chunk const *container, avi_chunk &result);
+ error find_next_list(std::uint32_t findme, avi_chunk const *container, avi_chunk &result);
+ error get_next_chunk_internal(avi_chunk const *parent, avi_chunk &newchunk, std::uint64_t offset);
+ error read_chunk_data(avi_chunk const &chunk, std::unique_ptr<std::uint8_t []> &buffer);
+
+ // chunk read helpers
+ error extract_movie_info();
+ error parse_avih_chunk(avi_chunk const &avih);
+ error parse_strh_chunk(avi_stream &stream, avi_chunk const &strh);
+ error parse_strf_chunk(avi_stream &stream, avi_chunk const &strf);
+ error parse_indx_chunk(avi_stream &stream, avi_chunk const &strf);
+ error parse_idx1_chunk(std::uint64_t baseoffset, avi_chunk const &idx1);
+
+ // core chunk write routines
+ error chunk_open(std::uint32_t type, std::uint32_t listtype, std::uint32_t estlength);
+ error chunk_close();
+ error chunk_write(std::uint32_t type, const void *data, std::uint32_t length);
+ error chunk_overwrite(std::uint32_t type, const void *data, std::uint32_t length, std::uint64_t &offset, bool initial_write);
+
+ // chunk write helpers
+ error write_avih_chunk(bool initial_write);
+ error write_strh_chunk(avi_stream &stream, bool initial_write);
+ error write_strf_chunk(avi_stream const &stream);
+ error write_indx_chunk(avi_stream &stream, bool initial_write);
+ error write_idx1_chunk();
+
+ // sound buffering helpers
+ error soundbuf_write_chunk(std::uint32_t framenum);
+ error soundbuf_flush(bool only_flush_full);
+
+ // debugging
+ void printf_chunk_recursive(avi_chunk const *chunk, int indent);
-/* chunk write helpers */
-static avi_error write_initial_headers(avi_file *file);
-static avi_error write_avih_chunk(avi_file *file, int initial_write);
-static avi_error write_strh_chunk(avi_file *file, avi_stream *stream, int initial_write);
-static avi_error write_strf_chunk(avi_file *file, avi_stream *stream);
-static avi_error write_indx_chunk(avi_file *file, avi_stream *stream, int initial_write);
-static avi_error write_idx1_chunk(avi_file *file);
+ /* shared data */
+ osd_file::ptr m_file; /* pointer to open file */
+ int m_type; /* type of access (read/create) */
+ movie_info m_info; /* movie info structure */
+ std::vector<std::uint8_t> m_tempbuffer; /* temporary buffer */
-/* sound buffering helpers */
-static avi_error soundbuf_initialize(avi_file *file);
-static avi_error soundbuf_write_chunk(avi_file *file, UINT32 framenum);
-static avi_error soundbuf_flush(avi_file *file, int only_flush_full);
+ /* only used when reading */
+ std::vector<avi_stream> m_streams; /* allocated array of stream information */
+ avi_chunk m_rootchunk; /* dummy root chunk that wraps the whole file */
-/* RGB helpers */
-static avi_error rgb32_compress_to_rgb(avi_stream *stream, const bitmap_rgb32 &bitmap, UINT8 *data, UINT32 numbytes);
+ /* only used when creating */
+ std::uint64_t m_writeoffs; /* current file write offset */
+ std::uint64_t m_riffbase; /* base of the current RIFF */
-/* YUY helpers */
-static avi_error yuv_decompress_to_yuy16(avi_stream *stream, const UINT8 *data, UINT32 numbytes, bitmap_yuy16 &bitmap);
-static avi_error yuy16_compress_to_yuy(avi_stream *stream, const bitmap_yuy16 &bitmap, UINT8 *data, UINT32 numbytes);
+ std::array<avi_chunk, 8> m_chunkstack; /* stack of chunks we are writing */
+ int m_chunksp; /* stack pointer for the current chunk */
-/* HuffYUV helpers */
-static avi_error huffyuv_extract_tables(avi_stream *stream, const UINT8 *chunkdata, UINT32 size);
-static avi_error huffyuv_decompress_to_yuy16(avi_stream *stream, const UINT8 *data, UINT32 numbytes, bitmap_yuy16 &bitmap);
+ std::uint64_t m_saved_movi_offset; /* writeoffset of movi list */
+ std::uint64_t m_saved_avih_offset; /* writeoffset of avih chunk */
-/* debugging */
-static void printf_chunk_recursive(avi_file *file, avi_chunk *chunk, int indent);
+ std::vector<std::int16_t> m_soundbuf; /* buffer for sound data */
+ std::uint32_t m_soundbuf_samples; /* length of sound buffer in samples */
+ std::uint32_t m_soundbuf_chansamples[MAX_SOUND_CHANNELS]; /* samples in buffer for each channel */
+ std::uint32_t m_soundbuf_chunks; /* number of chunks completed so far */
+ std::uint32_t m_soundbuf_frames; /* number of frames ahead of the video */
+};
@@ -471,7 +557,7 @@ static void printf_chunk_recursive(avi_file *file, avi_chunk *chunk, int indent)
-------------------------------------------------*/
/**
- * @fn static inline UINT16 fetch_16bits(const UINT8 *data)
+ * @fn static inline std::uint16_t fetch_16bits(const std::uint8_t *data)
*
* @brief Fetches the 16bits.
*
@@ -480,7 +566,7 @@ static void printf_chunk_recursive(avi_file *file, avi_chunk *chunk, int indent)
* @return The 16bits.
*/
-static inline UINT16 fetch_16bits(const UINT8 *data)
+inline std::uint16_t fetch_16bits(const std::uint8_t *data)
{
return data[0] | (data[1] << 8);
}
@@ -492,7 +578,7 @@ static inline UINT16 fetch_16bits(const UINT8 *data)
-------------------------------------------------*/
/**
- * @fn static inline UINT32 fetch_32bits(const UINT8 *data)
+ * @fn static inline std::uint32_t fetch_32bits(const std::uint8_t *data)
*
* @brief Fetches the 32bits.
*
@@ -501,7 +587,7 @@ static inline UINT16 fetch_16bits(const UINT8 *data)
* @return The 32bits.
*/
-static inline UINT32 fetch_32bits(const UINT8 *data)
+inline std::uint32_t fetch_32bits(const std::uint8_t *data)
{
return data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24);
}
@@ -513,7 +599,7 @@ static inline UINT32 fetch_32bits(const UINT8 *data)
-------------------------------------------------*/
/**
- * @fn static inline UINT64 fetch_64bits(const UINT8 *data)
+ * @fn static inline std::uint64_t fetch_64bits(const std::uint8_t *data)
*
* @brief Fetches the 64bits.
*
@@ -522,12 +608,12 @@ static inline UINT32 fetch_32bits(const UINT8 *data)
* @return The 64bits.
*/
-static inline UINT64 fetch_64bits(const UINT8 *data)
+inline std::uint64_t fetch_64bits(const std::uint8_t *data)
{
- return (UINT64)data[0] | ((UINT64)data[1] << 8) |
- ((UINT64)data[2] << 16) | ((UINT64)data[3] << 24) |
- ((UINT64)data[4] << 32) | ((UINT64)data[5] << 40) |
- ((UINT64)data[6] << 48) | ((UINT64)data[7] << 56);
+ return std::uint64_t(data[0]) | (std::uint64_t(data[1]) << 8) |
+ (std::uint64_t(data[2]) << 16) | (std::uint64_t(data[3]) << 24) |
+ (std::uint64_t(data[4]) << 32) | (std::uint64_t(data[5]) << 40) |
+ (std::uint64_t(data[6]) << 48) | (std::uint64_t(data[7]) << 56);
}
@@ -537,7 +623,7 @@ static inline UINT64 fetch_64bits(const UINT8 *data)
-------------------------------------------------*/
/**
- * @fn static inline void put_16bits(UINT8 *data, UINT16 value)
+ * @fn static inline void put_16bits(std::uint8_t *data, std::uint16_t value)
*
* @brief Puts the 16bits.
*
@@ -545,7 +631,7 @@ static inline UINT64 fetch_64bits(const UINT8 *data)
* @param value The value.
*/
-static inline void put_16bits(UINT8 *data, UINT16 value)
+inline void put_16bits(std::uint8_t *data, std::uint16_t value)
{
data[0] = value >> 0;
data[1] = value >> 8;
@@ -558,7 +644,7 @@ static inline void put_16bits(UINT8 *data, UINT16 value)
-------------------------------------------------*/
/**
- * @fn static inline void put_32bits(UINT8 *data, UINT32 value)
+ * @fn static inline void put_32bits(std::uint8_t *data, std::uint32_t value)
*
* @brief Puts the 32bits.
*
@@ -566,7 +652,7 @@ static inline void put_16bits(UINT8 *data, UINT16 value)
* @param value The value.
*/
-static inline void put_32bits(UINT8 *data, UINT32 value)
+inline void put_32bits(std::uint8_t *data, std::uint32_t value)
{
data[0] = value >> 0;
data[1] = value >> 8;
@@ -581,7 +667,7 @@ static inline void put_32bits(UINT8 *data, UINT32 value)
-------------------------------------------------*/
/**
- * @fn static inline void put_64bits(UINT8 *data, UINT64 value)
+ * @fn static inline void put_64bits(std::uint8_t *data, std::uint64_t value)
*
* @brief Puts the 64bits.
*
@@ -589,7 +675,7 @@ static inline void put_32bits(UINT8 *data, UINT32 value)
* @param value The value.
*/
-static inline void put_64bits(UINT8 *data, UINT64 value)
+inline void put_64bits(std::uint8_t *data, std::uint64_t value)
{
data[0] = value >> 0;
data[1] = value >> 8;
@@ -602,29 +688,120 @@ static inline void put_64bits(UINT8 *data, UINT64 value)
}
+/**
+ * @fn static void u64toa(std::uint64_t val, char *output)
+ *
+ * @brief 64toas.
+ *
+ * @param val The value.
+ * @param [in,out] output If non-null, the output.
+ */
+
+inline void u64toa(std::uint64_t val, char *output)
+{
+ std::uint32_t lo = std::uint32_t(val & 0xffffffff);
+ std::uint32_t hi = std::uint32_t(val >> 32);
+ if (hi != 0)
+ sprintf(output, "%X%08X", hi, lo);
+ else
+ sprintf(output, "%X", lo);
+}
+
+
+/*-------------------------------------------------
+ set_stream_chunk_info - set the chunk info
+ for a given chunk within a stream
+-------------------------------------------------*/
+
+/**
+ * @fn static inline avi_error set_stream_chunk_info(avi_stream *stream, std::uint32_t index, std::uint64_t offset, std::uint32_t length)
+ *
+ * @brief Sets stream chunk information.
+ *
+ * @param [in,out] stream If non-null, the stream.
+ * @param index Zero-based index of the.
+ * @param offset The offset.
+ * @param length The length.
+ *
+ * @return An avi_error.
+ */
+
+inline avi_file::error avi_stream::set_chunk_info(std::uint32_t index, std::uint64_t offset, std::uint32_t length)
+{
+ /* if we need to allocate more, allocate more */
+ if (index >= m_chunks.capacity())
+ {
+ try { m_chunks.reserve((std::max<std::size_t>)(index, m_chunks.capacity() + 1000)); }
+ catch (...) { return avi_file::error::NO_MEMORY; }
+ }
+
+ /* update the number of chunks */
+ m_chunks.resize((std::max<std::size_t>)(m_chunks.size(), index + 1));
+
+ /* set the data */
+ m_chunks[index].offset = offset;
+ m_chunks[index].length = length;
+
+ return avi_file::error::NONE;
+}
+
+
+inline avi_file::error avi_stream::set_strh_data(std::uint8_t const *data, std::uint32_t size)
+{
+ m_type = fetch_32bits(&data[0]);
+ m_scale = fetch_32bits(&data[20]);
+ m_rate = fetch_32bits(&data[24]);
+ m_samples = fetch_32bits(&data[32]);
+ return avi_file::error::NONE;
+}
+
+
+inline avi_file::error avi_stream::set_strf_data(std::uint8_t const *data, std::uint32_t size)
+{
+ /* audio and video streams have differing headers */
+ if (m_type == STREAMTYPE_VIDS)
+ {
+ m_width = fetch_32bits(&data[4]);
+ m_height = fetch_32bits(&data[8]);
+ m_depth = fetch_16bits(&data[14]);
+ m_format = fetch_32bits(&data[16]);
+
+ /* extra extraction for HuffYUV data */
+ if ((m_format == FORMAT_HFYU) && (size >= 56))
+ {
+ avi_file::error const avierr = huffyuv_extract_tables(data, size);
+ if (avierr != avi_file::error::NONE)
+ return avierr;
+ }
+ }
+ else if (m_type == STREAMTYPE_AUDS)
+ {
+ m_channels = fetch_16bits(&data[2]);
+ m_samplebits = fetch_16bits(&data[14]);
+ m_samplerate = fetch_32bits(&data[4]);
+ }
+ return avi_file::error::NONE;
+}
+
+
/*-------------------------------------------------
get_video_stream - return a pointer to the
video stream
-------------------------------------------------*/
/**
- * @fn static inline avi_stream *get_video_stream(avi_file *file)
+ * @fn static inline avi_stream *get_video_stream()
*
* @brief Gets video stream.
*
- * @param [in,out] file If non-null, the file.
- *
* @return null if it fails, else the video stream.
*/
-static inline avi_stream *get_video_stream(avi_file *file)
+inline avi_stream *avi_file_impl::get_video_stream()
{
- int streamnum;
-
- /* find the video stream */
- for (streamnum = 0; streamnum < file->streams; streamnum++)
- if (file->stream[streamnum].type == STREAMTYPE_VIDS)
- return &file->stream[streamnum];
+ for (int streamnum = 0; streamnum < m_streams.size(); streamnum++)
+ if (m_streams[streamnum].type() == STREAMTYPE_VIDS)
+ return &m_streams[streamnum];
return nullptr;
}
@@ -647,21 +824,18 @@ static inline avi_stream *get_video_stream(avi_file *file)
* @return null if it fails, else the audio stream.
*/
-static inline avi_stream *get_audio_stream(avi_file *file, int channel, int *offset)
+inline avi_stream *avi_file_impl::get_audio_stream(int channel, int &offset)
{
- int streamnum;
-
/* find the audios stream */
- for (streamnum = 0; streamnum < file->streams; streamnum++)
- if (file->stream[streamnum].type == STREAMTYPE_AUDS)
+ for (int streamnum = 0; streamnum < m_streams.size(); streamnum++)
+ if (m_streams[streamnum].type() == STREAMTYPE_AUDS)
{
- if (channel < file->stream[streamnum].channels)
+ if (channel < m_streams[streamnum].channels())
{
- if (offset != nullptr)
- *offset = channel;
- return &file->stream[streamnum];
+ offset = channel;
+ return &m_streams[streamnum];
}
- channel -= file->stream[streamnum].channels;
+ channel -= m_streams[streamnum].channels();
}
return nullptr;
@@ -669,58 +843,12 @@ static inline avi_stream *get_audio_stream(avi_file *file, int channel, int *off
/*-------------------------------------------------
- set_stream_chunk_info - set the chunk info
- for a given chunk within a stream
--------------------------------------------------*/
-
-/**
- * @fn static inline avi_error set_stream_chunk_info(avi_stream *stream, UINT32 index, UINT64 offset, UINT32 length)
- *
- * @brief Sets stream chunk information.
- *
- * @param [in,out] stream If non-null, the stream.
- * @param index Zero-based index of the.
- * @param offset The offset.
- * @param length The length.
- *
- * @return An avi_error.
- */
-
-static inline avi_error set_stream_chunk_info(avi_stream *stream, UINT32 index, UINT64 offset, UINT32 length)
-{
- /* if we need to allocate more, allocate more */
- if (index >= stream->chunksalloc)
- {
- UINT32 newcount = MAX(index, stream->chunksalloc + 1000);
- avi_chunk_list *newchunks = (avi_chunk_list *)malloc(newcount * sizeof(stream->chunk[0]));
- if (newchunks == nullptr)
- return AVIERR_NO_MEMORY;
- if (stream->chunk != nullptr)
- {
- memcpy(newchunks, stream->chunk, stream->chunksalloc * sizeof(stream->chunk[0]));
- free(stream->chunk);
- }
- stream->chunk = newchunks;
- stream->chunksalloc = newcount;
- }
-
- /* set the data */
- stream->chunk[index].offset = offset;
- stream->chunk[index].length = length;
-
- /* update the number of chunks */
- stream->chunks = MAX(stream->chunks, index + 1);
- return AVIERR_NONE;
-}
-
-
-/*-------------------------------------------------
compute_idx1_size - compute the size of the
idx1 chunk
-------------------------------------------------*/
/**
- * @fn static inline UINT32 compute_idx1_size(avi_file *file)
+ * @fn static inline std::uint32_t compute_idx1_size(avi_file *file)
*
* @brief Calculates the index 1 size.
*
@@ -729,14 +857,13 @@ static inline avi_error set_stream_chunk_info(avi_stream *stream, UINT32 index,
* @return The calculated index 1 size.
*/
-static inline UINT32 compute_idx1_size(avi_file *file)
+inline std::uint32_t avi_file_impl::compute_idx1_size() const
{
int chunks = 0;
- int strnum;
/* count chunks in streams */
- for (strnum = 0; strnum < file->streams; strnum++)
- chunks += file->stream[strnum].chunks;
+ for (int strnum = 0; strnum < m_streams.size(); strnum++)
+ chunks += m_streams[strnum].chunks();
return chunks * 16 + 8;
}
@@ -748,7 +875,7 @@ static inline UINT32 compute_idx1_size(avi_file *file)
-------------------------------------------------*/
/**
- * @fn static inline UINT32 get_chunkid_for_stream(avi_file *file, avi_stream *stream)
+ * @fn static inline std::uint32_t get_chunkid_for_stream(avi_file *file, avi_stream *stream)
*
* @brief Gets chunkid for stream.
*
@@ -758,14 +885,14 @@ static inline UINT32 compute_idx1_size(avi_file *file)
* @return The chunkid for stream.
*/
-static inline UINT32 get_chunkid_for_stream(avi_file *file, avi_stream *stream)
+inline std::uint32_t avi_file_impl::get_chunkid_for_stream(const avi_stream *stream) const
{
- UINT32 chunkid;
+ std::uint32_t chunkid;
- chunkid = AVI_FOURCC('0' + (stream - file->stream) / 10, '0' + (stream - file->stream) % 10, 0, 0);
- if (stream->type == STREAMTYPE_VIDS)
- chunkid |= (stream->format == 0) ? CHUNKTYPE_XXDB : CHUNKTYPE_XXDC;
- else if (stream->type == STREAMTYPE_AUDS)
+ chunkid = AVI_FOURCC('0' + (stream - &m_streams[0]) / 10, '0' + (stream - &m_streams[0]) % 10, 0, 0);
+ if (stream->type() == STREAMTYPE_VIDS)
+ chunkid |= (stream->format() == 0) ? CHUNKTYPE_XXDB : CHUNKTYPE_XXDC;
+ else if (stream->type() == STREAMTYPE_AUDS)
chunkid |= CHUNKTYPE_XXWB;
return chunkid;
@@ -778,19 +905,19 @@ static inline UINT32 get_chunkid_for_stream(avi_file *file, avi_stream *stream)
-------------------------------------------------*/
/**
- * @fn static inline UINT32 framenum_to_samplenum(avi_file *file, UINT32 framenum)
+ * @fn static inline std::uint32_t framenum_to_samplenum(avi_file *file, std::uint32_t framenum)
*
* @brief Framenum to samplenum.
*
* @param [in,out] file If non-null, the file.
* @param framenum The framenum.
*
- * @return An UINT32.
+ * @return An std::uint32_t.
*/
-static inline UINT32 framenum_to_samplenum(avi_file *file, UINT32 framenum)
+inline std::uint32_t avi_file_impl::framenum_to_samplenum(std::uint32_t framenum) const
{
- return ((UINT64)file->info.audio_samplerate * (UINT64)framenum * (UINT64)file->info.video_sampletime + file->info.video_timescale - 1) / (UINT64)file->info.video_timescale;
+ return (std::uint64_t(m_info.audio_samplerate) * std::uint64_t(framenum) * std::uint64_t(m_info.video_sampletime) + m_info.video_timescale - 1) / std::uint64_t(m_info.video_timescale);
}
@@ -801,7 +928,7 @@ static inline UINT32 framenum_to_samplenum(avi_file *file, UINT32 framenum)
-------------------------------------------------*/
/**
- * @fn static inline avi_error expand_tempbuffer(avi_file *file, UINT32 length)
+ * @fn static inline avi_error expand_tempbuffer(avi_file *file, std::uint32_t length)
*
* @brief Expand tempbuffer.
*
@@ -811,207 +938,532 @@ static inline UINT32 framenum_to_samplenum(avi_file *file, UINT32 framenum)
* @return An avi_error.
*/
-static inline avi_error expand_tempbuffer(avi_file *file, UINT32 length)
+inline avi_file::error avi_file_impl::expand_tempbuffer(std::uint32_t length)
{
/* expand the tempbuffer to hold the data if necessary */
- if (length > file->tempbuffersize)
+ if (length > m_tempbuffer.size())
{
- file->tempbuffersize = 2 * length;
- UINT8 *newbuffer = (UINT8 *)malloc(file->tempbuffersize);
- if (newbuffer == nullptr)
- return AVIERR_NO_MEMORY;
- if (file->tempbuffer != nullptr)
- free(file->tempbuffer);
- file->tempbuffer = newbuffer;
+ try { m_tempbuffer.resize(2 * length); }
+ catch (...) { return error::NO_MEMORY; }
}
- return AVIERR_NONE;
+ return error::NONE;
}
+/*-------------------------------------------------
+ rgb32_compress_to_rgb - "compress" an RGB32
+ bitmap to an RGB encoded frame
+-------------------------------------------------*/
+
+/**
+ * @fn static avi_error rgb32_compress_to_rgb(avi_stream *stream, const bitmap_rgb32 &bitmap, std::uint8_t *data, std::uint32_t numbytes)
+ *
+ * @brief RGB 32 compress to RGB.
+ *
+ * @param [in,out] stream If non-null, the stream.
+ * @param bitmap The bitmap.
+ * @param [in,out] data If non-null, the data.
+ * @param numbytes The numbytes.
+ *
+ * @return An avi_error.
+ */
+
+avi_file::error avi_stream::rgb32_compress_to_rgb(const bitmap_rgb32 &bitmap, std::uint8_t *data, std::uint32_t numbytes) const
+{
+ int const height = (std::min<int>)(m_height, bitmap.height());
+ int const width = (std::min<int>)(m_width, bitmap.width());
+ std::uint8_t *const dataend = data + numbytes;
+ int x, y;
+
+ /* compressed video */
+ for (y = 0; y < height; y++)
+ {
+ const std::uint32_t *source = &bitmap.pix32(y);
+ std::uint8_t *dest = data + (m_height - 1 - y) * m_width * 3;
+
+ for (x = 0; x < width && dest < dataend; x++)
+ {
+ rgb_t pix = *source++;
+ *dest++ = pix.b();
+ *dest++ = pix.g();
+ *dest++ = pix.r();
+ }
+
+ /* fill in any blank space on the right */
+ for ( ; x < m_width && dest < dataend; x++)
+ {
+ *dest++ = 0;
+ *dest++ = 0;
+ *dest++ = 0;
+ }
+ }
+
+ /* fill in any blank space on the bottom */
+ for ( ; y < m_height; y++)
+ {
+ std::uint8_t *dest = data + (m_height - 1 - y) * m_width * 3;
+ for (x = 0; x < m_width && dest < dataend; x++)
+ {
+ *dest++ = 0;
+ *dest++ = 0;
+ *dest++ = 0;
+ }
+ }
+
+ return avi_file::error::NONE;
+}
-/***************************************************************************
- IMPLEMENTATION
-***************************************************************************/
/*-------------------------------------------------
- avi_open - open an AVI movie file for read
+ yuv_decompress_to_yuy16 - decompress a YUV
+ encoded frame to a YUY16 bitmap
-------------------------------------------------*/
/**
- * @fn avi_error avi_open(const char *filename, avi_file **file)
+ * @fn static avi_error yuv_decompress_to_yuy16(avi_stream *stream, const std::uint8_t *data, std::uint32_t numbytes, bitmap_yuy16 &bitmap)
*
- * @brief Queries if a given avi open.
+ * @brief Yuv decompress to yuy 16.
*
- * @param filename Filename of the file.
- * @param [in,out] file If non-null, the file.
+ * @param [in,out] stream If non-null, the stream.
+ * @param data The data.
+ * @param numbytes The numbytes.
+ * @param [in,out] bitmap The bitmap.
*
* @return An avi_error.
*/
-avi_error avi_open(const char *filename, avi_file **file)
+avi_file::error avi_stream::yuv_decompress_to_yuy16(const std::uint8_t *data, std::uint32_t numbytes, bitmap_yuy16 &bitmap) const
{
- avi_file *newfile = nullptr;
- file_error filerr;
- avi_error avierr;
- UINT64 length;
-
- /* allocate the file */
- newfile = (avi_file *)malloc(sizeof(*newfile));
- if (newfile == nullptr)
- return AVIERR_NO_MEMORY;
- memset(newfile, 0, sizeof(*newfile));
- newfile->type = FILETYPE_READ;
+ std::uint16_t const *const dataend = reinterpret_cast<const std::uint16_t *>(data + numbytes);
+ int x, y;
- /* open the file */
- filerr = osd_open(filename, OPEN_FLAG_READ, &newfile->file, &length);
- if (filerr != FILERR_NONE)
+ /* compressed video */
+ for (y = 0; y < m_height; y++)
{
- avierr = AVIERR_CANT_OPEN_FILE;
- goto error;
+ const std::uint16_t *source = reinterpret_cast<const std::uint16_t *>(data) + y * m_width;
+ std::uint16_t *dest = &bitmap.pix16(y);
+
+ /* switch off the compression */
+ switch (m_format)
+ {
+ case FORMAT_UYVY:
+ for (x = 0; x < m_width && source < dataend; x++)
+ *dest++ = *source++;
+ break;
+
+ case FORMAT_VYUY:
+ case FORMAT_YUY2:
+ for (x = 0; x < m_width && source < dataend; x++)
+ {
+ std::uint16_t pix = *source++;
+ *dest++ = (pix >> 8) | (pix << 8);
+ }
+ break;
+ }
}
- /* make a root atom */
- newfile->rootchunk.offset = 0;
- newfile->rootchunk.size = length;
- newfile->rootchunk.type = 0;
- newfile->rootchunk.listtype = 0;
+ return avi_file::error::NONE;
+}
- /* parse the data */
- avierr = read_movie_data(newfile);
- if (avierr != AVIERR_NONE)
- goto error;
- *file = newfile;
- return AVIERR_NONE;
+/*-------------------------------------------------
+ yuy16_compress_to_yuy - "compress" a YUY16
+ bitmap to a YUV encoded frame
+-------------------------------------------------*/
-error:
- /* clean up after an error */
- if (newfile != nullptr)
+/**
+ * @fn static avi_error yuy16_compress_to_yuy(avi_stream *stream, const bitmap_yuy16 &bitmap, std::uint8_t *data, std::uint32_t numbytes)
+ *
+ * @brief Yuy 16 compress to yuy.
+ *
+ * @param [in,out] stream If non-null, the stream.
+ * @param bitmap The bitmap.
+ * @param [in,out] data If non-null, the data.
+ * @param numbytes The numbytes.
+ *
+ * @return An avi_error.
+ */
+
+avi_file::error avi_stream::yuy16_compress_to_yuy(const bitmap_yuy16 &bitmap, std::uint8_t *data, std::uint32_t numbytes) const
+{
+ std::uint16_t *const dataend = reinterpret_cast<std::uint16_t *>(data + numbytes);
+ int x, y;
+
+ /* compressed video */
+ for (y = 0; y < m_height; y++)
{
- if (newfile->file != nullptr)
- osd_close(newfile->file);
- free(newfile);
+ const std::uint16_t *source = &bitmap.pix16(y);
+ std::uint16_t *dest = reinterpret_cast<std::uint16_t *>(data) + y * m_width;
+
+ /* switch off the compression */
+ switch (m_format)
+ {
+ case FORMAT_UYVY:
+ for (x = 0; x < m_width && dest < dataend; x++)
+ *dest++ = *source++;
+ break;
+
+ case FORMAT_VYUY:
+ case FORMAT_YUY2:
+ for (x = 0; x < m_width && dest < dataend; x++)
+ {
+ std::uint16_t pix = *source++;
+ *dest++ = (pix >> 8) | (pix << 8);
+ }
+ break;
+ }
}
- return avierr;
+
+ return avi_file::error::NONE;
}
/*-------------------------------------------------
- avi_create - create a new AVI movie file
+ huffyuv_extract_tables - extract HuffYUV
+ tables
-------------------------------------------------*/
/**
- * @fn avi_error avi_create(const char *filename, const avi_movie_info *info, avi_file **file)
+ * @fn static avi_error huffyuv_extract_tables(avi_stream *stream, const std::uint8_t *chunkdata, std::uint32_t size)
*
- * @brief Avi create.
+ * @brief Huffyuv extract tables.
*
- * @param filename Filename of the file.
- * @param info The information.
- * @param [in,out] file If non-null, the file.
+ * @param [in,out] stream If non-null, the stream.
+ * @param chunkdata The chunkdata.
+ * @param size The size.
*
* @return An avi_error.
*/
-avi_error avi_create(const char *filename, const avi_movie_info *info, avi_file **file)
+avi_file::error avi_stream::huffyuv_extract_tables(const std::uint8_t *chunkdata, std::uint32_t size)
{
- avi_file *newfile = nullptr;
- file_error filerr;
- avi_stream *stream;
- avi_error avierr;
- UINT64 length;
+ const std::uint8_t *const chunkend = chunkdata + size;
- /* validate video info */
- if ((info->video_format != 0 && info->video_format != FORMAT_UYVY && info->video_format != FORMAT_VYUY && info->video_format != FORMAT_YUY2) ||
- info->video_width == 0 ||
- info->video_height == 0 ||
- info->video_depth == 0 || info->video_depth % 8 != 0)
- return AVIERR_UNSUPPORTED_VIDEO_FORMAT;
+ /* allocate memory for the data */
+ std::unique_ptr<huffyuv_data> huffyuv;
+ try { huffyuv = std::make_unique<huffyuv_data>(); }
+ catch (...) { return avi_file::error::NO_MEMORY; }
- /* validate audio info */
- if (info->audio_format != 0 ||
- info->audio_channels > MAX_SOUND_CHANNELS ||
- info->audio_samplebits != 16)
- return AVIERR_UNSUPPORTED_AUDIO_FORMAT;
+ /* extract predictor information */
+ if (&chunkdata[40] >= chunkend)
+ return avi_file::error::INVALID_DATA;
+ huffyuv->predictor = chunkdata[40];
- /* allocate the file */
- newfile = (avi_file *)malloc(sizeof(*newfile));
- if (newfile == nullptr)
- return AVIERR_NO_MEMORY;
- memset(newfile, 0, sizeof(*newfile));
- newfile->type = FILETYPE_CREATE;
+ /* make sure it's the left predictor */
+ if ((huffyuv->predictor & ~HUFFYUV_PREDICT_DECORR) != HUFFYUV_PREDICT_LEFT)
+ return avi_file::error::UNSUPPORTED_VIDEO_FORMAT;
- /* open the file */
- filerr = osd_open(filename, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS, &newfile->file, &length);
- if (filerr != FILERR_NONE)
+ /* make sure it's 16bpp YUV data */
+ if (chunkdata[41] != 16)
+ return avi_file::error::UNSUPPORTED_VIDEO_FORMAT;
+ chunkdata += 44;
+
+ /* loop over tables */
+ for (int tabnum = 0; tabnum < 3; tabnum++)
{
- avierr = AVIERR_CANT_OPEN_FILE;
- goto error;
+ huffyuv_table &table = huffyuv->table[tabnum];
+ std::uint32_t curbits, bitadd;
+ std::uint16_t bitsat16 = 0;
+ int offset = 0, bits;
+
+ /* loop until we populate the whole table */
+ while (offset < 256)
+ {
+ int data, shift, count, i;
+
+ /* extract the next run */
+ if (chunkdata >= chunkend)
+ return avi_file::error::INVALID_DATA;
+ data = *chunkdata++;
+ shift = data & 0x1f;
+ count = data >> 5;
+
+ /* zero count means next whole byte is a count */
+ if (count == 0)
+ {
+ if (chunkdata >= chunkend)
+ return avi_file::error::INVALID_DATA;
+ count = *chunkdata++;
+ }
+ for (i = 0; i < count; i++)
+ table.shift[offset++] = shift;
+ }
+
+ /* now determine bit patterns and masks */
+ curbits = 0;
+ for (bits = 31; bits >= 0; bits--)
+ {
+ bitadd = 1 << (32 - bits);
+
+ /* make sure we've cleared out all the bits below */
+ if ((curbits & (bitadd - 1)) != 0)
+ return avi_file::error::INVALID_DATA;
+
+ /* find all entries with this shift count and assign them */
+ for (offset = 0; offset < 256; offset++)
+ if (table.shift[offset] == bits)
+ {
+ table.bits[offset] = curbits;
+ table.mask[offset] = ~(bitadd - 1);
+ curbits += bitadd;
+ }
+
+ /* remember the bit pattern when we complete all the 17-bit codes */
+ if (bits == 17)
+ bitsat16 = curbits >> 16;
+ }
+
+ /* allocate the number of extra lookup tables we need */
+ if (bitsat16 > 0)
+ {
+ try { table.extralookup.resize(bitsat16 * 65536); }
+ catch (...) { return avi_file::error::NO_MEMORY; }
+ for (offset = 0; offset < bitsat16; offset++)
+ table.baselookup[offset] = (offset << 8) | 0;
+ }
+
+ /* then create lookup tables */
+ for (offset = 0; offset < 256; offset++)
+ if (table.shift[offset] > 16)
+ {
+ std::uint16_t *tablebase = &table.extralookup[(table.bits[offset] >> 16) * 65536];
+ std::uint32_t start = table.bits[offset] & 0xffff;
+ std::uint32_t end = start + ((1 << (32 - table.shift[offset])) - 1);
+ while (start <= end)
+ tablebase[start++] = (offset << 8) | (table.shift[offset] - 16);
+ }
+ else if (table.shift[offset] > 0)
+ {
+ std::uint32_t start = table.bits[offset] >> 16;
+ std::uint32_t end = start + ((1 << (16 - table.shift[offset])) - 1);
+ while (start <= end)
+ table.baselookup[start++] = (offset << 8) | table.shift[offset];
+ }
}
- /* copy the movie info */
- newfile->info = *info;
- newfile->info.video_numsamples = 0;
- newfile->info.audio_numsamples = 0;
+ m_huffyuv = std::move(huffyuv);
+ return avi_file::error::NONE;
+}
+
- /* allocate two streams */
- newfile->stream = (avi_stream *)malloc(2 * sizeof(newfile->stream[0]));
- if (newfile->stream == nullptr)
+/*-------------------------------------------------
+ huffyuv_decompress_to_yuy16 - decompress a
+ HuffYUV-encoded frame to a YUY16 bitmap
+-------------------------------------------------*/
+
+/**
+ * @fn static avi_error huffyuv_decompress_to_yuy16(avi_stream *stream, const std::uint8_t *data, std::uint32_t numbytes, bitmap_yuy16 &bitmap)
+ *
+ * @brief Huffyuv decompress to yuy 16.
+ *
+ * @param [in,out] stream If non-null, the stream.
+ * @param data The data.
+ * @param numbytes The numbytes.
+ * @param [in,out] bitmap The bitmap.
+ *
+ * @return An avi_error.
+ */
+
+avi_file::error avi_stream::huffyuv_decompress_to_yuy16(const std::uint8_t *data, std::uint32_t numbytes, bitmap_yuy16 &bitmap) const
+{
+ int prevlines = (m_height > 288) ? 2 : 1;
+ std::uint8_t lastprevy = 0, lastprevcb = 0, lastprevcr = 0;
+ std::uint8_t lasty = 0, lastcb = 0, lastcr = 0;
+ std::uint8_t bitsinbuffer = 0;
+ std::uint32_t bitbuffer = 0;
+ std::uint32_t dataoffs = 0;
+ int x, y;
+
+ /* compressed video */
+ for (y = 0; y < m_height; y++)
{
- avierr = AVIERR_NO_MEMORY;
- goto error;
+ std::uint16_t *dest = &bitmap.pix16(y);
+
+ /* handle the first four bytes independently */
+ x = 0;
+ if (y == 0)
+ {
+ /* first DWORD is stored as YUY2 */
+ lasty = data[dataoffs++];
+ lastcb = data[dataoffs++];
+ *dest++ = (lasty << 8) | lastcb;
+ lasty = data[dataoffs++];
+ lastcr = data[dataoffs++];
+ *dest++ = (lasty << 8) | lastcr;
+ x = 2;
+ }
+
+ /* loop over pixels */
+ for ( ; x < m_width; x++)
+ {
+ huffyuv_table const &ytable = m_huffyuv->table[0];
+ huffyuv_table const &ctable = m_huffyuv->table[1 + (x & 1)];
+ std::uint16_t huffdata;
+ int shift;
+
+ /* fill up the buffer; they store little-endian DWORDs, so we XOR with 3 */
+ while (bitsinbuffer <= 24 && dataoffs < numbytes)
+ {
+ bitbuffer |= data[dataoffs++ ^ 3] << (24 - bitsinbuffer);
+ bitsinbuffer += 8;
+ }
+
+ /* look up the Y component */
+ huffdata = ytable.baselookup[bitbuffer >> 16];
+ shift = huffdata & 0xff;
+ if (shift == 0)
+ {
+ bitsinbuffer -= 16;
+ bitbuffer <<= 16;
+
+ /* fill up the buffer; they store little-endian DWORDs, so we XOR with 3 */
+ while (bitsinbuffer <= 24 && dataoffs < numbytes)
+ {
+ bitbuffer |= data[dataoffs++ ^ 3] << (24 - bitsinbuffer);
+ bitsinbuffer += 8;
+ }
+
+ huffdata = ytable.extralookup[(huffdata >> 8) * 65536 + (bitbuffer >> 16)];
+ shift = huffdata & 0xff;
+ }
+ bitsinbuffer -= shift;
+ bitbuffer <<= shift;
+ std::uint16_t const pixel = huffdata & 0xff00;
+
+ /* fill up the buffer; they store little-endian DWORDs, so we XOR with 3 */
+ while (bitsinbuffer <= 24 && dataoffs < numbytes)
+ {
+ bitbuffer |= data[dataoffs++ ^ 3] << (24 - bitsinbuffer);
+ bitsinbuffer += 8;
+ }
+
+ /* look up the Cb/Cr component */
+ huffdata = ctable.baselookup[bitbuffer >> 16];
+ shift = huffdata & 0xff;
+ if (shift == 0)
+ {
+ bitsinbuffer -= 16;
+ bitbuffer <<= 16;
+
+ /* fill up the buffer; they store little-endian DWORDs, so we XOR with 3 */
+ while (bitsinbuffer <= 24 && dataoffs < numbytes)
+ {
+ bitbuffer |= data[dataoffs++ ^ 3] << (24 - bitsinbuffer);
+ bitsinbuffer += 8;
+ }
+
+ huffdata = ctable.extralookup[(huffdata >> 8) * 65536 + (bitbuffer >> 16)];
+ shift = huffdata & 0xff;
+ }
+ bitsinbuffer -= shift;
+ bitbuffer <<= shift;
+ *dest++ = pixel | (huffdata >> 8);
+ }
}
- memset(newfile->stream, 0, 2 * sizeof(newfile->stream[0]));
-
- /* initialize the video track */
- stream = &newfile->stream[newfile->streams++];
- stream->type = STREAMTYPE_VIDS;
- stream->format = newfile->info.video_format;
- stream->rate = newfile->info.video_timescale;
- stream->scale = newfile->info.video_sampletime;
- stream->width = newfile->info.video_width;
- stream->height = newfile->info.video_height;
- stream->depth = newfile->info.video_depth;
-
- /* initialize the audio track */
- if (newfile->info.audio_channels > 0)
+
+ /* apply deltas */
+ lastprevy = lastprevcb = lastprevcr = 0;
+ for (y = 0; y < m_height; y++)
{
- stream = &newfile->stream[newfile->streams++];
- stream->type = STREAMTYPE_AUDS;
- stream->format = newfile->info.audio_format;
- stream->rate = newfile->info.audio_timescale;
- stream->scale = newfile->info.audio_sampletime;
- stream->channels = newfile->info.audio_channels;
- stream->samplebits = newfile->info.audio_samplebits;
- stream->samplerate = newfile->info.audio_samplerate;
-
- /* initialize the sound buffering */
- avierr = soundbuf_initialize(newfile);
- if (avierr != AVIERR_NONE)
- goto error;
- }
+ std::uint16_t *prevrow = &bitmap.pix16(y - prevlines);
+ std::uint16_t *dest = &bitmap.pix16(y);
- /* write the initial headers */
- avierr = write_initial_headers(newfile);
- if (avierr != AVIERR_NONE)
- goto error;
+ /* handle the first four bytes independently */
+ x = 0;
+ if (y == 0)
+ {
+ /* lasty, lastcr, lastcb are set up previously */
+ x = 2;
+ }
- *file = newfile;
- return AVIERR_NONE;
+ /* left predict or gradient predict */
+ if ((m_huffyuv->predictor & ~HUFFYUV_PREDICT_DECORR) == HUFFYUV_PREDICT_LEFT ||
+ ((m_huffyuv->predictor & ~HUFFYUV_PREDICT_DECORR) == HUFFYUV_PREDICT_GRADIENT))
+ {
+ /* first do left deltas */
+ for ( ; x < m_width; x += 2)
+ {
+ std::uint16_t pixel0 = dest[x + 0];
+ std::uint16_t pixel1 = dest[x + 1];
-error:
- /* clean up after an error */
- if (newfile != nullptr)
- {
- if (newfile->stream != nullptr)
- free(newfile->stream);
- if (newfile->file != nullptr)
+ lasty += pixel0 >> 8;
+ lastcb += pixel0;
+ dest[x + 0] = (lasty << 8) | lastcb;
+
+ lasty += pixel1 >> 8;
+ lastcr += pixel1;
+ dest[x + 1] = (lasty << 8) | lastcr;
+ }
+
+ /* for gradient, we then add in the previous row */
+ if ((m_huffyuv->predictor & ~HUFFYUV_PREDICT_DECORR) == HUFFYUV_PREDICT_GRADIENT && y >= prevlines)
+ for (x = 0; x < m_width; x++)
+ {
+ std::uint16_t curpix = dest[x];
+ std::uint16_t prevpix = prevrow[x];
+ std::uint8_t ysum = (curpix >> 8) + (prevpix >> 8);
+ std::uint8_t csum = curpix + prevpix;
+ dest[x] = (ysum << 8) | csum;
+ }
+ }
+
+ /* median predict on rows > 0 */
+ else if ((m_huffyuv->predictor & ~HUFFYUV_PREDICT_DECORR) == HUFFYUV_PREDICT_MEDIAN && y >= prevlines)
{
- osd_close(newfile->file);
- osd_rmfile(filename);
+ for ( ; x < m_width; x += 2)
+ {
+ std::uint16_t prevpixel0 = prevrow[x + 0];
+ std::uint16_t prevpixel1 = prevrow[x + 1];
+ std::uint16_t pixel0 = dest[x + 0];
+ std::uint16_t pixel1 = dest[x + 1];
+ std::uint8_t a, b, c;
+
+ /* compute previous, above, and (prev + above - above-left) */
+ a = lasty;
+ b = prevpixel0 >> 8;
+ c = lastprevy;
+ lastprevy = b;
+ if (a > b) { std::uint8_t tmp = a; a = b; b = tmp; }
+ if (a > c) { std::uint8_t tmp = a; a = c; c = tmp; }
+ if (b > c) { std::uint8_t tmp = b; b = c; c = tmp; }
+ lasty = (pixel0 >> 8) + b;
+
+ /* compute previous, above, and (prev + above - above-left) */
+ a = lastcb;
+ b = prevpixel0 & 0xff;
+ c = lastprevcb;
+ lastprevcb = b;
+ if (a > b) { std::uint8_t tmp = a; a = b; b = tmp; }
+ if (a > c) { std::uint8_t tmp = a; a = c; c = tmp; }
+ if (b > c) { std::uint8_t tmp = b; b = c; c = tmp; }
+ lastcb = (pixel0 & 0xff) + b;
+ dest[x + 0] = (lasty << 8) | lastcb;
+
+ /* compute previous, above, and (prev + above - above-left) */
+ a = lasty;
+ b = prevpixel1 >> 8;
+ c = lastprevy;
+ lastprevy = b;
+ if (a > b) { std::uint8_t tmp = a; a = b; b = tmp; }
+ if (a > c) { std::uint8_t tmp = a; a = c; c = tmp; }
+ if (b > c) { std::uint8_t tmp = b; b = c; c = tmp; }
+ lasty = (pixel1 >> 8) + b;
+
+ /* compute previous, above, and (prev + above - above-left) */
+ a = lastcr;
+ b = prevpixel1 & 0xff;
+ c = lastprevcr;
+ lastprevcr = b;
+ if (a > b) { std::uint8_t tmp = a; a = b; b = tmp; }
+ if (a > c) { std::uint8_t tmp = a; a = c; c = tmp; }
+ if (b > c) { std::uint8_t tmp = b; b = c; c = tmp; }
+ lastcr = (pixel1 & 0xff) + b;
+ dest[x + 1] = (lasty << 8) | lastcr;
+ }
}
- free(newfile);
}
- return avierr;
+
+ return avi_file::error::NONE;
}
@@ -1029,73 +1481,46 @@ error:
* @return An avi_error.
*/
-avi_error avi_close(avi_file *file)
+avi_file_impl::~avi_file_impl()
{
- avi_error avierr = AVIERR_NONE;
- int strnum;
+ error avierr = error::NONE;
/* if we're creating a new file, finalize it by writing out the non-media chunks */
- if (file->type == FILETYPE_CREATE)
+ if (m_type == FILETYPE_CREATE)
{
/* flush any pending sound data */
- avierr = soundbuf_flush(file, FALSE);
+ avierr = soundbuf_flush(false);
/* close the movi chunk */
- if (avierr == AVIERR_NONE)
- avierr = chunk_close(file);
+ if (avierr == error::NONE)
+ avierr = chunk_close();
/* if this is the first RIFF chunk, write an idx1 */
- if (avierr == AVIERR_NONE && file->riffbase == 0)
- avierr = write_idx1_chunk(file);
+ if (avierr == error::NONE && m_riffbase == 0)
+ avierr = write_idx1_chunk();
/* update the strh and indx chunks for each stream */
- for (strnum = 0; strnum < file->streams; strnum++)
+ for (int strnum = 0; strnum < m_streams.size(); strnum++)
{
- if (avierr == AVIERR_NONE)
- avierr = write_strh_chunk(file, &file->stream[strnum], FALSE);
- if (avierr == AVIERR_NONE)
- avierr = write_indx_chunk(file, &file->stream[strnum], FALSE);
+ if (avierr == error::NONE)
+ avierr = write_strh_chunk(m_streams[strnum], false);
+ if (avierr == error::NONE)
+ avierr = write_indx_chunk(m_streams[strnum], false);
}
/* update the avih chunk */
- if (avierr == AVIERR_NONE)
- avierr = write_avih_chunk(file, FALSE);
+ if (avierr == error::NONE)
+ avierr = write_avih_chunk(false);
/* close the RIFF chunk */
- if (avierr == AVIERR_NONE)
- avierr = chunk_close(file);
+ if (avierr == error::NONE)
+ avierr = chunk_close();
}
/* close the file */
- osd_close(file->file);
-
- /* free the stream-specific data */
- for (strnum = 0; strnum < file->streams; strnum++)
- {
- avi_stream *stream = &file->stream[strnum];
- if (stream->huffyuv != nullptr)
- {
- huffyuv_data *huffyuv = stream->huffyuv;
- int table;
+ m_file.reset();
- for (table = 0; table < ARRAY_LENGTH(huffyuv->table); table++)
- if (huffyuv->table[table].extralookup != nullptr)
- free(huffyuv->table[table].extralookup);
- free(huffyuv);
- }
- if (stream->chunk != nullptr)
- free(stream->chunk);
- }
-
- /* free the file itself */
- if (file->soundbuf != nullptr)
- free(file->soundbuf);
- if (file->stream != nullptr)
- free(file->stream);
- if (file->tempbuffer != nullptr)
- free(file->tempbuffer);
- free(file);
- return avierr;
+ //return avierr;
}
@@ -1111,55 +1536,14 @@ avi_error avi_close(avi_file *file)
* @param [in,out] file If non-null, the file.
*/
-void avi_printf_chunks(avi_file *file)
-{
- printf_chunk_recursive(file, &file->rootchunk, 0);
-}
-
-
-/*-------------------------------------------------
- avi_error_string - get the error string for
- an avi_error
--------------------------------------------------*/
-
-/**
- * @fn const char *avi_error_string(avi_error err)
- *
- * @brief Avi error string.
- *
- * @param err The error.
- *
- * @return null if it fails, else a char*.
- */
-
-const char *avi_error_string(avi_error err)
+void avi_file_impl::printf_chunks()
{
- switch (err)
- {
- case AVIERR_NONE: return "success";
- case AVIERR_END: return "hit end of file";
- case AVIERR_INVALID_DATA: return "invalid data";
- case AVIERR_NO_MEMORY: return "out of memory";
- case AVIERR_READ_ERROR: return "read error";
- case AVIERR_WRITE_ERROR: return "write error";
- case AVIERR_STACK_TOO_DEEP: return "stack overflow";
- case AVIERR_UNSUPPORTED_FEATURE: return "unsupported feature";
- case AVIERR_CANT_OPEN_FILE: return "unable to open file";
- case AVIERR_INCOMPATIBLE_AUDIO_STREAMS: return "found incompatible audio streams";
- case AVIERR_INVALID_SAMPLERATE: return "found invalid sample rate";
- case AVIERR_INVALID_STREAM: return "invalid stream";
- case AVIERR_INVALID_FRAME: return "invalid frame index";
- case AVIERR_INVALID_BITMAP: return "invalid bitmap";
- case AVIERR_UNSUPPORTED_VIDEO_FORMAT: return "unsupported video format";
- case AVIERR_UNSUPPORTED_AUDIO_FORMAT: return "unsupported audio format";
- case AVIERR_EXCEEDED_SOUND_BUFFER: return "sound buffer overflow";
- default: return "undocumented error";
- }
+ printf_chunk_recursive(&m_rootchunk, 0);
}
/*-------------------------------------------------
- avi_get_movie_info - return a pointer to the
+ get_movie_info - return a pointer to the
movie info
-------------------------------------------------*/
@@ -1173,9 +1557,9 @@ const char *avi_error_string(avi_error err)
* @return null if it fails, else an avi_movie_info*.
*/
-const avi_movie_info *avi_get_movie_info(avi_file *file)
+avi_file::movie_info const &avi_file_impl::get_movie_info() const
{
- return &file->info;
+ return m_info;
}
@@ -1185,19 +1569,19 @@ const avi_movie_info *avi_get_movie_info(avi_file *file)
-------------------------------------------------*/
/**
- * @fn UINT32 avi_first_sample_in_frame(avi_file *file, UINT32 framenum)
+ * @fn std::uint32_t avi_first_sample_in_frame(avi_file *file, std::uint32_t framenum)
*
* @brief Avi first sample in frame.
*
* @param [in,out] file If non-null, the file.
* @param framenum The framenum.
*
- * @return An UINT32.
+ * @return An std::uint32_t.
*/
-UINT32 avi_first_sample_in_frame(avi_file *file, UINT32 framenum)
+std::uint32_t avi_file_impl::first_sample_in_frame(std::uint32_t framenum) const
{
- return framenum_to_samplenum(file, framenum);
+ return framenum_to_samplenum(framenum);
}
@@ -1208,7 +1592,7 @@ UINT32 avi_first_sample_in_frame(avi_file *file, UINT32 framenum)
-------------------------------------------------*/
/**
- * @fn avi_error avi_read_video_frame(avi_file *file, UINT32 framenum, bitmap_yuy16 &bitmap)
+ * @fn avi_error avi_read_video_frame(avi_file *file, std::uint32_t framenum, bitmap_yuy16 &bitmap)
*
* @brief Avi read video frame.
*
@@ -1219,54 +1603,51 @@ UINT32 avi_first_sample_in_frame(avi_file *file, UINT32 framenum)
* @return An avi_error.
*/
-avi_error avi_read_video_frame(avi_file *file, UINT32 framenum, bitmap_yuy16 &bitmap)
+avi_file::error avi_file_impl::read_video_frame(std::uint32_t framenum, bitmap_yuy16 &bitmap)
{
- avi_error avierr = AVIERR_NONE;
- UINT32 bytes_read, chunkid;
- file_error filerr;
- avi_stream *stream;
-
/* get the video stream */
- stream = get_video_stream(file);
- if (stream == nullptr)
- return AVIERR_INVALID_STREAM;
+ avi_stream *const stream = get_video_stream();
+ if (!stream)
+ return error::INVALID_STREAM;
/* validate our ability to handle the data */
- if (stream->format != FORMAT_UYVY && stream->format != FORMAT_VYUY && stream->format != FORMAT_YUY2 && stream->format != FORMAT_HFYU)
- return AVIERR_UNSUPPORTED_VIDEO_FORMAT;
+ if (stream->format() != FORMAT_UYVY && stream->format() != FORMAT_VYUY && stream->format() != FORMAT_YUY2 && stream->format() != FORMAT_HFYU)
+ return error::UNSUPPORTED_VIDEO_FORMAT;
/* assume one chunk == one frame */
- if (framenum >= stream->chunks)
- return AVIERR_INVALID_FRAME;
+ if (framenum >= stream->chunks())
+ return error::INVALID_FRAME;
/* we only support YUY-style bitmaps (16bpp) */
- if (bitmap.width() < stream->width || bitmap.height() < stream->height)
- return AVIERR_INVALID_BITMAP;
+ if (bitmap.width() < stream->width() || bitmap.height() < stream->height())
+ return error::INVALID_BITMAP;
/* expand the tempbuffer to hold the data if necessary */
- avierr = expand_tempbuffer(file, stream->chunk[framenum].length);
- if (avierr != AVIERR_NONE)
+ error avierr = error::NONE;
+ avierr = expand_tempbuffer(stream->chunk(framenum).length);
+ if (avierr != error::NONE)
return avierr;
/* read in the data */
- filerr = osd_read(file->file, file->tempbuffer, stream->chunk[framenum].offset, stream->chunk[framenum].length, &bytes_read);
- if (filerr != FILERR_NONE || bytes_read != stream->chunk[framenum].length)
- return AVIERR_READ_ERROR;
+ std::uint32_t bytes_read;
+ osd_file::error const filerr = m_file->read(&m_tempbuffer[0], stream->chunk(framenum).offset, stream->chunk(framenum).length, bytes_read);
+ if (filerr != osd_file::error::NONE || bytes_read != stream->chunk(framenum).length)
+ return error::READ_ERROR;
/* validate this is good data */
- chunkid = fetch_32bits(&file->tempbuffer[0]);
- if (chunkid == get_chunkid_for_stream(file, stream))
+ std::uint32_t const chunkid = fetch_32bits(&m_tempbuffer[0]);
+ if (chunkid == get_chunkid_for_stream(stream))
{
/* HuffYUV-compressed */
- if (stream->format == FORMAT_HFYU)
- avierr = huffyuv_decompress_to_yuy16(stream, file->tempbuffer + 8, stream->chunk[framenum].length - 8, bitmap);
+ if (stream->format() == FORMAT_HFYU)
+ avierr = stream->huffyuv_decompress_to_yuy16(&m_tempbuffer[8], stream->chunk(framenum).length - 8, bitmap);
/* other YUV-compressed */
else
- avierr = yuv_decompress_to_yuy16(stream, file->tempbuffer + 8, stream->chunk[framenum].length - 8, bitmap);
+ avierr = stream->yuv_decompress_to_yuy16(&m_tempbuffer[8], stream->chunk(framenum).length - 8, bitmap);
}
else
- avierr = AVIERR_INVALID_DATA;
+ avierr = error::INVALID_DATA;
return avierr;
}
@@ -1278,7 +1659,7 @@ avi_error avi_read_video_frame(avi_file *file, UINT32 framenum, bitmap_yuy16 &bi
-------------------------------------------------*/
/**
- * @fn avi_error avi_read_sound_samples(avi_file *file, int channel, UINT32 firstsample, UINT32 numsamples, INT16 *output)
+ * @fn avi_error avi_read_sound_samples(avi_file *file, int channel, std::uint32_t firstsample, std::uint32_t numsamples, std::int16_t *output)
*
* @brief Avi read sound samples.
*
@@ -1291,95 +1672,90 @@ avi_error avi_read_video_frame(avi_file *file, UINT32 framenum, bitmap_yuy16 &bi
* @return An avi_error.
*/
-avi_error avi_read_sound_samples(avi_file *file, int channel, UINT32 firstsample, UINT32 numsamples, INT16 *output)
+avi_file::error avi_file_impl::read_sound_samples(int channel, std::uint32_t firstsample, std::uint32_t numsamples, std::int16_t *output)
{
- avi_error avierr = AVIERR_NONE;
- UINT32 bytes_per_sample;
- file_error filerr;
- avi_stream *stream;
- int offset = 0;
-
/* get the audio stream */
- stream = get_audio_stream(file, channel, &offset);
- if (stream == nullptr)
- return AVIERR_INVALID_STREAM;
+ int offset = 0;
+ avi_stream *const stream = get_audio_stream(channel, offset);
+ if (!stream)
+ return error::INVALID_STREAM;
/* validate our ability to handle the data */
- if (stream->format != 0 || (stream->samplebits != 8 && stream->samplebits != 16))
- return AVIERR_UNSUPPORTED_AUDIO_FORMAT;
+ if (stream->format() != 0 || (stream->samplebits() != 8 && stream->samplebits() != 16))
+ return error::UNSUPPORTED_AUDIO_FORMAT;
/* verify we are in range */
- if (firstsample >= stream->samples)
- return AVIERR_INVALID_FRAME;
- if (firstsample + numsamples > stream->samples)
- numsamples = stream->samples - firstsample;
+ if (firstsample >= stream->samples())
+ return error::INVALID_FRAME;
+ if (firstsample + numsamples > stream->samples())
+ numsamples = stream->samples() - firstsample;
/* determine bytes per sample */
- bytes_per_sample = (stream->samplebits / 8) * stream->channels;
+ std::uint32_t const bytes_per_sample = stream->bytes_per_sample();
/* loop until all samples have been extracted */
while (numsamples > 0)
{
- UINT32 chunkbase = 0, chunkend = 0, chunkid;
- UINT32 bytes_read, samples_this_chunk;
+ std::uint32_t chunkbase = 0, chunkend = 0, chunkid;
+ std::uint32_t bytes_read, samples_this_chunk;
int chunknum, sampnum;
/* locate the chunk with the first sample */
- for (chunknum = 0; chunknum < stream->chunks; chunknum++)
+ for (chunknum = 0; chunknum < stream->chunks(); chunknum++)
{
- chunkend = chunkbase + (stream->chunk[chunknum].length - 8) / bytes_per_sample;
+ chunkend = chunkbase + (stream->chunk(chunknum).length - 8) / bytes_per_sample;
if (firstsample < chunkend)
break;
chunkbase = chunkend;
}
/* if we hit the end, fill the rest with silence */
- if (chunknum == stream->chunks)
+ if (chunknum == stream->chunks())
{
- memset(output, 0, numsamples * 2);
+ std::memset(output, 0, numsamples * 2);
break;
}
/* expand the tempbuffer to hold the data if necessary */
- avierr = expand_tempbuffer(file, stream->chunk[chunknum].length);
- if (avierr != AVIERR_NONE)
+ error avierr = expand_tempbuffer(stream->chunk(chunknum).length);
+ if (avierr != error::NONE)
return avierr;
/* read in the data */
- filerr = osd_read(file->file, file->tempbuffer, stream->chunk[chunknum].offset, stream->chunk[chunknum].length, &bytes_read);
- if (filerr != FILERR_NONE || bytes_read != stream->chunk[chunknum].length)
- return AVIERR_READ_ERROR;
+ auto const filerr = m_file->read(&m_tempbuffer[0], stream->chunk(chunknum).offset, stream->chunk(chunknum).length, bytes_read);
+ if (filerr != osd_file::error::NONE || bytes_read != stream->chunk(chunknum).length)
+ return error::READ_ERROR;
/* validate this is good data */
- chunkid = fetch_32bits(&file->tempbuffer[0]);
- if (chunkid != get_chunkid_for_stream(file, stream))
- return AVIERR_INVALID_DATA;
+ chunkid = fetch_32bits(&m_tempbuffer[0]);
+ if (chunkid != get_chunkid_for_stream(stream))
+ return error::INVALID_DATA;
/* determine how many samples to copy */
samples_this_chunk = chunkend - firstsample;
- samples_this_chunk = MIN(samples_this_chunk, numsamples);
+ samples_this_chunk = (std::min)(samples_this_chunk, numsamples);
/* extract 16-bit samples from the chunk */
- if (stream->samplebits == 16)
+ if (stream->samplebits() == 16)
{
- const INT16 *base = (const INT16 *)(file->tempbuffer + 8);
- base += stream->channels * (firstsample - chunkbase) + offset;
+ const std::int16_t *base = reinterpret_cast<const std::int16_t *>(&m_tempbuffer[8]);
+ base += stream->channels() * (firstsample - chunkbase) + offset;
for (sampnum = 0; sampnum < samples_this_chunk; sampnum++)
{
*output++ = LITTLE_ENDIANIZE_INT16(*base);
- base += stream->channels;
+ base += stream->channels();
}
}
/* extract 8-bit samples from the chunk */
- else if (stream->samplebits == 8)
+ else if (stream->samplebits() == 8)
{
- const UINT8 *base = (const UINT8 *)(file->tempbuffer + 8);
- base += stream->channels * (firstsample - chunkbase) + offset;
+ const std::uint8_t *base = &m_tempbuffer[8];
+ base += stream->channels() * (firstsample - chunkbase) + offset;
for (sampnum = 0; sampnum < samples_this_chunk; sampnum++)
{
*output++ = (*base << 8) - 0x8000;
- base += stream->channels;
+ base += stream->channels();
}
}
@@ -1388,7 +1764,7 @@ avi_error avi_read_sound_samples(avi_file *file, int channel, UINT32 firstsample
numsamples -= samples_this_chunk;
}
- return avierr;
+ return error::NONE;
}
@@ -1408,45 +1784,45 @@ avi_error avi_read_sound_samples(avi_file *file, int channel, UINT32 firstsample
* @return An avi_error.
*/
-avi_error avi_append_video_frame(avi_file *file, bitmap_yuy16 &bitmap)
+avi_file::error avi_file_impl::append_video_frame(bitmap_yuy16 &bitmap)
{
- avi_stream *stream = get_video_stream(file);
- avi_error avierr;
- UINT32 maxlength;
+ avi_stream *const stream = get_video_stream();
+ error avierr;
+ std::uint32_t maxlength;
/* validate our ability to handle the data */
- if (stream->format != FORMAT_UYVY && stream->format != FORMAT_VYUY && stream->format != FORMAT_YUY2 && stream->format != FORMAT_HFYU)
- return AVIERR_UNSUPPORTED_VIDEO_FORMAT;
+ if (stream->format() != FORMAT_UYVY && stream->format() != FORMAT_VYUY && stream->format() != FORMAT_YUY2 && stream->format() != FORMAT_HFYU)
+ return error::UNSUPPORTED_VIDEO_FORMAT;
/* write out any sound data first */
- avierr = soundbuf_write_chunk(file, stream->chunks);
- if (avierr != AVIERR_NONE)
+ avierr = soundbuf_write_chunk(stream->chunks());
+ if (avierr != error::NONE)
return avierr;
/* make sure we have enough room */
- maxlength = 2 * stream->width * stream->height;
- avierr = expand_tempbuffer(file, maxlength);
- if (avierr != AVIERR_NONE)
+ maxlength = 2 * stream->width() * stream->height();
+ avierr = expand_tempbuffer(maxlength);
+ if (avierr != error::NONE)
return avierr;
/* now compress the data */
- avierr = yuy16_compress_to_yuy(stream, bitmap, file->tempbuffer, maxlength);
- if (avierr != AVIERR_NONE)
+ avierr = stream->yuy16_compress_to_yuy(bitmap, &m_tempbuffer[0], maxlength);
+ if (avierr != error::NONE)
return avierr;
/* write the data */
- avierr = chunk_write(file, get_chunkid_for_stream(file, stream), file->tempbuffer, maxlength);
- if (avierr != AVIERR_NONE)
+ avierr = chunk_write(get_chunkid_for_stream(stream), &m_tempbuffer[0], maxlength);
+ if (avierr != error::NONE)
return avierr;
/* set the info for this new chunk */
- avierr = set_stream_chunk_info(stream, stream->chunks, file->writeoffs - maxlength - 8, maxlength + 8);
- if (avierr != AVIERR_NONE)
+ avierr = stream->set_chunk_info(stream->chunks(), m_writeoffs - maxlength - 8, maxlength + 8);
+ if (avierr != error::NONE)
return avierr;
- stream->samples = file->info.video_numsamples = stream->chunks;
+ stream->set_samples(m_info.video_numsamples = stream->chunks());
- return AVIERR_NONE;
+ return error::NONE;
}
@@ -1466,49 +1842,49 @@ avi_error avi_append_video_frame(avi_file *file, bitmap_yuy16 &bitmap)
* @return An avi_error.
*/
-avi_error avi_append_video_frame(avi_file *file, bitmap_rgb32 &bitmap)
+avi_file::error avi_file_impl::append_video_frame(bitmap_rgb32 &bitmap)
{
- avi_stream *stream = get_video_stream(file);
- avi_error avierr;
- UINT32 maxlength;
+ avi_stream *const stream = get_video_stream();
+ error avierr;
+ std::uint32_t maxlength;
/* validate our ability to handle the data */
- if (stream->format != 0)
- return AVIERR_UNSUPPORTED_VIDEO_FORMAT;
+ if (stream->format() != 0)
+ return error::UNSUPPORTED_VIDEO_FORMAT;
/* depth must be 24 */
- if (stream->depth != 24)
- return AVIERR_UNSUPPORTED_VIDEO_FORMAT;
+ if (stream->depth() != 24)
+ return error::UNSUPPORTED_VIDEO_FORMAT;
/* write out any sound data first */
- avierr = soundbuf_write_chunk(file, stream->chunks);
- if (avierr != AVIERR_NONE)
+ avierr = soundbuf_write_chunk(stream->chunks());
+ if (avierr != error::NONE)
return avierr;
/* make sure we have enough room */
- maxlength = 3 * stream->width * stream->height;
- avierr = expand_tempbuffer(file, maxlength);
- if (avierr != AVIERR_NONE)
+ maxlength = 3 * stream->width() * stream->height();
+ avierr = expand_tempbuffer(maxlength);
+ if (avierr != error::NONE)
return avierr;
/* copy the RGB data to the destination */
- avierr = rgb32_compress_to_rgb(stream, bitmap, file->tempbuffer, maxlength);
- if (avierr != AVIERR_NONE)
+ avierr = stream->rgb32_compress_to_rgb(bitmap, &m_tempbuffer[0], maxlength);
+ if (avierr != error::NONE)
return avierr;
/* write the data */
- avierr = chunk_write(file, get_chunkid_for_stream(file, stream), file->tempbuffer, maxlength);
- if (avierr != AVIERR_NONE)
+ avierr = chunk_write(get_chunkid_for_stream(stream), &m_tempbuffer[0], maxlength);
+ if (avierr != error::NONE)
return avierr;
/* set the info for this new chunk */
- avierr = set_stream_chunk_info(stream, stream->chunks, file->writeoffs - maxlength - 8, maxlength + 8);
- if (avierr != AVIERR_NONE)
+ avierr = stream->set_chunk_info(stream->chunks(), m_writeoffs - maxlength - 8, maxlength + 8);
+ if (avierr != error::NONE)
return avierr;
- stream->samples = file->info.video_numsamples = stream->chunks;
+ stream->set_samples(m_info.video_numsamples = stream->chunks());
- return AVIERR_NONE;
+ return error::NONE;
}
@@ -1518,7 +1894,7 @@ avi_error avi_append_video_frame(avi_file *file, bitmap_rgb32 &bitmap)
-------------------------------------------------*/
/**
- * @fn avi_error avi_append_sound_samples(avi_file *file, int channel, const INT16 *samples, UINT32 numsamples, UINT32 sampleskip)
+ * @fn avi_error avi_append_sound_samples(avi_file *file, int channel, const std::int16_t *samples, std::uint32_t numsamples, std::uint32_t sampleskip)
*
* @brief Avi append sound samples.
*
@@ -1531,27 +1907,27 @@ avi_error avi_append_video_frame(avi_file *file, bitmap_rgb32 &bitmap)
* @return An avi_error.
*/
-avi_error avi_append_sound_samples(avi_file *file, int channel, const INT16 *samples, UINT32 numsamples, UINT32 sampleskip)
+avi_file::error avi_file_impl::append_sound_samples(int channel, const std::int16_t *samples, std::uint32_t numsamples, std::uint32_t sampleskip)
{
- UINT32 sampoffset = file->soundbuf_chansamples[channel];
- UINT32 sampnum;
+ std::uint32_t sampoffset = m_soundbuf_chansamples[channel];
+ std::uint32_t sampnum;
/* see if we have enough room in the buffer */
- if (sampoffset + numsamples > file->soundbuf_samples)
- return AVIERR_EXCEEDED_SOUND_BUFFER;
+ if (sampoffset + numsamples > m_soundbuf_samples)
+ return error::EXCEEDED_SOUND_BUFFER;
/* append samples to the buffer in little-endian format */
for (sampnum = 0; sampnum < numsamples; sampnum++)
{
- INT16 data = *samples++;
+ std::int16_t data = *samples++;
samples += sampleskip;
data = LITTLE_ENDIANIZE_INT16(data);
- file->soundbuf[sampoffset++ * file->info.audio_channels + channel] = data;
+ m_soundbuf[sampoffset++ * m_info.audio_channels + channel] = data;
}
- file->soundbuf_chansamples[channel] = sampoffset;
+ m_soundbuf_chansamples[channel] = sampoffset;
/* flush any full sound chunks to disk */
- return soundbuf_flush(file, TRUE);
+ return soundbuf_flush(TRUE);
}
@@ -1561,7 +1937,7 @@ avi_error avi_append_sound_samples(avi_file *file, int channel, const INT16 *sam
-------------------------------------------------*/
/**
- * @fn static avi_error read_chunk_data(avi_file *file, const avi_chunk *chunk, UINT8 **buffer)
+ * @fn static avi_error read_chunk_data(avi_file *file, const avi_chunk *chunk, std::uint8_t **buffer)
*
* @brief Reads chunk data.
*
@@ -1572,26 +1948,22 @@ avi_error avi_append_sound_samples(avi_file *file, int channel, const INT16 *sam
* @return The chunk data.
*/
-static avi_error read_chunk_data(avi_file *file, const avi_chunk *chunk, UINT8 **buffer)
+avi_file::error avi_file_impl::read_chunk_data(avi_chunk const &chunk, std::unique_ptr<std::uint8_t []> &buffer)
{
- file_error filerr;
- UINT32 bytes_read;
-
/* allocate memory for the data */
- *buffer = (UINT8 *)malloc(chunk->size);
- if (*buffer == nullptr)
- return AVIERR_NO_MEMORY;
+ try { buffer.reset(new std::uint8_t[chunk.size]); }
+ catch (...) { return error::NO_MEMORY; }
/* read from the file */
- filerr = osd_read(file->file, *buffer, chunk->offset + 8, chunk->size, &bytes_read);
- if (filerr != FILERR_NONE || bytes_read != chunk->size)
+ std::uint32_t bytes_read;
+ osd_file::error const filerr = m_file->read(&buffer[0], chunk.offset + 8, chunk.size, bytes_read);
+ if (filerr != osd_file::error::NONE || bytes_read != chunk.size)
{
- free(*buffer);
- *buffer = nullptr;
- return AVIERR_READ_ERROR;
+ buffer.reset();
+ return error::READ_ERROR;
}
- return AVIERR_NONE;
+ return error::NONE;
}
@@ -1612,12 +1984,12 @@ static avi_error read_chunk_data(avi_file *file, const avi_chunk *chunk, UINT8 *
* @return The first chunk.
*/
-static avi_error get_first_chunk(avi_file *file, const avi_chunk *parent, avi_chunk *newchunk)
+avi_file::error avi_file_impl::get_first_chunk(avi_chunk const *parent, avi_chunk &newchunk)
{
- UINT64 startoffset = (parent != nullptr && parent->type != 0) ? parent->offset + 12 : 0;
+ std::uint64_t startoffset = (parent != nullptr && parent->type != 0) ? parent->offset + 12 : 0;
if (parent != nullptr && parent->type != CHUNKTYPE_LIST && parent->type != CHUNKTYPE_RIFF && parent->type != 0)
- return AVIERR_INVALID_DATA;
- return get_next_chunk_internal(file, parent, newchunk, startoffset);
+ return error::INVALID_DATA;
+ return get_next_chunk_internal(parent, newchunk, startoffset);
}
@@ -1638,10 +2010,10 @@ static avi_error get_first_chunk(avi_file *file, const avi_chunk *parent, avi_ch
* @return The next chunk.
*/
-static avi_error get_next_chunk(avi_file *file, const avi_chunk *parent, avi_chunk *newchunk)
+avi_file::error avi_file_impl::get_next_chunk(avi_chunk const *parent, avi_chunk &newchunk)
{
- UINT64 nextoffset = newchunk->offset + 8 + newchunk->size + (newchunk->size & 1);
- return get_next_chunk_internal(file, parent, newchunk, nextoffset);
+ std::uint64_t nextoffset = newchunk.offset + 8 + newchunk.size + (newchunk.size & 1);
+ return get_next_chunk_internal(parent, newchunk, nextoffset);
}
@@ -1651,7 +2023,7 @@ static avi_error get_next_chunk(avi_file *file, const avi_chunk *parent, avi_chu
-------------------------------------------------*/
/**
- * @fn static avi_error find_first_chunk(avi_file *file, UINT32 findme, const avi_chunk *container, avi_chunk *result)
+ * @fn static avi_error find_first_chunk(avi_file *file, std::uint32_t findme, const avi_chunk *container, avi_chunk *result)
*
* @brief Searches for the first chunk.
*
@@ -1663,13 +2035,13 @@ static avi_error get_next_chunk(avi_file *file, const avi_chunk *parent, avi_chu
* @return The found chunk.
*/
-static avi_error find_first_chunk(avi_file *file, UINT32 findme, const avi_chunk *container, avi_chunk *result)
+avi_file::error avi_file_impl::find_first_chunk(std::uint32_t findme, const avi_chunk *container, avi_chunk &result)
{
- avi_error avierr;
+ error avierr;
- for (avierr = get_first_chunk(file, container, result); avierr == AVIERR_NONE; avierr = get_next_chunk(file, container, result))
- if (result->type == findme)
- return AVIERR_NONE;
+ for (avierr = get_first_chunk(container, result); avierr == error::NONE; avierr = get_next_chunk(container, result))
+ if (result.type == findme)
+ return error::NONE;
return avierr;
}
@@ -1681,7 +2053,7 @@ static avi_error find_first_chunk(avi_file *file, UINT32 findme, const avi_chunk
-------------------------------------------------*/
/**
- * @fn static avi_error find_next_chunk(avi_file *file, UINT32 findme, const avi_chunk *container, avi_chunk *result)
+ * @fn static avi_error find_next_chunk(avi_file *file, std::uint32_t findme, const avi_chunk *container, avi_chunk *result)
*
* @brief Searches for the next chunk.
*
@@ -1693,13 +2065,13 @@ static avi_error find_first_chunk(avi_file *file, UINT32 findme, const avi_chunk
* @return The found chunk.
*/
-static avi_error find_next_chunk(avi_file *file, UINT32 findme, const avi_chunk *container, avi_chunk *result)
+avi_file::error avi_file_impl::find_next_chunk(std::uint32_t findme, const avi_chunk *container, avi_chunk &result)
{
- avi_error avierr;
+ error avierr;
- for (avierr = get_next_chunk(file, container, result); avierr == AVIERR_NONE; avierr = get_next_chunk(file, container, result))
- if (result->type == findme)
- return AVIERR_NONE;
+ for (avierr = get_next_chunk(container, result); avierr == error::NONE; avierr = get_next_chunk(container, result))
+ if (result.type == findme)
+ return error::NONE;
return avierr;
}
@@ -1711,7 +2083,7 @@ static avi_error find_next_chunk(avi_file *file, UINT32 findme, const avi_chunk
-------------------------------------------------*/
/**
- * @fn static avi_error find_first_list(avi_file *file, UINT32 findme, const avi_chunk *container, avi_chunk *result)
+ * @fn static avi_error find_first_list(avi_file *file, std::uint32_t findme, const avi_chunk *container, avi_chunk *result)
*
* @brief Searches for the first list.
*
@@ -1723,13 +2095,13 @@ static avi_error find_next_chunk(avi_file *file, UINT32 findme, const avi_chunk
* @return The found list.
*/
-static avi_error find_first_list(avi_file *file, UINT32 findme, const avi_chunk *container, avi_chunk *result)
+avi_file::error avi_file_impl::find_first_list(std::uint32_t findme, const avi_chunk *container, avi_chunk &result)
{
- avi_error avierr;
+ error avierr;
- for (avierr = find_first_chunk(file, CHUNKTYPE_LIST, container, result); avierr == AVIERR_NONE; avierr = find_next_chunk(file, CHUNKTYPE_LIST, container, result))
- if (result->listtype == findme)
- return AVIERR_NONE;
+ for (avierr = find_first_chunk(CHUNKTYPE_LIST, container, result); avierr == error::NONE; avierr = find_next_chunk(CHUNKTYPE_LIST, container, result))
+ if (result.listtype == findme)
+ return error::NONE;
return avierr;
}
@@ -1741,7 +2113,7 @@ static avi_error find_first_list(avi_file *file, UINT32 findme, const avi_chunk
-------------------------------------------------*/
/**
- * @fn static avi_error find_next_list(avi_file *file, UINT32 findme, const avi_chunk *container, avi_chunk *result)
+ * @fn static avi_error find_next_list(avi_file *file, std::uint32_t findme, const avi_chunk *container, avi_chunk *result)
*
* @brief Searches for the next list.
*
@@ -1753,13 +2125,13 @@ static avi_error find_first_list(avi_file *file, UINT32 findme, const avi_chunk
* @return The found list.
*/
-static avi_error find_next_list(avi_file *file, UINT32 findme, const avi_chunk *container, avi_chunk *result)
+avi_file::error avi_file_impl::find_next_list(std::uint32_t findme, const avi_chunk *container, avi_chunk &result)
{
- avi_error avierr;
+ error avierr;
- for (avierr = find_next_chunk(file, CHUNKTYPE_LIST, container, result); avierr == AVIERR_NONE; avierr = find_next_chunk(file, CHUNKTYPE_LIST, container, result))
- if (result->listtype == findme)
- return AVIERR_NONE;
+ for (avierr = find_next_chunk(CHUNKTYPE_LIST, container, result); avierr == error::NONE; avierr = find_next_chunk(CHUNKTYPE_LIST, container, result))
+ if (result.listtype == findme)
+ return error::NONE;
return avierr;
}
@@ -1771,7 +2143,7 @@ static avi_error find_next_list(avi_file *file, UINT32 findme, const avi_chunk *
-------------------------------------------------*/
/**
- * @fn static avi_error get_next_chunk_internal(avi_file *file, const avi_chunk *parent, avi_chunk *newchunk, UINT64 offset)
+ * @fn static avi_error get_next_chunk_internal(avi_file *file, const avi_chunk *parent, avi_chunk *newchunk, std::uint64_t offset)
*
* @brief Gets the next chunk internal.
*
@@ -1783,42 +2155,42 @@ static avi_error find_next_list(avi_file *file, UINT32 findme, const avi_chunk *
* @return The next chunk internal.
*/
-static avi_error get_next_chunk_internal(avi_file *file, const avi_chunk *parent, avi_chunk *newchunk, UINT64 offset)
+avi_file::error avi_file_impl::get_next_chunk_internal(const avi_chunk *parent, avi_chunk &newchunk, std::uint64_t offset)
{
- file_error filerr;
- UINT8 buffer[12];
- UINT32 bytesread;
+ osd_file::error filerr;
+ std::uint8_t buffer[12];
+ std::uint32_t bytesread;
/* NULL parent implies the root */
if (parent == nullptr)
- parent = &file->rootchunk;
+ parent = &m_rootchunk;
/* start at the current offset */
- newchunk->offset = offset;
+ newchunk.offset = offset;
/* if we're past the bounds of the parent, bail */
- if (newchunk->offset + 8 >= parent->offset + 8 + parent->size)
- return AVIERR_END;
+ if (newchunk.offset + 8 >= parent->offset + 8 + parent->size)
+ return error::END;
/* read the header */
- filerr = osd_read(file->file, buffer, newchunk->offset, 8, &bytesread);
- if (filerr != FILERR_NONE || bytesread != 8)
- return AVIERR_INVALID_DATA;
+ filerr = m_file->read(buffer, newchunk.offset, 8, bytesread);
+ if (filerr != osd_file::error::NONE || bytesread != 8)
+ return error::INVALID_DATA;
/* fill in the new chunk */
- newchunk->type = fetch_32bits(&buffer[0]);
- newchunk->size = fetch_32bits(&buffer[4]);
+ newchunk.type = fetch_32bits(&buffer[0]);
+ newchunk.size = fetch_32bits(&buffer[4]);
/* if we are a list, fetch the list type */
- if (newchunk->type == CHUNKTYPE_LIST || newchunk->type == CHUNKTYPE_RIFF)
+ if (newchunk.type == CHUNKTYPE_LIST || newchunk.type == CHUNKTYPE_RIFF)
{
- filerr = osd_read(file->file, &buffer[8], newchunk->offset + 8, 4, &bytesread);
- if (filerr != FILERR_NONE || bytesread != 4)
- return AVIERR_INVALID_DATA;
- newchunk->listtype = fetch_32bits(&buffer[8]);
+ filerr = m_file->read(&buffer[8], newchunk.offset + 8, 4, bytesread);
+ if (filerr != osd_file::error::NONE || bytesread != 4)
+ return error::INVALID_DATA;
+ newchunk.listtype = fetch_32bits(&buffer[8]);
}
- return AVIERR_NONE;
+ return error::NONE;
}
@@ -1836,98 +2208,95 @@ static avi_error get_next_chunk_internal(avi_file *file, const avi_chunk *parent
* @return The movie data.
*/
-static avi_error read_movie_data(avi_file *file)
+avi_file::error avi_file_impl::read_movie_data()
{
avi_chunk riff, hdrl, avih, strl, strh, strf, indx, movi, idx1;
- avi_error avierr;
- int strindex;
+ error avierr;
/* find the RIFF chunk */
- avierr = find_first_chunk(file, CHUNKTYPE_RIFF, nullptr, &riff);
- if (avierr != AVIERR_NONE)
- goto error;
+ avierr = find_first_chunk(CHUNKTYPE_RIFF, nullptr, riff);
+ if (avierr != error::NONE)
+ return avierr;
/* verify that the RIFF type is AVI */
if (riff.listtype != LISTTYPE_AVI)
{
- avierr = AVIERR_INVALID_DATA;
- goto error;
+ avierr = error::INVALID_DATA;
+ return avierr;
}
/* find the hdrl LIST chunk within the RIFF */
- avierr = find_first_list(file, LISTTYPE_HDRL, &riff, &hdrl);
- if (avierr != AVIERR_NONE)
- goto error;
+ avierr = find_first_list(LISTTYPE_HDRL, &riff, hdrl);
+ if (avierr != error::NONE)
+ return avierr;
/* find the avih chunk */
- avierr = find_first_chunk(file, CHUNKTYPE_AVIH, &hdrl, &avih);
- if (avierr != AVIERR_NONE)
- goto error;
+ avierr = find_first_chunk(CHUNKTYPE_AVIH, &hdrl, avih);
+ if (avierr != error::NONE)
+ return avierr;
/* parse the avih chunk */
- avierr = parse_avih_chunk(file, &avih);
- if (avierr != AVIERR_NONE)
- goto error;
+ avierr = parse_avih_chunk(avih);
+ if (avierr != error::NONE)
+ return avierr;
/* loop over strl LIST chunks */
- strindex = 0;
- for (avierr = find_first_list(file, LISTTYPE_STRL, &hdrl, &strl); avierr == AVIERR_NONE; avierr = find_next_list(file, LISTTYPE_STRL, &hdrl, &strl))
+ int strindex = 0;
+ for (avierr = find_first_list(LISTTYPE_STRL, &hdrl, strl); avierr == error::NONE; avierr = find_next_list(LISTTYPE_STRL, &hdrl, strl))
{
/* if we have too many, it's a bad file */
- if (strindex >= file->streams)
- goto error;
+ if (strindex >= m_streams.size())
+ return avierr;
/* find the strh chunk */
- avierr = find_first_chunk(file, CHUNKTYPE_STRH, &strl, &strh);
- if (avierr != AVIERR_NONE)
- goto error;
+ avierr = find_first_chunk(CHUNKTYPE_STRH, &strl, strh);
+ if (avierr != error::NONE)
+ return avierr;
/* parse the data */
- avierr = parse_strh_chunk(file, &file->stream[strindex], &strh);
- if (avierr != AVIERR_NONE)
- goto error;
+ avierr = parse_strh_chunk(m_streams[strindex], strh);
+ if (avierr != error::NONE)
+ return avierr;
/* find the strf chunk */
- avierr = find_first_chunk(file, CHUNKTYPE_STRF, &strl, &strf);
- if (avierr != AVIERR_NONE)
- goto error;
+ avierr = find_first_chunk(CHUNKTYPE_STRF, &strl, strf);
+ if (avierr != error::NONE)
+ return avierr;
/* parse the data */
- avierr = parse_strf_chunk(file, &file->stream[strindex], &strf);
- if (avierr != AVIERR_NONE)
- goto error;
+ avierr = parse_strf_chunk(m_streams[strindex], strf);
+ if (avierr != error::NONE)
+ return avierr;
/* find the indx chunk, if present */
- avierr = find_first_chunk(file, CHUNKTYPE_INDX, &strl, &indx);
- if (avierr == AVIERR_NONE)
- avierr = parse_indx_chunk(file, &file->stream[strindex], &indx);
+ avierr = find_first_chunk(CHUNKTYPE_INDX, &strl, indx);
+ if (avierr == error::NONE)
+ avierr = parse_indx_chunk(m_streams[strindex], indx);
/* next stream */
strindex++;
}
/* normalize the error after parsing the stream headers */
- if (avierr == AVIERR_END)
- avierr = AVIERR_NONE;
- if (avierr != AVIERR_NONE)
- goto error;
+ if (avierr == error::END)
+ avierr = error::NONE;
+ if (avierr != error::NONE)
+ return avierr;
/* find the base of the movi data */
- avierr = find_first_list(file, LISTTYPE_MOVI, &riff, &movi);
- if (avierr != AVIERR_NONE)
- goto error;
+ avierr = find_first_list(LISTTYPE_MOVI, &riff, movi);
+ if (avierr != error::NONE)
+ return avierr;
/* find and parse the idx1 chunk within the RIFF (if present) */
- avierr = find_first_chunk(file, CHUNKTYPE_IDX1, &riff, &idx1);
- if (avierr == AVIERR_NONE)
- avierr = parse_idx1_chunk(file, movi.offset + 8, &idx1);
- if (avierr != AVIERR_NONE)
- goto error;
+ avierr = find_first_chunk(CHUNKTYPE_IDX1, &riff, idx1);
+ if (avierr == error::NONE)
+ avierr = parse_idx1_chunk(movi.offset + 8, idx1);
+ if (avierr != error::NONE)
+ return avierr;
/* now extract the movie info */
- avierr = extract_movie_info(file);
-
-error:
+ avierr = extract_movie_info();
return avierr;
}
@@ -1947,59 +2316,55 @@ error:
* @return The extracted movie information.
*/
-static avi_error extract_movie_info(avi_file *file)
+avi_file::error avi_file_impl::extract_movie_info()
{
- //avi_stream *audiostream;
avi_stream *stream;
+ int offset;
/* get the video stream */
- stream = get_video_stream(file);
+ stream = get_video_stream();
if (stream != nullptr)
{
/* fill in the info */
- file->info.video_format = stream->format;
- file->info.video_timescale = stream->rate;
- file->info.video_sampletime = stream->scale;
- file->info.video_numsamples = stream->samples;
- file->info.video_width = stream->width;
- file->info.video_height = stream->height;
+ m_info.video_format = stream->format();
+ m_info.video_timescale = stream->rate();
+ m_info.video_sampletime = stream->scale();
+ m_info.video_numsamples = stream->samples();
+ m_info.video_width = stream->width();
+ m_info.video_height = stream->height();
}
/* get the first audio stream */
- stream = get_audio_stream(file, 0, nullptr);
+ stream = get_audio_stream(0, offset);
if (stream != nullptr)
{
/* fill in the info */
- file->info.audio_format = stream->format;
- file->info.audio_timescale = stream->rate;
- file->info.audio_sampletime = stream->scale;
- file->info.audio_numsamples = stream->samples;
- file->info.audio_channels = 1;
- file->info.audio_samplebits = stream->samplebits;
- file->info.audio_samplerate = stream->samplerate;
+ m_info.audio_format = stream->format();
+ m_info.audio_timescale = stream->rate();
+ m_info.audio_sampletime = stream->scale();
+ m_info.audio_numsamples = stream->samples();
+ m_info.audio_channels = 1;
+ m_info.audio_samplebits = stream->samplebits();
+ m_info.audio_samplerate = stream->samplerate();
}
/* now make sure all other audio streams are valid */
- //audiostream = stream;
- while (1)
+ while (nullptr != (stream = get_audio_stream(m_info.audio_channels, offset)))
{
/* get the stream info */
- stream = get_audio_stream(file, file->info.audio_channels, nullptr);
- if (stream == nullptr)
- break;
- file->info.audio_channels++;
+ m_info.audio_channels++;
/* verify compatibility */
- if (file->info.audio_format != stream->format ||
- file->info.audio_timescale != stream->rate ||
- file->info.audio_sampletime != stream->scale ||
- file->info.audio_numsamples != stream->samples ||
- file->info.audio_samplebits != stream->samplebits ||
- file->info.audio_samplerate != stream->samplerate)
- return AVIERR_INCOMPATIBLE_AUDIO_STREAMS;
+ if (m_info.audio_format != stream->format() ||
+ m_info.audio_timescale != stream->rate() ||
+ m_info.audio_sampletime != stream->scale() ||
+ m_info.audio_numsamples != stream->samples() ||
+ m_info.audio_samplebits != stream->samplebits() ||
+ m_info.audio_samplerate != stream->samplerate())
+ return error::INCOMPATIBLE_AUDIO_STREAMS;
}
- return AVIERR_NONE;
+ return error::NONE;
}
@@ -2019,28 +2384,21 @@ static avi_error extract_movie_info(avi_file *file)
* @return An avi_error.
*/
-static avi_error parse_avih_chunk(avi_file *file, avi_chunk *avih)
+avi_file::error avi_file_impl::parse_avih_chunk(avi_chunk const &avih)
{
- UINT8 *chunkdata = nullptr;
- avi_error avierr;
-
/* read the data */
- avierr = read_chunk_data(file, avih, &chunkdata);
- if (avierr != AVIERR_NONE)
- goto error;
+ std::unique_ptr<std::uint8_t []> chunkdata;
+ error avierr = read_chunk_data(avih, chunkdata);
+ if (avierr != error::NONE)
+ return avierr;
/* extract the data */
- file->streams = fetch_32bits(&chunkdata[24]);
+ std::uint32_t const streams = fetch_32bits(&chunkdata[24]);
/* allocate memory for the streams */
- file->stream = (avi_stream *)malloc(sizeof(*file->stream) * file->streams);
- if (file->stream == nullptr)
- goto error;
- memset(file->stream, 0, sizeof(*file->stream) * file->streams);
+ m_streams.clear();
+ m_streams.resize(streams);
-error:
- if (chunkdata != nullptr)
- free(chunkdata);
return avierr;
}
@@ -2062,26 +2420,16 @@ error:
* @return An avi_error.
*/
-static avi_error parse_strh_chunk(avi_file *file, avi_stream *stream, avi_chunk *strh)
+avi_file::error avi_file_impl::parse_strh_chunk(avi_stream &stream, avi_chunk const &strh)
{
- UINT8 *chunkdata = nullptr;
- avi_error avierr;
-
/* read the data */
- avierr = read_chunk_data(file, strh, &chunkdata);
- if (avierr != AVIERR_NONE)
- goto error;
+ std::unique_ptr<std::uint8_t []> chunkdata;
+ error const avierr = read_chunk_data(strh, chunkdata);
+ if (avierr != error::NONE)
+ return avierr;
/* extract the data */
- stream->type = fetch_32bits(&chunkdata[0]);
- stream->scale = fetch_32bits(&chunkdata[20]);
- stream->rate = fetch_32bits(&chunkdata[24]);
- stream->samples = fetch_32bits(&chunkdata[32]);
-
-error:
- if (chunkdata != nullptr)
- free(chunkdata);
- return avierr;
+ return stream.set_strh_data(&chunkdata[0], strh.size);
}
@@ -2102,43 +2450,17 @@ error:
* @return An avi_error.
*/
-static avi_error parse_strf_chunk(avi_file *file, avi_stream *stream, avi_chunk *strf)
+avi_file::error avi_file_impl::parse_strf_chunk(avi_stream &stream, avi_chunk const &strf)
{
- UINT8 *chunkdata = nullptr;
- avi_error avierr;
+ error avierr;
/* read the data */
- avierr = read_chunk_data(file, strf, &chunkdata);
- if (avierr != AVIERR_NONE)
- goto error;
-
- /* audio and video streams have differing headers */
- if (stream->type == STREAMTYPE_VIDS)
- {
- stream->width = fetch_32bits(&chunkdata[4]);
- stream->height = fetch_32bits(&chunkdata[8]);
- stream->depth = fetch_16bits(&chunkdata[14]);
- stream->format = fetch_32bits(&chunkdata[16]);
-
- /* extra extraction for HuffYUV data */
- if (stream->format == FORMAT_HFYU && strf->size >= 56)
- {
- avierr = huffyuv_extract_tables(stream, chunkdata, strf->size);
- if (avierr != AVIERR_NONE)
- goto error;
- }
- }
- else if (stream->type == STREAMTYPE_AUDS)
- {
- stream->channels = fetch_16bits(&chunkdata[2]);
- stream->samplebits = fetch_16bits(&chunkdata[14]);
- stream->samplerate = fetch_32bits(&chunkdata[4]);
- }
+ std::unique_ptr<std::uint8_t []> chunkdata;
+ avierr = read_chunk_data(strf, chunkdata);
+ if (avierr != error::NONE)
+ return avierr;
-error:
- if (chunkdata != nullptr)
- free(chunkdata);
- return avierr;
+ return stream.set_strf_data(&chunkdata[0], strf.size);
}
@@ -2158,50 +2480,46 @@ error:
* @return An avi_error.
*/
-static avi_error parse_indx_chunk(avi_file *file, avi_stream *stream, avi_chunk *strf)
+avi_file::error avi_file_impl::parse_indx_chunk(avi_stream &stream, avi_chunk const &strf)
{
- UINT32 entries, entry;
- UINT8 *chunkdata = nullptr;
- UINT16 longs_per_entry;
- UINT8 type;
- UINT64 baseoffset;
- avi_error avierr;
+ error avierr;
/* read the data */
- avierr = read_chunk_data(file, strf, &chunkdata);
- if (avierr != AVIERR_NONE)
- goto error;
+ std::unique_ptr<std::uint8_t []> chunkdata;
+ avierr = read_chunk_data(strf, chunkdata);
+ if (avierr != error::NONE)
+ return avierr;
/* extract the data */
- longs_per_entry = fetch_16bits(&chunkdata[0]);
+ std::uint16_t const longs_per_entry = fetch_16bits(&chunkdata[0]);
//subtype = chunkdata[2];
- type = chunkdata[3];
- entries = fetch_32bits(&chunkdata[4]);
+ std::uint8_t const type = chunkdata[3];
+ std::uint32_t const entries = fetch_32bits(&chunkdata[4]);
//id = fetch_32bits(&chunkdata[8]);
- baseoffset = fetch_64bits(&chunkdata[12]);
+ std::uint64_t const baseoffset = fetch_64bits(&chunkdata[12]);
/* if this is a superindex, loop over entries and call ourselves recursively */
if (type == AVI_INDEX_OF_INDEXES)
{
/* validate the size of each entry */
if (longs_per_entry != 4)
- return AVIERR_INVALID_DATA;
+ return error::INVALID_DATA;
/* loop over entries and create subchunks for each */
- for (entry = 0; entry < entries; entry++)
+ for (std::uint32_t entry = 0; entry < entries; entry++)
{
- const UINT8 *base = &chunkdata[24 + entry * 16];
- file_error filerr;
+ const std::uint8_t *base = &chunkdata[24 + entry * 16];
+ osd_file::error filerr;
avi_chunk subchunk;
- UINT32 bytes_read;
- UINT8 buffer[8];
+ std::uint32_t bytes_read;
+ std::uint8_t buffer[8];
/* go read the subchunk */
subchunk.offset = fetch_64bits(&base[0]);
- filerr = osd_read(file->file, buffer, subchunk.offset, sizeof(buffer), &bytes_read);
- if (filerr != FILERR_NONE || bytes_read != sizeof(buffer))
+ filerr = m_file->read(buffer, subchunk.offset, sizeof(buffer), bytes_read);
+ if (filerr != osd_file::error::NONE || bytes_read != sizeof(buffer))
{
- avierr = AVIERR_READ_ERROR;
+ avierr = error::READ_ERROR;
break;
}
@@ -2210,8 +2528,8 @@ static avi_error parse_indx_chunk(avi_file *file, avi_stream *stream, avi_chunk
subchunk.size = fetch_32bits(&buffer[4]);
/* recursively parse each referenced chunk; stop if we hit an error */
- avierr = parse_indx_chunk(file, stream, &subchunk);
- if (avierr != AVIERR_NONE)
+ avierr = parse_indx_chunk(stream, subchunk);
+ if (avierr != error::NONE)
break;
}
}
@@ -2221,25 +2539,22 @@ static avi_error parse_indx_chunk(avi_file *file, avi_stream *stream, avi_chunk
{
/* validate the size of each entry */
if (longs_per_entry != 2 && longs_per_entry != 3)
- return AVIERR_INVALID_DATA;
+ return error::INVALID_DATA;
/* loop over entries and parse out the data */
- for (entry = 0; entry < entries; entry++)
+ for (std::uint32_t entry = 0; entry < entries; entry++)
{
- const UINT8 *base = &chunkdata[24 + entry * 4 * longs_per_entry];
- UINT32 offset = fetch_32bits(&base[0]);
- UINT32 size = fetch_32bits(&base[4]) & 0x7fffffff; // bit 31 == NOT a keyframe
+ const std::uint8_t *base = &chunkdata[24 + entry * 4 * longs_per_entry];
+ std::uint32_t offset = fetch_32bits(&base[0]);
+ std::uint32_t size = fetch_32bits(&base[4]) & 0x7fffffff; // bit 31 == NOT a keyframe
/* set the info for this chunk and advance */
- avierr = set_stream_chunk_info(stream, stream->chunks++, baseoffset + offset - 8, size + 8);
- if (avierr != AVIERR_NONE)
+ avierr = stream.set_chunk_info(stream.chunks(), baseoffset + offset - 8, size + 8);
+ if (avierr != error::NONE)
break;
}
}
-error:
- if (chunkdata != nullptr)
- free(chunkdata);
return avierr;
}
@@ -2249,7 +2564,7 @@ error:
-------------------------------------------------*/
/**
- * @fn static avi_error parse_idx1_chunk(avi_file *file, UINT64 baseoffset, avi_chunk *idx1)
+ * @fn static avi_error parse_idx1_chunk(avi_file *file, std::uint64_t baseoffset, avi_chunk *idx1)
*
* @brief Parse index 1 chunk.
*
@@ -2260,48 +2575,39 @@ error:
* @return An avi_error.
*/
-static avi_error parse_idx1_chunk(avi_file *file, UINT64 baseoffset, avi_chunk *idx1)
+avi_file::error avi_file_impl::parse_idx1_chunk(std::uint64_t baseoffset, avi_chunk const &idx1)
{
- UINT8 *chunkdata = nullptr;
- avi_error avierr;
- UINT32 entries;
- UINT32 entry;
+ error avierr;
/* read the data */
- avierr = read_chunk_data(file, idx1, &chunkdata);
- if (avierr != AVIERR_NONE)
- goto error;
+ std::unique_ptr<std::uint8_t []> chunkdata;
+ avierr = read_chunk_data(idx1, chunkdata);
+ if (avierr != error::NONE)
+ return avierr;
/* loop over entries */
- entries = idx1->size / 16;
- for (entry = 0; entry < entries; entry++)
+ std::uint32_t const entries = idx1.size / 16;
+ for (std::uint32_t entry = 0; entry < entries; entry++)
{
- const UINT8 *base = &chunkdata[entry * 16];
- UINT32 chunkid = fetch_32bits(&base[0]);
- UINT32 offset = fetch_32bits(&base[8]);
- UINT32 size = fetch_32bits(&base[12]);
- avi_stream *stream;
+ std::uint8_t const *const base = &chunkdata[entry * 16];
+ std::uint32_t const chunkid = fetch_32bits(&base[0]);
+ std::uint32_t const offset = fetch_32bits(&base[8]);
+ std::uint32_t const size = fetch_32bits(&base[12]);
int streamnum;
/* determine the stream index */
streamnum = ((chunkid >> 8) & 0xff) - '0';
streamnum += 10 * ((chunkid & 0xff) - '0');
- if (streamnum >= file->streams)
- {
- avierr = AVIERR_INVALID_DATA;
- goto error;
- }
- stream = &file->stream[streamnum];
+ if (streamnum >= m_streams.size())
+ return error::INVALID_DATA;
+ avi_stream &stream = m_streams[streamnum];
/* set the appropriate entry */
- avierr = set_stream_chunk_info(stream, stream->chunks++, baseoffset + offset, size + 8);
- if (avierr != AVIERR_NONE)
- goto error;
+ avierr = stream.set_chunk_info(stream.chunks(), baseoffset + offset, size + 8);
+ if (avierr != error::NONE)
+ return avierr;
}
-error:
- if (chunkdata != nullptr)
- free(chunkdata);
return avierr;
}
@@ -2311,7 +2617,7 @@ error:
-------------------------------------------------*/
/**
- * @fn static avi_error chunk_open(avi_file *file, UINT32 type, UINT32 listtype, UINT32 estlength)
+ * @fn static avi_error chunk_open(avi_file *file, std::uint32_t type, std::uint32_t listtype, std::uint32_t estlength)
*
* @brief Queries if a given chunk open.
*
@@ -2323,57 +2629,55 @@ error:
* @return An avi_error.
*/
-static avi_error chunk_open(avi_file *file, UINT32 type, UINT32 listtype, UINT32 estlength)
+avi_file::error avi_file_impl::chunk_open(std::uint32_t type, std::uint32_t listtype, std::uint32_t estlength)
{
- file_error filerr;
- avi_chunk *chunk;
- UINT32 written;
-
/* if we're out of stack entries, bail */
- if (file->chunksp >= ARRAY_LENGTH(file->chunkstack))
- return AVIERR_STACK_TOO_DEEP;
- chunk = &file->chunkstack[file->chunksp++];
+ if (m_chunksp >= m_chunkstack.size())
+ return error::STACK_TOO_DEEP;
+ avi_chunk &chunk = m_chunkstack[m_chunksp++];
/* set up the chunk information */
- chunk->offset = file->writeoffs;
- chunk->size = estlength;
- chunk->type = type;
- chunk->listtype = listtype;
+ chunk.offset = m_writeoffs;
+ chunk.size = estlength;
+ chunk.type = type;
+ chunk.listtype = listtype;
/* non-list types */
if (type != CHUNKTYPE_RIFF && type != CHUNKTYPE_LIST)
{
- UINT8 buffer[8];
+ std::uint8_t buffer[8];
/* populate the header */
- put_32bits(&buffer[0], chunk->type);
- put_32bits(&buffer[4], chunk->size);
+ put_32bits(&buffer[0], chunk.type);
+ put_32bits(&buffer[4], chunk.size);
/* write the header */
- filerr = osd_write(file->file, buffer, file->writeoffs, sizeof(buffer), &written);
- if (filerr != FILERR_NONE || written != sizeof(buffer))
- return AVIERR_WRITE_ERROR;
- file->writeoffs += written;
+ std::uint32_t written;
+ osd_file::error const filerr = m_file->write(buffer, m_writeoffs, sizeof(buffer), written);
+ if (filerr != osd_file::error::NONE || written != sizeof(buffer))
+ return error::WRITE_ERROR;
+ m_writeoffs += written;
}
/* list types */
else
{
- UINT8 buffer[12];
+ std::uint8_t buffer[12];
/* populate the header */
- put_32bits(&buffer[0], chunk->type);
- put_32bits(&buffer[4], chunk->size);
- put_32bits(&buffer[8], chunk->listtype);
+ put_32bits(&buffer[0], chunk.type);
+ put_32bits(&buffer[4], chunk.size);
+ put_32bits(&buffer[8], chunk.listtype);
/* write the header */
- filerr = osd_write(file->file, buffer, file->writeoffs, sizeof(buffer), &written);
- if (filerr != FILERR_NONE || written != sizeof(buffer))
- return AVIERR_WRITE_ERROR;
- file->writeoffs += written;
+ std::uint32_t written;
+ osd_file::error const filerr = m_file->write(buffer, m_writeoffs, sizeof(buffer), written);
+ if (filerr != osd_file::error::NONE || written != sizeof(buffer))
+ return error::WRITE_ERROR;
+ m_writeoffs += written;
}
- return AVIERR_NONE;
+ return error::NONE;
}
@@ -2391,32 +2695,31 @@ static avi_error chunk_open(avi_file *file, UINT32 type, UINT32 listtype, UINT32
* @return An avi_error.
*/
-static avi_error chunk_close(avi_file *file)
+avi_file::error avi_file_impl::chunk_close()
{
- avi_chunk *chunk = &file->chunkstack[--file->chunksp];
- UINT64 chunksize = file->writeoffs - (chunk->offset + 8);
- UINT32 written;
+ avi_chunk const &chunk = m_chunkstack[--m_chunksp];
+ std::uint64_t const chunksize = m_writeoffs - (chunk.offset + 8);
/* error if we don't fit into 32 bits */
- if (chunksize != (UINT32)chunksize)
- return AVIERR_INVALID_DATA;
+ if (chunksize != std::uint32_t(chunksize))
+ return error::INVALID_DATA;
/* write the final size if it is different from the guess */
- if (chunk->size != chunksize)
+ if (chunk.size != chunksize)
{
- file_error filerr;
- UINT8 buffer[4];
+ std::uint8_t buffer[4];
- put_32bits(&buffer[0], (UINT32)chunksize);
- filerr = osd_write(file->file, buffer, chunk->offset + 4, sizeof(buffer), &written);
- if (filerr != FILERR_NONE || written != sizeof(buffer))
- return AVIERR_WRITE_ERROR;
+ put_32bits(&buffer[0], std::uint32_t(chunksize));
+ std::uint32_t written;
+ osd_file::error const filerr = m_file->write(buffer, chunk.offset + 4, sizeof(buffer), written);
+ if (filerr != osd_file::error::NONE || written != sizeof(buffer))
+ return error::WRITE_ERROR;
}
/* round up to the next word */
- file->writeoffs += chunksize & 1;
+ m_writeoffs += chunksize & 1;
- return AVIERR_NONE;
+ return error::NONE;
}
@@ -2425,7 +2728,7 @@ static avi_error chunk_close(avi_file *file)
-------------------------------------------------*/
/**
- * @fn static avi_error chunk_write(avi_file *file, UINT32 type, const void *data, UINT32 length)
+ * @fn static avi_error chunk_write(avi_file *file, std::uint32_t type, const void *data, std::uint32_t length)
*
* @brief Chunk write.
*
@@ -2437,67 +2740,63 @@ static avi_error chunk_close(avi_file *file)
* @return An avi_error.
*/
-static avi_error chunk_write(avi_file *file, UINT32 type, const void *data, UINT32 length)
+avi_file::error avi_file_impl::chunk_write(std::uint32_t type, const void *data, std::uint32_t length)
{
- file_error filerr;
- avi_error avierr;
- UINT32 idxreserve;
- UINT32 written;
+ error avierr;
/* if we are the first RIFF, we must reserve enough space for the IDX chunk */
- idxreserve = 0;
- if (file->riffbase == 0 && type != CHUNKTYPE_IDX1)
- idxreserve = compute_idx1_size(file);
+ std::uint32_t const idxreserve = (m_riffbase == 0 && type != CHUNKTYPE_IDX1) ? compute_idx1_size() : 0;
/* if we are getting too big, split the RIFF */
/* note that we ignore writes before the current RIFF base, as those are assumed to be
overwrites of a chunk from the previous RIFF */
- if (file->writeoffs >= file->riffbase && file->writeoffs + length + idxreserve - file->riffbase >= MAX_RIFF_SIZE)
+ if ((m_writeoffs >= m_riffbase) && ((m_writeoffs + length + idxreserve - m_riffbase) >= MAX_RIFF_SIZE))
{
/* close the movi list */
- avierr = chunk_close(file);
- if (avierr != AVIERR_NONE)
+ avierr = chunk_close();
+ if (avierr != error::NONE)
return avierr;
/* write the idx1 chunk if this is the first */
- if (file->riffbase == 0)
+ if (m_riffbase == 0)
{
- avierr = write_idx1_chunk(file);
- if (avierr != AVIERR_NONE)
+ avierr = write_idx1_chunk();
+ if (avierr != error::NONE)
return avierr;
}
/* close the RIFF */
- avierr = chunk_close(file);
- if (avierr != AVIERR_NONE)
+ avierr = chunk_close();
+ if (avierr != error::NONE)
return avierr;
/* open a new RIFF */
- file->riffbase = file->writeoffs;
- avierr = chunk_open(file, CHUNKTYPE_RIFF, LISTTYPE_AVIX, 0);
- if (avierr != AVIERR_NONE)
+ m_riffbase = m_writeoffs;
+ avierr = chunk_open(CHUNKTYPE_RIFF, LISTTYPE_AVIX, 0);
+ if (avierr != error::NONE)
return avierr;
/* open a nested movi list */
- file->saved_movi_offset = file->writeoffs;
- avierr = chunk_open(file, CHUNKTYPE_LIST, LISTTYPE_MOVI, 0);
- if (avierr != AVIERR_NONE)
+ m_saved_movi_offset = m_writeoffs;
+ avierr = chunk_open(CHUNKTYPE_LIST, LISTTYPE_MOVI, 0);
+ if (avierr != error::NONE)
return avierr;
}
/* open the chunk */
- avierr = chunk_open(file, type, 0, length);
- if (avierr != AVIERR_NONE)
+ avierr = chunk_open(type, 0, length);
+ if (avierr != error::NONE)
return avierr;
/* write the data */
- filerr = osd_write(file->file, data, file->writeoffs, length, &written);
- if (filerr != FILERR_NONE || written != length)
- return AVIERR_WRITE_ERROR;
- file->writeoffs += written;
+ std::uint32_t written;
+ osd_file::error const filerr = m_file->write(data, m_writeoffs, length, written);
+ if (filerr != osd_file::error::NONE || written != length)
+ return error::WRITE_ERROR;
+ m_writeoffs += written;
/* close the chunk */
- return chunk_close(file);
+ return chunk_close();
}
@@ -2509,7 +2808,7 @@ static avi_error chunk_write(avi_file *file, UINT32 type, const void *data, UINT
-------------------------------------------------*/
/**
- * @fn static avi_error chunk_overwrite(avi_file *file, UINT32 type, const void *data, UINT32 length, UINT64 *offset, int initial_write)
+ * @fn static avi_error chunk_overwrite(avi_file *file, std::uint32_t type, const void *data, std::uint32_t length, std::uint64_t *offset, int initial_write)
*
* @brief Chunk overwrite.
*
@@ -2523,28 +2822,27 @@ static avi_error chunk_write(avi_file *file, UINT32 type, const void *data, UINT
* @return An avi_error.
*/
-static avi_error chunk_overwrite(avi_file *file, UINT32 type, const void *data, UINT32 length, UINT64 *offset, int initial_write)
+avi_file::error avi_file_impl::chunk_overwrite(std::uint32_t type, const void *data, std::uint32_t length, std::uint64_t &offset, bool initial_write)
{
- UINT64 savedoffset = 0;
- avi_error avierr;
+ std::uint64_t savedoffset = 0;
/* if this is our initial write, save the offset */
if (initial_write)
- *offset = file->writeoffs;
+ offset = m_writeoffs;
/* otherwise, remember the current write offset and replace it with the original */
else
{
- savedoffset = file->writeoffs;
- file->writeoffs = *offset;
+ savedoffset = m_writeoffs;
+ m_writeoffs = offset;
}
/* write the chunk */
- avierr = chunk_write(file, type, data, length);
+ error const avierr = chunk_write(type, data, length);
/* if this isn't the initial write, restore the previous offset */
if (!initial_write)
- file->writeoffs = savedoffset;
+ m_writeoffs = savedoffset;
return avierr;
}
@@ -2565,67 +2863,66 @@ static avi_error chunk_overwrite(avi_file *file, UINT32 type, const void *data,
* @return An avi_error.
*/
-static avi_error write_initial_headers(avi_file *file)
+avi_file::error avi_file_impl::write_initial_headers()
{
- avi_error avierr;
- int strnum;
+ error avierr;
/* reset the write pointer */
- file->writeoffs = 0;
+ m_writeoffs = 0;
/* open a RIFF chunk */
- avierr = chunk_open(file, CHUNKTYPE_RIFF, LISTTYPE_AVI, 0);
- if (avierr != AVIERR_NONE)
+ avierr = chunk_open(CHUNKTYPE_RIFF, LISTTYPE_AVI, 0);
+ if (avierr != error::NONE)
return avierr;
/* open a hdlr LIST */
- avierr = chunk_open(file, CHUNKTYPE_LIST, LISTTYPE_HDRL, 0);
- if (avierr != AVIERR_NONE)
+ avierr = chunk_open(CHUNKTYPE_LIST, LISTTYPE_HDRL, 0);
+ if (avierr != error::NONE)
return avierr;
/* write an avih chunk */
- avierr = write_avih_chunk(file, TRUE);
- if (avierr != AVIERR_NONE)
+ avierr = write_avih_chunk(true);
+ if (avierr != error::NONE)
return avierr;
/* for each stream, write a strl LIST */
- for (strnum = 0; strnum < file->streams; strnum++)
+ for (int strnum = 0; strnum < m_streams.size(); strnum++)
{
/* open a strl LIST */
- avierr = chunk_open(file, CHUNKTYPE_LIST, LISTTYPE_STRL, 0);
- if (avierr != AVIERR_NONE)
+ avierr = chunk_open(CHUNKTYPE_LIST, LISTTYPE_STRL, 0);
+ if (avierr != error::NONE)
return avierr;
/* write the strh chunk */
- avierr = write_strh_chunk(file, &file->stream[strnum], TRUE);
- if (avierr != AVIERR_NONE)
+ avierr = write_strh_chunk(m_streams[strnum], true);
+ if (avierr != error::NONE)
return avierr;
/* write the strf chunk */
- avierr = write_strf_chunk(file, &file->stream[strnum]);
- if (avierr != AVIERR_NONE)
+ avierr = write_strf_chunk(m_streams[strnum]);
+ if (avierr != error::NONE)
return avierr;
/* write the indx chunk */
- avierr = write_indx_chunk(file, &file->stream[strnum], TRUE);
- if (avierr != AVIERR_NONE)
+ avierr = write_indx_chunk(m_streams[strnum], true);
+ if (avierr != error::NONE)
return avierr;
/* close the strl LIST */
- avierr = chunk_close(file);
- if (avierr != AVIERR_NONE)
+ avierr = chunk_close();
+ if (avierr != error::NONE)
return avierr;
}
/* close the hdlr LIST */
- avierr = chunk_close(file);
- if (avierr != AVIERR_NONE)
+ avierr = chunk_close();
+ if (avierr != error::NONE)
return avierr;
/* open a movi LIST */
- file->saved_movi_offset = file->writeoffs;
- avierr = chunk_open(file, CHUNKTYPE_LIST, LISTTYPE_MOVI, 0);
- if (avierr != AVIERR_NONE)
+ m_saved_movi_offset = m_writeoffs;
+ avierr = chunk_open(CHUNKTYPE_LIST, LISTTYPE_MOVI, 0);
+ if (avierr != error::NONE)
return avierr;
return avierr;
@@ -2648,23 +2945,23 @@ static avi_error write_initial_headers(avi_file *file)
* @return An avi_error.
*/
-static avi_error write_avih_chunk(avi_file *file, int initial_write)
+avi_file::error avi_file_impl::write_avih_chunk(bool initial_write)
{
- avi_stream *video = get_video_stream(file);
- UINT8 buffer[56];
+ avi_stream *video = get_video_stream();
+ std::uint8_t buffer[56];
/* reset the buffer */
- memset(buffer, 0, sizeof(buffer));
+ std::memset(buffer, 0, sizeof(buffer));
- put_32bits(&buffer[0], 1000000 * (INT64)video->scale / video->rate); /* dwMicroSecPerFrame */
+ put_32bits(&buffer[0], 1000000 * std::int64_t(video->scale()) / video->rate()); /* dwMicroSecPerFrame */
put_32bits(&buffer[12], AVIF_HASINDEX | AVIF_ISINTERLEAVED); /* dwFlags */
- put_32bits(&buffer[16], video->samples); /* dwTotalFrames */
- put_32bits(&buffer[24], file->streams); /* dwStreams */
- put_32bits(&buffer[32], video->width); /* dwWidth */
- put_32bits(&buffer[36], video->height); /* dwHeight */
+ put_32bits(&buffer[16], video->samples()); /* dwTotalFrames */
+ put_32bits(&buffer[24], m_streams.size()); /* dwStreams */
+ put_32bits(&buffer[32], video->width()); /* dwWidth */
+ put_32bits(&buffer[36], video->height()); /* dwHeight */
/* (over)write the chunk */
- return chunk_overwrite(file, CHUNKTYPE_AVIH, buffer, sizeof(buffer), &file->saved_avih_offset, initial_write);
+ return chunk_overwrite(CHUNKTYPE_AVIH, buffer, sizeof(buffer), m_saved_avih_offset, initial_write);
}
@@ -2685,41 +2982,41 @@ static avi_error write_avih_chunk(avi_file *file, int initial_write)
* @return An avi_error.
*/
-static avi_error write_strh_chunk(avi_file *file, avi_stream *stream, int initial_write)
+avi_file::error avi_file_impl::write_strh_chunk(avi_stream &stream, bool initial_write)
{
- UINT8 buffer[56];
+ std::uint8_t buffer[56];
/* reset the buffer */
- memset(buffer, 0, sizeof(buffer));
+ std::memset(buffer, 0, sizeof(buffer));
- put_32bits(&buffer[0], stream->type); /* fccType */
- put_32bits(&buffer[20], stream->scale); /* dwScale */
- put_32bits(&buffer[24], stream->rate); /* dwRate */
- put_32bits(&buffer[32], stream->samples); /* dwLength */
+ put_32bits(&buffer[0], stream.type()); /* fccType */
+ put_32bits(&buffer[20], stream.scale()); /* dwScale */
+ put_32bits(&buffer[24], stream.rate()); /* dwRate */
+ put_32bits(&buffer[32], stream.samples()); /* dwLength */
put_32bits(&buffer[40], 10000); /* dwQuality */
/* video-stream specific data */
- if (stream->type == STREAMTYPE_VIDS)
+ if (stream.type() == STREAMTYPE_VIDS)
{
put_32bits(&buffer[4], /* fccHandler */
- (stream->format == FORMAT_HFYU) ? HANDLER_HFYU : HANDLER_DIB);
+ (stream.format() == FORMAT_HFYU) ? HANDLER_HFYU : HANDLER_DIB);
put_32bits(&buffer[36], /* dwSuggestedBufferSize */
- stream->width * stream->height * 4);
- put_16bits(&buffer[52], stream->width); /* rcFrame.right */
- put_16bits(&buffer[54], stream->height); /* rcFrame.bottom */
+ stream.width() * stream.height() * 4);
+ put_16bits(&buffer[52], stream.width()); /* rcFrame.right */
+ put_16bits(&buffer[54], stream.height()); /* rcFrame.bottom */
}
/* audio-stream specific data */
- if (stream->type == STREAMTYPE_AUDS)
+ if (stream.type() == STREAMTYPE_AUDS)
{
put_32bits(&buffer[36], /* dwSuggestedBufferSize */
- stream->samplerate * stream->channels * (stream->samplebits / 8));
+ stream.samplerate() * stream.bytes_per_sample());
put_32bits(&buffer[44], /* dwSampleSize */
- stream->channels * (stream->samplebits / 8));
+ stream.bytes_per_sample());
}
/* write the chunk */
- return chunk_overwrite(file, CHUNKTYPE_STRH, buffer, sizeof(buffer), &stream->saved_strh_offset, initial_write);
+ return chunk_overwrite(CHUNKTYPE_STRH, buffer, sizeof(buffer), stream.saved_strh_offset(), initial_write);
}
@@ -2739,51 +3036,51 @@ static avi_error write_strh_chunk(avi_file *file, avi_stream *stream, int initia
* @return An avi_error.
*/
-static avi_error write_strf_chunk(avi_file *file, avi_stream *stream)
+avi_file::error avi_file_impl::write_strf_chunk(avi_stream const &stream)
{
/* video stream */
- if (stream->type == STREAMTYPE_VIDS)
+ if (stream.type() == STREAMTYPE_VIDS)
{
- UINT8 buffer[40];
+ std::uint8_t buffer[40];
/* reset the buffer */
- memset(buffer, 0, sizeof(buffer));
+ std::memset(buffer, 0, sizeof(buffer));
put_32bits(&buffer[0], sizeof(buffer)); /* biSize */
- put_32bits(&buffer[4], stream->width); /* biWidth */
- put_32bits(&buffer[8], stream->height); /* biHeight */
+ put_32bits(&buffer[4], stream.width()); /* biWidth */
+ put_32bits(&buffer[8], stream.height()); /* biHeight */
put_16bits(&buffer[12], 1); /* biPlanes */
- put_16bits(&buffer[14], stream->depth); /* biBitCount */
- put_32bits(&buffer[16], stream->format); /* biCompression */
+ put_16bits(&buffer[14], stream.depth()); /* biBitCount */
+ put_32bits(&buffer[16], stream.format()); /* biCompression */
put_32bits(&buffer[20], /* biSizeImage */
- stream->width * stream->height * (stream->depth + 7) / 8);
+ stream.width() * stream.height() * (stream.depth() + 7) / 8);
/* write the chunk */
- return chunk_write(file, CHUNKTYPE_STRF, buffer, sizeof(buffer));
+ return chunk_write(CHUNKTYPE_STRF, buffer, sizeof(buffer));
}
/* audio stream */
- if (stream->type == STREAMTYPE_AUDS)
+ if (stream.type() == STREAMTYPE_AUDS)
{
- UINT8 buffer[16];
+ std::uint8_t buffer[16];
/* reset the buffer */
- memset(buffer, 0, sizeof(buffer));
+ std::memset(buffer, 0, sizeof(buffer));
put_16bits(&buffer[0], 1); /* wFormatTag */
- put_16bits(&buffer[2], stream->channels); /* nChannels */
- put_32bits(&buffer[4], stream->samplerate); /* nSamplesPerSec */
+ put_16bits(&buffer[2], stream.channels()); /* nChannels */
+ put_32bits(&buffer[4], stream.samplerate()); /* nSamplesPerSec */
put_32bits(&buffer[8], /* nAvgBytesPerSec */
- stream->samplerate * stream->channels * (stream->samplebits / 8));
+ stream.samplerate() * stream.bytes_per_sample());
put_16bits(&buffer[12], /* nBlockAlign */
- stream->channels * (stream->samplebits / 8));
- put_16bits(&buffer[14], stream->samplebits); /* wBitsPerSample */
+ stream.bytes_per_sample());
+ put_16bits(&buffer[14], stream.samplebits()); /* wBitsPerSample */
/* write the chunk */
- return chunk_write(file, CHUNKTYPE_STRF, buffer, sizeof(buffer));
+ return chunk_write(CHUNKTYPE_STRF, buffer, sizeof(buffer));
}
- return AVIERR_INVALID_DATA;
+ return error::INVALID_DATA;
}
@@ -2804,35 +3101,30 @@ static avi_error write_strf_chunk(avi_file *file, avi_stream *stream)
* @return An avi_error.
*/
-static avi_error write_indx_chunk(avi_file *file, avi_stream *stream, int initial_write)
+avi_file::error avi_file_impl::write_indx_chunk(avi_stream &stream, bool initial_write)
{
- UINT8 buffer[24 + 16 * MAX_AVI_SIZE_IN_GB / 4];
- UINT32 chunkid, indexchunkid;
- UINT32 master_entries = 0;
+ std::uint8_t buffer[24 + 16 * MAX_AVI_SIZE_IN_GB / 4];
+ std::uint32_t master_entries = 0;
/* reset the buffer */
- memset(buffer, 0, sizeof(buffer));
+ std::memset(buffer, 0, sizeof(buffer));
/* construct the chunk ID and index chunk ID */
- chunkid = get_chunkid_for_stream(file, stream);
- indexchunkid = AVI_FOURCC('i', 'x', '0' + (stream - file->stream) / 10, '0' + (stream - file->stream) % 10);
+ std::uint32_t const chunkid = get_chunkid_for_stream(&stream);
+ std::uint32_t const indexchunkid = AVI_FOURCC('i', 'x', '0' + (&stream - &m_streams[0]) / 10, '0' + (&stream - &m_streams[0]) % 10);
/* loop over chunks of 4GB and write out indexes for them first */
- if (!initial_write && file->riffbase != 0)
+ if (!initial_write && m_riffbase != 0)
{
- UINT64 currentbase;
- for (currentbase = 0; currentbase < file->writeoffs; currentbase += FOUR_GB)
+ for (std::uint64_t currentbase = 0; currentbase < m_writeoffs; currentbase += FOUR_GB)
{
- UINT64 currentend = currentbase + FOUR_GB;
- UINT32 chunks_this_index = 0;
- UINT32 bytes_this_index = 0;
- avi_error avierr;
- UINT32 chunknum;
- UINT8 *tempbuf;
+ std::uint64_t const currentend = currentbase + FOUR_GB;
+ std::uint32_t chunks_this_index = 0;
+ std::uint32_t bytes_this_index = 0;
/* count chunks that are in this region */
- for (chunknum = 0; chunknum < stream->chunks; chunknum++)
- if (stream->chunk[chunknum].offset >= currentbase && stream->chunk[chunknum].offset < currentend)
+ for (std::uint32_t chunknum = 0; chunknum < stream.chunks(); chunknum++)
+ if (stream.chunk(chunknum).offset >= currentbase && stream.chunk(chunknum).offset < currentend)
chunks_this_index++;
/* if no chunks, skip */
@@ -2840,10 +3132,10 @@ static avi_error write_indx_chunk(avi_file *file, avi_stream *stream, int initia
continue;
/* allocate memory */
- tempbuf = (UINT8 *)malloc(24 + 8 * chunks_this_index);
- if (tempbuf == nullptr)
- return AVIERR_NO_MEMORY;
- memset(tempbuf, 0, 24 + 8 * chunks_this_index);
+ std::unique_ptr<std::uint8_t []> tempbuf;
+ try { tempbuf.reset(new std::uint8_t[24 + 8 * chunks_this_index]); }
+ catch (...) { return error::NO_MEMORY; }
+ std::memset(&tempbuf[0], 0, 24 + 8 * chunks_this_index);
/* make a regular index */
put_16bits(&tempbuf[0], 2); /* wLongsPerEntry */
@@ -2855,28 +3147,27 @@ static avi_error write_indx_chunk(avi_file *file, avi_stream *stream, int initia
/* now fill in the indexes */
chunks_this_index = 0;
- for (chunknum = 0; chunknum < stream->chunks; chunknum++)
- if (stream->chunk[chunknum].offset >= currentbase && stream->chunk[chunknum].offset < currentend)
+ for (std::uint32_t chunknum = 0; chunknum < stream.chunks(); chunknum++)
+ if (stream.chunk(chunknum).offset >= currentbase && stream.chunk(chunknum).offset < currentend)
{
- put_32bits(&tempbuf[24 + 8 * chunks_this_index + 0], stream->chunk[chunknum].offset + 8 - currentbase);
- put_32bits(&tempbuf[24 + 8 * chunks_this_index + 4], stream->chunk[chunknum].length - 8);
- bytes_this_index += stream->chunk[chunknum].length;
+ put_32bits(&tempbuf[24 + 8 * chunks_this_index + 0], stream.chunk(chunknum).offset + 8 - currentbase);
+ put_32bits(&tempbuf[24 + 8 * chunks_this_index + 4], stream.chunk(chunknum).length - 8);
+ bytes_this_index += stream.chunk(chunknum).length;
chunks_this_index++;
}
/* write the offset of this index to the master table */
- put_64bits(&buffer[24 + 16 * master_entries + 0], file->writeoffs);
+ put_64bits(&buffer[24 + 16 * master_entries + 0], m_writeoffs);
put_32bits(&buffer[24 + 16 * master_entries + 8], 24 + 8 * chunks_this_index + 8);
- if (stream->type == STREAMTYPE_VIDS)
+ if (stream.type() == STREAMTYPE_VIDS)
put_32bits(&buffer[24 + 16 * master_entries + 12], chunks_this_index);
- else if (stream->type == STREAMTYPE_AUDS)
- put_32bits(&buffer[24 + 16 * master_entries + 12], bytes_this_index / ((stream->samplebits / 8) * stream->channels));
+ else if (stream.type() == STREAMTYPE_AUDS)
+ put_32bits(&buffer[24 + 16 * master_entries + 12], bytes_this_index / stream.bytes_per_sample());
master_entries++;
/* write the index */
- avierr = chunk_write(file, indexchunkid, tempbuf, 24 + 8 * chunks_this_index);
- free(tempbuf);
- if (avierr != AVIERR_NONE)
+ error const avierr = chunk_write(indexchunkid, &tempbuf[0], 24 + 8 * chunks_this_index);
+ if (avierr != error::NONE)
return avierr;
}
}
@@ -2892,7 +3183,7 @@ static avi_error write_indx_chunk(avi_file *file, avi_stream *stream, int initia
}
/* (over)write the chunk */
- return chunk_overwrite(file, (master_entries == 0) ? CHUNKTYPE_JUNK : CHUNKTYPE_INDX, buffer, sizeof(buffer), &stream->saved_indx_offset, initial_write);
+ return chunk_overwrite((master_entries == 0) ? CHUNKTYPE_JUNK : CHUNKTYPE_INDX, buffer, sizeof(buffer), stream.saved_indx_offset(), initial_write);
}
@@ -2910,47 +3201,42 @@ static avi_error write_indx_chunk(avi_file *file, avi_stream *stream, int initia
* @return An avi_error.
*/
-static avi_error write_idx1_chunk(avi_file *file)
+avi_file::error avi_file_impl::write_idx1_chunk()
{
- UINT32 tempbuflength = compute_idx1_size(file) - 8;
- UINT32 curchunk[2] = { 0 };
- UINT32 curoffset;
- avi_error avierr;
- UINT8 *tempbuf;
+ std::uint32_t const tempbuflength = compute_idx1_size() - 8;
+ std::uint32_t curchunk[2] = { 0 };
/* allocate a temporary buffer */
- tempbuf = (UINT8 *)malloc(tempbuflength);
- if (tempbuf == nullptr)
- return AVIERR_NO_MEMORY;
+ std::unique_ptr<std::uint8_t []> tempbuf;
+ try { tempbuf.reset(new std::uint8_t[tempbuflength]); }
+ catch (...) { return error::NO_MEMORY; }
/* fill it in */
- for (curoffset = 0; curoffset < tempbuflength; curoffset += 16)
+ for (std::uint32_t curoffset = 0; curoffset < tempbuflength; curoffset += 16)
{
- UINT64 minoffset = ~(UINT64)0;
- int strnum, minstr = 0;
+ std::uint64_t minoffset = ~std::uint64_t(0);
+ int minstr = 0;
/* determine which stream has the next chunk */
- for (strnum = 0; strnum < file->streams; strnum++)
- if (curchunk[strnum] < file->stream[strnum].chunks && file->stream[strnum].chunk[curchunk[strnum]].offset < minoffset)
+ for (int strnum = 0; strnum < m_streams.size(); strnum++)
+ if (curchunk[strnum] < m_streams[strnum].chunks() && m_streams[strnum].chunk(curchunk[strnum]).offset < minoffset)
{
- minoffset = file->stream[strnum].chunk[curchunk[strnum]].offset;
+ minoffset = m_streams[strnum].chunk(curchunk[strnum]).offset;
minstr = strnum;
}
/* make an entry for this index */
- put_32bits(&tempbuf[curoffset + 0], get_chunkid_for_stream(file, &file->stream[minstr]));
+ put_32bits(&tempbuf[curoffset + 0], get_chunkid_for_stream(&m_streams[minstr]));
put_32bits(&tempbuf[curoffset + 4], 0x0010 /* AVIIF_KEYFRAME */);
- put_32bits(&tempbuf[curoffset + 8], minoffset - (file->saved_movi_offset + 8));
- put_32bits(&tempbuf[curoffset + 12], file->stream[minstr].chunk[curchunk[minstr]].length - 8);
+ put_32bits(&tempbuf[curoffset + 8], minoffset - (m_saved_movi_offset + 8));
+ put_32bits(&tempbuf[curoffset + 12], m_streams[minstr].chunk(curchunk[minstr]).length - 8);
/* advance the chunk counter for this stream */
curchunk[minstr]++;
}
/* write the chunk */
- avierr = chunk_write(file, CHUNKTYPE_IDX1, tempbuf, tempbuflength);
- free(tempbuf);
- return avierr;
+ return chunk_write(CHUNKTYPE_IDX1, &tempbuf[0], tempbuflength);
}
@@ -2969,31 +3255,31 @@ static avi_error write_idx1_chunk(avi_file *file)
* @return An avi_error.
*/
-static avi_error soundbuf_initialize(avi_file *file)
+avi_file::error avi_file_impl::soundbuf_initialize()
{
- avi_stream *audio = get_audio_stream(file, 0, nullptr);
- avi_stream *video = get_video_stream(file);
+ int offset;
+ avi_stream *const audio = get_audio_stream(0, offset);
+ avi_stream *const video = get_video_stream();
/* we require a video stream */
if (video == nullptr)
- return AVIERR_UNSUPPORTED_VIDEO_FORMAT;
+ return error::UNSUPPORTED_VIDEO_FORMAT;
/* skip if no audio stream */
if (audio == nullptr)
- return AVIERR_NONE;
+ return error::NONE;
/* determine the number of samples we want in our buffer; 2 seconds should be enough */
- file->soundbuf_samples = file->info.audio_samplerate * SOUND_BUFFER_MSEC / 1000;
+ m_soundbuf_samples = m_info.audio_samplerate * SOUND_BUFFER_MSEC / 1000;
/* allocate a buffer */
- file->soundbuf = (INT16 *)malloc(file->soundbuf_samples * file->info.audio_channels * sizeof(file->soundbuf[0]));
- if (file->soundbuf == nullptr)
- return AVIERR_NO_MEMORY;
- memset(file->soundbuf, 0, file->soundbuf_samples * file->info.audio_channels * sizeof(file->soundbuf[0]));
+ m_soundbuf.clear();
+ try { m_soundbuf.resize(m_soundbuf_samples * m_info.audio_channels, 0); }
+ catch (...) { return error::NO_MEMORY; }
/* determine the number of frames to be ahead (0.75secs) */
- file->soundbuf_frames = ((UINT64)video->rate * 75) / ((UINT64)video->scale * 100) + 1;
- return AVIERR_NONE;
+ m_soundbuf_frames = (std::uint64_t(video->rate()) * 75) / (std::uint64_t(video->scale()) * 100) + 1;
+ return error::NONE;
}
@@ -3003,7 +3289,7 @@ static avi_error soundbuf_initialize(avi_file *file)
-------------------------------------------------*/
/**
- * @fn static avi_error soundbuf_write_chunk(avi_file *file, UINT32 framenum)
+ * @fn static avi_error soundbuf_write_chunk(avi_file *file, std::uint32_t framenum)
*
* @brief Soundbuf write chunk.
*
@@ -3013,30 +3299,30 @@ static avi_error soundbuf_initialize(avi_file *file)
* @return An avi_error.
*/
-static avi_error soundbuf_write_chunk(avi_file *file, UINT32 framenum)
+avi_file::error avi_file_impl::soundbuf_write_chunk(std::uint32_t framenum)
{
- avi_stream *stream = get_audio_stream(file, 0, nullptr);
- avi_error avierr;
- UINT32 length;
+ int offset;
+ avi_stream *const stream = get_audio_stream(0, offset);
+ std::uint32_t length;
/* skip if no audio stream */
if (stream == nullptr)
- return AVIERR_NONE;
+ return error::NONE;
/* determine the length of this chunk */
if (framenum == 0)
- length = framenum_to_samplenum(file, file->soundbuf_frames);
+ length = framenum_to_samplenum(m_soundbuf_frames);
else
- length = framenum_to_samplenum(file, framenum + 1 + file->soundbuf_frames) - framenum_to_samplenum(file, framenum + file->soundbuf_frames);
- length *= stream->channels * sizeof(INT16);
+ length = framenum_to_samplenum(framenum + 1 + m_soundbuf_frames) - framenum_to_samplenum(framenum + m_soundbuf_frames);
+ length *= stream->channels() * sizeof(std::int16_t);
/* then do the initial write */
- avierr = chunk_write(file, get_chunkid_for_stream(file, stream), file->soundbuf, length);
- if (avierr != AVIERR_NONE)
+ error const avierr = chunk_write(get_chunkid_for_stream(stream), &m_soundbuf[0], length);
+ if (avierr != error::NONE)
return avierr;
/* set the info for this new chunk */
- return set_stream_chunk_info(stream, stream->chunks, file->writeoffs - length - 8, length + 8);
+ return stream->set_chunk_info(stream->chunks(), m_writeoffs - length - 8, length + 8);
}
@@ -3056,36 +3342,35 @@ static avi_error soundbuf_write_chunk(avi_file *file, UINT32 framenum)
* @return An avi_error.
*/
-static avi_error soundbuf_flush(avi_file *file, int only_flush_full)
+avi_file::error avi_file_impl::soundbuf_flush(bool only_flush_full)
{
- avi_stream *stream = get_audio_stream(file, 0, nullptr);
- INT32 channelsamples = file->soundbuf_samples;
- INT32 processedsamples = 0;
- UINT32 bytes_per_sample;
- UINT32 finalchunks;
- avi_error avierr;
- UINT32 chunknum;
- UINT32 chunkid;
- int channel;
+ int offset;
+ avi_stream *const stream = get_audio_stream(0, offset);
+ std::int32_t channelsamples = m_soundbuf_samples;
+ std::int32_t processedsamples = 0;
+ std::uint32_t finalchunks;
+ error avierr;
+ std::uint32_t chunknum;
+ std::uint32_t chunkid;
/* skip if no stream */
if (stream == nullptr)
- return AVIERR_NONE;
+ return error::NONE;
/* get the chunk ID for this stream */
- chunkid = get_chunkid_for_stream(file, stream);
- bytes_per_sample = stream->channels * sizeof(INT16);
- finalchunks = stream->chunks;
+ chunkid = get_chunkid_for_stream(stream);
+ std::uint32_t const bytes_per_sample = stream->channels() * sizeof(std::int16_t);
+ finalchunks = stream->chunks();
/* find out how many samples we've accumulated */
- for (channel = 0; channel < stream->channels; channel++)
- channelsamples = MIN(channelsamples, file->soundbuf_chansamples[channel]);
+ for (int channel = 0; channel < stream->channels(); channel++)
+ channelsamples = (std::min<std::int32_t>)(channelsamples, m_soundbuf_chansamples[channel]);
/* loop over pending sound chunks */
- for (chunknum = file->soundbuf_chunks; chunknum < stream->chunks; chunknum++)
+ for (chunknum = m_soundbuf_chunks; chunknum < stream->chunks(); chunknum++)
{
- avi_chunk_list *chunk = &stream->chunk[chunknum];
- UINT32 chunksamples = (chunk->length - 8) / bytes_per_sample;
+ avi_chunk_list &chunk = stream->chunk(chunknum);
+ std::uint32_t const chunksamples = (chunk.length - 8) / bytes_per_sample;
/* stop if we don't have enough to satisfy this chunk */
if (only_flush_full && channelsamples < chunksamples)
@@ -3094,696 +3379,300 @@ static avi_error soundbuf_flush(avi_file *file, int only_flush_full)
/* if we don't have all the samples we need, pad with 0's */
if (channelsamples > 0 && channelsamples < chunksamples)
{
- if (processedsamples + chunksamples > file->soundbuf_samples)
- return AVIERR_EXCEEDED_SOUND_BUFFER;
- memset(&file->soundbuf[(processedsamples + channelsamples) * stream->channels], 0, (chunksamples - channelsamples) * bytes_per_sample);
+ if (processedsamples + chunksamples > m_soundbuf_samples)
+ return error::EXCEEDED_SOUND_BUFFER;
+ std::memset(&m_soundbuf[(processedsamples + channelsamples) * stream->channels()], 0, (chunksamples - channelsamples) * bytes_per_sample);
}
/* if we're completely out of samples, clear the buffer entirely and use the end */
else if (channelsamples <= 0)
{
- processedsamples = file->soundbuf_samples - chunksamples;
- memset(&file->soundbuf[processedsamples * stream->channels], 0, chunksamples * bytes_per_sample);
+ processedsamples = m_soundbuf_samples - chunksamples;
+ std::memset(&m_soundbuf[processedsamples * stream->channels()], 0, chunksamples * bytes_per_sample);
chunkid = CHUNKTYPE_JUNK;
finalchunks--;
}
/* copy the sample data in */
- avierr = chunk_overwrite(file, chunkid, &file->soundbuf[processedsamples * stream->channels], chunk->length - 8, &chunk->offset, FALSE);
- if (avierr != AVIERR_NONE)
+ avierr = chunk_overwrite(chunkid, &m_soundbuf[processedsamples * stream->channels()], chunk.length - 8, chunk.offset, false);
+ if (avierr != error::NONE)
return avierr;
/* add up the samples */
if (channelsamples > chunksamples)
- file->info.audio_numsamples = stream->samples += chunksamples;
+ m_info.audio_numsamples = stream->add_samples(chunksamples);
else if (channelsamples > 0)
- file->info.audio_numsamples = stream->samples += channelsamples;
+ m_info.audio_numsamples = stream->add_samples(channelsamples);
/* advance past those */
processedsamples += chunksamples;
channelsamples -= chunksamples;
- channelsamples = MAX(0, channelsamples);
+ channelsamples = (std::max)(0, channelsamples);
}
/* if we have a non-zero offset, shift everything down */
if (processedsamples > 0)
{
/* first account for the samples we processed */
- memmove(&file->soundbuf[0], &file->soundbuf[processedsamples * stream->channels], (file->soundbuf_samples - processedsamples) * bytes_per_sample);
- for (channel = 0; channel < stream->channels; channel++)
- file->soundbuf_chansamples[channel] -= processedsamples;
+ std::memmove(&m_soundbuf[0], &m_soundbuf[processedsamples * stream->channels()], (m_soundbuf_samples - processedsamples) * bytes_per_sample);
+ for (int channel = 0; channel < stream->channels(); channel++)
+ m_soundbuf_chansamples[channel] -= processedsamples;
}
/* update the final chunk count */
if (!only_flush_full)
- stream->chunks = finalchunks;
+ stream->set_chunks(finalchunks);
/* account for flushed chunks */
- file->soundbuf_chunks = chunknum;
- return AVIERR_NONE;
+ m_soundbuf_chunks = chunknum;
+ return error::NONE;
}
/*-------------------------------------------------
- rgb32_compress_to_rgb - "compress" an RGB32
- bitmap to an RGB encoded frame
+ printf_chunk_recursive - print information
+ about a chunk recursively
-------------------------------------------------*/
/**
- * @fn static avi_error rgb32_compress_to_rgb(avi_stream *stream, const bitmap_rgb32 &bitmap, UINT8 *data, UINT32 numbytes)
- *
- * @brief RGB 32 compress to RGB.
+ * @fn static void printf_chunk_recursive(avi_file *file, avi_chunk *container, int indent)
*
- * @param [in,out] stream If non-null, the stream.
- * @param bitmap The bitmap.
- * @param [in,out] data If non-null, the data.
- * @param numbytes The numbytes.
+ * @brief Printf chunk recursive.
*
- * @return An avi_error.
+ * @param [in,out] file If non-null, the file.
+ * @param [in,out] container If non-null, the container.
+ * @param indent The indent.
*/
-static avi_error rgb32_compress_to_rgb(avi_stream *stream, const bitmap_rgb32 &bitmap, UINT8 *data, UINT32 numbytes)
+void avi_file_impl::printf_chunk_recursive(avi_chunk const *container, int indent)
{
- int height = MIN(stream->height, bitmap.height());
- int width = MIN(stream->width, bitmap.width());
- UINT8 *dataend = data + numbytes;
- int x, y;
+ char size[20], offset[20];
+ avi_chunk curchunk;
+ error avierr;
- /* compressed video */
- for (y = 0; y < height; y++)
+ /* iterate over chunks in this container */
+ for (avierr = get_first_chunk(container, curchunk); avierr == error::NONE; avierr = get_next_chunk(container, curchunk))
{
- const UINT32 *source = &bitmap.pix32(y);
- UINT8 *dest = data + (stream->height - 1 - y) * stream->width * 3;
-
- for (x = 0; x < width && dest < dataend; x++)
- {
- rgb_t pix = *source++;
- *dest++ = pix.b();
- *dest++ = pix.g();
- *dest++ = pix.r();
- }
+ std::uint32_t chunksize = curchunk.size;
+ bool recurse = false;
- /* fill in any blank space on the right */
- for ( ; x < stream->width && dest < dataend; x++)
- {
- *dest++ = 0;
- *dest++ = 0;
- *dest++ = 0;
- }
- }
+ u64toa(curchunk.size, size);
+ u64toa(curchunk.offset, offset);
+ printf("%*schunk = %c%c%c%c, size=%s (%s)\n", indent, "",
+ std::uint8_t(curchunk.type >> 0),
+ std::uint8_t(curchunk.type >> 8),
+ std::uint8_t(curchunk.type >> 16),
+ std::uint8_t(curchunk.type >> 24),
+ size, offset);
- /* fill in any blank space on the bottom */
- for ( ; y < stream->height; y++)
- {
- UINT8 *dest = data + (stream->height - 1 - y) * stream->width * 3;
- for (x = 0; x < stream->width && dest < dataend; x++)
+ /* certain chunks are just containers; recurse into them */
+ switch (curchunk.type)
{
- *dest++ = 0;
- *dest++ = 0;
- *dest++ = 0;
+ /* basic containers */
+ case CHUNKTYPE_RIFF:
+ case CHUNKTYPE_LIST:
+ printf("%*stype = %c%c%c%c\n", indent, "",
+ std::uint8_t(curchunk.listtype >> 0),
+ std::uint8_t(curchunk.listtype >> 8),
+ std::uint8_t(curchunk.listtype >> 16),
+ std::uint8_t(curchunk.listtype >> 24));
+ recurse = true;
+ chunksize = 0;
+ break;
}
- }
-
- return AVIERR_NONE;
-}
-
-
-/*-------------------------------------------------
- yuv_decompress_to_yuy16 - decompress a YUV
- encoded frame to a YUY16 bitmap
--------------------------------------------------*/
-
-/**
- * @fn static avi_error yuv_decompress_to_yuy16(avi_stream *stream, const UINT8 *data, UINT32 numbytes, bitmap_yuy16 &bitmap)
- *
- * @brief Yuv decompress to yuy 16.
- *
- * @param [in,out] stream If non-null, the stream.
- * @param data The data.
- * @param numbytes The numbytes.
- * @param [in,out] bitmap The bitmap.
- *
- * @return An avi_error.
- */
-static avi_error yuv_decompress_to_yuy16(avi_stream *stream, const UINT8 *data, UINT32 numbytes, bitmap_yuy16 &bitmap)
-{
- const UINT16 *dataend = (const UINT16 *)(data + numbytes);
- int x, y;
-
- /* compressed video */
- for (y = 0; y < stream->height; y++)
- {
- const UINT16 *source = (const UINT16 *)data + y * stream->width;
- UINT16 *dest = &bitmap.pix16(y);
-
- /* switch off the compression */
- switch (stream->format)
+ /* print data within the chunk */
+ if (chunksize > 0 && curchunk.size < 1024 * 1024)
{
- case FORMAT_UYVY:
- for (x = 0; x < stream->width && source < dataend; x++)
- *dest++ = *source++;
- break;
+ std::unique_ptr<std::uint8_t []> data;
- case FORMAT_VYUY:
- case FORMAT_YUY2:
- for (x = 0; x < stream->width && source < dataend; x++)
+ /* read the data for a chunk */
+ avierr = read_chunk_data(curchunk, data);
+ if (avierr == error::NONE)
+ {
+ std::uint32_t const bytes = (std::min)(std::uint32_t(512), chunksize);
+ for (std::uint32_t i = 0; i < bytes; i++)
{
- UINT16 pix = *source++;
- *dest++ = (pix >> 8) | (pix << 8);
+ if (i % 16 == 0) printf("%*s ", indent, "");
+ printf("%02X ", data[i]);
+ if (i % 16 == 15) printf("\n");
}
- break;
+ if (chunksize % 16 != 0) printf("\n");
+ }
}
+
+ /* if we're recursing, dive down */
+ if (recurse)
+ printf_chunk_recursive(&curchunk, indent + 4);
}
- return AVIERR_NONE;
+ /* if we didn't get a legitimate error, indicate that */
+ if (avierr != error::END)
+ printf("[chunk error %d]\n", int(avierr));
}
+} // anonymous namespace
+
+
+
+/***************************************************************************
+ IMPLEMENTATION
+***************************************************************************/
/*-------------------------------------------------
- yuy16_compress_to_yuy - "compress" a YUY16
- bitmap to a YUV encoded frame
+ avi_open - open an AVI movie file for read
-------------------------------------------------*/
/**
- * @fn static avi_error yuy16_compress_to_yuy(avi_stream *stream, const bitmap_yuy16 &bitmap, UINT8 *data, UINT32 numbytes)
+ * @fn avi_error avi_open(const char *filename, avi_file **file)
*
- * @brief Yuy 16 compress to yuy.
+ * @brief Queries if a given avi open.
*
- * @param [in,out] stream If non-null, the stream.
- * @param bitmap The bitmap.
- * @param [in,out] data If non-null, the data.
- * @param numbytes The numbytes.
+ * @param filename Filename of the file.
+ * @param [in,out] file If non-null, the file.
*
* @return An avi_error.
*/
-static avi_error yuy16_compress_to_yuy(avi_stream *stream, const bitmap_yuy16 &bitmap, UINT8 *data, UINT32 numbytes)
+avi_file::error avi_file::open(std::string const &filename, ptr &file)
{
- const UINT16 *dataend = (const UINT16 *)(data + numbytes);
- int x, y;
-
- /* compressed video */
- for (y = 0; y < stream->height; y++)
- {
- const UINT16 *source = &bitmap.pix16(y);
- UINT16 *dest = (UINT16 *)data + y * stream->width;
+ /* open the file */
+ osd_file::ptr f;
+ std::uint64_t length;
+ if (osd_file::open(filename, OPEN_FLAG_READ, f, length) != osd_file::error::NONE)
+ return error::CANT_OPEN_FILE;
- /* switch off the compression */
- switch (stream->format)
- {
- case FORMAT_UYVY:
- for (x = 0; x < stream->width && dest < dataend; x++)
- *dest++ = *source++;
- break;
+ /* allocate the file */
+ std::unique_ptr<avi_file_impl> newfile;
+ try { newfile = std::make_unique<avi_file_impl>(std::move(f), length); }
+ catch (...) { return error::NO_MEMORY; }
- case FORMAT_VYUY:
- case FORMAT_YUY2:
- for (x = 0; x < stream->width && dest < dataend; x++)
- {
- UINT16 pix = *source++;
- *dest++ = (pix >> 8) | (pix << 8);
- }
- break;
- }
- }
+ /* parse the data */
+ error const avierr = newfile->read_movie_data();
+ if (avierr != error::NONE)
+ return avierr;
- return AVIERR_NONE;
+ file = std::move(newfile);
+ return error::NONE;
}
/*-------------------------------------------------
- huffyuv_extract_tables - extract HuffYUV
- tables
+ avi_create - create a new AVI movie file
-------------------------------------------------*/
/**
- * @fn static avi_error huffyuv_extract_tables(avi_stream *stream, const UINT8 *chunkdata, UINT32 size)
+ * @fn avi_error avi_create(const char *filename, const avi_movie_info *info, avi_file **file)
*
- * @brief Huffyuv extract tables.
+ * @brief Avi create.
*
- * @param [in,out] stream If non-null, the stream.
- * @param chunkdata The chunkdata.
- * @param size The size.
+ * @param filename Filename of the file.
+ * @param info The information.
+ * @param [in,out] file If non-null, the file.
*
* @return An avi_error.
*/
-static avi_error huffyuv_extract_tables(avi_stream *stream, const UINT8 *chunkdata, UINT32 size)
+avi_file::error avi_file::create(std::string const &filename, movie_info const &info, ptr &file)
{
- const UINT8 *chunkend = chunkdata + size;
- avi_error avierr = AVIERR_NONE;
- int tabnum;
-
- /* allocate memory for the data */
- stream->huffyuv = (huffyuv_data *)malloc(sizeof(*stream->huffyuv));
- if (stream->huffyuv == nullptr)
- {
- avierr = AVIERR_NO_MEMORY;
- goto error;
- }
-
- /* extract predictor information */
- if (&chunkdata[40] >= chunkend)
- return AVIERR_INVALID_DATA;
- stream->huffyuv->predictor = chunkdata[40];
+ /* validate video info */
+ if ((info.video_format != 0 && info.video_format != FORMAT_UYVY && info.video_format != FORMAT_VYUY && info.video_format != FORMAT_YUY2) ||
+ (info.video_width == 0) ||
+ (info.video_height == 0) ||
+ (info.video_depth == 0) ||
+ (info.video_depth % 8 != 0))
+ return error::UNSUPPORTED_VIDEO_FORMAT;
- /* make sure it's the left predictor */
- if ((stream->huffyuv->predictor & ~HUFFYUV_PREDICT_DECORR) != HUFFYUV_PREDICT_LEFT)
- return AVIERR_UNSUPPORTED_VIDEO_FORMAT;
+ /* validate audio info */
+ if (info.audio_format != 0 ||
+ info.audio_channels > MAX_SOUND_CHANNELS ||
+ info.audio_samplebits != 16)
+ return error::UNSUPPORTED_AUDIO_FORMAT;
- /* make sure it's 16bpp YUV data */
- if (chunkdata[41] != 16)
- return AVIERR_UNSUPPORTED_VIDEO_FORMAT;
- chunkdata += 44;
+ /* open the file */
+ osd_file::ptr f;
+ std::uint64_t length;
+ osd_file::error const filerr = osd_file::open(filename, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS, f, length);
+ if (filerr != osd_file::error::NONE)
+ return error::CANT_OPEN_FILE;
- /* loop over tables */
- for (tabnum = 0; tabnum < 3; tabnum++)
+ /* allocate the file */
+ error avierr;
+ std::unique_ptr<avi_file_impl> newfile;
+ try { newfile = std::make_unique<avi_file_impl>(std::move(f), info); }
+ catch (...)
{
- huffyuv_table *table = &stream->huffyuv->table[tabnum];
- UINT32 curbits, bitadd;
- UINT16 bitsat16 = 0;
- int offset = 0, bits;
-
- /* loop until we populate the whole table */
- while (offset < 256)
- {
- int data, shift, count, i;
-
- /* extract the next run */
- if (chunkdata >= chunkend)
- {
- avierr = AVIERR_INVALID_DATA;
- goto error;
- }
- data = *chunkdata++;
- shift = data & 0x1f;
- count = data >> 5;
-
- /* zero count means next whole byte is a count */
- if (count == 0)
- {
- if (chunkdata >= chunkend)
- {
- avierr = AVIERR_INVALID_DATA;
- goto error;
- }
- count = *chunkdata++;
- }
- for (i = 0; i < count; i++)
- table->shift[offset++] = shift;
- }
-
- /* now determine bit patterns and masks */
- curbits = 0;
- for (bits = 31; bits >= 0; bits--)
- {
- bitadd = 1 << (32 - bits);
-
- /* make sure we've cleared out all the bits below */
- if ((curbits & (bitadd - 1)) != 0)
- {
- avierr = AVIERR_INVALID_DATA;
- goto error;
- }
-
- /* find all entries with this shift count and assign them */
- for (offset = 0; offset < 256; offset++)
- if (table->shift[offset] == bits)
- {
- table->bits[offset] = curbits;
- table->mask[offset] = ~(bitadd - 1);
- curbits += bitadd;
- }
+ avierr = error::NO_MEMORY;
+ goto error;
+ }
- /* remember the bit pattern when we complete all the 17-bit codes */
- if (bits == 17)
- bitsat16 = curbits >> 16;
- }
+ /* initialize the sound buffering */
+ avierr = newfile->soundbuf_initialize();
+ if (avierr != error::NONE)
+ goto error;
- /* allocate the number of extra lookup tables we need */
- if (bitsat16 > 0)
- {
- table->extralookup = (UINT16 *)malloc(bitsat16 * 65536 * sizeof(table->extralookup[0]));
- if (table->extralookup == nullptr)
- {
- avierr = AVIERR_NO_MEMORY;
- goto error;
- }
- for (offset = 0; offset < bitsat16; offset++)
- table->baselookup[offset] = (offset << 8) | 0;
- }
+ /* write the initial headers */
+ avierr = newfile->write_initial_headers();
+ if (avierr != error::NONE)
+ goto error;
- /* then create lookup tables */
- for (offset = 0; offset < 256; offset++)
- if (table->shift[offset] > 16)
- {
- UINT16 *tablebase = table->extralookup + (table->bits[offset] >> 16) * 65536;
- UINT32 start = table->bits[offset] & 0xffff;
- UINT32 end = start + ((1 << (32 - table->shift[offset])) - 1);
- while (start <= end)
- tablebase[start++] = (offset << 8) | (table->shift[offset] - 16);
- }
- else if (table->shift[offset] > 0)
- {
- UINT32 start = table->bits[offset] >> 16;
- UINT32 end = start + ((1 << (16 - table->shift[offset])) - 1);
- while (start <= end)
- table->baselookup[start++] = (offset << 8) | table->shift[offset];
- }
- }
+ file = std::move(newfile);
+ return error::NONE;
error:
- if (avierr != AVIERR_NONE && stream->huffyuv != nullptr)
- {
- free(stream->huffyuv);
- stream->huffyuv = nullptr;
- }
+ f.reset();
+ newfile.reset();
+ osd_file::remove(filename);
return avierr;
}
/*-------------------------------------------------
- huffyuv_decompress_to_yuy16 - decompress a
- HuffYUV-encoded frame to a YUY16 bitmap
+ avi_error_string - get the error string for
+ an avi_error
-------------------------------------------------*/
/**
- * @fn static avi_error huffyuv_decompress_to_yuy16(avi_stream *stream, const UINT8 *data, UINT32 numbytes, bitmap_yuy16 &bitmap)
+ * @fn const char *avi_error_string(avi_error err)
*
- * @brief Huffyuv decompress to yuy 16.
+ * @brief Avi error string.
*
- * @param [in,out] stream If non-null, the stream.
- * @param data The data.
- * @param numbytes The numbytes.
- * @param [in,out] bitmap The bitmap.
+ * @param err The error.
*
- * @return An avi_error.
+ * @return null if it fails, else a char*.
*/
-static avi_error huffyuv_decompress_to_yuy16(avi_stream *stream, const UINT8 *data, UINT32 numbytes, bitmap_yuy16 &bitmap)
+const char *avi_file::error_string(error err)
{
- huffyuv_data *huffyuv = stream->huffyuv;
- int prevlines = (stream->height > 288) ? 2 : 1;
- UINT8 lastprevy = 0, lastprevcb = 0, lastprevcr = 0;
- UINT8 lasty = 0, lastcb = 0, lastcr = 0;
- UINT8 bitsinbuffer = 0;
- UINT32 bitbuffer = 0;
- UINT32 dataoffs = 0;
- int x, y;
-
- /* compressed video */
- for (y = 0; y < stream->height; y++)
- {
- UINT16 *dest = &bitmap.pix16(y);
-
- /* handle the first four bytes independently */
- x = 0;
- if (y == 0)
- {
- /* first DWORD is stored as YUY2 */
- lasty = data[dataoffs++];
- lastcb = data[dataoffs++];
- *dest++ = (lasty << 8) | lastcb;
- lasty = data[dataoffs++];
- lastcr = data[dataoffs++];
- *dest++ = (lasty << 8) | lastcr;
- x = 2;
- }
-
- /* loop over pixels */
- for ( ; x < stream->width; x++)
- {
- huffyuv_table *ytable = &huffyuv->table[0];
- huffyuv_table *ctable = &huffyuv->table[1 + (x & 1)];
- UINT16 pixel, huffdata;
- int shift;
-
- /* fill up the buffer; they store little-endian DWORDs, so we XOR with 3 */
- while (bitsinbuffer <= 24 && dataoffs < numbytes)
- {
- bitbuffer |= data[dataoffs++ ^ 3] << (24 - bitsinbuffer);
- bitsinbuffer += 8;
- }
-
- /* look up the Y component */
- huffdata = ytable->baselookup[bitbuffer >> 16];
- shift = huffdata & 0xff;
- if (shift == 0)
- {
- bitsinbuffer -= 16;
- bitbuffer <<= 16;
-
- /* fill up the buffer; they store little-endian DWORDs, so we XOR with 3 */
- while (bitsinbuffer <= 24 && dataoffs < numbytes)
- {
- bitbuffer |= data[dataoffs++ ^ 3] << (24 - bitsinbuffer);
- bitsinbuffer += 8;
- }
-
- huffdata = ytable->extralookup[(huffdata >> 8) * 65536 + (bitbuffer >> 16)];
- shift = huffdata & 0xff;
- }
- bitsinbuffer -= shift;
- bitbuffer <<= shift;
- pixel = huffdata & 0xff00;
-
- /* fill up the buffer; they store little-endian DWORDs, so we XOR with 3 */
- while (bitsinbuffer <= 24 && dataoffs < numbytes)
- {
- bitbuffer |= data[dataoffs++ ^ 3] << (24 - bitsinbuffer);
- bitsinbuffer += 8;
- }
-
- /* look up the Cb/Cr component */
- huffdata = ctable->baselookup[bitbuffer >> 16];
- shift = huffdata & 0xff;
- if (shift == 0)
- {
- bitsinbuffer -= 16;
- bitbuffer <<= 16;
-
- /* fill up the buffer; they store little-endian DWORDs, so we XOR with 3 */
- while (bitsinbuffer <= 24 && dataoffs < numbytes)
- {
- bitbuffer |= data[dataoffs++ ^ 3] << (24 - bitsinbuffer);
- bitsinbuffer += 8;
- }
-
- huffdata = ctable->extralookup[(huffdata >> 8) * 65536 + (bitbuffer >> 16)];
- shift = huffdata & 0xff;
- }
- bitsinbuffer -= shift;
- bitbuffer <<= shift;
- *dest++ = pixel | (huffdata >> 8);
- }
- }
-
- /* apply deltas */
- lastprevy = lastprevcb = lastprevcr = 0;
- for (y = 0; y < stream->height; y++)
+ switch (err)
{
- UINT16 *prevrow = &bitmap.pix16(y - prevlines);
- UINT16 *dest = &bitmap.pix16(y);
-
- /* handle the first four bytes independently */
- x = 0;
- if (y == 0)
- {
- /* lasty, lastcr, lastcb are set up previously */
- x = 2;
- }
-
- /* left predict or gradient predict */
- if ((huffyuv->predictor & ~HUFFYUV_PREDICT_DECORR) == HUFFYUV_PREDICT_LEFT ||
- ((huffyuv->predictor & ~HUFFYUV_PREDICT_DECORR) == HUFFYUV_PREDICT_GRADIENT))
- {
- /* first do left deltas */
- for ( ; x < stream->width; x += 2)
- {
- UINT16 pixel0 = dest[x + 0];
- UINT16 pixel1 = dest[x + 1];
-
- lasty += pixel0 >> 8;
- lastcb += pixel0;
- dest[x + 0] = (lasty << 8) | lastcb;
-
- lasty += pixel1 >> 8;
- lastcr += pixel1;
- dest[x + 1] = (lasty << 8) | lastcr;
- }
-
- /* for gradient, we then add in the previous row */
- if ((huffyuv->predictor & ~HUFFYUV_PREDICT_DECORR) == HUFFYUV_PREDICT_GRADIENT && y >= prevlines)
- for (x = 0; x < stream->width; x++)
- {
- UINT16 curpix = dest[x];
- UINT16 prevpix = prevrow[x];
- UINT8 ysum = (curpix >> 8) + (prevpix >> 8);
- UINT8 csum = curpix + prevpix;
- dest[x] = (ysum << 8) | csum;
- }
- }
-
- /* median predict on rows > 0 */
- else if ((huffyuv->predictor & ~HUFFYUV_PREDICT_DECORR) == HUFFYUV_PREDICT_MEDIAN && y >= prevlines)
- {
- for ( ; x < stream->width; x += 2)
- {
- UINT16 prevpixel0 = prevrow[x + 0];
- UINT16 prevpixel1 = prevrow[x + 1];
- UINT16 pixel0 = dest[x + 0];
- UINT16 pixel1 = dest[x + 1];
- UINT8 a, b, c;
-
- /* compute previous, above, and (prev + above - above-left) */
- a = lasty;
- b = prevpixel0 >> 8;
- c = lastprevy;
- lastprevy = b;
- if (a > b) { UINT8 tmp = a; a = b; b = tmp; }
- if (a > c) { UINT8 tmp = a; a = c; c = tmp; }
- if (b > c) { UINT8 tmp = b; b = c; c = tmp; }
- lasty = (pixel0 >> 8) + b;
-
- /* compute previous, above, and (prev + above - above-left) */
- a = lastcb;
- b = prevpixel0 & 0xff;
- c = lastprevcb;
- lastprevcb = b;
- if (a > b) { UINT8 tmp = a; a = b; b = tmp; }
- if (a > c) { UINT8 tmp = a; a = c; c = tmp; }
- if (b > c) { UINT8 tmp = b; b = c; c = tmp; }
- lastcb = (pixel0 & 0xff) + b;
- dest[x + 0] = (lasty << 8) | lastcb;
-
- /* compute previous, above, and (prev + above - above-left) */
- a = lasty;
- b = prevpixel1 >> 8;
- c = lastprevy;
- lastprevy = b;
- if (a > b) { UINT8 tmp = a; a = b; b = tmp; }
- if (a > c) { UINT8 tmp = a; a = c; c = tmp; }
- if (b > c) { UINT8 tmp = b; b = c; c = tmp; }
- lasty = (pixel1 >> 8) + b;
-
- /* compute previous, above, and (prev + above - above-left) */
- a = lastcr;
- b = prevpixel1 & 0xff;
- c = lastprevcr;
- lastprevcr = b;
- if (a > b) { UINT8 tmp = a; a = b; b = tmp; }
- if (a > c) { UINT8 tmp = a; a = c; c = tmp; }
- if (b > c) { UINT8 tmp = b; b = c; c = tmp; }
- lastcr = (pixel1 & 0xff) + b;
- dest[x + 1] = (lasty << 8) | lastcr;
- }
- }
+ case error::NONE: return "success";
+ case error::END: return "hit end of file";
+ case error::INVALID_DATA: return "invalid data";
+ case error::NO_MEMORY: return "out of memory";
+ case error::READ_ERROR: return "read error";
+ case error::WRITE_ERROR: return "write error";
+ case error::STACK_TOO_DEEP: return "stack overflow";
+ case error::UNSUPPORTED_FEATURE: return "unsupported feature";
+ case error::CANT_OPEN_FILE: return "unable to open file";
+ case error::INCOMPATIBLE_AUDIO_STREAMS: return "found incompatible audio streams";
+ case error::INVALID_SAMPLERATE: return "found invalid sample rate";
+ case error::INVALID_STREAM: return "invalid stream";
+ case error::INVALID_FRAME: return "invalid frame index";
+ case error::INVALID_BITMAP: return "invalid bitmap";
+ case error::UNSUPPORTED_VIDEO_FORMAT: return "unsupported video format";
+ case error::UNSUPPORTED_AUDIO_FORMAT: return "unsupported audio format";
+ case error::EXCEEDED_SOUND_BUFFER: return "sound buffer overflow";
+ default: return "undocumented error";
}
-
- return AVIERR_NONE;
}
-/**
- * @fn static void u64toa(UINT64 val, char *output)
- *
- * @brief 64toas.
- *
- * @param val The value.
- * @param [in,out] output If non-null, the output.
- */
-static void u64toa(UINT64 val, char *output)
+avi_file::avi_file()
{
- UINT32 lo = (UINT32)(val & 0xffffffff);
- UINT32 hi = (UINT32)(val >> 32);
- if (hi != 0)
- sprintf(output, "%X%08X", hi, lo);
- else
- sprintf(output, "%X", lo);
}
-/*-------------------------------------------------
- printf_chunk_recursive - print information
- about a chunk recursively
--------------------------------------------------*/
-
-/**
- * @fn static void printf_chunk_recursive(avi_file *file, avi_chunk *container, int indent)
- *
- * @brief Printf chunk recursive.
- *
- * @param [in,out] file If non-null, the file.
- * @param [in,out] container If non-null, the container.
- * @param indent The indent.
- */
-
-static void printf_chunk_recursive(avi_file *file, avi_chunk *container, int indent)
+avi_file::~avi_file()
{
- char size[20], offset[20];
- avi_chunk curchunk;
- int avierr;
-
- /* iterate over chunks in this container */
- for (avierr = get_first_chunk(file, container, &curchunk); avierr == AVIERR_NONE; avierr = get_next_chunk(file, container, &curchunk))
- {
- UINT32 chunksize = curchunk.size;
- int recurse = FALSE;
-
- u64toa(curchunk.size, size);
- u64toa(curchunk.offset, offset);
- printf("%*schunk = %c%c%c%c, size=%s (%s)\n", indent, "",
- (UINT8)(curchunk.type >> 0),
- (UINT8)(curchunk.type >> 8),
- (UINT8)(curchunk.type >> 16),
- (UINT8)(curchunk.type >> 24),
- size, offset);
-
- /* certain chunks are just containers; recurse into them */
- switch (curchunk.type)
- {
- /* basic containers */
- case CHUNKTYPE_RIFF:
- case CHUNKTYPE_LIST:
- printf("%*stype = %c%c%c%c\n", indent, "",
- (UINT8)(curchunk.listtype >> 0),
- (UINT8)(curchunk.listtype >> 8),
- (UINT8)(curchunk.listtype >> 16),
- (UINT8)(curchunk.listtype >> 24));
- recurse = TRUE;
- chunksize = 0;
- break;
- }
-
- /* print data within the chunk */
- if (chunksize > 0 && curchunk.size < 1024 * 1024)
- {
- UINT8 *data = nullptr;
- int i;
-
- /* read the data for a chunk */
- avierr = read_chunk_data(file, &curchunk, &data);
- if (avierr == AVIERR_NONE)
- {
- int bytes = MIN(512, chunksize);
- for (i = 0; i < bytes; i++)
- {
- if (i % 16 == 0) printf("%*s ", indent, "");
- printf("%02X ", data[i]);
- if (i % 16 == 15) printf("\n");
- }
- if (chunksize % 16 != 0) printf("\n");
- free(data);
- }
- }
-
- /* if we're recursing, dive down */
- if (recurse)
- printf_chunk_recursive(file, &curchunk, indent + 4);
- }
-
- /* if we didn't get a legitimate error, indicate that */
- if (avierr != AVIERR_END)
- printf("[chunk error %d]\n", avierr);
}
diff --git a/src/lib/util/aviio.h b/src/lib/util/aviio.h
index 86e2fd19cd2..c6d547903fe 100644
--- a/src/lib/util/aviio.h
+++ b/src/lib/util/aviio.h
@@ -1,5 +1,5 @@
// license:BSD-3-Clause
-// copyright-holders:Aaron Giles
+// copyright-holders:Aaron Giles, Vas Crabb
/***************************************************************************
aviio.h
@@ -8,52 +8,15 @@
***************************************************************************/
-#ifndef __AVIIO_H__
-#define __AVIIO_H__
+#ifndef MAME_LIB_UTIL_AVIIO_H
+#define MAME_LIB_UTIL_AVIIO_H
#include "osdcore.h"
#include "bitmap.h"
-
-/***************************************************************************
- CONSTANTS
-***************************************************************************/
-
-enum avi_error
-{
- AVIERR_NONE = 0,
- AVIERR_END,
- AVIERR_INVALID_DATA,
- AVIERR_NO_MEMORY,
- AVIERR_READ_ERROR,
- AVIERR_WRITE_ERROR,
- AVIERR_STACK_TOO_DEEP,
- AVIERR_UNSUPPORTED_FEATURE,
- AVIERR_CANT_OPEN_FILE,
- AVIERR_INCOMPATIBLE_AUDIO_STREAMS,
- AVIERR_INVALID_SAMPLERATE,
- AVIERR_INVALID_STREAM,
- AVIERR_INVALID_FRAME,
- AVIERR_INVALID_BITMAP,
- AVIERR_UNSUPPORTED_VIDEO_FORMAT,
- AVIERR_UNSUPPORTED_AUDIO_FORMAT,
- AVIERR_EXCEEDED_SOUND_BUFFER
-};
-
-
-enum avi_datatype
-{
- AVIDATA_VIDEO,
- AVIDATA_AUDIO_CHAN0,
- AVIDATA_AUDIO_CHAN1,
- AVIDATA_AUDIO_CHAN2,
- AVIDATA_AUDIO_CHAN3,
- AVIDATA_AUDIO_CHAN4,
- AVIDATA_AUDIO_CHAN5,
- AVIDATA_AUDIO_CHAN6,
- AVIDATA_AUDIO_CHAN7
-};
-
+#include <cstdint>
+#include <memory>
+#include <string>
/***************************************************************************
@@ -69,53 +32,98 @@ enum avi_datatype
-/***************************************************************************
- TYPE DEFINITIONS
-***************************************************************************/
-
-struct avi_file;
-
-
-struct avi_movie_info
+class avi_file
{
- UINT32 video_format; /* format of video data */
- UINT32 video_timescale; /* timescale for video data */
- UINT32 video_sampletime; /* duration of a single video sample (frame) */
- UINT32 video_numsamples; /* total number of video samples */
- UINT32 video_width; /* width of the video */
- UINT32 video_height; /* height of the video */
- UINT32 video_depth; /* depth of the video */
-
- UINT32 audio_format; /* format of audio data */
- UINT32 audio_timescale; /* timescale for audio data */
- UINT32 audio_sampletime; /* duration of a single audio sample */
- UINT32 audio_numsamples; /* total number of audio samples */
- UINT32 audio_channels; /* number of audio channels */
- UINT32 audio_samplebits; /* number of bits per channel */
- UINT32 audio_samplerate; /* sample rate of audio */
+public:
+
+ /***********************************************************************
+ CONSTANTS
+ ***********************************************************************/
+
+ enum class error
+ {
+ NONE = 0,
+ END,
+ INVALID_DATA,
+ NO_MEMORY,
+ READ_ERROR,
+ WRITE_ERROR,
+ STACK_TOO_DEEP,
+ UNSUPPORTED_FEATURE,
+ CANT_OPEN_FILE,
+ INCOMPATIBLE_AUDIO_STREAMS,
+ INVALID_SAMPLERATE,
+ INVALID_STREAM,
+ INVALID_FRAME,
+ INVALID_BITMAP,
+ UNSUPPORTED_VIDEO_FORMAT,
+ UNSUPPORTED_AUDIO_FORMAT,
+ EXCEEDED_SOUND_BUFFER
+ };
+
+ enum class datatype
+ {
+ VIDEO,
+ AUDIO_CHAN0,
+ AUDIO_CHAN1,
+ AUDIO_CHAN2,
+ AUDIO_CHAN3,
+ AUDIO_CHAN4,
+ AUDIO_CHAN5,
+ AUDIO_CHAN6,
+ AUDIO_CHAN7
+ };
+
+
+ /***********************************************************************
+ TYPE DEFINITIONS
+ ***********************************************************************/
+
+ struct movie_info
+ {
+ std::uint32_t video_format; // format of video data
+ std::uint32_t video_timescale; // timescale for video data
+ std::uint32_t video_sampletime; // duration of a single video sample (frame)
+ std::uint32_t video_numsamples; // total number of video samples
+ std::uint32_t video_width; // width of the video
+ std::uint32_t video_height; // height of the video
+ std::uint32_t video_depth; // depth of the video
+
+ std::uint32_t audio_format; // format of audio data
+ std::uint32_t audio_timescale; // timescale for audio data
+ std::uint32_t audio_sampletime; // duration of a single audio sample
+ std::uint32_t audio_numsamples; // total number of audio samples
+ std::uint32_t audio_channels; // number of audio channels
+ std::uint32_t audio_samplebits; // number of bits per channel
+ std::uint32_t audio_samplerate; // sample rate of audio
+ };
+
+ typedef std::unique_ptr<avi_file> ptr;
+
+
+ /***********************************************************************
+ PROTOTYPES
+ ***********************************************************************/
+
+ static error open(std::string const &filename, ptr &file);
+ static error create(std::string const &filename, movie_info const &info, ptr &file);
+ virtual ~avi_file();
+
+ virtual void printf_chunks() = 0;
+ static const char *error_string(error err);
+
+ virtual movie_info const &get_movie_info() const = 0;
+ virtual std::uint32_t first_sample_in_frame(std::uint32_t framenum) const = 0;
+
+ virtual error read_video_frame(std::uint32_t framenum, bitmap_yuy16 &bitmap) = 0;
+ virtual error read_sound_samples(int channel, std::uint32_t firstsample, std::uint32_t numsamples, std::int16_t *output) = 0;
+
+ virtual error append_video_frame(bitmap_yuy16 &bitmap) = 0;
+ virtual error append_video_frame(bitmap_rgb32 &bitmap) = 0;
+ virtual error append_sound_samples(int channel, std::int16_t const *samples, std::uint32_t numsamples, std::uint32_t sampleskip) = 0;
+
+protected:
+ avi_file();
};
-
-
-/***************************************************************************
- PROTOTYPES
-***************************************************************************/
-
-avi_error avi_open(const char *filename, avi_file **file);
-avi_error avi_create(const char *filename, const avi_movie_info *info, avi_file **file);
-avi_error avi_close(avi_file *file);
-
-void avi_printf_chunks(avi_file *file);
-const char *avi_error_string(avi_error err);
-
-const avi_movie_info *avi_get_movie_info(avi_file *file);
-UINT32 avi_first_sample_in_frame(avi_file *file, UINT32 framenum);
-
-avi_error avi_read_video_frame(avi_file *file, UINT32 framenum, bitmap_yuy16 &bitmap);
-avi_error avi_read_sound_samples(avi_file *file, int channel, UINT32 firstsample, UINT32 numsamples, INT16 *output);
-
-avi_error avi_append_video_frame(avi_file *file, bitmap_yuy16 &bitmap);
-avi_error avi_append_video_frame(avi_file *file, bitmap_rgb32 &bitmap);
-avi_error avi_append_sound_samples(avi_file *file, int channel, const INT16 *samples, UINT32 numsamples, UINT32 sampleskip);
-
-#endif
+#endif // MAME_LIB_UTIL_AVIIO_H
diff --git a/src/lib/util/cdrom.cpp b/src/lib/util/cdrom.cpp
index 8bdf4af6c0f..da3d921ae4a 100644
--- a/src/lib/util/cdrom.cpp
+++ b/src/lib/util/cdrom.cpp
@@ -244,8 +244,8 @@ cdrom_file *cdrom_open(const char *inputfile)
for (i = 0; i < file->cdtoc.numtrks; i++)
{
- file_error filerr = util::core_file::open(file->track_info.track[i].fname.c_str(), OPEN_FLAG_READ, file->fhandle[i]);
- if (filerr != FILERR_NONE)
+ osd_file::error filerr = util::core_file::open(file->track_info.track[i].fname, OPEN_FLAG_READ, file->fhandle[i]);
+ if (filerr != osd_file::error::NONE)
{
fprintf(stderr, "Unable to open file: %s\n", file->track_info.track[i].fname.c_str());
cdrom_close(file);
diff --git a/src/lib/util/chd.cpp b/src/lib/util/chd.cpp
index 93a1b34ba29..3a97c6ce0fe 100644
--- a/src/lib/util/chd.cpp
+++ b/src/lib/util/chd.cpp
@@ -660,8 +660,8 @@ chd_error chd_file::create(const char *filename, UINT64 logicalbytes, UINT32 hun
// create the new file
util::core_file::ptr file;
- const file_error filerr = util::core_file::open(filename, OPEN_FLAG_READ | OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, file);
- if (filerr != FILERR_NONE)
+ const osd_file::error filerr = util::core_file::open(filename, OPEN_FLAG_READ | OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, file);
+ if (filerr != osd_file::error::NONE)
return CHDERR_FILE_NOT_FOUND;
// create the file normally, then claim the file
@@ -672,7 +672,7 @@ chd_error chd_file::create(const char *filename, UINT64 logicalbytes, UINT32 hun
if (chderr != CHDERR_NONE)
{
file.reset();
- osd_rmfile(filename);
+ osd_file::remove(filename);
}
else
{
@@ -705,8 +705,8 @@ chd_error chd_file::create(const char *filename, UINT64 logicalbytes, UINT32 hun
// create the new file
util::core_file::ptr file;
- const file_error filerr = util::core_file::open(filename, OPEN_FLAG_READ | OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, file);
- if (filerr != FILERR_NONE)
+ const osd_file::error filerr = util::core_file::open(filename, OPEN_FLAG_READ | OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, file);
+ if (filerr != osd_file::error::NONE)
return CHDERR_FILE_NOT_FOUND;
// create the file normally, then claim the file
@@ -717,7 +717,7 @@ chd_error chd_file::create(const char *filename, UINT64 logicalbytes, UINT32 hun
if (chderr != CHDERR_NONE)
{
file.reset();
- osd_rmfile(filename);
+ osd_file::remove(filename);
}
else
{
@@ -749,8 +749,8 @@ chd_error chd_file::open(const char *filename, bool writeable, chd_file *parent)
// open the file
const UINT32 openflags = writeable ? (OPEN_FLAG_READ | OPEN_FLAG_WRITE) : OPEN_FLAG_READ;
util::core_file::ptr file;
- const file_error filerr = util::core_file::open(filename, openflags, file);
- if (filerr != FILERR_NONE)
+ const osd_file::error filerr = util::core_file::open(filename, openflags, file);
+ if (filerr != osd_file::error::NONE)
return CHDERR_FILE_NOT_FOUND;
// now open the CHD
diff --git a/src/lib/util/chdcd.cpp b/src/lib/util/chdcd.cpp
index eeb196d242f..0e8b32b1ed6 100644
--- a/src/lib/util/chdcd.cpp
+++ b/src/lib/util/chdcd.cpp
@@ -87,13 +87,10 @@ static std::string get_file_path(std::string &path)
static UINT64 get_file_size(const char *filename)
{
- osd_file *file;
- UINT64 filesize = 0;
- file_error filerr;
+ osd_file::ptr file;
+ std::uint64_t filesize = 0;
- filerr = osd_open(filename, OPEN_FLAG_READ, &file, &filesize);
- if (filerr == FILERR_NONE)
- osd_close(file);
+ osd_file::open(filename, OPEN_FLAG_READ, file, filesize);
return filesize;
}
@@ -215,57 +212,51 @@ static UINT32 parse_wav_sample(const char *filename, UINT32 *dataoffs)
UINT32 length, rate, filesize;
UINT16 bits, temp16;
char buf[32];
- osd_file *file;
- file_error filerr;
+ osd_file::ptr file;
UINT64 fsize = 0;
- UINT32 actual;
+ std::uint32_t actual;
- filerr = osd_open(filename, OPEN_FLAG_READ, &file, &fsize);
- if (filerr != FILERR_NONE)
+ osd_file::error filerr = osd_file::open(filename, OPEN_FLAG_READ, file, fsize);
+ if (filerr != osd_file::error::NONE)
{
printf("ERROR: could not open (%s)\n", filename);
return 0;
}
/* read the core header and make sure it's a WAVE file */
- osd_read(file, buf, 0, 4, &actual);
+ file->read(buf, 0, 4, actual);
offset += actual;
if (offset < 4)
{
- osd_close(file);
printf("ERROR: unexpected RIFF offset %lu (%s)\n", offset, filename);
return 0;
}
if (memcmp(&buf[0], "RIFF", 4) != 0)
{
- osd_close(file);
printf("ERROR: could not find RIFF header (%s)\n", filename);
return 0;
}
/* get the total size */
- osd_read(file, &filesize, offset, 4, &actual);
+ file->read(&filesize, offset, 4, actual);
offset += actual;
if (offset < 8)
{
- osd_close(file);
printf("ERROR: unexpected size offset %lu (%s)\n", offset, filename);
return 0;
}
filesize = LITTLE_ENDIANIZE_INT32(filesize);
/* read the RIFF file type and make sure it's a WAVE file */
- osd_read(file, buf, offset, 4, &actual);
+ file->read(buf, offset, 4, actual);
offset += actual;
if (offset < 12)
{
- osd_close(file);
printf("ERROR: unexpected WAVE offset %lu (%s)\n", offset, filename);
return 0;
}
if (memcmp(&buf[0], "WAVE", 4) != 0)
{
- osd_close(file);
printf("ERROR: could not find WAVE header (%s)\n", filename);
return 0;
}
@@ -273,9 +264,9 @@ static UINT32 parse_wav_sample(const char *filename, UINT32 *dataoffs)
/* seek until we find a format tag */
while (1)
{
- osd_read(file, buf, offset, 4, &actual);
+ file->read(buf, offset, 4, actual);
offset += actual;
- osd_read(file, &length, offset, 4, &actual);
+ file->read(&length, offset, 4, actual);
offset += actual;
length = LITTLE_ENDIANIZE_INT32(length);
if (memcmp(&buf[0], "fmt ", 4) == 0)
@@ -285,56 +276,51 @@ static UINT32 parse_wav_sample(const char *filename, UINT32 *dataoffs)
offset += length;
if (offset >= filesize)
{
- osd_close(file);
printf("ERROR: could not find fmt tag (%s)\n", filename);
return 0;
}
}
/* read the format -- make sure it is PCM */
- osd_read(file, &temp16, offset, 2, &actual);
+ file->read(&temp16, offset, 2, actual);
offset += actual;
temp16 = LITTLE_ENDIANIZE_INT16(temp16);
if (temp16 != 1)
{
- osd_close(file);
printf("ERROR: unsupported format %u - only PCM is supported (%s)\n", temp16, filename);
return 0;
}
/* number of channels -- only stereo is supported */
- osd_read(file, &temp16, offset, 2, &actual);
+ file->read(&temp16, offset, 2, actual);
offset += actual;
temp16 = LITTLE_ENDIANIZE_INT16(temp16);
if (temp16 != 2)
{
- osd_close(file);
printf("ERROR: unsupported number of channels %u - only stereo is supported (%s)\n", temp16, filename);
return 0;
}
/* sample rate */
- osd_read(file, &rate, offset, 4, &actual);
+ file->read(&rate, offset, 4, actual);
offset += actual;
rate = LITTLE_ENDIANIZE_INT32(rate);
if (rate != 44100)
{
- osd_close(file);
printf("ERROR: unsupported samplerate %u - only 44100 is supported (%s)\n", rate, filename);
return 0;
}
/* bytes/second and block alignment are ignored */
- osd_read(file, buf, offset, 6, &actual);
+ file->read(buf, offset, 6, actual);
offset += actual;
/* bits/sample */
- osd_read(file, &bits, offset, 2, &actual);
+ file->read(&bits, offset, 2, actual);
offset += actual;
bits = LITTLE_ENDIANIZE_INT16(bits);
if (bits != 16)
{
- osd_close(file);
printf("ERROR: unsupported bits/sample %u - only 16 is supported (%s)\n", bits, filename);
return 0;
}
@@ -345,9 +331,9 @@ static UINT32 parse_wav_sample(const char *filename, UINT32 *dataoffs)
/* seek until we find a data tag */
while (1)
{
- osd_read(file, buf, offset, 4, &actual);
+ file->read(buf, offset, 4, actual);
offset += actual;
- osd_read(file, &length, offset, 4, &actual);
+ file->read(&length, offset, 4, actual);
offset += actual;
length = LITTLE_ENDIANIZE_INT32(length);
if (memcmp(&buf[0], "data", 4) == 0)
@@ -357,14 +343,11 @@ static UINT32 parse_wav_sample(const char *filename, UINT32 *dataoffs)
offset += length;
if (offset >= filesize)
{
- osd_close(file);
printf("ERROR: could not find data tag (%s)\n", filename);
return 0;
}
}
- osd_close(file);
-
/* if there was a 0 length data block, we're done */
if (length == 0)
{
diff --git a/src/lib/util/corealloc.h b/src/lib/util/corealloc.h
index 2c1df6dd46c..b5fc126cba5 100644
--- a/src/lib/util/corealloc.h
+++ b/src/lib/util/corealloc.h
@@ -10,15 +10,20 @@
#pragma once
-#ifndef __COREALLOC_H__
-#define __COREALLOC_H__
+#ifndef MAME_LIB_UTIL_COREALLOC_H
+#define MAME_LIB_UTIL_COREALLOC_H
+
+#include "osdcore.h"
#include <stdlib.h>
+
+#include <cstddef>
+#include <cstring>
#include <new>
+#include <memory>
#include <type_traits>
#include <utility>
-#include <memory>
-#include "osdcore.h"
+
//**************************************************************************
@@ -35,21 +40,21 @@
-template<typename _Tp, typename... _Args>
-inline _Tp* global_alloc_clear(_Args&&... __args)
+template<typename T, typename... Params>
+inline T* global_alloc_clear(Params &&... args)
{
- unsigned char * ptr = new unsigned char[sizeof(_Tp)]; // allocate memory
- memset(ptr, 0, sizeof(_Tp));
- return new(ptr) _Tp(std::forward<_Args>(__args)...);
+ void *const ptr = ::operator new(sizeof(T)); // allocate memory
+ std::memset(ptr, 0, sizeof(T));
+ return new(ptr) T(std::forward<Params>(args)...);
}
-template<typename _Tp>
-inline _Tp* global_alloc_array_clear(size_t __num)
+template<typename T>
+inline T* global_alloc_array_clear(std::size_t num)
{
- auto size = sizeof(_Tp) * __num;
- unsigned char* ptr = new unsigned char[size]; // allocate memory
- memset(ptr, 0, size);
- return new(ptr) _Tp[__num]();
+ auto const size = sizeof(T) * num;
+ void *const ptr = new unsigned char[size]; // allocate memory
+ std::memset(ptr, 0, size);
+ return new(ptr) T[num]();
}
@@ -104,4 +109,4 @@ inline typename _MakeUniqClear<_Tp>::__array make_unique_clear(size_t __num)
template<typename _Tp, typename... _Args>
inline typename _MakeUniqClear<_Tp>::__invalid_type make_unique_clear(_Args&&...) = delete;
-#endif /* __COREALLOC_H__ */
+#endif // MAME_LIB_UTIL_COREALLOC_H
diff --git a/src/lib/util/corefile.cpp b/src/lib/util/corefile.cpp
index 64169a606fc..e3d34ec3738 100644
--- a/src/lib/util/corefile.cpp
+++ b/src/lib/util/corefile.cpp
@@ -23,9 +23,7 @@
namespace util {
-
namespace {
-
/***************************************************************************
VALIDATION
***************************************************************************/
@@ -143,7 +141,7 @@ class core_proxy_file : public core_file
public:
core_proxy_file(core_file &file) : m_file(file) { }
virtual ~core_proxy_file() override { }
- virtual file_error compress(int level) override { return m_file.compress(level); }
+ virtual osd_file::error compress(int level) override { return m_file.compress(level); }
virtual int seek(std::int64_t offset, int whence) override { return m_file.seek(offset, whence); }
virtual std::uint64_t tell() const override { return m_file.tell(); }
@@ -159,9 +157,9 @@ public:
virtual std::uint32_t write(const void *buffer, std::uint32_t length) override { return m_file.write(buffer, length); }
virtual int puts(const char *s) override { return m_file.puts(s); }
virtual int vprintf(util::format_argument_pack<std::ostream> const &args) override { return m_file.vprintf(args); }
- virtual file_error truncate(std::uint64_t offset) override { return m_file.truncate(offset); }
+ virtual osd_file::error truncate(std::uint64_t offset) override { return m_file.truncate(offset); }
- virtual file_error flush() override { return m_file.flush(); }
+ virtual osd_file::error flush() override { return m_file.flush(); }
private:
core_file &m_file;
@@ -232,7 +230,7 @@ public:
}
~core_in_memory_file() override { purge(); }
- virtual file_error compress(int level) override { return FILERR_INVALID_ACCESS; }
+ virtual osd_file::error compress(int level) override { return osd_file::error::INVALID_ACCESS; }
virtual int seek(std::int64_t offset, int whence) override;
virtual std::uint64_t tell() const override { return m_offset; }
@@ -243,8 +241,8 @@ public:
virtual void const *buffer() override { return m_data; }
virtual std::uint32_t write(void const *buffer, std::uint32_t length) override { return 0; }
- virtual file_error truncate(std::uint64_t offset) override;
- virtual file_error flush() override { clear_putback(); return FILERR_NONE; }
+ virtual osd_file::error truncate(std::uint64_t offset) override;
+ virtual osd_file::error flush() override { clear_putback(); return osd_file::error::NONE; }
protected:
core_in_memory_file(std::uint32_t openflags, std::uint64_t length)
@@ -295,9 +293,9 @@ private:
class core_osd_file : public core_in_memory_file
{
public:
- core_osd_file(std::uint32_t openmode, osd_file *file, std::uint64_t length)
+ core_osd_file(std::uint32_t openmode, osd_file::ptr &&file, std::uint64_t length)
: core_in_memory_file(openmode, length)
- , m_file(file)
+ , m_file(std::move(file))
, m_zdata()
, m_bufferbase(0)
, m_bufferbytes(0)
@@ -305,7 +303,7 @@ public:
}
~core_osd_file() override;
- virtual file_error compress(int level) override;
+ virtual osd_file::error compress(int level) override;
virtual int seek(std::int64_t offset, int whence) override;
@@ -313,8 +311,8 @@ public:
virtual void const *buffer() override;
virtual std::uint32_t write(void const *buffer, std::uint32_t length) override;
- virtual file_error truncate(std::uint64_t offset) override;
- virtual file_error flush() override;
+ virtual osd_file::error truncate(std::uint64_t offset) override;
+ virtual osd_file::error flush() override;
protected:
@@ -323,10 +321,10 @@ protected:
private:
static constexpr std::size_t FILE_BUFFER_SIZE = 512;
- file_error osd_or_zlib_read(void *buffer, std::uint64_t offset, std::uint32_t length, std::uint32_t &actual);
- file_error osd_or_zlib_write(void const *buffer, std::uint64_t offset, std::uint32_t length, std::uint32_t &actual);
+ osd_file::error osd_or_zlib_read(void *buffer, std::uint64_t offset, std::uint32_t length, std::uint32_t &actual);
+ osd_file::error osd_or_zlib_write(void const *buffer, std::uint64_t offset, std::uint32_t length, std::uint32_t &actual);
- osd_file * m_file; // OSD file handle
+ osd_file::ptr m_file; // OSD file handle
zlib_data::ptr m_zdata; // compression data
std::uint64_t m_bufferbase; // base offset of internal buffer
std::uint32_t m_bufferbytes; // bytes currently loaded into buffer
@@ -613,6 +611,7 @@ int core_text_file::puts(char const *s)
int core_text_file::vprintf(util::format_argument_pack<std::ostream> const &args)
{
+ m_printf_buffer.clear();
m_printf_buffer.reserve(1024);
m_printf_buffer.seekp(0, ovectorstream::beg);
util::stream_format<std::ostream, std::ostream>(m_printf_buffer, args);
@@ -688,14 +687,14 @@ std::uint32_t core_in_memory_file::read(void *buffer, std::uint32_t length)
truncate - truncate a file
-------------------------------------------------*/
-file_error core_in_memory_file::truncate(std::uint64_t offset)
+osd_file::error core_in_memory_file::truncate(std::uint64_t offset)
{
if (m_length < offset)
- return FILERR_FAILURE;
+ return osd_file::error::FAILURE;
// adjust to new length and offset
set_length(offset);
- return FILERR_NONE;
+ return osd_file::error::NONE;
}
@@ -736,8 +735,6 @@ core_osd_file::~core_osd_file()
// close files and free memory
if (m_zdata)
compress(FCOMPRESS_NONE);
- if (m_file)
- osd_close(m_file);
}
@@ -747,13 +744,13 @@ core_osd_file::~core_osd_file()
compression, or up to 9 for max compression
-------------------------------------------------*/
-file_error core_osd_file::compress(int level)
+osd_file::error core_osd_file::compress(int level)
{
- file_error result = FILERR_NONE;
+ osd_file::error result = osd_file::error::NONE;
// can only do this for read-only and write-only cases
if (read_access() && write_access())
- return FILERR_INVALID_ACCESS;
+ return osd_file::error::INVALID_ACCESS;
// if we have been compressing, flush and free the data
if (m_zdata && (level == FCOMPRESS_NONE))
@@ -767,7 +764,7 @@ file_error core_osd_file::compress(int level)
zerr = m_zdata->finalise();
if ((zerr != Z_STREAM_END) && (zerr != Z_OK))
{
- result = FILERR_INVALID_DATA;
+ result = osd_file::error::INVALID_DATA;
break;
}
@@ -775,8 +772,8 @@ file_error core_osd_file::compress(int level)
if (m_zdata->has_output())
{
std::uint32_t actualdata;
- auto const filerr = osd_write(m_file, m_zdata->buffer_data(), m_zdata->realoffset(), m_zdata->output_size(), &actualdata);
- if (filerr != FILERR_NONE)
+ auto const filerr = m_file->write(m_zdata->buffer_data(), m_zdata->realoffset(), m_zdata->output_size(), actualdata);
+ if (filerr != osd_file::error::NONE)
break;
m_zdata->add_realoffset(actualdata);
m_zdata->reset_output();
@@ -800,7 +797,7 @@ file_error core_osd_file::compress(int level)
// on error, return an error
if (zerr != Z_OK)
- return FILERR_OUT_OF_MEMORY;
+ return osd_file::error::OUT_OF_MEMORY;
// flush buffers
m_bufferbytes = 0;
@@ -888,13 +885,12 @@ void const *core_osd_file::buffer()
// read the file
std::uint32_t read_length = 0;
auto const filerr = osd_or_zlib_read(buf, 0, length(), read_length);
- if ((filerr != FILERR_NONE) || (read_length != length()))
+ if ((filerr != osd_file::error::NONE) || (read_length != length()))
purge();
else
{
// close the file because we don't need it anymore
- osd_close(m_file);
- m_file = nullptr;
+ m_file.reset();
}
}
return core_in_memory_file::buffer();
@@ -931,19 +927,19 @@ std::uint32_t core_osd_file::write(void const *buffer, std::uint32_t length)
truncate - truncate a file
-------------------------------------------------*/
-file_error core_osd_file::truncate(std::uint64_t offset)
+osd_file::error core_osd_file::truncate(std::uint64_t offset)
{
if (is_loaded())
return core_in_memory_file::truncate(offset);
// truncate file
- auto const err = osd_truncate(m_file, offset);
- if (err != FILERR_NONE)
+ auto const err = m_file->truncate(offset);
+ if (err != osd_file::error::NONE)
return err;
// and adjust to new length and offset
set_length(offset);
- return FILERR_NONE;
+ return osd_file::error::NONE;
}
@@ -951,7 +947,7 @@ file_error core_osd_file::truncate(std::uint64_t offset)
flush - flush file buffers
-------------------------------------------------*/
-file_error core_osd_file::flush()
+osd_file::error core_osd_file::flush()
{
if (is_loaded())
return core_in_memory_file::flush();
@@ -962,7 +958,7 @@ file_error core_osd_file::flush()
// invalidate any buffered data
m_bufferbytes = 0;
- return osd_fflush(m_file);
+ return m_file->flush();
}
@@ -971,18 +967,18 @@ file_error core_osd_file::flush()
handles zlib-compressed data
-------------------------------------------------*/
-file_error core_osd_file::osd_or_zlib_read(void *buffer, std::uint64_t offset, std::uint32_t length, std::uint32_t &actual)
+osd_file::error core_osd_file::osd_or_zlib_read(void *buffer, std::uint64_t offset, std::uint32_t length, std::uint32_t &actual)
{
// if no compression, just pass through
if (!m_zdata)
- return osd_read(m_file, buffer, offset, length, &actual);
+ return m_file->read(buffer, offset, length, actual);
// if the offset doesn't match the next offset, fail
if (!m_zdata->is_nextoffset(offset))
- return FILERR_INVALID_ACCESS;
+ return osd_file::error::INVALID_ACCESS;
// set up the destination
- file_error filerr = FILERR_NONE;
+ osd_file::error filerr = osd_file::error::NONE;
m_zdata->set_output(buffer, length);
while (!m_zdata->output_full())
{
@@ -992,7 +988,7 @@ file_error core_osd_file::osd_or_zlib_read(void *buffer, std::uint64_t offset, s
auto const zerr = m_zdata->decompress();
if (Z_OK != zerr)
{
- if (Z_STREAM_END != zerr) filerr = FILERR_INVALID_DATA;
+ if (Z_STREAM_END != zerr) filerr = osd_file::error::INVALID_DATA;
break;
}
}
@@ -1001,8 +997,8 @@ file_error core_osd_file::osd_or_zlib_read(void *buffer, std::uint64_t offset, s
if (!m_zdata->has_input())
{
std::uint32_t actualdata = 0;
- filerr = osd_read(m_file, m_zdata->buffer_data(), m_zdata->realoffset(), m_zdata->buffer_size(), &actualdata);
- if (filerr != FILERR_NONE) break;
+ filerr = m_file->read(m_zdata->buffer_data(), m_zdata->realoffset(), m_zdata->buffer_size(), actualdata);
+ if (filerr != osd_file::error::NONE) break;
m_zdata->add_realoffset(actualdata);
m_zdata->reset_input(actualdata);
if (!m_zdata->has_input()) break;
@@ -1022,7 +1018,7 @@ file_error core_osd_file::osd_or_zlib_read(void *buffer, std::uint64_t offset, s
-------------------------------------------------*/
/**
- * @fn file_error osd_or_zlib_write(void const *buffer, std::uint64_t offset, std::uint32_t length, std::uint32_t actual)
+ * @fn osd_file::error osd_or_zlib_write(void const *buffer, std::uint64_t offset, std::uint32_t length, std::uint32_t actual)
*
* @brief OSD or zlib write.
*
@@ -1031,18 +1027,18 @@ file_error core_osd_file::osd_or_zlib_read(void *buffer, std::uint64_t offset, s
* @param length The length.
* @param [in,out] actual The actual.
*
- * @return A file_error.
+ * @return A osd_file::error.
*/
-file_error core_osd_file::osd_or_zlib_write(void const *buffer, std::uint64_t offset, std::uint32_t length, std::uint32_t &actual)
+osd_file::error core_osd_file::osd_or_zlib_write(void const *buffer, std::uint64_t offset, std::uint32_t length, std::uint32_t &actual)
{
// if no compression, just pass through
if (!m_zdata)
- return osd_write(m_file, buffer, offset, length, &actual);
+ return m_file->write(buffer, offset, length, actual);
// if the offset doesn't match the next offset, fail
if (!m_zdata->is_nextoffset(offset))
- return FILERR_INVALID_ACCESS;
+ return osd_file::error::INVALID_ACCESS;
// set up the source
m_zdata->set_input(buffer, length);
@@ -1054,15 +1050,15 @@ file_error core_osd_file::osd_or_zlib_write(void const *buffer, std::uint64_t of
{
actual = length - m_zdata->input_size();
m_zdata->add_nextoffset(actual);
- return FILERR_INVALID_DATA;
+ return osd_file::error::INVALID_DATA;
}
// write more data if we are full up
if (m_zdata->output_full())
{
std::uint32_t actualdata = 0;
- auto const filerr = osd_write(m_file, m_zdata->buffer_data(), m_zdata->realoffset(), m_zdata->output_size(), &actualdata);
- if (filerr != FILERR_NONE)
+ auto const filerr = m_file->write(m_zdata->buffer_data(), m_zdata->realoffset(), m_zdata->output_size(), actualdata);
+ if (filerr != osd_file::error::NONE)
return filerr;
m_zdata->add_realoffset(actualdata);
m_zdata->reset_output();
@@ -1072,7 +1068,7 @@ file_error core_osd_file::osd_or_zlib_write(void const *buffer, std::uint64_t of
// we wrote everything
actual = length;
m_zdata->add_nextoffset(actual);
- return FILERR_NONE;
+ return osd_file::error::NONE;
}
} // anonymous namespace
@@ -1088,24 +1084,23 @@ file_error core_osd_file::osd_or_zlib_write(void const *buffer, std::uint64_t of
return an error code
-------------------------------------------------*/
-file_error core_file::open(char const *filename, std::uint32_t openflags, ptr &file)
+osd_file::error core_file::open(std::string const &filename, std::uint32_t openflags, ptr &file)
{
- // attempt to open the file
- osd_file *f = nullptr;
- std::uint64_t length = 0;
- auto const filerr = osd_open(filename, openflags, &f, &length);
- if (filerr != FILERR_NONE)
- return filerr;
-
try
{
- file = std::make_unique<core_osd_file>(openflags, f, length);
- return FILERR_NONE;
+ // attempt to open the file
+ osd_file::ptr f;
+ std::uint64_t length = 0;
+ auto const filerr = osd_file::open(filename, openflags, f, length);
+ if (filerr != osd_file::error::NONE)
+ return filerr;
+
+ file = std::make_unique<core_osd_file>(openflags, std::move(f), length);
+ return osd_file::error::NONE;
}
catch (...)
{
- osd_close(f);
- return FILERR_OUT_OF_MEMORY;
+ return osd_file::error::OUT_OF_MEMORY;
}
}
@@ -1115,20 +1110,20 @@ file_error core_file::open(char const *filename, std::uint32_t openflags, ptr &f
like access and return an error code
-------------------------------------------------*/
-file_error core_file::open_ram(void const *data, std::size_t length, std::uint32_t openflags, ptr &file)
+osd_file::error core_file::open_ram(void const *data, std::size_t length, std::uint32_t openflags, ptr &file)
{
// can only do this for read access
if ((openflags & OPEN_FLAG_WRITE) || (openflags & OPEN_FLAG_CREATE))
- return FILERR_INVALID_ACCESS;
+ return osd_file::error::INVALID_ACCESS;
try
{
file.reset(new core_in_memory_file(openflags, data, length, false));
- return FILERR_NONE;
+ return osd_file::error::NONE;
}
catch (...)
{
- return FILERR_OUT_OF_MEMORY;
+ return osd_file::error::OUT_OF_MEMORY;
}
}
@@ -1139,24 +1134,24 @@ file_error core_file::open_ram(void const *data, std::size_t length, std::uint32
error code
-------------------------------------------------*/
-file_error core_file::open_ram_copy(void const *data, std::size_t length, std::uint32_t openflags, ptr &file)
+osd_file::error core_file::open_ram_copy(void const *data, std::size_t length, std::uint32_t openflags, ptr &file)
{
// can only do this for read access
if ((openflags & OPEN_FLAG_WRITE) || (openflags & OPEN_FLAG_CREATE))
- return FILERR_INVALID_ACCESS;
+ return osd_file::error::INVALID_ACCESS;
try
{
ptr result(new core_in_memory_file(openflags, data, length, true));
if (!result->buffer())
- return FILERR_OUT_OF_MEMORY;
+ return osd_file::error::OUT_OF_MEMORY;
file = std::move(result);
- return FILERR_NONE;
+ return osd_file::error::NONE;
}
catch (...)
{
- return FILERR_OUT_OF_MEMORY;
+ return osd_file::error::OUT_OF_MEMORY;
}
}
@@ -1166,16 +1161,16 @@ file_error core_file::open_ram_copy(void const *data, std::size_t length, std::u
object and return an error code
-------------------------------------------------*/
-file_error core_file::open_proxy(core_file &file, ptr &proxy)
+osd_file::error core_file::open_proxy(core_file &file, ptr &proxy)
{
try
{
proxy = std::make_unique<core_proxy_file>(file);
- return FILERR_NONE;
+ return osd_file::error::NONE;
}
catch (...)
{
- return FILERR_OUT_OF_MEMORY;
+ return osd_file::error::OUT_OF_MEMORY;
}
}
@@ -1195,19 +1190,19 @@ core_file::~core_file()
pointer
-------------------------------------------------*/
-file_error core_file::load(char const *filename, void **data, std::uint32_t &length)
+osd_file::error core_file::load(std::string const &filename, void **data, std::uint32_t &length)
{
ptr file;
// attempt to open the file
auto const err = open(filename, OPEN_FLAG_READ, file);
- if (err != FILERR_NONE)
+ if (err != osd_file::error::NONE)
return err;
// get the size
auto const size = file->size();
if (std::uint32_t(size) != size)
- return FILERR_OUT_OF_MEMORY;
+ return osd_file::error::OUT_OF_MEMORY;
// allocate memory
*data = osd_malloc(size);
@@ -1217,26 +1212,26 @@ file_error core_file::load(char const *filename, void **data, std::uint32_t &len
if (file->read(*data, size) != size)
{
free(*data);
- return FILERR_FAILURE;
+ return osd_file::error::FAILURE;
}
// close the file and return data
- return FILERR_NONE;
+ return osd_file::error::NONE;
}
-file_error core_file::load(char const *filename, dynamic_buffer &data)
+osd_file::error core_file::load(std::string const &filename, dynamic_buffer &data)
{
ptr file;
// attempt to open the file
auto const err = open(filename, OPEN_FLAG_READ, file);
- if (err != FILERR_NONE)
+ if (err != osd_file::error::NONE)
return err;
// get the size
auto const size = file->size();
if (std::uint32_t(size) != size)
- return FILERR_OUT_OF_MEMORY;
+ return osd_file::error::OUT_OF_MEMORY;
// allocate memory
data.resize(size);
@@ -1245,11 +1240,11 @@ file_error core_file::load(char const *filename, dynamic_buffer &data)
if (file->read(&data[0], size) != size)
{
data.clear();
- return FILERR_FAILURE;
+ return osd_file::error::FAILURE;
}
// close the file and return data
- return FILERR_NONE;
+ return osd_file::error::NONE;
}
diff --git a/src/lib/util/corefile.h b/src/lib/util/corefile.h
index 7ec76af7cb5..8f71832411f 100644
--- a/src/lib/util/corefile.h
+++ b/src/lib/util/corefile.h
@@ -10,8 +10,8 @@
#pragma once
-#ifndef __COREFILE_H__
-#define __COREFILE_H__
+#ifndef MAME_LIB_UTIL_COREFILE_H
+#define MAME_LIB_UTIL_COREFILE_H
#include "corestr.h"
#include "coretmpl.h"
@@ -23,7 +23,6 @@
namespace util {
-
/***************************************************************************
ADDITIONAL OPEN FLAGS
***************************************************************************/
@@ -49,22 +48,22 @@ public:
// ----- file open/close -----
// open a file with the specified filename
- static file_error open(const char *filename, std::uint32_t openflags, ptr &file);
+ static osd_file::error open(std::string const &filename, std::uint32_t openflags, ptr &file);
// open a RAM-based "file" using the given data and length (read-only)
- static file_error open_ram(const void *data, std::size_t length, std::uint32_t openflags, ptr &file);
+ static osd_file::error open_ram(const void *data, std::size_t length, std::uint32_t openflags, ptr &file);
// open a RAM-based "file" using the given data and length (read-only), copying the data
- static file_error open_ram_copy(const void *data, std::size_t length, std::uint32_t openflags, ptr &file);
+ static osd_file::error open_ram_copy(const void *data, std::size_t length, std::uint32_t openflags, ptr &file);
// open a proxy "file" that forwards requests to another file object
- static file_error open_proxy(core_file &file, ptr &proxy);
+ static osd_file::error open_proxy(core_file &file, ptr &proxy);
// close an open file
virtual ~core_file();
// enable/disable streaming file compression via zlib; level is 0 to disable compression, or up to 9 for max compression
- virtual file_error compress(int level) = 0;
+ virtual osd_file::error compress(int level) = 0;
// ----- file positioning -----
@@ -101,8 +100,8 @@ public:
virtual const void *buffer() = 0;
// open a file with the specified filename, read it into memory, and return a pointer
- static file_error load(const char *filename, void **data, std::uint32_t &length);
- static file_error load(const char *filename, dynamic_buffer &data);
+ static osd_file::error load(std::string const &filename, void **data, std::uint32_t &length);
+ static osd_file::error load(std::string const &filename, dynamic_buffer &data);
// ----- file write -----
@@ -121,10 +120,10 @@ public:
}
// file truncation
- virtual file_error truncate(std::uint64_t offset) = 0;
+ virtual osd_file::error truncate(std::uint64_t offset) = 0;
// flush file buffers
- virtual file_error flush() = 0;
+ virtual osd_file::error flush() = 0;
protected:
@@ -147,4 +146,4 @@ std::string core_filename_extract_base(const char *name, bool strip_extension =
int core_filename_ends_with(const char *filename, const char *extension);
-#endif /* __COREFILE_H__ */
+#endif // MAME_LIB_UTIL_COREFILE_H
diff --git a/src/lib/util/delegate.cpp b/src/lib/util/delegate.cpp
index 9c9e0fd3bf7..c8633633325 100644
--- a/src/lib/util/delegate.cpp
+++ b/src/lib/util/delegate.cpp
@@ -39,15 +39,12 @@ delegate_mfp::raw_mfp_data delegate_mfp::s_null_mfp = { {0 }};
delegate_generic_function delegate_mfp::convert_to_generic(delegate_generic_class *&object) const
{
-#if defined(__arm__) || defined(__ARMEL__) || defined(__aarch64__)
- // apply the "this" delta to the object first
- object = reinterpret_cast<delegate_generic_class *>(reinterpret_cast<std::uint8_t *>(object));
-
- // if the low bit of the vtable index is clear, then it is just a raw function pointer
- if (m_this_delta==0) {
+#if defined(__arm__) || defined(__ARMEL__) || defined(__aarch64__) || defined(__MIPSEL__) || defined(__mips_isa_rev) || defined(__mips64) || defined(EMSCRIPTEN)
+ if ((m_this_delta & 1) == 0) {
#if defined(LOG_DELEGATES)
printf("Calculated Addr = %08x\n", (uintptr_t)(void*)(m_function));
#endif
+ object = reinterpret_cast<delegate_generic_class *>(reinterpret_cast<std::uint8_t *>(object) + m_this_delta);
return reinterpret_cast<delegate_generic_function>(m_function);
}
object = reinterpret_cast<delegate_generic_class *>(reinterpret_cast<std::uint8_t *>(object));
diff --git a/src/lib/util/delegate.h b/src/lib/util/delegate.h
index ceae47bf54c..6b4f6a01f58 100644
--- a/src/lib/util/delegate.h
+++ b/src/lib/util/delegate.h
@@ -103,8 +103,6 @@
#define HAS_DIFFERENT_ABI 1
#elif defined(__clang__) && defined(__i386__) && defined(_WIN32)
#define USE_DELEGATE_TYPE DELEGATE_TYPE_COMPATIBLE
- #elif defined(EMSCRIPTEN)
- #define USE_DELEGATE_TYPE DELEGATE_TYPE_COMPATIBLE
#else
#define USE_DELEGATE_TYPE DELEGATE_TYPE_INTERNAL
#define MEMBER_ABI
diff --git a/src/lib/util/un7z.cpp b/src/lib/util/un7z.cpp
index b9cfa13eafe..bca825c1f71 100644
--- a/src/lib/util/un7z.cpp
+++ b/src/lib/util/un7z.cpp
@@ -1,5 +1,5 @@
// license:BSD-3-Clause
-// copyright-holders:Aaron Giles
+// copyright-holders:Aaron Giles, Vas Crabb
/***************************************************************************
un7z.c
@@ -10,364 +10,296 @@
// this is based on unzip.c, with modifications needed to use the 7zip library
-#include "osdcore.h"
-#include "un7z.h"
+#include "unzip.h"
-#include <ctype.h>
-#include <stdlib.h>
-#include <zlib.h>
+#include "corestr.h"
+#include "unicode.h"
+#include "lzma/C/7z.h"
+#include "lzma/C/7zCrc.h"
+#include "lzma/C/7zVersion.h"
+
+#include <algorithm>
+#include <array>
+#include <cassert>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <mutex>
+#include <utility>
+#include <vector>
+
+
+namespace util {
+namespace {
/***************************************************************************
- 7Zip Memory / File handling (adapted from 7zfile.c/.h and 7zalloc.c/.h)
+ TYPE DEFINITIONS
***************************************************************************/
-void *SZipAlloc(void *p, size_t size)
+struct CSzFile
{
- if (size == 0)
- return nullptr;
+ CSzFile() : currfpos(0), length(0), osdfile() {}
- return malloc(size);
-}
+ long currfpos;
+ std::uint64_t length;
+ osd_file::ptr osdfile;
-void SZipFree(void *p, void *address)
-{
- free(address);
-}
+ WRes read(void *data, std::size_t &size)
+ {
+ if (!osdfile)
+ {
+ std::printf("un7z.c: called File_Read without file\n");
+ return 1;
+ }
+ if (!size) return 0;
+ size_t originalSize = size;
+ std::uint32_t read_length;
+ //osd_file::error err =
+ osdfile->read(data, currfpos, originalSize, read_length);
+ size = read_length;
+ currfpos += read_length;
-void File_Construct(CSzFile *p)
-{
- p->_7z_osdfile = nullptr;
-}
+ if (size == originalSize)
+ return 0;
-static WRes File_Open(CSzFile *p, const char *name, int writeMode)
-{
- /* we handle this ourselves ... */
- if (!p->_7z_osdfile) return 1;
- else return 0;
-}
+ return 0;
+ }
+
+ WRes seek(Int64 &pos, ESzSeek origin)
+ {
+ if (origin == 0) currfpos = pos;
+ if (origin == 1) currfpos = currfpos + pos;
+ if (origin == 2) currfpos = length -pos;
-WRes InFile_Open(CSzFile *p, const char *name) { return File_Open(p, name, 0); }
-WRes OutFile_Open(CSzFile *p, const char *name) { return File_Open(p, name, 1); }
+ pos = currfpos;
+ return 0;
+ }
+};
-WRes File_Close(CSzFile *p)
+struct CFileInStream : public ISeekInStream, public CSzFile
{
- /* we handle this ourselves ... */
- return 0;
-}
+ CFileInStream();
+};
-WRes File_Read(CSzFile *p, void *data, size_t *size)
+
+class m7z_file_impl
{
-// file_error err;
- UINT32 read_length;
+public:
+ typedef std::unique_ptr<m7z_file_impl> ptr;
- if (!p->_7z_osdfile)
+ m7z_file_impl(const std::string &filename);
+ ~m7z_file_impl()
{
- printf("un7z.c: called File_Read without file\n");
- return 1;
+ if (m_out_buffer)
+ IAlloc_Free(&m_alloc_imp, m_out_buffer);
+ if (m_inited)
+ SzArEx_Free(&m_db, &m_alloc_imp);
}
- size_t originalSize = *size;
- if (originalSize == 0)
- return 0;
+ static ptr find_cached(const std::string &filename)
+ {
+ std::lock_guard<std::mutex> guard(s_cache_mutex);
+ for (std::size_t cachenum = 0; cachenum < s_cache.size(); cachenum++)
+ {
+ // if we have a valid entry and it matches our filename, use it and remove from the cache
+ if (s_cache[cachenum] && (filename == s_cache[cachenum]->m_filename))
+ {
+ ptr result;
+ std::swap(s_cache[cachenum], result);
+ return result;
+ }
+ }
+ return ptr();
+ }
+ static void close(ptr &&archive);
+ static void cache_clear()
+ {
+ // clear call cache entries
+ std::lock_guard<std::mutex> guard(s_cache_mutex);
+ for (std::size_t cachenum = 0; cachenum < s_cache.size(); s_cache[cachenum++].reset()) { }
+ }
-// err =
- osd_read( p->_7z_osdfile, data, p->_7z_currfpos, originalSize, &read_length );
- *size = read_length;
- p->_7z_currfpos += read_length;
+ archive_file::error initialize();
- if (*size == originalSize)
- return 0;
+ int first_file() { return search(0, 0, std::string(), false, false); }
+ int next_file() { return (m_curr_file_idx < 0) ? -1 : search(m_curr_file_idx + 1, 0, std::string(), false, false); }
- return 0;
-}
+ int search(std::uint32_t crc) { return search(0, crc, std::string(), true, false); }
+ int search(const std::string &filename) { return search(0, 0, filename, false, true); }
+ int search(std::uint32_t crc, const std::string &filename) { return search(0, crc, filename, true, true); }
-WRes File_Write(CSzFile *p, const void *data, size_t *size)
-{
- return 0;
-}
+ bool current_is_directory() const { return m_curr_is_dir; }
+ const std::string &current_name() const { return m_curr_name; }
+ std::uint64_t current_uncompressed_length() const { return m_curr_length; }
+ std::uint32_t current_crc() const { return m_curr_crc; }
-WRes File_Seek(CSzFile *p, Int64 *pos, ESzSeek origin)
-{
- if (origin==0) p->_7z_currfpos = *pos;
- if (origin==1) p->_7z_currfpos = p->_7z_currfpos + *pos;
- if (origin==2) p->_7z_currfpos = p->_7z_length - *pos;
+ archive_file::error decompress(void *buffer, std::uint32_t length);
- *pos = p->_7z_currfpos;
+private:
+ m7z_file_impl(const m7z_file_impl &) = delete;
+ m7z_file_impl(m7z_file_impl &&) = delete;
+ m7z_file_impl &operator=(const m7z_file_impl &) = delete;
+ m7z_file_impl &operator=(m7z_file_impl &&) = delete;
- return 0;
-}
+ int search(int i, std::uint32_t search_crc, const std::string &search_filename, bool matchcrc, bool matchname);
+ void make_utf8_name(int index);
-WRes File_GetLength(CSzFile *p, UInt64 *length)
-{
- *length = p->_7z_length;
- return 0;
-}
+ static constexpr std::size_t CACHE_SIZE = 8;
+ static std::array<ptr, CACHE_SIZE> s_cache;
+ static std::mutex s_cache_mutex;
-/* ---------- FileSeqInStream ---------- */
+ const std::string m_filename; // copy of _7Z filename (for caching)
-static SRes FileSeqInStream_Read(void *pp, void *buf, size_t *size)
-{
- CFileSeqInStream *p = (CFileSeqInStream *)pp;
- return File_Read(&p->file, buf, size) == 0 ? SZ_OK : SZ_ERROR_READ;
-}
+ int m_curr_file_idx; // current file index
+ bool m_curr_is_dir; // current file is directory
+ std::string m_curr_name; // current file name
+ std::uint64_t m_curr_length; // current file uncompressed length
+ std::uint32_t m_curr_crc; // current file crc
-void FileSeqInStream_CreateVTable(CFileSeqInStream *p)
-{
- p->s.Read = FileSeqInStream_Read;
-}
+ std::vector<UInt16> m_utf16_buf;
+ std::vector<unicode_char> m_uchar_buf;
+ std::vector<char> m_utf8_buf;
+ CFileInStream m_archive_stream;
+ CLookToRead m_look_stream;
+ CSzArEx m_db;
+ ISzAlloc m_alloc_imp;
+ ISzAlloc m_alloc_temp_imp;
+ bool m_inited;
-/* ---------- FileInStream ---------- */
+ // cached stuff for solid blocks
+ UInt32 m_block_index;
+ Byte * m_out_buffer;
+ std::size_t m_out_buffer_size;
-static SRes FileInStream_Read(void *pp, void *buf, size_t *size)
-{
- CFileInStream *p = (CFileInStream *)pp;
- return (File_Read(&p->file, buf, size) == 0) ? SZ_OK : SZ_ERROR_READ;
-}
+};
-static SRes FileInStream_Seek(void *pp, Int64 *pos, ESzSeek origin)
-{
- CFileInStream *p = (CFileInStream *)pp;
- return File_Seek(&p->file, pos, origin);
-}
-void FileInStream_CreateVTable(CFileInStream *p)
+class m7z_file_wrapper : public archive_file
{
- p->s.Read = FileInStream_Read;
- p->s.Seek = FileInStream_Seek;
-}
+public:
+ m7z_file_wrapper(m7z_file_impl::ptr &&impl) : m_impl(std::move(impl)) { assert(m_impl); }
+ virtual ~m7z_file_wrapper() override { m7z_file_impl::close(std::move(m_impl)); }
-/* ---------- FileOutStream ---------- */
+ virtual int first_file() override { return m_impl->first_file(); }
+ virtual int next_file() override { return m_impl->next_file(); }
-static size_t FileOutStream_Write(void *pp, const void *data, size_t size)
-{
- CFileOutStream *p = (CFileOutStream *)pp;
- File_Write(&p->file, data, &size);
- return size;
-}
+ virtual int search(std::uint32_t crc) override { return m_impl->search(crc); }
+ virtual int search(const std::string &filename) override { return m_impl->search(filename); }
+ virtual int search(std::uint32_t crc, const std::string &filename) override { return m_impl->search(crc, filename); }
-void FileOutStream_CreateVTable(CFileOutStream *p)
-{
- p->s.Write = FileOutStream_Write;
-}
+ virtual bool current_is_directory() const override { return m_impl->current_is_directory(); }
+ virtual const std::string &current_name() const override { return m_impl->current_name(); }
+ virtual std::uint64_t current_uncompressed_length() const override { return m_impl->current_uncompressed_length(); }
+ virtual std::uint32_t current_crc() const override { return m_impl->current_crc(); }
-/***************************************************************************
- CONSTANTS
-***************************************************************************/
+ virtual error decompress(void *buffer, std::uint32_t length) override { return m_impl->decompress(buffer, length); }
+
+private:
+ m7z_file_impl::ptr m_impl;
+};
-/* number of open files to cache */
-#define _7Z_CACHE_SIZE 8
/***************************************************************************
GLOBAL VARIABLES
***************************************************************************/
-static _7z_file *_7z_cache[_7Z_CACHE_SIZE];
-
-/***************************************************************************
- FUNCTION PROTOTYPES
-***************************************************************************/
+std::array<m7z_file_impl::ptr, m7z_file_impl::CACHE_SIZE> m7z_file_impl::s_cache;
+std::mutex m7z_file_impl::s_cache_mutex;
-/* cache management */
-static void free__7z_file(_7z_file *_7z);
/***************************************************************************
- _7Z FILE ACCESS
+ 7Zip Memory / File handling (adapted from 7zfile.c/.h and 7zalloc.c/.h)
***************************************************************************/
-/*-------------------------------------------------
- _7z_file_open - opens a _7Z file for reading
--------------------------------------------------*/
-
-int _7z_search_crc_match(_7z_file *new_7z, UINT32 search_crc, const char* search_filename, int search_filename_length, bool matchcrc, bool matchname)
-{
- UInt16 *temp = nullptr;
- size_t tempSize = 0;
-
- for (int i = 0; i < new_7z->db.db.NumFiles; i++)
- {
- const CSzFileItem *f = new_7z->db.db.Files + i;
- size_t len;
-
- len = SzArEx_GetFileNameUtf16(&new_7z->db, i, nullptr);
-
- // if it's a directory entry we don't care about it..
- if (f->IsDir)
- continue;
-
- if (len > tempSize)
- {
- SZipFree(nullptr, temp);
- tempSize = len;
- temp = (UInt16 *)SZipAlloc(nullptr, tempSize * sizeof(temp[0]));
- if (temp == nullptr)
- {
- return -1; // memory error
- }
- }
-
- bool crcmatch = false;
- bool namematch = false;
-
- UINT64 size = f->Size;
- UINT32 crc = f->Crc;
-
- /* Check for a name match */
- SzArEx_GetFileNameUtf16(&new_7z->db, i, temp);
-
- if (len == search_filename_length+1)
- {
- int j;
- for (j=0;j<search_filename_length;j++)
- {
- UINT8 sn = search_filename[j];
- UINT16 zn = temp[j]; // these are utf16
-
- // MAME filenames are always lowercase so be case insensitive
- if ((zn>=0x41) && (zn<=0x5a)) zn+=0x20;
-
- if (sn != zn) break;
- }
- if (j==search_filename_length) namematch = true;
- }
-
-
- /* Check for a CRC match */
- if (crc==search_crc) crcmatch = true;
-
- bool found = false;
-
- if (matchcrc && matchname)
- {
- if (crcmatch && namematch)
- found = true;
- }
- else if (matchcrc)
- {
- if (crcmatch)
- found = true;
- }
- else if (matchname)
- {
- if (namematch)
- found = true;
- }
+/* ---------- FileInStream ---------- */
- if (found)
- {
- // printf("found %S %d %08x %08x %08x %s %d\n", temp, len, crc, search_crc, size, search_filename, search_filename_length);
- new_7z->curr_file_idx = i;
- new_7z->uncompressed_length = size;
- new_7z->crc = crc;
+extern "C" {
- SZipFree(nullptr, temp);
- return i;
- }
- }
+static void *SZipAlloc(void *p, std::size_t size)
+{
+ return (size == 0) ? nullptr : std::malloc(size);
+}
- SZipFree(nullptr, temp);
- return -1;
+static void SZipFree(void *p, void *address)
+{
+ std::free(address);
}
-_7z_error _7z_file_open(const char *filename, _7z_file **_7z)
+static SRes FileInStream_Read(void *pp, void *buf, size_t *size)
{
- file_error err;
- _7z_error _7zerr = _7ZERR_NONE;
-
+ return (reinterpret_cast<CFileInStream *>(pp)->read(buf, *size) == 0) ? SZ_OK : SZ_ERROR_READ;
+}
- _7z_file *new_7z;
- char *string;
- int cachenum;
+static SRes FileInStream_Seek(void *pp, Int64 *pos, ESzSeek origin)
+{
+ return reinterpret_cast<CFileInStream *>(pp)->seek(*pos, origin);
+}
- SRes res;
+} // extern "C"
- /* ensure we start with a NULL result */
- *_7z = nullptr;
- /* see if we are in the cache, and reopen if so */
- for (cachenum = 0; cachenum < ARRAY_LENGTH(_7z_cache); cachenum++)
- {
- _7z_file *cached = _7z_cache[cachenum];
+CFileInStream::CFileInStream()
+{
+ Read = &FileInStream_Read;
+ Seek = &FileInStream_Seek;
+}
- /* if we have a valid entry and it matches our filename, use it and remove from the cache */
- if (cached != nullptr && cached->filename != nullptr && strcmp(filename, cached->filename) == 0)
- {
- *_7z = cached;
- _7z_cache[cachenum] = nullptr;
- return _7ZERR_NONE;
- }
- }
- /* allocate memory for the _7z_file structure */
- new_7z = (_7z_file *)malloc(sizeof(*new_7z));
- if (new_7z == nullptr)
- return _7ZERR_OUT_OF_MEMORY;
- memset(new_7z, 0, sizeof(*new_7z));
- new_7z->inited = false;
- new_7z->archiveStream.file._7z_currfpos = 0;
- err = osd_open(filename, OPEN_FLAG_READ, &new_7z->archiveStream.file._7z_osdfile, &new_7z->archiveStream.file._7z_length);
- if (err != FILERR_NONE)
- {
- _7zerr = _7ZERR_FILE_ERROR;
- goto error;
- }
+/***************************************************************************
+ CACHE MANAGEMENT
+***************************************************************************/
- new_7z->allocImp.Alloc = SZipAlloc;
- new_7z->allocImp.Free = SZipFree;
+m7z_file_impl::m7z_file_impl(const std::string &filename)
+ : m_filename(filename)
+ , m_curr_file_idx(-1)
+ , m_curr_is_dir(false)
+ , m_curr_name()
+ , m_curr_length(0)
+ , m_curr_crc(0)
+ , m_utf16_buf(128)
+ , m_uchar_buf(128)
+ , m_utf8_buf(512)
+ , m_inited(false)
+ , m_block_index(0xffffffff) // it can have any value before first call (if outBuffer = 0)
+ , m_out_buffer(nullptr) // it must be 0 before first call for each new archive
+ , m_out_buffer_size(0) // it can have any value before first call (if outBuffer = 0)
+{
+ m_alloc_imp.Alloc = SZipAlloc;
+ m_alloc_imp.Free = SZipFree;
- new_7z->allocTempImp.Alloc = SZipAlloc;
- new_7z->allocTempImp.Free = SZipFree;
+ m_alloc_temp_imp.Alloc = SZipAlloc;
+ m_alloc_temp_imp.Free = SZipFree;
+}
- if (InFile_Open(&new_7z->archiveStream.file, filename))
- {
- _7zerr = _7ZERR_FILE_ERROR;
- goto error;
- }
- FileInStream_CreateVTable(&new_7z->archiveStream);
- LookToRead_CreateVTable(&new_7z->lookStream, False);
+archive_file::error m7z_file_impl::initialize()
+{
+ osd_file::error const err = osd_file::open(m_filename, OPEN_FLAG_READ, m_archive_stream.osdfile, m_archive_stream.length);
+ if (err != osd_file::error::NONE)
+ return archive_file::error::FILE_ERROR;
- new_7z->lookStream.realStream = &new_7z->archiveStream.s;
- LookToRead_Init(&new_7z->lookStream);
+ LookToRead_CreateVTable(&m_look_stream, False);
+ m_look_stream.realStream = &m_archive_stream;
+ LookToRead_Init(&m_look_stream);
CrcGenerateTable();
- SzArEx_Init(&new_7z->db);
- new_7z->inited = true;
+ SzArEx_Init(&m_db);
+ m_inited = true;
- res = SzArEx_Open(&new_7z->db, &new_7z->lookStream.s, &new_7z->allocImp, &new_7z->allocTempImp);
+ SRes const res = SzArEx_Open(&m_db, &m_look_stream.s, &m_alloc_imp, &m_alloc_temp_imp);
if (res != SZ_OK)
- {
- _7zerr = _7ZERR_FILE_ERROR;
- goto error;
- }
-
- new_7z->blockIndex = 0xFFFFFFFF; /* it can have any value before first call (if outBuffer = 0) */
- new_7z->outBuffer = nullptr; /* it must be 0 before first call for each new archive. */
- new_7z->outBufferSize = 0; /* it can have any value before first call (if outBuffer = 0) */
+ return archive_file::error::FILE_ERROR;
- /* make a copy of the filename for caching purposes */
- string = (char *)malloc(strlen(filename) + 1);
- if (string == nullptr)
- {
- _7zerr = _7ZERR_OUT_OF_MEMORY;
- goto error;
- }
- strcpy(string, filename);
- new_7z->filename = string;
- *_7z = new_7z;
- return _7ZERR_NONE;
-
-error:
- free__7z_file(new_7z);
- return _7zerr;
+ return archive_file::error::NONE;
}
@@ -376,119 +308,184 @@ error:
to the cache
-------------------------------------------------*/
-void _7z_file_close(_7z_file *_7z)
+void m7z_file_impl::close(ptr &&archive)
{
- int cachenum;
+ if (!archive) return;
- /* close the open files */
- if (_7z->archiveStream.file._7z_osdfile != nullptr)
- osd_close(_7z->archiveStream.file._7z_osdfile);
- _7z->archiveStream.file._7z_osdfile = nullptr;
+ // close the open files
+ archive->m_archive_stream.osdfile.reset();
- /* find the first NULL entry in the cache */
- for (cachenum = 0; cachenum < ARRAY_LENGTH(_7z_cache); cachenum++)
- if (_7z_cache[cachenum] == nullptr)
+ // find the first NULL entry in the cache
+ std::lock_guard<std::mutex> guard(s_cache_mutex);
+ std::size_t cachenum;
+ for (cachenum = 0; cachenum < s_cache.size(); cachenum++)
+ if (!s_cache[cachenum])
break;
- /* if no room left in the cache, free the bottommost entry */
- if (cachenum == ARRAY_LENGTH(_7z_cache))
- free__7z_file(_7z_cache[--cachenum]);
+ // if no room left in the cache, free the bottommost entry
+ if (cachenum == s_cache.size())
+ s_cache[--cachenum].reset();
- /* move everyone else down and place us at the top */
- if (cachenum != 0)
- memmove(&_7z_cache[1], &_7z_cache[0], cachenum * sizeof(_7z_cache[0]));
- _7z_cache[0] = _7z;
+ // move everyone else down and place us at the top
+ for ( ; cachenum > 0; cachenum--)
+ s_cache[cachenum] = std::move(s_cache[cachenum - 1]);
+ s_cache[0] = std::move(archive);
}
-/*-------------------------------------------------
- _7z_file_cache_clear - clear the _7Z file
- cache and free all memory
--------------------------------------------------*/
-
-void _7z_file_cache_clear(void)
-{
- int cachenum;
-
- /* clear call cache entries */
- for (cachenum = 0; cachenum < ARRAY_LENGTH(_7z_cache); cachenum++)
- if (_7z_cache[cachenum] != nullptr)
- {
- free__7z_file(_7z_cache[cachenum]);
- _7z_cache[cachenum] = nullptr;
- }
-}
+/***************************************************************************
+ 7Z FILE ACCESS
+***************************************************************************/
/*-------------------------------------------------
_7z_file_decompress - decompress a file
from a _7Z into the target buffer
-------------------------------------------------*/
-_7z_error _7z_file_decompress(_7z_file *new_7z, void *buffer, UINT32 length)
+archive_file::error m7z_file_impl::decompress(void *buffer, std::uint32_t length)
{
- file_error err;
- SRes res;
- int index = new_7z->curr_file_idx;
-
- /* make sure the file is open.. */
- if (new_7z->archiveStream.file._7z_osdfile==nullptr)
+ // make sure the file is open..
+ if (!m_archive_stream.osdfile)
{
- new_7z->archiveStream.file._7z_currfpos = 0;
- err = osd_open(new_7z->filename, OPEN_FLAG_READ, &new_7z->archiveStream.file._7z_osdfile, &new_7z->archiveStream.file._7z_length);
- if (err != FILERR_NONE)
- return _7ZERR_FILE_ERROR;
+ m_archive_stream.currfpos = 0;
+ osd_file::error const err = osd_file::open(m_filename, OPEN_FLAG_READ, m_archive_stream.osdfile, m_archive_stream.length);
+ if (err != osd_file::error::NONE)
+ return archive_file::error::FILE_ERROR;
}
size_t offset = 0;
- size_t outSizeProcessed = 0;
+ size_t out_size_processed = 0;
- res = SzArEx_Extract(&new_7z->db, &new_7z->lookStream.s, index,
- &new_7z->blockIndex, &new_7z->outBuffer, &new_7z->outBufferSize,
- &offset, &outSizeProcessed,
- &new_7z->allocImp, &new_7z->allocTempImp);
+ SRes const res = SzArEx_Extract(
+ &m_db, &m_look_stream.s, m_curr_file_idx,
+ &m_block_index,
+ &m_out_buffer, &m_out_buffer_size,
+ &offset, &out_size_processed,
+ &m_alloc_imp, &m_alloc_temp_imp);
if (res != SZ_OK)
- return _7ZERR_FILE_ERROR;
+ return archive_file::error::FILE_ERROR;
- memcpy(buffer, new_7z->outBuffer + offset, length);
+ std::memcpy(buffer, m_out_buffer + offset, length);
- return _7ZERR_NONE;
+ return archive_file::error::NONE;
}
+int m7z_file_impl::search(int i, std::uint32_t search_crc, const std::string &search_filename, bool matchcrc, bool matchname)
+{
+ for ( ; i < m_db.db.NumFiles; i++)
+ {
+ const CSzFileItem &f(m_db.db.Files[i]);
-/***************************************************************************
- CACHE MANAGEMENT
-***************************************************************************/
+ make_utf8_name(i);
+ const std::uint64_t size(f.Size);
+ const std::uint32_t crc(f.Crc);
+ const bool crcmatch(crc == search_crc);
+ const bool namematch(!core_stricmp(search_filename.c_str(), &m_utf8_buf[0]));
-/*-------------------------------------------------
- free__7z_file - free all the data for a
- _7z_file
--------------------------------------------------*/
+ const bool found = ((!matchcrc && !matchname) || !f.IsDir) && (!matchcrc || crcmatch) && (!matchname || namematch);
+ if (found)
+ {
+ m_curr_file_idx = i;
+ m_curr_is_dir = bool(f.IsDir);
+ m_curr_name = &m_utf8_buf[0];
+ m_curr_length = size;
+ m_curr_crc = crc;
+
+ return i;
+ }
+ }
+
+ return -1;
+}
-/**
- * @fn static void free__7z_file(_7z_file *_7z)
- *
- * @brief Free 7z file.
- *
- * @param [in,out] _7z If non-null, the 7z.
- */
-static void free__7z_file(_7z_file *_7z)
+void m7z_file_impl::make_utf8_name(int index)
{
- if (_7z != nullptr)
+ std::size_t len, out_pos;
+
+ len = SzArEx_GetFileNameUtf16(&m_db, index, nullptr);
+ m_utf16_buf.resize((std::max<std::size_t>)(m_utf16_buf.size(), len));
+ SzArEx_GetFileNameUtf16(&m_db, index, &m_utf16_buf[0]);
+
+ m_uchar_buf.resize((std::max<std::size_t>)(m_uchar_buf.size(), len));
+ out_pos = 0;
+ for (std::size_t in_pos = 0; in_pos < (len - 1); )
{
- if (_7z->archiveStream.file._7z_osdfile != nullptr)
- osd_close(_7z->archiveStream.file._7z_osdfile);
- if (_7z->filename != nullptr)
- free((void *)_7z->filename);
+ const int used = uchar_from_utf16(&m_uchar_buf[out_pos], &m_utf16_buf[in_pos], len - in_pos);
+ if (used < 0)
+ {
+ in_pos++;
+ m_uchar_buf[out_pos++] = 0x00fffd; // Unicode REPLACEMENT CHARACTER
+ }
+ else
+ {
+ assert(used > 0);
+ in_pos += used;
+ out_pos++;
+ }
+ }
+ len = out_pos;
+
+ m_utf8_buf.resize((std::max<std::size_t>)(m_utf8_buf.size(), 4 * len + 1));
+ out_pos = 0;
+ for (std::size_t in_pos = 0; in_pos < len; in_pos++)
+ {
+ int produced = utf8_from_uchar(&m_utf8_buf[out_pos], m_utf8_buf.size() - out_pos, m_uchar_buf[in_pos]);
+ if (produced < 0)
+ produced = utf8_from_uchar(&m_utf8_buf[out_pos], m_utf8_buf.size() - out_pos, 0x00fffd);
+ if (produced >= 0)
+ out_pos += produced;
+ assert(out_pos < m_utf8_buf.size());
+ }
+ m_utf8_buf[out_pos++] = '\0';
+ m_utf8_buf.resize(out_pos);
+}
+
+} // anonymous namespace
- if (_7z->outBuffer) IAlloc_Free(&_7z->allocImp, _7z->outBuffer);
- if (_7z->inited) SzArEx_Free(&_7z->db, &_7z->allocImp);
+archive_file::error archive_file::open_7z(const std::string &filename, ptr &result)
+{
+ // ensure we start with a NULL result
+ result.reset();
+
+ // see if we are in the cache, and reopen if so
+ m7z_file_impl::ptr newimpl(m7z_file_impl::find_cached(filename));
+ if (!newimpl)
+ {
+ // allocate memory for the 7z file structure
+ try { newimpl = std::make_unique<m7z_file_impl>(filename); }
+ catch (...) { return error::OUT_OF_MEMORY; }
+ error const err = newimpl->initialize();
+ if (err != error::NONE) return err;
+ }
- free(_7z);
+ try
+ {
+ result = std::make_unique<m7z_file_wrapper>(std::move(newimpl));
+ return error::NONE;
+ }
+ catch (...)
+ {
+ m7z_file_impl::close(std::move(newimpl));
+ return error::OUT_OF_MEMORY;
}
}
+
+
+/*-------------------------------------------------
+ _7z_file_cache_clear - clear the _7Z file
+ cache and free all memory
+-------------------------------------------------*/
+
+void m7z_file_cache_clear()
+{
+ // This is a trampoline called from unzip.cpp to avoid the need to have the zip and 7zip code in one file
+ m7z_file_impl::cache_clear();
+}
+
+} // namespace util
diff --git a/src/lib/util/un7z.h b/src/lib/util/un7z.h
deleted file mode 100644
index d2c0c9f098a..00000000000
--- a/src/lib/util/un7z.h
+++ /dev/null
@@ -1,143 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Aaron Giles
-/***************************************************************************
-
- un7z.h
-
- 7z file management.
-
-***************************************************************************/
-
-// this is based on unzip.h, with modifications needed to use the 7zip library
-
-#pragma once
-
-#ifndef __UN_7Z_H__
-#define __UN_7Z_H__
-
-#include "osdcore.h"
-
-#include "lzma/C/7z.h"
-#include "lzma/C/7zCrc.h"
-#include "lzma/C/7zVersion.h"
-
-
-void *SZipAlloc(void *p, size_t size);
-void SZipFree(void *p, void *address);
-void *SZipAllocTemp(void *p, size_t size);
-void SZipFreeTemp(void *p, void *address);
-
-struct CSzFile
-{
- long _7z_currfpos;
- UINT64 _7z_length;
- osd_file * _7z_osdfile; /* OSD file handle */
-
-};
-
-
-struct CFileSeqInStream
-{
- ISeqInStream s;
- CSzFile file;
-};
-
-void FileSeqInStream_CreateVTable(CFileSeqInStream *p);
-
-
-struct CFileInStream
-{
- ISeekInStream s;
- CSzFile file;
-};
-
-void FileInStream_CreateVTable(CFileInStream *p);
-
-
-struct CFileOutStream
-{
- ISeqOutStream s;
- CSzFile file;
-} ;
-
-void FileOutStream_CreateVTable(CFileOutStream *p);
-
-
-
-/***************************************************************************
- CONSTANTS
-***************************************************************************/
-
-
-/* Error types */
-enum _7z_error
-{
- _7ZERR_NONE = 0,
- _7ZERR_OUT_OF_MEMORY,
- _7ZERR_FILE_ERROR,
- _7ZERR_BAD_SIGNATURE,
- _7ZERR_DECOMPRESS_ERROR,
- _7ZERR_FILE_TRUNCATED,
- _7ZERR_FILE_CORRUPT,
- _7ZERR_UNSUPPORTED,
- _7ZERR_BUFFER_TOO_SMALL
-};
-
-
-
-/***************************************************************************
- TYPE DEFINITIONS
-***************************************************************************/
-
-/* describes an open _7Z file */
-struct _7z_file
-{
- const char * filename; /* copy of _7Z filename (for caching) */
-
- int curr_file_idx; /* current file index */
- UINT64 uncompressed_length; /* current file uncompressed length */
- UINT64 crc; /* current file crc */
-
- CFileInStream archiveStream;
- CLookToRead lookStream;
- CSzArEx db;
- SRes res;
- ISzAlloc allocImp;
- ISzAlloc allocTempImp;
- bool inited;
-
- // cached stuff for solid blocks
- UInt32 blockIndex;// = 0xFFFFFFFF; /* it can have any value before first call (if outBuffer = 0) */
- Byte *outBuffer;// = 0; /* it must be 0 before first call for each new archive. */
- size_t outBufferSize;// = 0; /* it can have any value before first call (if outBuffer = 0) */
-};
-
-
-
-/***************************************************************************
- FUNCTION PROTOTYPES
-***************************************************************************/
-
-
-/* ----- _7Z file access ----- */
-
-/* open a _7Z file and parse its central directory */
-_7z_error _7z_file_open(const char *filename, _7z_file **_7z);
-
-/* close a _7Z file (may actually be left open due to caching) */
-void _7z_file_close(_7z_file *_7z);
-
-/* clear out all open _7Z files from the cache */
-void _7z_file_cache_clear(void);
-
-
-/* ----- contained file access ----- */
-
-/* find a file index by crc, filename or both */
-int _7z_search_crc_match(_7z_file *new_7z, UINT32 crc, const char *search_filename, int search_filename_length, bool matchcrc, bool matchname);
-
-/* decompress the most recently found file in the _7Z */
-_7z_error _7z_file_decompress(_7z_file *_7z, void *buffer, UINT32 length);
-
-
-#endif /* __UN_7Z_H__ */
diff --git a/src/lib/util/unzip.cpp b/src/lib/util/unzip.cpp
index 876d8ae90c5..2751f83ffb6 100644
--- a/src/lib/util/unzip.cpp
+++ b/src/lib/util/unzip.cpp
@@ -1,5 +1,5 @@
// license:BSD-3-Clause
-// copyright-holders:Aaron Giles
+// copyright-holders:Aaron Giles, Vas Crabb
/***************************************************************************
unzip.c
@@ -8,22 +8,30 @@
***************************************************************************/
-#include "osdcore.h"
#include "unzip.h"
-#include <ctype.h>
-#include <stdlib.h>
-#include <zlib.h>
+#include "corestr.h"
+#include "osdcore.h"
+
+#include <algorithm>
+#include <array>
+#include <cassert>
+#include <cstring>
+#include <cstdlib>
+#include <mutex>
+#include <utility>
+#include <vector>
+
+#include <zlib.h>
+namespace util {
+namespace {
/***************************************************************************
CONSTANTS
***************************************************************************/
-/* number of open files to cache */
-#define ZIP_CACHE_SIZE 8
-
/* offsets in end of central directory structure */
#define ZIPESIG 0x00
#define ZIPEDSK 0x04
@@ -67,30 +75,226 @@
#define ZIPCRC 0x0e
#define ZIPSIZE 0x12
#define ZIPUNCMP 0x16
+#define ZIPFNLN 0x1a
+#define ZIPXTRALN 0x1c
+#define ZIPNAME 0x1e
-/**
- * @def ZIPFNLN
- *
- * @brief A macro that defines zipfnln.
- */
-#define ZIPFNLN 0x1a
-/**
- * @def ZIPXTRALN
- *
- * @brief A macro that defines zipxtraln.
- */
+/***************************************************************************
+ TYPE DEFINITIONS
+***************************************************************************/
-#define ZIPXTRALN 0x1c
+class zip_file_impl
+{
+public:
+ typedef std::unique_ptr<zip_file_impl> ptr;
+
+ zip_file_impl(const std::string &filename)
+ : m_filename(filename)
+ , m_file()
+ , m_length(0)
+ , m_ecd()
+ , m_cd()
+ , m_cd_pos(0)
+ , m_header()
+ , m_curr_is_dir(false)
+ , m_curr_name()
+ , m_buffer()
+ {
+ std::memset(&m_header, 0, sizeof(m_header));
+ std::fill(m_buffer.begin(), m_buffer.end(), 0);
+ }
-/**
- * @def ZIPNAME
- *
- * @brief A macro that defines zipname.
- */
+ static ptr find_cached(const std::string &filename)
+ {
+ std::lock_guard<std::mutex> guard(s_cache_mutex);
+ for (std::size_t cachenum = 0; cachenum < s_cache.size(); cachenum++)
+ {
+ // if we have a valid entry and it matches our filename, use it and remove from the cache
+ if (s_cache[cachenum] && (filename == s_cache[cachenum]->m_filename))
+ {
+ ptr result;
+ std::swap(s_cache[cachenum], result);
+ return result;
+ }
+ }
+ return ptr();
+ }
+ static void close(ptr &&zip);
+ static void cache_clear()
+ {
+ // clear call cache entries
+ std::lock_guard<std::mutex> guard(s_cache_mutex);
+ for (std::size_t cachenum = 0; cachenum < s_cache.size(); s_cache[cachenum++].reset()) { }
+ }
-#define ZIPNAME 0x1e
+ archive_file::error initialize()
+ {
+ // read ecd data
+ auto const ziperr = read_ecd();
+ if (ziperr != archive_file::error::NONE)
+ return ziperr;
+
+ // verify that we can work with this zipfile (no disk spanning allowed)
+ if ((m_ecd.disk_number != m_ecd.cd_start_disk_number) || (m_ecd.cd_disk_entries != m_ecd.cd_total_entries))
+ return archive_file::error::UNSUPPORTED;
+
+ // allocate memory for the central directory
+ try { m_cd.resize(m_ecd.cd_size + 1); }
+ catch (...) { return archive_file::error::OUT_OF_MEMORY; }
+
+ // read the central directory
+ std::uint32_t read_length;
+ auto const filerr = m_file->read(&m_cd[0], m_ecd.cd_start_disk_offset, m_ecd.cd_size, read_length);
+ if ((filerr != osd_file::error::NONE) || (read_length != m_ecd.cd_size))
+ return (filerr == osd_file::error::NONE) ? archive_file::error::FILE_TRUNCATED : archive_file::error::FILE_ERROR;
+
+ return archive_file::error::NONE;
+ }
+
+ int first_file()
+ {
+ m_cd_pos = 0;
+ return search(0, std::string(), false, false);
+ }
+ int next_file()
+ {
+ return search(0, std::string(), false, false);
+ }
+ int search(std::uint32_t crc)
+ {
+ m_cd_pos = 0;
+ return search(crc, std::string(), true, false);
+ }
+ int search(const std::string &filename)
+ {
+ m_cd_pos = 0;
+ return search(0, filename, false, true);
+ }
+ int search(std::uint32_t crc, const std::string &filename)
+ {
+ m_cd_pos = 0;
+ return search(crc, filename, true, true);
+ }
+
+ bool current_is_directory() const { return m_curr_is_dir; }
+ const std::string &current_name() const { return m_curr_name; }
+ std::uint64_t current_uncompressed_length() const { return m_header.uncompressed_length; }
+ std::uint32_t current_crc() const { return m_header.crc; }
+
+ archive_file::error decompress(void *buffer, std::uint32_t length);
+
+private:
+ zip_file_impl(const zip_file_impl &) = delete;
+ zip_file_impl(zip_file_impl &&) = delete;
+ zip_file_impl &operator=(const zip_file_impl &) = delete;
+ zip_file_impl &operator=(zip_file_impl &&) = delete;
+
+ int search(std::uint32_t search_crc, const std::string &search_filename, bool matchcrc, bool matchname);
+
+ archive_file::error reopen()
+ {
+ if (!m_file)
+ {
+ auto const filerr = osd_file::open(m_filename, OPEN_FLAG_READ, m_file, m_length);
+ if (filerr != osd_file::error::NONE)
+ return archive_file::error::FILE_ERROR;
+ }
+ return archive_file::error::NONE;
+ }
+
+ // ZIP file parsing
+ archive_file::error read_ecd();
+ archive_file::error get_compressed_data_offset(std::uint64_t &offset);
+
+ // decompression interfaces
+ archive_file::error decompress_data_type_0(std::uint64_t offset, void *buffer, std::uint32_t length);
+ archive_file::error decompress_data_type_8(std::uint64_t offset, void *buffer, std::uint32_t length);
+
+ struct file_header
+ {
+ std::uint32_t signature; // central file header signature
+ std::uint16_t version_created; // version made by
+ std::uint16_t version_needed; // version needed to extract
+ std::uint16_t bit_flag; // general purpose bit flag
+ std::uint16_t compression; // compression method
+ std::uint16_t file_time; // last mod file time
+ std::uint16_t file_date; // last mod file date
+ std::uint32_t crc; // crc-32
+ std::uint32_t compressed_length; // compressed size
+ std::uint32_t uncompressed_length; // uncompressed size
+ std::uint16_t filename_length; // filename length
+ std::uint16_t extra_field_length; // extra field length
+ std::uint16_t file_comment_length; // file comment length
+ std::uint16_t start_disk_number; // disk number start
+ std::uint16_t internal_attributes; // internal file attributes
+ std::uint32_t external_attributes; // external file attributes
+ std::uint32_t local_header_offset; // relative offset of local header
+ const char * filename; // filename
+ };
+
+ // contains extracted end of central directory information
+ struct ecd
+ {
+ std::uint32_t signature; // end of central dir signature
+ std::uint16_t disk_number; // number of this disk
+ std::uint16_t cd_start_disk_number; // number of the disk with the start of the central directory
+ std::uint16_t cd_disk_entries; // total number of entries in the central directory on this disk
+ std::uint16_t cd_total_entries; // total number of entries in the central directory
+ std::uint32_t cd_size; // size of the central directory
+ std::uint32_t cd_start_disk_offset; // offset of start of central directory with respect to the starting disk number
+ std::uint16_t comment_length; // .ZIP file comment length
+ const char * comment; // .ZIP file comment
+
+ std::unique_ptr<std::uint8_t []> raw; // pointer to the raw data
+ std::uint32_t rawlength; // length of the raw data
+ };
+
+ static constexpr std::size_t DECOMPRESS_BUFSIZE = 16384;
+ static constexpr std::size_t CACHE_SIZE = 8; // number of open files to cache
+ static std::array<ptr, CACHE_SIZE> s_cache;
+ static std::mutex s_cache_mutex;
+
+ const std::string m_filename; // copy of ZIP filename (for caching)
+ osd_file::ptr m_file; // OSD file handle
+ std::uint64_t m_length; // length of zip file
+
+ ecd m_ecd; // end of central directory
+
+ std::vector<std::uint8_t> m_cd; // central directory raw data
+ std::uint32_t m_cd_pos; // position in central directory
+ file_header m_header; // current file header
+ bool m_curr_is_dir; // current file is directory
+ std::string m_curr_name; // current file name
+
+ std::array<std::uint8_t, DECOMPRESS_BUFSIZE> m_buffer; // buffer for decompression
+};
+
+
+class zip_file_wrapper : public archive_file
+{
+public:
+ zip_file_wrapper(zip_file_impl::ptr &&impl) : m_impl(std::move(impl)) { assert(m_impl); }
+ virtual ~zip_file_wrapper() { zip_file_impl::close(std::move(m_impl)); }
+
+ virtual int first_file() override { return m_impl->first_file(); }
+ virtual int next_file() override { return m_impl->next_file(); }
+
+ virtual int search(std::uint32_t crc) override { return m_impl->search(crc); }
+ virtual int search(const std::string &filename) override { return m_impl->search(filename); }
+ virtual int search(std::uint32_t crc, const std::string &filename) override { return m_impl->search(crc, filename); }
+
+ virtual bool current_is_directory() const override { return m_impl->current_is_directory(); }
+ virtual const std::string &current_name() const override { return m_impl->current_name(); }
+ virtual std::uint64_t current_uncompressed_length() const override { return m_impl->current_uncompressed_length(); }
+ virtual std::uint32_t current_crc() const override { return m_impl->current_crc(); }
+
+ virtual error decompress(void *buffer, std::uint32_t length) override { return m_impl->decompress(buffer, length); }
+
+private:
+ zip_file_impl::ptr m_impl;
+};
@@ -108,7 +312,7 @@
* @return The word.
*/
-static inline UINT16 read_word(UINT8 *buf)
+inline std::uint16_t read_word(std::uint8_t const *buf)
{
return (buf[1] << 8) | buf[0];
}
@@ -123,7 +327,7 @@ static inline UINT16 read_word(UINT8 *buf)
* @return The double word.
*/
-static inline UINT32 read_dword(UINT8 *buf)
+inline std::uint32_t read_dword(std::uint8_t const *buf)
{
return (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
}
@@ -135,130 +339,9 @@ static inline UINT32 read_dword(UINT8 *buf)
***************************************************************************/
/** @brief The zip cache[ zip cache size]. */
-static zip_file *zip_cache[ZIP_CACHE_SIZE];
-
-
-
-/***************************************************************************
- FUNCTION PROTOTYPES
-***************************************************************************/
-
-/* cache management */
-static void free_zip_file(zip_file *zip);
-
-/* ZIP file parsing */
-static zip_error read_ecd(zip_file *zip);
-static zip_error get_compressed_data_offset(zip_file *zip, UINT64 *offset);
-
-/* decompression interfaces */
-static zip_error decompress_data_type_0(zip_file *zip, UINT64 offset, void *buffer, UINT32 length);
-static zip_error decompress_data_type_8(zip_file *zip, UINT64 offset, void *buffer, UINT32 length);
-
-
-
-/***************************************************************************
- ZIP FILE ACCESS
-***************************************************************************/
-
-/*-------------------------------------------------
- zip_file_open - opens a ZIP file for reading
--------------------------------------------------*/
-
-/**
- * @fn zip_error zip_file_open(const char *filename, zip_file **zip)
- *
- * @brief Queries if a given zip file open.
- *
- * @param filename Filename of the file.
- * @param [in,out] zip If non-null, the zip.
- *
- * @return A zip_error.
- */
-
-zip_error zip_file_open(const char *filename, zip_file **zip)
-{
- zip_error ziperr = ZIPERR_NONE;
- file_error filerr;
- UINT32 read_length;
- zip_file *newzip;
- char *string;
- int cachenum;
-
- /* ensure we start with a NULL result */
- *zip = nullptr;
-
- /* see if we are in the cache, and reopen if so */
- for (cachenum = 0; cachenum < ARRAY_LENGTH(zip_cache); cachenum++)
- {
- zip_file *cached = zip_cache[cachenum];
-
- /* if we have a valid entry and it matches our filename, use it and remove from the cache */
- if (cached != nullptr && cached->filename != nullptr && strcmp(filename, cached->filename) == 0)
- {
- *zip = cached;
- zip_cache[cachenum] = nullptr;
- return ZIPERR_NONE;
- }
- }
+std::array<zip_file_impl::ptr, zip_file_impl::CACHE_SIZE> zip_file_impl::s_cache;
+std::mutex zip_file_impl::s_cache_mutex;
- /* allocate memory for the zip_file structure */
- newzip = (zip_file *)malloc(sizeof(*newzip));
- if (newzip == nullptr)
- return ZIPERR_OUT_OF_MEMORY;
- memset(newzip, 0, sizeof(*newzip));
-
- /* open the file */
- filerr = osd_open(filename, OPEN_FLAG_READ, &newzip->file, &newzip->length);
- if (filerr != FILERR_NONE)
- {
- ziperr = ZIPERR_FILE_ERROR;
- goto error;
- }
-
- /* read ecd data */
- ziperr = read_ecd(newzip);
- if (ziperr != ZIPERR_NONE)
- goto error;
-
- /* verify that we can work with this zipfile (no disk spanning allowed) */
- if (newzip->ecd.disk_number != newzip->ecd.cd_start_disk_number || newzip->ecd.cd_disk_entries != newzip->ecd.cd_total_entries)
- {
- ziperr = ZIPERR_UNSUPPORTED;
- goto error;
- }
-
- /* allocate memory for the central directory */
- newzip->cd = (UINT8 *)malloc(newzip->ecd.cd_size + 1);
- if (newzip->cd == nullptr)
- {
- ziperr = ZIPERR_OUT_OF_MEMORY;
- goto error;
- }
-
- /* read the central directory */
- filerr = osd_read(newzip->file, newzip->cd, newzip->ecd.cd_start_disk_offset, newzip->ecd.cd_size, &read_length);
- if (filerr != FILERR_NONE || read_length != newzip->ecd.cd_size)
- {
- ziperr = (filerr == FILERR_NONE) ? ZIPERR_FILE_TRUNCATED : ZIPERR_FILE_ERROR;
- goto error;
- }
-
- /* make a copy of the filename for caching purposes */
- string = (char *)malloc(strlen(filename) + 1);
- if (string == nullptr)
- {
- ziperr = ZIPERR_OUT_OF_MEMORY;
- goto error;
- }
- strcpy(string, filename);
- newzip->filename = string;
- *zip = newzip;
- return ZIPERR_NONE;
-
-error:
- free_zip_file(newzip);
- return ziperr;
-}
/*-------------------------------------------------
@@ -274,57 +357,31 @@ error:
* @param [in,out] zip If non-null, the zip.
*/
-void zip_file_close(zip_file *zip)
+void zip_file_impl::close(ptr &&zip)
{
- int cachenum;
+ if (!zip) return;
- /* close the open files */
- if (zip->file != nullptr)
- osd_close(zip->file);
- zip->file = nullptr;
+ // close the open files
+ zip->m_file.reset();
- /* find the first NULL entry in the cache */
- for (cachenum = 0; cachenum < ARRAY_LENGTH(zip_cache); cachenum++)
- if (zip_cache[cachenum] == nullptr)
+ // find the first NULL entry in the cache
+ std::lock_guard<std::mutex> guard(s_cache_mutex);
+ std::size_t cachenum;
+ for (cachenum = 0; cachenum < s_cache.size(); cachenum++)
+ if (!s_cache[cachenum])
break;
- /* if no room left in the cache, free the bottommost entry */
- if (cachenum == ARRAY_LENGTH(zip_cache))
- free_zip_file(zip_cache[--cachenum]);
-
- /* move everyone else down and place us at the top */
- if (cachenum != 0)
- memmove(&zip_cache[1], &zip_cache[0], cachenum * sizeof(zip_cache[0]));
- zip_cache[0] = zip;
-}
-
-
-/*-------------------------------------------------
- zip_file_cache_clear - clear the ZIP file
- cache and free all memory
--------------------------------------------------*/
-
-/**
- * @fn void zip_file_cache_clear(void)
- *
- * @brief Zip file cache clear.
- */
+ // if no room left in the cache, free the bottommost entry
+ if (cachenum == s_cache.size())
+ s_cache[--cachenum].reset();
-void zip_file_cache_clear(void)
-{
- int cachenum;
-
- /* clear call cache entries */
- for (cachenum = 0; cachenum < ARRAY_LENGTH(zip_cache); cachenum++)
- if (zip_cache[cachenum] != nullptr)
- {
- free_zip_file(zip_cache[cachenum]);
- zip_cache[cachenum] = nullptr;
- }
+ // move everyone else down and place us at the top
+ for ( ; cachenum > 0; cachenum--)
+ s_cache[cachenum] = std::move(s_cache[cachenum - 1]);
+ s_cache[0] = std::move(zip);
}
-
/***************************************************************************
CONTAINED FILE ACCESS
***************************************************************************/
@@ -334,88 +391,63 @@ void zip_file_cache_clear(void)
in the ZIP
-------------------------------------------------*/
-/**
- * @fn const zip_file_header *zip_file_first_file(zip_file *zip)
- *
- * @brief Zip file first file.
- *
- * @param [in,out] zip If non-null, the zip.
- *
- * @return null if it fails, else a zip_file_header*.
- */
-
-const zip_file_header *zip_file_first_file(zip_file *zip)
-{
- /* reset the position and go from there */
- zip->cd_pos = 0;
- return zip_file_next_file(zip);
-}
-
-
/*-------------------------------------------------
zip_file_next_entry - return the next entry
in the ZIP
-------------------------------------------------*/
-/**
- * @fn const zip_file_header *zip_file_next_file(zip_file *zip)
- *
- * @brief Zip file next file.
- *
- * @param [in,out] zip If non-null, the zip.
- *
- * @return null if it fails, else a zip_file_header*.
- */
-
-const zip_file_header *zip_file_next_file(zip_file *zip)
+int zip_file_impl::search(std::uint32_t search_crc, const std::string &search_filename, bool matchcrc, bool matchname)
{
- /* fix up any modified data */
- if (zip->header.raw != nullptr)
+ // if we're at or past the end, we're done
+ std::string filename;
+ while ((m_cd_pos + ZIPCFN) <= m_ecd.cd_size)
{
- zip->header.raw[ZIPCFN + zip->header.filename_length] = zip->header.saved;
- zip->header.raw = nullptr;
- }
+ // extract file header info
+ std::uint8_t const *const raw = &m_cd[0] + m_cd_pos;
+ m_header.signature = read_dword(raw + ZIPCENSIG);
+ m_header.version_created = read_word (raw + ZIPCVER);
+ m_header.version_needed = read_word (raw + ZIPCVXT);
+ m_header.bit_flag = read_word (raw + ZIPCFLG);
+ m_header.compression = read_word (raw + ZIPCMTHD);
+ m_header.file_time = read_word (raw + ZIPCTIM);
+ m_header.file_date = read_word (raw + ZIPCDAT);
+ m_header.crc = read_dword(raw + ZIPCCRC);
+ m_header.compressed_length = read_dword(raw + ZIPCSIZ);
+ m_header.uncompressed_length = read_dword(raw + ZIPCUNC);
+ m_header.filename_length = read_word (raw + ZIPCFNL);
+ m_header.extra_field_length = read_word (raw + ZIPCXTL);
+ m_header.file_comment_length = read_word (raw + ZIPCCML);
+ m_header.start_disk_number = read_word (raw + ZIPDSK);
+ m_header.internal_attributes = read_word (raw + ZIPINT);
+ m_header.external_attributes = read_dword(raw + ZIPEXT);
+ m_header.local_header_offset = read_dword(raw + ZIPOFST);
+ m_header.filename = reinterpret_cast<const char *>(raw + ZIPCFN);
+
+ // make sure we have enough data
+ std::uint32_t const rawlength = ZIPCFN + m_header.filename_length + m_header.extra_field_length + m_header.file_comment_length;
+ if ((m_cd_pos + rawlength) > m_ecd.cd_size)
+ break;
+
+ // advance the position
+ m_cd_pos += rawlength;
+
+ // copy the filename filename
+ bool const is_dir((m_header.filename_length > 0) && (m_header.filename[m_header.filename_length - 1] == '/'));
+ filename.assign(m_header.filename, m_header.filename_length - (is_dir ? 1 : 0));
+
+ // check to see if it matches query
+ bool const crcmatch(search_crc == m_header.crc);
+ const bool namematch(!core_stricmp(search_filename.c_str(), filename.c_str()));
- /* if we're at or past the end, we're done */
- if (zip->cd_pos >= zip->ecd.cd_size)
- return nullptr;
-
- /* extract file header info */
- zip->header.raw = zip->cd + zip->cd_pos;
- zip->header.rawlength = ZIPCFN;
- zip->header.signature = read_dword(zip->header.raw + ZIPCENSIG);
- zip->header.version_created = read_word (zip->header.raw + ZIPCVER);
- zip->header.version_needed = read_word (zip->header.raw + ZIPCVXT);
- zip->header.bit_flag = read_word (zip->header.raw + ZIPCFLG);
- zip->header.compression = read_word (zip->header.raw + ZIPCMTHD);
- zip->header.file_time = read_word (zip->header.raw + ZIPCTIM);
- zip->header.file_date = read_word (zip->header.raw + ZIPCDAT);
- zip->header.crc = read_dword(zip->header.raw + ZIPCCRC);
- zip->header.compressed_length = read_dword(zip->header.raw + ZIPCSIZ);
- zip->header.uncompressed_length = read_dword(zip->header.raw + ZIPCUNC);
- zip->header.filename_length = read_word (zip->header.raw + ZIPCFNL);
- zip->header.extra_field_length = read_word (zip->header.raw + ZIPCXTL);
- zip->header.file_comment_length = read_word (zip->header.raw + ZIPCCML);
- zip->header.start_disk_number = read_word (zip->header.raw + ZIPDSK);
- zip->header.internal_attributes = read_word (zip->header.raw + ZIPINT);
- zip->header.external_attributes = read_dword(zip->header.raw + ZIPEXT);
- zip->header.local_header_offset = read_dword(zip->header.raw + ZIPOFST);
- zip->header.filename = (char *)zip->header.raw + ZIPCFN;
-
- /* make sure we have enough data */
- zip->header.rawlength += zip->header.filename_length;
- zip->header.rawlength += zip->header.extra_field_length;
- zip->header.rawlength += zip->header.file_comment_length;
- if (zip->cd_pos + zip->header.rawlength > zip->ecd.cd_size)
- return nullptr;
-
- /* NULL terminate the filename */
- zip->header.saved = zip->header.raw[ZIPCFN + zip->header.filename_length];
- zip->header.raw[ZIPCFN + zip->header.filename_length] = 0;
-
- /* advance the position */
- zip->cd_pos += zip->header.rawlength;
- return &zip->header;
+ bool const found = ((!matchcrc && !matchname) || !is_dir) && (!matchcrc || crcmatch) && (!matchname || namematch);
+ if (found)
+ {
+ m_curr_is_dir = is_dir;
+ m_curr_name = std::move(filename);
+ return 0;
+ }
+ }
+ return -1;
}
@@ -436,38 +468,38 @@ const zip_file_header *zip_file_next_file(zip_file *zip)
* @return A zip_error.
*/
-zip_error zip_file_decompress(zip_file *zip, void *buffer, UINT32 length)
+archive_file::error zip_file_impl::decompress(void *buffer, std::uint32_t length)
{
- zip_error ziperr;
- UINT64 offset;
+ archive_file::error ziperr;
+ std::uint64_t offset;
- /* if we don't have enough buffer, error */
- if (length < zip->header.uncompressed_length)
- return ZIPERR_BUFFER_TOO_SMALL;
+ // if we don't have enough buffer, error
+ if (length < m_header.uncompressed_length)
+ return archive_file::error::BUFFER_TOO_SMALL;
- /* make sure the info in the header aligns with what we know */
- if (zip->header.start_disk_number != zip->ecd.disk_number)
- return ZIPERR_UNSUPPORTED;
+ // make sure the info in the header aligns with what we know
+ if (m_header.start_disk_number != m_ecd.disk_number)
+ return archive_file::error::UNSUPPORTED;
- /* get the compressed data offset */
- ziperr = get_compressed_data_offset(zip, &offset);
- if (ziperr != ZIPERR_NONE)
+ // get the compressed data offset
+ ziperr = get_compressed_data_offset(offset);
+ if (ziperr != archive_file::error::NONE)
return ziperr;
- /* handle compression types */
- switch (zip->header.compression)
+ // handle compression types
+ switch (m_header.compression)
{
- case 0:
- ziperr = decompress_data_type_0(zip, offset, buffer, length);
- break;
+ case 0:
+ ziperr = decompress_data_type_0(offset, buffer, length);
+ break;
- case 8:
- ziperr = decompress_data_type_8(zip, offset, buffer, length);
- break;
+ case 8:
+ ziperr = decompress_data_type_8(offset, buffer, length);
+ break;
- default:
- ziperr = ZIPERR_UNSUPPORTED;
- break;
+ default:
+ ziperr = archive_file::error::UNSUPPORTED;
+ break;
}
return ziperr;
}
@@ -475,41 +507,6 @@ zip_error zip_file_decompress(zip_file *zip, void *buffer, UINT32 length)
/***************************************************************************
- CACHE MANAGEMENT
-***************************************************************************/
-
-/*-------------------------------------------------
- free_zip_file - free all the data for a
- zip_file
--------------------------------------------------*/
-
-/**
- * @fn static void free_zip_file(zip_file *zip)
- *
- * @brief Free zip file.
- *
- * @param [in,out] zip If non-null, the zip.
- */
-
-static void free_zip_file(zip_file *zip)
-{
- if (zip != nullptr)
- {
- if (zip->file != nullptr)
- osd_close(zip->file);
- if (zip->filename != nullptr)
- free((void *)zip->filename);
- if (zip->ecd.raw != nullptr)
- free(zip->ecd.raw);
- if (zip->cd != nullptr)
- free(zip->cd);
- free(zip);
- }
-}
-
-
-
-/***************************************************************************
ZIP FILE PARSING
***************************************************************************/
@@ -527,72 +524,69 @@ static void free_zip_file(zip_file *zip)
* @return The ecd.
*/
-static zip_error read_ecd(zip_file *zip)
+archive_file::error zip_file_impl::read_ecd()
{
- UINT32 buflen = 1024;
- UINT8 *buffer;
+ // make sure the file handle is open
+ auto const ziperr = reopen();
+ if (ziperr != archive_file::error::NONE)
+ return ziperr;
- /* we may need multiple tries */
+ // we may need multiple tries
+ std::uint32_t buflen = 1024;
while (buflen < 65536)
{
- file_error error;
- UINT32 read_length;
- INT32 offset;
-
- /* max out the buffer length at the size of the file */
- if (buflen > zip->length)
- buflen = zip->length;
-
- /* allocate buffer */
- buffer = (UINT8 *)malloc(buflen + 1);
- if (buffer == nullptr)
- return ZIPERR_OUT_OF_MEMORY;
-
- /* read in one buffers' worth of data */
- error = osd_read(zip->file, buffer, zip->length - buflen, buflen, &read_length);
- if (error != FILERR_NONE || read_length != buflen)
- {
- free(buffer);
- return ZIPERR_FILE_ERROR;
- }
-
- /* find the ECD signature */
+ // max out the buffer length at the size of the file
+ if (buflen > m_length)
+ buflen = m_length;
+
+ // allocate buffer
+ std::unique_ptr<std::uint8_t []> buffer;
+ try { buffer.reset(new std::uint8_t[buflen + 1]); }
+ catch (...) { return archive_file::error::OUT_OF_MEMORY; }
+
+ // read in one buffers' worth of data
+ std::uint32_t read_length;
+ auto const error = m_file->read(&buffer[0], m_length - buflen, buflen, read_length);
+ if (error != osd_file::error::NONE || read_length != buflen)
+ return archive_file::error::FILE_ERROR;
+
+ // find the ECD signature
+ std::int32_t offset;
for (offset = buflen - 22; offset >= 0; offset--)
if (buffer[offset + 0] == 'P' && buffer[offset + 1] == 'K' && buffer[offset + 2] == 0x05 && buffer[offset + 3] == 0x06)
break;
- /* if we found it, fill out the data */
+ // if we found it, fill out the data
if (offset >= 0)
{
- /* reuse the buffer as our ECD buffer */
- zip->ecd.raw = buffer;
- zip->ecd.rawlength = buflen - offset;
+ // reuse the buffer as our ECD buffer
+ m_ecd.raw = std::move(buffer);
+ m_ecd.rawlength = buflen - offset;
/* append a NULL terminator to the comment */
- memmove(&buffer[0], &buffer[offset], zip->ecd.rawlength);
- zip->ecd.raw[zip->ecd.rawlength] = 0;
+ memmove(&m_ecd.raw[0], &m_ecd.raw[offset], m_ecd.rawlength);
+ m_ecd.raw[m_ecd.rawlength] = 0;
/* extract ecd info */
- zip->ecd.signature = read_dword(zip->ecd.raw + ZIPESIG);
- zip->ecd.disk_number = read_word (zip->ecd.raw + ZIPEDSK);
- zip->ecd.cd_start_disk_number = read_word (zip->ecd.raw + ZIPECEN);
- zip->ecd.cd_disk_entries = read_word (zip->ecd.raw + ZIPENUM);
- zip->ecd.cd_total_entries = read_word (zip->ecd.raw + ZIPECENN);
- zip->ecd.cd_size = read_dword(zip->ecd.raw + ZIPECSZ);
- zip->ecd.cd_start_disk_offset = read_dword(zip->ecd.raw + ZIPEOFST);
- zip->ecd.comment_length = read_word (zip->ecd.raw + ZIPECOML);
- zip->ecd.comment = (const char *)(zip->ecd.raw + ZIPECOM);
- return ZIPERR_NONE;
+ m_ecd.signature = read_dword(&m_ecd.raw[ZIPESIG]);
+ m_ecd.disk_number = read_word (&m_ecd.raw[ZIPEDSK]);
+ m_ecd.cd_start_disk_number = read_word (&m_ecd.raw[ZIPECEN]);
+ m_ecd.cd_disk_entries = read_word (&m_ecd.raw[ZIPENUM]);
+ m_ecd.cd_total_entries = read_word (&m_ecd.raw[ZIPECENN]);
+ m_ecd.cd_size = read_dword(&m_ecd.raw[ZIPECSZ]);
+ m_ecd.cd_start_disk_offset = read_dword(&m_ecd.raw[ZIPEOFST]);
+ m_ecd.comment_length = read_word (&m_ecd.raw[ZIPECOML]);
+ m_ecd.comment = reinterpret_cast<const char *>(&m_ecd.raw[ZIPECOM]);
+ return archive_file::error::NONE;
}
- /* didn't find it; free this buffer and expand our search */
- free(buffer);
- if (buflen < zip->length)
+ // didn't find it; free this buffer and expand our search
+ if (buflen < m_length)
buflen *= 2;
else
- return ZIPERR_BAD_SIGNATURE;
+ return archive_file::error::BAD_SIGNATURE;
}
- return ZIPERR_OUT_OF_MEMORY;
+ return archive_file::error::OUT_OF_MEMORY;
}
@@ -612,30 +606,25 @@ static zip_error read_ecd(zip_file *zip)
* @return The compressed data offset.
*/
-static zip_error get_compressed_data_offset(zip_file *zip, UINT64 *offset)
+archive_file::error zip_file_impl::get_compressed_data_offset(std::uint64_t &offset)
{
- file_error error;
- UINT32 read_length;
-
- /* make sure the file handle is open */
- if (zip->file == nullptr)
- {
- int filerr = osd_open(zip->filename, OPEN_FLAG_READ, &zip->file, &zip->length);
- if (filerr != FILERR_NONE)
- return ZIPERR_FILE_ERROR;
- }
+ // make sure the file handle is open
+ auto const ziperr = reopen();
+ if (ziperr != archive_file::error::NONE)
+ return ziperr;
- /* now go read the fixed-sized part of the local file header */
- error = osd_read(zip->file, zip->buffer, zip->header.local_header_offset, ZIPNAME, &read_length);
- if (error != FILERR_NONE || read_length != ZIPNAME)
- return (error == FILERR_NONE) ? ZIPERR_FILE_TRUNCATED : ZIPERR_FILE_ERROR;
+ // now go read the fixed-sized part of the local file header
+ std::uint32_t read_length;
+ auto const error = m_file->read(&m_buffer[0], m_header.local_header_offset, ZIPNAME, read_length);
+ if (error != osd_file::error::NONE || read_length != ZIPNAME)
+ return (error == osd_file::error::NONE) ? archive_file::error::FILE_TRUNCATED : archive_file::error::FILE_ERROR;
/* compute the final offset */
- *offset = zip->header.local_header_offset + ZIPNAME;
- *offset += read_word(zip->buffer + ZIPFNLN);
- *offset += read_word(zip->buffer + ZIPXTRALN);
+ offset = m_header.local_header_offset + ZIPNAME;
+ offset += read_word(&m_buffer[ZIPFNLN]);
+ offset += read_word(&m_buffer[ZIPXTRALN]);
- return ZIPERR_NONE;
+ return archive_file::error::NONE;
}
@@ -662,19 +651,18 @@ static zip_error get_compressed_data_offset(zip_file *zip, UINT64 *offset)
* @return A zip_error.
*/
-static zip_error decompress_data_type_0(zip_file *zip, UINT64 offset, void *buffer, UINT32 length)
+archive_file::error zip_file_impl::decompress_data_type_0(std::uint64_t offset, void *buffer, std::uint32_t length)
{
- file_error filerr;
- UINT32 read_length;
-
- /* the data is uncompressed; just read it */
- filerr = osd_read(zip->file, buffer, offset, zip->header.compressed_length, &read_length);
- if (filerr != FILERR_NONE)
- return ZIPERR_FILE_ERROR;
- else if (read_length != zip->header.compressed_length)
- return ZIPERR_FILE_TRUNCATED;
+ std::uint32_t read_length;
+
+ // the data is uncompressed; just read it
+ auto const filerr = m_file->read(buffer, offset, m_header.compressed_length, read_length);
+ if (filerr != osd_file::error::NONE)
+ return archive_file::error::FILE_ERROR;
+ else if (read_length != m_header.compressed_length)
+ return archive_file::error::FILE_TRUNCATED;
else
- return ZIPERR_NONE;
+ return archive_file::error::NONE;
}
@@ -696,75 +684,153 @@ static zip_error decompress_data_type_0(zip_file *zip, UINT64 offset, void *buff
* @return A zip_error.
*/
-static zip_error decompress_data_type_8(zip_file *zip, UINT64 offset, void *buffer, UINT32 length)
+archive_file::error zip_file_impl::decompress_data_type_8(std::uint64_t offset, void *buffer, std::uint32_t length)
{
- UINT32 input_remaining = zip->header.compressed_length;
- UINT32 read_length;
- z_stream stream;
- int filerr;
+ std::uint32_t input_remaining = m_header.compressed_length;
int zerr;
- /* make sure we don't need a newer mechanism */
- if (zip->header.version_needed > 0x14)
- return ZIPERR_UNSUPPORTED;
+ // make sure we don't need a newer mechanism
+ if (m_header.version_needed > 0x14)
+ return archive_file::error::UNSUPPORTED;
/* reset the stream */
+ z_stream stream;
memset(&stream, 0, sizeof(stream));
stream.next_out = (Bytef *)buffer;
stream.avail_out = length;
- /* initialize the decompressor */
+ // initialize the decompressor
zerr = inflateInit2(&stream, -MAX_WBITS);
if (zerr != Z_OK)
- return ZIPERR_DECOMPRESS_ERROR;
+ return archive_file::error::DECOMPRESS_ERROR;
- /* loop until we're done */
+ // loop until we're done
while (1)
{
- /* read in the next chunk of data */
- filerr = osd_read(zip->file, zip->buffer, offset, MIN(input_remaining, sizeof(zip->buffer)), &read_length);
- if (filerr != FILERR_NONE)
+ // read in the next chunk of data
+ std::uint32_t read_length;
+ auto const filerr = m_file->read(&m_buffer[0], offset, (std::min<std::uint32_t>)(input_remaining, m_buffer.size()), read_length);
+ if (filerr != osd_file::error::NONE)
{
inflateEnd(&stream);
- return ZIPERR_FILE_ERROR;
+ return archive_file::error::FILE_ERROR;
}
offset += read_length;
- /* if we read nothing, but still have data left, the file is truncated */
+ // if we read nothing, but still have data left, the file is truncated
if (read_length == 0 && input_remaining > 0)
{
inflateEnd(&stream);
- return ZIPERR_FILE_TRUNCATED;
+ return archive_file::error::FILE_TRUNCATED;
}
- /* fill out the input data */
- stream.next_in = zip->buffer;
+ // fill out the input data
+ stream.next_in = &m_buffer[0];
stream.avail_in = read_length;
input_remaining -= read_length;
- /* add a dummy byte at end of compressed data */
+ // add a dummy byte at end of compressed data
if (input_remaining == 0)
stream.avail_in++;
- /* now inflate */
+ // now inflate
zerr = inflate(&stream, Z_NO_FLUSH);
if (zerr == Z_STREAM_END)
break;
if (zerr != Z_OK)
{
inflateEnd(&stream);
- return ZIPERR_DECOMPRESS_ERROR;
+ return archive_file::error::DECOMPRESS_ERROR;
}
}
- /* finish decompression */
+ // finish decompression
zerr = inflateEnd(&stream);
if (zerr != Z_OK)
- return ZIPERR_DECOMPRESS_ERROR;
+ return archive_file::error::DECOMPRESS_ERROR;
/* if anything looks funny, report an error */
if (stream.avail_out > 0 || input_remaining > 0)
- return ZIPERR_DECOMPRESS_ERROR;
+ return archive_file::error::DECOMPRESS_ERROR;
+
+ return archive_file::error::NONE;
+}
+
+} // anonymous namespace
+
+
+
+/***************************************************************************
+ un7z.cpp TRAMPOLINES
+***************************************************************************/
+
+void m7z_file_cache_clear();
+
+
+
+/***************************************************************************
+ ZIP FILE ACCESS
+***************************************************************************/
+
+/*-------------------------------------------------
+ zip_file_open - opens a ZIP file for reading
+-------------------------------------------------*/
+
+/**
+ * @fn zip_error zip_file_open(const char *filename, zip_file **zip)
+ *
+ * @brief Queries if a given zip file open.
+ *
+ * @param filename Filename of the file.
+ * @param [in,out] zip If non-null, the zip.
+ *
+ * @return A zip_error.
+ */
+
+archive_file::error archive_file::open_zip(const std::string &filename, ptr &result)
+{
+ // ensure we start with a NULL result
+ result.reset();
+
+ // see if we are in the cache, and reopen if so
+ zip_file_impl::ptr newimpl(zip_file_impl::find_cached(filename));
+
+ if (!newimpl)
+ {
+ // allocate memory for the zip_file structure
+ try { newimpl = std::make_unique<zip_file_impl>(filename); }
+ catch (...) { return error::OUT_OF_MEMORY; }
+ auto const ziperr = newimpl->initialize();
+ if (ziperr != error::NONE) return ziperr;
+ }
- return ZIPERR_NONE;
+ try
+ {
+ result = std::make_unique<zip_file_wrapper>(std::move(newimpl));
+ return error::NONE;
+ }
+ catch (...)
+ {
+ zip_file_impl::close(std::move(newimpl));
+ return error::OUT_OF_MEMORY;
+ }
}
+
+
+/*-------------------------------------------------
+ zip_file_cache_clear - clear the ZIP file
+ cache and free all memory
+-------------------------------------------------*/
+
+void archive_file::cache_clear()
+{
+ zip_file_impl::cache_clear();
+ m7z_file_cache_clear();
+}
+
+
+archive_file::~archive_file()
+{
+}
+
+} // namespace util
diff --git a/src/lib/util/unzip.h b/src/lib/util/unzip.h
index fa3956be8c3..5fafaec57a4 100644
--- a/src/lib/util/unzip.h
+++ b/src/lib/util/unzip.h
@@ -1,138 +1,89 @@
// license:BSD-3-Clause
-// copyright-holders:Aaron Giles
+// copyright-holders:Aaron Giles, Vas Crabb
/***************************************************************************
unzip.h
- ZIP file management.
+ archive file management.
***************************************************************************/
#pragma once
-#ifndef __UNZIP_H__
-#define __UNZIP_H__
+#ifndef MAME_LIB_UTIL_UNZIP_H
+#define MAME_LIB_UTIL_UNZIP_H
#include "osdcore.h"
-
-/***************************************************************************
- CONSTANTS
-***************************************************************************/
-
-#define ZIP_DECOMPRESS_BUFSIZE 16384
-
-/* Error types */
-enum zip_error
-{
- ZIPERR_NONE = 0,
- ZIPERR_OUT_OF_MEMORY,
- ZIPERR_FILE_ERROR,
- ZIPERR_BAD_SIGNATURE,
- ZIPERR_DECOMPRESS_ERROR,
- ZIPERR_FILE_TRUNCATED,
- ZIPERR_FILE_CORRUPT,
- ZIPERR_UNSUPPORTED,
- ZIPERR_BUFFER_TOO_SMALL
-};
+#include <cstdint>
+#include <memory>
+#include <string>
+namespace util {
/***************************************************************************
TYPE DEFINITIONS
***************************************************************************/
-/* contains extracted file header information */
-struct zip_file_header
+// describes an open archive file
+class archive_file
{
- UINT32 signature; /* central file header signature */
- UINT16 version_created; /* version made by */
- UINT16 version_needed; /* version needed to extract */
- UINT16 bit_flag; /* general purpose bit flag */
- UINT16 compression; /* compression method */
- UINT16 file_time; /* last mod file time */
- UINT16 file_date; /* last mod file date */
- UINT32 crc; /* crc-32 */
- UINT32 compressed_length; /* compressed size */
- UINT32 uncompressed_length; /* uncompressed size */
- UINT16 filename_length; /* filename length */
- UINT16 extra_field_length; /* extra field length */
- UINT16 file_comment_length; /* file comment length */
- UINT16 start_disk_number; /* disk number start */
- UINT16 internal_attributes; /* internal file attributes */
- UINT32 external_attributes; /* external file attributes */
- UINT32 local_header_offset; /* relative offset of local header */
- const char * filename; /* filename */
-
- UINT8 * raw; /* pointer to the raw data */
- UINT32 rawlength; /* length of the raw data */
- UINT8 saved; /* saved byte from after filename */
-};
+public:
+ // Error types
+ enum class error
+ {
+ NONE = 0,
+ OUT_OF_MEMORY,
+ FILE_ERROR,
+ BAD_SIGNATURE,
+ DECOMPRESS_ERROR,
+ FILE_TRUNCATED,
+ FILE_CORRUPT,
+ UNSUPPORTED,
+ BUFFER_TOO_SMALL
+ };
-/* contains extracted end of central directory information */
-struct zip_ecd
-{
- UINT32 signature; /* end of central dir signature */
- UINT16 disk_number; /* number of this disk */
- UINT16 cd_start_disk_number; /* number of the disk with the start of the central directory */
- UINT16 cd_disk_entries; /* total number of entries in the central directory on this disk */
- UINT16 cd_total_entries; /* total number of entries in the central directory */
- UINT32 cd_size; /* size of the central directory */
- UINT32 cd_start_disk_offset; /* offset of start of central directory with respect to the starting disk number */
- UINT16 comment_length; /* .ZIP file comment length */
- const char * comment; /* .ZIP file comment */
-
- UINT8 * raw; /* pointer to the raw data */
- UINT32 rawlength; /* length of the raw data */
-};
+ typedef std::unique_ptr<archive_file> ptr;
-/* describes an open ZIP file */
-struct zip_file
-{
- const char * filename; /* copy of ZIP filename (for caching) */
- osd_file * file; /* OSD file handle */
- UINT64 length; /* length of zip file */
+ /* ----- archive file access ----- */
- zip_ecd ecd; /* end of central directory */
+ // open a ZIP file and parse its central directory
+ static error open_zip(const std::string &filename, ptr &zip);
- UINT8 * cd; /* central directory raw data */
- UINT32 cd_pos; /* position in central directory */
- zip_file_header header; /* current file header */
+ // open a 7Z file and parse its central directory
+ static error open_7z(const std::string &filename, ptr &result);
- UINT8 buffer[ZIP_DECOMPRESS_BUFSIZE]; /* buffer for decompression */
-};
-
-
-
-/***************************************************************************
- FUNCTION PROTOTYPES
-***************************************************************************/
-
-
-/* ----- ZIP file access ----- */
+ // close an archive file (may actually be left open due to caching)
+ virtual ~archive_file();
-/* open a ZIP file and parse its central directory */
-zip_error zip_file_open(const char *filename, zip_file **zip);
+ // clear out all open files from the cache
+ static void cache_clear();
-/* close a ZIP file (may actually be left open due to caching) */
-void zip_file_close(zip_file *zip);
-/* clear out all open ZIP files from the cache */
-void zip_file_cache_clear(void);
+ /* ----- contained file access ----- */
+ // iterating over files - returns negative on reaching end
+ virtual int first_file() = 0;
+ virtual int next_file() = 0;
-/* ----- contained file access ----- */
+ // find a file index by crc, filename or both - returns non-negative on match
+ virtual int search(std::uint32_t crc) = 0;
+ virtual int search(const std::string &filename) = 0;
+ virtual int search(std::uint32_t crc, const std::string &filename) = 0;
-/* find the first file in the ZIP */
-const zip_file_header *zip_file_first_file(zip_file *zip);
+ // information on most recently found file
+ virtual bool current_is_directory() const = 0;
+ virtual const std::string &current_name() const = 0;
+ virtual std::uint64_t current_uncompressed_length() const = 0;
+ virtual std::uint32_t current_crc() const = 0;
-/* find the next file in the ZIP */
-const zip_file_header *zip_file_next_file(zip_file *zip);
-
-/* decompress the most recently found file in the ZIP */
-zip_error zip_file_decompress(zip_file *zip, void *buffer, UINT32 length);
+ // decompress the most recently found file in the ZIP
+ virtual error decompress(void *buffer, std::uint32_t length) = 0;
+};
+} // namespace util
-#endif /* __UNZIP_H__ */
+#endif // MAME_LIB_UTIL_UNZIP_H
diff --git a/src/lib/util/vecstream.h b/src/lib/util/vecstream.h
index bf144501253..fda218c3e68 100644
--- a/src/lib/util/vecstream.h
+++ b/src/lib/util/vecstream.h
@@ -320,11 +320,10 @@ public:
basic_ivectorstream(vector_type const &content, std::ios_base::openmode mode = std::ios_base::in) : std::basic_istream<CharT, Traits>(&m_rdbuf), m_rdbuf(content, mode) { }
basic_ivectorstream(vector_type &&content, std::ios_base::openmode mode = std::ios_base::in) : std::basic_istream<CharT, Traits>(&m_rdbuf), m_rdbuf(std::move(content), mode) { }
- basic_vectorbuf<CharT, Traits, Allocator> *rdbuf() const { return reinterpret_cast<basic_vectorbuf<CharT, Traits, Allocator> *>(std::basic_istream<CharT, Traits>::rdbuf()); }
+ basic_vectorbuf<CharT, Traits, Allocator> *rdbuf() const { return static_cast<basic_vectorbuf<CharT, Traits, Allocator> *>(std::basic_istream<CharT, Traits>::rdbuf()); }
vector_type const &vec() const { return rdbuf()->vec(); }
void vec(const vector_type &content) { rdbuf()->vec(content); }
void vec(vector_type &&content) { rdbuf()->vec(std::move(content)); }
- basic_ivectorstream &clear() { rdbuf()->clear(); return *this; }
void swap(basic_ivectorstream &that) { std::basic_istream<CharT, Traits>::swap(that); rdbuf()->swap(*that.rdbuf()); }
@@ -342,12 +341,11 @@ public:
basic_ovectorstream(vector_type const &content, std::ios_base::openmode mode = std::ios_base::out) : std::basic_ostream<CharT, Traits>(&m_rdbuf), m_rdbuf(content, mode) { }
basic_ovectorstream(vector_type &&content, std::ios_base::openmode mode = std::ios_base::out) : std::basic_ostream<CharT, Traits>(&m_rdbuf), m_rdbuf(std::move(content), mode) { }
- basic_vectorbuf<CharT, Traits, Allocator> *rdbuf() const { return reinterpret_cast<basic_vectorbuf<CharT, Traits, Allocator> *>(std::basic_ostream<CharT, Traits>::rdbuf()); }
+ basic_vectorbuf<CharT, Traits, Allocator> *rdbuf() const { return static_cast<basic_vectorbuf<CharT, Traits, Allocator> *>(std::basic_ostream<CharT, Traits>::rdbuf()); }
vector_type const &vec() const { return rdbuf()->vec(); }
void vec(const vector_type &content) { rdbuf()->vec(content); }
void vec(vector_type &&content) { rdbuf()->vec(std::move(content)); }
- basic_ovectorstream &clear() { rdbuf()->clear(); return *this; }
basic_ovectorstream &reserve(typename vector_type::size_type size) { rdbuf()->reserve(size); return *this; }
void swap(basic_ovectorstream &that) { std::basic_ostream<CharT, Traits>::swap(that); rdbuf()->swap(*that.rdbuf()); }
@@ -366,12 +364,11 @@ public:
basic_vectorstream(vector_type const &content, std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out) : std::basic_iostream<CharT, Traits>(&m_rdbuf), m_rdbuf(content, mode) { }
basic_vectorstream(vector_type &&content, std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out) : std::basic_iostream<CharT, Traits>(&m_rdbuf), m_rdbuf(std::move(content), mode) { }
- basic_vectorbuf<CharT, Traits, Allocator> *rdbuf() const { return reinterpret_cast<basic_vectorbuf<CharT, Traits, Allocator> *>(std::basic_iostream<CharT, Traits>::rdbuf()); }
+ basic_vectorbuf<CharT, Traits, Allocator> *rdbuf() const { return static_cast<basic_vectorbuf<CharT, Traits, Allocator> *>(std::basic_iostream<CharT, Traits>::rdbuf()); }
vector_type const &vec() const { return rdbuf()->vec(); }
void vec(const vector_type &content) { rdbuf()->vec(content); }
void vec(vector_type &&content) { rdbuf()->vec(std::move(content)); }
- basic_vectorstream &clear() { rdbuf()->clear(); return *this; }
basic_vectorstream &reserve(typename vector_type::size_type size) { rdbuf()->reserve(size); return *this; }
void swap(basic_vectorstream &that) { std::basic_iostream<CharT, Traits>::swap(that); rdbuf()->swap(*that.rdbuf()); }
diff --git a/src/lib/util/zippath.cpp b/src/lib/util/zippath.cpp
index efe7c710481..edeecf80c47 100644
--- a/src/lib/util/zippath.cpp
+++ b/src/lib/util/zippath.cpp
@@ -8,15 +8,19 @@
***************************************************************************/
-#include <ctype.h>
-#include <stdlib.h>
-#include <new>
-#include <assert.h>
#include "zippath.h"
#include "unzip.h"
#include "corestr.h"
#include "osdcore.h"
+#include <stdlib.h>
+
+#include <cassert>
+#include <cctype>
+#include <new>
+
+
+namespace util {
/***************************************************************************
TYPE DEFINITIONS
@@ -66,7 +70,7 @@ public:
/** @brief true to called zip first. */
bool called_zip_first;
/** @brief The zipfile. */
- zip_file *zipfile;
+ archive_file::ptr zipfile;
/** @brief The zipprefix. */
std::string zipprefix;
/** @brief The returned dirlist. */
@@ -78,10 +82,10 @@ public:
FUNCTION PROTOTYPES
***************************************************************************/
-static const zip_file_header *zippath_find_sub_path(zip_file *zipfile, const char *subpath, osd_dir_entry_type *type);
-static int is_zip_file(const char *path);
-static int is_zip_file_separator(char c);
-static int is_7z_file(const char *path);
+static int zippath_find_sub_path(archive_file &zipfile, std::string const &subpath, osd_dir_entry_type &type);
+static bool is_zip_file(std::string const &path);
+static bool is_zip_file_separator(char c);
+static bool is_7z_file(std::string const &path);
/***************************************************************************
@@ -148,29 +152,15 @@ static void parse_parent_path(const char *path, int *beginpos, int *endpos)
zippath_parent - retrieves the parent directory
-------------------------------------------------*/
-/**
- * @fn std::string &zippath_parent(std::string &dst, const char *path)
- *
- * @brief Zippath parent.
- *
- * @param [in,out] dst Destination for the.
- * @param path Full pathname of the file.
- *
- * @return A std::string&amp;
- */
-
std::string &zippath_parent(std::string &dst, const char *path)
{
int pos;
parse_parent_path(path, &pos, nullptr);
- /* return the result */
- if (pos >= 0) {
+ if (pos >= 0)
dst.assign(path, pos + 1);
- }
- else {
+ else
dst.clear();
- }
return dst;
}
@@ -251,42 +241,42 @@ std::string &zippath_combine(std::string &dst, const char *path1, const char *pa
/*-------------------------------------------------
file_error_from_zip_error - translates a
- file_error to a zip_error
+ osd_file::error to a zip_error
-------------------------------------------------*/
/**
- * @fn static file_error file_error_from_zip_error(zip_error ziperr)
+ * @fn static osd_file::error file_error_from_zip_error(archive_file::error ziperr)
*
* @brief File error from zip error.
*
* @param ziperr The ziperr.
*
- * @return A file_error.
+ * @return A osd_file::error.
*/
-static file_error file_error_from_zip_error(zip_error ziperr)
+static osd_file::error file_error_from_zip_error(archive_file::error ziperr)
{
- file_error filerr;
+ osd_file::error filerr;
switch(ziperr)
{
- case ZIPERR_NONE:
- filerr = FILERR_NONE;
- break;
- case ZIPERR_OUT_OF_MEMORY:
- filerr = FILERR_OUT_OF_MEMORY;
- break;
- case ZIPERR_BAD_SIGNATURE:
- case ZIPERR_DECOMPRESS_ERROR:
- case ZIPERR_FILE_TRUNCATED:
- case ZIPERR_FILE_CORRUPT:
- case ZIPERR_UNSUPPORTED:
- case ZIPERR_FILE_ERROR:
- filerr = FILERR_INVALID_DATA;
- break;
- case ZIPERR_BUFFER_TOO_SMALL:
- default:
- filerr = FILERR_FAILURE;
- break;
+ case archive_file::error::NONE:
+ filerr = osd_file::error::NONE;
+ break;
+ case archive_file::error::OUT_OF_MEMORY:
+ filerr = osd_file::error::OUT_OF_MEMORY;
+ break;
+ case archive_file::error::BAD_SIGNATURE:
+ case archive_file::error::DECOMPRESS_ERROR:
+ case archive_file::error::FILE_TRUNCATED:
+ case archive_file::error::FILE_CORRUPT:
+ case archive_file::error::UNSUPPORTED:
+ case archive_file::error::FILE_ERROR:
+ filerr = osd_file::error::INVALID_DATA;
+ break;
+ case archive_file::error::BUFFER_TOO_SMALL:
+ default:
+ filerr = osd_file::error::FAILURE;
+ break;
}
return filerr;
}
@@ -298,7 +288,7 @@ static file_error file_error_from_zip_error(zip_error ziperr)
-------------------------------------------------*/
/**
- * @fn static file_error create_core_file_from_zip(zip_file *zip, const zip_file_header *header, util::core_file::ptr &file)
+ * @fn static osd_file::error create_core_file_from_zip(archive_file *zip, util::core_file::ptr &file)
*
* @brief Creates core file from zip.
*
@@ -309,28 +299,28 @@ static file_error file_error_from_zip_error(zip_error ziperr)
* @return The new core file from zip.
*/
-static file_error create_core_file_from_zip(zip_file *zip, const zip_file_header *header, util::core_file::ptr &file)
+static osd_file::error create_core_file_from_zip(archive_file &zip, util::core_file::ptr &file)
{
- file_error filerr;
- zip_error ziperr;
+ osd_file::error filerr;
+ archive_file::error ziperr;
void *ptr;
- ptr = malloc(header->uncompressed_length);
+ ptr = malloc(zip.current_uncompressed_length());
if (ptr == nullptr)
{
- filerr = FILERR_OUT_OF_MEMORY;
+ filerr = osd_file::error::OUT_OF_MEMORY;
goto done;
}
- ziperr = zip_file_decompress(zip, ptr, header->uncompressed_length);
- if (ziperr != ZIPERR_NONE)
+ ziperr = zip.decompress(ptr, zip.current_uncompressed_length());
+ if (ziperr != archive_file::error::NONE)
{
filerr = file_error_from_zip_error(ziperr);
goto done;
}
- filerr = util::core_file::open_ram_copy(ptr, header->uncompressed_length, OPEN_FLAG_READ, file);
- if (filerr != FILERR_NONE)
+ filerr = util::core_file::open_ram_copy(ptr, zip.current_uncompressed_length(), OPEN_FLAG_READ, file);
+ if (filerr != osd_file::error::NONE)
goto done;
done:
@@ -345,7 +335,7 @@ done:
-------------------------------------------------*/
/**
- * @fn file_error zippath_fopen(const char *filename, UINT32 openflags, util::core_file::ptr &file, std::string &revised_path)
+ * @fn osd_file::error zippath_fopen(const char *filename, UINT32 openflags, util::core_file::ptr &file, std::string &revised_path)
*
* @brief Zippath fopen.
*
@@ -354,17 +344,16 @@ done:
* @param [in,out] file [in,out] If non-null, the file.
* @param [in,out] revised_path Full pathname of the revised file.
*
- * @return A file_error.
+ * @return A osd_file::error.
*/
-file_error zippath_fopen(const char *filename, UINT32 openflags, util::core_file::ptr &file, std::string &revised_path)
+osd_file::error zippath_fopen(const char *filename, UINT32 openflags, util::core_file::ptr &file, std::string &revised_path)
{
- file_error filerr = FILERR_NOT_FOUND;
- zip_error ziperr;
- zip_file *zip = nullptr;
- const zip_file_header *header;
+ osd_file::error filerr = osd_file::error::NOT_FOUND;
+ archive_file::error ziperr;
+ archive_file::ptr zip;
+ int header;
osd_dir_entry_type entry_type;
- char *alloc_fullpath = nullptr;
int len;
/* first, set up the two types of paths */
@@ -377,56 +366,51 @@ file_error zippath_fopen(const char *filename, UINT32 openflags, util::core_file
&& ((openflags == OPEN_FLAG_READ) || (subpath.length() == 0)))
{
/* is the mainpath a ZIP path? */
- if (is_zip_file(mainpath.c_str()))
+ if (is_zip_file(mainpath) || is_7z_file(mainpath))
{
/* this file might be a zip file - lets take a look */
- ziperr = zip_file_open(mainpath.c_str(), &zip);
- if (ziperr == ZIPERR_NONE)
+ ziperr = is_zip_file(mainpath) ? archive_file::open_zip(mainpath, zip) : archive_file::open_7z(mainpath, zip);
+ if (ziperr == archive_file::error::NONE)
{
/* it is a zip file - error if we're not opening for reading */
if (openflags != OPEN_FLAG_READ)
{
- filerr = FILERR_ACCESS_DENIED;
+ filerr = osd_file::error::ACCESS_DENIED;
goto done;
}
if (subpath.length() > 0)
- header = zippath_find_sub_path(zip, subpath.c_str(), &entry_type);
+ header = zippath_find_sub_path(*zip, subpath, entry_type);
else
- header = zip_file_first_file(zip);
+ header = zip->first_file();
- if (header == nullptr)
+ if (header < 0)
{
- filerr = FILERR_NOT_FOUND;
+ filerr = osd_file::error::NOT_FOUND;
goto done;
}
/* attempt to read the file */
- filerr = create_core_file_from_zip(zip, header, file);
- if (filerr != FILERR_NONE)
+ filerr = create_core_file_from_zip(*zip, file);
+ if (filerr != osd_file::error::NONE)
goto done;
/* update subpath, if appropriate */
if (subpath.length() == 0)
- subpath.assign(header->filename);
+ subpath.assign(zip->current_name());
/* we're done */
goto done;
}
}
- else if (is_7z_file(mainpath.c_str()))
- {
- filerr = FILERR_INVALID_DATA;
- goto done;
- }
if (subpath.length() == 0)
filerr = util::core_file::open(filename, openflags, file);
else
- filerr = FILERR_NOT_FOUND;
+ filerr = osd_file::error::NOT_FOUND;
/* if we errored, then go up a directory */
- if (filerr != FILERR_NONE)
+ if (filerr != osd_file::error::NONE)
{
/* go up a directory */
std::string temp;
@@ -457,23 +441,19 @@ file_error zippath_fopen(const char *filename, UINT32 openflags, util::core_file
done:
/* store the revised path */
revised_path.clear();
- if (filerr == FILERR_NONE)
+ if (filerr == osd_file::error::NONE)
{
/* cannonicalize mainpath */
- filerr = osd_get_full_path(&alloc_fullpath, mainpath.c_str());
- if (filerr == FILERR_NONE)
+ std::string alloc_fullpath;
+ filerr = osd_get_full_path(alloc_fullpath, mainpath);
+ if (filerr == osd_file::error::NONE)
{
+ revised_path = alloc_fullpath;
if (subpath.length() > 0)
- revised_path.assign(alloc_fullpath).append(PATH_SEPARATOR).append(subpath);
- else
- revised_path.assign(alloc_fullpath);
+ revised_path.append(PATH_SEPARATOR).append(subpath);
}
}
- if (zip != nullptr)
- zip_file_close(zip);
- if (alloc_fullpath != nullptr)
- osd_free(alloc_fullpath);
return filerr;
}
@@ -528,10 +508,10 @@ static int is_root(const char *path)
* @return An int.
*/
-static int is_7z_file(const char *path)
+static bool is_7z_file(std::string const &path)
{
- const char *s = strrchr(path, '.');
- return (s != nullptr) && !core_stricmp(s, ".7z");
+ auto const s = path.rfind('.');
+ return (std::string::npos != s) && !core_stricmp(path.c_str() + s, ".7z");
}
@@ -540,20 +520,10 @@ static int is_7z_file(const char *path)
ZIP file
-------------------------------------------------*/
-/**
- * @fn static int is_zip_file(const char *path)
- *
- * @brief Is zip file.
- *
- * @param path Full pathname of the file.
- *
- * @return An int.
- */
-
-static int is_zip_file(const char *path)
+static bool is_zip_file(std::string const &path)
{
- const char *s = strrchr(path, '.');
- return (s != nullptr) && !core_stricmp(s, ".zip");
+ auto const s = path.rfind('.');
+ return (std::string::npos != s) && !core_stricmp(path.c_str() + s, ".zip");
}
@@ -573,7 +543,7 @@ static int is_zip_file(const char *path)
* @return An int.
*/
-static int is_zip_file_separator(char c)
+static bool is_zip_file_separator(char c)
{
return (c == '/') || (c == '\\');
}
@@ -595,7 +565,7 @@ static int is_zip_file_separator(char c)
* @return An int.
*/
-static int is_zip_path_separator(char c)
+static bool is_zip_path_separator(char c)
{
return is_zip_file_separator(c) || is_path_separator(c);
}
@@ -618,38 +588,35 @@ static int is_zip_path_separator(char c)
* @return A char.
*/
-static char next_path_char(const char *s, int *pos)
+static char next_path_char(std::string const &s, std::string::size_type &pos)
{
- char result;
-
- /* skip over any initial separators */
- if (*pos == 0)
+ // skip over any initial separators
+ if (pos == 0)
{
- while(is_zip_file_separator(s[*pos]))
- (*pos)++;
+ while ((pos < s.length()) && is_zip_file_separator(s[pos]))
+ pos++;
}
- /* are we at a path separator? */
- if (is_zip_file_separator(s[*pos]))
+ // are we at a path separator?
+ if (pos == s.length())
{
- /* skip over path separators */
- while(is_zip_file_separator(s[*pos]))
- (*pos)++;
-
- /* normalize as '/' */
- result = '/';
+ // return NUL
+ return '\0';
}
- else if (s[*pos] != '\0')
+ else if (is_zip_file_separator(s[pos]))
{
- /* return character */
- result = tolower(s[(*pos)++]);
+ // skip over path separators
+ while((pos < s.length()) && is_zip_file_separator(s[pos]))
+ pos++;
+
+ // normalize as '/'
+ return '/';
}
else
{
- /* return NUL */
- result = '\0';
+ // return character
+ return std::tolower(s[pos++]);
}
- return result;
}
@@ -661,7 +628,7 @@ static char next_path_char(const char *s, int *pos)
-------------------------------------------------*/
/**
- * @fn static const zip_file_header *zippath_find_sub_path(zip_file *zipfile, const char *subpath, osd_dir_entry_type *type)
+ * @fn static const zip_file_header *zippath_find_sub_path(archive_file *zipfile, const char *subpath, osd_dir_entry_type *type)
*
* @brief Zippath find sub path.
*
@@ -672,50 +639,36 @@ static char next_path_char(const char *s, int *pos)
* @return null if it fails, else a zip_file_header*.
*/
-static const zip_file_header *zippath_find_sub_path(zip_file *zipfile, const char *subpath, osd_dir_entry_type *type)
+static int zippath_find_sub_path(archive_file &zipfile, std::string const &subpath, osd_dir_entry_type &type)
{
- int i, j;
- char c1, c2, last_char;
- const zip_file_header *header;
-
- for (header = zip_file_first_file(zipfile); header != nullptr; header = zip_file_next_file(zipfile))
+ for (int header = zipfile.first_file(); header >= 0; header = zipfile.next_file())
{
- /* special case */
- if (subpath == nullptr)
+ std::string::size_type i = 0, j = 0;
+ char c1, c2;
+ do
{
- if (type != nullptr)
- *type = ENTTYPE_FILE;
- return header;
+ c1 = next_path_char(zipfile.current_name(), i);
+ c2 = next_path_char(subpath, j);
}
+ while ((c1 == c2) && c1 && c2);
- i = 0;
- j = 0;
- last_char = '/';
- while(((c1 = next_path_char(header->filename, &i)) == (c2 = next_path_char(subpath, &j))) &&
- ( c1 != '\0' && c2 != '\0' ))
- last_char = c2;
-
-
- if (c2 == '\0')
+ if (!c2 || ((c2 == '/') && !(c2 = next_path_char(subpath, j))))
{
- if (c1 == '\0')
+ if (!c1)
{
- if (type != nullptr)
- *type = ENTTYPE_FILE;
+ type = zipfile.current_is_directory() ? ENTTYPE_DIR : ENTTYPE_FILE;
return header;
}
- else if ((last_char == '/') || (c1 == '/'))
+ else if ((c1 == '/') || (i <= 1U))
{
- if (type != nullptr)
- *type = ENTTYPE_DIR;
+ type = ENTTYPE_DIR;
return header;
}
}
}
- if (type != nullptr)
- *type = ENTTYPE_NONE;
- return nullptr;
+ type = ENTTYPE_NONE;
+ return -1;
}
@@ -726,7 +679,7 @@ static const zip_file_header *zippath_find_sub_path(zip_file *zipfile, const cha
-------------------------------------------------*/
/**
- * @fn static file_error zippath_resolve(const char *path, osd_dir_entry_type &entry_type, zip_file *&zipfile, std::string &newpath)
+ * @fn static osd_file::error zippath_resolve(const char *path, osd_dir_entry_type &entry_type, archive_file *&zipfile, std::string &newpath)
*
* @brief Zippath resolve.
*
@@ -735,97 +688,81 @@ static const zip_file_header *zippath_find_sub_path(zip_file *zipfile, const cha
* @param [in,out] zipfile [in,out] If non-null, the zipfile.
* @param [in,out] newpath The newpath.
*
- * @return A file_error.
+ * @return A osd_file::error.
*/
-static file_error zippath_resolve(const char *path, osd_dir_entry_type &entry_type, zip_file *&zipfile, std::string &newpath)
+static osd_file::error zippath_resolve(const char *path, osd_dir_entry_type &entry_type, archive_file::ptr &zipfile, std::string &newpath)
{
- file_error err;
- osd_directory_entry *current_entry = nullptr;
- osd_dir_entry_type current_entry_type;
- int went_up = FALSE;
- int i;
-
newpath.clear();
- /* be conservative */
+ // be conservative
entry_type = ENTTYPE_NONE;
- zipfile = nullptr;
+ zipfile.reset();
std::string apath(path);
std::string apath_trimmed;
+ osd_dir_entry_type current_entry_type;
+ bool went_up = false;
do
{
- /* trim the path of trailing path separators */
- i = apath.length();
- while (i > 1 && is_path_separator(apath[i - 1]))
+ // trim the path of trailing path separators
+ auto i = apath.length();
+ while ((i > 1) && is_path_separator(apath[i - 1]))
i--;
- apath = apath.substr(0, i);
- apath_trimmed.assign(apath);
+ apath.resize(i);
+ apath_trimmed = apath;
- /* stat the path */
- current_entry = osd_stat(apath_trimmed.c_str());
+ // stat the path
+ std::unique_ptr<osd_directory_entry, void (*)(void *)> current_entry(osd_stat(apath_trimmed), &osd_free);
- /* did we find anything? */
- if (current_entry != nullptr)
+ // did we find anything?
+ if (current_entry)
{
- /* get the entry type and free the stat entry */
+ // get the entry type and free the stat entry
current_entry_type = current_entry->type;
- osd_free(current_entry);
- current_entry = nullptr;
}
else
{
- /* if we have not found the file or directory, go up */
+ // if we have not found the file or directory, go up
current_entry_type = ENTTYPE_NONE;
- went_up = TRUE;
+ went_up = true;
std::string parent;
- apath.assign(zippath_parent(parent, apath.c_str()));
+ apath = zippath_parent(parent, apath.c_str());
}
}
- while (current_entry_type == ENTTYPE_NONE && !is_root(apath.c_str()));
+ while ((current_entry_type == ENTTYPE_NONE) && !is_root(apath.c_str()));
- /* if we did not find anything, then error out */
+ // if we did not find anything, then error out
if (current_entry_type == ENTTYPE_NONE)
- {
- err = FILERR_NOT_FOUND;
- goto done;
- }
+ return osd_file::error::NOT_FOUND;
- /* is this file a ZIP file? */
- if ((current_entry_type == ENTTYPE_FILE) && is_zip_file(apath_trimmed.c_str())
- && (zip_file_open(apath_trimmed.c_str(), &zipfile) == ZIPERR_NONE))
+ // is this file a ZIP file?
+ if ((current_entry_type == ENTTYPE_FILE) &&
+ ((is_zip_file(apath_trimmed) && (archive_file::open_zip(apath_trimmed, zipfile) == archive_file::error::NONE)) ||
+ (is_7z_file(apath_trimmed) && (archive_file::open_7z(apath_trimmed, zipfile) == archive_file::error::NONE))))
{
- i = strlen(path + apath.length());
- while (i > 0 && is_zip_path_separator(path[apath.length() + i - 1]))
+ auto i = strlen(path + apath.length());
+ while ((i > 0) && is_zip_path_separator(path[apath.length() + i - 1]))
i--;
newpath.assign(path + apath.length(), i);
- /* this was a true ZIP path - attempt to identify the type of path */
- zippath_find_sub_path(zipfile, newpath.c_str(), &current_entry_type);
+ // this was a true ZIP path - attempt to identify the type of path
+ zippath_find_sub_path(*zipfile, newpath, current_entry_type);
if (current_entry_type == ENTTYPE_NONE)
- {
- err = FILERR_NOT_FOUND;
- goto done;
- }
+ return osd_file::error::NOT_FOUND;
}
else
{
- /* this was a normal path */
+ // this was a normal path
if (went_up)
- {
- err = FILERR_NOT_FOUND;
- goto done;
- }
- newpath.assign(path);
+ return osd_file::error::NOT_FOUND;
+
+ newpath = path;
}
- /* success! */
+ // success!
entry_type = current_entry_type;
- err = FILERR_NONE;
-
-done:
- return err;
+ return osd_file::error::NONE;
}
@@ -834,19 +771,19 @@ done:
-------------------------------------------------*/
/**
- * @fn file_error zippath_opendir(const char *path, zippath_directory **directory)
+ * @fn osd_file::error zippath_opendir(const char *path, zippath_directory **directory)
*
* @brief Zippath opendir.
*
* @param path Full pathname of the file.
* @param [in,out] directory If non-null, pathname of the directory.
*
- * @return A file_error.
+ * @return A osd_file::error.
*/
-file_error zippath_opendir(const char *path, zippath_directory **directory)
+osd_file::error zippath_opendir(const char *path, zippath_directory **directory)
{
- file_error err;
+ osd_file::error err;
/* allocate a directory */
zippath_directory *result = nullptr;
@@ -856,30 +793,30 @@ file_error zippath_opendir(const char *path, zippath_directory **directory)
}
catch (std::bad_alloc &)
{
- err = FILERR_OUT_OF_MEMORY;
+ err = osd_file::error::OUT_OF_MEMORY;
goto done;
}
/* resolve the path */
osd_dir_entry_type entry_type;
err = zippath_resolve(path, entry_type, result->zipfile, result->zipprefix);
- if (err != FILERR_NONE)
+ if (err != osd_file::error::NONE)
goto done;
/* we have to be a directory */
if (entry_type != ENTTYPE_DIR)
{
- err = FILERR_NOT_FOUND;
+ err = osd_file::error::NOT_FOUND;
goto done;
}
/* was the result a ZIP? */
- if (result->zipfile == nullptr)
+ if (!result->zipfile)
{
/* a conventional directory */
result->directory = osd_opendir(path);
- if (result->directory == nullptr)
+ if (!result->directory)
{
- err = FILERR_FAILURE;
+ err = osd_file::error::FAILURE;
goto done;
}
@@ -889,7 +826,7 @@ file_error zippath_opendir(const char *path, zippath_directory **directory)
}
done:
- if ((directory == nullptr || err != FILERR_NONE) && result != nullptr)
+ if ((directory == nullptr || err != osd_file::error::NONE) && result != nullptr)
{
zippath_closedir(result);
result = nullptr;
@@ -918,7 +855,7 @@ void zippath_closedir(zippath_directory *directory)
osd_closedir(directory->directory);
if (directory->zipfile != nullptr)
- zip_file_close(directory->zipfile);
+ directory->zipfile.reset();
while (directory->returned_dirlist != nullptr)
{
@@ -948,20 +885,27 @@ void zippath_closedir(zippath_directory *directory)
* @return null if it fails, else the relative path.
*/
-static const char *get_relative_path(zippath_directory *directory, const zip_file_header *header)
+static const char *get_relative_path(zippath_directory const &directory)
{
- const char *result = nullptr;
- int len = directory->zipprefix.length();
+ auto len = directory.zipprefix.length();
+ const char *prefix = directory.zipprefix.c_str();
+ while (is_zip_file_separator(*prefix))
+ {
+ len--;
+ prefix++;
+ }
- if ((len <= strlen(header->filename))
- && !strncmp(directory->zipprefix.c_str(), header->filename, len))
+ if ((len <= directory.zipfile->current_name().length()) &&
+ !strncmp(prefix, directory.zipfile->current_name().c_str(), len))
{
- result = &header->filename[len];
- while(is_zip_file_separator(*result))
+ const char *result = &directory.zipfile->current_name().c_str()[len];
+ while (is_zip_file_separator(*result))
result++;
+
+ return *result ? result : nullptr;
}
- return result;
+ return nullptr;
}
@@ -982,7 +926,7 @@ static const char *get_relative_path(zippath_directory *directory, const zip_fil
const osd_directory_entry *zippath_readdir(zippath_directory *directory)
{
const osd_directory_entry *result = nullptr;
- const zip_file_header *header;
+ int header;
const char *relpath;
const char *separator;
const char *s;
@@ -997,7 +941,7 @@ const osd_directory_entry *zippath_readdir(zippath_directory *directory)
directory->returned_entry.type = ENTTYPE_DIR;
result = &directory->returned_entry;
}
- else if (directory->directory != nullptr)
+ else if (directory->directory)
{
/* a normal directory read */
do
@@ -1007,7 +951,7 @@ const osd_directory_entry *zippath_readdir(zippath_directory *directory)
while((result != nullptr) && (!strcmp(result->name, ".") || !strcmp(result->name, "..")));
/* special case - is this entry a ZIP file? if so we need to return it as a "directory" */
- if ((result != nullptr) && is_zip_file(result->name))
+ if ((result != nullptr) && (is_zip_file(result->name) || is_7z_file(result->name)))
{
/* copy; but change the entry type */
directory->returned_entry = *result;
@@ -1015,7 +959,7 @@ const osd_directory_entry *zippath_readdir(zippath_directory *directory)
result = &directory->returned_entry;
}
}
- else if (directory->zipfile != nullptr)
+ else if (directory->zipfile)
{
do
{
@@ -1023,13 +967,13 @@ const osd_directory_entry *zippath_readdir(zippath_directory *directory)
do
{
if (!directory->called_zip_first)
- header = zip_file_first_file(directory->zipfile);
+ header = directory->zipfile->first_file();
else
- header = zip_file_next_file(directory->zipfile);
+ header = directory->zipfile->next_file();
directory->called_zip_first = true;
relpath = nullptr;
}
- while((header != nullptr) && ((relpath = get_relative_path(directory, header)) == nullptr));
+ while((header >= 0) && ((relpath = get_relative_path(*directory)) == nullptr));
if (relpath != nullptr)
{
@@ -1068,7 +1012,7 @@ const osd_directory_entry *zippath_readdir(zippath_directory *directory)
memset(&directory->returned_entry, 0, sizeof(directory->returned_entry));
directory->returned_entry.name = relpath;
directory->returned_entry.type = ENTTYPE_FILE;
- directory->returned_entry.size = header->uncompressed_length;
+ directory->returned_entry.size = directory->zipfile->current_uncompressed_length();
result = &directory->returned_entry;
}
}
@@ -1099,3 +1043,5 @@ int zippath_is_zip(zippath_directory *directory)
{
return directory->zipfile != nullptr;
}
+
+} // namespace util
diff --git a/src/lib/util/zippath.h b/src/lib/util/zippath.h
index ce40c87ba8d..653617d66cc 100644
--- a/src/lib/util/zippath.h
+++ b/src/lib/util/zippath.h
@@ -10,14 +10,16 @@
#pragma once
-#ifndef __ZIPPATH_H__
-#define __ZIPPATH_H__
+#ifndef MAME_LIB_UTIL_ZIPPATH_H
+#define MAME_LIB_UTIL_ZIPPATH_H
#include "corefile.h"
#include <string>
#include "unzip.h"
+namespace util {
+
/***************************************************************************
TYPE DEFINITIONS
***************************************************************************/
@@ -45,13 +47,13 @@ std::string &zippath_combine(std::string &dst, const char *path1, const char *pa
/* ----- file operations ----- */
/* opens a zip path file */
-file_error zippath_fopen(const char *filename, UINT32 openflags, util::core_file::ptr &file, std::string &revised_path);
+osd_file::error zippath_fopen(const char *filename, UINT32 openflags, util::core_file::ptr &file, std::string &revised_path);
/* ----- directory operations ----- */
/* opens a directory */
-file_error zippath_opendir(const char *path, zippath_directory **directory);
+osd_file::error zippath_opendir(const char *path, zippath_directory **directory);
/* closes a directory */
void zippath_closedir(zippath_directory *directory);
@@ -62,6 +64,7 @@ const osd_directory_entry *zippath_readdir(zippath_directory *directory);
/* returns TRUE if this path is a ZIP path or FALSE if not */
int zippath_is_zip(zippath_directory *directory);
+} // namespace util
-#endif /* __ZIPPATH_H__ */
+#endif /* MAME_LIB_UTIL_ZIPPATH_H */
diff --git a/src/mame/arcade.flt b/src/mame/arcade.flt
index 0ea37056023..c8dd56f91ad 100644
--- a/src/mame/arcade.flt
+++ b/src/mame/arcade.flt
@@ -1323,3 +1323,23 @@ zerozone.cpp
zn.cpp
zodiack.cpp
zr107.cpp
+//exceptions + to add - to remove from imported list
+//3do.cpp
+-3do
+-3do_m2
+-3do_pal
+//cdi.cpp
+-cdi490a
+-cdi910
+-cdimono1
+-cdimono2
+//cps1.cpp
+-sfach
+-sfzbch
+-sfzch
+-wofch
+//jaguar.cpp
+-jaguar
+-jaguarcd
+//vectrex.cpp
+-vectrex
diff --git a/src/mame/drivers/android.cpp b/src/mame/drivers/android.cpp
deleted file mode 100644
index 8c4ca2f2215..00000000000
--- a/src/mame/drivers/android.cpp
+++ /dev/null
@@ -1,321 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:David Haywood
-
-// Note, another VERY different version of this also exists, see https://www.youtube.com/watch?v=5rtqZqMBACI (uploaded by Chris Hardy)
-// it is unclear if that version is on the same hardware as this
-
-#include "emu.h"
-#include "cpu/z80/z80.h"
-#include "machine/i8255.h"
-#include "sound/2203intf.h"
-
-class androidp_state : public driver_device
-{
-public:
- androidp_state(const machine_config &mconfig, device_type type, const char *tag)
- : driver_device(mconfig, type, tag),
- m_maincpu(*this, "maincpu"),
- m_subcpu(*this, "subcpu"),
- m_gfxdecode(*this, "gfxdecode"),
- m_bgram(*this, "bgram")
-
- { }
-
- virtual void machine_start() override;
- virtual void machine_reset() override;
- virtual void video_start() override;
- UINT32 screen_update_androidp(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
- required_device<cpu_device> m_maincpu;
- required_device<cpu_device> m_subcpu;
- required_device<gfxdecode_device> m_gfxdecode;
-
- required_shared_ptr<UINT8> m_bgram;
- tilemap_t *m_bg_tilemap;
- TILE_GET_INFO_MEMBER(get_bg_tile_info);
- DECLARE_WRITE8_MEMBER(androidp_bgram_w);
- DECLARE_WRITE8_MEMBER(bg_scrollx_w);
-
- DECLARE_WRITE8_MEMBER(port_3_w);
-
- DECLARE_WRITE8_MEMBER(port_6_w);
- DECLARE_WRITE8_MEMBER(port_7_w);
- DECLARE_WRITE8_MEMBER(port_8_w);
- DECLARE_WRITE8_MEMBER(port_9_w);
-
- DECLARE_WRITE8_MEMBER(port_b_w);
-
- DECLARE_WRITE_LINE_MEMBER(irqhandler);
-
-};
-
-TILE_GET_INFO_MEMBER(androidp_state::get_bg_tile_info)
-{
- int code = (m_bgram[tile_index*2]);
- int attr = (m_bgram[(tile_index*2)+1]);
-
- code |= (attr & 0x7) << 8;
-
- int color = (attr & 0xf0) >> 4;
-
- SET_TILE_INFO_MEMBER(1,
- code,
- color,
- 0);
-}
-
-WRITE8_MEMBER(androidp_state::androidp_bgram_w)
-{
- m_bgram[offset] = data;
- m_bg_tilemap->mark_tile_dirty(offset/2);
-}
-
-
-
-void androidp_state::video_start()
-{
- m_bg_tilemap = &machine().tilemap().create(m_gfxdecode, tilemap_get_info_delegate(FUNC(androidp_state::get_bg_tile_info),this), TILEMAP_SCAN_ROWS, 8, 8, 64, 32);
-}
-
-UINT32 androidp_state::screen_update_androidp(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
-{
- m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
- return 0;
-}
-
-WRITE8_MEMBER(androidp_state::bg_scrollx_w)
-{
- m_bg_tilemap->set_scrollx(0, data);
-}
-
-
-WRITE8_MEMBER(androidp_state::port_3_w)
-{
- // 9b on startup
-// printf("port3_w %02x\n", data);
-}
-
-WRITE8_MEMBER(androidp_state::port_6_w)
-{
-// int bank = (data & 0x0e) >> 1;
-// membank("bank1")->set_entry(bank);
-
- // seems most likely candidate for ROM BANK
-
- // 04 during title, 08 during high score
- //printf("%04x: port6_w %02x\n", space.device().safe_pc(), data);
-}
-
-WRITE8_MEMBER(androidp_state::port_7_w)
-{
- // 92 on startup
- //printf("port7_w %02x\n", data);
-}
-
-WRITE8_MEMBER(androidp_state::port_8_w)
-{
- // 00 between screens
- //printf("port8_w %02x\n", data);
-}
-
-WRITE8_MEMBER(androidp_state::port_9_w)
-{
- if (data!=0x00)
- printf("port9_w %02x\n", data);
-}
-
-WRITE8_MEMBER(androidp_state::port_b_w)
-{
- // 00 on startup
- // 23 ff between scenes
-// printf("portb_w %02x\n", data);
-}
-
-static ADDRESS_MAP_START( androidp_map, AS_PROGRAM, 8, androidp_state )
- AM_RANGE(0x0000, 0x7fff) AM_ROM
- AM_RANGE(0x8000, 0x9fff) AM_RAM
- AM_RANGE(0xa000, 0xa0ff) AM_RAM // sprites?
- AM_RANGE(0xa800, 0xacff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette") // 0xa800 - 0xa8ff (bg) and 0xac00 - 0xacff (sprites) used
- AM_RANGE(0xb000, 0xbfff) AM_RAM_WRITE(androidp_bgram_w) AM_SHARE("bgram")
- AM_RANGE(0xc000, 0xffff) AM_ROMBANK("bank1")
-ADDRESS_MAP_END
-
-static ADDRESS_MAP_START( androidp_portmap, AS_IO, 8, androidp_state )
- ADDRESS_MAP_GLOBAL_MASK(0xff)
- AM_RANGE(0x02, 0x02) AM_READ_PORT("02") // probably from sub-cpu (inputs read by that?)
-
- AM_RANGE(0x03, 0x03) AM_WRITE( port_3_w )
-
- AM_RANGE(0x06, 0x06) AM_WRITE( port_6_w )
- AM_RANGE(0x07, 0x07) AM_WRITE( port_7_w )
- AM_RANGE(0x08, 0x08) AM_WRITE( port_8_w )
- AM_RANGE(0x09, 0x09) AM_WRITE( port_9_w )
-
- AM_RANGE(0x0a, 0x0a) AM_WRITE( bg_scrollx_w )
- AM_RANGE(0x0b, 0x0b) AM_WRITE( port_b_w )
-
-ADDRESS_MAP_END
-
-
-
-static ADDRESS_MAP_START( androidp_sub_map, AS_PROGRAM, 8, androidp_state )
- AM_RANGE(0x0000, 0x7fff) AM_ROM
- AM_RANGE(0xf800, 0xffff) AM_RAM
-
-ADDRESS_MAP_END
-
-static ADDRESS_MAP_START( androidp_sub_portmap, AS_IO, 8, androidp_state )
- ADDRESS_MAP_GLOBAL_MASK(0xff)
- AM_RANGE(0x00, 0x01) AM_DEVREADWRITE("ym", ym2203_device, read, write)
-
-ADDRESS_MAP_END
-
-
-
-static INPUT_PORTS_START( androidp )
-
- PORT_START("02")
- PORT_DIPNAME( 0x01, 0x01, DEF_STR( Unknown ) )
- PORT_DIPSETTING( 0x01, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_DIPNAME( 0x02, 0x02, DEF_STR( Unknown ) )
- PORT_DIPSETTING( 0x02, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_DIPNAME( 0x04, 0x04, DEF_STR( Unknown ) )
- PORT_DIPSETTING( 0x04, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_DIPNAME( 0x08, 0x08, DEF_STR( Unknown ) )
- PORT_DIPSETTING( 0x08, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unknown ) )
- PORT_DIPSETTING( 0x10, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_DIPNAME( 0x20, 0x20, DEF_STR( Unknown ) )
- PORT_DIPSETTING( 0x20, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_DIPNAME( 0x40, 0x40, DEF_STR( Unknown ) )
- PORT_DIPSETTING( 0x40, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x00, DEF_STR( On ) )
- PORT_DIPNAME( 0x80, 0x80, DEF_STR( Unknown ) )
- PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
- PORT_DIPSETTING( 0x00, DEF_STR( On ) )
-
-INPUT_PORTS_END
-
-
-
-static const gfx_layout sprite16x16_layout =
-{
- 16,16,
- RGN_FRAC(1,1),
- 4,
- { 0, 1, 2, 3 },
- { 4,0 ,12,8, 20,16, 28,24, 36,32, 44,40, 52, 48, 60, 56},
- { 0*64, 1*64, 2*64, 3*64, 4*64, 5*64, 6*64, 7*64, 8*64,9*64,10*64,11*64,12*64,13*64,14*64,15*64 },
- 64*16
-};
-
-static const gfx_layout tiles8x8_layout =
-{
- 8,8,
- RGN_FRAC(1,1),
- 4,
- { 0, 1, 2, 3 },
- { 4, 0, 12, 8, 20, 16, 28, 24 },
- { 0*32, 1*32, 2*32, 3*32, 4*32, 5*32, 6*32, 7*32 },
- 32*8
-};
-
-static GFXDECODE_START( androidp )
- GFXDECODE_ENTRY( "sprites", 0, sprite16x16_layout, 0, 16 )
- GFXDECODE_ENTRY( "gfx2", 0, tiles8x8_layout, 0, 16 )
-GFXDECODE_END
-
-
-
-void androidp_state::machine_start()
-{
- membank("bank1")->configure_entries(0, 6, memregion("maincpu")->base() + 0x0000, 0x4000);
-}
-
-void androidp_state::machine_reset()
-{
- membank("bank1")->set_entry(2);
-}
-
-WRITE_LINE_MEMBER(androidp_state::irqhandler)
-{
- m_subcpu->set_input_line(0, state ? ASSERT_LINE : CLEAR_LINE);
-}
-
-
-static MACHINE_CONFIG_START( androidp, androidp_state )
-
- /* basic machine hardware */
- MCFG_CPU_ADD("maincpu", Z80,4000000) /* ? MHz */
- MCFG_CPU_PROGRAM_MAP(androidp_map)
- MCFG_CPU_IO_MAP(androidp_portmap)
- MCFG_CPU_VBLANK_INT_DRIVER("screen", androidp_state, irq0_line_hold)
-
- MCFG_CPU_ADD("subcpu", Z80,4000000) /* ? MHz */
- MCFG_CPU_PROGRAM_MAP(androidp_sub_map)
- MCFG_CPU_IO_MAP(androidp_sub_portmap)
-// MCFG_CPU_VBLANK_INT_DRIVER("screen", androidp_state, irq0_line_hold)
-
- MCFG_DEVICE_ADD("ppi8255_0", I8255A, 0)
-// MCFG_I8255_IN_PORTA_CB(IOPORT("IN0"))
-// MCFG_I8255_IN_PORTB_CB(IOPORT("IN3"))
-
- MCFG_DEVICE_ADD("ppi8255_1", I8255A, 0)
-// MCFG_I8255_IN_PORTA_CB(IOPORT("IN1"))
-/// MCFG_I8255_IN_PORTB_CB(IOPORT("IN2"))
-// MCFG_I8255_IN_PORTC_CB(IOPORT("DSW1"))
-
- MCFG_SOUND_ADD("ym", YM2203, 4000000) // ? Mhz
- MCFG_YM2203_IRQ_HANDLER(WRITELINE(androidp_state, irqhandler))
- MCFG_SOUND_ROUTE(0, "mono", 0.65)
- MCFG_SOUND_ROUTE(1, "mono", 0.65)
- MCFG_SOUND_ROUTE(2, "mono", 0.65)
- MCFG_SOUND_ROUTE(3, "mono", 0.45)
-
-
- /* 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, 32*8)
- MCFG_SCREEN_VISIBLE_AREA(0, (30*8)-1, 0, (24*8)-1)
- MCFG_SCREEN_UPDATE_DRIVER(androidp_state, screen_update_androidp)
- MCFG_SCREEN_PALETTE("palette")
-
- MCFG_GFXDECODE_ADD("gfxdecode", "palette", androidp)
- MCFG_PALETTE_ADD("palette", 0x400)
- MCFG_PALETTE_FORMAT(xRRRRRGGGGGBBBBB)
- MCFG_PALETTE_ENDIANNESS(ENDIANNESS_LITTLE)
-
- /* sound hardware */
- MCFG_SPEAKER_STANDARD_MONO("mono")
-MACHINE_CONFIG_END
-
-
-
-ROM_START( androidp )
- ROM_REGION( 0x18000, "maincpu", 0 )
- ROM_LOAD( "MITSUBISHI_A01.toppcb.m5l27256k.k1.BIN", 0x00000, 0x08000, CRC(25ab85eb) SHA1(e1fab149c83ff880b119258206d5818f3db641c5) )
- ROM_LOAD( "MITSUBISHI_A02.toppcb.m5l27256k.J1.BIN", 0x08000, 0x08000, CRC(e41426be) SHA1(e7e06ef3ff5160bb7d870e148ba2799da52cf24c) )
- ROM_LOAD( "MITSUBISHI_A03.toppcb.m5l27256k.G1.BIN", 0x10000, 0x08000, CRC(6cf5f48a) SHA1(b9b4e5e7bace0e8d98fbc9f4ad91bc56ef42099e) )
-
- ROM_REGION( 0x18000, "subcpu", 0 )
- ROM_LOAD( "MITSUBISHI_A04.toppcb.m5l27256k.N6.BIN", 0x00000, 0x08000, CRC(13c38fe4) SHA1(34a35fa057159a5c83892a88b8c908faa39d5cb3) )
-
- ROM_REGION( 0x20000, "sprites", 0 )
- ROM_LOAD16_BYTE( "MITSUBISHI_A06.botpcb.m5l27512k.9E.BIN", 0x00000, 0x10000, CRC(5e42984e) SHA1(2a928960c740dfb94589e011cce093bed2fd7685) )
- ROM_LOAD16_BYTE( "MITSUBISHI_A07.botpcb.m5l27512k.9B.BIN", 0x00001, 0x10000, CRC(611ff400) SHA1(1a9aed33d0e3f063811f92b9fee3ecbff0e965bf) )
-
- ROM_REGION( 0x10000, "gfx2", 0 )
- ROM_LOAD( "MITSUBISHI_A05.toppcb.m5l27512k.F5.BIN", 0x00000, 0x10000, CRC(4c72a930) SHA1(f1542844391b55fe43293eef7ce48c09b7aca75a) )
-
- // + 2 undumped PLDs
-ROM_END
-
-
-GAME( 198?, androidp, 0, androidp, androidp, driver_device, 0, ROT90, "Nasco", "Android (early build?)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
diff --git a/src/mame/drivers/angelkds.cpp b/src/mame/drivers/angelkds.cpp
index db73d337800..aa6d996010b 100644
--- a/src/mame/drivers/angelkds.cpp
+++ b/src/mame/drivers/angelkds.cpp
@@ -22,13 +22,11 @@ for details on this encryption scheme
/* notes / todo:
-Decrypt Space Position Somehow (not something I
-can do)
Unknown Reads / Writes
Whats the Prom for? nothing important?
-Is the level order correct?
the progress sprite on the side of the screen re-appears at the bottom when you get
to the top, but the wrap-around is needed for other things, actual game bug?
+Angel Kids service mode doesn't seem to work, did it ever?
*/
@@ -130,7 +128,7 @@ Dumped by Chackn
#include "machine/segacrp2.h"
#include "sound/2203intf.h"
#include "includes/angelkds.h"
-
+#include "machine/i8255.h"
@@ -146,37 +144,8 @@ WRITE8_MEMBER(angelkds_state::angelkds_cpu_bank_write)
}
-/*** Fake Inputs
-
-these make the game a bit easier for testing purposes
-
-*/
-
-#define FAKEINPUTS 0
-
-#if FAKEINPUTS
-
-READ8_MEMBER(angelkds_state::angelkds_input_r)
-{
- int fake;
- static const char *const portnames[] = { "I81", "I82" };
- static const char *const fakenames[] = { "FAKE1", "FAKE2" };
- fake = ioport(fakenames[offset])->read();
-
- return ((fake & 0x01) ? fake : ioport(portnames[offset])->read());
-}
-
-#else
-
-READ8_MEMBER(angelkds_state::angelkds_input_r)
-{
- static const char *const portnames[] = { "I81", "I82" };
-
- return ioport(portnames[offset])->read();
-}
-#endif
/*** Memory Structures
@@ -202,7 +171,8 @@ static ADDRESS_MAP_START( main_map, AS_PROGRAM, 8, angelkds_state )
AM_RANGE(0xe400, 0xe7ff) AM_RAM_WRITE(angelkds_bgbotvideoram_w) AM_SHARE("bgbotvideoram") /* Bottom Half of Screen */
AM_RANGE(0xe800, 0xebff) AM_RAM_WRITE(angelkds_txvideoram_w) AM_SHARE("txvideoram")
AM_RANGE(0xec00, 0xecff) AM_RAM AM_SHARE("spriteram")
- AM_RANGE(0xed00, 0xeeff) AM_RAM_WRITE(angelkds_paletteram_w) AM_SHARE("paletteram")
+ AM_RANGE(0xed00, 0xedff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette")
+ AM_RANGE(0xee00, 0xeeff) AM_RAM_DEVWRITE("palette", palette_device, write_ext) AM_SHARE("palette_ext")
AM_RANGE(0xef00, 0xefff) AM_RAM
AM_RANGE(0xf000, 0xf000) AM_WRITE(angelkds_bgtopbank_write)
AM_RANGE(0xf001, 0xf001) AM_WRITE(angelkds_bgtopscroll_write)
@@ -220,17 +190,17 @@ ADDRESS_MAP_END
static ADDRESS_MAP_START( main_portmap, AS_IO, 8, angelkds_state )
ADDRESS_MAP_GLOBAL_MASK(0xff)
AM_RANGE(0x00, 0x00) AM_WRITENOP // 00 on start-up, not again
- AM_RANGE(0x42, 0x42) AM_WRITE(angelkds_cpu_bank_write)
- AM_RANGE(0x43, 0x43) AM_WRITENOP // 9a on start-up, not again
- AM_RANGE(0x40, 0x40) AM_READ_PORT("I40") /* "Coinage" Dip Switches */
- AM_RANGE(0x41, 0x41) AM_READ_PORT("I41") /* Other Dip Switches */
- AM_RANGE(0x42, 0x42) AM_READ_PORT("I42") /* Players inputs (not needed ?) */
- AM_RANGE(0x80, 0x80) AM_READ_PORT("I80") /* System inputs */
- AM_RANGE(0x81, 0x82) AM_READ(angelkds_input_r) /* Players inputs */
- AM_RANGE(0x83, 0x83) AM_WRITENOP // 9b on start-up, not again
+
+ AM_RANGE(0x40, 0x43) AM_DEVREADWRITE("ppi8255_0", i8255_device, read, write)
+ AM_RANGE(0x80, 0x83) AM_DEVREADWRITE("ppi8255_1", i8255_device, read, write)
+
AM_RANGE(0xc0, 0xc3) AM_READWRITE(angelkds_main_sound_r, angelkds_main_sound_w) // 02 various points
ADDRESS_MAP_END
+
+
+
+
/* sub cpu */
static ADDRESS_MAP_START( sub_map, AS_PROGRAM, 8, angelkds_state )
@@ -261,16 +231,6 @@ ADDRESS_MAP_END
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_JOYSTICKLEFT_LEFT ) PORT_PLAYER(player) PORT_8WAY \
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_JOYSTICKLEFT_RIGHT ) PORT_PLAYER(player) PORT_8WAY
-#define ANGELDSK_FAKE_PLAYERS_INPUT( player ) \
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(player) /* To enter initials */ \
- PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN ) /* Unused */ \
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(player) PORT_8WAY \
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(player) PORT_8WAY \
- PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(player) PORT_8WAY \
- PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(player) PORT_8WAY \
- PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(player) /* To shorten the rope and */ \
- /* move right in hiscores table */
-
static INPUT_PORTS_START( angelkds )
/*
@@ -339,15 +299,6 @@ static INPUT_PORTS_START( angelkds )
PORT_DIPSETTING( 0x80, DEF_STR( Hard ) )
PORT_DIPSETTING( 0x00, DEF_STR( Very_Hard ) )
- PORT_START("I42") /* inport $42 */
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN ) // duplicated IPT_JOYSTICK_LEFTRIGHT
- PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_8WAY // duplicated IPT_JOYSTICK_LEFTRIGHT
- PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_8WAY PORT_COCKTAIL
- PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START("I80") /* inport $80 */
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN1 )
@@ -365,23 +316,6 @@ static INPUT_PORTS_START( angelkds )
PORT_START("I82") /* inport $82 */
ANGELDSK_PLAYERS_INPUT( 2 )
-#if FAKEINPUTS
-
- /* Fake inputs to allow to play the game with 1 joystick instead of 2 */
- PORT_START("FAKE1")
- PORT_DIPNAME( 0x01, 0x00, "FAKE (for debug) Joysticks (Player 1)" )
- PORT_DIPSETTING( 0x01, "1" )
- PORT_DIPSETTING( 0x00, "2" )
- ANGELDSK_FAKE_PLAYERS_INPUT( 1 )
-
- PORT_START("FAKE2")
- PORT_DIPNAME( 0x01, 0x00, "FAKE (for debug) Joysticks (Player 2)" )
- PORT_DIPSETTING( 0x01, "1" )
- PORT_DIPSETTING( 0x00, "2" )
- ANGELDSK_FAKE_PLAYERS_INPUT( 2 )
-
-#endif
-
INPUT_PORTS_END
static INPUT_PORTS_START( spcpostn )
@@ -443,16 +377,6 @@ static INPUT_PORTS_START( spcpostn )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPUNUSED_DIPLOC( 0x80, 0x80, "SW2:8" ) /* Listed as "Unused" */
- PORT_START("I42") /* inport $42 */
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
-
PORT_START("I80") /* inport $80 */
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN1 )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_COIN2 )
@@ -601,6 +525,16 @@ static MACHINE_CONFIG_START( angelkds, angelkds_state )
MCFG_CPU_PROGRAM_MAP(sub_map)
MCFG_CPU_IO_MAP(sub_portmap)
+ MCFG_DEVICE_ADD("ppi8255_0", I8255A, 0)
+ MCFG_I8255_IN_PORTA_CB(IOPORT("I40"))
+ MCFG_I8255_IN_PORTB_CB(IOPORT("I41"))
+ MCFG_I8255_IN_PORTC_CB(READ8(angelkds_state, angeklds_ff_r)) // or left inputs don't work
+ MCFG_I8255_OUT_PORTC_CB(WRITE8(angelkds_state, angelkds_cpu_bank_write))
+
+ MCFG_DEVICE_ADD("ppi8255_1", I8255A, 0)
+ MCFG_I8255_IN_PORTA_CB(IOPORT("I80"))
+ MCFG_I8255_IN_PORTB_CB(IOPORT("I81"))
+ MCFG_I8255_IN_PORTC_CB(IOPORT("I82"))
MCFG_QUANTUM_TIME(attotime::from_hz(6000))
@@ -615,6 +549,7 @@ static MACHINE_CONFIG_START( angelkds, angelkds_state )
MCFG_GFXDECODE_ADD("gfxdecode", "palette", angelkds)
MCFG_PALETTE_ADD("palette", 0x100)
+ MCFG_PALETTE_FORMAT(xxxxBBBBGGGGRRRR)
MCFG_SPEAKER_STANDARD_MONO("mono")
@@ -657,7 +592,7 @@ ROM_START( angelkds )
ROM_REGION( 0x8000, "maincpu", 0 )
ROM_LOAD( "11428.c10", 0x00000, 0x08000, CRC(90daacd2) SHA1(7e50ad1cbed0c1e6bad04ef1611cad25538c905f) )
- ROM_REGION( 0x20000, "user1", 0 ) /* Banked Code */
+ ROM_REGION( 0x40000, "user1", 0 ) /* Banked Code */
ROM_LOAD( "11424.c1", 0x00000, 0x08000, CRC(b55997f6) SHA1(7ed746becac1851f39591f1fdbeff64aa97d6206) )
ROM_LOAD( "11425.c2", 0x08000, 0x08000, CRC(299359de) SHA1(f531dd3bfe6f64e9e043cb4f85d5657455241dc7) )
ROM_LOAD( "11426.c3", 0x10000, 0x08000, CRC(5fad8bd3) SHA1(4d865342eb10dcfb779eee4ac1e159bb9ec140cb) )
@@ -704,7 +639,7 @@ ROM_START( spcpostn )
ROM_REGION( 0x8000, "maincpu", 0 ) /* D317-0005 (NEC Z80 Custom) */
ROM_LOAD( "epr10125.c10", 0x00000, 0x08000, CRC(bffd38c6) SHA1(af02907124343ddecd21439d25f1ebb81ef9f51a) ) /* encrypted */
- ROM_REGION( 0x28000, "user1", 0 ) /* Banked Code */
+ ROM_REGION( 0x40000, "user1", 0 ) /* Banked Code */
ROM_LOAD( "epr10120.c1", 0x00000, 0x08000, CRC(d6399f99) SHA1(4c7d19a8798e5a10b688bf793ca74f5170fd9b51) )
ROM_LOAD( "epr10121.c2", 0x08000, 0x08000, CRC(d4861560) SHA1(74d28c36a08880abbd3c398cc3e990e8986caccb) )
ROM_LOAD( "epr10122.c3", 0x10000, 0x08000, CRC(7a1bff1b) SHA1(e1bda8430fd632c1813dd78e0f210a358e1b0d2f) )
@@ -740,7 +675,7 @@ ROM_END
DRIVER_INIT_MEMBER(angelkds_state,angelkds)
{
UINT8 *RAM = memregion("user1")->base();
- membank("bank1")->configure_entries(0, 8, &RAM[0x0000], 0x4000);
+ membank("bank1")->configure_entries(0, 16, &RAM[0x0000], 0x4000);
}
DRIVER_INIT_MEMBER(angelkds_state,spcpostn)
@@ -750,7 +685,7 @@ DRIVER_INIT_MEMBER(angelkds_state,spcpostn)
// 317-0005
sega_decode_317(memregion("maincpu")->base(), m_decrypted_opcodes, 1);
- membank("bank1")->configure_entries(0, 10, &RAM[0x0000], 0x4000);
+ membank("bank1")->configure_entries(0, 16, &RAM[0x0000], 0x4000);
}
diff --git a/src/mame/drivers/apple3.cpp b/src/mame/drivers/apple3.cpp
index 6608ca3a34f..d369a914217 100644
--- a/src/mame/drivers/apple3.cpp
+++ b/src/mame/drivers/apple3.cpp
@@ -61,7 +61,7 @@ static MACHINE_CONFIG_START( apple3, apple3_state )
MCFG_SCREEN_ADD("screen", RASTER)
MCFG_SCREEN_REFRESH_RATE(60)
MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */
- MCFG_SCREEN_SIZE(280*2, 224)
+ MCFG_SCREEN_SIZE((280*2)+32, 224)
MCFG_SCREEN_VISIBLE_AREA(0, (280*2)-1,0,192-1)
MCFG_SCREEN_UPDATE_DRIVER(apple3_state, screen_update_apple3)
MCFG_SCREEN_PALETTE("palette")
@@ -130,12 +130,12 @@ static MACHINE_CONFIG_START( apple3, apple3_state )
MCFG_DEVICE_ADD("rtc", MM58167, XTAL_32_768kHz)
/* via */
- MCFG_DEVICE_ADD("via6522_0", VIA6522, 2000000)
+ MCFG_DEVICE_ADD("via6522_0", VIA6522, 1000000)
MCFG_VIA6522_WRITEPA_HANDLER(WRITE8(apple3_state, apple3_via_0_out_a))
MCFG_VIA6522_WRITEPB_HANDLER(WRITE8(apple3_state, apple3_via_0_out_b))
MCFG_VIA6522_IRQ_HANDLER(WRITELINE(apple3_state, apple3_via_0_irq_func))
- MCFG_DEVICE_ADD("via6522_1", VIA6522, 2000000)
+ MCFG_DEVICE_ADD("via6522_1", VIA6522, 1000000)
MCFG_VIA6522_WRITEPA_HANDLER(WRITE8(apple3_state, apple3_via_1_out_a))
MCFG_VIA6522_WRITEPB_HANDLER(WRITE8(apple3_state, apple3_via_1_out_b))
MCFG_VIA6522_IRQ_HANDLER(WRITELINE(apple3_state, apple3_via_1_irq_func))
diff --git a/src/mame/drivers/carjmbre.cpp b/src/mame/drivers/carjmbre.cpp
index 68a1330fefd..127d6d7c385 100644
--- a/src/mame/drivers/carjmbre.cpp
+++ b/src/mame/drivers/carjmbre.cpp
@@ -4,6 +4,14 @@
Car Jamboree
Omori Electric CAD (OEC) 1983
+
+ TODO:
+ - colors are wrong
+ - sprite priorities?
+
+----------------------------------------------------------------------------
+
+ PCB sketch:
c14 c.d19
c13 c.d18 c10
diff --git a/src/mame/drivers/cclimber.cpp b/src/mame/drivers/cclimber.cpp
index bc924df4980..f8b89ed07b2 100644
--- a/src/mame/drivers/cclimber.cpp
+++ b/src/mame/drivers/cclimber.cpp
@@ -1382,6 +1382,37 @@ ROM_START( cclimbroper )
ROM_END
+ROM_START( cclimbrrod )
+ ROM_REGION( 0x6000, "maincpu", 0 )
+ ROM_LOAD( "cc5.bin", 0x0000, 0x1000, CRC(a67238e9) SHA1(f873b754f658f32e2462b63544cbb7f0866e23ff) )
+ ROM_LOAD( "cc4.bin", 0x1000, 0x1000, CRC(4b1abea6) SHA1(eae7c96fc0b64d313bed4a75bd6d397b37eaac7e) )
+ ROM_LOAD( "cc3.bin", 0x2000, 0x1000, CRC(5612bb3c) SHA1(213846bb3393467260f401b00b821cbab7ac9636) )
+ ROM_LOAD( "cc2.bin", 0x3000, 0x1000, CRC(653cebc4) SHA1(c0b664389f7a6f58e880ba0870118aa26c636a37) )
+ ROM_LOAD( "cc1.bin", 0x4000, 0x1000, CRC(3fcf912b) SHA1(d540895018bc409ae011ce5841c8c5384bbbb1b9) )
+
+ ROM_REGION( 0x4000, "gfx1", 0 )
+ ROM_LOAD( "cc13.bin", 0x0000, 0x0800, CRC(8e0299f5) SHA1(77aa4fd6ee2177971753168bad6eac33034d3fb9) )
+ /* 0x0800-0x0fff - empty */
+ ROM_LOAD( "cc12.bin", 0x1000, 0x0800, CRC(e8cd7b53) SHA1(d4d6120fa14016e197340e8d1eb1141f0eb0eee8) )
+ /* 0x1800-0xffff - empty */
+ ROM_LOAD( "cc11.bin", 0x2000, 0x0800, CRC(921ebd9a) SHA1(95873fcab5da5e4affacdb6c3cab12b305f4b9fd) )
+ /* 0x2800-0x2fff - empty */
+ ROM_LOAD( "cc10.bin", 0x3000, 0x0800, CRC(8ab5fa6b) SHA1(ff31d2c89fe8cd5a276247b11418fb60de03804c))
+ /* 0x3800-0x3fff - empty */
+
+ ROM_REGION( 0x1000, "gfx2", 0 )
+ ROM_LOAD( "cc9.bin", 0x0000, 0x0800, CRC(6fb2afaf) SHA1(d2fe31d00af10e6bcabef51885ce52fb17d1bfbc) )
+ ROM_LOAD( "cc8.bin", 0x0800, 0x0800, CRC(227ee804) SHA1(0cda61a0ceeab299e7d40d33bf6dad3490928323) )
+
+ ROM_REGION( 0x2000, "samples", 0 ) /* samples */
+ ROM_LOAD( "cc7.cpu", 0x0000, 0x1000, CRC(5f0bcdfb) SHA1(7f79bf6de117348f606696ed7ea1937bbf926612) )
+ ROM_LOAD( "cc6.cpu", 0x1000, 0x1000, CRC(9003ffbd) SHA1(fd016056aabc23957643f37230f03842294f795e) )
+
+ ROM_REGION( 0x0060, "proms", 0 ) // NOT verified on this board
+ ROM_LOAD( "cclimber.pr1", 0x0000, 0x0020, CRC(751c3325) SHA1(edce2bc883996c1d72dc6c1c9f62799b162d415a) )
+ ROM_LOAD( "cclimber.pr2", 0x0020, 0x0020, CRC(ab1940fa) SHA1(8d98e05cbaa6f55770c12e0a9a8ed9c73cc54423) )
+ ROM_LOAD( "cclimber.pr3", 0x0040, 0x0020, CRC(71317756) SHA1(1195f0a037e379cc1a3c0314cb746f5cd2bffe50) )
+ROM_END
/* Sets below are Crazy Kong Part II and have an extra screen in attract mode, showing a caged Kong and copyright */
@@ -2516,6 +2547,7 @@ GAME( 1980, ccboot, cclimber, cclimberx, cclimber, cclimber_state, cclimber
GAME( 1980, ccboot2, cclimber, cclimberx, cclimber, cclimber_state, cclimberj,ROT0, "bootleg", "Crazy Climber (bootleg set 2)", MACHINE_SUPPORTS_SAVE )
GAME( 1980, ccbootmr, cclimber, cclimberx, cclimber, cclimber_state, cclimberj,ROT0, "bootleg (Model Racing)", "Crazy Climber (Model Racing bootleg)", MACHINE_SUPPORTS_SAVE )
GAME( 1980, cclimbroper, cclimber, cclimber, cclimber, driver_device, 0, ROT0, "bootleg (Operamatic)", "Crazy Climber (Spanish, Operamatic bootleg)", MACHINE_SUPPORTS_SAVE )
+GAME( 1980, cclimbrrod, cclimber, cclimber, cclimber, driver_device, 0, ROT0, "bootleg (Rodmar)", "Crazy Climber (Spanish, Rodmar bootleg)", MACHINE_SUPPORTS_SAVE )
/* these sets have ugly colours, no extra attract screen, and no graphics for the extra attract screen in the BG roms
- there is a Falcon logo in the text roms which is unused
diff --git a/src/mame/drivers/fruitpc.cpp b/src/mame/drivers/fruitpc.cpp
index ce459586a45..20e206b4637 100644
--- a/src/mame/drivers/fruitpc.cpp
+++ b/src/mame/drivers/fruitpc.cpp
@@ -38,10 +38,7 @@ public:
required_ioport m_inp3;
required_ioport m_inp4;
- DECLARE_DRIVER_INIT(fruitpc);
DECLARE_READ8_MEMBER(fruit_inp_r);
- virtual void machine_start() override;
- virtual void machine_reset() override;
};
READ8_MEMBER(fruitpc_state::fruit_inp_r)
@@ -80,10 +77,6 @@ static ADDRESS_MAP_START( fruitpc_io, AS_IO, 32, fruitpc_state )
AM_RANGE(0x03f0, 0x03f7) AM_DEVREADWRITE16("ide", ide_controller_device, read_cs1, write_cs1, 0xffffffff)
ADDRESS_MAP_END
-#define AT_KEYB_HELPER(bit, text, key1) \
- PORT_BIT( bit, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME(text) PORT_CODE(key1)
-
-
static INPUT_PORTS_START( fruitpc )
PORT_START("INP1")
PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_COIN1 )
@@ -109,14 +102,6 @@ static INPUT_PORTS_START( fruitpc )
PORT_BIT( 0x00ff, IP_ACTIVE_LOW, IPT_UNKNOWN )
INPUT_PORTS_END
-void fruitpc_state::machine_start()
-{
-}
-
-void fruitpc_state::machine_reset()
-{
-}
-
static MACHINE_CONFIG_START( fruitpc, fruitpc_state )
MCFG_CPU_ADD("maincpu", I486, 66000000) // ST STPCD0166BTC3 66 MHz 486 CPU
MCFG_CPU_PROGRAM_MAP(fruitpc_map)
@@ -135,10 +120,6 @@ static MACHINE_CONFIG_START( fruitpc, fruitpc_state )
MCFG_SPEAKER_STANDARD_STEREO("lspeaker","rspeaker")
MACHINE_CONFIG_END
-DRIVER_INIT_MEMBER(fruitpc_state,fruitpc)
-{
-}
-
ROM_START( fruitpc )
ROM_REGION( 0x20000, "bios", 0 )
ROM_LOAD( "at-gs001.bin", 0x000000, 0x020000, CRC(7dec34d0) SHA1(81d194d67fef9f6531bd3cd1ee0baacb5c2558bf) )
@@ -147,7 +128,7 @@ ROM_START( fruitpc )
DISK_IMAGE( "fruit", 0,SHA1(df250ff06a97fa141a4144034f7035ac2947c53c) )
ROM_END
-GAME( 2006, fruitpc, 0, fruitpc, fruitpc, fruitpc_state, fruitpc, ROT0, "<unknown>", "Fruit Land", MACHINE_NO_SOUND|MACHINE_IMPERFECT_GRAPHICS )
+GAME( 2006, fruitpc, 0, fruitpc, fruitpc, driver_device, 0, ROT0, "<unknown>", "Fruit Land", MACHINE_NO_SOUND|MACHINE_IMPERFECT_GRAPHICS )
// this doesn't really belong here, but is some kind of x86 pc-like hardware, exact CPU type etc. unknown
// hardware ia by Paokai, motherboard has logos, large chip with logo too, http://www.paokai.com.tw/
@@ -159,4 +140,4 @@ ROM_START( gogostrk )
DISK_IMAGE( "ggs-5-2-07", 0,SHA1(f214fd39ec8ac02f008823f4b179ea6c6835e1b8) )
ROM_END
-GAME( 2007, gogostrk, 0, fruitpc, fruitpc, fruitpc_state, fruitpc, ROT0, "American Alpha / Paokai", "Go Go Strike", MACHINE_NOT_WORKING ) // motherboard is dated 2006, if the CF card string is a date it's 2007
+GAME( 2007, gogostrk, 0, fruitpc, fruitpc, driver_device, 0, ROT0, "American Alpha / Paokai", "Go Go Strike", MACHINE_NOT_WORKING ) // motherboard is dated 2006, if the CF card string is a date it's 2007
diff --git a/src/mame/drivers/gba.cpp b/src/mame/drivers/gba.cpp
index abaea79d40d..f2c05930332 100644
--- a/src/mame/drivers/gba.cpp
+++ b/src/mame/drivers/gba.cpp
@@ -35,8 +35,6 @@ static inline void ATTR_PRINTF(3,4) verboselog(device_t &device, int n_level, co
}
}
-#define GBA_ATTOTIME_NORMALIZE(a) a.normalize()
-
static const UINT32 timer_clks[4] = { 16777216, 16777216/64, 16777216/256, 16777216/1024 };
@@ -343,7 +341,6 @@ TIMER_CALLBACK_MEMBER(gba_state::timer_expire)
final = clocksel / rate;
m_timer_hz[tmr] = final;
time = attotime::from_hz(final);
- GBA_ATTOTIME_NORMALIZE(time);
m_tmr_timer[tmr]->adjust(time, tmr, time);
}
@@ -1639,7 +1636,6 @@ WRITE32_MEMBER(gba_state::gba_io_w)
if( !(data & 0x40000) ) // if we're not in Count-Up mode
{
attotime time = attotime::from_hz(final);
- GBA_ATTOTIME_NORMALIZE(time);
m_tmr_timer[offset]->adjust(time, offset, time);
}
}
diff --git a/src/mame/drivers/goldstar.cpp b/src/mame/drivers/goldstar.cpp
index ffb6089d3b4..21bc196b663 100644
--- a/src/mame/drivers/goldstar.cpp
+++ b/src/mame/drivers/goldstar.cpp
@@ -97,6 +97,25 @@
as NOT_WORKING till can figure out how can switch between games.
+ * Cherry Master '99 (V9B.00)
+
+ Inputs are hooked up as DIP switches for testing purposes. You can access
+ some kind of palette test by momentarily flipping input 2-8 to On position.
+ You can access the input port test by flipping input 2-7 to On position while
+ the game boots (like other Cherry Master games). All inputs are hooked up
+ correctly.
+
+ When not in the input test, the game appears to be stuck in a loop resetting
+ itself after initialising NVRAM.
+
+
+ * Cherry Master '99 (V9B.00 bootleg / hack)
+
+ Appears to be a bootleg/hack of the other Dyna set - NVRAM initialisation has
+ been changed from "DYNA QL-1 V9B.00" to " QQ-1 V9B.0", very few other
+ program ROM changes besides hacking out the Dyna name everywhere.
+
+
* Kkoj Noli
kkuj nol-i / kkoj noli (better romanization).
@@ -186,7 +205,7 @@
* Bingo (Wing)
It has a different machine driver to support the different pos of gfx
- layers. I strogly suspect there is a register to adjust the layer position.
+ layers. I strogly suspect there is a register to adjust the layer position.
***************************************************************************/
@@ -700,7 +719,6 @@ static ADDRESS_MAP_START( cm_map, AS_PROGRAM, 8, goldstar_state )
AM_RANGE(0xd000, 0xd7ff) AM_RAM AM_SHARE("nvram")
AM_RANGE(0xd800, 0xdfff) AM_RAM
-
AM_RANGE(0xe000, 0xe7ff) AM_RAM_WRITE(goldstar_fg_vidram_w) AM_SHARE("fg_vidram")
AM_RANGE(0xe800, 0xefff) AM_RAM_WRITE(goldstar_fg_atrram_w) AM_SHARE("fg_atrram")
@@ -1943,6 +1961,213 @@ static INPUT_PORTS_START( cmast91 )
INPUT_PORTS_END
+static INPUT_PORTS_START( cmast99 )
+ PORT_START("IN0") // called "PLAYER" in input test
+ PORT_DIPNAME( 0x01, 0x01, "0-1" )
+ PORT_DIPSETTING( 0x01, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x02, 0x02, "0-2" )
+ PORT_DIPSETTING( 0x02, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x04, 0x04, "0-3" )
+ PORT_DIPSETTING( 0x04, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x08, 0x08, "0-4" )
+ PORT_DIPSETTING( 0x08, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x10, 0x10, "0-5" )
+ PORT_DIPSETTING( 0x10, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x20, 0x20, "0-6" )
+ PORT_DIPSETTING( 0x20, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x40, 0x40, "0-7" )
+ PORT_DIPSETTING( 0x40, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x80, 0x80, "0-8" )
+ PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+
+ PORT_START("IN1") // called "COIN" in input test
+ PORT_DIPNAME( 0x01, 0x01, "1-1" )
+ PORT_DIPSETTING( 0x01, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x02, 0x02, "1-2" )
+ PORT_DIPSETTING( 0x02, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x04, 0x04, "1-3" )
+ PORT_DIPSETTING( 0x04, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x08, 0x08, "1-4" )
+ PORT_DIPSETTING( 0x08, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x10, 0x10, "1-5" )
+ PORT_DIPSETTING( 0x10, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x20, 0x20, "1-6" )
+ PORT_DIPSETTING( 0x20, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x40, 0x40, "1-7" )
+ PORT_DIPSETTING( 0x40, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x80, 0x80, "1-8" )
+ PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+
+
+ PORT_START("IN2") // called "TEST" in input test
+ PORT_DIPNAME( 0x01, 0x01, "2-1" )
+ PORT_DIPSETTING( 0x01, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x02, 0x02, "2-2" )
+ PORT_DIPSETTING( 0x02, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x04, 0x04, "2-3" )
+ PORT_DIPSETTING( 0x04, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x08, 0x08, "2-4" )
+ PORT_DIPSETTING( 0x08, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x10, 0x10, "2-5" )
+ PORT_DIPSETTING( 0x10, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x20, 0x20, "2-6" )
+ PORT_DIPSETTING( 0x20, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x40, 0x40, "2-7" )
+ PORT_DIPSETTING( 0x40, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x80, 0x80, "2-8" )
+ PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+
+ PORT_START("DSW1")
+ PORT_DIPNAME( 0x03, 0x03, "Game Min Bet" ) PORT_DIPLOCATION("DSW1:1,2")
+ PORT_DIPSETTING( 0x03, "15" )
+ PORT_DIPSETTING( 0x02, "30" )
+ PORT_DIPSETTING( 0x01, "45" )
+ PORT_DIPSETTING( 0x00, "60" )
+ PORT_DIPNAME( 0x04, 0x04, "Double Mode" ) PORT_DIPLOCATION("DSW1:3")
+ PORT_DIPSETTING( 0x00, "No (collect)" )
+ PORT_DIPSETTING( 0x04, "Yes (double)" )
+ PORT_DIPNAME( 0x18, 0x18, "Max Bet" ) PORT_DIPLOCATION("DSW1:4,5")
+ PORT_DIPSETTING( 0x00, "15" )
+ PORT_DIPSETTING( 0x08, "30" )
+ PORT_DIPSETTING( 0x10, "60" )
+ PORT_DIPSETTING( 0x18, "99" )
+ PORT_DIPNAME( 0x20, 0x20, "Double Picture" ) PORT_DIPLOCATION("DSW1:6")
+ PORT_DIPSETTING( 0x20, "Fruit" )
+ PORT_DIPSETTING( 0x00, "???" ) // not listed in manual
+ PORT_DIPNAME( 0x40, 0x40, "Payout Rate" ) PORT_DIPLOCATION("DSW1:7")
+ PORT_DIPSETTING( 0x00, "1" )
+ PORT_DIPSETTING( 0x40, "100" )
+ PORT_DIPNAME( 0x80, 0x80, DEF_STR( Unknown ) ) PORT_DIPLOCATION("DSW1:8") // not listed in manual
+ PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+
+ PORT_START("DSW2")
+ PORT_DIPNAME( 0x07, 0x06, "Main Game Pay Rate" ) PORT_DIPLOCATION("DSW2:1,2,3")
+ PORT_DIPSETTING( 0x00, "55%" )
+ PORT_DIPSETTING( 0x01, "60%" )
+ PORT_DIPSETTING( 0x02, "65%" )
+ PORT_DIPSETTING( 0x03, "70%" )
+ PORT_DIPSETTING( 0x04, "75%" )
+ PORT_DIPSETTING( 0x05, "80%" )
+ PORT_DIPSETTING( 0x06, "85%" )
+ PORT_DIPSETTING( 0x07, "90%" )
+ PORT_DIPNAME( 0x08, 0x08, "Double Up Game Pay Rate" ) PORT_DIPLOCATION("DSW2:4")
+ PORT_DIPSETTING( 0x00, "60%" )
+ PORT_DIPSETTING( 0x08, "70%" )
+ PORT_DIPNAME( 0x30, 0x20, "Coin In Rate" ) PORT_DIPLOCATION("DSW2:5,6")
+ PORT_DIPSETTING( 0x30, DEF_STR( 1C_5C ) )
+ PORT_DIPSETTING( 0x20, "1 Coin/10 Credits" )
+ PORT_DIPSETTING( 0x10, "1 Coin/25 Credits" )
+ PORT_DIPSETTING( 0x00, "1 Coin/50 Credits" )
+ PORT_DIPNAME( 0xc0, 0xc0, "Key In Rate" ) PORT_DIPLOCATION("DSW2:7,8")
+ PORT_DIPSETTING( 0xc0, "1 Coin/100 Credits" )
+ PORT_DIPSETTING( 0x80, "1 Coin/110 Credits" )
+ PORT_DIPSETTING( 0x40, "1 Coin/120 Credits" )
+ PORT_DIPSETTING( 0x00, "1 Coin/500 Credits" )
+
+ PORT_START("DSW3") // manual doesn't have explicit defaults, so taking first listed setting for each switch as default
+ PORT_DIPNAME( 0x01, 0x00, "Bonus 2 Poll Mode" ) PORT_DIPLOCATION("DSW3:1")
+ PORT_DIPSETTING( 0x00, DEF_STR( Easy ) )
+ PORT_DIPSETTING( 0x01, DEF_STR( Hard ) )
+ PORT_DIPNAME( 0x02, 0x00, "Bonus 3 Poll Mode" ) PORT_DIPLOCATION("DSW3:2")
+ PORT_DIPSETTING( 0x00, DEF_STR( Easy ) )
+ PORT_DIPSETTING( 0x02, DEF_STR( Hard ) )
+ PORT_DIPNAME( 0x04, 0x04, "???" ) PORT_DIPLOCATION("DSW3:3") // no name given in manual, but settings listed
+ PORT_DIPSETTING( 0x04, "30-40-50" )
+ PORT_DIPSETTING( 0x00, "40-55-70" )
+ PORT_DIPNAME( 0x08, 0x08, "When Watermelon Appear in Center Credit of Bonus Up Mode" ) PORT_DIPLOCATION("DSW3:4")
+ PORT_DIPSETTING( 0x08, "1-3-5" )
+ PORT_DIPSETTING( 0x00, "2-4-6" )
+ PORT_DIPNAME( 0x10, 0x10, "When Bet, Credit of Bonus Up Mode" ) PORT_DIPLOCATION("DSW3:5")
+ PORT_DIPSETTING( 0x10, "1-3-5" )
+ PORT_DIPSETTING( 0x00, "2-4-6" )
+ PORT_DIPNAME( 0x20, 0x20, "The Max Credit of Bonus 1-3" ) PORT_DIPLOCATION("DSW3:6")
+ PORT_DIPSETTING( 0x20, "999-1999-3999" )
+ PORT_DIPSETTING( 0x00, "2000-3000-4500" )
+ PORT_DIPNAME( 0x40, 0x40, "Start Up Credit of Bonus 1-3" ) PORT_DIPLOCATION("DSW3:7")
+ PORT_DIPSETTING( 0x00, "330-660-990" )
+ PORT_DIPSETTING( 0x40, "499-999-1999" )
+ PORT_DIPNAME( 0x80, 0x80, "Start Up Credit of Extra Bonus" ) PORT_DIPLOCATION("DSW3:8")
+ PORT_DIPSETTING( 0x80, "330" )
+ PORT_DIPSETTING( 0x00, "550" )
+
+ PORT_START("DSW4")
+ PORT_DIPNAME( 0x07, 0x00, "Max Pay Credit Limit" ) PORT_DIPLOCATION("DSW4:1,2,3")
+ PORT_DIPSETTING( 0x07, "5,000" )
+ PORT_DIPSETTING( 0x06, "10,000" )
+ PORT_DIPSETTING( 0x05, "15,000" )
+ PORT_DIPSETTING( 0x04, "20,000" )
+ PORT_DIPSETTING( 0x03, "30,000" )
+ PORT_DIPSETTING( 0x02, "40,000" )
+ PORT_DIPSETTING( 0x01, "50,000" )
+ PORT_DIPSETTING( 0x00, "100,000" )
+ PORT_DIPNAME( 0x08, 0x08, "Display Credit Limit" ) PORT_DIPLOCATION("DSW4:4")
+ PORT_DIPSETTING( 0x08, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x10, 0x10, "Add On Bonus Poll" ) PORT_DIPLOCATION("DSW4:5")
+ PORT_DIPSETTING( 0x00, "6-3-1" )
+ PORT_DIPSETTING( 0x10, "9-5-1" )
+ PORT_DIPNAME( 0x20, 0x20, "Add On Bonus Min Bet" ) PORT_DIPLOCATION("DSW4:6")
+ PORT_DIPSETTING( 0x20, "16" )
+ PORT_DIPSETTING( 0x00, "32" )
+ PORT_DIPNAME( 0x40, 0x40, "Game Speed" ) PORT_DIPLOCATION("DSW4:7")
+ PORT_DIPSETTING( 0x40, DEF_STR( Normal ) )
+ PORT_DIPSETTING( 0x00, "Fast" )
+ PORT_DIPNAME( 0x80, 0x80, "Alarm Sound" ) PORT_DIPLOCATION("DSW4:8")
+ PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x80, DEF_STR( On ) )
+
+ PORT_START("DSW5")
+ PORT_DIPNAME( 0x03, 0x03, "Key In Limit" ) PORT_DIPLOCATION("DSW5:1,2")
+ PORT_DIPSETTING( 0x00, "1,000" )
+ PORT_DIPSETTING( 0x01, "5,000" )
+ PORT_DIPSETTING( 0x02, "10,000" )
+ PORT_DIPSETTING( 0x03, "20,000" )
+ PORT_DIPNAME( 0x04, 0x04, "Bonus Girl" ) PORT_DIPLOCATION("DSW5:3")
+ PORT_DIPSETTING( 0x04, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x38, 0x38, "Credit Earned, Profit Table Set Zero" ) PORT_DIPLOCATION("DSW5:4,5,6")
+ PORT_DIPSETTING( 0x00, "20,000" )
+ PORT_DIPSETTING( 0x08, "30,000" )
+ PORT_DIPSETTING( 0x10, "40,000" )
+ PORT_DIPSETTING( 0x18, "50,000" )
+ PORT_DIPSETTING( 0x20, "70,000" )
+ PORT_DIPSETTING( 0x28, "100,000" )
+ PORT_DIPSETTING( 0x30, "200,000" )
+ PORT_DIPSETTING( 0x38, "990,000" )
+ PORT_DIPNAME( 0x40, 0x00, "Bonus 2 Poll Rate" ) PORT_DIPLOCATION("DSW5:7")
+ PORT_DIPSETTING( 0x00, DEF_STR( Normal ) )
+ PORT_DIPSETTING( 0x40, DEF_STR( Hard ) )
+ PORT_DIPNAME( 0x80, 0x00, "Bonus 3 Poll Rate" ) PORT_DIPLOCATION("DSW5:8")
+ PORT_DIPSETTING( 0x00, DEF_STR( Normal ) )
+ PORT_DIPSETTING( 0x80, DEF_STR( Hard ) )
+INPUT_PORTS_END
+
+
static INPUT_PORTS_START( goldstar )
PORT_START("IN0")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN ) // appear in the input test but seems to lack function
@@ -7446,7 +7671,7 @@ static MACHINE_CONFIG_START( cmast91, goldstar_state )
MCFG_CPU_ADD("maincpu", Z80, CPU_CLOCK)
MCFG_CPU_PROGRAM_MAP(cm_map)
MCFG_CPU_IO_MAP(cmast91_portmap)
- MCFG_CPU_VBLANK_INT_DRIVER("screen", goldstar_state, irq0_line_hold)
+ MCFG_CPU_VBLANK_INT_DRIVER("screen", goldstar_state, irq0_line_hold)
MCFG_DEVICE_ADD("ppi8255_0", I8255A, 0)
MCFG_I8255_IN_PORTA_CB(IOPORT("IN0"))
@@ -7469,10 +7694,10 @@ static MACHINE_CONFIG_START( cmast91, goldstar_state )
MCFG_GFXDECODE_ADD("gfxdecode", "palette", cmast91)
MCFG_PALETTE_ADD("palette", 256)
- MCFG_PALETTE_INIT_OWNER(goldstar_state,cmast91)
+ MCFG_PALETTE_INIT_OWNER(goldstar_state, cmast91)
MCFG_NVRAM_ADD_1FILL("nvram")
- MCFG_VIDEO_START_OVERRIDE(goldstar_state,cherrym)
+ MCFG_VIDEO_START_OVERRIDE(goldstar_state, cherrym)
/* sound hardware */
MCFG_SPEAKER_STANDARD_MONO("mono")
@@ -7483,6 +7708,7 @@ static MACHINE_CONFIG_START( cmast91, goldstar_state )
MACHINE_CONFIG_END
+
INTERRUPT_GEN_MEMBER(wingco_state::masked_irq)
{
if (m_nmi_enable)
@@ -8103,21 +8329,21 @@ MACHINE_CONFIG_END
EPROM:
- Name: 1
- File: gs1.bin
- Type: TMS JL 27C010A-12 LX78AC96P
-
- Name: 2
- File: gs2.bin
- Type: TMS JL 27C010A-10 LX73A5J4P
-
- Nome: 3
- File: gs3.bin
- Type: TMS JL 29C010A-12 LX78AC96P
-
- Nome: 4
- File: gs4.bin
- Type: TMS JL 27C010A-10 LX73A5J4P
+ Name: 1
+ File: gs1.bin
+ Type: TMS JL 27C010A-12 LX78AC96P
+
+ Name: 2
+ File: gs2.bin
+ Type: TMS JL 27C010A-10 LX73A5J4P
+
+ Nome: 3
+ File: gs3.bin
+ Type: TMS JL 29C010A-12 LX78AC96P
+
+ Nome: 4
+ File: gs4.bin
+ Type: TMS JL 27C010A-10 LX73A5J4P
Other IC's on MB
@@ -9429,20 +9655,15 @@ ROM_END
ROM_START( cmast99 )
ROM_REGION( 0x10000, "maincpu", 0 )
- ROM_LOAD( "cm99-041-8.u81", 0x0000, 0x1000, CRC(e0872d9f) SHA1(6d8f5e09e5c9daf834d5c74434eae86e5dd7e194) )
+ ROM_LOAD( "cm99-041-8.u81", 0x0000, 0x1000, CRC(5fb0800e) SHA1(14d316b7b89340c5b5c9fdd0b43d5810513b74d6) )
ROM_CONTINUE(0x4000,0x1000)
ROM_CONTINUE(0x3000,0x1000)
ROM_CONTINUE(0x7000,0x1000)
ROM_CONTINUE(0x1000,0x1000)
- ROM_CONTINUE(0x6000,0x1000) /* maybe wrong */
+ ROM_CONTINUE(0x6000,0x1000)
ROM_CONTINUE(0x2000,0x1000)
- ROM_CONTINUE(0x5000,0x1000) /* maybe wrong */
- ROM_CONTINUE(0x8000,0x1000)
- ROM_CONTINUE(0x9000,0x1000) /* maybe wrong */
- ROM_CONTINUE(0xa000,0x1000) /* maybe wrong */
- ROM_CONTINUE(0xb000,0x1000) /* maybe wrong */
- ROM_CONTINUE(0xc000,0x1000) /* maybe wrong */
- ROM_CONTINUE(0xd000,0x3000) /* padding that isn't visible to CPU (RAM mapped here) */
+ ROM_CONTINUE(0x5000,0x1000)
+ ROM_CONTINUE(0x8000,0x8000)
ROM_REGION( 0x18000, "gfx1", 0 )
ROM_LOAD( "cm99-041-7.u16", 0x00000, 0x8000, CRC(69e2aef2) SHA1(195faec239734650dcd777d55a8da84e3a0ed50c) )
@@ -9458,7 +9679,43 @@ ROM_START( cmast99 )
ROM_REGION( 0x10000, "user1", 0 )
ROM_FILL( 0x0000, 0x10000, 0xff ) // U53 (girl bitmaps) not populated
- /* proms taken from cmv4, probably wrong */
+ /* proms taken from cmv4, probably wrong; U79? and U84 known to be identical to Cherry Master 89 */
+ ROM_REGION( 0x200, "proms", 0 )
+ ROM_LOAD( "82s129.u84", 0x0000, 0x0100, CRC(0489b760) SHA1(78f8632b17a76335183c5c204cdec856988368b0) BAD_DUMP )
+ ROM_LOAD( "82s129.u70", 0x0100, 0x0100, CRC(21eb5b19) SHA1(9b8425bdb97f11f4855c998c7792c3291fd07470) BAD_DUMP )
+
+ ROM_REGION( 0x100, "proms2", 0 )
+ ROM_LOAD( "82s129.u46", 0x0000, 0x0100, CRC(50ec383b) SHA1(ae95b92bd3946b40134bcdc22708d5c6b0f4c23e) BAD_DUMP )
+ROM_END
+
+
+ROM_START( cmast99b )
+ ROM_REGION( 0x10000, "maincpu", 0 )
+ ROM_LOAD( "cm99b-041-8.u81", 0x0000, 0x1000, CRC(e0872d9f) SHA1(6d8f5e09e5c9daf834d5c74434eae86e5dd7e194) )
+ ROM_CONTINUE(0x4000,0x1000)
+ ROM_CONTINUE(0x3000,0x1000)
+ ROM_CONTINUE(0x7000,0x1000)
+ ROM_CONTINUE(0x1000,0x1000)
+ ROM_CONTINUE(0x6000,0x1000)
+ ROM_CONTINUE(0x2000,0x1000)
+ ROM_CONTINUE(0x5000,0x1000)
+ ROM_CONTINUE(0x8000,0x8000)
+
+ ROM_REGION( 0x18000, "gfx1", 0 )
+ ROM_LOAD( "cm99-041-7.u16", 0x00000, 0x8000, CRC(69e2aef2) SHA1(195faec239734650dcd777d55a8da84e3a0ed50c) )
+ ROM_LOAD( "cm99-041-6.u11", 0x08000, 0x8000, CRC(900f36f5) SHA1(0fd41f8c8cb2f7940b653a1fad93df2e3f28a34b) )
+ ROM_LOAD( "cm99-041-5.u4", 0x10000, 0x8000, CRC(3e465e38) SHA1(847dc27e45d495cb924b3fd5ce8e68a1cb83ffc8) )
+
+ ROM_REGION( 0x8000, "gfx2", 0 )
+ ROM_LOAD( "cm99-041-4.u15", 0x0000, 0x2000, CRC(6b870b29) SHA1(d65f24817d9d45c148cb857439b46e9e75dabfe7) )
+ ROM_LOAD( "cm99-041-3.u10", 0x2000, 0x2000, CRC(8a0b205f) SHA1(3afea0464b793526bf23610cac6736a31edc7ec2) )
+ ROM_LOAD( "cm99-041-2.u14", 0x4000, 0x2000, CRC(c84dba45) SHA1(ab4ac891a23d6b9a216df046d516e868c77e8a36) )
+ ROM_LOAD( "cm99-041-1.u9", 0x6000, 0x2000, CRC(44046c31) SHA1(c9703ce2371cf86bc597e5fdb9c0d4dd6d91f7dc) )
+
+ ROM_REGION( 0x10000, "user1", 0 )
+ ROM_FILL( 0x0000, 0x10000, 0xff ) // U53 (girl bitmaps) not populated
+
+ /* proms taken from cmv4, probably wrong; U79? and U84 known to be identical to Cherry Master 89 */
ROM_REGION( 0x200, "proms", 0 )
ROM_LOAD( "82s129.u84", 0x0000, 0x0100, CRC(0489b760) SHA1(78f8632b17a76335183c5c204cdec856988368b0) BAD_DUMP )
ROM_LOAD( "82s129.u70", 0x0100, 0x0100, CRC(21eb5b19) SHA1(9b8425bdb97f11f4855c998c7792c3291fd07470) BAD_DUMP )
@@ -10218,9 +10475,9 @@ ROM_END
/* Lucky Bar
Unknown reels game based on Wing's Lucky 8 Lines.
- W-4 hardware
+ W-4 hardware
- Daughterboard with Z80 + program ROM + MC68705P3S MCU at location ic4 (14b)
+ Daughterboard with Z80 + program ROM + MC68705P3S MCU at location ic4 (14b)
Game seems to be meant for progressive modes...
*/
@@ -10257,11 +10514,11 @@ ROM_END
/* Cherry Angel
(W-4 / CB3 hardware)
- Daughterboard with Z80 + program ROM + TTL at location ic4 (14b)
+ Daughterboard with Z80 + program ROM + TTL at location ic4 (14b)
- Encryption pattern:
- For each 0x100 block:
- 00-7f : 22 2a 82 2a...
+ Encryption pattern:
+ For each 0x100 block:
+ 00-7f : 22 2a 82 2a...
80-ff : a8 88 28 88...
*/
ROM_START( chryangla )
@@ -13886,7 +14143,6 @@ GAMEL( 1991, cmastere, cmaster, cm, cmasterb, cmaster_state, cmv4,
GAMEL( 1991, cmasterf, cmaster, cm, cmasterb, cmaster_state, cmv4, ROT0, "Dyna", "Cherry Master I (ver.1.01, set 7)", 0, layout_cmasterb )
GAMEL( 1991, cmasterg, cmaster, cm, cmasterg, cmaster_state, cmv4, ROT0, "Dyna", "Cherry Master I (ver.1.01, set 8, V4-B-)", 0, layout_cmasterb )
GAMEL( 1991, cmasterh, cmaster, cm, cmasterb, cmaster_state, cmv4, ROT0, "Dyna", "Cherry Master I (ver.1.10)", 0, layout_cmasterb )
-GAME( 199?, cmast99, 0, cm, cmv4, cmaster_state, cmv4, ROT0, "????", "Cherry Master '99", MACHINE_NOT_WORKING )
GAMEL( 1991, tonypok, 0, cm, tonypok, cmaster_state, tonypok, ROT0, "Corsica", "Poker Master (Tony-Poker V3.A, hack?)", 0 , layout_tonypok )
@@ -13897,6 +14153,8 @@ GAME( 1993, pkrmasta, jkrmast, pkrmast, pkrmast, driver_device, 0,
GAME( 1991, cmast91, 0, cmast91, cmast91, goldstar_state, cmast91, ROT0, "Dyna", "Cherry Master '91 (ver.1.30)", 0 )
GAME( 1992, cmast92, 0, cmast91, cmast91, goldstar_state, cmast91, ROT0, "Dyna", "Cherry Master '92", MACHINE_NOT_WORKING ) // no gfx roms are dumped
+GAME( 1999, cmast99, 0, cm, cmast99, cmaster_state, cmv4, ROT0, "Dyna", "Cherry Master '99 (V9B.00)", MACHINE_NOT_WORKING )
+GAME( 1999, cmast99b, cmast99, cm, cmast99, cmaster_state, cmv4, ROT0, "bootleg", "Cherry Master '99 (V9B.00 bootleg / hack)", MACHINE_NOT_WORKING )
// --- Wing W-4 hardware ---
diff --git a/src/mame/drivers/hh_cop400.cpp b/src/mame/drivers/hh_cop400.cpp
index 38f833668fe..160661d2f6d 100644
--- a/src/mame/drivers/hh_cop400.cpp
+++ b/src/mame/drivers/hh_cop400.cpp
@@ -281,7 +281,7 @@ WRITE8_MEMBER(ctstein_state::write_l)
{
// L0-L3: button lamps (strobed)
display_matrix(4, 1, data & 0xf, 1);
- display_matrix(4, 1, data & 0xf, 0);
+ display_matrix(4, 1, 0, 0);
}
READ8_MEMBER(ctstein_state::read_l)
@@ -396,7 +396,7 @@ WRITE8_MEMBER(h2hbaskb_state::write_l)
// L0-L6: digit segments A-G, L0-L4: led data
// strobe display
display_matrix(7, 16, data, sel);
- display_matrix(7, 16, 0, sel);
+ display_matrix(7, 16, 0, 0);
}
READ8_MEMBER(h2hbaskb_state::read_in)
diff --git a/src/mame/drivers/hh_sm510.cpp b/src/mame/drivers/hh_sm510.cpp
index 13c8b835fc4..beba7c0a259 100644
--- a/src/mame/drivers/hh_sm510.cpp
+++ b/src/mame/drivers/hh_sm510.cpp
@@ -57,7 +57,7 @@ void hh_sm510_state::machine_start()
{
// zerofill
m_inp_mux = 0;
-// m_inp_lines = 0;
+ /* m_inp_lines = 0; */ // not here
memset(m_lcd_output_cache, ~0, sizeof(m_lcd_output_cache));
// register for savestates
@@ -84,16 +84,19 @@ WRITE16_MEMBER(hh_sm510_state::lcd_segment_w)
{
for (int seg = 0; seg < 0x10; seg++)
{
- int state = data >> seg & 1;
int index = offset << 4 | seg;
+ UINT8 state = data >> seg & 1;
if (state != m_lcd_output_cache[index])
{
- // output to x.y, where x = row a/b/bs/c*4 + H1-4, y = seg1-16
+ // output to row.seg.H, where:
+ // row = row a/b/bs/c (0/1/2/3)
+ // seg = seg 1-16 (0-15)
+ // H = H1-H4 (0-3)
char buf[0x10];
- sprintf(buf, "%d.%d", offset, seg);
+ sprintf(buf, "%d.%d.%d", offset >> 2, seg, offset & 3);
output().set_value(buf, state);
-
+
m_lcd_output_cache[index] = state;
}
}
@@ -186,13 +189,13 @@ static INPUT_PORTS_START( ktopgun )
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_CHANGED_MEMBER(DEVICE_SELF, hh_sm510_state, input_changed, NULL)
PORT_START("IN.1")
- PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_CHANGED_MEMBER(DEVICE_SELF, hh_sm510_state, input_changed, NULL) // sel
- PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_CHANGED_MEMBER(DEVICE_SELF, hh_sm510_state, input_changed, NULL) // sound on/off
- PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_CHANGED_MEMBER(DEVICE_SELF, hh_sm510_state, input_changed, NULL) // off
- PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON4 ) PORT_CHANGED_MEMBER(DEVICE_SELF, hh_sm510_state, input_changed, NULL) // fire
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_SELECT ) PORT_CHANGED_MEMBER(DEVICE_SELF, hh_sm510_state, input_changed, NULL)
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_VOLUME_DOWN ) PORT_CHANGED_MEMBER(DEVICE_SELF, hh_sm510_state, input_changed, NULL) PORT_NAME("Sound")
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_POWER_OFF ) PORT_CHANGED_MEMBER(DEVICE_SELF, hh_sm510_state, input_changed, NULL)
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_CHANGED_MEMBER(DEVICE_SELF, hh_sm510_state, input_changed, NULL)
PORT_START("IN.2")
- PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON5 ) PORT_CHANGED_MEMBER(DEVICE_SELF, hh_sm510_state, input_changed, NULL) // on
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_POWER_ON ) PORT_CHANGED_MEMBER(DEVICE_SELF, hh_sm510_state, input_changed, NULL)
PORT_BIT( 0x0e, IP_ACTIVE_HIGH, IPT_UNUSED )
INPUT_PORTS_END
@@ -259,16 +262,16 @@ static INPUT_PORTS_START( ktmnt )
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_CHANGED_MEMBER(DEVICE_SELF, hh_sm510_state, input_changed, NULL)
PORT_START("IN.1")
- PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_CHANGED_MEMBER(DEVICE_SELF, hh_sm510_state, input_changed, NULL) // game select
- PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_CHANGED_MEMBER(DEVICE_SELF, hh_sm510_state, input_changed, NULL) // sound on/off
- PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_CHANGED_MEMBER(DEVICE_SELF, hh_sm510_state, input_changed, NULL) // off
- PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON4 ) PORT_CHANGED_MEMBER(DEVICE_SELF, hh_sm510_state, input_changed, NULL) // on/start
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_SELECT ) PORT_CHANGED_MEMBER(DEVICE_SELF, hh_sm510_state, input_changed, NULL)
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_VOLUME_DOWN ) PORT_CHANGED_MEMBER(DEVICE_SELF, hh_sm510_state, input_changed, NULL) PORT_NAME("Sound")
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_POWER_OFF ) PORT_CHANGED_MEMBER(DEVICE_SELF, hh_sm510_state, input_changed, NULL)
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_POWER_ON ) PORT_CHANGED_MEMBER(DEVICE_SELF, hh_sm510_state, input_changed, NULL)
PORT_START("IN.2")
- PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON5 ) PORT_CHANGED_MEMBER(DEVICE_SELF, hh_sm510_state, input_changed, NULL)
- PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON6 ) PORT_CHANGED_MEMBER(DEVICE_SELF, hh_sm510_state, input_changed, NULL)
- PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON7 ) PORT_CHANGED_MEMBER(DEVICE_SELF, hh_sm510_state, input_changed, NULL)
- PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON8 ) PORT_CHANGED_MEMBER(DEVICE_SELF, hh_sm510_state, input_changed, NULL)
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_CHANGED_MEMBER(DEVICE_SELF, hh_sm510_state, input_changed, NULL)
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_CHANGED_MEMBER(DEVICE_SELF, hh_sm510_state, input_changed, NULL)
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_CHANGED_MEMBER(DEVICE_SELF, hh_sm510_state, input_changed, NULL)
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON4 ) PORT_CHANGED_MEMBER(DEVICE_SELF, hh_sm510_state, input_changed, NULL)
INPUT_PORTS_END
static MACHINE_CONFIG_START( ktmnt, ktmnt_state )
diff --git a/src/mame/drivers/hh_tms1k.cpp b/src/mame/drivers/hh_tms1k.cpp
index e1be21683b7..2d16bdee2af 100644
--- a/src/mame/drivers/hh_tms1k.cpp
+++ b/src/mame/drivers/hh_tms1k.cpp
@@ -25,6 +25,7 @@
*MP0168 TMS1000 1979, Conic Basketball
@MP0170 TMS1000 1979, Conic Football
@MP0914 TMS1000 1979, Entex Baseball 1
+ *MP0919 TMS1000 1979, Tiger Copy Cat (model 7-520)
@MP0923 TMS1000 1979, Entex Baseball 2
@MP1030 TMS1100 1980, APF Mathemagician
@MP1133 TMS1470 1979, Kosmos Astro
@@ -44,6 +45,7 @@
*MP2139 TMS1370? 1982, Gakken Galaxy Invader 1000
@MP2726 TMS1040 1979, Tomy Break Up
*MP2788 TMS1040? 1980, Bandai Flight Time (? note: VFD-capable)
+ *MP3005 TMS1000? 1989, Tiger Copy Cat (model 7-522)
*MP3208 TMS1000 1977, Milton Bradley Electronic Battleship (1977, model 4750A or B)
@MP3226 TMS1000 1978, Milton Bradley Simon (model 4850)
*MP3232 TMS1000 1979, Fonas 2-Player Baseball (no "MP" on chip label)
@@ -122,7 +124,7 @@
#include "bigtrak.lh"
#include "cnfball.lh"
#include "cnfball2.lh"
-#include "cnsector.lh"
+#include "cnsector.lh" // clickable
#include "comp4.lh" // clickable
#include "cqback.lh"
#include "ebball.lh"
@@ -137,7 +139,7 @@
#include "gpoker.lh"
#include "h2hbaseb.lh"
#include "h2hfootb.lh"
-#include "lostreas.lh"
+#include "lostreas.lh" // clickable
#include "mathmagi.lh"
#include "mdndclab.lh" // clickable
#include "merlin.lh" // clickable
@@ -145,8 +147,8 @@
#include "simon.lh" // clickable
#include "ssimon.lh" // clickable
#include "splitsec.lh"
-#include "starwbc.lh"
-#include "stopthie.lh"
+#include "starwbc.lh" // clickable
+#include "stopthie.lh" // clickable
#include "tandy12.lh" // clickable
#include "tbreakup.lh"
#include "tc4.lh"
@@ -4748,7 +4750,7 @@ static INPUT_PORTS_START( lostreas )
PORT_START("IN.2") // O2
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_9) PORT_CODE(KEYCODE_9_PAD) PORT_NAME("9")
- PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_DEL) PORT_NAME("Clear")
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_C) PORT_CODE(KEYCODE_DEL) PORT_NAME("Clear")
PORT_BIT( 0x04, 0x04, IPT_SPECIAL ) PORT_CONDITION("FAKE", 0x03, NOTEQUALS, 0x00) // air/up
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_V) PORT_NAME("$ Value")
@@ -5757,8 +5759,8 @@ COMP( 1983, fxmcr165, 0, 0, fxmcr165, fxmcr165, driver_device, 0, "Gak
CONS( 1979, elecdet, 0, 0, elecdet, elecdet, driver_device, 0, "Ideal", "Electronic Detective", MACHINE_SUPPORTS_SAVE ) // ***
-CONS( 1979, starwbc, 0, 0, starwbc, starwbc, driver_device, 0, "Kenner", "Star Wars - Electronic Battle Command", MACHINE_SUPPORTS_SAVE )
-CONS( 1979, starwbcp, starwbc, 0, starwbc, starwbc, driver_device, 0, "Kenner", "Star Wars - Electronic Battle Command (patent)", MACHINE_SUPPORTS_SAVE )
+CONS( 1979, starwbc, 0, 0, starwbc, starwbc, driver_device, 0, "Kenner", "Star Wars - Electronic Battle Command", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK )
+CONS( 1979, starwbcp, starwbc, 0, starwbc, starwbc, driver_device, 0, "Kenner", "Star Wars - Electronic Battle Command (patent)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK )
COMP( 1979, astro, 0, 0, astro, astro, driver_device, 0, "Kosmos", "Astro", MACHINE_SUPPORTS_SAVE | MACHINE_NO_SOUND_HW )
@@ -5769,14 +5771,14 @@ CONS( 1978, simon, 0, 0, simon, simon, driver_device, 0, "Mil
CONS( 1979, ssimon, 0, 0, ssimon, ssimon, driver_device, 0, "Milton Bradley", "Super Simon", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK )
CONS( 1979, bigtrak, 0, 0, bigtrak, bigtrak, driver_device, 0, "Milton Bradley", "Big Trak", MACHINE_SUPPORTS_SAVE | MACHINE_MECHANICAL ) // ***
-CONS( 1977, cnsector, 0, 0, cnsector, cnsector, driver_device, 0, "Parker Brothers", "Code Name: Sector", MACHINE_SUPPORTS_SAVE | MACHINE_NO_SOUND_HW ) // ***
+CONS( 1977, cnsector, 0, 0, cnsector, cnsector, driver_device, 0, "Parker Brothers", "Code Name: Sector", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_NO_SOUND_HW ) // ***
CONS( 1978, merlin, 0, 0, merlin, merlin, driver_device, 0, "Parker Brothers", "Merlin - The Electronic Wizard", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK )
CONS( 1979, stopthie, 0, 0, stopthief, stopthief, driver_device, 0, "Parker Brothers", "Stop Thief (Electronic Crime Scanner)", MACHINE_SUPPORTS_SAVE ) // ***
CONS( 1979, stopthiep, stopthie, 0, stopthief, stopthief, driver_device, 0, "Parker Brothers", "Stop Thief (Electronic Crime Scanner) (patent)", MACHINE_SUPPORTS_SAVE | MACHINE_NOT_WORKING ) // ***
CONS( 1980, bankshot, 0, 0, bankshot, bankshot, driver_device, 0, "Parker Brothers", "Bank Shot - Electronic Pool", MACHINE_SUPPORTS_SAVE )
CONS( 1980, splitsec, 0, 0, splitsec, splitsec, driver_device, 0, "Parker Brothers", "Split Second", MACHINE_SUPPORTS_SAVE )
CONS( 1982, mmerlin, 0, 0, mmerlin, mmerlin, driver_device, 0, "Parker Brothers", "Master Merlin", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK )
-CONS( 1982, lostreas, 0, 0, lostreas, lostreas, driver_device, 0, "Parker Brothers", "Lost Treasure - The Electronic Deep-Sea Diving Game (Electronic Dive-Control Center)", MACHINE_SUPPORTS_SAVE ) // ***
+CONS( 1982, lostreas, 0, 0, lostreas, lostreas, driver_device, 0, "Parker Brothers", "Lost Treasure - The Electronic Deep-Sea Diving Game (Electronic Dive-Control Center)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK ) // ***
CONS( 1981, tandy12, 0, 0, tandy12, tandy12, driver_device, 0, "Tandy Radio Shack", "Tandy-12: Computerized Arcade", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK ) // some of the minigames: ***
diff --git a/src/mame/drivers/hh_ucom4.cpp b/src/mame/drivers/hh_ucom4.cpp
index bb7d99e82a7..fb866b8b410 100644
--- a/src/mame/drivers/hh_ucom4.cpp
+++ b/src/mame/drivers/hh_ucom4.cpp
@@ -2587,7 +2587,7 @@ CONS( 1980, splasfgt, 0, 0, splasfgt, splasfgt, driver_device, 0, "Bambin
CONS( 1982, bcclimbr, 0, 0, bcclimbr, bcclimbr, driver_device, 0, "Bandai", "Crazy Climber (Bandai)", MACHINE_SUPPORTS_SAVE | MACHINE_REQUIRES_ARTWORK )
-CONS( 1980, tactix, 0, 0, tactix, tactix, driver_device, 0, "Castle Toy", "Tactix (Castle Toy)", MACHINE_SUPPORTS_SAVE )
+CONS( 1980, tactix, 0, 0, tactix, tactix, driver_device, 0, "Castle Toy", "Tactix (Castle Toy)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK )
CONS( 1980, invspace, 0, 0, invspace, invspace, driver_device, 0, "Epoch", "Invader From Space", MACHINE_SUPPORTS_SAVE | MACHINE_REQUIRES_ARTWORK )
CONS( 1980, efball, 0, 0, efball, efball, driver_device, 0, "Epoch", "Electronic Football (Epoch)", MACHINE_SUPPORTS_SAVE )
diff --git a/src/mame/drivers/himesiki.cpp b/src/mame/drivers/himesiki.cpp
index 12f487b3b97..5aab4ee4b4e 100644
--- a/src/mame/drivers/himesiki.cpp
+++ b/src/mame/drivers/himesiki.cpp
@@ -1,13 +1,19 @@
// license:BSD-3-Clause
-// copyright-holders:Uki
+// copyright-holders:Uki, David Haywood
/*****************************************************************************
Himeshikibu (C) 1989 Hi-Soft
+Android (C) 198? Nasco
Driver by Uki
*****************************************************************************/
+// Note, another VERY different version of Android also exists, see https://www.youtube.com/watch?v=5rtqZqMBACI (uploaded by Chris Hardy)
+// it is unclear if that version is on the same hardware as this
+// Android uses PCBS MK-P102 and MK-P101 ONLY, there is no MK-P103 (extra sprites used on Himeshikibu)
+
+
/*
Himeshikibu
(c)1989 Hi-Soft (distributed by Rollertron)
@@ -88,14 +94,19 @@ A 12.000MHz
#include "cpu/z80/z80.h"
#include "sound/2203intf.h"
#include "includes/himesiki.h"
+#include "machine/i8255.h"
-#define MCLK XTAL_12MHz
+#define MCLK XTAL_12MHz // this is on the video board
+#define CLK2 XTAL_8MHz // near the CPUs
WRITE8_MEMBER(himesiki_state::himesiki_rombank_w)
{
- membank("bank1")->set_entry(((data & 0x08) >> 3));
+ membank("bank1")->set_entry(((data & 0x0c) >> 2));
+
+ m_flipscreen = (data & 0x10)>>4;
+ flip_screen_set(m_flipscreen);
- if (data & 0xf7)
+ if (data & 0xe3)
logerror("p06_w %02x\n", data);
}
@@ -110,7 +121,8 @@ WRITE8_MEMBER(himesiki_state::himesiki_sound_w)
static ADDRESS_MAP_START( himesiki_prm0, AS_PROGRAM, 8, himesiki_state )
AM_RANGE(0x0000, 0x7fff) AM_ROM
AM_RANGE(0x8000, 0x9fff) AM_RAM
- AM_RANGE(0xa000, 0xa7ff) AM_RAM AM_SHARE("spriteram")
+ AM_RANGE(0xa000, 0xa0ff) AM_RAM AM_SHARE("spriteram")
+ AM_RANGE(0xa100, 0xa7ff) AM_RAM AM_SHARE("sprram_p103a") // not on Android
AM_RANGE(0xa800, 0xafff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette")
AM_RANGE(0xb000, 0xbfff) AM_RAM_WRITE(himesiki_bg_ram_w) AM_SHARE("bg_ram")
AM_RANGE(0xc000, 0xffff) AM_ROMBANK("bank1")
@@ -118,19 +130,16 @@ ADDRESS_MAP_END
static ADDRESS_MAP_START( himesiki_iom0, AS_IO, 8, himesiki_state )
ADDRESS_MAP_GLOBAL_MASK(0xff)
- AM_RANGE(0x00, 0x00) AM_READ_PORT("1P")
- AM_RANGE(0x01, 0x01) AM_READ_PORT("2P")
- AM_RANGE(0x02, 0x02) AM_READ_PORT("OTHERS")
- AM_RANGE(0x03, 0x03) AM_WRITENOP // 8255 cw
- AM_RANGE(0x04, 0x04) AM_READ_PORT("DSW1")
- AM_RANGE(0x05, 0x05) AM_READ_PORT("DSW2")
- AM_RANGE(0x06, 0x06) AM_WRITE(himesiki_rombank_w)
- AM_RANGE(0x07, 0x07) AM_WRITENOP // 8255 cw
- AM_RANGE(0x08, 0x08) AM_WRITE(himesiki_flip_w)
+ AM_RANGE(0x00, 0x03) AM_DEVREADWRITE("ppi8255_0", i8255_device, read, write) // inputs
+ AM_RANGE(0x04, 0x07) AM_DEVREADWRITE("ppi8255_1", i8255_device, read, write) // dips + rombank
+ AM_RANGE(0x08, 0x08) AM_WRITE(himesiki_scrolly_w)
AM_RANGE(0x09, 0x0a) AM_WRITE(himesiki_scrollx_w)
AM_RANGE(0x0b, 0x0b) AM_WRITE(himesiki_sound_w)
ADDRESS_MAP_END
+
+
+
static ADDRESS_MAP_START( himesiki_prm1, AS_PROGRAM, 8, himesiki_state )
AM_RANGE(0x0000, 0x7fff) AM_ROM
AM_RANGE(0xf800, 0xffff) AM_RAM
@@ -226,9 +235,95 @@ static INPUT_PORTS_START( himesiki )
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
INPUT_PORTS_END
+static INPUT_PORTS_START( androidp )
+ PORT_START("DSW1")
+ PORT_DIPNAME( 0x01, 0x01, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x01, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x02, 0x02, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x02, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x0c, 0x08, DEF_STR( Lives ) )
+ PORT_DIPSETTING( 0x0c, "1" )
+ PORT_DIPSETTING( 0x04, "2" )
+ PORT_DIPSETTING( 0x08, "3" )
+ PORT_DIPSETTING( 0x00, "4" ) // first dragon scene only shows 3?
+ PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x10, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x20, 0x20, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x20, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x40, 0x40, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x40, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x80, 0x80, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+
+ PORT_START("DSW2")
+ PORT_DIPNAME( 0x07, 0x04, DEF_STR( Coinage ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( 6C_1C ) )
+ PORT_DIPSETTING( 0x01, DEF_STR( 5C_1C ) )
+ PORT_DIPSETTING( 0x02, DEF_STR( 4C_1C ) )
+ PORT_DIPSETTING( 0x04, DEF_STR( 1C_1C ) )
+ PORT_DIPSETTING( 0x05, DEF_STR( 1C_2C ) )
+ PORT_DIPSETTING( 0x06, DEF_STR( 1C_3C ) )
+ PORT_DIPSETTING( 0x07, DEF_STR( 1C_4C ) )
+ PORT_DIPSETTING( 0x03, "Invalid" ) // can't coin up or start? (probably a non-functioning freeplay)
+
+ PORT_DIPNAME( 0x08, 0x08, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x08, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x10, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x20, 0x20, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x20, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x40, 0x40, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x40, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x80, 0x80, DEF_STR( Unknown ) )
+ PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+
+ PORT_START("1P")
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP )
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN )
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT )
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT )
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 )
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 )
+ PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON3 )
+ PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
+
+ PORT_START("2P")
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(2)
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(2)
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(2)
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(2)
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2)
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2)
+ PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(2)
+ PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
+
+ PORT_START("OTHERS")
+ PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_COIN1 )
+ PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_SERVICE1 ) // coin?
+ PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_COIN2 ) // service?
+ PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_START1 )
+ PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_START2 )
+ PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
+INPUT_PORTS_END
+
+
+
/****************************************************************************/
-static const gfx_layout layout1 =
+static const gfx_layout layout_bg =
{
8,8,
RGN_FRAC(1,1),
@@ -239,7 +334,7 @@ static const gfx_layout layout1 =
8*8*4
};
-static const gfx_layout layout2 =
+static const gfx_layout layout_p103a =
{
32,32,
RGN_FRAC(1,1),
@@ -250,7 +345,7 @@ static const gfx_layout layout2 =
32*32*4
};
-static const gfx_layout layout3 =
+static const gfx_layout layout_spr =
{
16,16,
RGN_FRAC(1,1),
@@ -262,20 +357,22 @@ static const gfx_layout layout3 =
};
static GFXDECODE_START( himesiki )
- GFXDECODE_ENTRY( "bgtiles", 0, layout1, 0x000, 16 )
- GFXDECODE_ENTRY( "sprites_1", 0, layout2, 0x200, 16 )
- GFXDECODE_ENTRY( "sprites_2", 0, layout3, 0x200, 16 )
+ GFXDECODE_ENTRY( "bgtiles", 0, layout_bg, 0x000, 16 )
+ GFXDECODE_ENTRY( "sprites", 0, layout_spr, 0x200, 16 )
+ GFXDECODE_ENTRY( "spr_p103a", 0, layout_p103a, 0x200, 16 )
GFXDECODE_END
void himesiki_state::machine_start()
{
- UINT8 *ROM = memregion("maincpu")->base();
+ UINT8 *ROM = memregion("banks")->base();
- membank("bank1")->configure_entries(0, 2, &ROM[0x10000], 0x4000);
+ membank("bank1")->configure_entries(0, 4, ROM, 0x4000);
save_item(NAME(m_scrollx));
+ save_item(NAME(m_scrolly));
+
save_item(NAME(m_flipscreen));
}
@@ -283,21 +380,32 @@ void himesiki_state::machine_reset()
{
m_scrollx[0] = 0;
m_scrollx[1] = 0;
+ m_scrolly = 0;
+
m_flipscreen = 0;
}
static MACHINE_CONFIG_START( himesiki, himesiki_state )
/* basic machine hardware */
- MCFG_CPU_ADD("maincpu", Z80, MCLK/2) /* 6.000 MHz */
+ MCFG_CPU_ADD("maincpu", Z80, CLK2) /* it's a 6.000 MHz rated part, but near the 8 Mhz XTAL?? - Android skips lots of frames at 6, crashes at 4 */
MCFG_CPU_PROGRAM_MAP(himesiki_prm0)
MCFG_CPU_IO_MAP(himesiki_iom0)
MCFG_CPU_VBLANK_INT_DRIVER("screen", himesiki_state, irq0_line_hold)
- MCFG_CPU_ADD("sub", Z80, MCLK/3) /* 4.000 MHz */
+ MCFG_CPU_ADD("sub", Z80, CLK2/2) /* 4.000 MHz (4Mhz rated part, near the 8 Mhz XTAL) */
MCFG_CPU_PROGRAM_MAP(himesiki_prm1)
MCFG_CPU_IO_MAP(himesiki_iom1)
+ MCFG_DEVICE_ADD("ppi8255_0", I8255A, 0)
+ MCFG_I8255_IN_PORTA_CB(IOPORT("1P"))
+ MCFG_I8255_IN_PORTB_CB(IOPORT("2P"))
+ MCFG_I8255_IN_PORTC_CB(IOPORT("OTHERS"))
+
+ MCFG_DEVICE_ADD("ppi8255_1", I8255A, 0)
+ MCFG_I8255_IN_PORTA_CB(IOPORT("DSW1"))
+ MCFG_I8255_IN_PORTB_CB(IOPORT("DSW2"))
+ MCFG_I8255_OUT_PORTC_CB(WRITE8(himesiki_state, himesiki_rombank_w))
/* video hardware */
MCFG_SCREEN_ADD("screen", RASTER)
@@ -316,6 +424,7 @@ static MACHINE_CONFIG_START( himesiki, himesiki_state )
/* sound hardware */
MCFG_SPEAKER_STANDARD_MONO("mono")
MCFG_SOUND_ADD("ym2203", YM2203, MCLK/4)
+ MCFG_YM2203_IRQ_HANDLER(INPUTLINE("sub", 0))
MCFG_SOUND_ROUTE(0, "mono", 0.10)
MCFG_SOUND_ROUTE(1, "mono", 0.10)
MCFG_SOUND_ROUTE(2, "mono", 0.10)
@@ -326,9 +435,13 @@ MACHINE_CONFIG_END
/****************************************************************************/
ROM_START( himesiki )
- ROM_REGION( 0x018000, "maincpu", 0 ) /* z80 */
+ ROM_REGION( 0x08000, "maincpu", 0 ) /* z80 */
ROM_LOAD( "1.1k", 0x00000, 0x08000, CRC(fb4604b3) SHA1(e8155bbafb881125e1bf9a04808d6a6546887e90) )
- ROM_LOAD( "2.1g", 0x10000, 0x08000, CRC(0c30ded1) SHA1(0ad67115fa15d0b6261a278a946a6d46c06430ef) )
+
+ ROM_REGION( 0x10000, "banks", 0 )
+ ROM_LOAD( "2.1g", 0x00000, 0x04000, CRC(0c30ded1) SHA1(0ad67115fa15d0b6261a278a946a6d46c06430ef) )
+ ROM_CONTINUE( 0x08000, 0x04000)
+ // 1j is unpopulated on this game
ROM_REGION( 0x010000, "sub", 0 ) /* z80 */
ROM_LOAD( "5.6n", 0x00000, 0x08000, CRC(b1214ac7) SHA1(ee5459c28d9c3c2eb3467261716b1259ec486534) )
@@ -337,7 +450,14 @@ ROM_START( himesiki )
ROM_LOAD( "3.5f", 0x000000, 0x010000, CRC(73843e60) SHA1(0d8a397d8798e15f3fa7bf7a83e4c2ee44f6fa86) )
ROM_LOAD( "4.5d", 0x010000, 0x010000, CRC(443a3164) SHA1(08aa002214251a870581a01d775f497dd390957c) )
- ROM_REGION( 0x060000, "sprites_1", 0 ) /* sprites */
+ ROM_REGION( 0x040000, "sprites", 0 ) /* sprites */
+ ROM_LOAD16_BYTE( "13.9e", 0x000000, 0x010000, CRC(43102682) SHA1(0d4bde8bece0cbc6c06071aa8ad210a0636d862f) )
+ ROM_LOAD16_BYTE( "12.9c", 0x000001, 0x010000, CRC(19c8f9f4) SHA1(b14c8a6b94fd474be375e7a6a03d7f4517da2247) )
+ ROM_LOAD16_BYTE( "15.8e", 0x020000, 0x010000, CRC(2630d394) SHA1(b2e9e836b1f053fce3212912c53d3cdca3372439) )
+ ROM_LOAD16_BYTE( "14.8c", 0x020001, 0x010000, CRC(8103a207) SHA1(0dde8a0aaf2618d9c1589f35841db210439d0388) )
+
+
+ ROM_REGION( 0x060000, "spr_p103a", 0 ) /* sprites */
ROM_LOAD16_BYTE( "6.1a", 0x000000, 0x010000, CRC(14989c22) SHA1(fe0c31df10237294ea8ef0ab8965ba5bb25113a2) )
ROM_LOAD16_BYTE( "7.1c", 0x000001, 0x010000, CRC(cec56e16) SHA1(836ff413301044313fdf7af5d304c145137b898a) )
ROM_LOAD16_BYTE( "8.2a", 0x020000, 0x010000, CRC(44ba127e) SHA1(d756b6c3075d75287f9c8be662c1eab02f4245a3) )
@@ -345,11 +465,38 @@ ROM_START( himesiki )
ROM_LOAD16_BYTE( "10.4a", 0x040000, 0x010000, CRC(0adda8d1) SHA1(dfee2c7921fdc972b4e95fdf89520f74a4e8b4ee) )
ROM_LOAD16_BYTE( "11.4c", 0x040001, 0x010000, CRC(aa032946) SHA1(bd8900e4a22580e3bfe33b8164909db19bb07a8f) )
- ROM_REGION( 0x040000, "sprites_2", 0 ) /* sprites */
- ROM_LOAD16_BYTE( "13.9e", 0x000000, 0x010000, CRC(43102682) SHA1(0d4bde8bece0cbc6c06071aa8ad210a0636d862f) )
- ROM_LOAD16_BYTE( "12.9c", 0x000001, 0x010000, CRC(19c8f9f4) SHA1(b14c8a6b94fd474be375e7a6a03d7f4517da2247) )
- ROM_LOAD16_BYTE( "15.8e", 0x020000, 0x010000, CRC(2630d394) SHA1(b2e9e836b1f053fce3212912c53d3cdca3372439) )
- ROM_LOAD16_BYTE( "14.8c", 0x020001, 0x010000, CRC(8103a207) SHA1(0dde8a0aaf2618d9c1589f35841db210439d0388) )
ROM_END
+
+
+ROM_START( androidp )
+ ROM_REGION( 0x08000, "maincpu", 0 )
+ ROM_LOAD( "MITSUBISHI_A01.toppcb.m5l27256k.k1.BIN", 0x00000, 0x08000, CRC(25ab85eb) SHA1(e1fab149c83ff880b119258206d5818f3db641c5) )
+
+ ROM_REGION( 0x10000, "banks", 0 )
+ ROM_LOAD( "MITSUBISHI_A03.toppcb.m5l27256k.G1.BIN", 0x00000, 0x04000, CRC(6cf5f48a) SHA1(b9b4e5e7bace0e8d98fbc9f4ad91bc56ef42099e) )
+ ROM_CONTINUE( 0x08000, 0x04000)
+ ROM_LOAD( "MITSUBISHI_A02.toppcb.m5l27256k.J1.BIN", 0x04000, 0x04000, CRC(e41426be) SHA1(e7e06ef3ff5160bb7d870e148ba2799da52cf24c) )
+ ROM_CONTINUE( 0x0c000, 0x04000)
+
+ ROM_REGION( 0x18000, "sub", 0 )
+ ROM_LOAD( "MITSUBISHI_A04.toppcb.m5l27256k.N6.BIN", 0x00000, 0x08000, CRC(13c38fe4) SHA1(34a35fa057159a5c83892a88b8c908faa39d5cb3) )
+
+ ROM_REGION( 0x10000, "bgtiles", 0 )
+ ROM_LOAD( "MITSUBISHI_A05.toppcb.m5l27512k.F5.BIN", 0x00000, 0x10000, CRC(4c72a930) SHA1(f1542844391b55fe43293eef7ce48c09b7aca75a) )
+
+ ROM_REGION( 0x20000, "sprites", 0 )
+ ROM_LOAD16_BYTE( "MITSUBISHI_A06.botpcb.m5l27512k.9E.BIN", 0x00000, 0x10000, CRC(5e42984e) SHA1(2a928960c740dfb94589e011cce093bed2fd7685) )
+ ROM_LOAD16_BYTE( "MITSUBISHI_A07.botpcb.m5l27512k.9B.BIN", 0x00001, 0x10000, CRC(611ff400) SHA1(1a9aed33d0e3f063811f92b9fee3ecbff0e965bf) )
+
+ ROM_REGION( 0x20000, "spr_p103a", ROMREGION_ERASEFF )
+ // there's no P103A PCB for this on Android
+
+
+ // + 2 undumped PLDs
+ROM_END
+
+
GAME( 1989, himesiki, 0, himesiki, himesiki, driver_device, 0, ROT90, "Hi-Soft", "Himeshikibu (Japan)", MACHINE_SUPPORTS_SAVE )
+
+GAME( 198?, androidp, 0, himesiki, androidp, driver_device, 0, ROT90, "Nasco", "Android (early build?)", MACHINE_SUPPORTS_SAVE )
diff --git a/src/mame/drivers/igs017.cpp b/src/mame/drivers/igs017.cpp
index 1d1d439b3fc..8ab7a8711c2 100644
--- a/src/mame/drivers/igs017.cpp
+++ b/src/mame/drivers/igs017.cpp
@@ -4245,4 +4245,7 @@ GAME( 1998, slqz2, 0, slqz2, slqz2, igs017_state, slqz2, ROT
GAME( 1999?, tarzan, 0, iqblocka, iqblocka, igs017_state, tarzan, ROT0, "IGS", "Tarzan (V109C)", MACHINE_NOT_WORKING )
GAME( 1999?, tarzana, tarzan, iqblocka, iqblocka, igs017_state, tarzana, ROT0, "IGS", "Tarzan (V107)", MACHINE_NOT_WORKING )
GAME( 2000?, starzan, 0, starzan, iqblocka, igs017_state, starzan, ROT0, "IGS / G.F. Gioca", "Super Tarzan (Italy, V100I)", MACHINE_NOT_WORKING )
-GAME( ????, spkrform, spk116it, spkrform, spkrform, igs017_state, spkrform, ROT0, "IGS", "Super Poker (v100xD03) / Formosa", MACHINE_NOT_WORKING | MACHINE_UNEMULATED_PROTECTION )
+
+/* Parent spk306us in driver spoker.cpp. Move this set to that driver? */
+GAME( ????, spkrform, spk306us, spkrform, spkrform, igs017_state, spkrform, ROT0, "IGS", "Super Poker (v100xD03) / Formosa", MACHINE_NOT_WORKING | MACHINE_UNEMULATED_PROTECTION )
+
diff --git a/src/mame/drivers/iteagle.cpp b/src/mame/drivers/iteagle.cpp
index ff6b387bc45..9e725636055 100644
--- a/src/mame/drivers/iteagle.cpp
+++ b/src/mame/drivers/iteagle.cpp
@@ -142,11 +142,11 @@ void iteagle_state::machine_reset()
{
}
-#define PCI_ID_IDE ":pci:06.0"
+#define PCI_ID_IDE ":pci:06.0"
// Primary IDE Control ":pci:06.1"
// Seconday IDE Control ":pci:06.2"
#define PCI_ID_SOUND ":pci:07.0"
-#define PCI_ID_FPGA ":pci:08.0"
+#define PCI_ID_FPGA ":pci:08.0"
#define PCI_ID_VIDEO ":pci:09.0"
#define PCI_ID_EEPROM ":pci:0a.0"
@@ -161,7 +161,7 @@ static MACHINE_CONFIG_START( iteagle, iteagle_state )
MCFG_VRC4373_ADD( ":pci:00.0", ":maincpu")
MCFG_ITEAGLE_IDE_ADD( PCI_ID_IDE)
MCFG_ITEAGLE_IDE_IRQ_ADD( ":maincpu", MIPS3_IRQ2)
- MCFG_ITEAGLE_FPGA_ADD( PCI_ID_FPGA, ":maincpu", MIPS3_IRQ1)
+ MCFG_ITEAGLE_FPGA_ADD( PCI_ID_FPGA, ":maincpu", MIPS3_IRQ1, MIPS3_IRQ4)
MCFG_ES1373_ADD( PCI_ID_SOUND)
MCFG_SOUND_ROUTE(0, PCI_ID_SOUND":lspeaker", 1.0)
MCFG_SOUND_ROUTE(1, PCI_ID_SOUND":rspeaker", 1.0)
@@ -228,7 +228,15 @@ MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( bbhsc, iteagle )
MCFG_DEVICE_MODIFY(PCI_ID_FPGA)
- MCFG_ITEAGLE_FPGA_INIT(0x02000600, 0x0c0a0a)
+ // 0xXX01XXXX = tournament board
+ MCFG_ITEAGLE_FPGA_INIT(0x02010600, 0x0c0a0a)
+ MCFG_DEVICE_MODIFY(PCI_ID_EEPROM)
+ MCFG_ITEAGLE_EEPROM_INIT(0x0000, 0x7)
+MACHINE_CONFIG_END
+
+static MACHINE_CONFIG_DERIVED( bbh2sp, iteagle )
+ MCFG_DEVICE_MODIFY(PCI_ID_FPGA)
+ MCFG_ITEAGLE_FPGA_INIT(0x02000602, 0x0d0a0a)
MCFG_DEVICE_MODIFY(PCI_ID_EEPROM)
MCFG_ITEAGLE_EEPROM_INIT(0x0000, 0x7)
MACHINE_CONFIG_END
@@ -538,6 +546,21 @@ ROM_START( bbhsc )
DISK_REGION( PCI_ID_IDE":ide:0:hdd:image" )
DISK_IMAGE( "bbhsc_v1.50.07_cf", 0, SHA1(21dcf1f7e5ab901ac64e6afb099c35e273b3bf1f) ) /* Build 16:35:34, Feb 26 2002 - 4gb Compact Flash conversion */
ROM_END
+ //DISK_IMAGE( "bbhsc_v1.50.07_cf", 0, SHA1(21dcf1f7e5ab901ac64e6afb099c35e273b3bf1f) ) /* Build 16:35:34, Feb 26 2002 - 4gb Compact Flash conversion */
+ //DISK_IMAGE( "bbhsc_v1.60.01", 0, SHA1(8554fdd7193ee27c0fe8ca921aa8db9c0378b313) )
+
+ROM_START( bbh2sp )
+ EAGLE_BIOS
+
+ ROM_REGION( 0x0880, "atmel", 0 ) /* Atmel 90S2313 AVR internal CPU code */
+ ROM_LOAD( "bbh2-us.u53", 0x0000, 0x0880, NO_DUMP )
+
+ DISK_REGION( PCI_ID_IDE":ide:0:hdd:image" )
+ DISK_IMAGE( "bbh2sp_v2.02.11", 0, SHA1(63e41cca534f4774bfba4b4dda9620fe805029b4) )
+ROM_END
+ //DISK_IMAGE( "bbh2sp_v2.02.08", 0, SHA1(13b9b4ea0465f55dd1c7bc6e2f962c3c9b9566bd) )
+ //DISK_IMAGE( "bbh2sp_v2.02.09", 0, SHA1(fac3963b6da35a8c8b00f6826bc10e9c7230b1d6) )
+ //DISK_IMAGE( "bbh2sp_v2.02.11", 0, SHA1(63e41cca534f4774bfba4b4dda9620fe805029b4) )
ROM_START( bbhcotw ) /* This version is meant for 8meg GREEN board PCBs */
EAGLE_BIOS
@@ -570,4 +593,5 @@ GAME( 2004, gtfore05b, gtfore05, gtfore05, iteagle, driver_device, 0, ROT0, "I
GAME( 2004, gtfore05c, gtfore05, gtfore05, iteagle, driver_device, 0, ROT0, "Incredible Technologies", "Golden Tee Fore! 2005 Extra (v5.00.00)", 0 )
GAME( 2005, gtfore06, iteagle, gtfore06, iteagle, driver_device, 0, ROT0, "Incredible Technologies", "Golden Tee Fore! 2006 Complete (v6.00.01)", 0 )
GAME( 2002, bbhsc, iteagle, bbhsc, bbh, driver_device, 0, ROT0, "Incredible Technologies", "Big Buck Hunter - Shooter's Challenge (v1.50.07)", MACHINE_NOT_WORKING ) // doesn't boot
+GAME( 2002, bbh2sp, iteagle, bbh2sp, bbh, driver_device, 0, ROT0, "Incredible Technologies", "Big Buck Hunter II - Sportsman's Paradise (v2.02.11)", MACHINE_NOT_WORKING ) // SW51-2 needs to be off
GAME( 2006, bbhcotw, iteagle, bbhcotw, bbh, driver_device, 0, ROT0, "Incredible Technologies", "Big Buck Hunter Call of the Wild (v3.02.5)", MACHINE_NOT_WORKING ) // random lockups
diff --git a/src/mame/drivers/jaguar.cpp b/src/mame/drivers/jaguar.cpp
index e2fe252fe93..ee33848dd11 100644
--- a/src/mame/drivers/jaguar.cpp
+++ b/src/mame/drivers/jaguar.cpp
@@ -481,13 +481,13 @@ void jaguar_state::machine_reset()
emu_file jaguar_state::*jaguar_nvram_fopen( UINT32 openflags)
{
device_image_interface *image = dynamic_cast<device_image_interface *>(machine().device("cart"));
- file_error filerr;
+ osd_file::error filerr;
emu_file *file;
if (image->exists())
{
std::string fname(machine().system().name, PATH_SEPARATOR, image->basename_noext(), ".nv");
filerr = mame_fopen( SEARCHPATH_NVRAM, fname, openflags, &file);
- return (filerr == FILERR_NONE) ? file : NULL;
+ return (filerr == osd_file::error::NONE) ? file : NULL;
}
else
return NULL;
diff --git a/src/mame/drivers/k28.cpp b/src/mame/drivers/k28.cpp
index 2cc76c0f2c3..51ad5e805e8 100644
--- a/src/mame/drivers/k28.cpp
+++ b/src/mame/drivers/k28.cpp
@@ -64,7 +64,7 @@ public:
void display_update();
void set_display_size(int maxx, int maxy);
void set_display_segmask(UINT32 digits, UINT32 mask);
- void display_matrix(int maxx, int maxy, UINT32 setx, UINT32 sety);
+ void display_matrix(int maxx, int maxy, UINT32 setx, UINT32 sety, bool update = true);
bool m_power_on;
UINT8 m_inp_mux;
@@ -248,7 +248,7 @@ void k28_state::set_display_segmask(UINT32 digits, UINT32 mask)
}
}
-void k28_state::display_matrix(int maxx, int maxy, UINT32 setx, UINT32 sety)
+void k28_state::display_matrix(int maxx, int maxy, UINT32 setx, UINT32 sety, bool update)
{
set_display_size(maxx, maxy);
@@ -449,7 +449,7 @@ static INPUT_PORTS_START( k28 )
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_DEL_PAD) PORT_NAME(".")
PORT_START("IN.5")
- PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_PGUP) PORT_NAME("On") PORT_CHANGED_MEMBER(DEVICE_SELF, k28_state, power_on, nullptr)
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_POWER_ON ) PORT_CHANGED_MEMBER(DEVICE_SELF, k28_state, power_on, nullptr)
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_B) PORT_CHAR('B')
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_L) PORT_CHAR('L')
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_V) PORT_CHAR('V')
@@ -459,7 +459,7 @@ static INPUT_PORTS_START( k28 )
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_ENTER_PAD) PORT_CODE(KEYCODE_EQUALS) PORT_NAME("=")
PORT_START("IN.6")
- PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_PGDN) PORT_NAME("Off") // -> auto_power_off
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_POWER_OFF ) // -> auto_power_off
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_A) PORT_CHAR('A')
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_K) PORT_CHAR('K')
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_U) PORT_CHAR('U')
@@ -515,4 +515,5 @@ ROM_END
-COMP( 1981, k28, 0, 0, k28, k28, driver_device, 0, "Tiger Electronics", "K28: Talking Learning Computer (model 7-230)", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_SOUND | MACHINE_NOT_WORKING )
+/* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY, FULLNAME, FLAGS */
+COMP( 1981, k28, 0, 0, k28, k28, driver_device, 0, "Tiger Electronics", "K28: Talking Learning Computer (model 7-230)", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_SOUND | MACHINE_NOT_WORKING )
diff --git a/src/mame/drivers/lwings.cpp b/src/mame/drivers/lwings.cpp
index f0d7bf96932..28425f1664a 100644
--- a/src/mame/drivers/lwings.cpp
+++ b/src/mame/drivers/lwings.cpp
@@ -53,6 +53,7 @@ Notes:
#include "cpu/z80/z80.h"
#include "sound/2203intf.h"
#include "includes/lwings.h"
+#include "sound/okim6295.h"
/* Avengers runs on hardware almost identical to Trojan, but with a protection
* device and some small changes to the memory map and videohardware.
@@ -75,6 +76,10 @@ READ8_MEMBER(lwings_state::avengers_adpcm_r)
WRITE8_MEMBER(lwings_state::lwings_bankswitch_w)
{
+// if (data & 0xe0) printf("bankswitch_w %02x\n", data);
+// Fireball writes 0x20 on startup, maybe reset soundcpu?
+ m_sprbank = (data & 0x10)>>4; // Fireball only
+
/* bit 0 is flip screen */
flip_screen_set(~data & 0x01);
@@ -355,6 +360,58 @@ static ADDRESS_MAP_START( lwings_sound_map, AS_PROGRAM, 8, lwings_state )
AM_RANGE(0xe006, 0xe006) AM_WRITEONLY AM_SHARE("soundlatch2")
ADDRESS_MAP_END
+
+
+static ADDRESS_MAP_START( fball_map, AS_PROGRAM, 8, lwings_state )
+ AM_RANGE(0x0000, 0x7fff) AM_ROMBANK("bank2")
+ AM_RANGE(0x8000, 0xbfff) AM_ROMBANK("bank1")
+ AM_RANGE(0xc000, 0xddff) AM_RAM
+ AM_RANGE(0xde00, 0xdfff) AM_RAM AM_SHARE("spriteram")
+ AM_RANGE(0xe000, 0xe7ff) AM_RAM_WRITE(lwings_fgvideoram_w) AM_SHARE("fgvideoram")
+ AM_RANGE(0xe800, 0xefff) AM_RAM_WRITE(lwings_bg1videoram_w) AM_SHARE("bg1videoram")
+ AM_RANGE(0xf000, 0xf3ff) AM_RAM_DEVWRITE("palette", palette_device, write_ext) AM_SHARE("palette_ext")
+ AM_RANGE(0xf400, 0xf7ff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette")
+
+ AM_RANGE(0xf808, 0xf808) AM_READ_PORT("SERVICE")
+ AM_RANGE(0xf809, 0xf809) AM_READ_PORT("P1")
+ AM_RANGE(0xf808, 0xf809) AM_WRITE(lwings_bg1_scrollx_w)
+ AM_RANGE(0xf80a, 0xf80a) AM_READ_PORT("P2")
+ AM_RANGE(0xf80b, 0xf80b) AM_READ_PORT("DSWA")
+ AM_RANGE(0xf80a, 0xf80b) AM_WRITE(lwings_bg1_scrolly_w)
+ AM_RANGE(0xf80c, 0xf80c) AM_WRITE(soundlatch_byte_w)
+ AM_RANGE(0xf80d, 0xf80d) AM_READ_PORT("P3") AM_WRITE(watchdog_reset_w)
+ AM_RANGE(0xf80e, 0xf80e) AM_READ_PORT("P4")
+
+ AM_RANGE(0xf80e, 0xf80e) AM_WRITE(lwings_bankswitch_w)
+ADDRESS_MAP_END
+
+
+
+
+WRITE8_MEMBER(lwings_state::fball_oki_bank_w)
+{
+ //printf("fball_oki_bank_w %02x\n", data);
+ membank("samplebank")->set_entry((data >> 1) & 0x7);
+}
+
+static ADDRESS_MAP_START( fball_oki_map, AS_0, 8, lwings_state )
+ AM_RANGE(0x00000, 0x1ffff) AM_ROM
+ AM_RANGE(0x20000, 0x3ffff) AM_ROMBANK("samplebank")
+ADDRESS_MAP_END
+
+
+static ADDRESS_MAP_START( fball_sound_map, AS_PROGRAM, 8, lwings_state )
+ AM_RANGE(0x0000, 0x0fff) AM_ROM
+
+ AM_RANGE(0x8000, 0x8000) AM_READ(soundlatch_byte_r)
+
+ AM_RANGE(0xA000, 0xA000) AM_WRITE(fball_oki_bank_w)
+
+ AM_RANGE(0xc000, 0xc7ff) AM_RAM
+
+ AM_RANGE(0xe000, 0xe000) AM_DEVREADWRITE("oki", okim6295_device, read, write)
+ADDRESS_MAP_END
+
/* Yes, _no_ ram */
static ADDRESS_MAP_START( trojan_adpcm_map, AS_PROGRAM, 8, lwings_state )
AM_RANGE(0x0000, 0xffff) AM_ROM AM_WRITENOP
@@ -532,6 +589,58 @@ static INPUT_PORTS_START( lwingsb )
PORT_DIPSETTING( 0x00, "5" )
INPUT_PORTS_END
+
+static INPUT_PORTS_START( fball )
+ PORT_INCLUDE( lwings_generic )
+
+ PORT_MODIFY("SERVICE")
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_START3 )
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_START4 )
+
+
+ PORT_START("DSWA") // only one set of dipswitches
+ PORT_DIPNAME( 0x01, 0x01, DEF_STR( Difficulty ) ) PORT_DIPLOCATION("SWA:1")
+ PORT_DIPSETTING( 0x01, DEF_STR( Easy ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( Hard ) ) // smaller starting explosion
+ PORT_DIPNAME( 0x06, 0x04, DEF_STR( Lives ) ) PORT_DIPLOCATION("SWA:2,3")
+ PORT_DIPSETTING( 0x00, "1" )
+ PORT_DIPSETTING( 0x02, "2" )
+ PORT_DIPSETTING( 0x04, "3" )
+ PORT_DIPSETTING( 0x06, "4" )
+ PORT_DIPNAME( 0x18, 0x08, DEF_STR( Coinage ) ) PORT_DIPLOCATION("SWA:4,5")
+ PORT_DIPSETTING( 0x00, DEF_STR( 2C_1C ) )
+ PORT_DIPSETTING( 0x08, DEF_STR( 1C_1C ) )
+ PORT_DIPSETTING( 0x10, DEF_STR( 1C_2C ) )
+ PORT_DIPSETTING( 0x18, DEF_STR( 1C_4C ) )
+ PORT_DIPNAME( 0x20, 0x20, DEF_STR( Flip_Screen ) ) PORT_DIPLOCATION("SWA:6")
+ PORT_DIPSETTING( 0x20, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_DIPNAME( 0x40, 0x40, DEF_STR( Unused ) ) PORT_DIPLOCATION("SWA:7") // 'X' in test mode, presumably unused
+ PORT_DIPSETTING( 0x40, DEF_STR( Off ) )
+ PORT_DIPSETTING( 0x00, DEF_STR( On ) )
+ PORT_SERVICE_DIPLOC( 0x80, IP_ACTIVE_HIGH, "SWA:8" )
+
+ PORT_START("P3")
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(3)
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(3)
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(3)
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(3)
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(3)
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(3)
+ PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN ) /* probably unused */
+ PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) /* probably unused */
+
+ PORT_START("P4")
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(4)
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(4)
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(4)
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(4)
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(4)
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(4)
+ PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN ) /* probably unused */
+ PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) /* probably unused */
+INPUT_PORTS_END
+
/* Trojan with level selection - starting level dip switches not used */
static INPUT_PORTS_START( trojanls )
PORT_INCLUDE( lwings_generic )
@@ -743,6 +852,48 @@ void lwings_state::machine_start()
save_item(NAME(m_soundstate));
save_item(NAME(m_adpcm));
save_item(NAME(m_nmi_mask));
+ save_item(NAME(m_sprbank));
+
+ /*
+ Fireball has 2 copies of the 'fixed' code in the main program rom, with only slight changes.
+ it might be possible the hardware can bank that whole area or alternatively only see one version of the program
+ the only difference is 2 pieces of code have been swapped around. It is unknown when this code is called.
+
+ 3822: CD 73
+ 3823: 00 23
+ 3824: 3E 72
+ 3879: 73 CD
+ 387A: 23 00
+ 387B: 72 3E
+
+ bank 0
+ 3822: 73 ld (hl),e
+ 3823: 23 inc hl
+ 3824: 72 ld (hl),d
+ ...
+ 3879: CD 00 3E call $3E00
+
+ bank 1
+ 3822: CD 00 3E call $3E00
+ ..
+ 3879: 73 ld (hl),e
+ 387A: 23 inc hl
+ 387B: 72 ld (hl),d
+
+ */
+
+ if (membank("bank2"))
+ {
+ membank("bank2")->configure_entries(0, 2, &ROM[0x0000], 0x8000);
+ membank("bank2")->set_entry(0);
+ }
+
+ if (membank("samplebank"))
+ {
+ UINT8 *OKIROM = memregion("oki")->base();
+ membank("samplebank")->configure_entries(0, 8, OKIROM, 0x20000);
+ }
+
}
void lwings_state::machine_reset()
@@ -805,6 +956,52 @@ static MACHINE_CONFIG_START( lwings, lwings_state )
MCFG_SOUND_ROUTE(3, "mono", 0.10)
MACHINE_CONFIG_END
+
+
+
+
+
+
+
+
+static MACHINE_CONFIG_START( fball, lwings_state )
+
+ /* basic machine hardware */
+ MCFG_CPU_ADD("maincpu", Z80, XTAL_12MHz/2)
+ MCFG_CPU_PROGRAM_MAP(fball_map)
+ MCFG_CPU_VBLANK_INT_DRIVER("screen", lwings_state, avengers_interrupt)
+
+ MCFG_CPU_ADD("soundcpu", Z80, XTAL_12MHz/4) // ?
+ MCFG_CPU_PROGRAM_MAP(fball_sound_map)
+// MCFG_CPU_PERIODIC_INT_DRIVER(lwings_state, irq0_line_hold, 222)
+
+ /* video hardware */
+ MCFG_BUFFERED_SPRITERAM8_ADD("spriteram")
+
+ MCFG_SCREEN_ADD("screen", RASTER)
+ MCFG_SCREEN_REFRESH_RATE(60)
+ MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0))
+ MCFG_SCREEN_SIZE(32*8, 32*8)
+ MCFG_SCREEN_VISIBLE_AREA(0*8, 32*8-1, 1*8, 31*8-1) // the 16-pixel black border on left edge is correct, test mode actually uses that area
+ MCFG_SCREEN_UPDATE_DRIVER(lwings_state, screen_update_lwings)
+ MCFG_SCREEN_VBLANK_DEVICE("spriteram", buffered_spriteram8_device, vblank_copy_rising)
+ MCFG_SCREEN_PALETTE("palette")
+
+ MCFG_GFXDECODE_ADD("gfxdecode", "palette", lwings)
+
+ MCFG_PALETTE_ADD("palette", 1024)
+ MCFG_PALETTE_FORMAT(RRRRGGGGBBBBxxxx)
+
+ /* sound hardware */
+ MCFG_SPEAKER_STANDARD_MONO("mono")
+
+ MCFG_OKIM6295_ADD("oki", XTAL_12MHz/12, OKIM6295_PIN7_HIGH) // clock frequency & pin 7 not verified
+ MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0)
+ MCFG_DEVICE_ADDRESS_MAP(AS_0, fball_oki_map)
+
+MACHINE_CONFIG_END
+
+
static MACHINE_CONFIG_DERIVED( trojan, lwings )
/* basic machine hardware */
@@ -987,6 +1184,43 @@ ROM_START( lwingsb )
ROM_LOAD( "63s141.15g", 0x0000, 0x0100, CRC(d96bcc98) SHA1(99e69a624d5586e5eedacd2083fa68b36e7b5e40) ) /* timing (not used) */
ROM_END
+
+
+ROM_START( fball )
+ ROM_REGION( 0x20000, "maincpu", 0 )
+ ROM_LOAD( "D4.bin", 0x00000, 0x20000, CRC(6122b3dc) SHA1(25aad9a7a26a10985a4af2de34d48ac917cfff04) )
+
+ ROM_REGION( 0x01000, "soundcpu", ROMREGION_ERASEFF )
+ ROM_LOAD( "A05.bin", 0x00000, 0x01000, CRC(474dd19e) SHA1(962837716f54d0de2afb7f9df29f96b2e023bbcb) ) // BADADDR ----xxxxxxxxxxxx (16x data repeat)
+ ROM_IGNORE(0x01000) ROM_IGNORE(0x01000) ROM_IGNORE(0x01000) ROM_IGNORE(0x01000)
+ ROM_IGNORE(0x01000) ROM_IGNORE(0x01000) ROM_IGNORE(0x01000) ROM_IGNORE(0x01000)
+ ROM_IGNORE(0x01000) ROM_IGNORE(0x01000) ROM_IGNORE(0x01000) ROM_IGNORE(0x01000)
+ ROM_IGNORE(0x01000) ROM_IGNORE(0x01000) ROM_IGNORE(0x01000)
+
+ ROM_REGION( 0x04000, "gfx1", ROMREGION_ERASEFF )
+ ROM_LOAD( "J03.bin", 0x00000, 0x04000, CRC(be11627f) SHA1(de6b25e1b951d786d28a1c26716587754cfdc0df) ) // BADADDR --xxxxxxxxxxxxxx (4x data repeat)
+ ROM_IGNORE(0x04000)
+ ROM_IGNORE(0x04000)
+ ROM_IGNORE(0x04000)
+
+ ROM_REGION( 0x40000, "gfx2", ROMREGION_ERASEFF )
+ ROM_LOAD( "B15.bin", 0x20000, 0x10000, CRC(2169ad3e) SHA1(5628b97e6f4ad4291eb98b02ea8f9b2282b44c60) ) ROM_IGNORE(0x10000) // 1ST AND 2ND HALF IDENTICAL
+ ROM_LOAD( "C15.bin", 0x10000, 0x10000, CRC(0f77b03e) SHA1(23e4e7268346abcbadd9e42184853e2884a27430) ) ROM_IGNORE(0x10000) // ^
+ ROM_LOAD( "E15.bin", 0x00000, 0x10000, CRC(89a761d2) SHA1(71305ede65a2fa13f4331008f851509a0e1d92f9) ) ROM_IGNORE(0x10000) // ^
+ ROM_LOAD( "F15.bin", 0x30000, 0x10000, CRC(34b3f9a2) SHA1(29aeb22f0ee6b68a7a6d2a63bb99d5466d9ea798) ) ROM_IGNORE(0x10000) // ^
+
+ ROM_REGION( 0x40000, "gfx3", ROMREGION_ERASEFF )
+ ROM_LOAD( "J15.bin", 0x00000, 0x20000, CRC(ed7be8e7) SHA1(27f0e10161e0243b18326d4b23b2aaaaf4753960) )
+ ROM_LOAD( "H15.bin", 0x20000, 0x20000, CRC(6ffb5433) SHA1(8001b16f51909cf3f29f06650b60d99558759194) )
+
+ ROM_REGION( 0x100000, "oki", ROMREGION_ERASEFF )
+ ROM_LOAD( "A03.bin", 0x00000, 0x40000, CRC(22b0d089) SHA1(a82d04c389694e1ed0b9b24555ddd6f9d9f6ca38) )
+ ROM_RELOAD(0x40000,0x40000)
+ ROM_LOAD( "A02.bin", 0x80000, 0x40000, CRC(951d6579) SHA1(8976a836538eb510888f49af94dbf66dacb8f067) )
+ ROM_LOAD( "A01.bin", 0xc0000, 0x40000, CRC(020b5261) SHA1(698dbd7e125e4edd988791ecdae7db9ddc0705b3) )
+ROM_END
+
+
ROM_START( sectionz )
ROM_REGION( 0x20000, "maincpu", 0 ) /* 64k for code + 3*16k for the banked ROMs images */
ROM_LOAD( "6c_sz01.bin", 0x00000, 0x8000, CRC(69585125) SHA1(a341e3a5507e961d5763be6acf420695bb32709e) )
@@ -1509,3 +1743,8 @@ GAME( 1987, avengers, 0, avengers, avengers, driver_device, 0, ROT90, "C
GAME( 1987, avengers2, avengers, avengers, avengers, driver_device, 0, ROT90, "Capcom", "Avengers (US set 2)", MACHINE_SUPPORTS_SAVE )
GAME( 1987, buraiken, avengers, avengers, avengers, driver_device, 0, ROT90, "Capcom", "Hissatsu Buraiken (Japan)", MACHINE_SUPPORTS_SAVE )
GAME( 1987, buraikenb, avengers, avengersb,avengers, lwings_state, avengersb, ROT90, "Capcom", "Hissatsu Buraiken (Japan, bootleg?)", MACHINE_SUPPORTS_SAVE ) // unprotected at least
+
+// cloned lwings hardware
+GAME( 1992, fball, 0, fball, fball, driver_device, 0, ROT0, "FM Work", "Fire Ball (FM Work)", MACHINE_SUPPORTS_SAVE )
+
+ \ No newline at end of file
diff --git a/src/mame/drivers/microvsn.cpp b/src/mame/drivers/microvsn.cpp
index b7ff8fba4c8..33f0795ff1a 100644
--- a/src/mame/drivers/microvsn.cpp
+++ b/src/mame/drivers/microvsn.cpp
@@ -17,7 +17,7 @@ of the games were clocked at around 500KHz, 550KHz, or 300KHz.
#include "emu.h"
#include "cpu/mcs48/mcs48.h"
-#include "cpu/tms0980/tms0980.h"
+#include "cpu/tms1000/tms1100.h"
#include "sound/dac.h"
#include "rendlay.h"
@@ -547,7 +547,7 @@ DEVICE_IMAGE_LOAD_MEMBER(microvision_state, microvsn_cart)
if (pla)
m_pla = 1;
- tms1xxx_cpu_device::set_output_pla(m_tms1100, m_pla ? microvision_output_pla_1 : microvision_output_pla_0);
+ tms1100_cpu_device::set_output_pla(m_tms1100, m_pla ? microvision_output_pla_1 : microvision_output_pla_0);
// Set default setting for PCB type and RC type
m_pcb_type = microvision_state::PCB_TYPE_UNKNOWN;
diff --git a/src/mame/drivers/n64.cpp b/src/mame/drivers/n64.cpp
index 770c42a6a09..b4b22a35aca 100644
--- a/src/mame/drivers/n64.cpp
+++ b/src/mame/drivers/n64.cpp
@@ -111,6 +111,11 @@ static INPUT_PORTS_START( n64 )
PORT_CONFSETTING(0x0000, "Retail")
PORT_CONFSETTING(0x0100, "Development")
+ PORT_CONFNAME(0xC000, 0x8000, "EEPROM Size")
+ PORT_CONFSETTING(0x0000, "None")
+ PORT_CONFSETTING(0x8000, "4KB")
+ PORT_CONFSETTING(0xC000, "16KB")
+
//Player 1
PORT_START("P1")
PORT_BIT( 0x8000, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_PLAYER(1) PORT_NAME("P1 Button A / Left Click")
diff --git a/src/mame/drivers/namcos21.cpp b/src/mame/drivers/namcos21.cpp
index 4a9b4f51038..e8b629340da 100644
--- a/src/mame/drivers/namcos21.cpp
+++ b/src/mame/drivers/namcos21.cpp
@@ -1004,7 +1004,7 @@ void namcos21_state::render_slave_output(UINT16 data)
{
if( m_mpDspState->slaveOutputSize >= 4096 )
{
- fatalerror( "FATAL ERROR: SLAVE OVERFLOW (0x%x)\n",m_mpDspState->slaveOutputBuffer[0] );
+ fatalerror( "SLAVE OVERFLOW (0x%x)\n",m_mpDspState->slaveOutputBuffer[0] );
}
/* append word to slave output buffer */
diff --git a/src/mame/drivers/neogeo_noslot.cpp b/src/mame/drivers/neogeo_noslot.cpp
index f3f79953c03..8fc68f9edcf 100644
--- a/src/mame/drivers/neogeo_noslot.cpp
+++ b/src/mame/drivers/neogeo_noslot.cpp
@@ -683,6 +683,8 @@ ROM_END
. NGH-007
NEO-AEG PROG42G / NEO-AEG CHA42G
NEO-AEG PROG42G / NEO-AEG CHA-8M
+ . prototype
+ NEO-AEG PROG-EP / NEO-AEG CHA-EP
****************************************/
ROM_START( alpham2 ) /* MVS AND AES VERSION */
@@ -707,33 +709,33 @@ ROM_START( alpham2 ) /* MVS AND AES VERSION */
ROM_LOAD16_BYTE( "007-c4.c4", 0x200001, 0x080000, CRC(7d588349) SHA1(a5ed789d7bbc25be5c5b2d99883b64d379c103a2) ) /* Plane 2,3 */ /* TC534200 */
ROM_END
-ROM_START( alpham2p ) /* early prototype - all roms were hand labeled with CRCs, dumps verified against them */
+ROM_START( alpham2p ) /* early prototype - all roms were hand labeled with CRCs, dumps verified against them */ /* AES VERSION*/
ROM_REGION( 0x100000, "maincpu", 0 )
- ROM_LOAD16_BYTE( "proto_007-p1.p1", 0x000001, 0x080000, CRC(c763e52a) SHA1(b24acbac255c5ee1a2e92e77cdde6620a24081cf) )
- ROM_LOAD16_BYTE( "proto_007-p2.p2", 0x000000, 0x080000, CRC(7a0b435c) SHA1(40e6f42a92001d9f4e51898dd7489da143b6b74b) )
+ ROM_LOAD16_BYTE( "007_p1_faac.p1", 0x000001, 0x080000, CRC(c763e52a) SHA1(b24acbac255c5ee1a2e92e77cdde6620a24081cf) )
+ ROM_LOAD16_BYTE( "007_p2_1813.p2", 0x000000, 0x080000, CRC(7a0b435c) SHA1(40e6f42a92001d9f4e51898dd7489da143b6b74b) )
- NEO_SFIX_128K( "proto_007-s1.s1", CRC(efc9ae2e) SHA1(a594826b0082fe5a13191673e8d9aa42517230f5) )
+ NEO_SFIX_128K( "007_s1_36f1.s1", CRC(efc9ae2e) SHA1(a594826b0082fe5a13191673e8d9aa42517230f5) )
- NEO_BIOS_AUDIO_128K( "proto_007-m1.m1", CRC(5976b464) SHA1(ec824567ecc3579f6d86c9d9385710cbaeef16a3) )
+ NEO_BIOS_AUDIO_128K( "007_m1_9384.m1", CRC(5976b464) SHA1(ec824567ecc3579f6d86c9d9385710cbaeef16a3) )
ROM_REGION( 0x200000, "ymsnd", 0 )
- ROM_LOAD( "proto_007-v11.v11", 0x000000, 0x080000, CRC(18eaa9e1) SHA1(85c94d8660f8a32e4ca8e015f0bd704208482d68) )
- ROM_LOAD( "proto_007-v12.v12", 0x080000, 0x080000, CRC(2487d495) SHA1(49af3c4dc6a38c5158d3641fd8f9a40041b42aa6) )
- ROM_LOAD( "proto_007-v13.v13", 0x100000, 0x080000, CRC(25e60f25) SHA1(d06b0df872372de38fcf90187195070ac5f8c651) )
- ROM_LOAD( "proto_007-v21.v21", 0x180000, 0x080000, CRC(ac44b75a) SHA1(7399a05cd4e2c7ecde4a7323d3e189255afe5fc2) )
+ ROM_LOAD( "007_v11_1bb4.v11", 0x000000, 0x080000, CRC(18eaa9e1) SHA1(85c94d8660f8a32e4ca8e015f0bd704208482d68) )
+ ROM_LOAD( "007_v12_c8e8.v12", 0x080000, 0x080000, CRC(2487d495) SHA1(49af3c4dc6a38c5158d3641fd8f9a40041b42aa6) )
+ ROM_LOAD( "007_v13_09fa.v13", 0x100000, 0x080000, CRC(25e60f25) SHA1(d06b0df872372de38fcf90187195070ac5f8c651) )
+ ROM_LOAD( "007_v21_28c2.v21", 0x180000, 0x080000, CRC(ac44b75a) SHA1(7399a05cd4e2c7ecde4a7323d3e189255afe5fc2) )
ROM_REGION( 0x080000, "ymsnd.deltat", 0 )
ROM_COPY( "ymsnd", 0x180000, 0x00000, 0x80000 )
ROM_REGION( 0x400000, "sprites", 0 ) // note, ROM_LOAD32_BYTE
- ROM_LOAD32_BYTE( "proto_007-c1.c1", 0x000000, 0x80000, CRC(24841639) SHA1(fcc2a349121dad86ffefc44b9f0e8ba616ce0d30) ) /* Plane 0 */
- ROM_LOAD32_BYTE( "proto_007-c2.c2", 0x000002, 0x80000, CRC(912763ab) SHA1(cedf26d7d85ad140399ee62813c71f35e65498d6) ) /* Plane 2 */
- ROM_LOAD32_BYTE( "proto_007-c3.c3", 0x000001, 0x80000, CRC(0743bde2) SHA1(0d13ad6333909ad3cf10f9ac360f9abf191318de) ) /* Plane 1 */
- ROM_LOAD32_BYTE( "proto_007-c4.c4", 0x000003, 0x80000, CRC(61240212) SHA1(dee36f6604adaeb96e0d761a7256241c066b1cd2) ) /* Plane 3 */
- ROM_LOAD32_BYTE( "proto_007-c5.c5", 0x200000, 0x80000, CRC(cf9f4c53) SHA1(f979c85f83d9f76e554c2617f85f6d4efca6799c) ) /* Plane 0 */
- ROM_LOAD32_BYTE( "proto_007-c6.c6", 0x200002, 0x80000, CRC(3d903b19) SHA1(001a8c762336b855fe1df69fe2e605d30a3f00a1) ) /* Plane 2 */
- ROM_LOAD32_BYTE( "proto_007-c7.c7", 0x200001, 0x80000, CRC(e41e3875) SHA1(730aceb8a66cb33d0194b096568f053ad7dc000a) ) /* Plane 1 */
- ROM_LOAD32_BYTE( "proto_007-c8.c8", 0x200003, 0x80000, CRC(4483e2cf) SHA1(47c3364f5c36ae9dc3a49fe37ca60bcee0e73314) ) /* Plane 3 */
+ ROM_LOAD32_BYTE( "007_c1_210e.c11", 0x000000, 0x80000, CRC(24841639) SHA1(fcc2a349121dad86ffefc44b9f0e8ba616ce0d30) ) /* Plane 0 */
+ ROM_LOAD32_BYTE( "007_c2_29ae.c12", 0x000002, 0x80000, CRC(912763ab) SHA1(cedf26d7d85ad140399ee62813c71f35e65498d6) ) /* Plane 2 */
+ ROM_LOAD32_BYTE( "007_c3_c873.c13", 0x000001, 0x80000, CRC(0743bde2) SHA1(0d13ad6333909ad3cf10f9ac360f9abf191318de) ) /* Plane 1 */
+ ROM_LOAD32_BYTE( "007_c4_2462.c14", 0x000003, 0x80000, CRC(61240212) SHA1(dee36f6604adaeb96e0d761a7256241c066b1cd2) ) /* Plane 3 */
+ ROM_LOAD32_BYTE( "007_c5_5f16.c15", 0x200000, 0x80000, CRC(cf9f4c53) SHA1(f979c85f83d9f76e554c2617f85f6d4efca6799c) ) /* Plane 0 */
+ ROM_LOAD32_BYTE( "007_c6_8abc.c16", 0x200002, 0x80000, CRC(3d903b19) SHA1(001a8c762336b855fe1df69fe2e605d30a3f00a1) ) /* Plane 2 */
+ ROM_LOAD32_BYTE( "007_c7_c983.c17", 0x200001, 0x80000, CRC(e41e3875) SHA1(730aceb8a66cb33d0194b096568f053ad7dc000a) ) /* Plane 1 */
+ ROM_LOAD32_BYTE( "007_c8_b599.c18", 0x200003, 0x80000, CRC(4483e2cf) SHA1(47c3364f5c36ae9dc3a49fe37ca60bcee0e73314) ) /* Plane 3 */
ROM_END
/****************************************
@@ -1023,6 +1025,8 @@ ROM_END
NEO-MVS PROG42G / NEO-MVS CHA42G
. NGH-018
NEO-AEG PROG42G / NEO-AEG CHA42G
+ . prototype
+ NEO-AEG PROG-EP / NEO-AEG CHA-EP
****************************************/
ROM_START( burningf ) /* MVS AND AES VERSION */
@@ -1067,32 +1071,32 @@ ROM_START( burningfh ) /* AES VERSION (US) */
ROM_LOAD16_BYTE( "018-c4.c4", 0x200001, 0x100000, CRC(e2e0aff7) SHA1(1c691c092a6e2787de4f433b0eb9252bfdaa7e16) ) /* Plane 2,3 */ /* HN62408 */
ROM_END
-ROM_START( burningfp ) /* early prototype - all roms were hand labeled with CRCs, dumps verified against them */
+ROM_START( burningfp ) /* early prototype - all roms were hand labeled with CRCs, dumps verified against them */ /* AES VERSION */
ROM_REGION( 0x100000, "maincpu", 0 )
- ROM_LOAD16_BYTE( "proto_018-p1.p1", 0x000001, 0x080000, CRC(5b4032e7) SHA1(55df91dad6f484d3d49c28ab5972700bf71a8662) )
- ROM_LOAD16_BYTE( "proto_018-p2.p2", 0x000000, 0x080000, CRC(78762f68) SHA1(12170fc6efe75cb5d32624033d3d341032c97548) )
+ ROM_LOAD16_BYTE( "018_p1_9397.p1", 0x000001, 0x080000, CRC(5b4032e7) SHA1(55df91dad6f484d3d49c28ab5972700bf71a8662) )
+ ROM_LOAD16_BYTE( "018_p2_e335.p2", 0x000000, 0x080000, CRC(78762f68) SHA1(12170fc6efe75cb5d32624033d3d341032c97548) )
- NEO_SFIX_128K( "proto_018-s1.s1", CRC(f3d130e8) SHA1(2fdeb93f4bb2a60d391cac2822be41661b1e1795) )
+ NEO_SFIX_128K( "018_s1_9899.s1", CRC(f3d130e8) SHA1(2fdeb93f4bb2a60d391cac2822be41661b1e1795) )
- NEO_BIOS_AUDIO_128K( "proto_018-m1.m1", CRC(470dd5d4) SHA1(4291811b4aefe45261a1ae3631b6999fcd74fb3f) )
+ NEO_BIOS_AUDIO_128K( "018_m1_4586.m1", CRC(470dd5d4) SHA1(4291811b4aefe45261a1ae3631b6999fcd74fb3f) )
ROM_REGION( 0x200000, "ymsnd", 0 )
- ROM_LOAD( "proto_018-v11.v11", 0x000000, 0x080000, CRC(dc07ea3c) SHA1(c3e71aaec44ead7ddc581565d16b90030e6db5fd) )
- ROM_LOAD( "proto_018-v12.v12", 0x080000, 0x080000, CRC(f1ae637c) SHA1(02a4c7d4a544350a314ab7b26d8c9d3baa8f5778) )
- ROM_LOAD( "proto_018-v21.v21", 0x100000, 0x080000, CRC(9f3b4eda) SHA1(7f516923d04daa483b4b99c9babba66505931a34) )
+ ROM_LOAD( "018_v11_56ac.v11", 0x000000, 0x080000, CRC(dc07ea3c) SHA1(c3e71aaec44ead7ddc581565d16b90030e6db5fd) )
+ ROM_LOAD( "018_v12_db95.v12", 0x080000, 0x080000, CRC(f1ae637c) SHA1(02a4c7d4a544350a314ab7b26d8c9d3baa8f5778) )
+ ROM_LOAD( "018_v21_98dd.v21", 0x100000, 0x080000, CRC(9f3b4eda) SHA1(7f516923d04daa483b4b99c9babba66505931a34) )
ROM_REGION( 0x080000, "ymsnd.deltat", 0 )
ROM_COPY( "ymsnd", 0x100000, 0x00000, 0x80000 )
ROM_REGION( 0x400000, "sprites", 0 ) // note, ROM_LOAD32_BYTE
- ROM_LOAD32_BYTE( "proto_018-c1.c1", 0x000000, 0x80000, CRC(6569018b) SHA1(25040e0a9c2b72900100a22a2a41de5f6c339d8a) ) /* Plane 0 */
- ROM_LOAD32_BYTE( "proto_018-c2.c2", 0x000002, 0x80000, CRC(6949b501) SHA1(d8ee48837faff6cc849046ee8757b2b94d440303) ) /* Plane 2 */
- ROM_LOAD32_BYTE( "proto_018-c3.c3", 0x000001, 0x80000, CRC(410f653b) SHA1(ce94667721baa7b2c318fc268e3bb9209671c9f5) ) /* Plane 1 */
- ROM_LOAD32_BYTE( "proto_018-c4.c4", 0x000003, 0x80000, CRC(d43bf2a5) SHA1(c27985d8973611d02570f469a0d8cb4f5b63b614) ) /* Plane 3 */
- ROM_LOAD32_BYTE( "proto_018-c5.c5", 0x200000, 0x80000, CRC(837d09d3) SHA1(d3b06931fca6123604549599544b04529ef34c53) ) /* Plane 0 */
- ROM_LOAD32_BYTE( "proto_018-c6.c6", 0x200002, 0x80000, CRC(5fee51e7) SHA1(835c632fa12a1d5b4104cd80b8f686ac80b314a1) ) /* Plane 2 */
- ROM_LOAD32_BYTE( "proto_018-c7.c7", 0x200001, 0x80000, CRC(0f3f0823) SHA1(ec1d681c1795de43d20f30f85956e2473ec39c95) ) /* Plane 1 */
- ROM_LOAD32_BYTE( "proto_018-c8.c8", 0x200003, 0x80000, CRC(67cc9e34) SHA1(dc72a464c1456a4d2f7b992b416a984fb7885e99) ) /* Plane 3 */
+ ROM_LOAD32_BYTE( "018_c1_ba06.c11", 0x000000, 0x80000, CRC(6569018b) SHA1(25040e0a9c2b72900100a22a2a41de5f6c339d8a) ) /* Plane 0 */
+ ROM_LOAD32_BYTE( "018_c2_d534.c12", 0x000002, 0x80000, CRC(6949b501) SHA1(d8ee48837faff6cc849046ee8757b2b94d440303) ) /* Plane 2 */
+ ROM_LOAD32_BYTE( "018_c3_9d70.c13", 0x000001, 0x80000, CRC(410f653b) SHA1(ce94667721baa7b2c318fc268e3bb9209671c9f5) ) /* Plane 1 */
+ ROM_LOAD32_BYTE( "018_c4_bf9d.c14", 0x000003, 0x80000, CRC(d43bf2a5) SHA1(c27985d8973611d02570f469a0d8cb4f5b63b614) ) /* Plane 3 */
+ ROM_LOAD32_BYTE( "018_c5_ac9d.c15", 0x200000, 0x80000, CRC(837d09d3) SHA1(d3b06931fca6123604549599544b04529ef34c53) ) /* Plane 0 */
+ ROM_LOAD32_BYTE( "018_c6_d2a5.c16", 0x200002, 0x80000, CRC(5fee51e7) SHA1(835c632fa12a1d5b4104cd80b8f686ac80b314a1) ) /* Plane 2 */
+ ROM_LOAD32_BYTE( "018_c7_d568.c17", 0x200001, 0x80000, CRC(0f3f0823) SHA1(ec1d681c1795de43d20f30f85956e2473ec39c95) ) /* Plane 1 */
+ ROM_LOAD32_BYTE( "018_c8_d256.c18", 0x200003, 0x80000, CRC(67cc9e34) SHA1(dc72a464c1456a4d2f7b992b416a984fb7885e99) ) /* Plane 3 */
ROM_END
/****************************************
@@ -1287,6 +1291,9 @@ ROM_END
. NGM-024
NEO-MVS PROG42G-1 / NEO-MVS CHA42G-1
. NGH-024
+
+ . prototype
+ NEO-MVS PROG-EP / NEO-MVS CHA-EPG
****************************************/
ROM_START( lresort )
@@ -1310,32 +1317,32 @@ ROM_START( lresort )
ROM_LOAD16_BYTE( "024-c4.c4", 0x200001, 0x080000, CRC(7382fefb) SHA1(e916dec5bb5462eb9ae9711f08c7388937abb980) ) /* Plane 2,3 */ /* TC534200 */
ROM_END
-ROM_START( lresortp ) /* prototype - all roms were hand labeled with CRCs */
+ROM_START( lresortp ) /* prototype - all roms were hand labeled with CRCs */ /* MVS VERSION */
ROM_REGION( 0x100000, "maincpu", 0 )
- ROM_LOAD16_BYTE( "024_p1_5937.bin", 0x000001, 0x080000, CRC(8e6008ee) SHA1(6779663118782207156dc9fa9e24e81e30c6391c) )
- ROM_LOAD16_BYTE( "024_p2_8d37.bin", 0x000000, 0x080000, CRC(6d9ee90f) SHA1(ecd42182988092417bc96db8301ea408e47735f2) )
+ ROM_LOAD16_BYTE( "024_p1_5937.podd", 0x000001, 0x080000, CRC(8e6008ee) SHA1(6779663118782207156dc9fa9e24e81e30c6391c) )
+ ROM_LOAD16_BYTE( "024_p2_8d37.peven", 0x000000, 0x080000, CRC(6d9ee90f) SHA1(ecd42182988092417bc96db8301ea408e47735f2) )
- NEO_SFIX_128K( "024_s1_22fe.bin", CRC(5cef5cc6) SHA1(9ec305007bdb356e9f8f279beae5e2bcb3f2cf7b) )
+ NEO_SFIX_128K( "024_s1_22fe.s1", CRC(5cef5cc6) SHA1(9ec305007bdb356e9f8f279beae5e2bcb3f2cf7b) )
- NEO_BIOS_AUDIO_128K( "024_m1_fc7a.bin", CRC(22122875) SHA1(540c21559163381467679f836cb068adaf526659) )
+ NEO_BIOS_AUDIO_128K( "024_m1_fc7a.m1", CRC(22122875) SHA1(540c21559163381467679f836cb068adaf526659) )
ROM_REGION( 0x200000, "ymsnd", 0 )
- ROM_LOAD( "024_v11_b085.bin", 0x000000, 0x080000, CRC(0722da38) SHA1(66a9b463d5277908b3a01c03de82b3de9118f2cb) ) // 024_v11_b085.bin 024-v1.v1 [1/2] IDENTICAL
- ROM_LOAD( "024_v12_d3b7.bin", 0x080000, 0x080000, CRC(670ce3ec) SHA1(9004aa85d4a9b0ecf9cf9357b073ed55a98fdb02) ) // 024_v12_d3b7.bin 024-v1.v1 [2/2] IDENTICAL
- ROM_LOAD( "024_v13_a31e.bin", 0x100000, 0x080000, CRC(2e39462b) SHA1(b0a9b1a3377bf0369f3020192505c46ca52927d6) ) // 024_v13_a31e.bin 024-v2.v2 [1/2] IDENTICAL
- ROM_LOAD( "024_v24_2f0f.bin", 0x180000, 0x080000, CRC(7944754f) SHA1(d42a46c5127c6c62041ebffb0007af8a24abd360) ) // 024_v24_2f0f.bin 024-v2.v2 [2/2] IDENTICAL
+ ROM_LOAD( "024_v11_b085.v11", 0x000000, 0x080000, CRC(0722da38) SHA1(66a9b463d5277908b3a01c03de82b3de9118f2cb) ) // 024_v11_b085.bin 024-v1.v1 [1/2] IDENTICAL
+ ROM_LOAD( "024_v12_d3b7.v12", 0x080000, 0x080000, CRC(670ce3ec) SHA1(9004aa85d4a9b0ecf9cf9357b073ed55a98fdb02) ) // 024_v12_d3b7.bin 024-v1.v1 [2/2] IDENTICAL
+ ROM_LOAD( "024_v13_a31e.v13", 0x100000, 0x080000, CRC(2e39462b) SHA1(b0a9b1a3377bf0369f3020192505c46ca52927d6) ) // 024_v13_a31e.bin 024-v2.v2 [1/2] IDENTICAL
+ ROM_LOAD( "024_v24_2f0f.v24", 0x180000, 0x080000, CRC(7944754f) SHA1(d42a46c5127c6c62041ebffb0007af8a24abd360) ) // 024_v24_2f0f.bin 024-v2.v2 [2/2] IDENTICAL
NO_DELTAT_REGION
ROM_REGION( 0x400000, "sprites", 0 ) // note, ROM_LOAD32_BYTE
- ROM_LOAD32_BYTE( "024_c1_b764.bin", 0x000000, 0x80000, CRC(677749ec) SHA1(6f94675e037956a380652ab1056e6f1dec605bec) ) /* Plane 0 */
- ROM_LOAD32_BYTE( "024_c2_1951.bin", 0x000002, 0x80000, CRC(104d7b59) SHA1(404e8776ee8df4ca282eb7b747759af8628ddca1) ) /* Plane 2 */
- ROM_LOAD32_BYTE( "024_c3_0f63.bin", 0x000001, 0x80000, CRC(b0965a74) SHA1(e8026dd4f722ccab9c913261d09ab8843ef56a0e) ) /* Plane 1 */
- ROM_LOAD32_BYTE( "024_c4_c5b5.bin", 0x000003, 0x80000, CRC(dcfc3860) SHA1(8443b455ae8de656adab57f3b7e68919f22d3b9d) ) /* Plane 3 */
- ROM_LOAD32_BYTE( "024_c5_dd03.bin", 0x200000, 0x80000, CRC(50322397) SHA1(3308fbe48ad165b9894a52fc3a8d9898bbbc0c0e) ) /* Plane 0 */
- ROM_LOAD32_BYTE( "024_c6_c81a.bin", 0x200002, 0x80000, CRC(c3c93894) SHA1(f23b9d7e2b54d44c96370dde282bdf45cebd9cba) ) /* Plane 2 */
- ROM_LOAD32_BYTE( "024_c7_5edc.bin", 0x200001, 0x80000, CRC(21faf72b) SHA1(00bf257b06180ae6ede57744cea6257b3488d9f0) ) /* Plane 1 */
- ROM_LOAD32_BYTE( "024_c8_0850.bin", 0x200003, 0x80000, CRC(fb57217b) SHA1(607a98da754e8b1dd94a6432b21a36cc38e06a0f) ) /* Plane 3 */
+ ROM_LOAD32_BYTE( "024_c1_b764.c1", 0x000000, 0x80000, CRC(677749ec) SHA1(6f94675e037956a380652ab1056e6f1dec605bec) ) /* Plane 0 */
+ ROM_LOAD32_BYTE( "024_c2_1951.c2", 0x000002, 0x80000, CRC(104d7b59) SHA1(404e8776ee8df4ca282eb7b747759af8628ddca1) ) /* Plane 2 */
+ ROM_LOAD32_BYTE( "024_c3_0f63.c3", 0x000001, 0x80000, CRC(b0965a74) SHA1(e8026dd4f722ccab9c913261d09ab8843ef56a0e) ) /* Plane 1 */
+ ROM_LOAD32_BYTE( "024_c4_c5b5.c4", 0x000003, 0x80000, CRC(dcfc3860) SHA1(8443b455ae8de656adab57f3b7e68919f22d3b9d) ) /* Plane 3 */
+ ROM_LOAD32_BYTE( "024_c5_dd03.c5", 0x200000, 0x80000, CRC(50322397) SHA1(3308fbe48ad165b9894a52fc3a8d9898bbbc0c0e) ) /* Plane 0 */
+ ROM_LOAD32_BYTE( "024_c6_c81a.c6", 0x200002, 0x80000, CRC(c3c93894) SHA1(f23b9d7e2b54d44c96370dde282bdf45cebd9cba) ) /* Plane 2 */
+ ROM_LOAD32_BYTE( "024_c7_5edc.c7", 0x200001, 0x80000, CRC(21faf72b) SHA1(00bf257b06180ae6ede57744cea6257b3488d9f0) ) /* Plane 1 */
+ ROM_LOAD32_BYTE( "024_c8_0850.c8", 0x200003, 0x80000, CRC(fb57217b) SHA1(607a98da754e8b1dd94a6432b21a36cc38e06a0f) ) /* Plane 3 */
ROM_END
diff --git a/src/mame/drivers/ng_aes.cpp b/src/mame/drivers/ng_aes.cpp
index 994dfbef4e5..42577544f51 100644
--- a/src/mame/drivers/ng_aes.cpp
+++ b/src/mame/drivers/ng_aes.cpp
@@ -1523,27 +1523,12 @@ MACHINE_CONFIG_END
ROM_START( aes )
ROM_REGION16_BE( 0x20000, "mainbios", 0 )
ROM_SYSTEM_BIOS( 0, "asia", "Asia AES" )
- ROM_LOAD16_WORD_SWAP_BIOS( 0, "neo-epo.bin", 0x00000, 0x020000, CRC(d27a71f1) SHA1(1b3b22092f30c4d1b2c15f04d1670eb1e9fbea07) ) /* AES Console (Asia?) Bios */
+ ROM_LOAD16_WORD_SWAP_BIOS( 0, "neo-epo.bin", 0x00000, 0x020000, CRC(d27a71f1) SHA1(1b3b22092f30c4d1b2c15f04d1670eb1e9fbea07) ) /* AES Console (Asia?) Bios */
ROM_SYSTEM_BIOS( 1, "japan", "Japan AES" )
- ROM_LOAD16_WORD_SWAP_BIOS( 1, "neo-po.bin", 0x00000, 0x020000, CRC(16d0c132) SHA1(4e4a440cae46f3889d20234aebd7f8d5f522e22c) ) /* AES Console (Japan) Bios */
+ ROM_LOAD16_WORD_SWAP_BIOS( 1, "neo-po.bin", 0x00000, 0x020000, CRC(16d0c132) SHA1(4e4a440cae46f3889d20234aebd7f8d5f522e22c) ) /* AES Console (Japan) Bios */
ROM_SYSTEM_BIOS( 2, "devel", "Development System ROM" )
- ROM_LOAD16_WORD_SWAP_BIOS( 2, "neodebug.rom", 0x00000, 0x020000, CRC(698ebb7d) SHA1(081c49aa8cc7dad5939833dc1b18338321ea0a07) ) /* Official debug (development) ROM, for home-use base board */
- ROM_SYSTEM_BIOS( 3, "unibios31", "Universe Bios (Hack, Ver. 3.1)" )
- ROM_LOAD16_WORD_SWAP_BIOS( 3, "uni-bios_3_1.rom", 0x00000, 0x020000, CRC(0c58093f) SHA1(29329a3448c2505e1ff45ffa75e61e9693165153) ) /* Universe Bios v3.1 (hack) */
- ROM_SYSTEM_BIOS( 4, "unibios30", "Universe Bios (Hack, Ver. 3.0)" )
- ROM_LOAD16_WORD_SWAP_BIOS( 4, "uni-bios_3_0.rom", 0x00000, 0x020000, CRC(a97c89a9) SHA1(97a5eff3b119062f10e31ad6f04fe4b90d366e7f) ) /* Universe Bios v3.0 (hack) */
- ROM_SYSTEM_BIOS( 5, "unibios23", "Universe Bios (Hack, Ver. 2.3)" )
- ROM_LOAD16_WORD_SWAP_BIOS( 5, "uni-bios_2_3.rom", 0x00000, 0x020000, CRC(27664eb5) SHA1(5b02900a3ccf3df168bdcfc98458136fd2b92ac0) ) /* Universe Bios v2.3 (hack) */
- ROM_SYSTEM_BIOS( 6, "unibios23o", "Universe Bios (Hack, Ver. 2.3, older?)" )
- ROM_LOAD16_WORD_SWAP_BIOS( 6, "uni-bios_2_3o.rom", 0x00000, 0x020000, CRC(601720ae) SHA1(1b8a72c720cdb5ee3f1d735bbcf447b09204b8d9) ) /* Universe Bios v2.3 (hack) alt version, withdrawn? */
- ROM_SYSTEM_BIOS( 7, "unibios22", "Universe Bios (Hack, Ver. 2.2)" )
- ROM_LOAD16_WORD_SWAP_BIOS( 7, "uni-bios_2_2.rom", 0x00000, 0x020000, CRC(2d50996a) SHA1(5241a4fb0c63b1a23fd1da8efa9c9a9bd3b4279c) ) /* Universe Bios v2.2 (hack) */
- ROM_SYSTEM_BIOS( 8, "unibios21", "Universe Bios (Hack, Ver. 2.1)" )
- ROM_LOAD16_WORD_SWAP_BIOS( 8, "uni-bios_2_1.rom", 0x00000, 0x020000, CRC(8dabf76b) SHA1(c23732c4491d966cf0373c65c83c7a4e88f0082c) ) /* Universe Bios v2.1 (hack) */
- ROM_SYSTEM_BIOS( 9, "unibios20", "Universe Bios (Hack, Ver. 2.0)" )
- ROM_LOAD16_WORD_SWAP_BIOS( 9, "uni-bios_2_0.rom", 0x00000, 0x020000, CRC(0c12c2ad) SHA1(37bcd4d30f3892078b46841d895a6eff16dc921e) ) /* Universe Bios v2.0 (hack) */
- ROM_SYSTEM_BIOS(10, "unibios13", "Universe Bios (Hack, Ver. 1.3)" )
- ROM_LOAD16_WORD_SWAP_BIOS(10, "uni-bios_1_3.rom", 0x00000, 0x020000, CRC(b24b44a0) SHA1(eca8851d30557b97c309a0d9f4a9d20e5b14af4e) ) /* Universe Bios v1.3 (hack) - note: versions older than 1.3 don't support AES hardware */
+ ROM_LOAD16_WORD_SWAP_BIOS( 2, "neodebug.rom", 0x00000, 0x020000, CRC(698ebb7d) SHA1(081c49aa8cc7dad5939833dc1b18338321ea0a07) ) /* Official debug (development) ROM, for home-use base board */
+ NEOGEO_UNIBIOS(3)
ROM_REGION( 0x200000, "maincpu", ROMREGION_ERASEFF )
diff --git a/src/mame/drivers/ngen.cpp b/src/mame/drivers/ngen.cpp
index fc02d654308..388ad075d74 100644
--- a/src/mame/drivers/ngen.cpp
+++ b/src/mame/drivers/ngen.cpp
@@ -834,7 +834,7 @@ void ngen_state::machine_start()
memory_share* fontshare = memshare("fontram");
m_hd_buffer.allocate(1024*8); // 8kB buffer RAM for HD controller
if(vidshare == nullptr || fontshare == nullptr)
- fatalerror("Error: VRAM not found");
+ fatalerror("VRAM not found\n");
m_vram.set(*vidshare,2);
m_fontram.set(*fontshare,2);
}
diff --git a/src/mame/drivers/ngp.cpp b/src/mame/drivers/ngp.cpp
index ce57a2ca4db..ac01a692443 100644
--- a/src/mame/drivers/ngp.cpp
+++ b/src/mame/drivers/ngp.cpp
@@ -617,7 +617,7 @@ static INPUT_PORTS_START( ngp )
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNUSED )
PORT_START("Power")
- PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_CODE(KEYCODE_Q) PORT_NAME("Power") PORT_CHANGED_MEMBER(DEVICE_SELF, ngp_state, power_callback, NULL)
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_POWER_ON ) PORT_CHANGED_MEMBER(DEVICE_SELF, ngp_state, power_callback, NULL)
INPUT_PORTS_END
@@ -892,5 +892,6 @@ ROM_START( ngpc )
ROM_END
-CONS( 1998, ngp, 0, 0, ngp, ngp, driver_device, 0, "SNK", "NeoGeo Pocket", MACHINE_SUPPORTS_SAVE )
-CONS( 1999, ngpc, ngp, 0, ngpc, ngp, driver_device, 0, "SNK", "NeoGeo Pocket Color", MACHINE_SUPPORTS_SAVE )
+/* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY, FULLNAME, FLAGS */
+CONS( 1998, ngp, 0, 0, ngp, ngp, driver_device, 0, "SNK", "NeoGeo Pocket", MACHINE_SUPPORTS_SAVE )
+CONS( 1999, ngpc, ngp, 0, ngpc, ngp, driver_device, 0, "SNK", "NeoGeo Pocket Color", MACHINE_SUPPORTS_SAVE )
diff --git a/src/mame/drivers/notetaker.cpp b/src/mame/drivers/notetaker.cpp
index c5e12655e80..a7c641c9d7f 100644
--- a/src/mame/drivers/notetaker.cpp
+++ b/src/mame/drivers/notetaker.cpp
@@ -56,9 +56,10 @@ TODO: everything below.
* floppy controller wd1791 and its interrupt
According to [3] and [5] the format is double density/MFM, 128 bytes per sector, 16 sectors per track, 1 or 2 sided, for 170K or 340K per disk. Drive spins at 300RPM.
* According to the schematics, we're missing an 82s147 DISKSEP.PROM used as a data separator
+* hook up the DiskInt from the wd1791 either using m_fdc->intrq_r() polling or using device lines (latter is a much better idea)
WIP:
-* crt5027 video controller - the iocpu side is hooked up, but crashes due to a bug in the crt5027/tms9927 code. the actual drawing to screen part is not connected anywhere yet.
+* crt5027 video controller - the iocpu side is hooked up, screen drawing 'works' but is scrambled due to not emulating the clock chain halting and clock changing yet. The crt5027 core also needs the odd/even interrupt hooked up, and proper interlace support as well as clock change/screen resize support (down to DC/no clock, which I guess should be a 1x1 single black pixel!)
* pic8259 interrupt controller - this is attached as a device, but only the vblank interrupt is hooked to it yet.
* Harris 6402 serial/EIA UART - connected to iocpu, other end isn't connected anywhere, interrupt is not connected
* Harris 6402 keyboard UART (within notetaker) - connected to iocpu, other end isn't connected anywhere, interrupt is not connected
@@ -120,6 +121,7 @@ public:
DECLARE_WRITE16_MEMBER(IPConReg_w);
DECLARE_WRITE16_MEMBER(FIFOReg_w);
DECLARE_WRITE16_MEMBER(FIFOBus_w);
+ DECLARE_WRITE16_MEMBER(DiskReg_w);
DECLARE_WRITE16_MEMBER(LoadDispAddr_w);
// uarts
@@ -158,6 +160,23 @@ public:
UINT8 m_SHConB;
UINT8 m_SHConA;
UINT8 m_SetSH;
+ // DiskReg
+ UINT8 m_ADCSpd0;
+ UINT8 m_ADCSpd1;
+ UINT8 m_StopWordClock_q;
+ UINT8 m_ClrDiskCont_q;
+ UINT8 m_ProgBitClk1;
+ UINT8 m_ProgBitClk2;
+ UINT8 m_ProgBitClk3;
+ UINT8 m_AnSel4;
+ UINT8 m_AnSel2;
+ UINT8 m_AnSel1;
+ UINT8 m_DriveSel1;
+ UINT8 m_DriveSel2;
+ UINT8 m_DriveSel3;
+ UINT8 m_SideSelect;
+ UINT8 m_Disk5VOn;
+ UINT8 m_Disk12VOn;
// output fifo, for DAC
UINT16 m_outfifo[16]; // technically three 74LS225 5bit*16stage FIFO chips, arranged as a 16 stage, 12-bit wide fifo (one bit unused per chip)
UINT8 m_outfifo_count;
@@ -248,7 +267,7 @@ WRITE16_MEMBER(notetaker_state::IPConReg_w)
{
m_BootSeqDone = (data&0x80)?1:0;
m_ProcLock = (data&0x40)?1:0; // bus lock for this processor (hold other processor in wait state)
- m_CharCtr = (data&0x20)?1:0; // battery charge control
+ m_CharCtr = (data&0x20)?1:0; // battery charge control (incorrectly called 'Char counter' in source code)
m_DisableROM = (data&0x10)?1:0; // disable rom at 0000-0fff
m_CorrOn_q = (data&0x08)?1:0; // CorrectionOn (ECC correction enabled); also LedInd5
m_LedInd6 = (data&0x04)?1:0;
@@ -336,6 +355,57 @@ WRITE16_MEMBER(notetaker_state::FIFOBus_w)
m_outfifo_head_ptr&=0xF;
}
+WRITE16_MEMBER( notetaker_state::DiskReg_w )
+{
+ // See http://bitsavers.trailing-edge.com/pdf/xerox/notetaker/memos/19781023_More_NoteTaker_IO_Information.pdf but note that bit 12 (called bit 3 in documentation) was changed between oct 1978 and 1979 to reset the disk controller digital-PLL as ClrDiskCont' rather than acting as ProgBitClk0, which is permanently wired high instead, meaning only the 4.5Mhz - 18Mhz dot clocks are available for the CRTC.
+ m_ADCSpd0 = (data&0x8000)?1:0;
+ m_ADCSpd1 = (data&0x4000)?1:0;
+ m_StopWordClock_q = (data&0x2000)?1:0;
+ //if ((!(m_ClrDiskCont_q)) && (data&0x1000)) m_floppy->device_reset(); // reset on rising edge
+ m_ClrDiskCont_q = (data&0x1000)?1:0; // originally ProgBitClk0, but co-opted later to reset the FDC's external PLL
+ m_ProgBitClk1 = (data&0x0800)?1:0;
+ m_ProgBitClk2 = (data&0x0400)?1:0;
+ m_ProgBitClk3 = (data&0x0200)?1:0;
+ m_AnSel4 = (data&0x0100)?1:0;
+ m_AnSel2 = (data&0x80)?1:0;
+ m_AnSel1 = (data&0x40)?1:0;
+ m_DriveSel1 = (data&0x20)?1:0;
+ m_DriveSel2 = (data&0x10)?1:0; // drive 2 not present on hardware, but could work if present
+ m_DriveSel3 = (data&0x08)?1:0; // drive 3 not present on hardware, but could work if present
+ m_SideSelect = (data&0x04)?1:0;
+ m_Disk5VOn = (data&0x02)?1:0;
+ m_Disk12VOn = (data&0x01)?1:0;
+
+ // ADC stuff
+ //TODO
+
+ // FDC stuff
+ // first handle the motor stuff; we'll clobber whatever was in m_floppy, then reset it to what it should be
+ m_floppy = m_floppy0->get_device();
+ m_floppy->mon_w(!(m_Disk5VOn && m_Disk12VOn)); // Disk5VOn and 12VOn can be thought of as a crude MotorOn signal as the motor won't run with either? of them missing.
+ //m_floppy = m_floppy0->get_device();
+ //m_floppy->mon_w(!(m_Disk5VOn && m_Disk12VOn)); // Disk5VOn and 12VOn can be thought of as a crude MotorOn signal as the motor won't run with either? of them missing.
+ //m_floppy = m_floppy0->get_device();
+ //m_floppy->mon_w(!(m_Disk5VOn && m_Disk12VOn)); // Disk5VOn and 12VOn can be thought of as a crude MotorOn signal as the motor won't run with either? of them missing.
+ // now restore m_floppy state to what it should be
+ if (m_DriveSel1) m_floppy = m_floppy0->get_device();
+ //else if (m_DriveSel2) m_floppy = m_floppy1->get_device();
+ //else if (m_DriveSel3) m_floppy = m_floppy2->get_device();
+ else m_floppy = nullptr;
+ m_fdc->set_floppy(m_floppy); // select the floppy
+ if (m_floppy)
+ {
+ m_floppy->ss_w(m_SideSelect);
+ }
+ // Disk5VOn and 12VOn can be thought of as a crude MotorOn signal as the motor won't run with either? of them missing.
+ //m_floppy0->mon_w(!(m_Disk5VOn && m_Disk12VOn));
+ //m_floppy1->mon_w(!(m_Disk5VOn && m_Disk12VOn));
+ //m_floppy2->mon_w(!(m_Disk5VOn && m_Disk12VOn));
+
+ // CRTC clock rate stuff
+ //TODO
+}
+
WRITE16_MEMBER( notetaker_state::LoadDispAddr_w )
{
m_DispAddr = data;
@@ -519,7 +589,7 @@ static ADDRESS_MAP_START(notetaker_iocpu_io, AS_IO, 16, notetaker_state)
AM_RANGE(0x60, 0x61) AM_MIRROR(0x7E1E) AM_WRITE(FIFOReg_w) // DAC sample and hold and frequency setup
//AM_RANGE(0xa0, 0xa1) AM_MIRROR(0x7E18) AM_DEVREADWRITE("debug8255", 8255_device, read, write) // debugger board 8255
AM_RANGE(0xc0, 0xc1) AM_MIRROR(0x7E1E) AM_WRITE(FIFOBus_w) // DAC data write to FIFO
- //AM_RANGE(0x100, 0x101) AM_MIRROR(0x7E1E) AM_WRITE(DiskReg_w) I/O register (adc speed, crtc pixel clock enable, +5 and +12v relays for floppy, etc)
+ AM_RANGE(0x100, 0x101) AM_MIRROR(0x7E1E) AM_WRITE(DiskReg_w) // I/O register (adc speed, crtc pixel clock and clock enable, +5 and +12v relays for floppy, etc)
AM_RANGE(0x120, 0x127) AM_MIRROR(0x7E18) AM_DEVREADWRITE8("wd1791", fd1791_t, read, write, 0x00FF) // floppy controller
AM_RANGE(0x140, 0x15f) AM_MIRROR(0x7E00) AM_DEVREADWRITE8("crt5027", crt5027_device, read, write, 0x00FF) // crt controller
AM_RANGE(0x160, 0x161) AM_MIRROR(0x7E1E) AM_WRITE(LoadDispAddr_w) // loads the start address for the display framebuffer
@@ -546,8 +616,8 @@ irq7 VSync (interrupt from the VSYN VSync pin from the crt5027)
/* writes during boot of io roms v2.0:
0x88 to port 0x020 (PCR; BootSeqDone(1), processor not locked(0), battery charger off(0), rom not disabled(0) correction off&cr4 off(1), cr3 on(0), cr2 on(0), cr1 on (0);)
-0x02 to port 0x100 (IOR write: enable 5v only relay control)
-0x03 to port 0x100 (IOR write: in addition to above, enable 12v relay control)
+0x0002 to port 0x100 (IOR write: enable 5v only relay control)
+0x0003 to port 0x100 (IOR write: in addition to above, enable 12v relay control)
<dram memory 0x00000-0x3ffff is zeroed here>
0x13 to port 0x000 PIC (ICW1, 8085 vector 0b000[ignored], edge trigger mode, interval of 8, single mode (no cascade/ICW3), ICW4 needed )
0x08 to port 0x002 PIC (ICW2, T7-T3 = 0b00001)
@@ -557,21 +627,30 @@ irq7 VSync (interrupt from the VSYN VSync pin from the crt5027)
0x0000 to port 0x1ae (reset UART)
0x0016 to port 0x048 (kbd control reg write)
0x0005 to port 0x1a8 (UART control reg write)
-0x5f to port 0x140 \
-0xf2 to port 0x142 \
-0x7d to port 0x144 \
-0x1d to port 0x146 \_ set up CRTC
-0x04 to port 0x148 /
-0x10 to port 0x14a /
-0x00 to port 0x154 /
-0x1e to port 0x15a /
+0x5f to port 0x140 (reg0 95 horizontal lines) \
+0xf2 to port 0x142 (reg1 interlaced, hswidth=0xE, hsdelay=2) \
+0x7d to port 0x144 (reg2 16 scans/row, 5 chars/datarow) \
+0x1d to port 0x146 (reg3 0 skew bits, 0x1D datarows/frame) \_ set up CRTC
+0x04 to port 0x148 (reg4 4 scan lines/frame /
+0x10 to port 0x14a (reg5 0x10 vdatastart) /
+0x00 to port 0x154 (reset the crtc) /
+0x1e to port 0x15a (reg8 load cursor line address = 0x1e) /
0x0a03 to port 0x100 (IOR write: set bit clock to 12Mhz)
0x2a03 to port 0x100 (IOR write: enable crtc clock chain)
0x00 to port 0x15c (fire off crtc timing chain)
read from 0x0002 (byte wide) (IMR, read interrupt mask, will be 0xFF from above)
0xaf to port 0x002 PIC (mask out with 0xEF and 0xBF to unnmask interrupts IR4(OddInt) and IR6(KbdInt), and write back to IMR)
0x0400 to 0x060 (select DAC fifo frequency 2)
-read from 0x44 (byte wide) in a loop forever (read keyboard fifo status)
+read from 0x44 (byte wide) to check input fifo status
+... more stuff here missing relating to making the beep tone through fifo
+(around pc=6b6) read keyboard uart until mouse button is clicked (WaitNoBug)
+(around pc=6bc) read keyboard uart until mouse button is released (WaitBug)
+0x2a23 to port 0x100 (select drive 1)
+0x2a23 to port 0x100 (select drive 1)
+0x3a23 to port 0x100 (unset disk separator clear (allow disk head reading))
+0x3a27 to port 0x100 (select disk side 1)
+0x3a07 to port 0x100 (unselect all drives)
+
*/
/* Emulator CPU */
@@ -606,8 +685,12 @@ void notetaker_state::machine_start()
// allocate the DAC timer, and set it to fire NEVER. We'll set it up properly in IPReset.
m_FIFO_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(notetaker_state::timer_fifoclk),this));
m_FIFO_timer->adjust(attotime::never);
- // floppy stuff
- m_floppy = NULL;
+ // FDC: /DDEN is tied permanently LOW so MFM mode is ALWAYS ON
+ m_fdc->dden_w(0);
+ // Keyboard UART: /SWE is tied permanently LOW
+ m_kbduart->set_input_pin(AY31015_SWE, 0); // status word outputs are permanently enabled (pin 16 SFD(SWE) tied low, active)
+ // EIA UART: /SWE is tied permanently LOW
+ m_eiauart->set_input_pin(AY31015_SWE, 0); // status word outputs are permanently enabled (pin 16 SFD(SWE) tied low, active)
// savestate stuff
// TODO: add me!
}
@@ -622,11 +705,12 @@ void notetaker_state::machine_reset()
/* IP Reset; this emulates the IPReset' signal */
void notetaker_state::ip_reset()
{
- // not-really-reset related, set line on Keybaord UART
- m_kbduart->set_input_pin(AY31015_SWE, 0); // status word outputs are permanently enabled (pin 16 SFD(SWE) tied low, active)
// reset the Keyboard UART
m_kbduart->set_input_pin(AY31015_XR, 0); // MR - pin 21
m_kbduart->set_input_pin(AY31015_XR, 1); // ''
+ // reset the EIA UART
+ m_eiauart->set_input_pin(AY31015_XR, 0); // MR - pin 21
+ m_eiauart->set_input_pin(AY31015_XR, 1); // ''
// reset the IPConReg latch at #f1
m_BootSeqDone = 0;
m_ProcLock = 0;
@@ -636,6 +720,9 @@ void notetaker_state::ip_reset()
m_LedInd6 = 0;
m_LedInd7 = 0;
m_LedInd8 = 0;
+ // Clear the DAC FIFO
+ for (int i=0; i<16; i++) m_outfifo[i] = 0;
+ m_outfifo_count = m_outfifo_tail_ptr = m_outfifo_head_ptr = 0;
// reset the FIFOReg latch at #h9
m_TabletYOn = 0;
m_TabletXOn = 0;
@@ -645,19 +732,37 @@ void notetaker_state::ip_reset()
m_SHConB = 0;
m_SHConA = 0;
m_SetSH = 0;
- // Clear the DAC FIFO
- for (int i=0; i<16; i++) m_outfifo[i] = 0;
- m_outfifo_count = m_outfifo_tail_ptr = m_outfifo_head_ptr = 0;
- // Reset the DAC Timer
+ // handle consequences of above
m_FIFO_timer->adjust(attotime::from_hz(((XTAL_960kHz/10)/4)/((m_FrSel0<<3)+(m_FrSel1<<2)+(m_FrSel2<<1)+1))); // FIFO timer is clocked by 960khz divided by 10 (74ls162 decade counter), divided by 4 (mc14568B with divider 1 pins set to 4), divided by 1,3,5,7,9,11,13,15 (or 0,2,4,6,8,10,12,14?)
- // stuff on display/eia board also reset by IPReset:
+ // todo: handle tablet and sample/hold stuff as well
+ // reset the DiskReg latches at #c4 and #b4 on the disk/display/eia controller board
+ m_ADCSpd0 = 0;
+ m_ADCSpd1 = 0;
+ m_StopWordClock_q = 0;
+ m_ClrDiskCont_q = 0;
+ m_ProgBitClk1 = 0;
+ m_ProgBitClk2 = 0;
+ m_ProgBitClk3 = 0;
+ m_AnSel4 = 0;
+ m_AnSel2 = 0;
+ m_AnSel1 = 0;
+ m_DriveSel1 = 0;
+ m_DriveSel2 = 0;
+ m_DriveSel3 = 0;
+ m_SideSelect = 0;
+ m_Disk5VOn = 0;
+ m_Disk12VOn = 0;
+ // handle the consequences of the above.
+ // Disk12VOn probably runs the drive motor, and MotorOn is hard-wired to low/active, so turn the motor for all drives OFF
+ m_floppy = m_floppy0->get_device();
+ m_floppy->mon_w(1);
+ //m_floppy = m_floppy1->get_device();
+ //m_floppy->mon_w(1);
+ //m_floppy = m_floppy2->get_device();
+ //m_floppy->mon_w(1);
+ m_floppy = nullptr; // select no drive
// reset the Framebuffer Display Address:
m_DispAddr = 0;
- // reset the EIA UART
- m_eiauart->set_input_pin(AY31015_XR, 0); // MR - pin 21
- m_eiauart->set_input_pin(AY31015_XR, 1); // ''
- // reset the DiskReg latches at #c4 and #b4 on the disk/display/eia board
- // write me!
}
/* EP Reset; this emulates the EPReset' signal */
diff --git a/src/mame/drivers/pcat_dyn.cpp b/src/mame/drivers/pcat_dyn.cpp
index 00b1a7df54d..4131129cb82 100644
--- a/src/mame/drivers/pcat_dyn.cpp
+++ b/src/mame/drivers/pcat_dyn.cpp
@@ -9,8 +9,8 @@ Unmodified 486 PC-AT HW.
Jet Way Information Co. OP495SLC motherboard
- AMD Am486-DX40 CPU
- Trident TVGA9000i video card
- - Breve Technologies audio adapter
- - CH Products RollerMouse serial trackball
+ - Breve Technologies audio adapter, WSS+Sound Blaster
+ - CH Products RollerMouse serial trackball, Mouse Systems compatible
preliminary driver by Angelo Salese
@@ -23,45 +23,79 @@ If the output isn't satisfactory, it prints "I/O BOARD FAILURE".
#include "emu.h"
#include "cpu/i386/i386.h"
#include "machine/pcshare.h"
-#include "video/pc_vga.h"
+#include "bus/isa/trident.h"
#include "machine/bankdev.h"
#include "machine/ds128x.h"
#include "machine/ins8250.h"
+#include "machine/nvram.h"
+#include "sound/ad1848.h"
#include "bus/rs232/rs232.h"
#include "bus/rs232/ser_mouse.h"
+#include "bus/isa/isa.h"
+#include "bus/isa/sblaster.h"
class pcat_dyn_state : public pcat_base_state
{
public:
pcat_dyn_state(const machine_config &mconfig, device_type type, const char *tag)
: pcat_base_state(mconfig, type, tag)
- , m_bank1(*this, "bank1")
- , m_bank2(*this, "bank2"){ }
-
- required_device<address_map_bank_device> m_bank1;
- required_device<address_map_bank_device> m_bank2;
+ , m_isabus(*this, "isa")
+ , m_prgbank(*this, "prgbank")
+ , m_nvram_bank(*this, "nvram_bank")
+ , m_nvram_mem(0x2000){ }
+
+ required_device<isa8_device> m_isabus;
+ required_memory_bank m_prgbank;
+ required_memory_bank m_nvram_bank;
+ std::vector<UINT8> m_nvram_mem;
DECLARE_WRITE8_MEMBER(bank1_w);
DECLARE_WRITE8_MEMBER(bank2_w);
+ DECLARE_READ8_MEMBER(audio_r);
+ DECLARE_WRITE8_MEMBER(dma8237_1_dack_w);
+ virtual void machine_start() override;
+ void nvram_init(nvram_device &nvram, void *base, size_t size);
};
+void pcat_dyn_state::machine_start()
+{
+ m_prgbank->configure_entries(0, 256, memregion("game_prg")->base(), 0x1000);
+ m_nvram_bank->configure_entries(0, 2, &m_nvram_mem[0], 0x1000);
+ machine().device<nvram_device>("nvram")->set_base(&m_nvram_mem[0], 0x2000);
+}
+
+void pcat_dyn_state::nvram_init(nvram_device &nvram, void *base, size_t size)
+{
+ memcpy(base, memregion("nvram")->base(), size);
+}
+
+READ8_MEMBER(pcat_dyn_state::audio_r)
+{
+ switch(offset)
+ {
+ case 3:
+ return 4;
+ }
+ return 0;
+}
+
WRITE8_MEMBER(pcat_dyn_state::bank1_w)
{
- m_bank1->set_bank(data);
+ m_prgbank->set_entry(data);
}
WRITE8_MEMBER(pcat_dyn_state::bank2_w)
{
- m_bank2->set_bank(data);
+ m_nvram_bank->set_entry(data & 1);
}
static ADDRESS_MAP_START( pcat_map, AS_PROGRAM, 32, pcat_dyn_state )
AM_RANGE(0x00000000, 0x0009ffff) AM_RAM
- AM_RANGE(0x000a0000, 0x000bffff) AM_DEVREADWRITE8("vga", vga_device, mem_r, mem_w, 0xffffffff)
+ AM_RANGE(0x000a0000, 0x000bffff) AM_DEVREADWRITE8("vga", trident_vga_device, mem_r, mem_w, 0xffffffff)
AM_RANGE(0x000c0000, 0x000c7fff) AM_ROM AM_REGION("video_bios", 0)
AM_RANGE(0x000d0000, 0x000d0fff) AM_ROM AM_REGION("game_prg", 0x0000) AM_WRITE8(bank1_w, 0xffffffff)
AM_RANGE(0x000d1000, 0x000d1fff) AM_ROM AM_REGION("game_prg", 0x1000) AM_WRITE8(bank2_w, 0xffffffff)
- AM_RANGE(0x000d2000, 0x000d3fff) AM_DEVICE("bank1", address_map_bank_device, amap32)
- AM_RANGE(0x000d3000, 0x000d4fff) AM_DEVICE("bank2", address_map_bank_device, amap32)
+ AM_RANGE(0x000d2000, 0x000d2fff) AM_ROMBANK("prgbank")
+ AM_RANGE(0x000d3000, 0x000d3fff) AM_RAMBANK("nvram_bank")
AM_RANGE(0x000df400, 0x000df8ff) AM_RAM //I/O board?
AM_RANGE(0x000f0000, 0x000fffff) AM_ROM AM_REGION("bios", 0 )
AM_RANGE(0x00100000, 0x001fffff) AM_RAM
@@ -70,54 +104,49 @@ ADDRESS_MAP_END
static ADDRESS_MAP_START( pcat_io, AS_IO, 32, pcat_dyn_state )
AM_IMPORT_FROM(pcat32_io_common)
- AM_RANGE(0x03b0, 0x03bf) AM_DEVREADWRITE8("vga", vga_device, port_03b0_r, port_03b0_w, 0xffffffff)
- AM_RANGE(0x03c0, 0x03cf) AM_DEVREADWRITE8("vga", vga_device, port_03c0_r, port_03c0_w, 0xffffffff)
- AM_RANGE(0x03d0, 0x03df) AM_DEVREADWRITE8("vga", vga_device, port_03d0_r, port_03d0_w, 0xffffffff)
+ AM_RANGE(0x03b0, 0x03bf) AM_DEVREADWRITE8("vga", trident_vga_device, port_03b0_r, port_03b0_w, 0xffffffff)
+ AM_RANGE(0x03c0, 0x03cf) AM_DEVREADWRITE8("vga", trident_vga_device, port_03c0_r, port_03c0_w, 0xffffffff)
+ AM_RANGE(0x03d0, 0x03df) AM_DEVREADWRITE8("vga", trident_vga_device, port_03d0_r, port_03d0_w, 0xffffffff)
AM_RANGE(0x03f8, 0x03ff) AM_DEVREADWRITE8("ns16550", ns16550_device, ins8250_r, ins8250_w, 0xffffffff)
+ AM_RANGE(0x0530, 0x0533) AM_READ8(audio_r, 0xffffffff)
+ AM_RANGE(0x0534, 0x0537) AM_DEVREADWRITE8("ad1848", ad1848_device, read, write, 0xffffffff)
ADDRESS_MAP_END
-static ADDRESS_MAP_START( bank_map, AS_0, 32, pcat_dyn_state )
- AM_RANGE(0x00000, 0xfffff) AM_ROM AM_REGION("game_prg", 0)
-ADDRESS_MAP_END
-
-#define AT_KEYB_HELPER(bit, text, key1) \
- PORT_BIT( bit, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_NAME(text) PORT_CODE(key1)
+//TODO: use atmb device
+WRITE8_MEMBER( pcat_dyn_state::dma8237_1_dack_w ){ m_isabus->dack_w(1, data); }
static INPUT_PORTS_START( pcat_dyn )
+ // M,N,Numpad 6 -- Hang
+ // Enter,Numpad 4 -- 5 Credits
PORT_START("pc_keyboard_0")
- PORT_BIT ( 0x0001, 0x0000, IPT_UNUSED ) /* unused scancode 0 */
- AT_KEYB_HELPER( 0x0002, "Esc", KEYCODE_Q ) /* Esc 01 81 */
+ PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_SERVICE) PORT_NAME("Bookkeeping")
PORT_START("pc_keyboard_1")
- AT_KEYB_HELPER( 0x0020, "Y", KEYCODE_Y ) /* Y 15 95 */
- AT_KEYB_HELPER( 0x1000, "Enter", KEYCODE_ENTER ) /* Enter 1C 9C */
+ PORT_BIT(0x1000, IP_ACTIVE_HIGH, IPT_BILL1)
PORT_START("pc_keyboard_2")
-
- PORT_START("pc_keyboard_3")
- AT_KEYB_HELPER( 0x0002, "N", KEYCODE_N ) /* N 31 B1 */
- AT_KEYB_HELPER( 0x0800, "F1", KEYCODE_S ) /* F1 3B BB */
-
- PORT_START("pc_keyboard_4")
-
- PORT_START("pc_keyboard_5")
-
- PORT_START("pc_keyboard_6")
- AT_KEYB_HELPER( 0x0040, "(MF2)Cursor Up", KEYCODE_UP ) /* Up 67 e7 */
- AT_KEYB_HELPER( 0x0080, "(MF2)Page Up", KEYCODE_PGUP ) /* Page Up 68 e8 */
- AT_KEYB_HELPER( 0x0100, "(MF2)Cursor Left", KEYCODE_LEFT ) /* Left 69 e9 */
- AT_KEYB_HELPER( 0x0200, "(MF2)Cursor Right", KEYCODE_RIGHT ) /* Right 6a ea */
- AT_KEYB_HELPER( 0x0800, "(MF2)Cursor Down", KEYCODE_DOWN ) /* Down 6c ec */
- AT_KEYB_HELPER( 0x1000, "(MF2)Page Down", KEYCODE_PGDN ) /* Page Down 6d ed */
- AT_KEYB_HELPER( 0x4000, "Del", KEYCODE_A ) /* Delete 6f ef */
-
- PORT_START("pc_keyboard_7")
+ // Don't use IPT_BUTTON1 or the mouse axes are mapped incorrectly
+ PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("Mouse Button") PORT_CODE(MOUSECODE_BUTTON1)
+ PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_COIN1)
INPUT_PORTS_END
static SLOT_INTERFACE_START(pcat_dyn_com)
- SLOT_INTERFACE("msmouse", MSFT_SERIAL_MOUSE)
+ SLOT_INTERFACE("msmouse", MSYSTEM_SERIAL_MOUSE)
SLOT_INTERFACE_END
+static SLOT_INTERFACE_START( pcat_dyn_isa8_cards )
+ SLOT_INTERFACE("sb15", ISA8_SOUND_BLASTER_1_5)
+SLOT_INTERFACE_END
+
+static DEVICE_INPUT_DEFAULTS_START( pcat_dyn_sb_def )
+ DEVICE_INPUT_DEFAULTS("CONFIG", 0x03, 0x01)
+DEVICE_INPUT_DEFAULTS_END
+
+static MACHINE_CONFIG_FRAGMENT( pcat_dyn_sb_conf )
+ MCFG_DEVICE_MODIFY("pc_joy")
+ MCFG_DEVICE_SLOT_INTERFACE(pc_joysticks, nullptr, true) // remove joystick
+MACHINE_CONFIG_END
+
static MACHINE_CONFIG_START( pcat_dyn, pcat_dyn_state )
/* basic machine hardware */
MCFG_CPU_ADD("maincpu", I486, 40000000) /* Am486 DX-40 */
@@ -126,9 +155,10 @@ static MACHINE_CONFIG_START( pcat_dyn, pcat_dyn_state )
MCFG_CPU_IRQ_ACKNOWLEDGE_DEVICE("pic8259_1", pic8259_device, inta_cb)
/* video hardware */
- MCFG_FRAGMENT_ADD( pcvideo_vga )
+ MCFG_FRAGMENT_ADD( pcvideo_trident_vga )
MCFG_SCREEN_MODIFY("screen")
MCFG_SCREEN_REFRESH_RATE(60)
+ MCFG_DEVICE_REPLACE("vga", TVGA9000_VGA, 0)
MCFG_FRAGMENT_ADD( pcat_common )
@@ -137,18 +167,15 @@ static MACHINE_CONFIG_START( pcat_dyn, pcat_dyn_state )
MCFG_MC146818_IRQ_HANDLER(DEVWRITELINE("pic8259_2", pic8259_device, ir0_w))
MCFG_MC146818_CENTURY_INDEX(0x32)
- MCFG_DEVICE_ADD("bank1", ADDRESS_MAP_BANK, 0)
- MCFG_DEVICE_PROGRAM_MAP(bank_map)
- MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE)
- MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(32)
- MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(20)
- MCFG_ADDRESS_MAP_BANK_STRIDE(0x1000)
- MCFG_DEVICE_ADD("bank2", ADDRESS_MAP_BANK, 0)
- MCFG_DEVICE_PROGRAM_MAP(bank_map)
- MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE)
- MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(32)
- MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(20)
- MCFG_ADDRESS_MAP_BANK_STRIDE(0x1000)
+ MCFG_SOUND_ADD("ad1848", AD1848, 0)
+ MCFG_AD1848_IRQ_CALLBACK(DEVWRITELINE("pic8259_1", pic8259_device, ir5_w))
+ MCFG_AD1848_DRQ_CALLBACK(DEVWRITELINE("dma8237_1", am9517a_device, dreq0_w))
+
+ MCFG_DEVICE_MODIFY("dma8237_1")
+ MCFG_I8237_OUT_IOW_0_CB(DEVWRITE8("ad1848", ad1848_device, dack_w))
+ MCFG_I8237_OUT_IOW_1_CB(WRITE8(pcat_dyn_state, dma8237_1_dack_w))
+
+ MCFG_NVRAM_ADD_CUSTOM_DRIVER("nvram", pcat_dyn_state, nvram_init)
MCFG_DEVICE_ADD( "ns16550", NS16550, XTAL_1_8432MHz )
MCFG_INS8250_OUT_TX_CB(DEVWRITELINE("serport", rs232_port_device, write_txd))
@@ -162,6 +189,22 @@ static MACHINE_CONFIG_START( pcat_dyn, pcat_dyn_state )
MCFG_RS232_DSR_HANDLER(DEVWRITELINE("ns16550", ins8250_uart_device, dsr_w))
MCFG_RS232_RI_HANDLER(DEVWRITELINE("ns16550", ins8250_uart_device, ri_w))
MCFG_RS232_CTS_HANDLER(DEVWRITELINE("ns16550", ins8250_uart_device, cts_w))
+
+ MCFG_DEVICE_ADD("isa", ISA8, 0)
+ MCFG_ISA8_CPU(":maincpu")
+ MCFG_ISA_OUT_IRQ2_CB(DEVWRITELINE("pic8259_2", pic8259_device, ir2_w))
+ MCFG_ISA_OUT_IRQ3_CB(DEVWRITELINE("pic8259_1", pic8259_device, ir3_w))
+ //MCFG_ISA_OUT_IRQ4_CB(DEVWRITELINE("pic8259_1", pic8259_device, ir4_w))
+ //MCFG_ISA_OUT_IRQ5_CB(DEVWRITELINE("pic8259_1", pic8259_device, ir5_w))
+ MCFG_ISA_OUT_IRQ6_CB(DEVWRITELINE("pic8259_1", pic8259_device, ir6_w))
+ MCFG_ISA_OUT_IRQ7_CB(DEVWRITELINE("pic8259_1", pic8259_device, ir7_w))
+ MCFG_ISA_OUT_DRQ1_CB(DEVWRITELINE("dma8237_1", am9517a_device, dreq1_w))
+ MCFG_ISA_OUT_DRQ2_CB(DEVWRITELINE("dma8237_1", am9517a_device, dreq2_w))
+ MCFG_ISA_OUT_DRQ3_CB(DEVWRITELINE("dma8237_1", am9517a_device, dreq3_w))
+
+ MCFG_ISA8_SLOT_ADD("isa", "isa1", pcat_dyn_isa8_cards, "sb15", true)
+ MCFG_DEVICE_CARD_DEVICE_INPUT_DEFAULTS("sb15", pcat_dyn_sb_def)
+ MCFG_DEVICE_CARD_MACHINE_CONFIG("sb15", pcat_dyn_sb_conf)
MACHINE_CONFIG_END
/***************************************
@@ -182,9 +225,12 @@ ROM_START(toursol)
ROM_LOAD("sol.u21", 0x00000, 0x40000, CRC(e97724d9) SHA1(995b89d129c371b815c6b498093bd1bbf9fd8755))
ROM_LOAD("sol.u22", 0x40000, 0x40000, CRC(69d42f50) SHA1(737fe62f3827b00b4f6f3b72ef6c7b6740947e95))
ROM_LOAD("sol.u23", 0x80000, 0x40000, CRC(d1e39bd4) SHA1(39c7ee43cddb53fba0f7c0572ddc40289c4edd07))
- ROM_LOAD("sol.u24", 0xa0000, 0x40000, CRC(555341e0) SHA1(81fee576728855e234ff7aae06f54ae9705c3ab5))
- ROM_LOAD("sol.u28", 0xe0000, 0x02000, CRC(c9374d50) SHA1(49173bc69f70bb2a7e8af9d03e2538b34aa881d8))
+ ROM_LOAD("sol.u24", 0xc0000, 0x40000, CRC(555341e0) SHA1(81fee576728855e234ff7aae06f54ae9705c3ab5))
ROM_FILL(0x2a3e6, 1, 0xeb) // skip prot(?) check
+ ROM_FILL(0x51bd2, 2, 0x90) // opl2 probe expects timer expiration too quickly
+
+ ROM_REGION(0x2000, "nvram", 0)
+ ROM_LOAD("sol.u28", 0, 0x2000, CRC(c9374d50) SHA1(49173bc69f70bb2a7e8af9d03e2538b34aa881d8))
ROM_REGION(128, "rtc", 0)
ROM_LOAD("rtc", 0, 128, BAD_DUMP CRC(732f64c8) SHA1(5386eac3afef9b16af8dd7766e577f7ac700d9cc))
@@ -203,13 +249,15 @@ ROM_START(toursol1)
ROM_LOAD("prom.0", 0x00000, 0x40000, CRC(f26ce73f) SHA1(5516c31aa18716a47f46e412fc273ae8784d2061))
ROM_LOAD("prom.1", 0x40000, 0x40000, CRC(8f96e2a8) SHA1(bc3ce8b99e6ff40e355df2c3f797f1fe88b3b219))
ROM_LOAD("prom.2", 0x80000, 0x40000, CRC(8b0ac5cf) SHA1(1c2b6a53c9ff4d18a5227d899facbbc719f40205))
- ROM_LOAD("prom.3", 0xa0000, 0x40000, CRC(9352e965) SHA1(2bfb647ec27c60a8c821fdf7483199e1a444cea8))
- ROM_LOAD("prom.7", 0xe0000, 0x02000, CRC(154c8092) SHA1(4439ee82f36d5d5c334494ba7bb4848e839213a7))
+ ROM_LOAD("prom.3", 0xc0000, 0x40000, CRC(9352e965) SHA1(2bfb647ec27c60a8c821fdf7483199e1a444cea8))
+
+ ROM_REGION(0x2000, "nvram", 0)
+ ROM_LOAD("prom.7", 0, 0x2000, CRC(154c8092) SHA1(4439ee82f36d5d5c334494ba7bb4848e839213a7))
ROM_REGION(128, "rtc", 0)
ROM_LOAD("rtc", 0, 128, BAD_DUMP CRC(732f64c8) SHA1(5386eac3afef9b16af8dd7766e577f7ac700d9cc))
ROM_END
-GAME( 1995, toursol, 0, pcat_dyn, pcat_dyn, driver_device, 0, ROT0, "Dynamo", "Tournament Solitaire (V1.06, 08/03/95)", MACHINE_NOT_WORKING|MACHINE_NO_SOUND )
+GAME( 1995, toursol, 0, pcat_dyn, pcat_dyn, driver_device, 0, ROT0, "Dynamo", "Tournament Solitaire (V1.06, 08/03/95)", MACHINE_UNEMULATED_PROTECTION )
GAME( 1995, toursol1, toursol, pcat_dyn, pcat_dyn, driver_device, 0, ROT0, "Dynamo", "Tournament Solitaire (V1.04, 06/22/95)", MACHINE_NOT_WORKING|MACHINE_NO_SOUND )
diff --git a/src/mame/drivers/r9751.cpp b/src/mame/drivers/r9751.cpp
index fd93f310e2e..89cd7da81b0 100644
--- a/src/mame/drivers/r9751.cpp
+++ b/src/mame/drivers/r9751.cpp
@@ -51,6 +51,7 @@
#define TRACE_SMIOC 0
#define TRACE_CPU_REG 0
#define TRACE_LED 0
+#define TRACE_DMA 0
class r9751_state : public driver_device
{
@@ -116,14 +117,16 @@ READ8_MEMBER(r9751_state::pdc_dma_r)
{
/* This callback function takes the value written to 0xFF01000C as the bank offset */
UINT32 address = (fdd_dma_bank & 0x7FFFF800) + (offset&0xFFFF);
+ if(TRACE_DMA) logerror("DMA READ: %08X DATA: %08X\n", address, m_maincpu->space(AS_PROGRAM).read_byte(address));
return m_maincpu->space(AS_PROGRAM).read_byte(address);
}
WRITE8_MEMBER(r9751_state::pdc_dma_w)
{
/* This callback function takes the value written to 0xFF01000C as the bank offset */
- UINT32 address = (fdd_dma_bank & 0x7FFFF800) + (data&0xFFFF);
- m_maincpu->space(AS_PROGRAM).write_byte(m_pdc->fdd_68k_dma_address,address);
+ UINT32 address = (fdd_dma_bank & 0x7FFFF800) + (m_pdc->fdd_68k_dma_address&0xFFFF);
+ m_maincpu->space(AS_PROGRAM).write_byte(address,data);
+ if(TRACE_DMA) logerror("DMA WRITE: %08X DATA: %08X\n", address,data);
}
DRIVER_INIT_MEMBER(r9751_state,r9751)
@@ -177,7 +180,7 @@ READ32_MEMBER( r9751_state::r9751_mmio_5ff_r )
return 0;
case 0x30B0: /* FDD command completion status */
data = (m_pdc->reg_p5 << 8) + m_pdc->reg_p4;
- if(TRACE_FDC) logerror("--- SCSI FDD command completion status - Read: %08X, From: %08X, Register: %08X\n", data, space.machine().firstcpu->pc(), offset << 2 | 0x5FF00000);
+ if(TRACE_FDC && data != 0) logerror("--- SCSI FDD command completion status - Read: %08X, From: %08X, Register: %08X\n", data, space.machine().firstcpu->pc(), offset << 2 | 0x5FF00000);
return data;
default:
if(TRACE_FDC || TRACE_HDC || TRACE_SMIOC) logerror("Instruction: %08x READ MMIO(%08x): %08x & %08x\n", space.machine().firstcpu->pc(), offset << 2 | 0x5FF00000, 0, mem_mask);
@@ -229,7 +232,7 @@ WRITE32_MEMBER( r9751_state::r9751_mmio_5ff_w )
if(TRACE_FDC) logerror("--- FDD Command: %08X, From: %08X, Register: %08X\n", data, space.machine().firstcpu->pc(), offset << 2 | 0x5FF00000);
break;
case 0x04B0: /* FDD RESET PDC */
- if(TRACE_FDC) logerror("PDC RESET, PC: %08X\n", space.machine().firstcpu->pc());
+ if(TRACE_FDC) logerror("PDC RESET, PC: %08X DATA: %08X\n", space.machine().firstcpu->pc(),data);
m_pdc->reset();
break;
case 0x08B0: /* FDD SCSI read command */
@@ -249,16 +252,16 @@ WRITE32_MEMBER( r9751_state::r9751_mmio_5ff_w )
m_pdc->reg_p38 |= 0x2; /* Set bit 1 on port 38 register, PDC polls this port looking for a command */
if(TRACE_FDC) logerror("--- FDD Old Command: %02X and %02X\n", data_b0, data_b1);
break;
- case 0x80B0: /* fdd_dest_address register */
+ case 0xC0B0:
+ case 0xC1B0: /* fdd_dest_address register */
fdd_dest_address = data << 1;
- if(TRACE_FDC) logerror("--- FDD destination address: %08X\n", fdd_dest_address);
+ if(TRACE_FDC) logerror("--- FDD destination address: %08X PC: %08X Register: %08X\n", (fdd_dma_bank & 0x7FFFF800) + (fdd_dest_address&0xFFFF), space.machine().firstcpu->pc(), offset << 2 | 0x5FF00000);
data_b0 = data & 0xFF;
data_b1 = (data & 0xFF00) >> 8;
m_pdc->reg_p6 = data_b0;
m_pdc->reg_p7 = data_b1;
break;
- case 0xC0B0:
- case 0xC1B0: /* FDD command address register */
+ case 0x80B0: /* FDD command address register */
UINT32 fdd_scsi_command;
UINT32 fdd_scsi_command2;
unsigned char c_fdd_scsi_command[8]; // Array for SCSI command
@@ -269,14 +272,14 @@ WRITE32_MEMBER( r9751_state::r9751_mmio_5ff_w )
m_pdc->reg_p5 = 0;
/* Send FDD SCSI command location address to PDC 0x2, 0x3 */
- if(TRACE_FDC) logerror("--- FDD command address: %08X\n", data);
+ if(TRACE_FDC) logerror("--- FDD command address: %08X PC: %08X Register: %08X\n", (fdd_dma_bank & 0x7FFFF800) + ((data << 1)&0xFFFF), space.machine().firstcpu->pc(), offset << 2 | 0x5FF00000);
data_b0 = data & 0xFF;
data_b1 = (data & 0xFF00) >> 8;
m_pdc->reg_p2 = data_b0;
m_pdc->reg_p3 = data_b1;
- fdd_scsi_command = swap_uint32(m_mem->read_dword(data << 1));
- fdd_scsi_command2 = swap_uint32(m_mem->read_dword((data << 1)+4));
+ fdd_scsi_command = swap_uint32(m_mem->read_dword((fdd_dma_bank & 0x7FFFF800) + ((data << 1)&0xFFFF)));
+ fdd_scsi_command2 = swap_uint32(m_mem->read_dword(((fdd_dma_bank & 0x7FFFF800) + ((data << 1)&0xFFFF))+4));
memcpy(c_fdd_scsi_command,&fdd_scsi_command,4);
memcpy(c_fdd_scsi_command+4,&fdd_scsi_command2,4);
@@ -326,11 +329,14 @@ WRITE32_MEMBER( r9751_state::r9751_mmio_ff01_w )
{
case 0x000C: /* FDD DMA Offset */
fdd_dma_bank = data;
+ if(TRACE_DMA) logerror("Banking register(FDD): %08X PC: %08X Data: %08X\n", offset << 2 | 0xFF010000, space.machine().firstcpu->pc(), data);
return;
case 0x0010: /* SMIOC DMA Offset */
smioc_dma_bank = data;
+ if(TRACE_DMA) logerror("Banking register(SMIOC): %08X PC: %08X Data: %08X\n", offset << 2 | 0xFF010000, space.machine().firstcpu->pc(), data);
return;
default:
+ if(TRACE_DMA) logerror("Banking register(Unknown): %08X PC: %08X Data: %08X\n", offset << 2 | 0xFF010000, space.machine().firstcpu->pc(), data);
return;
}
}
@@ -376,6 +382,7 @@ WRITE32_MEMBER( r9751_state::r9751_mmio_ff05_w )
return;
case 0x0320:
timer_32khz_last = machine().time();
+ return;
default:
if(TRACE_CPU_REG) logerror("Instruction: %08x WRITE MMIO(%08x): %08x & %08x\n", space.machine().firstcpu->pc(), offset << 2 | 0xFF050000, data, mem_mask);
return;
diff --git a/src/mame/drivers/shanghai.cpp b/src/mame/drivers/shanghai.cpp
index 1aeb26c541f..e5f10928555 100644
--- a/src/mame/drivers/shanghai.cpp
+++ b/src/mame/drivers/shanghai.cpp
@@ -6,12 +6,10 @@ Shanghai
driver by Nicola Salmoria
-The end of round animation in Shanghai is wrong; change the opcode at 0xfb1f2
-to a NOP to jump to it immediately at the beginning of a round.
-
-I'm not sure about the refresh rate, 60Hz makes time match the dip switch
-settings, but music runs too fast.
-
+TODO:
+- games are currently too fast (especially noticeable with kothello screen transitions), either irqs actually
+ fires every two frames or a HD63484 SR bit isn't behaving correctly;
+- minor glitch with gfx copy on shanghai stage info panel (garbage on right);
* kothello
@@ -24,7 +22,7 @@ displayed.
#include "emu.h"
#include "cpu/nec/nec.h"
#include "audio/seibu.h"
-#include "video/hd63484.h"
+#include "video/h63484.h"
class shanghai_state : public driver_device
@@ -32,20 +30,14 @@ class shanghai_state : public driver_device
public:
shanghai_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag),
- m_maincpu(*this, "maincpu"),
- m_hd63484(*this, "hd63484") { }
+ m_maincpu(*this, "maincpu") { }
required_device<cpu_device> m_maincpu;
- required_device<hd63484_device> m_hd63484;
DECLARE_WRITE16_MEMBER(shanghai_coin_w);
- DECLARE_READ16_MEMBER(kothello_hd63484_status_r);
- virtual void video_start() override;
DECLARE_PALETTE_INIT(shanghai);
- UINT32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
-
INTERRUPT_GEN_MEMBER(interrupt);
};
@@ -80,57 +72,6 @@ PALETTE_INIT_MEMBER(shanghai_state,shanghai)
}
}
-void shanghai_state::video_start()
-{
-}
-
-UINT32 shanghai_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
-{
- int x, y, b, src;
-
- address_space &space = machine().driver_data()->generic_space();
- b = ((m_hd63484->regs_r(space, 0xcc/2, 0xffff) & 0x000f) << 16) + m_hd63484->regs_r(space, 0xce/2, 0xffff);
- for (y = 0; y < 280; y++)
- {
- for (x = 0 ; x < (m_hd63484->regs_r(space, 0xca/2, 0xffff) & 0x0fff) * 2 ; x += 2)
- {
- b &= (HD63484_RAM_SIZE - 1);
- src = m_hd63484->ram_r(space, b, 0xffff);
- bitmap.pix16(y, x) = src & 0x00ff;
- bitmap.pix16(y, x + 1) = (src & 0xff00) >> 8;
- b++;
- }
- }
-
- if ((m_hd63484->regs_r(space, 0x06/2, 0xffff) & 0x0300) == 0x0300)
- {
- int sy = (m_hd63484->regs_r(space, 0x94/2, 0xffff) & 0x0fff) - (m_hd63484->regs_r(space, 0x88/2, 0xffff) >> 8);
- int h = m_hd63484->regs_r(space, 0x96/2, 0xffff) & 0x0fff;
- int sx = ((m_hd63484->regs_r(space, 0x92/2, 0xffff) >> 8) - (m_hd63484->regs_r(space, 0x84/2, 0xffff) >> 8)) * 4;
- int w = (m_hd63484->regs_r(space, 0x92/2, 0xffff) & 0xff) * 4;
- if (sx < 0) sx = 0; // not sure about this (shangha2 title screen)
-
- b = (((m_hd63484->regs_r(space, 0xdc/2, 0xffff) & 0x000f) << 16) + m_hd63484->regs_r(space, 0xde/2, 0xffff));
-
- for (y = sy ; y <= sy + h && y < 280 ; y++)
- {
- for (x = 0 ; x < (m_hd63484->regs_r(space, 0xca/2, 0xffff) & 0x0fff) * 2 ; x += 2)
- {
- b &= (HD63484_RAM_SIZE - 1);
- src = m_hd63484->ram_r(space, b, 0xffff);
- if (x <= w && x + sx >= 0 && x + sx < (m_hd63484->regs_r(space, 0xca/2, 0xffff) & 0x0fff) * 2)
- {
- bitmap.pix16(y, x + sx) = src & 0x00ff;
- bitmap.pix16(y, x + sx + 1) = (src & 0xff00) >> 8;
- }
- b++;
- }
- }
- }
-
- return 0;
-}
-
INTERRUPT_GEN_MEMBER(shanghai_state::interrupt)
{
device.execute().set_input_line_and_vector(0,HOLD_LINE,0x80);
@@ -159,8 +100,8 @@ ADDRESS_MAP_END
static ADDRESS_MAP_START( shanghai_portmap, AS_IO, 16, shanghai_state )
- AM_RANGE(0x00, 0x01) AM_DEVREADWRITE("hd63484", hd63484_device, status_r, address_w)
- AM_RANGE(0x02, 0x03) AM_DEVREADWRITE("hd63484", hd63484_device, data_r, data_w)
+ AM_RANGE(0x00, 0x01) AM_DEVREADWRITE("h63484", h63484_device, status_r, address_w)
+ AM_RANGE(0x02, 0x03) AM_DEVREADWRITE("h63484", h63484_device, data_r, data_w)
AM_RANGE(0x20, 0x23) AM_DEVREADWRITE8("ymsnd", ym2203_device, read, write, 0x00ff)
AM_RANGE(0x40, 0x41) AM_READ_PORT("P1")
AM_RANGE(0x44, 0x45) AM_READ_PORT("P2")
@@ -173,21 +114,16 @@ static ADDRESS_MAP_START( shangha2_portmap, AS_IO, 16, shanghai_state )
AM_RANGE(0x00, 0x01) AM_READ_PORT("P1")
AM_RANGE(0x10, 0x11) AM_READ_PORT("P2")
AM_RANGE(0x20, 0x21) AM_READ_PORT("SYSTEM")
- AM_RANGE(0x30, 0x31) AM_DEVREADWRITE("hd63484", hd63484_device, status_r, address_w)
- AM_RANGE(0x32, 0x33) AM_DEVREADWRITE("hd63484", hd63484_device, data_r, data_w)
+ AM_RANGE(0x30, 0x31) AM_DEVREADWRITE("h63484", h63484_device, status_r, address_w)
+ AM_RANGE(0x32, 0x33) AM_DEVREADWRITE("h63484", h63484_device, data_r, data_w)
AM_RANGE(0x40, 0x43) AM_DEVREADWRITE8("ymsnd", ym2203_device, read, write, 0x00ff)
AM_RANGE(0x50, 0x51) AM_WRITE(shanghai_coin_w)
ADDRESS_MAP_END
-READ16_MEMBER(shanghai_state::kothello_hd63484_status_r)
-{
- return 0xff22; /* write FIFO ready + command end + read FIFO ready */
-}
-
static ADDRESS_MAP_START( kothello_map, AS_PROGRAM, 16, shanghai_state )
AM_RANGE(0x00000, 0x07fff) AM_RAM
- AM_RANGE(0x08010, 0x08011) AM_READ(kothello_hd63484_status_r) AM_DEVWRITE("hd63484", hd63484_device, address_w)
- AM_RANGE(0x08012, 0x08013) AM_DEVREADWRITE("hd63484", hd63484_device, data_r, data_w)
+ AM_RANGE(0x08010, 0x08011) AM_DEVREADWRITE("h63484", h63484_device, status_r, address_w)
+ AM_RANGE(0x08012, 0x08013) AM_DEVREADWRITE("h63484", h63484_device, data_r, data_w)
AM_RANGE(0x09010, 0x09011) AM_READ_PORT("P1")
AM_RANGE(0x09012, 0x09013) AM_READ_PORT("P2")
AM_RANGE(0x09014, 0x09015) AM_READ_PORT("SYSTEM")
@@ -418,6 +354,9 @@ static INPUT_PORTS_START( shangha2 )
PORT_DIPSETTING( 0x80, DEF_STR( 1C_4C ) )
INPUT_PORTS_END
+static ADDRESS_MAP_START( h63484_map, AS_0, 16, shanghai_state )
+ AM_RANGE(0x00000, 0x3ffff) AM_RAM
+ADDRESS_MAP_END
static MACHINE_CONFIG_START( shanghai, shanghai_state )
@@ -429,19 +368,19 @@ static MACHINE_CONFIG_START( shanghai, shanghai_state )
/* video hardware */
MCFG_SCREEN_ADD("screen", RASTER)
- MCFG_SCREEN_REFRESH_RATE(30)
+ MCFG_SCREEN_REFRESH_RATE(57)
+ //MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500))
MCFG_SCREEN_SIZE(384, 280)
- MCFG_SCREEN_VISIBLE_AREA(0, 384-1, 0, 280-1) // Base Screen is 384 pixel
- MCFG_SCREEN_UPDATE_DRIVER(shanghai_state, screen_update)
+ MCFG_SCREEN_VISIBLE_AREA(0, 384-1, 0, 280-1)
+ MCFG_SCREEN_UPDATE_DEVICE("h63484", h63484_device, update_screen)
MCFG_SCREEN_PALETTE("palette")
MCFG_PALETTE_ADD("palette", 256)
MCFG_PALETTE_FORMAT(xxxxBBBBGGGGRRRR)
MCFG_PALETTE_INIT_OWNER(shanghai_state,shanghai)
- // TODO: convert to use H63484
- MCFG_DEVICE_ADD("hd63484", HD63484, 0)
-
+ MCFG_H63484_ADD("h63484", 0, h63484_map)
+
/* sound hardware */
MCFG_SPEAKER_STANDARD_MONO("mono")
@@ -465,17 +404,17 @@ static MACHINE_CONFIG_START( shangha2, shanghai_state )
/* video hardware */
MCFG_SCREEN_ADD("screen", RASTER)
- MCFG_SCREEN_REFRESH_RATE(30)
+ MCFG_SCREEN_REFRESH_RATE(57)
+ //MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500))
MCFG_SCREEN_SIZE(384, 280)
- MCFG_SCREEN_VISIBLE_AREA(0, 384-1, 0, 280-1) // Base Screen is 384 pixel
- MCFG_SCREEN_UPDATE_DRIVER(shanghai_state, screen_update)
+ MCFG_SCREEN_VISIBLE_AREA(0, 384-1, 0, 280-1)
+ MCFG_SCREEN_UPDATE_DEVICE("h63484", h63484_device, update_screen)
MCFG_SCREEN_PALETTE("palette")
MCFG_PALETTE_ADD("palette", 256)
MCFG_PALETTE_FORMAT(xxxxBBBBGGGGRRRR)
- // TODO: convert to use H63484
- MCFG_DEVICE_ADD("hd63484", HD63484, 0)
+ MCFG_H63484_ADD("h63484", 0, h63484_map)
/* sound hardware */
MCFG_SPEAKER_STANDARD_MONO("mono")
@@ -503,17 +442,17 @@ static MACHINE_CONFIG_START( kothello, shanghai_state )
/* video hardware */
MCFG_SCREEN_ADD("screen", RASTER)
- MCFG_SCREEN_REFRESH_RATE(30) /* Should be 57Hz, but plays too fast */
+ MCFG_SCREEN_REFRESH_RATE(57)
+ //MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500))
MCFG_SCREEN_SIZE(384, 280)
- MCFG_SCREEN_VISIBLE_AREA(8, 384-1, 0, 250-1) // Base Screen is 376 pixel
- MCFG_SCREEN_UPDATE_DRIVER(shanghai_state, screen_update)
+ MCFG_SCREEN_VISIBLE_AREA(0, 384-1, 0, 280-1)
+ MCFG_SCREEN_UPDATE_DEVICE("h63484", h63484_device, update_screen)
MCFG_SCREEN_PALETTE("palette")
MCFG_PALETTE_ADD("palette", 256)
MCFG_PALETTE_FORMAT(xxxxBBBBGGGGRRRR)
- // TODO: convert to use H63484
- MCFG_DEVICE_ADD("hd63484", HD63484, 0)
+ MCFG_H63484_ADD("h63484", 0, h63484_map)
/* sound hardware */
MCFG_SPEAKER_STANDARD_MONO("mono")
diff --git a/src/mame/drivers/ssem.cpp b/src/mame/drivers/ssem.cpp
index 278d02518fb..dac314aa9eb 100644
--- a/src/mame/drivers/ssem.cpp
+++ b/src/mame/drivers/ssem.cpp
@@ -416,6 +416,7 @@ void ssem_state::glyph_print(bitmap_rgb32 &bitmap, INT32 x, INT32 y, Format &&fm
{
const rectangle &visarea = m_screen->visible_area();
+ m_glyph_print_buf.clear();
m_glyph_print_buf.seekp(0, util::ovectorstream::beg);
util::stream_format(m_glyph_print_buf, std::forward<Format>(fmt), std::forward<Params>(args)...);
m_glyph_print_buf.put('\0');
diff --git a/src/mame/drivers/svi318.cpp b/src/mame/drivers/svi318.cpp
index 2529508e2b3..37d7920a232 100644
--- a/src/mame/drivers/svi318.cpp
+++ b/src/mame/drivers/svi318.cpp
@@ -22,10 +22,18 @@
#include "formats/svi_cas.h"
#include "bus/generic/slot.h"
#include "bus/generic/carts.h"
+#include "bus/svi3x8/expander/expander.h"
#include "softlist.h"
//**************************************************************************
+// CONSTANTS & MACROS
+//**************************************************************************
+
+#define IS_SVI328 (m_ram->size() == 64 * 1024)
+
+
+//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
@@ -39,18 +47,33 @@ public:
m_basic(*this, "basic"),
m_speaker(*this, "speaker"),
m_cassette(*this, "cassette"),
- m_cart(*this, "cartslot"),
+ m_cart_rom(*this, "cartslot"),
+ m_expander(*this, "exp"),
m_keyboard(*this, "KEY"),
m_buttons(*this, "BUTTONS"),
+ m_intvdp(0), m_intexp(0),
+ m_romdis(1), m_ramdis(1),
+ m_cart(1), m_bk21(1),
+ m_rom2(1), m_rom3(1),
m_keyboard_row(0)
{}
DECLARE_READ8_MEMBER( ppi_port_a_r );
DECLARE_READ8_MEMBER( ppi_port_b_r );
DECLARE_WRITE8_MEMBER( ppi_port_c_w );
- DECLARE_WRITE8_MEMBER( psg_port_b_w );
+ DECLARE_WRITE8_MEMBER( bank_w );
DECLARE_WRITE_LINE_MEMBER( intvdp_w );
+ READ8_MEMBER( page1_r );
+ WRITE8_MEMBER( page1_w );
+ READ8_MEMBER( page2_r );
+ WRITE8_MEMBER( page2_w );
+
+ // from expander bus
+ DECLARE_WRITE_LINE_MEMBER( intexp_w );
+ DECLARE_WRITE_LINE_MEMBER( romdis_w );
+ DECLARE_WRITE_LINE_MEMBER( ramdis_w );
+
DECLARE_DEVICE_IMAGE_LOAD_MEMBER(cartridge);
protected:
@@ -58,17 +81,25 @@ protected:
virtual void machine_reset() override;
private:
- void reset_memory_configuration();
-
required_device<cpu_device> m_maincpu;
required_device<ram_device> m_ram;
required_memory_region m_basic;
required_device<speaker_sound_device> m_speaker;
required_device<cassette_image_device> m_cassette;
- required_device<generic_slot_device> m_cart;
+ required_device<generic_slot_device> m_cart_rom;
+ required_device<svi_expander_device> m_expander;
required_ioport_array<16> m_keyboard;
required_ioport m_buttons;
+ int m_intvdp;
+ int m_intexp;
+ int m_romdis;
+ int m_ramdis;
+ int m_cart;
+ int m_bk21;
+ int m_rom2;
+ int m_rom3;
+
UINT8 m_keyboard_row;
};
@@ -79,10 +110,13 @@ private:
static ADDRESS_MAP_START( svi3x8_mem, AS_PROGRAM, 8, svi3x8_state )
ADDRESS_MAP_UNMAP_HIGH
+ AM_RANGE(0x0000, 0x7fff) AM_READWRITE(page1_r, page1_w)
+ AM_RANGE(0x8000, 0xffff) AM_READWRITE(page2_r, page2_w)
ADDRESS_MAP_END
static ADDRESS_MAP_START( svi3x8_io, AS_IO, 8, svi3x8_state )
ADDRESS_MAP_GLOBAL_MASK(0xff)
+ AM_RANGE(0x00, 0x7f) AM_DEVREADWRITE("exp", svi_expander_device, iorq_r, iorq_w)
AM_RANGE(0x80, 0x80) AM_MIRROR(0x22) AM_DEVWRITE("vdp", tms9928a_device, vram_write)
AM_RANGE(0x81, 0x81) AM_MIRROR(0x22) AM_DEVWRITE("vdp", tms9928a_device, register_write)
AM_RANGE(0x84, 0x84) AM_MIRROR(0x22) AM_DEVREAD("vdp", tms9928a_device, vram_read)
@@ -261,7 +295,8 @@ WRITE_LINE_MEMBER( svi3x8_state::intvdp_w )
{
// note: schematics show a CNTRL line that allows switching between
// IRQ and NMI for the interrupt
- m_maincpu->set_input_line(INPUT_LINE_IRQ0, state);
+ m_intvdp = state;
+ m_maincpu->set_input_line(INPUT_LINE_IRQ0, (m_intvdp || m_intexp) ? ASSERT_LINE : CLEAR_LINE);
}
@@ -269,69 +304,110 @@ WRITE_LINE_MEMBER( svi3x8_state::intvdp_w )
// MACHINE EMULATION
//**************************************************************************
-void svi3x8_state::reset_memory_configuration()
-{
- m_maincpu->space(AS_PROGRAM).install_rom(0x0000, 0x7fff, m_basic->base());
-
- if (m_ram->size() == 64 * 1024)
- {
- // SVI-328
- m_maincpu->space(AS_PROGRAM).install_ram(0x8000, 0xffff, m_ram->pointer());
- }
- else
- {
- // SVI-318
- m_maincpu->space(AS_PROGRAM).unmap_readwrite(0x8000, 0xbfff);
- m_maincpu->space(AS_PROGRAM).install_ram(0xc000, 0xffff, m_ram->pointer());
- }
-}
-
void svi3x8_state::machine_start()
{
// register for save states
+ save_item(NAME(m_intvdp));
+ save_item(NAME(m_intexp));
+ save_item(NAME(m_romdis));
+ save_item(NAME(m_ramdis));
+ save_item(NAME(m_cart));
+ save_item(NAME(m_bk21));
+ save_item(NAME(m_rom2));
+ save_item(NAME(m_rom3));
save_item(NAME(m_keyboard_row));
}
void svi3x8_state::machine_reset()
{
- reset_memory_configuration();
+ m_intvdp = 0;
+ m_intexp = 0;
+ m_romdis = 1;
+ m_ramdis = 1;
+ m_cart = 1;
+ m_bk21 = 1;
+}
+
+READ8_MEMBER( svi3x8_state::page1_r)
+{
+ // cartridge /CCS1 and /CCS2
+ if (m_cart == 0)
+ return m_cart_rom->read_rom(space, offset);
+
+ UINT8 data = m_expander->mreq_r(space, offset);
+
+ if (m_romdis == 1)
+ data = m_basic->u8(offset);
+
+ if (m_bk21 == 0 && IS_SVI328)
+ data = m_ram->read(offset);
+
+ return data;
+}
+
+WRITE8_MEMBER( svi3x8_state::page1_w)
+{
+ if (m_cart == 0)
+ return;
+
+ m_expander->mreq_w(space, offset, data);
+
+ if (m_bk21 == 0 && IS_SVI328)
+ m_ram->write(offset, data);
}
-WRITE8_MEMBER( svi3x8_state::psg_port_b_w )
+READ8_MEMBER( svi3x8_state::page2_r)
{
- reset_memory_configuration();
-
- // CART
- if (BIT(data, 0) == 0)
- {
- if (m_cart->exists())
- m_maincpu->space(AS_PROGRAM).install_rom(0x0000, 0x7fff, m_cart->get_rom_base());
- else
- m_maincpu->space(AS_PROGRAM).unmap_readwrite(0x0000, 0x7fff);
- }
- else
- {
- // BK21 (SV-328)
- if (BIT(data, 1) == 0)
- {
- if (m_ram->size() == 64 * 1024)
- m_maincpu->space(AS_PROGRAM).install_ram(0x0000, 0x7fff, m_ram->pointer() + 0x8000);
- else
- m_maincpu->space(AS_PROGRAM).unmap_readwrite(0x0000, 0x7fff);
- }
-
- // BK22 (SV-807)
- if (BIT(data, 2) == 0)
- m_maincpu->space(AS_PROGRAM).unmap_readwrite(0x8000, 0xffff);
-
- // BK31 (SV-807)
- if (BIT(data, 3) == 0)
- m_maincpu->space(AS_PROGRAM).unmap_readwrite(0x0000, 0x7fff);
-
- // BK32 (SV-807)
- if (BIT(data, 4) == 0)
- m_maincpu->space(AS_PROGRAM).unmap_readwrite(0x8000, 0xffff);
- }
+ offset += 0x8000;
+
+ // cartridge /CCS3
+ if (m_cart == 0 && m_rom2 == 0 && offset < 0xc000)
+ return m_cart_rom->read_rom(space, offset);
+
+ // cartridge /CCS4
+ if (m_cart == 0 && m_rom3 == 0 && offset >= 0xc000)
+ return m_cart_rom->read_rom(space, offset);
+
+ UINT8 data = m_expander->mreq_r(space, offset);
+
+ if (m_ramdis == 1 && (offset >= 0x4000 || IS_SVI328))
+ return m_ram->read(IS_SVI328 ? offset : offset - 0xc000);
+
+ return data;
+}
+
+WRITE8_MEMBER( svi3x8_state::page2_w )
+{
+ offset += 0x8000;
+
+ // cartridge /CCS3
+ if (m_cart == 0 && m_rom2 == 0 && offset < 0xc000)
+ return;
+
+ // cartridge /CCS4
+ if (m_cart == 0 && m_rom3 == 0 && offset >= 0xc000)
+ return;
+
+ m_expander->mreq_w(space, offset, data);
+
+ if (m_ramdis == 1 && (offset >= 0x4000 || IS_SVI328))
+ m_ram->write(IS_SVI328 ? offset : offset - 0xc000, data);
+}
+
+WRITE8_MEMBER( svi3x8_state::bank_w )
+{
+ logerror("bank_w: %02x\n", data);
+
+ m_cart = BIT(data, 0);
+ m_bk21 = BIT(data, 1);
+
+ m_expander->bk21_w(BIT(data, 1));
+ m_expander->bk22_w(BIT(data, 2));
+ m_expander->bk31_w(BIT(data, 3));
+ m_expander->bk32_w(BIT(data, 4));
+
+ m_rom2 = BIT(data, 6);
+ m_rom3 = BIT(data, 7);
output().set_value("led_caps_lock", BIT(data, 5));
}
@@ -372,6 +448,22 @@ WRITE8_MEMBER( svi3x8_state::ppi_port_c_w )
m_speaker->level_w(BIT(data, 7));
}
+WRITE_LINE_MEMBER( svi3x8_state::intexp_w )
+{
+ m_intexp = state;
+ m_maincpu->set_input_line(INPUT_LINE_IRQ0, (m_intvdp || m_intexp) ? ASSERT_LINE : CLEAR_LINE);
+}
+
+WRITE_LINE_MEMBER( svi3x8_state::romdis_w )
+{
+ m_romdis = state;
+}
+
+WRITE_LINE_MEMBER( svi3x8_state::ramdis_w )
+{
+ m_ramdis = state;
+}
+
//**************************************************************************
// CARTRIDGE
@@ -379,16 +471,10 @@ WRITE8_MEMBER( svi3x8_state::ppi_port_c_w )
DEVICE_IMAGE_LOAD_MEMBER( svi3x8_state, cartridge )
{
- UINT32 size = m_cart->common_get_size("rom");
-
- if (size != 0x8000)
- {
- popmessage("Cartridge image '%s' invalid size: %u bytes", image.filename(), size);
- return IMAGE_INIT_FAIL;
- }
+ UINT32 size = m_cart_rom->common_get_size("rom");
- m_cart->rom_alloc(size, GENERIC_ROM8_WIDTH, ENDIANNESS_LITTLE);
- m_cart->common_load_rom(m_cart->get_rom_base(), size, "rom");
+ m_cart_rom->rom_alloc(size, GENERIC_ROM8_WIDTH, ENDIANNESS_LITTLE);
+ m_cart_rom->common_load_rom(m_cart_rom->get_rom_base(), size, "rom");
return IMAGE_INIT_PASS;
}
@@ -427,7 +513,7 @@ static MACHINE_CONFIG_START( svi318, svi3x8_state )
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25)
MCFG_SOUND_ADD("psg", AY8910, XTAL_10_738635MHz / 6)
MCFG_AY8910_PORT_A_READ_CB(IOPORT("JOY"))
- MCFG_AY8910_PORT_B_WRITE_CB(WRITE8(svi3x8_state, psg_port_b_w))
+ MCFG_AY8910_PORT_B_WRITE_CB(WRITE8(svi3x8_state, bank_w))
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.75)
// cassette
@@ -442,6 +528,12 @@ static MACHINE_CONFIG_START( svi318, svi3x8_state )
MCFG_GENERIC_EXTENSIONS("bin,rom")
MCFG_GENERIC_LOAD(svi3x8_state, cartridge)
MCFG_SOFTWARE_LIST_ADD("cart_list", "svi318_cart")
+
+ // expander bus
+ MCFG_SVI_EXPANDER_BUS_ADD("exp")
+ MCFG_SVI_EXPANDER_INT_HANDLER(WRITELINE(svi3x8_state, intexp_w))
+ MCFG_SVI_EXPANDER_ROMDIS_HANDLER(WRITELINE(svi3x8_state, romdis_w))
+ MCFG_SVI_EXPANDER_RAMDIS_HANDLER(WRITELINE(svi3x8_state, ramdis_w))
MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( svi318n, svi318 )
diff --git a/src/mame/drivers/svision.cpp b/src/mame/drivers/svision.cpp
index 55045c506ec..5779b8811c6 100644
--- a/src/mame/drivers/svision.cpp
+++ b/src/mame/drivers/svision.cpp
@@ -470,10 +470,11 @@ DEVICE_IMAGE_LOAD_MEMBER( svision_state, svision_cart )
void svision_state::machine_start()
{
- int num_banks;
+ int num_banks = 0;
std::string region_tag;
m_cart_rom = memregion(region_tag.assign(m_cart->tag()).append(GENERIC_ROM_REGION_TAG).c_str());
- num_banks = m_cart_rom->bytes() / 0x4000;
+ if (m_cart_rom)
+ num_banks = m_cart_rom->bytes() / 0x4000;
m_bank1 = membank("bank1");
m_bank2 = membank("bank2");
diff --git a/src/mame/drivers/symbolics.cpp b/src/mame/drivers/symbolics.cpp
new file mode 100644
index 00000000000..2455f51bab9
--- /dev/null
+++ b/src/mame/drivers/symbolics.cpp
@@ -0,0 +1,270 @@
+// license:BSD-3-Clause
+// copyright-holders:Jonathan Gevaryahu
+/******************************************************************************
+ Symbolics 36x0 (really in this case, 3670; the original 3600 is considerably rarer, 3670 is backwards compatible for the most part)
+ TODO: add credits, backstory, history, etc here
+ Front-end Processor dumped only, so far, plds/proms/pals not dumped yet
+
+ TODO:
+ The entire lispcpu half (more like 3/4) of the machine
+ Framebuffer 1152x864? (lives on the i/o card)
+ I8274 MPSC (z80dart.cpp) x2
+ 1024x4bit SRAM AM2148-50 x6 @F22-F27
+ 2048x8bit SRAM @F7 and @G7
+ keyboard/mouse (a 68k based console dedicated to this machine; talks through one of the MPSC chips)
+ am9517a-50 DMA controller
+ 'NanoFEP' i8749 mcu which runs the front panel and rtc clock (only on 3600, the 3670 lacks this)
+
+ DONE:
+ ROM Loading
+ 256K DRAM
+
+ Keyboard serial bit map:
+ Local (#x01), Caps Lock (LED) (#x02), Hyper (left) (#x03), Meta (left) (#x04), Control (right) (#x05), Super (right) (#x06), Scroll (#x07), Mode Lock (LED) (#x08), Select (#x0c), Symbol (left) (#x0d), Super (left) (#x0e), Control (left) (#x0f), Space (#x10), Meta (right) (#x11), Hyper (right) (#x12), End (#x13), Z (#x17), C (#x18), B (#x19), M (#x1a), . / > (#x1b), Shift (right) (#x1c), Repeat (#x1d), Abort (#x1e), Shift (left) (#x22), X (#x23), V (#x24), N (#x25), , / < (#x26), / / ? (#x27), Symbol (right) (#x28), Help (#x29), Rubout (#x2d), S (#x2e), F (#x2f), H (#x30), K (#x31), ; / : (#x32), Return (#x33), Complete (#x34), Network (#x38), A (#x39), D (#x3a), G (#x3b), J (#x3c), L (#x3d), ' / " (#x3e), Line (#x3f), Function (#x43), W (#x44), R (#x45), Y (#x46), I (#x47), P (#x48), ) / ] (#x49), Page (#x4a), Tab (#x4e), Q (#x4f), E (#x50), T (#x51), U (#x52), O (#x53), ( / [ (#x54), Back Space (#x55), : (#x59), 2 / @ (#x5a), 4 / $ (#x5b), 6 / ^ (#x5c), 8 / * (#x5d), 0 / ) (#x5e), = / + (#x5f), \ / { (#x60), 1 / ! (#x64), 3 / # (#x65), 5 / % (#x66), 7 / & (#x67), 9 / ( (#x68), - / _ (#x69), ` / ~ (#x6a), | / } (#x6b), Escape (#x6f), Refresh (#x70), Square (#x71), Circle (#x72), Triangle (#x73), Clear Input (#x74), Suspend (#x75), Resume (#x76)
+
+
+ Notes from US Patent 4887235 which has some FEP source code and limited memory info:
+ FEP main description starts on pdf page 47
+ FEP access the SPY bus which allows poking at the workings of the lisp cpu, as well as reading the ethernet interface (on 3600, later g-machine 3650 fep seems to use a separate z80 for this?) see patent pdf page 33
+ page 41 reveals the SPY bus is 8 data bits wide, and has an address of 6 bits
+ see page 97 of http://bitsavers.trailing-edge.com/pdf/symbolics/3600_series/Lisp_Machine_Hardware_Memos.pdf which explains what addresses do what.
+ FEP accesses a register called SQCLKC described with bits on pdf page 32, figure out where this maps
+
+ http://bitsavers.trailing-edge.com/pdf/symbolics/3600_series/3600_TechnicalSummary_Feb83.pdf <- page 114 describes the nanofep
+ http://bitsavers.trailing-edge.com/pdf/symbolics/3600_series/Symbolics_3600_Series_Basic_Field_Maint_Jul86.pdf <- page 84 describes the two types of FEP, older one with firmware v24 and newer one (emulated here) with firmware v127
+
+ fonts:
+ tiny7: 0x908 to 0xB08 in fep ROM is a thin font, 4 or 5 pixels wide, rows are in a weird scrambled order
+ normal or cptfont: 0x11e8 to 0x16d8 is a thick/wide font, 10? pixels wide
+ verylarge: 0x2a48 to 0x3638 is an even wider font, 14 pixels wide
+ tvfont?: 0x134d8-0x13ad0 is a thin font about 7 pixels wide with the rows in a weird scrambled order
+******************************************************************************/
+
+/* Core includes */
+#include "emu.h"
+#include "cpu/m68000/m68000.h"
+
+class symbolics_state : public driver_device
+{
+public:
+
+ symbolics_state(const machine_config &mconfig, device_type type, const char *tag)
+ : driver_device(mconfig, type, tag),
+ m_maincpu(*this, "maincpu")
+ {
+ }
+
+ required_device<m68000_base_device> m_maincpu;
+ DECLARE_DRIVER_INIT(symbolics);
+ DECLARE_READ16_MEMBER(buserror_r);
+
+//protected:
+// virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
+};
+
+READ16_MEMBER(symbolics_state::buserror_r)
+{
+ if(!space.debugger_access())
+ {
+ m_maincpu->set_input_line(M68K_LINE_BUSERROR, ASSERT_LINE);
+ m_maincpu->set_input_line(M68K_LINE_BUSERROR, CLEAR_LINE);
+ }
+ return 0;
+}
+
+
+/******************************************************************************
+ Address Maps
+******************************************************************************/
+/*
+Address maps (x = ignored; * = selects address within this range, ? = unknown, 1/0 = decodes only when this bit is set to 1/0)
+68k address map:
+a23 a22 a21 a20 a19 a18 a17 a16 a15 a14 a13 a12 a11 a10 a9 a8 a7 a6 a5 a4 a3 a2 a1 (a0 via UDS/LDS)
+? ? ? ? ? 0 0 0 0 0 * * * * * * * * * * * * * 0 R ROM 00H @D13 first half
+? ? ? ? ? 0 0 0 0 0 * * * * * * * * * * * * * 1 R ROM 00L @D7 first half
+? ? ? ? ? 0 0 0 0 1 * * * * * * * * * * * * * 0 R ROM 04H @D14 first half
+? ? ? ? ? 0 0 0 0 1 * * * * * * * * * * * * * 1 R ROM 04L @D8 first half
+? ? ? ? ? 0 0 0 1 0 * * * * * * * * * * * * * 0 R ROM 10H @D16 first half
+? ? ? ? ? 0 0 0 1 0 * * * * * * * * * * * * * 1 R ROM 10L @D10 first half
+? ? ? ? ? 0 0 0 1 1 * * * * * * * * * * * * * 0 R Open Bus (socket @D17 first half)
+? ? ? ? ? 0 0 0 1 1 * * * * * * * * * * * * * 1 R Open Bus (socket @D11 first half)
+? ? ? ? ? 0 0 1 0 0 * * * * * * * * * * * * * 0 R ROM 00H @D13 second half
+? ? ? ? ? 0 0 1 0 0 * * * * * * * * * * * * * 1 R ROM 00L @D7 second half
+? ? ? ? ? 0 0 1 0 1 * * * * * * * * * * * * * 0 R ROM 04H @D14 second half
+? ? ? ? ? 0 0 1 0 1 * * * * * * * * * * * * * 1 R ROM 04L @D8 second half
+? ? ? ? ? 0 0 1 1 0 * * * * * * * * * * * * * 0 R ROM 10H @D16 second half
+? ? ? ? ? 0 0 1 1 0 * * * * * * * * * * * * * 1 R ROM 10L @D10 second half
+? ? ? ? ? 0 0 1 1 1 * * * * * * * * * * * * * 0 R Open Bus (socket @D17 second half)
+? ? ? ? ? 0 0 1 1 1 * * * * * * * * * * * * * 1 R Open Bus (socket @D11 second half)
+? ? ? ? ? 0 1 * * * * * * * * * * * * * * * * * RW RAM (4164 DRAMs; these have parity as well, which is checked in the i/o area somehow?)
+1 1 1 1 1 1 1 1 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? * ? SPY BUS and FEP peripherals for OLD FEP hardware, not the NFEP we have here; the map of this area is listed in octal on pdf page 399 of us patent 4887235. The NFEP map is certainly not the same, but is probably similar.
+1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 1 0 0 * * * * RW SPY-CMEM (writes CMEM WD, reads UIR)
+1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 1 0 0 1 1 1 * W SPY-SQ-CTL
+1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 1 0 0 1 1 1 0 R SPY-BOARD-ID (read a given board's id prom, board select is in U AMRA register)
+1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 * R SPY-SQ-STATUS
+1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 1 0 1 0 0 1 * ? SPY-NEXT-CPC
+1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 1 0 1 0 0 1 0? ? SPY-TASK
+1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 1 0 1 0 0 1 1 R SPY-CTOS-HIGH
+1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 1 0 1 0 1 1 0? R SPY-OPC
+1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0? W SPY-MC-CONTROL
+1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 R SPY-MC-ID
+1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 1 R SPY-MC-ERROR-STATUS
+1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1 0 R SPY-ECC-SYNDROME
+1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1 1 R SPY-ECC-ADDRESS
+1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 1 1 0 0 1 0 *? R SPY-MC-STATUS
+1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 1 1 0 1 0 0 0 W SPY-NET-SELECT
+1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 1 1 0 1 0 0 1 W SPY-NET-CONTROL
+1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 x? 0 RW MPSC-0-A
+1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 x? 1 RW MPSC-0-B
+1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 0 0 0 0 1 x? 0 RW MPSC-1-A
+1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 0 0 0 0 1 x? 1 RW MPSC-1-B
+1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 0 0 0 1 0 1 *? R? SPY-DMA-HIGH-ADDRS
+1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 *? R SPY-DMA-CONTROLLER
+1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 ?? R FEP-PADDLE-ID-PROM
+1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 ?? R FEP-BOARD-ID-PROM
+1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 1 W FEP-BOARD-ID-CONTROL
+1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 1 1 0 0 0 1 1 W FEP-DMA-AND-CLOCK-CTL
+1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 1 1 0 0 1 0 0 W FEP-DMA-CONTROL
+1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 1 1 0 0 1 0 1 W FEP-PROC-CONTROL
+1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 1 1 0 1 0 0 0? W FEP(SPY)-LBUS-CONTROL
+1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 1 1 0 1 1 0 0? W FEP-SERIAL-BAUD-RATE-0
+1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 1 1 0 1 1 1 0? W FEP-SERIAL-BAUD-RATE-1
+1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0? W FEP-HSB-CONTROL
+1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 1 1 1 0 0 1 0? W FEP-HSB-DATA
+1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 1 1 1 0 1 0 0? W FEP-HSB-POINTER
+1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 0? W P-PORT
+ | | | | | | hex
+ | | | | | | | | octal
+@310: write
+@A2A4: write to FF
+
+
+*/
+
+static ADDRESS_MAP_START(m68k_mem, AS_PROGRAM, 16, symbolics_state )
+ ADDRESS_MAP_UNMAP_HIGH
+ AM_RANGE(0x000000, 0x01ffff) AM_ROM /* ROM lives here, and writing to 0x00-0x08 writes to the main lisp ram? */
+ //AM_RANGE(0x020000, 0x03ffff) AM_RAM /* Local FEP ram seems to be here? there are 18 mcm4164s on the pcb which probably map here, plus 2 parity bits? */
+ AM_RANGE(0x020000, 0x03ffff) AM_RAM /* Local FEP ram seems to be here? there are 18 mcm4164s on the pcb which probably map here, plus 2 parity bits? */
+ // 2x AM9128-10PC 2048x8 SRAMs @F7 and @G7 map somewhere
+ // 6x AM2148-50 1024x4bit SRAMs @F22-F27 map somewhere
+ //AM_RANGE(0x040000, 0xffffff) AM_READ(buserror_r);
+ //AM_RANGE(0x800000, 0xffffff) AM_RAM /* paged access to lispm ram? */
+ //FF00B0 is readable, may be to read the MC/SQ/DP/AU continuity lines?
+ //FF00E1 is writable, may control the LBUS_POWER_RESET line, see http://bitsavers.trailing-edge.com/pdf/symbolics/3600_series/Lisp_Machine_Hardware_Memos.pdf page 90
+ //FF018A is writable, gets 0x5555 written to it
+ADDRESS_MAP_END
+
+static ADDRESS_MAP_START(m68k_io, AS_IO, 16, symbolics_state )
+ADDRESS_MAP_END
+
+/******************************************************************************
+ Input Ports
+******************************************************************************/
+static INPUT_PORTS_START( symbolics )
+INPUT_PORTS_END
+
+/******************************************************************************
+ Machine Drivers
+******************************************************************************/
+/*void symbolics_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
+{
+ switch (id)
+ {
+ case TIMER_OUTFIFO_READ:
+ outfifo_read_cb(ptr, param);
+ break;
+ default:
+ assert_always(FALSE, "Unknown id in symbolics_state::device_timer");
+ }
+}
+
+TIMER_CALLBACK_MEMBER(symbolics_state::outfifo_read_cb)
+{
+ UINT16 data;
+}
+*/
+
+/* Driver init: stuff that needs setting up which isn't directly affected by reset */
+DRIVER_INIT_MEMBER(symbolics_state,symbolics)
+{
+}
+
+static MACHINE_CONFIG_START( symbolics, symbolics_state )
+ /* basic machine hardware */
+ // per page 159 of http://bitsavers.trailing-edge.com/pdf/symbolics/3600_series/Lisp_Machine_Hardware_Memos.pdf:
+ //XTALS: 16MHz @H11 (68k CPU clock)
+ // 4.9152MHz @J5 (driving the two MPSCs serial clocks)
+ // 66.67MHz @J10 (main lispcpu/system clock)
+ MCFG_CPU_ADD("maincpu", M68000, XTAL_16MHz/2) /* MC68000L8 @A27; clock is derived from the 16Mhz xtal @ H11 */
+ MCFG_CPU_PROGRAM_MAP(m68k_mem)
+ MCFG_CPU_IO_MAP(m68k_io)
+
+ //ADD ME:
+ // Framebuffer
+ // DMA Controller
+ // I8274 MPSC #1 (synchronous serial for keyboard)
+ // I8274 MPSC #2 (EIA/debug console?)
+
+MACHINE_CONFIG_END
+
+/******************************************************************************
+ ROM Definitions
+******************************************************************************/
+
+ROM_START( s3670 )
+ ROM_REGION16_BE(0x40000,"maincpu", 0)
+ // the older 'FEP V24' has similar roms but a different hw layout and memory map
+ ROM_SYSTEM_BIOS( 0, "v127", "Symbolics 3600 L-Machine 'NFEP V127'")
+ ROMX_LOAD("00h.127.27c128.d13", 0x00000, 0x2000, CRC(b8d7c8da) SHA1(663a09359f5db63beeac00e5c2783ccc25b94250), ROM_SKIP(1) | ROM_BIOS(1)) // Label: "00H.127" @D13
+ ROM_CONTINUE( 0x10000, 0x2000 )
+ ROMX_LOAD("00l.127.27128.d7", 0x00001, 0x2000, CRC(cc7bae9a) SHA1(057538eb821c4d00dde19cfe5136ccc0aee43800), ROM_SKIP(1) | ROM_BIOS(1)) // Label: "00L.127" @D7
+ ROM_CONTINUE( 0x10001, 0x2000 )
+ ROMX_LOAD("04h.127.27128.d14", 0x04000, 0x2000, CRC(e01a717b) SHA1(b87a670f7be13553485ce88fad5fcf90f01473c4), ROM_SKIP(1) | ROM_BIOS(1)) // Label: "04H.127" @D14
+ ROM_CONTINUE( 0x14000, 0x2000 )
+ ROMX_LOAD("04l.127.27128.d8", 0x04001, 0x2000, CRC(68d169fa) SHA1(d6fab3132fca332a9bedb174fddf5fc8c69d05b6), ROM_SKIP(1) | ROM_BIOS(1)) // Label: "04L.127" @D8
+ ROM_CONTINUE( 0x14001, 0x2000 )
+ ROMX_LOAD("10h.127.27128.d16", 0x08000, 0x2000, CRC(2ea7a70d) SHA1(61cc97aada028612c24d788d946d77e82116cf30), ROM_SKIP(1) | ROM_BIOS(1)) // Label: "10H.127" @D16
+ ROM_CONTINUE( 0x18000, 0x2000 )
+ ROMX_LOAD("10l.127.27c128.d10", 0x08001, 0x2000, CRC(b8ddb3c8) SHA1(e6c3b96340c5c767ef18abf48b73fa8e5d7353b9), ROM_SKIP(1) | ROM_BIOS(1)) // Label: "10L.127" @D10
+ ROM_CONTINUE( 0x18001, 0x2000 )
+ // D17, D11 are empty sockets; these would map to 0x0c000-0ffff and 0x1c000-0x1ffff
+ // note: load all the PLAs, PALs and PROMs here
+ // picture is at https://4310b1a9-a-11c96037-s-sites.googlegroups.com/a/ricomputermuseum.org/home/Home/equipment/symbolics-3645/Symbolics_3645_FEP.jpg
+ /*
+ LBBUFA.4 mb7124 @A6
+ LBBUFB.4 mb7124 @A7
+ LBBUFC.4 mb7124 @A9
+ LBAAR.4 @A12
+ LBPAR.4A @A13
+ PROCA.4 pal16R8A @A25
+ HSADR.4 pal1???? @C4
+ DYNMEM.5 pal16R8A @C20
+ PCDYNCTL @C21
+ REQSEL.4A @C22
+ DY2ACK pal16L8A @C23
+ PROC.4 pal? @C25
+ UDMAHA.4 pal? @D3
+ FEP 4642 16pprom? @D5 <- this is the serial number of the FEP board stored in a prom, readable at one of the local-io addresses
+ HRSQ.4 pal @D6
+ d7, d8, d10 are eproms, see above
+ d11 is empty socket marked 2764
+ d13, d14, d16 are eproms, see above
+ d17 is empty socket marked 2764
+ ?DVZNUR? @E21 <- unreadable label, recheck!
+ LDBD.4 pal16L8A @G18
+ PAGTAG.5 @H20
+ UDMABC.4 pal @I4
+ SERDMA.4 @I8
+ SERIAB.4 @I9
+ LBARB.4 @I18
+ SERCTL.4 @K6
+ */
+ROM_END
+
+/******************************************************************************
+ Drivers
+******************************************************************************/
+
+/* YEAR NAME PARENT COMPAT MACHINE INPUT STATE INIT COMPANY FULLNAME FLAGS */
+COMP( 1984, s3670, 0, 0, symbolics, symbolics, symbolics_state, symbolics, "Symbolics", "3670", MACHINE_IS_SKELETON | MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
diff --git a/src/mame/drivers/taitogn.cpp b/src/mame/drivers/taitogn.cpp
index 1077996e020..09721eb3f00 100644
--- a/src/mame/drivers/taitogn.cpp
+++ b/src/mame/drivers/taitogn.cpp
@@ -392,7 +392,6 @@ public:
DECLARE_DRIVER_INIT(coh3002t_nz);
protected:
- virtual void driver_start() override;
virtual void machine_reset() override;
private:
@@ -592,14 +591,6 @@ READ32_MEMBER(taitogn_state::zsg2_ext_r)
return 0;
}
-// Init and reset
-
-void taitogn_state::driver_start()
-{
- m_cat702_1->init(tt10);
- m_cat702_2->init(tt16);
-}
-
void taitogn_state::machine_reset()
{
// halt sound CPU since it has no valid program at start
@@ -680,9 +671,11 @@ static MACHINE_CONFIG_START( coh3002t, taitogn_state )
MCFG_DEVICE_ADD("cat702_1", CAT702, 0)
MCFG_CAT702_DATAOUT_HANDLER(WRITELINE(taitogn_state, cat702_1_dataout))
+ MCFG_CAT702_TRANSFORM_TABLE(tt10)
MCFG_DEVICE_ADD("cat702_2", CAT702, 0)
MCFG_CAT702_DATAOUT_HANDLER(WRITELINE(taitogn_state, cat702_2_dataout))
+ MCFG_CAT702_TRANSFORM_TABLE(tt16)
MCFG_DEVICE_ADD("zndip", ZNDIP, 0)
MCFG_ZNDIP_DATAOUT_HANDLER(WRITELINE(taitogn_state, zndip_dataout))
diff --git a/src/mame/drivers/vigilant.cpp b/src/mame/drivers/vigilant.cpp
index 239a7c85a53..35053e8f5e2 100644
--- a/src/mame/drivers/vigilant.cpp
+++ b/src/mame/drivers/vigilant.cpp
@@ -1005,30 +1005,30 @@ ROM_END
ROM_START( buccanrs )
ROM_REGION( 0x30000, "maincpu", 0 ) /* 64k for code + 128k for bankswitching */
- ROM_LOAD( "11.u58", 0x00000, 0x10000, CRC(bf1d7e6f) SHA1(55dcf993515b57c3eb1fab98097a2171df3e38ed) ) // both halves are identical (correct for rom type on this board tho)
- ROM_LOAD( "12.u25", 0x10000, 0x10000, CRC(87303ba8) SHA1(49a25393e853b9adf7df00a6f9c38a526a02ea4e) )
+ ROM_LOAD( "BC-011_K-163.U58", 0x00000, 0x10000, CRC(bf1d7e6f) SHA1(55dcf993515b57c3eb1fab98097a2171df3e38ed) ) // both halves are identical (correct for rom type on this board tho)
+ ROM_LOAD( "BC-012_K-163.U25", 0x10000, 0x10000, CRC(87303ba8) SHA1(49a25393e853b9adf7df00a6f9c38a526a02ea4e) )
ROM_REGION( 0x10000, "soundcpu", 0 ) /* 64k for sound */
- ROM_LOAD( "1.u128", 0x00000, 0x10000, CRC(eb65f8c3) SHA1(82566becb630ce92303905dc0c5bef9e80e9caad) )
+ ROM_LOAD( "BC-001_K-0161.U128", 0x00000, 0x10000, CRC(eb65f8c3) SHA1(82566becb630ce92303905dc0c5bef9e80e9caad) )
ROM_REGION( 0x20000, "gfx1", 0 )
- ROM_LOAD( "7.u212", 0x00000, 0x10000, CRC(95e3c517) SHA1(9954830ebc3a6414a3236f4e41981db082e5ea19) )
- ROM_LOAD( "8.u189", 0x10000, 0x10000, CRC(fe2377ab) SHA1(8578c5466d98f140fdfc41e91cd841e725786e32) )
+ ROM_LOAD( "BC-003_K-0161.U212", 0x00000, 0x10000, CRC(95e3c517) SHA1(9954830ebc3a6414a3236f4e41981db082e5ea19) )
+ ROM_LOAD( "BC-004_K-0161.U189", 0x10000, 0x10000, CRC(fe2377ab) SHA1(8578c5466d98f140fdfc41e91cd841e725786e32) )
ROM_REGION( 0x80000, "gfx2", 0 )
- ROM_LOAD( "3.u100", 0x00000, 0x10000, CRC(16dc435f) SHA1(0c13e9786b356770c84f94684697e43d0ea9e7cc) )
+ ROM_LOAD( "BC-005_K-0161.U113", 0x00000, 0x10000, CRC(16dc435f) SHA1(0c13e9786b356770c84f94684697e43d0ea9e7cc) )
ROM_CONTINUE( 0x20000, 0x10000 )
- ROM_LOAD( "4.u80", 0x10000, 0x10000, CRC(4fe3bf97) SHA1(7910ace1eed80bfafa1f9f057ed67e23aa446a22) )
- ROM_LOAD( "6.u52", 0x40000, 0x10000, CRC(078aef7f) SHA1(72e60d39d8af8bd31e9ae019b12620797eb0af7f) )
+ ROM_LOAD( "BC-006_K-161.U80", 0x10000, 0x10000, CRC(4fe3bf97) SHA1(7910ace1eed80bfafa1f9f057ed67e23aa446a22) )
+ ROM_LOAD( "BC-008_K-161.U52", 0x40000, 0x10000, CRC(078aef7f) SHA1(72e60d39d8af8bd31e9ae019b12620797eb0af7f) )
ROM_CONTINUE( 0x60000, 0x10000 )
- ROM_LOAD( "5.u70", 0x50000, 0x10000, CRC(f650fa90) SHA1(c87081b4d6b09f865d08c5120da3d0fb3196a2c3) )
+ ROM_LOAD( "BC-007_K-161.U70", 0x50000, 0x10000, CRC(f650fa90) SHA1(c87081b4d6b09f865d08c5120da3d0fb3196a2c3) )
ROM_REGION( 0x40000, "gfx3", 0 )
- ROM_LOAD( "9.u49", 0x20000, 0x20000, CRC(0c6188fb) SHA1(d49034384c6d0e94db2890223b32a2a49e79a639) )
- ROM_LOAD( "10.u27", 0x00000, 0x20000, CRC(2d383ff8) SHA1(3062baac27feba69c6ed94935c5ced72d89ed4fb) )
+ ROM_LOAD( "BC-009_K-163.U49", 0x20000, 0x20000, CRC(0c6188fb) SHA1(d49034384c6d0e94db2890223b32a2a49e79a639) )
+ ROM_LOAD( "BC-010_K-163.U27", 0x00000, 0x20000, CRC(2d383ff8) SHA1(3062baac27feba69c6ed94935c5ced72d89ed4fb) )
ROM_REGION( 0x10000, "samples", 0 ) /* samples */
- ROM_LOAD( "2.u74", 0x00000, 0x10000, CRC(36ee1dac) SHA1(6dfd2a885c0b1c9347abc4b204ade66551c4b404) )
+ ROM_LOAD( "BC-002_K-0161.U74", 0x00000, 0x10000, CRC(36ee1dac) SHA1(6dfd2a885c0b1c9347abc4b204ade66551c4b404) )
ROM_REGION( 0x400, "proms", 0 )
ROM_LOAD( "prom1.u54", 0x0000, 0x0100, CRC(c324835e) SHA1(cf6ffe38523badfda211d341410e93e647de87a9) ) // == ic52 video timing prom from vigilante
@@ -1045,29 +1045,64 @@ ROM_END
ROM_START( buccanrsa )
ROM_REGION( 0x30000, "maincpu", 0 ) /* 64k for code + 128k for bankswitching */
ROM_LOAD( "bc-011", 0x00000, 0x08000, CRC(6b657ef1) SHA1(a3356654d4b04177af23b39e924cc5ad64930bb6) )
- ROM_LOAD( "12.u25", 0x10000, 0x10000, CRC(87303ba8) SHA1(49a25393e853b9adf7df00a6f9c38a526a02ea4e) ) // not from this set, hopefully its only a data rom
+ ROM_LOAD( "BC-012_K-163.U25", 0x10000, 0x10000, CRC(87303ba8) SHA1(49a25393e853b9adf7df00a6f9c38a526a02ea4e) )
ROM_REGION( 0x10000, "soundcpu", 0 ) /* 64k for sound */
- ROM_LOAD( "1.u128", 0x00000, 0x10000, CRC(eb65f8c3) SHA1(82566becb630ce92303905dc0c5bef9e80e9caad) )
+ ROM_LOAD( "BC-001_K-0161.U128", 0x00000, 0x10000, CRC(eb65f8c3) SHA1(82566becb630ce92303905dc0c5bef9e80e9caad) )
ROM_REGION( 0x20000, "gfx1", 0 )
- ROM_LOAD( "7.u212", 0x00000, 0x10000, CRC(95e3c517) SHA1(9954830ebc3a6414a3236f4e41981db082e5ea19) )
- ROM_LOAD( "8.u189", 0x10000, 0x10000, CRC(fe2377ab) SHA1(8578c5466d98f140fdfc41e91cd841e725786e32) )
+ ROM_LOAD( "BC-003_K-0161.U212", 0x00000, 0x10000, CRC(95e3c517) SHA1(9954830ebc3a6414a3236f4e41981db082e5ea19) )
+ ROM_LOAD( "BC-004_K-0161.U189", 0x10000, 0x10000, CRC(fe2377ab) SHA1(8578c5466d98f140fdfc41e91cd841e725786e32) )
ROM_REGION( 0x80000, "gfx2", 0 )
- ROM_LOAD( "3.u100", 0x00000, 0x10000, CRC(16dc435f) SHA1(0c13e9786b356770c84f94684697e43d0ea9e7cc) )
+ ROM_LOAD( "BC-005_K-0161.U113", 0x00000, 0x10000, CRC(16dc435f) SHA1(0c13e9786b356770c84f94684697e43d0ea9e7cc) )
ROM_CONTINUE( 0x20000, 0x10000 )
- ROM_LOAD( "4.u80", 0x10000, 0x10000, CRC(4fe3bf97) SHA1(7910ace1eed80bfafa1f9f057ed67e23aa446a22) ) // was double size (2nd half blank) in this set)
- ROM_LOAD( "6.u52", 0x40000, 0x10000, CRC(078aef7f) SHA1(72e60d39d8af8bd31e9ae019b12620797eb0af7f) )
+ ROM_LOAD( "BC-006_K-161.U80", 0x10000, 0x10000, CRC(4fe3bf97) SHA1(7910ace1eed80bfafa1f9f057ed67e23aa446a22) )
+ ROM_LOAD( "BC-008_K-161.U52", 0x40000, 0x10000, CRC(078aef7f) SHA1(72e60d39d8af8bd31e9ae019b12620797eb0af7f) )
ROM_CONTINUE( 0x60000, 0x10000 )
- ROM_LOAD( "5.u70", 0x50000, 0x10000, CRC(f650fa90) SHA1(c87081b4d6b09f865d08c5120da3d0fb3196a2c3) ) // was double size (2nd half blank) in this set)
+ ROM_LOAD( "BC-007_K-161.U70", 0x50000, 0x10000, CRC(f650fa90) SHA1(c87081b4d6b09f865d08c5120da3d0fb3196a2c3) )
ROM_REGION( 0x40000, "gfx3", 0 )
- ROM_LOAD( "9.u49", 0x20000, 0x20000, CRC(0c6188fb) SHA1(d49034384c6d0e94db2890223b32a2a49e79a639) )
- ROM_LOAD( "10.u27", 0x00000, 0x20000, CRC(2d383ff8) SHA1(3062baac27feba69c6ed94935c5ced72d89ed4fb) )
+ ROM_LOAD( "BC-009_K-163.U49", 0x20000, 0x20000, CRC(0c6188fb) SHA1(d49034384c6d0e94db2890223b32a2a49e79a639) )
+ ROM_LOAD( "BC-010_K-163.U27", 0x00000, 0x20000, CRC(2d383ff8) SHA1(3062baac27feba69c6ed94935c5ced72d89ed4fb) )
ROM_REGION( 0x10000, "samples", 0 ) /* samples */
- ROM_LOAD( "2.u74", 0x00000, 0x10000, CRC(36ee1dac) SHA1(6dfd2a885c0b1c9347abc4b204ade66551c4b404) )
+ ROM_LOAD( "BC-002_K-0161.U74", 0x00000, 0x10000, CRC(36ee1dac) SHA1(6dfd2a885c0b1c9347abc4b204ade66551c4b404) )
+
+ ROM_REGION( 0x400, "proms", 0 )
+ ROM_LOAD( "prom1.u54", 0x0000, 0x0100, CRC(c324835e) SHA1(cf6ffe38523badfda211d341410e93e647de87a9) ) // == ic52 video timing prom from vigilante
+ ROM_LOAD( "prom4.u79", 0x0100, 0x0100, CRC(e6506ef4) SHA1(079841da7640b14d94aaaeb572bf018932b58293) )
+ ROM_LOAD( "prom3.u88", 0x0200, 0x0100, CRC(b43d094f) SHA1(2bed4892d8a91d7faac5a07bf858d9294eb30606) )
+ ROM_LOAD( "prom2.u99", 0x0300, 0x0100, CRC(e0aa8869) SHA1(ac8bdfeba69420ba56ec561bf3d0f1229d02cea2) )
+ROM_END
+
+
+ROM_START( buccanrsb )
+ ROM_REGION( 0x30000, "maincpu", 0 ) /* 64k for code + 128k for bankswitching */
+ ROM_LOAD( "rr_Du.u58", 0x00000, 0x08000, CRC(dcad3a8b) SHA1(e961927bdff28db18b829ce3f64051ff1604d1e6) )
+ ROM_LOAD( "BC-012_K-163.U25", 0x10000, 0x10000, CRC(87303ba8) SHA1(49a25393e853b9adf7df00a6f9c38a526a02ea4e) )
+
+ ROM_REGION( 0x10000, "soundcpu", 0 ) /* 64k for sound */
+ ROM_LOAD( "BC-001_K-0161.U128", 0x00000, 0x10000, CRC(eb65f8c3) SHA1(82566becb630ce92303905dc0c5bef9e80e9caad) )
+
+ ROM_REGION( 0x20000, "gfx1", 0 )
+ ROM_LOAD( "BC-003_K-0161.U212", 0x00000, 0x10000, CRC(95e3c517) SHA1(9954830ebc3a6414a3236f4e41981db082e5ea19) )
+ ROM_LOAD( "BC-004_K-0161.U189", 0x10000, 0x10000, CRC(fe2377ab) SHA1(8578c5466d98f140fdfc41e91cd841e725786e32) )
+
+ ROM_REGION( 0x80000, "gfx2", 0 )
+ ROM_LOAD( "BC-005_K-0161.U113", 0x00000, 0x10000, CRC(16dc435f) SHA1(0c13e9786b356770c84f94684697e43d0ea9e7cc) )
+ ROM_CONTINUE( 0x20000, 0x10000 )
+ ROM_LOAD( "BC-006_K-161.U80", 0x10000, 0x10000, CRC(4fe3bf97) SHA1(7910ace1eed80bfafa1f9f057ed67e23aa446a22) )
+ ROM_LOAD( "BC-008_K-161.U52", 0x40000, 0x10000, CRC(078aef7f) SHA1(72e60d39d8af8bd31e9ae019b12620797eb0af7f) )
+ ROM_CONTINUE( 0x60000, 0x10000 )
+ ROM_LOAD( "BC-007_K-161.U70", 0x50000, 0x10000, CRC(f650fa90) SHA1(c87081b4d6b09f865d08c5120da3d0fb3196a2c3) )
+
+ ROM_REGION( 0x40000, "gfx3", 0 )
+ ROM_LOAD( "BC-009_K-163.U49", 0x20000, 0x20000, CRC(0c6188fb) SHA1(d49034384c6d0e94db2890223b32a2a49e79a639) )
+ ROM_LOAD( "BC-010_K-163.U27", 0x00000, 0x20000, CRC(2d383ff8) SHA1(3062baac27feba69c6ed94935c5ced72d89ed4fb) )
+
+ ROM_REGION( 0x10000, "samples", 0 ) /* samples */
+ ROM_LOAD( "BC-002_K-0161.U74", 0x00000, 0x10000, CRC(36ee1dac) SHA1(6dfd2a885c0b1c9347abc4b204ade66551c4b404) )
ROM_REGION( 0x400, "proms", 0 )
ROM_LOAD( "prom1.u54", 0x0000, 0x0100, CRC(c324835e) SHA1(cf6ffe38523badfda211d341410e93e647de87a9) ) // == ic52 video timing prom from vigilante
@@ -1090,3 +1125,4 @@ GAME( 1988, kikcubicb, kikcubic, kikcubic, kikcubic, driver_device, 0, ROT0,
GAME( 1989, buccanrs, 0, buccanrs, buccanrs, driver_device, 0, ROT0, "Duintronic", "Buccaneers (set 1)", MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE )
GAME( 1989, buccanrsa, buccanrs, buccanrs, buccanra, driver_device, 0, ROT0, "Duintronic", "Buccaneers (set 2)", MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE )
+GAME( 1989, buccanrsb, buccanrs, buccanrs, buccanrs, driver_device, 0, ROT0, "Duintronic", "Buccaneers (set 3, harder)", MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE )
diff --git a/src/mame/drivers/zn.cpp b/src/mame/drivers/zn.cpp
index c4de6dc757f..dd5ad83ccc4 100644
--- a/src/mame/drivers/zn.cpp
+++ b/src/mame/drivers/zn.cpp
@@ -118,9 +118,6 @@ public:
void atpsx_dma_write(UINT32 *p_n_psxram, UINT32 n_address, INT32 n_size );
void jdredd_vblank(screen_device &screen, bool vblank_state);
-protected:
- virtual void driver_start() override;
-
private:
inline void ATTR_PRINTF(3,4) verboselog( int n_level, const char *s_fmt, ... );
inline void psxwriteword( UINT32 *p_n_psxram, UINT32 n_address, UINT16 n_data );
@@ -228,119 +225,6 @@ static const UINT8 tt07[ 8 ] = { 0x80, 0x10, 0xf1, 0x03, 0xfa, 0x38, 0x3c, 0xfc
static const UINT8 kn01[ 8 ] = { 0xf8, 0xe1, 0xe2, 0xfe, 0x3c, 0x30, 0x70, 0x80 }; /* brute forced */
static const UINT8 kn02[ 8 ] = { 0x01, 0x18, 0xe2, 0xfe, 0x3c, 0x30, 0x70, 0x80 }; /* brute forced */
-static const struct
-{
- const char *s_name;
- const UINT8 *p_n_mainsec;
- const UINT8 *p_n_gamesec;
-} zn_config_table[] =
-{
- { "nbajamex", ac01, ac02 }, /* black screen */
- { "jdredd", ac01, ac02 }, /* OK */
- { "jdreddb", ac01, ac02 }, /* OK */
- { "primrag2", tw01, tw02 }, /* locks up when starting a game */
- { "hvnsgate", at01, at02 }, /* OK */
- { "ts2", cp01, cp02 }, /* OK */
- { "ts2a", cp01, cp02 }, /* OK */
- { "ts2j", cp01, cp02 }, /* OK */
- { "starglad", cp01, cp03 }, /* OK */
- { "stargladj",cp01, cp03 }, /* OK */
- { "sfex", cp01, cp04 }, /* OK */
- { "sfexa", cp01, cp04 }, /* OK */
- { "sfexj", cp01, cp04 }, /* OK */
- { "sfexu", cp01, cp04 }, /* OK */
- { "sfexp", cp01, cp04 }, /* OK */
- { "sfexpu1", cp01, cp04 }, /* OK */
- { "sfexpj", cp01, cp04 }, /* OK */
- { "sfexpj1", cp01, cp04 }, /* OK */
- { "glpracr", cp01, cp05 }, /* OK */
- { "glpracrj", cp01, cp05 }, /* OK */
- { "rvschool", cp10, cp06 }, /* OK */
- { "rvschoolu",cp10, cp06 }, /* OK */
- { "rvschoola",cp10, cp06 }, /* OK */
- { "jgakuen", cp10, cp06 }, /* OK */
- { "plsmaswd", cp10, cp07 }, /* OK */
- { "stargld2", cp10, cp07 }, /* OK */
- { "plsmaswda",cp10, cp07 }, /* OK */
- { "sfex2", cp10, cp08 }, /* OK ( random crashes on garuda ) */
- { "sfex2j", cp10, cp08 }, /* OK ( random crashes on garuda ) */
- { "sfex2a", cp10, cp08 }, /* OK ( random crashes on garuda ) */
- { "sfex2h", cp10, cp08 }, /* OK ( random crashes on garuda ) */
- { "techromn", cp10, cp09 }, /* OK */
- { "techromnu",cp10, cp09 }, /* OK */
- { "kikaioh", cp10, cp09 }, /* OK */
- { "tgmj", cp10, cp11 }, /* OK */
- { "sfex2p", cp10, cp12 }, /* OK */
- { "sfex2pa", cp10, cp12 }, /* OK */
- { "sfex2pj", cp10, cp12 }, /* OK */
- { "sfex2ph", cp10, cp12 }, /* OK */
- { "strider2", cp10, cp13 }, /* OK ( random crashes on bosses ) */
- { "strider2a",cp10, cp13 }, /* OK ( random crashes on bosses ) */
- { "shiryu2", cp10, cp13 }, /* OK ( random crashes on bosses ) */
- { "beastrzr", et01, et02 }, /* OK */
- { "bldyroar", et01, et02 }, /* OK */
- { "beastrzrb",et01, et02 }, /* OK */
- { "bldyror2", et01, et03 }, /* OK */
- { "bldyror2u",et01, et03 }, /* OK */
- { "bldyror2a",et01, et03 }, /* OK */
- { "bldyror2j",et01, et03 }, /* OK */
- { "bam2", et01, et05 },
- { "glpracr2", mg01, mg02 }, /* locks up when starting a game/entering test mode */
- { "glpracr2j",mg01, mg02 }, /* locks up when starting a game/entering test mode */
- { "glpracr2l",mg01, mg02 }, /* locks up when starting a game/entering test mode */
- { "cbaj", mg01, mg03 }, /* OK */
- { "shngmtkb", mg01, mg04 }, /* OK */
- { "doapp", mg01, mg05 }, /* OK */
- { "flamegun", mg01, mg06 }, /* OK */
- { "flamegunj",mg01, mg06 }, /* OK */
- { "lpadv", mg01, mg07 },
- { "glpracr3", mg01, mg08 },
- { "glpracr3j",mg01, mg08 },
- { "tondemo", mg01, mg09 }, /* OK */
- { "1on1gov", mg01, mg10 }, /* OK */
- { "brvblade", mg01, mg11 }, /* OK */
- { "brvbladeu", mg01, mg11 }, /* OK */
- { "brvbladea", mg01, mg11 }, /* OK */
- { "brvbladej", mg01, mg11 }, /* OK */
- { "tblkkuzu", mg01, mg12 }, /* OK */
- { "tecmowcm", mg01, mg13 }, /* OK */
- { "mfjump", mg01, mg14 }, /* OK */
- { "sfchamp", tt01, tt02 }, /* OK */
- { "sfchampo", tt01, tt02 }, /* OK */
- { "sfchampu", tt01, tt02 }, /* OK */
- { "sfchampj", tt01, tt02 }, /* OK */
- { "psyforce", tt01, tt03 }, /* OK */
- { "psyforcej",tt01, tt03 }, /* OK */
- { "psyforcex",tt01, tt03 }, /* OK */
- { "raystorm", tt01, tt04 }, /* OK */
- { "raystormo",tt01, tt04 }, /* OK */
- { "raystormu",tt01, tt04 }, /* OK */
- { "raystormj",tt01, tt04 }, /* OK */
- { "ftimpact", tt01, tt05 }, /* OK */
- { "ftimpactu",tt01, tt05 }, /* OK */
- { "ftimpactj",tt01, tt05 }, /* OK */
- { "ftimpcta", tt01, tt05 }, /* OK */
- { "mgcldate", tt01, tt06 }, /* OK */
- { "mgcldtex", tt01, tt06 }, /* OK */
- { "gdarius", tt01, tt07 }, /* OK */
- { "gdariusb", tt01, tt07 }, /* OK */
- { "gdarius2", tt01, tt07 }, /* OK */
- { "aerofgts", kn01, kn02 }, /* OK */
- { "sncwgltd", kn01, kn02 }, /* OK */
- /* 2009-10 FP: to avoid crash when running BIOS sets alone, I added the entries below. */
- /* Now we get "Error B930 - Cannot Find Program Rom". Is this the correct way to handle them? */
- { "acpsx", ac01, ac02 },
- { "atpsx", tw01, tw02 },
- { "atluspsx", at01, at02 },
- { "cpzn1", cp01, cp02 },
- { "cpzn2", cp01, cp02 },
- { "psarc95", et01, et02 },
- { "tps", mg01, mg02 },
- { "taitofx1", tt01, tt02 },
- { "vspsx", kn01, kn02 },
- { nullptr, nullptr, nullptr }
-};
-
READ8_MEMBER(zn_state::znsecsel_r)
{
verboselog(2, "znsecsel_r( %08x, %08x )\n", offset, mem_mask );
@@ -441,23 +325,6 @@ static ADDRESS_MAP_START( zn_map, AS_PROGRAM, 32, zn_state )
AM_RANGE(0x1fb20000, 0x1fb20007) AM_READ16(unknown_r, 0xffffffff)
ADDRESS_MAP_END
-void zn_state::driver_start()
-{
- int n_game;
-
- n_game = 0;
- while( zn_config_table[ n_game ].s_name != nullptr )
- {
- if( strcmp( machine().system().name, zn_config_table[ n_game ].s_name ) == 0 )
- {
- m_cat702_1->init( zn_config_table[ n_game ].p_n_mainsec );
- m_cat702_2->init( zn_config_table[ n_game ].p_n_gamesec );
- break;
- }
- n_game++;
- }
-}
-
static MACHINE_CONFIG_START( zn1_1mb_vram, zn_state )
/* basic machine hardware */
@@ -735,10 +602,23 @@ static MACHINE_CONFIG_DERIVED( coh1000c, zn1_1mb_vram )
MCFG_QSOUND_ADD("qsound", QSOUND_CLOCK)
MCFG_SOUND_ROUTE(0, "lspeaker", 1.0)
MCFG_SOUND_ROUTE(1, "rspeaker", 1.0)
+
+ MCFG_DEVICE_MODIFY("cat702_1")
+ MCFG_CAT702_TRANSFORM_TABLE(cp01)
+ MCFG_DEVICE_MODIFY("cat702_2")
+ MCFG_CAT702_TRANSFORM_TABLE(cp02)
+MACHINE_CONFIG_END
+
+static MACHINE_CONFIG_DERIVED( starglad, coh1000c )
+ MCFG_DEVICE_MODIFY("cat702_2")
+ MCFG_CAT702_TRANSFORM_TABLE(cp03)
MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( glpracr, coh1000c )
MCFG_MACHINE_RESET_OVERRIDE(zn_state, glpracr)
+
+ MCFG_DEVICE_MODIFY("cat702_2")
+ MCFG_CAT702_TRANSFORM_TABLE(cp05)
MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( coh1002c, zn1_2mb_vram )
@@ -755,6 +635,11 @@ static MACHINE_CONFIG_DERIVED( coh1002c, zn1_2mb_vram )
MCFG_QSOUND_ADD("qsound", QSOUND_CLOCK)
MCFG_SOUND_ROUTE(0, "lspeaker", 1.0)
MCFG_SOUND_ROUTE(1, "rspeaker", 1.0)
+
+ MCFG_DEVICE_MODIFY("cat702_1")
+ MCFG_CAT702_TRANSFORM_TABLE(cp01)
+ MCFG_DEVICE_MODIFY("cat702_2")
+ MCFG_CAT702_TRANSFORM_TABLE(cp04)
MACHINE_CONFIG_END
/*
@@ -912,6 +797,41 @@ static MACHINE_CONFIG_DERIVED(coh3002c, zn2)
MCFG_QSOUND_ADD("qsound", QSOUND_CLOCK)
MCFG_SOUND_ROUTE(0, "lspeaker", 1.0)
MCFG_SOUND_ROUTE(1, "rspeaker", 1.0)
+
+ MCFG_DEVICE_MODIFY("cat702_1")
+ MCFG_CAT702_TRANSFORM_TABLE(cp10)
+ MCFG_DEVICE_MODIFY("cat702_2")
+ MCFG_CAT702_TRANSFORM_TABLE(cp06)
+MACHINE_CONFIG_END
+
+static MACHINE_CONFIG_DERIVED(plsmaswd, coh3002c)
+ MCFG_DEVICE_MODIFY("cat702_2")
+ MCFG_CAT702_TRANSFORM_TABLE(cp07)
+MACHINE_CONFIG_END
+
+static MACHINE_CONFIG_DERIVED(sfex2, coh3002c)
+ MCFG_DEVICE_MODIFY("cat702_2")
+ MCFG_CAT702_TRANSFORM_TABLE(cp08)
+MACHINE_CONFIG_END
+
+static MACHINE_CONFIG_DERIVED(techromn, coh3002c)
+ MCFG_DEVICE_MODIFY("cat702_2")
+ MCFG_CAT702_TRANSFORM_TABLE(cp09)
+MACHINE_CONFIG_END
+
+static MACHINE_CONFIG_DERIVED(tgmj, coh3002c)
+ MCFG_DEVICE_MODIFY("cat702_2")
+ MCFG_CAT702_TRANSFORM_TABLE(cp11)
+MACHINE_CONFIG_END
+
+static MACHINE_CONFIG_DERIVED(sfex2p, coh3002c)
+ MCFG_DEVICE_MODIFY("cat702_2")
+ MCFG_CAT702_TRANSFORM_TABLE(cp12)
+MACHINE_CONFIG_END
+
+static MACHINE_CONFIG_DERIVED(strider2, coh3002c)
+ MCFG_DEVICE_MODIFY("cat702_2")
+ MCFG_CAT702_TRANSFORM_TABLE(cp13)
MACHINE_CONFIG_END
/*
@@ -1201,6 +1121,21 @@ static MACHINE_CONFIG_DERIVED( coh1000ta, zn1_1mb_vram )
MCFG_DEVICE_ADD("tc0140syt", TC0140SYT, 0)
MCFG_TC0140SYT_MASTER_CPU("maincpu")
MCFG_TC0140SYT_SLAVE_CPU("audiocpu")
+
+ MCFG_DEVICE_MODIFY("cat702_1")
+ MCFG_CAT702_TRANSFORM_TABLE(tt01)
+ MCFG_DEVICE_MODIFY("cat702_2")
+ MCFG_CAT702_TRANSFORM_TABLE(tt02)
+MACHINE_CONFIG_END
+
+static MACHINE_CONFIG_DERIVED( psyforce, coh1000ta )
+ MCFG_DEVICE_MODIFY("cat702_2")
+ MCFG_CAT702_TRANSFORM_TABLE(tt03)
+MACHINE_CONFIG_END
+
+static MACHINE_CONFIG_DERIVED( mgcldate, coh1000ta )
+ MCFG_DEVICE_MODIFY("cat702_2")
+ MCFG_CAT702_TRANSFORM_TABLE(tt06)
MACHINE_CONFIG_END
WRITE8_MEMBER(zn_state::fx1b_fram_w)
@@ -1254,6 +1189,16 @@ static MACHINE_CONFIG_DERIVED(coh1000tb, zn1_1mb_vram)
MCFG_SOUND_ROUTE(1, "rspeaker", 0.45)
MCFG_FRAGMENT_ADD(taito_zoom_sound)
+
+ MCFG_DEVICE_MODIFY("cat702_1")
+ MCFG_CAT702_TRANSFORM_TABLE(tt01)
+ MCFG_DEVICE_MODIFY("cat702_2")
+ MCFG_CAT702_TRANSFORM_TABLE(tt04)
+MACHINE_CONFIG_END
+
+static MACHINE_CONFIG_DERIVED(ftimpact, coh1000tb)
+ MCFG_DEVICE_MODIFY("cat702_2")
+ MCFG_CAT702_TRANSFORM_TABLE(tt05)
MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED(coh1002tb, zn1_2mb_vram)
@@ -1274,6 +1219,11 @@ static MACHINE_CONFIG_DERIVED(coh1002tb, zn1_2mb_vram)
MCFG_SOUND_ROUTE(1, "rspeaker", 0.45)
MCFG_FRAGMENT_ADD(taito_zoom_sound)
+
+ MCFG_DEVICE_MODIFY("cat702_1")
+ MCFG_CAT702_TRANSFORM_TABLE(tt01)
+ MCFG_DEVICE_MODIFY("cat702_2")
+ MCFG_CAT702_TRANSFORM_TABLE(tt07)
MACHINE_CONFIG_END
/*
@@ -1509,6 +1459,11 @@ static MACHINE_CONFIG_DERIVED( coh1000w, zn1_2mb_vram )
MCFG_ATA_INTERFACE_IRQ_HANDLER(DEVWRITELINE("maincpu:irq", psxirq_device, intin10))
MCFG_PSX_DMA_CHANNEL_READ( "maincpu", 5, psx_dma_read_delegate( FUNC( zn_state::atpsx_dma_read ), (zn_state *) owner ) )
MCFG_PSX_DMA_CHANNEL_WRITE( "maincpu", 5, psx_dma_write_delegate( FUNC( zn_state::atpsx_dma_write ), (zn_state *) owner ) )
+
+ MCFG_DEVICE_MODIFY("cat702_1")
+ MCFG_CAT702_TRANSFORM_TABLE(tw01)
+ MCFG_DEVICE_MODIFY("cat702_2")
+ MCFG_CAT702_TRANSFORM_TABLE(tw02)
MACHINE_CONFIG_END
/*
@@ -1706,6 +1661,23 @@ static MACHINE_CONFIG_DERIVED(coh1002e, zn1_2mb_vram)
MCFG_SOUND_ADD("ymf", YMF271, XTAL_16_9344MHz)
MCFG_SOUND_ROUTE(0, "lspeaker", 1.0)
MCFG_SOUND_ROUTE(1, "rspeaker", 1.0)
+
+ MCFG_DEVICE_MODIFY("cat702_1")
+ MCFG_CAT702_TRANSFORM_TABLE(et01)
+ MCFG_DEVICE_MODIFY("cat702_2")
+ MCFG_CAT702_TRANSFORM_TABLE(et02)
+MACHINE_CONFIG_END
+
+static MACHINE_CONFIG_DERIVED(bldyror2, coh1002e)
+ MCFG_DEVICE_MODIFY("cat702_2")
+ MCFG_CAT702_TRANSFORM_TABLE(et03)
+MACHINE_CONFIG_END
+
+static MACHINE_CONFIG_DERIVED(brvblade, coh1002e)
+ MCFG_DEVICE_MODIFY("cat702_1")
+ MCFG_CAT702_TRANSFORM_TABLE(mg01)
+ MCFG_DEVICE_MODIFY("cat702_2")
+ MCFG_CAT702_TRANSFORM_TABLE(mg11)
MACHINE_CONFIG_END
@@ -1825,6 +1797,11 @@ static MACHINE_CONFIG_DERIVED( bam2, zn1_2mb_vram )
MCFG_CPU_PROGRAM_MAP(bam2_map)
MCFG_MACHINE_RESET_OVERRIDE(zn_state, bam2)
+
+ MCFG_DEVICE_MODIFY("cat702_1")
+ MCFG_CAT702_TRANSFORM_TABLE(et01)
+ MCFG_DEVICE_MODIFY("cat702_2")
+ MCFG_CAT702_TRANSFORM_TABLE(et05)
MACHINE_CONFIG_END
/*
@@ -2137,16 +2114,20 @@ static MACHINE_CONFIG_DERIVED( coh1000a, zn1_2mb_vram )
MCFG_CPU_MODIFY("maincpu")
MCFG_CPU_PROGRAM_MAP(coh1000a_map)
+ MCFG_DEVICE_MODIFY("cat702_1")
+ MCFG_CAT702_TRANSFORM_TABLE(ac01)
+ MCFG_DEVICE_MODIFY("cat702_2")
+ MCFG_CAT702_TRANSFORM_TABLE(ac02)
MACHINE_CONFIG_END
-static MACHINE_CONFIG_DERIVED( nbajamex, zn1_2mb_vram )
+static MACHINE_CONFIG_DERIVED( nbajamex, coh1000a )
MCFG_CPU_MODIFY("maincpu")
MCFG_CPU_PROGRAM_MAP(nbajamex_map)
MCFG_MACHINE_RESET_OVERRIDE(zn_state, nbajamex)
MACHINE_CONFIG_END
-static MACHINE_CONFIG_DERIVED( jdredd, zn1_2mb_vram )
+static MACHINE_CONFIG_DERIVED( jdredd, coh1000a )
MCFG_CPU_MODIFY("maincpu")
MCFG_CPU_PROGRAM_MAP(jdredd_map)
@@ -2325,6 +2306,11 @@ static MACHINE_CONFIG_DERIVED(coh1001l, zn1_2mb_vram)
MCFG_YMZ280B_IRQ_HANDLER(INPUTLINE("audiocpu", 2))
MCFG_SOUND_ROUTE(0, "lspeaker", 0.35)
MCFG_SOUND_ROUTE(1, "rspeaker", 0.35)
+
+ MCFG_DEVICE_MODIFY("cat702_1")
+ MCFG_CAT702_TRANSFORM_TABLE(at01)
+ MCFG_DEVICE_MODIFY("cat702_2")
+ MCFG_CAT702_TRANSFORM_TABLE(at02)
MACHINE_CONFIG_END
/*
@@ -2363,6 +2349,11 @@ static MACHINE_CONFIG_DERIVED( coh1002v, zn1_2mb_vram )
MCFG_CPU_PROGRAM_MAP(coh1002v_map)
MCFG_MACHINE_RESET_OVERRIDE(zn_state, coh1002v)
+
+ MCFG_DEVICE_MODIFY("cat702_1")
+ MCFG_CAT702_TRANSFORM_TABLE(kn01)
+ MCFG_DEVICE_MODIFY("cat702_2")
+ MCFG_CAT702_TRANSFORM_TABLE(kn02)
MACHINE_CONFIG_END
/*
@@ -2546,6 +2537,61 @@ static MACHINE_CONFIG_DERIVED( coh1002m, zn1_2mb_vram )
MCFG_CPU_PROGRAM_MAP(coh1002m_map)
MCFG_MACHINE_RESET_OVERRIDE(zn_state, coh1002m)
+
+ MCFG_DEVICE_MODIFY("cat702_1")
+ MCFG_CAT702_TRANSFORM_TABLE(mg01)
+ MCFG_DEVICE_MODIFY("cat702_2")
+ MCFG_CAT702_TRANSFORM_TABLE(mg02)
+MACHINE_CONFIG_END
+
+static MACHINE_CONFIG_DERIVED( shngmtkb, coh1002m )
+ MCFG_DEVICE_MODIFY("cat702_2")
+ MCFG_CAT702_TRANSFORM_TABLE(mg04)
+MACHINE_CONFIG_END
+
+static MACHINE_CONFIG_DERIVED( doapp, coh1002m )
+ MCFG_DEVICE_MODIFY("cat702_2")
+ MCFG_CAT702_TRANSFORM_TABLE(mg05)
+MACHINE_CONFIG_END
+
+static MACHINE_CONFIG_DERIVED( flamegun, coh1002m )
+ MCFG_DEVICE_MODIFY("cat702_2")
+ MCFG_CAT702_TRANSFORM_TABLE(mg06)
+MACHINE_CONFIG_END
+
+static MACHINE_CONFIG_DERIVED( lpadv, coh1002m )
+ MCFG_DEVICE_MODIFY("cat702_2")
+ MCFG_CAT702_TRANSFORM_TABLE(mg07)
+MACHINE_CONFIG_END
+
+static MACHINE_CONFIG_DERIVED( glpracr3, coh1002m )
+ MCFG_DEVICE_MODIFY("cat702_2")
+ MCFG_CAT702_TRANSFORM_TABLE(mg08)
+MACHINE_CONFIG_END
+
+static MACHINE_CONFIG_DERIVED( tondemo, coh1002m )
+ MCFG_DEVICE_MODIFY("cat702_2")
+ MCFG_CAT702_TRANSFORM_TABLE(mg09)
+MACHINE_CONFIG_END
+
+static MACHINE_CONFIG_DERIVED( 1on1gov, coh1002m )
+ MCFG_DEVICE_MODIFY("cat702_2")
+ MCFG_CAT702_TRANSFORM_TABLE(mg10)
+MACHINE_CONFIG_END
+
+static MACHINE_CONFIG_DERIVED( tblkkuzu, coh1002m )
+ MCFG_DEVICE_MODIFY("cat702_2")
+ MCFG_CAT702_TRANSFORM_TABLE(mg12)
+MACHINE_CONFIG_END
+
+static MACHINE_CONFIG_DERIVED( tecmowcm, coh1002m )
+ MCFG_DEVICE_MODIFY("cat702_2")
+ MCFG_CAT702_TRANSFORM_TABLE(mg13)
+MACHINE_CONFIG_END
+
+static MACHINE_CONFIG_DERIVED( mfjump, coh1002m )
+ MCFG_DEVICE_MODIFY("cat702_2")
+ MCFG_CAT702_TRANSFORM_TABLE(mg14)
MACHINE_CONFIG_END
READ8_MEMBER(zn_state::cbaj_sound_main_status_r)
@@ -2609,6 +2655,9 @@ static MACHINE_CONFIG_DERIVED( coh1002msnd, coh1002m )
MCFG_SOUND_ADD("ymz", YMZ280B, XTAL_16_9344MHz)
MCFG_SOUND_ROUTE(0, "lspeaker", 0.35)
MCFG_SOUND_ROUTE(1, "rspeaker", 0.35)
+
+ MCFG_DEVICE_MODIFY("cat702_2")
+ MCFG_CAT702_TRANSFORM_TABLE(mg03)
MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( coh1002ml, coh1002m )
@@ -4832,8 +4881,8 @@ GAME( 1995, cpzn1, 0, coh1000c, zn, driver_device, 0, ROT0, "Capcom
GAME( 1995, ts2, cpzn1, coh1000c, zn6b, driver_device, 0, ROT0, "Capcom / Takara", "Battle Arena Toshinden 2 (USA 951124)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
GAME( 1995, ts2a, ts2, coh1000c, zn6b, driver_device, 0, ROT0, "Capcom / Takara", "Battle Arena Toshinden 2 (USA 951124) Older", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
GAME( 1995, ts2j, ts2, coh1000c, zn6b, driver_device, 0, ROT0, "Capcom / Takara", "Battle Arena Toshinden 2 (Japan 951124)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
-GAME( 1996, starglad, cpzn1, coh1000c, zn6b, driver_device, 0, ROT0, "Capcom", "Star Gladiator Episode I: Final Crusade (USA 960627)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
-GAME( 1996, stargladj, starglad, coh1000c, zn6b, driver_device, 0, ROT0, "Capcom", "Star Gladiator Episode I: Final Crusade (Japan 960627)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
+GAME( 1996, starglad, cpzn1, starglad, zn6b, driver_device, 0, ROT0, "Capcom", "Star Gladiator Episode I: Final Crusade (USA 960627)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
+GAME( 1996, stargladj, starglad, starglad, zn6b, driver_device, 0, ROT0, "Capcom", "Star Gladiator Episode I: Final Crusade (Japan 960627)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
GAME( 1996, glpracr, cpzn1, glpracr, zn, driver_device, 0, ROT0, "Tecmo", "Gallop Racer (English Ver 10.17.K)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
GAME( 1996, glpracrj, glpracr, glpracr, zn, driver_device, 0, ROT0, "Tecmo", "Gallop Racer (Japanese Ver 9.01.12)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
GAME( 1996, sfex, cpzn1, coh1002c, zn6b, driver_device, 0, ROT0, "Capcom / Arika", "Street Fighter EX (Euro 961219)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
@@ -4856,24 +4905,24 @@ GAME( 1997, rvschool, cpzn2, coh3002c, zn6b, driver_device, 0, ROT0, "Capcom
GAME( 1997, rvschoolu, rvschool, coh3002c, zn6b, driver_device, 0, ROT0, "Capcom", "Rival Schools: United By Fate (USA 971117)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
GAME( 1997, rvschoola, rvschool, coh3002c, zn6b, driver_device, 0, ROT0, "Capcom", "Rival Schools: United By Fate (Asia 971117)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
GAME( 1997, jgakuen, rvschool, coh3002c, zn6b, driver_device, 0, ROT0, "Capcom", "Shiritsu Justice Gakuen: Legion of Heroes (Japan 971117)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
-GAME( 1998, sfex2, cpzn2, coh3002c, zn6b, driver_device, 0, ROT0, "Capcom / Arika", "Street Fighter EX2 (USA 980526)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
-GAME( 1998, sfex2a, sfex2, coh3002c, zn6b, driver_device, 0, ROT0, "Capcom / Arika", "Street Fighter EX2 (Asia 980312)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
-GAME( 1998, sfex2h, sfex2, coh3002c, zn6b, driver_device, 0, ROT0, "Capcom / Arika", "Street Fighter EX2 (Hispanic 980312)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
-GAME( 1998, sfex2j, sfex2, coh3002c, zn6b, driver_device, 0, ROT0, "Capcom / Arika", "Street Fighter EX2 (Japan 980312)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
-GAME( 1998, plsmaswd, cpzn2, coh3002c, zn6b, driver_device, 0, ROT0, "Capcom", "Plasma Sword: Nightmare of Bilstein (USA 980316)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
-GAME( 1998, plsmaswda, plsmaswd, coh3002c, zn6b, driver_device, 0, ROT0, "Capcom", "Plasma Sword: Nightmare of Bilstein (Asia 980316)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
-GAME( 1998, stargld2, plsmaswd, coh3002c, zn6b, driver_device, 0, ROT0, "Capcom", "Star Gladiator 2: Nightmare of Bilstein (Japan 980316)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
-GAME( 1998, tgmj, cpzn2, coh3002c, zn4w, driver_device, 0, ROT0, "Arika / Capcom", "Tetris The Grand Master (Japan 980710)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
-GAME( 1998, techromn, cpzn2, coh3002c, zn6b, driver_device, 0, ROT0, "Capcom", "Tech Romancer (Euro 980914)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
-GAME( 1998, techromnu, techromn, coh3002c, zn6b, driver_device, 0, ROT0, "Capcom", "Tech Romancer (USA 980914)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
-GAME( 1998, kikaioh, techromn, coh3002c, zn6b, driver_device, 0, ROT0, "Capcom", "Choukou Senki Kikaioh (Japan 980914)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
-GAME( 1999, sfex2p, cpzn2, coh3002c, zn6b, driver_device, 0, ROT0, "Capcom / Arika", "Street Fighter EX2 Plus (USA 990611)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
-GAME( 1999, sfex2pa, sfex2p, coh3002c, zn6b, driver_device, 0, ROT0, "Capcom / Arika", "Street Fighter EX2 Plus (Asia 990611)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
-GAME( 1999, sfex2ph, sfex2p, coh3002c, zn6b, driver_device, 0, ROT0, "Capcom / Arika", "Street Fighter EX2 Plus (Hispanic 990611)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
-GAME( 1999, sfex2pj, sfex2p, coh3002c, zn6b, driver_device, 0, ROT0, "Capcom / Arika", "Street Fighter EX2 Plus (Japan 990611)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
-GAME( 1999, strider2, cpzn2, coh3002c, zn, driver_device, 0, ROT0, "Capcom", "Strider 2 (USA 991213)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_NOT_WORKING ) // random hangs / crashes
-GAME( 1999, strider2a, strider2, coh3002c, zn, driver_device, 0, ROT0, "Capcom", "Strider 2 (Asia 991213)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_NOT_WORKING )
-GAME( 1999, shiryu2, strider2, coh3002c, zn, driver_device, 0, ROT0, "Capcom", "Strider Hiryu 2 (Japan 991213)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_NOT_WORKING )
+GAME( 1998, sfex2, cpzn2, sfex2, zn6b, driver_device, 0, ROT0, "Capcom / Arika", "Street Fighter EX2 (USA 980526)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
+GAME( 1998, sfex2a, sfex2, sfex2, zn6b, driver_device, 0, ROT0, "Capcom / Arika", "Street Fighter EX2 (Asia 980312)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
+GAME( 1998, sfex2h, sfex2, sfex2, zn6b, driver_device, 0, ROT0, "Capcom / Arika", "Street Fighter EX2 (Hispanic 980312)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
+GAME( 1998, sfex2j, sfex2, sfex2, zn6b, driver_device, 0, ROT0, "Capcom / Arika", "Street Fighter EX2 (Japan 980312)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
+GAME( 1998, plsmaswd, cpzn2, plsmaswd, zn6b, driver_device, 0, ROT0, "Capcom", "Plasma Sword: Nightmare of Bilstein (USA 980316)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
+GAME( 1998, plsmaswda, plsmaswd, plsmaswd, zn6b, driver_device, 0, ROT0, "Capcom", "Plasma Sword: Nightmare of Bilstein (Asia 980316)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
+GAME( 1998, stargld2, plsmaswd, plsmaswd, zn6b, driver_device, 0, ROT0, "Capcom", "Star Gladiator 2: Nightmare of Bilstein (Japan 980316)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
+GAME( 1998, tgmj, cpzn2, tgmj, zn4w, driver_device, 0, ROT0, "Arika / Capcom", "Tetris The Grand Master (Japan 980710)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
+GAME( 1998, techromn, cpzn2, techromn, zn6b, driver_device, 0, ROT0, "Capcom", "Tech Romancer (Euro 980914)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
+GAME( 1998, techromnu, techromn, techromn, zn6b, driver_device, 0, ROT0, "Capcom", "Tech Romancer (USA 980914)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
+GAME( 1998, kikaioh, techromn, techromn, zn6b, driver_device, 0, ROT0, "Capcom", "Choukou Senki Kikaioh (Japan 980914)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
+GAME( 1999, sfex2p, cpzn2, sfex2p, zn6b, driver_device, 0, ROT0, "Capcom / Arika", "Street Fighter EX2 Plus (USA 990611)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
+GAME( 1999, sfex2pa, sfex2p, sfex2p, zn6b, driver_device, 0, ROT0, "Capcom / Arika", "Street Fighter EX2 Plus (Asia 990611)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
+GAME( 1999, sfex2ph, sfex2p, sfex2p, zn6b, driver_device, 0, ROT0, "Capcom / Arika", "Street Fighter EX2 Plus (Hispanic 990611)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
+GAME( 1999, sfex2pj, sfex2p, sfex2p, zn6b, driver_device, 0, ROT0, "Capcom / Arika", "Street Fighter EX2 Plus (Japan 990611)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
+GAME( 1999, strider2, cpzn2, strider2, zn, driver_device, 0, ROT0, "Capcom", "Strider 2 (USA 991213)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_NOT_WORKING ) // random hangs / crashes
+GAME( 1999, strider2a, strider2, strider2, zn, driver_device, 0, ROT0, "Capcom", "Strider 2 (Asia 991213)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_NOT_WORKING )
+GAME( 1999, shiryu2, strider2, strider2, zn, driver_device, 0, ROT0, "Capcom", "Strider Hiryu 2 (Japan 991213)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_NOT_WORKING )
/* Atari */
@@ -4882,7 +4931,7 @@ GAME( 1999, shiryu2, strider2, coh3002c, zn, driver_device, 0, ROT0, "Capcom
/* it in every zip file */
GAME( 1996, atpsx, 0, coh1000w, zn, driver_device, 0, ROT0, "Atari", "Atari PSX", MACHINE_IS_BIOS_ROOT )
-GAME( 1996, primrag2, atpsx, coh1000w, primrag2, driver_device, 0, ROT0, "Atari", "Primal Rage 2 (Ver 0.36a)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_NOT_WORKING )
+GAME( 1996, primrag2, atpsx, coh1000w, primrag2, driver_device, 0, ROT0, "Atari", "Primal Rage 2 (Ver 0.36a)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_NOT_WORKING ) // locks up when starting a game
/* Acclaim */
@@ -4902,22 +4951,22 @@ GAME( 1996, jdreddb, jdredd, jdredd, jdredd, driver_device, 0, ROT0, "Accla
/* it in every zip file */
GAME( 1997, tps, 0, coh1002m, zn, driver_device, 0, ROT0, "Tecmo", "TPS", MACHINE_IS_BIOS_ROOT )
-GAME( 1997, glpracr2, tps, coh1002m, zn, driver_device, 0, ROT0, "Tecmo", "Gallop Racer 2 (USA)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_NOT_WORKING )
+GAME( 1997, glpracr2, tps, coh1002m, zn, driver_device, 0, ROT0, "Tecmo", "Gallop Racer 2 (USA)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_NOT_WORKING ) // locks up when starting a game/entering test mode
GAME( 1997, glpracr2j, glpracr2, coh1002m, zn, driver_device, 0, ROT0, "Tecmo", "Gallop Racer 2 (Japan)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_NOT_WORKING )
GAME( 1997, glpracr2l, glpracr2, coh1002ml, zn, driver_device, 0, ROT0, "Tecmo", "Gallop Racer 2 Link HW (Japan)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_NOT_WORKING )
-GAME( 1998, doapp, tps, coh1002m, zn, driver_device, 0, ROT0, "Tecmo", "Dead Or Alive ++ (Japan)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
+GAME( 1998, doapp, tps, doapp, zn, driver_device, 0, ROT0, "Tecmo", "Dead Or Alive ++ (Japan)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
GAME( 1998, cbaj, tps, coh1002msnd, zn, driver_device, 0, ROT0, "UEP Systems", "Cool Boarders Arcade Jam", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
-GAME( 1998, shngmtkb, tps, coh1002m, zn, driver_device, 0, ROT0, "Sunsoft / Activision", "Shanghai Matekibuyuu", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
-GAME( 1999, tondemo, tps, coh1002m, zn, driver_device, 0, ROT0, "Tecmo", "Tondemo Crisis (Japan)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
-GAME( 1999, glpracr3, tps, coh1002m, zn, driver_device, 0, ROT0, "Tecmo", "Gallop Racer 3 (Export)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
-GAME( 1999, glpracr3j, glpracr3, coh1002m, zn, driver_device, 0, ROT0, "Tecmo", "Gallop Racer 3 (Japan)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
-GAME( 1999, flamegun, tps, coh1002m, zn, driver_device, 0, ROT0, "Gaps Inc.", "Flame Gunner", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
-GAME( 1999, flamegunj, flamegun, coh1002m, zn, driver_device, 0, ROT0, "Gaps Inc.", "Flame Gunner (Japan)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
-GAME( 1999, lpadv, tps, coh1002m, zn, driver_device, 0, ROT0, "Amuse World", "Logic Pro Adventure (Japan)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
-GAME( 2000, tblkkuzu, tps, coh1002m, zn, driver_device, 0, ROT0, "Tamsoft / D3 Publisher", "The Block Kuzushi (Japan)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
-GAME( 2000, 1on1gov, tps, coh1002m, zn, driver_device, 0, ROT0, "Tecmo", "1 on 1 Government (Japan)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
-GAME( 2000, tecmowcm, tps, coh1002m, zn, driver_device, 0, ROT0, "Tecmo", "Tecmo World Cup Millennium (Japan)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
-GAME( 2001, mfjump, tps, coh1002m, zn, driver_device, 0, ROT0, "Tecmo", "Monster Farm Jump (Japan)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
+GAME( 1998, shngmtkb, tps, shngmtkb, zn, driver_device, 0, ROT0, "Sunsoft / Activision", "Shanghai Matekibuyuu", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
+GAME( 1999, tondemo, tps, tondemo, zn, driver_device, 0, ROT0, "Tecmo", "Tondemo Crisis (Japan)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
+GAME( 1999, glpracr3, tps, glpracr3, zn, driver_device, 0, ROT0, "Tecmo", "Gallop Racer 3 (Export)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
+GAME( 1999, glpracr3j, glpracr3, glpracr3, zn, driver_device, 0, ROT0, "Tecmo", "Gallop Racer 3 (Japan)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
+GAME( 1999, flamegun, tps, flamegun, zn, driver_device, 0, ROT0, "Gaps Inc.", "Flame Gunner", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
+GAME( 1999, flamegunj, flamegun, flamegun, zn, driver_device, 0, ROT0, "Gaps Inc.", "Flame Gunner (Japan)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
+GAME( 1999, lpadv, tps, lpadv, zn, driver_device, 0, ROT0, "Amuse World", "Logic Pro Adventure (Japan)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
+GAME( 2000, tblkkuzu, tps, tblkkuzu, zn, driver_device, 0, ROT0, "Tamsoft / D3 Publisher", "The Block Kuzushi (Japan)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
+GAME( 2000, 1on1gov, tps, 1on1gov, zn, driver_device, 0, ROT0, "Tecmo", "1 on 1 Government (Japan)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
+GAME( 2000, tecmowcm, tps, tecmowcm, zn, driver_device, 0, ROT0, "Tecmo", "Tecmo World Cup Millennium (Japan)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
+GAME( 2001, mfjump, tps, mfjump, zn, driver_device, 0, ROT0, "Tecmo", "Monster Farm Jump (Japan)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
/* Video System */
@@ -4940,20 +4989,20 @@ GAME( 1995, sfchamp, taitofx1, coh1000ta, zn, driver_device, 0, ROT0, "Taito",
GAME( 1995, sfchampo, sfchamp, coh1000ta, zn, driver_device, 0, ROT0, "Taito", "Super Football Champ (Ver 2.4O)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
GAME( 1995, sfchampu, sfchamp, coh1000ta, zn, driver_device, 0, ROT0, "Taito", "Super Football Champ (Ver 2.4A)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
GAME( 1995, sfchampj, sfchamp, coh1000ta, zn, driver_device, 0, ROT0, "Taito", "Super Football Champ (Ver 2.4J)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
-GAME( 1995, psyforce, taitofx1, coh1000ta, zn, driver_device, 0, ROT0, "Taito", "Psychic Force (Ver 2.4O)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
-GAME( 1995, psyforcej, psyforce, coh1000ta, zn, driver_device, 0, ROT0, "Taito", "Psychic Force (Ver 2.4J)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
-GAME( 1995, psyforcex, psyforce, coh1000ta, zn, driver_device, 0, ROT0, "Taito", "Psychic Force EX (Ver 2.0J)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
-GAME( 1996, mgcldate, mgcldtex, coh1000ta, zn, driver_device, 0, ROT0, "Taito", "Magical Date / Magical Date - dokidoki kokuhaku daisakusen (Ver 2.02J)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
-GAME( 1997, mgcldtex, taitofx1, coh1000ta, zn, driver_device, 0, ROT0, "Taito", "Magical Date EX / Magical Date - sotsugyou kokuhaku daisakusen (Ver 2.01J)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
+GAME( 1995, psyforce, taitofx1, psyforce, zn, driver_device, 0, ROT0, "Taito", "Psychic Force (Ver 2.4O)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
+GAME( 1995, psyforcej, psyforce, psyforce, zn, driver_device, 0, ROT0, "Taito", "Psychic Force (Ver 2.4J)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
+GAME( 1995, psyforcex, psyforce, psyforce, zn, driver_device, 0, ROT0, "Taito", "Psychic Force EX (Ver 2.0J)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
+GAME( 1996, mgcldate, mgcldtex, mgcldate, zn, driver_device, 0, ROT0, "Taito", "Magical Date / Magical Date - dokidoki kokuhaku daisakusen (Ver 2.02J)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
+GAME( 1997, mgcldtex, taitofx1, mgcldate, zn, driver_device, 0, ROT0, "Taito", "Magical Date EX / Magical Date - sotsugyou kokuhaku daisakusen (Ver 2.01J)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
GAME( 1996, raystorm, taitofx1, coh1000tb, zn, zn_state, coh1000tb, ROT0, "Taito", "Ray Storm (Ver 2.06A)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
GAME( 1996, raystormo, raystorm, coh1000tb, zn, zn_state, coh1000tb, ROT0, "Taito", "Ray Storm (Ver 2.05O)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
GAME( 1996, raystormu, raystorm, coh1000tb, zn, zn_state, coh1000tb, ROT0, "Taito", "Ray Storm (Ver 2.05A)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
GAME( 1996, raystormj, raystorm, coh1000tb, zn, zn_state, coh1000tb, ROT0, "Taito", "Ray Storm (Ver 2.05J)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
-GAME( 1996, ftimpact, ftimpcta, coh1000tb, zn, zn_state, coh1000tb, ROT0, "Taito", "Fighters' Impact (Ver 2.02O)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
-GAME( 1996, ftimpactu, ftimpcta, coh1000tb, zn, zn_state, coh1000tb, ROT0, "Taito", "Fighters' Impact (Ver 2.02A)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
-GAME( 1996, ftimpactj, ftimpcta, coh1000tb, zn, zn_state, coh1000tb, ROT0, "Taito", "Fighters' Impact (Ver 2.02J)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
-GAME( 1997, ftimpcta, taitofx1, coh1000tb, zn, zn_state, coh1000tb, ROT0, "Taito", "Fighters' Impact A (Ver 2.00J)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
+GAME( 1996, ftimpact, ftimpcta, ftimpact, zn, zn_state, coh1000tb, ROT0, "Taito", "Fighters' Impact (Ver 2.02O)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
+GAME( 1996, ftimpactu, ftimpcta, ftimpact, zn, zn_state, coh1000tb, ROT0, "Taito", "Fighters' Impact (Ver 2.02A)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
+GAME( 1996, ftimpactj, ftimpcta, ftimpact, zn, zn_state, coh1000tb, ROT0, "Taito", "Fighters' Impact (Ver 2.02J)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
+GAME( 1997, ftimpcta, taitofx1, ftimpact, zn, zn_state, coh1000tb, ROT0, "Taito", "Fighters' Impact A (Ver 2.00J)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
GAME( 1997, gdarius, gdarius2, coh1002tb, zn, zn_state, coh1000tb, ROT0, "Taito", "G-Darius (Ver 2.01J)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
GAME( 1997, gdariusb, gdarius2, coh1002tb, zn, zn_state, coh1000tb, ROT0, "Taito", "G-Darius (Ver 2.02A)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
GAME( 1997, gdarius2, taitofx1, coh1002tb, zn, zn_state, coh1000tb, ROT0, "Taito", "G-Darius Ver.2 (Ver 2.03J)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
@@ -4970,16 +5019,16 @@ GAME( 1997, bldyroar, beastrzr, coh1002e, zn, driver_device, 0, ROT0, "Eighti
GAME( 1997, beastrzrb, beastrzr, coh1002e, zn, driver_device, 0, ROT0, "bootleg", "Beastorizer (USA bootleg)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_NOT_WORKING )
/* The region on these is determined from the NVRAM, it can't be changed from the test menu, it's pre-programmed */
-GAME( 1998, bldyror2, psarc95, coh1002e, zn6b, driver_device, 0, ROT0, "Eighting / Raizing", "Bloody Roar 2 (World)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
-GAME( 1998, bldyror2u, bldyror2, coh1002e, zn6b, driver_device, 0, ROT0, "Eighting / Raizing", "Bloody Roar 2 (USA)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
-GAME( 1998, bldyror2a, bldyror2, coh1002e, zn6b, driver_device, 0, ROT0, "Eighting / Raizing", "Bloody Roar 2 (Asia)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
-GAME( 1998, bldyror2j, bldyror2, coh1002e, zn6b, driver_device, 0, ROT0, "Eighting / Raizing", "Bloody Roar 2 (Japan)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
+GAME( 1998, bldyror2, psarc95, bldyror2, zn6b, driver_device, 0, ROT0, "Eighting / Raizing", "Bloody Roar 2 (World)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
+GAME( 1998, bldyror2u, bldyror2, bldyror2, zn6b, driver_device, 0, ROT0, "Eighting / Raizing", "Bloody Roar 2 (USA)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
+GAME( 1998, bldyror2a, bldyror2, bldyror2, zn6b, driver_device, 0, ROT0, "Eighting / Raizing", "Bloody Roar 2 (Asia)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
+GAME( 1998, bldyror2j, bldyror2, bldyror2, zn6b, driver_device, 0, ROT0, "Eighting / Raizing", "Bloody Roar 2 (Japan)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
/* The region on these is determined from the NVRAM, it can't be changed from the test menu, it's pre-programmed */
-GAME( 2000, brvblade, tps, coh1002e, zn, driver_device, 0, ROT270, "Eighting / Raizing", "Brave Blade (World)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
-GAME( 2000, brvbladeu, brvblade, coh1002e, zn, driver_device, 0, ROT270, "Eighting / Raizing", "Brave Blade (USA)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
-GAME( 2000, brvbladea, brvblade, coh1002e, zn, driver_device, 0, ROT270, "Eighting / Raizing", "Brave Blade (Asia)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
-GAME( 2000, brvbladej, brvblade, coh1002e, zn, driver_device, 0, ROT270, "Eighting / Raizing", "Brave Blade (Japan)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
+GAME( 2000, brvblade, tps, brvblade, zn, driver_device, 0, ROT270, "Eighting / Raizing", "Brave Blade (World)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
+GAME( 2000, brvbladeu, brvblade, brvblade, zn, driver_device, 0, ROT270, "Eighting / Raizing", "Brave Blade (USA)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
+GAME( 2000, brvbladea, brvblade, brvblade, zn, driver_device, 0, ROT270, "Eighting / Raizing", "Brave Blade (Asia)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
+GAME( 2000, brvbladej, brvblade, brvblade, zn, driver_device, 0, ROT270, "Eighting / Raizing", "Brave Blade (Japan)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
/* Bust a Move 2 uses the PSARC95 bios and ET series security but the top board is completely different */
GAME( 1999, bam2, psarc95, bam2, zn, driver_device, 0, ROT0, "Metro / Enix / Namco", "Bust a Move 2 (Japanese ROM ver. 1999/07/17 10:00:00)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_NOT_WORKING )
diff --git a/src/mame/etc/jrcrypt.cpp b/src/mame/etc/jrcrypt.cpp
index e973df30753..89c1fc0b716 100644
--- a/src/mame/etc/jrcrypt.cpp
+++ b/src/mame/etc/jrcrypt.cpp
@@ -490,8 +490,8 @@ void Load(char *name,byte *buffer,int from, int length)
{
/*
emu_file file(options, NULL, OPEN_FLAG_READ);
- file_error filerr = file.open(name);
- if (filerr != FILERR_NONE)
+ osd_file::error filerr = file.open(name);
+ if (filerr != osd_file::error::NONE)
return;
while (length--)
buffer[from++]=file->getc();
diff --git a/src/mame/includes/angelkds.h b/src/mame/includes/angelkds.h
index ecd59f1e4e5..1617fc2579a 100644
--- a/src/mame/includes/angelkds.h
+++ b/src/mame/includes/angelkds.h
@@ -15,11 +15,9 @@ public:
m_bgbotvideoram(*this, "bgbotvideoram"),
m_txvideoram(*this, "txvideoram"),
m_spriteram(*this, "spriteram"),
- m_paletteram(*this, "paletteram"),
m_subcpu(*this, "sub"),
m_maincpu(*this, "maincpu"),
m_gfxdecode(*this, "gfxdecode"),
- m_palette(*this, "palette"),
m_decrypted_opcodes(*this, "decrypted_opcodes") { }
/* memory pointers */
@@ -27,7 +25,6 @@ public:
required_shared_ptr<UINT8> m_bgbotvideoram;
required_shared_ptr<UINT8> m_txvideoram;
required_shared_ptr<UINT8> m_spriteram;
- required_shared_ptr<UINT8> m_paletteram;
tilemap_t *m_tx_tilemap;
tilemap_t *m_bgbot_tilemap;
@@ -42,8 +39,8 @@ public:
/* devices */
required_device<cpu_device> m_subcpu;
+ DECLARE_READ8_MEMBER(angeklds_ff_r) { return 0xff; };
DECLARE_WRITE8_MEMBER(angelkds_cpu_bank_write);
- DECLARE_READ8_MEMBER(angelkds_input_r);
DECLARE_WRITE8_MEMBER(angelkds_main_sound_w);
DECLARE_READ8_MEMBER(angelkds_main_sound_r);
DECLARE_WRITE8_MEMBER(angelkds_sub_sound_w);
@@ -57,7 +54,6 @@ public:
DECLARE_WRITE8_MEMBER(angelkds_bgbotbank_write);
DECLARE_WRITE8_MEMBER(angelkds_bgbotscroll_write);
DECLARE_WRITE8_MEMBER(angelkds_layer_ctrl_write);
- DECLARE_WRITE8_MEMBER(angelkds_paletteram_w);
DECLARE_DRIVER_INIT(angelkds);
DECLARE_DRIVER_INIT(spcpostn);
TILE_GET_INFO_MEMBER(get_tx_tile_info);
@@ -71,6 +67,5 @@ public:
DECLARE_WRITE_LINE_MEMBER(irqhandler);
required_device<cpu_device> m_maincpu;
required_device<gfxdecode_device> m_gfxdecode;
- required_device<palette_device> m_palette;
optional_shared_ptr<UINT8> m_decrypted_opcodes;
};
diff --git a/src/mame/includes/apple3.h b/src/mame/includes/apple3.h
index 4d53b0bba56..384989adf90 100644
--- a/src/mame/includes/apple3.h
+++ b/src/mame/includes/apple3.h
@@ -98,6 +98,8 @@ public:
DECLARE_VIDEO_START(apple3);
UINT32 screen_update_apple3(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
TIMER_DEVICE_CALLBACK_MEMBER(apple3_interrupt);
+ TIMER_CALLBACK_MEMBER(scanstart_cb);
+ TIMER_CALLBACK_MEMBER(scanend_cb);
DECLARE_WRITE_LINE_MEMBER(apple3_acia_irq_func);
DECLARE_WRITE8_MEMBER(apple3_via_0_out_a);
DECLARE_WRITE8_MEMBER(apple3_via_0_out_b);
@@ -106,12 +108,12 @@ public:
DECLARE_WRITE_LINE_MEMBER(apple3_via_0_irq_func);
DECLARE_WRITE_LINE_MEMBER(apple3_via_1_irq_func);
void apple3_write_charmem();
- void apple3_video_text40(bitmap_ind16 &bitmap);
- void apple3_video_text80(bitmap_ind16 &bitmap);
- void apple3_video_graphics_hgr(bitmap_ind16 &bitmap);
- void apple3_video_graphics_chgr(bitmap_ind16 &bitmap);
- void apple3_video_graphics_shgr(bitmap_ind16 &bitmap);
- void apple3_video_graphics_chires(bitmap_ind16 &bitmap);
+ void text40(bitmap_ind16 &bitmap, const rectangle &cliprect);
+ void text80(bitmap_ind16 &bitmap, const rectangle &cliprect);
+ void graphics_hgr(bitmap_ind16 &bitmap, const rectangle &cliprect);
+ void graphics_chgr(bitmap_ind16 &bitmap, const rectangle &cliprect);
+ void graphics_shgr(bitmap_ind16 &bitmap, const rectangle &cliprect);
+ void graphics_chires(bitmap_ind16 &bitmap, const rectangle &cliprect);
UINT8 *apple3_bankaddr(UINT16 bank, offs_t offset);
UINT8 *apple3_get_zpa_addr(offs_t offset);
void apple3_update_memory();
@@ -160,6 +162,8 @@ private:
UINT16 m_lastchar, m_strobe;
UINT8 m_transchar;
+ emu_timer *m_scanstart, *m_scanend;
+
int m_analog_sel;
bool m_ramp_active;
int m_pdl_charge;
diff --git a/src/mame/includes/hh_tms1k.h b/src/mame/includes/hh_tms1k.h
index 46f6530ae7a..46372415b47 100644
--- a/src/mame/includes/hh_tms1k.h
+++ b/src/mame/includes/hh_tms1k.h
@@ -9,9 +9,14 @@
#ifndef _HH_TMS1K_H_
#define _HH_TMS1K_H_
-
#include "emu.h"
-#include "cpu/tms0980/tms0980.h"
+#include "cpu/tms1000/tms1000.h"
+#include "cpu/tms1000/tms1100.h"
+#include "cpu/tms1000/tms1400.h"
+#include "cpu/tms1000/tms0970.h"
+#include "cpu/tms1000/tms0980.h"
+#include "cpu/tms1000/tms0270.h"
+#include "cpu/tms1000/tp0320.h"
#include "sound/speaker.h"
diff --git a/src/mame/includes/himesiki.h b/src/mame/includes/himesiki.h
index 65cf5bbcba2..5412e564b2a 100644
--- a/src/mame/includes/himesiki.h
+++ b/src/mame/includes/himesiki.h
@@ -12,6 +12,7 @@ public:
himesiki_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag),
m_bg_ram(*this, "bg_ram"),
+ m_spriteram_p103a(*this, "sprram_p103a"),
m_spriteram(*this, "spriteram"),
m_subcpu(*this, "sub"),
m_maincpu(*this, "maincpu"),
@@ -20,11 +21,14 @@ public:
/* memory pointers */
required_shared_ptr<UINT8> m_bg_ram;
+ required_shared_ptr<UINT8> m_spriteram_p103a;
required_shared_ptr<UINT8> m_spriteram;
/* video-related */
tilemap_t *m_bg_tilemap;
int m_scrollx[2];
+ int m_scrolly;
+
int m_flipscreen;
/* devices */
@@ -33,7 +37,7 @@ public:
DECLARE_WRITE8_MEMBER(himesiki_sound_w);
DECLARE_WRITE8_MEMBER(himesiki_bg_ram_w);
DECLARE_WRITE8_MEMBER(himesiki_scrollx_w);
- DECLARE_WRITE8_MEMBER(himesiki_flip_w);
+ DECLARE_WRITE8_MEMBER(himesiki_scrolly_w);
TILE_GET_INFO_MEMBER(get_bg_tile_info);
virtual void machine_start() override;
virtual void machine_reset() override;
diff --git a/src/mame/includes/lwings.h b/src/mame/includes/lwings.h
index 6a7dedb889c..f5f24cb995f 100644
--- a/src/mame/includes/lwings.h
+++ b/src/mame/includes/lwings.h
@@ -12,6 +12,7 @@ public:
m_fgvideoram(*this, "fgvideoram"),
m_bg1videoram(*this, "bg1videoram"),
m_soundlatch2(*this, "soundlatch2"),
+ m_nmi_mask(0),
m_maincpu(*this, "maincpu"),
m_msm(*this, "5205"),
m_gfxdecode(*this, "gfxdecode"),
@@ -21,7 +22,7 @@ public:
required_device<buffered_spriteram8_device> m_spriteram;
required_shared_ptr<UINT8> m_fgvideoram;
required_shared_ptr<UINT8> m_bg1videoram;
- required_shared_ptr<UINT8> m_soundlatch2;
+ optional_shared_ptr<UINT8> m_soundlatch2;
/* video-related */
tilemap_t *m_fg_tilemap;
@@ -39,6 +40,7 @@ public:
UINT8 m_soundstate;
UINT8 m_adpcm;
UINT8 m_nmi_mask;
+ int m_sprbank;
DECLARE_WRITE8_MEMBER(avengers_adpcm_w);
DECLARE_READ8_MEMBER(avengers_adpcm_r);
@@ -54,6 +56,8 @@ public:
DECLARE_WRITE8_MEMBER(trojan_bg2_scrollx_w);
DECLARE_WRITE8_MEMBER(trojan_bg2_image_w);
DECLARE_WRITE8_MEMBER(msm5205_w);
+ DECLARE_WRITE8_MEMBER(fball_oki_bank_w);
+
TILEMAP_MAPPER_MEMBER(get_bg2_memory_offset);
TILE_GET_INFO_MEMBER(get_fg_tile_info);
TILE_GET_INFO_MEMBER(lwings_get_bg1_tile_info);
diff --git a/src/mame/includes/neogeo.h b/src/mame/includes/neogeo.h
index da50cb62765..2cd9c2efc86 100644
--- a/src/mame/includes/neogeo.h
+++ b/src/mame/includes/neogeo.h
@@ -365,6 +365,7 @@ ADDRESS_MAP_EXTERN(neogeo_main_map,16);
Some may be missing, there have been multiple CRCs reported for the same
revision in some cases (the Universe bios has an option for entering / displaying
a serial number; these should be noted as such if they're added).
+ Universe bios prior to version 1.3 was incompatible with AES.
The 'japan-hotel' BIOS is a dump of an MVS which could be found in some japanese
hotels. it is a custom MVS mobo which uses MVS carts but it hasn't jamma
@@ -386,6 +387,35 @@ ADDRESS_MAP_EXTERN(neogeo_main_map,16);
#define ROM_LOAD16_WORD_SWAP_BIOS(bios,name,offset,length,hash) \
ROMX_LOAD(name, offset, length, hash, ROM_GROUPWORD | ROM_REVERSE | ROM_BIOS(bios+1)) /* Note '+1' */
+#define NEOGEO_UNIBIOS(x) \
+ ROM_SYSTEM_BIOS( x+ 0, "unibios32", "Universe Bios (Hack, Ver. 3.2)" ) \
+ ROM_LOAD16_WORD_SWAP_BIOS( x+ 0, "uni-bios_3_2.rom", 0x00000, 0x020000, CRC(a4e8b9b3) SHA1(c92f18c3f1edda543d264ecd0ea915240e7c8258) ) /* Universe Bios v3.2 (hack) */ \
+ ROM_SYSTEM_BIOS( x+ 1, "unibios31", "Universe Bios (Hack, Ver. 3.1)" ) \
+ ROM_LOAD16_WORD_SWAP_BIOS( x+ 1, "uni-bios_3_1.rom", 0x00000, 0x020000, CRC(0c58093f) SHA1(29329a3448c2505e1ff45ffa75e61e9693165153) ) /* Universe Bios v3.1 (hack) */ \
+ ROM_SYSTEM_BIOS( x+ 2, "unibios30", "Universe Bios (Hack, Ver. 3.0)" ) \
+ ROM_LOAD16_WORD_SWAP_BIOS( x+ 2, "uni-bios_3_0.rom", 0x00000, 0x020000, CRC(a97c89a9) SHA1(97a5eff3b119062f10e31ad6f04fe4b90d366e7f) ) /* Universe Bios v3.0 (hack) */ \
+ ROM_SYSTEM_BIOS( x+ 3, "unibios23", "Universe Bios (Hack, Ver. 2.3)" ) \
+ ROM_LOAD16_WORD_SWAP_BIOS( x+ 3, "uni-bios_2_3.rom", 0x00000, 0x020000, CRC(27664eb5) SHA1(5b02900a3ccf3df168bdcfc98458136fd2b92ac0) ) /* Universe Bios v2.3 (hack) */ \
+ ROM_SYSTEM_BIOS( x+ 4, "unibios23o", "Universe Bios (Hack, Ver. 2.3, older?)" ) \
+ ROM_LOAD16_WORD_SWAP_BIOS( x+ 4, "uni-bios_2_3o.rom", 0x00000, 0x020000, CRC(601720ae) SHA1(1b8a72c720cdb5ee3f1d735bbcf447b09204b8d9) ) /* Universe Bios v2.3 (hack) alt version, withdrawn? */ \
+ ROM_SYSTEM_BIOS( x+ 5, "unibios22", "Universe Bios (Hack, Ver. 2.2)" ) \
+ ROM_LOAD16_WORD_SWAP_BIOS( x+ 5, "uni-bios_2_2.rom", 0x00000, 0x020000, CRC(2d50996a) SHA1(5241a4fb0c63b1a23fd1da8efa9c9a9bd3b4279c) ) /* Universe Bios v2.2 (hack) */ \
+ ROM_SYSTEM_BIOS( x+ 6, "unibios21", "Universe Bios (Hack, Ver. 2.1)" ) \
+ ROM_LOAD16_WORD_SWAP_BIOS( x+ 6, "uni-bios_2_1.rom", 0x00000, 0x020000, CRC(8dabf76b) SHA1(c23732c4491d966cf0373c65c83c7a4e88f0082c) ) /* Universe Bios v2.1 (hack) */ \
+ ROM_SYSTEM_BIOS( x+ 7, "unibios20", "Universe Bios (Hack, Ver. 2.0)" ) \
+ ROM_LOAD16_WORD_SWAP_BIOS( x+ 7, "uni-bios_2_0.rom", 0x00000, 0x020000, CRC(0c12c2ad) SHA1(37bcd4d30f3892078b46841d895a6eff16dc921e) ) /* Universe Bios v2.0 (hack) */ \
+ ROM_SYSTEM_BIOS( x+ 8, "unibios13", "Universe Bios (Hack, Ver. 1.3)" ) \
+ ROM_LOAD16_WORD_SWAP_BIOS( x+ 8, "uni-bios_1_3.rom", 0x00000, 0x020000, CRC(b24b44a0) SHA1(eca8851d30557b97c309a0d9f4a9d20e5b14af4e) ) /* Universe Bios v1.3 (hack) */
+#define NEOGEO_UNIBIOS_1_2_AND_OLDER(x) \
+ ROM_SYSTEM_BIOS( x+ 9, "unibios12", "Universe Bios (Hack, Ver. 1.2)" ) \
+ ROM_LOAD16_WORD_SWAP_BIOS( x+ 9, "uni-bios_1_2.rom", 0x00000, 0x020000, CRC(4fa698e9) SHA1(682e13ec1c42beaa2d04473967840c88fd52c75a) ) /* Universe Bios v1.2 (hack) */ \
+ ROM_SYSTEM_BIOS( x+10, "unibios12o", "Universe Bios (Hack, Ver. 1.2, older)" ) \
+ ROM_LOAD16_WORD_SWAP_BIOS( x+10, "uni-bios_1_2o.rom", 0x00000, 0x020000, CRC(e19d3ce9) SHA1(af88ef837f44a3af2d7144bb46a37c8512b67770) ) /* Universe Bios v1.2 (hack) alt version */ \
+ ROM_SYSTEM_BIOS( x+11, "unibios11", "Universe Bios (Hack, Ver. 1.1)" ) \
+ ROM_LOAD16_WORD_SWAP_BIOS( x+11, "uni-bios_1_1.rom", 0x00000, 0x020000, CRC(5dda0d84) SHA1(4153d533c02926a2577e49c32657214781ff29b7) ) /* Universe Bios v1.1 (hack) */ \
+ ROM_SYSTEM_BIOS( x+12, "unibios10", "Universe Bios (Hack, Ver. 1.0)" ) \
+ ROM_LOAD16_WORD_SWAP_BIOS( x+12, "uni-bios_1_0.rom", 0x00000, 0x020000, CRC(0ce453a0) SHA1(3b4c0cd26c176fc6b26c3a2f95143dd478f6abf9) ) /* Universe Bios v1.0 (hack) */
+
#define NEOGEO_BIOS \
ROM_REGION16_BE( 0x80000, "mainbios", 0 ) \
ROM_SYSTEM_BIOS( 0, "euro", "Europe MVS (Ver. 2)" ) \
@@ -398,7 +428,7 @@ ADDRESS_MAP_EXTERN(neogeo_main_map,16);
ROM_SYSTEM_BIOS( 3, "us-e", "US MVS (Ver. 1)" ) \
ROM_LOAD16_WORD_SWAP_BIOS( 3, "sp-e.sp1", 0x00000, 0x020000, CRC(2723a5b5) SHA1(5dbff7531cf04886cde3ef022fb5ca687573dcb8) ) /* US, 6 Slot (V5?) */ \
ROM_SYSTEM_BIOS( 4, "us-v2", "US MVS (4 slot, Ver 2)" ) \
- ROM_LOAD16_WORD_SWAP_BIOS(4, "v2.bin", 0x00000, 0x020000, CRC(62f021f4) SHA1(62d372269e1b3161c64ae21123655a0a22ffd1bb) ) /* US, 4 slot */ \
+ ROM_LOAD16_WORD_SWAP_BIOS( 4, "v2.bin", 0x00000, 0x020000, CRC(62f021f4) SHA1(62d372269e1b3161c64ae21123655a0a22ffd1bb) ) /* US, 4 slot */ \
\
ROM_SYSTEM_BIOS( 5, "asia", "Asia MVS (Ver. 3)" ) \
ROM_LOAD16_WORD_SWAP_BIOS( 5, "asia-s3.rom", 0x00000, 0x020000, CRC(91b64be3) SHA1(720a3e20d26818632aedf2c2fd16c54f213543e1) ) /* Asia */ \
@@ -412,36 +442,12 @@ ADDRESS_MAP_EXTERN(neogeo_main_map,16);
ROM_SYSTEM_BIOS( 9, "mv1c", "NEO-MVH MV1C" ) \
ROM_LOAD16_WORD_SWAP_BIOS( 9, "sp-45.sp1", 0x00000, 0x080000, CRC(03cc9f6a) SHA1(cdf1f49e3ff2bac528c21ed28449cf35b7957dc1) ) /* Latest Asia bios */ \
ROM_SYSTEM_BIOS( 10, "japan-j3", "Japan MVS (J3)" ) \
- ROM_LOAD16_WORD_SWAP_BIOS( 10, "japan-j3.bin", 0x00000, 0x020000, CRC(dff6d41f) SHA1(e92910e20092577a4523a6b39d578a71d4de7085) ) /* Latest Japan bios; correct chip label unknown */ \
- ROM_SYSTEM_BIOS(11, "japan-hotel", "Custom Japanese Hotel" ) \
- ROM_LOAD16_WORD_SWAP_BIOS(11, "sp-1v1_3db8c.bin", 0x00000, 0x020000, CRC(162f0ebe) SHA1(fe1c6dd3dfcf97d960065b1bb46c1e11cb7bf271) ) /* 'rare MVS found in japanese hotels' shows v1.3 in test mode */ \
+ ROM_LOAD16_WORD_SWAP_BIOS( 10, "japan-j3.bin", 0x00000, 0x020000, CRC(dff6d41f) SHA1(e92910e20092577a4523a6b39d578a71d4de7085) ) /* Latest Japan bios; correct chip label unknown */ \
+ ROM_SYSTEM_BIOS( 11, "japan-hotel", "Custom Japanese Hotel" ) \
+ ROM_LOAD16_WORD_SWAP_BIOS( 11, "sp-1v1_3db8c.bin", 0x00000, 0x020000, CRC(162f0ebe) SHA1(fe1c6dd3dfcf97d960065b1bb46c1e11cb7bf271) ) /* 'rare MVS found in japanese hotels' shows v1.3 in test mode */ \
\
- ROM_SYSTEM_BIOS(12, "unibios31", "Universe Bios (Hack, Ver. 3.1)" ) \
- ROM_LOAD16_WORD_SWAP_BIOS(12, "uni-bios_3_1.rom", 0x00000, 0x020000, CRC(0c58093f) SHA1(29329a3448c2505e1ff45ffa75e61e9693165153) ) /* Universe Bios v3.1 (hack) */ \
- ROM_SYSTEM_BIOS(13, "unibios30", "Universe Bios (Hack, Ver. 3.0)" ) \
- ROM_LOAD16_WORD_SWAP_BIOS(13, "uni-bios_3_0.rom", 0x00000, 0x020000, CRC(a97c89a9) SHA1(97a5eff3b119062f10e31ad6f04fe4b90d366e7f) ) /* Universe Bios v3.0 (hack) */ \
- ROM_SYSTEM_BIOS(14, "unibios23", "Universe Bios (Hack, Ver. 2.3)" ) \
- ROM_LOAD16_WORD_SWAP_BIOS(14, "uni-bios_2_3.rom", 0x00000, 0x020000, CRC(27664eb5) SHA1(5b02900a3ccf3df168bdcfc98458136fd2b92ac0) ) /* Universe Bios v2.3 (hack) */ \
- ROM_SYSTEM_BIOS(15, "unibios23o", "Universe Bios (Hack, Ver. 2.3, older?)" ) \
- ROM_LOAD16_WORD_SWAP_BIOS(15, "uni-bios_2_3o.rom", 0x00000, 0x020000, CRC(601720ae) SHA1(1b8a72c720cdb5ee3f1d735bbcf447b09204b8d9) ) /* Universe Bios v2.3 (hack) alt version, withdrawn? */ \
- ROM_SYSTEM_BIOS(16, "unibios22", "Universe Bios (Hack, Ver. 2.2)" ) \
- ROM_LOAD16_WORD_SWAP_BIOS(16, "uni-bios_2_2.rom", 0x00000, 0x020000, CRC(2d50996a) SHA1(5241a4fb0c63b1a23fd1da8efa9c9a9bd3b4279c) ) /* Universe Bios v2.2 (hack) */ \
- ROM_SYSTEM_BIOS(17, "unibios21", "Universe Bios (Hack, Ver. 2.1)" ) \
- ROM_LOAD16_WORD_SWAP_BIOS(17, "uni-bios_2_1.rom", 0x00000, 0x020000, CRC(8dabf76b) SHA1(c23732c4491d966cf0373c65c83c7a4e88f0082c) ) /* Universe Bios v2.1 (hack) */ \
- ROM_SYSTEM_BIOS(18, "unibios20", "Universe Bios (Hack, Ver. 2.0)" ) \
- ROM_LOAD16_WORD_SWAP_BIOS(18, "uni-bios_2_0.rom", 0x00000, 0x020000, CRC(0c12c2ad) SHA1(37bcd4d30f3892078b46841d895a6eff16dc921e) ) /* Universe Bios v2.0 (hack) */ \
- ROM_SYSTEM_BIOS(19, "unibios13", "Universe Bios (Hack, Ver. 1.3)" ) \
- ROM_LOAD16_WORD_SWAP_BIOS(19, "uni-bios_1_3.rom", 0x00000, 0x020000, CRC(b24b44a0) SHA1(eca8851d30557b97c309a0d9f4a9d20e5b14af4e) ) /* Universe Bios v1.3 (hack) */ \
- ROM_SYSTEM_BIOS(20, "unibios12", "Universe Bios (Hack, Ver. 1.2)" ) \
- ROM_LOAD16_WORD_SWAP_BIOS(20, "uni-bios_1_2.rom", 0x00000, 0x020000, CRC(4fa698e9) SHA1(682e13ec1c42beaa2d04473967840c88fd52c75a) ) /* Universe Bios v1.2 (hack) */ \
- ROM_SYSTEM_BIOS(21, "unibios12o", "Universe Bios (Hack, Ver. 1.2, older)" ) \
- ROM_LOAD16_WORD_SWAP_BIOS(21, "uni-bios_1_2o.rom", 0x00000, 0x020000, CRC(e19d3ce9) SHA1(af88ef837f44a3af2d7144bb46a37c8512b67770) ) /* Universe Bios v1.2 (hack) alt version */ \
- ROM_SYSTEM_BIOS(22, "unibios11", "Universe Bios (Hack, Ver. 1.1)" ) \
- ROM_LOAD16_WORD_SWAP_BIOS(22, "uni-bios_1_1.rom", 0x00000, 0x020000, CRC(5dda0d84) SHA1(4153d533c02926a2577e49c32657214781ff29b7) ) /* Universe Bios v1.1 (hack) */ \
- ROM_SYSTEM_BIOS(23, "unibios10", "Universe Bios (Hack, Ver. 1.0)" ) \
- ROM_LOAD16_WORD_SWAP_BIOS(23, "uni-bios_1_0.rom", 0x00000, 0x020000, CRC(0ce453a0) SHA1(3b4c0cd26c176fc6b26c3a2f95143dd478f6abf9) ) /* Universe Bios v1.0 (hack) */
-
-
+ NEOGEO_UNIBIOS(12) \
+ NEOGEO_UNIBIOS_1_2_AND_OLDER(12)
#define NEO_BIOS_AUDIO_64K(name, hash) \
diff --git a/src/mame/includes/xbox.h b/src/mame/includes/xbox.h
index 045d7504700..4dac71ab472 100644
--- a/src/mame/includes/xbox.h
+++ b/src/mame/includes/xbox.h
@@ -227,44 +227,60 @@ enum USBEndpointType
InterruptEndpoint
};
+struct usb_device_string
+{
+ UINT8 *position;
+ int size;
+};
+
struct usb_device_interface_alternate
{
+ UINT8 *position;
+ int size;
USBStandardInterfaceDescriptor interface_descriptor;
std::forward_list<USBStandardEndpointDescriptor> endpoint_descriptors;
};
struct usb_device_interface
{
- std::forward_list<usb_device_interface_alternate> alternate_settings;
+ UINT8 *position;
+ int size;
+ std::forward_list<usb_device_interface_alternate *> alternate_settings;
int selected_alternate;
};
struct usb_device_configuration
{
USBStandardConfigurationDescriptor configuration_descriptor;
- std::forward_list<usb_device_interface> interfaces;
+ UINT8 *position;
+ int size;
+ std::forward_list<usb_device_interface *> interfaces;
};
class ohci_function_device {
public:
ohci_function_device(running_machine &machine);
void execute_reset();
- int execute_transfer(int address, int endpoint, int pid, UINT8 *buffer, int size);
+ int execute_transfer(int address, int endpoint, int pid, UINT8 *buffer, int size) ;
protected:
- int handle_nonstandard_request(int endpoint, USBSetupPacket *setup);
- virtual int handle_get_status_request(int endpoint, USBSetupPacket *setup) = 0;
- virtual int handle_clear_feature_request(int endpoint, USBSetupPacket *setup) = 0;
- virtual int handle_set_feature_request(int endpoint, USBSetupPacket *setup) = 0;
- virtual int handle_set_descriptor_request(int endpoint, USBSetupPacket *setup) = 0;
- virtual int handle_synch_frame_request(int endpoint, USBSetupPacket *setup) = 0;
-private:
- void add_device_descriptor(USBStandardDeviceDescriptor &descriptor);
- void add_configuration_descriptor(USBStandardConfigurationDescriptor &descriptor);
- void add_interface_descriptor(USBStandardInterfaceDescriptor &descriptor);
- void add_endpoint_descriptor(USBStandardEndpointDescriptor &descriptor);
+ virtual int handle_nonstandard_request(int endpoint, USBSetupPacket *setup) { return -1; };
+ virtual int handle_get_status_request(int endpoint, USBSetupPacket *setup) { return 0; };
+ virtual int handle_clear_feature_request(int endpoint, USBSetupPacket *setup) { return 0; };
+ virtual int handle_set_feature_request(int endpoint, USBSetupPacket *setup) { return 0; };
+ virtual int handle_set_descriptor_request(int endpoint, USBSetupPacket *setup) { return 0; };
+ virtual int handle_synch_frame_request(int endpoint, USBSetupPacket *setup) { return 0; };
+
+ void add_device_descriptor(const USBStandardDeviceDescriptor &descriptor);
+ void add_configuration_descriptor(const USBStandardConfigurationDescriptor &descriptor);
+ void add_interface_descriptor(const USBStandardInterfaceDescriptor &descriptor);
+ void add_endpoint_descriptor(const USBStandardEndpointDescriptor &descriptor);
+ void add_string_descriptor(const UINT8 *descriptor);
void select_configuration(int index);
void select_alternate(int interfacei, int index);
int find_alternate(int interfacei);
+ UINT8 *position_device_descriptor(int &size);
+ UINT8 *position_configuration_descriptor(int index, int &size);
+ UINT8 *position_string_descriptor(int index, int &size);
struct {
int type;
int controldirection;
@@ -282,12 +298,27 @@ private:
UINT8 *descriptors;
int descriptors_pos;
USBStandardDeviceDescriptor device_descriptor;
- std::forward_list<usb_device_configuration> configurations;
+ std::forward_list<usb_device_configuration *> configurations;
+ std::forward_list<usb_device_string *> device_strings;
usb_device_configuration *latest_configuration;
usb_device_interface_alternate *latest_alternate;
usb_device_configuration *selected_configuration;
};
+class ohci_game_controller_device : public ohci_function_device
+{
+public:
+ ohci_game_controller_device(running_machine &machine);// :
+ //ohci_function_device(machine) {}
+ int handle_nonstandard_request(int endpoint, USBSetupPacket *setup) override;
+private:
+ static const USBStandardDeviceDescriptor devdesc;
+ static const USBStandardConfigurationDescriptor condesc;
+ static const USBStandardInterfaceDescriptor intdesc;
+ static const USBStandardEndpointDescriptor enddesc82;
+ static const USBStandardEndpointDescriptor enddesc02;
+};
+
class xbox_base_state : public driver_device
{
public:
diff --git a/src/mame/layout/cnsector.lay b/src/mame/layout/cnsector.lay
index 730e02c3d06..8bca9c3ab7a 100644
--- a/src/mame/layout/cnsector.lay
+++ b/src/mame/layout/cnsector.lay
@@ -5,7 +5,9 @@
<element name="static_black"><rect><color red="0.0" green="0.0" blue="0.0" /></rect></element>
<element name="static_white"><rect><color red="0.95" green="0.95" blue="0.95" /></rect></element>
- <element name="static_gray"><rect><color red="0.60" green="0.75" blue="0.63" /></rect></element>
+ <element name="static_white2"><rect><color red="0.88" green="0.85" blue="0.85" /></rect></element>
+ <element name="static_gray"><rect><color red="0.6" green="0.7" blue="0.65" /></rect></element>
+ <element name="static_gray2"><rect><color red="0.75" green="0.73" blue="0.73" /></rect></element>
<element name="static_red"><rect><color red="0.35" green="0.02" blue="0.04" /></rect></element>
<element name="digit" defstate="0">
@@ -17,20 +19,112 @@
<disk state="0"><color red="0.2" green="0.0" blue="0.0" /></disk>
</element>
+ <element name="button" defstate="0">
+ <rect state="1"><color red="0.42" green="0.49" blue="0.455" /></rect>
+ <rect state="0"><color red="0.6" green="0.7" blue="0.65" /></rect>
+ </element>
+ <element name="buttond" defstate="0">
+ <disk state="1"><color red="0.42" green="0.49" blue="0.455" /></disk>
+ <disk state="0"><color red="0.6" green="0.7" blue="0.65" /></disk>
+ </element>
+
+ <element name="text_rnext">
+ <rect><color red="0.35" green="0.02" blue="0.04" /></rect>
+ <text string="NEXT"><color red="0.75" green="0.73" blue="0.73" /></text>
+ </element>
+ <element name="text_rship">
+ <rect><color red="0.35" green="0.02" blue="0.04" /></rect>
+ <text string="SHIP"><color red="0.75" green="0.73" blue="0.73" /></text>
+ </element>
+ <element name="text_rmove">
+ <rect><color red="0.35" green="0.02" blue="0.04" /></rect>
+ <text string="MOVE"><color red="0.75" green="0.73" blue="0.73" /></text>
+ </element>
+ <element name="text_rrecall">
+ <rect><color red="0.35" green="0.02" blue="0.04" /></rect>
+ <text string="RECALL"><color red="0.75" green="0.73" blue="0.73" /></text>
+ </element>
+ <element name="text_rleft">
+ <rect><color red="0.35" green="0.02" blue="0.04" /></rect>
+ <text string="LEFT"><color red="0.75" green="0.73" blue="0.73" /></text>
+ </element>
+ <element name="text_rright">
+ <rect><color red="0.35" green="0.02" blue="0.04" /></rect>
+ <text string="RIGHT"><color red="0.75" green="0.73" blue="0.73" /></text>
+ </element>
+ <element name="text_rrange">
+ <rect><color red="0.35" green="0.02" blue="0.04" /></rect>
+ <text string="RANGE"><color red="0.75" green="0.73" blue="0.73" /></text>
+ </element>
+ <element name="text_raim">
+ <rect><color red="0.35" green="0.02" blue="0.04" /></rect>
+ <text string="AIM"><color red="0.75" green="0.73" blue="0.73" /></text>
+ </element>
+ <element name="text_rfire">
+ <rect><color red="0.35" green="0.02" blue="0.04" /></rect>
+ <text string="FIRE"><color red="0.75" green="0.73" blue="0.73" /></text>
+ </element>
+ <element name="text_rsteering">
+ <rect><color red="0.35" green="0.02" blue="0.04" /></rect>
+ <text string="STEERING"><color red="0.75" green="0.73" blue="0.73" /></text>
+ </element>
+ <element name="text_rspeed">
+ <rect><color red="0.35" green="0.02" blue="0.04" /></rect>
+ <text string="SPEED"><color red="0.75" green="0.73" blue="0.73" /></text>
+ </element>
+ <element name="text_rnav">
+ <rect><color red="0.35" green="0.02" blue="0.04" /></rect>
+ <text string="NAVIGATIONAL PROGRAMMING"><color red="0.75" green="0.73" blue="0.73" /></text>
+ </element>
+ <element name="text_rslower">
+ <rect><color red="0.35" green="0.02" blue="0.04" /></rect>
+ <text string="SLOWER"><color red="0.75" green="0.73" blue="0.73" /></text>
+ </element>
+ <element name="text_rfaster">
+ <rect><color red="0.35" green="0.02" blue="0.04" /></rect>
+ <text string="FASTER"><color red="0.75" green="0.73" blue="0.73" /></text>
+ </element>
+ <element name="text_rson">
+ <rect><color red="0.35" green="0.02" blue="0.04" /></rect>
+ <text string="SONAR CONTROL"><color red="0.75" green="0.73" blue="0.73" /></text>
+ </element>
+ <element name="text_rteach">
+ <rect><color red="0.35" green="0.02" blue="0.04" /></rect>
+ <text string="TEACH"><color red="0.75" green="0.73" blue="0.73" /></text>
+ </element>
+ <element name="text_rmode">
+ <rect><color red="0.35" green="0.02" blue="0.04" /></rect>
+ <text string="MODE"><color red="0.75" green="0.73" blue="0.73" /></text>
+ </element>
+ <element name="text_rsub">
+ <rect><color red="0.35" green="0.02" blue="0.04" /></rect>
+ <text string="SUB"><color red="0.75" green="0.73" blue="0.73" /></text>
+ </element>
+ <element name="text_rfinder">
+ <rect><color red="0.35" green="0.02" blue="0.04" /></rect>
+ <text string="FINDER"><color red="0.75" green="0.73" blue="0.73" /></text>
+ </element>
+ <element name="text_revasive">
+ <rect><color red="0.35" green="0.02" blue="0.04" /></rect>
+ <text string="EVASIVE"><color red="0.75" green="0.73" blue="0.73" /></text>
+ </element>
+ <element name="text_rcom">
+ <rect><color red="0.35" green="0.02" blue="0.04" /></rect>
+ <text string="COMBAT INFORMATION CENTER"><color red="0.75" green="0.73" blue="0.73" /></text>
+ </element>
+
<element name="text_ship">
<text string="SHIP"><color red="0.95" green="0.95" blue="0.95" /></text>
</element>
<element name="text_speed">
<text string="SPEED"><color red="0.95" green="0.95" blue="0.95" /></text>
</element>
-
<element name="text_north">
<text string="NORTH" align="2"><color red="0.95" green="0.95" blue="0.95" /></text>
</element>
<element name="text_east">
<text string="EAST" align="1"><color red="0.95" green="0.95" blue="0.95" /></text>
</element>
-
<element name="text_depth">
<text string="DEPTH"><color red="0.95" green="0.95" blue="0.95" /></text>
</element>
@@ -54,79 +148,146 @@
<rect><color red="0.35" green="0.02" blue="0.04" /></rect>
<text string="W"><color red="0.88" green="0.85" blue="0.85" /></text>
</element>
+ <element name="text_nw">
+ <rect><color red="0.35" green="0.02" blue="0.04" /></rect>
+ <text string="NW"><color red="0.88" green="0.85" blue="0.85" /></text>
+ </element>
+ <element name="text_ne">
+ <rect><color red="0.35" green="0.02" blue="0.04" /></rect>
+ <text string="NE"><color red="0.88" green="0.85" blue="0.85" /></text>
+ </element>
+ <element name="text_sw">
+ <rect><color red="0.35" green="0.02" blue="0.04" /></rect>
+ <text string="SW"><color red="0.88" green="0.85" blue="0.85" /></text>
+ </element>
+ <element name="text_se">
+ <rect><color red="0.35" green="0.02" blue="0.04" /></rect>
+ <text string="SE"><color red="0.88" green="0.85" blue="0.85" /></text>
+ </element>
<!-- build screen -->
<view name="Internal Layout">
- <bounds left="0" right="92" top="0" bottom="146" />
- <bezel element="static_black">
- <bounds left="0" right="92" top="0" bottom="146" />
- </bezel>
+ <bounds left="-1" right="228" top="0" bottom="141" />
<!-- digits -->
<bezel element="static_white"><bounds x="0" y="4" width="100" height="1" /></bezel>
<bezel element="static_white"><bounds x="0" y="12" width="100" height="1" /></bezel>
-
<bezel element="static_white"><bounds x="20" y="4.5" width="1" height="40" /></bezel>
<bezel element="static_white"><bounds x="41" y="4.5" width="1" height="40" /></bezel>
-
<bezel element="static_white"><bounds x="67" y="4.5" width="1" height="8" /></bezel>
-
<bezel element="static_white"><bounds x="20.5" y="36" width="80" height="1" /></bezel>
<bezel element="static_white"><bounds x="0" y="44" width="100" height="1" /></bezel>
+ <bezel element="static_black"><bounds x="92" y="0" width="10" height="49" /></bezel>
<bezel element="text_ship"><bounds x="0" y="5" width="20" height="7" /></bezel>
<bezel element="text_speed"><bounds x="21" y="5" width="20" height="7" /></bezel>
-
<bezel element="text_north"><bounds x="47" y="5" width="19" height="7" /></bezel>
<bezel element="text_east"><bounds x="69" y="5" width="19" height="7" /></bezel>
-
<bezel element="text_depth"><bounds x="21" y="37" width="20" height="7" /></bezel>
<bezel element="text_range"><bounds x="57" y="37" width="20" height="7" /></bezel>
- <bezel name="digit5" element="digit">
- <bounds x="5" y="17" width="10" height="15" />
- </bezel>
-
- <bezel name="digit4" element="digit">
- <bounds x="26" y="17" width="10" height="15" />
- </bezel>
-
- <bezel name="digit3" element="digit">
- <bounds x="47" y="17" width="10" height="15" />
- </bezel>
- <bezel name="digit2" element="digit">
- <bounds x="57" y="17" width="10" height="15" />
- </bezel>
- <bezel name="digit1" element="digit">
- <bounds x="67" y="17" width="10" height="15" />
- </bezel>
- <bezel name="digit0" element="digit">
- <bounds x="77" y="17" width="10" height="15" />
- </bezel>
+ <bezel name="digit5" element="digit"><bounds x="5" y="17" width="10" height="15" /></bezel>
+ <bezel name="digit4" element="digit"><bounds x="26" y="17" width="10" height="15" /></bezel>
+ <bezel name="digit3" element="digit"><bounds x="47" y="17" width="10" height="15" /></bezel>
+ <bezel name="digit2" element="digit"><bounds x="57" y="17" width="10" height="15" /></bezel>
+ <bezel name="digit1" element="digit"><bounds x="67" y="17" width="10" height="15" /></bezel>
+ <bezel name="digit0" element="digit"><bounds x="77" y="17" width="10" height="15" /></bezel>
<!-- compass -->
- <bezel element="static_gray"><bounds x="0" y="50" width="100" height="100" /></bezel>
- <bezel element="static_red"><bounds x="0" y="55" width="100" height="86" /></bezel>
+ <bezel element="static_gray"><bounds x="-2" y="50" width="102" height="6" /></bezel>
+ <bezel element="static_red"><bounds x="-2" y="55" width="102" height="86" /></bezel>
+ <bezel element="static_white2"><bounds x="13.5" y="65.5" width="65" height="65" /></bezel>
+ <bezel element="static_red"><bounds x="14.5" y="66.5" width="63" height="63" /></bezel>
<bezel name="6.a" element="led"><bounds x="42" y="62" width="8" height="8" /></bezel>
<bezel name="7.a" element="led"><bounds x="42" y="126" width="8" height="8" /></bezel>
<bezel name="8.a" element="led"><bounds x="74" y="94" width="8" height="8" /></bezel>
<bezel name="9.a" element="led"><bounds x="10" y="94" width="8" height="8" /></bezel>
+ <bezel element="text_nw"><bounds x="6" y="61" width="16" height="10" /></bezel>
+ <bezel element="text_ne"><bounds x="70" y="61" width="16" height="10" /></bezel>
+ <bezel element="text_sw"><bounds x="6" y="125" width="16" height="10" /></bezel>
+ <bezel element="text_se"><bounds x="70" y="125" width="16" height="10" /></bezel>
+
<bezel element="text_n"><bounds x="41" y="72" width="10" height="10" /></bezel>
<bezel element="text_s"><bounds x="41" y="114" width="10" height="10" /></bezel>
<bezel element="text_e"><bounds x="63" y="93" width="10" height="10" /></bezel>
<bezel element="text_w"><bounds x="21" y="93" width="10" height="10" /></bezel>
- <!-- crop borders -->
+ <!-- button panel -->
+
+ <bezel element="static_gray"><bounds x="93" y="-1" width="6" height="143" /></bezel>
+ <bezel element="static_red"><bounds x="98" y="-1" width="132" height="143" /></bezel>
+
+ <bezel element="text_rcom"><bounds x="99" y="11.5" width="128" height="11" /></bezel>
+
+ <bezel element="static_gray2"><bounds x="102" y="28" width="50" height="18" /></bezel>
+ <bezel element="static_red"><bounds x="103" y="29" width="48" height="16" /></bezel>
+ <bezel element="static_gray2"><bounds x="174" y="28" width="50" height="18" /></bezel>
+ <bezel element="static_red"><bounds x="175" y="29" width="48" height="16" /></bezel>
- <bezel element="static_black"><bounds x="92" y="0" width="10" height="160" /></bezel>
- <bezel element="static_black"><bounds x="0" y="146" width="100" height="10" /></bezel>
+ <bezel element="static_gray2"><bounds x="102" y="49" width="122" height="44" /></bezel>
+ <bezel element="static_red"><bounds x="103" y="51" width="120" height="41" /></bezel>
+ <bezel element="static_gray2"><bounds x="151" y="49" width="24" height="27" /></bezel>
+ <bezel element="static_red"><bounds x="152" y="48" width="22" height="27" /></bezel>
+ <bezel element="static_red"><bounds x="101" y="47" width="124" height="3" /></bezel>
+
+ <bezel element="static_gray2"><bounds x="102" y="97" width="74" height="33" /></bezel>
+ <bezel element="static_red"><bounds x="103" y="98" width="72" height="31" /></bezel>
+ <bezel element="static_gray2"><bounds x="198" y="97" width="26" height="33" /></bezel>
+ <bezel element="static_red"><bounds x="199" y="98" width="24" height="31" /></bezel>
+
+ <bezel element="button" inputtag="IN.0" inputmask="0x01"><bounds x="107" y="33" width="16" height="8" /></bezel>
+ <bezel element="button" inputtag="IN.2" inputmask="0x08"><bounds x="155" y="33" width="16" height="8" /></bezel>
+ <bezel element="button" inputtag="IN.4" inputmask="0x08"><bounds x="203" y="33" width="16" height="8" /></bezel>
+
+ <bezel element="button" inputtag="IN.0" inputmask="0x02"><bounds x="107" y="55" width="16" height="8" /></bezel>
+ <bezel element="button" inputtag="IN.1" inputmask="0x02"><bounds x="131" y="55" width="16" height="8" /></bezel>
+ <bezel element="buttond" inputtag="IN.2" inputmask="0x02"><bounds x="161" y="57" width="4" height="4" /></bezel>
+ <bezel element="button" inputtag="IN.3" inputmask="0x02"><bounds x="179" y="55" width="16" height="8" /></bezel>
+ <bezel element="button" inputtag="IN.4" inputmask="0x02"><bounds x="203" y="55" width="16" height="8" /></bezel>
+
+ <bezel element="button" inputtag="IN.0" inputmask="0x08"><bounds x="107" y="102" width="16" height="8" /></bezel>
+ <bezel element="button" inputtag="IN.1" inputmask="0x01"><bounds x="131" y="102" width="16" height="8" /></bezel>
+ <bezel element="button" inputtag="IN.2" inputmask="0x01"><bounds x="155" y="102" width="16" height="8" /></bezel>
+ <bezel element="buttond" inputtag="IN.3" inputmask="0x01"><bounds x="185" y="104" width="4" height="4" /></bezel>
+ <bezel element="button" inputtag="IN.4" inputmask="0x01"><bounds x="207" y="102" width="8" height="8" /></bezel>
+
+ <bezel element="text_rnext"><bounds x="127" y="32" width="18" height="5" /></bezel>
+ <bezel element="text_rship"><bounds x="127" y="37" width="18" height="5" /></bezel>
+ <bezel element="text_rrecall"><bounds x="154" y="43" width="18" height="5" /></bezel>
+ <bezel element="text_rmove"><bounds x="181" y="32" width="18" height="5" /></bezel>
+ <bezel element="text_rship"><bounds x="181" y="37" width="18" height="5" /></bezel>
+
+ <bezel element="text_rleft"><bounds x="106" y="65" width="18" height="5" /></bezel>
+ <bezel element="text_rright"><bounds x="130" y="65" width="18" height="5" /></bezel>
+ <bezel element="text_revasive"><bounds x="154" y="62.5" width="18" height="5" /></bezel>
+ <bezel element="text_rsub"><bounds x="154" y="67.5" width="18" height="5" /></bezel>
+ <bezel element="text_rslower"><bounds x="178" y="65" width="18" height="5" /></bezel>
+ <bezel element="text_rfaster"><bounds x="202" y="65" width="18" height="5" /></bezel>
+ <bezel element="text_rsteering"><bounds x="107" y="70" width="40" height="8" /></bezel>
+ <bezel element="text_rspeed"><bounds x="179" y="70" width="40" height="8" /></bezel>
+ <bezel element="text_rnav"><bounds x="107" y="80" width="112" height="8" /></bezel>
+
+ <bezel element="text_rrange"><bounds x="106" y="112" width="18" height="5" /></bezel>
+ <bezel element="text_raim"><bounds x="130" y="112" width="18" height="5" /></bezel>
+ <bezel element="text_rfire"><bounds x="154" y="112" width="18" height="5" /></bezel>
+ <bezel element="text_rsub"><bounds x="178" y="109.5" width="18" height="5" /></bezel>
+ <bezel element="text_rfinder"><bounds x="178" y="114.5" width="18" height="5" /></bezel>
+ <bezel element="text_rteach"><bounds x="202" y="112" width="18" height="5" /></bezel>
+ <bezel element="text_rmode"><bounds x="202" y="117" width="18" height="5" /></bezel>
+ <bezel element="text_rson"><bounds x="107" y="117" width="64" height="8" /></bezel>
+
+ <!-- crop borders -->
+ <bezel element="static_black"><bounds x="-3" y="-3" width="232" height="2.9" /></bezel>
+ <bezel element="static_black"><bounds x="-3" y="-3" width="1.9" height="150" /></bezel>
+ <bezel element="static_black"><bounds x="-3" y="141.1" width="232" height="2" /></bezel>
+ <bezel element="static_black"><bounds x="228.1" y="-3" width="3" height="150" /></bezel>
</view>
</mamelayout>
diff --git a/src/mame/layout/hh_sm510_test.lay b/src/mame/layout/hh_sm510_test.lay
index f960f795acc..6c767675bfd 100644
--- a/src/mame/layout/hh_sm510_test.lay
+++ b/src/mame/layout/hh_sm510_test.lay
@@ -22,280 +22,287 @@
<bounds left="0" right="64" top="0" bottom="64" />
</bezel>
- <!-- max 16*16 matrix -->
+ <!-- max 4*16*4 matrix -->
- <bezel name="0.0" element="led"><bounds x="0" y="0" width="1" height="1" /></bezel>
- <bezel name="0.1" element="led"><bounds x="0" y="2" width="1" height="1" /></bezel>
- <bezel name="0.2" element="led"><bounds x="0" y="4" width="1" height="1" /></bezel>
- <bezel name="0.3" element="led"><bounds x="0" y="6" width="1" height="1" /></bezel>
- <bezel name="0.4" element="led"><bounds x="0" y="8" width="1" height="1" /></bezel>
- <bezel name="0.5" element="led"><bounds x="0" y="10" width="1" height="1" /></bezel>
- <bezel name="0.6" element="led"><bounds x="0" y="12" width="1" height="1" /></bezel>
- <bezel name="0.7" element="led"><bounds x="0" y="14" width="1" height="1" /></bezel>
- <bezel name="0.8" element="led"><bounds x="0" y="16" width="1" height="1" /></bezel>
- <bezel name="0.9" element="led"><bounds x="0" y="18" width="1" height="1" /></bezel>
- <bezel name="0.10" element="led"><bounds x="0" y="20" width="1" height="1" /></bezel>
- <bezel name="0.11" element="led"><bounds x="0" y="22" width="1" height="1" /></bezel>
- <bezel name="0.12" element="led"><bounds x="0" y="24" width="1" height="1" /></bezel>
- <bezel name="0.13" element="led"><bounds x="0" y="26" width="1" height="1" /></bezel>
- <bezel name="0.14" element="led"><bounds x="0" y="28" width="1" height="1" /></bezel>
- <bezel name="0.15" element="led"><bounds x="0" y="30" width="1" height="1" /></bezel>
+ <!-- a -->
- <bezel name="1.0" element="led"><bounds x="2" y="0" width="1" height="1" /></bezel>
- <bezel name="1.1" element="led"><bounds x="2" y="2" width="1" height="1" /></bezel>
- <bezel name="1.2" element="led"><bounds x="2" y="4" width="1" height="1" /></bezel>
- <bezel name="1.3" element="led"><bounds x="2" y="6" width="1" height="1" /></bezel>
- <bezel name="1.4" element="led"><bounds x="2" y="8" width="1" height="1" /></bezel>
- <bezel name="1.5" element="led"><bounds x="2" y="10" width="1" height="1" /></bezel>
- <bezel name="1.6" element="led"><bounds x="2" y="12" width="1" height="1" /></bezel>
- <bezel name="1.7" element="led"><bounds x="2" y="14" width="1" height="1" /></bezel>
- <bezel name="1.8" element="led"><bounds x="2" y="16" width="1" height="1" /></bezel>
- <bezel name="1.9" element="led"><bounds x="2" y="18" width="1" height="1" /></bezel>
- <bezel name="1.10" element="led"><bounds x="2" y="20" width="1" height="1" /></bezel>
- <bezel name="1.11" element="led"><bounds x="2" y="22" width="1" height="1" /></bezel>
- <bezel name="1.12" element="led"><bounds x="2" y="24" width="1" height="1" /></bezel>
- <bezel name="1.13" element="led"><bounds x="2" y="26" width="1" height="1" /></bezel>
- <bezel name="1.14" element="led"><bounds x="2" y="28" width="1" height="1" /></bezel>
- <bezel name="1.15" element="led"><bounds x="2" y="30" width="1" height="1" /></bezel>
+ <bezel name="0.0.0" element="led"><bounds x="0" y="0" width="1" height="1" /></bezel>
+ <bezel name="0.1.0" element="led"><bounds x="0" y="2" width="1" height="1" /></bezel>
+ <bezel name="0.2.0" element="led"><bounds x="0" y="4" width="1" height="1" /></bezel>
+ <bezel name="0.3.0" element="led"><bounds x="0" y="6" width="1" height="1" /></bezel>
+ <bezel name="0.4.0" element="led"><bounds x="0" y="8" width="1" height="1" /></bezel>
+ <bezel name="0.5.0" element="led"><bounds x="0" y="10" width="1" height="1" /></bezel>
+ <bezel name="0.6.0" element="led"><bounds x="0" y="12" width="1" height="1" /></bezel>
+ <bezel name="0.7.0" element="led"><bounds x="0" y="14" width="1" height="1" /></bezel>
+ <bezel name="0.8.0" element="led"><bounds x="0" y="16" width="1" height="1" /></bezel>
+ <bezel name="0.9.0" element="led"><bounds x="0" y="18" width="1" height="1" /></bezel>
+ <bezel name="0.10.0" element="led"><bounds x="0" y="20" width="1" height="1" /></bezel>
+ <bezel name="0.11.0" element="led"><bounds x="0" y="22" width="1" height="1" /></bezel>
+ <bezel name="0.12.0" element="led"><bounds x="0" y="24" width="1" height="1" /></bezel>
+ <bezel name="0.13.0" element="led"><bounds x="0" y="26" width="1" height="1" /></bezel>
+ <bezel name="0.14.0" element="led"><bounds x="0" y="28" width="1" height="1" /></bezel>
+ <bezel name="0.15.0" element="led"><bounds x="0" y="30" width="1" height="1" /></bezel>
- <bezel name="2.0" element="led"><bounds x="4" y="0" width="1" height="1" /></bezel>
- <bezel name="2.1" element="led"><bounds x="4" y="2" width="1" height="1" /></bezel>
- <bezel name="2.2" element="led"><bounds x="4" y="4" width="1" height="1" /></bezel>
- <bezel name="2.3" element="led"><bounds x="4" y="6" width="1" height="1" /></bezel>
- <bezel name="2.4" element="led"><bounds x="4" y="8" width="1" height="1" /></bezel>
- <bezel name="2.5" element="led"><bounds x="4" y="10" width="1" height="1" /></bezel>
- <bezel name="2.6" element="led"><bounds x="4" y="12" width="1" height="1" /></bezel>
- <bezel name="2.7" element="led"><bounds x="4" y="14" width="1" height="1" /></bezel>
- <bezel name="2.8" element="led"><bounds x="4" y="16" width="1" height="1" /></bezel>
- <bezel name="2.9" element="led"><bounds x="4" y="18" width="1" height="1" /></bezel>
- <bezel name="2.10" element="led"><bounds x="4" y="20" width="1" height="1" /></bezel>
- <bezel name="2.11" element="led"><bounds x="4" y="22" width="1" height="1" /></bezel>
- <bezel name="2.12" element="led"><bounds x="4" y="24" width="1" height="1" /></bezel>
- <bezel name="2.13" element="led"><bounds x="4" y="26" width="1" height="1" /></bezel>
- <bezel name="2.14" element="led"><bounds x="4" y="28" width="1" height="1" /></bezel>
- <bezel name="2.15" element="led"><bounds x="4" y="30" width="1" height="1" /></bezel>
+ <bezel name="0.0.1" element="led"><bounds x="2" y="0" width="1" height="1" /></bezel>
+ <bezel name="0.1.1" element="led"><bounds x="2" y="2" width="1" height="1" /></bezel>
+ <bezel name="0.2.1" element="led"><bounds x="2" y="4" width="1" height="1" /></bezel>
+ <bezel name="0.3.1" element="led"><bounds x="2" y="6" width="1" height="1" /></bezel>
+ <bezel name="0.4.1" element="led"><bounds x="2" y="8" width="1" height="1" /></bezel>
+ <bezel name="0.5.1" element="led"><bounds x="2" y="10" width="1" height="1" /></bezel>
+ <bezel name="0.6.1" element="led"><bounds x="2" y="12" width="1" height="1" /></bezel>
+ <bezel name="0.7.1" element="led"><bounds x="2" y="14" width="1" height="1" /></bezel>
+ <bezel name="0.8.1" element="led"><bounds x="2" y="16" width="1" height="1" /></bezel>
+ <bezel name="0.9.1" element="led"><bounds x="2" y="18" width="1" height="1" /></bezel>
+ <bezel name="0.10.1" element="led"><bounds x="2" y="20" width="1" height="1" /></bezel>
+ <bezel name="0.11.1" element="led"><bounds x="2" y="22" width="1" height="1" /></bezel>
+ <bezel name="0.12.1" element="led"><bounds x="2" y="24" width="1" height="1" /></bezel>
+ <bezel name="0.13.1" element="led"><bounds x="2" y="26" width="1" height="1" /></bezel>
+ <bezel name="0.14.1" element="led"><bounds x="2" y="28" width="1" height="1" /></bezel>
+ <bezel name="0.15.1" element="led"><bounds x="2" y="30" width="1" height="1" /></bezel>
- <bezel name="3.0" element="led"><bounds x="6" y="0" width="1" height="1" /></bezel>
- <bezel name="3.1" element="led"><bounds x="6" y="2" width="1" height="1" /></bezel>
- <bezel name="3.2" element="led"><bounds x="6" y="4" width="1" height="1" /></bezel>
- <bezel name="3.3" element="led"><bounds x="6" y="6" width="1" height="1" /></bezel>
- <bezel name="3.4" element="led"><bounds x="6" y="8" width="1" height="1" /></bezel>
- <bezel name="3.5" element="led"><bounds x="6" y="10" width="1" height="1" /></bezel>
- <bezel name="3.6" element="led"><bounds x="6" y="12" width="1" height="1" /></bezel>
- <bezel name="3.7" element="led"><bounds x="6" y="14" width="1" height="1" /></bezel>
- <bezel name="3.8" element="led"><bounds x="6" y="16" width="1" height="1" /></bezel>
- <bezel name="3.9" element="led"><bounds x="6" y="18" width="1" height="1" /></bezel>
- <bezel name="3.10" element="led"><bounds x="6" y="20" width="1" height="1" /></bezel>
- <bezel name="3.11" element="led"><bounds x="6" y="22" width="1" height="1" /></bezel>
- <bezel name="3.12" element="led"><bounds x="6" y="24" width="1" height="1" /></bezel>
- <bezel name="3.13" element="led"><bounds x="6" y="26" width="1" height="1" /></bezel>
- <bezel name="3.14" element="led"><bounds x="6" y="28" width="1" height="1" /></bezel>
- <bezel name="3.15" element="led"><bounds x="6" y="30" width="1" height="1" /></bezel>
+ <bezel name="0.0.2" element="led"><bounds x="4" y="0" width="1" height="1" /></bezel>
+ <bezel name="0.1.2" element="led"><bounds x="4" y="2" width="1" height="1" /></bezel>
+ <bezel name="0.2.2" element="led"><bounds x="4" y="4" width="1" height="1" /></bezel>
+ <bezel name="0.3.2" element="led"><bounds x="4" y="6" width="1" height="1" /></bezel>
+ <bezel name="0.4.2" element="led"><bounds x="4" y="8" width="1" height="1" /></bezel>
+ <bezel name="0.5.2" element="led"><bounds x="4" y="10" width="1" height="1" /></bezel>
+ <bezel name="0.6.2" element="led"><bounds x="4" y="12" width="1" height="1" /></bezel>
+ <bezel name="0.7.2" element="led"><bounds x="4" y="14" width="1" height="1" /></bezel>
+ <bezel name="0.8.2" element="led"><bounds x="4" y="16" width="1" height="1" /></bezel>
+ <bezel name="0.9.2" element="led"><bounds x="4" y="18" width="1" height="1" /></bezel>
+ <bezel name="0.10.2" element="led"><bounds x="4" y="20" width="1" height="1" /></bezel>
+ <bezel name="0.11.2" element="led"><bounds x="4" y="22" width="1" height="1" /></bezel>
+ <bezel name="0.12.2" element="led"><bounds x="4" y="24" width="1" height="1" /></bezel>
+ <bezel name="0.13.2" element="led"><bounds x="4" y="26" width="1" height="1" /></bezel>
+ <bezel name="0.14.2" element="led"><bounds x="4" y="28" width="1" height="1" /></bezel>
+ <bezel name="0.15.2" element="led"><bounds x="4" y="30" width="1" height="1" /></bezel>
- <bezel name="4.0" element="led"><bounds x="8" y="0" width="1" height="1" /></bezel>
- <bezel name="4.1" element="led"><bounds x="8" y="2" width="1" height="1" /></bezel>
- <bezel name="4.2" element="led"><bounds x="8" y="4" width="1" height="1" /></bezel>
- <bezel name="4.3" element="led"><bounds x="8" y="6" width="1" height="1" /></bezel>
- <bezel name="4.4" element="led"><bounds x="8" y="8" width="1" height="1" /></bezel>
- <bezel name="4.5" element="led"><bounds x="8" y="10" width="1" height="1" /></bezel>
- <bezel name="4.6" element="led"><bounds x="8" y="12" width="1" height="1" /></bezel>
- <bezel name="4.7" element="led"><bounds x="8" y="14" width="1" height="1" /></bezel>
- <bezel name="4.8" element="led"><bounds x="8" y="16" width="1" height="1" /></bezel>
- <bezel name="4.9" element="led"><bounds x="8" y="18" width="1" height="1" /></bezel>
- <bezel name="4.10" element="led"><bounds x="8" y="20" width="1" height="1" /></bezel>
- <bezel name="4.11" element="led"><bounds x="8" y="22" width="1" height="1" /></bezel>
- <bezel name="4.12" element="led"><bounds x="8" y="24" width="1" height="1" /></bezel>
- <bezel name="4.13" element="led"><bounds x="8" y="26" width="1" height="1" /></bezel>
- <bezel name="4.14" element="led"><bounds x="8" y="28" width="1" height="1" /></bezel>
- <bezel name="4.15" element="led"><bounds x="8" y="30" width="1" height="1" /></bezel>
+ <bezel name="0.0.3" element="led"><bounds x="6" y="0" width="1" height="1" /></bezel>
+ <bezel name="0.1.3" element="led"><bounds x="6" y="2" width="1" height="1" /></bezel>
+ <bezel name="0.2.3" element="led"><bounds x="6" y="4" width="1" height="1" /></bezel>
+ <bezel name="0.3.3" element="led"><bounds x="6" y="6" width="1" height="1" /></bezel>
+ <bezel name="0.4.3" element="led"><bounds x="6" y="8" width="1" height="1" /></bezel>
+ <bezel name="0.5.3" element="led"><bounds x="6" y="10" width="1" height="1" /></bezel>
+ <bezel name="0.6.3" element="led"><bounds x="6" y="12" width="1" height="1" /></bezel>
+ <bezel name="0.7.3" element="led"><bounds x="6" y="14" width="1" height="1" /></bezel>
+ <bezel name="0.8.3" element="led"><bounds x="6" y="16" width="1" height="1" /></bezel>
+ <bezel name="0.9.3" element="led"><bounds x="6" y="18" width="1" height="1" /></bezel>
+ <bezel name="0.10.3" element="led"><bounds x="6" y="20" width="1" height="1" /></bezel>
+ <bezel name="0.11.3" element="led"><bounds x="6" y="22" width="1" height="1" /></bezel>
+ <bezel name="0.12.3" element="led"><bounds x="6" y="24" width="1" height="1" /></bezel>
+ <bezel name="0.13.3" element="led"><bounds x="6" y="26" width="1" height="1" /></bezel>
+ <bezel name="0.14.3" element="led"><bounds x="6" y="28" width="1" height="1" /></bezel>
+ <bezel name="0.15.3" element="led"><bounds x="6" y="30" width="1" height="1" /></bezel>
- <bezel name="5.0" element="led"><bounds x="10" y="0" width="1" height="1" /></bezel>
- <bezel name="5.1" element="led"><bounds x="10" y="2" width="1" height="1" /></bezel>
- <bezel name="5.2" element="led"><bounds x="10" y="4" width="1" height="1" /></bezel>
- <bezel name="5.3" element="led"><bounds x="10" y="6" width="1" height="1" /></bezel>
- <bezel name="5.4" element="led"><bounds x="10" y="8" width="1" height="1" /></bezel>
- <bezel name="5.5" element="led"><bounds x="10" y="10" width="1" height="1" /></bezel>
- <bezel name="5.6" element="led"><bounds x="10" y="12" width="1" height="1" /></bezel>
- <bezel name="5.7" element="led"><bounds x="10" y="14" width="1" height="1" /></bezel>
- <bezel name="5.8" element="led"><bounds x="10" y="16" width="1" height="1" /></bezel>
- <bezel name="5.9" element="led"><bounds x="10" y="18" width="1" height="1" /></bezel>
- <bezel name="5.10" element="led"><bounds x="10" y="20" width="1" height="1" /></bezel>
- <bezel name="5.11" element="led"><bounds x="10" y="22" width="1" height="1" /></bezel>
- <bezel name="5.12" element="led"><bounds x="10" y="24" width="1" height="1" /></bezel>
- <bezel name="5.13" element="led"><bounds x="10" y="26" width="1" height="1" /></bezel>
- <bezel name="5.14" element="led"><bounds x="10" y="28" width="1" height="1" /></bezel>
- <bezel name="5.15" element="led"><bounds x="10" y="30" width="1" height="1" /></bezel>
+ <!-- b -->
- <bezel name="6.0" element="led"><bounds x="12" y="0" width="1" height="1" /></bezel>
- <bezel name="6.1" element="led"><bounds x="12" y="2" width="1" height="1" /></bezel>
- <bezel name="6.2" element="led"><bounds x="12" y="4" width="1" height="1" /></bezel>
- <bezel name="6.3" element="led"><bounds x="12" y="6" width="1" height="1" /></bezel>
- <bezel name="6.4" element="led"><bounds x="12" y="8" width="1" height="1" /></bezel>
- <bezel name="6.5" element="led"><bounds x="12" y="10" width="1" height="1" /></bezel>
- <bezel name="6.6" element="led"><bounds x="12" y="12" width="1" height="1" /></bezel>
- <bezel name="6.7" element="led"><bounds x="12" y="14" width="1" height="1" /></bezel>
- <bezel name="6.8" element="led"><bounds x="12" y="16" width="1" height="1" /></bezel>
- <bezel name="6.9" element="led"><bounds x="12" y="18" width="1" height="1" /></bezel>
- <bezel name="6.10" element="led"><bounds x="12" y="20" width="1" height="1" /></bezel>
- <bezel name="6.11" element="led"><bounds x="12" y="22" width="1" height="1" /></bezel>
- <bezel name="6.12" element="led"><bounds x="12" y="24" width="1" height="1" /></bezel>
- <bezel name="6.13" element="led"><bounds x="12" y="26" width="1" height="1" /></bezel>
- <bezel name="6.14" element="led"><bounds x="12" y="28" width="1" height="1" /></bezel>
- <bezel name="6.15" element="led"><bounds x="12" y="30" width="1" height="1" /></bezel>
+ <bezel name="1.0.0" element="led"><bounds x="10" y="0" width="1" height="1" /></bezel>
+ <bezel name="1.1.0" element="led"><bounds x="10" y="2" width="1" height="1" /></bezel>
+ <bezel name="1.2.0" element="led"><bounds x="10" y="4" width="1" height="1" /></bezel>
+ <bezel name="1.3.0" element="led"><bounds x="10" y="6" width="1" height="1" /></bezel>
+ <bezel name="1.4.0" element="led"><bounds x="10" y="8" width="1" height="1" /></bezel>
+ <bezel name="1.5.0" element="led"><bounds x="10" y="10" width="1" height="1" /></bezel>
+ <bezel name="1.6.0" element="led"><bounds x="10" y="12" width="1" height="1" /></bezel>
+ <bezel name="1.7.0" element="led"><bounds x="10" y="14" width="1" height="1" /></bezel>
+ <bezel name="1.8.0" element="led"><bounds x="10" y="16" width="1" height="1" /></bezel>
+ <bezel name="1.9.0" element="led"><bounds x="10" y="18" width="1" height="1" /></bezel>
+ <bezel name="1.10.0" element="led"><bounds x="10" y="20" width="1" height="1" /></bezel>
+ <bezel name="1.11.0" element="led"><bounds x="10" y="22" width="1" height="1" /></bezel>
+ <bezel name="1.12.0" element="led"><bounds x="10" y="24" width="1" height="1" /></bezel>
+ <bezel name="1.13.0" element="led"><bounds x="10" y="26" width="1" height="1" /></bezel>
+ <bezel name="1.14.0" element="led"><bounds x="10" y="28" width="1" height="1" /></bezel>
+ <bezel name="1.15.0" element="led"><bounds x="10" y="30" width="1" height="1" /></bezel>
- <bezel name="7.0" element="led"><bounds x="14" y="0" width="1" height="1" /></bezel>
- <bezel name="7.1" element="led"><bounds x="14" y="2" width="1" height="1" /></bezel>
- <bezel name="7.2" element="led"><bounds x="14" y="4" width="1" height="1" /></bezel>
- <bezel name="7.3" element="led"><bounds x="14" y="6" width="1" height="1" /></bezel>
- <bezel name="7.4" element="led"><bounds x="14" y="8" width="1" height="1" /></bezel>
- <bezel name="7.5" element="led"><bounds x="14" y="10" width="1" height="1" /></bezel>
- <bezel name="7.6" element="led"><bounds x="14" y="12" width="1" height="1" /></bezel>
- <bezel name="7.7" element="led"><bounds x="14" y="14" width="1" height="1" /></bezel>
- <bezel name="7.8" element="led"><bounds x="14" y="16" width="1" height="1" /></bezel>
- <bezel name="7.9" element="led"><bounds x="14" y="18" width="1" height="1" /></bezel>
- <bezel name="7.10" element="led"><bounds x="14" y="20" width="1" height="1" /></bezel>
- <bezel name="7.11" element="led"><bounds x="14" y="22" width="1" height="1" /></bezel>
- <bezel name="7.12" element="led"><bounds x="14" y="24" width="1" height="1" /></bezel>
- <bezel name="7.13" element="led"><bounds x="14" y="26" width="1" height="1" /></bezel>
- <bezel name="7.14" element="led"><bounds x="14" y="28" width="1" height="1" /></bezel>
- <bezel name="7.15" element="led"><bounds x="14" y="30" width="1" height="1" /></bezel>
+ <bezel name="1.0.1" element="led"><bounds x="12" y="0" width="1" height="1" /></bezel>
+ <bezel name="1.1.1" element="led"><bounds x="12" y="2" width="1" height="1" /></bezel>
+ <bezel name="1.2.1" element="led"><bounds x="12" y="4" width="1" height="1" /></bezel>
+ <bezel name="1.3.1" element="led"><bounds x="12" y="6" width="1" height="1" /></bezel>
+ <bezel name="1.4.1" element="led"><bounds x="12" y="8" width="1" height="1" /></bezel>
+ <bezel name="1.5.1" element="led"><bounds x="12" y="10" width="1" height="1" /></bezel>
+ <bezel name="1.6.1" element="led"><bounds x="12" y="12" width="1" height="1" /></bezel>
+ <bezel name="1.7.1" element="led"><bounds x="12" y="14" width="1" height="1" /></bezel>
+ <bezel name="1.8.1" element="led"><bounds x="12" y="16" width="1" height="1" /></bezel>
+ <bezel name="1.9.1" element="led"><bounds x="12" y="18" width="1" height="1" /></bezel>
+ <bezel name="1.10.1" element="led"><bounds x="12" y="20" width="1" height="1" /></bezel>
+ <bezel name="1.11.1" element="led"><bounds x="12" y="22" width="1" height="1" /></bezel>
+ <bezel name="1.12.1" element="led"><bounds x="12" y="24" width="1" height="1" /></bezel>
+ <bezel name="1.13.1" element="led"><bounds x="12" y="26" width="1" height="1" /></bezel>
+ <bezel name="1.14.1" element="led"><bounds x="12" y="28" width="1" height="1" /></bezel>
+ <bezel name="1.15.1" element="led"><bounds x="12" y="30" width="1" height="1" /></bezel>
- <bezel name="8.0" element="led"><bounds x="16" y="0" width="1" height="1" /></bezel>
- <bezel name="8.1" element="led"><bounds x="16" y="2" width="1" height="1" /></bezel>
- <bezel name="8.2" element="led"><bounds x="16" y="4" width="1" height="1" /></bezel>
- <bezel name="8.3" element="led"><bounds x="16" y="6" width="1" height="1" /></bezel>
- <bezel name="8.4" element="led"><bounds x="16" y="8" width="1" height="1" /></bezel>
- <bezel name="8.5" element="led"><bounds x="16" y="10" width="1" height="1" /></bezel>
- <bezel name="8.6" element="led"><bounds x="16" y="12" width="1" height="1" /></bezel>
- <bezel name="8.7" element="led"><bounds x="16" y="14" width="1" height="1" /></bezel>
- <bezel name="8.8" element="led"><bounds x="16" y="16" width="1" height="1" /></bezel>
- <bezel name="8.9" element="led"><bounds x="16" y="18" width="1" height="1" /></bezel>
- <bezel name="8.10" element="led"><bounds x="16" y="20" width="1" height="1" /></bezel>
- <bezel name="8.11" element="led"><bounds x="16" y="22" width="1" height="1" /></bezel>
- <bezel name="8.12" element="led"><bounds x="16" y="24" width="1" height="1" /></bezel>
- <bezel name="8.13" element="led"><bounds x="16" y="26" width="1" height="1" /></bezel>
- <bezel name="8.14" element="led"><bounds x="16" y="28" width="1" height="1" /></bezel>
- <bezel name="8.15" element="led"><bounds x="16" y="30" width="1" height="1" /></bezel>
+ <bezel name="1.0.2" element="led"><bounds x="14" y="0" width="1" height="1" /></bezel>
+ <bezel name="1.1.2" element="led"><bounds x="14" y="2" width="1" height="1" /></bezel>
+ <bezel name="1.2.2" element="led"><bounds x="14" y="4" width="1" height="1" /></bezel>
+ <bezel name="1.3.2" element="led"><bounds x="14" y="6" width="1" height="1" /></bezel>
+ <bezel name="1.4.2" element="led"><bounds x="14" y="8" width="1" height="1" /></bezel>
+ <bezel name="1.5.2" element="led"><bounds x="14" y="10" width="1" height="1" /></bezel>
+ <bezel name="1.6.2" element="led"><bounds x="14" y="12" width="1" height="1" /></bezel>
+ <bezel name="1.7.2" element="led"><bounds x="14" y="14" width="1" height="1" /></bezel>
+ <bezel name="1.8.2" element="led"><bounds x="14" y="16" width="1" height="1" /></bezel>
+ <bezel name="1.9.2" element="led"><bounds x="14" y="18" width="1" height="1" /></bezel>
+ <bezel name="1.10.2" element="led"><bounds x="14" y="20" width="1" height="1" /></bezel>
+ <bezel name="1.11.2" element="led"><bounds x="14" y="22" width="1" height="1" /></bezel>
+ <bezel name="1.12.2" element="led"><bounds x="14" y="24" width="1" height="1" /></bezel>
+ <bezel name="1.13.2" element="led"><bounds x="14" y="26" width="1" height="1" /></bezel>
+ <bezel name="1.14.2" element="led"><bounds x="14" y="28" width="1" height="1" /></bezel>
+ <bezel name="1.15.2" element="led"><bounds x="14" y="30" width="1" height="1" /></bezel>
- <bezel name="9.0" element="led"><bounds x="18" y="0" width="1" height="1" /></bezel>
- <bezel name="9.1" element="led"><bounds x="18" y="2" width="1" height="1" /></bezel>
- <bezel name="9.2" element="led"><bounds x="18" y="4" width="1" height="1" /></bezel>
- <bezel name="9.3" element="led"><bounds x="18" y="6" width="1" height="1" /></bezel>
- <bezel name="9.4" element="led"><bounds x="18" y="8" width="1" height="1" /></bezel>
- <bezel name="9.5" element="led"><bounds x="18" y="10" width="1" height="1" /></bezel>
- <bezel name="9.6" element="led"><bounds x="18" y="12" width="1" height="1" /></bezel>
- <bezel name="9.7" element="led"><bounds x="18" y="14" width="1" height="1" /></bezel>
- <bezel name="9.8" element="led"><bounds x="18" y="16" width="1" height="1" /></bezel>
- <bezel name="9.9" element="led"><bounds x="18" y="18" width="1" height="1" /></bezel>
- <bezel name="9.10" element="led"><bounds x="18" y="20" width="1" height="1" /></bezel>
- <bezel name="9.11" element="led"><bounds x="18" y="22" width="1" height="1" /></bezel>
- <bezel name="9.12" element="led"><bounds x="18" y="24" width="1" height="1" /></bezel>
- <bezel name="9.13" element="led"><bounds x="18" y="26" width="1" height="1" /></bezel>
- <bezel name="9.14" element="led"><bounds x="18" y="28" width="1" height="1" /></bezel>
- <bezel name="9.15" element="led"><bounds x="18" y="30" width="1" height="1" /></bezel>
+ <bezel name="1.0.3" element="led"><bounds x="16" y="0" width="1" height="1" /></bezel>
+ <bezel name="1.1.3" element="led"><bounds x="16" y="2" width="1" height="1" /></bezel>
+ <bezel name="1.2.3" element="led"><bounds x="16" y="4" width="1" height="1" /></bezel>
+ <bezel name="1.3.3" element="led"><bounds x="16" y="6" width="1" height="1" /></bezel>
+ <bezel name="1.4.3" element="led"><bounds x="16" y="8" width="1" height="1" /></bezel>
+ <bezel name="1.5.3" element="led"><bounds x="16" y="10" width="1" height="1" /></bezel>
+ <bezel name="1.6.3" element="led"><bounds x="16" y="12" width="1" height="1" /></bezel>
+ <bezel name="1.7.3" element="led"><bounds x="16" y="14" width="1" height="1" /></bezel>
+ <bezel name="1.8.3" element="led"><bounds x="16" y="16" width="1" height="1" /></bezel>
+ <bezel name="1.9.3" element="led"><bounds x="16" y="18" width="1" height="1" /></bezel>
+ <bezel name="1.10.3" element="led"><bounds x="16" y="20" width="1" height="1" /></bezel>
+ <bezel name="1.11.3" element="led"><bounds x="16" y="22" width="1" height="1" /></bezel>
+ <bezel name="1.12.3" element="led"><bounds x="16" y="24" width="1" height="1" /></bezel>
+ <bezel name="1.13.3" element="led"><bounds x="16" y="26" width="1" height="1" /></bezel>
+ <bezel name="1.14.3" element="led"><bounds x="16" y="28" width="1" height="1" /></bezel>
+ <bezel name="1.15.3" element="led"><bounds x="16" y="30" width="1" height="1" /></bezel>
- <bezel name="10.0" element="led"><bounds x="20" y="0" width="1" height="1" /></bezel>
- <bezel name="10.1" element="led"><bounds x="20" y="2" width="1" height="1" /></bezel>
- <bezel name="10.2" element="led"><bounds x="20" y="4" width="1" height="1" /></bezel>
- <bezel name="10.3" element="led"><bounds x="20" y="6" width="1" height="1" /></bezel>
- <bezel name="10.4" element="led"><bounds x="20" y="8" width="1" height="1" /></bezel>
- <bezel name="10.5" element="led"><bounds x="20" y="10" width="1" height="1" /></bezel>
- <bezel name="10.6" element="led"><bounds x="20" y="12" width="1" height="1" /></bezel>
- <bezel name="10.7" element="led"><bounds x="20" y="14" width="1" height="1" /></bezel>
- <bezel name="10.8" element="led"><bounds x="20" y="16" width="1" height="1" /></bezel>
- <bezel name="10.9" element="led"><bounds x="20" y="18" width="1" height="1" /></bezel>
- <bezel name="10.10" element="led"><bounds x="20" y="20" width="1" height="1" /></bezel>
- <bezel name="10.11" element="led"><bounds x="20" y="22" width="1" height="1" /></bezel>
- <bezel name="10.12" element="led"><bounds x="20" y="24" width="1" height="1" /></bezel>
- <bezel name="10.13" element="led"><bounds x="20" y="26" width="1" height="1" /></bezel>
- <bezel name="10.14" element="led"><bounds x="20" y="28" width="1" height="1" /></bezel>
- <bezel name="10.15" element="led"><bounds x="20" y="30" width="1" height="1" /></bezel>
+ <!-- bs -->
- <bezel name="11.0" element="led"><bounds x="22" y="0" width="1" height="1" /></bezel>
- <bezel name="11.1" element="led"><bounds x="22" y="2" width="1" height="1" /></bezel>
- <bezel name="11.2" element="led"><bounds x="22" y="4" width="1" height="1" /></bezel>
- <bezel name="11.3" element="led"><bounds x="22" y="6" width="1" height="1" /></bezel>
- <bezel name="11.4" element="led"><bounds x="22" y="8" width="1" height="1" /></bezel>
- <bezel name="11.5" element="led"><bounds x="22" y="10" width="1" height="1" /></bezel>
- <bezel name="11.6" element="led"><bounds x="22" y="12" width="1" height="1" /></bezel>
- <bezel name="11.7" element="led"><bounds x="22" y="14" width="1" height="1" /></bezel>
- <bezel name="11.8" element="led"><bounds x="22" y="16" width="1" height="1" /></bezel>
- <bezel name="11.9" element="led"><bounds x="22" y="18" width="1" height="1" /></bezel>
- <bezel name="11.10" element="led"><bounds x="22" y="20" width="1" height="1" /></bezel>
- <bezel name="11.11" element="led"><bounds x="22" y="22" width="1" height="1" /></bezel>
- <bezel name="11.12" element="led"><bounds x="22" y="24" width="1" height="1" /></bezel>
- <bezel name="11.13" element="led"><bounds x="22" y="26" width="1" height="1" /></bezel>
- <bezel name="11.14" element="led"><bounds x="22" y="28" width="1" height="1" /></bezel>
- <bezel name="11.15" element="led"><bounds x="22" y="30" width="1" height="1" /></bezel>
+ <bezel name="2.0.0" element="led"><bounds x="20" y="0" width="1" height="1" /></bezel>
+ <bezel name="2.1.0" element="led"><bounds x="20" y="2" width="1" height="1" /></bezel>
+ <bezel name="2.2.0" element="led"><bounds x="20" y="4" width="1" height="1" /></bezel>
+ <bezel name="2.3.0" element="led"><bounds x="20" y="6" width="1" height="1" /></bezel>
+ <bezel name="2.4.0" element="led"><bounds x="20" y="8" width="1" height="1" /></bezel>
+ <bezel name="2.5.0" element="led"><bounds x="20" y="10" width="1" height="1" /></bezel>
+ <bezel name="2.6.0" element="led"><bounds x="20" y="12" width="1" height="1" /></bezel>
+ <bezel name="2.7.0" element="led"><bounds x="20" y="14" width="1" height="1" /></bezel>
+ <bezel name="2.8.0" element="led"><bounds x="20" y="16" width="1" height="1" /></bezel>
+ <bezel name="2.9.0" element="led"><bounds x="20" y="18" width="1" height="1" /></bezel>
+ <bezel name="2.10.0" element="led"><bounds x="20" y="20" width="1" height="1" /></bezel>
+ <bezel name="2.11.0" element="led"><bounds x="20" y="22" width="1" height="1" /></bezel>
+ <bezel name="2.12.0" element="led"><bounds x="20" y="24" width="1" height="1" /></bezel>
+ <bezel name="2.13.0" element="led"><bounds x="20" y="26" width="1" height="1" /></bezel>
+ <bezel name="2.14.0" element="led"><bounds x="20" y="28" width="1" height="1" /></bezel>
+ <bezel name="2.15.0" element="led"><bounds x="20" y="30" width="1" height="1" /></bezel>
- <bezel name="12.0" element="led"><bounds x="24" y="0" width="1" height="1" /></bezel>
- <bezel name="12.1" element="led"><bounds x="24" y="2" width="1" height="1" /></bezel>
- <bezel name="12.2" element="led"><bounds x="24" y="4" width="1" height="1" /></bezel>
- <bezel name="12.3" element="led"><bounds x="24" y="6" width="1" height="1" /></bezel>
- <bezel name="12.4" element="led"><bounds x="24" y="8" width="1" height="1" /></bezel>
- <bezel name="12.5" element="led"><bounds x="24" y="10" width="1" height="1" /></bezel>
- <bezel name="12.6" element="led"><bounds x="24" y="12" width="1" height="1" /></bezel>
- <bezel name="12.7" element="led"><bounds x="24" y="14" width="1" height="1" /></bezel>
- <bezel name="12.8" element="led"><bounds x="24" y="16" width="1" height="1" /></bezel>
- <bezel name="12.9" element="led"><bounds x="24" y="18" width="1" height="1" /></bezel>
- <bezel name="12.10" element="led"><bounds x="24" y="20" width="1" height="1" /></bezel>
- <bezel name="12.11" element="led"><bounds x="24" y="22" width="1" height="1" /></bezel>
- <bezel name="12.12" element="led"><bounds x="24" y="24" width="1" height="1" /></bezel>
- <bezel name="12.13" element="led"><bounds x="24" y="26" width="1" height="1" /></bezel>
- <bezel name="12.14" element="led"><bounds x="24" y="28" width="1" height="1" /></bezel>
- <bezel name="12.15" element="led"><bounds x="24" y="30" width="1" height="1" /></bezel>
+ <bezel name="2.0.1" element="led"><bounds x="22" y="0" width="1" height="1" /></bezel>
+ <bezel name="2.1.1" element="led"><bounds x="22" y="2" width="1" height="1" /></bezel>
+ <bezel name="2.2.1" element="led"><bounds x="22" y="4" width="1" height="1" /></bezel>
+ <bezel name="2.3.1" element="led"><bounds x="22" y="6" width="1" height="1" /></bezel>
+ <bezel name="2.4.1" element="led"><bounds x="22" y="8" width="1" height="1" /></bezel>
+ <bezel name="2.5.1" element="led"><bounds x="22" y="10" width="1" height="1" /></bezel>
+ <bezel name="2.6.1" element="led"><bounds x="22" y="12" width="1" height="1" /></bezel>
+ <bezel name="2.7.1" element="led"><bounds x="22" y="14" width="1" height="1" /></bezel>
+ <bezel name="2.8.1" element="led"><bounds x="22" y="16" width="1" height="1" /></bezel>
+ <bezel name="2.9.1" element="led"><bounds x="22" y="18" width="1" height="1" /></bezel>
+ <bezel name="2.10.1" element="led"><bounds x="22" y="20" width="1" height="1" /></bezel>
+ <bezel name="2.11.1" element="led"><bounds x="22" y="22" width="1" height="1" /></bezel>
+ <bezel name="2.12.1" element="led"><bounds x="22" y="24" width="1" height="1" /></bezel>
+ <bezel name="2.13.1" element="led"><bounds x="22" y="26" width="1" height="1" /></bezel>
+ <bezel name="2.14.1" element="led"><bounds x="22" y="28" width="1" height="1" /></bezel>
+ <bezel name="2.15.1" element="led"><bounds x="22" y="30" width="1" height="1" /></bezel>
- <bezel name="13.0" element="led"><bounds x="26" y="0" width="1" height="1" /></bezel>
- <bezel name="13.1" element="led"><bounds x="26" y="2" width="1" height="1" /></bezel>
- <bezel name="13.2" element="led"><bounds x="26" y="4" width="1" height="1" /></bezel>
- <bezel name="13.3" element="led"><bounds x="26" y="6" width="1" height="1" /></bezel>
- <bezel name="13.4" element="led"><bounds x="26" y="8" width="1" height="1" /></bezel>
- <bezel name="13.5" element="led"><bounds x="26" y="10" width="1" height="1" /></bezel>
- <bezel name="13.6" element="led"><bounds x="26" y="12" width="1" height="1" /></bezel>
- <bezel name="13.7" element="led"><bounds x="26" y="14" width="1" height="1" /></bezel>
- <bezel name="13.8" element="led"><bounds x="26" y="16" width="1" height="1" /></bezel>
- <bezel name="13.9" element="led"><bounds x="26" y="18" width="1" height="1" /></bezel>
- <bezel name="13.10" element="led"><bounds x="26" y="20" width="1" height="1" /></bezel>
- <bezel name="13.11" element="led"><bounds x="26" y="22" width="1" height="1" /></bezel>
- <bezel name="13.12" element="led"><bounds x="26" y="24" width="1" height="1" /></bezel>
- <bezel name="13.13" element="led"><bounds x="26" y="26" width="1" height="1" /></bezel>
- <bezel name="13.14" element="led"><bounds x="26" y="28" width="1" height="1" /></bezel>
- <bezel name="13.15" element="led"><bounds x="26" y="30" width="1" height="1" /></bezel>
+ <bezel name="2.0.2" element="led"><bounds x="24" y="0" width="1" height="1" /></bezel>
+ <bezel name="2.1.2" element="led"><bounds x="24" y="2" width="1" height="1" /></bezel>
+ <bezel name="2.2.2" element="led"><bounds x="24" y="4" width="1" height="1" /></bezel>
+ <bezel name="2.3.2" element="led"><bounds x="24" y="6" width="1" height="1" /></bezel>
+ <bezel name="2.4.2" element="led"><bounds x="24" y="8" width="1" height="1" /></bezel>
+ <bezel name="2.5.2" element="led"><bounds x="24" y="10" width="1" height="1" /></bezel>
+ <bezel name="2.6.2" element="led"><bounds x="24" y="12" width="1" height="1" /></bezel>
+ <bezel name="2.7.2" element="led"><bounds x="24" y="14" width="1" height="1" /></bezel>
+ <bezel name="2.8.2" element="led"><bounds x="24" y="16" width="1" height="1" /></bezel>
+ <bezel name="2.9.2" element="led"><bounds x="24" y="18" width="1" height="1" /></bezel>
+ <bezel name="2.10.2" element="led"><bounds x="24" y="20" width="1" height="1" /></bezel>
+ <bezel name="2.11.2" element="led"><bounds x="24" y="22" width="1" height="1" /></bezel>
+ <bezel name="2.12.2" element="led"><bounds x="24" y="24" width="1" height="1" /></bezel>
+ <bezel name="2.13.2" element="led"><bounds x="24" y="26" width="1" height="1" /></bezel>
+ <bezel name="2.14.2" element="led"><bounds x="24" y="28" width="1" height="1" /></bezel>
+ <bezel name="2.15.2" element="led"><bounds x="24" y="30" width="1" height="1" /></bezel>
- <bezel name="14.0" element="led"><bounds x="28" y="0" width="1" height="1" /></bezel>
- <bezel name="14.1" element="led"><bounds x="28" y="2" width="1" height="1" /></bezel>
- <bezel name="14.2" element="led"><bounds x="28" y="4" width="1" height="1" /></bezel>
- <bezel name="14.3" element="led"><bounds x="28" y="6" width="1" height="1" /></bezel>
- <bezel name="14.4" element="led"><bounds x="28" y="8" width="1" height="1" /></bezel>
- <bezel name="14.5" element="led"><bounds x="28" y="10" width="1" height="1" /></bezel>
- <bezel name="14.6" element="led"><bounds x="28" y="12" width="1" height="1" /></bezel>
- <bezel name="14.7" element="led"><bounds x="28" y="14" width="1" height="1" /></bezel>
- <bezel name="14.8" element="led"><bounds x="28" y="16" width="1" height="1" /></bezel>
- <bezel name="14.9" element="led"><bounds x="28" y="18" width="1" height="1" /></bezel>
- <bezel name="14.10" element="led"><bounds x="28" y="20" width="1" height="1" /></bezel>
- <bezel name="14.11" element="led"><bounds x="28" y="22" width="1" height="1" /></bezel>
- <bezel name="14.12" element="led"><bounds x="28" y="24" width="1" height="1" /></bezel>
- <bezel name="14.13" element="led"><bounds x="28" y="26" width="1" height="1" /></bezel>
- <bezel name="14.14" element="led"><bounds x="28" y="28" width="1" height="1" /></bezel>
- <bezel name="14.15" element="led"><bounds x="28" y="30" width="1" height="1" /></bezel>
+ <bezel name="2.0.3" element="led"><bounds x="26" y="0" width="1" height="1" /></bezel>
+ <bezel name="2.1.3" element="led"><bounds x="26" y="2" width="1" height="1" /></bezel>
+ <bezel name="2.2.3" element="led"><bounds x="26" y="4" width="1" height="1" /></bezel>
+ <bezel name="2.3.3" element="led"><bounds x="26" y="6" width="1" height="1" /></bezel>
+ <bezel name="2.4.3" element="led"><bounds x="26" y="8" width="1" height="1" /></bezel>
+ <bezel name="2.5.3" element="led"><bounds x="26" y="10" width="1" height="1" /></bezel>
+ <bezel name="2.6.3" element="led"><bounds x="26" y="12" width="1" height="1" /></bezel>
+ <bezel name="2.7.3" element="led"><bounds x="26" y="14" width="1" height="1" /></bezel>
+ <bezel name="2.8.3" element="led"><bounds x="26" y="16" width="1" height="1" /></bezel>
+ <bezel name="2.9.3" element="led"><bounds x="26" y="18" width="1" height="1" /></bezel>
+ <bezel name="2.10.3" element="led"><bounds x="26" y="20" width="1" height="1" /></bezel>
+ <bezel name="2.11.3" element="led"><bounds x="26" y="22" width="1" height="1" /></bezel>
+ <bezel name="2.12.3" element="led"><bounds x="26" y="24" width="1" height="1" /></bezel>
+ <bezel name="2.13.3" element="led"><bounds x="26" y="26" width="1" height="1" /></bezel>
+ <bezel name="2.14.3" element="led"><bounds x="26" y="28" width="1" height="1" /></bezel>
+ <bezel name="2.15.3" element="led"><bounds x="26" y="30" width="1" height="1" /></bezel>
- <bezel name="15.0" element="led"><bounds x="30" y="0" width="1" height="1" /></bezel>
- <bezel name="15.1" element="led"><bounds x="30" y="2" width="1" height="1" /></bezel>
- <bezel name="15.2" element="led"><bounds x="30" y="4" width="1" height="1" /></bezel>
- <bezel name="15.3" element="led"><bounds x="30" y="6" width="1" height="1" /></bezel>
- <bezel name="15.4" element="led"><bounds x="30" y="8" width="1" height="1" /></bezel>
- <bezel name="15.5" element="led"><bounds x="30" y="10" width="1" height="1" /></bezel>
- <bezel name="15.6" element="led"><bounds x="30" y="12" width="1" height="1" /></bezel>
- <bezel name="15.7" element="led"><bounds x="30" y="14" width="1" height="1" /></bezel>
- <bezel name="15.8" element="led"><bounds x="30" y="16" width="1" height="1" /></bezel>
- <bezel name="15.9" element="led"><bounds x="30" y="18" width="1" height="1" /></bezel>
- <bezel name="15.10" element="led"><bounds x="30" y="20" width="1" height="1" /></bezel>
- <bezel name="15.11" element="led"><bounds x="30" y="22" width="1" height="1" /></bezel>
- <bezel name="15.12" element="led"><bounds x="30" y="24" width="1" height="1" /></bezel>
- <bezel name="15.13" element="led"><bounds x="30" y="26" width="1" height="1" /></bezel>
- <bezel name="15.14" element="led"><bounds x="30" y="28" width="1" height="1" /></bezel>
- <bezel name="15.15" element="led"><bounds x="30" y="30" width="1" height="1" /></bezel>
+ <!-- c -->
+ <bezel name="3.0.0" element="led"><bounds x="30" y="0" width="1" height="1" /></bezel>
+ <bezel name="3.1.0" element="led"><bounds x="30" y="2" width="1" height="1" /></bezel>
+ <bezel name="3.2.0" element="led"><bounds x="30" y="4" width="1" height="1" /></bezel>
+ <bezel name="3.3.0" element="led"><bounds x="30" y="6" width="1" height="1" /></bezel>
+ <bezel name="3.4.0" element="led"><bounds x="30" y="8" width="1" height="1" /></bezel>
+ <bezel name="3.5.0" element="led"><bounds x="30" y="10" width="1" height="1" /></bezel>
+ <bezel name="3.6.0" element="led"><bounds x="30" y="12" width="1" height="1" /></bezel>
+ <bezel name="3.7.0" element="led"><bounds x="30" y="14" width="1" height="1" /></bezel>
+ <bezel name="3.8.0" element="led"><bounds x="30" y="16" width="1" height="1" /></bezel>
+ <bezel name="3.9.0" element="led"><bounds x="30" y="18" width="1" height="1" /></bezel>
+ <bezel name="3.10.0" element="led"><bounds x="30" y="20" width="1" height="1" /></bezel>
+ <bezel name="3.11.0" element="led"><bounds x="30" y="22" width="1" height="1" /></bezel>
+ <bezel name="3.12.0" element="led"><bounds x="30" y="24" width="1" height="1" /></bezel>
+ <bezel name="3.13.0" element="led"><bounds x="30" y="26" width="1" height="1" /></bezel>
+ <bezel name="3.14.0" element="led"><bounds x="30" y="28" width="1" height="1" /></bezel>
+ <bezel name="3.15.0" element="led"><bounds x="30" y="30" width="1" height="1" /></bezel>
+
+ <bezel name="3.0.1" element="led"><bounds x="32" y="0" width="1" height="1" /></bezel>
+ <bezel name="3.1.1" element="led"><bounds x="32" y="2" width="1" height="1" /></bezel>
+ <bezel name="3.2.1" element="led"><bounds x="32" y="4" width="1" height="1" /></bezel>
+ <bezel name="3.3.1" element="led"><bounds x="32" y="6" width="1" height="1" /></bezel>
+ <bezel name="3.4.1" element="led"><bounds x="32" y="8" width="1" height="1" /></bezel>
+ <bezel name="3.5.1" element="led"><bounds x="32" y="10" width="1" height="1" /></bezel>
+ <bezel name="3.6.1" element="led"><bounds x="32" y="12" width="1" height="1" /></bezel>
+ <bezel name="3.7.1" element="led"><bounds x="32" y="14" width="1" height="1" /></bezel>
+ <bezel name="3.8.1" element="led"><bounds x="32" y="16" width="1" height="1" /></bezel>
+ <bezel name="3.9.1" element="led"><bounds x="32" y="18" width="1" height="1" /></bezel>
+ <bezel name="3.10.1" element="led"><bounds x="32" y="20" width="1" height="1" /></bezel>
+ <bezel name="3.11.1" element="led"><bounds x="32" y="22" width="1" height="1" /></bezel>
+ <bezel name="3.12.1" element="led"><bounds x="32" y="24" width="1" height="1" /></bezel>
+ <bezel name="3.13.1" element="led"><bounds x="32" y="26" width="1" height="1" /></bezel>
+ <bezel name="3.14.1" element="led"><bounds x="32" y="28" width="1" height="1" /></bezel>
+ <bezel name="3.15.1" element="led"><bounds x="32" y="30" width="1" height="1" /></bezel>
+
+ <bezel name="3.0.2" element="led"><bounds x="34" y="0" width="1" height="1" /></bezel>
+ <bezel name="3.1.2" element="led"><bounds x="34" y="2" width="1" height="1" /></bezel>
+ <bezel name="3.2.2" element="led"><bounds x="34" y="4" width="1" height="1" /></bezel>
+ <bezel name="3.3.2" element="led"><bounds x="34" y="6" width="1" height="1" /></bezel>
+ <bezel name="3.4.2" element="led"><bounds x="34" y="8" width="1" height="1" /></bezel>
+ <bezel name="3.5.2" element="led"><bounds x="34" y="10" width="1" height="1" /></bezel>
+ <bezel name="3.6.2" element="led"><bounds x="34" y="12" width="1" height="1" /></bezel>
+ <bezel name="3.7.2" element="led"><bounds x="34" y="14" width="1" height="1" /></bezel>
+ <bezel name="3.8.2" element="led"><bounds x="34" y="16" width="1" height="1" /></bezel>
+ <bezel name="3.9.2" element="led"><bounds x="34" y="18" width="1" height="1" /></bezel>
+ <bezel name="3.10.2" element="led"><bounds x="34" y="20" width="1" height="1" /></bezel>
+ <bezel name="3.11.2" element="led"><bounds x="34" y="22" width="1" height="1" /></bezel>
+ <bezel name="3.12.2" element="led"><bounds x="34" y="24" width="1" height="1" /></bezel>
+ <bezel name="3.13.2" element="led"><bounds x="34" y="26" width="1" height="1" /></bezel>
+ <bezel name="3.14.2" element="led"><bounds x="34" y="28" width="1" height="1" /></bezel>
+ <bezel name="3.15.2" element="led"><bounds x="34" y="30" width="1" height="1" /></bezel>
+
+ <bezel name="3.0.3" element="led"><bounds x="36" y="0" width="1" height="1" /></bezel>
+ <bezel name="3.1.3" element="led"><bounds x="36" y="2" width="1" height="1" /></bezel>
+ <bezel name="3.2.3" element="led"><bounds x="36" y="4" width="1" height="1" /></bezel>
+ <bezel name="3.3.3" element="led"><bounds x="36" y="6" width="1" height="1" /></bezel>
+ <bezel name="3.4.3" element="led"><bounds x="36" y="8" width="1" height="1" /></bezel>
+ <bezel name="3.5.3" element="led"><bounds x="36" y="10" width="1" height="1" /></bezel>
+ <bezel name="3.6.3" element="led"><bounds x="36" y="12" width="1" height="1" /></bezel>
+ <bezel name="3.7.3" element="led"><bounds x="36" y="14" width="1" height="1" /></bezel>
+ <bezel name="3.8.3" element="led"><bounds x="36" y="16" width="1" height="1" /></bezel>
+ <bezel name="3.9.3" element="led"><bounds x="36" y="18" width="1" height="1" /></bezel>
+ <bezel name="3.10.3" element="led"><bounds x="36" y="20" width="1" height="1" /></bezel>
+ <bezel name="3.11.3" element="led"><bounds x="36" y="22" width="1" height="1" /></bezel>
+ <bezel name="3.12.3" element="led"><bounds x="36" y="24" width="1" height="1" /></bezel>
+ <bezel name="3.13.3" element="led"><bounds x="36" y="26" width="1" height="1" /></bezel>
+ <bezel name="3.14.3" element="led"><bounds x="36" y="28" width="1" height="1" /></bezel>
+ <bezel name="3.15.3" element="led"><bounds x="36" y="30" width="1" height="1" /></bezel>
</view>
</mamelayout>
diff --git a/src/mame/layout/lostreas.lay b/src/mame/layout/lostreas.lay
index ac967ce00f2..b837830fd10 100644
--- a/src/mame/layout/lostreas.lay
+++ b/src/mame/layout/lostreas.lay
@@ -3,16 +3,109 @@
<!-- define elements -->
+ <element name="static_black"><rect><color red="0.0" green="0.0" blue="0.0" /></rect></element>
+ <element name="static_black2"><rect><color red="0.02" green="0.03" blue="0.05" /></rect></element>
<element name="static_blue"><rect><color red="0.1" green="0.25" blue="0.5" /></rect></element>
<element name="static_blue2"><rect><color red="0.04" green="0.1" blue="0.2" /></rect></element>
- <element name="disk_cyan"><disk><color red="0.0" green="0.75" blue="1.0" /></disk></element>
- <element name="disk_white"><disk><color red="0.8" green="0.9" blue="1.0" /></disk></element>
+ <element name="disk_cyan1"><disk><color red="0.0" green="0.75" blue="1.0" /></disk></element>
+ <element name="disk_cyan2"><disk><color red="0.8" green="0.9" blue="1.0" /></disk></element>
<element name="led" defstate="0">
<disk state="0"><color red="0.2" green="0.04" blue="0.046" /></disk>
<disk state="1"><color red="1.0" green="0.2" blue="0.23" /></disk>
</element>
+ <element name="hl" defstate="0">
+ <text string=" ">
+ <bounds x="0.0" y="0.0" width="1.0" height="1.0" />
+ <color red="0.0" green="0.0" blue="0.0" />
+ </text>
+ <disk state="1">
+ <bounds x="0.07" y="0.07" width="0.86" height="0.86" />
+ <color red="0.0" green="0.0" blue="0.0" />
+ </disk>
+ </element>
+
+ <element name="static_cyan1"><rect><color red="0.0" green="0.75" blue="1.0" /></rect></element>
+ <element name="text_k1">
+ <rect><color red="0.0" green="0.75" blue="1.0" /></rect>
+ <text string="1"><color red="1" green="1" blue="1" /></text>
+ </element>
+ <element name="text_k2">
+ <rect><color red="0.0" green="0.75" blue="1.0" /></rect>
+ <text string="2"><color red="1" green="1" blue="1" /></text>
+ </element>
+ <element name="text_k3">
+ <rect><color red="0.0" green="0.75" blue="1.0" /></rect>
+ <text string="3"><color red="1" green="1" blue="1" /></text>
+ </element>
+ <element name="text_k4">
+ <rect><color red="0.0" green="0.75" blue="1.0" /></rect>
+ <text string="4"><color red="1" green="1" blue="1" /></text>
+ </element>
+ <element name="text_k5">
+ <rect><color red="0.0" green="0.75" blue="1.0" /></rect>
+ <text string="5"><color red="1" green="1" blue="1" /></text>
+ </element>
+ <element name="text_k6">
+ <rect><color red="0.0" green="0.75" blue="1.0" /></rect>
+ <text string="6"><color red="1" green="1" blue="1" /></text>
+ </element>
+ <element name="text_k7">
+ <rect><color red="0.0" green="0.75" blue="1.0" /></rect>
+ <text string="7"><color red="1" green="1" blue="1" /></text>
+ </element>
+ <element name="text_k8">
+ <rect><color red="0.0" green="0.75" blue="1.0" /></rect>
+ <text string="8"><color red="1" green="1" blue="1" /></text>
+ </element>
+ <element name="text_k9">
+ <rect><color red="0.0" green="0.75" blue="1.0" /></rect>
+ <text string="9"><color red="1" green="1" blue="1" /></text>
+ </element>
+ <element name="text_br31">
+ <rect><color red="0.0" green="0.75" blue="1.0" /></rect>
+ <text string="$"><color red="1" green="1" blue="1" /></text>
+ </element>
+ <element name="text_br32">
+ <rect><color red="0.0" green="0.75" blue="1.0" /></rect>
+ <text string="VALUE"><color red="1" green="1" blue="1" /></text>
+ </element>
+ <element name="text_br4">
+ <rect><color red="0.0" green="0.75" blue="1.0" /></rect>
+ <text string="CLEAR"><color red="1" green="1" blue="1" /></text>
+ </element>
+
+ <element name="static_cyan2"><rect><color red="0.6" green="0.85" blue="1.0" /></rect></element>
+ <element name="text_br1">
+ <rect><color red="0.6" green="0.85" blue="1.0" /></rect>
+ <text string="AIR"><color red="0.02" green="0.02" blue="0.02" /></text>
+ </element>
+ <element name="text_br2">
+ <rect><color red="0.6" green="0.85" blue="1.0" /></rect>
+ <text string="UP"><color red="0.02" green="0.02" blue="0.02" /></text>
+ </element>
+
+ <element name="static_gold"><rect><color red="0.8" green="0.6" blue="0.1" /></rect></element>
+ <element name="text_bl1">
+ <rect><color red="0.8" green="0.6" blue="0.1" /></rect>
+ <text string="N-S"><color red="0.02" green="0.02" blue="0.02" /></text>
+ </element>
+ <element name="text_bl2">
+ <rect><color red="0.8" green="0.6" blue="0.1" /></rect>
+ <text string="E-W"><color red="0.02" green="0.02" blue="0.02" /></text>
+ </element>
+
+ <element name="static_silv"><rect><color red="0.45" green="0.45" blue="0.48" /></rect></element>
+ <element name="text_bl3">
+ <rect><color red="0.45" green="0.45" blue="0.48" /></rect>
+ <text string="N-S"><color red="0.98" green="0.98" blue="0.98" /></text>
+ </element>
+ <element name="text_bl4">
+ <rect><color red="0.45" green="0.45" blue="0.48" /></rect>
+ <text string="E-W"><color red="0.98" green="0.98" blue="0.98" /></text>
+ </element>
+
<element name="text_1">
<rect><color red="0.1" green="0.25" blue="0.5" /></rect>
<text string="1"><color red="0.04" green="0.1" blue="0.2" /></text>
@@ -96,6 +189,15 @@
<text string="$$"><color red="0.04" green="0.1" blue="0.2" /></text>
</element>
+ <element name="text_l1">
+ <rect><color red="0.1" green="0.25" blue="0.5" /></rect>
+ <text string="ELECTRONIC"><color red="0.04" green="0.1" blue="0.2" /></text>
+ </element>
+ <element name="text_l2">
+ <rect><color red="0.1" green="0.25" blue="0.5" /></rect>
+ <text string="DIVE-CONTROL CENTER"><color red="0.04" green="0.1" blue="0.2" /></text>
+ </element>
+
<element name="text_n">
<rect><color red="0.0" green="0.75" blue="1.0" /></rect>
<text string="N"><color red="1" green="1" blue="1" /></text>
@@ -117,10 +219,12 @@
<!-- build screen -->
<view name="Internal Layout">
- <bounds left="2.2" right="18.5" top="1" bottom="17.3" />
+ <bounds left="2.2" right="39.2" top="1" bottom="17.3" />
<bezel element="static_blue">
- <bounds left="0" right="20" top="0" bottom="20" />
+ <bounds left="0" right="40" top="0" bottom="18" />
</bezel>
+ <bezel element="static_blue2"><bounds x="-1" y="-1" width="41" height="3.9" /></bezel>
+ <bezel element="static_black"><bounds x="-1" y="-1" width="41" height="3.7" /></bezel>
<!-- left side -->
@@ -152,7 +256,6 @@
<bezel element="static_blue2"><bounds x="3.1" y="10.57" width="0.77" height="0.06" /></bezel>
<bezel element="static_blue2"><bounds x="3.1" y="12.57" width="0.77" height="0.06" /></bezel>
<bezel element="static_blue2"><bounds x="3.1" y="14.57" width="0.77" height="0.06" /></bezel>
- <bezel element="static_blue2"><bounds x="7" y="0" width="0.3" height="20" /></bezel>
<bezel name="0.5" element="led"><bounds x="4" y="4" width="1.2" height="1.2" /></bezel>
<bezel name="0.4" element="led"><bounds x="4" y="6" width="1.2" height="1.2" /></bezel>
@@ -163,8 +266,16 @@
<!-- compass -->
- <bezel element="disk_white"><bounds x="8.1" y="2.1" width="9" height="9" /></bezel>
- <bezel element="disk_cyan"><bounds x="8.5" y="2.5" width="8.2" height="8.2" /></bezel>
+ <bezel element="static_blue2"><bounds x="7.1" y="0" width="11" height="12.1" /></bezel>
+ <bezel element="static_blue"><bounds x="7.3" y="1.2" width="10.6" height="10.7" /></bezel>
+ <bezel element="static_blue2"><bounds x="7.5" y="1.4" width="10.2" height="10.3" /></bezel>
+
+ <bezel element="static_blue2"><bounds x="11.1" y="13.1" width="3" height="0.2" /></bezel>
+ <bezel element="static_blue2"><bounds x="11.1" y="14.3" width="3" height="0.2" /></bezel>
+ <bezel element="static_blue2"><bounds x="11.1" y="15.5" width="3" height="0.2" /></bezel>
+
+ <bezel element="disk_cyan2"><bounds x="8.1" y="2.1" width="9" height="9" /></bezel>
+ <bezel element="disk_cyan1"><bounds x="8.5" y="2.5" width="8.2" height="8.2" /></bezel>
<bezel element="text_n"><bounds x="12" y="2.7" width="1.2" height="1.2" /></bezel>
<bezel element="text_s"><bounds x="12" y="9.3" width="1.2" height="1.2" /></bezel>
@@ -177,5 +288,86 @@
<bezel name="0.9" element="led"><bounds x="14" y="6" width="1.2" height="1.2" /></bezel>
<bezel name="0.10" element="led"><bounds x="12" y="6" width="1.2" height="1.2" /></bezel>
+ <!-- keypad -->
+
+ <bezel element="static_blue2"><bounds x="23.15" y="0" width="11" height="12.1" /></bezel>
+ <bezel element="static_blue"><bounds x="23.35" y="1.2" width="10.6" height="10.7" /></bezel>
+ <bezel element="static_blue2"><bounds x="23.55" y="1.4" width="10.2" height="10.3" /></bezel>
+
+ <bezel element="text_l1"><bounds x="23.15" y="13.1" width="11" height="1.2" /></bezel>
+ <bezel element="text_l2"><bounds x="22.15" y="14.3" width="13" height="1.2" /></bezel>
+
+ <bezel element="static_black2"><bounds x="24.15" y="2.1" width="9" height="9" /></bezel>
+ <bezel element="static_cyan1"><bounds x="24.35" y="2.3" width="2.7333" height="2.7333" /></bezel>
+ <bezel element="static_cyan1"><bounds x="27.28333" y="2.3" width="2.7333" height="2.7333" /></bezel>
+ <bezel element="static_cyan1"><bounds x="30.21666" y="2.3" width="2.7333" height="2.7333" /></bezel>
+ <bezel element="static_cyan1"><bounds x="24.35" y="5.2333" width="2.7333" height="2.7333" /></bezel>
+ <bezel element="static_cyan1"><bounds x="27.28333" y="5.2333" width="2.7333" height="2.7333" /></bezel>
+ <bezel element="static_cyan1"><bounds x="30.21666" y="5.2333" width="2.7333" height="2.7333" /></bezel>
+ <bezel element="static_cyan1"><bounds x="24.35" y="8.1666" width="2.7333" height="2.7333" /></bezel>
+ <bezel element="static_cyan1"><bounds x="27.28333" y="8.1666" width="2.7333" height="2.7333" /></bezel>
+ <bezel element="static_cyan1"><bounds x="30.21666" y="8.1666" width="2.7333" height="2.7333" /></bezel>
+
+ <bezel element="text_k1"><bounds x="24.35" y="3.0666" width="2.7333" height="1.2" /></bezel>
+ <bezel element="text_k2"><bounds x="27.28333" y="3.0666" width="2.7333" height="1.2" /></bezel>
+ <bezel element="text_k3"><bounds x="30.21666" y="3.0666" width="2.7333" height="1.2" /></bezel>
+ <bezel element="text_k4"><bounds x="24.35" y="6" width="2.7333" height="1.2" /></bezel>
+ <bezel element="text_k5"><bounds x="27.28333" y="6" width="2.7333" height="1.2" /></bezel>
+ <bezel element="text_k6"><bounds x="30.21666" y="6" width="2.7333" height="1.2" /></bezel>
+ <bezel element="text_k7"><bounds x="24.35" y="8.9333" width="2.7333" height="1.2" /></bezel>
+ <bezel element="text_k8"><bounds x="27.28333" y="8.9333" width="2.7333" height="1.2" /></bezel>
+ <bezel element="text_k9"><bounds x="30.21666" y="8.9333" width="2.7333" height="1.2" /></bezel>
+
+ <bezel element="hl" inputtag="IN.0" inputmask="0x01"><bounds x="24.35" y="2.3" width="2.7333" height="2.7333" /><color alpha="0.15" /></bezel>
+ <bezel element="hl" inputtag="IN.0" inputmask="0x02"><bounds x="27.28333" y="2.3" width="2.7333" height="2.7333" /><color alpha="0.15" /></bezel>
+ <bezel element="hl" inputtag="IN.0" inputmask="0x04"><bounds x="30.21666" y="2.3" width="2.7333" height="2.7333" /><color alpha="0.15" /></bezel>
+ <bezel element="hl" inputtag="IN.0" inputmask="0x08"><bounds x="24.35" y="5.2333" width="2.7333" height="2.7333" /><color alpha="0.15" /></bezel>
+ <bezel element="hl" inputtag="IN.1" inputmask="0x01"><bounds x="27.28333" y="5.2333" width="2.7333" height="2.7333" /><color alpha="0.15" /></bezel>
+ <bezel element="hl" inputtag="IN.1" inputmask="0x02"><bounds x="30.21666" y="5.2333" width="2.7333" height="2.7333" /><color alpha="0.15" /></bezel>
+ <bezel element="hl" inputtag="IN.1" inputmask="0x04"><bounds x="24.35" y="8.1666" width="2.7333" height="2.7333" /><color alpha="0.15" /></bezel>
+ <bezel element="hl" inputtag="IN.1" inputmask="0x08"><bounds x="27.28333" y="8.1666" width="2.7333" height="2.7333" /><color alpha="0.15" /></bezel>
+ <bezel element="hl" inputtag="IN.2" inputmask="0x01"><bounds x="30.21666" y="8.1666" width="2.7333" height="2.7333" /><color alpha="0.15" /></bezel>
+
+ <!-- other buttons -->
+
+ <bezel element="static_black2"><bounds x="19.1" y="3.8" width="3.05" height="11.6" /></bezel>
+ <bezel element="static_gold"><bounds x="19.3" y="4" width="2.65" height="2.65" /></bezel>
+ <bezel element="static_gold"><bounds x="19.3" y="6.85" width="2.65" height="2.65" /></bezel>
+ <bezel element="static_silv"><bounds x="19.3" y="9.7" width="2.65" height="2.65" /></bezel>
+ <bezel element="static_silv"><bounds x="19.3" y="12.55" width="2.65" height="2.65" /></bezel>
+
+ <bezel element="text_bl1"><bounds x="19.31" y="4.875" width="2.63" height="0.9" /></bezel>
+ <bezel element="text_bl2"><bounds x="19.31" y="7.725" width="2.63" height="0.9" /></bezel>
+ <bezel element="text_bl3"><bounds x="19.31" y="10.575" width="2.63" height="0.9" /></bezel>
+ <bezel element="text_bl4"><bounds x="19.31" y="13.425" width="2.63" height="0.9" /></bezel>
+
+ <bezel element="static_black2"><bounds x="35.15" y="3.8" width="3.05" height="11.6" /></bezel>
+ <bezel element="static_cyan2"><bounds x="35.35" y="4" width="2.65" height="2.65" /></bezel>
+ <bezel element="static_cyan2"><bounds x="35.35" y="6.85" width="2.65" height="2.65" /></bezel>
+ <bezel element="static_cyan1"><bounds x="35.35" y="9.7" width="2.65" height="2.65" /></bezel>
+ <bezel element="static_cyan1"><bounds x="35.35" y="12.55" width="2.65" height="2.65" /></bezel>
+
+ <bezel element="text_br1"><bounds x="35.36" y="4.875" width="2.63" height="0.9" /></bezel>
+ <bezel element="text_br2"><bounds x="35.36" y="7.725" width="2.63" height="0.9" /></bezel>
+ <bezel element="text_br31"><bounds x="35.36" y="10.125" width="2.63" height="0.9" /></bezel>
+ <bezel element="text_br32"><bounds x="35.36" y="11.025" width="2.63" height="0.9" /></bezel>
+ <bezel element="text_br4"><bounds x="35.36" y="13.425" width="2.63" height="0.9" /></bezel>
+
+ <bezel element="hl" inputtag="IN.3" inputmask="0x08"><bounds x="19.3" y="4" width="2.65" height="2.65" /><color alpha="0.15" /></bezel>
+ <bezel element="hl" inputtag="IN.3" inputmask="0x04"><bounds x="19.3" y="6.85" width="2.65" height="2.65" /><color alpha="0.15" /></bezel>
+ <bezel element="hl" inputtag="IN.3" inputmask="0x02"><bounds x="19.3" y="9.7" width="2.65" height="2.65" /><color alpha="0.15" /></bezel>
+ <bezel element="hl" inputtag="IN.3" inputmask="0x01"><bounds x="19.3" y="12.55" width="2.65" height="2.65" /><color alpha="0.15" /></bezel>
+ <bezel element="hl" inputtag="FAKE" inputmask="0x01"><bounds x="35.35" y="4" width="2.65" height="2.65" /><color alpha="0.15" /></bezel>
+ <bezel element="hl" inputtag="FAKE" inputmask="0x02"><bounds x="35.35" y="6.85" width="2.65" height="2.65" /><color alpha="0.15" /></bezel>
+ <bezel element="hl" inputtag="IN.2" inputmask="0x08"><bounds x="35.35" y="9.7" width="2.65" height="2.65" /><color alpha="0.15" /></bezel>
+ <bezel element="hl" inputtag="IN.2" inputmask="0x02"><bounds x="35.35" y="12.55" width="2.65" height="2.65" /><color alpha="0.15" /></bezel>
+
+ <!-- crop borders -->
+
+ <bezel element="static_black"><bounds x="-2" y="-2" width="4.1" height="21" /></bezel>
+ <bezel element="static_black"><bounds x="-2" y="-2" width="43" height="3" /></bezel>
+ <bezel element="static_black"><bounds x="39.3" y="-2" width="4" height="21" /></bezel>
+ <bezel element="static_black"><bounds x="-2" y="17.4" width="43" height="4" /></bezel>
+
</view>
</mamelayout>
diff --git a/src/mame/layout/starwbc.lay b/src/mame/layout/starwbc.lay
index 6469cb7dc9a..faa5e219c6d 100644
--- a/src/mame/layout/starwbc.lay
+++ b/src/mame/layout/starwbc.lay
@@ -4,9 +4,22 @@
<!-- define elements -->
<element name="static_black"><rect><color red="0.0" green="0.0" blue="0.0" /></rect></element>
- <element name="static_yellow"><rect><color red="0.67" green="0.65" blue="0.1" /></rect></element>
- <element name="static_red"><rect><color red="0.6" green="0.05" blue="0.0" /></rect></element>
- <element name="static_gray"><rect><color red="0.66" green="0.66" blue="0.66" /></rect></element>
+ <element name="static_yellow"><rect><color red="0.7" green="0.65" blue="0.05" /></rect></element>
+ <element name="static_green"><rect><color red="0.5" green="0.7" blue="0.05" /></rect></element>
+ <element name="static_red"><rect><color red="0.7" green="0.05" blue="0.1" /></rect></element>
+ <element name="static_blue"><rect><color red="0.05" green="0.5" blue="0.7" /></rect></element>
+ <element name="static_white"><rect><color red="0.7" green="0.7" blue="0.7" /></rect></element>
+
+ <element name="hl" defstate="0">
+ <text string=" ">
+ <bounds x="0" y="0" width="24" height="21" />
+ <color red="0.0" green="0.0" blue="0.0" />
+ </text>
+ <disk state="1">
+ <bounds x="3.5" y="2" width="17" height="17" />
+ <color red="1.0" green="1.0" blue="1.0" />
+ </disk>
+ </element>
<element name="digit" defstate="0">
<led7seg><color red="1.0" green="0.25" blue="0.23" /></led7seg>
@@ -29,27 +42,61 @@
<disk state="0"><color red="0.2" green="0.05" blue="0.04" /></disk>
</element>
- <element name="text_a"><text string="A"><color red="0.69" green="0.69" blue="0.69" /></text></element>
- <element name="text_b"><text string="B"><color red="0.69" green="0.69" blue="0.69" /></text></element>
- <element name="text_c"><text string="C"><color red="0.69" green="0.69" blue="0.69" /></text></element>
- <element name="text_d"><text string="D"><color red="0.69" green="0.69" blue="0.69" /></text></element>
+ <element name="text_a"><text string="A"><color red="0.7" green="0.7" blue="0.7" /></text></element>
+ <element name="text_b"><text string="B"><color red="0.7" green="0.7" blue="0.7" /></text></element>
+ <element name="text_c"><text string="C"><color red="0.7" green="0.7" blue="0.7" /></text></element>
+ <element name="text_d"><text string="D"><color red="0.7" green="0.7" blue="0.7" /></text></element>
+ <element name="text_1"><text string="1"><color red="0.7" green="0.7" blue="0.7" /></text></element>
+ <element name="text_2"><text string="2"><color red="0.7" green="0.7" blue="0.7" /></text></element>
+ <element name="text_3"><text string="3"><color red="0.7" green="0.7" blue="0.7" /></text></element>
+ <element name="text_4"><text string="4"><color red="0.7" green="0.7" blue="0.7" /></text></element>
+
+ <element name="text_alert"><text string="ALERT"><color red="0.7" green="0.7" blue="0.7" /></text></element>
+ <element name="text_combat"><text string="COMBAT"><color red="0.7" green="0.7" blue="0.7" /></text></element>
+ <element name="text_force"><text string="FORCE UNITS"><color red="0.7" green="0.7" blue="0.7" /></text></element>
+ <element name="text_players"><text string="PLAYERS"><color red="0.7" green="0.7" blue="0.7" /></text></element>
+
+ <element name="text_byl">
+ <rect><color red="0.0" green="0.0" blue="0.0" /></rect>
+ <text string="RECONNAISSANCE"><color red="0.7" green="0.7" blue="0.7" /></text>
+ </element>
+ <element name="text_by1"><text string="MAGNA"><color red="0.7" green="0.7" blue="0.7" /></text></element>
+ <element name="text_by2"><text string="ENEMY"><color red="0.7" green="0.7" blue="0.7" /></text></element>
- <element name="text_1"><text string="1"><color red="0.69" green="0.69" blue="0.69" /></text></element>
- <element name="text_2"><text string="2"><color red="0.69" green="0.69" blue="0.69" /></text></element>
- <element name="text_3"><text string="3"><color red="0.69" green="0.69" blue="0.69" /></text></element>
- <element name="text_4"><text string="4"><color red="0.69" green="0.69" blue="0.69" /></text></element>
+ <element name="text_bbl">
+ <rect><color red="0.0" green="0.0" blue="0.0" /></rect>
+ <text string="GAME"><color red="0.7" green="0.7" blue="0.7" /></text>
+ </element>
+ <element name="text_bb1"><text string="BASIC"><color red="0.7" green="0.7" blue="0.7" /></text></element>
+ <element name="text_bb2"><text string="INTER"><color red="0.7" green="0.7" blue="0.7" /></text></element>
+ <element name="text_bb3"><text string="ADV"><color red="0.7" green="0.7" blue="0.7" /></text></element>
+ <element name="text_bb4"><text string="P#"><color red="0.7" green="0.7" blue="0.7" /></text></element>
- <element name="text_alert"><text string="ALERT"><color red="0.69" green="0.69" blue="0.69" /></text></element>
- <element name="text_combat"><text string="COMBAT"><color red="0.69" green="0.69" blue="0.69" /></text></element>
- <element name="text_force"><text string="FORCE UNITS"><color red="0.69" green="0.69" blue="0.69" /></text></element>
- <element name="text_players"><text string="PLAYERS"><color red="0.69" green="0.69" blue="0.69" /></text></element>
+ <element name="text_bgl">
+ <rect><color red="0.0" green="0.0" blue="0.0" /></rect>
+ <text string="TACTICAL REACTION"><color red="0.7" green="0.7" blue="0.7" /></text>
+ </element>
+ <element name="text_bg1"><text string="EM"><color red="0.7" green="0.7" blue="0.7" /></text></element>
+ <element name="text_bg2"><text string="BS"><color red="0.7" green="0.7" blue="0.7" /></text></element>
+ <element name="text_bg3"><text string="SCR"><color red="0.7" green="0.7" blue="0.7" /></text></element>
+ <element name="text_brl">
+ <rect><color red="0.0" green="0.0" blue="0.0" /></rect>
+ <text string="MANEUVERS"><color red="0.7" green="0.7" blue="0.7" /></text>
+ </element>
+ <element name="text_br11"><text string="START"><color red="0.7" green="0.7" blue="0.7" /></text></element>
+ <element name="text_br12"><text string="TURN"><color red="0.7" green="0.7" blue="0.7" /></text></element>
+ <element name="text_br21"><text string="END"><color red="0.7" green="0.7" blue="0.7" /></text></element>
+ <element name="text_br22"><text string="TURN"><color red="0.7" green="0.7" blue="0.7" /></text></element>
+ <element name="text_br3"><text string="MOVE"><color red="0.7" green="0.7" blue="0.7" /></text></element>
+ <element name="text_br4"><text string="FIRE"><color red="0.7" green="0.7" blue="0.7" /></text></element>
+ <element name="text_bra"><text string="-->"><color red="0.7" green="0.7" blue="0.7" /></text></element>
<!-- build screen -->
<view name="Internal Layout">
- <bounds left="0" right="165" top="0" bottom="105" />
+ <bounds left="0" right="165" top="0" bottom="195" />
<bezel element="static_yellow"><bounds x="3" y="17" width="10" height="83" /></bezel>
<bezel element="static_black"><bounds x="4" y="18" width="8" height="81" /></bezel>
@@ -65,20 +112,19 @@
<bezel element="static_red"><bounds x="58" y="3.5" width="1" height="9" /></bezel>
<bezel element="static_red"><bounds x="78" y="3.5" width="1" height="9" /></bezel>
- <bezel element="text_a"><bounds x="4" y="24.5" width="8" height="8" /></bezel>
- <bezel element="text_b"><bounds x="4" y="44.5" width="8" height="8" /></bezel>
- <bezel element="text_c"><bounds x="4" y="64.5" width="8" height="8" /></bezel>
- <bezel element="text_d"><bounds x="4" y="84.5" width="8" height="8" /></bezel>
-
- <bezel element="text_1"><bounds x="24.5" y="4" width="8" height="8" /></bezel>
- <bezel element="text_2"><bounds x="44.5" y="4" width="8" height="8" /></bezel>
- <bezel element="text_3"><bounds x="64.5" y="4" width="8" height="8" /></bezel>
- <bezel element="text_4"><bounds x="84.5" y="4" width="8" height="8" /></bezel>
+ <bezel element="text_a"><bounds x="4" y="25" width="8" height="7" /></bezel>
+ <bezel element="text_b"><bounds x="4" y="45" width="8" height="7" /></bezel>
+ <bezel element="text_c"><bounds x="4" y="65" width="8" height="7" /></bezel>
+ <bezel element="text_d"><bounds x="4" y="85" width="8" height="7" /></bezel>
+ <bezel element="text_1"><bounds x="24.5" y="4.5" width="8" height="7" /></bezel>
+ <bezel element="text_2"><bounds x="44.5" y="4.5" width="8" height="7" /></bezel>
+ <bezel element="text_3"><bounds x="64.5" y="4.5" width="8" height="7" /></bezel>
+ <bezel element="text_4"><bounds x="84.5" y="4.5" width="8" height="7" /></bezel>
<!-- lamp matrix -->
- <bezel element="static_gray"><bounds x="17" y="17" width="83" height="83" /></bezel>
+ <bezel element="static_white"><bounds x="17" y="17" width="83" height="83" /></bezel>
<bezel name="lamp20" element="lamp"><bounds x="20" y="20" width="17" height="17" /></bezel>
<bezel name="lamp21" element="lamp"><bounds x="40" y="20" width="17" height="17" /></bezel>
@@ -100,28 +146,116 @@
<bezel name="lamp46" element="lamp"><bounds x="60" y="80" width="17" height="17" /></bezel>
<bezel name="lamp47" element="lamp"><bounds x="80" y="80" width="17" height="17" /></bezel>
-
<!-- right side -->
- <bezel element="static_gray"><bounds x="105" y="17" width="55" height="23" /></bezel>
+ <bezel element="static_white"><bounds x="105" y="17" width="55" height="23" /></bezel>
<bezel element="static_black"><bounds x="106" y="18" width="53" height="21" /></bezel>
<bezel element="text_alert"><bounds x="106" y="18.5" width="53" height="8" /></bezel>
<bezel name="lamp5" element="nlamp"><bounds x="130.8" y="30.5" width="3.4" height="3.4" /></bezel>
- <bezel element="static_gray"><bounds x="105" y="43" width="55" height="23" /></bezel>
+ <bezel element="static_white"><bounds x="105" y="43" width="55" height="23" /></bezel>
<bezel element="static_black"><bounds x="106" y="44" width="53" height="21" /></bezel>
- <bezel element="text_combat"><bounds x="106" y="44.5" width="53" height="8" /></bezel>
+ <bezel element="text_combat"><bounds x="106" y="45" width="53" height="7" /></bezel>
<bezel name="lamp4" element="nlamp"><bounds x="130.8" y="56.5" width="3.4" height="3.4" /></bezel>
- <bezel element="static_gray"><bounds x="105" y="69" width="55" height="31" /></bezel>
+ <bezel element="static_white"><bounds x="105" y="69" width="55" height="31" /></bezel>
<bezel element="static_black"><bounds x="106" y="70" width="53" height="29" /></bezel>
- <bezel element="text_force"><bounds x="106" y="70.5" width="53" height="8" /></bezel>
- <bezel element="text_players"><bounds x="106" y="90" width="53" height="8" /></bezel>
+ <bezel element="text_force"><bounds x="106" y="71" width="53" height="7" /></bezel>
+ <bezel element="text_players"><bounds x="106" y="90.5" width="53" height="7" /></bezel>
<bezel name="digit6" element="digit"><bounds x="126" y="79.7" width="6" height="9" /></bezel>
<bezel name="digit8" element="digit"><bounds x="132" y="79.7" width="6" height="9" /></bezel>
+ <!-- button panel -->
+
+ <bezel element="static_white"><bounds x="-1" y="105" width="167" height="1" /></bezel>
+
+ <bezel element="static_white"><bounds x="3" y="112" width="50" height="1" /></bezel>
+ <bezel element="text_byl"><bounds x="9.5" y="110" width="37" height="5" /></bezel>
+ <bezel element="static_yellow"><bounds x="3" y="116" width="24" height="21" /></bezel>
+ <bezel element="static_yellow"><bounds x="29" y="116" width="24" height="21" /></bezel>
+
+ <bezel element="static_white"><bounds x="84" y="112" width="76" height="1" /></bezel>
+ <bezel element="text_bgl"><bounds x="100.5" y="110" width="43" height="5" /></bezel>
+ <bezel element="static_green"><bounds x="84" y="116" width="24" height="21" /></bezel>
+ <bezel element="static_green"><bounds x="110" y="116" width="24" height="21" /></bezel>
+ <bezel element="static_green"><bounds x="136" y="116" width="24" height="21" /></bezel>
+
+ <bezel element="static_blue"><bounds x="3" y="142" width="24" height="21" /></bezel>
+ <bezel element="static_blue"><bounds x="29" y="142" width="24" height="21" /></bezel>
+ <bezel element="static_blue"><bounds x="3" y="165" width="24" height="21" /></bezel>
+ <bezel element="static_blue"><bounds x="29" y="165" width="24" height="21" /></bezel>
+ <bezel element="static_white"><bounds x="3" y="189" width="50" height="1" /></bezel>
+ <bezel element="text_bbl"><bounds x="21" y="187" width="14" height="5" /></bezel>
+
+ <bezel element="static_red"><bounds x="58" y="142" width="24" height="21" /></bezel>
+ <bezel element="static_red"><bounds x="84" y="142" width="24" height="21" /></bezel>
+ <bezel element="static_red"><bounds x="110" y="142" width="24" height="21" /></bezel>
+ <bezel element="static_red"><bounds x="136" y="142" width="24" height="21" /></bezel>
+ <bezel element="static_red"><bounds x="58" y="165" width="24" height="21" /></bezel>
+ <bezel element="static_red"><bounds x="84" y="165" width="24" height="21" /></bezel>
+ <bezel element="static_red"><bounds x="110" y="165" width="24" height="21" /></bezel>
+ <bezel element="static_red"><bounds x="136" y="165" width="24" height="21" /></bezel>
+ <bezel element="static_white"><bounds x="58" y="189" width="102" height="1" /></bezel>
+ <bezel element="text_brl"><bounds x="95.5" y="187" width="27" height="5" /></bezel>
+
+ <bezel element="static_black"><bounds x="6" y="119" width="18" height="15" /></bezel>
+ <bezel element="static_black"><bounds x="32" y="119" width="18" height="15" /></bezel>
+ <bezel element="static_black"><bounds x="87" y="119" width="18" height="15" /></bezel>
+ <bezel element="static_black"><bounds x="113" y="119" width="18" height="15" /></bezel>
+ <bezel element="static_black"><bounds x="139" y="119" width="18" height="15" /></bezel>
+ <bezel element="static_black"><bounds x="6" y="145" width="18" height="15" /></bezel>
+ <bezel element="static_black"><bounds x="32" y="145" width="18" height="15" /></bezel>
+ <bezel element="static_black"><bounds x="6" y="168" width="18" height="15" /></bezel>
+ <bezel element="static_black"><bounds x="32" y="168" width="18" height="15" /></bezel>
+ <bezel element="static_black"><bounds x="61" y="145" width="18" height="15" /></bezel>
+ <bezel element="static_black"><bounds x="87" y="145" width="18" height="15" /></bezel>
+ <bezel element="static_black"><bounds x="113" y="145" width="18" height="15" /></bezel>
+ <bezel element="static_black"><bounds x="139" y="145" width="18" height="15" /></bezel>
+ <bezel element="static_black"><bounds x="61" y="168" width="18" height="15" /></bezel>
+ <bezel element="static_black"><bounds x="87" y="168" width="18" height="15" /></bezel>
+ <bezel element="static_black"><bounds x="113" y="168" width="18" height="15" /></bezel>
+ <bezel element="static_black"><bounds x="139" y="168" width="18" height="15" /></bezel>
+
+ <bezel element="text_by1"><bounds x="6" y="124" width="18" height="5" /></bezel>
+ <bezel element="text_by2"><bounds x="32" y="124" width="18" height="5" /></bezel>
+ <bezel element="text_bg1"><bounds x="87" y="124" width="18" height="5" /></bezel>
+ <bezel element="text_bg2"><bounds x="113" y="124" width="18" height="5" /></bezel>
+ <bezel element="text_bg3"><bounds x="139" y="124" width="18" height="5" /></bezel>
+ <bezel element="text_bb1"><bounds x="6" y="150" width="18" height="5" /></bezel>
+ <bezel element="text_bb2"><bounds x="32" y="150" width="18" height="5" /></bezel>
+ <bezel element="text_bb3"><bounds x="6" y="173" width="18" height="5" /></bezel>
+ <bezel element="text_bb4"><bounds x="32" y="173" width="18" height="5" /></bezel>
+ <bezel element="text_br11"><bounds x="61" y="147.5" width="18" height="5" /></bezel>
+ <bezel element="text_br12"><bounds x="61" y="152.5" width="18" height="5" /></bezel>
+ <bezel element="text_br21"><bounds x="87" y="147.5" width="18" height="5" /></bezel>
+ <bezel element="text_br22"><bounds x="87" y="152.5" width="18" height="5" /></bezel>
+ <bezel element="text_br3"><bounds x="113" y="150" width="18" height="5" /></bezel>
+ <bezel element="text_br4"><bounds x="139" y="150" width="18" height="5" /></bezel>
+ <bezel element="text_bra"><bounds x="61" y="173" width="18" height="5" /><orientation rotate="180" /></bezel>
+ <bezel element="text_bra"><bounds x="93.5" y="168" width="5" height="15" /><orientation rotate="270" /></bezel>
+ <bezel element="text_bra"><bounds x="113" y="173" width="18" height="5" /></bezel>
+ <bezel element="text_bra"><bounds x="145.5" y="168" width="5" height="15" /><orientation rotate="90" /></bezel>
+
+ <bezel element="hl" inputtag="IN.2" inputmask="0x01"><bounds x="3" y="116" width="24" height="21" /><color alpha="0.15" /></bezel>
+ <bezel element="hl" inputtag="IN.2" inputmask="0x02"><bounds x="29" y="116" width="24" height="21" /><color alpha="0.15" /></bezel>
+ <bezel element="hl" inputtag="IN.3" inputmask="0x01"><bounds x="84" y="116" width="24" height="21" /><color alpha="0.15" /></bezel>
+ <bezel element="hl" inputtag="IN.3" inputmask="0x08"><bounds x="110" y="116" width="24" height="21" /><color alpha="0.15" /></bezel>
+ <bezel element="hl" inputtag="IN.2" inputmask="0x08"><bounds x="136" y="116" width="24" height="21" /><color alpha="0.15" /></bezel>
+ <bezel element="hl" inputtag="IN.0" inputmask="0x01"><bounds x="3" y="142" width="24" height="21" /><color alpha="0.15" /></bezel>
+ <bezel element="hl" inputtag="IN.0" inputmask="0x02"><bounds x="29" y="142" width="24" height="21" /><color alpha="0.15" /></bezel>
+ <bezel element="hl" inputtag="IN.0" inputmask="0x04"><bounds x="3" y="165" width="24" height="21" /><color alpha="0.15" /></bezel>
+ <bezel element="hl" inputtag="IN.0" inputmask="0x08"><bounds x="29" y="165" width="24" height="21" /><color alpha="0.15" /></bezel>
+ <bezel element="hl" inputtag="IN.1" inputmask="0x01"><bounds x="58" y="142" width="24" height="21" /><color alpha="0.15" /></bezel>
+ <bezel element="hl" inputtag="IN.1" inputmask="0x08"><bounds x="84" y="142" width="24" height="21" /><color alpha="0.15" /></bezel>
+ <bezel element="hl" inputtag="IN.3" inputmask="0x02"><bounds x="110" y="142" width="24" height="21" /><color alpha="0.15" /></bezel>
+ <bezel element="hl" inputtag="IN.3" inputmask="0x04"><bounds x="136" y="142" width="24" height="21" /><color alpha="0.15" /></bezel>
+ <bezel element="hl" inputtag="IN.4" inputmask="0x01"><bounds x="58" y="165" width="24" height="21" /><color alpha="0.15" /></bezel>
+ <bezel element="hl" inputtag="IN.4" inputmask="0x02"><bounds x="84" y="165" width="24" height="21" /><color alpha="0.15" /></bezel>
+ <bezel element="hl" inputtag="IN.4" inputmask="0x08"><bounds x="110" y="165" width="24" height="21" /><color alpha="0.15" /></bezel>
+ <bezel element="hl" inputtag="IN.4" inputmask="0x04"><bounds x="136" y="165" width="24" height="21" /><color alpha="0.15" /></bezel>
+
</view>
</mamelayout>
diff --git a/src/mame/machine/apple3.cpp b/src/mame/machine/apple3.cpp
index 69db605aa36..f24e5f3417b 100644
--- a/src/mame/machine/apple3.cpp
+++ b/src/mame/machine/apple3.cpp
@@ -135,12 +135,16 @@ READ8_MEMBER(apple3_state::apple3_c0xx_r)
case 0x40: case 0x41: case 0x42: case 0x43:
case 0x44: case 0x45: case 0x46: case 0x47:
case 0x48: case 0x49: case 0x4A: case 0x4B:
- case 0x4C: case 0x4D: case 0x4E: case 0x4F:
+ case 0x4C: case 0x4D:
m_c040_time = 200;
break;
+ case 0x4E: case 0x4F: // character RAM enable/disable
+ break;
+
case 0x50: case 0x51: case 0x52: case 0x53:
case 0x54: case 0x55: case 0x56: case 0x57:
+ machine().first_screen()->update_partial(machine().first_screen()->vpos());
/* graphics softswitches */
if (offset & 1)
m_flags |= 1 << ((offset - 0x50) / 2);
@@ -235,8 +239,8 @@ READ8_MEMBER(apple3_state::apple3_c0xx_r)
}
break;
- case 0xD0: case 0xD1: case 0xD2: case 0xD3:
- case 0xD4: case 0xD5: case 0xD6: case 0xD7:
+ case 0xd0: case 0xd1: case 0xd2: case 0xd3:
+ case 0xd4: case 0xd5: case 0xd6: case 0xd7:
/* external drive stuff */
m_fdc->read_c0dx(space, offset&0xf);
result = 0x00;
@@ -246,35 +250,56 @@ READ8_MEMBER(apple3_state::apple3_c0xx_r)
m_smoothscr = offset & 1;
break;
- case 0xDB:
+ case 0xda:
+// printf("ENCWRT off\n");
+ break;
+
+ case 0xdb:
apple3_write_charmem();
+// printf("ENCWRT on (write_charmem (r))\n");
+ break;
+
+ case 0xdc:
+// printf("ENCSEL off\n");
+ break;
+
+ case 0xdd:
+// printf("ENCSEL on\n");
+ break;
+
+ case 0xde:
+// printf("ENSIO off\n");
+ break;
+
+ case 0xdf:
+// printf("ENSIO on\n");
break;
- case 0xE0: case 0xE1:
+ case 0xe0: case 0xe1:
result = m_fdc->read(space, offset&0xf);
m_va = offset & 1;
break;
- case 0xE2: case 0xE3:
+ case 0xe2: case 0xe3:
result = m_fdc->read(space, offset&0xf);
m_vb = offset & 1;
break;
- case 0xE4: case 0xE5:
+ case 0xe4: case 0xe5:
result = m_fdc->read(space, offset&0xf);
m_vc = offset & 1;
break;
- case 0xE6: case 0xE7: case 0xE8: case 0xE9:
- case 0xEA: case 0xEB: case 0xEC: case 0xED:
- case 0xEE: case 0xEF:
+ case 0xe6: case 0xe7: case 0xe8: case 0xe9:
+ case 0xea: case 0xeb: case 0xec: case 0xed:
+ case 0xee: case 0xef:
result = m_fdc->read(space, offset&0xf);
break;
- case 0xF0:
- case 0xF1:
- case 0xF2:
- case 0xF3:
+ case 0xf0:
+ case 0xf1:
+ case 0xf2:
+ case 0xf3:
result = m_acia->read(space, offset & 0x03);
break;
}
@@ -314,12 +339,16 @@ WRITE8_MEMBER(apple3_state::apple3_c0xx_w)
case 0x40: case 0x41: case 0x42: case 0x43:
case 0x44: case 0x45: case 0x46: case 0x47:
case 0x48: case 0x49: case 0x4A: case 0x4B:
- case 0x4C: case 0x4D: case 0x4E: case 0x4F:
+ case 0x4C: case 0x4D:
m_c040_time = 200;
break;
+ case 0x4E: case 0x4F: // character RAM disable/enable
+ break;
+
case 0x50: case 0x51: case 0x52: case 0x53:
case 0x54: case 0x55: case 0x56: case 0x57:
+ machine().first_screen()->update_partial(machine().first_screen()->vpos());
/* graphics softswitches */
if (offset & 1)
m_flags |= 1 << ((offset - 0x50) / 2);
@@ -390,31 +419,52 @@ WRITE8_MEMBER(apple3_state::apple3_c0xx_w)
}
break;
- case 0xD0: case 0xD1: case 0xD2: case 0xD3:
- case 0xD4: case 0xD5: case 0xD6: case 0xD7:
+ case 0xd0: case 0xd1: case 0xd2: case 0xd3:
+ case 0xd4: case 0xd5: case 0xd6: case 0xd7:
/* external drive stuff */
m_fdc->write_c0dx(space, offset&0xf, data);
break;
- case 0xd9:
- popmessage("Smooth scroll enabled, contact MESSdev");
+ case 0xd8: case 0xd9:
+ m_smoothscr = offset & 1;
+ break;
+
+ case 0xda:
+// printf("ENCWRT off\n");
break;
- case 0xDB:
+ case 0xdb:
apple3_write_charmem();
+// printf("ENCWRT on (write_charmem (w))\n");
break;
- case 0xE0: case 0xE1: case 0xE2: case 0xE3:
- case 0xE4: case 0xE5: case 0xE6: case 0xE7:
- case 0xE8: case 0xE9: case 0xEA: case 0xEB:
- case 0xEC: case 0xED: case 0xEE: case 0xEF:
+ case 0xdc:
+// printf("ENCSEL off\n");
+ break;
+
+ case 0xdd:
+// printf("ENCSEL on\n");
+ break;
+
+ case 0xde:
+// printf("ENSIO off\n");
+ break;
+
+ case 0xdf:
+// printf("ENSIO on\n");
+ break;
+
+ case 0xe0: case 0xe1: case 0xe2: case 0xe3:
+ case 0xe4: case 0xe5: case 0xe6: case 0xe7:
+ case 0xe8: case 0xe9: case 0xea: case 0xeb:
+ case 0xec: case 0xed: case 0xee: case 0xef:
m_fdc->write(space, offset&0xf, data);
break;
- case 0xF0:
- case 0xF1:
- case 0xF2:
- case 0xF3:
+ case 0xf0:
+ case 0xf1:
+ case 0xf2:
+ case 0xf3:
m_acia->write(space, offset & 0x03, data);
break;
}
@@ -530,7 +580,6 @@ void apple3_state::apple3_update_memory()
}
else
{
- m_rom_has_been_disabled = true;
m_bank7rd = m_bank7wr;
// if we had an IRQ waiting for RAM to be paged in...
@@ -576,17 +625,6 @@ void apple3_state::apple3_irq_update()
{
if (m_acia_irq || m_via_1_irq || m_via_0_irq)
{
- // HACK: SOS floppy driver enables ROM at Fxxx *before* trying to
- // suppress IRQs. IRQ hits at inopportune time -> bad vector -> system crash.
- // This breaks the Confidence Test, but the Confidence Test
- // never disables the ROM so checking for that gets us
- // working in all cases.
- // Bonus points: for some reason this isn't a problem with -debug.
- // m6502 heisenbug maybe?
- if ((m_via_0_a & ENV_ROMENABLE) && (m_rom_has_been_disabled))
- {
- return;
- }
// printf(" setting IRQ\n");
m_maincpu->set_input_line(M6502_IRQ_LINE, ASSERT_LINE);
m_via_1->write_pa7(0); // this is active low
@@ -630,12 +668,14 @@ MACHINE_RESET_MEMBER(apple3_state,apple3)
m_c040_time = 0;
m_strobe = 0;
m_lastchar = 0x0d;
- m_rom_has_been_disabled = false;
m_cnxx_slot = -1;
m_analog_sel = 0;
m_ramp_active = false;
m_fdc->set_floppies_4(floppy0, floppy1, floppy2, floppy3);
+
+ m_scanstart->adjust(machine().first_screen()->time_until_pos(0, 0));
+ m_scanend->adjust(attotime::never);
}
@@ -702,6 +742,9 @@ DRIVER_INIT_MEMBER(apple3_state,apple3)
m_via_1->write_pb6(1);
m_via_1->write_pb7(1);
+ m_scanstart = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(apple3_state::scanstart_cb),this));
+ m_scanend = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(apple3_state::scanend_cb),this));
+
apple3_update_memory();
save_item(NAME(m_acia_irq));
@@ -714,7 +757,6 @@ DRIVER_INIT_MEMBER(apple3_state,apple3)
save_item(NAME(m_zpa));
save_item(NAME(m_last_n));
save_item(NAME(m_sync));
- save_item(NAME(m_rom_has_been_disabled));
save_item(NAME(m_indir_bank));
save_item(NAME(m_cnxx_slot));
save_item(NAME(m_speaker_state));
@@ -855,7 +897,11 @@ READ8_MEMBER(apple3_state::apple3_memory_r)
}
else
{
- if (offset >= 0xffd0 && offset <= 0xffdf)
+ if (offset >= 0xffc0 && offset <= 0xffcf)
+ {
+ rv = m_bank7wr[offset - 0xf000];
+ }
+ else if (offset >= 0xffd0 && offset <= 0xffdf)
{
rv = m_via_0->read(space, offset);
}
@@ -992,7 +1038,15 @@ WRITE8_MEMBER(apple3_state::apple3_memory_w)
}
else
{
- if (offset >= 0xffd0 && offset <= 0xffdf)
+ if (offset >= 0xffc0 && offset <= 0xffcf)
+ {
+ // does writeprot really apply to ffcx?
+ if (!(m_via_0_a & ENV_WRITEPROT))
+ {
+ m_bank7wr[offset - 0xf000] = data;
+ }
+ }
+ else if (offset >= 0xffd0 && offset <= 0xffdf)
{
if (!space.debugger_access())
{
@@ -1037,6 +1091,27 @@ TIMER_DEVICE_CALLBACK_MEMBER(apple3_state::apple3_c040_tick)
}
}
+TIMER_CALLBACK_MEMBER(apple3_state::scanstart_cb)
+{
+ int scanline;
+
+ scanline = machine().first_screen()->vpos();
+ //machine().first_screen()->update_partial(machine().first_screen()->vpos());
+
+ m_via_1->write_pb6(0);
+
+ m_scanend->adjust(machine().first_screen()->time_until_pos(scanline, 559));
+}
+
+TIMER_CALLBACK_MEMBER(apple3_state::scanend_cb)
+{
+ int scanline = machine().first_screen()->vpos();
+
+ m_via_1->write_pb6(1);
+
+ m_scanstart->adjust(machine().first_screen()->time_until_pos((scanline+1) % 224, 0));
+}
+
READ_LINE_MEMBER(apple3_state::ay3600_shift_r)
{
// either shift key
@@ -1205,7 +1280,7 @@ void apple3_state::pdl_handler(int offset)
break;
case 2:
- pdlread = m_joy1y->read();
+ pdlread = 255 - m_joy1y->read();
break;
case 4:
@@ -1213,7 +1288,7 @@ void apple3_state::pdl_handler(int offset)
break;
case 5:
- pdlread = m_joy2y->read();
+ pdlread = 255 - m_joy2y->read();
break;
default:
@@ -1224,8 +1299,8 @@ void apple3_state::pdl_handler(int offset)
// help the ROM self-test
if (m_pdl_charge > 82)
{
- m_pdl_charge += (pdlread*4);
- m_pdl_charge -= 93;
+ m_pdl_charge += (pdlread*7);
+ m_pdl_charge -= 100;
}
m_pdltimer->adjust(attotime::from_hz(1000000.0));
m_ramp_active = true;
diff --git a/src/mame/machine/cat702.cpp b/src/mame/machine/cat702.cpp
index c02c4394ce1..70c8398befb 100644
--- a/src/mame/machine/cat702.cpp
+++ b/src/mame/machine/cat702.cpp
@@ -90,6 +90,7 @@ const device_type CAT702 = &device_creator<cat702_device>;
cat702_device::cat702_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
device_t(mconfig, CAT702, "CAT702", tag, owner, clock, "cat702", __FILE__),
+ m_transform(nullptr),
m_dataout_handler(*this)
{
}
@@ -159,9 +160,9 @@ void cat702_device::apply_sbox(const UINT8 *sbox)
m_state = r;
}
-void cat702_device::init(const UINT8 *transform)
+void cat702_device::static_set_transform_table(device_t &device, const UINT8 *transform)
{
- m_transform = transform;
+ downcast<cat702_device &>(device).m_transform = transform;
}
WRITE_LINE_MEMBER(cat702_device::write_select)
@@ -214,3 +215,9 @@ WRITE_LINE_MEMBER(cat702_device::write_datain)
{
m_datain = state;
}
+
+void cat702_device::device_validity_check(validity_checker &valid) const
+{
+ if (m_transform == nullptr)
+ osd_printf_error("No transform table provided\n");
+}
diff --git a/src/mame/machine/cat702.h b/src/mame/machine/cat702.h
index 4b93865239f..a116283b1b1 100644
--- a/src/mame/machine/cat702.h
+++ b/src/mame/machine/cat702.h
@@ -14,6 +14,11 @@ extern const device_type CAT702;
#define MCFG_CAT702_DATAOUT_HANDLER(_devcb) \
devcb = &cat702_device::set_dataout_handler(*device, DEVCB_##_devcb);
+#define MCFG_CAT702_TRANSFORM_TABLE(_table) \
+ cat702_device::static_set_transform_table(*device, _table);
+
+class validity_checker;
+
class cat702_device : public device_t
{
public:
@@ -21,8 +26,7 @@ public:
// static configuration helpers
template<class _Object> static devcb_base &set_dataout_handler(device_t &device, _Object object) { return downcast<cat702_device &>(device).m_dataout_handler.set_callback(object); }
-
- void init(const UINT8 *transform); // TODO: region
+ static void static_set_transform_table(device_t &device, const UINT8 *transform); // TODO: region
DECLARE_WRITE_LINE_MEMBER(write_select);
DECLARE_WRITE_LINE_MEMBER(write_datain);
@@ -30,6 +34,7 @@ public:
protected:
virtual void device_start() override;
+ virtual void device_validity_check(validity_checker &valid) const override;
private:
UINT8 compute_sbox_coef(int sel, int bit);
diff --git a/src/mame/machine/fddebug.cpp b/src/mame/machine/fddebug.cpp
index fcb4a46bff8..9cf760337fc 100644
--- a/src/mame/machine/fddebug.cpp
+++ b/src/mame/machine/fddebug.cpp
@@ -591,8 +591,8 @@ static void load_overlay_file(running_machine &machine)
/* determine the filename and open the file */
emu_file file(OPEN_FLAG_READ);
- file_error filerr = file.open(machine.system().name, ".kov");
- if (filerr == FILERR_NONE)
+ osd_file::error filerr = file.open(machine.system().name, ".kov");
+ if (filerr == osd_file::error::NONE)
{
file.read(keystatus, keystatus_words * 2);
@@ -617,8 +617,8 @@ static void save_overlay_file(running_machine &machine)
/* determin the filename and open the file */
emu_file file(OPEN_FLAG_WRITE | OPEN_FLAG_CREATE);
- file_error filerr = file.open(machine.system().name, ".kov");
- if (filerr == FILERR_NONE)
+ osd_file::error filerr = file.open(machine.system().name, ".kov");
+ if (filerr == osd_file::error::NONE)
{
/* convert to big-endian */
for (pcaddr = 0; pcaddr < keystatus_words; pcaddr++)
@@ -760,8 +760,8 @@ static void execute_fdoutput(running_machine &machine, int ref, int params, cons
/* determin the filename and open the file */
emu_file file(OPEN_FLAG_WRITE | OPEN_FLAG_CREATE);
- file_error filerr = file.open(param[0]);
- if (filerr == FILERR_NONE)
+ osd_file::error filerr = file.open(param[0]);
+ if (filerr == osd_file::error::NONE)
file.write(keyregion, KEY_SIZE);
debug_console_printf(machine, "File '%s' saved\n", param[0]);
@@ -1183,8 +1183,8 @@ static void execute_fddasm(running_machine &machine, int ref, int params, const
/* open the file */
emu_file file(OPEN_FLAG_WRITE | OPEN_FLAG_CREATE);
- file_error filerr = file.open(filename);
- if (filerr != FILERR_NONE)
+ osd_file::error filerr = file.open(filename);
+ if (filerr != osd_file::error::NONE)
{
debug_console_printf(machine, "Unable to create file '%s'\n", filename);
return;
diff --git a/src/mame/machine/iteagle_fpga.cpp b/src/mame/machine/iteagle_fpga.cpp
index 40e1a9bb19e..7f4c6218f67 100644
--- a/src/mame/machine/iteagle_fpga.cpp
+++ b/src/mame/machine/iteagle_fpga.cpp
@@ -73,9 +73,11 @@ void iteagle_fpga_device::device_reset()
m_seq_rem1 = 0;
m_seq_rem2 = 0;
+ // Nibble starting at bit 20 is resolution, byte 0 is atmel response
// 0x00080000 and interrupt starts reading from 0x14
// 0x02000000 and interrupt starts reading from 0x18
- m_fpga_regs[0x04/4] = 0x00000000; // Nibble starting at bit 20 is resolution, byte 0 is atmel response
+ // Write 0x01000000 is a global interrupt clear
+ m_fpga_regs[0x04/4] = 0x00000000;
m_prev_reg = 0;
m_serial_str.clear();
@@ -89,6 +91,7 @@ void iteagle_fpga_device::device_reset()
m_serial_com1[0] = 0x2c;
m_serial_com2[0] = 0x2c;
m_serial_com3[0] = 0x2c;
+ m_serial_rx3.clear();
}
void iteagle_fpga_device::update_sequence(UINT32 data)
@@ -144,7 +147,7 @@ void iteagle_fpga_device::update_sequence_eg1(UINT32 data)
m_seq = (m_seq>>9) | ((feed&0x1ff)<<15);
m_fpga_regs[offset] = (m_fpga_regs[offset]&0xFFFFFF00) | ((val1 + m_seq_rem1 + m_seq_rem2) & 0xff);
}
- if (0 && LOG_FPGA)
+ if (0 && LOG_FPGA)
logerror("%s:fpga update_sequence In: %02X Seq: %06X Out: %02X other %02X%02X%02X\n", machine().describe_context(),
data, m_seq, m_fpga_regs[offset]&0xff, m_seq_rem2, m_seq_rem1, val1);
}
@@ -154,7 +157,7 @@ void iteagle_fpga_device::update_sequence_eg1(UINT32 data)
//-------------------------------------------------
void iteagle_fpga_device::device_timer(emu_timer &timer, device_timer_id tid, int param, void *ptr)
{
- if (m_fpga_regs[0x4/4]&0x01000000) {
+ if (m_fpga_regs[0x4/4] & 0x01000000) {
//m_fpga_regs[0x04/4] |= 0x02080000;
m_fpga_regs[0x04/4] |= 0x00080000;
m_cpu->set_input_line(m_irq_num, ASSERT_LINE);
@@ -179,7 +182,6 @@ READ32_MEMBER( iteagle_fpga_device::fpga_r )
if (LOG_FPGA && !ACCESSING_BITS_0_7)
logerror("%s:fpga_r offset %04X = %08X & %08X\n", machine().describe_context(), offset*4, result, mem_mask);
break;
-
case 0x08/4:
result = ((machine().root_device().ioport("TRACKY1")->read()&0xff)<<8) | (machine().root_device().ioport("TRACKX1")->read()&0xff);
if (LOG_FPGA && m_prev_reg!=offset)
@@ -195,7 +197,7 @@ READ32_MEMBER( iteagle_fpga_device::fpga_r )
if (LOG_FPGA)
logerror("%s:fpga_r offset %04X = %08X & %08X\n", machine().describe_context(), offset*4, result, mem_mask);
break;
- case 0x0c/4: // 1d = modem byte
+ case 0x0c/4: //
result = (result & 0xFFFF0000) | ((m_serial_com1[m_serial_idx]&0xff)<<8) | (m_serial_com0[m_serial_idx]&0xff);
if (ACCESSING_BITS_0_15) {
m_serial_data = false;
@@ -210,12 +212,25 @@ READ32_MEMBER( iteagle_fpga_device::fpga_r )
m_serial_data = false;
m_serial_idx = 0;
}
+ if (ACCESSING_BITS_24_31) {
+ if (!m_serial_rx3.empty()) {
+ logerror("fpga_r: read byte: %c\n", m_serial_rx3.at(0));
+ result = (result & 0x00FFFFFF) | (m_serial_rx3.at(0)<<24);
+ m_serial_rx3.erase(m_serial_rx3.begin());
+ }
+ if (m_serial_rx3.empty()) {
+ m_serial_com3[0] &= ~0x1;
+ m_serial_com3[3] &= ~0x20;
+ m_cpu->set_input_line(m_serial_irq_num, CLEAR_LINE);
+ }
+ }
if (LOG_FPGA)
logerror("%s:fpga_r offset %04X = %08X & %08X\n", machine().describe_context(), offset*4, result, mem_mask);
break;
default:
if (LOG_FPGA)
logerror("%s:fpga_r offset %04X = %08X & %08X\n", machine().describe_context(), offset*4, result, mem_mask);
+ osd_printf_debug("%s:fpga_r offset %04X = %08X & %08X\n", machine().describe_context(), offset*4, result, mem_mask);
break;
}
if (offset!=0x4/4)
@@ -236,9 +251,12 @@ WRITE32_MEMBER( iteagle_fpga_device::fpga_w )
update_sequence(data & 0xff);
if (0 && LOG_FPGA)
logerror("%s:fpga_w offset %04X = %08X & %08X\n", machine().describe_context(), offset*4, data, mem_mask);
- }
+ } else if (ACCESSING_BITS_8_15) {
+ // Interrupt enable?
+ if (LOG_FPGA)
+ logerror("%s:fpga_w offset %04X = %08X & %08X\n", machine().describe_context(), offset*4, data, mem_mask);
+ } else if (ACCESSING_BITS_24_31 && (data & 0x01000000)) {
// Interrupt clear/enable
- if (ACCESSING_BITS_24_31 && (data & 0x01000000)) {
m_cpu->set_input_line(m_irq_num, CLEAR_LINE);
// Not sure what value to use here, needed for lightgun
m_timer->adjust(attotime::from_hz(59));
@@ -295,7 +313,7 @@ WRITE32_MEMBER( iteagle_fpga_device::fpga_w )
if (m_serial_str.size()==0)
m_serial_str = "com1: ";
m_serial_str += (data>>24)&0xff;
- if (1 || ((data>>24)&0xff)==0xd) {
+ if (1) {
if (LOG_SERIAL) logerror("%s\n", m_serial_str.c_str());
osd_printf_debug("%s\n", m_serial_str.c_str());
m_serial_str.clear();
@@ -326,7 +344,7 @@ WRITE32_MEMBER( iteagle_fpga_device::fpga_w )
if (m_serial_str.size()==0)
m_serial_str = "com2: ";
m_serial_str += (data>>16)&0xff;
- if (1 || ((data>>16)&0xff)==0xd) {
+ if (1) {
if (LOG_SERIAL) logerror("%s\n", m_serial_str.c_str());
osd_printf_debug("%s\n", m_serial_str.c_str());
m_serial_str.clear();
@@ -339,6 +357,15 @@ WRITE32_MEMBER( iteagle_fpga_device::fpga_w )
if (((data>>24)&0xff)==0xd) {
if (LOG_SERIAL) logerror("%s\n", m_serial_str.c_str());
osd_printf_debug("%s\n", m_serial_str.c_str());
+ if (m_serial_str.find("ATI5") != -1)
+ m_serial_rx3 += "OK\r181\r";
+ else if (m_serial_str.find("ATS0?") != -1)
+ m_serial_rx3 += "0\r";
+ else
+ m_serial_rx3 += "OK\r";
+ m_serial_com3[0] |= 0x1;
+ m_serial_com3[3] = 0x20;
+ m_cpu->set_input_line(m_serial_irq_num, ASSERT_LINE);
m_serial_str.clear();
}
}
@@ -348,6 +375,7 @@ WRITE32_MEMBER( iteagle_fpga_device::fpga_w )
default:
if (LOG_FPGA)
logerror("%s:fpga_w offset %04X = %08X & %08X\n", machine().describe_context(), offset*4, data, mem_mask);
+ osd_printf_debug("%s:fpga_w offset %04X = %08X & %08X\n", machine().describe_context(), offset*4, data, mem_mask);
break;
}
}
@@ -362,7 +390,7 @@ WRITE32_MEMBER( iteagle_fpga_device::fpga_w )
void iteagle_fpga_device::nvram_default()
{
- memset(m_rtc_regs, 0, sizeof(m_rtc_regs));
+ memset(m_rtc_regs, 0x0, sizeof(m_rtc_regs));
}
//-------------------------------------------------
@@ -466,7 +494,8 @@ ADDRESS_MAP_END
// 0x6 = OperID
// 0xe = SW Version
// 0xf = 0x01 for extra courses
-// 0x7f = checksum
+// 0x3e = 0x0002 for good nvram
+// 0x3f = checksum
static const UINT16 iteagle_default_eeprom[0x40] =
{
0xd000,0x0022,0x0000,0x0003,0x1209,0x1111,0x2222,0x1234,
@@ -652,7 +681,7 @@ void iteagle_ide_device::device_reset()
{
pci_device::device_reset();
memset(m_ctrl_regs, 0, sizeof(m_ctrl_regs));
- m_ctrl_regs[0x10/4] = 0x00070000; // 0x6=No SIMM, 0x2, 0x1, 0x0 = SIMM . Top 16 bits are compared to 0x3. Bit 0 might be lan chip present.
+ m_ctrl_regs[0x10/4] = 0x00000000; // 0x6=No SIMM, 0x2, 0x1, 0x0 = SIMM . Top 16 bits are compared to 0x3. Bit 0 might be lan chip present.
memset(m_rtc_regs, 0, sizeof(m_rtc_regs));
m_rtc_regs[0xa] = 0x20; // 32.768 MHz
m_rtc_regs[0xb] = 0x02; // 24-hour format
@@ -667,6 +696,7 @@ READ32_MEMBER( iteagle_ide_device::ctrl_r )
case 0x0/4:
if (LOG_IDE_REG)
logerror("%s:fpga ctrl_r from offset %04X = %08X & %08X\n", machine().describe_context(), offset*4, result, mem_mask);
+ osd_printf_debug("%s:fpga ctrl_r from offset %04X = %08X & %08X\n", machine().describe_context(), offset*4, result, mem_mask);
break;
case 0x70/4:
if (ACCESSING_BITS_8_15) {
@@ -696,6 +726,7 @@ READ32_MEMBER( iteagle_ide_device::ctrl_r )
default:
if (LOG_IDE_REG)
logerror("%s:fpga ctrl_r from offset %04X = %08X & %08X\n", machine().describe_context(), offset*4, result, mem_mask);
+ osd_printf_debug("%s:fpga ctrl_r from offset %04X = %08X & %08X\n", machine().describe_context(), offset*4, result, mem_mask);
break;
}
return result;
@@ -737,7 +768,7 @@ READ32_MEMBER( iteagle_ide_device::ide_r )
if (m_irq_num!=-1 && m_irq_status==1) {
m_irq_status = 0;
m_cpu->set_input_line(m_irq_num, CLEAR_LINE);
- if (LOG_IDE)
+ if (LOG_IDE_CTRL)
logerror("%s:ide_r Clearing interrupt\n", machine().describe_context());
}
}
@@ -752,7 +783,7 @@ WRITE32_MEMBER( iteagle_ide_device::ide_w )
if (m_irq_num!=-1 && m_irq_status==1) {
m_irq_status = 0;
m_cpu->set_input_line(m_irq_num, CLEAR_LINE);
- if (LOG_IDE)
+ if (LOG_IDE_CTRL)
logerror("%s:ide_w Clearing interrupt\n", machine().describe_context());
}
}
diff --git a/src/mame/machine/iteagle_fpga.h b/src/mame/machine/iteagle_fpga.h
index fe5f9a76687..66d2238c2a9 100644
--- a/src/mame/machine/iteagle_fpga.h
+++ b/src/mame/machine/iteagle_fpga.h
@@ -10,15 +10,17 @@
#include "machine/idectrl.h"
#include "machine/eepromser.h"
-#define MCFG_ITEAGLE_FPGA_ADD(_tag, _cpu_tag, _irq_num) \
+//MCFG_PCI_DEVICE_ADD(_tag, _type, _main_id, _revision, _pclass, _subsystem_id)
+
+#define MCFG_ITEAGLE_FPGA_ADD(_tag, _cpu_tag, _irq_num, _serial_irq_num) \
MCFG_PCI_DEVICE_ADD(_tag, ITEAGLE_FPGA, 0x55CC33AA, 0xAA, 0xAAAAAA, 0x00) \
- downcast<iteagle_fpga_device *>(device)->set_irq_info(_cpu_tag, _irq_num);
+ downcast<iteagle_fpga_device *>(device)->set_irq_info(_cpu_tag, _irq_num, _serial_irq_num);
#define MCFG_ITEAGLE_FPGA_INIT(_version, _seq_init) \
downcast<iteagle_fpga_device *>(device)->set_init_info(_version, _seq_init);
#define MCFG_ITEAGLE_EEPROM_ADD(_tag) \
- MCFG_PCI_DEVICE_ADD(_tag, ITEAGLE_EEPROM, 0x80861229, 0x00, 0x088000, 0x00)
+ MCFG_PCI_DEVICE_ADD(_tag, ITEAGLE_EEPROM, 0x80861229, 0x02, 0x020000, 0x00)
#define MCFG_ITEAGLE_EEPROM_INIT(_sw_version, _hw_version) \
downcast<iteagle_eeprom_device *>(device)->set_info(_sw_version, _hw_version);
@@ -36,8 +38,8 @@ class iteagle_fpga_device : public pci_device,
public:
iteagle_fpga_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
void set_init_info(int version, int seq_init) {m_version=version; m_seq_init=seq_init;}
- void set_irq_info(const char *tag, const int irq_num) {m_cpu_tag = tag; m_irq_num = irq_num;}
-
+ void set_irq_info(const char *tag, const int irq_num, const int serial_num) {
+ m_cpu_tag = tag; m_irq_num = irq_num; m_serial_irq_num = serial_num;}
protected:
virtual void device_start() override;
@@ -54,6 +56,7 @@ private:
const char *m_cpu_tag;
cpu_device *m_cpu;
int m_irq_num;
+ int m_serial_irq_num;
UINT32 m_fpga_regs[0x20/4];
UINT32 m_rtc_regs[0x800/4];
@@ -61,6 +64,7 @@ private:
UINT32 m_prev_reg;
std::string m_serial_str;
+ std::string m_serial_rx3;
UINT8 m_serial_idx;
bool m_serial_data;
UINT8 m_serial_com0[0x10];
diff --git a/src/mame/machine/n64.cpp b/src/mame/machine/n64.cpp
index 32ba2ee627e..b7968787d94 100644
--- a/src/mame/machine/n64.cpp
+++ b/src/mame/machine/n64.cpp
@@ -1043,7 +1043,7 @@ READ32_MEMBER( n64_periphs::vi_reg_r )
break;
case 0x10/4: // VI_CURRENT_REG
- ret = (m_screen->vpos() & 0x3FE) + field; // << 1);
+ ret = (m_screen->vpos() & 0x3FE) + field;
break;
case 0x14/4: // VI_BURST_REG
@@ -1742,7 +1742,7 @@ int n64_periphs::pif_channel_handle_command(int channel, int slength, UINT8 *sda
{
// Read EEPROM status
rdata[0] = 0x00;
- rdata[1] = 0x80;
+ rdata[1] = (machine().root_device().ioport("input")->read() >> 8) & 0xC0;
rdata[2] = 0x00;
return 0;
@@ -2127,9 +2127,7 @@ void n64_periphs::pif_dma(int direction)
}
}
si_status |= 1;
- si_dma_timer->adjust(attotime::from_hz(1000));
- //si_status |= 0x1000;
- //signal_rcp_interrupt(SI_INTERRUPT);
+ si_dma_timer->adjust(attotime::from_hz(10000));
}
READ32_MEMBER( n64_periphs::si_reg_r )
@@ -2171,6 +2169,7 @@ WRITE32_MEMBER( n64_periphs::si_reg_w )
case 0x18/4: // SI_STATUS_REG
si_status = 0;
+ si_dma_timer->adjust(attotime::never);
clear_rcp_interrupt(SI_INTERRUPT);
break;
diff --git a/src/mame/machine/xbox.cpp b/src/mame/machine/xbox.cpp
index 2f8de78b4b4..89f17f7371f 100644
--- a/src/mame/machine/xbox.cpp
+++ b/src/mame/machine/xbox.cpp
@@ -833,12 +833,6 @@ void xbox_base_state::usb_ohci_plug(int port, ohci_function_device *function)
}
}
-static USBStandardDeviceDescriptor devdesc = {18,1,0x110,0x00,0x00,0x00,64,0x45e,0x202,0x100,0,0,0,1};
-static USBStandardConfigurationDescriptor condesc = {9,2,0x20,1,1,0,0x80,50};
-static USBStandardInterfaceDescriptor intdesc = {9,4,0,0,2,0x58,0x42,0,0};
-static USBStandardEndpointDescriptor enddesc82 = {7,5,0x82,3,0x20,4};
-static USBStandardEndpointDescriptor enddesc02 = {7,5,0x02,3,0x20,4};
-
ohci_function_device::ohci_function_device(running_machine &machine)
{
state = DefaultState;
@@ -857,16 +851,12 @@ ohci_function_device::ohci_function_device(running_machine &machine)
endpoints[0].type = ControlEndpoint;
settingaddress = false;
configurationvalue = 0;
+ selected_configuration = nullptr;
latest_configuration = nullptr;
latest_alternate = nullptr;
- add_device_descriptor(devdesc);
- add_configuration_descriptor(condesc);
- add_interface_descriptor(intdesc);
- add_endpoint_descriptor(enddesc82);
- add_endpoint_descriptor(enddesc02);
}
-void ohci_function_device::add_device_descriptor(USBStandardDeviceDescriptor &descriptor)
+void ohci_function_device::add_device_descriptor(const USBStandardDeviceDescriptor &descriptor)
{
UINT8 *p = descriptors + descriptors_pos;
@@ -892,7 +882,7 @@ void ohci_function_device::add_device_descriptor(USBStandardDeviceDescriptor &de
memcpy(&device_descriptor, &descriptor, sizeof(USBStandardDeviceDescriptor));
}
-void ohci_function_device::add_configuration_descriptor(USBStandardConfigurationDescriptor &descriptor)
+void ohci_function_device::add_configuration_descriptor(const USBStandardConfigurationDescriptor &descriptor)
{
usb_device_configuration *c = new usb_device_configuration;
UINT8 *p = descriptors + descriptors_pos;
@@ -906,14 +896,16 @@ void ohci_function_device::add_configuration_descriptor(USBStandardConfiguration
p[6] = descriptor.iConfiguration;
p[7] = descriptor.bmAttributes;
p[8] = descriptor.MaxPower;
+ c->position = p;
+ c->size = descriptor.bLength;
descriptors_pos += descriptor.bLength;
memcpy(&c->configuration_descriptor, &descriptor, sizeof(USBStandardConfigurationDescriptor));
- configurations.push_front(*c);
+ configurations.push_front(c);
latest_configuration = c;
latest_alternate = nullptr;
}
-void ohci_function_device::add_interface_descriptor(USBStandardInterfaceDescriptor &descriptor)
+void ohci_function_device::add_interface_descriptor(const USBStandardInterfaceDescriptor &descriptor)
{
usb_device_interface *ii;
usb_device_interface_alternate *aa;
@@ -931,13 +923,18 @@ void ohci_function_device::add_interface_descriptor(USBStandardInterfaceDescript
p[7] = descriptor.bInterfaceProtocol;
p[8] = descriptor.iInterface;
descriptors_pos += descriptor.bLength;
+ latest_configuration->size += descriptor.bLength;
for (auto i = latest_configuration->interfaces.begin(); i != latest_configuration->interfaces.end(); ++i)
{
- if (i->alternate_settings.front().interface_descriptor.bInterfaceNumber == descriptor.bInterfaceNumber)
+ if ((*i)->alternate_settings.front()->interface_descriptor.bInterfaceNumber == descriptor.bInterfaceNumber)
{
+ (*i)->size += descriptor.bLength;
+ latest_configuration->interfaces.front()->size += descriptor.bLength;
aa = new usb_device_interface_alternate;
memcpy(&aa->interface_descriptor, &descriptor, sizeof(USBStandardInterfaceDescriptor));
- i->alternate_settings.push_front(*aa);
+ aa->position = p;
+ aa->size = descriptor.bLength;
+ (*i)->alternate_settings.push_front(aa);
latest_alternate = aa;
return;
}
@@ -945,13 +942,17 @@ void ohci_function_device::add_interface_descriptor(USBStandardInterfaceDescript
ii = new usb_device_interface;
aa = new usb_device_interface_alternate;
memcpy(&aa->interface_descriptor, &descriptor, sizeof(USBStandardInterfaceDescriptor));
+ aa->position = p;
+ aa->size = descriptor.bLength;
+ ii->position = p;
+ ii->size = descriptor.bLength;
ii->selected_alternate = -1;
- ii->alternate_settings.push_front(*aa);
+ ii->alternate_settings.push_front(aa);
latest_alternate = aa;
- latest_configuration->interfaces.push_front(*ii);
+ latest_configuration->interfaces.push_front(ii);
}
-void ohci_function_device::add_endpoint_descriptor(USBStandardEndpointDescriptor &descriptor)
+void ohci_function_device::add_endpoint_descriptor(const USBStandardEndpointDescriptor &descriptor)
{
UINT8 *p = descriptors + descriptors_pos;
@@ -966,6 +967,25 @@ void ohci_function_device::add_endpoint_descriptor(USBStandardEndpointDescriptor
p[6] = descriptor.bInterval;
descriptors_pos += descriptor.bLength;
latest_alternate->endpoint_descriptors.push_front(descriptor);
+ latest_alternate->size += descriptor.bLength;
+ latest_configuration->interfaces.front()->size += descriptor.bLength;
+ latest_configuration->size += descriptor.bLength;
+}
+
+void ohci_function_device::add_string_descriptor(const UINT8 *descriptor)
+{
+ usb_device_string *ss;
+ int len = descriptor[0];
+ UINT8 *p = descriptors + descriptors_pos;
+
+
+ ss = new usb_device_string;
+ memcpy(p, descriptor, len);
+ descriptors_pos += len;
+ ss->size = len;
+ ss->position = p;
+ device_strings.push_front(ss);
+ //latest_configuration->size += len;
}
void ohci_function_device::select_configuration(int index)
@@ -973,52 +993,61 @@ void ohci_function_device::select_configuration(int index)
configurationvalue = index;
for (auto c = configurations.begin(); c != configurations.end(); ++c)
{
- if (c->configuration_descriptor.bConfigurationValue == index)
+ if ((*c)->configuration_descriptor.bConfigurationValue == index)
{
- selected_configuration = &(*c);
- for (auto i = c->interfaces.begin(); i != c->interfaces.end(); ++i)
+ selected_configuration = *c;
+ // by default, activate alternate setting 0 in each interface
+ for (auto i = (*c)->interfaces.begin(); i != (*c)->interfaces.end(); ++i)
{
- i->selected_alternate = 0;
- for (auto a = i->alternate_settings.begin(); a != i->alternate_settings.end(); ++a)
+ (*i)->selected_alternate = 0;
+ for (auto a = (*i)->alternate_settings.begin(); a != (*i)->alternate_settings.end(); ++a)
{
- if (a->interface_descriptor.bAlternateSetting == 0)
+ if ((*a)->interface_descriptor.bAlternateSetting == 0)
{
- for (auto e = a->endpoint_descriptors.begin(); e != a->endpoint_descriptors.end(); ++e)
+ // activate the endpoints in interface i alternate setting 0
+ for (auto e = (*a)->endpoint_descriptors.begin(); e != (*a)->endpoint_descriptors.end(); ++e)
{
endpoints[e->bEndpointAddress].type = e->bmAttributes & 3;
endpoints[e->bEndpointAddress].remain = 0;
}
+ break;
}
}
}
+ break;
}
}
}
void ohci_function_device::select_alternate(int interfacei, int index)
{
+ // among all the interfaces in the currently selected configuration, consider interface interfacei
for (auto i = selected_configuration->interfaces.begin(); i != selected_configuration->interfaces.end(); ++i)
{
- for (auto a = i->alternate_settings.begin(); a != i->alternate_settings.end(); ++a)
+ // deactivate the endpoints in the currently selected alternate setting for interface interfacei
+ for (auto a = (*i)->alternate_settings.begin(); a != (*i)->alternate_settings.end(); ++a)
{
- if ((a->interface_descriptor.bInterfaceNumber == interfacei) && (a->interface_descriptor.bAlternateSetting == i->selected_alternate))
+ if (((*a)->interface_descriptor.bInterfaceNumber == interfacei) && ((*a)->interface_descriptor.bAlternateSetting == (*i)->selected_alternate))
{
- for (auto e = a->endpoint_descriptors.begin(); e != a->endpoint_descriptors.end(); ++e)
+ for (auto e = (*a)->endpoint_descriptors.begin(); e != (*a)->endpoint_descriptors.end(); ++e)
{
endpoints[e->bEndpointAddress].type = -1;
}
+ break;
}
}
- for (auto a = i->alternate_settings.begin(); a != i->alternate_settings.end(); ++a)
+ // activate the endpoints in the newly selected alternate setting
+ for (auto a = (*i)->alternate_settings.begin(); a != (*i)->alternate_settings.end(); ++a)
{
- if ((a->interface_descriptor.bInterfaceNumber == interfacei) && (a->interface_descriptor.bAlternateSetting == index))
+ if (((*a)->interface_descriptor.bInterfaceNumber == interfacei) && ((*a)->interface_descriptor.bAlternateSetting == index))
{
- i->selected_alternate = index;
- for (auto e = a->endpoint_descriptors.begin(); e != a->endpoint_descriptors.end(); ++e)
+ (*i)->selected_alternate = index;
+ for (auto e = (*a)->endpoint_descriptors.begin(); e != (*a)->endpoint_descriptors.end(); ++e)
{
endpoints[e->bEndpointAddress].type = e->bmAttributes & 3;
endpoints[e->bEndpointAddress].remain = 0;
}
+ break;
}
}
}
@@ -1026,19 +1055,57 @@ void ohci_function_device::select_alternate(int interfacei, int index)
int ohci_function_device::find_alternate(int interfacei)
{
+ // find the active alternate setting for interface inteerfacei
for (auto i = selected_configuration->interfaces.begin(); i != selected_configuration->interfaces.end(); ++i)
{
- for (auto a = i->alternate_settings.begin(); a != i->alternate_settings.end(); ++a)
+ for (auto a = (*i)->alternate_settings.begin(); a != (*i)->alternate_settings.end(); ++a)
{
- if (a->interface_descriptor.bInterfaceNumber == interfacei)
+ if ((*a)->interface_descriptor.bInterfaceNumber == interfacei)
{
- return i->selected_alternate;
+ return (*i)->selected_alternate;
}
}
}
return 0;
}
+UINT8 *ohci_function_device::position_device_descriptor(int &size)
+{
+ size = descriptors_pos; // descriptors[0];
+ return descriptors;
+}
+
+UINT8 *ohci_function_device::position_configuration_descriptor(int index, int &size)
+{
+ for (auto c = configurations.begin(); c != configurations.end(); ++c)
+ {
+ if ((*c)->configuration_descriptor.bConfigurationValue == (index + 1))
+ {
+ size = (*c)->size;
+ return (*c)->position;
+ }
+ }
+ size = 0;
+ return nullptr;
+}
+
+UINT8 *ohci_function_device::position_string_descriptor(int index, int &size)
+{
+ int i = 0;
+
+ for (auto s = device_strings.begin(); s != device_strings.end(); ++s)
+ {
+ if (index == i)
+ {
+ size = (*s)->size;
+ return (*s)->position;
+ }
+ i++;
+ }
+ size = 0;
+ return nullptr;
+}
+
void ohci_function_device::execute_reset()
{
address = 0;
@@ -1047,7 +1114,7 @@ void ohci_function_device::execute_reset()
int ohci_function_device::execute_transfer(int address, int endpoint, int pid, UINT8 *buffer, int size)
{
- int descriptortype;// descriptorindex;
+ int descriptortype, descriptorindex;
if (pid == SetupPid) {
USBSetupPacket *p=(USBSetupPacket *)buffer;
@@ -1080,22 +1147,16 @@ int ohci_function_device::execute_transfer(int address, int endpoint, int pid, U
break;
case GET_DESCRIPTOR:
descriptortype = p->wValue >> 8;
- //descriptorindex = p->wValue & 255;
+ descriptorindex = p->wValue & 255;
if (descriptortype == DEVICE) { // device descriptor
- endpoints[endpoint].position = descriptors;
- endpoints[endpoint].remain = descriptors[0];
+ endpoints[endpoint].position = position_device_descriptor(endpoints[endpoint].remain);
}
else if (descriptortype == CONFIGURATION) { // configuration descriptor
- endpoints[endpoint].position = descriptors + 18;
- endpoints[endpoint].remain = descriptors[18 + 2];
- }
- else if (descriptortype == INTERFACE) { // interface descriptor
- endpoints[endpoint].position = descriptors + 18 + 9;
- endpoints[endpoint].remain = descriptors[18 + 9];
+ endpoints[endpoint].position = position_configuration_descriptor(descriptorindex, endpoints[endpoint].remain);
}
- else if (descriptortype == ENDPOINT) { // endpoint descriptor
- endpoints[endpoint].position = descriptors + 18 + 9 + 9;
- endpoints[endpoint].remain = descriptors[18 + 9 + 9];
+ else if (descriptortype == STRING) { // string descriptor
+ //p->wIndex; language id
+ endpoints[endpoint].position = position_string_descriptor(descriptorindex, endpoints[endpoint].remain);
}
else
endpoints[endpoint].remain = 0;
@@ -1196,11 +1257,63 @@ int ohci_function_device::execute_transfer(int address, int endpoint, int pid, U
return size;
}
-int ohci_function_device::handle_nonstandard_request(int endpoint, USBSetupPacket *setup)
+const USBStandardDeviceDescriptor ohci_game_controller_device::devdesc = { 18,1,0x110,0x00,0x00,0x00,64,0x45e,0x202,0x100,0,0,0,1 };
+const USBStandardConfigurationDescriptor ohci_game_controller_device::condesc = { 9,2,0x20,1,1,0,0x80,50 };
+const USBStandardInterfaceDescriptor ohci_game_controller_device::intdesc = { 9,4,0,0,2,0x58,0x42,0,0 };
+const USBStandardEndpointDescriptor ohci_game_controller_device::enddesc82 = { 7,5,0x82,3,0x20,4 };
+const USBStandardEndpointDescriptor ohci_game_controller_device::enddesc02 = { 7,5,0x02,3,0x20,4 };
+
+#if 0
+//ic10
+static USBStandardDeviceDescriptor ohci_hlean2131qc_device::devdesc = { 0x12,0x01,0x0100,0x60,0x00,0x00,0x40,0x0CA3,0x0002,0x0108,0x01,0x02,0x00,0x01 };
+static USBStandardConfigurationDescriptor ohci_hlean2131qc_device::condesc = { 0x09,0x02,0x0058,0x01,0x01,0x00,0x80,0x96 };
+static USBStandardInterfaceDescriptor ohci_hlean2131qc_device::intdesc = { 0x09,0x04,0x00,0x00,0x0A,0xFF,0x00,0x00,0x00 };
+static USBStandardEndpointDescriptor ohci_hlean2131qc_device::enddesc01 = { 0x07,0x05,0x01,0x02,0x0040,0x00 };
+static USBStandardEndpointDescriptor ohci_hlean2131qc_device::enddesc02 = { 0x07,0x05,0x02,0x02,0x0040,0x00 };
+static USBStandardEndpointDescriptor ohci_hlean2131qc_device::enddesc03 = { 0x07,0x05,0x03,0x02,0x0040,0x00 };
+static USBStandardEndpointDescriptor ohci_hlean2131qc_device::enddesc04 = { 0x07,0x05,0x04,0x02,0x0040,0x00 };
+static USBStandardEndpointDescriptor ohci_hlean2131qc_device::enddesc05 = { 0x07,0x05,0x05,0x02,0x0040,0x00 };
+static USBStandardEndpointDescriptor ohci_hlean2131qc_device::enddesc81 = { 0x07,0x05,0x81,0x02,0x0040,0x00 };
+static USBStandardEndpointDescriptor ohci_hlean2131qc_device::enddesc82 = { 0x07,0x05,0x82,0x02,0x0040,0x00 };
+static USBStandardEndpointDescriptor ohci_hlean2131qc_device::enddesc83 = { 0x07,0x05,0x83,0x02,0x0040,0x00 };
+static USBStandardEndpointDescriptor ohci_hlean2131qc_device::enddesc84 = { 0x07,0x05,0x84,0x02,0x0040,0x00 };
+static USBStandardEndpointDescriptor ohci_hlean2131qc_device::enddesc85 = { 0x07,0x05,0x85,0x02,0x0040,0x00 };
+static UINT8 ohci_hlean2131qc_device::strdesc0[] = { 0x04,0x03,0x00,0x00 };
+static UINT8 ohci_hlean2131qc_device::strdesc1[] = { 0x0A,0x03,0x53,0x00,0x45,0x00,0x47,0x00,0x41,0x00 };
+static UINT8 ohci_hlean2131qc_device::strdesc2[] = { 0x0E,0x03,0x42,0x00,0x41,0x00,0x53,0x00,0x45,0x00,0x42,0x03,0xFF,0x0B };
+
+//pc20
+static USBStandardDeviceDescriptor ohci_hlean2131sc_device::devdesc = { 0x12,0x01,0x0100,0x60,0x01,0x00,0x40,0x0CA3,0x0003,0x0110,0x01,0x02,0x00,0x01 };
+static USBStandardConfigurationDescriptor ohci_hlean2131sc_device::condesc = { 0x09,0x02,0x003C,0x01,0x01,0x00,0x80,0x96 };
+static USBStandardInterfaceDescriptor ohci_hlean2131sc_device::intdesc = { 0x09,0x04,0x00,0x00,0x06,0xFF,0x00,0x00,0x00 };
+static USBStandardEndpointDescriptor ohci_hlean2131sc_device::enddesc01 = { 0x07,0x05,0x01,0x02,0x0040,0x00 };
+static USBStandardEndpointDescriptor ohci_hlean2131sc_device::enddesc02 = { 0x07,0x05,0x02,0x02,0x0040,0x00 };
+static USBStandardEndpointDescriptor ohci_hlean2131sc_device::enddesc03 = { 0x07,0x05,0x03,0x02,0x0040,0x00 };
+static USBStandardEndpointDescriptor ohci_hlean2131sc_device::enddesc81 = { 0x07,0x05,0x81,0x02,0x0040,0x00 };
+static USBStandardEndpointDescriptor ohci_hlean2131sc_device::enddesc82 = { 0x07,0x05,0x82,0x02,0x0040,0x00 };
+static USBStandardEndpointDescriptor ohci_hlean2131sc_device::enddesc83 = { 0x07,0x05,0x83,0x02,0x0040,0x00 };
+static UINT8 ohci_hlean2131sc_device::strdesc0[] = { 0x04,0x03,0x00,0x00 };
+static UINT8 ohci_hlean2131sc_device::strdesc1[] = { 0x0A,0x03,0x53,0x00,0x45,0x00,0x47,0x00,0x41,0x00 };
+static UINT8 ohci_hlean2131sc_device::strdesc2[] = { 0x0E,0x03,0x42,0x00,0x41,0x00,0x53,0x00,0x45,0x00,0x42,0x00,0x44,0x00 };
+#endif
+
+ohci_game_controller_device::ohci_game_controller_device(running_machine &machine) :
+ ohci_function_device(machine)
+{
+ add_device_descriptor(devdesc);
+ add_configuration_descriptor(condesc);
+ add_interface_descriptor(intdesc);
+ add_endpoint_descriptor(enddesc82);
+ add_endpoint_descriptor(enddesc02);
+}
+
+int ohci_game_controller_device::handle_nonstandard_request(int endpoint, USBSetupPacket *setup)
{
// >=8 ==42 !=0 !=0 1,3 2<20 <=20
static UINT8 mytestdata[16] = { 0x10,0x42 ,0x32,0x43,1 ,0x65,0x18,0x20,0x98,0xa9,0xba,0xcb,0xdc,0xed,0xfe };
+ if (endpoint != 0)
+ return -1;
if ((endpoints[endpoint].controltype == VendorType) && (endpoints[endpoint].controlrecipient == InterfaceRecipient))
{
if (setup->bRequest == GET_DESCRIPTOR)
@@ -1869,7 +1982,7 @@ ADDRESS_MAP_END
void xbox_base_state::machine_start()
{
#ifdef USB_ENABLED
- ohci_function_device *usb_device;
+ ohci_game_controller_device *usb_device;
#endif
nvidia_nv2a = std::make_unique<nv2a_renderer>(machine());
@@ -1910,7 +2023,7 @@ void xbox_base_state::machine_start()
ohcist.space = &m_maincpu->space();
ohcist.timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(xbox_base_state::usb_ohci_timer), this), (void *)"USB OHCI Timer");
ohcist.timer->enable(false);
- usb_device = new ohci_function_device(machine());
+ usb_device = new ohci_game_controller_device(machine());
usb_ohci_plug(1, usb_device); // test connect
#endif
memset(&superiost, 0, sizeof(superiost));
diff --git a/src/mame/mame.lst b/src/mame/mame.lst
index aa2122e1ae3..44a58025a8e 100644
--- a/src/mame/mame.lst
+++ b/src/mame/mame.lst
@@ -1142,9 +1142,6 @@ amusco // 1987, Amusco.
@source:amust.cpp
amust //
-@source:android.cpp
-androidp // (c) 198? Nasco
-
@source:angelkds.cpp
angelkds // 833-6599 (c) 1988 Sega / Nasco?
spcpostn // (c) 1986 Sega / Nasco"
@@ -8893,6 +8890,7 @@ ccbootmr // Model Racing bootleg
cclimber // (c) 1980 Nichibutsu
cclimberj // (c) 1980 Nichibutsu
cclimbroper // Operamatic bootleg
+cclimbrrod // Rodmar bootleg
ckong // (c) 1981 (Kyoei)
ckongalc // bootleg (Alca)
ckongdks // Spanish Crazy Kong bootleg
@@ -13101,7 +13099,8 @@ chryglda // bootleg
cmast91 // (c) 1991 Dyna Electronics
cmast92 // (c) 1992 Dyna Electronics
cmast97 // (c) 1996 Dyna Electronics
-cmast99 // 1999?
+cmast99 // (c) 1999 Dyna Electronics
+cmast99b // bootleg
cmaster // (c) 1991 Dyna Electronics
cmasterb // (c) 1991 Dyna Electronics
cmasterbv // (c) 1991 Dyna Electronics / Gerald Duhamel?
@@ -13783,6 +13782,7 @@ sgnascar // 2000.09 Nascar Arcade
@source:himesiki.cpp
himesiki // (c) 1989 Hi-Soft
+androidp // (c) 198? Nasco
@source:hitme.cpp
barricad // (c) 1976 Ramtek
@@ -14208,6 +14208,7 @@ iskr1031 //
istellar // (c) 1983 Funai / Gakken
@source:iteagle.cpp
+bbh2sp //
bbhcotw //
bbhsc //
carnking //
@@ -16672,6 +16673,7 @@ trojana // 4/1986 (c) 1986 (US)
trojanb // bootleg
trojanj // 4/1986 (c) 1986 (Japan)
trojanr // 4/1986 (c) 1986 + Romstar
+fball //
@source:lynx.cpp
lynx // Atari Lynx Handheld
@@ -28443,7 +28445,7 @@ ssjkrpkr // (c) 1982 Southern Systems & Assembly, Ltd.
tpoker2 // (c) 1993 Micro Manufacturing, Inc.
@source:notetaker.cpp
-notetakr //
+notetakr //
@source:nova2001.cpp
ninjakun // UPL-84003 (c) 1984 Taito Corporation
@@ -33735,6 +33737,9 @@ swyft //
@source:sym1.cpp
sym1 // Synertek SYM-1
+@source:symbolics.cpp
+s3670 //
+
@source:sys2900.cpp
sys2900 //
@@ -35648,6 +35653,7 @@ videopkr // (c) 1984 InterFlip
@source:vigilant.cpp
buccanrs // (c) 1989 Duintronic
buccanrsa // (c) 1989 Duintronic
+buccanrsb // (c) 1989 Duintronic
kikcubic // (c) 1988 (Japan)
kikcubicb // bootleg
vigilant // (c) 1988 (World Rev E)
diff --git a/src/mame/mess.flt b/src/mame/mess.flt
index 93b0531b119..4c1a841c62a 100644
--- a/src/mame/mess.flt
+++ b/src/mame/mess.flt
@@ -553,6 +553,7 @@ swtpc.cpp
swtpc09.cpp
swyft.cpp
sym1.cpp
+symbolics.cpp
sys2900.cpp
systec.cpp
tamag1.cpp
diff --git a/src/mame/video/angelkds.cpp b/src/mame/video/angelkds.cpp
index 7ddc2da4892..bcb1e13931c 100644
--- a/src/mame/video/angelkds.cpp
+++ b/src/mame/video/angelkds.cpp
@@ -213,22 +213,6 @@ void angelkds_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprec
}
-/*** Palette Handling
-
- 4 bits of Red, 4 bits of Green, 4 bits of Blue
-
-*/
-
-WRITE8_MEMBER(angelkds_state::angelkds_paletteram_w)
-{
- int no;
-
- m_paletteram[offset] = data;
-
- no = offset & 0xff;
- m_palette->set_pen_color(no, pal4bit(m_paletteram[no]), pal4bit(m_paletteram[no]>>4), pal4bit(m_paletteram[no + 0x100]));
-}
-
/*** Video Start & Update
*/
diff --git a/src/mame/video/apple3.cpp b/src/mame/video/apple3.cpp
index 06245b5ef80..0a7e887ee4d 100644
--- a/src/mame/video/apple3.cpp
+++ b/src/mame/video/apple3.cpp
@@ -138,7 +138,7 @@ VIDEO_START_MEMBER(apple3_state,apple3)
-void apple3_state::apple3_video_text40(bitmap_ind16 &bitmap)
+void apple3_state::text40(bitmap_ind16 &bitmap, const rectangle &cliprect)
{
int x, y, col, row, lc;
offs_t offset;
@@ -149,8 +149,10 @@ void apple3_state::apple3_video_text40(bitmap_ind16 &bitmap)
UINT8 *ram = m_ram->pointer();
UINT32 ram_size = m_ram->size();
int smooth = m_va | (m_vb << 1) | (m_vc << 2);
+ int beginrow = (cliprect.min_y - (cliprect.min_y % 8)) / 8;
+ int endrow = (cliprect.max_y - (cliprect.max_y % 8) + 7) / 8;
- for (y = 0; y < 24; y++)
+ for (y = beginrow; y <= endrow; y++)
{
for (x = 0; x < 40; x++)
{
@@ -207,7 +209,7 @@ void apple3_state::apple3_video_text40(bitmap_ind16 &bitmap)
-void apple3_state::apple3_video_text80(bitmap_ind16 &bitmap)
+void apple3_state::text80(bitmap_ind16 &bitmap, const rectangle &cliprect)
{
int x, y, col, row, lc;
offs_t offset;
@@ -218,8 +220,10 @@ void apple3_state::apple3_video_text80(bitmap_ind16 &bitmap)
UINT8 *ram = m_ram->pointer();
UINT32 ram_size = m_ram->size();
int smooth = m_va | (m_vb << 1) | (m_vc << 2);
+ int beginrow = (cliprect.min_y - (cliprect.min_y % 8)) / 8;
+ int endrow = (cliprect.max_y - (cliprect.max_y % 8) + 7) / 8;
- for (y = 0; y < 24; y++)
+ for (y = beginrow; y <= endrow; y++)
{
for (x = 0; x < 40; x++)
{
@@ -270,7 +274,7 @@ void apple3_state::apple3_video_text80(bitmap_ind16 &bitmap)
-void apple3_state::apple3_video_graphics_hgr(bitmap_ind16 &bitmap)
+void apple3_state::graphics_hgr(bitmap_ind16 &bitmap, const rectangle &cliprect)
{
/* hi-res mode: 280x192x2 */
int y, i, x, ly, lyb;
@@ -280,7 +284,7 @@ void apple3_state::apple3_video_graphics_hgr(bitmap_ind16 &bitmap)
UINT8 *ram = m_ram->pointer();
int smooth = m_va | (m_vb << 1) | (m_vc << 2);
- for (y = 0; y < 192; y++)
+ for (y = cliprect.min_y; y <= cliprect.max_y; y++)
{
ly = y;
if (m_smoothscr)
@@ -313,7 +317,7 @@ void apple3_state::apple3_video_graphics_hgr(bitmap_ind16 &bitmap)
}
}
-void apple3_state::apple3_video_graphics_chgr(bitmap_ind16 &bitmap)
+void apple3_state::graphics_chgr(bitmap_ind16 &bitmap, const rectangle &cliprect)
{
/* color hi-res mode: 280x192x16 */
int y, i, x, ly, lyb;
@@ -325,7 +329,7 @@ void apple3_state::apple3_video_graphics_chgr(bitmap_ind16 &bitmap)
UINT8 *ram = m_ram->pointer();
int smooth = m_va | (m_vb << 1) | (m_vc << 2);
- for (y = 0; y < 192; y++)
+ for (y = cliprect.min_y; y <= cliprect.max_y; y++)
{
ly = y;
if (m_smoothscr)
@@ -371,7 +375,7 @@ void apple3_state::apple3_video_graphics_chgr(bitmap_ind16 &bitmap)
-void apple3_state::apple3_video_graphics_shgr(bitmap_ind16 &bitmap)
+void apple3_state::graphics_shgr(bitmap_ind16 &bitmap, const rectangle &cliprect)
{
/* super hi-res mode: 560x192x2 */
int y, i, x, ly, lyb;
@@ -382,7 +386,7 @@ void apple3_state::apple3_video_graphics_shgr(bitmap_ind16 &bitmap)
UINT8 *ram = m_ram->pointer();
int smooth = m_va | (m_vb << 1) | (m_vc << 2);
- for (y = 0; y < 192; y++)
+ for (y = cliprect.min_y; y <= cliprect.max_y; y++)
{
ly = y;
if (m_smoothscr)
@@ -429,7 +433,7 @@ void apple3_state::apple3_video_graphics_shgr(bitmap_ind16 &bitmap)
-void apple3_state::apple3_video_graphics_chires(bitmap_ind16 &bitmap)
+void apple3_state::graphics_chires(bitmap_ind16 &bitmap, const rectangle &cliprect)
{
UINT16 *pen;
UINT8 p1, p2, p3, p4;
@@ -437,7 +441,7 @@ void apple3_state::apple3_video_graphics_chires(bitmap_ind16 &bitmap)
UINT8 *ram = m_ram->pointer();
int smooth = m_va | (m_vb << 1) | (m_vc << 2);
- for (y = 0; y < 192; y++)
+ for (y = cliprect.min_y; y <= cliprect.max_y; y++)
{
ly = y;
if (m_smoothscr)
@@ -484,34 +488,34 @@ void apple3_state::apple3_video_graphics_chires(bitmap_ind16 &bitmap)
UINT32 apple3_state::screen_update_apple3(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
-// printf("gfx mode %x\n", m_flags & (VAR_VM3|VAR_VM1|VAR_VM0));
+// printf("gfx mode %x\n", m_flags & (VAR_VM3|VAR_VM1|VAR_VM0));
switch(m_flags & (VAR_VM3|VAR_VM1|VAR_VM0))
{
case 0:
case VAR_VM0:
- apple3_video_text40(bitmap);
+ text40(bitmap, cliprect); // 1
break;
- case VAR_VM1:
- case VAR_VM1|VAR_VM0:
- apple3_video_text80(bitmap);
+ case VAR_VM1: // 2
+ case VAR_VM1|VAR_VM0: // 3
+ text80(bitmap, cliprect);
break;
- case VAR_VM3:
- apple3_video_graphics_hgr(bitmap); /* hgr mode */
+ case VAR_VM3: // 8
+ graphics_hgr(bitmap, cliprect); /* hgr mode */
break;
- case VAR_VM3|VAR_VM0:
- apple3_video_graphics_chgr(bitmap);
+ case VAR_VM3|VAR_VM0: // 9
+ graphics_chgr(bitmap, cliprect);
break;
- case VAR_VM3|VAR_VM1:
- apple3_video_graphics_shgr(bitmap);
+ case VAR_VM3|VAR_VM1: // a
+ graphics_shgr(bitmap, cliprect);
break;
- case VAR_VM3|VAR_VM1|VAR_VM0:
- apple3_video_graphics_chires(bitmap);
+ case VAR_VM3|VAR_VM1|VAR_VM0: // b
+ graphics_chires(bitmap, cliprect);
break;
}
return 0;
diff --git a/src/mame/video/atarirle.cpp b/src/mame/video/atarirle.cpp
index 6a433d4666c..05a3fe4737d 100644
--- a/src/mame/video/atarirle.cpp
+++ b/src/mame/video/atarirle.cpp
@@ -191,7 +191,7 @@ void atari_rle_objects_device::device_start()
// resolve our memory
memory_share *share = owner()->memshare(tag());
if (share == nullptr)
- throw emu_fatalerror("Error: unable to find memory share '%s' needed for Atari RLE device", tag());
+ throw emu_fatalerror("Unable to find memory share '%s' needed for Atari RLE device", tag());
m_ram.set(*share, 2);
// register a VBLANK callback
diff --git a/src/mame/video/himesiki.cpp b/src/mame/video/himesiki.cpp
index d41f38ae49f..4d82c84e6ec 100644
--- a/src/mame/video/himesiki.cpp
+++ b/src/mame/video/himesiki.cpp
@@ -38,21 +38,19 @@ WRITE8_MEMBER(himesiki_state::himesiki_scrollx_w)
m_scrollx[offset] = data;
}
-WRITE8_MEMBER(himesiki_state::himesiki_flip_w)
+WRITE8_MEMBER(himesiki_state::himesiki_scrolly_w)
{
- m_flipscreen = data & 0xc0;
- flip_screen_set(m_flipscreen);
-
- if (data & 0x3f)
- logerror("p08_w %02x\n",data);
+ m_scrolly = data;
}
void himesiki_state::himesiki_draw_sprites( bitmap_ind16 &bitmap, const rectangle &cliprect )
{
- UINT8 *spriteram = m_spriteram;
+ UINT8 *spriteram;
int offs;
- for (offs = 0x100; offs < 0x160; offs += 4)
+ // these sprites are from the ET-P103A board (himesiki only)
+ spriteram = m_spriteram_p103a;
+ for (offs = 0x00; offs < 0x60; offs += 4)
{
int attr = spriteram[offs + 1];
int code = spriteram[offs + 0] | (attr & 3) << 8;
@@ -68,7 +66,7 @@ void himesiki_state::himesiki_draw_sprites( bitmap_ind16 &bitmap, const rectangl
if (m_flipscreen)
{
- y = (y + 33) & 0xff;
+ y = (y - 31) & 0xff;
x = 224 - x;
fx ^= 4;
fy = 1;
@@ -80,11 +78,20 @@ void himesiki_state::himesiki_draw_sprites( bitmap_ind16 &bitmap, const rectangl
y -= 0x100;
}
- m_gfxdecode->gfx(1)->transpen(bitmap,cliprect, code, col, fx, fy, x, y, 15);
+ m_gfxdecode->gfx(2)->transpen(bitmap,cliprect, code, col, fx, fy, x, y, 15);
}
+ // 0xc0 - 0xff unused
+ spriteram = m_spriteram;
for (offs = 0; offs < 0x100; offs += 4)
{
+ // not sure about this, but you sometimes get a garbage sprite in the corner otherwise.
+ if ((spriteram[offs + 0] == 0x00) &&
+ (spriteram[offs + 1] == 0x00) &&
+ (spriteram[offs + 2] == 0x00) &&
+ (spriteram[offs + 3] == 0x00))
+ continue;
+
int attr = spriteram[offs + 1];
int code = spriteram[offs + 0] | (attr & 7) << 8;
int x = spriteram[offs + 3] | (attr & 8) << 5;
@@ -98,7 +105,7 @@ void himesiki_state::himesiki_draw_sprites( bitmap_ind16 &bitmap, const rectangl
if (m_flipscreen)
{
- y += 49;
+ y = (y - 15) &0xff;
x = 240 - x;
f = 1;
}
@@ -109,7 +116,7 @@ void himesiki_state::himesiki_draw_sprites( bitmap_ind16 &bitmap, const rectangl
if (y > 0xf0)
y -= 0x100;
- m_gfxdecode->gfx(2)->transpen(bitmap,cliprect, code, col, f, f, x, y, 15);
+ m_gfxdecode->gfx(1)->transpen(bitmap,cliprect, code, col, f, f, x, y, 15);
}
}
@@ -117,6 +124,7 @@ UINT32 himesiki_state::screen_update_himesiki(screen_device &screen, bitmap_ind1
{
int x = -(m_scrollx[0] << 8 | m_scrollx[1]) & 0x1ff;
m_bg_tilemap->set_scrolldx(x, x);
+ m_bg_tilemap->set_scrolldy(-m_scrolly, -m_scrolly-64);
m_bg_tilemap->draw(screen, bitmap, cliprect, TILEMAP_DRAW_OPAQUE, 0);
himesiki_draw_sprites(bitmap, cliprect);
diff --git a/src/mame/video/lwings.cpp b/src/mame/video/lwings.cpp
index 0a06822b9f9..05416b83a5e 100644
--- a/src/mame/video/lwings.cpp
+++ b/src/mame/video/lwings.cpp
@@ -204,7 +204,7 @@ void lwings_state::lwings_draw_sprites( bitmap_ind16 &bitmap, const rectangle &c
}
m_gfxdecode->gfx(2)->transpen(bitmap,cliprect,
- code,color,
+ code+(m_sprbank*0x400),color,
flipx,flipy,
sx,sy,15);
}
diff --git a/src/osd/modules/file/posixfile.cpp b/src/osd/modules/file/posixfile.cpp
new file mode 100644
index 00000000000..a5e3fe6a54e
--- /dev/null
+++ b/src/osd/modules/file/posixfile.cpp
@@ -0,0 +1,483 @@
+// license:BSD-3-Clause
+// copyright-holders:Olivier Galibert, R. Belmont, Vas Crabb
+//============================================================
+//
+// sdlfile.c - SDL file access functions
+//
+// SDLMAME by Olivier Galibert and R. Belmont
+//
+//============================================================
+
+
+#ifndef _LARGEFILE64_SOURCE
+#define _LARGEFILE64_SOURCE
+#endif
+
+#ifdef __linux__
+#define __USE_LARGEFILE64
+#endif
+
+#ifdef WIN32
+#define _FILE_OFFSET_BITS 64
+#endif
+
+#if !defined(__FreeBSD__) && !defined(__NetBSD__) && !defined(__OpenBSD__) && !defined(__bsdi__) && !defined(__DragonFly__)
+#ifdef _XOPEN_SOURCE
+#if _XOPEN_SOURCE < 500
+#undef _XOPEN_SOURCE
+#endif
+#endif
+#ifndef _XOPEN_SOURCE
+#define _XOPEN_SOURCE 500
+#endif
+#endif
+
+// MAME headers
+#include "posixfile.h"
+
+#include <cassert>
+#include <cerrno>
+#include <cstring>
+#include <memory>
+#include <type_traits>
+#include <vector>
+
+#include <fcntl.h>
+#include <limits.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+
+
+namespace {
+
+//============================================================
+// CONSTANTS
+//============================================================
+
+#if defined(WIN32)
+constexpr char PATHSEPCH = '\\';
+constexpr char INVPATHSEPCH = '/';
+#else
+constexpr char PATHSEPCH = '/';
+constexpr char INVPATHSEPCH = '\\';
+#endif
+
+
+
+class posix_osd_file : public osd_file
+{
+public:
+ posix_osd_file(posix_osd_file const &) = delete;
+ posix_osd_file(posix_osd_file &&) = delete;
+ posix_osd_file& operator=(posix_osd_file const &) = delete;
+ posix_osd_file& operator=(posix_osd_file &&) = delete;
+
+ posix_osd_file(int fd) : m_fd(fd)
+ {
+ assert(m_fd >= 0);
+ }
+
+ virtual ~posix_osd_file() override
+ {
+ ::close(m_fd);
+ }
+
+ virtual error read(void *buffer, std::uint64_t offset, std::uint32_t count, std::uint32_t &actual) override
+ {
+ ssize_t result;
+
+#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__bsdi__) || defined(__DragonFly__) || defined(EMSCRIPTEN)
+ result = ::pread(m_fd, buffer, size_t(count), off_t(std::make_unsigned_t<off_t>(offset)));
+#elif defined(WIN32) || defined(SDLMAME_NO64BITIO)
+ if (lseek(m_fd, off_t(std::make_unsigned_t<off_t>(offset)), SEEK_SET) < 0)
+ return errno_to_file_error(errno)
+ result = ::read(m_fd, buffer, size_t(count));
+#else
+ result = ::pread64(m_fd, buffer, size_t(count), off64_t(offset));
+#endif
+
+ if (result < 0)
+ return errno_to_file_error(errno);
+
+ actual = std::uint32_t(std::size_t(result));
+ return error::NONE;
+ }
+
+ virtual error write(void const *buffer, std::uint64_t offset, std::uint32_t count, std::uint32_t &actual) override
+ {
+ ssize_t result;
+
+#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__bsdi__) || defined(__DragonFly__) || defined(EMSCRIPTEN)
+ result = ::pwrite(m_fd, buffer, size_t(count), off_t(std::make_unsigned_t<off_t>(offset)));
+#elif defined(WIN32) || defined(SDLMAME_NO64BITIO)
+ if (lseek(m_fd, off_t(std::make_unsigned_t<off_t>(offset)), SEEK_SET) < 0)
+ return errno_to_file_error(errno)
+ result = ::write(m_fd, buffer, size_t(count));
+#else
+ result = ::pwrite64(m_fd, buffer, size_t(count), off64_t(offset));
+#endif
+
+ if (result < 0)
+ return errno_to_file_error(errno);
+
+ actual = std::uint32_t(std::size_t(result));
+ return error::NONE;
+ }
+
+ virtual error truncate(std::uint64_t offset) override
+ {
+ int result;
+
+#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__bsdi__) || defined(__DragonFly__) || defined(EMSCRIPTEN) || defined(WIN32) || defined(SDLMAME_NO64BITIO)
+ result = ::ftruncate(m_fd, off_t(std::make_unsigned_t<off_t>(offset)));
+#else
+ result = ::ftruncate64(m_fd, off64_t(offset));
+#endif
+
+ if (result < 0)
+ return errno_to_file_error(errno);
+
+ return error::NONE;
+ }
+
+ virtual error flush() override
+ {
+ // no user-space buffering on unistd I/O
+ return error::NONE;
+ }
+
+private:
+ int m_fd;
+};
+
+
+//============================================================
+// is_path_separator
+//============================================================
+
+bool is_path_separator(char c)
+{
+ return (c == PATHSEPCH) || (c == INVPATHSEPCH);
+}
+
+
+//============================================================
+// create_path_recursive
+//============================================================
+
+osd_file::error create_path_recursive(std::string const &path)
+{
+ // if there's still a separator, and it's not the root, nuke it and recurse
+ auto const sep = path.rfind(PATHSEPCH);
+ if ((sep != std::string::npos) && (sep > 0) && (path[sep] != ':') && (path[sep - 1] != PATHSEPCH))
+ {
+ osd_file::error const err = create_path_recursive(path.substr(0, sep));
+ if (err != osd_file::error::NONE)
+ return err;
+ }
+
+ // if the path already exists, we're done
+ struct stat st;
+ if (!::stat(path.c_str(), &st))
+ return osd_file::error::NONE;
+
+ // create the path
+#ifdef WIN32
+ if (mkdir(path.c_str()) < 0)
+#else
+ if (mkdir(path.c_str(), 0777) < 0)
+#endif
+ return errno_to_file_error(errno);
+ else
+ return osd_file::error::NONE;
+}
+
+} // anonymous namespace
+
+
+//============================================================
+// osd_file::open
+//============================================================
+
+osd_file::error osd_file::open(std::string const &path, std::uint32_t openflags, ptr &file, std::uint64_t &filesize)
+{
+ std::string dst;
+ if (posix_check_socket_path(path))
+ return posix_open_socket(path, openflags, file, filesize);
+ else if (posix_check_ptty_path(path))
+ return posix_open_ptty(openflags, file, filesize, dst);
+
+ // select the file open modes
+ int access;
+ if (openflags & OPEN_FLAG_WRITE)
+ {
+ access = (openflags & OPEN_FLAG_READ) ? O_RDWR : O_WRONLY;
+ access |= (openflags & OPEN_FLAG_CREATE) ? (O_CREAT | O_TRUNC) : 0;
+ }
+ else if (openflags & OPEN_FLAG_READ)
+ {
+ access = O_RDONLY;
+ }
+ else
+ {
+ return error::INVALID_ACCESS;
+ }
+#if defined(WIN32)
+ access |= O_BINARY;
+#endif
+
+ // convert the path into something compatible
+ dst = path;
+ for (auto it = dst.begin(); it != dst.end(); ++it)
+ *it = (INVPATHSEPCH == *it) ? PATHSEPCH : *it;
+ osd_subst_env(dst, dst);
+
+ // attempt to open the file
+ int fd = -1;
+#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__bsdi__) || defined(__DragonFly__) || defined(__HAIKU__) || defined(WIN32) || defined(SDLMAME_NO64BITIO)
+ fd = ::open(dst.c_str(), access, 0666);
+#else
+ fd = ::open64(dst.c_str(), access, 0666);
+#endif
+
+ if (fd < 0)
+ {
+ // create the path if necessary
+ if ((openflags & OPEN_FLAG_CREATE) && (openflags & OPEN_FLAG_CREATE_PATHS))
+ {
+ auto const pathsep = dst.rfind(PATHSEPCH);
+ if (pathsep != std::string::npos)
+ {
+ // create the path up to the file
+ osd_file::error const error = create_path_recursive(dst.substr(0, pathsep));
+
+ // attempt to reopen the file
+ if (error == osd_file::error::NONE)
+ {
+#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__bsdi__) || defined(__DragonFly__) || defined(__HAIKU__) || defined(WIN32) || defined(SDLMAME_NO64BITIO)
+ fd = ::open(dst.c_str(), access, 0666);
+#else
+ fd = ::open64(dst.c_str(), access, 0666);
+#endif
+ }
+ }
+ }
+
+ // if we still failed, clean up and osd_free
+ if (fd < 0)
+ {
+ return errno_to_file_error(errno);
+ }
+ }
+
+ // get the file size
+#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__bsdi__) || defined(__DragonFly__) || defined(__HAIKU__) || defined(WIN32) || defined(SDLMAME_NO64BITIO)
+ struct stat st;
+ if (::fstat(fd, &st) < 0)
+#else
+ struct stat64 st;
+ if (::fstat64(fd, &st) < 0)
+#endif
+ {
+ int const error = errno;
+ ::close(fd);
+ return errno_to_file_error(error);
+ }
+ filesize = std::uint64_t(std::make_unsigned_t<decltype(st.st_size)>(st.st_size));
+
+ try
+ {
+ file = std::make_unique<posix_osd_file>(fd);
+ return error::NONE;
+ }
+ catch (...)
+ {
+ ::close(fd);
+ return error::OUT_OF_MEMORY;
+ }
+}
+
+
+//============================================================
+// osd_file::openpty
+//============================================================
+
+osd_file::error osd_file::openpty(ptr &file, std::string &name)
+{
+ std::uint64_t filesize;
+ return posix_open_ptty(OPEN_FLAG_READ | OPEN_FLAG_WRITE, file, filesize, name);
+}
+
+
+//============================================================
+// osd_file::remove
+//============================================================
+
+osd_file::error osd_file::remove(std::string const &filename)
+{
+ if (::unlink(filename.c_str()) < -1)
+ return errno_to_file_error(errno);
+ else
+ return error::NONE;
+}
+
+
+//============================================================
+// osd_get_physical_drive_geometry
+//============================================================
+
+int osd_get_physical_drive_geometry(const char *filename, UINT32 *cylinders, UINT32 *heads, UINT32 *sectors, UINT32 *bps)
+{
+ return FALSE; // no, no way, huh-uh, forget it
+}
+
+
+//============================================================
+// osd_stat
+//============================================================
+
+osd_directory_entry *osd_stat(const std::string &path)
+{
+#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__bsdi__) || defined(__DragonFly__) || defined(__HAIKU__) || defined(WIN32) || defined(SDLMAME_NO64BITIO)
+ struct stat st;
+ int const err = ::stat(path.c_str(), &st);
+#else
+ struct stat64 st;
+ int const err = ::stat64(path.c_str(), &st);
+#endif
+ if (err < 0) return nullptr;
+
+ // create an osd_directory_entry; be sure to make sure that the caller can
+ // free all resources by just freeing the resulting osd_directory_entry
+ osd_directory_entry *const result = reinterpret_cast<osd_directory_entry *>(osd_malloc_array(sizeof(osd_directory_entry) + path.length() + 1));
+ std::strcpy(reinterpret_cast<char *>(result) + sizeof(*result), path.c_str());
+ result->name = reinterpret_cast<char *>(result) + sizeof(*result);
+ result->type = S_ISDIR(st.st_mode) ? ENTTYPE_DIR : ENTTYPE_FILE;
+ result->size = std::uint64_t(std::make_unsigned_t<decltype(st.st_size)>(st.st_size));
+
+ return result;
+}
+
+
+//============================================================
+// osd_get_full_path
+//============================================================
+
+osd_file::error osd_get_full_path(std::string &dst, std::string const &path)
+{
+ try
+ {
+#if defined(WIN32)
+ std::vector<char> path_buffer(MAX_PATH);
+ if (::_fullpath(&path_buffer[0], path.c_str(), MAX_PATH))
+ {
+ dst = &path_buffer[0];
+ return osd_file::error::NONE;
+ }
+ else
+ {
+ return osd_file::error::FAILURE;
+ }
+#else
+ std::vector<char> path_buffer(PATH_MAX);
+ if (::realpath(path.c_str(), &path_buffer[0]))
+ {
+ dst = &path_buffer[0];
+ return osd_file::error::NONE;
+ }
+ else if (path[0] == PATHSEPCH)
+ {
+ dst = path;
+ return osd_file::error::NONE;
+ }
+ else
+ {
+ while (!::getcwd(&path_buffer[0], path_buffer.size()))
+ {
+ if (errno != ERANGE)
+ return errno_to_file_error(errno);
+ else
+ path_buffer.resize(path_buffer.size() * 2);
+ }
+ dst.assign(&path_buffer[0]).push_back(PATHSEPCH);
+ dst.append(path);
+ return osd_file::error::NONE;
+ }
+#endif
+ }
+ catch (...)
+ {
+ return osd_file::error::OUT_OF_MEMORY;
+ }
+}
+
+
+//============================================================
+// osd_is_absolute_path
+//============================================================
+
+bool osd_is_absolute_path(std::string const &path)
+{
+ if (!path.empty() && is_path_separator(path[0]))
+ return true;
+#if !defined(WIN32)
+ else if (!path.empty() && (path[0] == '.'))
+ return true;
+#elif !defined(UNDER_CE)
+ else if ((path.length() > 1) && (path[1] == ':'))
+ return true;
+#endif
+ else
+ return false;
+}
+
+
+//============================================================
+// osd_get_volume_name
+//============================================================
+
+const char *osd_get_volume_name(int idx)
+{
+ if (idx == 0)
+ return "/";
+ else
+ return nullptr;
+ }
+
+
+//============================================================
+// errno_to_file_error
+//============================================================
+
+osd_file::error errno_to_file_error(int error)
+{
+ switch (error)
+ {
+ case 0:
+ return osd_file::error::NONE;
+
+ case ENOENT:
+ case ENOTDIR:
+ return osd_file::error::NOT_FOUND;
+
+ case EACCES:
+ case EROFS:
+#ifndef WIN32
+ case ETXTBSY:
+#endif
+ case EEXIST:
+ case EPERM:
+ case EISDIR:
+ case EINVAL:
+ return osd_file::error::ACCESS_DENIED;
+
+ case ENFILE:
+ case EMFILE:
+ return osd_file::error::TOO_MANY_FILES;
+
+ default:
+ return osd_file::error::FAILURE;
+ }
+}
diff --git a/src/osd/modules/file/posixfile.h b/src/osd/modules/file/posixfile.h
new file mode 100644
index 00000000000..2339a52ceec
--- /dev/null
+++ b/src/osd/modules/file/posixfile.h
@@ -0,0 +1,28 @@
+// license:BSD-3-Clause
+// copyright-holders:Olivier Galibert, R. Belmont, Vas Crabb
+//============================================================
+//
+// sdlfile.h - SDL file access functions
+//
+// SDLMAME by Olivier Galibert and R. Belmont
+//
+//============================================================
+
+
+#include "osdcore.h"
+
+#include <cstdint>
+#include <string>
+
+
+//============================================================
+// PROTOTYPES
+//============================================================
+
+bool posix_check_socket_path(std::string const &path);
+osd_file::error posix_open_socket(std::string const &path, std::uint32_t openflags, osd_file::ptr &file, std::uint64_t &filesize);
+
+bool posix_check_ptty_path(std::string const &path);
+osd_file::error posix_open_ptty(std::uint32_t openflags, osd_file::ptr &file, std::uint64_t &filesize, std::string &name);
+
+osd_file::error errno_to_file_error(int error);
diff --git a/src/osd/modules/file/posixptty.cpp b/src/osd/modules/file/posixptty.cpp
new file mode 100644
index 00000000000..b84838c0578
--- /dev/null
+++ b/src/osd/modules/file/posixptty.cpp
@@ -0,0 +1,184 @@
+// license:BSD-3-Clause
+// copyright-holders:Olivier Galibert, R. Belmont, Vas Crabb
+//============================================================
+//
+// sdlptty_unix.c - SDL pseudo tty access functions
+//
+// SDLMAME by Olivier Galibert and R. Belmont
+//
+//============================================================
+
+#include "posixfile.h"
+
+#include <cassert>
+#include <cerrno>
+#include <cstring>
+
+#include <fcntl.h>
+#include <limits.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#if defined(__FreeBSD__) || defined(__DragonFly__)
+#include <termios.h>
+#include <libutil.h>
+#elif defined(__NetBSD__) || defined(__OpenBSD__) || defined(__APPLE__)
+#include <termios.h>
+#include <util.h>
+#elif defined(__linux__) || defined(EMSCRIPTEN)
+#include <pty.h>
+#elif defined(__HAIKU__)
+#include <bsd/pty.h>
+#endif
+
+
+namespace {
+#if defined(__APPLE__)
+char const *const posix_ptty_identifier = "/dev/pty";
+#else
+char const *const posix_ptty_identifier = "/dev/pts";
+#endif
+
+
+class posix_osd_ptty : public osd_file
+{
+public:
+ posix_osd_ptty(posix_osd_ptty const &) = delete;
+ posix_osd_ptty(posix_osd_ptty &&) = delete;
+ posix_osd_ptty& operator=(posix_osd_ptty const &) = delete;
+ posix_osd_ptty& operator=(posix_osd_ptty &&) = delete;
+
+ posix_osd_ptty(int fd) : m_fd(fd)
+ {
+ assert(m_fd >= 0);
+ }
+
+ virtual ~posix_osd_ptty()
+ {
+ ::close(m_fd);
+ }
+
+ virtual error read(void *buffer, std::uint64_t offset, std::uint32_t count, std::uint32_t &actual) override
+ {
+ ssize_t const result = ::read(m_fd, buffer, count);
+ if (result < 0)
+ return errno_to_file_error(errno);
+
+ actual = std::uint32_t(size_t(result));
+ return error::NONE;
+ }
+
+ virtual error write(void const *buffer, std::uint64_t offset, std::uint32_t count, std::uint32_t &actual) override
+ {
+ ssize_t const result = ::write(m_fd, buffer, count);
+ if (result < 0)
+ return errno_to_file_error(errno);
+
+ actual = std::uint32_t(size_t(result));
+ return error::NONE;
+ }
+
+ virtual error truncate(std::uint64_t offset) override
+ {
+ // doesn't make sense on ptty
+ return error::INVALID_ACCESS;
+ }
+
+ virtual error flush() override
+ {
+ // no userspace buffers on read/write
+ return error::NONE;
+ }
+
+private:
+ int m_fd;
+};
+
+} // anonymous namespace
+
+
+bool posix_check_ptty_path(std::string const &path)
+{
+ return strncmp(path.c_str(), posix_ptty_identifier, strlen(posix_ptty_identifier)) == 0;
+}
+
+
+osd_file::error posix_open_ptty(std::uint32_t openflags, osd_file::ptr &file, std::uint64_t &filesize, std::string &name)
+{
+#if (defined(sun) || defined(__sun)) && (defined(__SVR4) || defined(__svr4__))
+ int access = O_NOCTTY;
+ if (openflags & OPEN_FLAG_WRITE)
+ access |= (openflags & OPEN_FLAG_READ) ? O_RDWR : O_WRONLY;
+ else if (openflags & OPEN_FLAG_READ)
+ access |= O_RDONLY;
+ else
+ return error::INVALID_ACCESS;
+
+ int const masterfd = ::posix_openpt(access);
+ if (masterfd < 0)
+ return errno_to_file_error(errno);
+
+ // grant access to slave device and check that it can be opened
+ char const *slavepath;
+ int slavefd;
+ if ((::grantpt(masterfd) < 0) ||
+ (::unlockpt(masterfd) < 0) ||
+ ((slavepath = ::ptsname(masterfd)) == nullptr) ||
+ ((slavefd = ::open(slavepath, O_RDWR | O_NOCTTY)) < 0))
+ {
+ int const err = errno;
+ ::close(masterfd);
+ return errno_to_file_error(err);
+ }
+
+ // check that it's possible to stack BSD-compatibility STREAMS modules
+ if ((::ioctl(slavefd, I_PUSH, "ptem") < 0) ||
+ (::ioctl(slavefd, I_PUSH, "ldterm") < 0) ||
+ (::ioctl(slavefd, I_PUSH, "ttcompat") < 0))
+ {
+ int const err = errno;
+ ::close(slavefd);
+ ::close(masterfd);
+ return errno_to_file_error(err);
+ }
+#else
+ struct termios tios;
+ std::memset(&tios, 0, sizeof(tios));
+ ::cfmakeraw(&tios);
+
+ int masterfd = -1, slavefd = -1;
+ char slavepath[PATH_MAX];
+ if (::openpty(&masterfd, &slavefd, slavepath, &tios, nullptr) < 0)
+ return errno_to_file_error(errno);
+#endif
+
+ ::close(slavefd);
+
+ int const oldflags = ::fcntl(masterfd, F_GETFL, 0);
+ if (oldflags < 0)
+ {
+ int const err = errno;
+ ::close(masterfd);
+ return errno_to_file_error(err);
+ }
+
+ if (::fcntl(masterfd, F_SETFL, oldflags | O_NONBLOCK) < 0)
+ {
+ int const err = errno;
+ ::close(masterfd);
+ return errno_to_file_error(err);
+ }
+
+ try
+ {
+ name = slavepath;
+ file = std::make_unique<posix_osd_ptty>(masterfd);
+ filesize = 0;
+ return osd_file::error::NONE;
+ }
+ catch (...)
+ {
+ ::close(masterfd);
+ return osd_file::error::OUT_OF_MEMORY;
+ }
+}
diff --git a/src/osd/modules/file/posixsocket.cpp b/src/osd/modules/file/posixsocket.cpp
new file mode 100644
index 00000000000..d6655e4cf15
--- /dev/null
+++ b/src/osd/modules/file/posixsocket.cpp
@@ -0,0 +1,232 @@
+// license:BSD-3-Clause
+// copyright-holders:Olivier Galibert, R. Belmont, Vas Crabb
+//============================================================
+//
+// sdlsocket.c - SDL socket (inet) access functions
+//
+// SDLMAME by Olivier Galibert and R. Belmont
+//
+//============================================================
+
+#include "posixfile.h"
+
+#include <cassert>
+#include <cerrno>
+#include <cstdio>
+
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <sys/select.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <unistd.h>
+
+
+namespace {
+char const *const posixfile_socket_identifier = "socket.";
+
+
+class posix_osd_socket : public osd_file
+{
+public:
+ posix_osd_socket(posix_osd_socket const &) = delete;
+ posix_osd_socket(posix_osd_socket &&) = delete;
+ posix_osd_socket& operator=(posix_osd_socket const &) = delete;
+ posix_osd_socket& operator=(posix_osd_socket &&) = delete;
+
+ posix_osd_socket(int sock, bool listening)
+ : m_sock(sock)
+ , m_listening(listening)
+ {
+ assert(m_sock >= 0);
+ }
+
+ virtual ~posix_osd_socket()
+ {
+ ::close(m_sock);
+ }
+
+ virtual error read(void *buffer, std::uint64_t offset, std::uint32_t count, std::uint32_t &actual) override
+ {
+ fd_set readfds;
+ FD_ZERO(&readfds);
+ FD_SET(m_sock, &readfds);
+
+ struct timeval timeout;
+ timeout.tv_sec = timeout.tv_usec = 0;
+
+ if (select(m_sock + 1, &readfds, nullptr, nullptr, &timeout) < 0)
+ {
+ char line[80];
+ std::sprintf(line, "%s : %s : %d ", __func__, __FILE__, __LINE__);
+ std::perror(line);
+ return errno_to_file_error(errno);
+ }
+ else if (FD_ISSET(m_sock, &readfds))
+ {
+ if (!m_listening)
+ {
+ // connected socket
+ ssize_t const result = ::read(m_sock, buffer, count);
+ if (result < 0)
+ {
+ return errno_to_file_error(errno);
+ }
+ else
+ {
+ actual = std::uint32_t(size_t(result));
+ return error::NONE;
+ }
+ }
+ else
+ {
+ // listening socket
+ int const accepted = ::accept(m_sock, nullptr, nullptr);
+ if (accepted < 0)
+ {
+ return errno_to_file_error(errno);
+ }
+ else
+ {
+ ::close(m_sock);
+ m_sock = accepted;
+ m_listening = false;
+ actual = 0;
+
+ return error::NONE;
+ }
+ }
+ }
+ else
+ {
+ return error::FAILURE;
+ }
+ }
+
+ virtual error write(void const *buffer, std::uint64_t offset, std::uint32_t count, std::uint32_t &actual) override
+ {
+ ssize_t const result = ::write(m_sock, buffer, count);
+ if (result < 0)
+ return errno_to_file_error(errno);
+
+ actual = std::uint32_t(size_t(result));
+ return error::NONE;
+ }
+
+ virtual error truncate(std::uint64_t offset) override
+ {
+ // doesn't make sense on socket
+ return error::INVALID_ACCESS;
+ }
+
+ virtual error flush() override
+ {
+ // there's no simple way to flush buffers on a socket anyway
+ return error::NONE;
+ }
+
+private:
+ int m_sock;
+ bool m_listening;
+};
+
+} // anonymous namespace
+
+
+/*
+ Checks whether the path is a socket specification. A valid socket
+ specification has the format "socket." host ":" port. Host may be simple
+ or fully qualified. Port must be between 1 and 65535.
+*/
+bool posix_check_socket_path(std::string const &path)
+{
+ if (strncmp(path.c_str(), posixfile_socket_identifier, strlen(posixfile_socket_identifier)) == 0 &&
+ strchr(path.c_str(), ':') != nullptr) return true;
+ return false;
+}
+
+
+osd_file::error posix_open_socket(std::string const &path, std::uint32_t openflags, osd_file::ptr &file, std::uint64_t &filesize)
+{
+ char hostname[256];
+ int port;
+ std::sscanf(&path[strlen(posixfile_socket_identifier)], "%255[^:]:%d", hostname, &port);
+
+ struct hostent const *const localhost = ::gethostbyname(hostname);
+ if (!localhost)
+ return osd_file::error::NOT_FOUND;
+
+ struct sockaddr_in sai;
+ memset(&sai, 0, sizeof(sai));
+ sai.sin_family = AF_INET;
+ sai.sin_port = htons(port);
+ sai.sin_addr = *reinterpret_cast<struct in_addr *>(localhost->h_addr);
+
+ int const sock = ::socket(AF_INET, SOCK_STREAM, 0);
+ if (sock < 0)
+ return errno_to_file_error(errno);
+
+ int const flag = 1;
+ if (::setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, reinterpret_cast<const char *>(&flag), sizeof(flag)) < 0)
+ {
+ int const err = errno;
+ ::close(sock);
+ return errno_to_file_error(err);
+ }
+
+ // listening socket support
+ if (openflags & OPEN_FLAG_CREATE)
+ {
+ //printf("Listening for client at '%s' on port '%d'\n", hostname, port);
+ // bind socket...
+ if (::bind(sock, reinterpret_cast<struct sockaddr const *>(&sai), sizeof(struct sockaddr)) < 0)
+ {
+ int const err = errno;
+ ::close(sock);
+ return errno_to_file_error(err);
+ }
+
+ // start to listen...
+ if (::listen(sock, 1) < 0)
+ {
+ int const err = errno;
+ ::close(sock);
+ return errno_to_file_error(err);
+ }
+
+ // mark socket as "listening"
+ try
+ {
+ file = std::make_unique<posix_osd_socket>(sock, true);
+ filesize = 0;
+ return osd_file::error::NONE;
+ }
+ catch (...)
+ {
+ ::close(sock);
+ return osd_file::error::OUT_OF_MEMORY;
+ }
+ }
+ else
+ {
+ //printf("Connecting to server '%s' on port '%d'\n", hostname, port);
+ if (::connect(sock, reinterpret_cast<struct sockaddr const *>(&sai), sizeof(struct sockaddr)) < 0)
+ {
+ ::close(sock);
+ return osd_file::error::ACCESS_DENIED; // have to return this value or bitb won't try to bind on connect failure
+ }
+ try
+ {
+ file = std::make_unique<posix_osd_socket>(sock, false);
+ filesize = 0;
+ return osd_file::error::NONE;
+ }
+ catch (...)
+ {
+ ::close(sock);
+ return osd_file::error::OUT_OF_MEMORY;
+ }
+ }
+}
diff --git a/src/osd/modules/file/stdfile.cpp b/src/osd/modules/file/stdfile.cpp
new file mode 100644
index 00000000000..92920bba495
--- /dev/null
+++ b/src/osd/modules/file/stdfile.cpp
@@ -0,0 +1,251 @@
+// license:BSD-3-Clause
+// copyright-holders:Aaron Giles
+//============================================================
+//
+// minifile.c - Minimal core file access functions
+//
+//============================================================
+
+#include "osdcore.h"
+
+#include <cassert>
+#include <cstdint>
+#include <cstdio>
+#include <cstdlib>
+#include <string>
+
+#include <stdio.h> // for fileno
+#include <unistd.h> // for ftruncate
+
+
+namespace {
+class std_osd_file : public osd_file
+{
+public:
+
+ std_osd_file(FILE *f) : m_file(f) { assert(m_file); }
+
+ //============================================================
+ // osd_close
+ //============================================================
+
+ virtual ~std_osd_file() override
+ {
+ // close the file handle
+ if (m_file) std::fclose(m_file);
+ }
+
+ //============================================================
+ // osd_read
+ //============================================================
+
+ virtual error read(void *buffer, std::uint64_t offset, std::uint32_t length, std::uint32_t &actual) override
+ {
+ // seek to the new location; note that most fseek implementations are limited to 32 bits
+ if (std::fseek(m_file, offset, SEEK_SET) < 0)
+ return error::FAILURE;
+
+ // perform the read
+ std::size_t const count = std::fread(buffer, 1, length, m_file);
+ actual = count;
+
+ return error::NONE;
+ }
+
+ //============================================================
+ // osd_write
+ //============================================================
+
+ virtual error write(const void *buffer, std::uint64_t offset, std::uint32_t length, std::uint32_t &actual) override
+ {
+ // seek to the new location; note that most fseek implementations are limited to 32 bits
+ if (std::fseek(m_file, offset, SEEK_SET) < 0)
+ return error::FAILURE;
+
+ // perform the write
+ std::size_t const count = std::fwrite(buffer, 1, length, m_file);
+ actual = count;
+
+ return error::NONE;
+ }
+
+ //============================================================
+ // osd_truncate
+ //============================================================
+
+ error truncate(std::uint64_t offset) override
+ {
+ return (ftruncate(fileno(m_file), offset) < 0) ? error::FAILURE : error::NONE;
+ }
+
+ //============================================================
+ // osd_fflush
+ //============================================================
+
+ virtual error flush() override
+ {
+ return (std::fflush(m_file) == EOF) ? error::FAILURE : error::NONE;
+ }
+
+private:
+ FILE *m_file;
+};
+
+} // anonymous namespace
+
+
+//============================================================
+// osd_open
+//============================================================
+
+osd_file::error osd_file::open(std::string const &path, std::uint32_t openflags, ptr &file, std::uint64_t &filesize)
+{
+ // based on the flags, choose a mode
+ const char *mode;
+ if (openflags & OPEN_FLAG_WRITE)
+ {
+ if (openflags & OPEN_FLAG_READ)
+ mode = (openflags & OPEN_FLAG_CREATE) ? "w+b" : "r+b";
+ else
+ mode = "wb";
+ }
+ else if (openflags & OPEN_FLAG_READ)
+ mode = "rb";
+ else
+ return error::INVALID_ACCESS;
+
+ // open the file
+ FILE *const fileptr = std::fopen(path.c_str(), mode);
+ if (!fileptr)
+ return error::NOT_FOUND;
+
+ // get the size -- note that most fseek/ftell implementations are limited to 32 bits
+ long length;
+ if ((std::fseek(fileptr, 0, SEEK_END) < 0) ||
+ ((length = std::ftell(fileptr)) < 0) ||
+ (std::fseek(fileptr, 0, SEEK_SET) < 0))
+ {
+ std::fclose(fileptr);
+ return error::FAILURE;
+ }
+
+ try
+ {
+ file = std::make_unique<std_osd_file>(fileptr);
+ filesize = std::int64_t(length);
+ return error::NONE;
+ }
+ catch (...)
+ {
+ std::fclose(fileptr);
+ return error::OUT_OF_MEMORY;
+ }
+}
+
+
+//============================================================
+// osd_openpty
+//============================================================
+
+osd_file::error osd_file::openpty(ptr &file, std::string &name)
+{
+ return error::FAILURE;
+}
+
+
+//============================================================
+// osd_rmfile
+//============================================================
+
+osd_file::error osd_file::remove(std::string const &filename)
+{
+ return (std::remove(filename.c_str()) < 0) ? error::FAILURE : error::NONE;
+}
+
+
+//============================================================
+// osd_get_physical_drive_geometry
+//============================================================
+
+int osd_get_physical_drive_geometry(const char *filename, UINT32 *cylinders, UINT32 *heads, UINT32 *sectors, UINT32 *bps)
+{
+ // there is no standard way of doing this, so we always return FALSE, indicating
+ // that a given path is not a physical drive
+ return FALSE;
+}
+
+
+//============================================================
+// osd_uchar_from_osdchar
+//============================================================
+
+int osd_uchar_from_osdchar(UINT32 /* unicode_char */ *uchar, const char *osdchar, size_t count)
+{
+ // we assume a standard 1:1 mapping of characters to the first 256 unicode characters
+ *uchar = (UINT8)*osdchar;
+ return 1;
+}
+
+
+//============================================================
+// osd_stat
+//============================================================
+
+osd_directory_entry *osd_stat(const std::string &path)
+{
+ osd_directory_entry *result = nullptr;
+
+ // create an osd_directory_entry; be sure to make sure that the caller can
+ // free all resources by just freeing the resulting osd_directory_entry
+ result = (osd_directory_entry *)osd_malloc_array(sizeof(*result) + path.length() + 1);
+ strcpy((char *)(result + 1), path.c_str());
+ result->name = (char *)(result + 1);
+ result->type = ENTTYPE_NONE;
+ result->size = 0;
+
+ FILE *f = std::fopen(path.c_str(), "rb");
+ if (f != nullptr)
+ {
+ std::fseek(f, 0, SEEK_END);
+ result->type = ENTTYPE_FILE;
+ result->size = std::ftell(f);
+ std::fclose(f);
+ }
+ return result;
+}
+
+
+//============================================================
+// osd_get_full_path
+//============================================================
+
+osd_file::error osd_get_full_path(std::string &dst, std::string const &path)
+{
+ // derive the full path of the file in an allocated string
+ // for now just fake it since we don't presume any underlying file system
+ dst = path;
+
+ return osd_file::error::NONE;
+}
+
+
+//============================================================
+// osd_is_absolute_path
+//============================================================
+
+bool osd_is_absolute_path(std::string const &path)
+{
+ // assume no for everything
+ return false;
+}
+
+
+//============================================================
+// osd_get_volume_name
+//============================================================
+
+const char *osd_get_volume_name(int idx)
+{
+ // we don't expose volumes
+ return nullptr;
+}
diff --git a/src/osd/modules/file/winfile.cpp b/src/osd/modules/file/winfile.cpp
new file mode 100644
index 00000000000..9695aac7363
--- /dev/null
+++ b/src/osd/modules/file/winfile.cpp
@@ -0,0 +1,503 @@
+// license:BSD-3-Clause
+// copyright-holders:Aaron Giles, Vas Crabb
+//============================================================
+//
+// winfile.c - Win32 OSD core file access functions
+//
+//============================================================
+
+#define WIN32_LEAN_AND_MEAN
+
+#include "winfile.h"
+
+// MAMEOS headers
+#include "strconv.h"
+#include "winutil.h"
+#include "winutf8.h"
+
+// MAME headers
+#include "osdcore.h"
+
+#include <cassert>
+#include <cstring>
+
+// standard windows headers
+#include <windows.h>
+#include <winioctl.h>
+#include <tchar.h>
+#include <shlwapi.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+
+namespace {
+//============================================================
+// TYPE DEFINITIONS
+//============================================================
+
+class win_osd_file : public osd_file
+{
+public:
+ win_osd_file(win_osd_file const &) = delete;
+ win_osd_file(win_osd_file &&) = delete;
+ win_osd_file& operator=(win_osd_file const &) = delete;
+ win_osd_file& operator=(win_osd_file &&) = delete;
+
+ win_osd_file(HANDLE handle) : m_handle(handle)
+ {
+ assert(m_handle);
+ assert(INVALID_HANDLE_VALUE != m_handle);
+ }
+
+ virtual ~win_osd_file() override
+ {
+ FlushFileBuffers(m_handle);
+ CloseHandle(m_handle);
+ }
+
+ virtual error read(void *buffer, std::uint64_t offset, std::uint32_t length, std::uint32_t &actual) override
+ {
+ // attempt to set the file pointer
+ LARGE_INTEGER largeOffset;
+ largeOffset.QuadPart = offset;
+ if (!SetFilePointerEx(m_handle, largeOffset, nullptr, FILE_BEGIN))
+ return win_error_to_file_error(GetLastError());
+
+ // then perform the read
+ DWORD result = 0;
+ if (!ReadFile(m_handle, buffer, length, &result, NULL))
+ return win_error_to_file_error(GetLastError());
+
+ actual = result;
+ return error::NONE;
+ }
+
+ virtual error write(void const *buffer, std::uint64_t offset, std::uint32_t length, std::uint32_t &actual) override
+ {
+ // attempt to set the file pointer
+ LARGE_INTEGER largeOffset;
+ largeOffset.QuadPart = offset;
+ if (!SetFilePointerEx(m_handle, largeOffset, nullptr, FILE_BEGIN))
+ return win_error_to_file_error(GetLastError());
+
+ // then perform the write
+ DWORD result = 0;
+ if (!WriteFile(m_handle, buffer, length, &result, NULL))
+ return win_error_to_file_error(GetLastError());
+
+ actual = result;
+ return error::NONE;
+ }
+
+ virtual error truncate(std::uint64_t offset) override
+ {
+ // attempt to set the file pointer
+ LARGE_INTEGER largeOffset;
+ largeOffset.QuadPart = offset;
+ if (!SetFilePointerEx(m_handle, largeOffset, nullptr, FILE_BEGIN))
+ return win_error_to_file_error(GetLastError());
+
+ // then perform the truncation
+ if (!SetEndOfFile(m_handle))
+ return win_error_to_file_error(GetLastError());
+ else
+ return error::NONE;
+ }
+
+ virtual error flush() override
+ {
+ // shouldn't be any userspace buffers on the file handle
+ return error::NONE;
+ }
+
+private:
+ HANDLE m_handle;
+};
+
+
+template <typename T>
+class osd_disposer
+{
+public:
+ osd_disposer(T *&ptr) : m_ptr(ptr) { }
+ ~osd_disposer() { if (m_ptr) osd_free(m_ptr); }
+private:
+ T *&m_ptr;
+};
+
+
+
+//============================================================
+// INLINE FUNCTIONS
+//============================================================
+
+inline bool is_path_to_physical_drive(char const *path)
+{
+ return (_strnicmp(path, "\\\\.\\physicaldrive", 17) == 0);
+}
+
+
+
+//============================================================
+// create_path_recursive
+//============================================================
+
+DWORD create_path_recursive(TCHAR *path)
+{
+ // if there's still a separator, and it's not the root, nuke it and recurse
+ TCHAR *sep = _tcsrchr(path, '\\');
+ if (sep && (sep > path) && (sep[0] != ':') && (sep[-1] != '\\'))
+ {
+ *sep = 0;
+ create_path_recursive(path);
+ *sep = '\\';
+ }
+
+ // if the path already exists, we're done
+ WIN32_FILE_ATTRIBUTE_DATA fileinfo;
+ if (GetFileAttributesEx(path, GetFileExInfoStandard, &fileinfo))
+ return NO_ERROR;
+ else if (!CreateDirectory(path, NULL))
+ return GetLastError();
+ else
+ return NO_ERROR;
+}
+
+} // anonymous namespace
+
+
+
+//============================================================
+// osd_open
+//============================================================
+
+osd_file::error osd_file::open(std::string const &orig_path, UINT32 openflags, ptr &file, std::uint64_t &filesize)
+{
+ std::string path;
+ try { osd_subst_env(path, orig_path); }
+ catch (...) { return error::OUT_OF_MEMORY; }
+
+ if (win_check_socket_path(path))
+ return win_open_socket(path, openflags, file, filesize);
+ else if (win_check_ptty_path(path))
+ return win_open_ptty(path, openflags, file, filesize);
+
+ // convert path to TCHAR
+ TCHAR *t_path = tstring_from_utf8(path.c_str());
+ osd_disposer<TCHAR> t_path_disposer(t_path);
+ if (!t_path)
+ return error::OUT_OF_MEMORY;
+
+ // convert the path into something Windows compatible
+ for (TCHAR *src = t_path; *src != 0; src++)
+ *src = /* ('/' == *src) ? '\\' : */ *src;
+
+ // select the file open modes
+ DWORD disposition, access, sharemode;
+ if (openflags & OPEN_FLAG_WRITE)
+ {
+ disposition = (!is_path_to_physical_drive(path.c_str()) && (openflags & OPEN_FLAG_CREATE)) ? CREATE_ALWAYS : OPEN_EXISTING;
+ access = (openflags & OPEN_FLAG_READ) ? (GENERIC_READ | GENERIC_WRITE) : GENERIC_WRITE;
+ sharemode = FILE_SHARE_READ;
+ }
+ else if (openflags & OPEN_FLAG_READ)
+ {
+ disposition = OPEN_EXISTING;
+ access = GENERIC_READ;
+ sharemode = FILE_SHARE_READ;
+ }
+ else
+ {
+ return error::INVALID_ACCESS;
+ }
+
+ // attempt to open the file
+ HANDLE h = CreateFile(t_path, access, sharemode, NULL, disposition, 0, NULL);
+ if (INVALID_HANDLE_VALUE == h)
+ {
+ DWORD err = GetLastError();
+ // create the path if necessary
+ if ((ERROR_PATH_NOT_FOUND == err) && (openflags & OPEN_FLAG_CREATE) && (openflags & OPEN_FLAG_CREATE_PATHS))
+ {
+ TCHAR *pathsep = _tcsrchr(t_path, '\\');
+ if (pathsep != NULL)
+ {
+ // create the path up to the file
+ *pathsep = 0;
+ err = create_path_recursive(t_path);
+ *pathsep = '\\';
+
+ // attempt to reopen the file
+ if (err == NO_ERROR)
+ {
+ h = CreateFile(t_path, access, sharemode, NULL, disposition, 0, NULL);
+ err = GetLastError();
+ }
+ }
+ }
+
+ // if we still failed, clean up and free
+ if (INVALID_HANDLE_VALUE == h)
+ return win_error_to_file_error(err);
+ }
+
+ // get the file size
+ DWORD upper, lower;
+ lower = GetFileSize(h, &upper);
+ if (INVALID_FILE_SIZE == lower)
+ {
+ DWORD const err = GetLastError();
+ if (NO_ERROR != err)
+ {
+ CloseHandle(h);
+ return win_error_to_file_error(err);
+ }
+ }
+
+ try
+ {
+ file = std::make_unique<win_osd_file>(h);
+ filesize = (std::uint64_t(upper) << 32) | lower;
+ return error::NONE;
+ }
+ catch (...)
+ {
+ CloseHandle(h);
+ return error::OUT_OF_MEMORY;
+ }
+}
+
+
+
+//============================================================
+// osd_openpty
+//============================================================
+
+osd_file::error osd_file::openpty(ptr &file, std::string &name)
+{
+ return error::FAILURE;
+}
+
+
+
+//============================================================
+// osd_rmfile
+//============================================================
+
+osd_file::error osd_file::remove(std::string const &filename)
+{
+ TCHAR *tempstr = tstring_from_utf8(filename.c_str());
+ if (!tempstr)
+ return error::OUT_OF_MEMORY;
+
+ error filerr = error::NONE;
+ if (!DeleteFile(tempstr))
+ filerr = win_error_to_file_error(GetLastError());
+
+ osd_free(tempstr);
+ return filerr;
+}
+
+
+
+//============================================================
+// osd_get_physical_drive_geometry
+//============================================================
+
+int osd_get_physical_drive_geometry(const char *filename, UINT32 *cylinders, UINT32 *heads, UINT32 *sectors, UINT32 *bps)
+{
+ DISK_GEOMETRY dg;
+ DWORD bytesRead;
+ TCHAR *t_filename;
+ HANDLE file;
+ int result;
+
+ // if it doesn't smell like a physical drive, just return FALSE
+ if (!is_path_to_physical_drive(filename))
+ return FALSE;
+
+ // do a create file on the drive
+ t_filename = tstring_from_utf8(filename);
+ if (t_filename == NULL)
+ return FALSE;
+ file = CreateFile(t_filename, GENERIC_READ, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, NULL);
+ osd_free(t_filename);
+ if (file == INVALID_HANDLE_VALUE)
+ return FALSE;
+
+ // device I/O control should return the geometry
+ result = DeviceIoControl(file, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &dg, sizeof(dg), &bytesRead, NULL);
+ CloseHandle(file);
+
+ // if that failed, return false
+ if (!result)
+ return FALSE;
+
+ // store the results
+ *cylinders = (UINT32)dg.Cylinders.QuadPart;
+ *heads = dg.TracksPerCylinder;
+ *sectors = dg.SectorsPerTrack;
+ *bps = dg.BytesPerSector;
+
+ // normalize
+ while (*heads > 16 && !(*heads & 1))
+ {
+ *heads /= 2;
+ *cylinders *= 2;
+ }
+ return TRUE;
+}
+
+
+
+//============================================================
+// osd_stat
+//============================================================
+
+osd_directory_entry *osd_stat(const std::string &path)
+{
+ // convert the path to TCHARs
+ std::unique_ptr<TCHAR, void (*)(void *)> const t_path(tstring_from_utf8(path.c_str()), &osd_free);
+ if (!t_path)
+ return nullptr;
+
+ // is this path a root directory (e.g. - C:)?
+ WIN32_FIND_DATA find_data;
+ std::memset(&find_data, 0, sizeof(find_data));
+ if (isalpha(path[0]) && (path[1] == ':') && (path[2] == '\0'))
+ {
+ // need to do special logic for root directories
+ if (!GetFileAttributesEx(t_path.get(), GetFileExInfoStandard, &find_data.dwFileAttributes))
+ find_data.dwFileAttributes = INVALID_FILE_ATTRIBUTES;
+ }
+ else
+ {
+ // attempt to find the first file
+ HANDLE find = FindFirstFileEx(t_path.get(), FindExInfoStandard, &find_data, FindExSearchNameMatch, NULL, 0);
+ if (find == INVALID_HANDLE_VALUE)
+ return nullptr;
+ FindClose(find);
+ }
+
+ // create an osd_directory_entry; be sure to make sure that the caller can
+ // free all resources by just freeing the resulting osd_directory_entry
+ osd_directory_entry *const result = (osd_directory_entry *)osd_malloc_array(sizeof(*result) + path.length() + 1);
+ if (!result)
+ return nullptr;
+ strcpy(((char *) result) + sizeof(*result), path.c_str());
+ result->name = ((char *) result) + sizeof(*result);
+ result->type = win_attributes_to_entry_type(find_data.dwFileAttributes);
+ result->size = find_data.nFileSizeLow | ((UINT64) find_data.nFileSizeHigh << 32);
+
+ return result;
+}
+
+
+//============================================================
+// osd_get_full_path
+//============================================================
+
+osd_file::error osd_get_full_path(std::string &dst, std::string const &path)
+{
+ // convert the path to TCHARs
+ TCHAR *t_path = tstring_from_utf8(path.c_str());
+ osd_disposer<TCHAR> t_path_disposer(t_path);
+ if (!t_path)
+ return osd_file::error::OUT_OF_MEMORY;
+
+ // cannonicalize the path
+ TCHAR buffer[MAX_PATH];
+ if (!GetFullPathName(t_path, ARRAY_LENGTH(buffer), buffer, NULL))
+ return win_error_to_file_error(GetLastError());
+
+ // convert the result back to UTF-8
+ char *result = utf8_from_tstring(buffer);
+ osd_disposer<char> result_disposer(result);
+ if (!result)
+ return osd_file::error::OUT_OF_MEMORY;
+
+ dst = result;
+ return osd_file::error::NONE;
+}
+
+
+
+//============================================================
+// osd_is_absolute_path
+//============================================================
+
+bool osd_is_absolute_path(std::string const &path)
+{
+ bool result = false;
+ TCHAR *t_path = tstring_from_utf8(path.c_str());
+ if (t_path != NULL)
+ {
+ result = !PathIsRelative(t_path);
+ osd_free(t_path);
+ }
+ return result;
+}
+
+
+
+//============================================================
+// osd_get_volume_name
+//============================================================
+
+const char *osd_get_volume_name(int idx)
+{
+ static char szBuffer[128];
+ const char *p;
+
+ GetLogicalDriveStringsA(ARRAY_LENGTH(szBuffer), szBuffer);
+
+ p = szBuffer;
+ while(idx--) {
+ p += strlen(p) + 1;
+ if (!*p) return NULL;
+ }
+
+ return p;
+}
+
+
+
+//============================================================
+// win_error_to_file_error
+//============================================================
+
+osd_file::error win_error_to_file_error(DWORD error)
+{
+ osd_file::error filerr;
+
+ // convert a Windows error to a osd_file::error
+ switch (error)
+ {
+ case ERROR_SUCCESS:
+ filerr = osd_file::error::NONE;
+ break;
+
+ case ERROR_OUTOFMEMORY:
+ filerr = osd_file::error::OUT_OF_MEMORY;
+ break;
+
+ case ERROR_FILE_NOT_FOUND:
+ case ERROR_FILENAME_EXCED_RANGE:
+ case ERROR_PATH_NOT_FOUND:
+ filerr = osd_file::error::NOT_FOUND;
+ break;
+
+ case ERROR_ACCESS_DENIED:
+ filerr = osd_file::error::ACCESS_DENIED;
+ break;
+
+ case ERROR_SHARING_VIOLATION:
+ filerr = osd_file::error::ALREADY_OPEN;
+ break;
+
+ default:
+ filerr = osd_file::error::FAILURE;
+ break;
+ }
+ return filerr;
+}
diff --git a/src/osd/modules/file/winfile.h b/src/osd/modules/file/winfile.h
new file mode 100644
index 00000000000..9a6f1b8fc34
--- /dev/null
+++ b/src/osd/modules/file/winfile.h
@@ -0,0 +1,34 @@
+// license:BSD-3-Clause
+// copyright-holders:Aaron Giles, Vas Crabb
+//============================================================
+//
+// winfile.h - File access functions
+//
+//============================================================
+#ifndef MAME_OSD_WINDOWS_WINFILE_H
+#define MAME_OSD_WINDOWS_WINFILE_H
+
+#include "osdcore.h"
+
+#include <cstdint>
+#include <string>
+
+#include <winsock2.h>
+
+
+//============================================================
+// PROTOTYPES
+//============================================================
+
+bool win_init_sockets();
+void win_cleanup_sockets();
+
+bool win_check_socket_path(std::string const &path);
+osd_file::error win_open_socket(std::string const &path, std::uint32_t openflags, osd_file::ptr &file, std::uint64_t &filesize);
+
+bool win_check_ptty_path(std::string const &path);
+osd_file::error win_open_ptty(std::string const &path, std::uint32_t openflags, osd_file::ptr &file, std::uint64_t &filesize);
+
+osd_file::error win_error_to_file_error(DWORD error);
+
+#endif // MAME_OSD_WINDOWS_WINFILE_H
diff --git a/src/osd/modules/file/winptty.cpp b/src/osd/modules/file/winptty.cpp
new file mode 100644
index 00000000000..52e19491ea5
--- /dev/null
+++ b/src/osd/modules/file/winptty.cpp
@@ -0,0 +1,111 @@
+// license:BSD-3-Clause
+// copyright-holders:Aaron Giles, Vas Crabb
+
+#define WIN32_LEAN_AND_MEAN
+
+#include "winfile.h"
+
+#include "strconv.h"
+#include "winutil.h"
+
+#include <cassert>
+
+#include <windows.h>
+#include <stdlib.h>
+
+
+namespace {
+char const *const winfile_ptty_identifier = "\\\\.\\pipe\\";
+
+
+class win_osd_ptty : public osd_file
+{
+public:
+ win_osd_ptty(win_osd_ptty const &) = delete;
+ win_osd_ptty(win_osd_ptty &&) = delete;
+ win_osd_ptty& operator=(win_osd_ptty const &) = delete;
+ win_osd_ptty& operator=(win_osd_ptty &&) = delete;
+
+ win_osd_ptty(HANDLE handle) : m_handle(handle)
+ {
+ assert(m_handle);
+ assert(INVALID_HANDLE_VALUE != m_handle);
+ }
+
+ ~win_osd_ptty()
+ {
+ FlushFileBuffers(m_handle);
+ DisconnectNamedPipe(m_handle);
+ CloseHandle(m_handle);
+ }
+
+ virtual error read(void *buffer, std::uint64_t offset, std::uint32_t count, std::uint32_t &actual) override
+ {
+ DWORD bytes_read;
+ if (!ReadFile(m_handle, buffer, count, &bytes_read, NULL))
+ return win_error_to_file_error(GetLastError());
+
+ actual = bytes_read;
+ return error::NONE;
+ }
+
+ virtual error write(void const *buffer, std::uint64_t offset, std::uint32_t count, std::uint32_t &actual) override
+ {
+ DWORD bytes_written;
+ if (!WriteFile(m_handle, buffer, count, &bytes_written, NULL))
+ return win_error_to_file_error(GetLastError());
+
+ actual = bytes_written;
+ return error::NONE;
+ }
+
+ virtual error truncate(std::uint64_t offset) override
+ {
+ // doesn't make sense for a PTTY
+ return error::INVALID_ACCESS;
+ }
+
+ virtual error flush() override
+ {
+ // don't want to wait for client to read all data as implied by FlushFileBuffers
+ return error::NONE;
+ }
+
+private:
+ HANDLE m_handle;
+};
+
+} // anonymous namespace
+
+
+bool win_check_ptty_path(std::string const &path)
+{
+ if (strncmp(path.c_str(), winfile_ptty_identifier, strlen(winfile_ptty_identifier)) == 0) return true;
+ return false;
+}
+
+
+osd_file::error win_open_ptty(std::string const &path, std::uint32_t openflags, osd_file::ptr &file, std::uint64_t &filesize)
+{
+ TCHAR *t_name = tstring_from_utf8(path.c_str());
+ if (!t_name)
+ return osd_file::error::OUT_OF_MEMORY;
+
+ HANDLE pipe = CreateNamedPipe(t_name, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_NOWAIT, 1, 32, 32, 0, NULL);
+ osd_free(t_name);
+
+ if (INVALID_HANDLE_VALUE == pipe)
+ return osd_file::error::ACCESS_DENIED;
+
+ try
+ {
+ file = std::make_unique<win_osd_ptty>(pipe);
+ filesize = 0;
+ return osd_file::error::NONE;
+ }
+ catch (...)
+ {
+ CloseHandle(pipe);
+ return osd_file::error::OUT_OF_MEMORY;
+ }
+}
diff --git a/src/osd/modules/file/winsocket.cpp b/src/osd/modules/file/winsocket.cpp
new file mode 100644
index 00000000000..d1c3f4508e8
--- /dev/null
+++ b/src/osd/modules/file/winsocket.cpp
@@ -0,0 +1,277 @@
+// license:BSD-3-Clause
+// copyright-holders:Aaron Giles, Vas Crabb
+//============================================================
+//
+// winsocket.c - Windows socket (inet) access functions
+//
+//============================================================
+
+#define WIN32_LEAN_AND_MEAN
+
+#include "winfile.h"
+
+// MAMEOS headers
+#include "winutil.h"
+
+// MAME headers
+#include "osdcore.h"
+
+#include <cassert>
+#include <cstdio>
+
+// standard windows headers
+#include <windows.h>
+#include <winioctl.h>
+#include <tchar.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+
+namespace {
+char const *const winfile_socket_identifier = "socket.";
+
+
+class win_osd_socket : public osd_file
+{
+public:
+ win_osd_socket(win_osd_socket const &) = delete;
+ win_osd_socket(win_osd_socket &&) = delete;
+ win_osd_socket& operator=(win_osd_socket const &) = delete;
+ win_osd_socket& operator=(win_osd_socket &&) = delete;
+
+ win_osd_socket(SOCKET s, bool l)
+ : m_socket(s)
+ , m_listening(l)
+ {
+ assert(INVALID_SOCKET != m_socket);
+ }
+
+ virtual ~win_osd_socket() override
+ {
+ closesocket(m_socket);
+ }
+
+ virtual error read(void *buffer, std::uint64_t offset, std::uint32_t length, std::uint32_t &actual) override
+ {
+ fd_set readfds;
+ FD_ZERO(&readfds);
+ FD_SET(m_socket, &readfds);
+
+ struct timeval timeout;
+ timeout.tv_sec = timeout.tv_usec = 0;
+
+ if (select(m_socket + 1, &readfds, nullptr, nullptr, &timeout) < 0)
+ {
+ char line[80];
+ std::sprintf(line, "win_read_socket : %s : %d ", __FILE__, __LINE__);
+ std::perror(line);
+ return error::FAILURE;
+ }
+ else if (FD_ISSET(m_socket, &readfds))
+ {
+ if (!m_listening)
+ {
+ // connected socket
+ int const result = recv(m_socket, (char*)buffer, length, 0);
+ if (result < 0)
+ {
+ return wsa_error_to_file_error(WSAGetLastError());
+ }
+ else
+ {
+ actual = result;
+ return error::NONE;
+ }
+ }
+ else
+ {
+ // listening socket
+ SOCKET const accepted = accept(m_socket, nullptr, nullptr);
+ if (INVALID_SOCKET == accepted)
+ {
+ return wsa_error_to_file_error(WSAGetLastError());
+ }
+ else
+ {
+ closesocket(m_socket);
+ m_socket = accepted;
+ m_listening = false;
+ actual = 0;
+
+ return error::NONE;
+ }
+ }
+ }
+ else
+ {
+ return error::FAILURE;
+ }
+ }
+
+ virtual error write(void const *buffer, std::uint64_t offset, std::uint32_t length, std::uint32_t &actual) override
+ {
+ auto const result = send(m_socket, reinterpret_cast<const char *>(buffer), length, 0);
+ if (result < 0)
+ return wsa_error_to_file_error(WSAGetLastError());
+
+ actual = result;
+ return error::NONE;
+ }
+
+ virtual error truncate(std::uint64_t offset) override
+ {
+ // doesn't make sense for a socket
+ return error::INVALID_ACCESS;
+ }
+
+ virtual error flush() override
+ {
+ // no buffers to flush
+ return error::NONE;
+ }
+
+ static error wsa_error_to_file_error(int err)
+ {
+ switch (err)
+ {
+ case 0: return error::NONE;
+ case WSAEACCES: return error::ACCESS_DENIED;
+ case WSAEADDRINUSE: return error::ALREADY_OPEN;
+ case WSAEADDRNOTAVAIL: return error::NOT_FOUND;
+ case WSAECONNREFUSED: return error::NOT_FOUND;
+ case WSAEHOSTUNREACH: return error::NOT_FOUND;
+ case WSAENETUNREACH: return error::NOT_FOUND;
+ default: return error::FAILURE;
+ }
+ }
+
+private:
+ SOCKET m_socket;
+ bool m_listening;
+};
+
+} // anonymous namespace
+
+
+bool win_init_sockets()
+{
+ WSADATA wsaData;
+ WORD const version = MAKEWORD(2, 0);
+ int const error = WSAStartup(version, &wsaData);
+
+ // check for error
+ if (error)
+ {
+ // error occurred
+ return false;
+ }
+
+ // check for correct version
+ if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion ) != 0)
+ {
+ // incorrect WinSock version
+ WSACleanup();
+ return false;
+ }
+
+ // WinSock has been initialized
+ return true;
+}
+
+
+void win_cleanup_sockets()
+{
+ WSACleanup();
+}
+
+
+bool win_check_socket_path(std::string const &path)
+{
+ if (strncmp(path.c_str(), winfile_socket_identifier, strlen(winfile_socket_identifier)) == 0 &&
+ strchr(path.c_str(), ':') != nullptr) return true;
+ return false;
+}
+
+
+osd_file::error win_open_socket(std::string const &path, std::uint32_t openflags, osd_file::ptr &file, std::uint64_t &filesize)
+{
+ char hostname[256];
+ int port;
+ std::sscanf(&path[strlen(winfile_socket_identifier)], "%255[^:]:%d", hostname, &port);
+
+ struct hostent const *const localhost = gethostbyname(hostname);
+ if (!localhost)
+ return osd_file::error::NOT_FOUND;
+
+ struct sockaddr_in sai;
+ memset(&sai, 0, sizeof(sai));
+ sai.sin_family = AF_INET;
+ sai.sin_port = htons(port);
+ sai.sin_addr = *reinterpret_cast<struct in_addr *>(localhost->h_addr);
+
+ SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
+ if (INVALID_SOCKET == sock)
+ return win_osd_socket::wsa_error_to_file_error(WSAGetLastError());
+
+ int const flag = 1;
+ if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, reinterpret_cast<const char *>(&flag), sizeof(flag)) == SOCKET_ERROR)
+ {
+ int const err = WSAGetLastError();
+ closesocket(sock);
+ return win_osd_socket::wsa_error_to_file_error(err);
+ }
+
+ // listening socket support
+ if (openflags & OPEN_FLAG_CREATE)
+ {
+ //printf("Listening for client at '%s' on port '%d'\n", hostname, port);
+ // bind socket...
+ if (bind(sock, reinterpret_cast<struct sockaddr const *>(&sai), sizeof(struct sockaddr)) == SOCKET_ERROR)
+ {
+ int const err = WSAGetLastError();
+ closesocket(sock);
+ return win_osd_socket::wsa_error_to_file_error(err);
+ }
+
+ // start to listen...
+ if (listen(sock, 1) == SOCKET_ERROR)
+ {
+ int const err = WSAGetLastError();
+ closesocket(sock);
+ return win_osd_socket::wsa_error_to_file_error(err);
+ }
+
+ // mark socket as "listening"
+ try
+ {
+ file = std::make_unique<win_osd_socket>(sock, true);
+ filesize = 0;
+ return osd_file::error::NONE;
+ }
+ catch (...)
+ {
+ closesocket(sock);
+ return osd_file::error::OUT_OF_MEMORY;
+ }
+ }
+ else
+ {
+ //printf("Connecting to server '%s' on port '%d'\n", hostname, port);
+ if (connect(sock, reinterpret_cast<struct sockaddr const *>(&sai), sizeof(struct sockaddr)) == SOCKET_ERROR)
+ {
+ closesocket(sock);
+ return osd_file::error::ACCESS_DENIED; // have to return this value or bitb won't try to bind on connect failure
+ }
+ try
+ {
+ file = std::make_unique<win_osd_socket>(sock, false);
+ filesize = 0;
+ return osd_file::error::NONE;
+ }
+ catch (...)
+ {
+ closesocket(sock);
+ return osd_file::error::OUT_OF_MEMORY;
+ }
+ }
+}
diff --git a/src/osd/modules/font/font_dwrite.cpp b/src/osd/modules/font/font_dwrite.cpp
index cfcc952ef0d..80a8ba3a810 100644
--- a/src/osd/modules/font/font_dwrite.cpp
+++ b/src/osd/modules/font/font_dwrite.cpp
@@ -14,7 +14,6 @@
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
-#include <tchar.h>
#include <memory>
@@ -25,7 +24,6 @@
#include <initguid.h>
// Direct2D
-#include <dxgi1_2.h>
#include <d2d1_1.h>
#include <dwrite_1.h>
@@ -36,11 +34,8 @@ DEFINE_GUID(GUID_WICPixelFormat8bppAlpha, 0xe6cd0116, 0xeeba, 0x4161, 0xaa, 0x85
#include <wrl\client.h>
#undef interface
-#include "emu.h"
#include "strconv.h"
#include "corestr.h"
-#include "corealloc.h"
-#include "fileio.h"
#include "winutil.h"
using namespace Microsoft::WRL;
@@ -72,6 +67,16 @@ static const float POINTS_PER_DIP = (3.0f / 4.0f);
#define HR_RET0( CALL ) HR_RET(CALL, 0)
#define HR_RET1( CALL ) HR_RET(CALL, 1)
+struct osd_deleter
+{
+ void operator () (void * osd_pointer) const
+ {
+ osd_free(osd_pointer);
+ }
+};
+
+typedef std::unique_ptr<char, osd_deleter> osd_utf8_ptr;
+
// Typedefs for dynamically loaded functions
typedef lazy_loaded_function_p4<HRESULT, D2D1_FACTORY_TYPE, REFIID, const D2D1_FACTORY_OPTIONS*, void**> d2d_create_factory_fn;
typedef lazy_loaded_function_p3<HRESULT, DWRITE_FACTORY_TYPE, REFIID, IUnknown**> dwrite_create_factory_fn;
@@ -201,32 +206,32 @@ public:
m_designUnits = designUnits;
}
- UINT16 DesignUnitsPerEm()
+ UINT16 DesignUnitsPerEm() const
{
return m_designUnitsPerEm;
}
- float EmSizeInDip()
+ float EmSizeInDip() const
{
return m_emSizeInDip;
}
- float DesignUnits()
+ float DesignUnits() const
{
return m_designUnits;
}
- int Dips()
+ int Dips() const
{
- return (int)floor((m_designUnits * m_emSizeInDip) / m_designUnitsPerEm);
+ return static_cast<int>(floor((m_designUnits * m_emSizeInDip) / m_designUnitsPerEm));
}
- float Points()
+ float Points() const
{
return Dips() * POINTS_PER_DIP;
}
- FontDimension operator-(const FontDimension &other)
+ FontDimension operator-(const FontDimension &other) const
{
if (m_designUnitsPerEm != other.m_designUnitsPerEm || m_emSizeInDip != other.m_emSizeInDip)
{
@@ -236,7 +241,7 @@ public:
return FontDimension(m_designUnitsPerEm, m_emSizeInDip, m_designUnits - other.m_designUnits);
}
- FontDimension operator+(const FontDimension &other)
+ FontDimension operator+(const FontDimension &other) const
{
if (m_designUnitsPerEm != other.m_designUnitsPerEm || m_emSizeInDip != other.m_emSizeInDip)
{
@@ -267,12 +272,12 @@ public:
{
}
- FontDimension advanceWidth() { return m_advanceWidth; }
- FontDimension abcA() { return m_a; }
+ FontDimension advanceWidth() const { return m_advanceWidth; }
+ FontDimension abcA() const { return m_a; }
// Relationship between advanceWidth and B is ADV = A + B + C so B = ADV - A - C
- FontDimension abcB() { return advanceWidth() - abcA() - abcC(); }
- FontDimension abcC() { return m_c; }
+ FontDimension abcB() const { return advanceWidth() - abcA() - abcC(); }
+ FontDimension abcC() const { return m_c; }
};
//-------------------------------------------------
@@ -287,7 +292,7 @@ private:
float m_emSizeInDip;
public:
- float EmSizeInDip()
+ float EmSizeInDip() const
{
return m_emSizeInDip;
}
@@ -298,25 +303,25 @@ public:
m_emSizeInDip = emSizeInDip;
}
- FontDimension FromDip(float dip)
+ FontDimension FromDip(float dip) const
{
float sizeInDesignUnits = (dip / m_emSizeInDip) * m_designUnitsPerEm;
return FontDimension(m_designUnitsPerEm, m_emSizeInDip, sizeInDesignUnits);
}
- FontDimension FromDesignUnit(float designUnits)
+ FontDimension FromDesignUnit(float designUnits) const
{
return FontDimension(m_designUnitsPerEm, m_emSizeInDip, designUnits);
}
- FontDimension FromPoint(float pointSize)
+ FontDimension FromPoint(float pointSize) const
{
float sizeInDip = pointSize * (4.0f / 3.0f);
float sizeInDesignUnits = (sizeInDip / m_emSizeInDip) * m_designUnitsPerEm;
return FontDimension(m_designUnitsPerEm, m_emSizeInDip, sizeInDesignUnits);
}
- FontABCWidths CreateAbcWidths(float advanceWidth, float leftSideBearing, float rightSideBearing)
+ FontABCWidths CreateAbcWidths(float advanceWidth, float leftSideBearing, float rightSideBearing) const
{
return FontABCWidths(
FromDesignUnit(advanceWidth),
@@ -341,11 +346,11 @@ private:
public:
osd_font_dwrite(ComPtr<ID2D1Factory> d2dfactory, ComPtr<IDWriteFactory> dwriteFactory, ComPtr<IWICImagingFactory> wicFactory)
- : m_d2dfactory(d2dfactory), m_dwriteFactory(dwriteFactory), m_wicFactory(wicFactory)
+ : m_d2dfactory(d2dfactory), m_dwriteFactory(dwriteFactory), m_wicFactory(wicFactory), m_fontEmHeightInDips(0)
{
}
- virtual bool open(const char *font_path, const char *_name, int &height) override
+ virtual bool open(std::string const &font_path, std::string const &_name, int &height) override
{
if (m_d2dfactory == nullptr || m_dwriteFactory == nullptr || m_wicFactory == nullptr)
return false;
@@ -359,11 +364,11 @@ public:
bool italic = (strreplace(name, "[I]", "") + strreplace(name, "[i]", "") > 0);
// convert the face name
- auto familyName = std::wstring(std::unique_ptr<WCHAR, void(*)(void *)>(wstring_from_utf8(name.c_str()), osd_free).get());
+ std::unique_ptr<WCHAR, void(*)(void *)> familyName(wstring_from_utf8(name.c_str()), osd_free);
// find the font
HR_RET0(find_font(
- familyName.c_str(),
+ familyName.get(),
bold ? DWRITE_FONT_WEIGHT_BOLD : DWRITE_FONT_WEIGHT_NORMAL,
DWRITE_FONT_STRETCH_NORMAL,
italic ? DWRITE_FONT_STYLE_ITALIC : DWRITE_FONT_STYLE_NORMAL,
@@ -373,7 +378,7 @@ public:
m_font->GetMetrics(&metrics);
m_fontEmHeightInDips = DEFAULT_EM_HEIGHT;
- height = (int)round(m_fontEmHeightInDips * DIPS_PER_POINT);
+ height = static_cast<int>(round(m_fontEmHeightInDips * DIPS_PER_POINT));
return true;
}
@@ -397,7 +402,7 @@ public:
// pixel of a black & white font
//-------------------------------------------------
- virtual bool get_bitmap(unicode_char chnum, bitmap_argb32 &bitmap, INT32 &width, INT32 &xoffs, INT32 &yoffs) override
+ virtual bool get_bitmap(unicode_char chnum, bitmap_argb32 &bitmap, std::int32_t &width, std::int32_t &xoffs, std::int32_t &yoffs) override
{
const int MEM_ALIGN_CONST = 31;
const int BITMAP_PAD = 50;
@@ -493,7 +498,7 @@ public:
target->Clear(D2D1::ColorF(0.0f, 0.0f, 0.0f, 0.0f));
// now draw the character
- DWRITE_GLYPH_RUN run = { 0 };
+ DWRITE_GLYPH_RUN run = { nullptr };
DWRITE_GLYPH_OFFSET offsets;
offsets.advanceOffset = 0;
offsets.ascenderOffset = 0;
@@ -528,7 +533,7 @@ public:
// Lock the bitmap and get the data pointer
WICRect rect = { 0, 0, bmwidth, bmheight };
HR_RET0(wicBitmap->Lock(&rect, WICBitmapLockRead, lock.GetAddressOf()));
- HR_RET0(lock->GetDataPointer(&cbData, (BYTE**)&pixels));
+ HR_RET0(lock->GetDataPointer(&cbData, static_cast<BYTE**>(&pixels)));
// determine the actual left of the character
for (actbounds.min_x = 0; actbounds.min_x < bmwidth; actbounds.min_x++)
@@ -610,9 +615,9 @@ private:
// find_font - finds a font, given attributes
//-------------------------------------------------
- HRESULT find_font(std::wstring familyName, DWRITE_FONT_WEIGHT weight, DWRITE_FONT_STRETCH stretch, DWRITE_FONT_STYLE style, IDWriteFont ** ppfont)
+ HRESULT find_font(std::wstring familyName, DWRITE_FONT_WEIGHT weight, DWRITE_FONT_STRETCH stretch, DWRITE_FONT_STYLE style, IDWriteFont ** ppfont) const
{
- HRESULT result = S_OK;
+ HRESULT result;
ComPtr<IDWriteFontCollection> fonts;
HR_RETHR(m_dwriteFactory->GetSystemFontCollection(fonts.GetAddressOf()));
@@ -695,7 +700,7 @@ public:
reinterpret_cast<void**>(this->m_d2dfactory.GetAddressOf())));
// Initialize COM
- CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
+ CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
// Create a DirectWrite factory.
HR_RET1(m_pfnDWriteCreateFactory(
@@ -708,15 +713,97 @@ public:
NULL,
CLSCTX_INPROC_SERVER,
__uuidof(IWICImagingFactory),
- (void**)&m_wicFactory));
+ static_cast<void**>(&m_wicFactory)));
osd_printf_verbose("FontProvider: DirectWrite initialized successfully.\n");
return 0;
}
- virtual osd_font *font_alloc() override
+ virtual osd_font::ptr font_alloc() override
+ {
+ return std::make_unique<osd_font_dwrite>(m_d2dfactory, m_dwriteFactory, m_wicFactory);
+ }
+
+ virtual bool get_font_families(std::string const &font_path, std::vector<std::pair<std::string, std::string> > &fontresult) override
+ {
+ HRESULT result;
+ ComPtr<IDWriteFontFamily> family;
+ ComPtr<IDWriteLocalizedStrings> names;
+
+ // For now, we're just enumerating system fonts, if we want to support custom font
+ // collections, there's more work that neeeds to be done
+ ComPtr<IDWriteFontCollection> fonts;
+ HR_RET0(m_dwriteFactory->GetSystemFontCollection(fonts.GetAddressOf()));
+
+ int family_count = fonts->GetFontFamilyCount();
+ for (int i = 0; i < family_count; i++)
+ {
+ HR_RET0(fonts->GetFontFamily(i, family.ReleaseAndGetAddressOf()));
+
+ HR_RET0(family->GetFamilyNames(names.ReleaseAndGetAddressOf()));
+
+ std::unique_ptr<WCHAR[]> name = nullptr;
+ HR_RET0(get_localized_familyname(names, name));
+
+ auto utf8_name = osd_utf8_ptr(utf8_from_wstring(name.get()));
+ name.reset();
+
+ // Review: should the config name, be unlocalized?
+ // maybe the english name?
+ fontresult.push_back(
+ make_pair(
+ std::string(utf8_name.get()),
+ std::string(utf8_name.get())));
+
+ utf8_name.reset();
+ }
+
+ std::stable_sort(fontresult.begin(), fontresult.end());
+ return true;
+ }
+
+private:
+ HRESULT get_family_for_locale(ComPtr<IDWriteLocalizedStrings> family_names, const WCHAR* locale, std::unique_ptr<WCHAR[]> &family_name) const
+ {
+ HRESULT result;
+ UINT32 index;
+ BOOL exists = false;
+
+ result = family_names->FindLocaleName(locale, &index, &exists);
+
+ // if the above find did not find a match, retry with US English
+ if (SUCCEEDED(result) && !exists)
+ family_names->FindLocaleName(L"en-us", &index, &exists);
+
+ // If the specified locale doesn't exist, select the first on the list.
+ if (!exists)
+ index = 0;
+
+ // Get the length and allocate our buffer
+ UINT32 name_length = 0;
+ HR_RETHR(family_names->GetStringLength(index, &name_length));
+ auto name_buffer = std::make_unique<WCHAR[]>(name_length + 1);
+
+ // Get the name
+ HR_RETHR(family_names->GetString(index, name_buffer.get(), name_length + 1));
+
+ family_name = std::move(name_buffer);
+ return S_OK;
+ }
+
+ HRESULT get_localized_familyname(ComPtr<IDWriteLocalizedStrings> family_names, std::unique_ptr<WCHAR[]> &family_name) const
{
- return global_alloc(osd_font_dwrite(m_d2dfactory, m_dwriteFactory, m_wicFactory));
+ wchar_t localeName[LOCALE_NAME_MAX_LENGTH];
+
+ // Get the default locale for this user.
+ int defaultLocaleSuccess = GetUserDefaultLocaleName(localeName, LOCALE_NAME_MAX_LENGTH);
+
+ // If the default locale is returned, find that locale name, otherwise use "en-us".
+ if (defaultLocaleSuccess)
+ return get_family_for_locale(family_names, localeName, family_name);
+
+ // If locale can't be determined, fall back to US English
+ return get_family_for_locale(family_names, L"en-us", family_name);
}
};
diff --git a/src/osd/modules/font/font_module.h b/src/osd/modules/font/font_module.h
index c9c7b1f40cb..81ffaca74e5 100644
--- a/src/osd/modules/font/font_module.h
+++ b/src/osd/modules/font/font_module.h
@@ -5,12 +5,16 @@
*
*/
-#ifndef FONT_MODULE_H_
-#define FONT_MODULE_H_
+#ifndef MAME_OSD_MODULES_FONT_FONTMODULE_H
+#define MAME_OSD_MODULES_FONT_FONTMODULE_H
#include "osdepend.h"
#include "modules/osdmodule.h"
+#include <string>
+#include <vector>
+
+
//============================================================
// CONSTANTS
//============================================================
@@ -21,8 +25,13 @@ class font_module
{
public:
virtual ~font_module() { }
- virtual osd_font *font_alloc() = 0;
+
+ /** attempt to allocate a font instance */
+ virtual osd_font::ptr font_alloc() = 0;
+
+ /** attempt to list available font families */
+ virtual bool get_font_families(std::string const &font_path, std::vector<std::pair<std::string, std::string> > &result) = 0;
};
-#endif /* FONT_MODULE_H_ */
+#endif // MAME_OSD_MODULES_FONT_FONTMODULE_H
diff --git a/src/osd/modules/font/font_none.cpp b/src/osd/modules/font/font_none.cpp
index de9d01bb103..2716b52cf8e 100644
--- a/src/osd/modules/font/font_none.cpp
+++ b/src/osd/modules/font/font_none.cpp
@@ -8,61 +8,25 @@
#include "font_module.h"
#include "modules/osdmodule.h"
-//-------------------------------------------------
-// font_open - attempt to "open" a handle to the
-// font with the given name
-//-------------------------------------------------
-
class osd_font_none : public osd_font
{
public:
virtual ~osd_font_none() { }
- virtual bool open(const char *font_path, const char *name, int &height) override;
- virtual void close() override;
- virtual bool get_bitmap(unicode_char chnum, bitmap_argb32 &bitmap, INT32 &width, INT32 &xoffs, INT32 &yoffs) override;
+ virtual bool open(std::string const &font_path, std::string const &name, int &height) override { return false; }
+ virtual void close() override { }
+ virtual bool get_bitmap(unicode_char chnum, bitmap_argb32 &bitmap, std::int32_t &width, std::int32_t &xoffs, std::int32_t &yoffs) override { return false; }
};
-bool osd_font_none::open(const char *font_path, const char *_name, int &height)
-{
- return false;
-}
-
-//-------------------------------------------------
-// font_close - release resources associated with
-// a given OSD font
-//-------------------------------------------------
-
-void osd_font_none::close()
-{
-}
-
-//-------------------------------------------------
-// font_get_bitmap - allocate and populate a
-// BITMAP_FORMAT_ARGB32 bitmap containing the
-// pixel values rgb_t(0xff,0xff,0xff,0xff)
-// or rgb_t(0x00,0xff,0xff,0xff) for each
-// pixel of a black & white font
-//-------------------------------------------------
-
-bool osd_font_none::get_bitmap(unicode_char chnum, bitmap_argb32 &bitmap, INT32 &width, INT32 &xoffs, INT32 &yoffs)
-{
- return false;
-}
-
class font_none : public osd_module, public font_module
{
public:
- font_none() : osd_module(OSD_FONT_PROVIDER, "none"), font_module()
- {
- }
+ font_none() : osd_module(OSD_FONT_PROVIDER, "none"), font_module() { }
virtual int init(const osd_options &options) override { return 0; }
- virtual osd_font *font_alloc() override
- {
- return global_alloc(osd_font_none);
- }
+ virtual osd_font::ptr font_alloc() override { return std::make_unique<osd_font_none>(); }
+ virtual bool get_font_families(std::string const &font_path, std::vector<std::pair<std::string, std::string> > &result) override { return false; }
};
MODULE_DEFINITION(FONT_NONE, font_none)
diff --git a/src/osd/modules/font/font_osx.cpp b/src/osd/modules/font/font_osx.cpp
index 831321fdf34..e1c5137b397 100644
--- a/src/osd/modules/font/font_osx.cpp
+++ b/src/osd/modules/font/font_osx.cpp
@@ -1,5 +1,5 @@
// license:BSD-3-Clause
-// copyright-holders:Olivier Galibert, R. Belmont
+// copyright-holders:Olivier Galibert, R. Belmont, Vas Crabb
/*
* font_osx.c
*
@@ -10,14 +10,11 @@
#ifdef SDLMAME_MACOSX
-#include <Carbon/Carbon.h>
-
#include "corealloc.h"
#include "fileio.h"
-#define POINT_SIZE 144.0
-#define EXTRA_HEIGHT 1.0
-#define EXTRA_WIDTH 1.15
+#include <ApplicationServices/ApplicationServices.h>
+#include <CoreFoundation/CoreFoundation.h>
//-------------------------------------------------
// font_open - attempt to "open" a handle to the
@@ -27,48 +24,64 @@
class osd_font_osx : public osd_font
{
public:
- virtual ~osd_font_osx() { }
+ osd_font_osx() : m_font(NULL) { }
+ osd_font_osx(osd_font_osx &&obj) : m_font(obj.m_font) { obj.m_font = NULL; }
+ virtual ~osd_font_osx() { close(); }
- virtual bool open(const char *font_path, const char *name, int &height);
+ virtual bool open(std::string const &font_path, std::string const &name, int &height);
virtual void close();
- virtual bool get_bitmap(unicode_char chnum, bitmap_argb32 &bitmap, INT32 &width, INT32 &xoffs, INT32 &yoffs);
+ virtual bool get_bitmap(unicode_char chnum, bitmap_argb32 &bitmap, std::int32_t &width, std::int32_t &xoffs, std::int32_t &yoffs);
+
+ osd_font_osx &operator=(osd_font_osx &&obj)
+ {
+ using std::swap;
+ swap(m_font, obj.m_font);
+ return *this;
+ }
+
private:
+ osd_font_osx(osd_font_osx const &) = delete;
+ osd_font_osx &operator=(osd_font_osx const &) = delete;
+
+ static constexpr CGFloat POINT_SIZE = 144.0;
+ static constexpr CGFloat EXTRA_HEIGHT = 1.0;
+ static constexpr CGFloat EXTRA_WIDTH = 1.15;
+
CTFontRef m_font;
};
-bool osd_font_osx::open(const char *font_path, const char *name, int &height)
+bool osd_font_osx::open(std::string const &font_path, std::string const &name, int &height)
{
- m_font = NULL;
- osd_printf_verbose("FONT NAME %s\n", name);
+ osd_printf_verbose("FONT NAME %s\n", name.c_str());
#if 0
- if (!strcmp(name, "default"))
+ if (name != "default")
{
name = "LucidaGrande";
}
#endif
- CFStringRef const font_name = CFStringCreateWithCString(NULL, name, kCFStringEncodingUTF8);
- if (kCFNotFound != CFStringFind(font_name, CFSTR(".BDF"), kCFCompareCaseInsensitive | kCFCompareBackwards | kCFCompareAnchored | kCFCompareNonliteral).location)
+ CFStringRef const font_name = CFStringCreateWithCString(NULL, name.c_str(), kCFStringEncodingUTF8);
+ if (font_name && (kCFNotFound != CFStringFind(font_name, CFSTR(".BDF"), kCFCompareCaseInsensitive | kCFCompareBackwards | kCFCompareAnchored | kCFCompareNonliteral).location))
{
// handle bdf fonts in the core
CFRelease(font_name);
return false;
}
CTFontRef ct_font = NULL;
- if (font_name != NULL)
+ if (font_name)
{
CTFontDescriptorRef const font_descriptor = CTFontDescriptorCreateWithNameAndSize(font_name, 0.0);
- if (font_descriptor != NULL)
+ if (font_descriptor)
{
ct_font = CTFontCreateWithFontDescriptor(font_descriptor, POINT_SIZE, &CGAffineTransformIdentity);
CFRelease(font_descriptor);
}
+ CFRelease(font_name);
}
- CFRelease(font_name);
if (!ct_font)
{
- osd_printf_verbose("Couldn't find/open font %s, using MAME default\n", name);
+ osd_printf_verbose("Couldn't find/open font %s, using MAME default\n", name.c_str());
return false;
}
@@ -84,6 +97,7 @@ bool osd_font_osx::open(const char *font_path, const char *name, int &height)
line_height += CTFontGetLeading(ct_font);
height = ceilf(line_height * EXTRA_HEIGHT);
+ close();
m_font = ct_font;
return true;
}
@@ -96,9 +110,8 @@ bool osd_font_osx::open(const char *font_path, const char *name, int &height)
void osd_font_osx::close()
{
if (m_font != NULL)
- {
CFRelease(m_font);
- }
+ m_font = NULL;
}
//-------------------------------------------------
@@ -109,7 +122,7 @@ void osd_font_osx::close()
// pixel of a black & white font
//-------------------------------------------------
-bool osd_font_osx::get_bitmap(unicode_char chnum, bitmap_argb32 &bitmap, INT32 &width, INT32 &xoffs, INT32 &yoffs)
+bool osd_font_osx::get_bitmap(unicode_char chnum, bitmap_argb32 &bitmap, std::int32_t &width, std::int32_t &xoffs, std::int32_t &yoffs)
{
UniChar uni_char;
CGGlyph glyph;
@@ -180,21 +193,89 @@ bool osd_font_osx::get_bitmap(unicode_char chnum, bitmap_argb32 &bitmap, INT32 &
class font_osx : public osd_module, public font_module
{
public:
- font_osx()
- : osd_module(OSD_FONT_PROVIDER, "osx"), font_module()
+ font_osx() : osd_module(OSD_FONT_PROVIDER, "osx"), font_module() { }
+
+ virtual int init(const osd_options &options) override { return 0; }
+ virtual osd_font::ptr font_alloc() override { return std::make_unique<osd_font_osx>(); }
+ virtual bool get_font_families(std::string const &font_path, std::vector<std::pair<std::string, std::string> > &result) override;
+
+private:
+ static CFComparisonResult sort_callback(CTFontDescriptorRef first, CTFontDescriptorRef second, void *refCon)
{
+ CFStringRef left = (CFStringRef)CTFontDescriptorCopyLocalizedAttribute(first, kCTFontDisplayNameAttribute, NULL);
+ if (!left) left = (CFStringRef)CTFontDescriptorCopyAttribute(first, kCTFontNameAttribute);
+ CFStringRef right = (CFStringRef)CTFontDescriptorCopyLocalizedAttribute(second, kCTFontDisplayNameAttribute, NULL);
+ if (!right) right = (CFStringRef)CTFontDescriptorCopyAttribute(second, kCTFontNameAttribute);
+
+ CFComparisonResult result;
+ if (left && right) result = CFStringCompareWithOptions(left, right, CFRangeMake(0, CFStringGetLength(left)), kCFCompareCaseInsensitive | kCFCompareLocalized | kCFCompareNonliteral);
+ else if (!left) result = kCFCompareLessThan;
+ else if (!right) result = kCFCompareGreaterThan;
+ else result = kCFCompareEqualTo;
+
+ if (left) CFRelease(left);
+ if (right) CFRelease(right);
+ return result;
}
+};
- virtual int init(const osd_options &options) { return 0; }
-
- osd_font *font_alloc()
+bool font_osx::get_font_families(std::string const &font_path, std::vector<std::pair<std::string, std::string> > &result)
+{
+ CFStringRef keys[] = { kCTFontCollectionRemoveDuplicatesOption };
+ std::uintptr_t values[ARRAY_LENGTH(keys)] = { 1 };
+ CFDictionaryRef const options = CFDictionaryCreate(kCFAllocatorDefault, (void const **)keys, (void const **)values, ARRAY_LENGTH(keys), &kCFTypeDictionaryKeyCallBacks, NULL);
+ CTFontCollectionRef const collection = CTFontCollectionCreateFromAvailableFonts(NULL);
+ CFRelease(options);
+ if (!collection) return false;
+
+ CFArrayRef const descriptors = CTFontCollectionCreateMatchingFontDescriptorsSortedWithCallback(collection, &sort_callback, nullptr);
+ CFRelease(collection);
+ if (!descriptors) return false;
+
+ result.clear();
+ CFIndex const count = CFArrayGetCount(descriptors);
+ result.reserve(count);
+ for (CFIndex i = 0; i != count; i++)
{
- return global_alloc(osd_font_osx);
+ CTFontDescriptorRef const font = (CTFontDescriptorRef)CFArrayGetValueAtIndex(descriptors, i);
+ CFStringRef const name = (CFStringRef)CTFontDescriptorCopyAttribute(font, kCTFontNameAttribute);
+ CFStringRef const display = (CFStringRef)CTFontDescriptorCopyLocalizedAttribute(font, kCTFontDisplayNameAttribute, NULL);
+
+ if (name && display)
+ {
+ char const *utf;
+ std::vector<char> buf;
+
+ utf = CFStringGetCStringPtr(name, kCFStringEncodingUTF8);
+ if (!utf)
+ {
+ buf.resize(CFStringGetMaximumSizeForEncoding(std::max(CFStringGetLength(name), CFStringGetLength(display)), kCFStringEncodingUTF8));
+ CFStringGetCString(name, &buf[0], buf.size(), kCFStringEncodingUTF8);
+ }
+ std::string utf8name(utf ? utf : &buf[0]);
+
+ utf = CFStringGetCStringPtr(display, kCFStringEncodingUTF8);
+ if (!utf)
+ {
+ buf.resize(CFStringGetMaximumSizeForEncoding(CFStringGetLength(display), kCFStringEncodingUTF8));
+ CFStringGetCString(display, &buf[0], buf.size(), kCFStringEncodingUTF8);
+ }
+ std::string utf8display(utf ? utf : &buf[0]);
+
+ result.emplace_back(std::move(utf8name), std::move(utf8display));
+ }
+
+ if (name) CFRelease(name);
+ if (display) CFRelease(display);
}
-};
+ return true;
+}
+
#else /* SDLMAME_MACOSX */
- MODULE_NOT_SUPPORTED(font_osx, OSD_FONT_PROVIDER, "osx")
+
+MODULE_NOT_SUPPORTED(font_osx, OSD_FONT_PROVIDER, "osx")
+
#endif
MODULE_DEFINITION(FONT_OSX, font_osx)
diff --git a/src/osd/modules/font/font_sdl.cpp b/src/osd/modules/font/font_sdl.cpp
index ad5d1699e3b..c6f45635623 100644
--- a/src/osd/modules/font/font_sdl.cpp
+++ b/src/osd/modules/font/font_sdl.cpp
@@ -1,5 +1,5 @@
// license:BSD-3-Clause
-// copyright-holders:Olivier Galibert, R. Belmont
+// copyright-holders:Olivier Galibert, R. Belmont, Vas Crabb
/*
* font_sdl.c
*
@@ -8,19 +8,22 @@
#include "font_module.h"
#include "modules/osdmodule.h"
-#if defined(SDLMAME_UNIX) && (!defined(SDLMAME_MACOSX)) && (!defined(SDLMAME_SOLARIS)) && (!defined(SDLMAME_HAIKU)) && (!defined(SDLMAME_EMSCRIPTEN))
-
-#include <SDL2/SDL_ttf.h>
-#ifndef SDLMAME_HAIKU
-#include <fontconfig/fontconfig.h>
-#endif
-
+#if defined(SDLMAME_UNIX) && !defined(SDLMAME_MACOSX) && !defined(SDLMAME_SOLARIS) && !defined(SDLMAME_HAIKU)
#include "corestr.h"
#include "corealloc.h"
#include "fileio.h"
+#include "unicode.h"
+
+#ifdef SDLMAME_EMSCRIPTEN
+#include <SDL_ttf.h>
+#else
+#include <SDL2/SDL_ttf.h>
+#endif
+#if !defined(SDLMAME_HAIKU) && !defined(SDLMAME_EMSCRIPTEN)
+#include <fontconfig/fontconfig.h>
+#endif
-#define POINT_SIZE 144.0
//-------------------------------------------------
// font_open - attempt to "open" a handle to the
@@ -30,63 +33,78 @@
class osd_font_sdl : public osd_font
{
public:
- virtual ~osd_font_sdl() { }
+ osd_font_sdl() : m_font(nullptr, &TTF_CloseFont) { }
+ osd_font_sdl(osd_font_sdl &&obj) : m_font(std::move(obj.m_font)) { }
+ virtual ~osd_font_sdl() { close(); }
- virtual bool open(const char *font_path, const char *name, int &height);
+ virtual bool open(std::string const &font_path, std::string const &name, int &height);
virtual void close();
- virtual bool get_bitmap(unicode_char chnum, bitmap_argb32 &bitmap, INT32 &width, INT32 &xoffs, INT32 &yoffs);
+ virtual bool get_bitmap(unicode_char chnum, bitmap_argb32 &bitmap, std::int32_t &width, std::int32_t &xoffs, std::int32_t &yoffs);
+
+ osd_font_sdl & operator=(osd_font_sdl &&obj)
+ {
+ using std::swap;
+ swap(m_font, obj.m_font);
+ return *this;
+ }
+
private:
-#ifndef SDLMAME_HAIKU
- TTF_Font *search_font_config(std::string name, bool bold, bool italic, bool underline, bool &bakedstyles);
+ typedef std::unique_ptr<TTF_Font, void (*)(TTF_Font *)> TTF_Font_ptr;
+
+ osd_font_sdl(osd_font_sdl const &) = delete;
+ osd_font_sdl & operator=(osd_font_sdl const &) = delete;
+
+ static constexpr double POINT_SIZE = 144.0;
+
+#if !defined(SDLMAME_HAIKU) && !defined(SDLMAME_EMSCRIPTEN)
+ TTF_Font_ptr search_font_config(std::string const &family, std::string const &style, bool &bakedstyles);
#endif
- bool BDF_Check_Magic(std::string name);
- TTF_Font * TTF_OpenFont_Magic(std::string name, int fsize);
- TTF_Font *m_font;
+ bool BDF_Check_Magic(std::string const &name);
+ TTF_Font_ptr TTF_OpenFont_Magic(std::string const &name, int fsize, long index);
+
+ TTF_Font_ptr m_font;
};
-bool osd_font_sdl::open(const char *font_path, const char *_name, int &height)
+bool osd_font_sdl::open(std::string const &font_path, std::string const &_name, int &height)
{
- TTF_Font *font = (TTF_Font *)NULL;
bool bakedstyles = false;
- int style = 0;
- // accept qualifiers from the name
std::string name(_name);
-
- if (name.compare("default")==0)
+ if (name.compare("default") == 0)
{
- name = "Liberation Sans";
+ name = "Liberation Sans|Regular";
}
- bool bold = (strreplace(name, "[B]", "") + strreplace(name, "[b]", "") > 0);
- bool italic = (strreplace(name, "[I]", "") + strreplace(name, "[i]", "") > 0);
- bool underline = (strreplace(name, "[U]", "") + strreplace(name, "[u]", "") > 0);
- bool strike = (strreplace(name, "[S]", "") + strreplace(name, "[s]", "") > 0);
+ // accept qualifiers from the name
+ bool const underline = (strreplace(name, "[U]", "") + strreplace(name, "[u]", "") > 0);
+ bool const strike = (strreplace(name, "[S]", "") + strreplace(name, "[s]", "") > 0);
+ std::string::size_type const separator = name.rfind('|');
+ std::string const family(name.substr(0, separator));
+ std::string const style((std::string::npos != separator) ? name.substr(separator + 1) : std::string());
// first up, try it as a filename
- font = TTF_OpenFont_Magic(name, POINT_SIZE);
+ TTF_Font_ptr font = TTF_OpenFont_Magic(family, POINT_SIZE, 0);
// if no success, try the font path
-
if (!font)
{
- osd_printf_verbose("Searching font %s in -%s\n", name.c_str(), OPTION_FONTPATH);
+ osd_printf_verbose("Searching font %s in -%s\n", family.c_str(), OPTION_FONTPATH);
//emu_file file(options().font_path(), OPEN_FLAG_READ);
- emu_file file(font_path, OPEN_FLAG_READ);
- if (file.open(name.c_str()) == FILERR_NONE)
+ emu_file file(font_path.c_str(), OPEN_FLAG_READ);
+ if (file.open(family.c_str()) == osd_file::error::NONE)
{
std::string full_name = file.fullpath();
- font = TTF_OpenFont_Magic(full_name, POINT_SIZE);
+ font = TTF_OpenFont_Magic(full_name, POINT_SIZE, 0);
if (font)
osd_printf_verbose("Found font %s\n", full_name.c_str());
}
}
// if that didn't work, crank up the FontConfig database
-#ifndef SDLMAME_HAIKU
+#if !defined(SDLMAME_HAIKU) && !defined(SDLMAME_EMSCRIPTEN)
if (!font)
{
- font = search_font_config(name, bold, italic, underline, bakedstyles);
+ font = search_font_config(family, style, bakedstyles);
}
#endif
@@ -96,28 +114,29 @@ bool osd_font_sdl::open(const char *font_path, const char *_name, int &height)
{
osd_printf_verbose("font %s is not TrueType or BDF, using MAME default\n", name.c_str());
}
- return NULL;
+ return false;
}
// apply styles
+ int styleflags = 0;
if (!bakedstyles)
{
- style |= bold ? TTF_STYLE_BOLD : 0;
- style |= italic ? TTF_STYLE_ITALIC : 0;
+ if ((style.find("Bold") != std::string::npos) || (style.find("Black") != std::string::npos)) styleflags |= TTF_STYLE_BOLD;
+ if ((style.find("Italic") != std::string::npos) || (style.find("Oblique") != std::string::npos)) styleflags |= TTF_STYLE_ITALIC;
}
- style |= underline ? TTF_STYLE_UNDERLINE : 0;
+ styleflags |= underline ? TTF_STYLE_UNDERLINE : 0;
// SDL_ttf 2.0.9 and earlier does not define TTF_STYLE_STRIKETHROUGH
#if SDL_VERSIONNUM(TTF_MAJOR_VERSION, TTF_MINOR_VERSION, TTF_PATCHLEVEL) > SDL_VERSIONNUM(2,0,9)
- style |= strike ? TTF_STYLE_STRIKETHROUGH : 0;
+ styleflags |= strike ? TTF_STYLE_STRIKETHROUGH : 0;
#else
if (strike)
osd_printf_warning("Ignoring strikethrough for SDL_TTF older than 2.0.10\n");
#endif // PATCHLEVEL
- TTF_SetFontStyle(font, style);
+ TTF_SetFontStyle(font.get(), styleflags);
- height = TTF_FontLineSkip(font);
+ height = TTF_FontLineSkip(font.get());
- m_font = font;
+ m_font = std::move(font);
return true;
}
@@ -128,7 +147,7 @@ bool osd_font_sdl::open(const char *font_path, const char *_name, int &height)
void osd_font_sdl::close()
{
- TTF_CloseFont(this->m_font);
+ m_font.reset();
}
//-------------------------------------------------
@@ -139,18 +158,12 @@ void osd_font_sdl::close()
// pixel of a black & white font
//-------------------------------------------------
-bool osd_font_sdl::get_bitmap(unicode_char chnum, bitmap_argb32 &bitmap, INT32 &width, INT32 &xoffs, INT32 &yoffs)
+bool osd_font_sdl::get_bitmap(unicode_char chnum, bitmap_argb32 &bitmap, std::int32_t &width, std::int32_t &xoffs, std::int32_t &yoffs)
{
- TTF_Font *ttffont;
- SDL_Surface *drawsurf;
- SDL_Color fcol = { 0xff, 0xff, 0xff };
- UINT16 ustr[16];
-
- ttffont = m_font;
-
- memset(ustr,0,sizeof(ustr));
- ustr[0] = (UINT16)chnum;
- drawsurf = TTF_RenderUNICODE_Solid(ttffont, ustr, fcol);
+ SDL_Color const fcol = { 0xff, 0xff, 0xff };
+ char ustr[16];
+ ustr[utf8_from_uchar(ustr, ARRAY_LENGTH(ustr), chnum)] = '\0';
+ std::unique_ptr<SDL_Surface, void (*)(SDL_Surface *)> const drawsurf(TTF_RenderUTF8_Solid(m_font.get(), ustr, fcol), &SDL_FreeSurface);
// was nothing returned?
if (drawsurf)
@@ -161,163 +174,119 @@ bool osd_font_sdl::get_bitmap(unicode_char chnum, bitmap_argb32 &bitmap, INT32 &
// copy the rendered character image into it
for (int y = 0; y < bitmap.height(); y++)
{
- UINT32 *dstrow = &bitmap.pix32(y);
- UINT8 *srcrow = (UINT8 *)drawsurf->pixels;
-
- srcrow += (y * drawsurf->pitch);
+ std::uint32_t *const dstrow = &bitmap.pix32(y);
+ std::uint8_t const *const srcrow = reinterpret_cast<std::uint8_t const *>(drawsurf->pixels) + (y * drawsurf->pitch);
for (int x = 0; x < drawsurf->w; x++)
{
- dstrow[x] = srcrow[x] ? rgb_t(0xff,0xff,0xff,0xff) : rgb_t(0x00,0xff,0xff,0xff);
+ dstrow[x] = srcrow[x] ? rgb_t(0xff, 0xff, 0xff, 0xff) : rgb_t(0x00, 0xff, 0xff, 0xff);
}
}
// what are these?
xoffs = yoffs = 0;
width = drawsurf->w;
-
- SDL_FreeSurface(drawsurf);
}
return bitmap.valid();
}
-TTF_Font * osd_font_sdl::TTF_OpenFont_Magic(std::string name, int fsize)
+osd_font_sdl::TTF_Font_ptr osd_font_sdl::TTF_OpenFont_Magic(std::string const &name, int fsize, long index)
{
emu_file file(OPEN_FLAG_READ);
- if (file.open(name.c_str()) == FILERR_NONE)
+ if (file.open(name.c_str()) == osd_file::error::NONE)
{
- unsigned char buffer[5] = { 0xff, 0xff, 0xff, 0xff, 0xff };
- unsigned char magic[5] = { 0x00, 0x01, 0x00, 0x00, 0x00 };
- file.read(buffer,5);
- if (memcmp(buffer, magic, 5))
- return NULL;
+ unsigned char const ttf_magic[] = { 0x00, 0x01, 0x00, 0x00, 0x00 };
+ unsigned char const ttc1_magic[] = { 0x74, 0x74, 0x63, 0x66, 0x00, 0x01, 0x00, 0x00 };
+ unsigned char const ttc2_magic[] = { 0x74, 0x74, 0x63, 0x66, 0x00, 0x02, 0x00, 0x00 };
+ auto buffer_size = std::max({ sizeof(ttf_magic), sizeof(ttc1_magic), sizeof(ttc2_magic) });
+ unsigned char buffer[buffer_size];
+ auto const bytes_read = file.read(buffer, buffer_size);
+ file.close();
+
+ if (((bytes_read >= sizeof(ttf_magic)) && !std::memcmp(buffer, ttf_magic, sizeof(ttf_magic))) ||
+ ((bytes_read >= sizeof(ttc1_magic)) && !std::memcmp(buffer, ttc1_magic, sizeof(ttc1_magic))) ||
+ ((bytes_read >= sizeof(ttc2_magic)) && !std::memcmp(buffer, ttc2_magic, sizeof(ttc2_magic))))
+ return TTF_Font_ptr(TTF_OpenFontIndex(name.c_str(), POINT_SIZE, index), &TTF_CloseFont);
}
- return TTF_OpenFont(name.c_str(), POINT_SIZE);
+ return TTF_Font_ptr(nullptr, &TTF_CloseFont);
}
-bool osd_font_sdl::BDF_Check_Magic(std::string name)
+bool osd_font_sdl::BDF_Check_Magic(std::string const &name)
{
emu_file file(OPEN_FLAG_READ);
- if (file.open(name.c_str()) == FILERR_NONE)
+ if (file.open(name.c_str()) == osd_file::error::NONE)
{
- unsigned char buffer[9];
- unsigned char magic[9] = { 'S', 'T', 'A', 'R', 'T', 'F', 'O', 'N', 'T' };
- file.read(buffer, 9);
- file.close();
- if (!memcmp(buffer, magic, 9))
+ unsigned char const magic[] = { 'S', 'T', 'A', 'R', 'T', 'F', 'O', 'N', 'T' };
+ unsigned char buffer[sizeof(magic)];
+ if ((sizeof(magic) != file.read(buffer, sizeof(magic))) || memcmp(buffer, magic, sizeof(magic)))
return true;
}
-
return false;
}
-#ifndef SDLMAME_HAIKU
-TTF_Font *osd_font_sdl::search_font_config(std::string name, bool bold, bool italic, bool underline, bool &bakedstyles)
+#if !defined(SDLMAME_HAIKU) && !defined(SDLMAME_EMSCRIPTEN)
+osd_font_sdl::TTF_Font_ptr osd_font_sdl::search_font_config(std::string const &family, std::string const &style, bool &bakedstyles)
{
- TTF_Font *font = (TTF_Font *)NULL;
- FcConfig *config;
- FcPattern *pat;
- FcObjectSet *os;
- FcFontSet *fontset;
- FcValue val;
-
- config = FcConfigGetCurrent();
- pat = FcPatternCreate();
- os = FcObjectSetCreate();
- FcPatternAddString(pat, FC_FAMILY, (const FcChar8 *)name.c_str());
+ TTF_Font_ptr font(nullptr, &TTF_CloseFont);
+
+ FcConfig *const config = FcConfigGetCurrent();
+ std::unique_ptr<FcPattern, void (*)(FcPattern *)> pat(FcPatternCreate(), &FcPatternDestroy);
+ std::unique_ptr<FcObjectSet, void (*)(FcObjectSet *)> os(FcObjectSetCreate(), &FcObjectSetDestroy);
+ FcPatternAddString(pat.get(), FC_FAMILY, (const FcChar8 *)family.c_str());
// try and get a font with the requested styles baked-in
- if (bold)
- {
- if (italic)
- {
- FcPatternAddString(pat, FC_STYLE, (const FcChar8 *)"Bold Italic");
- }
- else
- {
- FcPatternAddString(pat, FC_STYLE, (const FcChar8 *)"Bold");
- }
- }
- else if (italic)
- {
- FcPatternAddString(pat, FC_STYLE, (const FcChar8 *)"Italic");
- }
- else
- {
- FcPatternAddString(pat, FC_STYLE, (const FcChar8 *)"Regular");
- }
+ if (!style.empty())
+ FcPatternAddString(pat.get(), FC_STYLE, (const FcChar8 *)style.c_str());
- FcPatternAddString(pat, FC_FONTFORMAT, (const FcChar8 *)"TrueType");
+ FcPatternAddString(pat.get(), FC_FONTFORMAT, (const FcChar8 *)"TrueType");
- FcObjectSetAdd(os, FC_FILE);
- fontset = FcFontList(config, pat, os);
+ FcObjectSetAdd(os.get(), FC_FILE);
+ FcObjectSetAdd(os.get(), FC_INDEX);
+ std::unique_ptr<FcFontSet, void (*)(FcFontSet *)> fontset(FcFontList(config, pat.get(), os.get()), &FcFontSetDestroy);
- for (int i = 0; i < fontset->nfont; i++)
+ for (int i = 0; (i < fontset->nfont) && !font; i++)
{
- if (FcPatternGet(fontset->fonts[i], FC_FILE, 0, &val) != FcResultMatch)
+ FcValue val;
+ if ((FcPatternGet(fontset->fonts[i], FC_FILE, 0, &val) == FcResultMatch) && (val.type == FcTypeString))
{
- continue;
- }
-
- if (val.type != FcTypeString)
- {
- continue;
- }
+ osd_printf_verbose("Matching font: %s\n", val.u.s);
- osd_printf_verbose("Matching font: %s\n", val.u.s);
- {
- std::string match_name((const char*)val.u.s);
- font = TTF_OpenFont_Magic(match_name, POINT_SIZE);
- }
+ std::string const match_name((const char*)val.u.s);
+ long const index = ((FcPatternGet(fontset->fonts[i], FC_INDEX, 0, &val) == FcResultMatch) && (val.type == FcTypeInteger)) ? val.u.i : 0;
+ font = TTF_OpenFont_Magic(match_name, POINT_SIZE, index);
- if (font)
- {
- bakedstyles = true;
- break;
+ if (font)
+ bakedstyles = true;
}
}
// didn't get a font above? try again with no baked-in styles
- if (!font)
+ // note that this simply returns the first match for the family name, which could be regular if you're lucky, but it could be bold oblique or something
+ if (!font && !style.empty())
{
- FcPatternDestroy(pat);
- FcFontSetDestroy(fontset);
+ pat.reset(FcPatternCreate());
+ FcPatternAddString(pat.get(), FC_FAMILY, (const FcChar8 *)family.c_str());
+ FcPatternAddString(pat.get(), FC_FONTFORMAT, (const FcChar8 *)"TrueType");
+ fontset.reset(FcFontList(config, pat.get(), os.get()));
- pat = FcPatternCreate();
- FcPatternAddString(pat, FC_FAMILY, (const FcChar8 *)name.c_str());
- FcPatternAddString(pat, FC_STYLE, (const FcChar8 *)"Regular");
- FcPatternAddString(pat, FC_FONTFORMAT, (const FcChar8 *)"TrueType");
- fontset = FcFontList(config, pat, os);
-
- for (int i = 0; i < fontset->nfont; i++)
+ for (int i = 0; (i < fontset->nfont) && !font; i++)
{
- if (FcPatternGet(fontset->fonts[i], FC_FILE, 0, &val) != FcResultMatch)
+ FcValue val;
+ if ((FcPatternGet(fontset->fonts[i], FC_FILE, 0, &val) == FcResultMatch) && (val.type == FcTypeString))
{
- continue;
- }
+ osd_printf_verbose("Matching unstyled font: %s\n", val.u.s);
- if (val.type != FcTypeString)
- {
- continue;
- }
-
- osd_printf_verbose("Matching unstyled font: %s\n", val.u.s);
- {
- std::string match_name((const char*)val.u.s);
- font = TTF_OpenFont_Magic(match_name, POINT_SIZE);
- }
+ std::string const match_name((const char*)val.u.s);
+ long const index = ((FcPatternGet(fontset->fonts[i], FC_INDEX, 0, &val) == FcResultMatch) && (val.type == FcTypeInteger)) ? val.u.i : 0;
+ font = TTF_OpenFont_Magic(match_name, POINT_SIZE, index);
- if (font)
- {
- break;
+ if (font)
+ bakedstyles = false;
}
}
}
- FcPatternDestroy(pat);
- FcObjectSetDestroy(os);
- FcFontSetDestroy(fontset);
return font;
}
#endif
@@ -330,12 +299,12 @@ public:
{
}
- osd_font *font_alloc()
+ osd_font::ptr font_alloc() override
{
- return global_alloc(osd_font_sdl);
+ return std::make_unique<osd_font_sdl>();
}
- virtual int init(const osd_options &options)
+ virtual int init(const osd_options &options) override
{
if (TTF_Init() == -1)
{
@@ -345,13 +314,72 @@ public:
return 0;
}
- virtual void exit()
+ virtual void exit() override
{
TTF_Quit();
}
+
+ virtual bool get_font_families(std::string const &font_path, std::vector<std::pair<std::string, std::string> > &result) override;
};
+
+
+bool font_sdl::get_font_families(std::string const &font_path, std::vector<std::pair<std::string, std::string> > &result)
+{
+ result.clear();
+
+ // TODO: enumerate TTF files in font path, since we can load them, too
+
+#if !defined(SDLMAME_HAIKU) && !defined(SDLMAME_EMSCRIPTEN)
+ FcConfig *const config = FcConfigGetCurrent();
+ std::unique_ptr<FcPattern, void (*)(FcPattern *)> pat(FcPatternCreate(), &FcPatternDestroy);
+ FcPatternAddString(pat.get(), FC_FONTFORMAT, (const FcChar8 *)"TrueType");
+
+ std::unique_ptr<FcObjectSet, void (*)(FcObjectSet *)> os(FcObjectSetCreate(), &FcObjectSetDestroy);
+ FcObjectSetAdd(os.get(), FC_FAMILY);
+ FcObjectSetAdd(os.get(), FC_FILE);
+ FcObjectSetAdd(os.get(), FC_STYLE);
+
+ std::unique_ptr<FcFontSet, void (*)(FcFontSet *)> fontset(FcFontList(config, pat.get(), os.get()), &FcFontSetDestroy);
+ for (int i = 0; (i < fontset->nfont); i++)
+ {
+ FcValue val;
+ if ((FcPatternGet(fontset->fonts[i], FC_FILE, 0, &val) == FcResultMatch) &&
+ (val.type == FcTypeString) &&
+ (FcPatternGet(fontset->fonts[i], FC_FAMILY, 0, &val) == FcResultMatch) &&
+ (val.type == FcTypeString))
+ {
+ auto const compare_fonts = [](std::pair<std::string, std::string> const &a, std::pair<std::string, std::string> const &b) -> bool
+ {
+ int const second = core_stricmp(a.second.c_str(), b.second.c_str());
+ if (second < 0) return true;
+ else if (second > 0) return false;
+ else return core_stricmp(b.first.c_str(), b.first.c_str()) < 0;
+ };
+ std::string config((const char *)val.u.s);
+ std::string display(config);
+ if ((FcPatternGet(fontset->fonts[i], FC_STYLE, 0, &val) == FcResultMatch) && (val.type == FcTypeString))
+ {
+ config.push_back('|');
+ config.append((const char *)val.u.s);
+ display.push_back(' ');
+ display.append((const char *)val.u.s);
+ }
+ std::pair<std::string, std::string> font(std::move(config), std::move(display));
+ auto const pos = std::lower_bound(result.begin(), result.end(), font, compare_fonts);
+ if ((result.end() == pos) || (pos->first != font.first)) result.emplace(pos, std::move(font));
+ }
+ }
+
+ return true;
+#else
+ return false;
+#endif
+}
+
#else /* SDLMAME_UNIX */
- MODULE_NOT_SUPPORTED(font_sdl, OSD_FONT_PROVIDER, "sdl")
+
+MODULE_NOT_SUPPORTED(font_sdl, OSD_FONT_PROVIDER, "sdl")
+
#endif
MODULE_DEFINITION(FONT_SDL, font_sdl)
diff --git a/src/osd/modules/font/font_windows.cpp b/src/osd/modules/font/font_windows.cpp
index 6d561e5cddd..0de5231f8a0 100644
--- a/src/osd/modules/font/font_windows.cpp
+++ b/src/osd/modules/font/font_windows.cpp
@@ -5,49 +5,64 @@
*
*/
+#define WIN32_LEAN_AND_MEAN
+
#include "font_module.h"
#include "modules/osdmodule.h"
#if defined(OSD_WINDOWS) || defined(SDLMAME_WIN32)
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#include <commctrl.h>
-#include <mmsystem.h>
-#include <tchar.h>
-#include <io.h>
-
#include "font_module.h"
#include "modules/osdmodule.h"
#include "strconv.h"
#include "corestr.h"
#include "corealloc.h"
-#include "fileio.h"
-//#define POINT_SIZE 144.0
-#define DEFAULT_FONT_HEIGHT (200)
+#include <cstring>
+
+#include <windows.h>
+#include <commctrl.h>
+#include <mmsystem.h>
+#include <tchar.h>
+#include <io.h>
-//-------------------------------------------------
-// font_open - attempt to "open" a handle to the
-// font with the given name
-//-------------------------------------------------
+
+namespace {
class osd_font_windows : public osd_font
{
public:
osd_font_windows(): m_font(NULL) { }
- virtual ~osd_font_windows() { }
+ osd_font_windows(osd_font_windows &&obj) : m_font(obj.m_font) { obj.m_font = NULL; }
+ virtual ~osd_font_windows() {close(); }
- virtual bool open(const char *font_path, const char *name, int &height) override;
+ virtual bool open(std::string const &font_path, std::string const &name, int &height) override;
virtual void close() override;
- virtual bool get_bitmap(unicode_char chnum, bitmap_argb32 &bitmap, INT32 &width, INT32 &xoffs, INT32 &yoffs) override;
+ virtual bool get_bitmap(unicode_char chnum, bitmap_argb32 &bitmap, std::int32_t &width, std::int32_t &xoffs, std::int32_t &yoffs) override;
+
+ osd_font_windows &operator=(osd_font_windows &&obj)
+ {
+ using std::swap;
+ swap(m_font, obj.m_font);
+ return *this;
+ }
+
private:
+ osd_font_windows(osd_font_windows const &) = delete;
+ osd_font_windows &operator=(osd_font_windows const &) = delete;
+
+ //#define POINT_SIZE 144.0
+ static constexpr LONG DEFAULT_HEIGHT = 200;
+
HGDIOBJ m_font;
};
-bool osd_font_windows::open(const char *font_path, const char *_name, int &height)
+bool osd_font_windows::open(std::string const &font_path, std::string const &_name, int &height)
{
+ // don't leak a handle if we already have a font open
+ close();
+
// accept qualifiers from the name
std::string name(_name);
if (name.compare("default")==0) name = "Tahoma";
@@ -56,7 +71,7 @@ bool osd_font_windows::open(const char *font_path, const char *_name, int &heigh
// build a basic LOGFONT description of what we want
LOGFONT logfont;
- logfont.lfHeight = DEFAULT_FONT_HEIGHT;
+ logfont.lfHeight = DEFAULT_HEIGHT;
logfont.lfWidth = 0;
logfont.lfEscapement = 0;
logfont.lfOrientation = 0;
@@ -85,13 +100,19 @@ bool osd_font_windows::open(const char *font_path, const char *_name, int &heigh
// select it into a temp DC and get the real font name
HDC dummyDC = CreateCompatibleDC(NULL);
HGDIOBJ oldfont = SelectObject(dummyDC, m_font);
- TCHAR realname[100];
- GetTextFace(dummyDC, ARRAY_LENGTH(realname), realname);
+ std::vector<TCHAR> realname((std::max)(GetTextFace(dummyDC, 0, nullptr), 0));
+ int facelen = GetTextFace(dummyDC, realname.size(), &realname[0]);
SelectObject(dummyDC, oldfont);
DeleteDC(dummyDC);
+ if (facelen <= 0)
+ {
+ DeleteObject(m_font);
+ m_font = NULL;
+ return false;
+ }
// if it doesn't match our request, fail
- char *utf = utf8_from_tstring(realname);
+ char *utf = utf8_from_tstring(&realname[0]);
int result = core_stricmp(utf, name.c_str());
osd_free(utf);
@@ -115,7 +136,7 @@ void osd_font_windows::close()
// delete the font ojbect
if (m_font != NULL)
DeleteObject(m_font);
-
+ m_font = NULL;
}
//-------------------------------------------------
@@ -269,20 +290,51 @@ bool osd_font_windows::get_bitmap(unicode_char chnum, bitmap_argb32 &bitmap, INT
class font_win : public osd_module, public font_module
{
public:
- font_win() : osd_module(OSD_FONT_PROVIDER, "win"), font_module()
- {
- }
+ font_win() : osd_module(OSD_FONT_PROVIDER, "win"), font_module() { }
virtual int init(const osd_options &options) override { return 0; }
- virtual osd_font *font_alloc() override
+ virtual osd_font::ptr font_alloc() override { return std::make_unique<osd_font_windows>(); }
+
+ virtual bool get_font_families(std::string const &font_path, std::vector<std::pair<std::string, std::string> > &result) override;
+
+private:
+ static int CALLBACK font_family_callback(LOGFONT const *lpelfe, TEXTMETRIC const *lpntme, DWORD FontType, LPARAM lParam)
{
- return global_alloc(osd_font_windows);
+ auto &result = *reinterpret_cast<std::vector<std::pair<std::string, std::string> > *>(lParam);
+ char *face = utf8_from_tstring(lpelfe->lfFaceName);
+ if ((*face != '@') && (result.empty() || (result.back().first != face))) result.emplace_back(face, face);
+ osd_free(face);
+ return TRUE;
}
-
};
-#else /* SDLMAME_UNIX */
- MODULE_NOT_SUPPORTED(font_win, OSD_FONT_PROVIDER, "win")
-#endif
+
+
+bool font_win::get_font_families(std::string const &font_path, std::vector<std::pair<std::string, std::string> > &result)
+{
+ result.clear();
+
+ LOGFONT logfont;
+ std::memset(&logfont, 0, sizeof(logfont));
+ logfont.lfCharSet = DEFAULT_CHARSET;
+ logfont.lfFaceName[0] = '\0';
+ logfont.lfPitchAndFamily = 0;
+
+ HDC dummyDC = CreateCompatibleDC(nullptr);
+ HRESULT err = EnumFontFamiliesEx(dummyDC, &logfont, &font_family_callback, reinterpret_cast<LPARAM>(&result), 0);
+ DeleteDC(dummyDC);
+
+ std::stable_sort(result.begin(), result.end());
+
+ return !FAILED(err);
+}
+
+} // anonymous namespace
+
+#else // defined(OSD_WINDOWS) || defined(SDLMAME_WIN32)
+
+MODULE_NOT_SUPPORTED(font_win, OSD_FONT_PROVIDER, "win")
+
+#endif // defined(OSD_WINDOWS) || defined(SDLMAME_WIN32)
MODULE_DEFINITION(FONT_WINDOWS, font_win)
diff --git a/src/osd/modules/input/input_common.cpp b/src/osd/modules/input/input_common.cpp
index 72a0261c99a..8c0ab270696 100644
--- a/src/osd/modules/input/input_common.cpp
+++ b/src/osd/modules/input/input_common.cpp
@@ -9,10 +9,8 @@
//============================================================
#include "input_module.h"
-#include "modules/osdmodule.h"
#include "modules/lib/osdobj_common.h"
-#include <mutex>
#include <memory>
// MAME headers
@@ -200,7 +198,7 @@ keyboard_trans_table::keyboard_trans_table(std::unique_ptr<key_trans_entry[]> en
m_table_size = size;
}
-int keyboard_trans_table::lookup_mame_index(const char *scode)
+int keyboard_trans_table::lookup_mame_index(const char *scode) const
{
for (int i = 0; i < m_table_size; i++)
{
@@ -210,7 +208,7 @@ int keyboard_trans_table::lookup_mame_index(const char *scode)
return -1;
}
-input_item_id keyboard_trans_table::lookup_mame_code(const char *scode)
+input_item_id keyboard_trans_table::lookup_mame_code(const char *scode) const
{
int const index = lookup_mame_index(scode);
if (index >= 0)
@@ -222,7 +220,7 @@ input_item_id keyboard_trans_table::lookup_mame_code(const char *scode)
// Windows specific lookup methods
#if defined(OSD_WINDOWS)
-input_item_id keyboard_trans_table::map_di_scancode_to_itemid(int scancode)
+input_item_id keyboard_trans_table::map_di_scancode_to_itemid(int scancode) const
{
int tablenum;
@@ -239,7 +237,7 @@ input_item_id keyboard_trans_table::map_di_scancode_to_itemid(int scancode)
// wininput_vkey_for_mame_code
//============================================================
-int keyboard_trans_table::vkey_for_mame_code(input_code code)
+int keyboard_trans_table::vkey_for_mame_code(input_code code) const
{
// only works for keyboard switches
if (code.device_class() == DEVICE_CLASS_KEYBOARD && code.item_class() == ITEM_CLASS_SWITCH)
diff --git a/src/osd/modules/input/input_common.h b/src/osd/modules/input/input_common.h
index 23d9c958c8c..d122762f791 100644
--- a/src/osd/modules/input/input_common.h
+++ b/src/osd/modules/input/input_common.h
@@ -13,7 +13,6 @@
#include <memory>
#include <chrono>
-#include <string>
#include <queue>
//============================================================
@@ -407,12 +406,12 @@ public:
UINT32 size() { return m_table_size; }
// public methods
- input_item_id lookup_mame_code(const char * scode);
- int lookup_mame_index(const char * scode);
+ input_item_id lookup_mame_code(const char * scode) const;
+ int lookup_mame_index(const char * scode) const;
#if defined(OSD_WINDOWS)
- input_item_id map_di_scancode_to_itemid(int di_scancode);
- int vkey_for_mame_code(input_code code);
+ input_item_id map_di_scancode_to_itemid(int di_scancode) const;
+ int vkey_for_mame_code(input_code code) const;
#endif
static keyboard_trans_table& instance()
@@ -444,7 +443,8 @@ public:
m_input_enabled(FALSE),
m_mouse_enabled(FALSE),
m_lightgun_enabled(FALSE),
- m_input_paused(FALSE)
+ m_input_paused(FALSE),
+ m_options(nullptr)
{
}
diff --git a/src/osd/modules/input/input_dinput.cpp b/src/osd/modules/input/input_dinput.cpp
index a56f913854d..6f581b0839a 100644
--- a/src/osd/modules/input/input_dinput.cpp
+++ b/src/osd/modules/input/input_dinput.cpp
@@ -14,8 +14,8 @@
// standard windows headers
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
-#include <winioctl.h>
#include <tchar.h>
+#include <wrl\client.h>
// undef WINNT for dinput.h to prevent duplicate definition
#undef WINNT
@@ -28,7 +28,6 @@
// MAME headers
#include "emu.h"
#include "osdepend.h"
-#include "ui/ui.h"
#include "strconv.h"
// MAMEOS headers
@@ -39,6 +38,8 @@
#include "input_common.h"
#include "input_windows.h"
+using namespace Microsoft::WRL;
+
#define STRUCTSIZE(x) (m_dinput_version == 0x0300) ? sizeof(x##_DX3) : sizeof(x)
static INT32 dinput_joystick_pov_get_state(void *device_internal, void *item_internal);
@@ -47,7 +48,7 @@ static INT32 dinput_joystick_pov_get_state(void *device_internal, void *item_int
// dinput_set_dword_property
//============================================================
-static HRESULT dinput_set_dword_property(LPDIRECTINPUTDEVICE device, REFGUID property_guid, DWORD object, DWORD how, DWORD value)
+static HRESULT dinput_set_dword_property(ComPtr<IDirectInputDevice> device, REFGUID property_guid, DWORD object, DWORD how, DWORD value)
{
DIPROPDWORD dipdw;
@@ -57,7 +58,7 @@ static HRESULT dinput_set_dword_property(LPDIRECTINPUTDEVICE device, REFGUID pro
dipdw.diph.dwHow = how;
dipdw.dwData = value;
- return IDirectInputDevice_SetProperty(device, property_guid, &dipdw.diph);
+ return IDirectInputDevice_SetProperty(device.Get(), property_guid, &dipdw.diph);
}
//============================================================
@@ -67,10 +68,10 @@ static HRESULT dinput_set_dword_property(LPDIRECTINPUTDEVICE device, REFGUID pro
// DirectInput-specific information about a device
struct dinput_api_state
{
- LPDIRECTINPUTDEVICE device;
- LPDIRECTINPUTDEVICE2 device2;
- DIDEVCAPS caps;
- LPCDIDATAFORMAT format;
+ ComPtr<IDirectInputDevice> device;
+ ComPtr<IDirectInputDevice2> device2;
+ DIDEVCAPS caps;
+ LPCDIDATAFORMAT format;
};
class dinput_device : public device_info
@@ -80,28 +81,37 @@ public:
dinput_device(running_machine &machine, const char *name, input_device_class deviceclass, input_module &module)
: device_info(machine, name, deviceclass, module),
- dinput({0})
+ dinput({nullptr})
{
}
+ virtual ~dinput_device()
+ {
+ if (dinput.device2 != nullptr)
+ dinput.device2.Reset();
+
+ if (dinput.device != nullptr)
+ dinput.device.Reset();
+ }
+
protected:
- HRESULT poll_dinput(LPVOID pState)
+ HRESULT poll_dinput(LPVOID pState) const
{
HRESULT result;
// first poll the device, then get the state
- if (dinput.device2 != NULL)
- IDirectInputDevice2_Poll(dinput.device2);
+ if (dinput.device2 != nullptr)
+ IDirectInputDevice2_Poll(dinput.device2.Get());
// GetDeviceState returns the immediate state
- result = IDirectInputDevice_GetDeviceState(dinput.device, dinput.format->dwDataSize, pState);
+ result = IDirectInputDevice_GetDeviceState(dinput.device.Get(), dinput.format->dwDataSize, pState);
// handle lost inputs here
if (result == DIERR_INPUTLOST || result == DIERR_NOTACQUIRED)
{
- result = IDirectInputDevice_Acquire(dinput.device);
+ result = IDirectInputDevice_Acquire(dinput.device.Get());
if (result == DI_OK)
- result = IDirectInputDevice_GetDeviceState(dinput.device, dinput.format->dwDataSize, pState);
+ result = IDirectInputDevice_GetDeviceState(dinput.device.Get(), dinput.format->dwDataSize, pState);
}
return result;
@@ -137,7 +147,7 @@ public:
void reset() override
{
- memset(&keyboard, 0, sizeof(keyboard));
+ memset(&keyboard.state, 0, sizeof(keyboard.state));
}
};
@@ -148,22 +158,24 @@ public:
class dinput_module : public wininput_module
{
private:
- LPDIRECTINPUT m_dinput;
+ ComPtr<IDirectInput> m_dinput;
int m_dinput_version;
public:
dinput_module(const char* type, const char* name)
- : wininput_module(type, name)
+ : wininput_module(type, name),
+ m_dinput(nullptr),
+ m_dinput_version(0)
{
}
int init_internal() override
{
- HRESULT result = S_OK;
+ HRESULT result;
#if DIRECTINPUT_VERSION >= 0x800
m_dinput_version = DIRECTINPUT_VERSION;
- result = DirectInput8Create(GetModuleHandleUni(), m_dinput_version, IID_IDirectInput8, (void **)&m_dinput, NULL);
+ result = DirectInput8Create(GetModuleHandleUni(), m_dinput_version, IID_IDirectInput8, reinterpret_cast<void **>(m_dinput.GetAddressOf()), nullptr);
if (result != DI_OK)
{
m_dinput_version = 0;
@@ -172,17 +184,17 @@ public:
#else
// first attempt to initialize DirectInput at the current version
m_dinput_version = DIRECTINPUT_VERSION;
- result = DirectInputCreate(GetModuleHandleUni(), m_dinput_version, &m_dinput, NULL);
+ result = DirectInputCreate(GetModuleHandleUni(), m_dinput_version, m_dinput.GetAddressOf(), nullptr);
if (result != DI_OK)
{
// if that fails, try version 5
m_dinput_version = 0x0500;
- result = DirectInputCreate(GetModuleHandleUni(), m_dinput_version, &m_dinput, NULL);
+ result = DirectInputCreate(GetModuleHandleUni(), m_dinput_version, m_dinput.GetAddressOf(), nullptr);
if (result != DI_OK)
{
// if that fails, try version 3
m_dinput_version = 0x0300;
- result = DirectInputCreate(GetModuleHandleUni(), m_dinput_version, &m_dinput, NULL);
+ result = DirectInputCreate(GetModuleHandleUni(), m_dinput_version, m_dinput.GetAddressOf(), nullptr);
if (result != DI_OK)
{
m_dinput_version = 0;
@@ -198,6 +210,7 @@ public:
void exit() override
{
+ m_dinput.Reset();
wininput_module::exit();
}
@@ -205,21 +218,23 @@ public:
struct dinput_callback_context
{
- dinput_module * self;
+ dinput_module * self;
running_machine * machine;
};
static BOOL CALLBACK enum_callback(LPCDIDEVICEINSTANCE instance, LPVOID ref)
{
- return ((dinput_callback_context*)ref)->self->device_enum_callback(instance, ((dinput_callback_context*)ref)->machine);
+ auto context = static_cast<dinput_callback_context*>(ref);
+ return context->self->device_enum_callback(instance, context->machine);
}
+
void input_init(running_machine &machine) override
{
dinput_callback_context context = { this, &machine };
- HRESULT result = IDirectInput_EnumDevices(m_dinput, dinput_devclass(), enum_callback, &context, DIEDFL_ATTACHEDONLY);
+ HRESULT result = IDirectInput_EnumDevices(m_dinput.Get(), dinput_devclass(), enum_callback, &context, DIEDFL_ATTACHEDONLY);
if (result != DI_OK)
- fatalerror("DirectInput: Unable to enumerate keyboards (result=%08X)\n", (UINT32)result);
+ fatalerror("DirectInput: Unable to enumerate keyboards (result=%08X)\n", static_cast<UINT32>(result));
}
protected:
@@ -243,55 +258,55 @@ protected:
TDevice* devinfo = devicelist()->create_device<TDevice>(machine, utf8_instance_name.get(), *this);
// attempt to create a device
- result = IDirectInput_CreateDevice(m_dinput, WRAP_REFIID(instance->guidInstance), &devinfo->dinput.device, NULL);
+ result = IDirectInput_CreateDevice(m_dinput.Get(), WRAP_REFIID(instance->guidInstance), devinfo->dinput.device.GetAddressOf(), NULL);
if (result != DI_OK)
goto error;
// try to get a version 2 device for it
- result = IDirectInputDevice_QueryInterface(devinfo->dinput.device, WRAP_REFIID(IID_IDirectInputDevice2), (void **)&devinfo->dinput.device2);
+ result = IDirectInputDevice_QueryInterface(devinfo->dinput.device.Get(), WRAP_REFIID(IID_IDirectInputDevice2), reinterpret_cast<void **>(devinfo->dinput.device2.GetAddressOf()));
if (result != DI_OK)
- devinfo->dinput.device2 = NULL;
+ devinfo->dinput.device2 = nullptr;
// get the caps
devinfo->dinput.caps.dwSize = STRUCTSIZE(DIDEVCAPS);
- result = IDirectInputDevice_GetCapabilities(devinfo->dinput.device, &devinfo->dinput.caps);
+ result = IDirectInputDevice_GetCapabilities(devinfo->dinput.device.Get(), &devinfo->dinput.caps);
if (result != DI_OK)
goto error;
// attempt to set the data format
devinfo->dinput.format = format1;
- result = IDirectInputDevice_SetDataFormat(devinfo->dinput.device, devinfo->dinput.format);
+ result = IDirectInputDevice_SetDataFormat(devinfo->dinput.device.Get(), devinfo->dinput.format);
if (result != DI_OK)
{
// use the secondary format if available
- if (format2 != NULL)
+ if (format2 != nullptr)
{
devinfo->dinput.format = format2;
- result = IDirectInputDevice_SetDataFormat(devinfo->dinput.device, devinfo->dinput.format);
+ result = IDirectInputDevice_SetDataFormat(devinfo->dinput.device.Get(), devinfo->dinput.format);
}
if (result != DI_OK)
goto error;
}
// set the cooperative level
- result = IDirectInputDevice_SetCooperativeLevel(devinfo->dinput.device, win_window_list->m_hwnd, cooperative_level);
+ result = IDirectInputDevice_SetCooperativeLevel(devinfo->dinput.device.Get(), win_window_list->m_hwnd, cooperative_level);
if (result != DI_OK)
goto error;
return devinfo;
error:
devicelist()->free_device(devinfo);
- return NULL;
+ return nullptr;
}
- std::string device_item_name(dinput_device * devinfo, int offset, const char * defstring, const TCHAR * suffix)
+ std::string device_item_name(dinput_device * devinfo, int offset, const char * defstring, const TCHAR * suffix) const
{
DIDEVICEOBJECTINSTANCE instance = { 0 };
HRESULT result;
// query the key name
instance.dwSize = STRUCTSIZE(DIDEVICEOBJECTINSTANCE);
- result = IDirectInputDevice_GetObjectInfo(devinfo->dinput.device, &instance, offset, DIPH_BYOFFSET);
+ result = IDirectInputDevice_GetObjectInfo(devinfo->dinput.device.Get(), &instance, offset, DIPH_BYOFFSET);
// if we got an error and have no default string, just return NULL
if (result != DI_OK)
@@ -348,13 +363,13 @@ public:
BOOL device_enum_callback(LPCDIDEVICEINSTANCE instance, LPVOID ref) override
{
- running_machine &machine = *(running_machine *)ref;
+ running_machine &machine = *static_cast<running_machine *>(ref);
dinput_keyboard_device *devinfo;
int keynum;
// allocate and link in a new device
- devinfo = create_dinput_device<dinput_keyboard_device>(machine, instance, &c_dfDIKeyboard, NULL, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE);
- if (devinfo == NULL)
+ devinfo = create_dinput_device<dinput_keyboard_device>(machine, instance, &c_dfDIKeyboard, nullptr, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE);
+ if (devinfo == nullptr)
goto exit;
// populate it
@@ -366,7 +381,7 @@ public:
// generate/fetch the name
snprintf(defname, ARRAY_LENGTH(defname), "Scan%03d", keynum);
- name = device_item_name(devinfo, keynum, defname, NULL);
+ name = device_item_name(devinfo, keynum, defname, nullptr);
// add the item to the device
devinfo->device()->add_item(name.c_str(), itemid, generic_button_get_state, &devinfo->keyboard.state[keynum]);
@@ -424,14 +439,14 @@ public:
BOOL device_enum_callback(LPCDIDEVICEINSTANCE instance, LPVOID ref) override
{
- dinput_mouse_device *devinfo = NULL;
- running_machine &machine = *(running_machine *)ref;
+ dinput_mouse_device *devinfo = nullptr;
+ running_machine &machine = *static_cast<running_machine *>(ref);
int axisnum, butnum;
HRESULT result;
// allocate and link in a new device
devinfo = create_dinput_device<dinput_mouse_device>(machine, instance, &c_dfDIMouse2, &c_dfDIMouse, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE);
- if (devinfo == NULL)
+ if (devinfo == nullptr)
goto exit;
// set relative mode on the mouse device
@@ -450,25 +465,25 @@ public:
for (axisnum = 0; axisnum < devinfo->dinput.caps.dwAxes; axisnum++)
{
// add to the mouse device and optionally to the gun device as well
- std::string name = device_item_name(devinfo, offsetof(DIMOUSESTATE, lX) + axisnum * sizeof(LONG), default_axis_name[axisnum], NULL);
- devinfo->device()->add_item(name.c_str(), (input_item_id)(ITEM_ID_XAXIS + axisnum), generic_axis_get_state, &devinfo->mouse.lX + axisnum);
+ std::string name = device_item_name(devinfo, offsetof(DIMOUSESTATE, lX) + axisnum * sizeof(LONG), default_axis_name[axisnum], nullptr);
+ devinfo->device()->add_item(name.c_str(), static_cast<input_item_id>(ITEM_ID_XAXIS + axisnum), generic_axis_get_state, &devinfo->mouse.lX + axisnum);
}
// populate the buttons
for (butnum = 0; butnum < devinfo->dinput.caps.dwButtons; butnum++)
{
- FPTR offset = (FPTR)(&((DIMOUSESTATE *)NULL)->rgbButtons[butnum]);
+ FPTR offset = reinterpret_cast<FPTR>(&static_cast<DIMOUSESTATE *>(nullptr)->rgbButtons[butnum]);
// add to the mouse device
- std::string name = device_item_name(devinfo, offset, default_button_name(butnum), NULL);
- devinfo->device()->add_item(name.c_str(), (input_item_id)(ITEM_ID_BUTTON1 + butnum), generic_button_get_state, &devinfo->mouse.rgbButtons[butnum]);
+ std::string name = device_item_name(devinfo, offset, default_button_name(butnum), nullptr);
+ devinfo->device()->add_item(name.c_str(), static_cast<input_item_id>(ITEM_ID_BUTTON1 + butnum), generic_button_get_state, &devinfo->mouse.rgbButtons[butnum]);
}
exit:
return DIENUM_CONTINUE;
error:
- if (devinfo != NULL)
+ if (devinfo != nullptr)
devicelist()->free_device(devinfo);
goto exit;
}
@@ -495,7 +510,7 @@ public:
void reset() override
{
- memset(&joystick, 0, sizeof(joystick));
+ memset(&joystick.state, 0, sizeof(joystick.state));
}
void poll() override
@@ -503,7 +518,8 @@ public:
int axisnum;
// poll the device first
- dinput_device::poll_dinput(&joystick.state);
+ if (dinput_device::poll_dinput(&joystick.state) != ERROR_SUCCESS)
+ return;
// normalize axis values
for (axisnum = 0; axisnum < 8; axisnum++)
@@ -535,16 +551,16 @@ public:
{
DWORD cooperative_level = DISCL_FOREGROUND | DISCL_NONEXCLUSIVE;
int axisnum, axiscount, povnum, butnum;
- running_machine &machine = *(running_machine *)ref;
+ running_machine &machine = *static_cast<running_machine *>(ref);
dinput_joystick_device *devinfo;
HRESULT result;
- if (win_window_list != NULL && win_window_list->win_has_menu()) {
+ if (win_window_list != nullptr && win_window_list->win_has_menu()) {
cooperative_level = DISCL_BACKGROUND | DISCL_NONEXCLUSIVE;
}
// allocate and link in a new device
- devinfo = create_dinput_device<dinput_joystick_device>(machine, instance, &c_dfDIJoystick, NULL, cooperative_level);
- if (devinfo == NULL)
+ devinfo = create_dinput_device<dinput_joystick_device>(machine, instance, &c_dfDIJoystick, nullptr, cooperative_level);
+ if (devinfo == nullptr)
goto exit;
// set absolute mode
@@ -578,7 +594,7 @@ public:
dipr.diph.dwHeaderSize = sizeof(dipr.diph);
dipr.diph.dwObj = offsetof(DIJOYSTATE2, lX) + axisnum * sizeof(LONG);
dipr.diph.dwHow = DIPH_BYOFFSET;
- result = IDirectInputDevice_GetProperty(devinfo->dinput.device, DIPROP_RANGE, &dipr.diph);
+ result = IDirectInputDevice_GetProperty(devinfo->dinput.device.Get(), DIPROP_RANGE, &dipr.diph);
if (result != DI_OK)
continue;
@@ -586,8 +602,8 @@ public:
devinfo->joystick.rangemax[axisnum] = dipr.lMax;
// populate the item description as well
- name = device_item_name(devinfo, offsetof(DIJOYSTATE2, lX) + axisnum * sizeof(LONG), default_axis_name[axisnum], NULL);
- devinfo->device()->add_item(name.c_str(), (input_item_id)(ITEM_ID_XAXIS + axisnum), generic_axis_get_state, &devinfo->joystick.state.lX + axisnum);
+ name = device_item_name(devinfo, offsetof(DIJOYSTATE2, lX) + axisnum * sizeof(LONG), default_axis_name[axisnum], nullptr);
+ devinfo->device()->add_item(name.c_str(), static_cast<input_item_id>(ITEM_ID_XAXIS + axisnum), generic_axis_get_state, &devinfo->joystick.state.lX + axisnum);
axiscount++;
}
@@ -599,33 +615,33 @@ public:
// left
name = device_item_name(devinfo, offsetof(DIJOYSTATE2, rgdwPOV) + povnum * sizeof(DWORD), default_pov_name(povnum), TEXT("L"));
- devinfo->device()->add_item(name.c_str(), ITEM_ID_OTHER_SWITCH, dinput_joystick_pov_get_state, (void *)(FPTR)(povnum * 4 + POVDIR_LEFT));
+ devinfo->device()->add_item(name.c_str(), ITEM_ID_OTHER_SWITCH, dinput_joystick_pov_get_state, reinterpret_cast<void *>(static_cast<FPTR>(povnum * 4 + POVDIR_LEFT)));
// right
name = device_item_name(devinfo, offsetof(DIJOYSTATE2, rgdwPOV) + povnum * sizeof(DWORD), default_pov_name(povnum), TEXT("R"));
- devinfo->device()->add_item(name.c_str(), ITEM_ID_OTHER_SWITCH, dinput_joystick_pov_get_state, (void *)(FPTR)(povnum * 4 + POVDIR_RIGHT));
+ devinfo->device()->add_item(name.c_str(), ITEM_ID_OTHER_SWITCH, dinput_joystick_pov_get_state, reinterpret_cast<void *>(static_cast<FPTR>(povnum * 4 + POVDIR_RIGHT)));
// up
name = device_item_name(devinfo, offsetof(DIJOYSTATE2, rgdwPOV) + povnum * sizeof(DWORD), default_pov_name(povnum), TEXT("U"));
- devinfo->device()->add_item(name.c_str(), ITEM_ID_OTHER_SWITCH, dinput_joystick_pov_get_state, (void *)(FPTR)(povnum * 4 + POVDIR_UP));
+ devinfo->device()->add_item(name.c_str(), ITEM_ID_OTHER_SWITCH, dinput_joystick_pov_get_state, reinterpret_cast<void *>(static_cast<FPTR>(povnum * 4 + POVDIR_UP)));
// down
name = device_item_name(devinfo, offsetof(DIJOYSTATE2, rgdwPOV) + povnum * sizeof(DWORD), default_pov_name(povnum), TEXT("D"));
- devinfo->device()->add_item(name.c_str(), ITEM_ID_OTHER_SWITCH, dinput_joystick_pov_get_state, (void *)(FPTR)(povnum * 4 + POVDIR_DOWN));
+ devinfo->device()->add_item(name.c_str(), ITEM_ID_OTHER_SWITCH, dinput_joystick_pov_get_state, reinterpret_cast<void *>(static_cast<FPTR>(povnum * 4 + POVDIR_DOWN)));
}
// populate the buttons
for (butnum = 0; butnum < devinfo->dinput.caps.dwButtons; butnum++)
{
- FPTR offset = (FPTR)(&((DIJOYSTATE2 *)NULL)->rgbButtons[butnum]);
- std::string name = device_item_name(devinfo, offset, default_button_name(butnum), NULL);
+ FPTR offset = reinterpret_cast<FPTR>(&static_cast<DIJOYSTATE2 *>(nullptr)->rgbButtons[butnum]);
+ std::string name = device_item_name(devinfo, offset, default_button_name(butnum), nullptr);
input_item_id itemid;
if (butnum < INPUT_MAX_BUTTONS)
- itemid = (input_item_id)(ITEM_ID_BUTTON1 + butnum);
+ itemid = static_cast<input_item_id>(ITEM_ID_BUTTON1 + butnum);
else if (butnum < INPUT_MAX_BUTTONS + INPUT_MAX_ADD_SWITCH)
- itemid = (input_item_id)(ITEM_ID_ADD_SWITCH1 - INPUT_MAX_BUTTONS + butnum);
+ itemid = static_cast<input_item_id>(ITEM_ID_ADD_SWITCH1 - INPUT_MAX_BUTTONS + butnum);
else
itemid = ITEM_ID_OTHER_SWITCH;
@@ -643,9 +659,9 @@ public:
static INT32 dinput_joystick_pov_get_state(void *device_internal, void *item_internal)
{
- dinput_joystick_device *devinfo = (dinput_joystick_device *)device_internal;
- int povnum = (FPTR)item_internal / 4;
- int povdir = (FPTR)item_internal % 4;
+ dinput_joystick_device *devinfo = static_cast<dinput_joystick_device *>(device_internal);
+ int povnum = reinterpret_cast<FPTR>(item_internal) / 4;
+ int povdir = reinterpret_cast<FPTR>(item_internal) % 4;
INT32 result = 0;
DWORD pov;
diff --git a/src/osd/modules/input/input_rawinput.cpp b/src/osd/modules/input/input_rawinput.cpp
index cf17742ce58..750033ea640 100644
--- a/src/osd/modules/input/input_rawinput.cpp
+++ b/src/osd/modules/input/input_rawinput.cpp
@@ -14,16 +14,15 @@
// standard windows headers
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
-#include <winioctl.h>
#include <tchar.h>
#undef interface
#include <mutex>
+#include <functional>
// MAME headers
#include "emu.h"
#include "osdepend.h"
-#include "ui/ui.h"
#include "strconv.h"
// MAMEOS headers
@@ -50,185 +49,236 @@ typedef lazy_loaded_function_p5<INT, HRAWINPUT, UINT, LPVOID, PINT, UINT> get_ra
typedef lazy_loaded_function_p4<INT, HANDLE, UINT, LPVOID, PINT> get_rawinput_device_info_ptr;
typedef lazy_loaded_function_p3<BOOL, PCRAWINPUTDEVICE, UINT, UINT> register_rawinput_devices_ptr;
+class safe_regkey
+{
+private:
+ HKEY m_key;
+
+public:
+ safe_regkey()
+ : m_key(nullptr)
+ {
+ }
+
+ explicit safe_regkey(HKEY key)
+ : m_key(key)
+ {
+ }
+
+ bool valid() const { return m_key != nullptr; }
+
+ void close()
+ {
+ if (m_key != nullptr)
+ {
+ RegCloseKey(m_key);
+ m_key = nullptr;
+ }
+ }
+
+ ~safe_regkey()
+ {
+ close();
+ }
+
+ operator HKEY() const { return m_key; }
+};
+
+//============================================================
+// reg_open_key
+//============================================================
+
+static safe_regkey reg_open_key(HKEY basekey, const std::wstring &subkey)
+{
+ HKEY key;
+ if (RegOpenKeyEx(basekey, subkey.c_str(), 0, KEY_READ, &key) == ERROR_SUCCESS)
+ return safe_regkey(key);
+
+ return safe_regkey();
+
+}
+
+//============================================================
+// reg_enum_key
+//============================================================
+
+static std::wstring reg_enum_key(HKEY key, int index)
+{
+ WCHAR keyname[MAX_PATH];
+ DWORD namelen;
+ if (RegEnumKeyEx(key, index, keyname, &namelen, nullptr, nullptr, nullptr, nullptr) == ERROR_SUCCESS)
+ return std::wstring(keyname, namelen);
+
+ return std::wstring();
+}
+
//============================================================
// reg_query_string
//============================================================
-static TCHAR *reg_query_string(HKEY key, const TCHAR *path)
+static std::wstring reg_query_string(HKEY key, const TCHAR *path)
{
- TCHAR *buffer;
DWORD datalen;
LONG result;
// first query to get the length
- result = RegQueryValueEx(key, path, NULL, NULL, NULL, &datalen);
+ result = RegQueryValueEx(key, path, nullptr, nullptr, nullptr, &datalen);
if (result != ERROR_SUCCESS)
- return NULL;
+ return std::wstring();
// allocate a buffer
- buffer = global_alloc_array(TCHAR, datalen + sizeof(*buffer));
- buffer[datalen / sizeof(*buffer)] = 0;
+ auto buffer = std::make_unique<TCHAR[]>(datalen + sizeof(TCHAR));
+ buffer[datalen / sizeof(TCHAR)] = 0;
// now get the actual data
- result = RegQueryValueEx(key, path, NULL, NULL, (LPBYTE)buffer, &datalen);
+ result = RegQueryValueEx(key, path, nullptr, nullptr, reinterpret_cast<LPBYTE>(buffer.get()), &datalen);
if (result == ERROR_SUCCESS)
- return buffer;
+ return std::wstring(buffer.get());
- // otherwise return a NULL buffer
- global_free_array(buffer);
- return NULL;
+ // otherwise return an empty string
+ return std::wstring();
}
-//============================================================
-// rawinput_device_improve_name
-//============================================================
-
-static TCHAR *rawinput_device_improve_name(TCHAR *name)
+static std::wstring trim_prefix(const std::wstring &devicename)
{
- static const TCHAR usbbasepath[] = TEXT("SYSTEM\\CurrentControlSet\\Enum\\USB");
- static const TCHAR basepath[] = TEXT("SYSTEM\\CurrentControlSet\\Enum\\");
- TCHAR *regstring = NULL;
- TCHAR *parentid = NULL;
- TCHAR *regpath = NULL;
- const TCHAR *chsrc;
- HKEY regkey = NULL;
- int usbindex;
- TCHAR *chdst;
- LONG result;
+ // remove anything prior to the final semicolon
+ auto semicolon_index = devicename.find_last_of(';');
+ if (semicolon_index != std::wstring::npos)
+ return devicename.substr(semicolon_index + 1);
- // The RAW name received is formatted as:
- // \??\type-id#hardware-id#instance-id#{DeviceClasses-id}
- // XP starts with "\??\"
- // Vista64 starts with "\\?\"
+ return devicename;
+}
- // ensure the name is something we can handle
- if (_tcsncmp(name, TEXT("\\\\?\\"), 4) != 0 && _tcsncmp(name, TEXT("\\??\\"), 4) != 0)
- return name;
+static std::wstring compute_device_regpath(const std::wstring &name)
+{
+ static const std::wstring basepath(L"SYSTEM\\CurrentControlSet\\Enum\\");
// allocate a temporary string and concatenate the base path plus the name
- regpath = global_alloc_array(TCHAR, _tcslen(basepath) + 1 + _tcslen(name));
- _tcscpy(regpath, basepath);
- chdst = regpath + _tcslen(regpath);
+ auto regpath_buffer = std::make_unique<TCHAR[]>(basepath.length() + 1 + name.length());
+ wcscpy(regpath_buffer.get(), basepath.c_str());
+ WCHAR * chdst = regpath_buffer.get() + basepath.length();
// convert all # to \ in the name
- for (chsrc = name + 4; *chsrc != 0; chsrc++)
- *chdst++ = (*chsrc == '#') ? '\\' : *chsrc;
+ for (int i = 4; i < name.length(); i++)
+ *chdst++ = (name[i] == '#') ? '\\' : name[i];
*chdst = 0;
// remove the final chunk
- chdst = _tcsrchr(regpath, '\\');
- if (chdst == NULL)
- goto exit;
+ chdst = wcsrchr(regpath_buffer.get(), '\\');
+ if (chdst == nullptr)
+ return std::wstring();
+
*chdst = 0;
+ return std::wstring(regpath_buffer.get());
+}
+
+static std::wstring improve_name_from_base_path(const std::wstring &regpath, bool *hid)
+{
// now try to open the registry key
- result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, regpath, 0, KEY_READ, &regkey);
- if (result != ERROR_SUCCESS)
- goto exit;
+ auto device_key = reg_open_key(HKEY_LOCAL_MACHINE, regpath);
+ if (!device_key.valid())
+ return std::wstring();
// fetch the device description; if it exists, we are finished
- regstring = reg_query_string(regkey, TEXT("DeviceDesc"));
- if (regstring != NULL)
- goto convert;
-
- // close this key
- RegCloseKey(regkey);
- regkey = NULL;
+ auto regstring = reg_query_string(device_key, L"DeviceDesc");
+ if (!regstring.empty())
+ return trim_prefix(regstring);
// if the key name does not contain "HID", it's not going to be in the USB tree; give up
- if (_tcsstr(regpath, TEXT("HID")) == NULL)
- goto exit;
+ *hid = regpath.find(L"HID") != std::string::npos;
+ return std::wstring();
+}
+
+static void foreach_subkey(HKEY key, std::function<bool(HKEY)> action)
+{
+ for (int i = 0; ; i++)
+ {
+ std::wstring name = reg_enum_key(key, i);
+ if (name.empty())
+ break;
+
+ safe_regkey subkey = reg_open_key(key, name);
+ if (!subkey.valid())
+ break;
+
+ bool shouldcontinue = action(subkey);
+ if (!shouldcontinue)
+ break;
+ }
+}
+
+static std::wstring improve_name_from_usb_path(const std::wstring &regpath)
+{
+ static const std::wstring usbbasepath(L"SYSTEM\\CurrentControlSet\\Enum\\USB");
// extract the expected parent ID from the regpath
- parentid = _tcsrchr(regpath, '\\');
- if (parentid == NULL)
- goto exit;
- parentid++;
+ size_t last_slash_index = regpath.find_last_of('\\');
+ if (last_slash_index == std::wstring::npos)
+ return std::wstring();
+
+ std::wstring parentid = regpath.substr(last_slash_index + 1);
// open the USB key
- result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, usbbasepath, 0, KEY_READ, &regkey);
- if (result != ERROR_SUCCESS)
- goto exit;
+ auto usb_key = reg_open_key(HKEY_LOCAL_MACHINE, usbbasepath);
+ if (!usb_key.valid())
+ return std::wstring();
- // enumerate the USB key
- for (usbindex = 0; result == ERROR_SUCCESS && regstring == NULL; usbindex++)
- {
- TCHAR keyname[MAX_PATH];
- DWORD namelen;
+ std::wstring regstring;
- // get the next enumerated subkey and scan it
- namelen = ARRAY_LENGTH(keyname) - 1;
- result = RegEnumKeyEx(regkey, usbindex, keyname, &namelen, NULL, NULL, NULL, NULL);
- if (result == ERROR_SUCCESS)
+ foreach_subkey(usb_key, [&regstring, &parentid](HKEY subkey)
+ {
+ foreach_subkey(subkey, [&regstring, &parentid](HKEY endkey)
{
- LONG subresult;
- int subindex;
- HKEY subkey;
+ std::wstring endparentid = reg_query_string(endkey, L"ParentIdPrefix");
+
+ // This key doesn't have a ParentIdPrefix
+ if (endparentid.empty())
+ return true;
- // open the subkey
- subresult = RegOpenKeyEx(regkey, keyname, 0, KEY_READ, &subkey);
- if (subresult != ERROR_SUCCESS)
- continue;
+ // do we have a match?
+ if (parentid.find(endparentid) == 0)
+ regstring = reg_query_string(endkey, L"DeviceDesc");
- // enumerate the subkey
- for (subindex = 0; subresult == ERROR_SUCCESS && regstring == NULL; subindex++)
- {
- // get the next enumerated subkey and scan it
- namelen = ARRAY_LENGTH(keyname) - 1;
- subresult = RegEnumKeyEx(subkey, subindex, keyname, &namelen, NULL, NULL, NULL, NULL);
- if (subresult == ERROR_SUCCESS)
- {
- TCHAR *endparentid;
- LONG endresult;
- HKEY endkey;
-
- // open this final key
- endresult = RegOpenKeyEx(subkey, keyname, 0, KEY_READ, &endkey);
- if (endresult != ERROR_SUCCESS)
- continue;
-
- // do we have a match?
- endparentid = reg_query_string(endkey, TEXT("ParentIdPrefix"));
- if (endparentid != NULL && _tcsncmp(parentid, endparentid, _tcslen(endparentid)) == 0)
- regstring = reg_query_string(endkey, TEXT("DeviceDesc"));
-
- // free memory and close the key
- if (endparentid != NULL)
- global_free_array(endparentid);
- RegCloseKey(endkey);
- }
- }
+ return regstring.empty();
+ });
- // close the subkey
- RegCloseKey(subkey);
- }
- }
+ return regstring.empty();
+ });
- // if we didn't find anything, go to the exit
- if (regstring == NULL)
- goto exit;
+ return trim_prefix(regstring);
+}
-convert:
- // replace the name with the nicer one
- global_free_array(name);
+//============================================================
+// rawinput_device_improve_name
+//============================================================
- // remove anything prior to the final semicolon
- chsrc = _tcsrchr(regstring, ';');
- if (chsrc != NULL)
- chsrc++;
- else
- chsrc = regstring;
- name = global_alloc_array(TCHAR, _tcslen(chsrc) + 1);
- _tcscpy(name, chsrc);
-
-exit:
- if (regstring != NULL)
- global_free_array(regstring);
- if (regpath != NULL)
- global_free_array(regpath);
- if (regkey != NULL)
- RegCloseKey(regkey);
+static std::wstring rawinput_device_improve_name(const std::wstring &name)
+{
+ // The RAW name received is formatted as:
+ // \??\type-id#hardware-id#instance-id#{DeviceClasses-id}
+ // XP starts with "\??\"
+ // Vista64 starts with "\\?\"
+ // ensure the name is something we can handle
+ if (name.find(L"\\\\?\\") != 0 && name.find(L"\\??\\") != 0)
+ return name;
+
+ std::wstring regpath = compute_device_regpath(name);
+
+ bool hid = false;
+ auto improved = improve_name_from_base_path(regpath, &hid);
+ if (!improved.empty())
+ return improved;
+
+ if (hid)
+ {
+ improved = improve_name_from_usb_path(regpath);
+ if (!improved.empty())
+ return improved;
+ }
+
+ // Fall back to the original name
return name;
}
@@ -244,11 +294,12 @@ private:
public:
rawinput_device(running_machine& machine, const char* name, input_device_class deviceclass, input_module& module)
- : event_based_device(machine, name, deviceclass, module)
+ : event_based_device(machine, name, deviceclass, module),
+ m_handle(nullptr)
{
}
- HANDLE device_handle() { return m_handle; }
+ HANDLE device_handle() const { return m_handle; }
void set_handle(HANDLE handle) { m_handle = handle; }
};
@@ -328,7 +379,7 @@ public:
// update zaxis
if (rawinput.data.mouse.usButtonFlags & RI_MOUSE_WHEEL)
- mouse.lZ += (INT16)rawinput.data.mouse.usButtonData * INPUT_RELATIVE_PER_PIXEL;
+ mouse.lZ += static_cast<INT16>(rawinput.data.mouse.usButtonData) * INPUT_RELATIVE_PER_PIXEL;
// update the button states; always update the corresponding mouse buttons
if (rawinput.data.mouse.usButtonFlags & RI_MOUSE_BUTTON_1_DOWN) mouse.rgbButtons[0] = 0x80;
@@ -370,7 +421,7 @@ public:
: wininput_module(type, name),
get_rawinput_device_list("GetRawInputDeviceList", L"user32.dll"),
get_rawinput_data("GetRawInputData", L"user32.dll"),
- get_rawinput_device_info("GetRawInputDeviceInfo", L"user32.dll"),
+ get_rawinput_device_info("GetRawInputDeviceInfoW", L"user32.dll"),
register_rawinput_devices("RegisterRawInputDevices", L"user32.dll")
{
}
@@ -392,7 +443,7 @@ public:
{
// get the number of devices, allocate a device list, and fetch it
int device_count = 0;
- if (get_rawinput_device_list(NULL, &device_count, sizeof(RAWINPUTDEVICELIST)) != 0)
+ if (get_rawinput_device_list(nullptr, &device_count, sizeof(RAWINPUTDEVICELIST)) != 0)
return;
if (device_count == 0)
@@ -452,10 +503,10 @@ protected:
template<class TDevice>
TDevice* create_rawinput_device(running_machine &machine, PRAWINPUTDEVICELIST rawinputdevice)
{
- TDevice* devinfo = nullptr;
+ TDevice* devinfo;
INT name_length = 0;
// determine the length of the device name, allocate it, and fetch it if not nameless
- if (get_rawinput_device_info(rawinputdevice->hDevice, RIDI_DEVICENAME, NULL, &name_length) != 0)
+ if (get_rawinput_device_info(rawinputdevice->hDevice, RIDI_DEVICENAME, nullptr, &name_length) != 0)
return nullptr;
std::unique_ptr<TCHAR[]> tname = std::make_unique<TCHAR[]>(name_length + 1);
@@ -463,15 +514,15 @@ protected:
return nullptr;
// if this is an RDP name, skip it
- if (_tcsstr(tname.get(), TEXT("Root#RDP_")) != NULL)
+ if (_tcsstr(tname.get(), TEXT("Root#RDP_")) != nullptr)
return nullptr;
// improve the name and then allocate a device
- tname = std::unique_ptr<TCHAR[]>(rawinput_device_improve_name(tname.release()));
+ std::wstring name = rawinput_device_improve_name(tname.get());
// convert name to utf8
auto osd_deleter = [](void *ptr) { osd_free(ptr); };
- auto utf8_name = std::unique_ptr<char, decltype(osd_deleter)>(utf8_from_tstring(tname.get()), osd_deleter);
+ auto utf8_name = std::unique_ptr<char, decltype(osd_deleter)>(utf8_from_wstring(name.c_str()), osd_deleter);
devinfo = devicelist()->create_device<TDevice>(machine, utf8_name.get(), *this);
@@ -487,12 +538,12 @@ protected:
if (!input_enabled() || eventid != INPUT_EVENT_RAWINPUT)
return FALSE;
- HRAWINPUT rawinputdevice = *(HRAWINPUT*)eventdata;
+ HRAWINPUT rawinputdevice = *static_cast<HRAWINPUT*>(eventdata);
BYTE small_buffer[4096];
std::unique_ptr<BYTE[]> larger_buffer;
LPBYTE data = small_buffer;
- BOOL result = FALSE;
+ BOOL result;
int size;
// ignore if not enabled
@@ -500,7 +551,7 @@ protected:
return FALSE;
// determine the size of databuffer we need
- if (get_rawinput_data(rawinputdevice, RID_INPUT, NULL, &size, sizeof(RAWINPUTHEADER)) != 0)
+ if (get_rawinput_data(rawinputdevice, RID_INPUT, nullptr, &size, sizeof(RAWINPUTHEADER)) != 0)
return FALSE;
// if necessary, allocate a temporary buffer and fetch the data
@@ -508,12 +559,12 @@ protected:
{
larger_buffer = std::make_unique<BYTE[]>(size);
data = larger_buffer.get();
- if (data == NULL)
+ if (data == nullptr)
return FALSE;
}
// fetch the data and process the appropriate message types
- result = get_rawinput_data((HRAWINPUT)rawinputdevice, RID_INPUT, data, &size, sizeof(RAWINPUTHEADER));
+ result = get_rawinput_data(static_cast<HRAWINPUT>(rawinputdevice), RID_INPUT, data, &size, sizeof(RAWINPUTHEADER));
if (result)
{
std::lock_guard<std::mutex> scope_lock(m_module_lock);
@@ -523,11 +574,14 @@ protected:
for (int i = 0; i < devicelist()->size(); i++)
{
devinfo = dynamic_cast<rawinput_device*>(devicelist()->at(i));
- RAWINPUT *input = reinterpret_cast<RAWINPUT*>(data);
- if (input->header.hDevice == devinfo->device_handle())
+ if (devinfo)
{
- devinfo->queue_events(input, 1);
- result = TRUE;
+ RAWINPUT *input = reinterpret_cast<RAWINPUT*>(data);
+ if (input->header.hDevice == devinfo->device_handle())
+ {
+ devinfo->queue_events(input, 1);
+ result = TRUE;
+ }
}
}
}
@@ -559,7 +613,7 @@ protected:
// allocate and link in a new device
rawinput_keyboard_device *devinfo = create_rawinput_device<rawinput_keyboard_device>(machine, device);
- if (devinfo == NULL)
+ if (devinfo == nullptr)
return;
keyboard_trans_table &table = keyboard_trans_table::instance();
@@ -606,19 +660,19 @@ protected:
// allocate and link in a new device
rawinput_mouse_device *devinfo = create_rawinput_device<rawinput_mouse_device>(machine, device);
- if (devinfo == NULL)
+ if (devinfo == nullptr)
return;
// populate the axes
for (int axisnum = 0; axisnum < 3; axisnum++)
{
- devinfo->device()->add_item(default_axis_name[axisnum], (input_item_id)(ITEM_ID_XAXIS + axisnum), generic_axis_get_state, &devinfo->mouse.lX + axisnum);
+ devinfo->device()->add_item(default_axis_name[axisnum], static_cast<input_item_id>(ITEM_ID_XAXIS + axisnum), generic_axis_get_state, &devinfo->mouse.lX + axisnum);
}
// populate the buttons
for (int butnum = 0; butnum < 5; butnum++)
{
- devinfo->device()->add_item(default_button_name(butnum), (input_item_id)(ITEM_ID_BUTTON1 + butnum), generic_button_get_state, &devinfo->mouse.rgbButtons[butnum]);
+ devinfo->device()->add_item(default_button_name(butnum), static_cast<input_item_id>(ITEM_ID_BUTTON1 + butnum), generic_button_get_state, &devinfo->mouse.rgbButtons[butnum]);
}
}
};
diff --git a/src/osd/modules/input/input_sdl.cpp b/src/osd/modules/input/input_sdl.cpp
index 43d4cbf6a6c..75c7c94e79f 100644
--- a/src/osd/modules/input/input_sdl.cpp
+++ b/src/osd/modules/input/input_sdl.cpp
@@ -443,7 +443,7 @@ public:
bool should_poll_devices(running_machine& machine) override
{
- return sdl_event_manager::instance().app_has_mouse_focus() && input_enabled();
+ return sdl_event_manager::instance().has_focus() && input_enabled();
}
virtual void handle_event(SDL_Event &sdlevent) override
diff --git a/src/osd/modules/input/input_sdlcommon.cpp b/src/osd/modules/input/input_sdlcommon.cpp
index e22606f9fb3..1a7aecf630e 100644
--- a/src/osd/modules/input/input_sdlcommon.cpp
+++ b/src/osd/modules/input/input_sdlcommon.cpp
@@ -79,18 +79,23 @@ void sdl_event_manager::process_window_event(running_machine &machine, SDL_Event
switch (sdlevent.window.event)
{
+ case SDL_WINDOWEVENT_SHOWN:
+ m_has_focus = true;
+ break;
+
case SDL_WINDOWEVENT_CLOSE:
machine.schedule_exit();
break;
case SDL_WINDOWEVENT_LEAVE:
machine.ui_input().push_mouse_leave_event(window->target());
- m_app_has_mouse_focus = 0;
+ m_mouse_over_window = 0;
break;
case SDL_WINDOWEVENT_MOVED:
window->notify_changed();
m_focus_window = window;
+ m_has_focus = true;
break;
case SDL_WINDOWEVENT_RESIZED:
@@ -105,16 +110,23 @@ void sdl_event_manager::process_window_event(running_machine &machine, SDL_Event
window->resize(sdlevent.window.data1, sdlevent.window.data2);
}
m_focus_window = window;
+ m_has_focus = true;
break;
case SDL_WINDOWEVENT_ENTER:
- m_app_has_mouse_focus = 1;
+ m_mouse_over_window = 1;
/* fall through */
case SDL_WINDOWEVENT_FOCUS_GAINED:
case SDL_WINDOWEVENT_EXPOSED:
case SDL_WINDOWEVENT_MAXIMIZED:
case SDL_WINDOWEVENT_RESTORED:
m_focus_window = window;
+ m_has_focus = true;
+ break;
+
+ case SDL_WINDOWEVENT_MINIMIZED:
+ case SDL_WINDOWEVENT_FOCUS_LOST:
+ m_has_focus = false;
break;
}
}
@@ -268,7 +280,7 @@ bool sdl_osd_interface::should_hide_mouse()
if (!options().mouse() && !options().lightgun())
return false;
- if (!sdl_event_manager::instance().app_has_mouse_focus())
+ if (!sdl_event_manager::instance().mouse_over_window())
return false;
// otherwise, yes
diff --git a/src/osd/modules/input/input_sdlcommon.h b/src/osd/modules/input/input_sdlcommon.h
index a4bde246967..833efb271a6 100644
--- a/src/osd/modules/input/input_sdlcommon.h
+++ b/src/osd/modules/input/input_sdlcommon.h
@@ -76,6 +76,10 @@ protected:
}
public:
+ virtual ~event_manager_t()
+ {
+ }
+
void subscribe(int* event_types, int num_event_types, TSubscriber *subscriber)
{
std::lock_guard<std::mutex> scope_lock(m_lock);
@@ -109,17 +113,20 @@ class sdl_window_info;
class sdl_event_manager : public event_manager_t<sdl_event_subscriber>
{
private:
- bool m_app_has_mouse_focus;
+ bool m_mouse_over_window;
+ bool m_has_focus;
sdl_window_info * m_focus_window;
sdl_event_manager()
- : m_app_has_mouse_focus(true),
+ : m_mouse_over_window(true),
+ m_has_focus(true),
m_focus_window(nullptr)
{
}
public:
- bool app_has_mouse_focus() { return m_app_has_mouse_focus; }
+ bool mouse_over_window() const { return m_mouse_over_window; }
+ bool has_focus() const { return m_focus_window; }
sdl_window_info * focus_window() { return m_focus_window; }
static sdl_event_manager& instance()
diff --git a/src/osd/modules/input/input_win32.cpp b/src/osd/modules/input/input_win32.cpp
index 0fb86095112..e9cfc734f2e 100644
--- a/src/osd/modules/input/input_win32.cpp
+++ b/src/osd/modules/input/input_win32.cpp
@@ -14,17 +14,11 @@
// standard windows headers
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
-#include <winioctl.h>
-#include <tchar.h>
#undef interface
-#include <mutex>
-
// MAME headers
#include "emu.h"
#include "osdepend.h"
-#include "ui/ui.h"
-#include "strconv.h"
// MAMEOS headers
#include "winmain.h"
@@ -101,13 +95,13 @@ public:
if (!input_enabled())
return FALSE;
- KeyPressEventArgs *args = nullptr;
+ KeyPressEventArgs *args;
switch (eventid)
{
case INPUT_EVENT_KEYDOWN:
case INPUT_EVENT_KEYUP:
- args = (KeyPressEventArgs*)eventdata;
+ args = static_cast<KeyPressEventArgs*>(eventdata);
for (int i = 0; i < devicelist()->size(); i++)
downcast<win32_keyboard_device*>(devicelist()->at(i))->queue_events(args, 1);
@@ -253,7 +247,8 @@ public:
win32_lightgun_device(running_machine& machine, const char *name, input_module &module)
: event_based_device(machine, name, DEVICE_CLASS_LIGHTGUN, module),
m_lightgun_shared_axis_mode(FALSE),
- m_gun_index(0)
+ m_gun_index(0),
+ mouse({0})
{
m_lightgun_shared_axis_mode = downcast<windows_options &>(machine.options()).dual_lightgun();
diff --git a/src/osd/modules/input/input_windows.cpp b/src/osd/modules/input/input_windows.cpp
index 2f7a6bc6d76..c9bc78b0ac3 100644
--- a/src/osd/modules/input/input_windows.cpp
+++ b/src/osd/modules/input/input_windows.cpp
@@ -7,30 +7,20 @@
//============================================================
#include "input_module.h"
-#include "modules/osdmodule.h"
#if defined(OSD_WINDOWS)
-// standard windows headers
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#include <winioctl.h>
-#include <tchar.h>
-#undef interface
-
// MAME headers
#include "emu.h"
#include "osdepend.h"
-#include "ui/ui.h"
// MAMEOS headers
#include "winmain.h"
-#include "window.h"
#include "input_common.h"
#include "input_windows.h"
-bool windows_osd_interface::should_hide_mouse()
+bool windows_osd_interface::should_hide_mouse() const
{
bool hidemouse = false;
hidemouse |= downcast<wininput_module*>(m_keyboard_input)->should_hide_mouse();
@@ -40,7 +30,7 @@ bool windows_osd_interface::should_hide_mouse()
return hidemouse;
}
-bool windows_osd_interface::handle_input_event(input_event eventid, void* eventdata)
+bool windows_osd_interface::handle_input_event(input_event eventid, void* eventdata) const
{
bool handled = false;
handled |= downcast<wininput_module*>(m_keyboard_input)->handle_input_event(eventid, eventdata);
@@ -50,7 +40,7 @@ bool windows_osd_interface::handle_input_event(input_event eventid, void* eventd
return handled;
}
-void windows_osd_interface::poll_input(running_machine &machine)
+void windows_osd_interface::poll_input(running_machine &machine) const
{
m_keyboard_input->poll_if_necessary(machine);
m_mouse_input->poll_if_necessary(machine);
@@ -68,7 +58,7 @@ void windows_osd_interface::customize_input_type_list(simple_list<input_type_ent
const char* uimode;
// loop over the defaults
- for (entry = typelist.first(); entry != NULL; entry = entry->next())
+ for (entry = typelist.first(); entry != nullptr; entry = entry->next())
switch (entry->type())
{
// disable the config menu if the ALT key is down
diff --git a/src/osd/modules/input/input_windows.h b/src/osd/modules/input/input_windows.h
index b79560c97a7..29133aa5999 100644
--- a/src/osd/modules/input/input_windows.h
+++ b/src/osd/modules/input/input_windows.h
@@ -9,6 +9,13 @@
#ifndef INPUT_WIN_H_
#define INPUT_WIN_H_
+// standard windows headers
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#undef interface
+
+#include "window.h"
+
//============================================================
// TYPEDEFS
//============================================================
@@ -37,7 +44,8 @@ protected:
public:
wininput_module(const char * type, const char * name)
- : input_module_base(type, name)
+ : input_module_base(type, name),
+ m_global_inputs_enabled(false)
{
}
diff --git a/src/osd/modules/input/input_x11.cpp b/src/osd/modules/input/input_x11.cpp
index 3a4073ef8c7..ef9226af3f4 100644
--- a/src/osd/modules/input/input_x11.cpp
+++ b/src/osd/modules/input/input_x11.cpp
@@ -494,7 +494,7 @@ public:
bool should_poll_devices(running_machine &machine) override
{
- return sdl_event_manager::instance().app_has_mouse_focus();
+ return sdl_event_manager::instance().has_focus();
}
void before_poll(running_machine &machine) override
diff --git a/src/osd/modules/input/input_xinput.cpp b/src/osd/modules/input/input_xinput.cpp
index b88dbe24c1a..596f79fabe4 100644
--- a/src/osd/modules/input/input_xinput.cpp
+++ b/src/osd/modules/input/input_xinput.cpp
@@ -297,13 +297,13 @@ protected:
continue;
// Add the axes
- for (int i = 0; i < XINPUT_MAX_AXIS; i++)
+ for (int axisnum = 0; axisnum < XINPUT_MAX_AXIS; axisnum++)
{
devinfo->device()->add_item(
- xinput_axis_name[i],
- xinput_axis_ids[i],
+ xinput_axis_name[axisnum],
+ xinput_axis_ids[axisnum],
generic_axis_get_state,
- &devinfo->gamepad.sThumbLX + i);
+ &devinfo->gamepad.sThumbLX + axisnum);
}
// Populate the POVs
diff --git a/src/osd/modules/lib/osdlib_unix.cpp b/src/osd/modules/lib/osdlib_unix.cpp
index 3075ea63769..fd60db54ba9 100644
--- a/src/osd/modules/lib/osdlib_unix.cpp
+++ b/src/osd/modules/lib/osdlib_unix.cpp
@@ -14,10 +14,6 @@
#include <sys/types.h>
#include <signal.h>
-#ifdef SDLMAME_EMSCRIPTEN
-#include <emscripten.h>
-#endif
-
// MAME headers
#include "osdcore.h"
#include "osdlib.h"
@@ -127,7 +123,8 @@ void osd_free_executable(void *ptr, size_t size)
void osd_break_into_debugger(const char *message)
{
- #ifdef MAME_DEBUG
+ //#ifdef MAME_DEBUG
+ #if 1
printf("MAME exception: %s\n", message);
printf("Attempting to fall into debugger\n");
kill(getpid(), SIGTRAP);
diff --git a/src/osd/modules/lib/osdobj_common.cpp b/src/osd/modules/lib/osdobj_common.cpp
index d8200463e62..abbb9241049 100644
--- a/src/osd/modules/lib/osdobj_common.cpp
+++ b/src/osd/modules/lib/osdobj_common.cpp
@@ -168,8 +168,10 @@ osd_common_t::osd_common_t(osd_options &options)
: osd_output(), m_machine(nullptr),
m_options(options),
m_print_verbose(false),
+ m_font_module(nullptr),
m_sound(nullptr),
m_debugger(nullptr),
+ m_midi(nullptr),
m_keyboard_input(nullptr),
m_mouse_input(nullptr),
m_lightgun_input(nullptr),
@@ -516,40 +518,6 @@ void osd_common_t::customize_input_type_list(simple_list<input_type_entry> &type
//-------------------------------------------------
-// font_open - attempt to "open" a handle to the
-// font with the given name
-//-------------------------------------------------
-
-osd_font *osd_common_t::font_open(const char *name, int &height)
-{
- return nullptr;
-}
-
-
-//-------------------------------------------------
-// font_close - release resources associated with
-// a given OSD font
-//-------------------------------------------------
-
-void osd_common_t::font_close(osd_font *font)
-{
-}
-
-
-//-------------------------------------------------
-// font_get_bitmap - allocate and populate a
-// BITMAP_FORMAT_ARGB32 bitmap containing the
-// pixel values rgb_t(0xff,0xff,0xff,0xff)
-// or rgb_t(0x00,0xff,0xff,0xff) for each
-// pixel of a black & white font
-//-------------------------------------------------
-
-bool osd_common_t::font_get_bitmap(osd_font *font, unicode_char chnum, bitmap_argb32 &bitmap, INT32 &width, INT32 &xoffs, INT32 &yoffs)
-{
- return false;
-}
-
-//-------------------------------------------------
// get_slider_list - allocate and populate a
// list of OS-dependent slider values.
//-------------------------------------------------
diff --git a/src/osd/modules/lib/osdobj_common.h b/src/osd/modules/lib/osdobj_common.h
index 7bf895a07b3..0b08745a22d 100644
--- a/src/osd/modules/lib/osdobj_common.h
+++ b/src/osd/modules/lib/osdobj_common.h
@@ -10,8 +10,8 @@
#pragma once
-#ifndef __OSDOBJ_COMMON_H__
-#define __OSDOBJ_COMMON__
+#ifndef MAME_OSD_LIB_OSDOBJ_COMMON_H
+#define MAME_OSD_LIB_OSDOBJ_COMMON_H
#include "osdepend.h"
#include "modules/osdmodule.h"
@@ -195,18 +195,14 @@ public:
// input overridables
virtual void customize_input_type_list(simple_list<input_type_entry> &typelist) override;
- // font overridables
- virtual osd_font *font_open(const char *name, int &height);
- virtual void font_close(osd_font *font);
- virtual bool font_get_bitmap(osd_font *font, unicode_char chnum, bitmap_argb32 &bitmap, INT32 &width, INT32 &xoffs, INT32 &yoffs);
-
// video overridables
virtual slider_state *get_slider_list() override;
// command option overrides
virtual bool execute_command(const char *command) override;
- virtual osd_font *font_alloc() override { return m_font_module->font_alloc(); }
+ virtual osd_font::ptr font_alloc() override { return m_font_module->font_alloc(); }
+ virtual bool get_font_families(std::string const &font_path, std::vector<std::pair<std::string, std::string> > &result) override { return m_font_module->get_font_families(font_path, result); }
virtual osd_midi_device *create_midi_device() override { return m_midi->create_midi_device(); }
@@ -302,4 +298,4 @@ debug_module *osd_debugger_creator()
return global_alloc(_DeviceClass());
}
-#endif /* __OSDOBJ_COMMON_H__ */
+#endif // MAME_OSD_LIB_OSDOBJ_COMMON_H
diff --git a/src/osd/modules/render/d3d/d3dcomm.h b/src/osd/modules/render/d3d/d3dcomm.h
index 28e79725cf5..51758bb70b6 100644
--- a/src/osd/modules/render/d3d/d3dcomm.h
+++ b/src/osd/modules/render/d3d/d3dcomm.h
@@ -245,7 +245,7 @@ public:
cache_target() { }
~cache_target();
- bool init(renderer_d3d9 *d3d, d3d_base *d3dintf, int width, int height, int prescale_x, int prescale_y);
+ bool init(renderer_d3d9 *d3d, d3d_base *d3dintf, int source_width, int source_height, int target_width, int target_height);
surface *last_target;
texture *last_texture;
@@ -270,31 +270,34 @@ public:
d3d_render_target() { }
~d3d_render_target();
- bool init(renderer_d3d9 *d3d, d3d_base *d3dintf, int width, int height, int prescale_x, int prescale_y);
+ bool init(renderer_d3d9 *d3d, d3d_base *d3dintf, int source_width, int source_height, int target_width, int target_height);
int next_index(int index) { return ++index > 1 ? 0 : index; }
+ // real target dimension
int target_width;
int target_height;
- int prescale_x;
- int prescale_y;
-
+ // only used to identify/find the render target
int width;
int height;
int screen_index;
int page_index;
- surface *prescale_target[2];
- texture *prescale_texture[2];
- surface *native_target[2];
- texture *native_texture[2];
+ surface *target_surface[2];
+ texture *target_texture[2];
+ surface *source_surface[2];
+ texture *source_texture[2];
d3d_render_target *next;
d3d_render_target *prev;
- surface *bloom_target[11];
+ surface *bloom_surface[11];
texture *bloom_texture[11];
+
+ float bloom_dims[11][2];
+
+ int bloom_count;
};
#endif
diff --git a/src/osd/modules/render/d3d/d3dhlsl.cpp b/src/osd/modules/render/d3d/d3dhlsl.cpp
index 59544be947d..6336404bd4a 100644
--- a/src/osd/modules/render/d3d/d3dhlsl.cpp
+++ b/src/osd/modules/render/d3d/d3dhlsl.cpp
@@ -38,7 +38,7 @@
//============================================================
static slider_state *g_slider_list;
-static file_error open_next(renderer_d3d9 *d3d, emu_file &file, const char *templ, const char *extension, int idx);
+static osd_file::error open_next(renderer_d3d9 *d3d, emu_file &file, const char *templ, const char *extension, int idx);
//============================================================
// PROTOTYPES
@@ -60,7 +60,7 @@ static direct3dx9_loadeffect_ptr g_load_effect = nullptr;
//============================================================
shaders::shaders() :
- d3dintf(nullptr), machine(nullptr), d3d(nullptr), num_screens(0), curr_screen(0), curr_frame(0), write_ini(false), read_ini(false), hlsl_prescale_x(0), hlsl_prescale_y(0), bloom_count(0),
+ d3dintf(nullptr), machine(nullptr), d3d(nullptr), num_screens(0), curr_screen(0), curr_frame(0),
vecbuf_type(), vecbuf_index(0), vecbuf_count(0), avi_output_file(nullptr), avi_frame(0), avi_copy_surface(nullptr), avi_copy_texture(nullptr), avi_final_target(nullptr), avi_final_texture(nullptr),
black_surface(nullptr), black_texture(nullptr), render_snap(false), snap_rendered(false), snap_copy_target(nullptr), snap_copy_texture(nullptr), snap_target(nullptr), snap_texture(nullptr),
snap_width(0), snap_height(0), lines_pending(false), backbuffer(nullptr), curr_effect(nullptr), default_effect(nullptr), prescale_effect(nullptr), post_effect(nullptr), distortion_effect(nullptr),
@@ -69,9 +69,6 @@ shaders::shaders() :
{
master_enable = false;
vector_enable = true;
- hlsl_prescale_x = 1;
- hlsl_prescale_x = 1;
- preset = -1;
shadow_texture = nullptr;
options = nullptr;
paused = true;
@@ -279,8 +276,8 @@ void shaders::render_snapshot(surface *surface)
int idx = cy * 2 + cx;
emu_file file(machine->options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
- file_error filerr = open_next(d3d, file, nullptr, "png", idx);
- if (filerr != FILERR_NONE)
+ osd_file::error filerr = open_next(d3d, file, nullptr, "png", idx);
+ if (filerr != osd_file::error::NONE)
{
return;
}
@@ -363,8 +360,8 @@ void shaders::record_texture()
{
// handle an AVI recording
// write the next frame
- avi_error avierr = avi_append_video_frame(avi_output_file, avi_snap);
- if (avierr != AVIERR_NONE)
+ avi_file::error avierr = avi_output_file->append_video_frame(avi_snap);
+ if (avierr != avi_file::error::NONE)
{
end_avi_recording();
return;
@@ -388,9 +385,9 @@ void shaders::end_avi_recording()
return;
}
- if (avi_output_file != nullptr)
+ if (avi_output_file)
{
- avi_close(avi_output_file);
+ avi_output_file.reset();
}
avi_output_file = nullptr;
@@ -410,8 +407,6 @@ void shaders::toggle()
{
// free shader resources before renderer resources
delete_resources(false);
-
- g_slider_list = nullptr;
}
master_enable = !master_enable;
@@ -436,10 +431,6 @@ void shaders::toggle()
{
master_enable = false;
}
- else
- {
- g_slider_list = init_slider_list();
- }
}
}
}
@@ -463,7 +454,7 @@ void shaders::begin_avi_recording(const char *name)
avi_next_frame_time = machine->time();
// build up information about this new movie
- avi_movie_info info;
+ avi_file::movie_info info;
info.video_format = 0;
info.video_timescale = 1000 * ((machine->first_screen() != nullptr) ? ATTOSECONDS_TO_HZ(machine->first_screen()->frame_period().m_attoseconds) : screen_device::DEFAULT_FRAME_RATE);
info.video_sampletime = 1000;
@@ -481,7 +472,7 @@ void shaders::begin_avi_recording(const char *name)
info.audio_samplerate = machine->sample_rate();
// create a new temporary movie file
- file_error filerr;
+ osd_file::error filerr;
std::string fullpath;
{
emu_file tempfile(machine->options().snapshot_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
@@ -500,19 +491,19 @@ void shaders::begin_avi_recording(const char *name)
}
// if we succeeded, make a copy of the name and create the real file over top
- if (filerr == FILERR_NONE)
+ if (filerr == osd_file::error::NONE)
{
fullpath = tempfile.fullpath();
}
}
- if (filerr == FILERR_NONE)
+ if (filerr == osd_file::error::NONE)
{
// create the file and free the string
- avi_error avierr = avi_create(fullpath.c_str(), &info, &avi_output_file);
- if (avierr != AVIERR_NONE)
+ avi_file::error avierr = avi_file::create(fullpath, info, avi_output_file);
+ if (avierr != avi_file::error::NONE)
{
- osd_printf_error("Error creating AVI: %s\n", avi_error_string(avierr));
+ osd_printf_error("Error creating AVI: %s\n", avi_file::error_string(avierr));
}
}
}
@@ -556,9 +547,9 @@ void shaders::remove_render_target(texture_info *texture)
remove_render_target(find_render_target(texture));
}
-void shaders::remove_render_target(int width, int height, UINT32 screen_index, UINT32 page_index)
+void shaders::remove_render_target(int source_width, int source_height, UINT32 screen_index, UINT32 page_index)
{
- d3d_render_target *target = find_render_target(width, height, screen_index, page_index);
+ d3d_render_target *target = find_render_target(source_width, source_height, screen_index, page_index);
if (target != nullptr)
{
remove_render_target(target);
@@ -662,14 +653,17 @@ void shaders::init(d3d_base *d3dintf, running_machine *machine, renderer_d3d9 *r
// check if no driver loaded (not all settings might be loaded yet)
if (&machine->system() == &GAME_NAME(___empty))
{
+ options->params_init = false;
+ last_options.params_init = false;
+
return;
}
+ enumerate_screens();
+
windows_options &winoptions = downcast<windows_options &>(machine->options());
master_enable = winoptions.d3d_hlsl_enable();
- hlsl_prescale_x = winoptions.d3d_hlsl_prescale_x();
- hlsl_prescale_y = winoptions.d3d_hlsl_prescale_y();
snap_width = winoptions.d3d_snap_width();
snap_height = winoptions.d3d_snap_height();
@@ -697,6 +691,7 @@ void shaders::init(d3d_base *d3dintf, running_machine *machine, renderer_d3d9 *r
options->scanline_alpha = winoptions.screen_scanline_amount();
options->scanline_scale = winoptions.screen_scanline_scale();
options->scanline_height = winoptions.screen_scanline_height();
+ options->scanline_variation = winoptions.screen_scanline_variation();
options->scanline_bright_scale = winoptions.screen_scanline_bright_scale();
options->scanline_bright_offset = winoptions.screen_scanline_bright_offset();
options->scanline_jitter = winoptions.screen_scanline_jitter();
@@ -749,8 +744,6 @@ void shaders::init(d3d_base *d3dintf, running_machine *machine, renderer_d3d9 *r
}
options->params_dirty = true;
-
- g_slider_list = init_slider_list();
}
@@ -957,6 +950,7 @@ int shaders::create_resources(bool reset)
effects[i]->add_uniform("ScreenDims", uniform::UT_VEC2, uniform::CU_SCREEN_DIMS);
effects[i]->add_uniform("QuadDims", uniform::UT_VEC2, uniform::CU_QUAD_DIMS);
effects[i]->add_uniform("SwapXY", uniform::UT_BOOL, uniform::CU_SWAP_XY);
+ effects[i]->add_uniform("VectorScreen", uniform::UT_BOOL, uniform::CU_VECTOR_SCREEN);
}
ntsc_effect->add_uniform("CCValue", uniform::UT_FLOAT, uniform::CU_NTSC_CCFREQ);
@@ -986,26 +980,19 @@ int shaders::create_resources(bool reset)
phosphor_effect->add_uniform("Phosphor", uniform::UT_VEC3, uniform::CU_PHOSPHOR_LIFE);
- post_effect->add_uniform("VignettingAmount", uniform::UT_FLOAT, uniform::CU_POST_VIGNETTING); // backward compatibility
- post_effect->add_uniform("CurvatureAmount", uniform::UT_FLOAT, uniform::CU_POST_CURVATURE); // backward compatibility
- post_effect->add_uniform("RoundCornerAmount", uniform::UT_FLOAT, uniform::CU_POST_ROUND_CORNER); // backward compatibility
- post_effect->add_uniform("SmoothBorderAmount", uniform::UT_FLOAT, uniform::CU_POST_SMOOTH_BORDER); // backward compatibility
- post_effect->add_uniform("ReflectionAmount", uniform::UT_FLOAT, uniform::CU_POST_REFLECTION); // backward compatibility
-
post_effect->add_uniform("ShadowAlpha", uniform::UT_FLOAT, uniform::CU_POST_SHADOW_ALPHA);
post_effect->add_uniform("ShadowCount", uniform::UT_VEC2, uniform::CU_POST_SHADOW_COUNT);
post_effect->add_uniform("ShadowUV", uniform::UT_VEC2, uniform::CU_POST_SHADOW_UV);
post_effect->add_uniform("ShadowUVOffset", uniform::UT_VEC2, uniform::CU_POST_SHADOW_UV_OFFSET);
post_effect->add_uniform("ShadowDims", uniform::UT_VEC2, uniform::CU_POST_SHADOW_DIMS);
-
post_effect->add_uniform("ScanlineAlpha", uniform::UT_FLOAT, uniform::CU_POST_SCANLINE_ALPHA);
post_effect->add_uniform("ScanlineScale", uniform::UT_FLOAT, uniform::CU_POST_SCANLINE_SCALE);
post_effect->add_uniform("ScanlineHeight", uniform::UT_FLOAT, uniform::CU_POST_SCANLINE_HEIGHT);
+ post_effect->add_uniform("ScanlineVariation", uniform::UT_FLOAT, uniform::CU_POST_SCANLINE_VARIATION);
post_effect->add_uniform("ScanlineBrightScale", uniform::UT_FLOAT, uniform::CU_POST_SCANLINE_BRIGHT_SCALE);
post_effect->add_uniform("ScanlineBrightOffset", uniform::UT_FLOAT, uniform::CU_POST_SCANLINE_BRIGHT_OFFSET);
post_effect->add_uniform("Power", uniform::UT_VEC3, uniform::CU_POST_POWER);
post_effect->add_uniform("Floor", uniform::UT_VEC3, uniform::CU_POST_FLOOR);
-
post_effect->add_uniform("RotationType", uniform::UT_INT, uniform::CU_ROTATION_TYPE);
distortion_effect->add_uniform("VignettingAmount", uniform::UT_FLOAT, uniform::CU_POST_VIGNETTING);
@@ -1013,11 +1000,12 @@ int shaders::create_resources(bool reset)
distortion_effect->add_uniform("RoundCornerAmount", uniform::UT_FLOAT, uniform::CU_POST_ROUND_CORNER);
distortion_effect->add_uniform("SmoothBorderAmount", uniform::UT_FLOAT, uniform::CU_POST_SMOOTH_BORDER);
distortion_effect->add_uniform("ReflectionAmount", uniform::UT_FLOAT, uniform::CU_POST_REFLECTION);
-
distortion_effect->add_uniform("RotationType", uniform::UT_INT, uniform::CU_ROTATION_TYPE);
initialized = true;
+ init_slider_list();
+
return 0;
}
@@ -1035,7 +1023,7 @@ void shaders::begin_draw()
curr_effect = default_effect;
- default_effect->set_technique("DefaultTechnique");
+ default_effect->set_technique("ScreenTechnique");
post_effect->set_technique("DefaultTechnique");
distortion_effect->set_technique("DefaultTechnique");
prescale_effect->set_technique("DefaultTechnique");
@@ -1158,9 +1146,9 @@ void shaders::init_effect_info(poly_info *poly)
// shaders::find_render_target
//============================================================
-d3d_render_target* shaders::find_render_target(texture_info *info)
+d3d_render_target* shaders::find_render_target(texture_info *texture)
{
- UINT32 screen_index_data = (UINT32)info->get_texinfo().osddata;
+ UINT32 screen_index_data = (UINT32)texture->get_texinfo().osddata;
UINT32 screen_index = screen_index_data >> 1;
UINT32 page_index = screen_index_data & 1;
@@ -1168,8 +1156,8 @@ d3d_render_target* shaders::find_render_target(texture_info *info)
while (curr != nullptr && (
curr->screen_index != screen_index ||
curr->page_index != page_index ||
- curr->width != info->get_texinfo().width ||
- curr->height != info->get_texinfo().height))
+ curr->width != texture->get_width() ||
+ curr->height != texture->get_height()))
{
curr = curr->next;
}
@@ -1182,12 +1170,12 @@ d3d_render_target* shaders::find_render_target(texture_info *info)
// shaders::find_render_target
//============================================================
-d3d_render_target* shaders::find_render_target(int width, int height, UINT32 screen_index, UINT32 page_index)
+d3d_render_target* shaders::find_render_target(int source_width, int source_height, UINT32 screen_index, UINT32 page_index)
{
d3d_render_target *curr = targethead;
while (curr != nullptr && (
- curr->width != width ||
- curr->height != height ||
+ curr->width != source_width ||
+ curr->height != source_height ||
curr->screen_index != screen_index ||
curr->page_index != page_index))
{
@@ -1236,9 +1224,9 @@ int shaders::ntsc_pass(d3d_render_target *rt, int source_index, poly_info *poly,
curr_effect->set_float("SignalOffset", signal_offset);
next_index = rt->next_index(next_index);
- blit(rt->native_target[next_index], true, D3DPT_TRIANGLELIST, 0, 2);
+ blit(rt->source_surface[next_index], true, D3DPT_TRIANGLELIST, 0, 2);
- color_effect->set_texture("Diffuse", rt->native_texture[next_index]);
+ color_effect->set_texture("Diffuse", rt->source_texture[next_index]);
return next_index;
}
@@ -1293,7 +1281,7 @@ int shaders::color_convolution_pass(d3d_render_target *rt, int source_index, pol
// initial "Diffuse" texture is set in shaders::set_texture() or the result of shaders::ntsc_pass()
next_index = rt->next_index(next_index);
- blit(rt->native_target[next_index], true, D3DPT_TRIANGLELIST, 0, 2);
+ blit(rt->source_surface[next_index], true, D3DPT_TRIANGLELIST, 0, 2);
return next_index;
}
@@ -1304,10 +1292,10 @@ int shaders::prescale_pass(d3d_render_target *rt, int source_index, poly_info *p
curr_effect = prescale_effect;
curr_effect->update_uniforms();
- curr_effect->set_texture("Diffuse", rt->native_texture[next_index]);
+ curr_effect->set_texture("Diffuse", rt->source_texture[next_index]);
next_index = rt->next_index(next_index);
- blit(rt->prescale_target[next_index], true, D3DPT_TRIANGLELIST, 0, 2);
+ blit(rt->target_surface[next_index], true, D3DPT_TRIANGLELIST, 0, 2);
return next_index;
}
@@ -1327,10 +1315,10 @@ int shaders::deconverge_pass(d3d_render_target *rt, int source_index, poly_info
curr_effect = deconverge_effect;
curr_effect->update_uniforms();
- curr_effect->set_texture("Diffuse", rt->prescale_texture[next_index]);
+ curr_effect->set_texture("Diffuse", rt->target_texture[next_index]);
next_index = rt->next_index(next_index);
- blit(rt->prescale_target[next_index], true, D3DPT_TRIANGLELIST, 0, 2);
+ blit(rt->target_surface[next_index], true, D3DPT_TRIANGLELIST, 0, 2);
return next_index;
}
@@ -1347,10 +1335,10 @@ int shaders::defocus_pass(d3d_render_target *rt, int source_index, poly_info *po
curr_effect = focus_effect;
curr_effect->update_uniforms();
- curr_effect->set_texture("Diffuse", rt->prescale_texture[next_index]);
+ curr_effect->set_texture("Diffuse", rt->target_texture[next_index]);
next_index = rt->next_index(next_index);
- blit(rt->prescale_target[next_index], true, D3DPT_TRIANGLELIST, 0, 2);
+ blit(rt->target_surface[next_index], true, D3DPT_TRIANGLELIST, 0, 2);
return next_index;
}
@@ -1367,17 +1355,17 @@ int shaders::phosphor_pass(d3d_render_target *rt, cache_target *ct, int source_i
curr_effect = phosphor_effect;
curr_effect->update_uniforms();
- curr_effect->set_texture("Diffuse", rt->prescale_texture[next_index]);
+ curr_effect->set_texture("Diffuse", rt->target_texture[next_index]);
curr_effect->set_texture("LastPass", ct->last_texture);
curr_effect->set_bool("Passthrough", false);
next_index = rt->next_index(next_index);
- blit(rt->prescale_target[next_index], true, D3DPT_TRIANGLELIST, 0, 2);
+ blit(rt->target_surface[next_index], true, D3DPT_TRIANGLELIST, 0, 2);
// Pass along our phosphor'd screen
curr_effect->update_uniforms();
- curr_effect->set_texture("Diffuse", rt->prescale_texture[next_index]);
- curr_effect->set_texture("LastPass", rt->prescale_texture[next_index]);
+ curr_effect->set_texture("Diffuse", rt->target_texture[next_index]);
+ curr_effect->set_texture("LastPass", rt->target_texture[next_index]);
curr_effect->set_bool("Passthrough", true);
// Avoid changing targets due to page flipping
@@ -1390,9 +1378,6 @@ int shaders::post_pass(d3d_render_target *rt, int source_index, poly_info *poly,
{
int next_index = source_index;
- bool prepare_vector =
- machine->first_screen()->screen_type() == SCREEN_TYPE_VECTOR;
-
screen_device_iterator screen_iterator(machine->root_device());
screen_device *screen = screen_iterator.first();
for (int i = 0; i < curr_screen; i++)
@@ -1409,15 +1394,20 @@ int shaders::post_pass(d3d_render_target *rt, int source_index, poly_info *poly,
float screen_scale[2] = { xscale, yscale };
float screen_offset[2] = { xoffset, yoffset };
- rgb_t back_color_rgb = !machine->first_screen()->has_palette() ? rgb_t(0, 0, 0) : machine->first_screen()->palette().palette()->entry_color(0);
+ rgb_t back_color_rgb = !machine->first_screen()->has_palette()
+ ? rgb_t(0, 0, 0)
+ : machine->first_screen()->palette().palette()->entry_color(0);
back_color_rgb = apply_color_convolution(back_color_rgb);
- float back_color[3] = { static_cast<float>(back_color_rgb.r()) / 255.0f, static_cast<float>(back_color_rgb.g()) / 255.0f, static_cast<float>(back_color_rgb.b()) / 255.0f };
+ float back_color[3] = {
+ static_cast<float>(back_color_rgb.r()) / 255.0f,
+ static_cast<float>(back_color_rgb.g()) / 255.0f,
+ static_cast<float>(back_color_rgb.b()) / 255.0f };
curr_effect = post_effect;
curr_effect->update_uniforms();
curr_effect->set_texture("ShadowTexture", shadow_texture == nullptr ? nullptr : shadow_texture->get_finaltex());
curr_effect->set_int("ShadowTileMode", options->shadow_mask_tile_mode);
- curr_effect->set_texture("DiffuseTexture", rt->prescale_texture[next_index]);
+ curr_effect->set_texture("DiffuseTexture", rt->target_texture[next_index]);
curr_effect->set_vector("BackColor", 3, back_color);
curr_effect->set_vector("ScreenScale", 2, screen_scale);
curr_effect->set_vector("ScreenOffset", 2, screen_offset);
@@ -1425,10 +1415,9 @@ int shaders::post_pass(d3d_render_target *rt, int source_index, poly_info *poly,
curr_effect->set_float("TimeMilliseconds", (float)machine->time().as_double() * 1000.0f);
curr_effect->set_float("HumBarAlpha", options->hum_bar_alpha);
curr_effect->set_bool("PrepareBloom", prepare_bloom);
- curr_effect->set_bool("PrepareVector", prepare_vector);
next_index = rt->next_index(next_index);
- blit(prepare_bloom ? rt->native_target[next_index] : rt->prescale_target[next_index], true, poly->get_type(), vertnum, poly->get_count());
+ blit(prepare_bloom ? rt->source_surface[next_index] : rt->target_surface[next_index], true, D3DPT_TRIANGLELIST, 0, 2);
return next_index;
}
@@ -1443,38 +1432,21 @@ int shaders::downsample_pass(d3d_render_target *rt, int source_index, poly_info
return next_index;
}
- bool prepare_vector =
- machine->first_screen()->screen_type() == SCREEN_TYPE_VECTOR;
-
curr_effect = downsample_effect;
curr_effect->update_uniforms();
- curr_effect->set_bool("PrepareVector", prepare_vector);
- int bloom_index = 0;
- float bloom_width = prepare_vector ? rt->target_width : rt->target_width / hlsl_prescale_x;
- float bloom_height = prepare_vector ? rt->target_height : rt->target_height / hlsl_prescale_y;
- float bloom_size = (bloom_width < bloom_height) ? bloom_width : bloom_height;
- for (; bloom_size >= 2.0f && bloom_index < 11; bloom_size *= 0.5f)
+ for (int bloom_index = 0; bloom_index < rt->bloom_count; bloom_index++)
{
- bloom_dims[bloom_index][0] = (float)(int)bloom_width;
- bloom_dims[bloom_index][1] = (float)(int)bloom_height;
-
- curr_effect->set_vector("TargetDims", 2, bloom_dims[bloom_index]);
+ curr_effect->set_vector("TargetDims", 2, rt->bloom_dims[bloom_index]);
+ curr_effect->set_int("BloomLevel", bloom_index + 1);
curr_effect->set_texture("DiffuseTexture",
bloom_index == 0
- ? rt->native_texture[next_index]
+ ? rt->source_texture[next_index]
: rt->bloom_texture[bloom_index - 1]);
- blit(rt->bloom_target[bloom_index], true, poly->get_type(), vertnum, poly->get_count());
-
- bloom_width *= 0.5f;
- bloom_height *= 0.5f;
-
- bloom_index++;
+ blit(rt->bloom_surface[bloom_index], true, D3DPT_TRIANGLELIST, 0, 2);
}
- bloom_count = bloom_index;
-
return next_index;
}
@@ -1519,33 +1491,33 @@ int shaders::bloom_pass(d3d_render_target *rt, int source_index, poly_info *poly
curr_effect->set_vector("Level78Weight", 2, weight78);
curr_effect->set_vector("Level9AWeight", 2, weight9A);
- curr_effect->set_vector("Level0Size", 2, bloom_dims[0]);
- curr_effect->set_vector("Level12Size", 4, bloom_dims[1]);
- curr_effect->set_vector("Level34Size", 4, bloom_dims[3]);
- curr_effect->set_vector("Level56Size", 4, bloom_dims[5]);
- curr_effect->set_vector("Level78Size", 4, bloom_dims[7]);
- curr_effect->set_vector("Level9ASize", 4, bloom_dims[9]);
+ curr_effect->set_vector("Level0Size", 2, rt->bloom_dims[0]);
+ curr_effect->set_vector("Level12Size", 4, rt->bloom_dims[1]);
+ curr_effect->set_vector("Level34Size", 4, rt->bloom_dims[3]);
+ curr_effect->set_vector("Level56Size", 4, rt->bloom_dims[5]);
+ curr_effect->set_vector("Level78Size", 4, rt->bloom_dims[7]);
+ curr_effect->set_vector("Level9ASize", 4, rt->bloom_dims[9]);
curr_effect->set_int("BloomBlendMode", options->bloom_blend_mode);
curr_effect->set_float("BloomScale", options->bloom_scale);
curr_effect->set_vector("BloomOverdrive", 3, options->bloom_overdrive);
- curr_effect->set_texture("DiffuseA", rt->prescale_texture[next_index]);
+ curr_effect->set_texture("DiffuseA", rt->target_texture[next_index]);
char name[9] = "Diffuse*";
- for (int index = 1; index < bloom_count; index++)
+ for (int index = 1; index < rt->bloom_count; index++)
{
name[7] = 'A' + index;
curr_effect->set_texture(name, rt->bloom_texture[index - 1]);
}
- for (int index = bloom_count; index < 11; index++)
+ for (int index = rt->bloom_count; index < 11; index++)
{
name[7] = 'A' + index;
curr_effect->set_texture(name, black_texture);
}
next_index = rt->next_index(next_index);
- blit(rt->prescale_target[next_index], true, poly->get_type(), vertnum, poly->get_count());
+ blit(rt->target_surface[next_index], true, D3DPT_TRIANGLELIST, 0, 2);
return next_index;
}
@@ -1564,32 +1536,12 @@ int shaders::distortion_pass(d3d_render_target *rt, int source_index, poly_info
return next_index;
}
- int screen_count = d3d->window().target()->current_view()->screens().count();
-
- // only one screen is supported
- if (screen_count > 1)
- {
- return next_index;
- }
-
- render_bounds bounds = d3d->window().target()->current_view()->bounds();
- render_bounds screen_bounds = d3d->window().target()->current_view()->screen_bounds();
-
- // artworks are not supported
- if (bounds.x0 != screen_bounds.x0 ||
- bounds.y0 != screen_bounds.y0 ||
- bounds.x1 != screen_bounds.x1 ||
- bounds.y1 != screen_bounds.y1)
- {
- return next_index;
- }
-
curr_effect = distortion_effect;
curr_effect->update_uniforms();
- curr_effect->set_texture("DiffuseTexture", rt->prescale_texture[next_index]);
+ curr_effect->set_texture("DiffuseTexture", rt->target_texture[next_index]);
next_index = rt->next_index(next_index);
- blit(rt->prescale_target[next_index], true, poly->get_type(), vertnum, poly->get_count());
+ blit(rt->target_surface[next_index], true, D3DPT_TRIANGLELIST, 0, 2);
return next_index;
}
@@ -1606,7 +1558,7 @@ int shaders::vector_pass(d3d_render_target *rt, int source_index, poly_info *pol
curr_effect->set_vector("TimeParams", 2, time_params);
curr_effect->set_vector("LengthParams", 3, length_params);
- blit(rt->prescale_target[next_index], true, poly->get_type(), vertnum, poly->get_count());
+ blit(rt->target_surface[next_index], true, poly->get_type(), vertnum, poly->get_count());
return next_index;
}
@@ -1617,13 +1569,12 @@ int shaders::vector_buffer_pass(d3d_render_target *rt, int source_index, poly_in
curr_effect = default_effect;
curr_effect->update_uniforms();
+ curr_effect->set_technique("VectorBufferTechnique");
- curr_effect->set_texture("Diffuse", rt->prescale_texture[next_index]);
- curr_effect->set_bool("PostPass", true);
- curr_effect->set_float("Brighten", 1.0f);
+ curr_effect->set_texture("Diffuse", rt->target_texture[next_index]);
next_index = rt->next_index(next_index);
- blit(rt->prescale_target[next_index], true, poly->get_type(), vertnum, poly->get_count());
+ blit(rt->target_surface[next_index], true, D3DPT_TRIANGLELIST, 0, 2);
return next_index;
}
@@ -1632,17 +1583,13 @@ int shaders::screen_pass(d3d_render_target *rt, int source_index, poly_info *pol
{
int next_index = source_index;
- bool prepare_vector =
- machine->first_screen()->screen_type() == SCREEN_TYPE_VECTOR;
-
curr_effect = default_effect;
curr_effect->update_uniforms();
+ curr_effect->set_technique("ScreenTechnique");
- curr_effect->set_texture("Diffuse", rt->prescale_texture[next_index]);
- curr_effect->set_bool("PostPass", true);
- curr_effect->set_float("Brighten", prepare_vector ? 1.0f : 0.0f);
+ curr_effect->set_texture("Diffuse", rt->target_texture[next_index]);
- // we do not clear the backbuffe here because multiple screens might rendered into
+ // we do not clear the backbuffe here because multiple screens might be rendered into
blit(backbuffer, false, poly->get_type(), vertnum, poly->get_count());
if (avi_output_file != nullptr)
@@ -1660,12 +1607,11 @@ int shaders::screen_pass(d3d_render_target *rt, int source_index, poly_info *pol
return next_index;
}
-void shaders::menu_pass(poly_info *poly, int vertnum)
+void shaders::ui_pass(poly_info *poly, int vertnum)
{
curr_effect = default_effect;
curr_effect->update_uniforms();
- curr_effect->set_bool("PostPass", false);
- curr_effect->set_float("Brighten", 0.0f);
+ curr_effect->set_technique("UiTechnique");
blit(nullptr, false, poly->get_type(), vertnum, poly->get_count());
}
@@ -1694,10 +1640,11 @@ void shaders::render_quad(poly_info *poly, int vertnum)
d3d_render_target *rt = curr_render_target;
if (rt == nullptr)
{
+ osd_printf_verbose("Direct3D: No raster render target\n");
return;
}
- cache_target *ct = find_cache_target(rt->screen_index, curr_texture->get_texinfo().width, curr_texture->get_texinfo().height);
+ cache_target *ct = find_cache_target(rt->screen_index, curr_texture->get_width(), curr_texture->get_height());
int next_index = 0;
@@ -1729,22 +1676,21 @@ void shaders::render_quad(poly_info *poly, int vertnum)
curr_texture->increment_frame_count();
curr_texture->mask_frame_count(options->yiq_phase_count);
- options->params_dirty = false;
-
curr_screen++;
}
else if (PRIMFLAG_GET_VECTOR(poly->get_flags()) && vector_enable)
{
+ lines_pending = true;
+
curr_render_target = find_render_target(d3d->get_width(), d3d->get_height(), 0, 0);
d3d_render_target *rt = curr_render_target;
if (rt == nullptr)
{
+ osd_printf_verbose("Direct3D: No vector render target\n");
return;
}
- lines_pending = true;
-
int next_index = 0;
next_index = vector_pass(rt, next_index, poly, vertnum);
@@ -1757,11 +1703,14 @@ void shaders::render_quad(poly_info *poly, int vertnum)
}
else if (PRIMFLAG_GET_VECTORBUF(poly->get_flags()) && vector_enable)
{
+ curr_screen = curr_screen < num_screens ? curr_screen : 0;
+
curr_render_target = find_render_target(d3d->get_width(), d3d->get_height(), 0, 0);
d3d_render_target *rt = curr_render_target;
if (rt == nullptr)
{
+ osd_printf_verbose("Direct3D: No vector buffer render target\n");
return;
}
@@ -1788,7 +1737,9 @@ void shaders::render_quad(poly_info *poly, int vertnum)
next_index = distortion_pass(rt, next_index, poly, vertnum);
// render on screen
+ d3d->set_wrap(D3DTADDRESS_MIRROR);
next_index = screen_pass(rt, next_index, poly, vertnum);
+ d3d->set_wrap(PRIMFLAG_GET_TEXWRAP(curr_texture->get_flags()) ? D3DTADDRESS_WRAP : D3DTADDRESS_CLAMP);
HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, backbuffer);
if (result != D3D_OK)
@@ -1797,12 +1748,16 @@ void shaders::render_quad(poly_info *poly, int vertnum)
}
lines_pending = false;
+
+ curr_screen++;
}
else
{
- menu_pass(poly, vertnum);
+ ui_pass(poly, vertnum);
}
+ options->params_dirty = false;
+
curr_render_target = nullptr;
curr_texture = nullptr;
curr_poly = nullptr;
@@ -1825,39 +1780,18 @@ void shaders::end_draw()
//============================================================
-// shaders::register_prescaled_texture
-//============================================================
-
-bool shaders::register_prescaled_texture(texture_info *texture)
-{
- return register_texture(texture);
-}
-
-
-//============================================================
// shaders::add_cache_target - register a cache target
//============================================================
-bool shaders::add_cache_target(renderer_d3d9* d3d, texture_info* info, int width, int height, int xprescale, int yprescale, int screen_index)
+bool shaders::add_cache_target(renderer_d3d9* d3d, texture_info* texture, int source_width, int source_height, int target_width, int target_height, int screen_index)
{
cache_target* target = (cache_target*)global_alloc_clear<cache_target>();
- if (!target->init(d3d, d3dintf, width, height, xprescale, yprescale))
+ if (!target->init(d3d, d3dintf, source_width, source_height, target_width, target_height))
{
global_free(target);
return false;
}
- if (info != nullptr)
- {
- target->width = info->get_texinfo().width;
- target->height = info->get_texinfo().height;
- }
- else
- {
- target->width = d3d->get_width();
- target->height = d3d->get_height();
- }
-
target->next = cachehead;
target->prev = nullptr;
@@ -1872,19 +1806,65 @@ bool shaders::add_cache_target(renderer_d3d9* d3d, texture_info* info, int width
return true;
}
-d3d_render_target* shaders::get_vector_target()
+//============================================================
+// shaders::get_texture_target(render_primitive::prim, texture_info::texture)
+//============================================================
+d3d_render_target* shaders::get_texture_target(render_primitive *prim, texture_info *texture)
{
if (!vector_enable)
{
return nullptr;
}
- return find_render_target(d3d->get_width(), d3d->get_height(), 0, 0);
+ bool swap_xy = d3d->swap_xy();
+ int target_width = swap_xy
+ ? static_cast<int>(prim->get_quad_height() + 0.5f)
+ : static_cast<int>(prim->get_quad_width() + 0.5f);
+ int target_height = swap_xy
+ ? static_cast<int>(prim->get_quad_width() + 0.5f)
+ : static_cast<int>(prim->get_quad_height() + 0.5f);
+
+ // find render target and check if the size of the target quad has changed
+ d3d_render_target *target = find_render_target(texture);
+ if (target != nullptr && target->target_width == target_width && target->target_height == target_height)
+ {
+ return target;
+ }
+
+ osd_printf_verbose("get_texture_target() - invalid size\n");
+
+ return nullptr;
+}
+
+d3d_render_target* shaders::get_vector_target(render_primitive *prim)
+{
+ if (!vector_enable)
+ {
+ return nullptr;
+ }
+
+ int target_width = static_cast<int>(prim->get_quad_width() + 0.5f);
+ int target_height = static_cast<int>(prim->get_quad_height() + 0.5f);
+
+ // find render target and check of the size of the target quad has changed
+ d3d_render_target *target = find_render_target(d3d->get_width(), d3d->get_height(), 0, 0);
+ if (target != nullptr && target->target_width == target_width && target->target_height == target_height)
+ {
+ return target;
+ }
+
+ osd_printf_verbose("get_vector_target() - invalid size\n");
+
+ return nullptr;
}
void shaders::create_vector_target(render_primitive *prim)
{
- if (!add_render_target(d3d, nullptr, d3d->get_width(), d3d->get_height(), 1, 1))
+ int target_width = static_cast<int>(prim->get_quad_width() + 0.5f);
+ int target_height = static_cast<int>(prim->get_quad_height() + 0.5f);
+
+ osd_printf_verbose("create_vector_target() - %f, %f; %d, %d\n", prim->get_quad_width(), prim->get_quad_height(), (int)(prim->get_quad_width() + 0.5f), (int)(prim->get_quad_height() + 0.5f));
+ if (!add_render_target(d3d, nullptr, d3d->get_width(), d3d->get_height(), target_width, target_height))
{
vector_enable = false;
}
@@ -1895,25 +1875,25 @@ void shaders::create_vector_target(render_primitive *prim)
// shaders::add_render_target - register a render target
//============================================================
-bool shaders::add_render_target(renderer_d3d9* d3d, texture_info* info, int width, int height, int xprescale, int yprescale)
+bool shaders::add_render_target(renderer_d3d9* d3d, texture_info* texture, int source_width, int source_height, int target_width, int target_height)
{
UINT32 screen_index = 0;
UINT32 page_index = 0;
- if (info != nullptr)
+ if (texture != nullptr)
{
- d3d_render_target *existing_target = find_render_target(info);
+ d3d_render_target *existing_target = find_render_target(texture);
if (existing_target != nullptr)
{
remove_render_target(existing_target);
}
- UINT32 screen_index_data = (UINT32)info->get_texinfo().osddata;
+ UINT32 screen_index_data = (UINT32)texture->get_texinfo().osddata;
screen_index = screen_index_data >> 1;
page_index = screen_index_data & 1;
}
else
{
- d3d_render_target *existing_target = find_render_target(d3d->get_width(), d3d->get_height(), 0, 0);
+ d3d_render_target *existing_target = find_render_target(source_width, source_height, 0, 0);
if (existing_target != nullptr)
{
remove_render_target(existing_target);
@@ -1922,37 +1902,26 @@ bool shaders::add_render_target(renderer_d3d9* d3d, texture_info* info, int widt
d3d_render_target* target = (d3d_render_target*)global_alloc_clear<d3d_render_target>();
- if (!target->init(d3d, d3dintf, width, height, xprescale, yprescale))
+ if (!target->init(d3d, d3dintf, source_width, source_height, target_width, target_height))
{
global_free(target);
return false;
}
- if (info != nullptr)
- {
- target->width = info->get_texinfo().width;
- target->height = info->get_texinfo().height;
- }
- else
- {
- target->width = d3d->get_width();
- target->height = d3d->get_height();
- }
+ target->screen_index = screen_index;
+ target->page_index = page_index;
- HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, target->prescale_target[0]);
+ HRESULT result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, target->target_surface[0]);
if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
result = (*d3dintf->device.clear)(d3d->get_device(), 0, nullptr, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result);
result = (*d3dintf->device.set_render_target)(d3d->get_device(), 0, backbuffer);
if (result != D3D_OK) osd_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
- target->screen_index = screen_index;
- target->page_index = page_index;
-
- cache_target* cache = find_cache_target(target->screen_index, target->width, target->height);
+ cache_target* cache = find_cache_target(target->screen_index, source_width, source_height);
if (cache == nullptr)
{
- if (!add_cache_target(d3d, info, width, height, xprescale, yprescale, target->screen_index))
+ if (!add_cache_target(d3d, texture, source_width, source_height, target_width, target_height, target->screen_index))
{
global_free(target);
return false;
@@ -1986,51 +1955,27 @@ void shaders::enumerate_screens()
// shaders::register_texture(texture::info)
//============================================================
-bool shaders::register_texture(texture_info *texture)
+bool shaders::register_texture(render_primitive *prim, texture_info *texture)
{
- int width = texture->get_width();
- int height = texture->get_height();
- int xscale = texture->get_xscale();
- int yscale = texture->get_yscale();
-
if (!master_enable || !d3dintf->post_fx_available)
{
return false;
}
- enumerate_screens();
-
- // Find the nearest prescale factor that is over our screen size
- if (hlsl_prescale_x == 0)
- {
- hlsl_prescale_x = 1;
- while (width * xscale * hlsl_prescale_x <= d3d->get_width())
- {
- hlsl_prescale_x++;
- }
- hlsl_prescale_x--;
- }
-
- if (hlsl_prescale_y == 0)
- {
- hlsl_prescale_y = 1;
- while (height * yscale * hlsl_prescale_y <= d3d->get_height())
- {
- hlsl_prescale_y++;
- }
- hlsl_prescale_y--;
- }
-
- hlsl_prescale_x = ((hlsl_prescale_x == 0) ? 1 : hlsl_prescale_x);
- hlsl_prescale_y = ((hlsl_prescale_y == 0) ? 1 : hlsl_prescale_y);
+ bool swap_xy = d3d->swap_xy();
+ int target_width = swap_xy
+ ? static_cast<int>(prim->get_quad_height() + 0.5f)
+ : static_cast<int>(prim->get_quad_width() + 0.5f);
+ int target_height = swap_xy
+ ? static_cast<int>(prim->get_quad_width() + 0.5f)
+ : static_cast<int>(prim->get_quad_height() + 0.5f);
- if (!add_render_target(d3d, texture, width, height, xscale * hlsl_prescale_x, yscale * hlsl_prescale_y))
+ osd_printf_verbose("register_texture() - %f, %f; %d, %d\n", prim->get_quad_width(), prim->get_quad_height(), (int)(prim->get_quad_width() + 0.5f), (int)(prim->get_quad_height() + 0.5f));
+ if (!add_render_target(d3d, texture, texture->get_width(), texture->get_height(), target_width, target_height))
{
return false;
}
- options->params_dirty = true;
-
return true;
}
@@ -2173,6 +2118,8 @@ void shaders::delete_resources(bool reset)
}
shadow_bitmap.reset();
+
+ g_slider_list = nullptr;
}
@@ -2325,6 +2272,7 @@ enum slider_option
SLIDER_SCANLINE_ALPHA,
SLIDER_SCANLINE_SCALE,
SLIDER_SCANLINE_HEIGHT,
+ SLIDER_SCANLINE_VARIATION,
SLIDER_SCANLINE_BRIGHT_SCALE,
SLIDER_SCANLINE_BRIGHT_OFFSET,
SLIDER_SCANLINE_JITTER,
@@ -2399,10 +2347,11 @@ slider_desc shaders::s_sliders[] =
{ "Screen Reflection", 0, 0, 100, 1, SLIDER_FLOAT, SLIDER_SCREEN_TYPE_ANY, SLIDER_REFLECTION, 0.01f, "%1.2f", {} },
{ "Image Vignetting", 0, 0, 100, 1, SLIDER_FLOAT, SLIDER_SCREEN_TYPE_ANY, SLIDER_VIGNETTING, 0.01f, "%1.2f", {} },
{ "Scanline Darkness", 0, 0, 100, 1, SLIDER_FLOAT, SLIDER_SCREEN_TYPE_LCD_OR_RASTER, SLIDER_SCANLINE_ALPHA, 0.01f, "%1.2f", {} },
- { "Scanline Screen Height", 1, 20, 80, 1, SLIDER_FLOAT, SLIDER_SCREEN_TYPE_LCD_OR_RASTER, SLIDER_SCANLINE_SCALE, 0.05f, "%1.2f", {} },
- { "Scanline Indiv. Height", 1, 20, 80, 1, SLIDER_FLOAT, SLIDER_SCREEN_TYPE_LCD_OR_RASTER, SLIDER_SCANLINE_HEIGHT, 0.05f, "%1.2f", {} },
- { "Scanline Brightness", 0, 20, 40, 1, SLIDER_FLOAT, SLIDER_SCREEN_TYPE_LCD_OR_RASTER, SLIDER_SCANLINE_BRIGHT_SCALE, 0.05f, "%1.2f", {} },
- { "Scanline Brightness Overdrive", 0, 0, 20, 1, SLIDER_FLOAT, SLIDER_SCREEN_TYPE_LCD_OR_RASTER, SLIDER_SCANLINE_BRIGHT_OFFSET, 0.05f, "%1.2f", {} },
+ { "Scanline Screen Scale", 0, 100, 400, 1, SLIDER_FLOAT, SLIDER_SCREEN_TYPE_LCD_OR_RASTER, SLIDER_SCANLINE_SCALE, 0.01f, "%1.2f", {} },
+ { "Scanline Height", 0, 100, 400, 1, SLIDER_FLOAT, SLIDER_SCREEN_TYPE_LCD_OR_RASTER, SLIDER_SCANLINE_HEIGHT, 0.01f, "%1.2f", {} },
+ { "Scanline Height Variation", 0, 100, 400, 1, SLIDER_FLOAT, SLIDER_SCREEN_TYPE_LCD_OR_RASTER, SLIDER_SCANLINE_VARIATION, 0.01f, "%1.2f", {} },
+ { "Scanline Brightness", 0, 100, 200, 1, SLIDER_FLOAT, SLIDER_SCREEN_TYPE_LCD_OR_RASTER, SLIDER_SCANLINE_BRIGHT_SCALE, 0.01f, "%1.2f", {} },
+ { "Scanline Brightness Overdrive", 0, 0, 100, 1, SLIDER_FLOAT, SLIDER_SCREEN_TYPE_LCD_OR_RASTER, SLIDER_SCANLINE_BRIGHT_OFFSET, 0.01f, "%1.2f", {} },
{ "Scanline Jitter", 0, 0, 100, 1, SLIDER_FLOAT, SLIDER_SCREEN_TYPE_LCD_OR_RASTER, SLIDER_SCANLINE_JITTER, 0.01f, "%1.2f", {} },
{ "Hum Bar Darkness", 0, 0, 100, 1, SLIDER_FLOAT, SLIDER_SCREEN_TYPE_LCD_OR_RASTER, SLIDER_HUM_BAR_ALPHA, 0.01f, "%2.2f", {} },
{ "Defocus", 0, 0, 100, 1, SLIDER_VEC2, SLIDER_SCREEN_TYPE_ANY, SLIDER_DEFOCUS, 0.1f, "%2.1f", {} },
@@ -2419,7 +2368,7 @@ slider_desc shaders::s_sliders[] =
{ "Gamma,", -80, 0, 80, 1, SLIDER_COLOR, SLIDER_SCREEN_TYPE_ANY, SLIDER_POWER, 0.1f, "%2.2f", {} },
{ "Floor,", 0, 0, 100, 1, SLIDER_COLOR, SLIDER_SCREEN_TYPE_ANY, SLIDER_FLOOR, 0.01f, "%2.2f", {} },
{ "Phosphor Life,", 0, 0, 100, 1, SLIDER_COLOR, SLIDER_SCREEN_TYPE_ANY, SLIDER_PHOSPHOR, 0.01f, "%2.2f", {} },
- { "Bloom Blend Mode", 0, 0, 1, 1, SLIDER_INT_ENUM, SLIDER_SCREEN_TYPE_ANY, SLIDER_BLOOM_BLEND_MODE, 0, "%s", { "Brighten", "Darken" } },
+ { "Bloom Blend Mode", 0, 0, 1, 1, SLIDER_INT_ENUM, SLIDER_SCREEN_TYPE_ANY, SLIDER_BLOOM_BLEND_MODE, 0, "%s", { "Brighten", "Darken" } },
{ "Bloom Scale", 0, 0, 2000, 5, SLIDER_FLOAT, SLIDER_SCREEN_TYPE_ANY, SLIDER_BLOOM_SCALE, 0.001f, "%1.3f", {} },
{ "Bloom Overdrive,", 0, 0, 2000, 5, SLIDER_COLOR, SLIDER_SCREEN_TYPE_ANY, SLIDER_BLOOM_OVERDRIVE, 0.001f, "%1.3f", {} },
{ "Bloom Level 0 Scale", 0, 100, 100, 1, SLIDER_FLOAT, SLIDER_SCREEN_TYPE_ANY, SLIDER_BLOOM_LVL0_SCALE, 0.01f, "%1.2f", {} },
@@ -2475,6 +2424,7 @@ void *shaders::get_slider_option(int id, int index)
case SLIDER_SCANLINE_ALPHA: return &(options->scanline_alpha);
case SLIDER_SCANLINE_SCALE: return &(options->scanline_scale);
case SLIDER_SCANLINE_HEIGHT: return &(options->scanline_height);
+ case SLIDER_SCANLINE_VARIATION: return &(options->scanline_variation);
case SLIDER_SCANLINE_BRIGHT_SCALE: return &(options->scanline_bright_scale);
case SLIDER_SCANLINE_BRIGHT_OFFSET: return &(options->scanline_bright_offset);
case SLIDER_SCANLINE_JITTER: return &(options->scanline_jitter);
@@ -2523,20 +2473,19 @@ void *shaders::get_slider_option(int id, int index)
return nullptr;
}
-slider_state *shaders::init_slider_list()
+void shaders::init_slider_list()
{
if (!master_enable || !d3dintf->post_fx_available)
{
g_slider_list = nullptr;
- return nullptr;
}
slider_state *listhead = nullptr;
slider_state **tailptr = &listhead;
- for (int index = 0; s_sliders[index].name != nullptr; index++)
+ for (int i = 0; s_sliders[i].name != nullptr; i++)
{
- slider_desc *desc = &s_sliders[index];
+ slider_desc *desc = &s_sliders[i];
int screen_type = machine->first_screen()->screen_type();
if ((screen_type == SCREEN_TYPE_VECTOR && (desc->screen_type & SLIDER_SCREEN_TYPE_VECTOR) == SLIDER_SCREEN_TYPE_VECTOR) ||
@@ -2556,9 +2505,10 @@ slider_state *shaders::init_slider_list()
count = 1;
break;
}
- for (int index = 0; index < count; index++)
+
+ for (int j = 0; j < count; j++)
{
- slider* slider_arg = new slider(desc, get_slider_option(desc->id, index), &options->params_dirty);
+ slider* slider_arg = new slider(desc, get_slider_option(desc->id, j), &options->params_dirty);
sliders.push_back(slider_arg);
std::string name = desc->name;
switch (desc->slider_type)
@@ -2566,13 +2516,13 @@ slider_state *shaders::init_slider_list()
case SLIDER_VEC2:
{
std::string names[2] = { " X", " Y" };
- name = name + names[index];
+ name = name + names[j];
break;
}
case SLIDER_COLOR:
{
std::string names[3] = { " Red", " Green", " Blue" };
- name = name + names[index];
+ name = name + names[j];
break;
}
default:
@@ -2584,7 +2534,7 @@ slider_state *shaders::init_slider_list()
}
}
- return listhead;
+ g_slider_list = listhead;
}
@@ -2660,28 +2610,25 @@ void uniform::update()
vec2f sourcedims = shadersys->curr_texture->get_rawdims();
m_shader->set_vector("SourceDims", 2, &sourcedims.c.x);
}
-
+ else
+ {
+ vec2f sourcedims = d3d->get_dims();
+ m_shader->set_vector("SourceDims", 2, &sourcedims.c.x);
+ }
break;
}
case CU_SOURCE_RECT:
{
- bool prepare_vector =
- d3d->window().machine().first_screen()->screen_type() == SCREEN_TYPE_VECTOR;
-
- if (prepare_vector)
- {
- float delta[2] = { 1.0f, 1.0f };
- m_shader->set_vector("SourceRect", 2, delta);
- break;
- }
-
if (shadersys->curr_texture != nullptr)
{
vec2f delta = shadersys->curr_texture->get_uvstop() - shadersys->curr_texture->get_uvstart();
m_shader->set_vector("SourceRect", 2, &delta.c.x);
- break;
}
-
+ else
+ {
+ float delta[2] = { 1.0f, 1.0f };
+ m_shader->set_vector("SourceRect", 2, delta);
+ }
break;
}
case CU_TARGET_DIMS:
@@ -2700,8 +2647,9 @@ void uniform::update()
if (shadersys->curr_poly != nullptr)
{
float quaddims[2] = {
- shadersys->curr_poly->get_prim_width(),
- shadersys->curr_poly->get_prim_height() };
+ // round
+ static_cast<float>(static_cast<int>(shadersys->curr_poly->get_prim_width() + 0.5f)),
+ static_cast<float>(static_cast<int>(shadersys->curr_poly->get_prim_height() + 0.5f)) };
m_shader->set_vector("QuadDims", 2, quaddims);
printf("Quad Dims: %f, %f\n", quaddims[0], quaddims[1]);
}
@@ -2710,18 +2658,15 @@ void uniform::update()
case CU_SWAP_XY:
{
- bool orientation_swap_xy =
- (d3d->window().machine().system().flags & ORIENTATION_SWAP_XY) == ORIENTATION_SWAP_XY;
- bool rotation_swap_xy =
- (d3d->window().target()->orientation() & ROT90) == ROT90 ||
- (d3d->window().target()->orientation() & ROT270) == ROT270;
- m_shader->set_bool("SwapXY", orientation_swap_xy ^ rotation_swap_xy);
+ m_shader->set_bool("SwapXY", d3d->swap_xy());
+ break;
}
case CU_ORIENTATION_SWAP:
{
bool orientation_swap_xy =
(d3d->window().machine().system().flags & ORIENTATION_SWAP_XY) == ORIENTATION_SWAP_XY;
m_shader->set_bool("OrientationSwapXY", orientation_swap_xy);
+ break;
}
case CU_ROTATION_SWAP:
@@ -2730,6 +2675,7 @@ void uniform::update()
(d3d->window().target()->orientation() & ROT90) == ROT90 ||
(d3d->window().target()->orientation() & ROT270) == ROT270;
m_shader->set_bool("RotationSwapXY", rotation_swap_xy);
+ break;
}
case CU_ROTATION_TYPE:
{
@@ -2742,6 +2688,14 @@ void uniform::update()
? 3
: 0;
m_shader->set_int("RotationType", rotation_type);
+ break;
+ }
+ case CU_VECTOR_SCREEN:
+ {
+ bool vector_screen =
+ d3d->window().machine().first_screen()->screen_type() == SCREEN_TYPE_VECTOR;
+ m_shader->set_bool("VectorScreen", vector_screen);
+ break;
}
case CU_NTSC_CCFREQ:
@@ -2880,6 +2834,9 @@ void uniform::update()
case CU_POST_SCANLINE_HEIGHT:
m_shader->set_float("ScanlineHeight", options->scanline_height);
break;
+ case CU_POST_SCANLINE_VARIATION:
+ m_shader->set_float("ScanlineVariation", options->scanline_variation);
+ break;
case CU_POST_SCANLINE_BRIGHT_SCALE:
m_shader->set_float("ScanlineBrightScale", options->scanline_bright_scale);
break;
@@ -3153,7 +3110,7 @@ slider_state *renderer_d3d9::get_slider_list()
// scheme
//-------------------------------------------------
-static file_error open_next(renderer_d3d9 *d3d, emu_file &file, const char *templ, const char *extension, int idx)
+static osd_file::error open_next(renderer_d3d9 *d3d, emu_file &file, const char *templ, const char *extension, int idx)
{
UINT32 origflags = file.openflags();
@@ -3280,8 +3237,8 @@ static file_error open_next(renderer_d3d9 *d3d, emu_file &file, const char *temp
strreplace(fname.assign(snapstr), "%i", string_format("%04d_%d", seq, idx).c_str());
// try to open the file; stop when we fail
- file_error filerr = file.open(fname.c_str());
- if (filerr != FILERR_NONE)
+ osd_file::error filerr = file.open(fname.c_str());
+ if (filerr != osd_file::error::NONE)
{
break;
}
diff --git a/src/osd/modules/render/d3d/d3dhlsl.h b/src/osd/modules/render/d3d/d3dhlsl.h
index ce2994c0cd4..5fde8b93067 100644
--- a/src/osd/modules/render/d3d/d3dhlsl.h
+++ b/src/osd/modules/render/d3d/d3dhlsl.h
@@ -53,6 +53,7 @@ public:
CU_ORIENTATION_SWAP,
CU_ROTATION_SWAP,
CU_ROTATION_TYPE,
+ CU_VECTOR_SCREEN,
CU_NTSC_CCFREQ,
CU_NTSC_A,
@@ -96,6 +97,7 @@ public:
CU_POST_SCANLINE_ALPHA,
CU_POST_SCANLINE_SCALE,
CU_POST_SCANLINE_HEIGHT,
+ CU_POST_SCANLINE_VARIATION,
CU_POST_SCANLINE_BRIGHT_SCALE,
CU_POST_SCANLINE_BRIGHT_OFFSET,
CU_POST_POWER,
@@ -207,6 +209,7 @@ struct hlsl_options
float scanline_alpha;
float scanline_scale;
float scanline_height;
+ float scanline_variation;
float scanline_bright_scale;
float scanline_bright_offset;
float scanline_jitter;
@@ -227,7 +230,7 @@ struct hlsl_options
float saturation;
// NTSC
- int yiq_enable;
+ int yiq_enable;
float yiq_jitter;
float yiq_cc;
float yiq_a;
@@ -285,9 +288,9 @@ public:
INT32 update(std::string *str, INT32 newval);
private:
- slider_desc * m_desc;
- void * m_value;
- bool * m_dirty;
+ slider_desc * m_desc;
+ void * m_value;
+ bool * m_dirty;
};
class shaders
@@ -306,7 +309,7 @@ public:
void toggle();
bool vector_enabled() { return master_enable && vector_enable; }
- d3d_render_target* get_vector_target();
+ d3d_render_target* get_vector_target(render_primitive *prim);
void create_vector_target(render_primitive *prim);
void begin_frame();
@@ -318,10 +321,10 @@ public:
void init_effect_info(poly_info *poly);
void render_quad(poly_info *poly, int vertnum);
- bool register_texture(texture_info *texture);
- bool register_prescaled_texture(texture_info *texture);
- bool add_render_target(renderer_d3d9* d3d, texture_info* info, int width, int height, int xprescale, int yprescale);
- bool add_cache_target(renderer_d3d9* d3d, texture_info* info, int width, int height, int xprescale, int yprescale, int screen_index);
+ bool register_texture(render_primitive *prim, texture_info *texture);
+ d3d_render_target* get_texture_target(render_primitive *prim, texture_info *texture);
+ bool add_render_target(renderer_d3d9* d3d, texture_info* texture, int source_width, int source_height, int target_width, int target_height);
+ bool add_cache_target(renderer_d3d9* d3d, texture_info* texture, int source_width, int source_height, int target_width, int target_height, int screen_index);
void window_save();
void window_record();
@@ -332,17 +335,17 @@ public:
void record_texture();
void init_fsfx_quad(void *vertbuf);
- void set_texture(texture_info *texture);
- d3d_render_target * find_render_target(texture_info *info);
+ void set_texture(texture_info *info);
+ d3d_render_target * find_render_target(texture_info *texture);
void remove_render_target(texture_info *texture);
- void remove_render_target(int width, int height, UINT32 screen_index, UINT32 page_index);
+ void remove_render_target(int source_width, int source_height, UINT32 screen_index, UINT32 page_index);
void remove_render_target(d3d_render_target *rt);
int create_resources(bool reset);
void delete_resources(bool reset);
// slider-related functions
- slider_state *init_slider_list();
+ void init_slider_list();
void *get_slider_option(int id, int index = 0);
private:
@@ -352,9 +355,7 @@ private:
void end_avi_recording();
void begin_avi_recording(const char *name);
- bool register_texture(texture_info *texture, int width, int height, int xscale, int yscale);
-
- d3d_render_target* find_render_target(int width, int height, UINT32 screen_index, UINT32 page_index);
+ d3d_render_target* find_render_target(int source_width, int source_height, UINT32 screen_index, UINT32 page_index);
cache_target * find_cache_target(UINT32 screen_index, int width, int height);
void remove_cache_target(cache_target *cache);
@@ -374,7 +375,7 @@ private:
int vector_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum);
int vector_buffer_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum);
int screen_pass(d3d_render_target *rt, int source_index, poly_info *poly, int vertnum);
- void menu_pass(poly_info *poly, int vertnum);
+ void ui_pass(poly_info *poly, int vertnum);
d3d_base * d3dintf; // D3D interface
@@ -388,13 +389,6 @@ private:
int curr_screen; // current screen for render target operations
int curr_frame; // current frame (0/1) of a screen for render target operations
int lastidx; // index of the last-encountered target
- bool write_ini; // enable external ini saving
- bool read_ini; // enable external ini loading
- int hlsl_prescale_x; // hlsl prescale x
- int hlsl_prescale_y; // hlsl prescale y
- float bloom_dims[11][2]; // bloom texture dimensions
- int bloom_count; // count of used bloom textures
- int preset; // preset, if relevant
bitmap_argb32 shadow_bitmap; // shadow mask bitmap for post-processing shader
texture_info * shadow_texture; // shadow mask texture for post-processing shader
hlsl_options * options; // current options
@@ -402,7 +396,7 @@ private:
UINT32 vecbuf_index;
UINT32 vecbuf_count;
- avi_file * avi_output_file; // AVI file
+ avi_file::ptr avi_output_file; // AVI file
bitmap_rgb32 avi_snap; // AVI snapshot
int avi_frame; // AVI frame
attotime avi_frame_period; // AVI frame period
@@ -450,7 +444,7 @@ private:
d3d_render_target * targethead;
cache_target * cachehead;
- std::vector<slider*> sliders;
+ std::vector<slider*> sliders;
static slider_desc s_sliders[];
static hlsl_options last_options; // last used options
diff --git a/src/osd/modules/render/drawbgfx.cpp b/src/osd/modules/render/drawbgfx.cpp
index 4372eee4f8a..630a50d73e3 100644
--- a/src/osd/modules/render/drawbgfx.cpp
+++ b/src/osd/modules/render/drawbgfx.cpp
@@ -85,7 +85,7 @@ static void* sdlNativeWindowHandle(SDL_Window* _window)
return nullptr;
}
-# if BX_PLATFORM_LINUX || BX_PLATFORM_BSD
+# if BX_PLATFORM_LINUX || BX_PLATFORM_BSD || BX_PLATFORM_RPI
return (void*)wmi.info.x11.window;
# elif BX_PLATFORM_OSX
return wmi.info.cocoa.window;
diff --git a/src/osd/modules/render/drawd3d.cpp b/src/osd/modules/render/drawd3d.cpp
index 0f50cae8d55..e927c36458f 100644
--- a/src/osd/modules/render/drawd3d.cpp
+++ b/src/osd/modules/render/drawd3d.cpp
@@ -209,6 +209,7 @@ render_primitive_list *renderer_d3d9::get_primitives()
}
if (m_shaders != nullptr)
{
+ // do not transform primitives (scale, offset) if shaders are enabled, the shaders will handle the transformation
window().target()->set_transform_primitives(!m_shaders->enabled());
}
return &window().target()->get_primitives();
@@ -636,8 +637,16 @@ void d3d_texture_manager::update_textures()
texture_info *texture = find_texinfo(&prim->texture, prim->flags);
if (texture == nullptr)
{
- // if there isn't one, create a new texture
- global_alloc(texture_info(this, &prim->texture, m_renderer->window().prescale(), prim->flags));
+ if (m_renderer->get_shaders()->enabled())
+ {
+ // if there isn't one, create a new texture without prescale
+ texture = global_alloc(texture_info(this, &prim->texture, 1, prim->flags));
+ }
+ else
+ {
+ // if there isn't one, create a new texture
+ texture = global_alloc(texture_info(this, &prim->texture, m_renderer->window().prescale(), prim->flags));
+ }
}
else
{
@@ -648,10 +657,21 @@ void d3d_texture_manager::update_textures()
texture->get_texinfo().seqid = prim->texture.seqid;
}
}
+
+ if (m_renderer->get_shaders()->enabled())
+ {
+ if (!m_renderer->get_shaders()->get_texture_target(prim, texture))
+ {
+ if (!m_renderer->get_shaders()->register_texture(prim, texture))
+ {
+ d3dintf->post_fx_available = false;
+ }
+ }
+ }
}
else if(m_renderer->get_shaders()->vector_enabled() && PRIMFLAG_GET_VECTORBUF(prim->flags))
{
- if (!m_renderer->get_shaders()->get_vector_target())
+ if (!m_renderer->get_shaders()->get_vector_target(prim))
{
m_renderer->get_shaders()->create_vector_target(prim);
}
@@ -684,12 +704,15 @@ void renderer_d3d9::begin_frame()
m_shaders->init_fsfx_quad(m_hlsl_buf);
}
+ // loop over line primitives
m_line_count = 0;
-
- // loop over primitives
for (render_primitive *prim = window().m_primlist->first(); prim != nullptr; prim = prim->next())
+ {
if (prim->type == render_primitive::LINE && PRIMFLAG_GET_VECTOR(prim->flags))
+ {
m_line_count++;
+ }
+ }
}
void renderer_d3d9::process_primitives()
@@ -1374,6 +1397,9 @@ void renderer_d3d9::batch_vectors()
m_vectorbatch = mesh_alloc(m_line_count * vector_size);
m_batchindex = 0;
+ float width = 0.0f;
+ float height = 0.0f;
+
static int start_index = 0;
int line_index = 0;
float period = options.screen_vector_time_period();
@@ -1398,6 +1424,14 @@ void renderer_d3d9::batch_vectors()
}
break;
+ case render_primitive::QUAD:
+ if (PRIMFLAG_GET_VECTORBUF(prim->flags))
+ {
+ width = prim->bounds.x1 - prim->bounds.x0;
+ height = prim->bounds.y1 - prim->bounds.y0;
+ }
+ break;
+
default:
// Skip
break;
@@ -1406,7 +1440,7 @@ void renderer_d3d9::batch_vectors()
// now add a polygon entry
m_poly[m_numpolys].init(D3DPT_TRIANGLELIST, m_line_count * (options.antialias() ? 8 : 2), vector_size * m_line_count, cached_flags,
- m_texture_manager->get_vector_texture(), D3DTOP_MODULATE, 0.0f, 1.0f, 0.0f, 0.0f);
+ m_texture_manager->get_vector_texture(), D3DTOP_MODULATE, 0.0f, 1.0f, width, height);
m_numpolys++;
start_index += (int)((float)line_index * period);
@@ -1631,11 +1665,12 @@ void renderer_d3d9::draw_quad(const render_primitive *prim)
float height = prim->bounds.y1 - prim->bounds.y0;
// set the texture coordinates
- if(texture != nullptr)
+ if (texture != nullptr)
{
vec2f& start = texture->get_uvstart();
vec2f& stop = texture->get_uvstop();
vec2f delta = stop - start;
+
vertex[0].u0 = start.c.x + delta.c.x * prim->texcoords.tl.u;
vertex[0].v0 = start.c.y + delta.c.y * prim->texcoords.tl.v;
vertex[1].u0 = start.c.x + delta.c.x * prim->texcoords.tr.u;
@@ -1888,6 +1923,30 @@ texture_info::texture_info(d3d_texture_manager *manager, const render_texinfo* t
m_d3dsurface = nullptr;
m_d3dfinaltex = nullptr;
+ // determine texture type, required to compute texture size
+ if (!PRIMFLAG_GET_SCREENTEX(flags))
+ {
+ m_type = TEXTURE_TYPE_PLAIN;
+ }
+ else
+ {
+ if ((m_xprescale == 1 && m_yprescale == 1) || m_renderer->get_shaders()->enabled())
+ {
+ m_type = m_texture_manager->is_dynamic_supported() ? TEXTURE_TYPE_DYNAMIC : TEXTURE_TYPE_PLAIN;
+ }
+ else
+ {
+ if (m_texture_manager->is_stretch_supported() && PRIMFLAG_GET_TEXFORMAT(flags) != TEXFORMAT_YUY16)
+ {
+ m_type = TEXTURE_TYPE_SURFACE;
+ }
+ else
+ {
+ m_type = m_texture_manager->is_dynamic_supported() ? TEXTURE_TYPE_DYNAMIC : TEXTURE_TYPE_PLAIN;
+ }
+ }
+ }
+
// compute the size
compute_size(texsource->width, texsource->height);
@@ -1899,7 +1958,6 @@ texture_info::texture_info(d3d_texture_manager *manager, const render_texinfo* t
if (result != D3D_OK)
goto error;
m_d3dfinaltex = m_d3dtex;
- m_type = TEXTURE_TYPE_PLAIN;
}
// screen textures are allocated differently
@@ -1964,16 +2022,9 @@ texture_info::texture_info(d3d_texture_manager *manager, const render_texinfo* t
if (result == D3D_OK)
{
m_d3dfinaltex = m_d3dtex;
- m_type = m_texture_manager->is_dynamic_supported() ? TEXTURE_TYPE_DYNAMIC : TEXTURE_TYPE_PLAIN;
- if (m_renderer->get_shaders()->enabled() && !m_renderer->get_shaders()->register_texture(this))
- {
- goto error;
- }
-
break;
}
}
-
// screen textures with prescaling require two allocations
else
{
@@ -1986,9 +2037,7 @@ texture_info::texture_info(d3d_texture_manager *manager, const render_texinfo* t
{
continue;
}
- m_type = TEXTURE_TYPE_SURFACE;
}
-
// otherwise, we allocate a dynamic texture for the source
else
{
@@ -1997,7 +2046,6 @@ texture_info::texture_info(d3d_texture_manager *manager, const render_texinfo* t
{
continue;
}
- m_type = m_texture_manager->is_dynamic_supported() ? TEXTURE_TYPE_DYNAMIC : TEXTURE_TYPE_PLAIN;
}
// for the target surface, we allocate a render target texture
@@ -2006,15 +2054,13 @@ texture_info::texture_info(d3d_texture_manager *manager, const render_texinfo* t
// target surfaces typically cannot be YCbCr, so we always pick RGB in that case
D3DFORMAT finalfmt = (format != m_texture_manager->get_yuv_format()) ? format : D3DFMT_A8R8G8B8;
+
result = (*d3dintf->device.create_texture)(m_renderer->get_device(), scwidth, scheight, 1, D3DUSAGE_RENDERTARGET, finalfmt, D3DPOOL_DEFAULT, &m_d3dfinaltex);
if (result == D3D_OK)
{
- if (m_renderer->get_shaders()->enabled() && !m_renderer->get_shaders()->register_prescaled_texture(this))
- {
- goto error;
- }
break;
}
+
(*d3dintf->texture.release)(m_d3dtex);
m_d3dtex = nullptr;
}
@@ -2024,7 +2070,6 @@ texture_info::texture_info(d3d_texture_manager *manager, const render_texinfo* t
// copy the data to the texture
set_data(texsource, flags);
- //texsource->osdhandle = (void*)this;
// add us to the texture list
if(m_texture_manager->get_texlist() != nullptr)
m_texture_manager->get_texlist()->m_prev = this;
@@ -2112,30 +2157,42 @@ void texture_info::compute_size(int texwidth, int texheight)
m_xborderpix = 0;
m_yborderpix = 0;
- // if we're not wrapping, add a 1-2 pixel border on all sides
- if (ENABLE_BORDER_PIX && !(m_flags & PRIMFLAG_TEXWRAP_MASK))
+ bool shaders_enabled = m_renderer->get_shaders()->enabled();
+ bool wrap_texture = (m_flags & PRIMFLAG_TEXWRAP_MASK) == PRIMFLAG_TEXWRAP_MASK;
+ bool border_texture = ENABLE_BORDER_PIX && !wrap_texture;
+ bool surface_texture = m_type == TEXTURE_TYPE_SURFACE;
+
+ // skip border when shaders are enabled and we're not creating a surface (UI) texture
+ if (!shaders_enabled || surface_texture)
{
- // note we need 2 pixels in X for YUY textures
- m_xborderpix = (PRIMFLAG_GET_TEXFORMAT(m_flags) == TEXFORMAT_YUY16) ? 2 : 1;
- m_yborderpix = 1;
+ // if we're not wrapping, add a 1-2 pixel border on all sides
+ if (border_texture)
+ {
+ // note we need 2 pixels in X for YUY textures
+ m_xborderpix = (PRIMFLAG_GET_TEXFORMAT(m_flags) == TEXFORMAT_YUY16) ? 2 : 1;
+ m_yborderpix = 1;
+ }
}
- // compute final texture size
finalwidth += 2 * m_xborderpix;
finalheight += 2 * m_yborderpix;
- compute_size_subroutine(finalwidth, finalheight, &finalwidth, &finalheight);
-
- // if we added pixels for the border, and that just barely pushed us over, take it back
- if (finalwidth > m_texture_manager->get_max_texture_width() || finalheight > m_texture_manager->get_max_texture_height())
+ // take texture size as given when shaders are enabled and we're not creating a surface (UI) texture, still update wrapped textures
+ if (!shaders_enabled || surface_texture || wrap_texture)
{
- finalheight = texheight;
- finalwidth = texwidth;
+ compute_size_subroutine(finalwidth, finalheight, &finalwidth, &finalheight);
- m_xborderpix = 0;
- m_yborderpix = 0;
+ // if we added pixels for the border, and that just barely pushed us over, take it back
+ if (finalwidth > m_texture_manager->get_max_texture_width() || finalheight > m_texture_manager->get_max_texture_height())
+ {
+ finalheight = texheight;
+ finalwidth = texwidth;
- compute_size_subroutine(finalwidth, finalheight, &finalwidth, &finalheight);
+ m_xborderpix = 0;
+ m_yborderpix = 0;
+
+ compute_size_subroutine(finalwidth, finalheight, &finalwidth, &finalheight);
+ }
}
// if we're above the max width/height, do what?
@@ -2714,18 +2771,20 @@ cache_target::~cache_target()
// cache_target::init - initializes a target cache
//============================================================
-bool cache_target::init(renderer_d3d9 *d3d, d3d_base *d3dintf, int width, int height, int prescale_x, int prescale_y)
+bool cache_target::init(renderer_d3d9 *d3d, d3d_base *d3dintf, int source_width, int source_height, int target_width, int target_height)
{
- HRESULT result = (*d3dintf->device.create_texture)(d3d->get_device(), width * prescale_x, height * prescale_y, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &last_texture);
+ this->width = source_width;
+ this->height = source_height;
+ this->target_width = target_width;
+ this->target_height = target_height;
+
+ HRESULT result = (*d3dintf->device.create_texture)(d3d->get_device(), target_width, target_height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &last_texture);
if (result != D3D_OK)
{
return false;
}
(*d3dintf->texture.get_surface_level)(last_texture, 0, &last_target);
- target_width = width * prescale_x;
- target_height = height * prescale_y;
-
return true;
}
@@ -2743,34 +2802,34 @@ d3d_render_target::~d3d_render_target()
(*d3dintf->texture.release)(bloom_texture[index]);
bloom_texture[index] = nullptr;
}
- if (bloom_target[index] != nullptr)
+ if (bloom_surface[index] != nullptr)
{
- (*d3dintf->surface.release)(bloom_target[index]);
- bloom_target[index] = nullptr;
+ (*d3dintf->surface.release)(bloom_surface[index]);
+ bloom_surface[index] = nullptr;
}
}
for (int index = 0; index < 2; index++)
{
- if (native_texture[index] != nullptr)
+ if (source_texture[index] != nullptr)
{
- (*d3dintf->texture.release)(native_texture[index]);
- native_texture[index] = nullptr;
+ (*d3dintf->texture.release)(source_texture[index]);
+ source_texture[index] = nullptr;
}
- if (native_target[index] != nullptr)
+ if (source_surface[index] != nullptr)
{
- (*d3dintf->surface.release)(native_target[index]);
- native_target[index] = nullptr;
+ (*d3dintf->surface.release)(source_surface[index]);
+ source_surface[index] = nullptr;
}
- if (prescale_texture[index] != nullptr)
+ if (target_texture[index] != nullptr)
{
- (*d3dintf->texture.release)(prescale_texture[index]);
- prescale_texture[index] = nullptr;
+ (*d3dintf->texture.release)(target_texture[index]);
+ target_texture[index] = nullptr;
}
- if (prescale_target[index] != nullptr)
+ if (target_surface[index] != nullptr)
{
- (*d3dintf->surface.release)(prescale_target[index]);
- prescale_target[index] = nullptr;
+ (*d3dintf->surface.release)(target_surface[index]);
+ target_surface[index] = nullptr;
}
}
}
@@ -2780,51 +2839,61 @@ d3d_render_target::~d3d_render_target()
// d3d_render_target::init - initializes a render target
//============================================================
-bool d3d_render_target::init(renderer_d3d9 *d3d, d3d_base *d3dintf, int width, int height, int prescale_x, int prescale_y)
+bool d3d_render_target::init(renderer_d3d9 *d3d, d3d_base *d3dintf, int source_width, int source_height, int target_width, int target_height)
{
HRESULT result;
+ this->width = source_width;
+ this->height = source_height;
+
+ this->target_width = target_width;
+ this->target_height = target_height;
+
for (int index = 0; index < 2; index++)
{
- result = (*d3dintf->device.create_texture)(d3d->get_device(), width, height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &native_texture[index]);
+ result = (*d3dintf->device.create_texture)(d3d->get_device(), source_width, source_height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &source_texture[index]);
if (result != D3D_OK)
{
return false;
}
- (*d3dintf->texture.get_surface_level)(native_texture[index], 0, &native_target[index]);
+ (*d3dintf->texture.get_surface_level)(source_texture[index], 0, &source_surface[index]);
- result = (*d3dintf->device.create_texture)(d3d->get_device(), width * prescale_x, height * prescale_y, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &prescale_texture[index]);
+ result = (*d3dintf->device.create_texture)(d3d->get_device(), target_width, target_height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &target_texture[index]);
if (result != D3D_OK)
{
return false;
}
- (*d3dintf->texture.get_surface_level)(prescale_texture[index], 0, &prescale_target[index]);
+ (*d3dintf->texture.get_surface_level)(target_texture[index], 0, &target_surface[index]);
}
- int bloom_index = 0;
- float bloom_size = (d3d->get_width() < d3d->get_height()) ? d3d->get_width() : d3d->get_height();
- float bloom_width = d3d->get_width();
- float bloom_height = d3d->get_height();
- for (; bloom_size >= 2.0f && bloom_index < 11; bloom_size *= 0.5f)
+ bool vector_screen =
+ d3d->window().machine().first_screen()->screen_type() == SCREEN_TYPE_VECTOR;
+
+ // larger blur width for vector screens than raster screens
+ float scale_factor = vector_screen ? 0.5f : 0.75f;
+
+ float bloom_width = (float)source_width;
+ float bloom_height = (float)source_height;
+ float bloom_size = bloom_width < bloom_height ? bloom_width : bloom_height;
+ for (int bloom_index = 0; bloom_index < 11 && bloom_size >= 2.0f; bloom_size *= scale_factor)
{
- bloom_width *= 0.5f;
- bloom_height *= 0.5f;
+ this->bloom_dims[bloom_index][0] = (int)bloom_width;
+ this->bloom_dims[bloom_index][1] = (int)bloom_height;
result = (*d3dintf->device.create_texture)(d3d->get_device(), (int)bloom_width, (int)bloom_height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &bloom_texture[bloom_index]);
if (result != D3D_OK)
{
return false;
}
- (*d3dintf->texture.get_surface_level)(bloom_texture[bloom_index], 0, &bloom_target[bloom_index]);
+ (*d3dintf->texture.get_surface_level)(bloom_texture[bloom_index], 0, &bloom_surface[bloom_index]);
- bloom_index++;
- }
+ bloom_width *= scale_factor;
+ bloom_height *= scale_factor;
- this->width = width;
- this->height = height;
+ bloom_index++;
- target_width = width * prescale_x;
- target_height = height * prescale_y;
+ this->bloom_count = bloom_index;
+ }
return true;
}
diff --git a/src/osd/modules/render/drawd3d.h b/src/osd/modules/render/drawd3d.h
index 474f9ef8487..de8506ebfbd 100644
--- a/src/osd/modules/render/drawd3d.h
+++ b/src/osd/modules/render/drawd3d.h
@@ -54,6 +54,17 @@ public:
virtual void record() override;
virtual void toggle_fsfx() override;
+ bool swap_xy()
+ {
+ // todo: move to osd_window
+ bool orientation_swap_xy =
+ (window().machine().system().flags & ORIENTATION_SWAP_XY) == ORIENTATION_SWAP_XY;
+ bool rotation_swap_xy =
+ (window().target()->orientation() & ROT90) == ROT90 ||
+ (window().target()->orientation() & ROT270) == ROT270;
+ return orientation_swap_xy ^ rotation_swap_xy;
+ };
+
int initialize();
int device_create(HWND device_HWND);
@@ -81,8 +92,6 @@ public:
vertex * mesh_alloc(int numverts);
- void update_textures();
-
void process_primitives();
void primitive_flush_pending();
diff --git a/src/osd/osdcore.h b/src/osd/osdcore.h
index dec4a5c030b..899f024d9f4 100644
--- a/src/osd/osdcore.h
+++ b/src/osd/osdcore.h
@@ -16,11 +16,16 @@
#pragma once
-#ifndef __OSDCORE_H__
-#define __OSDCORE_H__
+#ifndef MAME_OSD_OSDCORE_H
+#define MAME_OSD_OSDCORE_H
#include "osdcomm.h"
-#include <stdarg.h>
+
+#include <cstdarg>
+#include <cstdint>
+#include <memory>
+#include <string>
+
/***************************************************************************
FILE I/O INTERFACES
@@ -42,194 +47,185 @@
#define OPEN_FLAG_CREATE_PATHS 0x0008 /* create paths as necessary */
#define OPEN_FLAG_NO_PRELOAD 0x0010 /* do not decompress on open */
-/* error codes returned by routines below */
-enum file_error
+// osd_file is an interface which represents an open file/PTY/socket
+class osd_file
{
- FILERR_NONE,
- FILERR_FAILURE,
- FILERR_OUT_OF_MEMORY,
- FILERR_NOT_FOUND,
- FILERR_ACCESS_DENIED,
- FILERR_ALREADY_OPEN,
- FILERR_TOO_MANY_FILES,
- FILERR_INVALID_DATA,
- FILERR_INVALID_ACCESS
-};
+public:
+ // error codes returned by routines below
+ enum class error
+ {
+ NONE,
+ FAILURE,
+ OUT_OF_MEMORY,
+ NOT_FOUND,
+ ACCESS_DENIED,
+ ALREADY_OPEN,
+ TOO_MANY_FILES,
+ INVALID_DATA,
+ INVALID_ACCESS
+ };
-/* osd_file is an opaque type which represents an open file */
-struct osd_file;
+ typedef std::unique_ptr<osd_file> ptr;
-/*-----------------------------------------------------------------------------
- osd_open: open a new file.
- Parameters:
+ /*-----------------------------------------------------------------------------
+ osd_file::open: open a new file.
- path - path to the file to open
+ Parameters:
- openflags - some combination of:
+ path - path to the file to open
- OPEN_FLAG_READ - open the file for read access
- OPEN_FLAG_WRITE - open the file for write access
- OPEN_FLAG_CREATE - create/truncate the file when opening
- OPEN_FLAG_CREATE_PATHS - specifies that non-existant paths
- should be created if necessary
+ openflags - some combination of:
- file - pointer to an osd_file * to receive the newly-opened file
- handle; this is only valid if the function returns FILERR_NONE
+ OPEN_FLAG_READ - open the file for read access
+ OPEN_FLAG_WRITE - open the file for write access
+ OPEN_FLAG_CREATE - create/truncate the file when opening
+ OPEN_FLAG_CREATE_PATHS - specifies that non-existant paths
+ should be created if necessary
- filesize - pointer to a UINT64 to receive the size of the opened
- file; this is only valid if the function returns FILERR_NONE
+ file - reference to an osd_file::ptr to receive the newly-opened file
+ handle; this is only valid if the function returns FILERR_NONE
- Return value:
+ filesize - reference to a UINT64 to receive the size of the opened
+ file; this is only valid if the function returns FILERR_NONE
- a file_error describing any error that occurred while opening
- the file, or FILERR_NONE if no error occurred
+ Return value:
- Notes:
+ a file_error describing any error that occurred while opening
+ the file, or FILERR_NONE if no error occurred
- This function is called by core_fopen and several other places in
- the core to access files. These functions will construct paths by
- concatenating various search paths held in the options.c options
- database with partial paths specified by the core. The core assumes
- that the path separator is the first character of the string
- PATH_SEPARATOR, but does not interpret any path separators in the
- search paths, so if you use a different path separator in a search
- path, you may get a mixture of PATH_SEPARATORs (from the core) and
- alternate path separators (specified by users and placed into the
- options database).
------------------------------------------------------------------------------*/
-file_error osd_open(const char *path, UINT32 openflags, osd_file **file, UINT64 *filesize);
+ Notes:
+ This function is called by core_fopen and several other places in
+ the core to access files. These functions will construct paths by
+ concatenating various search paths held in the options.c options
+ database with partial paths specified by the core. The core assumes
+ that the path separator is the first character of the string
+ PATH_SEPARATOR, but does not interpret any path separators in the
+ search paths, so if you use a different path separator in a search
+ path, you may get a mixture of PATH_SEPARATORs (from the core) and
+ alternate path separators (specified by users and placed into the
+ options database).
+ -----------------------------------------------------------------------------*/
+ static error open(std::string const &path, std::uint32_t openflags, ptr &file, std::uint64_t &filesize);
-/*-----------------------------------------------------------------------------
- osd_close: close an open file
- Parameters:
+ /*-----------------------------------------------------------------------------
+ osd_file::openpty: create a new PTY pair
- file - handle to a file previously opened via osd_open
+ Parameters:
- Return value:
+ file - reference to an osd_file::ptr to receive the handle of the master
+ side of the newly-created PTY; this is only valid if the function
+ returns FILERR_NONE
- a file_error describing any error that occurred while closing
- the file, or FILERR_NONE if no error occurred
------------------------------------------------------------------------------*/
-file_error osd_close(osd_file *file);
+ name - reference to string where slave filename will be stored
+ Return value:
-/*-----------------------------------------------------------------------------
- osd_read: read from an open file
+ a file_error describing any error that occurred while creating the
+ PTY, or FILERR_NONE if no error occurred
+ -----------------------------------------------------------------------------*/
+ static error openpty(ptr &file, std::string &name);
- Parameters:
- file - handle to a file previously opened via osd_open
+ /*-----------------------------------------------------------------------------
+ osd_file::~osd_file: close an open file
+ -----------------------------------------------------------------------------*/
+ virtual ~osd_file() { }
- buffer - pointer to memory that will receive the data read
- offset - offset within the file to read from
+ /*-----------------------------------------------------------------------------
+ osd_file::read: read from an open file
- length - number of bytes to read from the file
+ Parameters:
- actual - pointer to a UINT32 to receive the number of bytes actually
- read during the operation; valid only if the function returns
- FILERR_NONE
+ buffer - pointer to memory that will receive the data read
- Return value:
+ offset - offset within the file to read from
- a file_error describing any error that occurred while reading
- from the file, or FILERR_NONE if no error occurred
------------------------------------------------------------------------------*/
-file_error osd_read(osd_file *file, void *buffer, UINT64 offset, UINT32 length, UINT32 *actual);
+ length - number of bytes to read from the file
+ actual - reference to a UINT32 to receive the number of bytes actually
+ read during the operation; valid only if the function returns
+ FILERR_NONE
-/*-----------------------------------------------------------------------------
- osd_write: write to an open file
+ Return value:
- Parameters:
+ a file_error describing any error that occurred while reading
+ from the file, or FILERR_NONE if no error occurred
+ -----------------------------------------------------------------------------*/
+ virtual error read(void *buffer, std::uint64_t offset, std::uint32_t length, std::uint32_t &actual) = 0;
- file - handle to a file previously opened via osd_open
- buffer - pointer to memory that contains the data to write
+ /*-----------------------------------------------------------------------------
+ osd_file::write: write to an open file
- offset - offset within the file to write to
+ Parameters:
- length - number of bytes to write to the file
+ buffer - pointer to memory that contains the data to write
- actual - pointer to a UINT32 to receive the number of bytes actually
- written during the operation; valid only if the function returns
- FILERR_NONE
+ offset - offset within the file to write to
- Return value:
+ length - number of bytes to write to the file
- a file_error describing any error that occurred while writing to
- the file, or FILERR_NONE if no error occurred
------------------------------------------------------------------------------*/
-file_error osd_write(osd_file *file, const void *buffer, UINT64 offset, UINT32 length, UINT32 *actual);
+ actual - reference to a UINT32 to receive the number of bytes actually
+ written during the operation; valid only if the function returns
+ FILERR_NONE
-/*-----------------------------------------------------------------------------
- osd_openpty: create a new PTY pair
+ Return value:
- Parameters:
+ a file_error describing any error that occurred while writing to
+ the file, or FILERR_NONE if no error occurred
+ -----------------------------------------------------------------------------*/
+ virtual error write(void const *buffer, std::uint64_t offset, std::uint32_t length, std::uint32_t &actual) = 0;
- file - pointer to an osd_file * to receive the handle of the master
- side of the newly-created PTY; this is only valid if the function
- returns FILERR_NONE
- name - pointer to memory where slave filename will be stored
+ /*-----------------------------------------------------------------------------
+ osd_file::truncate: change the size of an open file
- name_len - space allocated for name
+ Parameters:
- Return value:
+. offset - future size of the file
- a file_error describing any error that occurred while creating the
- PTY, or FILERR_NONE if no error occurred
------------------------------------------------------------------------------*/
-file_error osd_openpty(osd_file **file, char *name, size_t name_len);
+ Return value:
-/*-----------------------------------------------------------------------------
- osd_truncate: change the size of an open file
+ a file_error describing any error that occurred while writing to
+ the file, or FILERR_NONE if no error occurred
+ -----------------------------------------------------------------------------*/
+ virtual error truncate(std::uint64_t offset) = 0;
- Parameters:
- file - handle to a file previously opened via osd_open
+ /*-----------------------------------------------------------------------------
+ osd_file::flush: flush file buffers
- offset - future size of the file
+ Parameters:
- Return value:
+ file - handle to a file previously opened via osd_open
- a file_error describing any error that occurred while writing to
- the file, or FILERR_NONE if no error occurred
------------------------------------------------------------------------------*/
-file_error osd_truncate(osd_file *file, UINT64 offset);
+ Return value:
+ a file_error describing any error that occurred while flushing file
+ buffers, or FILERR_NONE if no error occurred
+ -----------------------------------------------------------------------------*/
+ virtual error flush() = 0;
-/*-----------------------------------------------------------------------------
- osd_fflus: flush file buffers
- Parameters:
+ /*-----------------------------------------------------------------------------
+ osd_file::remove: deletes a file
- file - handle to a file previously opened via osd_open
+ Parameters:
- Return value:
+ filename - path to file to delete
- a file_error describing any error that occurred while writing to
- the file, or FILERR_NONE if no error occurred
------------------------------------------------------------------------------*/
-file_error osd_fflush(osd_file *file);
-
-
-/*-----------------------------------------------------------------------------
- osd_rmfile: deletes a file
-
- Parameters:
-
- filename - path to file to delete
+ Return value:
- Return value:
+ a file_error describing any error that occurred while deleting
+ the file, or FILERR_NONE if no error occurred
+ -----------------------------------------------------------------------------*/
+ static error remove(std::string const &filename);
+};
- a file_error describing any error that occurred while deleting
- the file, or FILERR_NONE if no error occurred
------------------------------------------------------------------------------*/
-file_error osd_rmfile(const char *filename);
/*-----------------------------------------------------------------------------
@@ -383,7 +379,7 @@ void osd_closedir(osd_directory *dir);
non-zero if the path is absolute, zero otherwise
-----------------------------------------------------------------------------*/
-int osd_is_absolute_path(const char *path);
+bool osd_is_absolute_path(const std::string &path);
@@ -812,7 +808,7 @@ char *osd_get_clipboard_text(void);
free with osd_free()
-----------------------------------------------------------------------------*/
-osd_directory_entry *osd_stat(const char *path);
+osd_directory_entry *osd_stat(std::string const &path);
/***************************************************************************
PATH INTERFACES
@@ -824,14 +820,14 @@ osd_directory_entry *osd_stat(const char *path);
Parameters:
path - the path in question
- dst - pointer to receive new path; the returned string needs to be osd_free()-ed!
+ dst - reference to receive new path
Return value:
file error
-----------------------------------------------------------------------------*/
-file_error osd_get_full_path(char **dst, const char *path);
+osd_file::error osd_get_full_path(std::string &dst, std::string const &path);
/***************************************************************************
@@ -882,7 +878,7 @@ const char *osd_get_volume_name(int idx);
src - source string
-----------------------------------------------------------------------------*/
-void osd_subst_env(char **dst, const char *src);
+void osd_subst_env(std::string &dst,std::string const &src);
/* ----- output management ----- */
@@ -933,4 +929,4 @@ void CLIB_DECL osd_printf_debug(const char *format, ...) ATTR_PRINTF(1,2);
#define printf !MUST_USE_osd_printf_*_CALLS_WITHIN_THE_CORE!
*/
-#endif /* __OSDEPEND_H__ */
+#endif // MAME_OSD_OSDCORE_H
diff --git a/src/osd/osdepend.h b/src/osd/osdepend.h
index 3e5b7d91e8f..b6ab45003e1 100644
--- a/src/osd/osdepend.h
+++ b/src/osd/osdepend.h
@@ -10,14 +10,18 @@
#pragma once
-#ifndef __OSDEPEND_H__
-#define __OSDEPEND_H__
+#ifndef MAME_OSD_OSDEPEND_H
+#define MAME_OSD_OSDEPEND_H
#include "emucore.h"
#include "osdcore.h"
#include "unicode.h"
#include "cliopts.h"
+#include <memory>
+#include <string>
+#include <vector>
+
// forward references
class input_type_entry; // FIXME: including emu.h does not work because emu.h includes osdepend.h
@@ -32,11 +36,22 @@ class input_type_entry; // FIXME: including emu.h does not work because emu.
class osd_font
{
public:
- virtual ~osd_font() {}
+ typedef std::unique_ptr<osd_font> ptr;
+
+ virtual ~osd_font() { }
- virtual bool open(const char *font_path, const char *name, int &height) = 0;
+ /** attempt to "open" a handle to the font with the given name */
+ virtual bool open(std::string const &font_path, std::string const &name, int &height) = 0;
+
+ /** release resources associated with a given OSD font */
virtual void close() = 0;
- virtual bool get_bitmap(unicode_char chnum, bitmap_argb32 &bitmap, INT32 &width, INT32 &xoffs, INT32 &yoffs) = 0;
+
+ /*!
+ * allocate and populate a BITMAP_FORMAT_ARGB32 bitmap containing
+ * the pixel values rgb_t(0xff,0xff,0xff,0xff) or
+ * rgb_t(0x00,0xff,0xff,0xff) for each pixel of a black & white font
+ */
+ virtual bool get_bitmap(unicode_char chnum, bitmap_argb32 &bitmap, std::int32_t &width, std::int32_t &xoffs, std::int32_t &yoffs) = 0;
};
// ======================> osd_interface
@@ -68,7 +83,8 @@ public:
virtual slider_state *get_slider_list() = 0;
// font interface
- virtual osd_font *font_alloc() = 0;
+ virtual osd_font::ptr font_alloc() = 0;
+ virtual bool get_font_families(std::string const &font_path, std::vector<std::pair<std::string, std::string> > &result) = 0;
// command option overrides
virtual bool execute_command(const char *command) = 0;
@@ -80,4 +96,4 @@ protected:
virtual ~osd_interface() { }
};
-#endif /* __OSDEPEND_H__ */
+#endif // MAME_OSD_OSDEPEND_H
diff --git a/src/osd/osdmini/minidir.cpp b/src/osd/osdmini/minidir.cpp
index e061b644cdf..dde1448a694 100644
--- a/src/osd/osdmini/minidir.cpp
+++ b/src/osd/osdmini/minidir.cpp
@@ -42,14 +42,3 @@ void osd_closedir(osd_directory *dir)
// since there are no standard C library routines for walking directories,
// we do nothing
}
-
-
-//============================================================
-// osd_is_absolute_path
-//============================================================
-
-int osd_is_absolute_path(const char *path)
-{
- // assume no for everything
- return FALSE;
-}
diff --git a/src/osd/osdmini/minifile.cpp b/src/osd/osdmini/minifile.cpp
deleted file mode 100644
index b963634da51..00000000000
--- a/src/osd/osdmini/minifile.cpp
+++ /dev/null
@@ -1,238 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Aaron Giles
-//============================================================
-//
-// minifile.c - Minimal core file access functions
-//
-//============================================================
-
-#include "osdcore.h"
-#include <stdlib.h>
-#include <unistd.h>
-
-
-//============================================================
-// osd_open
-//============================================================
-
-file_error osd_open(const char *path, UINT32 openflags, osd_file **file, UINT64 *filesize)
-{
- const char *mode;
- FILE *fileptr;
-
- // based on the flags, choose a mode
- if (openflags & OPEN_FLAG_WRITE)
- {
- if (openflags & OPEN_FLAG_READ)
- mode = (openflags & OPEN_FLAG_CREATE) ? "w+b" : "r+b";
- else
- mode = "wb";
- }
- else if (openflags & OPEN_FLAG_READ)
- mode = "rb";
- else
- return FILERR_INVALID_ACCESS;
-
- // open the file
- fileptr = fopen(path, mode);
- if (fileptr == nullptr)
- return FILERR_NOT_FOUND;
-
- // store the file pointer directly as an osd_file
- *file = (osd_file *)fileptr;
-
- // get the size -- note that most fseek/ftell implementations are limited to 32 bits
- fseek(fileptr, 0, SEEK_END);
- *filesize = ftell(fileptr);
- fseek(fileptr, 0, SEEK_SET);
-
- return FILERR_NONE;
-}
-
-
-//============================================================
-// osd_close
-//============================================================
-
-file_error osd_close(osd_file *file)
-{
- // close the file handle
- fclose((FILE *)file);
- return FILERR_NONE;
-}
-
-
-//============================================================
-// osd_read
-//============================================================
-
-file_error osd_read(osd_file *file, void *buffer, UINT64 offset, UINT32 length, UINT32 *actual)
-{
- size_t count;
-
- // seek to the new location; note that most fseek implementations are limited to 32 bits
- fseek((FILE *)file, offset, SEEK_SET);
-
- // perform the read
- count = fread(buffer, 1, length, (FILE *)file);
- if (actual != nullptr)
- *actual = count;
-
- return FILERR_NONE;
-}
-
-
-//============================================================
-// osd_write
-//============================================================
-
-file_error osd_write(osd_file *file, const void *buffer, UINT64 offset, UINT32 length, UINT32 *actual)
-{
- size_t count;
-
- // seek to the new location; note that most fseek implementations are limited to 32 bits
- fseek((FILE *)file, offset, SEEK_SET);
-
- // perform the write
- count = fwrite(buffer, 1, length, (FILE *)file);
- if (actual != nullptr)
- *actual = count;
-
- return FILERR_NONE;
-}
-
-//============================================================
-// osd_openpty
-//============================================================
-
-file_error osd_openpty(osd_file **file, char *name, size_t name_len)
-{
- return FILERR_FAILURE;
-}
-
-//============================================================
-// osd_truncate
-//============================================================
-
-file_error osd_truncate(osd_file *file, UINT64 offset)
-{
- UINT32 result;
-
- if (!file)
- return FILERR_FAILURE;
-
- result = ftruncate(fileno((FILE *)file), offset);
- if (result)
- return FILERR_FAILURE;
-
- return FILERR_NONE;
-}
-
-//============================================================
-// osd_fflush
-//============================================================
-
-file_error osd_fflush(osd_file *file)
-{
- if (!file)
- return FILERR_FAILURE;
-
- int result = fflush((FILE *)file);
- if (result == EOF)
- return FILERR_FAILURE;
-
- return FILERR_NONE;
-}
-
-
-//============================================================
-// osd_rmfile
-//============================================================
-
-file_error osd_rmfile(const char *filename)
-{
- return remove(filename) ? FILERR_FAILURE : FILERR_NONE;
-}
-
-
-//============================================================
-// osd_get_physical_drive_geometry
-//============================================================
-
-int osd_get_physical_drive_geometry(const char *filename, UINT32 *cylinders, UINT32 *heads, UINT32 *sectors, UINT32 *bps)
-{
- // there is no standard way of doing this, so we always return FALSE, indicating
- // that a given path is not a physical drive
- return FALSE;
-}
-
-
-//============================================================
-// osd_uchar_from_osdchar
-//============================================================
-
-int osd_uchar_from_osdchar(UINT32 /* unicode_char */ *uchar, const char *osdchar, size_t count)
-{
- // we assume a standard 1:1 mapping of characters to the first 256 unicode characters
- *uchar = (UINT8)*osdchar;
- return 1;
-}
-
-
-//============================================================
-// osd_stat
-//============================================================
-
-osd_directory_entry *osd_stat(const char *path)
-{
- osd_directory_entry *result = nullptr;
-
- // create an osd_directory_entry; be sure to make sure that the caller can
- // free all resources by just freeing the resulting osd_directory_entry
- result = (osd_directory_entry *)osd_malloc_array(sizeof(*result) + strlen(path) + 1);
- strcpy((char *)(result + 1), path);
- result->name = (char *)(result + 1);
- result->type = ENTTYPE_NONE;
- result->size = 0;
-
- FILE *f = fopen(path, "rb");
- if (f != nullptr)
- {
- fseek(f, 0, SEEK_END);
- result->type = ENTTYPE_FILE;
- result->size = ftell(f);
- fclose(f);
- }
- return result;
-}
-
-
-//============================================================
-// osd_get_full_path
-//============================================================
-
-file_error osd_get_full_path(char **dst, const char *path)
-{
- // derive the full path of the file in an allocated string
- // for now just fake it since we don't presume any underlying file system
- *dst = nullptr;
- if (path != nullptr)
- {
- *dst = (char *)osd_malloc_array(strlen(path) + 1);
- if (*dst != nullptr)
- strcpy(*dst, path);
- }
-
- return FILERR_NONE;
-}
-
-
-//============================================================
-// osd_get_volume_name
-//============================================================
-
-const char *osd_get_volume_name(int idx)
-{
- // we don't expose volumes
- return nullptr;
-}
diff --git a/src/osd/osdmini/minimisc.cpp b/src/osd/osdmini/minimisc.cpp
index 9891447359b..fb4901ca461 100644
--- a/src/osd/osdmini/minimisc.cpp
+++ b/src/osd/osdmini/minimisc.cpp
@@ -103,9 +103,7 @@ int osd_setenv(const char *name, const char *value, int overwrite)
//============================================================
// osd_subst_env
//============================================================
-void osd_subst_env(char **dst, const char *src)
+void osd_subst_env(std::string &dst, const std::string &src)
{
- *dst = (char *)osd_malloc_array(strlen(src) + 1);
- if (*dst != nullptr)
- strcpy(*dst, src);
+ dst = src;
}
diff --git a/src/osd/sdl/osdsdl.h b/src/osd/sdl/osdsdl.h
index 0f6c3526c14..ddeabebc386 100644
--- a/src/osd/sdl/osdsdl.h
+++ b/src/osd/sdl/osdsdl.h
@@ -152,19 +152,11 @@ public:
virtual bool video_init() override;
virtual bool window_init() override;
-#ifdef USE_OLD_SDL_INPUT
- virtual bool input_init() override;
- virtual void input_pause() override;
- virtual void input_resume() override;
-#endif
virtual bool output_init() override;
//virtual bool midi_init();
virtual void video_exit() override;
virtual void window_exit() override;
-#ifdef USE_OLD_SDL_INPUT
- virtual void input_exit() override;
-#endif
virtual void output_exit() override;
//virtual void midi_exit();
diff --git a/src/osd/sdl/sdldir.cpp b/src/osd/sdl/sdldir.cpp
index 3d5071171d8..439eb0a9792 100644
--- a/src/osd/sdl/sdldir.cpp
+++ b/src/osd/sdl/sdldir.cpp
@@ -26,6 +26,10 @@
#define _XOPEN_SOURCE 500
#endif
+#include <cctype>
+#include <cstdlib>
+#include <utility>
+
//#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
@@ -234,4 +238,79 @@ void osd_closedir(osd_directory *dir)
}
+//============================================================
+// osd_subst_env
+//============================================================
+
+void osd_subst_env(std::string &dst, std::string const &src)
+{
+ std::string result, var;
+ auto start = src.begin();
+
+ // a leading tilde expands as $HOME
+ if ((src.end() != start) && ('~' == *start))
+ {
+ char const *const home = std::getenv("HOME");
+ if (home)
+ {
+ ++start;
+ if ((src.end() == start) || (PATHSEPCH == *start))
+ result.append(home);
+ else
+ result.push_back('~');
+ }
+ }
+
+ while (src.end() != start)
+ {
+ // find $ marking start of environment variable or end of string
+ auto it = start;
+ while ((src.end() != it) && ('$' != *it)) ++it;
+ if (start != it) result.append(start, it);
+ start = it;
+
+ if (src.end() != start)
+ {
+ start = ++it;
+ if ((src.end() != start) && ('{' == *start))
+ {
+ start = ++it;
+ for (++it; (src.end() != it) && ('}' != *it); ++it) { }
+ if (src.end() == it)
+ {
+ result.append("${").append(start, it);
+ start = it;
+ }
+ else
+ {
+ var.assign(start, it);
+ start = ++it;
+ const char *const exp = std::getenv(var.c_str());
+ if (exp)
+ result.append(exp);
+ else
+ fprintf(stderr, "Warning: osd_subst_env variable %s not found.\n", var.c_str());
+ }
+ }
+ else if ((src.end() != start) && (('_' == *start) || std::isalnum(*start)))
+ {
+ for (++it; (src.end() != it) && (('_' == *it) || std::isalnum(*it)); ++it) { }
+ var.assign(start, it);
+ start = it;
+ const char *const exp = std::getenv(var.c_str());
+ if (exp)
+ result.append(exp);
+ else
+ fprintf(stderr, "Warning: osd_subst_env variable %s not found.\n", var.c_str());
+ }
+ else
+ {
+ result.push_back('$');
+ }
+ }
+ }
+
+ dst = std::move(result);
+}
+
#endif
diff --git a/src/osd/sdl/sdlfile.cpp b/src/osd/sdl/sdlfile.cpp
deleted file mode 100644
index aa57e3356a0..00000000000
--- a/src/osd/sdl/sdlfile.cpp
+++ /dev/null
@@ -1,630 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Olivier Galibert, R. Belmont
-//============================================================
-//
-// sdlfile.c - SDL file access functions
-//
-// SDLMAME by Olivier Galibert and R. Belmont
-//
-//============================================================
-
-#ifdef SDLMAME_WIN32
-#include "../windows/winfile.cpp"
-#include "../windows/winutil.cpp"
-#else
-
-#ifndef _LARGEFILE64_SOURCE
-#define _LARGEFILE64_SOURCE
-#endif
-
-#ifdef SDLMAME_LINUX
-#define __USE_LARGEFILE64
-#endif
-
-#ifdef SDLMAME_WIN32
-#define _FILE_OFFSET_BITS 64
-#endif
-
-#ifndef SDLMAME_BSD
-#ifdef _XOPEN_SOURCE
-#undef _XOPEN_SOURCE
-#endif
-#define _XOPEN_SOURCE 500
-#endif
-
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <errno.h>
-
-// MAME headers
-#include "sdlfile.h"
-#include "modules/lib/osdlib.h"
-
-//============================================================
-// GLOBAL IDENTIFIERS
-//============================================================
-
-extern const char *sdlfile_socket_identifier;
-extern const char *sdlfile_ptty_identifier;
-
-//============================================================
-// CONSTANTS
-//============================================================
-
-#if defined(SDLMAME_WIN32)
-#define PATHSEPCH '\\'
-#define INVPATHSEPCH '/'
-#else
-#define PATHSEPCH '/'
-#define INVPATHSEPCH '\\'
-#endif
-
-#define NO_ERROR (0)
-
-//============================================================
-// Prototypes
-//============================================================
-
-static UINT32 create_path_recursive(char *path);
-
-//============================================================
-// error_to_file_error
-// (does filling this out on non-Windows make any sense?)
-//============================================================
-
-file_error error_to_file_error(UINT32 error)
-{
- switch (error)
- {
- case ENOENT:
- case ENOTDIR:
- return FILERR_NOT_FOUND;
-
- case EACCES:
- case EROFS:
- #ifndef SDLMAME_WIN32
- case ETXTBSY:
- #endif
- case EEXIST:
- case EPERM:
- case EISDIR:
- case EINVAL:
- return FILERR_ACCESS_DENIED;
-
- case ENFILE:
- case EMFILE:
- return FILERR_TOO_MANY_FILES;
-
- default:
- return FILERR_FAILURE;
- }
-}
-
-
-//============================================================
-// osd_open
-//============================================================
-
-file_error osd_open(const char *path, UINT32 openflags, osd_file **file, UINT64 *filesize)
-{
- UINT32 access;
- const char *src;
- char *dst;
- #if defined(SDLMAME_DARWIN) || defined(SDLMAME_WIN32) || defined(SDLMAME_NO64BITIO) || defined(SDLMAME_BSD) || defined(SDLMAME_HAIKU)
- struct stat st;
- #else
- struct stat64 st;
- #endif
- char *tmpstr;
- file_error filerr = FILERR_NONE;
-
- tmpstr = NULL;
-
- // allocate a file object, plus space for the converted filename
- *file = (osd_file *) osd_malloc_array(sizeof(**file) + sizeof(char) * strlen(path));
- if (*file == NULL)
- {
- filerr = FILERR_OUT_OF_MEMORY;
- goto error;
- }
-
- if (sdl_check_socket_path(path))
- {
- (*file)->type = SDLFILE_SOCKET;
- filerr = sdl_open_socket(path, openflags, file, filesize);
- if(filerr != FILERR_NONE && (*file)->socket != -1)
- close((*file)->socket);
- goto error;
- }
-
- if (strlen(sdlfile_ptty_identifier) > 0 && strncmp(path, sdlfile_ptty_identifier, strlen(sdlfile_ptty_identifier)) == 0)
- {
- (*file)->type = SDLFILE_PTTY;
- filerr = sdl_open_ptty(path, openflags, file, filesize);
- goto error;
- }
-
- (*file)->type = SDLFILE_FILE;
-
- // convert the path into something compatible
- dst = (*file)->filename;
- for (src = path; *src != 0; src++)
- *dst++ = (*src == INVPATHSEPCH) ? PATHSEPCH : *src;
- *dst++ = 0;
-
- // select the file open modes
- if (openflags & OPEN_FLAG_WRITE)
- {
- access = (openflags & OPEN_FLAG_READ) ? O_RDWR : O_WRONLY;
- access |= (openflags & OPEN_FLAG_CREATE) ? (O_CREAT | O_TRUNC) : 0;
- }
- else if (openflags & OPEN_FLAG_READ)
- {
- access = O_RDONLY;
- }
- else
- {
- filerr = FILERR_INVALID_ACCESS;
- goto error;
- }
-
- osd_subst_env(&tmpstr, (*file)->filename);
-
- #if defined(SDLMAME_WIN32)
- access |= O_BINARY;
- #endif
-
- // attempt to open the file
- #if defined(SDLMAME_DARWIN) || defined(SDLMAME_WIN32) || defined(SDLMAME_NO64BITIO) || defined(SDLMAME_BSD) || defined(SDLMAME_HAIKU)
- (*file)->handle = open(tmpstr, access, 0666);
- #else
- (*file)->handle = open64(tmpstr, access, 0666);
- #endif
- if ((*file)->handle == -1)
- {
- // create the path if necessary
- if ((openflags & OPEN_FLAG_CREATE) && (openflags & OPEN_FLAG_CREATE_PATHS))
- {
- char *pathsep = strrchr(tmpstr, PATHSEPCH);
- if (pathsep != NULL)
- {
- int error;
-
- // create the path up to the file
- *pathsep = 0;
- error = create_path_recursive(tmpstr);
- *pathsep = PATHSEPCH;
-
- // attempt to reopen the file
- if (error == NO_ERROR)
- {
- #if defined(SDLMAME_DARWIN) || defined(SDLMAME_WIN32) || defined(SDLMAME_NO64BITIO) || defined(SDLMAME_BSD) || defined(SDLMAME_HAIKU)
- (*file)->handle = open(tmpstr, access, 0666);
- #else
- (*file)->handle = open64(tmpstr, access, 0666);
- #endif
- }
- }
- }
-
- // if we still failed, clean up and osd_free
- if ((*file)->handle == -1)
- {
- osd_free(*file);
- *file = NULL;
- osd_free(tmpstr);
- return error_to_file_error(errno);
- }
- }
-
- // get the file size
- #if defined(SDLMAME_DARWIN) || defined(SDLMAME_WIN32) || defined(SDLMAME_NO64BITIO) || defined(SDLMAME_BSD) || defined(SDLMAME_HAIKU)
- fstat((*file)->handle, &st);
- #else
- fstat64((*file)->handle, &st);
- #endif
-
- *filesize = (UINT64)st.st_size;
-
-error:
- // cleanup
- if (filerr != FILERR_NONE && *file != NULL)
- {
- osd_free(*file);
- *file = NULL;
- }
- if (tmpstr)
- osd_free(tmpstr);
- return filerr;
-}
-
-
-//============================================================
-// osd_read
-//============================================================
-
-file_error osd_read(osd_file *file, void *buffer, UINT64 offset, UINT32 count, UINT32 *actual)
-{
- ssize_t result;
-
- switch (file->type)
- {
- case SDLFILE_FILE:
-#if defined(SDLMAME_DARWIN) || defined(SDLMAME_BSD) || defined(SDLMAME_EMSCRIPTEN)
- result = pread(file->handle, buffer, count, offset);
- if (result < 0)
-#elif defined(SDLMAME_WIN32) || defined(SDLMAME_NO64BITIO)
- lseek(file->handle, (UINT32)offset&0xffffffff, SEEK_SET);
- result = read(file->handle, buffer, count);
- if (result < 0)
-#elif defined(SDLMAME_UNIX)
- result = pread64(file->handle, buffer, count, offset);
- if (result < 0)
-#else
-#error Unknown SDL SUBARCH!
-#endif
- return error_to_file_error(errno);
-
- if (actual != NULL)
- *actual = result;
-
- return FILERR_NONE;
-
- case SDLFILE_SOCKET:
- return sdl_read_socket(file, buffer, offset, count, actual);
-
- case SDLFILE_PTTY:
- return sdl_read_ptty(file, buffer, offset, count, actual);
-
- default:
- return FILERR_FAILURE;
- }
-}
-
-
-//============================================================
-// osd_write
-//============================================================
-
-file_error osd_write(osd_file *file, const void *buffer, UINT64 offset, UINT32 count, UINT32 *actual)
-{
- UINT32 result;
-
- switch (file->type)
- {
- case SDLFILE_FILE:
-#if defined(SDLMAME_DARWIN) || defined(SDLMAME_BSD) || defined(SDLMAME_EMSCRIPTEN)
- result = pwrite(file->handle, buffer, count, offset);
- if (!result)
-#elif defined(SDLMAME_WIN32) || defined(SDLMAME_NO64BITIO)
- lseek(file->handle, (UINT32)offset&0xffffffff, SEEK_SET);
- result = write(file->handle, buffer, count);
- if (!result)
-#elif defined(SDLMAME_UNIX)
- result = pwrite64(file->handle, buffer, count, offset);
- if (!result)
-#else
-#error Unknown SDL SUBARCH!
-#endif
- return error_to_file_error(errno);
-
- if (actual != NULL)
- *actual = result;
- return FILERR_NONE;
-
- case SDLFILE_SOCKET:
- return sdl_write_socket(file, buffer, offset, count, actual);
-
- case SDLFILE_PTTY:
- return sdl_write_ptty(file, buffer, offset, count, actual);
-
- default:
- return FILERR_FAILURE;
- }
-}
-
-//============================================================
-// osd_openpty
-//============================================================
-
-file_error osd_openpty(osd_file **file, char *name, size_t name_len)
-{
- file_error res;
- UINT64 filesize;
-
- if ((res = osd_open(sdlfile_ptty_identifier , 0 , file , &filesize)) != FILERR_NONE) {
- return res;
- }
-
- if ((res = sdl_slave_name_ptty(*file , name , name_len)) != FILERR_NONE) {
- osd_close(*file);
- }
-
- return res;
-}
-
-//============================================================
-// osd_truncate
-//============================================================
-
-file_error osd_truncate(osd_file *file, UINT64 offset)
-{
- UINT32 result;
-
- if (!file || !file->handle)
- return FILERR_FAILURE;
-
- switch (file->type)
- {
- case SDLFILE_FILE:
- result = ftruncate(file->handle, offset);
- if (result)
- return error_to_file_error(errno);
- return FILERR_NONE;
-
- default:
- return FILERR_FAILURE;
- }
-}
-
-//============================================================
-// osd_truncate
-//============================================================
-
-file_error osd_fflush(osd_file *file)
-{
- if (!file || !file->handle)
- return FILERR_FAILURE;
-
- switch (file->type)
- {
- case SDLFILE_FILE:
- return FILERR_NONE;
-
- default:
- return FILERR_FAILURE;
- }
-}
-
-
-//============================================================
-// osd_close
-//============================================================
-
-file_error osd_close(osd_file *file)
-{
- // close the file handle and free the file structure
- switch (file->type)
- {
- case SDLFILE_FILE:
- close(file->handle);
- osd_free(file);
- return FILERR_NONE;
-
- case SDLFILE_SOCKET:
- return sdl_close_socket(file);
-
- case SDLFILE_PTTY:
- return sdl_close_ptty(file);
-
- default:
- return FILERR_FAILURE;
- }
-}
-
-//============================================================
-// osd_rmfile
-//============================================================
-
-file_error osd_rmfile(const char *filename)
-{
- if (unlink(filename) == -1)
- {
- return error_to_file_error(errno);
- }
-
- return FILERR_NONE;
-}
-
-//============================================================
-// create_path_recursive
-//============================================================
-
-static UINT32 create_path_recursive(char *path)
-{
- char *sep = strrchr(path, PATHSEPCH);
- UINT32 filerr;
- struct stat st;
-
- // if there's still a separator, and it's not the root, nuke it and recurse
- if (sep != NULL && sep > path && sep[0] != ':' && sep[-1] != PATHSEPCH)
- {
- *sep = 0;
- filerr = create_path_recursive(path);
- *sep = PATHSEPCH;
- if (filerr != NO_ERROR)
- return filerr;
- }
-
- // if the path already exists, we're done
- if (!stat(path, &st))
- return NO_ERROR;
-
- // create the path
- #ifdef SDLMAME_WIN32
- if (mkdir(path) != 0)
- #else
- if (mkdir(path, 0777) != 0)
- #endif
- return error_to_file_error(errno);
- return NO_ERROR;
-}
-
-//============================================================
-// osd_get_physical_drive_geometry
-//============================================================
-
-int osd_get_physical_drive_geometry(const char *filename, UINT32 *cylinders, UINT32 *heads, UINT32 *sectors, UINT32 *bps)
-{
- return FALSE; // no, no way, huh-uh, forget it
-}
-
-//============================================================
-// osd_is_path_separator
-//============================================================
-
-static int osd_is_path_separator(char c)
-{
- return (c == PATHSEPCH) || (c == INVPATHSEPCH);
-}
-
-//============================================================
-// osd_is_absolute_path
-//============================================================
-
-int osd_is_absolute_path(const char *path)
-{
- int result;
-
- if (osd_is_path_separator(path[0]))
- result = TRUE;
-#if !defined(SDLMAME_WIN32)
- else if (path[0] == '.')
- result = TRUE;
-#else
- #ifndef UNDER_CE
- else if (*path && path[1] == ':')
- result = TRUE;
- #endif
-#endif
- else
- result = FALSE;
-
- return result;
-}
-
-//============================================================
-// osd_stat
-//============================================================
-
-osd_directory_entry *osd_stat(const char *path)
-{
- int err;
- osd_directory_entry *result = NULL;
- #if defined(SDLMAME_NO64BITIO) || defined(SDLMAME_BSD) || defined(SDLMAME_DARWIN)
- struct stat st;
- #else
- struct stat64 st;
- #endif
-
- #if defined(SDLMAME_NO64BITIO) || defined(SDLMAME_BSD) || defined(SDLMAME_DARWIN)
- err = stat(path, &st);
- #else
- err = stat64(path, &st);
- #endif
-
- if( err == -1) return NULL;
-
- // create an osd_directory_entry; be sure to make sure that the caller can
- // free all resources by just freeing the resulting osd_directory_entry
- result = (osd_directory_entry *) osd_malloc_array(sizeof(*result) + strlen(path) + 1);
- strcpy(((char *) result) + sizeof(*result), path);
- result->name = ((char *) result) + sizeof(*result);
- result->type = S_ISDIR(st.st_mode) ? ENTTYPE_DIR : ENTTYPE_FILE;
- result->size = (UINT64)st.st_size;
-
- return result;
-}
-
-//============================================================
-// osd_get_full_path
-//============================================================
-
-file_error osd_get_full_path(char **dst, const char *path)
-{
- file_error err;
- char path_buffer[512];
-
- err = FILERR_NONE;
-
- if (getcwd(path_buffer, 511) == NULL)
- {
- printf("osd_get_full_path: failed!\n");
- err = FILERR_FAILURE;
- }
- else
- {
- *dst = (char *)osd_malloc_array(strlen(path_buffer)+strlen(path)+3);
-
- // if it's already a full path, just pass it through
- if (path[0] == '/')
- {
- strcpy(*dst, path);
- }
- else
- {
- sprintf(*dst, "%s%s%s", path_buffer, PATH_SEPARATOR, path);
- }
- }
-
- return err;
-}
-
-//============================================================
-// osd_get_volume_name
-//============================================================
-
-const char *osd_get_volume_name(int idx)
-{
- if (idx!=0) return NULL;
- return "/";
-}
-
-//============================================================
-// osd_subst_env
-//============================================================
-void osd_subst_env(char **dst, const char *src)
-{
- int i, j;
- char *envstr;
-
- osd_free(*dst);
- *dst = (char *) osd_malloc_array(strlen(src)+1);
- strcpy(*dst, src);
-
- // start with an environment variable?
- if (*dst[0] == '$')
- {
- envstr = (char *) osd_malloc_array(strlen(src)+1);
- strcpy(envstr, src);
-
- i = 0;
- while (!osd_is_path_separator(envstr[i]) && envstr[i] != 0 && envstr[i] != '.')
- {
- i++;
- }
-
- envstr[i] = '\0';
-
- const char *envval = osd_getenv(&envstr[1]);
- if (envval != NULL)
- {
- j = strlen(envval) + strlen(*dst) + 1;
- osd_free(*dst);
- *dst = (char *) osd_malloc_array(j);
-
- // start with the value of $HOME
- strcpy(*dst, envval);
- // replace the null with a path separator again
- envstr[i] = PATHSEPCH;
- // append it
- strcat(*dst, &envstr[i]);
- }
- else
- fprintf(stderr, "Warning: osd_subst_env variable %s not found.\n", envstr);
- osd_free(envstr);
- }
-}
-#endif
diff --git a/src/osd/sdl/sdlfile.h b/src/osd/sdl/sdlfile.h
deleted file mode 100644
index 4bd1b2a6292..00000000000
--- a/src/osd/sdl/sdlfile.h
+++ /dev/null
@@ -1,51 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Olivier Galibert, R. Belmont
-//============================================================
-//
-// sdlfile.h - SDL file access functions
-//
-// SDLMAME by Olivier Galibert and R. Belmont
-//
-//============================================================
-
-#include "osdcore.h"
-
-//============================================================
-// ENUM DEFINITIONS
-//============================================================
-enum
-{
- SDLFILE_FILE = 0,
- SDLFILE_SOCKET,
- SDLFILE_PTTY
-};
-
-//============================================================
-// TYPE DEFINITIONS
-//============================================================
-
-struct osd_file
-{
- int handle;
- int socket;
- int type;
- char filename[1];
-};
-
-//============================================================
-// PROTOTYPES
-//============================================================
-
-bool sdl_check_socket_path(const char *path);
-file_error sdl_open_socket(const char *path, UINT32 openflags, osd_file **file, UINT64 *filesize);
-file_error sdl_read_socket(osd_file *file, void *buffer, UINT64 offset, UINT32 count, UINT32 *actual);
-file_error sdl_write_socket(osd_file *file, const void *buffer, UINT64 offset, UINT32 count, UINT32 *actual);
-file_error sdl_close_socket(osd_file *file);
-
-file_error sdl_open_ptty(const char *path, UINT32 openflags, osd_file **file, UINT64 *filesize);
-file_error sdl_read_ptty(osd_file *file, void *buffer, UINT64 offset, UINT32 count, UINT32 *actual);
-file_error sdl_write_ptty(osd_file *file, const void *buffer, UINT64 offset, UINT32 count, UINT32 *actual);
-file_error sdl_close_ptty(osd_file *file);
-file_error sdl_slave_name_ptty(osd_file *file , char *name , size_t name_len);
-
-file_error error_to_file_error(UINT32 error);
diff --git a/src/osd/sdl/sdlptty_unix.cpp b/src/osd/sdl/sdlptty_unix.cpp
deleted file mode 100644
index 063b999b75d..00000000000
--- a/src/osd/sdl/sdlptty_unix.cpp
+++ /dev/null
@@ -1,161 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Olivier Galibert, R. Belmont
-//============================================================
-//
-// sdlptty_unix.c - SDL pseudo tty access functions
-//
-// SDLMAME by Olivier Galibert and R. Belmont
-//
-//============================================================
-
-#if (!defined(SDLMAME_SOLARIS))
-
-#include <sys/types.h>
-#include <sys/uio.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#if defined(SDLMAME_FREEBSD) || defined(SDLMAME_DRAGONFLY)
-# include <termios.h>
-# include <libutil.h>
-#elif defined(SDLMAME_NETBSD) || defined(SDLMAME_MACOSX)
-# include <termios.h>
-# include <util.h>
-#elif defined(SDLMAME_OPENBSD)
-# include <termios.h>
-# include <util.h>
-#elif defined(SDLMAME_LINUX) || defined(SDLMAME_EMSCRIPTEN)
-# include <pty.h>
-#elif defined(SDLMAME_HAIKU)
-# include <bsd/pty.h>
-#endif
-#include <stdlib.h>
-
-#include "sdlfile.h"
-
-#if defined(SDLMAME_MACOSX)
-const char *sdlfile_ptty_identifier = "/dev/pty";
-#else
-const char *sdlfile_ptty_identifier = "/dev/pts";
-#endif
-
-file_error sdl_open_ptty(const char *path, UINT32 openflags, osd_file **file, UINT64 *filesize)
-{
- int master;
- int aslave;
- struct termios tios;
- int oldflags;
-
- memset(&tios , 0 , sizeof(tios));
- cfmakeraw(&tios);
-
- if (openpty(&master, &aslave, NULL, &tios, NULL) >= 0)
- {
- oldflags = fcntl(master, F_GETFL, 0);
- if (oldflags == -1) {
- close(master);
- return FILERR_FAILURE;
- }
-
- fcntl(master, F_SETFL, oldflags | O_NONBLOCK);
- close(aslave);
- (*file)->handle = master;
- *filesize = 0;
- }
- else
- {
- return FILERR_ACCESS_DENIED;
- }
-
- return FILERR_NONE;
-}
-
-file_error sdl_read_ptty(osd_file *file, void *buffer, UINT64 offset, UINT32 count, UINT32 *actual)
-{
- ssize_t result;
-
- result = read(file->handle, buffer, count);
-
- if (result < 0)
- {
- return error_to_file_error(errno);
- }
-
- if (actual != NULL )
- {
- *actual = result;
- }
-
- return FILERR_NONE;
-}
-
-file_error sdl_write_ptty(osd_file *file, const void *buffer, UINT64 offset, UINT32 count, UINT32 *actual)
-{
- ssize_t result;
- result = write(file->handle, buffer, count);
-
- if (result < 0)
- {
- return error_to_file_error(errno);
- }
-
- if (actual != NULL )
- {
- *actual = result;
- }
-
- return FILERR_NONE;
-}
-
-file_error sdl_close_ptty(osd_file *file)
-{
- close(file->handle);
- osd_free(file);
-
- return FILERR_NONE;
-}
-
-file_error sdl_slave_name_ptty(osd_file *file , char *name , size_t name_len)
-{
- const char *slave_name = ptsname(file->handle);
-
- if (slave_name == NULL || strlen(slave_name) >= name_len) {
- return FILERR_INVALID_ACCESS;
- }
-
- strcpy(name , slave_name);
-
- return FILERR_NONE;
-}
-
-#else
-#include "sdlfile.h"
-
-const char *sdlfile_ptty_identifier = "";
-
-file_error sdl_open_ptty(const char *path, UINT32 openflags, osd_file **file, UINT64 *filesize)
-{
- return FILERR_ACCESS_DENIED;
-}
-
-file_error sdl_read_ptty(osd_file *file, void *buffer, UINT64 offset, UINT32 count, UINT32 *actual)
-{
- return FILERR_ACCESS_DENIED;
-}
-
-file_error sdl_write_ptty(osd_file *file, const void *buffer, UINT64 offset, UINT32 count, UINT32 *actual)
-{
- return FILERR_ACCESS_DENIED;
-}
-
-file_error sdl_close_ptty(osd_file *file)
-{
- return FILERR_ACCESS_DENIED;
-}
-
-file_error sdl_slave_name_ptty(osd_file *file)
-{
- return FILERR_ACCESS_DENIED;
-}
-
-#endif
diff --git a/src/osd/sdl/sdlptty_win32.cpp b/src/osd/sdl/sdlptty_win32.cpp
deleted file mode 100644
index fca49a12a99..00000000000
--- a/src/osd/sdl/sdlptty_win32.cpp
+++ /dev/null
@@ -1,12 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Olivier Galibert, R. Belmont
-//============================================================
-//
-// sdlptty_win32 - SDL psuedo tty access functions
-// (passthrough to Windows OSD version)
-//
-// SDLMAME by Olivier Galibert and R. Belmont
-//
-//============================================================
-
-#include "../windows/winptty.cpp"
diff --git a/src/osd/sdl/sdlsocket.cpp b/src/osd/sdl/sdlsocket.cpp
deleted file mode 100644
index 5d3e7030deb..00000000000
--- a/src/osd/sdl/sdlsocket.cpp
+++ /dev/null
@@ -1,193 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Olivier Galibert, R. Belmont
-//============================================================
-//
-// sdlsocket.c - SDL socket (inet) access functions
-//
-// SDLMAME by Olivier Galibert and R. Belmont
-//
-//============================================================
-
-#ifdef SDLMAME_WIN32
-#include "../windows/winsocket.cpp"
-#else
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/select.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <netdb.h>
-#include <errno.h>
-
-#include "emu.h"
-#include "sdlfile.h"
-
-const char *sdlfile_socket_identifier = "socket.";
-
-/*
- Checks whether the path is a socket specification. A valid socket
- specification has the format "socket." host ":" port. Host may be simple
- or fully qualified. Port must be between 1 and 65535.
-*/
-bool sdl_check_socket_path(const char *path)
-{
- if (strlen(sdlfile_socket_identifier) > 0 &&
- strncmp(path, sdlfile_socket_identifier, strlen(sdlfile_socket_identifier)) == 0 &&
- strchr(path, ':') != NULL) return true;
- return false;
-}
-
-file_error sdl_open_socket(const char *path, UINT32 openflags, osd_file **file, UINT64 *filesize)
-{
- char hostname[256];
- struct hostent *localhost;
- struct sockaddr_in sai;
- int flag = 1;
- int port;
-
- sscanf( path+strlen(sdlfile_socket_identifier), "%255[^:]:%d", hostname, &port );
-
-// printf("Connecting to server '%s' on port '%d'\n", hostname, port);
-
- if (((*file)->socket = socket(AF_INET, SOCK_STREAM, 0)) == -1)
- {
- return FILERR_ACCESS_DENIED;
- }
-
- if (setsockopt((*file)->socket, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(flag)) == -1)
- {
- return FILERR_ACCESS_DENIED;
- }
-
- localhost = gethostbyname(hostname);
-
- memset(&sai, 0, sizeof(sai));
- sai.sin_family = AF_INET;
- sai.sin_port = htons(port);
- sai.sin_addr = *((struct in_addr *)localhost->h_addr);
-
- // listening socket support
- if (openflags & OPEN_FLAG_CREATE)
- {
-// printf("Listening for client at '%s' on port '%d'\n", hostname, port);
- // bind socket...
- if (bind((*file)->socket, (struct sockaddr *)&sai, sizeof(struct sockaddr)) == -1)
- {
- return FILERR_ACCESS_DENIED;
- }
-
- // start to listen...
- if (listen((*file)->socket, 1) == -1) {
- return FILERR_ACCESS_DENIED;
- }
-
- // mark socket as "listening"
- (*file)->handle = 0;
- *filesize = 0;
- return FILERR_NONE;
- }
-
-// printf("Connecting to server '%s' on port '%d'\n", hostname, port);
- if (connect((*file)->socket, (struct sockaddr *)&sai, sizeof(struct sockaddr)) == -1)
- {
- return FILERR_ACCESS_DENIED;
- }
-
- *filesize = 0;
- (*file)->handle = -1;
- return FILERR_NONE;
-}
-
-file_error sdl_read_socket(osd_file *file, void *buffer, UINT64 offset, UINT32 count, UINT32 *actual)
-{
-#if (!defined(SDLMAME_EMSCRIPTEN))
- ssize_t result;
- char line[80];
- struct timeval timeout;
- fd_set readfds;
-
- FD_ZERO(&readfds);
- FD_SET(file->socket, &readfds);
- timeout.tv_sec = timeout.tv_usec = 0;
-
- if (select(file->socket + 1, &readfds, NULL, NULL, &timeout) < 0)
- {
- sprintf(line, "%s : %s : %d ", __func__, __FILE__, __LINE__);
- perror(line);
- return error_to_file_error(errno);
- }
- else if (FD_ISSET(file->socket, &readfds))
- {
- if (file->handle == -1)
- {
- // connected socket
- result = read(file->socket, buffer, count);
- }
- else
- {
- // listening socket
- int AcceptSocket;
- AcceptSocket = accept(file->socket, NULL, NULL);
- if (AcceptSocket < 0)
- {
- return FILERR_FAILURE;
- }
- close(file->socket);
- file->socket = AcceptSocket;
- file->handle = -1;
- if (actual != NULL )
- {
- *actual = 0;
- }
-
- return FILERR_NONE;
- }
- }
- else
- {
- return FILERR_FAILURE;
- }
-
- if (result < 0)
- {
- return error_to_file_error(errno);
- }
-
- if (actual != NULL )
- {
- *actual = result;
- }
-#endif
- return FILERR_NONE;
-}
-
-file_error sdl_write_socket(osd_file *file, const void *buffer, UINT64 offset, UINT32 count, UINT32 *actual)
-{
- ssize_t result;
-
- result = write(file->socket, buffer, count);
-
- if (result < 0)
- {
- return error_to_file_error(errno);
- }
-
- if (actual != NULL )
- {
- *actual = result;
- }
- return FILERR_NONE;
-}
-
-file_error sdl_close_socket(osd_file *file)
-{
- close(file->socket);
- osd_free(file);
- return FILERR_NONE;
-}
-#endif
diff --git a/src/osd/sdl/video.cpp b/src/osd/sdl/video.cpp
index b20dbcb9498..051b8d07c44 100644
--- a/src/osd/sdl/video.cpp
+++ b/src/osd/sdl/video.cpp
@@ -342,12 +342,7 @@ finishit:
static void check_osd_inputs(running_machine &machine)
{
-#ifdef USE_OLD_SDL_INPUT
- sdl_window_info *window = sdlinput_get_focus_window();
-#else
- // BUG: TODO: Fix focus window support
sdl_window_info *window = sdl_window_list;
-#endif
// check for toggling fullscreen mode
if (machine.ui_input().pressed(IPT_OSD_1))
diff --git a/src/osd/sdl/window.cpp b/src/osd/sdl/window.cpp
index 617dca4c971..f0f947ba503 100644
--- a/src/osd/sdl/window.cpp
+++ b/src/osd/sdl/window.cpp
@@ -607,13 +607,8 @@ void sdl_window_info::update_cursor_state()
// the possibility of losing control
if (!(machine().debug_flags & DEBUG_FLAG_OSD_ENABLED))
{
- //FIXME: SDL1.3: really broken: the whole SDL code
- // will only work correct with relative mouse movements ...
-#ifdef USE_OLD_SDL_INPUT
- bool should_hide_mouse = sdlinput_should_hide_mouse();
-#else
bool should_hide_mouse = downcast<sdl_osd_interface&>(machine().osd()).should_hide_mouse();
-#endif
+
if (!fullscreen() && !should_hide_mouse)
{
SDL_ShowCursor(SDL_ENABLE);
@@ -727,12 +722,7 @@ OSDWORK_CALLBACK( sdl_window_info::sdlwindow_video_window_destroy_wt )
}
SDL_DestroyWindow(window->sdl_window());
// release all keys ...
-#ifdef USE_OLD_SDL_INPUT
- sdlinput_release_keys();
-#else
downcast<sdl_osd_interface &>(window->machine().osd()).release_keys();
-#endif
-
osd_free(wp);
return nullptr;
@@ -1146,11 +1136,7 @@ OSDWORK_CALLBACK( sdl_window_info::draw_video_contents_wt )
ASSERT_REDRAW_THREAD();
// Some configurations require events to be polled in the worker thread
-#ifdef USE_OLD_SDL_INPUT
- sdlinput_process_events_buf();
-#else
downcast< sdl_osd_interface& >(window->machine().osd()).process_events_buf();
-#endif
// Check whether window has vector screens
diff --git a/src/osd/strconv.h b/src/osd/strconv.h
index 5de23d0b89b..6d23d78fbb1 100644
--- a/src/osd/strconv.h
+++ b/src/osd/strconv.h
@@ -6,8 +6,8 @@
//
//============================================================
-#ifndef __OSD_STRCONV__
-#define __OSD_STRCONV__
+#ifndef MAME_OSD_STRCONV_H
+#define MAME_OSD_STRCONV_H
#include "osdcore.h"
@@ -17,12 +17,14 @@
// FUNCTION PROTOTYPES
//============================================================
-#if defined(SDLMAME_WIN32) || defined(OSD_WINDOWS)
+#if defined(WIN32)
-#if defined(SDLMAME_WIN32)
+#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
#endif
+
+#include <windows.h>
+
// the result of these functions has to be released with osd_free()
CHAR *astring_from_utf8(const char *s);
@@ -39,7 +41,7 @@ char *utf8_from_wstring(const WCHAR *s);
#define utf8_from_tstring utf8_from_astring
#endif // UNICODE
-#endif //SDLMAME_WIN32
+#endif // defined(WIN32)
-#endif // __OSD_STRCONV__
+#endif // MAME_OSD_STRCONV_H
diff --git a/src/osd/windows/windir.cpp b/src/osd/windows/windir.cpp
index 7f172d7338a..87b1b5e05ce 100644
--- a/src/osd/windows/windir.cpp
+++ b/src/osd/windows/windir.cpp
@@ -72,7 +72,7 @@ osd_directory *osd_opendir(const char *dirname)
_sntprintf(dirfilter, dirfilter_size, TEXT("%s\\*.*"), t_dirname);
// attempt to find the first file
- dir->find = FindFirstFile(dirfilter, &dir->data);
+ dir->find = FindFirstFileEx(dirfilter, FindExInfoStandard, &dir->data, FindExSearchNameMatch, nullptr, 0);
error:
// cleanup
@@ -134,20 +134,3 @@ void osd_closedir(osd_directory *dir)
FindClose(dir->find);
free(dir);
}
-
-
-//============================================================
-// osd_is_absolute_path
-//============================================================
-
-int osd_is_absolute_path(const char *path)
-{
- int result = FALSE;
- TCHAR *t_path = tstring_from_utf8(path);
- if (t_path != NULL)
- {
- result = !PathIsRelative(t_path);
- osd_free(t_path);
- }
- return result;
-}
diff --git a/src/osd/windows/window.cpp b/src/osd/windows/window.cpp
index b94f68f570a..a5da299cddd 100644
--- a/src/osd/windows/window.cpp
+++ b/src/osd/windows/window.cpp
@@ -251,6 +251,7 @@ void windows_osd_interface::update_slider_list()
{
for (win_window_info *window = win_window_list; window != nullptr; window = window->m_next)
{
+ // check if any window has dirty sliders
if (window->m_renderer && window->m_renderer->sliders_dirty())
{
build_slider_list();
@@ -271,27 +272,13 @@ int windows_osd_interface::window_count()
void windows_osd_interface::build_slider_list()
{
- m_sliders = nullptr;
- slider_state *curr = m_sliders;
- for (win_window_info *info = win_window_list; info != nullptr; info = info->m_next)
+ // FIXME: take all sliders from all windows without concatenate them by slider_state->next
+
+ for (win_window_info *window = win_window_list; window != nullptr; window = window->m_next)
{
- slider_state *window_sliders = info->m_renderer->get_slider_list();
- if (window_sliders != nullptr)
- {
- if (m_sliders == nullptr)
- {
- m_sliders = window_sliders;
- curr = m_sliders;
- }
- else
- {
- while (curr->next != nullptr)
- {
- curr = curr->next;
- }
- curr->next = window_sliders;
- }
- }
+ // take the sliders of the first window
+ m_sliders = window->m_renderer->get_slider_list();
+ return;
}
}
diff --git a/src/osd/windows/winfile.cpp b/src/osd/windows/winfile.cpp
deleted file mode 100644
index 742f97363d6..00000000000
--- a/src/osd/windows/winfile.cpp
+++ /dev/null
@@ -1,571 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Aaron Giles
-//============================================================
-//
-// winfile.c - Win32 OSD core file access functions
-//
-//============================================================
-
-// standard windows headers
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#include <winioctl.h>
-#include <tchar.h>
-#include <stdlib.h>
-#include <ctype.h>
-
-// MAME headers
-#include "osdcore.h"
-
-// MAMEOS headers
-#include "strconv.h"
-#include "winutil.h"
-#include "winutf8.h"
-
-#include "winfile.h"
-
-//============================================================
-// FUNCTION PROTOTYPES
-//============================================================
-
-static DWORD create_path_recursive(const TCHAR *path);
-
-//============================================================
-// INLINE FUNCTIONS
-//============================================================
-
-static inline int is_path_to_physical_drive(const char *path)
-{
- return (_strnicmp(path, "\\\\.\\physicaldrive", 17) == 0);
-}
-
-extern const char *winfile_ptty_identifier;
-
-
-//============================================================
-// osd_open
-//============================================================
-
-file_error osd_open(const char *orig_path, UINT32 openflags, osd_file **file, UINT64 *filesize)
-{
- file_error filerr = FILERR_NONE;
- char *path = nullptr;
-
- osd_subst_env(&path, orig_path);
-
- // convert path to TCHAR
- TCHAR *t_path = tstring_from_utf8(path);
- if (t_path == NULL)
- {
- filerr = FILERR_OUT_OF_MEMORY;
- goto error;
- }
-
- // allocate a file object, plus space for the converted filename
- *file = (osd_file *)osd_malloc_array(sizeof(**file) + sizeof(TCHAR) * _tcslen(t_path));
- if (*file == NULL)
- {
- filerr = FILERR_OUT_OF_MEMORY;
- goto error;
- }
- memset(*file, 0x00, sizeof(**file) + sizeof(TCHAR) * _tcslen(t_path));
-
- if (win_check_socket_path(path))
- {
- (*file)->type = WINFILE_SOCKET;
- filerr = win_open_socket(path, openflags, file, filesize);
- goto error;
- }
-
- if (strncmp(path, winfile_ptty_identifier, strlen(winfile_ptty_identifier)) == 0)
- {
- (*file)->type = WINFILE_PTTY;
- filerr = win_open_ptty(path, openflags, file, filesize);
- goto error;
- }
-
- (*file)->type = WINFILE_FILE;
-
- // convert the path into something Windows compatible
- {
- TCHAR *dst = (*file)->filename;
- for (TCHAR const *src = t_path; *src != 0; src++)
- *dst++ = *src;//(*src == '/') ? '\\' : *src;
- *dst++ = 0;
- }
-
- // select the file open modes
- DWORD disposition, access, sharemode;
- if (openflags & OPEN_FLAG_WRITE)
- {
- disposition = (!is_path_to_physical_drive(path) && (openflags & OPEN_FLAG_CREATE)) ? CREATE_ALWAYS : OPEN_EXISTING;
- access = (openflags & OPEN_FLAG_READ) ? (GENERIC_READ | GENERIC_WRITE) : GENERIC_WRITE;
- sharemode = FILE_SHARE_READ;
- }
- else if (openflags & OPEN_FLAG_READ)
- {
- disposition = OPEN_EXISTING;
- access = GENERIC_READ;
- sharemode = FILE_SHARE_READ;
- }
- else
- {
- filerr = FILERR_INVALID_ACCESS;
- goto error;
- }
-
- // attempt to open the file
- (*file)->handle = CreateFile((*file)->filename, access, sharemode, NULL, disposition, 0, NULL);
- if ((*file)->handle == INVALID_HANDLE_VALUE)
- {
- DWORD error = GetLastError();
- // create the path if necessary
- if (error == ERROR_PATH_NOT_FOUND && (openflags & OPEN_FLAG_CREATE) && (openflags & OPEN_FLAG_CREATE_PATHS))
- {
- TCHAR *pathsep = _tcsrchr((*file)->filename, '\\');
- if (pathsep != NULL)
- {
- // create the path up to the file
- *pathsep = 0;
- error = create_path_recursive((*file)->filename);
- *pathsep = '\\';
-
- // attempt to reopen the file
- if (error == NO_ERROR)
- (*file)->handle = CreateFile((*file)->filename, access, sharemode, NULL, disposition, 0, NULL);
- }
- }
-
- // if we still failed, clean up and free
- if ((*file)->handle == INVALID_HANDLE_VALUE)
- {
- filerr = win_error_to_file_error(error);
- goto error;
- }
- }
-
- // get the file size
- DWORD upper;
- *filesize = GetFileSize((*file)->handle, &upper);
- *filesize |= (UINT64)upper << 32;
-
-error:
- // cleanup
- if (filerr != FILERR_NONE && *file != NULL)
- {
- osd_free(*file);
- *file = NULL;
- }
- osd_free(t_path);
- osd_free(path);
- return filerr;
-}
-
-
-//============================================================
-// osd_read
-//============================================================
-
-file_error osd_read(osd_file *file, void *buffer, UINT64 offset, UINT32 length, UINT32 *actual)
-{
- LONG upper = offset >> 32;
- DWORD result;
-
- switch (file->type)
- {
- case WINFILE_FILE:
- // attempt to set the file pointer
- result = SetFilePointer(file->handle, (UINT32)offset, &upper, FILE_BEGIN);
- if (result == INVALID_SET_FILE_POINTER)
- {
- DWORD error = GetLastError();
- if (error != NO_ERROR)
- return win_error_to_mame_file_error(error);
- }
-
- // then perform the read
- if (!ReadFile(file->handle, buffer, length, &result, NULL))
- return win_error_to_mame_file_error(GetLastError());
- if (actual != NULL)
- *actual = result;
- break;
- case WINFILE_SOCKET:
- return win_read_socket(file, buffer, offset, length, actual);
- case WINFILE_PTTY:
- return win_read_ptty(file, buffer, offset, length, actual);
-
- }
- return FILERR_NONE;
-}
-
-
-//============================================================
-// osd_write
-//============================================================
-
-file_error osd_write(osd_file *file, const void *buffer, UINT64 offset, UINT32 length, UINT32 *actual)
-{
- LONG upper = offset >> 32;
- DWORD result;
-
- switch (file->type)
- {
- case WINFILE_FILE:
- // attempt to set the file pointer
- result = SetFilePointer(file->handle, (UINT32)offset, &upper, FILE_BEGIN);
- if (result == INVALID_SET_FILE_POINTER)
- {
- DWORD error = GetLastError();
- if (error != NO_ERROR)
- return win_error_to_mame_file_error(error);
- }
-
- // then perform the read
- if (!WriteFile(file->handle, buffer, length, &result, NULL))
- return win_error_to_mame_file_error(GetLastError());
- if (actual != NULL)
- *actual = result;
- break;
- case WINFILE_SOCKET:
- return win_write_socket(file, buffer, offset, length, actual);
- case WINFILE_PTTY:
- return win_write_ptty(file, buffer, offset, length, actual);
-
- }
- return FILERR_NONE;
-}
-
-//============================================================
-// osd_openpty
-//============================================================
-
-file_error osd_openpty(osd_file **file, char *name, size_t name_len)
-{
- return FILERR_FAILURE;
-}
-
-//============================================================
-// osd_truncate
-//============================================================
-
-file_error osd_truncate(osd_file *file, UINT64 offset)
-{
- if (!file || !file->handle)
- return FILERR_FAILURE;
-
- DWORD result;
- LONG upper = offset >> 32;
-
- switch (file->type)
- {
- case WINFILE_FILE:
- // attempt to set the file pointer
- result = SetFilePointer(file->handle, (UINT32)offset, &upper, FILE_BEGIN);
- if (result == INVALID_SET_FILE_POINTER)
- {
- DWORD error = GetLastError();
- if (error != NO_ERROR)
- return win_error_to_mame_file_error(error);
- }
-
- // then perform the truncation
- if (!SetEndOfFile(file->handle))
- return win_error_to_mame_file_error(GetLastError());
- break;
- case WINFILE_SOCKET:
- return FILERR_FAILURE;
- case WINFILE_PTTY:
- return FILERR_FAILURE;
-
- }
- return FILERR_NONE;
-}
-
-//============================================================
-// osd_fflush
-//============================================================
-
-file_error osd_fflush(osd_file *file)
-{
- if (!file || !file->handle)
- return FILERR_FAILURE;
-
- return FILERR_NONE;
-}
-
-
-//============================================================
-// osd_close
-//============================================================
-
-file_error osd_close(osd_file *file)
-{
- file_error result = FILERR_NONE;
-
- switch (file->type)
- {
- case WINFILE_FILE:
- CloseHandle(file->handle);
- break;
- case WINFILE_SOCKET:
- result = win_close_socket(file);
- break;
- case WINFILE_PTTY:
- result = win_close_ptty(file);
- break;
- }
-
- osd_free(file);
- return result;
-}
-
-
-//============================================================
-// osd_rmfile
-//============================================================
-
-file_error osd_rmfile(const char *filename)
-{
- file_error filerr = FILERR_NONE;
-
- TCHAR *tempstr = tstring_from_utf8(filename);
- if (!tempstr)
- {
- filerr = FILERR_OUT_OF_MEMORY;
- goto done;
- }
-
- if (!DeleteFile(tempstr))
- {
- filerr = win_error_to_file_error(GetLastError());
- goto done;
- }
-
-done:
- if (tempstr)
- osd_free(tempstr);
- return filerr;
-}
-
-
-//============================================================
-// osd_get_physical_drive_geometry
-//============================================================
-
-int osd_get_physical_drive_geometry(const char *filename, UINT32 *cylinders, UINT32 *heads, UINT32 *sectors, UINT32 *bps)
-{
- DISK_GEOMETRY dg;
- DWORD bytesRead;
- TCHAR *t_filename;
- HANDLE file;
- int result;
-
- // if it doesn't smell like a physical drive, just return FALSE
- if (!is_path_to_physical_drive(filename))
- return FALSE;
-
- // do a create file on the drive
- t_filename = tstring_from_utf8(filename);
- if (t_filename == NULL)
- return FALSE;
- file = CreateFile(t_filename, GENERIC_READ, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, NULL);
- osd_free(t_filename);
- if (file == INVALID_HANDLE_VALUE)
- return FALSE;
-
- // device I/O control should return the geometry
- result = DeviceIoControl(file, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &dg, sizeof(dg), &bytesRead, NULL);
- CloseHandle(file);
-
- // if that failed, return false
- if (!result)
- return FALSE;
-
- // store the results
- *cylinders = (UINT32)dg.Cylinders.QuadPart;
- *heads = dg.TracksPerCylinder;
- *sectors = dg.SectorsPerTrack;
- *bps = dg.BytesPerSector;
-
- // normalize
- while (*heads > 16 && !(*heads & 1))
- {
- *heads /= 2;
- *cylinders *= 2;
- }
- return TRUE;
-}
-
-
-//============================================================
-// create_path_recursive
-//============================================================
-
-DWORD create_path_recursive(const TCHAR *path)
-{
- TCHAR *sep = (TCHAR *)_tcsrchr(path, '\\');
-
- // if there's still a separator, and it's not the root, nuke it and recurse
- if (sep != NULL && sep > path && sep[0] != ':' && sep[-1] != '\\')
- {
- *sep = 0;
- create_path_recursive(path);
- *sep = '\\';
- }
-
- // if the path already exists, we're done
- if (GetFileAttributes(path) != INVALID_FILE_ATTRIBUTES)
- return NO_ERROR;
-
- // create the path
- if (CreateDirectory(path, NULL) == 0)
- return GetLastError();
- return NO_ERROR;
-}
-
-//============================================================
-// win_error_to_mame_file_error
-//============================================================
-
-file_error win_error_to_mame_file_error(DWORD error)
-{
- file_error filerr;
-
- // convert a Windows error to a file_error
- switch (error)
- {
- case ERROR_SUCCESS:
- filerr = FILERR_NONE;
- break;
-
- case ERROR_OUTOFMEMORY:
- filerr = FILERR_OUT_OF_MEMORY;
- break;
-
- case ERROR_FILE_NOT_FOUND:
- case ERROR_PATH_NOT_FOUND:
- filerr = FILERR_NOT_FOUND;
- break;
-
- case ERROR_ACCESS_DENIED:
- filerr = FILERR_ACCESS_DENIED;
- break;
-
- case ERROR_SHARING_VIOLATION:
- filerr = FILERR_ALREADY_OPEN;
- break;
-
- default:
- filerr = FILERR_FAILURE;
- break;
- }
- return filerr;
-}
-
-//============================================================
-// osd_stat
-//============================================================
-
-osd_directory_entry *osd_stat(const char *path)
-{
- osd_directory_entry *result = NULL;
- TCHAR *t_path;
- HANDLE find = INVALID_HANDLE_VALUE;
- WIN32_FIND_DATA find_data;
-
- // convert the path to TCHARs
- t_path = tstring_from_utf8(path);
- if (t_path == NULL)
- goto done;
-
- // is this path a root directory (e.g. - C:)?
- if (isalpha(path[0]) && (path[1] == ':') && (path[2] == '\0'))
- {
- // need to do special logic for root directories
- memset(&find_data, 0, sizeof(find_data));
- find_data.dwFileAttributes = GetFileAttributes(t_path);
- }
- else
- {
- // attempt to find the first file
- find = FindFirstFile(t_path, &find_data);
- if (find == INVALID_HANDLE_VALUE)
- goto done;
- }
-
- // create an osd_directory_entry; be sure to make sure that the caller can
- // free all resources by just freeing the resulting osd_directory_entry
- result = (osd_directory_entry *)osd_malloc_array(sizeof(*result) + strlen(path) + 1);
- if (!result)
- goto done;
- strcpy(((char *) result) + sizeof(*result), path);
- result->name = ((char *) result) + sizeof(*result);
- result->type = win_attributes_to_entry_type(find_data.dwFileAttributes);
- result->size = find_data.nFileSizeLow | ((UINT64) find_data.nFileSizeHigh << 32);
-
-done:
- if (t_path != NULL)
- osd_free(t_path);
- return result;
-}
-
-//============================================================
-// osd_get_full_path
-//============================================================
-
-file_error osd_get_full_path(char **dst, const char *path)
-{
- file_error err;
- TCHAR *t_path;
- TCHAR buffer[MAX_PATH];
-
- // convert the path to TCHARs
- t_path = tstring_from_utf8(path);
- if (t_path == NULL)
- {
- err = FILERR_OUT_OF_MEMORY;
- goto done;
- }
-
- // cannonicalize the path
- if (!GetFullPathName(t_path, ARRAY_LENGTH(buffer), buffer, NULL))
- {
- err = win_error_to_mame_file_error(GetLastError());
- goto done;
- }
-
- // convert the result back to UTF-8
- *dst = utf8_from_tstring(buffer);
- if (!*dst)
- {
- err = FILERR_OUT_OF_MEMORY;
- goto done;
- }
-
- err = FILERR_NONE;
-
-done:
- if (t_path != NULL)
- osd_free(t_path);
- return err;
-}
-
-//============================================================
-// osd_get_volume_name
-//============================================================
-
-const char *osd_get_volume_name(int idx)
-{
- static char szBuffer[128];
- const char *p;
-
- GetLogicalDriveStringsA(ARRAY_LENGTH(szBuffer), szBuffer);
-
- p = szBuffer;
- while(idx--) {
- p += strlen(p) + 1;
- if (!*p) return NULL;
- }
-
- return p;
-}
diff --git a/src/osd/windows/winfile.h b/src/osd/windows/winfile.h
deleted file mode 100644
index 51e9acb5e0a..00000000000
--- a/src/osd/windows/winfile.h
+++ /dev/null
@@ -1,56 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Aaron Giles
-//============================================================
-//
-// winfile.h - File access functions
-//
-//============================================================
-#ifndef __WINFILE__
-#define __WINFILE__
-
-#include <winsock2.h>
-#include "osdcore.h"
-
-//============================================================
-// ENUM DEFINITIONS
-//============================================================
-enum
-{
- WINFILE_FILE = 0,
- WINFILE_SOCKET,
- WINFILE_PTTY
-};
-
-//============================================================
-// TYPE DEFINITIONS
-//============================================================
-
-struct osd_file
-{
- HANDLE handle;
- SOCKET socket;
- int type;
- TCHAR filename[1];
-};
-
-//============================================================
-// PROTOTYPES
-//============================================================
-
-bool win_init_sockets();
-void win_cleanup_sockets();
-
-bool win_check_socket_path(const char *path);
-file_error win_open_socket(const char *path, UINT32 openflags, osd_file **file, UINT64 *filesize);
-file_error win_read_socket(osd_file *file, void *buffer, UINT64 offset, UINT32 count, UINT32 *actual);
-file_error win_write_socket(osd_file *file, const void *buffer, UINT64 offset, UINT32 count, UINT32 *actual);
-file_error win_close_socket(osd_file *file);
-
-file_error win_open_ptty(const char *path, UINT32 openflags, osd_file **file, UINT64 *filesize);
-file_error win_read_ptty(osd_file *file, void *buffer, UINT64 offset, UINT32 count, UINT32 *actual);
-file_error win_write_ptty(osd_file *file, const void *buffer, UINT64 offset, UINT32 count, UINT32 *actual);
-file_error win_close_ptty(osd_file *file);
-
-file_error win_error_to_mame_file_error(DWORD error);
-
-#endif //__WINFILE__
diff --git a/src/osd/windows/winmain.cpp b/src/osd/windows/winmain.cpp
index 97650ba076d..e81037c48b1 100644
--- a/src/osd/windows/winmain.cpp
+++ b/src/osd/windows/winmain.cpp
@@ -283,8 +283,6 @@ const options_entry windows_options::s_option_entries[] =
{ nullptr, nullptr, OPTION_HEADER, "DIRECT3D POST-PROCESSING OPTIONS" },
{ WINOPTION_HLSL_ENABLE";hlsl", "0", OPTION_BOOLEAN, "enables HLSL post-processing (PS3.0 required)" },
{ WINOPTION_HLSLPATH, "hlsl", OPTION_STRING, "path to hlsl files" },
- { WINOPTION_HLSL_PRESCALE_X, "0", OPTION_INTEGER, "HLSL pre-scale override factor for X (0 for auto)" },
- { WINOPTION_HLSL_PRESCALE_Y, "0", OPTION_INTEGER, "HLSL pre-scale override factor for Y (0 for auto)" },
{ WINOPTION_HLSL_WRITE, nullptr, OPTION_STRING, "enables HLSL AVI writing (huge disk bandwidth suggested)" },
{ WINOPTION_HLSL_SNAP_WIDTH, "2048", OPTION_STRING, "HLSL upscaled-snapshot width" },
{ WINOPTION_HLSL_SNAP_HEIGHT, "1536", OPTION_STRING, "HLSL upscaled-snapshot height" },
@@ -306,25 +304,26 @@ const options_entry windows_options::s_option_entries[] =
{ WINOPTION_SCANLINE_AMOUNT";fs_scanam(0.0-4.0)", "0.0", OPTION_FLOAT, "overall alpha scaling value for scanlines" },
{ WINOPTION_SCANLINE_SCALE";fs_scansc(0.0-4.0)", "1.0", OPTION_FLOAT, "overall height scaling value for scanlines" },
{ WINOPTION_SCANLINE_HEIGHT";fs_scanh(0.0-4.0)", "1.0", OPTION_FLOAT, "individual height scaling value for scanlines" },
+ { WINOPTION_SCANLINE_VARIATION";fs_scanv(0.0-4.0)", "1.0", OPTION_FLOAT, "individual height varying value for scanlines" },
{ WINOPTION_SCANLINE_BRIGHT_SCALE";fs_scanbs(0.0-2.0)", "1.0", OPTION_FLOAT, "overall brightness scaling value for scanlines (multiplicative)" },
{ WINOPTION_SCANLINE_BRIGHT_OFFSET";fs_scanbo(0.0-1.0)", "0.0", OPTION_FLOAT, "overall brightness offset value for scanlines (additive)" },
{ WINOPTION_SCANLINE_JITTER";fs_scanjt(0.0-4.0)", "0.0", OPTION_FLOAT, "overall interlace jitter scaling value for scanlines" },
{ WINOPTION_HUM_BAR_ALPHA";fs_humba(0.0-1.0)", "0.0", OPTION_FLOAT, "overall alpha scaling value for hum bar" },
- { WINOPTION_DEFOCUS";fs_focus", "1.0,0.0", OPTION_STRING, "overall defocus value in screen-relative coords" },
- { WINOPTION_CONVERGE_X";fs_convx", "0.25,0.00,-0.25", OPTION_STRING, "convergence in screen-relative X direction" },
- { WINOPTION_CONVERGE_Y";fs_convy", "0.0,0.25,-0.25", OPTION_STRING, "convergence in screen-relative Y direction" },
+ { WINOPTION_DEFOCUS";fs_focus", "0.0,0.0", OPTION_STRING, "overall defocus value in screen-relative coords" },
+ { WINOPTION_CONVERGE_X";fs_convx", "0.0,0.0,0.0", OPTION_STRING, "convergence in screen-relative X direction" },
+ { WINOPTION_CONVERGE_Y";fs_convy", "0.0,0.0,0.0", OPTION_STRING, "convergence in screen-relative Y direction" },
{ WINOPTION_RADIAL_CONVERGE_X";fs_rconvx", "0.0,0.0,0.0", OPTION_STRING, "radial convergence in screen-relative X direction" },
{ WINOPTION_RADIAL_CONVERGE_Y";fs_rconvy", "0.0,0.0,0.0", OPTION_STRING, "radial convergence in screen-relative Y direction" },
/* RGB colorspace convolution below this line */
{ WINOPTION_RED_RATIO";fs_redratio", "1.0,0.0,0.0", OPTION_STRING, "red output signal generated by input signal" },
{ WINOPTION_GRN_RATIO";fs_grnratio", "0.0,1.0,0.0", OPTION_STRING, "green output signal generated by input signal" },
{ WINOPTION_BLU_RATIO";fs_bluratio", "0.0,0.0,1.0", OPTION_STRING, "blue output signal generated by input signal" },
- { WINOPTION_SATURATION";fs_sat(0.0-4.0)", "1.4", OPTION_FLOAT, "saturation scaling value" },
+ { WINOPTION_SATURATION";fs_sat(0.0-4.0)", "1.0", OPTION_FLOAT, "saturation scaling value" },
{ WINOPTION_OFFSET";fs_offset", "0.0,0.0,0.0", OPTION_STRING, "signal offset value (additive)" },
- { WINOPTION_SCALE";fs_scale", "0.95,0.95,0.95", OPTION_STRING, "signal scaling value (multiplicative)" },
- { WINOPTION_POWER";fs_power", "0.8,0.8,0.8", OPTION_STRING, "signal power value (exponential)" },
- { WINOPTION_FLOOR";fs_floor", "0.05,0.05,0.05", OPTION_STRING, "signal floor level" },
- { WINOPTION_PHOSPHOR";fs_phosphor", "0.4,0.4,0.4", OPTION_STRING, "phosphorescence decay rate (0.0 is instant, 1.0 is forever)" },
+ { WINOPTION_SCALE";fs_scale", "1.0,1.0,1.0", OPTION_STRING, "signal scaling value (multiplicative)" },
+ { WINOPTION_POWER";fs_power", "1.0,1.0,1.0", OPTION_STRING, "signal power value (exponential)" },
+ { WINOPTION_FLOOR";fs_floor", "0.0,0.0,0.0", OPTION_STRING, "signal floor level" },
+ { WINOPTION_PHOSPHOR";fs_phosphor", "0.0,0.0,0.0", OPTION_STRING, "phosphorescence decay rate (0.0 is instant, 1.0 is forever)" },
/* NTSC simulation below this line */
{ nullptr, nullptr, OPTION_HEADER, "NTSC POST-PROCESSING OPTIONS" },
{ WINOPTION_YIQ_ENABLE";yiq", "0", OPTION_BOOLEAN, "enables YIQ-space HLSL post-processing" },
@@ -346,20 +345,20 @@ const options_entry windows_options::s_option_entries[] =
{ WINOPTION_VECTOR_LENGTH_RATIO";vecsize", "500.0", OPTION_FLOAT, "Vector fade length (4.0 - vectors fade the most at and above 4 pixels, etc.)" },
/* Bloom below this line */
{ nullptr, nullptr, OPTION_HEADER, "BLOOM POST-PROCESSING OPTIONS" },
- { WINOPTION_BLOOM_BLEND_MODE, "0", OPTION_INTEGER, "bloom blend mode (0 for addition, 1 for darken)" },
- { WINOPTION_BLOOM_SCALE, "0.25", OPTION_FLOAT, "Intensity factor for bloom" },
+ { WINOPTION_BLOOM_BLEND_MODE, "0", OPTION_INTEGER, "bloom blend mode (0 for brighten, 1 for darken)" },
+ { WINOPTION_BLOOM_SCALE, "0.0", OPTION_FLOAT, "Intensity factor for bloom" },
{ WINOPTION_BLOOM_OVERDRIVE, "1.0,1.0,1.0", OPTION_STRING, "Overdrive factor for bloom" },
{ WINOPTION_BLOOM_LEVEL0_WEIGHT, "1.0", OPTION_FLOAT, "Bloom level 0 (full-size target) weight" },
- { WINOPTION_BLOOM_LEVEL1_WEIGHT, "0.64", OPTION_FLOAT, "Bloom level 1 (half-size target) weight" },
- { WINOPTION_BLOOM_LEVEL2_WEIGHT, "0.32", OPTION_FLOAT, "Bloom level 2 (quarter-size target) weight" },
- { WINOPTION_BLOOM_LEVEL3_WEIGHT, "0.16", OPTION_FLOAT, "Bloom level 3 (.) weight" },
- { WINOPTION_BLOOM_LEVEL4_WEIGHT, "0.08", OPTION_FLOAT, "Bloom level 4 (.) weight" },
- { WINOPTION_BLOOM_LEVEL5_WEIGHT, "0.04", OPTION_FLOAT, "Bloom level 5 (.) weight" },
- { WINOPTION_BLOOM_LEVEL6_WEIGHT, "0.04", OPTION_FLOAT, "Bloom level 6 (.) weight" },
- { WINOPTION_BLOOM_LEVEL7_WEIGHT, "0.02", OPTION_FLOAT, "Bloom level 7 (.) weight" },
- { WINOPTION_BLOOM_LEVEL8_WEIGHT, "0.02", OPTION_FLOAT, "Bloom level 8 (.) weight" },
- { WINOPTION_BLOOM_LEVEL9_WEIGHT, "0.01", OPTION_FLOAT, "Bloom level 9 (.) weight" },
- { WINOPTION_BLOOM_LEVEL10_WEIGHT, "0.01", OPTION_FLOAT, "Bloom level 10 (1x1 target) weight" },
+ { WINOPTION_BLOOM_LEVEL1_WEIGHT, "0.64", OPTION_FLOAT, "Bloom level 1 (1/2-size target) weight" },
+ { WINOPTION_BLOOM_LEVEL2_WEIGHT, "0.32", OPTION_FLOAT, "Bloom level 2 (1/4-size target) weight" },
+ { WINOPTION_BLOOM_LEVEL3_WEIGHT, "0.16", OPTION_FLOAT, "Bloom level 3 (1/8-size target) weight" },
+ { WINOPTION_BLOOM_LEVEL4_WEIGHT, "0.08", OPTION_FLOAT, "Bloom level 4 (1/16-size target) weight" },
+ { WINOPTION_BLOOM_LEVEL5_WEIGHT, "0.04", OPTION_FLOAT, "Bloom level 5 (1/32-size target) weight" },
+ { WINOPTION_BLOOM_LEVEL6_WEIGHT, "0.04", OPTION_FLOAT, "Bloom level 6 (1/64-size target) weight" },
+ { WINOPTION_BLOOM_LEVEL7_WEIGHT, "0.02", OPTION_FLOAT, "Bloom level 7 (1/128-size target) weight" },
+ { WINOPTION_BLOOM_LEVEL8_WEIGHT, "0.02", OPTION_FLOAT, "Bloom level 8 (1/256-size target) weight" },
+ { WINOPTION_BLOOM_LEVEL9_WEIGHT, "0.01", OPTION_FLOAT, "Bloom level 9 (1/512-size target) weight" },
+ { WINOPTION_BLOOM_LEVEL10_WEIGHT, "0.01", OPTION_FLOAT, "Bloom level 10 (1/1024-size target) weight" },
// full screen options
{ nullptr, nullptr, OPTION_HEADER, "FULL SCREEN OPTIONS" },
diff --git a/src/osd/windows/winmain.h b/src/osd/windows/winmain.h
index c0bd9f7e56a..9b5bac624fd 100644
--- a/src/osd/windows/winmain.h
+++ b/src/osd/windows/winmain.h
@@ -31,8 +31,6 @@
// core post-processing options
#define WINOPTION_HLSL_ENABLE "hlsl_enable"
#define WINOPTION_HLSLPATH "hlslpath"
-#define WINOPTION_HLSL_PRESCALE_X "hlsl_prescale_x"
-#define WINOPTION_HLSL_PRESCALE_Y "hlsl_prescale_y"
#define WINOPTION_HLSL_WRITE "hlsl_write"
#define WINOPTION_HLSL_SNAP_WIDTH "hlsl_snap_width"
#define WINOPTION_HLSL_SNAP_HEIGHT "hlsl_snap_height"
@@ -53,6 +51,7 @@
#define WINOPTION_SCANLINE_AMOUNT "scanline_alpha"
#define WINOPTION_SCANLINE_SCALE "scanline_size"
#define WINOPTION_SCANLINE_HEIGHT "scanline_height"
+#define WINOPTION_SCANLINE_VARIATION "scanline_variation"
#define WINOPTION_SCANLINE_BRIGHT_SCALE "scanline_bright_scale"
#define WINOPTION_SCANLINE_BRIGHT_OFFSET "scanline_bright_offset"
#define WINOPTION_SCANLINE_JITTER "scanline_jitter"
@@ -136,8 +135,6 @@ public:
const char *screen_post_fx_dir() const { return value(WINOPTION_HLSLPATH); }
bool d3d_hlsl_enable() const { return bool_value(WINOPTION_HLSL_ENABLE); }
const char *d3d_hlsl_write() const { return value(WINOPTION_HLSL_WRITE); }
- int d3d_hlsl_prescale_x() const { return int_value(WINOPTION_HLSL_PRESCALE_X); }
- int d3d_hlsl_prescale_y() const { return int_value(WINOPTION_HLSL_PRESCALE_Y); }
int d3d_snap_width() const { return int_value(WINOPTION_HLSL_SNAP_WIDTH); }
int d3d_snap_height() const { return int_value(WINOPTION_HLSL_SNAP_HEIGHT); }
int screen_shadow_mask_tile_mode() const { return int_value(WINOPTION_SHADOW_MASK_TILE_MODE); }
@@ -152,6 +149,7 @@ public:
float screen_scanline_amount() const { return float_value(WINOPTION_SCANLINE_AMOUNT); }
float screen_scanline_scale() const { return float_value(WINOPTION_SCANLINE_SCALE); }
float screen_scanline_height() const { return float_value(WINOPTION_SCANLINE_HEIGHT); }
+ float screen_scanline_variation() const { return float_value(WINOPTION_SCANLINE_VARIATION); }
float screen_scanline_bright_scale() const { return float_value(WINOPTION_SCANLINE_BRIGHT_SCALE); }
float screen_scanline_bright_offset() const { return float_value(WINOPTION_SCANLINE_BRIGHT_OFFSET); }
float screen_scanline_jitter() const { return float_value(WINOPTION_SCANLINE_JITTER); }
@@ -290,9 +288,9 @@ public:
void extract_video_config();
// windows osd specific
- bool handle_input_event(input_event eventid, void *eventdata);
- bool should_hide_mouse();
- void poll_input(running_machine &machine);
+ bool handle_input_event(input_event eventid, void *eventdata) const;
+ bool should_hide_mouse() const;
+ void poll_input(running_machine &machine) const;
windows_options &options() { return m_options; }
diff --git a/src/osd/windows/winptty.cpp b/src/osd/windows/winptty.cpp
deleted file mode 100644
index d04592d1749..00000000000
--- a/src/osd/windows/winptty.cpp
+++ /dev/null
@@ -1,70 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Aaron Giles
-#define WIN32_LEAN_AND_MEAN
-
-#include <windows.h>
-#include <stdlib.h>
-
-#include "winfile.h"
-#include "strconv.h"
-#include "winutil.h"
-
-const char *winfile_ptty_identifier = "\\\\.\\pipe\\";
-
-file_error win_open_ptty(const char *path, UINT32 openflags, osd_file **file, UINT64 *filesize)
-{
- TCHAR *t_name;
- HANDLE pipe;
-
- if((t_name = tstring_from_utf8(path)) == NULL)
- return FILERR_OUT_OF_MEMORY;
-
- pipe = CreateNamedPipe(t_name, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_NOWAIT, 1, 32, 32, 0, NULL);
-
- osd_free(t_name);
-
- if(pipe == INVALID_HANDLE_VALUE)
- return FILERR_ACCESS_DENIED;
-
- (*file)->handle = pipe;
- *filesize = 0;
- return FILERR_NONE;
-}
-
-file_error win_read_ptty(osd_file *file, void *buffer, UINT64 offset, UINT32 count, UINT32 *actual)
-{
- BOOL res;
- DWORD bytes_read;
-
- res = ReadFile(file->handle, buffer, count, &bytes_read, NULL);
- if(res == FALSE)
- return win_error_to_file_error(GetLastError());
-
- if(actual != NULL)
- *actual = bytes_read;
-
- return FILERR_NONE;
-}
-
-file_error win_write_ptty(osd_file *file, const void *buffer, UINT64 offset, UINT32 count, UINT32 *actual)
-{
- BOOL res;
- DWORD bytes_wrote;
-
- res = WriteFile(file->handle, buffer, count, &bytes_wrote, NULL);
- if(res == FALSE)
- return win_error_to_file_error(GetLastError());
-
- if(actual != NULL)
- *actual = bytes_wrote;
-
- return FILERR_NONE;
-}
-
-file_error win_close_ptty(osd_file *file)
-{
- FlushFileBuffers(file->handle);
- DisconnectNamedPipe(file->handle);
- CloseHandle(file->handle);
- return FILERR_NONE;
-}
diff --git a/src/osd/windows/winsocket.cpp b/src/osd/windows/winsocket.cpp
deleted file mode 100644
index cfa22dbbcb1..00000000000
--- a/src/osd/windows/winsocket.cpp
+++ /dev/null
@@ -1,204 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Aaron Giles
-//============================================================
-//
-// winsocket.c - Windows socket (inet) access functions
-//
-//============================================================
-// standard windows headers
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#include <winioctl.h>
-#include <tchar.h>
-#include <stdlib.h>
-#include <ctype.h>
-
-// MAME headers
-#include "osdcore.h"
-
-#include "winfile.h"
-
-const char *winfile_socket_identifier = "socket.";
-
-bool win_init_sockets()
-{
- WSADATA wsaData;
- WORD version;
- int error;
-
- version = MAKEWORD( 2, 0 );
-
- error = WSAStartup( version, &wsaData );
-
- /* check for error */
- if ( error != 0 )
- {
- /* error occurred */
- return FALSE;
- }
-
-
- /* check for correct version */
- if ( LOBYTE( wsaData.wVersion ) != 2 ||
- HIBYTE( wsaData.wVersion ) != 0 )
- {
- /* incorrect WinSock version */
- WSACleanup();
- return FALSE;
- }
- /* WinSock has been initialized */
- return TRUE;
-}
-
-void win_cleanup_sockets()
-{
- WSACleanup();
-}
-
-bool win_check_socket_path(const char *path)
-{
- if (strlen(winfile_socket_identifier) > 0 &&
- strncmp(path, winfile_socket_identifier, strlen(winfile_socket_identifier)) == 0 &&
- strchr(path, ':') != nullptr) return true;
- return false;
-}
-
-file_error win_open_socket(const char *path, UINT32 openflags, osd_file **file, UINT64 *filesize)
-{
- char hostname[256];
- struct hostent *localhost;
- struct sockaddr_in sai;
- int flag = 1;
- int port;
-
- sscanf( path+strlen(winfile_socket_identifier), "%255[^:]:%d", hostname, &port );
-
- if (((*file)->socket = socket(AF_INET, SOCK_STREAM, 0)) == -1)
- {
- return FILERR_ACCESS_DENIED;
- }
-
- if (setsockopt((*file)->socket, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(flag)) == -1)
- {
- return FILERR_ACCESS_DENIED;
- }
- localhost = gethostbyname(hostname);
-
- memset(&sai, 0, sizeof(sai));
- sai.sin_family = AF_INET;
- sai.sin_port = htons(port);
- sai.sin_addr = *((struct in_addr *)localhost->h_addr);
-
- // listening socket support
- if (openflags & OPEN_FLAG_CREATE)
- {
-// printf("Listening for client at '%s' on port '%d'\n", hostname, port);
- // bind socket...
- if (bind((*file)->socket, (struct sockaddr *)&sai, sizeof(struct sockaddr)) == -1)
- {
- return FILERR_ACCESS_DENIED;
- }
-
- // start to listen...
- if (listen((*file)->socket, 1) == -1) {
- return FILERR_ACCESS_DENIED;
- }
-
- // mark socket as "listening"
- (*file)->handle = nullptr;
- *filesize = 0;
- return FILERR_NONE;
- }
-
-// printf("Connecting to server '%s' on port '%d'\n", hostname, port);
- if (connect((*file)->socket, (struct sockaddr *)&sai, sizeof(struct sockaddr)) == -1)
- {
- return FILERR_ACCESS_DENIED;
- }
- *filesize = 0;
- (*file)->handle = INVALID_HANDLE_VALUE;
- return FILERR_NONE;
-}
-
-file_error win_read_socket(osd_file *file, void *buffer, UINT64 offset, UINT32 count, UINT32 *actual)
-{
- int result;
- char line[80];
- struct timeval timeout;
- fd_set readfds;
-
- FD_ZERO(&readfds);
- FD_SET(file->socket, &readfds);
- timeout.tv_sec = timeout.tv_usec = 0;
-
- if (select(file->socket + 1, &readfds, nullptr, nullptr, &timeout) < 0)
- {
- sprintf(line, "win_read_socket : %s : %d ", __FILE__, __LINE__);
- perror(line);
- return win_error_to_mame_file_error(GetLastError());
- }
- else if (FD_ISSET(file->socket, &readfds))
- {
- if (file->handle == INVALID_HANDLE_VALUE)
- {
- // connected socket
- result = recv(file->socket, (char*)buffer, count, 0);
- }
- else
- {
- // listening socket
- SOCKET AcceptSocket;
- AcceptSocket = accept(file->socket, nullptr, nullptr);
- if (AcceptSocket == INVALID_SOCKET)
- {
- return FILERR_FAILURE;
- }
- closesocket(file->socket);
- file->socket = AcceptSocket;
- file->handle = INVALID_HANDLE_VALUE;
- if (actual != nullptr )
- {
- *actual = 0;
- }
-
- return FILERR_NONE;
- }
- }
- else
- {
- return FILERR_FAILURE;
- }
-
- if (result < 0)
- {
- return win_error_to_mame_file_error(GetLastError());
- }
-
- if (actual != nullptr )
- {
- *actual = result;
- }
- return FILERR_NONE;
-}
-
-file_error win_write_socket(osd_file *file, const void *buffer, UINT64 offset, UINT32 count, UINT32 *actual)
-{
- int result;
- result = send(file->socket, (const char*)buffer, count, 0);
- if (result < 0)
- {
- return win_error_to_mame_file_error(GetLastError());
- }
-
- if (actual != nullptr )
- {
- *actual = result;
- }
- return FILERR_NONE;
-}
-
-file_error win_close_socket(osd_file *file)
-{
- closesocket(file->socket);
- return FILERR_NONE;
-}
diff --git a/src/osd/windows/winutil.cpp b/src/osd/windows/winutil.cpp
index eb63eecacd0..607699749bb 100644
--- a/src/osd/windows/winutil.cpp
+++ b/src/osd/windows/winutil.cpp
@@ -18,47 +18,6 @@
#include "winutil.h"
#include "strconv.h"
-//============================================================
-// win_error_to_file_error
-//============================================================
-
-file_error win_error_to_file_error(DWORD error)
-{
- file_error filerr;
-
- // convert a Windows error to a file_error
- switch (error)
- {
- case ERROR_SUCCESS:
- filerr = FILERR_NONE;
- break;
-
- case ERROR_OUTOFMEMORY:
- filerr = FILERR_OUT_OF_MEMORY;
- break;
-
- case ERROR_FILE_NOT_FOUND:
- case ERROR_FILENAME_EXCED_RANGE:
- case ERROR_PATH_NOT_FOUND:
- filerr = FILERR_NOT_FOUND;
- break;
-
- case ERROR_ACCESS_DENIED:
- filerr = FILERR_ACCESS_DENIED;
- break;
-
- case ERROR_SHARING_VIOLATION:
- filerr = FILERR_ALREADY_OPEN;
- break;
-
- default:
- filerr = FILERR_FAILURE;
- break;
- }
- return filerr;
-}
-
-
//============================================================
// win_attributes_to_entry_type
@@ -130,13 +89,16 @@ BOOL win_is_gui_application(void)
//============================================================
// osd_subst_env
//============================================================
-void osd_subst_env(char **dst, const char *src)
+void osd_subst_env(std::string &dst, const std::string &src)
{
TCHAR buffer[MAX_PATH];
- TCHAR *t_src = tstring_from_utf8(src);
+ TCHAR *t_src = tstring_from_utf8(src.c_str());
ExpandEnvironmentStrings(t_src, buffer, ARRAY_LENGTH(buffer));
- *dst = utf8_from_tstring(buffer);
+ osd_free(t_src);
+ char *cnv = utf8_from_tstring(buffer);
+ dst = cnv;
+ osd_free(cnv);
}
//-------------------------------------------------
diff --git a/src/osd/windows/winutil.h b/src/osd/windows/winutil.h
index 530327dcf61..6cb8297c277 100644
--- a/src/osd/windows/winutil.h
+++ b/src/osd/windows/winutil.h
@@ -14,7 +14,6 @@
#include <vector>
// Shared code
-file_error win_error_to_file_error(DWORD error);
osd_dir_entry_type win_attributes_to_entry_type(DWORD attributes);
BOOL win_is_gui_application(void);
HMODULE WINAPI GetModuleHandleUni();
@@ -26,10 +25,10 @@ HMODULE WINAPI GetModuleHandleUni();
class lazy_loaded_function
{
private:
- std::string m_name;
- std::vector<std::wstring> m_dll_names;
- HMODULE m_module;
- bool m_initialized;
+ std::string m_name;
+ std::vector<std::wstring> m_dll_names;
+ HMODULE m_module;
+ bool m_initialized;
protected:
void check_init();
diff --git a/src/tools/chdman.cpp b/src/tools/chdman.cpp
index 1a80bc76e13..95dd285a94d 100644
--- a/src/tools/chdman.cpp
+++ b/src/tools/chdman.cpp
@@ -34,8 +34,10 @@
// CONSTANTS & DEFINES
//**************************************************************************
/* MINGW has adopted the MSVC formatting for 64-bit ints as of gcc 4.4 */
-#if defined(__MINGW32__) || defined(_MSC_VER)
+#if defined(WIN32)
#define I64FMT "I64"
+#elif !defined(__APPLE__) && defined(__LP64__)
+#define I64FMT "l"
#else
#define I64FMT "ll"
#endif
@@ -331,8 +333,8 @@ public:
{
m_file.reset();
m_lastfile = m_info.track[tracknum].fname;
- file_error filerr = util::core_file::open(m_lastfile.c_str(), OPEN_FLAG_READ, m_file);
- if (filerr != FILERR_NONE)
+ osd_file::error filerr = util::core_file::open(m_lastfile, OPEN_FLAG_READ, m_file);
+ if (filerr != osd_file::error::NONE)
report_error(1, "Error opening input file (%s)'", m_lastfile.c_str());
}
@@ -438,15 +440,15 @@ public:
// read the sound samples
m_audio[chnum].resize(samples);
samplesptr[chnum] = &m_audio[chnum][0];
- avi_error avierr = avi_read_sound_samples(&m_file, chnum, first_sample, samples, &m_audio[chnum][0]);
- if (avierr != AVIERR_NONE)
- report_error(1, "Error reading audio samples %d-%d from channel %d: %s", first_sample, samples, chnum, avi_error_string(avierr));
+ avi_file::error avierr = m_file.read_sound_samples(chnum, first_sample, samples, &m_audio[chnum][0]);
+ if (avierr != avi_file::error::NONE)
+ report_error(1, "Error reading audio samples %d-%d from channel %d: %s", first_sample, samples, chnum, avi_file::error_string(avierr));
}
// read the video data
- avi_error avierr = avi_read_video_frame(&m_file, effframe / interlace_factor, m_bitmap);
- if (avierr != AVIERR_NONE)
- report_error(1, "Error reading AVI frame %d: %s", effframe / interlace_factor, avi_error_string(avierr));
+ avi_file::error avierr = m_file.read_video_frame(effframe / interlace_factor, m_bitmap);
+ if (avierr != avi_file::error::NONE)
+ report_error(1, "Error reading AVI frame %d: %s", effframe / interlace_factor, avi_file::error_string(avierr));
bitmap_yuy16 subbitmap(&m_bitmap.pix(effframe % interlace_factor), m_bitmap.width(), m_bitmap.height() / interlace_factor, m_bitmap.rowpixels() * interlace_factor);
// update metadata for this frame
@@ -1007,8 +1009,8 @@ static void check_existing_output_file(const parameters_t &params, const char *f
if (params.find(OPTION_OUTPUT_FORCE) == params.end())
{
util::core_file::ptr file;
- file_error filerr = util::core_file::open(filename, OPEN_FLAG_READ, file);
- if (filerr == FILERR_NONE)
+ osd_file::error filerr = util::core_file::open(filename, OPEN_FLAG_READ, file);
+ if (filerr == osd_file::error::NONE)
{
file.reset();
report_error(1, "Error: file already exists (%s)\nUse --force (or -f) to force overwriting", filename);
@@ -1572,8 +1574,8 @@ static void do_create_raw(parameters_t &params)
auto input_file_str = params.find(OPTION_INPUT);
if (input_file_str != params.end())
{
- file_error filerr = util::core_file::open(input_file_str->second->c_str(), OPEN_FLAG_READ, input_file);
- if (filerr != FILERR_NONE)
+ osd_file::error filerr = util::core_file::open(*input_file_str->second, OPEN_FLAG_READ, input_file);
+ if (filerr != osd_file::error::NONE)
report_error(1, "Unable to open file (%s)", input_file_str->second->c_str());
}
@@ -1651,7 +1653,7 @@ static void do_create_raw(parameters_t &params)
// delete the output file
auto output_chd_str = params.find(OPTION_OUTPUT);
if (output_chd_str != params.end())
- osd_rmfile(output_chd_str->second->c_str());
+ osd_file::remove(*output_chd_str->second);
throw;
}
}
@@ -1669,8 +1671,8 @@ static void do_create_hd(parameters_t &params)
auto input_file_str = params.find(OPTION_INPUT);
if (input_file_str != params.end())
{
- file_error filerr = util::core_file::open(input_file_str->second->c_str(), OPEN_FLAG_READ, input_file);
- if (filerr != FILERR_NONE)
+ osd_file::error filerr = util::core_file::open(*input_file_str->second, OPEN_FLAG_READ, input_file);
+ if (filerr != osd_file::error::NONE)
report_error(1, "Unable to open file (%s)", input_file_str->second->c_str());
}
@@ -1744,8 +1746,8 @@ static void do_create_hd(parameters_t &params)
if (ident_str != params.end())
{
// load the file
- file_error filerr = util::core_file::load(ident_str->second->c_str(), identdata);
- if (filerr != FILERR_NONE)
+ osd_file::error filerr = util::core_file::load(ident_str->second->c_str(), identdata);
+ if (filerr != osd_file::error::NONE)
report_error(1, "Error reading ident file (%s)", ident_str->second->c_str());
// must be at least 14 bytes; extract CHS data from there
@@ -1840,7 +1842,7 @@ static void do_create_hd(parameters_t &params)
// delete the output file
auto output_chd_str = params.find(OPTION_OUTPUT);
if (output_chd_str != params.end())
- osd_rmfile(output_chd_str->second->c_str());
+ osd_file::remove(*output_chd_str->second);
throw;
}
}
@@ -1932,7 +1934,7 @@ static void do_create_cd(parameters_t &params)
// delete the output file
auto output_chd_str = params.find(OPTION_OUTPUT);
if (output_chd_str != params.end())
- osd_rmfile(output_chd_str->second->c_str());
+ osd_file::remove(*output_chd_str->second);
throw;
}
}
@@ -1946,15 +1948,15 @@ static void do_create_cd(parameters_t &params)
static void do_create_ld(parameters_t &params)
{
// process input file
- avi_file *input_file = nullptr;
+ avi_file::ptr input_file;
auto input_file_str = params.find(OPTION_INPUT);
if (input_file_str != params.end())
{
- avi_error avierr = avi_open(input_file_str->second->c_str(), &input_file);
- if (avierr != AVIERR_NONE)
- report_error(1, "Error opening AVI file (%s): %s\n", input_file_str->second->c_str(), avi_error_string(avierr));
+ avi_file::error avierr = avi_file::open(*input_file_str->second, input_file);
+ if (avierr != avi_file::error::NONE)
+ report_error(1, "Error opening AVI file (%s): %s\n", input_file_str->second->c_str(), avi_file::error_string(avierr));
}
- const avi_movie_info *aviinfo = avi_get_movie_info(input_file);
+ const avi_file::movie_info &aviinfo = input_file->get_movie_info();
// process output CHD
chd_file output_parent;
@@ -1963,16 +1965,16 @@ static void do_create_ld(parameters_t &params)
// process input start/end
UINT64 input_start;
UINT64 input_end;
- parse_input_start_end(params, aviinfo->video_numsamples, 0, 1, input_start, input_end);
+ parse_input_start_end(params, aviinfo.video_numsamples, 0, 1, input_start, input_end);
// determine parameters of the incoming video stream
avi_info info;
- info.fps_times_1million = UINT64(aviinfo->video_timescale) * 1000000 / aviinfo->video_sampletime;
- info.width = aviinfo->video_width;
- info.height = aviinfo->video_height;
+ info.fps_times_1million = UINT64(aviinfo.video_timescale) * 1000000 / aviinfo.video_sampletime;
+ info.width = aviinfo.video_width;
+ info.height = aviinfo.video_height;
info.interlaced = ((info.fps_times_1million / 1000000) <= 30) && (info.height % 2 == 0) && (info.height > 288);
- info.channels = aviinfo->audio_channels;
- info.rate = aviinfo->audio_samplerate;
+ info.channels = aviinfo.audio_channels;
+ info.rate = aviinfo.audio_samplerate;
// adjust for interlacing
if (info.interlaced)
@@ -2008,7 +2010,7 @@ static void do_create_ld(parameters_t &params)
if (output_parent.opened())
printf("Parent CHD: %s\n", params.find(OPTION_OUTPUT_PARENT)->second->c_str());
printf("Input file: %s\n", input_file_str->second->c_str());
- if (input_start != 0 && input_end != aviinfo->video_numsamples)
+ if (input_start != 0 && input_end != aviinfo.video_numsamples)
printf("Input start: %s\n", big_int_string(tempstr, input_start));
printf("Input length: %s (%02d:%02d:%02d)\n", big_int_string(tempstr, input_end - input_start),
UINT32((UINT64(input_end - input_start) * 1000000 / info.fps_times_1million / 60 / 60)),
@@ -2059,7 +2061,7 @@ static void do_create_ld(parameters_t &params)
// delete the output file
auto output_chd_str = params.find(OPTION_OUTPUT);
if (output_chd_str != params.end())
- osd_rmfile(output_chd_str->second->c_str());
+ osd_file::remove(*output_chd_str->second);
throw;
}
}
@@ -2195,7 +2197,7 @@ static void do_copy(parameters_t &params)
// delete the output file
auto output_chd_str = params.find(OPTION_OUTPUT);
if (output_chd_str != params.end())
- osd_rmfile(output_chd_str->second->c_str());
+ osd_file::remove(*output_chd_str->second);
throw;
}
}
@@ -2238,8 +2240,8 @@ static void do_extract_raw(parameters_t &params)
try
{
// process output file
- file_error filerr = util::core_file::open(output_file_str->second->c_str(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, output_file);
- if (filerr != FILERR_NONE)
+ osd_file::error filerr = util::core_file::open(*output_file_str->second, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, output_file);
+ if (filerr != osd_file::error::NONE)
report_error(1, "Unable to open file (%s)", output_file_str->second->c_str());
// copy all data
@@ -2273,7 +2275,7 @@ static void do_extract_raw(parameters_t &params)
if (output_file != nullptr)
{
output_file.reset();
- osd_rmfile(output_file_str->second->c_str());
+ osd_file::remove(*output_file_str->second);
}
throw;
}
@@ -2343,15 +2345,15 @@ static void do_extract_cd(parameters_t &params)
}
// process output file
- file_error filerr = util::core_file::open(output_file_str->second->c_str(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_NO_BOM, output_toc_file);
- if (filerr != FILERR_NONE)
+ osd_file::error filerr = util::core_file::open(*output_file_str->second, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_NO_BOM, output_toc_file);
+ if (filerr != osd_file::error::NONE)
report_error(1, "Unable to open file (%s)", output_file_str->second->c_str());
// process output BIN file
if (mode != MODE_GDI)
{
- filerr = util::core_file::open(output_bin_file_str->c_str(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, output_bin_file);
- if (filerr != FILERR_NONE)
+ filerr = util::core_file::open(*output_bin_file_str, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, output_bin_file);
+ if (filerr != osd_file::error::NONE)
report_error(1, "Unable to open file (%s)", output_bin_file_str->c_str());
}
@@ -2386,8 +2388,8 @@ static void do_extract_cd(parameters_t &params)
output_bin_file.reset();
- filerr = util::core_file::open(trackbin_name.c_str(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, output_bin_file);
- if (filerr != FILERR_NONE)
+ filerr = util::core_file::open(trackbin_name, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, output_bin_file);
+ if (filerr != osd_file::error::NONE)
report_error(1, "Unable to open file (%s)", trackbin_name.c_str());
outputoffs = 0;
@@ -2471,8 +2473,8 @@ static void do_extract_cd(parameters_t &params)
// delete the output files
output_bin_file.reset();
output_toc_file.reset();
- osd_rmfile(output_bin_file_str->c_str());
- osd_rmfile(output_file_str->second->c_str());
+ osd_file::remove(*output_bin_file_str);
+ osd_file::remove(*output_file_str->second);
throw;
}
}
@@ -2528,7 +2530,7 @@ static void do_extract_ld(parameters_t &params)
input_end *= interlace_factor;
// build up the movie info
- avi_movie_info info;
+ avi_file::movie_info info;
info.video_format = FORMAT_YUY2;
info.video_timescale = fps_times_1million / interlace_factor;
info.video_sampletime = 1000000;
@@ -2558,12 +2560,12 @@ static void do_extract_ld(parameters_t &params)
}
// catch errors so we can close & delete the output file
- avi_file *output_file = nullptr;
+ avi_file::ptr output_file;
try
{
// process output file
- avi_error avierr = avi_create(output_file_str->second->c_str(), &info, &output_file);
- if (avierr != AVIERR_NONE)
+ avi_file::error avierr = avi_file::create(*output_file_str->second, info, output_file);
+ if (avierr != avi_file::error::NONE)
report_error(1, "Unable to open file (%s)", output_file_str->second->c_str());
// create the codec configuration
@@ -2599,30 +2601,29 @@ static void do_extract_ld(parameters_t &params)
// write audio
for (int chnum = 0; chnum < channels; chnum++)
{
- avi_error avierr = avi_append_sound_samples(output_file, chnum, avconfig.audio[chnum], actsamples, 0);
- if (avierr != AVIERR_NONE)
- report_error(1, "Error writing samples for hunk %d to file (%s): %s\n", framenum, output_file_str->second->c_str(), avi_error_string(avierr));
+ avi_file::error avierr = output_file->append_sound_samples(chnum, avconfig.audio[chnum], actsamples, 0);
+ if (avierr != avi_file::error::NONE)
+ report_error(1, "Error writing samples for hunk %d to file (%s): %s\n", framenum, output_file_str->second->c_str(), avi_file::error_string(avierr));
}
// write video
if ((framenum + 1) % interlace_factor == 0)
{
- avi_error avierr = avi_append_video_frame(output_file, fullbitmap);
- if (avierr != AVIERR_NONE)
- report_error(1, "Error writing video for hunk %d to file (%s): %s\n", framenum, output_file_str->second->c_str(), avi_error_string(avierr));
+ avi_file::error avierr = output_file->append_video_frame(fullbitmap);
+ if (avierr != avi_file::error::NONE)
+ report_error(1, "Error writing video for hunk %d to file (%s): %s\n", framenum, output_file_str->second->c_str(), avi_file::error_string(avierr));
}
}
// close and return
- avi_close(output_file);
+ output_file.reset();
printf("Extraction complete \n");
}
catch (...)
{
// delete the output file
- if (output_file != nullptr)
- avi_close(output_file);
- osd_rmfile(output_file_str->second->c_str());
+ output_file.reset();
+ osd_file::remove(*output_file_str->second);
throw;
}
}
@@ -2670,8 +2671,8 @@ static void do_add_metadata(parameters_t &params)
dynamic_buffer file;
if (file_str != params.end())
{
- file_error filerr = util::core_file::load(file_str->second->c_str(), file);
- if (filerr != FILERR_NONE)
+ osd_file::error filerr = util::core_file::load(file_str->second->c_str(), file);
+ if (filerr != osd_file::error::NONE)
report_error(1, "Error reading metadata file (%s)", file_str->second->c_str());
}
@@ -2794,8 +2795,8 @@ static void do_dump_metadata(parameters_t &params)
// create the file
if (output_file_str != params.end())
{
- file_error filerr = util::core_file::open(output_file_str->second->c_str(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, output_file);
- if (filerr != FILERR_NONE)
+ osd_file::error filerr = util::core_file::open(*output_file_str->second, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, output_file);
+ if (filerr != osd_file::error::NONE)
report_error(1, "Unable to open file (%s)", output_file_str->second->c_str());
// output the metadata
@@ -2820,7 +2821,7 @@ static void do_dump_metadata(parameters_t &params)
{
// delete the output file
output_file.reset();
- osd_rmfile(output_file_str->second->c_str());
+ osd_file::remove(*output_file_str->second);
throw;
}
}
diff --git a/src/tools/imgtool/stream.cpp b/src/tools/imgtool/stream.cpp
index 4cc4c9ec2db..b11e7a5e4be 100644
--- a/src/tools/imgtool/stream.cpp
+++ b/src/tools/imgtool/stream.cpp
@@ -104,33 +104,26 @@ static imgtool_stream *stream_open_zip(const char *zipname, const char *subname,
imgfile->imgtype = IMG_MEM;
- zip_file *z = nullptr;
- const zip_file_header *zipent = nullptr;
- zip_file_open(zipname, &z);
+ util::archive_file::ptr z;
+ util::archive_file::open_zip(zipname, z);
if (!z)
- goto error;
+ return nullptr;
- zipent = zip_file_first_file(z);
- while (zipent && subname && strcmp(subname, zipent->filename))
- zipent = zip_file_next_file(z);
- if (!zipent)
- goto error;
+ int zipent = z->first_file();
+ while ((zipent >= 0) && subname && strcmp(subname, z->current_name().c_str()))
+ zipent = z->next_file();
+ if (zipent < 0)
+ return nullptr;
- imgfile->filesize = zipent->uncompressed_length;
- imgfile->buffer = reinterpret_cast<std::uint8_t *>(malloc(zipent->uncompressed_length));
+ imgfile->filesize = z->current_uncompressed_length();
+ imgfile->buffer = reinterpret_cast<std::uint8_t *>(malloc(z->current_uncompressed_length()));
if (!imgfile->buffer)
- goto error;
+ return nullptr;
- if (zip_file_decompress(z, imgfile->buffer, zipent->uncompressed_length))
- goto error;
+ if (z->decompress(imgfile->buffer, z->current_uncompressed_length()) != util::archive_file::error::NONE)
+ return nullptr;
- zip_file_close(z);
return imgfile.release();
-
-error:
- if (z)
- zip_file_close(z);
- return nullptr;
}
@@ -154,7 +147,7 @@ imgtool_stream *stream_open(const char *fname, int read_or_write)
util::core_file::ptr f = nullptr;
auto const filerr = util::core_file::open(fname, write_modes[read_or_write], f);
- if (filerr != FILERR_NONE)
+ if (filerr != osd_file::error::NONE)
{
if (!read_or_write)
{
diff --git a/src/tools/ldverify.cpp b/src/tools/ldverify.cpp
index ab3947dfaea..45c20d9d70c 100644
--- a/src/tools/ldverify.cpp
+++ b/src/tools/ldverify.cpp
@@ -102,23 +102,23 @@ static bool chdinterlaced;
static void *open_avi(const char *filename, movie_info &info)
{
// open the file
- avi_file *avi;
- avi_error avierr = avi_open(filename, &avi);
- if (avierr != AVIERR_NONE)
+ avi_file::ptr avi;
+ avi_file::error avierr = avi_file::open(filename, avi);
+ if (avierr != avi_file::error::NONE)
{
- fprintf(stderr, "Error opening AVI file: %s\n", avi_error_string(avierr));
+ fprintf(stderr, "Error opening AVI file: %s\n", avi_file::error_string(avierr));
return nullptr;
}
// extract movie info
- const avi_movie_info *aviinfo = avi_get_movie_info(avi);
- info.framerate = (double)aviinfo->video_timescale / (double)aviinfo->video_sampletime;
- info.numframes = aviinfo->video_numsamples;
- info.width = aviinfo->video_width;
- info.height = aviinfo->video_height;
- info.samplerate = aviinfo->audio_samplerate;
- info.channels = aviinfo->audio_channels;
- return avi;
+ const avi_file::movie_info &aviinfo = avi->get_movie_info();
+ info.framerate = (double)aviinfo.video_timescale / (double)aviinfo.video_sampletime;
+ info.numframes = aviinfo.video_numsamples;
+ info.width = aviinfo.video_width;
+ info.height = aviinfo.video_height;
+ info.samplerate = aviinfo.audio_samplerate;
+ info.channels = aviinfo.audio_channels;
+ return avi.release();
}
@@ -131,17 +131,17 @@ static bool read_avi(void *file, int frame, bitmap_yuy16 &bitmap, INT16 *lsound,
avi_file *avifile = reinterpret_cast<avi_file *>(file);
// read the frame
- avi_error avierr = avi_read_video_frame(avifile, frame, bitmap);
- if (avierr != AVIERR_NONE)
+ avi_file::error avierr = avifile->read_video_frame(frame, bitmap);
+ if (avierr != avi_file::error::NONE)
return FALSE;
// read the samples
- const avi_movie_info *aviinfo = avi_get_movie_info(avifile);
- UINT32 firstsample = (UINT64(aviinfo->audio_samplerate) * UINT64(frame) * UINT64(aviinfo->video_sampletime) + aviinfo->video_timescale - 1) / UINT64(aviinfo->video_timescale);
- UINT32 lastsample = (UINT64(aviinfo->audio_samplerate) * UINT64(frame + 1) * UINT64(aviinfo->video_sampletime) + aviinfo->video_timescale - 1) / UINT64(aviinfo->video_timescale);
- avierr = avi_read_sound_samples(avifile, 0, firstsample, lastsample - firstsample, lsound);
- avierr = avi_read_sound_samples(avifile, 1, firstsample, lastsample - firstsample, rsound);
- if (avierr != AVIERR_NONE)
+ const avi_file::movie_info &aviinfo = avifile->get_movie_info();
+ UINT32 firstsample = (UINT64(aviinfo.audio_samplerate) * UINT64(frame) * UINT64(aviinfo.video_sampletime) + aviinfo.video_timescale - 1) / UINT64(aviinfo.video_timescale);
+ UINT32 lastsample = (UINT64(aviinfo.audio_samplerate) * UINT64(frame + 1) * UINT64(aviinfo.video_sampletime) + aviinfo.video_timescale - 1) / UINT64(aviinfo.video_timescale);
+ avierr = avifile->read_sound_samples(0, firstsample, lastsample - firstsample, lsound);
+ avierr = avifile->read_sound_samples(1, firstsample, lastsample - firstsample, rsound);
+ if (avierr != avi_file::error::NONE)
return false;
samples = lastsample - firstsample;
return true;
@@ -155,7 +155,7 @@ static bool read_avi(void *file, int frame, bitmap_yuy16 &bitmap, INT16 *lsound,
static void close_avi(void *file)
{
avi_file *avifile = reinterpret_cast<avi_file *>(file);
- avi_close(avifile);
+ delete avifile;
}
diff --git a/src/tools/pngcmp.cpp b/src/tools/pngcmp.cpp
index 5103740389b..e34bcf401e4 100644
--- a/src/tools/pngcmp.cpp
+++ b/src/tools/pngcmp.cpp
@@ -73,17 +73,17 @@ static int generate_png_diff(const std::string& imgfile1, const std::string& img
bitmap_argb32 finalbitmap;
int width, height, maxwidth;
util::core_file::ptr file;
- file_error filerr;
+ osd_file::error filerr;
png_error pngerr;
int error = 100;
bool bitmaps_differ;
int x, y;
/* open the source image */
- filerr = util::core_file::open(imgfile1.c_str(), OPEN_FLAG_READ, file);
- if (filerr != FILERR_NONE)
+ filerr = util::core_file::open(imgfile1, OPEN_FLAG_READ, file);
+ if (filerr != osd_file::error::NONE)
{
- printf("Could not open %s (%d)\n", imgfile1.c_str(), filerr);
+ printf("Could not open %s (%d)\n", imgfile1.c_str(), int(filerr));
goto error;
}
@@ -97,10 +97,10 @@ static int generate_png_diff(const std::string& imgfile1, const std::string& img
}
/* open the source image */
- filerr = util::core_file::open(imgfile2.c_str(), OPEN_FLAG_READ, file);
- if (filerr != FILERR_NONE)
+ filerr = util::core_file::open(imgfile2, OPEN_FLAG_READ, file);
+ if (filerr != osd_file::error::NONE)
{
- printf("Could not open %s (%d)\n", imgfile2.c_str(), filerr);
+ printf("Could not open %s (%d)\n", imgfile2.c_str(), int(filerr));
goto error;
}
@@ -170,10 +170,10 @@ static int generate_png_diff(const std::string& imgfile1, const std::string& img
}
/* write the final PNG */
- filerr = util::core_file::open(outfilename.c_str(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, file);
- if (filerr != FILERR_NONE)
+ filerr = util::core_file::open(outfilename, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, file);
+ if (filerr != osd_file::error::NONE)
{
- printf("Could not open %s (%d)\n", outfilename.c_str(), filerr);
+ printf("Could not open %s (%d)\n", outfilename.c_str(), int(filerr));
goto error;
}
pngerr = png_write_bitmap(*file, nullptr, finalbitmap, 0, nullptr);
@@ -193,6 +193,6 @@ static int generate_png_diff(const std::string& imgfile1, const std::string& img
error:
if (error == -1)
- osd_rmfile(outfilename.c_str());
+ osd_file::remove(outfilename);
return error;
}
diff --git a/src/tools/regrep.cpp b/src/tools/regrep.cpp
index b0cad2497ae..0c6d11093c6 100644
--- a/src/tools/regrep.cpp
+++ b/src/tools/regrep.cpp
@@ -235,7 +235,7 @@ int main(int argc, char *argv[])
/* read the template file into an astring */
std::string tempheader;
- if (util::core_file::load(tempfilename.c_str(), &buffer, bufsize) == FILERR_NONE)
+ if (util::core_file::load(tempfilename.c_str(), &buffer, bufsize) == osd_file::error::NONE)
{
tempheader.assign((const char *)buffer, bufsize);
osd_free(buffer);
@@ -565,7 +565,7 @@ static util::core_file::ptr create_file_and_output_header(std::string &filename,
util::core_file::ptr file;
/* create the indexfile */
- if (util::core_file::open(filename.c_str(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS | OPEN_FLAG_NO_BOM, file) != FILERR_NONE)
+ if (util::core_file::open(filename, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS | OPEN_FLAG_NO_BOM, file) != osd_file::error::NONE)
return util::core_file::ptr();
/* print a header */
@@ -728,27 +728,27 @@ static int compare_screenshots(summary_file *curfile)
if (curfile->status[listnum] == STATUS_SUCCESS)
{
std::string fullname;
- file_error filerr;
+ osd_file::error filerr;
util::core_file::ptr file;
/* get the filename for the image */
fullname = string_format("%s" PATH_SEPARATOR "snap" PATH_SEPARATOR "%s" PATH_SEPARATOR "final.png", lists[listnum].dir, curfile->name);
/* open the file */
- filerr = util::core_file::open(fullname.c_str(), OPEN_FLAG_READ, file);
+ filerr = util::core_file::open(fullname, OPEN_FLAG_READ, file);
/* if that failed, look in the old location */
- if (filerr != FILERR_NONE)
+ if (filerr != osd_file::error::NONE)
{
/* get the filename for the image */
fullname = string_format("%s" PATH_SEPARATOR "snap" PATH_SEPARATOR "_%s.png", lists[listnum].dir, curfile->name);
/* open the file */
- filerr = util::core_file::open(fullname.c_str(), OPEN_FLAG_READ, file);
+ filerr = util::core_file::open(fullname, OPEN_FLAG_READ, file);
}
/* if that worked, load the file */
- if (filerr == FILERR_NONE)
+ if (filerr == osd_file::error::NONE)
{
png_read_bitmap(*file, bitmaps[listnum]);
file.reset();
@@ -837,7 +837,7 @@ static int generate_png_diff(const summary_file *curfile, std::string &destdir,
int bitmapcount = 0;
int listnum, bmnum;
util::core_file::ptr file;
- file_error filerr;
+ osd_file::error filerr;
png_error pngerr;
int error = -1;
int starty;
@@ -853,8 +853,8 @@ static int generate_png_diff(const summary_file *curfile, std::string &destdir,
tempname = string_format("%s" PATH_SEPARATOR "%s", lists[listnum].dir, srcimgname.c_str());
/* open the source image */
- filerr = util::core_file::open(tempname.c_str(), OPEN_FLAG_READ, file);
- if (filerr != FILERR_NONE)
+ filerr = util::core_file::open(tempname, OPEN_FLAG_READ, file);
+ if (filerr != osd_file::error::NONE)
goto error;
/* load the source image */
@@ -925,8 +925,8 @@ static int generate_png_diff(const summary_file *curfile, std::string &destdir,
}
/* write the final PNG */
- filerr = util::core_file::open(dstfilename.c_str(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, file);
- if (filerr != FILERR_NONE)
+ filerr = util::core_file::open(dstfilename, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, file);
+ if (filerr != osd_file::error::NONE)
goto error;
pngerr = png_write_bitmap(*file, nullptr, finalbitmap, 0, nullptr);
file.reset();
@@ -938,7 +938,7 @@ static int generate_png_diff(const summary_file *curfile, std::string &destdir,
error:
if (error)
- osd_rmfile(dstfilename.c_str());
+ osd_file::remove(dstfilename);
return error;
}
diff --git a/src/tools/romcmp.cpp b/src/tools/romcmp.cpp
index 4d89718abe9..641667b6342 100644
--- a/src/tools/romcmp.cpp
+++ b/src/tools/romcmp.cpp
@@ -393,11 +393,11 @@ static float filecompare(const fileinfo *file1,const fileinfo *file2,int mode1,i
static void readfile(const char *path,fileinfo *file)
{
- file_error filerr;
+ osd_file::error filerr;
UINT64 filesize;
UINT32 actual;
char fullname[256];
- osd_file *f = nullptr;
+ osd_file::ptr f;
if (path)
{
@@ -414,22 +414,19 @@ static void readfile(const char *path,fileinfo *file)
return;
}
- filerr = osd_open(fullname, OPEN_FLAG_READ, &f, &filesize);
- if (filerr != FILERR_NONE)
+ filerr = osd_file::open(fullname, OPEN_FLAG_READ, f, filesize);
+ if (filerr != osd_file::error::NONE)
{
- printf("%s: error %d\n", fullname, filerr);
+ printf("%s: error %d\n", fullname, int(filerr));
return;
}
- filerr = osd_read(f, file->buf, 0, file->size, &actual);
- if (filerr != FILERR_NONE)
+ filerr = f->read(file->buf, 0, file->size, actual);
+ if (filerr != osd_file::error::NONE)
{
- printf("%s: error %d\n", fullname, filerr);
- osd_close(f);
+ printf("%s: error %d\n", fullname, int(filerr));
return;
}
-
- osd_close(f);
}
@@ -493,43 +490,45 @@ static int load_files(int i, int *found, const char *path)
/* if not, try to open as a ZIP file */
else
{
- zip_file *zip;
- const zip_file_header* zipent;
- zip_error ziperr;
+ util::archive_file::ptr zip;
/* wasn't a directory, so try to open it as a zip file */
- ziperr = zip_file_open(path, &zip);
- if (ziperr != ZIPERR_NONE)
+ if ((util::archive_file::open_zip(path, zip) != util::archive_file::error::NONE) &&
+ (util::archive_file::open_7z(path, zip) != util::archive_file::error::NONE))
{
printf("Error, cannot open zip file '%s' !\n", path);
return 1;
}
/* load all files in zip file */
- for (zipent = zip_file_first_file(zip); zipent != nullptr; zipent = zip_file_next_file(zip))
+ for (int zipent = zip->first_file(); zipent >= 0; zipent = zip->next_file())
{
+ if (zip->current_is_directory()) continue;
+
int size;
- size = zipent->uncompressed_length;
+ size = zip->current_uncompressed_length();
while (size && (size & 1) == 0) size >>= 1;
- if (zipent->uncompressed_length == 0) // || (size & ~1))
+ if (zip->current_uncompressed_length() == 0) // || (size & ~1))
+ {
printf("%-23s %-23s ignored (not a ROM)\n",
- i ? "" : zipent->filename, i ? zipent->filename : "");
+ i ? "" : zip->current_name().c_str(), i ? zip->current_name().c_str() : "");
+ }
else
{
fileinfo *file = &files[i][found[i]];
- const char *delim = strrchr(zipent->filename,'/');
+ const char *delim = strrchr(zip->current_name().c_str(), '/');
if (delim)
strcpy (file->name,delim+1);
else
- strcpy(file->name,zipent->filename);
- file->size = zipent->uncompressed_length;
+ strcpy(file->name,zip->current_name().c_str());
+ file->size = zip->current_uncompressed_length();
if ((file->buf = (unsigned char *)malloc(file->size)) == nullptr)
printf("%s: out of memory!\n",file->name);
else
{
- if (zip_file_decompress(zip, (char *)file->buf, file->size) != ZIPERR_NONE)
+ if (zip->decompress(file->buf, file->size) != util::archive_file::error::NONE)
{
free(file->buf);
file->buf = nullptr;
@@ -545,7 +544,6 @@ static int load_files(int i, int *found, const char *path)
found[i]++;
}
}
- zip_file_close(zip);
}
return 0;
}
@@ -747,6 +745,6 @@ int CLIB_DECL main(int argc,char *argv[])
}
}
- zip_file_cache_clear();
+ util::archive_file::cache_clear();
return 0;
}
diff --git a/src/tools/split.cpp b/src/tools/split.cpp
index f942e1481c2..586264283d7 100644
--- a/src/tools/split.cpp
+++ b/src/tools/split.cpp
@@ -69,7 +69,7 @@ static int split_file(const char *filename, const char *basename, UINT32 splitsi
void *splitbuffer = nullptr;
int index, partnum;
UINT64 totallength;
- file_error filerr;
+ osd_file::error filerr;
int error = 1;
// convert split size to MB
@@ -82,7 +82,7 @@ static int split_file(const char *filename, const char *basename, UINT32 splitsi
// open the file for read
filerr = util::core_file::open(filename, OPEN_FLAG_READ, infile);
- if (filerr != FILERR_NONE)
+ if (filerr != osd_file::error::NONE)
{
fprintf(stderr, "Fatal error: unable to open file '%s'\n", filename);
goto cleanup;
@@ -119,8 +119,8 @@ static int split_file(const char *filename, const char *basename, UINT32 splitsi
splitfilename.assign(basename).append(".split");
// create the split file
- filerr = util::core_file::open(splitfilename.c_str(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_NO_BOM, splitfile);
- if (filerr != FILERR_NONE)
+ filerr = util::core_file::open(splitfilename, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_NO_BOM, splitfile);
+ if (filerr != osd_file::error::NONE)
{
fprintf(stderr, "Fatal error: unable to create split file '%s'\n", splitfilename.c_str());
goto cleanup;
@@ -155,8 +155,8 @@ static int split_file(const char *filename, const char *basename, UINT32 splitsi
outfilename = string_format("%s.%03d", basename, partnum);
// create it
- filerr = util::core_file::open(outfilename.c_str(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, outfile);
- if (filerr != FILERR_NONE)
+ filerr = util::core_file::open(outfilename, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, outfile);
+ if (filerr != osd_file::error::NONE)
{
printf("\n");
fprintf(stderr, "Fatal error: unable to create output file '%s'\n", outfilename.c_str());
@@ -219,7 +219,7 @@ static int join_file(const char *filename, const char *outname, int write_output
std::string basepath;
util::core_file::ptr outfile, infile, splitfile;
void *splitbuffer = nullptr;
- file_error filerr;
+ osd_file::error filerr;
UINT32 splitsize;
char buffer[256];
int error = 1;
@@ -227,7 +227,7 @@ static int join_file(const char *filename, const char *outname, int write_output
// open the file for read
filerr = util::core_file::open(filename, OPEN_FLAG_READ, splitfile);
- if (filerr != FILERR_NONE)
+ if (filerr != osd_file::error::NONE)
{
fprintf(stderr, "Fatal error: unable to open file '%s'\n", filename);
goto cleanup;
@@ -267,8 +267,8 @@ static int join_file(const char *filename, const char *outname, int write_output
if (write_output)
{
// don't overwrite the original!
- filerr = util::core_file::open(outfilename.c_str(), OPEN_FLAG_READ, outfile);
- if (filerr == FILERR_NONE)
+ filerr = util::core_file::open(outfilename, OPEN_FLAG_READ, outfile);
+ if (filerr == osd_file::error::NONE)
{
outfile.reset();
fprintf(stderr, "Fatal error: output file '%s' already exists\n", outfilename.c_str());
@@ -276,8 +276,8 @@ static int join_file(const char *filename, const char *outname, int write_output
}
// open the output for write
- filerr = util::core_file::open(outfilename.c_str(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, outfile);
- if (filerr != FILERR_NONE)
+ filerr = util::core_file::open(outfilename, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE, outfile);
+ if (filerr != osd_file::error::NONE)
{
fprintf(stderr, "Fatal error: unable to create file '%s'\n", outfilename.c_str());
goto cleanup;
@@ -306,7 +306,7 @@ static int join_file(const char *filename, const char *outname, int write_output
// read the file's contents
infilename.insert(0, basepath);
filerr = util::core_file::load(infilename.c_str(), &splitbuffer, length);
- if (filerr != FILERR_NONE)
+ if (filerr != osd_file::error::NONE)
{
printf("\n");
fprintf(stderr, "Fatal error: unable to load file '%s'\n", infilename.c_str());
diff --git a/src/tools/src2html.cpp b/src/tools/src2html.cpp
index e95cbe11764..38260a62879 100644
--- a/src/tools/src2html.cpp
+++ b/src/tools/src2html.cpp
@@ -279,7 +279,7 @@ int main(int argc, char *argv[])
// read the template file into an std::string
UINT32 bufsize;
void *buffer;
- if (util::core_file::load(tempfilename.c_str(), &buffer, bufsize) == FILERR_NONE)
+ if (util::core_file::load(tempfilename.c_str(), &buffer, bufsize) == osd_file::error::NONE)
{
tempheader.assign((const char *)buffer, bufsize);
osd_free(buffer);
@@ -517,7 +517,7 @@ static int output_file(file_type type, int srcrootlen, int dstrootlen, std::stri
// open the source file
util::core_file::ptr src;
- if (util::core_file::open(srcfile.c_str(), OPEN_FLAG_READ, src) != FILERR_NONE)
+ if (util::core_file::open(srcfile, OPEN_FLAG_READ, src) != osd_file::error::NONE)
{
fprintf(stderr, "Unable to read file '%s'\n", srcfile.c_str());
return 1;
@@ -732,7 +732,7 @@ static util::core_file::ptr create_file_and_output_header(std::string &filename,
{
// create the indexfile
util::core_file::ptr file;
- if (util::core_file::open(filename.c_str(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS | OPEN_FLAG_NO_BOM, file) != FILERR_NONE)
+ if (util::core_file::open(filename, OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS | OPEN_FLAG_NO_BOM, file) != osd_file::error::NONE)
return util::core_file::ptr();
// print a header
@@ -865,7 +865,7 @@ static bool find_include_file(std::string &srcincpath, int srcrootlen, int dstro
// see if we can open it
util::core_file::ptr testfile;
- if (util::core_file::open(srcincpath.c_str(), OPEN_FLAG_READ, testfile) == FILERR_NONE)
+ if (util::core_file::open(srcincpath, OPEN_FLAG_READ, testfile) == osd_file::error::NONE)
{
// close the file
testfile.reset();
diff --git a/src/tools/unidasm.cpp b/src/tools/unidasm.cpp
index f69de2b0864..59cce01ad29 100644
--- a/src/tools/unidasm.cpp
+++ b/src/tools/unidasm.cpp
@@ -181,6 +181,7 @@ CPU_DISASSEMBLE( tms7000 );
CPU_DISASSEMBLE( tms9900 );
CPU_DISASSEMBLE( tms9980 );
CPU_DISASSEMBLE( tms9995 );
+CPU_DISASSEMBLE( tp0320 );
CPU_DISASSEMBLE( tx0_64kw );
CPU_DISASSEMBLE( tx0_8kw );
CPU_DISASSEMBLE( ucom4 );
@@ -333,6 +334,7 @@ static const dasm_table_entry dasm_table[] =
{ "tms9900", _16be, 0, CPU_DISASSEMBLE_NAME(tms9900) },
{ "tms9980", _8bit, 0, CPU_DISASSEMBLE_NAME(tms9980) },
{ "tms9995", _8bit, 0, CPU_DISASSEMBLE_NAME(tms9995) },
+ { "tp0320", _16be, 0, CPU_DISASSEMBLE_NAME(tp0320) },
{ "tx0_64kw", _32be, -2, CPU_DISASSEMBLE_NAME(tx0_64kw) },
{ "tx0_8kw", _32be, -2, CPU_DISASSEMBLE_NAME(tx0_8kw) },
{ "ucom4", _8bit, 0, CPU_DISASSEMBLE_NAME(ucom4) },
@@ -494,7 +496,7 @@ usage:
int main(int argc, char *argv[])
{
- file_error filerr;
+ osd_file::error filerr;
int displayendian;
int displaychunk;
UINT32 curbyte;
@@ -513,7 +515,7 @@ int main(int argc, char *argv[])
// load the file
filerr = util::core_file::load(opts.filename, &data, length);
- if (filerr != FILERR_NONE)
+ if (filerr != osd_file::error::NONE)
{
fprintf(stderr, "Error opening file '%s'\n", opts.filename);
return 1;