File: dynrec.c

package info (click to toggle)
nestra 0.66-1
  • links: PTS
  • area: contrib
  • in suites: potato
  • size: 300 kB
  • ctags: 462
  • sloc: ansic: 2,808; asm: 1,337; makefile: 65
file content (112 lines) | stat: -rw-r--r-- 4,343 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
/* Nestra dynrec.c */
/* Public Domain */

#include <stdio.h>
#include "mapper.h"
#include "globals.h"

/* This is the dynamic recompiler.  This takes 6502 code as input, looks
   up the opcodes in the translation dictionary, evaluates any expressions
   found therein, and writes the translated code to *(next_code_alloc++)
   Pretty simple, huh?  */

u_char *next_code_alloc=CODE_BASE;

/* Some declarataions for the asm code */
unsigned int VFLAG;   /* Store overflow flag */
unsigned int FLAGS;   /* Store 6502 process status reg */
unsigned int STACKPTR;/* Store 6502 stack pointer */
unsigned int PCR;     /* Store 6502 program counter */
void *XPC;            /* Translated program counter */
signed int INRET;     /* Input data return value */
signed int CTNI;      /* Cycles to next interrupt */
unsigned int VRAMPTR; /* address to read/write video memory */
unsigned int DMOD;    /* Dest addr to modify */
unsigned int LASTBANK;/* Last memory page code executed in */

/* x86-specific definitions */
#define NOP 0x90
#define BRK 0xCC

translate(int addr)
{
  int saddr;
  u_char src;
  unsigned int *ptr,*nptr;
  unsigned char *sptr;
  unsigned char *cptr,*bptr;
  int slen,dlen;
  int x;
  u_char m,l,o;
  u_char stop=0;
  
  XPC=cptr=next_code_alloc;
  if(disassemble)
  {
    printf("\n[%4x] (%8x) -> %8x\n",addr,(int)(MAPTABLE[addr>>12]+addr),cptr);fflush(stdout);
    disas (addr); /* This will output a disassembly of the 6502 code */
  }
  while(!stop)
  {
    saddr=addr;
    INT_MAP[(MAPTABLE[addr>>12]+addr)-RAM]=(unsigned int)cptr;
    ptr=(int *)TRANS_TBL;
    while(1)
    {
      src=*(MAPTABLE[addr>>12]+addr);
      addr++;
      /*printf("%x%x",src>>4,src&0xF);fflush(stdout);*/
      if(ptr[src]==0) break;
      if(ptr[src]&1) break;
      ptr=(int *)(ptr[src]+(int)TRANS_TBL);
    }
    if(ptr[src]==0) {
      addr=saddr+1;
      /*printf("!%2x-NULL!",src);*/
      if(!ignorebadinstr)
        *(cptr++)=BRK;
    }
    else{
      sptr=(u_char *)TRANS_TBL+ptr[src];
      slen=sptr[-1];
      dlen=x=*(sptr++);
      bptr=cptr;
      while(x--) *(cptr++)=*(sptr++);
      while(*sptr!=0)
      {
        m=*(sptr++);l=*(sptr++);o=*(sptr++);
        /*printf("[%c%d %d]",m,o,l);fflush(stdout);*/
        if(m=='!') stop=1;
        if(m=='B') bptr[l]=*(MAPTABLE[(saddr+o)>>12]+(saddr+o));
        if(m=='C') bptr[l]=~*(MAPTABLE[(saddr+o)>>12]+(saddr+o));
        if(m=='D') *((unsigned int *)(bptr+l))=(unsigned int)bptr+l+o;
        if(m=='E') *((int *)(bptr+l))=*((signed char *)(MAPTABLE[(saddr+o)>>12]+(saddr+o)));
        if(m=='Z') *((unsigned int *)(bptr+l))=(unsigned int)ZPMEM + *(MAPTABLE[(saddr+o)>>12]+saddr+o);
        if(m=='A') *((unsigned int *)(bptr+l))=(unsigned int)RAM + *(MAPTABLE[(saddr+o)>>12]+saddr+o) + ((*(MAPTABLE[(saddr+o+1)>>12]+saddr+o+1))<<8);
        if(m=='L') *((unsigned int *)(bptr+l))=(unsigned int)RAM;
        if(m=='W') *((unsigned short *)(bptr+l))= *(MAPTABLE[(saddr+o)>>12]+saddr+o) + ((*(MAPTABLE[(saddr+o+1)>>12]+saddr+o+1))<<8);
        if(m=='X') *((unsigned int *)(bptr+l))=(unsigned int)(MAPTABLE+((*(MAPTABLE[(saddr+o+1)>>12]+saddr+o+1))>>4));
        if(m=='M') *((unsigned int *)(bptr+l))=(unsigned int)(MAPTABLE);
        if(m=='T') *((unsigned int *)(bptr+l))=(unsigned int)STACK;
        if(m=='P') *((unsigned short *)(bptr+l))=saddr+o;
        if(m=='R') *((int *)(bptr+l))=*((signed char *)(MAPTABLE[(saddr+o)>>12]+saddr+o))+saddr+o+1;
        if(m=='J') *((unsigned int *)(bptr+l))=*(MAPTABLE[(saddr+o)>>12]+saddr+o) + ((*(MAPTABLE[(saddr+o+1)>>12]+saddr+o+1))<<8);
        if(m=='S') *((void **)(bptr+l))=&STACKPTR;
        if(m=='V') *((void **)(bptr+l))=&VFLAG;
        if(m=='F') *((void **)(bptr+l))=&FLAGS;
        if(m=='I') *((int *)(bptr+l))=(int)(&INPUT)-(int)(bptr+l)-4;
        if(m=='O') *((int *)(bptr+l))=(int)(&OUTPUT)-(int)(bptr+l)-4;
        if(m=='U') *((int *)(bptr+l))=(int)(&U)-(int)(bptr+l)-4;
        if(m=='N') *((int *)(bptr+l))=(int)(&NMI)-(int)(bptr+l)-4;
        if(m=='Y') *((int *)(bptr+l))=(int)(Mapper[MAPPERNUMBER])-(int)(bptr+l)-4;
        if(m=='>') bptr[l]+=(((*((signed char *)(MAPTABLE[(saddr+o)>>12]+saddr+o))+saddr+o+1)&0xFF00)!=((saddr+o+1)&0xFF00));
        if(m=='^') bptr[l]=ignorebadinstr?NOP:BRK;

      }
      addr=saddr+slen;
    }
  }
  while(((int)cptr&15)!=0) *(cptr++)=NOP;
  next_code_alloc=cptr;
}