diff --git a/Makefile b/Makefile index e4659bc3..1bd46eaf 100644 --- a/Makefile +++ b/Makefile @@ -3,5 +3,9 @@ all: src/collect_data src/collect_data: src/collect_data.c Makefile gcc -Wall -o src/collect_data src/collect_data.c +src/preprocess: src/preprocess.c Makefile + gcc -Wall -o src/preprocess src/preprocess.c + + c64/kernal-disasembly.html: wget -O c64/kernal-disassembly.html http://www.ffd2.com/fridge/docs/c64-diss.html diff --git a/README.md b/README.md index b3f48fa9..f5c9f614 100644 --- a/README.md +++ b/README.md @@ -48,3 +48,17 @@ We can capture this information using x64 -remotemonitor, and then making a prog and uses reset 0 to reset the CPU, and then types step and sends carriage returns repeatedly, and logs the instruction stream. If a program is loaded and run, then this will capture the instruction stream, and allow us to generate this call graph. + +# Specific Method + +1. Begin with the immutable starting point of the 6502 reset entries, IRQ entry and NMI entries, and the rest of the ROM being empty. This starting point can have no copyright problems. +2. Based on the public calling interface of the C64 KERNAL, make stub routines for the jump table. +3. All routines begin at the lowest address in the kernal, sorted by routine name. Thus the order of the routines is deterministic, and not the result of any creative process. +3. Run a test program with the C64 KERNAL, and collect entry points. +4. Implement the routines in the order that the entry points are discovered. +5. Where an entry point does not correspond to a public API of the KERNAL, research the function by searching for it in Google. Implement it according to the first matching reference. +6. Where an entry point means that previously implemented routines have to be moved to make space at a specific address, move only those routines required to do so, to the next available address. + +To organise this as we develop, we will assemble the ROM from many separate source files, each with a single routine in it, and with the name of the file matching the routine. Where code must be placed at a specific address, the file should be called xxxx.routine.s, where xxxx is the address. We will write a special preprocessor that will take the routines and put them in the correct deterministic order, and make +sure that no address placement violations occur. To make this easier to do, we are using the Ophis assembler, as it makes it quite easy to check such things. + diff --git a/src/preprocess.c b/src/preprocess.c new file mode 100644 index 00000000..42e3976c --- /dev/null +++ b/src/preprocess.c @@ -0,0 +1,58 @@ +/* + Pre-process the various assembly source files to create a single + file for assembly, that has everything where it needs to live. + +*/ + +#include +#include +#include +#include +#include +#include + +#define DO_ERROR(X) { retVal=-1; fprintf(stderr,"%s:%d:%s():%s\n",__FILE__,__LINE__,__func__,X); break; } + +void usage(void) +{ + fprintf(stderr,"usage: preprocess [-d ]\n"); + +} + +int main(int argc,char **argv) +{ + + int retVal=0; + DIR *d=NULL; + char *directory="."; + struct dirent *de=NULL; + + do { + + int opt; + + while ((opt=getopt(argc,argv,"d:")) != -1) { + switch(opt) { + case 'd': directory=optarg; break; + default: + usage(); + exit(-1); + } + } + + d=opendir(directory); + if (!d) DO_ERROR("opendir() failed"); + + while((de=readdir(d))!=NULL) { + if (strlen(de->d_name)>2) { + if (!strcmp(&de->d_name[strlen(de->d_name)-2],".s")) { + printf("%s\n",de->d_name); + } + } + } + + } while(0); + + if (d) closedir(d); + return retVal; +}