Aslai

Brainfuck to z80 compiler

Oct 10th, 2011
319
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 14.56 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 errors = 0;
  65.     int p = 0x9D93; //This is the Texas Instruments magic number for where programs are loaded in memory
  66.  
  67.     fprintf( a, "%c%c", 0xBB, 0x6D ); p+=2;     //.DB BBh,6Dh       ;Declare an ASM program
  68.     fprintf( a, "%c%c%c", 0x21, 0xEC, 0x86 ); p+=3; //LD HL,86ECh   ;Safe RAM
  69.  
  70.     fprintf( a, "%c%c%c", 0x11, 0x00, 0x03 ); p+=3;         //LD DE,0300h      ;Set the counter to 0xFF
  71.     fprintf( a, "%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c",
  72.             0x36, 0,                    //LD (HL),0         ;Clear the next 768 bytes
  73.             0x23,                       //INC HL            ;...
  74.             0x1B,                       //DEC DE            ;...
  75.             0x7B,                       //LD A,E            ;...
  76.             0xFE, 0,                    //CP 0              ;...
  77.             0xC2, p&0xFF,(p>>8)&0xFF,   //JP NZ,(BEGINLOOP) ;...
  78.             0x7A,                       //LD A,D            ;...
  79.             0xFE, 0x00,                 //CP 0              ;...
  80.             0xC2, p&0xFF,(p>>8)&0xFF ); //JP NZ,(BEGINLOOP) ;...
  81.             p+=16;
  82.     fprintf( a, "%c%c%c%c",
  83.             0xFD, 0xCB, 0x09, 0xA6      //RES onInterrupt,(IY+onFlags)      ;reset On key flag
  84.             ); p += 4;
  85.     char getAnstoDE[] = {   0x21, 0x78, 0x84,   //LD HL,OP1         ;Spell out the Ans variable
  86.                             0x36, 0x04,         //LD (HL),StrngObj  ;...
  87.                             0x23,               //INC HL            ;...
  88.                             0x36, 0x72,         //LD (HL),tAns      ;...
  89.                             0x23,               //INC HL            ;...
  90.                             0x36, 0x00,         //LD (HL),0         ;...
  91.                             0x23,               //INC HL            ;...
  92.                             0x36, 0x00,         //LD (HL),0         ;...
  93.                             0xEF, 0xF4, 0x42,   //B_CALL(_FindSym)  ;Load the pointer to a string in to DE
  94.                             0x1A, 0x6f,         //LD L,(DE)         ;Get the strings length in to HL
  95.                             0x13,               //INC DE            ;...
  96.                             0x1A, 0x67,         //LD H,(DE)         ;...
  97.                             0x13,               //INC DE            ;...
  98.                             0x19,               //ADD HL,DE         ;Move HL to the end of the string
  99.                             0x36, 0x00          //LD (HL),0         ;Null-terminate it
  100.                             };
  101.     fwrite( getAnstoDE, 26, 1, a ); p += 26;
  102.  
  103.     fprintf( a, "%c%c%c%c%c%c",
  104.             0x21, 0xEC, 0x86,           //LD HL,86ECh       ;Jump back to the start of the safe RAM
  105.             0x01, 0x00, 0x00 ); p+=6;   //LD BC,0            ;Set the bounds checker to 0
  106.  
  107.     fprintf( a, "%c%c%c",
  108.             0xC3, (p+116)&0xFF,((p+116)>>8)&0xFF  //JP (After defs)   ;Skip the definition code
  109.              ); p += 3;
  110.     //Define <
  111.     int GoLeft = p;
  112.     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",
  113.             0xDD, 0xE1,     //POP IX
  114.             0xDD, 0x7E, 0,  //LD A,(IX+0)
  115.             0x3D,           //DEC A
  116.             0x32, (GoLeft+20)&0xFF, ((GoLeft+20)>>8)&0xFF, //LD (ArgSpot),A ;Set up arg for recursion
  117.             0xDD, 0x23,     //INC IX
  118.             0xDD, 0xE5,     //PUSH IX
  119.  
  120.             0xFE, 0x00,     //CP 0
  121.             0x28, 0x04,     //JR Z,4
  122.             0xCD, (GoLeft)&0xFF, (GoLeft>>8)&0xFF,      //CALL GoLeft
  123.             0x00,
  124.  
  125.             0x23,           //INC HL    ;Move the pointer forwards
  126.             0x03,           //INC BC    ;Increase the bounds checker
  127.             0x78,           //LD A,B    ;Move the Bounds Checker high byte to the Accumulator
  128.             0xFE, 0x03,     //CP 3      ;Check if we're at max
  129.             0x20, 0x06,     //JR NZ,6    ;If it is 3, then move the pointer back by 768
  130.             0x25,           //DEC H     ;...
  131.             0x25,           //DEC H     ;...
  132.             0x25,           //DEC H     ;...
  133.             0x01, 0x00,0x00,//LD BC,0   ;Reset the bounds checker
  134.  
  135.             0xC9            //RET
  136.              );p+=35;
  137.     //define >
  138.     int GoRight = p;
  139.         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",
  140.             0xDD, 0xE1,     //POP IX
  141.             0xDD, 0x7E, 0,  //LD A,(IX+0)
  142.             0x3D,           //DEC A
  143.             0x32, (GoRight+20)&0xFF, ((GoRight+20)>>8)&0xFF, //LD (ArgSpot),A ;Set up arg for recursion
  144.             0xDD, 0x23,     //INC IX
  145.             0xDD, 0xE5,     //PUSH IX
  146.  
  147.             0xFE, 0x00,     //CP 0
  148.             0x28, 0x04,     //JR Z,4
  149.             0xCD, (GoRight)&0xFF, (GoRight>>8)&0xFF,      //CALL GoRight
  150.             0x00,
  151.  
  152.             0x2B,           //DEC HL    ;Move the pointer backwards
  153.             0x0B,           //DEC BC    ;Decrease the bounds checker
  154.             0x78,           //LD A,B    ;Move the Bounds Checker high byte to the Accumulator
  155.             0xFE, 0xFF,     //CP FFh    ;Check if we're at -1
  156.             0x20, 0x06,     //JR NZ,6   ;If it is -1, then move the pointer forward by 768
  157.             0x24,           //INC H     ;...
  158.             0x24,           //INC H     ;...
  159.             0x24,           //INC H     ;...
  160.             0x01, 0xFF,0x02,//LD BC,02FFh ;Reset the bounds checker
  161.             0xC9            //RET
  162.              );p+=35;
  163.     //Define ,
  164.     int GetC = p;
  165.     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",
  166.                 0x1A,               //LD A,(DE)             ;Check if 0
  167.                 0xFE, 0x00,         //CP 0                  ;...
  168.                 0x28, 0x17,         //JR Z,23d               ;RET if so
  169.  
  170.                 0xE5,               //PUSH HL               ;Save the registers
  171.                 0xD5,               //PUSH DE               ;...
  172.                 0xC5,               //PUSH BC               ;...
  173.                 0xEB,               //EX DE,HL              ;Get the token into HL
  174.                 0xEF, 0x94, 0x45,   //B_CALL(Get_Tok_Strng) ;Get the token string
  175.                 0x3A, 0x8E, 0x84,   //LD A,(OP3)            ;Load tokstring[0] into A
  176.                 0xC1,               //POP BC                ;Reoad the registers
  177.                 0xD1,               //POP DE                ;...
  178.                 0xE1,               //POP HL                ;...
  179.                 0x77,               //LD (HL),A             ;Load the ASCII value into memory
  180.                 0x1A,               //LD A,(DE)             ;Load the token value into A
  181.                 0xEF, 0xA3, 0x42,   //B_CALL(IsA2ByteTok)   ;Check if it should skip 2 bytes
  182.                 0x20, 0x01,         //JR NZ,1                ;Skip one if no
  183.                 0x13,               //INC DE                ;Advance STDIN
  184.                 0x13,               //INC DE
  185.                 0xC9,               //RET
  186.                 0x77,               //LD (HL),A             ;Load the ASCII value into memory
  187.                 0xC9
  188.             );p+=30;
  189.     //Define OnCheck
  190.     int OnCheck = p;
  191.     fprintf( a, "%c%c%c%c%c%c%c%c%c%c%c%c%c",
  192.             0xFD, 0xCB, 0x09, 0x66, //BIT onInterrupt,(IY+onFLags)  ;Check if ON was pressed
  193.             0x28, 0x06,             //JR Z,6                        ;If not pressed, RET
  194.             0xDD, 0xE1,             //POP IX
  195.             0xFD, 0xCB, 0x09, 0xA6, //RES onInterrupt,(IY+onFlags)      ;reset On key flag
  196.             0xC9                    //RET
  197.             ); p += 13;
  198.     int arithtrack = 0;
  199.     int movtrack = 0;
  200.  
  201.  
  202.  
  203.     for( int i = 0; in[i] != 0; i ++ ){
  204.         switch( in[i] ){
  205.             case '+':{
  206.                 MHAN
  207.                 arithtrack++;
  208.                 }break;
  209.             case '-':{
  210.                 MHAN
  211.                 arithtrack--;
  212.                 }break;
  213.             case '>':{
  214.                 AHAN
  215.                 movtrack++;
  216.                 }break;
  217.             case '<':{
  218.                 AHAN
  219.                 movtrack--;
  220.                 }break;
  221.             case '[':
  222.             {
  223.                 AHAN
  224.                 MHAN
  225.                 s.push( p+6 );  //Track the location of this for jumping back
  226.                 int pp = p+6;     //Temp pointer
  227.                 int arithchange = 0;
  228.                 int movcnt = 0;
  229.                 int  depth = 1;
  230.                 for( int j = i+1; in[j] != 0; j++ ){     //Find the matching ']'
  231.                     if( in[j] == '[' ) depth ++;
  232.                     if( in[j] == ']' ) depth --;
  233.                     if( in[j] == '+' || in[j] == '-'){
  234.                         if( in[j] == '+' ) arithchange ++;
  235.                         if( in[j] == '-' ) arithchange --;
  236.                     }
  237.                     else{
  238.                         if( arithchange < 0 ) arithchange = - arithchange;
  239.                         if( arithchange >=4 ) pp += 4;
  240.                         else pp += arithchange;
  241.                         arithchange = 0;
  242.                     }
  243.                     if( in[j] == '<' || in[j] == '>' ){
  244.                         if( in[j] == '<' ) movcnt--;
  245.                         if( in[j] == '>' ) movcnt++;
  246.                         //pp += 3;
  247.                     }
  248.                     else if( movcnt != 0 ){
  249.                         if( movcnt < 0 ) movcnt = -movcnt;
  250.                         while( movcnt > 0 ){
  251.                             pp += 4;
  252.                             movcnt >>= 8;
  253.                         }
  254.                     }
  255.                     if( in[j] == '[' || in[j] == ']' ){
  256.                         pp+=9;
  257.                     }
  258.                     if( in[j] == '.'){
  259.                         pp+=4;
  260.                     }
  261.                     if( in[j] == ','){
  262.                         pp += 3;
  263.                     }
  264.                     if( depth <= 0 ) break;
  265.                 }
  266.                 if( depth > 0 ){ printf( "ERROR: Unmatched '[' at position %i\n", i); errors++; }
  267.                 fprintf( a, "%c%c%c%c%c%c%c%c%c",
  268.                         0xCD, OnCheck&0xff, (OnCheck>>8)&0xff,     //CALL OnCheck
  269.                         0x7E,                       //LD A,(HL)         ;Grab the byte at the pointer and jump to the matching ']' if zero
  270.                         0xFE, 0x00,                 //CP 0              ;...
  271.                         0xCA, pp&0xFF, (pp>>8)&0xFF //JP Z,(MATCHING ]) ;...
  272.                          ); p+=9;
  273.             } break;
  274.             case ']':
  275.             {
  276.                 AHAN
  277.                 MHAN
  278.                 if( s.size() > 0 ){
  279.                     int pp = s.top( );
  280.                     s.pop();
  281.                     fprintf( a, "%c%c%c%c%c%c%c%c%c",
  282.                             0xCD, OnCheck&0xff, (OnCheck>>8)&0xff,     //CALL OnCheck
  283.                             0x7E,                       //LD A,(HL)             ;Grab the byte at the pointer and jump to the matching '[' if not zero
  284.                             0xFE, 0x00,                 //CP 0                  ;...
  285.                             0xC2, pp&0xFF, (pp>>8)&0xFF //JP NZ,(MATCHING [)    ;...
  286.                             ); p+=9;
  287.                 }
  288.                 else {
  289.                     printf( "ERROR: Unmatched ']' at position %i\n", i);
  290.                     errors++;
  291.                 }
  292.             } break;
  293.             case '.':
  294.             {
  295.                 AHAN
  296.                 MHAN
  297.                 fprintf( a, "%c%c%c%c",
  298.                         0x7E,               //LD A,(HL)     ;Print the character being pointed at
  299.                         0xEF, 0x04, 0x45    //B_CALL(PutC)  ;...
  300.                         ); p+=4;
  301.             } break;
  302.             case ',':
  303.             {
  304.                 AHAN
  305.                 MHAN
  306.                 fprintf( a, "%c%c%c",
  307.                         0xCD, GetC&0xff, (GetC>>8)&0xff     //CALL GetC
  308.                         ); p += 3;
  309.             } break;
  310.         }
  311.     }
  312.     AHAN
  313.     MHAN
  314.     fprintf( a, "%c", 0xC9 ); p+=1; //RET   ;Return control to the TI-OS
  315.     fclose( a );
  316.     if( errors > 0 ){
  317.         a = fopen( "out.bin","wb" );
  318.         fprintf( a, "%c%c%c%c%c%c%c%c%cThere were      errors in this  program.%c%c",
  319.                 0xBB, 0x6D,         //.db BBh, 6Dh      ;Declare an ASM program
  320.                 0x21, 0x9C, 0x9D,   //LD HL,StringPos   ;Load the pointer of the message into HL
  321.                 0xEF, 0x0A, 0x45,   //B_CALL(PutS)      ;Print the string
  322.                 0xC9,                //RET
  323.                 0, 0
  324.                 );
  325.          fclose( a );
  326.     }
  327. }
  328.  
  329.  
Advertisement
Add Comment
Please, Sign In to add comment