mirror of
https://github.com/mlaux/gb6.git
synced 2024-12-22 04:30:11 +00:00
generate simple "return 0x1234" and dynamically run
create example program
This commit is contained in:
parent
d22e2d9cba
commit
f9f199dad2
1
.gitignore
vendored
1
.gitignore
vendored
@ -14,3 +14,4 @@ lib
|
|||||||
imgui.ini
|
imgui.ini
|
||||||
.DS_Store
|
.DS_Store
|
||||||
roms
|
roms
|
||||||
|
examples/*.bin
|
||||||
|
15
examples/make.sh
Executable file
15
examples/make.sh
Executable file
@ -0,0 +1,15 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
for src_file in *.asm; do
|
||||||
|
[ -e "$src_file" ] || continue
|
||||||
|
|
||||||
|
|
||||||
|
obj_file="$(basename "$src_file" .asm).obj"
|
||||||
|
bin_file="$(basename "$src_file" .asm).bin"
|
||||||
|
echo "$src_file -> $bin_file"
|
||||||
|
|
||||||
|
rgbasm -o $obj_file $src_file
|
||||||
|
rgblink --nopad -o $bin_file $obj_file
|
||||||
|
done
|
||||||
|
|
||||||
|
rm -f *.obj
|
23
examples/simple.asm
Normal file
23
examples/simple.asm
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
section "main", rom0
|
||||||
|
|
||||||
|
nop
|
||||||
|
ld b, $0
|
||||||
|
ld c, $11
|
||||||
|
ld d, $22
|
||||||
|
ld e, $33
|
||||||
|
ld h, $44
|
||||||
|
ld l, $55
|
||||||
|
ld [hl], $66
|
||||||
|
ld a, $77
|
||||||
|
ld bc, $0123
|
||||||
|
ld de, $4567
|
||||||
|
ld hl, $89ab
|
||||||
|
ld sp, $cdef
|
||||||
|
simple_loop:
|
||||||
|
dec a
|
||||||
|
jr nz, simple_loop
|
||||||
|
|
||||||
|
end:
|
||||||
|
jr end
|
||||||
|
|
||||||
|
db $fd
|
@ -1,6 +1,8 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
|
||||||
// A -> D0
|
// A -> D0
|
||||||
// BC -> D1
|
// BC -> D1
|
||||||
@ -47,15 +49,40 @@ struct basic_block *compile_block(uint16_t src_address, uint8_t *gb_code)
|
|||||||
struct basic_block *bblock;
|
struct basic_block *bblock;
|
||||||
uint32_t dst_ptr = 0;
|
uint32_t dst_ptr = 0;
|
||||||
uint16_t src_ptr = 0;
|
uint16_t src_ptr = 0;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
printf("compile block starting at 0x%04x\n", src_address);
|
||||||
|
|
||||||
bblock = malloc(sizeof *bblock);
|
bblock = malloc(sizeof *bblock);
|
||||||
|
|
||||||
|
// for testing...
|
||||||
|
ret = mprotect(
|
||||||
|
(void *) ((uint64_t) bblock & 0xfffffffffffff000L),
|
||||||
|
4096,
|
||||||
|
PROT_READ | PROT_WRITE | PROT_EXEC
|
||||||
|
);
|
||||||
|
if (ret == -1) {
|
||||||
|
perror("mprotect");
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
// bblock->code = out_code + start;
|
// bblock->code = out_code + start;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
instruction = gb_code[src_ptr++];
|
instruction = gb_code[src_ptr++];
|
||||||
|
if (instruction == 0xfd) {
|
||||||
|
// invalid opcode for testing
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bblock->length = 6;
|
||||||
|
bblock->code[0] = 0xb8; // mov eax, 1234h
|
||||||
|
bblock->code[1] = 0x34;
|
||||||
|
bblock->code[2] = 0x12;
|
||||||
|
bblock->code[3] = 0x00;
|
||||||
|
bblock->code[4] = 0x00;
|
||||||
|
bblock->code[5] = 0xc3; // ret
|
||||||
|
|
||||||
return bblock;
|
return bblock;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,30 +93,63 @@ void run_block(struct basic_block *bblock)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
void block_cache_add(uint16_t src_address, struct basic_block *bblock);
|
void block_cache_add(uint16_t src_address, struct basic_block *bblock)
|
||||||
struct basic_block *block_cache_get(uint16_t src_address);
|
{
|
||||||
|
// no-op
|
||||||
|
}
|
||||||
|
|
||||||
|
struct basic_block *block_cache_get(uint16_t src_address)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
// 1. compile each block ending in a jump
|
// 1. compile each block ending in a jump
|
||||||
// 2. turn the jump into a return
|
// 2. turn the jump into a return
|
||||||
// 3. add the compiled code to some kind of cache
|
// 3. add the compiled code to some kind of cache
|
||||||
// 3. return back to check the cache and maybe compile the next block
|
// 3. return back to check the cache and maybe compile the next block
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
void run_all(uint8_t *gb_code)
|
||||||
{
|
{
|
||||||
struct basic_block *bblock;
|
struct basic_block *bblock;
|
||||||
|
uint16_t jump_target = 0;
|
||||||
bblock = compile_block(0, test_code);
|
|
||||||
block_cache_add(0, bblock);
|
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
uint16_t jump_target;
|
|
||||||
|
|
||||||
jump_target = ((uint16_t (*)()) bblock->code)();
|
|
||||||
|
|
||||||
bblock = block_cache_get(jump_target);
|
bblock = block_cache_get(jump_target);
|
||||||
if (!bblock) {
|
if (!bblock) {
|
||||||
bblock = compile_block(jump_target, test_code + jump_target);
|
bblock = compile_block(jump_target, gb_code + jump_target);
|
||||||
|
if (bblock->length == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
block_cache_add(jump_target, bblock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
jump_target = ((uint16_t (*)()) bblock->code)();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
long len;
|
||||||
|
uint8_t *data;
|
||||||
|
|
||||||
|
if (argc < 2) {
|
||||||
|
data = test_code;
|
||||||
|
} else {
|
||||||
|
fp = fopen(argv[1], "r");
|
||||||
|
fseek(fp, 0, SEEK_END);
|
||||||
|
len = ftell(fp);
|
||||||
|
rewind(fp);
|
||||||
|
data = malloc(len);
|
||||||
|
fread(data, 1, len, fp);
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
run_all(data);
|
||||||
|
|
||||||
|
if (data != test_code) {
|
||||||
|
free(data);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user