Previous 15994 Revisions Next

r883 Wednesday 29th August, 2007 at 00:39:50 UTC by Justin Kerk
Fix svn:eol-style and svn:executable
[src/mess]mslegacy.h
[src/mess/audio]lmc1992.c lmc1992.h
[src/mess/drivers]cybiko.c
[src/mess/includes]cybiko.h
[src/mess/machine]amigacd.c amigacd.h amigacrt.c amigacrt.h at45dbxx.c at45dbxx.h cybiko.c matsucd.c matsucd.h pcf8593.c pcf8593.h sst39vfx.c sst39vfx.h
[src/mess/video]hd66421.c hd66421.h
[src/osd/sdl]SDL1211_opengl.h

src/mess/audio/lmc1992.c
r882r883
1#include "lmc1992.h"
2 
3static struct LMC1992
4{
5   const lmc1992_interface *intf;
6 
7   int enable;
8   int data;
9   int clock;
10   UINT16 si;
11 
12   int input;
13   int bass, treble;
14   int volume;
15   int fader_rf, fader_lf, fader_rr, fader_lr;
16} lmc;
17 
18static void lmc1992_command_w(int addr, int data)
19{
20   switch (addr)
21   {
22   case LMC1992_FUNCTION_INPUT_SELECT:
23      if (data == LCM1992_INPUT_SELECT_OPEN)
24      {
25         logerror("LMC1992 Input Select : OPEN\n");
26      }
27      else
28      {
29         logerror("LMC1992 Input Select : INPUT%u\n", data);
30      }
31      lmc.input = data;
32      break;
33   case LMC1992_FUNCTION_BASS:
34      logerror("LMC1992 Bass : %i dB\n", -40 + (data * 2));
35      lmc.bass = data;
36      break;
37   case LMC1992_FUNCTION_TREBLE:
38      logerror("LMC1992 Treble : %i dB\n", -40 + (data * 2));
39      lmc.treble = data;
40      break;
41   case LMC1992_FUNCTION_VOLUME:
42      logerror("LMC1992 Volume : %i dB\n", -80 + (data * 2));
43      lmc.volume = data;
44      break;
45   case LMC1992_FUNCTION_RIGHT_FRONT_FADER:
46      logerror("LMC1992 Right Front Fader : %i dB\n", -40 + (data * 2));
47      lmc.fader_rf = data;
48      break;
49   case LMC1992_FUNCTION_LEFT_FRONT_FADER:
50      logerror("LMC1992 Left Front Fader : %i dB\n", -40 + (data * 2));
51      lmc.fader_lf = data;
52      break;
53   case LMC1992_FUNCTION_RIGHT_REAR_FADER:
54      logerror("LMC1992 Right Rear Fader : %i dB\n", -40 + (data * 2));
55      lmc.fader_rr = data;
56      break;
57   case LMC1992_FUNCTION_LEFT_REAR_FADER:
58      logerror("LMC1992 Left Rear Fader : %i dB\n", -40 + (data * 2));
59      lmc.fader_lr = data;
60      break;
61   }
62}
63 
64void lmc1992_clock_w(int level)
65{
66   // clock data in on rising edge
67 
68   if ((lmc.enable == 0) && ((lmc.clock == 0) && (level == 1)))
69   {
70      lmc.si >>= 1;
71      lmc.si = lmc.si & 0x7fff;
72 
73      if (lmc.data)
74      {
75         lmc.si &= 0x8000;
76      }
77   }
78 
79   lmc.clock = level;
80}
81 
82void lmc1992_data_w(int level)
83{
84   lmc.data = level;
85}
86 
87void lmc1992_enable_w(int level)
88{
89   if ((lmc.enable == 0) && (level == 1))
90   {
91      UINT8 device = (lmc.si & 0xc000) >> 14;
92      UINT8 addr = (lmc.si & 0x3800) >> 11;
93      UINT8 data = (lmc.si & 0x07e0) >> 5;
94 
95      if (device == LMC1992_MICROWIRE_DEVICE_ADDRESS)
96      {
97         lmc1992_command_w(addr, data);
98      }
99   }
100 
101   lmc.enable = level;
102}
103 
104void lmc1992_config(const lmc1992_interface *intf)
105{
106   memset(&lmc, 0, sizeof(lmc));
107 
108   lmc.intf = intf;
109 
110   state_save_register_global(lmc.enable);
111   state_save_register_global(lmc.data);
112   state_save_register_global(lmc.clock);
113   state_save_register_global(lmc.si);
114   state_save_register_global(lmc.input);
115   state_save_register_global(lmc.bass);
116   state_save_register_global(lmc.treble);
117   state_save_register_global(lmc.volume);
118   state_save_register_global(lmc.fader_rf);
119   state_save_register_global(lmc.fader_lf);
120   state_save_register_global(lmc.fader_rr);
121   state_save_register_global(lmc.fader_lr);
122}
1#include "lmc1992.h"
2
3static struct LMC1992
4{
5   const lmc1992_interface *intf;
6
7   int enable;
8   int data;
9   int clock;
10   UINT16 si;
11
12   int input;
13   int bass, treble;
14   int volume;
15   int fader_rf, fader_lf, fader_rr, fader_lr;
16} lmc;
17
18static void lmc1992_command_w(int addr, int data)
19{
20   switch (addr)
21   {
22   case LMC1992_FUNCTION_INPUT_SELECT:
23      if (data == LCM1992_INPUT_SELECT_OPEN)
24      {
25         logerror("LMC1992 Input Select : OPEN\n");
26      }
27      else
28      {
29         logerror("LMC1992 Input Select : INPUT%u\n", data);
30      }
31      lmc.input = data;
32      break;
33   case LMC1992_FUNCTION_BASS:
34      logerror("LMC1992 Bass : %i dB\n", -40 + (data * 2));
35      lmc.bass = data;
36      break;
37   case LMC1992_FUNCTION_TREBLE:
38      logerror("LMC1992 Treble : %i dB\n", -40 + (data * 2));
39      lmc.treble = data;
40      break;
41   case LMC1992_FUNCTION_VOLUME:
42      logerror("LMC1992 Volume : %i dB\n", -80 + (data * 2));
43      lmc.volume = data;
44      break;
45   case LMC1992_FUNCTION_RIGHT_FRONT_FADER:
46      logerror("LMC1992 Right Front Fader : %i dB\n", -40 + (data * 2));
47      lmc.fader_rf = data;
48      break;
49   case LMC1992_FUNCTION_LEFT_FRONT_FADER:
50      logerror("LMC1992 Left Front Fader : %i dB\n", -40 + (data * 2));
51      lmc.fader_lf = data;
52      break;
53   case LMC1992_FUNCTION_RIGHT_REAR_FADER:
54      logerror("LMC1992 Right Rear Fader : %i dB\n", -40 + (data * 2));
55      lmc.fader_rr = data;
56      break;
57   case LMC1992_FUNCTION_LEFT_REAR_FADER:
58      logerror("LMC1992 Left Rear Fader : %i dB\n", -40 + (data * 2));
59      lmc.fader_lr = data;
60      break;
61   }
62}
63
64void lmc1992_clock_w(int level)
65{
66   // clock data in on rising edge
67
68   if ((lmc.enable == 0) && ((lmc.clock == 0) && (level == 1)))
69   {
70      lmc.si >>= 1;
71      lmc.si = lmc.si & 0x7fff;
72
73      if (lmc.data)
74      {
75         lmc.si &= 0x8000;
76      }
77   }
78
79   lmc.clock = level;
80}
81
82void lmc1992_data_w(int level)
83{
84   lmc.data = level;
85}
86
87void lmc1992_enable_w(int level)
88{
89   if ((lmc.enable == 0) && (level == 1))
90   {
91      UINT8 device = (lmc.si & 0xc000) >> 14;
92      UINT8 addr = (lmc.si & 0x3800) >> 11;
93      UINT8 data = (lmc.si & 0x07e0) >> 5;
94
95      if (device == LMC1992_MICROWIRE_DEVICE_ADDRESS)
96      {
97         lmc1992_command_w(addr, data);
98      }
99   }
100
101   lmc.enable = level;
102}
103
104void lmc1992_config(const lmc1992_interface *intf)
105{
106   memset(&lmc, 0, sizeof(lmc));
107
108   lmc.intf = intf;
109
110   state_save_register_global(lmc.enable);
111   state_save_register_global(lmc.data);
112   state_save_register_global(lmc.clock);
113   state_save_register_global(lmc.si);
114   state_save_register_global(lmc.input);
115   state_save_register_global(lmc.bass);
116   state_save_register_global(lmc.treble);
117   state_save_register_global(lmc.volume);
118   state_save_register_global(lmc.fader_rf);
119   state_save_register_global(lmc.fader_lf);
120   state_save_register_global(lmc.fader_rr);
121   state_save_register_global(lmc.fader_lr);
122}
src/mess/audio/lmc1992.h
r882r883
1/*
2 
3            LMC1992 Digitally-Controlled Stereo Tone and Volume
4               Circuit with Four-Channel Input-Selector
5 
6                        ________________
7              Data    1   ---|      \/      |---  28  V+
8              Clock    2   ---|            |---  27  Bypass
9             Enable    3   ---|            |---  26  Right Input 1
10        Left Input 1    4   ---|            |---  25  Right Input 2
11        Left Input 2    5   ---|            |---  24  Right Input 3
12        Left Input 3    6   ---|              |---  23  Right Input 4
13        Left Input 4    7   ---|   LMC1992    |---  22  Right Select Out
14      Left Select Out    8   ---|   top view   |---  21  Right Select In
15      Left Select In    9   ---|            |---  20  Right Tone In
16        Left Tone In   10   ---|             |---  19  Right Tone Out
17       Left Tone Out   11   ---|            |---  18  Right Op Amp Out
18      Left Op Amp Out   12   ---|            |---  17  Right Rear Out
19       Left Rear Out   13  ---|            |---  16  Right Front Out
20      Left Front Out   14   ---|________________|---  15  Ground
21 
22*/
23 
24#ifndef __LMC1992_AUDIO__
25#define __LMC1992_AUDIO__
26 
27#include "driver.h"
28 
29typedef struct
30{
31   int dummy;
32   // left input 1
33   // left input 2
34   // left input 3
35   // left input 4
36   // right input 1
37   // right input 2
38   // right input 3
39   // right input 4
40} lmc1992_interface;
41 
42enum
43{
44   LMC1992_FUNCTION_INPUT_SELECT = 0,
45   LMC1992_FUNCTION_BASS,
46   LMC1992_FUNCTION_TREBLE,
47   LMC1992_FUNCTION_VOLUME,
48   LMC1992_FUNCTION_RIGHT_FRONT_FADER,
49   LMC1992_FUNCTION_LEFT_FRONT_FADER,
50   LMC1992_FUNCTION_RIGHT_REAR_FADER,
51   LMC1992_FUNCTION_LEFT_REAR_FADER
52};
53 
54enum
55{
56   LCM1992_INPUT_SELECT_OPEN = 0,
57   LCM1992_INPUT_SELECT_INPUT1,
58   LCM1992_INPUT_SELECT_INPUT2,
59   LCM1992_INPUT_SELECT_INPUT3,
60   LCM1992_INPUT_SELECT_INPUT4
61};
62 
63#define LMC1992_MICROWIRE_DEVICE_ADDRESS   2
64 
65void lmc1992_clock_w(int level);
66void lmc1992_data_w(int level);
67void lmc1992_enable_w(int level);
68 
69void lmc1992_config(const lmc1992_interface *intf);
70 
71#endif
1/*
2
3            LMC1992 Digitally-Controlled Stereo Tone and Volume
4               Circuit with Four-Channel Input-Selector
5
6                        ________________
7              Data    1   ---|      \/      |---  28  V+
8              Clock    2   ---|            |---  27  Bypass
9             Enable    3   ---|            |---  26  Right Input 1
10        Left Input 1    4   ---|            |---  25  Right Input 2
11        Left Input 2    5   ---|            |---  24  Right Input 3
12        Left Input 3    6   ---|              |---  23  Right Input 4
13        Left Input 4    7   ---|   LMC1992    |---  22  Right Select Out
14      Left Select Out    8   ---|   top view   |---  21  Right Select In
15      Left Select In    9   ---|            |---  20  Right Tone In
16        Left Tone In   10   ---|             |---  19  Right Tone Out
17       Left Tone Out   11   ---|            |---  18  Right Op Amp Out
18      Left Op Amp Out   12   ---|            |---  17  Right Rear Out
19       Left Rear Out   13  ---|            |---  16  Right Front Out
20      Left Front Out   14   ---|________________|---  15  Ground
21
22*/
23
24#ifndef __LMC1992_AUDIO__
25#define __LMC1992_AUDIO__
26
27#include "driver.h"
28
29typedef struct
30{
31   int dummy;
32   // left input 1
33   // left input 2
34   // left input 3
35   // left input 4
36   // right input 1
37   // right input 2
38   // right input 3
39   // right input 4
40} lmc1992_interface;
41
42enum
43{
44   LMC1992_FUNCTION_INPUT_SELECT = 0,
45   LMC1992_FUNCTION_BASS,
46   LMC1992_FUNCTION_TREBLE,
47   LMC1992_FUNCTION_VOLUME,
48   LMC1992_FUNCTION_RIGHT_FRONT_FADER,
49   LMC1992_FUNCTION_LEFT_FRONT_FADER,
50   LMC1992_FUNCTION_RIGHT_REAR_FADER,
51   LMC1992_FUNCTION_LEFT_REAR_FADER
52};
53
54enum
55{
56   LCM1992_INPUT_SELECT_OPEN = 0,
57   LCM1992_INPUT_SELECT_INPUT1,
58   LCM1992_INPUT_SELECT_INPUT2,
59   LCM1992_INPUT_SELECT_INPUT3,
60   LCM1992_INPUT_SELECT_INPUT4
61};
62
63#define LMC1992_MICROWIRE_DEVICE_ADDRESS   2
64
65void lmc1992_clock_w(int level);
66void lmc1992_data_w(int level);
67void lmc1992_enable_w(int level);
68
69void lmc1992_config(const lmc1992_interface *intf);
70
71#endif
src/mess/includes/cybiko.h
r882r883
1/*
2 
3   Cybiko Wireless Inter-tainment System
4 
5   (c) 2001-2007 Tim Schuerewegen
6 
7   Cybiko Classic (V1)
8   Cybiko Classic (V2)
9   Cybiko Xtreme
10 
11*/
12 
13#ifndef _CYBIKO_H_
14#define _CYBIKO_H_
15 
16#include "driver.h"
17 
18// driver init
19DRIVER_INIT( cybikov1 );
20DRIVER_INIT( cybikov2 );
21DRIVER_INIT( cybikoxt );
22 
23// non-volatile ram handler
24/*
25NVRAM_HANDLER( cybikov1 );
26NVRAM_HANDLER( cybikov2 );
27NVRAM_HANDLER( cybikoxt );
28*/
29 
30// machine start
31MACHINE_START( cybikov1 );
32MACHINE_START( cybikov2 );
33MACHINE_START( cybikoxt );
34 
35// machine reset
36MACHINE_RESET( cybikov1 );
37MACHINE_RESET( cybikov2 );
38MACHINE_RESET( cybikoxt );
39 
40// lcd read/write
41READ16_HANDLER( cybiko_lcd_r );
42WRITE16_HANDLER( cybiko_lcd_w );
43 
44// key read
45READ16_HANDLER( cybiko_key_r );
46 
47// unknown
48WRITE16_HANDLER( cybiko_unk1_w );
49READ16_HANDLER( cybiko_unk2_r );
50 
51// onchip registers read/write
52READ8_HANDLER( cybikov1_io_reg_r );
53READ8_HANDLER( cybikov2_io_reg_r );
54READ8_HANDLER( cybikoxt_io_reg_r );
55WRITE8_HANDLER( cybikov1_io_reg_w );
56WRITE8_HANDLER( cybikov2_io_reg_w );
57WRITE8_HANDLER( cybikoxt_io_reg_w );
58 
59#endif
1/*
2
3   Cybiko Wireless Inter-tainment System
4
5   (c) 2001-2007 Tim Schuerewegen
6
7   Cybiko Classic (V1)
8   Cybiko Classic (V2)
9   Cybiko Xtreme
10
11*/
12
13#ifndef _CYBIKO_H_
14#define _CYBIKO_H_
15
16#include "driver.h"
17
18// driver init
19DRIVER_INIT( cybikov1 );
20DRIVER_INIT( cybikov2 );
21DRIVER_INIT( cybikoxt );
22
23// non-volatile ram handler
24/*
25NVRAM_HANDLER( cybikov1 );
26NVRAM_HANDLER( cybikov2 );
27NVRAM_HANDLER( cybikoxt );
28*/
29
30// machine start
31MACHINE_START( cybikov1 );
32MACHINE_START( cybikov2 );
33MACHINE_START( cybikoxt );
34
35// machine reset
36MACHINE_RESET( cybikov1 );
37MACHINE_RESET( cybikov2 );
38MACHINE_RESET( cybikoxt );
39
40// lcd read/write
41READ16_HANDLER( cybiko_lcd_r );
42WRITE16_HANDLER( cybiko_lcd_w );
43
44// key read
45READ16_HANDLER( cybiko_key_r );
46
47// unknown
48WRITE16_HANDLER( cybiko_unk1_w );
49READ16_HANDLER( cybiko_unk2_r );
50
51// onchip registers read/write
52READ8_HANDLER( cybikov1_io_reg_r );
53READ8_HANDLER( cybikov2_io_reg_r );
54READ8_HANDLER( cybikoxt_io_reg_r );
55WRITE8_HANDLER( cybikov1_io_reg_w );
56WRITE8_HANDLER( cybikov2_io_reg_w );
57WRITE8_HANDLER( cybikoxt_io_reg_w );
58
59#endif
src/mess/video/hd66421.c
r882r883
1/*
2 
3   Hitachi HD66421 LCD Controller/Driver
4 
5   (c) 2001-2007 Tim Schuerewegen
6 
7*/
8 
9#include "hd66421.h"
10 
11#define LOG_LEVEL  1
12#define _logerror(level,...)  if (LOG_LEVEL > level) logerror(__VA_ARGS__)
13 
14//#define BRIGHTNESS_DOES_NOT_WORK
15 
16#define HD66421_RAM_SIZE  (HD66421_WIDTH * HD66421_HEIGHT / 4) // 2-bits per pixel
17 
18// R0 - control register 1
19#define LCD_R0_RMW      0x80 // read-modify-write mode
20#define LCD_R0_DISP     0x40 // display on/off
21#define LCD_R0_STBY     0x20 // standby (internal operation and power circuit halt)
22#define LCD_R0_PWR      0x10
23#define LCD_R0_AMP      0x08
24#define LCD_R0_REV      0x04 // reverse
25#define LCD_R0_HOLT     0x02
26#define LCD_R0_ADC      0x01
27 
28// R1 - control register 2
29#define LCD_R1_BIS1     0x80 // bias ratio (bit 1)
30#define LCD_R1_BIS0     0x40 // bias ratio (bit 0)
31#define LCD_R1_WLS      0x20
32#define LCD_R1_GRAY     0x10 // grayscale palette 4/32
33#define LCD_R1_DTY1     0x08 // display duty cycle (bit 1)
34#define LCD_R1_DTY0     0x04 // display duty cycle (bit 0)
35#define LCD_R1_INC      0x02
36#define LCD_R1_BLK      0x01 // blink function
37 
38// register 0 to 16
39#define LCD_REG_CONTROL_1   0x00 // control register 1
40#define LCD_REG_CONTROL_2   0x01 // control register 2
41#define LCD_REG_ADDR_X      0x02 // x address register
42#define LCD_REG_ADDR_Y      0x03 // y address register
43#define LCD_REG_RAM         0x04 // display ram access register
44#define LCD_REG_START_Y     0x05 // display start line register
45#define LCD_REG_BLINK_START 0x06 // blink start line register
46#define LCD_REG_BLINK_END   0x07 // blink end line register
47#define LCD_REG_BLINK_1     0x08 // blink register 1
48#define LCD_REG_BLINK_2     0x09 // blink register 2
49#define LCD_REG_BLINK_3     0x0A // blink register 3
50#define LCD_REG_PARTIAL     0x0B // partial display block register
51#define LCD_REG_COLOR_1     0x0C // gray scale palette 1 (0,0)
52#define LCD_REG_COLOR_2     0x0D // gray scale palette 2 (0,1)
53#define LCD_REG_COLOR_3     0x0E // gray scale palette 3 (1,0)
54#define LCD_REG_COLOR_4     0x0F // gray scale palette 4 (1,1)
55#define LCD_REG_CONTRAST    0x10 // contrast control register
56#define LCD_REG_PLANE       0x11 // plane selection register
57 
58typedef struct
59{
60   UINT8 idx, dat[32]; // index and data registers
61   UINT8 *ram;         // display ram
62   UINT32 pos;         // current position in ram
63} HD66421;
64 
65static HD66421 lcd;
66 
67UINT8 hd66421_reg_idx_r( void)
68{
69   _logerror( 2, "hd66421_reg_idx_r\n");
70   return lcd.idx;
71}
72 
73void hd66421_reg_idx_w( UINT8 data)
74{
75   _logerror( 2, "hd66421_reg_idx_w (%02X)\n", data);
76   lcd.idx = data;
77}
78 
79UINT8 hd66421_reg_dat_r( void)
80{
81   _logerror( 2, "hd66421_reg_dat_r\n");
82   return lcd.dat[lcd.idx];
83}
84 
85void hd66421_reg_dat_w( UINT8 data)
86{
87   _logerror( 2, "hd66421_reg_dat_w (%02X)\n", data);
88   lcd.dat[lcd.idx] = data;
89   switch (lcd.idx)
90   {
91      case LCD_REG_ADDR_Y : lcd.pos = data * HD66421_WIDTH / 4; break;
92      case LCD_REG_RAM    : lcd.ram[lcd.pos++] = data; break;
93   }
94}
95 
96INLINE void hd66421_plot_pixel( bitmap_t *bitmap, int x, int y, UINT32 color)
97{
98   *BITMAP_ADDR16( bitmap, y, x) = (UINT16)color;
99}
100 
101PALETTE_INIT( hd66421 )
102{
103   int i;
104   _logerror( 0, "palette_init_hd66421\n");
105   // init palette
106   for (i=0;i<4;i++)
107   {
108      palette_set_color( machine, i, RGB_WHITE);
109      #ifndef BRIGHTNESS_DOES_NOT_WORK
110      palette_set_brightness( machine, i, 1.0 * i / (4 - 1));
111      #endif
112      colortable[i] = i;
113   }
114}
115 
116void hd66421_state_save( void)
117{
118   const char *name = "hd66421";
119   state_save_register_item( name, 0, lcd.idx);
120   state_save_register_item_array( name, 0, lcd.dat);
121   state_save_register_item( name, 0, lcd.pos);
122   state_save_register_item_pointer( name, 0, lcd.ram, HD66421_RAM_SIZE);
123}
124 
125VIDEO_START( hd66421 )
126{
127   _logerror( 0, "video_start_hd66421\n");
128   memset( &lcd, 0, sizeof( lcd));
129   lcd.ram = auto_malloc( HD66421_RAM_SIZE);
130   hd66421_state_save();
131}
132 
133VIDEO_UPDATE( hd66421 )
134{
135   pen_t pen[4];
136   int i;
137   _logerror( 1, "video_update_hd66421\n");
138   // update palette
139   for (i=0;i<4;i++)
140   {
141      double bright;
142      int temp;
143      temp = 31 - (lcd.dat[LCD_REG_COLOR_1+i] - lcd.dat[LCD_REG_CONTRAST] + 0x03);
144      if (temp <  0) temp =  0;
145      if (temp > 31) temp = 31;
146      bright = 1.0 * temp / 31;
147      pen[i] = Machine->pens[i];
148      #ifdef BRIGHTNESS_DOES_NOT_WORK
149      palette_set_color( machine, pen[i], 255 * bright, 255 * bright, 255 * bright);
150      #else
151      palette_set_brightness( machine, pen[i], bright);
152      #endif
153   }
154   // draw bitmap (bottom to top)
155   if (lcd.dat[0] & LCD_R0_DISP)
156   {
157      int x, y;
158      x = 0;
159      y = HD66421_HEIGHT - 1;
160      for (i=0;i<HD66421_RAM_SIZE;i++)
161      {
162         hd66421_plot_pixel( bitmap, x++, y, pen[(lcd.ram[i] >> 6) & 3]);
163         hd66421_plot_pixel( bitmap, x++, y, pen[(lcd.ram[i] >> 4) & 3]);
164         hd66421_plot_pixel( bitmap, x++, y, pen[(lcd.ram[i] >> 2) & 3]);
165         hd66421_plot_pixel( bitmap, x++, y, pen[(lcd.ram[i] >> 0) & 3]);
166         if (x >= HD66421_WIDTH)
167         {
168            x = 0;
169            y = y - 1;
170         }
171      }
172   }
173   else
174   {
175      rectangle rect;
176      rect.min_x = 0;
177      rect.max_x = HD66421_WIDTH - 1;
178      rect.min_y = 0;
179      rect.max_y = HD66421_HEIGHT - 1;
180      fillbitmap( bitmap, get_white_pen( machine), &rect);
181   }
182   // flags
183   return 0;
184}
1/*
2
3   Hitachi HD66421 LCD Controller/Driver
4
5   (c) 2001-2007 Tim Schuerewegen
6
7*/
8
9#include "hd66421.h"
10
11#define LOG_LEVEL  1
12#define _logerror(level,...)  if (LOG_LEVEL > level) logerror(__VA_ARGS__)
13
14//#define BRIGHTNESS_DOES_NOT_WORK
15
16#define HD66421_RAM_SIZE  (HD66421_WIDTH * HD66421_HEIGHT / 4) // 2-bits per pixel
17
18// R0 - control register 1
19#define LCD_R0_RMW      0x80 // read-modify-write mode
20#define LCD_R0_DISP     0x40 // display on/off
21#define LCD_R0_STBY     0x20 // standby (internal operation and power circuit halt)
22#define LCD_R0_PWR      0x10
23#define LCD_R0_AMP      0x08
24#define LCD_R0_REV      0x04 // reverse
25#define LCD_R0_HOLT     0x02
26#define LCD_R0_ADC      0x01
27
28// R1 - control register 2
29#define LCD_R1_BIS1     0x80 // bias ratio (bit 1)
30#define LCD_R1_BIS0     0x40 // bias ratio (bit 0)
31#define LCD_R1_WLS      0x20
32#define LCD_R1_GRAY     0x10 // grayscale palette 4/32
33#define LCD_R1_DTY1     0x08 // display duty cycle (bit 1)
34#define LCD_R1_DTY0     0x04 // display duty cycle (bit 0)
35#define LCD_R1_INC      0x02
36#define LCD_R1_BLK      0x01 // blink function
37
38// register 0 to 16
39#define LCD_REG_CONTROL_1   0x00 // control register 1
40#define LCD_REG_CONTROL_2   0x01 // control register 2
41#define LCD_REG_ADDR_X      0x02 // x address register
42#define LCD_REG_ADDR_Y      0x03 // y address register
43#define LCD_REG_RAM         0x04 // display ram access register
44#define LCD_REG_START_Y     0x05 // display start line register
45#define LCD_REG_BLINK_START 0x06 // blink start line register
46#define LCD_REG_BLINK_END   0x07 // blink end line register
47#define LCD_REG_BLINK_1     0x08 // blink register 1
48#define LCD_REG_BLINK_2     0x09 // blink register 2
49#define LCD_REG_BLINK_3     0x0A // blink register 3
50#define LCD_REG_PARTIAL     0x0B // partial display block register
51#define LCD_REG_COLOR_1     0x0C // gray scale palette 1 (0,0)
52#define LCD_REG_COLOR_2     0x0D // gray scale palette 2 (0,1)
53#define LCD_REG_COLOR_3     0x0E // gray scale palette 3 (1,0)
54#define LCD_REG_COLOR_4     0x0F // gray scale palette 4 (1,1)
55#define LCD_REG_CONTRAST    0x10 // contrast control register
56#define LCD_REG_PLANE       0x11 // plane selection register
57
58typedef struct
59{
60   UINT8 idx, dat[32]; // index and data registers
61   UINT8 *ram;         // display ram
62   UINT32 pos;         // current position in ram
63} HD66421;
64
65static HD66421 lcd;
66
67UINT8 hd66421_reg_idx_r( void)
68{
69   _logerror( 2, "hd66421_reg_idx_r\n");
70   return lcd.idx;
71}
72
73void hd66421_reg_idx_w( UINT8 data)
74{
75   _logerror( 2, "hd66421_reg_idx_w (%02X)\n", data);
76   lcd.idx = data;
77}
78
79UINT8 hd66421_reg_dat_r( void)
80{
81   _logerror( 2, "hd66421_reg_dat_r\n");
82   return lcd.dat[lcd.idx];
83}
84
85void hd66421_reg_dat_w( UINT8 data)
86{
87   _logerror( 2, "hd66421_reg_dat_w (%02X)\n", data);
88   lcd.dat[lcd.idx] = data;
89   switch (lcd.idx)
90   {
91      case LCD_REG_ADDR_Y : lcd.pos = data * HD66421_WIDTH / 4; break;
92      case LCD_REG_RAM    : lcd.ram[lcd.pos++] = data; break;
93   }
94}
95
96INLINE void hd66421_plot_pixel( bitmap_t *bitmap, int x, int y, UINT32 color)
97{
98   *BITMAP_ADDR16( bitmap, y, x) = (UINT16)color;
99}
100
101PALETTE_INIT( hd66421 )
102{
103   int i;
104   _logerror( 0, "palette_init_hd66421\n");
105   // init palette
106   for (i=0;i<4;i++)
107   {
108      palette_set_color( machine, i, RGB_WHITE);
109      #ifndef BRIGHTNESS_DOES_NOT_WORK
110      palette_set_brightness( machine, i, 1.0 * i / (4 - 1));
111      #endif
112      colortable[i] = i;
113   }
114}
115
116void hd66421_state_save( void)
117{
118   const char *name = "hd66421";
119   state_save_register_item( name, 0, lcd.idx);
120   state_save_register_item_array( name, 0, lcd.dat);
121   state_save_register_item( name, 0, lcd.pos);
122   state_save_register_item_pointer( name, 0, lcd.ram, HD66421_RAM_SIZE);
123}
124
125VIDEO_START( hd66421 )
126{
127   _logerror( 0, "video_start_hd66421\n");
128   memset( &lcd, 0, sizeof( lcd));
129   lcd.ram = auto_malloc( HD66421_RAM_SIZE);
130   hd66421_state_save();
131}
132
133VIDEO_UPDATE( hd66421 )
134{
135   pen_t pen[4];
136   int i;
137   _logerror( 1, "video_update_hd66421\n");
138   // update palette
139   for (i=0;i<4;i++)
140   {
141      double bright;
142      int temp;
143      temp = 31 - (lcd.dat[LCD_REG_COLOR_1+i] - lcd.dat[LCD_REG_CONTRAST] + 0x03);
144      if (temp <  0) temp =  0;
145      if (temp > 31) temp = 31;
146      bright = 1.0 * temp / 31;
147      pen[i] = Machine->pens[i];
148      #ifdef BRIGHTNESS_DOES_NOT_WORK
149      palette_set_color( machine, pen[i], 255 * bright, 255 * bright, 255 * bright);
150      #else
151      palette_set_brightness( machine, pen[i], bright);
152      #endif
153   }
154   // draw bitmap (bottom to top)
155   if (lcd.dat[0] & LCD_R0_DISP)
156   {
157      int x, y;
158      x = 0;
159      y = HD66421_HEIGHT - 1;
160      for (i=0;i<HD66421_RAM_SIZE;i++)
161      {
162         hd66421_plot_pixel( bitmap, x++, y, pen[(lcd.ram[i] >> 6) & 3]);
163         hd66421_plot_pixel( bitmap, x++, y, pen[(lcd.ram[i] >> 4) & 3]);
164         hd66421_plot_pixel( bitmap, x++, y, pen[(lcd.ram[i] >> 2) & 3]);
165         hd66421_plot_pixel( bitmap, x++, y, pen[(lcd.ram[i] >> 0) & 3]);
166         if (x >= HD66421_WIDTH)
167         {
168            x = 0;
169            y = y - 1;
170         }
171      }
172   }
173   else
174   {
175      rectangle rect;
176      rect.min_x = 0;
177      rect.max_x = HD66421_WIDTH - 1;
178      rect.min_y = 0;
179      rect.max_y = HD66421_HEIGHT - 1;
180      fillbitmap( bitmap, get_white_pen( machine), &rect);
181   }
182   // flags
183   return 0;
184}
src/mess/video/hd66421.h
r882r883
1/*
2 
3   Hitachi HD66421 LCD Controller/Driver
4 
5   (c) 2001-2007 Tim Schuerewegen
6 
7*/
8 
9#ifndef _HD66421_H_
10#define _HD66421_H_
11 
12#include "driver.h"
13 
14#define HD66421_WIDTH   160
15#define HD66421_HEIGHT  100
16 
17UINT8 hd66421_reg_idx_r( void);
18void hd66421_reg_idx_w( UINT8 data);
19 
20UINT8 hd66421_reg_dat_r( void);
21void hd66421_reg_dat_w( UINT8 data);
22 
23PALETTE_INIT( hd66421 );
24 
25VIDEO_START( hd66421 );
26VIDEO_UPDATE( hd66421 );
27 
28#endif
1/*
2
3   Hitachi HD66421 LCD Controller/Driver
4
5   (c) 2001-2007 Tim Schuerewegen
6
7*/
8
9#ifndef _HD66421_H_
10#define _HD66421_H_
11
12#include "driver.h"
13
14#define HD66421_WIDTH   160
15#define HD66421_HEIGHT  100
16
17UINT8 hd66421_reg_idx_r( void);
18void hd66421_reg_idx_w( UINT8 data);
19
20UINT8 hd66421_reg_dat_r( void);
21void hd66421_reg_dat_w( UINT8 data);
22
23PALETTE_INIT( hd66421 );
24
25VIDEO_START( hd66421 );
26VIDEO_UPDATE( hd66421 );
27
28#endif
src/mess/machine/pcf8593.c
r882r883
1/*
2 
3   Philips PCF8593 CMOS clock/calendar circuit
4 
5   (c) 2001-2007 Tim Schuerewegen
6 
7*/
8 
9#include "pcf8593.h"
10 
11#include <time.h>
12 
13#define LOG_LEVEL  1
14#define _logerror(level,...)  if (LOG_LEVEL > level) logerror(__VA_ARGS__)
15 
16#define RTC_MODE_NONE  0
17#define RTC_MODE_SEND  1
18#define RTC_MODE_RECV  2
19 
20// get/set date
21#define RTC_GET_DATE_YEAR       ((rtc.data[5] >> 6) & 3)
22#define RTC_SET_DATE_YEAR(x)    rtc.data[5] = (rtc.data[5] & 0x3F) | (((x) % 4) << 6)
23#define RTC_GET_DATE_MONTH      bcd_to_dec( rtc.data[6])
24#define RTC_SET_DATE_MONTH(x)   rtc.data[6] = dec_to_bcd( x)
25#define RTC_GET_DATE_DAY        (bcd_to_dec( rtc.data[5] & 0x3F))
26#define RTC_SET_DATE_DAY(x)     rtc.data[5] = (rtc.data[5] & 0xC0) | dec_to_bcd( x)
27 
28// get/set time
29#define RTC_GET_TIME_HOUR       bcd_to_dec( rtc.data[4])
30#define RTC_SET_TIME_HOUR(x)    rtc.data[4] = dec_to_bcd( x)
31#define RTC_GET_TIME_MINUTE     bcd_to_dec( rtc.data[3])
32#define RTC_SET_TIME_MINUTE(x)  rtc.data[3] = dec_to_bcd( x)
33#define RTC_GET_TIME_SECOND     bcd_to_dec( rtc.data[2])
34#define RTC_SET_TIME_SECOND(x)  rtc.data[2] = dec_to_bcd( x)
35 
36static void pcf8593_clear_buffer_rx( void);
37static TIMER_CALLBACK( pcf8593_timer_callback );
38 
39typedef struct
40{
41   UINT8 *data;
42   UINT32 size;
43   int pin_scl, pin_sda, inp;
44   bool active;
45   int bits;
46   UINT8 data_recv_index, data_recv[50];
47   UINT8 mode, pos;
48   mame_timer *timer;
49} PCF8593;
50 
51static PCF8593 rtc;
52 
53void pcf8593_init( void)
54{
55   _logerror( 0, "pcf8593_init\n");
56   memset( &rtc, 0, sizeof( rtc));
57   rtc.size = 16;
58   rtc.data = malloc( rtc.size);
59   rtc.timer = mame_timer_alloc( pcf8593_timer_callback );
60   mame_timer_adjust( rtc.timer, MAME_TIME_IN_SEC(1), 0, MAME_TIME_IN_SEC(1));
61   pcf8593_reset();
62}
63 
64void pcf8593_exit( void)
65{
66   _logerror( 0, "pcf8593_exit\n");
67   free( rtc.data);
68}
69 
70void pcf8593_reset( void)
71{
72   _logerror( 0, "pcf8593_reset\n");
73   rtc.pin_scl = 1;
74   rtc.pin_sda = 1;
75   rtc.active  = FALSE;
76   rtc.inp     = 0;
77   rtc.mode    = RTC_MODE_RECV;
78   rtc.bits    = 0;
79   pcf8593_clear_buffer_rx();
80   rtc.pos     = 0;
81}
82 
83void pcf8593_pin_scl( int data)
84{
85   // send bit
86   if ((rtc.active) && (!rtc.pin_scl) && (data))
87   {
88      switch (rtc.mode)
89      {
90         // HOST -> RTC
91         case RTC_MODE_RECV :
92         {
93            // get bit
94             if (rtc.pin_sda) rtc.data_recv[rtc.data_recv_index] = rtc.data_recv[rtc.data_recv_index] | (0x80 >> rtc.bits);
95            rtc.bits++;
96            // bit 9 = end
97            if (rtc.bits > 8)
98            {
99               _logerror( 2, "pcf8593_write_byte(%02X)\n", rtc.data_recv[rtc.data_recv_index]);
100               // enter receive mode when 1st byte = 0xA3
101               if ((rtc.data_recv[0] == 0xA3) && (rtc.data_recv_index == 0))
102               {
103                    rtc.mode = RTC_MODE_SEND;
104               }
105               // A2 + xx = "read from pos xx" command
106               if ((rtc.data_recv[0] == 0xA2) && (rtc.data_recv_index == 1))
107               {
108                  rtc.pos = rtc.data_recv[1];
109               }
110               // A2 + xx + .. = write byte
111               if ((rtc.data_recv[0] == 0xA2) && (rtc.data_recv_index >= 2))
112               {
113                  UINT8 rtc_pos, rtc_val;
114                  rtc_pos = rtc.data_recv[1] + (rtc.data_recv_index - 2);
115                  rtc_val = rtc.data_recv[rtc.data_recv_index];
116                  //if (rtc_pos == 0) rtc_val = rtc_val & 3; // what is this doing here?
117                  rtc.data[rtc_pos] = rtc_val;
118               }
119               // next byte
120               rtc.bits = 0;
121                 rtc.data_recv_index++;
122            }
123         }
124         break;
125         // RTC -> HOST
126         case RTC_MODE_SEND :
127         {
128            // set bit
129            rtc.inp = (rtc.data[rtc.pos] >> (7 - rtc.bits)) & 1;
130            rtc.bits++;
131            // bit 9 = end
132            if (rtc.bits > 8)
133            {
134               _logerror( 2, "pcf8593_read_byte(%02X)\n", rtc.data[rtc.pos]);
135               // end ?
136                 if (rtc.pin_sda)
137               {
138                  _logerror( 2, "pcf8593 end\n");
139                    rtc.mode = RTC_MODE_RECV;
140                       pcf8593_clear_buffer_rx();
141               }
142               // next byte
143               rtc.bits = 0;
144               rtc.pos++;
145            }
146         }
147         break;
148      }
149   }
150   // save scl
151   rtc.pin_scl = data;
152}
153 
154void pcf8593_pin_sda_w( int data)
155{
156   // clock is high
157   if (rtc.pin_scl)
158   {
159      // log init I2C
160      if (data) _logerror( 1, "pcf8593 init i2c\n");
161      // start condition (high to low when clock is high)
162      if ((!data) && (rtc.pin_sda))
163      {
164         _logerror( 1, "pcf8593 start condition\n");
165         rtc.active          = TRUE;
166         rtc.bits            = 0;
167         rtc.data_recv_index = 0;
168         pcf8593_clear_buffer_rx();
169         //rtc.pos = 0;
170      }
171      // stop condition (low to high when clock is high)
172      if ((data) && (!rtc.pin_sda))
173      {
174         _logerror( 1, "pcf8593 stop condition\n");
175         rtc.active = FALSE;
176      }
177   }
178   // save sda
179   rtc.pin_sda = data;
180}
181 
182int pcf8593_pin_sda_r( void)
183{
184   return rtc.inp;
185}
186 
187void pcf8593_clear_buffer_rx( void)
188{
189   memset( &rtc.data_recv[0], 0, sizeof( rtc.data_recv));
190   rtc.data_recv_index = 0;
191}
192 
193static UINT8 dec_to_bcd( UINT8 data)
194{
195   return ((data / 10) << 4) | ((data % 10) << 0);
196}
197 
198static UINT8 bcd_to_dec( UINT8 data)
199{
200   if ((data & 0x0F) >= 0x0A) data = data - 0x0A + 0x10;
201   if ((data & 0xF0) >= 0xA0) data = data - 0xA0;
202   return (data & 0x0F) + (((data & 0xF0) >> 4) * 10);
203}
204 
205void pcf8593_set_time( int hour, int minute, int second)
206{
207   RTC_SET_TIME_HOUR( hour);
208   RTC_SET_TIME_MINUTE( minute);
209   RTC_SET_TIME_SECOND( second);
210   rtc.data[1] = 0; // hundreds of a seconds
211}
212 
213void pcf8593_set_date( int year, int month, int day)
214{
215   RTC_SET_DATE_YEAR( year);
216   RTC_SET_DATE_MONTH( month);
217   RTC_SET_DATE_DAY( day);
218}
219 
220static int get_days_in_month( int year, int month)
221{
222   static const int table[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
223   if ((month == 2) && ((year & 0x03) == 0)) return 29;
224   return table[month-1];
225}
226 
227static TIMER_CALLBACK( pcf8593_timer_callback )
228{
229   int value;
230   _logerror( 2, "pcf8593_timer_callback (%d)\n", param);
231   // check if counting is enabled
232   if (rtc.data[0] & 0x80) return;
233   // increment second
234   value = RTC_GET_TIME_SECOND;
235   if (value < 59)
236   {
237      RTC_SET_TIME_SECOND( value + 1);
238   }
239   else
240   {
241      RTC_SET_TIME_SECOND( 0);
242      // increment minute
243      value = RTC_GET_TIME_MINUTE;
244      if (value < 59)
245      {
246         RTC_SET_TIME_MINUTE( value + 1);
247      }
248      else
249      {
250         RTC_SET_TIME_MINUTE( 0);
251         // increment hour
252         value = RTC_GET_TIME_HOUR;
253         if (value < 23)
254         {
255            RTC_SET_TIME_HOUR( value + 1);
256         }
257         else
258         {
259            RTC_SET_TIME_HOUR( 0);
260            // increment day
261            value = RTC_GET_DATE_DAY;
262            if (value < get_days_in_month( RTC_GET_DATE_YEAR, RTC_GET_DATE_MONTH))
263            {
264               RTC_SET_DATE_DAY( value + 1);
265            }
266            else
267            {
268               RTC_SET_DATE_DAY( 1);
269               // increase month
270               value = RTC_GET_DATE_MONTH;
271               if (value < 12)
272               {
273                  RTC_SET_DATE_MONTH( value + 1);
274               }
275               else
276               {
277                  RTC_SET_DATE_MONTH( 1);
278                  // increase year
279                  RTC_SET_DATE_YEAR( RTC_GET_DATE_YEAR + 1);
280               }
281            }
282         }
283      }
284   }
285}
286 
287void pcf8593_load( mame_file *file)
288{
289   mame_system_time systime;
290   _logerror( 0, "pcf8593_load (%p)\n", file);
291   mame_fread( file, rtc.data, rtc.size);
292   mame_get_current_datetime( Machine, &systime);
293   pcf8593_set_date( systime.local_time.year, systime.local_time.month + 1, systime.local_time.mday);
294   pcf8593_set_time( systime.local_time.hour, systime.local_time.minute, systime.local_time.second);
295}
296 
297void pcf8593_save( mame_file *file)
298{
299   _logerror( 0, "pcf8593_save (%p)\n", file);
300   mame_fwrite( file, rtc.data, rtc.size);
301}
302 
303/*
304NVRAM_HANDLER( pcf8593 )
305{
306   _logerror( 0, "nvram_handler_pcf8593 (%p/%d)\n", file, read_or_write);
307   if (read_or_write)
308   {
309      pcf8593_save( file);
310   }
311   else
312   {
313      if (file)
314      {
315         pcf8593_load( file);
316      }
317      else
318      {
319         memset( rtc.data, 0, rtc.size);
320      }
321   }
322}
323*/
1/*
2
3   Philips PCF8593 CMOS clock/calendar circuit
4
5   (c) 2001-2007 Tim Schuerewegen
6
7*/
8
9#include "pcf8593.h"
10
11#include <time.h>
12
13#define LOG_LEVEL  1
14#define _logerror(level,...)  if (LOG_LEVEL > level) logerror(__VA_ARGS__)
15
16#define RTC_MODE_NONE  0
17#define RTC_MODE_SEND  1
18#define RTC_MODE_RECV  2
19
20// get/set date
21#define RTC_GET_DATE_YEAR       ((rtc.data[5] >> 6) & 3)
22#define RTC_SET_DATE_YEAR(x)    rtc.data[5] = (rtc.data[5] & 0x3F) | (((x) % 4) << 6)
23#define RTC_GET_DATE_MONTH      bcd_to_dec( rtc.data[6])
24#define RTC_SET_DATE_MONTH(x)   rtc.data[6] = dec_to_bcd( x)
25#define RTC_GET_DATE_DAY        (bcd_to_dec( rtc.data[5] & 0x3F))
26#define RTC_SET_DATE_DAY(x)     rtc.data[5] = (rtc.data[5] & 0xC0) | dec_to_bcd( x)
27
28// get/set time
29#define RTC_GET_TIME_HOUR       bcd_to_dec( rtc.data[4])
30#define RTC_SET_TIME_HOUR(x)    rtc.data[4] = dec_to_bcd( x)
31#define RTC_GET_TIME_MINUTE     bcd_to_dec( rtc.data[3])
32#define RTC_SET_TIME_MINUTE(x)  rtc.data[3] = dec_to_bcd( x)
33#define RTC_GET_TIME_SECOND     bcd_to_dec( rtc.data[2])
34#define RTC_SET_TIME_SECOND(x)  rtc.data[2] = dec_to_bcd( x)
35
36static void pcf8593_clear_buffer_rx( void);
37static TIMER_CALLBACK( pcf8593_timer_callback );
38
39typedef struct
40{
41   UINT8 *data;
42   UINT32 size;
43   int pin_scl, pin_sda, inp;
44   bool active;
45   int bits;
46   UINT8 data_recv_index, data_recv[50];
47   UINT8 mode, pos;
48   mame_timer *timer;
49} PCF8593;
50
51static PCF8593 rtc;
52
53void pcf8593_init( void)
54{
55   _logerror( 0, "pcf8593_init\n");
56   memset( &rtc, 0, sizeof( rtc));
57   rtc.size = 16;
58   rtc.data = malloc( rtc.size);
59   rtc.timer = mame_timer_alloc( pcf8593_timer_callback );
60   mame_timer_adjust( rtc.timer, MAME_TIME_IN_SEC(1), 0, MAME_TIME_IN_SEC(1));
61   pcf8593_reset();
62}
63
64void pcf8593_exit( void)
65{
66   _logerror( 0, "pcf8593_exit\n");
67   free( rtc.data);
68}
69
70void pcf8593_reset( void)
71{
72   _logerror( 0, "pcf8593_reset\n");
73   rtc.pin_scl = 1;
74   rtc.pin_sda = 1;
75   rtc.active  = FALSE;
76   rtc.inp     = 0;
77   rtc.mode    = RTC_MODE_RECV;
78   rtc.bits    = 0;
79   pcf8593_clear_buffer_rx();
80   rtc.pos     = 0;
81}
82
83void pcf8593_pin_scl( int data)
84{
85   // send bit
86   if ((rtc.active) && (!rtc.pin_scl) && (data))
87   {
88      switch (rtc.mode)
89      {
90         // HOST -> RTC
91         case RTC_MODE_RECV :
92         {
93            // get bit
94             if (rtc.pin_sda) rtc.data_recv[rtc.data_recv_index] = rtc.data_recv[rtc.data_recv_index] | (0x80 >> rtc.bits);
95            rtc.bits++;
96            // bit 9 = end
97            if (rtc.bits > 8)
98            {
99               _logerror( 2, "pcf8593_write_byte(%02X)\n", rtc.data_recv[rtc.data_recv_index]);
100               // enter receive mode when 1st byte = 0xA3
101               if ((rtc.data_recv[0] == 0xA3) && (rtc.data_recv_index == 0))
102               {
103                    rtc.mode = RTC_MODE_SEND;
104               }
105               // A2 + xx = "read from pos xx" command
106               if ((rtc.data_recv[0] == 0xA2) && (rtc.data_recv_index == 1))
107               {
108                  rtc.pos = rtc.data_recv[1];
109               }
110               // A2 + xx + .. = write byte
111               if ((rtc.data_recv[0] == 0xA2) && (rtc.data_recv_index >= 2))
112               {
113                  UINT8 rtc_pos, rtc_val;
114                  rtc_pos = rtc.data_recv[1] + (rtc.data_recv_index - 2);
115                  rtc_val = rtc.data_recv[rtc.data_recv_index];
116                  //if (rtc_pos == 0) rtc_val = rtc_val & 3; // what is this doing here?
117                  rtc.data[rtc_pos] = rtc_val;
118               }
119               // next byte
120               rtc.bits = 0;
121                 rtc.data_recv_index++;
122            }
123         }
124         break;
125         // RTC -> HOST
126         case RTC_MODE_SEND :
127         {
128            // set bit
129            rtc.inp = (rtc.data[rtc.pos] >> (7 - rtc.bits)) & 1;
130            rtc.bits++;
131            // bit 9 = end
132            if (rtc.bits > 8)
133            {
134               _logerror( 2, "pcf8593_read_byte(%02X)\n", rtc.data[rtc.pos]);
135               // end ?
136                 if (rtc.pin_sda)
137               {
138                  _logerror( 2, "pcf8593 end\n");
139                    rtc.mode = RTC_MODE_RECV;
140                       pcf8593_clear_buffer_rx();
141               }
142               // next byte
143               rtc.bits = 0;
144               rtc.pos++;
145            }
146         }
147         break;
148      }
149   }
150   // save scl
151   rtc.pin_scl = data;
152}
153
154void pcf8593_pin_sda_w( int data)
155{
156   // clock is high
157   if (rtc.pin_scl)
158   {
159      // log init I2C
160      if (data) _logerror( 1, "pcf8593 init i2c\n");
161      // start condition (high to low when clock is high)
162      if ((!data) && (rtc.pin_sda))
163      {
164         _logerror( 1, "pcf8593 start condition\n");
165         rtc.active          = TRUE;
166         rtc.bits            = 0;
167         rtc.data_recv_index = 0;
168         pcf8593_clear_buffer_rx();
169         //rtc.pos = 0;
170      }
171      // stop condition (low to high when clock is high)
172      if ((data) && (!rtc.pin_sda))
173      {
174         _logerror( 1, "pcf8593 stop condition\n");
175         rtc.active = FALSE;
176      }
177   }
178   // save sda
179   rtc.pin_sda = data;
180}
181
182int pcf8593_pin_sda_r( void)
183{
184   return rtc.inp;
185}
186
187void pcf8593_clear_buffer_rx( void)
188{
189   memset( &rtc.data_recv[0], 0, sizeof( rtc.data_recv));
190   rtc.data_recv_index = 0;
191}
192
193static UINT8 dec_to_bcd( UINT8 data)
194{
195   return ((data / 10) << 4) | ((data % 10) << 0);
196}
197
198static UINT8 bcd_to_dec( UINT8 data)
199{
200   if ((data & 0x0F) >= 0x0A) data = data - 0x0A + 0x10;
201   if ((data & 0xF0) >= 0xA0) data = data - 0xA0;
202   return (data & 0x0F) + (((data & 0xF0) >> 4) * 10);
203}
204
205void pcf8593_set_time( int hour, int minute, int second)
206{
207   RTC_SET_TIME_HOUR( hour);
208   RTC_SET_TIME_MINUTE( minute);
209   RTC_SET_TIME_SECOND( second);
210   rtc.data[1] = 0; // hundreds of a seconds
211}
212
213void pcf8593_set_date( int year, int month, int day)
214{
215   RTC_SET_DATE_YEAR( year);
216   RTC_SET_DATE_MONTH( month);
217   RTC_SET_DATE_DAY( day);
218}
219
220static int get_days_in_month( int year, int month)
221{
222   static const int table[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
223   if ((month == 2) && ((year & 0x03) == 0)) return 29;
224   return table[month-1];
225}
226
227static TIMER_CALLBACK( pcf8593_timer_callback )
228{
229   int value;
230   _logerror( 2, "pcf8593_timer_callback (%d)\n", param);
231   // check if counting is enabled
232   if (rtc.data[0] & 0x80) return;
233   // increment second
234   value = RTC_GET_TIME_SECOND;
235   if (value < 59)
236   {
237      RTC_SET_TIME_SECOND( value + 1);
238   }
239   else
240   {
241      RTC_SET_TIME_SECOND( 0);
242      // increment minute
243      value = RTC_GET_TIME_MINUTE;
244      if (value < 59)
245      {
246         RTC_SET_TIME_MINUTE( value + 1);
247      }
248      else
249      {
250         RTC_SET_TIME_MINUTE( 0);
251         // increment hour
252         value = RTC_GET_TIME_HOUR;
253         if (value < 23)
254         {
255            RTC_SET_TIME_HOUR( value + 1);
256         }
257         else
258         {
259            RTC_SET_TIME_HOUR( 0);
260            // increment day
261            value = RTC_GET_DATE_DAY;
262            if (value < get_days_in_month( RTC_GET_DATE_YEAR, RTC_GET_DATE_MONTH))
263            {
264               RTC_SET_DATE_DAY( value + 1);
265            }
266            else
267            {
268               RTC_SET_DATE_DAY( 1);
269               // increase month
270               value = RTC_GET_DATE_MONTH;
271               if (value < 12)
272               {
273                  RTC_SET_DATE_MONTH( value + 1);
274               }
275               else
276               {
277                  RTC_SET_DATE_MONTH( 1);
278                  // increase year
279                  RTC_SET_DATE_YEAR( RTC_GET_DATE_YEAR + 1);
280               }
281            }
282         }
283      }
284   }
285}
286
287void pcf8593_load( mame_file *file)
288{
289   mame_system_time systime;
290   _logerror( 0, "pcf8593_load (%p)\n", file);
291   mame_fread( file, rtc.data, rtc.size);
292   mame_get_current_datetime( Machine, &systime);
293   pcf8593_set_date( systime.local_time.year, systime.local_time.month + 1, systime.local_time.mday);
294   pcf8593_set_time( systime.local_time.hour, systime.local_time.minute, systime.local_time.second);
295}
296
297void pcf8593_save( mame_file *file)
298{
299   _logerror( 0, "pcf8593_save (%p)\n", file);
300   mame_fwrite( file, rtc.data, rtc.size);
301}
302
303/*
304NVRAM_HANDLER( pcf8593 )
305{
306   _logerror( 0, "nvram_handler_pcf8593 (%p/%d)\n", file, read_or_write);
307   if (read_or_write)
308   {
309      pcf8593_save( file);
310   }
311   else
312   {
313      if (file)
314      {
315         pcf8593_load( file);
316      }
317      else
318      {
319         memset( rtc.data, 0, rtc.size);
320      }
321   }
322}
323*/
src/mess/machine/at45dbxx.c
r882r883
1/*
2 
3   Atmel Serial DataFlash
4 
5   (c) 2001-2007 Tim Schuerewegen
6 
7   AT45DB041 -  528 KByte
8   AT45DB081 - 1056 KByte
9   AT45DB161 - 2112 KByte
10 
11*/
12 
13#include "at45dbxx.h"
14 
15#define LOG_LEVEL  1
16#define _logerror(level,...)  if (LOG_LEVEL > level) logerror(__VA_ARGS__)
17 
18#define FLASH_CMD_52  0x52
19#define FLASH_CMD_57  0x57
20#define FLASH_CMD_60  0x60
21#define FLASH_CMD_82  0x82
22 
23#define FLASH_MODE_XX  0 // unknown
24#define FLASH_MODE_SI  1 // input
25#define FLASH_MODE_SO  2 // output
26 
27typedef struct
28{
29   int cs;    // chip select
30   int sck;   // serial clock
31   int si;    // serial input
32   int so;    // serial output
33   int wp;    // write protect
34   int reset; // reset
35   int busy;  // busy
36} AT45DBXX_PINS;
37 
38typedef struct
39{
40   UINT8 data[8], size;
41} AT45DBXX_CMD;
42 
43typedef struct
44{
45   UINT8 *data;
46   UINT32 size, pos;
47} AT45DBXX_IO;
48 
49typedef struct
50{
51   UINT8 *data;
52   UINT32 size;
53   UINT32 pages, page_size;
54   UINT8 mode, status, devid, *buffer1, *buffer2;
55   AT45DBXX_PINS pin;
56   UINT8 si_byte, si_bits, so_byte, so_bits;
57   AT45DBXX_CMD cmd;
58   AT45DBXX_IO io;
59} AT45DBXX;
60 
61static AT45DBXX flash;
62 
63void at45dbxx_state_save( void);
64 
65void at45dbxx_init( int type)
66{
67   _logerror( 0, "at45dbxx_init (%d)\n", type);
68   memset( &flash, 0, sizeof( flash));
69   switch (type)
70   {
71      case AT45DB041 : flash.pages = 2048; flash.page_size = 264; flash.devid = 0x18; break;
72      case AT45DB081 : flash.pages = 4096; flash.page_size = 264; flash.devid = 0x20; break;
73      case AT45DB161 : flash.pages = 4096; flash.page_size = 528; flash.devid = 0x28; break;
74   }
75   flash.size = flash.pages * flash.page_size;
76   flash.data = (UINT8*)malloc( flash.size);
77   flash.buffer1 = (UINT8*)malloc( flash.page_size);
78   flash.buffer2 = (UINT8*)malloc( flash.page_size);
79   at45dbxx_state_save();
80}
81 
82void at45dbxx_exit( void)
83{
84   _logerror( 0, "at45dbxx_exit\n");
85   free( flash.buffer2);
86   free( flash.buffer1);
87   free( flash.data);
88}
89 
90void at45dbxx_reset( void)
91{
92   _logerror( 1, "at45dbxx_reset\n");
93   // mode
94   flash.mode = FLASH_MODE_SI;
95   // command
96   memset( &flash.cmd.data[0], 0, sizeof( flash.cmd.data));
97   flash.cmd.size = 0;
98   // input/output
99   flash.io.data = NULL;
100   flash.io.size = 0;
101   flash.io.pos  = 0;
102   // pins
103   flash.pin.cs    = 0;
104   flash.pin.sck   = 0;
105   flash.pin.si    = 0;
106   flash.pin.so    = 0;
107   flash.pin.wp    = 0;
108   flash.pin.reset = 0;
109   flash.pin.busy  = 0;
110   // output
111   flash.so_byte = 0;
112   flash.so_bits = 0;
113   // input
114   flash.si_byte = 0;
115   flash.si_bits = 0;
116}
117 
118void at45dbxx_state_save( void)
119{
120   const char *name = "at45dbxx";
121   // data
122   state_save_register_item_pointer( name, 0, flash.data, flash.size);
123   // pins
124   state_save_register_item( name, 0, flash.pin.cs);
125   state_save_register_item( name, 0, flash.pin.sck);
126   state_save_register_item( name, 0, flash.pin.si);
127   state_save_register_item( name, 0, flash.pin.so);
128   state_save_register_item( name, 0, flash.pin.wp);
129   state_save_register_item( name, 0, flash.pin.reset);
130   state_save_register_item( name, 0, flash.pin.busy);
131}
132 
133UINT8 at45dbxx_read_byte( void)
134{
135   UINT8 data;
136   // check mode
137   if ((flash.mode != FLASH_MODE_SO) || (!flash.io.data)) return 0;
138   // read byte
139   data = flash.io.data[flash.io.pos++];
140   _logerror( 2, "at45dbxx_read_byte (%02X) (%03d/%03d)\n", data, flash.io.pos, flash.io.size);
141   if (flash.io.pos == flash.io.size) flash.io.pos = 0;
142   return data;
143}
144 
145void flash_set_io( UINT8* data, UINT32 size, UINT32 pos)
146{
147   flash.io.data = data;
148   flash.io.size = size;
149   flash.io.pos  = pos;
150}
151 
152UINT32 flash_get_page_addr( void)
153{
154   switch (flash.devid)
155   {
156      case 0x18 : return ((flash.cmd.data[1] & 0x0F) << 7) | ((flash.cmd.data[2] & 0xFE) >> 1);
157      case 0x20 : return ((flash.cmd.data[1] & 0x1F) << 7) | ((flash.cmd.data[2] & 0xFE) >> 1);
158      case 0x28 : return ((flash.cmd.data[1] & 0x3F) << 6) | ((flash.cmd.data[2] & 0xFC) >> 2);
159      default   : return 0;
160   }
161}
162 
163UINT32 flash_get_byte_addr( void)
164{
165   switch (flash.devid)
166   {
167      case 0x18 : // fall-through
168      case 0x20 : return ((flash.cmd.data[2] & 0x01) << 8) | ((flash.cmd.data[3] & 0xFF) >> 0);
169      case 0x28 : return ((flash.cmd.data[2] & 0x03) << 8) | ((flash.cmd.data[3] & 0xFF) >> 0);
170      default   : return 0;
171   }
172}
173 
174void at45dbxx_write_byte( UINT8 data)
175{
176   // check mode
177   if (flash.mode != FLASH_MODE_SI) return;
178   // process byte
179   if (flash.cmd.size < 8)
180   {
181      UINT8 opcode;
182      _logerror( 2, "at45dbxx_write_byte (%02X)\n", data);
183      // add to command buffer
184      flash.cmd.data[flash.cmd.size++] = data;
185      // check opcode
186      opcode = flash.cmd.data[0];
187      switch (opcode)
188      {
189         // status register read
190         case FLASH_CMD_57 :
191         {
192            // 8 bits command
193            if (flash.cmd.size == 1)
194            {
195               _logerror( 1, "at45dbxx opcode %02X - status register read\n", opcode);
196               flash.status = (flash.status & 0xC7) | flash.devid; // 80 = busy / 40 = compare fail
197               flash_set_io( &flash.status, 1, 0);
198               flash.mode = FLASH_MODE_SO;
199               flash.cmd.size = 8;
200            }
201         }
202         break;
203         // main memory page to buffer 1 compare
204         case FLASH_CMD_60 :
205         {
206            // 8 bits command + 4 bits reserved + 11 bits page address + 9 bits don't care
207            if (flash.cmd.size == 4)
208            {
209               UINT32 page;
210               UINT8 comp;
211               page = flash_get_page_addr();
212               _logerror( 1, "at45dbxx opcode %02X - main memory page to buffer 1 compare [%04X]\n", opcode, page);
213               comp = memcmp( flash.data + page * flash.page_size, flash.buffer1, flash.page_size) == 0 ? 0 : 1;
214               if (comp) flash.status |= 0x40; else flash.status &= ~0x40;
215               _logerror( 1, "at45dbxx page compare %s\n", comp ? "failure" : "success");
216               flash.mode = FLASH_MODE_SI;
217               flash.cmd.size = 8;
218            }
219         }
220         break;
221         // main memory page read
222         case FLASH_CMD_52 :
223         {
224            // 8 bits command + 4 bits reserved + 11 bits page address + 9 bits buffer address + 32 bits don't care
225            if (flash.cmd.size == 8)
226            {
227               UINT32 page, byte;
228               page = flash_get_page_addr();
229               byte = flash_get_byte_addr();
230               _logerror( 1, "at45dbxx opcode %02X - main memory page read [%04X/%04X]\n", opcode, page, byte);
231               flash_set_io( flash.data + page * flash.page_size, flash.page_size, byte);
232               flash.mode = FLASH_MODE_SO;
233               flash.cmd.size = 8;
234            }
235         }
236         break;
237         // main memory page program through buffer 1
238         case FLASH_CMD_82 :
239         {
240            // 8 bits command + 4 bits reserved + 11 bits page address + 9 bits buffer address
241            if (flash.cmd.size == 4)
242            {
243               UINT32 page, byte;
244               page = flash_get_page_addr();
245               byte = flash_get_byte_addr();
246               _logerror( 1, "at45dbxx opcode %02X - main memory page program through buffer 1 [%04X/%04X]\n",opcode, page, byte);
247               flash_set_io( flash.buffer1, flash.page_size, byte);
248               memset( flash.buffer1, 0xFF, flash.page_size);
249               flash.mode = FLASH_MODE_SI;
250               flash.cmd.size = 8;
251            }
252         }
253         break;
254         // other
255         default :
256         {
257            _logerror( 1, "at45dbxx opcode %02X - unknown\n", opcode);
258            flash.cmd.data[0] = 0;
259            flash.cmd.size = 0;
260         }
261         break;
262      }
263   }
264   else
265   {
266      _logerror( 2, "at45dbxx_write_byte (%02X) (%03d/%03d)\n", data, flash.io.pos + 1, flash.io.size);
267      // store byte
268      flash.io.data[flash.io.pos] = data;
269      flash.io.pos++;
270      if (flash.io.pos == flash.io.size) flash.io.pos = 0;
271   }
272}
273 
274int at45dbxx_pin_so( void)
275{
276   if (flash.pin.cs == 0) return 0;
277   return flash.pin.so;
278}
279 
280void at45dbxx_pin_si( int data)
281{
282   if (flash.pin.cs == 0) return;
283   flash.pin.si = data;
284}
285 
286void at45dbxx_pin_cs( int data)
287{
288   // check if changed
289   if (flash.pin.cs == data) return;
290   // cs low-to-high
291   if (data != 0)
292   {
293      // complete program command
294      if ((flash.cmd.size >= 4) && (flash.cmd.data[0] == FLASH_CMD_82))
295      {
296         UINT32 page, byte;
297         page = flash_get_page_addr();
298         byte = flash_get_byte_addr();
299         _logerror( 1, "at45dbxx - program data stored in buffer 1 into selected page in main memory [%04X/%04X]\n", page, byte);
300         memcpy( flash.data + page * flash.page_size, flash.buffer1, flash.page_size);
301      }
302      // reset
303      at45dbxx_reset();
304   }
305   // save cs
306   flash.pin.cs = data;
307}
308 
309void at45dbxx_pin_sck( int data)
310{
311   // check if changed
312   if (flash.pin.sck == data) return;
313   // sck high-to-low
314   if (data == 0)
315   {
316      // output (part 1)
317      if (flash.so_bits == 8)
318      {
319         flash.so_bits = 0;
320         flash.so_byte = at45dbxx_read_byte();
321      }
322      // input
323      if (flash.pin.si) flash.si_byte = flash.si_byte | (1 << flash.si_bits);
324      flash.si_bits++;
325      if (flash.si_bits == 8)
326      {
327         flash.si_bits = 0;
328         at45dbxx_write_byte( flash.si_byte);
329         flash.si_byte = 0;
330      }
331      // output (part 2)
332      flash.pin.so = (flash.so_byte >> flash.so_bits) & 1;
333      flash.so_bits++;
334   }
335   // save sck
336   flash.pin.sck = data;
337}
338 
339void at45dbxx_load( mame_file *file)
340{
341   _logerror( 0, "at45dbxx_load (%p)\n", file);
342   mame_fread( file, flash.data, flash.size);
343}
344 
345void at45dbxx_save( mame_file *file)
346{
347   _logerror( 0, "at45dbxx_save (%p)\n", file);
348   mame_fwrite( file, flash.data, flash.size);
349}
350 
351/*
352NVRAM_HANDLER( at45dbxx )
353{
354   _logerror( 0, "nvram_handler_at45dbxx (%p/%d)\n", file, read_or_write);
355   if (read_or_write)
356   {
357      at45dbxx_save( file);
358   }
359   else
360   {
361      if (file)
362      {
363         at45dbxx_load( file);
364      }
365      else
366      {
367         memset( flash.data, 0xFF, flash.size);
368      }
369   }
370}
371*/
1/*
2
3   Atmel Serial DataFlash
4
5   (c) 2001-2007 Tim Schuerewegen
6
7   AT45DB041 -  528 KByte
8   AT45DB081 - 1056 KByte
9   AT45DB161 - 2112 KByte
10
11*/
12
13#include "at45dbxx.h"
14
15#define LOG_LEVEL  1
16#define _logerror(level,...)  if (LOG_LEVEL > level) logerror(__VA_ARGS__)
17
18#define FLASH_CMD_52  0x52
19#define FLASH_CMD_57  0x57
20#define FLASH_CMD_60  0x60
21#define FLASH_CMD_82  0x82
22
23#define FLASH_MODE_XX  0 // unknown
24#define FLASH_MODE_SI  1 // input
25#define FLASH_MODE_SO  2 // output
26
27typedef struct
28{
29   int cs;    // chip select
30   int sck;   // serial clock
31   int si;    // serial input
32   int so;    // serial output
33   int wp;    // write protect
34   int reset; // reset
35   int busy;  // busy
36} AT45DBXX_PINS;
37
38typedef struct
39{
40   UINT8 data[8], size;
41} AT45DBXX_CMD;
42
43typedef struct
44{
45   UINT8 *data;
46   UINT32 size, pos;
47} AT45DBXX_IO;
48
49typedef struct
50{
51   UINT8 *data;
52   UINT32 size;
53   UINT32 pages, page_size;
54   UINT8 mode, status, devid, *buffer1, *buffer2;
55   AT45DBXX_PINS pin;
56   UINT8 si_byte, si_bits, so_byte, so_bits;
57   AT45DBXX_CMD cmd;
58   AT45DBXX_IO io;
59} AT45DBXX;
60
61static AT45DBXX flash;
62
63void at45dbxx_state_save( void);
64
65void at45dbxx_init( int type)
66{
67   _logerror( 0, "at45dbxx_init (%d)\n", type);
68   memset( &flash, 0, sizeof( flash));
69   switch (type)
70   {
71      case AT45DB041 : flash.pages = 2048; flash.page_size = 264; flash.devid = 0x18; break;
72      case AT45DB081 : flash.pages = 4096; flash.page_size = 264; flash.devid = 0x20; break;
73      case AT45DB161 : flash.pages = 4096; flash.page_size = 528; flash.devid = 0x28; break;
74   }
75   flash.size = flash.pages * flash.page_size;
76   flash.data = (UINT8*)malloc( flash.size);
77   flash.buffer1 = (UINT8*)malloc( flash.page_size);
78   flash.buffer2 = (UINT8*)malloc( flash.page_size);
79   at45dbxx_state_save();
80}
81
82void at45dbxx_exit( void)
83{
84   _logerror( 0, "at45dbxx_exit\n");
85   free( flash.buffer2);
86   free( flash.buffer1);
87   free( flash.data);
88}
89
90void at45dbxx_reset( void)
91{
92   _logerror( 1, "at45dbxx_reset\n");
93   // mode
94   flash.mode = FLASH_MODE_SI;
95   // command
96   memset( &flash.cmd.data[0], 0, sizeof( flash.cmd.data));
97   flash.cmd.size = 0;
98   // input/output
99   flash.io.data = NULL;
100   flash.io.size = 0;
101   flash.io.pos  = 0;
102   // pins
103   flash.pin.cs    = 0;
104   flash.pin.sck   = 0;
105   flash.pin.si    = 0;
106   flash.pin.so    = 0;
107   flash.pin.wp    = 0;
108   flash.pin.reset = 0;
109   flash.pin.busy  = 0;
110   // output
111   flash.so_byte = 0;
112   flash.so_bits = 0;
113   // input
114   flash.si_byte = 0;
115   flash.si_bits = 0;
116}
117
118void at45dbxx_state_save( void)
119{
120   const char *name = "at45dbxx";
121   // data
122   state_save_register_item_pointer( name, 0, flash.data, flash.size);
123   // pins
124   state_save_register_item( name, 0, flash.pin.cs);
125   state_save_register_item( name, 0, flash.pin.sck);
126   state_save_register_item( name, 0, flash.pin.si);
127   state_save_register_item( name, 0, flash.pin.so);
128   state_save_register_item( name, 0, flash.pin.wp);
129   state_save_register_item( name, 0, flash.pin.reset);
130   state_save_register_item( name, 0, flash.pin.busy);
131}
132
133UINT8 at45dbxx_read_byte( void)
134{
135   UINT8 data;
136   // check mode
137   if ((flash.mode != FLASH_MODE_SO) || (!flash.io.data)) return 0;
138   // read byte
139   data = flash.io.data[flash.io.pos++];
140   _logerror( 2, "at45dbxx_read_byte (%02X) (%03d/%03d)\n", data, flash.io.pos, flash.io.size);
141   if (flash.io.pos == flash.io.size) flash.io.pos = 0;
142   return data;
143}
144
145void flash_set_io( UINT8* data, UINT32 size, UINT32 pos)
146{
147   flash.io.data = data;
148   flash.io.size = size;
149   flash.io.pos  = pos;
150}
151
152UINT32 flash_get_page_addr( void)
153{
154   switch (flash.devid)
155   {
156      case 0x18 : return ((flash.cmd.data[1] & 0x0F) << 7) | ((flash.cmd.data[2] & 0xFE) >> 1);
157      case 0x20 : return ((flash.cmd.data[1] & 0x1F) << 7) | ((flash.cmd.data[2] & 0xFE) >> 1);
158      case 0x28 : return ((flash.cmd.data[1] & 0x3F) << 6) | ((flash.cmd.data[2] & 0xFC) >> 2);
159      default   : return 0;
160   }
161}
162
163UINT32 flash_get_byte_addr( void)
164{
165   switch (flash.devid)
166   {
167      case 0x18 : // fall-through
168      case 0x20 : return ((flash.cmd.data[2] & 0x01) << 8) | ((flash.cmd.data[3] & 0xFF) >> 0);
169      case 0x28 : return ((flash.cmd.data[2] & 0x03) << 8) | ((flash.cmd.data[3] & 0xFF) >> 0);
170      default   : return 0;
171   }
172}
173
174void at45dbxx_write_byte( UINT8 data)
175{
176   // check mode
177   if (flash.mode != FLASH_MODE_SI) return;
178   // process byte
179   if (flash.cmd.size < 8)
180   {
181      UINT8 opcode;
182      _logerror( 2, "at45dbxx_write_byte (%02X)\n", data);
183      // add to command buffer
184      flash.cmd.data[flash.cmd.size++] = data;
185      // check opcode
186      opcode = flash.cmd.data[0];
187      switch (opcode)
188      {
189         // status register read
190         case FLASH_CMD_57 :
191         {
192            // 8 bits command
193            if (flash.cmd.size == 1)
194            {
195               _logerror( 1, "at45dbxx opcode %02X - status register read\n", opcode);
196               flash.status = (flash.status & 0xC7) | flash.devid; // 80 = busy / 40 = compare fail
197               flash_set_io( &flash.status, 1, 0);
198               flash.mode = FLASH_MODE_SO;
199               flash.cmd.size = 8;
200            }
201         }
202         break;
203         // main memory page to buffer 1 compare
204         case FLASH_CMD_60 :
205         {
206            // 8 bits command + 4 bits reserved + 11 bits page address + 9 bits don't care
207            if (flash.cmd.size == 4)
208            {
209               UINT32 page;
210               UINT8 comp;
211               page = flash_get_page_addr();
212               _logerror( 1, "at45dbxx opcode %02X - main memory page to buffer 1 compare [%04X]\n", opcode, page);
213               comp = memcmp( flash.data + page * flash.page_size, flash.buffer1, flash.page_size) == 0 ? 0 : 1;
214               if (comp) flash.status |= 0x40; else flash.status &= ~0x40;
215               _logerror( 1, "at45dbxx page compare %s\n", comp ? "failure" : "success");
216               flash.mode = FLASH_MODE_SI;
217               flash.cmd.size = 8;
218            }
219         }
220         break;
221         // main memory page read
222         case FLASH_CMD_52 :
223         {
224            // 8 bits command + 4 bits reserved + 11 bits page address + 9 bits buffer address + 32 bits don't care
225            if (flash.cmd.size == 8)
226            {
227               UINT32 page, byte;
228               page = flash_get_page_addr();
229               byte = flash_get_byte_addr();
230               _logerror( 1, "at45dbxx opcode %02X - main memory page read [%04X/%04X]\n", opcode, page, byte);
231               flash_set_io( flash.data + page * flash.page_size, flash.page_size, byte);
232               flash.mode = FLASH_MODE_SO;
233               flash.cmd.size = 8;
234            }
235         }
236         break;
237         // main memory page program through buffer 1
238         case FLASH_CMD_82 :
239         {
240            // 8 bits command + 4 bits reserved + 11 bits page address + 9 bits buffer address
241            if (flash.cmd.size == 4)
242            {
243               UINT32 page, byte;
244               page = flash_get_page_addr();
245               byte = flash_get_byte_addr();
246               _logerror( 1, "at45dbxx opcode %02X - main memory page program through buffer 1 [%04X/%04X]\n",opcode, page, byte);
247               flash_set_io( flash.buffer1, flash.page_size, byte);
248               memset( flash.buffer1, 0xFF, flash.page_size);
249               flash.mode = FLASH_MODE_SI;
250               flash.cmd.size = 8;
251            }
252         }
253         break;
254         // other
255         default :
256         {
257            _logerror( 1, "at45dbxx opcode %02X - unknown\n", opcode);
258            flash.cmd.data[0] = 0;
259            flash.cmd.size = 0;
260         }
261         break;
262      }
263   }
264   else
265   {
266      _logerror( 2, "at45dbxx_write_byte (%02X) (%03d/%03d)\n", data, flash.io.pos + 1, flash.io.size);
267      // store byte
268      flash.io.data[flash.io.pos] = data;
269      flash.io.pos++;
270      if (flash.io.pos == flash.io.size) flash.io.pos = 0;
271   }
272}
273
274int at45dbxx_pin_so( void)
275{
276   if (flash.pin.cs == 0) return 0;
277   return flash.pin.so;
278}
279
280void at45dbxx_pin_si( int data)
281{
282   if (flash.pin.cs == 0) return;
283   flash.pin.si = data;
284}
285
286void at45dbxx_pin_cs( int data)
287{
288   // check if changed
289   if (flash.pin.cs == data) return;
290   // cs low-to-high
291   if (data != 0)
292   {
293      // complete program command
294      if ((flash.cmd.size >= 4) && (flash.cmd.data[0] == FLASH_CMD_82))
295      {
296         UINT32 page, byte;
297         page = flash_get_page_addr();
298         byte = flash_get_byte_addr();
299         _logerror( 1, "at45dbxx - program data stored in buffer 1 into selected page in main memory [%04X/%04X]\n", page, byte);
300         memcpy( flash.data + page * flash.page_size, flash.buffer1, flash.page_size);
301      }
302      // reset
303      at45dbxx_reset();
304   }
305   // save cs
306   flash.pin.cs = data;
307}
308
309void at45dbxx_pin_sck( int data)
310{
311   // check if changed
312   if (flash.pin.sck == data) return;
313   // sck high-to-low
314   if (data == 0)
315   {
316      // output (part 1)
317      if (flash.so_bits == 8)
318      {
319         flash.so_bits = 0;
320         flash.so_byte = at45dbxx_read_byte();
321      }
322      // input
323      if (flash.pin.si) flash.si_byte = flash.si_byte | (1 << flash.si_bits);
324      flash.si_bits++;
325      if (flash.si_bits == 8)
326      {
327         flash.si_bits = 0;
328         at45dbxx_write_byte( flash.si_byte);
329         flash.si_byte = 0;
330      }
331      // output (part 2)
332      flash.pin.so = (flash.so_byte >> flash.so_bits) & 1;
333      flash.so_bits++;
334   }
335   // save sck
336   flash.pin.sck = data;
337}
338
339void at45dbxx_load( mame_file *file)
340{
341   _logerror( 0, "at45dbxx_load (%p)\n", file);
342   mame_fread( file, flash.data, flash.size);
343}
344
345void at45dbxx_save( mame_file *file)
346{
347   _logerror( 0, "at45dbxx_save (%p)\n", file);
348   mame_fwrite( file, flash.data, flash.size);
349}
350
351/*
352NVRAM_HANDLER( at45dbxx )
353{
354   _logerror( 0, "nvram_handler_at45dbxx (%p/%d)\n", file, read_or_write);
355   if (read_or_write)
356   {
357      at45dbxx_save( file);
358   }
359   else
360   {
361      if (file)
362      {
363         at45dbxx_load( file);
364      }
365      else
366      {
367         memset( flash.data, 0xFF, flash.size);
368      }
369   }
370}
371*/
src/mess/machine/pcf8593.h
r882r883
1/*
2 
3   Philips PCF8593 CMOS clock/calendar circuit
4 
5   (c) 2001-2007 Tim Schuerewegen
6 
7*/
8 
9#ifndef _PCF8593_H_
10#define _PCF8593_H_
11 
12#include "driver.h"
13 
14// init/exit/reset
15void pcf8593_init( void);
16void pcf8593_exit( void);
17void pcf8593_reset( void);
18 
19// pins
20void pcf8593_pin_scl( int data);
21void pcf8593_pin_sda_w( int data);
22int  pcf8593_pin_sda_r( void);
23 
24// load/save
25void pcf8593_load( mame_file *file);
26void pcf8593_save( mame_file *file);
27 
28// non-volatile ram handler
29NVRAM_HANDLER( pcf8593 );
30 
31#endif
1/*
2
3   Philips PCF8593 CMOS clock/calendar circuit
4
5   (c) 2001-2007 Tim Schuerewegen
6
7*/
8
9#ifndef _PCF8593_H_
10#define _PCF8593_H_
11
12#include "driver.h"
13
14// init/exit/reset
15void pcf8593_init( void);
16void pcf8593_exit( void);
17void pcf8593_reset( void);
18
19// pins
20void pcf8593_pin_scl( int data);
21void pcf8593_pin_sda_w( int data);
22int  pcf8593_pin_sda_r( void);
23
24// load/save
25void pcf8593_load( mame_file *file);
26void pcf8593_save( mame_file *file);
27
28// non-volatile ram handler
29NVRAM_HANDLER( pcf8593 );
30
31#endif
src/mess/machine/at45dbxx.h
r882r883
1/*
2 
3   Atmel Serial DataFlash
4 
5   (c) 2001-2007 Tim Schuerewegen
6 
7   AT45DB041 -  528 KByte
8   AT45DB081 - 1056 KByte
9   AT45DB161 - 2112 KByte
10 
11*/
12 
13#ifndef _AT45DBXX_H_
14#define _AT45DBXX_H_
15 
16#include "driver.h"
17 
18enum
19{
20   AT45DB041,
21   AT45DB081,
22   AT45DB161
23};
24 
25// init/exit/reset
26void at45dbxx_init( int type);
27void at45dbxx_exit( void);
28void at45dbxx_reset( void);
29 
30// pins
31void at45dbxx_pin_cs( int data);
32void at45dbxx_pin_sck( int data);
33void at45dbxx_pin_si( int data);
34int  at45dbxx_pin_so( void);
35 
36// load/save
37void at45dbxx_load( mame_file *file);
38void at45dbxx_save( mame_file *file);
39 
40// non-volatile ram handler
41/*
42NVRAM_HANDLER( at45dbxx );
43*/
44 
45#endif
1/*
2
3   Atmel Serial DataFlash
4
5   (c) 2001-2007 Tim Schuerewegen
6
7   AT45DB041 -  528 KByte
8   AT45DB081 - 1056 KByte
9   AT45DB161 - 2112 KByte
10
11*/
12
13#ifndef _AT45DBXX_H_
14#define _AT45DBXX_H_
15
16#include "driver.h"
17
18enum
19{
20   AT45DB041,
21   AT45DB081,
22   AT45DB161
23};
24
25// init/exit/reset
26void at45dbxx_init( int type);
27void at45dbxx_exit( void);
28void at45dbxx_reset( void);
29
30// pins
31void at45dbxx_pin_cs( int data);
32void at45dbxx_pin_sck( int data);
33void at45dbxx_pin_si( int data);
34int  at45dbxx_pin_so( void);
35
36// load/save
37void at45dbxx_load( mame_file *file);
38void at45dbxx_save( mame_file *file);
39
40// non-volatile ram handler
41/*
42NVRAM_HANDLER( at45dbxx );
43*/
44
45#endif
src/mess/machine/amigacd.c
r882r883
1/***************************************************************************
2 
3   Amiga cdrom controller emulation
4   
5Notes:
6Many thanks to Toni Willem for all the help and information about the
7DMAC controller.
8 
9***************************************************************************/
10 
11#include "mame.h"
12#include "driver.h"
13#include "amiga.h"
14#include "amigacd.h"
15#include "machine/6526cia.h"
16#include "machine/wd33c93.h"
17#include "tpi6525.h"
18#include "matsucd.h"
19 
20#define VERBOSE_DMAC 0
21 
22#if VERBOSE_DMAC
23#define LOG logerror
24#else
25INLINE void dummy_log( const char *a, ... ) {}
26#define LOG dummy_log
27#endif
28 
29/* constants */
30#define CD_SECTOR_TIME      (1000/((300*1024)/2048))   /* 2X CDROM sector time in msec (300KBps) */
31 
32/***************************************************************************
33 
34   DMAC
35   
36***************************************************************************/
37 
38/*
39 * value to go into DAWR
40 */
41#define DAWR_ATZSC      3       /* according to A3000T service-manual */
42 
43/*
44 * bits defined for CNTR
45 */
46#define CNTR_TCEN       (1<<7)  /* Terminal Count Enable */
47#define CNTR_PREST      (1<<6)  /* Perp Reset (not implemented :-((( ) */
48#define CNTR_PDMD       (1<<5)  /* Perp Device Mode Select (1=SCSI,0=XT/AT) */
49#define CNTR_INTEN      (1<<4)  /* Interrupt Enable */
50#define CNTR_DDIR       (1<<3)  /* Device Direction. 1==rd host, wr to perp */
51 
52/*
53 * bits defined for ISTR
54 */
55#define ISTR_INTX       (1<<8)  /* XT/AT Interrupt pending */
56#define ISTR_INT_F      (1<<7)  /* Interrupt Follow */
57#define ISTR_INTS       (1<<6)  /* SCSI Peripheral Interrupt */
58#define ISTR_E_INT      (1<<5)  /* End-Of-Process Interrupt */
59#define ISTR_INT_P      (1<<4)  /* Interrupt Pending */
60#define ISTR_UE_INT     (1<<3)  /* Under-Run FIFO Error Interrupt */
61#define ISTR_OE_INT     (1<<2)  /* Over-Run FIFO Error Interrupt */
62#define ISTR_FF_FLG     (1<<1)  /* FIFO-Full Flag */
63#define ISTR_FE_FLG     (1<<0)  /* FIFO-Empty Flag */
64 
65typedef struct
66{
67   UINT16      istr;      /* Interrupt Status Register (R) */
68    UINT16      cntr;      /* Control Register (RW) */
69   UINT32      wtc;      /* Word Transfer Count Register (RW) */
70   UINT32      acr;      /* Address Count Register (RW) */
71   UINT16      dawr;      /* DACK Width Register (W) */
72   mame_timer *dma_timer;
73} _dmac_data;
74 
75static _dmac_data dmac_data;
76 
77static void check_interrupts( void )
78{
79   /* if interrupts are disabled, bail */
80   if ( (dmac_data.cntr & CNTR_INTEN) == 0 )
81      return;
82   
83   /* if no interrupts are pending, bail */
84   if ( (dmac_data.istr & ISTR_INT_P) == 0 )
85      return;
86   
87   /* otherwise, generate the IRQ */
88   amiga_custom_w(REG_INTREQ, 0x8000 | INTENA_PORTS, 0);
89}
90 
91static TIMER_CALLBACK(dmac_dma_proc)
92{
93   while( dmac_data.wtc > 0 )
94   {
95      UINT16   dat16;
96      UINT8   dat8;
97       
98      if ( matsucd_get_next_byte( &dat8 ) < 0 )
99         break;
100       
101      dat16 = dat8;
102               
103      if ( matsucd_get_next_byte( &dat8 ) < 0 )
104         break;
105       
106      dat16 <<= 8;
107      dat16 |= dat8;
108       
109      amiga_chip_ram_w(dmac_data.acr, dat16);
110       
111      dmac_data.acr += 2;
112      dmac_data.wtc--;
113   }
114   
115   if ( dmac_data.wtc > 0 )
116   {
117      matsucd_read_next_block();
118      mame_timer_adjust( dmac_data.dma_timer, MAME_TIME_IN_MSEC( CD_SECTOR_TIME ), 0, time_zero );
119   }
120   else
121   {
122      dmac_data.istr |= ISTR_INT_P | ISTR_E_INT;
123      check_interrupts();
124   }
125}
126 
127static READ16_HANDLER( amiga_dmac_r )
128{
129   offset &= 0xff;
130 
131   switch( offset )
132   {
133      case 0x20:
134      {
135         UINT8   v = dmac_data.istr;
136         LOG( "DMAC: PC=%08x - ISTR Read(%04x)\n", activecpu_get_pc(), dmac_data.istr );
137         
138         dmac_data.istr &= ~0x0f;
139         return v;
140      }
141      break;
142       
143      case 0x21:
144      {
145         LOG( "DMAC: PC=%08x - CNTR Read(%04x)\n", activecpu_get_pc(), dmac_data.cntr );
146         return dmac_data.cntr;
147      }
148      break;
149       
150      case 0x40:   /* wtc hi */
151      {
152         LOG( "DMAC: PC=%08x - WTC HI Read\n", activecpu_get_pc() );
153         return (dmac_data.wtc >> 16);
154      }
155      break;
156         
157      case 0x41:   /* wtc lo */
158      {
159         LOG( "DMAC: PC=%08x - WTC LO Read\n", activecpu_get_pc() );
160         return dmac_data.wtc;
161      }
162      break;
163       
164      case 0x42:   /* acr hi */
165      {
166         LOG( "DMAC: PC=%08x - ACR HI Read\n", activecpu_get_pc() );
167         return (dmac_data.acr >> 16);
168      }
169      break;
170         
171      case 0x43:   /* acr lo */
172      {
173         LOG( "DMAC: PC=%08x - ACR LO Read\n", activecpu_get_pc() );
174         return dmac_data.acr;
175      }
176      break;
177 
178      case 0x48:   /* wd33c93 SCSI expansion */
179      case 0x49:
180      {
181         LOG( "DMAC: PC=%08x - WD33C93 Read(%d)\n", activecpu_get_pc(), offset & 1 );
182         return 0x00;   /* Not available without SCSI expansion */
183      }
184      break;
185       
186      case 0x50:
187      {
188         LOG( "DMAC: PC=%08x - CDROM RESP Read\n", activecpu_get_pc() );
189         return matsucd_response_r();
190      }
191      break;
192       
193      case 0x51:   /* XT IO */
194      case 0x52:
195      case 0x53:
196      {
197         LOG( "DMAC: PC=%08x - XT IO Read(%d)\n", activecpu_get_pc(), (offset & 3)-1 );
198         return 0xff;
199      }
200      break;
201       
202      case 0x58:   /* TPI6525 */
203      case 0x59:
204      case 0x5A:
205      case 0x5B:
206      case 0x5C:
207      case 0x5D:
208      case 0x5E:
209      case 0x5F:
210      case 0x60:
211      case 0x61:
212      case 0x62:
213      case 0x63:
214      case 0x64:
215      case 0x65:
216      case 0x66:
217      case 0x67:
218      {
219         LOG( "DMAC: PC=%08x - TPI6525 Read(%d)\n", activecpu_get_pc(), (offset - 0x58) );
220         return tpi6525_0_port_r(offset - 0x58);
221      }
222      break;
223       
224      case 0x70:   /* DMA start strobe */
225      {
226         LOG( "DMAC: PC=%08x - DMA Start Strobe\n", activecpu_get_pc() );
227         mame_timer_adjust( dmac_data.dma_timer, MAME_TIME_IN_MSEC( CD_SECTOR_TIME ), 0, time_zero );
228      }
229      break;
230       
231      case 0x71:   /* DMA stop strobe */
232      {
233         LOG( "DMAC: PC=%08x - DMA Stop Strobe\n", activecpu_get_pc() );
234         mame_timer_reset( dmac_data.dma_timer, time_never );
235      }
236      break;
237       
238      case 0x72:   /* Clear IRQ strobe */
239      {
240         LOG( "DMAC: PC=%08x - IRQ Clear Strobe\n", activecpu_get_pc() );
241         dmac_data.istr &= ~ISTR_INT_P;
242      }
243      break;
244       
245      case 0x74:   /* Flush strobe */
246      {
247         LOG( "DMAC: PC=%08x - Flush Strobe\n", activecpu_get_pc() );
248         dmac_data.istr |= ISTR_FE_FLG;
249      }
250      break;
251             
252      default:
253         logerror( "DMAC-READ: PC=%08x, offset = %02x\n", activecpu_get_pc(), offset );
254      break;
255   }
256   
257   return 0;
258}
259 
260static WRITE16_HANDLER( amiga_dmac_w )
261{
262   offset &= 0xff;
263 
264   switch( offset )
265   {
266      case 0x21:   /* control write */
267      {
268         LOG( "DMAC: PC=%08x - CNTR Write(%04x)\n", activecpu_get_pc(), data );
269         dmac_data.cntr = data;
270         check_interrupts();
271      }
272      break;
273       
274      case 0x40:   /* wtc hi */
275      {
276         LOG( "DMAC: PC=%08x - WTC HI Write - data = %04x\n", activecpu_get_pc(), data );
277         dmac_data.wtc &= 0x0000ffff;
278         dmac_data.wtc |= ((UINT32)data) << 16;
279      }
280      break;
281         
282      case 0x41:   /* wtc lo */
283      {
284         LOG( "DMAC: PC=%08x - WTC LO Write - data = %04x\n", activecpu_get_pc(), data );
285         dmac_data.wtc &= 0xffff0000;
286         dmac_data.wtc |= data;
287      }
288      break;
289       
290      case 0x42:   /* acr hi */
291      {
292         LOG( "DMAC: PC=%08x - ACR HI Write - data = %04x\n", activecpu_get_pc(), data );
293         dmac_data.acr &= 0x0000ffff;
294         dmac_data.acr |= ((UINT32)data) << 16;
295      }
296      break;
297         
298      case 0x43:   /* acr lo */
299      {
300         LOG( "DMAC: PC=%08x - ACR LO Write - data = %04x\n", activecpu_get_pc(), data );
301         dmac_data.acr &= 0xffff0000;
302         dmac_data.acr |= data;
303      }
304      break;
305       
306      case 0x47:   /* dawr */
307      {
308         LOG( "DMAC: PC=%08x - DAWR Write - data = %04x\n", activecpu_get_pc(), data );
309         dmac_data.dawr = data;
310      }
311      break;
312       
313      case 0x48:   /* wd33c93 SCSI expansion */
314      case 0x49:
315      {
316         LOG( "DMAC: PC=%08x - WD33C93 Write(%d) - data = %04x\n", activecpu_get_pc(), offset & 1, data );
317         /* Not available without SCSI expansion */
318      }
319      break;
320       
321      case 0x50:
322      {
323         LOG( "DMAC: PC=%08x - CDROM CMD Write - data = %04x\n", activecpu_get_pc(), data );
324         matsucd_command_w( data );
325      }
326      break;
327       
328      case 0x58:   /* TPI6525 */
329      case 0x59:
330      case 0x5A:
331      case 0x5B:
332      case 0x5C:
333      case 0x5D:
334      case 0x5E:
335      case 0x5F:
336      case 0x60:
337      case 0x61:
338      case 0x62:
339      case 0x63:
340      case 0x64:
341      case 0x65:
342      case 0x66:
343      case 0x67:
344      {
345         LOG( "DMAC: PC=%08x - TPI6525 Write(%d) - data = %04x\n", activecpu_get_pc(), (offset - 0x58), data );
346         tpi6525_0_port_w(offset - 0x58, data);
347      }
348      break;
349       
350      case 0x70:   /* DMA start strobe */
351      {
352         LOG( "DMAC: PC=%08x - DMA Start Strobe\n", activecpu_get_pc() );
353         mame_timer_adjust( dmac_data.dma_timer, MAME_TIME_IN_MSEC( CD_SECTOR_TIME ), 0, time_zero );
354      }
355      break;
356       
357      case 0x71:   /* DMA stop strobe */
358      {
359         LOG( "DMAC: PC=%08x - DMA Stop Strobe\n", activecpu_get_pc() );
360         mame_timer_reset( dmac_data.dma_timer, time_never );
361      }
362      break;
363       
364      case 0x72:   /* Clear IRQ strobe */
365      {
366         LOG( "DMAC: PC=%08x - IRQ Clear Strobe\n", activecpu_get_pc() );
367         dmac_data.istr &= ~ISTR_INT_P;
368      }
369      break;
370       
371      case 0x74:   /* Flush Strobe */
372      {
373         LOG( "DMAC: PC=%08x - Flush Strobe\n", activecpu_get_pc() );
374         dmac_data.istr |= ISTR_FE_FLG;
375      }
376      break;
377       
378      default:
379         logerror( "DMAC-WRITE: PC=%08x, offset = %02x, data = %04x\n", activecpu_get_pc(), offset, data );
380      break;
381   }
382}
383 
384/***************************************************************************
385 
386   Autoconfig
387   
388***************************************************************************/
389 
390static void   dmac_install(offs_t base)
391{
392   memory_install_read16_handler(0, ADDRESS_SPACE_PROGRAM, base, base + 0xFFFF, 0, 0, amiga_dmac_r);
393   memory_install_write16_handler(0, ADDRESS_SPACE_PROGRAM, base, base + 0xFFFF, 0, 0, amiga_dmac_w);
394}
395 
396static void   dmac_uninstall(offs_t base)
397{
398   memory_install_read16_handler(0, ADDRESS_SPACE_PROGRAM, base, base + 0xFFFF, 0, 0, MRA16_UNMAP);
399   memory_install_write16_handler(0, ADDRESS_SPACE_PROGRAM, base, base + 0xFFFF, 0, 0, MWA16_UNMAP);
400}
401 
402static amiga_autoconfig_device dmac_device =
403{
404   0,            /* link into free memory list */
405   0,            /* ROM vector offset valid */
406   0,            /* multiple devices on card */
407   1,            /* number of 64k pages */
408   3,            /* product number (DMAC) */
409   0,            /* prefer 8MB address space */
410   0,            /* can be shut up */
411   0x0202,         /* manufacturers number (Commodore) */
412   0,            /* serial number */
413   0,            /* ROM vector offset */
414   NULL,         /* interrupt control read */
415   NULL,         /* interrupt control write */
416   dmac_install,   /* memory installation */
417   dmac_uninstall   /* memory uninstallation */
418};
419 
420/***************************************************************************
421 
422   TPI6525
423   
424***************************************************************************/
425 
426static int tp6525_portc_r( void )
427{
428   int   ret = 0;
429   
430   if ( (tpi6525[0].c.ddr & 0x04) == 0 ) /* if pin 2 is set to input */
431   {
432      ret |= matsucd_stch_r() ? 0x00 : 0x04;   /* read status change signal */
433   }
434   
435   if ( (tpi6525[0].c.ddr & 0x08) == 0 ) /* if pin 3 is set to input */
436      ret |= matsucd_sten_r() ? 0x08 : 0x00;   /* read enable signal */
437   
438   return ret;
439}
440 
441static void tp6525_portb_w( int data )
442{
443   if ( tpi6525[0].b.ddr & 0x01 ) /* if pin 0 is set to output */
444      matsucd_cmd_w( data & 1 ); /* write to the /CMD signal */
445   
446   if ( tpi6525[0].b.ddr & 0x02 ) /* if pin 1 is set to output */
447      matsucd_enable_w( data & 2 ); /* write to the /ENABLE signal */
448}
449 
450static mame_timer *tp6525_delayed_timer;
451 
452static TIMER_CALLBACK(tp6525_delayed_irq)
453{
454   (void)param;
455   
456   if ( (CUSTOM_REG(REG_INTREQ) & INTENA_PORTS) == 0 )
457   {
458      amiga_custom_w(REG_INTREQ, 0x8000 | INTENA_PORTS, 0);
459   }
460   else
461   {
462      mame_timer_adjust( tp6525_delayed_timer, MAME_TIME_IN_MSEC(1), 0, time_zero );
463   }
464}
465 
466static void tp6525_irq( int level )
467{
468   LOG( "TPI6525 Interrupt: level = %d\n", level);
469   
470   if ( level )
471   {
472      if ( (CUSTOM_REG(REG_INTREQ) & INTENA_PORTS) == 0 )
473      {
474         amiga_custom_w(REG_INTREQ, 0x8000 | INTENA_PORTS, 0);
475      }
476      else
477      {
478         /* we *have to* deliver the irq, so if we can't, delay it and try again later */
479         mame_timer_adjust( tp6525_delayed_timer, MAME_TIME_IN_MSEC(1), 0, time_zero );
480      }
481   }
482}
483 
484static void cdrom_status_enabled( int level )
485{
486   /* PC3 on the 6525 */
487   tpi6525_0_irq3_level( level );
488}
489 
490static void cdrom_status_change( int level )
491{
492   /* invert */
493   level = level ? 0 : 1;
494   
495   /* PC2 on the 6525 */
496   tpi6525_0_irq2_level( level );
497}
498 
499static void cdrom_subcode_ready( int level )
500{
501   /* PC1 on the 6525 */
502   tpi6525_0_irq1_level( level );
503}
504 
505void amigacd_init( void )
506{
507   /* initialize the dmac */
508   memset( &dmac_data, 0, sizeof( dmac_data ) );
509   
510   dmac_data.dma_timer = mame_timer_alloc(dmac_dma_proc);
511   tp6525_delayed_timer = mame_timer_alloc(tp6525_delayed_irq);
512   
513   /* initialize the 6525 TPI */
514   tpi6525_0_reset();
515   
516   tpi6525[0].a.read = NULL;
517   tpi6525[0].b.read = NULL;
518   tpi6525[0].c.read = tp6525_portc_r;
519   
520   tpi6525[0].a.output = NULL;
521   tpi6525[0].b.output = tp6525_portb_w;
522   tpi6525[0].c.output = NULL;
523   
524   tpi6525[0].interrupt.output = tp6525_irq;
525   tpi6525[0].ca.output = NULL;
526   tpi6525[0].cb.output = NULL;
527   
528   /* initialize the cdrom */
529   matsucd_init();
530   matsucd_set_status_enabled_callback( cdrom_status_enabled );
531   matsucd_set_status_changed_callback( cdrom_status_change );
532   matsucd_set_subcode_ready_callback( cdrom_subcode_ready );
533   
534   /* set up DMAC with autoconfig */
535   amiga_add_autoconfig( &dmac_device );
536}
1/***************************************************************************
2
3   Amiga cdrom controller emulation
4   
5Notes:
6Many thanks to Toni Willem for all the help and information about the
7DMAC controller.
8
9***************************************************************************/
10
11#include "mame.h"
12#include "driver.h"
13#include "amiga.h"
14#include "amigacd.h"
15#include "machine/6526cia.h"
16#include "machine/wd33c93.h"
17#include "tpi6525.h"
18#include "matsucd.h"
19
20#define VERBOSE_DMAC 0
21
22#if VERBOSE_DMAC
23#define LOG logerror
24#else
25INLINE void dummy_log( const char *a, ... ) {}
26#define LOG dummy_log
27#endif
28
29/* constants */
30#define CD_SECTOR_TIME      (1000/((300*1024)/2048))   /* 2X CDROM sector time in msec (300KBps) */
31
32/***************************************************************************
33
34   DMAC
35   
36***************************************************************************/
37
38/*
39 * value to go into DAWR
40 */
41#define DAWR_ATZSC      3       /* according to A3000T service-manual */
42
43/*
44 * bits defined for CNTR
45 */
46#define CNTR_TCEN       (1<<7)  /* Terminal Count Enable */
47#define CNTR_PREST      (1<<6)  /* Perp Reset (not implemented :-((( ) */
48#define CNTR_PDMD       (1<<5)  /* Perp Device Mode Select (1=SCSI,0=XT/AT) */
49#define CNTR_INTEN      (1<<4)  /* Interrupt Enable */
50#define CNTR_DDIR       (1<<3)  /* Device Direction. 1==rd host, wr to perp */
51
52/*
53 * bits defined for ISTR
54 */
55#define ISTR_INTX       (1<<8)  /* XT/AT Interrupt pending */
56#define ISTR_INT_F      (1<<7)  /* Interrupt Follow */
57#define ISTR_INTS       (1<<6)  /* SCSI Peripheral Interrupt */
58#define ISTR_E_INT      (1<<5)  /* End-Of-Process Interrupt */
59#define ISTR_INT_P      (1<<4)  /* Interrupt Pending */
60#define ISTR_UE_INT     (1<<3)  /* Under-Run FIFO Error Interrupt */
61#define ISTR_OE_INT     (1<<2)  /* Over-Run FIFO Error Interrupt */
62#define ISTR_FF_FLG     (1<<1)  /* FIFO-Full Flag */
63#define ISTR_FE_FLG     (1<<0)  /* FIFO-Empty Flag */
64
65typedef struct
66{
67   UINT16      istr;      /* Interrupt Status Register (R) */
68    UINT16      cntr;      /* Control Register (RW) */
69   UINT32      wtc;      /* Word Transfer Count Register (RW) */
70   UINT32      acr;      /* Address Count Register (RW) */
71   UINT16      dawr;      /* DACK Width Register (W) */
72   mame_timer *dma_timer;
73} _dmac_data;
74
75static _dmac_data dmac_data;
76
77static void check_interrupts( void )
78{
79   /* if interrupts are disabled, bail */
80   if ( (dmac_data.cntr & CNTR_INTEN) == 0 )
81      return;
82   
83   /* if no interrupts are pending, bail */
84   if ( (dmac_data.istr & ISTR_INT_P) == 0 )
85      return;
86   
87   /* otherwise, generate the IRQ */
88   amiga_custom_w(REG_INTREQ, 0x8000 | INTENA_PORTS, 0);
89}
90
91static TIMER_CALLBACK(dmac_dma_proc)
92{
93   while( dmac_data.wtc > 0 )
94   {
95      UINT16   dat16;
96      UINT8   dat8;
97     
98      if ( matsucd_get_next_byte( &dat8 ) < 0 )
99         break;
100     
101      dat16 = dat8;
102               
103      if ( matsucd_get_next_byte( &dat8 ) < 0 )
104         break;
105     
106      dat16 <<= 8;
107      dat16 |= dat8;
108     
109      amiga_chip_ram_w(dmac_data.acr, dat16);
110     
111      dmac_data.acr += 2;
112      dmac_data.wtc--;
113   }
114   
115   if ( dmac_data.wtc > 0 )
116   {
117      matsucd_read_next_block();
118      mame_timer_adjust( dmac_data.dma_timer, MAME_TIME_IN_MSEC( CD_SECTOR_TIME ), 0, time_zero );
119   }
120   else
121   {
122      dmac_data.istr |= ISTR_INT_P | ISTR_E_INT;
123      check_interrupts();
124   }
125}
126
127static READ16_HANDLER( amiga_dmac_r )
128{
129   offset &= 0xff;
130
131   switch( offset )
132   {
133      case 0x20:
134      {
135         UINT8   v = dmac_data.istr;
136         LOG( "DMAC: PC=%08x - ISTR Read(%04x)\n", activecpu_get_pc(), dmac_data.istr );
137         
138         dmac_data.istr &= ~0x0f;
139         return v;
140      }
141      break;
142     
143      case 0x21:
144      {
145         LOG( "DMAC: PC=%08x - CNTR Read(%04x)\n", activecpu_get_pc(), dmac_data.cntr );
146         return dmac_data.cntr;
147      }
148      break;
149     
150      case 0x40:   /* wtc hi */
151      {
152         LOG( "DMAC: PC=%08x - WTC HI Read\n", activecpu_get_pc() );
153         return (dmac_data.wtc >> 16);
154      }
155      break;
156         
157      case 0x41:   /* wtc lo */
158      {
159         LOG( "DMAC: PC=%08x - WTC LO Read\n", activecpu_get_pc() );
160         return dmac_data.wtc;
161      }
162      break;
163     
164      case 0x42:   /* acr hi */
165      {
166         LOG( "DMAC: PC=%08x - ACR HI Read\n", activecpu_get_pc() );
167         return (dmac_data.acr >> 16);
168      }
169      break;
170         
171      case 0x43:   /* acr lo */
172      {
173         LOG( "DMAC: PC=%08x - ACR LO Read\n", activecpu_get_pc() );
174         return dmac_data.acr;
175      }
176      break;
177
178      case 0x48:   /* wd33c93 SCSI expansion */
179      case 0x49:
180      {
181         LOG( "DMAC: PC=%08x - WD33C93 Read(%d)\n", activecpu_get_pc(), offset & 1 );
182         return 0x00;   /* Not available without SCSI expansion */
183      }
184      break;
185     
186      case 0x50:
187      {
188         LOG( "DMAC: PC=%08x - CDROM RESP Read\n", activecpu_get_pc() );
189         return matsucd_response_r();
190      }
191      break;
192     
193      case 0x51:   /* XT IO */
194      case 0x52:
195      case 0x53:
196      {
197         LOG( "DMAC: PC=%08x - XT IO Read(%d)\n", activecpu_get_pc(), (offset & 3)-1 );
198         return 0xff;
199      }
200      break;
201     
202      case 0x58:   /* TPI6525 */
203      case 0x59:
204      case 0x5A:
205      case 0x5B:
206      case 0x5C:
207      case 0x5D:
208      case 0x5E:
209      case 0x5F:
210      case 0x60:
211      case 0x61:
212      case 0x62:
213      case 0x63:
214      case 0x64:
215      case 0x65:
216      case 0x66:
217      case 0x67:
218      {
219         LOG( "DMAC: PC=%08x - TPI6525 Read(%d)\n", activecpu_get_pc(), (offset - 0x58) );
220         return tpi6525_0_port_r(offset - 0x58);
221      }
222      break;
223     
224      case 0x70:   /* DMA start strobe */
225      {
226         LOG( "DMAC: PC=%08x - DMA Start Strobe\n", activecpu_get_pc() );
227         mame_timer_adjust( dmac_data.dma_timer, MAME_TIME_IN_MSEC( CD_SECTOR_TIME ), 0, time_zero );
228      }
229      break;
230     
231      case 0x71:   /* DMA stop strobe */
232      {
233         LOG( "DMAC: PC=%08x - DMA Stop Strobe\n", activecpu_get_pc() );
234         mame_timer_reset( dmac_data.dma_timer, time_never );
235      }
236      break;
237     
238      case 0x72:   /* Clear IRQ strobe */
239      {
240         LOG( "DMAC: PC=%08x - IRQ Clear Strobe\n", activecpu_get_pc() );
241         dmac_data.istr &= ~ISTR_INT_P;
242      }
243      break;
244     
245      case 0x74:   /* Flush strobe */
246      {
247         LOG( "DMAC: PC=%08x - Flush Strobe\n", activecpu_get_pc() );
248         dmac_data.istr |= ISTR_FE_FLG;
249      }
250      break;
251           
252      default:
253         logerror( "DMAC-READ: PC=%08x, offset = %02x\n", activecpu_get_pc(), offset );
254      break;
255   }
256   
257   return 0;
258}
259
260static WRITE16_HANDLER( amiga_dmac_w )
261{
262   offset &= 0xff;
263
264   switch( offset )
265   {
266      case 0x21:   /* control write */
267      {
268         LOG( "DMAC: PC=%08x - CNTR Write(%04x)\n", activecpu_get_pc(), data );
269         dmac_data.cntr = data;
270         check_interrupts();
271      }
272      break;
273     
274      case 0x40:   /* wtc hi */
275      {
276         LOG( "DMAC: PC=%08x - WTC HI Write - data = %04x\n", activecpu_get_pc(), data );
277         dmac_data.wtc &= 0x0000ffff;
278         dmac_data.wtc |= ((UINT32)data) << 16;
279      }
280      break;
281         
282      case 0x41:   /* wtc lo */
283      {
284         LOG( "DMAC: PC=%08x - WTC LO Write - data = %04x\n", activecpu_get_pc(), data );
285         dmac_data.wtc &= 0xffff0000;
286         dmac_data.wtc |= data;
287      }
288      break;
289     
290      case 0x42:   /* acr hi */
291      {
292         LOG( "DMAC: PC=%08x - ACR HI Write - data = %04x\n", activecpu_get_pc(), data );
293         dmac_data.acr &= 0x0000ffff;
294         dmac_data.acr |= ((UINT32)data) << 16;
295      }
296      break;
297         
298      case 0x43:   /* acr lo */
299      {
300         LOG( "DMAC: PC=%08x - ACR LO Write - data = %04x\n", activecpu_get_pc(), data );
301         dmac_data.acr &= 0xffff0000;
302         dmac_data.acr |= data;
303      }
304      break;
305     
306      case 0x47:   /* dawr */
307      {
308         LOG( "DMAC: PC=%08x - DAWR Write - data = %04x\n", activecpu_get_pc(), data );
309         dmac_data.dawr = data;
310      }
311      break;
312     
313      case 0x48:   /* wd33c93 SCSI expansion */
314      case 0x49:
315      {
316         LOG( "DMAC: PC=%08x - WD33C93 Write(%d) - data = %04x\n", activecpu_get_pc(), offset & 1, data );
317         /* Not available without SCSI expansion */
318      }
319      break;
320     
321      case 0x50:
322      {
323         LOG( "DMAC: PC=%08x - CDROM CMD Write - data = %04x\n", activecpu_get_pc(), data );
324         matsucd_command_w( data );
325      }
326      break;
327     
328      case 0x58:   /* TPI6525 */
329      case 0x59:
330      case 0x5A:
331      case 0x5B:
332      case 0x5C:
333      case 0x5D:
334      case 0x5E:
335      case 0x5F:
336      case 0x60:
337      case 0x61:
338      case 0x62:
339      case 0x63:
340      case 0x64:
341      case 0x65:
342      case 0x66:
343      case 0x67:
344      {
345         LOG( "DMAC: PC=%08x - TPI6525 Write(%d) - data = %04x\n", activecpu_get_pc(), (offset - 0x58), data );
346         tpi6525_0_port_w(offset - 0x58, data);
347      }
348      break;
349     
350      case 0x70:   /* DMA start strobe */
351      {
352         LOG( "DMAC: PC=%08x - DMA Start Strobe\n", activecpu_get_pc() );
353         mame_timer_adjust( dmac_data.dma_timer, MAME_TIME_IN_MSEC( CD_SECTOR_TIME ), 0, time_zero );
354      }
355      break;
356     
357      case 0x71:   /* DMA stop strobe */
358      {
359         LOG( "DMAC: PC=%08x - DMA Stop Strobe\n", activecpu_get_pc() );
360         mame_timer_reset( dmac_data.dma_timer, time_never );
361      }
362      break;
363     
364      case 0x72:   /* Clear IRQ strobe */
365      {
366         LOG( "DMAC: PC=%08x - IRQ Clear Strobe\n", activecpu_get_pc() );
367         dmac_data.istr &= ~ISTR_INT_P;
368      }
369      break;
370     
371      case 0x74:   /* Flush Strobe */
372      {
373         LOG( "DMAC: PC=%08x - Flush Strobe\n", activecpu_get_pc() );
374         dmac_data.istr |= ISTR_FE_FLG;
375      }
376      break;
377     
378      default:
379         logerror( "DMAC-WRITE: PC=%08x, offset = %02x, data = %04x\n", activecpu_get_pc(), offset, data );
380      break;
381   }
382}
383
384/***************************************************************************
385
386   Autoconfig
387   
388***************************************************************************/
389
390static void   dmac_install(offs_t base)
391{
392   memory_install_read16_handler(0, ADDRESS_SPACE_PROGRAM, base, base + 0xFFFF, 0, 0, amiga_dmac_r);
393   memory_install_write16_handler(0, ADDRESS_SPACE_PROGRAM, base, base + 0xFFFF, 0, 0, amiga_dmac_w);
394}
395
396static void   dmac_uninstall(offs_t base)
397{
398   memory_install_read16_handler(0, ADDRESS_SPACE_PROGRAM, base, base + 0xFFFF, 0, 0, MRA16_UNMAP);
399   memory_install_write16_handler(0, ADDRESS_SPACE_PROGRAM, base, base + 0xFFFF, 0, 0, MWA16_UNMAP);
400}
401
402static amiga_autoconfig_device dmac_device =
403{
404   0,            /* link into free memory list */
405   0,            /* ROM vector offset valid */
406   0,            /* multiple devices on card */
407   1,            /* number of 64k pages */
408   3,            /* product number (DMAC) */
409   0,            /* prefer 8MB address space */
410   0,            /* can be shut up */
411   0x0202,         /* manufacturers number (Commodore) */
412   0,            /* serial number */
413   0,            /* ROM vector offset */
414   NULL,         /* interrupt control read */
415   NULL,         /* interrupt control write */
416   dmac_install,   /* memory installation */
417   dmac_uninstall   /* memory uninstallation */
418};
419
420/***************************************************************************
421
422   TPI6525
423   
424***************************************************************************/
425
426static int tp6525_portc_r( void )
427{
428   int   ret = 0;
429   
430   if ( (tpi6525[0].c.ddr & 0x04) == 0 ) /* if pin 2 is set to input */
431   {
432      ret |= matsucd_stch_r() ? 0x00 : 0x04;   /* read status change signal */
433   }
434   
435   if ( (tpi6525[0].c.ddr & 0x08) == 0 ) /* if pin 3 is set to input */
436      ret |= matsucd_sten_r() ? 0x08 : 0x00;   /* read enable signal */
437   
438   return ret;
439}
440
441static void tp6525_portb_w( int data )
442{
443   if ( tpi6525[0].b.ddr & 0x01 ) /* if pin 0 is set to output */
444      matsucd_cmd_w( data & 1 ); /* write to the /CMD signal */
445   
446   if ( tpi6525[0].b.ddr & 0x02 ) /* if pin 1 is set to output */
447      matsucd_enable_w( data & 2 ); /* write to the /ENABLE signal */
448}
449
450static mame_timer *tp6525_delayed_timer;
451
452static TIMER_CALLBACK(tp6525_delayed_irq)
453{
454   (void)param;
455   
456   if ( (CUSTOM_REG(REG_INTREQ) & INTENA_PORTS) == 0 )
457   {
458      amiga_custom_w(REG_INTREQ, 0x8000 | INTENA_PORTS, 0);
459   }
460   else
461   {
462      mame_timer_adjust( tp6525_delayed_timer, MAME_TIME_IN_MSEC(1), 0, time_zero );
463   }
464}
465
466static void tp6525_irq( int level )
467{
468   LOG( "TPI6525 Interrupt: level = %d\n", level);
469   
470   if ( level )
471   {
472      if ( (CUSTOM_REG(REG_INTREQ) & INTENA_PORTS) == 0 )
473      {
474         amiga_custom_w(REG_INTREQ, 0x8000 | INTENA_PORTS, 0);
475      }
476      else
477      {
478         /* we *have to* deliver the irq, so if we can't, delay it and try again later */
479         mame_timer_adjust( tp6525_delayed_timer, MAME_TIME_IN_MSEC(1), 0, time_zero );
480      }
481   }
482}
483
484static void cdrom_status_enabled( int level )
485{
486   /* PC3 on the 6525 */
487   tpi6525_0_irq3_level( level );
488}
489
490static void cdrom_status_change( int level )
491{
492   /* invert */
493   level = level ? 0 : 1;
494   
495   /* PC2 on the 6525 */
496   tpi6525_0_irq2_level( level );
497}
498
499static void cdrom_subcode_ready( int level )
500{
501   /* PC1 on the 6525 */
502   tpi6525_0_irq1_level( level );
503}
504
505void amigacd_init( void )
506{
507   /* initialize the dmac */
508   memset( &dmac_data, 0, sizeof( dmac_data ) );
509   
510   dmac_data.dma_timer = mame_timer_alloc(dmac_dma_proc);
511   tp6525_delayed_timer = mame_timer_alloc(tp6525_delayed_irq);
512   
513   /* initialize the 6525 TPI */
514   tpi6525_0_reset();
515   
516   tpi6525[0].a.read = NULL;
517   tpi6525[0].b.read = NULL;
518   tpi6525[0].c.read = tp6525_portc_r;
519   
520   tpi6525[0].a.output = NULL;
521   tpi6525[0].b.output = tp6525_portb_w;
522   tpi6525[0].c.output = NULL;
523   
524   tpi6525[0].interrupt.output = tp6525_irq;
525   tpi6525[0].ca.output = NULL;
526   tpi6525[0].cb.output = NULL;
527   
528   /* initialize the cdrom */
529   matsucd_init();
530   matsucd_set_status_enabled_callback( cdrom_status_enabled );
531   matsucd_set_status_changed_callback( cdrom_status_change );
532   matsucd_set_subcode_ready_callback( cdrom_subcode_ready );
533   
534   /* set up DMAC with autoconfig */
535   amiga_add_autoconfig( &dmac_device );
536}
src/mess/machine/amigacd.h
r882r883
1#ifndef AMIGACD_H
2#define AMIGACD_H
3 
4void amigacd_init( void );
5 
6#endif /* AMIGACD_H */
1#ifndef AMIGACD_H
2#define AMIGACD_H
3
4void amigacd_init( void );
5
6#endif /* AMIGACD_H */
src/mess/machine/sst39vfx.c
r882r883
1/*
2 
3   SST Multi-Purpose Flash (MPF)
4 
5   (c) 2001-2007 Tim Schuerewegen
6 
7   SST39VF020  - 256 KByte
8   SST39VF400A - 512 Kbyte
9 
10*/
11 
12#include "sst39vfx.h"
13 
14#define LOG_LEVEL  1
15#define _logerror(level,...)  if (LOG_LEVEL > level) logerror(__VA_ARGS__)
16 
17typedef struct
18{
19   UINT8 *data;
20   UINT32 size;
21   UINT8 swap;
22} SST39VFX;
23 
24static SST39VFX flash;
25 
26void sst39vfx_state_save( void);
27 
28void sst39vfx_init( int type, int cpu_datawidth, int cpu_endianess)
29{
30   _logerror( 0, "sst39vfx_init (%d)\n", type);
31   memset( &flash, 0, sizeof( flash));
32   switch (type)
33   {
34      case SST39VF020  : flash.size = 256 * 1024; break;
35      case SST39VF400A : flash.size = 512 * 1024; break;
36   }
37   flash.data = (UINT8*)malloc( flash.size);
38#ifdef LSB_FIRST
39   if (cpu_endianess != CPU_IS_LE) flash.swap = cpu_datawidth / 8; else flash.swap = 0;
40#else
41   if (cpu_endianess != CPU_IS_BE) flash.swap = cpu_datawidth / 8; else flash.swap = 0;
42#endif
43   sst39vfx_state_save();
44}
45 
46void sst39vfx_exit( void)
47{
48   _logerror( 0, "sst39vfx_exit\n");
49   free( flash.data);
50}
51 
52void sst39vfx_reset( void)
53{
54   _logerror( 0, "sst39vfx_reset\n");
55}
56 
57void sst39vfx_state_save( void)
58{
59   const char *name = "sst39vfx";
60   state_save_register_item_pointer( name, 0, flash.data, flash.size);
61   state_save_register_item( name, 0, flash.swap);
62}
63 
64UINT8* sst39vfx_get_base( void)
65{
66   return flash.data;
67}
68 
69UINT32 sst39vfx_get_size( void)
70{
71   return flash.size;
72}
73 
74/*
75#define OFFSET_SWAP(offset,width) (offset & (~(width - 1))) | (width - 1 - (offset & (width - 1)))
76*/
77 
78/*
79READ8_HANDLER( sst39vfx_r )
80{
81   _logerror( 1, "sst39vfx_r (%08X)\n", offset);
82   if (flash.swap) offset = OFFSET_SWAP( offset, flash.swap);
83   return flash.data[offset];
84}
85*/
86 
87/*
88WRITE8_HANDLER( sst39vfx_w )
89{
90   _logerror( 1, "sst39vfx_w (%08X/%02X)\n", offset, data);
91   if (flash.swap) offset = OFFSET_SWAP( offset, flash.swap);
92   flash.data[offset] = data;
93}
94*/
95 
96void sst39vfx_swap( void)
97{
98   int i, j;
99   UINT8 *base, temp[8];
100   base = flash.data;
101   for (i=0;i<flash.size;i+=flash.swap)
102   {
103      memcpy( temp, base, flash.swap);
104      for (j=flash.swap-1;j>=0;j--) *base++ = temp[j];
105   }
106}
107 
108void sst39vfx_load( mame_file *file)
109{
110   _logerror( 0, "sst39vfx_load (%p)\n", file);
111   mame_fread( file, flash.data, flash.size);
112   if (flash.swap) sst39vfx_swap();
113}
114 
115void sst39vfx_save( mame_file *file)
116{
117   _logerror( 0, "sst39vfx_save (%p)\n", file);
118   if (flash.swap) sst39vfx_swap();
119   mame_fwrite( file, flash.data, flash.size);
120   if (flash.swap) sst39vfx_swap();
121}
122 
123/*
124NVRAM_HANDLER( sst39vfx )
125{
126   _logerror( 0, "nvram_handler_sst39vfx (%p/%d)\n", file, read_or_write);
127   if (read_or_write)
128   {
129      sst39vfx_save( file);
130   }
131   else
132   {
133      if (file)
134      {
135         sst39vfx_load( file);
136      }
137      else
138      {
139         memset( flash.data, 0xFF, flash.size);
140      }
141   }
142}
143*/
1/*
2
3   SST Multi-Purpose Flash (MPF)
4
5   (c) 2001-2007 Tim Schuerewegen
6
7   SST39VF020  - 256 KByte
8   SST39VF400A - 512 Kbyte
9
10*/
11
12#include "sst39vfx.h"
13
14#define LOG_LEVEL  1
15#define _logerror(level,...)  if (LOG_LEVEL > level) logerror(__VA_ARGS__)
16
17typedef struct
18{
19   UINT8 *data;
20   UINT32 size;
21   UINT8 swap;
22} SST39VFX;
23
24static SST39VFX flash;
25
26void sst39vfx_state_save( void);
27
28void sst39vfx_init( int type, int cpu_datawidth, int cpu_endianess)
29{
30   _logerror( 0, "sst39vfx_init (%d)\n", type);
31   memset( &flash, 0, sizeof( flash));
32   switch (type)
33   {
34      case SST39VF020  : flash.size = 256 * 1024; break;
35      case SST39VF400A : flash.size = 512 * 1024; break;
36   }
37   flash.data = (UINT8*)malloc( flash.size);
38#ifdef LSB_FIRST
39   if (cpu_endianess != CPU_IS_LE) flash.swap = cpu_datawidth / 8; else flash.swap = 0;
40#else
41   if (cpu_endianess != CPU_IS_BE) flash.swap = cpu_datawidth / 8; else flash.swap = 0;
42#endif
43   sst39vfx_state_save();
44}
45
46void sst39vfx_exit( void)
47{
48   _logerror( 0, "sst39vfx_exit\n");
49   free( flash.data);
50}
51
52void sst39vfx_reset( void)
53{
54   _logerror( 0, "sst39vfx_reset\n");
55}
56
57void sst39vfx_state_save( void)
58{
59   const char *name = "sst39vfx";
60   state_save_register_item_pointer( name, 0, flash.data, flash.size);
61   state_save_register_item( name, 0, flash.swap);
62}
63
64UINT8* sst39vfx_get_base( void)
65{
66   return flash.data;
67}
68
69UINT32 sst39vfx_get_size( void)
70{
71   return flash.size;
72}
73
74/*
75#define OFFSET_SWAP(offset,width) (offset & (~(width - 1))) | (width - 1 - (offset & (width - 1)))
76*/
77
78/*
79READ8_HANDLER( sst39vfx_r )
80{
81   _logerror( 1, "sst39vfx_r (%08X)\n", offset);
82   if (flash.swap) offset = OFFSET_SWAP( offset, flash.swap);
83   return flash.data[offset];
84}
85*/
86
87/*
88WRITE8_HANDLER( sst39vfx_w )
89{
90   _logerror( 1, "sst39vfx_w (%08X/%02X)\n", offset, data);
91   if (flash.swap) offset = OFFSET_SWAP( offset, flash.swap);
92   flash.data[offset] = data;
93}
94*/
95
96void sst39vfx_swap( void)
97{
98   int i, j;
99   UINT8 *base, temp[8];
100   base = flash.data;
101   for (i=0;i<flash.size;i+=flash.swap)
102   {
103      memcpy( temp, base, flash.swap);
104      for (j=flash.swap-1;j>=0;j--) *base++ = temp[j];
105   }
106}
107
108void sst39vfx_load( mame_file *file)
109{
110   _logerror( 0, "sst39vfx_load (%p)\n", file);
111   mame_fread( file, flash.data, flash.size);
112   if (flash.swap) sst39vfx_swap();
113}
114
115void sst39vfx_save( mame_file *file)
116{
117   _logerror( 0, "sst39vfx_save (%p)\n", file);
118   if (flash.swap) sst39vfx_swap();
119   mame_fwrite( file, flash.data, flash.size);
120   if (flash.swap) sst39vfx_swap();
121}
122
123/*
124NVRAM_HANDLER( sst39vfx )
125{
126   _logerror( 0, "nvram_handler_sst39vfx (%p/%d)\n", file, read_or_write);
127   if (read_or_write)
128   {
129      sst39vfx_save( file);
130   }
131   else
132   {
133      if (file)
134      {
135         sst39vfx_load( file);
136      }
137      else
138      {
139         memset( flash.data, 0xFF, flash.size);
140      }
141   }
142}
143*/
src/mess/machine/sst39vfx.h
r882r883
1/*
2 
3   SST Multi-Purpose Flash (MPF)
4 
5   (c) 2001-2007 Tim Schuerewegen
6 
7   SST39VF020  - 256 KByte
8   SST39VF400A - 512 Kbyte
9 
10*/
11 
12#ifndef _SST39VFX_H_
13#define _SST39VFX_H_
14 
15#include "driver.h"
16 
17enum
18{
19   SST39VF020,
20   SST39VF400A
21};
22 
23// init/exit/reset
24void sst39vfx_init( int type, int cpu_datawidth, int cpu_endianess);
25void sst39vfx_exit( void);
26void sst39vfx_reset( void);
27 
28// get base/size
29UINT8* sst39vfx_get_base( void);
30UINT32 sst39vfx_get_size( void);
31 
32// read/write handler
33/*
34READ8_HANDLER( sst39vfx_r );
35WRITE8_HANDLER( sst39vfx_w );
36*/
37 
38// load/save
39void sst39vfx_load( mame_file *file);
40void sst39vfx_save( mame_file *file);
41 
42// non-volatile ram handler
43/*
44NVRAM_HANDLER( sst39vfx );
45*/
46 
47#endif
1/*
2
3   SST Multi-Purpose Flash (MPF)
4
5   (c) 2001-2007 Tim Schuerewegen
6
7   SST39VF020  - 256 KByte
8   SST39VF400A - 512 Kbyte
9
10*/
11
12#ifndef _SST39VFX_H_
13#define _SST39VFX_H_
14
15#include "driver.h"
16
17enum
18{
19   SST39VF020,
20   SST39VF400A
21};
22
23// init/exit/reset
24void sst39vfx_init( int type, int cpu_datawidth, int cpu_endianess);
25void sst39vfx_exit( void);
26void sst39vfx_reset( void);
27
28// get base/size
29UINT8* sst39vfx_get_base( void);
30UINT32 sst39vfx_get_size( void);
31
32// read/write handler
33/*
34READ8_HANDLER( sst39vfx_r );
35WRITE8_HANDLER( sst39vfx_w );
36*/
37
38// load/save
39void sst39vfx_load( mame_file *file);
40void sst39vfx_save( mame_file *file);
41
42// non-volatile ram handler
43/*
44NVRAM_HANDLER( sst39vfx );
45*/
46
47#endif
src/mess/machine/matsucd.c
r882r883
1/***************************************************************************
2 
3   Matsushita/Panasonic CDR521/522 type CDROM drive emulation
4   
5Notes:
6This version implements the drive found in Amiga CDTV. There are
7different drives supporting this command-set (look in the sbpcd driver
8in Linux for examples). Most drives support the exact same command
9structure, but the command numbers differ. Eventually this driver
10can be expanded with support for the other drives as needed.
11 
12***************************************************************************/
13 
14#include "mame.h"
15#include "driver.h"
16#include "devices/chd_cd.h"
17#include "sound/cdda.h"
18 
19 
20#define MATSU_STATUS_READY      ( 1 << 0 )   /* driver ready */
21#define MATSU_STATUS_DOORLOCKED   ( 1 << 1 )   /* door locked */
22#define MATSU_STATUS_PLAYING   ( 1 << 2 )   /* drive playing */
23#define MATSU_STATUS_SUCCESS   ( 1 << 3 )   /* last command was succesful */
24#define MATSU_STATUS_ERROR      ( 1 << 4 )   /* last command failed */
25#define MATSU_STATUS_MOTOR      ( 1 << 5 )   /* spinning */
26#define MATSU_STATUS_MEDIA      ( 1 << 6 )   /* media present (in caddy or tray) */
27#define MATSU_STATUS_DOORCLOSED   ( 1 << 7 )   /* tray status */
28 
29typedef struct
30{
31   UINT8   enabled;      /* /ENABLE - Unit enabled */
32   UINT8   cmd_signal;      /* /CMD - Command mode    */
33   UINT8   stch_signal;   /* /STCH - Status Changed */
34   UINT8   sten_signal;   /* /STEN - Status Enabled */
35   UINT8   scor_signal;   /* /STEN - Subcode Ready */
36   UINT8   input[16];
37   UINT8   input_pos;
38   UINT8   output[16];
39   UINT8   output_pos;
40   UINT8   output_len;
41   UINT8   status;
42   UINT8   motor;
43   UINT16   sector_size;
44   UINT32   lba;
45   UINT16   num_blocks;
46   UINT16   xfer_offset;
47   UINT8   sector_buffer[CD_MAX_SECTOR_DATA];
48   UINT8   cdda_set;
49   void (*sten_cb)( int level );   /* Status enabled callback */
50   void (*stch_cb)( int level );   /* Status changed callback */
51   void (*scor_cb)( int level );   /* Subcode ready callback */
52   cdrom_file *cdrom;
53   mame_timer *frame_timer;
54} matsucd;
55 
56static matsucd cd;
57 
58#define MSF2LBA(msf) (((msf >> 16) & 0xff) * 60 * 75 + ((msf >> 8) & 0xff) * 75 + ((msf >> 0) & 0xff))
59#define LBA2MSF(lba) (((lba / (75 * 60)) << 16) | (((lba / 75) % 60) << 8) | (lba % 75))
60 
61static TIMER_CALLBACK(matsu_subcode_proc);
62 
63void matsucd_init( void )
64{
65   memset(&cd, 0, sizeof( matsucd ) );
66   
67   cd.cdrom = mess_cd_get_cdrom_file_by_number(0);
68   
69   cd.frame_timer = mame_timer_alloc(matsu_subcode_proc);
70   
71   cd.stch_signal = 1;
72}
73 
74void matsucd_set_status_enabled_callback( void (*sten_cb)( int level ) )
75{
76   /* add the callback for status enabled signal */
77   cd.sten_cb = sten_cb;
78}
79 
80void matsucd_set_status_changed_callback( void (*stch_cb)( int level ) )
81{
82   /* add the callback for status changed signal */
83   cd.stch_cb = stch_cb;
84}
85 
86void matsucd_set_subcode_ready_callback( void (*scor_cb)( int level ) )
87{
88   /* add the callback for subcode ready signal */
89   cd.scor_cb = scor_cb;
90}
91 
92static int matsucd_getsector_type( void )
93{
94   switch( cd.sector_size )
95   {
96      case 2048: return CD_TRACK_MODE1; break;
97      case 2324: return CD_TRACK_MODE2_FORM2; break;
98      case 2336: return CD_TRACK_MODE2; break;
99      case 2352: return CD_TRACK_MODE2_RAW; break;
100       
101      default: logerror( "MATSUCD: Sector size %d unsupported!\n", cd.sector_size ); break;
102   }
103   
104   return CD_TRACK_RAW_DONTCARE;
105}
106 
107void matsucd_read_next_block( void )
108{
109   cd.xfer_offset = 0;
110   
111   if ( cd.num_blocks )
112   {
113      cd.lba++;
114      cd.num_blocks--;
115       
116      if (!cdrom_read_data(cd.cdrom, cd.lba, cd.sector_buffer, matsucd_getsector_type()))
117      {
118         logerror( "MATSUCD - Warning: Read error on CD!\n" );
119      }
120   }
121}
122 
123int matsucd_get_next_byte( UINT8 *data )
124{
125   /* no more data to read on this sector */
126   if ( cd.xfer_offset >= cd.sector_size )
127      return -1;
128   
129   if ( data )
130      *data = cd.sector_buffer[cd.xfer_offset++];
131   
132   return 0;   
133}
134 
135static void matsucd_cdda_stop( void )
136{
137   int cddanum = cdda_num_from_cdrom(cd.cdrom);
138   
139   if (cddanum != -1)
140   {
141      cdda_stop_audio(cddanum);
142      mame_timer_reset( cd.frame_timer, time_never );
143   }
144}
145 
146static void matsucd_cdda_play( UINT32 lba, UINT32 num_blocks )
147{
148   int cddanum = cdda_num_from_cdrom(cd.cdrom);
149   if (cddanum != -1)
150   {
151      cdda_start_audio(cddanum, lba, num_blocks);
152      mame_timer_adjust( cd.frame_timer, MAME_TIME_IN_HZ( 75 ), 0, time_zero );
153   }
154}
155 
156static void matsucd_cdda_pause( int pause )
157{
158   int cddanum = cdda_num_from_cdrom(cd.cdrom);
159   if (cddanum != -1)
160   {
161      cdda_pause_audio(cddanum, pause);
162       
163      if ( pause )
164      {
165         mame_timer_reset( cd.frame_timer, time_never );
166      }
167      else
168      {
169         mame_timer_adjust( cd.frame_timer, MAME_TIME_IN_HZ( 75 ), 0, time_zero );
170      }
171   }
172}
173 
174static UINT8 matsucd_cdda_getstatus( UINT32 *lba )
175{
176   int cddanum = cdda_num_from_cdrom(cd.cdrom);
177   
178   if ( lba ) *lba = 0;
179   
180   if (cddanum != -1)
181   {
182      if (cdda_audio_active(cddanum))
183      {
184         if ( lba ) *lba = cdda_get_audio_lba(cddanum);
185             
186         if (cdda_audio_paused(cddanum))
187         {
188            return 0x12;   /* audio paused */
189         }
190         else
191         {
192            return 0x11;   /* audio in progress */
193         }
194      }
195      else if (cdda_audio_ended(cddanum))
196      {
197         return 0x13;   /* audio ended */
198      }
199   }
200   
201   return 0x15;   /* no audio status */
202}
203 
204void matsucd_enable_w( int level )
205{
206   cd.enabled = ( level ) ? 0 : 1;
207}
208 
209void matsucd_cmd_w( int level )
210{
211   cd.cmd_signal = ( level ) ? 0 : 1;
212}
213 
214int matsucd_stch_r( void )
215{
216   return cd.stch_signal ? 0 : 1;
217}
218 
219int matsucd_sten_r( void )
220{
221   return cd.sten_signal ? 0 : 1;
222}
223 
224int matsucd_scor_r( void )
225{
226   return cd.scor_signal ? 0 : 1;
227}
228 
229static void update_status_enable( int level )
230{
231   cd.sten_signal = level;
232   
233   if ( cd.sten_cb )
234   {
235      (*cd.sten_cb)(cd.sten_signal);
236   }
237}
238 
239static void update_status_changed( int level )
240{
241   cd.stch_signal = level;
242   
243   if ( cd.stch_cb )
244   {
245      (*cd.stch_cb)(cd.stch_signal);
246   }
247}
248 
249static void update_subcode_ready( int level )
250{
251   cd.scor_signal = level;
252   
253   if ( cd.scor_cb )
254   {
255      (*cd.scor_cb)(cd.scor_signal);
256   }
257}
258 
259static TIMER_CALLBACK(matsucd_set_status_end)
260{
261   update_status_changed( 1 );
262}
263 
264static void matsucd_set_status( UINT8 status )
265{
266   if ( status != cd.status )
267   {
268      cd.status = status;
269       
270      if ( cd.stch_signal != 0 )
271      {
272         update_status_changed( 0 );
273         mame_timer_set( MAME_TIME_IN_MSEC(1), 0, matsucd_set_status_end );
274      }
275   }
276}
277 
278static TIMER_CALLBACK(matsu_subcode_proc)
279{
280   int cddanum = cdda_num_from_cdrom(cd.cdrom);
281   
282   (void)param;
283   
284   if (cddanum != -1)
285   {
286      UINT8   s = matsucd_cdda_getstatus(NULL);
287      UINT8   newstatus = cd.status;
288       
289      if ( s == 0x11 || s == 0x12 )
290      {
291         if ( s == 0x11 )
292         {
293            update_subcode_ready( 1 );
294            update_subcode_ready( 0 );
295         }
296         
297         newstatus |= MATSU_STATUS_PLAYING;
298         
299         mame_timer_adjust( cd.frame_timer, MAME_TIME_IN_HZ( 75 ), 0, time_zero );
300      }
301      else
302      {
303         newstatus &= ~MATSU_STATUS_PLAYING;
304      }
305       
306      matsucd_set_status( newstatus );
307   }
308}
309 
310static void matsucd_command_error( void )
311{
312   UINT8   newstatus = cd.status;
313       
314   newstatus &= ~MATSU_STATUS_SUCCESS;
315   newstatus |= MATSU_STATUS_ERROR;
316   
317   matsucd_set_status( newstatus );
318}
319 
320static void matsucd_complete_cmd( UINT8 len )
321{
322   UINT8   newstatus = cd.status;
323   
324   cd.input_pos = 0;
325   cd.output_pos = 0;
326   cd.output_len = len;
327   
328   newstatus &= ~MATSU_STATUS_ERROR;
329   newstatus |= MATSU_STATUS_SUCCESS;
330   
331   matsucd_set_status( newstatus );
332   
333   update_status_enable( 1 );
334   update_status_enable( 0 );
335}
336 
337UINT8 matsucd_response_r( void )
338{
339   UINT8   v = cd.output[cd.output_pos++];
340   
341   if ( cd.output_pos < cd.output_len )
342   {
343      update_status_enable( 1 );
344      update_status_enable( 0 );
345   }
346   
347   return v;
348}
349 
350void matsucd_command_w( UINT8 data )
351{
352   UINT8   cmd;
353   
354   /* make sure we're enabled */
355   if ( cd.enabled == 0 )
356      return;
357   
358   /* make sure /CMD is asserted */
359   if ( cd.cmd_signal == 0 )
360      return;
361   
362   if ( cd.cdda_set == 0 )
363   {
364      if ( cd.cdrom )
365         cdda_set_cdrom(0, cd.cdrom);
366       
367      cd.cdda_set = 1;
368   }
369   
370   cd.input[cd.input_pos++] = data;
371 
372   cmd = cd.input[0];
373   
374   switch( cmd )
375   {
376      case 0x01:   /* seek */
377      {
378         if ( cd.input_pos < 7 )
379            return;
380             
381         /* stop CDDA audio if necessary */
382         matsucd_cdda_stop();
383         
384         cd.motor = 1;
385                   
386         memset( cd.output, 0, 6 );
387         matsucd_complete_cmd( 0 );
388      }
389      break;
390       
391      case 0x02:   /* read sectors */
392      {
393         if ( cd.input_pos < 7 )
394            return;
395         
396         /* stop CDDA audio if necessary */
397         matsucd_cdda_stop();
398             
399         /* LBA */
400         cd.lba = cd.input[1];
401         cd.lba <<= 8;
402         cd.lba |= cd.input[2];
403         cd.lba <<= 8;
404         cd.lba |= cd.input[3];
405         
406         /* Number of blocks */
407         cd.num_blocks = cd.input[4];
408         cd.num_blocks <<= 8;
409         cd.num_blocks |= cd.input[5];
410         
411         /* Reset transfer count */
412         cd.xfer_offset = 0;
413         
414         /* go ahead and cache the first block */
415         if (!cdrom_read_data(cd.cdrom, cd.lba, cd.sector_buffer, matsucd_getsector_type()))
416         {
417            logerror( "MATSUCD - Warning: Read error on CD!\n" );
418            matsucd_command_error();
419            return;
420         }
421         
422         cd.motor = 1;
423                   
424         memset( cd.output, 0, 6 );
425         matsucd_complete_cmd( 0 );
426      }
427      break;
428       
429      case 0x04:   /* motor on */
430      {
431         if ( cd.input_pos < 7 )
432            return;
433             
434         cd.motor = 1;
435                   
436         memset( cd.output, 0, 6 );
437         matsucd_complete_cmd( 0 );
438      }
439      break;
440       
441      case 0x05:   /* motor off */
442      {
443         if ( cd.input_pos < 7 )
444            return;
445             
446         /* stop CDDA audio if necessary */
447         matsucd_cdda_stop();
448         
449         cd.motor = 0;
450                   
451         memset( cd.output, 0, 6 );
452         matsucd_complete_cmd( 0 );
453      }
454      break;
455       
456      case 0x09:   /* play audio cd, LBA mode */
457      {
458         UINT32   lba, numblocks;
459         
460         if ( cd.input_pos < 7 )
461            return;
462         
463         lba = cd.input[1];
464         lba <<= 8;
465         lba |= cd.input[2];
466         lba <<= 8;
467         lba |= cd.input[3];
468         
469         numblocks = cd.input[4];
470         numblocks <<= 8;
471         numblocks |= cd.input[5];
472         numblocks <<= 8;
473         numblocks |= cd.input[6];
474         
475         matsucd_cdda_play( lba, numblocks );
476         
477         cd.motor = 1;
478                   
479         memset( cd.output, 0, 6 );
480         matsucd_complete_cmd( 0 );
481      }
482      break;
483       
484      case 0x0a:   /* play audio cd, MSF mode */
485      {
486         UINT32   start, end, lba_start, lba_end;
487         
488         if ( cd.input_pos < 7 )
489            return;
490         
491         start = cd.input[1];
492         start <<= 8;
493         start |= cd.input[2];
494         start <<= 8;
495         start |= cd.input[3];
496         
497         end = cd.input[4];
498         end <<= 8;
499         end |= cd.input[5];
500         end <<= 8;
501         end |= cd.input[6];
502         
503         lba_start = MSF2LBA( start );
504         lba_end = MSF2LBA( end );
505         
506         if ( end == 0xffffff )
507         {
508            lba_end = cdrom_get_track_start(cd.cdrom,cdrom_get_last_track(cd.cdrom)-1);
509            lba_end += cdrom_get_toc(cd.cdrom)->tracks[cdrom_get_last_track(cd.cdrom)-1].frames;
510         }
511         
512         if ( lba_end <= lba_start )
513         {
514            matsucd_cdda_stop();
515         }
516         else
517         {
518            matsucd_cdda_play( lba_start, lba_end - lba_start );
519            cd.motor = 1;
520         }
521         
522         memset( cd.output, 0, 6 );
523         matsucd_complete_cmd( 0 );
524      }
525      break;
526       
527      case 0x0b:   /* play audio track and index */
528      {
529         UINT8   track_start = cd.input[1];
530         UINT8   index_start = cd.input[2];
531         UINT8   track_end = cd.input[3];
532         UINT8   index_end = cd.input[4];
533         UINT32   lba_start, lba_end;
534         
535         /* TODO: Add index support once the CDDA engine supports it */
536         (void)index_start;
537         (void)index_end;
538         
539         /* sanitize values */
540         if ( track_start == 0 ) track_start++;
541         if ( track_end > cdrom_get_last_track(cd.cdrom) )
542            track_end = cdrom_get_last_track(cd.cdrom);
543 
544         /* find the start and stop positions */
545         lba_start = cdrom_get_track_start(cd.cdrom,track_start-1);
546         lba_end = cdrom_get_track_start(cd.cdrom,track_end-1);
547         
548         lba_end += cdrom_get_toc(cd.cdrom)->tracks[track_end-1].frames;
549         
550         if ( lba_end <= lba_start )
551         {
552            matsucd_cdda_stop();
553         }
554         else
555         {
556            matsucd_cdda_play( lba_start, lba_end - lba_start );
557            cd.motor = 1;
558         }
559         
560         memset( cd.output, 0, 6 );
561         matsucd_complete_cmd( 0 );
562      }
563      break;
564       
565      case 0x81:   /* status read */
566      {
567         UINT8   newstatus = cd.status;
568         
569         newstatus &= MATSU_STATUS_SUCCESS | MATSU_STATUS_ERROR | MATSU_STATUS_PLAYING;
570         newstatus |= MATSU_STATUS_READY;
571         
572         if (cd.cdrom)
573         {
574            newstatus |= MATSU_STATUS_MEDIA;
575         }
576         
577         if (cd.motor)
578            newstatus |= MATSU_STATUS_MOTOR;
579         
580         cd.output[0] = newstatus;
581         
582         matsucd_set_status( newstatus );
583         
584         matsucd_complete_cmd( 1 );
585      }
586      break;
587       
588      case 0x82:   /* error read */
589      {
590         if ( cd.input_pos < 7 )
591            return;
592         
593         memset( cd.output, 0, 6 );
594         matsucd_complete_cmd( 6 );
595      }
596      break;
597       
598      case 0x84:   /* set mode */
599      {
600         if ( cd.input_pos < 7 )
601            return;
602             
603         cd.sector_size = cd.input[2];
604         cd.sector_size <<= 8;
605         cd.sector_size |= cd.input[3];
606         
607         memset( cd.output, 0, 6 );
608         matsucd_complete_cmd( 0 );
609      }
610      break;
611       
612      case 0x87:   /* read SUBQ */
613      {
614         int      msfmode;
615         UINT32   lba;
616         UINT8   track;
617                   
618         if ( cd.input_pos < 7 )
619            return;
620         
621         msfmode = (cd.input[1] & 0x02) ? 1 : 0;
622             
623         memset( cd.output, 0, 13 );
624         
625         cd.output[0] = matsucd_cdda_getstatus( &lba );
626         
627         if ( lba > 0 )
628         {
629            UINT32   disk_pos;
630            UINT32   track_pos;
631             
632            track = cdrom_get_track(cd.cdrom, lba);
633                   
634            cd.output[1] = cdrom_get_adr_control(cd.cdrom, track);
635            cd.output[2] = track+1;
636            cd.output[3] = 0; /* index */
637         
638            disk_pos = lba;
639            if ( msfmode ) disk_pos = LBA2MSF(disk_pos);
640               
641            cd.output[4] = (disk_pos >> 24) & 0xff;
642            cd.output[5] = (disk_pos >> 16) & 0xff;
643            cd.output[6] = (disk_pos >> 8) & 0xff;
644            cd.output[7] = (disk_pos) & 0xff;
645         
646            track_pos = lba - cdrom_get_track_start(cd.cdrom, track);
647            if ( msfmode ) track_pos = LBA2MSF(track_pos);
648         
649            cd.output[8] = (track_pos >> 24) & 0xff;
650            cd.output[9] = (track_pos >> 16) & 0xff;
651            cd.output[10] = (track_pos >> 8) & 0xff;
652            cd.output[11] = (track_pos) & 0xff;
653         
654            /* TODO: UPC flag at offset 12 */
655            cd.output[12] = 0;
656         }
657         
658         matsucd_complete_cmd( 13 );
659      }
660      break;
661       
662      case 0x89:   /* read disk info */
663      {
664         UINT32   end;
665         
666         if ( cd.input_pos < 7 )
667            return;
668         
669         memset( cd.output, 0, 5 );
670         
671         cd.output[0] = cdrom_get_last_track(cd.cdrom) ? 1 : 0;
672         cd.output[1] = cdrom_get_last_track(cd.cdrom);
673         end = cdrom_get_track_start(cd.cdrom,cd.output[1]-1);
674         end += cdrom_get_toc(cd.cdrom)->tracks[cd.output[1]-1].frames;
675         end = LBA2MSF(end);
676         cd.output[2] = (end >> 16) & 0xff;
677         cd.output[3] = (end >> 8) & 0xff;
678         cd.output[4] = (end) & 0xff;
679         
680         matsucd_complete_cmd( 5 );
681      }
682      break;
683       
684      case 0x8a:   /* read toc */
685      {
686         UINT8   track;
687         int      msfmode;
688         UINT32   track_start;
689         
690         if ( cd.input_pos < 7 )
691            return;
692         
693         /* stop CDDA audio if necessary */
694         matsucd_cdda_stop();
695                   
696         track = cd.input[2];
697         msfmode = (cd.input[1] & 0x02) ? 1 : 0;
698             
699         if ( cd.cdrom == NULL )
700         {
701            logerror( "MATSUCD - Warning: Reading TOC without a CD!\n" );
702            matsucd_command_error();
703            return;
704         }
705         
706         if ( track > cdrom_get_last_track(cd.cdrom) )
707         {
708            logerror( "MATSUCD - Warning: Reading invalid track entry from TOC!\n" );
709            matsucd_command_error();
710            return;
711         }
712         
713         memset( cd.output, 0, 7 );
714   
715         track_start = cdrom_get_track_start(cd.cdrom, track > 0 ? (track-1) : track );
716         if ( msfmode ) track_start = LBA2MSF( track_start );
717 
718         cd.output[1] = cdrom_get_adr_control(cd.cdrom, track > 0 ? (track-1) : track);
719         cd.output[2] = track;
720         cd.output[3] = (track == 0 ) ? cdrom_get_last_track(cd.cdrom) : 0;
721         cd.output[4] = (track_start >> 24) & 0xff;
722         cd.output[5] = (track_start >> 16) & 0xff;
723         cd.output[6] = (track_start >> 8) & 0xff;
724         cd.output[7] = (track_start) & 0xff;
725         
726         cd.motor = 1;
727         
728         matsucd_complete_cmd( 8 );
729      }
730      break;
731       
732      case 0x8b:   /* pause audio */
733      {
734         if ( cd.input_pos < 7 )
735            return;
736         
737         matsucd_cdda_pause( (cd.input[1] == 0) ? 1 : 0 );
738         memset( cd.output, 0, 7 );
739         matsucd_complete_cmd( 0 );
740      }
741      break;
742       
743      case 0xa3:   /* front panel */
744      {
745         if ( cd.input_pos < 7 )
746            return;
747         
748         /* TODO: ??? */
749             
750         memset( cd.output, 0, 7 );
751         matsucd_complete_cmd( 0 );
752      }
753      break;
754       
755      default:
756         logerror( "MATSUCD: Unknown/inimplemented command %08x\n", cmd );
757      break;
758   }
759}
1/***************************************************************************
2
3   Matsushita/Panasonic CDR521/522 type CDROM drive emulation
4   
5Notes:
6This version implements the drive found in Amiga CDTV. There are
7different drives supporting this command-set (look in the sbpcd driver
8in Linux for examples). Most drives support the exact same command
9structure, but the command numbers differ. Eventually this driver
10can be expanded with support for the other drives as needed.
11
12***************************************************************************/
13
14#include "mame.h"
15#include "driver.h"
16#include "devices/chd_cd.h"
17#include "sound/cdda.h"
18
19
20#define MATSU_STATUS_READY      ( 1 << 0 )   /* driver ready */
21#define MATSU_STATUS_DOORLOCKED   ( 1 << 1 )   /* door locked */
22#define MATSU_STATUS_PLAYING   ( 1 << 2 )   /* drive playing */
23#define MATSU_STATUS_SUCCESS   ( 1 << 3 )   /* last command was succesful */
24#define MATSU_STATUS_ERROR      ( 1 << 4 )   /* last command failed */
25#define MATSU_STATUS_MOTOR      ( 1 << 5 )   /* spinning */
26#define MATSU_STATUS_MEDIA      ( 1 << 6 )   /* media present (in caddy or tray) */
27#define MATSU_STATUS_DOORCLOSED   ( 1 << 7 )   /* tray status */
28
29typedef struct
30{
31   UINT8   enabled;      /* /ENABLE - Unit enabled */
32   UINT8   cmd_signal;      /* /CMD - Command mode    */
33   UINT8   stch_signal;   /* /STCH - Status Changed */
34   UINT8   sten_signal;   /* /STEN - Status Enabled */
35   UINT8   scor_signal;   /* /STEN - Subcode Ready */
36   UINT8   input[16];
37   UINT8   input_pos;
38   UINT8   output[16];
39   UINT8   output_pos;
40   UINT8   output_len;
41   UINT8   status;
42   UINT8   motor;
43   UINT16   sector_size;
44   UINT32   lba;
45   UINT16   num_blocks;
46   UINT16   xfer_offset;
47   UINT8   sector_buffer[CD_MAX_SECTOR_DATA];
48   UINT8   cdda_set;
49   void (*sten_cb)( int level );   /* Status enabled callback */
50   void (*stch_cb)( int level );   /* Status changed callback */
51   void (*scor_cb)( int level );   /* Subcode ready callback */
52   cdrom_file *cdrom;
53   mame_timer *frame_timer;
54} matsucd;
55
56static matsucd cd;
57
58#define MSF2LBA(msf) (((msf >> 16) & 0xff) * 60 * 75 + ((msf >> 8) & 0xff) * 75 + ((msf >> 0) & 0xff))
59#define LBA2MSF(lba) (((lba / (75 * 60)) << 16) | (((lba / 75) % 60) << 8) | (lba % 75))
60
61static TIMER_CALLBACK(matsu_subcode_proc);
62
63void matsucd_init( void )
64{
65   memset(&cd, 0, sizeof( matsucd ) );
66   
67   cd.cdrom = mess_cd_get_cdrom_file_by_number(0);
68   
69   cd.frame_timer = mame_timer_alloc(matsu_subcode_proc);
70   
71   cd.stch_signal = 1;
72}
73
74void matsucd_set_status_enabled_callback( void (*sten_cb)( int level ) )
75{
76   /* add the callback for status enabled signal */
77   cd.sten_cb = sten_cb;
78}
79
80void matsucd_set_status_changed_callback( void (*stch_cb)( int level ) )
81{
82   /* add the callback for status changed signal */
83   cd.stch_cb = stch_cb;
84}
85
86void matsucd_set_subcode_ready_callback( void (*scor_cb)( int level ) )
87{
88   /* add the callback for subcode ready signal */
89   cd.scor_cb = scor_cb;
90}
91
92static int matsucd_getsector_type( void )
93{
94   switch( cd.sector_size )
95   {
96      case 2048: return CD_TRACK_MODE1; break;
97      case 2324: return CD_TRACK_MODE2_FORM2; break;
98      case 2336: return CD_TRACK_MODE2; break;
99      case 2352: return CD_TRACK_MODE2_RAW; break;
100     
101      default: logerror( "MATSUCD: Sector size %d unsupported!\n", cd.sector_size ); break;
102   }
103   
104   return CD_TRACK_RAW_DONTCARE;
105}
106
107void matsucd_read_next_block( void )
108{
109   cd.xfer_offset = 0;
110   
111   if ( cd.num_blocks )
112   {
113      cd.lba++;
114      cd.num_blocks--;
115     
116      if (!cdrom_read_data(cd.cdrom, cd.lba, cd.sector_buffer, matsucd_getsector_type()))
117      {
118         logerror( "MATSUCD - Warning: Read error on CD!\n" );
119      }
120   }
121}
122
123int matsucd_get_next_byte( UINT8 *data )
124{
125   /* no more data to read on this sector */
126   if ( cd.xfer_offset >= cd.sector_size )
127      return -1;
128   
129   if ( data )
130      *data = cd.sector_buffer[cd.xfer_offset++];
131   
132   return 0;   
133}
134
135static void matsucd_cdda_stop( void )
136{
137   int cddanum = cdda_num_from_cdrom(cd.cdrom);
138   
139   if (cddanum != -1)
140   {
141      cdda_stop_audio(cddanum);
142      mame_timer_reset( cd.frame_timer, time_never );
143   }
144}
145
146static void matsucd_cdda_play( UINT32 lba, UINT32 num_blocks )
147{
148   int cddanum = cdda_num_from_cdrom(cd.cdrom);
149   if (cddanum != -1)
150   {
151      cdda_start_audio(cddanum, lba, num_blocks);
152      mame_timer_adjust( cd.frame_timer, MAME_TIME_IN_HZ( 75 ), 0, time_zero );
153   }
154}
155
156static void matsucd_cdda_pause( int pause )
157{
158   int cddanum = cdda_num_from_cdrom(cd.cdrom);
159   if (cddanum != -1)
160   {
161      cdda_pause_audio(cddanum, pause);
162     
163      if ( pause )
164      {
165         mame_timer_reset( cd.frame_timer, time_never );
166      }
167      else
168      {
169         mame_timer_adjust( cd.frame_timer, MAME_TIME_IN_HZ( 75 ), 0, time_zero );
170      }
171   }
172}
173
174static UINT8 matsucd_cdda_getstatus( UINT32 *lba )
175{
176   int cddanum = cdda_num_from_cdrom(cd.cdrom);
177   
178   if ( lba ) *lba = 0;
179   
180   if (cddanum != -1)
181   {
182      if (cdda_audio_active(cddanum))
183      {
184         if ( lba ) *lba = cdda_get_audio_lba(cddanum);
185           
186         if (cdda_audio_paused(cddanum))
187         {
188            return 0x12;   /* audio paused */
189         }
190         else
191         {
192            return 0x11;   /* audio in progress */
193         }
194      }
195      else if (cdda_audio_ended(cddanum))
196      {
197         return 0x13;   /* audio ended */
198      }
199   }
200   
201   return 0x15;   /* no audio status */
202}
203
204void matsucd_enable_w( int level )
205{
206   cd.enabled = ( level ) ? 0 : 1;
207}
208
209void matsucd_cmd_w( int level )
210{
211   cd.cmd_signal = ( level ) ? 0 : 1;
212}
213
214int matsucd_stch_r( void )
215{
216   return cd.stch_signal ? 0 : 1;
217}
218
219int matsucd_sten_r( void )
220{
221   return cd.sten_signal ? 0 : 1;
222}
223
224int matsucd_scor_r( void )
225{
226   return cd.scor_signal ? 0 : 1;
227}
228
229static void update_status_enable( int level )
230{
231   cd.sten_signal = level;
232   
233   if ( cd.sten_cb )
234   {
235      (*cd.sten_cb)(cd.sten_signal);
236   }
237}
238
239static void update_status_changed( int level )
240{
241   cd.stch_signal = level;
242   
243   if ( cd.stch_cb )
244   {
245      (*cd.stch_cb)(cd.stch_signal);
246   }
247}
248
249static void update_subcode_ready( int level )
250{
251   cd.scor_signal = level;
252   
253   if ( cd.scor_cb )
254   {
255      (*cd.scor_cb)(cd.scor_signal);
256   }
257}
258
259static TIMER_CALLBACK(matsucd_set_status_end)
260{
261   update_status_changed( 1 );
262}
263
264static void matsucd_set_status( UINT8 status )
265{
266   if ( status != cd.status )
267   {
268      cd.status = status;
269     
270      if ( cd.stch_signal != 0 )
271      {
272         update_status_changed( 0 );
273         mame_timer_set( MAME_TIME_IN_MSEC(1), 0, matsucd_set_status_end );
274      }
275   }
276}
277
278static TIMER_CALLBACK(matsu_subcode_proc)
279{
280   int cddanum = cdda_num_from_cdrom(cd.cdrom);
281   
282   (void)param;
283   
284   if (cddanum != -1)
285   {
286      UINT8   s = matsucd_cdda_getstatus(NULL);
287      UINT8   newstatus = cd.status;
288     
289      if ( s == 0x11 || s == 0x12 )
290      {
291         if ( s == 0x11 )
292         {
293            update_subcode_ready( 1 );
294            update_subcode_ready( 0 );
295         }
296         
297         newstatus |= MATSU_STATUS_PLAYING;
298         
299         mame_timer_adjust( cd.frame_timer, MAME_TIME_IN_HZ( 75 ), 0, time_zero );
300      }
301      else
302      {
303         newstatus &= ~MATSU_STATUS_PLAYING;
304      }
305     
306      matsucd_set_status( newstatus );
307   }
308}
309
310static void matsucd_command_error( void )
311{
312   UINT8   newstatus = cd.status;
313     
314   newstatus &= ~MATSU_STATUS_SUCCESS;
315   newstatus |= MATSU_STATUS_ERROR;
316   
317   matsucd_set_status( newstatus );
318}
319
320static void matsucd_complete_cmd( UINT8 len )
321{
322   UINT8   newstatus = cd.status;
323   
324   cd.input_pos = 0;
325   cd.output_pos = 0;
326   cd.output_len = len;
327   
328   newstatus &= ~MATSU_STATUS_ERROR;
329   newstatus |= MATSU_STATUS_SUCCESS;
330   
331   matsucd_set_status( newstatus );
332   
333   update_status_enable( 1 );
334   update_status_enable( 0 );
335}
336
337UINT8 matsucd_response_r( void )
338{
339   UINT8   v = cd.output[cd.output_pos++];
340   
341   if ( cd.output_pos < cd.output_len )
342   {
343      update_status_enable( 1 );
344      update_status_enable( 0 );
345   }
346   
347   return v;
348}
349
350void matsucd_command_w( UINT8 data )
351{
352   UINT8   cmd;
353   
354   /* make sure we're enabled */
355   if ( cd.enabled == 0 )
356      return;
357   
358   /* make sure /CMD is asserted */
359   if ( cd.cmd_signal == 0 )
360      return;
361   
362   if ( cd.cdda_set == 0 )
363   {
364      if ( cd.cdrom )
365         cdda_set_cdrom(0, cd.cdrom);
366     
367      cd.cdda_set = 1;
368   }
369   
370   cd.input[cd.input_pos++] = data;
371
372   cmd = cd.input[0];
373   
374   switch( cmd )
375   {
376      case 0x01:   /* seek */
377      {
378         if ( cd.input_pos < 7 )
379            return;
380           
381         /* stop CDDA audio if necessary */
382         matsucd_cdda_stop();
383         
384         cd.motor = 1;
385                 
386         memset( cd.output, 0, 6 );
387         matsucd_complete_cmd( 0 );
388      }
389      break;
390     
391      case 0x02:   /* read sectors */
392      {
393         if ( cd.input_pos < 7 )
394            return;
395         
396         /* stop CDDA audio if necessary */
397         matsucd_cdda_stop();
398           
399         /* LBA */
400         cd.lba = cd.input[1];
401         cd.lba <<= 8;
402         cd.lba |= cd.input[2];
403         cd.lba <<= 8;
404         cd.lba |= cd.input[3];
405         
406         /* Number of blocks */
407         cd.num_blocks = cd.input[4];
408         cd.num_blocks <<= 8;
409         cd.num_blocks |= cd.input[5];
410         
411         /* Reset transfer count */
412         cd.xfer_offset = 0;
413         
414         /* go ahead and cache the first block */
415         if (!cdrom_read_data(cd.cdrom, cd.lba, cd.sector_buffer, matsucd_getsector_type()))
416         {
417            logerror( "MATSUCD - Warning: Read error on CD!\n" );
418            matsucd_command_error();
419            return;
420         }
421         
422         cd.motor = 1;
423                 
424         memset( cd.output, 0, 6 );
425         matsucd_complete_cmd( 0 );
426      }
427      break;
428     
429      case 0x04:   /* motor on */
430      {
431         if ( cd.input_pos < 7 )
432            return;
433           
434         cd.motor = 1;
435                 
436         memset( cd.output, 0, 6 );
437         matsucd_complete_cmd( 0 );
438      }
439      break;
440     
441      case 0x05:   /* motor off */
442      {
443         if ( cd.input_pos < 7 )
444            return;
445           
446         /* stop CDDA audio if necessary */
447         matsucd_cdda_stop();
448         
449         cd.motor = 0;
450                 
451         memset( cd.output, 0, 6 );
452         matsucd_complete_cmd( 0 );
453      }
454      break;
455     
456      case 0x09:   /* play audio cd, LBA mode */
457      {
458         UINT32   lba, numblocks;
459         
460         if ( cd.input_pos < 7 )
461            return;
462         
463         lba = cd.input[1];
464         lba <<= 8;
465         lba |= cd.input[2];
466         lba <<= 8;
467         lba |= cd.input[3];
468         
469         numblocks = cd.input[4];
470         numblocks <<= 8;
471         numblocks |= cd.input[5];
472         numblocks <<= 8;
473         numblocks |= cd.input[6];
474         
475         matsucd_cdda_play( lba, numblocks );
476         
477         cd.motor = 1;
478                 
479         memset( cd.output, 0, 6 );
480         matsucd_complete_cmd( 0 );
481      }
482      break;
483     
484      case 0x0a:   /* play audio cd, MSF mode */
485      {
486         UINT32   start, end, lba_start, lba_end;
487         
488         if ( cd.input_pos < 7 )
489            return;
490         
491         start = cd.input[1];
492         start <<= 8;
493         start |= cd.input[2];
494         start <<= 8;
495         start |= cd.input[3];
496         
497         end = cd.input[4];
498         end <<= 8;
499         end |= cd.input[5];
500         end <<= 8;
501         end |= cd.input[6];
502         
503         lba_start = MSF2LBA( start );
504         lba_end = MSF2LBA( end );
505         
506         if ( end == 0xffffff )
507         {
508            lba_end = cdrom_get_track_start(cd.cdrom,cdrom_get_last_track(cd.cdrom)-1);
509            lba_end += cdrom_get_toc(cd.cdrom)->tracks[cdrom_get_last_track(cd.cdrom)-1].frames;
510         }
511         
512         if ( lba_end <= lba_start )
513         {
514            matsucd_cdda_stop();
515         }
516         else
517         {
518            matsucd_cdda_play( lba_start, lba_end - lba_start );
519            cd.motor = 1;
520         }
521         
522         memset( cd.output, 0, 6 );
523         matsucd_complete_cmd( 0 );
524      }
525      break;
526     
527      case 0x0b:   /* play audio track and index */
528      {
529         UINT8   track_start = cd.input[1];
530         UINT8   index_start = cd.input[2];
531         UINT8   track_end = cd.input[3];
532         UINT8   index_end = cd.input[4];
533         UINT32   lba_start, lba_end;
534         
535         /* TODO: Add index support once the CDDA engine supports it */
536         (void)index_start;
537         (void)index_end;
538         
539         /* sanitize values */
540         if ( track_start == 0 ) track_start++;
541         if ( track_end > cdrom_get_last_track(cd.cdrom) )
542            track_end = cdrom_get_last_track(cd.cdrom);
543
544         /* find the start and stop positions */
545         lba_start = cdrom_get_track_start(cd.cdrom,track_start-1);
546         lba_end = cdrom_get_track_start(cd.cdrom,track_end-1);
547         
548         lba_end += cdrom_get_toc(cd.cdrom)->tracks[track_end-1].frames;
549         
550         if ( lba_end <= lba_start )
551         {
552            matsucd_cdda_stop();
553         }
554         else
555         {
556            matsucd_cdda_play( lba_start, lba_end - lba_start );
557            cd.motor = 1;
558         }
559         
560         memset( cd.output, 0, 6 );
561         matsucd_complete_cmd( 0 );
562      }
563      break;
564     
565      case 0x81:   /* status read */
566      {
567         UINT8   newstatus = cd.status;
568         
569         newstatus &= MATSU_STATUS_SUCCESS | MATSU_STATUS_ERROR | MATSU_STATUS_PLAYING;
570         newstatus |= MATSU_STATUS_READY;
571         
572         if (cd.cdrom)
573         {
574            newstatus |= MATSU_STATUS_MEDIA;
575         }
576         
577         if (cd.motor)
578            newstatus |= MATSU_STATUS_MOTOR;
579         
580         cd.output[0] = newstatus;
581         
582         matsucd_set_status( newstatus );
583         
584         matsucd_complete_cmd( 1 );
585      }
586      break;
587     
588      case 0x82:   /* error read */
589      {
590         if ( cd.input_pos < 7 )
591            return;
592         
593         memset( cd.output, 0, 6 );
594         matsucd_complete_cmd( 6 );
595      }
596      break;
597     
598      case 0x84:   /* set mode */
599      {
600         if ( cd.input_pos < 7 )
601            return;
602           
603         cd.sector_size = cd.input[2];
604         cd.sector_size <<= 8;
605         cd.sector_size |= cd.input[3];
606         
607         memset( cd.output, 0, 6 );
608         matsucd_complete_cmd( 0 );
609      }
610      break;
611     
612      case 0x87:   /* read SUBQ */
613      {
614         int      msfmode;
615         UINT32   lba;
616         UINT8   track;
617                 
618         if ( cd.input_pos < 7 )
619            return;
620         
621         msfmode = (cd.input[1] & 0x02) ? 1 : 0;
622           
623         memset( cd.output, 0, 13 );
624         
625         cd.output[0] = matsucd_cdda_getstatus( &lba );
626         
627         if ( lba > 0 )
628         {
629            UINT32   disk_pos;
630            UINT32   track_pos;
631           
632            track = cdrom_get_track(cd.cdrom, lba);
633                 
634            cd.output[1] = cdrom_get_adr_control(cd.cdrom, track);
635            cd.output[2] = track+1;
636            cd.output[3] = 0; /* index */
637         
638            disk_pos = lba;
639            if ( msfmode ) disk_pos = LBA2MSF(disk_pos);
640               
641            cd.output[4] = (disk_pos >> 24) & 0xff;
642            cd.output[5] = (disk_pos >> 16) & 0xff;
643            cd.output[6] = (disk_pos >> 8) & 0xff;
644            cd.output[7] = (disk_pos) & 0xff;
645         
646            track_pos = lba - cdrom_get_track_start(cd.cdrom, track);
647            if ( msfmode ) track_pos = LBA2MSF(track_pos);
648         
649            cd.output[8] = (track_pos >> 24) & 0xff;
650            cd.output[9] = (track_pos >> 16) & 0xff;
651            cd.output[10] = (track_pos >> 8) & 0xff;
652            cd.output[11] = (track_pos) & 0xff;
653         
654            /* TODO: UPC flag at offset 12 */
655            cd.output[12] = 0;
656         }
657         
658         matsucd_complete_cmd( 13 );
659      }
660      break;
661     
662      case 0x89:   /* read disk info */
663      {
664         UINT32   end;
665         
666         if ( cd.input_pos < 7 )
667            return;
668         
669         memset( cd.output, 0, 5 );
670         
671         cd.output[0] = cdrom_get_last_track(cd.cdrom) ? 1 : 0;
672         cd.output[1] = cdrom_get_last_track(cd.cdrom);
673         end = cdrom_get_track_start(cd.cdrom,cd.output[1]-1);
674         end += cdrom_get_toc(cd.cdrom)->tracks[cd.output[1]-1].frames;
675         end = LBA2MSF(end);
676         cd.output[2] = (end >> 16) & 0xff;
677         cd.output[3] = (end >> 8) & 0xff;
678         cd.output[4] = (end) & 0xff;
679         
680         matsucd_complete_cmd( 5 );
681      }
682      break;
683     
684      case 0x8a:   /* read toc */
685      {
686         UINT8   track;
687         int      msfmode;
688         UINT32   track_start;
689         
690         if ( cd.input_pos < 7 )
691            return;
692         
693         /* stop CDDA audio if necessary */
694         matsucd_cdda_stop();
695                 
696         track = cd.input[2];
697         msfmode = (cd.input[1] & 0x02) ? 1 : 0;
698           
699         if ( cd.cdrom == NULL )
700         {
701            logerror( "MATSUCD - Warning: Reading TOC without a CD!\n" );
702            matsucd_command_error();
703            return;
704         }
705         
706         if ( track > cdrom_get_last_track(cd.cdrom) )
707         {
708            logerror( "MATSUCD - Warning: Reading invalid track entry from TOC!\n" );
709            matsucd_command_error();
710            return;
711         }
712         
713         memset( cd.output, 0, 7 );
714   
715         track_start = cdrom_get_track_start(cd.cdrom, track > 0 ? (track-1) : track );
716         if ( msfmode ) track_start = LBA2MSF( track_start );
717
718         cd.output[1] = cdrom_get_adr_control(cd.cdrom, track > 0 ? (track-1) : track);
719         cd.output[2] = track;
720         cd.output[3] = (track == 0 ) ? cdrom_get_last_track(cd.cdrom) : 0;
721         cd.output[4] = (track_start >> 24) & 0xff;
722         cd.output[5] = (track_start >> 16) & 0xff;
723         cd.output[6] = (track_start >> 8) & 0xff;
724         cd.output[7] = (track_start) & 0xff;
725         
726         cd.motor = 1;
727         
728         matsucd_complete_cmd( 8 );
729      }
730      break;
731     
732      case 0x8b:   /* pause audio */
733      {
734         if ( cd.input_pos < 7 )
735            return;
736         
737         matsucd_cdda_pause( (cd.input[1] == 0) ? 1 : 0 );
738         memset( cd.output, 0, 7 );
739         matsucd_complete_cmd( 0 );
740      }
741      break;
742     
743      case 0xa3:   /* front panel */
744      {
745         if ( cd.input_pos < 7 )
746            return;
747         
748         /* TODO: ??? */
749           
750         memset( cd.output, 0, 7 );
751         matsucd_complete_cmd( 0 );
752      }
753      break;
754     
755      default:
756         logerror( "MATSUCD: Unknown/inimplemented command %08x\n", cmd );
757      break;
758   }
759}
src/mess/machine/matsucd.h
r882r883
1/***************************************************************************
2 
3   Matsushita/Panasonic CDR521/522 type CDROM drive emulation
4 
5***************************************************************************/
6 
7/* initialization */
8extern void matsucd_init( void );
9 
10/* signaling */
11extern void matsucd_enable_w( int level );   /* /ENABLE pin */
12extern void matsucd_cmd_w( int level );      /* /CMD pin */
13extern int matsucd_stch_r( void );         /* /STCH pin */
14extern int matsucd_sten_r( void );         /* /STEN pin */
15extern int matsucd_scor_r( void );         /* /SCOR pin */
16 
17/* callback for signal changes */
18extern void matsucd_set_status_enabled_callback( void (*sten_cb)( int level ) );
19extern void matsucd_set_status_changed_callback( void (*stch_cb)( int level ) );
20extern void matsucd_set_subcode_ready_callback( void (*scor_cb)( int level ) );
21 
22/* data transfer routines */
23extern void matsucd_read_next_block( void );
24extern int matsucd_get_next_byte( UINT8 *data );
25 
26/* main command interface */
27extern void matsucd_command_w( UINT8 data );
28extern UINT8 matsucd_response_r( void );
1/***************************************************************************
2
3   Matsushita/Panasonic CDR521/522 type CDROM drive emulation
4
5***************************************************************************/
6
7/* initialization */
8extern void matsucd_init( void );
9
10/* signaling */
11extern void matsucd_enable_w( int level );   /* /ENABLE pin */
12extern void matsucd_cmd_w( int level );      /* /CMD pin */
13extern int matsucd_stch_r( void );         /* /STCH pin */
14extern int matsucd_sten_r( void );         /* /STEN pin */
15extern int matsucd_scor_r( void );         /* /SCOR pin */
16
17/* callback for signal changes */
18extern void matsucd_set_status_enabled_callback( void (*sten_cb)( int level ) );
19extern void matsucd_set_status_changed_callback( void (*stch_cb)( int level ) );
20extern void matsucd_set_subcode_ready_callback( void (*scor_cb)( int level ) );
21
22/* data transfer routines */
23extern void matsucd_read_next_block( void );
24extern int matsucd_get_next_byte( UINT8 *data );
25
26/* main command interface */
27extern void matsucd_command_w( UINT8 data );
28extern UINT8 matsucd_response_r( void );
src/mess/machine/cybiko.c
r882r883
1/*
2 
3   Cybiko Wireless Inter-tainment System
4 
5   (c) 2001-2007 Tim Schuerewegen
6 
7   Cybiko Classic (V1)
8   Cybiko Classic (V2)
9   Cybiko Xtreme
10 
11*/
12 
13#include "includes/cybiko.h"
14 
15#include "cpu/h8s2xxx/h8s2xxx.h"
16#include "video/hd66421.h"
17#include "sound/speaker.h"
18#include "machine/pcf8593.h"
19#include "machine/at45dbxx.h"
20#include "machine/sst39vfx.h"
21#include "debugger.h"
22 
23#define LOG_LEVEL  1
24#define _logerror(level,...)  if (LOG_LEVEL > level) logerror(__VA_ARGS__)
25 
26/////////////////////////
27// FUNCTION PROTOTYPES //
28/////////////////////////
29 
30#define MACHINE_STOP(name) \
31   void machine_stop_##name( running_machine *machine)
32 
33// machine stop
34MACHINE_STOP( cybikov1 );
35MACHINE_STOP( cybikov2 );
36MACHINE_STOP( cybikoxt );
37 
38// rs232
39void cybiko_rs232_init( void);
40void cybiko_rs232_exit( void);
41void cybiko_rs232_reset( void);
42 
43////////////////////////
44// DRIVER INIT & EXIT //
45////////////////////////
46 
47static void init_ram_handler( offs_t start, offs_t size, offs_t mirror)
48{
49   memory_install_read_handler( 0, ADDRESS_SPACE_PROGRAM, start, start + size - 1, 0, mirror - size, STATIC_BANK1);
50   memory_install_write_handler( 0, ADDRESS_SPACE_PROGRAM, start, start + size - 1, 0, mirror - size, STATIC_BANK1);
51   memory_set_bankptr( 1, mess_ram);
52}
53 
54DRIVER_INIT( cybikov1 )
55{
56   _logerror( 0, "init_cybikov1\n");
57   init_ram_handler( 0x200000, mess_ram_size, 0x200000);
58}
59 
60DRIVER_INIT( cybikov2 )
61{
62   _logerror( 0, "init_cybikov2\n");
63   init_ram_handler( 0x200000, mess_ram_size, 0x200000);
64}
65 
66DRIVER_INIT( cybikoxt )
67{
68   _logerror( 0, "init_cybikoxt\n");
69   init_ram_handler( 0x400000, mess_ram_size, 0x200000);
70}
71 
72////////////////////
73// NVRAM HANDLERS //
74////////////////////
75 
76/*
77NVRAM_HANDLER( cybikov1 )
78{
79   _logerror( 0, "nvram_handler_cybikov1 (%p/%d)\n", file, read_or_write);
80   nvram_handler_at45dbxx( machine, file, read_or_write);
81   nvram_handler_pcf8593( machine, file, read_or_write);
82}
83*/
84 
85/*
86NVRAM_HANDLER( cybikov2 )
87{
88   _logerror( 0, "nvram_handler_cybikov2 (%p/%d)\n", file, read_or_write);
89   nvram_handler_at45dbxx( machine, file, read_or_write);
90   nvram_handler_sst39vfx( machine, file, read_or_write);
91   nvram_handler_pcf8593( machine, file, read_or_write);
92}
93*/
94 
95/*
96NVRAM_HANDLER( cybikoxt )
97{
98   _logerror( 0, "nvram_handler_cybikoxt (%p/%d)\n", file, read_or_write);
99   nvram_handler_sst39vfx( machine, file, read_or_write);
100   nvram_handler_pcf8593( machine, file, read_or_write);
101}
102*/
103 
104///////////////////
105// MACHINE START //
106///////////////////
107 
108static mame_file *nvram_system_fopen( running_machine *machine, UINT32 openflags, const char *name)
109{
110   astring *fname;
111   file_error filerr;
112   mame_file *file;
113   fname = astring_assemble_4( astring_alloc(), machine->gamedrv->name, PATH_SEPARATOR, name, ".nv");
114   filerr = mame_fopen( SEARCHPATH_NVRAM, astring_c( fname), openflags, &file);
115   astring_free( fname);
116   return (filerr == FILERR_NONE) ? file : NULL;
117}
118 
119typedef void (nvram_load_func)( mame_file *file);
120 
121static int nvram_system_load( running_machine *machine, const char *name, nvram_load_func _nvram_load, int required)
122{
123   mame_file *file;
124   file = nvram_system_fopen( machine, OPEN_FLAG_READ, name);
125   if (!file)
126   {
127      if (required) mame_printf_error( "nvram load failed (%s)\n", name);
128      return FALSE;
129   }
130   _nvram_load( file);
131   mame_fclose( file);
132   return TRUE;
133}
134 
135typedef void (nvram_save_func)( mame_file *file);
136 
137static int nvram_system_save( running_machine *machine, const char *name, nvram_save_func _nvram_save)
138{
139   mame_file *file;
140   file = nvram_system_fopen( machine, OPEN_FLAG_CREATE | OPEN_FLAG_WRITE | OPEN_FLAG_CREATE_PATHS, name);
141   if (!file)
142   {
143      mame_printf_error( "nvram save failed (%s)\n", name);
144      return FALSE;
145   }
146   _nvram_save( file);
147   mame_fclose( file);
148   return TRUE;
149}
150 
151MACHINE_START( cybikov1 )
152{
153   _logerror( 0, "machine_start_cybikov1\n");
154   // real-time clock
155   pcf8593_init();
156   nvram_system_load( machine, "rtc", pcf8593_load, 0);
157   // serial dataflash
158   at45dbxx_init( AT45DB041);
159   nvram_system_load( machine, "flash1", &at45dbxx_load, 1);
160   // serial port
161   cybiko_rs232_init();
162   // other
163   add_exit_callback( machine, machine_stop_cybikov1);
164}
165 
166MACHINE_START( cybikov2 )
167{
168   _logerror( 0, "machine_start_cybikov2\n");
169   // real-time clock
170   pcf8593_init();
171   nvram_system_load( machine, "rtc", pcf8593_load, 0);
172   // serial dataflash
173   at45dbxx_init( AT45DB041);
174   nvram_system_load( machine, "flash1", &at45dbxx_load, 1);
175   // multi-purpose flash
176   sst39vfx_init( SST39VF020, 16, CPU_IS_BE);
177   nvram_system_load( machine, "flash2", &sst39vfx_load, 1);
178   memory_set_bankptr( 2, sst39vfx_get_base());
179   // serial port
180   cybiko_rs232_init();
181   // other
182   add_exit_callback( machine, machine_stop_cybikov2);
183}
184 
185MACHINE_START( cybikoxt )
186{
187   _logerror( 0, "machine_start_cybikoxt\n");
188   // real-time clock
189   pcf8593_init();
190   nvram_system_load( machine, "rtc", pcf8593_load, 0);
191   // multi-purpose flash
192   sst39vfx_init( SST39VF400A, 16, CPU_IS_BE);
193   nvram_system_load( machine, "flash1", &sst39vfx_load, 1);
194   memory_set_bankptr( 2, sst39vfx_get_base());
195   // serial port
196   cybiko_rs232_init();
197   // other
198   add_exit_callback( machine, machine_stop_cybikoxt);
199}
200 
201///////////////////
202// MACHINE RESET //
203///////////////////
204 
205MACHINE_RESET( cybikov1 )
206{
207   _logerror( 0, "machine_reset_cybikov1\n");
208   pcf8593_reset();
209   at45dbxx_reset();
210   cybiko_rs232_reset();
211}
212 
213MACHINE_RESET( cybikov2 )
214{
215   _logerror( 0, "machine_reset_cybikov2\n");
216   pcf8593_reset();
217   at45dbxx_reset();
218   sst39vfx_reset();
219   cybiko_rs232_reset();
220}
221 
222MACHINE_RESET( cybikoxt )
223{
224   _logerror( 0, "machine_reset_cybikoxt\n");
225   pcf8593_reset();
226   sst39vfx_reset();
227   cybiko_rs232_reset();
228}
229 
230//////////////////
231// MACHINE STOP //
232//////////////////
233 
234MACHINE_STOP( cybikov1 )
235{
236   _logerror( 0, "machine_stop_cybikov1\n");
237   // real-time clock
238   nvram_system_save( machine, "rtc", pcf8593_save);
239   pcf8593_exit();
240   // serial dataflash
241   nvram_system_save( machine, "flash1", &at45dbxx_save);
242   at45dbxx_exit();
243   // serial port
244   cybiko_rs232_exit();
245}
246 
247MACHINE_STOP( cybikov2 )
248{
249   _logerror( 0, "machine_stop_cybikov2\n");
250   // real-time clock
251   nvram_system_save( machine, "rtc", pcf8593_save);
252   pcf8593_exit();
253   // serial dataflash
254   nvram_system_save( machine, "flash1", &at45dbxx_save);
255   at45dbxx_exit();
256   // multi-purpose flash
257   nvram_system_save( machine, "flash2", &sst39vfx_save);
258   sst39vfx_exit();
259   // serial port
260   cybiko_rs232_exit();
261}
262 
263MACHINE_STOP( cybikoxt )
264{
265   _logerror( 0, "machine_stop_cybikoxt\n");
266   // real-time clock
267   nvram_system_save( machine, "rtc", pcf8593_save);
268   pcf8593_exit();
269   // multi-purpose flash
270   nvram_system_save( machine, "flash1", &sst39vfx_save);
271   sst39vfx_exit();
272   // serial port
273   cybiko_rs232_exit();
274}
275 
276///////////
277// RS232 //
278///////////
279 
280typedef struct
281{
282   int sck; // serial clock
283   int txd; // transmit data
284   int rxd; // receive data
285} CYBIKO_RS232_PINS;
286 
287typedef struct
288{
289   CYBIKO_RS232_PINS pin;
290   UINT8 rx_bits, rx_byte, tx_byte, tx_bits;
291} CYBIKO_RS232;
292 
293static CYBIKO_RS232 rs232;
294 
295void cybiko_rs232_init( void)
296{
297   _logerror( 0, "cybiko_rs232_init\n");
298   memset( &rs232, 0, sizeof( rs232));
299//   timer_pulse( TIME_IN_HZ( 10), 0, rs232_timer_callback);
300}
301 
302void cybiko_rs232_exit( void)
303{
304   _logerror( 0, "cybiko_rs232_exit\n");
305}
306 
307void cybiko_rs232_reset( void)
308{
309   _logerror( 0, "cybiko_rs232_reset\n");
310}
311 
312void cybiko_rs232_write_byte( UINT8 data)
313{
314   #if 0
315   printf( "%c", data);
316   #endif
317}
318 
319void cybiko_rs232_pin_sck( int data)
320{
321   _logerror( 3, "cybiko_rs232_pin_sck (%d)\n", data);
322   // clock high-to-low
323   if ((rs232.pin.sck == 1) && (data == 0))
324   {
325      // transmit
326      if (rs232.pin.txd) rs232.tx_byte = rs232.tx_byte | (1 << rs232.tx_bits);
327      rs232.tx_bits++;
328      if (rs232.tx_bits == 8)
329      {
330         rs232.tx_bits = 0;
331         cybiko_rs232_write_byte( rs232.tx_byte);
332         rs232.tx_byte = 0;
333      }
334      // receive
335      rs232.pin.rxd = (rs232.rx_byte >> rs232.rx_bits) & 1;
336      rs232.rx_bits++;
337      if (rs232.rx_bits == 8)
338      {
339         rs232.rx_bits = 0;
340         rs232.rx_byte = 0;
341      }
342   }
343   // save sck
344   rs232.pin.sck = data;
345}
346 
347void cybiko_rs232_pin_txd( int data)
348{
349   _logerror( 3, "cybiko_rs232_pin_txd (%d)\n", data);
350   rs232.pin.txd = data;
351}
352 
353int cybiko_rs232_pin_rxd( void)
354{
355   _logerror( 3, "cybiko_rs232_pin_rxd\n");
356   return rs232.pin.rxd;
357}
358 
359int cybiko_rs232_rx_queue( void)
360{
361   return 0;
362}
363 
364/////////////////////////
365// READ/WRITE HANDLERS //
366/////////////////////////
367 
368READ16_HANDLER( cybiko_lcd_r )
369{
370   UINT16 data = 0;
371   if ACCESSING_MSB16 data = data | (hd66421_reg_idx_r() << 8);
372   if ACCESSING_LSB16 data = data | (hd66421_reg_dat_r() << 0);
373   return data;
374}
375 
376WRITE16_HANDLER( cybiko_lcd_w )
377{
378   if ACCESSING_MSB16 hd66421_reg_idx_w( (data >> 8) & 0xFF);
379   if ACCESSING_LSB16 hd66421_reg_dat_w( (data >> 0) & 0xFF);
380}
381 
382READ8_HANDLER( cybiko_key_r_byte )
383{
384   UINT8 data = 0xFF;
385   int i;
386   _logerror( 2, "cybiko_key_r_byte (%08X)\n", offset);
387   // A11
388   if (!(offset & (1 << 11))) data &= 0xFE;
389   // A1 .. A9
390   for (i=1;i<10;i++) if (!(offset & (1 << i))) data &= readinputport( i - 1);
391   // A0
392   if (!(offset & (1 <<  0))) data |= 0xFF;
393   //
394   return data;
395}
396 
397READ16_HANDLER( cybiko_key_r )
398{
399   UINT16 data = 0;
400   _logerror( 2, "cybiko_key_r (%08X/%04X)\n", offset, mem_mask);
401   if ACCESSING_MSB16 data = data | (cybiko_key_r_byte( offset * 2 + 0) << 8);
402   if ACCESSING_LSB16 data = data | (cybiko_key_r_byte( offset * 2 + 1) << 0);
403   _logerror( 2, "%04X\n", data);
404   return data;
405}
406 
407READ8_HANDLER( cybiko_io_reg_r )
408{
409   UINT8 data = 0;
410   _logerror( 2, "cybiko_io_reg_r (%08X)\n", offset);
411   switch (offset)
412   {
413      // keyboard
414      case H8S_IO_PORT1 :
415      {
416         //if (readinputport(0) & 0x02) data = data | 0x08; else data = data & (~0x08); // "esc" key
417         data = data | 0x08;
418      }
419      break;
420      // serial dataflash
421      case H8S_IO_PORT3 : if (at45dbxx_pin_so()) data = data | H8S_P3_RXD1; break;
422      // rs232
423      case H8S_IO_PORT5 : if (cybiko_rs232_pin_rxd()) data = data | H8S_P5_RXD2; break;
424      // real-time clock
425      case H8S_IO_PORTF :
426      {
427         data = H8S_PF_PF2;
428         if (pcf8593_pin_sda_r()) data |= H8S_PF_PF0;
429      }
430      break;
431      // serial 2
432      case H8S_IO_SSR2 :
433      {
434         if (cybiko_rs232_rx_queue()) data = data | H8S_SSR_RDRF;
435      }
436      break;
437   }
438   return data;
439}
440 
441WRITE8_HANDLER( cybiko_io_reg_w )
442{
443   _logerror( 2, "cybiko_io_reg_w (%08X/%02X)\n", offset, data);
444   switch (offset)
445   {
446      // speaker
447      case H8S_IO_P1DR : speaker_level_w( 0, (data & H8S_P1_TIOCB1) ? 1 : 0); break;
448      // serial dataflash
449      case H8S_IO_P3DR :
450      {
451         at45dbxx_pin_cs ( (data & H8S_P3_SCK0) ? 0 : 1);
452         at45dbxx_pin_si ( (data & H8S_P3_TXD1) ? 1 : 0);
453         at45dbxx_pin_sck( (data & H8S_P3_SCK1) ? 1 : 0);
454      }
455      break;
456      // rs232
457      case H8S_IO_P5DR :
458      {
459         cybiko_rs232_pin_txd( (data & H8S_P5_TXD2) ? 1 : 0);
460         cybiko_rs232_pin_sck( (data & H8S_P5_SCK2) ? 1 : 0);
461      }
462      break;
463      // real-time clock
464      case H8S_IO_PFDR  : pcf8593_pin_scl( (data & H8S_PF_PF1) ? 1 : 0); break;
465      case H8S_IO_PFDDR : pcf8593_pin_sda_w( (data & H8S_PF_PF0) ? 0 : 1); break;
466   }
467}
468 
469READ8_HANDLER( cybikov1_io_reg_r )
470{
471   _logerror( 2, "cybikov1_io_reg_r (%08X)\n", offset);
472   return cybiko_io_reg_r( offset);
473}
474 
475READ8_HANDLER( cybikov2_io_reg_r )
476{
477   _logerror( 2, "cybikov2_io_reg_r (%08X)\n", offset);
478   return cybiko_io_reg_r( offset);
479}
480 
481READ8_HANDLER( cybikoxt_io_reg_r )
482{
483   UINT8 data = 0;
484   _logerror( 2, "cybikoxt_io_reg_r (%08X)\n", offset);
485   switch (offset)
486   {
487      // rs232
488      case H8S_IO_PORT3 : if (cybiko_rs232_pin_rxd()) data = data | H8S_P3_RXD1; break;
489      // default
490      default : data = cybiko_io_reg_r( offset);
491   }
492   return data;
493}
494 
495WRITE8_HANDLER( cybikov1_io_reg_w )
496{
497   _logerror( 2, "cybikov1_io_reg_w (%08X/%02X)\n", offset, data);
498   cybiko_io_reg_w( offset, data);
499}
500 
501WRITE8_HANDLER( cybikov2_io_reg_w )
502{
503   _logerror( 2, "cybikov2_io_reg_w (%08X/%02X)\n", offset, data);
504   cybiko_io_reg_w( offset, data);
505}
506 
507WRITE8_HANDLER( cybikoxt_io_reg_w )
508{
509   _logerror( 2, "cybikoxt_io_reg_w (%08X/%02X)\n", offset, data);
510   switch (offset)
511   {
512      // rs232
513      case H8S_IO_P3DR :
514      {
515         cybiko_rs232_pin_txd( (data & H8S_P3_TXD1) ? 1 : 0);
516         cybiko_rs232_pin_sck( (data & H8S_P3_SCK1) ? 1 : 0);
517      }
518      break;
519      // default
520      default : cybiko_io_reg_w( offset, data);
521   }
522}
523 
524// Cybiko Xtreme writes following byte pairs to 0x200003/0x200000
525// 00/01, 00/C0, 0F/32, 0D/03, 0B/03, 09/50, 07/D6, 05/00, 04/00, 20/00, 23/08, 27/01, 2F/08, 2C/02, 2B/08, 28/01
526// 04/80, 05/02, 00/C8, 00/C8, 00/C0, 1B/2C, 00/01, 00/C0, 1B/6C, 0F/10, 0D/07, 0B/07, 09/D2, 07/D6, 05/00, 04/00,
527// 20/00, 23/08, 27/01, 2F/08, 2C/02, 2B/08, 28/01, 37/08, 34/04, 33/08, 30/03, 04/80, 05/02, 1B/6C, 00/C8
528WRITE16_HANDLER( cybiko_unk1_w )
529{
530   if ACCESSING_MSB16 logerror( "[%08X] <- %02X\n", 0x200000 + offset * 2 + 0, (data >> 8) & 0xFF);
531   if ACCESSING_LSB16 logerror( "[%08X] <- %02X\n", 0x200000 + offset * 2 + 1, (data >> 0) & 0xFF);
532}
533 
534READ16_HANDLER( cybiko_unk2_r )
535{
536   switch (offset << 1)
537   {
538      case 0x000 : return 0xBA0B; break; // magic (part 1)
539      case 0x002 : return 0xAB15; break; // magic (part 2)
540      case 0x004 : return (0x07 << 8) | (0x07 ^0xFF); break; // brightness (or contrast) & value xor FF
541//      case 0x006 : return 0x2B57; break; // do not show "Free Games and Applications at www.cybiko.com" screen
542      case 0x008 : return 0xDEBA; break; // enable debug output
543      case 0x016 : return 0x5000 | 0x03FF; break; // ?
544      case 0x7FC : return 0x22A1; break; // crc32 (part 1)
545      case 0x7FE : return 0x8728; break; // crc32 (part 2)
546      default    : return 0xFFFF; break;
547   }
548}
1/*
2
3   Cybiko Wireless Inter-tainment System
4
5   (c) 2001-2007 Tim Schuerewegen
6
7   Cybiko Classic (V1)
8   Cybiko Classic (V2)
9   Cybiko Xtreme
10
11*/
12
13#include "includes/cybiko.h"
14
15#include "cpu/h8s2xxx/h8s2xxx.h"
16#include "video/hd66421.h"
17#include "sound/speaker.h"
18#include "machine/pcf8593.h"
19#include "machine/at45dbxx.h"
20#include "machine/sst39vfx.h"
21#include "debugger.h"
22
23#define LOG_LEVEL  1
24#define _logerror(level,...)  if (LOG_LEVEL > level) logerror(__VA_ARGS__)
25
26/////////////////////////
27// FUNCTION PROTOTYPES //
28/////////////////////////
29
30#define MACHINE_STOP(name) \
31   void machine_stop_##name( running_machine *machine)
32
33// machine stop
34MACHINE_STOP( cybikov1 );
35MACHINE_STOP( cybikov2 );
36MACHINE_STOP( cybikoxt );
37
38// rs232
39void cybiko_rs232_init( void);
40void cybiko_rs232_exit( void);
41void cybiko_rs232_reset( void);
42
43////////////////////////
44// DRIVER INIT & EXIT //
45////////////////////////
46
47static void init_ram_handler( offs_t start, offs_t size, offs_t mirror)
48{
49   memory_install_read_handler( 0, ADDRESS_SPACE_PROGRAM, start, start + size - 1, 0, mirror - size, STATIC_BANK1);
50   memory_install_write_handler( 0, ADDRESS_SPACE_PROGRAM, start, start + size - 1, 0, mirror - size, STATIC_BANK1);
51   memory_set_bankptr( 1, mess_ram);
52}
53
54DRIVER_INIT( cybikov1 )
55{
56   _logerror( 0, "init_cybikov1\n");
57   init_ram_handler( 0x200000, mess_ram_size, 0x200000);
58}
59
60DRIVER_INIT( cybikov2 )
61{
62   _logerror( 0, "init_cybikov2\n");
63   init_ram_handler( 0x200000, mess_ram_size, 0x200000);
64}
65
66DRIVER_INIT( cybikoxt )
67{
68   _logerror( 0, "init_cybikoxt\n");
69   init_ram_handler( 0x400000, mess_ram_size, 0x200000);
70}
71
72////////////////////
73// NVRAM HANDLERS //
74////////////////////
75
76/*
77NVRAM_HANDLER( cybikov1 )
78{
79   _logerror( 0, "nvram_handler_cybikov1 (%p/%d)\n", file, read_or_write);
80   nvram_handler_at45dbxx( machine, file, read_or_write);
81   nvram_handler_pcf8593( machine, file, read_or_write);
82}
83*/
84
85/*
86NVRAM_HANDLER( cybikov2 )
87{
88   _logerror( 0, "nvram_handler_cybikov2 (%p/%d)\n", file, read_or_write);
89   nvram_handler_at45dbxx( machine, file, read_or_write);
90   nvram_handler_sst39vfx( machine, file, read_or_write);
91   nvram_handler_pcf8593( machine, file, read_or_write);
92}
93*/
94
95/*
96NVRAM_HANDLER( cybikoxt )
97{
98   _logerror( 0, "nvram_handler_cybikoxt (%p/%d)\n", file, read_or_write);
99   nvram_handler_sst39vfx( machine, file, read_or_write);
100   nvram_handler_pcf8593( machine, file, read_or_write);
101}
102*/
103
104///////////////////
105// MACHINE START //
106///////////////////
107
108static mame_file *nvram_system_fopen( running_machine *machine, UINT32 openflags, const char *name)
109{
110   astring *fname;
111   file_error filerr;
112   mame_file *file;
113   fname = astring_assemble_4( astring_alloc(), machine->gamedrv->name, PATH_SEPARATOR, name, ".nv");
114   filerr = mame_fopen( SEARCHPATH_NVRAM, astring_c( fname), openflags, &file);
115   astring_free( fname);
116   return (filerr == FILERR_NONE) ? file : NULL;
117}
118
119typedef void (nvram_load_func)( mame_file *file);
120
121static int nvram_system_load( running_machine *machine, const char *name, nvram_load_func _nvram_load, int required)
122{
123   mame_file *file;
124   file = nvram_system_fopen( machine, OPEN_FLAG_READ, name);
125   if (!file)
126   {
127      if (required) mame_printf_error( "nvram load failed (%s)\n", name);
128      return FALSE;
129   }
130   _nvram_load( file);
131   mame_fclose( file);
132   return TRUE;
133}
134
135typedef void (nvram_save_func)( mame_file *file);
136
137static int nvram_system_save( running_machine *machine, const char *name, nvram_save_func _nvram_save)
138{
139   mame_file *file;
140   file = nvram_system_fopen( machine, OPEN_FLAG_CREATE | OPEN_FLAG_WRITE | OPEN_FLAG_CREATE_PATHS, name);
141   if (!file)
142   {
143      mame_printf_error( "nvram save failed (%s)\n", name);
144      return FALSE;
145   }
146   _nvram_save( file);
147   mame_fclose( file);
148   return TRUE;
149}
150
151MACHINE_START( cybikov1 )
152{
153   _logerror( 0, "machine_start_cybikov1\n");
154   // real-time clock
155   pcf8593_init();
156   nvram_system_load( machine, "rtc", pcf8593_load, 0);
157   // serial dataflash
158   at45dbxx_init( AT45DB041);
159   nvram_system_load( machine, "flash1", &at45dbxx_load, 1);
160   // serial port
161   cybiko_rs232_init();
162   // other
163   add_exit_callback( machine, machine_stop_cybikov1);
164}
165
166MACHINE_START( cybikov2 )
167{
168   _logerror( 0, "machine_start_cybikov2\n");
169   // real-time clock
170   pcf8593_init();
171   nvram_system_load( machine, "rtc", pcf8593_load, 0);
172   // serial dataflash
173   at45dbxx_init( AT45DB041);
174   nvram_system_load( machine, "flash1", &at45dbxx_load, 1);
175   // multi-purpose flash
176   sst39vfx_init( SST39VF020, 16, CPU_IS_BE);
177   nvram_system_load( machine, "flash2", &sst39vfx_load, 1);
178   memory_set_bankptr( 2, sst39vfx_get_base());
179   // serial port
180   cybiko_rs232_init();
181   // other
182   add_exit_callback( machine, machine_stop_cybikov2);
183}
184
185MACHINE_START( cybikoxt )
186{
187   _logerror( 0, "machine_start_cybikoxt\n");
188   // real-time clock
189   pcf8593_init();
190   nvram_system_load( machine, "rtc", pcf8593_load, 0);
191   // multi-purpose flash
192   sst39vfx_init( SST39VF400A, 16, CPU_IS_BE);
193   nvram_system_load( machine, "flash1", &sst39vfx_load, 1);
194   memory_set_bankptr( 2, sst39vfx_get_base());
195   // serial port
196   cybiko_rs232_init();
197   // other
198   add_exit_callback( machine, machine_stop_cybikoxt);
199}
200
201///////////////////
202// MACHINE RESET //
203///////////////////
204
205MACHINE_RESET( cybikov1 )
206{
207   _logerror( 0, "machine_reset_cybikov1\n");
208   pcf8593_reset();
209   at45dbxx_reset();
210   cybiko_rs232_reset();
211}
212
213MACHINE_RESET( cybikov2 )
214{
215   _logerror( 0, "machine_reset_cybikov2\n");
216   pcf8593_reset();
217   at45dbxx_reset();
218   sst39vfx_reset();
219   cybiko_rs232_reset();
220}
221
222MACHINE_RESET( cybikoxt )
223{
224   _logerror( 0, "machine_reset_cybikoxt\n");
225   pcf8593_reset();
226   sst39vfx_reset();
227   cybiko_rs232_reset();
228}
229
230//////////////////
231// MACHINE STOP //
232//////////////////
233
234MACHINE_STOP( cybikov1 )
235{
236   _logerror( 0, "machine_stop_cybikov1\n");
237   // real-time clock
238   nvram_system_save( machine, "rtc", pcf8593_save);
239   pcf8593_exit();
240   // serial dataflash
241   nvram_system_save( machine, "flash1", &at45dbxx_save);
242   at45dbxx_exit();
243   // serial port
244   cybiko_rs232_exit();
245}
246
247MACHINE_STOP( cybikov2 )
248{
249   _logerror( 0, "machine_stop_cybikov2\n");
250   // real-time clock
251   nvram_system_save( machine, "rtc", pcf8593_save);
252   pcf8593_exit();
253   // serial dataflash
254   nvram_system_save( machine, "flash1", &at45dbxx_save);
255   at45dbxx_exit();
256   // multi-purpose flash
257   nvram_system_save( machine, "flash2", &sst39vfx_save);
258   sst39vfx_exit();
259   // serial port
260   cybiko_rs232_exit();
261}
262
263MACHINE_STOP( cybikoxt )
264{
265   _logerror( 0, "machine_stop_cybikoxt\n");
266   // real-time clock
267   nvram_system_save( machine, "rtc", pcf8593_save);
268   pcf8593_exit();
269   // multi-purpose flash
270   nvram_system_save( machine, "flash1", &sst39vfx_save);
271   sst39vfx_exit();
272   // serial port
273   cybiko_rs232_exit();
274}
275
276///////////
277// RS232 //
278///////////
279
280typedef struct
281{
282   int sck; // serial clock
283   int txd; // transmit data
284   int rxd; // receive data
285} CYBIKO_RS232_PINS;
286
287typedef struct
288{
289   CYBIKO_RS232_PINS pin;
290   UINT8 rx_bits, rx_byte, tx_byte, tx_bits;
291} CYBIKO_RS232;
292
293static CYBIKO_RS232 rs232;
294
295void cybiko_rs232_init( void)
296{
297   _logerror( 0, "cybiko_rs232_init\n");
298   memset( &rs232, 0, sizeof( rs232));
299//   timer_pulse( TIME_IN_HZ( 10), 0, rs232_timer_callback);
300}
301
302void cybiko_rs232_exit( void)
303{
304   _logerror( 0, "cybiko_rs232_exit\n");
305}
306
307void cybiko_rs232_reset( void)
308{
309   _logerror( 0, "cybiko_rs232_reset\n");
310}
311
312void cybiko_rs232_write_byte( UINT8 data)
313{
314   #if 0
315   printf( "%c", data);
316   #endif
317}
318
319void cybiko_rs232_pin_sck( int data)
320{
321   _logerror( 3, "cybiko_rs232_pin_sck (%d)\n", data);
322   // clock high-to-low
323   if ((rs232.pin.sck == 1) && (data == 0))
324   {
325      // transmit
326      if (rs232.pin.txd) rs232.tx_byte = rs232.tx_byte | (1 << rs232.tx_bits);
327      rs232.tx_bits++;
328      if (rs232.tx_bits == 8)
329      {
330         rs232.tx_bits = 0;
331         cybiko_rs232_write_byte( rs232.tx_byte);
332         rs232.tx_byte = 0;
333      }
334      // receive
335      rs232.pin.rxd = (rs232.rx_byte >> rs232.rx_bits) & 1;
336      rs232.rx_bits++;
337      if (rs232.rx_bits == 8)
338      {
339         rs232.rx_bits = 0;
340         rs232.rx_byte = 0;
341      }
342   }
343   // save sck
344   rs232.pin.sck = data;
345}
346
347void cybiko_rs232_pin_txd( int data)
348{
349   _logerror( 3, "cybiko_rs232_pin_txd (%d)\n", data);
350   rs232.pin.txd = data;
351}
352
353int cybiko_rs232_pin_rxd( void)
354{
355   _logerror( 3, "cybiko_rs232_pin_rxd\n");
356   return rs232.pin.rxd;
357}
358
359int cybiko_rs232_rx_queue( void)
360{
361   return 0;
362}
363
364/////////////////////////
365// READ/WRITE HANDLERS //
366/////////////////////////
367
368READ16_HANDLER( cybiko_lcd_r )
369{
370   UINT16 data = 0;
371   if ACCESSING_MSB16 data = data | (hd66421_reg_idx_r() << 8);
372   if ACCESSING_LSB16 data = data | (hd66421_reg_dat_r() << 0);
373   return data;
374}
375
376WRITE16_HANDLER( cybiko_lcd_w )
377{
378   if ACCESSING_MSB16 hd66421_reg_idx_w( (data >> 8) & 0xFF);
379   if ACCESSING_LSB16 hd66421_reg_dat_w( (data >> 0) & 0xFF);
380}
381
382READ8_HANDLER( cybiko_key_r_byte )
383{
384   UINT8 data = 0xFF;
385   int i;
386   _logerror( 2, "cybiko_key_r_byte (%08X)\n", offset);
387   // A11
388   if (!(offset & (1 << 11))) data &= 0xFE;
389   // A1 .. A9
390   for (i=1;i<10;i++) if (!(offset & (1 << i))) data &= readinputport( i - 1);
391   // A0
392   if (!(offset & (1 <<  0))) data |= 0xFF;
393   //
394   return data;
395}
396
397READ16_HANDLER( cybiko_key_r )
398{
399   UINT16 data = 0;
400   _logerror( 2, "cybiko_key_r (%08X/%04X)\n", offset, mem_mask);
401   if ACCESSING_MSB16 data = data | (cybiko_key_r_byte( offset * 2 + 0) << 8);
402   if ACCESSING_LSB16 data = data | (cybiko_key_r_byte( offset * 2 + 1) << 0);
403   _logerror( 2, "%04X\n", data);
404   return data;
405}
406
407READ8_HANDLER( cybiko_io_reg_r )
408{
409   UINT8 data = 0;
410   _logerror( 2, "cybiko_io_reg_r (%08X)\n", offset);
411   switch (offset)
412   {
413      // keyboard
414      case H8S_IO_PORT1 :
415      {
416         //if (readinputport(0) & 0x02) data = data | 0x08; else data = data & (~0x08); // "esc" key
417         data = data | 0x08;
418      }
419      break;
420      // serial dataflash
421      case H8S_IO_PORT3 : if (at45dbxx_pin_so()) data = data | H8S_P3_RXD1; break;
422      // rs232
423      case H8S_IO_PORT5 : if (cybiko_rs232_pin_rxd()) data = data | H8S_P5_RXD2; break;
424      // real-time clock
425      case H8S_IO_PORTF :
426      {
427         data = H8S_PF_PF2;
428         if (pcf8593_pin_sda_r()) data |= H8S_PF_PF0;
429      }
430      break;
431      // serial 2
432      case H8S_IO_SSR2 :
433      {
434         if (cybiko_rs232_rx_queue()) data = data | H8S_SSR_RDRF;
435      }
436      break;
437   }
438   return data;
439}
440
441WRITE8_HANDLER( cybiko_io_reg_w )
442{
443   _logerror( 2, "cybiko_io_reg_w (%08X/%02X)\n", offset, data);
444   switch (offset)
445   {
446      // speaker
447      case H8S_IO_P1DR : speaker_level_w( 0, (data & H8S_P1_TIOCB1) ? 1 : 0); break;
448      // serial dataflash
449      case H8S_IO_P3DR :
450      {
451         at45dbxx_pin_cs ( (data & H8S_P3_SCK0) ? 0 : 1);
452         at45dbxx_pin_si ( (data & H8S_P3_TXD1) ? 1 : 0);
453         at45dbxx_pin_sck( (data & H8S_P3_SCK1) ? 1 : 0);
454      }
455      break;
456      // rs232
457      case H8S_IO_P5DR :
458      {
459         cybiko_rs232_pin_txd( (data & H8S_P5_TXD2) ? 1 : 0);
460         cybiko_rs232_pin_sck( (data & H8S_P5_SCK2) ? 1 : 0);
461      }
462      break;
463      // real-time clock
464      case H8S_IO_PFDR  : pcf8593_pin_scl( (data & H8S_PF_PF1) ? 1 : 0); break;
465      case H8S_IO_PFDDR : pcf8593_pin_sda_w( (data & H8S_PF_PF0) ? 0 : 1); break;
466   }
467}
468
469READ8_HANDLER( cybikov1_io_reg_r )
470{
471   _logerror( 2, "cybikov1_io_reg_r (%08X)\n", offset);
472   return cybiko_io_reg_r( offset);
473}
474
475READ8_HANDLER( cybikov2_io_reg_r )
476{
477   _logerror( 2, "cybikov2_io_reg_r (%08X)\n", offset);
478   return cybiko_io_reg_r( offset);
479}
480
481READ8_HANDLER( cybikoxt_io_reg_r )
482{
483   UINT8 data = 0;
484   _logerror( 2, "cybikoxt_io_reg_r (%08X)\n", offset);
485   switch (offset)
486   {
487      // rs232
488      case H8S_IO_PORT3 : if (cybiko_rs232_pin_rxd()) data = data | H8S_P3_RXD1; break;
489      // default
490      default : data = cybiko_io_reg_r( offset);
491   }
492   return data;
493}
494
495WRITE8_HANDLER( cybikov1_io_reg_w )
496{
497   _logerror( 2, "cybikov1_io_reg_w (%08X/%02X)\n", offset, data);
498   cybiko_io_reg_w( offset, data);
499}
500
501WRITE8_HANDLER( cybikov2_io_reg_w )
502{
503   _logerror( 2, "cybikov2_io_reg_w (%08X/%02X)\n", offset, data);
504   cybiko_io_reg_w( offset, data);
505}
506
507WRITE8_HANDLER( cybikoxt_io_reg_w )
508{
509   _logerror( 2, "cybikoxt_io_reg_w (%08X/%02X)\n", offset, data);
510   switch (offset)
511   {
512      // rs232
513      case H8S_IO_P3DR :
514      {
515         cybiko_rs232_pin_txd( (data & H8S_P3_TXD1) ? 1 : 0);
516         cybiko_rs232_pin_sck( (data & H8S_P3_SCK1) ? 1 : 0);
517      }
518      break;
519      // default
520      default : cybiko_io_reg_w( offset, data);
521   }
522}
523
524// Cybiko Xtreme writes following byte pairs to 0x200003/0x200000
525// 00/01, 00/C0, 0F/32, 0D/03, 0B/03, 09/50, 07/D6, 05/00, 04/00, 20/00, 23/08, 27/01, 2F/08, 2C/02, 2B/08, 28/01
526// 04/80, 05/02, 00/C8, 00/C8, 00/C0, 1B/2C, 00/01, 00/C0, 1B/6C, 0F/10, 0D/07, 0B/07, 09/D2, 07/D6, 05/00, 04/00,
527// 20/00, 23/08, 27/01, 2F/08, 2C/02, 2B/08, 28/01, 37/08, 34/04, 33/08, 30/03, 04/80, 05/02, 1B/6C, 00/C8
528WRITE16_HANDLER( cybiko_unk1_w )
529{
530   if ACCESSING_MSB16 logerror( "[%08X] <- %02X\n", 0x200000 + offset * 2 + 0, (data >> 8) & 0xFF);
531   if ACCESSING_LSB16 logerror( "[%08X] <- %02X\n", 0x200000 + offset * 2 + 1, (data >> 0) & 0xFF);
532}
533
534READ16_HANDLER( cybiko_unk2_r )
535{
536   switch (offset << 1)
537   {
538      case 0x000 : return 0xBA0B; break; // magic (part 1)
539      case 0x002 : return 0xAB15; break; // magic (part 2)
540      case 0x004 : return (0x07 << 8) | (0x07 ^0xFF); break; // brightness (or contrast) & value xor FF
541//      case 0x006 : return 0x2B57; break; // do not show "Free Games and Applications at www.cybiko.com" screen
542      case 0x008 : return 0xDEBA; break; // enable debug output
543      case 0x016 : return 0x5000 | 0x03FF; break; // ?
544      case 0x7FC : return 0x22A1; break; // crc32 (part 1)
545      case 0x7FE : return 0x8728; break; // crc32 (part 2)
546      default    : return 0xFFFF; break;
547   }
548}
src/mess/drivers/cybiko.c
r882r883
1/*
2 
3   Cybiko Wireless Inter-tainment System
4 
5   (c) 2001-2007 Tim Schuerewegen
6 
7   Cybiko Classic (V1)
8   Cybiko Classic (V2)
9   Cybiko Xtreme
10 
11*/
12 
13#include "includes/cybiko.h"
14 
15#include "driver.h"
16#include "cpu/h8s2xxx/h8s2xxx.h"
17#include "video/hd66421.h"
18#include "inputx.h"
19#include "cybiko.lh"
20 
21//   +------------------------------------------------------+
22//   | Cybiko Classic (CY6411)                         | V2 |
23//   +------------------------------------------------------+
24//   | - CYBIKO | CY-OS 1.1.7 | 6432241M04FA | 0028R JAPAN  |
25//   | - SST 39VF020 | 90-4C-WH | 0012175-D                 |
26//   | - ATMEL 0027 | AT90S2313-4SC                         |
27//   | - ATMEL | AT45DB041A | TC | 0027                     |
28//   | - RF2915 | RFMD0028 | 0F540BT                        |
29//   | - EliteMT | LP62S2048X-70LLT | 0026B H4A27HA         |
30//   | - MP02AB | LMX2315 | TMD                             |
31//   +------------------------------------------------------+
32 
33//   +------------------------------------------------------+
34//   | Cybiko Xtreme (CY44802)                              |
35//   +------------------------------------------------------+
36//   | - CYBIKO | CYBOOT 1.5A | HD6432323G03F | 0131 JAPAN  |
37//   | - SST 39VF400A | 70-4C-EK                            |
38//   | - ATMEL 0033 | AT90S2313-4SC                         |
39//   | - SAMSUNG 129 | K4F171612D-TL60                      |
40//   | - 2E16AB | USBN9604-28M | NSC00A1                    |
41//   +------------------------------------------------------+
42 
43//   +------------------------------------------------------+
44//   | Cybiko MP3 Player (CY65P10)                          |
45//   +------------------------------------------------------+
46//   | - H8S/2246 | 0G1 | HD6472246FA20 | JAPAN             |
47//   | - MICRONAS | DAC3550A C2 | 0394 22 HM U | 089472.000 |
48//   | - 2E08AJ | USBN9603-28M | NSC99A1                    |
49//   +------------------------------------------------------+
50 
51///////////////////////////
52// ADDRESS MAP - PROGRAM //
53///////////////////////////
54 
55#define AM_RANGE_SL( start, length) \
56   AM_RANGE( start, start + length - 1)
57 
58// 512 kbyte ram + no memory mapped flash
59ADDRESS_MAP_START( cybikov1_mem, ADDRESS_SPACE_PROGRAM, 16 )
60   AM_RANGE_SL( 0x000000, 0x008000) AM_ROM
61//   AM_RANGE_SL( 0x200000, 0x080000) AM_RAM AM_MIRROR( 0x180000)
62   AM_RANGE_SL( 0x600000, 0x000002) AM_READWRITE( cybiko_lcd_r, cybiko_lcd_w)
63   AM_RANGE_SL( 0xE00000, 0x008000) AM_READ( cybiko_key_r)
64ADDRESS_MAP_END
65 
66//   +-------------------------------------+
67//   | Cybiko Classic (V2) - Memory Map    |
68//   +-------------------------------------+
69//   | 000000 - 007FFF | rom               |
70//   | 008000 - 00FFFF | 17 51 17 51 ..    |
71//   | 010000 - 0FFFFF | flash mirror      |
72//   | 100000 - 13FFFF | flash             |
73//   | 140000 - 1FFFFF | flash mirror      |
74//   | 200000 - 23FFFF | ram               |
75//   | 240000 - 3FFFFF | ram mirror        |
76//   | 400000 - 5FFFFF | FF FF FF FF ..    |
77//   | 600000 - 600001 | lcd               |
78//   | 600002 - DFFFFF | FF FF FF FF ..    |
79//   | E00000 - FFDBFF | keyboard          |
80//   | FFDC00 - FFFFFF | onchip ram & regs |
81//   +-------------------------------------+
82 
83// 256 kbyte ram + 256 kbyte memory mapped flash
84ADDRESS_MAP_START( cybikov2_mem, ADDRESS_SPACE_PROGRAM, 16 )
85   AM_RANGE_SL( 0x000000, 0x008000) AM_ROM
86   AM_RANGE_SL( 0x100000, 0x040000) AM_READ( MRA16_BANK2) AM_MIRROR( 0x0C0000)
87//   AM_RANGE_SL( 0x200000, 0x040000) AM_RAM AM_MIRROR( 0x1C0000)
88   AM_RANGE_SL( 0x600000, 0x000002) AM_READWRITE( cybiko_lcd_r, cybiko_lcd_w)
89   AM_RANGE_SL( 0xE00000, 0x1FDC00) AM_READ( cybiko_key_r)
90ADDRESS_MAP_END
91 
92// 2048? kbyte ram + 512 kbyte memory mapped flash
93ADDRESS_MAP_START( cybikoxt_mem, ADDRESS_SPACE_PROGRAM, 16 )
94   AM_RANGE_SL( 0x000000, 0x008000) AM_ROM
95   AM_RANGE_SL( 0x100000, 0x000002) AM_READWRITE( cybiko_lcd_r, cybiko_lcd_w)
96   AM_RANGE_SL( 0x200000, 0x000004) AM_WRITE( cybiko_unk1_w)
97//   AM_RANGE_SL( 0x400000, 0x200000) AM_RAM
98   AM_RANGE_SL( 0x600000, 0x080000) AM_READ( MRA16_BANK2)
99   AM_RANGE_SL( 0x7FF800, 0x000800) AM_READ( cybiko_unk2_r)
100   AM_RANGE_SL( 0xE00000, 0x1FDC00) AM_READ( cybiko_key_r)
101ADDRESS_MAP_END
102 
103//////////////////////
104// ADDRESS MAP - IO //
105//////////////////////
106 
107ADDRESS_MAP_START( cybikov1_io, ADDRESS_SPACE_IO, 8 )
108   AM_RANGE( 0xFFFE40, 0xFFFFFF) AM_READWRITE( cybikov1_io_reg_r, cybikov1_io_reg_w)
109ADDRESS_MAP_END
110 
111ADDRESS_MAP_START( cybikov2_io, ADDRESS_SPACE_IO, 8 )
112   AM_RANGE( 0xFFFE40, 0xFFFFFF) AM_READWRITE( cybikov2_io_reg_r, cybikov2_io_reg_w)
113ADDRESS_MAP_END
114 
115ADDRESS_MAP_START( cybikoxt_io, ADDRESS_SPACE_IO, 8 )
116   AM_RANGE( 0xFFFE40, 0xFFFFFF) AM_READWRITE( cybikoxt_io_reg_r, cybikoxt_io_reg_w)
117ADDRESS_MAP_END
118 
119/////////////////
120// INPUT PORTS //
121/////////////////
122 
123#define CYBIKO_PORT_BIT_K( mask)  \
124   PORT_BIT( mask, IP_ACTIVE_LOW, IPT_KEYBOARD)
125 
126#define CYBIKO_PORT_BIT_U( mask)  \
127   PORT_BIT( mask, IP_ACTIVE_LOW, IPT_UNUSED)
128 
129INPUT_PORTS_START( cybiko)
130   PORT_START // A1
131   CYBIKO_PORT_BIT_K( 0x01) PORT_NAME( "F7"    ) PORT_CODE( KEYCODE_F7        ) PORT_CHAR( UCHAR_MAMEKEY( F7    ))
132   CYBIKO_PORT_BIT_K( 0x02) PORT_NAME( "Esc"   ) PORT_CODE( KEYCODE_ESC       ) PORT_CHAR( UCHAR_MAMEKEY( ESC   ))
133   CYBIKO_PORT_BIT_K( 0x04) PORT_NAME( "Del"   ) PORT_CODE( KEYCODE_DEL       ) PORT_CHAR( UCHAR_MAMEKEY( DEL   ))
134   CYBIKO_PORT_BIT_K( 0x08) PORT_NAME( "Left"  ) PORT_CODE( KEYCODE_LEFT      ) PORT_CHAR( UCHAR_MAMEKEY( LEFT  ))
135   CYBIKO_PORT_BIT_K( 0x10) PORT_NAME( "Q"     ) PORT_CODE( KEYCODE_Q         ) PORT_CHAR( 'Q'                   )
136   CYBIKO_PORT_BIT_K( 0x20) PORT_NAME( "A"     ) PORT_CODE( KEYCODE_A         ) PORT_CHAR( 'A'                   )
137   CYBIKO_PORT_BIT_K( 0x40) PORT_NAME( "`"     )                                PORT_CHAR( '`'                   )
138   CYBIKO_PORT_BIT_K( 0x80) PORT_NAME( "Shift" ) PORT_CODE( KEYCODE_LSHIFT    ) PORT_CHAR( UCHAR_SHIFT_1         )
139   PORT_START // A2
140   CYBIKO_PORT_BIT_K( 0x01) PORT_NAME( "F6"    ) PORT_CODE( KEYCODE_F6        ) PORT_CHAR( UCHAR_MAMEKEY( F6    ))
141   CYBIKO_PORT_BIT_K( 0x02) PORT_NAME( "Up"    ) PORT_CODE( KEYCODE_UP        ) PORT_CHAR( UCHAR_MAMEKEY( UP    ))
142   CYBIKO_PORT_BIT_K( 0x04) PORT_NAME( "Ins"   ) PORT_CODE( KEYCODE_INSERT    ) PORT_CHAR( UCHAR_MAMEKEY( INSERT))
143   CYBIKO_PORT_BIT_K( 0x08) PORT_NAME( "2 @"   ) PORT_CODE( KEYCODE_2         ) PORT_CHAR( '2'                   ) PORT_CHAR( '@')
144   CYBIKO_PORT_BIT_K( 0x10) PORT_NAME( "W"     ) PORT_CODE( KEYCODE_W         ) PORT_CHAR( 'W'                   )
145   CYBIKO_PORT_BIT_K( 0x20) PORT_NAME( "S"     ) PORT_CODE( KEYCODE_S         ) PORT_CHAR( 'S'                   )
146   CYBIKO_PORT_BIT_K( 0x40) PORT_NAME( "Z"     ) PORT_CODE( KEYCODE_Z         ) PORT_CHAR( 'Z'                   )
147   CYBIKO_PORT_BIT_K( 0x80) PORT_NAME( "Fn"    ) PORT_CODE( KEYCODE_LCONTROL  ) PORT_CHAR( UCHAR_SHIFT_2         )
148   PORT_START // A3
149   CYBIKO_PORT_BIT_K( 0x01) PORT_NAME( "F5"    ) PORT_CODE( KEYCODE_F5        ) PORT_CHAR( UCHAR_MAMEKEY( F5    ))
150   CYBIKO_PORT_BIT_K( 0x02) PORT_NAME( "F3"    ) PORT_CODE( KEYCODE_F3        ) PORT_CHAR( UCHAR_MAMEKEY( F3    ))
151   CYBIKO_PORT_BIT_K( 0x04) PORT_NAME( "Space" ) PORT_CODE( KEYCODE_SPACE     ) PORT_CHAR( ' '                   )
152   CYBIKO_PORT_BIT_K( 0x08) PORT_NAME( "3 #"   ) PORT_CODE( KEYCODE_3         ) PORT_CHAR( '3'                   ) PORT_CHAR( '#')
153   CYBIKO_PORT_BIT_K( 0x10) PORT_NAME( "E"     ) PORT_CODE( KEYCODE_E         ) PORT_CHAR( 'E'                   )
154   CYBIKO_PORT_BIT_K( 0x20) PORT_NAME( "D"     ) PORT_CODE( KEYCODE_D         ) PORT_CHAR( 'D'                   )
155   CYBIKO_PORT_BIT_K( 0x40) PORT_NAME( "X"     ) PORT_CODE( KEYCODE_X         ) PORT_CHAR( 'X'                   )
156   CYBIKO_PORT_BIT_K( 0x80) PORT_NAME( "Help"  ) PORT_CODE( KEYCODE_END       ) PORT_CHAR( UCHAR_MAMEKEY( END   ))
157   PORT_START // A4
158   CYBIKO_PORT_BIT_K( 0x01) PORT_NAME( "F4"    ) PORT_CODE( KEYCODE_F4        ) PORT_CHAR( UCHAR_MAMEKEY( F4    ))
159   CYBIKO_PORT_BIT_K( 0x02) PORT_NAME( "1 !"   ) PORT_CODE( KEYCODE_1         ) PORT_CHAR( '1'                   ) PORT_CHAR( '!')
160   CYBIKO_PORT_BIT_K( 0x04) PORT_NAME( "Tab"   ) PORT_CODE( KEYCODE_TAB       ) PORT_CHAR( 9                     )
161   CYBIKO_PORT_BIT_K( 0x08) PORT_NAME( "4 $"   ) PORT_CODE( KEYCODE_4         ) PORT_CHAR( '4'                   ) PORT_CHAR( '$')
162   CYBIKO_PORT_BIT_K( 0x10) PORT_NAME( "R"     ) PORT_CODE( KEYCODE_R         ) PORT_CHAR( 'R'                   )
163   CYBIKO_PORT_BIT_K( 0x20) PORT_NAME( "F"     ) PORT_CODE( KEYCODE_F         ) PORT_CHAR( 'F'                   )
164   CYBIKO_PORT_BIT_K( 0x40) PORT_NAME( "C"     ) PORT_CODE( KEYCODE_C         ) PORT_CHAR( 'C'                   )
165   CYBIKO_PORT_BIT_K( 0x80) PORT_NAME( "[ {"   ) PORT_CODE( KEYCODE_OPENBRACE ) PORT_CHAR( '['                   )
166   PORT_START // A5
167   CYBIKO_PORT_BIT_K( 0x01) PORT_NAME( "Right" ) PORT_CODE( KEYCODE_RIGHT     ) PORT_CHAR( UCHAR_MAMEKEY( RIGHT ))
168   CYBIKO_PORT_BIT_K( 0x02) PORT_NAME( "Down"  ) PORT_CODE( KEYCODE_DOWN      ) PORT_CHAR( UCHAR_MAMEKEY( DOWN  ))
169   CYBIKO_PORT_BIT_K( 0x04) PORT_NAME( "Select") PORT_CODE( KEYCODE_HOME      ) PORT_CHAR( UCHAR_MAMEKEY( HOME  ))
170   CYBIKO_PORT_BIT_K( 0x08) PORT_NAME( "5 %"   ) PORT_CODE( KEYCODE_5         ) PORT_CHAR( '5'                   ) PORT_CHAR( '%')
171   CYBIKO_PORT_BIT_K( 0x10) PORT_NAME( "T"     ) PORT_CODE( KEYCODE_T         ) PORT_CHAR( 'T'                   )
172   CYBIKO_PORT_BIT_K( 0x20) PORT_NAME( "G"     ) PORT_CODE( KEYCODE_G         ) PORT_CHAR( 'G'                   )
173   CYBIKO_PORT_BIT_K( 0x40) PORT_NAME( "V"     ) PORT_CODE( KEYCODE_V         ) PORT_CHAR( 'V'                   )
174   CYBIKO_PORT_BIT_K( 0x80) PORT_NAME( "] }"   ) PORT_CODE( KEYCODE_CLOSEBRACE) PORT_CHAR( ']'                   )
175   PORT_START // A6
176   CYBIKO_PORT_BIT_K( 0x01) PORT_NAME( "F2"    ) PORT_CODE( KEYCODE_F2        ) PORT_CHAR( UCHAR_MAMEKEY( F2    ))
177   CYBIKO_PORT_BIT_K( 0x02) PORT_NAME( "; :"   ) PORT_CODE( KEYCODE_COLON     ) PORT_CHAR( ';'                   ) PORT_CHAR( ':')
178   CYBIKO_PORT_BIT_K( 0x04) PORT_NAME( "Enter" ) PORT_CODE( KEYCODE_ENTER     ) PORT_CHAR( 13                    )
179   CYBIKO_PORT_BIT_K( 0x08) PORT_NAME( "6 ^"   ) PORT_CODE( KEYCODE_6         ) PORT_CHAR( '6'                   )
180   CYBIKO_PORT_BIT_K( 0x10) PORT_NAME( "Y"     ) PORT_CODE( KEYCODE_Y         ) PORT_CHAR( 'Y'                   )
181   CYBIKO_PORT_BIT_K( 0x20) PORT_NAME( "H"     ) PORT_CODE( KEYCODE_H         ) PORT_CHAR( 'H'                   )
182   CYBIKO_PORT_BIT_K( 0x40) PORT_NAME( "B"     ) PORT_CODE( KEYCODE_B         ) PORT_CHAR( 'B'                   )
183   CYBIKO_PORT_BIT_K( 0x80) PORT_NAME( "\\ |"  ) PORT_CODE( KEYCODE_BACKSLASH ) PORT_CHAR( '\\'                  ) PORT_CHAR( '|')
184   PORT_START // A7
185   CYBIKO_PORT_BIT_K( 0x01) PORT_NAME( "F1"    ) PORT_CODE( KEYCODE_F1        ) PORT_CHAR( UCHAR_MAMEKEY( F1    ))
186   CYBIKO_PORT_BIT_K( 0x02) PORT_NAME( "/ ?"   ) PORT_CODE( KEYCODE_SLASH     ) PORT_CHAR( '/'                   ) PORT_CHAR( '?')
187   CYBIKO_PORT_BIT_K( 0x04) PORT_NAME( "BkSp"  ) PORT_CODE( KEYCODE_BACKSPACE ) PORT_CHAR( 8                     )
188   CYBIKO_PORT_BIT_K( 0x08) PORT_NAME( "7 &"   ) PORT_CODE( KEYCODE_7         ) PORT_CHAR( '7'                   ) PORT_CHAR( '&')
189   CYBIKO_PORT_BIT_K( 0x10) PORT_NAME( "U"     ) PORT_CODE( KEYCODE_U         ) PORT_CHAR( 'U'                   )
190   CYBIKO_PORT_BIT_K( 0x20) PORT_NAME( "J"     ) PORT_CODE( KEYCODE_J         ) PORT_CHAR( 'J'                   )
191   CYBIKO_PORT_BIT_K( 0x40) PORT_NAME( "N"     ) PORT_CODE( KEYCODE_N         ) PORT_CHAR( 'N'                   )
192   CYBIKO_PORT_BIT_U( 0x80)
193   PORT_START // A8
194   CYBIKO_PORT_BIT_K( 0x01) PORT_NAME( "- _"   ) PORT_CODE( KEYCODE_MINUS     ) PORT_CHAR( '-'                   ) PORT_CHAR( '_')
195   CYBIKO_PORT_BIT_K( 0x02) PORT_NAME( ". >"   )                                PORT_CHAR( '.'                   ) PORT_CHAR( '>')
196   CYBIKO_PORT_BIT_K( 0x04) PORT_NAME( "0 )"   ) PORT_CODE( KEYCODE_0         ) PORT_CHAR( '0'                   ) PORT_CHAR( ')')
197   CYBIKO_PORT_BIT_K( 0x08) PORT_NAME( "8 *"   ) PORT_CODE( KEYCODE_8         ) PORT_CHAR( '8'                   ) PORT_CHAR( '*')
198   CYBIKO_PORT_BIT_K( 0x10) PORT_NAME( "I"     ) PORT_CODE( KEYCODE_I         ) PORT_CHAR( 'I'                   )
199   CYBIKO_PORT_BIT_K( 0x20) PORT_NAME( "K"     ) PORT_CODE( KEYCODE_K         ) PORT_CHAR( 'K'                   )
200   CYBIKO_PORT_BIT_K( 0x40) PORT_NAME( "M"     ) PORT_CODE( KEYCODE_M         ) PORT_CHAR( 'M'                   )
201   CYBIKO_PORT_BIT_U( 0x80)
202   PORT_START // A9
203   CYBIKO_PORT_BIT_K( 0x01) PORT_NAME( "' \""  ) PORT_CODE( KEYCODE_QUOTE     ) PORT_CHAR( '\''                  ) PORT_CHAR( '"')
204   CYBIKO_PORT_BIT_K( 0x02) PORT_NAME( "= +"   ) PORT_CODE( KEYCODE_EQUALS    ) PORT_CHAR( '='                   ) PORT_CHAR( '+')
205   CYBIKO_PORT_BIT_K( 0x04) PORT_NAME( "9 ("   ) PORT_CODE( KEYCODE_9         ) PORT_CHAR( '9'                   ) PORT_CHAR( '(')
206   CYBIKO_PORT_BIT_K( 0x08) PORT_NAME( "P"     ) PORT_CODE( KEYCODE_P         ) PORT_CHAR( 'P'                   )
207   CYBIKO_PORT_BIT_K( 0x10) PORT_NAME( "O"     ) PORT_CODE( KEYCODE_O         ) PORT_CHAR( 'O'                   )
208   CYBIKO_PORT_BIT_K( 0x20) PORT_NAME( "L"     ) PORT_CODE( KEYCODE_L         ) PORT_CHAR( 'L'                   )
209   CYBIKO_PORT_BIT_K( 0x40) PORT_NAME( ", <"   ) PORT_CODE( KEYCODE_COMMA     ) PORT_CHAR( ','                   ) PORT_CHAR( '<')
210   CYBIKO_PORT_BIT_U( 0x80)
211INPUT_PORTS_END
212 
213/////////
214// ROM //
215/////////
216 
217ROM_START( cybikov1 )
218   ROM_REGION( 0x8000, REGION_CPU1, 0)
219   ROM_LOAD( "cyrom112.bin", 0, 0x8000, CRC(9E1F1A0F) SHA1(6FC08DE6B2C67D884EC78F748E4A4BAD27EE8045))
220ROM_END
221 
222ROM_START( cybikov2 )
223   ROM_REGION( 0x8000, REGION_CPU1, 0)
224   ROM_LOAD( "cyrom117.bin", 0, 0x8000, CRC(268DA7BF) SHA1(135EAF9E3905E69582AABD9B06BC4DE0A66780D5))
225ROM_END
226 
227ROM_START( cybikoxt )
228   ROM_REGION( 0x8000, REGION_CPU1, 0)
229   ROM_LOAD( "cyrom150.bin", 0, 0x8000, CRC(18B9B21F) SHA1(28868D6174EB198A6CEC6C3C70B6E494517229B9))
230ROM_END
231 
232///////////////////
233// SYSTEM CONFIG //
234///////////////////
235 
236SYSTEM_CONFIG_START( cybikov1 )
237   CONFIG_RAM_DEFAULT( 512 * 1024)
238   CONFIG_RAM( 1024 * 1024)
239SYSTEM_CONFIG_END
240 
241SYSTEM_CONFIG_START( cybikov2 )
242   CONFIG_RAM_DEFAULT( 256 * 1024)
243   CONFIG_RAM(  512 * 1024)
244   CONFIG_RAM( 1024 * 1024)
245SYSTEM_CONFIG_END
246 
247SYSTEM_CONFIG_START( cybikoxt )
248   CONFIG_RAM_DEFAULT( 2048 * 1024)
249SYSTEM_CONFIG_END
250 
251////////////////////
252// MACHINE DRIVER //
253////////////////////
254 
255MACHINE_DRIVER_START( cybikov1 )
256   // cpu
257   MDRV_CPU_ADD_TAG( "main", H8S2241, 11059200)
258   MDRV_CPU_PROGRAM_MAP( cybikov1_mem, 0)
259   MDRV_CPU_IO_MAP( cybikov1_io, 0)
260   // screen
261   MDRV_SCREEN_REFRESH_RATE( 60)
262   MDRV_SCREEN_FORMAT( BITMAP_FORMAT_INDEXED16)
263   MDRV_SCREEN_SIZE( HD66421_WIDTH, HD66421_HEIGHT)
264   MDRV_SCREEN_VISIBLE_AREA( 0, HD66421_WIDTH - 1, 0, HD66421_HEIGHT - 1)
265   // video
266   MDRV_VIDEO_ATTRIBUTES( VIDEO_TYPE_RASTER)
267   MDRV_PALETTE_LENGTH( 4)
268   MDRV_COLORTABLE_LENGTH( 4)
269   MDRV_PALETTE_INIT( hd66421)
270   MDRV_VIDEO_START( hd66421)
271   MDRV_VIDEO_UPDATE( hd66421)
272   MDRV_DEFAULT_LAYOUT( layout_cybiko)
273   // sound
274   MDRV_SPEAKER_STANDARD_MONO( "mono")
275   MDRV_SOUND_ADD_TAG( "speaker", SPEAKER, 0)
276   MDRV_SOUND_ROUTE( ALL_OUTPUTS, "mono", 1.00)
277   // machine
278   MDRV_MACHINE_START( cybikov1)
279   MDRV_MACHINE_RESET( cybikov1)
280   // non-volatile ram
281//   MDRV_NVRAM_HANDLER( cybikov1)
282MACHINE_DRIVER_END
283 
284MACHINE_DRIVER_START( cybikov2 )
285   // import
286   MDRV_IMPORT_FROM( cybikov1)
287   // cpu
288   MDRV_CPU_REPLACE( "main", H8S2246, 11059200)
289   MDRV_CPU_PROGRAM_MAP( cybikov2_mem, 0)
290   MDRV_CPU_IO_MAP( cybikov2_io, 0)
291   // machine
292   MDRV_MACHINE_START( cybikov2)
293   MDRV_MACHINE_RESET( cybikov2)
294   // non-volatile ram
295//   MDRV_NVRAM_HANDLER( cybikov2)
296MACHINE_DRIVER_END
297 
298MACHINE_DRIVER_START( cybikoxt )
299   // import
300   MDRV_IMPORT_FROM( cybikov1)
301   // cpu
302   MDRV_CPU_REPLACE( "main", H8S2323, 18432000)
303   MDRV_CPU_PROGRAM_MAP( cybikoxt_mem, 0)
304   MDRV_CPU_IO_MAP( cybikoxt_io, 0)
305   // sound
306   MDRV_SPEAKER_REMOVE( "mono")
307   MDRV_SOUND_REMOVE( "speaker")
308   // machine
309   MDRV_MACHINE_START( cybikoxt)
310   MDRV_MACHINE_RESET( cybikoxt)
311   // non-volatile ram
312//   MDRV_NVRAM_HANDLER( cybikoxt)
313MACHINE_DRIVER_END
314 
315//////////////
316// COMPUTER //
317//////////////
318 
319// YEAR - NAME - PARENT - BIOS - COMPAT - MACHINE - INPUT - INIT - CONFIG - COMPANY - FULLNAME - FLAGS
320COMPB( 2000, cybikov1, 0,        0, 0, cybikov1, cybiko, cybikov1, cybikov1, "Cybiko, Inc.", "Cybiko Classic (V1)", GAME_IMPERFECT_SOUND)
321COMPB( 2000, cybikov2, cybikov1, 0, 0, cybikov2, cybiko, cybikov2, cybikov2, "Cybiko, Inc.", "Cybiko Classic (V2)", GAME_IMPERFECT_SOUND)
322COMPB( 2001, cybikoxt, cybikov1, 0, 0, cybikoxt, cybiko, cybikoxt, cybikoxt, "Cybiko, Inc.", "Cybiko Xtreme",       GAME_NO_SOUND | GAME_NOT_WORKING)
1/*
2
3   Cybiko Wireless Inter-tainment System
4
5   (c) 2001-2007 Tim Schuerewegen
6
7   Cybiko Classic (V1)
8   Cybiko Classic (V2)
9   Cybiko Xtreme
10
11*/
12
13#include "includes/cybiko.h"
14
15#include "driver.h"
16#include "cpu/h8s2xxx/h8s2xxx.h"
17#include "video/hd66421.h"
18#include "inputx.h"
19#include "cybiko.lh"
20
21//   +------------------------------------------------------+
22//   | Cybiko Classic (CY6411)                         | V2 |
23//   +------------------------------------------------------+
24//   | - CYBIKO | CY-OS 1.1.7 | 6432241M04FA | 0028R JAPAN  |
25//   | - SST 39VF020 | 90-4C-WH | 0012175-D                 |
26//   | - ATMEL 0027 | AT90S2313-4SC                         |
27//   | - ATMEL | AT45DB041A | TC | 0027                     |
28//   | - RF2915 | RFMD0028 | 0F540BT                        |
29//   | - EliteMT | LP62S2048X-70LLT | 0026B H4A27HA         |
30//   | - MP02AB | LMX2315 | TMD                             |
31//   +------------------------------------------------------+
32
33//   +------------------------------------------------------+
34//   | Cybiko Xtreme (CY44802)                              |
35//   +------------------------------------------------------+
36//   | - CYBIKO | CYBOOT 1.5A | HD6432323G03F | 0131 JAPAN  |
37//   | - SST 39VF400A | 70-4C-EK                            |
38//   | - ATMEL 0033 | AT90S2313-4SC                         |
39//   | - SAMSUNG 129 | K4F171612D-TL60                      |
40//   | - 2E16AB | USBN9604-28M | NSC00A1                    |
41//   +------------------------------------------------------+
42
43//   +------------------------------------------------------+
44//   | Cybiko MP3 Player (CY65P10)                          |
45//   +------------------------------------------------------+
46//   | - H8S/2246 | 0G1 | HD6472246FA20 | JAPAN             |
47//   | - MICRONAS | DAC3550A C2 | 0394 22 HM U | 089472.000 |
48//   | - 2E08AJ | USBN9603-28M | NSC99A1                    |
49//   +------------------------------------------------------+
50
51///////////////////////////
52// ADDRESS MAP - PROGRAM //
53///////////////////////////
54
55#define AM_RANGE_SL( start, length) \
56   AM_RANGE( start, start + length - 1)
57
58// 512 kbyte ram + no memory mapped flash
59ADDRESS_MAP_START( cybikov1_mem, ADDRESS_SPACE_PROGRAM, 16 )
60   AM_RANGE_SL( 0x000000, 0x008000) AM_ROM
61//   AM_RANGE_SL( 0x200000, 0x080000) AM_RAM AM_MIRROR( 0x180000)
62   AM_RANGE_SL( 0x600000, 0x000002) AM_READWRITE( cybiko_lcd_r, cybiko_lcd_w)
63   AM_RANGE_SL( 0xE00000, 0x008000) AM_READ( cybiko_key_r)
64ADDRESS_MAP_END
65
66//   +-------------------------------------+
67//   | Cybiko Classic (V2) - Memory Map    |
68//   +-------------------------------------+
69//   | 000000 - 007FFF | rom               |
70//   | 008000 - 00FFFF | 17 51 17 51 ..    |
71//   | 010000 - 0FFFFF | flash mirror      |
72//   | 100000 - 13FFFF | flash             |
73//   | 140000 - 1FFFFF | flash mirror      |
74//   | 200000 - 23FFFF | ram               |
75//   | 240000 - 3FFFFF | ram mirror        |
76//   | 400000 - 5FFFFF | FF FF FF FF ..    |
77//   | 600000 - 600001 | lcd               |
78//   | 600002 - DFFFFF | FF FF FF FF ..    |
79//   | E00000 - FFDBFF | keyboard          |
80//   | FFDC00 - FFFFFF | onchip ram & regs |
81//   +-------------------------------------+
82
83// 256 kbyte ram + 256 kbyte memory mapped flash
84ADDRESS_MAP_START( cybikov2_mem, ADDRESS_SPACE_PROGRAM, 16 )
85   AM_RANGE_SL( 0x000000, 0x008000) AM_ROM
86   AM_RANGE_SL( 0x100000, 0x040000) AM_READ( MRA16_BANK2) AM_MIRROR( 0x0C0000)
87//   AM_RANGE_SL( 0x200000, 0x040000) AM_RAM AM_MIRROR( 0x1C0000)
88   AM_RANGE_SL( 0x600000, 0x000002) AM_READWRITE( cybiko_lcd_r, cybiko_lcd_w)
89   AM_RANGE_SL( 0xE00000, 0x1FDC00) AM_READ( cybiko_key_r)
90ADDRESS_MAP_END
91
92// 2048? kbyte ram + 512 kbyte memory mapped flash
93ADDRESS_MAP_START( cybikoxt_mem, ADDRESS_SPACE_PROGRAM, 16 )
94   AM_RANGE_SL( 0x000000, 0x008000) AM_ROM
95   AM_RANGE_SL( 0x100000, 0x000002) AM_READWRITE( cybiko_lcd_r, cybiko_lcd_w)
96   AM_RANGE_SL( 0x200000, 0x000004) AM_WRITE( cybiko_unk1_w)
97//   AM_RANGE_SL( 0x400000, 0x200000) AM_RAM
98   AM_RANGE_SL( 0x600000, 0x080000) AM_READ( MRA16_BANK2)
99   AM_RANGE_SL( 0x7FF800, 0x000800) AM_READ( cybiko_unk2_r)
100   AM_RANGE_SL( 0xE00000, 0x1FDC00) AM_READ( cybiko_key_r)
101ADDRESS_MAP_END
102
103//////////////////////
104// ADDRESS MAP - IO //
105//////////////////////
106
107ADDRESS_MAP_START( cybikov1_io, ADDRESS_SPACE_IO, 8 )
108   AM_RANGE( 0xFFFE40, 0xFFFFFF) AM_READWRITE( cybikov1_io_reg_r, cybikov1_io_reg_w)
109ADDRESS_MAP_END
110
111ADDRESS_MAP_START( cybikov2_io, ADDRESS_SPACE_IO, 8 )
112   AM_RANGE( 0xFFFE40, 0xFFFFFF) AM_READWRITE( cybikov2_io_reg_r, cybikov2_io_reg_w)
113ADDRESS_MAP_END
114
115ADDRESS_MAP_START( cybikoxt_io, ADDRESS_SPACE_IO, 8 )
116   AM_RANGE( 0xFFFE40, 0xFFFFFF) AM_READWRITE( cybikoxt_io_reg_r, cybikoxt_io_reg_w)
117ADDRESS_MAP_END
118
119/////////////////
120// INPUT PORTS //
121/////////////////
122
123#define CYBIKO_PORT_BIT_K( mask)  \
124   PORT_BIT( mask, IP_ACTIVE_LOW, IPT_KEYBOARD)
125
126#define CYBIKO_PORT_BIT_U( mask)  \
127   PORT_BIT( mask, IP_ACTIVE_LOW, IPT_UNUSED)
128
129INPUT_PORTS_START( cybiko)
130   PORT_START // A1
131   CYBIKO_PORT_BIT_K( 0x01) PORT_NAME( "F7"    ) PORT_CODE( KEYCODE_F7        ) PORT_CHAR( UCHAR_MAMEKEY( F7    ))
132   CYBIKO_PORT_BIT_K( 0x02) PORT_NAME( "Esc"   ) PORT_CODE( KEYCODE_ESC       ) PORT_CHAR( UCHAR_MAMEKEY( ESC   ))
133   CYBIKO_PORT_BIT_K( 0x04) PORT_NAME( "Del"   ) PORT_CODE( KEYCODE_DEL       ) PORT_CHAR( UCHAR_MAMEKEY( DEL   ))
134   CYBIKO_PORT_BIT_K( 0x08) PORT_NAME( "Left"  ) PORT_CODE( KEYCODE_LEFT      ) PORT_CHAR( UCHAR_MAMEKEY( LEFT  ))
135   CYBIKO_PORT_BIT_K( 0x10) PORT_NAME( "Q"     ) PORT_CODE( KEYCODE_Q         ) PORT_CHAR( 'Q'                   )
136   CYBIKO_PORT_BIT_K( 0x20) PORT_NAME( "A"     ) PORT_CODE( KEYCODE_A         ) PORT_CHAR( 'A'                   )
137   CYBIKO_PORT_BIT_K( 0x40) PORT_NAME( "`"     )                                PORT_CHAR( '`'                   )
138   CYBIKO_PORT_BIT_K( 0x80) PORT_NAME( "Shift" ) PORT_CODE( KEYCODE_LSHIFT    ) PORT_CHAR( UCHAR_SHIFT_1         )
139   PORT_START // A2
140   CYBIKO_PORT_BIT_K( 0x01) PORT_NAME( "F6"    ) PORT_CODE( KEYCODE_F6        ) PORT_CHAR( UCHAR_MAMEKEY( F6    ))
141   CYBIKO_PORT_BIT_K( 0x02) PORT_NAME( "Up"    ) PORT_CODE( KEYCODE_UP        ) PORT_CHAR( UCHAR_MAMEKEY( UP    ))
142   CYBIKO_PORT_BIT_K( 0x04) PORT_NAME( "Ins"   ) PORT_CODE( KEYCODE_INSERT    ) PORT_CHAR( UCHAR_MAMEKEY( INSERT))
143   CYBIKO_PORT_BIT_K( 0x08) PORT_NAME( "2 @"   ) PORT_CODE( KEYCODE_2         ) PORT_CHAR( '2'                   ) PORT_CHAR( '@')
144   CYBIKO_PORT_BIT_K( 0x10) PORT_NAME( "W"     ) PORT_CODE( KEYCODE_W         ) PORT_CHAR( 'W'                   )
145   CYBIKO_PORT_BIT_K( 0x20) PORT_NAME( "S"     ) PORT_CODE( KEYCODE_S         ) PORT_CHAR( 'S'                   )
146   CYBIKO_PORT_BIT_K( 0x40) PORT_NAME( "Z"     ) PORT_CODE( KEYCODE_Z         ) PORT_CHAR( 'Z'                   )
147   CYBIKO_PORT_BIT_K( 0x80) PORT_NAME( "Fn"    ) PORT_CODE( KEYCODE_LCONTROL  ) PORT_CHAR( UCHAR_SHIFT_2         )
148   PORT_START // A3
149   CYBIKO_PORT_BIT_K( 0x01) PORT_NAME( "F5"    ) PORT_CODE( KEYCODE_F5        ) PORT_CHAR( UCHAR_MAMEKEY( F5    ))
150   CYBIKO_PORT_BIT_K( 0x02) PORT_NAME( "F3"    ) PORT_CODE( KEYCODE_F3        ) PORT_CHAR( UCHAR_MAMEKEY( F3    ))
151   CYBIKO_PORT_BIT_K( 0x04) PORT_NAME( "Space" ) PORT_CODE( KEYCODE_SPACE     ) PORT_CHAR( ' '                   )
152   CYBIKO_PORT_BIT_K( 0x08) PORT_NAME( "3 #"   ) PORT_CODE( KEYCODE_3         ) PORT_CHAR( '3'                   ) PORT_CHAR( '#')
153   CYBIKO_PORT_BIT_K( 0x10) PORT_NAME( "E"     ) PORT_CODE( KEYCODE_E         ) PORT_CHAR( 'E'                   )
154   CYBIKO_PORT_BIT_K( 0x20) PORT_NAME( "D"     ) PORT_CODE( KEYCODE_D         ) PORT_CHAR( 'D'                   )
155   CYBIKO_PORT_BIT_K( 0x40) PORT_NAME( "X"     ) PORT_CODE( KEYCODE_X         ) PORT_CHAR( 'X'                   )
156   CYBIKO_PORT_BIT_K( 0x80) PORT_NAME( "Help"  ) PORT_CODE( KEYCODE_END       ) PORT_CHAR( UCHAR_MAMEKEY( END   ))
157   PORT_START // A4
158   CYBIKO_PORT_BIT_K( 0x01) PORT_NAME( "F4"    ) PORT_CODE( KEYCODE_F4        ) PORT_CHAR( UCHAR_MAMEKEY( F4    ))
159   CYBIKO_PORT_BIT_K( 0x02) PORT_NAME( "1 !"   ) PORT_CODE( KEYCODE_1         ) PORT_CHAR( '1'                   ) PORT_CHAR( '!')
160   CYBIKO_PORT_BIT_K( 0x04) PORT_NAME( "Tab"   ) PORT_CODE( KEYCODE_TAB       ) PORT_CHAR( 9                     )
161   CYBIKO_PORT_BIT_K( 0x08) PORT_NAME( "4 $"   ) PORT_CODE( KEYCODE_4         ) PORT_CHAR( '4'                   ) PORT_CHAR( '$')
162   CYBIKO_PORT_BIT_K( 0x10) PORT_NAME( "R"     ) PORT_CODE( KEYCODE_R         ) PORT_CHAR( 'R'                   )
163   CYBIKO_PORT_BIT_K( 0x20) PORT_NAME( "F"     ) PORT_CODE( KEYCODE_F         ) PORT_CHAR( 'F'                   )
164   CYBIKO_PORT_BIT_K( 0x40) PORT_NAME( "C"     ) PORT_CODE( KEYCODE_C         ) PORT_CHAR( 'C'                   )
165   CYBIKO_PORT_BIT_K( 0x80) PORT_NAME( "[ {"   ) PORT_CODE( KEYCODE_OPENBRACE ) PORT_CHAR( '['                   )
166   PORT_START // A5
167   CYBIKO_PORT_BIT_K( 0x01) PORT_NAME( "Right" ) PORT_CODE( KEYCODE_RIGHT     ) PORT_CHAR( UCHAR_MAMEKEY( RIGHT ))
168   CYBIKO_PORT_BIT_K( 0x02) PORT_NAME( "Down"  ) PORT_CODE( KEYCODE_DOWN      ) PORT_CHAR( UCHAR_MAMEKEY( DOWN  ))
169   CYBIKO_PORT_BIT_K( 0x04) PORT_NAME( "Select") PORT_CODE( KEYCODE_HOME      ) PORT_CHAR( UCHAR_MAMEKEY( HOME  ))
170   CYBIKO_PORT_BIT_K( 0x08) PORT_NAME( "5 %"   ) PORT_CODE( KEYCODE_5         ) PORT_CHAR( '5'                   ) PORT_CHAR( '%')
171   CYBIKO_PORT_BIT_K( 0x10) PORT_NAME( "T"     ) PORT_CODE( KEYCODE_T         ) PORT_CHAR( 'T'                   )
172   CYBIKO_PORT_BIT_K( 0x20) PORT_NAME( "G"     ) PORT_CODE( KEYCODE_G         ) PORT_CHAR( 'G'                   )
173   CYBIKO_PORT_BIT_K( 0x40) PORT_NAME( "V"     ) PORT_CODE( KEYCODE_V         ) PORT_CHAR( 'V'                   )
174   CYBIKO_PORT_BIT_K( 0x80) PORT_NAME( "] }"   ) PORT_CODE( KEYCODE_CLOSEBRACE) PORT_CHAR( ']'                   )
175   PORT_START // A6
176   CYBIKO_PORT_BIT_K( 0x01) PORT_NAME( "F2"    ) PORT_CODE( KEYCODE_F2        ) PORT_CHAR( UCHAR_MAMEKEY( F2    ))
177   CYBIKO_PORT_BIT_K( 0x02) PORT_NAME( "; :"   ) PORT_CODE( KEYCODE_COLON     ) PORT_CHAR( ';'                   ) PORT_CHAR( ':')
178   CYBIKO_PORT_BIT_K( 0x04) PORT_NAME( "Enter" ) PORT_CODE( KEYCODE_ENTER     ) PORT_CHAR( 13                    )
179   CYBIKO_PORT_BIT_K( 0x08) PORT_NAME( "6 ^"   ) PORT_CODE( KEYCODE_6         ) PORT_CHAR( '6'                   )
180   CYBIKO_PORT_BIT_K( 0x10) PORT_NAME( "Y"     ) PORT_CODE( KEYCODE_Y         ) PORT_CHAR( 'Y'                   )
181   CYBIKO_PORT_BIT_K( 0x20) PORT_NAME( "H"     ) PORT_CODE( KEYCODE_H         ) PORT_CHAR( 'H'                   )
182   CYBIKO_PORT_BIT_K( 0x40) PORT_NAME( "B"     ) PORT_CODE( KEYCODE_B         ) PORT_CHAR( 'B'                   )
183   CYBIKO_PORT_BIT_K( 0x80) PORT_NAME( "\\ |"  ) PORT_CODE( KEYCODE_BACKSLASH ) PORT_CHAR( '\\'                  ) PORT_CHAR( '|')
184   PORT_START // A7
185   CYBIKO_PORT_BIT_K( 0x01) PORT_NAME( "F1"    ) PORT_CODE( KEYCODE_F1        ) PORT_CHAR( UCHAR_MAMEKEY( F1    ))
186   CYBIKO_PORT_BIT_K( 0x02) PORT_NAME( "/ ?"   ) PORT_CODE( KEYCODE_SLASH     ) PORT_CHAR( '/'                   ) PORT_CHAR( '?')
187   CYBIKO_PORT_BIT_K( 0x04) PORT_NAME( "BkSp"  ) PORT_CODE( KEYCODE_BACKSPACE ) PORT_CHAR( 8                     )
188   CYBIKO_PORT_BIT_K( 0x08) PORT_NAME( "7 &"   ) PORT_CODE( KEYCODE_7         ) PORT_CHAR( '7'                   ) PORT_CHAR( '&')
189   CYBIKO_PORT_BIT_K( 0x10) PORT_NAME( "U"     ) PORT_CODE( KEYCODE_U         ) PORT_CHAR( 'U'                   )
190   CYBIKO_PORT_BIT_K( 0x20) PORT_NAME( "J"     ) PORT_CODE( KEYCODE_J         ) PORT_CHAR( 'J'                   )
191   CYBIKO_PORT_BIT_K( 0x40) PORT_NAME( "N"     ) PORT_CODE( KEYCODE_N         ) PORT_CHAR( 'N'                   )
192   CYBIKO_PORT_BIT_U( 0x80)
193   PORT_START // A8
194   CYBIKO_PORT_BIT_K( 0x01) PORT_NAME( "- _"   ) PORT_CODE( KEYCODE_MINUS     ) PORT_CHAR( '-'                   ) PORT_CHAR( '_')
195   CYBIKO_PORT_BIT_K( 0x02) PORT_NAME( ". >"   )                                PORT_CHAR( '.'                   ) PORT_CHAR( '>')
196   CYBIKO_PORT_BIT_K( 0x04) PORT_NAME( "0 )"   ) PORT_CODE( KEYCODE_0         ) PORT_CHAR( '0'                   ) PORT_CHAR( ')')
197   CYBIKO_PORT_BIT_K( 0x08) PORT_NAME( "8 *"   ) PORT_CODE( KEYCODE_8         ) PORT_CHAR( '8'                   ) PORT_CHAR( '*')
198   CYBIKO_PORT_BIT_K( 0x10) PORT_NAME( "I"     ) PORT_CODE( KEYCODE_I         ) PORT_CHAR( 'I'                   )
199   CYBIKO_PORT_BIT_K( 0x20) PORT_NAME( "K"     ) PORT_CODE( KEYCODE_K         ) PORT_CHAR( 'K'                   )
200   CYBIKO_PORT_BIT_K( 0x40) PORT_NAME( "M"     ) PORT_CODE( KEYCODE_M         ) PORT_CHAR( 'M'                   )
201   CYBIKO_PORT_BIT_U( 0x80)
202   PORT_START // A9
203   CYBIKO_PORT_BIT_K( 0x01) PORT_NAME( "' \""  ) PORT_CODE( KEYCODE_QUOTE     ) PORT_CHAR( '\''                  ) PORT_CHAR( '"')
204   CYBIKO_PORT_BIT_K( 0x02) PORT_NAME( "= +"   ) PORT_CODE( KEYCODE_EQUALS    ) PORT_CHAR( '='                   ) PORT_CHAR( '+')
205   CYBIKO_PORT_BIT_K( 0x04) PORT_NAME( "9 ("   ) PORT_CODE( KEYCODE_9         ) PORT_CHAR( '9'                   ) PORT_CHAR( '(')
206   CYBIKO_PORT_BIT_K( 0x08) PORT_NAME( "P"     ) PORT_CODE( KEYCODE_P         ) PORT_CHAR( 'P'                   )
207   CYBIKO_PORT_BIT_K( 0x10) PORT_NAME( "O"     ) PORT_CODE( KEYCODE_O         ) PORT_CHAR( 'O'                   )
208   CYBIKO_PORT_BIT_K( 0x20) PORT_NAME( "L"     ) PORT_CODE( KEYCODE_L         ) PORT_CHAR( 'L'                   )
209   CYBIKO_PORT_BIT_K( 0x40) PORT_NAME( ", <"   ) PORT_CODE( KEYCODE_COMMA     ) PORT_CHAR( ','                   ) PORT_CHAR( '<')
210   CYBIKO_PORT_BIT_U( 0x80)
211INPUT_PORTS_END
212
213/////////
214// ROM //
215/////////
216
217ROM_START( cybikov1 )
218   ROM_REGION( 0x8000, REGION_CPU1, 0)
219   ROM_LOAD( "cyrom112.bin", 0, 0x8000, CRC(9E1F1A0F) SHA1(6FC08DE6B2C67D884EC78F748E4A4BAD27EE8045))
220ROM_END
221
222ROM_START( cybikov2 )
223   ROM_REGION( 0x8000, REGION_CPU1, 0)
224   ROM_LOAD( "cyrom117.bin", 0, 0x8000, CRC(268DA7BF) SHA1(135EAF9E3905E69582AABD9B06BC4DE0A66780D5))
225ROM_END
226
227ROM_START( cybikoxt )
228   ROM_REGION( 0x8000, REGION_CPU1, 0)
229   ROM_LOAD( "cyrom150.bin", 0, 0x8000, CRC(18B9B21F) SHA1(28868D6174EB198A6CEC6C3C70B6E494517229B9))
230ROM_END
231
232///////////////////
233// SYSTEM CONFIG //
234///////////////////
235
236SYSTEM_CONFIG_START( cybikov1 )
237   CONFIG_RAM_DEFAULT( 512 * 1024)
238   CONFIG_RAM( 1024 * 1024)
239SYSTEM_CONFIG_END
240
241SYSTEM_CONFIG_START( cybikov2 )
242   CONFIG_RAM_DEFAULT( 256 * 1024)
243   CONFIG_RAM(  512 * 1024)
244   CONFIG_RAM( 1024 * 1024)
245SYSTEM_CONFIG_END
246
247SYSTEM_CONFIG_START( cybikoxt )
248   CONFIG_RAM_DEFAULT( 2048 * 1024)
249SYSTEM_CONFIG_END
250
251////////////////////
252// MACHINE DRIVER //
253////////////////////
254
255MACHINE_DRIVER_START( cybikov1 )
256   // cpu
257   MDRV_CPU_ADD_TAG( "main", H8S2241, 11059200)
258   MDRV_CPU_PROGRAM_MAP( cybikov1_mem, 0)
259   MDRV_CPU_IO_MAP( cybikov1_io, 0)
260   // screen
261   MDRV_SCREEN_REFRESH_RATE( 60)
262   MDRV_SCREEN_FORMAT( BITMAP_FORMAT_INDEXED16)
263   MDRV_SCREEN_SIZE( HD66421_WIDTH, HD66421_HEIGHT)
264   MDRV_SCREEN_VISIBLE_AREA( 0, HD66421_WIDTH - 1, 0, HD66421_HEIGHT - 1)
265   // video
266   MDRV_VIDEO_ATTRIBUTES( VIDEO_TYPE_RASTER)
267   MDRV_PALETTE_LENGTH( 4)
268   MDRV_COLORTABLE_LENGTH( 4)
269   MDRV_PALETTE_INIT( hd66421)
270   MDRV_VIDEO_START( hd66421)
271   MDRV_VIDEO_UPDATE( hd66421)
272   MDRV_DEFAULT_LAYOUT( layout_cybiko)
273   // sound
274   MDRV_SPEAKER_STANDARD_MONO( "mono")
275   MDRV_SOUND_ADD_TAG( "speaker", SPEAKER, 0)
276   MDRV_SOUND_ROUTE( ALL_OUTPUTS, "mono", 1.00)
277   // machine
278   MDRV_MACHINE_START( cybikov1)
279   MDRV_MACHINE_RESET( cybikov1)
280   // non-volatile ram
281//   MDRV_NVRAM_HANDLER( cybikov1)
282MACHINE_DRIVER_END
283
284MACHINE_DRIVER_START( cybikov2 )
285   // import
286   MDRV_IMPORT_FROM( cybikov1)
287   // cpu
288   MDRV_CPU_REPLACE( "main", H8S2246, 11059200)
289   MDRV_CPU_PROGRAM_MAP( cybikov2_mem, 0)
290   MDRV_CPU_IO_MAP( cybikov2_io, 0)
291   // machine
292   MDRV_MACHINE_START( cybikov2)
293   MDRV_MACHINE_RESET( cybikov2)
294   // non-volatile ram
295//   MDRV_NVRAM_HANDLER( cybikov2)
296MACHINE_DRIVER_END
297
298MACHINE_DRIVER_START( cybikoxt )
299   // import
300   MDRV_IMPORT_FROM( cybikov1)
301   // cpu
302   MDRV_CPU_REPLACE( "main", H8S2323, 18432000)
303   MDRV_CPU_PROGRAM_MAP( cybikoxt_mem, 0)
304   MDRV_CPU_IO_MAP( cybikoxt_io, 0)
305   // sound
306   MDRV_SPEAKER_REMOVE( "mono")
307   MDRV_SOUND_REMOVE( "speaker")
308   // machine
309   MDRV_MACHINE_START( cybikoxt)
310   MDRV_MACHINE_RESET( cybikoxt)
311   // non-volatile ram
312//   MDRV_NVRAM_HANDLER( cybikoxt)
313MACHINE_DRIVER_END
314
315//////////////
316// COMPUTER //
317//////////////
318
319// YEAR - NAME - PARENT - BIOS - COMPAT - MACHINE - INPUT - INIT - CONFIG - COMPANY - FULLNAME - FLAGS
320COMPB( 2000, cybikov1, 0,        0, 0, cybikov1, cybiko, cybikov1, cybikov1, "Cybiko, Inc.", "Cybiko Classic (V1)", GAME_IMPERFECT_SOUND)
321COMPB( 2000, cybikov2, cybikov1, 0, 0, cybikov2, cybiko, cybikov2, cybikov2, "Cybiko, Inc.", "Cybiko Classic (V2)", GAME_IMPERFECT_SOUND)
322COMPB( 2001, cybikoxt, cybikov1, 0, 0, cybikoxt, cybiko, cybikoxt, cybikoxt, "Cybiko, Inc.", "Cybiko Xtreme",       GAME_NO_SOUND | GAME_NOT_WORKING)

Previous 15994 Revisions Next


© 1998-2018 The MESS Team