From: brian Date: Fri, 30 Jan 2004 07:40:47 +0000 (+0000) Subject: 2003/11/03 02:10:52 X-Git-Tag: RC3~385 X-Git-Url: http://git.megacz.com/?p=org.ibex.core.git;a=commitdiff_plain;h=ef41f45f245c8673f2a3648967c9d42a4c9c3184 2003/11/03 02:10:52 darcs-hash:20040130074047-aa32f-e9d551f38ca60aa901e51ea0c2bc94e38c830e35.gz --- diff --git a/Makefile b/Makefile index d0361e7..d89b329 100644 --- a/Makefile +++ b/Makefile @@ -178,7 +178,10 @@ build/mips/%.c.o: src/%.c make .install_freetype-2.1.4_mips-unknown-elf target=mips-unknown-elf mkdir -p $(@D) echo -e "\n\033[1mcompiling $< -> $@ (mips)\033[0m" - upstream/install/bin/mips-unknown-elf-gcc -march=r3000 -I upstream/freetype-2.1.4/src/include -c -o $@ $< + upstream/install/bin/mips-unknown-elf-gcc -march=r3000 \ + -Iupstream/freetype-2.1.4/src/include \ + -Iupstream/libmspack-20030726/libmspack/mspack/ \ + -c -o $@ $< build/res/freetype.mips: build/mips/org/xwt/translators/Freetype.c.o build/mips/org/xwt/mips/crt0.c.o build/mips/org/xwt/mips/syscalls.c.o make .install_freetype-2.1.4_mips-unknown-elf target=mips-unknown-elf diff --git a/src/org/xwt/mips/VM.java b/src/org/xwt/mips/VM.java index 08fee29..b0bbf7b 100644 --- a/src/org/xwt/mips/VM.java +++ b/src/org/xwt/mips/VM.java @@ -1,7 +1,7 @@ package org.xwt.mips; import java.io.*; -abstract class VM implements Syscalls, Errno { +public abstract class VM implements Syscalls, Errno { // Register Names protected final static int ZERO = 0; // Immutable, hardwired to 0 protected final static int AT = 1; // Reserved for assembler @@ -125,7 +125,7 @@ abstract class VM implements Syscalls, Errno { int end = start + (min(PAGE_SIZE-(addr&(PAGE_SIZE-1)),(length-n)&~3) >> 2); int[] page = readPages[addr >>> PAGE_SHIFT]; if(page == null) throw new ReadFaultException(addr); - if(page == emptyPage) { addr+=(end-start); n+=(end-start); continue; } + if(page == emptyPage) { addr+=(end-start)<<2; n+=(end-start)<<2; continue; } for(int i=start;i>>24)&0xff); a[n++] = (byte)((word>>>16)&0xff); @@ -504,7 +504,7 @@ abstract class VM implements Syscalls, Errno { } // Helper function to read a cstring from main memory - private String cstring(int addr) throws ReadFaultException { + public String cstring(int addr) throws ReadFaultException { StringBuffer sb = new StringBuffer(); for(;;) { int word = memRead(addr&~3); diff --git a/src/org/xwt/translators/MSPack.c b/src/org/xwt/translators/MSPack.c index 42bafcf..96cb1ac 100644 --- a/src/org/xwt/translators/MSPack.c +++ b/src/org/xwt/translators/MSPack.c @@ -1,16 +1,202 @@ -// Copyright 2003 Adam Megacz, see the COPYING file for licensing [GPL] +/* +UserInfo: + On start: + 0: Addr of CAB/EXE + 1: Length of CAB/EXE + On Edit: + 2: Addr of output_table array -/* NOTE: _user_info is defined in crt0.c. It points to a 4096 byte - block of memory that contains 1024 32-bit values that can be set - with the setUserInfo() method of MIPSEmu. +Exit codes: + 0: Success + 1: Internal Error + 2: Invalid CAB +*/ - The VM will pause after initialization. When unpaused, it expects - that: +#include +#include +#include +#include +#include - FIXME +#include "mspack.h" -*/ +#define MAX(a,b) (((a)>(b))?(a):(b)) +#define MIN(a,b) (((a)<(b))?(a):(b)) +#define MAX_MEMBERS 64 + +char *xstrdup(const char *s) { + char *ret = strdup(s); + if(ret == NULL) exit(1); + return ret; +} + +typedef struct { + char *addr; + int pos; + int size; + int length; + int writable; +} mem_buf_t; + +static mem_buf_t *cab_mem_buf = NULL; + +static void mem_buf_grow(mem_buf_t *buf,size_t newsize) { + size_t new_len; + char *p; + if(buf->length < 0) exit(1); + if(newsize <= buf->length) return; + new_len = MAX(buf->length ? buf->length*2 : 65536,newsize); + p = realloc(buf->addr,new_len); + if(p == NULL) exit(1); + buf->addr = p; + buf->length = new_len; +} + +static struct { + char *filename; + mem_buf_t buf; +} write_buf_table[MAX_MEMBERS]; + +static struct { + char *filename; + char *data; + int length; +} output_table[MAX_MEMBERS+1]; + +static struct mspack_file *my_open(struct mspack_system *sys, char *filename, int mode) { + mem_buf_t *buf = NULL; + int i; + if(strcmp(filename,"/dev/cab")==0) { + if(mode != MSPACK_SYS_OPEN_READ) return NULL; + buf = cab_mem_buf; + } else { + if(mode != MSPACK_SYS_OPEN_WRITE) return NULL; + + for(i=0;iwritable = 1; + break; + } + } + } + + return (struct mspack_file *) buf; +} + +static void my_close(struct mspack_file *buf_) { + mem_buf_t *buf = (mem_buf_t*) buf_; + /* NO OP */ +} + +static int my_read(struct mspack_file *buf_, void *out, int count) { + mem_buf_t *buf = (mem_buf_t*) buf_; + count = MIN(buf->size - buf->pos, count); + memcpy(out,buf->addr + buf->pos,count); + buf->pos += count; + return count; +} + +static int my_write(struct mspack_file *buf_, void *in, int count) { + mem_buf_t *buf = (mem_buf_t*) buf_; + if(!buf->writable) return -1; + if(buf->length < buf->pos + count) mem_buf_grow(buf,buf->pos + count); + memcpy(buf->addr+buf->pos,in,count); + buf->pos += count; + buf->size = MAX(buf->size,buf->pos); + return count; +} + +static int my_seek(struct mspack_file *buf_, off_t off, int mode) { + mem_buf_t *buf = (mem_buf_t*) buf_; + int newpos; + switch(mode) { + case MSPACK_SYS_SEEK_START: newpos = off; break; + case MSPACK_SYS_SEEK_CUR: newpos = buf->pos + off; break; + case MSPACK_SYS_SEEK_END: newpos = buf->size - off; break; + default: return -1; + } + if(newpos < 0) return -1; + if(newpos > buf->size) { + if(buf->writable) return -1; + if(newpos > buf->length) + mem_buf_grow(buf,newpos); + } + buf->pos = newpos; + return 0; +} + +static off_t my_tell(struct mspack_file *buf_) { + mem_buf_t *buf = (mem_buf_t*) buf_; + return buf ? buf->pos : 0; +} + +// FEATURE: Remove this to possibly avoid pulling in stdio from libc +// (it may be getting pulled in anyway from malloc or something) +static void my_message(struct mspack_file *file, char *format, ...) { + va_list ap; + va_start(ap, format); + vfprintf(stderr, format, ap); + va_end(ap); + fputc((int) '\n', stderr); + fflush(stderr); +} + +static void *my_alloc(struct mspack_system *sys, size_t size) { return malloc(size); } +static void my_free(void *p) { free(p); } +static void my_copy(void *src, void *dest, size_t bytes) { memcpy(dest, src, bytes); } + +static struct mspack_system my_system = { + &my_open, + &my_close, + &my_read, + &my_write, + &my_seek, + &my_tell, + &my_message, + &my_alloc, + &my_free, + &my_copy, + NULL +}; + +extern char **_user_info; + +int main(int argc, char **argv) { + struct mscab_decompressor *decomp; + struct mscabd_cabinet *cab; + struct mscabd_file *file; + mem_buf_t mem_buf; + size_t size = (size_t)_user_info[1]; + int i; + + mem_buf.addr = _user_info[0]; + mem_buf.pos = mem_buf.writable = 0; + mem_buf.length = -1; + mem_buf.size = size; + + cab_mem_buf = &mem_buf; + + decomp = mspack_create_cab_decompressor(&my_system); + if(!decomp) exit(1); + + cab = decomp->search(decomp,"/dev/cab"); + if(!cab) exit(2); -int main(int argc, char** argv) { - // FIXME: do some cool stuff here + for(file = cab->files;file;file=file->next) + decomp->extract(decomp,file,file->filename); + + decomp->close(decomp,cab); + mspack_destroy_cab_decompressor(decomp); + + for(i=0;i