mirror of https://github.com/ClassiCube/ClassiCube
Add 32x support code
This commit is contained in:
parent
8ca9709969
commit
12d127248c
|
|
@ -0,0 +1,131 @@
|
|||
#ifndef __32X_H__
|
||||
#define __32X_H__
|
||||
|
||||
/* Create a 5:5:5 RGB color */
|
||||
#define COLOR(r,g,b) (((r)&0x1F)|((g)&0x1F)<<5|((b)&0x1F)<<10)
|
||||
|
||||
#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
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* global functions in sh2_crt0.s */
|
||||
extern void fast_memcpy(void *dst, void *src, int len);
|
||||
extern void CacheControl(int mode);
|
||||
extern void CacheClearLine(void* ptr);
|
||||
extern void ScreenStretch(int src, int width, int height, int interp);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
ifdef $(GENDEV)
|
||||
ROOTDIR = $(GENDEV)
|
||||
else
|
||||
ROOTDIR = /opt/toolchains/sega
|
||||
endif
|
||||
|
||||
LDSCRIPTSDIR = $(ROOTDIR)/ldscripts
|
||||
|
||||
LIBPATH = -L$(ROOTDIR)/sh-elf/lib -L$(ROOTDIR)/sh-elf/lib/gcc/sh-elf/4.6.2 -L$(ROOTDIR)/sh-elf/sh-elf/lib
|
||||
INCPATH = -I. -I../include -I$(ROOTDIR)/sh-elf/include -I$(ROOTDIR)/sh-elf/sh-elf/include
|
||||
|
||||
SHCCFLAGS = -m2 -mb -Ofast -Wall -g -c -fomit-frame-pointer -DPLAT_32X -ffunction-sections -fdata-sections
|
||||
SHHWFLAGS = -m2 -mb -O1 -Wall -g -c -fomit-frame-pointer
|
||||
SHLDFLAGS = -T $(LDSCRIPTSDIR)/mars.ld -Wl,-Map=output.map -nostdlib -Wl,--gc-sections
|
||||
SHASFLAGS = --big
|
||||
|
||||
MDLDFLAGS = -T $(LDSCRIPTSDIR)/md.ld --oformat binary
|
||||
MDASFLAGS = -m68000 --register-prefix-optional
|
||||
|
||||
SHPREFIX = $(ROOTDIR)/sh-elf/bin/sh-elf-
|
||||
SHCC = $(SHPREFIX)gcc
|
||||
SHAS = $(SHPREFIX)as
|
||||
SHLD = $(SHPREFIX)ld
|
||||
SHOBJC = $(SHPREFIX)objcopy
|
||||
|
||||
MDPREFIX = $(ROOTDIR)/m68k-elf/bin/m68k-elf-
|
||||
MDAS = $(MDPREFIX)as
|
||||
MDLD = $(MDPREFIX)ld
|
||||
|
||||
DD = dd
|
||||
RM = rm -f
|
||||
|
||||
TARGET = ClassiCube
|
||||
LIBS = $(LIBPATH) -lc -lgcc -lgcc-Os-4-200 -lnosys
|
||||
|
||||
SOURCE_DIRS = ../../src
|
||||
C_FILES = $(foreach dir,$(SOURCE_DIRS),$(wildcard $(dir)/*.c))
|
||||
OBJS = sh2_crt0.o main_32x.o hw_32x.o $(notdir $(C_FILES:%.c=%.o))
|
||||
|
||||
all: m68k_crt0.bin m68k_crt1.bin $(TARGET).bin
|
||||
|
||||
$(TARGET).bin: $(TARGET).elf
|
||||
$(SHOBJC) -O binary $< temp.bin
|
||||
$(DD) if=temp.bin of=$@ bs=64K conv=sync
|
||||
|
||||
$(TARGET).elf: $(OBJS)
|
||||
$(SHCC) $(SHLDFLAGS) $(OBJS) $(LIBS) -o $(TARGET).elf
|
||||
|
||||
m68k_crt0.bin: m68k_crt0.s
|
||||
$(MDAS) $(MDASFLAGS) -o m68k_crt0.o m68k_crt0.s
|
||||
$(MDLD) $(MDLDFLAGS) -o m68k_crt0.bin m68k_crt0.o
|
||||
|
||||
m68k_crt1.bin: m68k_crt1.s
|
||||
$(MDAS) $(MDASFLAGS) -o m68k_crt1.o m68k_crt1.s
|
||||
$(MDLD) $(MDLDFLAGS) -o m68k_crt1.bin m68k_crt1.o
|
||||
|
||||
hw_32x.o: hw_32x.c
|
||||
$(SHCC) $(SHHWFLAGS) $(INCPATH) $< -o $@
|
||||
|
||||
%.o: %.c
|
||||
$(SHCC) $(SHCCFLAGS) $(INCPATH) $< -o $@
|
||||
|
||||
%.o: ../../src/%.c
|
||||
$(SHCC) $(SHCCFLAGS) $(INCPATH) $< -o $@
|
||||
|
||||
%.o: %.s
|
||||
$(SHAS) $(SHASFLAGS) $(INCPATH) $< -o $@
|
||||
|
||||
clean:
|
||||
$(RM) *.o *.bin *.elf output.map
|
||||
|
|
@ -0,0 +1,259 @@
|
|||
/*
|
||||
* Licensed under the BSD license
|
||||
*
|
||||
* debug_32x.c - Debug screen functions.
|
||||
*
|
||||
* Copyright (c) 2005 Marcus R. Brown <mrbrown@ocgnet.org>
|
||||
* Copyright (c) 2005 James Forshaw <tyranid@gmail.com>
|
||||
* Copyright (c) 2005 John Kelley <ps2dev@kelley.ca>
|
||||
*
|
||||
* Altered for 32X by Chilly Willy
|
||||
*/
|
||||
|
||||
#include "32x.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
static int init = 0;
|
||||
static unsigned short fgc = 0, bgc = 0;
|
||||
static unsigned char fgs = 0, bgs = 0;
|
||||
|
||||
static unsigned short currentFB = 0;
|
||||
|
||||
void Hw32xSetFGColor(int s, int r, int g, int b)
|
||||
{
|
||||
volatile unsigned short *palette = &MARS_CRAM;
|
||||
fgs = s;
|
||||
fgc = COLOR(r, g, b);
|
||||
palette[fgs] = fgc;
|
||||
}
|
||||
|
||||
void Hw32xSetBGColor(int s, int r, int g, int b)
|
||||
{
|
||||
volatile unsigned short *palette = &MARS_CRAM;
|
||||
bgs = s;
|
||||
bgc = COLOR(r, g, b);
|
||||
palette[bgs] = bgc;
|
||||
}
|
||||
|
||||
void Hw32xInit(int vmode, int lineskip)
|
||||
{
|
||||
volatile unsigned short *frameBuffer16 = &MARS_FRAMEBUFFER;
|
||||
int i;
|
||||
|
||||
// Wait for the SH2 to gain access to the VDP
|
||||
while ((MARS_SYS_INTMSK & MARS_SH2_ACCESS_VDP) == 0) ;
|
||||
|
||||
if (vmode == MARS_VDP_MODE_32K)
|
||||
{
|
||||
// Set 16-bit direct mode, 224 lines
|
||||
MARS_VDP_DISPMODE = MARS_224_LINES | MARS_VDP_MODE_32K;
|
||||
|
||||
// init both framebuffers
|
||||
|
||||
// Flip the framebuffer selection bit and wait for it to take effect
|
||||
MARS_VDP_FBCTL = currentFB ^ 1;
|
||||
while ((MARS_VDP_FBCTL & MARS_VDP_FS) == currentFB) ;
|
||||
currentFB ^= 1;
|
||||
// rewrite line table
|
||||
for (i=0; i<224/(lineskip+1); i++)
|
||||
{
|
||||
if (lineskip)
|
||||
{
|
||||
int j = lineskip + 1;
|
||||
while (j)
|
||||
{
|
||||
frameBuffer16[i*(lineskip+1) + (lineskip + 1 - j)] = i*320 + 0x100; /* word offset of line */
|
||||
j--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (i<200)
|
||||
frameBuffer16[i] = i*320 + 0x100; /* word offset of line */
|
||||
else
|
||||
frameBuffer16[i] = 200*320 + 0x100; /* word offset of line */
|
||||
}
|
||||
}
|
||||
// clear screen
|
||||
for (i=0x100; i<0x10000; i++)
|
||||
frameBuffer16[i] = 0;
|
||||
|
||||
// Flip the framebuffer selection bit and wait for it to take effect
|
||||
MARS_VDP_FBCTL = currentFB ^ 1;
|
||||
while ((MARS_VDP_FBCTL & MARS_VDP_FS) == currentFB) ;
|
||||
currentFB ^= 1;
|
||||
// rewrite line table
|
||||
for (i=0; i<224/(lineskip+1); i++)
|
||||
{
|
||||
if (lineskip)
|
||||
{
|
||||
int j = lineskip + 1;
|
||||
while (j)
|
||||
{
|
||||
frameBuffer16[i*(lineskip+1) + (lineskip + 1 - j)] = i*320 + 0x100; /* word offset of line */
|
||||
j--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (i<200)
|
||||
frameBuffer16[i] = i*320 + 0x100; /* word offset of line */
|
||||
else
|
||||
frameBuffer16[i] = 200*320 + 0x100; /* word offset of line */
|
||||
}
|
||||
}
|
||||
// clear screen
|
||||
for (i=0x100; i<0x10000; i++)
|
||||
frameBuffer16[i] = 0;
|
||||
}
|
||||
|
||||
Hw32xSetFGColor(255,31,31,31);
|
||||
Hw32xSetBGColor(0,0,0,0);
|
||||
init = vmode;
|
||||
}
|
||||
|
||||
void Hw32xScreenClear()
|
||||
{
|
||||
int i;
|
||||
int l = (init == MARS_VDP_MODE_256) ? 320*224/2 + 0x100 : 320*200 + 0x100;
|
||||
volatile unsigned short *frameBuffer16 = &MARS_FRAMEBUFFER;
|
||||
|
||||
// clear screen
|
||||
for (i=0x100; i<l; i++)
|
||||
frameBuffer16[i] = 0;
|
||||
|
||||
// Flip the framebuffer selection bit and wait for it to take effect
|
||||
MARS_VDP_FBCTL = currentFB ^ 1;
|
||||
while ((MARS_VDP_FBCTL & MARS_VDP_FS) == currentFB) ;
|
||||
currentFB ^= 1;
|
||||
|
||||
// clear screen
|
||||
for (i=0x100; i<l; i++)
|
||||
frameBuffer16[i] = 0;
|
||||
|
||||
Hw32xSetFGColor(255,31,31,31);
|
||||
Hw32xSetBGColor(0,0,0,0);
|
||||
X = Y = 0;
|
||||
}
|
||||
|
||||
extern unsigned char msx[];
|
||||
|
||||
void Hw32xDelay(int ticks)
|
||||
{
|
||||
unsigned long ct = MARS_SYS_COMM12 + ticks;
|
||||
while (MARS_SYS_COMM12 < ct) ;
|
||||
}
|
||||
|
||||
void Hw32xScreenFlip(int wait)
|
||||
{
|
||||
// Flip the framebuffer selection bit
|
||||
MARS_VDP_FBCTL = currentFB ^ 1;
|
||||
if (wait)
|
||||
{
|
||||
while ((MARS_VDP_FBCTL & MARS_VDP_FS) == currentFB) ;
|
||||
currentFB ^= 1;
|
||||
}
|
||||
}
|
||||
|
||||
void Hw32xFlipWait()
|
||||
{
|
||||
while ((MARS_VDP_FBCTL & MARS_VDP_FS) == currentFB) ;
|
||||
currentFB ^= 1;
|
||||
}
|
||||
|
||||
|
||||
// MD Command support code ---------------------------------------------
|
||||
|
||||
unsigned short HwMdReadPad(int port)
|
||||
{
|
||||
if (port == 0)
|
||||
return MARS_SYS_COMM8;
|
||||
else if (port == 1)
|
||||
return MARS_SYS_COMM10;
|
||||
else
|
||||
return SEGA_CTRL_NONE;
|
||||
}
|
||||
|
||||
unsigned char HwMdReadSram(unsigned short offset)
|
||||
{
|
||||
while (MARS_SYS_COMM0) ; // wait until 68000 has responded to any earlier requests
|
||||
MARS_SYS_COMM2 = offset;
|
||||
MARS_SYS_COMM0 = 0x0100; // Read SRAM
|
||||
while (MARS_SYS_COMM0) ;
|
||||
return MARS_SYS_COMM2 & 0x00FF;
|
||||
}
|
||||
|
||||
void HwMdWriteSram(unsigned char byte, unsigned short offset)
|
||||
{
|
||||
while (MARS_SYS_COMM0) ; // wait until 68000 has responded to any earlier requests
|
||||
MARS_SYS_COMM2 = offset;
|
||||
MARS_SYS_COMM0 = 0x0200 | byte; // Write SRAM
|
||||
while (MARS_SYS_COMM0) ;
|
||||
}
|
||||
|
||||
int HwMdReadMouse(int port)
|
||||
{
|
||||
unsigned int mouse1, mouse2;
|
||||
while (MARS_SYS_COMM0) ; // wait until 68000 has responded to any earlier requests
|
||||
MARS_SYS_COMM0 = 0x0300|port; // tells 68000 to read mouse
|
||||
while (MARS_SYS_COMM0 == (0x0300|port)) ; // wait for mouse value
|
||||
mouse1 = MARS_SYS_COMM0;
|
||||
mouse2 = MARS_SYS_COMM2;
|
||||
MARS_SYS_COMM0 = 0; // tells 68000 we got the mouse value
|
||||
return (int)((mouse1 << 16) | mouse2);
|
||||
}
|
||||
|
||||
void HwMdClearScreen(void)
|
||||
{
|
||||
while (MARS_SYS_COMM0) ; // wait until 68000 has responded to any earlier requests
|
||||
MARS_SYS_COMM0 = 0x0400; // Clear Screen (Name Table B)
|
||||
while (MARS_SYS_COMM0) ;
|
||||
}
|
||||
|
||||
void HwMdSetOffset(unsigned short offset)
|
||||
{
|
||||
while (MARS_SYS_COMM0) ; // wait until 68000 has responded to any earlier requests
|
||||
MARS_SYS_COMM2 = offset;
|
||||
MARS_SYS_COMM0 = 0x0500; // Set offset (into either Name Table B or VRAM)
|
||||
while (MARS_SYS_COMM0) ;
|
||||
}
|
||||
|
||||
void HwMdSetNTable(unsigned short word)
|
||||
{
|
||||
while (MARS_SYS_COMM0) ; // wait until 68000 has responded to any earlier requests
|
||||
MARS_SYS_COMM2 = word;
|
||||
MARS_SYS_COMM0 = 0x0600; // Set word at offset in Name Table B
|
||||
while (MARS_SYS_COMM0) ;
|
||||
}
|
||||
|
||||
void HwMdSetVram(unsigned short word)
|
||||
{
|
||||
while (MARS_SYS_COMM0) ; // wait until 68000 has responded to any earlier requests
|
||||
MARS_SYS_COMM2 = word;
|
||||
MARS_SYS_COMM0 = 0x0700; // Set word at offset in VRAM
|
||||
while (MARS_SYS_COMM0) ;
|
||||
}
|
||||
|
||||
void HwMdPuts(char *str, int color, int x, int y)
|
||||
{
|
||||
HwMdSetOffset(((y<<6) | x) << 1);
|
||||
while (*str)
|
||||
HwMdSetNTable(((*str++ - 0x20) & 0xFF) | color);
|
||||
}
|
||||
|
||||
void HwMdPutc(char chr, int color, int x, int y)
|
||||
{
|
||||
HwMdSetOffset(((y<<6) | x) << 1);
|
||||
HwMdSetNTable(((chr - 0x20) & 0xFF) | color);
|
||||
}
|
||||
|
||||
|
||||
// Slave SH2 support code ----------------------------------------------
|
||||
|
||||
void slave(void)
|
||||
{
|
||||
while (1) ;
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
#ifndef HW_32X_H
|
||||
#define HW_32X_H
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
extern void Hw32xSetFGColor(int s, int r, int g, int b);
|
||||
extern void Hw32xSetBGColor(int s, int r, int g, int b);
|
||||
extern void Hw32xInit(int vmode, int lineskip);
|
||||
extern int Hw32xScreenGetX();
|
||||
extern int Hw32xScreenGetY();
|
||||
extern void Hw32xScreenSetXY(int x, int y);
|
||||
extern void Hw32xScreenClear();
|
||||
extern void Hw32xDelay(int ticks);
|
||||
extern void Hw32xScreenFlip(int wait);
|
||||
extern void Hw32xFlipWait();
|
||||
|
||||
extern unsigned short HwMdReadPad(int port);
|
||||
extern unsigned char HwMdReadSram(unsigned short offset);
|
||||
extern void HwMdWriteSram(unsigned char byte, unsigned short offset);
|
||||
extern int HwMdReadMouse(int port);
|
||||
extern void HwMdClearScreen(void);
|
||||
extern void HwMdSetOffset(unsigned short offset);
|
||||
extern void HwMdSetNTable(unsigned short word);
|
||||
extern void HwMdSetVram(unsigned short word);
|
||||
extern void HwMdPuts(char *str, int color, int x, int y);
|
||||
extern void HwMdPutc(char chr, int color, int x, int y);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
| 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 adapter 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 Example" /* SEGA must be the first four chars for TMSS */
|
||||
.ascii "(C)2024 "
|
||||
.ascii "ClassiCube 32X " /* export name */
|
||||
.ascii " "
|
||||
.ascii " "
|
||||
.ascii "ClassiCube 32X " /* domestic (Japanese) name */
|
||||
.ascii " "
|
||||
.ascii " "
|
||||
.ascii "GM MK-0000 -00"
|
||||
.word 0x0000 /* checksum - not needed */
|
||||
.ascii "J6 "
|
||||
.long 0x00000000,0x0007FFFF /* ROM start, end */
|
||||
.long 0x00FF0000,0x00FFFFFF /* RAM start, end */
|
||||
|
||||
.ifdef HAS_SAVE_RAM
|
||||
.ascii "RA" /* External RAM */
|
||||
.byte 0xF8 /* don't clear + odd bytes */
|
||||
.byte 0x20 /* SRAM */
|
||||
.long 0x00200001,0x0020FFFF /* SRAM start, end */
|
||||
.else
|
||||
.ascii " " /* no SRAM */
|
||||
.endif
|
||||
|
||||
.ascii " "
|
||||
.ascii " "
|
||||
|
||||
.ifdef MYTH_HOMEBREW
|
||||
.ascii "MYTH3900" /* memo indicates Myth native executable */
|
||||
.else
|
||||
.ascii " " /* memo */
|
||||
.endif
|
||||
|
||||
.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 */
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,29 @@
|
|||
#include <stdlib.h>
|
||||
|
||||
#include "32x.h"
|
||||
#include "hw_32x.h"
|
||||
|
||||
int32_t fix16_sqrt(int32_t value)
|
||||
{
|
||||
uint32_t t;
|
||||
uint32_t r = value;
|
||||
uint32_t b = 0x40000000;
|
||||
uint32_t q = 0;
|
||||
|
||||
while (b > 0x40) {
|
||||
t = q + b;
|
||||
|
||||
if (r >= t) {
|
||||
r -= t;
|
||||
q = t + b; /* Equivalent to q += 2 * b */
|
||||
}
|
||||
|
||||
r <<= 1;
|
||||
b >>= 1;
|
||||
}
|
||||
|
||||
q >>= 8;
|
||||
|
||||
return q;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,802 @@
|
|||
! 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 "m68k_crt0.bin", 0, 0x3C0
|
||||
|
||||
! Standard Mars Header at 0x3C0
|
||||
|
||||
.ascii "32X Example " /* module name (16 chars) */
|
||||
.long 0x00000000 /* version */
|
||||
.long __text_end-0x02000000 /* 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 "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
|
||||
|
||||
! do all initializers
|
||||
mov.l _master_do_init,r0
|
||||
jsr @r0
|
||||
nop
|
||||
|
||||
! 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
|
||||
jsr @r0
|
||||
nop
|
||||
|
||||
! do all finishers
|
||||
mov.l _master_do_fini,r0
|
||||
jsr @r0
|
||||
nop
|
||||
2:
|
||||
bra 2b
|
||||
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
|
||||
_master_do_init:
|
||||
.long __INIT_SECTION__
|
||||
_master_do_fini:
|
||||
.long __FINI_SECTION__
|
||||
|
||||
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
|
||||
|
||||
! 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
|
||||
|
||||
! void ScreenStretch(int src, int width, int height, int interp);
|
||||
! On entry: r4 = src pointer, r5 = width, r6 = height, r7 = interpolate
|
||||
|
||||
.align 4
|
||||
.global _ScreenStretch
|
||||
_ScreenStretch:
|
||||
cmp/pl r7
|
||||
bt ss_interp
|
||||
|
||||
! stretch screen without interpolation
|
||||
|
||||
0:
|
||||
mov r5,r3
|
||||
shll r3
|
||||
mov r3,r2
|
||||
shll r2
|
||||
add r4,r3
|
||||
add r4,r2
|
||||
1:
|
||||
add #-2,r3
|
||||
mov.w @r3,r0
|
||||
extu.w r0,r1
|
||||
shll16 r0
|
||||
or r1,r0
|
||||
mov.l r0,@-r2
|
||||
cmp/eq r3,r4
|
||||
bf 1b
|
||||
|
||||
/* next line */
|
||||
mov.w ss_pitch,r0
|
||||
dt r6
|
||||
bf/s 0b
|
||||
add r0,r4
|
||||
rts
|
||||
nop
|
||||
|
||||
ss_interp:
|
||||
|
||||
! stretch screen with interpolation
|
||||
|
||||
0:
|
||||
mov r5,r3
|
||||
shll r3
|
||||
mov r3,r2
|
||||
shll r2
|
||||
add r4,r3
|
||||
add r4,r2
|
||||
mov #0,r7
|
||||
1:
|
||||
add #-2,r3
|
||||
mov.w @r3,r0
|
||||
mov.w ss_mask,r1
|
||||
and r0,r1 /* masked curr pixel */
|
||||
shll16 r0
|
||||
add r1,r7 /* add to masked prev pixel */
|
||||
shlr r7 /* blended pixel */
|
||||
or r7,r0 /* curr pixel << 16 | blended pixel */
|
||||
mov r1,r7 /* masked prev pixel = masked curr pixel */
|
||||
mov.l r0,@-r2
|
||||
cmp/eq r3,r4
|
||||
bf 1b
|
||||
|
||||
/* next line */
|
||||
mov.w ss_pitch,r0
|
||||
dt r6
|
||||
bf/s 0b
|
||||
add r0,r4
|
||||
rts
|
||||
nop
|
||||
|
||||
ss_mask:
|
||||
.word 0x7BDE
|
||||
ss_pitch:
|
||||
.word 640
|
||||
|
||||
.align 2
|
||||
|
||||
.text
|
||||
|
||||
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:
|
||||
|
||||
31
src/Core.h
31
src/Core.h
|
|
@ -459,23 +459,24 @@ typedef cc_uint8 cc_bool;
|
|||
#undef CC_BUILD_ADVLIGHTING
|
||||
#undef CC_BUILD_FILESYSTEM
|
||||
#elif defined PLAT_32X
|
||||
#define CC_BUILD_32X
|
||||
#define CC_BUILD_CONSOLE
|
||||
#define CC_BUILD_LOWMEM
|
||||
#define CC_BUILD_TINYMEM
|
||||
#define CC_BUILD_COOPTHREADED
|
||||
#define CC_BUILD_NOMUSIC
|
||||
#define CC_BUILD_NOSOUNDS
|
||||
#define CC_BUILD_SMALLSTACK
|
||||
#define CC_BUILD_TINYSTACK
|
||||
#undef CC_BUILD_RESOURCES
|
||||
#undef CC_BUILD_NETWORKING
|
||||
#define CC_DISABLE_ANIMATIONS /* Very costly in FPU less system */
|
||||
#define CC_DISABLE_HELDBLOCK /* Very costly in FPU less system */
|
||||
#undef CC_BUILD_ADVLIGHTING
|
||||
#undef CC_BUILD_FILESYSTEM
|
||||
#define CC_BUILD_32X
|
||||
#define CC_BUILD_CONSOLE
|
||||
#define CC_BUILD_LOWMEM
|
||||
#define CC_BUILD_TINYMEM
|
||||
#define CC_BUILD_COOPTHREADED
|
||||
#define CC_BUILD_NOMUSIC
|
||||
#define CC_BUILD_NOSOUNDS
|
||||
#define CC_BUILD_SMALLSTACK
|
||||
#define CC_BUILD_TINYSTACK
|
||||
#undef CC_BUILD_RESOURCES
|
||||
#undef CC_BUILD_NETWORKING
|
||||
#define CC_DISABLE_ANIMATIONS /* Very costly in FPU less system */
|
||||
#define CC_DISABLE_HELDBLOCK /* Very costly in FPU less system */
|
||||
#undef CC_BUILD_ADVLIGHTING
|
||||
#undef CC_BUILD_FILESYSTEM
|
||||
#define CC_GFX_BACKEND CC_GFX_BACKEND_SOFTGPU
|
||||
#define CC_DISABLE_EXTRA_MODELS
|
||||
#define SOFTGPU_DISABLE_ZBUFFER
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -180,7 +180,7 @@ float Random_Float(RNGState* seed) {
|
|||
|
||||
float Math_SinF(float x) { return sinf(x); }
|
||||
float Math_CosF(float x) { return cosf(x); }
|
||||
#elif defined CC_BUILD_PS1 || defined CC_BUILD_SATURN || defined CC_BUILD_NDS
|
||||
#elif defined CC_BUILD_PS1 || defined CC_BUILD_SATURN || defined CC_BUILD_NDS || defined CC_BUILD_32X
|
||||
|
||||
// Source https://www.coranac.com/2009/07/sines
|
||||
#define ISIN_QN 10
|
||||
|
|
|
|||
|
|
@ -39,8 +39,14 @@ void Gfx_FreeState(void) {
|
|||
}
|
||||
|
||||
void Gfx_Create(void) {
|
||||
#ifdef CC_BUILD_TINYMEM
|
||||
Gfx.MaxTexWidth = 16;
|
||||
Gfx.MaxTexHeight = 16;
|
||||
#else
|
||||
Gfx.MaxTexWidth = 4096;
|
||||
Gfx.MaxTexHeight = 4096;
|
||||
#endif
|
||||
|
||||
Gfx.Created = true;
|
||||
Gfx.BackendType = CC_GFX_BACKEND_SOFTGPU;
|
||||
|
||||
|
|
@ -150,8 +156,10 @@ static void ClearColorBuffer(void) {
|
|||
}
|
||||
|
||||
static void ClearDepthBuffer(void) {
|
||||
#ifndef SOFTGPU_DISABLE_ZBUFFER
|
||||
int i, size = fb_width * fb_height;
|
||||
for (i = 0; i < size; i++) depthBuffer[i] = 100000000.0f;
|
||||
#endif
|
||||
}
|
||||
|
||||
void Gfx_ClearBuffers(GfxBuffers buffers) {
|
||||
|
|
@ -529,11 +537,15 @@ static void DrawTriangle3D(Vertex* V0, Vertex* V1, Vertex* V2) {
|
|||
float w = 1 / (ic0 * w0 + ic1 * w1 + ic2 * w2);
|
||||
float z = (ic0 * z0 + ic1 * z1 + ic2 * z2) * w;
|
||||
|
||||
#ifndef SOFTGPU_DISABLE_ZBUFFER
|
||||
if (depthTest && (z < 0 || z > depthBuffer[db_index])) continue;
|
||||
if (!colWrite) {
|
||||
if (depthWrite) depthBuffer[db_index] = z;
|
||||
continue;
|
||||
}
|
||||
#else
|
||||
if (!colWrite) continue;
|
||||
#endif
|
||||
|
||||
int R, G, B, A;
|
||||
if (gfx_format == VERTEX_FORMAT_TEXTURED) {
|
||||
|
|
@ -573,7 +585,9 @@ static void DrawTriangle3D(Vertex* V0, Vertex* V1, Vertex* V2) {
|
|||
B = (B * A + dstB * (255 - A)) >> 8;
|
||||
}
|
||||
|
||||
#ifndef SOFTGPU_DISABLE_ZBUFFER
|
||||
if (depthWrite) depthBuffer[db_index] = z;
|
||||
#endif
|
||||
colorBuffer[cb_index] = BitmapCol_Make(R, G, B, 0xFF);
|
||||
}
|
||||
}
|
||||
|
|
@ -943,8 +957,10 @@ void Gfx_OnWindowResize(void) {
|
|||
colorBuffer = fb_bmp.scan0;
|
||||
cb_stride = fb_bmp.width;
|
||||
|
||||
#ifndef SOFTGPU_DISABLE_ZBUFFER
|
||||
depthBuffer = Mem_Alloc(fb_width * fb_height, 4, "depth buffer");
|
||||
db_stride = fb_width;
|
||||
#endif
|
||||
|
||||
Gfx_SetViewport(0, 0, Game.Width, Game.Height);
|
||||
Gfx_SetScissor (0, 0, Game.Width, Game.Height);
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include "_PlatformConsole.h"
|
||||
#include "../misc/32x/32x.h"
|
||||
#include "../misc/32x/hw_32x.h"
|
||||
|
|
@ -35,11 +36,17 @@ cc_bool Platform_ReadonlyFilesystem = true;
|
|||
*#########################################################################################################################*/
|
||||
void* Mem_TryAlloc(cc_uint32 numElems, cc_uint32 elemsSize) {
|
||||
cc_uint32 size = CalcMemSize(numElems, elemsSize);
|
||||
return size ? malloc(size) : NULL;
|
||||
Platform_Log1(" MALLOC: %i", &size);
|
||||
void* ptr = size ? malloc(size) : NULL;
|
||||
Platform_Log1("MALLOCED: %x", &ptr);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void* Mem_TryAllocCleared(cc_uint32 numElems, cc_uint32 elemsSize) {
|
||||
return calloc(numElems, elemsSize);
|
||||
Platform_Log1(" CALLOC: %i", &numElems);
|
||||
void* ptr = calloc(numElems, elemsSize);
|
||||
Platform_Log1("CALLOCED: %x", &ptr);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void* Mem_TryRealloc(void* mem, cc_uint32 numElems, cc_uint32 elemsSize) {
|
||||
|
|
@ -57,12 +64,12 @@ void Mem_Free(void* mem) {
|
|||
*#########################################################################################################################*/
|
||||
static int logY;
|
||||
void Platform_Log(const char* msg, int len) {
|
||||
char buf[128+1];
|
||||
len = min(len, 128);
|
||||
Mem_Copy(buf, msg, len);
|
||||
buf[len] = '\0';
|
||||
for (int i = 0; i < 20; i++)
|
||||
HwMdPutc(' ', 0x0000, 1 + i, logY);
|
||||
|
||||
for (int i = 0; i < min(len, 64); i++)
|
||||
HwMdPutc(msg[i], 0x0000, 1 + i, logY);
|
||||
|
||||
HwMdPuts(buf, 0x0000, 1, logY);
|
||||
logY = (logY + 1) % 26;
|
||||
}
|
||||
|
||||
|
|
@ -84,7 +91,7 @@ cc_uint64 Stopwatch_Measure(void) {
|
|||
|
||||
cc_uint64 Stopwatch_ElapsedMicroseconds(cc_uint64 beg, cc_uint64 end) {
|
||||
if (end < beg) return 0;
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void Stopwatch_Init(void) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue