Advertisement
Aslai

Brainfuck to z80 compiler

Oct 9th, 2011
217
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 11.69 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stack>
  3.  
  4.     #define AHAN \
  5.     {\
  6.         if( arithtrack != 0 ){\
  7.             bool neg = arithtrack < 0;\
  8.             if( arithtrack < 0 ) arithtrack = -arithtrack;\
  9.             arithtrack = arithtrack & 0xFF;\
  10.             if( !neg && arithtrack < 4 )\
  11.                 while( arithtrack-- > 0 )\
  12.                     {fprintf( a, "%c", 0x34 ); p++;}      \
  13.             else if( neg && arithtrack < 4 )\
  14.                 while( arithtrack-- > 0 )\
  15.                     {fprintf( a, "%c", 0x35 ); p++;}      \
  16.             else if( !neg )\
  17.                 {fprintf( a, "%c%c%c%c", \
  18.                         0x7E,                   \
  19.                         0xC6, arithtrack&0xFF,  \
  20.                         0x77                    \
  21.                         ); p+=4;}     \
  22.             else if( neg )\
  23.                 {fprintf( a, "%c%c%c%c", \
  24.                         0x7E,                       \
  25.                         0xD6, (arithtrack)&0xFF,   \
  26.                         0x77                        \
  27.                         ); p+=4;}\
  28.             arithtrack = 0;\
  29.         }\
  30.     }
  31.  
  32.     #define MHAN\
  33.     {\
  34.         if( movtrack != 0 )\
  35.         {\
  36.             while( movtrack > 0 ){\
  37.                 fprintf( a, "%c%c%c%c",\
  38.                         0xCD, GoRight&0xff, (GoRight>>8)&0xff,    \
  39.                         movtrack&0xff                             \
  40.                         ); p += 4;\
  41.                 movtrack >>= 8;\
  42.             }\
  43.             if( movtrack < 0 ){\
  44.                 movtrack = -movtrack;\
  45.                 while( movtrack > 0 ){\
  46.                     fprintf( a, "%c%c%c%c",\
  47.                             0xCD, GoLeft&0xff, (GoLeft>>8)&0xff,    \
  48.                             movtrack&0xff                           \
  49.                             ); p += 4;\
  50.                     movtrack >>= 8;\
  51.                 }\
  52.             }\
  53.             movtrack = 0;\
  54.         }\
  55.     }
  56.  
  57.  
  58. int main(){
  59.     //Initialise the butters
  60.     std::stack<int> s;         //Stack to hold '[' locations
  61.     char in[100000];           //input butter
  62.     printf( ": "); gets( in ); //Get the BF program
  63.     FILE* a = fopen( "out.bin", "wb" );
  64.     int p = 0x9D93; //This is the Texas Instruments magic number for where programs are loaded in memory
  65.  
  66.     fprintf( a, "%c%c", 0xBB, 0x6D ); p+=2;     //.DB BBh,6Dh       ;Declare an ASM program
  67.     fprintf( a, "%c%c%c", 0x21, 0xEC, 0x86 ); p+=3; //LD HL,86ECh   ;Safe RAM
  68.  
  69.     fprintf( a, "%c%c%c", 0x11, 0x00, 0x03 ); p+=3;         //LD DE,0300h      ;Set the counter to 0xFF
  70.     fprintf( a, "%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c",
  71.             0x36, 0,                    //LD (HL),0         ;Clear the next 768 bytes
  72.             0x23,                       //INC HL            ;...
  73.             0x1B,                       //DEC DE            ;...
  74.             0x7B,                       //LD A,E            ;...
  75.             0xFE, 0,                    //CP 0              ;...
  76.             0xC2, p&0xFF,(p>>8)&0xFF,   //JP NZ,(BEGINLOOP) ;...
  77.             0x7A,                       //LD A,D            ;...
  78.             0xFE, 0x00,                 //CP 0              ;...
  79.             0xC2, p&0xFF,(p>>8)&0xFF ); //JP NZ,(BEGINLOOP) ;...
  80.             p+=16;
  81.     char getAnstoDE[] = {   0x21, 0x78, 0x84,   //LD HL,OP1         ;Spell out the Ans variable
  82.                             0x36, 0x04,         //LD (HL),StrngObj  ;...
  83.                             0x23,               //INC HL            ;...
  84.                             0x36, 0x72,         //LD (HL),tAns      ;...
  85.                             0x23,               //INC HL            ;...
  86.                             0x36, 0x00,         //LD (HL),0         ;...
  87.                             0x23,               //INC HL            ;...
  88.                             0x36, 0x00,         //LD (HL),0         ;...
  89.                             0xEF, 0xF4, 0x42,   //B_CALL(_FindSym)  ;Load the pointer to a string in to DE
  90.                             0x1A, 0x6f,         //LD L,(DE)         ;Get the strings length in to HL
  91.                             0x13,               //INC DE            ;...
  92.                             0x1A, 0x67,         //LD H,(DE)         ;...
  93.                             0x13,               //INC DE            ;...
  94.                             0x19,               //ADD HL,DE         ;Move HL to the end of the string
  95.                             0x36, 0x00          //LD (HL),0         ;Null-terminate it
  96.                             };
  97.     fwrite( getAnstoDE, 26, 1, a ); p += 26;
  98.  
  99.     fprintf( a, "%c%c%c%c%c%c",
  100.             0x21, 0xEC, 0x86,           //LD HL,86ECh       ;Jump back to the start of the safe RAM
  101.             0x01, 0x00, 0x00 ); p+=6;   //LD BC,0            ;Set the bounds checker to 0
  102.  
  103.     fprintf( a, "%c%c%c",
  104.             0xC3, (p+81)&0xFF,((p+81)>>8)&0xFF  //JP (After defs)   ;Skip the definition code
  105.              ); p += 3;
  106.     //Define <
  107.     int GoLeft = p;
  108.     fprintf( a, "%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c",
  109.             0xDD, 0xE1,     //POP IX
  110.             0xDD, 0x7E, 0,  //LD A,(IX+0)
  111.             0x3D,           //DEC A
  112.             0x32, (GoLeft+20)&0xFF, ((GoLeft+20)>>8)&0xFF, //LD (ArgSpot),A ;Set up arg for recursion
  113.             0xDD, 0x23,     //INC IX
  114.             0xDD, 0xE5,     //PUSH IX
  115.  
  116.             0xFE, 0x00,     //CP 0
  117.             0x28, 0x04,     //JR Z,4
  118.             0xCD, (GoLeft)&0xFF, (GoLeft>>8)&0xFF,      //CALL GoLeft
  119.             0x00,
  120.  
  121.             0x23,           //INC HL    ;Move the pointer forwards
  122.             0x03,           //INC BC    ;Increase the bounds checker
  123.             0x78,           //LD A,B    ;Move the Bounds Checker high byte to the Accumulator
  124.             0xFE, 0x03,     //CP 3      ;Check if we're at max
  125.             0x20, 0x06,     //JR NZ,6    ;If it is 3, then move the pointer back by 768
  126.             0x25,           //DEC H     ;...
  127.             0x25,           //DEC H     ;...
  128.             0x25,           //DEC H     ;...
  129.             0x01, 0x00,0x00,//LD BC,0   ;Reset the bounds checker
  130.             0xC9            //RET
  131.              );p+=35;
  132.     //define >
  133.     int GoRight = p;
  134.         fprintf( a, "%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c",
  135.             0xDD, 0xE1,     //POP IX
  136.             0xDD, 0x7E, 0,  //LD A,(IX+0)
  137.             0x3D,           //DEC A
  138.             0x32, (GoRight+20)&0xFF, ((GoRight+20)>>8)&0xFF, //LD (ArgSpot),A ;Set up arg for recursion
  139.             0xDD, 0x23,     //INC IX
  140.             0xDD, 0xE5,     //PUSH IX
  141.  
  142.             0xFE, 0x00,     //CP 0
  143.             0x28, 0x04,     //JR Z,4
  144.             0xCD, (GoRight)&0xFF, (GoRight>>8)&0xFF,      //CALL GoRight
  145.             0x00,
  146.  
  147.             0x2B,           //DEC HL    ;Move the pointer backwards
  148.             0x0B,           //DEC BC    ;Decrease the bounds checker
  149.             0x78,           //LD A,B    ;Move the Bounds Checker high byte to the Accumulator
  150.             0xFE, 0xFF,     //CP FFh    ;Check if we're at -1
  151.             0x20, 0x06,     //JR NZ,6   ;If it is -1, then move the pointer forward by 768
  152.             0x24,           //INC H     ;...
  153.             0x24,           //INC H     ;...
  154.             0x24,           //INC H     ;...
  155.             0x01, 0xFF,0x02,//LD BC,02FFh ;Reset the bounds checker
  156.             0xC9            //RET
  157.              );p+=35;
  158.     //Define ,
  159.     int GetC = p;
  160.     fprintf( a, "%c%c%c%c%c%c%c%c",
  161.             0x1A,       //LD A,(DE) ;Get the next char on the input stream
  162.             0x77,       //LD (HL),A ;Stick it in to the memory at pointer
  163.             0xFE, 0x00, //CP 0      ;If it's zero, then don't increase the input stream pointer
  164.             0x28, 0x01, //JR Z,1    ;...
  165.             0x13,       //INC DE    ;...
  166.             0xC9        //RET
  167.             );p+=8;
  168.     int arithtrack = 0;
  169.     int movtrack = 0;
  170.  
  171.  
  172.  
  173.     for( int i = 0; in[i] != 0; i ++ ){
  174.         switch( in[i] ){
  175.             case '+':{
  176.                 MHAN
  177.                 arithtrack++;
  178.                 }break;
  179.             case '-':{
  180.                 MHAN
  181.                 arithtrack--;
  182.                 }break;
  183.             case '>':{
  184.                 AHAN
  185.                 movtrack++;
  186.                 }break;
  187.             case '<':{
  188.                 AHAN
  189.                 movtrack--;
  190.                 }break;
  191.             case '[':
  192.             {
  193.                 AHAN
  194.                 MHAN
  195.                 s.push( p+6 );  //Track the location of this for jumping back
  196.                 int pp = p+6;     //Temp pointer
  197.                 int arithchange = 0;
  198.                 int movcnt = 0;
  199.  
  200.                 for( int j = i+1, depth = 1; in[j] != 0; j++ ){     //Find the matching ']'
  201.                     if( in[j] == '[' ) depth ++;
  202.                     if( in[j] == ']' ) depth --;
  203.                     if( in[j] == '+' || in[j] == '-'){
  204.                         if( in[j] == '+' ) arithchange ++;
  205.                         if( in[j] == '-' ) arithchange --;
  206.                     }
  207.                     else{
  208.                         if( arithchange < 0 ) arithchange = - arithchange;
  209.                         if( arithchange >=4 ) pp += 4;
  210.                         else pp += arithchange;
  211.                         arithchange = 0;
  212.                     }
  213.                     if( in[j] == '<' || in[j] == '>' ){
  214.                         if( in[j] == '<' ) movcnt--;
  215.                         if( in[j] == '>' ) movcnt++;
  216.                         //pp += 3;
  217.                     }
  218.                     else if( movcnt != 0 ){
  219.                         if( movcnt < 0 ) movcnt = -movcnt;
  220.                         while( movcnt > 0 ){
  221.                             pp += 4;
  222.                             movcnt >>= 8;
  223.                         }
  224.                     }
  225.                     if( in[j] == '[' || in[j] == ']' ){
  226.                         pp+=6;
  227.                     }
  228.                     if( in[j] == '.'){
  229.                         pp+=4;
  230.                     }
  231.                     if( in[j] == ','){
  232.                         pp += 3;
  233.                     }
  234.                     if( depth <= 0 ) break;
  235.                 }
  236.                 fprintf( a, "%c%c%c%c%c%c",
  237.                         0x7E,                       //LD A,(HL)         ;Grab the byte at the pointer and jump to the matching ']' if zero
  238.                         0xFE, 0x00,                 //CP 0              ;...
  239.                         0xCA, pp&0xFF, (pp>>8)&0xFF //JP Z,(MATCHING ]) ;...
  240.                          ); p+=6;
  241.             } break;
  242.             case ']':
  243.             {
  244.                 AHAN
  245.                 MHAN
  246.                 int pp = s.top( );
  247.                 s.pop();
  248.                 fprintf( a, "%c%c%c%c%c%c",
  249.                         0x7E,                       //LD A,(HL)             ;Grab the byte at the pointer and jump to the matching '[' if not zero
  250.                         0xFE, 0x00,                 //CP 0                  ;...
  251.                         0xC2, pp&0xFF, (pp>>8)&0xFF //JP NZ,(MATCHING [)    ;...
  252.                         ); p+=6;
  253.             } break;
  254.             case '.':
  255.             {
  256.                 AHAN
  257.                 MHAN
  258.                 fprintf( a, "%c%c%c%c",
  259.                         0x7E,               //LD A,(HL)     ;Print the character being pointed at
  260.                         0xEF, 0x04, 0x45    //B_CALL(PutC)  ;...
  261.                         ); p+=4;
  262.             } break;
  263.             case ',':
  264.             {
  265.                 AHAN
  266.                 MHAN
  267.                 fprintf( a, "%c%c%c",
  268.                         0xCD, GetC&0xff, (GetC>>8)&0xff     //CALL GetC
  269.                         ); p += 3;
  270.             } break;
  271.         }
  272.     }
  273.     AHAN
  274.     MHAN
  275.     fprintf( a, "%c", 0xC9 ); p+=1; //RET   ;Return control to the TI-OS
  276. }
  277.  
  278.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement