Changeset 27
- Timestamp:
- 10/22/09 21:01:41 (3 years ago)
- Location:
- trunk/src
- Files:
-
- 4 modified
-
Failboy.cpp (modified) (6 diffs)
-
Memory.cpp (modified) (2 diffs)
-
Memory.h (modified) (4 diffs)
-
cpu.h (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/Failboy.cpp
r26 r27 10 10 #include <SDL/SDL.h> 11 11 #include "failboy.h" 12 //#include "RenderSDL.h" 13 #include <time.h> 12 14 //using namespace std; 13 15 … … 40 42 } 41 43 44 //const clock_t inv = 1000/CLOCKS_PER_SEC; 45 //#define CLOCK_MS_DIV (1000)/(CLOCKS_PER_SEC) 46 //Returns the number of clock intervals to get ts milliseconds 47 //#define CLOCK_MS(ts) ((ts)/(CLOCK_MS_DIV)) 48 42 49 FILE *fileLoad(const char* filename) { 43 50 return fopen (filename, "rb"); … … 73 80 //Set up the screen 160x144 74 81 screen = SDL_SetVideoMode( 160*zoom, 144*zoom, 24, SDL_SWSURFACE | SDL_DOUBLEBUF ); 75 76 82 77 83 //If there was an error in setting up the screen … … 136 142 printf("\n"); 137 143 138 printf("Initializing Subsystems..\n"); 139 FILE* file = fileLoad("Tetris.gb"); 140 if(file == NULL) { 141 printf("Bad File!"); 142 return 1; 143 } 144 u32 size = fileSize(file); 145 if(size < 32768) { 146 printf(" Bad Cartridge Size.\n"); 147 fclose(file); 148 return 1; 149 } 150 printf("Initializing Cartridge.\n"); 151 Cart *cart = new Cart(size); 152 fread(cart->data,1,size,file); 153 fclose(file); 154 delete file; 155 file = NULL; 156 157 cart->initialize(); 158 // for(int i=0;i<0x200;i++) { 159 // printf("%02X ",cart->data[i]); 160 // if(!((i+1)%16)) printf("\n"); 144 // printf("Initializing Subsystems..\n"); 145 // FILE* file = fileLoad("Tetris.gb"); 146 // if(file == NULL) { 147 // printf("Bad File!"); 148 // return 1; 161 149 // } 162 printf("Initializing Video.\n"); 163 Video *video = new Video(); 164 printf("Initializing Memory Controller.\n"); 165 Memory *mem = new Memory(cart, video); 150 // u32 size = fileSize(file); 151 // if(size < 32768) { 152 // printf(" Bad Cartridge Size.\n"); 153 // fclose(file); 154 // return 1; 155 // } 156 // printf("Initializing Cartridge.\n"); 157 // Cart *cart = new Cart(size); 158 // fread(cart->data,1,size,file); 159 // fclose(file); 160 // delete file; 161 // file = NULL; 162 // 163 // cart->initialize(); 164 // 165 // printf("Initializing Video.\n"); 166 // Video *video = new Video(); 167 // printf("Initializing Memory Controller.\n"); 168 Memory *mem = new Memory(); 166 169 printf("Initializing Processor.\n"); 167 170 CPU *cpu = new CPU(mem); 168 171 169 170 printf("Initialization Complete.\n"); 171 172 // for(int i=0;i<100;i++) { 173 // event_handle(); 174 // SDL_Delay(10); 175 // } 176 177 u32 cycle = 0; 178 s32 Counter = 70224; 172 // printf("Initializing Rendering System.\n"); 173 // RenderSDL *render = new RenderSDL(screen, video); 174 // printf("Initialization Complete.\n"); 175 176 s32 Counter = 0; 177 clock_t s = clock(); 179 178 while(!quit) { 180 179 event_handle(); … … 190 189 } 191 190 191 // printf("Run CPU Step\n"); 192 192 //Run the CPU cycle 193 193 u8 time = cpu->step(); … … 199 199 } 200 200 } 201 Counter -= time;201 Counter += time; 202 202 203 203 if(cpu->stop) continue; 204 204 //SDL_Delay(100); 205 205 206 mem->time->run(time); 207 208 //Run Interrupts, etc 209 if(interrupt || Counter <= 0) { 210 if(!(++cycle % 2)) 211 SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format,255,255,255)); 212 else 213 SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format,0,0,0)); 214 215 if( SDL_Flip( screen ) == -1 ) { 216 return 2; 217 } 218 //if(cycle%3) SDL_Delay(17); else 219 SDL_Delay(8); 220 221 Counter += 70224; //?? 222 223 //Counter+=InterruptPeriod; 224 interrupt = false; 225 } 226 } 206 // mem->time->run(time); 207 // mem->vid->run(time); 208 // render->render(); 209 210 clock_t t = clock(); 211 if(Counter >= 41943) { 212 if(t-s < 10) { 213 u8 time = 10 - (t - s); 214 SDL_Delay(time); 215 } 216 s = clock(); 217 } 218 } 219 // delete render; 227 220 delete cpu; 228 221 delete mem; 229 delete video;222 // delete video; 230 223 231 224 //shutdown(); -
trunk/src/Memory.cpp
r26 r27 2 2 * Memory.cpp 3 3 * 4 * Created on: Sep 21, 20094 * Created on: Oct 22, 2009 5 5 * Author: Chase 6 6 */ 7 7 8 8 #include "Memory.h" 9 10 void Cart::initialize() {11 printf(" Determining ROM Type.\n");12 type = data[0x0147];13 romsize = data[0x0148];14 ramsize = data[0x0149];15 16 //for now we only have ROM17 printf(" Setting up pointers.\n");18 rom0 = &data[0];19 rom1 = &data[0x4000];20 }21 22 void Cart::write(u16 addr, u8 val) {23 if(addr >= 0xA000 && addr < 0xC000) {24 if(!ramsize) {25 //do no writing26 }27 } else {28 //No extra chip support yet29 }30 }31 32 u8 Cart::read(u16 addr) {33 if(addr >= 0xA000 && addr < 0xC000) {34 if(!ramsize) {35 //nothing is here36 }37 } else {38 if(addr < 0x4000) {39 return rom0[addr];40 } else if(addr < 0x8000) {41 return rom1[addr-0x4000];42 }43 }44 return (u8)rand(); //return garbage45 }46 47 Video::Video() {48 printf(" Allocating Video Ram Tables.\n");49 vram = (u8*)malloc(0x2000);50 oam = (u8*)malloc(0xA0);51 lCount = 0;52 access = false;53 enabled = true;54 }55 56 void Video::setMemory(Memory*m) {57 mem = m;58 }59 60 void Video::run(u8 time) {61 if(!enabled) return;62 //we are not on, so we are not rendering63 //lines, so no LY, etc64 lCount += time;65 66 if(LY < 144) {67 if(lCount < 80) {68 STAT = (STAT & 0xFC) | 2;69 access = true;70 //READING OAM HERE71 if(STAT & OINT) {72 mem->IF |= mem->INT48;73 }74 } else if(lCount < 252) {75 STAT = (STAT & 0xFC) | 3;76 access = false;77 //READING EVERYTHING HERE78 } else if(lCount < 456) {79 STAT = (STAT & 0xFC) | 0;80 if(STAT & HINT) {81 mem->IF |= mem->INT48;82 }83 } else { //if(lCount >= 456) {84 STAT = (STAT & 0xFC) | 1;85 LY++;86 lCount -= 456;87 //Set V-Blank88 mem->IF |= mem->INT40;89 }90 } else {91 if(lCount >= 456) {92 LY++;93 lCount -= 456;94 if(LY > 153) LY = 0;95 }96 }97 98 //Set LYC-LC coincident if needed99 if(LY != LYC) STAT &= ~(1<<2);100 else {101 STAT |= (1<<2);102 if(STAT & LINT) {103 mem->IF |= mem->INT48;104 }105 }106 107 }108 109 u8 Video::write(u16 addr, u8 val) {110 if(addr == 0xFF40) {111 //bit 7 turns on or off the LCD112 LCDC = val;113 if(LCDC & (1<<7)) {114 //turn on115 } else {116 enabled = false;117 access = true;118 }119 return LCDC;120 }121 if(!access) return 0xFF;122 123 if(addr == 0xFF41) {124 return STAT = val & 0xF8;125 }126 if(addr == 0xFF42) return SCY = val;127 if(addr == 0xFF43) return SCX = val;128 if(addr == 0xFF44) return LY = 0;129 if(addr == 0xFF45) return LYC = val;130 if(addr == 0xFF46) {131 mem->dma = true;132 //DMA133 u16 addr = val << 8;134 }135 if(addr == 0xFF47) return BGP = val;136 if(addr == 0xFF48) return OBP0 = val;137 if(addr == 0xFF49) return OBP1 = val;138 139 if(addr == 0xFF4A) return WY = val;140 if(addr == 0xFF4B) return WX = val;141 142 if(mem->dma) return 0xFF;143 if(addr >= 0x8000 && addr < 0xA000) {144 return vram[addr - 0x8000] = val;145 } else146 if(addr >= 0xFE00 && addr < 0xFEA0) {147 return oam[addr - 0xFE00] = val;148 }149 return read(addr);150 }151 152 u8 Video::read(u16 addr) {153 if(addr == 0xFF40) {154 155 }156 if(!access) return 0xFF;157 if(addr == 0xFF41) {158 return STAT;159 }160 if(addr == 0xFF42) return SCY;161 if(addr == 0xFF43) return SCX;162 if(addr == 0xFF44) return LY;163 if(addr == 0xFF45) return LYC;164 165 if(addr == 0xFF47) return BGP;166 if(addr == 0xFF48) return OBP0;167 if(addr == 0xFF49) return OBP1;168 169 if(addr == 0xFF4A) return WY;170 if(addr == 0xFF4B) return WX;171 172 if(mem->dma) return 0xFF;173 if(addr >= 0x8000 && addr < 0xA000) {174 return vram[addr - 0x8000];175 } else176 if(addr >= 0xFE00 && addr < 0xFEA0) {177 return oam[addr - 0xFE00];178 }179 return 0xFF;180 }181 182 void Timer::run(u8 time) {183 dCount += time;184 tCount += time;185 if(mem->dma) {186 dma += time;187 if(dma >= 648)188 mem->dma = false;189 }190 if(dCount >= 256) {191 DIV++;192 dCount -= 256;193 }194 if(TAC & 4) {195 //timer running196 u8 rate = TTAC[TAC & 3];197 if(tCount > rate) {198 if(TIMA == 0xFF) {199 mem->IF |= mem->INT50;200 }201 tCount -= rate;202 TIMA = TMA;203 }204 }205 }206 207 Memory::Memory(Cart* c, Video* v) {208 cart = c;209 vid = v;210 vid->setMemory(this);211 time = new Timer(this);212 mExt = new MemExt(this);213 readonly = false;214 215 printf(" Allocating Ram Tables.\n");216 hram = (u8*)malloc(0x80);217 wram0 = (u8*)malloc(0x1000);218 wram1 = (u8*)malloc(0x1000);219 220 printf(" Setting up default values.\n");221 (*this)[0xFF05] = (u8)0x00; //TIMA222 (*this)[0xFF06] = (u8)0x00; // TMA223 (*this)[0xFF07] = (u8)0x00; // TAC224 (*this)[0xFF10] = (u8)0x80; // NR10225 (*this)[0xFF11] = (u8)0xBF; // NR11226 (*this)[0xFF12] = (u8)0xF3; // NR12227 (*this)[0xFF14] = (u8)0xBF; // NR14228 (*this)[0xFF16] = (u8)0x3F; // NR21229 (*this)[0xFF17] = (u8)0x00; // NR22230 (*this)[0xFF19] = (u8)0xBF; // NR24231 (*this)[0xFF1A] = (u8)0x7F; // NR30232 (*this)[0xFF1B] = (u8)0xFF; // NR31233 (*this)[0xFF1C] = (u8)0x9F; // NR32234 (*this)[0xFF1E] = (u8)0xBF; // NR33235 (*this)[0xFF20] = (u8)0xFF; // NR41236 (*this)[0xFF21] = (u8)0x00; // NR42237 (*this)[0xFF22] = (u8)0x00; // NR43238 (*this)[0xFF23] = (u8)0xBF; // NR30239 (*this)[0xFF24] = (u8)0x77; // NR50240 (*this)[0xFF25] = (u8)0xF3; // NR51241 (*this)[0xFF40] = (u8)0x91; // LCDC242 (*this)[0xFF42] = (u8)0x00; // SCY243 (*this)[0xFF43] = (u8)0x00; // SCX244 (*this)[0xFF45] = (u8)0x00; // LYC245 (*this)[0xFF47] = (u8)0xFC; // BGP246 (*this)[0xFF48] = (u8)0xFF; // OBP0247 (*this)[0xFF49] = (u8)0xFF; // OBP1248 (*this)[0xFF4A] = (u8)0x00; // WY249 (*this)[0xFF4B] = (u8)0x00; // WX250 (*this)[0xFFFF] = (u8)0x00; // IE251 // //IS GAMEBOY?252 (*this)[0xFF26] = (u8)0xF1; // NR52253 // //IS SUPER GAMEBOY?254 // //mem[0xFF26] = 0xF0; // NR52255 256 readonly = true;257 }258 259 Memory::~Memory() {260 delete mExt;261 free(hram);262 free(wram0);263 free(wram1);264 delete time;265 }266 267 u8 Memory::write(u16 addr, u8 val) {268 if(addr == 0xFFFF) return IE = val;269 if(addr == 0xFF0F) return IF = val;270 if(addr >= 0xFF04 && addr <= 0xFF07) return time->write(addr,val);271 if(addr >= 0xFF40 && addr <= 0xFF4B) return vid->write(addr,val);272 if(addr >= 0x8000 && addr < 0xA000) return vid->write(addr,val);273 if(addr >= 0xFE00 && addr < 0xFEA0) return vid->write(addr,val);274 if(addr >= 0xFFE0) return hram[addr-0xFFE0] = val;275 if(dma) return 0;276 //Memory277 if(addr < 0x8000 || (addr >= 0xA000 && addr < 0xC000)) {278 cart->write(addr, val);279 } else280 if(addr >= 0xC000 && addr < 0xD000) {281 return wram0[addr-0xC000] = val;282 } else283 if(addr >= 0xD000 && addr < 0xE000) {284 return wram1[addr-0xD000] = val;285 } else286 if(addr >= 0xE000 && addr < 0xFE00) {287 return write(addr-0x2000,(u8)val);288 }289 return 0;290 }291 292 u16 Memory::write(u16 addr, u16 val) {293 //write the first 16, write the second 16294 write(addr,(u8)(val & 0xFF));295 write(addr+1,(u8)((val & 0xFF00) >> 8));296 return 0;297 }298 299 u8 Memory::read(u16 addr) {300 if(addr == 0xFFFF) return IE;301 if(addr == 0xFF0F) return IF;302 if(addr >= 0xFF04 && addr <= 0xFF07) return time->read(addr);303 if(addr >= 0xFF40 && addr <= 0xFF4B) return vid->read(addr);304 if(addr >= 0x8000 && addr < 0xA000) return vid->read(addr);305 if(addr >= 0xFE00 && addr < 0xFEA0) return vid->read(addr);306 307 if(addr >= 0xFFE0) {308 return hram[addr-0xFFE0];309 }310 if(dma) return 0;311 //Mem312 if(addr < 0x8000 || (addr >= 0xA000 && addr < 0xC000)) {313 return cart->read(addr);314 } else315 if(addr >= 0xC000 && addr < 0xD000) {316 return wram0[addr-0xC000];317 } else318 if(addr >= 0xD000 && addr < 0xE000) {319 return wram1[addr-0xD000];320 } else321 if(addr >= 0xE000 && addr < 0xFE00) {322 return read(addr-0x2000);323 }324 return (u8)rand();325 }326 9 327 10 MemExt::MemExt(Memory* m) { … … 333 16 } 334 17 u8 MemExt::operator= (const u8& b) { 335 return parent->write(addr,b); 18 parent->write(addr,b); 19 return parent->read(b); 336 20 } 337 21 u16 MemExt::operator= (const u16& b) { 338 return parent->write(addr,b); 22 parent->write(addr,b); 23 return parent->read(b); 339 24 } 25 26 Memory::Memory() { 27 mExt = new MemExt(this); 28 } 29 30 Memory::~Memory() { 31 delete mExt; 32 } 33 void Memory::write(u16 addr, u8 val) { 34 } 35 void Memory::write(u16 addr, u16 val) { 36 } 37 u8 Memory::read(u16 addr) { 38 return 0; 39 } -
trunk/src/Memory.h
r26 r27 2 2 * Memory.h 3 3 * 4 * Created on: Sep 21, 20094 * Created on: Oct 22, 2009 5 5 * Author: Chase 6 6 */ 7 7 8 8 #pragma once 9 10 9 #include "types.h" 11 #include <stdlib.h>12 #include <stdio.h>13 14 class Memory;15 16 /*17 TYPE:18 0 - ROM ONLY 12 - ROM+MBC3+RAM19 1 - ROM+MBC1 13 - ROM+MBC3+RAM+BATT20 2 - ROM+MBC1+RAM 19 - ROM+MBC521 3 - ROM+MBC1+RAM+BATT 1A - ROM+MBC5+RAM22 5 - ROM+MBC2 1B - ROM+MBC5+RAM+BATT23 6 - ROM+MBC2+BATTERY 1C - ROM+MBC5+RUMBLE24 8 - ROM+RAM 1D - ROM+MBC5+RUMBLE+SRAM25 9 - ROM+RAM+BATTERY 1E - ROM+MBC5+RUMBLE+SRAM+BATT26 B - ROM+MMM01 1F - Pocket Camera27 C - ROM+MMM01+SRAM FD - Bandai TAMA528 D - ROM+MMM01+SRAM+BATT FE - Hudson HuC-329 30 ROM size;31 0 - 256Kbit = 32KByte = 2 banks32 1 - 512Kbit = 64KByte = 4 banks33 2 - 1Mbit = 128KByte = 8 banks34 3 - 2Mbit = 256KByte = 16 banks35 4 - 4Mbit = 512KByte = 32 banks36 5 - 8Mbit = 1MByte = 64 banks37 6 - 16Mbit = 2MByte = 128 banks38 $52 - 9Mbit = 1.1MByte = 72 banks39 $53 - 10Mbit = 1.2MByte = 80 banks40 $54 - 12Mbit = 1.5MByte = 96 banks41 42 RAM size:43 0 - None44 1 - 16kBit = 2kB = 1 bank45 2 - 64kBit = 8kB = 1 bank46 3 - 256kBit = 32kB = 4 banks47 4 - 1MBit = 128kB = 16 banks48 49 MBC150 MBC251 MBC352 MBC553 MMM0154 */55 class Cart {56 public:57 u8 type;58 u8 romsize;59 u8 ramsize;60 u8 *data;61 //u8 *data;62 ///////////////63 u8 *rom0;64 u8 *rom1;65 //u8 *ramBank;66 Cart(u32 length) {67 printf(" Allocating %u bytes ROM.\n", length);68 data = (u8*)malloc(length);69 //size = length;70 }71 ~Cart() {72 free(data);73 }74 void initialize();75 void write(u16 addr, u8 val);76 u8 read(u16 addr);77 };78 79 class Video {80 private:81 Memory *mem;82 public:83 u8* oam;84 u8* vram;85 86 u8 BGP, OBP0, OBP1;87 u8 STAT, LCDC;88 u8 SCY, SCX;89 u8 LY, LYC;90 u8 WY,WX;91 92 bool enabled;93 bool access;94 95 s16 lCount;96 97 enum {98 LYCF = (1<<2),99 HINT = (1<<3),100 VINT = (1<<4),101 OINT = (1<<5),102 LINT = (1<<6)103 };104 105 Video();106 ~Video() {107 free(vram);108 free(oam);109 }110 //0xFF means do not111 u8 drawLine() {112 if((STAT & 2) == 3) {113 return LY;114 }115 return 0xFF;116 }117 void setMemory(Memory*);118 void run(u8 t);119 u8 write(u16, u8);120 u8 read(u16);121 };122 10 123 11 //this is a very simple single initialization version … … 131 19 MemExt(Memory*); 132 20 public: 133 //Type1& operator= (const Type2& b);134 21 operator u8(void); 135 22 u8 operator= (const u8& b); … … 137 24 }; 138 25 139 const u16 TTAC[] = {1024,16,64,256};140 141 class Timer {142 public:143 Memory* mem;144 //every 256 cycles, increment this145 u8 DIV; //0xFF04 - Divider Register (R/W)146 u8 TIMA;//0xFF05 - Timer counter (R/W)147 u8 TMA; //0xFF06 - Timer Modulo (R/W)148 u8 TAC; //0xFF07 - Timer Control (R/W)149 150 //4194304 Hz151 // Bit 2 - Timer Stop (0=Stop, 1=Start)152 // Bits 1-0 - Input Clock Select153 // 00: 4096 Hz 1024 Cycles154 // 01: 262144 Hz 16 Cycles155 // 10: 65536 Hz 64 Cycles156 // 11: 16384 Hz 256 Cycles157 s16 dCount,tCount;158 u16 dma;159 Timer(Memory*m) {160 mem = m;161 dCount = tCount = 0;162 }163 void run(u8);164 u8 write(u16 addr, u8 v) {165 if(addr == 0xFF04) DIV = 0;166 if(addr == 0xFF05) return TIMA = v;167 if(addr == 0xFF06) return TMA = v;168 if(addr == 0xFF07) return TAC = v;169 return 0;170 }171 u8 read(u16 addr) {172 if(addr == 0xFF04) return DIV;173 if(addr == 0xFF05) return TIMA;174 if(addr == 0xFF06) return TMA;175 return 0;176 }177 178 };179 180 //these two classes allow me to do simple stuff like Memory[PC] = x181 //without having to write out Memory->write(PC,x), for special IO values182 26 class Memory { 183 27 friend class MemExt; 184 private:185 Cart *cart;186 Video *vid;187 28 MemExt *mExt; 188 u8 *hram; //0x80 0xFF80 - 0xFFFE189 u8 *wram0;//0x1000 0xC000190 u8 *wram1;//0x1000 0xD000191 29 192 u8write(u16, u8);193 u16write(u16, u16);30 void write(u16, u8); 31 void write(u16, u16); 194 32 u8 read(u16); 195 33 public: 196 Timer *time; 197 bool dma; 198 //Interrupts! 199 enum { 200 INT40 = (1<<0), INT48 = (1<<1), 201 INT50 = (1<<2), INT58 = (1<<3), 202 INT60 = (1<<4) 203 }; 34 Memory(); 35 ~Memory(); 36 37 //Extended 8-Registers 38 u8 dma; 39 u8 IF; //0xFF0F 204 40 u8 IE; //0xFFFF 205 u8 IF; //0xFF0F206 41 207 bool readonly; 208 Memory(Cart*,Video*); 209 virtual ~Memory(); 42 210 43 MemExt operator[](const int nIndex) { 211 44 mExt->addr = nIndex; … … 213 46 } 214 47 }; 215 -
trunk/src/cpu.h
r25 r27 50 50 51 51 Memory *mem; 52 u8 rawTMP;53 52 54 53 //Run Opcode … … 91 90 u8 step() { 92 91 //Check interrupt requests 92 // printf("--CPU: Check Interrupt\n"); 93 93 for(int i=0x40;i<0x61 && IME;i++) { 94 94 interrupt(i); 95 95 } 96 // printf("--CPU: Check DMA\n"); 97 if(PC < 0xFF80 && mem->dma) return 4; 96 98 if(wfi) return 4; //we are doing nothing, ergo the nop 97 99 100 // printf("--CPU: Load OP\n"); 98 101 u8 op = (*mem)[PC++]; 99 if(op & 0xCB) { 102 // printf("--CPU: OPCODE #%02X\n",op); 103 if((op & 0xCB) == 0xCB) { 100 104 op = (*mem)[PC++]; 101 105 ropx(op); 102 106 return timingCB[op % 8]; 103 107 } 108 104 109 rop(op); 110 // printf("--CPU: Operation Complete\n"); 105 111 106 112 return timing[op]; … … 108 114 109 115 u8& operator[](const int n) { 116 static u8 rawTMP; 110 117 if(0x0 == n) return B; 111 118 if(0x1 == n) return C;