Previous 15994 Revisions Next

r4352 Thursday 26th February, 2009 at 13:18:56 UTC by Robbbert
[SUPER80] Split video to a separate file.
[src/mess/drivers]super80.c
[src/mess/includes]super80.h*
[src/mess/video]super80.c*

src/mess/video/super80.c
r0r4352
1/* Super80.c written by Robbbert, 2005-2009. See the MESS wiki for documentation. */
2 
3#include "driver.h"
4#include "super80.h"
5 
6 
7static UINT16 vidpg=0xfe00;   /* Home position of video page being displayed */
8 
9static UINT8 current_palette;   /* for super80m and super80v */
10static UINT8 current_charset;   /* for super80m */
11 
12static UINT8 mc6845_cursor[16];            // cursor shape
13static UINT8 mc6845_reg[20];            /* registers */
14static UINT8 mc6845_ind;            /* register index */
15static const UINT8 mc6845_mask[]={0xff,0xff,0xff,0x0f,0x7f,0x1f,0x7f,0x7f,3,0x1f,0x7f,0x1f,0x3f,0xff,0x3f,0xff,0,0};
16 
17/**************************** PALETTES for super80m and super80v ******************************************/
18 
19static const UINT8 super80_rgb_palette[16*3] =
20{
21   0x00, 0x00, 0x00,   /*  0 Black      */
22   0x00, 0x00, 0x00,   /*  1 Black      */
23   0x00, 0x00, 0x7f,   /*  2 Blue      */
24   0x00, 0x00, 0xff,   /*  3 Light Blue   */
25   0x00, 0x7f, 0x00,   /*  4 Green      */
26   0x00, 0xff, 0x00,   /*  5 Bright Green   */
27   0x00, 0x7f, 0x7f,   /*  6 Cyan      */
28   0x00, 0xff, 0xff,   /*  7 Turquoise      */
29   0x7f, 0x00, 0x00,   /*  8 Dark Red      */
30   0xff, 0x00, 0x00,   /*  9 Red      */
31   0x7f, 0x00, 0x7f,   /* 10 Purple      */
32   0xff, 0x00, 0xff,   /* 11 Magenta      */
33   0x7f, 0x7f, 0x00,   /* 12 Lime      */
34   0xff, 0xff, 0x00,   /* 13 Yellow      */
35   0xbf, 0xbf, 0xbf,   /* 14 Off White      */
36   0xff, 0xff, 0xff,   /* 15 White      */
37};
38 
39static const UINT8 super80_comp_palette[16*3] =
40{
41   0x00, 0x00, 0x00,   /*  0 Black      */
42   0x80, 0x80, 0x80,   /*  1 Grey      */
43   0x00, 0x00, 0xff,   /*  2 Blue      */
44   0xff, 0xff, 0x80,   /*  3 Light Yellow   */
45   0x00, 0xff, 0x00,   /*  4 Green      */
46   0xff, 0x80, 0xff,   /*  5 Light Magenta   */
47   0x00, 0xff, 0xff,   /*  6 Cyan      */
48   0xff, 0x40, 0x40,   /*  7 Light Red      */
49   0xff, 0x00, 0x00,   /*  8 Red      */
50   0x00, 0x80, 0x80,   /*  9 Dark Cyan      */
51   0xff, 0x00, 0xff,   /* 10 Magenta      */
52   0x80, 0xff, 0x80,   /* 11 Light Green   */
53   0xff, 0xff, 0x00,   /* 12 Yellow      */
54   0x00, 0x00, 0x80,   /* 13 Dark Blue      */
55   0xff, 0xff, 0xff,   /* 14 White      */
56   0x00, 0x00, 0x00,   /* 15 Black      */
57};
58 
59static void palette_set_colors_rgb(running_machine *machine, const UINT8 *colors)
60{
61   UINT8 r, b, g, color_count = 16;
62 
63   while (color_count--)
64   {
65      r = *colors++; g = *colors++; b = *colors++;
66      colortable_palette_set_color(machine->colortable, 15 - color_count, MAKE_RGB(r, g, b));
67   }
68}
69 
70PALETTE_INIT( super80m )
71{
72   int i;
73   machine->colortable = colortable_alloc(machine, 16);
74   palette_set_colors_rgb(machine, super80_rgb_palette);
75 
76   for( i = 0; i < 256; i++ )
77   {
78      colortable_entry_set_value(machine->colortable, i*2, i>>4);
79      colortable_entry_set_value(machine->colortable, i*2+1, i&15);
80   }
81}
82 
83 
84/**************************** VIDEO *****************************************************************/
85/* the following are for super80v */
86READ8_HANDLER( super80v_low_r )
87{
88   if (!super80v_vid_col)
89      return colorram[offset];
90   else
91      return videoram[offset];
92}
93 
94WRITE8_HANDLER( super80v_low_w )
95{
96   if (!super80v_vid_col)
97      colorram[offset] = data;
98   else
99      videoram[offset] = data;
100}
101 
102READ8_HANDLER( super80v_high_r )
103{
104   if (!super80v_vid_col)
105      return colorram[0x800+offset];
106 
107   if (!super80v_rom_pcg)
108      return pcgram[offset];
109   else
110      return pcgram[0x800+offset];
111}
112 
113WRITE8_HANDLER( super80v_high_w )
114{
115   if (!super80v_vid_col)
116      colorram[offset+0x800] = data;
117   else
118   {
119      videoram[offset+0x800] = data;
120 
121      if (super80v_rom_pcg)
122      {
123         int chr = 0x80 + (offset>>4);
124         pcgram[0x800+offset] = data;
125 
126         /* decode character graphics again */
127         gfx_element_mark_dirty(space->machine->gfx[0], chr);
128      }
129   }
130}
131 
132/* The 6845 can produce a variety of cursor shapes - all are emulated here */
133static void mc6845_cursor_configure(void)
134{
135   UINT8 i,curs_type=0,r9,r10,r11;
136 
137   /* curs_type holds the general cursor shape to be created
138      0 = no cursor
139      1 = partial cursor (only shows on a block of scan lines)
140      2 = full cursor
141      3 = two-part cursor (has a part at the top and bottom with the middle blank) */
142 
143   for ( i = 0; i < ARRAY_LENGTH(mc6845_cursor); i++) mc6845_cursor[i] = 0;      // prepare cursor by erasing old one
144 
145   r9  = mc6845_reg[9];               // number of scan lines - 1
146   r10 = mc6845_reg[10] & 0x1f;            // cursor start line = last 5 bits
147   r11 = mc6845_reg[11]+1;               // cursor end line incremented to suit for-loops below
148 
149   /* decide the curs_type by examining the registers */
150   if (r10 < r11) curs_type=1;            // start less than end, show start to end
151   else
152   if (r10 == r11) curs_type=2;            // if equal, show full cursor
153   else curs_type=3;               // if start greater than end, it's a two-part cursor
154 
155   if ((r11 - 1) > r9) curs_type=2;         // if end greater than scan-lines, show full cursor
156   if (r10 > r9) curs_type=0;            // if start greater than scan-lines, then no cursor
157   if (r11 > 16) r11=16;               // truncate 5-bit register to fit our 4-bit hardware
158 
159   /* create the new cursor */
160   if (curs_type > 1) for (i = 0;i < ARRAY_LENGTH(mc6845_cursor);i++) mc6845_cursor[i]=0xff; // turn on full cursor
161 
162   if (curs_type == 1) for (i = r10;i < r11;i++) mc6845_cursor[i]=0xff; // for each line that should show, turn on that scan line
163 
164   if (curs_type == 3) for (i = r11; i < r10;i++) mc6845_cursor[i]=0; // now take a bite out of the middle
165}
166 
167/* Resize the screen within the limits of the hardware. Expand the image to fill the screen area */
168static void mc6845_screen_configure(running_machine *machine)
169{
170   rectangle visarea;
171 
172   UINT16 width = mc6845_reg[1]*7-1;                     // width in pixels
173   UINT16 height = mc6845_reg[6]*(mc6845_reg[9]+1)-1;               // height in pixels
174   UINT16 bytes = mc6845_reg[1]*mc6845_reg[6]-1;                  // video ram needed -1
175 
176   /* Resize the screen */
177   visarea.min_x = 0;
178   visarea.max_x = width-1;
179   visarea.min_y = 0;
180   visarea.max_y = height-1;
181   if ((width < 610) && (height < 460) && (bytes < 0x1000))   /* bounds checking to prevent an assert or violation */
182      video_screen_set_visarea(machine->primary_screen, 0, width, 0, height);
183}
184 
185VIDEO_EOF( super80m )
186{
187   /* if we chose another palette or colour mode, enable it */
188   UINT8 chosen_palette = (input_port_read(machine, "CONFIG") & 0x60)>>5;            // read colour dipswitches
189 
190   if (chosen_palette != current_palette)                  // any changes?
191   {
192      current_palette = chosen_palette;               // save new palette
193      if (!current_palette)
194         palette_set_colors_rgb(machine, super80_comp_palette);      // composite colour
195      else
196         palette_set_colors_rgb(machine, super80_rgb_palette);      // rgb and b&w
197   }
198}
199 
200VIDEO_UPDATE( super80 )
201{
202   UINT8 x, y, code=32, screen_on=0;
203   UINT8 mask = screen->machine->gfx[0]->total_elements - 1;   /* 0x3F for super80; 0xFF for super80d & super80e */
204 
205   if ((super80_mhz == 1) || (!(input_port_read(screen->machine, "CONFIG") & 4)))   /* bit 2 of port F0 is high, OR user turned on config switch */
206      screen_on++;
207 
208   /* display the picture */
209   for (y=0; y<16; y++)
210   {
211      for (x=0; x<32; x++)
212      {
213         if (screen_on)
214            code = memory_read_byte(cputag_get_address_space(screen->machine,"maincpu",ADDRESS_SPACE_PROGRAM), vidpg | x | (y<<5));
215 
216         drawgfx(bitmap, screen->machine->gfx[0], code & mask, 0, 0, 0, x*8, y*10,
217            cliprect, TRANSPARENCY_NONE, 0);
218      }
219   }
220 
221   return 0;
222}
223 
224VIDEO_UPDATE( super80m )
225{
226   UINT8 x, y, code=32, col=0, screen_on=0, options=input_port_read(screen->machine, "CONFIG");
227 
228   /* get selected character generator */
229   UINT8 cgen = current_charset ^ ((options & 0x10)>>4);   /* bit 0 of port F1 and cgen config switch */
230 
231   if ((super80_mhz == 1) || (!(options & 4)))   /* bit 2 of port F0 is high, OR user turned on config switch */
232      screen_on++;
233 
234   if (screen_on)
235   {
236      if ((options & 0x60) == 0x60)
237         col = 15;      /* b&w */
238      else
239         col = 5;      /* green */
240   }
241 
242   /* display the picture */
243   for (y=0; y<16; y++)
244   {
245      for (x=0; x<32; x++)
246      {
247         if (screen_on)
248         {
249            code = memory_read_byte(cputag_get_address_space(screen->machine,"maincpu",ADDRESS_SPACE_PROGRAM), vidpg | x | (y<<5));      /* get character to display */
250 
251            if (!(options & 0x40)) col = memory_read_byte(cputag_get_address_space(screen->machine,"maincpu",ADDRESS_SPACE_PROGRAM), 0xfe00 | x | (y<<5));   /* byte of colour to display */
252         }
253 
254         drawgfx(bitmap, screen->machine->gfx[cgen], code, col, 0, 0, x*8, y*10,
255            cliprect, TRANSPARENCY_NONE, 0);
256      }
257   }
258 
259   return 0;
260}
261 
262VIDEO_UPDATE( super80v )
263{
264   static UINT8 framecnt=0;
265   UINT16 i, bytes = mc6845_reg[1]*mc6845_reg[6];
266   UINT8 speed = mc6845_reg[10]&0x20, flash = mc6845_reg[10]&0x40;            // cursor modes
267   UINT16 cursor = (mc6845_reg[14]<<8) | mc6845_reg[15];               // get cursor position
268   UINT16 screen_home = (mc6845_reg[12]<<8) | mc6845_reg[13];            // screen home offset (usually zero)
269   UINT8 options=input_port_read(screen->machine, "CONFIG");
270   framecnt++;
271 
272   /* Get the graphics of the character under the cursor, xor with the visible cursor scan lines,
273      and store as character number 256. If inverse mode, drop bit 7 of character before xoring */
274   if (!super80v_rom_pcg)
275      for ( i = 0; i < ARRAY_LENGTH(mc6845_cursor); i++)
276         pcgram[0x1000+i] = pcgram[(videoram[cursor]&0x7f)*16+i] ^ mc6845_cursor[i];
277   else
278      for ( i = 0; i < ARRAY_LENGTH(mc6845_cursor); i++)
279         pcgram[0x1000+i] = pcgram[(videoram[cursor])*16 + i] ^ mc6845_cursor[i];
280 
281   gfx_element_mark_dirty(screen->machine->gfx[0],256);         // and into machine graphics
282 
283   for( i = 0; i < bytes; i++ )
284   {
285      int mem = (i + screen_home) & 0xfff;
286      int sy = (i / mc6845_reg[1]) * (mc6845_reg[9] + 1);
287      int sx = (i % mc6845_reg[1]) * 7;
288      int chr = videoram[mem];
289 
290      /* get colour or b&w */
291      int col = 5;               /* green */
292      if ((options & 0x60) == 0x60) col = 15;      /* b&w */
293      if (!(options & 0x40)) col = colorram[mem];         // read a byte of colour
294 
295      if ((!super80v_rom_pcg) && (chr > 0x7f))         // is it a high chr in inverse mode
296      {
297         col = BITSWAP8(col,3,2,1,0,7,6,5,4);         // swap nibbles
298         chr &= 0x7f;                  // and drop bit 7
299      }
300 
301      /* if cursor is on and we are at cursor position, show it */
302      /* NOTE: flash rates obtained from real hardware */
303 
304      if ((((!flash) && (!speed)) ||               // (5,6)=(0,0) = cursor on always
305         ((flash) && (speed) && (framecnt & 0x10)) ||      // (5,6)=(1,1) = cycle per 32 frames
306         ((flash) && (!speed) && (framecnt & 8))) &&      // (5,6)=(0,1) = cycle per 16 frames
307         (i == cursor))                  // displaying at cursor position?
308            chr = 256;               // 256 = cursor character
309 
310      drawgfx( bitmap, screen->machine->gfx[0],chr,col,0,0,sx,sy,
311         cliprect,TRANSPARENCY_NONE,0);   // put character on the screen
312 
313   }
314 
315   return 0;
316}
317 
318/**************************** I/O PORTS *****************************************************************/
319 
320READ8_HANDLER( super80v_11_r )
321{
322   if ((mc6845_ind > 13) && (mc6845_ind < 18))      /* determine readable registers */
323      return mc6845_reg[mc6845_ind];
324   else
325      return 0;
326}
327 
328WRITE8_HANDLER( super80v_10_w )
329{
330   if (data < 18) mc6845_ind = data; else mc6845_ind = 19;      /* make sure if you try using an invalid register your write will go nowhere */
331}
332 
333WRITE8_HANDLER( super80v_11_w )
334{
335   if (mc6845_ind < 16) mc6845_reg[mc6845_ind] = data & mc6845_mask[mc6845_ind];   /* save data in register */
336   if ((mc6845_ind == 1) || (mc6845_ind == 6) || (mc6845_ind == 9)) mc6845_screen_configure(space->machine); /* adjust screen size */
337   if ((mc6845_ind > 8) && (mc6845_ind < 12)) mc6845_cursor_configure();      /* adjust cursor shape */
338}
339 
340WRITE8_HANDLER( super80_f1_w )
341{
342   vidpg = (data & 0xfe) << 8;
343   current_charset = data & 1;
344}
345 
src/mess/includes/super80.h
r0r4352
1 
2 
3PALETTE_INIT( super80m );
4READ8_HANDLER( super80v_low_r );
5WRITE8_HANDLER( super80v_low_w );
6READ8_HANDLER( super80v_high_r );
7WRITE8_HANDLER( super80v_high_w );
8VIDEO_UPDATE( super80 );
9VIDEO_UPDATE( super80m );
10VIDEO_UPDATE( super80v );
11VIDEO_EOF( super80m );
12READ8_HANDLER( super80v_11_r );
13WRITE8_HANDLER( super80v_10_w );
14WRITE8_HANDLER( super80v_11_w );
15WRITE8_HANDLER( super80_f1_w );
16 
17extern UINT8 *pcgram;
18extern UINT8 super80v_vid_col;
19extern UINT8 super80v_rom_pcg;
20extern UINT8 super80_mhz;
src/mess/drivers/super80.c
r4351r4352
1/* Super80.c written by Robbbert, 2005-2008. See the MESS wiki for documentation. */
1/* Super80.c written by Robbbert, 2005-2009. See the MESS wiki for documentation. */
22
33#include "driver.h"
44#include "cpu/z80/z80.h"
r4351r4352
1111#include "devices/z80bin.h"
1212#include "sound/speaker.h"
1313#include "machine/ctronics.h"
14#include "super80.h"
1415
1516
16static UINT8 super80_mhz=2;   /* state of bit 2 of port F0 */
17static UINT16 vidpg=0xfe00;   /* Home position of video page being displayed */
18static UINT8 int_sw;      /* internal 1 MHz flipflop */
19
20static UINT8 current_palette;   /* for super80m and super80v */
21static UINT8 current_charset;   /* for super80m */
2217static UINT8 irq_counter;
2318
2419static const device_config *super80_z80pio;
r4351r4352
2621static const device_config *super80_cassette;
2722static const device_config *super80_printer;
2823
29/* the rest are for super80v */
30static UINT8 *pcgram;
31static UINT8 framecnt = 0;
32static UINT8 super80v_vid_col=1;         // 0 = color ram ; 1 = video ram
33static UINT8 super80v_rom_pcg=1;         // 0 = prom ; 1 = pcg
34static UINT8 mc6845_cursor[16];            // cursor shape
35static UINT8 mc6845_reg[20];            /* registers */
36static UINT8 mc6845_ind;            /* register index */
37static const UINT8 mc6845_mask[]={0xff,0xff,0xff,0x0f,0x7f,0x1f,0x7f,0x7f,3,0x1f,0x7f,0x1f,0x3f,0xff,0x3f,0xff,0,0};
24UINT8 *pcgram;
25UINT8 super80v_vid_col=1;         // 0 = color ram ; 1 = video ram
26UINT8 super80v_rom_pcg=1;         // 0 = prom ; 1 = pcg
27UINT8 super80_mhz=2;   /* state of bit 2 of port F0 */
3828
3929#define MASTER_CLOCK         (XTAL_12MHz)
4030#define PIXEL_CLOCK         (MASTER_CLOCK/2)
r4351r4352
4838#define SUPER80V_SCREEN_WIDTH      (560)
4939#define SUPER80V_SCREEN_HEIGHT      (300)
5040
51/**************************** PALETTES for super80m and super80v ******************************************/
5241
53static const UINT8 super80_rgb_palette[16*3] =
54{
55   0x00, 0x00, 0x00,   /*  0 Black      */
56   0x00, 0x00, 0x00,   /*  1 Black      */
57   0x00, 0x00, 0x7f,   /*  2 Blue      */
58   0x00, 0x00, 0xff,   /*  3 Light Blue   */
59   0x00, 0x7f, 0x00,   /*  4 Green      */
60   0x00, 0xff, 0x00,   /*  5 Bright Green   */
61   0x00, 0x7f, 0x7f,   /*  6 Cyan      */
62   0x00, 0xff, 0xff,   /*  7 Turquoise      */
63   0x7f, 0x00, 0x00,   /*  8 Dark Red      */
64   0xff, 0x00, 0x00,   /*  9 Red      */
65   0x7f, 0x00, 0x7f,   /* 10 Purple      */
66   0xff, 0x00, 0xff,   /* 11 Magenta      */
67   0x7f, 0x7f, 0x00,   /* 12 Lime      */
68   0xff, 0xff, 0x00,   /* 13 Yellow      */
69   0xbf, 0xbf, 0xbf,   /* 14 Off White      */
70   0xff, 0xff, 0xff,   /* 15 White      */
71};
72
73static const UINT8 super80_comp_palette[16*3] =
74{
75   0x00, 0x00, 0x00,   /*  0 Black      */
76   0x80, 0x80, 0x80,   /*  1 Grey      */
77   0x00, 0x00, 0xff,   /*  2 Blue      */
78   0xff, 0xff, 0x80,   /*  3 Light Yellow   */
79   0x00, 0xff, 0x00,   /*  4 Green      */
80   0xff, 0x80, 0xff,   /*  5 Light Magenta   */
81   0x00, 0xff, 0xff,   /*  6 Cyan      */
82   0xff, 0x40, 0x40,   /*  7 Light Red      */
83   0xff, 0x00, 0x00,   /*  8 Red      */
84   0x00, 0x80, 0x80,   /*  9 Dark Cyan      */
85   0xff, 0x00, 0xff,   /* 10 Magenta      */
86   0x80, 0xff, 0x80,   /* 11 Light Green   */
87   0xff, 0xff, 0x00,   /* 12 Yellow      */
88   0x00, 0x00, 0x80,   /* 13 Dark Blue      */
89   0xff, 0xff, 0xff,   /* 14 White      */
90   0x00, 0x00, 0x00,   /* 15 Black      */
91};
92
93static void palette_set_colors_rgb(running_machine *machine, const UINT8 *colors)
94{
95   UINT8 r, b, g, color_count = 16;
96
97   while (color_count--)
98   {
99      r = *colors++; g = *colors++; b = *colors++;
100      colortable_palette_set_color(machine->colortable, 15 - color_count, MAKE_RGB(r, g, b));
101   }
102}
103
104static PALETTE_INIT( super80m )
105{
106   int i;
107   machine->colortable = colortable_alloc(machine, 16);
108   palette_set_colors_rgb(machine, super80_rgb_palette);
109
110   for( i = 0; i < 256; i++ )
111   {
112      colortable_entry_set_value(machine->colortable, i*2, i>>4);
113      colortable_entry_set_value(machine->colortable, i*2+1, i&15);
114   }
115}
116
117
118/**************************** VIDEO *****************************************************************/
119/* the following are for super80v */
120static READ8_HANDLER( super80v_low_r )
121{
122   if (!super80v_vid_col)
123      return colorram[offset];
124   else
125      return videoram[offset];
126}
127
128static WRITE8_HANDLER( super80v_low_w )
129{
130   if (!super80v_vid_col)
131      colorram[offset] = data;
132   else
133      videoram[offset] = data;
134}
135
136static READ8_HANDLER( super80v_high_r )
137{
138   if (!super80v_vid_col)
139      return colorram[0x800+offset];
140
141   if (!super80v_rom_pcg)
142      return pcgram[offset];
143   else
144      return pcgram[0x800+offset];
145}
146
147static WRITE8_HANDLER( super80v_high_w )
148{
149   if (!super80v_vid_col)
150      colorram[offset+0x800] = data;
151   else
152   {
153      videoram[offset+0x800] = data;
154
155      if (super80v_rom_pcg)
156      {
157         int chr = 0x80 + (offset>>4);
158         pcgram[0x800+offset] = data;
159
160         /* decode character graphics again */
161         gfx_element_mark_dirty(space->machine->gfx[0], chr);
162      }
163   }
164}
165
166/* The 6845 can produce a variety of cursor shapes - all are emulated here */
167static void mc6845_cursor_configure(void)
168{
169   UINT8 i,curs_type=0,r9,r10,r11;
170
171   /* curs_type holds the general cursor shape to be created
172      0 = no cursor
173      1 = partial cursor (only shows on a block of scan lines)
174      2 = full cursor
175      3 = two-part cursor (has a part at the top and bottom with the middle blank) */
176
177   for ( i = 0; i < ARRAY_LENGTH(mc6845_cursor); i++) mc6845_cursor[i] = 0;      // prepare cursor by erasing old one
178
179   r9  = mc6845_reg[9];               // number of scan lines - 1
180   r10 = mc6845_reg[10] & 0x1f;            // cursor start line = last 5 bits
181   r11 = mc6845_reg[11]+1;               // cursor end line incremented to suit for-loops below
182
183   /* decide the curs_type by examining the registers */
184   if (r10 < r11) curs_type=1;            // start less than end, show start to end
185   else
186   if (r10 == r11) curs_type=2;            // if equal, show full cursor
187   else curs_type=3;               // if start greater than end, it's a two-part cursor
188
189   if ((r11 - 1) > r9) curs_type=2;         // if end greater than scan-lines, show full cursor
190   if (r10 > r9) curs_type=0;            // if start greater than scan-lines, then no cursor
191   if (r11 > 16) r11=16;               // truncate 5-bit register to fit our 4-bit hardware
192
193   /* create the new cursor */
194   if (curs_type > 1) for (i = 0;i < ARRAY_LENGTH(mc6845_cursor);i++) mc6845_cursor[i]=0xff; // turn on full cursor
195
196   if (curs_type == 1) for (i = r10;i < r11;i++) mc6845_cursor[i]=0xff; // for each line that should show, turn on that scan line
197
198   if (curs_type == 3) for (i = r11; i < r10;i++) mc6845_cursor[i]=0; // now take a bite out of the middle
199}
200
201/* Resize the screen within the limits of the hardware. Expand the image to fill the screen area */
202static void mc6845_screen_configure(running_machine *machine)
203{
204   rectangle visarea;
205
206   UINT16 width = mc6845_reg[1]*7-1;                     // width in pixels
207   UINT16 height = mc6845_reg[6]*(mc6845_reg[9]+1)-1;               // height in pixels
208   UINT16 bytes = mc6845_reg[1]*mc6845_reg[6]-1;                  // video ram needed -1
209
210   /* Resize the screen */
211   visarea.min_x = 0;
212   visarea.max_x = width-1;
213   visarea.min_y = 0;
214   visarea.max_y = height-1;
215   if ((width < 610) && (height < 460) && (bytes < 0x1000))   /* bounds checking to prevent an assert or violation */
216      video_screen_set_visarea(machine->primary_screen, 0, width, 0, height);
217}
218
219static VIDEO_EOF( super80m )
220{
221   /* if we chose another palette or colour mode, enable it */
222   UINT8 chosen_palette = (input_port_read(machine, "CONFIG") & 0x60)>>5;            // read colour dipswitches
223
224   if (chosen_palette != current_palette)                  // any changes?
225   {
226      current_palette = chosen_palette;               // save new palette
227      if (!current_palette)
228         palette_set_colors_rgb(machine, super80_comp_palette);      // composite colour
229      else
230         palette_set_colors_rgb(machine, super80_rgb_palette);      // rgb and b&w
231   }
232}
233
234static VIDEO_UPDATE( super80 )
235{
236   UINT8 x, y, code=32, screen_on=0;
237   UINT8 mask = screen->machine->gfx[0]->total_elements - 1;   /* 0x3F for super80; 0xFF for super80d & super80e */
238
239   if ((super80_mhz == 1) || (!(input_port_read(screen->machine, "CONFIG") & 4)))   /* bit 2 of port F0 is high, OR user turned on config switch */
240      screen_on++;
241
242   /* display the picture */
243   for (y=0; y<16; y++)
244   {
245      for (x=0; x<32; x++)
246      {
247         if (screen_on)
248            code = memory_read_byte(cputag_get_address_space(screen->machine,"maincpu",ADDRESS_SPACE_PROGRAM), vidpg + x + (y<<5));
249
250         drawgfx(bitmap, screen->machine->gfx[0], code & mask, 0, 0, 0, x*8, y*10,
251            cliprect, TRANSPARENCY_NONE, 0);
252      }
253   }
254
255   return 0;
256}
257
258static VIDEO_UPDATE( super80m )
259{
260   UINT8 x, y, code=32, col=0, screen_on=0, options=input_port_read(screen->machine, "CONFIG");
261
262   /* get selected character generator */
263   UINT8 cgen = current_charset ^ ((options & 0x10)>>4);   /* bit 0 of port F1 and cgen config switch */
264
265   if ((super80_mhz == 1) || (!(options & 4)))   /* bit 2 of port F0 is high, OR user turned on config switch */
266      screen_on++;
267
268   if (screen_on)
269   {
270      if ((options & 0x60) == 0x60)
271         col = 15;      /* b&w */
272      else
273         col = 5;      /* green */
274   }
275
276   /* display the picture */
277   for (y=0; y<16; y++)
278   {
279      for (x=0; x<32; x++)
280      {
281         if (screen_on)
282         {
283            code = memory_read_byte(cputag_get_address_space(screen->machine,"maincpu",ADDRESS_SPACE_PROGRAM), vidpg + x + (y<<5));      /* get character to display */
284
285            if (!(options & 0x40)) col = memory_read_byte(cputag_get_address_space(screen->machine,"maincpu",ADDRESS_SPACE_PROGRAM), 0xfe00 + x + (y<<5));   /* byte of colour to display */
286         }
287
288         drawgfx(bitmap, screen->machine->gfx[cgen], code, col, 0, 0, x*8, y*10,
289            cliprect, TRANSPARENCY_NONE, 0);
290      }
291   }
292
293   return 0;
294}
295
296static VIDEO_UPDATE( super80v )
297{
298   UINT16 i, bytes = mc6845_reg[1]*mc6845_reg[6];
299   UINT8 speed = mc6845_reg[10]&0x20, flash = mc6845_reg[10]&0x40;            // cursor modes
300   UINT16 cursor = (mc6845_reg[14]<<8) | mc6845_reg[15];               // get cursor position
301   UINT16 screen_home = (mc6845_reg[12]<<8) | mc6845_reg[13];            // screen home offset (usually zero)
302   UINT8 options=input_port_read(screen->machine, "CONFIG");
303   framecnt++;
304
305   /* Get the graphics of the character under the cursor, xor with the visible cursor scan lines,
306      and store as character number 256. If inverse mode, drop bit 7 of character before xoring */
307   if (!super80v_rom_pcg)
308      for ( i = 0; i < ARRAY_LENGTH(mc6845_cursor); i++)
309         pcgram[0x1000+i] = pcgram[(videoram[cursor]&0x7f)*16+i] ^ mc6845_cursor[i];
310   else
311      for ( i = 0; i < ARRAY_LENGTH(mc6845_cursor); i++)
312         pcgram[0x1000+i] = pcgram[(videoram[cursor])*16 + i] ^ mc6845_cursor[i];
313
314   gfx_element_mark_dirty(screen->machine->gfx[0],256);         // and into machine graphics
315
316   for( i = 0; i < bytes; i++ )
317   {
318      int mem = (i + screen_home) & 0xfff;
319      int sy = (i / mc6845_reg[1]) * (mc6845_reg[9] + 1);
320      int sx = (i % mc6845_reg[1]) * 7;
321      int chr = videoram[mem];
322
323      /* get colour or b&w */
324      int col = 5;               /* green */
325      if ((options & 0x60) == 0x60) col = 15;      /* b&w */
326      if (!(options & 0x40)) col = colorram[mem];         // read a byte of colour
327
328      if ((!super80v_rom_pcg) && (chr > 0x7f))         // is it a high chr in inverse mode
329      {
330         col = BITSWAP8(col,3,2,1,0,7,6,5,4);         // swap nibbles
331         chr &= 0x7f;                  // and drop bit 7
332      }
333
334      /* if cursor is on and we are at cursor position, show it */
335      /* NOTE: flash rates obtained from real hardware */
336
337      if ((((!flash) && (!speed)) ||               // (5,6)=(0,0) = cursor on always
338         ((flash) && (speed) && (framecnt & 0x10)) ||      // (5,6)=(1,1) = cycle per 32 frames
339         ((flash) && (!speed) && (framecnt & 8))) &&      // (5,6)=(0,1) = cycle per 16 frames
340         (i == cursor))                  // displaying at cursor position?
341            chr = 256;               // 256 = cursor character
342
343      drawgfx( bitmap, screen->machine->gfx[0],chr,col,0,0,sx,sy,
344         cliprect,TRANSPARENCY_NONE,0);   // put character on the screen
345
346   }
347
348   return 0;
349}
350
35142/**************************** PIO ******************************************************************************/
35243
35344static UINT8 keylatch;
r4351r4352
463154
464155/**************************** I/O PORTS *****************************************************************/
465156
466static READ8_HANDLER( super80v_11_r )
467{
468   if ((mc6845_ind > 13) && (mc6845_ind < 18))      /* determine readable registers */
469      return mc6845_reg[mc6845_ind];
470   else
471      return 0;
472}
473
474157static READ8_HANDLER( super80_dc_r )
475158{
476159   UINT8 data=0x7f;
r4351r4352
491174   return data;
492175}
493176
494static WRITE8_HANDLER( super80v_10_w )
495{
496   if (data < 18) mc6845_ind = data; else mc6845_ind = 19;      /* make sure if you try using an invalid register your write will go nowhere */
497}
498
499static WRITE8_HANDLER( super80v_11_w )
500{
501   if (mc6845_ind < 16) mc6845_reg[mc6845_ind] = data & mc6845_mask[mc6845_ind];   /* save data in register */
502   if ((mc6845_ind == 1) || (mc6845_ind == 6) || (mc6845_ind == 9)) mc6845_screen_configure(space->machine); /* adjust screen size */
503   if ((mc6845_ind > 8) && (mc6845_ind < 12)) mc6845_cursor_configure();      /* adjust cursor shape */
504}
505
506177static WRITE8_HANDLER( super80_dc_w )
507178{
508179   /* hardware strobe driven from port select, bit 7..0 = data */
r4351r4352
552223   last_data = data;
553224}
554225
555static WRITE8_HANDLER( super80_f1_w )
556{
557   vidpg = (data & 0xfe) << 8;
558   current_charset = data & 1;
559}
560
561226static READ8_HANDLER( super80_f8_r ) { return z80pio_d_r (super80_z80pio,0); }
562227static READ8_HANDLER( super80_f9_r ) { return z80pio_c_r (super80_z80pio,0); }
563228static READ8_HANDLER( super80_fa_r ) { return z80pio_d_r (super80_z80pio,1); }
r4351r4352
945610
946611static TIMER_CALLBACK( super80_halfspeed )
947612{
613   static UINT8 int_sw=0;
948614   UINT8 go_fast = 0;
949615   if ((super80_mhz == 2) || (!(input_port_read(machine, "CONFIG") & 2)))   /* bit 2 of port F0 is low, OR user turned on config switch */
950616      go_fast++;

Previous 15994 Revisions Next


© 1998-2018 The MESS Team