?? gamectrl.c
字號:
/* Copyright 1998, ESS Technology, Inc. */
/* SCCSID @(#)gamectrl.c 1.15 12/3/98 */
/*
* This is based on version 1.307 of top.c
* Also merged in contents from dsc.c, int.c, ir.c, ngame.c and util.c
*/
#define MAIN
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include "mvd.h"
#include "common.h"
#include "util.h"
#include "debug.h"
#include "ioport.h"
#include "ir.h"
#include "constvar.h"
#include "timedef.h"
#include "const.h"
#include "keydef.h"
#ifdef DSC
#include "dsc.h"
#endif
/* Use these absolue address to pass parameters between VCD code and game */
#define GAME_TYPE 0x8020
#define GAME_PARAMETER 0x8024
#define GAME_ECHO 0x8028
/***************************************************************************
* Variables local to this module.
***************************************************************************/
unsigned long vcx_romdatastart = 0;
int which_game;
int Jump_addr;
unsigned int save_buscon_dma_scale_type;
/* Dummy variables to foo compiler */
int VCD_30;
int track_list;
ushort *hex2bcd;
/* Dummy functions to foo compiler */
int preprocess_digit_key(int num, int *ignore_key, int ten_key);
void preprocess_function_key(int key);
int vcd30_key_preprocess(int);
#ifdef NGAME_PARALLEL_PORT
unsigned int mirror;
void NGAME_control(int, unsigned char);
#else
unsigned int mirror_mapper;
void NGAME_control(unsigned short);
#endif
/***************************************************************************
Various defines.
***************************************************************************/
#define RUN_REAL_GAME 0x0
#define RUN_RAM_CLEAR 0x1
#define RUN_BIG_GAME 0x2
#ifdef NGAME_PARALLEL_PORT
#define NGAME_DOWNLOAD 0x03 /* Download, VCD, reset */
#define NGAME_RUNGAME 0x04 /* RunGame, game, run */
#define NGAME_RESET 0x05 /* RunGame, game, reset */
#define NGAME_RUNPROGRAM 0x06 /* RunGame, VCD, run */
#define NGAME_OFFSET_0 0x00 /* where we put game code */
#define NGAME_OFFSET_1 0x04 /* where we put game code */
#define NGAME_OFFSET_2 0x08 /* where we put game code */
#define NGAME_OFFSET_3 0x0c /* where we put game code */
#define VCD_VIDEO_OUT 0x10
#else
#define RESET_GAME 0x0000
#define RUN_GAME 0x8000
#define OFFSET_0 0x0000
#define OFFSET_1 0x2000
#define OFFSET_2 0x4000
#define OFFSET_3 0x6000
#define VCD_VIDEO 0x0100
#define GAME_VIDEO 0x0000
#endif /* NGAME_PARALLEL_PORT */
#ifdef NGAME_PARALLEL_PORT
#define SWITCH_VIDEO_TO_GAME CLEAR_EAUX8
#define SWITCH_VIDEO_TO_VCD SET_EAUX8
#else
#define SWITCH_VIDEO_TO_GAME
#define SWITCH_VIDEO_TO_VCD
#endif
/***************************************************************************
Debugging.
***************************************************************************/
#define PRINTF(a)
/***************************************************************************
Imported variables
***************************************************************************/
/***************************************************************************
Local function prototypes.
***************************************************************************/
static void initialization(void);
static void install_interrupt_vectors(void);
static int *mem_shrink(int *, int*, int, int, int);
static int *mem_expand(int *, int*, int, int, int);
/* Dummy functions to link with microvfd.o */
int preprocess_digit_key(int num, int *ignore_key, int ten_key)
{
}
void preprocess_function_key(int key)
{
}
int vcd30_key_preprocess(int x)
{
}
/***************************************************************************
All low level initialisation.
***************************************************************************/
static void initialization()
{
mvd[riface_irqmask] = 0xc000; /* disable irqs */
install_interrupt_vectors();
RISC_start_timer2();
#ifdef IR
IR_init();
#endif
#ifdef NGAME
/* Tristate BUSCON DMA bus before going to game */
save_buscon_dma_scale_type = mvd[buscon_dma_scale_type];
mvd[buscon_dma_scale_type] = save_buscon_dma_scale_type | 0x80;
/* Disable all BUSCON DMA */
mvd[buscon_dma_disable] = 0x3fffff;
if (which_game != RUN_RAM_CLEAR) {
int offset;
if (which_game == RUN_REAL_GAME)
offset = OFFSET_3;
else
offset = OFFSET_0; /* For big game(256K) */
/* Run real game and switch Video output */
#ifdef NGAME_PARALLEL_PORT
NGAME_control(0, NGAME_RUNGAME | mirror);
#else
NGAME_control(RUN_GAME | offset | GAME_VIDEO | (mirror_mapper << 9));
#endif
SWITCH_VIDEO_TO_GAME;
}
else {
/* Run NGAME_ram_clear() only, do NOT switch video */
#ifdef NGAME_PARALLEL_PORT
NGAME_control(0, NGAME_RUNGAME | VCD_VIDEO_OUT);
#else
NGAME_control(RUN_GAME | OFFSET_3 | VCD_VIDEO);
#endif
}
#endif
}
/***************************************************************************
The main entry point.
***************************************************************************/
main()
{
int echo_on;
/* ******** RISC and register setups ******** */
register int psw_shadow = 0xc3;
asm volatile("movtos %0,psw" : :"r" (psw_shadow) );
mvd = (int *)OMNI_BASE;
vcx_romdatastart += 0x60; /* 6 commands occupy 0x60B */
hex2bcd = T_hex2bcd;
running_game = 1;
#ifdef MKROM
/* Chip version detected in startup.s; 0xc3 at 0 means 3210 */
mvd_version = (*((int *)(dram(0))) == 0xc3) ? 0x3210 : 0x3208;
#endif
#ifdef DSC
DSC_getstatus();
#endif
which_game = *(int *)GAME_TYPE;
echo_on = *(int *)GAME_ECHO;
#ifdef NGAME_PARALLEL_PORT
mirror = *(unsigned int *)GAME_PARAMETER;
#else
mirror_mapper = *(unsigned int *)GAME_PARAMETER;
#endif
if (which_game == RUN_BIG_GAME) {
/* Save VCD data, stack, buffers to even bytes - *
* - check with memmory map to see what needs to be saved */
mem_expand((int *)0x10000000, (int *)0x10014000, 0x2400/4, 1, 1);
mem_expand((int *)0x1000f400, (int *)0x10018800, 0x4400/4, 1, 1);
/* Expand game data to odd bytes -- *
* since game data is from 0x10030000 to 0x1006fffc, so *
* we have to expand in two times to avoid overwriting */
mem_expand((int *)0x10030000, (int *)0x10000000, 0x30000/4, 1, 0);
mem_expand((int *)0x1006fffc, (int *)0x1007fffc, 0x10000/4, 0, 0);
}
initialization();
#if (DSC && ECHO_ANALOG_BYPASS)
/* Enable analog bypass if it is not enabled yet*/
if ((echo_on == -1) && (which_game != RUN_RAM_CLEAR)) {
unsigned int adc2 = 0x20;
unsigned int shadow_audioxmt1 = 0x69;
adc2 |= 0x8;
DSC_cmd(dsc_audioadc2, adc2);
shadow_audioxmt1 &= 0xbf; /* Disable zero_mute */
DSC_cmd(dsc_audioxmt1, shadow_audioxmt1);
}
#endif
DBG_allocate_trace_buffer();
initMicroObject();
while (1) {
static int timer;
int timeout = 0, i, tmp, key;
/* Since there is no video interrupt, we have to *
* simulate updating glbTimer 50-60 times per second */
timer ++;
if (timer == 200) {
timer = 0;
glbTimer ++;
}
microEngine();
tmp = get_keycode();
if (tmp != -1)
key = tmp & 0xff;
if (which_game == RUN_RAM_CLEAR) {
/* Wait for it to finish */
for (i = 0; i < 2000000; i++) ;
timeout = 1;
}
if (key == STOP_KEY || key == POWER_KEY || timeout) {
#ifdef NGAME_PARALLEL_PORT
NGAME_control(0, NGAME_DOWNLOAD);
#else
NGAME_control(RESET_GAME | VCD_VIDEO);
#endif
/* Reenable BUSCON DMA bus after game is done */
mvd[buscon_dma_scale_type] = save_buscon_dma_scale_type & (~0x80);
/* Enable all BUSCON DMA */
mvd[buscon_dma_disable] = 0;
if (which_game == RUN_BIG_GAME) {
/* Restore VCD data, stack, buffer from even bytes */
mem_shrink((int *)0x10014000, (int *)0x10000000,
0x2400/4*2, 1, 1);
mem_shrink((int *)0x10018800, (int *)0x1000f400,
0x4400/4*2, 1, 1);
}
if (key == POWER_KEY)
*(int *)GAME_PARAMETER = 1; /* Tell VCD to power off */
else
*(int *)GAME_PARAMETER = 0;
#if (DSC && ECHO_ANALOG_BYPASS)
/* Disable analog bypass if we didn't turn it on in VCD mode */
if ((echo_on == -1) && (which_game != RUN_RAM_CLEAR)) {
unsigned int shadow_audioxmt1 = 0x69;
DSC_cmd(dsc_audioadc2, 0x0); /* cause soft reset adc */
shadow_audioxmt1 |= 0x40; /* Enable zero_mute */
DSC_cmd(dsc_audioxmt1, shadow_audioxmt1);
}
#endif
SWITCH_VIDEO_TO_VCD;
asm("ld _Jump_addr[r25],r2");
asm("jspci r2,#0,r0");
asm("nop");
asm("nop");
}
#ifdef VCD
VCX_service();
#endif
}
}
/***************************************************************************
Misc interrupt handling.
***************************************************************************/
extern void trap0;
static int *trapptr0 = &trap0;
static void install_interrupt_vectors()
{
int *a, *b, i;
#ifdef MKROM
b = (int*)((int)trapptr0<<2);
#else
b = (int*)((int)trapptr0);
#endif
/*
* The DWORD at 0x18 is used for resume!!
* The DWORD at 0x1c is used for real-time clock!!
*
* Don't read 0x10 to 0x1f, they meant to be noncachable.
*/
for (a = (int*)0, i = 0; i < 4; i++) *a++ = *b++;
}
/**************** This part is from version 1.63 of util.c ******************/
/*
* Remote control depends on timer to get signal width. For convenience,
* we need the least significant 20 bits of starting timer value to be
* all 0's. Therefore, INTERVAL and multiplication factors are both
* set to 1024 instead of 1000.
*/
#define INTERVAL 500 /* In msec (i.e. timer will be .5 sec) */
/************************************************************************
Timer2 interrupt service.
************************************************************************/
void RISC_timer2_interrupt_service(void)
{
mvd[riface_clear_timer2] = 0; /* clear timer irq */
/* Timer reloaded automatically */
#ifdef DSC
DSC_toggle(); /* Tell 3207 that we are not dead! */
#endif
}
/**************************************************************************
Start timer2.
**************************************************************************/
void RISC_start_timer2(void)
{
timer2_period = 0x0 - (INTERVAL * CPUCLK * 100);
mvd[riface_clear_timer2] = 0; /* clear timer irq */
mvd[riface_timer2] = timer2_period;
enable_int(tim2);
}
/**************** This part is from version 1.5 of ngame.c ******************/
/*
* Use this routine to control the game module
*
* Input
* port: 0 is for CTL0 (i.e. admin stuff)
* 1 is for CTL1 (i.e. remote control input)
*
* data: Data to be sent.
*/
#ifdef NGAME_PARALLEL_PORT
void NGAME_control(port, data)
int port;
unsigned char data;
{
register volatile unsigned char * ctlptr;
ctlptr = (unsigned char *) x18000000;
ctlptr += port;
*ctlptr = data;
}
#else
void NGAME_control(data)
unsigned short data;
{
register volatile unsigned char * ctlptr;
int i;
ctlptr = (unsigned char *) x18000000;
*ctlptr ++ = 0;
for (i = 0; i < 16; i++) {
*ctlptr = data;
data >>= 1;
}
}
#endif
/***************** This part is from version 1.86 of dsc.c *****************/
/************************************************************************
* Local defines. *
************************************************************************/
#ifdef DVD_VCD
#define DSC_SELECT SET_AUX0
#define DSC_DESELECT CLEAR_AUX0
#else
#define DSC_SELECT SET_AUX5
#define DSC_DESELECT CLEAR_AUX5
#endif
/************************************************************************
* Following defines are valid for 3207VA or later chips. *
************************************************************************/
#ifdef DSC_DITHER
#define AUDIORCV1_DITHER 0x4
#else
#define AUDIORCV1_DITHER 0
#endif
#ifdef DSC_FLIP_VPOWER
#define DVECTL3_VIDEO_OFF 1
#define DVECTL3_VIDEO_ON 0
#else
#define DVECTL3_VIDEO_OFF 0
#define DVECTL3_VIDEO_ON 1
#endif
#ifdef DSC_MUTE_ZERO
#define AUDIOXMT1_MUTE_ZERO 0x40
#else
#define AUDIOXMT1_MUTE_ZERO 0
#endif
#ifdef DSC_ANALOG_PLL
#define AUDIOACNT0H_ANALOG_PLL 0x90
#else
#define AUDIOACNT0H_ANALOG_PLL 0
#endif
#ifdef DSC_DETECT_CENTER
#define AUDIOADC2_DETECT 0
#else
#define AUDIOADC2_DETECT 0x40
#endif
/************************************************************************
* Variables used in this module only. *
************************************************************************/
PRIVATE unsigned int shadow_eaux0_dat; /* Shadow for dsc_aux0_dat */
PRIVATE unsigned int shadow_eaux1_dat; /* Shadow for dsc_aux1_dat */
PRIVATE unsigned int shadow_eaux0_ctl; /* Shadow for dsc_aux0_ctl */
PRIVATE unsigned int shadow_eaux1_ctl; /* Shadow for dsc_aux1_ctl */
PRIVATE unsigned int shadow_cchip_ctl; /* Shadow for dsc_cchip_ctl*/
#ifdef DSC_IRQ
PRIVATE unsigned int shadow_irq_ctl; /* Shadow for dsc_irq_ctl */
PRIVATE unsigned int shadow_aux_mode; /* Shadow for dsc_aux_mode */
#endif
/*
* This routine has to be called before all DSC routine.
*
* This routine will set DSC select. Then it will only be toggled in
* timer interrupt.
*/
void DSC_getstatus()
{
DSC_toggle();
DSC_status = DSC_STATUS_RUNNING;
DSC_cmd(dsc_watchdog, 0xf2);
}
/*
* Toggle DSC_S (a convention to tell 3207 that 3210 is still alive, so
* it will not be reset accidentally.)
*
* We can't toggle DSC_S in the middle of communication, and this
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -