Subversion Repositories pentevo

Rev

Blame | Last modification | View Log | Download | RSS feed | ?url?

  1. /* codevector.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS-Portierung                                                             */
  6. /*                                                                           */
  7. /* Codegenerator Atari Asteroids Vector Processor                            */
  8. /*                                                                           */
  9. /*****************************************************************************/
  10.  
  11. #include "stdinc.h"
  12. #include <stdio.h>
  13. #include <string.h>
  14. #include <ctype.h>
  15.  
  16. #include "nls.h"
  17. #include "strutil.h"
  18. #include "bpemu.h"
  19. #include "asmdef.h"
  20. #include "asmsub.h"
  21. #include "asmpars.h"
  22. #include "asmitree.h"
  23. #include "intpseudo.h"
  24. #include "codevars.h"
  25. #include "headids.h"
  26. #include "errmsg.h"
  27. #include "codepseudo.h"
  28.  
  29. #include "codevector.h"
  30.  
  31. static CPUVar CPUVector;
  32.  
  33. /*--------------------------------------------------------------------------
  34.  * Operand Parsers
  35.  *--------------------------------------------------------------------------*/
  36.  
  37. static Boolean Is4(const char *pAsc, Word *pResult)
  38. {
  39.   *pResult = 0;
  40.  
  41.   for (; *pAsc; pAsc++)
  42.   {
  43.     if (!isdigit(*pAsc))
  44.       return False;
  45.     *pResult = (*pResult * 10) + (*pAsc - '0');
  46.   }
  47.   return (*pResult <= 15);
  48. }
  49.  
  50. static Boolean DecodeScale(tStrComp *pArg, Word *pResult)
  51. {
  52.   Boolean OK;
  53.  
  54.   KillPrefBlanksStrComp(pArg);
  55.   KillPostBlanksStrComp(pArg);
  56.  
  57.   if ((toupper(*pArg->str.p_str) == 'S') && (Is4(pArg->str.p_str + 1, pResult)))
  58.     return True;
  59.  
  60.   *pResult = EvalStrIntExpression(pArg, UInt4, &OK);
  61.   return OK;
  62. }
  63.  
  64. static Boolean DecodeBright(tStrComp *pArg, Word *pResult)
  65. {
  66.   Boolean OK;
  67.  
  68.   KillPrefBlanksStrComp(pArg);
  69.   KillPostBlanksStrComp(pArg);
  70.  
  71.   if ((toupper(*pArg->str.p_str) == 'Z') && (Is4(pArg->str.p_str + 1, pResult)))
  72.     return True;
  73.  
  74.   *pResult = EvalStrIntExpression(pArg, UInt4, &OK);
  75.   return OK;
  76. }
  77.  
  78. static Boolean DecodeSign(tStrComp *pArg, Word *pResult, Boolean Signed)
  79. {
  80.   LongInt Val;
  81.   Boolean OK;
  82.   tSymbolFlags Flags;
  83.  
  84.   Val = EvalStrIntExpressionWithFlags(pArg, SInt16, &OK, &Flags);
  85.   if (!OK)
  86.     return False;
  87.  
  88.   if (mFirstPassUnknown(Flags))
  89.     Val = 0;
  90.  
  91.   if (!ChkRange(Val, Signed ? -1023 : 0, 1023))
  92.     return False;
  93.  
  94.   if ((Signed) && (Val < 0))
  95.     *pResult = (-Val) | (1 << 10);
  96.   else
  97.     *pResult = Val;
  98.   return True;
  99. }
  100.  
  101. static Boolean DecodeXY(tStrComp *pArg, Word *pX, Word *pY, Boolean Signed)
  102. {
  103.   tStrComp Tot, Left, Right;
  104.   char *pEnd, *pPos;
  105.  
  106.   KillPrefBlanksStrComp(pArg);
  107.   KillPostBlanksStrComp(pArg);
  108.  
  109.   if (*pArg->str.p_str != '(')
  110.   {
  111.     WrError(ErrNum_BrackErr);
  112.     return False;
  113.   }
  114.   StrCompRefRight(&Tot, pArg, 1);
  115.  
  116.   pEnd = Tot.str.p_str + strlen(Tot.str.p_str) - 1;
  117.   if (*pEnd != ')')
  118.   {
  119.     WrError(ErrNum_BrackErr);
  120.     return False;
  121.   }
  122.   *pEnd = '\0';
  123.   Tot.Pos.Len--;
  124.  
  125.   pPos = strchr(Tot.str.p_str, ',');
  126.   if (!pPos)
  127.   {
  128.     WrError(ErrNum_UseLessAttr);
  129.     return False;
  130.   }
  131.   StrCompSplitRef(&Left, &Right, &Tot, pPos);
  132.  
  133.   if (!DecodeSign(&Left, pX, Signed))
  134.     return False;
  135.   if (!DecodeSign(&Right, pY, Signed))
  136.     return False;
  137.  
  138.   return True;
  139. }
  140.  
  141. /*--------------------------------------------------------------------------
  142.  * Code Handlers
  143.  *--------------------------------------------------------------------------*/
  144.  
  145. static void DecodeFixed(Word Index)
  146. {
  147.   if (ChkArgCnt(0, 0))
  148.   {
  149.     WAsmCode[0] = Index;
  150.     CodeLen = 1;
  151.   }
  152. }
  153.  
  154. static void DecodeJmp(Word Index)
  155. {
  156.   Boolean OK;
  157.  
  158.   if (ChkArgCnt(1, 1))
  159.   {
  160.     WAsmCode[0] = Index | EvalStrIntExpression(&ArgStr[1], UInt12, &OK);
  161.     if (OK)
  162.       CodeLen = 1;
  163.   }
  164. }
  165.  
  166. static void DecodeLAbs(Word Index)
  167. {
  168.   Word X, Y, Scale;
  169.  
  170.   UNUSED(Index);
  171.  
  172.   if (!ChkArgCnt(2, 2));
  173.   else if (!DecodeXY(&ArgStr[1], &X, &Y, False));
  174.   else if (!DecodeScale(&ArgStr[2], &Scale));
  175.   else
  176.   {
  177.     WAsmCode[0] = 0xa000 | Y;
  178.     WAsmCode[1] = (Scale << 12) | X;
  179.     CodeLen = 2;
  180.   }
  181. }
  182.  
  183. static void DecodeVctr(Word Index)
  184. {
  185.   Word X, Y, Scale, Bright;
  186.  
  187.   UNUSED(Index);
  188.  
  189.   if (!ChkArgCnt(3, 3));
  190.   else if (!DecodeXY(&ArgStr[1], &X, &Y, True));
  191.   else if (!DecodeScale(&ArgStr[2], &Scale));
  192.   else if (!DecodeBright(&ArgStr[3], &Bright));
  193.   else
  194.   {
  195.     WAsmCode[0] = (Scale << 12) | Y;
  196.     WAsmCode[1] = (Bright << 12) | X;
  197.     CodeLen = 2;
  198.   }
  199. }
  200.  
  201. static void DecodeSVec(Word Index)
  202. {
  203.   Word X, Y, Scale, Bright;
  204.  
  205.   UNUSED(Index);
  206.  
  207.   if (!ChkArgCnt(3, 3));
  208.   else if (!DecodeXY(&ArgStr[1], &X, &Y, True));
  209.   else if ((X & 0xff) || (Y & 0xff)) WrError(ErrNum_NotAligned);
  210.   else if (!DecodeScale(&ArgStr[2], &Scale));
  211.   else if (Scale > 3) WrError(ErrNum_OverRange);
  212.   else if (!DecodeBright(&ArgStr[3], &Bright));
  213.   else
  214.   {
  215.     WAsmCode[0] = 0xf000
  216.                 | (Bright << 4)
  217.                 | ((X >> 8) & 3)
  218.                 | (Y & 0x300)
  219.                 | ((Scale & 1) << 11)
  220.                 | ((Scale & 2) << 2);
  221.     CodeLen = 1;
  222.   }
  223. }
  224.  
  225. /*--------------------------------------------------------------------------
  226.  * Instruction Table Handling
  227.  *--------------------------------------------------------------------------*/
  228.  
  229. static void InitFields(void)
  230. {
  231.   InstTable = CreateInstTable(17);
  232.  
  233.   AddInstTable(InstTable, "RTSL", 0xd000, DecodeFixed);
  234.   AddInstTable(InstTable, "HALT", 0xb0b0, DecodeFixed);
  235.  
  236.   AddInstTable(InstTable, "JMPL", 0xe000, DecodeJmp);
  237.   AddInstTable(InstTable, "JSRL", 0xc000, DecodeJmp);
  238.  
  239.   AddInstTable(InstTable, "LABS", 0x0000, DecodeLAbs);
  240.   AddInstTable(InstTable, "VCTR", 0x0000, DecodeVctr);
  241.   AddInstTable(InstTable, "SVEC", 0x0000, DecodeSVec);
  242. }
  243.  
  244. static void DeinitFields(void)
  245. {
  246.   DestroyInstTable(InstTable);
  247. }
  248.  
  249. /*--------------------------------------------------------------------------
  250.  * Semipublic Functions
  251.  *--------------------------------------------------------------------------*/
  252.  
  253. static Boolean IsDef_Vector(void)
  254. {
  255.   return FALSE;
  256. }
  257.  
  258. static void SwitchFrom_Vector(void)
  259. {
  260.   DeinitFields();
  261. }
  262.  
  263. static void MakeCode_Vector(void)
  264. {
  265.   CodeLen = 0; DontPrint = False;
  266.  
  267.   /* zu ignorierendes */
  268.  
  269.   if (Memo("")) return;
  270.  
  271.   if (!LookupInstTable(InstTable, OpPart.str.p_str))
  272.     WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
  273. }
  274.  
  275. static void SwitchTo_Vector(void)
  276. {
  277.   const TFamilyDescr *FoundDescr;
  278.  
  279.   FoundDescr = FindFamilyByName("ATARI_VECTOR");
  280.  
  281.   TurnWords = False;
  282.   SetIntConstMode(eIntConstModeMoto);
  283.  
  284.   PCSymbol = "$"; HeaderID = FoundDescr->Id;
  285.  
  286.   /* NOP = ??? */
  287.  
  288.   NOPCode = 0x00000;
  289.   DivideChars = ","; HasAttrs = False;
  290.  
  291.   ValidSegs = (1 << SegCode);
  292.   Grans[SegCode] = 2; ListGrans[SegCode] = 2; SegInits[SegCode] = 0;
  293.   SegLimits[SegCode] = 0xfff;
  294.  
  295.   MakeCode = MakeCode_Vector; IsDef = IsDef_Vector;
  296.   SwitchFrom = SwitchFrom_Vector; InitFields();
  297. }
  298.  
  299. /*--------------------------------------------------------------------------
  300.  * Initialization
  301.  *--------------------------------------------------------------------------*/
  302.  
  303. void codevector_init(void)
  304. {
  305.   CPUVector = AddCPU("ATARI_VECTOR", SwitchTo_Vector);
  306. }
  307.