Browse Source

Add files to repository

master
Alec Murphy 4 months ago
parent
commit
672a60ce69
  1. 23
      Lib/Debug.HC
  2. 368
      Lib/ELF64.HC
  3. 709
      Lib/LibC.HC
  4. 24
      Lib/Misc.HC
  5. 401
      Lib/SDL2.HC
  6. 0
      Lib/SDL2_net.HC
  7. 154
      Lib/TOSGame.HC
  8. 15
      Load.HC
  9. 1
      Run.HC

23
Lib/Debug.HC

@ -0,0 +1,23 @@
class Debug {
Bool enabled;
I64 bookmark;
I64 counter;
};
Debug debug;
// debug.bookmark = 466900;
// debug.bookmark = 17000;
debug.bookmark = 1838479;
debug.counter = 0;
debug.enabled = FALSE;
U0 debug_print(U8 *fmt, ...) {
if (!debug.enabled || debug.counter < debug.bookmark) {
debug.counter++;
return;
}
U8 *buf = StrPrintJoin(NULL, fmt, argc, argv);
"[%05d] %s", debug.counter, buf;
Free(buf);
debug.counter++;
}

368
Lib/ELF64.HC

@ -0,0 +1,368 @@
#define EI_NIDENT 16
#define EM_X86_64 0x3E
#define ET_EXEC 2
#define ET_DYN 3
#define STT_OBJECT 1
#define STT_FUNC 2
class Elf64_Ehdr {
U8 e_ident[EI_NIDENT]; /* Magic number and other info */
U16 e_type; /* Object file type */
U16 e_machine; /* Architecture */
U32 e_version; /* Object file version */
U64 e_entry; /* Entry point virtual address */
U64 e_phoff; /* Program header table file offset */
U64 e_shoff; /* Section header table file offset */
U32 e_flags; /* Processor-specific flags */
U16 e_ehsize; /* ELF header size in bytes */
U16 e_phentsize; /* Program header table entry size */
U16 e_phnum; /* Program header table entry count */
U16 e_shentsize; /* Section header table entry size */
U16 e_shnum; /* Section header table entry count */
U16 e_shstrndx; /* Section header string table index */
};
class Elf64_Shdr {
U32 sh_name; /* Section name (string tbl index) */
U32 sh_type; /* Section type */
U64 sh_flags; /* Section flags */
U64 sh_addr; /* Section virtual addr at execution */
U64 sh_offset; /* Section file offset */
U64 sh_size; /* Section size in bytes */
U32 sh_link; /* Link to another section */
U32 sh_info; /* Additional section information */
U64 sh_addralign; /* Section alignment */
U64 sh_entsize; /* Entry size if section holds table */
};
class Elf64_Sym {
U32 st_name; /* Symbol name (string tbl index) */
U8 st_info; /* Symbol type and binding */
U8 st_other; /* Symbol visibility */
U16 st_shndx; /* Section index */
U64 st_value; /* Symbol value */
U64 st_size; /* Symbol size */
};
class PLT_entry {
U8 pad[0x10];
};
class RELA_entry {
U64 r_offset;
U64 r_info;
I64 r_addend;
};
class Elf {
union {
U8 *u8;
Elf64_Ehdr *ehdr;
} I64 size;
U8 *dynstr;
Elf64_Sym *dynsym;
PLT_entry *plt;
RELA_entry *rela_dyn;
RELA_entry *rela_plt;
Elf64_Sym *strtab;
Elf64_Sym *symtab;
I64 rela_dyn_size;
I64 rela_plt_size;
I64 strtab_size;
I64 symtab_size;
};
U0 (*_start)();
U0 unimplemented_symbol() {
I32 s = 0xDEADF00D;
"Unimplemented symbol: %s\n", s;
while (1)
Sleep(1);
}
Bool is_valid_elf(Elf *elf) {
Bool res = TRUE;
if (MemCmp(elf->u8 + 1, "ELF", 3)) {
debug_print("Invalid signature (not ELF).\n");
res = FALSE;
}
if (elf->ehdr->e_type != ET_EXEC && elf->ehdr->e_type != ET_DYN) {
debug_print("Invalid object file type.\n");
res = FALSE;
}
if (elf->ehdr->e_machine != EM_X86_64) {
debug_print("Invalid architecture.\n");
res = FALSE;
}
return res;
}
U0 find_value(U8 *value) {
U64 addr = 0x0;
while (addr < 0x2000000) {
if (!MemCmp(addr, value, StrLen(value))) {
"found at 0x%08x\n", addr;
return;
}
addr++;
}
"not found\n";
}
U0 process_elf_section_header_table(Elf *elf) {
Elf64_Shdr *shdr = elf->u8 + elf->ehdr->e_shoff;
Elf64_Shdr *shdr_shstrtab = shdr + elf->ehdr->e_shstrndx;
U8 *shstrtab = elf->u8 + shdr_shstrtab->sh_offset;
I64 i = 0;
while (i < elf->ehdr->e_shnum) {
if (!StrCmp(shstrtab + shdr->sh_name, ".symtab")) {
debug_print("found symtab at 0x%08x, size = %d\n", shdr->sh_offset,
shdr->sh_size);
elf->symtab = elf->u8 + shdr->sh_offset;
elf->symtab_size = shdr->sh_size;
}
if (!StrCmp(shstrtab + shdr->sh_name, ".strtab")) {
debug_print("found strtab at 0x%08x, size = %d\n", shdr->sh_offset,
shdr->sh_size);
elf->strtab = elf->u8 + shdr->sh_offset;
elf->strtab_size = shdr->sh_size;
}
if (shdr->sh_addr) {
MemCpy(shdr->sh_addr, elf->u8 + shdr->sh_offset, shdr->sh_size);
if (!StrCmp(shstrtab + shdr->sh_name, ".dynstr"))
elf->dynstr = shdr->sh_addr;
if (!StrCmp(shstrtab + shdr->sh_name, ".dynsym"))
elf->dynsym = shdr->sh_addr;
if (!StrCmp(shstrtab + shdr->sh_name, ".plt"))
elf->plt = shdr->sh_addr;
if (!StrCmp(shstrtab + shdr->sh_name, ".rela.dyn")) {
elf->rela_dyn = shdr->sh_addr;
elf->rela_dyn_size = shdr->sh_size / shdr->sh_entsize;
}
if (!StrCmp(shstrtab + shdr->sh_name, ".rela.plt")) {
elf->rela_plt = shdr->sh_addr;
elf->rela_plt_size = shdr->sh_size / shdr->sh_entsize;
}
debug_print(
"MemCpy section '%s' to physical address 0x%06x, size = %d bytes\n",
shstrtab + shdr->sh_name, shdr->sh_addr, shdr->sh_size);
if (!StrCmp(shstrtab + shdr->sh_name, ".bss")) {
MemSet(shdr->sh_addr, NULL, shdr->sh_size);
debug_print("MemSet section '%s' at physical address 0x%06x to NULL, "
"size = %d bytes\n",
shstrtab + shdr->sh_name, shdr->sh_addr, shdr->sh_size);
}
}
shdr++;
i++;
}
}
U0 process_elf_rela_dyn_entries(Elf *elf) {
I64 i;
U8 *entry_name;
RELA_entry *rela_dyn = elf->rela_dyn;
for (i = 0; i < elf->rela_dyn_size; i++) {
entry_name = elf->dynstr + elf->dynsym[(rela_dyn->r_info >> 32)].st_name;
debug_print("rela_dyn->r_offset = %08x\n", rela_dyn->r_offset);
debug_print("entry name = '%s'\n", entry_name);
if (!StrCmp(entry_name, "__libc_start_main")) {
*(rela_dyn->r_offset)(U64 *) = &_main;
debug_print("Set value for .rela.dyn entry '%s' to: &_main\n",
entry_name);
}
if (!StrCmp(entry_name, "stdin")) {
*(rela_dyn->r_offset)(U64 *) = 0;
debug_print("Set value for .rela.dyn entry '%s' to: %d\n", entry_name, 0);
}
if (!StrCmp(entry_name, "stdout")) {
*(rela_dyn->r_offset)(U64 *) = 1;
debug_print("Set value for .rela.dyn entry '%s' to: %d\n", entry_name, 1);
}
if (!StrCmp(entry_name, "stderr")) {
*(rela_dyn->r_offset)(U64 *) = 2;
debug_print("Set value for .rela.dyn entry '%s' to: %d\n", entry_name, 2);
}
rela_dyn++;
}
}
CHashClass *get_symbol_hash_entry(U8 *entry_name) {
I64 i;
CHashSrcSym *sym;
CHashTable *tbl = Fs->hash_table;
while (tbl) {
for (i = 0; i < tbl->mask; i++) {
sym = tbl->body[i];
while (sym) {
if (sym->type == HTT_CLASS)
if (!StrCmp(sym->str, entry_name))
return sym;
sym = sym->next;
}
}
tbl = tbl->next;
}
return NULL;
}
U0 process_elf_debug_symbols(Elf *elf) {
I64 i = 0;
I64 entry_bind;
U64 entry_name;
I64 entry_type;
CHashFun *hf;
CHashGlblVar *hgv;
Elf64_Sym *symtab = elf->symtab;
entry_name = elf->strtab;
entry_name += symtab->st_name;
while (i < 3551) {
entry_bind = symtab->st_info >> 4;
entry_type = symtab->st_info & 0xf;
switch (entry_type) {
case STT_OBJECT:
hgv = CAlloc(sizeof(CHashGlblVar));
hgv->str = entry_name;
hgv->type = HTT_GLBL_VAR;
hgv->data_addr = symtab->st_value;
hgv->size = symtab->st_size;
// TempleOS reboots if I nest a switch table here, for some reason, so we
// have to do this dumb shit instead...
hgv->var_class = get_symbol_hash_entry("U32");
if (hgv->size == 1)
hgv->var_class = get_symbol_hash_entry("U8");
if (hgv->size == 2)
hgv->var_class = get_symbol_hash_entry("U16");
HashAdd(hgv, Fs->hash_table);
debug_print(
"Add global variable '%s' to hash table, addr = 0x%08x, size = %d\n",
entry_name, symtab->st_value, symtab->st_size);
break;
case STT_FUNC:
hf = CAlloc(sizeof(CHashFun));
hf->str = entry_name;
hf->type = HTT_FUN;
hf->exe_addr = symtab->st_value;
hf->size = symtab->st_size;
HashAdd(hf, Fs->hash_table);
debug_print("Add function '%s' to hash table, addr = 0x%08x, size = %d\n",
entry_name, symtab->st_value, symtab->st_size);
break;
}
symtab++;
i++;
entry_name = elf->strtab;
entry_name += symtab->st_name;
}
}
U64 get_symbol_address(U8 *entry_name) {
I64 i;
CHashSrcSym *sym;
CHashTable *tbl = Fs->hash_table;
while (tbl) {
for (i = 0; i < tbl->mask; i++) {
sym = tbl->body[i];
while (sym) {
if (sym->type == HTT_GLBL_VAR)
if (!StrCmp(sym->str, entry_name))
return sym(CHashGlblVar *)->data_addr;
if (sym->type == HTT_FUN)
if (!StrCmp(sym->str, entry_name))
return sym(CHashFun *)->exe_addr;
sym = sym->next;
}
}
tbl = tbl->next;
}
return NULL;
}
U0 @catch_Z_Malloc() {
// PUSH_SYSV_REGS
asm
{
MOV [&p0], RDI
}
debug_print("called: Z_Malloc(%d, %d, %d)\n", p0, p1, p2);
PressAKey;
// POP_SYSV_REGS
}
U0 process_debug_patches(Elf *elf) { no_warn elf; }
U0 process_elf_rela_plt_entries(Elf *elf) {
I64 i;
U32 handler;
U32 *patch;
U8 *entry_name;
Bool symbol_exists;
PLT_entry *plt = elf->plt;
RELA_entry *rela_plt = elf->rela_plt;
plt++;
for (i = 0; i < elf->rela_plt_size; i++) {
symbol_exists = FALSE;
entry_name = elf->dynstr + elf->dynsym[(rela_plt->r_info >> 32)].st_name;
handler = MAlloc(sizeof(unimplemented_symbol), Fs->code_heap);
MemCpy(handler, &unimplemented_symbol, sizeof(unimplemented_symbol));
patch = handler + 0x0A;
*patch = entry_name;
PatchJmpRel32(plt, handler);
PatchCallRel32(handler + 0x16, &PrintErr);
PatchCallRel32(handler + 0x21, &_exit);
if (!StrCmp(entry_name, "__libc_start_main")) {
symbol_exists = TRUE;
PatchJmpRel32(plt, &_main);
debug_print("Set value for .rela.plt entry '%s' to &_main\n", entry_name);
}
if (get_symbol_address(entry_name)) {
symbol_exists = TRUE;
PatchJmpRel32(plt, get_symbol_address(entry_name));
debug_print("Set value for .rela.plt entry '%s' to &%s\n", entry_name,
entry_name);
}
if (!symbol_exists)
debug_print(
"Set value for .rela.plt entry '%s' to &unimplemented_symbol\n",
entry_name);
rela_plt++;
plt++;
}
}
U0 load_elf(...) {
if (argc < 1) {
PrintErr("Not enough arguments.\n");
return;
}
if (!FileFind(argv[0])) {
PrintErr("File not found: %s\n", argv[0]);
return;
}
Elf elf;
elf.u8 = FileRead(argv[0], &elf.size);
debug_print("Load file '%s', size = %d bytes\n", argv[0], elf.size);
if (!is_valid_elf(&elf)) {
PrintErr("File is not a valid ELF x86-64 executable.\n");
return;
}
process_elf_section_header_table(&elf);
process_elf_rela_dyn_entries(&elf);
process_elf_rela_plt_entries(&elf);
process_elf_debug_symbols(&elf);
_start = elf.ehdr->e_entry;
elf_argc = argc;
elf_argv = argv;
process_debug_patches(&elf);
// B(0x449340);
_start();
}

709
Lib/LibC.HC

@ -0,0 +1,709 @@
#define SEEK_SET 0
#define SEEK_CUR 1
#define SEEK_END 2
U8 *f_whence[3];
f_whence[0] = "SEEK_SET";
f_whence[1] = "SEEK_CUR";
f_whence[2] = "SEEK_END";
class FILE {
U8 *filename;
U8 *data;
U8 *mode;
I64 descriptor;
I64 size;
I64 offset;
I64 pos;
};
class va_list {
U32 gp_offset;
U32 fp_offset;
U8 *overflow_arg_area;
U8 *reg_save_area;
};
FILE *iwad_fp = NULL;
#define PUSH_SYSV_REGS \
asm {PUSH RCX PUSH RDX PUSH RBX PUSH RBP PUSH RSI PUSH RDI PUSH R8 PUSH R9 PUSH \
R10 PUSH R11 PUSH R12 PUSH R13 PUSH R14 PUSH R15}
#define POP_SYSV_REGS \
asm {POP R15 POP R14 POP R13 POP R12 POP R11 POP R10 POP R9 POP R8 POP RDI POP \
RSI POP RBP POP RBX POP RDX POP RCX}
#define MOV_ANS_RAX asm {MOV [&ans], RAX}
#define MOV_P0_RDI asm {MOV [&p0], RDI}
#define MOV_P1_RSI asm {MOV [&p1], RSI}
#define MOV_P2_RDX asm {MOV [&p2], RDX}
#define MOV_P3_RCX asm {MOV [&p3], RCX}
#define MOV_P4_R8 asm {MOV [&p4], R8}
#define MOV_P5_R9 asm {MOV [&p5], R9}
#define GET_SYSV_ARGS \
MOV_P0_RDI MOV_P1_RSI MOV_P2_RDX MOV_P3_RCX MOV_P4_R8 MOV_P5_R9
I64 new_fd = 3;
I64 p0, p1, p2, p3, p4, p5;
I64 elf_argc;
U8 **elf_argv;
#define stdin 0
#define stdout 1
#define stderr 2
asm {
_ELF_CALL::
PUSH RBP
MOV RBP,RSP
MOV RAX,U64 SF_ARG1[RBP]
MOV RDI,U64 SF_ARG2[RBP]
MOV RSI,U64 SF_ARG3[RBP]
TEST RAX,RAX
JZ @@05
CALL RAX
@@05: POP RBP
RET1 8
}
U0 _main() {
MOV_P0_RDI
CallInd(_ELF_CALL, p0, elf_argc, elf_argv);
MOV_ANS_RAX
throw('end', TRUE);
}
U0 _exit() {
MOV_ANS_RAX
throw('end', TRUE);
}
U0 convert_format_string(U8 *s) {
while (*s) {
switch (*s) {
case '%':
if (s[1] == 'i')
s[1] = 'd';
if (s[1] == 'p')
s[1] = 'x';
break;
}
s++;
}
}
U0 putc() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: putc('%c', %d)\n", p0, p1);
switch (p1) {
case stdout:
case stderr:
PutChars(p0);
break;
default:
PrintErr("putc: not yet implemented\n");
break;
}
POP_SYSV_REGS
}
U8 *@calloc(I64 nitems, I64 size) {
return CAlloc(nitems * size, Fs->code_heap);
}
U0 calloc() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: calloc(%d, %d)\n", p0, p1);
@calloc(p0, p1);
POP_SYSV_REGS
}
U8 *@getenv(U8 *str) {
if (!StrCmp(str, "HOME"))
return "B:";
return NULL;
}
U0 getenv() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: getenv(\"%s\")\n", p0);
@getenv(p0);
POP_SYSV_REGS
}
I64 @fileno(FILE *f) {
debug_print("fileno: 0x%08x has fd %d\n", f, f->descriptor);
return f->descriptor;
}
U0 fileno() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: fileno(0x%08x)\n", p0);
@fileno(p0);
POP_SYSV_REGS
}
I64 @fflush(FILE *f) {
no_warn f;
return NULL;
}
U0 fflush() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: fflush(0x%08x)\n", p0);
@fflush(p0);
POP_SYSV_REGS
}
I64 @fclose(FILE *f) {
if (!f)
return NULL;
if (f->data)
Free(f->data);
if (f->filename)
Free(f->filename);
if (f->mode)
Free(f->mode);
Free(f);
return NULL;
}
U0 fclose() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: fclose(%d)\n", p0(FILE *)->descriptor);
@fclose(p0);
POP_SYSV_REGS
}
FILE *@fopen(U8 *filename, U8 *mode) {
U64 file_data;
FILE *f;
if (!StrCmp(mode, "r") || !StrCmp(mode, "r+") || !StrCmp(mode, "rb")) {
if (!FileFind(filename))
return NULL;
f = MAlloc(sizeof(FILE), Fs->code_heap);
f->filename = StrNew(filename);
file_data = FileRead(filename, &f->size);
f->data = CAlloc(f->size, Fs->code_heap);
// MemCpy(f->data, file_data, f->size);
MemCpy(f->data, file_data, f->size);
f->descriptor = new_fd++;
f->mode = StrNew(mode);
debug_print("fopen: got file descriptor %d\n", f->descriptor);
return f;
}
}
U0 fopen() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: fopen(\"%s\",\"%s\")\n", p0, p1);
@fopen(p0, p1);
POP_SYSV_REGS
}
I64 @fread(U8 *ptr, I64 size, I64 nmemb, FILE *f) {
MemCpy(ptr, f->data + f->pos, (size * nmemb));
//"fread @ pos, size: %d, %d\n", f->pos, (size * nmemb);
// D(ptr, Min(256, size * nmemb));
f->pos += (size * nmemb);
// if (debug.enabled)
// debug_print("fread: pos: %d\n", f->pos);
return (size * nmemb);
}
U0 efread() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called fread(0x%08x, %d, %d, %d)\n", p0, p1, p2,
p3(FILE *)->descriptor);
@fread(p0, p1, p2, p3);
POP_SYSV_REGS
}
U0 free() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called free(0x%08x)\n", p0);
Free(p0);
POP_SYSV_REGS
}
I64 @fseek(FILE *f, I64 off, I64 whence) {
switch (whence) {
case SEEK_SET:
f->pos = off;
break;
case SEEK_CUR:
f->pos += off;
break;
case SEEK_END:
f->pos = f->size + off;
break;
}
return NULL;
}
U0 fseek() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: fseek(%d, %d, %s)\n", p0(FILE *)->descriptor, p1,
f_whence[p2]);
@fseek(p0, p1, p2);
POP_SYSV_REGS
}
I64 @ftell(FILE *f) {
debug_print("ftell: %d\n", f->pos);
return f->pos;
}
U0 ftell() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: ftell(%d)\n", p0(FILE *)->descriptor);
@ftell(p0);
POP_SYSV_REGS
}
I64 @fwrite(U8 *ptr, I64 size, I64 nmemb, FILE *f) {
return (size * nmemb);
MemCpy(f->data + f->pos, ptr, (size * nmemb));
if (debug.enabled)
D(f->data + f->pos, Min(256, size * nmemb));
f->pos += (size * nmemb);
debug_print("fwrite: pos: %d\n", f->pos);
return (size * nmemb);
}
U0 fwrite() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called fwrite(0x%08x, %d, %d, 0x%08x)\n", p0, p1, p2,
p3(FILE *)->descriptor);
if (p3(FILE *)->descriptor(U64) >= 0x100000000) {
// mock for stderr problem
PutS(p0);
"\n";
}
if (p3(FILE *)->descriptor(U64) < 0x100000000)
@fwrite(p0, p1, p2, p3);
POP_SYSV_REGS
}
Bool @isatty(I64 fd) {
no_warn fd;
return TRUE;
}
U0 isatty() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: isatty(%d)\n", p0);
@isatty(p0);
POP_SYSV_REGS
}
U64 @malloc(I64 size) {
U64 ptr = NULL;
ptr = MAlloc(p0, Fs->code_heap);
debug_print("malloc(%d), result: 0x%08x\n", size, ptr);
return ptr;
}
U0 malloc() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: malloc(%d)\n", p0);
@malloc(p0);
POP_SYSV_REGS
}
U0 memcpy() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: memcpy(0x%08x, 0x%08x, %d)\n", p0, p1, p2);
MemCpy(p0, p1, p2);
POP_SYSV_REGS
}
U0 memcmp() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: memcmp(0x%08x, 0x%08x, %d)\n", p0, p1, p2);
MemCmp(p0, p1, p2);
POP_SYSV_REGS
}
U0 memset() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: memset(0x%08x, %d, %d)\n", p0, p1, p2);
// if (debug.counter > 1845140)
// PressAKey;
MemSet(p0, p1, p2);
POP_SYSV_REGS
}
I64 @mkdir(U8 *path) {
path = StrNew(path);
while (path[StrLen(path) - 1] == '/')
path[StrLen(path) - 1] = NULL;
CDoc *olddoc = Fs->put_doc;
CDoc *tmpdoc = DocNew;
Fs->put_doc = tmpdoc;
DirMk(path);
Fs->put_doc = olddoc;
DocDel(tmpdoc);
return 0;
}
U0 mkdir() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: mkdir(\"%s\")\n", p0);
@mkdir(p0);
POP_SYSV_REGS
}
I64 @open(U8 *path) {
iwad_fp = @fopen(path, "rb");
return iwad_fp->descriptor;
}
U0 open() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: open(\"%s\", %d, %d)\n", p0, p1, p2);
@open(p0);
POP_SYSV_REGS
}
U0 lseek() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: lseek(%d, %d, %d)\n", p0, p1, p2);
@fseek(iwad_fp, p1, p2);
POP_SYSV_REGS
}
U8 *@mmap(I64 fd) {
no_warn fd;
return iwad_fp->data;
}
U0 mmap() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: mmap(0x%08x, %d, %d, %d, %d, %d)\n", p0, p1, p2, p3, p4,
p5);
@mmap(p4);
POP_SYSV_REGS
}
U0 read() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called read(%d, 0x%08x, %d)\n", p0, p1, p2);
@fread(p1, 1, p2, iwad_fp);
POP_SYSV_REGS
}
I64 @putchar(I64 ch) {
if (ch != 0x8)
PutChars(ch);
if (ch == 0x8)
Fs->put_doc->cur_col--;
return 0;
}
U0 putchar() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: putchar(%d)\n", p0);
@putchar(p0);
POP_SYSV_REGS
}
U0 puts() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
PutS(p0);
"\n";
POP_SYSV_REGS
}
U8 *@realloc(U8 *ptr, I64 size) {
U8 *new;
if (!ptr) {
new = MAlloc(size, Fs->code_heap);
} else {
new = MAlloc(size, Fs->code_heap);
MemCpy(new, ptr, size);
Free(ptr);
}
return new;
}
U0 realloc() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called realloc(0x%08x, %d)\n", p0, p1);
@realloc(p0, p1);
POP_SYSV_REGS
}
U0 strcasecmp() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: strcasecmp(\"%s\",\"%s\")\n", p0, p1);
StrICmp(p0, p1);
POP_SYSV_REGS
}
U0 strcmp() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: strcmp(\"%s\",\"%s\")\n", p0, p1);
StrCmp(p0, p1);
POP_SYSV_REGS
}
U0 strlen() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: strlen(\"%s\")\n", p0);
StrLen(p0);
POP_SYSV_REGS
}
I64 @strncmp(U8 *s1, U8 *s2, I64 n) {
while (n && *s1 && (*s1 == *s2)) {
++s1;
++s2;
--n;
}
if (n == 0) {
return 0;
} else {
return (*s1 - *s2);
}
}
U0 strncmp() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: strncmp(\"%s\", \"%s\", %d)\n", p0, p1, p2);
@strncmp(p0, p1, p2);
POP_SYSV_REGS
}
/*
* This array is designed for mapping upper and lower case letter
* together for a case independent comparison. The mappings are
* based upon ascii character sequences.
*/
U8 @strncasecmp_charmap[256] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73,
0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b,
0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83,
0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b,
0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3,
0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
0xc0, 0xe1, 0xe2, 0xe3, 0xe4, 0xc5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb,
0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
0xf8, 0xf9, 0xfa, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3,
0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb,
0xfc, 0xfd, 0xfe, 0xff};
I64 @strncasecmp(U8 *s1, U8 *s2, I64 n) {
U64 u1 = 0, u2 = 0;
for (n == n; n != 0; --n) {
u1 = *s1++;
u2 = *s2++;
if (@strncasecmp_charmap[u1] != @strncasecmp_charmap[u2]) {
return @strncasecmp_charmap[u1] - @strncasecmp_charmap[u2];
}
if (u1 == '\0') {
return 0;
}
}
return 0;
}
U0 strncasecmp() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: strncasecmp(0x%08x, 0x%08x, %d)\n", p0, p1, p2);
debug_print("strncasecmp: return value is %d\n", @strncasecmp(p0, p1, p2));
@strncasecmp(p0, p1, p2);
POP_SYSV_REGS
}
U8 *@strncpy(U8 *destination, U8 *source, I64 num) {
// return if no memory is allocated to the destination
if (destination == NULL) {
return NULL;
}
// take a pointer pointing to the beginning of the destination string
U8 *ptr = destination;
// copy first `num` characters of C-string pointed by source
// into the array pointed by destination
while (*source && num--) {
*destination = *source;
destination++;
source++;
}
// null terminate destination string
*destination = '\0';
// the destination is returned by standard `strncpy()`
return ptr;
}
U0 strncpy() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: strncpy(0x%08x, 0x%08x, %d)\n", p0, p1, p2);
@strncpy(p0, p1, p2);
POP_SYSV_REGS
}
U8 *@strrchr(U8 *str, I64 ch) {
U8 str2[2];
str2[0] = ch;
str2[1] = NULL;
return StrLastOcc(str, &str2);
}
U0 strrchr() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called strrchr(\"%s\",'%c')\n", p0, p1);
@strrchr(p0, p1);
POP_SYSV_REGS
}
U8 *CTYPE_TOUPPER_LOC = MAlloc(256, Fs->code_heap);
;
I64 @ctype_toupper_i;
for (@ctype_toupper_i = 0; @ctype_toupper_i < 256; @ctype_toupper_i++) {
switch (@ctype_toupper_i) {
case 'a' ... 'z':
CTYPE_TOUPPER_LOC[@ctype_toupper_i] = @ctype_toupper_i - 0x20;
break;
default:
CTYPE_TOUPPER_LOC[@ctype_toupper_i] = @ctype_toupper_i;
break;
}
}
U8 *@__ctype_toupper_loc() { return &CTYPE_TOUPPER_LOC; }
U0 __ctype_toupper_loc() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: __ctype_toupper_loc()\n");
@__ctype_toupper_loc;
POP_SYSV_REGS
}
U0 printf() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: printf(\"%s\")\n", p0);
convert_format_string(p0);
Print(p0, p1, p2, p3, p4, p5);
POP_SYSV_REGS
}
U0 system() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: system(\"%s\")\n", p0);
POP_SYSV_REGS
}
U0 toupper() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: toupper(\"%c\")\n", p0);
ToUpper(p0);
POP_SYSV_REGS
}
U0 time() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: time(%d)\n", p0);
SysTimerRead;
POP_SYSV_REGS
}
U0 vfprintf() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: vfprintf(0x%08x, 0x%08x, 0x%08x)\n", p0, p1, p2);
switch (p0) {
case 1:
// PutS(p2);
va_list *ap = p2;
U64 va_ptr = ap->reg_save_area;
va_ptr += ap->gp_offset;
Print(p1, *va_ptr(U64 *));
debug_print("addr is : 0x%08x\n", *va_ptr(U64 *));
break;
}
POP_SYSV_REGS
}
U0 vprintf() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: vprintf()\n");
va_list *ap = p1;
U64 va_ptr = ap->reg_save_area;
va_ptr += ap->gp_offset;
Print(p0, *va_ptr(U64 *));
debug_print("addr is : 0x%08x\n", *va_ptr(U64 *));
POP_SYSV_REGS
}
U0 vsnprintf() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: vsnprintf()\n");
va_list *ap = p3;
U64 va_ptr = ap->reg_save_area;
U64 va_ptr2;
va_ptr += ap->gp_offset;
va_ptr2 = va_ptr + 8;
if (StrFind("STCFN", p2) || debug.counter > 1646600) {
//"string: %s\n", p2;
// PressAKey;
}
convert_format_string(p2);
StrPrint(p0, p2, *va_ptr(U64 *), *va_ptr2(U64 *));
POP_SYSV_REGS
}

24
Lib/Misc.HC

@ -0,0 +1,24 @@
U0 PatchCallRel32(U32 from, U32 to) {
*(from(U8 *)) = 0xE8;
*((from + 1)(I32 *)) = to - from - 5;
}
U0 PatchJmpRel32(U32 from, U32 to) {
*(from(U8 *)) = 0xE9;
*((from + 1)(I32 *)) = to - from - 5;
}
U0 EnableSSE() {
asm
{
MOV_EAX_CR0
AND AX, 0xFFFB // clear coprocessor emulation CR0.EM
OR AX, 0x2 // set coprocessor monitoring CR0.MP
MOV_CR0_EAX
MOV_EAX_CR4
OR AX, 3 << 9 // set CR4.OSFXSR and CR4.OSXMMEXCPT at the same time
MOV_CR4_EAX
}
}
EnableSSE;

401
Lib/SDL2.HC

@ -0,0 +1,401 @@
#define SDL_APPACTIVE 0x04
#define SDL_APPINPUTFOCUS 0x02
#define SDL_APPMOUSEFOCUS 0x01
CDC *dc_gamescreen = DCNew(320, 200);
U16 sdl_mouse_x = 0;
U16 sdl_mouse_y = 0;
class SDL_Rect {
I16 x, y;
U16 w, h;
};
class SDL_Color {
U8 r;
U8 g;
U8 b;
U8 a;
};
class SDL_Palette {
I32 ncolors;
SDL_Color *colors;
};
class SDL_PixelFormat {
SDL_Palette *palette;
U8 BitsPerPixel;
U8 BytesPerPixel;
U8 Rloss, Gloss, Bloss, Aloss;
U8 Rshift, Gshift, Bshift, Ashift;
U32 Rmask, Gmask, Bmask, Amask;
U32 colorkey;
U8 alpha;
};
class SDL_Surface {
U64 flags;
SDL_PixelFormat *format;
I32 w, h;
U16 pitch;
U16 pad;
U32 pad2;
U8 *pixels;
SDL_Rect clip_rect;
I32 refcount;
};
class SDL_VideoInfo {
U32 hw_available;
U32 wm_available;
U32 blit_hw;
U32 blit_hw_CC;
U32 blit_hw_A;
U32 blit_sw;
U32 blit_sw_CC;
U32 blit_sw_A;
U32 blit_fill;
U32 video_mem;
SDL_PixelFormat *vfmt;
};
class @sdl {
I32 ticks_init;
};
@sdl sdl;
I64 sdl_p0, sdl_p1, sdl_p2;
#define POP_SDL_3 \
asm { POP RAX MOV [&sdl_p0], RAX POP RAX MOV [&sdl_p1], RAX POP RAX MOV [&sdl_p2], RAX}
I64 @SDL_Init() { return 0; }
I64 @SDL_CreateCursor() { return NULL; }
U0 SDL_CreateCursor() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: SDL_GetCursor(0x%08x, 0x%08x, %d, %d, %d, %d)\n", p0, p1,
p2, p3, p4, p5);
@SDL_CreateCursor;
POP_SYSV_REGS
}
/*
U0 SDL_CreateRGBSurfaceFrom() {
POP_SDL_3
PUSH_SYSV_REGS
GET_SYSV_ARGS
"called: SDL_CreateRGBSurfaceFrom(0x%08x, %d, %d, %d, %d, "
"0x%08x, 0x%08x, 0x%08x, 0x%08x",
p0, p1, p2, p3, p4, p5, sdl_p0, sdl_p1, sdl_p2;
PressAKey;
POP_SYSV_REGS
}
*/
U0 SDL_Delay() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: SDL_Delay(%d)\n", p0);
Sleep(p0);
POP_SYSV_REGS
}
I32 @SDL_EnableKeyRepeat(I32 delay, I32 interval) {
no_warn delay;
no_warn interval;
return 0;
}
U0 SDL_EnableKeyRepeat() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: SDL_EnableKeyRepeat(%d)\n", p0, p1);
@SDL_EnableKeyRepeat(p0, p1);
POP_SYSV_REGS
}
I32 @SDL_EnableUNICODE(I32 i) { return i; }
U0 SDL_EnableUNICODE() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: SDL_EnableUNICODE(%d)\n", p0);
@SDL_EnableUNICODE(p0);
POP_SYSV_REGS
}
I64 @SDL_FillRect(SDL_Surface *surface, SDL_Rect *rect, U32 color) {
no_warn rect;
MemSet(surface->pixels, color, surface->w * surface->h);
return NULL;
}
U0 SDL_FillRect() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: SDL_FillRect(0x%08x, 0x%08x, 0x%04x", p0, p1, p2);
POP_SYSV_REGS
}
I64 @SDL_Flip(SDL_Surface *surface) {
// dc_gamescreen->body = surface->pixels;
// GrBlot(gr.dc, 0, 0, dc_gamescreen);
while ((InU8(VGA_INSTAT_READ) & 1))
;
while (!(InU8(VGA_INSTAT_READ) & 1))
;
MemCpy(VGAM_GRAPHICS, surface->pixels, TG_WIDTH * TG_HEIGHT);
return 0;
}
U0 SDL_Flip() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: SDL_Flip(0x%08x)\n", p0);
// PressAKey;
@SDL_Flip(p0);
POP_SYSV_REGS
}
U0 SDL_UpdateRect() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: SDL_UpdateRect(0x%08x, %d, %d, %d, %d)\n", p0, p1, p2,
p3, p4);
@SDL_Flip(p0);
POP_SYSV_REGS
}
U0 SDL_Init() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: SDL_Init()\n");
sdl.ticks_init = cnts.jiffies;
@SDL_Init;
POP_SYSV_REGS
}
I64 @SDL_GetAppState() { return SDL_APPACTIVE | SDL_APPINPUTFOCUS; }
U0 SDL_GetAppState() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: SDL_GetAppState()\n");
@SDL_GetAppState;
POP_SYSV_REGS
}
I64 @SDL_GetCursor() { return NULL; }
U0 SDL_GetCursor() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: SDL_GetCursor()\n");
@SDL_GetCursor;
POP_SYSV_REGS
}
U8 @SDL_GetRelativeMouseState(I32 *x, I32 *y) {
no_warn x;
no_warn y;
return NULL;
}
U0 SDL_GetRelativeMouseState() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: SDL_GetRelativeMouseState(0x%08x, 0x%08x)\n", p0, p1);
@SDL_GetRelativeMouseState(p0, p1);
POP_SYSV_REGS
}
I32 @SDL_GetTicks() { return cnts.jiffies - sdl.ticks_init; }
U0 SDL_GetTicks() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: SDL_GetTicks()\n");
@SDL_GetTicks;
POP_SYSV_REGS
}
SDL_VideoInfo *@SDL_GetVideoInfo() {
SDL_VideoInfo *vinfo = CAlloc(sizeof(SDL_VideoInfo), Fs->code_heap);
vinfo->hw_available = 1;
vinfo->wm_available = 1;
vinfo->blit_hw = 1;
vinfo->blit_hw_CC = 1;
vinfo->blit_hw_A = 1;
vinfo->blit_sw = 1;
vinfo->blit_sw_CC = 1;
vinfo->blit_sw_A = 1;
vinfo->blit_fill = 1;
vinfo->video_mem = 1048576;
vinfo->vfmt = CAlloc(sizeof(SDL_PixelFormat), Fs->code_heap);
vinfo->vfmt->palette = CAlloc(sizeof(SDL_Palette), Fs->code_heap);
vinfo->vfmt->palette->ncolors = 256;
vinfo->vfmt->palette->colors = CAlloc(sizeof(SDL_Color) * 256, Fs->code_heap);
vinfo->vfmt->BitsPerPixel = 8;
vinfo->vfmt->BytesPerPixel = 1;
return vinfo;
}
U0 SDL_GetVideoInfo() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: SDL_GetVideoInfo()\n");
@SDL_GetVideoInfo;
POP_SYSV_REGS
}
SDL_Rect **@SDL_ListModes() {
SDL_Rect **modes = CAlloc(sizeof(SDL_Rect *) * 2, Fs->code_heap);
modes[0] = CAlloc(sizeof(SDL_Rect), Fs->code_heap);
modes[0]->w = 320;
modes[0]->h = 200;
return modes;
}
U0 SDL_ListModes() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: SDL_ListModes()\n");
@SDL_ListModes;
POP_SYSV_REGS
}
I64 @SDL_PollEvent(U64 event) {
no_warn event;
return 0;
}
U0 SDL_PollEvent() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: SDL_PollEvent(0x%08x)\n", p0);
@SDL_PollEvent(p0);
POP_SYSV_REGS
}
U0 @SDL_PumpEvents() {}
U0 SDL_PumpEvents() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: SDL_PumpEvents()\n");
@SDL_PumpEvents;
POP_SYSV_REGS
}
I64 @SDL_SetColors(SDL_Surface *surface, SDL_Color *colors, I64 firstcolor,
I64 ncolors) {
I64 i;
SDL_Color *dst_colors = surface->format->palette->colors;
for (i = firstcolor; i < ncolors; i++) {
TG_ColorSet(i, colors->r, colors->g, colors->b);
dst_colors->r = colors->r;
dst_colors->g = colors->g;
dst_colors->b = colors->b;
dst_colors++;
colors++;
}
return 1;
}
U0 SDL_SetColors() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: SDL_SetColors(0x%08x, 0x%08x, %d, %d)\n", p0, p1, p2,
p3);
@SDL_SetColors(p0, p1, p2, p3);
POP_SYSV_REGS
}
SDL_Surface *@SDL_SetVideoMode(I32 width, I32 height, I32 bpp, U32 flags) {
no_warn bpp;
TG_Start;
SDL_Surface *surface = CAlloc(sizeof(SDL_Surface), Fs->code_heap);
surface->flags = flags;
surface->format = CAlloc(sizeof(SDL_PixelFormat), Fs->code_heap);
surface->format->palette = CAlloc(sizeof(SDL_Palette), Fs->code_heap);
surface->format->palette->ncolors = 256;
surface->format->palette->colors =
CAlloc(sizeof(SDL_Color) * 256, Fs->code_heap);
surface->format->BitsPerPixel = 8;
surface->format->BytesPerPixel = 1;
surface->w = width;
surface->h = height;
surface->pitch = width;
surface->pixels = CAlloc(width * height, Fs->code_heap);
return surface;
}
U0 SDL_SetVideoMode() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: SDL_SetVideoMode(%d, %d, %d, %d)\n", p0, p1, p2, p3);
@SDL_SetVideoMode(p0, p1, p2, p3);
POP_SYSV_REGS
}
I64 @SDL_ShowCursor(I64 i) { return i; }
U0 SDL_ShowCursor() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: SDL_ShowCursor(%d)\n", p0);
@SDL_ShowCursor(p0);
POP_SYSV_REGS
}
U8 *@SDL_VideoDriverName(U8 *namebuf, I32 maxlen) {
no_warn maxlen;
StrCpy(namebuf, "TempleOS");
return namebuf;
}
U0 SDL_VideoDriverName() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: SDL_VideoDriverName(0x%08x, %d)\n", p0, p1);
@SDL_VideoDriverName(p0, p1);
POP_SYSV_REGS
}
U0 @SDL_WarpMouse(U16 x, U16 y) {
sdl_mouse_x = x;
sdl_mouse_y = y;
}
U0 SDL_WarpMouse() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called SDL_WarpMouse(%d, %d)\n", p0, p1);
@SDL_WarpMouse(p0, p1);
POP_SYSV_REGS
}
I64 @SDL_WM_GrabInput(I64 i) { return i; }
U0 SDL_WM_GrabInput() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: SDL_WM_GrabInput(%d)\n", p0);
@SDL_WM_GrabInput(p0);
POP_SYSV_REGS
}
U0 SDL_WM_SetCaption() {
PUSH_SYSV_REGS
GET_SYSV_ARGS
debug_print("called: SDL_WM_SetCaption('%s', 0x%08x)\n", p0, p1);
POP_SYSV_REGS
}

0
Lib/SDL2_net.HC

154
Lib/TOSGame.HC

@ -0,0 +1,154 @@
Bool TG_Debug = FALSE;
#define TG_COLORS 256
#define TG_WIDTH 320
#define TG_HEIGHT 200
#define VGA_MODE_320x200x256 0
#define VGA_MODE_640x480x16 1
#define VGA_MISC_WRITE 0x3C2
#define VGA_NUM_SEQ_REGS 5
#define VGA_SEQ_INDEX 0x3C4
#define VGA_SEQ_DATA 0x3C5
#define VGA_CRTC_INDEX 0x3D4
#define VGA_CRTC_DATA 0x3D5
#define VGA_NUM_CRTC_REGS 25
#define VGA_NUM_GC_REGS 9
#define VGA_GC_INDEX 0x3CE
#define VGA_GC_DATA 0x3CF
#define VGA_NUM_AC_REGS 21
#define VGA_INSTAT_READ 0x3DA
#define VGA_AC_INDEX 0x3C0
#define VGA_AC_WRITE 0x3C0
Bool TG_VGA_UPDATE = FALSE;
CBGR48 TOS_PALETTE[COLORS_NUM];
CDC *TG_Canvas = DCNew(TG_WIDTH, TG_HEIGHT);
I64 TOS_KEYDEV_FP[26];
U8 TG_VGAMode320x200x256[61] = {
0x63, 0x03, 0x01, 0x0F, 0x00, 0x0E, 0x5F, 0x4F, 0x50, 0x82, 0x54,
0x80, 0xBF, 0x1F, 0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x9C, 0x0E, 0x8F, 0x28, 0x40, 0x96, 0xB9, 0xA3, 0xFF, 0x00, 0x00,
0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, 0xFF, 0x00, 0x01, 0x02, 0x03,
0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
0x0F, 0x41, 0x00, 0x0F, 0x00, 0x00};
U8 TG_VGAMode640x480x16[61] = {
0xE3, 0x03, 0x01, 0x08, 0x00, 0x06, 0x5F, 0x4F, 0x50, 0x82, 0x54,
0x80, 0x0B, 0x3E, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xEA, 0x0C, 0xDF, 0x28, 0x00, 0xE7, 0x04, 0xE3, 0xFF, 0x00, 0x00,
0x00, 0x00, 0x03, 0x00, 0x05, 0x0F, 0xFF, 0x00, 0x01, 0x02, 0x03,
0x04, 0x05, 0x14, 0x07, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E,
0x3F, 0x01, 0x00, 0x0F, 0x00, 0x00};
U0 TG_VGASwitchMode(I64 mode) {
I64 i;
U8 *regs;
switch (mode) {
case VGA_MODE_320x200x256:
regs = &TG_VGAMode320x200x256;
break;
case VGA_MODE_640x480x16:
regs = &TG_VGAMode640x480x16;
break;
default:
return;
break;
}
OutU8(VGA_MISC_WRITE, *regs);
regs++;
for (i = 0; i < VGA_NUM_SEQ_REGS; i++) {
OutU8(VGA_SEQ_INDEX, i);
OutU8(VGA_SEQ_DATA, *regs);
regs++;
}
OutU8(VGA_CRTC_INDEX, 0x03);
OutU8(VGA_CRTC_DATA, InU8(VGA_CRTC_DATA) | 0x80);
OutU8(VGA_CRTC_INDEX, 0x11);
OutU8(VGA_CRTC_DATA, InU8(VGA_CRTC_DATA) & ~0x80);
regs[0x03] |= 0x80;
regs[0x11] &= ~0x80;
for (i = 0; i < VGA_NUM_CRTC_REGS; i++) {
OutU8(VGA_CRTC_INDEX, i);
OutU8(VGA_CRTC_DATA, *regs);
regs++;
}
for (i = 0; i < VGA_NUM_GC_REGS; i++) {
OutU8(VGA_GC_INDEX, i);
OutU8(VGA_GC_DATA, *regs);
regs++;
}
for (i = 0; i < VGA_NUM_AC_REGS; i++) {
InU8(VGA_INSTAT_READ);
OutU8(VGA_AC_INDEX, i);
OutU8(VGA_AC_WRITE, *regs);
regs++;
}
InU8(VGA_INSTAT_READ);
OutU8(VGA_AC_INDEX, 0x20);
}
U0 TG_ColorSet(I64 index, I64 r, I64 g,
I64 b) { // Set color value for color 0-255, RGB 0-255.
OutU8(VGAP_REG_WRITE, index);
OutU8(VGAP_PALETTE_DATA, r >> 2);
OutU8(VGAP_PALETTE_DATA, g >> 2);
OutU8(VGAP_PALETTE_DATA, b >> 2);
}
U0 TG_ColorGet(I64 index, I64 *r, I64 *g,
I64 *b) { // Get color value for color 0-255, RGB 0-255.
OutU8(VGAP_REG_READ, index);
r[0] = InU8(VGAP_PALETTE_DATA) << 2;
g[0] = InU8(VGAP_PALETTE_DATA) << 2;
b[0] = InU8(VGAP_PALETTE_DATA) << 2;
}
U0 TG_Flip() {
while ((InU8(VGA_INSTAT_READ) & 1))
;
while (!(InU8(VGA_INSTAT_READ) & 1))
;
MemCpy(VGAM_GRAPHICS, TG_Canvas->body, TG_WIDTH * TG_HEIGHT);
}
Bool TG_KeyDown(I64 sc) { return Bt(kbd.down_bitmap, sc); }
I64 TG_MouseX() { return ms.pos.x / 2; }
I64 TG_MouseY() { return ms.pos.y / 2.4; }
U0 TG_Start() {
I64 i;
GrPaletteGet(&TOS_PALETTE);
LBts(&sys_winmgr_task->task_flags, TASKf_SUSPENDED);
TG_VGASwitchMode(VGA_MODE_320x200x256);
for (i = 0; i < 26; i++) {
TOS_KEYDEV_FP[i] = keydev.fp_ctrl_alt_cbs[i];
keydev.fp_ctrl_alt_cbs[i] = NULL;
}
}
U0 TG_Exit() {
I64 i;
TG_VGASwitchMode(VGA_MODE_640x480x16);
GrPaletteSet(&TOS_PALETTE);
GrPaletteIndicesSet;
VGAFlush;
FifoU8Flush(kbd.scan_code_fifo);
FlushMsgs;
for (i = 0; i < 26; i++) {
keydev.fp_ctrl_alt_cbs[i] = TOS_KEYDEV_FP[i];
}
LBtc(&sys_winmgr_task->task_flags, TASKf_SUSPENDED);
}
U0 TG_Resume() {
// Resume from debugger.
TG_Start;
TG_Debug = FALSE;
G2;
}

15
Load.HC

@ -0,0 +1,15 @@
#define include_noreindex #include
include_noreindex "Lib/Debug";
include_noreindex "Lib/TOSGame";
include_noreindex "Lib/Misc";
include_noreindex "Lib/LibC";
include_noreindex "Lib/SDL2";
include_noreindex "Lib/SDL2_net";
include_noreindex "Lib/ELF64";
DocMax;
WinMax;
load_elf("chocolate-doom", "-mmap", "-nomouse", "-nosound", "-iwad",
"doom.wad");

1
Run.HC

@ -0,0 +1 @@
XTalkWait(Fs, "#include \"Load\";\n");
Loading…
Cancel
Save