Created
May 5, 2020 08:36
-
-
Save Ced2911/4b5f03b9b1f93049b6d09a07e3c7a742 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Copyright 2014 Theo Berkau | |
This file is part of PseudoSaturn. | |
PseudoSaturn is free software; you can redistribute it and/or modify | |
it under the terms of the GNU General Public License as published by | |
the Free Software Foundation; either version 2 of the License, or | |
(at your option) any later version. | |
PseudoSaturn is distributed in the hope that it will be useful, | |
but WITHOUT ANY WARRANTY; without even the implied warranty of | |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
GNU General Public License for more details. | |
You should have received a copy of the GNU General Public License | |
along with PseudoSaturn; if not, write to the Free Software | |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
*/ | |
/* | |
Program that installs PseudoSaturn firmware to flash. | |
*/ | |
#include <string.h> | |
#include <stdio.h> | |
#include <iapetus.h> | |
#include "version.h" | |
#define CODE_IN_LRAM __attribute__((section(".lram_data"))) __attribute__((noinline)) __attribute__((optimize("O1"))) | |
static font_struct main_font; | |
#define CDWORKBUF ((void *)0x202C0000) | |
#define VDP1_TEXT_ADDR 0x20000 | |
#define VDP1_PAL_ADDR 0x40000 | |
u32 vdp_tile_start_address = 0x20000; | |
u32 vdp_tile_l_offset = 0; | |
u32 vdp_tile_u_offset = 0x8000; | |
//static uint16_t tiles_pixels[NB_TILE][8][8]; | |
//static uint16_t * tile_addr = (uint16_t*)&tiles_pixels; | |
static volatile uint8_t *tile_addr = (volatile uint8_t *)(VDP1_TEXT_ADDR + VDP1_RAM); | |
static volatile uint16_t ***tiles_pixels = (volatile uint16_t ***)(VDP1_TEXT_ADDR + VDP1_RAM); | |
static volatile uint16_t *pal_addr = (volatile uint16_t *)(VDP1_PAL_ADDR + VDP1_RAM); | |
static volatile uint8_t *pal_addr_u8 = (volatile uint8_t *)(VDP1_PAL_ADDR + VDP1_RAM); | |
void vdp2_scroll_test_set_map(screen_settings_struct *settings, int which) | |
{ | |
int i; | |
for (i = 0; i < 4; i++) | |
{ | |
settings->map[i] = which; | |
} | |
} | |
void ps_init() | |
{ | |
screen_settings_struct settings; | |
init_iapetus(RES_320x240); | |
// Setup a screen for us draw on | |
settings.is_bitmap = TRUE; | |
settings.bitmap_size = BG_BITMAP512x512; | |
settings.transparent_bit = 0; | |
settings.color = BG_256COLOR; | |
settings.special_priority = 0; | |
settings.special_color_calc = 0; | |
settings.extra_palette_num = 0; | |
settings.map_offset = 0; | |
settings.rotation_mode = 0; | |
settings.parameter_addr = 0x25E60000; | |
vdp_rbg0_init(&settings); | |
vdp_set_default_palette(); | |
// Setup the default 8x8 1BPP font | |
main_font.data = font_8x8; | |
main_font.width = 8; | |
main_font.height = 8; | |
main_font.bpp = 1; | |
main_font.out = (u8 *)0x25E00000; | |
vdp_set_font(SCREEN_RBG0, &main_font, 1); | |
/* | |
u16 *pal = (u16 *)(VDP1_RAM + PAL_ADDR); | |
pal[0] = RGB32TO16(0xFF, 0xFF, 0xFF) | 0x8000; | |
pal[1] = RGB32TO16(0xFF, 0xFF, 0xFF) | 0x8000; | |
pal[9] = RGB32TO16(0xFF, 0, 0) | 0x8000; | |
*/ | |
settings.is_bitmap = FALSE; | |
settings.bitmap_size = BG_BITMAP512x256; | |
settings.transparent_bit = 0; | |
settings.color = BG_16COLOR; //BG_256COLOR; | |
//settings.color = BG_256COLOR; | |
settings.special_priority = 0; | |
settings.special_color_calc = 0; | |
settings.extra_palette_num = 0; | |
settings.map_offset = 0; | |
settings.rotation_mode = 0; | |
settings.parameter_addr = 0; | |
settings.char_size = 0; | |
settings.plane_size = 0; | |
vdp2_scroll_test_set_map(&settings, 0); | |
vdp_nbg0_init(&settings); | |
// 16 bit color | |
// VDP2_REG_RAMCTL = (VDP2_REG_RAMCTL & 0xCFFF) | (2 << 12); | |
// Display everything | |
vdp_disp_on(); | |
} | |
#define GTMCommandLongTileIdx 0 // data -> tile index (24 bits); palette index (8 bits) | |
#define GTMCommandLoadPalette 1 // data -> palette index (8 bits); palette format (8 bits) (00: RGBA32); RGBA bytes (32bits) | |
// new commands here | |
#define GTMCommandFrameEnd 28 // commandBits bit 0 -> keyframe end | |
#define GTMCommandTileset 29 // data -> start tile (32 bits); end tile (32 bits); indexes per tile (64 bytes); commandBits -> indexes bit count | |
#define GTMCommandSetDimensions 30 // data -> height in tiles (16 bits); width in tiles (16 bits); frame length in nanoseconds (32 bits); tile count (32 bits); | |
#define GTMCommandExtendedCommand 31 // data -> custom commands, proprietary extensions, ...; commandBits -> extended command index | |
#define GTMCommandShortTileIdxStart 32 // short tile index #0 ...; commandBits: palette index (3 bits); V mirror (1 bit); H mirror (1 bit) | |
#define GTMCommandShortTileIdxEnd 1919 // ... short tile index #1887 | |
#define GTMCommandSkipBlockStart 1920 // skipping 128 tiles ... | |
#define GTMCommandSkipBlockEnd 2047 // ... skipping 1 tile | |
#define CTileWidth (8) | |
#define CTMAttrBits (1 + 1 + 3) // HMir + VMir + PalIdx | |
#define CShortIdxBits (16 - CTMAttrBits) | |
typedef struct | |
{ | |
uint16_t width; | |
uint16_t height; | |
uint32_t frame_length; | |
uint32_t tile_count; | |
uint32_t palette_size; | |
uint32_t tile_map_positon; | |
// file... | |
file_struct *gtm_file; | |
uint32_t file_size; | |
uint8_t *ptr; | |
uint8_t *frame_data; | |
uint32_t data_pos; | |
// saturn specific | |
uint16_t *palettes; | |
uint8_t *tiles; | |
} gtm_ctx; | |
void GTM_init(gtm_ctx *gtm_ctx, | |
file_struct *gtm_file, | |
uint8_t *file_fuffer) | |
{ | |
gtm_ctx->ptr = file_fuffer; | |
gtm_ctx->frame_data = file_fuffer; | |
gtm_ctx->data_pos = 0; | |
gtm_ctx->tile_map_positon = 0; | |
// saturn specific | |
gtm_ctx->file_size = gtm_file->size; | |
gtm_ctx->gtm_file = gtm_file; | |
} | |
#define CD_BUF 1024 * 600 | |
uint8_t GTM_readByte(gtm_ctx *gtm_ctx) | |
{ | |
if (gtm_ctx->data_pos >= CD_BUF) | |
{ | |
int ret = 0; | |
vdp_printf(&main_font, 10, 20, 15, "GTM_readByte read disc"); | |
if ((ret = cdfs_read(gtm_ctx->ptr, CD_BUF, 1, gtm_ctx->gtm_file)) != IAPETUS_ERR_OK) | |
{ | |
vdp_printf(&main_font, 10, 28, 15, "cdfs_read error %d ", ret); | |
while (1) | |
vdp_vsync(); | |
} | |
vdp_printf(&main_font, 10, 28, 15, "ok"); | |
gtm_ctx->data_pos = 0; | |
gtm_ctx->frame_data = gtm_ctx->ptr; | |
} | |
return gtm_ctx->frame_data[gtm_ctx->data_pos++]; | |
} | |
uint16_t GTM_readU16(gtm_ctx *gtm_ctx) | |
{ | |
//return GTM_readByte(gtm_ctx) | (GTM_readByte(gtm_ctx) << 8); | |
uint16_t d = *(uint16_t *)(gtm_ctx->frame_data + gtm_ctx->data_pos); | |
gtm_ctx->data_pos += 2; | |
return __builtin_bswap16(d); | |
} | |
uint32_t GTM_readU32(gtm_ctx *gtm_ctx) | |
{ | |
// return GTM_readU16(gtm_ctx) | (GTM_readU16(gtm_ctx) << 16); | |
uint32_t d = *(uint32_t *)(gtm_ctx->frame_data + gtm_ctx->data_pos); | |
gtm_ctx->data_pos += 4; | |
return __builtin_bswap32(d); | |
} | |
uint16_t GTM_readCommand(gtm_ctx *gtm_ctx) | |
{ | |
uint16_t v = GTM_readU16(gtm_ctx); | |
return v; | |
} | |
void GTM_drawTilemapItem(gtm_ctx *gtm_ctx, uint32_t idx, uint16_t attrs) | |
{ | |
uint32_t base = 0x000000; | |
volatile u32 *p = (volatile u32 *)(VDP2_RAM + base); | |
uint32_t x = (gtm_ctx->tile_map_positon % gtm_ctx->width); | |
uint32_t y = (gtm_ctx->tile_map_positon / gtm_ctx->width); | |
int special_priority = 0; | |
int special_color = 0; | |
uint32_t tile_addr = vdp_tile_start_address; | |
uint16_t palette = ((attrs >> 2)); | |
uint16_t tile = idx; | |
uint8_t flip = attrs & 3; | |
p[(y * 0x40) + x] = | |
(flip << 30) | | |
(special_priority << 29) | | |
(special_color << 28) | | |
(tile_addr >> 5) | | |
(tile) | | |
(palette << 16); | |
gtm_ctx->tile_map_positon++; | |
} | |
void decodeAllChr() | |
{ | |
volatile uint8_t *vdp_dst = (volatile u8 *)(VDP2_RAM + vdp_tile_start_address); | |
for (int n = 0; n < 1024; n++) | |
{ | |
for (int row = 0; row < 8; row++) | |
{ | |
for (int column = 0; column < 8; column++) | |
{ | |
vdp_dst[(n * 8 * 8) + (row * 8) + column] = n; | |
} | |
} | |
} | |
} | |
void debugPal(gtm_ctx *gtm_ctx) | |
{ | |
decodeAllChr(); | |
for (int i = 0; i < 1024; i++) | |
{ | |
gtm_ctx->tile_map_positon = i; | |
GTM_drawTilemapItem(gtm_ctx, i, 0); | |
} | |
while (1) | |
{ | |
vdp_vsync(); | |
} | |
} | |
void debugTile(gtm_ctx *gtm_ctx) | |
{ | |
for (int i = 0; i < 1024; i++) | |
{ | |
gtm_ctx->tile_map_positon = i; | |
GTM_drawTilemapItem(gtm_ctx, i, 0); | |
} | |
while (1) | |
{ | |
vdp_vsync(); | |
} | |
} | |
uint8_t GTM_decodeFrame(gtm_ctx *gtm_ctx) | |
{ | |
static uint16_t l = 0; | |
uint32_t cmd = GTM_readCommand(gtm_ctx); | |
uint16_t cmd_0 = cmd & ((1 << CShortIdxBits) - 1); | |
uint16_t cmd_1 = cmd >> CShortIdxBits; | |
if (l > 240) | |
{ | |
l = 0; | |
vdp_clear_screen(&main_font); | |
} | |
switch (cmd_0) | |
{ | |
case GTMCommandSetDimensions: | |
{ | |
gtm_ctx->width = GTM_readU16(gtm_ctx); | |
gtm_ctx->height = GTM_readU16(gtm_ctx); | |
gtm_ctx->frame_length = GTM_readU32(gtm_ctx); // / (1000 * 1000); | |
gtm_ctx->tile_count = GTM_readU32(gtm_ctx); | |
/* | |
vdp_printf(&main_font, 11, l += 8, 12, "gtm_ctx->width %d ", gtm_ctx->width); | |
vdp_printf(&main_font, 11, l += 8, 12, "gtm_ctx->height %d ", gtm_ctx->height); | |
vdp_printf(&main_font, 11, l += 8, 12, "gtm_ctx->frameLength %d ", gtm_ctx->frame_length); | |
vdp_printf(&main_font, 11, l += 8, 12, "gtm_ctx->tile_count %d ", gtm_ctx->tile_count); | |
while (1) | |
{ | |
vdp_vsync(); | |
} | |
*/ | |
break; | |
} | |
case GTMCommandTileset: | |
{ | |
uint32_t start = GTM_readU32(gtm_ctx); | |
uint32_t end = GTM_readU32(gtm_ctx); | |
gtm_ctx->palette_size = 1 << cmd_1; | |
volatile uint8_t *dst = gtm_ctx->tiles + (start * CTileWidth * CTileWidth); | |
for (uint32_t tile = start; tile <= end; tile++) | |
{ | |
for (uint32_t w = 0; w < (CTileWidth * CTileWidth) / 2; w++) | |
{ | |
uint8_t dot_0 = GTM_readByte(gtm_ctx); | |
uint8_t dot_1 = GTM_readByte(gtm_ctx); | |
*dst++ = (dot_0 << 4) | dot_1; | |
} | |
} | |
// debugTile(gtm_ctx); | |
break; | |
} | |
case GTMCommandLoadPalette: | |
{ | |
uint8_t palIdx = GTM_readByte(gtm_ctx); | |
uint8_t palFmt = GTM_readByte(gtm_ctx); | |
// vdp_printf(&main_font, 11, l += 8, 12, "palIdx %d ", palIdx); | |
volatile uint16_t *dst = gtm_ctx->palettes + (palIdx * gtm_ctx->palette_size); | |
//volatile uint32_t *dst = gtm_ctx->palettes + (palIdx * gtm_ctx->palette_size); | |
for (uint16_t i = 0; i < gtm_ctx->palette_size; i++) | |
{ | |
uint8_t r = GTM_readByte(gtm_ctx); | |
uint8_t g = GTM_readByte(gtm_ctx); | |
uint8_t b = GTM_readByte(gtm_ctx); | |
uint8_t a = GTM_readByte(gtm_ctx); | |
*dst++ = RGB555(r >> 3, g >> 3, b >> 3); | |
//*dst++ = (r << 0) | (g << 8) | (b << 16); | |
} | |
break; | |
} | |
case GTMCommandLongTileIdx: | |
{ | |
//debugPal(gtm_ctx); | |
uint32_t v = GTM_readU32(gtm_ctx); | |
GTM_drawTilemapItem(gtm_ctx, v & 0x00ffffff, (cmd_1 & 3) | ((v >> 22) & 0x3fc)); | |
break; | |
} | |
case GTMCommandFrameEnd: | |
gtm_ctx->tile_map_positon = 0; | |
// vdp_printf(&main_font, 11, l += 8, 12, "GTMCommandFrameEnd %d ", cmd_1); | |
// for (int i = 0; i < 240; i++) | |
for (int i = 0; i < 8; i++) | |
vdp_vsync(); | |
return -1; | |
break; | |
default: | |
if (cmd_0 >= GTMCommandShortTileIdxStart && cmd_0 <= GTMCommandShortTileIdxEnd) | |
{ | |
GTM_drawTilemapItem(gtm_ctx, cmd_0 - GTMCommandShortTileIdxStart, cmd_1); | |
} | |
else if (cmd_0 >= GTMCommandSkipBlockStart && cmd_0 <= GTMCommandSkipBlockEnd) | |
{ | |
gtm_ctx->tile_map_positon += GTMCommandSkipBlockEnd - cmd_0 + 1; | |
} | |
else | |
{ | |
vdp_printf(&main_font, 10, 20, 15, "Undecoded command %d", cmd_0); | |
while (1) | |
{ | |
vdp_vsync(); | |
} | |
//console.error('Undecoded command @' + gtmdata_pos + ': ' + cmd + '\n'); | |
} | |
break; | |
} | |
return 0; | |
} | |
extern uint8_t LRAM__start, LRAM__end, lram_ptr; | |
uint8_t *lram = (uint8_t *)0x00200000; | |
int main() | |
{ | |
#if 0 | |
uint8_t *src = &lram_ptr; | |
uint8_t *dst = &LRAM__start; | |
while (dst < &LRAM__end) | |
{ | |
*dst++ = *src++; | |
} | |
#endif | |
file_struct gtm_file; | |
int ret; | |
ps_init(); | |
vdp_printf(&main_font, 10, 0, 15, "Start", 0); | |
vdp_vsync(); | |
if ((ret = cdfs_init(CDWORKBUF, 4096)) != IAPETUS_ERR_OK) | |
{ | |
vdp_printf(&main_font, 11, 20, 15, "cdfs_init error %d ", ret); | |
vdp_vsync(); | |
return ret; | |
} | |
if ((ret = cdfs_open("GUNDAM", >m_file)) != IAPETUS_ERR_OK) | |
{ | |
vdp_printf(&main_font, 10, 20, 15, "cdfs_open error %d ", ret); | |
vdp_vsync(); | |
return ret; | |
} | |
if ((ret = cdfs_read(lram, CD_BUF, 1, >m_file)) != IAPETUS_ERR_OK) | |
{ | |
vdp_printf(&main_font, 10, 20, 15, "cdfs_read error %d ", ret); | |
vdp_vsync(); | |
return ret; | |
} | |
//vdp_printf(&main_font, 10, 20, 15, "volatile uint8_t *vdp_dst = (volatile u8 *)(VDP2_RAM + vdp_tile_start_address);", 0); | |
//vdp_vsync(); | |
volatile uint8_t *vdp_dst = (volatile u8 *)(VDP2_RAM + vdp_tile_start_address); | |
gtm_ctx gtm_ctx; | |
GTM_init(>m_ctx, >m_file, lram); | |
gtm_ctx.tiles = vdp_dst; | |
gtm_ctx.palettes = vdp2_cram; | |
if (0) | |
{ | |
gtm_ctx.width = 10; | |
// dbg ... | |
decodeAllChr(); | |
for (int i = 0; i < 16; i++) | |
{ | |
gtm_ctx.tile_map_positon = i + 10; | |
GTM_drawTilemapItem(>m_ctx, i, 0); | |
} | |
gtm_ctx.tile_map_positon = 0; | |
} | |
if (0) | |
while (1) | |
{ | |
vdp_vsync(); | |
} | |
for (;;) | |
{ | |
if (GTM_decodeFrame(>m_ctx) == -1) | |
{ | |
} | |
if (gtm_ctx.data_pos >= gtm_ctx.file_size) | |
{ | |
gtm_ctx.data_pos = 0; | |
} | |
} | |
return 0; | |
} | |
////////////////////////////////////////////////////////////////////////////// |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment