/*************************************************************************** * __________ __ ___. * Open \______ \ ____ ____ | | _\_ |__ _______ ___ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * \/ \/ \/ \/ \/ * $Id$ * * Pacbox - a Pacman Emulator for Rockbox * * Based on PIE - Pacman Instructional Emulator * * Copyright (c) 1997-2003,2004 Alessandro Scotti * http://www.ascotti.org/ * * 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 software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * ****************************************************************************/ #include "plugin.h" #include "hardware.h" extern const struct plugin_api* rb; /* The main data for Pacman */ unsigned char ram_[20*1024] IBSS_ATTR; // ROM (16K) and RAM (4K) unsigned char charset_rom_[4*1024] IBSS_ATTR; // Character set ROM (4K) unsigned char spriteset_rom_[4*1024] IBSS_ATTR; // Sprite set ROM (4K) unsigned char dirty_[1024] IBSS_ATTR; unsigned char video_mem_[1024] IBSS_ATTR; // Video memory (1K) unsigned char color_mem_[1024] IBSS_ATTR; // Color memory (1K) unsigned char charmap_[256*8*8] IBSS_ATTR; /* Character data for 256 8x8 characters */ unsigned char spritemap_[64*16*16]; /* Sprite data for 64 16x16 sprites */ unsigned char output_devices_ IBSS_ATTR; /* Output flip-flops set by the game program */ unsigned char interrupt_vector_ IBSS_ATTR; unsigned coin_counter_ IBSS_ATTR; unsigned char port1_ IBSS_ATTR; unsigned char port2_ IBSS_ATTR; unsigned char dip_switches_ IBSS_ATTR; /* Internal tables and structures for faster access to data */ struct PacmanSprite sprites_[8]; /* Sprites */ short vchar_to_i_[1024]; /* For Z80 Environment: write a byte to memory. */ void writeByte( unsigned addr, unsigned char b ) { addr &= 0x7FFF; if( addr < 0x4000 ) { // This is a ROM address, do not write into it! } else if( addr < 0x4400 ) { // Video memory if (ram_[addr] != b) { int x = vchar_to_i_[addr-0x4000]; ram_[addr] = b; dirty_[x] = 1; video_mem_[x] = b; } } else if( addr < 0x4800 ) { // Color memory if (ram_[addr] != b) { int x = vchar_to_i_[addr-0x4400]; ram_[addr] = b; dirty_[x] = 1; color_mem_[x] = b; } } else if( addr < 0x4FF0 ) { // Standard memory ram_[addr] = b; } else if( addr < 0x5000 ) { // Sprites ram_[addr] = b; unsigned idx = (addr - 0x4FF0) / 2; if( addr & 1 ) { sprites_[ idx ].color = b; } else { sprites_[ idx ].n = b >> 2; sprites_[ idx ].mode = b & 0x03; } } else { // Memory mapped ports switch( addr ) { case 0x5000: // Interrupt enable setOutputFlipFlop( InterruptEnabled, b & 0x01 ); break; case 0x5001: // Sound enable setOutputFlipFlop( SoundEnabled, b & 0x01 ); break; case 0x5002: // Aux board enable? break; case 0x5003: // Flip screen setOutputFlipFlop( FlipScreen, b & 0x01 ); break; case 0x5004: // Player 1 start light setOutputFlipFlop( PlayerOneLight, b & 0x01 ); break; case 0x5005: // Player 2 start light setOutputFlipFlop( PlayerTwoLight, b & 0x01 ); break; case 0x5006: // Coin lockout: bit 0 is used to enable/disable the coin insert slots // (0=disable). // The coin slot is enabled at startup and (temporarily) disabled when // the maximum number of credits (99) is inserted. setOutputFlipFlop( CoinLockout, b & 0x01 ); break; case 0x5007: // Coin meter (coin counter incremented on 0/1 edge) if( (output_devices_ & CoinMeter) == 0 && (b & 0x01) != 0 ) coin_counter_++; setOutputFlipFlop( CoinMeter, b & 0x01 ); break; case 0x50c0: // Watchdog reset break; default: if( addr >= 0x5040 && addr < 0x5060 ) { // Sound registers //SOUND sound_chip_.setRegister( addr-0x5040, b ); } else if( addr >= 0x5060 && addr < 0x5070 ) { // Sprite coordinates, x/y pairs for 8 sprites unsigned idx = (addr-0x5060) / 2; if( addr & 1 ) { sprites_[ idx ].y = 272 - b + 1; } else { sprites_[ idx ].x = 240 - b - 1; if( idx <= 2 ) { // In Pacman the first few sprites must be further offset // to the left to get a correct display (is this a hack?) sprites_[ idx ].x -= 1; } } } break; } } } /* For Z80 Environment: read from a port. Note: all ports in Pacman are memory mapped so they are read with readByte(). */ unsigned char readPort( unsigned port ) { (void)port; return 0; } /* For Z80 Environment: write to a port. */ void writePort( unsigned addr, unsigned char b ) { if( addr == 0 ) { // Sets the interrupt vector for the next CPU interrupt interrupt_vector_ = b; } } void setOutputFlipFlop( unsigned char bit, unsigned char value ) { if( value ) { output_devices_ |= bit; } else { output_devices_ &= ~bit; } }