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
)