Previous 15994 Revisions Next

r1069 Wednesday 3rd October, 2007 at 12:25:11 UTC by Nathan Woods
[X68000] Changed to use common 68901 MFP code. [Barry Rodewald]
[docs]messnew.txt
[src/mess]mess.mak
[src/mess/drivers]x68k.c
[src/mess/includes]x68k.h
[src/mess/machine]68901mfp.c
[src/mess/video]x68k.c

src/mess/includes/x68k.h
r1068r1069
102102      int irqline;
103103      int eoi_mode;
104104      int current_irq;
105      unsigned char gpio;
105106   } mfp;  // MC68901 Multifunction Peripheral (4MHz)
106107   struct
107108   {
r1068r1069
167168   } mouse;
168169};
169170
170
171/*
171172TIMER_CALLBACK(mfp_timer_a_callback);
172173TIMER_CALLBACK(mfp_timer_b_callback);
173174TIMER_CALLBACK(mfp_timer_c_callback);
174175TIMER_CALLBACK(mfp_timer_d_callback);
175176void mfp_trigger_irq(int);
176
177*/
177178TIMER_CALLBACK(x68k_crtc_raster_irq);
178179TIMER_CALLBACK(x68k_crtc_vblank_irq);
179180TIMER_CALLBACK(x68k_hsync);
src/mess/video/x68k.c
r1068r1069
2929#include "inputx.h"
3030#include "render.h"
3131#include "includes/x68k.h"
32#include "machine/68901mfp.h"
3233
3334extern struct x68k_system sys;
3435
r1068r1069
188189   int state = param;
189190   mame_time irq_time = video_screen_get_scan_period(0);
190191   mame_time hsync_time = MAME_TIME_IN_CYCLES(0,32);
191   
192
193   sys.crtc.hblank = state;   
192194   if(state == 1)
193195   {
194      sys.crtc.hblank = 1;
195      mfp_trigger_irq(MFP_IRQ_GPIP7);  // HSync
196//      mfp_trigger_irq(MFP_IRQ_GPIP7);  // HSync
196197      mame_timer_adjust(scanline_timer,hsync_time,0,time_never);
197198   }
198199   if(state == 0)
199200   {
200201      double time_to_irq = mame_time_to_double(irq_time) - mame_time_to_double(hsync_time);
201      sys.crtc.hblank = 0;
202202      mame_timer_adjust(scanline_timer,double_to_mame_time(time_to_irq),1,time_never);
203      if(!(sys.mfp.gpio & 0x40))  // if GPIP6 is active, clear it
204         sys.mfp.gpio |= 0x40;
203205   }
204206}
205207
r1068r1069
208210{
209211   int scan = param;
210212   mame_time irq_time;
211   mfp_trigger_irq(MFP_IRQ_GPIP6);
212   if((sys.mfp.iera & 0x40) && (readinputportbytag("options") & 0x01))
213//   mfp_trigger_irq(MFP_IRQ_GPIP6);
214   sys.mfp.gpio &= ~0x40;  // GPIP6
215   if((readinputportbytag("options") & 0x01))
213216   {
214      video_screen_update_partial(0,(scan+1));
217      video_screen_update_partial(0,scan+1);
215218   }
216219
217220   irq_time = video_screen_get_time_until_pos(0,scan,2);
r1068r1069
229232
230233   if(val == 1)  // VBlank on
231234   {
232      mfp_timer_a_callback(machine, 0);
235      //mfp_timer_a_callback(machine, 0);
233236//      if(!(sys.mfp.aer & 0x10))
234         mfp_trigger_irq(MFP_IRQ_GPIP4);  // V-DISP
237//         mfp_trigger_irq(MFP_IRQ_GPIP4);  // V-DISP
235238      vblank_line = sys.crtc.reg[6];
236239      if(vblank_line > sys.crtc.reg[4])
237240         vblank_line = sys.crtc.reg[4];
r1068r1069
992995   {
993996      sys.mfp.isra = 0;
994997      sys.mfp.isrb = 0;
995      mfp_trigger_irq(MFP_IRQ_GPIP6);
998//      mfp_trigger_irq(MFP_IRQ_GPIP6);
996999//      cpunum_set_input_line_and_vector(0,6,ASSERT_LINE,0x43);
9971000   }
9981001   if(input_code_pressed(KEYCODE_9))
src/mess/machine/68901mfp.c
r1068r1069
569569            logerror("MFP68901 #%u Transmitter Auto Turnaround Disabled\n", which);
570570
571571         mfp_p->tsr = data & 0x2f;
572         mfp_p->tsr |= 0x80;  // x68000 expects the buffer to be empty, so this will do for now
572573      }
573574      break;
574575
src/mess/mess.mak
r1068r1069
953953   $(MESS_DRIVERS)/x68k.o   \
954954   $(MESS_VIDEO)/x68k.o   \
955955   $(MESS_MACHINE)/hd63450.o   \
956   $(MESS_MACHINE)/68901mfp.o \
956957   $(MESS_MACHINE)/rp5c15.o   \
957958
958959$(MESSOBJ)/hp48.a:     \
src/mess/drivers/x68k.c
r1068r1069
128128#include "inputx.h"
129129#include "render.h"
130130#include "cpu/m68000/m68000.h"
131#include "machine/68901mfp.h"
131132#include "machine/8255ppi.h"
132133#include "machine/nec765.h"
133134#include "sound/2151intf.h"
r1068r1069
151152UINT8 current_irq_line;
152153unsigned int x68k_scanline;
153154
155UINT8 mfp_key;
156
154157extern mame_bitmap* x68k_text_bitmap;  // 1024x1024 4x1bpp planes text
155158extern mame_bitmap* x68k_gfx_0_bitmap_16;  // 16 colour, 512x512, 4 pages
156159extern mame_bitmap* x68k_gfx_1_bitmap_16;
r1068r1069
166169extern tilemap* x68k_bg1_16;
167170
168171mame_timer* kb_timer;
169mame_timer* mfp_timer[4];
170mame_timer* mfp_irq;
172//mame_timer* mfp_timer[4];
173//mame_timer* mfp_irq;
171174mame_timer* scanline_timer;
172175mame_timer* raster_irq;
173176mame_timer* vblank_irq;
174177mame_timer* mouse_timer;  // to set off the mouse interrupts via the SCC
175178
176179// MFP is clocked at 4MHz, so at /4 prescaler the timer is triggered after 1us (4 cycles)
177static mame_time prescale(int val)
180// No longer necessary with the new MFP core
181/*static mame_time prescale(int val)
178182{
179183   switch(val)
180184   {
r1068r1069
189193      default:
190194         fatalerror("out of range");
191195   }
192}
196}*/
193197
194198void mfp_init(void);
195static TIMER_CALLBACK(mfp_update_irq);
199//static TIMER_CALLBACK(mfp_update_irq);
196200
197201void mfp_init()
198202{
r1068r1069
201205   sys.mfp.irqline = 6;  // MFP is connected to 68000 IRQ line 6
202206   sys.mfp.current_irq = -1;  // No current interrupt
203207
204   mfp_timer[0] = mame_timer_alloc(mfp_timer_a_callback);
208/*   mfp_timer[0] = mame_timer_alloc(mfp_timer_a_callback);
205209   mfp_timer[1] = mame_timer_alloc(mfp_timer_b_callback);
206210   mfp_timer[2] = mame_timer_alloc(mfp_timer_c_callback);
207211   mfp_timer[3] = mame_timer_alloc(mfp_timer_d_callback);
208212   mfp_irq = mame_timer_alloc(mfp_update_irq);
209213   mame_timer_adjust(mfp_irq, time_zero, 0, MAME_TIME_IN_USEC(32));
214*/
210215}
211
216/*
212217TIMER_CALLBACK(mfp_update_irq)
213218{
214219   int x;
r1068r1069
335340   logerror("MFP: Timer #%i set to %2.1fus\n",timer, mame_time_to_double(prescale(data & 0x07)) * 1000000);
336341
337342}
338
343*/
339344// 4 channel DMA controller (Hitachi HD63450)
340345WRITE16_HANDLER( x68k_dmac_w )
341346{
r1068r1069
435440      if(sys.keyboard.enabled != 0)
436441      {
437442         sys.mfp.rsr |= 0x80;  // Buffer full
438         mfp_trigger_irq(MFP_IRQ_RX_FULL);
443//         mfp_trigger_irq(MFP_IRQ_RX_FULL);
439444         logerror("MFP: Receive buffer full IRQ sent\n");
440445      }
441446   }
r1068r1069
443448   if(sys.keyboard.headpos > 15)
444449   {
445450      sys.keyboard.headpos = 0;
446      mfp_trigger_irq(MFP_IRQ_RX_ERROR);
451//      mfp_trigger_irq(MFP_IRQ_RX_ERROR);
447452   }
448453}
449454
r1068r1069
501506   sys.mfp.tsr |= 0x80;
502507   sys.mfp.usart.recv_buffer = 0x00;   // TODO: set up keyboard data
503508   sys.mfp.vector = current_vector[6] = (sys.mfp.vr & 0xf0) | 0x0c;
504   mfp_trigger_irq(MFP_IRQ_RX_FULL);
509//   mfp_trigger_irq(MFP_IRQ_RX_FULL);
505510//   logerror("MFP: Receive buffer full IRQ sent\n");
506511}
507512
r1068r1069
922927   }
923928}
924929
925
930/*
926931READ16_HANDLER( x68k_mfp_r )
927932{
928933   int ret;
929   /* Initial settings indicate that IRQs are generated for FM (YM2151), Receive buffer error or full,
930      MFP Timer C, and the power switch*/
934   // Initial settings indicate that IRQs are generated for FM (YM2151), Receive buffer error or full,
935   // MFP Timer C, and the power switch
931936//   logerror("MFP: [%08x] Reading offset %i\n",activecpu_get_pc(),offset);
932937   switch(offset)
933938   {
r1068r1069
986991}
987992
988993WRITE16_HANDLER( x68k_mfp_w )
989{
994{*/
990995   /* For the Interrupt registers, the bits are set out as such:
991996      Reg A - bit 7: GPIP7 (HSync)
992997              bit 6: GPIP6 (CRTC CIRQ)
r1068r1069
10051010            bit 1: GPIP1 (EXPON)
10061011            bit 0: GPIP0 (Alarm)
10071012   */
1008   switch(offset)
1013/*   switch(offset)
10091014   {
10101015   case 0:  // GPDR
10111016      // All bits are inputs generally, so no action taken.
r1068r1069
11111116      return;
11121117   }
11131118}
1119*/
11141120
11151121WRITE16_HANDLER( x68k_ppi_w )
11161122{
r1068r1069
11371143   if(sys.mfp.aer & 0x01)
11381144   {
11391145      if(state == 1)
1140         mfp_trigger_irq(MFP_IRQ_GPIP0);  // RTC ALARM
1146         sys.mfp.gpio |= 0x01;
1147         //mfp_trigger_irq(MFP_IRQ_GPIP0);  // RTC ALARM
11411148   }
11421149   else
11431150   {
11441151      if(state == 0)
1145         mfp_trigger_irq(MFP_IRQ_GPIP0);  // RTC ALARM
1152         sys.mfp.gpio &= ~0x01;
1153         //mfp_trigger_irq(MFP_IRQ_GPIP0);  // RTC ALARM
11461154   }
11471155}
11481156
r1068r1069
12451253{
12461254}
12471255
1256READ16_HANDLER( x68k_areaset_r )
1257{
1258   // register is write-only
1259   return 0xffff;
1260}
1261
1262WRITE16_HANDLER( x68k_areaset_w )
1263{
1264   // TODO
1265   logerror("SYS: Supervisor area set: 0x%02x\n",data & 0xff);
1266}
1267
1268WRITE16_HANDLER( x68k_enh_areaset_w )
1269{
1270   // TODO
1271   logerror("SYS: Enhanced Supervisor area set (from %iMB): 0x%02x\n",(offset + 1) * 2,data & 0xff);
1272}
1273
12481274static TIMER_CALLBACK(x68k_fake_bus_error)
12491275{
12501276   int val = param;
r1068r1069
13511377
13521378void x68k_fm_irq(int irq)
13531379{
1354   if(irq == ASSERT_LINE)
1380   if(irq == CLEAR_LINE)
13551381   {
1356//      sys.mfp.isrb |= 0x08;
1357//      current_vector[6] = (sys.mfp.vr & 0xf0) | 0x03;
1358//      current_irq_line = 6;
1359      mfp_trigger_irq(MFP_IRQ_GPIP3);
1382      sys.mfp.gpio |= 0x08;
13601383   }
1384   else
1385   {
1386      sys.mfp.gpio &= ~0x08;
1387      current_vector[6] = 0x43;
1388   }
1389   
13611390}
13621391
1392READ8_HANDLER(mfp_gpio_r)
1393{
1394   UINT8 data = sys.mfp.gpio;
1395   
1396   data &= ~(video_screen_get_hblank(0) << 7);
1397   data &= ~(sys.crtc.vblank << 4);
1398   data |= 0x23;  // GPIP5 is unused, always 1
1399   mfp68901_tai_w(0,sys.crtc.vblank);
1400
1401   return data;
1402}
1403
1404TIMER_CALLBACK( x68k_delayed_irq )
1405{
1406   if((sys.ioc.irqstatus & 0xc0) != 0)  // if the FDC is busy, then we don't want to miss that IRQ
1407   {
1408      mame_timer_set(MAME_TIME_IN_CYCLES(32,0),param,x68k_delayed_irq);
1409      return;
1410   }
1411   current_vector[6] = param;
1412   cpunum_set_input_line_and_vector(0,6,HOLD_LINE,param);
1413}
1414
1415void mfp_irq_callback(int which, int state, int vector)
1416{
1417   if(state == HOLD_LINE)
1418   {
1419      if((sys.ioc.irqstatus & 0xc0) != 0)  // if the FDC is busy, then we don't want to miss that IRQ
1420      {
1421         mame_timer_set(MAME_TIME_IN_CYCLES(32,0),vector,x68k_delayed_irq);
1422         return;
1423      }
1424      current_vector[6] = vector;
1425      cpunum_set_input_line_and_vector(0,6,state,vector);
1426//      logerror("MFP IRQ callback: state=%i,vector=0x%02x\n",state,vector);
1427   }
1428}
1429
13631430static INTERRUPT_GEN( x68k_vsync_irq )
13641431{
13651432//   if(sys.mfp.ierb & 0x40)
r1068r1069
13701437//   mfp_timer_a_callback(0);  // Timer A is usually always in event count mode, and is tied to V-DISP
13711438//   mfp_trigger_irq(MFP_IRQ_GPIP4);
13721439//   }
1373   if(sys.crtc.height == 256)
1374      video_screen_update_partial(0,256);//sys.crtc.reg[4]/2);
1375   else
1376      video_screen_update_partial(0,512);//sys.crtc.reg[4]);
1440//   if(sys.crtc.height == 256)
1441//      video_screen_update_partial(0,256);//sys.crtc.reg[4]/2);
1442//   else
1443//      video_screen_update_partial(0,512);//sys.crtc.reg[4]);
13771444}
13781445
13791446static int x68k_int_ack(int line)
r1068r1069
13901457   if(line == 6)  // MFP
13911458   {
13921459//      if(sys.mfp.isra & 0x10)
1393         sys.mfp.rsr &= ~0x80;
1460//         sys.mfp.rsr &= ~0x80;
13941461//      if(sys.mfp.isra & 0x04)
1395         sys.mfp.tsr &= ~0x80;
1462//         sys.mfp.tsr &= ~0x80;
13961463
1397      if(sys.mfp.current_irq < 8)
1398      {
1399         sys.mfp.iprb &= ~(1 << sys.mfp.current_irq);
1464//      if(sys.mfp.current_irq < 8)
1465//      {
1466//         sys.mfp.iprb &= ~(1 << sys.mfp.current_irq);
14001467         // IRQ is in service
1401         if(sys.mfp.eoi_mode != 0)  // automatic EOI does not set the ISR registers
1402            sys.mfp.isrb |= (1 << sys.mfp.current_irq);
1403      }
1404      else
1405      {
1406         sys.mfp.ipra &= ~(1 << (sys.mfp.current_irq - 8));
1468//         if(sys.mfp.eoi_mode != 0)  // automatic EOI does not set the ISR registers
1469//            sys.mfp.isrb |= (1 << sys.mfp.current_irq);
1470//      }
1471//      else
1472//      {
1473//         sys.mfp.ipra &= ~(1 << (sys.mfp.current_irq - 8));
14071474         // IRQ is in service
1408         if(sys.mfp.eoi_mode != 0)  // automatic EOI does not set the ISR registers
1409            sys.mfp.isra |= (1 << (sys.mfp.current_irq - 8));
1410      }
1475//         if(sys.mfp.eoi_mode != 0)  // automatic EOI does not set the ISR registers
1476//            sys.mfp.isra |= (1 << (sys.mfp.current_irq - 8));
1477//      }
14111478      sys.mfp.current_irq = -1;
14121479   }
14131480
r1068r1069
14251492   AM_RANGE(0xe80000, 0xe81fff) AM_READWRITE(x68k_crtc_r, x68k_crtc_w)
14261493   AM_RANGE(0xe82000, 0xe83fff) AM_READWRITE(x68k_vid_r, x68k_vid_w)
14271494   AM_RANGE(0xe84000, 0xe85fff) AM_READWRITE(x68k_dmac_r, x68k_dmac_w)
1428//  AM_RANGE(0xe86000, 0xe87fff) AM_READWRITE(x68k_areaset_r, x68k_areaset_w)
1429   AM_RANGE(0xe88000, 0xe89fff) AM_READWRITE(x68k_mfp_r, x68k_mfp_w)
1495   AM_RANGE(0xe86000, 0xe87fff) AM_READWRITE(x68k_areaset_r, x68k_areaset_w)
1496   AM_RANGE(0xe88000, 0xe89fff) AM_READWRITE(mfp68901_0_register_lsb_r, mfp68901_0_register_lsb_w)
14301497   AM_RANGE(0xe8a000, 0xe8bfff) AM_READWRITE(x68k_rtc_r, x68k_rtc_w)
14311498//  AM_RANGE(0xe8c000, 0xe8dfff) AM_READWRITE(x68k_printer_r, x68k_printer_w)
14321499   AM_RANGE(0xe8e000, 0xe8ffff) AM_READWRITE(x68k_sysport_r, x68k_sysport_w)
r1068r1069
14381505   AM_RANGE(0xe9a000, 0xe9bfff) AM_READWRITE(x68k_ppi_r, x68k_ppi_w)
14391506   AM_RANGE(0xe9c000, 0xe9dfff) AM_READWRITE(x68k_ioc_r, x68k_ioc_w)
14401507   AM_RANGE(0xeafa00, 0xeafa1f) AM_READWRITE(x68k_exp_r, x68k_exp_w)
1508   AM_RANGE(0xeafa80, 0xeafa89) AM_READWRITE(x68k_areaset_r, x68k_enh_areaset_w)
14411509   AM_RANGE(0xeb0000, 0xeb7fff) AM_READWRITE(x68k_spritereg_r, x68k_spritereg_w)
14421510   AM_RANGE(0xeb8000, 0xebffff) AM_READWRITE(x68k_spriteram_r, x68k_spriteram_w)
14431511   AM_RANGE(0xec0000, 0xecffff) AM_NOP  // User I/O
r1068r1069
14471515   AM_RANGE(0xf00000, 0xffffff) AM_ROM
14481516ADDRESS_MAP_END
14491517
1518static mfp68901_interface mfp_interface =
1519{
1520   4000000, // 4MHz clock
1521   4000000,
1522   0,
1523   0,
1524   &mfp_key,  // Rx
1525   NULL,      // Tx
1526   NULL,
1527   mfp_irq_callback,
1528   mfp_gpio_r,
1529   NULL
1530};
1531
14501532static ppi8255_interface ppi_interface =
14511533{
14521534   1,  // 1 PPI
r1068r1069
18221904   
18231905   // start HBlank timer
18241906   mame_timer_adjust(scanline_timer,video_screen_get_scan_period(0),1,time_never);
1907
1908   sys.mfp.gpio = 0xfb;
18251909}
18261910
18271911MACHINE_START( x68000 )
r1068r1069
18831967
18841968   memset(&sys,0,sizeof(sys));
18851969
1970   mfp68901_config(0,&mfp_interface);
18861971   cpunum_set_irq_callback(0, x68k_int_ack);
18871972
18881973   // init keyboard
docs/messnew.txt
r1068r1069
1717
1818- [PCE] Added preliminary emulation of the CD-ROM interface.  [Wilbert Pol]
1919
20- [X68000] Changed to use common 68901 MFP code.  [Barry Rodewald]
2021
2122
23
2224User Interface Changes:
2325-----------------------
2426(none)

Previous 15994 Revisions Next


© 1998-2018 The MESS Team