home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / nasm097s.zip / INSNS.BAS < prev    next >
BASIC Source File  |  1997-10-01  |  14KB  |  536 lines

  1. ' INFO_1: Converter for INSNS.DAT to INSNSA.C and INSNSD.C
  2. '
  3. ' INFO_2: Written by Mark Junker in 1997
  4. '         InterNet: mjs@prg.hannover.sgh-net.de
  5. '         FIDO:     Mark Junker@2:2437/47.21
  6. '
  7. ' COMMENT: While I wrote this program I often asked me, if it isn't easier
  8. '          to write an interpreter for pearl-scripts :]
  9. '
  10. ' COMMENT: To start the program press SHIFT+F5 within the QBasic IDE
  11. '          or start it from the command-line with QBASIC /RUN MACROS
  12. '
  13.  
  14. DEFINT A-Z
  15.  
  16. DECLARE FUNCTION ReplaceOp$ (a$)
  17. DECLARE FUNCTION StrTrimLeft$ (a$, b$)
  18. DECLARE FUNCTION StrTrimRight$ (a$, b$)
  19. DECLARE FUNCTION StrTrim$ (a$, b$)
  20. DECLARE SUB StrSplitString (SplitString$, SplitChars$, SplitField$(), SplitCount%)
  21. DECLARE FUNCTION Min% (a%, b%)
  22. DECLARE FUNCTION StrInstrLeft% (SearchStart%, SearchIn$, SearchFor$)
  23. DECLARE FUNCTION StrAscii% (a$)
  24.  
  25.  
  26. CONST MaxOpCodeBase = 3
  27. CONST MaxOpCodeType = 8
  28.  
  29. CLS
  30. DIM LineData$(1 TO 2)
  31. DIM StrucData$(1 TO 5)
  32. DIM OpCodeList$(0 TO 255)
  33. DIM OpCodeByte(1 TO MaxOpCodeType, 1 TO MaxOpCodeBase)
  34. DIM OpCodeStat(1 TO 10)   ' don't need mode :)
  35.  
  36. Instructs$ = ""
  37. LineOfs$ = ""
  38.  
  39. OPEN "I", 1, "insns.dat"
  40. OPEN "B", 3, "insns.tmp"
  41.  
  42. qt$ = CHR$(34)
  43. crlf$ = CHR$(13) + CHR$(10)
  44.  
  45.  
  46. '
  47. ' preprocessing the current file
  48. '
  49.  
  50. HexChar$ = "0123456789ABCDEF"
  51.  
  52. PRINT "Preprocessing INSNS.DAT"
  53. OpCodes = 0
  54. OpCodeDebug = 0
  55. NowLineOfs& = 1
  56. lineNr = 0
  57. WHILE NOT EOF(1)
  58.   lineNr = lineNr + 1
  59.   IF (lineNr AND 15) = 0 THEN
  60.     LOCATE , 1
  61.     PRINT lineNr, OpCodes, OpCodeDebug;
  62.   END IF
  63.  
  64.   LINE INPUT #1, l$
  65.   CALL StrSplitString(l$, ";", LineData$(), SplitCount)
  66.   IF SplitCount THEN
  67.     LineData$(1) = StrTrim$(LineData$(1), CHR$(9) + " ")
  68.     IF LEN(LineData$(1)) THEN
  69.       CALL StrSplitString(LineData$(1), " ", StrucData$(), cntSplit)
  70.       IF cntSplit <> 4 THEN
  71.         PRINT "line"; lineNr; " does not contain four fields"
  72.         END
  73.       END IF
  74.  
  75.       tst$ = UCASE$(StrucData$(2))
  76.       res$ = ""
  77.       cnt% = 1
  78.       isfirst = 1
  79.       op = 1
  80.       p = StrInstrLeft(1, tst$ + ",", "|:,")
  81.       WHILE p
  82.         h$ = ReplaceOp$(MID$(tst$, op, p - op))
  83.         IF LEN(h$) THEN
  84.           SELECT CASE MID$(tst$, p, 1)
  85.           CASE ""
  86.             IF isfirst THEN
  87.               res$ = res$ + h$
  88.             ELSE
  89.               res$ = res$ + "|" + h$
  90.             END IF
  91.             isfirst = 0
  92.           CASE ","
  93.             IF isfirst THEN
  94.               res$ = res$ + h$ + ","
  95.             ELSE
  96.               res$ = res$ + "|" + h$ + ","
  97.             END IF
  98.             cnt% = cnt% + 1
  99.             isfirst = 1
  100.           CASE "|"
  101.             IF isfirst THEN
  102.               res$ = res$ + h$
  103.             ELSE
  104.               res$ = res$ + "|" + h$
  105.             END IF
  106.             isfirst = 0
  107.           CASE ":"
  108.             res$ = res$ + h$ + "|COLON,"
  109.             cnt% = cnt% + 1
  110.           END SELECT
  111.         END IF
  112.         op = p + 1
  113.         p = StrInstrLeft(op, tst$ + ",", "|:,")
  114.       WEND
  115.       FOR a = cnt% + 1 TO 3
  116.         res$ = res$ + ",0"
  117.       NEXT
  118.       StrucData$(2) = res$
  119.       IF LEFT$(res$, 2) = "0," THEN cnt% = cnt% - 1
  120.       StrucData$(5) = LTRIM$(STR$(cnt%))
  121.  
  122.       NoDebug = 0
  123.       res$ = ""
  124.       tst$ = UCASE$(StrucData$(4))
  125.       op = 1
  126.       p = INSTR(tst$ + ",", ",")
  127.       isfirst = 1
  128.       WHILE p
  129.         h$ = MID$(tst$, op, p - op)
  130.         IF h$ = "ND" THEN
  131.           NoDebug = 1
  132.         ELSE
  133.           IF isfirst THEN
  134.             res$ = res$ + "IF_" + h$
  135.           ELSE
  136.             res$ = res$ + "|IF_" + h$
  137.           END IF
  138.           isfirst = 0
  139.         END IF
  140.         op = p + 1
  141.         p = INSTR(op, tst$ + ",", ",")
  142.       WEND
  143.       StrucData$(4) = res$
  144.  
  145.       tst$ = UCASE$(StrucData$(3))
  146.       SELECT CASE tst$
  147.       CASE "IGNORE"
  148.         GOTO skipOpCode
  149.       CASE "\0", "\340"
  150.         OpCodeDebug = OpCodeDebug + 1    ' don't forget to increment
  151.         GOTO skipOpCode
  152.       END SELECT
  153.  
  154.       AddRegs = 0
  155.       AddCCode = 0
  156.       NextIsOpCode = 0
  157.       opCodeVal$ = ""
  158.       op = 1
  159.       p = INSTR(tst$ + "\", "\")
  160.       DO WHILE p
  161.         h$ = MID$(tst$, op, p - op)
  162.         IF LEFT$(h$, 1) = "X" THEN
  163.           opCodeVal$ = CHR$(VAL("&H" + MID$(h$, 2)))
  164.           EXIT DO
  165.         ELSE
  166.           SELECT CASE h$
  167.           CASE "1", "2", "3"
  168.             NextIsOpCode = 1
  169.           CASE "4"
  170.             opCodeVal$ = CHR$(&H7) + CHR$(&H17) + CHR$(&H1F)
  171.             EXIT DO
  172.           CASE "5"
  173.             opCodeVal$ = CHR$(&HA1) + CHR$(&HA9)
  174.             EXIT DO
  175.           CASE "6"
  176.             opCodeVal$ = CHR$(&H6) + CHR$(&HE) + CHR$(&H16) + CHR$(&H1E)
  177.             EXIT DO
  178.           CASE "7"
  179.             opCodeVal$ = CHR$(&HA0) + CHR$(&HA8)
  180.             EXIT DO
  181.           CASE "10", "11", "12"
  182.             NextIsOpCode = 1
  183.             AddRegs = VAL(h$) - 9
  184.           CASE "330"
  185.             NextIsOpCode = 1
  186.             AddCCode = VAL(h$) - 329
  187.           CASE "17"
  188.             opCodeVal$ = CHR$(0)
  189.             EXIT DO
  190.           CASE ELSE
  191.             IF NextIsOpCode THEN
  192.               PRINT "Line:"; lineNr
  193.               PRINT "Unknown value: " + h$
  194.               END
  195.             END IF
  196.           END SELECT
  197.         END IF
  198.         op = p + 1
  199.         p = INSTR(op, tst$ + "\", "\")
  200.       LOOP
  201.       IF (p = 0) THEN
  202.         PRINT "No opcode found in line"; lineNr
  203.         PRINT "Line:"
  204.         PRINT l$
  205.         END
  206.       END IF
  207.  
  208.       IF NoDebug = 0 THEN
  209.         FOR a = 1 TO LEN(opCodeVal$)
  210.           h = ASC(MID$(opCodeVal$, a, 1))
  211.           OpCodeStr$ = MKI$(OpCodeDebug)
  212.           IF AddRegs THEN
  213.             EndNr = 7
  214.           ELSEIF AddCCode THEN
  215.             EndNr = 15
  216.           ELSE
  217.             EndNr = 0
  218.           END IF
  219.           FOR b = 0 TO EndNr
  220.             OpCodeList$(h + b) = OpCodeList$(h + b) + OpCodeStr$
  221.           NEXT
  222.         NEXT
  223.         OpCodeDebug = OpCodeDebug + 1
  224.       END IF
  225.  
  226. skipOpCode:
  227.       OpCodes = OpCodes + 1
  228.       LineOfs$ = LineOfs$ + MKL$(NowLineOfs&)
  229.       LineLg = 1
  230.       h$ = CHR$(NoDebug)
  231.       PUT #3, NowLineOfs&, h$
  232.       NowLineOfs& = NowLineOfs& + 1
  233.       FOR a = 1 TO 5
  234.         lg = LEN(StrucData$(a))
  235.         h$ = CHR$(lg) + StrucData$(a)
  236.         PUT #3, NowLineOfs&, h$
  237.         NowLineOfs& = NowLineOfs& + lg + 1
  238.         LineLg = LineLg + lg + 1
  239.       NEXT
  240.       LineOfs$ = LineOfs$ + MKI$(LineLg)
  241.     END IF
  242.   END IF
  243. WEND
  244. LOCATE , 1
  245. PRINT lineNr, OpCodes, OpCodeDebug
  246.  
  247.  
  248. '
  249. ' creating insnsa.c
  250. '
  251.  
  252.  
  253. PRINT "Creating INSNSA.C"
  254.  
  255. OPEN "O", 2, "insnsa.c"
  256. strBegStart$ = "static struct itemplate instrux_"
  257. strBegEnd$ = "[] = {"
  258. strEnd$ = "    {-1}" + crlf$ + "};" + crlf$
  259.  
  260. PRINT #2, "/* This file auto-generated from insns.dat by insns.bas - don't edit it */"
  261. PRINT #2, ""
  262. PRINT #2, "#include <stdio.h>"
  263. PRINT #2, "#include " + qt$ + "nasm.h" + qt$
  264. PRINT #2, "#include " + qt$ + "insns.h" + qt$
  265. PRINT #2, ""
  266.  
  267. oldOpCode$ = ""
  268. pOfs = 1
  269. FOR a = 1 TO OpCodes
  270.   LineOfs& = CVL(MID$(LineOfs$, pOfs, 4))
  271.   l$ = SPACE$(CVI(MID$(LineOfs$, pOfs + 4, 2)))
  272.   pOfs = pOfs + 6
  273.   GET #3, LineOfs&, l$
  274.  
  275.   ' split data into fields
  276.   NoDebug = ASC(LEFT$(l$, 1))
  277.   pLn = 2
  278.   FOR b = 1 TO 5
  279.     lgLn = ASC(MID$(l$, pLn, 1))
  280.     StrucData$(b) = MID$(l$, pLn + 1, lgLn)
  281.     pLn = pLn + lgLn + 1
  282.   NEXT
  283.  
  284.   IF oldOpCode$ <> StrucData$(1) THEN
  285.     Instructs$ = Instructs$ + StrucData$(1) + CHR$(0)
  286.     IF LEN(oldOpCode$) THEN PRINT #2, strEnd$
  287.     PRINT #2, strBegStart$ + StrucData$(1) + strBegEnd$
  288.     oldOpCode$ = StrucData$(1)
  289.   END IF
  290.   SELECT CASE UCASE$(StrucData$(3))
  291.   CASE "IGNORE"
  292.   CASE ELSE
  293.     PRINT #2, "    {I_" + oldOpCode$ + ", " + StrucData$(5) + ", {" + StrucData$(2) + "}, " + qt$ + StrucData$(3) + qt$ + ", " + StrucData$(4) + "},"
  294.   END SELECT
  295. NEXT
  296. IF LEN(oldOpCode$) THEN PRINT #2, strEnd$
  297.  
  298. PRINT #2, "struct itemplate *nasm_instructions[] = {"
  299. op = 1
  300. p = INSTR(Instructs$, CHR$(0))
  301. WHILE p
  302.   h$ = MID$(Instructs$, op, p - op)
  303.   PRINT #2, "    instrux_" + h$ + ","
  304.   op = p + 1
  305.   p = INSTR(op, Instructs$, CHR$(0))
  306. WEND
  307. PRINT #2, "};"
  308.  
  309. CLOSE 2
  310.  
  311.  
  312.  
  313. '
  314. ' creating insnsd.c
  315. '
  316.  
  317.  
  318. PRINT "Creating INSNSD.C"
  319.  
  320. OPEN "O", 2, "insnsd.c"
  321.  
  322. PRINT #2, "/* This file auto-generated from insns.dat by insns.bas - don't edit it */"
  323. PRINT #2, ""
  324. PRINT #2, "#include <stdio.h>"
  325. PRINT #2, "#include " + qt$ + "nasm.h" + qt$
  326. PRINT #2, "#include " + qt$ + "insns.h" + qt$
  327. PRINT #2, ""
  328.  
  329.  
  330. PRINT #2, "static struct itemplate instrux[] = {"
  331. pOfs = 1
  332. FOR a = 1 TO OpCodes
  333.   LineOfs& = CVL(MID$(LineOfs$, pOfs, 4))
  334.   l$ = SPACE$(CVI(MID$(LineOfs$, pOfs + 4, 2)))
  335.   pOfs = pOfs + 6
  336.   GET #3, LineOfs&, l$
  337.  
  338.   ' split data into fields
  339.   NoDebug = ASC(LEFT$(l$, 1))
  340.   pLn = 2
  341.   FOR b = 1 TO 5
  342.     lgLn = ASC(MID$(l$, pLn, 1))
  343.     StrucData$(b) = MID$(l$, pLn + 1, lgLn)
  344.     pLn = pLn + lgLn + 1
  345.   NEXT
  346.  
  347.   IF NoDebug OR (UCASE$(StrucData$(3)) = "IGNORE") THEN
  348.     ' ignorieren
  349.   ELSE
  350.     PRINT #2, "    {I_" + StrucData$(1) + ", " + StrucData$(5) + ", {" + StrucData$(2) + "}, " + qt$ + StrucData$(3) + qt$ + ", " + StrucData$(4) + "},"
  351.   END IF
  352. NEXT
  353. PRINT #2, "    {-1}" + crlf$ + "};" + crlf$
  354.  
  355.  
  356. OpCodeBegS$ = "static struct itemplate *itable_"
  357. OpCodeBegE$ = "[] = {"
  358. OpCodeEnd$ = "    NULL" + crlf$ + "};" + crlf$
  359.  
  360. FOR a = 0 TO 255
  361.   PRINT #2, OpCodeBegS$ + RIGHT$("00" + HEX$(a), 2) + OpCodeBegE$
  362.   h$ = OpCodeList$(a)
  363.   FOR b = 1 TO LEN(h$) STEP 2
  364.     OpCodePos = CVI(MID$(h$, b, 2))
  365.     PRINT #2, "    instrux +" + STR$(OpCodePos) + ","
  366.   NEXT
  367.   PRINT #2, OpCodeEnd$
  368. NEXT
  369.  
  370. PRINT #2, "struct itemplate **itable[] = {"
  371. FOR a = 0 TO 255
  372.   PRINT #2, "    itable_" + RIGHT$("00" + HEX$(a), 2) + ","
  373. NEXT
  374. PRINT #2, "};"
  375.  
  376. CLOSE 2
  377.  
  378.  
  379.  
  380. CLOSE 3
  381. KILL "insns.tmp"
  382. CLOSE 1
  383. SYSTEM
  384.  
  385. FUNCTION ReplaceOp$ (a$)
  386.   tst$ = UCASE$(a$)
  387.   SELECT CASE tst$
  388. '  CASE "ND"
  389. '    ReplaceOp$ = ""
  390.   CASE "VOID", ""
  391.     ReplaceOp$ = "0"
  392.   CASE "IMM"
  393.     ReplaceOp$ = "IMMEDIATE"
  394.   CASE "MEM"
  395.     ReplaceOp$ = "MEMORY"
  396.   CASE "MEM8", "MEM16", "MEM32", "MEM64", "MEM80"
  397.     ReplaceOp$ = "MEMORY|BITS" + MID$(tst$, 4)
  398.   CASE "REG8", "REG16", "REG32"
  399.     ReplaceOp$ = tst$
  400.   CASE "RM8", "RM16", "RM32"
  401.     ReplaceOp$ = "REGMEM|BITS" + MID$(tst$, 3)
  402.   CASE "IMM8", "IMM16", "IMM32"
  403.     ReplaceOp$ = "IMMEDIATE|BITS" + MID$(tst$, 4)
  404.   CASE ELSE
  405.     ReplaceOp$ = tst$
  406.   END SELECT
  407. END FUNCTION
  408.  
  409. FUNCTION Min% (a%, b%)
  410.   IF a% < b% THEN Min% = a% ELSE Min% = b%
  411. END FUNCTION
  412.  
  413. FUNCTION StrAscii (a$)
  414.   IF LEN(a$) = 0 THEN
  415.     StrAscii = -1
  416.   ELSE
  417.     StrAscii = ASC(a$)
  418.   END IF
  419. END FUNCTION
  420.  
  421. ' same as =INSTR(SearchStart, SearchIn, ANY SearchFor$) in PowerBASIC(tm)
  422. '
  423. FUNCTION StrInstrLeft (SearchStart, SearchIn$, SearchFor$)
  424.  ValuesCount = LEN(SearchFor$)
  425.  MaxValue = LEN(SearchIn$) + 1
  426.  MinValue = MaxValue
  427.  FOR Counter1 = 1 TO ValuesCount
  428.   SearchChar$ = MID$(SearchFor$, Counter1, 1)
  429.   hVal2 = INSTR(SearchStart, SearchIn$, SearchChar$)
  430.   IF hVal2 > 0 THEN MinValue = Min%(hVal2, MinValue)
  431.  NEXT
  432.  IF MinValue = MaxValue THEN MinValue = 0
  433.  StrInstrLeft = MinValue
  434. END FUNCTION
  435.  
  436. '
  437. ' This is a very damn fuckin' shit version of this splitting routine.
  438. ' At this time, it's not very useful :]
  439. '
  440. SUB StrSplitString (SplitString$, SplitChars$, SplitField$(), SplitCount)
  441.   StartIndex = LBOUND(SplitField$)
  442.   LastIndex = UBOUND(SplitField$)
  443.   ActualIndex& = StartIndex
  444.   SplitCount = 0
  445.  
  446.   LastPos = 1
  447.   FoundPos = StrInstrLeft(LastPos, SplitString$, SplitChars$ + CHR$(34))
  448.   GetDirect = 0
  449.   EndLoop = 0
  450.   TempString$ = ""
  451.   DO WHILE FoundPos > 0
  452.     FoundCharVal = StrAscii(MID$(SplitString$, FoundPos, 1))
  453.     PosDiff = (FoundPos - LastPos) + 1
  454.     SELECT CASE FoundCharVal
  455.     CASE 34
  456.       TempString$ = TempString$ + MID$(SplitString$, LastPos, PosDiff - 1)
  457.       SELECT CASE EndLoop
  458.       CASE 0
  459.         EndLoop = 2
  460.       CASE 3
  461.         EndLoop = 0
  462.       END SELECT
  463.     CASE ELSE
  464.       TempString$ = TempString$ + MID$(SplitString$, LastPos, PosDiff - 1)
  465.       SplitField$(ActualIndex&) = TempString$
  466.       TempString$ = ""
  467.       ActualIndex& = ActualIndex& + 1
  468.       IF ActualIndex& > LastIndex THEN
  469.         ActualIndex& = LastIndex
  470.         EndLoop = 1
  471.       END IF
  472.     END SELECT
  473.     SELECT CASE EndLoop
  474.     CASE 0
  475.       DO
  476.         LastPos = FoundPos + 1
  477.         FoundPos = StrInstrLeft(LastPos, SplitString$, SplitChars$)
  478.       LOOP WHILE LastPos = FoundPos
  479.       FoundPos = StrInstrLeft(LastPos, SplitString$, SplitChars$ + CHR$(34))
  480.     CASE 1
  481.       FoundPos = 0
  482.       LastPos = LEN(SplitString$) + 1
  483.     CASE 2
  484.       EndLoop = 3
  485.       LastPos = FoundPos + 1
  486.       FoundPos = StrInstrLeft(LastPos, SplitString$, CHR$(34))
  487.       IF FoundPos = 0 THEN
  488.        SplitString$ = SplitString$ + CHR$(34)
  489.        FoundPos = LEN(SplitString$)
  490.       END IF
  491.     END SELECT
  492.   LOOP
  493.   IF EndLoop = 0 THEN
  494.     IF LEN(TempString$) > 0 THEN
  495.       SplitField$(ActualIndex&) = TempString$
  496.     ELSEIF LastPos <= LEN(SplitString$) THEN
  497.       SplitField$(ActualIndex&) = MID$(SplitString$, LastPos)
  498.     ELSE
  499.       ActualIndex& = ActualIndex& - 1
  500.     END IF
  501.   END IF
  502.   FOR a = ActualIndex& + 1 TO LastIndex
  503.     SplitField$(a) = ""
  504.   NEXT
  505.   SplitCount = (ActualIndex& - StartIndex) + 1
  506. END SUB
  507.  
  508. FUNCTION StrTrim$ (a$, b$)
  509.         StrTrim$ = StrTrimRight$(StrTrimLeft$(a$, b$), b$)
  510. END FUNCTION
  511.  
  512. FUNCTION StrTrimLeft$ (a$, b$) 'public
  513.         p = 0
  514.         l = LEN(a$)
  515.         DO
  516.           p = p + 1
  517.           t$ = MID$(a$, p, 1)
  518.         LOOP WHILE (p < l) AND (INSTR(b$, t$) > 0)
  519.         StrTrimLeft$ = MID$(a$, p)
  520. END FUNCTION
  521.  
  522. FUNCTION StrTrimRight$ (a$, b$) 'public
  523.         l = LEN(a$)
  524.         p = l + 1
  525.         DO
  526.           p = p - 1
  527.           IF p > 0 THEN
  528.             t$ = MID$(a$, p, 1)
  529.           ELSE
  530.             t$ = ""
  531.           END IF
  532.         LOOP WHILE (p > 0) AND (INSTR(b$, t$) > 0)
  533.         StrTrimRight$ = LEFT$(a$, p)
  534. END FUNCTION
  535.  
  536.