mirror of https://github.com/mgba-emu/mgba.git
GB MBC: New MBC7 implementation
This commit is contained in:
parent
b399afdf9f
commit
7b543df002
1
CHANGES
1
CHANGES
|
@ -140,6 +140,7 @@ Misc:
|
||||||
- GB: Trust ROM header for number of SRAM banks (fixes mgba.io/i/726)
|
- GB: Trust ROM header for number of SRAM banks (fixes mgba.io/i/726)
|
||||||
- Core: Config values can now be hexadecimal
|
- Core: Config values can now be hexadecimal
|
||||||
- GB: Reset with initial state of DIV register
|
- GB: Reset with initial state of DIV register
|
||||||
|
- GB MBC: New MBC7 implementation
|
||||||
|
|
||||||
0.5.2: (2016-12-31)
|
0.5.2: (2016-12-31)
|
||||||
Bugfixes:
|
Bugfixes:
|
||||||
|
|
|
@ -67,21 +67,23 @@ typedef void (*GBMemoryBankControllerWrite)(struct GB*, uint16_t address, uint8_
|
||||||
typedef uint8_t (*GBMemoryBankControllerRead)(struct GBMemory*, uint16_t address);
|
typedef uint8_t (*GBMemoryBankControllerRead)(struct GBMemory*, uint16_t address);
|
||||||
|
|
||||||
DECL_BITFIELD(GBMBC7Field, uint8_t);
|
DECL_BITFIELD(GBMBC7Field, uint8_t);
|
||||||
DECL_BIT(GBMBC7Field, SK, 6);
|
|
||||||
DECL_BIT(GBMBC7Field, CS, 7);
|
DECL_BIT(GBMBC7Field, CS, 7);
|
||||||
DECL_BIT(GBMBC7Field, IO, 1);
|
DECL_BIT(GBMBC7Field, CLK, 6);
|
||||||
|
DECL_BIT(GBMBC7Field, DI, 1);
|
||||||
|
DECL_BIT(GBMBC7Field, DO, 0);
|
||||||
|
|
||||||
enum GBMBC7MachineState {
|
enum GBMBC7MachineState {
|
||||||
GBMBC7_STATE_NULL = -1,
|
|
||||||
GBMBC7_STATE_IDLE = 0,
|
GBMBC7_STATE_IDLE = 0,
|
||||||
GBMBC7_STATE_READ_COMMAND = 1,
|
GBMBC7_STATE_READ_COMMAND = 1,
|
||||||
GBMBC7_STATE_READ_ADDRESS = 2,
|
GBMBC7_STATE_DO = 2,
|
||||||
GBMBC7_STATE_COMMAND_0 = 3,
|
|
||||||
GBMBC7_STATE_COMMAND_SR_WRITE = 4,
|
GBMBC7_STATE_EEPROM_EWDS = 0x10,
|
||||||
GBMBC7_STATE_COMMAND_SR_READ = 5,
|
GBMBC7_STATE_EEPROM_WRAL = 0x11,
|
||||||
GBMBC7_STATE_COMMAND_SR_FILL = 6,
|
GBMBC7_STATE_EEPROM_ERAL = 0x12,
|
||||||
GBMBC7_STATE_READ = 7,
|
GBMBC7_STATE_EEPROM_EWEN = 0x13,
|
||||||
GBMBC7_STATE_WRITE = 8,
|
GBMBC7_STATE_EEPROM_WRITE = 0x14,
|
||||||
|
GBMBC7_STATE_EEPROM_READ = 0x18,
|
||||||
|
GBMBC7_STATE_EEPROM_ERASE = 0x1C,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GBMBC1State {
|
struct GBMBC1State {
|
||||||
|
@ -91,12 +93,13 @@ struct GBMBC1State {
|
||||||
|
|
||||||
struct GBMBC7State {
|
struct GBMBC7State {
|
||||||
enum GBMBC7MachineState state;
|
enum GBMBC7MachineState state;
|
||||||
uint32_t sr;
|
uint16_t sr;
|
||||||
uint8_t address;
|
uint8_t address;
|
||||||
bool writable;
|
bool writable;
|
||||||
int srBits;
|
int srBits;
|
||||||
int command;
|
uint8_t access;
|
||||||
GBMBC7Field field;
|
uint8_t latch;
|
||||||
|
GBMBC7Field eeprom;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GBPocketCamState {
|
struct GBPocketCamState {
|
||||||
|
|
231
src/gb/mbc.c
231
src/gb/mbc.c
|
@ -198,7 +198,7 @@ void GBMBCInit(struct GB* gb) {
|
||||||
case GB_MBC7:
|
case GB_MBC7:
|
||||||
gb->memory.mbcWrite = _GBMBC7;
|
gb->memory.mbcWrite = _GBMBC7;
|
||||||
gb->memory.mbcRead = _GBMBC7Read;
|
gb->memory.mbcRead = _GBMBC7Read;
|
||||||
gb->sramSize = GB_SIZE_EXTERNAL_RAM;
|
gb->sramSize = 0x100;
|
||||||
break;
|
break;
|
||||||
case GB_MMM01:
|
case GB_MMM01:
|
||||||
mLOG(GB_MBC, WARN, "unimplemented MBC: MMM01");
|
mLOG(GB_MBC, WARN, "unimplemented MBC: MMM01");
|
||||||
|
@ -472,12 +472,25 @@ void _GBMBC6(struct GB* gb, uint16_t address, uint8_t value) {
|
||||||
void _GBMBC7(struct GB* gb, uint16_t address, uint8_t value) {
|
void _GBMBC7(struct GB* gb, uint16_t address, uint8_t value) {
|
||||||
int bank = value & 0x7F;
|
int bank = value & 0x7F;
|
||||||
switch (address >> 13) {
|
switch (address >> 13) {
|
||||||
|
case 0x0:
|
||||||
|
switch (value) {
|
||||||
|
default:
|
||||||
|
case 0:
|
||||||
|
gb->memory.mbcState.mbc7.access = 0;
|
||||||
|
break;
|
||||||
|
case 0xA:
|
||||||
|
gb->memory.mbcState.mbc7.access |= 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 0x1:
|
case 0x1:
|
||||||
GBMBCSwitchBank(gb, bank);
|
GBMBCSwitchBank(gb, bank);
|
||||||
break;
|
break;
|
||||||
case 0x2:
|
case 0x2:
|
||||||
if (value < 0x10) {
|
if (value == 0x40) {
|
||||||
GBMBCSwitchSramBank(gb, value);
|
gb->memory.mbcState.mbc7.access |= 2;
|
||||||
|
} else {
|
||||||
|
gb->memory.mbcState.mbc7.access &= ~2;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -489,17 +502,15 @@ void _GBMBC7(struct GB* gb, uint16_t address, uint8_t value) {
|
||||||
|
|
||||||
uint8_t _GBMBC7Read(struct GBMemory* memory, uint16_t address) {
|
uint8_t _GBMBC7Read(struct GBMemory* memory, uint16_t address) {
|
||||||
struct GBMBC7State* mbc7 = &memory->mbcState.mbc7;
|
struct GBMBC7State* mbc7 = &memory->mbcState.mbc7;
|
||||||
|
if (mbc7->access != 3) {
|
||||||
|
return 0xFF;
|
||||||
|
}
|
||||||
switch (address & 0xF0) {
|
switch (address & 0xF0) {
|
||||||
case 0x00:
|
|
||||||
case 0x10:
|
|
||||||
case 0x60:
|
|
||||||
case 0x70:
|
|
||||||
return 0;
|
|
||||||
case 0x20:
|
case 0x20:
|
||||||
if (memory->rotation && memory->rotation->readTiltX) {
|
if (memory->rotation && memory->rotation->readTiltX) {
|
||||||
int32_t x = -memory->rotation->readTiltX(memory->rotation);
|
int32_t x = -memory->rotation->readTiltX(memory->rotation);
|
||||||
x >>= 21;
|
x >>= 21;
|
||||||
x += 2047;
|
x += 0x81D0;
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
return 0xFF;
|
return 0xFF;
|
||||||
|
@ -507,7 +518,7 @@ uint8_t _GBMBC7Read(struct GBMemory* memory, uint16_t address) {
|
||||||
if (memory->rotation && memory->rotation->readTiltX) {
|
if (memory->rotation && memory->rotation->readTiltX) {
|
||||||
int32_t x = -memory->rotation->readTiltX(memory->rotation);
|
int32_t x = -memory->rotation->readTiltX(memory->rotation);
|
||||||
x >>= 21;
|
x >>= 21;
|
||||||
x += 2047;
|
x += 0x81D0;
|
||||||
return x >> 8;
|
return x >> 8;
|
||||||
}
|
}
|
||||||
return 7;
|
return 7;
|
||||||
|
@ -515,7 +526,7 @@ uint8_t _GBMBC7Read(struct GBMemory* memory, uint16_t address) {
|
||||||
if (memory->rotation && memory->rotation->readTiltY) {
|
if (memory->rotation && memory->rotation->readTiltY) {
|
||||||
int32_t y = -memory->rotation->readTiltY(memory->rotation);
|
int32_t y = -memory->rotation->readTiltY(memory->rotation);
|
||||||
y >>= 21;
|
y >>= 21;
|
||||||
y += 2047;
|
y += 0x81D0;
|
||||||
return y;
|
return y;
|
||||||
}
|
}
|
||||||
return 0xFF;
|
return 0xFF;
|
||||||
|
@ -523,144 +534,142 @@ uint8_t _GBMBC7Read(struct GBMemory* memory, uint16_t address) {
|
||||||
if (memory->rotation && memory->rotation->readTiltY) {
|
if (memory->rotation && memory->rotation->readTiltY) {
|
||||||
int32_t y = -memory->rotation->readTiltY(memory->rotation);
|
int32_t y = -memory->rotation->readTiltY(memory->rotation);
|
||||||
y >>= 21;
|
y >>= 21;
|
||||||
y += 2047;
|
y += 0x81D0;
|
||||||
return y >> 8;
|
return y >> 8;
|
||||||
}
|
}
|
||||||
return 7;
|
return 7;
|
||||||
|
case 0x60:
|
||||||
|
return 0;
|
||||||
case 0x80:
|
case 0x80:
|
||||||
return (mbc7->sr >> 16) & 1;
|
return mbc7->eeprom;
|
||||||
default:
|
default:
|
||||||
return 0xFF;
|
return 0xFF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GBMBC7Write(struct GBMemory* memory, uint16_t address, uint8_t value) {
|
void GBMBC7Write(struct GBMemory* memory, uint16_t address, uint8_t value) {
|
||||||
if ((address & 0xF0) != 0x80) {
|
struct GBMBC7State* mbc7 = &memory->mbcState.mbc7;
|
||||||
|
if (mbc7->access != 3) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
struct GBMBC7State* mbc7 = &memory->mbcState.mbc7;
|
switch (address & 0xF0) {
|
||||||
GBMBC7Field old = memory->mbcState.mbc7.field;
|
case 0x00:
|
||||||
mbc7->field = GBMBC7FieldClearIO(value);
|
mbc7->latch = (value & 0x55) == 0x55;
|
||||||
if (!GBMBC7FieldIsCS(old) && GBMBC7FieldIsCS(value)) {
|
return;
|
||||||
if (mbc7->state == GBMBC7_STATE_WRITE) {
|
case 0x10:
|
||||||
if (mbc7->writable) {
|
mbc7->latch |= (value & 0xAA);
|
||||||
memory->sramBank[mbc7->address * 2] = mbc7->sr >> 8;
|
if (mbc7->latch == 0xFF && memory->rotation && memory->rotation->sample) {
|
||||||
memory->sramBank[mbc7->address * 2 + 1] = mbc7->sr;
|
memory->rotation->sample(memory->rotation);
|
||||||
}
|
|
||||||
mbc7->sr = 0x1FFFF;
|
|
||||||
mbc7->state = GBMBC7_STATE_NULL;
|
|
||||||
} else {
|
|
||||||
mbc7->state = GBMBC7_STATE_IDLE;
|
|
||||||
}
|
}
|
||||||
|
mbc7->latch = 0;
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
mLOG(GB_MBC, STUB, "MBC7 unknown register: %04X:%02X", address, value);
|
||||||
|
return;
|
||||||
|
case 0x80:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (!GBMBC7FieldIsSK(old) && GBMBC7FieldIsSK(value)) {
|
GBMBC7Field old = memory->mbcState.mbc7.eeprom;
|
||||||
if (mbc7->state > GBMBC7_STATE_IDLE && mbc7->state != GBMBC7_STATE_READ) {
|
value = GBMBC7FieldFillDO(value); // Hi-Z
|
||||||
|
if (!GBMBC7FieldIsCS(old) && GBMBC7FieldIsCS(value)) {
|
||||||
|
mbc7->state = GBMBC7_STATE_IDLE;
|
||||||
|
}
|
||||||
|
if (!GBMBC7FieldIsCLK(old) && GBMBC7FieldIsCLK(value)) {
|
||||||
|
if (mbc7->state == GBMBC7_STATE_READ_COMMAND || mbc7->state == GBMBC7_STATE_EEPROM_WRITE || mbc7->state == GBMBC7_STATE_EEPROM_WRAL) {
|
||||||
mbc7->sr <<= 1;
|
mbc7->sr <<= 1;
|
||||||
mbc7->sr |= GBMBC7FieldGetIO(value);
|
mbc7->sr |= GBMBC7FieldGetDI(value);
|
||||||
++mbc7->srBits;
|
++mbc7->srBits;
|
||||||
}
|
}
|
||||||
switch (mbc7->state) {
|
switch (mbc7->state) {
|
||||||
case GBMBC7_STATE_IDLE:
|
case GBMBC7_STATE_IDLE:
|
||||||
if (GBMBC7FieldIsIO(value)) {
|
if (GBMBC7FieldIsDI(value)) {
|
||||||
mbc7->state = GBMBC7_STATE_READ_COMMAND;
|
mbc7->state = GBMBC7_STATE_READ_COMMAND;
|
||||||
mbc7->srBits = 0;
|
mbc7->srBits = 0;
|
||||||
mbc7->sr = 0;
|
mbc7->sr = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GBMBC7_STATE_READ_COMMAND:
|
case GBMBC7_STATE_READ_COMMAND:
|
||||||
if (mbc7->srBits == 2) {
|
if (mbc7->srBits == 10) {
|
||||||
mbc7->state = GBMBC7_STATE_READ_ADDRESS;
|
mbc7->state = 0x10 | (mbc7->sr >> 6);
|
||||||
mbc7->srBits = 0;
|
if (mbc7->state & 0xC) {
|
||||||
mbc7->command = mbc7->sr;
|
mbc7->state &= ~0x3;
|
||||||
}
|
|
||||||
break;
|
|
||||||
case GBMBC7_STATE_READ_ADDRESS:
|
|
||||||
if (mbc7->srBits == 8) {
|
|
||||||
mbc7->state = GBMBC7_STATE_COMMAND_0 + mbc7->command;
|
|
||||||
mbc7->srBits = 0;
|
|
||||||
mbc7->address = mbc7->sr;
|
|
||||||
if (mbc7->state == GBMBC7_STATE_COMMAND_0) {
|
|
||||||
switch (mbc7->address >> 6) {
|
|
||||||
case 0:
|
|
||||||
mbc7->writable = false;
|
|
||||||
mbc7->state = GBMBC7_STATE_NULL;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
mbc7->writable = true;
|
|
||||||
mbc7->state = GBMBC7_STATE_NULL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
break;
|
|
||||||
case GBMBC7_STATE_COMMAND_0:
|
|
||||||
if (mbc7->srBits == 16) {
|
|
||||||
switch (mbc7->address >> 6) {
|
|
||||||
case 0:
|
|
||||||
mbc7->writable = false;
|
|
||||||
mbc7->state = GBMBC7_STATE_NULL;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
mbc7->state = GBMBC7_STATE_WRITE;
|
|
||||||
if (mbc7->writable) {
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < 256; ++i) {
|
|
||||||
memory->sramBank[i * 2] = mbc7->sr >> 8;
|
|
||||||
memory->sramBank[i * 2 + 1] = mbc7->sr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
mbc7->state = GBMBC7_STATE_WRITE;
|
|
||||||
if (mbc7->writable) {
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < 256; ++i) {
|
|
||||||
memory->sramBank[i * 2] = 0xFF;
|
|
||||||
memory->sramBank[i * 2 + 1] = 0xFF;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
mbc7->writable = true;
|
|
||||||
mbc7->state = GBMBC7_STATE_NULL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case GBMBC7_STATE_COMMAND_SR_WRITE:
|
|
||||||
if (mbc7->srBits == 16) {
|
|
||||||
mbc7->srBits = 0;
|
mbc7->srBits = 0;
|
||||||
mbc7->state = GBMBC7_STATE_WRITE;
|
mbc7->address = mbc7->sr & 0x7F;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GBMBC7_STATE_COMMAND_SR_READ:
|
case GBMBC7_STATE_DO:
|
||||||
if (mbc7->srBits == 1) {
|
value = GBMBC7FieldSetDO(value, mbc7->sr >> 15);
|
||||||
mbc7->sr = memory->sramBank[mbc7->address * 2] << 8;
|
mbc7->sr <<= 1;
|
||||||
mbc7->sr |= memory->sramBank[mbc7->address * 2 + 1];
|
--mbc7->srBits;
|
||||||
mbc7->srBits = 0;
|
if (!mbc7->srBits) {
|
||||||
mbc7->state = GBMBC7_STATE_READ;
|
mbc7->state = GBMBC7_STATE_IDLE;
|
||||||
}
|
|
||||||
break;
|
|
||||||
case GBMBC7_STATE_COMMAND_SR_FILL:
|
|
||||||
if (mbc7->srBits == 16) {
|
|
||||||
mbc7->sr = 0xFFFF;
|
|
||||||
mbc7->srBits = 0;
|
|
||||||
mbc7->state = GBMBC7_STATE_WRITE;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else if (GBMBC7FieldIsSK(old) && !GBMBC7FieldIsSK(value)) {
|
switch (mbc7->state) {
|
||||||
if (mbc7->state == GBMBC7_STATE_READ) {
|
case GBMBC7_STATE_EEPROM_EWEN:
|
||||||
mbc7->sr <<= 1;
|
mbc7->writable = true;
|
||||||
++mbc7->srBits;
|
mbc7->state = GBMBC7_STATE_IDLE;
|
||||||
|
break;
|
||||||
|
case GBMBC7_STATE_EEPROM_EWDS:
|
||||||
|
mbc7->writable = false;
|
||||||
|
mbc7->state = GBMBC7_STATE_IDLE;
|
||||||
|
break;
|
||||||
|
case GBMBC7_STATE_EEPROM_WRITE:
|
||||||
if (mbc7->srBits == 16) {
|
if (mbc7->srBits == 16) {
|
||||||
mbc7->srBits = 0;
|
if (mbc7->writable) {
|
||||||
mbc7->state = GBMBC7_STATE_NULL;
|
memory->sram[mbc7->address * 2] = mbc7->sr >> 8;
|
||||||
|
memory->sram[mbc7->address * 2 + 1] = mbc7->sr;
|
||||||
|
}
|
||||||
|
mbc7->state = GBMBC7_STATE_IDLE;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case GBMBC7_STATE_EEPROM_ERASE:
|
||||||
|
if (mbc7->writable) {
|
||||||
|
memory->sram[mbc7->address * 2] = 0xFF;
|
||||||
|
memory->sram[mbc7->address * 2 + 1] = 0xFF;
|
||||||
|
}
|
||||||
|
mbc7->state = GBMBC7_STATE_IDLE;
|
||||||
|
break;
|
||||||
|
case GBMBC7_STATE_EEPROM_READ:
|
||||||
|
mbc7->srBits = 16;
|
||||||
|
mbc7->sr = memory->sram[mbc7->address * 2] << 8;
|
||||||
|
mbc7->sr |= memory->sram[mbc7->address * 2 + 1];
|
||||||
|
mbc7->state = GBMBC7_STATE_DO;
|
||||||
|
value = GBMBC7FieldClearDO(value);
|
||||||
|
break;
|
||||||
|
case GBMBC7_STATE_EEPROM_WRAL:
|
||||||
|
if (mbc7->srBits == 16) {
|
||||||
|
if (mbc7->writable) {
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < 128; ++i) {
|
||||||
|
memory->sram[i * 2] = mbc7->sr >> 8;
|
||||||
|
memory->sram[i * 2 + 1] = mbc7->sr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mbc7->state = GBMBC7_STATE_IDLE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case GBMBC7_STATE_EEPROM_ERAL:
|
||||||
|
if (mbc7->writable) {
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < 128; ++i) {
|
||||||
|
memory->sram[i * 2] = 0xFF;
|
||||||
|
memory->sram[i * 2 + 1] = 0xFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mbc7->state = GBMBC7_STATE_IDLE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
} else if (GBMBC7FieldIsCS(value) && GBMBC7FieldIsCLK(old) && !GBMBC7FieldIsCLK(value)) {
|
||||||
|
value = GBMBC7FieldSetDO(value, GBMBC7FieldGetDO(old));
|
||||||
}
|
}
|
||||||
|
mbc7->eeprom = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _GBHuC3(struct GB* gb, uint16_t address, uint8_t value) {
|
void _GBHuC3(struct GB* gb, uint16_t address, uint8_t value) {
|
||||||
|
|
|
@ -185,9 +185,6 @@ void _endMode1(struct mTiming* timing, void* context, uint32_t cyclesLate) {
|
||||||
next = GB_VIDEO_MODE_2_LENGTH + (video->p->memory.io[REG_SCX] & 7);
|
next = GB_VIDEO_MODE_2_LENGTH + (video->p->memory.io[REG_SCX] & 7);
|
||||||
video->mode = 2;
|
video->mode = 2;
|
||||||
video->modeEvent.callback = _endMode2;
|
video->modeEvent.callback = _endMode2;
|
||||||
if (video->p->memory.mbcType == GB_MBC7 && video->p->memory.rotation && video->p->memory.rotation->sample) {
|
|
||||||
video->p->memory.rotation->sample(video->p->memory.rotation);
|
|
||||||
}
|
|
||||||
} else if (video->ly == GB_VIDEO_VERTICAL_TOTAL_PIXELS) {
|
} else if (video->ly == GB_VIDEO_VERTICAL_TOTAL_PIXELS) {
|
||||||
video->p->memory.io[REG_LY] = 0;
|
video->p->memory.io[REG_LY] = 0;
|
||||||
next = GB_VIDEO_HORIZONTAL_LENGTH - 8;
|
next = GB_VIDEO_HORIZONTAL_LENGTH - 8;
|
||||||
|
|
Loading…
Reference in New Issue