Previous 199869 Revisions Next

r26774 Friday 27th December, 2013 at 08:03:27 UTC by Robbbert
(MESS) bml3 : replaced beeper with speaker; fixed a video issue (nw)
[src/mess/drivers]bml3.c

trunk/src/mess/drivers/bml3.c
r26773r26774
1818#include "cpu/m6809/m6809.h"
1919#include "machine/bml3bus.h"
2020#include "video/mc6845.h"
21#include "sound/beep.h"
2221#include "machine/6821pia.h"
2322#include "machine/6850acia.h"
2423#include "sound/2203intf.h"
2524#include "machine/bml3mp1802.h"
2625#include "machine/bml3mp1805.h"
2726#include "machine/bml3kanji.h"
28
27#include "sound/speaker.h"
28//#include "sound/wave.h"
2929//#include "imagedev/cassette.h"
3030
3131// System clock definitions, from the MB-6890 servce manual, p.48:
r26773r26774
6767{
6868public:
6969   bml3_state(const machine_config &mconfig, device_type type, const char *tag)
70      : driver_device(mconfig, type, tag),
71      m_maincpu(*this, "maincpu"),
72      m_bml3bus(*this, "bml3bus"),
73      m_crtc(*this, "crtc"),
74      //m_cass(*this, "cassette"),
75      m_beep(*this, "beeper"),
76      m_ym2203(*this, "ym2203")
77   {
78   }
70      : driver_device(mconfig, type, tag)
71      , m_maincpu(*this, "maincpu")
72      , m_bml3bus(*this, "bml3bus")
73      , m_crtc(*this, "crtc")
74      //, m_cass(*this, "cassette")
75      , m_speaker(*this, "speaker")
76      , m_ym2203(*this, "ym2203")
77   { }
7978
80   required_device<cpu_device> m_maincpu;
81   required_device<bml3bus_device> m_bml3bus;
82   required_device<mc6845_device> m_crtc;
83   //required_device<cassette_image_device> m_cass;
84   required_device<beep_device> m_beep;
85   optional_device<ym2203_device> m_ym2203;
79   DECLARE_READ8_MEMBER(bml3_6845_r);
8680   DECLARE_WRITE8_MEMBER(bml3_6845_w);
8781   DECLARE_READ8_MEMBER(bml3_keyboard_r);
8882   DECLARE_WRITE8_MEMBER(bml3_keyboard_w);
r26773r26774
115109   DECLARE_READ8_MEMBER(bml3_f000_r); DECLARE_WRITE8_MEMBER(bml3_f000_w);
116110   DECLARE_READ8_MEMBER(bml3_fff0_r); DECLARE_WRITE8_MEMBER(bml3_fff0_w);
117111
112   UINT8 *m_p_videoram;
113   UINT8 *m_p_chargen;
114   UINT8 m_hres_reg;
115   UINT8 m_crtc_vreg[0x100];
116   // INTERRUPT_GEN_MEMBER(bml3_irq);
117   INTERRUPT_GEN_MEMBER(bml3_timer_firq);
118   TIMER_DEVICE_CALLBACK_MEMBER(keyboard_callback);
119   DECLARE_READ8_MEMBER(bml3_ym2203_r);
120   DECLARE_WRITE8_MEMBER(bml3_ym2203_w);
121private:
122   UINT8 m_psg_latch;
118123   UINT8 m_attr_latch;
119124   UINT8 m_io_latch;
120   UINT8 m_hres_reg;
121125   UINT8 m_vres_reg;
122126   UINT8 m_keyb_interrupt_disabled;
123127   UINT8 m_keyb_nmi_disabled;
r26773r26774
127131   UINT8 m_keyb_capslock_led_on;
128132   UINT8 m_keyb_hiragana_led_on;
129133   UINT8 m_keyb_katakana_led_on;
130   UINT8 *m_p_chargen;
131   UINT8 m_psg_latch;
132   void m6845_change_clock(UINT8 setting);
133   UINT8 m_crtc_vreg[0x100],m_crtc_index;
134   UINT8 *m_extram;
135   UINT8 m_firq_mask,m_firq_status;
136
137protected:
138134   virtual void machine_reset();
139
140135   virtual void machine_start();
141   virtual void video_start();
142136   virtual void palette_init();
143public:
144   UINT32 screen_update_bml3(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
145   // INTERRUPT_GEN_MEMBER(bml3_irq);
146   INTERRUPT_GEN_MEMBER(bml3_timer_firq);
147   TIMER_DEVICE_CALLBACK_MEMBER(keyboard_callback);
148   DECLARE_READ8_MEMBER(bml3_ym2203_r);
149   DECLARE_WRITE8_MEMBER(bml3_ym2203_w);
137   void m6845_change_clock(UINT8 setting);
138   UINT8 m_crtc_index;
139   UINT8 *m_extram;
140   UINT8 m_firq_mask,m_firq_status;
141   required_device<cpu_device> m_maincpu;
142   required_device<bml3bus_device> m_bml3bus;
143   required_device<mc6845_device> m_crtc;
144   //required_device<cassette_image_device> m_cass;
145   required_device<speaker_sound_device> m_speaker;
146   optional_device<ym2203_device> m_ym2203;
150147};
151148
152149#define mc6845_h_char_total     (m_crtc_vreg[0])
r26773r26774
167164#define mc6845_update_addr      (((m_crtc_vreg[0x12]<<8) & 0x3f00) | (m_crtc_vreg[0x13] & 0xff))
168165
169166
170void bml3_state::video_start()
171{
172   m_p_chargen = memregion("chargen")->base();
173}
174167
175UINT32 bml3_state::screen_update_bml3(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
168READ8_MEMBER( bml3_state::bml3_6845_r )
176169{
177   // The MB-6890 has a 5-bit colour RAM region.  The meaning of the bits are:
178   // 0: blue
179   // 1: red
180   // 2: green
181   // 3: reverse/inverse video
182   // 4: graphic (not character)
183
184   int x,y,hf,count;
185   int xi,yi;
186   int width,interlace,lowres;
187   int bgcolor;
188   int rawbits,dots[2],color,reverse,graphic;
189   UINT8 *vram = memregion("vram")->base();
190
191   count = 0x0000;
192
193   width = (m_hres_reg & 0x80) ? 80 : 40;
194   interlace = (m_vres_reg & 0x08) ? 1 : 0;
195   lowres = (m_hres_reg & 0x40) ? 1 : 0;
196   bgcolor = m_hres_reg & 0x07;
197
198   // redundant initializers to keep compiler happy
199   rawbits = dots[0] = dots[1] = color = reverse = graphic = 0;
200
201//  popmessage("%02x %02x",m_hres_reg,m_vres_reg);
202
203   for(y=0;y<25;y++)
204   {
205      for(x=0;x<width;x++)
206      {
207         for(yi=0;yi<8;yi++)
208         {
209            if (!lowres || yi == 0) {
210               int offset = count + yi * (width / 40 * 0x400) + mc6845_start_addr - 0x400;
211               if (offset >= 0x0000 && offset < 0x4000) {
212                  rawbits = vram[offset+0x0000];
213                  color = vram[offset+0x4000] & 7;
214                  reverse = vram[offset+0x4000] & 8;
215                  graphic = vram[offset+0x4000] & 0x10;
216               }
217               else {
218                  // outside vram - don't know what should happen here
219                  rawbits = color = reverse = graphic = 0;
220               }
221            }
222            if (graphic) {
223               if (lowres) {
224                  // low-res graphics, each tile has 8 bits arranged as follows:
225                  // 4 0
226                  // 5 1
227                  // 6 2
228                  // 7 3
229                  dots[0] = dots[1] = (rawbits >> yi/2 & 0x11) * 0xf;
230               }
231               else {
232                  dots[0] = dots[1] = rawbits;
233               }
234            }
235            else {
236               // character mode
237               int tile = rawbits  & 0x7f;
238               int tile_bank = (rawbits & 0x80) >> 7;
239               if (interlace) {
240                  dots[0] = m_p_chargen[(tile_bank<<11)|(tile<<4)|(yi<<1)];
241                  dots[1] = m_p_chargen[(tile_bank<<11)|(tile<<4)|(yi<<1)|tile_bank];
242               }
243               else {
244                  dots[0] = dots[1] = m_p_chargen[(tile<<4)|(yi<<1)|tile_bank];
245               }
246            }
247            for(hf=0;hf<=interlace;hf++)
248            {
249               for(xi=0;xi<8;xi++)
250               {
251                  int pen;
252
253                  if(reverse)
254                     pen = (dots[hf] >> (7-xi) & 1) ? bgcolor : color;
255                  else
256                     pen = (dots[hf] >> (7-xi) & 1) ? color : bgcolor;
257
258                  bitmap.pix16((y*8+yi)*(interlace+1)+hf, x*8+xi) = pen;
259               }
260            }
261         }
262
263         if(mc6845_cursor_addr-mc6845_start_addr == count)
264         {
265            int xc,yc,cursor_on;
266
267            cursor_on = 0;
268            switch(mc6845_cursor_y_start & 0x60)
269            {
270               case 0x00: cursor_on = 1; break; //always on
271               case 0x20: cursor_on = 0; break; //always off
272               case 0x40: if(machine().primary_screen->frame_number() & 0x10) { cursor_on = 1; } break; //fast blink
273               case 0x60: if(machine().primary_screen->frame_number() & 0x20) { cursor_on = 1; } break; //slow blink
274            }
275
276            if(cursor_on)
277            {
278               for(yc=0;yc<(8-(mc6845_cursor_y_start & 7));yc++)
279               {
280                  for(xc=0;xc<8;xc++)
281                  {
282                     if(interlace)
283                     {
284                        bitmap.pix16((y*8+yc+7)*2+0, x*8+xc) = 7;
285                        bitmap.pix16((y*8+yc+7)*2+1, x*8+xc) = 7;
286                     }
287                     else
288                        bitmap.pix16(y*8+yc+7, x*8+xc) = 7;
289                  }
290               }
291            }
292         }
293
294         count++;
295      }
296   }
297
298   return 0;
170   if (offset)
171      return m_crtc->register_r(space, 0);
172   else
173      return m_crtc->status_r(space, 0);
299174}
300175
301176WRITE8_MEMBER( bml3_state::bml3_6845_w )
r26773r26774
373248
374249READ8_MEMBER( bml3_state::bml3_vram_r )
375250{
376   UINT8 *vram = memregion("vram")->base();
377
378251   // Bit 7 masks reading back to the latch
379   if ((m_attr_latch & 0x80) == 0) {
380      m_attr_latch = vram[offset+0x4000];
252   if (!BIT(m_attr_latch, 7))
253   {
254      m_attr_latch = m_p_videoram[offset+0x4000];
381255   }
382256
383   return vram[offset];
257   return m_p_videoram[offset];
384258}
385259
386260WRITE8_MEMBER( bml3_state::bml3_vram_w )
387261{
388   UINT8 *vram = memregion("vram")->base();
389
390   vram[offset] = data;
262   m_p_videoram[offset] = data;
391263   // color ram is 5-bit
392   vram[offset+0x4000] = m_attr_latch & 0x1F;
264   m_p_videoram[offset+0x4000] = m_attr_latch & 0x1F;
393265}
394266
395267READ8_MEMBER( bml3_state::bml3_psg_latch_r)
r26773r26774
444316
445317WRITE8_MEMBER( bml3_state::bml3_beep_w)
446318{
447   m_beep->set_state(!BIT(data, 7));
319   m_speaker->level_w(BIT(data, 7));
448320}
449321
450322READ8_MEMBER( bml3_state::bml3_a000_r) { return m_extram[offset + 0xa000]; }
r26773r26774
505377   AM_RANGE(0xffc0, 0xffc3) AM_DEVREADWRITE("pia6821", pia6821_device, read, write)
506378   AM_RANGE(0xffc4, 0xffc4) AM_DEVREADWRITE("acia6850", acia6850_device, status_read, control_write)
507379   AM_RANGE(0xffc5, 0xffc5) AM_DEVREADWRITE("acia6850", acia6850_device, data_read, data_write)
508   AM_RANGE(0xffc6, 0xffc7) AM_WRITE(bml3_6845_w)
380   AM_RANGE(0xffc6, 0xffc7) AM_READWRITE(bml3_6845_r,bml3_6845_w)
509381   // KBNMI - Keyboard "Break" key non-maskable interrupt
510382   AM_RANGE(0xffc8, 0xffc8) AM_READ(bml3_keyb_nmi_r) // keyboard nmi
511383   // DIPSW - DIP switches on system mainboard
r26773r26774
518390   AM_RANGE(0xffd0, 0xffd0) AM_WRITE(bml3_hres_reg_w)
519391   // TRACE - Trace counter
520392//  AM_RANGE(0xffd1, 0xffd1)
521   // REMOTE - Remote relay control for cassette?
393   // REMOTE - Remote relay control for cassette - bit 7
522394//  AM_RANGE(0xffd2, 0xffd2)
523395   // MUSIC_SEL - Music select: toggle audio output level when rising
524396   AM_RANGE(0xffd3, 0xffd3) AM_READWRITE(bml3_beep_r,bml3_beep_w)
r26773r26774
699571   PORT_BIT(0xffe00000,IP_ACTIVE_HIGH,IPT_UNKNOWN)
700572INPUT_PORTS_END
701573
574static MC6845_UPDATE_ROW( update_row )
575{
576   bml3_state *state = device->machine().driver_data<bml3_state>();
577   const rgb_t *palette = palette_entry_list_raw(bitmap.palette());
578   // The MB-6890 has a 5-bit colour RAM region.  The meaning of the bits are:
579   // 0: blue
580   // 1: red
581   // 2: green
582   // 3: reverse/inverse video
583   // 4: graphic (not character)
702584
585   UINT8 x=0,hf=0,xi=0,interlace=0,bgcolor=0,rawbits=0,dots[2],color=0,pen=0;
586   bool reverse=0,graphic=0,lowres=0;
587   UINT16 mem=0;
588
589   interlace = (state->m_crtc_vreg[8] & 3) ? 1 : 0;
590   lowres = BIT(state->m_hres_reg, 6);
591   bgcolor = state->m_hres_reg & 7;
592
593   if (interlace)
594   {
595      ra >>= 1;
596      if (y > 0x176) return;
597   }
598
599   // redundant initializers to keep compiler happy
600   dots[0] = dots[1] = 0;
601
602   for(x=0; x<x_count; x++)
603   {
604      if (lowres)
605         mem = (ma + x - 0x400) & 0x3fff;
606      else
607         mem = (ma + x + ra * x_count/40 * 0x400 -0x400) & 0x3fff;
608
609      color = state->m_p_videoram[mem|0x4000] & 7;
610      reverse = BIT(state->m_p_videoram[mem|0x4000], 3) ^ (x == cursor_x);
611      graphic = BIT(state->m_p_videoram[mem|0x4000], 4);
612
613      rawbits = state->m_p_videoram[mem];
614
615      if (graphic)
616      {
617         if (lowres)
618         {
619            // low-res graphics, each tile has 8 bits arranged as follows:
620            // 4 0
621            // 5 1
622            // 6 2
623            // 7 3
624            dots[0] = dots[1] = (rawbits >> ra/2 & 0x11) * 0xf;
625         }
626         else
627         {
628            dots[0] = dots[1] = rawbits;
629         }
630      }
631      else
632      {
633         // character mode
634         int tile = rawbits & 0x7f;
635         int tile_bank = BIT(rawbits, 7);
636         if (interlace)
637         {
638            dots[0] = state->m_p_chargen[(tile_bank<<11)|(tile<<4)|(ra<<1)];
639            dots[1] = state->m_p_chargen[(tile_bank<<11)|(tile<<4)|(ra<<1)|tile_bank];
640         }
641         else
642         {
643            dots[0] = dots[1] = state->m_p_chargen[(tile<<4)|(ra<<1)|tile_bank];
644         }
645      }
646
647      for(hf=0;hf<=interlace;hf++)
648      {
649         for(xi=0;xi<8;xi++)
650         {
651            if(reverse)
652               pen = (dots[hf] >> (7-xi) & 1) ? bgcolor : color;
653            else
654               pen = (dots[hf] >> (7-xi) & 1) ? color : bgcolor;
655
656            bitmap.pix32(y, x*8+xi) = palette[pen];
657            // when the mc6845 device gains full interlace&video support, replace the line above with the line below
658            // bitmap.pix32(y*(interlace+1)+hf, x*8+xi) = palette[pen];
659         }
660      }
661   }
662}
663
703664static MC6845_INTERFACE( mc6845_intf )
704665{
705666   false,      /* show border area */
706667   8,          /* number of pixels per video memory address */
707668   NULL,       /* before pixel update callback */
708   NULL,       /* row update callback */
669   update_row,       /* row update callback */
709670   NULL,       /* after pixel update callback */
710671   DEVCB_NULL, /* callback for display state changes */
711672   DEVCB_NULL, /* callback for cursor state changes */
r26773r26774
788749
789750void bml3_state::machine_start()
790751{
791   m_beep->set_frequency(1200); //guesswork
792   m_beep->set_state(0);
793752   m_extram = auto_alloc_array(machine(),UINT8,0x10000);
753   m_p_chargen = memregion("chargen")->base();
754   m_p_videoram = memregion("vram")->base();
794755}
795756
796757void bml3_state::machine_reset()
r26773r26774
987948   MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2400)) /* Service manual specifies "Raster return period" as 2.4 ms (p.64), although the total vertical non-displaying time seems to be 4 ms. */
988949   MCFG_SCREEN_SIZE(640, 400)
989950   MCFG_SCREEN_VISIBLE_AREA(0, 320-1, 0, 200-1)
990   MCFG_SCREEN_UPDATE_DRIVER(bml3_state, screen_update_bml3)
951   MCFG_SCREEN_UPDATE_DEVICE("crtc", mc6845_device, screen_update)
991952   MCFG_PALETTE_LENGTH(8)
992953
993954   /* Devices */
r26773r26774
1001962
1002963   /* Audio */
1003964   MCFG_SPEAKER_STANDARD_MONO("mono")
1004   MCFG_SOUND_ADD("beeper", BEEP, 0)
1005   MCFG_SOUND_ROUTE(ALL_OUTPUTS,"mono",0.50)
965   //MCFG_SOUND_WAVE_ADD(WAVE_TAG, "cassette")
966   //MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25)
967   MCFG_SOUND_ADD("speaker", SPEAKER_SOUND, 0)
968   MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50)
1006969
1007970   /* slot devices */
1008971   MCFG_BML3BUS_BUS_ADD("bml3bus", "maincpu", bml3bus_intf)

Previous 199869 Revisions Next


© 1997-2024 The MAME Team