Previous 15994 Revisions Next

r9928 Wednesday 5th January, 2011 at 16:03:23 UTC by Miodrag Milanović
Moved some image devices to emu section, and updated MESS for using it.
[src/emu]emu.mak uiimage.c uiimage.h uimenu.c
[src/emu/imagedev]bitbngr.c* bitbngr.h* cartslot.c* cartslot.h* cassette.c* cassette.h* cassimg.c* cassimg.h* chd_cd.c* chd_cd.h* flopdrv.c* flopdrv.h* flopimg.c* flopimg.h* harddriv.c* harddriv.h* multcart.c* multcart.h* printer.c* printer.h* snapquik.c* snapquik.h* wavfile.c* wavfile.h*
[src/emu/machine]idectrl.c scsicd.c scsihd.c
[src/emu/sound]wave.c
[src/mame/drivers]megadriv.c
[src/mame/machine]stvcd.c
[src/mess]mess.mak messcore.mak tiny.mak uimess.c uimess.h
[src/mess/devices]aescart.c aescart.h appldriv.c bitbngr.c bitbngr.h cartslot.c cartslot.h cassette.c cassette.h chd_cd.c chd_cd.h coco_fdc.c cococart.c cococart.h flopdrv.c flopdrv.h harddriv.c harddriv.h multcart.c multcart.h printer.c printer.h snapquik.c snapquik.h sonydriv.c sonydriv.h ti99_hd.c z80bin.c z80bin.h
[src/mess/drivers]3do.c a2600.c a310.c a7800.c abc1600.c abc80.c abc80x.c adam.c advision.c aim65.c altair.c ami1200.c amiga.c amstrad.c apf.c apogee.c apple1.c apple2.c apple2gs.c apple3.c apricot.c apricotf.c aquarius.c arcadia.c astrocde.c at.c atari.c atarist.c atm.c atom.c b2m.c bbc.c bbcbc.c bebox.c beta.c bk.c bmjr.c bob85.c bullet.c bw12.c bw2.c c80.c casloopy.c cdi.c cgenie.c channelf.c coco.c coleco.c compis.c comquest.c comx35.c concept.c cosmicos.c crvision.c d6800.c dai.c dc.c dgn_beta.c e01.c einstein.c electron.c elf.c elwro800.c enterp.c eti660.c exelv.c exidy.c exp85.c fm7.c fmtowns.c galaxy.c gamecom.c gamepock.c gb.c gba.c gmaster.c hec2hrp.c ht68k.c huebler.c interact.c intv.c ip20.c ip22.c jaguar.c jr100.c jtc.c jupiter.c kaypro.c kc.c kim1.c kyocera.c lc80.c lviv.c lynx.c mac.c mbee.c mc10.c mc1000.c mekd2.c microdec.c microtan.c mikro80.c mikromik.c mikrosha.c mpf1.c msx.c mtx.c mycom.c mz2500.c mz700.c mz80.c n64.c nanos.c nascom1.c nc.c nes.c newbrain.c ng_aes.c ngp.c odyssey2.c ondra.c orao.c oric.c orion.c osbexec.c osborne1.c osi.c p8k.c partner.c pasogo.c pb1000.c pc.c pc6001.c pc8001.c pc8401a.c pc8801.c pce.c pcw.c pcw16.c pecom.c pegasus.c pentagon.c phc25.c pippin.c pk8000.c pk8020.c pmd85.c pockstat.c pokemini.c poly88.c poly880.c portfoli.c prestige.c primo.c prof80.c psion.c psx.c pv1000.c pv2000.c px4.c px8.c pyl601.c ql.c radio86.c rmnimbus.c rx78.c samcoupe.c saturn.c scorpion.c scv.c sg1000.c smc777.c sms.c sord.c spc1000.c spec128.c special.c specpls3.c spectrum.c ssem.c studio2.c super80.c supracan.c svi318.c svision.c tandy2k.c thomson.c ti85.c ti990_4.c ti99_4p.c ti99_4x.c ti99_8.c tiki100.c timex.c tm990189.c tmc1800.c tmc2000e.c tmc600.c trs80.c trs80m2.c tutor.c unixpc.c ut88.c v1050.c vboy.c vc4000.c vector06.c vectrex.c vg5k.c vic20.c victor9k.c vidbrain.c vii.c vip.c vixen.c vtech1.c vtech2.c wswan.c x07.c x1.c x68k.c xerox820.c xor100.c z80ne.c zx.c
[src/mess/formats]a26_cas.h adam_dsk.h ami_dsk.h ap2_dsk.h ap_dsk35.h apf_apt.h apridisk.h atarist_dsk.h atom_atm.h atom_tap.h basicdsk.h cassimg.c cassimg.h cbm_snqk.h cbm_tap.h cgen_cas.h coco_cas.h coco_dsk.h comx35_comx.h comx35_dsk.h coupedsk.h cpis_dsk.h cqm_dsk.c csw_cas.h d64_dsk.c d64_dsk.h d81_dsk.h d88_dsk.c dim_dsk.h dsk_dsk.c exidydsk.h fdi_dsk.c flopimg.c flopimg.h fm7_cas.h fmsx_cas.h g64_dsk.c g64_dsk.h gtp_cas.h hect_tap.h imd_dsk.c jupi_tap.h kim1_cas.h lviv_lvt.h m65_snqk.h msx_dsk.h mz_cas.h nes_dsk.h orao_cas.h oric_dsk.c oric_dsk.h oric_tap.h p6001_cas.h pc_dsk.h pmd_pmd.h primoptp.h rk_cas.h smx_dsk.h sord_cas.h spec_snqk.h svi_cas.h svi_dsk.h td0_dsk.c thom_cas.c thom_dsk.h ti99_dsk.h timex_dck.h trd_dsk.h trs_cas.h trs_cmd.h trs_dsk.c trs_dsk.h tzx_cas.h uef_cas.h vg5k_cas.h vt_cas.h vt_dsk.h wavfile.c wavfile.h x1_tap.h z80ne_dsk.c z80ne_dsk.h zx81_p.c zx81_p.h
[src/mess/includes]amstrad.h apple1.h c64.h cbm.h cbmb.h coco.h comx35.h exidy.h galaxy.h genesis.h kaypro.h kc.h lviv.h lynx.h mbee.h microtan.h msx.h mtx.h nascom1.h pet.h pk8020.h poly88.h primo.h spectrum.h thomson.h ti85.h trs80.h v1050.h z1013.h
[src/mess/machine]990_dk.c 990_dk.h 990_hd.c 990_hd.h abc830.c abc830.h adam.c amigacd.c amigafdc.c amstrad.c apple1.c apple2.c apple2gs.c atarifdc.c b2m.c bbc.c beta.c bk.c c128.c c1541.c c1551.c c1571.c c1581.c c16.c c2040.c c64.c c8280.c cbm.c cbmb.c cdic.c cdic.h cdicdic.c cdicdic.h cgenie.c coco.c comx35.c concept.c corvushd.c ctronics.c dai.c dc.c dgn_beta.c electron.c exidy.c galaxy.c gb.c gdrom.c genesis.c hec2hrp.c i8271.c ibmpc.c jupiter.c kaypro.c kc.c lviv.c lynx.c matsucd.c mbee.c mc6843.c microtan.c mikro80.c msx.c mtx.c mz700.c mz80.c nascom1.c nes.c odyssey2.c ondra.c orao.c oric.c orion.c osborne1.c partner.c pc.c pc_hdc.c pce.c pecom.c pet.c pk8020.c pmd85.c poly88.c primo.c radio86.c rmnimbus.c smartmed.c smc92x4.c sms.c snescart.c snescart.h special.c super80.c svi318.c tf20.c trs80.c upd765.h ut88.c vector06.c vtech2.c wd17xx.c wswan.c x68k_hdc.c z80ne.c zx.c
[src/mess/machine/ti99]bwg.c gromport.c gromport.h hfdc.c peribox.c sgcpu.c ti_fdc.c tiboard.c
[src/mess/osd/windows]menu.c
[src/mess/tools/castool]main.c
[src/mess/tools/imgtool]iflopimg.c iflopimg.h imgtool.h
[src/osd/windows]input.c

src/mame/machine/stvcd.c
r9927r9928
2222***************************************************************************/
2323
2424#include "emu.h"
25#ifdef MESS
26#include "devices/chd_cd.h"
27#endif
25#include "imagedev/chd_cd.h"
2826#include "cdrom.h"
2927#include "stvcd.h"
3028
src/mame/drivers/megadriv.c
r9927r9928
271271#include "cpu/sh2/sh2.h"
272272#include "cpu/sh2/sh2comn.h"
273273#include "sound/cdda.h"
274#ifdef MESS
275#include "devices/chd_cd.h"
276#endif
274#include "imagedev/chd_cd.h"
277275#include "sound/rf5c68.h"
278276
279277#define MEGADRIV_VDP_VRAM(address) megadrive_vdp_vram[(address)&0x7fff]
src/osd/windows/input.c
r9927r9928
7272#include "strconv.h"
7373#include "config.h"
7474
75#ifdef MESS
76#include "uimess.h"
77#endif
78
79
80
8175//============================================================
8276//  PARAMETERS
8377//============================================================
src/emu/uimenu.c
r9927r9928
1919#include "uimenu.h"
2020#include "audit.h"
2121#include "crsshair.h"
22
23#ifdef MESS
24#include "uimess.h"
25#endif /* MESS */
26
2722#include <ctype.h>
23#include "imagedev/cassette.h"
24#include "imagedev/bitbngr.h"
2825
2926
3027
r9927r9928
15491546
15501547      /* add file manager menu */
15511548      ui_menu_item_append(menu, "File Manager", NULL, 0, (void*)ui_image_menu_file_manager);
1552   #ifdef MESS
1553      /* add MESS-specific menus */
1554      ui_mess_main_menu_populate(machine, menu);
1555   #endif /* MESS */
1549     
1550      /* add tape control menu */
1551      if (machine->m_devicelist.first(CASSETTE))
1552         ui_menu_item_append(menu, "Tape Control", NULL, 0, (void*)ui_mess_menu_tape_control);
1553
1554      /* add bitbanger control menu */
1555      if (machine->m_devicelist.first(BITBANGER))
1556         ui_menu_item_append(menu, "Bitbanger Control", NULL, 0, (void*)ui_mess_menu_bitbanger_control);
15561557   }
15571558   /* add keyboard mode menu */
15581559   if (input_machine_has_keyboard(machine) && inputx_can_post(machine))
src/emu/sound/wave.c
r9927r9928
1515
1616#include "emu.h"
1717#include "streams.h"
18#ifdef MESS
19#include "devices/cassette.h"
20#endif
18#include "imagedev/cassette.h"
2119#include "wave.h"
2220
2321#define ALWAYS_PLAY_SOUND   0
2422
2523static STREAM_UPDATE( wave_sound_update )
2624{
27#ifdef MESS
2825   device_image_interface *image = (device_image_interface *)param;
2926   int speakers = speaker_output_count(image->device().machine->config);
3027   cassette_image *cassette;
r9927r9928
6259      if (speakers > 1)
6360         memset(right_buffer, 0, sizeof(*right_buffer) * samples);
6461   }
65#endif
6662}
6763
6864
r9927r9928
7470   assert( device != NULL );
7571   assert( device->baseconfig().static_config() != NULL );
7672   int speakers = speaker_output_count(device->machine->config);
77#ifdef MESS
7873   image = dynamic_cast<device_image_interface *>(device->machine->device( (const char *)device->baseconfig().static_config()));
79#endif
8074   if (speakers > 1)
8175      stream_create(device, 0, 2, device->machine->sample_rate, (void *)image, wave_sound_update);
8276   else
src/emu/uiimage.c
r9927r9928
2323#include "uimenu.h"
2424#include "zippath.h"
2525#include "unicode.h"
26#include "imagedev/cassette.h"
27#include "imagedev/bitbngr.h"
2628
2729
2830
r9927r9928
10141016   /* process the menu */
10151017   ui_menu_process(machine, menu, 0);
10161018}
1019
1020/***************************************************************************
1021    TYPE DEFINITIONS
1022***************************************************************************/
1023#define TAPECMD_NULL         ((void *) 0x0000)
1024#define TAPECMD_STOP         ((void *) 0x0001)
1025#define TAPECMD_PLAY         ((void *) 0x0002)
1026#define TAPECMD_RECORD         ((void *) 0x0003)
1027#define TAPECMD_REWIND         ((void *) 0x0004)
1028#define TAPECMD_FAST_FORWARD      ((void *) 0x0005)
1029#define TAPECMD_SLIDER         ((void *) 0x0006)
1030#define TAPECMD_SELECT         ((void *) 0x0007)
1031
1032#define BITBANGERCMD_SELECT         ((void *) 0x0000)
1033#define BITBANGERCMD_MODE         ((void *) 0x0001)
1034#define BITBANGERCMD_BAUD         ((void *) 0x0002)
1035#define BITBANGERCMD_TUNE         ((void *) 0x0003)
1036
1037
1038typedef struct _tape_control_menu_state tape_control_menu_state;
1039struct _tape_control_menu_state
1040{
1041   int index;
1042   device_image_interface *device;
1043};
1044
1045
1046
1047typedef struct _bitbanger_control_menu_state bitbanger_control_menu_state;
1048struct _bitbanger_control_menu_state
1049{
1050   int index;
1051   device_image_interface *device;
1052};
1053
1054
1055
1056/***************************************************************************
1057    IMPLEMENTATION
1058***************************************************************************/
1059
1060/*-------------------------------------------------
1061    cassette_count - returns the number of cassette
1062    devices in the machine
1063-------------------------------------------------*/
1064
1065INLINE int cassette_count( running_machine *machine )
1066{
1067   int count = 0;
1068   device_t *device = machine->m_devicelist.first(CASSETTE);
1069
1070   while ( device )
1071   {
1072      count++;
1073      device = device->typenext();
1074   }
1075   return count;
1076}
1077
1078/*-------------------------------------------------
1079    bitbanger_count - returns the number of bitbanger
1080    devices in the machine
1081-------------------------------------------------*/
1082
1083INLINE int bitbanger_count( running_machine *machine )
1084{
1085   int count = 0;
1086   device_t *device = machine->m_devicelist.first(BITBANGER);
1087
1088   while ( device )
1089   {
1090      count++;
1091      device = device->typenext();
1092   }
1093   return count;
1094}
1095
1096/*-------------------------------------------------
1097    tapecontrol_gettime - returns a textual
1098    representation of the time
1099-------------------------------------------------*/
1100
1101astring *tapecontrol_gettime(astring *dest, device_t *device, int *curpos, int *endpos)
1102{
1103   double t0, t1;
1104
1105   t0 = cassette_get_position(device);
1106   t1 = cassette_get_length(device);
1107
1108   if (t1)
1109      astring_printf(dest, "%04d/%04d", (int) t0, (int) t1);
1110   else
1111      astring_printf(dest, "%04d/%04d", 0, (int) t1);
1112
1113   if (curpos != NULL)
1114      *curpos = t0;
1115   if (endpos != NULL)
1116      *endpos = t1;
1117
1118   return dest;
1119}
1120
1121
1122
1123/*-------------------------------------------------
1124    menu_tape_control_populate - populates the
1125    main tape control menu
1126-------------------------------------------------*/
1127
1128static void menu_tape_control_populate(running_machine *machine, ui_menu *menu, tape_control_menu_state *menustate)
1129{
1130   astring timepos;
1131   cassette_state state;
1132   int count = cassette_count(machine);
1133   UINT32 flags = 0;
1134
1135   if( count > 0 )
1136   {
1137      if( menustate->index == (count-1) )
1138         flags |= MENU_FLAG_LEFT_ARROW;
1139      else
1140         flags |= MENU_FLAG_RIGHT_ARROW;
1141   }
1142
1143   if (menustate->device->exists())
1144   {
1145      double t0, t1;
1146      UINT32 tapeflags = 0;
1147
1148      t0 = cassette_get_position(&menustate->device->device());
1149      t1 = cassette_get_length(&menustate->device->device());
1150
1151      if (t1 > 0)
1152      {
1153         if (t0 > 0)
1154            tapeflags |= MENU_FLAG_LEFT_ARROW;
1155         if (t0 < t1)
1156            tapeflags |= MENU_FLAG_RIGHT_ARROW;
1157      }
1158
1159      /* name of tape */
1160      ui_menu_item_append(menu, menustate->device->image_config().devconfig().name(), menustate->device->filename(), flags, TAPECMD_SELECT);
1161
1162      /* state */
1163      tapecontrol_gettime(&timepos, &menustate->device->device(), NULL, NULL);
1164      state = cassette_get_state(&menustate->device->device());
1165      ui_menu_item_append(
1166         menu,
1167         (state & CASSETTE_MASK_UISTATE) == CASSETTE_STOPPED
1168            ?   "stopped"
1169            :   ((state & CASSETTE_MASK_UISTATE) == CASSETTE_PLAY
1170               ? ((state & CASSETTE_MASK_MOTOR) == CASSETTE_MOTOR_ENABLED ? "playing" : "(playing)")
1171               : ((state & CASSETTE_MASK_MOTOR) == CASSETTE_MOTOR_ENABLED ? "recording" : "(recording)")
1172               ),
1173         astring_c(&timepos),
1174         tapeflags,
1175         TAPECMD_SLIDER);
1176
1177      /* pause or stop */
1178      ui_menu_item_append(menu, "Pause/Stop", NULL, 0, TAPECMD_STOP);
1179
1180      /* play */
1181      ui_menu_item_append(menu, "Play", NULL, 0, TAPECMD_PLAY);
1182
1183      /* record */
1184      ui_menu_item_append(menu, "Record", NULL, 0, TAPECMD_RECORD);
1185
1186      /* rewind */
1187      ui_menu_item_append(menu, "Rewind", NULL, 0, TAPECMD_REWIND);
1188
1189      /* fast forward */
1190      ui_menu_item_append(menu, "Fast Forward", NULL, 0, TAPECMD_FAST_FORWARD);
1191   }
1192   else
1193   {
1194      /* no tape loaded */
1195      ui_menu_item_append(menu, "No Tape Image loaded", NULL, flags, NULL);
1196   }
1197}
1198
1199
1200/*-------------------------------------------------
1201    menu_bitbanger_control_populate - populates the
1202    main bitbanger control menu
1203-------------------------------------------------*/
1204
1205static void menu_bitbanger_control_populate(running_machine *machine, ui_menu *menu, bitbanger_control_menu_state *menustate)
1206{
1207   int count = bitbanger_count(machine);
1208   UINT32 flags = 0, mode_flags = 0, baud_flags = 0, tune_flags = 0;
1209
1210   if( count > 0 )
1211   {
1212      if( menustate->index == (count-1) )
1213         flags |= MENU_FLAG_LEFT_ARROW;
1214      else
1215         flags |= MENU_FLAG_RIGHT_ARROW;
1216   }
1217
1218   if (bitbanger_inc_mode(&menustate->device->device(), TRUE))
1219      mode_flags |= MENU_FLAG_RIGHT_ARROW;
1220
1221   if (bitbanger_dec_mode(&menustate->device->device(), TRUE))
1222      mode_flags |= MENU_FLAG_LEFT_ARROW;
1223
1224   if (bitbanger_inc_baud(&menustate->device->device(), TRUE))
1225      baud_flags |= MENU_FLAG_RIGHT_ARROW;
1226
1227   if (bitbanger_dec_baud(&menustate->device->device(), TRUE))
1228      baud_flags |= MENU_FLAG_LEFT_ARROW;
1229
1230   if (bitbanger_inc_tune(&menustate->device->device(), TRUE))
1231      tune_flags |= MENU_FLAG_RIGHT_ARROW;
1232
1233   if (bitbanger_dec_tune(&menustate->device->device(), TRUE))
1234      tune_flags |= MENU_FLAG_LEFT_ARROW;
1235
1236
1237   if (menustate->device->exists())
1238   {
1239      /* name of bitbanger file */
1240      ui_menu_item_append(menu, menustate->device->image_config().devconfig().name(), menustate->device->filename(), flags, BITBANGERCMD_SELECT);
1241      ui_menu_item_append(menu, "Device Mode:", bitbanger_mode_string(&menustate->device->device()), mode_flags, BITBANGERCMD_MODE);
1242      ui_menu_item_append(menu, "Baud:", bitbanger_baud_string(&menustate->device->device()), baud_flags, BITBANGERCMD_BAUD);
1243      ui_menu_item_append(menu, "Baud Tune:", bitbanger_tune_string(&menustate->device->device()), tune_flags, BITBANGERCMD_TUNE);
1244      ui_menu_item_append(menu, "Protocol:", "8-1-N", 0, NULL);
1245   }
1246   else
1247   {
1248      /* no tape loaded */
1249      ui_menu_item_append(menu, "No Bitbanger Image loaded", NULL, flags, NULL);
1250   }
1251}
1252
1253
1254/*-------------------------------------------------
1255    menu_tape_control - main tape control menu
1256-------------------------------------------------*/
1257
1258void ui_mess_menu_tape_control(running_machine *machine, ui_menu *menu, void *parameter, void *state)
1259{
1260   tape_control_menu_state *menustate;
1261   const ui_menu_event *event;
1262
1263   /* if no state, allocate some */
1264   if (state == NULL)
1265      state = ui_menu_alloc_state(menu, sizeof(*menustate), NULL);
1266   menustate = (tape_control_menu_state *) state;
1267
1268   /* do we have to load the device? */
1269   if (menustate->device == NULL)
1270   {
1271      int index = menustate->index;
1272      device_image_interface *device = NULL;
1273      for (bool gotone = machine->m_devicelist.first(device); gotone; gotone = device->next(device))
1274      {
1275         if(device->device().type() == CASSETTE) {
1276            if (index==0) break;
1277            index--;
1278         }
1279      }
1280      menustate->device = device;
1281      ui_menu_reset(menu, (ui_menu_reset_options)0);
1282   }
1283
1284   /* rebuild the menu - we have to do this so that the counter updates */
1285   ui_menu_reset(menu, UI_MENU_RESET_REMEMBER_POSITION);
1286   menu_tape_control_populate(machine, menu, (tape_control_menu_state*)state);
1287
1288   /* process the menu */
1289   event = ui_menu_process(machine, menu, UI_MENU_PROCESS_LR_REPEAT);
1290   if (event != NULL)
1291   {
1292      switch(event->iptkey)
1293      {
1294         case IPT_UI_LEFT:
1295            if (event->itemref==TAPECMD_SLIDER)
1296               cassette_seek(&menustate->device->device(), -1, SEEK_CUR);
1297            else
1298            if (event->itemref==TAPECMD_SELECT)
1299            {
1300               /* left arrow - rotate left through cassette devices */
1301               if (menustate->index > 0)
1302                  menustate->index--;
1303               else
1304                  menustate->index = cassette_count(machine) - 1;
1305               menustate->device = NULL;
1306            }
1307            break;
1308
1309         case IPT_UI_RIGHT:
1310            if (event->itemref==TAPECMD_SLIDER)
1311               cassette_seek(&menustate->device->device(), +1, SEEK_CUR);
1312            else
1313            if (event->itemref==TAPECMD_SELECT)
1314            {
1315               /* right arrow - rotate right through cassette devices */
1316               if (menustate->index < cassette_count(machine) - 1)
1317                  menustate->index++;
1318               else
1319                  menustate->index = 0;
1320               menustate->device = NULL;
1321            }
1322            break;
1323
1324         case IPT_UI_SELECT:
1325            {
1326               if (event->itemref==TAPECMD_STOP)
1327                  cassette_change_state(&menustate->device->device(), CASSETTE_STOPPED, CASSETTE_MASK_UISTATE);
1328               else
1329               if (event->itemref==TAPECMD_PLAY)
1330                  cassette_change_state(&menustate->device->device(), CASSETTE_PLAY, CASSETTE_MASK_UISTATE);
1331               else
1332               if (event->itemref==TAPECMD_RECORD)
1333                  cassette_change_state(&menustate->device->device(), CASSETTE_RECORD, CASSETTE_MASK_UISTATE);
1334               else
1335               if (event->itemref==TAPECMD_REWIND)
1336                  cassette_seek(&menustate->device->device(), -30, SEEK_CUR);
1337               else
1338               if (event->itemref==TAPECMD_FAST_FORWARD)
1339                  cassette_seek(&menustate->device->device(), 30, SEEK_CUR);
1340               else
1341               if (event->itemref==TAPECMD_SLIDER)
1342                  cassette_seek(&menustate->device->device(), 0, SEEK_SET);
1343            }
1344            break;
1345      }
1346   }
1347}
1348
1349
1350/*-------------------------------------------------
1351    menu_bitbanger_control - main bitbanger
1352    control menu
1353-------------------------------------------------*/
1354
1355void ui_mess_menu_bitbanger_control(running_machine *machine, ui_menu *menu, void *parameter, void *state)
1356{
1357   bitbanger_control_menu_state *menustate;
1358   const ui_menu_event *event;
1359
1360   /* if no state, allocate some */
1361   if (state == NULL)
1362      state = ui_menu_alloc_state(menu, sizeof(*menustate), NULL);
1363   menustate = (bitbanger_control_menu_state *) state;
1364
1365   /* do we have to load the device? */
1366   if (menustate->device == NULL)
1367   {
1368      int index = menustate->index;
1369      device_image_interface *device = NULL;
1370      for (bool gotone = machine->m_devicelist.first(device); gotone; gotone = device->next(device))
1371      {
1372         if(device->device().type() == BITBANGER) {
1373            if (index==0) break;
1374            index--;
1375         }
1376      }
1377      menustate->device = device;
1378      ui_menu_reset(menu, (ui_menu_reset_options)0);
1379   }
1380
1381   /* rebuild the menu */
1382   ui_menu_reset(menu, UI_MENU_RESET_REMEMBER_POSITION);
1383   menu_bitbanger_control_populate(machine, menu, (bitbanger_control_menu_state*)state);
1384
1385   /* process the menu */
1386   event = ui_menu_process(machine, menu, UI_MENU_PROCESS_LR_REPEAT);
1387   if (event != NULL)
1388   {
1389      switch(event->iptkey)
1390      {
1391         case IPT_UI_LEFT:
1392            if (event->itemref==BITBANGERCMD_SELECT)
1393            {
1394               /* left arrow - rotate left through cassette devices */
1395               if (menustate->index > 0)
1396                  menustate->index--;
1397               else
1398                  menustate->index = bitbanger_count(machine) - 1;
1399               menustate->device = NULL;
1400            }
1401            else if (event->itemref==BITBANGERCMD_MODE)
1402            {
1403               bitbanger_dec_mode(&menustate->device->device(), FALSE);
1404            }
1405            else if (event->itemref==BITBANGERCMD_BAUD)
1406            {
1407               bitbanger_dec_baud(&menustate->device->device(), FALSE);
1408            }
1409            else if (event->itemref==BITBANGERCMD_TUNE)
1410            {
1411               bitbanger_dec_tune(&menustate->device->device(), FALSE);
1412            }
1413            break;
1414
1415         case IPT_UI_RIGHT:
1416            if (event->itemref==BITBANGERCMD_SELECT)
1417            {
1418               /* right arrow - rotate right through cassette devices */
1419               if (menustate->index < bitbanger_count(machine) - 1)
1420                  menustate->index++;
1421               else
1422                  menustate->index = 0;
1423               menustate->device = NULL;
1424            }
1425            else if (event->itemref==BITBANGERCMD_MODE)
1426            {
1427               bitbanger_inc_mode(&menustate->device->device(), FALSE);
1428            }
1429            else if (event->itemref==BITBANGERCMD_BAUD)
1430            {
1431               bitbanger_inc_baud(&menustate->device->device(), FALSE);
1432            }
1433            else if (event->itemref==BITBANGERCMD_TUNE)
1434            {
1435               bitbanger_inc_tune(&menustate->device->device(), FALSE);
1436            }
1437            break;
1438      }
1439   }
1440}
1441
src/emu/uiimage.h
r9927r9928
2424
2525void ui_image_menu_image_info(running_machine *machine, ui_menu *menu, void *parameter, void *state);
2626
27void ui_mess_menu_bitbanger_control(running_machine *machine, ui_menu *menu, void *parameter, void *state);
28
29void ui_mess_menu_tape_control(running_machine *machine, ui_menu *menu, void *parameter, void *state);
30
2731#endif   /* __UIIMAGE_H__ */
src/emu/imagedev/snapquik.h
r0r9928
1/*********************************************************************
2
3    snapquik.h
4
5    Snapshots and quickloads
6
7*********************************************************************/
8
9#ifndef __SNAPQUIK_H__
10#define __SNAPQUIK_H__
11
12#include "image.h"
13#include "ui.h"
14
15
16/***************************************************************************
17    CONSTANTS
18***************************************************************************/
19
20enum
21{
22   DEVINFO_FCT_SNAPSHOT_QUICKLOAD_LOAD = DEVINFO_FCT_DEVICE_SPECIFIC
23};
24
25
26
27/***************************************************************************
28    MACROS
29***************************************************************************/
30
31DECLARE_LEGACY_IMAGE_DEVICE(SNAPSHOT, snapshot);
32DECLARE_LEGACY_IMAGE_DEVICE(QUICKLOAD, quickload);
33DECLARE_LEGACY_IMAGE_DEVICE(Z80BIN, z80bin);
34
35#define SNAPSHOT_LOAD_NAME(name)   snapshot_load_##name
36#define SNAPSHOT_LOAD(name)         int SNAPSHOT_LOAD_NAME(name)(device_image_interface &image, const char *file_type, int snapshot_size)
37
38#define QUICKLOAD_LOAD_NAME(name)   quickload_load_##name
39#define QUICKLOAD_LOAD(name)      int QUICKLOAD_LOAD_NAME(name)(device_image_interface &image, const char *file_type, int quickload_size)
40
41#define Z80BIN_EXECUTE_NAME(name)   z80bin_execute_##name
42#define Z80BIN_EXECUTE(name)      void Z80BIN_EXECUTE_NAME(name)(running_machine *machine, UINT16 start_address, UINT16 end_address, UINT16 execute_address, int autorun)
43
44#define LOAD_REG(_cpu, _reg, _data) \
45        do { \
46          cpu_set_reg(_cpu, _reg, (_data)); \
47        } while (0)
48
49#define EXEC_NA "N/A"
50#define z80bin_execute_default      NULL
51
52/***************************************************************************
53    TYPE DEFINITIONS
54***************************************************************************/
55
56typedef int (*snapquick_load_func)(device_image_interface &image, const char *file_type, int file_size);
57
58typedef struct _snapquick_config snapquick_config;
59struct _snapquick_config
60{
61   snapquick_load_func   load;            /* loading function */
62   const char *      file_extensions;   /* file extensions */
63   seconds_t         delay_seconds;      /* loading delay (seconds) */
64   attoseconds_t      delay_attoseconds;   /* loading delay (attoseconds) */
65};
66
67typedef void (*z80bin_execute_func)(running_machine *machine, UINT16 start_address, UINT16 end_address, UINT16 execute_address, int autorun);
68
69typedef struct _z80bin_config z80bin_config;
70struct _z80bin_config
71{
72   snapquick_config base;
73   z80bin_execute_func execute;
74};
75
76/***************************************************************************
77    SNAPSHOT DEVICE CONFIGURATION MACROS
78***************************************************************************/
79
80#define MCFG_SNAPSHOT_ADD(_tag, _load, _file_extensions, _delay)   \
81   MCFG_DEVICE_ADD(_tag, SNAPSHOT, 0) \
82   MCFG_DEVICE_CONFIG_DATAPTR(snapquick_config, load, SNAPSHOT_LOAD_NAME(_load))   \
83   MCFG_DEVICE_CONFIG_DATAPTR(snapquick_config, file_extensions, _file_extensions) \
84   MCFG_DEVICE_CONFIG_DATA64(snapquick_config, delay_seconds, (seconds_t) (_delay)) \
85   MCFG_DEVICE_CONFIG_DATA64(snapquick_config, delay_attoseconds, (attoseconds_t) (((_delay) - (int)(_delay)) * ATTOSECONDS_PER_SECOND)) \
86
87/***************************************************************************
88    QUICKLOAD DEVICE CONFIGURATION MACROS
89***************************************************************************/
90
91#define MCFG_QUICKLOAD_ADD(_tag, _load, _file_extensions, _delay)   \
92   MCFG_DEVICE_ADD(_tag, QUICKLOAD, 0) \
93   MCFG_DEVICE_CONFIG_DATAPTR(snapquick_config, load, QUICKLOAD_LOAD_NAME(_load))   \
94   MCFG_DEVICE_CONFIG_DATAPTR(snapquick_config, file_extensions, _file_extensions) \
95   MCFG_DEVICE_CONFIG_DATA64(snapquick_config, delay_seconds, (seconds_t) (_delay)) \
96   MCFG_DEVICE_CONFIG_DATA64(snapquick_config, delay_attoseconds, (attoseconds_t) (((_delay) - (int)(_delay)) * ATTOSECONDS_PER_SECOND)) \
97
98/***************************************************************************
99    Z80BIN QUICKLOAD DEVICE CONFIGURATION MACROS
100***************************************************************************/
101
102#define MCFG_Z80BIN_QUICKLOAD_ADD(_tag, _execute, _delay) \
103   MCFG_DEVICE_ADD(_tag, Z80BIN, 0) \
104   MCFG_DEVICE_CONFIG_DATA64(snapquick_config, delay_seconds, (seconds_t) (_delay)) \
105   MCFG_DEVICE_CONFIG_DATA64(snapquick_config, delay_attoseconds, (attoseconds_t) (((_delay) - (int)(_delay)) * ATTOSECONDS_PER_SECOND)) \
106   MCFG_DEVICE_CONFIG_DATAPTR(z80bin_config, execute, Z80BIN_EXECUTE_NAME(_execute))
107   
108/***************************************************************************
109    FUNCTION PROTOTYPES
110***************************************************************************/
111
112void log_quickload(const char *type, UINT32 start, UINT32 length, UINT32 exec, const char *exec_format);
113
114
115#endif /* __SNAPQUIK_H__ */
src/emu/imagedev/multcart.h
r0r9928
1/*********************************************************************
2
3    multcart.h
4
5    Multi-cartridge handling code
6
7*********************************************************************/
8
9#ifndef __MULTCART_H__
10#define __MULTCART_H__
11
12#include "osdcore.h"
13
14
15/***************************************************************************
16    TYPE DEFINITIONS
17***************************************************************************/
18
19enum _multicart_load_flags
20{
21   MULTICART_FLAGS_DONT_LOAD_RESOURCES   = 0x00,
22   MULTICART_FLAGS_LOAD_RESOURCES      = 0x01
23};
24typedef enum _multicart_load_flags multicart_load_flags;
25
26enum _multicart_resource_type
27{
28   MULTICART_RESOURCE_TYPE_INVALID,
29   MULTICART_RESOURCE_TYPE_ROM,
30   MULTICART_RESOURCE_TYPE_RAM
31};
32typedef enum _multicart_resource_type multicart_resource_type;
33
34typedef struct _multicart_resource multicart_resource;
35struct _multicart_resource
36{
37   const char *            id;
38   const char *            filename;
39   multicart_resource *      next;
40   multicart_resource_type      type;
41   UINT32                  length;
42   void *                  ptr;
43};
44
45
46typedef struct _multicart_socket multicart_socket;
47struct _multicart_socket
48{
49   const char *            id;
50   multicart_socket *         next;
51   const multicart_resource *   resource;
52   void *                  ptr;
53};
54
55
56typedef struct _multicart_private multicart_private;
57
58typedef struct _multicart_t multicart_t;
59struct _multicart_t
60{
61   const multicart_resource *   resources;
62   const multicart_socket *   sockets;
63   const char *            pcb_type;
64   const char *            gamedrv_name; /* need this to find the path to the nvram files */
65   multicart_private *         data;
66};
67
68
69enum _multicart_open_error
70{
71   MCERR_NONE,
72   MCERR_NOT_MULTICART,
73   MCERR_CORRUPT,
74   MCERR_OUT_OF_MEMORY,
75   MCERR_XML_ERROR,
76   MCERR_INVALID_FILE_REF,
77   MCERR_ZIP_ERROR,
78   MCERR_MISSING_RAM_LENGTH,
79   MCERR_INVALID_RAM_SPEC,
80   MCERR_UNKNOWN_RESOURCE_TYPE,
81   MCERR_INVALID_RESOURCE_REF,
82   MCERR_INVALID_FILE_FORMAT,
83   MCERR_MISSING_LAYOUT,
84   MCERR_NO_PCB_OR_RESOURCES
85};
86typedef enum _multicart_open_error multicart_open_error;
87
88const char *multicart_error_text(multicart_open_error error);
89
90/***************************************************************************
91    PROTOTYPES
92***************************************************************************/
93
94/* opens a multicart */
95multicart_open_error multicart_open(const char *filename, const char *drvname, multicart_load_flags load_flags, multicart_t **cart);
96
97/* closes a multicart */
98void multicart_close(multicart_t *cart);
99
100#endif /* __MULTCART_H__ */
src/emu/imagedev/cartslot.h
r0r9928
1/***************************************************************************
2
3    Cartrige loading
4
5***************************************************************************/
6
7#ifndef __CARTSLOT_H__
8#define __CARTSLOT_H__
9
10#include "image.h"
11#include "multcart.h"
12
13
14/***************************************************************************
15    MACROS
16***************************************************************************/
17#define TAG_PCB      "pcb"
18
19#define ROM_CART_LOAD(tag,offset,length,flags)   \
20   { NULL, tag, offset, length, ROMENTRYTYPE_CARTRIDGE | (flags) },
21
22#define ROM_MIRROR      0x01000000
23#define ROM_NOMIRROR   0x00000000
24#define ROM_FULLSIZE   0x02000000
25#define ROM_FILL_FF      0x04000000
26#define ROM_NOCLEAR      0x08000000
27
28DECLARE_LEGACY_IMAGE_DEVICE(CARTSLOT, cartslot);
29
30
31
32/***************************************************************************
33    TYPE DEFINITIONS
34***************************************************************************/
35
36typedef struct _cartslot_t cartslot_t;
37struct _cartslot_t
38{
39   device_t *pcb_device;
40   multicart_t *mc;
41};
42
43
44typedef struct _cartslot_pcb_type cartslot_pcb_type;
45struct _cartslot_pcb_type
46{
47   const char *               name;
48   device_type                  devtype;
49};
50
51
52typedef struct _cartslot_config cartslot_config;
53struct _cartslot_config
54{
55   const char *               extensions;
56   const char *               interface;
57   int                        must_be_loaded;
58   device_start_func            device_start;
59   device_image_load_func         device_load;
60   device_image_unload_func      device_unload;
61   device_image_partialhash_func   device_partialhash;
62   cartslot_pcb_type            pcb_types[16];
63};
64
65
66/***************************************************************************
67    FUNCTION PROTOTYPES
68***************************************************************************/
69
70/* accesses the PCB associated with this cartslot */
71device_t *cartslot_get_pcb(device_t *device);
72
73/* accesses a particular socket */
74void *cartslot_get_socket(device_t *device, const char *socket_name);
75
76/* accesses a particular socket; gets the length of the associated resource */
77int cartslot_get_resource_length(device_t *device, const char *socket_name);
78
79
80/***************************************************************************
81    DEVICE CONFIGURATION MACROS
82***************************************************************************/
83
84#define MCFG_CARTSLOT_ADD(_tag)                               \
85   MCFG_DEVICE_ADD(_tag, CARTSLOT, 0)                           \
86
87#define MCFG_CARTSLOT_MODIFY(_tag)                              \
88   MCFG_DEVICE_MODIFY(_tag)                           \
89
90#define MCFG_CARTSLOT_EXTENSION_LIST(_extensions)                  \
91   MCFG_DEVICE_CONFIG_DATAPTR(cartslot_config, extensions, _extensions)
92
93#define MCFG_CARTSLOT_NOT_MANDATORY                              \
94   MCFG_DEVICE_CONFIG_DATA32(cartslot_config, must_be_loaded, FALSE)
95
96#define MCFG_CARTSLOT_MANDATORY                                 \
97   MCFG_DEVICE_CONFIG_DATA32(cartslot_config, must_be_loaded, TRUE)
98
99#define MCFG_CARTSLOT_START(_start)                              \
100   MCFG_DEVICE_CONFIG_DATAPTR(cartslot_config, device_start, DEVICE_START_NAME(_start))
101
102#define MCFG_CARTSLOT_LOAD(_load)                              \
103   MCFG_DEVICE_CONFIG_DATAPTR(cartslot_config, device_load, DEVICE_IMAGE_LOAD_NAME(_load))
104
105#define MCFG_CARTSLOT_UNLOAD(_unload)                           \
106   MCFG_DEVICE_CONFIG_DATAPTR(cartslot_config, device_unload, DEVICE_IMAGE_UNLOAD_NAME(_unload))
107
108#define MCFG_CARTSLOT_PARTIALHASH(_partialhash)                     \
109   MCFG_DEVICE_CONFIG_DATAPTR(cartslot_config, device_partialhash, _partialhash)
110
111#define MCFG_CARTSLOT_PCBTYPE(_index, _pcb_type_name, _pcb_devtype)         \
112   MCFG_DEVICE_CONFIG_DATAPTR_ARRAY_MEMBER(cartslot_config, pcb_types, _index, cartslot_pcb_type, name, _pcb_type_name) \
113   MCFG_DEVICE_CONFIG_DATAPTR_ARRAY_MEMBER(cartslot_config, pcb_types, _index, cartslot_pcb_type, devtype, _pcb_devtype)
114
115#define MCFG_CARTSLOT_INTERFACE(_interface)                     \
116   MCFG_DEVICE_CONFIG_DATAPTR(cartslot_config, interface, _interface )
117
118#define DECLARE_LEGACY_CART_SLOT_DEVICE(name, basename) _DECLARE_LEGACY_DEVICE(name, basename, basename##_device_config, basename##_device, legacy_cart_slot_device_config_base, legacy_cart_slot_device_base)
119#define DEFINE_LEGACY_CART_SLOT_DEVICE(name, basename) _DEFINE_LEGACY_DEVICE(name, basename, basename##_device_config, basename##_device, legacy_cart_slot_device_config_base, legacy_cart_slot_device_base)
120
121// ======================> device_config_cart_slot_interface
122
123// class representing interface-specific configuration cart_slot
124class device_config_cart_slot_interface : public device_config_interface
125{
126public:
127   // construction/destruction
128   device_config_cart_slot_interface(const machine_config &mconfig, device_config &device);
129   virtual ~device_config_cart_slot_interface();
130};
131
132
133
134// ======================> device_cart_slot_interface
135
136// class representing interface-specific live cart_slot
137class device_cart_slot_interface : public device_interface
138{
139public:
140   // construction/destruction
141   device_cart_slot_interface(running_machine &machine, const device_config &config, device_t &device);
142   virtual ~device_cart_slot_interface();
143
144   // configuration access
145   const device_config_cart_slot_interface &cart_slot_config() const { return m_cart_slot_config; }
146protected:
147
148   // configuration
149   const device_config_cart_slot_interface &m_cart_slot_config;   // reference to our device_config_execute_interface
150};
151// ======================> legacy_cart_slot_device_config
152
153// legacy_cart_slot_device_config is a device_config with a cart_slot interface
154class legacy_cart_slot_device_config_base :    public legacy_device_config_base,
155                                 public device_config_cart_slot_interface
156{
157protected:
158   // construction/destruction
159   legacy_cart_slot_device_config_base(const machine_config &mconfig, device_type type, const char *tag, const device_config *owner, UINT32 clock, device_get_config_func get_config);
160public:
161   INT64 get_config_int(UINT32 state) const { return get_legacy_config_int(state); }
162   genf *get_config_fct(UINT32 state) const { return get_legacy_config_fct(state); }
163   void *get_config_ptr(UINT32 state) const { return get_legacy_config_ptr(state); }
164};
165
166
167
168// ======================> legacy_cart_slot_device
169
170// legacy_cart_slot_device is a legacy_device_base with a cart_slot interface
171class legacy_cart_slot_device_base :   public legacy_device_base,
172                           public device_cart_slot_interface
173{
174protected:
175   // construction/destruction
176   legacy_cart_slot_device_base(running_machine &machine, const device_config &config);
177
178   // device_cart_slot_interface overrides
179};
180#endif /* __cart_slot_H__ */
src/emu/imagedev/wavfile.h
r0r9928
1/*********************************************************************
2
3    wavfile.h
4
5    Format code for wave (*.wav) files
6
7*********************************************************************/
8
9#ifndef WAVFILE_H
10#define WAVFILE_H
11
12#include "cassimg.h"
13
14extern const struct CassetteFormat wavfile_format;
15
16#endif /* WAVFILE_H */
src/emu/imagedev/flopimg.h
r0r9928
1/*********************************************************************
2
3    flopimg.h
4
5    Floppy disk image abstraction code
6
7*********************************************************************/
8
9#ifndef FLOPIMG_H
10#define FLOPIMG_H
11
12#include "emu.h"
13#include "opresolv.h"
14
15
16/***************************************************************************
17
18    Constants
19
20***************************************************************************/
21
22#define FLOPPY_FLAGS_READWRITE      0
23#define FLOPPY_FLAGS_READONLY      1
24
25
26
27/***************************************************************************
28
29    Type definitions
30
31***************************************************************************/
32
33typedef enum
34{
35   FLOPPY_ERROR_SUCCESS,         /* no error */
36   FLOPPY_ERROR_INTERNAL,         /* fatal internal error */
37   FLOPPY_ERROR_UNSUPPORTED,      /* this operation is unsupported */
38   FLOPPY_ERROR_OUTOFMEMORY,      /* ran out of memory */
39   FLOPPY_ERROR_SEEKERROR,         /* attempted to seek to nonexistant location */
40   FLOPPY_ERROR_INVALIDIMAGE,      /* this image in invalid */
41   FLOPPY_ERROR_READONLY,         /* attempt to write to read-only image */
42   FLOPPY_ERROR_NOSPACE,
43   FLOPPY_ERROR_PARAMOUTOFRANGE,
44   FLOPPY_ERROR_PARAMNOTSPECIFIED
45}
46floperr_t;
47
48typedef struct _floppy_image floppy_image;
49
50struct FloppyCallbacks
51{
52   floperr_t (*read_sector)(floppy_image *floppy, int head, int track, int sector, void *buffer, size_t buflen);
53   floperr_t (*write_sector)(floppy_image *floppy, int head, int track, int sector, const void *buffer, size_t buflen, int ddam);
54   floperr_t (*read_indexed_sector)(floppy_image *floppy, int head, int track, int sector_index, void *buffer, size_t buflen);
55   floperr_t (*write_indexed_sector)(floppy_image *floppy, int head, int track, int sector_index, const void *buffer, size_t buflen, int ddam);
56   floperr_t (*read_track)(floppy_image *floppy, int head, int track, UINT64 offset, void *buffer, size_t buflen);
57   floperr_t (*write_track)(floppy_image *floppy, int head, int track, UINT64 offset, const void *buffer, size_t buflen);
58   floperr_t (*format_track)(floppy_image *floppy, int head, int track, option_resolution *params);
59   floperr_t (*post_format)(floppy_image *floppy, option_resolution *params);
60   int (*get_heads_per_disk)(floppy_image *floppy);
61   int (*get_tracks_per_disk)(floppy_image *floppy);
62   int (*get_sectors_per_track)(floppy_image *floppy, int head, int track);
63   UINT32 (*get_track_size)(floppy_image *floppy, int head, int track);
64   floperr_t (*get_sector_length)(floppy_image *floppy, int head, int track, int sector, UINT32 *sector_length);
65   floperr_t (*get_indexed_sector_info)(floppy_image *floppy, int head, int track, int sector_index, int *cylinder, int *side, int *sector, UINT32 *sector_length, unsigned long *flags);
66   floperr_t (*get_track_data_offset)(floppy_image *floppy, int head, int track, UINT64 *offset);
67};
68
69
70
71struct FloppyFormat
72{
73   const char *name;
74   const char *extensions;
75   const char *description;
76   floperr_t (*identify)(floppy_image *floppy, const struct FloppyFormat *format, int *vote);
77   floperr_t (*construct)(floppy_image *floppy, const struct FloppyFormat *format, option_resolution *params);
78   const char *param_guidelines;
79};
80
81#define FLOPPY_IDENTIFY(name)   floperr_t name(floppy_image *floppy, const struct FloppyFormat *format, int *vote)
82#define FLOPPY_CONSTRUCT(name)   floperr_t name(floppy_image *floppy, const struct FloppyFormat *format, option_resolution *params)
83
84FLOPPY_IDENTIFY(td0_dsk_identify);
85FLOPPY_CONSTRUCT(td0_dsk_construct);
86
87FLOPPY_IDENTIFY(imd_dsk_identify);
88FLOPPY_CONSTRUCT(imd_dsk_construct);
89
90FLOPPY_IDENTIFY(cqm_dsk_identify);
91FLOPPY_CONSTRUCT(cqm_dsk_construct);
92
93FLOPPY_IDENTIFY(dsk_dsk_identify);
94FLOPPY_CONSTRUCT(dsk_dsk_construct);
95
96FLOPPY_IDENTIFY(d88_dsk_identify);
97FLOPPY_CONSTRUCT(d88_dsk_construct);
98
99FLOPPY_IDENTIFY(fdi_dsk_identify);
100FLOPPY_CONSTRUCT(fdi_dsk_construct);
101
102#define FLOPPY_OPTIONS_NAME(name)   floppyoptions_##name
103
104#define FLOPPY_OPTIONS_START(name)                                    \
105   const struct FloppyFormat floppyoptions_##name[] =                        \
106   {                                                         \
107
108#define FLOPPY_OPTIONS_END0 \
109      { NULL }                     \
110   };
111
112#define FLOPPY_OPTIONS_EXTERN(name)                                    \
113   extern const struct FloppyFormat floppyoptions_##name[]                     \
114
115#define FLOPPY_OPTION(name, extensions_, description_, identify_, construct_, ranges_)\
116   { #name, extensions_, description_, identify_, construct_, ranges_ },            \
117
118#define FLOPPY_OPTIONS_END                                          \
119      FLOPPY_OPTION( fdi, "fdi", "Formatted Disk Image", fdi_dsk_identify, fdi_dsk_construct, NULL) \
120      FLOPPY_OPTION( td0, "td0", "Teledisk floppy disk image",   td0_dsk_identify, td0_dsk_construct, NULL) \
121      FLOPPY_OPTION( imd, "imd", "IMD floppy disk image",   imd_dsk_identify, imd_dsk_construct, NULL) \
122      FLOPPY_OPTION( cqm, "cqm,dsk", "CopyQM floppy disk image",   cqm_dsk_identify, cqm_dsk_construct, NULL) \
123      FLOPPY_OPTION( dsk, "dsk", "DSK floppy disk image",   dsk_dsk_identify, dsk_dsk_construct, NULL) \
124      FLOPPY_OPTION( d88, "d77,d88,1dd", "D88 Floppy Disk image", d88_dsk_identify, d88_dsk_construct, NULL) \
125   FLOPPY_OPTIONS_END0
126
127FLOPPY_OPTIONS_EXTERN(default);
128
129#define PARAM_END            '\0'
130#define PARAM_HEADS            'H'
131#define PARAM_TRACKS         'T'
132#define PARAM_SECTORS         'S'
133#define PARAM_SECTOR_LENGTH      'L'
134#define PARAM_INTERLEAVE      'I'
135#define PARAM_FIRST_SECTOR_ID   'F'
136
137#define HEADS(range)         "H" #range
138#define TRACKS(range)         "T" #range
139#define SECTORS(range)         "S" #range
140#define SECTOR_LENGTH(range)   "L" #range
141#define INTERLEAVE(range)      "I" #range
142#define FIRST_SECTOR_ID(range)   "F" #range
143
144
145/***************************************************************************
146
147    Prototypes
148
149***************************************************************************/
150
151OPTION_GUIDE_EXTERN(floppy_option_guide);
152
153/* opening, closing and creating of floppy images */
154floperr_t floppy_open(void *fp, const struct io_procs *procs, const char *extension, const struct FloppyFormat *format, int flags, floppy_image **outfloppy);
155floperr_t floppy_open_choices(void *fp, const struct io_procs *procs, const char *extension, const struct FloppyFormat *formats, int flags, floppy_image **outfloppy);
156floperr_t floppy_create(void *fp, const struct io_procs *procs, const struct FloppyFormat *format, option_resolution *parameters, floppy_image **outfloppy);
157void floppy_close(floppy_image *floppy);
158
159/* useful for identifying a floppy image */
160floperr_t floppy_identify(void *fp, const struct io_procs *procs, const char *extension,
161   const struct FloppyFormat *formats, int *identified_format);
162
163/* functions useful within format constructors */
164void *floppy_tag(floppy_image *floppy);
165void *floppy_create_tag(floppy_image *floppy, size_t tagsize);
166struct FloppyCallbacks *floppy_callbacks(floppy_image *floppy);
167UINT8 floppy_get_filler(floppy_image *floppy);
168void floppy_set_filler(floppy_image *floppy, UINT8 filler);
169
170/* calls for accessing disk image data */
171floperr_t floppy_read_sector(floppy_image *floppy, int head, int track, int sector, int offset, void *buffer, size_t buffer_len);
172floperr_t floppy_write_sector(floppy_image *floppy, int head, int track, int sector, int offset, const void *buffer, size_t buffer_len, int ddam);
173floperr_t floppy_read_indexed_sector(floppy_image *floppy, int head, int track, int sector_index, int offset, void *buffer, size_t buffer_len);
174floperr_t floppy_write_indexed_sector(floppy_image *floppy, int head, int track, int sector_index, int offset, const void *buffer, size_t buffer_len, int ddam);
175floperr_t floppy_read_track(floppy_image *floppy, int head, int track, void *buffer, size_t buffer_len);
176floperr_t floppy_write_track(floppy_image *floppy, int head, int track, const void *buffer, size_t buffer_len);
177floperr_t floppy_read_track_data(floppy_image *floppy, int head, int track, void *buffer, size_t buffer_len);
178floperr_t floppy_write_track_data(floppy_image *floppy, int head, int track, const void *buffer, size_t buffer_len);
179floperr_t floppy_format_track(floppy_image *floppy, int head, int track, option_resolution *params);
180int floppy_get_tracks_per_disk(floppy_image *floppy);
181int floppy_get_heads_per_disk(floppy_image *floppy);
182UINT32 floppy_get_track_size(floppy_image *floppy, int head, int track);
183floperr_t floppy_get_sector_length(floppy_image *floppy, int head, int track, int sector, UINT32 *sector_length);
184floperr_t floppy_get_indexed_sector_info(floppy_image *floppy, int head, int track, int sector_index, int *cylinder, int *side, int *sector, UINT32 *sector_length, unsigned long *flags);
185floperr_t floppy_get_sector_count(floppy_image *floppy, int head, int track, int *sector_count);
186floperr_t floppy_load_track(floppy_image *floppy, int head, int track, int dirtify, void **track_data, size_t *track_length);
187int floppy_is_read_only(floppy_image *floppy);
188UINT8 floppy_random_byte(floppy_image *floppy);
189
190/* accessors for meta information about the image */
191const char *floppy_format_description(floppy_image *floppy);
192
193/* calls for accessing the raw disk image */
194void floppy_image_read(floppy_image *floppy, void *buffer, UINT64 offset, size_t length);
195void floppy_image_write(floppy_image *floppy, const void *buffer, UINT64 offset, size_t length);
196void floppy_image_write_filler(floppy_image *floppy, UINT8 filler, UINT64 offset, size_t length);
197UINT64 floppy_image_size(floppy_image *floppy);
198
199/* misc */
200const char *floppy_error(floperr_t err);
201
202
203#endif /* FLOPIMG_H */
204
src/emu/imagedev/harddriv.c
r0r9928
1/*********************************************************************
2
3    Code to interface the MESS image code with MAME's harddisk core.
4
5    We do not support diff files as it will involve some changes in
6    the MESS image code.  Additionally, the need for diff files comes
7    from MAME's need for "cannonical" hard drive images.
8
9    Raphael Nabet 2003
10
11    Update: 23-Feb-2004 - Unlike floppy disks, for which we support
12    myriad formats on many systems, it is my intention for MESS to
13    standardize on the CHD file format for hard drives so I made a few
14    changes to support this
15
16*********************************************************************/
17
18#include "emu.h"
19#include "harddisk.h"
20#include "harddriv.h"
21
22
23static const char *const error_strings[] =
24{
25   "no error",
26   "no drive interface",
27   "out of memory",
28   "invalid file",
29   "invalid parameter",
30   "invalid data",
31   "file not found",
32   "requires parent",
33   "file not writeable",
34   "read error",
35   "write error",
36   "codec error",
37   "invalid parent",
38   "hunk out of range",
39   "decompression error",
40   "compression error",
41   "can't create file",
42   "can't verify file"
43   "operation not supported",
44   "can't find metadata",
45   "invalid metadata size",
46   "unsupported CHD version"
47};
48
49static const char *chd_get_error_string(int chderr)
50{
51   if ((chderr < 0 ) || (chderr >= ARRAY_LENGTH(error_strings)))
52      return NULL;
53   return error_strings[chderr];
54}
55
56
57
58static OPTION_GUIDE_START(mess_hd_option_guide)
59   OPTION_INT('C', "cylinders",      "Cylinders")
60   OPTION_INT('H', "heads",         "Heads")
61   OPTION_INT('S', "sectors",         "Sectors")
62   OPTION_INT('L', "sectorlength",      "Sector Bytes")
63   OPTION_INT('K', "hunksize",         "Hunk Bytes")
64OPTION_GUIDE_END
65
66static const char *mess_hd_option_spec =
67   "C1-[512]-1024;H1/2/[4]/8;S1-[16]-64;L128/256/[512]/1024;K512/1024/2048/[4096]";
68
69
70typedef struct _dev_harddisk_t   dev_harddisk_t;
71struct _dev_harddisk_t
72{
73   const struct harddisk_callback_config   *config;
74   chd_file      *chd;
75   hard_disk_file   *hard_disk_handle;
76};
77
78
79INLINE dev_harddisk_t *get_safe_token(device_t *device)
80{
81   assert( device != NULL );
82   assert( ( device->type() == HARDDISK ) ||
83           ( device->type() == IDE_HARDDISK ) );
84   return (dev_harddisk_t *) downcast<legacy_device_base *>(device)->token();
85}
86
87
88/*************************************
89 *
90 *  DEVICE_IMAGE_LOAD(mess_hd)
91 *  DEVICE_IMAGE_CREATE(mess_hd)
92 *
93 *  Device load and create
94 *
95 *************************************/
96
97static int internal_load_mess_hd(device_image_interface &image, const char *metadata)
98{
99   dev_harddisk_t   *harddisk = get_safe_token( &image.device() );
100   chd_error      err = (chd_error)0;
101   int            is_writeable;
102
103   /* open the CHD file */
104   do
105   {
106      is_writeable = image.is_writable();
107      harddisk->chd = NULL;
108      err = chd_open_file(image.image_core_file(), is_writeable ? CHD_OPEN_READWRITE : CHD_OPEN_READ, NULL, &harddisk->chd);
109
110      /* special case; if we get CHDERR_FILE_NOT_WRITEABLE, make the
111         * image read only and repeat */
112      if (err == CHDERR_FILE_NOT_WRITEABLE)
113         image.make_readonly();
114   }
115   while(!harddisk->chd && is_writeable && (err == CHDERR_FILE_NOT_WRITEABLE));
116   if (!harddisk->chd)
117      goto done;
118
119   /* if we created the image and hence, have metadata to set, set the metadata */
120   if (metadata)
121   {
122      err = chd_set_metadata(harddisk->chd, HARD_DISK_METADATA_TAG, 0, metadata, strlen(metadata) + 1, 0);
123      if (err != CHDERR_NONE)
124         goto done;
125   }
126
127   /* open the hard disk file */
128   harddisk->hard_disk_handle = hard_disk_open(harddisk->chd);
129   if (!harddisk->hard_disk_handle)
130      goto done;
131
132done:
133   if (err)
134   {
135      /* if we had an error, close out the CHD */
136      if (harddisk->chd != NULL)
137      {
138         chd_close(harddisk->chd);
139         harddisk->chd = NULL;
140      }
141
142      image.seterror(IMAGE_ERROR_UNSPECIFIED, chd_get_error_string(err));
143   }
144   return err ? IMAGE_INIT_FAIL : IMAGE_INIT_PASS;
145}
146
147
148
149static DEVICE_IMAGE_LOAD( mess_hd )
150{
151   dev_harddisk_t   *harddisk = get_safe_token( image );
152   int our_result;
153
154   our_result = internal_load_mess_hd(image, NULL);
155
156   /* Check if there is an image_load callback defined */
157   if ( harddisk->config && harddisk->config->device_image_load )
158   {
159      /* Let the override do some additional work/checks */
160      our_result = harddisk->config->device_image_load( image );
161   }
162   return our_result;
163}
164
165
166static DEVICE_IMAGE_CREATE( mess_hd )
167{
168   int err;
169   char metadata[256];
170   UINT32 sectorsize, hunksize;
171   UINT32 cylinders, heads, sectors, totalsectors;
172
173   cylinders   = option_resolution_lookup_int(create_args, 'C');
174   heads      = option_resolution_lookup_int(create_args, 'H');
175   sectors      = option_resolution_lookup_int(create_args, 'S');
176   sectorsize   = option_resolution_lookup_int(create_args, 'L');
177   hunksize   = option_resolution_lookup_int(create_args, 'K');
178
179   totalsectors = cylinders * heads * sectors;
180
181   /* create the CHD file */
182   err = chd_create_file(image.image_core_file(), (UINT64)totalsectors * (UINT64)sectorsize, hunksize, CHDCOMPRESSION_NONE, NULL);
183   if (err != CHDERR_NONE)
184      goto error;
185
186   sprintf(metadata, HARD_DISK_METADATA_FORMAT, cylinders, heads, sectors, sectorsize);
187   return internal_load_mess_hd(image, metadata);
188
189error:
190   return IMAGE_INIT_FAIL;
191}
192
193
194
195/*************************************
196 *
197 *  DEVICE_IMAGE_UNLOAD(mess_hd)
198 *
199 *  Device unload
200 *
201 *************************************/
202
203static DEVICE_IMAGE_UNLOAD( mess_hd )
204{
205   dev_harddisk_t   *harddisk = get_safe_token( image );
206
207   /* Check if there is an image_unload callback defined */
208   if ( harddisk->config && harddisk->config->device_image_unload )
209   {
210      harddisk->config->device_image_unload( image );
211   }
212
213   if (harddisk->hard_disk_handle != NULL)
214   {
215      hard_disk_close(harddisk->hard_disk_handle);
216      harddisk->hard_disk_handle = NULL;
217   }
218
219   if (harddisk->chd != NULL)
220   {
221      chd_close(harddisk->chd);
222      harddisk->chd = NULL;
223   }
224}
225
226
227/*************************************
228 *
229 *  Get the MESS/MAME hard disk handle (from the src/harddisk.c core)
230 *  after an image has been opened with the mess_hd core
231 *
232 *************************************/
233
234hard_disk_file *mess_hd_get_hard_disk_file(device_t *device)
235{
236   dev_harddisk_t   *harddisk = get_safe_token( device );
237
238   return harddisk->hard_disk_handle;
239}
240
241
242/*************************************
243 *
244 *  Get the MESS/MAME CHD file (from the src/chd.c core)
245 *  after an image has been opened with the mess_hd core
246 *
247 *************************************/
248
249chd_file *mess_hd_get_chd_file(device_t *device)
250{
251   chd_file *result = NULL;
252   hard_disk_file *hd_file;
253
254   if (device)
255   {
256      hd_file = mess_hd_get_hard_disk_file(device);
257      if (hd_file)
258         result = hard_disk_get_chd(hd_file);
259   }
260   return result;
261}
262
263
264/*-------------------------------------------------
265    DEVICE_START(mess_hd)
266-------------------------------------------------*/
267
268static DEVICE_START(mess_hd)
269{
270   dev_harddisk_t   *harddisk = get_safe_token( device );
271
272   harddisk->config = (const harddisk_callback_config*)device->baseconfig().static_config();
273   harddisk->chd = NULL;
274   harddisk->hard_disk_handle = NULL;
275}
276
277
278/*-------------------------------------------------
279    DEVICE_GET_INFO(mess_hd)
280-------------------------------------------------*/
281
282DEVICE_GET_INFO(mess_hd)
283{
284   switch( state )
285   {
286      /* --- the following bits of info are returned as 64-bit signed integers --- */
287      case DEVINFO_INT_TOKEN_BYTES:            info->i = sizeof(dev_harddisk_t); break;
288      case DEVINFO_INT_INLINE_CONFIG_BYTES:      info->i = 0; break;
289      case DEVINFO_INT_IMAGE_TYPE:            info->i = IO_HARDDISK; break;
290      case DEVINFO_INT_IMAGE_READABLE:         info->i = 1; break;
291      case DEVINFO_INT_IMAGE_WRITEABLE:         info->i = 1; break;
292      case DEVINFO_INT_IMAGE_CREATABLE:         info->i = 0; break;
293      case DEVINFO_INT_IMAGE_CREATE_OPTCOUNT:      info->i = 1; break;
294
295      /* --- the following bits of info are returned as pointers to data or functions --- */
296      case DEVINFO_FCT_START:                  info->start = DEVICE_START_NAME(mess_hd); break;
297      case DEVINFO_FCT_IMAGE_LOAD:            info->f = (genf *) DEVICE_IMAGE_LOAD_NAME(mess_hd); break;
298      case DEVINFO_FCT_IMAGE_UNLOAD:            info->f = (genf *) DEVICE_IMAGE_UNLOAD_NAME(mess_hd); break;
299      case DEVINFO_FCT_IMAGE_CREATE:            info->f = (genf *) DEVICE_IMAGE_CREATE_NAME(mess_hd); break;
300      case DEVINFO_PTR_IMAGE_CREATE_OPTGUIDE:      info->p = (void *) mess_hd_option_guide; break;
301      case DEVINFO_PTR_IMAGE_CREATE_OPTSPEC+0:   info->p = (void *) mess_hd_option_spec; break;
302
303      /* --- the following bits of info are returned as NULL-terminated strings --- */
304      case DEVINFO_STR_NAME:                  strcpy(info->s, "Harddisk"); break;
305      case DEVINFO_STR_FAMILY:               strcpy(info->s, "Harddisk"); break;
306      case DEVINFO_STR_SOURCE_FILE:            strcpy(info->s, __FILE__); break;
307      case DEVINFO_STR_IMAGE_FILE_EXTENSIONS:      strcpy(info->s, "chd,hd"); break;
308      case DEVINFO_STR_IMAGE_CREATE_OPTNAME+0:   strcpy(info->s, "chd"); break;
309      case DEVINFO_STR_IMAGE_CREATE_OPTDESC+0:   strcpy(info->s, "MAME/MESS CHD Hard drive"); break;
310      case DEVINFO_STR_IMAGE_CREATE_OPTEXTS+0:   strcpy(info->s, "chd,hd"); break;
311   }
312}
313
314
315static DEVICE_START(mess_ide)
316{
317   /* old code from idedrive.c */
318#ifdef UNUSED_FUNCTION
319   int which_bus, which_address;
320   struct ide_interface *intf;
321   device_start_func parent_init;
322
323   /* get the basics */
324   ide_get_params(device, &which_bus, &which_address, &intf, &parent_init, NULL, NULL);
325
326   /* call the parent init function */
327   parent_init(device);
328
329   /* configure IDE */
330   /* FIXME IDE */
331   /* ide_controller_init_custom(which_bus, intf, NULL); */
332#endif
333}
334
335
336static DEVICE_IMAGE_LOAD(mess_ide)
337{
338   /* old code from idedrive.c */
339#ifdef UNUSED_FUNCTION
340   int result, which_bus, which_address;
341   struct ide_interface *intf;
342   device_image_load_func parent_load;
343
344   /* get the basics */
345   ide_get_params(image, &which_bus, &which_address, &intf, NULL, &parent_load, NULL);
346
347   /* call the parent load function */
348   result = parent_load(image);
349   if (result != IMAGE_INIT_PASS)
350      return result;
351
352   /* configure IDE */
353   /* FIXME IDE */
354   /* ide_controller_init_custom(which_bus, intf, mess_hd_get_chd_file(image)); */
355   /* ide_controller_reset(which_bus); */
356   return IMAGE_INIT_PASS;
357#endif
358   return device_load_mess_hd( image );
359}
360
361
362static DEVICE_IMAGE_UNLOAD(mess_ide)
363{
364   /* old code from idedrive.c */
365#ifdef UNUSED_FUNCTION
366   int which_bus, which_address;
367   struct ide_interface *intf;
368   device_image_unload_func parent_unload;
369
370   /* get the basics */
371   ide_get_params(image, &which_bus, &which_address, &intf, NULL, NULL, &parent_unload);
372
373   /* call the parent unload function */
374   parent_unload(image);
375
376   /* configure IDE */
377   /* FIXME IDE */
378   /* ide_controller_init_custom(which_bus, intf, NULL); */
379   /* ide_controller_reset(which_bus); */
380#endif
381   device_unload_mess_hd( image );
382}
383
384
385DEVICE_GET_INFO(mess_ide)
386{
387   switch( state )
388   {
389      /* --- the following bits of info are returned as pointers to data or functions --- */
390      case DEVINFO_FCT_START:                  info->start = DEVICE_START_NAME(mess_ide); break;
391      case DEVINFO_FCT_IMAGE_LOAD:            info->f = (genf *) DEVICE_IMAGE_LOAD_NAME(mess_ide); break;
392      case DEVINFO_FCT_IMAGE_UNLOAD:            info->f = (genf *) DEVICE_IMAGE_UNLOAD_NAME(mess_ide); break;
393
394      /* --- the following bits of info are returned as NULL-terminated strings --- */
395      case DEVINFO_STR_NAME:                  strcpy(info->s, "IDE harddisk"); break;
396      case DEVINFO_STR_IMAGE_INSTANCE_NAME:      strcpy(info->s, "ideharddrive"); break;
397      case DEVINFO_STR_IMAGE_BRIEF_INSTANCE_NAME:   strcpy(info->s, "idehd"); break;
398
399      default:                           DEVICE_GET_INFO_CALL( mess_hd ); break;
400   }
401}
402
403DEFINE_LEGACY_IMAGE_DEVICE(HARDDISK, mess_hd);
404DEFINE_LEGACY_IMAGE_DEVICE(IDE_HARDDISK, mess_ide);
src/emu/imagedev/chd_cd.c
r0r9928
1/*********************************************************************
2
3    Code to interface the MESS image code with MAME's CHD-CD core.
4
5    Based on harddriv.c by Raphael Nabet 2003
6
7*********************************************************************/
8
9#include "emu.h"
10#include "cdrom.h"
11#include "chd_cd.h"
12
13
14static const char *const error_strings[] =
15{
16   "no error",
17   "no drive interface",
18   "out of memory",
19   "invalid file",
20   "invalid parameter",
21   "invalid data",
22   "file not found",
23   "requires parent",
24   "file not writeable",
25   "read error",
26   "write error",
27   "codec error",
28   "invalid parent",
29   "hunk out of range",
30   "decompression error",
31   "compression error",
32   "can't create file",
33   "can't verify file"
34   "operation not supported",
35   "can't find metadata",
36   "invalid metadata size",
37   "unsupported CHD version"
38};
39
40INLINE const cdrom_config *get_config_dev(const device_config *device)
41{
42   assert(device != NULL);
43   assert(device->type() == CDROM);
44   return (const cdrom_config *)downcast<const legacy_device_config_base *>(device)->inline_config();
45}
46
47static const char *chd_get_error_string(int chderr)
48{
49   if ((chderr < 0 ) || (chderr >= ARRAY_LENGTH(error_strings)))
50      return NULL;
51   return error_strings[chderr];
52}
53
54
55static OPTION_GUIDE_START(mess_cd_option_guide)
56   OPTION_INT('K', "hunksize",         "Hunk Bytes")
57OPTION_GUIDE_END
58
59static const char mess_cd_option_spec[] =
60   "K512/1024/2048/[4096]";
61
62
63typedef struct _dev_cdrom_t   dev_cdrom_t;
64struct _dev_cdrom_t
65{
66   cdrom_file   *cdrom_handle;
67};
68
69
70INLINE dev_cdrom_t *get_safe_token(device_t *device) {
71   assert( device != NULL );
72   assert( ( device->type() == CDROM ) );
73   return (dev_cdrom_t *)  downcast<legacy_device_base *>(device)->token();
74}
75
76
77static DEVICE_IMAGE_LOAD(cdrom)
78{
79   dev_cdrom_t   *cdrom = get_safe_token(&image.device());
80   chd_error   err = (chd_error)0;
81   chd_file   *chd = NULL;
82
83   err = chd_open_file( image.image_core_file(), CHD_OPEN_READ, NULL, &chd );   /* CDs are never writeable */
84   if ( err )
85      goto error;
86
87   /* open the CHD file */
88   cdrom->cdrom_handle = cdrom_open( chd );
89   if ( ! cdrom->cdrom_handle )
90      goto error;
91
92   return IMAGE_INIT_PASS;
93
94error:
95   if ( chd )
96      chd_close( chd );
97   if ( err )
98      image.seterror( IMAGE_ERROR_UNSPECIFIED, chd_get_error_string( err ) );
99   return IMAGE_INIT_FAIL;
100}
101
102
103static DEVICE_IMAGE_UNLOAD(cdrom)
104{
105   dev_cdrom_t   *cdrom = get_safe_token( &image.device() );
106
107   assert( cdrom->cdrom_handle );
108   cdrom_close( cdrom->cdrom_handle );
109   cdrom->cdrom_handle = NULL;
110}
111
112
113/*************************************
114 *
115 *  Get the MESS/MAME cdrom handle (from the src/cdrom.c core)
116 *  after an image has been opened with the mess_cd core
117 *
118 *************************************/
119
120cdrom_file *mess_cd_get_cdrom_file(device_t *image)
121{
122   dev_cdrom_t   *cdrom = get_safe_token( image );
123
124   return cdrom->cdrom_handle;
125}
126
127
128/*-------------------------------------------------
129    DEVICE_START(cdrom)
130-------------------------------------------------*/
131
132static DEVICE_START(cdrom)
133{
134   dev_cdrom_t   *cdrom = get_safe_token( device );
135
136   cdrom->cdrom_handle = NULL;
137}
138
139/*-------------------------------------------------
140    DEVICE_IMAGE_SOFTLIST_LOAD(cdrom)
141-------------------------------------------------*/
142static DEVICE_IMAGE_SOFTLIST_LOAD(cdrom)
143{
144   return image.load_software(swlist, swname, start_entry);
145}
146
147/*-------------------------------------------------
148    DEVICE_GET_INFO(cdrom)
149-------------------------------------------------*/
150
151DEVICE_GET_INFO(cdrom)
152{
153   switch( state )
154   {
155      /* --- the following bits of info are returned as 64-bit signed integers --- */
156      case DEVINFO_INT_TOKEN_BYTES:            info->i = sizeof(dev_cdrom_t); break;
157      case DEVINFO_INT_INLINE_CONFIG_BYTES:      info->i = sizeof(cdrom_config); break;
158      case DEVINFO_INT_IMAGE_TYPE:            info->i = IO_CDROM; break;
159      case DEVINFO_INT_IMAGE_READABLE:         info->i = 1; break;
160      case DEVINFO_INT_IMAGE_WRITEABLE:         info->i = 0; break;
161      case DEVINFO_INT_IMAGE_CREATABLE:         info->i = 0; break;
162      case DEVINFO_INT_IMAGE_CREATE_OPTCOUNT:      info->i = 1; break;
163
164      /* --- the following bits of info are returned as pointers to data or functions --- */
165      case DEVINFO_FCT_START:                  info->start = DEVICE_START_NAME(cdrom); break;
166      case DEVINFO_FCT_IMAGE_LOAD:            info->f = (genf *) DEVICE_IMAGE_LOAD_NAME(cdrom); break;
167      case DEVINFO_FCT_IMAGE_UNLOAD:            info->f = (genf *) DEVICE_IMAGE_UNLOAD_NAME(cdrom); break;
168      case DEVINFO_FCT_IMAGE_SOFTLIST_LOAD:      info->f = (genf *) DEVICE_IMAGE_SOFTLIST_LOAD_NAME(cdrom);   break;
169      case DEVINFO_PTR_IMAGE_CREATE_OPTGUIDE:      info->p = (void *) mess_cd_option_guide; break;
170      case DEVINFO_PTR_IMAGE_CREATE_OPTSPEC+0:   info->p = (void *) mess_cd_option_spec; break;
171
172      /* --- the following bits of info are returned as NULL-terminated strings --- */
173      case DEVINFO_STR_NAME:                  strcpy(info->s, "Cdrom"); break;
174      case DEVINFO_STR_FAMILY:               strcpy(info->s, "Cdrom"); break;
175      case DEVINFO_STR_SOURCE_FILE:            strcpy(info->s, __FILE__); break;
176      case DEVINFO_STR_IMAGE_FILE_EXTENSIONS:      strcpy(info->s, "chd"); break;
177      case DEVINFO_STR_IMAGE_CREATE_OPTNAME+0:   strcpy(info->s, "chdcd"); break;
178      case DEVINFO_STR_IMAGE_CREATE_OPTDESC+0:   strcpy(info->s, "MAME/MESS CHD CD-ROM drive"); break;
179      case DEVINFO_STR_IMAGE_CREATE_OPTEXTS+0:   strcpy(info->s, "chd"); break;
180
181      case DEVINFO_STR_IMAGE_INTERFACE:
182         if ( device && downcast<const legacy_image_device_config_base *>(device)->inline_config() && get_config_dev(device)->interface )
183         {
184            strcpy(info->s, get_config_dev(device)->interface );
185         }
186         break;
187
188   }
189}
190
191DEFINE_LEGACY_IMAGE_DEVICE(CDROM, cdrom);
src/emu/imagedev/harddriv.h
r0r9928
1/*********************************************************************
2
3    harddriv.h
4
5    MESS interface to the MAME CHD code
6
7*********************************************************************/
8
9#ifndef MESS_HD_H
10#define MESS_HD_H
11
12#include "image.h"
13#include "harddisk.h"
14
15DECLARE_LEGACY_IMAGE_DEVICE(HARDDISK, mess_hd);
16DECLARE_LEGACY_IMAGE_DEVICE(IDE_HARDDISK, mess_ide);
17
18#define MCFG_HARDDISK_ADD(_tag) \
19   MCFG_DEVICE_ADD(_tag, HARDDISK, 0) \
20
21#define MCFG_IDE_HARDDISK_ADD(_tag) \
22   MCFG_DEVICE_ADD(_tag, IDE_HARDDISK, 0) \
23
24hard_disk_file *mess_hd_get_hard_disk_file(device_t *device);
25chd_file *mess_hd_get_chd_file(device_t *device);
26
27struct harddisk_callback_config
28{
29   device_image_load_func      device_image_load;
30   device_image_unload_func   device_image_unload;
31};
32
33
34#endif /* MESS_HD_H */
src/emu/imagedev/chd_cd.h
r0r9928
1/*********************************************************************
2
3    chd_cd.h
4
5    MESS interface to the MAME CHD CDROM code
6
7*********************************************************************/
8
9#ifndef MESS_CD_H
10#define MESS_CD_H
11
12#include "cdrom.h"
13
14/***************************************************************************
15    TYPE DEFINITIONS
16***************************************************************************/
17
18typedef struct cdrom_config_t   cdrom_config;
19struct cdrom_config_t
20{
21   const char *               interface;
22};
23
24/***************************************************************************
25    FUNCTION PROTOTYPES
26***************************************************************************/
27DECLARE_LEGACY_IMAGE_DEVICE(CDROM, cdrom);
28
29
30cdrom_file *mess_cd_get_cdrom_file(device_t *device);
31
32/***************************************************************************
33    DEVICE CONFIGURATION MACROS
34***************************************************************************/
35
36
37#define MCFG_CDROM_ADD(_tag) \
38   MCFG_DEVICE_ADD(_tag, CDROM, 0) \
39
40#define MCFG_CDROM_INTERFACE(_interface)                     \
41   MCFG_DEVICE_CONFIG_DATAPTR(cdrom_config, interface, _interface )
42
43#endif /* MESS_CD_H */
src/emu/imagedev/cassette.c
r0r9928
1/*********************************************************************
2
3    cassette.c
4
5    MESS interface to the cassette image abstraction code
6
7*********************************************************************/
8
9#include "emu.h"
10#include "imageutl.h"
11#include "cassette.h"
12#include "cassimg.h"
13#include "ui.h"
14
15
16#define CASSETTE_TAG      "cassette"
17#define ANIMATION_FPS      1
18#define ANIMATION_FRAMES   4
19
20#define VERBOSE            0
21#define LOG(x) do { if (VERBOSE) logerror x; } while (0)
22
23
24typedef struct _dev_cassette_t   dev_cassette_t;
25struct _dev_cassette_t
26{
27   const cassette_config   *config;
28   cassette_image   *cassette;
29   cassette_state   state;
30   double         position;
31   double         position_time;
32   INT32         value;
33};
34
35
36/* Default cassette_config for drivers only wav files */
37const cassette_config default_cassette_config =
38{
39   cassette_default_formats,
40   NULL,
41   CASSETTE_PLAY,
42   NULL
43};
44
45
46INLINE dev_cassette_t *get_safe_token(device_t *device)
47{
48   assert( device != NULL );
49   assert( device->type() == CASSETTE );
50   return (dev_cassette_t *) downcast<legacy_device_base *>(device)->token();
51}
52
53
54/*********************************************************************
55    cassette IO
56*********************************************************************/
57
58INLINE int cassette_is_motor_on(device_t *device)
59{
60   dev_cassette_t   *cassette = get_safe_token( device );
61
62   if ((cassette->state & CASSETTE_MASK_UISTATE) == CASSETTE_STOPPED)
63      return FALSE;
64   if ((cassette->state & CASSETTE_MASK_MOTOR) != CASSETTE_MOTOR_ENABLED)
65      return FALSE;
66   return TRUE;
67}
68
69
70
71static void cassette_update(device_t *device)
72{
73   dev_cassette_t   *cassette = get_safe_token( device );
74   double cur_time = attotime_to_double(timer_get_time(device->machine));
75
76   if (cassette_is_motor_on(device))
77   {
78      double new_position = cassette->position + (cur_time - cassette->position_time);
79
80      switch(cassette->state & CASSETTE_MASK_UISTATE) {
81      case CASSETTE_RECORD:
82         cassette_put_sample(cassette->cassette, 0, cassette->position, new_position - cassette->position, cassette->value);
83         break;
84
85      case CASSETTE_PLAY:
86         if ( cassette->cassette )
87         {
88            cassette_get_sample(cassette->cassette, 0, new_position, 0.0, &cassette->value);
89            /* See if reached end of tape */
90            double length = cassette_get_length(device);
91            if (new_position > length)
92            {
93               cassette->state = (cassette_state)(( cassette->state & ~CASSETTE_MASK_UISTATE ) | CASSETTE_STOPPED);
94               new_position = length;
95            }
96         }
97         break;
98      }
99      cassette->position = new_position;
100   }
101   cassette->position_time = cur_time;
102}
103
104
105
106cassette_state cassette_get_state(device_t *device)
107{
108   dev_cassette_t   *cassette = get_safe_token( device );
109   return cassette->state;
110}
111
112
113
114void cassette_change_state(device_t *device, cassette_state state, cassette_state mask)
115{
116   dev_cassette_t   *cassette = get_safe_token( device );
117   cassette_state new_state;
118
119   new_state = cassette->state;
120   new_state = (cassette_state)(new_state & ~mask);
121   new_state = (cassette_state)(new_state | (state & mask));
122
123   if (new_state != cassette->state)
124   {
125      cassette_update(device);
126      cassette->state = new_state;
127   }
128}
129
130
131
132void cassette_set_state(device_t *device, cassette_state state)
133{
134   cassette_change_state(device, state, (cassette_state)(~0));
135}
136
137
138
139double cassette_input(device_t *device)
140{
141   dev_cassette_t   *cassette = get_safe_token( device );
142   INT32 sample;
143   double double_value;
144
145   cassette_update(device);
146   sample = cassette->value;
147   double_value = sample / ((double) 0x7FFFFFFF);
148
149   LOG(("cassette_input(): time_index=%g value=%g\n", cassette->position, double_value));
150
151   return double_value;
152}
153
154
155
156void cassette_output(device_t *device, double value)
157{
158   dev_cassette_t   *cassette = get_safe_token( device );
159
160   if (((cassette->state & CASSETTE_MASK_UISTATE) == CASSETTE_RECORD) && (cassette->value != value))
161   {
162      cassette_update(device);
163
164      value = MIN(value, 1.0);
165      value = MAX(value, -1.0);
166
167      cassette->value = (INT32) (value * 0x7FFFFFFF);
168   }
169}
170
171
172
173cassette_image *cassette_get_image(device_t *device)
174{
175   dev_cassette_t   *cassette = get_safe_token( device );
176
177   return cassette->cassette;
178}
179
180
181
182double cassette_get_position(device_t *device)
183{
184   dev_cassette_t   *cassette = get_safe_token( device );
185   double position;
186
187   position = cassette->position;
188
189   if (cassette_is_motor_on(device))
190      position += attotime_to_double(timer_get_time(device->machine)) - cassette->position_time;
191   return position;
192}
193
194
195
196double cassette_get_length(device_t *device)
197{
198   dev_cassette_t   *cassette = get_safe_token( device );
199   struct CassetteInfo info;
200
201   cassette_get_info(cassette->cassette, &info);
202   return ((double) info.sample_count) / info.sample_frequency;
203}
204
205
206
207void cassette_seek(device_t *device, double time, int origin)
208{
209   dev_cassette_t   *cassette = get_safe_token( device );
210
211   double length;
212
213   cassette_update(device);
214
215   length = cassette_get_length(device);
216
217   switch(origin) {
218   case SEEK_SET:
219      break;
220
221   case SEEK_END:
222      time += length;
223      break;
224
225   case SEEK_CUR:
226      time += cassette_get_position(device);
227      break;
228   }
229
230   /* clip position into legal bounds */
231   if (time < 0)
232      time = 0;
233   else
234   if (time > length)
235      time = length;
236
237   cassette->position = time;
238}
239
240
241
242/*********************************************************************
243    cassette device init/load/unload/specify
244*********************************************************************/
245
246static DEVICE_START( cassette )
247{
248   dev_cassette_t   *cassette = get_safe_token( device );
249
250   /* set to default state */
251   cassette->config = (const cassette_config*)device->baseconfig().static_config();
252   cassette->cassette = NULL;
253   cassette->state = cassette->config->default_state;
254}
255
256
257
258static DEVICE_IMAGE_LOAD( cassette )
259{
260   device_t *device = &image.device();
261   dev_cassette_t   *cassette = get_safe_token( device );
262   casserr_t err;
263   int cassette_flags;
264   const struct CassetteFormat * const *formats;
265   const struct CassetteOptions *create_opts;
266   const char *extension;
267   int is_writable;
268
269   /* figure out the cassette format */
270   formats = cassette->config->formats;
271
272   if (image.has_been_created())
273   {
274      /* creating an image */
275      create_opts = cassette->config->create_opts;
276      err = cassette_create(device->machine, (void *) &image, &image_ioprocs, &wavfile_format, create_opts, CASSETTE_FLAG_READWRITE|CASSETTE_FLAG_SAVEONEXIT, &cassette->cassette);
277      if (err)
278         goto error;
279   }
280   else
281   {
282      /* opening an image */
283      do
284      {
285         is_writable = image.is_writable();
286         cassette_flags = is_writable ? (CASSETTE_FLAG_READWRITE|CASSETTE_FLAG_SAVEONEXIT) : CASSETTE_FLAG_READONLY;
287         extension = image.filetype();
288         err = cassette_open_choices(device->machine,(void *) &image, &image_ioprocs, extension, formats, cassette_flags, &cassette->cassette);
289
290         /* this is kind of a hack */
291         if (err && is_writable)
292            image.make_readonly();
293      }
294      while(err && is_writable);
295
296      if (err)
297         goto error;
298   }
299
300   /* set to default state, but only change the UI state */
301   cassette_change_state(device, cassette->config->default_state, CASSETTE_MASK_UISTATE);
302
303   /* reset the position */
304   cassette->position = 0.0;
305   cassette->position_time = attotime_to_double(timer_get_time(device->machine));
306
307   return IMAGE_INIT_PASS;
308
309error:
310   return IMAGE_INIT_FAIL;
311}
312
313
314
315static DEVICE_IMAGE_UNLOAD( cassette )
316{
317   device_t *device = &image.device();
318   dev_cassette_t   *cassette = get_safe_token( device );
319
320   /* if we are recording, write the value to the image */
321   if ((cassette->state & CASSETTE_MASK_UISTATE) == CASSETTE_RECORD)
322      cassette_update(device);
323
324   /* close out the cassette */
325   cassette_close(cassette->cassette);
326   cassette->cassette = NULL;
327
328   /* set to default state, but only change the UI state */
329   cassette_change_state(device, CASSETTE_STOPPED, CASSETTE_MASK_UISTATE);
330}
331
332
333
334/*
335    display a small tape icon, with the current position in the tape image
336*/
337static DEVICE_IMAGE_DISPLAY(cassette)
338{
339   device_t *device = &image.device();
340   char buf[65];
341   float x, y;
342   int n;
343   double position, length;
344   cassette_state uistate;
345   device_t *dev;
346   static const UINT8 shapes[8] = { 0x2d, 0x5c, 0x7c, 0x2f, 0x2d, 0x20, 0x20, 0x20 };
347
348   /* abort if we should not be showing the image */
349   if (!image.exists())
350      return;
351   if (!cassette_is_motor_on(device))
352      return;
353
354   /* figure out where we are in the cassette */
355   position = cassette_get_position(device);
356   length = cassette_get_length(device);
357   uistate = (cassette_state)(cassette_get_state(device) & CASSETTE_MASK_UISTATE);
358
359   /* choose a location on the screen */
360   x = 0.2f;
361   y = 0.5f;
362
363   dev = device->machine->m_devicelist.first(CASSETTE );
364
365   while ( dev && strcmp( dev->tag(), device->tag() ) )
366   {
367      y += 1;
368      dev = dev->typenext();
369   }
370
371   y *= ui_get_line_height(*device->machine) + 2.0f * UI_BOX_TB_BORDER;
372   /* choose which frame of the animation we are at */
373   n = ((int) position / ANIMATION_FPS) % ANIMATION_FRAMES;
374   /* Since you can have anything in a BDF file, we will use crude ascii characters instead */
375   snprintf(buf, ARRAY_LENGTH(buf), "%c%c %c %02d:%02d (%04d) [%02d:%02d (%04d)]",
376#if 0
377   /* THE ANIMATION HASN'T WORKED SINCE 0.114 - LEFT HERE FOR REFERENCE */
378   /* NEVER SEEN THE PLAY / RECORD ICONS */
379   /* character pairs 2-3, 4-5, 6-7, 8-9 form little tape cassette images */
380      n * 2 + 2,                        /* cassette icon left */
381      n * 2 + 3,                        /* cassette icon right */
382      (uistate == CASSETTE_PLAY) ? 16 : 14,   /* play or record icon */
383#else
384      shapes[n],               /* cassette icon left */
385      shapes[n|4],               /* cassette icon right */
386      (uistate == CASSETTE_PLAY) ? 0x50 : 0x52,   /* play (P) or record (R) */
387#endif
388      ((int) position / 60),
389      ((int) position % 60),
390      (int) position,
391      ((int) length / 60),
392      ((int) length % 60),
393      (int) length);
394
395   /* draw the cassette */
396   ui_draw_text_box(&device->machine->render().ui_container(), buf, JUSTIFY_LEFT, x, y, UI_BACKGROUND_COLOR);
397}
398
399/*-------------------------------------------------
400    DEVICE_IMAGE_SOFTLIST_LOAD(cassette)
401-------------------------------------------------*/
402static DEVICE_IMAGE_SOFTLIST_LOAD(cassette)
403{
404   return image.load_software(swlist, swname, start_entry);
405}
406
407DEVICE_GET_INFO(cassette)
408{
409   switch( state )
410   {
411      /* --- the following bits of info are returned as 64-bit signed integers --- */
412      case DEVINFO_INT_TOKEN_BYTES:            info->i = sizeof(dev_cassette_t); break;
413      case DEVINFO_INT_INLINE_CONFIG_BYTES:      info->i = 0; break;
414      case DEVINFO_INT_IMAGE_TYPE:            info->i = IO_CASSETTE; break;
415      case DEVINFO_INT_IMAGE_READABLE:         info->i = 1; break;
416      case DEVINFO_INT_IMAGE_WRITEABLE:         info->i = 1; break;
417      case DEVINFO_INT_IMAGE_CREATABLE:         info->i = 1; break;
418
419      /* --- the following bits of info are returned as pointers to data or functions --- */
420      case DEVINFO_FCT_START:                  info->start = DEVICE_START_NAME(cassette); break;
421      case DEVINFO_FCT_IMAGE_LOAD:            info->f = (genf *) DEVICE_IMAGE_LOAD_NAME(cassette); break;
422      case DEVINFO_FCT_IMAGE_UNLOAD:            info->f = (genf *) DEVICE_IMAGE_UNLOAD_NAME(cassette); break;
423      case DEVINFO_FCT_IMAGE_DISPLAY:            info->f = (genf *) DEVICE_IMAGE_DISPLAY_NAME(cassette); break;
424      case DEVINFO_FCT_IMAGE_SOFTLIST_LOAD:      info->f = (genf *) DEVICE_IMAGE_SOFTLIST_LOAD_NAME(cassette);   break;
425
426      /* --- the following bits of info are returned as NULL-terminated strings --- */
427      case DEVINFO_STR_NAME:                  strcpy(info->s, "Cassette"); break;
428      case DEVINFO_STR_FAMILY:               strcpy(info->s, "Cassette"); break;
429      case DEVINFO_STR_SOURCE_FILE:            strcpy(info->s, __FILE__); break;
430      case DEVINFO_STR_IMAGE_FILE_EXTENSIONS:
431         if ( device && device->static_config() )
432         {
433            const struct CassetteFormat * const *formats = ((cassette_config *)device->static_config())->formats;
434            int      i;
435
436            /* set up a temporary string */
437            info->s[0] = '\0';
438
439            for ( i = 0; formats[i]; i++ )
440               image_specify_extension( info->s, 256, formats[i]->extensions );
441         }
442         break;
443      case DEVINFO_STR_IMAGE_INTERFACE:
444         if ( device && device->static_config() && ((cassette_config *)device->static_config())->interface)
445         {
446            strcpy(info->s, ((cassette_config *)device->static_config())->interface );
447         }
448         break;
449   }
450}
451
452DEFINE_LEGACY_IMAGE_DEVICE(CASSETTE, cassette);
src/emu/imagedev/flopdrv.c
r0r9928
1/*
2    This code handles the floppy drives.
3    All FDD actions should be performed using these functions.
4
5    The functions are emulated and a disk image is used.
6
7  Real disk operation:
8  - set unit id
9
10  TODO:
11    - Override write protect if disk image has been opened in read mode
12*/
13
14#include "emu.h"
15#include "imageutl.h"
16#include "flopdrv.h"
17
18#define VERBOSE      0
19#define LOG(x) do { if (VERBOSE) logerror x; } while (0)
20
21/***************************************************************************
22    CONSTANTS
23***************************************************************************/
24
25#define FLOPDRVTAG   "flopdrv"
26#define LOG_FLOPPY      0
27
28/***************************************************************************
29    TYPE DEFINITIONS
30***************************************************************************/
31
32typedef struct _floppy_drive floppy_drive;
33struct _floppy_drive
34{
35   /* callbacks */
36   devcb_resolved_write_line out_idx_func;
37   devcb_resolved_read_line in_mon_func;
38   devcb_resolved_write_line out_tk00_func;
39   devcb_resolved_write_line out_wpt_func;
40   devcb_resolved_write_line out_rdy_func;
41   devcb_resolved_write_line out_dskchg_func;
42
43   /* state of input lines */
44   int drtn; /* direction */
45   int stp;  /* step */
46   int wtg;  /* write gate */
47   int mon;  /* motor on */
48
49   /* state of output lines */
50   int idx;  /* index pulse */
51   int tk00; /* track 00 */
52   int wpt;  /* write protect */
53   int rdy;  /* ready */
54   int dskchg;      /* disk changed */
55
56   /* drive select logic */
57   int drive_id;
58   int active;
59
60   const floppy_config   *config;
61
62   /* flags */
63   int flags;
64   /* maximum track allowed */
65   int max_track;
66   /* num sides */
67   int num_sides;
68   /* current track - this may or may not relate to the present cylinder number
69    stored by the fdc */
70   int current_track;
71
72   /* index pulse timer */
73   void   *index_timer;
74   /* index pulse callback */
75   void   (*index_pulse_callback)(device_t *controller,device_t *image, int state);
76   /* rotation per minute => gives index pulse frequency */
77   float rpm;
78
79   void   (*ready_state_change_callback)(device_t *controller,device_t *img, int state);
80
81   int id_index;
82
83   device_t *controller;
84
85   floppy_image *floppy;
86   int track;
87   void (*load_proc)(device_image_interface &image);
88   void (*unload_proc)(device_image_interface &image);
89   void *custom_data;
90   int floppy_drive_type;
91};
92
93
94typedef struct _floppy_error_map floppy_error_map;
95struct _floppy_error_map
96{
97   floperr_t ferr;
98   image_error_t ierr;
99   const char *message;
100};
101
102
103
104/***************************************************************************
105    GLOBAL VARIABLES
106***************************************************************************/
107
108static const floppy_error_map errmap[] =
109{
110   { FLOPPY_ERROR_SUCCESS,         IMAGE_ERROR_SUCCESS },
111   { FLOPPY_ERROR_INTERNAL,      IMAGE_ERROR_INTERNAL },
112   { FLOPPY_ERROR_UNSUPPORTED,      IMAGE_ERROR_UNSUPPORTED },
113   { FLOPPY_ERROR_OUTOFMEMORY,      IMAGE_ERROR_OUTOFMEMORY },
114   { FLOPPY_ERROR_INVALIDIMAGE,   IMAGE_ERROR_INVALIDIMAGE }
115};
116
117/***************************************************************************
118    IMPLEMENTATION
119***************************************************************************/
120DECLARE_LEGACY_IMAGE_DEVICE(FLOPPY_APPLE, apple525);
121DECLARE_LEGACY_IMAGE_DEVICE(FLOPPY_SONY, sonydriv);
122
123INLINE floppy_drive *get_safe_token(device_t *device)
124{
125   assert( device != NULL );
126   assert( device->type() == FLOPPY || device->type() == FLOPPY_APPLE || device->type() == FLOPPY_SONY);
127   return (floppy_drive *) downcast<legacy_device_base *>(device)->token();
128}
129
130floppy_image *flopimg_get_image(device_t *image)
131{
132   return get_safe_token(image)->floppy;
133}
134
135void *flopimg_get_custom_data(device_t *image)
136{
137   floppy_drive *flopimg = get_safe_token( image );
138   return flopimg->custom_data;
139}
140
141void flopimg_alloc_custom_data(device_t *image,void *custom)
142{
143   floppy_drive *flopimg = get_safe_token( image );
144   flopimg->custom_data = custom;
145}
146
147static int flopimg_get_sectors_per_track(device_t *image, int side)
148{
149   floperr_t err;
150   int sector_count;
151   floppy_drive *flopimg = get_safe_token( image );
152
153   if (!flopimg || !flopimg->floppy)
154      return 0;
155
156   err = floppy_get_sector_count(flopimg->floppy, side, flopimg->track, &sector_count);
157   if (err)
158      return 0;
159   return sector_count;
160}
161
162static void flopimg_get_id_callback(device_t *image, chrn_id *id, int id_index, int side)
163{
164   floppy_drive *flopimg;
165   int cylinder, sector, N;
166   unsigned long flags;
167   UINT32 sector_length;
168
169   flopimg = get_safe_token( image );
170   if (!flopimg || !flopimg->floppy)
171      return;
172
173   floppy_get_indexed_sector_info(flopimg->floppy, side, flopimg->track, id_index, &cylinder, &side, &sector, &sector_length, &flags);
174
175   N = compute_log2(sector_length);
176
177   id->C = cylinder;
178   id->H = side;
179   id->R = sector;
180   id->data_id = id_index;
181   id->flags = flags;
182   id->N = ((N >= 7) && (N <= 10)) ? N - 7 : 0;
183}
184
185static void log_readwrite(const char *name, int head, int track, int sector, const char *buf, int length)
186{
187   char membuf[1024];
188   int i;
189   for (i = 0; i < length; i++)
190      sprintf(membuf + i*2, "%02x", (int) (UINT8) buf[i]);
191   logerror("%s:  head=%i track=%i sector=%i buffer='%s'\n", name, head, track, sector, membuf);
192}
193
194static void floppy_drive_set_geometry_absolute(device_t *img, int tracks, int sides)
195{
196   floppy_drive *pDrive = get_safe_token( img );
197   pDrive->max_track = tracks;
198   pDrive->num_sides = sides;
199}
200
201void floppy_drive_set_geometry(device_t *img, floppy_type_t type)
202{
203   floppy_drive_set_geometry_absolute(img, type.max_track_number, type.head_number);
204}
205
206static TIMER_CALLBACK(floppy_drive_index_callback);
207
208/* this is called on device init */
209static void floppy_drive_init(device_t *img)
210{
211   floppy_drive *pDrive = get_safe_token( img );
212
213   /* initialise flags */
214   pDrive->flags = 0;
215   pDrive->index_pulse_callback = NULL;
216   pDrive->ready_state_change_callback = NULL;
217   pDrive->index_timer = timer_alloc(img->machine, floppy_drive_index_callback, (void *) img);
218   pDrive->idx = 0;
219
220   floppy_drive_set_geometry(img, ((floppy_config*)img->baseconfig().static_config())->floppy_type);
221
222   /* initialise id index - not so important */
223   pDrive->id_index = 0;
224   /* initialise track */
225   pDrive->current_track = 0;
226
227   /* default RPM */
228   pDrive->rpm = 300;
229
230   pDrive->controller = NULL;
231
232   pDrive->custom_data = NULL;
233
234   pDrive->floppy_drive_type = FLOPPY_TYPE_REGULAR;
235}
236
237/* index pulses at rpm/60 Hz, and stays high 1/20th of time */
238static void floppy_drive_index_func(device_t *img)
239{
240   floppy_drive *drive = get_safe_token( img );
241
242   double ms = 1000.0 / (drive->rpm / 60.0);
243
244   if (drive->idx)
245   {
246      drive->idx = 0;
247      timer_adjust_oneshot((emu_timer*)drive->index_timer, double_to_attotime(ms*19/20/1000.0), 0);
248   }
249   else
250   {
251      drive->idx = 1;
252      timer_adjust_oneshot((emu_timer*)drive->index_timer, double_to_attotime(ms/20/1000.0), 0);
253   }
254
255   devcb_call_write_line(&drive->out_idx_func, drive->idx);
256
257   if (drive->index_pulse_callback)
258      drive->index_pulse_callback(drive->controller, img, drive->idx);
259}
260
261static TIMER_CALLBACK(floppy_drive_index_callback)
262{
263   device_t *image = (device_t *) ptr;
264   floppy_drive_index_func(image);
265}
266
267/*************************************************************************/
268/* IO_FLOPPY device functions */
269
270/* set flag state */
271void floppy_drive_set_flag_state(device_t *img, int flag, int state)
272{
273   floppy_drive *drv = get_safe_token( img );
274   int prev_state;
275   int new_state;
276
277   /* get old state */
278   prev_state = drv->flags & flag;
279
280   /* set new state */
281   drv->flags &= ~flag;
282   if (state)
283      drv->flags |= flag;
284
285   /* get new state */
286   new_state = drv->flags & flag;
287
288   /* changed state? */
289   if (prev_state ^ new_state)
290   {
291      if (flag & FLOPPY_DRIVE_READY)
292      {
293         /* trigger state change callback */
294         devcb_call_write_line(&drv->out_rdy_func, new_state ? ASSERT_LINE : CLEAR_LINE);
295
296         if (drv->ready_state_change_callback)
297            drv->ready_state_change_callback(drv->controller, img, new_state);
298      }
299   }
300}
301
302/* for pc, drive is always ready, for amstrad,pcw,spectrum it is only ready under
303a fixed set of circumstances */
304/* use this to set ready state of drive */
305void floppy_drive_set_ready_state(device_t *img, int state, int flag)
306{
307   floppy_drive *drive = get_safe_token(img);
308   device_image_interface *image = dynamic_cast<device_image_interface *>(img);
309   if (flag)
310   {
311      /* set ready only if drive is present, disk is in the drive,
312        and disk motor is on - for Amstrad, Spectrum and PCW*/
313
314      /* drive present? */
315      /* disk inserted? */
316      if (image->exists())
317      {
318         if (drive->mon == CLEAR_LINE)
319         {
320            /* set state */
321            floppy_drive_set_flag_state(img, FLOPPY_DRIVE_READY, state);
322            return;
323         }
324      }
325      floppy_drive_set_flag_state(img, FLOPPY_DRIVE_READY, 0);
326   }
327   else
328   {
329      /* force ready state - for PC driver */
330      floppy_drive_set_flag_state(img, FLOPPY_DRIVE_READY, state);
331   }
332}
333
334/* get flag state */
335int   floppy_drive_get_flag_state(device_t *img, int flag)
336{
337   floppy_drive *drv = get_safe_token( img );
338   int drive_flags;
339   int flags;
340
341   flags = 0;
342
343   drive_flags = drv->flags;
344
345   /* these flags are independant of a real drive/disk image */
346    flags |= drive_flags & (FLOPPY_DRIVE_READY | FLOPPY_DRIVE_INDEX);
347
348    flags &= flag;
349
350   return flags;
351}
352
353
354void floppy_drive_seek(device_t *img, signed int signed_tracks)
355{
356   device_image_interface *image = dynamic_cast<device_image_interface *>(img);
357   floppy_drive *pDrive;
358
359   pDrive = get_safe_token( img );
360
361   LOG(("seek from: %d delta: %d\n",pDrive->current_track, signed_tracks));
362
363   /* update position */
364   pDrive->current_track+=signed_tracks;
365
366   if (pDrive->current_track<0)
367   {
368      pDrive->current_track = 0;
369   }
370   else
371   if (pDrive->current_track>=pDrive->max_track)
372   {
373      pDrive->current_track = pDrive->max_track-1;
374   }
375
376   /* set track 0 flag */
377   pDrive->tk00 = (pDrive->current_track == 0) ? CLEAR_LINE : ASSERT_LINE;
378   devcb_call_write_line(&pDrive->out_tk00_func, pDrive->tk00);
379
380   /* clear disk changed flag */
381   pDrive->dskchg = ASSERT_LINE;
382   //devcb_call_write_line(&flopimg->out_dskchg_func, flopimg->dskchg);
383
384   /* inform disk image of step operation so it can cache information */
385   if (image->exists())
386      pDrive->track = pDrive->current_track;
387
388   pDrive->id_index = 0;
389}
390
391
392/* this is not accurate. But it will do for now */
393int   floppy_drive_get_next_id(device_t *img, int side, chrn_id *id)
394{
395   floppy_drive *pDrive;
396   int spt;
397
398   pDrive = get_safe_token( img );
399
400   /* get sectors per track */
401   spt = flopimg_get_sectors_per_track(img, side);
402
403   /* set index */
404   if ((pDrive->id_index==(spt-1)) || (spt==0))
405   {
406      floppy_drive_set_flag_state(img, FLOPPY_DRIVE_INDEX, 1);
407   }
408   else
409   {
410      floppy_drive_set_flag_state(img, FLOPPY_DRIVE_INDEX, 0);
411   }
412
413   /* get id */
414   if (spt!=0)
415   {
416      flopimg_get_id_callback(img, id, pDrive->id_index, side);
417   }
418
419   pDrive->id_index++;
420   if (spt!=0)
421      pDrive->id_index %= spt;
422   else
423      pDrive->id_index = 0;
424
425   return (spt == 0) ? 0 : 1;
426}
427
428void floppy_drive_read_track_data_info_buffer(device_t *img, int side, void *ptr, int *length )
429{
430   floppy_drive *flopimg;
431   device_image_interface *image = dynamic_cast<device_image_interface *>(img);
432
433   if (image->exists())
434   {
435      flopimg = get_safe_token( img );
436      if (!flopimg || !flopimg->floppy)
437         return;
438
439      floppy_read_track_data(flopimg->floppy, side, flopimg->track, ptr, *length);
440   }
441}
442
443void floppy_drive_write_track_data_info_buffer(device_t *img, int side, const void *ptr, int *length )
444{
445   floppy_drive *flopimg;
446   device_image_interface *image = dynamic_cast<device_image_interface *>(img);
447
448   if (image->exists())
449   {
450      flopimg = get_safe_token( img );
451      if (!flopimg || !flopimg->floppy)
452         return;
453
454      floppy_write_track_data(flopimg->floppy, side, flopimg->track, ptr, *length);
455   }
456}
457
458void floppy_drive_format_sector(device_t *img, int side, int sector_index,int c,int h, int r, int n, int filler)
459{
460   device_image_interface *image = dynamic_cast<device_image_interface *>(img);
461
462   if (image->exists())
463   {
464/*      if (drv->interface_.format_sector)
465            drv->interface_.format_sector(img, side, sector_index,c, h, r, n, filler);*/
466   }
467}
468
469void floppy_drive_read_sector_data(device_t *img, int side, int index1, void *ptr, int length)
470{
471   floppy_drive *flopimg;
472   device_image_interface *image = dynamic_cast<device_image_interface *>(img);
473
474   if (image->exists())
475   {
476      flopimg = get_safe_token( img );
477      if (!flopimg || !flopimg->floppy)
478         return;
479
480      floppy_read_indexed_sector(flopimg->floppy, side, flopimg->track, index1, 0, ptr, length);
481
482      if (LOG_FLOPPY)
483         log_readwrite("sector_read", side, flopimg->track, index1, (const char *)ptr, length);
484
485   }
486}
487
488void floppy_drive_write_sector_data(device_t *img, int side, int index1, const void *ptr,int length, int ddam)
489{
490   floppy_drive *flopimg;
491   device_image_interface *image = dynamic_cast<device_image_interface *>(img);
492
493   if (image->exists())
494   {
495      flopimg = get_safe_token( img );
496      if (!flopimg || !flopimg->floppy)
497         return;
498
499      if (LOG_FLOPPY)
500         log_readwrite("sector_write", side, flopimg->track, index1, (const char *)ptr, length);
501
502      floppy_write_indexed_sector(flopimg->floppy, side, flopimg->track, index1, 0, ptr, length, ddam);
503   }
504}
505
506void floppy_install_load_proc(device_t *image, void (*proc)(device_image_interface &image))
507{
508   floppy_drive *flopimg = get_safe_token( image );
509   flopimg->load_proc = proc;
510}
511
512void floppy_install_unload_proc(device_t *image, void (*proc)(device_image_interface &image))
513{
514   floppy_drive *flopimg = get_safe_token( image );
515   flopimg->unload_proc = proc;
516}
517
518/* set the callback for the index pulse */
519void floppy_drive_set_index_pulse_callback(device_t *img, void (*callback)(device_t *controller,device_t *image, int state))
520{
521   floppy_drive *pDrive = get_safe_token( img );
522   pDrive->index_pulse_callback = callback;
523}
524
525
526void floppy_drive_set_ready_state_change_callback(device_t *img, void (*callback)(device_t *controller,device_t *img, int state))
527{
528   floppy_drive *pDrive = get_safe_token( img );
529   pDrive->ready_state_change_callback = callback;
530}
531
532int   floppy_drive_get_current_track(device_t *img)
533{
534   floppy_drive *drv = get_safe_token( img );
535   return drv->current_track;
536}
537
538UINT64 floppy_drive_get_current_track_size(device_t *img, int head)
539{
540   floppy_drive *drv = get_safe_token( img );
541   int size = 0;
542   device_image_interface *image = dynamic_cast<device_image_interface *>(img);
543
544   if (image->exists())
545   {
546      size = floppy_get_track_size(drv->floppy, head, drv->current_track);
547   }
548
549   return size;
550}
551
552void floppy_drive_set_rpm(device_t *img, float rpm)
553{
554   floppy_drive *drv = get_safe_token( img );
555   drv->rpm = rpm;
556}
557
558void floppy_drive_set_controller(device_t *img, device_t *controller)
559{
560   floppy_drive *drv = get_safe_token( img );
561   drv->controller = controller;
562}
563
564/* ----------------------------------------------------------------------- */
565DEVICE_START( floppy )
566{
567   floppy_drive *floppy = get_safe_token( device );
568   floppy->config = (const floppy_config*)device->baseconfig().static_config();
569   floppy_drive_init(device);
570
571   floppy->drive_id = floppy_get_drive(device);
572   floppy->active = FALSE;
573
574   /* resolve callbacks */
575   devcb_resolve_write_line(&floppy->out_idx_func, &floppy->config->out_idx_func, device);
576   devcb_resolve_read_line(&floppy->in_mon_func, &floppy->config->in_mon_func, device);
577   devcb_resolve_write_line(&floppy->out_tk00_func, &floppy->config->out_tk00_func, device);
578   devcb_resolve_write_line(&floppy->out_wpt_func, &floppy->config->out_wpt_func, device);
579   devcb_resolve_write_line(&floppy->out_rdy_func, &floppy->config->out_rdy_func, device);
580//  devcb_resolve_write_line(&floppy->out_dskchg_func, &floppy->config->out_dskchg_func, device);
581
582   /* by default we are not write-protected */
583   floppy->wpt = ASSERT_LINE;
584   devcb_call_write_line(&floppy->out_wpt_func, floppy->wpt);
585
586   /* not at track 0 */
587   floppy->tk00 = ASSERT_LINE;
588   devcb_call_write_line(&floppy->out_tk00_func, floppy->tk00);
589
590   /* motor off */
591   floppy->mon = ASSERT_LINE;
592
593   /* disk changed */
594   floppy->dskchg = CLEAR_LINE;
595//  devcb_call_write_line(&floppy->out_dskchg_func, floppy->dskchg);
596}
597
598static int internal_floppy_device_load(device_image_interface *image, int create_format, option_resolution *create_args)
599{
600   floperr_t err;
601   floppy_drive *flopimg;
602   const struct FloppyFormat *floppy_options;
603   int floppy_flags, i;
604   const char *extension;
605
606   /* look up instance data */
607   flopimg = get_safe_token( &image->device() );
608
609   /* figure out the floppy options */
610   floppy_options = ((floppy_config*)image->device().baseconfig().static_config())->formats;
611
612   if (image->has_been_created())
613   {
614      /* creating an image */
615      assert(create_format >= 0);
616      err = floppy_create((void *) image, &image_ioprocs, &floppy_options[create_format], create_args, &flopimg->floppy);
617      if (err)
618         goto error;
619   }
620   else
621   {
622      /* opening an image */
623      floppy_flags = image->is_writable() ? FLOPPY_FLAGS_READWRITE : FLOPPY_FLAGS_READONLY;
624      extension = image->filetype();
625      err = floppy_open_choices((void *) image, &image_ioprocs, extension, floppy_options, floppy_flags, &flopimg->floppy);
626      if (err)
627         goto error;
628   }
629   if (floppy_callbacks(flopimg->floppy)->get_heads_per_disk && floppy_callbacks(flopimg->floppy)->get_tracks_per_disk)
630   {
631      floppy_drive_set_geometry_absolute(&image->device(),
632         floppy_get_tracks_per_disk(flopimg->floppy),
633         floppy_get_heads_per_disk(flopimg->floppy));
634   }
635   return IMAGE_INIT_PASS;
636
637error:
638   for (i = 0; i < ARRAY_LENGTH(errmap); i++)
639   {
640      if (err == errmap[i].ferr)
641         image->seterror(errmap[i].ierr, errmap[i].message);
642   }
643   return IMAGE_INIT_FAIL;
644}
645
646static TIMER_CALLBACK( set_wpt )
647{
648   floppy_drive *flopimg = (floppy_drive *)ptr;
649
650   flopimg->wpt = param;
651   devcb_call_write_line(&flopimg->out_wpt_func, param);
652}
653
654DEVICE_IMAGE_LOAD( floppy )
655{
656   floppy_drive *flopimg;
657   int retVal = internal_floppy_device_load(&image, -1, NULL);
658   flopimg = get_safe_token( &image.device() );
659   if (retVal==IMAGE_INIT_PASS) {
660      /* if we have one of our hacky unload procs, call it */
661      if (flopimg->load_proc)
662         flopimg->load_proc(image);
663   }
664
665   /* push disk halfway into drive */
666   flopimg->wpt = CLEAR_LINE;
667   devcb_call_write_line(&flopimg->out_wpt_func, flopimg->wpt);
668
669   /* set timer for disk load */
670   int next_wpt;
671
672   if (image.is_writable())
673      next_wpt = ASSERT_LINE;
674   else
675      next_wpt = CLEAR_LINE;
676
677   timer_set(image.device().machine, ATTOTIME_IN_MSEC(250), flopimg, next_wpt, set_wpt);
678
679   return retVal;
680}
681
682DEVICE_IMAGE_CREATE( floppy )
683{
684   return internal_floppy_device_load(&image, create_format, create_args);
685}
686
687DEVICE_IMAGE_UNLOAD( floppy )
688{
689   floppy_drive *flopimg = get_safe_token( &image.device() );
690   if (flopimg->unload_proc)
691      flopimg->unload_proc(image);
692
693   floppy_close(flopimg->floppy);
694   flopimg->floppy = NULL;
695
696   /* disk changed */
697   flopimg->dskchg = CLEAR_LINE;
698   //devcb_call_write_line(&flopimg->out_dskchg_func, flopimg->dskchg);
699
700   /* pull disk halfway out of drive */
701   flopimg->wpt = CLEAR_LINE;
702   devcb_call_write_line(&flopimg->out_wpt_func, flopimg->wpt);
703
704   /* set timer for disk eject */
705   timer_set(image.device().machine, ATTOTIME_IN_MSEC(250), flopimg, ASSERT_LINE, set_wpt);
706}
707
708device_t *floppy_get_device(running_machine *machine,int drive)
709{
710   switch(drive) {
711      case 0 : return machine->device(FLOPPY_0);
712      case 1 : return machine->device(FLOPPY_1);
713      case 2 : return machine->device(FLOPPY_2);
714      case 3 : return machine->device(FLOPPY_3);
715   }
716   return NULL;
717}
718
719int floppy_get_drive_type(device_t *image)
720{
721   floppy_drive *flopimg = get_safe_token( image );
722   return flopimg->floppy_drive_type;
723}
724
725void floppy_set_type(device_t *image,int ftype)
726{
727   floppy_drive *flopimg = get_safe_token( image );
728   flopimg->floppy_drive_type = ftype;
729}
730
731device_t *floppy_get_device_by_type(running_machine *machine,int ftype,int drive)
732{
733   int i;
734   int cnt = 0;
735   for (i=0;i<4;i++) {
736      device_t *disk = floppy_get_device(machine,i);
737      if (floppy_get_drive_type(disk)==ftype) {
738         if (cnt==drive) {
739            return disk;
740         }
741         cnt++;
742      }
743   }
744   return NULL;
745}
746
747int floppy_get_drive(device_t *image)
748{
749   int drive =0;
750   if (strcmp(image->tag(), FLOPPY_0) == 0) drive = 0;
751   if (strcmp(image->tag(), FLOPPY_1) == 0) drive = 1;
752   if (strcmp(image->tag(), FLOPPY_2) == 0) drive = 2;
753   if (strcmp(image->tag(), FLOPPY_3) == 0) drive = 3;
754   return drive;
755}
756
757int floppy_get_drive_by_type(device_t *image,int ftype)
758{
759   int i,drive =0;
760   for (i=0;i<4;i++) {
761      device_t *disk = floppy_get_device(image->machine,i);
762      if (floppy_get_drive_type(disk)==ftype) {
763         if (image==disk) {
764            return drive;
765         }
766         drive++;
767      }
768   }
769   return drive;
770}
771
772int floppy_get_count(running_machine *machine)
773{
774   int cnt = 0;
775   if (machine->device(FLOPPY_0)) cnt++;
776    if (machine->device(FLOPPY_1)) cnt++;
777    if (machine->device(FLOPPY_2)) cnt++;
778    if (machine->device(FLOPPY_3)) cnt++;
779   return cnt;
780}
781
782
783/* drive select 0 */
784WRITE_LINE_DEVICE_HANDLER( floppy_ds0_w )
785{
786   floppy_drive *drive = get_safe_token(device);
787
788   if (state == CLEAR_LINE)
789      drive->active = (drive->drive_id == 0);
790}
791
792/* drive select 1 */
793WRITE_LINE_DEVICE_HANDLER( floppy_ds1_w )
794{
795   floppy_drive *drive = get_safe_token(device);
796
797   if (state == CLEAR_LINE)
798      drive->active = (drive->drive_id == 1);
799}
800
801/* drive select 2 */
802WRITE_LINE_DEVICE_HANDLER( floppy_ds2_w )
803{
804   floppy_drive *drive = get_safe_token(device);
805
806   if (state == CLEAR_LINE)
807      drive->active = (drive->drive_id == 2);
808}
809
810/* drive select 3 */
811WRITE_LINE_DEVICE_HANDLER( floppy_ds3_w )
812{
813   floppy_drive *drive = get_safe_token(device);
814
815   if (state == CLEAR_LINE)
816      drive->active = (drive->drive_id == 3);
817}
818
819/* shortcut to write all four ds lines */
820WRITE8_DEVICE_HANDLER( floppy_ds_w )
821{
822   floppy_ds0_w(device, BIT(data, 0));
823   floppy_ds1_w(device, BIT(data, 1));
824   floppy_ds2_w(device, BIT(data, 2));
825   floppy_ds3_w(device, BIT(data, 3));
826}
827
828/* motor on, active low */
829WRITE_LINE_DEVICE_HANDLER( floppy_mon_w )
830{
831   floppy_drive *drive = get_safe_token(device);
832   device_image_interface *image = dynamic_cast<device_image_interface *>(device);
833   /* force off if there is no attached image */
834   if (!image->exists())
835      state = ASSERT_LINE;
836
837   /* off -> on */
838   if (drive->mon && state == CLEAR_LINE)
839   {
840      drive->idx = 0;
841      floppy_drive_index_func(device);
842   }
843
844   /* on -> off */
845   else if (drive->mon == CLEAR_LINE && state)
846      timer_adjust_oneshot((emu_timer*)drive->index_timer, attotime_zero, 0);
847
848   drive->mon = state;
849}
850
851/* direction */
852WRITE_LINE_DEVICE_HANDLER( floppy_drtn_w )
853{
854   floppy_drive *drive = get_safe_token(device);
855   drive->drtn = state;
856}
857
858/* write data */
859WRITE_LINE_DEVICE_HANDLER( floppy_wtd_w )
860{
861
862}
863
864/* step */
865WRITE_LINE_DEVICE_HANDLER( floppy_stp_w )
866{
867   floppy_drive *drive = get_safe_token(device);
868
869   /* move head one track when going from high to low and write gate is high */
870   if (drive->active && drive->stp && state == CLEAR_LINE && drive->wtg)
871   {
872      /* move head according to the direction line */
873      if (drive->drtn)
874      {
875         /* move head outward */
876         if (drive->current_track > 0)
877            drive->current_track--;
878
879         /* are we at track 0 now? */
880         drive->tk00 = (drive->current_track == 0) ? CLEAR_LINE : ASSERT_LINE;
881      }
882      else
883      {
884         /* move head inward */
885         if (drive->current_track < drive->max_track)
886            drive->current_track++;
887
888         /* we can't be at track 0 here, so reset the line */
889         drive->tk00 = ASSERT_LINE;
890      }
891
892      /* update track 0 line with new status */
893      devcb_call_write_line(&drive->out_tk00_func, drive->tk00);
894   }
895
896   drive->stp = state;
897}
898
899/* write gate */
900WRITE_LINE_DEVICE_HANDLER( floppy_wtg_w )
901{
902   floppy_drive *drive = get_safe_token(device);
903   drive->wtg = state;
904}
905
906/* write protect signal, active low */
907READ_LINE_DEVICE_HANDLER( floppy_wpt_r )
908{
909   floppy_drive *drive = get_safe_token(device);
910   return drive->wpt;
911}
912
913/* track 0 detect */
914READ_LINE_DEVICE_HANDLER( floppy_tk00_r )
915{
916   floppy_drive *drive = get_safe_token(device);
917   return drive->tk00;
918}
919
920/* disk changed */
921READ_LINE_DEVICE_HANDLER( floppy_dskchg_r )
922{
923   floppy_drive *drive = get_safe_token(device);
924   return drive->dskchg;
925}
926
927/* 2-sided disk */
928READ_LINE_DEVICE_HANDLER( floppy_twosid_r )
929{
930   floppy_drive *drive = get_safe_token(device);
931
932   if (drive->floppy == NULL)
933      return ASSERT_LINE;
934   else
935      return !floppy_get_heads_per_disk(drive->floppy);
936}
937
938/*-------------------------------------------------
939    DEVICE_IMAGE_SOFTLIST_LOAD(floppy)
940-------------------------------------------------*/
941static DEVICE_IMAGE_SOFTLIST_LOAD(floppy)
942{
943   return image.load_software(swlist, swname, start_entry);
944}
945
946/*************************************
947 *
948 *  Device specification function
949 *
950 *************************************/
951/*-------------------------------------------------
952    safe_strcpy - hack
953-------------------------------------------------*/
954
955static void safe_strcpy(char *dst, const char *src)
956{
957   strcpy(dst, src ? src : "");
958}
959
960DEVICE_GET_INFO(floppy)
961{
962   switch( state )
963   {
964      /* --- the following bits of info are returned as 64-bit signed integers --- */
965      case DEVINFO_INT_TOKEN_BYTES:            info->i = sizeof(floppy_drive); break;
966      case DEVINFO_INT_INLINE_CONFIG_BYTES:      info->i = 0; break;
967      case DEVINFO_INT_IMAGE_TYPE:            info->i = IO_FLOPPY; break;
968      case DEVINFO_INT_IMAGE_READABLE:         info->i = 1; break;
969      case DEVINFO_INT_IMAGE_WRITEABLE:         info->i = 1; break;
970      case DEVINFO_INT_IMAGE_CREATABLE:
971                                 {
972                                    int cnt = 0;
973                                    if ( device && device->static_config() )
974                                    {
975                                       const struct FloppyFormat *floppy_options = ((floppy_config*)device->static_config())->formats;
976                                       int   i;
977                                       for ( i = 0; floppy_options[i].construct; i++ ) {
978                                          if(floppy_options[i].param_guidelines) cnt++;
979                                       }
980                                    }
981                                    info->i = (cnt>0) ? 1 : 0;
982                                 }
983                                 break;
984      /* --- the following bits of info are returned as pointers to data or functions --- */
985      case DEVINFO_FCT_START:                  info->start = DEVICE_START_NAME(floppy); break;
986      case DEVINFO_FCT_IMAGE_CREATE:            info->f = (genf *) DEVICE_IMAGE_CREATE_NAME(floppy); break;
987      case DEVINFO_FCT_IMAGE_LOAD:            info->f = (genf *) DEVICE_IMAGE_LOAD_NAME(floppy); break;
988      case DEVINFO_FCT_IMAGE_UNLOAD:            info->f = (genf *) DEVICE_IMAGE_UNLOAD_NAME(floppy); break;
989      case DEVINFO_FCT_IMAGE_SOFTLIST_LOAD:      info->f = (genf *) DEVICE_IMAGE_SOFTLIST_LOAD_NAME(floppy);   break;
990      case DEVINFO_PTR_IMAGE_CREATE_OPTGUIDE:      info->p = (void *)floppy_option_guide; break;
991      case DEVINFO_INT_IMAGE_CREATE_OPTCOUNT:
992      {
993         const struct FloppyFormat *floppy_options = ((floppy_config*)device->static_config())->formats;
994         int count;
995         for (count = 0; floppy_options[count].construct; count++)
996            ;
997         info->i = count;
998         break;
999      }
1000
1001      /* --- the following bits of info are returned as NULL-terminated strings --- */
1002      case DEVINFO_STR_NAME:                  strcpy(info->s, "Floppy Disk"); break;
1003      case DEVINFO_STR_FAMILY:               strcpy(info->s, "Floppy Disk"); break;
1004      case DEVINFO_STR_SOURCE_FILE:            strcpy(info->s, __FILE__); break;
1005      case DEVINFO_STR_IMAGE_FILE_EXTENSIONS:
1006         if ( device && device->static_config() )
1007         {
1008            const struct FloppyFormat *floppy_options = ((floppy_config*)device->static_config())->formats;
1009            int      i;
1010            /* set up a temporary string */
1011            info->s[0] = '\0';
1012            for ( i = 0; floppy_options[i].construct; i++ )
1013               image_specify_extension( info->s, 256, floppy_options[i].extensions );
1014         }
1015         break;
1016      case DEVINFO_STR_IMAGE_INTERFACE:
1017         if ( device && device->static_config() && ((floppy_config *)device->static_config())->interface)
1018         {
1019            strcpy(info->s, ((floppy_config *)device->static_config())->interface );
1020         }
1021         break;
1022      default:
1023         {
1024            if ( device && device->static_config() )
1025            {
1026               const struct FloppyFormat *floppy_options = ((floppy_config*)device->static_config())->formats;
1027               if ((state >= DEVINFO_PTR_IMAGE_CREATE_OPTSPEC) && (state < DEVINFO_PTR_IMAGE_CREATE_OPTSPEC + DEVINFO_IMAGE_CREATE_OPTMAX)) {
1028                  info->p = (void *) floppy_options[state - DEVINFO_PTR_IMAGE_CREATE_OPTSPEC].param_guidelines;
1029               } else if ((state >= DEVINFO_STR_IMAGE_CREATE_OPTNAME) && (state < DEVINFO_STR_IMAGE_CREATE_OPTNAME + DEVINFO_IMAGE_CREATE_OPTMAX)) {
1030                  safe_strcpy(info->s,floppy_options[state - DEVINFO_STR_IMAGE_CREATE_OPTNAME].name);
1031               }
1032               else if ((state >= DEVINFO_STR_IMAGE_CREATE_OPTDESC) && (state < DEVINFO_STR_IMAGE_CREATE_OPTDESC + DEVINFO_IMAGE_CREATE_OPTMAX)) {
1033                  safe_strcpy(info->s,floppy_options[state - DEVINFO_STR_IMAGE_CREATE_OPTDESC].description);
1034               }
1035               else if ((state >= DEVINFO_STR_IMAGE_CREATE_OPTEXTS) && (state < DEVINFO_STR_IMAGE_CREATE_OPTEXTS + DEVINFO_IMAGE_CREATE_OPTMAX)) {
1036                  safe_strcpy(info->s,floppy_options[state - DEVINFO_STR_IMAGE_CREATE_OPTEXTS].extensions);
1037               }
1038            }
1039         }
1040
1041         break;
1042   }
1043}
1044
1045DEFINE_LEGACY_IMAGE_DEVICE(FLOPPY, floppy);
src/emu/imagedev/cassette.h
r0r9928
1/*********************************************************************
2
3    cassette.h
4
5    MESS interface to the cassette image abstraction code
6
7*********************************************************************/
8
9#ifndef CASSETTE_H
10#define CASSETTE_H
11
12#include "image.h"
13#include "cassimg.h"
14
15
16enum _cassette_state
17{
18   /* this part of the state is controlled by the UI */
19   CASSETTE_STOPPED         = 0,
20   CASSETTE_PLAY            = 1,
21   CASSETTE_RECORD            = 2,
22
23   /* this part of the state is controlled by drivers */
24   CASSETTE_MOTOR_ENABLED      = 0,
25   CASSETTE_MOTOR_DISABLED      = 4,
26   CASSETTE_SPEAKER_ENABLED   = 0,
27   CASSETTE_SPEAKER_MUTED      = 8,
28
29   /* masks */
30   CASSETTE_MASK_UISTATE      = 3,
31   CASSETTE_MASK_MOTOR         = 4,
32   CASSETTE_MASK_SPEAKER      = 8,
33   CASSETTE_MASK_DRVSTATE      = 12
34};
35
36typedef enum _cassette_state cassette_state;
37
38
39/***************************************************************************
40    TYPE DEFINITIONS
41***************************************************************************/
42
43typedef struct cassette_config_t   cassette_config;
44struct cassette_config_t
45{
46   const struct CassetteFormat*   const *formats;
47   const struct CassetteOptions   *create_opts;
48   const cassette_state         default_state;
49   const char *               interface;
50};
51
52
53/***************************************************************************
54    FUNCTION PROTOTYPES
55***************************************************************************/
56
57cassette_state cassette_get_state(device_t *cassette);
58void cassette_set_state(device_t *cassette, cassette_state state);
59void cassette_change_state(device_t *cassette, cassette_state state, cassette_state mask);
60
61double cassette_input(device_t *cassette);
62void cassette_output(device_t *cassette, double value);
63
64cassette_image *cassette_get_image(device_t *cassette);
65double cassette_get_position(device_t *cassette);
66double cassette_get_length(device_t *cassette);
67void cassette_seek(device_t *cassette, double time, int origin);
68
69DECLARE_LEGACY_IMAGE_DEVICE(CASSETTE, cassette);
70
71/***************************************************************************
72    DEVICE CONFIGURATION MACROS
73***************************************************************************/
74
75#define MCFG_CASSETTE_ADD(_tag, _config)   \
76   MCFG_DEVICE_ADD(_tag, CASSETTE, 0)         \
77   MCFG_DEVICE_CONFIG(_config)
78
79#define MCFG_CASSETTE_MODIFY(_tag, _config)   \
80   MCFG_DEVICE_MODIFY(_tag)      \
81   MCFG_DEVICE_CONFIG(_config)
82
83extern const cassette_config default_cassette_config;
84
85#endif /* CASSETTE_H */
src/emu/imagedev/flopdrv.h
r0r9928
1/* flopdrv provides simple emulation of a disc drive */
2/* the 8271, upd765 and wd179x use this */
3
4#ifndef __FLOPDRV_H__
5#define __FLOPDRV_H__
6
7#include "devcb.h"
8#include "image.h"
9#include "flopimg.h"
10
11#define FLOPPY_TYPE_REGULAR 0
12#define FLOPPY_TYPE_APPLE   1
13#define FLOPPY_TYPE_SONY   2
14
15#define FLOPPY_DRIVE_2_8_INCH   1
16#define FLOPPY_DRIVE_3_INCH      2
17#define FLOPPY_DRIVE_3_5_INCH   3
18#define FLOPPY_DRIVE_5_25_INCH   4
19#define FLOPPY_DRIVE_8_INCH      5
20
21// Maximum supported density
22#define FLOPPY_DRIVE_SD 1
23#define FLOPPY_DRIVE_DD 2
24#define FLOPPY_DRIVE_QD 3
25#define FLOPPY_DRIVE_HD 4
26#define FLOPPY_DRIVE_ED 5
27
28#define FLOPPY_STANDARD_3_SSDD       { FLOPPY_DRIVE_3_INCH,    1, 42, FLOPPY_DRIVE_DD }
29#define FLOPPY_STANDARD_3_DSDD       { FLOPPY_DRIVE_3_INCH,    2, 42, FLOPPY_DRIVE_DD }
30#define FLOPPY_STANDARD_3_5_DSDD     { FLOPPY_DRIVE_3_5_INCH,  2, 83, FLOPPY_DRIVE_DD }
31#define FLOPPY_STANDARD_3_5_DSHD     { FLOPPY_DRIVE_3_5_INCH,  2, 83, FLOPPY_DRIVE_HD }
32#define FLOPPY_STANDARD_5_25_SSSD_35 { FLOPPY_DRIVE_5_25_INCH, 1, 37, FLOPPY_DRIVE_SD }
33#define FLOPPY_STANDARD_5_25_DSSD_35 { FLOPPY_DRIVE_5_25_INCH, 2, 37, FLOPPY_DRIVE_SD }
34#define FLOPPY_STANDARD_5_25_SSSD    { FLOPPY_DRIVE_5_25_INCH, 1, 42, FLOPPY_DRIVE_SD }
35#define FLOPPY_STANDARD_5_25_DSSD    { FLOPPY_DRIVE_5_25_INCH, 2, 42, FLOPPY_DRIVE_SD }
36#define FLOPPY_STANDARD_5_25_SSDD_40 { FLOPPY_DRIVE_5_25_INCH, 1, 42, FLOPPY_DRIVE_DD }
37#define FLOPPY_STANDARD_5_25_DSDD_40 { FLOPPY_DRIVE_5_25_INCH, 2, 42, FLOPPY_DRIVE_DD }
38#define FLOPPY_STANDARD_5_25_SSDD    { FLOPPY_DRIVE_5_25_INCH, 1, 83, FLOPPY_DRIVE_DD }
39#define FLOPPY_STANDARD_5_25_DSDD    { FLOPPY_DRIVE_5_25_INCH, 2, 83, FLOPPY_DRIVE_DD }
40#define FLOPPY_STANDARD_5_25_DSQD    { FLOPPY_DRIVE_5_25_INCH, 2, 83, FLOPPY_DRIVE_QD }
41#define FLOPPY_STANDARD_5_25_DSHD    { FLOPPY_DRIVE_5_25_INCH, 2, 83, FLOPPY_DRIVE_HD }
42#define FLOPPY_STANDARD_8_SSSD       { FLOPPY_DRIVE_8_INCH,    1, 77, FLOPPY_DRIVE_SD }
43#define FLOPPY_STANDARD_8_DSSD       { FLOPPY_DRIVE_8_INCH,    2, 77, FLOPPY_DRIVE_SD }
44#define FLOPPY_STANDARD_8_DSDD       { FLOPPY_DRIVE_8_INCH,    2, 77, FLOPPY_DRIVE_DD }
45
46/***************************************************************************
47    TYPE DEFINITIONS
48***************************************************************************/
49typedef struct floppy_type_t   floppy_type;
50struct floppy_type_t
51{
52   UINT8 media_size;
53   UINT8 head_number;
54   UINT8 max_track_number;
55   UINT8 max_density;
56};
57
58typedef struct floppy_config_t   floppy_config;
59struct floppy_config_t
60{
61   devcb_write_line out_idx_func;  /* index */
62   devcb_read_line  in_mon_func;   /* motor on */
63   devcb_write_line out_tk00_func; /* track 00 */
64   devcb_write_line out_wpt_func;  /* write protect */
65   devcb_write_line out_rdy_func;  /* ready */
66//  devcb_write_line out_dskchg_func;  /* disk changed */
67
68   floppy_type_t floppy_type;
69   const struct FloppyFormat *formats;
70   const char *interface;
71};
72
73/* sector has a deleted data address mark */
74#define ID_FLAG_DELETED_DATA   0x0001
75/* CRC error in id field */
76#define ID_FLAG_CRC_ERROR_IN_ID_FIELD 0x0002
77/* CRC error in data field */
78#define ID_FLAG_CRC_ERROR_IN_DATA_FIELD 0x0004
79
80typedef struct chrn_id
81{
82   unsigned char C;
83   unsigned char H;
84   unsigned char R;
85   unsigned char N;
86   int data_id;         // id for read/write data command
87   unsigned long flags;
88} chrn_id;
89
90/* set if drive is ready */
91#define FLOPPY_DRIVE_READY                  0x0010
92/* set if index has just occured */
93#define FLOPPY_DRIVE_INDEX                  0x0020
94
95/* a callback which will be executed if the ready state of the drive changes e.g. not ready->ready, ready->not ready */
96void floppy_drive_set_ready_state_change_callback(device_t *img, void (*callback)(device_t *controller,device_t *img, int state));
97
98void floppy_drive_set_index_pulse_callback(device_t *img, void (*callback)(device_t *controller,device_t *image, int state));
99
100/* set flag state */
101int floppy_drive_get_flag_state(device_t *img, int flag);
102/* get flag state */
103void floppy_drive_set_flag_state(device_t *img, int flag, int state);
104/* get current physical track drive is on */
105int floppy_drive_get_current_track(device_t *img);
106/* get current physical track size */
107UINT64 floppy_drive_get_current_track_size(device_t *img, int head);
108
109/* get next id from track, 1 if got a id, 0 if no id was got */
110int floppy_drive_get_next_id(device_t *img, int side, chrn_id *);
111/* set ready state of drive. If flag == 1, set ready state only if drive present,
112disk is in drive, and motor is on. Otherwise set ready state to the state passed */
113void floppy_drive_set_ready_state(device_t *img, int state, int flag);
114
115/* seek up or down */
116void floppy_drive_seek(device_t *img, signed int signed_tracks);
117
118void floppy_drive_read_track_data_info_buffer(device_t *img, int side, void *ptr, int *length );
119void floppy_drive_write_track_data_info_buffer(device_t *img, int side, const void *ptr, int *length );
120void floppy_drive_format_sector(device_t *img, int side, int sector_index, int c, int h, int r, int n, int filler);
121void floppy_drive_read_sector_data(device_t *img, int side, int index1, void *pBuffer, int length);
122void floppy_drive_write_sector_data(device_t *img, int side, int index1, const void *pBuffer, int length, int ddam);
123
124/* set motor speed to get correct index pulses
125   standard RPM are 300 RPM (common) and 360 RPM
126   Note: this actually only works for soft sectored disks: one index pulse per
127   track.
128*/
129void floppy_drive_set_rpm(device_t *image, float rpm);
130
131void floppy_drive_set_controller(device_t *img, device_t *controller);
132
133floppy_image *flopimg_get_image(device_t *image);
134
135/* hack for apple II; replace this when we think of something better */
136void floppy_install_unload_proc(device_t *image, void (*proc)(device_image_interface &image));
137
138void floppy_install_load_proc(device_t *image, void (*proc)(device_image_interface &image));
139
140device_t *floppy_get_device(running_machine *machine,int drive);
141device_t *floppy_get_device_by_type(running_machine *machine,int ftype,int drive);
142int floppy_get_drive_type(device_t *image);
143void floppy_set_type(device_t *image,int ftype);
144int floppy_get_count(running_machine *machine);
145
146int floppy_get_drive(device_t *image);
147int floppy_get_drive_by_type(device_t *image,int ftype);
148
149void *flopimg_get_custom_data(device_t *image);
150void flopimg_alloc_custom_data(device_t *image,void *custom);
151
152void floppy_drive_set_geometry(device_t *img, floppy_type_t type);
153
154/* drive select lines */
155WRITE_LINE_DEVICE_HANDLER( floppy_ds0_w );
156WRITE_LINE_DEVICE_HANDLER( floppy_ds1_w );
157WRITE_LINE_DEVICE_HANDLER( floppy_ds2_w );
158WRITE_LINE_DEVICE_HANDLER( floppy_ds3_w );
159WRITE8_DEVICE_HANDLER( floppy_ds_w );
160
161WRITE_LINE_DEVICE_HANDLER( floppy_mon_w );
162WRITE_LINE_DEVICE_HANDLER( floppy_drtn_w );
163WRITE_LINE_DEVICE_HANDLER( floppy_stp_w );
164WRITE_LINE_DEVICE_HANDLER( floppy_wtd_w );
165WRITE_LINE_DEVICE_HANDLER( floppy_wtg_w );
166
167/* write-protect */
168READ_LINE_DEVICE_HANDLER( floppy_wpt_r );
169
170/* track 0 detect */
171READ_LINE_DEVICE_HANDLER( floppy_tk00_r );
172
173/* disk changed */
174READ_LINE_DEVICE_HANDLER( floppy_dskchg_r );
175
176/* 2-sided disk */
177READ_LINE_DEVICE_HANDLER( floppy_twosid_r );
178
179DECLARE_LEGACY_IMAGE_DEVICE(FLOPPY, floppy);
180
181extern DEVICE_START( floppy );
182extern DEVICE_IMAGE_LOAD( floppy );
183extern DEVICE_IMAGE_CREATE( floppy );
184extern DEVICE_IMAGE_UNLOAD( floppy );
185
186/***************************************************************************
187    DEVICE CONFIGURATION MACROS
188***************************************************************************/
189#define FLOPPY_0 "floppy0"
190#define FLOPPY_1 "floppy1"
191#define FLOPPY_2 "floppy2"
192#define FLOPPY_3 "floppy3"
193
194
195#define MCFG_FLOPPY_DRIVE_ADD(_tag, _config)   \
196   MCFG_DEVICE_ADD(_tag, FLOPPY, 0)         \
197   MCFG_DEVICE_CONFIG(_config)
198
199#define MCFG_FLOPPY_DRIVE_MODIFY(_tag, _config)   \
200   MCFG_DEVICE_MODIFY(_tag)      \
201   MCFG_DEVICE_CONFIG(_config)
202
203#define MCFG_FLOPPY_4_DRIVES_ADD(_config)   \
204   MCFG_DEVICE_ADD(FLOPPY_0, FLOPPY, 0)      \
205   MCFG_DEVICE_CONFIG(_config)   \
206   MCFG_DEVICE_ADD(FLOPPY_1, FLOPPY, 0)      \
207   MCFG_DEVICE_CONFIG(_config)   \
208   MCFG_DEVICE_ADD(FLOPPY_2, FLOPPY, 0)      \
209   MCFG_DEVICE_CONFIG(_config)   \
210   MCFG_DEVICE_ADD(FLOPPY_3, FLOPPY, 0)      \
211   MCFG_DEVICE_CONFIG(_config)
212
213#define MCFG_FLOPPY_4_DRIVES_MODIFY(_config)   \
214   MCFG_DEVICE_MODIFY(FLOPPY_0)      \
215   MCFG_DEVICE_CONFIG(_config)   \
216   MCFG_DEVICE_MODIFY(FLOPPY_1)      \
217   MCFG_DEVICE_CONFIG(_config)   \
218   MCFG_DEVICE_MODIFY(FLOPPY_2)      \
219   MCFG_DEVICE_CONFIG(_config)   \
220   MCFG_DEVICE_MODIFY(FLOPPY_3)      \
221   MCFG_DEVICE_CONFIG(_config)
222
223#define MCFG_FLOPPY_4_DRIVES_REMOVE()   \
224   MCFG_DEVICE_REMOVE(FLOPPY_0)      \
225   MCFG_DEVICE_REMOVE(FLOPPY_1)      \
226   MCFG_DEVICE_REMOVE(FLOPPY_2)      \
227   MCFG_DEVICE_REMOVE(FLOPPY_3)
228
229#define MCFG_FLOPPY_2_DRIVES_ADD(_config)   \
230   MCFG_DEVICE_ADD(FLOPPY_0, FLOPPY, 0)      \
231   MCFG_DEVICE_CONFIG(_config)   \
232   MCFG_DEVICE_ADD(FLOPPY_1, FLOPPY, 0)      \
233   MCFG_DEVICE_CONFIG(_config)
234
235#define MCFG_FLOPPY_2_DRIVES_MODIFY(_config)   \
236   MCFG_DEVICE_MODIFY(FLOPPY_0)      \
237   MCFG_DEVICE_CONFIG(_config)   \
238   MCFG_DEVICE_MODIFY(FLOPPY_1)      \
239   MCFG_DEVICE_CONFIG(_config)
240
241#define MCFG_FLOPPY_2_DRIVES_REMOVE()   \
242   MCFG_DEVICE_REMOVE(FLOPPY_0)      \
243   MCFG_DEVICE_REMOVE(FLOPPY_1)
244
245#endif /* __FLOPDRV_H__ */
src/emu/imagedev/printer.c
r0r9928
1/****************************************************************************
2
3    printer.c
4
5    Code for handling printer devices
6
7****************************************************************************/
8
9#include "emu.h"
10#include "printer.h"
11
12
13
14/***************************************************************************
15    IMPLEMENTATION
16***************************************************************************/
17
18/*-------------------------------------------------
19    printer_is_ready - checks to see if a printer
20    is ready
21-------------------------------------------------*/
22
23int printer_is_ready(device_t *printer)
24{
25   device_image_interface *image = dynamic_cast<device_image_interface *>(printer);
26   /* if there is a file attached to it, it's online */
27   return image->exists() != 0;
28}
29
30
31
32/*-------------------------------------------------
33    printer_output - outputs data to a printer
34-------------------------------------------------*/
35
36void printer_output(device_t *printer, UINT8 data)
37{
38   device_image_interface *image = dynamic_cast<device_image_interface *>(printer);
39   if (image->exists())
40   {
41      image->fwrite(&data, 1);
42   }
43}
44
45
46/*-------------------------------------------------
47    DEVICE_IMAGE_LOAD( printer )
48-------------------------------------------------*/
49
50static DEVICE_IMAGE_LOAD( printer )
51{
52   const printer_config *conf = (const printer_config *)downcast<const legacy_image_device_config_base &>(image.device().baseconfig()).inline_config();
53
54   /* send notify that the printer is now online */
55   if (conf != NULL && conf->online != NULL)
56      conf->online(image, TRUE);
57
58   /* we don't need to do anything special */
59   return IMAGE_INIT_PASS;
60}
61
62
63/*-------------------------------------------------
64    DEVICE_IMAGE_UNLOAD( printer )
65-------------------------------------------------*/
66
67static DEVICE_IMAGE_UNLOAD( printer )
68{
69   const printer_config *conf = (const printer_config *)downcast<const legacy_image_device_config_base &>(image.device().baseconfig()).inline_config();
70
71   /* send notify that the printer is now offline */
72   if (conf != NULL && conf->online != NULL)
73      conf->online(image, FALSE);
74}
75
76
77/*-------------------------------------------------
78    DEVICE_START(printer)
79-------------------------------------------------*/
80
81static DEVICE_START(printer)
82{
83}
84
85
86
87/*-------------------------------------------------
88    DEVICE_GET_INFO(printer)
89-------------------------------------------------*/
90
91DEVICE_GET_INFO(printer)
92{
93   switch(state)
94   {
95      /* --- the following bits of info are returned as 64-bit signed integers --- */
96      case DEVINFO_INT_TOKEN_BYTES:               info->i = 1; break;
97      case DEVINFO_INT_INLINE_CONFIG_BYTES:         info->i = sizeof(printer_config); break;
98      case DEVINFO_INT_IMAGE_TYPE:               info->i = IO_PRINTER; break;
99      case DEVINFO_INT_IMAGE_READABLE:            info->i = 0; break;
100      case DEVINFO_INT_IMAGE_WRITEABLE:            info->i = 1; break;
101      case DEVINFO_INT_IMAGE_CREATABLE:            info->i = 1; break;
102
103      /* --- the following bits of info are returned as pointers to data or functions --- */
104      case DEVINFO_FCT_START:                     info->start = DEVICE_START_NAME(printer); break;
105      case DEVINFO_FCT_IMAGE_LOAD:               info->f = (genf *) DEVICE_IMAGE_LOAD_NAME(printer);      break;
106      case DEVINFO_FCT_IMAGE_UNLOAD:               info->f = (genf *) DEVICE_IMAGE_UNLOAD_NAME(printer);   break;
107
108      /* --- the following bits of info are returned as NULL-terminated strings --- */
109      case DEVINFO_STR_NAME:                     strcpy(info->s, "Printer"); break;
110      case DEVINFO_STR_FAMILY:                  strcpy(info->s, "Printer"); break;
111      case DEVINFO_STR_SOURCE_FILE:               strcpy(info->s, __FILE__); break;
112      case DEVINFO_STR_IMAGE_FILE_EXTENSIONS:         strcpy(info->s, "prn"); break;
113   }
114}
115
116DEFINE_LEGACY_IMAGE_DEVICE(PRINTER, printer);
src/emu/imagedev/cassimg.c
r0r9928
1/*********************************************************************
2
3    cassimg.c
4
5    Cassette tape image abstraction code
6
7*********************************************************************/
8
9
10#include <string.h>
11
12#include "emu.h"
13#include "imageutl.h"
14#include "pool.h"
15#include "cassimg.h"
16
17
18/* debugging parameters */
19#define LOG_PUT_SAMPLES         0
20#define DUMP_CASSETTES         0
21
22#define SAMPLES_PER_BLOCK      0x40000
23#define CASSETTE_FLAG_DIRTY      0x10000
24
25
26CASSETTE_FORMATLIST_START(cassette_default_formats)
27CASSETTE_FORMATLIST_END
28
29
30
31/*********************************************************************
32    helper code
33*********************************************************************/
34
35static double map_double(double d, UINT64 low, UINT64 high, UINT64 value)
36{
37#if defined(_MSC_VER) && (_MSC_VER <= 1200)
38   /* casting unsigned __int64 to double is not supported on VC6 or before */
39   return d * (INT64)(value - low) / (INT64)(high - low);
40#else
41   return d * (value - low) / (high - low);
42#endif
43}
44
45
46
47static size_t waveform_bytes_per_sample(int waveform_flags)
48{
49   return (size_t) (1 << ((waveform_flags & 0x06) / 2));
50}
51
52
53
54/*********************************************************************
55    extrapolation and interpolation
56*********************************************************************/
57
58static INT32 extrapolate8(INT8 value)
59{
60   return ((INT32) value) << 24;
61}
62
63static INT32 extrapolate16(INT16 value)
64{
65   return ((INT32) value) << 16;
66}
67
68static INT8 interpolate8(INT32 value)
69{
70   return (INT8) (value >> 24);
71}
72
73static INT16 interpolate16(INT32 value)
74{
75   return (INT16) (value >> 16);
76}
77
78
79
80/*********************************************************************
81    initialization and termination
82*********************************************************************/
83
84static cassette_image *cassette_init(running_machine *machine,const struct CassetteFormat *format, void *file, const struct io_procs *procs, int flags)
85{
86   cassette_image *cassette;
87
88   cassette = (cassette_image *)malloc(sizeof(struct _cassette_image));
89   if (!cassette)
90      return NULL;
91
92   memset(cassette, 0, sizeof(*cassette));
93   cassette->format = format;
94   cassette->io.file = file;
95   cassette->io.procs = procs;
96   cassette->flags = flags;
97   cassette->pool = pool_alloc_lib(NULL);
98   cassette->machine = machine;
99   return cassette;
100}
101
102
103
104static void cassette_finishinit(casserr_t err, cassette_image *cassette, cassette_image **outcassette)
105{
106   if (cassette && (err || !outcassette))
107   {
108      cassette_close(cassette);
109      cassette = NULL;
110   }
111   if (outcassette)
112      *outcassette = cassette;
113}
114
115
116
117static int good_format(const struct CassetteFormat *format, const char *extension, int flags)
118{
119   if (extension && !image_find_extension(format->extensions, extension))
120      return FALSE;
121   if (((flags & CASSETTE_FLAG_READONLY) == 0) && !format->save)
122      return FALSE;
123   return TRUE;
124}
125
126
127
128casserr_t cassette_open_choices(running_machine *machine,void *file, const struct io_procs *procs, const char *extension,
129   const struct CassetteFormat *const *formats, int flags, cassette_image **outcassette)
130{
131   casserr_t err;
132   cassette_image *cassette;
133   const struct CassetteFormat *format;
134   struct CassetteOptions opts = {0, };
135   int i;
136
137   /* if not specified, use the dummy arguments */
138   if (!formats)
139      formats = cassette_default_formats;
140
141   /* create the cassette object */
142   cassette = cassette_init(machine, NULL, file, procs, flags);
143   if (!cassette)
144   {
145      err = CASSETTE_ERROR_OUTOFMEMORY;
146      goto done;
147   }
148
149   /* identify the image */
150   format = NULL;
151   for (i = 0; !format && formats[i]; i++)
152   {
153      if (good_format(formats[i], extension, flags))
154      {
155         format = formats[i];
156         memset(&opts, 0, sizeof(opts));
157         err = format->identify(cassette, &opts);
158         if (err == CASSETTE_ERROR_INVALIDIMAGE)
159            format = NULL;
160         else if (err)
161            goto done;
162      }
163   }
164
165   /* have we found a proper format */
166   if (!format)
167   {
168      err = CASSETTE_ERROR_INVALIDIMAGE;
169      goto done;
170   }
171   cassette->format = format;
172
173   /* read the options */
174   cassette->channels = opts.channels;
175   cassette->sample_frequency = opts.sample_frequency;
176
177   /* load the image */
178   err = format->load(cassette);
179   if (err)
180      goto done;
181
182   /* success */
183   cassette->flags &= ~CASSETTE_FLAG_DIRTY;
184   err = CASSETTE_ERROR_SUCCESS;
185
186done:
187   cassette_finishinit(err, cassette, outcassette);
188   return err;
189}
190
191
192
193casserr_t cassette_open(running_machine *machine, void *file, const struct io_procs *procs,
194   const struct CassetteFormat *format, int flags, cassette_image **outcassette)
195{
196   const struct CassetteFormat *formats[2];
197   formats[0] = format;
198   formats[1] = NULL;
199   return cassette_open_choices(machine, file, procs, NULL, formats, flags, outcassette);
200}
201
202
203
204casserr_t cassette_create(running_machine *machine, void *file, const struct io_procs *procs, const struct CassetteFormat *format,
205   const struct CassetteOptions *opts, int flags, cassette_image **outcassette)
206{
207   casserr_t err;
208   cassette_image *cassette;
209   static const struct CassetteOptions default_options = { 1, 16, 44100 };
210
211   /* cannot create to a read only image */
212   if (flags & CASSETTE_FLAG_READONLY)
213      return CASSETTE_ERROR_INVALIDIMAGE;
214
215   /* is this a good format? */
216   if (!good_format(format, NULL, flags))
217      return CASSETTE_ERROR_INVALIDIMAGE;
218
219   /* normalize arguments */
220   if (!opts)
221      opts = &default_options;
222
223   /* create the cassette object */
224   cassette = cassette_init(machine, format, file, procs, flags);
225   if (!cassette)
226   {
227      err = CASSETTE_ERROR_OUTOFMEMORY;
228      goto done;
229   }
230
231   /* read the options */
232   cassette->channels = opts->channels;
233   cassette->sample_frequency = opts->sample_frequency;
234
235   err = CASSETTE_ERROR_SUCCESS;
236
237done:
238   cassette_finishinit(err, cassette, outcassette);
239   return err;
240}
241
242
243
244static casserr_t cassette_perform_save(cassette_image *cassette)
245{
246   struct CassetteInfo info;
247   cassette_get_info(cassette, &info);
248   return cassette->format->save(cassette, &info);
249}
250
251
252
253casserr_t cassette_save(cassette_image *cassette)
254{
255   casserr_t err;
256
257   if (!cassette->format || !cassette->format->save)
258      return CASSETTE_ERROR_UNSUPPORTED;
259
260   err = cassette_perform_save(cassette);
261   if (err)
262      return err;
263
264   cassette->flags &= ~CASSETTE_FLAG_DIRTY;
265   return CASSETTE_ERROR_SUCCESS;
266}
267
268
269
270void cassette_get_info(cassette_image *cassette, struct CassetteInfo *info)
271{
272   memset(info, 0, sizeof(*info));
273   info->channels = cassette->channels;
274   info->sample_count = cassette->sample_count;
275   info->sample_frequency = cassette->sample_frequency;
276   info->bits_per_sample = (int) waveform_bytes_per_sample(cassette->flags) * 8;
277}
278
279
280
281void cassette_close(cassette_image *cassette)
282{
283   if (cassette)
284   {
285      if ((cassette->flags & CASSETTE_FLAG_DIRTY) && (cassette->flags & CASSETTE_FLAG_SAVEONEXIT))
286         cassette_save(cassette);
287      pool_free_lib(cassette->pool);
288      free(cassette);
289   }
290}
291
292
293
294void cassette_change(cassette_image *cassette, void *file, const struct io_procs *procs, const struct CassetteFormat *format, int flags)
295{
296   if ((flags & CASSETTE_FLAG_READONLY) == 0)
297      flags |= CASSETTE_FLAG_DIRTY;
298   cassette->io.file = file;
299   cassette->io.procs = procs;
300   cassette->format = format;
301   cassette->flags = flags;
302}
303
304
305
306/*********************************************************************
307    calls for accessing the raw cassette image
308*********************************************************************/
309
310void cassette_image_read(cassette_image *cassette, void *buffer, UINT64 offset, size_t length)
311{
312   io_generic_read(&cassette->io, buffer, offset, length);
313}
314
315
316
317void cassette_image_write(cassette_image *cassette, const void *buffer, UINT64 offset, size_t length)
318{
319   io_generic_write(&cassette->io, buffer, offset, length);
320}
321
322
323
324UINT64 cassette_image_size(cassette_image *cassette)
325{
326   return io_generic_size(&cassette->io);
327}
328
329
330
331/*********************************************************************
332    waveform accesses
333*********************************************************************/
334
335struct manipulation_ranges
336{
337   int channel_first;
338   int channel_last;
339   size_t sample_first;
340   size_t sample_last;
341};
342
343
344
345static size_t my_round(double d)
346{
347   size_t result;
348   d += 0.5;
349   result = (size_t) d;
350   return result;
351}
352
353
354
355static casserr_t compute_manipulation_ranges(cassette_image *cassette, int channel,
356   double time_index, double sample_period, struct manipulation_ranges *ranges)
357{
358   if (channel < 0)
359   {
360      ranges->channel_first = 0;
361      ranges->channel_last = cassette->channels - 1;
362   }
363   else
364   {
365      ranges->channel_first = channel;
366      ranges->channel_last = channel;
367   }
368
369   ranges->sample_first = my_round(time_index * cassette->sample_frequency);
370   ranges->sample_last = my_round((time_index + sample_period) * cassette->sample_frequency);
371
372   if (ranges->sample_last > ranges->sample_first)
373      ranges->sample_last--;
374
375   return CASSETTE_ERROR_SUCCESS;
376}
377
378
379
380static casserr_t lookup_sample(cassette_image *cassette, int channel, size_t sample, int allocate, INT32 **ptr)
381{
382   size_t sample_block;
383   size_t sample_index;
384   size_t sample_size;
385   size_t new_block_count;
386   size_t new_block_sample_count;
387   INT32 *new_block;
388   struct sample_block *new_blocks;
389   struct sample_block *block;
390
391   *ptr = NULL;
392   sample_block = (sample / SAMPLES_PER_BLOCK) * cassette->channels + channel;
393   sample_index = sample % SAMPLES_PER_BLOCK;
394   sample_size = sizeof(block->block[0]);
395
396   /* is this block beyond the edge of our waveform? */
397   if (sample_block >= cassette->block_count)
398   {
399      if (!allocate)
400         return CASSETTE_ERROR_SUCCESS;
401
402      /* allocate new blocks */
403      new_block_count = sample_block + 1;
404      new_blocks = (struct sample_block *)pool_realloc_lib(cassette->pool, cassette->blocks, new_block_count * sizeof(cassette->blocks[0]));
405      if (!new_blocks)
406         return CASSETTE_ERROR_OUTOFMEMORY;
407
408      cassette->blocks = new_blocks;
409      memset(&cassette->blocks[cassette->block_count], 0, (new_block_count - cassette->block_count) * sizeof(cassette->blocks[0]));
410      cassette->block_count = new_block_count;
411   }
412
413   block = &cassette->blocks[sample_block];
414
415   /* is this sample access off the current block? */
416   if (sample_index >= block->sample_count)
417   {
418      if (!allocate)
419         return CASSETTE_ERROR_SUCCESS;
420
421      new_block_sample_count = SAMPLES_PER_BLOCK;
422
423      new_block = (INT32*)pool_realloc_lib(cassette->pool, block->block, new_block_sample_count * sample_size);
424      if (!new_block)
425         return CASSETTE_ERROR_OUTOFMEMORY;
426
427      block->block = new_block;
428      memset(&block->block[block->sample_count], 0, (new_block_sample_count - block->sample_count) * sample_size);
429      block->sample_count = new_block_sample_count;
430   }
431
432   *ptr = &block->block[sample_index];
433   return CASSETTE_ERROR_SUCCESS;
434}
435
436
437
438/*********************************************************************
439    waveform accesses
440*********************************************************************/
441
442casserr_t cassette_get_samples(cassette_image *cassette, int channel,
443   double time_index, double sample_period, size_t sample_count, size_t sample_bytes,
444   void *samples, int waveform_flags)
445{
446   casserr_t err;
447   struct manipulation_ranges ranges;
448   size_t sample_index;
449   size_t cassette_sample_index;
450   UINT8 *dest_ptr;
451   const INT32 *source_ptr;
452   double d;
453   INT16 word;
454   INT32 dword;
455   INT64 sum;
456
457   assert(cassette);
458
459   err = compute_manipulation_ranges(cassette, channel, time_index, sample_period, &ranges);
460   if (err)
461      return err;
462
463   for (sample_index = 0; sample_index < sample_count; sample_index++)
464   {
465      sum = 0;
466
467      for (channel = ranges.channel_first; channel <= ranges.channel_last; channel++)
468      {
469         /* find the sample that we are putting */
470         d = map_double(ranges.sample_last + 1 - ranges.sample_first, 0, sample_count, sample_index) + ranges.sample_first;
471         cassette_sample_index = (size_t) d;
472         err = lookup_sample(cassette, channel, cassette_sample_index, TRUE, (INT32 **) &source_ptr);
473         if (err)
474            return err;
475
476         sum += *source_ptr;
477      }
478
479      /* average out the samples */
480      sum /= (ranges.channel_last + 1 - ranges.channel_first);
481
482      /* and write out the result */
483      dest_ptr = (UINT8*)samples;
484      dest_ptr += waveform_bytes_per_sample(waveform_flags) * sample_index;
485      switch(waveform_bytes_per_sample(waveform_flags))
486      {
487         case 1:
488            *((INT8 *) dest_ptr) = interpolate8(sum);
489            break;
490         case 2:
491            word = interpolate16(sum);
492            if (waveform_flags & CASSETTE_WAVEFORM_ENDIAN_FLIP)
493               word = FLIPENDIAN_INT16(word);
494            *((INT16 *) dest_ptr) = word;
495            break;
496         case 4:
497            dword = sum;
498            if (waveform_flags & CASSETTE_WAVEFORM_ENDIAN_FLIP)
499               dword = FLIPENDIAN_INT32(dword);
500            *((INT32 *) dest_ptr) = dword;
501            break;
502      }
503   }
504   return CASSETTE_ERROR_SUCCESS;
505}
506
507
508
509casserr_t cassette_put_samples(cassette_image *cassette, int channel,
510   double time_index, double sample_period, size_t sample_count, size_t sample_bytes,
511   const void *samples, int waveform_flags)
512{
513   casserr_t err;
514   struct manipulation_ranges ranges;
515   size_t sample_index;
516   INT32 *dest_ptr;
517   INT32 dest_value;
518   INT16 word;
519   INT32 dword;
520   const UINT8 *source_ptr;
521   double d;
522
523   if (!cassette)
524      return CASSETTE_ERROR_SUCCESS;
525
526   if (sample_period == 0)
527      return CASSETTE_ERROR_SUCCESS;
528
529   err = compute_manipulation_ranges(cassette, channel, time_index, sample_period, &ranges);
530   if (err)
531      return err;
532
533   if (cassette->sample_count < ranges.sample_last+1)
534      cassette->sample_count = ranges.sample_last + 1;
535   cassette->flags |= CASSETTE_FLAG_DIRTY;
536
537   if (LOG_PUT_SAMPLES)
538   {
539      logerror("cassette_put_samples(): Putting samples TIME=[%2.6g..%2.6g] INDEX=[%i..%i]\n",
540         time_index,            time_index + sample_period,
541         (int)ranges.sample_first,   (int)ranges.sample_last);
542   }
543
544   for (sample_index = ranges.sample_first; sample_index <= ranges.sample_last; sample_index++)
545   {
546      /* figure out the source pointer */
547      d = map_double(sample_count, ranges.sample_first, ranges.sample_last + 1, sample_index);
548      source_ptr = (const UINT8*)samples;
549      source_ptr += ((size_t) d) * sample_bytes;
550
551      /* compute the value that we are writing */
552      switch(waveform_bytes_per_sample(waveform_flags)) {
553      case 1:
554         dest_value = extrapolate8(*((INT8 *) source_ptr));
555         break;
556      case 2:
557         word = *((INT16 *) source_ptr);
558         if (waveform_flags & CASSETTE_WAVEFORM_ENDIAN_FLIP)
559            word = FLIPENDIAN_INT16(word);
560         dest_value = extrapolate16(word);
561         break;
562      case 4:
563         dword = *((INT32 *) source_ptr);
564         if (waveform_flags & CASSETTE_WAVEFORM_ENDIAN_FLIP)
565            dword = FLIPENDIAN_INT32(dword);
566         dest_value = dword;
567         break;
568      default:
569         return CASSETTE_ERROR_INTERNAL;
570      }
571
572      for (channel = ranges.channel_first; channel <= ranges.channel_last; channel++)
573      {
574         /* find the sample that we are putting */
575         err = lookup_sample(cassette, channel, sample_index, TRUE, &dest_ptr);
576         if (err)
577            return err;
578         *dest_ptr = dest_value;
579      }
580   }
581   return CASSETTE_ERROR_SUCCESS;
582}
583
584
585
586casserr_t cassette_get_sample(cassette_image *cassette, int channel,
587   double time_index, double sample_period, INT32 *sample)
588{
589   return cassette_get_samples(cassette, channel, time_index,
590       sample_period, 1, 0, sample, CASSETTE_WAVEFORM_32BIT);
591}
592
593
594
595casserr_t cassette_put_sample(cassette_image *cassette, int channel,
596   double time_index, double sample_period, INT32 sample)
597{
598   return cassette_put_samples(cassette, channel, time_index,
599       sample_period, 1, 0, &sample, CASSETTE_WAVEFORM_32BIT);
600}
601
602
603
604/*********************************************************************
605    waveform accesses to/from the raw image
606*********************************************************************/
607
608casserr_t cassette_read_samples(cassette_image *cassette, int channels, double time_index,
609   double sample_period, size_t sample_count, UINT64 offset, int waveform_flags)
610{
611   casserr_t err;
612   size_t chunk_sample_count;
613   size_t bytes_per_sample;
614   size_t sample_bytes;
615   size_t samples_loaded = 0;
616   double chunk_time_index;
617   double chunk_sample_period;
618   int channel;
619   UINT8 buffer[8192];
620
621   bytes_per_sample = waveform_bytes_per_sample(waveform_flags);
622   sample_bytes = bytes_per_sample * channels;
623
624   while(samples_loaded < sample_count)
625   {
626      chunk_sample_count = MIN(sizeof(buffer) / sample_bytes, (sample_count - samples_loaded));
627      chunk_sample_period = map_double(sample_period, 0, sample_count, chunk_sample_count);
628      chunk_time_index = time_index + map_double(sample_period, 0, sample_count, samples_loaded);
629
630      cassette_image_read(cassette, buffer, offset, chunk_sample_count * sample_bytes);
631
632      for (channel = 0; channel < channels; channel++)
633      {
634         err = cassette_put_samples(cassette, channel, chunk_time_index, chunk_sample_period,
635            chunk_sample_count, sample_bytes, &buffer[channel * bytes_per_sample], waveform_flags);
636         if (err)
637            return err;
638      }
639
640      offset += chunk_sample_count * sample_bytes;
641      samples_loaded += chunk_sample_count;
642   }
643   return CASSETTE_ERROR_SUCCESS;
644}
645
646
647
648casserr_t cassette_write_samples(cassette_image *cassette, int channels, double time_index,
649   double sample_period, size_t sample_count, UINT64 offset, int waveform_flags)
650{
651   casserr_t err;
652   size_t chunk_sample_count;
653   size_t bytes_per_sample;
654   size_t sample_bytes;
655   size_t samples_saved = 0;
656   double chunk_time_index;
657   double chunk_sample_period;
658   int channel;
659   UINT8 buffer[8192];
660
661   bytes_per_sample = waveform_bytes_per_sample(waveform_flags);
662   sample_bytes = bytes_per_sample * channels;
663
664   while(samples_saved < sample_count)
665   {
666      chunk_sample_count = MIN(sizeof(buffer) / sample_bytes, (sample_count - samples_saved));
667      chunk_sample_period = map_double(sample_period, 0, sample_count, chunk_sample_count);
668      chunk_time_index = time_index + map_double(sample_period, 0, sample_count, samples_saved);
669
670      for (channel = 0; channel < channels; channel++)
671      {
672         err = cassette_get_samples(cassette, channel, chunk_time_index, chunk_sample_period,
673            chunk_sample_count, sample_bytes, &buffer[channel * bytes_per_sample], waveform_flags);
674         if (err)
675            return err;
676      }
677
678      cassette_image_write(cassette, buffer, offset, chunk_sample_count * sample_bytes);
679
680      offset += chunk_sample_count * sample_bytes;
681      samples_saved += chunk_sample_count;
682   }
683   return CASSETTE_ERROR_SUCCESS;
684}
685
686
687
688/*********************************************************************
689    waveform accesses to/from the raw image
690*********************************************************************/
691
692static const INT8 *choose_wave(const struct CassetteModulation *modulation, size_t *wave_bytes_length)
693{
694   static const INT8 square_wave[] = { -128, 127 };
695   static const INT8 sine_wave[] = { 0, 48, 89, 117, 127, 117, 89, 48, 0, -48, -89, -117, -127, -117, -89, -48 };
696
697   if (modulation->flags & CASSETTE_MODULATION_SINEWAVE)
698   {
699      *wave_bytes_length = ARRAY_LENGTH(sine_wave);
700      return sine_wave;
701   }
702   else
703   {
704      *wave_bytes_length = ARRAY_LENGTH(square_wave);
705      return square_wave;
706   }
707}
708
709
710
711casserr_t cassette_modulation_identify(cassette_image *cassette, const struct CassetteModulation *modulation,
712   struct CassetteOptions *opts)
713{
714   size_t wave_bytes_length;
715   choose_wave(modulation, &wave_bytes_length);
716   opts->bits_per_sample = 8;
717   opts->channels = 1;
718   opts->sample_frequency = (UINT32) (MAX(modulation->zero_frequency_high, modulation->one_frequency_high) * wave_bytes_length * 2);
719   return CASSETTE_ERROR_SUCCESS;
720}
721
722
723
724casserr_t cassette_put_modulated_data(cassette_image *cassette, int channel, double time_index,
725   const void *data, size_t data_length, const struct CassetteModulation *modulation,
726   double *time_displacement)
727{
728   casserr_t err;
729   const UINT8 *data_bytes = (const UINT8 *)data;
730   const INT8 *wave_bytes;
731   size_t wave_bytes_length;
732   double total_displacement = 0.0;
733   double pulse_period;
734   double pulse_frequency;
735   UINT8 b;
736   int i;
737
738   wave_bytes = choose_wave(modulation, &wave_bytes_length);
739
740   while(data_length--)
741   {
742      b = *(data_bytes++);
743      for (i = 0; i < 8; i++)
744      {
745         pulse_frequency = (b & (1 << i)) ? modulation->one_frequency_cannonical : modulation->zero_frequency_cannonical;
746         pulse_period = 1 / pulse_frequency;
747         err = cassette_put_samples(cassette, 0, time_index, pulse_period, wave_bytes_length, 1, wave_bytes, CASSETTE_WAVEFORM_8BIT);
748         if (err)
749            goto done;
750         time_index += pulse_period;
751         total_displacement += pulse_period;
752      }
753   }
754   err = CASSETTE_ERROR_SUCCESS;
755
756done:
757   if (time_displacement)
758      *time_displacement = total_displacement;
759   return err;
760}
761
762
763
764casserr_t cassette_put_modulated_filler(cassette_image *cassette, int channel, double time_index,
765   UINT8 filler, size_t filler_length, const struct CassetteModulation *modulation,
766   double *time_displacement)
767{
768   casserr_t err;
769   double delta;
770   double total_displacement = 0.0;
771
772   while(filler_length--)
773   {
774      err = cassette_put_modulated_data(cassette, channel, time_index, &filler, 1, modulation, &delta);
775      if (err)
776         return err;
777      total_displacement += delta;
778      time_index += delta;
779   }
780
781   if (time_displacement)
782      *time_displacement = total_displacement;
783   return CASSETTE_ERROR_SUCCESS;
784}
785
786
787
788casserr_t cassette_read_modulated_data(cassette_image *cassette, int channel, double time_index,
789   UINT64 offset, UINT64 length, const struct CassetteModulation *modulation,
790   double *time_displacement)
791{
792   casserr_t err;
793   UINT8 buffer_stack[1024];
794   UINT8 *buffer;
795   UINT8 *alloc_buffer = NULL;
796   double delta;
797   double total_displacement = 0.0;
798   size_t this_length;
799   size_t buffer_length;
800
801   if (length <= sizeof(buffer_stack))
802   {
803      buffer = buffer_stack;
804      buffer_length = sizeof(buffer_stack);
805   }
806   else
807   {
808      buffer_length = MIN(length, 100000);
809      alloc_buffer = (UINT8*)malloc(buffer_length);
810      if (!alloc_buffer)
811      {
812         err = CASSETTE_ERROR_OUTOFMEMORY;
813         goto done;
814      }
815      buffer = alloc_buffer;
816   }
817
818   while(length > 0)
819   {
820      this_length = (size_t) MIN(length, buffer_length);
821      cassette_image_read(cassette, buffer, offset, this_length);
822
823      err = cassette_put_modulated_data(cassette, channel, time_index, buffer, this_length, modulation, &delta);
824      if (err)
825         goto done;
826      total_displacement += delta;
827      time_index += delta;
828      length -= this_length;
829   }
830
831   if (time_displacement)
832      *time_displacement = total_displacement;
833   err = CASSETTE_ERROR_SUCCESS;
834
835done:
836   if (alloc_buffer)
837      free(alloc_buffer);
838   return err;
839}
840
841
842
843casserr_t cassette_put_modulated_data_bit(cassette_image *cassette, int channel, double time_index,
844   UINT8 data, const struct CassetteModulation *modulation,
845   double *time_displacement)
846{
847   casserr_t err;
848   const INT8 *wave_bytes;
849   size_t wave_bytes_length;
850   double total_displacement = 0.0;
851   double pulse_period;
852   double pulse_frequency;
853
854   wave_bytes = choose_wave(modulation, &wave_bytes_length);
855
856   pulse_frequency = (data) ? modulation->one_frequency_cannonical : modulation->zero_frequency_cannonical;
857   pulse_period = 1 / pulse_frequency;
858   err = cassette_put_samples(cassette, 0, time_index, pulse_period, wave_bytes_length, 1, wave_bytes, CASSETTE_WAVEFORM_8BIT);
859   if (err)
860      goto done;
861   time_index += pulse_period;
862   total_displacement += pulse_period;
863
864   err = CASSETTE_ERROR_SUCCESS;
865
866done:
867   if (time_displacement)
868      *time_displacement = total_displacement;
869   return err;
870}
871
872
873
874/*********************************************************************
875    waveform accesses to/from the raw image
876*********************************************************************/
877
878casserr_t cassette_legacy_identify(cassette_image *cassette, struct CassetteOptions *opts,
879   const struct CassetteLegacyWaveFiller *legacy_args)
880{
881   opts->channels = 1;
882   opts->bits_per_sample = 16;
883   opts->sample_frequency = legacy_args->sample_frequency;
884   return CASSETTE_ERROR_SUCCESS;
885}
886
887
888
889casserr_t cassette_legacy_construct(cassette_image *cassette,
890   const struct CassetteLegacyWaveFiller *legacy_args)
891{
892   casserr_t err;
893   int length;
894   int sample_count;
895   void *bytes = NULL;
896   void *chunk = NULL;
897   INT16 *samples = NULL;
898   int pos = 0;
899   UINT64 offset = 0;
900   UINT64 size;
901   struct CassetteLegacyWaveFiller args;
902
903   /* sanity check the args */
904   assert(legacy_args->header_samples >= -1);
905   assert(legacy_args->trailer_samples >= 0);
906   assert(legacy_args->fill_wave);
907
908   size = cassette_image_size(cassette);
909
910   /* normalize the args */
911   args = *legacy_args;
912   if (args.chunk_size == 0)
913      args.chunk_size = 1;
914   else if (args.chunk_size < 0)
915      args.chunk_size = cassette_image_size(cassette);
916   if (args.sample_frequency == 0)
917      args.sample_frequency = 11025;
918
919   /* allocate a buffer for the binary data */
920   chunk = malloc(args.chunk_size);
921   if (!chunk)
922   {
923      err = CASSETTE_ERROR_OUTOFMEMORY;
924      goto done;
925   }
926
927   /* determine number of samples */
928   if (args.chunk_sample_calc)
929   {
930      if (size > 0x7FFFFFFF)
931      {
932         err = CASSETTE_ERROR_OUTOFMEMORY;
933         goto done;
934      }
935
936      bytes = malloc(size);
937      if (!bytes)
938      {
939         err = CASSETTE_ERROR_OUTOFMEMORY;
940         goto done;
941      }
942      cassette_image_read(cassette, bytes, 0, size);
943      sample_count = args.chunk_sample_calc((const UINT8*)bytes, (int) size);
944
945      if (args.header_samples < 0)
946         args.header_samples = sample_count;
947   }
948   else
949   {
950      sample_count = ((size + args.chunk_size - 1) / args.chunk_size)
951         * args.chunk_samples;
952   }
953   sample_count += args.header_samples + args.trailer_samples;
954
955   /* allocate a buffer for the completed samples */
956   samples = (INT16*)malloc(sample_count * sizeof(*samples));
957   if (!samples)
958   {
959      err = CASSETTE_ERROR_OUTOFMEMORY;
960      goto done;
961   }
962
963   /* if there has to be a header */
964   if (args.header_samples > 0)
965   {
966      length = args.fill_wave(samples + pos, sample_count - pos, CODE_HEADER);
967      if (length < 0)
968      {
969         err = CASSETTE_ERROR_INVALIDIMAGE;
970         goto done;
971      }
972      pos += length;
973   }
974
975   /* convert the file data to samples */
976   while((pos < sample_count) && (offset < size))
977   {
978      cassette_image_read(cassette, chunk, offset, args.chunk_size);
979      offset += args.chunk_size;
980
981      length = args.fill_wave(samples + pos, sample_count - pos, (UINT8*)chunk);
982      if (length < 0)
983      {
984         err = CASSETTE_ERROR_INVALIDIMAGE;
985         goto done;
986      }
987      pos += length;
988      if (length == 0)
989         break;
990   }
991
992   /* if there has to be a trailer */
993   if (args.trailer_samples > 0)
994   {
995      length = args.fill_wave(samples + pos, sample_count - pos, CODE_TRAILER);
996      if (length < 0)
997      {
998         err = CASSETTE_ERROR_INVALIDIMAGE;
999         goto done;
1000      }
1001      pos += length;
1002   }
1003
1004   /* specify the wave */
1005   err = cassette_put_samples(cassette, 0, 0.0, ((double) pos) / args.sample_frequency,
1006      pos, 2, samples, CASSETTE_WAVEFORM_16BIT);
1007   if (err)
1008      goto done;
1009
1010   /* success! */
1011   err = CASSETTE_ERROR_SUCCESS;
1012
1013#if DUMP_CASSETTES
1014   cassette_dump(cassette, "C:\\TEMP\\CASDUMP.WAV");
1015#endif
1016
1017done:
1018   if (samples)
1019      free(samples);
1020   if (chunk)
1021      free(chunk);
1022   if (bytes)
1023      free(bytes);
1024   return err;
1025}
1026
1027
1028
1029/*********************************************************************
1030    cassette_dump
1031
1032    A debugging call to dump a casette image to a disk based wave file
1033*********************************************************************/
1034
1035void cassette_dump(cassette_image *image, const char *filename)
1036{
1037   FILE *f;
1038   struct io_generic saved_io;
1039   const struct CassetteFormat *saved_format;
1040
1041   f = fopen(filename, "wb");
1042   if (!f)
1043      return;
1044
1045   memcpy(&saved_io, &image->io, sizeof(saved_io));
1046   saved_format = image->format;
1047
1048   image->io.file = f;
1049   image->io.procs = &stdio_ioprocs_noclose;
1050   image->format = &wavfile_format;
1051   cassette_perform_save(image);
1052
1053   memcpy(&image->io, &saved_io, sizeof(saved_io));
1054   image->format = saved_format;
1055
1056   fclose(f);
1057}
1058
1059
src/emu/imagedev/bitbngr.c
r0r9928
1/*********************************************************************
2
3    bitbngr.c
4
5    TRS style "bitbanger" serial port
6
7*********************************************************************/
8
9#include "emu.h"
10#include "bitbngr.h"
11
12
13
14/***************************************************************************
15    TYPE DEFINITIONS
16***************************************************************************/
17
18typedef struct _bitbanger_token bitbanger_token;
19struct _bitbanger_token
20{
21   emu_timer *bitbanger_output_timer;
22   emu_timer *bitbanger_input_timer;
23   int output_value;
24   int build_count;
25   int build_byte;
26   attotime idle_delay;
27   attotime current_baud;
28   UINT32 input_buffer_size;
29   UINT32 input_buffer_cursor;
30   int mode;
31   int baud;
32   int tune;
33   UINT8 input_buffer[1000];
34};
35
36
37
38/***************************************************************************
39    FUNCTION PROTOTYPES
40***************************************************************************/
41
42static TIMER_CALLBACK(bitbanger_output_timer);
43static TIMER_CALLBACK(bitbanger_input_timer);
44
45
46
47/***************************************************************************
48    INLINE FUNCTIONS
49***************************************************************************/
50
51
52/*-------------------------------------------------
53    get_token - safely gets the bitbanger data
54-------------------------------------------------*/
55
56INLINE bitbanger_token *get_token(device_t *device)
57{
58   assert(device != NULL);
59   assert(device->type() == BITBANGER);
60   return (bitbanger_token *) downcast<legacy_device_base *>(device)->token();
61}
62
63
64/*-------------------------------------------------
65    get_config - safely gets the bitbanger config
66-------------------------------------------------*/
67
68INLINE const bitbanger_config *get_config(device_t *device)
69{
70   assert(device != NULL);
71   assert(device->type() == BITBANGER);
72   return (const bitbanger_config *) device->baseconfig().static_config();
73}
74
75
76
77/***************************************************************************
78    IMPLEMENTATION
79***************************************************************************/
80
81
82/*-------------------------------------------------
83    native_output - outputs data to a file
84-------------------------------------------------*/
85
86static void native_output(device_t *bitbanger, UINT8 data)
87{
88   device_image_interface *image = dynamic_cast<device_image_interface *>(bitbanger);
89   if (image->exists())
90   {
91      image->fwrite(&data, 1);
92   }
93}
94
95
96/*-------------------------------------------------
97    native_input - inputs data from a file
98-------------------------------------------------*/
99
100static UINT32 native_input(device_t *bitbanger, void *buffer, UINT32 length)
101{
102   device_image_interface *image = dynamic_cast<device_image_interface *>(bitbanger);
103   if (image->exists())
104   {
105      return image->fread(buffer, length);
106   }
107
108   return 0;
109}
110
111
112/*-------------------------------------------------
113    bitbanger_mode_string
114-------------------------------------------------*/
115const char *bitbanger_mode_string(device_t *device)
116{
117   bitbanger_token *bi = get_token(device);
118   static const char *const modes[] = {"Printer", "Modem"};
119
120   return(modes[bi->mode]);
121}
122
123
124/*-------------------------------------------------
125    bitbanger_inc_mode
126-------------------------------------------------*/
127bool bitbanger_inc_mode(device_t *device, bool test)
128{
129   bitbanger_token *bi = get_token(device);
130   int adjust_mode = (int)bi->mode + 1;
131
132   if( adjust_mode >= BITBANGER_MODE_MAX )
133      return FALSE;
134
135   if( !test)
136      bi->mode = adjust_mode;
137
138   return TRUE;
139}
140
141
142/*-------------------------------------------------
143    bitbanger_dec_mode
144-------------------------------------------------*/
145bool bitbanger_dec_mode(device_t *device, bool test)
146{
147   bitbanger_token *bi = get_token(device);
148   int adjust_mode = bi->mode - 1;
149
150   if( adjust_mode < 0 )
151      return FALSE;
152
153   if( !test)
154      bi->mode = adjust_mode;
155
156   return TRUE;
157}
158
159
160/*-------------------------------------------------
161    bitbanger_tune_string
162-------------------------------------------------*/
163const char *bitbanger_tune_string(device_t *device)
164{
165   bitbanger_token *bi = get_token(device);
166   static const char *const tunes[] = {"-2.0%", "-1.75%", "-1.5%", "-1.25%", "-1.0%", "-0.75%", "-0.5", "-0.25%", "\xc2\xb1""0%",
167                                 "+0.25%",  "+0.5%", "+0.75%", "+1.0%", "+1.25%", "+1.5%", "+1.75%", "+2.0%"};
168
169   return(tunes[bi->tune]);
170}
171
172
173/*-------------------------------------------------
174    bitbanger_tune_value
175-------------------------------------------------*/
176static float bitbanger_tune_value(device_t *device)
177{
178   bitbanger_token *bi = get_token(device);
179   static const float tunes[] = {0.97f, 0.9825f, 0.985f, 0.9875f, 0.99f, 0.9925f, 0.995f, 0.9975f, 1.0f,
180                  1.0025f, 1.005f, 1.0075f, 1.01f, 1.0125f, 1.015f, 1.0175f, 1.02f};
181
182   return(tunes[bi->tune]);
183}
184
185
186/*-------------------------------------------------
187    bitbanger_baud_value
188-------------------------------------------------*/
189
190static UINT32 bitbanger_baud_value(device_t *device)
191{
192   bitbanger_token *bi = get_token(device);
193   static const float bauds[] = { 150.0f, 300.0f, 600.0f, 1200.0f, 2400.0f, 4800.0f, 9600.0f,
194            14400.0f, 28800.0f, 38400.0f, 57600.0f, 115200.0f};
195   float result = bitbanger_tune_value(device) * bauds[bi->baud];
196   return (UINT32)result;
197}
198
199
200/*-------------------------------------------------
201    bitbanger_baud_string
202-------------------------------------------------*/
203
204const char *bitbanger_baud_string(device_t *device)
205{
206   bitbanger_token *bi = get_token(device);
207   static const char *const bauds[] = { "150", "300", "600", "1200", "2400", "4800",
208                     "9600", "14400", "28800", "38400", "57600", "115200"};
209
210   return(bauds[bi->baud]);
211}
212
213
214/*-------------------------------------------------
215    bitbanger_inc_baud
216-------------------------------------------------*/
217bool bitbanger_inc_baud(device_t *device, bool test)
218{
219   bitbanger_token *bi = get_token(device);
220   int adjust_baud = (int)bi->baud + 1;
221
222   if( adjust_baud >= BITBANGER_BAUD_MAX )
223      return FALSE;
224
225   if( !test)
226   {
227      bi->baud = adjust_baud;
228      bi->current_baud = ATTOTIME_IN_HZ(bitbanger_baud_value(device));
229   }
230
231   return TRUE;
232}
233
234
235/*-------------------------------------------------
236    bitbanger_dec_baud
237-------------------------------------------------*/
238bool bitbanger_dec_baud(device_t *device, bool test)
239{
240   bitbanger_token *bi = get_token(device);
241   int adjust_baud = bi->baud - 1;
242
243   if( adjust_baud < 0 )
244      return FALSE;
245
246   if( !test)
247   {
248      bi->baud = adjust_baud;
249      bi->current_baud = ATTOTIME_IN_HZ(bitbanger_baud_value(device));
250   }
251
252   return TRUE;
253}
254
255
256/*-------------------------------------------------
257    bitbanger_inc_tune
258-------------------------------------------------*/
259bool bitbanger_inc_tune(device_t *device, bool test)
260{
261   bitbanger_token *bi = get_token(device);
262   int adjust_tune = (int)bi->tune + 1;
263
264   if( adjust_tune >= BITBANGER_TUNE_MAX )
265      return FALSE;
266
267   if( !test)
268   {
269      bi->tune = adjust_tune;
270      bi->current_baud = ATTOTIME_IN_HZ(bitbanger_baud_value(device));
271   }
272
273   return TRUE;
274}
275
276
277/*-------------------------------------------------
278    bitbanger_dec_tune
279-------------------------------------------------*/
280bool bitbanger_dec_tune(device_t *device, bool test)
281{
282   bitbanger_token *bi = get_token(device);
283   int adjust_tune = bi->tune - 1;
284
285   if( adjust_tune < 0 )
286      return FALSE;
287
288   if( !test)
289   {
290      bi->tune = adjust_tune;
291      bi->current_baud = ATTOTIME_IN_HZ(bitbanger_baud_value(device));
292   }
293
294   return TRUE;
295}
296
297
298/*-------------------------------------------------
299    bitbanger_bytes_to_bits_81N
300-------------------------------------------------*/
301static void bitbanger_bytes_to_bits_81N(device_t *img)
302{
303   bitbanger_token *bi = get_token(img);
304   UINT8 byte_buffer[100];
305   UINT32 byte_buffer_size, bit_buffer_size;
306   int i, j;
307   static const UINT8 bitmask[8] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
308
309   bit_buffer_size = 0;
310   byte_buffer_size = native_input(img, byte_buffer, sizeof(byte_buffer));
311
312   /* Translate byte buffer into bit buffer using: 1 start bit, 8 data bits, 1 stop bit, no parity */
313
314   for( i=0; i<byte_buffer_size; i++ )
315   {
316      bi->input_buffer[bit_buffer_size++] = 0;
317
318      for( j=0; j<8; j++ )
319      {
320         if( byte_buffer[i] & bitmask[j] )
321            bi->input_buffer[bit_buffer_size++] = 1;
322         else
323            bi->input_buffer[bit_buffer_size++] = 0;
324      }
325
326      bi->input_buffer[bit_buffer_size++] = 1;
327   }
328
329   bi->input_buffer_size = bit_buffer_size;
330   bi->input_buffer_cursor = 0;
331}
332
333
334/*-------------------------------------------------
335    DEVICE_START(bitbanger)
336-------------------------------------------------*/
337
338static DEVICE_START(bitbanger)
339{
340   bitbanger_token *bi;
341   const bitbanger_config *config = get_config(device);
342
343   bi = get_token(device);
344
345   /* output config */
346   bi->build_count = 0;
347   bi->bitbanger_output_timer = timer_alloc(device->machine, bitbanger_output_timer, (void *) device);
348
349   /* input config */
350   bi->bitbanger_input_timer = timer_alloc(device->machine, bitbanger_input_timer, (void *) device );
351   bi->idle_delay = ATTOTIME_IN_SEC(1);
352   bi->input_buffer_size = 0;
353   bi->input_buffer_cursor = 0;
354
355   bi->mode = config->default_mode;
356   bi->baud = config->default_baud;
357   bi->tune = config->default_tune;
358   bi->current_baud = ATTOTIME_IN_HZ(bitbanger_baud_value(device));
359
360   /* test callback */
361   if(!config->input_callback)
362      fatalerror("Misconfigured bitbanger device: input_callback cannot be NULL\n");
363}
364
365
366/*-------------------------------------------------
367    TIMER_CALLBACK(bitbanger_output_timer)
368-------------------------------------------------*/
369
370static TIMER_CALLBACK(bitbanger_output_timer)
371{
372   device_t *device = (device_t *) ptr;
373   bitbanger_token *bi = get_token(device);
374
375   /* this ia harded coded for 8-1-N */
376   if( bi->output_value )
377      bi->build_byte |= 0x200;
378
379   bi->build_byte >>= 1;
380   bi->build_count--;
381
382   if(bi->build_count == 0)
383   {
384      if( bi->output_value == 1 )
385         native_output( device, bi->build_byte );
386      else
387         logerror("Bitbanger: Output framing error.\n" );
388
389      timer_reset(bi->bitbanger_output_timer, attotime_never);
390   }
391}
392
393
394/*-------------------------------------------------
395    TIMER_CALLBACK(bitbanger_input_timer)
396-------------------------------------------------*/
397
398static TIMER_CALLBACK(bitbanger_input_timer)
399{
400   device_t *device = (device_t *) ptr;
401   bitbanger_token *bi = get_token(device);
402   const bitbanger_config *config = get_config(device);
403
404   if(bi->input_buffer_cursor == bi->input_buffer_size)
405   {
406      /* get more data */
407      bitbanger_bytes_to_bits_81N(device);
408
409      if(bi->input_buffer_size == 0)
410      {
411         /* no more data, wait and try again */
412         bi->idle_delay = attotime_min(attotime_add(bi->idle_delay, ATTOTIME_IN_MSEC(100)), ATTOTIME_IN_SEC(1));
413         timer_adjust_oneshot(bi->bitbanger_input_timer, bi->idle_delay, 0);
414
415
416         if( bi->mode == BITBANGER_MODEM )
417            config->input_callback(machine, 1);
418         else
419            config->input_callback(machine, 0);
420
421         return;
422      }
423      else
424      {
425         bi->idle_delay = bi->current_baud;
426         timer_adjust_periodic(bi->bitbanger_input_timer, bi->idle_delay, 0, bi->idle_delay);
427      }
428   }
429
430   /* send bit to driver */
431   config->input_callback(machine, bi->input_buffer[(bi->input_buffer_cursor)++]);
432}
433
434
435/*-------------------------------------------------
436    bitbanger_output - outputs data to a bitbanger
437    port
438-------------------------------------------------*/
439
440void bitbanger_output(device_t *device, int value)
441{
442   bitbanger_token *bi = get_token(device);
443   attotime one_point_five_baud;
444
445   if( bi->build_count == 0 && bi->output_value == 1 && value == 0 )
446   {
447      /* we found our start bit */
448      /* eight bits of data, plus one of stop */
449      bi->build_count = 9;
450      bi->build_byte = 0;
451
452      one_point_five_baud = attotime_add(bi->current_baud, attotime_div(bi->current_baud,2));
453      timer_adjust_periodic(bi->bitbanger_output_timer, one_point_five_baud, 0, bi->current_baud);
454   }
455
456   //fprintf(stderr,"%s, %d\n", attotime_string(timer_get_time(device->machine),9), value);
457   bi->output_value = value;
458}
459
460
461/*-------------------------------------------------
462    DEVICE_IMAGE_LOAD( bitbanger )
463-------------------------------------------------*/
464
465static DEVICE_IMAGE_LOAD( bitbanger )
466{
467   device_t *device = &image.device();
468   bitbanger_token *bi;
469   bi = get_token(device);
470
471   timer_enable(bi->bitbanger_input_timer, TRUE);
472   timer_adjust_periodic(bi->bitbanger_input_timer, attotime_zero, 0, ATTOTIME_IN_SEC(1));
473
474   /* we don't need to do anything special */
475   return IMAGE_INIT_PASS;
476}
477
478
479/*-------------------------------------------------
480    DEVICE_IMAGE_UNLOAD( bitbanger )
481-------------------------------------------------*/
482
483static DEVICE_IMAGE_UNLOAD( bitbanger )
484{
485   device_t *device = &image.device();
486   bitbanger_token *bi;
487   bi = get_token(device);
488
489   timer_enable(bi->bitbanger_input_timer, FALSE);
490}
491
492
493/*-------------------------------------------------
494    DEVICE_GET_INFO(bitbanger) - device getinfo
495    function
496-------------------------------------------------*/
497
498DEVICE_GET_INFO(bitbanger)
499{
500   switch(state)
501   {
502      /* --- the following bits of info are returned as 64-bit signed integers --- */
503      case DEVINFO_INT_TOKEN_BYTES:               info->i = sizeof(bitbanger_token); break;
504      case DEVINFO_INT_INLINE_CONFIG_BYTES:         info->i = 0; break;
505      case DEVINFO_INT_IMAGE_TYPE:               info->i = IO_PRINTER; break;
506      case DEVINFO_INT_IMAGE_READABLE:            info->i = 1; break;
507      case DEVINFO_INT_IMAGE_WRITEABLE:            info->i = 1; break;
508      case DEVINFO_INT_IMAGE_CREATABLE:            info->i = 1; break;
509
510      /* --- the following bits of info are returned as pointers to data or functions --- */
511      case DEVINFO_FCT_START:                     info->start = DEVICE_START_NAME(bitbanger); break;
512      case DEVINFO_FCT_IMAGE_LOAD:               info->f = (genf *) DEVICE_IMAGE_LOAD_NAME(bitbanger);      break;
513      case DEVINFO_FCT_IMAGE_UNLOAD:               info->f = (genf *) DEVICE_IMAGE_UNLOAD_NAME(bitbanger);   break;
514
515      /* --- the following bits of info are returned as NULL-terminated strings --- */
516      case DEVINFO_STR_NAME:                     strcpy(info->s, "Bitbanger"); break;
517      case DEVINFO_STR_FAMILY:                  strcpy(info->s, "Bitbanger"); break;
518      case DEVINFO_STR_SOURCE_FILE:               strcpy(info->s, __FILE__); break;
519      case DEVINFO_STR_IMAGE_FILE_EXTENSIONS:         strcpy(info->s, "prn"); break;
520   }
521}
522
523DEFINE_LEGACY_IMAGE_DEVICE(BITBANGER, bitbanger);
src/emu/imagedev/printer.h
r0r9928
1/****************************************************************************
2
3    printer.h
4
5    Code for handling printer devices
6
7****************************************************************************/
8
9#ifndef __PRINTER_H__
10#define __PRINTER_H__
11
12#include "image.h"
13
14
15/***************************************************************************
16    TYPE DEFINITIONS
17***************************************************************************/
18
19typedef void (*online_func)(device_t *device, int state);
20
21typedef struct _printer_config printer_config;
22struct _printer_config
23{
24   online_func online;
25};
26
27
28DECLARE_LEGACY_IMAGE_DEVICE(PRINTER, printer);
29
30
31#define MCFG_PRINTER_ADD(_tag) \
32   MCFG_DEVICE_ADD(_tag, PRINTER, 0) \
33
34#define MCFG_PRINTER_ONLINE(_online) \
35   MCFG_DEVICE_CONFIG_DATAPTR(printer_config, online, _online)
36
37
38/***************************************************************************
39    FUNCTION PROTOTYPES
40***************************************************************************/
41
42/* checks to see if a printer is ready */
43int printer_is_ready(device_t *printer);
44
45/* outputs data to a printer */
46void printer_output(device_t *printer, UINT8 data);
47
48#endif /* __PRINTER_H__ */
src/emu/imagedev/cassimg.h
r0r9928
1/*********************************************************************
2
3    cassimg.h
4
5    Cassette tape image abstraction code
6
7*********************************************************************/
8
9#ifndef CASSIMG_H
10#define CASSIMG_H
11
12#include "pool.h"
13#include "emu.h"
14
15/***************************************************************************
16
17    Constants
18
19***************************************************************************/
20
21#define CASSETTE_FLAG_READWRITE         0
22#define CASSETTE_FLAG_READONLY         1
23#define CASSETTE_FLAG_NOSAVEONEXIT      0
24#define CASSETTE_FLAG_SAVEONEXIT      2
25
26#define CASSETTE_WAVEFORM_8BIT         0
27#define CASSETTE_WAVEFORM_16BIT         2
28#define CASSETTE_WAVEFORM_16BIT_FLIP   3
29#define CASSETTE_WAVEFORM_32BIT         4
30#define CASSETTE_WAVEFORM_32BIT_FLIP   5
31#define CASSETTE_WAVEFORM_ENDIAN_FLIP   1
32
33#define CASSETTE_MODULATION_SQUAREWAVE   0
34#define CASSETTE_MODULATION_SINEWAVE   1
35
36
37#ifdef LSB_FIRST
38#define CASSETTE_WAVEFORM_16BITBE      CASSETTE_WAVEFORM_16BIT_FLIP
39#define CASSETTE_WAVEFORM_16BITLE      CASSETTE_WAVEFORM_16BIT
40#define CASSETTE_WAVEFORM_32BITBE      CASSETTE_WAVEFORM_32BIT_FLIP
41#define CASSETTE_WAVEFORM_32BITLE      CASSETTE_WAVEFORM_32BIT
42#else
43#define CASSETTE_WAVEFORM_16BITBE      CASSETTE_WAVEFORM_16BIT
44#define CASSETTE_WAVEFORM_16BITLE      CASSETTE_WAVEFORM_16BIT_FLIP
45#define CASSETTE_WAVEFORM_32BITBE      CASSETTE_WAVEFORM_32BIT
46#define CASSETTE_WAVEFORM_32BITLE      CASSETTE_WAVEFORM_32BIT_FLIP
47#endif
48
49
50/***************************************************************************
51
52    Type definitions
53
54***************************************************************************/
55
56typedef enum
57{
58   CASSETTE_ERROR_SUCCESS,         /* no error */
59   CASSETTE_ERROR_INTERNAL,      /* fatal internal error */
60   CASSETTE_ERROR_UNSUPPORTED,      /* this operation is unsupported */
61   CASSETTE_ERROR_OUTOFMEMORY,      /* ran out of memory */
62   CASSETTE_ERROR_INVALIDIMAGE,   /* invalid image */
63   CASSETTE_ERROR_INVALIDARG
64}
65casserr_t;
66
67struct sample_block
68{
69   INT32 *block;
70   size_t sample_count;
71};
72
73struct CassetteOptions
74{
75   int channels;
76   int bits_per_sample;
77   UINT32 sample_frequency;
78};
79
80struct CassetteInfo
81{
82   int channels;
83   int bits_per_sample;
84   UINT32 sample_frequency;
85   size_t sample_count;
86};
87
88struct _cassette_image
89{
90   const struct CassetteFormat *format;
91   struct io_generic io;
92   object_pool *pool;
93
94   int channels;
95   int flags;
96   UINT32 sample_frequency;
97
98   struct sample_block *blocks;
99   size_t block_count;
100   size_t sample_count;
101
102   running_machine *machine;
103};
104
105typedef struct _cassette_image cassette_image;
106
107struct CassetteFormat
108{
109   const char *extensions;
110   casserr_t (*identify)(cassette_image *cassette, struct CassetteOptions *opts);
111   casserr_t (*load)(cassette_image *cassette);
112   casserr_t (*save)(cassette_image *cassette, const struct CassetteInfo *info);
113};
114
115/* used for the core modulation code */
116struct CassetteModulation
117{
118   int flags;
119   double zero_frequency_low;
120   double zero_frequency_cannonical;
121   double zero_frequency_high;
122   double one_frequency_low;
123   double one_frequency_cannonical;
124   double one_frequency_high;
125};
126
127/* code to adapt existing legacy fill_wave functions */
128struct CassetteLegacyWaveFiller
129{
130   int (*fill_wave)(INT16 *, int, UINT8 *);
131   int chunk_size;
132   int chunk_samples;
133   int (*chunk_sample_calc)(const UINT8 *bytes, int length);
134   UINT32 sample_frequency;
135   int header_samples;
136   int trailer_samples;
137};
138
139/* builtin formats */
140extern const struct CassetteFormat wavfile_format;
141
142/* macros for specifying format lists */
143#define CASSETTE_FORMATLIST_EXTERN(name)   \
144   extern const struct CassetteFormat *const name[]
145
146#define CASSETTE_FORMATLIST_START(name)      \
147   const struct CassetteFormat *const name[] =   \
148   {                              \
149      &wavfile_format,               \
150
151#define CASSETTE_FORMAT(name)            \
152      &(name),                     \
153
154#define CASSETTE_FORMATLIST_END            \
155      NULL                        \
156   };
157
158CASSETTE_FORMATLIST_EXTERN(cassette_default_formats);
159
160/***************************************************************************
161
162    Prototypes
163
164***************************************************************************/
165
166casserr_t cassette_open(running_machine *machine,void *file, const struct io_procs *procs,
167   const struct CassetteFormat *format, int flags, cassette_image **outcassette);
168casserr_t cassette_open_choices(running_machine *machine,void *file, const struct io_procs *procs, const char *extension,
169   const struct CassetteFormat *const *formats, int flags, cassette_image **outcassette);
170casserr_t cassette_create(running_machine *machine,void *file, const struct io_procs *procs, const struct CassetteFormat *format,
171   const struct CassetteOptions *opts, int flags, cassette_image **outcassette);
172casserr_t cassette_save(cassette_image *cassette);
173void cassette_close(cassette_image *cassette);
174void cassette_change(cassette_image *cassette, void *file, const struct io_procs *procs, const struct CassetteFormat *format, int flags);
175void cassette_get_info(cassette_image *cassette, struct CassetteInfo *info);
176
177/* calls for accessing the raw cassette image */
178void cassette_image_read(cassette_image *cassette, void *buffer, UINT64 offset, size_t length);
179void cassette_image_write(cassette_image *cassette, const void *buffer, UINT64 offset, size_t length);
180UINT64 cassette_image_size(cassette_image *cassette);
181
182/* waveform accesses */
183casserr_t cassette_get_samples(cassette_image *cassette, int channel,
184   double time_index, double sample_period, size_t sample_count, size_t sample_bytes,
185   void *samples, int waveform_flags);
186casserr_t cassette_put_samples(cassette_image *cassette, int channel,
187   double time_index, double sample_period, size_t sample_count, size_t sample_bytes,
188   const void *samples, int waveform_flags);
189casserr_t cassette_get_sample(cassette_image *cassette, int channel,
190   double time_index, double sample_period, INT32 *sample);
191casserr_t cassette_put_sample(cassette_image *cassette, int channel,
192   double time_index, double sample_period, INT32 sample);
193
194/* waveform accesses to/from the raw image */
195casserr_t cassette_read_samples(cassette_image *cassette, int channels, double time_index,
196   double sample_period, size_t sample_count, UINT64 offset, int waveform_flags);
197casserr_t cassette_write_samples(cassette_image *cassette, int channels, double time_index,
198   double sample_period, size_t sample_count, UINT64 offset, int waveform_flags);
199
200/* modulation support */
201casserr_t cassette_modulation_identify(cassette_image *cassette, const struct CassetteModulation *modulation,
202   struct CassetteOptions *opts);
203casserr_t cassette_put_modulated_data(cassette_image *cassette, int channel, double time_index,
204   const void *data, size_t data_length, const struct CassetteModulation *modulation,
205   double *time_displacement);
206casserr_t cassette_put_modulated_filler(cassette_image *cassette, int channel, double time_index,
207   UINT8 filler, size_t filler_length, const struct CassetteModulation *modulation,
208   double *time_displacement);
209casserr_t cassette_read_modulated_data(cassette_image *cassette, int channel, double time_index,
210   UINT64 offset, UINT64 length, const struct CassetteModulation *modulation,
211   double *time_displacement);
212casserr_t cassette_put_modulated_data_bit(cassette_image *cassette, int channel, double time_index,
213   UINT8 data, const struct CassetteModulation *modulation,
214   double *time_displacement);
215
216/* debug calls */
217void cassette_dump(cassette_image *image, const char *filename);
218
219/* legacy code support */
220#define CODE_HEADER    ((UINT8*)-1)
221#define CODE_TRAILER   ((UINT8*)-2)
222casserr_t cassette_legacy_identify(cassette_image *cassette, struct CassetteOptions *opts,
223   const struct CassetteLegacyWaveFiller *legacy_args);
224casserr_t cassette_legacy_construct(cassette_image *cassette,
225   const struct CassetteLegacyWaveFiller *legacy_args);
226
227#endif /* CASSIMG_H */
src/emu/imagedev/cartslot.c
r0r9928
1/**********************************************************************
2
3    cartslot.c
4
5    Cartridge device
6
7**********************************************************************/
8
9#include <ctype.h>
10#include "emu.h"
11#include "cartslot.h"
12#include "multcart.h"
13
14/***************************************************************************
15    CONSTANTS
16***************************************************************************/
17
18enum _process_mode
19{
20   PROCESS_CLEAR,
21   PROCESS_LOAD
22};
23typedef enum _process_mode process_mode;
24
25
26/***************************************************************************
27    INLINE FUNCTIONS
28***************************************************************************/
29
30INLINE cartslot_t *get_token(device_t *device)
31{
32   assert(device != NULL);
33   assert(device->type() == CARTSLOT);
34   return (cartslot_t *) downcast<legacy_device_base *>(device)->token();
35}
36
37
38INLINE const cartslot_config *get_config(device_t *device)
39{
40   assert(device != NULL);
41   assert(device->type() == CARTSLOT);
42   return (const cartslot_config *) downcast<const legacy_device_config_base &>(device->baseconfig()).inline_config();
43}
44
45INLINE const cartslot_config *get_config_dev(const device_config *device)
46{
47   assert(device != NULL);
48   assert(device->type() == CARTSLOT);
49   return (const cartslot_config *)downcast<const legacy_device_config_base *>(device)->inline_config();
50}
51
52/***************************************************************************
53    IMPLEMENTATION
54***************************************************************************/
55
56/*-------------------------------------------------
57    load_cartridge
58-------------------------------------------------*/
59
60static int load_cartridge(device_image_interface *image, const rom_entry *romrgn, const rom_entry *roment, process_mode mode)
61{
62   const char *region;
63   const char *type;
64   UINT32 flags;
65   offs_t offset, length, read_length, pos = 0, len;
66   UINT8 *ptr;
67   UINT8 clear_val;
68   int datawidth, littleendian, i, j;
69   device_t *cpu;
70
71   region = ROMREGION_GETTAG(romrgn);
72   offset = ROM_GETOFFSET(roment);
73   length = ROM_GETLENGTH(roment);
74   flags = ROM_GETFLAGS(roment);
75   ptr = ((UINT8 *) image->device().machine->region(region)->base()) + offset;
76
77   if (mode == PROCESS_LOAD)
78   {
79      if (image->software_entry() == NULL)
80      {
81         /* must this be full size */
82         if (flags & ROM_FULLSIZE)
83         {
84            if (image->length() != length)
85               return IMAGE_INIT_FAIL;
86         }
87
88         /* read the ROM */
89         pos = read_length = image->fread(ptr, length);
90
91         /* reset the ROM to the initial point. */
92         /* eventually, we could add a flag to allow the ROM to continue instead of restarting whenever a new cart region is present */
93         image->fseek(0, SEEK_SET);
94      }
95      else
96      {
97         /* must this be full size */
98         if (flags & ROM_FULLSIZE)
99         {
100            if (image->get_software_region_length("rom") != length)
101               return IMAGE_INIT_FAIL;
102         }
103
104         /* read the ROM */
105         pos = read_length = image->get_software_region_length("rom");
106         memcpy(ptr, image->get_software_region("rom"), read_length);
107      }
108
109      /* do we need to mirror the ROM? */
110      if (flags & ROM_MIRROR)
111      {
112         while(pos < length)
113         {
114            len = MIN(read_length, length - pos);
115            memcpy(ptr + pos, ptr, len);
116            pos += len;
117         }
118      }
119
120      /* postprocess this region */
121      type = ROMREGION_GETTAG(romrgn);
122      littleendian = ROMREGION_ISLITTLEENDIAN(romrgn);
123      datawidth = ROMREGION_GETWIDTH(romrgn) / 8;
124
125      /* if the region is inverted, do that now */
126      device_memory_interface *memory;
127      cpu = image->device().machine->device(type);
128      if (cpu!=NULL && cpu->interface(memory))
129      {
130         datawidth = device_memory(cpu)->space_config(AS_PROGRAM)->m_databus_width / 8;
131         littleendian = (device_memory(cpu)->space_config()->m_endianness == ENDIANNESS_LITTLE);
132      }
133
134      /* swap the endianness if we need to */
135#ifdef LSB_FIRST
136      if (datawidth > 1 && !littleendian)
137#else
138      if (datawidth > 1 && littleendian)
139#endif
140      {
141         for (i = 0; i < length; i += datawidth)
142         {
143            UINT8 temp[8];
144            memcpy(temp, &ptr[i], datawidth);
145            for (j = datawidth - 1; j >= 0; j--)
146               ptr[i + j] = temp[datawidth - 1 - j];
147         }
148      }
149   }
150
151   /* clear out anything that remains */
152   if (!(flags & ROM_NOCLEAR))
153   {
154      clear_val = (flags & ROM_FILL_FF) ? 0xFF : 0x00;
155      memset(ptr + pos, clear_val, length - pos);
156   }
157   return IMAGE_INIT_PASS;
158}
159
160
161
162/*-------------------------------------------------
163    process_cartridge
164-------------------------------------------------*/
165
166static int process_cartridge(device_image_interface *image, process_mode mode)
167{
168   const rom_source *source;
169   const rom_entry *romrgn, *roment;
170   int result = 0;
171
172   for (source = rom_first_source(*image->device().machine->config); source != NULL; source = rom_next_source(*source))
173   {
174      for (romrgn = rom_first_region(*source); romrgn != NULL; romrgn = rom_next_region(romrgn))
175      {
176         roment = romrgn + 1;
177         while(!ROMENTRY_ISREGIONEND(roment))
178         {
179            if (ROMENTRY_GETTYPE(roment) == ROMENTRYTYPE_CARTRIDGE)
180            {
181               if (strcmp(roment->_hashdata,image->device().tag())==0)
182               {
183                  result |= load_cartridge(image, romrgn, roment, mode);
184
185                  /* if loading failed in any cart region, stop loading */
186                  if (result)
187                     return result;
188               }
189            }
190            roment++;
191         }
192      }
193   }
194
195   return IMAGE_INIT_PASS;
196}
197
198
199/*-------------------------------------------------
200    cartslot_get_pcb
201-------------------------------------------------*/
202
203device_t *cartslot_get_pcb(device_t *device)
204{
205   cartslot_t *cart = get_token(device);
206   return cart->pcb_device;
207}
208
209
210/*-------------------------------------------------
211    cartslot_get_socket
212-------------------------------------------------*/
213
214void *cartslot_get_socket(device_t *device, const char *socket_name)
215{
216   cartslot_t *cart = get_token(device);
217   device_image_interface *image = dynamic_cast<device_image_interface *>(device);
218   void *result = NULL;
219
220   if (cart->mc != NULL)
221   {
222      const multicart_socket *socket;
223      for (socket = cart->mc->sockets; socket != NULL; socket = socket->next)
224      {
225         if (!strcmp(socket->id, socket_name))
226            break;
227      }
228      result = socket ? socket->ptr : NULL;
229   }
230   else if (socket_name[0] == '\0')
231   {
232      result = image->ptr();
233   }
234   return result;
235}
236
237/*-------------------------------------------------
238    cartslot_get_resource_length
239-------------------------------------------------*/
240
241int cartslot_get_resource_length(device_t *device, const char *socket_name)
242{
243   cartslot_t *cart = get_token(device);
244   int result = 0;
245
246   if (cart->mc != NULL)
247   {
248      const multicart_socket *socket;
249
250      for (socket = cart->mc->sockets; socket != NULL; socket = socket->next)
251      {
252         if (!strcmp(socket->id, socket_name)) {
253            break;
254         }
255      }
256      if (socket != NULL)
257         result = socket->resource->length;
258   }
259   else
260      result = 0;
261
262   return result;
263}
264
265
266/*-------------------------------------------------
267    DEVICE_START( cartslot )
268-------------------------------------------------*/
269
270static DEVICE_START( cartslot )
271{
272   cartslot_t *cart = get_token(device);
273   const cartslot_config *config = get_config(device);
274
275   /* if this cartridge has a custom DEVICE_START, use it */
276   if (config->device_start != NULL)
277   {
278      (*config->device_start)(device);
279      goto done;
280   }
281
282   /* find the PCB (if there is one) */
283   cart->pcb_device = device->subdevice(TAG_PCB);
284
285done:
286   return;
287}
288
289
290/*-------------------------------------------------
291    DEVICE_IMAGE_LOAD( cartslot )
292-------------------------------------------------*/
293
294static DEVICE_IMAGE_LOAD( cartslot )
295{
296   int result;
297   device_t *device = &image.device();
298   cartslot_t *cart = get_token(device);
299   const cartslot_config *config = get_config(device);
300
301   /* if this cartridge has a custom DEVICE_IMAGE_LOAD, use it */
302   if (config->device_load != NULL)
303      return (*config->device_load)(image);
304
305   /* try opening this as if it were a multicart */
306   multicart_open(image.filename(), device->machine->gamedrv->name, MULTICART_FLAGS_LOAD_RESOURCES, &cart->mc);
307   if (cart->mc == NULL)
308   {
309
310
311      /* otherwise try the normal route */
312      result = process_cartridge(&image, PROCESS_LOAD);
313      if (result != IMAGE_INIT_PASS)
314         return result;
315   }
316
317   return IMAGE_INIT_PASS;
318}
319
320
321/*-------------------------------------------------
322    DEVICE_IMAGE_UNLOAD( cartslot )
323-------------------------------------------------*/
324
325static DEVICE_IMAGE_UNLOAD( cartslot )
326{
327   device_t *device = &image.device();
328   cartslot_t *cart = get_token(device);
329   const cartslot_config *config = get_config(device);
330
331   /* if this cartridge has a custom DEVICE_IMAGE_UNLOAD, use it */
332   if (config->device_unload != NULL)
333   {
334      (*config->device_unload)(image);
335      return;
336   }
337
338   if (cart->mc != NULL)
339   {
340      multicart_close(cart->mc);
341      cart->mc = NULL;
342   }
343
344   process_cartridge(&image, PROCESS_CLEAR);
345}
346
347
348/*-------------------------------------------------
349    identify_pcb
350-------------------------------------------------*/
351
352static const cartslot_pcb_type *identify_pcb(device_image_interface &image)
353{
354   const cartslot_config *config = get_config(&image.device());
355   astring pcb_name;
356   const cartslot_pcb_type *pcb_type = NULL;
357   multicart_t *mc;
358   int i;
359
360   if (image.software_entry() == NULL && image.exists())
361   {
362      /* try opening this as if it were a multicart */
363      multicart_open_error me = multicart_open(image.filename(), image.device().machine->gamedrv->name, MULTICART_FLAGS_DONT_LOAD_RESOURCES, &mc);
364      if (me == MCERR_NONE)
365      {
366         /* this was a multicart - read from it */
367         astring_cpyc(&pcb_name, mc->pcb_type);
368         multicart_close(mc);
369      }
370      else
371      {
372         if (me != MCERR_NOT_MULTICART)
373            fatalerror("multicart error: %s", multicart_error_text(me));
374         
375         /* Force fetching of image metadata */
376         image.crc();
377         
378         if (image.pcb() != NULL)
379         {
380            /* read from hash file */
381            astring_cpyc(&pcb_name, image.pcb());
382         }
383      }
384
385      /* look for PCB type with matching name */
386      for (i = 0; (i < ARRAY_LENGTH(config->pcb_types)) && (config->pcb_types[i].name != NULL); i++)
387      {
388         if ((config->pcb_types[i].name[0] == '\0') || !strcmp(astring_c(&pcb_name), config->pcb_types[i].name))
389         {
390            pcb_type = &config->pcb_types[i];
391            break;
392         }
393      }
394
395      /* check for unknown PCB type */
396      if ((mc != NULL) && (pcb_type == NULL))
397         fatalerror("Unknown PCB type \"%s\"", astring_c(&pcb_name));
398   }
399   else
400   {
401      /* no device loaded; use the default */
402      pcb_type = (config->pcb_types[0].name != NULL) ? &config->pcb_types[0] : NULL;
403   }
404   return pcb_type;
405}
406
407/*-------------------------------------------------
408    DEVICE_IMAGE_GET_DEVICES(cartslot)
409-------------------------------------------------*/
410static DEVICE_IMAGE_GET_DEVICES(cartslot)
411{
412   const cartslot_pcb_type *pcb_type;
413   device_t *device = &image.device();
414
415   pcb_type = identify_pcb(image);
416   if (pcb_type != NULL)
417   {
418      image_add_device_with_subdevices(device,pcb_type->devtype,TAG_PCB,0);
419   }
420}
421
422/*-------------------------------------------------
423    DEVICE_IMAGE_SOFTLIST_LOAD(cartslot)
424-------------------------------------------------*/
425static DEVICE_IMAGE_SOFTLIST_LOAD(cartslot)
426{
427   load_software_part_region( &image.device(), swlist, swname, start_entry );
428   return TRUE;
429}
430
431/*-------------------------------------------------
432    DEVICE_GET_INFO( cartslot )
433-------------------------------------------------*/
434
435DEVICE_GET_INFO( cartslot )
436{
437   switch(state)
438   {
439      /* --- the following bits of info are returned as 64-bit signed integers --- */
440      case DEVINFO_INT_TOKEN_BYTES:            info->i = sizeof(cartslot_t); break;
441      case DEVINFO_INT_INLINE_CONFIG_BYTES:      info->i = sizeof(cartslot_config); break;
442      case DEVINFO_INT_IMAGE_TYPE:            info->i = IO_CARTSLOT; break;
443      case DEVINFO_INT_IMAGE_READABLE:         info->i = 1; break;
444      case DEVINFO_INT_IMAGE_WRITEABLE:         info->i = 0; break;
445      case DEVINFO_INT_IMAGE_CREATABLE:         info->i = 0; break;
446      case DEVINFO_INT_IMAGE_RESET_ON_LOAD:      info->i = 1; break;
447      case DEVINFO_INT_IMAGE_MUST_BE_LOADED:
448         if ( device && downcast<const legacy_image_device_config_base *>(device)->inline_config()) {
449            info->i = get_config_dev(device)->must_be_loaded;
450         } else {
451            info->i = 0;
452         }
453         break;
454
455      /* --- the following bits of info are returned as pointers to functions --- */
456      case DEVINFO_FCT_START:                  info->start = DEVICE_START_NAME(cartslot);               break;
457      case DEVINFO_FCT_IMAGE_LOAD:            info->f = (genf *) DEVICE_IMAGE_LOAD_NAME(cartslot);      break;
458      case DEVINFO_FCT_IMAGE_UNLOAD:            info->f = (genf *) DEVICE_IMAGE_UNLOAD_NAME(cartslot);      break;
459      case DEVINFO_FCT_IMAGE_GET_DEVICES:         info->f = (genf *) DEVICE_IMAGE_GET_DEVICES_NAME(cartslot);   break;
460      case DEVINFO_FCT_IMAGE_SOFTLIST_LOAD:      info->f = (genf *) DEVICE_IMAGE_SOFTLIST_LOAD_NAME(cartslot);   break;
461      case DEVINFO_FCT_IMAGE_PARTIAL_HASH:
462         if ( device && downcast<const legacy_image_device_config_base *>(device)->inline_config() && get_config_dev(device)->device_partialhash) {
463            info->f = (genf *) get_config_dev(device)->device_partialhash;
464         } else {
465            info->f = NULL;
466         }
467         break;
468
469      /* --- the following bits of info are returned as NULL-terminated strings --- */
470      case DEVINFO_STR_NAME:                  strcpy(info->s, "Cartslot"); break;
471      case DEVINFO_STR_FAMILY:               strcpy(info->s, "Cartslot"); break;
472      case DEVINFO_STR_SOURCE_FILE:            strcpy(info->s, __FILE__); break;
473      case DEVINFO_STR_IMAGE_FILE_EXTENSIONS:
474         if ( device && downcast<const legacy_image_device_config_base *>(device)->inline_config() && get_config_dev(device)->extensions )
475         {
476            strcpy(info->s, get_config_dev(device)->extensions);
477         }
478         else
479         {
480            strcpy(info->s, "bin");
481         }
482         break;
483      case DEVINFO_STR_IMAGE_INTERFACE:
484         if ( device && downcast<const legacy_image_device_config_base *>(device)->inline_config() && get_config_dev(device)->interface )
485         {
486            strcpy(info->s, get_config_dev(device)->interface );
487         }
488         break;
489   }
490}
491
492DEFINE_LEGACY_IMAGE_DEVICE(CARTSLOT, cartslot);
493
494
495//**************************************************************************
496//  DEVICE CONFIG CARTSLOT INTERFACE
497//**************************************************************************
498
499//-------------------------------------------------
500//  device_config_cart_slot_interface - constructor
501//-------------------------------------------------
502
503device_config_cart_slot_interface::device_config_cart_slot_interface(const machine_config &mconfig, device_config &devconfig)
504   : device_config_interface(mconfig, devconfig)
505{
506}
507
508
509//-------------------------------------------------
510//  ~device_config_cart_slot_interface - destructor
511//-------------------------------------------------
512
513device_config_cart_slot_interface::~device_config_cart_slot_interface()
514{
515}
516
517
518
519//**************************************************************************
520//  DEVICE CARTSLOT INTERFACE
521//**************************************************************************
522
523//-------------------------------------------------
524//  device_cart_slot_interface - constructor
525//-------------------------------------------------
526
527device_cart_slot_interface::device_cart_slot_interface(running_machine &machine, const device_config &config, device_t &device)
528   : device_interface(machine, config, device),
529     m_cart_slot_config(dynamic_cast<const device_config_cart_slot_interface &>(config))
530{
531}
532
533
534//-------------------------------------------------
535//  ~device_cart_slot_interface - destructor
536//-------------------------------------------------
537
538device_cart_slot_interface::~device_cart_slot_interface()
539{
540}
541
542//**************************************************************************
543//  LEGACY cart_slot DEVICE CONFIGURATION
544//**************************************************************************
545
546//-------------------------------------------------
547//  legacy_cart_slot_device_config_base - constructor
548//-------------------------------------------------
549
550legacy_cart_slot_device_config_base::legacy_cart_slot_device_config_base(const machine_config &mconfig, device_type type, const char *tag, const device_config *owner, UINT32 clock, device_get_config_func get_config)
551   : legacy_device_config_base(mconfig, type, tag, owner, clock, get_config),
552     device_config_cart_slot_interface(mconfig, *this)
553{
554}
555
556
557//**************************************************************************
558//  LIVE LEGACY cart_slot DEVICE
559//**************************************************************************
560
561//-------------------------------------------------
562//  legacy_cart_slot_device_base - constructor
563//-------------------------------------------------
564
565legacy_cart_slot_device_base::legacy_cart_slot_device_base(running_machine &machine, const device_config &config)
566   : legacy_device_base(machine, config),
567     device_cart_slot_interface(machine, config, *this)
568{
569}
src/emu/imagedev/multcart.c
r0r9928
1/*********************************************************************
2
3    multcart.c
4
5    Multi-cartridge handling code
6
7*********************************************************************/
8
9#include "multcart.h"
10#include "pool.h"
11#include "unzip.h"
12#include "corestr.h"
13#include "xmlfile.h"
14#include "emu.h"
15#include "hash.h"
16#include "machine/ram.h"
17
18/***************************************************************************
19    TYPE DEFINITIONS
20***************************************************************************/
21
22struct _multicart_private
23{
24   object_pool *   pool;
25   zip_file *      zip;
26};
27
28
29typedef struct _multicart_load_state multicart_load_state;
30struct _multicart_load_state
31{
32   multicart_t *         multicart;
33   zip_file *         zip;
34   xml_data_node *         layout_xml;
35   xml_data_node *         resources_node;
36   xml_data_node *         pcb_node;
37   multicart_resource *      resources;
38   multicart_socket *      sockets;
39};
40
41static const char error_text[14][30] =
42{
43   "no error",
44   "not a multicart",
45   "module definition corrupt",
46   "out of memory",
47   "xml format error",
48   "invalid file reference",
49   "zip file error",
50   "missing ram length",
51   "invalid ram specification",
52   "unknown resource type",
53   "invalid resource reference",
54   "invalid file format",
55   "missing layout",
56   "no pcb or resource found"
57};
58
59const char *multicart_error_text(multicart_open_error error)
60{
61   return error_text[(int)error];
62}
63
64/***************************************************************************
65    IMPLEMENTATION
66***************************************************************************/
67
68/*-------------------------------------------------
69    find_file
70-------------------------------------------------*/
71
72static const zip_file_header *find_file(zip_file *zip, const char *filename)
73{
74   const zip_file_header *header;
75   for (header = zip_file_first_file(zip); header != NULL; header = zip_file_next_file(zip))
76   {
77      if (!core_stricmp(header->filename, filename))
78         return header;
79   }
80   return NULL;
81}
82
83static const zip_file_header *find_file_crc(zip_file *zip, const char *filename, UINT32 crc)
84{
85   const zip_file_header *header;
86   for (header = zip_file_first_file(zip); header != NULL; header = zip_file_next_file(zip))
87   {
88      // if the CRC and name both match, we're good
89      // if the CRC matches and the name doesn't, we're still good
90      if ((!core_stricmp(header->filename, filename)) && (header->crc == crc))
91      {
92         return header;
93      }
94      else if (header->crc == crc)
95      {
96         return header;
97      }
98   }
99   return NULL;
100}
101
102/*-------------------------------------------------
103    find_pcb_and_resource_nodes
104-------------------------------------------------*/
105
106static int find_pcb_and_resource_nodes(xml_data_node *layout_xml,
107   xml_data_node **pcb_node, xml_data_node **resource_node)
108{
109   xml_data_node *romset_node;
110   xml_data_node *configuration_node;
111
112   *pcb_node = NULL;
113   *resource_node = NULL;
114
115   romset_node = xml_get_sibling(layout_xml->child, "romset");
116   if (romset_node == NULL)
117      return FALSE;
118
119   configuration_node = xml_get_sibling(romset_node->child, "configuration");
120   if (configuration_node == NULL)
121      return FALSE;
122
123   *pcb_node = xml_get_sibling(configuration_node->child, "pcb");
124   if (*pcb_node == NULL)
125      return FALSE;
126
127   *resource_node = xml_get_sibling(romset_node->child, "resources");
128   if (*resource_node == NULL)
129      return FALSE;
130
131   return TRUE;
132}
133
134
135/*-------------------------------------------------
136    get_resource_type
137-------------------------------------------------*/
138
139static multicart_resource_type get_resource_type(const char *s)
140{
141   multicart_resource_type result;
142   if (!strcmp(s, "rom"))
143      result = MULTICART_RESOURCE_TYPE_ROM;
144   else if (!strcmp(s, "ram"))
145      result = MULTICART_RESOURCE_TYPE_RAM;
146   else
147      result = MULTICART_RESOURCE_TYPE_INVALID;
148   return result;
149}
150
151
152/*-------------------------------------------------
153    load_rom_resource
154-------------------------------------------------*/
155
156static multicart_open_error load_rom_resource(multicart_load_state *state, xml_data_node *resource_node,
157   multicart_resource *resource)
158{
159   const char *file, *crcstr, *sha1;
160   const zip_file_header *header;
161   zip_error ziperr;
162   UINT32 crc;
163
164   /* locate the 'file' attribute */
165   file = xml_get_attribute_string(resource_node, "file", NULL);
166   if (file == NULL)
167      return MCERR_XML_ERROR;
168
169   if (!(crcstr = xml_get_attribute_string(resource_node, "crc", NULL)))
170   {
171      /* locate the file in the ZIP file */
172      header = find_file(state->zip, file);
173   }
174   else   /* CRC tag is present, use it */
175   {
176      crc = strtoul(crcstr, NULL, 16);
177      header = find_file_crc(state->zip, file, crc);
178   }
179   if (header == NULL)
180      return MCERR_INVALID_FILE_REF;
181   resource->length = header->uncompressed_length;
182
183   /* allocate bytes for this resource */
184   resource->ptr = pool_malloc_lib(state->multicart->data->pool, resource->length);
185   if (resource->ptr == NULL)
186      return MCERR_OUT_OF_MEMORY;
187
188   /* and decompress it */
189   ziperr = zip_file_decompress(state->zip, resource->ptr, resource->length);
190   if (ziperr != ZIPERR_NONE)
191      return MCERR_ZIP_ERROR;
192
193   /* check SHA1 now */
194   if ((sha1 = xml_get_attribute_string(resource_node, "sha1", NULL)))
195   {
196      char calc_sha[256];
197
198      memset(calc_sha, 0, sizeof(calc_sha));
199      hash_compute(&calc_sha[0], (const unsigned char*)resource->ptr, resource->length, HASH_SHA1);
200
201      if ((strncmp(sha1, &calc_sha[2], 20)))
202      {
203         return MCERR_INVALID_FILE_REF;
204      }
205   }
206
207   return MCERR_NONE;
208}
209
210
211/*-------------------------------------------------
212    load_ram_resource
213-------------------------------------------------*/
214
215static multicart_open_error load_ram_resource(multicart_load_state *state, xml_data_node *resource_node,
216   multicart_resource *resource)
217{
218   const char *length_string;
219   const char *ram_type;
220   const char *ram_filename;
221
222   astring *ram_pathname;
223
224   /* locate the 'length' attribute */
225   length_string = xml_get_attribute_string(resource_node, "length", NULL);
226   if (length_string == NULL)
227      return MCERR_MISSING_RAM_LENGTH;
228
229   /* ...and parse it */
230   resource->length = ram_parse_string(length_string);
231   if (resource->length <= 0)
232      return MCERR_INVALID_RAM_SPEC;
233
234   /* allocate bytes for this resource */
235   resource->ptr = pool_malloc_lib(state->multicart->data->pool, resource->length);
236   if (resource->ptr == NULL)
237      return MCERR_OUT_OF_MEMORY;
238
239   /* Is this a persistent RAM resource? Then try to load it. */
240   ram_type = xml_get_attribute_string(resource_node, "type", NULL);
241   if (ram_type != NULL)
242   {
243      if (strcmp(ram_type, "persistent")==0)
244      {
245         astring tmp;
246
247         /* Get the file name. */
248         ram_filename = xml_get_attribute_string(resource_node, "file", NULL);
249         if (ram_filename==NULL)
250            return MCERR_XML_ERROR;
251
252         ram_pathname = astring_assemble_3(&tmp, state->multicart->gamedrv_name, PATH_SEPARATOR, ram_filename);
253
254         /* Save the file name so that we can write the contents on unloading.
255               If the RAM resource has no filename, we know that it was volatile only. */
256         resource->filename = pool_strdup_lib(state->multicart->data->pool, astring_c(ram_pathname));
257
258         if (resource->filename == NULL)
259            return MCERR_OUT_OF_MEMORY;
260
261         image_battery_load_by_name(resource->filename, resource->ptr, resource->length, 0x00);
262      }
263      /* else this type is volatile, in which case we just have
264            a memory expansion */
265   }
266   return MCERR_NONE;
267}
268
269
270/*-------------------------------------------------
271    load_resource
272-------------------------------------------------*/
273
274static multicart_open_error load_resource(multicart_load_state *state, xml_data_node *resource_node,
275   multicart_resource_type resource_type)
276{
277   const char *id;
278   multicart_open_error err;
279   multicart_resource *resource;
280   multicart_resource **next_resource;
281
282   /* get the 'id' attribute; error if not present */
283   id = xml_get_attribute_string(resource_node, "id", NULL);
284   if (id == NULL)
285      return MCERR_XML_ERROR;
286
287   /* allocate memory for the resource */
288   resource = (multicart_resource *)pool_malloc_lib(state->multicart->data->pool, sizeof(*resource));
289   if (resource == NULL)
290      return MCERR_OUT_OF_MEMORY;
291   memset(resource, 0, sizeof(*resource));
292   resource->type = resource_type;
293
294   /* copy id */
295   resource->id = pool_strdup_lib(state->multicart->data->pool, id);
296   if (resource->id == NULL)
297      return MCERR_OUT_OF_MEMORY;
298
299   switch(resource->type)
300   {
301      case MULTICART_RESOURCE_TYPE_ROM:
302         err = load_rom_resource(state, resource_node, resource);
303         if (err != MCERR_NONE)
304            return err;
305         break;
306
307      case MULTICART_RESOURCE_TYPE_RAM:
308         err = load_ram_resource(state, resource_node, resource);
309         if (err != MCERR_NONE)
310            return err;
311         break;
312
313      default:
314         return MCERR_UNKNOWN_RESOURCE_TYPE;
315   }
316
317   /* append the resource */
318   for (next_resource = &state->resources; *next_resource; next_resource = &(*next_resource)->next)
319      ;
320   *next_resource = resource;
321
322   return MCERR_NONE;
323}
324
325
326/*-------------------------------------------------
327    load_all_resources
328-------------------------------------------------*/
329
330static multicart_open_error load_all_resources(multicart_load_state *state)
331{
332   multicart_open_error err;
333   xml_data_node *resource_node;
334   multicart_resource_type resource_type;
335
336   for (resource_node = state->resources_node->child; resource_node != NULL; resource_node = resource_node->next)
337   {
338      resource_type = get_resource_type(resource_node->name);
339      if (resource_type != MULTICART_RESOURCE_TYPE_INVALID)
340      {
341         err = load_resource(state, resource_node, resource_type);
342         if (err != MCERR_NONE)
343            return err;
344      }
345   }
346
347   state->multicart->resources = state->resources;
348   return MCERR_NONE;
349}
350
351/*-------------------------------------------------
352    save_ram_resources. This is important for persistent RAM. All
353    resources were allocated within the memory pool of this device and will
354    be freed on multicart_close.
355-------------------------------------------------*/
356
357static multicart_open_error save_ram_resources(multicart_t *cart)
358{
359   const multicart_resource *resource;
360
361   for (resource = cart->resources; resource != NULL; resource = resource->next)
362   {
363      if ((resource->type == MULTICART_RESOURCE_TYPE_RAM) && (resource->filename != NULL))
364      {
365         image_battery_save_by_name(resource->filename, resource->ptr, resource->length);
366      }
367   }
368   return MCERR_NONE;
369}
370
371/*-------------------------------------------------
372    load_socket
373-------------------------------------------------*/
374
375static multicart_open_error load_socket(multicart_load_state *state, xml_data_node *socket_node)
376{
377   const char *id;
378   const char *uses;
379   const multicart_resource *resource;
380   multicart_socket *socket;
381   multicart_socket **next_socket;
382
383   /* get the 'id' and 'uses' attributes; error if not present */
384   id = xml_get_attribute_string(socket_node, "id", NULL);
385   uses = xml_get_attribute_string(socket_node, "uses", NULL);
386   if ((id == NULL) || (uses == NULL))
387      return MCERR_XML_ERROR;
388
389   /* find the resource */
390   for (resource = state->multicart->resources; resource != NULL; resource = resource->next)
391   {
392      if (!strcmp(uses, resource->id))
393         break;
394   }
395   if (resource == NULL)
396      return MCERR_INVALID_RESOURCE_REF;
397
398   /* create the socket */
399   socket = (multicart_socket *)pool_malloc_lib(state->multicart->data->pool, sizeof(*socket));
400   if (socket == NULL)
401      return MCERR_OUT_OF_MEMORY;
402   memset(socket, 0, sizeof(*socket));
403   socket->resource = resource;
404   socket->ptr = resource->ptr;
405
406   /* copy id */
407   socket->id = pool_strdup_lib(state->multicart->data->pool, id);
408   if (socket->id == NULL)
409      return MCERR_OUT_OF_MEMORY;
410
411   /* which pointer should I use? */
412   if (resource->ptr != NULL)
413   {
414      /* use the resource's ptr */
415      socket->ptr = resource->ptr;
416   }
417   else
418   {
419      /* allocate bytes for this socket */
420      socket->ptr = pool_malloc_lib(state->multicart->data->pool, resource->length);
421      if (socket->ptr == NULL)
422         return MCERR_OUT_OF_MEMORY;
423
424      /* ...and clear it */
425      memset(socket->ptr, 0xCD, resource->length);
426   }
427
428   /* append the resource */
429   for (next_socket = &state->sockets; *next_socket; next_socket = &(*next_socket)->next)
430      ;
431   *next_socket = socket;
432
433   return MCERR_NONE;
434}
435
436
437/*-------------------------------------------------
438    load_all_sockets
439-------------------------------------------------*/
440
441static multicart_open_error load_all_sockets(multicart_load_state *state)
442{
443   multicart_open_error err;
444   xml_data_node *socket_node;
445
446   for (socket_node = xml_get_sibling(state->pcb_node->child, "socket"); socket_node != NULL;
447      socket_node = xml_get_sibling(socket_node->next, "socket"))
448   {
449      err = load_socket(state, socket_node);
450      if (err != MCERR_NONE)
451         return err;
452   }
453
454   state->multicart->sockets = state->sockets;
455   return MCERR_NONE;
456}
457
458
459/*-------------------------------------------------
460    multicart_open - opens a multicart
461-------------------------------------------------*/
462
463multicart_open_error multicart_open(const char *filename, const char *gamedrv, multicart_load_flags load_flags, multicart_t **cart)
464{
465   multicart_open_error err;
466   zip_error ziperr;
467   object_pool *pool;
468   multicart_load_state state = {0, };
469   const zip_file_header *header;
470   const char *pcb_type;
471   char *layout_text = NULL;
472
473   /* allocate an object pool */
474   pool = pool_alloc_lib(NULL);
475   if (pool == NULL)
476   {
477      err = MCERR_OUT_OF_MEMORY;
478      goto done;
479   }
480
481   /* allocate the multicart */
482   state.multicart = (multicart_t*)pool_malloc_lib(pool, sizeof(*state.multicart));
483   if (state.multicart == NULL)
484   {
485      err = MCERR_OUT_OF_MEMORY;
486      goto done;
487   }
488   memset(state.multicart, 0, sizeof(*state.multicart));
489
490   /* allocate the multicart's private data */
491   state.multicart->data = (multicart_private*)pool_malloc_lib(pool, sizeof(*state.multicart->data));
492   if (state.multicart->data == NULL)
493   {
494      err = MCERR_OUT_OF_MEMORY;
495      goto done;
496   }
497   memset(state.multicart->data, 0, sizeof(*state.multicart->data));
498   state.multicart->data->pool = pool;
499   pool = NULL;
500
501   /* open the ZIP file */
502   ziperr = zip_file_open(filename, &state.zip);
503   if (ziperr != ZIPERR_NONE)
504   {
505      err = MCERR_NOT_MULTICART;
506      goto done;
507   }
508
509   /* find the layout.xml file */
510   header = find_file(state.zip, "layout.xml");
511   if (header == NULL)
512   {
513      err = MCERR_MISSING_LAYOUT;
514      goto done;
515   }
516
517   /* reserve space for the layout text */
518   layout_text = (char*)malloc(header->uncompressed_length + 1);
519   if (layout_text == NULL)
520   {
521      err = MCERR_OUT_OF_MEMORY;
522      goto done;
523   }
524
525   /* uncompress the layout text */
526   ziperr = zip_file_decompress(state.zip, layout_text, header->uncompressed_length);
527   if (ziperr != ZIPERR_NONE)
528   {
529      err = MCERR_ZIP_ERROR;
530      goto done;
531   }
532   layout_text[header->uncompressed_length] = '\0';
533
534   /* parse the layout text */
535   state.layout_xml = xml_string_read(layout_text, NULL);
536   if (state.layout_xml == NULL)
537   {
538      err = MCERR_XML_ERROR;
539      goto done;
540   }
541
542   /* locate the PCB node */
543   if (!find_pcb_and_resource_nodes(state.layout_xml, &state.pcb_node, &state.resources_node))
544   {
545      err = MCERR_NO_PCB_OR_RESOURCES;
546      goto done;
547   }
548
549   /* get the PCB resource_type */
550   pcb_type = xml_get_attribute_string(state.pcb_node, "type", "");
551   state.multicart->pcb_type = pool_strdup_lib(state.multicart->data->pool, pcb_type);
552   if (state.multicart->pcb_type == NULL)
553   {
554      err = MCERR_OUT_OF_MEMORY;
555      goto done;
556   }
557
558   state.multicart->gamedrv_name = pool_strdup_lib(state.multicart->data->pool, gamedrv);
559   if (state.multicart->gamedrv_name == NULL)
560   {
561      err = MCERR_OUT_OF_MEMORY;
562      goto done;
563   }
564
565   /* do we have to load resources? */
566   if (load_flags & MULTICART_FLAGS_LOAD_RESOURCES)
567   {
568      err = load_all_resources(&state);
569      if (err != MCERR_NONE)
570         goto done;
571
572      err = load_all_sockets(&state);
573      if (err != MCERR_NONE)
574         goto done;
575   }
576
577   err = MCERR_NONE;
578
579done:
580   if (pool != NULL)
581      pool_free_lib(pool);
582   if (state.zip != NULL)
583      zip_file_close(state.zip);
584   if (layout_text != NULL)
585      free(layout_text);
586   if (state.layout_xml != NULL)
587      xml_file_free(state.layout_xml);
588
589   if ((err != MCERR_NONE) && (state.multicart != NULL))
590   {
591      multicart_close(state.multicart);
592      state.multicart = NULL;
593   }
594   *cart = state.multicart;
595   return err;
596}
597
598
599/*-------------------------------------------------
600    multicart_close - closes a multicart
601-------------------------------------------------*/
602
603void multicart_close(multicart_t *cart)
604{
605   save_ram_resources(cart);
606   pool_free_lib(cart->data->pool);
607}
src/emu/imagedev/snapquik.c
r0r9928
1/*********************************************************************
2
3    snapquik.h
4
5    Snapshots and quickloads
6
7*********************************************************************/
8
9#include "emu.h"
10#include "snapquik.h"
11
12/***************************************************************************
13    TYPE DEFINITIONS
14***************************************************************************/
15
16typedef struct _snapquick_token snapquick_token;
17struct _snapquick_token
18{
19   emu_timer *timer;
20   snapquick_load_func load;
21};
22
23
24
25/***************************************************************************
26    INLINE FUNCTIONS
27***************************************************************************/
28
29/*-------------------------------------------------
30    assert_is_snapshot_or_quickload - asserts/confirms
31    that a given device is a snapshot or quickload
32-------------------------------------------------*/
33
34INLINE void assert_is_snapshot_or_quickload(device_t *device)
35{
36   assert(device != NULL);
37   assert(downcast<const legacy_device_config_base &>(device->baseconfig()).inline_config() != NULL);
38   assert((device->type() == SNAPSHOT) || (device->type() == QUICKLOAD)
39      || (device->type() == Z80BIN));
40}
41
42
43
44/*-------------------------------------------------
45    get_token - safely gets the snapshot/quickload data
46-------------------------------------------------*/
47
48INLINE snapquick_token *get_token(device_t *device)
49{
50   assert_is_snapshot_or_quickload(device);
51   return (snapquick_token *) downcast<legacy_device_base *>(device)->token();
52}
53
54
55
56/*-------------------------------------------------
57    get_config - safely gets the quickload config
58-------------------------------------------------*/
59
60INLINE const snapquick_config *get_config(device_t *device)
61{
62   assert_is_snapshot_or_quickload(device);
63   return (const snapquick_config *) downcast<const legacy_device_config_base &>(device->baseconfig()).inline_config();
64}
65
66INLINE const snapquick_config *get_config_dev(const device_config *device)
67{
68   assert(device != NULL);
69   assert((device->type() == SNAPSHOT) || (device->type() == QUICKLOAD)
70      || (device->type() == Z80BIN));
71   return (const snapquick_config *) downcast<const legacy_device_config_base *>(device)->inline_config();
72}
73
74/*-------------------------------------------------
75    log_quickload - logs and displays useful
76    data for the end user
77-------------------------------------------------*/
78
79void log_quickload(const char *type, UINT32 start, UINT32 length, UINT32 exec, const char *exec_format)
80{
81    astring tempstring;
82
83    logerror("Loading %04X bytes of RAM at %04X\n", length, start);
84
85    tempstring.catprintf("Quickload type: %s   Length: %d bytes\n", type, length);
86    tempstring.catprintf("Start: 0x%04X   End: 0x%04X   Exec: ", start, start + length - 1);
87
88    logerror("Quickload loaded.\n");
89    if (!mame_stricmp(exec_format, EXEC_NA))
90        tempstring.cat("N/A");
91    else
92    {
93        logerror("Execution can resume with ");
94        logerror(exec_format, exec);
95        logerror("\n");
96        tempstring.catprintf(exec_format, exec);
97    }
98
99    ui_popup_time(10, "%s", tempstring.cstr());
100}
101
102/***************************************************************************
103    IMPLEMENTATION
104***************************************************************************/
105
106/*-------------------------------------------------
107    TIMER_CALLBACK(process_snapshot_or_quickload)
108-------------------------------------------------*/
109
110static TIMER_CALLBACK(process_snapshot_or_quickload)
111{
112   device_image_interface *image = (device_image_interface *) ptr;
113   snapquick_token *token = get_token(&image->device());
114
115   /* invoke the load */
116   (*token->load)(*image,
117      image->filetype(),
118      image->length());
119
120   /* unload the device */
121   image->unload();
122}
123
124
125
126/*-------------------------------------------------
127    DEVICE_START( snapquick )
128-------------------------------------------------*/
129
130static DEVICE_START( snapquick )
131{
132   snapquick_token *token = get_token(device);
133
134   /* allocate a timer */
135   token->timer = timer_alloc(device->machine, process_snapshot_or_quickload, (void *) dynamic_cast<device_image_interface *>(device));
136
137}
138
139
140
141/*-------------------------------------------------
142    DEVICE_IMAGE_LOAD( snapquick )
143-------------------------------------------------*/
144
145static DEVICE_IMAGE_LOAD( snapquick )
146{
147   const snapquick_config *config = get_config(image);
148   snapquick_token *token = get_token(image);
149
150   /* locate the load function */
151   token->load = (snapquick_load_func) reinterpret_cast<snapquick_load_func>(image.get_device_specific_call());
152
153   /* adjust the timer */
154   timer_adjust_oneshot(
155      token->timer,
156      attotime_make(config->delay_seconds, config->delay_attoseconds),
157      0);
158
159   return IMAGE_INIT_PASS;
160}
161
162
163
164/*-------------------------------------------------
165    DEVICE_GET_INFO(snapquick) - device getinfo
166    function
167-------------------------------------------------*/
168
169static DEVICE_GET_INFO(snapquick)
170{
171   switch(state)
172   {
173      /* --- the following bits of info are returned as 64-bit signed integers --- */
174      case DEVINFO_INT_TOKEN_BYTES:               info->i = sizeof(snapquick_token); break;
175      case DEVINFO_INT_INLINE_CONFIG_BYTES:         info->i = sizeof(snapquick_config); break;
176      case DEVINFO_INT_IMAGE_READABLE:            info->i = 1; break;
177      case DEVINFO_INT_IMAGE_WRITEABLE:            info->i = 0; break;
178      case DEVINFO_INT_IMAGE_CREATABLE:            info->i = 0; break;
179
180      /* --- the following bits of info are returned as pointers to functions --- */
181      case DEVINFO_FCT_START:                     info->start = DEVICE_START_NAME(snapquick); break;
182      case DEVINFO_FCT_IMAGE_LOAD:               info->f = (genf *) DEVICE_IMAGE_LOAD_NAME(snapquick); break;
183      case DEVINFO_FCT_SNAPSHOT_QUICKLOAD_LOAD:      info->f = (genf *) get_config_dev(device)->load; break;
184
185      /* --- the following bits of info are returned as NULL-terminated strings --- */
186      case DEVINFO_STR_SOURCE_FILE:               strcpy(info->s, __FILE__); break;
187      case DEVINFO_STR_IMAGE_FILE_EXTENSIONS:         strcpy(info->s, get_config_dev(device)->file_extensions); break;
188   }
189}
190
191
192
193/*-------------------------------------------------
194    DEVICE_GET_INFO(snapshot) - device getinfo
195    function
196-------------------------------------------------*/
197
198DEVICE_GET_INFO(snapshot)
199{
200   switch(state)
201   {
202      /* --- the following bits of info are returned as 64-bit signed integers --- */
203      case DEVINFO_INT_IMAGE_TYPE:               info->i = IO_SNAPSHOT; break;
204
205      /* --- the following bits of info are returned as NULL-terminated strings --- */
206      case DEVINFO_STR_NAME:                     strcpy(info->s, "Snapshot"); break;
207      case DEVINFO_STR_FAMILY:                  strcpy(info->s, "Snapshot"); break;
208
209      default: DEVICE_GET_INFO_CALL(snapquick); break;
210   }
211}
212
213
214
215/*-------------------------------------------------
216    DEVICE_GET_INFO(quickload) - device getinfo
217    function
218-------------------------------------------------*/
219
220DEVICE_GET_INFO(quickload)
221{
222   switch(state)
223   {
224      /* --- the following bits of info are returned as 64-bit signed integers --- */
225      case DEVINFO_INT_IMAGE_TYPE:               info->i = IO_QUICKLOAD; break;
226
227      /* --- the following bits of info are returned as NULL-terminated strings --- */
228      case DEVINFO_STR_NAME:                     strcpy(info->s, "Quickload"); break;
229      case DEVINFO_STR_FAMILY:                  strcpy(info->s, "Quickload"); break;
230
231      default: DEVICE_GET_INFO_CALL(snapquick); break;
232   }
233}
234/*-------------------------------------------------
235    z80bin_load_file - load a z80bin file into
236    memory
237-------------------------------------------------*/
238
239static int z80bin_load_file(device_image_interface *image, const char *file_type, UINT16 *exec_addr, UINT16 *start_addr, UINT16 *end_addr )
240{
241   int ch;
242   UINT16 args[3];
243   UINT16 i=0, j, size;
244   UINT8 data;
245   char pgmname[256];
246   char message[256];
247
248   image->fseek(7, SEEK_SET);
249
250   while((ch = image->fgetc()) != 0x1A)
251   {
252      if (ch == EOF)
253      {
254         image->seterror(IMAGE_ERROR_INVALIDIMAGE, "Unexpected EOF while getting file name");
255         image->message(" Unexpected EOF while getting file name");
256         return IMAGE_INIT_FAIL;
257      }
258
259      if (ch != '\0')
260      {
261         if (i >= (ARRAY_LENGTH(pgmname) - 1))
262         {
263            image->seterror(IMAGE_ERROR_INVALIDIMAGE, "File name too long");
264            image->message(" File name too long");
265            return IMAGE_INIT_FAIL;
266         }
267
268         pgmname[i] = ch;   /* build program name */
269         i++;
270      }
271   }
272
273   pgmname[i] = '\0';   /* terminate string with a null */
274
275   if (image->fread(args, sizeof(args)) != sizeof(args))
276   {
277      image->seterror(IMAGE_ERROR_INVALIDIMAGE, "Unexpected EOF while getting file size");
278      image->message(" Unexpected EOF while getting file size");
279      return IMAGE_INIT_FAIL;
280   }
281
282   exec_addr[0] = LITTLE_ENDIANIZE_INT16(args[0]);
283   start_addr[0] = LITTLE_ENDIANIZE_INT16(args[1]);
284   end_addr[0]   = LITTLE_ENDIANIZE_INT16(args[2]);
285
286   size = (end_addr[0] - start_addr[0] + 1) & 0xffff;
287
288   /* display a message about the loaded quickload */
289   image->message(" %s\nsize=%04X : start=%04X : end=%04X : exec=%04X",pgmname,size,start_addr[0],end_addr[0],exec_addr[0]);
290
291   for (i = 0; i < size; i++)
292   {
293      j = (start_addr[0] + i) & 0xffff;
294      if (image->fread(&data, 1) != 1)
295      {
296         snprintf(message, ARRAY_LENGTH(message), "%s: Unexpected EOF while writing byte to %04X", pgmname, (unsigned) j);
297         image->seterror(IMAGE_ERROR_INVALIDIMAGE, message);
298         image->message("%s: Unexpected EOF while writing byte to %04X", pgmname, (unsigned) j);
299         return IMAGE_INIT_FAIL;
300      }
301      cputag_get_address_space(image->device().machine,"maincpu",ADDRESS_SPACE_PROGRAM)->write_byte(j, data);
302   }
303
304   return IMAGE_INIT_PASS;
305}
306
307
308
309/*-------------------------------------------------
310    QUICKLOAD_LOAD( z80bin )
311-------------------------------------------------*/
312
313static QUICKLOAD_LOAD( z80bin )
314{
315   const z80bin_config *config;
316   UINT16 exec_addr, start_addr, end_addr;
317   int autorun;
318
319   /* load the binary into memory */
320   if (z80bin_load_file(&image, file_type, &exec_addr, &start_addr, &end_addr) == IMAGE_INIT_FAIL)
321      return IMAGE_INIT_FAIL;
322
323   /* is this file executable? */
324   if (exec_addr != 0xffff)
325   {
326      config = (const z80bin_config *)downcast<const legacy_device_config_base &>(image.device().baseconfig()).inline_config();
327
328      /* check to see if autorun is on (I hate how this works) */
329      autorun = input_port_read_safe(image.device().machine, "CONFIG", 0xFF) & 1;
330
331      /* start program */
332      if (config->execute != NULL)
333      {
334         (*config->execute)(image.device().machine, start_addr, end_addr, exec_addr, autorun);
335      }
336      else
337      {
338         if (autorun)
339            cpu_set_reg(image.device().machine->device("maincpu"), STATE_GENPC, exec_addr);
340      }
341   }
342
343   return IMAGE_INIT_PASS;
344}
345
346
347
348/*-------------------------------------------------
349    DEVICE_GET_INFO(z80bin)
350-------------------------------------------------*/
351
352DEVICE_GET_INFO(z80bin)
353{
354   /* quickload */
355   switch(state)
356   {
357      /* --- the following bits of info are returned as 64-bit signed integers --- */
358      case DEVINFO_INT_INLINE_CONFIG_BYTES:         info->i = sizeof(z80bin_config); break;
359
360      /* --- the following bits of info are returned as NULL-terminated strings --- */
361      case DEVINFO_STR_SOURCE_FILE:               strcpy(info->s, __FILE__); break;
362      case DEVINFO_STR_IMAGE_FILE_EXTENSIONS:         strcpy(info->s, "bin"); break;
363
364      /* --- the following bits of info are returned as pointers to functions --- */
365      case DEVINFO_FCT_SNAPSHOT_QUICKLOAD_LOAD:      info->f = (genf *) quickload_load_z80bin; break;
366
367      default:   DEVICE_GET_INFO_CALL(quickload); break;
368   }
369}
370
371DEFINE_LEGACY_IMAGE_DEVICE(Z80BIN, z80bin);
372DEFINE_LEGACY_IMAGE_DEVICE(SNAPSHOT, snapshot);
373DEFINE_LEGACY_IMAGE_DEVICE(QUICKLOAD, quickload);
src/emu/imagedev/bitbngr.h
r0r9928
1/*********************************************************************
2
3    bitbngr.h
4
5    TRS style "bitbanger" serial port
6
7*********************************************************************/
8
9#ifndef __BITBNGR_H__
10#define __BITBNGR_H__
11
12#include "image.h"
13
14
15enum
16{
17   BITBANGER_PRINTER         = 0,
18   BITBANGER_MODEM,
19   BITBANGER_MODE_MAX,
20
21   BITBANGER_150            = 0,
22   BITBANGER_300,
23   BITBANGER_600,
24   BITBANGER_1200,
25   BITBANGER_2400,
26   BITBANGER_4800,
27   BITBANGER_9600,
28   BITBANGER_14400,
29   BITBANGER_28800,
30   BITBANGER_38400,
31   BITBANGER_57600,
32   BITBANGER_115200,
33   BITBANGER_BAUD_MAX,
34
35   BITBANGER_NEG40PERCENT  = 0,
36   BITBANGER_NEG35PERCENT,
37   BITBANGER_NEG30PERCENT,
38   BITBANGER_NEG25PERCENT,
39   BITBANGER_NEG20PERCENT,
40   BITBANGER_NEG15PERCENT,
41   BITBANGER_NEG10PERCENT,
42   BITBANGER_NEG5PERCENT,
43   BITBANGER_0PERCENT,
44   BITBANGER_POS5PERCENT,
45   BITBANGER_POS10PERCENT,
46   BITBANGER_POS15PERCENT,
47   BITBANGER_POS20PERCENT,
48   BITBANGER_POS25PERCENT,
49   BITBANGER_POS30PERCENT,
50   BITBANGER_POS35PERCENT,
51   BITBANGER_POS40PERCENT,
52   BITBANGER_TUNE_MAX
53};
54
55/***************************************************************************
56    CONSTANTS
57***************************************************************************/
58DECLARE_LEGACY_IMAGE_DEVICE(BITBANGER, bitbanger);
59
60#define MCFG_BITBANGER_ADD(_tag, _intrf) \
61   MCFG_DEVICE_ADD(_tag, BITBANGER, 0) \
62   MCFG_DEVICE_CONFIG(_intrf)
63
64
65/***************************************************************************
66    TYPE DEFINITIONS
67***************************************************************************/
68
69typedef struct _bitbanger_config bitbanger_config;
70struct _bitbanger_config
71{
72   /* callback to driver */
73   void (*input_callback)(running_machine *machine, UINT8 bit);
74   int default_mode;                  /* emulating a printer or modem */
75   int default_baud;                  /* output bits per second */
76   int default_tune;                /* fine tune adjustment to the baud */
77};
78
79
80
81/***************************************************************************
82    FUNCTION PROTOTYPES
83***************************************************************************/
84
85/* outputs data to a bitbanger port */
86void bitbanger_output(device_t *device, int value);
87
88/* ui functions */
89const char *bitbanger_mode_string(device_t *device);
90const char *bitbanger_baud_string(device_t *device);
91const char *bitbanger_tune_string(device_t *device);
92bool bitbanger_inc_mode(device_t *device, bool test);
93bool bitbanger_dec_mode(device_t *device, bool test);
94bool bitbanger_inc_tune(device_t *device, bool test);
95bool bitbanger_dec_tune(device_t *device, bool test);
96bool bitbanger_inc_baud(device_t *device, bool test);
97bool bitbanger_dec_baud(device_t *device, bool test);
98
99#endif /* __BITBNGR_H__ */
src/emu/imagedev/flopimg.c
r0r9928
1/*********************************************************************
2
3    flopimg.c
4
5    Floppy disk image abstraction code
6
7*********************************************************************/
8
9#include <stdlib.h>
10#include <string.h>
11#include <stdio.h>
12#include <ctype.h>
13#include <assert.h>
14#include <limits.h>
15
16#include "osdepend.h"
17#include "flopimg.h"
18#include "pool.h"
19#include "imageutl.h"
20
21#define TRACK_LOADED      0x01
22#define TRACK_DIRTY         0x02
23
24
25struct _floppy_image
26{
27   struct io_generic io;
28
29   const struct FloppyFormat *floppy_option;
30   struct FloppyCallbacks format;
31
32   /* loaded track stuff */
33   int loaded_track_head;
34   int loaded_track_index;
35   UINT32 loaded_track_size;
36   void *loaded_track_data;
37   UINT8 loaded_track_status;
38   UINT8 flags;
39
40   /* tagging system */
41   object_pool *tags;
42   void *tag_data;
43};
44
45
46
47struct _floppy_params
48{
49   int param;
50   int value;
51};
52
53
54
55static floperr_t floppy_track_unload(floppy_image *floppy);
56
57OPTION_GUIDE_START(floppy_option_guide)
58   OPTION_INT('H', "heads",         "Heads")
59   OPTION_INT('T', "tracks",         "Tracks")
60   OPTION_INT('S', "sectors",         "Sectors")
61   OPTION_INT('L', "sectorlength",      "Sector Bytes")
62   OPTION_INT('I', "interleave",      "Interleave")
63   OPTION_INT('F', "firstsectorid",   "First Sector")
64OPTION_GUIDE_END
65
66
67static void floppy_close_internal(floppy_image *floppy, int close_file);
68
69/*********************************************************************
70    opening, closing and creating of floppy images
71*********************************************************************/
72
73/* basic floppy_image initialization common to floppy_open() and floppy_create() */
74static floppy_image *floppy_init(void *fp, const struct io_procs *procs, int flags)
75{
76   floppy_image *floppy;
77
78   floppy = (floppy_image *)malloc(sizeof(struct _floppy_image));
79   if (!floppy)
80      return NULL;
81
82   memset(floppy, 0, sizeof(*floppy));
83   floppy->tags = pool_alloc_lib(NULL);
84   floppy->tag_data = NULL;
85   floppy->io.file = fp;
86   floppy->io.procs = procs;
87   floppy->io.filler = 0xFF;
88   floppy->flags = (UINT8) flags;
89   return floppy;
90}
91
92
93
94/* main code for identifying and maybe opening a disk image; not exposed
95 * directly because this function is big and hideous */
96static floperr_t floppy_open_internal(void *fp, const struct io_procs *procs, const char *extension,
97   const struct FloppyFormat *floppy_options, int max_options, int flags, floppy_image **outfloppy,
98   int *outoption)
99{
100   floperr_t err;
101   floppy_image *floppy;
102   int best_option = -1;
103   int best_vote = 0;
104   int vote;
105   size_t i;
106
107   floppy = floppy_init(fp, procs, flags);
108   if (!floppy)
109   {
110      err = FLOPPY_ERROR_OUTOFMEMORY;
111      goto done;
112   }
113
114   /* vote on the best format */
115   for (i = 0; (i < max_options) && floppy_options[i].construct; i++)
116   {
117      if (!extension || !floppy_options[i].extensions || image_find_extension(floppy_options[i].extensions, extension))
118      {
119         if (floppy_options[i].identify)
120         {
121            vote = 0;
122            err = floppy_options[i].identify(floppy, &floppy_options[i], &vote);
123            if (err)
124               goto done;
125         }
126         else
127         {
128            vote = 1;
129         }
130
131         /* is this option a better one? */
132         if (vote > best_vote)
133         {
134            best_vote = vote;
135            best_option = i;
136         }
137      }
138   }
139
140   /* did we find a format? */
141   if (best_option == -1)
142   {
143      err = FLOPPY_ERROR_INVALIDIMAGE;
144      goto done;
145   }
146
147   if (outfloppy)
148   {
149      /* call the format constructor */
150      err = floppy_options[best_option].construct(floppy, &floppy_options[best_option], NULL);
151      if (err)
152         goto done;
153
154      floppy->floppy_option = &floppy_options[best_option];
155   }
156
157   err = FLOPPY_ERROR_SUCCESS;
158
159done:
160   /* if we have a floppy disk and we either errored or are not keeping it, close it */
161   if (floppy && (!outfloppy || err))
162   {
163      floppy_close_internal(floppy, FALSE);
164      floppy = NULL;
165   }
166
167   if (outoption)
168      *outoption = err ? -1 : best_option;
169   if (outfloppy)
170      *outfloppy = floppy;
171   return err;
172}
173
174
175
176floperr_t floppy_identify(void *fp, const struct io_procs *procs, const char *extension,
177   const struct FloppyFormat *formats, int *identified_format)
178{
179   return floppy_open_internal(fp, procs, extension, formats, INT_MAX, FLOPPY_FLAGS_READONLY, NULL, identified_format);
180}
181
182
183
184floperr_t floppy_open(void *fp, const struct io_procs *procs, const char *extension,
185   const struct FloppyFormat *format, int flags, floppy_image **outfloppy)
186{
187   return floppy_open_internal(fp, procs, extension, format, 1, flags, outfloppy, NULL);
188}
189
190
191
192floperr_t floppy_open_choices(void *fp, const struct io_procs *procs, const char *extension,
193   const struct FloppyFormat *formats, int flags, floppy_image **outfloppy)
194{
195   return floppy_open_internal(fp, procs, extension, formats, INT_MAX, flags, outfloppy, NULL);
196}
197
198
199
200static floperr_t option_to_floppy_error(optreserr_t oerr)
201{
202   floperr_t err;
203   switch(oerr) {
204   case OPTIONRESOLUTION_ERROR_SUCCESS:
205      err = FLOPPY_ERROR_SUCCESS;
206      break;
207   case OPTIONRESOLUTION_ERROR_OUTOFMEMORY:
208      err = FLOPPY_ERROR_OUTOFMEMORY;
209      break;
210   case OPTIONRESOLUTION_ERROR_PARAMOUTOFRANGE:
211   case OPTIONRESOLUTION_ERROR_PARAMNOTSPECIFIED:
212   case OPTIONRESOLUTION_ERROR_PARAMNOTFOUND:
213   case OPTIONRESOLUTION_ERROR_PARAMALREADYSPECIFIED:
214   case OPTIONRESOLUTION_ERROR_BADPARAM:
215   case OPTIONRESOLUTION_ERROR_SYNTAX:
216   default:
217      err = FLOPPY_ERROR_INTERNAL;
218      break;
219   };
220   return err;
221}
222
223
224
225floperr_t floppy_create(void *fp, const struct io_procs *procs, const struct FloppyFormat *format, option_resolution *parameters, floppy_image **outfloppy)
226{
227   floppy_image *floppy = NULL;
228   optreserr_t oerr;
229   floperr_t err;
230   int heads, tracks, h, t;
231   option_resolution *alloc_resolution = NULL;
232
233   assert(format);
234
235   /* create the new image */
236   floppy = floppy_init(fp, procs, 0);
237   if (!floppy)
238   {
239      err = FLOPPY_ERROR_OUTOFMEMORY;
240      goto done;
241   }
242
243   /* if this format expects creation parameters and none were specified, create some */
244   if (!parameters && format->param_guidelines)
245   {
246      alloc_resolution = option_resolution_create(floppy_option_guide, format->param_guidelines);
247      if (!alloc_resolution)
248      {
249         err = FLOPPY_ERROR_OUTOFMEMORY;
250         goto done;
251      }
252      parameters = alloc_resolution;
253   }
254
255   /* finish the parameters, if specified */
256   if (parameters)
257   {
258      oerr = option_resolution_finish(parameters);
259      if (oerr)
260      {
261         err = option_to_floppy_error(oerr);
262         goto done;
263      }
264   }
265
266   /* call the format constructor */
267   err = format->construct(floppy, format, parameters);
268   if (err)
269      goto done;
270
271   /* format the disk, ignoring if formatting not implemented */
272   if (floppy->format.format_track)
273   {
274      heads = floppy_get_heads_per_disk(floppy);
275      tracks = floppy_get_tracks_per_disk(floppy);
276
277      for (h = 0; h < heads; h++)
278      {
279         for (t = 0; t < tracks; t++)
280         {
281            err = floppy->format.format_track(floppy, h, t, parameters);
282            if (err)
283               goto done;
284         }
285      }
286   }
287
288   /* call the post_format function, if present */
289   if (floppy->format.post_format)
290   {
291      err = floppy->format.post_format(floppy, parameters);
292      if (err)
293         goto done;
294   }
295
296   floppy->floppy_option = format;
297   err = FLOPPY_ERROR_SUCCESS;
298
299done:
300   if (err && floppy)
301   {
302      floppy_close_internal(floppy, FALSE);
303      floppy = NULL;
304   }
305
306   if (outfloppy)
307      *outfloppy = floppy;
308   else if (floppy)
309      floppy_close_internal(floppy, FALSE);
310
311   if (alloc_resolution)
312      option_resolution_close(alloc_resolution);
313   return err;
314}
315
316
317
318static void floppy_close_internal(floppy_image *floppy, int close_file)
319{
320   if (floppy) {
321      floppy_track_unload(floppy);
322      if (close_file)
323         io_generic_close(&floppy->io);
324      if (floppy->loaded_track_data)
325         free(floppy->loaded_track_data);
326      pool_free_lib(floppy->tags);
327
328      free(floppy);
329   }
330}
331
332
333
334void floppy_close(floppy_image *floppy)
335{
336   floppy_close_internal(floppy, TRUE);
337}
338
339
340
341/*********************************************************************
342    functions useful in format constructors
343*********************************************************************/
344
345struct FloppyCallbacks *floppy_callbacks(floppy_image *floppy)
346{
347   assert(floppy);
348   return &floppy->format;
349}
350
351
352
353void *floppy_tag(floppy_image *floppy)
354{
355   assert(floppy);
356   return floppy->tag_data;
357}
358
359
360
361void *floppy_create_tag(floppy_image *floppy, size_t tagsize)
362{
363   floppy->tag_data = pool_malloc_lib(floppy->tags,tagsize);
364   return floppy->tag_data;
365}
366
367
368
369UINT8 floppy_get_filler(floppy_image *floppy)
370{
371   return floppy->io.filler;
372}
373
374
375
376void floppy_set_filler(floppy_image *floppy, UINT8 filler)
377{
378   floppy->io.filler = filler;
379}
380
381
382
383/*********************************************************************
384    calls for accessing the raw disk image
385*********************************************************************/
386
387void floppy_image_read(floppy_image *floppy, void *buffer, UINT64 offset, size_t length)
388{
389   io_generic_read(&floppy->io, buffer, offset, length);
390}
391
392
393
394void floppy_image_write(floppy_image *floppy, const void *buffer, UINT64 offset, size_t length)
395{
396   io_generic_write(&floppy->io, buffer, offset, length);
397}
398
399
400
401void floppy_image_write_filler(floppy_image *floppy, UINT8 filler, UINT64 offset, size_t length)
402{
403   io_generic_write_filler(&floppy->io, filler, offset, length);
404}
405
406
407
408UINT64 floppy_image_size(floppy_image *floppy)
409{
410   return io_generic_size(&floppy->io);
411}
412
413
414
415/*********************************************************************
416    calls for accessing disk image data
417*********************************************************************/
418
419static floperr_t floppy_readwrite_sector(floppy_image *floppy, int head, int track, int sector, int offset,
420   void *buffer, size_t buffer_len, int writing, int indexed, int ddam)
421{
422   floperr_t err;
423   const struct FloppyCallbacks *fmt;
424   size_t this_buffer_len;
425   UINT8 *alloc_buf = NULL;
426   UINT32 sector_length;
427   UINT8 *buffer_ptr = (UINT8 *)buffer;
428   floperr_t (*read_sector)(floppy_image *floppy, int head, int track, int sector, void *buffer, size_t buflen);
429   floperr_t (*write_sector)(floppy_image *floppy, int head, int track, int sector, const void *buffer, size_t buflen, int ddam);
430
431   fmt = floppy_callbacks(floppy);
432
433   /* choose proper calls for indexed vs non-indexed */
434   if (indexed)
435   {
436      read_sector = fmt->read_indexed_sector;
437      write_sector = fmt->write_indexed_sector;
438      if (!fmt->get_indexed_sector_info)
439      {
440         err = FLOPPY_ERROR_UNSUPPORTED;
441         goto done;
442      }
443   }
444   else
445   {
446      read_sector = fmt->read_sector;
447      write_sector = fmt->write_sector;
448      if (!fmt->get_sector_length)
449      {
450         err = FLOPPY_ERROR_UNSUPPORTED;
451         goto done;
452      }
453   }
454
455   /* check to make sure that the operation is supported */
456   if (!read_sector || (writing && !write_sector))
457   {
458      err = FLOPPY_ERROR_UNSUPPORTED;
459      goto done;
460   }
461
462   /* main loop */
463   while(buffer_len > 0)
464   {
465      /* find out the size of this sector */
466      if (indexed)
467         err = fmt->get_indexed_sector_info(floppy, head, track, sector, NULL, NULL, NULL, &sector_length, NULL);
468      else
469         err = fmt->get_sector_length(floppy, head, track, sector, &sector_length);
470      if (err)
471         goto done;
472
473      /* do we even do anything with this sector? */
474      if (offset < sector_length)
475      {
476         /* ok we will be doing something */
477         if ((offset > 0) || (buffer_len < sector_length))
478         {
479            /* we will be doing an partial read/write; in other words we
480                 * will not be reading/writing a full sector */
481            if (alloc_buf) free(alloc_buf);
482            alloc_buf = (UINT8*)malloc(sector_length);
483            if (!alloc_buf)
484            {
485               err = FLOPPY_ERROR_OUTOFMEMORY;
486               goto done;
487            }
488
489            /* read the sector (we need to do this even when writing */
490            err = read_sector(floppy, head, track, sector, alloc_buf, sector_length);
491            if (err)
492               goto done;
493
494            this_buffer_len = MIN(buffer_len, sector_length - offset);
495
496            if (writing)
497            {
498               memcpy(alloc_buf + offset, buffer_ptr, this_buffer_len);
499
500               err = write_sector(floppy, head, track, sector, alloc_buf, sector_length, ddam);
501               if (err)
502                  goto done;
503            }
504            else
505            {
506               memcpy(buffer_ptr, alloc_buf + offset, this_buffer_len);
507            }
508            offset += this_buffer_len;
509            offset %= sector_length;
510         }
511         else
512         {
513            this_buffer_len = sector_length;
514
515            if (writing)
516               err = write_sector(floppy, head, track, sector, buffer_ptr, sector_length, ddam);
517            else
518               err = read_sector(floppy, head, track, sector, buffer_ptr, sector_length);
519            if (err)
520               goto done;
521         }
522      }
523      else
524      {
525         /* skip this sector */
526         offset -= sector_length;
527         this_buffer_len = 0;
528      }
529
530      buffer_ptr += this_buffer_len;
531      buffer_len -= this_buffer_len;
532      sector++;
533   }
534
535   err = FLOPPY_ERROR_SUCCESS;
536
537done:
538   if (alloc_buf)
539      free(alloc_buf);
540   return err;
541}
542
543
544
545floperr_t floppy_read_sector(floppy_image *floppy, int head, int track, int sector, int offset,   void *buffer, size_t buffer_len)
546{
547   return floppy_readwrite_sector(floppy, head, track, sector, offset, buffer, buffer_len, FALSE, FALSE, 0);
548}
549
550
551
552floperr_t floppy_write_sector(floppy_image *floppy, int head, int track, int sector, int offset, const void *buffer, size_t buffer_len, int ddam)
553{
554   return floppy_readwrite_sector(floppy, head, track, sector, offset, (void *) buffer, buffer_len, TRUE, FALSE, ddam);
555}
556
557
558
559floperr_t floppy_read_indexed_sector(floppy_image *floppy, int head, int track, int sector_index, int offset,   void *buffer, size_t buffer_len)
560{
561   return floppy_readwrite_sector(floppy, head, track, sector_index, offset, buffer, buffer_len, FALSE, TRUE, 0);
562}
563
564
565
566floperr_t floppy_write_indexed_sector(floppy_image *floppy, int head, int track, int sector_index, int offset, const void *buffer, size_t buffer_len, int ddam)
567{
568   return floppy_readwrite_sector(floppy, head, track, sector_index, offset, (void *) buffer, buffer_len, TRUE, TRUE, ddam);
569}
570
571
572static floperr_t floppy_get_track_data_offset(floppy_image *floppy, int head, int track, UINT64 *offset)
573{
574   floperr_t err;
575   const struct FloppyCallbacks *callbacks;
576
577   *offset = 0;
578   callbacks = floppy_callbacks(floppy);
579   if (callbacks->get_track_data_offset)
580   {
581      err = callbacks->get_track_data_offset(floppy, head, track, offset);
582      if (err)
583         return err;
584   }
585   return FLOPPY_ERROR_SUCCESS;
586}
587
588
589
590static floperr_t floppy_read_track_offset(floppy_image *floppy, int head, int track, UINT64 offset, void *buffer, size_t buffer_len)
591{
592   floperr_t err;
593   const struct FloppyCallbacks *format;
594
595   format = floppy_callbacks(floppy);
596
597   if (!format->read_track)
598      return FLOPPY_ERROR_UNSUPPORTED;
599
600   err = floppy_track_unload(floppy);
601   if (err)
602      return err;
603
604   err = format->read_track(floppy, head, track, offset, buffer, buffer_len);
605   if (err)
606      return err;
607
608   return FLOPPY_ERROR_SUCCESS;
609}
610
611
612
613floperr_t floppy_read_track(floppy_image *floppy, int head, int track, void *buffer, size_t buffer_len)
614{
615   return floppy_read_track_offset(floppy, head, track, 0, buffer, buffer_len);
616}
617
618
619
620floperr_t floppy_read_track_data(floppy_image *floppy, int head, int track, void *buffer, size_t buffer_len)
621{
622   floperr_t err;
623   UINT64 offset;
624
625   err = floppy_get_track_data_offset(floppy, head, track, &offset);
626   if (err)
627      return err;
628
629   return floppy_read_track_offset(floppy, head, track, offset, buffer, buffer_len);
630}
631
632
633
634static floperr_t floppy_write_track_offset(floppy_image *floppy, int head, int track, UINT64 offset, const void *buffer, size_t buffer_len)
635{
636   floperr_t err;
637
638   /* track writing supported? */
639   if (!floppy_callbacks(floppy)->write_track)
640      return FLOPPY_ERROR_UNSUPPORTED;
641
642   /* read only? */
643   if (floppy->flags & FLOPPY_FLAGS_READONLY)
644      return FLOPPY_ERROR_READONLY;
645
646   err = floppy_track_unload(floppy);
647   if (err)
648      return err;
649
650   err = floppy_callbacks(floppy)->write_track(floppy, head, track, offset, buffer, buffer_len);
651   if (err)
652      return err;
653
654   return FLOPPY_ERROR_SUCCESS;
655}
656
657
658
659floperr_t floppy_write_track(floppy_image *floppy, int head, int track, const void *buffer, size_t buffer_len)
660{
661   return floppy_write_track_offset(floppy, head, track, 0, buffer, buffer_len);
662}
663
664
665
666floperr_t floppy_write_track_data(floppy_image *floppy, int head, int track, const void *buffer, size_t buffer_len)
667{
668   floperr_t err;
669   UINT64 offset;
670
671   err = floppy_get_track_data_offset(floppy, head, track, &offset);
672   if (err)
673      return err;
674
675   return floppy_write_track_offset(floppy, head, track, offset, buffer, buffer_len);
676}
677
678
679
680floperr_t floppy_format_track(floppy_image *floppy, int head, int track, option_resolution *parameters)
681{
682   floperr_t err;
683   struct FloppyCallbacks *format;
684   option_resolution *alloc_resolution = NULL;
685   optreserr_t oerr;
686
687   /* supported? */
688   format = floppy_callbacks(floppy);
689   if (!format->format_track)
690   {
691      err = FLOPPY_ERROR_UNSUPPORTED;
692      goto done;
693   }
694
695   /* create a dummy resolution; if no parameters were specified */
696   if (!parameters)
697   {
698      alloc_resolution = option_resolution_create(floppy_option_guide, floppy->floppy_option->param_guidelines);
699      if (!alloc_resolution)
700      {
701         err = FLOPPY_ERROR_OUTOFMEMORY;
702         goto done;
703      }
704      parameters = alloc_resolution;
705   }
706
707   oerr = option_resolution_finish(parameters);
708   if (oerr)
709   {
710      err = option_to_floppy_error(oerr);
711      goto done;
712   }
713
714   err = format->format_track(floppy, head, track, parameters);
715   if (err)
716      goto done;
717
718done:
719   if (alloc_resolution)
720      option_resolution_close(alloc_resolution);
721   return err;
722}
723
724
725
726int floppy_get_tracks_per_disk(floppy_image *floppy)
727{
728   return floppy_callbacks(floppy)->get_tracks_per_disk(floppy);
729}
730
731
732
733int floppy_get_heads_per_disk(floppy_image *floppy)
734{
735   return floppy_callbacks(floppy)->get_heads_per_disk(floppy);
736}
737
738
739
740UINT32 floppy_get_track_size(floppy_image *floppy, int head, int track)
741{
742   const struct FloppyCallbacks *fmt;
743
744   fmt = floppy_callbacks(floppy);
745   if (!fmt->get_track_size)
746      return 0;
747
748   return fmt->get_track_size(floppy, head, track);
749}
750
751
752
753floperr_t floppy_get_sector_length(floppy_image *floppy, int head, int track, int sector, UINT32 *sector_length)
754{
755   const struct FloppyCallbacks *fmt;
756
757   fmt = floppy_callbacks(floppy);
758   if (!fmt->get_sector_length)
759      return FLOPPY_ERROR_UNSUPPORTED;
760
761   return fmt->get_sector_length(floppy, head, track, sector, sector_length);
762}
763
764
765
766floperr_t floppy_get_indexed_sector_info(floppy_image *floppy, int head, int track, int sector_index, int *cylinder, int *side, int *sector, UINT32 *sector_length, unsigned long *flags)
767{
768   const struct FloppyCallbacks *fmt;
769
770   fmt = floppy_callbacks(floppy);
771   if (!fmt->get_indexed_sector_info)
772      return FLOPPY_ERROR_UNSUPPORTED;
773
774   return fmt->get_indexed_sector_info(floppy, head, track, sector_index, cylinder, side, sector, sector_length, flags);
775}
776
777
778
779floperr_t floppy_get_sector_count(floppy_image *floppy, int head, int track, int *sector_count)
780{
781   floperr_t err;
782   int sector_index = 0;
783
784   do
785   {
786      err = floppy_get_indexed_sector_info(floppy, head, track, sector_index, NULL, NULL, NULL, NULL, NULL);
787      if (!err)
788         sector_index++;
789   }
790   while(!err);
791
792   if (sector_index && (err == FLOPPY_ERROR_SEEKERROR))
793      err = FLOPPY_ERROR_SUCCESS;
794   if (sector_count)
795      *sector_count = err ? 0 : sector_index;
796   return err;
797}
798
799
800
801int floppy_is_read_only(floppy_image *floppy)
802{
803   return floppy->flags & FLOPPY_FLAGS_READONLY;
804}
805
806
807
808UINT8 floppy_random_byte(floppy_image *floppy)
809{
810   /* can't use mame_rand(); this might not be in the core */
811#ifdef rand
812#undef rand
813#endif
814   return rand();
815}
816
817
818
819/*********************************************************************
820    calls for track based IO
821*********************************************************************/
822
823floperr_t floppy_load_track(floppy_image *floppy, int head, int track, int dirtify, void **track_data, size_t *track_length)
824{
825   floperr_t err;
826   void *new_loaded_track_data;
827   UINT32 track_size;
828
829   /* have we already loaded this track? */
830   if (((floppy->loaded_track_status & TRACK_LOADED) == 0) || (head != floppy->loaded_track_head) || (track != floppy->loaded_track_index))
831   {
832      err = floppy_track_unload(floppy);
833      if (err)
834         goto error;
835
836      track_size = floppy_callbacks(floppy)->get_track_size(floppy, head, track);
837
838      if (floppy->loaded_track_data) free(floppy->loaded_track_data);
839      new_loaded_track_data = malloc(track_size);
840      if (!new_loaded_track_data)
841      {
842         err = FLOPPY_ERROR_OUTOFMEMORY;
843         goto error;
844      }
845
846      floppy->loaded_track_data = new_loaded_track_data;
847      floppy->loaded_track_size = track_size;
848      floppy->loaded_track_head = head;
849      floppy->loaded_track_index = track;
850
851      err = floppy_callbacks(floppy)->read_track(floppy, floppy->loaded_track_head, floppy->loaded_track_index, 0, floppy->loaded_track_data, floppy->loaded_track_size);
852      if (err)
853         goto error;
854
855      floppy->loaded_track_status |= TRACK_LOADED | (dirtify ? TRACK_DIRTY : 0);
856   }
857   else
858      floppy->loaded_track_status |= (dirtify ? TRACK_DIRTY : 0);
859
860   if (track_data)
861      *track_data = floppy->loaded_track_data;
862   if (track_length)
863      *track_length = floppy->loaded_track_size;
864   return FLOPPY_ERROR_SUCCESS;
865
866error:
867   if (track_data)
868      *track_data = NULL;
869   if (track_length)
870      *track_length = 0;
871   return err;
872}
873
874
875
876static floperr_t floppy_track_unload(floppy_image *floppy)
877{
878   int err;
879   if (floppy->loaded_track_status & TRACK_DIRTY)
880   {
881      err = floppy_callbacks(floppy)->write_track(floppy, floppy->loaded_track_head, floppy->loaded_track_index, 0, floppy->loaded_track_data, floppy->loaded_track_size);
882      if (err)
883         return (floperr_t)err;
884   }
885
886   floppy->loaded_track_status &= ~(TRACK_LOADED | TRACK_DIRTY);
887   return FLOPPY_ERROR_SUCCESS;
888}
889
890
891
892/*********************************************************************
893    accessors for meta information about the image
894*********************************************************************/
895
896const char *floppy_format_description(floppy_image *floppy)
897{
898   return floppy->floppy_option->description;
899}
900
901
902
903/*********************************************************************
904    misc calls
905*********************************************************************/
906
907const char *floppy_error(floperr_t err)
908{
909   static const char *const error_messages[] =
910   {
911      "The operation completed successfully",
912      "Fatal internal error",
913      "This operation is unsupported",
914      "Out of memory",
915      "Seek error",
916      "Invalid image",
917      "Attempted to write to read only image",
918      "No space left on image",
919      "Parameter out of range",
920      "Required parameter not specified"
921   };
922
923   if ((err < 0) || (err >= ARRAY_LENGTH(error_messages)))
924      return NULL;
925   return error_messages[err];
926}
927
928
929FLOPPY_OPTIONS_START(default)
930FLOPPY_OPTIONS_END
src/emu/imagedev/wavfile.c
r0r9928
1/*********************************************************************
2
3    wavfile.c
4
5    Format code for wave (*.wav) files
6
7*********************************************************************/
8
9#include <stdio.h>
10#include <assert.h>
11
12#include "wavfile.h"
13#include "cassimg.h"
14
15static const char magic1[4] = { 'R', 'I', 'F', 'F' };
16static const char magic2[4] = { 'W', 'A', 'V', 'E' };
17static const char format_tag_id[4] = { 'f', 'm', 't', ' ' };
18static const char data_tag_id[4] = { 'd', 'a', 't', 'a' };
19
20#define WAV_FORMAT_PCM      1
21
22
23
24static UINT32 get_leuint32(const void *ptr)
25{
26   UINT32 value;
27   memcpy(&value, ptr, sizeof(value));
28   return LITTLE_ENDIANIZE_INT32(value);
29}
30
31
32
33static UINT16 get_leuint16(const void *ptr)
34{
35   UINT16 value;
36   memcpy(&value, ptr, sizeof(value));
37   return LITTLE_ENDIANIZE_INT16(value);
38}
39
40
41
42static void put_leuint32(void *ptr, UINT32 value)
43{
44   value = LITTLE_ENDIANIZE_INT32(value);
45   memcpy(ptr, &value, sizeof(value));
46}
47
48
49
50static void put_leuint16(void *ptr, UINT16 value)
51{
52   value = LITTLE_ENDIANIZE_INT16(value);
53   memcpy(ptr, &value, sizeof(value));
54}
55
56
57
58static casserr_t wavfile_process(cassette_image *cassette, struct CassetteOptions *opts,
59   int read_waveform)
60{
61   UINT8 file_header[12];
62   UINT8 tag_header[8];
63   UINT8 format_tag[16];
64   UINT32 stated_size;
65   UINT64 file_size;
66   UINT32 tag_size;
67   UINT32 tag_samples;
68   UINT64 offset;
69   int format_specified = FALSE;
70
71   UINT16 format_type = 0;
72   UINT32 bytes_per_second = 0;
73   UINT16 block_align = 0;
74   int waveform_flags = 0;
75
76   /* read header */
77   cassette_image_read(cassette, file_header, 0, sizeof(file_header));
78   offset = sizeof(file_header);
79
80   /* check magic numbers */
81   if (memcmp(&file_header[0], magic1, 4))
82      return CASSETTE_ERROR_INVALIDIMAGE;
83   if (memcmp(&file_header[8], magic2, 4))
84      return CASSETTE_ERROR_INVALIDIMAGE;
85
86   /* read and sanity check size */
87   stated_size = get_leuint32(&file_header[4]) + 8;
88   file_size = cassette_image_size(cassette);
89   if (stated_size > file_size)
90      stated_size = (UINT32) file_size;
91
92   while(offset < stated_size)
93   {
94      cassette_image_read(cassette, tag_header, offset, sizeof(tag_header));
95      tag_size = get_leuint32(&tag_header[4]);
96      offset += sizeof(tag_header);
97
98      if (!memcmp(tag_header, format_tag_id, 4))
99      {
100         /* format tag */
101         if (format_specified || (tag_size < sizeof(format_tag)))
102            return CASSETTE_ERROR_INVALIDIMAGE;
103         format_specified = TRUE;
104
105         cassette_image_read(cassette, format_tag, offset, sizeof(format_tag));
106
107         format_type            = get_leuint16(&format_tag[0]);
108         opts->channels         = get_leuint16(&format_tag[2]);
109         opts->sample_frequency   = get_leuint32(&format_tag[4]);
110         bytes_per_second      = get_leuint32(&format_tag[8]);
111         block_align            = get_leuint16(&format_tag[12]);
112         opts->bits_per_sample   = get_leuint16(&format_tag[14]);
113
114         if (format_type != WAV_FORMAT_PCM)
115            return CASSETTE_ERROR_INVALIDIMAGE;
116         if (opts->sample_frequency * opts->bits_per_sample * opts->channels / 8 != bytes_per_second)
117            return CASSETTE_ERROR_INVALIDIMAGE;
118
119         switch(opts->bits_per_sample)
120         {
121            case 8:
122               waveform_flags = CASSETTE_WAVEFORM_8BIT;
123               break;
124            case 16:
125               waveform_flags = CASSETTE_WAVEFORM_16BITLE;
126               break;
127            case 32:
128               waveform_flags = CASSETTE_WAVEFORM_32BITLE;
129               break;
130            default:
131               return CASSETTE_ERROR_INVALIDIMAGE;
132         }
133      }
134      else if (!memcmp(tag_header, data_tag_id, 4))
135      {
136         /* data tag */
137         if (!format_specified)
138            return CASSETTE_ERROR_INVALIDIMAGE;
139
140         if (read_waveform)
141         {
142            tag_samples = tag_size / (opts->bits_per_sample / 8) / opts->channels;
143            cassette_read_samples(cassette, opts->channels, 0.0, tag_samples / ((double) opts->sample_frequency),
144               tag_samples, offset, waveform_flags);
145         }
146      }
147      else
148      {
149         /* ignore other tags */
150      }
151      offset += tag_size;
152   }
153
154   return CASSETTE_ERROR_SUCCESS;
155}
156
157
158
159static casserr_t wavfile_identify(cassette_image *cassette, struct CassetteOptions *opts)
160{
161   return wavfile_process(cassette, opts, FALSE);
162}
163
164
165
166static casserr_t wavfile_load(cassette_image *cassette)
167{
168   struct CassetteOptions opts;
169   memset(&opts, 0, sizeof(opts));
170   return wavfile_process(cassette, &opts, TRUE);
171}
172
173
174
175static casserr_t wavfile_save(cassette_image *cassette, const struct CassetteInfo *info)
176{
177   casserr_t err;
178   UINT8 consolidated_header[12 + 8 + 16 + 8];
179   UINT8 *header            = &consolidated_header[0];
180   UINT8 *format_tag_header   = &consolidated_header[12];
181   UINT8 *format_tag_data      = &consolidated_header[12 + 8];
182   UINT8 *data_tag_header      = &consolidated_header[12 + 8 + 16];
183   UINT32 file_size;
184   UINT32 bytes_per_second;
185   UINT16 bits_per_sample;
186   UINT32 data_size;
187   size_t bytes_per_sample = 2;
188   int waveform_flags = CASSETTE_WAVEFORM_16BITLE;
189   UINT16 block_align;
190
191   bits_per_sample = (UINT16) (bytes_per_sample * 8);
192   bytes_per_second = info->sample_frequency * bytes_per_sample * info->channels;
193   data_size = (UINT32) (info->sample_count * bytes_per_sample * info->channels);
194   file_size = data_size + sizeof(consolidated_header) - 8;
195   block_align = (UINT16) (bytes_per_sample * info->channels);
196
197   /* set up header */
198   memcpy(&header[0],               magic1, 4);
199   memcpy(&header[8],               magic2, 4);
200   put_leuint32(&header[4],         file_size);
201
202   /* set up format tag */
203   memcpy(&format_tag_header[0],      format_tag_id, 4);
204   put_leuint32(&format_tag_header[4],   16);
205   put_leuint16(&format_tag_data[0],   WAV_FORMAT_PCM);
206   put_leuint16(&format_tag_data[2],   info->channels);
207   put_leuint32(&format_tag_data[4],   info->sample_frequency);
208   put_leuint32(&format_tag_data[8],   bytes_per_second);
209   put_leuint16(&format_tag_data[12],   block_align);
210   put_leuint16(&format_tag_data[14],   bits_per_sample);
211
212   /* set up data tag */
213   memcpy(&data_tag_header[0],         data_tag_id, 4);
214   put_leuint32(&data_tag_header[4],   data_size);
215
216   /* write consolidated header */
217   cassette_image_write(cassette, consolidated_header, 0, sizeof(consolidated_header));
218
219   /* write out the actual data */
220   err = cassette_write_samples(cassette, info->channels, 0.0, info->sample_count
221      / (double) info->sample_frequency, info->sample_count, sizeof(consolidated_header),
222      waveform_flags);
223   if (err)
224      return err;
225
226   return CASSETTE_ERROR_SUCCESS;
227}
228
229
230
231const struct CassetteFormat wavfile_format =
232{
233   "wav",
234   wavfile_identify,
235   wavfile_load,
236   wavfile_save
237};
238
239
240
241/*********************************************************************
242    wavfile_testload()
243
244    This is a hokey function used to test the cassette wave loading
245    system, specifically to test that when one loads a WAV file image
246    that the resulting info queried will be the same data in the WAV.
247
248    This code has already identified some rounding errors
249*********************************************************************/
250
251#ifdef UNUSED_FUNCTION
252void wavfile_testload(const char *fname)
253{
254   cassette_image *cassette;
255   FILE *f;
256   long offset;
257   int freq, samples, i;
258   INT32 cassamp;
259   INT16 wavsamp;
260
261   f = fopen(fname, "rb");
262   if (!f)
263      return;
264
265   if (cassette_open(f, &stdio_ioprocs, &wavfile_format, CASSETTE_FLAG_READONLY, &cassette))
266   {
267      fclose(f);
268      return;
269   }
270
271   offset = 44;
272   freq = 44100;
273   samples = 5667062;
274
275   for (i = 0; i < samples; i++)
276   {
277      cassette_get_sample(cassette, 0, i / (double) freq, 0.0, &cassamp);
278
279      fseek(f, offset + i * 2, SEEK_SET);
280      fread(&wavsamp, 1, 2, f);
281      assert(cassamp == (((UINT32) wavsamp) << 16));
282   }
283
284   cassette_close(cassette);
285
286   fclose(f);
287}
288#endif
289
290
291
src/emu/emu.mak
r9927r9928
1717EMUDRIVERS = $(EMUOBJ)/drivers
1818EMULAYOUT = $(EMUOBJ)/layout
1919EMUMACHINE = $(EMUOBJ)/machine
20EMUIMAGEDEV = $(EMUOBJ)/imagedev
2021EMUVIDEO = $(EMUOBJ)/video
2122
2223OBJDIRS += \
r9927r9928
2829   $(EMUOBJ)/drivers \
2930   $(EMUOBJ)/machine \
3031   $(EMUOBJ)/layout \
32   $(EMUOBJ)/imagedev \
3133   $(EMUOBJ)/video \
3234
3335OSDSRC = $(SRC)/osd
r9927r9928
235237   $(EMUVIDEO)/vector.o \
236238   $(EMUVIDEO)/voodoo.o \
237239
238LIBEMUOBJS = $(EMUOBJS) $(EMUSOUNDOBJS) $(EMUAUDIOOBJS) $(EMUDRIVEROBJS) $(EMUMACHINEOBJS) $(EMUVIDEOOBJS)
240EMUIMAGEDEVOBJS = \
241   $(EMUIMAGEDEV)/bitbngr.o   \
242   $(EMUIMAGEDEV)/cartslot.o   \
243   $(EMUIMAGEDEV)/cassette.o   \
244   $(EMUIMAGEDEV)/cassimg.o   \
245   $(EMUIMAGEDEV)/chd_cd.o      \
246   $(EMUIMAGEDEV)/flopdrv.o   \
247   $(EMUIMAGEDEV)/flopimg.o   \
248   $(EMUIMAGEDEV)/harddriv.o   \
249   $(EMUIMAGEDEV)/multcart.o   \
250   $(EMUIMAGEDEV)/printer.o   \
251   $(EMUIMAGEDEV)/snapquik.o   \
252   $(EMUIMAGEDEV)/wavfile.o   \
239253
254
255LIBEMUOBJS = $(EMUOBJS) $(EMUSOUNDOBJS) $(EMUAUDIOOBJS) $(EMUDRIVEROBJS) $(EMUMACHINEOBJS) $(EMUIMAGEDEVOBJS) $(EMUVIDEOOBJS)
256
240257$(LIBEMU): $(LIBEMUOBJS)
241258
242259
src/emu/machine/scsihd.c
r9927r9928
77#include "emu.h"
88#include "scsidev.h"
99#include "harddisk.h"
10
11#ifdef MESS
12#include "devices/harddriv.h"
13#endif
10#include "imagedev/harddriv.h"
1411#include "scsihd.h"
1512
1613typedef struct
src/emu/machine/idectrl.c
r9927r9928
77#include "emu.h"
88#include "idectrl.h"
99#include "debugger.h"
10#include "imagedev/harddriv.h"
1011
11#ifdef MESS
12#include "devices/harddriv.h"
13#endif
14
1512/***************************************************************************
1613    DEBUGGING
1714***************************************************************************/
src/emu/machine/scsicd.c
r9927r9928
88#include "scsidev.h"
99#include "cdrom.h"
1010#include "sound/cdda.h"
11#ifdef MESS
12#include "devices/chd_cd.h"
13#endif
11#include "imagedev/chd_cd.h"
1412#include "scsicd.h"
1513
1614typedef struct
src/mess/uimess.c
r9927r9928
1/*********************************************************************
2
3    uimess.c
4
5    MESS supplement to ui.c.
6
7*********************************************************************/
8
9#include "emu.h"
10#include "uimenu.h"
11#include "uimess.h"
12#include "uiinput.h"
13#include "input.h"
14#include "devices/cassette.h"
15#include "devices/bitbngr.h"
16
17
18/***************************************************************************
19    TYPE DEFINITIONS
20***************************************************************************/
21#define TAPECMD_NULL         ((void *) 0x0000)
22#define TAPECMD_STOP         ((void *) 0x0001)
23#define TAPECMD_PLAY         ((void *) 0x0002)
24#define TAPECMD_RECORD         ((void *) 0x0003)
25#define TAPECMD_REWIND         ((void *) 0x0004)
26#define TAPECMD_FAST_FORWARD      ((void *) 0x0005)
27#define TAPECMD_SLIDER         ((void *) 0x0006)
28#define TAPECMD_SELECT         ((void *) 0x0007)
29
30#define BITBANGERCMD_SELECT         ((void *) 0x0000)
31#define BITBANGERCMD_MODE         ((void *) 0x0001)
32#define BITBANGERCMD_BAUD         ((void *) 0x0002)
33#define BITBANGERCMD_TUNE         ((void *) 0x0003)
34
35
36typedef struct _tape_control_menu_state tape_control_menu_state;
37struct _tape_control_menu_state
38{
39   int index;
40   device_image_interface *device;
41};
42
43
44
45typedef struct _bitbanger_control_menu_state bitbanger_control_menu_state;
46struct _bitbanger_control_menu_state
47{
48   int index;
49   device_image_interface *device;
50};
51
52
53
54/***************************************************************************
55    IMPLEMENTATION
56***************************************************************************/
57
58/*-------------------------------------------------
59    ui_mess_main_menu_populate - populate MESS-specific menus
60-------------------------------------------------*/
61
62void ui_mess_main_menu_populate(running_machine *machine, ui_menu *menu)
63{
64   /* add tape control menu */
65   if (machine->m_devicelist.first(CASSETTE))
66      ui_menu_item_append(menu, "Tape Control", NULL, 0, (void*)ui_mess_menu_tape_control);
67
68   /* add bitbanger control menu */
69   if (machine->m_devicelist.first(BITBANGER))
70      ui_menu_item_append(menu, "Bitbanger Control", NULL, 0, (void*)ui_mess_menu_bitbanger_control);
71}
72
73
74/*-------------------------------------------------
75    cassette_count - returns the number of cassette
76    devices in the machine
77-------------------------------------------------*/
78
79INLINE int cassette_count( running_machine *machine )
80{
81   int count = 0;
82   device_t *device = machine->m_devicelist.first(CASSETTE);
83
84   while ( device )
85   {
86      count++;
87      device = device->typenext();
88   }
89   return count;
90}
91
92/*-------------------------------------------------
93    bitbanger_count - returns the number of bitbanger
94    devices in the machine
95-------------------------------------------------*/
96
97INLINE int bitbanger_count( running_machine *machine )
98{
99   int count = 0;
100   device_t *device = machine->m_devicelist.first(BITBANGER);
101
102   while ( device )
103   {
104      count++;
105      device = device->typenext();
106   }
107   return count;
108}
109
110/*-------------------------------------------------
111    tapecontrol_gettime - returns a textual
112    representation of the time
113-------------------------------------------------*/
114
115astring *tapecontrol_gettime(astring *dest, device_t *device, int *curpos, int *endpos)
116{
117   double t0, t1;
118
119   t0 = cassette_get_position(device);
120   t1 = cassette_get_length(device);
121
122   if (t1)
123      astring_printf(dest, "%04d/%04d", (int) t0, (int) t1);
124   else
125      astring_printf(dest, "%04d/%04d", 0, (int) t1);
126
127   if (curpos != NULL)
128      *curpos = t0;
129   if (endpos != NULL)
130      *endpos = t1;
131
132   return dest;
133}
134
135
136
137/*-------------------------------------------------
138    menu_tape_control_populate - populates the
139    main tape control menu
140-------------------------------------------------*/
141
142static void menu_tape_control_populate(running_machine *machine, ui_menu *menu, tape_control_menu_state *menustate)
143{
144   astring timepos;
145   cassette_state state;
146   int count = cassette_count(machine);
147   UINT32 flags = 0;
148
149   if( count > 0 )
150   {
151      if( menustate->index == (count-1) )
152         flags |= MENU_FLAG_LEFT_ARROW;
153      else
154         flags |= MENU_FLAG_RIGHT_ARROW;
155   }
156
157   if (menustate->device->exists())
158   {
159      double t0, t1;
160      UINT32 tapeflags = 0;
161
162      t0 = cassette_get_position(&menustate->device->device());
163      t1 = cassette_get_length(&menustate->device->device());
164
165      if (t1 > 0)
166      {
167         if (t0 > 0)
168            tapeflags |= MENU_FLAG_LEFT_ARROW;
169         if (t0 < t1)
170            tapeflags |= MENU_FLAG_RIGHT_ARROW;
171      }
172
173      /* name of tape */
174      ui_menu_item_append(menu, menustate->device->image_config().devconfig().name(), menustate->device->filename(), flags, TAPECMD_SELECT);
175
176      /* state */
177      tapecontrol_gettime(&timepos, &menustate->device->device(), NULL, NULL);
178      state = cassette_get_state(&menustate->device->device());
179      ui_menu_item_append(
180         menu,
181         (state & CASSETTE_MASK_UISTATE) == CASSETTE_STOPPED
182            ?   "stopped"
183            :   ((state & CASSETTE_MASK_UISTATE) == CASSETTE_PLAY
184               ? ((state & CASSETTE_MASK_MOTOR) == CASSETTE_MOTOR_ENABLED ? "playing" : "(playing)")
185               : ((state & CASSETTE_MASK_MOTOR) == CASSETTE_MOTOR_ENABLED ? "recording" : "(recording)")
186               ),
187         astring_c(&timepos),
188         tapeflags,
189         TAPECMD_SLIDER);
190
191      /* pause or stop */
192      ui_menu_item_append(menu, "Pause/Stop", NULL, 0, TAPECMD_STOP);
193
194      /* play */
195      ui_menu_item_append(menu, "Play", NULL, 0, TAPECMD_PLAY);
196
197      /* record */
198      ui_menu_item_append(menu, "Record", NULL, 0, TAPECMD_RECORD);
199
200      /* rewind */
201      ui_menu_item_append(menu, "Rewind", NULL, 0, TAPECMD_REWIND);
202
203      /* fast forward */
204      ui_menu_item_append(menu, "Fast Forward", NULL, 0, TAPECMD_FAST_FORWARD);
205   }
206   else
207   {
208      /* no tape loaded */
209      ui_menu_item_append(menu, "No Tape Image loaded", NULL, flags, NULL);
210   }
211}
212
213
214/*-------------------------------------------------
215    menu_bitbanger_control_populate - populates the
216    main bitbanger control menu
217-------------------------------------------------*/
218
219static void menu_bitbanger_control_populate(running_machine *machine, ui_menu *menu, bitbanger_control_menu_state *menustate)
220{
221   int count = bitbanger_count(machine);
222   UINT32 flags = 0, mode_flags = 0, baud_flags = 0, tune_flags = 0;
223
224   if( count > 0 )
225   {
226      if( menustate->index == (count-1) )
227         flags |= MENU_FLAG_LEFT_ARROW;
228      else
229         flags |= MENU_FLAG_RIGHT_ARROW;
230   }
231
232   if (bitbanger_inc_mode(&menustate->device->device(), TRUE))
233      mode_flags |= MENU_FLAG_RIGHT_ARROW;
234
235   if (bitbanger_dec_mode(&menustate->device->device(), TRUE))
236      mode_flags |= MENU_FLAG_LEFT_ARROW;
237
238   if (bitbanger_inc_baud(&menustate->device->device(), TRUE))
239      baud_flags |= MENU_FLAG_RIGHT_ARROW;
240
241   if (bitbanger_dec_baud(&menustate->device->device(), TRUE))
242      baud_flags |= MENU_FLAG_LEFT_ARROW;
243
244   if (bitbanger_inc_tune(&menustate->device->device(), TRUE))
245      tune_flags |= MENU_FLAG_RIGHT_ARROW;
246
247   if (bitbanger_dec_tune(&menustate->device->device(), TRUE))
248      tune_flags |= MENU_FLAG_LEFT_ARROW;
249
250
251   if (menustate->device->exists())
252   {
253      /* name of bitbanger file */
254      ui_menu_item_append(menu, menustate->device->image_config().devconfig().name(), menustate->device->filename(), flags, BITBANGERCMD_SELECT);
255      ui_menu_item_append(menu, "Device Mode:", bitbanger_mode_string(&menustate->device->device()), mode_flags, BITBANGERCMD_MODE);
256      ui_menu_item_append(menu, "Baud:", bitbanger_baud_string(&menustate->device->device()), baud_flags, BITBANGERCMD_BAUD);
257      ui_menu_item_append(menu, "Baud Tune:", bitbanger_tune_string(&menustate->device->device()), tune_flags, BITBANGERCMD_TUNE);
258      ui_menu_item_append(menu, "Protocol:", "8-1-N", 0, NULL);
259   }
260   else
261   {
262      /* no tape loaded */
263      ui_menu_item_append(menu, "No Bitbanger Image loaded", NULL, flags, NULL);
264   }
265}
266
267
268/*-------------------------------------------------
269    menu_tape_control - main tape control menu
270-------------------------------------------------*/
271
272void ui_mess_menu_tape_control(running_machine *machine, ui_menu *menu, void *parameter, void *state)
273{
274   tape_control_menu_state *menustate;
275   const ui_menu_event *event;
276
277   /* if no state, allocate some */
278   if (state == NULL)
279      state = ui_menu_alloc_state(menu, sizeof(*menustate), NULL);
280   menustate = (tape_control_menu_state *) state;
281
282   /* do we have to load the device? */
283   if (menustate->device == NULL)
284   {
285      int index = menustate->index;
286      device_image_interface *device = NULL;
287      for (bool gotone = machine->m_devicelist.first(device); gotone; gotone = device->next(device))
288      {
289         if(device->device().type() == CASSETTE) {
290            if (index==0) break;
291            index--;
292         }
293      }
294      menustate->device = device;
295      ui_menu_reset(menu, (ui_menu_reset_options)0);
296   }
297
298   /* rebuild the menu - we have to do this so that the counter updates */
299   ui_menu_reset(menu, UI_MENU_RESET_REMEMBER_POSITION);
300   menu_tape_control_populate(machine, menu, (tape_control_menu_state*)state);
301
302   /* process the menu */
303   event = ui_menu_process(machine, menu, UI_MENU_PROCESS_LR_REPEAT);
304   if (event != NULL)
305   {
306      switch(event->iptkey)
307      {
308         case IPT_UI_LEFT:
309            if (event->itemref==TAPECMD_SLIDER)
310               cassette_seek(&menustate->device->device(), -1, SEEK_CUR);
311            else
312            if (event->itemref==TAPECMD_SELECT)
313            {
314               /* left arrow - rotate left through cassette devices */
315               if (menustate->index > 0)
316                  menustate->index--;
317               else
318                  menustate->index = cassette_count(machine) - 1;
319               menustate->device = NULL;
320            }
321            break;
322
323         case IPT_UI_RIGHT:
324            if (event->itemref==TAPECMD_SLIDER)
325               cassette_seek(&menustate->device->device(), +1, SEEK_CUR);
326            else
327            if (event->itemref==TAPECMD_SELECT)
328            {
329               /* right arrow - rotate right through cassette devices */
330               if (menustate->index < cassette_count(machine) - 1)
331                  menustate->index++;
332               else
333                  menustate->index = 0;
334               menustate->device = NULL;
335            }
336            break;
337
338         case IPT_UI_SELECT:
339            {
340               if (event->itemref==TAPECMD_STOP)
341                  cassette_change_state(&menustate->device->device(), CASSETTE_STOPPED, CASSETTE_MASK_UISTATE);
342               else
343               if (event->itemref==TAPECMD_PLAY)
344                  cassette_change_state(&menustate->device->device(), CASSETTE_PLAY, CASSETTE_MASK_UISTATE);
345               else
346               if (event->itemref==TAPECMD_RECORD)
347                  cassette_change_state(&menustate->device->device(), CASSETTE_RECORD, CASSETTE_MASK_UISTATE);
348               else
349               if (event->itemref==TAPECMD_REWIND)
350                  cassette_seek(&menustate->device->device(), -30, SEEK_CUR);
351               else
352               if (event->itemref==TAPECMD_FAST_FORWARD)
353                  cassette_seek(&menustate->device->device(), 30, SEEK_CUR);
354               else
355               if (event->itemref==TAPECMD_SLIDER)
356                  cassette_seek(&menustate->device->device(), 0, SEEK_SET);
357            }
358            break;
359      }
360   }
361}
362
363
364/*-------------------------------------------------
365    menu_bitbanger_control - main bitbanger
366    control menu
367-------------------------------------------------*/
368
369void ui_mess_menu_bitbanger_control(running_machine *machine, ui_menu *menu, void *parameter, void *state)
370{
371   bitbanger_control_menu_state *menustate;
372   const ui_menu_event *event;
373
374   /* if no state, allocate some */
375   if (state == NULL)
376      state = ui_menu_alloc_state(menu, sizeof(*menustate), NULL);
377   menustate = (bitbanger_control_menu_state *) state;
378
379   /* do we have to load the device? */
380   if (menustate->device == NULL)
381   {
382      int index = menustate->index;
383      device_image_interface *device = NULL;
384      for (bool gotone = machine->m_devicelist.first(device); gotone; gotone = device->next(device))
385      {
386         if(device->device().type() == BITBANGER) {
387            if (index==0) break;
388            index--;
389         }
390      }
391      menustate->device = device;
392      ui_menu_reset(menu, (ui_menu_reset_options)0);
393   }
394
395   /* rebuild the menu */
396   ui_menu_reset(menu, UI_MENU_RESET_REMEMBER_POSITION);
397   menu_bitbanger_control_populate(machine, menu, (bitbanger_control_menu_state*)state);
398
399   /* process the menu */
400   event = ui_menu_process(machine, menu, UI_MENU_PROCESS_LR_REPEAT);
401   if (event != NULL)
402   {
403      switch(event->iptkey)
404      {
405         case IPT_UI_LEFT:
406            if (event->itemref==BITBANGERCMD_SELECT)
407            {
408               /* left arrow - rotate left through cassette devices */
409               if (menustate->index > 0)
410                  menustate->index--;
411               else
412                  menustate->index = bitbanger_count(machine) - 1;
413               menustate->device = NULL;
414            }
415            else if (event->itemref==BITBANGERCMD_MODE)
416            {
417               bitbanger_dec_mode(&menustate->device->device(), FALSE);
418            }
419            else if (event->itemref==BITBANGERCMD_BAUD)
420            {
421               bitbanger_dec_baud(&menustate->device->device(), FALSE);
422            }
423            else if (event->itemref==BITBANGERCMD_TUNE)
424            {
425               bitbanger_dec_tune(&menustate->device->device(), FALSE);
426            }
427            break;
428
429         case IPT_UI_RIGHT:
430            if (event->itemref==BITBANGERCMD_SELECT)
431            {
432               /* right arrow - rotate right through cassette devices */
433               if (menustate->index < bitbanger_count(machine) - 1)
434                  menustate->index++;
435               else
436                  menustate->index = 0;
437               menustate->device = NULL;
438            }
439            else if (event->itemref==BITBANGERCMD_MODE)
440            {
441               bitbanger_inc_mode(&menustate->device->device(), FALSE);
442            }
443            else if (event->itemref==BITBANGERCMD_BAUD)
444            {
445               bitbanger_inc_baud(&menustate->device->device(), FALSE);
446            }
447            else if (event->itemref==BITBANGERCMD_TUNE)
448            {
449               bitbanger_inc_tune(&menustate->device->device(), FALSE);
450            }
451            break;
452      }
453   }
454}
455
src/mess/uimess.h
r9927r9928
1/*********************************************************************
2
3    uimess.h
4
5    MESS supplement to ui.c.
6
7*********************************************************************/
8
9#ifndef __UIMESS_H__
10#define __UIMESS_H__
11
12#include "ui.h"
13#include "uimenu.h"
14
15/***************************************************************************
16    PROTOTYPES
17***************************************************************************/
18/* bitbanger control */
19void ui_mess_menu_bitbanger_control(running_machine *machine, ui_menu *menu, void *parameter, void *state);
20
21/* tape control */
22void ui_mess_menu_tape_control(running_machine *machine, ui_menu *menu, void *parameter, void *state);
23astring *tapecontrol_gettime(astring *dest, device_t *device, int *curpos, int *endpos);
24
25/* populate MESS-specific menus */
26void ui_mess_main_menu_populate(running_machine *machine, ui_menu *menu);
27
28#endif /* __UIMESS_H__ */
src/mess/devices/multcart.h
r9927r9928
1/*********************************************************************
2
3    multcart.h
4
5    Multi-cartridge handling code
6
7*********************************************************************/
8
9#ifndef __MULTCART_H__
10#define __MULTCART_H__
11
12#include "osdcore.h"
13
14
15/***************************************************************************
16    TYPE DEFINITIONS
17***************************************************************************/
18
19enum _multicart_load_flags
20{
21   MULTICART_FLAGS_DONT_LOAD_RESOURCES   = 0x00,
22   MULTICART_FLAGS_LOAD_RESOURCES      = 0x01
23};
24typedef enum _multicart_load_flags multicart_load_flags;
25
26enum _multicart_resource_type
27{
28   MULTICART_RESOURCE_TYPE_INVALID,
29   MULTICART_RESOURCE_TYPE_ROM,
30   MULTICART_RESOURCE_TYPE_RAM
31};
32typedef enum _multicart_resource_type multicart_resource_type;
33
34typedef struct _multicart_resource multicart_resource;
35struct _multicart_resource
36{
37   const char *            id;
38   const char *            filename;
39   multicart_resource *      next;
40   multicart_resource_type      type;
41   UINT32                  length;
42   void *                  ptr;
43};
44
45
46typedef struct _multicart_socket multicart_socket;
47struct _multicart_socket
48{
49   const char *            id;
50   multicart_socket *         next;
51   const multicart_resource *   resource;
52   void *                  ptr;
53};
54
55
56typedef struct _multicart_private multicart_private;
57
58typedef struct _multicart_t multicart_t;
59struct _multicart_t
60{
61   const multicart_resource *   resources;
62   const multicart_socket *   sockets;
63   const char *            pcb_type;
64   const char *            gamedrv_name; /* need this to find the path to the nvram files */
65   multicart_private *         data;
66};
67
68
69enum _multicart_open_error
70{
71   MCERR_NONE,
72   MCERR_NOT_MULTICART,
73   MCERR_CORRUPT,
74   MCERR_OUT_OF_MEMORY,
75   MCERR_XML_ERROR,
76   MCERR_INVALID_FILE_REF,
77   MCERR_ZIP_ERROR,
78   MCERR_MISSING_RAM_LENGTH,
79   MCERR_INVALID_RAM_SPEC,
80   MCERR_UNKNOWN_RESOURCE_TYPE,
81   MCERR_INVALID_RESOURCE_REF,
82   MCERR_INVALID_FILE_FORMAT,
83   MCERR_MISSING_LAYOUT,
84   MCERR_NO_PCB_OR_RESOURCES
85};
86typedef enum _multicart_open_error multicart_open_error;
87
88const char *multicart_error_text(multicart_open_error error);
89
90/***************************************************************************
91    PROTOTYPES
92***************************************************************************/
93
94/* opens a multicart */
95multicart_open_error multicart_open(const char *filename, const char *drvname, multicart_load_flags load_flags, multicart_t **cart);
96
97/* closes a multicart */
98void multicart_close(multicart_t *cart);
99
100#endif /* __MULTCART_H__ */
src/mess/devices/snapquik.h
r9927r9928
1/*********************************************************************
2
3    snapquik.h
4
5    Snapshots and quickloads
6
7*********************************************************************/
8
9#ifndef __SNAPQUIK_H__
10#define __SNAPQUIK_H__
11
12#include "image.h"
13#include "ui.h"
14
15
16/***************************************************************************
17    CONSTANTS
18***************************************************************************/
19
20enum
21{
22   DEVINFO_FCT_SNAPSHOT_QUICKLOAD_LOAD = DEVINFO_FCT_DEVICE_SPECIFIC
23};
24
25
26
27/***************************************************************************
28    MACROS
29***************************************************************************/
30
31DECLARE_LEGACY_IMAGE_DEVICE(SNAPSHOT, snapshot);
32DECLARE_LEGACY_IMAGE_DEVICE(QUICKLOAD   , quickload);
33
34#define SNAPSHOT_LOAD_NAME(name)   snapshot_load_##name
35#define SNAPSHOT_LOAD(name)         int SNAPSHOT_LOAD_NAME(name)(device_image_interface &image, const char *file_type, int snapshot_size)
36
37#define QUICKLOAD_LOAD_NAME(name)   quickload_load_##name
38#define QUICKLOAD_LOAD(name)      int QUICKLOAD_LOAD_NAME(name)(device_image_interface &image, const char *file_type, int quickload_size)
39
40#define LOAD_REG(_cpu, _reg, _data) \
41        do { \
42          cpu_set_reg(_cpu, _reg, (_data)); \
43        } while (0)
44
45#define EXEC_NA "N/A"
46
47/***************************************************************************
48    TYPE DEFINITIONS
49***************************************************************************/
50
51typedef int (*snapquick_load_func)(device_image_interface &image, const char *file_type, int file_size);
52
53typedef struct _snapquick_config snapquick_config;
54struct _snapquick_config
55{
56   snapquick_load_func   load;            /* loading function */
57   const char *      file_extensions;   /* file extensions */
58   seconds_t         delay_seconds;      /* loading delay (seconds) */
59   attoseconds_t      delay_attoseconds;   /* loading delay (attoseconds) */
60};
61
62
63
64/***************************************************************************
65    SNAPSHOT DEVICE CONFIGURATION MACROS
66***************************************************************************/
67
68#define MCFG_SNAPSHOT_ADD(_tag, _load, _file_extensions, _delay)   \
69   MCFG_DEVICE_ADD(_tag, SNAPSHOT, 0) \
70   MCFG_DEVICE_CONFIG_DATAPTR(snapquick_config, load, SNAPSHOT_LOAD_NAME(_load))   \
71   MCFG_DEVICE_CONFIG_DATAPTR(snapquick_config, file_extensions, _file_extensions) \
72   MCFG_DEVICE_CONFIG_DATA64(snapquick_config, delay_seconds, (seconds_t) (_delay)) \
73   MCFG_DEVICE_CONFIG_DATA64(snapquick_config, delay_attoseconds, (attoseconds_t) (((_delay) - (int)(_delay)) * ATTOSECONDS_PER_SECOND)) \
74
75/***************************************************************************
76    QUICKLOAD DEVICE CONFIGURATION MACROS
77***************************************************************************/
78
79#define MCFG_QUICKLOAD_ADD(_tag, _load, _file_extensions, _delay)   \
80   MCFG_DEVICE_ADD(_tag, QUICKLOAD, 0) \
81   MCFG_DEVICE_CONFIG_DATAPTR(snapquick_config, load, QUICKLOAD_LOAD_NAME(_load))   \
82   MCFG_DEVICE_CONFIG_DATAPTR(snapquick_config, file_extensions, _file_extensions) \
83   MCFG_DEVICE_CONFIG_DATA64(snapquick_config, delay_seconds, (seconds_t) (_delay)) \
84   MCFG_DEVICE_CONFIG_DATA64(snapquick_config, delay_attoseconds, (attoseconds_t) (((_delay) - (int)(_delay)) * ATTOSECONDS_PER_SECOND)) \
85
86/***************************************************************************
87    FUNCTION PROTOTYPES
88***************************************************************************/
89
90void log_quickload(const char *type, UINT32 start, UINT32 length, UINT32 exec, const char *exec_format);
91
92
93#endif /* __SNAPQUIK_H__ */
src/mess/devices/harddriv.c
r9927r9928
1/*********************************************************************
2
3    Code to interface the MESS image code with MAME's harddisk core.
4
5    We do not support diff files as it will involve some changes in
6    the MESS image code.  Additionally, the need for diff files comes
7    from MAME's need for "cannonical" hard drive images.
8
9    Raphael Nabet 2003
10
11    Update: 23-Feb-2004 - Unlike floppy disks, for which we support
12    myriad formats on many systems, it is my intention for MESS to
13    standardize on the CHD file format for hard drives so I made a few
14    changes to support this
15
16*********************************************************************/
17
18#include "emu.h"
19#include "harddisk.h"
20#include "harddriv.h"
21
22
23static const char *const error_strings[] =
24{
25   "no error",
26   "no drive interface",
27   "out of memory",
28   "invalid file",
29   "invalid parameter",
30   "invalid data",
31   "file not found",
32   "requires parent",
33   "file not writeable",
34   "read error",
35   "write error",
36   "codec error",
37   "invalid parent",
38   "hunk out of range",
39   "decompression error",
40   "compression error",
41   "can't create file",
42   "can't verify file"
43   "operation not supported",
44   "can't find metadata",
45   "invalid metadata size",
46   "unsupported CHD version"
47};
48
49static const char *chd_get_error_string(int chderr)
50{
51   if ((chderr < 0 ) || (chderr >= ARRAY_LENGTH(error_strings)))
52      return NULL;
53   return error_strings[chderr];
54}
55
56
57
58static OPTION_GUIDE_START(mess_hd_option_guide)
59   OPTION_INT('C', "cylinders",      "Cylinders")
60   OPTION_INT('H', "heads",         "Heads")
61   OPTION_INT('S', "sectors",         "Sectors")
62   OPTION_INT('L', "sectorlength",      "Sector Bytes")
63   OPTION_INT('K', "hunksize",         "Hunk Bytes")
64OPTION_GUIDE_END
65
66static const char *mess_hd_option_spec =
67   "C1-[512]-1024;H1/2/[4]/8;S1-[16]-64;L128/256/[512]/1024;K512/1024/2048/[4096]";
68
69
70typedef struct _dev_harddisk_t   dev_harddisk_t;
71struct _dev_harddisk_t
72{
73   const struct harddisk_callback_config   *config;
74   chd_file      *chd;
75   hard_disk_file   *hard_disk_handle;
76};
77
78
79INLINE dev_harddisk_t *get_safe_token(device_t *device)
80{
81   assert( device != NULL );
82   assert( ( device->type() == HARDDISK ) ||
83           ( device->type() == IDE_HARDDISK ) );
84   return (dev_harddisk_t *) downcast<legacy_device_base *>(device)->token();
85}
86
87
88/*************************************
89 *
90 *  DEVICE_IMAGE_LOAD(mess_hd)
91 *  DEVICE_IMAGE_CREATE(mess_hd)
92 *
93 *  Device load and create
94 *
95 *************************************/
96
97static int internal_load_mess_hd(device_image_interface &image, const char *metadata)
98{
99   dev_harddisk_t   *harddisk = get_safe_token( &image.device() );
100   chd_error      err = (chd_error)0;
101   int            is_writeable;
102
103   /* open the CHD file */
104   do
105   {
106      is_writeable = image.is_writable();
107      harddisk->chd = NULL;
108      err = chd_open_file(image.image_core_file(), is_writeable ? CHD_OPEN_READWRITE : CHD_OPEN_READ, NULL, &harddisk->chd);
109
110      /* special case; if we get CHDERR_FILE_NOT_WRITEABLE, make the
111         * image read only and repeat */
112      if (err == CHDERR_FILE_NOT_WRITEABLE)
113         image.make_readonly();
114   }
115   while(!harddisk->chd && is_writeable && (err == CHDERR_FILE_NOT_WRITEABLE));
116   if (!harddisk->chd)
117      goto done;
118
119   /* if we created the image and hence, have metadata to set, set the metadata */
120   if (metadata)
121   {
122      err = chd_set_metadata(harddisk->chd, HARD_DISK_METADATA_TAG, 0, metadata, strlen(metadata) + 1, 0);
123      if (err != CHDERR_NONE)
124         goto done;
125   }
126
127   /* open the hard disk file */
128   harddisk->hard_disk_handle = hard_disk_open(harddisk->chd);
129   if (!harddisk->hard_disk_handle)
130      goto done;
131
132done:
133   if (err)
134   {
135      /* if we had an error, close out the CHD */
136      if (harddisk->chd != NULL)
137      {
138         chd_close(harddisk->chd);
139         harddisk->chd = NULL;
140      }
141
142      image.seterror(IMAGE_ERROR_UNSPECIFIED, chd_get_error_string(err));
143   }
144   return err ? IMAGE_INIT_FAIL : IMAGE_INIT_PASS;
145}
146
147
148
149static DEVICE_IMAGE_LOAD( mess_hd )
150{
151   dev_harddisk_t   *harddisk = get_safe_token( image );
152   int our_result;
153
154   our_result = internal_load_mess_hd(image, NULL);
155
156   /* Check if there is an image_load callback defined */
157   if ( harddisk->config && harddisk->config->device_image_load )
158   {
159      /* Let the override do some additional work/checks */
160      our_result = harddisk->config->device_image_load( image );
161   }
162   return our_result;
163}
164
165
166static DEVICE_IMAGE_CREATE( mess_hd )
167{
168   int err;
169   char metadata[256];
170   UINT32 sectorsize, hunksize;
171   UINT32 cylinders, heads, sectors, totalsectors;
172
173   cylinders   = option_resolution_lookup_int(create_args, 'C');
174   heads      = option_resolution_lookup_int(create_args, 'H');
175   sectors      = option_resolution_lookup_int(create_args, 'S');
176   sectorsize   = option_resolution_lookup_int(create_args, 'L');
177   hunksize   = option_resolution_lookup_int(create_args, 'K');
178
179   totalsectors = cylinders * heads * sectors;
180
181   /* create the CHD file */
182   err = chd_create_file(image.image_core_file(), (UINT64)totalsectors * (UINT64)sectorsize, hunksize, CHDCOMPRESSION_NONE, NULL);
183   if (err != CHDERR_NONE)
184      goto error;
185
186   sprintf(metadata, HARD_DISK_METADATA_FORMAT, cylinders, heads, sectors, sectorsize);
187   return internal_load_mess_hd(image, metadata);
188
189error:
190   return IMAGE_INIT_FAIL;
191}
192
193
194
195/*************************************
196 *
197 *  DEVICE_IMAGE_UNLOAD(mess_hd)
198 *
199 *  Device unload
200 *
201 *************************************/
202
203static DEVICE_IMAGE_UNLOAD( mess_hd )
204{
205   dev_harddisk_t   *harddisk = get_safe_token( image );
206
207   /* Check if there is an image_unload callback defined */
208   if ( harddisk->config && harddisk->config->device_image_unload )
209   {
210      harddisk->config->device_image_unload( image );
211   }
212
213   if (harddisk->hard_disk_handle != NULL)
214   {
215      hard_disk_close(harddisk->hard_disk_handle);
216      harddisk->hard_disk_handle = NULL;
217   }
218
219   if (harddisk->chd != NULL)
220   {
221      chd_close(harddisk->chd);
222      harddisk->chd = NULL;
223   }
224}
225
226
227/*************************************
228 *
229 *  Get the MESS/MAME hard disk handle (from the src/harddisk.c core)
230 *  after an image has been opened with the mess_hd core
231 *
232 *************************************/
233
234hard_disk_file *mess_hd_get_hard_disk_file(device_t *device)
235{
236   dev_harddisk_t   *harddisk = get_safe_token( device );
237
238   return harddisk->hard_disk_handle;
239}
240
241
242/*************************************
243 *
244 *  Get the MESS/MAME CHD file (from the src/chd.c core)
245 *  after an image has been opened with the mess_hd core
246 *
247 *************************************/
248
249chd_file *mess_hd_get_chd_file(device_t *device)
250{
251   chd_file *result = NULL;
252   hard_disk_file *hd_file;
253
254   if (device)
255   {
256      hd_file = mess_hd_get_hard_disk_file(device);
257      if (hd_file)
258         result = hard_disk_get_chd(hd_file);
259   }
260   return result;
261}
262
263
264/*-------------------------------------------------
265    DEVICE_START(mess_hd)
266-------------------------------------------------*/
267
268static DEVICE_START(mess_hd)
269{
270   dev_harddisk_t   *harddisk = get_safe_token( device );
271
272   harddisk->config = (const harddisk_callback_config*)device->baseconfig().static_config();
273   harddisk->chd = NULL;
274   harddisk->hard_disk_handle = NULL;
275}
276
277
278/*-------------------------------------------------
279    DEVICE_GET_INFO(mess_hd)
280-------------------------------------------------*/
281
282DEVICE_GET_INFO(mess_hd)
283{
284   switch( state )
285   {
286      /* --- the following bits of info are returned as 64-bit signed integers --- */
287      case DEVINFO_INT_TOKEN_BYTES:            info->i = sizeof(dev_harddisk_t); break;
288      case DEVINFO_INT_INLINE_CONFIG_BYTES:      info->i = 0; break;
289      case DEVINFO_INT_IMAGE_TYPE:            info->i = IO_HARDDISK; break;
290      case DEVINFO_INT_IMAGE_READABLE:         info->i = 1; break;
291      case DEVINFO_INT_IMAGE_WRITEABLE:         info->i = 1; break;
292      case DEVINFO_INT_IMAGE_CREATABLE:         info->i = 0; break;
293      case DEVINFO_INT_IMAGE_CREATE_OPTCOUNT:      info->i = 1; break;
294
295      /* --- the following bits of info are returned as pointers to data or functions --- */
296      case DEVINFO_FCT_START:                  info->start = DEVICE_START_NAME(mess_hd); break;
297      case DEVINFO_FCT_IMAGE_LOAD:            info->f = (genf *) DEVICE_IMAGE_LOAD_NAME(mess_hd); break;
298      case DEVINFO_FCT_IMAGE_UNLOAD:            info->f = (genf *) DEVICE_IMAGE_UNLOAD_NAME(mess_hd); break;
299      case DEVINFO_FCT_IMAGE_CREATE:            info->f = (genf *) DEVICE_IMAGE_CREATE_NAME(mess_hd); break;
300      case DEVINFO_PTR_IMAGE_CREATE_OPTGUIDE:      info->p = (void *) mess_hd_option_guide; break;
301      case DEVINFO_PTR_IMAGE_CREATE_OPTSPEC+0:   info->p = (void *) mess_hd_option_spec; break;
302
303      /* --- the following bits of info are returned as NULL-terminated strings --- */
304      case DEVINFO_STR_NAME:                  strcpy(info->s, "Harddisk"); break;
305      case DEVINFO_STR_FAMILY:               strcpy(info->s, "Harddisk"); break;
306      case DEVINFO_STR_SOURCE_FILE:            strcpy(info->s, __FILE__); break;
307      case DEVINFO_STR_IMAGE_FILE_EXTENSIONS:      strcpy(info->s, "chd,hd"); break;
308      case DEVINFO_STR_IMAGE_CREATE_OPTNAME+0:   strcpy(info->s, "chd"); break;
309      case DEVINFO_STR_IMAGE_CREATE_OPTDESC+0:   strcpy(info->s, "MAME/MESS CHD Hard drive"); break;
310      case DEVINFO_STR_IMAGE_CREATE_OPTEXTS+0:   strcpy(info->s, "chd,hd"); break;
311   }
312}
313
314
315static DEVICE_START(mess_ide)
316{
317   /* old code from idedrive.c */
318#ifdef UNUSED_FUNCTION
319   int which_bus, which_address;
320   struct ide_interface *intf;
321   device_start_func parent_init;
322
323   /* get the basics */
324   ide_get_params(device, &which_bus, &which_address, &intf, &parent_init, NULL, NULL);
325
326   /* call the parent init function */
327   parent_init(device);
328
329   /* configure IDE */
330   /* FIXME IDE */
331   /* ide_controller_init_custom(which_bus, intf, NULL); */
332#endif
333}
334
335
336static DEVICE_IMAGE_LOAD(mess_ide)
337{
338   /* old code from idedrive.c */
339#ifdef UNUSED_FUNCTION
340   int result, which_bus, which_address;
341   struct ide_interface *intf;
342   device_image_load_func parent_load;
343
344   /* get the basics */
345   ide_get_params(image, &which_bus, &which_address, &intf, NULL, &parent_load, NULL);
346
347   /* call the parent load function */
348   result = parent_load(image);
349   if (result != IMAGE_INIT_PASS)
350      return result;
351
352   /* configure IDE */
353   /* FIXME IDE */
354   /* ide_controller_init_custom(which_bus, intf, mess_hd_get_chd_file(image)); */
355   /* ide_controller_reset(which_bus); */
356   return IMAGE_INIT_PASS;
357#endif
358   return device_load_mess_hd( image );
359}
360
361
362static DEVICE_IMAGE_UNLOAD(mess_ide)
363{
364   /* old code from idedrive.c */
365#ifdef UNUSED_FUNCTION
366   int which_bus, which_address;
367   struct ide_interface *intf;
368   device_image_unload_func parent_unload;
369
370   /* get the basics */
371   ide_get_params(image, &which_bus, &which_address, &intf, NULL, NULL, &parent_unload);
372
373   /* call the parent unload function */
374   parent_unload(image);
375
376   /* configure IDE */
377   /* FIXME IDE */
378   /* ide_controller_init_custom(which_bus, intf, NULL); */
379   /* ide_controller_reset(which_bus); */
380#endif
381   device_unload_mess_hd( image );
382}
383
384
385DEVICE_GET_INFO(mess_ide)
386{
387   switch( state )
388   {
389      /* --- the following bits of info are returned as pointers to data or functions --- */
390      case DEVINFO_FCT_START:                  info->start = DEVICE_START_NAME(mess_ide); break;
391      case DEVINFO_FCT_IMAGE_LOAD:            info->f = (genf *) DEVICE_IMAGE_LOAD_NAME(mess_ide); break;
392      case DEVINFO_FCT_IMAGE_UNLOAD:            info->f = (genf *) DEVICE_IMAGE_UNLOAD_NAME(mess_ide); break;
393
394      /* --- the following bits of info are returned as NULL-terminated strings --- */
395      case DEVINFO_STR_NAME:                  strcpy(info->s, "IDE harddisk"); break;
396      case DEVINFO_STR_IMAGE_INSTANCE_NAME:      strcpy(info->s, "ideharddrive"); break;
397      case DEVINFO_STR_IMAGE_BRIEF_INSTANCE_NAME:   strcpy(info->s, "idehd"); break;
398
399      default:                           DEVICE_GET_INFO_CALL( mess_hd ); break;
400   }
401}
402
403DEFINE_LEGACY_IMAGE_DEVICE(HARDDISK, mess_hd);
404DEFINE_LEGACY_IMAGE_DEVICE(IDE_HARDDISK, mess_ide);
src/mess/devices/harddriv.h
r9927r9928
1/*********************************************************************
2
3    harddriv.h
4
5    MESS interface to the MAME CHD code
6
7*********************************************************************/
8
9#ifndef MESS_HD_H
10#define MESS_HD_H
11
12#include "image.h"
13#include "harddisk.h"
14
15DECLARE_LEGACY_IMAGE_DEVICE(HARDDISK, mess_hd);
16DECLARE_LEGACY_IMAGE_DEVICE(IDE_HARDDISK, mess_ide);
17
18#define MCFG_HARDDISK_ADD(_tag) \
19   MCFG_DEVICE_ADD(_tag, HARDDISK, 0) \
20
21#define MCFG_IDE_HARDDISK_ADD(_tag) \
22   MCFG_DEVICE_ADD(_tag, IDE_HARDDISK, 0) \
23
24hard_disk_file *mess_hd_get_hard_disk_file(device_t *device);
25chd_file *mess_hd_get_chd_file(device_t *device);
26
27struct harddisk_callback_config
28{
29   device_image_load_func      device_image_load;
30   device_image_unload_func   device_image_unload;
31};
32
33
34#endif /* MESS_HD_H */
src/mess/devices/z80bin.c
r9927r9928
1/*********************************************************************
2
3    z80bin.c
4
5    A binary quickload format used by the Microbee, the Exidy Sorcerer
6    VZ200/300 and the Super 80
7
8*********************************************************************/
9
10#include "emu.h"
11#include "z80bin.h"
12#include "snapquik.h"
13
14
15
16/***************************************************************************
17    INLINE FUNCTIONS
18***************************************************************************/
19
20/***************************************************************************
21    IMPLEMENTATION
22***************************************************************************/
23
24/*-------------------------------------------------
25    z80bin_load_file - load a z80bin file into
26    memory
27-------------------------------------------------*/
28
29static int z80bin_load_file(device_image_interface *image, const char *file_type, UINT16 *exec_addr, UINT16 *start_addr, UINT16 *end_addr )
30{
31   int ch;
32   UINT16 args[3];
33   UINT16 i=0, j, size;
34   UINT8 data;
35   char pgmname[256];
36   char message[256];
37
38   image->fseek(7, SEEK_SET);
39
40   while((ch = image->fgetc()) != 0x1A)
41   {
42      if (ch == EOF)
43      {
44         image->seterror(IMAGE_ERROR_INVALIDIMAGE, "Unexpected EOF while getting file name");
45         image->message(" Unexpected EOF while getting file name");
46         return IMAGE_INIT_FAIL;
47      }
48
49      if (ch != '\0')
50      {
51         if (i >= (ARRAY_LENGTH(pgmname) - 1))
52         {
53            image->seterror(IMAGE_ERROR_INVALIDIMAGE, "File name too long");
54            image->message(" File name too long");
55            return IMAGE_INIT_FAIL;
56         }
57
58         pgmname[i] = ch;   /* build program name */
59         i++;
60      }
61   }
62
63   pgmname[i] = '\0';   /* terminate string with a null */
64
65   if (image->fread(args, sizeof(args)) != sizeof(args))
66   {
67      image->seterror(IMAGE_ERROR_INVALIDIMAGE, "Unexpected EOF while getting file size");
68      image->message(" Unexpected EOF while getting file size");
69      return IMAGE_INIT_FAIL;
70   }
71
72   exec_addr[0] = LITTLE_ENDIANIZE_INT16(args[0]);
73   start_addr[0] = LITTLE_ENDIANIZE_INT16(args[1]);
74   end_addr[0]   = LITTLE_ENDIANIZE_INT16(args[2]);
75
76   size = (end_addr[0] - start_addr[0] + 1) & 0xffff;
77
78   /* display a message about the loaded quickload */
79   image->message(" %s\nsize=%04X : start=%04X : end=%04X : exec=%04X",pgmname,size,start_addr[0],end_addr[0],exec_addr[0]);
80
81   for (i = 0; i < size; i++)
82   {
83      j = (start_addr[0] + i) & 0xffff;
84      if (image->fread(&data, 1) != 1)
85      {
86         snprintf(message, ARRAY_LENGTH(message), "%s: Unexpected EOF while writing byte to %04X", pgmname, (unsigned) j);
87         image->seterror(IMAGE_ERROR_INVALIDIMAGE, message);
88         image->message("%s: Unexpected EOF while writing byte to %04X", pgmname, (unsigned) j);
89         return IMAGE_INIT_FAIL;
90      }
91      cputag_get_address_space(image->device().machine,"maincpu",ADDRESS_SPACE_PROGRAM)->write_byte(j, data);
92   }
93
94   return IMAGE_INIT_PASS;
95}
96
97
98
99/*-------------------------------------------------
100    QUICKLOAD_LOAD( z80bin )
101-------------------------------------------------*/
102
103static QUICKLOAD_LOAD( z80bin )
104{
105   const z80bin_config *config;
106   UINT16 exec_addr, start_addr, end_addr;
107   int autorun;
108
109   /* load the binary into memory */
110   if (z80bin_load_file(&image, file_type, &exec_addr, &start_addr, &end_addr) == IMAGE_INIT_FAIL)
111      return IMAGE_INIT_FAIL;
112
113   /* is this file executable? */
114   if (exec_addr != 0xffff)
115   {
116      config = (const z80bin_config *)downcast<const legacy_device_config_base &>(image.device().baseconfig()).inline_config();
117
118      /* check to see if autorun is on (I hate how this works) */
119      autorun = input_port_read_safe(image.device().machine, "CONFIG", 0xFF) & 1;
120
121      /* start program */
122      if (config->execute != NULL)
123      {
124         (*config->execute)(image.device().machine, start_addr, end_addr, exec_addr, autorun);
125      }
126      else
127      {
128         if (autorun)
129            cpu_set_reg(image.device().machine->device("maincpu"), STATE_GENPC, exec_addr);
130      }
131   }
132
133   return IMAGE_INIT_PASS;
134}
135
136
137
138/*-------------------------------------------------
139    DEVICE_GET_INFO(z80bin)
140-------------------------------------------------*/
141
142DEVICE_GET_INFO(z80bin)
143{
144   /* quickload */
145   switch(state)
146   {
147      /* --- the following bits of info are returned as 64-bit signed integers --- */
148      case DEVINFO_INT_INLINE_CONFIG_BYTES:         info->i = sizeof(z80bin_config); break;
149
150      /* --- the following bits of info are returned as NULL-terminated strings --- */
151      case DEVINFO_STR_SOURCE_FILE:               strcpy(info->s, __FILE__); break;
152      case DEVINFO_STR_IMAGE_FILE_EXTENSIONS:         strcpy(info->s, "bin"); break;
153
154      /* --- the following bits of info are returned as pointers to functions --- */
155      case DEVINFO_FCT_SNAPSHOT_QUICKLOAD_LOAD:      info->f = (genf *) quickload_load_z80bin; break;
156
157      default:   DEVICE_GET_INFO_CALL(quickload); break;
158   }
159}
160
161DEFINE_LEGACY_IMAGE_DEVICE(Z80BIN, z80bin);
src/mess/devices/cassette.c
r9927r9928
1/*********************************************************************
2
3    cassette.c
4
5    MESS interface to the cassette image abstraction code
6
7*********************************************************************/
8
9#include "emu.h"
10#include "imageutl.h"
11#include "cassette.h"
12#include "formats/cassimg.h"
13#include "ui.h"
14
15
16#define CASSETTE_TAG      "cassette"
17#define ANIMATION_FPS      1
18#define ANIMATION_FRAMES   4
19
20#define VERBOSE            0
21#define LOG(x) do { if (VERBOSE) logerror x; } while (0)
22
23
24typedef struct _dev_cassette_t   dev_cassette_t;
25struct _dev_cassette_t
26{
27   const cassette_config   *config;
28   cassette_image   *cassette;
29   cassette_state   state;
30   double         position;
31   double         position_time;
32   INT32         value;
33};
34
35
36/* Default cassette_config for drivers only wav files */
37const cassette_config default_cassette_config =
38{
39   cassette_default_formats,
40   NULL,
41   CASSETTE_PLAY,
42   NULL
43};
44
45
46INLINE dev_cassette_t *get_safe_token(device_t *device)
47{
48   assert( device != NULL );
49   assert( device->type() == CASSETTE );
50   return (dev_cassette_t *) downcast<legacy_device_base *>(device)->token();
51}
52
53
54/*********************************************************************
55    cassette IO
56*********************************************************************/
57
58INLINE int cassette_is_motor_on(device_t *device)
59{
60   dev_cassette_t   *cassette = get_safe_token( device );
61
62   if ((cassette->state & CASSETTE_MASK_UISTATE) == CASSETTE_STOPPED)
63      return FALSE;
64   if ((cassette->state & CASSETTE_MASK_MOTOR) != CASSETTE_MOTOR_ENABLED)
65      return FALSE;
66   return TRUE;
67}
68
69
70
71static void cassette_update(device_t *device)
72{
73   dev_cassette_t   *cassette = get_safe_token( device );
74   double cur_time = attotime_to_double(timer_get_time(device->machine));
75
76   if (cassette_is_motor_on(device))
77   {
78      double new_position = cassette->position + (cur_time - cassette->position_time);
79
80      switch(cassette->state & CASSETTE_MASK_UISTATE) {
81      case CASSETTE_RECORD:
82         cassette_put_sample(cassette->cassette, 0, cassette->position, new_position - cassette->position, cassette->value);
83         break;
84
85      case CASSETTE_PLAY:
86         if ( cassette->cassette )
87         {
88            cassette_get_sample(cassette->cassette, 0, new_position, 0.0, &cassette->value);
89            /* See if reached end of tape */
90            double length = cassette_get_length(device);
91            if (new_position > length)
92            {
93               cassette->state = (cassette_state)(( cassette->state & ~CASSETTE_MASK_UISTATE ) | CASSETTE_STOPPED);
94               new_position = length;
95            }
96         }
97         break;
98      }
99      cassette->position = new_position;
100   }
101   cassette->position_time = cur_time;
102}
103
104
105
106cassette_state cassette_get_state(device_t *device)
107{
108   dev_cassette_t   *cassette = get_safe_token( device );
109   return cassette->state;
110}
111
112
113
114void cassette_change_state(device_t *device, cassette_state state, cassette_state mask)
115{
116   dev_cassette_t   *cassette = get_safe_token( device );
117   cassette_state new_state;
118
119   new_state = cassette->state;
120   new_state = (cassette_state)(new_state & ~mask);
121   new_state = (cassette_state)(new_state | (state & mask));
122
123   if (new_state != cassette->state)
124   {
125      cassette_update(device);
126      cassette->state = new_state;
127   }
128}
129
130
131
132void cassette_set_state(device_t *device, cassette_state state)
133{
134   cassette_change_state(device, state, (cassette_state)(~0));
135}
136
137
138
139double cassette_input(device_t *device)
140{
141   dev_cassette_t   *cassette = get_safe_token( device );
142   INT32 sample;
143   double double_value;
144
145   cassette_update(device);
146   sample = cassette->value;
147   double_value = sample / ((double) 0x7FFFFFFF);
148
149   LOG(("cassette_input(): time_index=%g value=%g\n", cassette->position, double_value));
150
151   return double_value;
152}
153
154
155
156void cassette_output(device_t *device, double value)
157{
158   dev_cassette_t   *cassette = get_safe_token( device );
159
160   if (((cassette->state & CASSETTE_MASK_UISTATE) == CASSETTE_RECORD) && (cassette->value != value))
161   {
162      cassette_update(device);
163
164      value = MIN(value, 1.0);
165      value = MAX(value, -1.0);
166
167      cassette->value = (INT32) (value * 0x7FFFFFFF);
168   }
169}
170
171
172
173cassette_image *cassette_get_image(device_t *device)
174{
175   dev_cassette_t   *cassette = get_safe_token( device );
176
177   return cassette->cassette;
178}
179
180
181
182double cassette_get_position(device_t *device)
183{
184   dev_cassette_t   *cassette = get_safe_token( device );
185   double position;
186
187   position = cassette->position;
188
189   if (cassette_is_motor_on(device))
190      position += attotime_to_double(timer_get_time(device->machine)) - cassette->position_time;
191   return position;
192}
193
194
195
196double cassette_get_length(device_t *device)
197{
198   dev_cassette_t   *cassette = get_safe_token( device );
199   struct CassetteInfo info;
200
201   cassette_get_info(cassette->cassette, &info);
202   return ((double) info.sample_count) / info.sample_frequency;
203}
204
205
206
207void cassette_seek(device_t *device, double time, int origin)
208{
209   dev_cassette_t   *cassette = get_safe_token( device );
210
211   double length;
212
213   cassette_update(device);
214
215   length = cassette_get_length(device);
216
217   switch(origin) {
218   case SEEK_SET:
219      break;
220
221   case SEEK_END:
222      time += length;
223      break;
224
225   case SEEK_CUR:
226      time += cassette_get_position(device);
227      break;
228   }
229
230   /* clip position into legal bounds */
231   if (time < 0)
232      time = 0;
233   else
234   if (time > length)
235      time = length;
236
237   cassette->position = time;
238}
239
240
241
242/*********************************************************************
243    cassette device init/load/unload/specify
244*********************************************************************/
245
246static DEVICE_START( cassette )
247{
248   dev_cassette_t   *cassette = get_safe_token( device );
249
250   /* set to default state */
251   cassette->config = (const cassette_config*)device->baseconfig().static_config();
252   cassette->cassette = NULL;
253   cassette->state = cassette->config->default_state;
254}
255
256
257
258static DEVICE_IMAGE_LOAD( cassette )
259{
260   device_t *device = &image.device();
261   dev_cassette_t   *cassette = get_safe_token( device );
262   casserr_t err;
263   int cassette_flags;
264   const struct CassetteFormat * const *formats;
265   const struct CassetteOptions *create_opts;
266   const char *extension;
267   int is_writable;
268
269   /* figure out the cassette format */
270   formats = cassette->config->formats;
271
272   if (image.has_been_created())
273   {
274      /* creating an image */
275      create_opts = cassette->config->create_opts;
276      err = cassette_create(device->machine, (void *) &image, &image_ioprocs, &wavfile_format, create_opts, CASSETTE_FLAG_READWRITE|CASSETTE_FLAG_SAVEONEXIT, &cassette->cassette);
277      if (err)
278         goto error;
279   }
280   else
281   {
282      /* opening an image */
283      do
284      {
285         is_writable = image.is_writable();
286         cassette_flags = is_writable ? (CASSETTE_FLAG_READWRITE|CASSETTE_FLAG_SAVEONEXIT) : CASSETTE_FLAG_READONLY;
287         extension = image.filetype();
288         err = cassette_open_choices(device->machine,(void *) &image, &image_ioprocs, extension, formats, cassette_flags, &cassette->cassette);
289
290         /* this is kind of a hack */
291         if (err && is_writable)
292            image.make_readonly();
293      }
294      while(err && is_writable);
295
296      if (err)
297         goto error;
298   }
299
300   /* set to default state, but only change the UI state */
301   cassette_change_state(device, cassette->config->default_state, CASSETTE_MASK_UISTATE);
302
303   /* reset the position */
304   cassette->position = 0.0;
305   cassette->position_time = attotime_to_double(timer_get_time(device->machine));
306
307   return IMAGE_INIT_PASS;
308
309error:
310   return IMAGE_INIT_FAIL;
311}
312
313
314
315static DEVICE_IMAGE_UNLOAD( cassette )
316{
317   device_t *device = &image.device();
318   dev_cassette_t   *cassette = get_safe_token( device );
319
320   /* if we are recording, write the value to the image */
321   if ((cassette->state & CASSETTE_MASK_UISTATE) == CASSETTE_RECORD)
322      cassette_update(device);
323
324   /* close out the cassette */
325   cassette_close(cassette->cassette);
326   cassette->cassette = NULL;
327
328   /* set to default state, but only change the UI state */
329   cassette_change_state(device, CASSETTE_STOPPED, CASSETTE_MASK_UISTATE);
330}
331
332
333
334/*
335    display a small tape icon, with the current position in the tape image
336*/
337static DEVICE_IMAGE_DISPLAY(cassette)
338{
339   device_t *device = &image.device();
340   char buf[65];
341   float x, y;
342   int n;
343   double position, length;
344   cassette_state uistate;
345   device_t *dev;
346   static const UINT8 shapes[8] = { 0x2d, 0x5c, 0x7c, 0x2f, 0x2d, 0x20, 0x20, 0x20 };
347
348   /* abort if we should not be showing the image */
349   if (!image.exists())
350      return;
351   if (!cassette_is_motor_on(device))
352      return;
353
354   /* figure out where we are in the cassette */
355   position = cassette_get_position(device);
356   length = cassette_get_length(device);
357   uistate = (cassette_state)(cassette_get_state(device) & CASSETTE_MASK_UISTATE);
358
359   /* choose a location on the screen */
360   x = 0.2f;
361   y = 0.5f;
362
363   dev = device->machine->m_devicelist.first(CASSETTE );
364
365   while ( dev && strcmp( dev->tag(), device->tag() ) )
366   {
367      y += 1;
368      dev = dev->typenext();
369   }
370
371   y *= ui_get_line_height(*device->machine) + 2.0f * UI_BOX_TB_BORDER;
372   /* choose which frame of the animation we are at */
373   n = ((int) position / ANIMATION_FPS) % ANIMATION_FRAMES;
374   /* Since you can have anything in a BDF file, we will use crude ascii characters instead */
375   snprintf(buf, ARRAY_LENGTH(buf), "%c%c %c %02d:%02d (%04d) [%02d:%02d (%04d)]",
376#if 0
377   /* THE ANIMATION HASN'T WORKED SINCE 0.114 - LEFT HERE FOR REFERENCE */
378   /* NEVER SEEN THE PLAY / RECORD ICONS */
379   /* character pairs 2-3, 4-5, 6-7, 8-9 form little tape cassette images */
380      n * 2 + 2,                        /* cassette icon left */
381      n * 2 + 3,                        /* cassette icon right */
382      (uistate == CASSETTE_PLAY) ? 16 : 14,   /* play or record icon */
383#else
384      shapes[n],               /* cassette icon left */
385      shapes[n|4],               /* cassette icon right */
386      (uistate == CASSETTE_PLAY) ? 0x50 : 0x52,   /* play (P) or record (R) */
387#endif
388      ((int) position / 60),
389      ((int) position % 60),
390      (int) position,
391      ((int) length / 60),
392      ((int) length % 60),
393      (int) length);
394
395   /* draw the cassette */
396   ui_draw_text_box(&device->machine->render().ui_container(), buf, JUSTIFY_LEFT, x, y, UI_BACKGROUND_COLOR);
397}
398
399/*-------------------------------------------------
400    DEVICE_IMAGE_SOFTLIST_LOAD(cassette)
401-------------------------------------------------*/
402static DEVICE_IMAGE_SOFTLIST_LOAD(cassette)
403{
404   return image.load_software(swlist, swname, start_entry);
405}
406
407DEVICE_GET_INFO(cassette)
408{
409   switch( state )
410   {
411      /* --- the following bits of info are returned as 64-bit signed integers --- */
412      case DEVINFO_INT_TOKEN_BYTES:            info->i = sizeof(dev_cassette_t); break;
413      case DEVINFO_INT_INLINE_CONFIG_BYTES:      info->i = 0; break;
414      case DEVINFO_INT_IMAGE_TYPE:            info->i = IO_CASSETTE; break;
415      case DEVINFO_INT_IMAGE_READABLE:         info->i = 1; break;
416      case DEVINFO_INT_IMAGE_WRITEABLE:         info->i = 1; break;
417      case DEVINFO_INT_IMAGE_CREATABLE:         info->i = 1; break;
418
419      /* --- the following bits of info are returned as pointers to data or functions --- */
420      case DEVINFO_FCT_START:                  info->start = DEVICE_START_NAME(cassette); break;
421      case DEVINFO_FCT_IMAGE_LOAD:            info->f = (genf *) DEVICE_IMAGE_LOAD_NAME(cassette); break;
422      case DEVINFO_FCT_IMAGE_UNLOAD:            info->f = (genf *) DEVICE_IMAGE_UNLOAD_NAME(cassette); break;
423      case DEVINFO_FCT_IMAGE_DISPLAY:            info->f = (genf *) DEVICE_IMAGE_DISPLAY_NAME(cassette); break;
424      case DEVINFO_FCT_IMAGE_SOFTLIST_LOAD:      info->f = (genf *) DEVICE_IMAGE_SOFTLIST_LOAD_NAME(cassette);   break;
425
426      /* --- the following bits of info are returned as NULL-terminated strings --- */
427      case DEVINFO_STR_NAME:                  strcpy(info->s, "Cassette"); break;
428      case DEVINFO_STR_FAMILY:               strcpy(info->s, "Cassette"); break;
429      case DEVINFO_STR_SOURCE_FILE:            strcpy(info->s, __FILE__); break;
430      case DEVINFO_STR_IMAGE_FILE_EXTENSIONS:
431         if ( device && device->static_config() )
432         {
433            const struct CassetteFormat * const *formats = ((cassette_config *)device->static_config())->formats;
434            int      i;
435
436            /* set up a temporary string */
437            info->s[0] = '\0';
438
439            for ( i = 0; formats[i]; i++ )
440               image_specify_extension( info->s, 256, formats[i]->extensions );
441         }
442         break;
443      case DEVINFO_STR_IMAGE_INTERFACE:
444         if ( device && device->static_config() && ((cassette_config *)device->static_config())->interface)
445         {
446            strcpy(info->s, ((cassette_config *)device->static_config())->interface );
447         }
448         break;
449   }
450}
451
452DEFINE_LEGACY_IMAGE_DEVICE(CASSETTE, cassette);
src/mess/devices/flopdrv.c
r9927r9928
1/*
2    This code handles the floppy drives.
3    All FDD actions should be performed using these functions.
4
5    The functions are emulated and a disk image is used.
6
7  Real disk operation:
8  - set unit id
9
10  TODO:
11    - Override write protect if disk image has been opened in read mode
12*/
13
14#include "emu.h"
15#include "imageutl.h"
16#include "flopdrv.h"
17
18#define VERBOSE      0
19#define LOG(x) do { if (VERBOSE) logerror x; } while (0)
20
21/***************************************************************************
22    CONSTANTS
23***************************************************************************/
24
25#define FLOPDRVTAG   "flopdrv"
26#define LOG_FLOPPY      0
27
28/***************************************************************************
29    TYPE DEFINITIONS
30***************************************************************************/
31
32typedef struct _floppy_drive floppy_drive;
33struct _floppy_drive
34{
35   /* callbacks */
36   devcb_resolved_write_line out_idx_func;
37   devcb_resolved_read_line in_mon_func;
38   devcb_resolved_write_line out_tk00_func;
39   devcb_resolved_write_line out_wpt_func;
40   devcb_resolved_write_line out_rdy_func;
41   devcb_resolved_write_line out_dskchg_func;
42
43   /* state of input lines */
44   int drtn; /* direction */
45   int stp;  /* step */
46   int wtg;  /* write gate */
47   int mon;  /* motor on */
48
49   /* state of output lines */
50   int idx;  /* index pulse */
51   int tk00; /* track 00 */
52   int wpt;  /* write protect */
53   int rdy;  /* ready */
54   int dskchg;      /* disk changed */
55
56   /* drive select logic */
57   int drive_id;
58   int active;
59
60   const floppy_config   *config;
61
62   /* flags */
63   int flags;
64   /* maximum track allowed */
65   int max_track;
66   /* num sides */
67   int num_sides;
68   /* current track - this may or may not relate to the present cylinder number
69    stored by the fdc */
70   int current_track;
71
72   /* index pulse timer */
73   void   *index_timer;
74   /* index pulse callback */
75   void   (*index_pulse_callback)(device_t *controller,device_t *image, int state);
76   /* rotation per minute => gives index pulse frequency */
77   float rpm;
78
79   void   (*ready_state_change_callback)(device_t *controller,device_t *img, int state);
80
81   int id_index;
82
83   device_t *controller;
84
85   floppy_image *floppy;
86   int track;
87   void (*load_proc)(device_image_interface &image);
88   void (*unload_proc)(device_image_interface &image);
89   void *custom_data;
90   int floppy_drive_type;
91};
92
93
94typedef struct _floppy_error_map floppy_error_map;
95struct _floppy_error_map
96{
97   floperr_t ferr;
98   image_error_t ierr;
99   const char *message;
100};
101
102
103
104/***************************************************************************
105    GLOBAL VARIABLES
106***************************************************************************/
107
108static const floppy_error_map errmap[] =
109{
110   { FLOPPY_ERROR_SUCCESS,         IMAGE_ERROR_SUCCESS },
111   { FLOPPY_ERROR_INTERNAL,      IMAGE_ERROR_INTERNAL },
112   { FLOPPY_ERROR_UNSUPPORTED,      IMAGE_ERROR_UNSUPPORTED },
113   { FLOPPY_ERROR_OUTOFMEMORY,      IMAGE_ERROR_OUTOFMEMORY },
114   { FLOPPY_ERROR_INVALIDIMAGE,   IMAGE_ERROR_INVALIDIMAGE }
115};
116
117/***************************************************************************
118    IMPLEMENTATION
119***************************************************************************/
120DECLARE_LEGACY_IMAGE_DEVICE(FLOPPY_APPLE, apple525);
121DECLARE_LEGACY_IMAGE_DEVICE(FLOPPY_SONY, sonydriv);
122
123INLINE floppy_drive *get_safe_token(device_t *device)
124{
125   assert( device != NULL );
126   assert( device->type() == FLOPPY || device->type() == FLOPPY_APPLE || device->type() == FLOPPY_SONY);
127   return (floppy_drive *) downcast<legacy_device_base *>(device)->token();
128}
129
130floppy_image *flopimg_get_image(device_t *image)
131{
132   return get_safe_token(image)->floppy;
133}
134
135void *flopimg_get_custom_data(device_t *image)
136{
137   floppy_drive *flopimg = get_safe_token( image );
138   return flopimg->custom_data;
139}
140
141void flopimg_alloc_custom_data(device_t *image,void *custom)
142{
143   floppy_drive *flopimg = get_safe_token( image );
144   flopimg->custom_data = custom;
145}
146
147static int flopimg_get_sectors_per_track(device_t *image, int side)
148{
149   floperr_t err;
150   int sector_count;
151   floppy_drive *flopimg = get_safe_token( image );
152
153   if (!flopimg || !flopimg->floppy)
154      return 0;
155
156   err = floppy_get_sector_count(flopimg->floppy, side, flopimg->track, &sector_count);
157   if (err)
158      return 0;
159   return sector_count;
160}
161
162static void flopimg_get_id_callback(device_t *image, chrn_id *id, int id_index, int side)
163{
164   floppy_drive *flopimg;
165   int cylinder, sector, N;
166   unsigned long flags;
167   UINT32 sector_length;
168
169   flopimg = get_safe_token( image );
170   if (!flopimg || !flopimg->floppy)
171      return;
172
173   floppy_get_indexed_sector_info(flopimg->floppy, side, flopimg->track, id_index, &cylinder, &side, &sector, &sector_length, &flags);
174
175   N = compute_log2(sector_length);
176
177   id->C = cylinder;
178   id->H = side;
179   id->R = sector;
180   id->data_id = id_index;
181   id->flags = flags;
182   id->N = ((N >= 7) && (N <= 10)) ? N - 7 : 0;
183}
184
185static void log_readwrite(const char *name, int head, int track, int sector, const char *buf, int length)
186{
187   char membuf[1024];
188   int i;
189   for (i = 0; i < length; i++)
190      sprintf(membuf + i*2, "%02x", (int) (UINT8) buf[i]);
191   logerror("%s:  head=%i track=%i sector=%i buffer='%s'\n", name, head, track, sector, membuf);
192}
193
194static void floppy_drive_set_geometry_absolute(device_t *img, int tracks, int sides)
195{
196   floppy_drive *pDrive = get_safe_token( img );
197   pDrive->max_track = tracks;
198   pDrive->num_sides = sides;
199}
200
201void floppy_drive_set_geometry(device_t *img, floppy_type_t type)
202{
203   floppy_drive_set_geometry_absolute(img, type.max_track_number, type.head_number);
204}
205
206static TIMER_CALLBACK(floppy_drive_index_callback);
207
208/* this is called on device init */
209static void floppy_drive_init(device_t *img)
210{
211   floppy_drive *pDrive = get_safe_token( img );
212
213   /* initialise flags */
214   pDrive->flags = 0;
215   pDrive->index_pulse_callback = NULL;
216   pDrive->ready_state_change_callback = NULL;
217   pDrive->index_timer = timer_alloc(img->machine, floppy_drive_index_callback, (void *) img);
218   pDrive->idx = 0;
219
220   floppy_drive_set_geometry(img, ((floppy_config*)img->baseconfig().static_config())->floppy_type);
221
222   /* initialise id index - not so important */
223   pDrive->id_index = 0;
224   /* initialise track */
225   pDrive->current_track = 0;
226
227   /* default RPM */
228   pDrive->rpm = 300;
229
230   pDrive->controller = NULL;
231
232   pDrive->custom_data = NULL;
233
234   pDrive->floppy_drive_type = FLOPPY_TYPE_REGULAR;
235}
236
237/* index pulses at rpm/60 Hz, and stays high 1/20th of time */
238static void floppy_drive_index_func(device_t *img)
239{
240   floppy_drive *drive = get_safe_token( img );
241
242   double ms = 1000.0 / (drive->rpm / 60.0);
243
244   if (drive->idx)
245   {
246      drive->idx = 0;
247      timer_adjust_oneshot((emu_timer*)drive->index_timer, double_to_attotime(ms*19/20/1000.0), 0);
248   }
249   else
250   {
251      drive->idx = 1;
252      timer_adjust_oneshot((emu_timer*)drive->index_timer, double_to_attotime(ms/20/1000.0), 0);
253   }
254
255   devcb_call_write_line(&drive->out_idx_func, drive->idx);
256
257   if (drive->index_pulse_callback)
258      drive->index_pulse_callback(drive->controller, img, drive->idx);
259}
260
261static TIMER_CALLBACK(floppy_drive_index_callback)
262{
263   device_t *image = (device_t *) ptr;
264   floppy_drive_index_func(image);
265}
266
267/*************************************************************************/
268/* IO_FLOPPY device functions */
269
270/* set flag state */
271void floppy_drive_set_flag_state(device_t *img, int flag, int state)
272{
273   floppy_drive *drv = get_safe_token( img );
274   int prev_state;
275   int new_state;
276
277   /* get old state */
278   prev_state = drv->flags & flag;
279
280   /* set new state */
281   drv->flags &= ~flag;
282   if (state)
283      drv->flags |= flag;
284
285   /* get new state */
286   new_state = drv->flags & flag;
287
288   /* changed state? */
289   if (prev_state ^ new_state)
290   {
291      if (flag & FLOPPY_DRIVE_READY)
292      {
293         /* trigger state change callback */
294         devcb_call_write_line(&drv->out_rdy_func, new_state ? ASSERT_LINE : CLEAR_LINE);
295
296         if (drv->ready_state_change_callback)
297            drv->ready_state_change_callback(drv->controller, img, new_state);
298      }
299   }
300}
301
302/* for pc, drive is always ready, for amstrad,pcw,spectrum it is only ready under
303a fixed set of circumstances */
304/* use this to set ready state of drive */
305void floppy_drive_set_ready_state(device_t *img, int state, int flag)
306{
307   floppy_drive *drive = get_safe_token(img);
308   device_image_interface *image = dynamic_cast<device_image_interface *>(img);
309   if (flag)
310   {
311      /* set ready only if drive is present, disk is in the drive,
312        and disk motor is on - for Amstrad, Spectrum and PCW*/
313
314      /* drive present? */
315      /* disk inserted? */
316      if (image->exists())
317      {
318         if (drive->mon == CLEAR_LINE)
319         {
320            /* set state */
321            floppy_drive_set_flag_state(img, FLOPPY_DRIVE_READY, state);
322            return;
323         }
324      }
325      floppy_drive_set_flag_state(img, FLOPPY_DRIVE_READY, 0);
326   }
327   else
328   {
329      /* force ready state - for PC driver */
330      floppy_drive_set_flag_state(img, FLOPPY_DRIVE_READY, state);
331   }
332}
333
334/* get flag state */
335int   floppy_drive_get_flag_state(device_t *img, int flag)
336{
337   floppy_drive *drv = get_safe_token( img );
338   int drive_flags;
339   int flags;
340
341   flags = 0;
342
343   drive_flags = drv->flags;
344
345   /* these flags are independant of a real drive/disk image */
346    flags |= drive_flags & (FLOPPY_DRIVE_READY | FLOPPY_DRIVE_INDEX);
347
348    flags &= flag;
349
350   return flags;
351}
352
353
354void floppy_drive_seek(device_t *img, signed int signed_tracks)
355{
356   device_image_interface *image = dynamic_cast<device_image_interface *>(img);
357   floppy_drive *pDrive;
358
359   pDrive = get_safe_token( img );
360
361   LOG(("seek from: %d delta: %d\n",pDrive->current_track, signed_tracks));
362
363   /* update position */
364   pDrive->current_track+=signed_tracks;
365
366   if (pDrive->current_track<0)
367   {
368      pDrive->current_track = 0;
369   }
370   else
371   if (pDrive->current_track>=pDrive->max_track)
372   {
373      pDrive->current_track = pDrive->max_track-1;
374   }
375
376   /* set track 0 flag */
377   pDrive->tk00 = (pDrive->current_track == 0) ? CLEAR_LINE : ASSERT_LINE;
378   devcb_call_write_line(&pDrive->out_tk00_func, pDrive->tk00);
379
380   /* clear disk changed flag */
381   pDrive->dskchg = ASSERT_LINE;
382   //devcb_call_write_line(&flopimg->out_dskchg_func, flopimg->dskchg);
383
384   /* inform disk image of step operation so it can cache information */
385   if (image->exists())
386      pDrive->track = pDrive->current_track;
387
388   pDrive->id_index = 0;
389}
390
391
392/* this is not accurate. But it will do for now */
393int   floppy_drive_get_next_id(device_t *img, int side, chrn_id *id)
394{
395   floppy_drive *pDrive;
396   int spt;
397
398   pDrive = get_safe_token( img );
399
400   /* get sectors per track */
401   spt = flopimg_get_sectors_per_track(img, side);
402
403   /* set index */
404   if ((pDrive->id_index==(spt-1)) || (spt==0))
405   {
406      floppy_drive_set_flag_state(img, FLOPPY_DRIVE_INDEX, 1);
407   }
408   else
409   {
410      floppy_drive_set_flag_state(img, FLOPPY_DRIVE_INDEX, 0);
411   }
412
413   /* get id */
414   if (spt!=0)
415   {
416      flopimg_get_id_callback(img, id, pDrive->id_index, side);
417   }
418
419   pDrive->id_index++;
420   if (spt!=0)
421      pDrive->id_index %= spt;
422   else
423      pDrive->id_index = 0;
424
425   return (spt == 0) ? 0 : 1;
426}
427
428void floppy_drive_read_track_data_info_buffer(device_t *img, int side, void *ptr, int *length )
429{
430   floppy_drive *flopimg;
431   device_image_interface *image = dynamic_cast<device_image_interface *>(img);
432
433   if (image->exists())
434   {
435      flopimg = get_safe_token( img );
436      if (!flopimg || !flopimg->floppy)
437         return;
438
439      floppy_read_track_data(flopimg->floppy, side, flopimg->track, ptr, *length);
440   }
441}
442
443void floppy_drive_write_track_data_info_buffer(device_t *img, int side, const void *ptr, int *length )
444{
445   floppy_drive *flopimg;
446   device_image_interface *image = dynamic_cast<device_image_interface *>(img);
447
448   if (image->exists())
449   {
450      flopimg = get_safe_token( img );
451      if (!flopimg || !flopimg->floppy)
452         return;
453
454      floppy_write_track_data(flopimg->floppy, side, flopimg->track, ptr, *length);
455   }
456}
457
458void floppy_drive_format_sector(device_t *img, int side, int sector_index,int c,int h, int r, int n, int filler)
459{
460   device_image_interface *image = dynamic_cast<device_image_interface *>(img);
461
462   if (image->exists())
463   {
464/*      if (drv->interface_.format_sector)
465            drv->interface_.format_sector(img, side, sector_index,c, h, r, n, filler);*/
466   }
467}
468
469void floppy_drive_read_sector_data(device_t *img, int side, int index1, void *ptr, int length)
470{
471   floppy_drive *flopimg;
472   device_image_interface *image = dynamic_cast<device_image_interface *>(img);
473
474   if (image->exists())
475   {
476      flopimg = get_safe_token( img );
477      if (!flopimg || !flopimg->floppy)
478         return;
479
480      floppy_read_indexed_sector(flopimg->floppy, side, flopimg->track, index1, 0, ptr, length);
481
482      if (LOG_FLOPPY)
483         log_readwrite("sector_read", side, flopimg->track, index1, (const char *)ptr, length);
484
485   }
486}
487
488void floppy_drive_write_sector_data(device_t *img, int side, int index1, const void *ptr,int length, int ddam)
489{
490   floppy_drive *flopimg;
491   device_image_interface *image = dynamic_cast<device_image_interface *>(img);
492
493   if (image->exists())
494   {
495      flopimg = get_safe_token( img );
496      if (!flopimg || !flopimg->floppy)
497         return;
498
499      if (LOG_FLOPPY)
500         log_readwrite("sector_write", side, flopimg->track, index1, (const char *)ptr, length);
501
502      floppy_write_indexed_sector(flopimg->floppy, side, flopimg->track, index1, 0, ptr, length, ddam);
503   }
504}
505
506void floppy_install_load_proc(device_t *image, void (*proc)(device_image_interface &image))
507{
508   floppy_drive *flopimg = get_safe_token( image );
509   flopimg->load_proc = proc;
510}
511
512void floppy_install_unload_proc(device_t *image, void (*proc)(device_image_interface &image))
513{
514   floppy_drive *flopimg = get_safe_token( image );
515   flopimg->unload_proc = proc;
516}
517
518/* set the callback for the index pulse */
519void floppy_drive_set_index_pulse_callback(device_t *img, void (*callback)(device_t *controller,device_t *image, int state))
520{
521   floppy_drive *pDrive = get_safe_token( img );
522   pDrive->index_pulse_callback = callback;
523}
524
525
526void floppy_drive_set_ready_state_change_callback(device_t *img, void (*callback)(device_t *controller,device_t *img, int state))
527{
528   floppy_drive *pDrive = get_safe_token( img );
529   pDrive->ready_state_change_callback = callback;
530}
531
532int   floppy_drive_get_current_track(device_t *img)
533{
534   floppy_drive *drv = get_safe_token( img );
535   return drv->current_track;
536}
537
538UINT64 floppy_drive_get_current_track_size(device_t *img, int head)
539{
540   floppy_drive *drv = get_safe_token( img );
541   int size = 0;
542   device_image_interface *image = dynamic_cast<device_image_interface *>(img);
543
544   if (image->exists())
545   {
546      size = floppy_get_track_size(drv->floppy, head, drv->current_track);
547   }
548
549   return size;
550}
551
552void floppy_drive_set_rpm(device_t *img, float rpm)
553{
554   floppy_drive *drv = get_safe_token( img );
555   drv->rpm = rpm;
556}
557
558void floppy_drive_set_controller(device_t *img, device_t *controller)
559{
560   floppy_drive *drv = get_safe_token( img );
561   drv->controller = controller;
562}
563
564/* ----------------------------------------------------------------------- */
565DEVICE_START( floppy )
566{
567   floppy_drive *floppy = get_safe_token( device );
568   floppy->config = (const floppy_config*)device->baseconfig().static_config();
569   floppy_drive_init(device);
570
571   floppy->drive_id = floppy_get_drive(device);
572   floppy->active = FALSE;
573
574   /* resolve callbacks */
575   devcb_resolve_write_line(&floppy->out_idx_func, &floppy->config->out_idx_func, device);
576   devcb_resolve_read_line(&floppy->in_mon_func, &floppy->config->in_mon_func, device);
577   devcb_resolve_write_line(&floppy->out_tk00_func, &floppy->config->out_tk00_func, device);
578   devcb_resolve_write_line(&floppy->out_wpt_func, &floppy->config->out_wpt_func, device);
579   devcb_resolve_write_line(&floppy->out_rdy_func, &floppy->config->out_rdy_func, device);
580//  devcb_resolve_write_line(&floppy->out_dskchg_func, &floppy->config->out_dskchg_func, device);
581
582   /* by default we are not write-protected */
583   floppy->wpt = ASSERT_LINE;
584   devcb_call_write_line(&floppy->out_wpt_func, floppy->wpt);
585
586   /* not at track 0 */
587   floppy->tk00 = ASSERT_LINE;
588   devcb_call_write_line(&floppy->out_tk00_func, floppy->tk00);
589
590   /* motor off */
591   floppy->mon = ASSERT_LINE;
592
593   /* disk changed */
594   floppy->dskchg = CLEAR_LINE;
595//  devcb_call_write_line(&floppy->out_dskchg_func, floppy->dskchg);
596}
597
598static int internal_floppy_device_load(device_image_interface *image, int create_format, option_resolution *create_args)
599{
600   floperr_t err;
601   floppy_drive *flopimg;
602   const struct FloppyFormat *floppy_options;
603   int floppy_flags, i;
604   const char *extension;
605
606   /* look up instance data */
607   flopimg = get_safe_token( &image->device() );
608
609   /* figure out the floppy options */
610   floppy_options = ((floppy_config*)image->device().baseconfig().static_config())->formats;
611
612   if (image->has_been_created())
613   {
614      /* creating an image */
615      assert(create_format >= 0);
616      err = floppy_create((void *) image, &image_ioprocs, &floppy_options[create_format], create_args, &flopimg->floppy);
617      if (err)
618         goto error;
619   }
620   else
621   {
622      /* opening an image */
623      floppy_flags = image->is_writable() ? FLOPPY_FLAGS_READWRITE : FLOPPY_FLAGS_READONLY;
624      extension = image->filetype();
625      err = floppy_open_choices((void *) image, &image_ioprocs, extension, floppy_options, floppy_flags, &flopimg->floppy);
626      if (err)
627         goto error;
628   }
629   if (floppy_callbacks(flopimg->floppy)->get_heads_per_disk && floppy_callbacks(flopimg->floppy)->get_tracks_per_disk)
630   {
631      floppy_drive_set_geometry_absolute(&image->device(),
632         floppy_get_tracks_per_disk(flopimg->floppy),
633         floppy_get_heads_per_disk(flopimg->floppy));
634   }
635   return IMAGE_INIT_PASS;
636
637error:
638   for (i = 0; i < ARRAY_LENGTH(errmap); i++)
639   {
640      if (err == errmap[i].ferr)
641         image->seterror(errmap[i].ierr, errmap[i].message);
642   }
643   return IMAGE_INIT_FAIL;
644}
645
646static TIMER_CALLBACK( set_wpt )
647{
648   floppy_drive *flopimg = (floppy_drive *)ptr;
649
650   flopimg->wpt = param;
651   devcb_call_write_line(&flopimg->out_wpt_func, param);
652}
653
654DEVICE_IMAGE_LOAD( floppy )
655{
656   floppy_drive *flopimg;
657   int retVal = internal_floppy_device_load(&image, -1, NULL);
658   flopimg = get_safe_token( &image.device() );
659   if (retVal==IMAGE_INIT_PASS) {
660      /* if we have one of our hacky unload procs, call it */
661      if (flopimg->load_proc)
662         flopimg->load_proc(image);
663   }
664
665   /* push disk halfway into drive */
666   flopimg->wpt = CLEAR_LINE;
667   devcb_call_write_line(&flopimg->out_wpt_func, flopimg->wpt);
668
669   /* set timer for disk load */
670   int next_wpt;
671
672   if (image.is_writable())
673      next_wpt = ASSERT_LINE;
674   else
675      next_wpt = CLEAR_LINE;
676
677   timer_set(image.device().machine, ATTOTIME_IN_MSEC(250), flopimg, next_wpt, set_wpt);
678
679   return retVal;
680}
681
682DEVICE_IMAGE_CREATE( floppy )
683{
684   return internal_floppy_device_load(&image, create_format, create_args);
685}
686
687DEVICE_IMAGE_UNLOAD( floppy )
688{
689   floppy_drive *flopimg = get_safe_token( &image.device() );
690   if (flopimg->unload_proc)
691      flopimg->unload_proc(image);
692
693   floppy_close(flopimg->floppy);
694   flopimg->floppy = NULL;
695
696   /* disk changed */
697   flopimg->dskchg = CLEAR_LINE;
698   //devcb_call_write_line(&flopimg->out_dskchg_func, flopimg->dskchg);
699
700   /* pull disk halfway out of drive */
701   flopimg->wpt = CLEAR_LINE;
702   devcb_call_write_line(&flopimg->out_wpt_func, flopimg->wpt);
703
704   /* set timer for disk eject */
705   timer_set(image.device().machine, ATTOTIME_IN_MSEC(250), flopimg, ASSERT_LINE, set_wpt);
706}
707
708device_t *floppy_get_device(running_machine *machine,int drive)
709{
710   switch(drive) {
711      case 0 : return machine->device(FLOPPY_0);
712      case 1 : return machine->device(FLOPPY_1);
713      case 2 : return machine->device(FLOPPY_2);
714      case 3 : return machine->device(FLOPPY_3);
715   }
716   return NULL;
717}
718
719int floppy_get_drive_type(device_t *image)
720{
721   floppy_drive *flopimg = get_safe_token( image );
722   return flopimg->floppy_drive_type;
723}
724
725void floppy_set_type(device_t *image,int ftype)
726{
727   floppy_drive *flopimg = get_safe_token( image );
728   flopimg->floppy_drive_type = ftype;
729}
730
731device_t *floppy_get_device_by_type(running_machine *machine,int ftype,int drive)
732{
733   int i;
734   int cnt = 0;
735   for (i=0;i<4;i++) {
736      device_t *disk = floppy_get_device(machine,i);
737      if (floppy_get_drive_type(disk)==ftype) {
738         if (cnt==drive) {
739            return disk;
740         }
741         cnt++;
742      }
743   }
744   return NULL;
745}
746
747int floppy_get_drive(device_t *image)
748{
749   int drive =0;
750   if (strcmp(image->tag(), FLOPPY_0) == 0) drive = 0;
751   if (strcmp(image->tag(), FLOPPY_1) == 0) drive = 1;
752   if (strcmp(image->tag(), FLOPPY_2) == 0) drive = 2;
753   if (strcmp(image->tag(), FLOPPY_3) == 0) drive = 3;
754   return drive;
755}
756
757int floppy_get_drive_by_type(device_t *image,int ftype)
758{
759   int i,drive =0;
760   for (i=0;i<4;i++) {
761      device_t *disk = floppy_get_device(image->machine,i);
762      if (floppy_get_drive_type(disk)==ftype) {
763         if (image==disk) {
764            return drive;
765         }
766         drive++;
767      }
768   }
769   return drive;
770}
771
772int floppy_get_count(running_machine *machine)
773{
774   int cnt = 0;
775   if (machine->device(FLOPPY_0)) cnt++;
776    if (machine->device(FLOPPY_1)) cnt++;
777    if (machine->device(FLOPPY_2)) cnt++;
778    if (machine->device(FLOPPY_3)) cnt++;
779   return cnt;
780}
781
782
783/* drive select 0 */
784WRITE_LINE_DEVICE_HANDLER( floppy_ds0_w )
785{
786   floppy_drive *drive = get_safe_token(device);
787
788   if (state == CLEAR_LINE)
789      drive->active = (drive->drive_id == 0);
790}
791
792/* drive select 1 */
793WRITE_LINE_DEVICE_HANDLER( floppy_ds1_w )
794{
795   floppy_drive *drive = get_safe_token(device);
796
797   if (state == CLEAR_LINE)
798      drive->active = (drive->drive_id == 1);
799}
800
801/* drive select 2 */
802WRITE_LINE_DEVICE_HANDLER( floppy_ds2_w )
803{
804   floppy_drive *drive = get_safe_token(device);
805
806   if (state == CLEAR_LINE)
807      drive->active = (drive->drive_id == 2);
808}
809
810/* drive select 3 */
811WRITE_LINE_DEVICE_HANDLER( floppy_ds3_w )
812{
813   floppy_drive *drive = get_safe_token(device);
814
815   if (state == CLEAR_LINE)
816      drive->active = (drive->drive_id == 3);
817}
818
819/* shortcut to write all four ds lines */
820WRITE8_DEVICE_HANDLER( floppy_ds_w )
821{
822   floppy_ds0_w(device, BIT(data, 0));
823   floppy_ds1_w(device, BIT(data, 1));
824   floppy_ds2_w(device, BIT(data, 2));
825   floppy_ds3_w(device, BIT(data, 3));
826}
827
828/* motor on, active low */
829WRITE_LINE_DEVICE_HANDLER( floppy_mon_w )
830{
831   floppy_drive *drive = get_safe_token(device);
832   device_image_interface *image = dynamic_cast<device_image_interface *>(device);
833   /* force off if there is no attached image */
834   if (!image->exists())
835      state = ASSERT_LINE;
836
837   /* off -> on */
838   if (drive->mon && state == CLEAR_LINE)
839   {
840      drive->idx = 0;
841      floppy_drive_index_func(device);
842   }
843
844   /* on -> off */
845   else if (drive->mon == CLEAR_LINE && state)
846      timer_adjust_oneshot((emu_timer*)drive->index_timer, attotime_zero, 0);
847
848   drive->mon = state;
849}
850
851/* direction */
852WRITE_LINE_DEVICE_HANDLER( floppy_drtn_w )
853{
854   floppy_drive *drive = get_safe_token(device);
855   drive->drtn = state;
856}
857
858/* write data */
859WRITE_LINE_DEVICE_HANDLER( floppy_wtd_w )
860{
861
862}
863
864/* step */
865WRITE_LINE_DEVICE_HANDLER( floppy_stp_w )
866{
867   floppy_drive *drive = get_safe_token(device);
868
869   /* move head one track when going from high to low and write gate is high */
870   if (drive->active && drive->stp && state == CLEAR_LINE && drive->wtg)
871   {
872      /* move head according to the direction line */
873      if (drive->drtn)
874      {
875         /* move head outward */
876         if (drive->current_track > 0)
877            drive->current_track--;
878
879         /* are we at track 0 now? */
880         drive->tk00 = (drive->current_track == 0) ? CLEAR_LINE : ASSERT_LINE;
881      }
882      else
883      {
884         /* move head inward */
885         if (drive->current_track < drive->max_track)
886            drive->current_track++;
887
888         /* we can't be at track 0 here, so reset the line */
889         drive->tk00 = ASSERT_LINE;
890      }
891
892      /* update track 0 line with new status */
893      devcb_call_write_line(&drive->out_tk00_func, drive->tk00);
894   }
895
896   drive->stp = state;
897}
898
899/* write gate */
900WRITE_LINE_DEVICE_HANDLER( floppy_wtg_w )
901{
902   floppy_drive *drive = get_safe_token(device);
903   drive->wtg = state;
904}
905
906/* write protect signal, active low */
907READ_LINE_DEVICE_HANDLER( floppy_wpt_r )
908{
909   floppy_drive *drive = get_safe_token(device);
910   return drive->wpt;
911}
912
913/* track 0 detect */
914READ_LINE_DEVICE_HANDLER( floppy_tk00_r )
915{
916   floppy_drive *drive = get_safe_token(device);
917   return drive->tk00;
918}
919
920/* disk changed */
921READ_LINE_DEVICE_HANDLER( floppy_dskchg_r )
922{
923   floppy_drive *drive = get_safe_token(device);
924   return drive->dskchg;
925}
926
927/* 2-sided disk */
928READ_LINE_DEVICE_HANDLER( floppy_twosid_r )
929{
930   floppy_drive *drive = get_safe_token(device);
931
932   if (drive->floppy == NULL)
933      return ASSERT_LINE;
934   else
935      return !floppy_get_heads_per_disk(drive->floppy);
936}
937
938/*-------------------------------------------------
939    DEVICE_IMAGE_SOFTLIST_LOAD(floppy)
940-------------------------------------------------*/
941static DEVICE_IMAGE_SOFTLIST_LOAD(floppy)
942{
943   return image.load_software(swlist, swname, start_entry);
944}
945
946/*************************************
947 *
948 *  Device specification function
949 *
950 *************************************/
951/*-------------------------------------------------
952    safe_strcpy - hack
953-------------------------------------------------*/
954
955static void safe_strcpy(char *dst, const char *src)
956{
957   strcpy(dst, src ? src : "");
958}
959
960DEVICE_GET_INFO(floppy)
961{
962   switch( state )
963   {
964      /* --- the following bits of info are returned as 64-bit signed integers --- */
965      case DEVINFO_INT_TOKEN_BYTES:            info->i = sizeof(floppy_drive); break;
966      case DEVINFO_INT_INLINE_CONFIG_BYTES:      info->i = 0; break;
967      case DEVINFO_INT_IMAGE_TYPE:            info->i = IO_FLOPPY; break;
968      case DEVINFO_INT_IMAGE_READABLE:         info->i = 1; break;
969      case DEVINFO_INT_IMAGE_WRITEABLE:         info->i = 1; break;
970      case DEVINFO_INT_IMAGE_CREATABLE:
971                                 {
972                                    int cnt = 0;
973                                    if ( device && device->static_config() )
974                                    {
975                                       const struct FloppyFormat *floppy_options = ((floppy_config*)device->static_config())->formats;
976                                       int   i;
977                                       for ( i = 0; floppy_options[i].construct; i++ ) {
978                                          if(floppy_options[i].param_guidelines) cnt++;
979                                       }
980                                    }
981                                    info->i = (cnt>0) ? 1 : 0;
982                                 }
983                                 break;
984      /* --- the following bits of info are returned as pointers to data or functions --- */
985      case DEVINFO_FCT_START:                  info->start = DEVICE_START_NAME(floppy); break;
986      case DEVINFO_FCT_IMAGE_CREATE:            info->f = (genf *) DEVICE_IMAGE_CREATE_NAME(floppy); break;
987      case DEVINFO_FCT_IMAGE_LOAD:            info->f = (genf *) DEVICE_IMAGE_LOAD_NAME(floppy); break;
988      case DEVINFO_FCT_IMAGE_UNLOAD:            info->f = (genf *) DEVICE_IMAGE_UNLOAD_NAME(floppy); break;
989      case DEVINFO_FCT_IMAGE_SOFTLIST_LOAD:      info->f = (genf *) DEVICE_IMAGE_SOFTLIST_LOAD_NAME(floppy);   break;
990      case DEVINFO_PTR_IMAGE_CREATE_OPTGUIDE:      info->p = (void *)floppy_option_guide; break;
991      case DEVINFO_INT_IMAGE_CREATE_OPTCOUNT:
992      {
993         const struct FloppyFormat *floppy_options = ((floppy_config*)device->static_config())->formats;
994         int count;
995         for (count = 0; floppy_options[count].construct; count++)
996            ;
997         info->i = count;
998         break;
999      }
1000
1001      /* --- the following bits of info are returned as NULL-terminated strings --- */
1002      case DEVINFO_STR_NAME:                  strcpy(info->s, "Floppy Disk"); break;
1003      case DEVINFO_STR_FAMILY:               strcpy(info->s, "Floppy Disk"); break;
1004      case DEVINFO_STR_SOURCE_FILE:            strcpy(info->s, __FILE__); break;
1005      case DEVINFO_STR_IMAGE_FILE_EXTENSIONS:
1006         if ( device && device->static_config() )
1007         {
1008            const struct FloppyFormat *floppy_options = ((floppy_config*)device->static_config())->formats;
1009            int      i;
1010            /* set up a temporary string */
1011            info->s[0] = '\0';
1012            for ( i = 0; floppy_options[i].construct; i++ )
1013               image_specify_extension( info->s, 256, floppy_options[i].extensions );
1014         }
1015         break;
1016      case DEVINFO_STR_IMAGE_INTERFACE:
1017         if ( device && device->static_config() && ((floppy_config *)device->static_config())->interface)
1018         {
1019            strcpy(info->s, ((floppy_config *)device->static_config())->interface );
1020         }
1021         break;
1022      default:
1023         {
1024            if ( device && device->static_config() )
1025            {
1026               const struct FloppyFormat *floppy_options = ((floppy_config*)device->static_config())->formats;
1027               if ((state >= DEVINFO_PTR_IMAGE_CREATE_OPTSPEC) && (state < DEVINFO_PTR_IMAGE_CREATE_OPTSPEC + DEVINFO_IMAGE_CREATE_OPTMAX)) {
1028                  info->p = (void *) floppy_options[state - DEVINFO_PTR_IMAGE_CREATE_OPTSPEC].param_guidelines;
1029               } else if ((state >= DEVINFO_STR_IMAGE_CREATE_OPTNAME) && (state < DEVINFO_STR_IMAGE_CREATE_OPTNAME + DEVINFO_IMAGE_CREATE_OPTMAX)) {
1030                  safe_strcpy(info->s,floppy_options[state - DEVINFO_STR_IMAGE_CREATE_OPTNAME].name);
1031               }
1032               else if ((state >= DEVINFO_STR_IMAGE_CREATE_OPTDESC) && (state < DEVINFO_STR_IMAGE_CREATE_OPTDESC + DEVINFO_IMAGE_CREATE_OPTMAX)) {
1033                  safe_strcpy(info->s,floppy_options[state - DEVINFO_STR_IMAGE_CREATE_OPTDESC].description);
1034               }
1035               else if ((state >= DEVINFO_STR_IMAGE_CREATE_OPTEXTS) && (state < DEVINFO_STR_IMAGE_CREATE_OPTEXTS + DEVINFO_IMAGE_CREATE_OPTMAX)) {
1036                  safe_strcpy(info->s,floppy_options[state - DEVINFO_STR_IMAGE_CREATE_OPTEXTS].extensions);
1037               }
1038            }
1039         }
1040
1041         break;
1042   }
1043}
1044
1045DEFINE_LEGACY_IMAGE_DEVICE(FLOPPY, floppy);
src/mess/devices/z80bin.h
r9927r9928
1/*********************************************************************
2
3    z80bin.h
4
5    A binary quickload format used by the Microbee, the Exidy Sorcerer
6    VZ200/300 and the Super 80
7
8*********************************************************************/
9
10#ifndef __Z80BIN_H__
11#define __Z80BIN_H__
12
13#include "image.h"
14#include "snapquik.h"
15
16
17/***************************************************************************
18    MACROS
19***************************************************************************/
20
21DECLARE_LEGACY_IMAGE_DEVICE(Z80BIN, z80bin);
22
23#define Z80BIN_EXECUTE_NAME(name)   z80bin_execute_##name
24#define Z80BIN_EXECUTE(name)      void Z80BIN_EXECUTE_NAME(name)(running_machine *machine, UINT16 start_address, UINT16 end_address, UINT16 execute_address, int autorun)
25
26#define z80bin_execute_default      NULL
27
28
29
30/***************************************************************************
31    TYPE DEFINITIONS
32***************************************************************************/
33
34typedef void (*z80bin_execute_func)(running_machine *machine, UINT16 start_address, UINT16 end_address, UINT16 execute_address, int autorun);
35
36typedef struct _z80bin_config z80bin_config;
37struct _z80bin_config
38{
39   snapquick_config base;
40   z80bin_execute_func execute;
41};
42
43
44
45/***************************************************************************
46    Z80BIN QUICKLOAD DEVICE CONFIGURATION MACROS
47***************************************************************************/
48
49#define MCFG_Z80BIN_QUICKLOAD_ADD(_tag, _execute, _delay) \
50   MCFG_DEVICE_ADD(_tag, Z80BIN, 0) \
51   MCFG_DEVICE_CONFIG_DATA64(snapquick_config, delay_seconds, (seconds_t) (_delay)) \
52   MCFG_DEVICE_CONFIG_DATA64(snapquick_config, delay_attoseconds, (attoseconds_t) (((_delay) - (int)(_delay)) * ATTOSECONDS_PER_SECOND)) \
53   MCFG_DEVICE_CONFIG_DATAPTR(z80bin_config, execute, Z80BIN_EXECUTE_NAME(_execute))
54
55#endif /* __Z80BIN_H__ */
src/mess/devices/cassette.h
r9927r9928
1/*********************************************************************
2
3    cassette.h
4
5    MESS interface to the cassette image abstraction code
6
7*********************************************************************/
8
9#ifndef CASSETTE_H
10#define CASSETTE_H
11
12#include "image.h"
13#include "formats/cassimg.h"
14
15
16enum _cassette_state
17{
18   /* this part of the state is controlled by the UI */
19   CASSETTE_STOPPED         = 0,
20   CASSETTE_PLAY            = 1,
21   CASSETTE_RECORD            = 2,
22
23   /* this part of the state is controlled by drivers */
24   CASSETTE_MOTOR_ENABLED      = 0,
25   CASSETTE_MOTOR_DISABLED      = 4,
26   CASSETTE_SPEAKER_ENABLED   = 0,
27   CASSETTE_SPEAKER_MUTED      = 8,
28
29   /* masks */
30   CASSETTE_MASK_UISTATE      = 3,
31   CASSETTE_MASK_MOTOR         = 4,
32   CASSETTE_MASK_SPEAKER      = 8,
33   CASSETTE_MASK_DRVSTATE      = 12
34};
35
36typedef enum _cassette_state cassette_state;
37
38
39/***************************************************************************
40    TYPE DEFINITIONS
41***************************************************************************/
42
43typedef struct cassette_config_t   cassette_config;
44struct cassette_config_t
45{
46   const struct CassetteFormat*   const *formats;
47   const struct CassetteOptions   *create_opts;
48   const cassette_state         default_state;
49   const char *               interface;
50};
51
52
53/***************************************************************************
54    FUNCTION PROTOTYPES
55***************************************************************************/
56
57cassette_state cassette_get_state(device_t *cassette);
58void cassette_set_state(device_t *cassette, cassette_state state);
59void cassette_change_state(device_t *cassette, cassette_state state, cassette_state mask);
60
61double cassette_input(device_t *cassette);
62void cassette_output(device_t *cassette, double value);
63
64cassette_image *cassette_get_image(device_t *cassette);
65double cassette_get_position(device_t *cassette);
66double cassette_get_length(device_t *cassette);
67void cassette_seek(device_t *cassette, double time, int origin);
68
69DECLARE_LEGACY_IMAGE_DEVICE(CASSETTE, cassette);
70
71/***************************************************************************
72    DEVICE CONFIGURATION MACROS
73***************************************************************************/
74
75#define MCFG_CASSETTE_ADD(_tag, _config)   \
76   MCFG_DEVICE_ADD(_tag, CASSETTE, 0)         \
77   MCFG_DEVICE_CONFIG(_config)
78
79#define MCFG_CASSETTE_MODIFY(_tag, _config)   \
80   MCFG_DEVICE_MODIFY(_tag)      \
81   MCFG_DEVICE_CONFIG(_config)
82
83extern const cassette_config default_cassette_config;
84
85#endif /* CASSETTE_H */
src/mess/devices/flopdrv.h
r9927r9928
1/* flopdrv provides simple emulation of a disc drive */
2/* the 8271, upd765 and wd179x use this */
3
4#ifndef __FLOPDRV_H__
5#define __FLOPDRV_H__
6
7#include "devcb.h"
8#include "image.h"
9#include "formats/flopimg.h"
10
11#define FLOPPY_TYPE_REGULAR 0
12#define FLOPPY_TYPE_APPLE   1
13#define FLOPPY_TYPE_SONY   2
14
15#define FLOPPY_DRIVE_2_8_INCH   1
16#define FLOPPY_DRIVE_3_INCH      2
17#define FLOPPY_DRIVE_3_5_INCH   3
18#define FLOPPY_DRIVE_5_25_INCH   4
19#define FLOPPY_DRIVE_8_INCH      5
20
21// Maximum supported density
22#define FLOPPY_DRIVE_SD 1
23#define FLOPPY_DRIVE_DD 2
24#define FLOPPY_DRIVE_QD 3
25#define FLOPPY_DRIVE_HD 4
26#define FLOPPY_DRIVE_ED 5
27
28#define FLOPPY_STANDARD_3_SSDD       { FLOPPY_DRIVE_3_INCH,    1, 42, FLOPPY_DRIVE_DD }
29#define FLOPPY_STANDARD_3_DSDD       { FLOPPY_DRIVE_3_INCH,    2, 42, FLOPPY_DRIVE_DD }
30#define FLOPPY_STANDARD_3_5_DSDD     { FLOPPY_DRIVE_3_5_INCH,  2, 83, FLOPPY_DRIVE_DD }
31#define FLOPPY_STANDARD_3_5_DSHD     { FLOPPY_DRIVE_3_5_INCH,  2, 83, FLOPPY_DRIVE_HD }
32#define FLOPPY_STANDARD_5_25_SSSD_35 { FLOPPY_DRIVE_5_25_INCH, 1, 37, FLOPPY_DRIVE_SD }
33#define FLOPPY_STANDARD_5_25_DSSD_35 { FLOPPY_DRIVE_5_25_INCH, 2, 37, FLOPPY_DRIVE_SD }
34#define FLOPPY_STANDARD_5_25_SSSD    { FLOPPY_DRIVE_5_25_INCH, 1, 42, FLOPPY_DRIVE_SD }
35#define FLOPPY_STANDARD_5_25_DSSD    { FLOPPY_DRIVE_5_25_INCH, 2, 42, FLOPPY_DRIVE_SD }
36#define FLOPPY_STANDARD_5_25_SSDD_40 { FLOPPY_DRIVE_5_25_INCH, 1, 42, FLOPPY_DRIVE_DD }
37#define FLOPPY_STANDARD_5_25_DSDD_40 { FLOPPY_DRIVE_5_25_INCH, 2, 42, FLOPPY_DRIVE_DD }
38#define FLOPPY_STANDARD_5_25_SSDD    { FLOPPY_DRIVE_5_25_INCH, 1, 83, FLOPPY_DRIVE_DD }
39#define FLOPPY_STANDARD_5_25_DSDD    { FLOPPY_DRIVE_5_25_INCH, 2, 83, FLOPPY_DRIVE_DD }
40#define FLOPPY_STANDARD_5_25_DSQD    { FLOPPY_DRIVE_5_25_INCH, 2, 83, FLOPPY_DRIVE_QD }
41#define FLOPPY_STANDARD_5_25_DSHD    { FLOPPY_DRIVE_5_25_INCH, 2, 83, FLOPPY_DRIVE_HD }
42#define FLOPPY_STANDARD_8_SSSD       { FLOPPY_DRIVE_8_INCH,    1, 77, FLOPPY_DRIVE_SD }
43#define FLOPPY_STANDARD_8_DSSD       { FLOPPY_DRIVE_8_INCH,    2, 77, FLOPPY_DRIVE_SD }
44#define FLOPPY_STANDARD_8_DSDD       { FLOPPY_DRIVE_8_INCH,    2, 77, FLOPPY_DRIVE_DD }
45
46/***************************************************************************
47    TYPE DEFINITIONS
48***************************************************************************/
49typedef struct floppy_type_t   floppy_type;
50struct floppy_type_t
51{
52   UINT8 media_size;
53   UINT8 head_number;
54   UINT8 max_track_number;
55   UINT8 max_density;
56};
57
58typedef struct floppy_config_t   floppy_config;
59struct floppy_config_t
60{
61   devcb_write_line out_idx_func;  /* index */
62   devcb_read_line  in_mon_func;   /* motor on */
63   devcb_write_line out_tk00_func; /* track 00 */
64   devcb_write_line out_wpt_func;  /* write protect */
65   devcb_write_line out_rdy_func;  /* ready */
66//  devcb_write_line out_dskchg_func;  /* disk changed */
67
68   floppy_type_t floppy_type;
69   const struct FloppyFormat *formats;
70   const char *interface;
71};
72
73/* sector has a deleted data address mark */
74#define ID_FLAG_DELETED_DATA   0x0001
75/* CRC error in id field */
76#define ID_FLAG_CRC_ERROR_IN_ID_FIELD 0x0002
77/* CRC error in data field */
78#define ID_FLAG_CRC_ERROR_IN_DATA_FIELD 0x0004
79
80typedef struct chrn_id
81{
82   unsigned char C;
83   unsigned char H;
84   unsigned char R;
85   unsigned char N;
86   int data_id;         // id for read/write data command
87   unsigned long flags;
88} chrn_id;
89
90/* set if drive is ready */
91#define FLOPPY_DRIVE_READY                  0x0010
92/* set if index has just occured */
93#define FLOPPY_DRIVE_INDEX                  0x0020
94
95/* a callback which will be executed if the ready state of the drive changes e.g. not ready->ready, ready->not ready */
96void floppy_drive_set_ready_state_change_callback(device_t *img, void (*callback)(device_t *controller,device_t *img, int state));
97
98void floppy_drive_set_index_pulse_callback(device_t *img, void (*callback)(device_t *controller,device_t *image, int state));
99
100/* set flag state */
101int floppy_drive_get_flag_state(device_t *img, int flag);
102/* get flag state */
103void floppy_drive_set_flag_state(device_t *img, int flag, int state);
104/* get current physical track drive is on */
105int floppy_drive_get_current_track(device_t *img);
106/* get current physical track size */
107UINT64 floppy_drive_get_current_track_size(device_t *img, int head);
108
109/* get next id from track, 1 if got a id, 0 if no id was got */
110int floppy_drive_get_next_id(device_t *img, int side, chrn_id *);
111/* set ready state of drive. If flag == 1, set ready state only if drive present,
112disk is in drive, and motor is on. Otherwise set ready state to the state passed */
113void floppy_drive_set_ready_state(device_t *img, int state, int flag);
114
115/* seek up or down */
116void floppy_drive_seek(device_t *img, signed int signed_tracks);
117
118void floppy_drive_read_track_data_info_buffer(device_t *img, int side, void *ptr, int *length );
119void floppy_drive_write_track_data_info_buffer(device_t *img, int side, const void *ptr, int *length );
120void floppy_drive_format_sector(device_t *img, int side, int sector_index, int c, int h, int r, int n, int filler);
121void floppy_drive_read_sector_data(device_t *img, int side, int index1, void *pBuffer, int length);
122void floppy_drive_write_sector_data(device_t *img, int side, int index1, const void *pBuffer, int length, int ddam);
123
124/* set motor speed to get correct index pulses
125   standard RPM are 300 RPM (common) and 360 RPM
126   Note: this actually only works for soft sectored disks: one index pulse per
127   track.
128*/
129void floppy_drive_set_rpm(device_t *image, float rpm);
130
131void floppy_drive_set_controller(device_t *img, device_t *controller);
132
133floppy_image *flopimg_get_image(device_t *image);
134
135/* hack for apple II; replace this when we think of something better */
136void floppy_install_unload_proc(device_t *image, void (*proc)(device_image_interface &image));
137
138void floppy_install_load_proc(device_t *image, void (*proc)(device_image_interface &image));
139
140device_t *floppy_get_device(running_machine *machine,int drive);
141device_t *floppy_get_device_by_type(running_machine *machine,int ftype,int drive);
142int floppy_get_drive_type(device_t *image);
143void floppy_set_type(device_t *image,int ftype);
144int floppy_get_count(running_machine *machine);
145
146int floppy_get_drive(device_t *image);
147int floppy_get_drive_by_type(device_t *image,int ftype);
148
149void *flopimg_get_custom_data(device_t *image);
150void flopimg_alloc_custom_data(device_t *image,void *custom);
151
152void floppy_drive_set_geometry(device_t *img, floppy_type_t type);
153
154/* drive select lines */
155WRITE_LINE_DEVICE_HANDLER( floppy_ds0_w );
156WRITE_LINE_DEVICE_HANDLER( floppy_ds1_w );
157WRITE_LINE_DEVICE_HANDLER( floppy_ds2_w );
158WRITE_LINE_DEVICE_HANDLER( floppy_ds3_w );
159WRITE8_DEVICE_HANDLER( floppy_ds_w );
160
161WRITE_LINE_DEVICE_HANDLER( floppy_mon_w );
162WRITE_LINE_DEVICE_HANDLER( floppy_drtn_w );
163WRITE_LINE_DEVICE_HANDLER( floppy_stp_w );
164WRITE_LINE_DEVICE_HANDLER( floppy_wtd_w );
165WRITE_LINE_DEVICE_HANDLER( floppy_wtg_w );
166
167/* write-protect */
168READ_LINE_DEVICE_HANDLER( floppy_wpt_r );
169
170/* track 0 detect */
171READ_LINE_DEVICE_HANDLER( floppy_tk00_r );
172
173/* disk changed */
174READ_LINE_DEVICE_HANDLER( floppy_dskchg_r );
175
176/* 2-sided disk */
177READ_LINE_DEVICE_HANDLER( floppy_twosid_r );
178
179DECLARE_LEGACY_IMAGE_DEVICE(FLOPPY, floppy);
180
181extern DEVICE_START( floppy );
182extern DEVICE_IMAGE_LOAD( floppy );
183extern DEVICE_IMAGE_CREATE( floppy );
184extern DEVICE_IMAGE_UNLOAD( floppy );
185
186/***************************************************************************
187    DEVICE CONFIGURATION MACROS
188***************************************************************************/
189#define FLOPPY_0 "floppy0"
190#define FLOPPY_1 "floppy1"
191#define FLOPPY_2 "floppy2"
192#define FLOPPY_3 "floppy3"
193
194
195#define MCFG_FLOPPY_DRIVE_ADD(_tag, _config)   \
196   MCFG_DEVICE_ADD(_tag, FLOPPY, 0)         \
197   MCFG_DEVICE_CONFIG(_config)
198
199#define MCFG_FLOPPY_DRIVE_MODIFY(_tag, _config)   \
200   MCFG_DEVICE_MODIFY(_tag)      \
201   MCFG_DEVICE_CONFIG(_config)
202
203#define MCFG_FLOPPY_4_DRIVES_ADD(_config)   \
204   MCFG_DEVICE_ADD(FLOPPY_0, FLOPPY, 0)      \
205   MCFG_DEVICE_CONFIG(_config)   \
206   MCFG_DEVICE_ADD(FLOPPY_1, FLOPPY, 0)      \
207   MCFG_DEVICE_CONFIG(_config)   \
208   MCFG_DEVICE_ADD(FLOPPY_2, FLOPPY, 0)      \
209   MCFG_DEVICE_CONFIG(_config)   \
210   MCFG_DEVICE_ADD(FLOPPY_3, FLOPPY, 0)      \
211   MCFG_DEVICE_CONFIG(_config)
212
213#define MCFG_FLOPPY_4_DRIVES_MODIFY(_config)   \
214   MCFG_DEVICE_MODIFY(FLOPPY_0)      \
215   MCFG_DEVICE_CONFIG(_config)   \
216   MCFG_DEVICE_MODIFY(FLOPPY_1)      \
217   MCFG_DEVICE_CONFIG(_config)   \
218   MCFG_DEVICE_MODIFY(FLOPPY_2)      \
219   MCFG_DEVICE_CONFIG(_config)   \
220   MCFG_DEVICE_MODIFY(FLOPPY_3)      \
221   MCFG_DEVICE_CONFIG(_config)
222
223#define MCFG_FLOPPY_4_DRIVES_REMOVE()   \
224   MCFG_DEVICE_REMOVE(FLOPPY_0)      \
225   MCFG_DEVICE_REMOVE(FLOPPY_1)      \
226   MCFG_DEVICE_REMOVE(FLOPPY_2)      \
227   MCFG_DEVICE_REMOVE(FLOPPY_3)
228
229#define MCFG_FLOPPY_2_DRIVES_ADD(_config)   \
230   MCFG_DEVICE_ADD(FLOPPY_0, FLOPPY, 0)      \
231   MCFG_DEVICE_CONFIG(_config)   \
232   MCFG_DEVICE_ADD(FLOPPY_1, FLOPPY, 0)      \
233   MCFG_DEVICE_CONFIG(_config)
234
235#define MCFG_FLOPPY_2_DRIVES_MODIFY(_config)   \
236   MCFG_DEVICE_MODIFY(FLOPPY_0)      \
237   MCFG_DEVICE_CONFIG(_config)   \
238   MCFG_DEVICE_MODIFY(FLOPPY_1)      \
239   MCFG_DEVICE_CONFIG(_config)
240
241#define MCFG_FLOPPY_2_DRIVES_REMOVE()   \
242   MCFG_DEVICE_REMOVE(FLOPPY_0)      \
243   MCFG_DEVICE_REMOVE(FLOPPY_1)
244
245#endif /* __FLOPDRV_H__ */
src/mess/devices/cartslot.c
r9927r9928
1/**********************************************************************
2
3    cartslot.c
4
5    Cartridge device
6
7**********************************************************************/
8
9#include <ctype.h>
10#include "emu.h"
11#include "cartslot.h"
12#include "multcart.h"
13
14/***************************************************************************
15    CONSTANTS
16***************************************************************************/
17
18enum _process_mode
19{
20   PROCESS_CLEAR,
21   PROCESS_LOAD
22};
23typedef enum _process_mode process_mode;
24
25
26/***************************************************************************
27    INLINE FUNCTIONS
28***************************************************************************/
29
30INLINE cartslot_t *get_token(device_t *device)
31{
32   assert(device != NULL);
33   assert(device->type() == CARTSLOT);
34   return (cartslot_t *) downcast<legacy_device_base *>(device)->token();
35}
36
37
38INLINE const cartslot_config *get_config(device_t *device)
39{
40   assert(device != NULL);
41   assert(device->type() == CARTSLOT);
42   return (const cartslot_config *) downcast<const legacy_device_config_base &>(device->baseconfig()).inline_config();
43}
44
45INLINE const cartslot_config *get_config_dev(const device_config *device)
46{
47   assert(device != NULL);
48   assert(device->type() == CARTSLOT);
49   return (const cartslot_config *)downcast<const legacy_device_config_base *>(device)->inline_config();
50}
51
52/***************************************************************************
53    IMPLEMENTATION
54***************************************************************************/
55
56/*-------------------------------------------------
57    load_cartridge
58-------------------------------------------------*/
59
60static int load_cartridge(device_image_interface *image, const rom_entry *romrgn, const rom_entry *roment, process_mode mode)
61{
62   const char *region;
63   const char *type;
64   UINT32 flags;
65   offs_t offset, length, read_length, pos = 0, len;
66   UINT8 *ptr;
67   UINT8 clear_val;
68   int datawidth, littleendian, i, j;
69   device_t *cpu;
70
71   region = ROMREGION_GETTAG(romrgn);
72   offset = ROM_GETOFFSET(roment);
73   length = ROM_GETLENGTH(roment);
74   flags = ROM_GETFLAGS(roment);
75   ptr = ((UINT8 *) image->device().machine->region(region)->base()) + offset;
76
77   if (mode == PROCESS_LOAD)
78   {
79      if (image->software_entry() == NULL)
80      {
81         /* must this be full size */
82         if (flags & ROM_FULLSIZE)
83         {
84            if (image->length() != length)
85               return IMAGE_INIT_FAIL;
86         }
87
88         /* read the ROM */
89         pos = read_length = image->fread(ptr, length);
90
91         /* reset the ROM to the initial point. */
92         /* eventually, we could add a flag to allow the ROM to continue instead of restarting whenever a new cart region is present */
93         image->fseek(0, SEEK_SET);
94      }
95      else
96      {
97         /* must this be full size */
98         if (flags & ROM_FULLSIZE)
99         {
100            if (image->get_software_region_length("rom") != length)
101               return IMAGE_INIT_FAIL;
102         }
103
104         /* read the ROM */
105         pos = read_length = image->get_software_region_length("rom");
106         memcpy(ptr, image->get_software_region("rom"), read_length);
107      }
108
109      /* do we need to mirror the ROM? */
110      if (flags & ROM_MIRROR)
111      {
112         while(pos < length)
113         {
114            len = MIN(read_length, length - pos);
115            memcpy(ptr + pos, ptr, len);
116            pos += len;
117         }
118      }
119
120      /* postprocess this region */
121      type = ROMREGION_GETTAG(romrgn);
122      littleendian = ROMREGION_ISLITTLEENDIAN(romrgn);
123      datawidth = ROMREGION_GETWIDTH(romrgn) / 8;
124
125      /* if the region is inverted, do that now */
126      device_memory_interface *memory;
127      cpu = image->device().machine->device(type);
128      if (cpu!=NULL && cpu->interface(memory))
129      {
130         datawidth = device_memory(cpu)->space_config(AS_PROGRAM)->m_databus_width / 8;
131         littleendian = (device_memory(cpu)->space_config()->m_endianness == ENDIANNESS_LITTLE);
132      }
133
134      /* swap the endianness if we need to */
135#ifdef LSB_FIRST
136      if (datawidth > 1 && !littleendian)
137#else
138      if (datawidth > 1 && littleendian)
139#endif
140      {
141         for (i = 0; i < length; i += datawidth)
142         {
143            UINT8 temp[8];
144            memcpy(temp, &ptr[i], datawidth);
145            for (j = datawidth - 1; j >= 0; j--)
146               ptr[i + j] = temp[datawidth - 1 - j];
147         }
148      }
149   }
150
151   /* clear out anything that remains */
152   if (!(flags & ROM_NOCLEAR))
153   {
154      clear_val = (flags & ROM_FILL_FF) ? 0xFF : 0x00;
155      memset(ptr + pos, clear_val, length - pos);
156   }
157   return IMAGE_INIT_PASS;
158}
159
160
161
162/*-------------------------------------------------
163    process_cartridge
164-------------------------------------------------*/
165
166static int process_cartridge(device_image_interface *image, process_mode mode)
167{
168   const rom_source *source;
169   const rom_entry *romrgn, *roment;
170   int result = 0;
171
172   for (source = rom_first_source(*image->device().machine->config); source != NULL; source = rom_next_source(*source))
173   {
174      for (romrgn = rom_first_region(*source); romrgn != NULL; romrgn = rom_next_region(romrgn))
175      {
176         roment = romrgn + 1;
177         while(!ROMENTRY_ISREGIONEND(roment))
178         {
179            if (ROMENTRY_GETTYPE(roment) == ROMENTRYTYPE_CARTRIDGE)
180            {
181               if (strcmp(roment->_hashdata,image->device().tag())==0)
182               {
183                  result |= load_cartridge(image, romrgn, roment, mode);
184
185                  /* if loading failed in any cart region, stop loading */
186                  if (result)
187                     return result;
188               }
189            }
190            roment++;
191         }
192      }
193   }
194
195   return IMAGE_INIT_PASS;
196}
197
198
199/*-------------------------------------------------
200    cartslot_get_pcb
201-------------------------------------------------*/
202
203device_t *cartslot_get_pcb(device_t *device)
204{
205   cartslot_t *cart = get_token(device);
206   return cart->pcb_device;
207}
208
209
210/*-------------------------------------------------
211    cartslot_get_socket
212-------------------------------------------------*/
213
214void *cartslot_get_socket(device_t *device, const char *socket_name)
215{
216   cartslot_t *cart = get_token(device);
217   device_image_interface *image = dynamic_cast<device_image_interface *>(device);
218   void *result = NULL;
219
220   if (cart->mc != NULL)
221   {
222      const multicart_socket *socket;
223      for (socket = cart->mc->sockets; socket != NULL; socket = socket->next)
224      {
225         if (!strcmp(socket->id, socket_name))
226            break;
227      }
228      result = socket ? socket->ptr : NULL;
229   }
230   else if (socket_name[0] == '\0')
231   {
232      result = image->ptr();
233   }
234   return result;
235}
236
237/*-------------------------------------------------
238    cartslot_get_resource_length
239-------------------------------------------------*/
240
241int cartslot_get_resource_length(device_t *device, const char *socket_name)
242{
243   cartslot_t *cart = get_token(device);
244   int result = 0;
245
246   if (cart->mc != NULL)
247   {
248      const multicart_socket *socket;
249
250      for (socket = cart->mc->sockets; socket != NULL; socket = socket->next)
251      {
252         if (!strcmp(socket->id, socket_name)) {
253            break;
254         }
255      }
256      if (socket != NULL)
257         result = socket->resource->length;
258   }
259   else
260      result = 0;
261
262   return result;
263}
264
265
266/*-------------------------------------------------
267    DEVICE_START( cartslot )
268-------------------------------------------------*/
269
270static DEVICE_START( cartslot )
271{
272   cartslot_t *cart = get_token(device);
273   const cartslot_config *config = get_config(device);
274
275   /* if this cartridge has a custom DEVICE_START, use it */
276   if (config->device_start != NULL)
277   {
278      (*config->device_start)(device);
279      goto done;
280   }
281
282   /* find the PCB (if there is one) */
283   cart->pcb_device = device->subdevice(TAG_PCB);
284
285done:
286   return;
287}
288
289
290/*-------------------------------------------------
291    DEVICE_IMAGE_LOAD( cartslot )
292-------------------------------------------------*/
293
294static DEVICE_IMAGE_LOAD( cartslot )
295{
296   int result;
297   device_t *device = &image.device();
298   cartslot_t *cart = get_token(device);
299   const cartslot_config *config = get_config(device);
300
301   /* if this cartridge has a custom DEVICE_IMAGE_LOAD, use it */
302   if (config->device_load != NULL)
303      return (*config->device_load)(image);
304
305   /* try opening this as if it were a multicart */
306   multicart_open(image.filename(), device->machine->gamedrv->name, MULTICART_FLAGS_LOAD_RESOURCES, &cart->mc);
307   if (cart->mc == NULL)
308   {
309
310
311      /* otherwise try the normal route */
312      result = process_cartridge(&image, PROCESS_LOAD);
313      if (result != IMAGE_INIT_PASS)
314         return result;
315   }
316
317   return IMAGE_INIT_PASS;
318}
319
320
321/*-------------------------------------------------
322    DEVICE_IMAGE_UNLOAD( cartslot )
323-------------------------------------------------*/
324
325static DEVICE_IMAGE_UNLOAD( cartslot )
326{
327   device_t *device = &image.device();
328   cartslot_t *cart = get_token(device);
329   const cartslot_config *config = get_config(device);
330
331   /* if this cartridge has a custom DEVICE_IMAGE_UNLOAD, use it */
332   if (config->device_unload != NULL)
333   {
334      (*config->device_unload)(image);
335      return;
336   }
337
338   if (cart->mc != NULL)
339   {
340      multicart_close(cart->mc);
341      cart->mc = NULL;
342   }
343
344   process_cartridge(&image, PROCESS_CLEAR);
345}
346
347
348/*-------------------------------------------------
349    identify_pcb
350-------------------------------------------------*/
351
352static const cartslot_pcb_type *identify_pcb(device_image_interface &image)
353{
354   const cartslot_config *config = get_config(&image.device());
355   astring pcb_name;
356   const cartslot_pcb_type *pcb_type = NULL;
357   multicart_t *mc;
358   int i;
359
360   if (image.software_entry() == NULL && image.exists())
361   {
362      /* try opening this as if it were a multicart */
363      multicart_open_error me = multicart_open(image.filename(), image.device().machine->gamedrv->name, MULTICART_FLAGS_DONT_LOAD_RESOURCES, &mc);
364      if (me == MCERR_NONE)
365      {
366         /* this was a multicart - read from it */
367         astring_cpyc(&pcb_name, mc->pcb_type);
368         multicart_close(mc);
369      }
370      else
371      {
372         if (me != MCERR_NOT_MULTICART)
373            fatalerror("multicart error: %s", multicart_error_text(me));
374         
375         /* Force fetching of image metadata */
376         image.crc();
377         
378         if (image.pcb() != NULL)
379         {
380            /* read from hash file */
381            astring_cpyc(&pcb_name, image.pcb());
382         }
383      }
384
385      /* look for PCB type with matching name */
386      for (i = 0; (i < ARRAY_LENGTH(config->pcb_types)) && (config->pcb_types[i].name != NULL); i++)
387      {
388         if ((config->pcb_types[i].name[0] == '\0') || !strcmp(astring_c(&pcb_name), config->pcb_types[i].name))
389         {
390            pcb_type = &config->pcb_types[i];
391            break;
392         }
393      }
394
395      /* check for unknown PCB type */
396      if ((mc != NULL) && (pcb_type == NULL))
397         fatalerror("Unknown PCB type \"%s\"", astring_c(&pcb_name));
398   }
399   else
400   {
401      /* no device loaded; use the default */
402      pcb_type = (config->pcb_types[0].name != NULL) ? &config->pcb_types[0] : NULL;
403   }
404   return pcb_type;
405}
406
407/*-------------------------------------------------
408    DEVICE_IMAGE_GET_DEVICES(cartslot)
409-------------------------------------------------*/
410static DEVICE_IMAGE_GET_DEVICES(cartslot)
411{
412   const cartslot_pcb_type *pcb_type;
413   device_t *device = &image.device();
414
415   pcb_type = identify_pcb(image);
416   if (pcb_type != NULL)
417   {
418      image_add_device_with_subdevices(device,pcb_type->devtype,TAG_PCB,0);
419   }
420}
421
422/*-------------------------------------------------
423    DEVICE_IMAGE_SOFTLIST_LOAD(cartslot)
424-------------------------------------------------*/
425static DEVICE_IMAGE_SOFTLIST_LOAD(cartslot)
426{
427   load_software_part_region( &image.device(), swlist, swname, start_entry );
428   return TRUE;
429}
430
431/*-------------------------------------------------
432    DEVICE_GET_INFO( cartslot )
433-------------------------------------------------*/
434
435DEVICE_GET_INFO( cartslot )
436{
437   switch(state)
438   {
439      /* --- the following bits of info are returned as 64-bit signed integers --- */
440      case DEVINFO_INT_TOKEN_BYTES:            info->i = sizeof(cartslot_t); break;
441      case DEVINFO_INT_INLINE_CONFIG_BYTES:      info->i = sizeof(cartslot_config); break;
442      case DEVINFO_INT_IMAGE_TYPE:            info->i = IO_CARTSLOT; break;
443      case DEVINFO_INT_IMAGE_READABLE:         info->i = 1; break;
444      case DEVINFO_INT_IMAGE_WRITEABLE:         info->i = 0; break;
445      case DEVINFO_INT_IMAGE_CREATABLE:         info->i = 0; break;
446      case DEVINFO_INT_IMAGE_RESET_ON_LOAD:      info->i = 1; break;
447      case DEVINFO_INT_IMAGE_MUST_BE_LOADED:
448         if ( device && downcast<const legacy_image_device_config_base *>(device)->inline_config()) {
449            info->i = get_config_dev(device)->must_be_loaded;
450         } else {
451            info->i = 0;
452         }
453         break;
454
455      /* --- the following bits of info are returned as pointers to functions --- */
456      case DEVINFO_FCT_START:                  info->start = DEVICE_START_NAME(cartslot);               break;
457      case DEVINFO_FCT_IMAGE_LOAD:            info->f = (genf *) DEVICE_IMAGE_LOAD_NAME(cartslot);      break;
458      case DEVINFO_FCT_IMAGE_UNLOAD:            info->f = (genf *) DEVICE_IMAGE_UNLOAD_NAME(cartslot);      break;
459      case DEVINFO_FCT_IMAGE_GET_DEVICES:         info->f = (genf *) DEVICE_IMAGE_GET_DEVICES_NAME(cartslot);   break;
460      case DEVINFO_FCT_IMAGE_SOFTLIST_LOAD:      info->f = (genf *) DEVICE_IMAGE_SOFTLIST_LOAD_NAME(cartslot);   break;
461      case DEVINFO_FCT_IMAGE_PARTIAL_HASH:
462         if ( device && downcast<const legacy_image_device_config_base *>(device)->inline_config() && get_config_dev(device)->device_partialhash) {
463            info->f = (genf *) get_config_dev(device)->device_partialhash;
464         } else {
465            info->f = NULL;
466         }
467         break;
468
469      /* --- the following bits of info are returned as NULL-terminated strings --- */
470      case DEVINFO_STR_NAME:                  strcpy(info->s, "Cartslot"); break;
471      case DEVINFO_STR_FAMILY:               strcpy(info->s, "Cartslot"); break;
472      case DEVINFO_STR_SOURCE_FILE:            strcpy(info->s, __FILE__); break;
473      case DEVINFO_STR_IMAGE_FILE_EXTENSIONS:
474         if ( device && downcast<const legacy_image_device_config_base *>(device)->inline_config() && get_config_dev(device)->extensions )
475         {
476            strcpy(info->s, get_config_dev(device)->extensions);
477         }
478         else
479         {
480            strcpy(info->s, "bin");
481         }
482         break;
483      case DEVINFO_STR_IMAGE_INTERFACE:
484         if ( device && downcast<const legacy_image_device_config_base *>(device)->inline_config() && get_config_dev(device)->interface )
485         {
486            strcpy(info->s, get_config_dev(device)->interface );
487         }
488         break;
489   }
490}
491
492DEFINE_LEGACY_IMAGE_DEVICE(CARTSLOT, cartslot);
493
494
495//**************************************************************************
496//  DEVICE CONFIG CARTSLOT INTERFACE
497//**************************************************************************
498
499//-------------------------------------------------
500//  device_config_cart_slot_interface - constructor
501//-------------------------------------------------
502
503device_config_cart_slot_interface::device_config_cart_slot_interface(const machine_config &mconfig, device_config &devconfig)
504   : device_config_interface(mconfig, devconfig)
505{
506}
507
508
509//-------------------------------------------------
510//  ~device_config_cart_slot_interface - destructor
511//-------------------------------------------------
512
513device_config_cart_slot_interface::~device_config_cart_slot_interface()
514{
515}
516
517
518
519//**************************************************************************
520//  DEVICE CARTSLOT INTERFACE
521//**************************************************************************
522
523//-------------------------------------------------
524//  device_cart_slot_interface - constructor
525//-------------------------------------------------
526
527device_cart_slot_interface::device_cart_slot_interface(running_machine &machine, const device_config &config, device_t &device)
528   : device_interface(machine, config, device),
529     m_cart_slot_config(dynamic_cast<const device_config_cart_slot_interface &>(config))
530{
531}
532
533
534//-------------------------------------------------
535//  ~device_cart_slot_interface - destructor
536//-------------------------------------------------
537
538device_cart_slot_interface::~device_cart_slot_interface()
539{
540}
541
542//**************************************************************************
543//  LEGACY cart_slot DEVICE CONFIGURATION
544//**************************************************************************
545
546//-------------------------------------------------
547//  legacy_cart_slot_device_config_base - constructor
548//-------------------------------------------------
549
550legacy_cart_slot_device_config_base::legacy_cart_slot_device_config_base(const machine_config &mconfig, device_type type, const char *tag, const device_config *owner, UINT32 clock, device_get_config_func get_config)
551   : legacy_device_config_base(mconfig, type, tag, owner, clock, get_config),
552     device_config_cart_slot_interface(mconfig, *this)
553{
554}
555
556
557//**************************************************************************
558//  LIVE LEGACY cart_slot DEVICE
559//**************************************************************************
560
561//-------------------------------------------------
562//  legacy_cart_slot_device_base - constructor
563//-------------------------------------------------
564
565legacy_cart_slot_device_base::legacy_cart_slot_device_base(running_machine &machine, const device_config &config)
566   : legacy_device_base(machine, config),
567     device_cart_slot_interface(machine, config, *this)
568{
569}
src/mess/devices/cartslot.h
r9927r9928
1/***************************************************************************
2
3    Cartrige loading
4
5***************************************************************************/
6
7#ifndef __CARTSLOT_H__
8#define __CARTSLOT_H__
9
10#include "image.h"
11#include "multcart.h"
12
13
14/***************************************************************************
15    MACROS
16***************************************************************************/
17#define TAG_PCB      "pcb"
18
19#define ROM_CART_LOAD(tag,offset,length,flags)   \
20   { NULL, tag, offset, length, ROMENTRYTYPE_CARTRIDGE | (flags) },
21
22#define ROM_MIRROR      0x01000000
23#define ROM_NOMIRROR   0x00000000
24#define ROM_FULLSIZE   0x02000000
25#define ROM_FILL_FF      0x04000000
26#define ROM_NOCLEAR      0x08000000
27
28DECLARE_LEGACY_IMAGE_DEVICE(CARTSLOT, cartslot);
29
30
31
32/***************************************************************************
33    TYPE DEFINITIONS
34***************************************************************************/
35
36typedef struct _cartslot_t cartslot_t;
37struct _cartslot_t
38{
39   device_t *pcb_device;
40   multicart_t *mc;
41};
42
43
44typedef struct _cartslot_pcb_type cartslot_pcb_type;
45struct _cartslot_pcb_type
46{
47   const char *               name;
48   device_type                  devtype;
49};
50
51
52typedef struct _cartslot_config cartslot_config;
53struct _cartslot_config
54{
55   const char *               extensions;
56   const char *               interface;
57   int                        must_be_loaded;
58   device_start_func            device_start;
59   device_image_load_func         device_load;
60   device_image_unload_func      device_unload;
61   device_image_partialhash_func   device_partialhash;
62   cartslot_pcb_type            pcb_types[16];
63};
64
65
66/***************************************************************************
67    FUNCTION PROTOTYPES
68***************************************************************************/
69
70/* accesses the PCB associated with this cartslot */
71device_t *cartslot_get_pcb(device_t *device);
72
73/* accesses a particular socket */
74void *cartslot_get_socket(device_t *device, const char *socket_name);
75
76/* accesses a particular socket; gets the length of the associated resource */
77int cartslot_get_resource_length(device_t *device, const char *socket_name);
78
79
80/***************************************************************************
81    DEVICE CONFIGURATION MACROS
82***************************************************************************/
83
84#define MCFG_CARTSLOT_ADD(_tag)                               \
85   MCFG_DEVICE_ADD(_tag, CARTSLOT, 0)                           \
86
87#define MCFG_CARTSLOT_MODIFY(_tag)                              \
88   MCFG_DEVICE_MODIFY(_tag)                           \
89
90#define MCFG_CARTSLOT_EXTENSION_LIST(_extensions)                  \
91   MCFG_DEVICE_CONFIG_DATAPTR(cartslot_config, extensions, _extensions)
92
93#define MCFG_CARTSLOT_NOT_MANDATORY                              \
94   MCFG_DEVICE_CONFIG_DATA32(cartslot_config, must_be_loaded, FALSE)
95
96#define MCFG_CARTSLOT_MANDATORY                                 \
97   MCFG_DEVICE_CONFIG_DATA32(cartslot_config, must_be_loaded, TRUE)
98
99#define MCFG_CARTSLOT_START(_start)                              \
100   MCFG_DEVICE_CONFIG_DATAPTR(cartslot_config, device_start, DEVICE_START_NAME(_start))
101
102#define MCFG_CARTSLOT_LOAD(_load)                              \
103   MCFG_DEVICE_CONFIG_DATAPTR(cartslot_config, device_load, DEVICE_IMAGE_LOAD_NAME(_load))
104
105#define MCFG_CARTSLOT_UNLOAD(_unload)                           \
106   MCFG_DEVICE_CONFIG_DATAPTR(cartslot_config, device_unload, DEVICE_IMAGE_UNLOAD_NAME(_unload))
107
108#define MCFG_CARTSLOT_PARTIALHASH(_partialhash)                     \
109   MCFG_DEVICE_CONFIG_DATAPTR(cartslot_config, device_partialhash, _partialhash)
110
111#define MCFG_CARTSLOT_PCBTYPE(_index, _pcb_type_name, _pcb_devtype)         \
112   MCFG_DEVICE_CONFIG_DATAPTR_ARRAY_MEMBER(cartslot_config, pcb_types, _index, cartslot_pcb_type, name, _pcb_type_name) \
113   MCFG_DEVICE_CONFIG_DATAPTR_ARRAY_MEMBER(cartslot_config, pcb_types, _index, cartslot_pcb_type, devtype, _pcb_devtype)
114
115#define MCFG_CARTSLOT_INTERFACE(_interface)                     \
116   MCFG_DEVICE_CONFIG_DATAPTR(cartslot_config, interface, _interface )
117
118#define DECLARE_LEGACY_CART_SLOT_DEVICE(name, basename) _DECLARE_LEGACY_DEVICE(name, basename, basename##_device_config, basename##_device, legacy_cart_slot_device_config_base, legacy_cart_slot_device_base)
119#define DEFINE_LEGACY_CART_SLOT_DEVICE(name, basename) _DEFINE_LEGACY_DEVICE(name, basename, basename##_device_config, basename##_device, legacy_cart_slot_device_config_base, legacy_cart_slot_device_base)
120
121// ======================> device_config_cart_slot_interface
122
123// class representing interface-specific configuration cart_slot
124class device_config_cart_slot_interface : public device_config_interface
125{
126public:
127   // construction/destruction
128   device_config_cart_slot_interface(const machine_config &mconfig, device_config &device);
129   virtual ~device_config_cart_slot_interface();
130};
131
132
133
134// ======================> device_cart_slot_interface
135
136// class representing interface-specific live cart_slot
137class device_cart_slot_interface : public device_interface
138{
139public:
140   // construction/destruction
141   device_cart_slot_interface(running_machine &machine, const device_config &config, device_t &device);
142   virtual ~device_cart_slot_interface();
143
144   // configuration access
145   const device_config_cart_slot_interface &cart_slot_config() const { return m_cart_slot_config; }
146protected:
147
148   // configuration
149   const device_config_cart_slot_interface &m_cart_slot_config;   // reference to our device_config_execute_interface
150};
151// ======================> legacy_cart_slot_device_config
152
153// legacy_cart_slot_device_config is a device_config with a cart_slot interface
154class legacy_cart_slot_device_config_base :    public legacy_device_config_base,
155                                 public device_config_cart_slot_interface
156{
157protected:
158   // construction/destruction
159   legacy_cart_slot_device_config_base(const machine_config &mconfig, device_type type, const char *tag, const device_config *owner, UINT32 clock, device_get_config_func get_config);
160public:
161   INT64 get_config_int(UINT32 state) const { return get_legacy_config_int(state); }
162   genf *get_config_fct(UINT32 state) const { return get_legacy_config_fct(state); }
163   void *get_config_ptr(UINT32 state) const { return get_legacy_config_ptr(state); }
164};
165
166
167
168// ======================> legacy_cart_slot_device
169
170// legacy_cart_slot_device is a legacy_device_base with a cart_slot interface
171class legacy_cart_slot_device_base :   public legacy_device_base,
172                           public device_cart_slot_interface
173{
174protected:
175   // construction/destruction
176   legacy_cart_slot_device_base(running_machine &machine, const device_config &config);
177
178   // device_cart_slot_interface overrides
179};
180#endif /* __cart_slot_H__ */
src/mess/devices/chd_cd.c
r9927r9928
1/*********************************************************************
2
3    Code to interface the MESS image code with MAME's CHD-CD core.
4
5    Based on harddriv.c by Raphael Nabet 2003
6
7*********************************************************************/
8
9#include "emu.h"
10#include "cdrom.h"
11#include "chd_cd.h"
12
13
14static const char *const error_strings[] =
15{
16   "no error",
17   "no drive interface",
18   "out of memory",
19   "invalid file",
20   "invalid parameter",
21   "invalid data",
22   "file not found",
23   "requires parent",
24   "file not writeable",
25   "read error",
26   "write error",
27   "codec error",
28   "invalid parent",
29   "hunk out of range",
30   "decompression error",
31   "compression error",
32   "can't create file",
33   "can't verify file"
34   "operation not supported",
35   "can't find metadata",
36   "invalid metadata size",
37   "unsupported CHD version"
38};
39
40INLINE const cdrom_config *get_config_dev(const device_config *device)
41{
42   assert(device != NULL);
43   assert(device->type() == CDROM);
44   return (const cdrom_config *)downcast<const legacy_device_config_base *>(device)->inline_config();
45}
46
47static const char *chd_get_error_string(int chderr)
48{
49   if ((chderr < 0 ) || (chderr >= ARRAY_LENGTH(error_strings)))
50      return NULL;
51   return error_strings[chderr];
52}
53
54
55static OPTION_GUIDE_START(mess_cd_option_guide)
56   OPTION_INT('K', "hunksize",         "Hunk Bytes")
57OPTION_GUIDE_END
58
59static const char mess_cd_option_spec[] =
60   "K512/1024/2048/[4096]";
61
62
63typedef struct _dev_cdrom_t   dev_cdrom_t;
64struct _dev_cdrom_t
65{
66   cdrom_file   *cdrom_handle;
67};
68
69
70INLINE dev_cdrom_t *get_safe_token(device_t *device) {
71   assert( device != NULL );
72   assert( ( device->type() == CDROM ) );
73   return (dev_cdrom_t *)  downcast<legacy_device_base *>(device)->token();
74}
75
76
77static DEVICE_IMAGE_LOAD(cdrom)
78{
79   dev_cdrom_t   *cdrom = get_safe_token(&image.device());
80   chd_error   err = (chd_error)0;
81   chd_file   *chd = NULL;
82
83   err = chd_open_file( image.image_core_file(), CHD_OPEN_READ, NULL, &chd );   /* CDs are never writeable */
84   if ( err )
85      goto error;
86
87   /* open the CHD file */
88   cdrom->cdrom_handle = cdrom_open( chd );
89   if ( ! cdrom->cdrom_handle )
90      goto error;
91
92   return IMAGE_INIT_PASS;
93
94error:
95   if ( chd )
96      chd_close( chd );
97   if ( err )
98      image.seterror( IMAGE_ERROR_UNSPECIFIED, chd_get_error_string( err ) );
99   return IMAGE_INIT_FAIL;
100}
101
102
103static DEVICE_IMAGE_UNLOAD(cdrom)
104{
105   dev_cdrom_t   *cdrom = get_safe_token( &image.device() );
106
107   assert( cdrom->cdrom_handle );
108   cdrom_close( cdrom->cdrom_handle );
109   cdrom->cdrom_handle = NULL;
110}
111
112
113/*************************************
114 *
115 *  Get the MESS/MAME cdrom handle (from the src/cdrom.c core)
116 *  after an image has been opened with the mess_cd core
117 *
118 *************************************/
119
120cdrom_file *mess_cd_get_cdrom_file(device_t *image)
121{
122   dev_cdrom_t   *cdrom = get_safe_token( image );
123
124   return cdrom->cdrom_handle;
125}
126
127
128/*-------------------------------------------------
129    DEVICE_START(cdrom)
130-------------------------------------------------*/
131
132static DEVICE_START(cdrom)
133{
134   dev_cdrom_t   *cdrom = get_safe_token( device );
135
136   cdrom->cdrom_handle = NULL;
137}
138
139/*-------------------------------------------------
140    DEVICE_IMAGE_SOFTLIST_LOAD(cdrom)
141-------------------------------------------------*/
142static DEVICE_IMAGE_SOFTLIST_LOAD(cdrom)
143{
144   return image.load_software(swlist, swname, start_entry);
145}
146
147/*-------------------------------------------------
148    DEVICE_GET_INFO(cdrom)
149-------------------------------------------------*/
150
151DEVICE_GET_INFO(cdrom)
152{
153   switch( state )
154   {
155      /* --- the following bits of info are returned as 64-bit signed integers --- */
156      case DEVINFO_INT_TOKEN_BYTES:            info->i = sizeof(dev_cdrom_t); break;
157      case DEVINFO_INT_INLINE_CONFIG_BYTES:      info->i = sizeof(cdrom_config); break;
158      case DEVINFO_INT_IMAGE_TYPE:            info->i = IO_CDROM; break;
159      case DEVINFO_INT_IMAGE_READABLE:         info->i = 1; break;
160      case DEVINFO_INT_IMAGE_WRITEABLE:         info->i = 0; break;
161      case DEVINFO_INT_IMAGE_CREATABLE:         info->i = 0; break;
162      case DEVINFO_INT_IMAGE_CREATE_OPTCOUNT:      info->i = 1; break;
163
164      /* --- the following bits of info are returned as pointers to data or functions --- */
165      case DEVINFO_FCT_START:                  info->start = DEVICE_START_NAME(cdrom); break;
166      case DEVINFO_FCT_IMAGE_LOAD:            info->f = (genf *) DEVICE_IMAGE_LOAD_NAME(cdrom); break;
167      case DEVINFO_FCT_IMAGE_UNLOAD:            info->f = (genf *) DEVICE_IMAGE_UNLOAD_NAME(cdrom); break;
168      case DEVINFO_FCT_IMAGE_SOFTLIST_LOAD:      info->f = (genf *) DEVICE_IMAGE_SOFTLIST_LOAD_NAME(cdrom);   break;
169      case DEVINFO_PTR_IMAGE_CREATE_OPTGUIDE:      info->p = (void *) mess_cd_option_guide; break;
170      case DEVINFO_PTR_IMAGE_CREATE_OPTSPEC+0:   info->p = (void *) mess_cd_option_spec; break;
171
172      /* --- the following bits of info are returned as NULL-terminated strings --- */
173      case DEVINFO_STR_NAME:                  strcpy(info->s, "Cdrom"); break;
174      case DEVINFO_STR_FAMILY:               strcpy(info->s, "Cdrom"); break;
175      case DEVINFO_STR_SOURCE_FILE:            strcpy(info->s, __FILE__); break;
176      case DEVINFO_STR_IMAGE_FILE_EXTENSIONS:      strcpy(info->s, "chd"); break;
177      case DEVINFO_STR_IMAGE_CREATE_OPTNAME+0:   strcpy(info->s, "chdcd"); break;
178      case DEVINFO_STR_IMAGE_CREATE_OPTDESC+0:   strcpy(info->s, "MAME/MESS CHD CD-ROM drive"); break;
179      case DEVINFO_STR_IMAGE_CREATE_OPTEXTS+0:   strcpy(info->s, "chd"); break;
180
181      case DEVINFO_STR_IMAGE_INTERFACE:
182         if ( device && downcast<const legacy_image_device_config_base *>(device)->inline_config() && get_config_dev(device)->interface )
183         {
184            strcpy(info->s, get_config_dev(device)->interface );
185         }
186         break;
187
188   }
189}
190
191DEFINE_LEGACY_IMAGE_DEVICE(CDROM, cdrom);
src/mess/devices/chd_cd.h
r9927r9928
1/*********************************************************************
2
3    chd_cd.h
4
5    MESS interface to the MAME CHD CDROM code
6
7*********************************************************************/
8
9#ifndef MESS_CD_H
10#define MESS_CD_H
11
12#include "cdrom.h"
13
14/***************************************************************************
15    TYPE DEFINITIONS
16***************************************************************************/
17
18typedef struct cdrom_config_t   cdrom_config;
19struct cdrom_config_t
20{
21   const char *               interface;
22};
23
24/***************************************************************************
25    FUNCTION PROTOTYPES
26***************************************************************************/
27DECLARE_LEGACY_IMAGE_DEVICE(CDROM, cdrom);
28
29
30cdrom_file *mess_cd_get_cdrom_file(device_t *device);
31
32/***************************************************************************
33    DEVICE CONFIGURATION MACROS
34***************************************************************************/
35
36
37#define MCFG_CDROM_ADD(_tag) \
38   MCFG_DEVICE_ADD(_tag, CDROM, 0) \
39
40#define MCFG_CDROM_INTERFACE(_interface)                     \
41   MCFG_DEVICE_CONFIG_DATAPTR(cdrom_config, interface, _interface )
42
43#endif /* MESS_CD_H */
src/mess/devices/printer.c
r9927r9928
1/****************************************************************************
2
3    printer.c
4
5    Code for handling printer devices
6
7****************************************************************************/
8
9#include "emu.h"
10#include "printer.h"
11
12
13
14/***************************************************************************
15    IMPLEMENTATION
16***************************************************************************/
17
18/*-------------------------------------------------
19    printer_is_ready - checks to see if a printer
20    is ready
21-------------------------------------------------*/
22
23int printer_is_ready(device_t *printer)
24{
25   device_image_interface *image = dynamic_cast<device_image_interface *>(printer);
26   /* if there is a file attached to it, it's online */
27   return image->exists() != 0;
28}
29
30
31
32/*-------------------------------------------------
33    printer_output - outputs data to a printer
34-------------------------------------------------*/
35
36void printer_output(device_t *printer, UINT8 data)
37{
38   device_image_interface *image = dynamic_cast<device_image_interface *>(printer);
39   if (image->exists())
40   {
41      image->fwrite(&data, 1);
42   }
43}
44
45
46/*-------------------------------------------------
47    DEVICE_IMAGE_LOAD( printer )
48-------------------------------------------------*/
49
50static DEVICE_IMAGE_LOAD( printer )
51{
52   const printer_config *conf = (const printer_config *)downcast<const legacy_image_device_config_base &>(image.device().baseconfig()).inline_config();
53
54   /* send notify that the printer is now online */
55   if (conf != NULL && conf->online != NULL)
56      conf->online(image, TRUE);
57
58   /* we don't need to do anything special */
59   return IMAGE_INIT_PASS;
60}
61
62
63/*-------------------------------------------------
64    DEVICE_IMAGE_UNLOAD( printer )
65-------------------------------------------------*/
66
67static DEVICE_IMAGE_UNLOAD( printer )
68{
69   const printer_config *conf = (const printer_config *)downcast<const legacy_image_device_config_base &>(image.device().baseconfig()).inline_config();
70
71   /* send notify that the printer is now offline */
72   if (conf != NULL && conf->online != NULL)
73      conf->online(image, FALSE);
74}
75
76
77/*-------------------------------------------------
78    DEVICE_START(printer)
79-------------------------------------------------*/
80
81static DEVICE_START(printer)
82{
83}
84
85
86
87/*-------------------------------------------------
88    DEVICE_GET_INFO(printer)
89-------------------------------------------------*/
90
91DEVICE_GET_INFO(printer)
92{
93   switch(state)
94   {
95      /* --- the following bits of info are returned as 64-bit signed integers --- */
96      case DEVINFO_INT_TOKEN_BYTES:               info->i = 1; break;
97      case DEVINFO_INT_INLINE_CONFIG_BYTES:         info->i = sizeof(printer_config); break;
98      case DEVINFO_INT_IMAGE_TYPE:               info->i = IO_PRINTER; break;
99      case DEVINFO_INT_IMAGE_READABLE:            info->i = 0; break;
100      case DEVINFO_INT_IMAGE_WRITEABLE:            info->i = 1; break;
101      case DEVINFO_INT_IMAGE_CREATABLE:            info->i = 1; break;
102
103      /* --- the following bits of info are returned as pointers to data or functions --- */
104      case DEVINFO_FCT_START:                     info->start = DEVICE_START_NAME(printer); break;
105      case DEVINFO_FCT_IMAGE_LOAD:               info->f = (genf *) DEVICE_IMAGE_LOAD_NAME(printer);      break;
106      case DEVINFO_FCT_IMAGE_UNLOAD:               info->f = (genf *) DEVICE_IMAGE_UNLOAD_NAME(printer);   break;
107
108      /* --- the following bits of info are returned as NULL-terminated strings --- */
109      case DEVINFO_STR_NAME:                     strcpy(info->s, "Printer"); break;
110      case DEVINFO_STR_FAMILY:                  strcpy(info->s, "Printer"); break;
111      case DEVINFO_STR_SOURCE_FILE:               strcpy(info->s, __FILE__); break;
112      case DEVINFO_STR_IMAGE_FILE_EXTENSIONS:         strcpy(info->s, "prn"); break;
113   }
114}
115
116DEFINE_LEGACY_IMAGE_DEVICE(PRINTER, printer);
src/mess/devices/bitbngr.c
r9927r9928
1/*********************************************************************
2
3    bitbngr.c
4
5    TRS style "bitbanger" serial port
6
7*********************************************************************/
8
9#include "emu.h"
10#include "bitbngr.h"
11
12
13
14/***************************************************************************
15    TYPE DEFINITIONS
16***************************************************************************/
17
18typedef struct _bitbanger_token bitbanger_token;
19struct _bitbanger_token
20{
21   emu_timer *bitbanger_output_timer;
22   emu_timer *bitbanger_input_timer;
23   int output_value;
24   int build_count;
25   int build_byte;
26   attotime idle_delay;
27   attotime current_baud;
28   UINT32 input_buffer_size;
29   UINT32 input_buffer_cursor;
30   int mode;
31   int baud;
32   int tune;
33   UINT8 input_buffer[1000];
34};
35
36
37
38/***************************************************************************
39    FUNCTION PROTOTYPES
40***************************************************************************/
41
42static TIMER_CALLBACK(bitbanger_output_timer);
43static TIMER_CALLBACK(bitbanger_input_timer);
44
45
46
47/***************************************************************************
48    INLINE FUNCTIONS
49***************************************************************************/
50
51
52/*-------------------------------------------------
53    get_token - safely gets the bitbanger data
54-------------------------------------------------*/
55
56INLINE bitbanger_token *get_token(device_t *device)
57{
58   assert(device != NULL);
59   assert(device->type() == BITBANGER);
60   return (bitbanger_token *) downcast<legacy_device_base *>(device)->token();
61}
62
63
64/*-------------------------------------------------
65    get_config - safely gets the bitbanger config
66-------------------------------------------------*/
67
68INLINE const bitbanger_config *get_config(device_t *device)
69{
70   assert(device != NULL);
71   assert(device->type() == BITBANGER);
72   return (const bitbanger_config *) device->baseconfig().static_config();
73}
74
75
76
77/***************************************************************************
78    IMPLEMENTATION
79***************************************************************************/
80
81
82/*-------------------------------------------------
83    native_output - outputs data to a file
84-------------------------------------------------*/
85
86static void native_output(device_t *bitbanger, UINT8 data)
87{
88   device_image_interface *image = dynamic_cast<device_image_interface *>(bitbanger);
89   if (image->exists())
90   {
91      image->fwrite(&data, 1);
92   }
93}
94
95
96/*-------------------------------------------------
97    native_input - inputs data from a file
98-------------------------------------------------*/
99
100static UINT32 native_input(device_t *bitbanger, void *buffer, UINT32 length)
101{
102   device_image_interface *image = dynamic_cast<device_image_interface *>(bitbanger);
103   if (image->exists())
104   {
105      return image->fread(buffer, length);
106   }
107
108   return 0;
109}
110
111
112/*-------------------------------------------------
113    bitbanger_mode_string
114-------------------------------------------------*/
115const char *bitbanger_mode_string(device_t *device)
116{
117   bitbanger_token *bi = get_token(device);
118   static const char *const modes[] = {"Printer", "Modem"};
119
120   return(modes[bi->mode]);
121}
122
123
124/*-------------------------------------------------
125    bitbanger_inc_mode
126-------------------------------------------------*/
127bool bitbanger_inc_mode(device_t *device, bool test)
128{
129   bitbanger_token *bi = get_token(device);
130   int adjust_mode = (int)bi->mode + 1;
131
132   if( adjust_mode >= BITBANGER_MODE_MAX )
133      return FALSE;
134
135   if( !test)
136      bi->mode = adjust_mode;
137
138   return TRUE;
139}
140
141
142/*-------------------------------------------------
143    bitbanger_dec_mode
144-------------------------------------------------*/
145bool bitbanger_dec_mode(device_t *device, bool test)
146{
147   bitbanger_token *bi = get_token(device);
148   int adjust_mode = bi->mode - 1;
149
150   if( adjust_mode < 0 )
151      return FALSE;
152
153   if( !test)
154      bi->mode = adjust_mode;
155
156   return TRUE;
157}
158
159
160/*-------------------------------------------------
161    bitbanger_tune_string
162-------------------------------------------------*/
163const char *bitbanger_tune_string(device_t *device)
164{
165   bitbanger_token *bi = get_token(device);
166   static const char *const tunes[] = {"-2.0%", "-1.75%", "-1.5%", "-1.25%", "-1.0%", "-0.75%", "-0.5", "-0.25%", "\xc2\xb1""0%",
167                                 "+0.25%",  "+0.5%", "+0.75%", "+1.0%", "+1.25%", "+1.5%", "+1.75%", "+2.0%"};
168
169   return(tunes[bi->tune]);
170}
171
172
173/*-------------------------------------------------
174    bitbanger_tune_value
175-------------------------------------------------*/
176static float bitbanger_tune_value(device_t *device)
177{
178   bitbanger_token *bi = get_token(device);
179   static const float tunes[] = {0.97f, 0.9825f, 0.985f, 0.9875f, 0.99f, 0.9925f, 0.995f, 0.9975f, 1.0f,
180                  1.0025f, 1.005f, 1.0075f, 1.01f, 1.0125f, 1.015f, 1.0175f, 1.02f};
181
182   return(tunes[bi->tune]);
183}
184
185
186/*-------------------------------------------------
187    bitbanger_baud_value
188-------------------------------------------------*/
189
190static UINT32 bitbanger_baud_value(device_t *device)
191{
192   bitbanger_token *bi = get_token(device);
193   static const float bauds[] = { 150.0f, 300.0f, 600.0f, 1200.0f, 2400.0f, 4800.0f, 9600.0f,
194            14400.0f, 28800.0f, 38400.0f, 57600.0f, 115200.0f};
195   float result = bitbanger_tune_value(device) * bauds[bi->baud];
196   return (UINT32)result;
197}
198
199
200/*-------------------------------------------------
201    bitbanger_baud_string
202-------------------------------------------------*/
203
204const char *bitbanger_baud_string(device_t *device)
205{
206   bitbanger_token *bi = get_token(device);
207   static const char *const bauds[] = { "150", "300", "600", "1200", "2400", "4800",
208                     "9600", "14400", "28800", "38400", "57600", "115200"};
209
210   return(bauds[bi->baud]);
211}
212
213
214/*-------------------------------------------------
215    bitbanger_inc_baud
216-------------------------------------------------*/
217bool bitbanger_inc_baud(device_t *device, bool test)
218{
219   bitbanger_token *bi = get_token(device);
220   int adjust_baud = (int)bi->baud + 1;
221
222   if( adjust_baud >= BITBANGER_BAUD_MAX )
223      return FALSE;
224
225   if( !test)
226   {
227      bi->baud = adjust_baud;
228      bi->current_baud = ATTOTIME_IN_HZ(bitbanger_baud_value(device));
229   }
230
231   return TRUE;
232}
233
234
235/*-------------------------------------------------
236    bitbanger_dec_baud
237-------------------------------------------------*/
238bool bitbanger_dec_baud(device_t *device, bool test)
239{
240   bitbanger_token *bi = get_token(device);
241   int adjust_baud = bi->baud - 1;
242
243   if( adjust_baud < 0 )
244      return FALSE;
245
246   if( !test)
247   {
248      bi->baud = adjust_baud;
249      bi->current_baud = ATTOTIME_IN_HZ(bitbanger_baud_value(device));
250   }
251
252   return TRUE;
253}
254
255
256/*-------------------------------------------------
257    bitbanger_inc_tune
258-------------------------------------------------*/
259bool bitbanger_inc_tune(device_t *device, bool test)
260{
261   bitbanger_token *bi = get_token(device);
262   int adjust_tune = (int)bi->tune + 1;
263
264   if( adjust_tune >= BITBANGER_TUNE_MAX )
265      return FALSE;
266
267   if( !test)
268   {
269      bi->tune = adjust_tune;
270      bi->current_baud = ATTOTIME_IN_HZ(bitbanger_baud_value(device));
271   }
272
273   return TRUE;
274}
275
276
277/*-------------------------------------------------
278    bitbanger_dec_tune
279-------------------------------------------------*/
280bool bitbanger_dec_tune(device_t *device, bool test)
281{
282   bitbanger_token *bi = get_token(device);
283   int adjust_tune = bi->tune - 1;
284
285   if( adjust_tune < 0 )
286      return FALSE;
287
288   if( !test)
289   {
290      bi->tune = adjust_tune;
291      bi->current_baud = ATTOTIME_IN_HZ(bitbanger_baud_value(device));
292   }
293
294   return TRUE;
295}
296
297
298/*-------------------------------------------------
299    bitbanger_bytes_to_bits_81N
300-------------------------------------------------*/
301static void bitbanger_bytes_to_bits_81N(device_t *img)
302{
303   bitbanger_token *bi = get_token(img);
304   UINT8 byte_buffer[100];
305   UINT32 byte_buffer_size, bit_buffer_size;
306   int i, j;
307   static const UINT8 bitmask[8] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
308
309   bit_buffer_size = 0;
310   byte_buffer_size = native_input(img, byte_buffer, sizeof(byte_buffer));
311
312   /* Translate byte buffer into bit buffer using: 1 start bit, 8 data bits, 1 stop bit, no parity */
313
314   for( i=0; i<byte_buffer_size; i++ )
315   {
316      bi->input_buffer[bit_buffer_size++] = 0;
317
318      for( j=0; j<8; j++ )
319      {
320         if( byte_buffer[i] & bitmask[j] )
321            bi->input_buffer[bit_buffer_size++] = 1;
322         else
323            bi->input_buffer[bit_buffer_size++] = 0;
324      }
325
326      bi->input_buffer[bit_buffer_size++] = 1;
327   }
328
329   bi->input_buffer_size = bit_buffer_size;
330   bi->input_buffer_cursor = 0;
331}
332
333
334/*-------------------------------------------------
335    DEVICE_START(bitbanger)
336-------------------------------------------------*/
337
338static DEVICE_START(bitbanger)
339{
340   bitbanger_token *bi;
341   const bitbanger_config *config = get_config(device);
342
343   bi = get_token(device);
344
345   /* output config */
346   bi->build_count = 0;
347   bi->bitbanger_output_timer = timer_alloc(device->machine, bitbanger_output_timer, (void *) device);
348
349   /* input config */
350   bi->bitbanger_input_timer = timer_alloc(device->machine, bitbanger_input_timer, (void *) device );
351   bi->idle_delay = ATTOTIME_IN_SEC(1);
352   bi->input_buffer_size = 0;
353   bi->input_buffer_cursor = 0;
354
355   bi->mode = config->default_mode;
356   bi->baud = config->default_baud;
357   bi->tune = config->default_tune;
358   bi->current_baud = ATTOTIME_IN_HZ(bitbanger_baud_value(device));
359
360   /* test callback */
361   if(!config->input_callback)
362      fatalerror("Misconfigured bitbanger device: input_callback cannot be NULL\n");
363}
364
365
366/*-------------------------------------------------
367    TIMER_CALLBACK(bitbanger_output_timer)
368-------------------------------------------------*/
369
370static TIMER_CALLBACK(bitbanger_output_timer)
371{
372   device_t *device = (device_t *) ptr;
373   bitbanger_token *bi = get_token(device);
374
375   /* this ia harded coded for 8-1-N */
376   if( bi->output_value )
377      bi->build_byte |= 0x200;
378
379   bi->build_byte >>= 1;
380   bi->build_count--;
381
382   if(bi->build_count == 0)
383   {
384      if( bi->output_value == 1 )
385         native_output( device, bi->build_byte );
386      else
387         logerror("Bitbanger: Output framing error.\n" );
388
389      timer_reset(bi->bitbanger_output_timer, attotime_never);
390   }
391}
392
393
394/*-------------------------------------------------
395    TIMER_CALLBACK(bitbanger_input_timer)
396-------------------------------------------------*/
397
398static TIMER_CALLBACK(bitbanger_input_timer)
399{
400   device_t *device = (device_t *) ptr;
401   bitbanger_token *bi = get_token(device);
402   const bitbanger_config *config = get_config(device);
403
404   if(bi->input_buffer_cursor == bi->input_buffer_size)
405   {
406      /* get more data */
407      bitbanger_bytes_to_bits_81N(device);
408
409      if(bi->input_buffer_size == 0)
410      {
411         /* no more data, wait and try again */
412         bi->idle_delay = attotime_min(attotime_add(bi->idle_delay, ATTOTIME_IN_MSEC(100)), ATTOTIME_IN_SEC(1));
413         timer_adjust_oneshot(bi->bitbanger_input_timer, bi->idle_delay, 0);
414
415
416         if( bi->mode == BITBANGER_MODEM )
417            config->input_callback(machine, 1);
418         else
419            config->input_callback(machine, 0);
420
421         return;
422      }
423      else
424      {
425         bi->idle_delay = bi->current_baud;
426         timer_adjust_periodic(bi->bitbanger_input_timer, bi->idle_delay, 0, bi->idle_delay);
427      }
428   }
429
430   /* send bit to driver */
431   config->input_callback(machine, bi->input_buffer[(bi->input_buffer_cursor)++]);
432}
433
434
435/*-------------------------------------------------
436    bitbanger_output - outputs data to a bitbanger
437    port
438-------------------------------------------------*/
439
440void bitbanger_output(device_t *device, int value)
441{
442   bitbanger_token *bi = get_token(device);
443   attotime one_point_five_baud;
444
445   if( bi->build_count == 0 && bi->output_value == 1 && value == 0 )
446   {
447      /* we found our start bit */
448      /* eight bits of data, plus one of stop */
449      bi->build_count = 9;
450      bi->build_byte = 0;
451
452      one_point_five_baud = attotime_add(bi->current_baud, attotime_div(bi->current_baud,2));
453      timer_adjust_periodic(bi->bitbanger_output_timer, one_point_five_baud, 0, bi->current_baud);
454   }
455
456   //fprintf(stderr,"%s, %d\n", attotime_string(timer_get_time(device->machine),9), value);
457   bi->output_value = value;
458}
459
460
461/*-------------------------------------------------
462    DEVICE_IMAGE_LOAD( bitbanger )
463-------------------------------------------------*/
464
465static DEVICE_IMAGE_LOAD( bitbanger )
466{
467   device_t *device = &image.device();
468   bitbanger_token *bi;
469   bi = get_token(device);
470
471   timer_enable(bi->bitbanger_input_timer, TRUE);
472   timer_adjust_periodic(bi->bitbanger_input_timer, attotime_zero, 0, ATTOTIME_IN_SEC(1));
473
474   /* we don't need to do anything special */
475   return IMAGE_INIT_PASS;
476}
477
478
479/*-------------------------------------------------
480    DEVICE_IMAGE_UNLOAD( bitbanger )
481-------------------------------------------------*/
482
483static DEVICE_IMAGE_UNLOAD( bitbanger )
484{
485   device_t *device = &image.device();
486   bitbanger_token *bi;
487   bi = get_token(device);
488
489   timer_enable(bi->bitbanger_input_timer, FALSE);
490}
491
492
493/*-------------------------------------------------
494    DEVICE_GET_INFO(bitbanger) - device getinfo
495    function
496-------------------------------------------------*/
497
498DEVICE_GET_INFO(bitbanger)
499{
500   switch(state)
501   {
502      /* --- the following bits of info are returned as 64-bit signed integers --- */
503      case DEVINFO_INT_TOKEN_BYTES:               info->i = sizeof(bitbanger_token); break;
504      case DEVINFO_INT_INLINE_CONFIG_BYTES:         info->i = 0; break;
505      case DEVINFO_INT_IMAGE_TYPE:               info->i = IO_PRINTER; break;
506      case DEVINFO_INT_IMAGE_READABLE:            info->i = 1; break;
507      case DEVINFO_INT_IMAGE_WRITEABLE:            info->i = 1; break;
508      case DEVINFO_INT_IMAGE_CREATABLE:            info->i = 1; break;
509
510      /* --- the following bits of info are returned as pointers to data or functions --- */
511      case DEVINFO_FCT_START:                     info->start = DEVICE_START_NAME(bitbanger); break;
512      case DEVINFO_FCT_IMAGE_LOAD:               info->f = (genf *) DEVICE_IMAGE_LOAD_NAME(bitbanger);      break;
513      case DEVINFO_FCT_IMAGE_UNLOAD:               info->f = (genf *) DEVICE_IMAGE_UNLOAD_NAME(bitbanger);   break;
514
515      /* --- the following bits of info are returned as NULL-terminated strings --- */
516      case DEVINFO_STR_NAME:                     strcpy(info->s, "Bitbanger"); break;
517      case DEVINFO_STR_FAMILY:                  strcpy(info->s, "Bitbanger"); break;
518      case DEVINFO_STR_SOURCE_FILE:               strcpy(info->s, __FILE__); break;
519      case DEVINFO_STR_IMAGE_FILE_EXTENSIONS:         strcpy(info->s, "prn"); break;
520   }
521}
522
523DEFINE_LEGACY_IMAGE_DEVICE(BITBANGER, bitbanger);
src/mess/devices/printer.h
r9927r9928
1/****************************************************************************
2
3    printer.h
4
5    Code for handling printer devices
6
7****************************************************************************/
8
9#ifndef __PRINTER_H__
10#define __PRINTER_H__
11
12#include "image.h"
13
14
15/***************************************************************************
16    TYPE DEFINITIONS
17***************************************************************************/
18
19typedef void (*online_func)(device_t *device, int state);
20
21typedef struct _printer_config printer_config;
22struct _printer_config
23{
24   online_func online;
25};
26
27
28DECLARE_LEGACY_IMAGE_DEVICE(PRINTER, printer);
29
30
31#define MCFG_PRINTER_ADD(_tag) \
32   MCFG_DEVICE_ADD(_tag, PRINTER, 0) \
33
34#define MCFG_PRINTER_ONLINE(_online) \
35   MCFG_DEVICE_CONFIG_DATAPTR(printer_config, online, _online)
36
37
38/***************************************************************************
39    FUNCTION PROTOTYPES
40***************************************************************************/
41
42/* checks to see if a printer is ready */
43int printer_is_ready(device_t *printer);
44
45/* outputs data to a printer */
46void printer_output(device_t *printer, UINT8 data);
47
48#endif /* __PRINTER_H__ */
src/mess/devices/multcart.c
r9927r9928
1/*********************************************************************
2
3    multcart.c
4
5    Multi-cartridge handling code
6
7*********************************************************************/
8
9#include "multcart.h"
10#include "pool.h"
11#include "unzip.h"
12#include "corestr.h"
13#include "xmlfile.h"
14#include "emu.h"
15#include "hash.h"
16#include "machine/ram.h"
17
18/***************************************************************************
19    TYPE DEFINITIONS
20***************************************************************************/
21
22struct _multicart_private
23{
24   object_pool *   pool;
25   zip_file *      zip;
26};
27
28
29typedef struct _multicart_load_state multicart_load_state;
30struct _multicart_load_state
31{
32   multicart_t *         multicart;
33   zip_file *         zip;
34   xml_data_node *         layout_xml;
35   xml_data_node *         resources_node;
36   xml_data_node *         pcb_node;
37   multicart_resource *      resources;
38   multicart_socket *      sockets;
39};
40
41static const char error_text[14][30] =
42{
43   "no error",
44   "not a multicart",
45   "module definition corrupt",
46   "out of memory",
47   "xml format error",
48   "invalid file reference",
49   "zip file error",
50   "missing ram length",
51   "invalid ram specification",
52   "unknown resource type",
53   "invalid resource reference",
54   "invalid file format",
55   "missing layout",
56   "no pcb or resource found"
57};
58
59const char *multicart_error_text(multicart_open_error error)
60{
61   return error_text[(int)error];
62}
63
64/***************************************************************************
65    IMPLEMENTATION
66***************************************************************************/
67
68/*-------------------------------------------------
69    find_file
70-------------------------------------------------*/
71
72static const zip_file_header *find_file(zip_file *zip, const char *filename)
73{
74   const zip_file_header *header;
75   for (header = zip_file_first_file(zip); header != NULL; header = zip_file_next_file(zip))
76   {
77      if (!core_stricmp(header->filename, filename))
78         return header;
79   }
80   return NULL;
81}
82
83static const zip_file_header *find_file_crc(zip_file *zip, const char *filename, UINT32 crc)
84{
85   const zip_file_header *header;
86   for (header = zip_file_first_file(zip); header != NULL; header = zip_file_next_file(zip))
87   {
88      // if the CRC and name both match, we're good
89      // if the CRC matches and the name doesn't, we're still good
90      if ((!core_stricmp(header->filename, filename)) && (header->crc == crc))
91      {
92         return header;
93      }
94      else if (header->crc == crc)
95      {
96         return header;
97      }
98   }
99   return NULL;
100}
101
102/*-------------------------------------------------
103    find_pcb_and_resource_nodes
104-------------------------------------------------*/
105
106static int find_pcb_and_resource_nodes(xml_data_node *layout_xml,
107   xml_data_node **pcb_node, xml_data_node **resource_node)
108{
109   xml_data_node *romset_node;
110   xml_data_node *configuration_node;
111
112   *pcb_node = NULL;
113   *resource_node = NULL;
114
115   romset_node = xml_get_sibling(layout_xml->child, "romset");
116   if (romset_node == NULL)
117      return FALSE;
118
119   configuration_node = xml_get_sibling(romset_node->child, "configuration");
120   if (configuration_node == NULL)
121      return FALSE;
122
123   *pcb_node = xml_get_sibling(configuration_node->child, "pcb");
124   if (*pcb_node == NULL)
125      return FALSE;
126
127   *resource_node = xml_get_sibling(romset_node->child, "resources");
128   if (*resource_node == NULL)
129      return FALSE;
130
131   return TRUE;
132}
133
134
135/*-------------------------------------------------
136    get_resource_type
137-------------------------------------------------*/
138
139static multicart_resource_type get_resource_type(const char *s)
140{
141   multicart_resource_type result;
142   if (!strcmp(s, "rom"))
143      result = MULTICART_RESOURCE_TYPE_ROM;
144   else if (!strcmp(s, "ram"))
145      result = MULTICART_RESOURCE_TYPE_RAM;
146   else
147      result = MULTICART_RESOURCE_TYPE_INVALID;
148   return result;
149}
150
151
152/*-------------------------------------------------
153    load_rom_resource
154-------------------------------------------------*/
155
156static multicart_open_error load_rom_resource(multicart_load_state *state, xml_data_node *resource_node,
157   multicart_resource *resource)
158{
159   const char *file, *crcstr, *sha1;
160   const zip_file_header *header;
161   zip_error ziperr;
162   UINT32 crc;
163
164   /* locate the 'file' attribute */
165   file = xml_get_attribute_string(resource_node, "file", NULL);
166   if (file == NULL)
167      return MCERR_XML_ERROR;
168
169   if (!(crcstr = xml_get_attribute_string(resource_node, "crc", NULL)))
170   {
171      /* locate the file in the ZIP file */
172      header = find_file(state->zip, file);
173   }
174   else   /* CRC tag is present, use it */
175   {
176      crc = strtoul(crcstr, NULL, 16);
177      header = find_file_crc(state->zip, file, crc);
178   }
179   if (header == NULL)
180      return MCERR_INVALID_FILE_REF;
181   resource->length = header->uncompressed_length;
182
183   /* allocate bytes for this resource */
184   resource->ptr = pool_malloc_lib(state->multicart->data->pool, resource->length);
185   if (resource->ptr == NULL)
186      return MCERR_OUT_OF_MEMORY;
187
188   /* and decompress it */
189   ziperr = zip_file_decompress(state->zip, resource->ptr, resource->length);
190   if (ziperr != ZIPERR_NONE)
191      return MCERR_ZIP_ERROR;
192
193   /* check SHA1 now */
194   if ((sha1 = xml_get_attribute_string(resource_node, "sha1", NULL)))
195   {
196      char calc_sha[256];
197
198      memset(calc_sha, 0, sizeof(calc_sha));
199      hash_compute(&calc_sha[0], (const unsigned char*)resource->ptr, resource->length, HASH_SHA1);
200
201      if ((strncmp(sha1, &calc_sha[2], 20)))
202      {
203         return MCERR_INVALID_FILE_REF;
204      }
205   }
206
207   return MCERR_NONE;
208}
209
210
211/*-------------------------------------------------
212    load_ram_resource
213-------------------------------------------------*/
214
215static multicart_open_error load_ram_resource(multicart_load_state *state, xml_data_node *resource_node,
216   multicart_resource *resource)
217{
218   const char *length_string;
219   const char *ram_type;
220   const char *ram_filename;
221
222   astring *ram_pathname;
223
224   /* locate the 'length' attribute */
225   length_string = xml_get_attribute_string(resource_node, "length", NULL);
226   if (length_string == NULL)
227      return MCERR_MISSING_RAM_LENGTH;
228
229   /* ...and parse it */
230   resource->length = ram_parse_string(length_string);
231   if (resource->length <= 0)
232      return MCERR_INVALID_RAM_SPEC;
233
234   /* allocate bytes for this resource */
235   resource->ptr = pool_malloc_lib(state->multicart->data->pool, resource->length);
236   if (resource->ptr == NULL)
237      return MCERR_OUT_OF_MEMORY;
238
239   /* Is this a persistent RAM resource? Then try to load it. */
240   ram_type = xml_get_attribute_string(resource_node, "type", NULL);
241   if (ram_type != NULL)
242   {
243      if (strcmp(ram_type, "persistent")==0)
244      {
245         astring tmp;
246
247         /* Get the file name. */
248         ram_filename = xml_get_attribute_string(resource_node, "file", NULL);
249         if (ram_filename==NULL)
250            return MCERR_XML_ERROR;
251
252         ram_pathname = astring_assemble_3(&tmp, state->multicart->gamedrv_name, PATH_SEPARATOR, ram_filename);
253
254         /* Save the file name so that we can write the contents on unloading.
255               If the RAM resource has no filename, we know that it was volatile only. */
256         resource->filename = pool_strdup_lib(state->multicart->data->pool, astring_c(ram_pathname));
257
258         if (resource->filename == NULL)
259            return MCERR_OUT_OF_MEMORY;
260
261         image_battery_load_by_name(resource->filename, resource->ptr, resource->length, 0x00);
262      }
263      /* else this type is volatile, in which case we just have
264            a memory expansion */
265   }
266   return MCERR_NONE;
267}
268
269
270/*-------------------------------------------------
271    load_resource
272-------------------------------------------------*/
273
274static multicart_open_error load_resource(multicart_load_state *state, xml_data_node *resource_node,
275   multicart_resource_type resource_type)
276{
277   const char *id;
278   multicart_open_error err;
279   multicart_resource *resource;
280   multicart_resource **next_resource;
281
282   /* get the 'id' attribute; error if not present */
283   id = xml_get_attribute_string(resource_node, "id", NULL);
284   if (id == NULL)
285      return MCERR_XML_ERROR;
286
287   /* allocate memory for the resource */
288   resource = (multicart_resource *)pool_malloc_lib(state->multicart->data->pool, sizeof(*resource));
289   if (resource == NULL)
290      return MCERR_OUT_OF_MEMORY;
291   memset(resource, 0, sizeof(*resource));
292   resource->type = resource_type;
293
294   /* copy id */
295   resource->id = pool_strdup_lib(state->multicart->data->pool, id);
296   if (resource->id == NULL)
297      return MCERR_OUT_OF_MEMORY;
298
299   switch(resource->type)
300   {
301      case MULTICART_RESOURCE_TYPE_ROM:
302         err = load_rom_resource(state, resource_node, resource);
303         if (err != MCERR_NONE)
304            return err;
305         break;
306
307      case MULTICART_RESOURCE_TYPE_RAM:
308         err = load_ram_resource(state, resource_node, resource);
309         if (err != MCERR_NONE)
310            return err;
311         break;
312
313      default:
314         return MCERR_UNKNOWN_RESOURCE_TYPE;
315   }
316
317   /* append the resource */
318   for (next_resource = &state->resources; *next_resource; next_resource = &(*next_resource)->next)
319      ;
320   *next_resource = resource;
321
322   return MCERR_NONE;
323}
324
325
326/*-------------------------------------------------
327    load_all_resources
328-------------------------------------------------*/
329
330static multicart_open_error load_all_resources(multicart_load_state *state)
331{
332   multicart_open_error err;
333   xml_data_node *resource_node;
334   multicart_resource_type resource_type;
335
336   for (resource_node = state->resources_node->child; resource_node != NULL; resource_node = resource_node->next)
337   {
338      resource_type = get_resource_type(resource_node->name);
339      if (resource_type != MULTICART_RESOURCE_TYPE_INVALID)
340      {
341         err = load_resource(state, resource_node, resource_type);
342         if (err != MCERR_NONE)
343            return err;
344      }
345   }
346
347   state->multicart->resources = state->resources;
348   return MCERR_NONE;
349}
350
351/*-------------------------------------------------
352    save_ram_resources. This is important for persistent RAM. All
353    resources were allocated within the memory pool of this device and will
354    be freed on multicart_close.
355-------------------------------------------------*/
356
357static multicart_open_error save_ram_resources(multicart_t *cart)
358{
359   const multicart_resource *resource;
360
361   for (resource = cart->resources; resource != NULL; resource = resource->next)
362   {
363      if ((resource->type == MULTICART_RESOURCE_TYPE_RAM) && (resource->filename != NULL))
364      {
365         image_battery_save_by_name(resource->filename, resource->ptr, resource->length);
366      }
367   }
368   return MCERR_NONE;
369}
370
371/*-------------------------------------------------
372    load_socket
373-------------------------------------------------*/
374
375static multicart_open_error load_socket(multicart_load_state *state, xml_data_node *socket_node)
376{
377   const char *id;
378   const char *uses;
379   const multicart_resource *resource;
380   multicart_socket *socket;
381   multicart_socket **next_socket;
382
383   /* get the 'id' and 'uses' attributes; error if not present */
384   id = xml_get_attribute_string(socket_node, "id", NULL);
385   uses = xml_get_attribute_string(socket_node, "uses", NULL);
386   if ((id == NULL) || (uses == NULL))
387      return MCERR_XML_ERROR;
388
389   /* find the resource */
390   for (resource = state->multicart->resources; resource != NULL; resource = resource->next)
391   {
392      if (!strcmp(uses, resource->id))
393         break;
394   }
395   if (resource == NULL)
396      return MCERR_INVALID_RESOURCE_REF;
397
398   /* create the socket */
399   socket = (multicart_socket *)pool_malloc_lib(state->multicart->data->pool, sizeof(*socket));
400   if (socket == NULL)
401      return MCERR_OUT_OF_MEMORY;
402   memset(socket, 0, sizeof(*socket));
403   socket->resource = resource;
404   socket->ptr = resource->ptr;
405
406   /* copy id */
407   socket->id = pool_strdup_lib(state->multicart->data->pool, id);
408   if (socket->id == NULL)
409      return MCERR_OUT_OF_MEMORY;
410
411   /* which pointer should I use? */
412   if (resource->ptr != NULL)
413   {
414      /* use the resource's ptr */
415      socket->ptr = resource->ptr;
416   }
417   else
418   {
419      /* allocate bytes for this socket */
420      socket->ptr = pool_malloc_lib(state->multicart->data->pool, resource->length);
421      if (socket->ptr == NULL)
422         return MCERR_OUT_OF_MEMORY;
423
424      /* ...and clear it */
425      memset(socket->ptr, 0xCD, resource->length);
426   }
427
428   /* append the resource */
429   for (next_socket = &state->sockets; *next_socket; next_socket = &(*next_socket)->next)
430      ;
431   *next_socket = socket;
432
433   return MCERR_NONE;
434}
435
436
437/*-------------------------------------------------
438    load_all_sockets
439-------------------------------------------------*/
440
441static multicart_open_error load_all_sockets(multicart_load_state *state)
442{
443   multicart_open_error err;
444   xml_data_node *socket_node;
445
446   for (socket_node = xml_get_sibling(state->pcb_node->child, "socket"); socket_node != NULL;
447      socket_node = xml_get_sibling(socket_node->next, "socket"))
448   {
449      err = load_socket(state, socket_node);
450      if (err != MCERR_NONE)
451         return err;
452   }
453
454   state->multicart->sockets = state->sockets;
455   return MCERR_NONE;
456}
457
458
459/*-------------------------------------------------
460    multicart_open - opens a multicart
461-------------------------------------------------*/
462
463multicart_open_error multicart_open(const char *filename, const char *gamedrv, multicart_load_flags load_flags, multicart_t **cart)
464{
465   multicart_open_error err;
466   zip_error ziperr;
467   object_pool *pool;
468   multicart_load_state state = {0, };
469   const zip_file_header *header;
470   const char *pcb_type;
471   char *layout_text = NULL;
472
473   /* allocate an object pool */
474   pool = pool_alloc_lib(NULL);
475   if (pool == NULL)
476   {
477      err = MCERR_OUT_OF_MEMORY;
478      goto done;
479   }
480
481   /* allocate the multicart */
482   state.multicart = (multicart_t*)pool_malloc_lib(pool, sizeof(*state.multicart));
483   if (state.multicart == NULL)
484   {
485      err = MCERR_OUT_OF_MEMORY;
486      goto done;
487   }
488   memset(state.multicart, 0, sizeof(*state.multicart));
489
490   /* allocate the multicart's private data */
491   state.multicart->data = (multicart_private*)pool_malloc_lib(pool, sizeof(*state.multicart->data));
492   if (state.multicart->data == NULL)
493   {
494      err = MCERR_OUT_OF_MEMORY;
495      goto done;
496   }
497   memset(state.multicart->data, 0, sizeof(*state.multicart->data));
498   state.multicart->data->pool = pool;
499   pool = NULL;
500
501   /* open the ZIP file */
502   ziperr = zip_file_open(filename, &state.zip);
503   if (ziperr != ZIPERR_NONE)
504   {
505      err = MCERR_NOT_MULTICART;
506      goto done;
507   }
508
509   /* find the layout.xml file */
510   header = find_file(state.zip, "layout.xml");
511   if (header == NULL)
512   {
513      err = MCERR_MISSING_LAYOUT;
514      goto done;
515   }
516
517   /* reserve space for the layout text */
518   layout_text = (char*)malloc(header->uncompressed_length + 1);
519   if (layout_text == NULL)
520   {
521      err = MCERR_OUT_OF_MEMORY;
522      goto done;
523   }
524
525   /* uncompress the layout text */
526   ziperr = zip_file_decompress(state.zip, layout_text, header->uncompressed_length);
527   if (ziperr != ZIPERR_NONE)
528   {
529      err = MCERR_ZIP_ERROR;
530      goto done;
531   }
532   layout_text[header->uncompressed_length] = '\0';
533
534   /* parse the layout text */
535   state.layout_xml = xml_string_read(layout_text, NULL);
536   if (state.layout_xml == NULL)
537   {
538      err = MCERR_XML_ERROR;
539      goto done;
540   }
541
542   /* locate the PCB node */
543   if (!find_pcb_and_resource_nodes(state.layout_xml, &state.pcb_node, &state.resources_node))
544   {
545      err = MCERR_NO_PCB_OR_RESOURCES;
546      goto done;
547   }
548
549   /* get the PCB resource_type */
550   pcb_type = xml_get_attribute_string(state.pcb_node, "type", "");
551   state.multicart->pcb_type = pool_strdup_lib(state.multicart->data->pool, pcb_type);
552   if (state.multicart->pcb_type == NULL)
553   {
554      err = MCERR_OUT_OF_MEMORY;
555      goto done;
556   }
557
558   state.multicart->gamedrv_name = pool_strdup_lib(state.multicart->data->pool, gamedrv);
559   if (state.multicart->gamedrv_name == NULL)
560   {
561      err = MCERR_OUT_OF_MEMORY;
562      goto done;
563   }
564
565   /* do we have to load resources? */
566   if (load_flags & MULTICART_FLAGS_LOAD_RESOURCES)
567   {
568      err = load_all_resources(&state);
569      if (err != MCERR_NONE)
570         goto done;
571
572      err = load_all_sockets(&state);
573      if (err != MCERR_NONE)
574         goto done;
575   }
576
577   err = MCERR_NONE;
578
579done:
580   if (pool != NULL)
581      pool_free_lib(pool);
582   if (state.zip != NULL)
583      zip_file_close(state.zip);
584   if (layout_text != NULL)
585      free(layout_text);
586   if (state.layout_xml != NULL)
587      xml_file_free(state.layout_xml);
588
589   if ((err != MCERR_NONE) && (state.multicart != NULL))
590   {
591      multicart_close(state.multicart);
592      state.multicart = NULL;
593   }
594   *cart = state.multicart;
595   return err;
596}
597
598
599/*-------------------------------------------------
600    multicart_close - closes a multicart
601-------------------------------------------------*/
602
603void multicart_close(multicart_t *cart)
604{
605   save_ram_resources(cart);
606   pool_free_lib(cart->data->pool);
607}
src/mess/devices/snapquik.c
r9927r9928
1/*********************************************************************
2
3    snapquik.h
4
5    Snapshots and quickloads
6
7*********************************************************************/
8
9#include "emu.h"
10#include "snapquik.h"
11#include "z80bin.h"
12
13
14
15/***************************************************************************
16    TYPE DEFINITIONS
17***************************************************************************/
18
19typedef struct _snapquick_token snapquick_token;
20struct _snapquick_token
21{
22   emu_timer *timer;
23   snapquick_load_func load;
24};
25
26
27
28/***************************************************************************
29    INLINE FUNCTIONS
30***************************************************************************/
31
32/*-------------------------------------------------
33    assert_is_snapshot_or_quickload - asserts/confirms
34    that a given device is a snapshot or quickload
35-------------------------------------------------*/
36
37INLINE void assert_is_snapshot_or_quickload(device_t *device)
38{
39   assert(device != NULL);
40   assert(downcast<const legacy_device_config_base &>(device->baseconfig()).inline_config() != NULL);
41   assert((device->type() == SNAPSHOT) || (device->type() == QUICKLOAD)
42      || (device->type() == Z80BIN));
43}
44
45
46
47/*-------------------------------------------------
48    get_token - safely gets the snapshot/quickload data
49-------------------------------------------------*/
50
51INLINE snapquick_token *get_token(device_t *device)
52{
53   assert_is_snapshot_or_quickload(device);
54   return (snapquick_token *) downcast<legacy_device_base *>(device)->token();
55}
56
57
58
59/*-------------------------------------------------
60    get_config - safely gets the quickload config
61-------------------------------------------------*/
62
63INLINE const snapquick_config *get_config(device_t *device)
64{
65   assert_is_snapshot_or_quickload(device);
66   return (const snapquick_config *) downcast<const legacy_device_config_base &>(device->baseconfig()).inline_config();
67}
68
69INLINE const snapquick_config *get_config_dev(const device_config *device)
70{
71   assert(device != NULL);
72   assert((device->type() == SNAPSHOT) || (device->type() == QUICKLOAD)
73      || (device->type() == Z80BIN));
74   return (const snapquick_config *) downcast<const legacy_device_config_base *>(device)->inline_config();
75}
76
77/*-------------------------------------------------
78    log_quickload - logs and displays useful
79    data for the end user
80-------------------------------------------------*/
81
82void log_quickload(const char *type, UINT32 start, UINT32 length, UINT32 exec, const char *exec_format)
83{
84    astring tempstring;
85
86    logerror("Loading %04X bytes of RAM at %04X\n", length, start);
87
88    tempstring.catprintf("Quickload type: %s   Length: %d bytes\n", type, length);
89    tempstring.catprintf("Start: 0x%04X   End: 0x%04X   Exec: ", start, start + length - 1);
90
91    logerror("Quickload loaded.\n");
92    if (!mame_stricmp(exec_format, EXEC_NA))
93        tempstring.cat("N/A");
94    else
95    {
96        logerror("Execution can resume with ");
97        logerror(exec_format, exec);
98        logerror("\n");
99        tempstring.catprintf(exec_format, exec);
100    }
101
102    ui_popup_time(10, "%s", tempstring.cstr());
103}
104
105/***************************************************************************
106    IMPLEMENTATION
107***************************************************************************/
108
109/*-------------------------------------------------
110    TIMER_CALLBACK(process_snapshot_or_quickload)
111-------------------------------------------------*/
112
113static TIMER_CALLBACK(process_snapshot_or_quickload)
114{
115   device_image_interface *image = (device_image_interface *) ptr;
116   snapquick_token *token = get_token(&image->device());
117
118   /* invoke the load */
119   (*token->load)(*image,
120      image->filetype(),
121      image->length());
122
123   /* unload the device */
124   image->unload();
125}
126
127
128
129/*-------------------------------------------------
130    DEVICE_START( snapquick )
131-------------------------------------------------*/
132
133static DEVICE_START( snapquick )
134{
135   snapquick_token *token = get_token(device);
136
137   /* allocate a timer */
138   token->timer = timer_alloc(device->machine, process_snapshot_or_quickload, (void *) dynamic_cast<device_image_interface *>(device));
139
140}
141
142
143
144/*-------------------------------------------------
145    DEVICE_IMAGE_LOAD( snapquick )
146-------------------------------------------------*/
147
148static DEVICE_IMAGE_LOAD( snapquick )
149{
150   const snapquick_config *config = get_config(image);
151   snapquick_token *token = get_token(image);
152
153   /* locate the load function */
154   token->load = (snapquick_load_func) reinterpret_cast<snapquick_load_func>(image.get_device_specific_call());
155
156   /* adjust the timer */
157   timer_adjust_oneshot(
158      token->timer,
159      attotime_make(config->delay_seconds, config->delay_attoseconds),
160      0);
161
162   return IMAGE_INIT_PASS;
163}
164
165
166
167/*-------------------------------------------------
168    DEVICE_GET_INFO(snapquick) - device getinfo
169    function
170-------------------------------------------------*/
171
172static DEVICE_GET_INFO(snapquick)
173{
174   switch(state)
175   {
176      /* --- the following bits of info are returned as 64-bit signed integers --- */
177      case DEVINFO_INT_TOKEN_BYTES:               info->i = sizeof(snapquick_token); break;
178      case DEVINFO_INT_INLINE_CONFIG_BYTES:         info->i = sizeof(snapquick_config); break;
179      case DEVINFO_INT_IMAGE_READABLE:            info->i = 1; break;
180      case DEVINFO_INT_IMAGE_WRITEABLE:            info->i = 0; break;
181      case DEVINFO_INT_IMAGE_CREATABLE:            info->i = 0; break;
182
183      /* --- the following bits of info are returned as pointers to functions --- */
184      case DEVINFO_FCT_START:                     info->start = DEVICE_START_NAME(snapquick); break;
185      case DEVINFO_FCT_IMAGE_LOAD:               info->f = (genf *) DEVICE_IMAGE_LOAD_NAME(snapquick); break;
186      case DEVINFO_FCT_SNAPSHOT_QUICKLOAD_LOAD:      info->f = (genf *) get_config_dev(device)->load; break;
187
188      /* --- the following bits of info are returned as NULL-terminated strings --- */
189      case DEVINFO_STR_SOURCE_FILE:               strcpy(info->s, __FILE__); break;
190      case DEVINFO_STR_IMAGE_FILE_EXTENSIONS:         strcpy(info->s, get_config_dev(device)->file_extensions); break;
191   }
192}
193
194
195
196/*-------------------------------------------------
197    DEVICE_GET_INFO(snapshot) - device getinfo
198    function
199-------------------------------------------------*/
200
201DEVICE_GET_INFO(snapshot)
202{
203   switch(state)
204   {
205      /* --- the following bits of info are returned as 64-bit signed integers --- */
206      case DEVINFO_INT_IMAGE_TYPE:               info->i = IO_SNAPSHOT; break;
207
208      /* --- the following bits of info are returned as NULL-terminated strings --- */
209      case DEVINFO_STR_NAME:                     strcpy(info->s, "Snapshot"); break;
210      case DEVINFO_STR_FAMILY:                  strcpy(info->s, "Snapshot"); break;
211
212      default: DEVICE_GET_INFO_CALL(snapquick); break;
213   }
214}
215
216
217
218/*-------------------------------------------------
219    DEVICE_GET_INFO(quickload) - device getinfo
220    function
221-------------------------------------------------*/
222
223DEVICE_GET_INFO(quickload)
224{
225   switch(state)
226   {
227      /* --- the following bits of info are returned as 64-bit signed integers --- */
228      case DEVINFO_INT_IMAGE_TYPE:               info->i = IO_QUICKLOAD; break;
229
230      /* --- the following bits of info are returned as NULL-terminated strings --- */
231      case DEVINFO_STR_NAME:                     strcpy(info->s, "Quickload"); break;
232      case DEVINFO_STR_FAMILY:                  strcpy(info->s, "Quickload"); break;
233
234      default: DEVICE_GET_INFO_CALL(snapquick); break;
235   }
236}
237
238DEFINE_LEGACY_IMAGE_DEVICE(SNAPSHOT, snapshot);
239DEFINE_LEGACY_IMAGE_DEVICE(QUICKLOAD, quickload);
src/mess/devices/bitbngr.h
r9927r9928
1/*********************************************************************
2
3    bitbngr.h
4
5    TRS style "bitbanger" serial port
6
7*********************************************************************/
8
9#ifndef __BITBNGR_H__
10#define __BITBNGR_H__
11
12#include "image.h"
13
14
15enum
16{
17   BITBANGER_PRINTER         = 0,
18   BITBANGER_MODEM,
19   BITBANGER_MODE_MAX,
20
21   BITBANGER_150            = 0,
22   BITBANGER_300,
23   BITBANGER_600,
24   BITBANGER_1200,
25   BITBANGER_2400,
26   BITBANGER_4800,
27   BITBANGER_9600,
28   BITBANGER_14400,
29   BITBANGER_28800,
30   BITBANGER_38400,
31   BITBANGER_57600,
32   BITBANGER_115200,
33   BITBANGER_BAUD_MAX,
34
35   BITBANGER_NEG40PERCENT  = 0,
36   BITBANGER_NEG35PERCENT,
37   BITBANGER_NEG30PERCENT,
38   BITBANGER_NEG25PERCENT,
39   BITBANGER_NEG20PERCENT,
40   BITBANGER_NEG15PERCENT,
41   BITBANGER_NEG10PERCENT,
42   BITBANGER_NEG5PERCENT,
43   BITBANGER_0PERCENT,
44   BITBANGER_POS5PERCENT,
45   BITBANGER_POS10PERCENT,
46   BITBANGER_POS15PERCENT,
47   BITBANGER_POS20PERCENT,
48   BITBANGER_POS25PERCENT,
49   BITBANGER_POS30PERCENT,
50   BITBANGER_POS35PERCENT,
51   BITBANGER_POS40PERCENT,
52   BITBANGER_TUNE_MAX
53};
54
55/***************************************************************************
56    CONSTANTS
57***************************************************************************/
58DECLARE_LEGACY_IMAGE_DEVICE(BITBANGER, bitbanger);
59
60#define MCFG_BITBANGER_ADD(_tag, _intrf) \
61   MCFG_DEVICE_ADD(_tag, BITBANGER, 0) \
62   MCFG_DEVICE_CONFIG(_intrf)
63
64
65/***************************************************************************
66    TYPE DEFINITIONS
67***************************************************************************/
68
69typedef struct _bitbanger_config bitbanger_config;
70struct _bitbanger_config
71{
72   /* callback to driver */
73   void (*input_callback)(running_machine *machine, UINT8 bit);
74   int default_mode;                  /* emulating a printer or modem */
75   int default_baud;                  /* output bits per second */
76   int default_tune;                /* fine tune adjustment to the baud */
77};
78
79
80
81/***************************************************************************
82    FUNCTION PROTOTYPES
83***************************************************************************/
84
85/* outputs data to a bitbanger port */
86void bitbanger_output(device_t *device, int value);
87
88/* ui functions */
89const char *bitbanger_mode_string(device_t *device);
90const char *bitbanger_baud_string(device_t *device);
91const char *bitbanger_tune_string(device_t *device);
92bool bitbanger_inc_mode(device_t *device, bool test);
93bool bitbanger_dec_mode(device_t *device, bool test);
94bool bitbanger_inc_tune(device_t *device, bool test);
95bool bitbanger_dec_tune(device_t *device, bool test);
96bool bitbanger_inc_baud(device_t *device, bool test);
97bool bitbanger_dec_baud(device_t *device, bool test);
98
99#endif /* __BITBNGR_H__ */
src/mess/devices/coco_fdc.c
r9927r9928
6868
6969#include "emu.h"
7070#include "cococart.h"
71#include "flopdrv.h"
71#include "imagedev/flopdrv.h"
7272#include "includes/coco.h"
7373#include "machine/wd17xx.h"
7474#include "machine/ds1315.h"
7575#include "machine/msm6242.h"
76#include "devices/flopdrv.h"
76#include "imagedev/flopdrv.h"
7777#include "formats/coco_dsk.h"
7878
7979
src/mess/devices/cococart.h
r9927r9928
1010#define __COCOCART_H__
1111
1212#include "image.h"
13#include "cartslot.h"
13#include "imagedev/cartslot.h"
1414
1515/***************************************************************************
1616    CONSTANTS
src/mess/devices/ti99_hd.c
r9927r9928
1414#include "emu.h"
1515#include "imageutl.h"
1616#include "harddisk.h"
17#include "harddriv.h"
17#include "imagedev/harddriv.h"
1818#include "machine/smc92x4.h"
1919
2020#include "ti99_hd.h"
src/mess/devices/sonydriv.c
r9927r9928
3434#include "machine/applefdc.h"
3535#include "sonydriv.h"
3636#include "formats/ap_dsk35.h"
37#include "flopdrv.h"
37#include "imagedev/flopdrv.h"
3838
3939
4040#ifdef MAME_DEBUG
src/mess/devices/appldriv.c
r9927r9928
77*********************************************************************/
88#include "emu.h"
99#include "appldriv.h"
10#include "flopdrv.h"
10#include "imagedev/flopdrv.h"
1111#include "formats/ap2_dsk.h"
1212
1313struct apple525_disk
src/mess/devices/sonydriv.h
r9927r9928
1010#define SONYDRIV_H
1111
1212#include "image.h"
13#include "flopdrv.h"
13#include "imagedev/flopdrv.h"
1414
1515#if 0
1616enum
src/mess/devices/aescart.c
r9927r9928
1313*********************************************************************/
1414#include "emu.h"
1515#include "aescart.h"
16#include "cartslot.h"
17#include "multcart.h"
16#include "imagedev/cartslot.h"
17#include "imagedev/multcart.h"
1818#include "includes/neogeo.h"
1919
2020typedef int assmfct(running_machine *machine, device_t *);
src/mess/devices/aescart.h
r9927r9928
1010#define __AESCART_H__
1111
1212#include "image.h"
13#include "cartslot.h"
13#include "imagedev/cartslot.h"
1414
1515DECLARE_LEGACY_CART_SLOT_DEVICE(AES_MULTICART, aes_multicart);
1616DECLARE_LEGACY_CART_SLOT_DEVICE(AES_CARTRIDGE_PCB_NONE, aes_cartridge_pcb_none);
src/mess/devices/cococart.c
r9927r9928
88
99#include "emu.h"
1010#include "cococart.h"
11#include "cartslot.h"
11#include "imagedev/cartslot.h"
1212
1313
1414/***************************************************************************
src/mess/osd/windows/menu.c
r9927r9928
2525#include "strconv.h"
2626#include "debug/debugcpu.h"
2727#include "inptport.h"
28#include "devices/cassette.h"
28#include "imagedev/cassette.h"
2929#include "windows/window.h"
30#include "uimess.h"
3130#include "winutf8.h"
3231
3332#ifdef UNDER_CE
src/mess/messcore.mak
r9927r9928
7575
7676EMUOBJS += \
7777   $(MESSOBJ)/mess.o      \
78   $(MESSOBJ)/uimess.o      \
7978
8079$(LIBEMU): $(EMUOBJS)
src/mess/tiny.mak
r9927r9928
5050   $(MESSOBJ)/tiny.o \
5151   $(MESS_DRIVERS)/coleco.o \
5252   $(EMU_VIDEO)/tms9928a.o \
53   $(MESS_DEVICES)/cartslot.o \
54   $(MESS_DEVICES)/cassette.o   \
55   $(MESS_DEVICES)/messram.o   \
56   $(MESS_DEVICES)/multcart.o   \
57   $(MESS_FORMATS)/cassimg.o   \
58   $(MESS_FORMATS)/wavfile.o   \
5953
6054
6155
src/mess/tools/castool/main.c
r9927r9928
1919#include "mess.h"
2020#include "fileio.h"
2121
22#include "devices/cassette.h"
22#include "imagedev/cassette.h"
2323
2424#include "formats/a26_cas.h"
2525#include "formats/apf_apt.h"
src/mess/tools/imgtool/iflopimg.c
r9927r9928
77*********************************************************************/
88
99#include "emu.h"
10#include "formats/flopimg.h"
10#include "imagedev/flopimg.h"
1111#include "imgtoolx.h"
1212#include "library.h"
1313#include "iflopimg.h"
src/mess/tools/imgtool/iflopimg.h
r9927r9928
99#ifndef IFLOPIMG_H
1010#define IFLOPIMG_H
1111
12#include "formats/flopimg.h"
12#include "imagedev/flopimg.h"
1313#include "imgtoolx.h"
1414#include "library.h"
1515
src/mess/tools/imgtool/imgtool.h
r9927r9928
1414
1515#include "emu.h"
1616#include "osdepend.h"
17#include "formats/flopimg.h"
17#include "imagedev/flopimg.h"
1818#include "opresolv.h"
1919#include "library.h"
2020#include "filter.h"
src/mess/machine/dgn_beta.c
r9927r9928
6666#include "machine/6551.h"
6767#include "image.h"
6868#include "machine/wd17xx.h"
69#include "devices/flopdrv.h"
69#include "imagedev/flopdrv.h"
7070
7171#include "debug/debugcpu.h"
7272#include "debug/debugcon.h"
src/mess/machine/gdrom.c
r9927r9928
99#include "cdrom.h"
1010#include "sound/cdda.h"
1111#ifdef MESS
12#include "devices/chd_cd.h"
12#include "imagedev/chd_cd.h"
1313#endif
1414#include "gdrom.h"
1515
src/mess/machine/dai.c
r9927r9928
1111
1212#include <stdarg.h>
1313#include "emu.h"
14#include "devices/cassette.h"
14#include "imagedev/cassette.h"
1515#include "cpu/i8085/i8085.h"
1616#include "machine/i8255a.h"
1717#include "includes/dai.h"
src/mess/machine/upd765.h
r9927r9928
1111#define __UPD765_H__
1212
1313#include "devcb.h"
14#include "devices/flopdrv.h"
14#include "imagedev/flopdrv.h"
1515
1616
1717/***************************************************************************
src/mess/machine/c1581.c
r9927r9928
2020#include "emu.h"
2121#include "c1581.h"
2222#include "cpu/m6502/m6502.h"
23#include "devices/flopdrv.h"
23#include "imagedev/flopdrv.h"
2424#include "formats/d81_dsk.h"
2525#include "machine/6526cia.h"
2626#include "machine/cbmiec.h"
src/mess/machine/adam.c
r9927r9928
99#include "emu.h"
1010#include "video/tms9928a.h"
1111#include "includes/adam.h"
12#include "devices/flopdrv.h"
13#include "devices/cartslot.h"
12#include "imagedev/flopdrv.h"
13#include "imagedev/cartslot.h"
1414
1515
1616
src/mess/machine/cbmb.c
r9927r9928
1414#include "includes/cbmb.h"
1515#include "crsshair.h"
1616
17#include "devices/cartslot.h"
17#include "imagedev/cartslot.h"
1818
1919/* 2008-05 FP: Were these added as a reminder to add configs of
2020drivers 8 & 9 as in pet.c ? */
src/mess/machine/mbee.c
r9927r9928
1010
1111#include "emu.h"
1212#include "machine/mc146818.h"
13#include "devices/flopdrv.h"
13#include "imagedev/flopdrv.h"
1414#include "includes/mbee.h"
1515
1616
src/mess/machine/ti99/gromport.c
r9927r9928
66
77#include "emu.h"
88#include "gromport.h"
9#include "devices/cartslot.h"
10#include "devices/multcart.h"
9#include "imagedev/cartslot.h"
10#include "imagedev/multcart.h"
1111#include "grom.h"
1212
1313typedef UINT8   (*read8z_device_func)  (ATTR_UNUSED device_t *device, ATTR_UNUSED offs_t offset, UINT8 *value);
src/mess/machine/ti99/gromport.h
r9927r9928
99#ifndef __TI99CART_H__
1010#define __TI99CART_H__
1111
12#include "devices/cartslot.h"
12#include "imagedev/cartslot.h"
1313#include "ti99defs.h"
1414
1515typedef struct _ti99_multicart_config
src/mess/machine/ti99/sgcpu.c
r9927r9928
1616#include "sgcpu.h"
1717#include "videowrp.h"
1818#include "sound/sn76496.h"
19#include "devices/cassette.h"
19#include "imagedev/cassette.h"
2020
2121typedef struct _sgcpu_state
2222{
src/mess/machine/ti99/ti_fdc.c
r9927r9928
99#include "ti_fdc.h"
1010#include "machine/wd17xx.h"
1111#include "formats/ti99_dsk.h"
12#include "devices/flopdrv.h"
12#include "imagedev/flopdrv.h"
1313
1414#define CRU_BASE 0x1100
1515
src/mess/machine/ti99/hfdc.c
r9927r9928
77#include "ti_fdc.h"
88#include "machine/wd17xx.h"
99#include "formats/ti99_dsk.h"
10#include "devices/flopdrv.h"
10#include "imagedev/flopdrv.h"
1111#include "devices/ti99_hd.h"
1212#include "machine/mm58274c.h"
1313#include "hfdc.h"
src/mess/machine/ti99/peribox.c
r9927r9928
131131#include "spchsyn.h"
132132#include "evpc.h"
133133
134#include "devices/flopdrv.h"
135#include "devices/harddriv.h"
134#include "imagedev/flopdrv.h"
135#include "imagedev/harddriv.h"
136136#include "formats/ti99_dsk.h"
137137#include "devices/ti99_hd.h"
138138
src/mess/machine/ti99/bwg.c
r9927r9928
2323#include "bwg.h"
2424#include "machine/wd17xx.h"
2525#include "formats/ti99_dsk.h"
26#include "devices/flopdrv.h"
26#include "imagedev/flopdrv.h"
2727#include "machine/mm58274c.h"
2828
2929#define CRU_BASE 0x1100
src/mess/machine/ti99/tiboard.c
r9927r9928
1111#include "video/tms9928a.h"
1212#include "handset.h"
1313#include "mecmouse.h"
14#include "devices/cassette.h"
14#include "imagedev/cassette.h"
1515#include "mapper8.h"
1616
1717typedef struct _tiboard_state
src/mess/machine/coco.c
r9927r9928
9595#include "machine/6551.h"
9696#include "video/coco6847.h"
9797#include "formats/cocopak.h"
98#include "devices/bitbngr.h"
99#include "devices/printer.h"
100#include "devices/cassette.h"
98#include "imagedev/bitbngr.h"
99#include "imagedev/printer.h"
100#include "imagedev/cassette.h"
101101#include "machine/wd17xx.h"
102102#include "sound/dac.h"
103103#include "sound/ay8910.h"
104104#include "devices/cococart.h"
105#include "devices/cartslot.h"
106#include "devices/flopdrv.h"
105#include "imagedev/cartslot.h"
106#include "imagedev/flopdrv.h"
107107#include "machine/ram.h"
108108#include "crsshair.h"
109109
src/mess/machine/gb.c
r9927r9928
3737
3838#include "emu.h"
3939#include "cpu/lr35902/lr35902.h"
40#include "devices/cartslot.h"
40#include "imagedev/cartslot.h"
4141#include "machine/ram.h"
4242#include "image.h"
4343#include "audio/gb.h"
src/mess/machine/990_hd.c
r9927r9928
2121#include "990_hd.h"
2222
2323#include "harddisk.h"
24#include "devices/harddriv.h"
24#include "imagedev/harddriv.h"
2525
2626static void update_interrupt(running_machine *machine);
2727
src/mess/machine/990_hd.h
r9927r9928
44#ifndef __990_HD_H_
55#define __990_HD_H_
66
7#include "devices/harddriv.h"
7#include "imagedev/harddriv.h"
88
99MACHINE_START( ti990_hdc );
1010
src/mess/machine/radio86.c
r9927r9928
99
1010#include "emu.h"
1111#include "cpu/i8085/i8085.h"
12#include "devices/cassette.h"
12#include "imagedev/cassette.h"
1313#include "machine/i8255a.h"
1414#include "machine/i8257.h"
1515#include "video/i8275.h"
src/mess/machine/smartmed.c
r9927r9928
2121#include "smartmed.h"
2222
2323#include "harddisk.h"
24#include "devices/harddriv.h"
24#include "imagedev/harddriv.h"
2525
2626#define MAX_SMARTMEDIA   1
2727
src/mess/machine/b2m.c
r9927r9928
99
1010#include "emu.h"
1111#include "cpu/i8085/i8085.h"
12#include "devices/cassette.h"
12#include "imagedev/cassette.h"
1313#include "machine/i8255a.h"
1414#include "machine/pit8253.h"
1515#include "machine/wd17xx.h"
r9927r9928
1717#include "machine/msm8251.h"
1818#include "includes/b2m.h"
1919#include "machine/ram.h"
20#include "devices/flopdrv.h"
20#include "imagedev/flopdrv.h"
2121
2222static READ8_HANDLER (b2m_keyboard_r )
2323{
src/mess/machine/cdicdic.c
r9927r9928
2121
2222#include "emu.h"
2323#include "cpu/m68000/m68000.h"
24#include "devices/chd_cd.h"
24#include "imagedev/chd_cd.h"
2525#include "machine/cdicdic.h"
2626#include "includes/cdi.h"
2727#include "sound/cdda.h"
src/mess/machine/cdicdic.h
r9927r9928
2525#define __CDICDIC_H__
2626
2727#include "emu.h"
28#include "devices/chd_cd.h"
28#include "imagedev/chd_cd.h"
2929
3030//**************************************************************************
3131//  INTERFACE CONFIGURATION MACROS
src/mess/machine/pmd85.c
r9927r9928
1010***************************************************************************/
1111
1212#include "emu.h"
13#include "devices/cassette.h"
13#include "imagedev/cassette.h"
1414#include "cpu/i8085/i8085.h"
1515#include "machine/i8255a.h"
1616#include "includes/pmd85.h"
src/mess/machine/c128.c
r9927r9928
1515#include "includes/cbm.h"
1616#include "machine/cbmiec.h"
1717#include "cpu/m6502/m6502.h"
18#include "devices/cassette.h"
18#include "imagedev/cassette.h"
1919#include "machine/6526cia.h"
2020#include "sound/sid6581.h"
2121#include "video/vic6567.h"
src/mess/machine/c2040.c
r9927r9928
2424#include "emu.h"
2525#include "c2040.h"
2626#include "cpu/m6502/m6502.h"
27#include "devices/flopdrv.h"
27#include "imagedev/flopdrv.h"
2828#include "formats/d64_dsk.h"
2929#include "formats/g64_dsk.h"
3030#include "machine/6522via.h"
src/mess/machine/pet.c
r9927r9928
1414
1515#include "includes/pet.h"
1616
17#include "devices/cartslot.h"
18#include "devices/cassette.h"
17#include "imagedev/cartslot.h"
18#include "imagedev/cassette.h"
1919#include "machine/ram.h"
2020
2121#define VERBOSE_LEVEL 0
src/mess/machine/c16.c
r9927r9928
1212#include "image.h"
1313#include "audio/ted7360.h"
1414#include "cpu/m6502/m6502.h"
15#include "devices/cassette.h"
16#include "devices/cartslot.h"
15#include "imagedev/cassette.h"
16#include "imagedev/cartslot.h"
1717#include "machine/ram.h"
1818#include "includes/c16.h"
1919#include "machine/cbmiec.h"
src/mess/machine/oric.c
r9927r9928
2525#include "machine/applefdc.h"
2626#include "machine/6551.h"
2727#include "machine/ctronics.h"
28#include "devices/cassette.h"
28#include "imagedev/cassette.h"
2929#include "sound/ay8910.h"
30#include "devices/flopdrv.h"
30#include "imagedev/flopdrv.h"
3131
3232
3333
src/mess/machine/990_dk.c
r9927r9928
1212
1313#include "990_dk.h"
1414#include "formats/basicdsk.h"
15#include "devices/flopdrv.h"
15#include "imagedev/flopdrv.h"
1616
1717#define MAX_FLOPPIES 4
1818
src/mess/machine/orao.c
r9927r9928
99
1010#include "emu.h"
1111#include "sound/dac.h"
12#include "devices/cassette.h"
12#include "imagedev/cassette.h"
1313#include "includes/orao.h"
1414
1515
src/mess/machine/990_dk.h
r9927r9928
11/*
22    990_dk.h: include file for 990_dk.c
33*/
4#include "formats/flopimg.h"
4#include "imagedev/flopimg.h"
55
66FLOPPY_OPTIONS_EXTERN(fd800);
77
src/mess/machine/vector06.c
r9927r9928
1111#include "cpu/i8085/i8085.h"
1212#include "machine/i8255a.h"
1313#include "machine/wd17xx.h"
14#include "devices/cassette.h"
14#include "imagedev/cassette.h"
1515#include "includes/vector06.h"
1616#include "machine/ram.h"
1717
src/mess/machine/electron.c
r9927r9928
1010#include "emu.h"
1111#include "includes/electron.h"
1212#include "sound/beep.h"
13#include "devices/cassette.h"
13#include "imagedev/cassette.h"
1414
1515
1616static device_t *cassette_device_image( running_machine *machine )
src/mess/machine/pc_hdc.c
r9927r9928
3232#include "emu.h"
3333#include "machine/pc_hdc.h"
3434#include "machine/8237dma.h"
35#include "devices/harddriv.h"
35#include "imagedev/harddriv.h"
3636#include "memconv.h"
3737
3838
src/mess/machine/orion.c
r9927r9928
1010
1111#include "emu.h"
1212#include "cpu/i8085/i8085.h"
13#include "devices/cassette.h"
13#include "imagedev/cassette.h"
1414#include "machine/mc146818.h"
1515#include "machine/wd17xx.h"
1616#include "sound/speaker.h"
src/mess/machine/amigafdc.c
r9927r9928
1313
1414#include "emu.h"
1515#include "includes/amiga.h"
16#include "devices/flopdrv.h"
16#include "imagedev/flopdrv.h"
1717#include "formats/ami_dsk.h"
1818#include "amigafdc.h"
1919#include "machine/6526cia.h"
src/mess/machine/bk.c
r9927r9928
88
99
1010#include "emu.h"
11#include "devices/cassette.h"
11#include "imagedev/cassette.h"
1212#include "machine/i8255a.h"
1313#include "includes/bk.h"
1414
src/mess/machine/c1541.c
r9927r9928
136136#include "emu.h"
137137#include "c1541.h"
138138#include "cpu/m6502/m6502.h"
139#include "devices/flopdrv.h"
139#include "imagedev/flopdrv.h"
140140#include "formats/d64_dsk.h"
141141#include "formats/g64_dsk.h"
142142#include "machine/6522via.h"
src/mess/machine/matsucd.c
r9927r9928
1313
1414
1515#include "emu.h"
16#include "devices/chd_cd.h"
16#include "imagedev/chd_cd.h"
1717#include "sound/cdda.h"
1818#include "machine/matsucd.h"
1919
src/mess/machine/nascom1.c
r9927r9928
1414#include "machine/ay31015.h"
1515
1616/* Devices */
17#include "devices/snapquik.h"
18#include "devices/cassette.h"
19#include "devices/flopdrv.h"
17#include "imagedev/snapquik.h"
18#include "imagedev/cassette.h"
19#include "imagedev/flopdrv.h"
2020#include "machine/ram.h"
2121
2222#define NASCOM1_KEY_RESET   0x02
src/mess/machine/microtan.c
r9927r9928
2323#include "sound/ay8910.h"
2424
2525/* Devices */
26#include "devices/cassette.h"
27//#include "devices/snapquik.h"
26#include "imagedev/cassette.h"
27//#include "imagedev/snapquik.h"
2828
2929
3030#ifndef VERBOSE
src/mess/machine/osborne1.c
r9927r9928
2222#include "cpu/z80/z80daisy.h"
2323#include "sound/beep.h"
2424#include "includes/osborne1.h"
25#include "devices/flopdrv.h"
25#include "imagedev/flopdrv.h"
2626#include "machine/ram.h"
2727
2828#define RAMMODE      (0x01)
src/mess/machine/amstrad.c
r9927r9928
4141#include "machine/mc146818.h"
4242#include "machine/upd765.h"
4343#include "machine/ctronics.h"
44#include "devices/cassette.h"
45#include "devices/snapquik.h"
44#include "imagedev/cassette.h"
45#include "imagedev/snapquik.h"
4646#include "includes/amstrad.h"
4747#include "sound/ay8910.h"
4848#include "machine/ram.h"
src/mess/machine/wd17xx.c
r9927r9928
139139#include "emu.h"
140140#include "imageutl.h"
141141#include "machine/wd17xx.h"
142#include "devices/flopdrv.h"
143#include "formats/flopimg.h"
142#include "imagedev/flopdrv.h"
143#include "imagedev/flopimg.h"
144144
145145/***************************************************************************
146146    CONSTANTS
src/mess/machine/sms.c
r9927r9928
44#include "includes/sms.h"
55#include "video/smsvdp.h"
66#include "sound/2413intf.h"
7#include "devices/cartslot.h"
7#include "imagedev/cartslot.h"
88
99#define VERBOSE 0
1010#define LOG(x) do { if (VERBOSE) logerror x; } while (0)
src/mess/machine/poly88.c
r9927r9928
88
99#include "emu.h"
1010#include "cpu/i8085/i8085.h"
11#include "devices/cassette.h"
11#include "imagedev/cassette.h"
1212#include "includes/poly88.h"
1313
1414
src/mess/machine/c8280.c
r9927r9928
1010#include "emu.h"
1111#include "c8280.h"
1212#include "cpu/m6502/m6502.h"
13#include "devices/flopdrv.h"
13#include "imagedev/flopdrv.h"
1414#include "machine/6532riot.h"
1515#include "machine/ieee488.h"
1616
src/mess/machine/comx35.c
r9927r9928
117117#include "emu.h"
118118#include "cpu/cosmac/cosmac.h"
119119#include "machine/wd17xx.h"
120#include "devices/printer.h"
121#include "devices/snapquik.h"
120#include "imagedev/printer.h"
121#include "imagedev/snapquik.h"
122122#include "sound/cdp1869.h"
123123#include "video/mc6845.h"
124124#include "includes/comx35.h"
125125#include "machine/rescap.h"
126#include "devices/flopdrv.h"
126#include "imagedev/flopdrv.h"
127127#include "machine/ram.h"
128128
129129enum
src/mess/machine/trs80.c
r9927r9928
1919#include "machine/wd17xx.h"
2020
2121/* Devices */
22#include "devices/cassette.h"
23#include "devices/flopdrv.h"
22#include "imagedev/cassette.h"
23#include "imagedev/flopdrv.h"
2424
2525
2626#ifdef MAME_DEBUG
src/mess/machine/odyssey2.c
r9927r9928
88
99#include "emu.h"
1010#include "includes/odyssey2.h"
11#include "devices/cartslot.h"
11#include "imagedev/cartslot.h"
1212#include "sound/sp0256.h"
1313
1414
src/mess/machine/primo.c
r9927r9928
1919#include "sound/speaker.h"
2020
2121/* Devices */
22#include "devices/cassette.h"
23#include "devices/snapquik.h"
24#include "devices/cartslot.h"
22#include "imagedev/cassette.h"
23#include "imagedev/snapquik.h"
24#include "imagedev/cartslot.h"
2525
2626
2727
src/mess/machine/svi318.c
r9927r9928
1414#include "machine/ins8250.h"
1515#include "machine/wd17xx.h"
1616#include "machine/ctronics.h"
17#include "devices/flopdrv.h"
18#include "devices/cassette.h"
17#include "imagedev/flopdrv.h"
18#include "imagedev/cassette.h"
1919#include "formats/svi_cas.h"
2020#include "sound/dac.h"
2121#include "sound/ay8910.h"
src/mess/machine/galaxy.c
r9927r9928
1010#include "emu.h"
1111#include "cpu/z80/z80.h"
1212#include "includes/galaxy.h"
13#include "devices/cassette.h"
13#include "imagedev/cassette.h"
1414#include "machine/ram.h"
1515
1616/***************************************************************************
src/mess/machine/vtech2.c
r9927r9928
1515
1616#include "emu.h"
1717#include "includes/vtech2.h"
18#include "devices/flopdrv.h"
19#include "devices/cassette.h"
18#include "imagedev/flopdrv.h"
19#include "imagedev/cassette.h"
2020#include "sound/speaker.h"
2121
2222/* public */
src/mess/machine/corvushd.c
r9927r9928
6464//
6565
6666#include "emu.h"
67#include "devices/harddriv.h"
67#include "imagedev/harddriv.h"
6868#include "includes/corvushd.h"
6969#include <ctype.h>
7070
src/mess/machine/c1551.c
r9927r9928
2020#include "emu.h"
2121#include "c1551.h"
2222#include "cpu/m6502/m6502.h"
23#include "devices/flopdrv.h"
23#include "imagedev/flopdrv.h"
2424#include "formats/d64_dsk.h"
2525#include "formats/g64_dsk.h"
2626#include "machine/6525tpi.h"
src/mess/machine/wswan.c
r9927r9928
1717
1818#include "emu.h"
1919#include "includes/wswan.h"
20#include "devices/cartslot.h"
20#include "imagedev/cartslot.h"
2121#include "image.h"
2222
2323#define INTERNAL_EEPROM_SIZE   1024
src/mess/machine/zx.c
r9927r9928
99#include "emu.h"
1010#include "cpu/z80/z80.h"
1111#include "includes/zx.h"
12#include "devices/cassette.h"
12#include "imagedev/cassette.h"
1313#include "sound/speaker.h"
1414#include "machine/ram.h"
1515
src/mess/machine/cbm.c
r9927r9928
11#include "emu.h"
2#include "devices/cassette.h"
2#include "imagedev/cassette.h"
33#include "crsshair.h"
44#include "includes/cbm.h"
55#include "formats/cbm_tap.h"
src/mess/machine/z80ne.c
r9927r9928
1919#include "machine/wd17xx.h"
2020
2121/* Devices */
22#include "devices/cassette.h"
23#include "devices/flopdrv.h"
22#include "imagedev/cassette.h"
23#include "imagedev/flopdrv.h"
2424
2525#define VERBOSE 0
2626#define LOG(x) do { if (VERBOSE) logerror x; } while (0)
src/mess/machine/apple2gs.c
r9927r9928
113113#include "machine/applefdc.h"
114114#include "devices/sonydriv.h"
115115#include "machine/8530scc.h"
116#include "devices/flopdrv.h"
116#include "imagedev/flopdrv.h"
117117#include "cpu/g65816/g65816.h"
118118#include "sound/es5503.h"
119119#include "machine/ram.h"
src/mess/machine/x68k_hdc.c
r9927r9928
1616*/
1717
1818#include "x68k_hdc.h"
19#include "devices/harddriv.h"
19#include "imagedev/harddriv.h"
2020#include "image.h"
2121
2222static TIMER_CALLBACK( req_delay )
src/mess/machine/i8271.c
r9927r9928
1414
1515#include "emu.h"
1616#include "i8271.h"
17#include "devices/flopdrv.h"
17#include "imagedev/flopdrv.h"
1818
1919/* data request */
2020#define I8271_FLAGS_DATA_REQUEST 0x01
src/mess/machine/ctronics.c
r9927r9928
66
77#include "emu.h"
88#include "ctronics.h"
9#include "devices/printer.h"
9#include "imagedev/printer.h"
1010
1111
1212/***************************************************************************
src/mess/machine/amigacd.c
r9927r9928
1515#include "machine/6525tpi.h"
1616#include "machine/6526cia.h"
1717#include "machine/wd33c93.h"
18#include "devices/chd_cd.h"
18#include "imagedev/chd_cd.h"
1919#include "matsucd.h"
2020
2121
src/mess/machine/nes.c
r9927r9928
55#include "video/ppu2c0x.h"
66#include "includes/nes.h"
77#include "machine/nes_mmc.h"
8#include "devices/cartslot.h"
9#include "devices/flopdrv.h"
8#include "imagedev/cartslot.h"
9#include "imagedev/flopdrv.h"
1010
1111/***************************************************************************
1212    CONSTANTS
src/mess/machine/concept.c
r9927r9928
1212#include "machine/wd17xx.h"
1313#include "cpu/m68000/m68000.h"
1414#include "includes/corvushd.h"
15#include "devices/flopdrv.h"
15#include "imagedev/flopdrv.h"
1616
1717
1818#define VERBOSE 1
src/mess/machine/msx.c
r9927r9928
1717#include "includes/msx.h"
1818#include "machine/tc8521.h"
1919#include "machine/wd17xx.h"
20#include "devices/flopdrv.h"
20#include "imagedev/flopdrv.h"
2121#include "formats/basicdsk.h"
2222#include "video/tms9928a.h"
2323#include "cpu/z80/z80.h"
2424#include "video/v9938.h"
2525#include "machine/ctronics.h"
26#include "devices/cassette.h"
26#include "imagedev/cassette.h"
2727#include "osdepend.h"
2828#include "sound/ay8910.h"
2929#include "sound/2413intf.h"
src/mess/machine/mz700.c
r9927r9928
1818#include "machine/74145.h"
1919#include "machine/ctronics.h"
2020#include "sound/speaker.h"
21#include "devices/cassette.h"
21#include "imagedev/cassette.h"
2222#include "machine/ram.h"
2323
2424#ifndef VERBOSE
src/mess/machine/dc.c
r9927r9928
2121#include "sound/aica.h"
2222#include "includes/naomi.h"
2323#include "machine/gdrom.h"
24#include "devices/chd_cd.h"
24#include "imagedev/chd_cd.h"
2525
2626#define ATAPI_CYCLES_PER_SECTOR (5000)   // TBD for Dreamcast
2727
src/mess/machine/lynx.c
r9927r9928
66#include "includes/lynx.h"
77#include "cpu/m6502/m6502.h"
88
9#include "devices/cartslot.h"
9#include "imagedev/cartslot.h"
1010#include "hash.h"
1111
1212
src/mess/machine/cgenie.c
r9927r9928
1111#include "cpu/z80/z80.h"
1212#include "includes/cgenie.h"
1313#include "machine/wd17xx.h"
14#include "devices/cartslot.h"
15#include "devices/cassette.h"
14#include "imagedev/cartslot.h"
15#include "imagedev/cassette.h"
1616#include "sound/ay8910.h"
1717#include "sound/dac.h"
18#include "devices/flopdrv.h"
18#include "imagedev/flopdrv.h"
1919#include "machine/ram.h"
2020
2121#define AYWriteReg(chip,port,value) \
src/mess/machine/ondra.c
r9927r9928
99
1010#include "emu.h"
1111#include "cpu/z80/z80.h"
12#include "devices/cassette.h"
12#include "imagedev/cassette.h"
1313#include "includes/ondra.h"
1414#include "machine/ram.h"
1515
src/mess/machine/kaypro.c
r9927r9928
22#include "emu.h"
33#include "cpu/z80/z80.h"
44#include "machine/ctronics.h"
5#include "devices/snapquik.h"
5#include "imagedev/snapquik.h"
66#include "includes/kaypro.h"
7#include "devices/flopdrv.h"
7#include "imagedev/flopdrv.h"
88
99
1010
src/mess/machine/super80.c
r9927r9928
33#include "emu.h"
44//#include "cpu/z80/z80.h"
55#include "sound/wave.h"
6#include "devices/cassette.h"
6#include "imagedev/cassette.h"
77#include "sound/speaker.h"
88#include "machine/ctronics.h"
99#include "includes/super80.h"
src/mess/machine/beta.c
r9927r9928
88
99*********************************************************************/
1010#include "emu.h"
11#include "devices/flopdrv.h"
11#include "imagedev/flopdrv.h"
1212#include "formats/trd_dsk.h"
1313#include "machine/wd17xx.h"
1414#include "machine/beta.h"
src/mess/machine/lviv.c
r9927r9928
1010***************************************************************************/
1111
1212#include "emu.h"
13#include "devices/cassette.h"
14#include "devices/snapquik.h"
13#include "imagedev/cassette.h"
14#include "imagedev/snapquik.h"
1515#include "cpu/i8085/i8085.h"
1616#include "machine/i8255a.h"
1717#include "includes/lviv.h"
src/mess/machine/abc830.c
r9927r9928
184184#include "cpu/z80/z80daisy.h"
185185#include "machine/wd17xx.h"
186186#include "machine/abcbus.h"
187#include "devices/flopdrv.h"
188#include "formats/flopimg.h"
187#include "imagedev/flopdrv.h"
188#include "imagedev/flopimg.h"
189189#include "formats/basicdsk.h"
190190
191191/***************************************************************************
src/mess/machine/exidy.c
r9927r9928
99#include "sound/dac.h"
1010#include "sound/wave.h"
1111#include "machine/ctronics.h"
12#include "devices/cassette.h"
13#include "devices/snapquik.h"
14#include "devices/cartslot.h"
12#include "imagedev/cassette.h"
13#include "imagedev/snapquik.h"
14#include "imagedev/cartslot.h"
1515#include "machine/ay31015.h"
1616#include "includes/exidy.h"
17#include "devices/flopdrv.h"
17#include "imagedev/flopdrv.h"
1818
1919
2020
src/mess/machine/abc830.h
r9927r9928
22#define __CONKORT__
33
44#include "emu.h"
5#include "formats/flopimg.h"
5#include "imagedev/flopimg.h"
66
77/***************************************************************************
88    MACROS / CONSTANTS
src/mess/machine/partner.c
r9927r9928
99
1010#include "emu.h"
1111#include "cpu/i8085/i8085.h"
12#include "devices/cassette.h"
12#include "imagedev/cassette.h"
1313#include "machine/i8255a.h"
1414#include "machine/i8257.h"
1515#include "machine/wd17xx.h"
1616#include "video/i8275.h"
1717#include "includes/radio86.h"
1818#include "includes/partner.h"
19#include "devices/flopdrv.h"
19#include "imagedev/flopdrv.h"
2020#include "machine/ram.h"
2121
2222
src/mess/machine/apple1.c
r9927r9928
4949#include "machine/6821pia.h"
5050#include "cpu/m6502/m6502.h"
5151#include "image.h"
52#include "devices/cassette.h"
52#include "imagedev/cassette.h"
5353#include "machine/ram.h"
5454
5555static TIMER_CALLBACK(apple1_kbd_poll);
src/mess/machine/mc6843.c
r9927r9928
3232
3333#include "emu.h"
3434#include "mc6843.h"
35#include "devices/flopdrv.h"
35#include "imagedev/flopdrv.h"
3636
3737
3838/******************* parameters ******************/
src/mess/machine/ibmpc.c
r9927r9928
11#include "emu.h"
22#include "memconv.h"
33#include "includes/ibmpc.h"
4#include "devices/cassette.h"
4#include "imagedev/cassette.h"
55#include "machine/pit8253.h"
66#include "machine/pcshare.h"
77#include "coreutil.h"
src/mess/machine/hec2hrp.c
r9927r9928
3737*/
3838
3939#include "emu.h"
40#include "devices/cassette.h"
41#include "devices/printer.h"
40#include "imagedev/cassette.h"
41#include "imagedev/printer.h"
4242#include "sound/sn76477.h"   /* for sn sound*/
4343#include "sound/wave.h"      /* for K7 sound*/
4444#include "sound/discrete.h"  /* for 1 Bit sound*/
src/mess/machine/mtx.c
r9927r9928
1010#include "imageutl.h"
1111#include "includes/mtx.h"
1212#include "cpu/z80/z80.h"
13#include "devices/cassette.h"
13#include "imagedev/cassette.h"
1414#include "machine/ram.h"
15#include "devices/snapquik.h"
15#include "imagedev/snapquik.h"
1616#include "machine/ctronics.h"
1717#include "machine/z80ctc.h"
1818#include "machine/z80dart.h"
src/mess/machine/special.c
r9927r9928
1111#include "emu.h"
1212#include "cpu/i8085/i8085.h"
1313#include "sound/dac.h"
14#include "devices/cassette.h"
14#include "imagedev/cassette.h"
1515#include "machine/i8255a.h"
1616#include "machine/pit8253.h"
1717#include "machine/wd17xx.h"
1818#include "includes/special.h"
1919#include "machine/ram.h"
20#include "devices/flopdrv.h"
20#include "imagedev/flopdrv.h"
2121
2222
2323
src/mess/machine/jupiter.c
r9927r9928
99
1010#include "emu.h"
1111#include "cpu/z80/z80.h"
12#include "devices/snapquik.h"
12#include "imagedev/snapquik.h"
1313#include "includes/jupiter.h"
1414
1515
src/mess/machine/mikro80.c
r9927r9928
99
1010#include "emu.h"
1111#include "cpu/i8085/i8085.h"
12#include "devices/cassette.h"
12#include "imagedev/cassette.h"
1313#include "machine/i8255a.h"
1414#include "includes/mikro80.h"
1515
src/mess/machine/rmnimbus.c
r9927r9928
5353#include "cpu/i86/i86.h"
5454#include "debug/debugcpu.h"
5555#include "debug/debugcon.h"
56#include "devices/flopdrv.h"
56#include "imagedev/flopdrv.h"
5757#include "machine/ram.h"
5858#include "machine/er59256.h"
5959#include "machine/pic8259.h"
src/mess/machine/mz80.c
r9927r9928
99#include "emu.h"
1010#include "machine/i8255a.h"
1111#include "machine/pit8253.h"
12#include "devices/cassette.h"
12#include "imagedev/cassette.h"
1313#include "sound/speaker.h"
1414#include "includes/mz80.h"
1515
src/mess/machine/c1571.c
r9927r9928
2121#include "emu.h"
2222#include "c1571.h"
2323#include "cpu/m6502/m6502.h"
24#include "devices/flopdrv.h"
24#include "imagedev/flopdrv.h"
2525#include "formats/d64_dsk.h"
2626#include "formats/g64_dsk.h"
2727#include "machine/6522via.h"
src/mess/machine/ut88.c
r9927r9928
1010#include "emu.h"
1111#include "cpu/i8085/i8085.h"
1212#include "sound/dac.h"
13#include "devices/cassette.h"
13#include "imagedev/cassette.h"
1414#include "machine/i8255a.h"
1515#include "includes/ut88.h"
1616
src/mess/machine/tf20.c
r9927r9928
1515#include "machine/ram.h"
1616#include "machine/upd7201.h"
1717#include "machine/upd765.h"
18#include "devices/flopdrv.h"
18#include "imagedev/flopdrv.h"
1919
2020
2121/***************************************************************************
src/mess/machine/snescart.c
r9927r9928
88
99#include "emu.h"
1010#include "includes/snes.h"
11#include "devices/cartslot.h"
11#include "imagedev/cartslot.h"
1212#include "snescart.h"
1313
1414#define SNES_CART_DEBUG 0
src/mess/machine/apple2.c
r9927r9928
1919#include "machine/applefdc.h"
2020#include "devices/sonydriv.h"
2121#include "devices/appldriv.h"
22#include "devices/flopdrv.h"
22#include "imagedev/flopdrv.h"
2323#include "image.h"
24#include "devices/cassette.h"
24#include "imagedev/cassette.h"
2525#include "machine/ram.h"
2626#include "sound/speaker.h"
2727#include "profiler.h"
src/mess/machine/snescart.h
r9927r9928
66#ifndef _SNESCART_H
77#define _SNESCART_H
88
9#include "devices/cartslot.h"
9#include "imagedev/cartslot.h"
1010
1111MACHINE_START( snes_mess );
1212MACHINE_START( snesst );
src/mess/machine/c64.c
r9927r9928
2525#include "includes/cbm.h"
2626#include "includes/c64.h"
2727
28#include "devices/cassette.h"
29#include "devices/cartslot.h"
28#include "imagedev/cassette.h"
29#include "imagedev/cartslot.h"
3030
3131#define VERBOSE_LEVEL 0
3232#define DBG_LOG( MACHINE, N, M, A ) \
src/mess/machine/genesis.c
r9927r9928
4848#include "imageutl.h"
4949#include "cpu/m68000/m68000.h"
5050
51#include "devices/cartslot.h"
51#include "imagedev/cartslot.h"
5252#include "includes/genesis.h"
5353#include "gen_pcb.h"
5454
src/mess/machine/pc.c
r9927r9928
3939#include "includes/europc.h"
4040#include "includes/ibmpc.h"
4141#include "machine/pcshare.h"
42#include "devices/cassette.h"
42#include "imagedev/cassette.h"
4343#include "sound/speaker.h"
4444
4545#include "machine/8237dma.h"
src/mess/machine/cdic.c
r9927r9928
2222
2323#include "cpu/m68000/m68000.h"
2424#include "sound/dmadac.h"
25#include "devices/chd_cd.h"
25#include "imagedev/chd_cd.h"
2626#include "machine/timekpr.h"
2727#include "sound/cdda.h"
2828
src/mess/machine/pecom.c
r9927r9928
99#include "emu.h"
1010#include "cpu/cosmac/cosmac.h"
1111#include "sound/cdp1869.h"
12#include "devices/cassette.h"
12#include "imagedev/cassette.h"
1313#include "includes/pecom.h"
1414#include "machine/ram.h"
1515
src/mess/machine/cdic.h
r9927r9928
11#ifndef _MACHINE_CDIC_H_
22#define _MACHINE_CDIC_H_
33
4#include "devices/chd_cd.h"
4#include "imagedev/chd_cd.h"
55
66namespace CDI
77{
src/mess/machine/pce.c
r9927r9928
5757#include "coreutil.h"
5858#include "cpu/h6280/h6280.h"
5959#include "includes/pce.h"
60#include "devices/chd_cd.h"
60#include "imagedev/chd_cd.h"
6161#include "sound/msm5205.h"
6262#include "sound/cdda.h"
6363
src/mess/machine/smc92x4.c
r9927r9928
1717
1818#include "emu.h"
1919#include "imageutl.h"
20#include "devices/flopdrv.h"
21#include "devices/harddriv.h"
20#include "imagedev/flopdrv.h"
21#include "imagedev/harddriv.h"
2222#include "harddisk.h"
2323
2424#include "smc92x4.h"
src/mess/machine/atarifdc.c
r9927r9928
1616#include "ataridev.h"
1717#include "sound/pokey.h"
1818#include "machine/6821pia.h"
19#include "devices/flopdrv.h"
19#include "imagedev/flopdrv.h"
2020#include "image.h"
2121
2222#define VERBOSE_SERIAL   0
src/mess/machine/pk8020.c
r9927r9928
1212#include "cpu/i8085/i8085.h"
1313#include "machine/wd17xx.h"
1414#include "machine/ram.h"
15#include "devices/flopdrv.h"
15#include "imagedev/flopdrv.h"
1616
1717static void pk8020_set_bank(running_machine *machine,UINT8 data);
1818
src/mess/machine/bbc.c
r9927r9928
1515#include "sound/tms5220.h"
1616#include "machine/6522via.h"
1717#include "machine/wd17xx.h"
18#include "devices/flopdrv.h"
18#include "imagedev/flopdrv.h"
1919#include "includes/bbc.h"
2020#include "machine/upd7002.h"
2121#include "machine/i8271.h"
2222#include "machine/mc146818.h"
2323#include "machine/ctronics.h"
24#include "devices/cassette.h"
24#include "imagedev/cassette.h"
2525
2626/* BBC Memory Size */
2727/* this stores the DIP switch setting for the DFS type being used */
src/mess/machine/kc.c
r9927r9928
1111#include "sound/speaker.h"
1212
1313/* Devices */
14#include "devices/cassette.h"
14#include "imagedev/cassette.h"
1515#include "machine/ram.h"
1616
1717#define KC_DEBUG 1
src/mess/includes/kc.h
r9927r9928
1010#include "cpu/z80/z80daisy.h"
1111#include "machine/z80ctc.h"
1212#include "machine/z80pio.h"
13#include "devices/snapquik.h"
13#include "imagedev/snapquik.h"
1414#include "machine/upd765.h"
1515
1616#define KC85_4_CLOCK 1750000
src/mess/includes/cbm.h
r9927r9928
77#ifndef CBM_H_
88#define CBM_H_
99
10#include "devices/cassette.h"
10#include "imagedev/cassette.h"
1111
1212
1313/* global header file for c16, c64, c65, c128, vc20 */
src/mess/includes/cbmb.h
r9927r9928
1313
1414#include "video/mc6845.h"
1515#include "machine/6526cia.h"
16#include "devices/cartslot.h"
16#include "imagedev/cartslot.h"
1717
1818class cbmb_state : public driver_device
1919{
src/mess/includes/mbee.h
r9927r9928
88#define MBEE_H_
99
1010#include "machine/wd17xx.h"
11#include "devices/snapquik.h"
12#include "devices/z80bin.h"
11#include "imagedev/snapquik.h"
1312#include "machine/z80pio.h"
14#include "devices/cassette.h"
13#include "imagedev/cassette.h"
1514#include "machine/ctronics.h"
1615#include "machine/mc146818.h"
1716#include "video/mc6845.h"
src/mess/includes/coco.h
r9927r9928
99#ifndef __COCO_H__
1010#define __COCO_H__
1111
12#include "devices/snapquik.h"
12#include "imagedev/snapquik.h"
1313#include "machine/wd17xx.h"
1414#include "machine/6883sam.h"
1515#include "machine/6821pia.h"
src/mess/includes/msx.h
r9927r9928
88#define __MSX_H__
99
1010#include "machine/wd17xx.h"
11#include "formats/flopimg.h"
11#include "imagedev/flopimg.h"
1212
1313#define MSX_MAX_CARTS   (2)
1414
src/mess/includes/thomson.h
r9927r9928
1818#include "sound/dac.h"
1919#include "audio/mea8000.h"
2020#include "machine/ctronics.h"
21#include "devices/cartslot.h"
21#include "imagedev/cartslot.h"
2222#include "machine/serial.h"
23#include "devices/cassette.h"
23#include "imagedev/cassette.h"
2424#include "machine/mc6843.h"
2525#include "machine/mc6846.h"
2626#include "machine/mc6854.h"
src/mess/includes/lynx.h
r9927r9928
77#ifndef LYNX_H_
88#define LYNX_H_
99
10#include "devices/cartslot.h"
10#include "imagedev/cartslot.h"
1111
1212
1313#define LYNX_CART      0
src/mess/includes/spectrum.h
r9927r9928
77#ifndef __SPECTRUM_H__
88#define __SPECTRUM_H__
99
10#include "devices/snapquik.h"
11#include "devices/cartslot.h"
10#include "imagedev/snapquik.h"
11#include "imagedev/cartslot.h"
1212
1313/* Spectrum crystals */
1414
src/mess/includes/kaypro.h
r9927r9928
44#include "machine/z80pio.h"
55#include "machine/z80sio.h"
66#include "machine/wd17xx.h"
7#include "devices/snapquik.h"
7#include "imagedev/snapquik.h"
88
99
1010class kaypro_state : public driver_device
src/mess/includes/lviv.h
r9927r9928
77#ifndef LVIV_H_
88#define LVIV_H_
99
10#include "devices/snapquik.h"
10#include "imagedev/snapquik.h"
1111#include "machine/i8255a.h"
1212
1313class lviv_state : public driver_device
src/mess/includes/exidy.h
r9927r9928
77#ifndef EXIDY_H_
88#define EXIDY_H_
99
10#include "devices/z80bin.h"
10#include "imagedev/snapquik.h"
1111
1212typedef struct {
1313   struct {
src/mess/includes/pet.h
r9927r9928
1010#include "video/mc6845.h"
1111#include "machine/6821pia.h"
1212#include "machine/6522via.h"
13#include "devices/cartslot.h"
13#include "imagedev/cartslot.h"
1414
1515typedef struct
1616{
src/mess/includes/v1050.h
r9927r9928
11#ifndef __V1050__
22#define __V1050__
33
4#include "devices/flopdrv.h"
4#include "imagedev/flopdrv.h"
55#include "machine/ram.h"
66
77#define SCREEN_TAG            "screen"
src/mess/includes/apple1.h
r9927r9928
77#ifndef APPLE1_H_
88#define APPLE1_H_
99
10#include "devices/snapquik.h"
10#include "imagedev/snapquik.h"
1111#include "machine/6821pia.h"
1212
1313typedef short termchar_t;
src/mess/includes/nascom1.h
r9927r9928
77#ifndef NASCOM1_H_
88#define NASCOM1_H_
99
10#include "devices/snapquik.h"
10#include "imagedev/snapquik.h"
1111#include "machine/wd17xx.h"
1212
1313typedef struct
src/mess/includes/mtx.h
r9927r9928
77#ifndef __MTX__
88#define __MTX__
99
10#include "devices/snapquik.h"
10#include "imagedev/snapquik.h"
1111
1212#define Z80_TAG         "z80"
1313#define Z80CTC_TAG      "z80ctc"
src/mess/includes/microtan.h
r9927r9928
1515#ifndef MICROTAN_H_
1616#define MICROTAN_H_
1717
18#include "devices/snapquik.h"
18#include "imagedev/snapquik.h"
1919#include "machine/6522via.h"
2020
2121
src/mess/includes/amstrad.h
r9927r9928
99
1010#include "machine/upd765.h"
1111#include "video/mc6845.h"
12#include "devices/snapquik.h"
12#include "imagedev/snapquik.h"
1313
1414/****************************
1515 * Gate Array data (CPC) -
src/mess/includes/poly88.h
r9927r9928
99
1010#include "machine/serial.h"
1111#include "machine/msm8251.h"
12#include "devices/snapquik.h"
12#include "imagedev/snapquik.h"
1313
1414class poly88_state : public driver_device
1515{
src/mess/includes/comx35.h
r9927r9928
44#include "cpu/cosmac/cosmac.h"
55#include "sound/cdp1869.h"
66#include "machine/cdp1871.h"
7#include "devices/snapquik.h"
7#include "imagedev/snapquik.h"
88#include "machine/wd17xx.h"
99#include "machine/ram.h"
1010
src/mess/includes/z1013.h
r9927r9928
88#define Z1013_H_
99
1010#include "machine/z80pio.h"
11#include "devices/snapquik.h"
11#include "imagedev/snapquik.h"
1212
1313
1414class z1013_state : public driver_device
src/mess/includes/trs80.h
r9927r9928
77#ifndef TRS80_H_
88#define TRS80_H_
99
10#include "devices/snapquik.h"
10#include "imagedev/snapquik.h"
1111#include "machine/wd17xx.h"
1212
1313#define FW 6
src/mess/includes/primo.h
r9927r9928
77#ifndef PRIMO_H_
88#define PRIMO_H_
99
10#include "devices/snapquik.h"
10#include "imagedev/snapquik.h"
1111
1212
1313class primo_state : public driver_device
src/mess/includes/ti85.h
r9927r9928
77#ifndef TI85_H_
88#define TI85_H_
99
10#include "devices/snapquik.h"
10#include "imagedev/snapquik.h"
1111
1212
1313class ti85_state : public driver_device
src/mess/includes/c64.h
r9927r9928
1414#define C64_H_
1515
1616#include "machine/6526cia.h"
17#include "devices/cartslot.h"
17#include "imagedev/cartslot.h"
1818
1919#define C64_MAX_ROMBANK 64 // .crt files contain multiple 'CHIPs', i.e. rom banks (of variable size) with headers. Known carts have at most 64 'CHIPs'.
2020
src/mess/includes/genesis.h
r9927r9928
77#ifndef GENESIS_H_
88#define GENESIS_H_
99
10#include "devices/cartslot.h"
10#include "imagedev/cartslot.h"
1111
1212/*----------- defined in machine/genesis.c -----------*/
1313
src/mess/includes/pk8020.h
r9927r9928
1111#include "machine/pit8253.h"
1212#include "machine/pic8259.h"
1313#include "machine/msm8251.h"
14#include "devices/cassette.h"
14#include "imagedev/cassette.h"
1515#include "sound/speaker.h"
1616#include "sound/wave.h"
1717
src/mess/includes/galaxy.h
r9927r9928
77#ifndef GALAXY_H_
88#define GALAXY_H_
99
10#include "devices/snapquik.h"
10#include "imagedev/snapquik.h"
1111
1212
1313class galaxy_state : public driver_device
src/mess/formats/flopimg.c
r9927r9928
1/*********************************************************************
2
3    flopimg.c
4
5    Floppy disk image abstraction code
6
7*********************************************************************/
8
9#include <stdlib.h>
10#include <string.h>
11#include <stdio.h>
12#include <ctype.h>
13#include <assert.h>
14#include <limits.h>
15
16#include "osdepend.h"
17#include "formats/flopimg.h"
18#include "pool.h"
19#include "imageutl.h"
20
21#define TRACK_LOADED      0x01
22#define TRACK_DIRTY         0x02
23
24
25struct _floppy_image
26{
27   struct io_generic io;
28
29   const struct FloppyFormat *floppy_option;
30   struct FloppyCallbacks format;
31
32   /* loaded track stuff */
33   int loaded_track_head;
34   int loaded_track_index;
35   UINT32 loaded_track_size;
36   void *loaded_track_data;
37   UINT8 loaded_track_status;
38   UINT8 flags;
39
40   /* tagging system */
41   object_pool *tags;
42   void *tag_data;
43};
44
45
46
47struct _floppy_params
48{
49   int param;
50   int value;
51};
52
53
54
55static floperr_t floppy_track_unload(floppy_image *floppy);
56
57OPTION_GUIDE_START(floppy_option_guide)
58   OPTION_INT('H', "heads",         "Heads")
59   OPTION_INT('T', "tracks",         "Tracks")
60   OPTION_INT('S', "sectors",         "Sectors")
61   OPTION_INT('L', "sectorlength",      "Sector Bytes")
62   OPTION_INT('I', "interleave",      "Interleave")
63   OPTION_INT('F', "firstsectorid",   "First Sector")
64OPTION_GUIDE_END
65
66
67static void floppy_close_internal(floppy_image *floppy, int close_file);
68
69/*********************************************************************
70    opening, closing and creating of floppy images
71*********************************************************************/
72
73/* basic floppy_image initialization common to floppy_open() and floppy_create() */
74static floppy_image *floppy_init(void *fp, const struct io_procs *procs, int flags)
75{
76   floppy_image *floppy;
77
78   floppy = (floppy_image *)malloc(sizeof(struct _floppy_image));
79   if (!floppy)
80      return NULL;
81
82   memset(floppy, 0, sizeof(*floppy));
83   floppy->tags = pool_alloc_lib(NULL);
84   floppy->tag_data = NULL;
85   floppy->io.file = fp;
86   floppy->io.procs = procs;
87   floppy->io.filler = 0xFF;
88   floppy->flags = (UINT8) flags;
89   return floppy;
90}
91
92
93
94/* main code for identifying and maybe opening a disk image; not exposed
95 * directly because this function is big and hideous */
96static floperr_t floppy_open_internal(void *fp, const struct io_procs *procs, const char *extension,
97   const struct FloppyFormat *floppy_options, int max_options, int flags, floppy_image **outfloppy,
98   int *outoption)
99{
100   floperr_t err;
101   floppy_image *floppy;
102   int best_option = -1;
103   int best_vote = 0;
104   int vote;
105   size_t i;
106
107   floppy = floppy_init(fp, procs, flags);
108   if (!floppy)
109   {
110      err = FLOPPY_ERROR_OUTOFMEMORY;
111      goto done;
112   }
113
114   /* vote on the best format */
115   for (i = 0; (i < max_options) && floppy_options[i].construct; i++)
116   {
117      if (!extension || !floppy_options[i].extensions || image_find_extension(floppy_options[i].extensions, extension))
118      {
119         if (floppy_options[i].identify)
120         {
121            vote = 0;
122            err = floppy_options[i].identify(floppy, &floppy_options[i], &vote);
123            if (err)
124               goto done;
125         }
126         else
127         {
128            vote = 1;
129         }
130
131         /* is this option a better one? */
132         if (vote > best_vote)
133         {
134            best_vote = vote;
135            best_option = i;
136         }
137      }
138   }
139
140   /* did we find a format? */
141   if (best_option == -1)
142   {
143      err = FLOPPY_ERROR_INVALIDIMAGE;
144      goto done;
145   }
146
147   if (outfloppy)
148   {
149      /* call the format constructor */
150      err = floppy_options[best_option].construct(floppy, &floppy_options[best_option], NULL);
151      if (err)
152         goto done;
153
154      floppy->floppy_option = &floppy_options[best_option];
155   }
156
157   err = FLOPPY_ERROR_SUCCESS;
158
159done:
160   /* if we have a floppy disk and we either errored or are not keeping it, close it */
161   if (floppy && (!outfloppy || err))
162   {
163      floppy_close_internal(floppy, FALSE);
164      floppy = NULL;
165   }
166
167   if (outoption)
168      *outoption = err ? -1 : best_option;
169   if (outfloppy)
170      *outfloppy = floppy;
171   return err;
172}
173
174
175
176floperr_t floppy_identify(void *fp, const struct io_procs *procs, const char *extension,
177   const struct FloppyFormat *formats, int *identified_format)
178{
179   return floppy_open_internal(fp, procs, extension, formats, INT_MAX, FLOPPY_FLAGS_READONLY, NULL, identified_format);
180}
181
182
183
184floperr_t floppy_open(void *fp, const struct io_procs *procs, const char *extension,
185   const struct FloppyFormat *format, int flags, floppy_image **outfloppy)
186{
187   return floppy_open_internal(fp, procs, extension, format, 1, flags, outfloppy, NULL);
188}
189
190
191
192floperr_t floppy_open_choices(void *fp, const struct io_procs *procs, const char *extension,
193   const struct FloppyFormat *formats, int flags, floppy_image **outfloppy)
194{
195   return floppy_open_internal(fp, procs, extension, formats, INT_MAX, flags, outfloppy, NULL);
196}
197
198
199
200static floperr_t option_to_floppy_error(optreserr_t oerr)
201{
202   floperr_t err;
203   switch(oerr) {
204   case OPTIONRESOLUTION_ERROR_SUCCESS:
205      err = FLOPPY_ERROR_SUCCESS;
206      break;
207   case OPTIONRESOLUTION_ERROR_OUTOFMEMORY:
208      err = FLOPPY_ERROR_OUTOFMEMORY;
209      break;
210   case OPTIONRESOLUTION_ERROR_PARAMOUTOFRANGE:
211   case OPTIONRESOLUTION_ERROR_PARAMNOTSPECIFIED:
212   case OPTIONRESOLUTION_ERROR_PARAMNOTFOUND:
213   case OPTIONRESOLUTION_ERROR_PARAMALREADYSPECIFIED:
214   case OPTIONRESOLUTION_ERROR_BADPARAM:
215   case OPTIONRESOLUTION_ERROR_SYNTAX:
216   default:
217      err = FLOPPY_ERROR_INTERNAL;
218      break;
219   };
220   return err;
221}
222
223
224
225floperr_t floppy_create(void *fp, const struct io_procs *procs, const struct FloppyFormat *format, option_resolution *parameters, floppy_image **outfloppy)
226{
227   floppy_image *floppy = NULL;
228   optreserr_t oerr;
229   floperr_t err;
230   int heads, tracks, h, t;
231   option_resolution *alloc_resolution = NULL;
232
233   assert(format);
234
235   /* create the new image */
236   floppy = floppy_init(fp, procs, 0);
237   if (!floppy)
238   {
239      err = FLOPPY_ERROR_OUTOFMEMORY;
240      goto done;
241   }
242
243   /* if this format expects creation parameters and none were specified, create some */
244   if (!parameters && format->param_guidelines)
245   {
246      alloc_resolution = option_resolution_create(floppy_option_guide, format->param_guidelines);
247      if (!alloc_resolution)
248      {
249         err = FLOPPY_ERROR_OUTOFMEMORY;
250         goto done;
251      }
252      parameters = alloc_resolution;
253   }
254
255   /* finish the parameters, if specified */
256   if (parameters)
257   {
258      oerr = option_resolution_finish(parameters);
259      if (oerr)
260      {
261         err = option_to_floppy_error(oerr);
262         goto done;
263      }
264   }
265
266   /* call the format constructor */
267   err = format->construct(floppy, format, parameters);
268   if (err)
269      goto done;
270
271   /* format the disk, ignoring if formatting not implemented */
272   if (floppy->format.format_track)
273   {
274      heads = floppy_get_heads_per_disk(floppy);
275      tracks = floppy_get_tracks_per_disk(floppy);
276
277      for (h = 0; h < heads; h++)
278      {
279         for (t = 0; t < tracks; t++)
280         {
281            err = floppy->format.format_track(floppy, h, t, parameters);
282            if (err)
283               goto done;
284         }
285      }
286   }
287
288   /* call the post_format function, if present */
289   if (floppy->format.post_format)
290   {
291      err = floppy->format.post_format(floppy, parameters);
292      if (err)
293         goto done;
294   }
295
296   floppy->floppy_option = format;
297   err = FLOPPY_ERROR_SUCCESS;
298
299done:
300   if (err && floppy)
301   {
302      floppy_close_internal(floppy, FALSE);
303      floppy = NULL;
304   }
305
306   if (outfloppy)
307      *outfloppy = floppy;
308   else if (floppy)
309      floppy_close_internal(floppy, FALSE);
310
311   if (alloc_resolution)
312      option_resolution_close(alloc_resolution);
313   return err;
314}
315
316
317
318static void floppy_close_internal(floppy_image *floppy, int close_file)
319{
320   if (floppy) {
321      floppy_track_unload(floppy);
322      if (close_file)
323         io_generic_close(&floppy->io);
324      if (floppy->loaded_track_data)
325         free(floppy->loaded_track_data);
326      pool_free_lib(floppy->tags);
327
328      free(floppy);
329   }
330}
331
332
333
334void floppy_close(floppy_image *floppy)
335{
336   floppy_close_internal(floppy, TRUE);
337}
338
339
340
341/*********************************************************************
342    functions useful in format constructors
343*********************************************************************/
344
345struct FloppyCallbacks *floppy_callbacks(floppy_image *floppy)
346{
347   assert(floppy);
348   return &floppy->format;
349}
350
351
352
353void *floppy_tag(floppy_image *floppy)
354{
355   assert(floppy);
356   return floppy->tag_data;
357}
358
359
360
361void *floppy_create_tag(floppy_image *floppy, size_t tagsize)
362{
363   floppy->tag_data = pool_malloc_lib(floppy->tags,tagsize);
364   return floppy->tag_data;
365}
366
367
368
369UINT8 floppy_get_filler(floppy_image *floppy)
370{
371   return floppy->io.filler;
372}
373
374
375
376void floppy_set_filler(floppy_image *floppy, UINT8 filler)
377{
378   floppy->io.filler = filler;
379}
380
381
382
383/*********************************************************************
384    calls for accessing the raw disk image
385*********************************************************************/
386
387void floppy_image_read(floppy_image *floppy, void *buffer, UINT64 offset, size_t length)
388{
389   io_generic_read(&floppy->io, buffer, offset, length);
390}
391
392
393
394void floppy_image_write(floppy_image *floppy, const void *buffer, UINT64 offset, size_t length)
395{
396   io_generic_write(&floppy->io, buffer, offset, length);
397}
398
399
400
401void floppy_image_write_filler(floppy_image *floppy, UINT8 filler, UINT64 offset, size_t length)
402{
403   io_generic_write_filler(&floppy->io, filler, offset, length);
404}
405
406
407
408UINT64 floppy_image_size(floppy_image *floppy)
409{
410   return io_generic_size(&floppy->io);
411}
412
413
414
415/*********************************************************************
416    calls for accessing disk image data
417*********************************************************************/
418
419static floperr_t floppy_readwrite_sector(floppy_image *floppy, int head, int track, int sector, int offset,
420   void *buffer, size_t buffer_len, int writing, int indexed, int ddam)
421{
422   floperr_t err;
423   const struct FloppyCallbacks *fmt;
424   size_t this_buffer_len;
425   UINT8 *alloc_buf = NULL;
426   UINT32 sector_length;
427   UINT8 *buffer_ptr = (UINT8 *)buffer;
428   floperr_t (*read_sector)(floppy_image *floppy, int head, int track, int sector, void *buffer, size_t buflen);
429   floperr_t (*write_sector)(floppy_image *floppy, int head, int track, int sector, const void *buffer, size_t buflen, int ddam);
430
431   fmt = floppy_callbacks(floppy);
432
433   /* choose proper calls for indexed vs non-indexed */
434   if (indexed)
435   {
436      read_sector = fmt->read_indexed_sector;
437      write_sector = fmt->write_indexed_sector;
438      if (!fmt->get_indexed_sector_info)
439      {
440         err = FLOPPY_ERROR_UNSUPPORTED;
441         goto done;
442      }
443   }
444   else
445   {
446      read_sector = fmt->read_sector;
447      write_sector = fmt->write_sector;
448      if (!fmt->get_sector_length)
449      {
450         err = FLOPPY_ERROR_UNSUPPORTED;
451         goto done;
452      }
453   }
454
455   /* check to make sure that the operation is supported */
456   if (!read_sector || (writing && !write_sector))
457   {
458      err = FLOPPY_ERROR_UNSUPPORTED;
459      goto done;
460   }
461
462   /* main loop */
463   while(buffer_len > 0)
464   {
465      /* find out the size of this sector */
466      if (indexed)
467         err = fmt->get_indexed_sector_info(floppy, head, track, sector, NULL, NULL, NULL, &sector_length, NULL);
468      else
469         err = fmt->get_sector_length(floppy, head, track, sector, &sector_length);
470      if (err)
471         goto done;
472
473      /* do we even do anything with this sector? */
474      if (offset < sector_length)
475      {
476         /* ok we will be doing something */
477         if ((offset > 0) || (buffer_len < sector_length))
478         {
479            /* we will be doing an partial read/write; in other words we
480                 * will not be reading/writing a full sector */
481            if (alloc_buf) free(alloc_buf);
482            alloc_buf = (UINT8*)malloc(sector_length);
483            if (!alloc_buf)
484            {
485               err = FLOPPY_ERROR_OUTOFMEMORY;
486               goto done;
487            }
488
489            /* read the sector (we need to do this even when writing */
490            err = read_sector(floppy, head, track, sector, alloc_buf, sector_length);
491            if (err)
492               goto done;
493
494            this_buffer_len = MIN(buffer_len, sector_length - offset);
495
496            if (writing)
497            {
498               memcpy(alloc_buf + offset, buffer_ptr, this_buffer_len);
499
500               err = write_sector(floppy, head, track, sector, alloc_buf, sector_length, ddam);
501               if (err)
502                  goto done;
503            }
504            else
505            {
506               memcpy(buffer_ptr, alloc_buf + offset, this_buffer_len);
507            }
508            offset += this_buffer_len;
509            offset %= sector_length;
510         }
511         else
512         {
513            this_buffer_len = sector_length;
514
515            if (writing)
516               err = write_sector(floppy, head, track, sector, buffer_ptr, sector_length, ddam);
517            else
518               err = read_sector(floppy, head, track, sector, buffer_ptr, sector_length);
519            if (err)
520               goto done;
521         }
522      }
523      else
524      {
525         /* skip this sector */
526         offset -= sector_length;
527         this_buffer_len = 0;
528      }
529
530      buffer_ptr += this_buffer_len;
531      buffer_len -= this_buffer_len;
532      sector++;
533   }
534
535   err = FLOPPY_ERROR_SUCCESS;
536
537done:
538   if (alloc_buf)
539      free(alloc_buf);
540   return err;
541}
542
543
544
545floperr_t floppy_read_sector(floppy_image *floppy, int head, int track, int sector, int offset,   void *buffer, size_t buffer_len)
546{
547   return floppy_readwrite_sector(floppy, head, track, sector, offset, buffer, buffer_len, FALSE, FALSE, 0);
548}
549
550
551
552floperr_t floppy_write_sector(floppy_image *floppy, int head, int track, int sector, int offset, const void *buffer, size_t buffer_len, int ddam)
553{
554   return floppy_readwrite_sector(floppy, head, track, sector, offset, (void *) buffer, buffer_len, TRUE, FALSE, ddam);
555}
556
557
558
559floperr_t floppy_read_indexed_sector(floppy_image *floppy, int head, int track, int sector_index, int offset,   void *buffer, size_t buffer_len)
560{
561   return floppy_readwrite_sector(floppy, head, track, sector_index, offset, buffer, buffer_len, FALSE, TRUE, 0);
562}
563
564
565
566floperr_t floppy_write_indexed_sector(floppy_image *floppy, int head, int track, int sector_index, int offset, const void *buffer, size_t buffer_len, int ddam)
567{
568   return floppy_readwrite_sector(floppy, head, track, sector_index, offset, (void *) buffer, buffer_len, TRUE, TRUE, ddam);
569}
570
571
572static floperr_t floppy_get_track_data_offset(floppy_image *floppy, int head, int track, UINT64 *offset)
573{
574   floperr_t err;
575   const struct FloppyCallbacks *callbacks;
576
577   *offset = 0;
578   callbacks = floppy_callbacks(floppy);
579   if (callbacks->get_track_data_offset)
580   {
581      err = callbacks->get_track_data_offset(floppy, head, track, offset);
582      if (err)
583         return err;
584   }
585   return FLOPPY_ERROR_SUCCESS;
586}
587
588
589
590static floperr_t floppy_read_track_offset(floppy_image *floppy, int head, int track, UINT64 offset, void *buffer, size_t buffer_len)
591{
592   floperr_t err;
593   const struct FloppyCallbacks *format;
594
595   format = floppy_callbacks(floppy);
596
597   if (!format->read_track)
598      return FLOPPY_ERROR_UNSUPPORTED;
599
600   err = floppy_track_unload(floppy);
601   if (err)
602      return err;
603
604   err = format->read_track(floppy, head, track, offset, buffer, buffer_len);
605   if (err)
606      return err;
607
608   return FLOPPY_ERROR_SUCCESS;
609}
610
611
612
613floperr_t floppy_read_track(floppy_image *floppy, int head, int track, void *buffer, size_t buffer_len)
614{
615   return floppy_read_track_offset(floppy, head, track, 0, buffer, buffer_len);
616}
617
618
619
620floperr_t floppy_read_track_data(floppy_image *floppy, int head, int track, void *buffer, size_t buffer_len)
621{
622   floperr_t err;
623   UINT64 offset;
624
625   err = floppy_get_track_data_offset(floppy, head, track, &offset);
626   if (err)
627      return err;
628
629   return floppy_read_track_offset(floppy, head, track, offset, buffer, buffer_len);
630}
631
632
633
634static floperr_t floppy_write_track_offset(floppy_image *floppy, int head, int track, UINT64 offset, const void *buffer, size_t buffer_len)
635{
636   floperr_t err;
637
638   /* track writing supported? */
639   if (!floppy_callbacks(floppy)->write_track)
640      return FLOPPY_ERROR_UNSUPPORTED;
641
642   /* read only? */
643   if (floppy->flags & FLOPPY_FLAGS_READONLY)
644      return FLOPPY_ERROR_READONLY;
645
646   err = floppy_track_unload(floppy);
647   if (err)
648      return err;
649
650   err = floppy_callbacks(floppy)->write_track(floppy, head, track, offset, buffer, buffer_len);
651   if (err)
652      return err;
653
654   return FLOPPY_ERROR_SUCCESS;
655}
656
657
658
659floperr_t floppy_write_track(floppy_image *floppy, int head, int track, const void *buffer, size_t buffer_len)
660{
661   return floppy_write_track_offset(floppy, head, track, 0, buffer, buffer_len);
662}
663
664
665
666floperr_t floppy_write_track_data(floppy_image *floppy, int head, int track, const void *buffer, size_t buffer_len)
667{
668   floperr_t err;
669   UINT64 offset;
670
671   err = floppy_get_track_data_offset(floppy, head, track, &offset);
672   if (err)
673      return err;
674
675   return floppy_write_track_offset(floppy, head, track, offset, buffer, buffer_len);
676}
677
678
679
680floperr_t floppy_format_track(floppy_image *floppy, int head, int track, option_resolution *parameters)
681{
682   floperr_t err;
683   struct FloppyCallbacks *format;
684   option_resolution *alloc_resolution = NULL;
685   optreserr_t oerr;
686
687   /* supported? */
688   format = floppy_callbacks(floppy);
689   if (!format->format_track)
690   {
691      err = FLOPPY_ERROR_UNSUPPORTED;
692      goto done;
693   }
694
695   /* create a dummy resolution; if no parameters were specified */
696   if (!parameters)
697   {
698      alloc_resolution = option_resolution_create(floppy_option_guide, floppy->floppy_option->param_guidelines);
699      if (!alloc_resolution)
700      {
701         err = FLOPPY_ERROR_OUTOFMEMORY;
702         goto done;
703      }
704      parameters = alloc_resolution;
705   }
706
707   oerr = option_resolution_finish(parameters);
708   if (oerr)
709   {
710      err = option_to_floppy_error(oerr);
711      goto done;
712   }
713
714   err = format->format_track(floppy, head, track, parameters);
715   if (err)
716      goto done;
717
718done:
719   if (alloc_resolution)
720      option_resolution_close(alloc_resolution);
721   return err;
722}
723
724
725
726int floppy_get_tracks_per_disk(floppy_image *floppy)
727{
728   return floppy_callbacks(floppy)->get_tracks_per_disk(floppy);
729}
730
731
732
733int floppy_get_heads_per_disk(floppy_image *floppy)
734{
735   return floppy_callbacks(floppy)->get_heads_per_disk(floppy);
736}
737
738
739
740UINT32 floppy_get_track_size(floppy_image *floppy, int head, int track)
741{
742   const struct FloppyCallbacks *fmt;
743
744   fmt = floppy_callbacks(floppy);
745   if (!fmt->get_track_size)
746      return 0;
747
748   return fmt->get_track_size(floppy, head, track);
749}
750
751
752
753floperr_t floppy_get_sector_length(floppy_image *floppy, int head, int track, int sector, UINT32 *sector_length)
754{
755   const struct FloppyCallbacks *fmt;
756
757   fmt = floppy_callbacks(floppy);
758   if (!fmt->get_sector_length)
759      return FLOPPY_ERROR_UNSUPPORTED;
760
761   return fmt->get_sector_length(floppy, head, track, sector, sector_length);
762}
763
764
765
766floperr_t floppy_get_indexed_sector_info(floppy_image *floppy, int head, int track, int sector_index, int *cylinder, int *side, int *sector, UINT32 *sector_length, unsigned long *flags)
767{
768   const struct FloppyCallbacks *fmt;
769
770   fmt = floppy_callbacks(floppy);
771   if (!fmt->get_indexed_sector_info)
772      return FLOPPY_ERROR_UNSUPPORTED;
773
774   return fmt->get_indexed_sector_info(floppy, head, track, sector_index, cylinder, side, sector, sector_length, flags);
775}
776
777
778
779floperr_t floppy_get_sector_count(floppy_image *floppy, int head, int track, int *sector_count)
780{
781   floperr_t err;
782   int sector_index = 0;
783
784   do
785   {
786      err = floppy_get_indexed_sector_info(floppy, head, track, sector_index, NULL, NULL, NULL, NULL, NULL);
787      if (!err)
788         sector_index++;
789   }
790   while(!err);
791
792   if (sector_index && (err == FLOPPY_ERROR_SEEKERROR))
793      err = FLOPPY_ERROR_SUCCESS;
794   if (sector_count)
795      *sector_count = err ? 0 : sector_index;
796   return err;
797}
798
799
800
801int floppy_is_read_only(floppy_image *floppy)
802{
803   return floppy->flags & FLOPPY_FLAGS_READONLY;
804}
805
806
807
808UINT8 floppy_random_byte(floppy_image *floppy)
809{
810   /* can't use mame_rand(); this might not be in the core */
811#ifdef rand
812#undef rand
813#endif
814   return rand();
815}
816
817
818
819/*********************************************************************
820    calls for track based IO
821*********************************************************************/
822
823floperr_t floppy_load_track(floppy_image *floppy, int head, int track, int dirtify, void **track_data, size_t *track_length)
824{
825   floperr_t err;
826   void *new_loaded_track_data;
827   UINT32 track_size;
828
829   /* have we already loaded this track? */
830   if (((floppy->loaded_track_status & TRACK_LOADED) == 0) || (head != floppy->loaded_track_head) || (track != floppy->loaded_track_index))
831   {
832      err = floppy_track_unload(floppy);
833      if (err)
834         goto error;
835
836      track_size = floppy_callbacks(floppy)->get_track_size(floppy, head, track);
837
838      if (floppy->loaded_track_data) free(floppy->loaded_track_data);
839      new_loaded_track_data = malloc(track_size);
840      if (!new_loaded_track_data)
841      {
842         err = FLOPPY_ERROR_OUTOFMEMORY;
843         goto error;
844      }
845
846      floppy->loaded_track_data = new_loaded_track_data;
847      floppy->loaded_track_size = track_size;
848      floppy->loaded_track_head = head;
849      floppy->loaded_track_index = track;
850
851      err = floppy_callbacks(floppy)->read_track(floppy, floppy->loaded_track_head, floppy->loaded_track_index, 0, floppy->loaded_track_data, floppy->loaded_track_size);
852      if (err)
853         goto error;
854
855      floppy->loaded_track_status |= TRACK_LOADED | (dirtify ? TRACK_DIRTY : 0);
856   }
857   else
858      floppy->loaded_track_status |= (dirtify ? TRACK_DIRTY : 0);
859
860   if (track_data)
861      *track_data = floppy->loaded_track_data;
862   if (track_length)
863      *track_length = floppy->loaded_track_size;
864   return FLOPPY_ERROR_SUCCESS;
865
866error:
867   if (track_data)
868      *track_data = NULL;
869   if (track_length)
870      *track_length = 0;
871   return err;
872}
873
874
875
876static floperr_t floppy_track_unload(floppy_image *floppy)
877{
878   int err;
879   if (floppy->loaded_track_status & TRACK_DIRTY)
880   {
881      err = floppy_callbacks(floppy)->write_track(floppy, floppy->loaded_track_head, floppy->loaded_track_index, 0, floppy->loaded_track_data, floppy->loaded_track_size);
882      if (err)
883         return (floperr_t)err;
884   }
885
886   floppy->loaded_track_status &= ~(TRACK_LOADED | TRACK_DIRTY);
887   return FLOPPY_ERROR_SUCCESS;
888}
889
890
891
892/*********************************************************************
893    accessors for meta information about the image
894*********************************************************************/
895
896const char *floppy_format_description(floppy_image *floppy)
897{
898   return floppy->floppy_option->description;
899}
900
901
902
903/*********************************************************************
904    misc calls
905*********************************************************************/
906
907const char *floppy_error(floperr_t err)
908{
909   static const char *const error_messages[] =
910   {
911      "The operation completed successfully",
912      "Fatal internal error",
913      "This operation is unsupported",
914      "Out of memory",
915      "Seek error",
916      "Invalid image",
917      "Attempted to write to read only image",
918      "No space left on image",
919      "Parameter out of range",
920      "Required parameter not specified"
921   };
922
923   if ((err < 0) || (err >= ARRAY_LENGTH(error_messages)))
924      return NULL;
925   return error_messages[err];
926}
927
928
929FLOPPY_OPTIONS_START(default)
930FLOPPY_OPTIONS_END
src/mess/formats/flopimg.h
r9927r9928
1/*********************************************************************
2
3    flopimg.h
4
5    Floppy disk image abstraction code
6
7*********************************************************************/
8
9#ifndef FLOPIMG_H
10#define FLOPIMG_H
11
12#include "emu.h"
13#include "opresolv.h"
14
15
16/***************************************************************************
17
18    Constants
19
20***************************************************************************/
21
22#define FLOPPY_FLAGS_READWRITE      0
23#define FLOPPY_FLAGS_READONLY      1
24
25
26
27/***************************************************************************
28
29    Type definitions
30
31***************************************************************************/
32
33typedef enum
34{
35   FLOPPY_ERROR_SUCCESS,         /* no error */
36   FLOPPY_ERROR_INTERNAL,         /* fatal internal error */
37   FLOPPY_ERROR_UNSUPPORTED,      /* this operation is unsupported */
38   FLOPPY_ERROR_OUTOFMEMORY,      /* ran out of memory */
39   FLOPPY_ERROR_SEEKERROR,         /* attempted to seek to nonexistant location */
40   FLOPPY_ERROR_INVALIDIMAGE,      /* this image in invalid */
41   FLOPPY_ERROR_READONLY,         /* attempt to write to read-only image */
42   FLOPPY_ERROR_NOSPACE,
43   FLOPPY_ERROR_PARAMOUTOFRANGE,
44   FLOPPY_ERROR_PARAMNOTSPECIFIED
45}
46floperr_t;
47
48typedef struct _floppy_image floppy_image;
49
50struct FloppyCallbacks
51{
52   floperr_t (*read_sector)(floppy_image *floppy, int head, int track, int sector, void *buffer, size_t buflen);
53   floperr_t (*write_sector)(floppy_image *floppy, int head, int track, int sector, const void *buffer, size_t buflen, int ddam);
54   floperr_t (*read_indexed_sector)(floppy_image *floppy, int head, int track, int sector_index, void *buffer, size_t buflen);
55   floperr_t (*write_indexed_sector)(floppy_image *floppy, int head, int track, int sector_index, const void *buffer, size_t buflen, int ddam);
56   floperr_t (*read_track)(floppy_image *floppy, int head, int track, UINT64 offset, void *buffer, size_t buflen);
57   floperr_t (*write_track)(floppy_image *floppy, int head, int track, UINT64 offset, const void *buffer, size_t buflen);
58   floperr_t (*format_track)(floppy_image *floppy, int head, int track, option_resolution *params);
59   floperr_t (*post_format)(floppy_image *floppy, option_resolution *params);
60   int (*get_heads_per_disk)(floppy_image *floppy);
61   int (*get_tracks_per_disk)(floppy_image *floppy);
62   int (*get_sectors_per_track)(floppy_image *floppy, int head, int track);
63   UINT32 (*get_track_size)(floppy_image *floppy, int head, int track);
64   floperr_t (*get_sector_length)(floppy_image *floppy, int head, int track, int sector, UINT32 *sector_length);
65   floperr_t (*get_indexed_sector_info)(floppy_image *floppy, int head, int track, int sector_index, int *cylinder, int *side, int *sector, UINT32 *sector_length, unsigned long *flags);
66   floperr_t (*get_track_data_offset)(floppy_image *floppy, int head, int track, UINT64 *offset);
67};
68
69
70
71struct FloppyFormat
72{
73   const char *name;
74   const char *extensions;
75   const char *description;
76   floperr_t (*identify)(floppy_image *floppy, const struct FloppyFormat *format, int *vote);
77   floperr_t (*construct)(floppy_image *floppy, const struct FloppyFormat *format, option_resolution *params);
78   const char *param_guidelines;
79};
80
81#define FLOPPY_IDENTIFY(name)   floperr_t name(floppy_image *floppy, const struct FloppyFormat *format, int *vote)
82#define FLOPPY_CONSTRUCT(name)   floperr_t name(floppy_image *floppy, const struct FloppyFormat *format, option_resolution *params)
83
84FLOPPY_IDENTIFY(td0_dsk_identify);
85FLOPPY_CONSTRUCT(td0_dsk_construct);
86
87FLOPPY_IDENTIFY(imd_dsk_identify);
88FLOPPY_CONSTRUCT(imd_dsk_construct);
89
90FLOPPY_IDENTIFY(cqm_dsk_identify);
91FLOPPY_CONSTRUCT(cqm_dsk_construct);
92
93FLOPPY_IDENTIFY(dsk_dsk_identify);
94FLOPPY_CONSTRUCT(dsk_dsk_construct);
95
96FLOPPY_IDENTIFY(d88_dsk_identify);
97FLOPPY_CONSTRUCT(d88_dsk_construct);
98
99FLOPPY_IDENTIFY(fdi_dsk_identify);
100FLOPPY_CONSTRUCT(fdi_dsk_construct);
101
102#define FLOPPY_OPTIONS_NAME(name)   floppyoptions_##name
103
104#define FLOPPY_OPTIONS_START(name)                                    \
105   const struct FloppyFormat floppyoptions_##name[] =                        \
106   {                                                         \
107
108#define FLOPPY_OPTIONS_END0 \
109      { NULL }                     \
110   };
111
112#define FLOPPY_OPTIONS_EXTERN(name)                                    \
113   extern const struct FloppyFormat floppyoptions_##name[]                     \
114
115#define FLOPPY_OPTION(name, extensions_, description_, identify_, construct_, ranges_)\
116   { #name, extensions_, description_, identify_, construct_, ranges_ },            \
117
118#define FLOPPY_OPTIONS_END                                          \
119      FLOPPY_OPTION( fdi, "fdi", "Formatted Disk Image", fdi_dsk_identify, fdi_dsk_construct, NULL) \
120      FLOPPY_OPTION( td0, "td0", "Teledisk floppy disk image",   td0_dsk_identify, td0_dsk_construct, NULL) \
121      FLOPPY_OPTION( imd, "imd", "IMD floppy disk image",   imd_dsk_identify, imd_dsk_construct, NULL) \
122      FLOPPY_OPTION( cqm, "cqm,dsk", "CopyQM floppy disk image",   cqm_dsk_identify, cqm_dsk_construct, NULL) \
123      FLOPPY_OPTION( dsk, "dsk", "DSK floppy disk image",   dsk_dsk_identify, dsk_dsk_construct, NULL) \
124      FLOPPY_OPTION( d88, "d77,d88,1dd", "D88 Floppy Disk image", d88_dsk_identify, d88_dsk_construct, NULL) \
125   FLOPPY_OPTIONS_END0
126
127FLOPPY_OPTIONS_EXTERN(default);
128
129#define PARAM_END            '\0'
130#define PARAM_HEADS            'H'
131#define PARAM_TRACKS         'T'
132#define PARAM_SECTORS         'S'
133#define PARAM_SECTOR_LENGTH      'L'
134#define PARAM_INTERLEAVE      'I'
135#define PARAM_FIRST_SECTOR_ID   'F'
136
137#define HEADS(range)         "H" #range
138#define TRACKS(range)         "T" #range
139#define SECTORS(range)         "S" #range
140#define SECTOR_LENGTH(range)   "L" #range
141#define INTERLEAVE(range)      "I" #range
142#define FIRST_SECTOR_ID(range)   "F" #range
143
144
145/***************************************************************************
146
147    Prototypes
148
149***************************************************************************/
150
151OPTION_GUIDE_EXTERN(floppy_option_guide);
152
153/* opening, closing and creating of floppy images */
154floperr_t floppy_open(void *fp, const struct io_procs *procs, const char *extension, const struct FloppyFormat *format, int flags, floppy_image **outfloppy);
155floperr_t floppy_open_choices(void *fp, const struct io_procs *procs, const char *extension, const struct FloppyFormat *formats, int flags, floppy_image **outfloppy);
156floperr_t floppy_create(void *fp, const struct io_procs *procs, const struct FloppyFormat *format, option_resolution *parameters, floppy_image **outfloppy);
157void floppy_close(floppy_image *floppy);
158
159/* useful for identifying a floppy image */
160floperr_t floppy_identify(void *fp, const struct io_procs *procs, const char *extension,
161   const struct FloppyFormat *formats, int *identified_format);
162
163/* functions useful within format constructors */
164void *floppy_tag(floppy_image *floppy);
165void *floppy_create_tag(floppy_image *floppy, size_t tagsize);
166struct FloppyCallbacks *floppy_callbacks(floppy_image *floppy);
167UINT8 floppy_get_filler(floppy_image *floppy);
168void floppy_set_filler(floppy_image *floppy, UINT8 filler);
169
170/* calls for accessing disk image data */
171floperr_t floppy_read_sector(floppy_image *floppy, int head, int track, int sector, int offset, void *buffer, size_t buffer_len);
172floperr_t floppy_write_sector(floppy_image *floppy, int head, int track, int sector, int offset, const void *buffer, size_t buffer_len, int ddam);
173floperr_t floppy_read_indexed_sector(floppy_image *floppy, int head, int track, int sector_index, int offset, void *buffer, size_t buffer_len);
174floperr_t floppy_write_indexed_sector(floppy_image *floppy, int head, int track, int sector_index, int offset, const void *buffer, size_t buffer_len, int ddam);
175floperr_t floppy_read_track(floppy_image *floppy, int head, int track, void *buffer, size_t buffer_len);
176floperr_t floppy_write_track(floppy_image *floppy, int head, int track, const void *buffer, size_t buffer_len);
177floperr_t floppy_read_track_data(floppy_image *floppy, int head, int track, void *buffer, size_t buffer_len);
178floperr_t floppy_write_track_data(floppy_image *floppy, int head, int track, const void *buffer, size_t buffer_len);
179floperr_t floppy_format_track(floppy_image *floppy, int head, int track, option_resolution *params);
180int floppy_get_tracks_per_disk(floppy_image *floppy);
181int floppy_get_heads_per_disk(floppy_image *floppy);
182UINT32 floppy_get_track_size(floppy_image *floppy, int head, int track);
183floperr_t floppy_get_sector_length(floppy_image *floppy, int head, int track, int sector, UINT32 *sector_length);
184floperr_t floppy_get_indexed_sector_info(floppy_image *floppy, int head, int track, int sector_index, int *cylinder, int *side, int *sector, UINT32 *sector_length, unsigned long *flags);
185floperr_t floppy_get_sector_count(floppy_image *floppy, int head, int track, int *sector_count);
186floperr_t floppy_load_track(floppy_image *floppy, int head, int track, int dirtify, void **track_data, size_t *track_length);
187int floppy_is_read_only(floppy_image *floppy);
188UINT8 floppy_random_byte(floppy_image *floppy);
189
190/* accessors for meta information about the image */
191const char *floppy_format_description(floppy_image *floppy);
192
193/* calls for accessing the raw disk image */
194void floppy_image_read(floppy_image *floppy, void *buffer, UINT64 offset, size_t length);
195void floppy_image_write(floppy_image *floppy, const void *buffer, UINT64 offset, size_t length);
196void floppy_image_write_filler(floppy_image *floppy, UINT8 filler, UINT64 offset, size_t length);
197UINT64 floppy_image_size(floppy_image *floppy);
198
199/* misc */
200const char *floppy_error(floperr_t err);
201
202
203#endif /* FLOPIMG_H */
204
src/mess/formats/cassimg.c
r9927r9928
1/*********************************************************************
2
3    cassimg.c
4
5    Cassette tape image abstraction code
6
7*********************************************************************/
8
9
10#include <string.h>
11
12#include "emu.h"
13#include "imageutl.h"
14#include "pool.h"
15#include "formats/cassimg.h"
16
17
18/* debugging parameters */
19#define LOG_PUT_SAMPLES         0
20#define DUMP_CASSETTES         0
21
22#define SAMPLES_PER_BLOCK      0x40000
23#define CASSETTE_FLAG_DIRTY      0x10000
24
25
26CASSETTE_FORMATLIST_START(cassette_default_formats)
27CASSETTE_FORMATLIST_END
28
29
30
31/*********************************************************************
32    helper code
33*********************************************************************/
34
35static double map_double(double d, UINT64 low, UINT64 high, UINT64 value)
36{
37#if defined(_MSC_VER) && (_MSC_VER <= 1200)
38   /* casting unsigned __int64 to double is not supported on VC6 or before */
39   return d * (INT64)(value - low) / (INT64)(high - low);
40#else
41   return d * (value - low) / (high - low);
42#endif
43}
44
45
46
47static size_t waveform_bytes_per_sample(int waveform_flags)
48{
49   return (size_t) (1 << ((waveform_flags & 0x06) / 2));
50}
51
52
53
54/*********************************************************************
55    extrapolation and interpolation
56*********************************************************************/
57
58static INT32 extrapolate8(INT8 value)
59{
60   return ((INT32) value) << 24;
61}
62
63static INT32 extrapolate16(INT16 value)
64{
65   return ((INT32) value) << 16;
66}
67
68static INT8 interpolate8(INT32 value)
69{
70   return (INT8) (value >> 24);
71}
72
73static INT16 interpolate16(INT32 value)
74{
75   return (INT16) (value >> 16);
76}
77
78
79
80/*********************************************************************
81    initialization and termination
82*********************************************************************/
83
84static cassette_image *cassette_init(running_machine *machine,const struct CassetteFormat *format, void *file, const struct io_procs *procs, int flags)
85{
86   cassette_image *cassette;
87
88   cassette = (cassette_image *)malloc(sizeof(struct _cassette_image));
89   if (!cassette)
90      return NULL;
91
92   memset(cassette, 0, sizeof(*cassette));
93   cassette->format = format;
94   cassette->io.file = file;
95   cassette->io.procs = procs;
96   cassette->flags = flags;
97   cassette->pool = pool_alloc_lib(NULL);
98   cassette->machine = machine;
99   return cassette;
100}
101
102
103
104static void cassette_finishinit(casserr_t err, cassette_image *cassette, cassette_image **outcassette)
105{
106   if (cassette && (err || !outcassette))
107   {
108      cassette_close(cassette);
109      cassette = NULL;
110   }
111   if (outcassette)
112      *outcassette = cassette;
113}
114
115
116
117static int good_format(const struct CassetteFormat *format, const char *extension, int flags)
118{
119   if (extension && !image_find_extension(format->extensions, extension))
120      return FALSE;
121   if (((flags & CASSETTE_FLAG_READONLY) == 0) && !format->save)
122      return FALSE;
123   return TRUE;
124}
125
126
127
128casserr_t cassette_open_choices(running_machine *machine,void *file, const struct io_procs *procs, const char *extension,
129   const struct CassetteFormat *const *formats, int flags, cassette_image **outcassette)
130{
131   casserr_t err;
132   cassette_image *cassette;
133   const struct CassetteFormat *format;
134   struct CassetteOptions opts = {0, };
135   int i;
136
137   /* if not specified, use the dummy arguments */
138   if (!formats)
139      formats = cassette_default_formats;
140
141   /* create the cassette object */
142   cassette = cassette_init(machine, NULL, file, procs, flags);
143   if (!cassette)
144   {
145      err = CASSETTE_ERROR_OUTOFMEMORY;
146      goto done;
147   }
148
149   /* identify the image */
150   format = NULL;
151   for (i = 0; !format && formats[i]; i++)
152   {
153      if (good_format(formats[i], extension, flags))
154      {
155         format = formats[i];
156         memset(&opts, 0, sizeof(opts));
157         err = format->identify(cassette, &opts);
158         if (err == CASSETTE_ERROR_INVALIDIMAGE)
159            format = NULL;
160         else if (err)
161            goto done;
162      }
163   }
164
165   /* have we found a proper format */
166   if (!format)
167   {
168      err = CASSETTE_ERROR_INVALIDIMAGE;
169      goto done;
170   }
171   cassette->format = format;
172
173   /* read the options */
174   cassette->channels = opts.channels;
175   cassette->sample_frequency = opts.sample_frequency;
176
177   /* load the image */
178   err = format->load(cassette);
179   if (err)
180      goto done;
181
182   /* success */
183   cassette->flags &= ~CASSETTE_FLAG_DIRTY;
184   err = CASSETTE_ERROR_SUCCESS;
185
186done:
187   cassette_finishinit(err, cassette, outcassette);
188   return err;
189}
190
191
192
193casserr_t cassette_open(running_machine *machine, void *file, const struct io_procs *procs,
194   const struct CassetteFormat *format, int flags, cassette_image **outcassette)
195{
196   const struct CassetteFormat *formats[2];
197   formats[0] = format;
198   formats[1] = NULL;
199   return cassette_open_choices(machine, file, procs, NULL, formats, flags, outcassette);
200}
201
202
203
204casserr_t cassette_create(running_machine *machine, void *file, const struct io_procs *procs, const struct CassetteFormat *format,
205   const struct CassetteOptions *opts, int flags, cassette_image **outcassette)
206{
207   casserr_t err;
208   cassette_image *cassette;
209   static const struct CassetteOptions default_options = { 1, 16, 44100 };
210
211   /* cannot create to a read only image */
212   if (flags & CASSETTE_FLAG_READONLY)
213      return CASSETTE_ERROR_INVALIDIMAGE;
214
215   /* is this a good format? */
216   if (!good_format(format, NULL, flags))
217      return CASSETTE_ERROR_INVALIDIMAGE;
218
219   /* normalize arguments */
220   if (!opts)
221      opts = &default_options;
222
223   /* create the cassette object */
224   cassette = cassette_init(machine, format, file, procs, flags);
225   if (!cassette)
226   {
227      err = CASSETTE_ERROR_OUTOFMEMORY;
228      goto done;
229   }
230
231   /* read the options */
232   cassette->channels = opts->channels;
233   cassette->sample_frequency = opts->sample_frequency;
234
235   err = CASSETTE_ERROR_SUCCESS;
236
237done:
238   cassette_finishinit(err, cassette, outcassette);
239   return err;
240}
241
242
243
244static casserr_t cassette_perform_save(cassette_image *cassette)
245{
246   struct CassetteInfo info;
247   cassette_get_info(cassette, &info);
248   return cassette->format->save(cassette, &info);
249}
250
251
252
253casserr_t cassette_save(cassette_image *cassette)
254{
255   casserr_t err;
256
257   if (!cassette->format || !cassette->format->save)
258      return CASSETTE_ERROR_UNSUPPORTED;
259
260   err = cassette_perform_save(cassette);
261   if (err)
262      return err;
263
264   cassette->flags &= ~CASSETTE_FLAG_DIRTY;
265   return CASSETTE_ERROR_SUCCESS;
266}
267
268
269
270void cassette_get_info(cassette_image *cassette, struct CassetteInfo *info)
271{
272   memset(info, 0, sizeof(*info));
273   info->channels = cassette->channels;
274   info->sample_count = cassette->sample_count;
275   info->sample_frequency = cassette->sample_frequency;
276   info->bits_per_sample = (int) waveform_bytes_per_sample(cassette->flags) * 8;
277}
278
279
280
281void cassette_close(cassette_image *cassette)
282{
283   if (cassette)
284   {
285      if ((cassette->flags & CASSETTE_FLAG_DIRTY) && (cassette->flags & CASSETTE_FLAG_SAVEONEXIT))
286         cassette_save(cassette);
287      pool_free_lib(cassette->pool);
288      free(cassette);
289   }
290}
291
292
293
294void cassette_change(cassette_image *cassette, void *file, const struct io_procs *procs, const struct CassetteFormat *format, int flags)
295{
296   if ((flags & CASSETTE_FLAG_READONLY) == 0)
297      flags |= CASSETTE_FLAG_DIRTY;
298   cassette->io.file = file;
299   cassette->io.procs = procs;
300   cassette->format = format;
301   cassette->flags = flags;
302}
303
304
305
306/*********************************************************************
307    calls for accessing the raw cassette image
308*********************************************************************/
309
310void cassette_image_read(cassette_image *cassette, void *buffer, UINT64 offset, size_t length)
311{
312   io_generic_read(&cassette->io, buffer, offset, length);
313}
314
315
316
317void cassette_image_write(cassette_image *cassette, const void *buffer, UINT64 offset, size_t length)
318{
319   io_generic_write(&cassette->io, buffer, offset, length);
320}
321
322
323
324UINT64 cassette_image_size(cassette_image *cassette)
325{
326   return io_generic_size(&cassette->io);
327}
328
329
330
331/*********************************************************************
332    waveform accesses
333*********************************************************************/
334
335struct manipulation_ranges
336{
337   int channel_first;
338   int channel_last;
339   size_t sample_first;
340   size_t sample_last;
341};
342
343
344
345static size_t my_round(double d)
346{
347   size_t result;
348   d += 0.5;
349   result = (size_t) d;
350   return result;
351}
352
353
354
355static casserr_t compute_manipulation_ranges(cassette_image *cassette, int channel,
356   double time_index, double sample_period, struct manipulation_ranges *ranges)
357{
358   if (channel < 0)
359   {
360      ranges->channel_first = 0;
361      ranges->channel_last = cassette->channels - 1;
362   }
363   else
364   {
365      ranges->channel_first = channel;
366      ranges->channel_last = channel;
367   }
368
369   ranges->sample_first = my_round(time_index * cassette->sample_frequency);
370   ranges->sample_last = my_round((time_index + sample_period) * cassette->sample_frequency);
371
372   if (ranges->sample_last > ranges->sample_first)
373      ranges->sample_last--;
374
375   return CASSETTE_ERROR_SUCCESS;
376}
377
378
379
380static casserr_t lookup_sample(cassette_image *cassette, int channel, size_t sample, int allocate, INT32 **ptr)
381{
382   size_t sample_block;
383   size_t sample_index;
384   size_t sample_size;
385   size_t new_block_count;
386   size_t new_block_sample_count;
387   INT32 *new_block;
388   struct sample_block *new_blocks;
389   struct sample_block *block;
390
391   *ptr = NULL;
392   sample_block = (sample / SAMPLES_PER_BLOCK) * cassette->channels + channel;
393   sample_index = sample % SAMPLES_PER_BLOCK;
394   sample_size = sizeof(block->block[0]);
395
396   /* is this block beyond the edge of our waveform? */
397   if (sample_block >= cassette->block_count)
398   {
399      if (!allocate)
400         return CASSETTE_ERROR_SUCCESS;
401
402      /* allocate new blocks */
403      new_block_count = sample_block + 1;
404      new_blocks = (struct sample_block *)pool_realloc_lib(cassette->pool, cassette->blocks, new_block_count * sizeof(cassette->blocks[0]));
405      if (!new_blocks)
406         return CASSETTE_ERROR_OUTOFMEMORY;
407
408      cassette->blocks = new_blocks;
409      memset(&cassette->blocks[cassette->block_count], 0, (new_block_count - cassette->block_count) * sizeof(cassette->blocks[0]));
410      cassette->block_count = new_block_count;
411   }
412
413   block = &cassette->blocks[sample_block];
414
415   /* is this sample access off the current block? */
416   if (sample_index >= block->sample_count)
417   {
418      if (!allocate)
419         return CASSETTE_ERROR_SUCCESS;
420
421      new_block_sample_count = SAMPLES_PER_BLOCK;
422
423      new_block = (INT32*)pool_realloc_lib(cassette->pool, block->block, new_block_sample_count * sample_size);
424      if (!new_block)
425         return CASSETTE_ERROR_OUTOFMEMORY;
426
427      block->block = new_block;
428      memset(&block->block[block->sample_count], 0, (new_block_sample_count - block->sample_count) * sample_size);
429      block->sample_count = new_block_sample_count;
430   }
431
432   *ptr = &block->block[sample_index];
433   return CASSETTE_ERROR_SUCCESS;
434}
435
436
437
438/*********************************************************************
439    waveform accesses
440*********************************************************************/
441
442casserr_t cassette_get_samples(cassette_image *cassette, int channel,
443   double time_index, double sample_period, size_t sample_count, size_t sample_bytes,
444   void *samples, int waveform_flags)
445{
446   casserr_t err;
447   struct manipulation_ranges ranges;
448   size_t sample_index;
449   size_t cassette_sample_index;
450   UINT8 *dest_ptr;
451   const INT32 *source_ptr;
452   double d;
453   INT16 word;
454   INT32 dword;
455   INT64 sum;
456
457   assert(cassette);
458
459   err = compute_manipulation_ranges(cassette, channel, time_index, sample_period, &ranges);
460   if (err)
461      return err;
462
463   for (sample_index = 0; sample_index < sample_count; sample_index++)
464   {
465      sum = 0;
466
467      for (channel = ranges.channel_first; channel <= ranges.channel_last; channel++)
468      {
469         /* find the sample that we are putting */
470         d = map_double(ranges.sample_last + 1 - ranges.sample_first, 0, sample_count, sample_index) + ranges.sample_first;
471         cassette_sample_index = (size_t) d;
472         err = lookup_sample(cassette, channel, cassette_sample_index, TRUE, (INT32 **) &source_ptr);
473         if (err)
474            return err;
475
476         sum += *source_ptr;
477      }
478
479      /* average out the samples */
480      sum /= (ranges.channel_last + 1 - ranges.channel_first);
481
482      /* and write out the result */
483      dest_ptr = (UINT8*)samples;
484      dest_ptr += waveform_bytes_per_sample(waveform_flags) * sample_index;
485      switch(waveform_bytes_per_sample(waveform_flags))
486      {
487         case 1:
488            *((INT8 *) dest_ptr) = interpolate8(sum);
489            break;
490         case 2:
491            word = interpolate16(sum);
492            if (waveform_flags & CASSETTE_WAVEFORM_ENDIAN_FLIP)
493               word = FLIPENDIAN_INT16(word);
494            *((INT16 *) dest_ptr) = word;
495            break;
496         case 4:
497            dword = sum;
498            if (waveform_flags & CASSETTE_WAVEFORM_ENDIAN_FLIP)
499               dword = FLIPENDIAN_INT32(dword);
500            *((INT32 *) dest_ptr) = dword;
501            break;
502      }
503   }
504   return CASSETTE_ERROR_SUCCESS;
505}
506
507
508
509casserr_t cassette_put_samples(cassette_image *cassette, int channel,
510   double time_index, double sample_period, size_t sample_count, size_t sample_bytes,
511   const void *samples, int waveform_flags)
512{
513   casserr_t err;
514   struct manipulation_ranges ranges;
515   size_t sample_index;
516   INT32 *dest_ptr;
517   INT32 dest_value;
518   INT16 word;
519   INT32 dword;
520   const UINT8 *source_ptr;
521   double d;
522
523   if (!cassette)
524      return CASSETTE_ERROR_SUCCESS;
525
526   if (sample_period == 0)
527      return CASSETTE_ERROR_SUCCESS;
528
529   err = compute_manipulation_ranges(cassette, channel, time_index, sample_period, &ranges);
530   if (err)
531      return err;
532
533   if (cassette->sample_count < ranges.sample_last+1)
534      cassette->sample_count = ranges.sample_last + 1;
535   cassette->flags |= CASSETTE_FLAG_DIRTY;
536
537   if (LOG_PUT_SAMPLES)
538   {
539      logerror("cassette_put_samples(): Putting samples TIME=[%2.6g..%2.6g] INDEX=[%i..%i]\n",
540         time_index,            time_index + sample_period,
541         (int)ranges.sample_first,   (int)ranges.sample_last);
542   }
543
544   for (sample_index = ranges.sample_first; sample_index <= ranges.sample_last; sample_index++)
545   {
546      /* figure out the source pointer */
547      d = map_double(sample_count, ranges.sample_first, ranges.sample_last + 1, sample_index);
548      source_ptr = (const UINT8*)samples;
549      source_ptr += ((size_t) d) * sample_bytes;
550
551      /* compute the value that we are writing */
552      switch(waveform_bytes_per_sample(waveform_flags)) {
553      case 1:
554         dest_value = extrapolate8(*((INT8 *) source_ptr));
555         break;
556      case 2:
557         word = *((INT16 *) source_ptr);
558         if (waveform_flags & CASSETTE_WAVEFORM_ENDIAN_FLIP)
559            word = FLIPENDIAN_INT16(word);
560         dest_value = extrapolate16(word);
561         break;
562      case 4:
563         dword = *((INT32 *) source_ptr);
564         if (waveform_flags & CASSETTE_WAVEFORM_ENDIAN_FLIP)
565            dword = FLIPENDIAN_INT32(dword);
566         dest_value = dword;
567         break;
568      default:
569         return CASSETTE_ERROR_INTERNAL;
570      }
571
572      for (channel = ranges.channel_first; channel <= ranges.channel_last; channel++)
573      {
574         /* find the sample that we are putting */
575         err = lookup_sample(cassette, channel, sample_index, TRUE, &dest_ptr);
576         if (err)
577            return err;
578         *dest_ptr = dest_value;
579      }
580   }
581   return CASSETTE_ERROR_SUCCESS;
582}
583
584
585
586casserr_t cassette_get_sample(cassette_image *cassette, int channel,
587   double time_index, double sample_period, INT32 *sample)
588{
589   return cassette_get_samples(cassette, channel, time_index,
590       sample_period, 1, 0, sample, CASSETTE_WAVEFORM_32BIT);
591}
592
593
594
595casserr_t cassette_put_sample(cassette_image *cassette, int channel,
596   double time_index, double sample_period, INT32 sample)
597{
598   return cassette_put_samples(cassette, channel, time_index,
599       sample_period, 1, 0, &sample, CASSETTE_WAVEFORM_32BIT);
600}
601
602
603
604/*********************************************************************
605    waveform accesses to/from the raw image
606*********************************************************************/
607
608casserr_t cassette_read_samples(cassette_image *cassette, int channels, double time_index,
609   double sample_period, size_t sample_count, UINT64 offset, int waveform_flags)
610{
611   casserr_t err;
612   size_t chunk_sample_count;
613   size_t bytes_per_sample;
614   size_t sample_bytes;
615   size_t samples_loaded = 0;
616   double chunk_time_index;
617   double chunk_sample_period;
618   int channel;
619   UINT8 buffer[8192];
620
621   bytes_per_sample = waveform_bytes_per_sample(waveform_flags);
622   sample_bytes = bytes_per_sample * channels;
623
624   while(samples_loaded < sample_count)
625   {
626      chunk_sample_count = MIN(sizeof(buffer) / sample_bytes, (sample_count - samples_loaded));
627      chunk_sample_period = map_double(sample_period, 0, sample_count, chunk_sample_count);
628      chunk_time_index = time_index + map_double(sample_period, 0, sample_count, samples_loaded);
629
630      cassette_image_read(cassette, buffer, offset, chunk_sample_count * sample_bytes);
631
632      for (channel = 0; channel < channels; channel++)
633      {
634         err = cassette_put_samples(cassette, channel, chunk_time_index, chunk_sample_period,
635            chunk_sample_count, sample_bytes, &buffer[channel * bytes_per_sample], waveform_flags);
636         if (err)
637            return err;
638      }
639
640      offset += chunk_sample_count * sample_bytes;
641      samples_loaded += chunk_sample_count;
642   }
643   return CASSETTE_ERROR_SUCCESS;
644}
645
646
647
648casserr_t cassette_write_samples(cassette_image *cassette, int channels, double time_index,
649   double sample_period, size_t sample_count, UINT64 offset, int waveform_flags)
650{
651   casserr_t err;
652   size_t chunk_sample_count;
653   size_t bytes_per_sample;
654   size_t sample_bytes;
655   size_t samples_saved = 0;
656   double chunk_time_index;
657   double chunk_sample_period;
658   int channel;
659   UINT8 buffer[8192];
660
661   bytes_per_sample = waveform_bytes_per_sample(waveform_flags);
662   sample_bytes = bytes_per_sample * channels;
663
664   while(samples_saved < sample_count)
665   {
666      chunk_sample_count = MIN(sizeof(buffer) / sample_bytes, (sample_count - samples_saved));
667      chunk_sample_period = map_double(sample_period, 0, sample_count, chunk_sample_count);
668      chunk_time_index = time_index + map_double(sample_period, 0, sample_count, samples_saved);
669
670      for (channel = 0; channel < channels; channel++)
671      {
672         err = cassette_get_samples(cassette, channel, chunk_time_index, chunk_sample_period,
673            chunk_sample_count, sample_bytes, &buffer[channel * bytes_per_sample], waveform_flags);
674         if (err)
675            return err;
676      }
677
678      cassette_image_write(cassette, buffer, offset, chunk_sample_count * sample_bytes);
679
680      offset += chunk_sample_count * sample_bytes;
681      samples_saved += chunk_sample_count;
682   }
683   return CASSETTE_ERROR_SUCCESS;
684}
685
686
687
688/*********************************************************************
689    waveform accesses to/from the raw image
690*********************************************************************/
691
692static const INT8 *choose_wave(const struct CassetteModulation *modulation, size_t *wave_bytes_length)
693{
694   static const INT8 square_wave[] = { -128, 127 };
695   static const INT8 sine_wave[] = { 0, 48, 89, 117, 127, 117, 89, 48, 0, -48, -89, -117, -127, -117, -89, -48 };
696
697   if (modulation->flags & CASSETTE_MODULATION_SINEWAVE)
698   {
699      *wave_bytes_length = ARRAY_LENGTH(sine_wave);
700      return sine_wave;
701   }
702   else
703   {
704      *wave_bytes_length = ARRAY_LENGTH(square_wave);
705      return square_wave;
706   }
707}
708
709
710
711casserr_t cassette_modulation_identify(cassette_image *cassette, const struct CassetteModulation *modulation,
712   struct CassetteOptions *opts)
713{
714   size_t wave_bytes_length;
715   choose_wave(modulation, &wave_bytes_length);
716   opts->bits_per_sample = 8;
717   opts->channels = 1;
718   opts->sample_frequency = (UINT32) (MAX(modulation->zero_frequency_high, modulation->one_frequency_high) * wave_bytes_length * 2);
719   return CASSETTE_ERROR_SUCCESS;
720}
721
722
723
724casserr_t cassette_put_modulated_data(cassette_image *cassette, int channel, double time_index,
725   const void *data, size_t data_length, const struct CassetteModulation *modulation,
726   double *time_displacement)
727{
728   casserr_t err;
729   const UINT8 *data_bytes = (const UINT8 *)data;
730   const INT8 *wave_bytes;
731   size_t wave_bytes_length;
732   double total_displacement = 0.0;
733   double pulse_period;
734   double pulse_frequency;
735   UINT8 b;
736   int i;
737
738   wave_bytes = choose_wave(modulation, &wave_bytes_length);
739
740   while(data_length--)
741   {
742      b = *(data_bytes++);
743      for (i = 0; i < 8; i++)
744      {
745         pulse_frequency = (b & (1 << i)) ? modulation->one_frequency_cannonical : modulation->zero_frequency_cannonical;
746         pulse_period = 1 / pulse_frequency;
747         err = cassette_put_samples(cassette, 0, time_index, pulse_period, wave_bytes_length, 1, wave_bytes, CASSETTE_WAVEFORM_8BIT);
748         if (err)
749            goto done;
750         time_index += pulse_period;
751         total_displacement += pulse_period;
752      }
753   }
754   err = CASSETTE_ERROR_SUCCESS;
755
756done:
757   if (time_displacement)
758      *time_displacement = total_displacement;
759   return err;
760}
761
762
763
764casserr_t cassette_put_modulated_filler(cassette_image *cassette, int channel, double time_index,
765   UINT8 filler, size_t filler_length, const struct CassetteModulation *modulation,
766   double *time_displacement)
767{
768   casserr_t err;
769   double delta;
770   double total_displacement = 0.0;
771
772   while(filler_length--)
773   {
774      err = cassette_put_modulated_data(cassette, channel, time_index, &filler, 1, modulation, &delta);
775      if (err)
776         return err;
777      total_displacement += delta;
778      time_index += delta;
779   }
780
781   if (time_displacement)
782      *time_displacement = total_displacement;
783   return CASSETTE_ERROR_SUCCESS;
784}
785
786
787
788casserr_t cassette_read_modulated_data(cassette_image *cassette, int channel, double time_index,
789   UINT64 offset, UINT64 length, const struct CassetteModulation *modulation,
790   double *time_displacement)
791{
792   casserr_t err;
793   UINT8 buffer_stack[1024];
794   UINT8 *buffer;
795   UINT8 *alloc_buffer = NULL;
796   double delta;
797   double total_displacement = 0.0;
798   size_t this_length;
799   size_t buffer_length;
800
801   if (length <= sizeof(buffer_stack))
802   {
803      buffer = buffer_stack;
804      buffer_length = sizeof(buffer_stack);
805   }
806   else
807   {
808      buffer_length = MIN(length, 100000);
809      alloc_buffer = (UINT8*)malloc(buffer_length);
810      if (!alloc_buffer)
811      {
812         err = CASSETTE_ERROR_OUTOFMEMORY;
813         goto done;
814      }
815      buffer = alloc_buffer;
816   }
817
818   while(length > 0)
819   {
820      this_length = (size_t) MIN(length, buffer_length);
821      cassette_image_read(cassette, buffer, offset, this_length);
822
823      err = cassette_put_modulated_data(cassette, channel, time_index, buffer, this_length, modulation, &delta);
824      if (err)
825         goto done;
826      total_displacement += delta;
827      time_index += delta;
828      length -= this_length;
829   }
830
831   if (time_displacement)
832      *time_displacement = total_displacement;
833   err = CASSETTE_ERROR_SUCCESS;
834
835done:
836   if (alloc_buffer)
837      free(alloc_buffer);
838   return err;
839}
840
841
842
843casserr_t cassette_put_modulated_data_bit(cassette_image *cassette, int channel, double time_index,
844   UINT8 data, const struct CassetteModulation *modulation,
845   double *time_displacement)
846{
847   casserr_t err;
848   const INT8 *wave_bytes;
849   size_t wave_bytes_length;
850   double total_displacement = 0.0;
851   double pulse_period;
852   double pulse_frequency;
853
854   wave_bytes = choose_wave(modulation, &wave_bytes_length);
855
856   pulse_frequency = (data) ? modulation->one_frequency_cannonical : modulation->zero_frequency_cannonical;
857   pulse_period = 1 / pulse_frequency;
858   err = cassette_put_samples(cassette, 0, time_index, pulse_period, wave_bytes_length, 1, wave_bytes, CASSETTE_WAVEFORM_8BIT);
859   if (err)
860      goto done;
861   time_index += pulse_period;
862   total_displacement += pulse_period;
863
864   err = CASSETTE_ERROR_SUCCESS;
865
866done:
867   if (time_displacement)
868      *time_displacement = total_displacement;
869   return err;
870}
871
872
873
874/*********************************************************************
875    waveform accesses to/from the raw image
876*********************************************************************/
877
878casserr_t cassette_legacy_identify(cassette_image *cassette, struct CassetteOptions *opts,
879   const struct CassetteLegacyWaveFiller *legacy_args)
880{
881   opts->channels = 1;
882   opts->bits_per_sample = 16;
883   opts->sample_frequency = legacy_args->sample_frequency;
884   return CASSETTE_ERROR_SUCCESS;
885}
886
887
888
889casserr_t cassette_legacy_construct(cassette_image *cassette,
890   const struct CassetteLegacyWaveFiller *legacy_args)
891{
892   casserr_t err;
893   int length;
894   int sample_count;
895   void *bytes = NULL;
896   void *chunk = NULL;
897   INT16 *samples = NULL;
898   int pos = 0;
899   UINT64 offset = 0;
900   UINT64 size;
901   struct CassetteLegacyWaveFiller args;
902
903   /* sanity check the args */
904   assert(legacy_args->header_samples >= -1);
905   assert(legacy_args->trailer_samples >= 0);
906   assert(legacy_args->fill_wave);
907
908   size = cassette_image_size(cassette);
909
910   /* normalize the args */
911   args = *legacy_args;
912   if (args.chunk_size == 0)
913      args.chunk_size = 1;
914   else if (args.chunk_size < 0)
915      args.chunk_size = cassette_image_size(cassette);
916   if (args.sample_frequency == 0)
917      args.sample_frequency = 11025;
918
919   /* allocate a buffer for the binary data */
920   chunk = malloc(args.chunk_size);
921   if (!chunk)
922   {
923      err = CASSETTE_ERROR_OUTOFMEMORY;
924      goto done;
925   }
926
927   /* determine number of samples */
928   if (args.chunk_sample_calc)
929   {
930      if (size > 0x7FFFFFFF)
931      {
932         err = CASSETTE_ERROR_OUTOFMEMORY;
933         goto done;
934      }
935
936      bytes = malloc(size);
937      if (!bytes)
938      {
939         err = CASSETTE_ERROR_OUTOFMEMORY;
940         goto done;
941      }
942      cassette_image_read(cassette, bytes, 0, size);
943      sample_count = args.chunk_sample_calc((const UINT8*)bytes, (int) size);
944
945      if (args.header_samples < 0)
946         args.header_samples = sample_count;
947   }
948   else
949   {
950      sample_count = ((size + args.chunk_size - 1) / args.chunk_size)
951         * args.chunk_samples;
952   }
953   sample_count += args.header_samples + args.trailer_samples;
954
955   /* allocate a buffer for the completed samples */
956   samples = (INT16*)malloc(sample_count * sizeof(*samples));
957   if (!samples)
958   {
959      err = CASSETTE_ERROR_OUTOFMEMORY;
960      goto done;
961   }
962
963   /* if there has to be a header */
964   if (args.header_samples > 0)
965   {
966      length = args.fill_wave(samples + pos, sample_count - pos, CODE_HEADER);
967      if (length < 0)
968      {
969         err = CASSETTE_ERROR_INVALIDIMAGE;
970         goto done;
971      }
972      pos += length;
973   }
974
975   /* convert the file data to samples */
976   while((pos < sample_count) && (offset < size))
977   {
978      cassette_image_read(cassette, chunk, offset, args.chunk_size);
979      offset += args.chunk_size;
980
981      length = args.fill_wave(samples + pos, sample_count - pos, (UINT8*)chunk);
982      if (length < 0)
983      {
984         err = CASSETTE_ERROR_INVALIDIMAGE;
985         goto done;
986      }
987      pos += length;
988      if (length == 0)
989         break;
990   }
991
992   /* if there has to be a trailer */
993   if (args.trailer_samples > 0)
994   {
995      length = args.fill_wave(samples + pos, sample_count - pos, CODE_TRAILER);
996      if (length < 0)
997      {
998         err = CASSETTE_ERROR_INVALIDIMAGE;
999         goto done;
1000      }
1001      pos += length;
1002   }
1003
1004   /* specify the wave */
1005   err = cassette_put_samples(cassette, 0, 0.0, ((double) pos) / args.sample_frequency,
1006      pos, 2, samples, CASSETTE_WAVEFORM_16BIT);
1007   if (err)
1008      goto done;
1009
1010   /* success! */
1011   err = CASSETTE_ERROR_SUCCESS;
1012
1013#if DUMP_CASSETTES
1014   cassette_dump(cassette, "C:\\TEMP\\CASDUMP.WAV");
1015#endif
1016
1017done:
1018   if (samples)
1019      free(samples);
1020   if (chunk)
1021      free(chunk);
1022   if (bytes)
1023      free(bytes);
1024   return err;
1025}
1026
1027
1028
1029/*********************************************************************
1030    cassette_dump
1031
1032    A debugging call to dump a casette image to a disk based wave file
1033*********************************************************************/
1034
1035void cassette_dump(cassette_image *image, const char *filename)
1036{
1037   FILE *f;
1038   struct io_generic saved_io;
1039   const struct CassetteFormat *saved_format;
1040
1041   f = fopen(filename, "wb");
1042   if (!f)
1043      return;
1044
1045   memcpy(&saved_io, &image->io, sizeof(saved_io));
1046   saved_format = image->format;
1047
1048   image->io.file = f;
1049   image->io.procs = &stdio_ioprocs_noclose;
1050   image->format = &wavfile_format;
1051   cassette_perform_save(image);
1052
1053   memcpy(&image->io, &saved_io, sizeof(saved_io));
1054   image->format = saved_format;
1055
1056   fclose(f);
1057}
1058
1059
src/mess/formats/cassimg.h
r9927r9928
1/*********************************************************************
2
3    cassimg.h
4
5    Cassette tape image abstraction code
6
7*********************************************************************/
8
9#ifndef CASSIMG_H
10#define CASSIMG_H
11
12#include "pool.h"
13#include "emu.h"
14
15/***************************************************************************
16
17    Constants
18
19***************************************************************************/
20
21#define CASSETTE_FLAG_READWRITE         0
22#define CASSETTE_FLAG_READONLY         1
23#define CASSETTE_FLAG_NOSAVEONEXIT      0
24#define CASSETTE_FLAG_SAVEONEXIT      2
25
26#define CASSETTE_WAVEFORM_8BIT         0
27#define CASSETTE_WAVEFORM_16BIT         2
28#define CASSETTE_WAVEFORM_16BIT_FLIP   3
29#define CASSETTE_WAVEFORM_32BIT         4
30#define CASSETTE_WAVEFORM_32BIT_FLIP   5
31#define CASSETTE_WAVEFORM_ENDIAN_FLIP   1
32
33#define CASSETTE_MODULATION_SQUAREWAVE   0
34#define CASSETTE_MODULATION_SINEWAVE   1
35
36
37#ifdef LSB_FIRST
38#define CASSETTE_WAVEFORM_16BITBE      CASSETTE_WAVEFORM_16BIT_FLIP
39#define CASSETTE_WAVEFORM_16BITLE      CASSETTE_WAVEFORM_16BIT
40#define CASSETTE_WAVEFORM_32BITBE      CASSETTE_WAVEFORM_32BIT_FLIP
41#define CASSETTE_WAVEFORM_32BITLE      CASSETTE_WAVEFORM_32BIT
42#else
43#define CASSETTE_WAVEFORM_16BITBE      CASSETTE_WAVEFORM_16BIT
44#define CASSETTE_WAVEFORM_16BITLE      CASSETTE_WAVEFORM_16BIT_FLIP
45#define CASSETTE_WAVEFORM_32BITBE      CASSETTE_WAVEFORM_32BIT
46#define CASSETTE_WAVEFORM_32BITLE      CASSETTE_WAVEFORM_32BIT_FLIP
47#endif
48
49
50/***************************************************************************
51
52    Type definitions
53
54***************************************************************************/
55
56typedef enum
57{
58   CASSETTE_ERROR_SUCCESS,         /* no error */
59   CASSETTE_ERROR_INTERNAL,      /* fatal internal error */
60   CASSETTE_ERROR_UNSUPPORTED,      /* this operation is unsupported */
61   CASSETTE_ERROR_OUTOFMEMORY,      /* ran out of memory */
62   CASSETTE_ERROR_INVALIDIMAGE,   /* invalid image */
63   CASSETTE_ERROR_INVALIDARG
64}
65casserr_t;
66
67struct sample_block
68{
69   INT32 *block;
70   size_t sample_count;
71};
72
73struct CassetteOptions
74{
75   int channels;
76   int bits_per_sample;
77   UINT32 sample_frequency;
78};
79
80struct CassetteInfo
81{
82   int channels;
83   int bits_per_sample;
84   UINT32 sample_frequency;
85   size_t sample_count;
86};
87
88struct _cassette_image
89{
90   const struct CassetteFormat *format;
91   struct io_generic io;
92   object_pool *pool;
93
94   int channels;
95   int flags;
96   UINT32 sample_frequency;
97
98   struct sample_block *blocks;
99   size_t block_count;
100   size_t sample_count;
101
102   running_machine *machine;
103};
104
105typedef struct _cassette_image cassette_image;
106
107struct CassetteFormat
108{
109   const char *extensions;
110   casserr_t (*identify)(cassette_image *cassette, struct CassetteOptions *opts);
111   casserr_t (*load)(cassette_image *cassette);
112   casserr_t (*save)(cassette_image *cassette, const struct CassetteInfo *info);
113};
114
115/* used for the core modulation code */
116struct CassetteModulation
117{
118   int flags;
119   double zero_frequency_low;
120   double zero_frequency_cannonical;
121   double zero_frequency_high;
122   double one_frequency_low;
123   double one_frequency_cannonical;
124   double one_frequency_high;
125};
126
127/* code to adapt existing legacy fill_wave functions */
128struct CassetteLegacyWaveFiller
129{
130   int (*fill_wave)(INT16 *, int, UINT8 *);
131   int chunk_size;
132   int chunk_samples;
133   int (*chunk_sample_calc)(const UINT8 *bytes, int length);
134   UINT32 sample_frequency;
135   int header_samples;
136   int trailer_samples;
137};
138
139/* builtin formats */
140extern const struct CassetteFormat wavfile_format;
141
142/* macros for specifying format lists */
143#define CASSETTE_FORMATLIST_EXTERN(name)   \
144   extern const struct CassetteFormat *const name[]
145
146#define CASSETTE_FORMATLIST_START(name)      \
147   const struct CassetteFormat *const name[] =   \
148   {                              \
149      &wavfile_format,               \
150
151#define CASSETTE_FORMAT(name)            \
152      &(name),                     \
153
154#define CASSETTE_FORMATLIST_END            \
155      NULL                        \
156   };
157
158CASSETTE_FORMATLIST_EXTERN(cassette_default_formats);
159
160/***************************************************************************
161
162    Prototypes
163
164***************************************************************************/
165
166casserr_t cassette_open(running_machine *machine,void *file, const struct io_procs *procs,
167   const struct CassetteFormat *format, int flags, cassette_image **outcassette);
168casserr_t cassette_open_choices(running_machine *machine,void *file, const struct io_procs *procs, const char *extension,
169   const struct CassetteFormat *const *formats, int flags, cassette_image **outcassette);
170casserr_t cassette_create(running_machine *machine,void *file, const struct io_procs *procs, const struct CassetteFormat *format,
171   const struct CassetteOptions *opts, int flags, cassette_image **outcassette);
172casserr_t cassette_save(cassette_image *cassette);
173void cassette_close(cassette_image *cassette);
174void cassette_change(cassette_image *cassette, void *file, const struct io_procs *procs, const struct CassetteFormat *format, int flags);
175void cassette_get_info(cassette_image *cassette, struct CassetteInfo *info);
176
177/* calls for accessing the raw cassette image */
178void cassette_image_read(cassette_image *cassette, void *buffer, UINT64 offset, size_t length);
179void cassette_image_write(cassette_image *cassette, const void *buffer, UINT64 offset, size_t length);
180UINT64 cassette_image_size(cassette_image *cassette);
181
182/* waveform accesses */
183casserr_t cassette_get_samples(cassette_image *cassette, int channel,
184   double time_index, double sample_period, size_t sample_count, size_t sample_bytes,
185   void *samples, int waveform_flags);
186casserr_t cassette_put_samples(cassette_image *cassette, int channel,
187   double time_index, double sample_period, size_t sample_count, size_t sample_bytes,
188   const void *samples, int waveform_flags);
189casserr_t cassette_get_sample(cassette_image *cassette, int channel,
190   double time_index, double sample_period, INT32 *sample);
191casserr_t cassette_put_sample(cassette_image *cassette, int channel,
192   double time_index, double sample_period, INT32 sample);
193
194/* waveform accesses to/from the raw image */
195casserr_t cassette_read_samples(cassette_image *cassette, int channels, double time_index,
196   double sample_period, size_t sample_count, UINT64 offset, int waveform_flags);
197casserr_t cassette_write_samples(cassette_image *cassette, int channels, double time_index,
198   double sample_period, size_t sample_count, UINT64 offset, int waveform_flags);
199
200/* modulation support */
201casserr_t cassette_modulation_identify(cassette_image *cassette, const struct CassetteModulation *modulation,
202   struct CassetteOptions *opts);
203casserr_t cassette_put_modulated_data(cassette_image *cassette, int channel, double time_index,
204   const void *data, size_t data_length, const struct CassetteModulation *modulation,
205   double *time_displacement);
206casserr_t cassette_put_modulated_filler(cassette_image *cassette, int channel, double time_index,
207   UINT8 filler, size_t filler_length, const struct CassetteModulation *modulation,
208   double *time_displacement);
209casserr_t cassette_read_modulated_data(cassette_image *cassette, int channel, double time_index,
210   UINT64 offset, UINT64 length, const struct CassetteModulation *modulation,
211   double *time_displacement);
212casserr_t cassette_put_modulated_data_bit(cassette_image *cassette, int channel, double time_index,
213   UINT8 data, const struct CassetteModulation *modulation,
214   double *time_displacement);
215
216/* debug calls */
217void cassette_dump(cassette_image *image, const char *filename);
218
219/* legacy code support */
220#define CODE_HEADER    ((UINT8*)-1)
221#define CODE_TRAILER   ((UINT8*)-2)
222casserr_t cassette_legacy_identify(cassette_image *cassette, struct CassetteOptions *opts,
223   const struct CassetteLegacyWaveFiller *legacy_args);
224casserr_t cassette_legacy_construct(cassette_image *cassette,
225   const struct CassetteLegacyWaveFiller *legacy_args);
226
227#endif /* CASSIMG_H */
src/mess/formats/wavfile.c
r9927r9928
1/*********************************************************************
2
3    wavfile.c
4
5    Format code for wave (*.wav) files
6
7*********************************************************************/
8
9#include <stdio.h>
10#include <assert.h>
11
12#include "wavfile.h"
13#include "cassimg.h"
14
15static const char magic1[4] = { 'R', 'I', 'F', 'F' };
16static const char magic2[4] = { 'W', 'A', 'V', 'E' };
17static const char format_tag_id[4] = { 'f', 'm', 't', ' ' };
18static const char data_tag_id[4] = { 'd', 'a', 't', 'a' };
19
20#define WAV_FORMAT_PCM      1
21
22
23
24static UINT32 get_leuint32(const void *ptr)
25{
26   UINT32 value;
27   memcpy(&value, ptr, sizeof(value));
28   return LITTLE_ENDIANIZE_INT32(value);
29}
30
31
32
33static UINT16 get_leuint16(const void *ptr)
34{
35   UINT16 value;
36   memcpy(&value, ptr, sizeof(value));
37   return LITTLE_ENDIANIZE_INT16(value);
38}
39
40
41
42static void put_leuint32(void *ptr, UINT32 value)
43{
44   value = LITTLE_ENDIANIZE_INT32(value);
45   memcpy(ptr, &value, sizeof(value));
46}
47
48
49
50static void put_leuint16(void *ptr, UINT16 value)
51{
52   value = LITTLE_ENDIANIZE_INT16(value);
53   memcpy(ptr, &value, sizeof(value));
54}
55
56
57
58static casserr_t wavfile_process(cassette_image *cassette, struct CassetteOptions *opts,
59   int read_waveform)
60{
61   UINT8 file_header[12];
62   UINT8 tag_header[8];
63   UINT8 format_tag[16];
64   UINT32 stated_size;
65   UINT64 file_size;
66   UINT32 tag_size;
67   UINT32 tag_samples;
68   UINT64 offset;
69   int format_specified = FALSE;
70
71   UINT16 format_type = 0;
72   UINT32 bytes_per_second = 0;
73   UINT16 block_align = 0;
74   int waveform_flags = 0;
75
76   /* read header */
77   cassette_image_read(cassette, file_header, 0, sizeof(file_header));
78   offset = sizeof(file_header);
79
80   /* check magic numbers */
81   if (memcmp(&file_header[0], magic1, 4))
82      return CASSETTE_ERROR_INVALIDIMAGE;
83   if (memcmp(&file_header[8], magic2, 4))
84      return CASSETTE_ERROR_INVALIDIMAGE;
85
86   /* read and sanity check size */
87   stated_size = get_leuint32(&file_header[4]) + 8;
88   file_size = cassette_image_size(cassette);
89   if (stated_size > file_size)
90      stated_size = (UINT32) file_size;
91
92   while(offset < stated_size)
93   {
94      cassette_image_read(cassette, tag_header, offset, sizeof(tag_header));
95      tag_size = get_leuint32(&tag_header[4]);
96      offset += sizeof(tag_header);
97
98      if (!memcmp(tag_header, format_tag_id, 4))
99      {
100         /* format tag */
101         if (format_specified || (tag_size < sizeof(format_tag)))
102            return CASSETTE_ERROR_INVALIDIMAGE;
103         format_specified = TRUE;
104
105         cassette_image_read(cassette, format_tag, offset, sizeof(format_tag));
106
107         format_type            = get_leuint16(&format_tag[0]);
108         opts->channels         = get_leuint16(&format_tag[2]);
109         opts->sample_frequency   = get_leuint32(&format_tag[4]);
110         bytes_per_second      = get_leuint32(&format_tag[8]);
111         block_align            = get_leuint16(&format_tag[12]);
112         opts->bits_per_sample   = get_leuint16(&format_tag[14]);
113
114         if (format_type != WAV_FORMAT_PCM)
115            return CASSETTE_ERROR_INVALIDIMAGE;
116         if (opts->sample_frequency * opts->bits_per_sample * opts->channels / 8 != bytes_per_second)
117            return CASSETTE_ERROR_INVALIDIMAGE;
118
119         switch(opts->bits_per_sample)
120         {
121            case 8:
122               waveform_flags = CASSETTE_WAVEFORM_8BIT;
123               break;
124            case 16:
125               waveform_flags = CASSETTE_WAVEFORM_16BITLE;
126               break;
127            case 32:
128               waveform_flags = CASSETTE_WAVEFORM_32BITLE;
129               break;
130            default:
131               return CASSETTE_ERROR_INVALIDIMAGE;
132         }
133      }
134      else if (!memcmp(tag_header, data_tag_id, 4))
135      {
136         /* data tag */
137         if (!format_specified)
138            return CASSETTE_ERROR_INVALIDIMAGE;
139
140         if (read_waveform)
141         {
142            tag_samples = tag_size / (opts->bits_per_sample / 8) / opts->channels;
143            cassette_read_samples(cassette, opts->channels, 0.0, tag_samples / ((double) opts->sample_frequency),
144               tag_samples, offset, waveform_flags);
145         }
146      }
147      else
148      {
149         /* ignore other tags */
150      }
151      offset += tag_size;
152   }
153
154   return CASSETTE_ERROR_SUCCESS;
155}
156
157
158
159static casserr_t wavfile_identify(cassette_image *cassette, struct CassetteOptions *opts)
160{
161   return wavfile_process(cassette, opts, FALSE);
162}
163
164
165
166static casserr_t wavfile_load(cassette_image *cassette)
167{
168   struct CassetteOptions opts;
169   memset(&opts, 0, sizeof(opts));
170   return wavfile_process(cassette, &opts, TRUE);
171}
172
173
174
175static casserr_t wavfile_save(cassette_image *cassette, const struct CassetteInfo *info)
176{
177   casserr_t err;
178   UINT8 consolidated_header[12 + 8 + 16 + 8];
179   UINT8 *header            = &consolidated_header[0];
180   UINT8 *format_tag_header   = &consolidated_header[12];
181   UINT8 *format_tag_data      = &consolidated_header[12 + 8];
182   UINT8 *data_tag_header      = &consolidated_header[12 + 8 + 16];
183   UINT32 file_size;
184   UINT32 bytes_per_second;
185   UINT16 bits_per_sample;
186   UINT32 data_size;
187   size_t bytes_per_sample = 2;
188   int waveform_flags = CASSETTE_WAVEFORM_16BITLE;
189   UINT16 block_align;
190
191   bits_per_sample = (UINT16) (bytes_per_sample * 8);
192   bytes_per_second = info->sample_frequency * bytes_per_sample * info->channels;
193   data_size = (UINT32) (info->sample_count * bytes_per_sample * info->channels);
194   file_size = data_size + sizeof(consolidated_header) - 8;
195   block_align = (UINT16) (bytes_per_sample * info->channels);
196
197   /* set up header */
198   memcpy(&header[0],               magic1, 4);
199   memcpy(&header[8],               magic2, 4);
200   put_leuint32(&header[4],         file_size);
201
202   /* set up format tag */
203   memcpy(&format_tag_header[0],      format_tag_id, 4);
204   put_leuint32(&format_tag_header[4],   16);
205   put_leuint16(&format_tag_data[0],   WAV_FORMAT_PCM);
206   put_leuint16(&format_tag_data[2],   info->channels);
207   put_leuint32(&format_tag_data[4],   info->sample_frequency);
208   put_leuint32(&format_tag_data[8],   bytes_per_second);
209   put_leuint16(&format_tag_data[12],   block_align);
210   put_leuint16(&format_tag_data[14],   bits_per_sample);
211
212   /* set up data tag */
213   memcpy(&data_tag_header[0],         data_tag_id, 4);
214   put_leuint32(&data_tag_header[4],   data_size);
215
216   /* write consolidated header */
217   cassette_image_write(cassette, consolidated_header, 0, sizeof(consolidated_header));
218
219   /* write out the actual data */
220   err = cassette_write_samples(cassette, info->channels, 0.0, info->sample_count
221      / (double) info->sample_frequency, info->sample_count, sizeof(consolidated_header),
222      waveform_flags);
223   if (err)
224      return err;
225
226   return CASSETTE_ERROR_SUCCESS;
227}
228
229
230
231const struct CassetteFormat wavfile_format =
232{
233   "wav",
234   wavfile_identify,
235   wavfile_load,
236   wavfile_save
237};
238
239
240
241/*********************************************************************
242    wavfile_testload()
243
244    This is a hokey function used to test the cassette wave loading
245    system, specifically to test that when one loads a WAV file image
246    that the resulting info queried will be the same data in the WAV.
247
248    This code has already identified some rounding errors
249*********************************************************************/
250
251#ifdef UNUSED_FUNCTION
252void wavfile_testload(const char *fname)
253{
254   cassette_image *cassette;
255   FILE *f;
256   long offset;
257   int freq, samples, i;
258   INT32 cassamp;
259   INT16 wavsamp;
260
261   f = fopen(fname, "rb");
262   if (!f)
263      return;
264
265   if (cassette_open(f, &stdio_ioprocs, &wavfile_format, CASSETTE_FLAG_READONLY, &cassette))
266   {
267      fclose(f);
268      return;
269   }
270
271   offset = 44;
272   freq = 44100;
273   samples = 5667062;
274
275   for (i = 0; i < samples; i++)
276   {
277      cassette_get_sample(cassette, 0, i / (double) freq, 0.0, &cassamp);
278
279      fseek(f, offset + i * 2, SEEK_SET);
280      fread(&wavsamp, 1, 2, f);
281      assert(cassamp == (((UINT32) wavsamp) << 16));
282   }
283
284   cassette_close(cassette);
285
286   fclose(f);
287}
288#endif
289
290
291
src/mess/formats/wavfile.h
r9927r9928
1/*********************************************************************
2
3    wavfile.h
4
5    Format code for wave (*.wav) files
6
7*********************************************************************/
8
9#ifndef WAVFILE_H
10#define WAVFILE_H
11
12#include "cassimg.h"
13
14extern const struct CassetteFormat wavfile_format;
15
16#endif /* WAVFILE_H */
src/mess/formats/trs_cmd.h
r9927r9928
1212#define __TRS_CMD__
1313
1414#include "emu.h"
15#include "devices/snapquik.h"
15#include "imagedev/snapquik.h"
1616
1717QUICKLOAD_LOAD( trs80_cmd );
1818
src/mess/formats/d88_dsk.c
r9927r9928
2828 */
2929
3030#include "emu.h"
31#include "formats/flopimg.h"
32#include "devices/flopdrv.h"
31#include "imagedev/flopimg.h"
32#include "imagedev/flopdrv.h"
3333
3434#define D88_HEADER_LEN 0x2b0
3535
src/mess/formats/fmsx_cas.h
r9927r9928
99#ifndef FMSX_CAS_H
1010#define FMSX_CAS_H
1111
12#include "formats/cassimg.h"
12#include "imagedev/cassimg.h"
1313
1414CASSETTE_FORMATLIST_EXTERN(fmsx_cassette_formats);
1515
src/mess/formats/uef_cas.h
r9927r9928
77#ifndef UEF_CAS_H
88#define UEF_CAS_H
99
10#include "formats/cassimg.h"
10#include "imagedev/cassimg.h"
1111
1212extern const struct CassetteFormat uef_cassette_format;
1313
src/mess/formats/dim_dsk.h
r9927r9928
99#ifndef DIM_DSK_H
1010#define DIM_DSK_H
1111
12#include "formats/flopimg.h"
12#include "imagedev/flopimg.h"
1313
1414/**************************************************************************/
1515
src/mess/formats/tzx_cas.h
r9927r9928
88#ifndef TZX_CAS_H
99#define TZX_CAS_H
1010
11#include "formats/cassimg.h"
11#include "imagedev/cassimg.h"
1212
1313CASSETTE_FORMATLIST_EXTERN(tzx_cassette_formats);
1414CASSETTE_FORMATLIST_EXTERN(cdt_cassette_formats);
src/mess/formats/cqm_dsk.c
r9927r9928
88
99#include <string.h>
1010#include "emu.h"
11#include "formats/flopimg.h"
12#include "devices/flopdrv.h"
11#include "imagedev/flopimg.h"
12#include "imagedev/flopdrv.h"
1313
1414#define CQM_HEADER_SIZE 133
1515
src/mess/formats/vt_cas.h
r9927r9928
99#ifndef VT_CAS_H
1010#define VT_CAS_H
1111
12#include "formats/cassimg.h"
12#include "imagedev/cassimg.h"
1313
1414CASSETTE_FORMATLIST_EXTERN(vtech1_cassette_formats);
1515CASSETTE_FORMATLIST_EXTERN(vtech2_cassette_formats);
src/mess/formats/csw_cas.h
r9927r9928
77#ifndef CSW_CAS_H
88#define CSW_CAS_H
99
10#include "formats/cassimg.h"
10#include "imagedev/cassimg.h"
1111
1212CASSETTE_FORMATLIST_EXTERN(csw_cassette_formats);
1313CASSETTE_FORMATLIST_EXTERN(bbc_cassette_formats);
src/mess/formats/coco_dsk.h
r9927r9928
99#ifndef COCO_DSK_H
1010#define COCO_DSK_H
1111
12#include "formats/flopimg.h"
12#include "imagedev/flopimg.h"
1313
1414
1515/**************************************************************************/
src/mess/formats/nes_dsk.h
r9927r9928
99#ifndef NES_DSK_H_
1010#define NES_DSK_H_
1111
12#include "formats/flopimg.h"
12#include "imagedev/flopimg.h"
1313
1414FLOPPY_OPTIONS_EXTERN(nes_only);
1515
src/mess/formats/x1_tap.h
r9927r9928
77#ifndef X1_TAP_H_
88#define X1_TAP_H_
99
10#include "formats/cassimg.h"
10#include "imagedev/cassimg.h"
1111
1212CASSETTE_FORMATLIST_EXTERN( x1_cassette_formats );
1313
src/mess/formats/apridisk.h
r9927r9928
77#ifndef __APRIDISK_H__
88#define __APRIDISK_H__
99
10#include "flopimg.h"
10#include "imagedev/flopimg.h"
1111
1212FLOPPY_IDENTIFY( apridisk_identify );
1313FLOPPY_CONSTRUCT( apridisk_construct );
src/mess/formats/msx_dsk.h
r9927r9928
99#ifndef MSX_DSK_H
1010#define MSX_DSK_H
1111
12#include "formats/flopimg.h"
12#include "imagedev/flopimg.h"
1313
1414/**************************************************************************/
1515
src/mess/formats/ap_dsk35.h
r9927r9928
99#ifndef AP_DSK35_H
1010#define AP_DSK35_H
1111
12#include "formats/flopimg.h"
12#include "imagedev/flopimg.h"
1313
1414void sony_filltrack(UINT8 *buffer, size_t buffer_len, size_t *pos, UINT8 data);
1515UINT8 sony_fetchtrack(const UINT8 *buffer, size_t buffer_len, size_t *pos);
src/mess/formats/comx35_dsk.h
r9927r9928
99#ifndef COMX35_DSK_H
1010#define COMX35_DSK_H
1111
12#include "formats/flopimg.h"
12#include "imagedev/flopimg.h"
1313
1414/**************************************************************************/
1515
src/mess/formats/svi_cas.h
r9927r9928
99#ifndef SVI_CAS_H
1010#define SVI_CAS_H
1111
12#include "formats/cassimg.h"
12#include "imagedev/cassimg.h"
1313
1414CASSETTE_FORMATLIST_EXTERN(svi_cassette_formats);
1515
src/mess/formats/d64_dsk.c
r9927r9928
1919
2020#include "emu.h"
2121#include "g64_dsk.h"
22#include "formats/flopimg.h"
22#include "imagedev/flopimg.h"
2323#include "formats/d64_dsk.h"
24#include "devices/flopdrv.h"
24#include "imagedev/flopdrv.h"
2525
2626/***************************************************************************
2727    PARAMETERS
src/mess/formats/trd_dsk.h
r9927r9928
99#ifndef TRD_DSK_H
1010#define TRD_DSK_H
1111
12#include "formats/flopimg.h"
12#include "imagedev/flopimg.h"
1313
1414/**************************************************************************/
1515
src/mess/formats/g64_dsk.c
r9927r9928
1717
1818#include "emu.h"
1919#include "g64_dsk.h"
20#include "formats/flopimg.h"
21#include "devices/flopdrv.h"
20#include "imagedev/flopimg.h"
21#include "imagedev/flopdrv.h"
2222
2323/***************************************************************************
2424    PARAMETERS
src/mess/formats/trs_cas.h
r9927r9928
99#ifndef __TRS_CAS_H
1010#define __TRS_CAS_H
1111
12#include "formats/cassimg.h"
12#include "imagedev/cassimg.h"
1313
1414CASSETTE_FORMATLIST_EXTERN(trs80l2_cassette_formats);
1515
src/mess/formats/d64_dsk.h
r9927r9928
99#ifndef __D64_DSK__
1010#define __D64_DSK__
1111
12#include "formats/flopimg.h"
12#include "imagedev/flopimg.h"
1313
1414/***************************************************************************
1515    PROTOTYPES
src/mess/formats/atom_atm.h
r9927r9928
1212#define __ATOM_ATM__
1313
1414#include "emu.h"
15#include "devices/snapquik.h"
15#include "imagedev/snapquik.h"
1616
1717QUICKLOAD_LOAD( atom_atm );
1818
src/mess/formats/g64_dsk.h
r9927r9928
99#ifndef __G64_DSK__
1010#define __G64_DSK__
1111
12#include "formats/flopimg.h"
12#include "imagedev/flopimg.h"
1313
1414/***************************************************************************
1515    MACROS / CONSTANTS
src/mess/formats/pc_dsk.h
r9927r9928
99#ifndef PC_DSK_H
1010#define PC_DSK_H
1111
12#include "formats/flopimg.h"
12#include "imagedev/flopimg.h"
1313
1414
1515/**************************************************************************/
src/mess/formats/lviv_lvt.h
r9927r9928
99#ifndef LVIV_LVT_H
1010#define LVIV_LVT_H
1111
12#include "formats/cassimg.h"
12#include "imagedev/cassimg.h"
1313
1414CASSETTE_FORMATLIST_EXTERN(lviv_lvt_format);
1515
src/mess/formats/thom_dsk.h
r9927r9928
11#ifndef THOM_DSK
22#define THOM_DSK
33
4#include "devices/flopdrv.h"
4#include "imagedev/flopdrv.h"
55
66/* recognized image formats:
77   - .fd    one-side 5"1/4 (single and double density), 3"1/2
src/mess/formats/atarist_dsk.h
r9927r9928
99#ifndef ATARIST_DSK_H
1010#define ATARIST_DSK_H
1111
12#include "formats/flopimg.h"
12#include "imagedev/flopimg.h"
1313
1414/**************************************************************************/
1515
src/mess/formats/primoptp.h
r9927r9928
99#ifndef PRIMOPTP_H
1010#define PRIMOPTP_H
1111
12#include "formats/cassimg.h"
12#include "imagedev/cassimg.h"
1313
1414CASSETTE_FORMATLIST_EXTERN( primo_ptp_format );
1515
src/mess/formats/dsk_dsk.c
r9927r9928
1010
1111#include "emu.h"
1212#include "imageutl.h"
13#include "formats/flopimg.h"
14#include "devices/flopdrv.h"
13#include "imagedev/flopimg.h"
14#include "imagedev/flopdrv.h"
1515
1616#define MV_CPC     "MV - CPC"
1717#define EXTENDED   "EXTENDED"
src/mess/formats/zx81_p.c
r9927r9928
3131
3232#include "emu.h"
3333#include "zx81_p.h"
34#include "devices/cassette.h"
34#include "imagedev/cassette.h"
3535
3636
3737#define WAVEENTRY_LOW   -32768
src/mess/formats/zx81_p.h
r9927r9928
99#ifndef ZX81_P_H
1010#define ZX81_P_H
1111
12#include "formats/cassimg.h"
12#include "imagedev/cassimg.h"
1313
1414CASSETTE_FORMATLIST_EXTERN(zx81_p_format);
1515CASSETTE_FORMATLIST_EXTERN(zx80_o_format);
src/mess/formats/vt_dsk.h
r9927r9928
99#ifndef VT_DSK_H
1010#define VT_DSK_H
1111
12#include "formats/flopimg.h"
12#include "imagedev/flopimg.h"
1313
1414FLOPPY_OPTIONS_EXTERN(vz);
1515
src/mess/formats/cpis_dsk.h
r9927r9928
99#ifndef CPIS_DSK_H
1010#define CPIS_DSK_H
1111
12#include "formats/flopimg.h"
12#include "imagedev/flopimg.h"
1313
1414
1515/**************************************************************************/
src/mess/formats/z80ne_dsk.c
r9927r9928
99#include "emu.h"
1010#include "formats/z80ne_dsk.h"
1111#include "formats/basicdsk.h"
12#include "devices/flopdrv.h"
12#include "imagedev/flopdrv.h"
1313#include "imageutl.h"
1414
1515/* -----------------------------------------------------------------------
src/mess/formats/oric_tap.h
r9927r9928
99#ifndef ORIC_TAP_H
1010#define ORIC_TAP_H
1111
12#include "formats/cassimg.h"
12#include "imagedev/cassimg.h"
1313
1414CASSETTE_FORMATLIST_EXTERN(oric_cassette_formats);
1515
src/mess/formats/atom_tap.h
r9927r9928
1111#ifndef __ATOM_TAP__
1212#define __ATOM_TAP__
1313
14#include "formats/cassimg.h"
14#include "imagedev/cassimg.h"
1515
1616extern const struct CassetteFormat atom_tap_format;
1717
src/mess/formats/z80ne_dsk.h
r9927r9928
99#ifndef Z80NE_DSK_H
1010#define Z80NE_DSK_H
1111
12#include "formats/flopimg.h"
12#include "imagedev/flopimg.h"
1313
1414
1515/**************************************************************************/
src/mess/formats/cbm_tap.h
r9927r9928
99#ifndef CBM_TAP_H
1010#define CBM_TAP_H
1111
12#include "formats/cassimg.h"
12#include "imagedev/cassimg.h"
1313
1414CASSETTE_FORMATLIST_EXTERN(cbm_cassette_formats);
1515
src/mess/formats/jupi_tap.h
r9927r9928
99#ifndef JUPI_TAP_H
1010#define JUPI_TAP_H
1111
12#include "formats/cassimg.h"
12#include "imagedev/cassimg.h"
1313
1414CASSETTE_FORMATLIST_EXTERN(jupiter_cassette_formats);
1515
src/mess/formats/coupedsk.h
r9927r9928
99#ifndef __COUPEDSK_H__
1010#define __COUPEDSK_H__
1111
12#include "formats/flopimg.h"
12#include "imagedev/flopimg.h"
1313
1414
1515FLOPPY_CONSTRUCT( coupe_mgt_construct );
src/mess/formats/svi_dsk.h
r9927r9928
99#ifndef SVI_DSK_H
1010#define SVI_DSK_H
1111
12#include "formats/flopimg.h"
12#include "imagedev/flopimg.h"
1313
1414/**************************************************************************/
1515
src/mess/formats/adam_dsk.h
r9927r9928
99#ifndef ADAM_DSK_H
1010#define ADAM_DSK_H
1111
12#include "formats/flopimg.h"
12#include "imagedev/flopimg.h"
1313
1414
1515/**************************************************************************/
src/mess/formats/m65_snqk.h
r9927r9928
1515#ifndef __M65_SNQK_H__
1616#define __M65_SNQK_H__
1717
18#include "devices/snapquik.h"
18#include "imagedev/snapquik.h"
1919
2020SNAPSHOT_LOAD( microtan );
2121QUICKLOAD_LOAD( microtan );
src/mess/formats/trs_dsk.c
r9927r9928
33#include "formats/trs_dsk.h"
44#include "formats/basicdsk.h"
55#include "formats/coco_dsk.h"
6#include "devices/flopdrv.h"
6#include "imagedev/flopdrv.h"
77
88/* -----------------------------------------------------------------------
99 * JV1 (Jeff Vavasour 1) format
src/mess/formats/ami_dsk.h
r9927r9928
99#ifndef AMI_DSK_H_
1010#define AMI_DSK_H_
1111
12#include "formats/flopimg.h"
12#include "imagedev/flopimg.h"
1313
1414FLOPPY_OPTIONS_EXTERN(amiga);
1515FLOPPY_OPTIONS_EXTERN(amiga_only);
src/mess/formats/trs_dsk.h
r9927r9928
99#ifndef TRS_DSK_H
1010#define TRS_DSK_H
1111
12#include "flopimg.h"
12#include "imagedev/flopimg.h"
1313
14
1514/**************************************************************************/
1615
1716FLOPPY_OPTIONS_EXTERN( trs80 );
src/mess/formats/apf_apt.h
r9927r9928
11#ifndef APFCAS_H
22#define APFCAS_H
33
4#include "formats/cassimg.h"
4#include "imagedev/cassimg.h"
55
66CASSETTE_FORMATLIST_EXTERN(apf_cassette_formats);
77
src/mess/formats/fm7_cas.h
r9927r9928
55#ifndef FM7_CAS_H_
66#define FM7_CAS_H_
77
8#include "formats/cassimg.h"
8#include "imagedev/cassimg.h"
99
1010CASSETTE_FORMATLIST_EXTERN( fm7_cassette_formats );
1111
src/mess/formats/orao_cas.h
r9927r9928
88#ifndef ORAO_CAS_H
99#define ORAO_CAS_H
1010
11#include "formats/cassimg.h"
11#include "imagedev/cassimg.h"
1212
1313CASSETTE_FORMATLIST_EXTERN(orao_cassette_formats);
1414
src/mess/formats/p6001_cas.h
r9927r9928
55#ifndef PC6001_CAS_H_
66#define PC6001_CAS_H_
77
8#include "formats/cassimg.h"
8#include "imagedev/cassimg.h"
99
1010CASSETTE_FORMATLIST_EXTERN( pc6001_cassette_formats );
1111
src/mess/formats/cbm_snqk.h
r9927r9928
77#ifndef __CBM_SNQK_H__
88#define __CBM_SNQK_H__
99
10#include "devices/snapquik.h"
10#include "imagedev/snapquik.h"
1111
1212#define CBM_QUICKLOAD_DELAY_SECONDS 3
1313
src/mess/formats/fdi_dsk.c
r9927r9928
1616
1717#include "emu.h"
1818#include "imageutl.h"
19#include "formats/flopimg.h"
20#include "devices/flopdrv.h"
19#include "imagedev/flopimg.h"
20#include "imagedev/flopdrv.h"
2121
2222/***************************************************************************
2323    PARAMETERS
src/mess/formats/ti99_dsk.h
r9927r9928
1010#ifndef TI99_DSK_H
1111#define TI99_DSK_H
1212
13#include "formats/flopimg.h"
13#include "imagedev/flopimg.h"
1414
1515FLOPPY_OPTIONS_EXTERN(ti99);
1616
src/mess/formats/mz_cas.h
r9927r9928
99#ifndef MZ_CAS_H
1010#define MZ_CAS_H
1111
12#include "formats/cassimg.h"
12#include "imagedev/cassimg.h"
1313
1414CASSETTE_FORMATLIST_EXTERN(mz700_cassette_formats);
1515
src/mess/formats/gtp_cas.h
r9927r9928
88#ifndef GTP_CAS_H
99#define GTP_CAS_H
1010
11#include "formats/cassimg.h"
11#include "imagedev/cassimg.h"
1212
1313CASSETTE_FORMATLIST_EXTERN(gtp_cassette_formats);
1414
src/mess/formats/ap2_dsk.h
r9927r9928
99#ifndef AP2_DISK_H
1010#define AP2_DISK_H
1111
12#include "formats/flopimg.h"
12#include "imagedev/flopimg.h"
1313
1414
1515/***************************************************************************
src/mess/formats/td0_dsk.c
r9927r9928
1414
1515#include <string.h>
1616#include "emu.h"
17#include "formats/flopimg.h"
18#include "devices/flopdrv.h"
17#include "imagedev/flopimg.h"
18#include "imagedev/flopdrv.h"
1919
2020struct td0dsk_tag
2121{
src/mess/formats/exidydsk.h
r9927r9928
99#ifndef EXI_DSK_H
1010#define EXI_DSK_H
1111
12#include "formats/flopimg.h"
12#include "imagedev/flopimg.h"
1313
1414/**************************************************************************/
1515
src/mess/formats/spec_snqk.h
r9927r9928
77#ifndef __SPEC_SNQK_H__
88#define __SPEC_SNQK_H__
99
10#include "devices/snapquik.h"
11#include "devices/cartslot.h"
10#include "imagedev/snapquik.h"
11#include "imagedev/cartslot.h"
1212
1313void spectrum_setup_sna(running_machine *machine, UINT8 *snapdata, UINT32 snapsize);
1414void spectrum_setup_z80(running_machine *machine, UINT8 *snapdata, UINT32 snapsize);
src/mess/formats/d81_dsk.h
r9927r9928
99#ifndef __D81_DSK__
1010#define __D81_DSK__
1111
12#include "formats/flopimg.h"
12#include "imagedev/flopimg.h"
1313
1414/***************************************************************************
1515    PROTOTYPES
src/mess/formats/sord_cas.h
r9927r9928
99#ifndef SORD_CAS_H
1010#define SORD_CAS_H
1111
12#include "formats/cassimg.h"
12#include "imagedev/cassimg.h"
1313
1414CASSETTE_FORMATLIST_EXTERN(sordm5_cassette_formats);
1515
src/mess/formats/vg5k_cas.h
r9927r9928
77#ifndef VG5K_CAS_H
88#define VG5K_CAS_H
99
10#include "formats/cassimg.h"
10#include "imagedev/cassimg.h"
1111
1212CASSETTE_FORMATLIST_EXTERN(vg5k_cassette_formats);
1313
src/mess/formats/cgen_cas.h
r9927r9928
99#ifndef __CGEN_CAS_H
1010#define __CGEN_CAS_H
1111
12#include "formats/cassimg.h"
12#include "imagedev/cassimg.h"
1313
1414CASSETTE_FORMATLIST_EXTERN(cgenie_cassette_formats);
1515
src/mess/formats/rk_cas.h
r9927r9928
88#ifndef RK_CAS_H
99#define RK_CAS_H
1010
11#include "formats/cassimg.h"
11#include "imagedev/cassimg.h"
1212
1313CASSETTE_FORMATLIST_EXTERN(rku_cassette_formats);
1414CASSETTE_FORMATLIST_EXTERN(rk8_cassette_formats);
src/mess/formats/comx35_comx.h
r9927r9928
1212#define __COMX35_COMX__
1313
1414#include "emu.h"
15#include "devices/snapquik.h"
15#include "imagedev/snapquik.h"
1616
1717QUICKLOAD_LOAD( comx35_comx );
1818
src/mess/formats/imd_dsk.c
r9927r9928
88
99#include <string.h>
1010#include "emu.h"
11#include "formats/flopimg.h"
12#include "devices/flopdrv.h"
11#include "imagedev/flopimg.h"
12#include "imagedev/flopdrv.h"
1313
1414struct imddsk_tag
1515{
src/mess/formats/timex_dck.h
r9927r9928
77#ifndef __TIMEX_DCK_H__
88#define __TIMEX_DCK_H__
99
10#include "devices/snapquik.h"
11#include "devices/cartslot.h"
10#include "imagedev/snapquik.h"
11#include "imagedev/cartslot.h"
1212
1313enum
1414{
src/mess/formats/coco_cas.h
r9927r9928
99#ifndef COCO_CAS_H
1010#define COCO_CAS_H
1111
12#include "formats/cassimg.h"
12#include "imagedev/cassimg.h"
1313
1414extern const struct CassetteFormat coco_cas_format;
1515extern const struct CassetteModulation coco_cas_modulation;
src/mess/formats/pmd_pmd.h
r9927r9928
99#ifndef PMD_PMD_H
1010#define PMD_PMD_H
1111
12#include "formats/cassimg.h"
12#include "imagedev/cassimg.h"
1313
1414CASSETTE_FORMATLIST_EXTERN(pmd85_pmd_format);
1515
src/mess/formats/kim1_cas.h
r9927r9928
99#ifndef __KIM1_CAS_H
1010#define __KIM1_CAS_H
1111
12#include "formats/cassimg.h"
12#include "imagedev/cassimg.h"
1313
1414CASSETTE_FORMATLIST_EXTERN(kim1_cassette_formats);
1515
src/mess/formats/oric_dsk.c
r9927r9928
1212#include "imageutl.h"
1313#include "formats/oric_dsk.h"
1414#include "formats/basicdsk.h"
15#include "devices/flopdrv.h"
15#include "imagedev/flopdrv.h"
1616
1717
1818#define mfm_disk_header_size   0x0100
src/mess/formats/oric_dsk.h
r9927r9928
99#ifndef ORIC_DSK_H
1010#define ORIC_DSK_H
1111
12#include "formats/flopimg.h"
12#include "imagedev/flopimg.h"
1313
1414/**************************************************************************/
1515
src/mess/formats/smx_dsk.h
r9927r9928
99#ifndef SMX_DSK_H
1010#define SMX_DSK_H
1111
12#include "formats/flopimg.h"
12#include "imagedev/flopimg.h"
1313
1414/**************************************************************************/
1515
src/mess/formats/a26_cas.h
r9927r9928
77#ifndef A26_CAS_H
88#define A26_CAS_H
99
10#include "formats/cassimg.h"
10#include "imagedev/cassimg.h"
1111
1212CASSETTE_FORMATLIST_EXTERN(a26_cassette_formats);
1313
src/mess/formats/basicdsk.h
r9927r9928
99#ifndef BASICDSK_H
1010#define BASICDSK_H
1111
12#include "formats/flopimg.h"
12#include "imagedev/flopimg.h"
1313
1414struct basicdsk_geometry
1515{
src/mess/formats/hect_tap.h
r9927r9928
99#ifndef HECT_TAP_H
1010#define HECT_TAP_H
1111
12#include "formats/cassimg.h"
12#include "imagedev/cassimg.h"
1313
1414CASSETTE_FORMATLIST_EXTERN(hector_cassette_formats);
1515
src/mess/formats/thom_cas.c
r9927r9928
99#include <math.h>
1010
1111#include "emu.h"
12#include "devices/cassette.h"
13#include "formats/cassimg.h"
12#include "imagedev/cassette.h"
13#include "imagedev/cassimg.h"
1414#include "includes/thomson.h"
1515#include "formats/thom_cas.h"
1616
src/mess/mess.mak
r9927r9928
424424   $(MESS_AUDIO)/lmc1992.o      \
425425   $(MESS_AUDIO)/mea8000.o      \
426426   $(MESS_AUDIO)/spchroms.o   \
427   $(MESS_DEVICES)/bitbngr.o   \
428   $(MESS_DEVICES)/cartslot.o   \
429   $(MESS_DEVICES)/cassette.o   \
430   $(MESS_DEVICES)/chd_cd.o   \
431427   $(MESS_FORMATS)/imd_dsk.o   \
432428   $(MESS_FORMATS)/ami_dsk.o   \
433429   $(MESS_FORMATS)/td0_dsk.o   \
r9927r9928
435431   $(MESS_FORMATS)/dsk_dsk.o   \
436432   $(MESS_FORMATS)/d88_dsk.o   \
437433   $(MESS_FORMATS)/fdi_dsk.o   \
438   $(MESS_DEVICES)/flopdrv.o   \
439   $(MESS_DEVICES)/harddriv.o   \
440434   $(MESS_DEVICES)/microdrv.o   \
441   $(MESS_DEVICES)/multcart.o   \
442   $(MESS_DEVICES)/printer.o   \
443   $(MESS_DEVICES)/snapquik.o   \
444   $(MESS_DEVICES)/z80bin.o   \
445435   $(MESS_FORMATS)/basicdsk.o   \
446   $(MESS_FORMATS)/cassimg.o   \
447436   $(MESS_FORMATS)/coco_cas.o   \
448437   $(MESS_FORMATS)/coco_dsk.o   \
449   $(MESS_FORMATS)/flopimg.o   \
450438   $(MESS_FORMATS)/pc_dsk.o   \
451439   $(MESS_FORMATS)/rk_cas.o   \
452   $(MESS_FORMATS)/wavfile.o   \
453440   $(MESS_MACHINE)/6551.o      \
454441   $(MESS_MACHINE)/68901mfp.o   \
455442   $(MESS_MACHINE)/74145.o      \
src/mess/drivers/vip.c
r9927r9928
222222#include "emu.h"
223223#include "includes/vip.h"
224224#include "cpu/cosmac/cosmac.h"
225#include "devices/cassette.h"
226#include "devices/snapquik.h"
225#include "imagedev/cassette.h"
226#include "imagedev/snapquik.h"
227227#include "audio/vp550.h"
228228#include "audio/vp595.h"
229229#include "sound/cdp1863.h"
src/mess/drivers/comquest.c
r9927r9928
4242#include "emu.h"
4343#include "cpu/m6805/m6805.h"
4444#include "includes/comquest.h"
45#include "devices/cartslot.h"
45#include "imagedev/cartslot.h"
4646
4747#ifdef UNUSED_FUNCTION
4848static  READ8_HANDLER(comquest_read)
src/mess/drivers/pb1000.c
r9927r9928
1616#include "emu.h"
1717#include "cpu/hd61700/hd61700.h"
1818#include "video/hd44352.h"
19#include "devices/cartslot.h"
19#include "imagedev/cartslot.h"
2020#include "machine/nvram.h"
2121#include "sound/beep.h"
2222
src/mess/drivers/dgn_beta.c
r9927r9928
4444#include "includes/dgn_beta.h"
4545#include "machine/6551.h"
4646#include "formats/coco_dsk.h"
47#include "devices/flopdrv.h"
47#include "imagedev/flopdrv.h"
4848#include "devices/coco_vhd.h"
4949#include "machine/ram.h"
5050
src/mess/drivers/elf.c
r9927r9928
1515#include "emu.h"
1616#include "includes/elf.h"
1717#include "cpu/cosmac/cosmac.h"
18#include "devices/cassette.h"
19#include "devices/snapquik.h"
18#include "imagedev/cassette.h"
19#include "imagedev/snapquik.h"
2020#include "machine/mm74c922.h"
2121#include "video/cdp1861.h"
2222#include "video/dm9368.h"
src/mess/drivers/jaguar.c
r9927r9928
7676#include "cpu/m68000/m68000.h"
7777#include "cpu/mips/r3000.h"
7878#include "cpu/jaguar/jaguar.h"
79#include "devices/cartslot.h"
80#include "devices/snapquik.h"
79#include "imagedev/cartslot.h"
80#include "imagedev/snapquik.h"
8181#include "sound/dac.h"
8282#include "machine/eeprom.h"
8383#include "includes/jaguar.h"
src/mess/drivers/bob85.c
r9927r9928
99
1010#include "emu.h"
1111#include "cpu/i8085/i8085.h"
12#include "devices/cassette.h"
12#include "imagedev/cassette.h"
1313#include "bob85.lh"
1414
1515
src/mess/drivers/pc8401a.c
r9927r9928
11#include "emu.h"
22#include "includes/pc8401a.h"
33#include "cpu/z80/z80.h"
4#include "devices/cartslot.h"
4#include "imagedev/cartslot.h"
55#include "machine/i8255a.h"
66#include "machine/msm8251.h"
77#include "machine/upd1990a.h"
src/mess/drivers/apple3.c
r9927r9928
1414#include "cpu/m6502/m6502.h"
1515#include "includes/apple3.h"
1616#include "includes/apple2.h"
17#include "devices/flopdrv.h"
17#include "imagedev/flopdrv.h"
1818#include "formats/ap2_dsk.h"
1919#include "machine/6551.h"
2020#include "machine/6522via.h"
src/mess/drivers/3do.c
r9927r9928
9393
9494#include "emu.h"
9595#include "includes/3do.h"
96#include "devices/chd_cd.h"
96#include "imagedev/chd_cd.h"
9797#include "cpu/arm/arm.h"
9898#include "cpu/arm7/arm7.h"
9999
src/mess/drivers/osbexec.c
r9927r9928
77#include "emu.h"
88#include "cpu/z80/z80.h"
99#include "cpu/z80/z80daisy.h"
10#include "devices/flopdrv.h"
10#include "imagedev/flopdrv.h"
1111#include "formats/basicdsk.h"
1212#include "sound/speaker.h"
1313#include "machine/wd17xx.h"
src/mess/drivers/dai.c
r9927r9928
6565#include "includes/dai.h"
6666#include "machine/pit8253.h"
6767#include "machine/tms5501.h"
68#include "devices/cassette.h"
68#include "imagedev/cassette.h"
6969#include "machine/ram.h"
7070
7171/* I/O ports */
src/mess/drivers/mc1000.c
r9927r9928
2323#include "emu.h"
2424#include "includes/mc1000.h"
2525#include "cpu/z80/z80.h"
26#include "devices/cassette.h"
26#include "imagedev/cassette.h"
2727#include "video/m6847.h"
2828#include "sound/ay8910.h"
2929#include "machine/ctronics.h"
src/mess/drivers/adam.c
r9927r9928
190190#include "video/tms9928a.h"
191191#include "includes/adam.h"
192192#include "cpu/m6800/m6800.h"
193#include "devices/cartslot.h"
194#include "devices/flopdrv.h"
193#include "imagedev/cartslot.h"
194#include "imagedev/flopdrv.h"
195195#include "formats/adam_dsk.h"
196196
197197static ADDRESS_MAP_START( adam_mem, ADDRESS_SPACE_PROGRAM, 8)
src/mess/drivers/unixpc.c
r9927r9928
1515#include "cpu/m68000/m68000.h"
1616#include "machine/ram.h"
1717#include "machine/wd17xx.h"
18#include "devices/flopdrv.h"
18#include "imagedev/flopdrv.h"
1919#include "unixpc.lh"
2020
2121
src/mess/drivers/mbee.c
r9927r9928
9494#include "cpu/z80/z80daisy.h"
9595#include "machine/mc146818.h"
9696#include "sound/wave.h"
97#include "devices/flopdrv.h"
97#include "imagedev/flopdrv.h"
9898#include "formats/basicdsk.h"
9999#include "includes/mbee.h"
100100#define XTAL_13_5MHz 13500000
src/mess/drivers/pc6001.c
r9927r9928
129129#include "sound/ay8910.h"
130130#include "sound/wave.h"
131131
132#include "devices/cassette.h"
133#include "devices/cartslot.h"
132#include "imagedev/cassette.h"
133#include "imagedev/cartslot.h"
134134#include "formats/p6001_cas.h"
135135
136136
src/mess/drivers/pokemini.c
r9927r9928
1212#include "machine/i2cmem.h"
1313#include "includes/pokemini.h"
1414#include "cpu/minx/minx.h"
15#include "devices/cartslot.h"
15#include "imagedev/cartslot.h"
1616
1717
1818static ADDRESS_MAP_START( pokemini_mem_map, ADDRESS_SPACE_PROGRAM, 8 )
src/mess/drivers/coco.c
r9927r9928
3535#include "machine/6551.h"
3636#include "formats/coco_dsk.h"
3737#include "formats/coco_cas.h"
38#include "devices/printer.h"
39#include "devices/flopdrv.h"
40#include "devices/cassette.h"
41#include "devices/bitbngr.h"
42#include "devices/snapquik.h"
43#include "devices/cartslot.h"
38#include "imagedev/printer.h"
39#include "imagedev/flopdrv.h"
40#include "imagedev/cassette.h"
41#include "imagedev/bitbngr.h"
42#include "imagedev/snapquik.h"
43#include "imagedev/cartslot.h"
4444#include "devices/cococart.h"
4545#include "devices/coco_vhd.h"
4646#include "sound/ay8910.h"
src/mess/drivers/mycom.c
r9927r9928
5050#include "video/mc6845.h"
5151#include "machine/i8255a.h"
5252#include "sound/sn76496.h"
53#include "devices/cassette.h"
53#include "imagedev/cassette.h"
5454#include "sound/wave.h"
5555#include "machine/wd17xx.h"
56#include "devices/flopdrv.h"
56#include "imagedev/flopdrv.h"
5757#include "formats/basicdsk.h"
5858
5959
src/mess/drivers/ti99_8.c
r9927r9928
196196//#include "video/tms9928a.h"
197197#include "sound/wave.h"
198198#include "machine/tms9901.h"
199#include "devices/cassette.h"
199#include "imagedev/cassette.h"
200200
201201#include "machine/ti99/tiboard.h"
202202
src/mess/drivers/spc1000.c
r9927r9928
1212#include "video/m6847.h"
1313#include "sound/ay8910.h"
1414#include "sound/wave.h"
15#include "devices/cassette.h"
15#include "imagedev/cassette.h"
1616#include "machine/ram.h"
1717
1818
src/mess/drivers/vii.c
r9927r9928
4040
4141#include "emu.h"
4242#include "cpu/unsp/unsp.h"
43#include "devices/cartslot.h"
43#include "imagedev/cartslot.h"
4444#include "machine/i2cmem.h"
4545
4646#define PAGE_ENABLE_MASK      0x0008
src/mess/drivers/x1.c
r9927r9928
196196#include "sound/wave.h"
197197
198198#include "machine/wd17xx.h"
199#include "devices/cassette.h"
200#include "devices/flopdrv.h"
201#include "formats/flopimg.h"
199#include "imagedev/cassette.h"
200#include "imagedev/flopdrv.h"
201#include "imagedev/flopimg.h"
202202#include "formats/basicdsk.h"
203203#include "formats/x1_tap.h"
204#include "devices/cartslot.h"
204#include "imagedev/cartslot.h"
205205#include "includes/x1.h"
206206//#include <ctype.h>
207207
src/mess/drivers/gb.c
r9927r9928
438438#include "emu.h"
439439#include "machine/ram.h"
440440#include "cpu/lr35902/lr35902.h"
441#include "devices/cartslot.h"
441#include "imagedev/cartslot.h"
442442#include "rendlay.h"
443443#include "audio/gb.h"
444444#include "includes/gb.h"
src/mess/drivers/xor100.c
r9927r9928
2121#include "emu.h"
2222#include "cpu/z80/z80.h"
2323#include "formats/basicdsk.h"
24#include "devices/flopdrv.h"
24#include "imagedev/flopdrv.h"
2525#include "machine/ram.h"
2626#include "machine/com8116.h"
2727#include "machine/ctronics.h"
src/mess/drivers/d6800.c
r9927r9928
3535#include "emu.h"
3636#include "cpu/m6800/m6800.h"
3737#include "sound/beep.h"
38#include "devices/cassette.h"
38#include "imagedev/cassette.h"
3939#include "sound/wave.h"
4040#include "sound/speaker.h"
4141#include "machine/6821pia.h"
src/mess/drivers/kim1.c
r9927r9928
8383#include "cpu/m6502/m6502.h"
8484#include "sound/dac.h"
8585#include "machine/mos6530.h"
86#include "devices/cassette.h"
86#include "imagedev/cassette.h"
8787#include "formats/kim1_cas.h"
8888#include "kim1.lh"
8989
src/mess/drivers/gamecom.c
r9927r9928
1818#include "emu.h"
1919#include "includes/gamecom.h"
2020#include "cpu/sm8500/sm8500.h"
21#include "devices/cartslot.h"
21#include "imagedev/cartslot.h"
2222
2323
2424static ADDRESS_MAP_START(gamecom_mem_map, ADDRESS_SPACE_PROGRAM, 8)
src/mess/drivers/tmc600.c
r9927r9928
8383
8484#include "emu.h"
8585#include "machine/ctronics.h"
86#include "devices/flopdrv.h"
86#include "imagedev/flopdrv.h"
8787#include "formats/basicdsk.h"
88#include "devices/cassette.h"
89#include "devices/snapquik.h"
88#include "imagedev/cassette.h"
89#include "imagedev/snapquik.h"
9090#include "cpu/cosmac/cosmac.h"
9191#include "sound/cdp1869.h"
9292#include "includes/tmc600.h"
src/mess/drivers/radio86.c
r9927r9928
1313#include "machine/i8255a.h"
1414#include "machine/i8257.h"
1515#include "video/i8275.h"
16#include "devices/cassette.h"
17#include "devices/cartslot.h"
16#include "imagedev/cassette.h"
17#include "imagedev/cartslot.h"
1818#include "formats/rk_cas.h"
1919#include "includes/radio86.h"
2020
src/mess/drivers/advision.c
r9927r9928
2222#include "includes/advision.h"
2323#include "cpu/mcs48/mcs48.h"
2424#include "cpu/cop400/cop400.h"
25#include "devices/cartslot.h"
25#include "imagedev/cartslot.h"
2626#include "sound/dac.h"
2727
2828/* Memory Maps */
src/mess/drivers/b2m.c
r9927r9928
99
1010#include "emu.h"
1111#include "cpu/i8085/i8085.h"
12#include "devices/cassette.h"
12#include "imagedev/cassette.h"
1313#include "machine/i8255a.h"
1414#include "machine/pit8253.h"
1515#include "machine/pic8259.h"
1616#include "machine/msm8251.h"
1717#include "machine/wd17xx.h"
18#include "devices/flopdrv.h"
18#include "imagedev/flopdrv.h"
1919#include "formats/basicdsk.h"
2020#include "machine/ram.h"
2121#include "includes/b2m.h"
src/mess/drivers/aim65.c
r9927r9928
1919#include "machine/6522via.h"
2020#include "machine/6532riot.h"
2121#include "machine/6821pia.h"
22#include "devices/cartslot.h"
22#include "imagedev/cartslot.h"
2323#include "machine/ram.h"
2424#include "aim65.lh"
2525
src/mess/drivers/vic20.c
r9927r9928
7676#include "includes/cbm.h"
7777#include "formats/cbm_snqk.h"
7878#include "cpu/m6502/m6502.h"
79#include "devices/cartslot.h"
79#include "imagedev/cartslot.h"
8080#include "machine/ram.h"
8181#include "machine/6522via.h"
8282#include "machine/c1541.h"
src/mess/drivers/arcadia.c
r9927r9928
121121#include "emu.h"
122122#include "cpu/s2650/s2650.h"
123123#include "includes/arcadia.h"
124#include "devices/cartslot.h"
124#include "imagedev/cartslot.h"
125125
126126static ADDRESS_MAP_START( arcadia_mem, ADDRESS_SPACE_PROGRAM, 8)
127127   AM_RANGE( 0x0000, 0x0fff) AM_ROM
src/mess/drivers/tm990189.c
r9927r9928
4242#include "machine/tms9901.h"
4343#include "machine/tms9902.h"
4444#include "video/tms9928a.h"
45#include "devices/cassette.h"
45#include "imagedev/cassette.h"
4646#include "sound/speaker.h"
4747#include "sound/wave.h"
4848#include "machine/serial.h"
src/mess/drivers/smc777.c
r9927r9928
2020
2121#include "machine/wd17xx.h"
2222#include "formats/basicdsk.h"
23#include "devices/flopdrv.h"
23#include "imagedev/flopdrv.h"
2424
2525
2626class smc777_state : public driver_device
src/mess/drivers/thomson.c
r9927r9928
7272#include "machine/6821pia.h"
7373#include "machine/wd17xx.h"
7474#include "machine/ctronics.h"
75#include "devices/flopdrv.h"
75#include "imagedev/flopdrv.h"
7676#include "formats/basicdsk.h"
7777#include "machine/ram.h"
7878#include "machine/serial.h"
src/mess/drivers/scorpion.c
r9927r9928
146146
147147#include "emu.h"
148148#include "includes/spectrum.h"
149#include "devices/snapquik.h"
150#include "devices/cartslot.h"
151#include "devices/cassette.h"
149#include "imagedev/snapquik.h"
150#include "imagedev/cartslot.h"
151#include "imagedev/cassette.h"
152152#include "sound/ay8910.h"
153153#include "sound/speaker.h"
154154#include "formats/tzx_cas.h"
src/mess/drivers/abc80.c
r9927r9928
181181#include "emu.h"
182182#include "cpu/z80/z80.h"
183183#include "cpu/z80/z80daisy.h"
184#include "devices/cassette.h"
185#include "devices/flopdrv.h"
184#include "imagedev/cassette.h"
185#include "imagedev/flopdrv.h"
186186#include "machine/ram.h"
187#include "devices/printer.h"
187#include "imagedev/printer.h"
188188#include "machine/abcbus.h"
189189#include "machine/abc830.h"
190190#include "machine/rs232.h"
src/mess/drivers/pmd85.c
r9927r9928
172172#include "emu.h"
173173#include "cpu/i8085/i8085.h"
174174#include "sound/wave.h"
175#include "devices/cassette.h"
175#include "imagedev/cassette.h"
176176#include "includes/pmd85.h"
177177#include "machine/i8255a.h"
178178#include "machine/pit8253.h"
src/mess/drivers/spectrum.c
r9927r9928
274274#include "sound/speaker.h"
275275#include "sound/wave.h"
276276#include "includes/spectrum.h"
277#include "devices/snapquik.h"
278#include "devices/cartslot.h"
279#include "devices/cassette.h"
277#include "imagedev/snapquik.h"
278#include "imagedev/cartslot.h"
279#include "imagedev/cassette.h"
280280#include "machine/ram.h"
281281#include "formats/tzx_cas.h"
282282#include "formats/spec_snqk.h"
src/mess/drivers/mpf1.c
r9927r9928
3333#include "audio/spchroms.h"
3434#include "sound/speaker.h"
3535#include "sound/tms5220.h"
36#include "devices/cassette.h"
36#include "imagedev/cassette.h"
3737#include "mpf1.lh"
3838#include "mpf1b.lh"
3939#include "mpf1p.lh"
src/mess/drivers/astrocde.c
r9927r9928
1010#include "cpu/z80/z80.h"
1111#include "includes/astrocde.h"
1212#include "sound/astrocde.h"
13#include "devices/cartslot.h"
13#include "imagedev/cartslot.h"
1414
1515
1616/*************************************
src/mess/drivers/atarist.c
r9927r9928
44#include "cpu/m6800/m6800.h"
55#include "audio/lmc1992.h"
66#include "formats/atarist_dsk.h"
7#include "devices/cartslot.h"
8#include "devices/flopdrv.h"
7#include "imagedev/cartslot.h"
8#include "imagedev/flopdrv.h"
99#include "machine/ram.h"
1010#include "machine/6850acia.h"
1111#include "machine/68901mfp.h"
src/mess/drivers/sg1000.c
r9927r9928
6666
6767#include "emu.h"
6868#include "cpu/z80/z80.h"
69#include "devices/flopdrv.h"
70#include "devices/cartslot.h"
71#include "devices/cassette.h"
69#include "imagedev/flopdrv.h"
70#include "imagedev/cartslot.h"
71#include "imagedev/cassette.h"
7272#include "machine/ram.h"
73#include "devices/printer.h"
73#include "imagedev/printer.h"
7474#include "formats/basicdsk.h"
7575#include "machine/ctronics.h"
7676#include "machine/i8255a.h"
src/mess/drivers/ip22.c
r9927r9928
5252#include "machine/pcshare.h"
5353#include "video/newport.h"
5454#include "machine/wd33c93.h"
55#include "devices/harddriv.h"
56#include "devices/chd_cd.h"
55#include "imagedev/harddriv.h"
56#include "imagedev/chd_cd.h"
5757#include "sound/dac.h"
5858
5959
src/mess/drivers/eti660.c
r9927r9928
1212#include "emu.h"
1313#include "includes/eti660.h"
1414#include "cpu/cosmac/cosmac.h"
15#include "devices/cassette.h"
15#include "imagedev/cassette.h"
1616#include "machine/ram.h"
1717#include "machine/6821pia.h"
1818#include "machine/rescap.h"
src/mess/drivers/px8.c
r9927r9928
3131#include "includes/px8.h"
3232#include "cpu/z80/z80.h"
3333#include "cpu/m6800/m6800.h"
34#include "devices/cartslot.h"
35#include "devices/cassette.h"
34#include "imagedev/cartslot.h"
35#include "imagedev/cassette.h"
3636#include "machine/ram.h"
3737#include "machine/msm8251.h"
3838#include "machine/pf10.h"
src/mess/drivers/phc25.c
r9927r9928
4444#include "emu.h"
4545#include "includes/phc25.h"
4646#include "cpu/z80/z80.h"
47#include "devices/cassette.h"
47#include "imagedev/cassette.h"
4848#include "machine/ram.h"
4949#include "machine/ctronics.h"
5050#include "video/m6847.h"
src/mess/drivers/mikromik.c
r9927r9928
22
33#include "emu.h"
44#include "formats/basicdsk.h"
5#include "devices/flopdrv.h"
5#include "imagedev/flopdrv.h"
66#include "cpu/i8085/i8085.h"
77#include "machine/8237dma.h"
88#include "machine/i8212.h"
src/mess/drivers/spec128.c
r9927r9928
151151#include "emu.h"
152152#include "cpu/z80/z80.h"
153153#include "includes/spectrum.h"
154#include "devices/snapquik.h"
155#include "devices/cartslot.h"
156#include "devices/cassette.h"
154#include "imagedev/snapquik.h"
155#include "imagedev/cartslot.h"
156#include "imagedev/cassette.h"
157157#include "sound/ay8910.h"
158158#include "sound/speaker.h"
159159#include "formats/tzx_cas.h"
src/mess/drivers/a2600.c
r9927r9928
99#include "cpu/m6502/m6502.h"
1010#include "sound/wave.h"
1111#include "sound/tiaintf.h"
12#include "devices/cartslot.h"
13#include "devices/cassette.h"
12#include "imagedev/cartslot.h"
13#include "imagedev/cassette.h"
1414#include "formats/a26_cas.h"
1515#include "video/tia.h"
1616
src/mess/drivers/pcw.c
r9927r9928
9898#include "machine/i8243.h"
9999// upd765 interface
100100#include "machine/upd765.h"
101#include "devices/flopdrv.h"
101#include "imagedev/flopdrv.h"
102102// pcw video hardware
103103#include "includes/pcw.h"
104104// pcw/pcw16 beeper
src/mess/drivers/studio2.c
r9927r9928
198198#include "emu.h"
199199#include "includes/studio2.h"
200200#include "cpu/cosmac/cosmac.h"
201#include "devices/cartslot.h"
201#include "imagedev/cartslot.h"
202202#include "formats/studio2_st2.h"
203203#include "sound/beep.h"
204204#include "sound/cdp1864.h"
src/mess/drivers/osi.c
r9927r9928
183183#include "machine/6821pia.h"
184184#include "sound/discrete.h"
185185#include "sound/beep.h"
186#include "devices/flopdrv.h"
186#include "imagedev/flopdrv.h"
187187#include "formats/basicdsk.h"
188#include "devices/cassette.h"
188#include "imagedev/cassette.h"
189189#include "machine/ram.h"
190190
191191/* Sound */
src/mess/drivers/oric.c
r9927r9928
2121#include "sound/wave.h"
2222#include "includes/oric.h"
2323#include "machine/ctronics.h"
24#include "devices/flopdrv.h"
25#include "devices/cassette.h"
24#include "imagedev/flopdrv.h"
25#include "imagedev/cassette.h"
2626#include "formats/oric_dsk.h"
2727#include "formats/ap2_dsk.h"
2828#include "formats/oric_tap.h"
src/mess/drivers/pippin.c
r9927r9928
3030
3131#include "emu.h"
3232#include "cpu/powerpc/ppc.h"
33#include "devices/chd_cd.h"
33#include "imagedev/chd_cd.h"
3434#include "sound/cdda.h"
3535
3636
src/mess/drivers/orao.c
r9927r9928
1515#include "sound/dac.h"
1616#include "sound/wave.h"
1717#include "includes/orao.h"
18#include "devices/cassette.h"
18#include "imagedev/cassette.h"
1919#include "formats/orao_cas.h"
2020
2121/* Address maps */
src/mess/drivers/mekd2.c
r9927r9928
3737#include "sound/dac.h"
3838#include "machine/6821pia.h"
3939#include "machine/6850acia.h"
40#include "devices/cartslot.h"
40#include "imagedev/cartslot.h"
4141#include "includes/mekd2.h"
4242
4343#define XTAL_MEKD2 1228800
src/mess/drivers/at.c
r9927r9928
4444
4545#include "machine/pcshare.h"
4646
47#include "devices/flopdrv.h"
48#include "devices/harddriv.h"
47#include "imagedev/flopdrv.h"
48#include "imagedev/harddriv.h"
4949#include "formats/pc_dsk.h"
5050
5151#include "machine/8237dma.h"
src/mess/drivers/ssem.c
r9927r9928
66
77#include "emu.h"
88#include "cpu/ssem/ssem.h"
9#include "devices/cartslot.h"
9#include "imagedev/cartslot.h"
1010#include <stdarg.h>
1111
1212
src/mess/drivers/vector06.c
r9927r9928
1313#include "sound/wave.h"
1414#include "machine/i8255a.h"
1515#include "machine/wd17xx.h"
16#include "devices/cassette.h"
17#include "devices/cartslot.h"
18#include "devices/flopdrv.h"
16#include "imagedev/cassette.h"
17#include "imagedev/cartslot.h"
18#include "imagedev/flopdrv.h"
1919#include "formats/basicdsk.h"
2020#include "includes/vector06.h"
2121#include "machine/ram.h"
src/mess/drivers/electron.c
r9927r9928
2525#include "emu.h"
2626#include "cpu/m6502/m6502.h"
2727#include "includes/electron.h"
28#include "devices/cassette.h"
28#include "imagedev/cassette.h"
2929#include "formats/uef_cas.h"
3030#include "sound/beep.h"
3131
src/mess/drivers/v1050.c
r9927r9928
109109#include "cpu/z80/z80.h"
110110#include "cpu/m6502/m6502.h"
111111#include "cpu/mcs48/mcs48.h"
112#include "devices/flopdrv.h"
112#include "imagedev/flopdrv.h"
113113#include "machine/ram.h"
114114#include "formats/basicdsk.h"
115115#include "machine/ctronics.h"
src/mess/drivers/ql.c
r9927r9928
4545#include "cpu/m68000/m68000.h"
4646#include "cpu/mcs48/mcs48.h"
4747#include "cpu/mcs51/mcs51.h"
48#include "devices/cartslot.h"
49#include "devices/flopdrv.h"
48#include "imagedev/cartslot.h"
49#include "imagedev/flopdrv.h"
5050#include "machine/ram.h"
5151#include "devices/microdrv.h"
5252#include "formats/basicdsk.h"
src/mess/drivers/mikrosha.c
r9927r9928
1414#include "machine/i8257.h"
1515#include "machine/pit8253.h"
1616#include "video/i8275.h"
17#include "devices/cassette.h"
17#include "imagedev/cassette.h"
1818#include "formats/rk_cas.h"
1919#include "includes/radio86.h"
2020
src/mess/drivers/amiga.c
r9927r9928
3535#include "sound/cdda.h"
3636
3737/* Devices */
38#include "devices/chd_cd.h"
39#include "devices/cartslot.h"
38#include "imagedev/chd_cd.h"
39#include "imagedev/cartslot.h"
4040
4141
4242static READ8_DEVICE_HANDLER( amiga_cia_0_portA_r );
src/mess/drivers/abc80x.c
r9927r9928
240240#include "cpu/z80/z80.h"
241241#include "cpu/z80/z80daisy.h"
242242#include "cpu/mcs48/mcs48.h"
243#include "devices/cassette.h"
244#include "devices/printer.h"
243#include "imagedev/cassette.h"
244#include "imagedev/printer.h"
245245#include "machine/ram.h"
246246#include "machine/z80ctc.h"
247247#include "machine/z80dart.h"
src/mess/drivers/orion.c
r9927r9928
1616#include "sound/wave.h"
1717#include "machine/mc146818.h"
1818#include "machine/wd17xx.h"
19#include "devices/flopdrv.h"
19#include "imagedev/flopdrv.h"
2020#include "formats/basicdsk.h"
21#include "devices/cassette.h"
22#include "devices/cartslot.h"
21#include "imagedev/cassette.h"
22#include "imagedev/cartslot.h"
2323#include "formats/rk_cas.h"
2424#include "includes/orion.h"
2525#include "machine/ram.h"
src/mess/drivers/tmc1800.c
r9927r9928
116116#include "cpu/cosmac/cosmac.h"
117117#include "video/cdp1861.h"
118118#include "sound/cdp1864.h"
119#include "devices/cassette.h"
120#include "devices/snapquik.h"
119#include "imagedev/cassette.h"
120#include "imagedev/snapquik.h"
121121#include "machine/rescap.h"
122122#include "sound/beep.h"
123123#include "machine/ram.h"
src/mess/drivers/crvision.c
r9927r9928
128128#include "emu.h"
129129#include "includes/crvision.h"
130130#include "cpu/m6502/m6502.h"
131#include "devices/cartslot.h"
132#include "devices/cassette.h"
133#include "devices/flopdrv.h"
131#include "imagedev/cartslot.h"
132#include "imagedev/cassette.h"
133#include "imagedev/flopdrv.h"
134134#include "formats/basicdsk.h"
135135#include "machine/ctronics.h"
136136#include "machine/6821pia.h"
src/mess/drivers/bk.c
r9927r9928
1111#include "cpu/t11/t11.h"
1212#include "sound/wave.h"
1313#include "includes/bk.h"
14#include "devices/cassette.h"
14#include "imagedev/cassette.h"
1515#include "formats/rk_cas.h"
1616
1717  /* Address maps */
src/mess/drivers/fmtowns.c
r9927r9928
116116#include "sound/2612intf.h"
117117#include "sound/rf5c68.h"
118118#include "sound/cdda.h"
119#include "devices/chd_cd.h"
119#include "imagedev/chd_cd.h"
120120#include "machine/pit8253.h"
121121#include "machine/pic8259.h"
122122#include "formats/basicdsk.h"
123123#include "machine/wd17xx.h"
124#include "devices/flopdrv.h"
124#include "imagedev/flopdrv.h"
125125#include "machine/upd71071.h"
126126#include "machine/ram.h"
127127#include "includes/fmtowns.h"
128128#include "machine/nvram.h"
129#include "devices/harddriv.h"
129#include "imagedev/harddriv.h"
130130#include "machine/scsi.h"
131131#include "machine/fm_scsi.h"
132132
src/mess/drivers/mz2500.c
r9927r9928
5454#include "sound/beep.h"
5555#include "machine/rp5c15.h"
5656
57//#include "devices/cassette.h"
58#include "devices/flopdrv.h"
59#include "formats/flopimg.h"
57//#include "imagedev/cassette.h"
58#include "imagedev/flopdrv.h"
59#include "imagedev/flopimg.h"
6060#include "formats/basicdsk.h"
6161
6262
src/mess/drivers/a7800.c
r9927r9928
1717#include "cpu/m6502/m6502.h"
1818#include "sound/pokey.h"
1919#include "sound/tiaintf.h"
20#include "devices/cartslot.h"
20#include "imagedev/cartslot.h"
2121#include "machine/6532riot.h"
2222#include "includes/a7800.h"
2323
src/mess/drivers/nascom1.c
r9927r9928
5959#include "machine/z80pio.h"
6060
6161/* Devices */
62#include "devices/flopdrv.h"
62#include "imagedev/flopdrv.h"
6363#include "formats/basicdsk.h"
64#include "devices/cartslot.h"
65#include "devices/cassette.h"
64#include "imagedev/cartslot.h"
65#include "imagedev/cassette.h"
6666#include "machine/ram.h"
6767
6868
src/mess/drivers/gmaster.c
r9927r9928
44
55#include "emu.h"
66#include "cpu/upd7810/upd7810.h"
7#include "devices/cartslot.h"
7#include "imagedev/cartslot.h"
88
99#include "includes/gmaster.h"
1010
src/mess/drivers/newbrain.c
r9927r9928
99#include "machine/z80sio.h"
1010#include "includes/newbrain.h"
1111#include "machine/serial.h"
12#include "devices/flopdrv.h"
12#include "imagedev/flopdrv.h"
1313#include "formats/basicdsk.h"
14#include "devices/cassette.h"
14#include "imagedev/cassette.h"
1515#include "machine/rescap.h"
1616#include "machine/ram.h"
1717#include "newbrain.lh"
src/mess/drivers/microtan.c
r9927r9928
4848#include "machine/6551.h"
4949
5050/* Devices */
51#include "devices/cassette.h"
51#include "imagedev/cassette.h"
5252#include "formats/m65_snqk.h"
5353
5454
src/mess/drivers/einstein.c
r9927r9928
5757#include "machine/wd17xx.h"
5858#include "machine/ctronics.h"
5959#include "machine/msm8251.h"
60#include "devices/flopdrv.h"
60#include "imagedev/flopdrv.h"
6161#include "sound/ay8910.h"
6262#include "video/mc6845.h"
6363#include "rendlay.h"
src/mess/drivers/vboy.c
r9927r9928
1515
1616#include "emu.h"
1717#include "cpu/v810/v810.h"
18#include "devices/cartslot.h"
18#include "imagedev/cartslot.h"
1919#include "vboy.lh"
2020
2121typedef struct _vboy_regs_t vboy_regs_t;
src/mess/drivers/bullet.c
r9927r9928
6060
6161#include "emu.h"
6262#include "cpu/z80/z80.h"
63#include "devices/flopdrv.h"
63#include "imagedev/flopdrv.h"
6464#include "machine/ram.h"
6565#include "machine/ctronics.h"
6666#include "machine/terminal.h"
src/mess/drivers/osborne1.c
r9927r9928
3838#include "cpu/z80/z80.h"
3939#include "cpu/z80/z80daisy.h"
4040#include "sound/beep.h"
41#include "devices/flopdrv.h"
41#include "imagedev/flopdrv.h"
4242#include "formats/basicdsk.h"
4343#include "machine/wd17xx.h"
4444#include "machine/6821pia.h"
src/mess/drivers/vtech1.c
r9927r9928
118118#include "machine/ctronics.h"
119119#include "sound/wave.h"
120120#include "sound/speaker.h"
121#include "devices/cartslot.h"
122#include "devices/flopdrv.h"
123#include "devices/snapquik.h"
124#include "devices/cassette.h"
125#include "devices/z80bin.h"
121#include "imagedev/cartslot.h"
122#include "imagedev/flopdrv.h"
123#include "imagedev/snapquik.h"
124#include "imagedev/cassette.h"
126125#include "machine/ram.h"
127126#include "formats/vt_cas.h"
128127
src/mess/drivers/amstrad.c
r9927r9928
9898#include "machine/ctronics.h"
9999
100100/* Devices */
101#include "devices/flopdrv.h"
101#include "imagedev/flopdrv.h"
102102#include "formats/basicdsk.h"
103103#include "formats/msx_dsk.h"
104#include "devices/snapquik.h"
105#include "devices/cartslot.h"
106#include "devices/cassette.h"
104#include "imagedev/snapquik.h"
105#include "imagedev/cartslot.h"
106#include "imagedev/cassette.h"
107107#include "formats/tzx_cas.h"
108108
109109#include "machine/ram.h"
src/mess/drivers/ng_aes.c
r9927r9928
3535#include "cpu/z80/z80.h"
3636#include "sound/2610intf.h"
3737#include "devices/aescart.h"
38#include "devices/cartslot.h"
38#include "imagedev/cartslot.h"
3939
4040#include "neogeo.lh"
4141
src/mess/drivers/kyocera.c
r9927r9928
6565#include "emu.h"
6666#include "includes/kyocera.h"
6767#include "cpu/i8085/i8085.h"
68#include "devices/cartslot.h"
69#include "devices/cassette.h"
68#include "imagedev/cartslot.h"
69#include "imagedev/cassette.h"
7070#include "machine/ram.h"
7171#include "machine/ctronics.h"
7272#include "machine/upd1990a.h"
src/mess/drivers/cdi.c
r9927r9928
2626#include "emu.h"
2727#include "cpu/m68000/m68000.h"
2828#include "sound/dmadac.h"
29#include "devices/chd_cd.h"
29#include "imagedev/chd_cd.h"
3030#include "machine/timekpr.h"
3131#include "sound/cdda.h"
3232#include "includes/cdi.h"
src/mess/drivers/sms.c
r9927r9928
6666#include "sound/2413intf.h"
6767#include "includes/sms.h"
6868#include "video/smsvdp.h"
69#include "devices/cartslot.h"
69#include "imagedev/cartslot.h"
7070
7171#include "sms1.lh"
7272
src/mess/drivers/poly88.c
r9927r9928
88
99#include "emu.h"
1010#include "cpu/i8085/i8085.h"
11#include "devices/cassette.h"
11#include "imagedev/cassette.h"
1212#include "sound/wave.h"
1313#include "includes/poly88.h"
1414
src/mess/drivers/psx.c
r9927r9928
1414
1515#include "emu.h"
1616#include "cpu/mips/psx.h"
17#include "devices/snapquik.h"
18#include "devices/chd_cd.h"
17#include "imagedev/snapquik.h"
18#include "imagedev/chd_cd.h"
1919#include "includes/psx.h"
2020#include "sound/psx.h"
2121#include "debugger.h"
src/mess/drivers/samcoupe.c
r9927r9928
4141#include "sound/speaker.h"
4242
4343/* devices */
44#include "devices/cassette.h"
44#include "imagedev/cassette.h"
4545#include "formats/tzx_cas.h"
46#include "devices/flopdrv.h"
46#include "imagedev/flopdrv.h"
4747#include "formats/coupedsk.h"
4848#include "machine/ram.h"
4949
src/mess/drivers/tutor.c
r9927r9928
162162#include "cpu/tms9900/tms9900.h"
163163#include "sound/wave.h"
164164#include "video/tms9928a.h"
165#include "devices/cartslot.h"
166#include "devices/cassette.h"
165#include "imagedev/cartslot.h"
166#include "imagedev/cassette.h"
167167#include "sound/sn76496.h"
168168#include "machine/ctronics.h"
169169
src/mess/drivers/comx35.c
r9927r9928
1717#include "cpu/cosmac/cosmac.h"
1818#include "sound/cdp1869.h"
1919#include "sound/wave.h"
20#include "devices/flopdrv.h"
20#include "imagedev/flopdrv.h"
2121#include "formats/comx35_dsk.h"
2222#include "formats/comx35_comx.h"
23#include "devices/cassette.h"
24#include "devices/printer.h"
25#include "devices/snapquik.h"
23#include "imagedev/cassette.h"
24#include "imagedev/printer.h"
25#include "imagedev/snapquik.h"
2626#include "machine/cdp1871.h"
2727#include "machine/wd17xx.h"
2828#include "machine/ram.h"
src/mess/drivers/trs80.c
r9927r9928
152152#include "sound/speaker.h"
153153
154154/* Devices */
155#include "devices/flopdrv.h"
155#include "imagedev/flopdrv.h"
156156#include "formats/trs_dsk.h"
157#include "devices/cassette.h"
157#include "imagedev/cassette.h"
158158#include "formats/trs_cas.h"
159159#include "formats/trs_cmd.h"
160160
src/mess/drivers/jtc.c
r9927r9928
99#include "emu.h"
1010#include "includes/jtc.h"
1111#include "cpu/z8/z8.h"
12#include "devices/cassette.h"
12#include "imagedev/cassette.h"
1313#include "machine/ctronics.h"
1414#include "sound/speaker.h"
1515#include "sound/wave.h"
src/mess/drivers/tiki100.c
r9927r9928
2727#include "includes/tiki100.h"
2828#include "cpu/z80/z80.h"
2929#include "cpu/z80/z80daisy.h"
30#include "devices/flopdrv.h"
30#include "imagedev/flopdrv.h"
3131#include "formats/basicdsk.h"
3232#include "machine/z80ctc.h"
3333#include "machine/z80dart.h"
src/mess/drivers/atm.c
r9927r9928
11#include "emu.h"
22#include "includes/spectrum.h"
3#include "devices/snapquik.h"
4#include "devices/cartslot.h"
5#include "devices/cassette.h"
3#include "imagedev/snapquik.h"
4#include "imagedev/cartslot.h"
5#include "imagedev/cassette.h"
66#include "sound/ay8910.h"
77#include "sound/speaker.h"
88#include "machine/wd17xx.h"
src/mess/drivers/odyssey2.c
r9927r9928
1212#include "emu.h"
1313#include "cpu/mcs48/mcs48.h"
1414#include "includes/odyssey2.h"
15#include "devices/cartslot.h"
15#include "imagedev/cartslot.h"
1616#include "sound/sp0256.h"
1717
1818static ADDRESS_MAP_START( odyssey2_mem , ADDRESS_SPACE_PROGRAM, 8)
src/mess/drivers/primo.c
r9927r9928
109109#include "sound/wave.h"
110110#include "includes/primo.h"
111111#include "cpu/z80/z80.h"
112#include "devices/cassette.h"
113#include "devices/snapquik.h"
114#include "devices/cartslot.h"
112#include "imagedev/cassette.h"
113#include "imagedev/snapquik.h"
114#include "imagedev/cartslot.h"
115115#include "formats/primoptp.h"
116116#include "machine/cbmiec.h"
117117
src/mess/drivers/pockstat.c
r9927r9928
3131#include "emu.h"
3232#include "cpu/arm7/arm7.h"
3333#include "cpu/arm7/arm7core.h"
34#include "devices/cartslot.h"
34#include "imagedev/cartslot.h"
3535#include "sound/dac.h"
3636
3737#define MAX_PS_TIMERS   3
src/mess/drivers/ti85.c
r9927r9928
189189#include "cpu/z80/z80.h"
190190#include "sound/speaker.h"
191191#include "includes/ti85.h"
192#include "devices/snapquik.h"
192#include "imagedev/snapquik.h"
193193#include "formats/ti85_ser.h"
194194#include "machine/nvram.h"
195195
src/mess/drivers/casloopy.c
r9927r9928
141141#include "emu.h"
142142#include "cpu/sh2/sh2.h"
143143//#include "cpu/v60/v60.h"
144#include "devices/cartslot.h"
144#include "imagedev/cartslot.h"
145145
146146
147147class casloopy_state : public driver_device
src/mess/drivers/abc1600.c
r9927r9928
2828
2929#include "emu.h"
3030#include "cpu/m68000/m68000.h"
31#include "devices/flopdrv.h"
31#include "imagedev/flopdrv.h"
3232#include "machine/ram.h"
3333#include "machine/8530scc.h"
3434#include "machine/abc99.h"
src/mess/drivers/svi318.c
r9927r9928
1818#include "machine/i8255a.h"
1919#include "machine/wd17xx.h"
2020#include "machine/ctronics.h"
21#include "devices/flopdrv.h"
21#include "imagedev/flopdrv.h"
2222#include "formats/svi_dsk.h"
23#include "devices/cartslot.h"
24#include "devices/cassette.h"
23#include "imagedev/cartslot.h"
24#include "imagedev/cassette.h"
2525#include "formats/svi_cas.h"
2626#include "sound/dac.h"
2727#include "sound/ay8910.h"
src/mess/drivers/interact.c
r9927r9928
5151#include "emu.h"
5252#include "cpu/z80/z80.h"
5353#include "cpu/i8085/i8085.h"
54#include "devices/cassette.h"
54#include "imagedev/cassette.h"
5555#include "formats/hect_tap.h"
56#include "devices/printer.h"
56#include "imagedev/printer.h"
5757#include "sound/wave.h"      /* for K7 sound*/
5858#include "sound/sn76477.h"   /* for sn sound*/
5959#include "sound/discrete.h"  /* for 1 Bit sound*/
src/mess/drivers/tandy2k.c
r9927r9928
2929#include "emu.h"
3030#include "cpu/i86/i86.h"
3131#include "cpu/mcs48/mcs48.h"
32#include "devices/flopdrv.h"
32#include "imagedev/flopdrv.h"
3333#include "machine/ram.h"
3434#include "machine/ctronics.h"
3535#include "machine/i8255a.h"
src/mess/drivers/x07.c
r9927r9928
2828#include "cpu/z80/z80.h"
2929#include "sound/beep.h"
3030#include "includes/x07.h"
31#include "devices/printer.h"
31#include "imagedev/printer.h"
3232
3333static void t6834_cmd (running_machine *machine, UINT8 cmd);
3434static void receive_from_t6834 (running_machine *machine);
src/mess/drivers/nanos.c
r9927r9928
1313#include "machine/z80sio.h"
1414#include "machine/z80ctc.h"
1515#include "machine/upd765.h"
16#include "devices/flopdrv.h"
16#include "imagedev/flopdrv.h"
1717#include "formats/basicdsk.h"
1818#include "machine/ram.h"
1919
src/mess/drivers/galaxy.c
r9927r9928
2525#include "cpu/z80/z80.h"
2626#include "sound/wave.h"
2727#include "includes/galaxy.h"
28#include "devices/snapquik.h"
29#include "devices/cassette.h"
28#include "imagedev/snapquik.h"
29#include "imagedev/cassette.h"
3030#include "sound/ay8910.h"
3131#include "formats/gtp_cas.h"
3232#include "machine/ram.h"
src/mess/drivers/gamepock.c
r9927r9928
22#include "softlist.h"
33#include "cpu/upd7810/upd7810.h"
44#include "sound/speaker.h"
5#include "devices/cartslot.h"
5#include "imagedev/cartslot.h"
66#include "includes/gamepock.h"
77
88
src/mess/drivers/huebler.c
r9927r9928
2424#include "includes/huebler.h"
2525#include "cpu/z80/z80.h"
2626#include "cpu/z80/z80daisy.h"
27#include "devices/cassette.h"
27#include "imagedev/cassette.h"
2828#include "machine/z80pio.h"
2929#include "machine/z80dart.h"
3030#include "machine/z80ctc.h"
src/mess/drivers/fm7.c
r9927r9928
4242#include "sound/wave.h"
4343#include "sound/beep.h"
4444
45#include "devices/cassette.h"
45#include "imagedev/cassette.h"
4646#include "formats/fm7_cas.h"
4747#include "machine/wd17xx.h"
48#include "devices/flopdrv.h"
48#include "imagedev/flopdrv.h"
4949#include "machine/ctronics.h"
5050
5151#include "includes/fm7.h"
src/mess/drivers/compis.c
r9927r9928
3838#include "machine/ctronics.h"
3939#include "includes/compis.h"
4040#include "video/i82720.h"
41#include "devices/flopdrv.h"
41#include "imagedev/flopdrv.h"
4242#include "machine/pit8253.h"
4343#include "machine/pic8259.h"
4444#include "machine/mm58274c.h"
src/mess/drivers/vtech2.c
r9927r9928
6868#include "sound/speaker.h"
6969#include "sound/wave.h"
7070#include "includes/vtech2.h"
71#include "devices/cartslot.h"
72#include "devices/cassette.h"
73#include "devices/flopdrv.h"
71#include "imagedev/cartslot.h"
72#include "imagedev/cassette.h"
73#include "imagedev/flopdrv.h"
7474#include "formats/vt_cas.h"
7575
7676static ADDRESS_MAP_START(vtech2_mem, ADDRESS_SPACE_PROGRAM, 8 )
src/mess/drivers/jr100.c
r9927r9928
1414#include "emu.h"
1515#include "cpu/m6800/m6800.h"
1616#include "machine/6522via.h"
17#include "devices/cassette.h"
17#include "imagedev/cassette.h"
1818#include "sound/wave.h"
1919#include "sound/speaker.h"
2020#include "sound/beep.h"
21#include "devices/snapquik.h"
21#include "imagedev/snapquik.h"
2222
2323
2424class jr100_state : public driver_device
src/mess/drivers/vidbrain.c
r9927r9928
2929#include "emu.h"
3030#include "includes/vidbrain.h"
3131#include "cpu/f8/f8.h"
32#include "devices/cartslot.h"
33#include "devices/cassette.h"
32#include "imagedev/cartslot.h"
33#include "imagedev/cassette.h"
3434#include "machine/ram.h"
3535#include "sound/discrete.h"
3636
src/mess/drivers/wswan.c
r9927r9928
3434#include "emu.h"
3535#include "cpu/v30mz/nec.h"
3636#include "includes/wswan.h"
37#include "devices/cartslot.h"
37#include "imagedev/cartslot.h"
3838
3939static ADDRESS_MAP_START (wswan_mem, ADDRESS_SPACE_PROGRAM, 8)
4040   AM_RANGE(0x00000, 0x03fff) AM_RAM      /* 16kb RAM / 4 colour tiles */
src/mess/drivers/zx.c
r9927r9928
4343#include "sound/speaker.h"
4444#include "sound/wave.h"
4545#include "includes/zx.h"
46#include "devices/cassette.h"
46#include "imagedev/cassette.h"
4747#include "formats/zx81_p.h"
4848#include "machine/ram.h"
4949
src/mess/drivers/z80ne.c
r9927r9928
9292#include "emu.h"
9393#include "cpu/z80/z80.h"
9494#include "includes/z80ne.h"
95#include "devices/flopdrv.h"
96#include "devices/cassette.h"
95#include "imagedev/flopdrv.h"
96#include "imagedev/cassette.h"
9797#include "formats/z80ne_dsk.h"
9898#include "machine/ram.h"
9999
src/mess/drivers/exp85.c
r9927r9928
2020#include "emu.h"
2121#include "includes/exp85.h"
2222#include "cpu/i8085/i8085.h"
23#include "devices/cassette.h"
23#include "imagedev/cassette.h"
2424#include "machine/i8155.h"
2525#include "machine/i8355.h"
2626#include "sound/speaker.h"
src/mess/drivers/ami1200.c
r9927r9928
4242#include "sound/cdda.h"
4343#include "includes/amiga.h"
4444#include "includes/cubocd32.h"
45#include "devices/chd_cd.h"
45#include "imagedev/chd_cd.h"
4646
4747
4848class ami1200_state : public cubocd32_state
src/mess/drivers/apple2gs.c
r9927r9928
4444#include "cpu/g65816/g65816.h"
4545#include "includes/apple2.h"
4646#include "machine/ay3600.h"
47#include "devices/flopdrv.h"
47#include "imagedev/flopdrv.h"
4848#include "formats/ap2_dsk.h"
4949#include "formats/ap_dsk35.h"
5050#include "includes/apple2gs.h"
r9927r9928
5858#include "machine/8530scc.h"
5959#include "sound/ay8910.h"
6060#include "sound/speaker.h"
61#include "devices/cassette.h"
61#include "imagedev/cassette.h"
6262#include "machine/ram.h"
6363#include "deprecat.h"
6464
src/mess/drivers/trs80m2.c
r9927r9928
2121#include "cpu/z80/z80daisy.h"
2222#include "cpu/mcs48/mcs48.h"
2323#include "cpu/m68000/m68000.h"
24#include "devices/flopdrv.h"
24#include "imagedev/flopdrv.h"
2525#include "machine/ram.h"
2626#include "machine/ctronics.h"
2727#include "machine/wd17xx.h"
src/mess/drivers/pv1000.c
r9927r9928
66
77#include "emu.h"
88#include "cpu/z80/z80.h"
9#include "devices/cartslot.h"
9#include "imagedev/cartslot.h"
1010#include "streams.h"
1111
1212
src/mess/drivers/atari.c
r9927r9928
3434#include "cpu/m6502/m6502.h"
3535#include "includes/atari.h"
3636#include "machine/ataridev.h"
37#include "devices/cartslot.h"
37#include "imagedev/cartslot.h"
3838#include "sound/pokey.h"
3939#include "machine/6821pia.h"
4040#include "video/gtia.h"
src/mess/drivers/mac.c
r9927r9928
4646#include "machine/ncr5380.h"
4747#include "machine/applefdc.h"
4848#include "devices/sonydriv.h"
49#include "devices/harddriv.h"
49#include "imagedev/harddriv.h"
5050#include "formats/ap_dsk35.h"
5151#include "machine/ram.h"
52#include "devices/chd_cd.h"
52#include "imagedev/chd_cd.h"
5353#include "sound/asc.h"
5454#include "sound/cdda.h"
5555#include "includes/mac.h"
src/mess/drivers/nc.c
r9927r9928
103103#include "machine/mc146818.h"   /* for NC200 real time clock */
104104#include "machine/tc8521.h"   /* for NC100 real time clock */
105105#include "machine/upd765.h"      /* for NC200 disk drive interface */
106#include "devices/flopdrv.h"   /* for NC200 disk image */
106#include "imagedev/flopdrv.h"   /* for NC200 disk image */
107107#include "formats/pc_dsk.h"      /* for NC200 disk image */
108#include "devices/cartslot.h"
108#include "imagedev/cartslot.h"
109109#include "sound/beep.h"
110110#include "machine/ram.h"
111111
src/mess/drivers/p8k.c
r9927r9928
2020#include "cpu/z8000/z8000.h"
2121#include "cpu/z80/z80daisy.h"
2222#include "formats/basicdsk.h"
23#include "devices/flopdrv.h"
23#include "imagedev/flopdrv.h"
2424#include "machine/upd765.h"
2525#include "machine/z80ctc.h"
2626#include "machine/z80pio.h"
src/mess/drivers/sord.c
r9927r9928
3434#include "cpu/z80/z80daisy.h"
3535#include "machine/ctronics.h"
3636#include "machine/z80ctc.h"
37#include "devices/cartslot.h"
38#include "devices/cassette.h"
37#include "imagedev/cartslot.h"
38#include "imagedev/cassette.h"
3939#include "formats/sord_cas.h"
4040
4141/* FD-5 floppy support */
4242#include "machine/8255ppi.h"
43#include "devices/flopdrv.h"
43#include "imagedev/flopdrv.h"
4444#include "formats/basicdsk.h"
4545#include "machine/upd765.h"
4646
src/mess/drivers/bw12.c
r9927r9928
2727
2828#include "emu.h"
2929#include "cpu/z80/z80.h"
30#include "devices/flopdrv.h"
30#include "imagedev/flopdrv.h"
3131#include "machine/ram.h"
3232#include "formats/basicdsk.h"
3333#include "machine/6821pia.h"
src/mess/drivers/pentagon.c
r9927r9928
11#include "emu.h"
22#include "includes/spectrum.h"
3#include "devices/snapquik.h"
4#include "devices/cartslot.h"
5#include "devices/cassette.h"
3#include "imagedev/snapquik.h"
4#include "imagedev/cartslot.h"
5#include "imagedev/cassette.h"
66#include "sound/ay8910.h"
77#include "sound/speaker.h"
88#include "formats/tzx_cas.h"
src/mess/drivers/pk8000.c
r9927r9928
1010#include "emu.h"
1111#include "cpu/i8085/i8085.h"
1212#include "machine/i8255a.h"
13#include "devices/cassette.h"
13#include "imagedev/cassette.h"
1414#include "formats/fmsx_cas.h"
1515#include "sound/speaker.h"
1616#include "sound/wave.h"
src/mess/drivers/prestige.c
r9927r9928
7777#include "emu.h"
7878#include "cpu/z80/z80.h"
7979#include "machine/ram.h"
80#include "devices/cartslot.h"
80#include "imagedev/cartslot.h"
8181
8282
8383class prestige_state : public driver_device
src/mess/drivers/ngp.c
r9927r9928
9797#include "emu.h"
9898#include "cpu/tlcs900/tlcs900.h"
9999#include "cpu/z80/z80.h"
100#include "devices/cartslot.h"
100#include "imagedev/cartslot.h"
101101#include "sound/t6w28.h"
102102#include "sound/dac.h"
103103#include "video/k1ge.h"
src/mess/drivers/nes.c
r9927r9928
1515#include "machine/nes_mmc.h"
1616#include "includes/nes.h"
1717#include "cpu/m6502/m6502.h"
18#include "devices/cartslot.h"
18#include "imagedev/cartslot.h"
1919#include "sound/nes_apu.h"
20#include "devices/flopdrv.h"
20#include "imagedev/flopdrv.h"
2121#include "formats/nes_dsk.h"
2222
2323
src/mess/drivers/concept.c
r9927r9928
3131#include "emu.h"
3232#include "cpu/m68000/m68000.h"
3333#include "includes/concept.h"
34#include "devices/flopdrv.h"
34#include "imagedev/flopdrv.h"
3535#include "formats/basicdsk.h"
36#include "devices/harddriv.h"
36#include "imagedev/harddriv.h"
3737#include "machine/mm58274c.h"
3838#include "machine/wd17xx.h"
3939
src/mess/drivers/pcw16.c
r9927r9928
103103
104104/* Devices */
105105#include "formats/pc_dsk.h"      /* pc disk images */
106#include "devices/flopdrv.h"
106#include "imagedev/flopdrv.h"
107107#include "machine/ram.h"
108108
109109// interrupt counter
src/mess/drivers/ti990_4.c
r9927r9928
4444#else
4545#include "video/733_asr.h"
4646#endif
47#include "devices/flopdrv.h"
47#include "imagedev/flopdrv.h"
4848
4949
5050class ti990_4_state : public driver_device
src/mess/drivers/ht68k.c
r9927r9928
99#include "emu.h"
1010#include "cpu/m68000/m68000.h"
1111#include "machine/68681.h"
12#include "devices/flopdrv.h"
12#include "imagedev/flopdrv.h"
1313#include "machine/wd17xx.h"
1414#include "machine/terminal.h"
1515
src/mess/drivers/msx.c
r9927r9928
286286#include "machine/ctronics.h"
287287#include "includes/msx_slot.h"
288288#include "includes/msx.h"
289#include "devices/flopdrv.h"
290#include "devices/cartslot.h"
291#include "devices/cassette.h"
289#include "imagedev/flopdrv.h"
290#include "imagedev/cartslot.h"
291#include "imagedev/cassette.h"
292292#include "formats/fmsx_cas.h"
293293#include "formats/msx_dsk.h"
294294#include "sound/ay8910.h"
src/mess/drivers/mz700.c
r9927r9928
7474#include "sound/sn76496.h"
7575#include "sound/speaker.h"
7676#include "sound/wave.h"
77#include "devices/cassette.h"
77#include "imagedev/cassette.h"
7878#include "machine/ram.h"
7979#include "formats/mz_cas.h"
8080
src/mess/drivers/prof80.c
r9927r9928
3232#include "cpu/z80/z80daisy.h"
3333#include "video/mc6845.h"
3434#include "formats/basicdsk.h"
35#include "devices/flopdrv.h"
35#include "imagedev/flopdrv.h"
3636#include "machine/ram.h"
3737#include "machine/i8255a.h"
3838#include "machine/upd765.h"
src/mess/drivers/vectrex.c
r9927r9928
1313#include "video/vector.h"
1414#include "machine/6522via.h"
1515#include "includes/vectrex.h"
16#include "devices/cartslot.h"
16#include "imagedev/cartslot.h"
1717#include "sound/ay8910.h"
1818#include "sound/dac.h"
1919#include "machine/nvram.h"
src/mess/drivers/microdec.c
r9927r9928
99#include "emu.h"
1010#include "cpu/z80/z80.h"
1111#include "machine/upd765.h"
12#include "devices/flopdrv.h"
12#include "imagedev/flopdrv.h"
1313#include "machine/terminal.h"
1414
1515
src/mess/drivers/dc.c
r9927r9928
2525#include "cpu/arm7/arm7core.h"
2626#include "sound/aica.h"
2727#include "includes/dc.h"
28#include "devices/chd_cd.h"
28#include "imagedev/chd_cd.h"
2929
3030#define CPU_CLOCK (200000000)
3131
src/mess/drivers/pasogo.c
r9927r9928
1111
1212#include "emu.h"
1313#include "cpu/i86/i86.h"
14#include "devices/cartslot.h"
14#include "imagedev/cartslot.h"
1515#include "machine/pic8259.h"
1616#include "machine/pit8253.h"
1717/*
src/mess/drivers/lynx.c
r9927r9928
1010#include "cpu/m6502/m6502.h"
1111#include "includes/lynx.h"
1212
13#include "devices/snapquik.h"
13#include "imagedev/snapquik.h"
1414
1515static QUICKLOAD_LOAD( lynx );
1616
src/mess/drivers/aquarius.c
r9927r9928
2323#include "cpu/z80/z80.h"
2424#include "sound/ay8910.h"
2525#include "sound/speaker.h"
26#include "devices/flopdrv.h"
26#include "imagedev/flopdrv.h"
2727#include "formats/basicdsk.h"
28#include "devices/cartslot.h"
29#include "devices/cassette.h"
30#include "devices/printer.h"
28#include "imagedev/cartslot.h"
29#include "imagedev/cassette.h"
30#include "imagedev/printer.h"
3131#include "machine/ram.h"
3232
3333/***************************************************************************
src/mess/drivers/cgenie.c
r9927r9928
2929#include "emu.h"
3030#include "cpu/z80/z80.h"
3131#include "includes/cgenie.h"
32#include "devices/flopdrv.h"
32#include "imagedev/flopdrv.h"
3333#include "formats/basicdsk.h"
34#include "devices/cartslot.h"
35#include "devices/cassette.h"
34#include "imagedev/cartslot.h"
35#include "imagedev/cassette.h"
3636#include "sound/ay8910.h"
3737#include "sound/dac.h"
3838#include "formats/cgen_cas.h"
src/mess/drivers/specpls3.c
r9927r9928
146146
147147#include "emu.h"
148148#include "includes/spectrum.h"
149#include "devices/snapquik.h"
150#include "devices/cartslot.h"
151#include "devices/cassette.h"
149#include "imagedev/snapquik.h"
150#include "imagedev/cartslot.h"
151#include "imagedev/cassette.h"
152152#include "sound/ay8910.h"
153153#include "sound/speaker.h"
154154#include "formats/tzx_cas.h"
155155
156156/* +3 hardware */
157157#include "machine/upd765.h"
158#include "devices/flopdrv.h"
158#include "imagedev/flopdrv.h"
159159#include "machine/ram.h"
160160
161161/****************************************************************************************************/
src/mess/drivers/x68k.c
r9927r9928
128128#include "machine/8530scc.h"
129129#include "machine/hd63450.h"
130130#include "machine/rp5c15.h"
131#include "devices/flopdrv.h"
131#include "imagedev/flopdrv.h"
132132#include "formats/basicdsk.h"
133133#include "formats/dim_dsk.h"
134#include "devices/harddriv.h"
134#include "imagedev/harddriv.h"
135135#include "machine/x68k_hdc.h"
136136#include "includes/x68k.h"
137137#include "machine/ram.h"
src/mess/drivers/ondra.c
r9927r9928
1010#include "emu.h"
1111#include "cpu/z80/z80.h"
1212#include "sound/wave.h"
13#include "devices/cassette.h"
13#include "imagedev/cassette.h"
1414#include "machine/ram.h"
1515#include "includes/ondra.h"
1616
src/mess/drivers/kaypro.c
r9927r9928
3737#include "cpu/z80/z80daisy.h"
3838#include "machine/ctronics.h"
3939#include "sound/beep.h"
40#include "devices/snapquik.h"
41#include "devices/flopdrv.h"
40#include "imagedev/snapquik.h"
41#include "imagedev/flopdrv.h"
4242#include "formats/basicdsk.h"
4343#include "includes/kaypro.h"
4444
src/mess/drivers/super80.c
r9927r9928
185185#include "cpu/z80/z80.h"
186186#include "cpu/z80/z80daisy.h"
187187#include "sound/wave.h"
188#include "devices/snapquik.h"
189#include "devices/cartslot.h"
190#include "devices/cassette.h"
191#include "devices/z80bin.h"
188#include "imagedev/snapquik.h"
189#include "imagedev/cartslot.h"
190#include "imagedev/cassette.h"
192191#include "sound/speaker.h"
193192#include "machine/ctronics.h"
194193#include "super80.lh"
src/mess/drivers/n64.c
r9927r9928
1111#include "cpu/rsp/rsp.h"
1212#include "cpu/mips/mips3.h"
1313#include "sound/dmadac.h"
14#include "devices/cartslot.h"
14#include "imagedev/cartslot.h"
1515#include "includes/n64.h"
1616
1717
src/mess/drivers/victor9k.c
r9927r9928
2828#include "emu.h"
2929#include "cpu/i86/i86.h"
3030#include "cpu/mcs48/mcs48.h"
31#include "devices/flopdrv.h"
31#include "imagedev/flopdrv.h"
3232#include "machine/ram.h"
3333#include "machine/ctronics.h"
3434#include "machine/6522via.h"
src/mess/drivers/pc8001.c
r9927r9928
2525#include "emu.h"
2626#include "includes/pc8001.h"
2727#include "cpu/z80/z80.h"
28#include "devices/cassette.h"
28#include "imagedev/cassette.h"
2929#include "machine/ram.h"
3030#include "machine/i8257.h"
3131#include "machine/ctronics.h"
src/mess/drivers/beta.c
r9927r9928
1717#include "emu.h"
1818#include "includes/beta.h"
1919#include "cpu/m6502/m6502.h"
20#include "devices/cartslot.h"
20#include "imagedev/cartslot.h"
2121#include "machine/6532riot.h"
2222#include "sound/speaker.h"
2323#include "machine/ram.h"
src/mess/drivers/px4.c
r9927r9928
1111#include "cpu/z80/z80.h"
1212#include "machine/ram.h"
1313#include "machine/ctronics.h"
14#include "devices/cartslot.h"
15#include "devices/cassette.h"
14#include "imagedev/cartslot.h"
15#include "imagedev/cassette.h"
1616#include "machine/tf20.h"
1717#include "machine/ram.h"
1818#include "px4.lh"
src/mess/drivers/lviv.c
r9927r9928
286286#include "sound/wave.h"
287287#include "machine/i8255a.h"
288288#include "includes/lviv.h"
289#include "devices/snapquik.h"
290#include "devices/cassette.h"
289#include "imagedev/snapquik.h"
290#include "imagedev/cassette.h"
291291#include "formats/lviv_lvt.h"
292292#include "machine/ram.h"
293293
src/mess/drivers/exidy.c
r9927r9928
146146#include "sound/wave.h"
147147#include "machine/ctronics.h"
148148#include "machine/wd17xx.h"
149#include "devices/cassette.h"
150#include "devices/snapquik.h"
151#include "devices/cartslot.h"
149#include "imagedev/cassette.h"
150#include "imagedev/snapquik.h"
151#include "imagedev/cartslot.h"
152152#include "machine/ay31015.h"
153#include "devices/flopdrv.h"
153#include "imagedev/flopdrv.h"
154154#include "formats/exidydsk.h"
155155#include "includes/exidy.h"
156156
src/mess/drivers/pc8801.c
r9927r9928
9696#include "emu.h"
9797#include "includes/pc8801.h"
9898#include "cpu/z80/z80.h"
99#include "devices/cassette.h"
100#include "devices/flopdrv.h"
99#include "imagedev/cassette.h"
100#include "imagedev/flopdrv.h"
101101#include "machine/ctronics.h"
102102#include "machine/i8255a.h"
103103#include "machine/upd1990a.h"
src/mess/drivers/poly880.c
r9927r9928
1212#include "includes/poly880.h"
1313#include "cpu/z80/z80.h"
1414#include "cpu/z80/z80daisy.h"
15#include "devices/cassette.h"
15#include "imagedev/cassette.h"
1616#include "machine/z80pio.h"
1717#include "machine/z80ctc.h"
1818#include "machine/ram.h"
src/mess/drivers/timex.c
r9927r9928
147147#include "emu.h"
148148#include "cpu/z80/z80.h"
149149#include "includes/spectrum.h"
150#include "devices/snapquik.h"
151#include "devices/cartslot.h"
152#include "devices/cassette.h"
150#include "imagedev/snapquik.h"
151#include "imagedev/cartslot.h"
152#include "imagedev/cassette.h"
153153#include "sound/speaker.h"
154154#include "sound/ay8910.h"
155155#include "formats/tzx_cas.h"
src/mess/drivers/bw2.c
r9927r9928
3131
3232#include "emu.h"
3333#include "cpu/z80/z80.h"
34#include "devices/flopdrv.h"
34#include "imagedev/flopdrv.h"
3535#include "machine/ram.h"
3636#include "formats/basicdsk.h"
3737#include "machine/serial.h"
src/mess/drivers/enterp.c
r9927r9928
1919#include "cpu/z80/z80.h"
2020#include "audio/dave.h"
2121#include "machine/wd17xx.h"
22#include "devices/flopdrv.h"
22#include "imagedev/flopdrv.h"
2323#include "formats/basicdsk.h"
2424#include "machine/ram.h"
2525#include "includes/enterp.h"
src/mess/drivers/portfoli.c
r9927r9928
8080#include "emu.h"
8181#include "includes/portfoli.h"
8282#include "cpu/i86/i86.h"
83#include "devices/cartslot.h"
83#include "imagedev/cartslot.h"
8484#include "machine/ram.h"
85#include "devices/printer.h"
85#include "imagedev/printer.h"
8686#include "machine/ctronics.h"
8787#include "machine/i8255a.h"
8888#include "machine/ins8250.h"
src/mess/drivers/mc10.c
r9927r9928
1313#include "sound/dac.h"
1414#include "video/m6847.h"
1515#include "video/ef9345.h"
16#include "devices/cassette.h"
16#include "imagedev/cassette.h"
1717#include "formats/coco_cas.h"
1818#include "machine/ram.h"
1919
src/mess/drivers/atom.c
r9927r9928
110110#include "emu.h"
111111#include "includes/atom.h"
112112#include "cpu/m6502/m6502.h"
113#include "devices/cartslot.h"
114#include "devices/cassette.h"
115#include "devices/flopdrv.h"
113#include "imagedev/cartslot.h"
114#include "imagedev/cassette.h"
115#include "imagedev/flopdrv.h"
116116#include "machine/ram.h"
117#include "devices/snapquik.h"
117#include "imagedev/snapquik.h"
118118#include "formats/atom_atm.h"
119119#include "formats/atom_tap.h"
120120#include "formats/basicdsk.h"
src/mess/drivers/apricot.c
r9927r9928
1717#include "sound/sn76496.h"
1818#include "video/mc6845.h"
1919#include "machine/ram.h"
20#include "devices/flopdrv.h"
20#include "imagedev/flopdrv.h"
2121#include "formats/apridisk.h"
2222
2323
src/mess/drivers/coleco.c
r9927r9928
6666#include "cpu/z80/z80.h"
6767#include "sound/sn76496.h"
6868#include "video/tms9928a.h"
69#include "devices/cartslot.h"
69#include "imagedev/cartslot.h"
7070
7171
7272class coleco_state : public driver_device
src/mess/drivers/lc80.c
r9927r9928
2222#include "includes/lc80.h"
2323#include "cpu/z80/z80.h"
2424#include "cpu/z80/z80daisy.h"
25#include "devices/cassette.h"
25#include "imagedev/cassette.h"
2626#include "machine/z80pio.h"
2727#include "machine/z80ctc.h"
2828#include "sound/speaker.h"
src/mess/drivers/apf.c
r9927r9928
1919
2020#include "machine/6821pia.h"
2121#include "machine/wd17xx.h"
22#include "devices/flopdrv.h"
22#include "imagedev/flopdrv.h"
2323#include "formats/basicdsk.h"
24#include "devices/cassette.h"
25#include "devices/cartslot.h"
24#include "imagedev/cassette.h"
25#include "imagedev/cartslot.h"
2626#include "formats/apf_apt.h"
2727#include "sound/speaker.h"
2828
src/mess/drivers/rx78.c
r9927r9928
4343#include "emu.h"
4444#include "cpu/z80/z80.h"
4545#include "sound/sn76496.h"
46#include "devices/cartslot.h"
47#include "devices/cassette.h"
46#include "imagedev/cartslot.h"
47#include "imagedev/cassette.h"
4848#include "sound/wave.h"
4949#include "machine/ram.h"
5050
src/mess/drivers/partner.c
r9927r9928
1414#include "machine/i8257.h"
1515#include "machine/wd17xx.h"
1616#include "video/i8275.h"
17#include "devices/cassette.h"
18#include "devices/flopdrv.h"
17#include "imagedev/cassette.h"
18#include "imagedev/flopdrv.h"
1919#include "formats/basicdsk.h"
2020#include "formats/rk_cas.h"
2121#include "includes/radio86.h"
src/mess/drivers/altair.c
r9927r9928
99#include "emu.h"
1010#include "cpu/i8085/i8085.h"
1111#include "machine/terminal.h"
12#include "devices/snapquik.h"
12#include "imagedev/snapquik.h"
1313
1414
1515class altair_state : public driver_device
src/mess/drivers/saturn.c
r9927r9928
166166#include "machine/stvcd.h"
167167#include "machine/scudsp.h"
168168#include "sound/scsp.h"
169#include "devices/chd_cd.h"
170#include "devices/cartslot.h"
169#include "imagedev/chd_cd.h"
170#include "imagedev/cartslot.h"
171171#include "includes/stv.h"
172172#include "coreutil.h"
173173
src/mess/drivers/supracan.c
r9927r9928
7676#include "emu.h"
7777#include "cpu/m68000/m68000.h"
7878#include "cpu/m6502/m6502.h"
79#include "devices/cartslot.h"
79#include "imagedev/cartslot.h"
8080#include "debugger.h"
8181
8282#define SOUNDCPU_BOOT_HACK      (1)
src/mess/drivers/channelf.c
r9927r9928
1414#include "emu.h"
1515#include "cpu/f8/f8.h"
1616#include "includes/channelf.h"
17#include "devices/cartslot.h"
17#include "imagedev/cartslot.h"
1818
1919
2020#ifndef VERBOSE
src/mess/drivers/apple1.c
r9927r9928
7171#include "cpu/m6502/m6502.h"
7272#include "machine/6821pia.h"
7373#include "includes/apple1.h"
74#include "devices/snapquik.h"
75#include "devices/cassette.h"
74#include "imagedev/snapquik.h"
75#include "imagedev/cassette.h"
7676#include "machine/ram.h"
7777
7878/* port i/o functions */
src/mess/drivers/c80.c
r9927r9928
1111#include "cpu/z80/z80.h"
1212#include "cpu/z80/z80daisy.h"
1313#include "machine/z80pio.h"
14#include "devices/cassette.h"
14#include "imagedev/cassette.h"
1515#include "machine/ram.h"
1616#include "c80.lh"
1717
src/mess/drivers/tmc2000e.c
r9927r9928
3232#include "emu.h"
3333#include "includes/tmc2000e.h"
3434#include "cpu/cosmac/cosmac.h"
35#include "devices/printer.h"
36#include "devices/flopdrv.h"
35#include "imagedev/printer.h"
36#include "imagedev/flopdrv.h"
3737#include "formats/basicdsk.h"
38#include "devices/cassette.h"
38#include "imagedev/cassette.h"
3939#include "sound/cdp1864.h"
4040#include "machine/rescap.h"
4141#include "machine/ram.h"
src/mess/drivers/hec2hrp.c
r9927r9928
7070
7171#include "emu.h"
7272
73#include "devices/cassette.h"
73#include "imagedev/cassette.h"
7474#include "formats/hect_tap.h"
75#include "devices/printer.h"
75#include "imagedev/printer.h"
7676#include "sound/sn76477.h"   /* for sn sound*/
7777#include "sound/wave.h"      /* for K7 sound*/
7878#include "sound/discrete.h"  /* for 1 Bit sound*/
7979#include "machine/upd765.h"   /* for floppy disc controller */
80#include "devices/flopdrv.h"
80#include "imagedev/flopdrv.h"
8181#include "formats/basicdsk.h"
8282#include "cpu/z80/z80.h"
8383
src/mess/drivers/bebox.c
r9927r9928
3131#include "machine/intelfsh.h"
3232
3333/* Devices */
34#include "devices/flopdrv.h"
35#include "devices/chd_cd.h"
36#include "devices/harddriv.h"
34#include "imagedev/flopdrv.h"
35#include "imagedev/chd_cd.h"
36#include "imagedev/harddriv.h"
3737#include "formats/pc_dsk.h"
3838#include "machine/ram.h"
3939
src/mess/drivers/apogee.c
r9927r9928
1313#include "machine/i8255a.h"
1414#include "machine/i8257.h"
1515#include "video/i8275.h"
16#include "devices/cassette.h"
16#include "imagedev/cassette.h"
1717#include "formats/rk_cas.h"
1818#include "includes/radio86.h"
1919
src/mess/drivers/apricotf.c
r9927r9928
99#include "emu.h"
1010#include "cpu/i86/i86.h"
1111#include "machine/wd17xx.h"
12#include "devices/flopdrv.h"
12#include "imagedev/flopdrv.h"
1313#include "cpu/z80/z80daisy.h"
1414#include "machine/z80ctc.h"
15#include "devices/flopdrv.h"
15#include "imagedev/flopdrv.h"
1616#include "formats/basicdsk.h"
1717
1818class act_state : public driver_device
src/mess/drivers/pegasus.c
r9927r9928
3232#include "emu.h"
3333#include "cpu/m6809/m6809.h"
3434#include "machine/6821pia.h"
35#include "devices/cartslot.h"
36#include "devices/cassette.h"
35#include "imagedev/cartslot.h"
36#include "imagedev/cassette.h"
3737#include "includes/pegasus.h"
3838
3939UINT8 pegasus_control_bits = 0;
src/mess/drivers/mtx.c
r9927r9928
2525#include "includes/mtx.h"
2626#include "cpu/z80/z80.h"
2727#include "cpu/z80/z80daisy.h"
28#include "devices/cassette.h"
28#include "imagedev/cassette.h"
2929#include "machine/ram.h"
30#include "devices/snapquik.h"
30#include "imagedev/snapquik.h"
3131#include "machine/ctronics.h"
3232#include "machine/z80ctc.h"
3333#include "machine/z80dart.h"
src/mess/drivers/vg5k.c
r9927r9928
4242#include "emu.h"
4343#include "cpu/z80/z80.h"
4444#include "machine/ram.h"
45#include "devices/printer.h"
45#include "imagedev/printer.h"
4646#include "video/ef9345.h"
4747#include "sound/dac.h"
48#include "devices/cassette.h"
48#include "imagedev/cassette.h"
4949#include "sound/wave.h"
5050#include "formats/vg5k_cas.h"
5151
src/mess/drivers/intv.c
r9927r9928
3535#include "cpu/m6502/m6502.h"
3636#include "cpu/cp1610/cp1610.h"
3737#include "includes/intv.h"
38#include "devices/cartslot.h"
38#include "imagedev/cartslot.h"
3939#include "sound/ay8910.h"
4040
4141#ifndef VERBOSE
src/mess/drivers/elwro800.c
r9927r9928
2525#include "machine/msm8251.h"
2626
2727/* Devices */
28#include "devices/flopdrv.h"
29#include "devices/cassette.h"
28#include "imagedev/flopdrv.h"
29#include "imagedev/cassette.h"
3030#include "formats/tzx_cas.h"
3131#include "machine/ram.h"
3232
src/mess/drivers/special.c
r9927r9928
1616#include "includes/special.h"
1717#include "machine/i8255a.h"
1818#include "machine/pit8253.h"
19#include "devices/cassette.h"
20#include "devices/flopdrv.h"
19#include "imagedev/cassette.h"
20#include "imagedev/flopdrv.h"
2121#include "formats/basicdsk.h"
2222#include "formats/rk_cas.h"
2323#include "formats/smx_dsk.h"
src/mess/drivers/jupiter.c
r9927r9928
2828
2929#include "emu.h"
3030#include "cpu/z80/z80.h"
31#include "devices/cassette.h"
32#include "devices/snapquik.h"
31#include "imagedev/cassette.h"
32#include "imagedev/snapquik.h"
3333#include "sound/speaker.h"
3434#include "sound/wave.h"
3535#include "formats/jupi_tap.h"
src/mess/drivers/exelv.c
r9927r9928
5555#include "video/tms3556.h"
5656#include "sound/tms5220.h"
5757#include "audio/spchroms.h"
58/*#include "devices/cartslot.h"
59#include "devices/cassette.h"*/
58/*#include "imagedev/cartslot.h"
59#include "imagedev/cassette.h"*/
6060
6161
6262class exelv_state : public driver_device
src/mess/drivers/pv2000.c
r9927r9928
3131#include "cpu/z80/z80.h"
3232#include "sound/sn76496.h"
3333#include "video/tms9928a.h"
34#include "devices/cartslot.h"
35#include "devices/cassette.h"
34#include "imagedev/cartslot.h"
35#include "imagedev/cassette.h"
3636
3737
3838class pv2000_state : public driver_device
src/mess/drivers/mikro80.c
r9927r9928
1212#include "sound/wave.h"
1313#include "machine/i8255a.h"
1414#include "includes/mikro80.h"
15#include "devices/cassette.h"
16#include "devices/cartslot.h"
15#include "imagedev/cassette.h"
16#include "imagedev/cartslot.h"
1717#include "formats/rk_cas.h"
1818#include "sound/dac.h"
1919
src/mess/drivers/pyl601.c
r9927r9928
99#include "emu.h"
1010#include "cpu/m6800/m6800.h"
1111#include "video/mc6845.h"
12#include "devices/flopdrv.h"
12#include "imagedev/flopdrv.h"
1313#include "formats/basicdsk.h"
1414#include "machine/upd765.h"
1515#include "machine/ram.h"
src/mess/drivers/scv.c
r9927r9928
88#include "emu.h"
99#include "devcb.h"
1010#include "cpu/upd7810/upd7810.h"
11#include "devices/cartslot.h"
11#include "imagedev/cartslot.h"
1212#include "audio/upd1771.h"
1313
1414
src/mess/drivers/rmnimbus.c
r9927r9928
1111#include "image.h"
1212#include "cpu/i86/i86.h"
1313#include "cpu/mcs51/mcs51.h"
14#include "devices/flopdrv.h"
15#include "devices/harddriv.h"
14#include "imagedev/flopdrv.h"
15#include "imagedev/harddriv.h"
1616#include "machine/ram.h"
17#include "formats/flopimg.h"
17#include "imagedev/flopimg.h"
1818#include "formats/pc_dsk.h"
1919#include "includes/rmnimbus.h"
2020#include "machine/er59256.h"
src/mess/drivers/mz80.c
r9927r9928
1212#include "sound/wave.h"
1313#include "machine/i8255a.h"
1414#include "machine/pit8253.h"
15#include "devices/cassette.h"
15#include "imagedev/cassette.h"
1616#include "includes/mz80.h"
1717
1818
src/mess/drivers/a310.c
r9927r9928
5757
5858#include "emu.h"
5959#include "machine/wd17xx.h"
60#include "devices/flopdrv.h"
60#include "imagedev/flopdrv.h"
6161#include "cpu/arm/arm.h"
6262#include "sound/dac.h"
6363#include "includes/archimds.h"
src/mess/drivers/ut88.c
r9927r9928
1313#include "sound/dac.h"
1414#include "sound/wave.h"
1515#include "includes/ut88.h"
16#include "devices/cassette.h"
16#include "imagedev/cassette.h"
1717#include "formats/rk_cas.h"
1818#include "ut88mini.lh"
1919
src/mess/drivers/apple2.c
r9927r9928
185185#include "cpu/z80/z80.h"
186186#include "deprecat.h"
187187#include "devices/appldriv.h"
188#include "devices/flopdrv.h"
189#include "devices/cassette.h"
188#include "imagedev/flopdrv.h"
189#include "imagedev/cassette.h"
190190#include "formats/ap2_dsk.h"
191191#include "includes/apple2.h"
192192#include "machine/ay3600.h"
r9927r9928
200200#include "machine/ram.h"
201201#include "machine/a2cffa.h"
202202#include "machine/idectrl.h"
203#include "devices/harddriv.h"
203#include "imagedev/harddriv.h"
204204
205205
206206/***************************************************************************
src/mess/drivers/e01.c
r9927r9928
4949#include "emu.h"
5050#include "includes/e01.h"
5151#include "cpu/m6502/m6502.h"
52#include "devices/flopdrv.h"
52#include "imagedev/flopdrv.h"
5353#include "machine/ram.h"
5454#include "machine/ctronics.h"
5555#include "machine/6522via.h"
src/mess/drivers/svision.c
r9927r9928
99#include "cpu/m6502/m6502.h"
1010
1111#include "includes/svision.h"
12#include "devices/cartslot.h"
12#include "imagedev/cartslot.h"
1313#include "svision.lh"
1414
1515#define MAKE8_RGB15(red3, green3, blue2) ( ( (red3)<<(10+2)) | ( (green3)<<(5+2)) | ( (blue2)<<(0+3)) )
src/mess/drivers/xerox820.c
r9927r9928
3131#include "cpu/z80/z80daisy.h"
3232#include "cpu/i86/i86.h"
3333#include "formats/basicdsk.h"
34#include "devices/flopdrv.h"
34#include "imagedev/flopdrv.h"
3535#include "machine/ram.h"
3636#include "machine/z80pio.h"
3737#include "machine/z80ctc.h"
src/mess/drivers/ti99_4p.c
r9927r9928
5757#include "machine/tms9902.h"
5858#include "machine/ti99/peribox.h"
5959
60#include "devices/cassette.h"
60#include "imagedev/cassette.h"
6161#include "machine/ti99/videowrp.h"
6262#include "machine/ti99/sgcpu.h"
6363#include "machine/ti99/peribox.h"
src/mess/drivers/pc.c
r9927r9928
147147#include "includes/pc.h"
148148
149149#include "machine/pc_hdc.h"
150#include "devices/flopdrv.h"
151#include "devices/harddriv.h"
152#include "devices/cassette.h"
153#include "devices/cartslot.h"
150#include "imagedev/flopdrv.h"
151#include "imagedev/harddriv.h"
152#include "imagedev/cassette.h"
153#include "imagedev/cartslot.h"
154154#include "formats/pc_dsk.h"
155155
156156#include "machine/8237dma.h"
src/mess/drivers/pecom.c
r9927r9928
1010#include "cpu/cosmac/cosmac.h"
1111#include "sound/cdp1869.h"
1212#include "sound/wave.h"
13#include "devices/cassette.h"
13#include "imagedev/cassette.h"
1414#include "includes/pecom.h"
1515#include "machine/ram.h"
1616
src/mess/drivers/pce.c
r9927r9928
5959#include "video/vdc.h"
6060#include "cpu/h6280/h6280.h"
6161#include "includes/pce.h"
62#include "devices/cartslot.h"
63#include "devices/chd_cd.h"
62#include "imagedev/cartslot.h"
63#include "imagedev/chd_cd.h"
6464#include "sound/c6280.h"
6565#include "sound/cdda.h"
6666#include "sound/msm5205.h"
src/mess/drivers/ti99_4x.c
r9927r9928
2626#include "sound/wave.h"
2727#include "video/v9938.h"
2828#include "machine/tms9901.h"
29#include "devices/cassette.h"
29#include "imagedev/cassette.h"
3030
3131#include "machine/ti99/tiboard.h"
3232
src/mess/drivers/ip20.c
r9927r9928
2424#include "machine/eeprom.h"
2525#include "machine/8530scc.h"
2626#include "machine/wd33c93.h"
27#include "devices/harddriv.h"
28#include "devices/chd_cd.h"
27#include "imagedev/harddriv.h"
28#include "imagedev/chd_cd.h"
2929
3030
3131class ip20_state : public driver_device
src/mess/drivers/vc4000.c
r9927r9928
5050#include "cpu/s2650/s2650.h"
5151
5252#include "includes/vc4000.h"
53#include "devices/cartslot.h"
54#include "devices/snapquik.h"
53#include "imagedev/cartslot.h"
54#include "imagedev/snapquik.h"
5555
5656static QUICKLOAD_LOAD( vc4000 );
5757
src/mess/drivers/cosmicos.c
r9927r9928
3535#include "emu.h"
3636#include "includes/cosmicos.h"
3737#include "cpu/cosmac/cosmac.h"
38#include "devices/cassette.h"
38#include "imagedev/cassette.h"
3939#include "machine/ram.h"
40#include "devices/snapquik.h"
40#include "imagedev/snapquik.h"
4141#include "machine/rescap.h"
4242#include "sound/cdp1864.h"
4343#include "sound/speaker.h"
src/mess/drivers/pk8020.c
r9927r9928
1111#include "cpu/i8085/i8085.h"
1212#include "machine/i8255a.h"
1313#include "machine/wd17xx.h"
14#include "devices/flopdrv.h"
14#include "imagedev/flopdrv.h"
1515#include "formats/basicdsk.h"
1616#include "includes/pk8020.h"
1717#include "machine/ram.h"
src/mess/drivers/bbc.c
r9927r9928
1717#include "includes/bbc.h"
1818#include "machine/upd7002.h"
1919#include "machine/ctronics.h"
20#include "devices/flopdrv.h"
20#include "imagedev/flopdrv.h"
2121#include "formats/basicdsk.h"
22#include "devices/cartslot.h"
23#include "devices/cassette.h"
22#include "imagedev/cartslot.h"
23#include "imagedev/cassette.h"
2424#include "formats/uef_cas.h"
2525#include "formats/csw_cas.h"
2626#include "sound/sn76496.h"
src/mess/drivers/psion.c
r9927r9928
2323#include "emu.h"
2424#include "cpu/m6800/m6800.h"
2525#include "sound/beep.h"
26#include "devices/cartslot.h"
26#include "imagedev/cartslot.h"
2727#include "video/hd44780.h"
2828#include "includes/psion.h"
2929
src/mess/drivers/gba.c
r9927r9928
1919#include "video/generic.h"
2020#include "cpu/arm7/arm7.h"
2121#include "cpu/arm7/arm7core.h"
22#include "devices/cartslot.h"
22#include "imagedev/cartslot.h"
2323#include "sound/dac.h"
2424#include "machine/intelfsh.h"
2525#include "audio/gb.h"
src/mess/drivers/vixen.c
r9927r9928
5858
5959#include "emu.h"
6060#include "cpu/z80/z80.h"
61#include "devices/flopdrv.h"
61#include "imagedev/flopdrv.h"
6262#include "machine/ram.h"
6363#include "machine/i8155.h"
6464#include "machine/ieee488.h"
src/mess/drivers/bmjr.c
r9927r9928
1515#include "emu.h"
1616#include "cpu/m6800/m6800.h"
1717#include "sound/beep.h"
18#include "devices/cassette.h"
18#include "imagedev/cassette.h"
1919#include "sound/wave.h"
2020
2121
src/mess/drivers/bbcbc.c
r9927r9928
1313#include "video/tms9928a.h"
1414#include "machine/z80pio.h"
1515#include "cpu/z80/z80daisy.h"
16#include "devices/cartslot.h"
16#include "imagedev/cartslot.h"
1717
1818
1919class bbcbc_state : public driver_device
src/mess/drivers/kc.c
r9927r9928
2626#include "machine/upd765.h"
2727
2828/* Devices */
29#include "devices/cassette.h"
30#include "devices/flopdrv.h"
29#include "imagedev/cassette.h"
30#include "imagedev/flopdrv.h"
3131#include "formats/basicdsk.h"
3232#include "machine/ram.h"
3333

Previous 15994 Revisions Next


© 1998-2018 The MESS Team