patches.cpp
1 /* 2 Copyright Frank Bösing, 2017 3 4 This file is part of Teensy64. 5 6 Teensy64 is free software: you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation, either version 3 of the License, or 9 (at your option) any later version. 10 11 Teensy64 is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with Teensy64. If not, see <http://www.gnu.org/licenses/>. 18 19 Diese Datei ist Teil von Teensy64. 20 21 Teensy64 ist Freie Software: Sie können es unter den Bedingungen 22 der GNU General Public License, wie von der Free Software Foundation, 23 Version 3 der Lizenz oder (nach Ihrer Wahl) jeder späteren 24 veröffentlichten Version, weiterverbreiten und/oder modifizieren. 25 26 Teensy64 wird in der Hoffnung, dass es nützlich sein wird, aber 27 OHNE JEDE GEWÄHRLEISTUNG, bereitgestellt; sogar ohne die implizite 28 Gewährleistung der MARKTFÄHIGKEIT oder EIGNUNG FÜR EINEN BESTIMMTEN ZWECK. 29 Siehe die GNU General Public License für weitere Details. 30 31 Sie sollten eine Kopie der GNU General Public License zusammen mit diesem 32 Programm erhalten haben. Wenn nicht, siehe <http://www.gnu.org/licenses/>. 33 34 */ 35 36 #include "patches.h" 37 #include "emuapi.h" 38 #include "platform_config.h" 39 40 41 #define DIRECTORY ROMSDIR + "/\0" 42 43 static char filename[64]; 44 static char buffer[2]; 45 46 extern char * menuSelection(void); 47 48 void patchLOAD(void) { 49 50 int device; 51 int secondaryAddress; 52 uint16_t addr,size; 53 54 device = cpu.RAM[0xBA]; 55 if (device != 1) { 56 //Jump to unpatched original address: 57 cpu.pc = rom_kernal[cpu.pc - 0xe000 + 1] * 256 + rom_kernal[cpu.pc - 0xe000]; 58 return; 59 }; 60 61 62 #if XXX 63 if (cpu.RAM[cpu.RAM[0xBC] * 256 + cpu.RAM[0xBB]] == '$' && cpu.RAM[0xB7] == 1) { 64 //Directoy listing with LOAD "$" 65 printf("Listing of "); 66 printf(DIRECTORY); 67 printf("\n"); 68 file = SD.open(DIRECTORY); 69 int blocks, start, len; 70 addr = cpu.RAM[0x2C] * 256 + cpu.RAM[0x2B]; 71 72 /*first line of BASIC listing */ 73 start = addr; 74 cpu.RAM[addr++] = (start + 30) & 0xff; 75 cpu.RAM[addr++] = (start + 30) >> 8; 76 blocks = 0; 77 cpu.RAM[addr++] = blocks & 0xff; 78 cpu.RAM[addr++] = blocks >> 8; 79 80 const char title[] = "\x12\"TEENSY64 \" FB " VERSION; 81 strcpy((char * )&cpu.RAM[addr], title); 82 addr = start + 30; 83 84 while (true) { 85 entry = file.openNextFile(); 86 if (! entry) { 87 // no more files 88 break; 89 } 90 int offset; 91 if (!entry.isDirectory()) { 92 93 /* Listing to BASIC-RAM */ 94 start = addr; 95 offset = 0; 96 97 //pointer to next line: 98 cpu.RAM[addr++] = (start + 32) & 0xff; 99 cpu.RAM[addr++] = (start + 32) >> 8; 100 101 //# of blocks 102 blocks = ceil((float)entry.size()/256.0f); 103 cpu.RAM[addr++] = blocks & 0xff; 104 cpu.RAM[addr++] = blocks >> 8; 105 106 if (blocks < 100) { cpu.RAM[addr++] = ' '; offset++;} 107 if (blocks < 10) { cpu.RAM[addr++] = ' '; offset++; } 108 cpu.RAM[addr++] = ' '; 109 110 //filename: 111 cpu.RAM[addr++] = '"'; 112 char *s = (char * )&cpu.RAM[addr]; 113 entry.getName(s, 17); 114 while(*s) {*s = toupper(*s); s++;} 115 //strcpy((char * )&cpu.RAM[addr], entry.name()); 116 len = strlen((char * )&cpu.RAM[addr]); 117 118 if (len > 16) len = 16; 119 addr += len; 120 cpu.RAM[addr++] = '"'; 121 122 //fill with space 123 while ((addr-start) < (32)) { cpu.RAM[addr++] = ' ';} 124 125 //display "PRG" 126 addr = start + 23 + offset; 127 cpu.RAM[addr++] = ' '; 128 cpu.RAM[addr++] = 'P'; 129 cpu.RAM[addr++] = 'R'; 130 cpu.RAM[addr++] = 'G'; 131 132 //line-ending 133 cpu.RAM[start+31] = 0; 134 addr = start + 32; 135 136 /* Listing to serial console */ 137 itoa (blocks,filename,10); 138 len = strlen(filename); 139 while (len < 4) { strcat(filename," "); len++; }; 140 strcat(filename, "\""); 141 char nbuf[18] = {0}; 142 entry.getName(nbuf, 17); 143 strcat(filename, nbuf); 144 //strcat(filename, entry.getName()); 145 strcat(filename, "\""); 146 len = strlen(filename); 147 while (len < 18+4) { strcat(filename," "); len++; }; 148 strcat(filename," PRG "); 149 //printf(filename); 150 151 } 152 entry.close(); 153 } 154 file.close(); 155 156 /*add last line to BASIC listing*/ 157 start = addr; 158 cpu.RAM[addr++] = (start + 32) & 0xff; 159 cpu.RAM[addr++] = (start + 32) >> 8; 160 //# of blocks. todo : determine free space on sd card 161 blocks = 65535; 162 cpu.RAM[addr++] = blocks & 0xff; 163 cpu.RAM[addr++] = blocks >> 8; 164 if (blocks < 100) { cpu.RAM[addr++] = ' ';} 165 if (blocks < 10) { cpu.RAM[addr++] = ' ';} 166 const char blockfree[] = "BLOCKS FREE."; 167 168 strcpy((char * )&cpu.RAM[addr], blockfree); 169 len = strlen(blockfree); 170 addr += len; 171 while ((addr-start) < (32)) { cpu.RAM[addr++] = ' ';} 172 cpu.RAM[start+31] = 0; 173 cpu.RAM[start+32] = 0; 174 cpu.RAM[start+33] = 0; 175 176 cpu.y = 0x49; //Offset for "LOADING" 177 cpu.pc = 0xF12B; //Print and return 178 return; 179 } // end directory listing 180 #endif 181 182 //$B7 : Length of file name or disk command 183 //$BB-$BC: Pointer to current file name or disk command 184 memset(filename,0,sizeof(filename)); 185 if ( cpu.RAM[0xB7] == 0) { 186 strcpy(filename,menuSelection()); 187 } 188 else { 189 strncpy(filename, (char*)&cpu.RAM[cpu.RAM[0xBC] * 256 + cpu.RAM[0xBB]], cpu.RAM[0xB7] ); 190 } 191 secondaryAddress = cpu.RAM[0xB9]; 192 193 Serial.println("loading"); 194 //printf("%s,%d,%d:", filename, device, secondaryAddress); 195 #ifdef EXTERNAL_SD 196 tft.stopDMA(); 197 //emu_resetSD(); 198 tft.fillScreenNoDma( RGBVAL16(0x00,0x00,0x00) ); 199 #endif 200 if (emu_FileOpen(filename) == 0) { 201 //Serial.println("not found"); 202 cpu.pc = 0xf530; //Jump to $F530 203 #ifdef EXTERNAL_SD 204 tft.startDMA(); 205 #endif 206 return; 207 } 208 209 size = emu_FileSize(filename); 210 emu_FileOpen(filename); 211 emu_FileRead(buffer, 2); 212 addr = buffer[1] * 256 + buffer[0]; 213 emu_FileRead((char*)&cpu.RAM[addr], size - 2); 214 emu_FileClose(); 215 216 cpu.RAM[0xAF] = (addr + size - 2) & 0xff; 217 cpu.RAM[0xAE] = (addr + size - 2) / 256; 218 219 cpu.y = 0x49; //Offset for "LOADING" 220 cpu.pc = 0xF12B; //Print and return 221 emu_printf("loaded"); 222 #ifdef EXTERNAL_SD 223 tft.startDMA(); 224 #endif 225 return; 226 } 227 228 void patchSAVE(void) { 229 #ifdef XXX 230 int device; 231 int secondaryAddress; 232 uint16_t addr,size; 233 234 Serial.println("Patched SAVE"); 235 device = cpu.RAM[0xBA]; 236 if (device != 1) { 237 //Jump to unpatched original address: 238 cpu.pc = rom_kernal[cpu.pc - 0xe000 + 1] * 256 + rom_kernal[cpu.pc - 0xe000]; 239 return; 240 }; 241 242 if (!SDinitialized) { 243 cpu.pc = 0xF707; //Device not present error 244 Serial.println("SD Card not initialized"); 245 return; 246 } 247 248 if( !SD.exists(DIRECTORY) && SD.mkdir(DIRECTORY) ) { 249 cpu.pc = 0xF707; //Device not present error 250 Serial.println("SD: Could not create " DIRECTORY); 251 } 252 253 //$B7 : Length of file name or disk command 254 //$BB-$BC: Pointer to current file name or disk command 255 memset(filename,0,sizeof(filename)); 256 strcpy(filename, DIRECTORY); 257 strncat(filename, (char*)&cpu.RAM[cpu.RAM[0xBC] * 256 + cpu.RAM[0xBB]], cpu.RAM[0xB7] ); 258 259 secondaryAddress = cpu.RAM[0xB9]; 260 261 Serial.print(filename); 262 Serial.print(","); 263 Serial.print(device); 264 Serial.print(","); 265 Serial.print(secondaryAddress); 266 Serial.print(":"); 267 268 addr = cpu.RAM[cpu.a + 1] * 256 + cpu.RAM[cpu.a]; 269 size = (cpu.y * 256 + cpu.x) - addr; 270 271 buffer[0] = addr & 0xff; 272 buffer[1] = addr >> 8; 273 274 if (SD.exists(filename)) SD.remove(filename); 275 file = SD.open(filename, FILE_WRITE); 276 if (!file) { 277 Serial.println ("not possible."); 278 cpu.pc = 0xf530; //Jump to $F530 279 return; 280 } 281 file.write(buffer, 2); 282 file.write(&cpu.RAM[addr], size); 283 file.close(); 284 285 if (cpu.RAM[0x9D] & 128) { 286 uint16_t pushval = 0xF68D; 287 cpu.RAM[BASE_STACK + cpu.sp] = (pushval >> 8) & 0xFF; 288 cpu.RAM[BASE_STACK + ((cpu.sp - 1) & 0xFF)] = pushval & 0xFF; 289 cpu.sp -= 2; 290 291 cpu.y = 0x51; 292 cpu.pc = 0xF12F; 293 } else { 294 cpu.pc = 0xF68D; 295 } 296 297 Serial.println("saved."); 298 return; 299 #endif 300 }