-
Notifications
You must be signed in to change notification settings - Fork 38
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'libretro:master' into naive-disk-control
- Loading branch information
Showing
9 changed files
with
220 additions
and
79 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
#include "extern_c.h" | ||
|
||
#include <stdint.h> | ||
|
||
EXTERN_C_BEGIN | ||
|
||
/* | ||
Define the position of the primary label on each Opera disc, the | ||
block offset between avatars, and the index of the last avatar | ||
(i.e. the avatar count minus one). The latter figure *must* match | ||
the ROOT_HIGHEST_AVATAR figure from "filesystem.h", as the same | ||
File structure is use to read the label at boot time, and to provide | ||
access to the root directory. | ||
*/ | ||
|
||
#define DISC_LABEL_RECORD_TYPE 1 | ||
#define DISC_BLOCK_SIZE 2048 | ||
#define DISC_LABEL_OFFSET 225 | ||
#define DISC_LABEL_AVATAR_DELTA 32786 | ||
#define DISC_LABEL_HIGHEST_AVATAR 7 | ||
#define DISC_TOTAL_BLOCKS 330000 | ||
|
||
#define ROOT_HIGHEST_AVATAR 7 | ||
#define FILESYSTEM_MAX_NAME_LEN 32 | ||
|
||
#define VOLUME_STRUCTURE_OPERA_READONLY 1 | ||
#define VOLUME_STRUCTURE_LINKED_MEM 2 | ||
|
||
#define NVRAM_VOLUME_UNIQUE_ID -1 | ||
#define NVRAM_ROOT_UNIQUE_ID -2 | ||
#define VOLUME_SYNC_BYTE 'Z' | ||
#define VOLUME_SYNC_BYTE_LEN 5 | ||
#define VOLUME_COM_LEN 32 | ||
#define VOLUME_ID_LEN 32 | ||
|
||
/* | ||
// This disc won't necessarily cause a reboot when inserted. This flag is | ||
// advisory ONLY. Only by checking with cdromdipir can you be really sure. | ||
// Place in dl_VolumeFlags. Note: the first volume gets this flag also. | ||
*/ | ||
#define VOLUME_FLAGS_DATADISC 0x01 | ||
|
||
/* | ||
Data structures written on CD disc (Compact Disc disc?) | ||
*/ | ||
typedef struct DiscLabel DiscLabel; | ||
struct DiscLabel | ||
{ | ||
uint8_t dl_RecordType; /* Should contain 1 */ | ||
uint8_t dl_VolumeSyncBytes[VOLUME_SYNC_BYTE_LEN]; /* Synchronization byte */ | ||
uint8_t dl_VolumeStructureVersion; /* Should contain 1 */ | ||
uint8_t dl_VolumeFlags; /* Should contain 0 */ | ||
uint8_t dl_VolumeCommentary[VOLUME_COM_LEN]; /* Random comments about volume */ | ||
uint8_t dl_VolumeIdentifier[VOLUME_ID_LEN]; /* Should contain disc name */ | ||
uint32_t dl_VolumeUniqueIdentifier; /* Roll a billion-sided die */ | ||
uint32_t dl_VolumeBlockSize; /* Usually contains 2048 */ | ||
uint32_t dl_VolumeBlockCount; /* # of blocks on disc */ | ||
uint32_t dl_RootUniqueIdentifier; /* Roll a billion-sided die */ | ||
uint32_t dl_RootDirectoryBlockCount; /* # of blocks in root */ | ||
uint32_t dl_RootDirectoryBlockSize; /* usually same as vol blk size */ | ||
uint32_t dl_RootDirectoryLastAvatarIndex; /* should contain 7 */ | ||
uint32_t dl_RootDirectoryAvatarList[ROOT_HIGHEST_AVATAR+1]; | ||
}; | ||
|
||
typedef struct DirectoryHeader DirectoryHeader; | ||
struct DirectoryHeader | ||
{ | ||
int32_t dh_NextBlock; | ||
int32_t dh_PrevBlock; | ||
uint32_t dh_Flags; | ||
uint32_t dh_FirstFreeByte; | ||
uint32_t dh_FirstEntryOffset; | ||
}; | ||
|
||
#define DIRECTORYRECORD(AVATARCOUNT) \ | ||
uint32_t dir_Flags; \ | ||
uint32_t dir_UniqueIdentifier; \ | ||
uint32_t dir_Type; \ | ||
uint32_t dir_BlockSize; \ | ||
uint32_t dir_ByteCount; \ | ||
uint32_t dir_BlockCount; \ | ||
uint32_t dir_Burst; \ | ||
uint32_t dir_Gap; \ | ||
char dir_FileName[FILESYSTEM_MAX_NAME_LEN]; \ | ||
uint32_t dir_LastAvatarIndex; \ | ||
uint32_t dir_AvatarList[AVATARCOUNT]; | ||
|
||
typedef struct DirectoryRecord { | ||
DIRECTORYRECORD(1) | ||
} DirectoryRecord; | ||
|
||
#define DIRECTORY_LAST_IN_DIR 0x80000000 | ||
#define DIRECTORY_LAST_IN_BLOCK 0x40000000 | ||
|
||
EXTERN_C_END |
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
#pragma once | ||
|
||
#include <stdint.h> | ||
|
||
/* | ||
LinkedMemDisk defines a high-level "disk" which consists of a | ||
doubly-linked list of storage blocks in memory (RAM, ROM, NVRAM, | ||
or out on a gamesaver cartridge. LinkedMemDisks have a standard | ||
Opera label at offset 0, with a type code of 2. The linked list | ||
normally begins immediately after the label; its offset is given | ||
by the zero'th avatar of the root directory. LinkedMemDisks are, | ||
by definition, flat file systems and cannot contain directories. | ||
*/ | ||
|
||
#define FINGERPRINT_FILEBLOCK 0xBE4F32A6 | ||
#define FINGERPRINT_FREEBLOCK 0x7AA565BD | ||
#define FINGERPRINT_ANCHORBLOCK 0x855A02B6 | ||
|
||
typedef struct LinkedMemBlock LinkedMemBlock; | ||
struct LinkedMemBlock | ||
{ | ||
uint32_t fingerprint; | ||
uint32_t flinkoffset; | ||
uint32_t blinkoffset; | ||
uint32_t blockcount; | ||
uint32_t headerblockcount; | ||
}; |
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
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
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,79 +1,81 @@ | ||
#include "discdata.h" | ||
#include "linkedmemblock.h" | ||
|
||
#include "opera_mem.h" | ||
|
||
#include "endianness.h" | ||
|
||
#include "boolean.h" | ||
|
||
#include <stdint.h> | ||
#include <string.h> | ||
|
||
#pragma pack(push,1) | ||
#define NVRAM_BLOCKSIZE 1 | ||
#define NVRAM_BLOCKCOUNT (32 * 1024) | ||
|
||
typedef struct nvram_header_t nvram_header_t; | ||
struct nvram_header_t | ||
bool | ||
opera_nvram_initialized(void *buf_, | ||
const int bufsize_) | ||
{ | ||
uint8_t record_type; | ||
uint8_t sync_bytes[5]; | ||
uint8_t record_version; | ||
uint8_t flags; | ||
uint8_t comment[32]; | ||
uint8_t label[32]; | ||
uint32_t id; | ||
uint32_t block_size; | ||
uint32_t block_count; | ||
uint32_t root_dir_id; | ||
uint32_t root_dir_blocks; | ||
uint32_t root_dir_block_size; | ||
uint32_t last_root_dir_copy; | ||
uint32_t root_dir_copies[8]; | ||
int i; | ||
DiscLabel *dl; | ||
|
||
uint32_t unknown_value0; | ||
uint32_t unknown_value1; | ||
uint32_t unknown_value2; | ||
uint32_t unknown_value3; | ||
uint32_t unknown_value4; | ||
uint32_t unknown_value5; | ||
uint32_t unknown_value6; | ||
uint32_t unknown_value7; | ||
uint32_t blocks_remaining; | ||
uint32_t unknown_value8; | ||
}; | ||
dl = (DiscLabel*)buf_; | ||
|
||
#pragma pack(pop) | ||
if(dl->dl_RecordType != DISC_LABEL_RECORD_TYPE) | ||
return false; | ||
if(dl->dl_VolumeStructureVersion != VOLUME_STRUCTURE_LINKED_MEM) | ||
return false; | ||
for(i = 0; i < VOLUME_SYNC_BYTE_LEN; i++) | ||
{ | ||
if(dl->dl_VolumeSyncBytes[i] != VOLUME_SYNC_BYTE) | ||
return false; | ||
} | ||
|
||
return true; | ||
} | ||
|
||
// The below code mimics the official 3DO formatting tool "format" | ||
// https://github.com/trapexit/portfolio_os/blob/master/src/filesystem/format.c | ||
// https://github.com/trapexit/portfolio_os/blob/master/src/filesystem/lmadm.c | ||
void | ||
opera_nvram_init(void) | ||
opera_nvram_init(void *buf_, | ||
const int bufsize_) | ||
{ | ||
nvram_header_t *nvram_hdr = (nvram_header_t*)NVRAM; | ||
DiscLabel *disc_label; | ||
LinkedMemBlock *anchor_block; | ||
LinkedMemBlock *free_block; | ||
|
||
disc_label = (DiscLabel*)buf_; | ||
anchor_block = (LinkedMemBlock*)&disc_label[1]; | ||
free_block = &anchor_block[1]; | ||
|
||
memset(buf_,0,bufsize_); | ||
|
||
disc_label->dl_RecordType = DISC_LABEL_RECORD_TYPE; | ||
memset(disc_label->dl_VolumeSyncBytes,VOLUME_SYNC_BYTE,VOLUME_SYNC_BYTE_LEN); | ||
disc_label->dl_VolumeStructureVersion = VOLUME_STRUCTURE_LINKED_MEM; | ||
disc_label->dl_VolumeFlags = 0; | ||
strncpy((char*)disc_label->dl_VolumeCommentary,"opera formatted", VOLUME_COM_LEN); | ||
strncpy((char*)disc_label->dl_VolumeIdentifier,"nvram", VOLUME_ID_LEN); | ||
disc_label->dl_VolumeUniqueIdentifier = swap32_if_le(NVRAM_VOLUME_UNIQUE_ID); // ??? | ||
disc_label->dl_VolumeBlockSize = swap32_if_le(NVRAM_BLOCKSIZE); | ||
disc_label->dl_VolumeBlockCount = swap32_if_le(bufsize_); | ||
disc_label->dl_RootUniqueIdentifier = swap32_if_le(NVRAM_ROOT_UNIQUE_ID); | ||
disc_label->dl_RootDirectoryBlockCount = 0; | ||
disc_label->dl_RootDirectoryBlockSize = swap32_if_le(NVRAM_BLOCKSIZE); | ||
disc_label->dl_RootDirectoryLastAvatarIndex = 0; | ||
disc_label->dl_RootDirectoryAvatarList[0] = swap32_if_le(sizeof(DiscLabel)); | ||
|
||
memset(nvram_hdr,0,sizeof(nvram_header_t)); | ||
anchor_block->fingerprint = swap32_if_le(FINGERPRINT_ANCHORBLOCK); | ||
anchor_block->flinkoffset = swap32_if_le(sizeof(DiscLabel) + sizeof(LinkedMemBlock)); | ||
anchor_block->blinkoffset = swap32_if_le(sizeof(DiscLabel) + sizeof(LinkedMemBlock)); | ||
anchor_block->blockcount = swap32_if_le(sizeof(LinkedMemBlock)); | ||
anchor_block->headerblockcount = swap32_if_le(sizeof(LinkedMemBlock)); | ||
|
||
nvram_hdr->record_type = 0x01; | ||
nvram_hdr->sync_bytes[0] = 'Z'; | ||
nvram_hdr->sync_bytes[1] = 'Z'; | ||
nvram_hdr->sync_bytes[2] = 'Z'; | ||
nvram_hdr->sync_bytes[3] = 'Z'; | ||
nvram_hdr->sync_bytes[4] = 'Z'; | ||
nvram_hdr->record_version = 0x02; | ||
nvram_hdr->label[0] = 'N'; | ||
nvram_hdr->label[1] = 'V'; | ||
nvram_hdr->label[2] = 'R'; | ||
nvram_hdr->label[3] = 'A'; | ||
nvram_hdr->label[4] = 'M'; | ||
nvram_hdr->id = swap32_if_little_endian(0xFFFFFFFF); | ||
nvram_hdr->block_size = swap32_if_little_endian(0x00000001); | ||
nvram_hdr->block_count = swap32_if_little_endian(0x00008000); | ||
nvram_hdr->root_dir_id = swap32_if_little_endian(0xFFFFFFFE); | ||
nvram_hdr->root_dir_blocks = swap32_if_little_endian(0x00000000); | ||
nvram_hdr->root_dir_block_size = swap32_if_little_endian(0x00000001); | ||
nvram_hdr->last_root_dir_copy = swap32_if_little_endian(0x00000000); | ||
nvram_hdr->root_dir_copies[0] = swap32_if_little_endian(0x00000084); | ||
nvram_hdr->unknown_value0 = swap32_if_little_endian(0x855A02B6); | ||
nvram_hdr->unknown_value1 = swap32_if_little_endian(0x00000098); | ||
nvram_hdr->unknown_value2 = swap32_if_little_endian(0x00000098); | ||
nvram_hdr->unknown_value3 = swap32_if_little_endian(0x00000014); | ||
nvram_hdr->unknown_value4 = swap32_if_little_endian(0x00000014); | ||
nvram_hdr->unknown_value5 = swap32_if_little_endian(0x7AA565BD); | ||
nvram_hdr->unknown_value6 = swap32_if_little_endian(0x00000084); | ||
nvram_hdr->unknown_value7 = swap32_if_little_endian(0x00000084); | ||
nvram_hdr->blocks_remaining = swap32_if_little_endian(0x00007F68); | ||
nvram_hdr->unknown_value8 = swap32_if_little_endian(0x00000014); | ||
free_block->fingerprint = swap32_if_le(FINGERPRINT_FREEBLOCK); | ||
free_block->flinkoffset = swap32_if_le(sizeof(DiscLabel)); | ||
free_block->blinkoffset = swap32_if_le(sizeof(DiscLabel)); | ||
free_block->blockcount = swap32_if_le(bufsize_ - sizeof(DiscLabel) - sizeof(LinkedMemBlock)); | ||
free_block->headerblockcount = swap32_if_le(sizeof(LinkedMemBlock)); | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,9 @@ | ||
#ifndef OPERA_NVRAM_H_INCLUDED | ||
#define OPERA_NVRAM_H_INCLUDED | ||
|
||
void opera_nvram_init(void); | ||
#include "boolean.h" | ||
|
||
bool opera_nvram_initialized(void *buf, const int bufsize); | ||
void opera_nvram_init(void *buf, const int bufsize); | ||
|
||
#endif |
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