Graphics implemented! :D
This commit is contained in:
parent
6eddacbba2
commit
37ce16ca8a
1 changed files with 578 additions and 144 deletions
722
emulator_shell.c
722
emulator_shell.c
|
@ -556,6 +556,13 @@ int emulate8080(State8080* state) {
|
||||||
state->b = opcode[1];
|
state->b = opcode[1];
|
||||||
state->pc += 1;
|
state->pc += 1;
|
||||||
break;
|
break;
|
||||||
|
case 0x07: // RLC
|
||||||
|
{
|
||||||
|
uint8_t x = state->a;
|
||||||
|
state->a = ((x & 0x80) >> 7) | (x << 1);
|
||||||
|
state->cc.cy = (0x80 == (x & 0x80));
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 0x09: // DAD B
|
case 0x09: // DAD B
|
||||||
{
|
{
|
||||||
uint32_t h1 = (state->h << 8) | state->l;
|
uint32_t h1 = (state->h << 8) | state->l;
|
||||||
|
@ -608,6 +615,10 @@ int emulate8080(State8080* state) {
|
||||||
state->d++;
|
state->d++;
|
||||||
}}
|
}}
|
||||||
break;
|
break;
|
||||||
|
case 0x16: // MVI D, byte
|
||||||
|
state->d = opcode[1];
|
||||||
|
state->pc++;
|
||||||
|
break;
|
||||||
case 0x19: // DAD D
|
case 0x19: // DAD D
|
||||||
{
|
{
|
||||||
uint32_t h1 = (state->h << 8) | state->l;
|
uint32_t h1 = (state->h << 8) | state->l;
|
||||||
|
@ -627,22 +638,31 @@ int emulate8080(State8080* state) {
|
||||||
|
|
||||||
case 0x21: // LXI H, word
|
case 0x21: // LXI H, word
|
||||||
{
|
{
|
||||||
state->h = opcode[2];
|
state->h = opcode[2];
|
||||||
state->l = opcode[1];
|
state->l = opcode[1];
|
||||||
state->pc += 2;
|
state->pc += 2;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case 0x22: // SHLD
|
||||||
|
{
|
||||||
|
uint16_t address = (opcode[2] << 8) | opcode[1];
|
||||||
|
state->memory[address] = state->l;
|
||||||
|
state->memory[address+1] = state->h;
|
||||||
|
state->pc += 2;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 0x23: // INX H
|
case 0x23: // INX H
|
||||||
{
|
{
|
||||||
state->l++;
|
state->l++;
|
||||||
if (state->l == 0) {
|
if (state->l == 0) {
|
||||||
state->h++;
|
state->h++;
|
||||||
}}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 0x26: // MVI H, byte
|
case 0x26: // MVI H, byte
|
||||||
{
|
{
|
||||||
state->h = opcode[1];
|
state->h = opcode[1];
|
||||||
state->pc++;
|
state->pc++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x27: // DAA
|
case 0x27: // DAA
|
||||||
|
@ -661,22 +681,62 @@ int emulate8080(State8080* state) {
|
||||||
break;
|
break;
|
||||||
case 0x29: // DAD H
|
case 0x29: // DAD H
|
||||||
{
|
{
|
||||||
uint32_t hl = (state->h << 8) | state->l;
|
uint32_t hl = (state->h << 8) | state->l;
|
||||||
uint32_t result = hl + hl;
|
uint32_t result = hl + hl;
|
||||||
state->h = (result & 0xff00) >> 8;
|
state->h = (result & 0xff00) >> 8;
|
||||||
state->l = result & 0xff;
|
state->l = result & 0xff;
|
||||||
state->cc.cy = ((result & 0xffff0000) != 0);
|
state->cc.cy = ((result & 0xffff0000) != 0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 0x2a: // LHLD adress
|
||||||
|
{
|
||||||
|
uint16_t adress = (opcode[2]<<8) | (opcode[1]);
|
||||||
|
state->h = state->memory[adress];
|
||||||
|
state->l = state->memory[adress+1];
|
||||||
|
state->pc += 2;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0x2b: // DCX H
|
||||||
|
{
|
||||||
|
state->l--;
|
||||||
|
if (state->l == 0xff) {
|
||||||
|
state->h--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0x2c: // INR L
|
||||||
|
{
|
||||||
|
state->l++;
|
||||||
|
state->cc.z = (state->l == 0);
|
||||||
|
state->cc.s = (0x80 == (state->l & 0x80));
|
||||||
|
state->cc.p = parity(state->l, 8);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0x2d: // DCR L
|
||||||
|
{
|
||||||
|
state->l--;
|
||||||
|
state->cc.z = (state->l == 0);
|
||||||
|
state->cc.s = (0x80 == (state->l & 0x80));
|
||||||
|
state->cc.p = parity(state->l, 8);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0x2e: // MVI L, Adress
|
||||||
|
state->l = opcode[1];
|
||||||
|
state->pc++;
|
||||||
|
break;
|
||||||
|
case 0x2f: // CMA (NOT)
|
||||||
|
state->a = ~state->a;
|
||||||
|
break;
|
||||||
case 0x31: // LXI SP, word
|
case 0x31: // LXI SP, word
|
||||||
state->sp = ((opcode[2] << 8) | opcode[1]);
|
state->sp = ((opcode[2] << 8) | opcode[1]);
|
||||||
state->pc += 2;
|
state->pc += 2;
|
||||||
break;
|
break;
|
||||||
case 0x32: // STA adress
|
case 0x32: // STA adress
|
||||||
{
|
{
|
||||||
uint16_t adress = (opcode[2]<<8) | (opcode[1]);
|
uint16_t adress = (opcode[2]<<8) | (opcode[1]);
|
||||||
state->memory[adress] = state->a;
|
state->memory[adress] = state->a;
|
||||||
state->pc += 2;
|
state->pc += 2;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -702,9 +762,9 @@ int emulate8080(State8080* state) {
|
||||||
break;
|
break;
|
||||||
case 0x36: // MVI M, byte
|
case 0x36: // MVI M, byte
|
||||||
{
|
{
|
||||||
uint16_t adress = (state->h <<8) | (state->l);
|
uint16_t adress = (state->h <<8) | (state->l);
|
||||||
state->memory[adress] = opcode[1];
|
state->memory[adress] = opcode[1];
|
||||||
state->pc++;
|
state->pc++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -714,9 +774,9 @@ int emulate8080(State8080* state) {
|
||||||
|
|
||||||
case 0x3a: // LDA adress
|
case 0x3a: // LDA adress
|
||||||
{
|
{
|
||||||
uint16_t adress = (opcode[2]<<8) | (opcode[1]);
|
uint16_t adress = (opcode[2]<<8) | (opcode[1]);
|
||||||
state->a = state->memory[adress];
|
state->a = state->memory[adress];
|
||||||
state->pc += 2;
|
state->pc += 2;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x3d: // DCR A
|
case 0x3d: // DCR A
|
||||||
|
@ -740,22 +800,147 @@ int emulate8080(State8080* state) {
|
||||||
case 0x43: // MOV B, E
|
case 0x43: // MOV B, E
|
||||||
state->b = state->e;
|
state->b = state->e;
|
||||||
break;
|
break;
|
||||||
|
case 0x44: // MOV B, H
|
||||||
|
state->b = state->h;
|
||||||
|
break;
|
||||||
|
case 0x45: // MOV B, L
|
||||||
|
state->b = state->l;
|
||||||
|
break;
|
||||||
|
case 0x46: // MOV B, M
|
||||||
|
{
|
||||||
|
uint16_t adress = (state->h<<8) | (state->l);
|
||||||
|
state->b = state->memory[adress];
|
||||||
|
}
|
||||||
|
case 0x47: // MOV B, A
|
||||||
|
state->b = state->a;
|
||||||
|
break;
|
||||||
|
case 0x48: // MOV C, B
|
||||||
|
state->c = state->b;
|
||||||
|
break;
|
||||||
|
case 0x49: // MOV C, C
|
||||||
|
break;
|
||||||
|
case 0x4a: // MOV C, D
|
||||||
|
state->c = state->d;
|
||||||
|
break;
|
||||||
|
case 0x4b: // MOV C, E
|
||||||
|
state->c = state->e;
|
||||||
|
break;
|
||||||
|
case 0x4c: // MOV C, H
|
||||||
|
state->c = state->h;
|
||||||
|
break;
|
||||||
|
case 0x4d: // MOV C, L
|
||||||
|
state->c = state->l;
|
||||||
|
break;
|
||||||
|
case 0x4e: // MOV C, M
|
||||||
|
{
|
||||||
|
uint16_t adress = (state->h<<8) | (state->l);
|
||||||
|
state->c = state->memory[adress];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0x4f: // MOV C, A
|
||||||
|
state->c = state->a;
|
||||||
|
break;
|
||||||
|
case 0x50: // MOV D, B
|
||||||
|
state->d = state->b;
|
||||||
|
break;
|
||||||
|
case 0x51: // MOV D, C
|
||||||
|
state->d = state->c;
|
||||||
|
break;
|
||||||
|
case 0x52: // MOV D, D
|
||||||
|
break;
|
||||||
|
case 0x53: // MOV D, E
|
||||||
|
state->d = state->e;
|
||||||
|
break;
|
||||||
|
case 0x54: // MOV D, H
|
||||||
|
state->d = state->h;
|
||||||
|
break;
|
||||||
|
case 0x55: // MOV D, L
|
||||||
|
state->d = state->l;
|
||||||
|
break;
|
||||||
case 0x56: // MOV D, M
|
case 0x56: // MOV D, M
|
||||||
{
|
{
|
||||||
uint16_t adress = (state->h<<8) | (state->l);
|
uint16_t adress = (state->h<<8) | (state->l);
|
||||||
state->d = state->memory[adress];
|
state->d = state->memory[adress];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 0x57: // MOV D, A
|
||||||
|
state->d = state->a;
|
||||||
|
break;
|
||||||
|
case 0x58: // MOV E, B
|
||||||
|
state->e = state->b;
|
||||||
|
break;
|
||||||
|
case 0x59: // MOV E, C
|
||||||
|
state->e = state->c;
|
||||||
|
break;
|
||||||
|
case 0x5a: // MOV E, D
|
||||||
|
state->e = state->d;
|
||||||
|
break;
|
||||||
|
case 0x5b: // MOV E, E
|
||||||
|
break;
|
||||||
|
case 0x5c: // MOV E, H
|
||||||
|
state->e = state->h;
|
||||||
|
break;
|
||||||
|
case 0x5d: // MOV E, L
|
||||||
|
state->e = state->l;
|
||||||
|
break;
|
||||||
case 0x5e: // MOV E, M
|
case 0x5e: // MOV E, M
|
||||||
{
|
{
|
||||||
uint16_t adress = (state->h<<8) | (state->l);
|
uint16_t adress = (state->h<<8) | (state->l);
|
||||||
state->e = state->memory[adress];
|
state->e = state->memory[adress];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 0x5f: // MOV E, A
|
||||||
|
state->e = state->a;
|
||||||
|
break;
|
||||||
|
case 0x60: // MOV H, B
|
||||||
|
state->h = state->b;
|
||||||
|
break;
|
||||||
|
case 0x61: // MOV H, C
|
||||||
|
state->h = state->c;
|
||||||
|
break;
|
||||||
|
case 0x62: // MOV H, D
|
||||||
|
state->h = state->d;
|
||||||
|
break;
|
||||||
|
case 0x63: // MOV H, E
|
||||||
|
state->h = state->e;
|
||||||
|
break;
|
||||||
|
case 0x64: // MOV H, H
|
||||||
|
break;
|
||||||
|
case 0x65: // MOV H, L
|
||||||
|
state->h = state->l;
|
||||||
|
break;
|
||||||
case 0x66: // MOV H, M
|
case 0x66: // MOV H, M
|
||||||
{
|
{
|
||||||
uint16_t adress = (state->h<<8) | (state->l);
|
uint16_t adress = (state->h<<8) | (state->l);
|
||||||
state->h = state->memory[adress];
|
state->h = state->memory[adress];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0x67: // MOV H, A
|
||||||
|
{
|
||||||
|
state->h = state->a;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0x68: // MOV L, B
|
||||||
|
state->l = state->b;
|
||||||
|
break;
|
||||||
|
case 0x69: // MOV L, C
|
||||||
|
state->l = state->c;
|
||||||
|
break;
|
||||||
|
case 0x6a: // MOV L, D
|
||||||
|
state->l = state->d;
|
||||||
|
break;
|
||||||
|
case 0x6b: // MOV L, E
|
||||||
|
state->l = state->e;
|
||||||
|
break;
|
||||||
|
case 0x6c: // MOV L, H
|
||||||
|
state->l = state->h;
|
||||||
|
break;
|
||||||
|
case 0x6d: // MOV L, L
|
||||||
|
break;
|
||||||
|
case 0x6e: // MOV L, M
|
||||||
|
{
|
||||||
|
uint16_t adress = (state->h<<8) | (state->l);
|
||||||
|
state->l = state->memory[adress];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x6f: // MOV L, A
|
case 0x6f: // MOV L, A
|
||||||
|
@ -763,52 +948,63 @@ int emulate8080(State8080* state) {
|
||||||
break;
|
break;
|
||||||
case 0x77: // MOV M, A
|
case 0x77: // MOV M, A
|
||||||
{
|
{
|
||||||
uint16_t adress = (state->h<<8) | (state->l);
|
uint16_t adress = (state->h<<8) | (state->l);
|
||||||
state->memory[adress] = state->a;
|
state->memory[adress] = state->a;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x7a: // MOV A, D
|
case 0x7a: // MOV A, D
|
||||||
state->a = state->d;
|
state->a = state->d;
|
||||||
break;
|
break;
|
||||||
|
case 0x78: // MOV A, B
|
||||||
|
state->a = state->b;
|
||||||
|
break;
|
||||||
|
case 0x79: // MOV A, C
|
||||||
|
state->a = state->c;
|
||||||
|
break;
|
||||||
case 0x7b: // MOV A, E
|
case 0x7b: // MOV A, E
|
||||||
state->a = state->e;
|
state->a = state->e;
|
||||||
break;
|
break;
|
||||||
case 0x7c: // MOV A, H
|
case 0x7c: // MOV A, H
|
||||||
state->a = state->h;
|
state->a = state->h;
|
||||||
break;
|
break;
|
||||||
|
case 0x7d: // MOV A, L
|
||||||
|
state->a = state->l;
|
||||||
|
break;
|
||||||
case 0x7e: // MOV A, M
|
case 0x7e: // MOV A, M
|
||||||
{
|
{
|
||||||
uint16_t adress = (state->h<<8) | (state->l);
|
uint16_t adress = (state->h<<8) | (state->l);
|
||||||
state->a = state->memory[adress];
|
state->a = state->memory[adress];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 0x7f: // MOV A, A
|
||||||
|
break;
|
||||||
case 0x80: // ADD B
|
case 0x80: // ADD B
|
||||||
{
|
{
|
||||||
uint16_t answer = (uint16_t) state->a + (uint16_t) state->b;
|
uint16_t answer = (uint16_t) state->a + (uint16_t) state->b;
|
||||||
state->cc.z = ((answer & 0xff) == 0);
|
state->cc.z = ((answer & 0xff) == 0);
|
||||||
state->cc.s = ((answer & 0x80) != 0);
|
state->cc.s = ((answer & 0x80) != 0);
|
||||||
state->cc.cy = (answer > 0xff);
|
state->cc.cy = (answer > 0xff);
|
||||||
state->cc.p = parity(answer & 0xff, 8);
|
state->cc.p = parity(answer & 0xff, 8);
|
||||||
state->a = answer & 0xff;
|
state->a = answer & 0xff;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x86: // ADD M
|
case 0x86: // ADD M
|
||||||
{
|
{
|
||||||
uint16_t offset = (state->h<<8) | (state->l);
|
uint16_t offset = (state->h<<8) | (state->l);
|
||||||
uint16_t answer = (uint16_t) state->a + state->memory[offset];
|
uint16_t answer = (uint16_t) state->a + state->memory[offset];
|
||||||
state->cc.z = ((answer & 0xff) == 0);
|
state->cc.z = ((answer & 0xff) == 0);
|
||||||
state->cc.s = ((answer & 0x80) != 0);
|
state->cc.s = ((answer & 0x80) != 0);
|
||||||
state->cc.cy = (answer > 0xff);
|
state->cc.cy = (answer > 0xff);
|
||||||
state->cc.p = parity(answer & 0xff, 8);
|
state->cc.p = parity(answer & 0xff, 8);
|
||||||
state->a = answer & 0xff;
|
state->a = answer & 0xff;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x1f: // RAR
|
case 0x1f: // RAR
|
||||||
{
|
{
|
||||||
uint8_t x = state->a;
|
uint8_t x = state->a;
|
||||||
state->a = (state->cc.cy << 7) | (x >> 1);
|
state->a = (state->cc.cy << 7) | (x >> 1);
|
||||||
state->cc.cy = (1 == (x & 1));
|
state->cc.cy = (1 == (x & 1));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -828,6 +1024,23 @@ int emulate8080(State8080* state) {
|
||||||
state->cc.cy = 0;
|
state->cc.cy = 0;
|
||||||
state->cc.ac = 0;
|
state->cc.ac = 0;
|
||||||
break;
|
break;
|
||||||
|
case 0xb0: // ORA B
|
||||||
|
state->a |= state->b;
|
||||||
|
state->cc.cy = state->cc.ac = 0;
|
||||||
|
state->cc.z = (state->a == 0);
|
||||||
|
state->cc.s = (0x80 == (state->a & 0x80));
|
||||||
|
state->cc.p = parity(state->a, 8);
|
||||||
|
break;
|
||||||
|
case 0xb6: // ORA M
|
||||||
|
{
|
||||||
|
uint16_t offset = (state->h<<8) | (state->l);
|
||||||
|
state->a |= state->memory[offset];
|
||||||
|
state->cc.cy = state->cc.ac = 0;
|
||||||
|
state->cc.z = (state->a == 0);
|
||||||
|
state->cc.s = (0x80 == (state->a & 0x80));
|
||||||
|
state->cc.p = parity(state->a, 8);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 0xc0: // RNZ
|
case 0xc0: // RNZ
|
||||||
{
|
{
|
||||||
if (state->cc.z == 0) {
|
if (state->cc.z == 0) {
|
||||||
|
@ -853,6 +1066,19 @@ int emulate8080(State8080* state) {
|
||||||
case 0xc3: // JMP adress
|
case 0xc3: // JMP adress
|
||||||
state->pc = (opcode[2] << 8) | opcode[1];
|
state->pc = (opcode[2] << 8) | opcode[1];
|
||||||
break;
|
break;
|
||||||
|
case 0xc4: // CNZ adress
|
||||||
|
{
|
||||||
|
if (0 == state->cc.z) {
|
||||||
|
uint16_t ret = state->pc+2;
|
||||||
|
state->memory[state->sp-1] = (ret >> 8) & 0xff;
|
||||||
|
state->memory[state->sp-2] = ret & 0xff;
|
||||||
|
state->sp -= 2;
|
||||||
|
state->pc = (opcode[2] << 8) | opcode[1];
|
||||||
|
} else {
|
||||||
|
state->pc += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case 0xc5: // PUSH B
|
case 0xc5: // PUSH B
|
||||||
state->memory[state->sp-1] = state->b;
|
state->memory[state->sp-1] = state->b;
|
||||||
|
@ -861,12 +1087,12 @@ int emulate8080(State8080* state) {
|
||||||
break;
|
break;
|
||||||
case 0xc6: // ADI byte
|
case 0xc6: // ADI byte
|
||||||
{
|
{
|
||||||
uint16_t answer = (uint16_t) state->a + (uint16_t) opcode[1];
|
uint16_t answer = (uint16_t) state->a + (uint16_t) opcode[1];
|
||||||
state->cc.z = ((state->a & 0xff) == 0);
|
state->cc.z = ((state->a & 0xff) == 0);
|
||||||
state->cc.s = ((state->a & 0x80) == 0x80);
|
state->cc.s = ((state->a & 0x80) == 0x80);
|
||||||
state->cc.cy = (state->a > 0xff);
|
state->cc.cy = (state->a > 0xff);
|
||||||
state->cc.p = parity(state->a & 0xff, 8);
|
state->cc.p = parity(state->a & 0xff, 8);
|
||||||
state->pc++;
|
state->pc++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -894,11 +1120,11 @@ int emulate8080(State8080* state) {
|
||||||
|
|
||||||
case 0xcd: // CALL adress
|
case 0xcd: // CALL adress
|
||||||
{
|
{
|
||||||
uint16_t ret = state -> pc+2;
|
uint16_t ret = state -> pc+2;
|
||||||
state->memory[state->sp-1] = (ret >> 8) & 0xff;
|
state->memory[state->sp-1] = (ret >> 8) & 0xff;
|
||||||
state->memory[state->sp-2] = (ret & 0xff);
|
state->memory[state->sp-2] = (ret & 0xff);
|
||||||
state->sp -= 2;
|
state->sp -= 2;
|
||||||
state->pc = (opcode[2] << 8) | opcode[1];
|
state->pc = (opcode[2] << 8) | opcode[1];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0xd1: // POP D
|
case 0xd1: // POP D
|
||||||
|
@ -917,9 +1143,9 @@ int emulate8080(State8080* state) {
|
||||||
break;
|
break;
|
||||||
case 0xd3: // OUT byte
|
case 0xd3: // OUT byte
|
||||||
{
|
{
|
||||||
uint8_t port = opcode[1];
|
uint8_t port = opcode[1];
|
||||||
machineOut(state, port, 0x00); // PROBLEM: We need to pass a value to machineOUT
|
machineOut(state, port, 0x00); // PROBLEM: We need to pass a value to machineOUT
|
||||||
state->pc++;
|
state->pc++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0xd5: // PUSH D
|
case 0xd5: // PUSH D
|
||||||
|
@ -927,6 +1153,14 @@ int emulate8080(State8080* state) {
|
||||||
state->memory[state->sp-2] = state->e;
|
state->memory[state->sp-2] = state->e;
|
||||||
state->sp -= 2;
|
state->sp -= 2;
|
||||||
break;
|
break;
|
||||||
|
case 0xd8: // RC
|
||||||
|
{
|
||||||
|
if (state->cc.cy != 0) {
|
||||||
|
state->pc = state->memory[state->sp] | (state->memory[state->sp+1] << 8);
|
||||||
|
state->sp += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 0xda: // JC adress
|
case 0xda: // JC adress
|
||||||
{
|
{
|
||||||
if (state->cc.cy != 0) {
|
if (state->cc.cy != 0) {
|
||||||
|
@ -938,9 +1172,9 @@ int emulate8080(State8080* state) {
|
||||||
break;
|
break;
|
||||||
case 0xdb: // IN byte
|
case 0xdb: // IN byte
|
||||||
{
|
{
|
||||||
uint8_t port = opcode[1];
|
uint8_t port = opcode[1];
|
||||||
state->a = machineIn(state, port);
|
state->a = machineIn(state, port);
|
||||||
state->pc++;
|
state->pc++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0xe1: // POP H
|
case 0xe1: // POP H
|
||||||
|
@ -948,50 +1182,167 @@ int emulate8080(State8080* state) {
|
||||||
state->h = state->memory[state->sp+1];
|
state->h = state->memory[state->sp+1];
|
||||||
state->sp += 2;
|
state->sp += 2;
|
||||||
break;
|
break;
|
||||||
|
case 0xe2: // JPO adress
|
||||||
|
{
|
||||||
|
if (0 == state->cc.p) {
|
||||||
|
state->pc = (opcode[2] << 8) | opcode[1];
|
||||||
|
} else {
|
||||||
|
state->pc += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0xe3: // XTHL
|
||||||
|
{
|
||||||
|
uint8_t tmp = state->l;
|
||||||
|
state->l = state->memory[state->sp];
|
||||||
|
state->memory[state->sp] = tmp;
|
||||||
|
tmp = state->h;
|
||||||
|
state->h = state->memory[state->sp+1];
|
||||||
|
state->memory[state->sp+1] = tmp;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0xe4: // CPO adress
|
||||||
|
{
|
||||||
|
if (0 == state->cc.p) {
|
||||||
|
uint16_t ret = state -> pc+2;
|
||||||
|
state->memory[state->sp-1] = (ret >> 8) & 0xff;
|
||||||
|
state->memory[state->sp-2] = (ret & 0xff);
|
||||||
|
state->sp -= 2;
|
||||||
|
state->pc = (opcode[2] << 8) | opcode[1];
|
||||||
|
} else {
|
||||||
|
state->pc += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 0xe5: // PUSH H
|
case 0xe5: // PUSH H
|
||||||
state->memory[state->sp-1] = state->h;
|
state->memory[state->sp-1] = state->h;
|
||||||
state->memory[state->sp-2] = state->l;
|
state->memory[state->sp-2] = state->l;
|
||||||
state->sp -= 2;
|
state->sp -= 2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x2f: // CMA (NOT)
|
|
||||||
state->a = ~state->a;
|
|
||||||
break;
|
|
||||||
case 0xe6: // ANI byte
|
case 0xe6: // ANI byte
|
||||||
{
|
{
|
||||||
uint8_t x = state->a & opcode[1];
|
uint8_t x = state->a & opcode[1];
|
||||||
state->cc.z = (x == 0);
|
state->cc.z = (x == 0);
|
||||||
state->cc.s = (0x80 == (x & 0x80));
|
state->cc.s = (0x80 == (x & 0x80));
|
||||||
state->cc.cy = 0;
|
state->cc.cy = 0;
|
||||||
state->cc.p = parity(x, 8);
|
state->cc.p = parity(x, 8);
|
||||||
state->pc++;
|
state->pc++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 0xe7: // RST 4
|
||||||
|
{
|
||||||
|
uint16_t ret = state -> pc+2;
|
||||||
|
state->memory[state->sp-1] = (ret >> 8) & 0xff;
|
||||||
|
state->memory[state->sp-2] = (ret & 0xff);
|
||||||
|
state->sp -= 2;
|
||||||
|
state->pc = 0x20;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0xe8: // RPE
|
||||||
|
{
|
||||||
|
if (0 != state->cc.p) {
|
||||||
|
state->pc = state->memory[state->sp] | (state->memory[state->sp+1] << 8);
|
||||||
|
state->sp += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0xe9: // PCHL
|
||||||
|
state->pc = (state->h << 8) | state->l;
|
||||||
|
break;
|
||||||
|
case 0xea: // JPE
|
||||||
|
if (state->cc.p != 0)
|
||||||
|
state->pc = (opcode[2] << 8) | opcode[1];
|
||||||
|
else
|
||||||
|
state->pc += 2;
|
||||||
|
break;
|
||||||
case 0xeb: // XCHG
|
case 0xeb: // XCHG
|
||||||
{
|
{
|
||||||
uint8_t tmp = state->h;
|
uint8_t tmp = state->h;
|
||||||
state->h = state->d;
|
state->h = state->d;
|
||||||
state->d = tmp;
|
state->d = tmp;
|
||||||
tmp = state->l;
|
tmp = state->l;
|
||||||
state->l = state->e;
|
state->l = state->e;
|
||||||
state->e = tmp;
|
state->e = tmp;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0xec: // CPE Adress
|
||||||
|
{
|
||||||
|
if (state->cc.p != 0) {
|
||||||
|
uint16_t ret = state->pc+2;
|
||||||
|
state->memory[state->sp-1] = (ret >> 8) & 0xff;
|
||||||
|
state->memory[state->sp-2] = (ret & 0xff);
|
||||||
|
state->sp -= 2;
|
||||||
|
state->pc = (opcode[2] << 8) | opcode[1];
|
||||||
|
} else {
|
||||||
|
state->pc += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0xee: // XRI Data
|
||||||
|
{
|
||||||
|
uint8_t x = state->a ^opcode[1];
|
||||||
|
state->cc.z = (x == 0);
|
||||||
|
state->cc.s = (0x80 == (x & 0x80));
|
||||||
|
state->cc.p = parity(x, 8);
|
||||||
|
state->cc.cy = 0;
|
||||||
|
state->a = x;
|
||||||
|
state->pc++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0xef: // RST 5
|
||||||
|
{
|
||||||
|
uint16_t ret = state->pc+2;
|
||||||
|
state->memory[state->sp-1] = (ret >> 8) & 0xff;
|
||||||
|
state->memory[state->sp-2] = (ret & 0xff);
|
||||||
|
state->sp -=2;
|
||||||
|
state->pc = 0x28;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0xf0: // RP
|
||||||
|
{
|
||||||
|
if (state->cc.s == 0) {
|
||||||
|
state->pc = state->memory[state->sp] | (state->memory[state->sp+1]<<8);
|
||||||
|
state->pc += 2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xf1: // POP PSW
|
case 0xf1: // POP PSW
|
||||||
{
|
{
|
||||||
state->a = state->memory[state->sp+1];
|
state->a = state->memory[state->sp+1];
|
||||||
uint8_t psw = state->memory[state->sp];
|
uint8_t psw = state->memory[state->sp];
|
||||||
state->cc.z = (0x01 == (psw & 0x01));
|
state->cc.z = (0x01 == (psw & 0x01));
|
||||||
state->cc.s = (0x02 == (psw & 0x02));
|
state->cc.s = (0x02 == (psw & 0x02));
|
||||||
state->cc.p = (0x04 == (psw & 0x04));
|
state->cc.p = (0x04 == (psw & 0x04));
|
||||||
state->cc.cy = (0x08 == (psw & 0x08));
|
state->cc.cy = (0x08 == (psw & 0x08));
|
||||||
state->cc.ac = (0x10 == (psw & 0x10));
|
state->cc.ac = (0x10 == (psw & 0x10));
|
||||||
state->sp += 2;
|
state->sp += 2;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0xf2: // JP Adress
|
||||||
|
{
|
||||||
|
if (state->cc.s == 0) {
|
||||||
|
state->pc = (opcode[2] << 8) | opcode[1];
|
||||||
|
} else {
|
||||||
|
state->pc += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case 0xf3: // DI
|
||||||
|
state->int_enable = 0;
|
||||||
|
break;
|
||||||
|
case 0xf4: // CP
|
||||||
|
{
|
||||||
|
if (state->cc.s == 0) {
|
||||||
|
uint16_t ret = state->pc+2;
|
||||||
|
state->memory[state->sp-1] = (ret >> 8) & 0xff;
|
||||||
|
state->memory[state->sp-2] = (ret & 0xff);
|
||||||
|
state->sp -= 2;
|
||||||
|
state->pc = (opcode[2] << 8) | opcode[1];
|
||||||
|
} else {
|
||||||
|
state->pc += 2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xf5: // PUSH PSW
|
case 0xf5: // PUSH PSW
|
||||||
state->memory[state->sp-1] = state->a;
|
state->memory[state->sp-1] = state->a;
|
||||||
state->memory[state->sp-2] = (state->cc.z | (state->cc.s << 1) | (state->cc.p << 2) | (state->cc.cy << 3) | (state->cc.ac << 4));
|
state->memory[state->sp-2] = (state->cc.z | (state->cc.s << 1) | (state->cc.p << 2) | (state->cc.cy << 3) | (state->cc.ac << 4));
|
||||||
|
@ -1004,12 +1355,12 @@ int emulate8080(State8080* state) {
|
||||||
|
|
||||||
case 0xfe: // CPI byte
|
case 0xfe: // CPI byte
|
||||||
{
|
{
|
||||||
uint8_t x = state->a - opcode[1];
|
uint8_t x = state->a - opcode[1];
|
||||||
state->cc.z = (x == 0);
|
state->cc.z = (x == 0);
|
||||||
state->cc.s = (0x80 == (x & 0x80));
|
state->cc.s = (0x80 == (x & 0x80));
|
||||||
state->cc.cy = (state->a < opcode[1]);
|
state->cc.cy = (state->a < opcode[1]);
|
||||||
state->cc.p = parity(x, 8);
|
state->cc.p = parity(x, 8);
|
||||||
state->pc++;
|
state->pc++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1103,43 +1454,114 @@ typedef struct cpu_data {
|
||||||
|
|
||||||
// ===== GTK GRAPHICS =====
|
// ===== GTK GRAPHICS =====
|
||||||
|
|
||||||
static void draw_callback(GtkWidget *widget, cairo_t *cr, gpointer user_data) {
|
// static void draw_callback(GtkWidget *widget, cairo_t *cr, gpointer user_data) {
|
||||||
int x, y;
|
// int upscaleFactor = 1;
|
||||||
int upscaleFactor = 1;
|
// uint8_t *video = malloc(sizeof(uint8_t) * 224 * 256);
|
||||||
uint8_t *video = malloc(sizeof(uint8_t) * 224 * 256 * 4);
|
// //ROTATION ALGORITHM
|
||||||
|
// for (int i=0; i< 224; i++)
|
||||||
//ROTATION ALGORITHM
|
// {
|
||||||
for (int i=0; i< 224; i++)
|
// for (int j = 0; j < 256; j+= 8)
|
||||||
{
|
// {
|
||||||
for (int j = 0; j < 256; j+= 8)
|
// //Read the first 1-bit pixel
|
||||||
{
|
// // divide by 8 because there are 8 pixels
|
||||||
int p;
|
// // in a byte
|
||||||
//Read the first 1-bit pixel
|
// uint8_t pix = bitmap[(i*(256/8)) + j/8];
|
||||||
// divide by 8 because there are 8 pixels
|
|
||||||
// in a byte
|
|
||||||
unsigned char pix = bitmap[(i*(256/8)) + j/8];
|
|
||||||
|
|
||||||
//That makes 8 output vertical pixels
|
// //That makes 8 output vertical pixels
|
||||||
// we need to do a vertical flip
|
// // we need to do a vertical flip
|
||||||
// so j needs to start at the last line
|
// // so j needs to start at the last line
|
||||||
// and advance backward through the buffer
|
// // and advance backward through the buffer
|
||||||
int offset = (255-j)*(224*4) + (i*4);
|
// int offset = (255-j)*(224*4) + (i*4);
|
||||||
unsigned int *p1 = (unsigned int*)(&video[offset]);
|
// uint8_t *p1 = (uint8_t*)(&video[offset]);
|
||||||
for (p=0; p<8; p++)
|
// for (int p=0; p<8; p++)
|
||||||
{
|
// {
|
||||||
if ( 0!= (pix & (1<<p)))
|
// if ( 0!= (pix & (1<<p)))
|
||||||
*p1 = 1;
|
// *p1 = 1;
|
||||||
else
|
// else
|
||||||
*p1 = 0;
|
// *p1 = 0;
|
||||||
p1-=224; //next line
|
// p1-=224; //next line
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// for (int x = 0; x < 256; x++) {
|
||||||
|
// for (int y = 0; y < 224; y++) {
|
||||||
|
// if (video[y*256 + x]) {
|
||||||
|
// cairo_set_source_rgb(cr, 1.0, 1.0, 1.0); // Set color to white
|
||||||
|
// } else {
|
||||||
|
// cairo_set_source_rgb(cr, 0.0, 0.0, 0.0); // Set color to black
|
||||||
|
// }
|
||||||
|
|
||||||
|
// cairo_rectangle(cr, x * upscaleFactor, y * upscaleFactor, upscaleFactor, upscaleFactor);
|
||||||
|
// cairo_fill(cr);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// free(video);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// static void draw_callback(GtkWidget *widget, cairo_t *cr, gpointer user_data) {
|
||||||
|
// int upscaleFactor = 1;
|
||||||
|
// uint8_t *video = malloc(sizeof(uint8_t) * 224 * 256);
|
||||||
|
// // Clear the drawing area
|
||||||
|
// cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
|
||||||
|
// cairo_paint(cr);
|
||||||
|
|
||||||
|
// // Copying the bitmap to video output
|
||||||
|
// for (int i = 0; i < 224; i++) {
|
||||||
|
// for (int j = 0; j < 32; j++) {
|
||||||
|
// uint8_t byte = bitmap[i*32 + j];
|
||||||
|
// for (int p = 0; p < 8; p++) {
|
||||||
|
// int pixel = (byte >> (7 - p)) & 1; // flip the bit order
|
||||||
|
// int x = 255 - (j*8 + p); // flip the x-coordinate
|
||||||
|
// int y = i;
|
||||||
|
// video[y*256 + x] = pixel;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Rendering the graphics
|
||||||
|
// for (int x = 0; x < 256; x++) {
|
||||||
|
// for (int y = 0; y < 224; y++) {
|
||||||
|
// if (video[y*256 + x]) {
|
||||||
|
// cairo_set_source_rgb(cr, 1.0, 1.0, 1.0); // Set color to white
|
||||||
|
// } else {
|
||||||
|
// cairo_set_source_rgb(cr, 0.0, 0.0, 0.0); // Set color to black
|
||||||
|
// }
|
||||||
|
|
||||||
|
// cairo_rectangle(cr, x * upscaleFactor, y * upscaleFactor, upscaleFactor, upscaleFactor);
|
||||||
|
// cairo_fill(cr);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// free(video);
|
||||||
|
// }
|
||||||
|
|
||||||
|
static void draw_callback(GtkWidget *widget, cairo_t *cr, gpointer user_data) {
|
||||||
|
int upscaleFactor = 2;
|
||||||
|
uint8_t *video = malloc(sizeof(uint8_t) * 256 * 256); // Adjusted size
|
||||||
|
// Clear the drawing area
|
||||||
|
cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
|
||||||
|
cairo_paint(cr);
|
||||||
|
|
||||||
|
// Copying the bitmap to video output
|
||||||
|
for (int i = 0; i < 224; i++) {
|
||||||
|
for (int j = 0; j < 32; j++) {
|
||||||
|
uint8_t byte = bitmap[i*32 + j];
|
||||||
|
for (int p = 0; p < 8; p++) {
|
||||||
|
int pixel = (byte >> p) & 1; // flip the bit order within each byte
|
||||||
|
int x = i; // swap x and y
|
||||||
|
int y = 255 - (j*8 + p); // flip the y-coordinate
|
||||||
|
if (x >= 0 && x < 256 && y >= 0 && y < 256) { // Check bounds
|
||||||
|
video[y*256 + x] = pixel;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// RENDERING GRAPHICS
|
|
||||||
|
// Rendering the graphics
|
||||||
for (x = 0; x < 224; x++) {
|
for (int x = 0; x < 256; x++) {
|
||||||
for (y = 0; y < 256; y++) {
|
for (int y = 0; y < 256; y++) {
|
||||||
if (video[y * 224 + x]) {
|
if (video[y*256 + x]) {
|
||||||
cairo_set_source_rgb(cr, 1.0, 1.0, 1.0); // Set color to white
|
cairo_set_source_rgb(cr, 1.0, 1.0, 1.0); // Set color to white
|
||||||
} else {
|
} else {
|
||||||
cairo_set_source_rgb(cr, 0.0, 0.0, 0.0); // Set color to black
|
cairo_set_source_rgb(cr, 0.0, 0.0, 0.0); // Set color to black
|
||||||
|
@ -1149,9 +1571,11 @@ static void draw_callback(GtkWidget *widget, cairo_t *cr, gpointer user_data) {
|
||||||
cairo_fill(cr);
|
cairo_fill(cr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
free(video);
|
free(video);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void *cpu(void* arg) {
|
void *cpu(void* arg) {
|
||||||
cpu_data *cpu = (cpu_data*) arg;
|
cpu_data *cpu = (cpu_data*) arg;
|
||||||
char done = cpu->done;
|
char done = cpu->done;
|
||||||
|
@ -1163,8 +1587,8 @@ void *cpu(void* arg) {
|
||||||
cpu->total_cycles_count += counter;
|
cpu->total_cycles_count += counter;
|
||||||
printf("Total cycles: %d\n", cpu->total_cycles_count);
|
printf("Total cycles: %d\n", cpu->total_cycles_count);
|
||||||
|
|
||||||
usleep(counter / 2); // EMULATION OF THE PROCESSOR ŠPEED
|
//usleep(counter / 2); // EMULATION OF THE PROCESSOR ŠPEED
|
||||||
if ((cpu->total_cycles_count > 16600) && (state->int_enable)) //1/60 second has elapsed
|
if ((cpu->total_cycles_count > 16000) && (state->int_enable)) //1/60 second has elapsed
|
||||||
{
|
{
|
||||||
//redraw screen() will be handeled by the gtk_main() function
|
//redraw screen() will be handeled by the gtk_main() function
|
||||||
if (which_interrupt == 2) {
|
if (which_interrupt == 2) {
|
||||||
|
@ -1181,9 +1605,19 @@ void *cpu(void* arg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
gboolean update_ui(gpointer data) {
|
||||||
|
// Seems like GTK is not thread safe
|
||||||
|
// we fix it with update_ui using gtk_main_iteration_do(FALSE)
|
||||||
|
GtkWidget *drawing_area = (GtkWidget*)data;
|
||||||
|
gtk_widget_queue_draw(drawing_area);
|
||||||
|
while (gtk_events_pending())
|
||||||
|
gtk_main_iteration_do(FALSE);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
int main (int argc, char *argv[]) {
|
int main (int argc, char *argv[]) {
|
||||||
|
|
||||||
// EMULATOR INIT
|
// Emulator init
|
||||||
|
|
||||||
State8080 *state = (State8080*) calloc(1, sizeof(State8080)); //memset obsolte with calloc
|
State8080 *state = (State8080*) calloc(1, sizeof(State8080)); //memset obsolte with calloc
|
||||||
state->cc.z = 1;
|
state->cc.z = 1;
|
||||||
|
@ -1193,23 +1627,23 @@ int main (int argc, char *argv[]) {
|
||||||
state->cc.ac = 1;
|
state->cc.ac = 1;
|
||||||
state->int_enable = 1;
|
state->int_enable = 1;
|
||||||
state->pc = 0;
|
state->pc = 0;
|
||||||
state->memory = malloc(0x10000);
|
state->memory = calloc(0x10000, 1);
|
||||||
|
|
||||||
read_Space_Invaders_ROM(state, "ROM/invaders.h", 0);
|
read_Space_Invaders_ROM(state, "ROM/invaders.h", 0);
|
||||||
read_Space_Invaders_ROM(state, "ROM/invaders.g", 0x800);
|
read_Space_Invaders_ROM(state, "ROM/invaders.g", 0x800);
|
||||||
read_Space_Invaders_ROM(state, "ROM/invaders.f", 0x1000);
|
read_Space_Invaders_ROM(state, "ROM/invaders.f", 0x1000);
|
||||||
read_Space_Invaders_ROM(state, "ROM/invaders.e", 0x1800);
|
read_Space_Invaders_ROM(state, "ROM/invaders.e", 0x1800);
|
||||||
|
|
||||||
// GTK INIT
|
// GTK init
|
||||||
gtk_init(&argc, &argv);
|
gtk_init(&argc, &argv);
|
||||||
GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
||||||
gtk_window_set_default_size(GTK_WINDOW(window), 800, 600);
|
gtk_window_set_default_size(GTK_WINDOW(window), 800, 600);
|
||||||
gtk_window_set_title(GTK_WINDOW(window), "Lux8080-Emulator");
|
gtk_window_set_title(GTK_WINDOW(window), "Turi's Super Duper Emulatinator");
|
||||||
g_signal_connect(window, "key-press-event", G_CALLBACK(on_key_press), NULL);
|
g_signal_connect(window, "key-press-event", G_CALLBACK(on_key_press), NULL);
|
||||||
g_signal_connect(window, "key-release-event", G_CALLBACK(on_key_release), NULL);
|
g_signal_connect(window, "key-release-event", G_CALLBACK(on_key_release), NULL);
|
||||||
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
|
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
|
||||||
|
|
||||||
// DRAWING AREA INIT
|
// Drawing area init
|
||||||
bitmap = &(state->memory[0x2400]);
|
bitmap = &(state->memory[0x2400]);
|
||||||
GtkWidget *drawing_area = gtk_drawing_area_new();
|
GtkWidget *drawing_area = gtk_drawing_area_new();
|
||||||
gtk_widget_set_app_paintable(drawing_area, TRUE);
|
gtk_widget_set_app_paintable(drawing_area, TRUE);
|
||||||
|
@ -1217,20 +1651,20 @@ int main (int argc, char *argv[]) {
|
||||||
g_signal_connect(drawing_area, "draw", G_CALLBACK(draw_callback), NULL);
|
g_signal_connect(drawing_area, "draw", G_CALLBACK(draw_callback), NULL);
|
||||||
gtk_widget_show_all(window);
|
gtk_widget_show_all(window);
|
||||||
|
|
||||||
// CPU INIT
|
// CPU-init
|
||||||
cpu_data *cpu_eco = malloc(sizeof(cpu_data));
|
cpu_data *cpu_eco = malloc(sizeof(cpu_data));
|
||||||
cpu_eco->state = state;
|
cpu_eco->state = state;
|
||||||
cpu_eco->drawing_area = drawing_area;
|
cpu_eco->drawing_area = drawing_area;
|
||||||
cpu_eco->done = 0;
|
cpu_eco->done = 0;
|
||||||
cpu_eco->total_cycles_count = 0;
|
cpu_eco->total_cycles_count = 0;
|
||||||
|
|
||||||
// PTHREAD
|
// Pthread
|
||||||
pthread_t pid;
|
pthread_t pid;
|
||||||
pthread_create(&pid, NULL, cpu, (void*) cpu_eco);
|
pthread_create(&pid, NULL, cpu, (void*) cpu_eco);
|
||||||
|
|
||||||
|
|
||||||
//MAIN LOOP & TERMINATION //gtk_widget_queue_draw
|
// Main GTK Loop
|
||||||
g_timeout_add(16, (GSourceFunc)gtk_widget_queue_draw, drawing_area);
|
g_timeout_add(200, update_ui, drawing_area);
|
||||||
gtk_main();
|
gtk_main();
|
||||||
pthread_join(pid, NULL);
|
pthread_join(pid, NULL);
|
||||||
free(state->memory);
|
free(state->memory);
|
||||||
|
|
Loading…
Reference in a new issue