/* ed:set tabstop=8 noexpandtab: */ /****************************************************************************** * arcadia.c - Arcadia 2001 console emulation * Info taken from MESS' Arcadia driver by Peter Trauner * * Copyright (c) 2004-2006 by Juergen Buchmueller * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: video.c,v 1.20 2006/02/08 20:17:34 pullmoll Exp $ ******************************************************************************/ #include "systypes.h" #include "arcadia/s2637.h" #include "arcadia/sound.h" #include "arcadia/kbd.h" #include "osd.h" #define PAD_DEBUG 0 #define SPR_DEBUG 0 #define MEM_DEBUG 0 #define CHARCOLS 16 #define CHARROWS 26 #define TOTALCOLS 20 #define TOTALROWS 28 #define FIRSTVROW 8 #define LASTVROW (FIRSTVROW+CHARROWS*8) #define FIRSTVCOL 2 #define LASTVCOL (FIRSTVCOL+CHARCOLS-1) #define SCANLINES 262 typedef struct arcadia_s { int frame; u32 scanline; u32 screen[CHARROWS * CHARCOLS]; u32 dirtyall; u32 bgcolor[2]; u32 fgcolor[2]; u8 adselect; u8 skew; u8 charline; u8 row; u8 resolution; u8 graphics; u8 doublescan; u8 *mcolor; u8 *pixpan; u8 *oldpan; u8 bgcoll; u8 spcoll; u8 sense; u32 spritex[4]; u32 spritey[4]; int spritec[4]; u32 spriteh[4]; } arcadia_t; s2637_t *s2637; static arcadia_t arcadia; static osd_bitmap_t *font[2]; static osd_bitmap_t *charmap; static u8 chargen[128 * 8] = { /* char 0x00 */ /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* char 0x01 */ /* .......# */ 0x01, /* ......#. */ 0x02, /* .....#.. */ 0x04, /* ....#... */ 0x08, /* ...#.... */ 0x10, /* ..#..... */ 0x20, /* .#...... */ 0x40, /* #....... */ 0x80, /* char 0x02 */ /* #....... */ 0x80, /* .#...... */ 0x40, /* ..#..... */ 0x20, /* ...#.... */ 0x10, /* ....#... */ 0x08, /* .....#.. */ 0x04, /* ......#. */ 0x02, /* .......# */ 0x01, /* char 0x03 */ /* ######## */ 0xff, /* ######## */ 0xff, /* ######## */ 0xff, /* ######## */ 0xff, /* ######## */ 0xff, /* ######## */ 0xff, /* ######## */ 0xff, /* ######## */ 0xff, /* char 0x04 */ /* ######## */ 0xff, /* ######## */ 0xff, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* char 0x05 */ /* ......## */ 0x03, /* ......## */ 0x03, /* ......## */ 0x03, /* ......## */ 0x03, /* ......## */ 0x03, /* ......## */ 0x03, /* ......## */ 0x03, /* ......## */ 0x03, /* char 0x06 */ /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ######## */ 0xff, /* ######## */ 0xff, /* char 0x07 */ /* ##...... */ 0xc0, /* ##...... */ 0xc0, /* ##...... */ 0xc0, /* ##...... */ 0xc0, /* ##...... */ 0xc0, /* ##...... */ 0xc0, /* ##...... */ 0xc0, /* ##...... */ 0xc0, /* char 0x08 */ /* ######## */ 0xff, /* ######## */ 0xff, /* ......## */ 0x03, /* ......## */ 0x03, /* ......## */ 0x03, /* ......## */ 0x03, /* ......## */ 0x03, /* ......## */ 0x03, /* char 0x09 */ /* ######## */ 0xff, /* ######## */ 0xff, /* ##...... */ 0xc0, /* ##...... */ 0xc0, /* ##...... */ 0xc0, /* ##...... */ 0xc0, /* ##...... */ 0xc0, /* ##...... */ 0xc0, /* char 0x0a */ /* ##...... */ 0xc0, /* ##...... */ 0xc0, /* ##...... */ 0xc0, /* ##...... */ 0xc0, /* ##...... */ 0xc0, /* ##...... */ 0xc0, /* ######## */ 0xff, /* ######## */ 0xff, /* char 0x0b */ /* ......## */ 0x03, /* ......## */ 0x03, /* ......## */ 0x03, /* ......## */ 0x03, /* ......## */ 0x03, /* ......## */ 0x03, /* ######## */ 0xff, /* ######## */ 0xff, /* char 0x0c */ /* .......# */ 0x01, /* ......## */ 0x03, /* .....### */ 0x07, /* ....#### */ 0x0f, /* ...##### */ 0x1f, /* ..###### */ 0x3f, /* .####### */ 0x7f, /* ######## */ 0xff, /* char 0x0d */ /* #....... */ 0x80, /* ##...... */ 0xc0, /* ###..... */ 0xe0, /* ####.... */ 0xf0, /* #####... */ 0xf8, /* ######.. */ 0xfc, /* #######. */ 0xfe, /* ######## */ 0xff, /* char 0x0e */ /* ######## */ 0xff, /* #######. */ 0xfe, /* ######.. */ 0xfc, /* #####... */ 0xf8, /* ####.... */ 0xf0, /* ###..... */ 0xe0, /* ##...... */ 0xc0, /* #....... */ 0x80, /* char 0x0f */ /* ######## */ 0xff, /* .####### */ 0x7f, /* ..###### */ 0x3f, /* ...##### */ 0x1f, /* ....#### */ 0x0f, /* .....### */ 0x07, /* ......## */ 0x03, /* .......# */ 0x01, /* char 0x10 */ /* ........ */ 0x00, /* ...###.. */ 0x1c, /* ..#...#. */ 0x22, /* ..#..##. */ 0x26, /* ..#.#.#. */ 0x2a, /* ..##..#. */ 0x32, /* ..#...#. */ 0x22, /* ...###.. */ 0x1c, /* char 0x11 */ /* ........ */ 0x00, /* ....#... */ 0x08, /* ...##... */ 0x18, /* ....#... */ 0x08, /* ....#... */ 0x08, /* ....#... */ 0x08, /* ....#... */ 0x08, /* ...###.. */ 0x1c, /* char 0x12 */ /* ........ */ 0x00, /* ...###.. */ 0x1c, /* ..#...#. */ 0x22, /* ......#. */ 0x02, /* ....##.. */ 0x0c, /* ...#.... */ 0x10, /* ..#..... */ 0x20, /* ..#####. */ 0x3e, /* char 0x13 */ /* ........ */ 0x00, /* ..#####. */ 0x3e, /* ......#. */ 0x02, /* .....#.. */ 0x04, /* ....##.. */ 0x0c, /* ......#. */ 0x02, /* ..#...#. */ 0x22, /* ...###.. */ 0x1c, /* char 0x14 */ /* ........ */ 0x00, /* .....#.. */ 0x04, /* ....##.. */ 0x0c, /* ...#.#.. */ 0x14, /* ..#..#.. */ 0x24, /* ..#####. */ 0x3e, /* .....#.. */ 0x04, /* .....#.. */ 0x04, /* char 0x15 */ /* ........ */ 0x00, /* ..#####. */ 0x3e, /* ..#..... */ 0x20, /* ..####.. */ 0x3c, /* ......#. */ 0x02, /* ......#. */ 0x02, /* ..#...#. */ 0x22, /* ...###.. */ 0x1c, /* char 0x16 */ /* ........ */ 0x00, /* ....##.. */ 0x0c, /* ...#.... */ 0x10, /* ..#..... */ 0x20, /* ..####.. */ 0x3c, /* ..#...#. */ 0x22, /* ..#...#. */ 0x22, /* ...###.. */ 0x1c, /* char 0x17 */ /* ........ */ 0x00, /* .#####.. */ 0x7c, /* ......#. */ 0x02, /* .....#.. */ 0x04, /* ....#... */ 0x08, /* ...#.... */ 0x10, /* ...#.... */ 0x10, /* ...#.... */ 0x10, /* char 0x18 */ /* ........ */ 0x00, /* ...###.. */ 0x1c, /* ..#...#. */ 0x22, /* ..#...#. */ 0x22, /* ...###.. */ 0x1c, /* ..#...#. */ 0x22, /* ..#...#. */ 0x22, /* ...###.. */ 0x1c, /* char 0x19 */ /* ........ */ 0x00, /* ...###.. */ 0x1c, /* ..#...#. */ 0x22, /* ..#...#. */ 0x22, /* ..#####. */ 0x3e, /* ......#. */ 0x02, /* .....#.. */ 0x04, /* ...##... */ 0x18, /* char 0x1a */ /* ........ */ 0x00, /* ....#... */ 0x08, /* ...#.#.. */ 0x14, /* ..#...#. */ 0x22, /* ..#...#. */ 0x22, /* ..#####. */ 0x3e, /* ..#...#. */ 0x22, /* ..#...#. */ 0x22, /* char 0x1b */ /* ........ */ 0x00, /* ..####.. */ 0x3c, /* ..#...#. */ 0x22, /* ..#...#. */ 0x22, /* ..####.. */ 0x3c, /* ..#...#. */ 0x22, /* ..#...#. */ 0x22, /* ..####.. */ 0x3c, /* char 0x1c */ /* ........ */ 0x00, /* ...###.. */ 0x1c, /* ..#...#. */ 0x22, /* ..#..... */ 0x20, /* ..#..... */ 0x20, /* ..#..... */ 0x20, /* ..#...#. */ 0x22, /* ...###.. */ 0x1c, /* char 0x1d */ /* ........ */ 0x00, /* ..####.. */ 0x3c, /* ..#...#. */ 0x22, /* ..#...#. */ 0x22, /* ..#...#. */ 0x22, /* ..#...#. */ 0x22, /* ..#...#. */ 0x22, /* ..####.. */ 0x3c, /* char 0x1e */ /* ........ */ 0x00, /* ..#####. */ 0x3e, /* ..#..... */ 0x20, /* ..#..... */ 0x20, /* ..####.. */ 0x3c, /* ..#..... */ 0x20, /* ..#..... */ 0x20, /* ..#####. */ 0x3e, /* char 0x1f */ /* ........ */ 0x00, /* ..#####. */ 0x3e, /* ..#..... */ 0x20, /* ..#..... */ 0x20, /* ..####.. */ 0x3c, /* ..#..... */ 0x20, /* ..#..... */ 0x20, /* ..#..... */ 0x20, /* char 0x20 */ /* ........ */ 0x00, /* ...####. */ 0x1e, /* ..#..... */ 0x20, /* ..#..... */ 0x20, /* ..#..... */ 0x20, /* ..#..##. */ 0x26, /* ..#...#. */ 0x22, /* ...####. */ 0x1e, /* char 0x21 */ /* ........ */ 0x00, /* ..#...#. */ 0x22, /* ..#...#. */ 0x22, /* ..#...#. */ 0x22, /* ..#####. */ 0x3e, /* ..#...#. */ 0x22, /* ..#...#. */ 0x22, /* ..#...#. */ 0x22, /* char 0x22 */ /* ........ */ 0x00, /* ...###.. */ 0x1c, /* ....#... */ 0x08, /* ....#... */ 0x08, /* ....#... */ 0x08, /* ....#... */ 0x08, /* ....#... */ 0x08, /* ...###.. */ 0x1c, /* char 0x23 */ /* ........ */ 0x00, /* ......#. */ 0x02, /* ......#. */ 0x02, /* ......#. */ 0x02, /* ......#. */ 0x02, /* ......#. */ 0x02, /* ..#...#. */ 0x22, /* ...###.. */ 0x1c, /* char 0x24 */ /* ........ */ 0x00, /* ..#...#. */ 0x22, /* ..#..#.. */ 0x24, /* ..#.#... */ 0x28, /* ..##.... */ 0x30, /* ..#.#... */ 0x28, /* ..#..#.. */ 0x24, /* ..#...#. */ 0x22, /* char 0x25 */ /* ........ */ 0x00, /* ..#..... */ 0x20, /* ..#..... */ 0x20, /* ..#..... */ 0x20, /* ..#..... */ 0x20, /* ..#..... */ 0x20, /* ..#..... */ 0x20, /* ..#####. */ 0x3e, /* char 0x26 */ /* ........ */ 0x00, /* ..#...#. */ 0x22, /* ..##.##. */ 0x36, /* ..#.#.#. */ 0x2a, /* ..#.#.#. */ 0x2a, /* ..#...#. */ 0x22, /* ..#...#. */ 0x22, /* ..#...#. */ 0x22, /* char 0x27 */ /* ........ */ 0x00, /* ..#...#. */ 0x22, /* ..#...#. */ 0x22, /* ..##..#. */ 0x32, /* ..#.#.#. */ 0x2a, /* ..#..##. */ 0x26, /* ..#...#. */ 0x22, /* ..#...#. */ 0x22, /* char 0x28 */ /* ........ */ 0x00, /* ...###.. */ 0x1c, /* ..#...#. */ 0x22, /* ..#...#. */ 0x22, /* ..#...#. */ 0x22, /* ..#...#. */ 0x22, /* ..#...#. */ 0x22, /* ...###.. */ 0x1c, /* char 0x29 */ /* ........ */ 0x00, /* ..####.. */ 0x3c, /* ..#...#. */ 0x22, /* ..#...#. */ 0x22, /* ..####.. */ 0x3c, /* ..#..... */ 0x20, /* ..#..... */ 0x20, /* ..#..... */ 0x20, /* char 0x2a */ /* ........ */ 0x00, /* ...###.. */ 0x1c, /* ..#...#. */ 0x22, /* ..#...#. */ 0x22, /* ..#...#. */ 0x22, /* ..#.#.#. */ 0x2a, /* ..#..#.. */ 0x24, /* ...##.#. */ 0x1a, /* char 0x2b */ /* ........ */ 0x00, /* ..####.. */ 0x3c, /* ..#...#. */ 0x22, /* ..#...#. */ 0x22, /* ..####.. */ 0x3c, /* ..#.#... */ 0x28, /* ..#..#.. */ 0x24, /* ..#...#. */ 0x22, /* char 0x2c */ /* ........ */ 0x00, /* ...###.. */ 0x1c, /* ..#...#. */ 0x22, /* ..#..... */ 0x20, /* ...###.. */ 0x1c, /* ......#. */ 0x02, /* ..#...#. */ 0x22, /* ...###.. */ 0x1c, /* char 0x2d */ /* ........ */ 0x00, /* ..#####. */ 0x3e, /* ....#... */ 0x08, /* ....#... */ 0x08, /* ....#... */ 0x08, /* ....#... */ 0x08, /* ....#... */ 0x08, /* ....#... */ 0x08, /* char 0x2e */ /* ........ */ 0x00, /* ..#...#. */ 0x22, /* ..#...#. */ 0x22, /* ..#...#. */ 0x22, /* ..#...#. */ 0x22, /* ..#...#. */ 0x22, /* ..#...#. */ 0x22, /* ...###.. */ 0x1c, /* char 0x2f */ /* ........ */ 0x00, /* ..#...#. */ 0x22, /* ..#...#. */ 0x22, /* ..#...#. */ 0x22, /* ..#...#. */ 0x22, /* ..#...#. */ 0x22, /* ...#.#.. */ 0x14, /* ....#... */ 0x08, /* char 0x30 */ /* ........ */ 0x00, /* ..#...#. */ 0x22, /* ..#...#. */ 0x22, /* ..#...#. */ 0x22, /* ..#.#.#. */ 0x2a, /* ..#.#.#. */ 0x2a, /* ..##.##. */ 0x36, /* ..#...#. */ 0x22, /* char 0x31 */ /* ........ */ 0x00, /* ..#...#. */ 0x22, /* ..#...#. */ 0x22, /* ...#.#.. */ 0x14, /* ....#... */ 0x08, /* ...#.#.. */ 0x14, /* ..#...#. */ 0x22, /* ..#...#. */ 0x22, /* char 0x32 */ /* ........ */ 0x00, /* ..#...#. */ 0x22, /* ..#...#. */ 0x22, /* ...#.#.. */ 0x14, /* ....#... */ 0x08, /* ....#... */ 0x08, /* ....#... */ 0x08, /* ....#... */ 0x08, /* char 0x33 */ /* ........ */ 0x00, /* ..#####. */ 0x3e, /* ......#. */ 0x02, /* .....#.. */ 0x04, /* ....#... */ 0x08, /* ...#.... */ 0x10, /* ..#..... */ 0x20, /* ..#####. */ 0x3e, /* char 0x34 */ /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ....#... */ 0x08, /* char 0x35 */ /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ....#... */ 0x08, /* ....#... */ 0x08, /* ...#.... */ 0x10, /* char 0x36 */ /* ........ */ 0x00, /* ........ */ 0x00, /* ....#... */ 0x08, /* ....#... */ 0x08, /* ..#####. */ 0x3e, /* ....#... */ 0x08, /* ....#... */ 0x08, /* ........ */ 0x00, /* char 0x37 */ /* ........ */ 0x00, /* ....#... */ 0x08, /* ...####. */ 0x1e, /* ..#.#... */ 0x28, /* ...###.. */ 0x1c, /* ....#.#. */ 0x0a, /* ..####.. */ 0x3c, /* ....#... */ 0x08, /* char 0x38 */ /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* char 0x39 */ /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* char 0x3a */ /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* char 0x3b */ /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* char 0x3c */ /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* char 0x3d */ /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* char 0x3e */ /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* char 0x3f */ /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* char 0x40 */ /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* char 0x41 */ /* ......## */ 0x03, /* ......## */ 0x03, /* ......## */ 0x03, /* ......## */ 0x03, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* char 0x42 */ /* ...###.. */ 0x1c, /* ...###.. */ 0x1c, /* ...###.. */ 0x1c, /* ...###.. */ 0x1c, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* char 0x43 */ /* ...##### */ 0x1f, /* ...##### */ 0x1f, /* ...##### */ 0x1f, /* ...##### */ 0x1f, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* char 0x44 */ /* ###..... */ 0xe0, /* ###..... */ 0xe0, /* ###..... */ 0xe0, /* ###..... */ 0xe0, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* char 0x45 */ /* ###...## */ 0xe3, /* ###...## */ 0xe3, /* ###...## */ 0xe3, /* ###...## */ 0xe3, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* char 0x46 */ /* ######.. */ 0xfc, /* ######.. */ 0xfc, /* ######.. */ 0xfc, /* ######.. */ 0xfc, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* char 0x47 */ /* ######## */ 0xff, /* ######## */ 0xff, /* ######## */ 0xff, /* ######## */ 0xff, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* char 0x48 */ /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ......## */ 0x03, /* ......## */ 0x03, /* ......## */ 0x03, /* ......## */ 0x03, /* char 0x49 */ /* ......## */ 0x03, /* ......## */ 0x03, /* ......## */ 0x03, /* ......## */ 0x03, /* ......## */ 0x03, /* ......## */ 0x03, /* ......## */ 0x03, /* ......## */ 0x03, /* char 0x4a */ /* ...###.. */ 0x1c, /* ...###.. */ 0x1c, /* ...###.. */ 0x1c, /* ...###.. */ 0x1c, /* ......## */ 0x03, /* ......## */ 0x03, /* ......## */ 0x03, /* ......## */ 0x03, /* char 0x4b */ /* ...##### */ 0x1f, /* ...##### */ 0x1f, /* ...##### */ 0x1f, /* ...##### */ 0x1f, /* ......## */ 0x03, /* ......## */ 0x03, /* ......## */ 0x03, /* ......## */ 0x03, /* char 0x4c */ /* ###..... */ 0xe0, /* ###..... */ 0xe0, /* ###..... */ 0xe0, /* ###..... */ 0xe0, /* ......## */ 0x03, /* ......## */ 0x03, /* ......## */ 0x03, /* ......## */ 0x03, /* char 0x4d */ /* ###...## */ 0xe3, /* ###...## */ 0xe3, /* ###...## */ 0xe3, /* ###...## */ 0xe3, /* ......## */ 0x03, /* ......## */ 0x03, /* ......## */ 0x03, /* ......## */ 0x03, /* char 0x4e */ /* ######.. */ 0xfc, /* ######.. */ 0xfc, /* ######.. */ 0xfc, /* ######.. */ 0xfc, /* ......## */ 0x03, /* ......## */ 0x03, /* ......## */ 0x03, /* ......## */ 0x03, /* char 0x4f */ /* ######## */ 0xff, /* ######## */ 0xff, /* ######## */ 0xff, /* ######## */ 0xff, /* ......## */ 0x03, /* ......## */ 0x03, /* ......## */ 0x03, /* ......## */ 0x03, /* char 0x50 */ /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ...###.. */ 0x1c, /* ...###.. */ 0x1c, /* ...###.. */ 0x1c, /* ...###.. */ 0x1c, /* char 0x51 */ /* ......## */ 0x03, /* ......## */ 0x03, /* ......## */ 0x03, /* ......## */ 0x03, /* ...###.. */ 0x1c, /* ...###.. */ 0x1c, /* ...###.. */ 0x1c, /* ...###.. */ 0x1c, /* char 0x52 */ /* ...###.. */ 0x1c, /* ...###.. */ 0x1c, /* ...###.. */ 0x1c, /* ...###.. */ 0x1c, /* ...###.. */ 0x1c, /* ...###.. */ 0x1c, /* ...###.. */ 0x1c, /* ...###.. */ 0x1c, /* char 0x53 */ /* ...##### */ 0x1f, /* ...##### */ 0x1f, /* ...##### */ 0x1f, /* ...##### */ 0x1f, /* ...###.. */ 0x1c, /* ...###.. */ 0x1c, /* ...###.. */ 0x1c, /* ...###.. */ 0x1c, /* char 0x54 */ /* ###..... */ 0xe0, /* ###..... */ 0xe0, /* ###..... */ 0xe0, /* ###..... */ 0xe0, /* ...###.. */ 0x1c, /* ...###.. */ 0x1c, /* ...###.. */ 0x1c, /* ...###.. */ 0x1c, /* char 0x55 */ /* ###...## */ 0xe3, /* ###...## */ 0xe3, /* ###...## */ 0xe3, /* ###...## */ 0xe3, /* ...###.. */ 0x1c, /* ...###.. */ 0x1c, /* ...###.. */ 0x1c, /* ...###.. */ 0x1c, /* char 0x56 */ /* ######.. */ 0xfc, /* ######.. */ 0xfc, /* ######.. */ 0xfc, /* ######.. */ 0xfc, /* ...###.. */ 0x1c, /* ...###.. */ 0x1c, /* ...###.. */ 0x1c, /* ...###.. */ 0x1c, /* char 0x57 */ /* ######## */ 0xff, /* ######## */ 0xff, /* ######## */ 0xff, /* ######## */ 0xff, /* ...###.. */ 0x1c, /* ...###.. */ 0x1c, /* ...###.. */ 0x1c, /* ...###.. */ 0x1c, /* char 0x58 */ /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ...##### */ 0x1f, /* ...##### */ 0x1f, /* ...##### */ 0x1f, /* ...##### */ 0x1f, /* char 0x59 */ /* ......## */ 0x03, /* ......## */ 0x03, /* ......## */ 0x03, /* ......## */ 0x03, /* ...##### */ 0x1f, /* ...##### */ 0x1f, /* ...##### */ 0x1f, /* ...##### */ 0x1f, /* char 0x5a */ /* ...###.. */ 0x1c, /* ...###.. */ 0x1c, /* ...###.. */ 0x1c, /* ...###.. */ 0x1c, /* ...##### */ 0x1f, /* ...##### */ 0x1f, /* ...##### */ 0x1f, /* ...##### */ 0x1f, /* char 0x5b */ /* ...##### */ 0x1f, /* ...##### */ 0x1f, /* ...##### */ 0x1f, /* ...##### */ 0x1f, /* ...##### */ 0x1f, /* ...##### */ 0x1f, /* ...##### */ 0x1f, /* ...##### */ 0x1f, /* char 0x5c */ /* ###..... */ 0xe0, /* ###..... */ 0xe0, /* ###..... */ 0xe0, /* ###..... */ 0xe0, /* ...##### */ 0x1f, /* ...##### */ 0x1f, /* ...##### */ 0x1f, /* ...##### */ 0x1f, /* char 0x5d */ /* ###...## */ 0xe3, /* ###...## */ 0xe3, /* ###...## */ 0xe3, /* ###...## */ 0xe3, /* ...##### */ 0x1f, /* ...##### */ 0x1f, /* ...##### */ 0x1f, /* ...##### */ 0x1f, /* char 0x5e */ /* ######.. */ 0xfc, /* ######.. */ 0xfc, /* ######.. */ 0xfc, /* ######.. */ 0xfc, /* ...##### */ 0x1f, /* ...##### */ 0x1f, /* ...##### */ 0x1f, /* ...##### */ 0x1f, /* char 0x5f */ /* ######## */ 0xff, /* ######## */ 0xff, /* ######## */ 0xff, /* ######## */ 0xff, /* ...##### */ 0x1f, /* ...##### */ 0x1f, /* ...##### */ 0x1f, /* ...##### */ 0x1f, /* char 0x60 */ /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ###..... */ 0xe0, /* ###..... */ 0xe0, /* ###..... */ 0xe0, /* ###..... */ 0xe0, /* char 0x61 */ /* ......## */ 0x03, /* ......## */ 0x03, /* ......## */ 0x03, /* ......## */ 0x03, /* ###..... */ 0xe0, /* ###..... */ 0xe0, /* ###..... */ 0xe0, /* ###..... */ 0xe0, /* char 0x62 */ /* ...###.. */ 0x1c, /* ...###.. */ 0x1c, /* ...###.. */ 0x1c, /* ...###.. */ 0x1c, /* ###..... */ 0xe0, /* ###..... */ 0xe0, /* ###..... */ 0xe0, /* ###..... */ 0xe0, /* char 0x63 */ /* ...##### */ 0x1f, /* ...##### */ 0x1f, /* ...##### */ 0x1f, /* ...##### */ 0x1f, /* ###..... */ 0xe0, /* ###..... */ 0xe0, /* ###..... */ 0xe0, /* ###..... */ 0xe0, /* char 0x64 */ /* ###..... */ 0xe0, /* ###..... */ 0xe0, /* ###..... */ 0xe0, /* ###..... */ 0xe0, /* ###..... */ 0xe0, /* ###..... */ 0xe0, /* ###..... */ 0xe0, /* ###..... */ 0xe0, /* char 0x65 */ /* ###...## */ 0xe3, /* ###...## */ 0xe3, /* ###...## */ 0xe3, /* ###...## */ 0xe3, /* ###..... */ 0xe0, /* ###..... */ 0xe0, /* ###..... */ 0xe0, /* ###..... */ 0xe0, /* char 0x66 */ /* ######.. */ 0xfc, /* ######.. */ 0xfc, /* ######.. */ 0xfc, /* ######.. */ 0xfc, /* ###..... */ 0xe0, /* ###..... */ 0xe0, /* ###..... */ 0xe0, /* ###..... */ 0xe0, /* char 0x67 */ /* ######## */ 0xff, /* ######## */ 0xff, /* ######## */ 0xff, /* ######## */ 0xff, /* ###..... */ 0xe0, /* ###..... */ 0xe0, /* ###..... */ 0xe0, /* ###..... */ 0xe0, /* char 0x68 */ /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ###...## */ 0xe3, /* ###...## */ 0xe3, /* ###...## */ 0xe3, /* ###...## */ 0xe3, /* char 0x69 */ /* ......## */ 0x03, /* ......## */ 0x03, /* ......## */ 0x03, /* ......## */ 0x03, /* ###...## */ 0xe3, /* ###...## */ 0xe3, /* ###...## */ 0xe3, /* ###...## */ 0xe3, /* char 0x6a */ /* ...###.. */ 0x1c, /* ...###.. */ 0x1c, /* ...###.. */ 0x1c, /* ...###.. */ 0x1c, /* ###...## */ 0xe3, /* ###...## */ 0xe3, /* ###...## */ 0xe3, /* ###...## */ 0xe3, /* char 0x6b */ /* ...##### */ 0x1f, /* ...##### */ 0x1f, /* ...##### */ 0x1f, /* ...##### */ 0x1f, /* ###...## */ 0xe3, /* ###...## */ 0xe3, /* ###...## */ 0xe3, /* ###...## */ 0xe3, /* char 0x6c */ /* ###..... */ 0xe0, /* ###..... */ 0xe0, /* ###..... */ 0xe0, /* ###..... */ 0xe0, /* ###...## */ 0xe3, /* ###...## */ 0xe3, /* ###...## */ 0xe3, /* ###...## */ 0xe3, /* char 0x6d */ /* ###...## */ 0xe3, /* ###...## */ 0xe3, /* ###...## */ 0xe3, /* ###...## */ 0xe3, /* ###...## */ 0xe3, /* ###...## */ 0xe3, /* ###...## */ 0xe3, /* ###...## */ 0xe3, /* char 0x6e */ /* ######.. */ 0xfc, /* ######.. */ 0xfc, /* ######.. */ 0xfc, /* ######.. */ 0xfc, /* ###...## */ 0xe3, /* ###...## */ 0xe3, /* ###...## */ 0xe3, /* ###...## */ 0xe3, /* char 0x6f */ /* ######## */ 0xff, /* ######## */ 0xff, /* ######## */ 0xff, /* ######## */ 0xff, /* ###...## */ 0xe3, /* ###...## */ 0xe3, /* ###...## */ 0xe3, /* ###...## */ 0xe3, /* char 0x70 */ /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ######.. */ 0xfc, /* ######.. */ 0xfc, /* ######.. */ 0xfc, /* ######.. */ 0xfc, /* char 0x71 */ /* ......## */ 0x03, /* ......## */ 0x03, /* ......## */ 0x03, /* ......## */ 0x03, /* ######.. */ 0xfc, /* ######.. */ 0xfc, /* ######.. */ 0xfc, /* ######.. */ 0xfc, /* char 0x72 */ /* ...###.. */ 0x1c, /* ...###.. */ 0x1c, /* ...###.. */ 0x1c, /* ...###.. */ 0x1c, /* ######.. */ 0xfc, /* ######.. */ 0xfc, /* ######.. */ 0xfc, /* ######.. */ 0xfc, /* char 0x73 */ /* ...##### */ 0x1f, /* ...##### */ 0x1f, /* ...##### */ 0x1f, /* ...##### */ 0x1f, /* ######.. */ 0xfc, /* ######.. */ 0xfc, /* ######.. */ 0xfc, /* ######.. */ 0xfc, /* char 0x74 */ /* ###..... */ 0xe0, /* ###..... */ 0xe0, /* ###..... */ 0xe0, /* ###..... */ 0xe0, /* ######.. */ 0xfc, /* ######.. */ 0xfc, /* ######.. */ 0xfc, /* ######.. */ 0xfc, /* char 0x75 */ /* ###...## */ 0xe3, /* ###...## */ 0xe3, /* ###...## */ 0xe3, /* ###...## */ 0xe3, /* ######.. */ 0xfc, /* ######.. */ 0xfc, /* ######.. */ 0xfc, /* ######.. */ 0xfc, /* char 0x76 */ /* ######.. */ 0xfc, /* ######.. */ 0xfc, /* ######.. */ 0xfc, /* ######.. */ 0xfc, /* ######.. */ 0xfc, /* ######.. */ 0xfc, /* ######.. */ 0xfc, /* ######.. */ 0xfc, /* char 0x77 */ /* ######## */ 0xff, /* ######## */ 0xff, /* ######## */ 0xff, /* ######## */ 0xff, /* ######.. */ 0xfc, /* ######.. */ 0xfc, /* ######.. */ 0xfc, /* ######.. */ 0xfc, /* char 0x78 */ /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ........ */ 0x00, /* ######## */ 0xff, /* ######## */ 0xff, /* ######## */ 0xff, /* ######## */ 0xff, /* char 0x79 */ /* ......## */ 0x03, /* ......## */ 0x03, /* ......## */ 0x03, /* ......## */ 0x03, /* ######## */ 0xff, /* ######## */ 0xff, /* ######## */ 0xff, /* ######## */ 0xff, /* char 0x7a */ /* ...###.. */ 0x1c, /* ...###.. */ 0x1c, /* ...###.. */ 0x1c, /* ...###.. */ 0x1c, /* ######## */ 0xff, /* ######## */ 0xff, /* ######## */ 0xff, /* ######## */ 0xff, /* char 0x7b */ /* ...##### */ 0x1f, /* ...##### */ 0x1f, /* ...##### */ 0x1f, /* ...##### */ 0x1f, /* ######## */ 0xff, /* ######## */ 0xff, /* ######## */ 0xff, /* ######## */ 0xff, /* char 0x7c */ /* ###..... */ 0xe0, /* ###..... */ 0xe0, /* ###..... */ 0xe0, /* ###..... */ 0xe0, /* ######## */ 0xff, /* ######## */ 0xff, /* ######## */ 0xff, /* ######## */ 0xff, /* char 0x7d */ /* ###...## */ 0xe3, /* ###...## */ 0xe3, /* ###...## */ 0xe3, /* ###...## */ 0xe3, /* ######## */ 0xff, /* ######## */ 0xff, /* ######## */ 0xff, /* ######## */ 0xff, /* char 0x7e */ /* ######.. */ 0xfc, /* ######.. */ 0xfc, /* ######.. */ 0xfc, /* ######.. */ 0xfc, /* ######## */ 0xff, /* ######## */ 0xff, /* ######## */ 0xff, /* ######## */ 0xff, /* char 0x7f */ /* ######## */ 0xff, /* ######## */ 0xff, /* ######## */ 0xff, /* ######## */ 0xff, /* ######## */ 0xff, /* ######## */ 0xff, /* ######## */ 0xff, /* ######## */ 0xff, }; static u32 palette[8]; static void sprite_dirty(int n); #if SPR_DEBUG static const char *binary(u32 val) { static char buff[4][64]; static int which; char *dst; int i; which = (which + 1) % 4; dst = buff[which]; for (i = 32; i > 0; i--) { dst[i-1] = '0' + (val & 1); val >>= 1; } dst[32] = '\0'; return buff[which]; } #endif INLINE void arcadia_charline(void) { int scanline = cpu_getscanline(); int h = 16 >> arcadia.resolution; #if 0 if (scanline < 0) { arcadia.scanline = 0; } else if (scanline >= SCANLINES) { arcadia.scanline = SCANLINES - 1; } else { arcadia.scanline = scanline; } #else arcadia.scanline = scanline - 7; #endif if (scanline < arcadia.skew) { arcadia.row = 31; arcadia.charline = 15; return; } scanline -= arcadia.skew; if (scanline >= CHARROWS * 8) { arcadia.row = 26; arcadia.charline = 13; return; } arcadia.row = scanline / h; arcadia.charline = arcadia.row; if (arcadia.charline >= 13) arcadia.charline -= 13; } /*********** 000 - 0cf *************************** * 13 lines with 16 characters each * bit(s) function * ----------------------------------------------- * 7,6 color * 5-0 character code ************************************************/ WRITE8_HANDLER( s2637_video1_w ) { s2637->video1[offset] = data; } READ8_HANDLER( s2637_video1_r ) { return s2637->video1[offset]; } /*********** 0d0 - 0ef *************************** * 32 bytes of user RAM *************************************************/ WRITE8_HANDLER( s2637_ram1_w ) { s2637->ram1[offset] = data; } READ8_HANDLER( s2637_ram1_r ) { return s2637->ram1[offset]; } /*********** 0f0,0f2,0f4,0f6 ********************* * bit(s) function * ----------------------------------------------- * 7-0 sprite 0,1,2,3 scanline offset * 0xfe -> scanline 2 * ... * 0x00 -> scanline 256 *********** 0f1,0f3,0f5,0f7 * bit(s) function * ----------------------------------------------- * 7-0 sprite 0,1,2,3 clock offset (pixel) * ----------------------------------------------- * The value is the pixel offset in the scanline * where the sprite is displayed minus 10. * The offset is probably due to the delay caused * by loading a shift register with the character * generator data. *************************************************/ WRITE8_HANDLER( s2637_sprite_w ) { int n; if (data == s2637->sprite[offset]) return; n = offset / 2; sprite_dirty(n); if (offset & 1) { arcadia.spritex[n] = data - 10 - (4 - FIRSTVCOL) * 8; } else { arcadia.spritey[n] = (data ^ 0xff) + 1; } s2637->sprite[offset] = data; } READ8_HANDLER( s2637_sprite_r ) { return s2637->sprite[offset]; } /*********** 0f8 - 0fb * 4 bytes of user RAM *************************************************/ WRITE8_HANDLER( s2637_ram2_w ) { s2637->ram2[offset] = data; } READ8_HANDLER( s2637_ram2_r ) { return s2637->ram2[offset]; } /*********** 0fc * bit(s) function * ----------------------------------------------- * 7-0 scanline offset (1's complement) * ----------------------------------------------- *************************************************/ WRITE8_HANDLER( s2637_vpos_w ) { if (data == s2637->vpos) return; arcadia.skew = data ^ 0xff; arcadia.dirtyall = -1; s2637->vpos = data; } READ8_HANDLER( s2637_vpos_r ) { return s2637->vpos; } /*********** 0fd * bit(s) function * ----------------------------------------------- * 7 multi color mode * 6-0 sound pitch * ----------------------------------------------- *************************************************/ WRITE8_HANDLER( s2637_pitch_w ) { if (data == s2637->pitch) return; if ((data ^ s2637->pitch) & 0x80) { arcadia_charline(); arcadia.mcolor[arcadia.scanline + 8] = ((data ^ 0x80) >> 7) & 1; } if ((data ^ s2637->pitch) & 0x7f) { s2637_sh_pitch_w(0, data & 0x7f); } s2637->pitch = data; } READ8_HANDLER( s2637_pitch_r ) { return s2637->pitch; } /*********** 0fe * bit(s) function * ----------------------------------------------- * 7,6,5 character line pixel offset * 4 random noise enable * 3 sound enable * 2,1,0 sound volume * ----------------------------------------------- *************************************************/ WRITE8_HANDLER( s2637_volume_w ) { if (data == s2637->volume) return; if ((data ^ s2637->volume) & 0xe0) { arcadia_charline(); arcadia.pixpan[arcadia.scanline + 8] = (data & 0xe0) >> 5; } if ((data ^ s2637->volume) & 0x1f) { s2637_sh_volume_w(0, data & 0x1f); } s2637->volume = data; } READ8_HANDLER( s2637_volume_r ) { u8 data = s2637->volume; return data; } /*********** 0ff - current character line * bit(s) function * ----------------------------------------------- * 7,6,5,4 unused (always 1) * 3,2,1,0 current character row * ----------------------------------------------- * 15 = beginning of DMA (before first line) * 0-12 = current character line * 13 = end of DMA (after last line) *************************************************/ WRITE8_HANDLER( s2637_charline_w ) { /* not writeable */ } /*********** 0ff - current character line ******** * bit(s) function * ----------------------------------------------- * 7,6,5,4 unused (always 1) * 3,2,1,0 current character line * ----------------------------------------------- * NOTE: counts 0,1,2 .. 12 for visible lines * 13 for background lines (vertical blank) *************************************************/ READ8_HANDLER( s2637_charline_r ) { arcadia_charline(); s2637->charline = 0xf0 | arcadia.charline; return s2637->charline; } /*********** 100-103 * bit(s) function * ----------------------------------------------- * 7-4 unused * 3 row #3 key: [ 1 ] [ 2 ] [ 3 ] [ A ] * 2 row #2 key: [ 4 ] [ 5 ] [ 6 ] [ B ] * 1 row #1 key: [ 7 ] [ 8 ] [ 9 ] [ C ] * 0 row #0 key: [ENT] [ 0 ] [CLR] [ D ] * ----------------------------------------------- * Column 3 (A,B,C,D) exists only on some systems *************************************************/ WRITE8_HANDLER( s2637_keypad1_w ) { /* read only register */ } READ8_HANDLER( s2637_keypad1_r ) { return s2637->keypad1[offset]; } /*********** 104-107 * bit(s) function * ----------------------------------------------- * 7-4 unused * 3 row #3 key: [ 1 ] [ 2 ] [ 3 ] [ A ] * 2 row #2 key: [ 4 ] [ 5 ] [ 6 ] [ B ] * 1 row #1 key: [ 7 ] [ 8 ] [ 9 ] [ C ] * 0 row #0 key: [ENT] [ 0 ] [CLR] [ D ] * ----------------------------------------------- * Column 3 (A,B,C,D) exists only on some systems *************************************************/ WRITE8_HANDLER( s2637_keypad2_w ) { /* read only register */ } READ8_HANDLER( s2637_keypad2_r ) { return s2637->keypad2[offset]; } /*********** 108 * bit(s) function * ----------------------------------------------- * 7-4 unused * 3 unknown (seems to be queried) * 2 select button * 1 option button * 0 start button * ----------------------------------------------- * The bits are "sample and hold" until vblank *************************************************/ WRITE8_HANDLER( s2637_buttons_w ) { s2637->buttons = data; } READ8_HANDLER( s2637_buttons_r ) { /*********** 1908 * bit(s) function * ----------------------------------------------- * 7-4 unused * 3 unknown (seems to be queried) * 2 select button * 1 option button * 0 start button * ----------------------------------------------- * The bits are "sample and hold" until vblank ***********/ #if PAD_DEBUG LOG((3,"S2637","buttons: %02x\n", s2637->buttons)); #endif return s2637->buttons; } /*********** 109-17f * Unmapped memory (not RAM?) *************************************************/ WRITE8_HANDLER( s2637_unmapped_w ) { /* don't write */ } READ8_HANDLER( s2637_unmapped_r ) { return s2637->unmapped[offset]; } /*********** 180-1bf * bit(s) function * ----------------------------------------------- * 7-0 pixel data with bit 7 = leftmost * ----------------------------------------------- * The 8 character codes 0x38 to 0x3f are user * defined graphics. Each character takes 8 * consecutive bytes. The first four characters * at the same time are used to display sprites. *************************************************/ WRITE8_HANDLER( s2637_chgen_w ) { int n; if (data == s2637->chgen[offset]) return; n = offset / 8; if (n < 4) sprite_dirty(n); s2637->chgen[offset] = data; } READ8_HANDLER( s2637_chgen_r ) { return s2637->chgen[offset]; } /*********** 1c0-1f7 ***************************** * The function of this memory range is unkown *************************************************/ WRITE8_HANDLER( s2637_unknown_w ) { s2637->unknown[offset] = data; } READ8_HANDLER( s2637_unknown_r ) { return s2637->unknown[offset]; } /*********** 1f8 ********************************* * bit(s) function * ----------------------------------------------- * 7 graphics mode * 6 screen resolution 26/13 lines * 5,4,3 palette entry 0 foreground color * 2,1,0 palette entry 0 background color * ----------------------------------------------- * write only register - read returns 0xff *************************************************/ WRITE8_HANDLER( s2637_pal0_w ) { if (data == s2637->pal0) return; arcadia.graphics = (data >> 1) & 0x40; arcadia.resolution = (data >> 6) & 1; arcadia.fgcolor[0] = (data >> 3) & 7; arcadia.bgcolor[0] = data & 7; s2637->pal0 = data; } READ8_HANDLER( s2637_pal0_r ) { return 0xff; } /*********** 1f9 ********************************* * bit(s) function * ----------------------------------------------- * 7 double scan mode * 6 A/D select (0 horz, 1, vert) * 5,4,3 palette entry 1 foreground color * 2,1,0 palette entry 1 background color * ----------------------------------------------- * write only register - read returns 0xff *************************************************/ WRITE8_HANDLER( s2637_pal1_w ) { if (data == s2637->pal1) return; arcadia.doublescan = (data & 0x80) ? 0 : 1; arcadia.adselect = (data & 0x40) ? 0 : 1; arcadia.fgcolor[1] = (data >> 3) & 7; arcadia.bgcolor[1] = data & 7; s2637->pal1 = data; } READ8_HANDLER( s2637_pal1_r ) { return 0xff; } /*********** 1fa ********************************* * bit(s) function * ----------------------------------------------- * 7 sprite 2 double scan * 6 sprite 3 double scan * 5,4,3 sprite 2 color * 2,1,0 sprite 3 color * ----------------------------------------------- * write only register - read returns 0xff *************************************************/ WRITE8_HANDLER( s2637_pal2_w ) { if (data == s2637->pal2) return; sprite_dirty(2); arcadia.spriteh[2] = (data & 0x80) ? 8 : 16; arcadia.spritec[2] = (data >> 3) & 7; sprite_dirty(3); arcadia.spriteh[3] = (data & 0x40) ? 8 : 16; arcadia.spritec[3] = data & 7; s2637->pal2 = data; } READ8_HANDLER( s2637_pal2_r ) { return 0xff; } /*********** 1fb ********************************* * bit(s) function * ----------------------------------------------- * 7 sprite 0 double scan * 6 sprite 1 double scan * 5,4,3 sprite 0 color * 2,1,0 sprite 1 color * ----------------------------------------------- * write only register - read returns 0xff *************************************************/ WRITE8_HANDLER( s2637_pal3_w ) { if (data == s2637->pal3) return; sprite_dirty(0); arcadia.spriteh[0] = (data & 0x80) ? 8 : 16; arcadia.spritec[0] = (data >> 3) & 7; sprite_dirty(1); arcadia.spriteh[1] = (data & 0x40) ? 8 : 16; arcadia.spritec[1] = data & 7; s2637->pal3 = data; } READ8_HANDLER( s2637_pal3_r ) { return 0xff; } /*********** 1fc * bit(s) function * ----------------------------------------------- * 7,6,5,4 always 1 * 3 sprite 3 background collision (0) * 2 sprite 2 background collision (0) * 1 sprite 1 background collision (0) * 0 sprite 0 background collision (0) * ----------------------------------------------- * Reads (and writes?) reset this register. *************************************************/ WRITE8_HANDLER( s2637_bgcoll_w ) { s2637->bgcoll = 0xff; } READ8_HANDLER( s2637_bgcoll_r ) { u8 data = s2637->bgcoll; s2637->bgcoll = 0xff; return data; } /*********** 1fd * bit(s) function * ----------------------------------------------- * 7,6 always 1 * 5 sprite 2 sprite 3 collision (0) * 4 sprite 1 sprite 3 collision (0) * 3 sprite 1 sprite 2 collision (0) * 2 sprite 0 sprite 3 collision (0) * 1 sprite 0 sprite 2 collision (0) * 0 sprite 0 sprite 1 collision (0) * ----------------------------------------------- * Reads (and writes?) reset this register. *************************************************/ WRITE8_HANDLER( s2637_spcoll_w ) { s2637->spcoll = 0xff; } READ8_HANDLER( s2637_spcoll_r ) { u8 data = s2637->spcoll; s2637->spcoll = 0xff; return data; } /*********** 1fe * bit(s) function * ----------------------------------------------- * 7-0 paddle 2 position * ----------------------------------------------- * Range 00 - fe, ff during VRST * paddle2 x or y *************************************************/ WRITE8_HANDLER( s2637_paddle2_w ) { /* read only register */ } READ8_HANDLER( s2637_paddle2_r ) { if (arcadia.adselect) { s2637->paddle2 = arcadia_paddle_y_r(1); } else { s2637->paddle2 = arcadia_paddle_x_r(1); } #if PAD_DEBUG LOG((3,"S2637","adselect:%d paddle2:%02x\n", arcadia.adselect, s2637->paddle2)); #endif return s2637->paddle2; } /*********** 1ff * bit(s) function * ----------------------------------------------- * 7-0 paddle 1 position * ----------------------------------------------- * Range 00 - fe, ff during VRST * paddle1 x or y *************************************************/ WRITE8_HANDLER( s2637_paddle1_w ) { /* read only register */ } READ8_HANDLER( s2637_paddle1_r ) { if (arcadia.adselect) { s2637->paddle1 = arcadia_paddle_y_r(0); } else { s2637->paddle1 = arcadia_paddle_x_r(0); } #if PAD_DEBUG LOG((3,"S2637","adselect:%d paddle1:%02x\n", arcadia.adselect, s2637->paddle1)); #endif return s2637->paddle1; } /*********** 200 - 2cf * bit(s) function * ----------------------------------------------- * 7,6 color * 5-0 character code * ----------------------------------------------- * 13 lines with 16 characters each *************************************************/ WRITE8_HANDLER( s2637_video2_w ) { s2637->video2[offset] = data; } READ8_HANDLER( s2637_video2_r ) { return s2637->video2[offset]; } /*********** 2d0 - 2ff * 48 bytes of user RAM *************************************************/ WRITE8_HANDLER( s2637_ram3_w ) { s2637->ram3[offset] = data; } READ8_HANDLER( s2637_ram3_r ) { return s2637->ram3[offset]; } READ8_HANDLER( s2637_sense_r ) { return cpu_getvblank() ? 0x80 : 0x00; } static void combine(int x, int y) { if (x < charmap->xmin) charmap->xmin = x; if (x > charmap->xmax) charmap->xmax = x; if (y < charmap->ymin) charmap->ymin = y; if (y > charmap->ymax) charmap->ymax = y; } static void sprite_dirty(int n) { int x, y, w, h; x = arcadia.spritex[n]; if (x <= - 8 || x >= TOTALCOLS * 8) return; y = arcadia.spritey[n] - FIRSTVROW; w = 8; h = arcadia.spriteh[n]; x *= charmap->xscale; y *= charmap->yscale; w *= charmap->xscale; h *= charmap->yscale; combine(x, y); combine(x + w - 1, y); combine(x, y + h - 1); combine(x + w - 1, y + h - 1); } INLINE void sprite_draw(osd_bitmap_t *bitmap, int n) { int i, x, y, w, h; u32 pix; x = arcadia.spritex[n]; if (x <= - 8 || x >= TOTALCOLS * 8) return; y = arcadia.spritey[n] - FIRSTVROW; w = 8; h = arcadia.spriteh[n] / 8; pix = palette[arcadia.spritec[n]]; for (i = 0; i < 8; i++) { u8 data = chargen[(0x38 + n) * 8 + i]; if (data & 0x80) osd_fillrect(bitmap, x+0, y+i*h, 1, h, pix); if (data & 0x40) osd_fillrect(bitmap, x+1, y+i*h, 1, h, pix); if (data & 0x20) osd_fillrect(bitmap, x+2, y+i*h, 1, h, pix); if (data & 0x10) osd_fillrect(bitmap, x+3, y+i*h, 1, h, pix); if (data & 0x08) osd_fillrect(bitmap, x+4, y+i*h, 1, h, pix); if (data & 0x04) osd_fillrect(bitmap, x+5, y+i*h, 1, h, pix); if (data & 0x02) osd_fillrect(bitmap, x+6, y+i*h, 1, h, pix); if (data & 0x01) osd_fillrect(bitmap, x+7, y+i*h, 1, h, pix); } } INLINE void sprite_background(u8 coll, int n, int y) { int x1, y1, h1, x2, y2, r1, r2, row, col, code, mask1, mask2; if (0 == (arcadia.bgcoll & coll)) return; x1 = arcadia.spritex[n]; y1 = arcadia.spritey[n]; h1 = arcadia.spriteh[n]; r1 = y - y1; if (h1 > 8) r1 /= 2; mask1 = chargen[(0x38+n) * 8 + r1] << (16 - (x1 & 7)); y2 = y - arcadia.skew; /* above first or below last scanline? */ if (y2 < 0 || y2 >= TOTALROWS * 8) return; if (arcadia.resolution) { /* single scan */ row = y2 / 8; r2 = y2 - row * 8; } else { /* double scan */ row = y2 / 16; r2 = (y2 - row * 16) / 2; } x2 = arcadia.pixpan[y]; /* left off first or right off last pixel column? */ if (x1 < x2 + FIRSTVCOL * 8 - 7 || x1 >= x2 + LASTVCOL * 8) return; col = x1 / 8 - FIRSTVCOL; if (col < 0) { /* first character is empty */ code = arcadia.screen[row * 16 + col + 1] & 0x7f; mask2 = chargen[code * 8 + r2] << 8; } else if (col >= CHARCOLS - 1) { /* second character is empty */ code = arcadia.screen[row * 16 + col + 0] & 0x7f; mask2 = chargen[code * 8 + r2] << 16; } else { /* sprite covers two characters */ code = arcadia.screen[row * 16 + col + 0] & 0x7f; mask2 = chargen[code * 8 + r2] << 16; code = arcadia.screen[row * 16 + col + 1] & 0x7f; mask2 |= chargen[code * 8 + r2] << 8; } mask2 = mask2 >> (x2 & 7); if (mask1 & mask2) { #if SPR_DEBUG LOG((3,"S2637","BG collision n:%d x2:%3d y2:%3d row:%2d r2:%d\n%s\n%s\n", n, x2, y2, row, r2, binary(mask1), binary(mask2))); #endif arcadia.bgcoll &= ~coll; } } INLINE void sprite_collisions(u8 coll, int s1, int s2, int y) { int x1, x2, y1, y2, h1, h2, r1, r2, mask1, mask2; if (0 == (arcadia.spcoll & coll)) return; if (y < arcadia.skew || y >= arcadia.skew + TOTALROWS * 8) return; x1 = arcadia.spritex[s1]; y1 = arcadia.spritey[s1]; h1 = arcadia.spriteh[s1]; x2 = arcadia.spritex[s2]; y2 = arcadia.spritey[s2]; h2 = arcadia.spriteh[s2]; if (x1 <= - 8 || x1 >= TOTALCOLS * 8) return; if (x2 <= - 8 || x2 >= TOTALCOLS * 8) return; if (y < y1) return; if (y < y2) return; if (y1 + h1 < y) return; if (y2 + h2 < y) return; if (x1 + 8 < x2) return; if (x1 > x2 + 8) return; r1 = y - y1; if (h1 > 8) r1 /= 2; r2 = y - y2; if (h2 > 8) r2 /= 2; mask1 = chargen[(0x38+s1) * 8 + r1] << (8 - (x1 % 8)); mask2 = chargen[(0x38+s2) * 8 + r2] << (8 - (x2 % 8)); if (mask1 & mask2) { #if SPR_DEBUG LOG((3,"S2637","SPR collision: %d+%d at %d,%d-%d / %d,%d-%d 0x%02x\n", s1, s2, x1, y1, h1, x2, y2, h2, coll)); #endif arcadia.spcoll &= ~coll; } } static void blank(osd_bitmap_t *bitmap, int x, int y, int w, int h, int color) { osd_fillrect(bitmap, x, y, w, h, palette[color]); } static void update(osd_bitmap_t *bitmap) { u32 pal2[2]; u32 row, col, x, y, h, scanline; u32 mode, data, code, color, bg; if (arcadia.dirtyall) { bg = arcadia.bgcolor[arcadia.mcolor[0]]; blank(bitmap, 0, 0, TOTALCOLS * 8, TOTALROWS * 8, bg); memset(arcadia.screen, -1, sizeof(arcadia.screen)); } y = arcadia.skew - FIRSTVROW; h = 0 == arcadia.resolution ? 16 : 8; for (row = 0; row < 13; row++, y += h) { scanline = FIRSTVROW + y; x = FIRSTVCOL * 8 + arcadia.pixpan[scanline]; mode = arcadia.graphics; if (arcadia.pixpan[scanline] != arcadia.oldpan[scanline]) { bg = arcadia.bgcolor[arcadia.mcolor[scanline]]; blank(bitmap, 0, y, FIRSTVCOL * 8 + 8, h, bg); blank(bitmap, LASTVCOL * 8, y, (TOTALCOLS - LASTVCOL) * 8, h, bg); memset(&arcadia.screen[row*16], -1, 16 * sizeof(arcadia.screen[0])); } for (col = 0; col < 16; col++, x += 8) { data = s2637->video1[row*16+col]; code = data & 0x3f; color = data & 0xc0; if (0 == code) { if (0x40 == color) mode = 0x00; else if (0xc0 == color) mode = 0x40; } code |= mode; if (code == arcadia.screen[row * 16 + col]) continue; arcadia.screen[row * 16 + col] = code; if (0 == arcadia.mcolor[scanline]) { pal2[0] = palette[arcadia.bgcolor[(color >> 7) & 1]]; pal2[1] = palette[arcadia.fgcolor[(color >> 6) & 1]]; osd_pattern(bitmap, font[arcadia.doublescan], x, y, code, 2, pal2, 8, 8); } else { pal2[0] = palette[arcadia.bgcolor[1]]; pal2[1] = palette[(color >> 5) | (arcadia.fgcolor[1] & 1)]; osd_pattern(bitmap, font[arcadia.doublescan], x, y, code, 2, pal2, 8, 8); } } } if (0 == arcadia.resolution) return; for (row = 13; row < 26; row++, y += h) { scanline = FIRSTVROW + y; x = FIRSTVCOL * 8 + arcadia.pixpan[scanline]; mode = arcadia.graphics; if (arcadia.pixpan[scanline] != arcadia.oldpan[scanline]) { bg = arcadia.bgcolor[arcadia.mcolor[scanline]]; blank(bitmap, 0, y, FIRSTVCOL * 8 + 8, h, bg); blank(bitmap, LASTVCOL * 8, y, (TOTALCOLS - LASTVCOL) * 8, h, bg); memset(&arcadia.screen[row*16], -1, 16 * sizeof(arcadia.screen[0])); } for (col = 0; col < 16; col++, x += 8) { data = s2637->video2[(row-13)*16+col]; code = data & 0x3f; color = data & 0xc0; if (0 == code) { if (0x40 == color) mode = 0x00; else if (0xc0 == color) mode = 0x40; } code |= mode; if (code == arcadia.screen[row * 16 + col]) continue; arcadia.screen[row * 16 + col] = code; if (0 == arcadia.mcolor[scanline]) { pal2[0] = palette[arcadia.bgcolor[(color >> 7) & 1]]; pal2[1] = palette[arcadia.fgcolor[(color >> 6) & 1]]; osd_pattern(bitmap, font[0], x, y, code, 2, pal2, 8, 8); } else { pal2[0] = palette[arcadia.bgcolor[1]]; pal2[1] = palette[(color >> 5) | (arcadia.fgcolor[1] & 1)]; osd_pattern(bitmap, font[0], x, y, code, 2, pal2, 8, 8); } } } } VIDEO_UPDATE( arcadia ) { u32 ch, i, offs; u8 pixpan, mcolor; arcadia.frame++; s2637->buttons = 0; s2637->bgcoll = arcadia.bgcoll; s2637->spcoll = arcadia.spcoll; /* render dirty characters */ for (i = 0; i < 8; i++) { ch = 0x38 + i; if (0 == memcmp(&chargen[ch*8], &s2637->chgen[i*8], 8)) continue; osd_render_font(font[0], &s2637->chgen[i*8], ch, 1, 8, 8, 1, 1, NULL); osd_render_font(font[1], &s2637->chgen[i*8], ch, 1, 8, 8, 1, 1, NULL); for (offs = 0; offs < CHARROWS * CHARCOLS; offs++) if (ch == (arcadia.screen[offs] & 0x3f)) arcadia.screen[offs] = -1; } pixpan = (s2637->volume >> 5) & 7; mcolor = ((s2637->pitch ^ 0x80) >> 7) & 1; for (i = 0; i < SCANLINES; i++) { if (0xff == arcadia.pixpan[i]) { arcadia.pixpan[i] = pixpan; } else { pixpan = arcadia.pixpan[i]; } if (0xff == arcadia.mcolor[i]) { arcadia.mcolor[i] = mcolor; } else { mcolor = arcadia.mcolor[i]; } } /* copy character generator data */ memcpy(&chargen[0x38*8], s2637->chgen, 8 * 8); /* update dirty characters */ update(charmap); osd_blit(bitmap, charmap, 0, 0, -1, -1, 0, 0); /* draw sprites in bitmap */ sprite_draw(bitmap, 0); sprite_draw(bitmap, 1); sprite_draw(bitmap, 2); sprite_draw(bitmap, 3); arcadia.dirtyall = 0; } VIDEO_EOF( arcadia ) { u32 y; arcadia.bgcoll = 0x0f; arcadia.spcoll = 0x3f; for (y = 0; y < arcadia.spriteh[0]; y++) { sprite_collisions(0x01, 0, 1, arcadia.spritey[0] + y); sprite_collisions(0x02, 0, 2, arcadia.spritey[0] + y); sprite_collisions(0x04, 0, 3, arcadia.spritey[0] + y); sprite_background(0x01, 0, arcadia.spritey[0] + y); } for (y = 0; y < arcadia.spriteh[1]; y++) { sprite_collisions(0x08, 1, 2, arcadia.spritey[1] + y); sprite_collisions(0x10, 1, 3, arcadia.spritey[1] + y); sprite_background(0x02, 1, arcadia.spritey[1] + y); } for (y = 0; y < arcadia.spriteh[2]; y++) { sprite_collisions(0x20, 2, 3, arcadia.spritey[2] + y); sprite_background(0x04, 2, arcadia.spritey[2] + y); } for (y = 0; y < arcadia.spriteh[3]; y++) { sprite_background(0x08, 3, arcadia.spritey[3] + y); } memcpy(arcadia.oldpan, arcadia.pixpan, SCANLINES); memset(arcadia.pixpan, 0xff, SCANLINES); } VIDEO_START( arcadia ) { u8 *rom = mem_region_base(REGION_CPU1); s2637 = (s2637_t *)&rom[0x1800]; memset(s2637, 0, sizeof(*s2637)); memset(s2637->unmapped, 0xff, sizeof(s2637->unmapped)); memset(&arcadia, 0, sizeof(arcadia)); arcadia.pixpan = malloc(SCANLINES + 8); if (NULL == arcadia.pixpan) return -1; arcadia.oldpan = malloc(SCANLINES + 8); if (NULL == arcadia.oldpan) return -1; arcadia.mcolor = malloc(SCANLINES + 8); if (NULL == arcadia.mcolor) return -1; arcadia.frame = 0; arcadia.charline = 15; arcadia.skew = 0; arcadia.adselect = 0; arcadia.doublescan = 0; arcadia.resolution = 1; arcadia.graphics = 0; memset(arcadia.pixpan, 0xff, SCANLINES); memset(arcadia.oldpan, 0xff, SCANLINES); memset(arcadia.mcolor, 0xff, SCANLINES); s2637->bgcoll = arcadia.bgcoll; s2637->spcoll = arcadia.spcoll; arcadia.bgcoll = 0x0f; arcadia.spcoll = 0x3f; vid_open_display(TOTALCOLS * 8, TOTALROWS * 8, "Arcadia"); charmap = vid_alloc_bitmap(TOTALCOLS * 8, TOTALROWS * 8, 32, 1, 1); font[0] = vid_alloc_bitmap(128 * 8, 8, 8, 1, 1); font[1] = vid_alloc_bitmap(128 * 8, 8, 8, 1, 2); osd_render_font(font[0], chargen, 0, 128, 8, 8, 1, 1, NULL); osd_render_font(font[1], chargen, 0, 128, 8, 8, 1, 1, NULL); return 0; } PALETTE_INIT( arcadia ) { int i; for (i = 0; i < 8; i++) { palette[i] = osd_color(NULL, (i & 2) ? 0x00 : 0xff, (i & 4) ? 0x00 : 0xff, (i & 1) ? 0x00 : 0xff); } }