-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathprg.cpp
More file actions
130 lines (119 loc) · 3.69 KB
/
Copy pathprg.cpp
File metadata and controls
130 lines (119 loc) · 3.69 KB
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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#include <stdio.h>
#include <string.h>
#include "tedmem.h"
#include "types.h"
static FILE *prg;
static unsigned char lpBufPtr[0x10000];
static void prgLoadFromBuffer(unsigned short &adr, unsigned int size, unsigned char *buf, TED *mem )
{
unsigned int endaddr = adr + size;
for (unsigned int i = 0; i < size; i++)
mem->poke(adr + i, buf[i]);
mem->Write(0x2D,(endaddr)&0xFF);
mem->Write(0x2E,(endaddr)>>8);
mem->Write(0x2F,(endaddr)&0xFF);
mem->Write(0x30,(endaddr)>>8);
mem->Write(0x31,(endaddr)&0xFF);
mem->Write(0x32,(endaddr)>>8);
unsigned short loadEndAddPtr = mem->getEndLoadAddressPtr();
mem->Write(loadEndAddPtr,(endaddr)&0xFF);
mem->Write(loadEndAddPtr + 1,(endaddr)>>8);
}
bool PrgLoad(const char *fname, int loadaddress, TED *mem)
{
unsigned short loadaddr;
unsigned int fsize;
char *fext;
int p00offset = 0;
if ((prg = fopen(fname, "rb"))== NULL) {
return false;
} else {
fext = (char *) strrchr( fname, '.');
if (!strcmp( fext, ".p00") || !strcmp(fext, ".P00"))
p00offset = 26;
// load PRG file
fseek(prg, 0L, SEEK_END);
fsize = ftell(prg) - p00offset;
fsize &= 0xFFFF;
fseek(prg, p00offset, SEEK_SET);
fread(lpBufPtr, 1, fsize, prg);
fclose(prg);
if (fsize < 2)
return false;
// copy to memory
if (loadaddress&0x10000)
loadaddr = loadaddress&0xFFFF;
else
loadaddr = lpBufPtr[0]|(lpBufPtr[1] << 8);
fsize -= 2;
// Some VIC20 PRG's are actually cartridges
if (mem->getEmulationLevel() == 3) {
if (loadaddr == 0xA000)
mem->loadromfromfile(1, fname, 0);
else {
const unsigned short currMemSize = mem->getRamSize();
if (currMemSize < 8 && loadaddr == 0x1201)
mem->setRamSize(3 + 16);
else if (currMemSize != 3 && loadaddr == 0x1001)
mem->setRamSize(3);
else if (currMemSize != 6 && loadaddr == 0x0401)
mem->setRamSize(6);
if (currMemSize != mem->getRamSize()) {
mem->Reset(2);
unsigned int frames = mem->getAutostartDelay();
while (frames--)
mem->ted_process(1);
fprintf(stderr, "RAM size changed to %u kB\n", mem->getRamSize());
}
prgLoadFromBuffer(loadaddr, fsize, lpBufPtr + 2, mem);
}
}
else
prgLoadFromBuffer(loadaddr, fsize, lpBufPtr + 2, mem);
}
fprintf( stderr, "Loaded: %s at $%04X-$%04X\n", fname, loadaddr, loadaddr + fsize);
return true;
}
bool prgLoadFromT64(const char *t64path, unsigned short *loadAddress, TED *mem)
{
bool rv = false;
if ((prg = fopen(t64path, "rb"))) {
unsigned char dirEntry[32];
fseek(prg, 0x40, SEEK_SET);
if (fread(dirEntry, 1, 32, prg) == 32) {
// PRG type?
if (dirEntry[1]) {
unsigned short adr = dirEntry[2] | (dirEntry[3] << 8);
unsigned short endAddr = dirEntry[4] | (dirEntry[5] << 8);
int fsize = int(endAddr - adr);
if (fsize > 0) {
unsigned int offsetInFile = dirEntry[8] | (dirEntry[9] << 8) | (dirEntry[10] << 16) | (dirEntry[11] << 24);
fseek(prg, offsetInFile, SEEK_SET);
if (fread(lpBufPtr, 1, fsize, prg)) {
prgLoadFromBuffer(adr, fsize, lpBufPtr, mem);
fprintf(stderr, "First PRG loaded from '%s' to $%04X-$%04X\n", t64path, adr, endAddr);
rv = true;
}
}
}
}
fclose(prg);
}
return rv;
}
bool prgSaveBasicMemory(const char *prgname, TED *mem, unsigned short &beginAddr, unsigned short &endAddr, bool isBasic)
{
if ((prg = fopen(prgname, "wb"))) {
if (isBasic || beginAddr >= endAddr) {
beginAddr = (mem->Read(0x2C) << 8) | mem->Read(0x2B);
endAddr = (mem->Read(0x2E) << 8) | mem->Read(0x2F);
}
fputc(beginAddr & 0xFF, prg);
fputc(beginAddr >> 8, prg);
for(unsigned int i = beginAddr; i <= endAddr; i++)
fputc(mem->Ram[i], prg);
fclose(prg);
fprintf(stderr, "Memory $%04X-$%04X saved to %s\n", beginAddr, endAddr, prgname);
}
return false;
}