www.pudn.com > raine.rar > starhelp.c


/******************************************************************************/
/*                                                                            */
/*                     RAINE - STARSCREAM 68000 INTERFACE                     */
/*                                                                            */
/******************************************************************************/

#include "starhelp.h"
#include "raine.h"
#include "debug.h"
#include "savegame.h"

/*
 *  Fill in the basic structures via these functions...
 */

// FIRST EMULATED 68000

static UINT32 ma;

static UINT32 program_count[MAX_68000];
static UINT32 data_count_rb[MAX_68000];
static UINT32 data_count_rw[MAX_68000];
static UINT32 data_count_wb[MAX_68000];
static UINT32 data_count_ww[MAX_68000];

void AddMemoryList(UINT32 d0, UINT32 d1, void *d2, UINT8 *d3)
{
   MC68000A_memoryall[ma].lowaddr    = d0;
   MC68000A_memoryall[ma].highaddr   = d1;
   MC68000A_memoryall[ma].memorycall = d2;
   MC68000A_memoryall[ma].userdata   = d3;
   ma++;
}

static void add_s68000_program_region(UINT32 cpu, UINT32 d0, UINT32 d1, UINT8 *d2)
{
   M68000_programregion[cpu][program_count[cpu]].lowaddr  = d0;
   M68000_programregion[cpu][program_count[cpu]].highaddr = d1;
   M68000_programregion[cpu][program_count[cpu]].offset   = (UINT32) d2;
   program_count[cpu]++;

   if(cpu == 0)
      ma = 0;
}

static void add_s68000_data_region_rb(UINT32 cpu, UINT32 d0, UINT32 d1, void *d2, UINT8 *d3)
{
   M68000_dataregion_rb[cpu][data_count_rb[cpu]].lowaddr    = d0;
   M68000_dataregion_rb[cpu][data_count_rb[cpu]].highaddr   = d1;
   M68000_dataregion_rb[cpu][data_count_rb[cpu]].memorycall = d2;
   M68000_dataregion_rb[cpu][data_count_rb[cpu]].userdata   = d3 - d0;
   data_count_rb[cpu]++;

   if(cpu == 0)
      AddMemoryList(d0,d1,d2,d3);
}

static void add_s68000_data_region_rw(UINT32 cpu, UINT32 d0, UINT32 d1, void *d2, UINT8 *d3)
{
   M68000_dataregion_rw[cpu][data_count_rw[cpu]].lowaddr    = d0;
   M68000_dataregion_rw[cpu][data_count_rw[cpu]].highaddr   = d1;
   M68000_dataregion_rw[cpu][data_count_rw[cpu]].memorycall = d2;
   M68000_dataregion_rw[cpu][data_count_rw[cpu]].userdata   = d3 - d0;
   data_count_rw[cpu]++;

   if(cpu == 0)
      AddMemoryList(d0,d1,d2,d3);
}

static void add_s68000_data_region_wb(UINT32 cpu, UINT32 d0, UINT32 d1, void *d2, UINT8 *d3)
{
   M68000_dataregion_wb[cpu][data_count_wb[cpu]].lowaddr    = d0;
   M68000_dataregion_wb[cpu][data_count_wb[cpu]].highaddr   = d1;
   M68000_dataregion_wb[cpu][data_count_wb[cpu]].memorycall = d2;
   M68000_dataregion_wb[cpu][data_count_wb[cpu]].userdata   = d3 - d0;
   data_count_wb[cpu]++;

   if(cpu == 0)
      AddMemoryList(d0,d1,d2,d3);
}

static void add_s68000_data_region_ww(UINT32 cpu, UINT32 d0, UINT32 d1, void *d2, UINT8 *d3)
{
   M68000_dataregion_ww[cpu][data_count_ww[cpu]].lowaddr    = d0;
   M68000_dataregion_ww[cpu][data_count_ww[cpu]].highaddr   = d1;
   M68000_dataregion_ww[cpu][data_count_ww[cpu]].memorycall = d2;
   M68000_dataregion_ww[cpu][data_count_ww[cpu]].userdata   = d3 - d0;
   data_count_ww[cpu]++;

   if(cpu == 0)
      AddMemoryList(d0,d1,d2,d3);
}

void AddMemFetch(UINT32 d0, UINT32 d1, UINT8 *d2)
{
   add_s68000_program_region(0, d0, d1, d2);
}

void AddReadByte(UINT32 d0, UINT32 d1, void *d2, UINT8 *d3)
{
   add_s68000_data_region_rb(0, d0, d1, d2, d3);
}

void AddReadWord(UINT32 d0, UINT32 d1, void *d2, UINT8 *d3)
{
   add_s68000_data_region_rw(0, d0, d1, d2, d3);
}

void AddReadBW (UINT32 d0, UINT32 d1, void *d2, UINT8 *d3) {
   add_s68000_data_region_rb(0, d0, d1, d2, d3);
   add_s68000_data_region_rw(0, d0, d1, d2, d3);
}  


void AddWriteByte(UINT32 d0, UINT32 d1, void *d2, UINT8 *d3)
{
   add_s68000_data_region_wb(0, d0, d1, d2, d3);
}

void AddWriteWord(UINT32 d0, UINT32 d1, void *d2, UINT8 *d3)
{
   add_s68000_data_region_ww(0, d0, d1, d2, d3);
}

void AddWriteBW(UINT32 d0, UINT32 d1, void *d2, UINT8 *d3)
{
   add_s68000_data_region_wb(0, d0, d1, d2, d3);
   add_s68000_data_region_ww(0, d0, d1, d2, d3);
}

void AddRWBW (UINT32 d0, UINT32 d1, void *d2, UINT8 *d3)
{
   add_s68000_data_region_rb(0, d0, d1, d2, d3);
   add_s68000_data_region_rw(0, d0, d1, d2, d3);
   add_s68000_data_region_wb(0, d0, d1, d2, d3);
   add_s68000_data_region_ww(0, d0, d1, d2, d3);
}  

void AddResetHandler(void *d0)
{
   M68000_resethandler[0] = d0;
}

/*

darn, neill moves things around in the context, so it's not
safe to save starscream contexts incase they change in future
releases, have to 'pack' them into our own save buffer then.

*/

typedef struct SAVE_BUFFER
{
   UINT32 id;
   UINT32 interrupts[8];
   UINT32 dreg[8];
   UINT32 areg[8];
   UINT32 asp;
   UINT32 pc;
   UINT32 odometer;
   UINT16 sr;
   UINT8 stopped;
} SAVE_BUFFER;

static struct SAVE_BUFFER save_buffer[2];

void AddInitMemory(void)
{
   M68000_context[0].fetch       = M68000_programregion[0];
   M68000_context[0].readbyte    = M68000_dataregion_rb[0];
   M68000_context[0].readword    = M68000_dataregion_rw[0];
   M68000_context[0].writebyte   = M68000_dataregion_wb[0];
   M68000_context[0].writeword   = M68000_dataregion_ww[0];
   M68000_context[0].s_fetch     = M68000_programregion[0];
   M68000_context[0].s_readbyte  = M68000_dataregion_rb[0];
   M68000_context[0].s_readword  = M68000_dataregion_rw[0];
   M68000_context[0].s_writebyte = M68000_dataregion_wb[0];
   M68000_context[0].s_writeword = M68000_dataregion_ww[0];
   M68000_context[0].u_fetch     = M68000_programregion[0];
   M68000_context[0].u_readbyte  = M68000_dataregion_rb[0];
   M68000_context[0].u_readword  = M68000_dataregion_rw[0];
   M68000_context[0].u_writebyte = M68000_dataregion_wb[0];
   M68000_context[0].u_writeword = M68000_dataregion_ww[0];
   M68000_context[0].resethandler = M68000_resethandler[0];
   M68000_context[0].sr = 0x2700;

   AddSaveCallback_Internal(M68000A_save_update);
   AddLoadCallback_Internal(M68000A_load_update);
   AddSaveData(SAVE_68K_0, (UINT8 *) &save_buffer[0], sizeof(SAVE_BUFFER));

   StarScreamEngine = 1;
}

void Clear68000List(void)
{
   UINT32 ta;

   for(ta = 0; ta < MAX_68000; ta ++){
      program_count[ta] = 0;
      data_count_rb[ta] = 0;
      data_count_rw[ta] = 0;
      data_count_wb[ta] = 0;
      data_count_ww[ta] = 0;
      M68000_resethandler[ta] = NULL;
   }

   ma = 0;
}

void WriteStarScreamByte(UINT32 address, UINT8 data)
{
   int ta;

   for(ta=0;(UINT32)ta=MC68000A_memoryall[ta].lowaddr)&&(MC68000A_memoryall[ta].highaddr>=address)){
            if(MC68000A_memoryall[ta].memorycall==NULL){
               WriteByte( ((UINT8 *) MC68000A_memoryall[ta].userdata) + ((address^1)-MC68000A_memoryall[ta].lowaddr),data);
               ta=ma;
            }
            //else{
            //   *MC68000A_memoryall[ta].memorycall(address,data);
            //}
         }
      }
   }
}

UINT8 ReadStarScreamByte(UINT32 address)
{
   int ta;

   for(ta=0;(UINT32)ta=MC68000A_memoryall[ta].lowaddr)&&(MC68000A_memoryall[ta].highaddr>=address)){
            if(MC68000A_memoryall[ta].memorycall==NULL){
               return ReadByte( ((UINT8 *) MC68000A_memoryall[ta].userdata) + ((address^1)-MC68000A_memoryall[ta].lowaddr) );
            }
         }
      }
   }

   return 0x00;
}

// SECOND EMULATED 68000

void AddMemFetchMC68000B(UINT32 d0, UINT32 d1, UINT8 *d2)
{
   add_s68000_program_region(1, d0, d1, d2);
}

void AddReadByteMC68000B(UINT32 d0, UINT32 d1, void *d2, UINT8 *d3)
{
   add_s68000_data_region_rb(1, d0, d1, d2, d3);
}

void AddReadWordMC68000B(UINT32 d0, UINT32 d1, void *d2, UINT8 *d3)
{
   add_s68000_data_region_rw(1, d0, d1, d2, d3);
}

void AddWriteByteMC68000B(UINT32 d0, UINT32 d1, void *d2, UINT8 *d3)
{
   add_s68000_data_region_wb(1, d0, d1, d2, d3);
}

void AddWriteWordMC68000B(UINT32 d0, UINT32 d1, void *d2, UINT8 *d3)
{
   add_s68000_data_region_ww(1, d0, d1, d2, d3);
}

void AddInitMemoryMC68000B(void)
{
   M68000_context[1].fetch       = M68000_programregion[1];
   M68000_context[1].readbyte    = M68000_dataregion_rb[1];
   M68000_context[1].readword    = M68000_dataregion_rw[1];
   M68000_context[1].writebyte   = M68000_dataregion_wb[1];
   M68000_context[1].writeword   = M68000_dataregion_ww[1];
   M68000_context[1].s_fetch     = M68000_programregion[1];
   M68000_context[1].s_readbyte  = M68000_dataregion_rb[1];
   M68000_context[1].s_readword  = M68000_dataregion_rw[1];
   M68000_context[1].s_writebyte = M68000_dataregion_wb[1];
   M68000_context[1].s_writeword = M68000_dataregion_ww[1];
   M68000_context[1].u_fetch     = M68000_programregion[1];
   M68000_context[1].u_readbyte  = M68000_dataregion_rb[1];
   M68000_context[1].u_readword  = M68000_dataregion_rw[1];
   M68000_context[1].u_writebyte = M68000_dataregion_wb[1];
   M68000_context[1].u_writeword = M68000_dataregion_ww[1];
   M68000_context[1].resethandler = M68000_resethandler[1];
   M68000_context[1].sr = 0x2700;

   AddSaveCallback_Internal(M68000B_save_update);
   AddLoadCallback_Internal(M68000B_load_update);
   AddSaveData(SAVE_68K_1, (UINT8 *) &save_buffer[1], sizeof(SAVE_BUFFER));

   StarScreamEngine = 2;
}

/*
 *  Helper Functions for Starscream memory read/write structs
 *  ---------------------------------------------------------
 */

void Stop68000(UINT32 address, UINT8 data)
{
	(void)(address);
	(void)(data);
   s68000releaseTimeslice();
   #ifdef RAINE_DEBUG
   print_debug("[Stop68000]\n");
   #endif
}

UINT8 DefBadReadByte(UINT32 address)
{
   #ifdef RAINE_DEBUG
      print_debug("RB(%06x) [%06x]\n",address,s68000readPC());
   #endif
   return 0xFF;
}

UINT16 DefBadReadWord(UINT32 address)
{
   #ifdef RAINE_DEBUG
       print_debug("RW(%06x) [%06x]\n",address,s68000readPC());
   #endif
   return 0x0000;
}

void DefBadWriteByte(UINT32 address, UINT8 data)
{
   #ifdef RAINE_DEBUG
      print_debug("WB(%06x,%02x) [%06x]\n",address,data,s68000readPC());
   #endif
}

void DefBadWriteWord(UINT32 address, UINT16 data)
{
   #ifdef RAINE_DEBUG
      print_debug("WW(%06x,%04x) [%06x]\n",address,data,s68000readPC());
   #endif
}

void ByteSwap(UINT8 *MEM, UINT32 size)
{
   UINT32 ta;
   for(ta=0;tadreg[ta];
      M68000_context[cpu].areg[ta]       = old_context->areg[ta];
      M68000_context[cpu].interrupts[ta] = 0x00;
      }

      M68000_context[cpu].asp         = old_context->asp;
      M68000_context[cpu].pc          = old_context->pc;
      M68000_context[cpu].odometer    = old_context->odometer;
      M68000_context[cpu].sr          = old_context->sr;
   }
}

void M68000A_load_update(void)
{
   do_load_unpacking(0);
}

void M68000B_load_update(void)
{
   do_load_unpacking(1);
}