/* * Test of 6809 instructions. * * The strategy is to allocate one kilobyte for a test area, which will * allow the code to load data at locations under and over the code itself. * There is a small control routine that is set and then calls the test * at location 500. It expects the test to return with a RTS instruction. */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include "cputest.h" #include "framework.h" void systemf1(const char *command, const char *param) { char tmp[strlen(command)+strlen(param)+2]; sprintf(tmp, command, param); //fprintf(stderr, "Executing %s\n", tmp); system(tmp); } /* Allocate enough memory to run the instructions in that allows * for jumps back and forth. Stack pointer is set at top. * initregs must follow immediately. */ // CODESTRT: ORG 0 // memory: ORG 0 - 99 // ctlmemory: ORG 100 - 1xx unsigned char memory[MEMSIZE+CTLMEMSIZE+REGSIZE+4]; // 4 for save_s and dpLoc /* Small code segment to save registers and call test. */ unsigned char *ctlmemory /* [100] */ = &memory[MEMSIZE]; /* WARNING! Host byte-sex sensitive */ struct registers *initregs = (struct registers *)&memory[MEMSIZE+CTLMEMSIZE]; char *currtest; #define CODESTRT 0 /* Store the initial value of the stack pointer. */ unsigned short *save_s = (unsigned short *)&memory[MEMSIZE+CTLMEMSIZE+REGSIZE]; unsigned short *dpLoc = (unsigned short *)&memory[MEMSIZE+CTLMEMSIZE+REGSIZE+2]; /** * Copy the instructions to test. * Instructions must begin at CODESTRT * The instructions must end with an RTS */ void copydata(int start, char *insv, int insc) { register int i; for (i = 0; i < insc; i++) { memory[start++] = insv[i]; } } void writebyte(int loc, char value) { memory[loc] = value; } unsigned setMem(int addr, char value) { memory[addr] = value; return (unsigned) addr; } void writeword(int loc, unsigned value) { memory[loc++] = Micro(value) >> 8; memory[loc] = Micro(value) & 0xFF; } /** * Calculate a valid value for the DP register. */ static unsigned calcDP(void) { //register unsigned t = 0 /* (unsigned) memory*/; //t = (t & 0xff00) + ((t & 0xff) != 0 ? 0x100 : 0x0); //return t; return 0x0200; // let's always put DP in page 2 } /* * Start location is the argument on the stack. */ static int codelen = 0; void jsrtest(int startloc) { //fprintf(stderr, "Jsr %04x\n", startloc&0xffff); #ifdef SBT // SBT int memp; FILE *bin, *dat; dat = fopen("code/prog.dat", "w"); fprintf(dat, "code 0000\n"); fprintf(dat, "label 0000 %s\n", currtest); fprintf(dat, "data %04x-03FF\n", codelen); fprintf(dat, "code 0400\n"); fprintf(dat, "label 0400 ENTRYPT\n"); fprintf(dat, "data 0418-0464\n"); fclose(dat); bin = fopen("code/prog.bin", "wb"); for (memp = 0; memp < MEMSIZE+CTLMEMSIZE; memp++) { fputc(memory[memp], bin); } fclose(bin); systemf1("../6809dasm --sbt code/prog.bin code/prog.dat > code/%s.c", currtest); #else #ifdef EMULATOR // Emulator #else // Native 6809 #asm * ldu 4,s * stu save_s,y jsr [4,s] #endasm #endif #endif /* SBT */ } void runcode(char *ctest, char *insv, int insc) { codelen = insc; // length of test code if using SBT. copydata(CODESTRT, insv, insc); runtest(ctest); } void runtest(char *ctest) { currtest = ctest; #ifdef SBT // SBT #else #ifdef EMULATOR // Emulator #else // Native 6809 #endif #endif /* SBT */ jsrtest((char *)ctlmemory-(char *)memory); } int setupCtl(void) { int start; start = 0; /* printf("Memory addr: %X\n", memory); */ *dpLoc = Micro(calcDP()); /* Push existing register state on normal stack */ ctlmemory[start++] = 0x34; ctlmemory[start++] = 0x7F; // 0x347F (PshS all regs?) /* Remember SP value */ ctlmemory[start++] = 0x10; ctlmemory[start++] = 0xFF; // 0x10FF /* STS */ ctlmemory[start++] = ((unsigned short)((char *)save_s-(char *)&memory[0])) >> 8; ctlmemory[start++] = ((unsigned short)((char *)save_s-(char *)&memory[0])) & 0xFF; // &save_s; /* Change SP to initregs */ ctlmemory[start++] = 0x10; ctlmemory[start++] = 0xCE; // 0x10CE /* LDS */ ctlmemory[start++] = ((unsigned short)(unsigned int)((char *)initregs-(char *)&memory[0])) >> 8; ctlmemory[start++] = ((unsigned short)(unsigned int)((char *)initregs-(char *)&memory[0])) & 0xff; // &initregs; /* Pull all registers */ ctlmemory[start++] = 0x35; ctlmemory[start++] = 0x7F; // 0x357F /* PulS all regs */ /* Call subroutine */ ctlmemory[start++] = 0xBD; /* JSR */ ctlmemory[start++] = ((unsigned short)(unsigned int)(CODESTRT)) >> 8; ctlmemory[start++] = ((unsigned short)(unsigned int)(CODESTRT)) & 0xFF; // &memory[CODESTRT] (0000) /* Push registers back to initregs */ ctlmemory[start++] = 0x34; ctlmemory[start++] = 0x7F; // 0x347F /* PshS all regs */ /* Reset SP to normal stack by loading content of save_s */ // NOT ADDRESS OF save_s ?? ctlmemory[start++] = 0x10; ctlmemory[start++] = 0xFE; // 0x10FE /* LDS */ // THIS MAY BE WRONG: ctlmemory[start++] = ((unsigned short)((char *)save_s-(char *)&memory[0])) >> 8; ctlmemory[start++] = ((unsigned short)((char *)save_s-(char *)&memory[0])) & 0xFF; // &save_s; /* Pull all registers */ ctlmemory[start++] = 0x35; ctlmemory[start++] = 0x7F; // 0x357F /* PulS all regs */ ctlmemory[start++] = 0x39; /* RTS */ return start; } void printMem(int start, int size) { register int i; for (i = start; i < start+size; i++) { fprintf(stderr, "%02X", memory[i]); if (i % 12 == 11) { fprintf(stderr, "\n"); } else { fprintf(stderr, ":"); } } } // to use: printCtl(CTLMEMSIZE); void printCtl(int ctlsize) { register int i; // should use 'dumpfile' format from my 'hexdump' program... /* This is all assuming a 16-bit host! Totally fails when host is an emulator on 32- or 64-bit machine */ //fprintf(stderr, "Save_s addr: %04x\n", (char *)save_s-(char *)&memory[0]); /* not interesting */ // fprintf(stderr, "Save_s content: %04x\n", (save_s[0]&255)<<8 | (save_s[1]&255)); // fprintf(stderr, "Memory addr: %04x\n", &memory[0]-&memory[0]); /* always 0 */ fprintf(stderr, "Initregs addr: %04x size: %d\n", (char *)initregs-(char *)&memory[0], REGSIZE); printMem((char *)initregs-(char *)&memory[0], REGSIZE); // fprintf(stderr, "Preloaded Stack addr: %04x\n", 0x0464); printMem(0x0464, 10); /* same as initregs */ fprintf(stderr, "\nCtlMem addr: %04x size: %d\n", (char *)ctlmemory-(char *)&memory[0], CTLMEMSIZE); // updated for portability for (i = 0; i < ctlsize; i+=2) { fprintf(stderr, "%04X", ((ctlmemory[i]&255)<<8) | (ctlmemory[i+1]&255) ); if (i % 12 == 11) { fprintf(stderr, "\n"); } else { fprintf(stderr, ":"); } } fprintf(stderr, "\n"); } /** * Read a value from the direct page. */ int readDPloc(int offset) { int loc = Host(*dpLoc) /* - (unsigned) memory */ + offset; //fprintf(stderr, "readDPloc(%d): memory[%04x] = 0x%02x\n", offset, loc, memory[loc] & 0xFF); return memory[loc] & 0xFF; } /** * Write a value into the direct page. */ void writeDPloc(int offset, unsigned char value) { int loc = Host(*dpLoc) /* - (unsigned) memory */ + offset; memory[loc] = value; //fprintf(stderr, "writeDPloc(%d,%u): memory[%04x] = 0x%02x\n", offset, value, loc, value); }