mirror of
https://github.com/XProger/OpenLara.git
synced 2025-01-17 12:58:50 +01:00
#407 32X support, initial commit, cinematic cutscenes
This commit is contained in:
parent
28ac8e9ba7
commit
fe8826d5b8
@ -13,6 +13,69 @@
|
||||
#define CAM_ANGLE_COMBAT ANGLE(-10)
|
||||
#define CAM_ANGLE_MAX ANGLE(85)
|
||||
|
||||
void Camera::initCinematic()
|
||||
{
|
||||
switch (gLevelID)
|
||||
{
|
||||
case LVL_TR1_CUT_1:
|
||||
gCinematicCamera.view.pos.x = 36668;
|
||||
gCinematicCamera.view.pos.z = 63180;
|
||||
gCinematicCamera.targetAngle.y = -ANGLE(128);
|
||||
break;
|
||||
case LVL_TR1_CUT_2:
|
||||
gCinematicCamera.view.pos.x = 51962;
|
||||
gCinematicCamera.view.pos.z = 53760;
|
||||
gCinematicCamera.targetAngle.y = ANGLE_90 - 4;
|
||||
break;
|
||||
case LVL_TR1_CUT_3:
|
||||
gCinematicCamera.targetAngle.y = ANGLE_90;
|
||||
//level.flip();
|
||||
break;
|
||||
case LVL_TR1_CUT_4:
|
||||
gCinematicCamera.targetAngle.y = ANGLE_90;
|
||||
break;
|
||||
default:
|
||||
ASSERT(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Camera::updateCinematic()
|
||||
{
|
||||
const CameraFrame &frame = level.cameraFrames[timer++];
|
||||
|
||||
int32 px = frame.pos.x;
|
||||
int32 py = frame.pos.y;
|
||||
int32 pz = frame.pos.z;
|
||||
|
||||
int32 dx = frame.target.x - px;
|
||||
int32 dy = frame.target.y - py;
|
||||
int32 dz = frame.target.z - pz;
|
||||
|
||||
anglesFromVector(dx, dy, dz, angle.x, angle.y);
|
||||
|
||||
int32 s, c;
|
||||
sincos(targetAngle.y, s, c);
|
||||
|
||||
X_ROTXY(pz, px, s, c);
|
||||
|
||||
px += view.pos.x;
|
||||
py += view.pos.y;
|
||||
pz += view.pos.z;
|
||||
|
||||
matrixSetView(_vec3i(px, py, pz), angle.x, angle.y + targetAngle.y);
|
||||
|
||||
Room* nextRoom = view.room->getRoom(px, py, pz);
|
||||
if (nextRoom) {
|
||||
view.room = nextRoom;
|
||||
}
|
||||
|
||||
if (timer >= level.cameraFramesCount) {
|
||||
timer = level.cameraFramesCount - 1;
|
||||
nextLevel(LevelID(gLevelID + 1));
|
||||
}
|
||||
}
|
||||
|
||||
void Camera::init(ItemObj* lara)
|
||||
{
|
||||
ASSERT(lara->extraL);
|
||||
|
@ -7,7 +7,7 @@ vec3i gCameraViewPos;
|
||||
Matrix gMatrixStack[MAX_MATRICES];
|
||||
Matrix* gMatrixPtr = gMatrixStack;
|
||||
|
||||
EWRAM_DATA Sphere gSpheres[2][MAX_SPHERES];
|
||||
EWRAM_DATA Sphere gSpheres[2][MAX_SPHERES]; // EWRAM 1k
|
||||
|
||||
const FloorData* gLastFloorData;
|
||||
FloorData gLastFloorSlant;
|
||||
@ -45,7 +45,7 @@ EWRAM_DATA ExtraInfoLara playersExtra[MAX_PLAYERS];
|
||||
#ifdef __3DO__ // TODO fix the title scren on 3DO
|
||||
EWRAM_DATA LevelID gLevelID = LVL_TR1_1;
|
||||
#else
|
||||
EWRAM_DATA LevelID gLevelID = LVL_TR1_TITLE;
|
||||
EWRAM_DATA LevelID gLevelID = LVL_TR1_1;
|
||||
#endif
|
||||
|
||||
const LevelInfo gLevelInfo[LVL_MAX] = {
|
||||
@ -1144,7 +1144,7 @@ X_INLINE int16 lerpAngleSlow(int16 a, int16 b, int32 mul, int32 div)
|
||||
void matrixPush_c()
|
||||
{
|
||||
ASSERT(gMatrixPtr - gMatrixStack < MAX_MATRICES);
|
||||
memcpy(gMatrixPtr + 1, gMatrixPtr, sizeof(Matrix));
|
||||
gMatrixPtr[1] = gMatrixPtr[0];
|
||||
gMatrixPtr++;
|
||||
}
|
||||
|
||||
@ -1556,7 +1556,8 @@ void palSet(const uint16* palette, int32 gamma, int32 bright)
|
||||
|
||||
if (gamma || bright)
|
||||
{
|
||||
uint16 tmp[256];
|
||||
uint16* tmp = (uint16*)&gSpheres;
|
||||
|
||||
if (gamma) {
|
||||
palGamma(pal, tmp, gamma);
|
||||
pal = tmp;
|
||||
@ -1574,9 +1575,11 @@ void palSet(const uint16* palette, int32 gamma, int32 bright)
|
||||
void dmaFill(void* dst, uint8 value, uint32 count)
|
||||
{
|
||||
ASSERT((count & 3) == 0);
|
||||
#ifdef __GBA__
|
||||
#if defined(__GBA__)
|
||||
vu32 v = value;
|
||||
dma3_fill(dst, v, count);
|
||||
#elif defined(__32X__)
|
||||
fast_memset(dst, value, count >> 2);
|
||||
#else
|
||||
memset(dst, value, count);
|
||||
#endif
|
||||
@ -1586,8 +1589,10 @@ void dmaFill(void* dst, uint8 value, uint32 count)
|
||||
void dmaCopy(const void* src, void* dst, uint32 size)
|
||||
{
|
||||
ASSERT((size & 3) == 0);
|
||||
#ifdef __GBA__
|
||||
#if defined(__GBA__)
|
||||
dma3_cpy(dst, src, size);
|
||||
#elif defined(__32X__)
|
||||
fast_memcpy(dst, src, size >> 2);
|
||||
#else
|
||||
memcpy(dst, src, size);
|
||||
#endif
|
||||
|
@ -10,46 +10,64 @@
|
||||
|
||||
#if defined(_WIN32)
|
||||
#define MODE4
|
||||
//#define MODE13
|
||||
#define USE_DIV_TABLE
|
||||
|
||||
#define MODE4
|
||||
#define FRAME_WIDTH 240
|
||||
#define FRAME_HEIGHT 160
|
||||
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#include <windows.h>
|
||||
#elif defined(__GBA__)
|
||||
#define MODE4
|
||||
#define USE_DIV_TABLE
|
||||
#define ROM_READ
|
||||
#define USE_ASM
|
||||
#define ALIGNED_LIGHTMAP
|
||||
|
||||
#define MODE4
|
||||
#define FRAME_WIDTH 240
|
||||
#define FRAME_HEIGHT 160
|
||||
|
||||
#include <tonc.h>
|
||||
#elif defined(__NDS__)
|
||||
#define MODEHW
|
||||
#define USE_DIV_TABLE
|
||||
|
||||
#define MODEHW
|
||||
#define FRAME_WIDTH 256
|
||||
#define FRAME_HEIGHT 192
|
||||
|
||||
#include <nds.h>
|
||||
#include <fat.h>
|
||||
#include <filesystem.h>
|
||||
#elif defined(__TNS__)
|
||||
#define MODE13
|
||||
#define USE_DIV_TABLE
|
||||
|
||||
#define MODE13
|
||||
#define FRAME_WIDTH 320
|
||||
#define FRAME_HEIGHT 240
|
||||
|
||||
#include <os.h>
|
||||
#elif defined(__DOS__)
|
||||
#define MODE13
|
||||
#define USE_DIV_TABLE
|
||||
|
||||
#define MODE13
|
||||
#define FRAME_WIDTH 320
|
||||
#define FRAME_HEIGHT 200
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <conio.h>
|
||||
#include <dos.h>
|
||||
#include <mem.h>
|
||||
#elif defined(__3DO__)
|
||||
#define MODEHW
|
||||
#define USE_DIV_TABLE // 4k of DRAM
|
||||
#define CPU_BIG_ENDIAN
|
||||
#define USE_ASM
|
||||
|
||||
#define MODEHW
|
||||
#define FRAME_WIDTH 320
|
||||
#define FRAME_HEIGHT 240
|
||||
|
||||
#include <displayutils.h>
|
||||
#include <debug.h>
|
||||
#include <nodes.h>
|
||||
@ -69,6 +87,16 @@
|
||||
#include <celutils.h>
|
||||
#include <timerutils.h>
|
||||
#include <hardware.h>
|
||||
#elif defined(__32X__)
|
||||
#define USE_DIV_TABLE
|
||||
#define CPU_BIG_ENDIAN
|
||||
#define ROM_READ
|
||||
|
||||
#define MODE13
|
||||
#define FRAME_WIDTH 320
|
||||
#define FRAME_HEIGHT 224
|
||||
|
||||
#include "32x.h"
|
||||
#else
|
||||
#error unsupported platform
|
||||
#endif
|
||||
@ -81,30 +109,8 @@
|
||||
|
||||
#include <math.h>
|
||||
#include <limits.h>
|
||||
#include <new>
|
||||
|
||||
#if defined(MODEHW)
|
||||
#if defined(__3DO__)
|
||||
#define FRAME_WIDTH 320
|
||||
#define FRAME_HEIGHT 240
|
||||
#elif defined(__NDS__)
|
||||
#define FRAME_WIDTH 256
|
||||
#define FRAME_HEIGHT 192
|
||||
#endif
|
||||
#elif defined(MODE4)
|
||||
#define VRAM_WIDTH 120 // in shorts (240 bytes)
|
||||
#define FRAME_WIDTH 240
|
||||
#define FRAME_HEIGHT 160
|
||||
#elif defined(MODE13)
|
||||
#define VRAM_WIDTH 160 // in shorts (320 bytes)
|
||||
#define FRAME_WIDTH 320
|
||||
|
||||
#if defined(__TNS__)
|
||||
#define FRAME_HEIGHT 240 // MODE X?
|
||||
#else
|
||||
#define FRAME_HEIGHT 200
|
||||
#endif
|
||||
#endif
|
||||
#define VRAM_WIDTH (FRAME_WIDTH/2) // in shorts
|
||||
|
||||
// Optimization flags =========================================================
|
||||
#ifdef __GBA__
|
||||
@ -143,6 +149,23 @@
|
||||
#define FAST_HITMASK
|
||||
#endif
|
||||
|
||||
#ifdef __32X__
|
||||
// hide dead enemies after a while to reduce the number of polygons on the screen
|
||||
#define HIDE_CORPSES (30*10) // 10 sec
|
||||
// replace trap flor geometry by two flat quads in the static state
|
||||
#define LOD_TRAP_FLOOR
|
||||
// disable some plants environment to reduce overdraw of transparent geometry
|
||||
#define NO_STATIC_MESH_PLANTS
|
||||
// use IWRAM_CODE section that faster for matrix interpolation (GBA only)
|
||||
#define IWRAM_MATRIX_LERP
|
||||
// the maximum of active enemies
|
||||
#define MAX_ENEMIES 3
|
||||
// visibility distance
|
||||
#define VIEW_DIST (1024 * 10)
|
||||
// skip collideSpheres for enemies
|
||||
#define FAST_HITMASK
|
||||
#endif
|
||||
|
||||
#ifndef NAV_STEPS
|
||||
#define NAV_STEPS 5
|
||||
#endif
|
||||
@ -190,16 +213,24 @@ typedef unsigned int uint32;
|
||||
typedef uint16 divTableInt;
|
||||
#endif
|
||||
|
||||
#if defined(__3DO__)
|
||||
//#include <new>
|
||||
inline void* operator new(size_t, void *ptr)
|
||||
{
|
||||
return ptr;
|
||||
}
|
||||
|
||||
#if defined(__3DO__) || defined(__32X__)
|
||||
X_INLINE int32 abs(int32 x) {
|
||||
return (x >= 0) ? x : -x;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(__GBA__) || defined(__NDS__)
|
||||
#if defined(__GBA__) || defined(__NDS__) || defined(__32X__)
|
||||
#define int2str(x,str) itoa(x, str, 10)
|
||||
#elif defined(__3DO__)
|
||||
#define int2str(x,str) sprintf(str, "%d", x)
|
||||
#elif defined(__TNS__)
|
||||
#define int2str(x,str) __itoa(x, str, 10)
|
||||
#else
|
||||
#define int2str(x,str) _itoa(x, str, 10)
|
||||
#endif
|
||||
@ -436,7 +467,7 @@ extern int32 fps;
|
||||
#define MAX_TEXTURES 1536
|
||||
#define MAX_SPRITES 180
|
||||
#define MAX_FACES 1920
|
||||
#define MAX_ROOM_LIST 16
|
||||
#define MAX_ROOM_LIST 32
|
||||
#define MAX_PORTALS 16
|
||||
#define MAX_CAUSTICS 32
|
||||
#define MAX_RAND_TABLE 32
|
||||
@ -521,10 +552,11 @@ enum InputKey {
|
||||
IK_C = (1 << 6),
|
||||
IK_X = (1 << 7),
|
||||
IK_Y = (1 << 8),
|
||||
IK_L = (1 << 9),
|
||||
IK_R = (1 << 10),
|
||||
IK_START = (1 << 11),
|
||||
IK_SELECT = (1 << 12)
|
||||
IK_Z = (1 << 9),
|
||||
IK_L = (1 << 10),
|
||||
IK_R = (1 << 11),
|
||||
IK_START = (1 << 12),
|
||||
IK_SELECT = (1 << 13)
|
||||
};
|
||||
|
||||
// action keys (ItemObj::input)
|
||||
@ -1322,6 +1354,9 @@ struct Camera {
|
||||
bool lastFixed;
|
||||
bool center;
|
||||
|
||||
void initCinematic();
|
||||
void updateCinematic();
|
||||
|
||||
void init(ItemObj* lara);
|
||||
Location getLocationForAngle(int32 angle, int32 distH, int32 distV);
|
||||
void clip(Location &loc);
|
||||
@ -1517,6 +1552,8 @@ struct ExtraInfoLara
|
||||
|
||||
extern ExtraInfoLara playersExtra[MAX_PLAYERS];
|
||||
|
||||
#define gCinematicCamera playersExtra[0].camera
|
||||
|
||||
struct Enemy;
|
||||
|
||||
enum EnemyMood
|
||||
@ -1993,6 +2030,14 @@ struct Box
|
||||
uint16 overlap;
|
||||
};
|
||||
|
||||
struct CameraFrame
|
||||
{
|
||||
vec3s target;
|
||||
vec3s pos;
|
||||
int16 fov;
|
||||
int16 roll;
|
||||
};
|
||||
|
||||
struct Level
|
||||
{
|
||||
uint32 magic;
|
||||
@ -2037,7 +2082,7 @@ struct Level
|
||||
const uint16* zones[2][ZONE_MAX];
|
||||
const int16* animTexData;
|
||||
const ItemObjInfo* itemsInfo;
|
||||
uint32 cameraFrames;
|
||||
const CameraFrame* cameraFrames;
|
||||
const uint16* soundMap;
|
||||
const SoundInfo* soundsInfo;
|
||||
const uint8* soundData;
|
||||
@ -2645,6 +2690,13 @@ vec3i boxPushOut(const AABBi &a, const AABBi &b);
|
||||
void flush_c();
|
||||
#endif
|
||||
|
||||
#ifdef __32X__ // TODO
|
||||
#undef matrixPush
|
||||
#define matrixPush matrixPush_asm
|
||||
|
||||
extern "C" void matrixPush_asm();
|
||||
#endif
|
||||
|
||||
#define matrixPop() gMatrixPtr--
|
||||
|
||||
X_INLINE vec3i matrixGetDir(const Matrix &m)
|
||||
@ -2678,6 +2730,7 @@ void drawText(int32 x, int32 y, const char* text, TextAlign align);
|
||||
void drawModel(const ItemObj* item);
|
||||
void drawItem(const ItemObj* item);
|
||||
void drawRooms(Camera* camera);
|
||||
void drawCinematicRooms();
|
||||
void drawHUD(Lara* lara);
|
||||
void drawNodesLerp(const ItemObj* item, const AnimFrame* frameA, const AnimFrame* frameB, int32 frameDelta, int32 frameRate);
|
||||
|
||||
|
@ -771,6 +771,48 @@ void drawRooms(Camera* camera)
|
||||
setViewport(vp);
|
||||
}
|
||||
|
||||
void drawCinematicRooms()
|
||||
{
|
||||
RectMinMax vp = viewport;
|
||||
#if 1
|
||||
gCinematicCamera.view.room->clip = viewport;
|
||||
|
||||
Room** visRoom = gCinematicCamera.view.room->getVisibleRooms();
|
||||
|
||||
// draw rooms and objects
|
||||
while (*visRoom)
|
||||
{
|
||||
Room* room = *visRoom++;
|
||||
drawRoom(room);
|
||||
room->reset();
|
||||
}
|
||||
#else
|
||||
for (int32 i = 0; i < level.roomsCount; i++)
|
||||
{
|
||||
rooms[i].clip = vp;
|
||||
}
|
||||
|
||||
for (int32 i = 0; i < level.roomsCount; i++)
|
||||
{
|
||||
if (rooms[i].info->alternateRoom != NO_ROOM) {
|
||||
rooms[rooms[i].info->alternateRoom].clip.x0 = 0xFFFF;
|
||||
}
|
||||
}
|
||||
|
||||
for (int32 i = 0; i < level.roomsCount; i++)
|
||||
{
|
||||
const Room* room = rooms + i;
|
||||
if (room->clip.x0 == 0xFFFF)
|
||||
continue;
|
||||
|
||||
drawRoom(room);
|
||||
}
|
||||
#endif
|
||||
|
||||
setPaletteIndex(0);
|
||||
setViewport(vp);
|
||||
}
|
||||
|
||||
void drawHUD(Lara* lara)
|
||||
{
|
||||
int32 x = (FRAME_WIDTH - (100 + 2 + 2)) - 4;
|
||||
|
@ -149,6 +149,11 @@ void gameLoadLevel(const void* data)
|
||||
}
|
||||
ItemObj::sFirstFree = items + level.itemsCount;
|
||||
|
||||
for (int32 i = 0; i < MAX_PLAYERS; i++)
|
||||
{
|
||||
players[i] = NULL;
|
||||
}
|
||||
|
||||
if (gLevelID == LVL_TR1_TITLE) {
|
||||
// init dummy Lara for updateInput()
|
||||
items->extraL = playersExtra;
|
||||
@ -173,13 +178,19 @@ void gameLoadLevel(const void* data)
|
||||
item->angle.y = ((info->flags >> 14) - 2) * ANGLE_90;
|
||||
item->flags = info->flags;
|
||||
|
||||
if (item->type == ITEM_LARA || item->type == ITEM_CUT_1) {
|
||||
if (item->type == ITEM_LARA) {
|
||||
players[0] = (Lara*)item;
|
||||
}
|
||||
|
||||
item->init(rooms + info->roomIndex);
|
||||
}
|
||||
|
||||
if (isCutsceneLevel())
|
||||
{
|
||||
gCinematicCamera.initCinematic();
|
||||
}
|
||||
|
||||
|
||||
// gym
|
||||
//resetLara(0, 7, _vec3i(39038, -1280, 51712), ANGLE_90); // start
|
||||
//resetLara(0, 8, _vec3i(55994, 0, 52603), ANGLE_90); // piano
|
||||
@ -233,10 +244,17 @@ void updateItems()
|
||||
item = next;
|
||||
}
|
||||
|
||||
for (int32 i = 0; i < MAX_PLAYERS; i++)
|
||||
if (isCutsceneLevel())
|
||||
{
|
||||
if (players[i]) {
|
||||
players[i]->update();
|
||||
gCinematicCamera.updateCinematic();
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int32 i = 0; i < MAX_PLAYERS; i++)
|
||||
{
|
||||
if (players[i]) {
|
||||
players[i]->update();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -306,9 +324,17 @@ void gameRender()
|
||||
{
|
||||
// TODO set viewports for coop
|
||||
#ifndef PROFILE_SOUNDTIME
|
||||
drawRooms(&players[i]->extraL->camera);
|
||||
if (isCutsceneLevel()) {
|
||||
drawCinematicRooms();
|
||||
} else {
|
||||
drawRooms(&players[i]->extraL->camera);
|
||||
}
|
||||
#endif
|
||||
drawHUD(players[i]);
|
||||
|
||||
if (players[i])
|
||||
{
|
||||
drawHUD(players[i]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
inventory.draw();
|
||||
|
@ -937,7 +937,7 @@ int32 ItemObj::getSpheres(Sphere* spheres, bool flag) const
|
||||
#include "enemy.h"
|
||||
#include "object.h"
|
||||
|
||||
#ifdef __GBA__
|
||||
#ifdef __GNUC__
|
||||
// ItemObj ctor is called on existing and pre-filled memory
|
||||
#pragma GCC diagnostic ignored "-Wuninitialized"
|
||||
#endif
|
||||
@ -992,7 +992,7 @@ ItemObj::ItemObj(Room* room)
|
||||
room->add(this);
|
||||
}
|
||||
|
||||
#ifdef __GBA__
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic warning "-Wuninitialized"
|
||||
#endif
|
||||
|
||||
@ -1472,10 +1472,10 @@ ItemObj* ItemObj::init(Room* room)
|
||||
// INIT_ITEM( GEARS_1 , ??? );
|
||||
// INIT_ITEM( GEARS_2 , ??? );
|
||||
// INIT_ITEM( GEARS_3 , ??? );
|
||||
// INIT_ITEM( CUT_1 , ??? );
|
||||
// INIT_ITEM( CUT_2 , ??? );
|
||||
// INIT_ITEM( CUT_3 , ??? );
|
||||
// INIT_ITEM( CUT_4 , ??? );
|
||||
INIT_ITEM( CUT_1 , CinematicObject );
|
||||
INIT_ITEM( CUT_2 , CinematicObject );
|
||||
INIT_ITEM( CUT_3 , CinematicObject );
|
||||
INIT_ITEM( CUT_4 , CinematicObject );
|
||||
// INIT_ITEM( INV_PASSPORT_CLOSED , ??? );
|
||||
// INIT_ITEM( INV_MAP , ??? );
|
||||
INIT_ITEM( CRYSTAL , Crystal );
|
||||
|
@ -2737,6 +2737,14 @@ struct Lara : ItemObj
|
||||
if (keys & IK_L) input |= IN_LOOK;
|
||||
if (keys & IK_R) input |= IN_WALK;
|
||||
}
|
||||
#elif defined(__32X__)
|
||||
// 6 buttons
|
||||
if (keys & IK_A) input |= IN_JUMP;
|
||||
if (keys & IK_B) input |= IN_ACTION;
|
||||
if (keys & IK_C) input |= IN_WEAPON;
|
||||
if (keys & IK_X) input |= IN_WALK;
|
||||
if (keys & IK_Y) input |= IN_UP | IN_DOWN;
|
||||
if (keys & IK_Z) input |= IN_LOOK;
|
||||
#elif defined(__GBA__) || defined(_WIN32)
|
||||
int32 ikA, ikB;
|
||||
|
||||
|
@ -224,4 +224,12 @@ int32 getAmbientTrack()
|
||||
return gLevelInfo[gLevelID].track;
|
||||
}
|
||||
|
||||
bool isCutsceneLevel()
|
||||
{
|
||||
return (gLevelID == LVL_TR1_CUT_1) ||
|
||||
(gLevelID == LVL_TR1_CUT_2) ||
|
||||
(gLevelID == LVL_TR1_CUT_3) ||
|
||||
(gLevelID == LVL_TR1_CUT_4);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -335,6 +335,35 @@ struct TrapDoor : Object
|
||||
};
|
||||
|
||||
|
||||
struct CinematicObject : Object
|
||||
{
|
||||
CinematicObject(Room* room) : Object(room)
|
||||
{
|
||||
angle.y = 0;
|
||||
|
||||
if (type == ITEM_CUT_1)
|
||||
{
|
||||
gCinematicCamera.view.pos = pos;
|
||||
gCinematicCamera.view.room = room;
|
||||
}
|
||||
|
||||
flags |= ITEM_FLAG_SHADOW;
|
||||
|
||||
activate();
|
||||
}
|
||||
|
||||
virtual void update()
|
||||
{
|
||||
if (type == ITEM_CUT_1 || type == ITEM_CUT_2 || type == ITEM_CUT_3)
|
||||
{
|
||||
pos = playersExtra[0].camera.view.pos;
|
||||
angle.y = playersExtra[0].camera.targetAngle.y;
|
||||
}
|
||||
animProcess();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct Crystal : Object
|
||||
{
|
||||
Crystal(Room* room) : Object(room)
|
||||
|
128
src/platform/32x/32x.h
Normal file
128
src/platform/32x/32x.h
Normal file
@ -0,0 +1,128 @@
|
||||
#ifndef __32X_H__
|
||||
#define __32X_H__
|
||||
|
||||
#define MARS_CRAM (*(volatile unsigned short *)0x20004200)
|
||||
#define MARS_FRAMEBUFFER (*(volatile unsigned short *)0x24000000)
|
||||
#define MARS_OVERWRITE_IMG (*(volatile unsigned short *)0x24020000)
|
||||
#define MARS_SDRAM (*(volatile unsigned short *)0x26000000)
|
||||
|
||||
#define MARS_SYS_INTMSK (*(volatile unsigned short *)0x20004000)
|
||||
#define MARS_SYS_DMACTR (*(volatile unsigned short *)0x20004006)
|
||||
#define MARS_SYS_DMASAR (*(volatile unsigned long *)0x20004008)
|
||||
#define MARS_SYS_DMADAR (*(volatile unsigned long *)0x2000400C)
|
||||
#define MARS_SYS_DMALEN (*(volatile unsigned short *)0x20004010)
|
||||
#define MARS_SYS_DMAFIFO (*(volatile unsigned short *)0x20004012)
|
||||
#define MARS_SYS_VRESI_CLR (*(volatile unsigned short *)0x20004014)
|
||||
#define MARS_SYS_VINT_CLR (*(volatile unsigned short *)0x20004016)
|
||||
#define MARS_SYS_HINT_CLR (*(volatile unsigned short *)0x20004018)
|
||||
#define MARS_SYS_CMDI_CLR (*(volatile unsigned short *)0x2000401A)
|
||||
#define MARS_SYS_PWMI_CLR (*(volatile unsigned short *)0x2000401C)
|
||||
#define MARS_SYS_COMM0 (*(volatile unsigned short *)0x20004020) /* Master SH2 communication */
|
||||
#define MARS_SYS_COMM2 (*(volatile unsigned short *)0x20004022)
|
||||
#define MARS_SYS_COMM4 (*(volatile unsigned short *)0x20004024) /* Slave SH2 communication */
|
||||
#define MARS_SYS_COMM6 (*(volatile unsigned short *)0x20004026)
|
||||
#define MARS_SYS_COMM8 (*(volatile unsigned short *)0x20004028) /* controller 1 current value */
|
||||
#define MARS_SYS_COMM10 (*(volatile unsigned short *)0x2000402A) /* controller 2 current value */
|
||||
#define MARS_SYS_COMM12 (*(volatile unsigned long *)0x2000402C) /* vcount current value */
|
||||
|
||||
#define MARS_PWM_CTRL (*(volatile unsigned short *)0x20004030)
|
||||
#define MARS_PWM_CYCLE (*(volatile unsigned short *)0x20004032)
|
||||
#define MARS_PWM_LEFT (*(volatile unsigned short *)0x20004034)
|
||||
#define MARS_PWM_RIGHT (*(volatile unsigned short *)0x20004036)
|
||||
#define MARS_PWM_MONO (*(volatile unsigned short *)0x20004038)
|
||||
|
||||
#define MARS_VDP_DISPMODE (*(volatile unsigned short *)0x20004100)
|
||||
#define MARS_VDP_FILLEN (*(volatile unsigned short *)0x20004104)
|
||||
#define MARS_VDP_FILADR (*(volatile unsigned short *)0x20004106)
|
||||
#define MARS_VDP_FILDAT (*(volatile unsigned short *)0x20004108)
|
||||
#define MARS_VDP_FBCTL (*(volatile unsigned short *)0x2000410A)
|
||||
|
||||
#define MARS_SH2_ACCESS_VDP 0x8000
|
||||
#define MARS_68K_ACCESS_VDP 0x0000
|
||||
|
||||
#define MARS_PAL_FORMAT 0x0000
|
||||
#define MARS_NTSC_FORMAT 0x8000
|
||||
|
||||
#define MARS_VDP_PRIO_68K 0x0000
|
||||
#define MARS_VDP_PRIO_32X 0x0080
|
||||
|
||||
#define MARS_224_LINES 0x0000
|
||||
#define MARS_240_LINES 0x0040
|
||||
|
||||
#define MARS_VDP_MODE_OFF 0x0000
|
||||
#define MARS_VDP_MODE_256 0x0001
|
||||
#define MARS_VDP_MODE_32K 0x0002
|
||||
#define MARS_VDP_MODE_RLE 0x0003
|
||||
|
||||
#define MARS_VDP_VBLK 0x8000
|
||||
#define MARS_VDP_HBLK 0x4000
|
||||
#define MARS_VDP_PEN 0x2000
|
||||
#define MARS_VDP_FEN 0x0002
|
||||
#define MARS_VDP_FS 0x0001
|
||||
|
||||
#define SH2_CCTL_CP 0x10
|
||||
#define SH2_CCTL_TW 0x08
|
||||
#define SH2_CCTL_CE 0x01
|
||||
|
||||
#define SH2_FRT_TIER (*(volatile unsigned char *)0xFFFFFE10)
|
||||
#define SH2_FRT_FTCSR (*(volatile unsigned char *)0xFFFFFE11)
|
||||
#define SH2_FRT_FRCH (*(volatile unsigned char *)0xFFFFFE12)
|
||||
#define SH2_FRT_FRCL (*(volatile unsigned char *)0xFFFFFE13)
|
||||
#define SH2_FRT_OCRH (*(volatile unsigned char *)0xFFFFFE14)
|
||||
#define SH2_FRT_OCRL (*(volatile unsigned char *)0xFFFFFE15)
|
||||
#define SH2_FRT_TCR (*(volatile unsigned char *)0xFFFFFE16)
|
||||
#define SH2_FRT_TOCR (*(volatile unsigned char *)0xFFFFFE17)
|
||||
#define SH2_FRT_ICRH (*(volatile unsigned char *)0xFFFFFE18)
|
||||
#define SH2_FRT_ICRL (*(volatile unsigned char *)0xFFFFFE19)
|
||||
|
||||
#define SH2_DMA_SAR0 (*(volatile unsigned long *)0xFFFFFF80)
|
||||
#define SH2_DMA_DAR0 (*(volatile unsigned long *)0xFFFFFF84)
|
||||
#define SH2_DMA_TCR0 (*(volatile unsigned long *)0xFFFFFF88)
|
||||
#define SH2_DMA_CHCR0 (*(volatile unsigned long *)0xFFFFFF8C)
|
||||
#define SH2_DMA_VCR0 (*(volatile unsigned long *)0xFFFFFFA0)
|
||||
#define SH2_DMA_DRCR0 (*(volatile unsigned char *)0xFFFFFE71)
|
||||
|
||||
#define SH2_DMA_SAR1 (*(volatile unsigned long *)0xFFFFFF90)
|
||||
#define SH2_DMA_DAR1 (*(volatile unsigned long *)0xFFFFFF94)
|
||||
#define SH2_DMA_TCR1 (*(volatile unsigned long *)0xFFFFFF98)
|
||||
#define SH2_DMA_CHCR1 (*(volatile unsigned long *)0xFFFFFF9C)
|
||||
#define SH2_DMA_VCR1 (*(volatile unsigned long *)0xFFFFFFA8)
|
||||
#define SH2_DMA_DRCR1 (*(volatile unsigned char *)0xFFFFFE72)
|
||||
|
||||
#define SH2_DMA_DMAOR (*(volatile unsigned long *)0xFFFFFFB0)
|
||||
|
||||
#define SH2_INT_IPRA (*(volatile unsigned short *)0xFFFFFEE2)
|
||||
|
||||
#define SEGA_CTRL_UP 0x0001
|
||||
#define SEGA_CTRL_DOWN 0x0002
|
||||
#define SEGA_CTRL_LEFT 0x0004
|
||||
#define SEGA_CTRL_RIGHT 0x0008
|
||||
#define SEGA_CTRL_B 0x0010
|
||||
#define SEGA_CTRL_C 0x0020
|
||||
#define SEGA_CTRL_A 0x0040
|
||||
#define SEGA_CTRL_START 0x0080
|
||||
#define SEGA_CTRL_Z 0x0100
|
||||
#define SEGA_CTRL_Y 0x0200
|
||||
#define SEGA_CTRL_X 0x0400
|
||||
#define SEGA_CTRL_MODE 0x0800
|
||||
|
||||
#define SEGA_CTRL_TYPE 0xF000
|
||||
#define SEGA_CTRL_THREE 0x0000
|
||||
#define SEGA_CTRL_SIX 0x1000
|
||||
#define SEGA_CTRL_NONE 0xF000
|
||||
|
||||
#define MASTER_STATUS_OK 1
|
||||
#define SLAVE_STATUS_OK 2
|
||||
#define MASTER_LOCK 4
|
||||
#define SLAVE_LOCK 8
|
||||
|
||||
/* global functions in sh2_crt0.s */
|
||||
extern "C"
|
||||
{
|
||||
void fast_memcpy(void *dst, const void *src, int len);
|
||||
void fast_memset(void *dst, int value, int len);
|
||||
void CacheControl(int mode);
|
||||
void CacheClearLine(void* ptr);
|
||||
}
|
||||
|
||||
#endif
|
91
src/platform/32x/Makefile
Normal file
91
src/platform/32x/Makefile
Normal file
@ -0,0 +1,91 @@
|
||||
ifdef $(GENDEV)
|
||||
ROOTDIR = $(GENDEV)
|
||||
else
|
||||
ROOTDIR = /opt/toolchains/sega
|
||||
endif
|
||||
|
||||
TARGET = OpenLara
|
||||
BUILD = build
|
||||
SOURCES = . asm ../../fixed
|
||||
|
||||
LDSCRIPTSDIR = $(ROOTDIR)/ldscripts
|
||||
|
||||
SHPREFIX = $(ROOTDIR)/sh-elf/bin/sh-elf-
|
||||
SHCC = $(SHPREFIX)gcc
|
||||
SHXX = $(SHPREFIX)g++
|
||||
SHAS = $(SHPREFIX)as
|
||||
SHLD = $(SHPREFIX)ld
|
||||
SHOBJC = $(SHPREFIX)objcopy
|
||||
|
||||
CC_VER := $(shell $(SHCC) -dumpversion)
|
||||
|
||||
MDPREFIX = $(ROOTDIR)/m68k-elf/bin/m68k-elf-
|
||||
MDAS = $(MDPREFIX)as
|
||||
MDLD = $(MDPREFIX)ld
|
||||
|
||||
LIBPATH = -L$(ROOTDIR)/sh-elf/lib -L$(ROOTDIR)/sh-elf/lib/gcc/sh-elf/$(CC_VER) -L$(ROOTDIR)/sh-elf/sh-elf/lib
|
||||
INCPATH = -I. -I../../fixed -I$(ROOTDIR)/sh-elf/include -I$(ROOTDIR)/sh-elf/sh-elf/include
|
||||
|
||||
SHCCFLAGS = -D__32X__ -m2 -mb -O2 -Wall -g -c -fno-rtti -fno-exceptions -fno-asynchronous-unwind-tables -fomit-frame-pointer -ffast-math -Wno-class-memaccess
|
||||
SHLDFLAGS = -T $(LDSCRIPTSDIR)/mars.ld -Wl,-Map=$(BUILD)/output.map -nostdlib
|
||||
SHASFLAGS = --big
|
||||
|
||||
MDLDFLAGS = -T $(LDSCRIPTSDIR)/md.ld --oformat binary
|
||||
MDASFLAGS = -m68000 --register-prefix-optional
|
||||
|
||||
DD = dd
|
||||
RM = rm -f
|
||||
|
||||
FILES_AS = $(foreach dir, $(SOURCES), $(wildcard $(dir)/*.s))
|
||||
FILES_CC = $(foreach dir, $(SOURCES), $(wildcard $(dir)/*.c))
|
||||
FILES_XX = $(foreach dir, $(SOURCES), $(wildcard $(dir)/*.cpp))
|
||||
|
||||
LIBS = $(LIBPATH) -lm -lc -lgcc -lgcc-Os-4-200 -lnosys
|
||||
OBJS = $(BUILD)/sh2_crt0.o
|
||||
OBJS += $(addprefix $(BUILD)/, $(notdir $(FILES_AS:%.s=%.o)))
|
||||
OBJS += $(addprefix $(BUILD)/, $(notdir $(FILES_CC:%.c=%.o)))
|
||||
OBJS += $(addprefix $(BUILD)/, $(notdir $(FILES_XX:%.cpp=%.o)))
|
||||
|
||||
.PHONY: dump clean
|
||||
|
||||
all: $(BUILD) m68k_crt0.bin m68k_crt1.bin $(TARGET).32x
|
||||
|
||||
dump:
|
||||
@[ -d dump ] || mkdir -p dump
|
||||
$(SHXX) $(SHCCFLAGS) $(INCPATH) -S -o dump/main.s main.cpp
|
||||
$(SHXX) $(SHCCFLAGS) $(INCPATH) -S -o dump/render.s render.cpp
|
||||
$(SHXX) $(SHCCFLAGS) $(INCPATH) -S -o dump/sound.s sound.cpp
|
||||
$(SHXX) $(SHCCFLAGS) $(INCPATH) -S -o dump/common.s ../../fixed/common.cpp
|
||||
|
||||
$(BUILD):
|
||||
@[ -d $@ ] || mkdir -p $@
|
||||
|
||||
$(TARGET).32x: $(TARGET).elf
|
||||
$(SHOBJC) -O binary $< temp.bin
|
||||
$(DD) if=temp.bin of=$@ bs=1024K conv=sync
|
||||
$(RM) -f temp.bin
|
||||
|
||||
$(TARGET).elf: $(OBJS)
|
||||
$(SHCC) $(SHLDFLAGS) $(OBJS) $(LIBS) -o $(TARGET).elf
|
||||
|
||||
%.bin: crt/%.s
|
||||
$(MDAS) $(MDASFLAGS) -o $(BUILD)/$@.o $<
|
||||
$(MDLD) $(MDLDFLAGS) -o $(BUILD)/$@ $(BUILD)/$@.o
|
||||
|
||||
$(BUILD)/%.o: crt/%.s
|
||||
$(SHAS) $(SHASFLAGS) $(INCPATH) -o $@ $<
|
||||
|
||||
$(BUILD)/%.o: asm/%.s
|
||||
$(SHAS) $(SHASFLAGS) $(INCPATH) -o $@ $<
|
||||
|
||||
$(BUILD)/%.o: %.c
|
||||
$(SHCC) $(SHCCFLAGS) $(INCPATH) -o $@ $<
|
||||
|
||||
$(BUILD)/%.o: %.cpp
|
||||
$(SHXX) $(SHCCFLAGS) $(INCPATH) -o $@ $<
|
||||
|
||||
$(BUILD)/%.o: ../../fixed/%.cpp
|
||||
$(SHXX) $(SHCCFLAGS) $(INCPATH) -o $@ $<
|
||||
|
||||
clean:
|
||||
$(RM) $(BUILD)/* *.32x *.elf
|
17
src/platform/32x/asm/data.s
Normal file
17
src/platform/32x/asm/data.s
Normal file
@ -0,0 +1,17 @@
|
||||
.text
|
||||
/*
|
||||
.global _TITLE_PKD
|
||||
.align 4
|
||||
_TITLE_PKD:
|
||||
.long TITLE
|
||||
TITLE:
|
||||
.incbin "data/TITLE.PKD"
|
||||
*/
|
||||
.global _LEVEL1_PKD
|
||||
.align 4
|
||||
_LEVEL1_PKD:
|
||||
.long LEVEL1
|
||||
LEVEL1:
|
||||
.incbin "data/LEVEL1.PKD"
|
||||
|
||||
.align 4
|
42
src/platform/32x/asm/matrixPush.s
Normal file
42
src/platform/32x/asm/matrixPush.s
Normal file
@ -0,0 +1,42 @@
|
||||
.text
|
||||
|
||||
.global _matrixPush_asm
|
||||
_matrixPush_asm:
|
||||
mov.l .var_matrixPtr, r5
|
||||
mov.l @r5, r0
|
||||
|
||||
/* row[0] */
|
||||
mov.l @r0+, r1
|
||||
mov.l @r0+, r2
|
||||
mov.l @r0+, r3
|
||||
mov.l @r0+, r4
|
||||
mov.l r1, @(32, r0)
|
||||
mov.l r2, @(36, r0)
|
||||
mov.l r3, @(40, r0)
|
||||
mov.l r4, @(44, r0)
|
||||
|
||||
/* row[1] */
|
||||
mov.l @r0+, r1
|
||||
mov.l @r0+, r2
|
||||
mov.l @r0+, r3
|
||||
mov.l @r0+, r4
|
||||
mov.l r1, @(32, r0)
|
||||
mov.l r2, @(36, r0)
|
||||
mov.l r3, @(40, r0)
|
||||
mov.l r4, @(44, r0)
|
||||
|
||||
/* row[2] */
|
||||
mov.l @r0+, r1
|
||||
mov.l @r0+, r2
|
||||
mov.l @r0+, r3
|
||||
mov.l @r0+, r4
|
||||
mov.l r1, @(32, r0)
|
||||
mov.l r2, @(36, r0)
|
||||
mov.l r3, @(40, r0)
|
||||
mov.l r4, @(44, r0)
|
||||
|
||||
rts
|
||||
mov.l r0, @r5
|
||||
|
||||
.var_matrixPtr:
|
||||
.long _gMatrixPtr
|
85
src/platform/32x/crt/m68k_crt0.s
Normal file
85
src/platform/32x/crt/m68k_crt0.s
Normal file
@ -0,0 +1,85 @@
|
||||
| SEGA 32X support code for the 68000
|
||||
| by Chilly Willy
|
||||
| First part of rom header
|
||||
|
||||
.text
|
||||
|
||||
| Initial exception vectors. When the console is first turned on, it is
|
||||
| in MegaDrive mode. All vectors just point to the code to start up the
|
||||
| Mars adapter. After the adapter is enabled, none of these vectors will
|
||||
| appear as the adpater uses its own vector table to route exceptions to
|
||||
| the jump table. 0x3F0 is where the 68000 starts at for the 32X.
|
||||
|
||||
.long 0x01000000,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0
|
||||
.long 0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0
|
||||
.long 0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0
|
||||
.long 0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0
|
||||
.long 0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0
|
||||
.long 0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0
|
||||
.long 0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0
|
||||
.long 0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0,0x000003F0
|
||||
|
||||
| Standard MegaDrive ROM header at 0x100
|
||||
|
||||
.ascii "SEGA 32X " /* First 4 bytes must be "SEGA" */
|
||||
.ascii "XProger (c)2022 " /* Copyright and date */
|
||||
.ascii "OpenLara Alpha " /* JP Name */
|
||||
.ascii "OpenLara Alpha " /* EN Name */
|
||||
.ascii "GM 14021968-01" /* Serial No. */
|
||||
.word 0x0000
|
||||
.ascii "J6 "
|
||||
.long 0x00000000,0x003FFFFF /* ROM start, end */
|
||||
.long 0x00FF0000,0x00FFFFFF /* RAM start, end */
|
||||
|
||||
| .ascii "RA" /* External RAM */
|
||||
| .byte 0xF8 /* don't clear + odd bytes */
|
||||
| .byte 0x20 /* SRAM */
|
||||
| .long 0x00200001,0x0020FFFF /* SRAM start, end */
|
||||
|
||||
.ascii " " /* no SRAM */
|
||||
|
||||
.ascii " "
|
||||
.ascii " "
|
||||
.ascii " "
|
||||
.ascii " "
|
||||
.ascii "F " /* enable any hardware configuration */
|
||||
|
||||
| Mars exception vector jump table at 0x200
|
||||
|
||||
jmp 0x880800.l /* reset = hot start */
|
||||
jsr 0x880806.l /* EX_BusError */
|
||||
jsr 0x880806.l /* EX_AddrError */
|
||||
jsr 0x880806.l /* EX_IllInstr */
|
||||
jsr 0x880806.l /* EX_DivByZero */
|
||||
jsr 0x880806.l /* EX_CHK */
|
||||
jsr 0x880806.l /* EX_TrapV */
|
||||
jsr 0x880806.l /* EX_Priviledge */
|
||||
jsr 0x880806.l /* EX_Trace */
|
||||
jsr 0x880806.l /* EX_LineA */
|
||||
jsr 0x880806.l /* EX_LineF */
|
||||
.space 72 /* reserved */
|
||||
jsr 0x880806.l /* EX_Spurious */
|
||||
jsr 0x880806.l /* EX_Level1 */
|
||||
jsr 0x880806.l /* EX_Level2 */
|
||||
jsr 0x880806.l /* EX_Level3 */
|
||||
jmp 0x88080C.l /* EX_Level4 HBlank */
|
||||
jsr 0x880806.l /* EX_Level5 */
|
||||
jmp 0x880812.l /* EX_Level6 VBlank */
|
||||
jsr 0x880806.l /* EX_Level7 */
|
||||
jsr 0x880806.l /* EX_Trap0 */
|
||||
jsr 0x880806.l /* EX_Trap1 */
|
||||
jsr 0x880806.l /* EX_Trap2 */
|
||||
jsr 0x880806.l /* EX_Trap3 */
|
||||
jsr 0x880806.l /* EX_Trap4 */
|
||||
jsr 0x880806.l /* EX_Trap5 */
|
||||
jsr 0x880806.l /* EX_Trap6 */
|
||||
jsr 0x880806.l /* EX_Trap7 */
|
||||
jsr 0x880806.l /* EX_Trap8 */
|
||||
jsr 0x880806.l /* EX_Trap9 */
|
||||
jsr 0x880806.l /* EX_TrapA */
|
||||
jsr 0x880806.l /* EX_TrapB */
|
||||
jsr 0x880806.l /* EX_TrapC */
|
||||
jsr 0x880806.l /* EX_TrapD */
|
||||
jsr 0x880806.l /* EX_TrapE */
|
||||
jsr 0x880806.l /* EX_TrapF */
|
||||
.space 166 /* reserved */
|
548
src/platform/32x/crt/m68k_crt1.s
Normal file
548
src/platform/32x/crt/m68k_crt1.s
Normal file
@ -0,0 +1,548 @@
|
||||
| SEGA 32X support code for the 68000
|
||||
| by Chilly Willy
|
||||
| Third part of rom header
|
||||
|
||||
.text
|
||||
|
||||
| Standard Mars startup code at 0x3F0 - this is included as binary as SEGA
|
||||
| uses this as a security key. US law allows us to include this as-is because
|
||||
| it's used for security. The interoperability clauses in the law state this
|
||||
| trumps copyright... and the Supreme Court agrees. :P
|
||||
|
||||
.word 0x287C,0xFFFF,0xFFC0,0x23FC,0x0000,0x0000,0x00A1,0x5128
|
||||
.word 0x46FC,0x2700,0x4BF9,0x00A1,0x0000,0x7001,0x0CAD,0x4D41
|
||||
.word 0x5253,0x30EC,0x6600,0x03E6,0x082D,0x0007,0x5101,0x67F8
|
||||
.word 0x4AAD,0x0008,0x6710,0x4A6D,0x000C,0x670A,0x082D,0x0000
|
||||
.word 0x5101,0x6600,0x03B8,0x102D,0x0001,0x0200,0x000F,0x6706
|
||||
.word 0x2B78,0x055A,0x4000,0x7200,0x2C41,0x4E66,0x41F9,0x0000
|
||||
.word 0x04D4,0x6100,0x0152,0x6100,0x0176,0x47F9,0x0000,0x04E8
|
||||
.word 0x43F9,0x00A0,0x0000,0x45F9,0x00C0,0x0011,0x3E3C,0x0100
|
||||
.word 0x7000,0x3B47,0x1100,0x3B47,0x1200,0x012D,0x1100,0x66FA
|
||||
.word 0x7425,0x12DB,0x51CA,0xFFFC,0x3B40,0x1200,0x3B40,0x1100
|
||||
.word 0x3B47,0x1200,0x149B,0x149B,0x149B,0x149B,0x41F9,0x0000
|
||||
.word 0x04C0,0x43F9,0x00FF,0x0000,0x22D8,0x22D8,0x22D8,0x22D8
|
||||
.word 0x22D8,0x22D8,0x22D8,0x22D8,0x41F9,0x00FF,0x0000,0x4ED0
|
||||
.word 0x1B7C,0x0001,0x5101,0x41F9,0x0000,0x06BC,0xD1FC,0x0088
|
||||
.word 0x0000,0x4ED0,0x0404,0x303C,0x076C,0x0000,0x0000,0xFF00
|
||||
.word 0x8137,0x0002,0x0100,0x0000,0xAF01,0xD91F,0x1127,0x0021
|
||||
.word 0x2600,0xF977,0xEDB0,0xDDE1,0xFDE1,0xED47,0xED4F,0xD1E1
|
||||
.word 0xF108,0xD9C1,0xD1E1,0xF1F9,0xF3ED,0x5636,0xE9E9,0x9FBF
|
||||
.word 0xDFFF,0x4D41,0x5253,0x2049,0x6E69,0x7469,0x616C,0x2026
|
||||
.word 0x2053,0x6563,0x7572,0x6974,0x7920,0x5072,0x6F67,0x7261
|
||||
.word 0x6D20,0x2020,0x2020,0x2020,0x2020,0x2043,0x6172,0x7472
|
||||
.word 0x6964,0x6765,0x2056,0x6572,0x7369,0x6F6E,0x2020,0x2020
|
||||
.word 0x436F,0x7079,0x7269,0x6768,0x7420,0x5345,0x4741,0x2045
|
||||
.word 0x4E54,0x4552,0x5052,0x4953,0x4553,0x2C4C,0x5444,0x2E20
|
||||
.word 0x3139,0x3934,0x2020,0x2020,0x2020,0x2020,0x2020,0x2020
|
||||
.word 0x2020,0x2020,0x2020,0x2020,0x2020,0x2020,0x2020,0x2020
|
||||
.word 0x2020,0x2020,0x2020,0x524F,0x4D20,0x5665,0x7273,0x696F
|
||||
.word 0x6E20,0x312E,0x3000,0x48E7,0xC040,0x43F9,0x00C0,0x0004
|
||||
.word 0x3011,0x303C,0x8000,0x323C,0x0100,0x3E3C,0x0012,0x1018
|
||||
.word 0x3280,0xD041,0x51CF,0xFFF8,0x4CDF,0x0203,0x4E75,0x48E7
|
||||
.word 0x81C0,0x41F9,0x0000,0x063E,0x43F9,0x00C0,0x0004,0x3298
|
||||
.word 0x3298,0x3298,0x3298,0x3298,0x3298,0x3298,0x2298,0x3341
|
||||
.word 0xFFFC,0x3011,0x0800,0x0001,0x66F8,0x3298,0x3298,0x7000
|
||||
.word 0x22BC,0xC000,0x0000,0x7E0F,0x3340,0xFFFC,0x3340,0xFFFC
|
||||
.word 0x3340,0xFFFC,0x3340,0xFFFC,0x51CF,0xFFEE,0x22BC,0x4000
|
||||
.word 0x0010,0x7E09,0x3340,0xFFFC,0x3340,0xFFFC,0x3340,0xFFFC
|
||||
.word 0x3340,0xFFFC,0x51CF,0xFFEE,0x4CDF,0x0381,0x4E75,0x8114
|
||||
.word 0x8F01,0x93FF,0x94FF,0x9500,0x9600,0x9780,0x4000,0x0080
|
||||
.word 0x8104,0x8F02,0x48E7,0xC140,0x43F9,0x00A1,0x5180,0x08A9
|
||||
.word 0x0007,0xFF80,0x66F8,0x3E3C,0x00FF,0x7000,0x7200,0x337C
|
||||
.word 0x00FF,0x0004,0x3341,0x0006,0x3340,0x0008,0x4E71,0x0829
|
||||
.word 0x0001,0x000B,0x66F8,0x0641,0x0100,0x51CF,0xFFE8,0x4CDF
|
||||
.word 0x0283,0x4E75,0x48E7,0x8180,0x41F9,0x00A1,0x5200,0x08A8
|
||||
.word 0x0007,0xFF00,0x66F8,0x3E3C,0x001F,0x20C0,0x20C0,0x20C0
|
||||
.word 0x20C0,0x51CF,0xFFF6,0x4CDF,0x0181,0x4E75,0x41F9,0x00FF
|
||||
.word 0x0000,0x3E3C,0x07FF,0x7000,0x20C0,0x20C0,0x20C0,0x20C0
|
||||
.word 0x20C0,0x20C0,0x20C0,0x20C0,0x51CF,0xFFEE,0x3B7C,0x0000
|
||||
.word 0x1200,0x7E0A,0x51CF,0xFFFE,0x43F9,0x00A1,0x5100,0x7000
|
||||
.word 0x2340,0x0020,0x2340,0x0024,0x1B7C,0x0003,0x5101,0x2E79
|
||||
.word 0x0088,0x0000,0x0891,0x0007,0x66FA,0x7000,0x3340,0x0002
|
||||
.word 0x3340,0x0004,0x3340,0x0006,0x2340,0x0008,0x2340,0x000C
|
||||
.word 0x3340,0x0010,0x3340,0x0030,0x3340,0x0032,0x3340,0x0038
|
||||
.word 0x3340,0x0080,0x3340,0x0082,0x08A9,0x0000,0x008B,0x66F8
|
||||
.word 0x6100,0xFF12,0x08E9,0x0000,0x008B,0x67F8,0x6100,0xFF06
|
||||
.word 0x08A9,0x0000,0x008B,0x6100,0xFF3C,0x303C,0x0040,0x2229
|
||||
.word 0x0020,0x0C81,0x5351,0x4552,0x6700,0x0092,0x303C,0x0080
|
||||
.word 0x2229,0x0020,0x0C81,0x5344,0x4552,0x6700,0x0080,0x21FC
|
||||
.word 0x0088,0x02A2,0x0070,0x303C,0x0002,0x7200,0x122D,0x0001
|
||||
.word 0x1429,0x0080,0xE14A,0x8242,0x0801,0x000F,0x660A,0x0801
|
||||
.word 0x0006,0x6700,0x0058,0x6008,0x0801,0x0006,0x6600,0x004E
|
||||
.word 0x7020,0x41F9,0x0088,0x0000,0x3C28,0x018E,0x4A46,0x6700
|
||||
.word 0x0010,0x3429,0x0028,0x0C42,0x0000,0x67F6,0xB446,0x662C
|
||||
.word 0x7000,0x2340,0x0028,0x2340,0x002C,0x3E14,0x2C7C,0xFFFF
|
||||
.word 0xFFC0,0x4CD6,0x7FF9,0x44FC,0x0000,0x6014,0x43F9,0x00A1
|
||||
.word 0x5100,0x3340,0x0006,0x303C,0x8000,0x6004,0x44FC,0x0001
|
||||
|
||||
| At this point (0x800), the Work RAM is clear, the VDP initialized, the
|
||||
| VRAM/VSRAM/CRAM cleared, the Z80 initialized, the 32X initialized,
|
||||
| both 32X framebuffers cleared, the 32X palette cleared, the SH2s
|
||||
| checked for a startup error, the adapter TV mode matches the MD TV
|
||||
| mode, and the ROM checksum checked. If any error is detected, the
|
||||
| carry is set, otherwise it is cleared. The 68000 main code is now
|
||||
| entered.
|
||||
|
||||
jmp __start+0x00880000+0x3F0
|
||||
|
||||
| 68000 General exception handler at 0x806
|
||||
|
||||
jmp __except+0x00880000+0x3F0
|
||||
|
||||
| 68000 Level 4 interrupt handler at 0x80C - HBlank IRQ
|
||||
|
||||
jmp __hblank+0x00880000+0x3F0
|
||||
|
||||
| 68000 Level 6 interrupt handler at 0x812 - VBlank IRQ
|
||||
|
||||
jmp __vblank+0x00880000+0x3F0
|
||||
|
||||
__except:
|
||||
move.l d0,-(sp)
|
||||
move.l 4(sp),d0 /* jump table return address */
|
||||
sub.w #0x206,d0 /* 0 = BusError, 6 = AddrError, etc */
|
||||
|
||||
| handle exception
|
||||
|
||||
move.l (sp)+,d0
|
||||
addq.l #4,sp /* pop jump table return address */
|
||||
rte
|
||||
|
||||
__hblank:
|
||||
rte
|
||||
|
||||
__vblank:
|
||||
move.l d0,-(sp)
|
||||
move.l 0xFF0FFC,d0
|
||||
beq.b 1f
|
||||
move.l a0,-(sp)
|
||||
movea.l d0,a0
|
||||
jmp (a0)
|
||||
1:
|
||||
move.l (sp)+,d0
|
||||
rte
|
||||
|
||||
|
||||
__start:
|
||||
move.b #0,0xA15107 /* clear RV - allow SH2 to access ROM */
|
||||
0:
|
||||
cmp.l #0x4D5F4F4B,0xA15120 /* M_OK */
|
||||
bne.b 0b /* wait for master ok */
|
||||
1:
|
||||
cmp.l #0x535F4F4B,0xA15124 /* S_OK */
|
||||
bne.b 1b /* wait for slave ok */
|
||||
|
||||
| init joyports
|
||||
move.b #0x40,0xA10009
|
||||
move.b #0x40,0xA1000B
|
||||
move.b #0x40,0xA10003
|
||||
move.b #0x40,0xA10005
|
||||
|
||||
| init MD VDP
|
||||
lea 0xC00004,a0
|
||||
move.w #0x8004,(a0) /* reg. 0 - Disable HBL INT */
|
||||
move.w #0x8174,(a0) /* reg. 1 - Enable display, VBL INT, DMA + 28 VCell size */
|
||||
move.w #0x8230,(a0) /* reg. 2 - Plane A =$30*$400=$C000 */
|
||||
move.w #0x832C,(a0) /* reg. 3 - Window =$2C*$400=$B000 */
|
||||
move.w #0x8407,(a0) /* reg. 4 - Plane B =$7*$2000=$E000 */
|
||||
move.w #0x855E,(a0) /* reg. 5 - sprite table begins at $BC00=$5E*$200 */
|
||||
move.w #0x8600,(a0) /* reg. 6 - not used */
|
||||
move.w #0x8700,(a0) /* reg. 7 - Background Color number*/
|
||||
move.w #0x8800,(a0) /* reg. 8 - not used */
|
||||
move.w #0x8900,(a0) /* reg. 9 - not used */
|
||||
move.w #0x8A01,(a0) /* reg 10 - HInterrupt timing */
|
||||
move.w #0x8B00,(a0) /* reg 11 - $0000abcd a=extr.int b=vscr cd=hscr */
|
||||
move.w #0x8C81,(a0) /* reg 12 - hcell mode + shadow/highight + interlaced mode (40 cell, no shadow, no interlace)*/
|
||||
move.w #0x8D2E,(a0) /* reg 13 - HScroll Table = $B800 */
|
||||
move.w #0x8E00,(a0) /* reg 14 - not used */
|
||||
move.w #0x8F02,(a0) /* reg 15 - auto increment data */
|
||||
move.w #0x9011,(a0) /* reg 16 - scrl screen v&h size (64x64) */
|
||||
move.w #0x9100,(a0) /* reg 17 - window hpos */
|
||||
move.w #0x92FF,(a0) /* reg 18 - window vpos */
|
||||
|
||||
| Copy 68000 main loop to Work RAM to keep contention for the ROM with
|
||||
| SH2s to a minimum.
|
||||
lea __m68k_start(pc),a0
|
||||
lea 0x00FF1000,a1
|
||||
move.w #__m68k_end-__m68k_start-1,d0
|
||||
cpyloop:
|
||||
move.b (a0)+,(a1)+
|
||||
dbra d0,cpyloop
|
||||
|
||||
move.w #0,0xA15128 /* controller 1 */
|
||||
move.w #0,0xA1512A /* controller 2 */
|
||||
| look for mouse
|
||||
lea 0xA10003,a0
|
||||
0:
|
||||
bsr get_mky
|
||||
cmpi.l #-2,d0
|
||||
beq.b 0b /* timeout */
|
||||
cmpi.l #-1,d0
|
||||
beq.b 1f /* no mouse */
|
||||
move.w #0xF001,0xA15128 /* mouse in port 1 */
|
||||
1:
|
||||
lea 2(a0),a0
|
||||
2:
|
||||
bsr get_mky
|
||||
cmpi.l #-2,d0
|
||||
beq.b 2b /* timeout */
|
||||
cmpi.l #-1,d0
|
||||
beq.b 3f /* no mouse */
|
||||
move.w #0xF001,0xA1512A /* mouse in port 2 */
|
||||
3:
|
||||
move.l #0,0xA1512C /* clear the vblank count */
|
||||
|
||||
| jump to main loop in Work RAM
|
||||
jmp 0xFF1000.l
|
||||
|
||||
| this block of code must be pc relative as it's copied into Work RAM
|
||||
|
||||
__m68k_start:
|
||||
move.b #1,0xA15107 /* set RV */
|
||||
move.b #2,0xA130F1 /* SRAM disabled, write protected */
|
||||
move.b #0,0xA15107 /* clear RV */
|
||||
|
||||
move.w 0xA15100,d0
|
||||
or.w #0x8000,d0
|
||||
move.w d0,0xA15100 /* set FM - allow SH2 access to MARS hw */
|
||||
move.l #0,0xA15120 /* let Master SH2 run */
|
||||
|
||||
lea vert_blank(pc),a0
|
||||
move.l a0,0xFF0FFC /* set vertical blank interrupt handler */
|
||||
move.w #0x2000,sr /* enable interrupts */
|
||||
|
||||
main_loop:
|
||||
move.w 0xA15120,d0 /* get COMM0 */
|
||||
bne.b handle_req
|
||||
|
||||
| any other 68000 tasks here
|
||||
|
||||
bra.b main_loop
|
||||
|
||||
| process request from Master SH2
|
||||
handle_req:
|
||||
cmpi.w #0x01FF,d0
|
||||
bls read_sram
|
||||
cmpi.w #0x02FF,d0
|
||||
bls write_sram
|
||||
cmpi.w #0x03FF,d0
|
||||
bls start_music
|
||||
cmpi.w #0x04FF,d0
|
||||
bls stop_music
|
||||
cmpi.w #0x05FF,d0
|
||||
bls read_mouse
|
||||
| unknown command
|
||||
move.w #0,0xA15120 /* done */
|
||||
bra.b main_loop
|
||||
|
||||
read_sram:
|
||||
move.w #0x2700,sr /* disable ints */
|
||||
moveq #0,d1
|
||||
moveq #0,d0
|
||||
move.w 0xA15122,d0 /* COMM2 holds offset */
|
||||
lea 0x200000,a0
|
||||
move.b #1,0xA15107 /* set RV */
|
||||
move.b #3,0xA130F1 /* SRAM enabled, write protected */
|
||||
move.b 1(a0,d0.l),d1 /* read SRAM */
|
||||
move.b #2,0xA130F1 /* SRAM disabled, write protected */
|
||||
move.b #0,0xA15107 /* clear RV */
|
||||
move.w d1,0xA15122 /* COMM2 holds return byte */
|
||||
move.w #0,0xA15120 /* done */
|
||||
move.w #0x2000,sr /* enable ints */
|
||||
bra main_loop
|
||||
|
||||
write_sram:
|
||||
move.w #0x2700,sr /* disable ints */
|
||||
moveq #0,d1
|
||||
move.w 0xA15122,d1 /* COMM2 holds offset */
|
||||
lea 0x200000,a0
|
||||
move.b #1,0xA15107 /* set RV */
|
||||
move.b #1,0xA130F1 /* SRAM enabled, write enabled */
|
||||
move.b d0,1(a0,d1.l) /* write SRAM */
|
||||
move.b #2,0xA130F1 /* SRAM disabled, write protected */
|
||||
move.b #0,0xA15107 /* clear RV */
|
||||
move.w #0,0xA15120 /* done */
|
||||
move.w #0x2000,sr /* enable ints */
|
||||
bra main_loop
|
||||
|
||||
set_rom_bank:
|
||||
move.l a0,d3
|
||||
swap d3
|
||||
lsr.w #4,d3
|
||||
andi.w #3,d3
|
||||
move.w d3,0xA15104 /* set ROM bank select */
|
||||
move.l a0,d3
|
||||
andi.l #0x0FFFFF,d3
|
||||
ori.l #0x900000,d3
|
||||
movea.l d3,a1
|
||||
rts
|
||||
|
||||
start_music:
|
||||
stop_music:
|
||||
move.w #0,0xA15120 /* done */
|
||||
bra main_loop
|
||||
|
||||
read_mouse:
|
||||
tst.b d0
|
||||
bne.b 1f /* skip port 1 */
|
||||
|
||||
move.w 0xA15128,d0
|
||||
andi.w #0xF001,d0
|
||||
cmpi.w #0xF001,d0
|
||||
bne.b 1f /* no mouse in port 1 */
|
||||
lea 0xA10003,a0
|
||||
bsr get_mky
|
||||
bset #31,d0
|
||||
move.w d0,0xA15122
|
||||
swap d0
|
||||
move.w d0,0xA15120
|
||||
0:
|
||||
move.w 0xA15120,d0
|
||||
bne.b 0b /* wait for SH2 to read mouse value */
|
||||
bra main_loop
|
||||
1:
|
||||
move.w 0xA1512A,d0
|
||||
andi.w #0xF001,d0
|
||||
cmpi.w #0xF001,d0
|
||||
bne.b 3f /* no mouse in port 2 */
|
||||
lea 0xA10005,a0
|
||||
bsr get_mky
|
||||
bset #31,d0
|
||||
move.w d0,0xA15122
|
||||
swap d0
|
||||
move.w d0,0xA15120
|
||||
2:
|
||||
move.w 0xA15120,d0
|
||||
bne.b 2b /* wait for SH2 to read mouse value */
|
||||
bra main_loop
|
||||
3:
|
||||
move.l #-1,d0 /* no mouse */
|
||||
move.w d0,0xA15122
|
||||
swap d0
|
||||
move.w d0,0xA15120
|
||||
4:
|
||||
move.w 0xA15120,d0
|
||||
bne.b 4b /* wait for SH2 to read mouse value */
|
||||
bra main_loop
|
||||
|
||||
|
||||
vert_blank:
|
||||
move.l d1,-(sp)
|
||||
move.l d2,-(sp)
|
||||
|
||||
/* read controllers */
|
||||
move.w 0xA15128,d0
|
||||
andi.w #0xF000,d0
|
||||
cmpi.w #0xF000,d0
|
||||
beq.b 0f /* no pad in port 1 (or mouse) */
|
||||
lea 0xA10003,a0
|
||||
bsr.b get_pad
|
||||
move.w d2,0xA15128 /* controller 1 current value */
|
||||
0:
|
||||
move.w 0xA1512A,d0
|
||||
andi.w #0xF000,d0
|
||||
cmpi.w #0xF000,d0
|
||||
beq.b 1f /* no pad in port 2 (or mouse) */
|
||||
lea 0xA10005,a0
|
||||
bsr.b get_pad
|
||||
move.w d2,0xA1512A /* controller 2 current value */
|
||||
1:
|
||||
move.l 0xA1512C,d0
|
||||
addq.l #1,d0
|
||||
move.l d0,0xA1512C /* increment the vblank count */
|
||||
|
||||
move.l (sp)+,d2
|
||||
move.l (sp)+,d1
|
||||
movea.l (sp)+,a0
|
||||
move.l (sp)+,d0
|
||||
rte
|
||||
|
||||
| get current pad value
|
||||
| entry: a0 = pad control port
|
||||
| exit: d2 = pad value (0 0 0 1 M X Y Z S A C B R L D U) or (0 0 0 0 0 0 0 0 S A C B R L D U)
|
||||
get_pad:
|
||||
bsr.b get_input /* - 0 s a 0 0 d u - 1 c b r l d u */
|
||||
move.w d0,d1
|
||||
andi.w #0x0C00,d0
|
||||
bne.b no_pad
|
||||
bsr.b get_input /* - 0 s a 0 0 d u - 1 c b r l d u */
|
||||
bsr.b get_input /* - 0 s a 0 0 0 0 - 1 c b m x y z */
|
||||
move.w d0,d2
|
||||
bsr.b get_input /* - 0 s a 1 1 1 1 - 1 c b r l d u */
|
||||
andi.w #0x0F00,d0 /* 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 */
|
||||
cmpi.w #0x0F00,d0
|
||||
beq.b common /* six button pad */
|
||||
move.w #0x010F,d2 /* three button pad */
|
||||
common:
|
||||
lsl.b #4,d2 /* - 0 s a 0 0 0 0 m x y z 0 0 0 0 */
|
||||
lsl.w #4,d2 /* 0 0 0 0 m x y z 0 0 0 0 0 0 0 0 */
|
||||
andi.w #0x303F,d1 /* 0 0 s a 0 0 0 0 0 0 c b r l d u */
|
||||
move.b d1,d2 /* 0 0 0 0 m x y z 0 0 c b r l d u */
|
||||
lsr.w #6,d1 /* 0 0 0 0 0 0 0 0 s a 0 0 0 0 0 0 */
|
||||
or.w d1,d2 /* 0 0 0 0 m x y z s a c b r l d u */
|
||||
eori.w #0x1FFF,d2 /* 0 0 0 1 M X Y Z S A C B R L D U */
|
||||
rts
|
||||
|
||||
no_pad:
|
||||
move.w #0xF000,d2
|
||||
rts
|
||||
|
||||
| read single phase from controller
|
||||
get_input:
|
||||
move.b #0x00,(a0)
|
||||
nop
|
||||
nop
|
||||
move.b (a0),d0
|
||||
move.b #0x40,(a0)
|
||||
lsl.w #8,d0
|
||||
move.b (a0),d0
|
||||
rts
|
||||
|
||||
| get current mouse value
|
||||
| entry: a0 = mouse control port
|
||||
| exit: d0 = mouse value (0 0 0 0 0 0 0 0 YO XO YS XS S M R L X7 X6 X5 X4 X3 X2 X1 X0 Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0) or -2 (timeout) or -1 (no mouse)
|
||||
get_mky:
|
||||
move.w sr,d2
|
||||
move.w #0x2700,sr /* disable ints */
|
||||
|
||||
move.b #0x60,6(a0) /* set direction bits */
|
||||
nop
|
||||
nop
|
||||
move.b #0x60,(a0) /* first phase of mouse packet */
|
||||
nop
|
||||
nop
|
||||
0:
|
||||
btst #4,(a0)
|
||||
beq.b 0b /* wait on handshake */
|
||||
move.b (a0),d0
|
||||
andi.b #15,d0
|
||||
bne mky_err /* not 0 means not mouse */
|
||||
|
||||
move.b #0x20,(a0) /* next phase */
|
||||
move.w #254,d1 /* number retries before timeout */
|
||||
1:
|
||||
btst #4,(a0)
|
||||
bne.b 2f /* handshake */
|
||||
dbra d1,1b
|
||||
bra timeout_err
|
||||
2:
|
||||
move.b (a0),d0
|
||||
andi.b #15,d0
|
||||
move.b #0,(a0) /* next phase */
|
||||
cmpi.b #11,d0
|
||||
bne mky_err /* not 11 means not mouse */
|
||||
3:
|
||||
btst #4,(a0)
|
||||
beq.b 4f /* handshake */
|
||||
dbra d1,3b
|
||||
bra timeout_err
|
||||
4:
|
||||
move.b (a0),d0 /* specs say should be 15 */
|
||||
nop
|
||||
nop
|
||||
move.b #0x20,(a0) /* next phase */
|
||||
nop
|
||||
nop
|
||||
5:
|
||||
btst #4,(a0)
|
||||
bne.b 6f
|
||||
dbra d1,5b
|
||||
bra timeout_err
|
||||
6:
|
||||
move.b (a0),d0 /* specs say should be 15 */
|
||||
nop
|
||||
nop
|
||||
move.b #0,(a0) /* next phase */
|
||||
moveq #0,d0 /* clear reg to hold packet */
|
||||
nop
|
||||
7:
|
||||
btst #4,(a0)
|
||||
beq.b 8f /* handshake */
|
||||
dbra d1,7b
|
||||
bra timeout_err
|
||||
8:
|
||||
move.b (a0),d0 /* YO XO YS XS */
|
||||
move.b #0x20,(a0) /* next phase */
|
||||
lsl.w #8,d0 /* save nibble */
|
||||
9:
|
||||
btst #4,(a0)
|
||||
bne.b 10f /* handshake */
|
||||
dbra d1,9b
|
||||
bra timeout_err
|
||||
10:
|
||||
move.b (a0),d0 /* S M R L */
|
||||
move.b #0,(a0) /* next phase */
|
||||
lsl.b #4,d0 /* YO XO YS XS S M R L 0 0 0 0 */
|
||||
lsl.l #4,d0 /* YO XO YS XS S M R L 0 0 0 0 0 0 0 0 */
|
||||
11:
|
||||
btst #4,(a0)
|
||||
beq.b 12f /* handshake */
|
||||
dbra d1,11b
|
||||
bra timeout_err
|
||||
12:
|
||||
move.b (a0),d0 /* X7 X6 X5 X4 */
|
||||
move.b #0x20,(a0) /* next phase */
|
||||
lsl.b #4,d0 /* YO XO YS XS S M R L X7 X6 X5 X4 0 0 0 0 */
|
||||
lsl.l #4,d0 /* YO XO YS XS S M R L X7 X6 X5 X4 0 0 0 0 0 0 0 0 */
|
||||
13:
|
||||
btst #4,(a0)
|
||||
bne.b 14f /* handshake */
|
||||
dbra d1,13b
|
||||
bra timeout_err
|
||||
14:
|
||||
move.b (a0),d0 /* X3 X2 X1 X0 */
|
||||
move.b #0,(a0) /* next phase */
|
||||
lsl.b #4,d0 /* YO XO YS XS S M R L X7 X6 X5 X4 X3 X2 X1 X0 0 0 0 0 */
|
||||
lsl.l #4,d0 /* YO XO YS XS S M R L X7 X6 X5 X4 X3 X2 X1 X0 0 0 0 0 0 0 0 0 */
|
||||
15:
|
||||
btst #4,(a0)
|
||||
beq.b 16f /* handshake */
|
||||
dbra d1,15b
|
||||
bra timeout_err
|
||||
16:
|
||||
move.b (a0),d0 /* Y7 Y6 Y5 Y4 */
|
||||
move.b #0x20,(a0) /* next phase */
|
||||
lsl.b #4,d0 /* YO XO YS XS S M R L X7 X6 X5 X4 X3 X2 X1 X0 Y7 Y6 Y5 Y4 0 0 0 0 */
|
||||
lsl.l #4,d0 /* YO XO YS XS S M R L X7 X6 X5 X4 X3 X2 X1 X0 Y7 Y6 Y5 Y4 0 0 0 0 0 0 0 0*/
|
||||
17:
|
||||
btst #4,(a0)
|
||||
beq.b 18f /* handshake */
|
||||
dbra d1,17b
|
||||
bra timeout_err
|
||||
18:
|
||||
move.b (a0),d0 /* Y3 Y2 Y1 Y0 */
|
||||
move.b #0x60,(a0) /* first phase */
|
||||
lsl.b #4,d0 /* YO XO YS XS S M R L X7 X6 X5 X4 X3 X2 X1 X0 Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 0 0 0 0 */
|
||||
lsr.l #4,d0 /* YO XO YS XS S M R L X7 X6 X5 X4 X3 X2 X1 X0 Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 */
|
||||
19:
|
||||
btst #4,(a0)
|
||||
beq.b 19b /* wait on handshake */
|
||||
|
||||
move.w d2,sr /* restore int status */
|
||||
rts
|
||||
|
||||
timeout_err:
|
||||
move.b #0x60,(a0) /* first phase */
|
||||
nop
|
||||
nop
|
||||
0:
|
||||
btst #4,(a0)
|
||||
beq.b 0b /* wait on handshake */
|
||||
|
||||
move.w d2,sr /* restore int status */
|
||||
moveq #-2,d0
|
||||
rts
|
||||
|
||||
mky_err:
|
||||
move.b #0x40,6(a0) /* set direction bits */
|
||||
nop
|
||||
nop
|
||||
move.b #0x40,(a0)
|
||||
|
||||
move.w d2,sr /* restore int status */
|
||||
moveq #-1,d0
|
||||
rts
|
||||
|
||||
__m68k_end:
|
||||
|
||||
.align 4
|
719
src/platform/32x/crt/sh2_crt0.s
Normal file
719
src/platform/32x/crt/sh2_crt0.s
Normal file
@ -0,0 +1,719 @@
|
||||
! SEGA 32X support code for SH2
|
||||
! by Chilly Willy
|
||||
! Rom header and SH2 init/exception code - must be first in object list
|
||||
|
||||
.text
|
||||
|
||||
! Standard MD Header at 0x000
|
||||
|
||||
.incbin "build/m68k_crt0.bin", 0, 0x3C0
|
||||
|
||||
! Standard Mars Header at 0x3C0
|
||||
|
||||
.ascii "OpenLara " /* module name */
|
||||
.long 0x00000000 /* version */
|
||||
.long __text_size /* Source (in ROM) */
|
||||
.long 0x00000000 /* Destination (in SDRAM) */
|
||||
.long __data_size /* Size */
|
||||
.long 0x06000240 /* Master SH2 Jump */
|
||||
.long 0x06000244 /* Slave SH2 Jump */
|
||||
.long 0x06000000 /* Master SH2 VBR */
|
||||
.long 0x06000120 /* Slave SH2 VBR */
|
||||
|
||||
! Standard MD startup code at 0x3F0
|
||||
|
||||
.incbin "build/m68k_crt1.bin"
|
||||
|
||||
|
||||
.data
|
||||
|
||||
! Master Vector Base Table at 0x06000000
|
||||
|
||||
.long mstart /* Cold Start PC */
|
||||
.long 0x0603FC00 /* Cold Start SP */
|
||||
.long mstart /* Manual Reset PC */
|
||||
.long 0x0603FC00 /* Manual Reset SP */
|
||||
.long main_err /* Illegal instruction */
|
||||
.long 0x00000000 /* reserved */
|
||||
.long main_err /* Invalid slot instruction */
|
||||
.long 0x20100400 /* reserved */
|
||||
.long 0x20100420 /* reserved */
|
||||
.long main_err /* CPU address error */
|
||||
.long main_err /* DMA address error */
|
||||
.long main_err /* NMI vector */
|
||||
.long main_err /* User break vector */
|
||||
.space 76 /* reserved */
|
||||
.long main_err /* TRAPA #32 */
|
||||
.long main_err /* TRAPA #33 */
|
||||
.long main_err /* TRAPA #34 */
|
||||
.long main_err /* TRAPA #35 */
|
||||
.long main_err /* TRAPA #36 */
|
||||
.long main_err /* TRAPA #37 */
|
||||
.long main_err /* TRAPA #38 */
|
||||
.long main_err /* TRAPA #39 */
|
||||
.long main_err /* TRAPA #40 */
|
||||
.long main_err /* TRAPA #41 */
|
||||
.long main_err /* TRAPA #42 */
|
||||
.long main_err /* TRAPA #43 */
|
||||
.long main_err /* TRAPA #44 */
|
||||
.long main_err /* TRAPA #45 */
|
||||
.long main_err /* TRAPA #46 */
|
||||
.long main_err /* TRAPA #47 */
|
||||
.long main_err /* TRAPA #48 */
|
||||
.long main_err /* TRAPA #49 */
|
||||
.long main_err /* TRAPA #50 */
|
||||
.long main_err /* TRAPA #51 */
|
||||
.long main_err /* TRAPA #52 */
|
||||
.long main_err /* TRAPA #53 */
|
||||
.long main_err /* TRAPA #54 */
|
||||
.long main_err /* TRAPA #55 */
|
||||
.long main_err /* TRAPA #56 */
|
||||
.long main_err /* TRAPA #57 */
|
||||
.long main_err /* TRAPA #58 */
|
||||
.long main_err /* TRAPA #59 */
|
||||
.long main_err /* TRAPA #60 */
|
||||
.long main_err /* TRAPA #61 */
|
||||
.long main_err /* TRAPA #62 */
|
||||
.long main_err /* TRAPA #63 */
|
||||
.long main_irq /* Level 1 IRQ */
|
||||
.long main_irq /* Level 2 & 3 IRQ's */
|
||||
.long main_irq /* Level 4 & 5 IRQ's */
|
||||
.long main_irq /* PWM interupt */
|
||||
.long main_irq /* Command interupt */
|
||||
.long main_irq /* H Blank interupt */
|
||||
.long main_irq /* V Blank interupt */
|
||||
.long main_irq /* Reset Button */
|
||||
|
||||
! Slave Vector Base Table at 0x06000120
|
||||
|
||||
.long sstart /* Cold Start PC */
|
||||
.long 0x06040000 /* Cold Start SP */
|
||||
.long sstart /* Manual Reset PC */
|
||||
.long 0x06040000 /* Manual Reset SP */
|
||||
.long slav_err /* Illegal instruction */
|
||||
.long 0x00000000 /* reserved */
|
||||
.long slav_err /* Invalid slot instruction */
|
||||
.long 0x20100400 /* reserved */
|
||||
.long 0x20100420 /* reserved */
|
||||
.long slav_err /* CPU address error */
|
||||
.long slav_err /* DMA address error */
|
||||
.long slav_err /* NMI vector */
|
||||
.long slav_err /* User break vector */
|
||||
.space 76 /* reserved */
|
||||
.long slav_err /* TRAPA #32 */
|
||||
.long slav_err /* TRAPA #33 */
|
||||
.long slav_err /* TRAPA #34 */
|
||||
.long slav_err /* TRAPA #35 */
|
||||
.long slav_err /* TRAPA #36 */
|
||||
.long slav_err /* TRAPA #37 */
|
||||
.long slav_err /* TRAPA #38 */
|
||||
.long slav_err /* TRAPA #39 */
|
||||
.long slav_err /* TRAPA #40 */
|
||||
.long slav_err /* TRAPA #41 */
|
||||
.long slav_err /* TRAPA #42 */
|
||||
.long slav_err /* TRAPA #43 */
|
||||
.long slav_err /* TRAPA #44 */
|
||||
.long slav_err /* TRAPA #45 */
|
||||
.long slav_err /* TRAPA #46 */
|
||||
.long slav_err /* TRAPA #47 */
|
||||
.long slav_err /* TRAPA #48 */
|
||||
.long slav_err /* TRAPA #49 */
|
||||
.long slav_err /* TRAPA #50 */
|
||||
.long slav_err /* TRAPA #51 */
|
||||
.long slav_err /* TRAPA #52 */
|
||||
.long slav_err /* TRAPA #53 */
|
||||
.long slav_err /* TRAPA #54 */
|
||||
.long slav_err /* TRAPA #55 */
|
||||
.long slav_err /* TRAPA #56 */
|
||||
.long slav_err /* TRAPA #57 */
|
||||
.long slav_err /* TRAPA #58 */
|
||||
.long slav_err /* TRAPA #59 */
|
||||
.long slav_err /* TRAPA #60 */
|
||||
.long slav_err /* TRAPA #61 */
|
||||
.long slav_err /* TRAPA #62 */
|
||||
.long slav_err /* TRAPA #63 */
|
||||
.long slav_irq /* Level 1 IRQ */
|
||||
.long slav_irq /* Level 2 & 3 IRQ's */
|
||||
.long slav_irq /* Level 4 & 5 IRQ's */
|
||||
.long slav_irq /* PWM interupt */
|
||||
.long slav_irq /* Command interupt */
|
||||
.long slav_irq /* H Blank interupt */
|
||||
.long slav_irq /* V Blank interupt */
|
||||
.long slav_irq /* Reset Button */
|
||||
|
||||
! The main SH2 starts here at 0x06000240
|
||||
|
||||
mstart:
|
||||
bra mcont
|
||||
nop
|
||||
|
||||
! The slave SH2 starts here at 0x06000244
|
||||
|
||||
sstart:
|
||||
bra scont
|
||||
nop
|
||||
|
||||
! Each section of code below has its own data table so that the code
|
||||
! can be extended without worrying about the offsets becoming too big.
|
||||
! This results in duplicate entries, but not so many that we care. :)
|
||||
|
||||
mcont:
|
||||
! clear interrupt flags
|
||||
mov.l _master_int_clr,r1
|
||||
mov.w r0,@-r1 /* PWM INT clear */
|
||||
mov.w r0,@r1
|
||||
mov.w r0,@-r1 /* CMD INT clear */
|
||||
mov.w r0,@r1
|
||||
mov.w r0,@-r1 /* H INT clear */
|
||||
mov.w r0,@r1
|
||||
mov.w r0,@-r1 /* V INT clear */
|
||||
mov.w r0,@r1
|
||||
mov.w r0,@-r1 /* VRES INT clear */
|
||||
mov.w r0,@r1
|
||||
|
||||
mov.l _master_stk,r15
|
||||
! purge cache and turn it off
|
||||
mov.l _master_cctl,r0
|
||||
mov #0x10,r1
|
||||
mov.b r1,@r0
|
||||
|
||||
! clear bss
|
||||
mov #0,r0
|
||||
mov.l _master_bss_start,r1
|
||||
mov.l _master_bss_end,r2
|
||||
0:
|
||||
mov.l r0,@r1
|
||||
cmp/eq r1,r2
|
||||
bf/s 0b
|
||||
add #4,r1
|
||||
|
||||
! wait for 68000 to finish init
|
||||
mov.l _master_sts,r0
|
||||
mov.l _master_ok,r1
|
||||
1:
|
||||
mov.l @r0,r2
|
||||
nop
|
||||
nop
|
||||
cmp/eq r1,r2
|
||||
bt 1b
|
||||
|
||||
! let Slave SH2 run
|
||||
mov #0,r1
|
||||
mov.l r1,@(4,r0) /* clear slave status */
|
||||
|
||||
mov #0x80,r0
|
||||
mov.l _master_adapter,r1
|
||||
mov.b r0,@r1 /* set FM */
|
||||
mov #0x00,r0
|
||||
mov.b r0,@(1,r1) /* set int enables */
|
||||
mov #0x20,r0
|
||||
ldc r0,sr /* allow ints */
|
||||
|
||||
! purge cache, turn it on, and run main()
|
||||
mov.l _master_cctl,r0
|
||||
mov #0x11,r1
|
||||
mov.b r1,@r0
|
||||
mov.l _master_go,r0
|
||||
jmp @r0
|
||||
nop
|
||||
|
||||
.align 2
|
||||
_master_int_clr:
|
||||
.long 0x2000401E /* one word passed last int clr reg */
|
||||
_master_stk:
|
||||
.long 0x0603FC00 /* Cold Start SP */
|
||||
_master_sts:
|
||||
.long 0x20004020
|
||||
_master_ok:
|
||||
.ascii "M_OK"
|
||||
_master_adapter:
|
||||
.long 0x20004000
|
||||
_master_cctl:
|
||||
.long 0xFFFFFE92
|
||||
_master_go:
|
||||
.long _main
|
||||
|
||||
_master_bss_start:
|
||||
.long __bss_start
|
||||
_master_bss_end:
|
||||
.long __bss_end
|
||||
|
||||
scont:
|
||||
! clear interrupt flags
|
||||
mov.l _slave_int_clr,r1
|
||||
mov.w r0,@-r1 /* PWM INT clear */
|
||||
mov.w r0,@r1
|
||||
mov.w r0,@-r1 /* CMD INT clear */
|
||||
mov.w r0,@r1
|
||||
mov.w r0,@-r1 /* H INT clear */
|
||||
mov.w r0,@r1
|
||||
mov.w r0,@-r1 /* V INT clear */
|
||||
mov.w r0,@r1
|
||||
mov.w r0,@-r1 /* VRES INT clear */
|
||||
mov.w r0,@r1
|
||||
|
||||
mov.l _slave_stk,r15
|
||||
! wait for Master SH2 and 68000 to finish init
|
||||
mov.l _slave_sts,r0
|
||||
mov.l _slave_ok,r1
|
||||
1:
|
||||
mov.l @r0,r2
|
||||
nop
|
||||
nop
|
||||
cmp/eq r1,r2
|
||||
bt 1b
|
||||
|
||||
mov.l _slave_adapter,r1
|
||||
mov #0x00,r0
|
||||
mov.b r0,@(1,r1) /* set int enables (different from master despite same address!) */
|
||||
mov #0x20,r0
|
||||
ldc r0,sr /* allow ints */
|
||||
|
||||
! purge cache, turn it on, and run slave()
|
||||
mov.l _slave_cctl,r0
|
||||
mov #0x11,r1
|
||||
mov.b r1,@r0
|
||||
mov.l _slave_go,r0
|
||||
jmp @r0
|
||||
nop
|
||||
|
||||
.align 2
|
||||
_slave_int_clr:
|
||||
.long 0x2000401E /* one word passed last int clr reg */
|
||||
_slave_stk:
|
||||
.long 0x06040000 /* Cold Start SP */
|
||||
_slave_sts:
|
||||
.long 0x20004024
|
||||
_slave_ok:
|
||||
.ascii "S_OK"
|
||||
_slave_adapter:
|
||||
.long 0x20004000
|
||||
_slave_cctl:
|
||||
.long 0xFFFFFE92
|
||||
_slave_go:
|
||||
.long _slave
|
||||
|
||||
! Master exception handler
|
||||
|
||||
main_err:
|
||||
rte
|
||||
nop
|
||||
|
||||
! Master IRQ handler
|
||||
|
||||
main_irq:
|
||||
mov.l r0,@-r15
|
||||
|
||||
stc sr,r0 /* SR holds IRQ level in I3-I0 */
|
||||
shlr2 r0
|
||||
and #0x38,r0
|
||||
cmp/eq #0x28,r0
|
||||
bt main_h_irq
|
||||
cmp/eq #0x18,r0
|
||||
bt main_pwm_irq
|
||||
cmp/eq #0x30,r0
|
||||
bt main_v_irq
|
||||
cmp/eq #0x20,r0
|
||||
bt main_cmd_irq
|
||||
cmp/eq #0x38,r0
|
||||
bt main_vres_irq
|
||||
|
||||
mov.l @r15+,r0
|
||||
rte
|
||||
nop
|
||||
|
||||
main_v_irq:
|
||||
mov.l r1,@-r15
|
||||
|
||||
mov.l mvi_mars_adapter,r1
|
||||
mov.w r0,@(0x16,r1) /* clear V IRQ */
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
|
||||
! handle V IRQ
|
||||
|
||||
mov.l @r15+,r1
|
||||
mov.l @r15+,r0
|
||||
rte
|
||||
nop
|
||||
|
||||
.align 2
|
||||
mvi_mars_adapter:
|
||||
.long 0x20004000
|
||||
|
||||
main_h_irq:
|
||||
mov.l r1,@-r15
|
||||
|
||||
mov.l mhi_mars_adapter,r1
|
||||
mov.w r0,@(0x18,r1) /* clear H IRQ */
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
|
||||
! handle H IRQ
|
||||
|
||||
mov.l @r15+,r1
|
||||
mov.l @r15+,r0
|
||||
rte
|
||||
nop
|
||||
|
||||
.align 2
|
||||
mhi_mars_adapter:
|
||||
.long 0x20004000
|
||||
|
||||
main_cmd_irq:
|
||||
mov.l r1,@-r15
|
||||
|
||||
mov.l mci_mars_adapter,r1
|
||||
mov.w r0,@(0x1A,r1) /* clear CMD IRQ */
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
|
||||
! handle CMD IRQ
|
||||
|
||||
mov.l @r15+,r1
|
||||
mov.l @r15+,r0
|
||||
rte
|
||||
nop
|
||||
|
||||
.align 2
|
||||
mci_mars_adapter:
|
||||
.long 0x20004000
|
||||
|
||||
main_pwm_irq:
|
||||
mov.l r1,@-r15
|
||||
|
||||
mov.l mpi_mars_adapter,r1
|
||||
mov.w r0,@(0x1C,r1) /* clear PWM IRQ */
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
|
||||
! handle PWM IRQ
|
||||
|
||||
mov.l @r15+,r1
|
||||
mov.l @r15+,r0
|
||||
rte
|
||||
nop
|
||||
|
||||
.align 2
|
||||
mpi_mars_adapter:
|
||||
.long 0x20004000
|
||||
|
||||
main_vres_irq:
|
||||
mov.l mvri_mars_adapter,r1
|
||||
mov.w r0,@(0x14,r1) /* clear VRES IRQ */
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
|
||||
mov #0x0F,r0
|
||||
shll2 r0
|
||||
shll2 r0
|
||||
ldc r0,sr /* disallow ints */
|
||||
|
||||
mov.l mvri_master_stk,r15
|
||||
mov.l mvri_master_vres,r0
|
||||
jmp @r0
|
||||
nop
|
||||
|
||||
.align 2
|
||||
mvri_mars_adapter:
|
||||
.long 0x20004000
|
||||
mvri_master_stk:
|
||||
.long 0x0603FC00 /* Cold Start SP */
|
||||
mvri_master_vres:
|
||||
.long main_reset
|
||||
|
||||
! Slave exception handler
|
||||
|
||||
slav_err:
|
||||
rte
|
||||
nop
|
||||
|
||||
! Slave IRQ handler
|
||||
|
||||
slav_irq:
|
||||
mov.l r0,@-r15
|
||||
|
||||
stc sr,r0 /* SR holds IRQ level I3-I0 */
|
||||
shlr2 r0
|
||||
and #0x38,r0
|
||||
cmp/eq #0x28,r0
|
||||
bt slav_h_irq
|
||||
cmp/eq #0x18,r0
|
||||
bt slav_pwm_irq
|
||||
cmp/eq #0x30,r0
|
||||
bt slav_v_irq
|
||||
cmp/eq #0x20,r0
|
||||
bt slav_cmd_irq
|
||||
cmp/eq #0x38,r0
|
||||
bt slav_vres_irq
|
||||
|
||||
mov.l @r15+,r0
|
||||
rte
|
||||
nop
|
||||
|
||||
slav_v_irq:
|
||||
mov.l r1,@-r15
|
||||
|
||||
mov.l svi_mars_adapter,r1
|
||||
mov.w r0,@(0x16,r1) /* clear V IRQ */
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
|
||||
! handle V IRQ
|
||||
|
||||
mov.l @r15+,r1
|
||||
mov.l @r15+,r0
|
||||
rte
|
||||
nop
|
||||
|
||||
.align 2
|
||||
svi_mars_adapter:
|
||||
.long 0x20004000
|
||||
|
||||
slav_h_irq:
|
||||
mov.l r1,@-r15
|
||||
|
||||
mov.l shi_mars_adapter,r1
|
||||
mov.w r0,@(0x18,r1) /* clear H IRQ */
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
|
||||
! handle H IRQ
|
||||
|
||||
mov.l @r15+,r1
|
||||
mov.l @r15+,r0
|
||||
rte
|
||||
nop
|
||||
|
||||
.align 2
|
||||
shi_mars_adapter:
|
||||
.long 0x20004000
|
||||
|
||||
slav_cmd_irq:
|
||||
mov.l r1,@-r15
|
||||
|
||||
mov.l sci_mars_adapter,r1
|
||||
mov.w r0,@(0x1A,r1) /* clear CMD IRQ */
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
|
||||
! handle CMD IRQ
|
||||
|
||||
mov.l @r15+,r1
|
||||
mov.l @r15+,r0
|
||||
rte
|
||||
nop
|
||||
|
||||
.align 2
|
||||
sci_mars_adapter:
|
||||
.long 0x20004000
|
||||
|
||||
slav_pwm_irq:
|
||||
mov.l r1,@-r15
|
||||
|
||||
mov.l spi_mars_adapter,r1
|
||||
mov.w r0,@(0x1C,r1) /* clear PWM IRQ */
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
|
||||
! handle PWM IRQ
|
||||
|
||||
mov.l @r15+,r1
|
||||
mov.l @r15+,r0
|
||||
rte
|
||||
nop
|
||||
|
||||
.align 2
|
||||
spi_mars_adapter:
|
||||
.long 0x20004000
|
||||
|
||||
slav_vres_irq:
|
||||
mov.l svri_mars_adapter,r1
|
||||
mov.w r0,@(0x14,r1) /* clear VRES IRQ */
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
|
||||
mov #0x0F,r0
|
||||
shll2 r0
|
||||
shll2 r0
|
||||
ldc r0,sr /* disallow ints */
|
||||
|
||||
mov.l svri_slave_stk,r15
|
||||
mov.l svri_slave_vres,r0
|
||||
jmp @r0
|
||||
nop
|
||||
|
||||
.align 2
|
||||
svri_mars_adapter:
|
||||
.long 0x20004000
|
||||
svri_slave_stk:
|
||||
.long 0x06040000 /* Cold Start SP */
|
||||
svri_slave_vres:
|
||||
.long slav_reset
|
||||
|
||||
|
||||
! Fast memcpy function - copies longs, runs from sdram for speed
|
||||
! On entry: r4 = dst, r5 = src, r6 = len (in longs)
|
||||
|
||||
.align 4
|
||||
.global _fast_memcpy
|
||||
_fast_memcpy:
|
||||
mov.l @r5+,r3
|
||||
mov.l r3,@r4
|
||||
dt r6
|
||||
bf/s _fast_memcpy
|
||||
add #4,r4
|
||||
rts
|
||||
nop
|
||||
|
||||
! Fast memset function - sets long values, runs from sdram for speed
|
||||
! On entry: r4 = dst, r5 = value, r6 = len (in longs)
|
||||
|
||||
.align 4
|
||||
.global _fast_memset
|
||||
_fast_memset:
|
||||
mov.l r5,@r4
|
||||
dt r6
|
||||
bf/s _fast_memset
|
||||
add #4,r4
|
||||
rts
|
||||
nop
|
||||
|
||||
! Cache clear line function
|
||||
! On entry: r4 = ptr - should be 16 byte aligned
|
||||
|
||||
.align 4
|
||||
.global _CacheClearLine
|
||||
_CacheClearLine:
|
||||
mov.l _cache_flush,r0
|
||||
or r0,r4
|
||||
mov #0,r0
|
||||
mov.l r0,@r4
|
||||
rts
|
||||
nop
|
||||
|
||||
.align 2
|
||||
|
||||
_cache_flush:
|
||||
.long 0x40000000
|
||||
|
||||
! Cache control function
|
||||
! On entry: r4 = cache mode => 0x10 = CP, 0x08 = TW, 0x01 = CE
|
||||
|
||||
.align 4
|
||||
.global _CacheControl
|
||||
_CacheControl:
|
||||
mov.l _sh2_cctl,r0
|
||||
mov.b r4,@r0
|
||||
rts
|
||||
nop
|
||||
|
||||
.align 2
|
||||
|
||||
_sh2_cctl:
|
||||
.long 0xFFFFFE92
|
||||
|
||||
main_reset:
|
||||
! do any master SH2 specific reset code here
|
||||
|
||||
mov.l slav_st,r0
|
||||
mov.l slav_ok,r1
|
||||
0:
|
||||
mov.l @r0,r2
|
||||
nop
|
||||
nop
|
||||
cmp/eq r1,r2
|
||||
bf 0b /* wait for slave */
|
||||
|
||||
! recopy rom data to sdram
|
||||
|
||||
mov.l rom_header,r1
|
||||
mov.l @r1,r2 /* src relative to start of rom */
|
||||
mov.l @(4,r1),r3 /* dst relative to start of sdram */
|
||||
mov.l @(8,r1),r4 /* size (longword aligned) */
|
||||
mov.l rom_start,r1
|
||||
add r1,r2
|
||||
mov.l sdram_start,r1
|
||||
add r1,r3
|
||||
shlr2 r4 /* number of longs */
|
||||
add #-1,r4
|
||||
1:
|
||||
mov.l @r2+,r0
|
||||
mov.l r0,@r3
|
||||
add #4,r3
|
||||
dt r4
|
||||
bf 1b
|
||||
|
||||
mov.l main_st,r0
|
||||
mov.l main_ok,r1
|
||||
mov.l r1,@r0 /* tell everyone reset complete */
|
||||
|
||||
mov.l main_go,r0
|
||||
jmp @r0
|
||||
nop
|
||||
|
||||
slav_reset:
|
||||
! do any slave SH2 specific reset code here
|
||||
|
||||
mov.l slav_st,r0
|
||||
mov.l slav_ok,r1
|
||||
mov.l r1,@r0 /* tell master to start reset */
|
||||
|
||||
mov.l main_st,r0
|
||||
mov.l main_ok,r1
|
||||
0:
|
||||
mov.l @r0,r2
|
||||
nop
|
||||
nop
|
||||
cmp/eq r1,r2
|
||||
bf 0b /* wait for master to do the work */
|
||||
|
||||
mov.l slav_go,r0
|
||||
jmp @r0
|
||||
nop
|
||||
|
||||
.align 2
|
||||
main_st:
|
||||
.long 0x20004020
|
||||
main_ok:
|
||||
.ascii "M_OK"
|
||||
main_go:
|
||||
.long mstart
|
||||
rom_header:
|
||||
.long 0x220003D4
|
||||
rom_start:
|
||||
.long 0x22000000
|
||||
sdram_start:
|
||||
.long 0x26000000
|
||||
|
||||
slav_st:
|
||||
.long 0x20004024
|
||||
slav_ok:
|
||||
.ascii "S_OK"
|
||||
slav_go:
|
||||
.long sstart
|
||||
|
||||
|
||||
.global _start
|
||||
_start:
|
||||
|
3
src/platform/32x/deploy.sh
Normal file
3
src/platform/32x/deploy.sh
Normal file
@ -0,0 +1,3 @@
|
||||
make clean
|
||||
make
|
||||
/c/RetroArch/retroarch.exe -L C:\\RetroArch\\cores\\picodrive_libretro.dll OpenLara.32x
|
149
src/platform/32x/main.cpp
Normal file
149
src/platform/32x/main.cpp
Normal file
@ -0,0 +1,149 @@
|
||||
const void* TRACKS_IMA;
|
||||
const void* TITLE_SCR;
|
||||
|
||||
extern void* LEVEL1_PKD;
|
||||
|
||||
#include "game.h"
|
||||
|
||||
int32 fps;
|
||||
|
||||
void osSetPalette(const uint16* palette)
|
||||
{
|
||||
void *dst = (void*)&MARS_CRAM;
|
||||
memcpy(dst, palette, 256 * 2);
|
||||
}
|
||||
|
||||
int32 osGetSystemTimeMS()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool osSaveSettings()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool osLoadSettings()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool osCheckSave()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool osSaveGame()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool osLoadGame()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void osJoyVibrate(int32 index, int32 L, int32 R)
|
||||
{
|
||||
// nope
|
||||
}
|
||||
|
||||
void updateInput()
|
||||
{
|
||||
keys = 0;
|
||||
|
||||
uint16 mask = MARS_SYS_COMM8;
|
||||
if (mask & SEGA_CTRL_UP) keys |= IK_UP;
|
||||
if (mask & SEGA_CTRL_RIGHT) keys |= IK_RIGHT;
|
||||
if (mask & SEGA_CTRL_DOWN) keys |= IK_DOWN;
|
||||
if (mask & SEGA_CTRL_LEFT) keys |= IK_LEFT;
|
||||
if (mask & SEGA_CTRL_A) keys |= IK_A;
|
||||
if (mask & SEGA_CTRL_B) keys |= IK_B;
|
||||
if (mask & SEGA_CTRL_C) keys |= IK_C;
|
||||
if (mask & SEGA_CTRL_X) keys |= IK_X;
|
||||
if (mask & SEGA_CTRL_Y) keys |= IK_Y;
|
||||
if (mask & SEGA_CTRL_Z) keys |= IK_Z;
|
||||
if (mask & SEGA_CTRL_START) keys |= IK_START;
|
||||
if (mask & SEGA_CTRL_MODE) keys |= IK_SELECT;
|
||||
}
|
||||
|
||||
void* osLoadLevel(const char* name)
|
||||
{
|
||||
return (void*)LEVEL1_PKD;
|
||||
}
|
||||
|
||||
uint16 pageIndex = 0;
|
||||
|
||||
void pageWait()
|
||||
{
|
||||
while ((MARS_VDP_FBCTL & MARS_VDP_FS) != pageIndex);
|
||||
}
|
||||
|
||||
void pageFlip()
|
||||
{
|
||||
pageIndex ^= 1;
|
||||
MARS_VDP_FBCTL = pageIndex;
|
||||
}
|
||||
|
||||
extern "C" void slave(void)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
while ((MARS_SYS_INTMSK & MARS_SH2_ACCESS_VDP) == 0);
|
||||
MARS_VDP_DISPMODE = MARS_224_LINES | MARS_VDP_MODE_256;
|
||||
|
||||
for (int32 page = 0; page < 2; page++)
|
||||
{
|
||||
pageFlip();
|
||||
pageWait();
|
||||
|
||||
volatile uint16* lineTable = &MARS_FRAMEBUFFER;
|
||||
uint16 wordOffset = 0x100;
|
||||
for (int32 i = 0; i < 224; i++, wordOffset += FRAME_WIDTH / 2)
|
||||
{
|
||||
lineTable[i] = wordOffset;
|
||||
}
|
||||
|
||||
uint8* fb = (uint8*)(lineTable + 0x100);
|
||||
memset(fb, 0, 0x10000 - 0x200);
|
||||
}
|
||||
|
||||
gameInit(gLevelInfo[gLevelID].name);
|
||||
|
||||
int32 lastFrame = (MARS_SYS_COMM12 >> 1) - 1;
|
||||
|
||||
while (1)
|
||||
{
|
||||
int32 frame = MARS_SYS_COMM12;
|
||||
|
||||
if (!(MARS_VDP_DISPMODE & MARS_NTSC_FORMAT))
|
||||
{
|
||||
frame = frame * 6 / 5; // PAL fix
|
||||
}
|
||||
|
||||
frame >>= 1;
|
||||
|
||||
int32 delta = frame - lastFrame;
|
||||
|
||||
if (!delta)
|
||||
continue;
|
||||
|
||||
lastFrame = frame;
|
||||
|
||||
updateInput();
|
||||
|
||||
gameUpdate(delta);
|
||||
|
||||
pageWait();
|
||||
|
||||
gameRender();
|
||||
|
||||
pageFlip();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
809
src/platform/32x/rasterizer.h
Normal file
809
src/platform/32x/rasterizer.h
Normal file
@ -0,0 +1,809 @@
|
||||
#ifndef H_RASTERIZER_MODE13
|
||||
#define H_RASTERIZER_MODE13
|
||||
|
||||
#include "common.h"
|
||||
|
||||
extern uint8 gLightmap[256 * 32];
|
||||
extern const uint8* gTile;
|
||||
|
||||
#define rasterizeS rasterizeS_c
|
||||
#define rasterizeF rasterizeF_c
|
||||
#define rasterizeG rasterizeG_c
|
||||
#define rasterizeFT rasterizeFT_c
|
||||
#define rasterizeGT rasterizeGT_c
|
||||
#define rasterizeFTA rasterizeFTA_c
|
||||
#define rasterizeGTA rasterizeGTA_c
|
||||
#define rasterizeSprite rasterizeSprite_c
|
||||
#define rasterizeLineH rasterizeLineH_c
|
||||
#define rasterizeLineV rasterizeLineV_c
|
||||
#define rasterizeFillS rasterizeFillS_c
|
||||
|
||||
void rasterizeS_c(uint16* pixel, const VertexLink* L, const VertexLink* R)
|
||||
{
|
||||
const uint8* ft_lightmap = &gLightmap[0x1A00];
|
||||
|
||||
int32 Lh = 0;
|
||||
int32 Rh = 0;
|
||||
int32 Ldx = 0;
|
||||
int32 Rdx = 0;
|
||||
int32 Rx;
|
||||
int32 Lx;
|
||||
|
||||
while (1)
|
||||
{
|
||||
while (!Lh)
|
||||
{
|
||||
const VertexLink* N = L + L->prev;
|
||||
|
||||
if (N->v.y < L->v.y) return;
|
||||
|
||||
Lh = N->v.y - L->v.y;
|
||||
Lx = L->v.x;
|
||||
|
||||
if (Lh > 1)
|
||||
{
|
||||
uint32 tmp = FixedInvU(Lh);
|
||||
Ldx = tmp * (N->v.x - Lx);
|
||||
}
|
||||
|
||||
Lx <<= 16;
|
||||
L = N;
|
||||
}
|
||||
|
||||
while (!Rh)
|
||||
{
|
||||
const VertexLink* N = R + R->next;
|
||||
|
||||
if (N->v.y < R->v.y) return;
|
||||
|
||||
Rh = N->v.y - R->v.y;
|
||||
Rx = R->v.x;
|
||||
|
||||
if (Rh > 1) {
|
||||
uint32 tmp = FixedInvU(Rh);
|
||||
Rdx = tmp * (N->v.x - Rx);
|
||||
}
|
||||
|
||||
Rx <<= 16;
|
||||
R = N;
|
||||
}
|
||||
|
||||
int32 h = X_MIN(Lh, Rh);
|
||||
Lh -= h;
|
||||
Rh -= h;
|
||||
|
||||
while (h--)
|
||||
{
|
||||
int32 x1 = Lx >> 16;
|
||||
int32 x2 = Rx >> 16;
|
||||
|
||||
int32 width = x2 - x1;
|
||||
|
||||
if (width > 0)
|
||||
{
|
||||
volatile uint8* ptr = (uint8*)pixel + x1;
|
||||
|
||||
if (x1 & 1)
|
||||
{
|
||||
ptr[0] = ft_lightmap[ptr[0]];
|
||||
ptr++;
|
||||
width--;
|
||||
}
|
||||
|
||||
if (width & 1)
|
||||
{
|
||||
width--;
|
||||
ptr[width] = ft_lightmap[ptr[width]];
|
||||
}
|
||||
|
||||
while (width)
|
||||
{
|
||||
uint16 p = *(uint16*)ptr;
|
||||
|
||||
uint16 index = ft_lightmap[p & 0xFF];
|
||||
index |= ft_lightmap[p >> 8] << 8;
|
||||
|
||||
*(uint16*)ptr = index;
|
||||
ptr += 2;
|
||||
width -= 2;
|
||||
}
|
||||
}
|
||||
|
||||
pixel += VRAM_WIDTH;
|
||||
|
||||
Lx += Ldx;
|
||||
Rx += Rdx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void rasterizeF_c(uint16* pixel, const VertexLink* L, const VertexLink* R)
|
||||
{
|
||||
uint32 color = (uint32)R;
|
||||
color = gLightmap[(L->v.g << 8) | color];
|
||||
color |= (color << 8);
|
||||
|
||||
int32 Lh = 0;
|
||||
int32 Rh = 0;
|
||||
int32 Ldx = 0;
|
||||
int32 Rdx = 0;
|
||||
int32 Rx;
|
||||
int32 Lx;
|
||||
|
||||
R = L;
|
||||
|
||||
while (1)
|
||||
{
|
||||
while (!Lh)
|
||||
{
|
||||
const VertexLink* N = L + L->prev;
|
||||
|
||||
ASSERT(L->v.y >= 0);
|
||||
|
||||
if (N->v.y < L->v.y) return;
|
||||
|
||||
Lh = N->v.y - L->v.y;
|
||||
Lx = L->v.x;
|
||||
|
||||
if (Lh > 1)
|
||||
{
|
||||
uint32 tmp = FixedInvU(Lh);
|
||||
Ldx = tmp * (N->v.x - Lx);
|
||||
}
|
||||
|
||||
Lx <<= 16;
|
||||
L = N;
|
||||
}
|
||||
|
||||
while (!Rh)
|
||||
{
|
||||
const VertexLink* N = R + R->next;
|
||||
|
||||
ASSERT(R->v.y >= 0);
|
||||
|
||||
if (N->v.y < R->v.y) return;
|
||||
|
||||
Rh = N->v.y - R->v.y;
|
||||
Rx = R->v.x;
|
||||
|
||||
if (Rh > 1) {
|
||||
uint32 tmp = FixedInvU(Rh);
|
||||
Rdx = tmp * (N->v.x - Rx);
|
||||
}
|
||||
|
||||
Rx <<= 16;
|
||||
R = N;
|
||||
}
|
||||
|
||||
int32 h = X_MIN(Lh, Rh);
|
||||
Lh -= h;
|
||||
Rh -= h;
|
||||
|
||||
while (h--)
|
||||
{
|
||||
int32 x1 = Lx >> 16;
|
||||
int32 x2 = Rx >> 16;
|
||||
|
||||
int32 width = x2 - x1;
|
||||
|
||||
if (width > 0)
|
||||
{
|
||||
volatile uint8* ptr = (uint8*)pixel + x1;
|
||||
|
||||
if (intptr_t(ptr) & 1)
|
||||
{
|
||||
*ptr++ = uint8(color);
|
||||
width--;
|
||||
}
|
||||
|
||||
if (width & 1)
|
||||
{
|
||||
ptr[width - 1] = uint8(color);
|
||||
}
|
||||
|
||||
if (width & 2)
|
||||
{
|
||||
*(uint16*)ptr = color;
|
||||
ptr += 2;
|
||||
}
|
||||
|
||||
width >>= 2;
|
||||
while (width--)
|
||||
{
|
||||
*(uint16*)ptr = color;
|
||||
ptr += 2;
|
||||
*(uint16*)ptr = color;
|
||||
ptr += 2;
|
||||
}
|
||||
}
|
||||
|
||||
pixel += VRAM_WIDTH;
|
||||
|
||||
Lx += Ldx;
|
||||
Rx += Rdx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void rasterizeG_c(uint16* pixel, const VertexLink* L, const VertexLink* R)
|
||||
{
|
||||
int32 Lh = 0, Rh = 0;
|
||||
int32 Lx, Rx, Ldx = 0, Rdx = 0;
|
||||
int32 Lg, Rg, Ldg = 0, Rdg = 0;
|
||||
|
||||
const uint8* ft_lightmap = gLightmap + L->t.t;
|
||||
|
||||
while (1)
|
||||
{
|
||||
while (!Lh)
|
||||
{
|
||||
const VertexLink* N = L + L->prev;
|
||||
|
||||
if (N->v.y < L->v.y) return;
|
||||
|
||||
Lh = N->v.y - L->v.y;
|
||||
Lx = L->v.x;
|
||||
Lg = L->v.g;
|
||||
|
||||
if (Lh > 1)
|
||||
{
|
||||
int32 tmp = FixedInvU(Lh);
|
||||
Ldx = tmp * (N->v.x - Lx);
|
||||
Ldg = tmp * (N->v.g - Lg);
|
||||
}
|
||||
|
||||
Lx <<= 16;
|
||||
Lg <<= 16;
|
||||
L = N;
|
||||
}
|
||||
|
||||
while (!Rh)
|
||||
{
|
||||
const VertexLink* N = R + R->next;
|
||||
|
||||
if (N->v.y < R->v.y) return;
|
||||
|
||||
Rh = N->v.y - R->v.y;
|
||||
Rx = R->v.x;
|
||||
Rg = R->v.g;
|
||||
|
||||
if (Rh > 1)
|
||||
{
|
||||
int32 tmp = FixedInvU(Rh);
|
||||
Rdx = tmp * (N->v.x - Rx);
|
||||
Rdg = tmp * (N->v.g - Rg);
|
||||
}
|
||||
|
||||
Rx <<= 16;
|
||||
Rg <<= 16;
|
||||
R = N;
|
||||
}
|
||||
|
||||
int32 h = X_MIN(Lh, Rh);
|
||||
Lh -= h;
|
||||
Rh -= h;
|
||||
|
||||
while (h--)
|
||||
{
|
||||
int32 x1 = Lx >> 16;
|
||||
int32 x2 = Rx >> 16;
|
||||
|
||||
int32 width = x2 - x1;
|
||||
|
||||
if (width > 0)
|
||||
{
|
||||
int32 tmp = FixedInvU(width);
|
||||
|
||||
int32 dgdx = tmp * ((Rg - Lg) >> 5) >> 10;
|
||||
|
||||
int32 g = Lg;
|
||||
|
||||
volatile uint8* ptr = (uint8*)pixel + x1;
|
||||
|
||||
if (intptr_t(ptr) & 1)
|
||||
{
|
||||
*ptr++ = ft_lightmap[g >> 16 << 8];
|
||||
g += dgdx >> 1;
|
||||
width--;
|
||||
}
|
||||
|
||||
if (width & 1)
|
||||
{
|
||||
ptr[width - 1] = ft_lightmap[Rg >> 16 << 8];
|
||||
}
|
||||
|
||||
if (width & 2)
|
||||
{
|
||||
uint8 p = ft_lightmap[g >> 16 << 8];
|
||||
g += dgdx;
|
||||
*(uint16*)ptr = p | (p << 8);
|
||||
ptr += 2;
|
||||
}
|
||||
|
||||
width >>= 2;
|
||||
while (width--)
|
||||
{
|
||||
uint8 p;
|
||||
|
||||
p = ft_lightmap[g >> 16 << 8];
|
||||
*(uint16*)ptr = p | (p << 8);
|
||||
g += dgdx;
|
||||
ptr += 2;
|
||||
|
||||
p = ft_lightmap[g >> 16 << 8];
|
||||
*(uint16*)ptr = p | (p << 8);
|
||||
g += dgdx;
|
||||
ptr += 2;
|
||||
}
|
||||
}
|
||||
|
||||
pixel += VRAM_WIDTH;
|
||||
|
||||
Lx += Ldx;
|
||||
Rx += Rdx;
|
||||
Lg += Ldg;
|
||||
Rg += Rdg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void rasterizeFT_c(uint16* pixel, const VertexLink* L, const VertexLink* R)
|
||||
{
|
||||
const uint8* ft_lightmap = &gLightmap[L->v.g << 8];
|
||||
|
||||
int32 Lh = 0, Rh = 0;
|
||||
int32 Lx, Rx, Ldx = 0, Rdx = 0;
|
||||
uint32 Lt, Rt, Ldt, Rdt;
|
||||
Ldt = 0;
|
||||
Rdt = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
while (!Lh)
|
||||
{
|
||||
const VertexLink* N = L + L->prev;
|
||||
|
||||
if (N->v.y < L->v.y) return;
|
||||
|
||||
Lh = N->v.y - L->v.y;
|
||||
Lx = L->v.x;
|
||||
Lt = L->t.t;
|
||||
|
||||
if (Lh > 1)
|
||||
{
|
||||
int32 tmp = FixedInvU(Lh);
|
||||
Ldx = tmp * (N->v.x - Lx);
|
||||
|
||||
uint32 duv = N->t.t - Lt;
|
||||
uint32 du = tmp * int16(duv >> 16);
|
||||
uint32 dv = tmp * int16(duv);
|
||||
Ldt = (du & 0xFFFF0000) | (dv >> 16);
|
||||
}
|
||||
|
||||
Lx <<= 16;
|
||||
L = N;
|
||||
}
|
||||
|
||||
while (!Rh)
|
||||
{
|
||||
const VertexLink* N = R + R->next;
|
||||
|
||||
if (N->v.y < R->v.y) return;
|
||||
|
||||
Rh = N->v.y - R->v.y;
|
||||
Rx = R->v.x;
|
||||
Rt = R->t.t;
|
||||
|
||||
if (Rh > 1)
|
||||
{
|
||||
int32 tmp = FixedInvU(Rh);
|
||||
Rdx = tmp * (N->v.x - Rx);
|
||||
|
||||
uint32 duv = N->t.t - Rt;
|
||||
uint32 du = tmp * int16(duv >> 16);
|
||||
uint32 dv = tmp * int16(duv);
|
||||
Rdt = (du & 0xFFFF0000) | (dv >> 16);
|
||||
}
|
||||
|
||||
Rx <<= 16;
|
||||
R = N;
|
||||
}
|
||||
|
||||
int32 h = X_MIN(Lh, Rh);
|
||||
Lh -= h;
|
||||
Rh -= h;
|
||||
|
||||
while (h--)
|
||||
{
|
||||
int32 x1 = Lx >> 16;
|
||||
int32 x2 = Rx >> 16;
|
||||
|
||||
int32 width = x2 - x1;
|
||||
|
||||
if (width > 0)
|
||||
{
|
||||
uint32 tmp = FixedInvU(width);
|
||||
|
||||
uint32 duv = Rt - Lt;
|
||||
uint32 du = tmp * int16(duv >> 16);
|
||||
uint32 dv = tmp * int16(duv);
|
||||
uint32 dtdx = (du & 0xFFFF0000) | (dv >> 16);
|
||||
|
||||
uint32 t = Lt;
|
||||
|
||||
volatile uint8* ptr = (uint8*)pixel + x1;
|
||||
|
||||
if (intptr_t(ptr) & 1)
|
||||
{
|
||||
*ptr++ = ft_lightmap[gTile[(t & 0xFF00) | (t >> 24)]];
|
||||
t += dtdx;
|
||||
width--;
|
||||
}
|
||||
|
||||
if (width & 1)
|
||||
{
|
||||
uint32 tmp = Rt - dtdx;
|
||||
ptr[width - 1] = ft_lightmap[gTile[(tmp & 0xFF00) | (tmp >> 24)]];
|
||||
}
|
||||
|
||||
width >>= 1;
|
||||
while (width--)
|
||||
{
|
||||
uint8 indexA = ft_lightmap[gTile[(t & 0xFF00) | (t >> 24)]];
|
||||
t += dtdx;
|
||||
uint8 indexB = ft_lightmap[gTile[(t & 0xFF00) | (t >> 24)]];
|
||||
t += dtdx;
|
||||
|
||||
#ifdef CPU_BIG_ENDIAN
|
||||
*(uint16*)ptr = indexB | (indexA << 8);
|
||||
#else
|
||||
*(uint16*)ptr = indexA | (indexB << 8);
|
||||
#endif
|
||||
|
||||
ptr += 2;
|
||||
}
|
||||
}
|
||||
|
||||
pixel += VRAM_WIDTH;
|
||||
|
||||
Lx += Ldx;
|
||||
Rx += Rdx;
|
||||
Lt += Ldt;
|
||||
Rt += Rdt;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void rasterizeGT_c(uint16* pixel, const VertexLink* L, const VertexLink* R)
|
||||
{
|
||||
#ifdef ALIGNED_LIGHTMAP
|
||||
ASSERT((intptr_t(gLightmap) & 0xFFFF) == 0); // lightmap should be 64k aligned
|
||||
#endif
|
||||
|
||||
int32 Lh = 0, Rh = 0;
|
||||
int32 Lx, Rx, Lg, Rg, Ldx = 0, Rdx = 0, Ldg = 0, Rdg = 0;
|
||||
uint32 Lt, Rt, Ldt, Rdt;
|
||||
Ldt = 0;
|
||||
Rdt = 0;
|
||||
|
||||
// 8-bit fractional part precision for Gouraud component
|
||||
// has some artifacts but allow to save one reg for inner loop
|
||||
// for aligned by 64k address of lightmap array
|
||||
|
||||
while (1)
|
||||
{
|
||||
while (!Lh)
|
||||
{
|
||||
const VertexLink* N = L + L->prev;
|
||||
|
||||
if (N->v.y < L->v.y) return;
|
||||
|
||||
Lh = N->v.y - L->v.y;
|
||||
Lx = L->v.x;
|
||||
Lg = L->v.g;
|
||||
Lt = L->t.t;
|
||||
|
||||
if (Lh > 1)
|
||||
{
|
||||
int32 tmp = FixedInvU(Lh);
|
||||
Ldx = tmp * (N->v.x - Lx);
|
||||
Ldg = tmp * (N->v.g - Lg) >> 8;
|
||||
|
||||
uint32 duv = N->t.t - Lt;
|
||||
uint32 du = tmp * int16(duv >> 16);
|
||||
uint32 dv = tmp * int16(duv);
|
||||
Ldt = (du & 0xFFFF0000) | (dv >> 16);
|
||||
}
|
||||
|
||||
Lx <<= 16;
|
||||
Lg <<= 8;
|
||||
L = N;
|
||||
}
|
||||
|
||||
while (!Rh)
|
||||
{
|
||||
const VertexLink* N = R + R->next;
|
||||
|
||||
if (N->v.y < R->v.y) return;
|
||||
|
||||
Rh = N->v.y - R->v.y;
|
||||
Rx = R->v.x;
|
||||
Rg = R->v.g;
|
||||
Rt = R->t.t;
|
||||
|
||||
if (Rh > 1)
|
||||
{
|
||||
int32 tmp = FixedInvU(Rh);
|
||||
Rdx = tmp * (N->v.x - Rx);
|
||||
Rdg = tmp * (N->v.g - Rg) >> 8;
|
||||
|
||||
uint32 duv = N->t.t - Rt;
|
||||
uint32 du = tmp * int16(duv >> 16);
|
||||
uint32 dv = tmp * int16(duv);
|
||||
Rdt = (du & 0xFFFF0000) | (dv >> 16);
|
||||
}
|
||||
|
||||
Rx <<= 16;
|
||||
Rg <<= 8;
|
||||
R = N;
|
||||
}
|
||||
|
||||
int32 h = X_MIN(Lh, Rh);
|
||||
Lh -= h;
|
||||
Rh -= h;
|
||||
|
||||
while (h--)
|
||||
{
|
||||
int32 x1 = Lx >> 16;
|
||||
int32 x2 = Rx >> 16;
|
||||
|
||||
int32 width = x2 - x1;
|
||||
|
||||
if (width > 0)
|
||||
{
|
||||
int32 tmp = FixedInvU(width);
|
||||
|
||||
int32 dgdx = tmp * (Rg - Lg) >> 15;
|
||||
|
||||
uint32 duv = Rt - Lt;
|
||||
uint32 u = tmp * int16(duv >> 16);
|
||||
uint32 v = tmp * int16(duv);
|
||||
uint32 dtdx = (u & 0xFFFF0000) | (v >> 16);
|
||||
|
||||
int32 g = Lg;
|
||||
uint32 t = Lt;
|
||||
|
||||
volatile uint8* ptr = (uint8*)pixel + x1;
|
||||
|
||||
if (intptr_t(ptr) & 1)
|
||||
{
|
||||
*ptr++ = gLightmap[(g >> 8 << 8) | gTile[(t & 0xFF00) | (t >> 24)]];
|
||||
t += dtdx;
|
||||
g += dgdx >> 1;
|
||||
width--;
|
||||
}
|
||||
|
||||
if (width & 1)
|
||||
{
|
||||
uint32 tmp = Rt - dtdx;
|
||||
ptr[width - 1] = gLightmap[(Rg >> 8 << 8) | gTile[(tmp & 0xFF00) | (tmp >> 24)]];
|
||||
}
|
||||
|
||||
#ifdef ALIGNED_LIGHTMAP
|
||||
g += intptr_t(gLightmap);
|
||||
#endif
|
||||
|
||||
width >>= 1;
|
||||
|
||||
while (width--)
|
||||
{
|
||||
#ifdef ALIGNED_LIGHTMAP
|
||||
const uint8* LMAP = (uint8*)(g >> 8 << 8);
|
||||
|
||||
uint8 indexA = LMAP[gTile[(t & 0xFF00) | (t >> 24)]];
|
||||
t += dtdx;
|
||||
uint8 indexB = LMAP[gTile[(t & 0xFF00) | (t >> 24)]];
|
||||
t += dtdx;
|
||||
g += dgdx;
|
||||
#else
|
||||
uint8 indexA = gLightmap[(g >> 8 << 8) | gTile[(t & 0xFF00) | (t >> 24)]];
|
||||
t += dtdx;
|
||||
uint8 indexB = gLightmap[(g >> 8 << 8) | gTile[(t & 0xFF00) | (t >> 24)]];
|
||||
t += dtdx;
|
||||
g += dgdx;
|
||||
#endif
|
||||
|
||||
#ifdef CPU_BIG_ENDIAN
|
||||
*(uint16*)ptr = indexB | (indexA << 8);
|
||||
#else
|
||||
*(uint16*)ptr = indexA | (indexB << 8);
|
||||
#endif
|
||||
|
||||
ptr += 2;
|
||||
}
|
||||
}
|
||||
|
||||
pixel += VRAM_WIDTH;
|
||||
|
||||
Lx += Ldx;
|
||||
Rx += Rdx;
|
||||
Lg += Ldg;
|
||||
Rg += Rdg;
|
||||
Lt += Ldt;
|
||||
Rt += Rdt;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void rasterizeFTA_c(uint16* pixel, const VertexLink* L, const VertexLink* R)
|
||||
{
|
||||
const uint8* ft_lightmap = &gLightmap[L->v.g << 8];
|
||||
|
||||
int32 Lh = 0, Rh = 0;
|
||||
int32 Lx, Rx, Ldx = 0, Rdx = 0;
|
||||
uint32 Lt, Rt, Ldt, Rdt;
|
||||
Ldt = 0;
|
||||
Rdt = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
while (!Lh)
|
||||
{
|
||||
const VertexLink* N = L + L->prev;
|
||||
|
||||
if (N->v.y < L->v.y) return;
|
||||
|
||||
Lh = N->v.y - L->v.y;
|
||||
Lx = L->v.x;
|
||||
Lt = L->t.t;
|
||||
|
||||
if (Lh > 1)
|
||||
{
|
||||
int32 tmp = FixedInvU(Lh);
|
||||
Ldx = tmp * (N->v.x - Lx);
|
||||
|
||||
uint32 duv = N->t.t - Lt;
|
||||
uint32 du = tmp * int16(duv >> 16);
|
||||
uint32 dv = tmp * int16(duv);
|
||||
Ldt = (du & 0xFFFF0000) | (dv >> 16);
|
||||
}
|
||||
|
||||
Lx <<= 16;
|
||||
L = N;
|
||||
}
|
||||
|
||||
while (!Rh)
|
||||
{
|
||||
const VertexLink* N = R + R->next;
|
||||
|
||||
if (N->v.y < R->v.y) return;
|
||||
|
||||
Rh = N->v.y - R->v.y;
|
||||
Rx = R->v.x;
|
||||
Rt = R->t.t;
|
||||
|
||||
if (Rh > 1)
|
||||
{
|
||||
int32 tmp = FixedInvU(Rh);
|
||||
Rdx = tmp * (N->v.x - Rx);
|
||||
|
||||
uint32 duv = N->t.t - Rt;
|
||||
uint32 du = tmp * int16(duv >> 16);
|
||||
uint32 dv = tmp * int16(duv);
|
||||
Rdt = (du & 0xFFFF0000) | (dv >> 16);
|
||||
}
|
||||
|
||||
Rx <<= 16;
|
||||
R = N;
|
||||
}
|
||||
|
||||
int32 h = X_MIN(Lh, Rh);
|
||||
Lh -= h;
|
||||
Rh -= h;
|
||||
|
||||
while (h--)
|
||||
{
|
||||
int32 x1 = Lx >> 16;
|
||||
int32 x2 = Rx >> 16;
|
||||
|
||||
int32 width = x2 - x1;
|
||||
|
||||
if (width > 0)
|
||||
{
|
||||
uint32 tmp = FixedInvU(width);
|
||||
|
||||
uint32 duv = Rt - Lt;
|
||||
uint32 du = tmp * int16(duv >> 16);
|
||||
uint32 dv = tmp * int16(duv);
|
||||
uint32 dtdx = (du & 0xFFFF0000) | (dv >> 16);
|
||||
|
||||
uint32 t = Lt;
|
||||
|
||||
volatile uint8* ptr = (uint8*)pixel + x1;
|
||||
|
||||
if (intptr_t(ptr) & 1)
|
||||
{
|
||||
uint8 p = gTile[(t & 0xFF00) | (t >> 24)];
|
||||
if (p) {
|
||||
*ptr = ft_lightmap[p];
|
||||
}
|
||||
ptr++;
|
||||
t += dtdx;
|
||||
width--;
|
||||
}
|
||||
|
||||
if (width & 1)
|
||||
{
|
||||
uint32 tmp = Rt - dtdx;
|
||||
uint8 p = gTile[(tmp & 0xFF00) | (tmp >> 24)];
|
||||
if (p) {
|
||||
ptr[width - 1] = ft_lightmap[p];
|
||||
}
|
||||
}
|
||||
|
||||
width >>= 1;
|
||||
while (width--)
|
||||
{
|
||||
uint8 indexA = gTile[(t & 0xFF00) | (t >> 24)];
|
||||
t += dtdx;
|
||||
uint8 indexB = gTile[(t & 0xFF00) | (t >> 24)];
|
||||
t += dtdx;
|
||||
|
||||
|
||||
if (indexA && indexB)
|
||||
{
|
||||
indexA = ft_lightmap[indexA];
|
||||
indexB = ft_lightmap[indexB];
|
||||
|
||||
#ifdef CPU_BIG_ENDIAN
|
||||
*(uint16*)ptr = indexB | (indexA << 8);
|
||||
#else
|
||||
*(uint16*)ptr = indexA | (indexB << 8);
|
||||
#endif
|
||||
|
||||
}/* else if (indexA) {
|
||||
*(uint16*)ptr = (*(uint16*)ptr & 0xFF00) | ft_lightmap[indexA];
|
||||
} else if (indexB) {
|
||||
*(uint16*)ptr = (*(uint16*)ptr & 0x00FF) | (ft_lightmap[indexB] << 8);
|
||||
}*/
|
||||
|
||||
ptr += 2;
|
||||
}
|
||||
}
|
||||
|
||||
pixel += VRAM_WIDTH;
|
||||
|
||||
Lx += Ldx;
|
||||
Rx += Rdx;
|
||||
Lt += Ldt;
|
||||
Rt += Rdt;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void rasterizeGTA_c(uint16* pixel, const VertexLink* L, const VertexLink* R)
|
||||
{
|
||||
rasterizeFTA(pixel, L, R);
|
||||
}
|
||||
|
||||
void rasterizeSprite_c(uint16* pixel, const VertexLink* L, const VertexLink* R)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
void rasterizeLineH_c(uint16* pixel, const VertexLink* L, const VertexLink* R)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
void rasterizeLineV_c(uint16* pixel, const VertexLink* L, const VertexLink* R)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
void rasterizeFillS_c(uint16* pixel, const VertexLink* L, const VertexLink* R)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
#endif
|
1320
src/platform/32x/render.cpp
Normal file
1320
src/platform/32x/render.cpp
Normal file
File diff suppressed because it is too large
Load Diff
51
src/platform/32x/sound.cpp
Normal file
51
src/platform/32x/sound.cpp
Normal file
@ -0,0 +1,51 @@
|
||||
#include "common.h"
|
||||
|
||||
void sndInit()
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
void sndInitSamples()
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
void sndFreeSamples()
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
void* sndPlaySample(int32 index, int32 volume, int32 pitch, int32 mode)
|
||||
{
|
||||
return NULL; // TODO
|
||||
}
|
||||
|
||||
void sndPlayTrack(int32 track)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
void sndStopTrack()
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
bool sndTrackIsPlaying()
|
||||
{
|
||||
return false; // TODO
|
||||
}
|
||||
|
||||
void sndStopSample(int32 index)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
void sndStop()
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
void sndFill(uint8* buffer, int32 count)
|
||||
{
|
||||
// TODO
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user