-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgsslam.c
107 lines (90 loc) · 2.29 KB
/
gsslam.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
FILE* fdata;
int h;
int len;
int addr;
typedef struct seg {
int length;
int address;
unsigned char* buffer;
} seg;
void err(char* msg){
printf("ERROR: %s",msg);
exit(0);
}
int read3(FILE* fptr){
char buf[3];
int i = fread(buf,3,1,fdata);
if(i==1)
return buf[0] + (buf[1]<<8) + (buf[2]<<16);
else
return -1;
}
int segRead(seg* seg, FILE* fptr) {
seg->length = read3(fptr);
if(seg->length <0) err("Unable to read segment length");
if(seg->length==0) return 0;
seg->address = read3(fptr);
if(seg->address <0) err("Unable to read segment addr");
seg->buffer = malloc(seg->length);
if(!seg->buffer) err("Unable to allocate buffer");
int i = fread(seg->buffer,seg->length,1,fptr);
if(i != 1) err("Unable to read into buffer");
return 1;
}
int segWrite(seg* seg,int han){
long i;
i = lseek(han,seg->address,SEEK_SET);
if(i != seg->address) err("Unable to seek to segment position in RAM");
i = write(han,seg->buffer,seg->length);
if(i != seg->length) err("Unable to write segment to RAM");
return seg->length;
}
void segFree(seg* seg){
free(seg->buffer);
}
void segPrint(seg* seg){
printf("$%06X: $%06X bytes",seg->address,seg->length);
}
unsigned main(int argc,char**argv) {
int i;
if(argc != 3) {
printf(
"Usage: gsslam <filename> <ramfile>\n\n"\
"Slam a 'nonlinear' format file generated by 64TASS 65c816 assembler\n"\
"into a modified GSplus emulator's RAM backing file <ramfile>\n"\
"Nonlinear files consist of segments. Each starts with a header\n"\
"containing a 3-byte size and a 3-byte address, followed by data.\n");
exit(0);
}
// Read the head, and unpack 3-byte length and address fields
fdata = fopen(argv[1],"rb");
if(!fdata) err("Unable to open binary file");
// open RAM and write data
h = open(argv[2],O_RDWR);
if(h==-1) err("unable to open RAM");
seg seg;
while(i=segRead(&seg,fdata)){
i=segWrite(&seg,h);
segPrint(&seg);
segFree(&seg);
printf("\n");
}
close(h);
fclose(fdata);
/*
printf("opened RAM.bin: %x\n",h);
pos = lseek(h,0x5BC,SEEK_SET);
printf("seek: %x\n",pos);
pos = write(h,&q,1);
printf("wrote: %x\n",pos);
fsync(h);
close(h);
*/
return 0;
}