diff options
Diffstat (limited to 'src/mame/video/arcadia.c')
-rw-r--r-- | src/mame/video/arcadia.c | 676 |
1 files changed, 676 insertions, 0 deletions
diff --git a/src/mame/video/arcadia.c b/src/mame/video/arcadia.c new file mode 100644 index 00000000000..869439aef10 --- /dev/null +++ b/src/mame/video/arcadia.c @@ -0,0 +1,676 @@ +// license:GPL-2.0+ +// copyright-holders:Peter Trauner +/****************************************************************************** +Consolidation and enhancment of documentation by Manfred Schneider based on previous work from + PeT mess@utanet.at and Paul Robson (autismuk@aol.com) + + Schematics, manuals and anything you can desire for at http://amigan.1emu.net/ + + TODO: find a dump of the charactyer ROM + convert the drawing code to tilemap + + emulation of signetics 2637 video/audio device + +General +The UVI is capable of controlling 512 Bytes of RAM. It also generates a select signal +for a 128 byte wide area. +This whole addres space maps in the arcadia and compatible machines from $1800 - $1AFF. + +1. Video Memory + +The screen table is at 1800-CF and 1A00-CF. Each page has 13 lines of the +screen (16 bytes per line,26 lines in total, 208 scan lines). The 2 most +significant bits of each byte are colour data, the 6 least significant +are character data. The resolution of the Arcadia is 128 x 208 pixels. + +It is possible to halve the screen resolution so 1A00..1ACF can +be used for code. This is controlled by bit 6 of $19F8. + +The byte at location $18FF is the current Character Line address, lower +4 bits only. The start line goes from 1800 to 18C0 then from 1900 to 19C0. +The 4 least significant bits of this count 0123456789ABC0123456789ABC, +going to D when in vertical blank. The 4 most significant bits are always +'1'. Some games do use this for scrolling effects - a good example of this +is the routine at $010F in Alien Invaders which scrolls the various bits of +the screen about using the memory locations $18FF and $18FE. + +The screen can be scrolled upto 7 pixels to the left using the high 3 bits +of $18FE. This is used in Alien Invaders. + +A line beginning with $C0 contains block graphics. Each square contains +3 wide x 2 high pixels, coloured as normal. The 3 least significant bits +are the top, the next 3 bits are the bottom. Alien Invaders uses this for +shields. The graphics are returned to normal for the next line. + +The VBlank signal (maybe VSYNC) is connected to the SENSE input. This is +logic '1' when the system is in VBLANK. + +The Flag line does.... something graphical - it might make the sprites +half width/double height perhaps. Breakaway sets this when the bats are +double size in vertical mode. + + +2. Character codes + +Character codes 00..37 to be in a ROM somewhere in the Emerson. These +are known, others may be discovered by comparing the screen snapshots +against the character tables. If the emulator displays an exclamation +mark you've found one. Get a snapshot to see what it looks like +normally and let me know. Codes 38..3F are taken from RAM. + +00 (space) +01..0F Graphic Characters +10..19 0..9 +1A..33 A..Z +34 Decimal Point +35 comma +36 + +37 $ +38..3F User Defined Characters (8 off, from 1980..19FF) + +Character data is stored 8 bits per character , as a single plane graphic +The 2nd and 3rd bits of palette data come from the screen tables, so there +are two colours per character and 4 possible palette selections for the +background. + + +3. Sound + +fixed frequency sound and random Noise generator. +18FD pitch (lower 7 bits) +18FE volume ( bits 0 - 2) +18fe bit 3 set means sound on +18fe bit 4 set means random noise on + +Calculation of sound frequency is done as follows + 1/Freq = 2 (pitch +1) * (horizontal line period) + + +4. Sprites + +Sprite pointers are at 18F0..18F7 (there are four of them). The graphics +used are the ones in the 1980..19BF UDG table (the first four). + +Sprite addresses (x,y) are converted to offsets in the 128 x 208 as follows: + +1) 1's complement the y coordinate +2) subtract 16 from the y coordinate +3) subtract 43 from the x coordinate + +5. Palette + +The Palette is encoded between 19F8-19FB. This section describes the method +by which colours are allocated. There are 8 colours, information is coded +3 bits per colour (usually 2 colours per byte) + + Colour Code Name + ------ ----- ------- + 7 111 Black + 6 110 Blue + 5 101 Red + 4 100 Magenta + 3 011 Green + 2 010 Cyan + 1 001 Yellow + 0 000 White + +Bits 0..2 of $19F9 are the screen colour +Bits 3..5 of $19F9 are the colours of characters +Bit 6 of $19f9 is for poti axis +Bit 7 of $19f9 is for character size (1 = 8x8; 0 = 8x16) +Bits 0..5 of $19FA are the colours of Sprites 2 & 3 (sprite 3 is low bits) +Bit 6 of $19FA is for size of sprite 3 (0 = 8x16; 1 = 8x8) +Bit 7 of $19FA is for size of sprite 2 (0 = 8x16; 1 = 8x8) +Bits 0..5 of $19FB are the colours of Sprites 0 & 1 (sprite 1 is low bits) +Bit 6 of $19FB is for size of sprite 1 (0 = 8x16; 1 = 8x8) +Bit 7 of $19FB is for size of sprite 0 (0 = 8x16; 1 = 8x8) + + +6. Collision Detection + +Bits are set to zero on a collision - I think they are reset at the +frame start. There are two locations : one is for sprite/background +collisions, one is for sprite/sprite collisions. + +19FC bits 0..3 are collision between sprites 0..3 and the background. + +19FD bit 0 is sprite 0 / 1 collision + bit 1 is sprite 0 / 2 collision + bit 2 is sprite 0 / 3 collision + bit 3 is sprite 1 / 2 collision + bit 4 is sprite 1 / 3 collision (guess) + bit 5 is sprite 2 / 3 collision (guess) + + +7. Graphic Mode +19f8 bit 7 graphics mode on (lower 6 bits descripe rectangles) +0xc0 in line switches to graphics mode in this line +0x40 in line switches to char mode in this line + 22211100 + 22211100 + 22211100 + 22211100 + 55544433 + 55544433 + 55544433 + 55544433 + + 8. Memory Map + The offsets in the following memory Map are from the view of the UVI. + In the arcadia and compatibles the base offset is $1800 thats how the CPU sees the UVI + + 0000 - 00FF external RAM + 0000 - 00CF upper screen character/graphics codes organised as 16 char x 13 rows + 00D0 - 00EF RAM (not used by UVI, can be used by CPU) + 00F0 vertical offset object 0 + 00F1 horizontal offset object 0 + 00F2 vertical offset object 1 + 00F3 horizontal offset object 1 + 00F4 vertical offset object 2 + 00F5 horizontal offset object 2 + 00F6 vertical offset object 3 + 00F7 horizontal offset object 3 + 00F8 - 00FB RAM (not used by UVI, can be used by CPU) + 00FC complement number of rows from the trailing edge of VRST + to the start of character display + 00FD bit0 - 6 sound frequeny, bit 7 color mode + 00FE bit0 - 2 loudness, bit 3 sound enable when set, bit 4 random noise enable when set + bit 5 - 7 delay for row of characters + 00FF bit 0 - 3 DMA number, bit 4 - 7 unused +0100 - 017F CE area. In arcadia used for keypad. +0180 - 01FF internal UVI registers + 0180 - 0187 image of object 0 or UDC-code $38 + 0188 - 018F image of object 1 or UDC-code $39 + 0190 - 0197 image of object 2 or UDC-code $3A + 0198 - 019F image of object 3 or UDC-code $3B + 01A0 - 01A7 image of UDC-code $3C + 01A8 - 01AF image of UDC-code $3D + 01B0 - 01B7 image of UDC-code $3E + 01B8 - 01BF image of UDC-code $3F + 01C0 - 01F7 unused + 01F8 bit 0 - 2 alternate screen color, bit 3 - 5 alternate character color + bit 6 Refresh mode when set entire character field will be display twice + bit 7 Grahics mode + 01F9 bit 0 - 2 screen color, bit 3 - 5 character color + bit 6 poti mux control + bit 7 character size when set size=8x8 else size=8x16 + 01FA bit 0 - 2 color of object 3, bit 3 - 5 color of object 2 + bit 6 size of object 3 when set size=8x8 else size=8x16 + bit 7 size of object 2 when set size=8x8 else size=8x16 + 01FB bit 0 - 2 color of object 1, bit 3 - 5 color of object 0 + bit 6 size of object 1 when set size=8x8 else size=8x16 + bit 7 size of object 0 when set size=8x8 else size=8x16 + 01FC object - character collision bits + bit 0 when low object 0 collided with character + bit 1 when low object 1 collided with character + bit 2 when low object 2 collided with character + bit 3 when low object 3 collided with character + bit 4 - 7 unused set to high + 01FD inter object collision + bit 0 - when low object 1 and 2 collide + bit 1 - when low object 1 and 3 collide + bit 2 - when low object 1 and 4 collide + bit 3 - when low object 2 and 3 collide + bit 4 - when low object 2 and 4 collide + bit 5 - when low object 3 and 4 collide + bit 6 - 7 unused set to high + 01FE digital value of POT1 or POT3 input. Valid only during VRST + 01FF digital value of POT2 or POT4 input. Valid only furing VRST +0200 - 02FF 2nd external RAM + 0200 - 02CF lower screen character/graphics codes organised as 16 char x 13 rows + 02D0 - 02FF RAM (not used by UVI, can be used by CPU) +*/ + + +#include "includes/arcadia.h" + +static const UINT8 chars[0x40][8]={ + // read from the screen generated from a palladium + { 0,0,0,0,0,0,0,0 }, // 00 (space) + { 1,2,4,8,16,32,64,128 }, // 01 (\) + { 128,64,32,16,8,4,2,1 }, // 02 (/) + { 255,255,255,255,255,255,255,255 }, // 03 (solid block) + { 0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00 },// 04 (?) + { 3,3,3,3,3,3,3,3 }, // 05 (half square right on) + { 0,0,0,0,0,0,255,255 }, // 06 (horz lower line) + { 0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0 },// 07 (half square left on) + { 0xff,0xff,3,3,3,3,3,3 }, // 08 (?) + { 0xff,0xff,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0 },// 09 (?) + { 192,192,192,192,192,192,255,255 }, // 0A (!_) + { 3,3,3,3,3,3,255,255 }, // 0B (_!) + { 1,3,7,15,31,63,127,255 }, // 0C (diagonal block) + { 128,192,224,240,248,252,254,255 }, // 0D (diagonal block) + { 255,254,252,248,240,224,192,128 }, // 0E (diagonal block) + { 255,127,63,31,15,7,3,1 }, // 0F (diagonal block) + { 0x00,0x1c,0x22,0x26,0x2a,0x32,0x22,0x1c },// 10 0 + { 0x00,0x08,0x18,0x08,0x08,0x08,0x08,0x1c },// 11 1 + { 0x00,0x1c,0x22,0x02,0x0c,0x10,0x20,0x3e },// 12 2 + { 0x00,0x3e,0x02,0x04,0x0c,0x02,0x22,0x1c },// 13 3 + { 0x00,0x04,0x0c,0x14,0x24,0x3e,0x04,0x04 },// 14 4 + { 0x00,0x3e,0x20,0x3c,0x02,0x02,0x22,0x1c },// 15 5 + { 0x00,0x0c,0x10,0x20,0x3c,0x22,0x22,0x1c },// 16 6 + { 0x00,0x7c,0x02,0x04,0x08,0x10,0x10,0x10 },// 17 7 + { 0x00,0x1c,0x22,0x22,0x1c,0x22,0x22,0x1c },// 18 8 + { 0x00,0x1c,0x22,0x22,0x3e,0x02,0x04,0x18 },// 19 9 + { 0x00,0x08,0x14,0x22,0x22,0x3e,0x22,0x22 },// 1A A + { 0x00,0x3c,0x22,0x22,0x3c,0x22,0x22,0x3c },// 1B B + { 0x00,0x1c,0x22,0x20,0x20,0x20,0x22,0x1c },// 1C C + { 0x00,0x3c,0x22,0x22,0x22,0x22,0x22,0x3c },// 1D D + { 0x00,0x3e,0x20,0x20,0x3c,0x20,0x20,0x3e },// 1E E + { 0x00,0x3e,0x20,0x20,0x3c,0x20,0x20,0x20 },// 1F F + { 0x00,0x1e,0x20,0x20,0x20,0x26,0x22,0x1e },// 20 G + { 0x00,0x22,0x22,0x22,0x3e,0x22,0x22,0x22 },// 21 H + { 0x00,0x1c,0x08,0x08,0x08,0x08,0x08,0x1c },// 22 I + { 0x00,0x02,0x02,0x02,0x02,0x02,0x22,0x1c },// 23 J + { 0x00,0x22,0x24,0x28,0x30,0x28,0x24,0x22 },// 24 K + { 0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x3e },// 25 L + { 0x00,0x22,0x36,0x2a,0x2a,0x22,0x22,0x22 },// 26 M + { 0x00,0x22,0x22,0x32,0x2a,0x26,0x22,0x22 },// 27 N + { 0x00,0x1c,0x22,0x22,0x22,0x22,0x22,0x1c },// 28 O + { 0x00,0x3c,0x22,0x22,0x3c,0x20,0x20,0x20 },// 29 P + { 0x00,0x1c,0x22,0x22,0x22,0x2a,0x24,0x1a },// 2A Q + { 0x00,0x3c,0x22,0x22,0x3c,0x28,0x24,0x22 },// 2B R + { 0x00,0x1c,0x22,0x20,0x1c,0x02,0x22,0x1c },// 2C S + { 0x00,0x3e,0x08,0x08,0x08,0x08,0x08,0x08 },// 2D T + { 0x00,0x22,0x22,0x22,0x22,0x22,0x22,0x1c },// 2E U + { 0x00,0x22,0x22,0x22,0x22,0x22,0x14,0x08 },// 2F V + { 0x00,0x22,0x22,0x22,0x2a,0x2a,0x36,0x22 },// 30 W + { 0x00,0x22,0x22,0x14,0x08,0x14,0x22,0x22 },// 31 X + { 0x00,0x22,0x22,0x14,0x08,0x08,0x08,0x08 },// 32 Y + { 0x00,0x3e,0x02,0x04,0x08,0x10,0x20,0x3e },// 33 Z + { 0,0,0,0,0,0,0,8 }, // 34 . + { 0,0,0,0,0,8,8,0x10 }, // 35 , + { 0,0,8,8,0x3e,8,8,0 }, // 36 + + { 0,8,0x1e,0x28,0x1c,0xa,0x3c,8 }, // 37 $ + // 8x user defined +}; + +void arcadia_state::video_start() +{ + int i; + memcpy(&m_chars, chars, sizeof(chars)); + for (i=0; i<0x40; i++) + { + m_rectangle[i][0]=0; + m_rectangle[i][4]=0; + if (i&1) m_rectangle[i][0]|=3; + if (i&2) m_rectangle[i][0]|=0x1c; + if (i&4) m_rectangle[i][0]|=0xe0; + if (i&8) m_rectangle[i][4]|=3; + if (i&0x10) m_rectangle[i][4]|=0x1c; + if (i&0x20) m_rectangle[i][4]|=0xe0; + m_rectangle[i][1]=m_rectangle[i][2]=m_rectangle[i][3]=m_rectangle[i][0]; + m_rectangle[i][5]=m_rectangle[i][6]=m_rectangle[i][7]=m_rectangle[i][4]; + } + + { + int width = m_screen->width(); + int height = m_screen->height(); + m_bitmap = auto_bitmap_ind16_alloc(machine(), width, height); + } +} + +READ8_MEMBER( arcadia_state::video_r ) +{ + UINT8 data=0; + switch (offset) + { + case 0xff: data = m_charline|0xf0;break; + case 0x100: data = m_controller1_col1->read();break; + case 0x101: data = m_controller1_col2->read();break; + case 0x102: data = m_controller1_col3->read();break; + case 0x103: data = m_controller1_extra->read();break; + case 0x104: data = m_controller2_col1->read();break; + case 0x105: data = m_controller2_col2->read();break; + case 0x106: data = m_controller2_col3->read();break; + case 0x107: data = m_controller2_extra->read();break; + case 0x108: data = m_panel->read();break; +#if 0 + case 0x1fe: + if (m_ad_select) + data=ioport("controller1_joy_y")->read()<<3; + else + data=ioport("controller1_joy_x")->read()<<3; + break; + case 0x1ff: + if (m_ad_select) + data=ioport("controller2_joy_y")->read()<<3; + else + data=ioport("controller2_joy_x")->read()<<3; + break; +#else + case 0x1fe: + data = 0x80; + if (m_ad_select) + { + if (m_joysticks->read()&0x10) data=0; + if (m_joysticks->read()&0x20) data=0xff; + } + else + { + if (m_joysticks->read()&0x40) data=0xff; + if (m_joysticks->read()&0x80) data=0; + } + break; + case 0x1ff: + data = 0x6f; // 0x7f too big for alien invaders (move right) + if (m_ad_select) + { + if (m_joysticks->read()&0x1) data=0; + if (m_joysticks->read()&0x2) data=0xff; + } + else + { + if (m_joysticks->read()&0x4) data=0xff; + if (m_joysticks->read()&0x8) data=0; + } + break; +#endif + default: + data = m_reg.data[offset]; + } + return data; +} + +WRITE8_MEMBER( arcadia_state::video_w ) +{ + m_reg.data[offset]=data; + switch (offset) + { + case 0xfc: + m_ypos=255-data+YPOS; + break; + case 0xfd: + m_custom->write(space, offset&3, data); + m_multicolor = data & 0x80; + break; + case 0xfe: + m_custom->write(space, offset&3, data); + m_shift = (data>>5); + break; + case 0xf0: + case 0xf2: + case 0xf4: + case 0xf6: + m_pos[(offset>>1)&3].y = (data^0xff)+1; + break; + case 0xf1: + case 0xf3: + case 0xf5: + case 0xf7: + m_pos[(offset>>1)&3].x = data-43; + break; + case 0x180: case 0x181: case 0x182: case 0x183: case 0x184: case 0x185: case 0x186: case 0x187: + case 0x188: case 0x189: case 0x18a: case 0x18b: case 0x18c: case 0x18d: case 0x18e: case 0x18f: + case 0x190: case 0x191: case 0x192: case 0x193: case 0x194: case 0x195: case 0x196: case 0x197: + case 0x198: case 0x199: case 0x19a: case 0x19b: case 0x19c: case 0x19d: case 0x19e: case 0x19f: + case 0x1a0: case 0x1a1: case 0x1a2: case 0x1a3: case 0x1a4: case 0x1a5: case 0x1a6: case 0x1a7: + case 0x1a8: case 0x1a9: case 0x1aa: case 0x1ab: case 0x1ac: case 0x1ad: case 0x1ae: case 0x1af: + case 0x1b0: case 0x1b1: case 0x1b2: case 0x1b3: case 0x1b4: case 0x1b5: case 0x1b6: case 0x1b7: + case 0x1b8: case 0x1b9: case 0x1ba: case 0x1bb: case 0x1bc: case 0x1bd: case 0x1be: case 0x1bf: + m_chars[0x38|((offset>>3)&7)][offset&7] = data; + break; + case 0x1f8: + m_lines26 = data & 0x40; + m_graphics = data & 0x80; + break; + case 0x1f9: + m_doublescan =! (data&0x80); + m_ad_delay = 10; + break; + } +} + +void arcadia_state::draw_char(UINT8 *ch, int charcode, int y, int x) +{ + int k,b,cc,sc, colour; + if (m_multicolor) + { + if (charcode&0x40) + cc=((m_reg.d.pal[1]>>3)&7); + else + cc=((m_reg.d.pal[0]>>3)&7); + + if (charcode&0x80) + sc=(m_reg.d.pal[1]&7); + else + sc=(m_reg.d.pal[0]&7); + } + else + { + cc=((m_reg.d.pal[1]>>3)&1)|((charcode>>5)&6); + sc=(m_reg.d.pal[1]&7); + } + colour = (((sc << 3) | cc) + 4); + + if (m_doublescan) + { + for (k=0; (k<8)&&(y<m_bitmap->height()); k++, y+=2) + { + b=ch[k]; + m_bg[y][x>>3]|=b>>(x&7); + m_bg[y][(x>>3)+1]|=b<<(8-(x&7)); + + if (y+1<m_bitmap->height()) + { + m_bg[y+1][x>>3]|=b>>(x&7); + m_bg[y+1][(x>>3)+1]|=b<<(8-(x&7)); + m_gfxdecode->gfx(0)->opaque(*m_bitmap,m_bitmap->cliprect(), b,colour, 0,0,x,y); + m_gfxdecode->gfx(0)->opaque(*m_bitmap,m_bitmap->cliprect(), b,colour, 0,0,x,y+1); + } + } + } + else + { + for (k=0; (k<8)&&(y<m_bitmap->height()); k++, y++) + { + b=ch[k]; + m_bg[y][x>>3]|=b>>(x&7); + m_bg[y][(x>>3)+1]|=b<<(8-(x&7)); + + m_gfxdecode->gfx(0)->opaque(*m_bitmap,m_bitmap->cliprect(), b,colour, 0,0,x,y); + } + } +} + + +void arcadia_state::vh_draw_line(int y, UINT8 chars1[16]) +{ + int x, ch, j, h; + int graphics = m_graphics; + h = m_doublescan ? 16 : 8 ; + + if (m_bitmap->height() - m_line < h) + h = m_bitmap->height() - m_line; + + m_bitmap->plot_box(0, y, m_bitmap->width(), h, (m_reg.d.pal[1]&7)); + memset(m_bg[y], 0, sizeof(m_bg[0])*h); + + for (x=XPOS+m_shift, j=0; j<16;j++,x+=8) + { + ch=chars1[j]; +// hangman switches with 0x40 +// alien invaders shield lines start with 0xc0 + if ((ch&0x3f)==0) + { + switch (ch) + { + case 0xc0: graphics=TRUE;break; + case 0x40: graphics=FALSE;break; +// case 0x80: +// alien invaders shields are empty 0x80 +// popmessage(5, "graphics code 0x80 used"); + } + } + if (graphics) + draw_char(m_rectangle[ch&0x3f], ch, y, x); + else + draw_char(m_chars[ch&0x3f], ch, y, x); + } +} + + +int arcadia_state::sprite_collision(int n1, int n2) +{ + int k, b1, b2, x; + if (m_pos[n1].x+8<=m_pos[n2].x) + return FALSE; + if (m_pos[n1].x>=m_pos[n2].x+8) + return FALSE; + + for (k=0; k<8; k++) + { + if (m_pos[n1].y+k<m_pos[n2].y) + continue; + if (m_pos[n1].y+k>=m_pos[n2].y+8) + break; + x=m_pos[n1].x-m_pos[n2].x; + b1=m_reg.d.chars[n1][k]; + b2=m_reg.d.chars[n2][m_pos[n1].y+k-m_pos[n2].y]; + if (x<0) + b2>>=-x; + if (x>0) + b1>>=x; + if (b1&b2) + return TRUE; + } + return FALSE; +} + + +void arcadia_state::draw_sprites() +{ + int i, k, x, y, color=0; + UINT8 b; + + m_reg.d.collision_bg|=0xf; + m_reg.d.collision_sprite|=0x3f; + for (i=0; i<4; i++) + { + int doublescan = FALSE; + if (m_pos[i].y<=-YPOS) continue; + if (m_pos[i].y>=m_bitmap->height()-YPOS-8) continue; + if (m_pos[i].x<=-XPOS) continue; + if (m_pos[i].x>=128+XPOS-8) continue; + + switch (i) + { + case 0: + color=(m_reg.d.pal[3]>>3)&7; + doublescan=m_reg.d.pal[3]&0x80?FALSE:TRUE; + break; + case 1: + color=m_reg.d.pal[3]&7; + doublescan=m_reg.d.pal[3]&0x40?FALSE:TRUE; + break; + case 2: + color=(m_reg.d.pal[2]>>3)&7; + doublescan=m_reg.d.pal[2]&0x80?FALSE:TRUE; + break; + case 3: + color=m_reg.d.pal[2]&7; + doublescan=m_reg.d.pal[2]&0x40?FALSE:TRUE; + break; + } + for (k=0; k<8; k++) + { + int j, m; + b=m_reg.d.chars[i][k]; + x=m_pos[i].x+XPOS; + if (!doublescan) + { + y=m_pos[i].y+YPOS+k; + for (j=0,m=0x80; j<8; j++, m>>=1) + { + if (b & m) + m_bitmap->pix16(y, x + j) = color; + } + } + else + { + y=m_pos[i].y+YPOS+k*2; + for (j=0,m=0x80; j<8; j++, m>>=1) + { + if (b & m) + { + m_bitmap->pix16(y, x + j) = color; + m_bitmap->pix16(y+1, x + j) = color; + } + } + } + if (m_reg.d.collision_bg&(1<<i)) + { + if ( (b<<(8-(x&7))) & ((m_bg[y][x>>3]<<8) | m_bg[y][(x>>3)+1]) ) + m_reg.d.collision_bg&=~(1<<i); + } + } + } + if (sprite_collision(0,1)) m_reg.d.collision_sprite&=~1; + if (sprite_collision(0,2)) m_reg.d.collision_sprite&=~2; + if (sprite_collision(0,3)) m_reg.d.collision_sprite&=~4; + if (sprite_collision(1,2)) m_reg.d.collision_sprite&=~8; + if (sprite_collision(1,3)) m_reg.d.collision_sprite&=~0x10; //guess + if (sprite_collision(2,3)) m_reg.d.collision_sprite&=~0x20; //guess +} + +INTERRUPT_GEN_MEMBER(arcadia_state::video_line) +{ + int width = m_screen->width(); + + if (m_ad_delay<=0) + m_ad_select=m_reg.d.pal[1]&0x40; + else m_ad_delay--; + + m_line++; + m_line%=262; + // unbelievable, reflects only charline, but alien invaders uses it for + // alien scrolling + + if (m_line<m_ypos) + { + m_bitmap->plot_box(0, m_line, width, 1, (m_reg.d.pal[1])&7); + memset(m_bg[m_line], 0, sizeof(m_bg[0])); + } + else + { + int h=m_doublescan?16:8; + + m_charline=(m_line-m_ypos)/h; + + if (m_charline<13) + { + if (((m_line-m_ypos)&(h-1))==0) + { + vh_draw_line(m_charline*h+m_ypos, m_reg.d.chars1[m_charline]); + } + } + else + if (m_lines26 && (m_charline<26)) + { + if (((m_line-m_ypos)&(h-1))==0) + { + vh_draw_line(m_charline*h+m_ypos, m_reg.d.chars2[m_charline-13]); + } + m_charline-=13; + } + else + { + m_charline=0xd; + m_bitmap->plot_box(0, m_line, width, 1, (m_reg.d.pal[1])&7); + memset(m_bg[m_line], 0, sizeof(m_bg[0])); + } + } + if (m_line==261) + draw_sprites(); +} + +READ8_MEMBER( arcadia_state::vsync_r ) +{ + return m_line>=216 ? 0x80 : 0 ; +} + +UINT32 arcadia_state::screen_update_arcadia(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +{ + copybitmap(bitmap, *m_bitmap, 0, 0, 0, 0, cliprect); + return 0; +} |