📄 vmu.c
字号:
/* vmu.c
* thanks to Ken Friece for this code
*
*/
#include <kos.h>
#include "vmu.h"
void dc_print (char *fmt, ...);
void print_uint32 (uint32 val);
uint8 init_vmu() {
return(maple_first_vmu());
}
void novmu() {
printf("No VMU present!\r\n");
/* must add a "no vmu found" screen here */
}
uint16 calcCRC(const unsigned char *buf, int size) {
int i, c, n = 0;
for (i = 0; i < size; i++) {
n ^= (buf[i]<<8);
for (c = 0; c < 8; c++)
if (n & 0x8000)
n = (n << 1) ^ 4129;
else
n = (n << 1);
}
return (n & 0xffff);
}
uint16 get_next_block_from_fat (uint16 block_number) {
uint8 addr = maple_first_vmu();
uint16 fatblock;
uint8 buf[512];
uint16 *buf16 = (uint16*)buf;
//uint8 free_blocks = 0;
if (vmu_block_read(addr, 255, buf)) {
return 0;
}
thd_sleep(30);
fatblock = buf16[0x46/2];
if (vmu_block_read(addr, fatblock, buf) != 0) {
return 0;
}
thd_sleep(30);
return buf16[block_number];
}
uint16 check_vmu_for_game (const char* game_name) {
int i, n;
uint8 addr = maple_first_vmu(), *ent;
uint8 buf[512];
uint16 *buf16 = (uint16*)buf, dirblock, dirlength;//, *ent16;
//uint16 icondata = 0;
char *rom_name = (char *)malloc(12);
uint8 filename_size = strlen (game_name);
int number = 0;
/* Make sure we have a VMU */
if (!addr) {
novmu();
free(rom_name);
return 0;
}
for (i=0; i<11; i++) {
if (i < filename_size)
rom_name[i] = game_name[i];
else
rom_name[i] = ' ';
}
rom_name[11] = '&';
/* Read the root block and find out where the directory is located */
if (vmu_block_read(addr, 255, buf)) {
printf("Can't read VMU root block\r\n");
// return 0;
}
thd_sleep(30);
dirblock = buf16[0x4a/2]; dirlength = buf16[0x4c/2];
/* Draw entries and look for the ICONDATA.VMS entry */
for (n=dirlength; n>0; n--) {
/* Read one dir block */
if (vmu_block_read(addr, dirblock, buf) != 0) {
printf("Can't read VMU block %d\r\n", dirblock);
free(rom_name);
return 0;
}
thd_sleep(30);
/* Each block has 16 entries */
for (i=0; i<16; i++) {
dirent_vmu *vmu_val = (dirent_vmu *)ent;
int ii;
ent = buf+i*32;
//dc_print (testing->filename);
//thd_sleep (1000);
if (!*ent) {
continue;
}
number = 0;
for (ii=0; ii<12; ii++) {
if (ent[ii+4] == rom_name[ii]) {
number++;
}
}
if (number == 12) {
uint8 buf2[512];
file_hdr_vmu *hdr_ptr = (file_hdr_vmu *)buf2;
if (vmu_block_read(addr, vmu_val->firstblk, buf2)) {
printf("Can't read VMU root block\r\n");
}
thd_sleep(30);
if ((strcmp (hdr_ptr->desc_short, game_name) == 0) && (strcmp (hdr_ptr->app_id, "***NesterDC***") == 0)) {
free(rom_name);
return vmu_val->firstblk;
}
}
}
dirblock--;
}
free(rom_name);
return 0;
}
void update_fat (uint8 *free_mem, uint8 blocks_left) {
uint8 addr = maple_first_vmu();
uint16 fatblock;
uint8 buf[512];
uint16 *buf16 = (uint16*)buf;
uint16 this_block = 0;
//uint16 blocks_left = 18;
uint8 max_block = blocks_left;
int i;
if (vmu_block_read(addr, 255, buf)) {
return;
}
thd_sleep (30);
fatblock = buf16[0x46/2];
if (vmu_block_read(addr, fatblock, buf) != 0) {
return;
}
thd_sleep (30);
for (i=0; i<200; i++) {
if (free_mem[199-i] == 1) {
/* first file block */
if (blocks_left == max_block) {
this_block = 199 - i;
}
/* need the next one */
if (blocks_left < max_block) {
buf16[this_block] = 199 - i;
this_block = 199 - i;
}
blocks_left--;
}
/* last file block */
if (blocks_left == 0) {
buf16[this_block] = 0xfffa;
break;
}
}
if (vmu_block_write (addr, fatblock, (uint8 *)buf16) != 0) {
dc_print("there was an error updating the fat");
}
thd_sleep (30);
}
void upload_vmu_data (uint8 *vmu_file, uint8 *free_mem, uint8 blocks_left) {
uint8 addr = maple_first_vmu();
//uint8 blocks_left = 18;
uint8 *temp_ptr = vmu_file;
uint8 *temp_p = (uint8 *)malloc(512);
int i;
for (i=0; i<200; i++) {
if (free_mem[199-i] == 1) {
if (vmu_block_read (addr, 199-i, temp_p) != 0) {
dc_print ("there was an error reading data");
print_uint32 ((uint32)blocks_left);
}
thd_sleep(30);
if (vmu_block_write (addr, 199-i, temp_ptr) != 0) {
dc_print ("there was an error writing data");
print_uint32 ((uint32)blocks_left);
}
blocks_left--;
temp_ptr += 512;
thd_sleep (30);
}
if (blocks_left == 0) break;
}
free(temp_p);
}
void upload_data_by_block (uint8 *vmu_file, uint16 block_number, uint8 blocks_left) {
uint8 addr = maple_first_vmu();
uint8 *temp_p = (uint8 *)malloc(512);
uint8 *temp_ptr = vmu_file;
uint16 block_copy = block_number;
int i;
for (i=0; i<blocks_left; i++) {
//dc_print ("the block number we are on is");
//print_uint32 ((uint32)block_number);
//thd_sleep (2000);
block_copy = block_number;
if (vmu_block_read (addr, block_copy, temp_p) != 0) {
dc_print ("there was an error reading data");
print_uint32 ((uint32)block_number);
thd_sleep(2000);
}
thd_sleep (30);
block_copy = block_number;
if (vmu_block_write (addr, block_copy, temp_ptr) != 0) {
dc_print ("there was an error writing data");
print_uint32 ((uint32)block_number);
thd_sleep(2000);
}
thd_sleep (30);
temp_ptr += 512;
block_number = get_next_block_from_fat (block_number);
}
free(temp_p);
}
void update_vmu_dir (uint16 block, const char *filename, uint8 blocks) {
int i, ii, n;//, drawn = 0;
uint8 addr = maple_first_vmu(), *ent;
uint8 buf[512];
//uint8 *buf_ptr = buf;
uint16 *buf16 = (uint16*)buf, dirblock, dirlength;//, *ent16;
//uint16 icondata = 0;
dirent_vmu *dir_entry;
if (!addr) {
novmu();
printf("No VMU present!\r\n");
return;
}
/* Read the root block and find out where the directory is located */
if (vmu_block_read(addr, 255, buf)) {
dc_print("There was an error reading the root block");
printf("Can't read VMU root block\r\n");
}
thd_sleep (30);
dirblock = buf16[0x4a/2]; dirlength = buf16[0x4c/2];
dir_entry = (dirent_vmu *)malloc(1);
//uint8 *dir_entry = (uint8*)malloc(32);
create_dir_vmu (dir_entry, filename, block, blocks);
/* Draw entries and look for the ICONDATA.VMS entry */
for (n=dirlength; n>0; n--) {
/* Read one dir block */
if (vmu_block_read(addr, dirblock, buf) != 0) {
dc_print ("There was an error reading the dirblock");
printf("Can't read VMU block %d\r\n", dirblock);
free(dir_entry);
return;
}
thd_sleep(30);
/* Each block has 16 entries */
for (i=0; i<16; i++) {
ent = buf+i*32;
if (!*ent) {
uint8 *temp_ptr = (uint8 *)dir_entry;
for (ii=0; ii<32; ii++) {
ent[ii] = temp_ptr[ii];
}
if (vmu_block_write(addr, dirblock, buf) != 0) {
dc_print("There was an error updating the directory");
}
vmu_block_read(addr, dirblock, buf);
thd_sleep(30);
free(dir_entry);
return;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -