1 ' INFO_1: Converter for INSNS.DAT to INSNSA.C and INSNSD.C
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
7 ' COMMENT: While I wrote this program I often asked me, if it isn't easier
8 ' to write an interpreter for Perl-scripts :]
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
14 ' THIS PROGRAM NEEDS TO BE UPDATED -- it doesn't create insnsi.h
15 ' and insnsn.c. However, Perl interpreters are now available for both
16 ' DOS and Windows, so it seems pointless to spend the effort.
21 DECLARE FUNCTION ReplaceOp$ (a$)
22 DECLARE FUNCTION StrTrimLeft$ (a$, b$)
23 DECLARE FUNCTION StrTrimRight$ (a$, b$)
24 DECLARE FUNCTION StrTrim$ (a$, b$)
25 DECLARE SUB StrSplitString (SplitString$, SplitChars$, SplitField$(), SplitCount%)
26 DECLARE FUNCTION Min% (a%, b%)
27 DECLARE FUNCTION StrInstrLeft% (SearchStart%, SearchIn$, SearchFor$)
28 DECLARE FUNCTION StrAscii% (a$)
31 CONST MaxOpCodeBase = 3
32 CONST MaxOpCodeType = 8
36 DIM StrucData$(1 TO 5)
37 DIM OpCodeList$(0 TO 255)
38 DIM OpCodeByte(1 TO MaxOpCodeType, 1 TO MaxOpCodeBase)
39 DIM OpCodeStat(1 TO 10) ' don't need mode :)
44 OPEN "I", 1, "insns.dat"
45 OPEN "B", 3, "insns.tmp"
48 crlf$ = CHR$(13) + CHR$(10)
52 ' preprocessing the current file
55 HexChar$ = "0123456789ABCDEF"
57 PRINT "Preprocessing INSNS.DAT"
64 IF (lineNr AND 15) = 0 THEN
66 PRINT lineNr, OpCodes, OpCodeDebug;
70 CALL StrSplitString(l$, ";", LineData$(), SplitCount)
72 LineData$(1) = StrTrim$(LineData$(1), CHR$(9) + " ")
73 IF LEN(LineData$(1)) THEN
74 CALL StrSplitString(LineData$(1), " ", StrucData$(), cntSplit)
76 PRINT "line"; lineNr; " does not contain four fields"
80 tst$ = UCASE$(StrucData$(2))
85 p = StrInstrLeft(1, tst$ + ",", "|:,")
87 h$ = ReplaceOp$(MID$(tst$, op, p - op))
89 SELECT CASE MID$(tst$, p, 1)
94 res$ = res$ + "|" + h$
99 res$ = res$ + h$ + ","
101 res$ = res$ + "|" + h$ + ","
109 res$ = res$ + "|" + h$
113 res$ = res$ + h$ + "|COLON,"
118 p = StrInstrLeft(op, tst$ + ",", "|:,")
120 FOR a = cnt% + 1 TO 3
124 IF LEFT$(res$, 2) = "0," THEN cnt% = cnt% - 1
125 StrucData$(5) = LTRIM$(STR$(cnt%))
129 tst$ = UCASE$(StrucData$(4))
131 p = INSTR(tst$ + ",", ",")
134 h$ = MID$(tst$, op, p - op)
139 res$ = res$ + "IF_" + h$
141 res$ = res$ + "|IF_" + h$
146 p = INSTR(op, tst$ + ",", ",")
150 tst$ = UCASE$(StrucData$(3))
155 OpCodeDebug = OpCodeDebug + 1 ' don't forget to increment
164 p = INSTR(tst$ + "\", "\")
166 h$ = MID$(tst$, op, p - op)
167 IF LEFT$(h$, 1) = "X" THEN
168 opCodeVal$ = CHR$(VAL("&H" + MID$(h$, 2)))
175 opCodeVal$ = CHR$(&H7) + CHR$(&H17) + CHR$(&H1F)
178 opCodeVal$ = CHR$(&HA1) + CHR$(&HA9)
181 opCodeVal$ = CHR$(&H6) + CHR$(&HE) + CHR$(&H16) + CHR$(&H1E)
184 opCodeVal$ = CHR$(&HA0) + CHR$(&HA8)
186 CASE "10", "11", "12"
188 AddRegs = VAL(h$) - 9
191 AddCCode = VAL(h$) - 329
197 PRINT "Line:"; lineNr
198 PRINT "Unknown value: " + h$
204 p = INSTR(op, tst$ + "\", "\")
207 PRINT "No opcode found in line"; lineNr
214 FOR a = 1 TO LEN(opCodeVal$)
215 h = ASC(MID$(opCodeVal$, a, 1))
216 OpCodeStr$ = MKI$(OpCodeDebug)
225 OpCodeList$(h + b) = OpCodeList$(h + b) + OpCodeStr$
228 OpCodeDebug = OpCodeDebug + 1
232 OpCodes = OpCodes + 1
233 LineOfs$ = LineOfs$ + MKL$(NowLineOfs&)
236 PUT #3, NowLineOfs&, h$
237 NowLineOfs& = NowLineOfs& + 1
239 lg = LEN(StrucData$(a))
240 h$ = CHR$(lg) + StrucData$(a)
241 PUT #3, NowLineOfs&, h$
242 NowLineOfs& = NowLineOfs& + lg + 1
243 LineLg = LineLg + lg + 1
245 LineOfs$ = LineOfs$ + MKI$(LineLg)
250 PRINT lineNr, OpCodes, OpCodeDebug
258 PRINT "Creating INSNSA.C"
260 OPEN "O", 2, "insnsa.c"
261 strBegStart$ = "static struct itemplate instrux_"
262 strBegEnd$ = "[] = {"
263 strEnd$ = " {-1}" + crlf$ + "};" + crlf$
265 PRINT #2, "/* This file auto-generated from insns.dat by insns.bas - don't edit it */"
267 PRINT #2, "#include <stdio.h>"
268 PRINT #2, "#include " + qt$ + "nasm.h" + qt$
269 PRINT #2, "#include " + qt$ + "insns.h" + qt$
275 LineOfs& = CVL(MID$(LineOfs$, pOfs, 4))
276 l$ = SPACE$(CVI(MID$(LineOfs$, pOfs + 4, 2)))
280 ' split data into fields
281 NoDebug = ASC(LEFT$(l$, 1))
284 lgLn = ASC(MID$(l$, pLn, 1))
285 StrucData$(b) = MID$(l$, pLn + 1, lgLn)
289 IF oldOpCode$ <> StrucData$(1) THEN
290 Instructs$ = Instructs$ + StrucData$(1) + CHR$(0)
291 IF LEN(oldOpCode$) THEN PRINT #2, strEnd$
292 PRINT #2, strBegStart$ + StrucData$(1) + strBegEnd$
293 oldOpCode$ = StrucData$(1)
295 SELECT CASE UCASE$(StrucData$(3))
298 PRINT #2, " {I_" + oldOpCode$ + ", " + StrucData$(5) + ", {" + StrucData$(2) + "}, " + qt$ + StrucData$(3) + qt$ + ", " + StrucData$(4) + "},"
301 IF LEN(oldOpCode$) THEN PRINT #2, strEnd$
303 PRINT #2, "struct itemplate *nasm_instructions[] = {"
305 p = INSTR(Instructs$, CHR$(0))
307 h$ = MID$(Instructs$, op, p - op)
308 PRINT #2, " instrux_" + h$ + ","
310 p = INSTR(op, Instructs$, CHR$(0))
323 PRINT "Creating INSNSD.C"
325 OPEN "O", 2, "insnsd.c"
327 PRINT #2, "/* This file auto-generated from insns.dat by insns.bas - don't edit it */"
329 PRINT #2, "#include <stdio.h>"
330 PRINT #2, "#include " + qt$ + "nasm.h" + qt$
331 PRINT #2, "#include " + qt$ + "insns.h" + qt$
335 PRINT #2, "static struct itemplate instrux[] = {"
338 LineOfs& = CVL(MID$(LineOfs$, pOfs, 4))
339 l$ = SPACE$(CVI(MID$(LineOfs$, pOfs + 4, 2)))
343 ' split data into fields
344 NoDebug = ASC(LEFT$(l$, 1))
347 lgLn = ASC(MID$(l$, pLn, 1))
348 StrucData$(b) = MID$(l$, pLn + 1, lgLn)
352 IF NoDebug OR (UCASE$(StrucData$(3)) = "IGNORE") THEN
355 PRINT #2, " {I_" + StrucData$(1) + ", " + StrucData$(5) + ", {" + StrucData$(2) + "}, " + qt$ + StrucData$(3) + qt$ + ", " + StrucData$(4) + "},"
358 PRINT #2, " {-1}" + crlf$ + "};" + crlf$
361 OpCodeBegS$ = "static struct itemplate *itable_"
362 OpCodeBegE$ = "[] = {"
363 OpCodeEnd$ = " NULL" + crlf$ + "};" + crlf$
366 PRINT #2, OpCodeBegS$ + RIGHT$("00" + HEX$(a), 2) + OpCodeBegE$
368 FOR b = 1 TO LEN(h$) STEP 2
369 OpCodePos = CVI(MID$(h$, b, 2))
370 PRINT #2, " instrux +" + STR$(OpCodePos) + ","
375 PRINT #2, "struct itemplate **itable[] = {"
377 PRINT #2, " itable_" + RIGHT$("00" + HEX$(a), 2) + ","
390 FUNCTION ReplaceOp$ (a$)
398 ReplaceOp$ = "IMMEDIATE"
400 ReplaceOp$ = "MEMORY"
401 CASE "MEM8", "MEM16", "MEM32", "MEM64", "MEM80"
402 ReplaceOp$ = "MEMORY|BITS" + MID$(tst$, 4)
403 CASE "REG8", "REG16", "REG32"
405 CASE "RM8", "RM16", "RM32"
406 ReplaceOp$ = "REGMEM|BITS" + MID$(tst$, 3)
407 CASE "IMM8", "IMM16", "IMM32"
408 ReplaceOp$ = "IMMEDIATE|BITS" + MID$(tst$, 4)
414 FUNCTION Min% (a%, b%)
415 IF a% < b% THEN Min% = a% ELSE Min% = b%
418 FUNCTION StrAscii (a$)
426 ' same as =INSTR(SearchStart, SearchIn, ANY SearchFor$) in PowerBASIC(tm)
428 FUNCTION StrInstrLeft (SearchStart, SearchIn$, SearchFor$)
429 ValuesCount = LEN(SearchFor$)
430 MaxValue = LEN(SearchIn$) + 1
432 FOR Counter1 = 1 TO ValuesCount
433 SearchChar$ = MID$(SearchFor$, Counter1, 1)
434 hVal2 = INSTR(SearchStart, SearchIn$, SearchChar$)
435 IF hVal2 > 0 THEN MinValue = Min%(hVal2, MinValue)
437 IF MinValue = MaxValue THEN MinValue = 0
438 StrInstrLeft = MinValue
442 ' This is a very damn fuckin' shit version of this splitting routine.
443 ' At this time, it's not very useful :]
445 SUB StrSplitString (SplitString$, SplitChars$, SplitField$(), SplitCount)
446 StartIndex = LBOUND(SplitField$)
447 LastIndex = UBOUND(SplitField$)
448 ActualIndex& = StartIndex
452 FoundPos = StrInstrLeft(LastPos, SplitString$, SplitChars$ + CHR$(34))
456 DO WHILE FoundPos > 0
457 FoundCharVal = StrAscii(MID$(SplitString$, FoundPos, 1))
458 PosDiff = (FoundPos - LastPos) + 1
459 SELECT CASE FoundCharVal
461 TempString$ = TempString$ + MID$(SplitString$, LastPos, PosDiff - 1)
469 TempString$ = TempString$ + MID$(SplitString$, LastPos, PosDiff - 1)
470 SplitField$(ActualIndex&) = TempString$
472 ActualIndex& = ActualIndex& + 1
473 IF ActualIndex& > LastIndex THEN
474 ActualIndex& = LastIndex
481 LastPos = FoundPos + 1
482 FoundPos = StrInstrLeft(LastPos, SplitString$, SplitChars$)
483 LOOP WHILE LastPos = FoundPos
484 FoundPos = StrInstrLeft(LastPos, SplitString$, SplitChars$ + CHR$(34))
487 LastPos = LEN(SplitString$) + 1
490 LastPos = FoundPos + 1
491 FoundPos = StrInstrLeft(LastPos, SplitString$, CHR$(34))
493 SplitString$ = SplitString$ + CHR$(34)
494 FoundPos = LEN(SplitString$)
499 IF LEN(TempString$) > 0 THEN
500 SplitField$(ActualIndex&) = TempString$
501 ELSEIF LastPos <= LEN(SplitString$) THEN
502 SplitField$(ActualIndex&) = MID$(SplitString$, LastPos)
504 ActualIndex& = ActualIndex& - 1
507 FOR a = ActualIndex& + 1 TO LastIndex
510 SplitCount = (ActualIndex& - StartIndex) + 1
513 FUNCTION StrTrim$ (a$, b$)
514 StrTrim$ = StrTrimRight$(StrTrimLeft$(a$, b$), b$)
517 FUNCTION StrTrimLeft$ (a$, b$) 'public
523 LOOP WHILE (p < l) AND (INSTR(b$, t$) > 0)
524 StrTrimLeft$ = MID$(a$, p)
527 FUNCTION StrTrimRight$ (a$, b$) 'public
537 LOOP WHILE (p > 0) AND (INSTR(b$, t$) > 0)
538 StrTrimRight$ = LEFT$(a$, p)