Previous 15994 Revisions Next

r9247 Tuesday 28th September, 2010 at 02:24:45 UTC by Curt Coder
[VIDBRAIN] Added missing file.
[src/mess/video]vidbrain.c*

src/mess/video/vidbrain.c
r0r9247
1/*
2
3    TODO:
4
5   - X order
6   - freeze (light pen)
7   - screen size
8   - scanline based update
9   - partial updates to allow mid-screen zoom change
10
11*/
12
13#include "emu.h"
14#include "includes/vidbrain.h"
15#include "cpu/f8/f8.h"
16
17/***************************************************************************
18    CONSTANTS
19***************************************************************************/
20
21#define LOG 0
22
23// write-only registers
24#define REGISTER_COMMAND         0xf7
25#define REGISTER_BACKGROUND         0xf5
26#define REGISTER_FINAL_MODIFIER      0xf2
27#define REGISTER_Y_INTERRUPT      0xf0
28
29// read-only registers
30#define REGISTER_X_FREEZE         0xf8
31#define REGISTER_Y_FREEZE_LOW      0xf9
32#define REGISTER_Y_FREEZE_HIGH      0xfa
33#define REGISTER_CURRENT_Y_LOW      0xfb
34
35// read/write registers - RAM memory
36#define RAM_RP_LO               0x00   // cartridge pointer low order
37#define RAM_RP_HI               0x10   // cartridge pointer high order and color
38#define RAM_DX                  0x20   // dX, intensity, X-copy
39#define RAM_DY                  0x30   // dY
40#define RAM_X                  0x40   // X value
41#define RAM_Y_LO_A               0x50   // Y value low order list A
42#define RAM_Y_LO_B               0x60   // Y value low order list B
43#define RAM_XY_HI_A               0x70   // Y value high order and X order list A
44#define RAM_XY_HI_B               0x80   // Y value high order and Y order list B
45
46// command register bits
47#define COMMAND_YINT_H_O         0x80
48#define COMMAND_A_B               0x40
49#define COMMAND_Y_ZM            0x20
50#define COMMAND_KBD               0x10
51#define COMMAND_INT               0x08
52#define COMMAND_ENB               0x04
53#define COMMAND_FRZ               0x02
54#define COMMAND_X_ZM            0x01
55
56/***************************************************************************
57    READ/WRITE HANDLERS
58***************************************************************************/
59
60/*-------------------------------------------------
61    vidbrain_vlsi_r - video VLSI read
62-------------------------------------------------*/
63
64READ8_HANDLER( vidbrain_vlsi_r )
65{
66   vidbrain_state *state = space->machine->driver_data<vidbrain_state>();
67
68   UINT8 data = 0xff;
69
70   switch (offset)
71   {
72   case REGISTER_X_FREEZE:
73      data = state->freeze_x;
74      if (LOG) logerror("X-Freeze %02x\n", data);
75      break;
76
77   case REGISTER_Y_FREEZE_LOW:
78      data = state->freeze_y & 0xff;
79      if (LOG) logerror("Y-Freeze Low %02x\n", data);
80      break;
81
82   case REGISTER_Y_FREEZE_HIGH:
83      /*
84
85         bit      signal      description
86
87         0      Y-F8      Y freeze high order (MSB) bit
88         1      Y-C8      current Y counter high order (MSB) bit
89         2
90         3
91         4
92         5
93         6
94         7      O/_E      odd/even field
95
96      */
97
98      data = (state->field << 7) | (BIT(state->screen->vpos(), 8) << 1) | BIT(state->freeze_y, 8);
99      if (LOG) logerror("Y-Freeze High %02x\n", data);
100      break;
101
102   case REGISTER_CURRENT_Y_LOW:
103      data = state->screen->vpos() & 0xff;
104      if (LOG) logerror("Current-Y Low %02x\n", data);
105      break;
106
107   default:
108      if (offset < 0x90)
109         data = state->vlsi_ram[offset];
110      else
111         if (LOG) logerror("Unknown VLSI read from %02x!\n", offset);
112   }
113
114   return data;
115}
116
117/*-------------------------------------------------
118    set_y_interrupt - set Y interrupt timer
119-------------------------------------------------*/
120
121static void set_y_interrupt(vidbrain_state *state)
122{
123   int scanline = ((state->cmd & COMMAND_YINT_H_O) << 1) | state->y_int;
124
125   state->timer_y_int->adjust(state->screen->time_until_pos(scanline, 0), 0, state->screen->frame_period());
126}
127
128/*-------------------------------------------------
129    vidbrain_vlsi_w - video VLSI write
130-------------------------------------------------*/
131
132WRITE8_HANDLER( vidbrain_vlsi_w )
133{
134   vidbrain_state *state = space->machine->driver_data<vidbrain_state>();
135
136   switch (offset)
137   {
138   case REGISTER_Y_INTERRUPT:
139      if (LOG) logerror("Y-Interrupt %02x\n", data);
140
141      if (state->y_int != data)
142      {
143         state->y_int = data;
144         set_y_interrupt(state);
145      }
146      break;
147
148   case REGISTER_FINAL_MODIFIER:
149      /*
150
151         bit      signal      description
152
153         0      RED         red
154         1      GREEN      green
155         2      BLUE      blue
156         3      INT 0      intensity 0
157         4      INT 1      intensity 1
158         5      not used
159         6      not used
160         7      not used
161
162      */
163
164      if (LOG) logerror("Final Modifier %02x\n", data);
165
166      state->fmod = data & 0x1f;
167      break;
168
169   case REGISTER_BACKGROUND:
170      /*
171
172         bit      signal      description
173
174         0      RED         red
175         1      GREEN      green
176         2      BLUE      blue
177         3      INT 0      intensity 0
178         4      INT 1      intensity 1
179         5      not used
180         6      not used
181         7      not used
182
183      */
184
185      if (LOG) logerror("Background %02x\n", data);
186
187      state->bg = data & 0x1f;
188      break;
189
190   case REGISTER_COMMAND:
191      /*
192
193         bit      signal      description
194
195         0      X-ZM      X zoom
196         1      FRZ         freeze
197         2      ENB         COMMAND_ENB
198         3      INT         COMMAND_INT
199         4      KBD         general purpose output
200         5      Y-ZM      Y zoom
201         6      A/_B      list selection
202         7      YINT H.O.   Y COMMAND_INT register high order bit
203
204      */
205
206      if (LOG) logerror("Command %02x\n", data);
207     
208      if (BIT(state->cmd, 7) != BIT(data, 7))
209      {
210         set_y_interrupt(state);
211      }
212
213      state->cmd = data;
214      break;
215
216   default:
217      if (offset < 0x90)
218         state->vlsi_ram[offset] = data;
219      else
220         logerror("Unknown VLSI write %02x to %02x!\n", data, offset);
221   }
222}
223
224/***************************************************************************
225    VIDEO
226***************************************************************************/
227
228/*-------------------------------------------------
229    PALETTE_INIT( vidbrain )
230-------------------------------------------------*/
231
232static PALETTE_INIT( vidbrain )
233{
234   static const UINT8 INTENSITY[] = { 0x90, 0xb0, 0xd0, 0xff };
235
236   for (int i = 0; i < 4; i++)
237   {
238      int offset = i * 8;
239      UINT8 value = INTENSITY[i];
240
241      palette_set_color_rgb(machine, offset + 0, 0,      0,      0);      // black
242      palette_set_color_rgb(machine, offset + 1, value,   0,      0);      // red
243      palette_set_color_rgb(machine, offset + 2, 0,      value,   0);      // green
244      palette_set_color_rgb(machine, offset + 3, value,   value,   0);      // red-green
245      palette_set_color_rgb(machine, offset + 4, 0,      0,      value); // blue
246      palette_set_color_rgb(machine, offset + 5, value,   0,      value); // red-blue
247      palette_set_color_rgb(machine, offset + 6, 0,      value,   value); // green-blue
248      palette_set_color_rgb(machine, offset + 7, value,   value,   value); // white
249   }
250}
251
252/*-------------------------------------------------
253    VIDEO_START( vidbrain )
254-------------------------------------------------*/
255
256static VIDEO_START( vidbrain )
257{
258   vidbrain_state *state = machine->driver_data<vidbrain_state>();
259   
260   /* register for state saving */
261   state_save_register_global_array(machine, state->vlsi_ram);
262   state_save_register_global(machine, state->y_int);
263   state_save_register_global(machine, state->fmod);
264   state_save_register_global(machine, state->bg);
265   state_save_register_global(machine, state->cmd);
266   state_save_register_global(machine, state->freeze_x);
267   state_save_register_global(machine, state->freeze_y);
268   state_save_register_global(machine, state->field);
269
270   /* get the devices */
271   state->screen = machine->device<screen_device>(SCREEN_TAG);
272   state->timer_y_int = machine->device<timer_device>(TIMER_Y_INT_TAG);
273}
274
275/*-------------------------------------------------
276    VIDEO_UPDATE( vidbrain )
277-------------------------------------------------*/
278
279#define RAM(_offset) state->vlsi_ram[_offset + i]
280
281static VIDEO_UPDATE( vidbrain )
282{
283   vidbrain_state *state = screen->machine->driver_data<vidbrain_state>();
284   address_space *program = cputag_get_address_space(screen->machine, F3850_TAG, ADDRESS_SPACE_PROGRAM);
285
286   if (!(state->cmd & COMMAND_ENB))
287   {
288      bitmap_fill(bitmap, cliprect, get_black_pen(screen->machine));
289      return 0;
290   }
291
292   bitmap_fill(bitmap, cliprect, state->bg);
293
294   for (int i = 0; i < 16; i++)
295   {
296      UINT16 rp = ((RAM(RAM_RP_HI) << 8) | RAM(RAM_RP_LO)) & 0x1fff;
297      int color = ((RAM(RAM_DX) >> 2) | (BIT(RAM(RAM_RP_HI), 5) << 2) | (BIT(RAM(RAM_RP_HI), 6) << 1) | (BIT(RAM(RAM_RP_HI), 7))) & 0x1f;
298      int dx = RAM(RAM_DX) & 0x1f;
299      int dy = RAM(RAM_DY);
300      int xcopy = BIT(RAM(RAM_DX), 7);
301      int x = RAM(RAM_X);
302      int xord_a = RAM(RAM_Y_LO_A) & 0x0f;
303      int xord_b = RAM(RAM_Y_LO_B) & 0x0f;
304      int y_a = ((RAM(RAM_XY_HI_A) & 0x80) << 1) | RAM(RAM_Y_LO_A);
305      int y_b = ((RAM(RAM_XY_HI_B) & 0x80) << 1) | RAM(RAM_Y_LO_B);
306      int y = (state->cmd & COMMAND_A_B) ? y_a : y_b;
307      int xord = (state->cmd & COMMAND_A_B) ? xord_a : xord_b;
308
309      if (LOG) logerror("Object %u rp %04x color %u dx %u dy %u xcopy %u x %u y %u xord %u\n", i, rp, color, dx, dy, xcopy, x, y, xord);
310
311      if (rp == 0) continue;
312      if (y > 255) continue;
313
314      for (int sy = 0; sy < dy; sy++)
315      {
316         for (int sx = 0; sx < dx; sx++)
317         {
318            UINT8 data = program->read_byte(rp);
319
320            for (int bit = 0; bit < 8; bit++)
321            {
322               int pixel = ((BIT(data, 7) ? color : state->bg) ^ state->fmod) & 0x1f;
323
324               if (state->cmd & COMMAND_Y_ZM)
325               {
326                  if (state->cmd & COMMAND_X_ZM)
327                  {
328                     *BITMAP_ADDR16(bitmap, y + (sy * 2), x + (sx * 8) + (bit * 2)) = pixel;
329                     *BITMAP_ADDR16(bitmap, y + (sy * 2) + 1, x + (sx * 8) + (bit * 2)) = pixel;
330                     *BITMAP_ADDR16(bitmap, y + (sy * 2), x + (sx * 8) + (bit * 2) + 1) = pixel;
331                     *BITMAP_ADDR16(bitmap, y + (sy * 2) + 1, x + (sx * 8) + (bit * 2) + 1) = pixel;
332                  }
333                  else
334                  {
335                     *BITMAP_ADDR16(bitmap, y + (sy * 2), x + (sx * 8) + bit) = pixel;
336                     *BITMAP_ADDR16(bitmap, y + (sy * 2) + 1, x + (sx * 8) + bit) = pixel;
337                  }
338               }
339               else
340               {
341                  if (state->cmd & COMMAND_X_ZM)
342                  {
343                     *BITMAP_ADDR16(bitmap, y + sy, x + (sx * 8) + (bit * 2)) = pixel;
344                     *BITMAP_ADDR16(bitmap, y + sy, x + (sx * 8) + (bit * 2) + 1) = pixel;
345                  }
346                  else
347                  {
348                     *BITMAP_ADDR16(bitmap, y + sy, x + (sx * 8) + bit) = pixel;
349                  }
350               }
351
352               data <<= 1;
353            }
354
355            if (!xcopy) rp++;
356         }
357
358         if (xcopy) rp++;
359      }
360   }
361
362   return 0;
363}
364
365/*-------------------------------------------------
366    gfx_layout vidbrain_charlayout
367-------------------------------------------------*/
368
369static const gfx_layout vidbrain_charlayout =
370{
371   8, 7,               /* 8 x 7 characters */
372   59,                  /* 59 characters */
373   1,                  /* 1 bits per pixel */
374   { 0 },               /* no bitplanes */
375   /* x offsets */
376   { 0, 1, 2, 3, 4, 5, 6, 7 },
377   /* y offsets */
378   { STEP8(0,8) },
379   8*7               /* every char takes 7 bytes */
380};
381
382/*-------------------------------------------------
383    GFXDECODE( vidbrain )
384-------------------------------------------------*/
385
386static GFXDECODE_START( vidbrain )
387   GFXDECODE_ENTRY( F3850_TAG, 0x2010, vidbrain_charlayout, 0, 1 )
388GFXDECODE_END
389
390/*-------------------------------------------------
391    TIMER_DEVICE_CALLBACK( scanline_tick )
392-------------------------------------------------*/
393
394static TIMER_DEVICE_CALLBACK( y_int_tick )
395{
396   vidbrain_state *state = timer.machine->driver_data<vidbrain_state>();
397
398   if ((state->cmd & COMMAND_INT) && !(state->cmd & COMMAND_FRZ))
399   {
400//      f3853_set_external_interrupt_in_line(state->smi, 1);
401      state->ext_int_latch = 1;
402      vidbrain_interrupt_check(timer.machine);
403   }
404}
405
406/*-------------------------------------------------
407    TIMER_DEVICE_CALLBACK( field_tick )
408-------------------------------------------------*/
409
410static TIMER_DEVICE_CALLBACK( field_tick )
411{
412   vidbrain_state *state = timer.machine->driver_data<vidbrain_state>();
413
414   state->field = !state->field;
415}
416
417/***************************************************************************
418    MACHINE CONFIGURATION
419***************************************************************************/
420
421/*-------------------------------------------------
422    MACHINE_CONFIG_FRAGMENT( vidbrain_video )
423-------------------------------------------------*/
424
425MACHINE_CONFIG_FRAGMENT( vidbrain_video )
426    /* video hardware */
427    MDRV_SCREEN_ADD(SCREEN_TAG, RASTER)
428    MDRV_SCREEN_REFRESH_RATE(30)
429    MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */
430    MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16)
431    MDRV_SCREEN_SIZE(320, 525)
432    MDRV_SCREEN_VISIBLE_AREA(0, 256-1, 0, 262-1)
433   MDRV_GFXDECODE(vidbrain)
434    MDRV_PALETTE_LENGTH(32)
435    MDRV_PALETTE_INIT(vidbrain)
436
437    MDRV_VIDEO_START(vidbrain)
438    MDRV_VIDEO_UPDATE(vidbrain)
439
440   MDRV_TIMER_ADD(TIMER_Y_INT_TAG, y_int_tick)
441   MDRV_TIMER_ADD_PERIODIC(TIMER_FIELD_TAG, field_tick, HZ(60))
442MACHINE_CONFIG_END

Previous 15994 Revisions Next


© 1998-2018 The MESS Team