Previous 199869 Revisions Next

r24065 Thursday 4th July, 2013 at 10:43:00 UTC by Miodrag Milanović
(MESS)bml3: Add stub variants bml3mk2 (for MB-6891) and bml3mk5 [jedwidz]
(for MB-6892). For now these behave the same as bml3 (MB-6890).
Refactor disk controllers and kanji ROM as slot devices. This allows
switching between MP-1802 and MP-1805 disk controllers. MP-1805 disk
controller now works. Kanji ROM now works.
Keyboard scanning in 'counter disabled' mode now works.

imgtool: Add bml3 driver, supporting both single-density (MP-1805
controller) and double-density (MP-1802 controller) disks in D88 format.

mc6843: Work around floppy_get_device() not finding drives attached to a
slot device.Store all 8 bits in CTAR current track register, rather than
excluding bit 7 (needed for bml3 MP-1805 boot)
[src/emu/machine]mc6843.c
[src/mess]mess.lst mess.mak
[src/mess/drivers]bml3.c
[src/mess/machine]bml3bus.c* bml3bus.h* bml3kanji.c* bml3kanji.h* bml3mp1802.c* bml3mp1802.h* bml3mp1805.c* bml3mp1805.h*
[src/mess/tools/imgtool]filtbas.c filter.c filter.h imgtool.mak modules.c
[src/mess/tools/imgtool/modules]bml3.c*

trunk/src/emu/machine/mc6843.c
r24064r24065
118118
119119
120120
121static device_t* mc6843_floppy_image ( device_t *device, UINT8 drive )
122{
123   device_t *img = floppy_get_device( device->machine(), drive );
124   if (!img && device->owner()) {
125      // For slot devices, drives are typically attached to the slot rather than the machine
126      const char *floppy_name = NULL;
127      switch (drive) {
128      case 0:
129         floppy_name = FLOPPY_0;
130         break;
131      case 1:
132         floppy_name = FLOPPY_1;
133         break;
134      case 2:
135         floppy_name = FLOPPY_2;
136         break;
137      case 3:
138         floppy_name = FLOPPY_3;
139         break;
140      }
141      img = device->owner()->subdevice(floppy_name);
142   }
143   return img;
144}
145
146
121147static device_t* mc6843_floppy_image ( device_t *device )
122148{
123149   mc6843_t* mc6843 = get_safe_token( device );
124   return floppy_get_device( device->machine(), mc6843->drive );
150   return mc6843_floppy_image( device, mc6843->drive );
125151}
126152
127153
128
129154void mc6843_set_drive( device_t *device, int drive )
130155{
131156   mc6843_t* mc6843 = get_safe_token( device );
r24064r24065
234259   device_t* img = mc6843_floppy_image( device );
235260
236261   /* seek to track */
237   floppy_drive_seek( img, mc6843->GCR - mc6843->CTAR );
262   // TODO: not sure how CTAR bit 7 is handled here, but this is the safest approach for now
263   floppy_drive_seek( img, mc6843->GCR - (mc6843->CTAR & 0x7F) );
238264
239   LOG(( "%f mc6843_finish_SEK: from %i to %i (actual=%i)\n", device->machine().time().as_double(), mc6843->CTAR, mc6843->GCR, floppy_drive_get_current_track( img ) ));
265   LOG(( "%f mc6843_finish_SEK: from %i to %i (actual=%i)\n", device->machine().time().as_double(), (mc6843->CTAR & 0x7F), mc6843->GCR, floppy_drive_get_current_track( img ) ));
240266
241267   /* update state */
242268   mc6843->CTAR = mc6843->GCR;
r24064r24065
672698   }
673699
674700   case 1: /* Current-Track Address Register (CTAR) */
675      mc6843->CTAR = data & 0x7f;
701      mc6843->CTAR = data;
676702      LOG(( "%f $%04x mc6843_w: set CTAR to %i %02X (actual=%i) \n",
677703            space.machine().time().as_double(), space.machine().firstcpu->pcbase( ), mc6843->CTAR, data,
678704            floppy_drive_get_current_track( mc6843_floppy_image( device ) ) ));
r24064r24065
776802   /* setup/reset floppy drive */
777803   for ( i = 0; i < 4; i++ )
778804   {
779      device_t * img = floppy_get_device( device->machine(), i );
805      device_t * img = mc6843_floppy_image( device, i );
780806      floppy_mon_w(img, CLEAR_LINE);
781807      floppy_drive_set_ready_state( img, FLOPPY_DRIVE_READY, 0 );
782808      floppy_drive_set_rpm( img, 300. );
trunk/src/mess/mess.mak
r24064r24065
14471447$(MESSOBJ)/hitachi.a:           \
14481448   $(MESS_DRIVERS)/bmjr.o      \
14491449   $(MESS_DRIVERS)/bml3.o      \
1450   $(MESS_MACHINE)/bml3bus.o   \
1451   $(MESS_MACHINE)/bml3mp1802.o\
1452   $(MESS_MACHINE)/bml3mp1805.o\
1453   $(MESS_MACHINE)/bml3kanji.o \
14501454   $(MESS_DRIVERS)/b16.o       \
14511455
14521456$(MESSOBJ)/homebrew.a:          \
trunk/src/mess/drivers/bml3.c
r24064r24065
11/**************************************************************************************
22
3    Basic Master Level 3 (MB-6890) (c) 1980 Hitachi
3    Basic Master Level 3 (MB-689x) (c) 1980 Hitachi
44
55    Driver by Angelo Salese, Jonathan Edwards and Christopher Edwards
66
77    TODO:
88    - tape support
9    - disk support in bml3b machine
9    - implement sound as a bml3bus slot device
10    - account for hardware differences between MB-6890, MB-6891 and MB-6892
11      (e.g. custom font support on the MB-6892)
1012
1113**************************************************************************************/
1214
1315#include "emu.h"
1416#include "cpu/m6809/m6809.h"
17#include "machine/bml3bus.h"
1518#include "video/mc6845.h"
16#include "machine/wd_fdc.h"
17#include "machine/mc6843.h"
1819#include "sound/beep.h"
1920#include "machine/6821pia.h"
2021#include "machine/6850acia.h"
2122#include "sound/2203intf.h"
23#include "machine/bml3mp1802.h"
24#include "machine/bml3mp1805.h"
25#include "machine/bml3kanji.h"
2226
2327//#include "imagedev/cassette.h"
24#include "imagedev/flopdrv.h"
25//#include "formats/basicdsk.h"
26//#include "imagedev/floppy.h"
2728
2829// System clock definitions, from the MB-6890 servce manual, p.48:
2930
r24064r24065
6667   bml3_state(const machine_config &mconfig, device_type type, const char *tag)
6768      : driver_device(mconfig, type, tag),
6869      m_maincpu(*this, "maincpu"),
70      m_bml3bus(*this, "bml3bus"),
6971      m_crtc(*this, "crtc"),
7072      //m_cass(*this, "cassette"),
7173      m_beep(*this, "beeper"),
72      m_ym2203(*this, "ym2203"),
73      m_wd17xx(*this, "wd17xx"),
74      m_wd17xx_0(*this, "wd17xx:0"),
75      m_wd17xx_1(*this, "wd17xx:1"),
76      m_mc6843(*this, "mc6843")
74      m_ym2203(*this, "ym2203")
7775   {
7876   }
7977
8078   required_device<cpu_device> m_maincpu;
79   required_device<bml3bus_device> m_bml3bus;
8180   required_device<mc6845_device> m_crtc;
8281   //required_device<cassette_image_device> m_cass;
8382   required_device<beep_device> m_beep;
8483   optional_device<ym2203_device> m_ym2203;
85   optional_device<mb8866_t> m_wd17xx;
86   optional_device<floppy_connector> m_wd17xx_0;
87   optional_device<floppy_connector> m_wd17xx_1;
88   optional_device<mc6843_device> m_mc6843;
8984   DECLARE_WRITE8_MEMBER(bml3_6845_w);
9085   DECLARE_READ8_MEMBER(bml3_keyboard_r);
9186   DECLARE_WRITE8_MEMBER(bml3_keyboard_w);
r24064r24065
9388   DECLARE_WRITE8_MEMBER(bml3_vres_reg_w);
9489   DECLARE_READ8_MEMBER(bml3_vram_r);
9590   DECLARE_WRITE8_MEMBER(bml3_vram_w);
96   DECLARE_READ8_MEMBER(bml3_mp1802_r);
97   DECLARE_WRITE8_MEMBER(bml3_mp1802_w);
98   DECLARE_READ8_MEMBER(bml3_mp1805_r);
99   DECLARE_WRITE8_MEMBER(bml3_mp1805_w);
100   DECLARE_READ8_MEMBER(bml3_kanji_r);
101   DECLARE_WRITE8_MEMBER(bml3_kanji_w);
10291   DECLARE_READ8_MEMBER(bml3_psg_latch_r);
10392   DECLARE_WRITE8_MEMBER(bml3_psg_latch_w);
10493   DECLARE_READ8_MEMBER(bml3_vram_attr_r);
r24064r24065
11099   DECLARE_WRITE8_MEMBER(bml3_firq_mask_w);
111100   DECLARE_READ8_MEMBER(bml3_firq_status_r);
112101
102   DECLARE_WRITE8_MEMBER(bml3bus_nmi_w);
103   DECLARE_WRITE8_MEMBER(bml3bus_irq_w);
104   DECLARE_WRITE8_MEMBER(bml3bus_firq_w);
113105
114106   DECLARE_READ_LINE_MEMBER( bml3_acia_rx_r );
115107   DECLARE_WRITE_LINE_MEMBER( bml3_acia_tx_w );
r24064r24065
140132   UINT8 m_psg_latch;
141133   void m6845_change_clock(UINT8 setting);
142134   UINT8 m_crtc_vreg[0x100],m_crtc_index;
143   UINT16 m_kanji_addr;
144135   UINT8 *m_extram;
145136   UINT8 m_firq_mask,m_firq_status;
146137
r24064r24065
157148   TIMER_DEVICE_CALLBACK_MEMBER(keyboard_callback);
158149   DECLARE_READ8_MEMBER(bml3_ym2203_r);
159150   DECLARE_WRITE8_MEMBER(bml3_ym2203_w);
160   void bml3_wd17xx_intrq_w(bool state);
161151};
162152
163153#define mc6845_h_char_total     (m_crtc_vreg[0])
r24064r24065
403393   vram[offset+0x4000] = m_attr_latch & 0x1F;
404394}
405395
406READ8_MEMBER( bml3_state::bml3_mp1802_r)
407{
408   return m_wd17xx->drq_r() ? 0x00 : 0x80;
409}
410
411WRITE8_MEMBER( bml3_state::bml3_mp1802_w)
412{
413   int drive = data & 0x03;
414   int side = BIT(data, 4);
415   int motor = BIT(data, 3);
416
417   // drive select
418   floppy_image_device *floppy = (drive == 0 ? m_wd17xx_0 : m_wd17xx_1)->get_device();
419
420   // side select
421   if(floppy) {
422      floppy->ss_w(side);
423      floppy->mon_w(!motor);
424   }
425
426   m_wd17xx->set_floppy(floppy);
427}
428
429READ8_MEMBER( bml3_state::bml3_mp1805_r )
430{
431   //logerror("FDD 0xff20 R\n");
432   return -1;
433}
434
435WRITE8_MEMBER( bml3_state::bml3_mp1805_w )
436{
437   //logerror("FDD 0xff20 W %02x\n",data);
438   // ? something here, gets 0x81 written to it if latch found at FF19, or 0x00 if not
439   // don't know which bits are what
440   //   int drive = ?;
441   //   int side = ?;
442   //   int motor = ?;
443   //   mc6843_set_drive( machine().device("mc6843"), drive );
444   //   mc6843_set_side( machine().device("mc6843"), side );
445   //   floppy_mon_w(floppy_get_device(machine(),drive), motor);
446   //   floppy_drive_set_ready_state(floppy_get_device(machine(), drive), ASSERT_LINE, 0);
447}
448
449READ8_MEMBER( bml3_state::bml3_kanji_r )
450{
451//  return m_kanji_rom[m_kanji_addr << 1 + offset];
452   return machine().rand();
453}
454
455WRITE8_MEMBER( bml3_state::bml3_kanji_w )
456{
457   m_kanji_addr &= (0xff << (offset*8));
458   m_kanji_addr |= (data << ((offset^1)*8));
459}
460
461396READ8_MEMBER( bml3_state::bml3_psg_latch_r)
462397{
463398   return 0x7f;
r24064r24065
547482   return res;
548483}
549484
485WRITE8_MEMBER(bml3_state::bml3bus_nmi_w)
486{
487   m_maincpu->set_input_line(INPUT_LINE_NMI, data);
488}
489
490WRITE8_MEMBER(bml3_state::bml3bus_irq_w)
491{
492   m_maincpu->set_input_line(M6809_IRQ_LINE, data);
493}
494
495WRITE8_MEMBER(bml3_state::bml3bus_firq_w)
496{
497   m_maincpu->set_input_line(M6809_FIRQ_LINE, data);
498}
499
500
550501static ADDRESS_MAP_START(bml3_mem, AS_PROGRAM, 8, bml3_state)
551502   ADDRESS_MAP_UNMAP_HIGH
552503   AM_RANGE(0x0000, 0x03ff) AM_RAM
553504   AM_RANGE(0x0400, 0x43ff) AM_READWRITE(bml3_vram_r,bml3_vram_w)
554505   AM_RANGE(0x4400, 0x9fff) AM_RAM
555   AM_RANGE(0xff75, 0xff76) AM_READWRITE(bml3_kanji_r,bml3_kanji_w)// kanji i/f
556506   AM_RANGE(0xffc0, 0xffc3) AM_DEVREADWRITE("pia6821", pia6821_device, read, write)
557507   AM_RANGE(0xffc4, 0xffc4) AM_DEVREADWRITE("acia6850", acia6850_device, status_read, control_write)
558508   AM_RANGE(0xffc5, 0xffc5) AM_DEVREADWRITE("acia6850", acia6850_device, data_read, data_write)
r24064r24065
594544   AM_RANGE(0xe000, 0xefff) AM_WRITE(bml3_e000_w)
595545   AM_RANGE(0xf000, 0xfeff) AM_WRITE(bml3_f000_w)
596546   AM_RANGE(0xfff0, 0xffff) AM_WRITE(bml3_fff0_w)
547
548#if 0
549   AM_RANGE(0xff00, 0xff00) AM_READWRITE(bml3_ym2203_r,bml3_ym2203_w)
550   AM_RANGE(0xff02, 0xff02) AM_READWRITE(bml3_psg_latch_r,bml3_psg_latch_w) // PSG address/data select
551#endif
597552ADDRESS_MAP_END
598553
599static ADDRESS_MAP_START(bml3a_mem, AS_PROGRAM, 8, bml3_state)
554static ADDRESS_MAP_START(bml3mk2_mem, AS_PROGRAM, 8, bml3_state)
600555   AM_IMPORT_FROM(bml3_mem)
556   // TODO: anything to add here?
601557
602   AM_RANGE(0xff00, 0xff03) AM_DEVREADWRITE("wd17xx", mb8866_t, read, write)
603   AM_RANGE(0xff04, 0xff04) AM_READWRITE(bml3_mp1802_r,bml3_mp1802_w)
604558ADDRESS_MAP_END
605559
606static ADDRESS_MAP_START(bml3b_mem, AS_PROGRAM, 8, bml3_state)
560static ADDRESS_MAP_START(bml3mk5_mem, AS_PROGRAM, 8, bml3_state)
607561   AM_IMPORT_FROM(bml3_mem)
562   // TODO: anything to add here?
608563
609   AM_RANGE(0xff00, 0xff00) AM_READWRITE(bml3_ym2203_r,bml3_ym2203_w)
610   // TODO: what's this?
611   // AM_RANGE(0xff02, 0xff02) AM_READWRITE(bml3_psg_latch_r,bml3_psg_latch_w) // PSG address/data select
612   AM_RANGE(0xff18, 0xff1f) AM_DEVREADWRITE_LEGACY("mc6843",mc6843_r,mc6843_w)
613   AM_RANGE(0xff20, 0xff20) AM_READWRITE(bml3_mp1805_r,bml3_mp1805_w) // FDD drive select
614564ADDRESS_MAP_END
615565
616
617566/* Input ports */
618567
619568static INPUT_PORTS_START( bml3 )
r24064r24065
767716   NULL        /* update address callback */
768717};
769718
770void bml3_state::bml3_wd17xx_intrq_w(bool state)
771{
772   if (state)
773      m_maincpu->set_input_line(INPUT_LINE_NMI, PULSE_LINE);
774}
775
776719TIMER_DEVICE_CALLBACK_MEMBER(bml3_state::keyboard_callback)
777720{
778721   static const char *const portnames[3] = { "key1","key2","key3" };
r24064r24065
782725   {
783726      m_keyb_scancode = (m_keyb_scancode + 1) & 0x7F;
784727      if (m_keyb_counter_operation_disabled) {
785         m_keyb_scancode &= 0xF;
728         m_keyb_scancode &= 0x7;
786729      }
787730
788731      if (m_keyb_scancode == 0x7F)
r24064r24065
850793   m_beep->set_frequency(1200); //guesswork
851794   m_beep->set_state(0);
852795   m_extram = auto_alloc_array(machine(),UINT8,0x10000);
853
854   // floppy callbacks
855   if (m_wd17xx) {
856      m_wd17xx->setup_intrq_cb(wd_fdc_t::line_cb(FUNC(bml3_state::bml3_wd17xx_intrq_w), this));
857   }
858796}
859797
860798void bml3_state::machine_reset()
r24064r24065
873811   m_firq_mask = -1; // disable firq
874812}
875813
876const mc6843_interface bml3_6843_if = { NULL };
877
878814WRITE8_MEMBER(bml3_state::bml3_piaA_w)
879815{
880816   address_space &mem = m_maincpu->space(AS_PROGRAM);
r24064r24065
1045981   DEVCB_NULL  // write B
1046982};
1047983
1048static const floppy_format_type bml3_floppy_formats[] = {
1049   FLOPPY_D88_FORMAT,
1050   NULL
984static const struct bml3bus_interface bml3bus_intf =
985{
986   // interrupt lines
987   DEVCB_DRIVER_MEMBER(bml3_state,bml3bus_nmi_w),
988   DEVCB_DRIVER_MEMBER(bml3_state,bml3bus_irq_w),
989   DEVCB_DRIVER_MEMBER(bml3_state,bml3bus_firq_w),
1051990};
1052991
1053static SLOT_INTERFACE_START( bml3_mp1802_floppies )
1054   SLOT_INTERFACE( "525dd", FLOPPY_525_DD )
992static SLOT_INTERFACE_START(bml3_cards)
993   SLOT_INTERFACE("bml3mp1802", BML3BUS_MP1802)  /* MP-1802 Floppy Controller Card */
994   SLOT_INTERFACE("bml3mp1805", BML3BUS_MP1805)  /* MP-1805 Floppy Controller Card */
995   SLOT_INTERFACE("bml3kanji",  BML3BUS_KANJI)
1055996SLOT_INTERFACE_END
1056997
1057static const floppy_interface bml3_mp1805_floppy_interface =
1058{
1059   DEVCB_NULL,
1060   DEVCB_NULL,
1061   DEVCB_NULL,
1062   DEVCB_NULL,
1063   DEVCB_NULL,
1064   FLOPPY_STANDARD_3_SSDD,
1065   LEGACY_FLOPPY_OPTIONS_NAME(default),
1066   NULL
1067};
1068998
1069//static SLOT_INTERFACE_START( bml3_mp1805_floppies )
1070//   SLOT_INTERFACE( "3ssdd", FLOPPY_3_SSDD )
1071//SLOT_INTERFACE_END
1072
1073999static MACHINE_CONFIG_START( bml3_common, bml3_state )
10741000   /* basic machine hardware */
10751001   MCFG_CPU_ADD("maincpu",M6809, CPU_CLOCK)
r24064r24065
11011027   MCFG_SOUND_ADD("beeper", BEEP, 0)
11021028   MCFG_SOUND_ROUTE(ALL_OUTPUTS,"mono",0.50)
11031029
1104   MCFG_SOFTWARE_LIST_ADD("disk_list","bml3_flop")
1030   /* slot devices */
1031   MCFG_BML3BUS_BUS_ADD("bml3bus", "maincpu", bml3bus_intf)
1032   /* Default to MP-1805 disk (3" or 5.25" SS/SD), as our MB-6892 ROM dump includes
1033      the MP-1805 ROM.
1034      User may want to switch this to MP-1802 (5.25" DS/DD).
1035      Note it isn't feasible to use both, as they each place boot ROM at F800.
1036    */
1037   MCFG_BML3BUS_SLOT_ADD("bml3bus", "sl1", bml3_cards, "bml3mp1805")
1038   MCFG_BML3BUS_SLOT_ADD("bml3bus", "sl2", bml3_cards, NULL)
1039   MCFG_BML3BUS_SLOT_ADD("bml3bus", "sl3", bml3_cards, NULL)
1040   MCFG_BML3BUS_SLOT_ADD("bml3bus", "sl4", bml3_cards, NULL)
1041   MCFG_BML3BUS_SLOT_ADD("bml3bus", "sl5", bml3_cards, NULL)
1042   MCFG_BML3BUS_SLOT_ADD("bml3bus", "sl6", bml3_cards, "bml3kanji")
11051043
11061044MACHINE_CONFIG_END
11071045
r24064r24065
11091047   MCFG_CPU_MODIFY( "maincpu" )
11101048   MCFG_CPU_PROGRAM_MAP(bml3_mem)
11111049
1112   // MCFG_MACHINE_START_OVERRIDE( bml3_state, bml3 )
1113MACHINE_CONFIG_END
1114
1115static MACHINE_CONFIG_DERIVED( bml3a, bml3_common )
1116   MCFG_CPU_MODIFY( "maincpu" )
1117   MCFG_CPU_PROGRAM_MAP(bml3a_mem)
1118   /* floppy */
1119   MCFG_MB8866x_ADD("wd17xx", CPU_CLOCK )
1120   MCFG_FLOPPY_DRIVE_ADD("wd17xx:0", bml3_mp1802_floppies, "525dd", bml3_floppy_formats)
1121   MCFG_FLOPPY_DRIVE_ADD("wd17xx:1", bml3_mp1802_floppies, "525dd", bml3_floppy_formats)
1122MACHINE_CONFIG_END
1123
1124static MACHINE_CONFIG_DERIVED( bml3b, bml3_common )
1125   MCFG_CPU_MODIFY( "maincpu" )
1126   MCFG_CPU_PROGRAM_MAP(bml3b_mem)
1127   /* floppy */
1128   MCFG_MC6843_ADD( "mc6843", bml3_6843_if )
1129   MCFG_LEGACY_FLOPPY_4_DRIVES_ADD(bml3_mp1805_floppy_interface)
1130//   MCFG_FLOPPY_DRIVE_ADD("mc6843:0", bml3_mp1805_floppies, "3ssdd", bml3_floppy_formats)
1131//   MCFG_FLOPPY_DRIVE_ADD("mc6843:1", bml3_mp1805_floppies, "3ssdd", bml3_floppy_formats)
1132
1050#if 0
1051   // TODO: slot device for sound card
11331052   // audio
11341053   MCFG_SOUND_ADD("ym2203", YM2203, 2000000) //unknown clock / divider
11351054   MCFG_YM2203_AY8910_INTF(&ay8910_config)
r24064r24065
11371056   MCFG_SOUND_ROUTE(1, "mono", 0.25)
11381057   MCFG_SOUND_ROUTE(2, "mono", 0.50)
11391058   MCFG_SOUND_ROUTE(3, "mono", 0.50)
1059#endif
11401060MACHINE_CONFIG_END
11411061
1062static MACHINE_CONFIG_DERIVED( bml3mk2, bml3_common )
1063   MCFG_CPU_MODIFY( "maincpu" )
1064   MCFG_CPU_PROGRAM_MAP(bml3mk2_mem)
11421065
1066   // TODO: anything to add here?
1067MACHINE_CONFIG_END
11431068
1069static MACHINE_CONFIG_DERIVED( bml3mk5, bml3_common )
1070   MCFG_CPU_MODIFY( "maincpu" )
1071   MCFG_CPU_PROGRAM_MAP(bml3mk5_mem)
1072
1073   // TODO: anything to add here?
1074MACHINE_CONFIG_END
1075
1076
1077
11441078/* ROM definition */
11451079ROM_START( bml3 )
11461080   ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASEFF )
11471081//  ROM_LOAD( "l3bas.rom", 0xa000, 0x6000, BAD_DUMP CRC(d81baa07) SHA1(a8fd6b29d8c505b756dbf5354341c48f9ac1d24d)) //original, 24k isn't a proper rom size!
1148   /* Handcrafted ROMs, rom labels and contents might not match */
1082   // TODO: replace with MB-6890 ROMs (these are from an MB-6892)
11491083   ROM_LOAD( "598 p16611.ic3", 0xa000, 0x2000, BAD_DUMP CRC(954b9bad) SHA1(047948fac6808717c60a1d0ac9205a5725362430))
11501084   ROM_LOAD( "599 p16561.ic4", 0xc000, 0x2000, BAD_DUMP CRC(b27a48f5) SHA1(94cb616df4caa6415c5076f9acdf675acb7453e2))
11511085   // TODO: Replace checksums with a ROM dump without a disk controller patch (checksums here are inclusive of the MP1805 patch)
r24064r24065
11551089   ROM_LOAD("font.rom", 0x00000, 0x1000, BAD_DUMP CRC(0b6f2f10) SHA1(dc411b447ca414e94843636d8b5f910c954581fb) ) // handcrafted
11561090
11571091   ROM_REGION( 0x8000, "vram", ROMREGION_ERASEFF )
1158
1159   ROM_REGION( 0x20000, "kanji", ROMREGION_ERASEFF )
1160   ROM_LOAD("kanji.rom", 0x00000, 0x20000, NO_DUMP )
11611092ROM_END
11621093
1163ROM_START( bml3a )
1094ROM_START( bml3mk2 )
11641095   ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASEFF )
11651096//  ROM_LOAD( "l3bas.rom", 0xa000, 0x6000, BAD_DUMP CRC(d81baa07) SHA1(a8fd6b29d8c505b756dbf5354341c48f9ac1d24d)) //original, 24k isn't a proper rom size!
1166   /* Handcrafted ROMs, rom labels and contents might not match */
1097   // TODO: replace with MB-6891 ROMs (these are from an MB-6892)
11671098   ROM_LOAD( "598 p16611.ic3", 0xa000, 0x2000, BAD_DUMP CRC(954b9bad) SHA1(047948fac6808717c60a1d0ac9205a5725362430))
11681099   ROM_LOAD( "599 p16561.ic4", 0xc000, 0x2000, BAD_DUMP CRC(b27a48f5) SHA1(94cb616df4caa6415c5076f9acdf675acb7453e2))
1169   // TODO: Replace checksums with a ROM dump without a disk controller patch (checksums here are inclusive of the MP1805 patch)
11701100   ROM_LOAD( "600 p16681.ic5", 0xe000, 0x2000, BAD_DUMP CRC(fe3988a5) SHA1(edc732f1cd421e0cf45ffcfc71c5589958ceaae7))
11711101
1172   // MP-1502 disk controller ROM, which replaces part of the system ROM
1173   ROM_LOAD( "mp1802.rom", 0xf800, 0x0800, BAD_DUMP CRC(8d0dc101) SHA1(92f7d1cebecafa7472e45c4999520de5c01c6dbc))
1174
11751102   ROM_REGION( 0x1000, "chargen", 0 )
11761103   ROM_LOAD("font.rom", 0x00000, 0x1000, BAD_DUMP CRC(0b6f2f10) SHA1(dc411b447ca414e94843636d8b5f910c954581fb) ) // handcrafted
11771104
11781105   ROM_REGION( 0x8000, "vram", ROMREGION_ERASEFF )
1179
1180   ROM_REGION( 0x20000, "kanji", ROMREGION_ERASEFF )
1181   ROM_LOAD("kanji.rom", 0x00000, 0x20000, NO_DUMP )
11821106ROM_END
11831107
1184ROM_START( bml3b )
1108ROM_START( bml3mk5 )
11851109   ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASEFF )
11861110//  ROM_LOAD( "l3bas.rom", 0xa000, 0x6000, BAD_DUMP CRC(d81baa07) SHA1(a8fd6b29d8c505b756dbf5354341c48f9ac1d24d)) //original, 24k isn't a proper rom size!
11871111   /* Handcrafted ROMs, rom labels and contents might not match */
r24064r24065
11901114   // TODO: Replace checksums with a ROM dump without a disk controller patch (checksums here are inclusive of the MP1805 patch)
11911115   ROM_LOAD( "600 p16681.ic5", 0xe000, 0x2000, BAD_DUMP CRC(fe3988a5) SHA1(edc732f1cd421e0cf45ffcfc71c5589958ceaae7))
11921116
1193   // MP-1505 disk controller ROM, which replaces part of the system ROM
1194   ROM_LOAD( "mp1805.rom", 0xf800, 0x0800, BAD_DUMP CRC(b532d8d9) SHA1(6f1160356d5bf64b5926b1fdb60db414edf65f22))
1195
11961117   ROM_REGION( 0x1000, "chargen", 0 )
11971118   ROM_LOAD("font.rom", 0x00000, 0x1000, BAD_DUMP CRC(0b6f2f10) SHA1(dc411b447ca414e94843636d8b5f910c954581fb) ) // handcrafted
11981119
11991120   ROM_REGION( 0x8000, "vram", ROMREGION_ERASEFF )
1200
1201   ROM_REGION( 0x20000, "kanji", ROMREGION_ERASEFF )
1202   ROM_LOAD("kanji.rom", 0x00000, 0x20000, NO_DUMP )
12031121ROM_END
12041122
12051123/* Driver */
12061124
1207/* Configurations are focussed on disk support rather than computer model.
1208 * The following three models were produced:
1209 *
1210 * <year> / <model> / <name>
1211 * 1980 / MB-6890 / Basic Master Level 3
1212 * 1982 / MB-6891 / Basic Master Level 3 Mark 2
1213 * 1983 / MB-6892 / Basic Master Level 3 Mark 5
1214 *
1215 * If it turns out that these models had different ROMs or significant base hardware changes, then a model-oriented configuration
1216 * set might be more appropriate.
1217 */
1218
12191125/*    YEAR  NAME    PARENT  COMPAT   MACHINE    INPUT    INIT                      COMPANY    FULLNAME                        FLAGS */
12201126COMP( 1980, bml3,   0,      0,       bml3,      bml3,    driver_device,    0,      "Hitachi", "MB-6890 Basic Master Level 3", GAME_NOT_WORKING)
1221COMP( 1980, bml3a,  bml3,   0,       bml3a,     bml3,    driver_device,    0,      "Hitachi", "MB-6890 Basic Master Level 3 + MP-1502 (5.25\" disk)", 0)
1222COMP( 1980, bml3b,  bml3,   0,       bml3b,     bml3,    driver_device,    0,      "Hitachi", "MB-6890 Basic Master Level 3 + MP-1505 (3\" disk) + YM-2203 (sound)", GAME_NOT_WORKING)
1127COMP( 1982, bml3mk2,bml3,   0,       bml3mk2,   bml3,    driver_device,    0,      "Hitachi", "MB-6891 Basic Master Level 3 Mark 2", GAME_NOT_WORKING)
1128COMP( 1983, bml3mk5,bml3,   0,       bml3mk5,   bml3,    driver_device,    0,      "Hitachi", "MB-6892 Basic Master Level 3 Mark 5", GAME_NOT_WORKING)
trunk/src/mess/tools/imgtool/imgtool.mak
r24064r24065
6060   $(IMGTOOL_MODULES)/cybiko.o         \
6161   $(IMGTOOL_MODULES)/cybikoxt.o       \
6262   $(IMGTOOL_MODULES)/psion.o      \
63   $(IMGTOOL_MODULES)/bml3.o      \
6364
6465$(LIBIMGTOOL): $(IMGTOOL_LIB_OBJS)
6566
trunk/src/mess/tools/imgtool/modules.c
r24064r24065
111111MODULE(cybiko)
112112MODULE(cybikoxt)
113113MODULE(psion)
114MODULE(bml3)
114115
115116#endif /* MODULES_RECURSIVE */
trunk/src/mess/tools/imgtool/filtbas.c
r24064r24065
807807   NULL        /* 0xff */
808808};
809809
810static const char *const bml3bas_statements[] =
811{
812   "END",      /* 0x80 */
813   "FOR",      /* 0x81 */
814   "NEXT",     /* 0x82 */
815   "DATA",     /* 0x83 */
816   "DIM",      /* 0x84 */
817   "READ",     /* 0x85 */
818   "LET",      /* 0x86 */
819   "GO",       /* 0x87 */
820   "RUN",      /* 0x88 */
821   "IF",       /* 0x89 */
822   "RESTORE",  /* 0x8a */
823   "RETURN",   /* 0x8b */
824   "REM",      /* 0x8c */
825   "'",        /* 0x8d */
826   "STOP",     /* 0x8e */
827   "ELSE",     /* 0x8f */
828   "TRON",     /* 0x90 */
829   "TROFF",    /* 0x91 */
830   "SWAP",     /* 0x92 */
831   "DEFSTR",   /* 0x93 */
832   "DEFINT",   /* 0x94 */
833   "DEFSNG",   /* 0x95 */
834   "DEFDBL",   /* 0x96 */
835   "ON",       /* 0x97 */
836   "WAIT",     /* 0x98 */
837   "RENUM",    /* 0x99 */
838   "EDIT",     /* 0x9a */
839   "ERROR",    /* 0x9b */
840   "RESUME",   /* 0x9c */
841   "AUTO",     /* 0x9d */
842   "DELETE",   /* 0x9e */
843   "TERM",     /* 0x9f */
844   "WIDTH",    /* 0xa0 */
845   "UNLIST",   /* 0xa1 */
846   "MON",      /* 0xa2 */
847   "LOCATE",   /* 0xa3 */
848   "CLS",      /* 0xa4 */
849   "CONSOLE",  /* 0xa5 */
850   "PSET",     /* 0xa6 */
851   "PRESET",   /* 0xa7 */
852   "MOTOR",    /* 0xa8 */
853   "SKIPF",    /* 0xa9 */
854   "SAVE",     /* 0xaa */
855   "LOAD",     /* 0xab */
856   "MERGE",    /* 0xac */
857   "EXEC",     /* 0xad */
858   "OPEN",     /* 0xae */
859   "CLOSE",    /* 0xaf */
860   "FILES",    /* 0xb0 */
861   "COM",      /* 0xb1 */
862   "KEY",      /* 0xb2 */
863   "PAINT",    /* 0xb3 */
864   "BEEP",     /* 0xb4 */
865   "COLOR",    /* 0xb5 */
866   "LINE",     /* 0xb6 */
867   "DEF",      /* 0xb7 */
868   "POKE",     /* 0xb8 */
869   "PRINT",    /* 0xb9 */
870   "CONT",     /* 0xba */
871   "LIST",     /* 0xbb */
872   "CLEAR",    /* 0xbc */
873   "RANDOMIZE",/* 0xbd */
874   "WHILE",    /* 0xbe */
875   "WEND",     /* 0xbf */
876   "NEW",      /* 0xc0 */
877   "TAB(",     /* 0xc1 */
878   "TO",       /* 0xc2 */
879   "SUB",      /* 0xc3 */
880   "FN",       /* 0xc4 */
881   "SPC(",     /* 0xc5 */
882   "USING",    /* 0xc6 */
883   "USR",      /* 0xc7 */
884   "ERL",      /* 0xc8 */
885   "ERR",      /* 0xc9 */
886   "OFF",      /* 0xca */
887   "THEN",     /* 0xcb */
888   "NOT",      /* 0xcc */
889   "STEP",     /* 0xcd */
890   "+",        /* 0xce */
891   "-",        /* 0xcf */
892   "*",        /* 0xd0 */
893   "/",        /* 0xd1 */
894   "^",        /* 0xd2 */
895   "AND",      /* 0xd3 */
896   "OR",       /* 0xd4 */
897   "XOR",      /* 0xd5 */
898   "EQV",      /* 0xd6 */
899   "IMP",      /* 0xd7 */
900   "MOD",      /* 0xd8 */
901   "\\",       /* 0xd9 */
902   ">",        /* 0xda */
903   "=",        /* 0xdb */
904   "<"         /* 0xdc */
905};
906
907static const char *const bml3bas_functions[] =
908{
909   "SGN",      /* 0xff80 */
910   "INT",      /* 0xff81 */
911   "ABS",      /* 0xff82 */
912   "FRE",      /* 0xff83 */
913   "POS",      /* 0xff84 */
914   "SQR",      /* 0xff85 */
915   "LOG",      /* 0xff86 */
916   "EXP",      /* 0xff87 */
917   "COS",      /* 0xff88 */
918   "SIN",      /* 0xff89 */
919   "TAN",      /* 0xff8a */
920   "ATN",      /* 0xff8b */
921   "PEEK",     /* 0xff8c */
922   "LEN",      /* 0xff8d */
923   "STR$",     /* 0xff8e */
924   "VAL",      /* 0xff8f */
925   "ASC",      /* 0xff90 */
926   "CHR$",     /* 0xff91 */
927   "CINT",     /* 0xff92 */
928   "CSNG",     /* 0xff93 */
929   "CDBL",     /* 0xff94 */
930   "FIX",      /* 0xff95 */
931   "SPACE$",   /* 0xff96 */
932   "HEX$",     /* 0xff97 */
933   "OCT$",     /* 0xff98 */
934   "LOF",      /* 0xff99 */
935   "EOF",      /* 0xff9a */
936   "PEN",      /* 0xff9b */
937   "LEFT$",    /* 0xff9c */
938   "RIGHT$",   /* 0xff9d */
939   "MID$",     /* 0xff9e */
940   "INSTR",    /* 0xff9f */
941   "SCREEN",   /* 0xffa0 */
942   "VARPTR",   /* 0xffa1 */
943   "STRING$",  /* 0xffa2 */
944   "RND",      /* 0xffa3 */
945   "INKEY$",   /* 0xffa4 */
946   "INPUT",    /* 0xffa5 */
947   "CSRLIN",   /* 0xffa6 */
948   "POINT",    /* 0xffa7 */
949   "TIME",     /* 0xffa8 */
950   "DATE"      /* 0xffa9 */
951};
952
953
810954#ifdef BASIC_
811955/* ----------------------------------------------------------------------- *
812956 * CBM machines                                                            *
r24064r24065
29233067      case FILTINFO_PTR_WRITEFILE:    info->write_file = vzbas_writefile; break;
29243068   }
29253069}
3070
3071
3072
3073/***************************************************************************
3074    BML3 BASIC
3075***************************************************************************/
3076
3077static const basictoken_tableent bml3bas_tokenents[] =
3078{
3079   { 0x00, 0x80,   bml3bas_statements, ARRAY_LENGTH(bml3bas_statements) },
3080   { 0xff, 0x80,   bml3bas_functions,  ARRAY_LENGTH(bml3bas_functions) }
3081};
3082
3083static const basictokens bml3bas_tokens =
3084{
3085   0x2600,
3086   3,
3087   TRUE,
3088   bml3bas_tokenents,
3089   ARRAY_LENGTH(bml3bas_tokenents)
3090};
3091
3092static imgtoolerr_t bml3bas_readfile(imgtool_partition *partition, const char *filename,
3093   const char *fork, imgtool_stream *destf)
3094{
3095   return basic_readfile(&bml3bas_tokens, partition, filename, fork, destf);
3096}
3097
3098static imgtoolerr_t bml3bas_writefile(imgtool_partition *partition, const char *filename,
3099   const char *fork, imgtool_stream *sourcef, option_resolution *opts)
3100{
3101   return basic_writefile(&bml3bas_tokens, partition, filename, fork, sourcef, opts);
3102}
3103
3104void filter_bml3bas_getinfo(UINT32 state, union filterinfo *info)
3105{
3106   switch(state)
3107   {
3108      case FILTINFO_STR_NAME:         info->s = "bml3bas"; break;
3109      case FILTINFO_STR_HUMANNAME:    info->s = "Basic Master Level 3 Tokenized Basic Files"; break;
3110      case FILTINFO_PTR_READFILE:     info->read_file = bml3bas_readfile; break;
3111      case FILTINFO_PTR_WRITEFILE:    info->write_file = bml3bas_writefile; break;
3112   }
3113}
3114
trunk/src/mess/tools/imgtool/filter.c
r24064r24065
5858   filter_thombas7_getinfo,
5959   filter_thombas128_getinfo,
6060   filter_thomcrypt_getinfo,
61   filter_bml3bas_getinfo,
6162   NULL
6263};
6364
trunk/src/mess/tools/imgtool/modules/bml3.c
r0r24065
1/****************************************************************************
2
3    bml3.c
4
5    Hitachi bml3 disk images
6
7    By Jonathan Edwards, based on rsdos.c (both use Microsoft BASIC)
8
9****************************************************************************/
10
11/* Supported Hitachi floppy formats are:
12   - 3" or 5"1/4 single density, single-sided: 40 tracks, 16 sectors/track, 128 bytes/sector
13   -   (used with MP-1805 floppy disk controller card)
14   - 5"1/4 double density, double-sided: 40 tracks, 16 sectors/track, 256 bytes/sector
15   -   (first track on first head may be single density)
16   -   (used with MP-1802 floppy disk controller card)
17*/
18
19#include <stdio.h>
20#include <string.h>
21#include <stdlib.h>
22#include "imgtool.h"
23#include "iflopimg.h"
24
25#define MAX_SECTOR_SIZE 256
26
27struct bml3_diskinfo
28{
29   UINT16 sector_size;   /* 128 or 256 */
30   UINT8  heads;         /* 1 or 2 */
31   UINT8  fat_start_sector; /* in cylinder 20, start sector of FAT */
32   UINT8  fat_start_offset; /* start byte of FAT in sector */
33   UINT8  fat_sectors;   /* the number of sectors in the FAT */
34   UINT8  dirent_start_sector;  /* in cylinder 20, start sector of directory entries */
35   UINT8  granule_sectors;  /* how many sectors per granule */
36   UINT8  first_granule_cylinder; /* the number of the first cylinder with granule numbers assigned */
37   UINT8  variant;       /* 0 - older version, uses EOF to terminate files, 1 - newer version, stores file length */
38};
39
40/* this structure mirrors the structure of a directory entry on disk */
41struct bml3_dirent
42{
43   char fname[8];
44   char fext[3];
45   UINT8 ftype;
46   UINT8 asciiflag;
47   UINT8 first_granule;
48   UINT16 lastsectorbytes;
49   // TODO there are some 'unused' bytes here that are sometimes used to store a timestamp, maybe support this?
50};
51
52struct bml3_direnum
53{
54   int index;
55   int eof;
56};
57
58#define MAX_GRANULEMAP_SIZE 256
59
60struct granule_list_t {
61   UINT8 granules[MAX_GRANULEMAP_SIZE];
62   UINT8 granule_count;
63   UINT8 last_granule_sectors;
64};
65
66#define BML3_OPTIONS_FTYPE     'T'
67#define BML3_OPTIONS_ASCII     'M'
68
69static imgtoolerr_t bml3_diskimage_deletefile(imgtool_partition *partition, const char *fname);
70
71
72
73/*********************************************************************
74    Imgtool module code
75*********************************************************************/
76
77static bml3_diskinfo *bml3_get_diskinfo(imgtool_image *image)
78{
79   return (bml3_diskinfo *) imgtool_floppy_extrabytes(image);
80}
81
82
83
84static int max_dirents(imgtool_image *image)
85{
86   bml3_diskinfo *info = bml3_get_diskinfo(image);
87   return (16 * info->heads + 1 - info->dirent_start_sector)*(info->sector_size/32);
88}
89
90
91
92static void dirent_location(imgtool_image *image, int index_loc, UINT8 *head, UINT8 *track, UINT8 *sector, UINT8 *offset)
93{
94   bml3_diskinfo *info = bml3_get_diskinfo(image);
95   *track = 20;
96   *sector = info->dirent_start_sector + index_loc / (info->sector_size / 32);
97   *head = 0;
98   if (*sector > 16) {
99      // wrap to second head
100      *sector -= 16;
101      (*head)++;
102   }
103   *offset = index_loc % (info->sector_size/32) * 32;
104}
105
106
107
108static floperr_t get_bml3_dirent(imgtool_image *f, int index_loc, struct bml3_dirent *ent)
109{
110   floperr_t err;
111   UINT8 head, track, sector, offset;
112   UINT8 buf[32];
113   bml3_diskinfo *info = bml3_get_diskinfo(f);
114   dirent_location(f, index_loc, &head, &track, &sector, &offset);
115   err = floppy_read_sector(imgtool_floppy(f), head, track, sector, offset, (void *) buf, sizeof(buf));
116   memset(ent, 0, sizeof(*ent));
117   switch (info->variant) {
118   case 0:
119      memcpy(&ent->fname, &buf[0], 8);
120      ent->ftype = buf[11];
121      ent->asciiflag = buf[12];
122      ent->first_granule = buf[14];
123      break;
124   case 1:
125      memcpy(&ent->fname, &buf[0], 8);
126      memcpy(&ent->fext, &buf[8], 3);
127      ent->ftype = buf[11];
128      ent->asciiflag = buf[12];
129      ent->first_granule = buf[13];
130      ent->lastsectorbytes = (buf[14] << 8) | buf[15];
131      break;
132   default:
133      return FLOPPY_ERROR_INVALIDIMAGE;
134   }
135   return err;
136}
137
138
139
140static floperr_t put_bml3_dirent(imgtool_image *f, int index_loc, const struct bml3_dirent *ent)
141{
142   floperr_t err;
143   UINT8 head, track, sector, offset;
144   UINT8 buf[32];
145   bml3_diskinfo *info = bml3_get_diskinfo(f);
146   if (index_loc >= max_dirents(f))
147      return (floperr_t)IMGTOOLERR_FILENOTFOUND;
148   dirent_location(f, index_loc, &head, &track, &sector, &offset);
149   memset(buf, 0, sizeof(buf));
150   switch (info->variant) {
151   case 0:
152      memcpy(&buf[0], &ent->fname, 8);
153      buf[11] = ent->ftype;
154      buf[12] = ent->asciiflag;
155      buf[14] = ent->first_granule;
156      break;
157   case 1:
158      memcpy(&buf[0], &ent->fname, 8);
159      memcpy(&buf[8], &ent->fext, 3);
160      buf[11] = ent->ftype;
161      buf[12] = ent->asciiflag;
162      buf[13] = ent->first_granule;
163      buf[14] = ent->lastsectorbytes >> 8;
164      buf[15] = ent->lastsectorbytes & 0xff;
165      break;
166   default:
167      return FLOPPY_ERROR_INVALIDIMAGE;
168   }
169   err = floppy_write_sector(imgtool_floppy(f), head, track, sector, offset, (void *) buf, sizeof(buf), 0); /* TODO: pass ddam argument from imgtool */
170   return err;
171}
172
173
174
175/* fnamebuf must have at least 13 bytes */
176static void get_dirent_fname(char *fnamebuf, const struct bml3_dirent *ent)
177{
178   char *s;
179
180   memset(fnamebuf, 0, 13);
181   memcpy(fnamebuf, ent->fname, sizeof(ent->fname));
182   rtrim(fnamebuf);
183   s = fnamebuf + strlen(fnamebuf);
184   *(s++) = '.';
185   memcpy(s, ent->fext, sizeof(ent->fext));
186   rtrim(s);
187
188   /* If no extension, remove period */
189   if (*s == '\0')
190      s[-1] = '\0';
191}
192
193
194
195static imgtoolerr_t lookup_bml3_file(imgtool_image *f, const char *fname, struct bml3_dirent *ent, int *position)
196{
197   int i;
198   floperr_t ferr;
199   char fnamebuf[13];
200
201   i = 0;
202   fnamebuf[0] = '\0';
203
204   do
205   {
206      do
207      {
208         ferr = get_bml3_dirent(f, i++, ent);
209         if (ferr)
210            return imgtool_floppy_error(ferr);
211      }
212      while(ent->fname[0] == '\0');
213
214
215      if (ent->fname[0] != -1)
216         get_dirent_fname(fnamebuf, ent);
217   }
218   while((ent->fname[0] != -1) && core_stricmp(fnamebuf, fname));
219
220   if (ent->fname[0] == -1)
221      return IMGTOOLERR_FILENOTFOUND;
222
223   if (position)
224      *position = i - 1;
225   return (imgtoolerr_t)0;
226}
227
228
229
230static UINT8 get_granule_count(imgtool_image *img)
231{
232   // UINT16 tracks;
233   UINT16 disk_granules;
234   bml3_diskinfo *info = bml3_get_diskinfo(img);
235
236   // This always returns 82 for D88, so not quite right
237   // tracks = floppy_get_tracks_per_disk(imgtool_floppy(img));
238
239   // The number of granules is primarily constrained by the disk capacity.
240   disk_granules = (40 - 1 - info->first_granule_cylinder) * info->heads * (16 / info->granule_sectors);
241   // Also, granule numbers from 0xC0 upwards are reserved for terminating a granule chain
242   return (UINT8)((disk_granules < 0xC0) ? disk_granules : 0xC0);
243}
244
245/* granule_map must be an array of MAX_GRANULEMAP_SIZE bytes */
246static floperr_t get_granule_map(imgtool_image *img, UINT8 *granule_map, UINT8 *granule_count)
247{
248   bml3_diskinfo *info = bml3_get_diskinfo(img);
249   UINT8 count;
250
251   count = get_granule_count(img);
252   if (granule_count)
253      *granule_count = count;
254
255   // The first byte of the granule map sector is ignored (and expected to be 0)
256   return floppy_read_sector(imgtool_floppy(img), 0, 20, info->fat_start_sector, info->fat_start_offset, granule_map, count);
257}
258
259
260
261static floperr_t put_granule_map(imgtool_image *img, const UINT8 *granule_map, UINT8 granule_count)
262{
263   bml3_diskinfo *info = bml3_get_diskinfo(img);
264   return floppy_write_sector(imgtool_floppy(img), 0, 20, info->fat_start_sector, info->fat_start_offset, granule_map, granule_count, 0);    /* TODO: pass ddam argument from imgtool */
265}
266
267
268
269
270static void granule_location(imgtool_image *image, UINT8 granule, UINT8 *head, UINT8 *track, UINT8 *sector)
271{
272   bml3_diskinfo *info = bml3_get_diskinfo(image);
273   UINT16 abs_track = granule * info->granule_sectors / 16;
274   *head = abs_track % info->heads;
275   *track = abs_track / info->heads + info->first_granule_cylinder;
276   // skip filesystem cylinder
277   if (*track >= 20)
278      (*track)++;
279   *sector = granule * info->granule_sectors % 16 + 1;
280}
281
282
283
284static imgtoolerr_t transfer_granule(imgtool_image *img, UINT8 granule, int length, imgtool_stream *f, imgtoolerr_t (*proc)(imgtool_image *, int, int, int, int, size_t, imgtool_stream *))
285{
286   imgtoolerr_t err = IMGTOOLERR_SUCCESS;
287   UINT8 head, track, sector;
288   granule_location(img, granule, &head, &track, &sector);
289   if (length > 0)
290      err = proc(img, head, track, sector, 0, length, f);
291   return err;
292}
293
294
295static imgtoolerr_t transfer_from_granule(imgtool_image *img, UINT8 granule, int length, imgtool_stream *destf)
296{
297   return transfer_granule(img, granule, length, destf, imgtool_floppy_read_sector_to_stream);
298}
299
300
301
302static imgtoolerr_t transfer_to_granule(imgtool_image *img, UINT8 granule, int length, imgtool_stream *sourcef)
303{
304   return transfer_granule(img, granule, length, sourcef, imgtool_floppy_write_sector_from_stream);
305}
306
307
308
309static floperr_t read_granule(imgtool_image *img, UINT8 granule, int offset, int length, UINT8 *buf)
310{
311   UINT8 head, track, sector;
312   granule_location(img, granule, &head, &track, &sector);
313   return floppy_read_sector(imgtool_floppy(img), head, track, sector, offset, buf, length);
314}
315
316
317
318static floperr_t write_granule(imgtool_image *img, UINT8 granule, int offset, int length, const UINT8 *buf)
319{
320   UINT8 head, track, sector;
321   granule_location(img, granule, &head, &track, &sector);
322   return floppy_write_sector(imgtool_floppy(img), head, track, sector, offset, buf, length, 0); /* TODO: pass ddam argument from imgtool */
323}
324
325
326
327static imgtoolerr_t list_granules(struct bml3_dirent *ent, imgtool_image *img, struct granule_list_t *granule_list)
328{
329   floperr_t ferr;
330   UINT8 max_granules;
331   UINT8 granule;
332   UINT8 usedmap[MAX_GRANULEMAP_SIZE]; /* Used to detect infinite loops */
333   UINT8 granule_map[MAX_GRANULEMAP_SIZE];
334   bml3_diskinfo *info = bml3_get_diskinfo(img);
335
336   ferr = get_granule_map(img, granule_map, &max_granules);
337   if (ferr)
338      return imgtool_floppy_error(ferr);
339
340   memset(usedmap, 0, max_granules);
341
342   granule = ent->first_granule;
343   granule_list->granule_count = 0;
344
345   while(!usedmap[granule] && granule < max_granules)
346   {
347      usedmap[granule] = 1;
348      granule_list->granules[granule_list->granule_count++] = granule;
349      granule = granule_map[granule];
350   }
351
352   granule_list->last_granule_sectors = granule - 0xc0;
353   if (info->variant == 0) {
354      // add final incomplete sector
355      granule_list->last_granule_sectors++;
356   }
357
358   // A value of zero (variant 1) and max (variant 0) seem to indicate a file open for writing.
359   // Strictly speaking this means the image is corrupt, although a real system will happily read
360   //   garbage from the file.
361   if (granule_list->last_granule_sectors > info->granule_sectors)
362      return IMGTOOLERR_CORRUPTIMAGE;
363
364   return IMGTOOLERR_SUCCESS;
365}
366
367
368
369static imgtoolerr_t get_file_size(struct bml3_dirent *ent, imgtool_image *img, const struct granule_list_t *granule_list, size_t *size)
370{
371   floperr_t ferr;
372   size_t last_sector_bytes = 0;
373   bml3_diskinfo *info = bml3_get_diskinfo(img);
374
375   // TODO are these special cases valid, or maybe indicate a corrupt image?
376   if (granule_list->granule_count == 0) {
377      *size = 0;
378      return IMGTOOLERR_SUCCESS;
379   }
380   else if (granule_list->last_granule_sectors == 0) {
381      *size = info->sector_size * ((granule_list->granule_count - 1) * info->granule_sectors);
382      return IMGTOOLERR_SUCCESS;
383   }
384
385   // determine size excluding final sector
386   *size = info->sector_size * ((granule_list->granule_count - 1) * info->granule_sectors + granule_list->last_granule_sectors - 1);
387
388   // determine bytes used in final sector
389   switch (info->variant) {
390   case 0:
391      // look for EOF (ASCII SUB) and trailing NULs in final sector
392      {
393         UINT8 buf[MAX_SECTOR_SIZE];
394         ferr = read_granule(img, granule_list->granules[granule_list->granule_count-1], info->sector_size * (granule_list->last_granule_sectors - 1), info->sector_size, buf);
395         if (ferr)
396            return imgtool_floppy_error(ferr);
397         for (last_sector_bytes = info->sector_size - 1; last_sector_bytes >= 0; last_sector_bytes--) {
398            if (buf[last_sector_bytes] != 0)
399               break;
400         }
401         if (buf[last_sector_bytes] != 0x1a) {
402            last_sector_bytes++;
403         }
404      }
405      break;
406   case 1:
407      last_sector_bytes = ent->lastsectorbytes;
408      break;
409   }
410
411   // TODO is it valid for last_sector_bytes == 0?
412   if (last_sector_bytes < 0 || last_sector_bytes > info->sector_size) {
413      return IMGTOOLERR_CORRUPTIMAGE;
414   }
415   *size += last_sector_bytes;
416   return IMGTOOLERR_SUCCESS;
417}
418
419
420
421static imgtoolerr_t process_bml3_file(struct bml3_dirent *ent, imgtool_image *img, imgtool_stream *destf, size_t *size)
422{
423   imgtoolerr_t err;
424   size_t remaining_size, granule_size;
425   bml3_diskinfo *info = bml3_get_diskinfo(img);
426   struct granule_list_t granule_list;
427   granule_list.granule_count = 0;
428
429   err = list_granules(ent, img, &granule_list);
430   if (err)
431      return err;
432   err = get_file_size(ent, img, &granule_list, size);
433   if (err)
434      return err;
435
436   if (destf) {
437      remaining_size = *size;
438      granule_size = info->granule_sectors * info->sector_size;
439
440      for (int c = 0; c < granule_list.granule_count; c++) {
441         if (granule_size >= remaining_size)
442            granule_size = remaining_size;
443         transfer_from_granule(img, granule_list.granules[c], granule_size, destf);
444         remaining_size -= granule_size;
445      }
446   }
447   return IMGTOOLERR_SUCCESS;
448}
449
450
451
452/* create a new directory entry with a specified name */
453static imgtoolerr_t prepare_dirent(UINT8 variant, struct bml3_dirent *ent, const char *fname)
454{
455   const char *fname_end;
456   const char *fname_ext;
457   int fname_ext_len;
458
459   memset(ent, '\0', sizeof(*ent));
460   memset(ent->fname, ' ', sizeof(ent->fname));
461   memset(ent->fext, ' ', sizeof(ent->fext));
462
463   fname_end = strchr(fname, '.');
464   if (fname_end)
465      fname_ext = fname_end + 1;
466   else
467      fname_end = fname_ext = fname + strlen(fname);
468
469   fname_ext_len = strlen(fname_ext);
470
471   switch (variant) {
472   case 0:
473      /* 8-character max filename */
474      if (((fname_end - fname) > 8) || (fname_ext_len > 0))
475         return IMGTOOLERR_BADFILENAME;
476      break;
477   case 1:
478      /*8.3 filename */
479      if (((fname_end - fname) > 8) || (fname_ext_len > 3))
480         return IMGTOOLERR_BADFILENAME;
481      break;
482   default:
483      return IMGTOOLERR_CORRUPTIMAGE;
484   }
485
486   memcpy(ent->fname, fname, fname_end - fname);
487   memcpy(ent->fext, fname_ext, fname_ext_len);
488
489   /* By default, set as a type 2 binary file */
490   ent->ftype = 2;
491   ent->asciiflag = 0;
492   return IMGTOOLERR_SUCCESS;
493}
494
495
496
497static imgtoolerr_t bml3_diskimage_open(imgtool_image *image, imgtool_stream *stream)
498{
499   // imgtoolerr_t err;
500   floperr_t ferr;
501   bml3_diskinfo *info = bml3_get_diskinfo(image);
502   floppy_image_legacy *floppy = imgtool_floppy(image);
503   const struct FloppyCallbacks *callbacks = floppy_callbacks(floppy);
504
505   // probe disk geometry to guess format
506   int heads_per_disk = callbacks->get_heads_per_disk(floppy);
507   UINT32 sector_length;
508   ferr = callbacks->get_sector_length(floppy, 0, 20, 1, &sector_length);
509   if (ferr)
510      return imgtool_floppy_error(ferr);
511   int sectors_per_track = callbacks->get_sectors_per_track(floppy, 0, 20);
512
513   if (heads_per_disk == 2 && sector_length == 128 && sectors_per_track == 16) {
514      // single-sided, single-density
515      info->sector_size = 128;
516      info->heads = 1;
517      info->fat_start_sector = 1;
518      info->fat_start_offset = 5;
519      info->fat_sectors = 2;
520      info->dirent_start_sector = 7;
521      info->granule_sectors = 4;
522      info->first_granule_cylinder = 0;
523      info->variant = 0;
524   }
525   else if (heads_per_disk == 2 && sector_length == 256 && sectors_per_track == 16) {
526      // double-sided, double-density
527      info->sector_size = 256;
528      info->heads = 2;
529      info->fat_start_sector = 2;
530      info->fat_start_offset = 1;
531      info->fat_sectors = 1;
532      info->dirent_start_sector = 5;
533      info->granule_sectors = 8;
534      info->first_granule_cylinder = 1;
535      info->variant = 1;
536   }
537   else {
538      // invalid or unsupported format
539      return IMGTOOLERR_CORRUPTIMAGE;
540   }
541
542   return IMGTOOLERR_SUCCESS;
543}
544
545
546
547static imgtoolerr_t bml3_diskimage_nextenum(imgtool_directory *enumeration, imgtool_dirent *ent)
548{
549   floperr_t ferr;
550   imgtoolerr_t err;
551   size_t filesize;
552   struct bml3_direnum *rsenum;
553   struct bml3_dirent rsent;
554   char fname[13];
555   imgtool_image *image;
556
557   image = imgtool_directory_image(enumeration);
558   rsenum = (struct bml3_direnum *) imgtool_directory_extrabytes(enumeration);
559
560   /* Did we hit the end of file before? */
561   if (rsenum->eof)
562      goto eof;
563
564   do
565   {
566      if (rsenum->index >= max_dirents(image))
567         goto eof;
568
569      ferr = get_bml3_dirent(image, rsenum->index++, &rsent);
570      if (ferr)
571         return imgtool_floppy_error(ferr);
572   }
573   while(rsent.fname[0] == '\0');
574
575   /* Now are we at the eof point? */
576   if (rsent.fname[0] == -1)
577   {
578      rsenum->eof = 1;
579eof:
580      ent->eof = 1;
581   }
582   else
583   {
584      /* Not the end of file */
585      err = process_bml3_file(&rsent, image, NULL, &filesize);
586      if (err)
587         return err;
588
589      if (filesize == ((size_t) -1))
590      {
591         /* corrupt! */
592         ent->filesize = 0;
593         ent->corrupt = 1;
594      }
595      else
596      {
597         ent->filesize = filesize;
598         ent->corrupt = 0;
599      }
600      ent->eof = 0;
601
602      get_dirent_fname(fname, &rsent);
603
604      snprintf(ent->filename, ARRAY_LENGTH(ent->filename), "%s", fname);
605      snprintf(ent->attr, ARRAY_LENGTH(ent->attr), "%d %c", (int) rsent.ftype, (char) (rsent.asciiflag + 'B'));
606   }
607   return IMGTOOLERR_SUCCESS;
608}
609
610
611
612static imgtoolerr_t bml3_diskimage_freespace(imgtool_partition *partition, UINT64 *size)
613{
614   floperr_t ferr;
615   UINT8 i;
616   size_t s = 0;
617   UINT8 granule_count;
618   UINT8 granule_map[MAX_GRANULEMAP_SIZE];
619   imgtool_image *image = imgtool_partition_image(partition);
620   bml3_diskinfo *info = bml3_get_diskinfo(image);
621
622   ferr = get_granule_map(image, granule_map, &granule_count);
623   if (ferr)
624      return imgtool_floppy_error(ferr);
625
626   for (i = 0; i < granule_count; i++)
627   {
628      if (granule_map[i] == 0xff)
629         s += (info->granule_sectors * info->sector_size);
630   }
631   *size = s;
632   return (imgtoolerr_t)FLOPPY_ERROR_SUCCESS;
633}
634
635
636
637static imgtoolerr_t delete_entry(imgtool_image *img, struct bml3_dirent *ent, int pos)
638{
639   floperr_t ferr;
640   unsigned char g, i;
641   UINT8 granule_count;
642   UINT8 granule_map[MAX_GRANULEMAP_SIZE];
643
644   /* Write a NUL in the filename, marking it deleted */
645   ent->fname[0] = 0;
646   ferr = put_bml3_dirent(img, pos, ent);
647   if (ferr)
648      return imgtool_floppy_error(ferr);
649
650   ferr = get_granule_map(img, granule_map, &granule_count);
651   if (ferr)
652      return imgtool_floppy_error(ferr);
653
654   /* Now free up the granules */
655   g = ent->first_granule;
656   while (g < granule_count)
657   {
658      i = granule_map[g];
659      granule_map[g] = 0xff;
660      g = i;
661   }
662
663   ferr = put_granule_map(img, granule_map, granule_count);
664   if (ferr)
665      return imgtool_floppy_error(ferr);
666
667   return IMGTOOLERR_SUCCESS;
668}
669
670
671
672static imgtoolerr_t bml3_diskimage_readfile(imgtool_partition *partition, const char *fname, const char *fork, imgtool_stream *destf)
673{
674   imgtoolerr_t err;
675   struct bml3_dirent ent;
676   size_t size;
677   imgtool_image *img = imgtool_partition_image(partition);
678
679   err = lookup_bml3_file(img, fname, &ent, NULL);
680   if (err)
681      return err;
682
683   err = process_bml3_file(&ent, img, destf, &size);
684   if (err)
685      return err;
686
687   if (size == (size_t) -1)
688      return IMGTOOLERR_CORRUPTIMAGE;
689
690   return (imgtoolerr_t)0;
691}
692
693
694
695static imgtoolerr_t bml3_diskimage_writefile(imgtool_partition *partition, const char *fname, const char *fork, imgtool_stream *sourcef, option_resolution *writeoptions)
696{
697   floperr_t ferr;
698   imgtoolerr_t err;
699   imgtool_image *img = imgtool_partition_image(partition);
700   bml3_diskinfo *info = bml3_get_diskinfo(img);
701   struct bml3_dirent ent, ent2;
702   size_t i;
703   UINT64 sz, read_sz;
704   UINT64 freespace = 0;
705   unsigned char g;
706   unsigned char *gptr;
707   UINT8 granule_count;
708   UINT8 granule_map[MAX_GRANULEMAP_SIZE];
709   UINT8 eof_buf[MAX_SECTOR_SIZE];
710
711   // one-time setup of eof_buf
712   memset(eof_buf, 0, sizeof(eof_buf));
713   eof_buf[0] = 0x1A;
714
715   /* can we write to this image? */
716   if (floppy_is_read_only(imgtool_floppy(img)))
717      return IMGTOOLERR_READONLY;
718
719   err = bml3_diskimage_freespace(partition, &freespace);
720   if (err)
721      return err;
722
723   /* is there enough space? */
724   sz = read_sz = stream_size(sourcef);
725   if (info->variant == 0) {
726      // also need to write EOF
727      sz++;
728   }
729   if (sz > freespace)
730      return IMGTOOLERR_NOSPACE;
731
732   /* setup our directory entry */
733   err = prepare_dirent(info->variant, &ent, fname);
734   if (err)
735      return err;
736
737   ent.ftype = option_resolution_lookup_int(writeoptions, BML3_OPTIONS_FTYPE);
738   ent.asciiflag = ((UINT8) option_resolution_lookup_int(writeoptions, BML3_OPTIONS_ASCII)) - 1;
739   gptr = &ent.first_granule;
740
741   ferr = get_granule_map(img, granule_map, &granule_count);
742   if (ferr)
743      return imgtool_floppy_error(ferr);
744
745   g = 0x00;
746
747   do
748   {
749      while (granule_map[g] != 0xff)
750      {
751         g++;
752         if ((g >= granule_count) || (g == 0))
753            return IMGTOOLERR_UNEXPECTED;   /* We should have already verified that there is enough space */
754      }
755      *gptr = g;
756      gptr = &granule_map[g];
757
758
759      i = MIN(read_sz, info->granule_sectors * info->sector_size);
760      if (i > 0) {
761         err = transfer_to_granule(img, g, i, sourcef);
762         if (err)
763            return err;
764         read_sz -= i;
765         sz -= i;
766      }
767      if (i < info->granule_sectors * info->sector_size && sz > 0) {
768         // write EOF and trailing NULs in the final sector
769         ferr = write_granule(img, g, i, (info->granule_sectors * info->sector_size - i - 1) % info->sector_size + 1, eof_buf);
770         if (ferr)
771            return imgtool_floppy_error(ferr);
772         sz--;
773         i++;
774      }
775
776      /* Go to next granule */
777      g++;
778   }
779   while(sz > 0);
780
781   /* Now that we are done with the file, we need to specify the final entry
782    * in the file allocation table
783    */
784   *gptr = 0xc0 + ((i + info->sector_size-1) / info->sector_size) - (info->variant == 0 ? 1 : 0);
785   ent.lastsectorbytes = (i - 1) % info->sector_size + 1;
786
787   /* delete file if it already exists */
788   err = bml3_diskimage_deletefile(partition, fname);
789   if (err && err != IMGTOOLERR_FILENOTFOUND)
790      return err;
791
792   /* Now we need to find an empty directory entry */
793   i = -1;
794   do
795   {
796      ferr = get_bml3_dirent(img, ++i, &ent2);
797      if (ferr)
798         return imgtool_floppy_error(ferr);
799   }
800   while(ent2.fname[0] != '\0' && ent2.fname[0] != -1);
801
802   ferr = put_bml3_dirent(img, i, &ent);
803   if (ferr)
804      return imgtool_floppy_error(ferr);
805
806   /* write the granule map back out */
807   ferr = put_granule_map(img, granule_map, granule_count);
808   if (ferr)
809      return imgtool_floppy_error(ferr);
810
811   return IMGTOOLERR_SUCCESS;
812}
813
814
815
816static imgtoolerr_t bml3_diskimage_deletefile(imgtool_partition *partition, const char *fname)
817{
818   imgtoolerr_t err;
819   imgtool_image *image = imgtool_partition_image(partition);
820   int pos;
821   struct bml3_dirent ent;
822
823   err = lookup_bml3_file(image, fname, &ent, &pos);
824   if (err)
825      return err;
826
827   return delete_entry(image, &ent, pos);
828}
829
830
831
832static imgtoolerr_t bml3_diskimage_suggesttransfer(imgtool_partition *partition, const char *fname, imgtool_transfer_suggestion *suggestions, size_t suggestions_length)
833{
834   imgtoolerr_t err;
835   imgtool_image *image = imgtool_partition_image(partition);
836   struct bml3_dirent ent;
837   int pos;
838
839   if (fname)
840   {
841      err = lookup_bml3_file(image, fname, &ent, &pos);
842      if (err)
843         return err;
844
845      if (ent.asciiflag == 0xFF)
846      {
847         /* ASCII file */
848         suggestions[0].viability = SUGGESTION_RECOMMENDED;
849         suggestions[0].filter = filter_eoln_getinfo;
850         suggestions[1].viability = SUGGESTION_POSSIBLE;
851         suggestions[1].filter = NULL;
852      }
853      else if (ent.ftype == 0)
854      {
855         /* tokenized BASIC file */
856         suggestions[0].viability = SUGGESTION_RECOMMENDED;
857         suggestions[0].filter = NULL;
858         suggestions[1].viability = SUGGESTION_POSSIBLE;
859         suggestions[1].filter = filter_bml3bas_getinfo;
860      }
861   }
862   else
863   {
864      suggestions[0].viability = SUGGESTION_RECOMMENDED;
865      suggestions[0].filter = NULL;
866      suggestions[1].viability = SUGGESTION_POSSIBLE;
867      suggestions[1].filter = filter_eoln_getinfo;
868      suggestions[2].viability = SUGGESTION_POSSIBLE;
869      suggestions[2].filter = filter_bml3bas_getinfo;
870   }
871
872   return IMGTOOLERR_SUCCESS;
873}
874
875
876
877/*********************************************************************
878    Imgtool module declaration
879*********************************************************************/
880
881static OPTION_GUIDE_START( bml3_writefile_optionguide )
882   OPTION_ENUM_START(  BML3_OPTIONS_FTYPE, "ftype", "File type" )
883      OPTION_ENUM(    0,      "basic",        "Basic" )
884      OPTION_ENUM(    1,      "data",         "Data" )
885      OPTION_ENUM(    2,      "binary",       "Binary" )
886      OPTION_ENUM(    3,      "assembler",    "Assembler Source" )
887   OPTION_ENUM_END
888   OPTION_ENUM_START(  BML3_OPTIONS_ASCII, "ascii", "Ascii flag" )
889      OPTION_ENUM(    0,      "ascii",        "Ascii" )
890      OPTION_ENUM(    1,      "binary",       "Binary" )
891   OPTION_ENUM_END
892OPTION_GUIDE_END
893
894
895
896void bml3_get_info(const imgtool_class *imgclass, UINT32 state, union imgtoolinfo *info)
897{
898   switch(state)
899   {
900      /* --- the following bits of info are returned as 64-bit signed integers --- */
901      case IMGTOOLINFO_INT_PREFER_UCASE:                  info->i = 1; break;
902      case IMGTOOLINFO_INT_IMAGE_EXTRA_BYTES:             info->i = sizeof(bml3_diskinfo); break;
903      case IMGTOOLINFO_INT_DIRECTORY_EXTRA_BYTES:             info->i = sizeof(struct bml3_direnum); break;
904
905      /* --- the following bits of info are returned as NULL-terminated strings --- */
906      case IMGTOOLINFO_STR_NAME:                          strcpy(info->s = imgtool_temp_str(), "bml3"); break;
907      case IMGTOOLINFO_STR_DESCRIPTION:                   strcpy(info->s = imgtool_temp_str(), "Basic Master Level 3 format"); break;
908      case IMGTOOLINFO_STR_FILE:                          strcpy(info->s = imgtool_temp_str(), __FILE__); break;
909      case IMGTOOLINFO_STR_EOLN:                          strcpy(info->s = imgtool_temp_str(), "\r"); break;
910      case IMGTOOLINFO_STR_WRITEFILE_OPTSPEC:             strcpy(info->s = imgtool_temp_str(), "T0-[2]-3;M0-[1]"); break;
911
912      /* --- the following bits of info are returned as pointers to data or functions --- */
913      case IMGTOOLINFO_PTR_MAKE_CLASS:                    info->make_class = imgtool_floppy_make_class; break;
914      case IMGTOOLINFO_PTR_FLOPPY_OPEN:                   info->open = bml3_diskimage_open; break;
915      case IMGTOOLINFO_PTR_NEXT_ENUM:                     info->next_enum = bml3_diskimage_nextenum; break;
916      case IMGTOOLINFO_PTR_FREE_SPACE:                    info->free_space = bml3_diskimage_freespace; break;
917      case IMGTOOLINFO_PTR_READ_FILE:                     info->read_file = bml3_diskimage_readfile; break;
918      case IMGTOOLINFO_PTR_WRITE_FILE:                    info->write_file = bml3_diskimage_writefile; break;
919      case IMGTOOLINFO_PTR_DELETE_FILE:                   info->delete_file = bml3_diskimage_deletefile; break;
920      case IMGTOOLINFO_PTR_SUGGEST_TRANSFER:              info->suggest_transfer = bml3_diskimage_suggesttransfer; break;
921      case IMGTOOLINFO_PTR_WRITEFILE_OPTGUIDE:            info->writefile_optguide = bml3_writefile_optionguide; break;
922      case IMGTOOLINFO_PTR_FLOPPY_FORMAT:                 info->p = (void *) floppyoptions_default; break;
923   }
924}
Property changes on: trunk/src/mess/tools/imgtool/modules/bml3.c
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/mess/tools/imgtool/filter.h
r24064r24065
5858extern void filter_thombas7_getinfo(UINT32 state, union filterinfo *info);
5959extern void filter_thombas128_getinfo(UINT32 state, union filterinfo *info);
6060extern void filter_thomcrypt_getinfo(UINT32 state, union filterinfo *info);
61extern void filter_bml3bas_getinfo(UINT32 state, union filterinfo *info);
6162
6263
6364#endif /* FILTER_H */
trunk/src/mess/machine/bml3mp1805.c
r0r24065
1/*********************************************************************
2
3    bml3mp1805.c
4
5    Hitachi MP-1805 floppy disk controller card for the MB-6890
6    Floppy drive is attached
7
8*********************************************************************/
9
10#include "emu.h"
11#include "bml3mp1805.h"
12
13
14/***************************************************************************
15    PARAMETERS
16***************************************************************************/
17
18//**************************************************************************
19//  GLOBAL VARIABLES
20//**************************************************************************
21
22const device_type BML3BUS_MP1805 = &device_creator<bml3bus_mp1805_device>;
23
24static const floppy_interface bml3_mp1805_floppy_interface =
25{
26   DEVCB_NULL,
27   DEVCB_NULL,
28   DEVCB_NULL,
29   DEVCB_NULL,
30   DEVCB_NULL,
31   FLOPPY_STANDARD_3_SSDD,
32   LEGACY_FLOPPY_OPTIONS_NAME(default),
33   NULL
34};
35
36static WRITE_LINE_DEVICE_HANDLER( bml3_mc6843_intrq_w )
37{
38   bml3bus_mp1805_device *fdc = dynamic_cast<bml3bus_mp1805_device *>(device->owner());
39   if (state) {
40      fdc->m_bml3bus->set_nmi_line(PULSE_LINE);
41   }
42}
43
44const mc6843_interface bml3_6843_if =
45{
46   bml3_mc6843_intrq_w
47};
48
49
50#define MP1805_ROM_REGION  "mp1805_rom"
51
52ROM_START( mp1805 )
53   ROM_REGION(0x10000, MP1805_ROM_REGION, 0)
54   // MP-1805 disk controller ROM, which replaces part of the system ROM
55   ROM_LOAD( "mp1805.rom", 0xf800, 0x0800, BAD_DUMP CRC(b532d8d9) SHA1(6f1160356d5bf64b5926b1fdb60db414edf65f22))
56ROM_END
57
58MACHINE_CONFIG_FRAGMENT( mp1805 )
59   MCFG_MC6843_ADD( "mc6843", bml3_6843_if )
60   MCFG_LEGACY_FLOPPY_4_DRIVES_ADD(bml3_mp1805_floppy_interface)
61MACHINE_CONFIG_END
62
63/***************************************************************************
64    FUNCTION PROTOTYPES
65***************************************************************************/
66
67//-------------------------------------------------
68//  machine_config_additions - device-specific
69//  machine configurations
70//-------------------------------------------------
71
72machine_config_constructor bml3bus_mp1805_device::device_mconfig_additions() const
73{
74   return MACHINE_CONFIG_NAME( mp1805 );
75}
76
77//-------------------------------------------------
78//  rom_region - device-specific ROM region
79//-------------------------------------------------
80
81const rom_entry *bml3bus_mp1805_device::device_rom_region() const
82{
83   return ROM_NAME( mp1805 );
84}
85
86READ8_MEMBER( bml3bus_mp1805_device::bml3_mp1805_r)
87{
88   // TODO: read supported or not?
89   //   return mc6843_drq_r(m_mc6843) ? 0x00 : 0x80;
90   return -1;
91}
92
93WRITE8_MEMBER( bml3bus_mp1805_device::bml3_mp1805_w)
94{
95   // b7 b6 b5 b4 b3 b2 b1 b0
96   // MT ?  ?  ?  D3 D2 D1 D0
97   // MT: 0=motor off, 1=motor on
98   // Dn: 1=select drive <n>
99   int drive_select = data & 0x0f;
100   int drive;
101   // TODO: MESS UI for flipping disk? Note that D88 images are double-sided, but the physical drive is single-sided
102   int side = 0;
103   int motor = BIT(data, 7);
104   const char *floppy_name = NULL;
105   switch (drive_select) {
106   case 1:
107      drive = 0;
108      break;
109   case 2:
110      drive = 1;
111      break;
112   case 4:
113      drive = 2;
114      break;
115   case 8:
116      drive = 3;
117      break;
118   default:
119      // TODO: what's the correct behaviour if more than one drive select bit is set? Or no bit set?
120      drive = 0;
121      break;
122   }
123   switch (drive) {
124   case 0:
125      floppy_name = FLOPPY_0;
126      break;
127   case 1:
128      floppy_name = FLOPPY_1;
129      break;
130   case 2:
131      floppy_name = FLOPPY_2;
132      break;
133   case 3:
134      floppy_name = FLOPPY_3;
135      break;
136   }
137   device_t *floppy = subdevice(floppy_name);
138   mc6843_set_drive(m_mc6843,drive);
139   floppy_mon_w(floppy, motor);
140   floppy_drive_set_ready_state(floppy, ASSERT_LINE, 0);
141   mc6843_set_side(m_mc6843,side);
142}
143
144
145//**************************************************************************
146//  LIVE DEVICE
147//**************************************************************************
148
149bml3bus_mp1805_device::bml3bus_mp1805_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
150   device_t(mconfig, BML3BUS_MP1805, "Hitachi MP-1805 Floppy Controller Card", tag, owner, clock, "bml3mp1805", __FILE__),
151   device_bml3bus_card_interface(mconfig, *this),
152   m_mc6843(*this, "mc6843")
153{
154}
155
156
157//-------------------------------------------------
158//  device_start - device-specific startup
159//-------------------------------------------------
160
161void bml3bus_mp1805_device::device_start()
162{
163   // set_bml3bus_device makes m_slot valid
164   set_bml3bus_device();
165
166   m_rom = memregion(MP1805_ROM_REGION)->base();
167
168   // install into memory
169   address_space &space_prg = machine().firstcpu->space(AS_PROGRAM);
170   space_prg.install_legacy_readwrite_handler(m_mc6843, 0xff18, 0xff1f, FUNC(mc6843_r), FUNC(mc6843_w));
171   space_prg.install_readwrite_handler(0xff20, 0xff20, read8_delegate( FUNC(bml3bus_mp1805_device::bml3_mp1805_r), this), write8_delegate(FUNC(bml3bus_mp1805_device::bml3_mp1805_w), this) );
172   // overwriting the main ROM (rather than using e.g. install_rom) should mean that bank switches for RAM expansion still work...
173   UINT8 *mainrom = device().machine().root_device().memregion("maincpu")->base();
174   memcpy(mainrom + 0xf800, m_rom + 0xf800, 0x800);
175}
176
177void bml3bus_mp1805_device::device_reset()
178{
179}
Property changes on: trunk/src/mess/machine/bml3mp1805.c
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/mess/machine/bml3mp1805.h
r0r24065
1/*********************************************************************
2
3    bml3mp1805.h
4
5    Hitachi MP-1805 floppy disk controller card for the MB-6890
6    Floppy drive is attached
7
8*********************************************************************/
9
10#ifndef __BML3BUS_MP1805__
11#define __BML3BUS_MP1805__
12
13#include "emu.h"
14#include "machine/bml3bus.h"
15#include "imagedev/flopdrv.h"
16#include "machine/mc6843.h"
17
18//**************************************************************************
19//  TYPE DEFINITIONS
20//**************************************************************************
21
22class bml3bus_mp1805_device:
23   public device_t,
24   public device_bml3bus_card_interface
25{
26public:
27   // construction/destruction
28   bml3bus_mp1805_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
29
30   // optional information overrides
31   virtual machine_config_constructor device_mconfig_additions() const;
32   virtual const rom_entry *device_rom_region() const;
33
34   DECLARE_READ8_MEMBER(bml3_mp1805_r);
35   DECLARE_WRITE8_MEMBER(bml3_mp1805_w);
36
37protected:
38   virtual void device_start();
39   virtual void device_reset();
40
41   required_device<mc6843_device> m_mc6843;
42
43private:
44   UINT8 *m_rom;
45};
46
47// device type definition
48extern const device_type BML3BUS_MP1805;
49
50#endif /* __BML3BUS_MP1805__ */
Property changes on: trunk/src/mess/machine/bml3mp1805.h
Added: svn:eol-style
   + native
Added: svn:mime-type
   + text/plain
trunk/src/mess/machine/bml3kanji.c
r0r24065
1/*********************************************************************
2
3    bml3kanji.c
4
5    Hitachi MP-9740 (?) kanji character ROM for the MB-689x
6
7*********************************************************************/
8
9#include "emu.h"
10#include "bml3kanji.h"
11
12
13/***************************************************************************
14    PARAMETERS
15***************************************************************************/
16
17//**************************************************************************
18//  GLOBAL VARIABLES
19//**************************************************************************
20
21const device_type BML3BUS_KANJI = &device_creator<bml3bus_kanji_device>;
22
23#define KANJI_ROM_REGION  "kanji_rom"
24
25ROM_START( kanji )
26   ROM_REGION( 0x20000, KANJI_ROM_REGION, ROMREGION_ERASEFF )
27   ROM_LOAD("kanji.rom", 0x00000, 0x20000, BAD_DUMP CRC(de99a726) SHA1(65fead5d0d779b242f6e0ac25fcc9899dc343101))
28ROM_END
29
30MACHINE_CONFIG_FRAGMENT( kanji )
31   // nothing to add
32MACHINE_CONFIG_END
33
34/***************************************************************************
35    FUNCTION PROTOTYPES
36***************************************************************************/
37
38//-------------------------------------------------
39//  machine_config_additions - device-specific
40//  machine configurations
41//-------------------------------------------------
42
43machine_config_constructor bml3bus_kanji_device::device_mconfig_additions() const
44{
45   return MACHINE_CONFIG_NAME( kanji );
46}
47
48//-------------------------------------------------
49//  rom_region - device-specific ROM region
50//-------------------------------------------------
51
52const rom_entry *bml3bus_kanji_device::device_rom_region() const
53{
54   return ROM_NAME( kanji );
55}
56
57READ8_MEMBER( bml3bus_kanji_device::bml3_kanji_r )
58{
59   return m_rom[((UINT32)m_kanji_addr << 1) + offset];
60}
61
62WRITE8_MEMBER( bml3bus_kanji_device::bml3_kanji_w )
63{
64   m_kanji_addr &= (0xff << (offset*8));
65   m_kanji_addr |= (data << ((offset^1)*8));
66}
67
68
69//**************************************************************************
70//  LIVE DEVICE
71//**************************************************************************
72
73bml3bus_kanji_device::bml3bus_kanji_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
74   device_t(mconfig, BML3BUS_KANJI, "Hitachi MP-9740 Kanji Character ROM Card", tag, owner, clock, "bml3kanji", __FILE__),
75   device_bml3bus_card_interface(mconfig, *this)
76{
77}
78
79
80//-------------------------------------------------
81//  device_start - device-specific startup
82//-------------------------------------------------
83
84void bml3bus_kanji_device::device_start()
85{
86   // set_bml3bus_device makes m_slot valid
87   set_bml3bus_device();
88
89   m_rom = memregion(KANJI_ROM_REGION)->base();
90
91   // install into memory
92   address_space &space_prg = machine().firstcpu->space(AS_PROGRAM);
93   space_prg.install_readwrite_handler(0xff75, 0xff76, read8_delegate( FUNC(bml3bus_kanji_device::bml3_kanji_r), this), write8_delegate(FUNC(bml3bus_kanji_device::bml3_kanji_w), this) );
94}
95
96void bml3bus_kanji_device::device_reset()
97{
98   m_kanji_addr = 0;
99}
Property changes on: trunk/src/mess/machine/bml3kanji.c
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/mess/machine/bml3kanji.h
r0r24065
1/*********************************************************************
2
3    bml3kanji.h
4
5    Hitachi MP-9740 (?) kanji character ROM for the MB-689x
6
7*********************************************************************/
8
9#ifndef __BML3BUS_KANJI__
10#define __BML3BUS_KANJI__
11
12#include "emu.h"
13#include "machine/bml3bus.h"
14
15//**************************************************************************
16//  TYPE DEFINITIONS
17//**************************************************************************
18
19class bml3bus_kanji_device:
20   public device_t,
21   public device_bml3bus_card_interface
22{
23public:
24   // construction/destruction
25   bml3bus_kanji_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
26
27   // optional information overrides
28   virtual machine_config_constructor device_mconfig_additions() const;
29   virtual const rom_entry *device_rom_region() const;
30
31   DECLARE_READ8_MEMBER(bml3_kanji_r);
32   DECLARE_WRITE8_MEMBER(bml3_kanji_w);
33
34protected:
35   virtual void device_start();
36   virtual void device_reset();
37
38   UINT16 m_kanji_addr;
39
40private:
41   UINT8 *m_rom;
42};
43
44// device type definition
45extern const device_type BML3BUS_KANJI;
46
47#endif /* __BML3BUS_KANJI__ */
Property changes on: trunk/src/mess/machine/bml3kanji.h
Added: svn:eol-style
   + native
Added: svn:mime-type
   + text/plain
trunk/src/mess/machine/bml3mp1802.c
r0r24065
1/*********************************************************************
2
3    bml3mp1802.c
4
5    Hitachi MP-1802 floppy disk controller card for the MB-6890
6    Hitachi MP-3550 floppy drive is attached
7
8*********************************************************************/
9
10#include "emu.h"
11#include "bml3mp1802.h"
12
13
14/***************************************************************************
15    PARAMETERS
16***************************************************************************/
17
18//**************************************************************************
19//  GLOBAL VARIABLES
20//**************************************************************************
21
22const device_type BML3BUS_MP1802 = &device_creator<bml3bus_mp1802_device>;
23
24static const floppy_interface bml3_mp1802_floppy_interface =
25{
26   DEVCB_NULL,
27   DEVCB_NULL,
28   DEVCB_NULL,
29   DEVCB_NULL,
30   DEVCB_NULL,
31   FLOPPY_STANDARD_5_25_DSDD,
32   LEGACY_FLOPPY_OPTIONS_NAME(default),
33   NULL
34};
35
36static WRITE_LINE_DEVICE_HANDLER( bml3_wd17xx_intrq_w )
37{
38   bml3bus_mp1802_device *fdc = dynamic_cast<bml3bus_mp1802_device *>(device->owner());
39   if (state) {
40      fdc->m_bml3bus->set_nmi_line(PULSE_LINE);
41   }
42}
43
44const wd17xx_interface bml3_wd17xx_interface =
45{
46   DEVCB_NULL,
47   DEVCB_LINE(bml3_wd17xx_intrq_w),
48   DEVCB_NULL,
49   {FLOPPY_0, FLOPPY_1}
50};
51
52
53#define MP1802_ROM_REGION  "mp1802_rom"
54
55ROM_START( mp1802 )
56   ROM_REGION(0x10000, MP1802_ROM_REGION, 0)
57   // MP-1802 disk controller ROM, which replaces part of the system ROM
58   ROM_LOAD( "mp1802.rom", 0xf800, 0x800, BAD_DUMP CRC(8d0dc101) SHA1(92f7d1cebecafa7472e45c4999520de5c01c6dbc))
59ROM_END
60
61MACHINE_CONFIG_FRAGMENT( mp1802 )
62   MCFG_MB8866_ADD("wd17xx", bml3_wd17xx_interface )
63   MCFG_LEGACY_FLOPPY_2_DRIVES_ADD(bml3_mp1802_floppy_interface)
64MACHINE_CONFIG_END
65
66/***************************************************************************
67    FUNCTION PROTOTYPES
68***************************************************************************/
69
70//-------------------------------------------------
71//  machine_config_additions - device-specific
72//  machine configurations
73//-------------------------------------------------
74
75machine_config_constructor bml3bus_mp1802_device::device_mconfig_additions() const
76{
77   return MACHINE_CONFIG_NAME( mp1802 );
78}
79
80//-------------------------------------------------
81//  rom_region - device-specific ROM region
82//-------------------------------------------------
83
84const rom_entry *bml3bus_mp1802_device::device_rom_region() const
85{
86   return ROM_NAME( mp1802 );
87}
88
89READ8_MEMBER( bml3bus_mp1802_device::bml3_mp1802_r)
90{
91   return wd17xx_drq_r(m_wd17xx) ? 0x00 : 0x80;
92}
93
94WRITE8_MEMBER( bml3bus_mp1802_device::bml3_mp1802_w)
95{
96   int drive = data & 0x03;
97   int side = BIT(data, 4);
98   int motor = BIT(data, 3);
99   const char *floppy_name = NULL;
100   switch (drive) {
101   case 0:
102      floppy_name = FLOPPY_0;
103      break;
104   case 1:
105      floppy_name = FLOPPY_1;
106      break;
107   case 2:
108      floppy_name = FLOPPY_2;
109      break;
110   case 3:
111      floppy_name = FLOPPY_3;
112      break;
113   }
114   device_t *floppy = subdevice(floppy_name);
115   wd17xx_set_drive(m_wd17xx,drive);
116   floppy_mon_w(floppy, !motor);
117   floppy_drive_set_ready_state(floppy, ASSERT_LINE, 0);
118   wd17xx_set_side(m_wd17xx,side);
119}
120
121
122//**************************************************************************
123//  LIVE DEVICE
124//**************************************************************************
125
126bml3bus_mp1802_device::bml3bus_mp1802_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
127   device_t(mconfig, BML3BUS_MP1802, "Hitachi MP-1802 Floppy Controller Card", tag, owner, clock, "bml3mp1802", __FILE__),
128   device_bml3bus_card_interface(mconfig, *this),
129   m_wd17xx(*this, "wd17xx")
130{
131}
132
133
134//-------------------------------------------------
135//  device_start - device-specific startup
136//-------------------------------------------------
137
138void bml3bus_mp1802_device::device_start()
139{
140   // set_bml3bus_device makes m_slot valid
141   set_bml3bus_device();
142
143   m_rom = memregion(MP1802_ROM_REGION)->base();
144
145   // install into memory
146   address_space &space_prg = machine().firstcpu->space(AS_PROGRAM);
147   space_prg.install_legacy_readwrite_handler(m_wd17xx, 0xff00, 0xff03, FUNC(wd17xx_r), FUNC(wd17xx_w));
148   space_prg.install_readwrite_handler(0xff04, 0xff04, read8_delegate( FUNC(bml3bus_mp1802_device::bml3_mp1802_r), this), write8_delegate(FUNC(bml3bus_mp1802_device::bml3_mp1802_w), this) );
149   // overwriting the main ROM (rather than using e.g. install_rom) should mean that bank switches for RAM expansion still work...
150   UINT8 *mainrom = device().machine().root_device().memregion("maincpu")->base();
151   memcpy(mainrom + 0xf800, m_rom + 0xf800, 0x800);
152}
153
154void bml3bus_mp1802_device::device_reset()
155{
156}
Property changes on: trunk/src/mess/machine/bml3mp1802.c
Added: svn:eol-style
   + native
Added: svn:mime-type
   + text/plain
trunk/src/mess/machine/bml3bus.c
r0r24065
1/***************************************************************************
2
3  bml3bus.c - Hitachi MB-6890 slot bus and card emulation
4
5  Adapted from a2bus by Jonathan Edwards
6
7  Pinout (/ indicates an inverted signal, ie, one that would have a bar over it
8          on a schematic diagram)
9
10       out <-> CPU CPU <-> out
11       ----------  -----------
12       +5V <--  1   2  <-> GND
13        D0 <->  3   4  <-> D1
14        D2 <->  5   6  <-> D3
15        D4 <->  7   8  <-> D5
16        D6 <->  9  10  <-> D7
17        A0 <-> 11  12  <-> A1
18        A2 <-> 13  14  <-> A3
19        A4 <-> 15  16  <-> A5
20        A6 <-> 17  18  <-> A7
21        A8 <-> 19  20  <-> A9
22       A10 <-> 21  22  <-> A11
23       A12 <-> 23  24  <-> A13
24       A14 <-> 25  26  <-> A15
25        BA <-- 27  28  --> BS
26  /ROM-KIL --> 29  30  --> EXROM-KIL
27    R/W IN --> 31  32  --> /EX-I/O
28   R/W OUT <-- 33  34  --> VMA OUT
29         E <-- 35  36  --> Q
30      /RES <-- 37  38  <-- /NMI
31      /IRQ --> 39  40  <-- /FIRQ
32     /HALT --> 41  42  <-- /VMA CTRL
33      /DMA --> 43  44  --> /BANK-SW
34  HALT ACK <-- 45  46  <-- SOUND IN
35     16MCK <-- 47  48  <-> GND
36      2MCK <-- 49  50  <-> GND
37       -5V <-- 51  52  --> /EX-I/O2
38      -12V <-- 53  54  --> +12V
39       GND <-> 55  56  --> +5V
40
41***************************************************************************/
42
43#include "emu.h"
44#include "emuopts.h"
45#include "machine/bml3bus.h"
46
47
48//**************************************************************************
49//  GLOBAL VARIABLES
50//**************************************************************************
51
52const device_type BML3BUS_SLOT = &device_creator<bml3bus_slot_device>;
53
54//**************************************************************************
55//  LIVE DEVICE
56//**************************************************************************
57
58//-------------------------------------------------
59//  bml3bus_slot_device - constructor
60//-------------------------------------------------
61bml3bus_slot_device::bml3bus_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
62      device_t(mconfig, BML3BUS_SLOT, "Hitachi MB-6890 Slot", tag, owner, clock, "bml3bus_slot", __FILE__),
63      device_slot_interface(mconfig, *this)
64{
65}
66
67bml3bus_slot_device::bml3bus_slot_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source) :
68      device_t(mconfig, type, name, tag, owner, clock, shortname, source),
69      device_slot_interface(mconfig, *this)
70{
71}
72
73void bml3bus_slot_device::static_set_bml3bus_slot(device_t &device, const char *tag, const char *slottag)
74{
75   bml3bus_slot_device &bml3bus_card = dynamic_cast<bml3bus_slot_device &>(device);
76   bml3bus_card.m_bml3bus_tag = tag;
77   bml3bus_card.m_bml3bus_slottag = slottag;
78}
79
80//-------------------------------------------------
81//  device_start - device-specific startup
82//-------------------------------------------------
83
84void bml3bus_slot_device::device_start()
85{
86   device_bml3bus_card_interface *dev = dynamic_cast<device_bml3bus_card_interface *>(get_card_device());
87
88   if (dev) device_bml3bus_card_interface::static_set_bml3bus_tag(*dev, m_bml3bus_tag, m_bml3bus_slottag);
89}
90
91//**************************************************************************
92//  GLOBAL VARIABLES
93//**************************************************************************
94
95const device_type BML3BUS = &device_creator<bml3bus_device>;
96
97void bml3bus_device::static_set_cputag(device_t &device, const char *tag)
98{
99   bml3bus_device &bml3bus = downcast<bml3bus_device &>(device);
100   bml3bus.m_cputag = tag;
101}
102
103//-------------------------------------------------
104//  device_config_complete - perform any
105//  operations now that the configuration is
106//  complete
107//-------------------------------------------------
108
109void bml3bus_device::device_config_complete()
110{
111   // inherit a copy of the static data
112   const bml3bus_interface *intf = reinterpret_cast<const bml3bus_interface *>(static_config());
113   if (intf != NULL)
114   {
115      *static_cast<bml3bus_interface *>(this) = *intf;
116   }
117
118   // or initialize to defaults if none provided
119   else
120   {
121      memset(&m_out_nmi_cb, 0, sizeof(m_out_nmi_cb));
122      memset(&m_out_irq_cb, 0, sizeof(m_out_irq_cb));
123      memset(&m_out_firq_cb, 0, sizeof(m_out_firq_cb));
124   }
125}
126
127//**************************************************************************
128//  LIVE DEVICE
129//**************************************************************************
130
131//-------------------------------------------------
132//  bml3bus_device - constructor
133//-------------------------------------------------
134
135bml3bus_device::bml3bus_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
136      device_t(mconfig, BML3BUS, "Hitachi MB-6890 Bus", tag, owner, clock, "bml3bus", __FILE__)
137{
138}
139
140bml3bus_device::bml3bus_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source) :
141      device_t(mconfig, type, name, tag, owner, clock, shortname, source)
142{
143}
144//-------------------------------------------------
145//  device_start - device-specific startup
146//-------------------------------------------------
147
148void bml3bus_device::device_start()
149{
150   m_maincpu = machine().device<cpu_device>(m_cputag);
151
152   // resolve callbacks
153   m_out_nmi_func.resolve(m_out_nmi_cb, *this);
154   m_out_irq_func.resolve(m_out_irq_cb, *this);
155   m_out_firq_func.resolve(m_out_firq_cb, *this);
156
157   // clear slots
158   for (int i = 0; i < BML3BUS_MAX_SLOTS; i++)
159   {
160      m_device_list[i] = NULL;
161   }
162}
163
164//-------------------------------------------------
165//  device_reset - device-specific reset
166//-------------------------------------------------
167
168void bml3bus_device::device_reset()
169{
170}
171
172device_bml3bus_card_interface *bml3bus_device::get_bml3bus_card(int slot)
173{
174   if (slot < 0)
175   {
176      return NULL;
177   }
178
179   return m_device_list[slot];
180}
181
182void bml3bus_device::add_bml3bus_card(int slot, device_bml3bus_card_interface *card)
183{
184   m_device_list[slot] = card;
185}
186
187void bml3bus_device::set_nmi_line(int state)
188{
189   m_out_nmi_func(state);
190}
191
192void bml3bus_device::set_irq_line(int state)
193{
194   m_out_irq_func(state);
195}
196
197void bml3bus_device::set_firq_line(int state)
198{
199   m_out_firq_func(state);
200}
201
202// interrupt request from bml3bus card
203WRITE_LINE_MEMBER( bml3bus_device::nmi_w ) { m_out_nmi_func(state); }
204WRITE_LINE_MEMBER( bml3bus_device::irq_w ) { m_out_irq_func(state); }
205WRITE_LINE_MEMBER( bml3bus_device::firq_w ) { m_out_firq_func(state); }
206
207//**************************************************************************
208//  DEVICE CONFIG BML3BUS CARD INTERFACE
209//**************************************************************************
210
211
212//**************************************************************************
213//  DEVICE BML3BUS CARD INTERFACE
214//**************************************************************************
215
216//-------------------------------------------------
217//  device_bml3bus_card_interface - constructor
218//-------------------------------------------------
219
220device_bml3bus_card_interface::device_bml3bus_card_interface(const machine_config &mconfig, device_t &device)
221   : device_slot_card_interface(mconfig, device),
222      m_bml3bus(NULL),
223      m_bml3bus_tag(NULL)
224{
225}
226
227
228//-------------------------------------------------
229//  ~device_bml3bus_card_interface - destructor
230//-------------------------------------------------
231
232device_bml3bus_card_interface::~device_bml3bus_card_interface()
233{
234}
235
236void device_bml3bus_card_interface::static_set_bml3bus_tag(device_t &device, const char *tag, const char *slottag)
237{
238   device_bml3bus_card_interface &bml3bus_card = dynamic_cast<device_bml3bus_card_interface &>(device);
239   bml3bus_card.m_bml3bus_tag = tag;
240   bml3bus_card.m_bml3bus_slottag = slottag;
241}
242
243void device_bml3bus_card_interface::set_bml3bus_device()
244{
245   // extract the slot number from the last digit of the slot tag
246   int tlen = strlen(m_bml3bus_slottag);
247
248   m_slot = (m_bml3bus_slottag[tlen-1] - '1');
249
250   if (m_slot < 0 || m_slot >= BML3BUS_MAX_SLOTS)
251   {
252      fatalerror("Slot %x out of range for Hitachi MB-6890 Bus\n", m_slot);
253   }
254
255   m_bml3bus = dynamic_cast<bml3bus_device *>(device().machine().device(m_bml3bus_tag));
256   m_bml3bus->add_bml3bus_card(m_slot, this);
257}
Property changes on: trunk/src/mess/machine/bml3bus.c
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/mess/machine/bml3mp1802.h
r0r24065
1/*********************************************************************
2
3    bml3mp1802.h
4
5    Hitachi MP-1802 floppy disk controller card for the MB-6890
6    Hitachi MP-3550 floppy drive is attached
7
8*********************************************************************/
9
10#ifndef __BML3BUS_MP1802__
11#define __BML3BUS_MP1802__
12
13#include "emu.h"
14#include "machine/bml3bus.h"
15#include "imagedev/flopdrv.h"
16#include "machine/wd17xx.h"
17
18//**************************************************************************
19//  TYPE DEFINITIONS
20//**************************************************************************
21
22class bml3bus_mp1802_device:
23   public device_t,
24   public device_bml3bus_card_interface
25{
26public:
27   // construction/destruction
28   bml3bus_mp1802_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
29
30   // optional information overrides
31   virtual machine_config_constructor device_mconfig_additions() const;
32   virtual const rom_entry *device_rom_region() const;
33
34   DECLARE_READ8_MEMBER(bml3_mp1802_r);
35   DECLARE_WRITE8_MEMBER(bml3_mp1802_w);
36
37protected:
38   virtual void device_start();
39   virtual void device_reset();
40
41   required_device<mb8866_device> m_wd17xx;
42
43private:
44   UINT8 *m_rom;
45};
46
47// device type definition
48extern const device_type BML3BUS_MP1802;
49
50#endif /* __BML3BUS_MP1802__ */
Property changes on: trunk/src/mess/machine/bml3mp1802.h
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/mess/machine/bml3bus.h
r0r24065
1/***************************************************************************
2
3  bml3bus.h - Hitachi MB-6890 slot bus and card emulation
4
5  Adapted from a2bus by Jonathan Edwards
6
7***************************************************************************/
8
9#pragma once
10
11#ifndef __BML3BUS_H__
12#define __BML3BUS_H__
13
14#include "emu.h"
15
16#define BML3BUS_MAX_SLOTS 6
17
18//**************************************************************************
19//  INTERFACE CONFIGURATION MACROS
20//**************************************************************************
21
22#define MCFG_BML3BUS_BUS_ADD(_tag, _cputag, _config) \
23   MCFG_DEVICE_ADD(_tag, BML3BUS, 0) \
24   MCFG_DEVICE_CONFIG(_config) \
25   bml3bus_device::static_set_cputag(*device, _cputag);
26#define MCFG_BML3BUS_SLOT_ADD(_nbtag, _tag, _slot_intf, _def_slot) \
27   MCFG_DEVICE_ADD(_tag, BML3BUS_SLOT, 0) \
28   MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, false) \
29   bml3bus_slot_device::static_set_bml3bus_slot(*device, _nbtag, _tag);
30#define MCFG_BML3BUS_SLOT_REMOVE(_tag)    \
31   MCFG_DEVICE_REMOVE(_tag)
32
33#define MCFG_BML3BUS_ONBOARD_ADD(_nbtag, _tag, _dev_type) \
34   MCFG_DEVICE_ADD(_tag, _dev_type, 0) \
35   device_bml3bus_card_interface::static_set_bml3bus_tag(*device, _nbtag, _tag);
36
37#define MCFG_BML3BUS_BUS_REMOVE(_tag) \
38   MCFG_DEVICE_REMOVE(_tag)
39
40//**************************************************************************
41//  TYPE DEFINITIONS
42//**************************************************************************
43
44class bml3bus_device;
45
46class bml3bus_slot_device : public device_t,
47                     public device_slot_interface
48{
49public:
50   // construction/destruction
51   bml3bus_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
52   bml3bus_slot_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source);
53
54   // device-level overrides
55   virtual void device_start();
56
57   // inline configuration
58   static void static_set_bml3bus_slot(device_t &device, const char *tag, const char *slottag);
59protected:
60   // configuration
61   const char *m_bml3bus_tag, *m_bml3bus_slottag;
62};
63
64// device type definition
65extern const device_type BML3BUS_SLOT;
66
67// ======================> bml3bus_interface
68
69struct bml3bus_interface
70{
71   devcb_write_line    m_out_nmi_cb;
72   devcb_write_line    m_out_irq_cb;
73   devcb_write_line    m_out_firq_cb;
74};
75
76class device_bml3bus_card_interface;
77// ======================> bml3bus_device
78class bml3bus_device : public device_t,
79               public bml3bus_interface
80{
81public:
82   // construction/destruction
83   bml3bus_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
84   bml3bus_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source);
85   // inline configuration
86   static void static_set_cputag(device_t &device, const char *tag);
87
88   void add_bml3bus_card(int slot, device_bml3bus_card_interface *card);
89   device_bml3bus_card_interface *get_bml3bus_card(int slot);
90
91   void set_nmi_line(int state);
92   void set_irq_line(int state);
93   void set_firq_line(int state);
94
95   DECLARE_WRITE_LINE_MEMBER( nmi_w );
96   DECLARE_WRITE_LINE_MEMBER( irq_w );
97   DECLARE_WRITE_LINE_MEMBER( firq_w );
98
99protected:
100   // device-level overrides
101   virtual void device_start();
102   virtual void device_reset();
103   virtual void device_config_complete();
104
105   // internal state
106   cpu_device   *m_maincpu;
107
108   devcb_resolved_write_line   m_out_nmi_func;
109   devcb_resolved_write_line   m_out_irq_func;
110   devcb_resolved_write_line   m_out_firq_func;
111
112   device_bml3bus_card_interface *m_device_list[BML3BUS_MAX_SLOTS];
113   const char *m_cputag;
114};
115
116
117// device type definition
118extern const device_type BML3BUS;
119
120// ======================> device_bml3bus_card_interface
121
122// class representing interface-specific live bml3bus card
123class device_bml3bus_card_interface : public device_slot_card_interface
124{
125   friend class bml3bus_device;
126public:
127   // construction/destruction
128   device_bml3bus_card_interface(const machine_config &mconfig, device_t &device);
129   virtual ~device_bml3bus_card_interface();
130
131   device_bml3bus_card_interface *next() const { return m_next; }
132
133   void set_bml3bus_device();
134
135   void raise_slot_nmi() { m_bml3bus->set_nmi_line(ASSERT_LINE); }
136   void lower_slot_nmi() { m_bml3bus->set_nmi_line(CLEAR_LINE); }
137   void raise_slot_irq() { m_bml3bus->set_irq_line(ASSERT_LINE); }
138   void lower_slot_irq() { m_bml3bus->set_irq_line(CLEAR_LINE); }
139   void raise_slot_firq() { m_bml3bus->set_firq_line(ASSERT_LINE); }
140   void lower_slot_firq() { m_bml3bus->set_firq_line(CLEAR_LINE); }
141
142   // inline configuration
143   static void static_set_bml3bus_tag(device_t &device, const char *tag, const char *slottag);
144public:
145   bml3bus_device  *m_bml3bus;
146   const char *m_bml3bus_tag, *m_bml3bus_slottag;
147   int m_slot;
148   device_bml3bus_card_interface *m_next;
149};
150
151#endif  /* __BML3BUS_H__ */
Property changes on: trunk/src/mess/machine/bml3bus.h
Added: svn:eol-style
   + native
Added: svn:mime-type
   + text/plain
trunk/src/mess/mess.lst
r24064r24065
20942094rx78
20952095bmjr
20962096bml3
2097bml3a
2098bml3b
2097bml3mk2
2098bml3mk5
20992099b16
21002100psioncm
21012101psionla

Previous 199869 Revisions Next


© 1997-2024 The MAME Team