From b6d479c59502ca758008f63faa7d099ce3d13a03 Mon Sep 17 00:00:00 2001 From: Hojun-Cho Date: Tue, 16 Jul 2024 21:19:27 +0900 Subject: [PATCH] add mbc1 --- gb.c | 29 +++++++++++++++++++++++++---- gb.h | 2 +- mem.c | 43 ++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 68 insertions(+), 6 deletions(-) diff --git a/gb.c b/gb.c index f3925dd..fcf722e 100644 --- a/gb.c +++ b/gb.c @@ -4,6 +4,7 @@ int cpuhalt; int backup; +int savefd = -1; u64 clock; u8 mbc, feat, mode; @@ -14,7 +15,13 @@ loadrom(const char* file) long sz; static u8 mbctab[31] = { 0, 1, 1, 1, -1, 2, 2, -1, 0, 0, -1, 6, 6, 6, -1, 3, 3, 3, 3, 3, -1, 4, 4, 4, -1, 5, 5, 5, 5, 5, 5 }; - + static u8 feattab[31] = { + 0, 0, FEATRAM, FEATRAM|FEATBAT, 0, FEATRAM, FEATRAM|FEATBAT, 0, + FEATRAM, FEATRAM|FEATBAT, 0, 0, FEATRAM, FEATRAM|FEATBAT, 0, FEATTIM|FEATBAT, + FEATTIM|FEATRAM|FEATBAT, 0, FEATRAM, FEATRAM|FEATBAT, 0, 0, FEATRAM, FEATRAM|FEATBAT, + 0, 0, FEATRAM, FEATRAM|FEATBAT, 0, FEATRAM, FEATRAM|FEATBAT, + }; + f = fopen(file, "r"); if (f == nil) panic("can't open %s", file); @@ -31,11 +38,25 @@ loadrom(const char* file) if (rom[0x147] > 0x1F) panic("bad cartidge type %d\n", rom[0x147]); mbc = mbctab[rom[0x147]]; + feat = feattab[rom[0x147]]; + if((feat & FEATRAM) != 0){ + switch(rom[0x149]){ + case 0: feat &= ~FEATRAM; break; + case 1: nback = 2048; break; + case 2: nback = 8192; break; + case 3: nback = 32768; break; + default: panic("Unkown Ram size %d\n", rom[0x149]); + } + } + back = xalloc(nback); + if(nback == 0) + nbackbank = 1; + else + nbackbank = (nback + 8191) / 8192; switch (mbc) { - case 0: + case 0: case 1: break; - default: - panic("unsupported mbc %d", mbc); + default: panic("unsupported mbc %d", mbc); } if ((rom[0x143] & 0x80) != 0 && (mode & FORCEDMG) == 0) mode = CGB | COL; diff --git a/gb.h b/gb.h index 1c377e4..b408d20 100644 --- a/gb.h +++ b/gb.h @@ -147,7 +147,7 @@ struct Event extern u8 *rom, *back, reg[256], oam[256]; extern u8 vram[16384]; -extern int nrom; +extern int nrom, nback, nbackbank; extern u32 pal[64]; extern u8 dma; extern u32 divclock; diff --git a/mem.c b/mem.c index f0e20bf..3967f55 100644 --- a/mem.c +++ b/mem.c @@ -2,6 +2,8 @@ static int mbc0(int a, int _); +static int +mbc1(int a, int _); u8* rom; u8 *romb, *vramb, *wramb, *eramb; @@ -15,7 +17,7 @@ int prish; u8 dma; u32 moncols[4]; u32 white; -int (*mappers[])(int, int) = { mbc0 }; +int (*mappers[])(int, int) = { mbc0, mbc1 }; int (*mapper)(int, int); static u8 @@ -192,6 +194,45 @@ mbc0(int a, int _) return 0; } +static int +mbc1(int a, int v) +{ + static u8 ramen, b0, b1, romram; + u16 b; + + if (a < 0) { + switch(a) { + case INIT: return 0; + case SAVE: + case RSTR: + break; + case READ: + return -1; + default: panic("MBC1 does not have function of %d", a); + } + } + switch (a >> 13) { + case 0: ramen = (v & 0xF) == 0xA; break; + case 1: v &= 0x1F; b0 = v != 0 ? v : 1; break; + case 2: b1 = v & 3; b1 % nbackbank; break; + case 3: romram = v & 1; break; + } + b = b0; + if (romram == 0) + b |= b1 << 5; + b %= nrom >> 14; /* 32KB => 2bank */ + romb = rom + (b << 14); + if (ramen) { + if (romram) + eramb = back + (b1 << 13); + else + eramb = back; + } else { + eramb = nil; + } + return 0; +} + void meminit(void) {